Last time on February 15th of 2021 I posted a tutorial on how to quote on quote "restore" the GHZ ball. Back then, !!!I DID NOT KNOW WHAT I WAS DOING WHATSOEVER!!! So I decided to make a NEW thread and revisit the inaccuracies and mistakes I missed in my "tutorial". Github Diassmebly 1: Importing the code from the prototype Now here's where we are gonna get our disassemblies out today. Firstly download the MDDC disassembly. It is mostly recommended considering in the inaccurate tutorial from months ago it targeted MDDC's. Now look for the code for Object ID 19. In MDDC it is included in the main text file sonic.asm. It will be labeled "ObjRollingBall" in MDDC. Now the code SHOULD look like this. Code: ObjRollingBall: moveq #0,d0 move.b $24(a0),d0 move.w off_5C8E(pc,d0.w),d1 jmp off_5C8E(pc,d1.w) ; --------------------------------------------------------------------------- off_5C8E: dc.w loc_5C98-off_5C8E, loc_5D2C-off_5C8E, loc_5D86-off_5C8E, loc_5E4A-off_5C8E, loc_5CEE-off_5C8E ; --------------------------------------------------------------------------- loc_5C98: move.b #$18,$16(a0) move.b #$C,$17(a0) bsr.w ObjectFall jsr ObjectHitFloor tst.w d1 bpl.s locret_5CEC add.w d1,$C(a0) move.w #0,$12(a0) move.b #8,$24(a0) move.l #MapRollingBall,4(a0) move.w #$43AA,2(a0) move.b #4,1(a0) move.b #3,$19(a0) move.b #$18,$18(a0) move.b #1,$1F(a0) bsr.w sub_5DC8 locret_5CEC: rts ; --------------------------------------------------------------------------- loc_5CEE: move.w #$23,d1 move.w #$18,d2 move.w #$18,d3 move.w 8(a0),d4 bsr.w sub_A2BC btst #5,$22(a0) bne.s loc_5D14 move.w (ObjectsList+8).w,d0 sub.w 8(a0),d0 bcs.s loc_5D20 loc_5D14: move.b #2,$24(a0) move.w #$80,$14(a0) loc_5D20: bsr.w sub_5DC8 bsr.w ObjectDisplay bra.w loc_5E2A ; --------------------------------------------------------------------------- loc_5D2C: btst #1,$22(a0) bne.w loc_5D86 bsr.w sub_5DC8 bsr.w sub_5E50 bsr.w ObjectMove move.w #$23,d1 move.w #$18,d2 move.w #$18,d3 move.w 8(a0),d4 bsr.w sub_A2BC jsr ObjSonic_AnglePosition cmpi.w #$20,8(a0) bcc.s loc_5D70 move.w #$20,8(a0) move.w #$400,$14(a0) loc_5D70: btst #1,$22(a0) beq.s loc_5D7E move.w #$FC00,$12(a0) loc_5D7E: bsr.w ObjectDisplay bra.w loc_5E2A ; --------------------------------------------------------------------------- loc_5D86: bsr.w sub_5DC8 bsr.w ObjectMove move.w #$23,d1 move.w #$18,d2 move.w #$18,d3 move.w 8(a0),d4 bsr.w sub_A2BC jsr ObjSonic_Floor btst #1,$22(a0) beq.s loc_5DBE move.w $12(a0),d0 addi.w #$28,d0 move.w d0,$12(a0) bra.s loc_5DC0 ; --------------------------------------------------------------------------- loc_5DBE: nop loc_5DC0: bsr.w ObjectDisplay bra.w loc_5E2A ; --------------------------------------------------------------------------- sub_5DC8: tst.b $1A(a0) beq.s loc_5DD6 move.b #0,$1A(a0) rts ; --------------------------------------------------------------------------- loc_5DD6: move.b $14(a0),d0 beq.s loc_5E02 bmi.s loc_5E0A subq.b #1,$1E(a0) bpl.s loc_5E02 neg.b d0 addq.b #8,d0 bcs.s loc_5DEC moveq #0,d0 loc_5DEC: move.b d0,$1E(a0) move.b $1F(a0),d0 addq.b #1,d0 cmpi.b #4,d0 bne.s loc_5DFE moveq #1,d0 loc_5DFE: move.b d0,$1F(a0) loc_5E02: move.b $1F(a0),$1A(a0) rts ; --------------------------------------------------------------------------- loc_5E0A: subq.b #1,$1E(a0) bpl.s loc_5E02 addq.b #8,d0 bcs.s loc_5E16 moveq #0,d0 loc_5E16: move.b d0,$1E(a0) move.b $1F(a0),d0 subq.b #1,d0 bne.s loc_5E24 moveq #3,d0 loc_5E24: move.b d0,$1F(a0) bra.s loc_5E02 ; --------------------------------------------------------------------------- loc_5E2A: move.w 8(a0),d0 andi.w #$FF80,d0 move.w (CameraX).w,d1 subi.w #$80,d1 andi.w #$FF80,d1 sub.w d1,d0 cmpi.w #$280,d0 bhi.w ObjectDelete rts ; --------------------------------------------------------------------------- loc_5E4A: bsr.w ObjectDelete rts ; --------------------------------------------------------------------------- sub_5E50: move.b $26(a0),d0 bsr.w GetSine move.w d0,d2 muls.w #$38,d2 asr.l #8,d2 add.w d2,$14(a0) muls.w $14(a0),d1 asr.l #8,d1 move.w d1,$10(a0) muls.w $14(a0),d0 asr.l #8,d0 move.w d0,$12(a0) rts ; --------------------------------------------------------------------------- include "levels/GHZ/RollingBall/Sprite.map" even ; --------------------------------------------------------------------------- Now I know what you are thinking. "I can just put this in and call it a day!". Well... NOPE! This code features invalid code not used in the final, so we need to replace some code with the final versions. 2: Changing prototype code DO NOT SKIP THIS PART! This is an important part, skipping this would lead to lots of errors. Now firstly, you may see the title "ObjRollingBall". Well in Github it is simply labeled "Obj19". Simply just replace the prototype title with "Obj19". So that is it right? Still no. There is more to replace. Here is the graphic code: Code: move.l #MapRollingBall,4(a0) move.w #$43AA,2(a0) In Github, there is no such thing as "MapRollingBall" whatsoever. We are gonna have to replace it with this. Code: move.l #Map_GBall,obMap(a0) move.w #$43AA,obGfx(a0) The second problem is a major part of the code, named sub_A2BC. This is an obvious prototype version of SolidObject. Replacing it to SpeedToPos is VERY unrecommended. If your looking for a more accurate ball, I recommend replacing it with SolidObject. Replace it with either, I really don't care. As long as your ball is moving and it makes you happy, that's good. Another major part is ObjectMove. This basically makes it move and what makes it roll. Now seen in MDDC, it is VERY similar to "BossMove", Something to make bosses move. BossToMove Path Scroll all the way to the bottom of your code, and copy and paste the BossMove code, replace the label "BossMove" with "ObjectMove", Simple. SpeedToPos Path In the comments, Painto pointed out ObjectMove is actually SpeedToPos. Replace ObjectMove w/ SpeedToPos. ------------------------------------------- There is now something called ObjectFloorDistance. This is obviously Obj_FloorDist. Replace it with that. ObjSonic_AnglePosition? Basically Sonic_AnglePos. Replace it with that. Obj_SonicFloor? Leave Sonic_Floor exactly the way it is, though delete the "Obj" part. Now for "GetSine". Replace it with CalcSine. ObjectDisplay is DisplaySprite... ObjectDelete.. DeleteObject.. Blah blah blah i could do this all da- wait a second.. CAMERAX?! What is CameraX you ask? Its a flag in the final game Simply replace it with $FFFFF700. There's also ObjectList. Just delete that simply, or replace it with v_player. Delete this: Code: ; --------------------------------------------------------------------------- include "levels/GHZ/RollingBall/Sprite.map" even ; --------------------------------------------------------------------------- Or the build will have.. certain problems. 3. Make those balls solid In case step 2 didn't work with the sub_A2BC part, use step 3. Can't be balls without it being SOLID! Put this code under all bsr.w SpeedToPos: Code: move.w #$20,d1 move.w #$1B,d2 move.w #$18,d3 bsr.w SolidObject Oh yeah! We're done! Now build the game and.. wait an error of bsr.w MvSonicOnPlatform? Wait how can Github make an error of a code that's been in the game for 30 years? The answer is the bsr.w SolidObject. Don't delete the SolidObject. Go to "sub SolidObject" in your "_incObj" folder in your diassembly and replace bsr.w MvSonicOnPlatform with "jsr MvSonicOnPlatform". 4. BUILD DAT GAME UP! Now your balls should be ready! Build the game up and.. wait a second is that.. T-T...TWO BALLS? Apparently, when those balls are offscreen, another ball respawns. And it does NOT delete the previous ball. Here's a problem I cannot fix. If anyone knows how to fix this just let me know. EDIT: Something about three previous points in loc_5E2A causes this. Also I'd like to thank Painto for correcting me on some things, without them this revisited thread would be inaccurate again. HIVEBRAIN TUTORIAL COMMIN' SOON!
No problem! However, if it says theres errors in sub SolidObject about the "bsr.w MvSonicOnPlatform", change bsr.w to jsr instead. Edit: set it to jsr not jmp
Don't do this, that's not the right instruction for any distance branching and returning. Do jsr instead, jmp is for bra instructions.
i've founded out that there are some "Undefined label" errors after running build.bat: Error : Symbol 'objecthitfloor' not defined Error : Symbol 'objectslist' not defined Error : Symbol 'objectdisplay' not defined Error : Symbol 'objsonic_angleposition' not defined Error : Symbol 'objsonic_floor' not defined Error : Symbol 'camerax' not defined Error : Symbol 'objectdelete' not defined so you need to replace: 'objecthitfloor' with 'ObjFloorDist' , 'ObjFindFloor' or 'Sonic_Floor' (?) [in this case try both] 'objectslist' with 'Object_Pointers' 'objectdisplay' with 'DisplaySprite' 'objsonic_angleposition' with 'Sonic_AnglePos' 'objsonic_floor' with 'Sonic_Floor' 'camerax' with (?) [seriously, i don't know how to replace this *facepalm*] 'objectdelete' with 'DeleteObject' i hope this will be helpful!
CameraX is a old and unused label from the prototype, after updating the code because there was a few innacuracies I made with the ported ball code, I realised CameraX is its only flag in the final. The flag is $FFFFF700
ok, but if you can, change the code for making the ball work since i'd some stressful moments while i was redefining the early code for making it working on the final version. thanks!
I'd like to adress few things I noticed: Actually judging by setup itself (values for d1-d4) it seems to be a call for SolidObject, not SpeedToPos. This also makes step 3 redundant. Even simpler, it's actually SpeedToPos. I personally don't see any reason for deletion for this one, and while I didn't looked into the proto disasm, I can safely assume from similar objects that "ObjectList" is "v_player"/$FFFFD000. Also: Code for that is in the object (loc_5E2A), so maybe it has something to do with three previous points.
I have merged the two threads together. There was no need to create a separate one, as the content in the second thread was a progression of the first thread.