Basic Questions and Answers Thread

Discussion in 'Discussion & Q&A' started by Malevolence, Jul 7, 2009.

  1. SpirituInsanum

    SpirituInsanum Well-Known Member Member

    Joined:
    Feb 11, 2010
    Messages:
    642
    Thanks for the answers.

    There's no more to see than what's in that screen, really.

    Anyway, I think I find what's causing the bug: lag.

    In order to test if the changes are supported, I replaced a bunch of lsl/lsr #6 with mulu/divu #sstsize (sstsize now being $4c). While I knew it would cause major slowdowns, I didn't know those slowdowns would also break the object. It's apparently a problem with an interruption causing a loss of data when the children addresses are being calculated.

    I was planning to change the children system later, but it looks like I have to do it sooner than expected.
     
  2. vladikcomper

    vladikcomper Well-Known Member Member

    Joined:
    Dec 2, 2009
    Messages:
    415
    If interrupts were really breaking the code they interrupted, the game would be way too unstable. Sonic 1 lags quite often as you walk through the level, but as you see, nothing gets broken during that.

    When vertical interrupt occurs, VBlank routine saves all the registers, as they were before the interrupt, into the stack and restores them after the VBlank code was processed. Same goes for the horizontal interrupt routine, except for it saves only a few registers, because its code simply doesn't touch the others. Saving all the registers guarantees nothing will be broken in the code that was interrupted, it will go on in the exact same state as it did before the interrupt.

    The only thing that will be lost after the interrupt is the current VRAM/CRAM/VSRAM offset to write/read from. But this relates to VDP state, not M68K state. Just remember to disable interrupts if you're accessing VDP outside of vertical interrupt code, as that code performs a lot of DMA transfers and simple VRAM writes, as the VDP memory location you were accessing in you code will be lost, if it gets interrupted.

    But that was a very special case. It has nothing to do with most of coding in the game, including objects code. If you're not doing some hardware-specific stuff in your code, virtually nothing changes if the code gets interrupted. I'm pretty sure the problem you have is caused by some changes you have made to the objects code.

    Trust me, if some code was broken during the interrupt, the game would crash nearly every time it lagged.
     
    Last edited by a moderator: Mar 2, 2013
  3. SpirituInsanum

    SpirituInsanum Well-Known Member Member

    Joined:
    Feb 11, 2010
    Messages:
    642
    The object is exactly like the original aside from those divisions/multiplications, and the bug disappears when I remove them. Aside from the interruptions, I really can't find anything that would cause this. :/
     
  4. vladikcomper

    vladikcomper Well-Known Member Member

    Joined:
    Dec 2, 2009
    Messages:
    415
    So division and multiplication commands were the reason, you say? This totally makes sense now!


    These commands are quite special in the way they handle operand sizes. If you do:
     


    divu.w #$40,d0
    The destination operand (register D0 in this example) is long word, not word in spit of .w after the instruction. That .w only determines the size of the source operand (divisor), while the destination operand is always long word. Actually, DIVU.w is the only possible form on the MC68000, some of the later revisions implemented DIVU.l form, where both operands were long-sized.

    In Obj15_MakeChain, where the child objects are created, the code relies that register size is word at some point, when calculating offsets:


    bsr.w SingleObjLoad
    bne.s loc_7A92
    addq.b #1,$28(a0)
    move.w a1,d5
    subi.w #$D000,d5 ; d5 = Object offset in object RAM
    lsr.w #6,d5 ; d5 /= $40
    andi.w #$7F,d5
    move.b d5,(a2)+

    If you simply replace LSR with DIVS/DIVU, register D5 be treated as a long word in that instruction, while the code only loaded a word into it on move.w a1,d5. The other half of the register isn't touched, which means there can be anything in it, you can't say for sure, these are random leftovers from different calculations that took place earlier. This is why the bugs happens. The value loaded in D5 isn't proper. The division is incorrect.

    So, this really is a memory corruption like I said few posts earlier. The corruption, caused by incorrect calculations in Obj15_MakeChain.

    Here is what you can do in order to have your division perform correctly:

    Code:
    		bsr.w	SingleObjLoad
    		bne.s	loc_7A92
    		addq.b	#1,$28(a0)
    		moveq	#0,d5		; ++
    		move.w	a1,d5
    		subi.w	#$D000,d5
    		divu.w	#SST_Size,d5	; ~~
    		andi.w	#$7F,d5
    		move.b	d5,(a2)+
    
     
    Last edited by a moderator: Mar 2, 2013
  5. SpirituInsanum

    SpirituInsanum Well-Known Member Member

    Joined:
    Feb 11, 2010
    Messages:
    642
    I tried that as well, but I'll check if I forgot or incorrectly reset a data register just in case. :/

    Thanks anyway. I began work on my new routine to create lists of children objects though, all I really needed was to know for sure where the problem was. No more divu, mulu, lsl and lsr in this routine, just plain addresses. xD

    Edit: it appears I indeed forgot one in that object, oddly enough I also forgot one in bridges and they never broke. I think I'll leave this there and just convert to the new system rather than trying to understand the logic behind this.
     
    Last edited by a moderator: Mar 2, 2013
  6. Mike B Berry

    Mike B Berry A grandiose return Member

    Joined:
    Jun 6, 2012
    Messages:
    377
    Location:
    New places, newer motivation
    Where to begin? Ah yes; after the terrible event that lead to the restart of the project, I have been working on this hack harder than ever before. Assuming that I have ported him in the first place, I am having a tough time getting Tails to load so much as his art separately from Sonic's in my Sonic 1 hack...

    Yes, I have decided to have Tails and Sonic  Share the same object pointers. Since I have tried changing the art and mappings, failing miserably in the process; when using the extra characters guide (Which I already know, was a bad choice to begin with,) would it easier to load Tails pointers with the DynPLC code, or should I set it up in a separate asm file?

    EDIT, I am porting his some of the manditory S3K art of Tails in this, with the S2 animations for the tails object.
     
    Last edited by a moderator: Mar 8, 2013
  7. JoenickROS

    JoenickROS ROS (bug fixing in progress) Member

    Joined:
    Feb 5, 2012
    Messages:
    929
    Quick question.. In sonic 2 in the asm file what controls how many rings there are in each act?
     
  8. MainMemory

    MainMemory Well-Known Member Member

    Joined:
    Mar 29, 2011
    Messages:
    922
    RingsManager_Setup I guess? It reads the ring layout file for the level and sets the Perfect counter and ring tables in RAM.
     
  9. JoenickROS

    JoenickROS ROS (bug fixing in progress) Member

    Joined:
    Feb 5, 2012
    Messages:
    929
    Cants seem to find anything that looks like it controls the number of rings there are in each act in the rings manager section of the asm file. The reason I asked this question is because I want the newly added WZ to know how many rings there are in the stage right now its just if I collect 1 ring or no rings it gives me a perfect bonus at the end when there is clearly more rings then that. I also added HPZ but it worked without me changing the ring controls. Myabe I added WZ wrong? Couldnt be I added it the same way as HPZ.
     
    Last edited by a moderator: Mar 9, 2013
  10. MainMemory

    MainMemory Well-Known Member Member

    Joined:
    Mar 29, 2011
    Messages:
    922
    The perfect count is calculated from the ring layout file. Perhaps Wood Zone's rings are using the ring object instead of entries in the ring layout file?
     
  11. JoenickROS

    JoenickROS ROS (bug fixing in progress) Member

    Joined:
    Feb 5, 2012
    Messages:
    929
    Hmm could be ill have to study the ring manger section a little to see how it fuctions so I can get a better idea of what im dealing with. I guess just skimming it isnt going to help me figure it out XD
     
  12. rika_chou

    rika_chou Adopt Member

    Joined:
    Aug 11, 2007
    Messages:
    689
    Soned2 will tell you how many rings are in the level. If the level is using the object file for rings it will say 0.
     
  13. MainMemory

    MainMemory Well-Known Member Member

    Joined:
    Mar 29, 2011
    Messages:
    922
    SonLVL does that as well. *cough*
     
  14. JoenickROS

    JoenickROS ROS (bug fixing in progress) Member

    Joined:
    Feb 5, 2012
    Messages:
    929
    Yeah it says there are no rings, so all I have to do now is add them in the project file, thanks for the help.

    EDIT: It worked
     
    Last edited by a moderator: Mar 9, 2013
  15. JoenickROS

    JoenickROS ROS (bug fixing in progress) Member

    Joined:
    Feb 5, 2012
    Messages:
    929
    (Sorry for double post but another quick question)

    What controls what life icon is loaded for each character and the end of level sign.

    I think this section is telling the game what character you are playing as and to load that certain signpost

    loc_192A0:
     tst.b obj0D_finalanim(a0)
     bne.w loc_19350
     move.b #3,obj0D_finalanim(a0)
     cmpi.w #2,(Player_mode).w
     bne.s loc_192BC
     move.b #4,obj0D_finalanim(a0)

    And about the lives counter I cant find the section for that.


    If im not mistaken #2,(Player_mode).w, is tails player number because thats what object number he is.

    and this bne.s loc_192BC means if your not playing as tails branch to that location, unless im wrong.
     
    Last edited by a moderator: Mar 10, 2013
  16. MainMemory

    MainMemory Well-Known Member Member

    Joined:
    Mar 29, 2011
    Messages:
    922
    Tails is player ID 2, but that has nothing to do with his object ID, which is 2 by coincidence. Most of the time new characters (like Knuckles in KiS2) add a new PLC that overwrites Sonic's image on the signpost.
     
  17. JoenickROS

    JoenickROS ROS (bug fixing in progress) Member

    Joined:
    Feb 5, 2012
    Messages:
    929
    Oh cant I just add a sprite onto the signpost file and have it point to loading it when knuckles is being played?

    Ive already added knuckles signpost to the file and it didnt overwrite any of the signs.
     
    Last edited by a moderator: Mar 10, 2013
  18. MainMemory

    MainMemory Well-Known Member Member

    Joined:
    Mar 29, 2011
    Messages:
    922
    Well you could, but depending on the order of art loading, it will either overwrite or be overwritten by whatever comes after it normally in VRAM. Unless you use the uncompressed art version with DPLCs from 2P mode. Or you could be lucky and nothing is loaded immediately after the signpost art, but there's still a limit on how much you can add to the art file before it does run into something.

    Most of my Knuckles porting guide can be followed even if you're using the old disassembly, the only difference is you would use numbers instead of ID constants.
     
    Last edited by a moderator: Mar 10, 2013
  19. JoenickROS

    JoenickROS ROS (bug fixing in progress) Member

    Joined:
    Feb 5, 2012
    Messages:
    929
    Yeah when I was having problems with knuckles I did look online so see if anyone made a guide On porting him and I found yours and I did figure out how too fix the issues I was having with knuckles by that (thanks for that btw) but then I went to the section on importing his signpost art and it was harder to understand how to do it for the Xenowhirl disassembly since some labels You said to go to didn't exist in the Xenowhirl ASM file . I can't remember does your guide also explain how to get the end of level text to say knuckles passed instead of Sonic passed, when playing as knuckles?
     
    Last edited by a moderator: Mar 10, 2013
  20. MainMemory

    MainMemory Well-Known Member Member

    Joined:
    Mar 29, 2011
    Messages:
    922
    It does. Although that particular part is more difficult with your disassembly, because the end of act mappings are binary rather than asm. Basically you would have to copy the entire mappings from KiS2, rather than the abbreviated version in my guide.