Bug report/fix: text groups after 63 do not work correctly.

Post Reply
User avatar
chronicleroflegends
Posts: 190
Joined: Thu Sep 06, 2018 3:51 am

Bug report/fix: text groups after 63 do not work correctly.

Post by chronicleroflegends » Sun Oct 20, 2019 12:32 am

Hello everyone! While working on my game recently I found a bug with the way text groups are handled.

It is not noticeable until you get to groups 64 and up. This won't affect most games, but I figured I would post the fix I worked out here in case anybody else is working
on a story-heavy game and runs into this same issue. Thankfully it is pretty easy to solve.

HUGE thanks to SpiderDave for the help in working out this fix and editing my script to make it as efficient as possible!

Remember guys, when working with engine scripts:
ALWAYS save a backup in case anything messes up!

Anyways on to the culprit:

in system/loadScreenData.asm we have this subroutine:

Code: Select all

getTextForScreen:
	LDA currentBank
	STA prevBank
	LDY #$16
	JSR bankswitchY
	
	LDA stringGroupPointer ;; this is the group of the string. 
	ASL
	ASL
	TAY
	LDA AllTextGroups,y
	STA screenText
	INY
	LDA AllTextGroups,y
	STA screenText+1
	INY
	LDA AllTextGroups,y
	STA screenText+2
	INY
	LDA AllTextGroups,y
	STA screenText+3

	LDY prevBank
	JSR bankswitchY		
	RTS
To get the correct address for the text group and its entries, the variable has to have its bits shifted left twice (to account for each group taking up 4 bytes)
The problem is if you have 64 (01000000) or greater shifting the bits left twice destroys the left two bits and you are left with a garbage value. This makes it seem
like your text groups wrap around back to the start after 63.

The fix for this is to find the address using a 16-bit variable instead of an 8 bit one. That way we do not lose any bits in the calculation.
Here is the script to fix it:

Code: Select all

getTextForScreen:
	LDA currentBank
	STA prevBank
	LDY #$16
	JSR bankswitchY
	
	;; 16 bit addressing
	;; Find the address the text groups begin at.
	LDA #<AllTextGroups
	STA temp16
	LDA #>AllTextGroups
	STA temp16+1
	
	;; Add the hi end
	LDA stringGroupPointer ;; Get the text group for this screen
	ASL ;;Shift them left twice, to make each text group equal to 4 entries.
	ASL
	CLC
	ADC temp16 ;; We need more space so we do not lose left 2 bits, store it in temp16
	STA temp16
	
	;;grab the carry flag if it exists
	LDA #$00
	ADC #$00 ;; this draws out the carry bit by not clearing it before addition.
	STA temp
	
	;; Add the lo end
	LDA stringGroupPointer ;; Get the text group for this screen
	;; get the left 2 bits if they exist
	AND #%11000000
	LSR ;; shift them to the far right side
	LSR
	LSR
	LSR
	LSR
	LSR
	CLC
	ADC temp16+1 ;; add to the lo end of temp16
	ADC temp ;; add the carry if it exists
	STA temp16+1	
	
	;;load the 4 text entries from our new address
	LDY #$00
-
    	LDA (temp16), y
    	STA (screenText), y
   	INY
    	CPY #$04
    	BNE -

	LDY prevBank
	JSR bankswitchY		
	RTS
This uses the temp16 variable to load the address, which makes it possible to load past group 63.
~Do you believe in legends? ~
My Games: Nix: The Paradox Relic
User avatar
dale_coop
Posts: 4476
Joined: Fri Feb 16, 2018 7:05 am
Location: France

Re: Bug report/fix: text groups after 63 do not work correctly.

Post by dale_coop » Sun Oct 20, 2019 6:10 pm

Awesome! Thank you, chronicleroflegends <3 Nice tutorial
-----
Sorry about my poor english
All I need: A Damn Fine Cup of Coffee
My games: PRESS START GAME / UNDERGROUND ADVENTURE / UNDERGROUND ADVENTURE (Arcade version - Byte-Off-2019)
Post Reply