I've noticed that certain palette indexes are crashing the game; either I've discovered a new bug, or my ROM hack is trying to fight back against me; whatever the case, here's the index, in case someone figures out why the issue occurs. Code (Text): PalPointers: PalPtr_SEGA: palptr Pal_SEGA, 0 PalPtr_Title: palptr Pal_Title, 1 PalPtr_BGND: palptr Pal_BGND, 0 PalPtr_EHZ: palptr Pal_EHZ, 1 PalPtr_EHZ2: palptr Pal_EHZ2, 1 PalPtr_OWZ1: palptr Pal_OWZ1, 1 PalPtr_OWZ2: palptr Pal_OWZ2, 1 PalPtr_WZ: palptr Pal_WZ, 1 PalPtr_SSZ1: palptr Pal_SSZ1, 1 PalPtr_SSZ2: palptr Pal_SSZ2, 1 PalPtr_MTZ: palptr Pal_MTZ, 1 PalPtr_MTZ2: palptr Pal_MTZ, 1 PalPtr_WFZ: palptr Pal_WFZ, 1 PalPtr_HTZ: palptr Pal_HTZ, 1 PalPtr_HPZ: palptr Pal_HPZ, 1 PalPtr_RWZ: palptr Pal_RWZ, 1 PalPtr_OOZ: palptr Pal_OOZ, 1 PalPtr_MCZ: palptr Pal_MCZ, 1 PalPtr_CNZ: palptr Pal_CNZ, 1 PalPtr_CPZ: palptr Pal_CPZ, 1 PalPtr_CPZ2: palptr Pal_CPZ2, 1 PalPtr_DEZ: palptr Pal_DEZ, 1 PalPtr_ARZ: palptr Pal_ARZ, 1 PalPtr_ARZ2: palptr Pal_ARZ2, 1 palptr Pal_EHZ, 1 ; for some reason, this specific entry crashes the game... PalPtr_SCZ: palptr Pal_SCZ, 1 PalPtr_OWZ1_U: palptr Pal_OWZ1_U, 1 PalPtr_HPZ_U: palptr Pal_HPZ_U, 0 PalPtr_CPZ_U: palptr Pal_CPZ_U, 0 PalPtr_SS: palptr Pal_SS, 0 PalPtr_ARZ_U: palptr Pal_ARZ_U, 0 PalPtr_ARZ2_U: palptr Pal_ARZ2_U, 0 PalPtr_MCZ_B: palptr Pal_MCZ_B, 1 PalPtr_CNZ_B: palptr Pal_CNZ_B, 1 PalPtr_SS1: palptr Pal_SS1, 3 PalPtr_SS2: palptr Pal_SS2, 3 PalPtr_SS3: palptr Pal_SS3, 3 PalPtr_SS4: palptr Pal_SS4, 3 PalPtr_SS5: palptr Pal_SS5, 3 PalPtr_SS6: palptr Pal_SS6, 3 PalPtr_SS7: palptr Pal_SS7, 3 PalPtr_SS1_2p: palptr Pal_SS1_2p,3 PalPtr_SS2_2p: palptr Pal_SS2_2p,3 PalPtr_SS3_2p: palptr Pal_SS3_2p,3 PalPtr_OOZ_B: palptr Pal_OOZ_B, 1 PalPtr_Result: palptr Pal_Result,0 palptr Pal_EHZ, 1 ; this too! palptr Pal_EHZ, 1 ; this too! palptr Pal_EHZ, 1 ; this too! PalPtr_Knux: palptr Pal_Knux, 0 PalPtr_CPZ_K_U: palptr Pal_CPZ_K_U, 0 PalPtr_ARZ_K_U: palptr Pal_ARZ_K_U, 0 PalPtr_SS_K: palptr Pal_SS_K, 0 PalPtr_HPZ_K_U: palptr Pal_HPZ_K_U, 0 ; MENUS GO HERE PalPtr_SonicMenu: palptr Pal_SonicMenu, 0 PalPtr_TailsMenu: palptr Pal_TailsMenu, 0 PalPtr_KnuxMenu: palptr Pal_KnuxMenu, 0 PalPtr_EggmanMenu: palptr Pal_EggmanMenu, 0 PalPtr_RetroMenu: palptr Pal_RetroMenu, 0 PalPtr_Ending: palptr Pal_Ending, 0
I'm not sure what you exactly mean by "crashing the game". Are you trying to load those Pal_EHZ entries? The only issue that I came across was with "levartptrs" not being able to take into account any additional operators without surrounding it with parenthesis (i.e. you can't put in PalID_EHZ+1, because it gets assembled as "PalID_EHZ+1<<24", which is PalID_EHZ+$1000000). To fix that alongside any other potential issues, I changed: Code (Text): dc.l (plc1<<24)|art dc.l (plc2<<24)|map16x16 dc.l (palette<<24)|map128x128 to Code (Text): dc.l ((plc1)<<24)|(art) dc.l ((plc2)<<24)|(map16x16) dc.l ((palette)<<24)|(map128x128)
I assume "crashing the game" refers to a 68K exception occurring when you try to use those palette indices, but without knowing what kind of exception (address error, illegal instruction, etc.) is occurring, I would not know where to start looking. Are you using an exception handler in your hack?
No, as in it crashes if ANYTHING tries to load those entries. I wasn't, although that gave me the idea to import the Sonic 1 error exception to see what comes up; I got Line 1111 Emulator $00000001 as my result.
Line 1111 Emulator exception at offset $00000001 (part of the initial stack pointer value in the vector table). Seems something is causing those pointers to jump to invalid code instead of their intended destination.
Strange, as the broken entries are broken regardless of what's there, even with a generic EHZ entry. PalLoad function.
Please post some code/be more specific, because otherwise, I'm lost. I wanna see how EXACTLY you are doing it. It's possible that there's something about it you are not catching. So far, you've only really told me what you are intending to do, but not what's actually being done.
Code (Text): moveq #$36,d0 ; load Knuckles' palette index + bsr.w PalLoad_Now ; load Sonic's palette line The code used to load the palette; and yes, I did also use move.b and even move.w to load it instead, but it still crashes.
Okay, so a couple of things: Code (Text): PalPtr_SEGA: palptr Pal_SEGA, 0 ; 00 PalPtr_Title: palptr Pal_Title, 1 ; 01 PalPtr_BGND: palptr Pal_BGND, 0 ; 02 PalPtr_EHZ: palptr Pal_EHZ, 1 ; 03 PalPtr_EHZ2: palptr Pal_EHZ2, 1 ; 04 PalPtr_OWZ1: palptr Pal_OWZ1, 1 ; 05 PalPtr_OWZ2: palptr Pal_OWZ2, 1 ; 06 PalPtr_WZ: palptr Pal_WZ, 1 ; 07 PalPtr_SSZ1: palptr Pal_SSZ1, 1 ; 08 PalPtr_SSZ2: palptr Pal_SSZ2, 1 ; 09 PalPtr_MTZ: palptr Pal_MTZ, 1 ; 0A PalPtr_MTZ2: palptr Pal_MTZ, 1 ; 0B PalPtr_WFZ: palptr Pal_WFZ, 1 ; 0C PalPtr_HTZ: palptr Pal_HTZ, 1 ; 0D PalPtr_HPZ: palptr Pal_HPZ, 1 ; 0E PalPtr_RWZ: palptr Pal_RWZ, 1 ; 0F PalPtr_OOZ: palptr Pal_OOZ, 1 ; 10 PalPtr_MCZ: palptr Pal_MCZ, 1 ; 11 PalPtr_CNZ: palptr Pal_CNZ, 1 ; 12 PalPtr_CPZ: palptr Pal_CPZ, 1 ; 13 PalPtr_CPZ2: palptr Pal_CPZ2, 1 ; 14 PalPtr_DEZ: palptr Pal_DEZ, 1 ; 15 PalPtr_ARZ: palptr Pal_ARZ, 1 ; 16 PalPtr_ARZ2: palptr Pal_ARZ2, 1 ; 17 palptr Pal_EHZ, 1 ; 18 PalPtr_SCZ: palptr Pal_SCZ, 1 ; 19 PalPtr_OWZ1_U: palptr Pal_OWZ1_U, 1 ; 1A PalPtr_HPZ_U: palptr Pal_HPZ_U, 0 ; 1B PalPtr_CPZ_U: palptr Pal_CPZ_U, 0 ; 1C PalPtr_SS: palptr Pal_SS, 0 ; 1D PalPtr_ARZ_U: palptr Pal_ARZ_U, 0 ; 1E PalPtr_ARZ2_U: palptr Pal_ARZ2_U, 0 ; 1F PalPtr_MCZ_B: palptr Pal_MCZ_B, 1 ; 20 PalPtr_CNZ_B: palptr Pal_CNZ_B, 1 ; 21 PalPtr_SS1: palptr Pal_SS1, 3 ; 22 PalPtr_SS2: palptr Pal_SS2, 3 ; 23 PalPtr_SS3: palptr Pal_SS3, 3 ; 24 PalPtr_SS4: palptr Pal_SS4, 3 ; 25 PalPtr_SS5: palptr Pal_SS5, 3 ; 26 PalPtr_SS6: palptr Pal_SS6, 3 ; 27 PalPtr_SS7: palptr Pal_SS7, 3 ; 28 PalPtr_SS1_2p: palptr Pal_SS1_2p,3 ; 29 PalPtr_SS2_2p: palptr Pal_SS2_2p,3 ; 2A PalPtr_SS3_2p: palptr Pal_SS3_2p,3 ; 2B PalPtr_OOZ_B: palptr Pal_OOZ_B, 1 ; 2C PalPtr_Result: palptr Pal_Result,0 ; 2D palptr Pal_EHZ, 1 ; 2E palptr Pal_EHZ, 1 ; 2F palptr Pal_EHZ, 1 ; 30 PalPtr_Knux: palptr Pal_Knux, 0 ; 31 PalPtr_CPZ_K_U: palptr Pal_CPZ_K_U, 0 ; 32 PalPtr_ARZ_K_U: palptr Pal_ARZ_K_U, 0 ; 33 PalPtr_SS_K: palptr Pal_SS_K, 0 ; 34 PalPtr_HPZ_K_U: palptr Pal_HPZ_K_U, 0 ; 35 PalPtr_SonicMenu: palptr Pal_SonicMenu, 0 ; 36 PalPtr_TailsMenu: palptr Pal_TailsMenu, 0 ; 37 PalPtr_KnuxMenu: palptr Pal_KnuxMenu, 0 ; 38 PalPtr_EggmanMenu: palptr Pal_EggmanMenu, 0 ; 39 PalPtr_RetroMenu: palptr Pal_RetroMenu, 0 ; 3A PalPtr_Ending: palptr Pal_Ending, 0 ; 3B Looks like you miscounted, or you changed the palette table. One more question, from where is this being run at? Is it from an object?
It's just the routine that loads Sonic's (or, in this case, Knuckles') palette when starting the level (Level_LoadPal).
Only thing I can think of is for you to go to where the stack pointer register points to in RAM, and follow the path of addresses that are pushed from calls/interrupts to determine where it's exactly crashing from, with the help of your listing output (note that interrupts/exceptions push the return address and the status register (which will look something like $23xx or $27xx in Sonic 2), so keep that in mind. Also if you are using vladikcomper's debugger, the stack trace starting from SP is already there at the bottom of the screen). Might be helpful to post the rest of what's under Level_LoadPal, maybe. It might be better to move this into Basic Q&A or a separate thread, to be honest. Kinda clogging up this thread.
Fixing the Pitch of the Sega Sound This is one that I am absolutely amazed no one ANYWHERE has seemed to have noticed, much less discussed: the pitch of the SEGA Sound in Sonic 2 is just a tiny bit higher pitched than it should be. Whether it is intentional or not, I don't know, but I found it impossible to ignore. Thankfully, it is actually really easy to restore it to match Sonic 1 and 3K. In the sound driver, find this section under zPlaySegaSound: Code (Text): .loop: ld a,(hl) ; Get next PCM byte ld (zYM2612_D0),a ; Send to DAC inc hl ; Advance pointer nop ld b,0Ch ; Sega PCM pitch djnz $ ; Delay loop nop ld a,(zAbsVar.QueueToPlay) ; Get next item to play cp c ; Is it 80h? jr nz,.stop ; If not, stop Sega PCM ld a,(hl) ; Get next PCM byte ld (zYM2612_D0),a ; Send to DAC inc hl ; Advance pointer nop ld b,0Ch ; Sega PCM pitch djnz $ ; Delay loop nop dec de ; 2 less bytes to play ld a,d ; a = d or e ; Is de zero? jp nz,.loop ; If not, loop Delete all four of the nops, and change both instances of '0Ch' to '0Dh'. That's it. (This does appear to be safe for real hardware; the 2612 in my Model 1 VA6 handles it without any problems.) Fix Erratic Behavior of Various Badniks in Debug Mode In debug mode, quite a few Badniks will still track Sonic while he is an object, while others will behave erratically, such as Grabbers moving up and down wildly. This is caused by Obj_GetOrientationToPlayer not checking for debug mode. This is also a simple fix: Code (Text): Obj_GetOrientationToPlayer: moveq #0,d0 moveq #0,d1 lea (MainCharacter).w,a1 ; a1=character move.w x_pos(a0),d2 sub.w x_pos(a1),d2 mvabs.w d2,d4 ; absolute horizontal distance to main character lea (Sidekick).w,a2 ; a2=character move.w x_pos(a0),d3 sub.w x_pos(a2),d3 mvabs.w d3,d5 ; absolute horizontal distance to sidekick cmp.w d5,d4 ; get shorter distance bls.s ++ ; branch, if main character is closer Above the 'cmp.w d5,d4', insert these two lines: Code (Text): tst.w (Debug_placement_mode).w ; is debug mode active? bne.s + ; if so, treat sidekick as closer There are quite a few other similar bugs in debug mode in both Sonic 1 and 2 that can be fixed by inserting those two lines in various locations.
You know how in 2-player mode, whenever a teleport monitor is hit, the background color never changes? Well, turns out it's the result of a single line of code; in Vint_Level, you should see something similar to this: Code (Text): Vint_Level: bsr.w ReadJoypads tst.b (Teleport_timer).w beq.s loc_6F8 lea (VDP_control_port).l,a5 tst.w (Game_paused).w ; is the game paused ? bne.w loc_748 ; if yes, branch subq.b #1,(Teleport_timer).w bne.s + move.b #0,(Teleport_flag).w + cmpi.b #$10,(Teleport_timer).w blo.s loc_6F8 lea (VDP_data_port).l,a6 move.l #vdpComm($0000,CRAM,WRITE),(VDP_control_port).l move.w #$EEE,d0 move.w #$1F,d1 - move.w d0,(a6) dbf d1,- That $1F should be changed to $20, and now the color changes correctly.
I don't think that's correct. Here's the complete code: Code (ASM): lea (VDP_data_port).l,a6 move.l #vdpComm($0000,CRAM,WRITE),(VDP_control_port).l move.w #$EEE,d0 ; White. move.w #32-1,d1 - move.w d0,(a6) dbf d1,- ; Skip a colour. move.l #vdpComm($0042,CRAM,WRITE),(VDP_control_port).l if fixBugs move.w #31-1,d1 else ; This does one more colour than necessary: it isn't accounting for ; the colour that was skipped earlier! move.w #32-1,d1 endif - move.w d0,(a6) dbf d1,- What this does is fill the first two palette lines with white, skip the first colour of the third palette line, and then set the remaining colours to white. Skipping that one colour is deliberate. There is, however, a small bug where the first colour of the first palette line is set to white twice because of an incorrect loop counter.