I recently tried to port the Bubble Shield from Sonic 3 to Sonic 2, but unfortunately the Shield does not appear already tried everything but it does not work. Here is the code: Code: obj_bubble_shield: move.l #Map_BubbleShield,Mappings(a0) move.l #DPLC_BubbleShield,$3C(a0) move.l #Artnem_bubbleShield,$38(a0) move.b #4,render_flags(a0) move.w #1,priority(a0) move.b #$18,width_pixels(a0) move.w #$79C,Art_tile(a0) move.w #$F380,$40(a0) btst #7,($FFFFB00A).w beq.s loc_19908 bset #7,art_tile(a0) loc_19908: ; CODE XREF: ROM:00019900j move.w #1,anim(a0) move.b #-1,$34(a0) movea.w parent(a0),a1 bsr.w ResumeMusic move.l #loc_19922,(a0) loc_19922: ; DATA XREF: ROM:0001991Co movea.w parent(a0),a2 btst #1,status_secondary(a2) bne.s locret_1998A cmpi.b #$1C,anim(a2) beq.s locret_1998A btst #0,status_secondary(a2) beq.s loc_1998C move.w x_pos(a2),x_pos(a0) move.w y_pos(a2),y_pos(a0) move.b Status(a2),Status(a0) andi.b #1,Status(a0) tst.b ($FFFFF7C6).w beq.s loc_19962 ori.b #2,Status(a0) loc_19962: ; CODE XREF: ROM:0001995Aj andi.w #drawing_mask,art_tile(a0) tst.w art_tile(a2) bpl.s loc_19974 ori.w #high_priority,art_tile(a0) loc_19974: ; CODE XREF: ROM:0001996Cj lea (Ani_BubbleShield).l,a1 jsr AnimateSprite bsr.w PLCLoad_Shields jmp DisplaySprite ; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ locret_1998A: ; CODE XREF: ROM:0001992Cj ; ROM:00019934j rts ; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ loc_1998C: ; CODE XREF: ROM:0001993Cj andi.b #$8E,$2B(a2) move.b #Objid_InstaShield,(a0) rts ; ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ S U B R O U T I N E ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ PLCLoad_Shields: ; CODE XREF: ROM:0001959Ap ; ROM:00019686p ... moveq #0,d0 move.b Mapping_frame(a0),d0 cmp.b $34(a0),d0 beq.s locret_199E8 move.b d0,$34(a0) movea.l $3C(a0),a2 add.w d0,d0 adda.w (a2,d0.w),a2 move.w (a2)+,d5 subq.w #1,d5 bmi.s locret_199E8 move.w $40(a0),d4 loc_199BE: ; CODE XREF: PLCLoad_Shields+4Aj moveq #0,d1 move.w (a2)+,d1 move.w d1,d3 lsr.w #8,d3 andi.w #$F0,d3 addi.w #$10,d3 andi.w #$FFF,d1 lsl.l #5,d1 add.l $38(a0),d1 move.w d4,d2 add.w d3,d4 add.w d3,d4 jsr (QueueDMATransfer).l dbf d5,loc_199BE locret_199E8: ; CODE XREF: PLCLoad_Shields+Aj ; PLCLoad_Shields+1Ej rts ; End of function PLCLoad_Shields
Did you convert the bubble shield's mappings? Using mappings from the wrong game's format can cause the object to not appear at all. Example: Using Sonic's raw mappings from Sonic 2 won't make him appear in Sonic 1 unless you convert them. You can do this by opening SonMapED, switching mode to S3K (CTRL+ALT+SHIFT+3), loading the shield's mappings (and art if you feel the need to), switching back to Sonic 2 format (CTRL+ALT+SHIFT+2) and saving the new mappings. (Please correct me if I'm wrong, I haven't added the elemental shields myself and I don't convert mappings often.)
Code: move.l #Artnem_bubbleShield,$38(a0) It looks like either your bubble shield sprite is using Nemesis compressed tiles, or you put the tiles in the wrong folder. If it's the former, then you need to decompress the tiles so you can use them with dynamic pattern load cues. On that note, make sure your dynamic pattern load cues are in Sonic 2's format. Code: move.w #1,priority(a0) That should be move.b because Sonic 2 uses one byte to store an object's priority. Code: move.w #$F380,$40(a0) The SST for each object is $40 bytes long in Sonic 2, so any thing in $40(a0) or after is being used by the next object. You don't need to store that value anyway because it isn't changed during the game at all. Remove that line and replace: Code: move.w $40(a0),d4 with Code: move.w #$F380,d4 Otherwise, the code looks pretty good. Edit: I mistook this for Sonic 1, but fortunately everything applies to both games.
@ProjectFM Sonic 2, not Sonic 1. Though the same rule for the $40 SST limit applies here, too. @Trakinas Another issue I see is that you didn't convert the object to use the ID system. In Sonic 3, each object just uses a pointer to the object code, and can just switch it out for the next time it runs, so it doesn't need to use a routine ID and table. However, Sonic 2 doesn't do this and is stuck with using an ID that references a list of pointers to object code. And because of the fact it's not as easy to just swap out the value without assigning the new ID you want to another object, it's best to use the routine ID system. What you need to do is make it so that at the start of the object, it uses the code that gets the routine ID and jumps to a label from a table. This can be seen for pretty much every common object in the game. As for the table itself, be sure that the first entry points to a new label before the "move.l #Map_BubbleShield,Mappings(a0)", and have the second entry point to "loc_19922". The final thing left to do is change the "move.l #loc_19922,(a0)" to "addq.b #2,routine(a0)", so that the object goes to the 2nd routine the next time it runs to avoid initializing the object twice. Another thing I see is that "$3C(a0)" is used as a longword, which then overwrites "$3E(a0)", which is "parent(a0)", in which that is used by the object. You'll need to find another SST that will not overwrite anything important. "($FFFFB00A).w" is the equivalent of "(MainCharacter+art_tile).w" "($FFFFF7C6).w" is the reverse gravity flag in Sonic 3K, which doesn't exist in Sonic 2, so the line that uses it and the other 2 after it are useless (unless you are also implementing reverse gravity mechanics). Finally, while "$2B(a2)" is correct, it's probably best to convert that to "status_secondary(a2)" anyways.
Can I ask where you obtained this code? The disassembly you are using does not seem to be any of the known ones available. If you downloaded it from the internet, where did you get it from?
You should probably just use the Github disassembly. It's not perfect, but its' definitely got better documentation.