Basic Questions & Answers thread NEWBIES: Start here!
#4231
Posted 28 June 2012 - 05:07 PM
#4233
Posted 28 June 2012 - 06:33 PM
MoDule, on 28 June 2012 - 10:07 AM, said:
E-122-Psi, on 19 June 2012 - 06:57 AM, said:
I'm pretty sure this happens, because in 2p mode object deletion is handled by the objects manager instead of the objects themselves, from what I understand. Apparently it's doing it wrong for the HTZ lifts, most likely because they move very far horizontally. Mind, this is just speculation.
As for how to fix it, other than replacing the objects manager with a new one, I wouldn't know. With the changes I made to the s3k objects manager (so far unreleased, I think) it definitely works.
Cool might edit it in if you release it. Anything else work differently in 2P mode with the new objects manager?
#4234
Posted 02 July 2012 - 07:42 PM
#4235
Posted 03 July 2012 - 01:10 PM
#4236
Posted 04 July 2012 - 12:47 AM
The way it works is by applying a simple Trigonometry concept called the "Unit Circle." By calculating the sine and cosine of a specific angle, you can get the X and Y values for a point on a circle at that angle. (That's how it was explained to me — there's probably better explanations out there.) The Sonic engine happens to coincidentally have a routine that'll calculate a sine and cosine, albeit only with 256 angle values, however this isn't real problematic. It actually lifts the data from a LUT for optimisation purposes.
We can obviously use this method to make an object (or anything else you may choose to) go in a circle. To do that, we'll first need to look at how the Sonic engine does it's sine and cosine calculation. Here's the routine from Sonic 1, commented by me:
CalcSine: ; XREF: SS_BGAnimate; et al andi.w #$FF, d0 ; Get lower byte add.w d0, d0 ; Multiply by 2 addi.w #$80, d0 ; Add 128 move.w Sine_Data(pc, d0.w), d1 ; Get value out of table (Cosine value) subi.w #$80, d0 ; Subtract 128 move.w Sine_Data(pc, d0.w), d0 ; Get another value out of the table (Sine Value) rts ; End of function CalcSine ; =========================================================================== Sine_Data: incbin misc\sinewave.bin ; values for a 360° sine wave
Like I said above, this routine uses a byte as the angle offset, but due to the Mega Drive's limited screen size, if you're displaying anything with this sine data it shouldn't be too noticeable. Now, as with the concept of the Unit Circle I explained above, we can simply add the sine and cosine value to the X and Y values of the object, respectively to make it go clockwise (reverse it to make it go counterclockwise!) But if you were to simply add those to SST $8 and $C, the object wouldn't stay in one place. To fix that, you have to back up the object's X and Y positions up to another space in it's SST entry when it's loaded, like so:
move.w $8(a0), $30(a0) ; Back up X move.w $C(a0), $32(a0) ; Back up Y
Now, instead of adding the output of the CalcSine function to the SST's X and Y positions, you restore the backed up positions to registers and add them, then write the values of those registers to the X and Y position. That's all dandy, but you may notice the object not on screen or making a huge circle. Reason for that is that CalcSine outputs signed word values. To make these values work a bit better with object rotation, we can shift them to the right to divide them, like so:
move.b $29(a0), d0 ; Get the angle to d0 move.w $30(a0), d6 ; Write backed up X to d6 move.w $32(a0), d5 ; Write backed up Y to d5 moveq #2, d2 ; Shift offset (written to register to reduce memory fetches for instruction) jsr CalcSine ; Get sine and cosine (d0, d1) asr.w d2, d0 ; Shift the sine value asr.w d2, d1 ; Shift the cosine value add.w d0, d6 ; Add sine to X add.w d1, d5 ; Cosine to Y move.w d6, $8(a0) ; Set X move.w d5, $C(a0) ; Set Y
As a rule of thumb, each shift is a division of two. So, shifting by two bits will divide the sine by four, shifting three by eight, four by 16, and so on. Note the use of asr, as this keeps the signage of the number intact. If you were to use lsr, you would only get about a fourth of a circle. Also note if you don't want the number to be shifted, you can remove the ars's and the moveq above the jump to CalcSine. Here's a few pictures illustrating the different shift values:
Shift right 1 bit:

Shift right 2 bits:

Shift right 3 bits:

Shift right 4 bits:

Those are five different sprites, each with a different value added to the angle each frame to give the impression of them moving in a nice circle. Hopefully this information helps someone out there =P
#4237
Posted 04 July 2012 - 06:11 AM
E-122-Psi, on 02 July 2012 - 07:42 PM, said:
Your answer accidently got moved to the Regen topic here. Incase, here is the posts:
redhotsonic, on 03 July 2012 - 07:34 AM, said:
move.w #$600,(a4) move.w #$C,2(a4) move.w #$80,4(a4)
In order of Sonic's top speed, acceleration, and deceration.
Tails set speeds are at "loc_136CA:"
Knuckles is at "loc_164AA:"
His shoes speeds (when you run out, not when you get them) are at "loc_10CE8:" loc_1394E: loc_1669A:
His in water speeds are at "loc_10E2E:" loc_1463A: loc_166F6:
His out water speeds are at loc_10EA6: loc_146BA: loc_1676E:
His super set speeds are at loc_11A6A: loc_151A4: loc_17912:
His revert to normal speeds are at loc_11BA8: not sure not sure
Unlike Sonic 1 and Sonic 2, each character right at the beginning of their object code set their speed RAM to a4 and does this every frame:
lea (Sonic_Knux_top_speed).w,a4
Then, instead of setting the speeds directly to the RAM address (like it does in S1 and S2), it sets it to a4 address register.
flamewing, on 03 July 2012 - 07:51 AM, said:
E-122-Psi, on 02 July 2012 - 07:42 PM, said:
If I am not mistaken, that section is for the 2p stats. The in-game stats are set in several places, and I think that there is common code for all characters in some locations. If you search for "#$600,(a4)" and "Sonic_Knux_top_speed" you can find most locations where it is set.
Edit: should have read RHS's reply before putting my own; his is more complete.
#4239
Posted 08 July 2012 - 09:01 AM
When I try to edit a compressed file from this folder, (Let's use the Monkey Dude.bin for an example) Obviously it has to be decompressed first. - Unless I'm mistaken, it is Nemesis compressed...
I decompress it, and everything in the tile is set to 0. I tried this with Triad, SonMapEd, The KENS Data Compression Tool importing the sprite into SonLVL's object definition... the problem is with the file, after I decompress it, is completely 0.
I don't know why... Nothing in Sonic 1 or 2 does this, and some of the files in S3K don't do this.
I'm sorry if this doesn't warrant its own topic, but I have a feeling that this is an error with files in the disassembly or something... and thought it would warrant a topic if that is the case. PLEASE correct me if I am wrong.
NOTE: all files in the game appear as they should, as other than decompressing, I didn't edit anything.
Any thoughts?
#4240
Posted 08 July 2012 - 09:32 AM
#4241
Posted 08 July 2012 - 09:47 AM
Funny though, why does SonMapEd automatically attempt to treat it as Nemesis compression? If you select the first option, it auto-detects.
Also when I tried to put this in the SonLVL ini... (One that I created for AIZ objects) it didn't draw the object. Is there something special I need to put in the .ini somewhere to dictate the compression format used?
#4243
Posted 08 July 2012 - 06:59 PM
Cinossu Edit: Done.
#4244
Posted 12 July 2012 - 10:12 PM
If you could help (and especially if it doesn't require a disassembly), I'd be very appreciative.
#4245
Posted 13 July 2012 - 07:45 AM
Tiberious, on 12 July 2012 - 10:12 PM, said:
If you could help (and especially if it doesn't require a disassembly), I'd be very appreciative.
I'd like to see something on this also. I'm not in the exact situation, but my situation is that I ported HPZ from the beta to the final Sonic 2, and have it working, though I am running into object art that is rather funky and garbled.
It's the load request that is doing it to me also... and I am using a disassembly (HG/Merc./SVN)
Perhaps one for disasm, and one without if possible.
