I'm trying to add the down attack from Sonic Mania to Sonic 2, a skill that Mighty has, but I want to make the screen shake the same as it does in Sonic Mania when it hits the ground Here is the code [/spoiler] Mighty_DownJump: tst.b $21(a0) ; is Sonic currently performing a double jump? bne.w loc_169C2 ; if yes, branch move.b ($FFFFF603).w,d0 andi.b #$70,d0 beq.w loc_169C2 ; if not, branch move.b #1,$21(a0) move.w #0,x_vel(a0) ; halt horizontal speed... move.w #0,inertia(a0) ; ...both ground and air move.w #$800,y_vel(a0) ; force Sonic down bpl.s loc_169C2 move.b #$14,(Screen_Shaking_Flag).w loc_169C2: rts
Normally, Screen_Shaking_Flag is processed by the level's scrolling routine to produce the effect. Do you have some code set up to read the value?
More importantly, that flag is never set, since the y_vel(a0) will always be positive. What I think you meant to do, is check for its value each frame to detect landing. However, in order to do this correctly and efficiently, you need to add some code checking for some flag (I assume $21(a0)), and if set, then save the value to the screen shaking flag. The routine where you should add it, is in a routine that is called whenever the player either lands on a floor or solid object. In sonic 2 Git disassembly, the routine you want is called Sonic_ResetOnFloor_Part3.
Hello everyone, this is my first real post! What tool can I use to convert Lost World HKX files to Gens format?
I can not make the tails carry the Sonic, the game simply hangs. Here is the code: Spoiler Code (Text): tails_Carry_sonic: tst.b (a2) beq.w loc_14534 cmpi.b #4,routine(a1) bcc.w loc_14466 btst #1,Status(a1) beq.w loc_1445A move.w ($FFFFF744).w,d1 cmp.w x_vel(a1),d1 bne.s loc_1445A move.w ($FFFFF74C).w,d1 cmp.w y_vel(a1),d1 bne.s loc_14460 tst.b ($FFFFB02A).w bmi.s loc_1446A andi.b #$70,d0 beq.w loc_14474 clr.b ($FFFFB02A).w clr.b (a2) move.b #$12,1(a2) andi.w #$F00,d0 beq.w loc_14410 move.b #$3C,1(a2) loc_14410: ; CODE XREF: Tails_Carry_Sonic+4Cj btst #$A,d0 beq.s loc_1441C move.w #-$200,x_vel(a1) loc_1441C: ; CODE XREF: Tails_Carry_Sonic+5Aj btst #$B,d0 beq.s loc_14428 move.w #$200,x_vel(a1) loc_14428: ; CODE XREF: Tails_Carry_Sonic+66j move.w #-$380,y_vel(a1) bset #1,Status(a1) move.b #1,jumping(a1) move.b #$E,y_radius(a1) move.b #7,x_radius(a1) move.b #2,anim(a1) bset #2,Status(a1) bclr #4,Status(a1) rts ; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ loc_1445A: ; CODE XREF: Tails_Carry_Sonic+16j ; Tails_Carry_Sonic+22j move.w #-$100,y_vel(a1) loc_14460: ; CODE XREF: Tails_Carry_Sonic+2Cj move.b #0,jumping(a1) loc_14466: ; CODE XREF: Tails_Carry_Sonic+Cj clr.b ($FFFFB02A).w loc_1446A: ; CODE XREF: Tails_Carry_Sonic+32j clr.b (a2) move.b #$3C,1(a2) rts ; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ loc_14474: ; CODE XREF: Tails_Carry_Sonic+38j move.w x_pos(a0),x_pos(a1) move.w y_pos(a0),y_pos(a1) addi.w #$1C,y_pos(a1) andi.b #-4,4(a1) andi.b #-2,Status(a1) move.b Status(a0),d0 andi.b #1,d0 or.b d0,4(a1) or.b d0,Status(a1) subq.b #1,anim_frame_duration(a1) bpl.s loc_144F8 move.b #$B,anim_frame_duration(a1) moveq #0,d1 move.b anim_frame(a1),d1 addq.b #1,anim_frame(a1) move.b byte_14522(pc,d1.w),d0 cmpi.b #-1,d0 bne.s loc_144E4 move.b #0,anim_frame(a1) move.b byte_14522(pc),d0 loc_144E4: ; CODE XREF: Tails_Carry_Sonic+11Ej move.b d0,mapping_frame(a1) moveq #0,d0 move.b mapping_frame(a1),d0 move.l a2,-(sp) jsr Tails_Carry_LoadPLC movea.l (sp)+,a2 loc_144F8: ; CODE XREF: Tails_Carry_Sonic+104j move.w x_Vel(a0),($FFFFB018).w move.w x_Vel(a0),($FFFFF744).w move.w y_Vel(a0),($FFFFB01A).w move.w y_Vel(a0),($FFFFF74C).w movem.l d0-a6,-(sp) lea ($FFFFB000).w,a0 bsr.w Sonic_DoLevelCollision movem.l (sp)+,d0-a6 rts ; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ byte_14522: dc.b $6B ; DATA XREF: Tails_Carry_Sonic+126t dc.b $6B dc.b $6C dc.b $6C dc.b $6C dc.b $6C dc.b $6C dc.b $6C dc.b $6B dc.b $6B dc.b $6B dc.b $6B dc.b $6B dc.b $6B dc.b $6B dc.b $6B dc.b $FF dc.b 0 ; ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ loc_14534: ; CODE XREF: Tails_Carry_Sonic+2j tst.b 1(a2) beq.s loc_14542 subq.b #1,1(a2) bne.w locret_1459C loc_14542: ; CODE XREF: Tails_Carry_Sonic+17Ej move.w x_pos(a1),d0 sub.w x_pos(a0),d0 addi.w #$10,d0 cmpi.w #$20,d0 bcc.w locret_1459C move.w y_pos(a1),d1 sub.w y_pos(a0),d1 subi.w #$20,d1 cmpi.w #$10,d1 bcc.w locret_1459C tst.b ($FFFFB02A).w bne.s locret_1459C cmpi.b #4,routine(a1) bcc.s locret_1459C tst.w (Debug_placement_mode).w bne.s locret_1459C tst.b spindash_flag(a1) bne.s locret_1459C bsr.s sub_1459E moveq #$4A,d0 jsr (PlaySound).l move.b #1,(a2) locret_1459C: ; CODE XREF: Tails_Carry_Sonic+184j ; Tails_Carry_Sonic+198j ... rts ; End of function Tails_Carry_Sonic ; ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ S U B R O U T I N E ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ sub_1459E: ; CODE XREF: ROM:00013FEAp ; ROM:000140F6p ... clr.w x_vel(a1) clr.w y_vel(a1) clr.w inertia(a1) clr.w angle(a1) move.w x_pos(a0),x_pos(a1) move.w y_pos(a0),y_pos(a1) addi.w #$1C,y_pos(a1) move.w #$2200,anim(a1) move.b #0,anim_frame_duration(a1) move.b #0,anim_frame(a1) move.b #3,($FFFFB02A).w bset #1,Status(a1) bclr #4,Status(a1) move.b #0,spindash_flag(a1) andi.b #-4,4(a1) andi.b #-2,Status(a1) move.b Status(a0),d0 andi.b #1,d0 or.b d0,4(a1) or.b d0,Status(a1) move.w x_vel(a0),($FFFFF744).w move.w x_vel(a0),x_vel(a1) move.w y_Vel(a0),($FFFFF74C).w move.w y_Vel(a0),y_Vel(a1) eori.b #2,4(a1) rts ; End of function sub_1459E
There are a few "4(a1)" in that code, this is supposed to be the mappings pointer in Sonic 2. I assume this code is ported from Sonic 3, the 4 should be a 1, or "render_flags" as the equates appear to be. It would explain why the sprites are spazed all over the place, it would also explain a possible reason for the crash. There could be other reasons, but I'm sticking a bet with that for now.
Does anyone know what this line means? Spoiler Code (Text): move.w x_Vel(a0),($FFFFB018).w move.w x_Vel(a0),($FFFFF744).w move.w y_Vel(a0),($FFFFB01A).w move.w y_Vel(a0),($FFFFF74C).w
These appear to be copying the X and Y speeds of an object to different RAM addresses. The $FFFFB018 and $FFFFB01A is within an object in Sonic 2 I believe. I assume this is Sonic's object slot since he is usually the first object in the object RAM, I would also assume that 18 is the x_Vel (X speed), and 1A is the y_Vel (Y speed). I would also assume judging by your previous post regarding tails carrying Sonic, that a0 must therefore be Tails' object slot (probably $FFFFB040), so, this must be Tails copying his X and Y speed to Sonic's X and Y speeds. X in mathematics is usually associated with horizontal (left/right) and Y with vertical (up/down). So the "move.w x_Vel(a0),($FFFFB018).w" and "move.w y_Vel(a0),($FFFFB01A).w" are copying Tails' Up/Down and Left/Right speed movement to Sonic, which makes sense as when Tails is to suddenly let go by perhaps landing while moving at speed, Sonic needs to move at that same speed in the same direction. As for the "move.w x_Vel(a0),($FFFFF744).w" and "move.w y_Vel(a0),($FFFFF74C).w", well these are keeping a copy of the X and Y speeds in these RAM slots, I am not sure what for but there's bound to be a good reason. Everything above I've just said is just an assumption, I am not really in any position right now to go looking through source codes to find out exactly what it's doing.
I'm attempting to edit one of Generations challenge acts in Sonicglvl (#ghz202.ar.00) but for some reason it won't load terrain collision or objects. Typically it asks if I want to load terrain but with this specific stage it doesn't bother. I've attempted in both sonicglvl and libgens-sonicglvl but the results are the same. Most of the other challenge acts I've attempted to load seem to behave strangely compared to the main modern stages, making me wonder if there's an additional step needed to loading challenge acts. Even so, ghz202 is the only one that behaves like this specifically. I'd be grateful for any advice
This is kind of a crap first post but it's irritating me that I don't have the knowhow to work it out myself... I've written a customised build of Sonic 3 Complete to a couple of M27C160 EEPROMs to solder into a cartridge once a suitable one arrives but one of the EEPROMs appears to be faulty in a very specific and minute way: it is refusing to allow one single nibble to be written properly, perhaps because it isn't erasing it properly, which means that instead of getting a D0 at that offset I'm getting a D4. Specifically, if I read the entire rom back off the EEPROM, reassemble it and then reverse the byte-swapping process, this erroneous D4 sits at offset $380278. So here's my question: what does the D0 byte at offset $380278 in a customised Sonic 3 Complete ROM actually do? I'd simply rewrite it to a fresh EEPROM if I could, but I don't have one that isn't knackered and they're not the sort of thing I can simply walk into a shop and buy (only got 2 left, this is one of them and the other flat out refuses to even write to a different address). What I figure is, this single byte being written as a D4 rather than a D0 might not make a damn bit of difference to me playing the game, given that there's a whole bunch of code in Sonic 3 Complete that I will never, ever use. For instance, if it turned out to be part of one of the Sonic & Knuckles Collection music files, that would be totally immaterial because I don't use them. Or it could be part of the level layout for the original release version of Flying Battery, which I don't play because I prefer the "prototype". You get the idea. I'm trying not to waste an EEPROM, essentially, if this isn't going to cause an issue for me. I've booted up the reassembled ROM (i.e. written to EEPROM incorrectly, read back off EEPROM and reassembled) in Bizhawk and in Kega Fusion, and have not thus far found anything obviously amiss in either but obviously it's such a teensy imperfection that it will presumably require a very specific scenario in which to bump into whatever job that byte does and potentially encounter a catastrophe. The standard ROM doesn't even contain this offset because the file isn't as big so doesn't extend that far, but it's there in every file the customiser spits out when I whack in some options. It isn't specific to my preferred custom options, either, because I tried to isolate it a very tedious manual way by changing every single option I'd modified in the customiser to see if any of them modified that offset but it doesn't matter what settings I use and what IPS patches are getting applied, this byte always downloads as a D0 (despite it not even being present in the un-customised 130810 ROM). I can't see what difference it makes if it's a D4. There might be a better place to ask this, in which case feel free to let me know. It's a very small thing I'm asking about but it requires some explanation so sorry about the length of the post; I was a bit nervous of starting a whole new topic for something so trivial. I dunno if maybe Neo might be my guy here, but I don't want to immediately show up and then PM him asking a question about a project that appears to have essentially ended some time ago.
1C A9 27 00 BF 0A D0 F4 D0 F8 1D F4 1E 00 2B 4C Assuming I checked the right build, that address lands right in the middle of the the Kosinski-compressed 128x128 chunk definitions for Launch Base Zone 2. Now, I have no clue what the implications of a random corrupted bit in a compressed archive are, but I'm pretty sure something will be wrong.
Woah, thank you so much! I guess I'll be redoing that EPROM instead of soldering it in anyway, then. Damn. ... I now want to play LBZ in emulation and see if anything nuts happens though. (I just now realised the obvious dumb flaw in what I said about that offset only being in customised builds: the offset will presumably just change because stuff got packed into the start of the file, so this code is still in the standard build except at a different offset. Sleep has value...) I really appreciate everything you're doing with Sonic 3 by the way, I've been following the Unlocked blog for a wee while. It's extremely helpful to see you breaking stuff down like you do!
Sorry if this is a stupid question, I was trying to fix up Sonic 2 before I make any kind of hack of it, and one of the bugs was the broken one way barrier in Chemical Plant and Death Egg. I spent a while on it and believe I'm stuck. It says here that the object subtype of the barrier should be $02 and not $00 (for Nemesis art decompression I presume) : https://tcrf.net/Sonic_the_Hedgehog_2_(Genesis)#CPZ.2FDEZ_Door The problem is that I cannot find that subtype property anywhere : Code (Text): ; =========================================================================== ; loc_116AC: Obj2D_Init: addq.b #2,routine(a0) move.l #Obj2D_MapUnc_11822,mappings(a0) move.w #make_art_tile(ArtTile_ArtNem_HtzValveBarrier,1,0),art_tile(a0) move.b #8,width_pixels(a0) cmpi.b #metropolis_zone,(Current_Zone).w beq.s + cmpi.b #metropolis_zone_2,(Current_Zone).w bne.s ++ + move.w #make_art_tile(ArtTile_ArtKos_LevelArt,3,0),art_tile(a0) move.b #$C,width_pixels(a0) + cmpi.b #chemical_plant_zone,(Current_Zone).w bne.s + move.w #make_art_tile(ArtTile_ArtNem_ConstructionStripes_2,1,0),art_tile(a0) move.b #8,width_pixels(a0) + cmpi.b #death_egg_zone,(Current_Zone).w bne.s + move.w #make_art_tile(ArtTile_ArtNem_ConstructionStripes_1,1,0),art_tile(a0) move.b #8,width_pixels(a0) + cmpi.b #aquatic_ruin_zone,(Current_Zone).w bne.s + move.w #make_art_tile(ArtTile_ArtNem_ARZBarrierThing,1,0),art_tile(a0) move.b #8,width_pixels(a0) + bsr.w Adjust2PArtPointer ori.b #4,render_flags(a0) move.b #4,priority(a0) move.w y_pos(a0),objoff_32(a0) move.b subtype(a0),mapping_frame(a0) move.w x_pos(a0),d2 move.w d2,d3 subi.w #$200,d2 addi.w #$18,d3 btst #0,status(a0) beq.s + subi.w #-$1E8,d2 addi.w #$1E8,d3 + move.w d2,objoff_38(a0) move.w d3,objoff_3A(a0) ; loc_1175E: Obj2D_Main: btst #0,status(a0) bne.s + move.w objoff_38(a0),d2 move.w x_pos(a0),d3 tst.b routine_secondary(a0) ; check if barrier is moving up beq.s ++ move.w objoff_3A(a0),d3 bra.s ++ ; =========================================================================== I tried changing zeroes to twos here and there (even in the object's hex file), changing the position of some lines of code, but all it did was either change the palette, glitch up the graphics of the barrier, or freeze completely going down the slope at the beginning of CPZ2 (because the barrier loads in that area). I don't see any disassembly notes about fixing the barrier either, whereas other glitches are described in detail in the disasm. I'm very new to assembly, so excuse me if the answer is super obvious.
Normally you'd fix the object's subtype by editing the object layout data with SonLVL/SonED2. You can fix it in code, if you find the parts relevant to CPZ and DEZ, and insert the line: move.b #2,subtype(a0)
Thank you very much. So by changing the CPZ and DEZ sections like so : Code (Text): cmpi.b #chemical_plant_zone,(Current_Zone).w bne.s + move.w #make_art_tile(ArtTile_ArtNem_ConstructionStripes_2,1,0),art_tile(a0) move.b #8,width_pixels(a0) move.b #2,subtype(a0) + cmpi.b #death_egg_zone,(Current_Zone).w bne.s + move.w #make_art_tile(ArtTile_ArtNem_ConstructionStripes_1,1,0),art_tile(a0) move.b #8,width_pixels(a0) move.b #2,subtype(a0) It fixed the door! : https://imgur.com/a/xwz06BT
Excuse me for poking my head in again, but the door fix missed one door. This is the second door after Metal Sonic : https://imgur.com/gallery/rHM7siB I presume this particular door is part of some sort of sequence data rather than object data. There are many reasons I come to this conclusion, first, there is no SonLVL data about this 2nd door, it just ends up being a blank space in the editor. Then, I removed the subtype line of code for Death Egg and flipped all the doors around, didn't help (which of course, since i checked the original game after and that one door was always broken). And finally, I realized that this one door works differently to the other doors, in the sense that it doesn't go up immediately upon arrival like all the other doors, it only opens after Eggman does the scared face for a second which is in turn triggered by the arrival at the door. Of course, the reason why I'm here is because I can't find this sequence data anywhere in the assembly, probably because the door is a completely different object than obj2D in this instance or it's something else that's either more cryptic or way too obvious. Anyways, thanks again for the advice.
That door in particular is spawned as a sub-object of object C6, Eggman. It has its own mappings in objC6_b.bin, so you'll have to edit that to fix it.