I tried delving deep into the assembler, and the only option I could think of would be to remove all of the checks for ' symbol, unfortunately it's tied quite heavily to " symbol (obviously as a string has to end with the same symbol it started with), so I substituted ' for " so there are no string references. But then I would hit an issue where it wasn't accepting ' and so I'm assuming there's gonna be a table of acceptable characters or an array of comparison and conditional jumps for it somewhere (haven't found it yet). It's such an annoying quirk about Z80 assembly, the ' serves really no purpose being with af,af other than to indicate visually to the programmer it's swapping with an alternate af, but I'd ask "what else would it swap with?", so it seems mute. With regards to your macro issue, I'm not sure what you mean, I suspect I'm misunderstanding, because I tried your macro myself and it worked fine: Code (Text): getzreg a dc.b zreg getzreg c dc.b zreg ...this produced... Code (Text): 07 01 I'm assuming your using this macro in a particular way that mitigates the above?
Turns out it was just a typo. I was sending the wrong value to getzreg. ex af,af' will have to be the one instruction that isn't perfectly matched then. Everything else seems to be working, including instructions shared with 68000. I just have a few details to iron out and it'll be ready for release.
I saw that in Sonic 1 Kawarino hack the goggles object was loaded on Sonic in Labyrinth Zone and Scrap Brain Zone, Act 3. But, I tried everything to get them to load. How do I implement them? I know I need VRAM, pattern load cues, and mappings, but does anyone know?
There's a guide on the wiki that shows you how to set it up. https://info.sonicretro.org/SCHG_How-to:Set_up_the_Goggle_Monitor_to_work_with_it
I did that Goggles in the Sonic 1 Prototype - YouTube and they don't load the object that follows him.
I've had this issue for a few months but didn't get a chance to say it here. Everyone but Sonic stays blank when they switch to path 2. I know it's a bit 6 issue, but I can't say where the issue lies. Here's a screenshot for reference: For all I know, it's in Sonic_Loops, and it ties to bit 6. I'll send the code below: Spoiler: Sonic_Loops Code (Text): ; --------------------------------------------------------------------------- ; Subroutine to make Sonic run around loops (GHZ/SLZ) ; --------------------------------------------------------------------------- ; ||||||||||||||| S U B R O U T I N E ||||||||||||||||||||||||||||||||||||||| Sonic_Loops: ; XREF: Obj01_Control cmpi.b #id_SLZ,(v_zone).w ; is level SLZ ? beq.s @isstarlight ; if yes, branch tst.b (v_zone).w ; is level GHZ ? bne.w @noloops ; if not, branch @isstarlight: move.w obY(a0),d0 lsr.w #1,d0 andi.w #$380,d0 move.b obX(a0),d1 andi.w #$7F,d1 add.w d1,d0 lea (v_lvllayout).w,a1 move.b (a1,d0.w),d1 ; d1 is the 256x256 tile Sonic is currently on cmp.b (v_256roll1).w,d1 ; is Sonic on a "roll tunnel" tile? beq.w Obj01_ChkRoll ; if yes, branch cmp.b (v_256roll2).w,d1 beq.w Obj01_ChkRoll cmp.b (v_256loop1).w,d1 ; is Sonic on a loop tile? beq.s @chkifleft ; if yes, branch cmp.b (v_256loop2).w,d1 beq.s @chkifinair bclr #6,obRender(a0) ; return Sonic to high plane rts ; =========================================================================== @chkifinair: btst #1,obStatus(a0) ; is Sonic in the air? beq.s @chkifleft ; if not, branch bclr #6,obRender(a0) ; return Sonic to high plane rts ; =========================================================================== @chkifleft: move.w obX(a0),d2 cmpi.b #$2C,d2 bcc.s @chkifright bclr #6,obRender(a0) ; return Sonic to high plane rts ; =========================================================================== @chkifright: cmpi.b #$E0,d2 bcs.s @chkangle1 bset #6,obRender(a0) ; send Sonic to low plane rts ; =========================================================================== @chkangle1: btst #6,obRender(a0) ; is Sonic on low plane? bne.s @chkangle2 ; if yes, branch move.b obAngle(a0),d1 beq.s @done cmpi.b #$80,d1 ; is Sonic upside-down? bhi.s @done ; if yes, branch bset #6,obRender(a0) ; send Sonic to low plane rts ; =========================================================================== @chkangle2: move.b obAngle(a0),d1 cmpi.b #$80,d1 ; is Sonic upright? bls.s @done ; if yes, branch bclr #6,obRender(a0) ; send Sonic to high plane @noloops: @done: rts ; End of function Sonic_Loops All the code is pretty much the same as ReadySonic and has not changed. Unfortunately, I initially used the Hivebrain code which also didn't work either. Does anyone know how I'm able to fix this?
Hello! I'm brand spanking new to creating mods for Sonic Gens, and I would like to completely remove a set of models/enemies. Specifically I would like to alter the 06 mod to not have any Iblis or Mephiles, and replace them with the G.U.N. robots and shadow respectively. Can anyone point me in the right direction of what I need to look into doing? I read all the guides on this site but don't see anything specific on how to do what I'm trying to do with character models. I can research how to use the tools, I just need a bit help knowing what tools I need/a birdseye view of what's involved. Hello! I asked on the Basic Q&A but not sure if that's the right place for this question. I'm brand spanking new to creating mods for Sonic Gens, and I would like to completely remove a set of models/enemies. Specifically I would like to alter the 06 mod to not have any Iblis or Mephiles, and replace them with the G.U.N. robots and shadow respectively. Can anyone point me in the right direction of what I need to look into doing? I read all the guides on this site but don't see anything specific on how to do what I'm trying to do with character models. I can research how to use the tools, I just need a bit help knowing what tools I need/a birdseye view of what's involved. Thank you so much for your patience!
EDIT: I solved it myself. Apparently under no circumstances can = make a forward reference, even if it's referencing a fixed value (equ). I just had to define the sizeof values earlier. I'm trying to automate VRAM management with some macros, and I've run into a bit of a problem: What's causing this error? sizeof_nem_ring is definitely $1C0, it's defined by the following line which I'm quite sure is working: sizeof_nem_ring is defined after last_vram, but that shouldn't be a problem because it's an equ. This is the line in the macro that's causing trouble.
If I have a bclr instruction followed by a beq, does that mean it branches if the bit was already clear? I'm assuming that's how it works but I just wanted to confirm. Example: Code (Text): bclr #0,d0 ; clear bit 0 beq.s @offset_even ; branch if already clear
Aight, here we go again. Sonic 1 Definitive, I'm currently working slowly on level transitions. This doesn't cover the entire portion of that mess, though, specifically one part: Moduled Kosinski. It, for some reason, only wants to load 1 module. I'll send the code involved and the relevant portion of my variables file. Spoiler: Moduled Kosinski ported code Code (Text): ;--------------------------------------------------------------------------- ; Adds a Kosinski Moduled archive to the module queue ; Inputs: ; a1 = address of the archive ; d2 = destination in VRAM ; --------------------------------------------------------------------------- ; =============== S U B R O U T I N E ======================================= Queue_Kos_Module: lea (Kos_module_queue).w,a2 tst.l (a2) ; is the first slot free? beq.s Process_Kos_Module_Queue_Init ; if it is, branch addq.w #6,a2 ; otherwise, check next slot KosM_FindFreeSlot: tst.l (a2) beq.s KosM_FreeSlotFound addq.w #6,a2 bra.s KosM_FindFreeSlot ; --------------------------------------------------------------------------- KosM_FreeSlotFound: move.l a1,(a2)+ ; store source address move.w d2,(a2)+ ; store destination VRAM address rts ; End of function Queue_Kos_Module ; --------------------------------------------------------------------------- ; Initializes processing of the first module on the queue ; --------------------------------------------------------------------------- ; =============== S U B R O U T I N E ======================================= Process_Kos_Module_Queue_Init: move.w (a1)+,d3 ; get uncompressed size cmpi.w #$A000,d3 bne.s @size move.w #$8000,d3 ; $A000 means $8000 for some reason @size: lsr.w #1,d3 move.w d3,d0 rol.w #5,d0 andi.w #$1F,d0 ; get number of complete modules move.b d0,(Kos_modules_left).w andi.l #$7FF,d3 ; get size of last module in words bne.s @nonzero ; branch if it's non-zero subq.b #1,(Kos_modules_left).w ; otherwise decrement the number of modules move.l #$800,d3 ; and take the size of the last module to be $800 words @nonzero: move.w d3,(Kos_last_module_size).w move.w d2,(Kos_module_destination).w move.l a1,(Kos_module_queue).w addq.b #1,(Kos_modules_left).w ; store total number of modules rts ; End of function Process_Kos_Module_Queue_Init ; --------------------------------------------------------------------------- ; Processes the first module on the queue ; --------------------------------------------------------------------------- ; =============== S U B R O U T I N E ======================================= Process_Kos_Module_Queue: tst.b (Kos_modules_left).w bne.s KosM_ModulesLeft KosM_Done: rts ; --------------------------------------------------------------------------- KosM_ModulesLeft: bmi.s KosM_DecompressionStarted cmpi.w #4,(Kos_decomp_queue_count).w bhs.s KosM_Done ; branch if the Kosinski decompression queue is full movea.l (Kos_module_queue).w,a1 lea (Kos_decomp_buffer).w,a2 bsr.w Queue_Kos ; add current module to decompression queue ori.b #$80,(Kos_modules_left).w ; and set bit to signify decompression in progress rts ; --------------------------------------------------------------------------- KosM_DecompressionStarted: tst.w (Kos_decomp_queue_count).w bne.s KosM_Done ; branch if the decompression isn't complete ; otherwise, DMA the decompressed data to VRAM andi.b #$7F,(Kos_modules_left).w move.l #$800,d3 subq.b #1,(Kos_modules_left).w bne.s @notlast ; branch if it isn't the last module move.w (Kos_last_module_size).w,d3 @notlast: move.w (Kos_module_destination).w,d2 move.w d2,d0 add.w d3,d0 add.w d3,d0 move.w d0,(Kos_module_destination).w ; set new destination move.l (Kos_module_queue).w,d0 move.l (Kos_decomp_queue).w,d1 sub.l d1,d0 andi.l #$F,d0 add.l d0,d1 ; round to the nearest $10 boundary move.l d1,(Kos_module_queue).w ; and set new source move.l #Kos_decomp_buffer,d1 andi.l #$FFFFFF,d1 jsr (QueueDMATransfer).l tst.b (Kos_modules_left).w bne.s @return ; return if this wasn't the last module lea (Kos_module_queue).w,a0 lea (Kos_module_queue+6).w,a1 move.l (a1)+,(a0)+ ; otherwise, shift all entries up move.w (a1)+,(a0)+ move.l (a1)+,(a0)+ move.w (a1)+,(a0)+ move.l (a1)+,(a0)+ move.w (a1)+,(a0)+ move.l #0,(a0)+ ; and mark the last slot as free move.w #0,(a0)+ move.l (Kos_module_queue).w,d0 beq.s @return ; return if the queue is now empty movea.l d0,a1 move.w (Kos_module_destination).w,d2 jmp (Process_Kos_Module_Queue_Init).l @return: rts ; End of function Process_Kos_Module_Queue ; =============== S U B R O U T I N E ======================================= Queue_Kos: move.w (Kos_decomp_queue_count).w,d0 lsl.w #3,d0 lea (Kos_decomp_queue).w,a3 move.l a1,(a3,d0.w) ; store source move.l a2,4(a3,d0.w) ; store destination addq.w #1,(Kos_decomp_queue_count).w rts ; End of function Queue_Kos ; --------------------------------------------------------------------------- ; Checks if V-int occured in the middle of Kosinski queue processing ; and stores the location from which processing is to resume if it did ; --------------------------------------------------------------------------- ; =============== S U B R O U T I N E ======================================= Set_Kos_Bookmark: tst.w (Kos_decomp_queue_count).w bpl.s @no ; branch if a decompression wasn't in progress move.l $42(sp),d0 ; check address V-int is supposed to rte to cmpi.l #Process_Kos_Queue_Main,d0 blo.s @no cmpi.l #Process_Kos_Queue_Done,d0 bhs.s @no move.l $42(sp),(Kos_decomp_bookmark).w move.l #Backup_Kos_Registers,$42(sp) ; force V-int to rte here instead if needed @no: rts ; End of function Set_Kos_Bookmark ; --------------------------------------------------------------------------- ; Processes the first entry in the Kosinski decompression queue ; --------------------------------------------------------------------------- ; =============== S U B R O U T I N E ======================================= Process_Kos_Queue: tst.w (Kos_decomp_queue_count).w beq.w Process_Kos_Queue_Done bmi.w Restore_Kos_Bookmark ; branch if a decompression was interrupted by V-int Process_Kos_Queue_Main: ori.w #$8000,(Kos_decomp_queue_count).w ; set sign bit to signify decompression in progress movea.l (Kos_decomp_queue).w,a0 movea.l (Kos_decomp_destination).w,a1 ; what follows is identical to the normal Kosinski decompressor except for using Kos_description_field instead of the stack lea (Kos_description_field).w,a2 move.b (a0)+,1(a2) move.b (a0)+,(a2) move.w (a2),d5 moveq #$F,d4 Process_Kos_Queue_Loop: lsr.w #1,d5 move sr,d6 dbf d4,Process_Kos_Queue_ChkBit move.b (a0)+,1(a2) move.b (a0)+,(a2) move.w (a2),d5 moveq #$F,d4 Process_Kos_Queue_ChkBit: move d6,ccr bcc.s Process_Kos_Queue_RLE move.b (a0)+,(a1)+ bra.s Process_Kos_Queue_Loop ; --------------------------------------------------------------------------- Process_Kos_Queue_RLE: moveq #0,d3 lsr.w #1,d5 move sr,d6 dbf d4,Process_Kos_Queue_ChkBit2 move.b (a0)+,1(a2) move.b (a0)+,(a2) move.w (a2),d5 moveq #$F,d4 Process_Kos_Queue_ChkBit2: move d6,ccr bcs.s Process_Kos_Queue_SeparateRLE lsr.w #1,d5 dbf d4,@loop move.b (a0)+,1(a2) move.b (a0)+,(a2) move.w (a2),d5 moveq #$F,d4 @loop: roxl.w #1,d3 lsr.w #1,d5 dbf d4,@loop2 move.b (a0)+,1(a2) move.b (a0)+,(a2) move.w (a2),d5 moveq #$F,d4 @loop2: roxl.w #1,d3 addq.w #1,d3 moveq #-1,d2 move.b (a0)+,d2 bra.s Process_Kos_Queue_RLELoop ; --------------------------------------------------------------------------- Process_Kos_Queue_SeparateRLE: move.b (a0)+,d0 move.b (a0)+,d1 moveq #-1,d2 move.b d1,d2 lsl.w #5,d2 move.b d0,d2 andi.w #7,d1 beq.s Process_Kos_Queue_SeparateRLE2 move.b d1,d3 addq.w #1,d3 Process_Kos_Queue_RLELoop: move.b (a1,d2.w),d0 move.b d0,(a1)+ dbf d3,Process_Kos_Queue_RLELoop bra.s Process_Kos_Queue_Loop ; --------------------------------------------------------------------------- Process_Kos_Queue_SeparateRLE2: move.b (a0)+,d1 beq.s Process_Kos_Queue_EndReached cmpi.b #1,d1 beq.w Process_Kos_Queue_Loop move.b d1,d3 bra.s Process_Kos_Queue_RLELoop ; --------------------------------------------------------------------------- Process_Kos_Queue_EndReached: move.l a0,(Kos_decomp_queue).w move.l a1,(Kos_decomp_destination).w andi.w #$7FFF,(Kos_decomp_queue_count).w ; clear decompression in progress bit subq.w #1,(Kos_decomp_queue_count).w beq.s Process_Kos_Queue_Done ; branch if there aren't any entries remaining in the queue lea (Kos_decomp_queue).w,a0 lea (Kos_decomp_queue+8).w,a1 ; otherwise, shift all entries up move.l (a1)+,(a0)+ move.l (a1)+,(a0)+ move.l (a1)+,(a0)+ move.l (a1)+,(a0)+ move.l (a1)+,(a0)+ move.l (a1)+,(a0)+ Process_Kos_Queue_Done: rts ; --------------------------------------------------------------------------- Restore_Kos_Bookmark: movem.l (Kos_decomp_stored_registers).w,d0-d6/a0-a2 move.l (Kos_decomp_bookmark).w,-(sp) move.w (Kos_decomp_stored_SR).w,-(sp) rte ; --------------------------------------------------------------------------- Backup_Kos_Registers: move sr,(Kos_decomp_stored_SR).w movem.l d0-d6/a0-a2,(Kos_decomp_stored_registers).w rts ; End of function Process_Kos_Queue Spoiler: VBlank calls VBla_02: Code (Text): VBla_02: bsr.w sub_106E VBla_14: tst.w (v_demolength).w beq.w @end subq.w #1,(v_demolength).w @end: jmp (Set_Kos_Bookmark).l VBla_08: Code (Text): VBla_08: ; stopZ80 ; waitZ80 bsr.w ReadJoypads tst.b (f_wtr_state).w bne.s @waterabove writeCRAM v_pal_dry,$80,0 bra.s @waterbelow @waterabove: writeCRAM v_pal_water,$80,0 @waterbelow: move.w (v_hbla_hreg).w,(a5) move.b (v_hbla_line).w,(v_cramwaterpos).w writeVRAM v_hscrolltablebuffer,$380,vram_hscroll writeVRAM v_spritetablebuffer,$280,vram_sprites jsr (ProcessDMAQueue).l @nochg: startZ80 movem.l (v_screenposx).w,d0-d7 movem.l d0-d7,(v_screenposx_dup).w movem.l (v_fg_scroll_flags).w,d0-d1 movem.l d0-d1,(v_fg_scroll_flags_dup).w bsr.s Demo_Time jmp (Set_Kos_Bookmark).l VBla_0A: Code (Text): VBla_0A: ; stopZ80 ; waitZ80 bsr.w ReadJoypads writeCRAM v_pal_dry,$80,0 writeVRAM v_spritetablebuffer,$280,vram_sprites writeVRAM v_hscrolltablebuffer,$380,vram_hscroll startZ80 bsr.w PalCycle_SS jsr (ProcessDMAQueue).l @nochg: cmpi.b #96,(v_hbla_line).w bcc.s @update bra.w @end @update: jsr SS_LoadWalls tst.w (v_demolength).w ; is there time left on the demo? beq.w @end ; if not, return subq.w #1,(v_demolength).w ; subtract 1 from time left in demo @end: jmp (Set_Kos_Bookmark).l VBla_0C: Code (Text): VBla_0C: ; stopZ80 ; waitZ80 bsr.w ReadJoypads tst.b (f_wtr_state).w bne.s @waterabove writeCRAM v_pal_dry,$80,0 bra.s @waterbelow @waterabove: writeCRAM v_pal_water,$80,0 @waterbelow: move.w (v_hbla_hreg).w,(a5) move.b (v_hbla_line).w,(v_cramwaterpos).w writeVRAM v_hscrolltablebuffer,$380,vram_hscroll writeVRAM v_spritetablebuffer,$280,vram_sprites jsr (ProcessDMAQueue).l @nochg: startZ80 movem.l (v_screenposx).w,d0-d7 movem.l d0-d7,(v_screenposx_dup).w movem.l (v_fg_scroll_flags).w,d0-d1 movem.l d0-d1,(v_fg_scroll_flags_dup).w jsr LoadTilesAsYouMove jsr (AnimateLevelGfx).l cmpi.b #id_BS,(v_zone).w bne.s @normal jsr (HUD_UpdateBS).l bra.s @cont @normal: jsr (HUD_Update).l @cont: bsr.w sub_1642 jmp (Set_Kos_Bookmark).l VBla_16: Code (Text): VBla_16: ; stopZ80 ; waitZ80 bsr.w ReadJoypads writeCRAM v_pal_dry,$80,0 writeVRAM v_spritetablebuffer,$280,vram_sprites writeVRAM v_hscrolltablebuffer,$380,vram_hscroll startZ80 jsr (ProcessDMAQueue).l @nochg: cmpi.b #96,(v_hbla_line).w bcc.s @update bra.w @end @update: jsr SS_LoadWalls tst.w (v_demolength).w beq.w @end subq.w #1,(v_demolength).w @end: jmp (Set_Kos_Bookmark).l Spoiler: Level gamemode calls Code (Text): Level_TtlCardLoop: move.b #$C,(v_vbla_routine).w jsr (Process_Kos_Queue).l bsr.w WaitForVBla jsr (ExecuteObjects).l jsr (BuildSprites).l bsr.w RunPLC jsr (Process_Kos_Module_Queue).l move.w (v_objspace+$108).w,d0 cmp.w (v_objspace+$130).w,d0 ; has title card sequence finished? bne.s Level_TtlCardLoop ; if not, branch tst.l (v_plc_buffer).w ; are there any items in the pattern load cue? bne.s Level_TtlCardLoop ; if yes, branch jsr (Hud_Base).l ; load basic HUD gfx Code (Text): Level_MainLoop: bsr.w PauseGame move.b #8,(v_vbla_routine).w jsr (Process_Kos_Queue).l bsr.w WaitForVBla addq.w #1,(v_framecount).w ; add 1 to level timer bsr.w MoveSonicInDemo bsr.w LZWaterFeatures jsr (ExecuteObjects).l if Revision=0 else tst.w (f_restart).w bne GM_Level endc tst.w (v_debuguse).w ; is debug mode being used? bne.s Level_DoScroll ; if yes, branch cmpi.b #6,(v_player+obRoutine).w ; has Sonic just died? bhs.s Level_SkipScroll ; if yes, branch Level_DoScroll: bsr.w DeformLayers Level_SkipScroll: jsr (BuildSprites).l jsr (ObjPosLoad).l jsr RingsManager bsr.w PaletteCycle bsr.w RunPLC jsr (Process_Kos_Module_Queue).l bsr.w OscillateNumDo bsr.w SynchroAnimate bsr.w SignpostArtLoad cmpi.b #id_Demo,(v_gamemode).w beq.s Level_ChkDemo ; if mode is 8 (demo), branch if Revision=0 tst.w (f_restart).w ; is the level set to restart? bne.w GM_Level ; if yes, branch else endc cmpi.b #id_Level,(v_gamemode).w beq.w Level_MainLoop ; if mode is $C (level), branch rts Spoiler: Variables Code (Text): Camera_X_pos_last: equ $FFFFDC02 Camera_Y_pos_last: equ $FFFFDC04 ; $FFFFDC06 - $FFFFEFFF are unused. Kos_last_module_size: equ $FFFFDC06 ; the uncompressed size of the last module in words. All other modules are $800 words. Kos_module_queue: equ $FFFFDC08 ; 6 bytes per entry, first longword is source location and next word is VRAM destination. Twelve words. Kos_module_source: equ $FFFFDC30 ; long ; the compressed data location for the first module in the queue Kos_decomp_source: equ Kos_decomp_queue ; long ; the compressed data location for the first entry in the queue Kos_decomp_destination: equ Kos_decomp_queue+4 ; long ; the decompression location for the first entry in the queue Kos_module_destination: equ Kos_module_queue+4 ; word ; the VRAM destination for the first module in the queue Kos_decomp_queue_count: equ $FFFFDC38 ; the number of pieces of data on the queue. Sign bit set indicates a decompression is in progress. A word. Kos_decomp_stored_registers: equ $FFFFDC3A ; allows decompression to be spread over multiple frames. 40 bytes. Kos_decomp_stored_SR: equ $FFFFDC80 ; word Kos_decomp_bookmark: equ $FFFFDC82 ; the address within the Kosinski queue processor at which processing is to be resumed. A longword. Kos_description_field: equ $FFFFDC86 ; used by the Kosinski queue processor the same way the stack is used by the normal Kosinski decompression routine. A word. Kos_decomp_queue: equ $FFFFDC90 ; 2 longwords per entry, first is source location and second is decompression location. 32 bytes. Kos_modules_left: equ $FFFFDDFE ; the number of modules left to decompresses. Sign bit set indicates a module is being decompressed/has been decompressed. Byte. Kos_decomp_buffer: equ $FFFFDE00 ; $1000 byte buffer used by KosM. v_snddriver_ram: equ $FFFFF000 ; start of RAM for the sound driver data ($5C0 bytes) I'm seriously baffled. If anyone can help, that'd be nice.
Is anyone here experienced with monitor editing or adding new icons? Basically I wanna add new monitors to Sonic 2, but I'm out of space, so my plan was to compress by having some icons like Eggman and the shield mirror one half. It displays alright on the monitor itself, but when you break it... It seems like the programming for the floating icon only takes the first block on the sprite. Anyone know how to fix this so the mirrored tiles take their extra block? EDIT: Now I have more technical info on the situation, what I wanna do is edit Obj2E (the hovering icon when you break a monitor natch). Code (Text): loc_128C2: move.b d0,anim(a0) loc_128C6: ; Determine correct mappings offset. addq.b #1,d0 move.b d0,mapping_frame(a0) movea.l #Obj26_MapUnc_12D36,a1 add.b d0,d0 adda.w (a1,d0.w),a1 addq.w #2,a1 move.l a1,mappings(a0) loc_128DE: bsr.s sub_128E4 bra.w DisplaySprite Basically from what I get the jist of, it just shows the very front chunk of the monitor frame (which is always the icon). This of course causes issue when I try to make the icon out of two mirrored chunks. Is there any way to get this routine to load the first TWO chunks of a frame instead of just one?
I don't know the specifics for Sonic 2, but in Sonic 1 there's a render flag for "raw mappings" which has the object display a single sprite. You'd need to disable that flag and create a new set of mappings for all monitor icons.
So, SonLVL suddenly started working on my computer again, so I'm back to work on Sonic Like Legos. However, before I can release a demo, I would very much appreciate assistance with 2 things. Firstly, in the Github disassembly for Sonic 1, how would one edit the level order? I tried using the guide, but it's not written with this version in mind... And second, might anyone know how to fix this draw order issue on Robotnik's chain? Thanks in advance.
This does appear to be the perfect thread for my question after spending a long time piecing together the answer from different articles with zero success... Super new to ASM and the file structures so apologies in advance, but I'm looking to load a different palette in Sonic 1 once a monitor is broken. I'm using the disassembly, and I've found the events in the '2E Monitor Content Power-Up.asm' file. As this file is completely separate and cannot reference Sonic.asm etc, do I need to write/copy the whole palette swap routine within the 2E.asm file itself and then reference it that way? It seems disconnected and can't work out an easy way to just simply load the palette into memory. I guess I was hoping for a nice single line call, but know that isn't the case. Any help appreciated - thanks!
I'll leave the second question to someone else, but for the first one, if you mean the order in which levels are played, you simply have to move stuff around in an array stored in, of all things, the code for the "SONIC HAS PASSED ACT X" object. Actually, if you're using the Sonic Retro GitHub version, if you've already set up the palette within the pointer list, you can simply do this within the monitor power-up file: Code (Text): moveq #palid_Sonic2,d0 ; load replacement palette for Sonic bsr.w PalLoad1 Labels and routines can be cross-referenced between files so long as they're not local labels (i.e. start with @).
Super helpful, thanks so much. That's what I had thought, but unfortunately, when I try to call the routine from Sonic.asm in the Monitor Power-up File I get an error trying to build the ROM: Code (Text): Illegal value (-35330) Any ideas?
The label you're referencing is too far away from the instruction. Change the "bsr.w PalLoad1" to "jsr (PalLoad1).l".
Thanks, that compiles correctly now. Unfortunately, it still crashes the game with an ILLEGAL INSTRUCTION reference. I can replace the level palette in the game just fine, but I want the level palette to only change on monitor break and it's just not playing ball.