don't click here

Basic Questions & Answers thread

Discussion in 'Engineering & Reverse Engineering' started by Tweaker, May 29, 2008.

  1. Devon

    Devon

    La mer va embrassé moi et délivré moi lakay. Tech Member
    1,491
    1,829
    93
    your mom
    Technically, no. For sprites, you have 128 pixels on both axes of space beyond the left and top of the screen, so a sprite placed at (128, 128) will be placed on the top left of the screen. I think the sprite coordinate space only goes up to 512 pixels on both axes (it's the smallest power of 2 that can account for the top left space, screen space, and bottom right space without issue). There's not really any reason to go beyond that, it's simple and it does the job fine as is.

    If I recall, X=0 causes sprites after it on the same scanline to not be visible, which I think is how Sonic 2 handled masking Sonic and Tails on the title screen. Could be wrong, though, it's been a while since I checked.
     
  2. MarkeyJester

    MarkeyJester

    Original, No substitute Resident Jester
    2,254
    516
    93
    Japan
    EDIT: Nevermind, the caché was funny and didn't show Devon's post.

    So as to not waste the post, Devon is correct about Sonic 2's title screen using X = 0 as a mask.

    However, to clarify, it only works if a sprite of higher priority is X = Non-0 first on those scanlines. But other than that, solid post :thumbsup:
     
    Last edited: Nov 20, 2024
  3. BenoitRen

    BenoitRen

    Tech Member
    860
    468
    63
    If that's the case, that makes me wonder why X and Y are signed in Sonic CD for the sprite objects. Then again, other things that wouldn't ever be negative, like systemtimer and timebonus, are also signed.
     
  4. Kilo

    Kilo

    Starting new projects every week Tech Member
    1,231
    1,177
    93
    Canada
    Changes with the weather
    Is it possible you're misinterpreting large positive unsigned values as signed negative values? What exactly are you doing?
     
  5. Brainulator

    Brainulator

    Regular garden-variety member Member
    Is this just about the C conversion? If so, this could just be the converters (that is, the people doing the converting) not paying attention or caring about the result.
     
  6. MarkeyJester

    MarkeyJester

    Original, No substitute Resident Jester
    2,254
    516
    93
    Japan
    Signed/unsigned is merely an illusion, and dependent on circumstance.

    All objects have 2 bits of the render flag dedicated to how the X/Y is interpreted. These are bits 2 and 3.

    There are 4 modes with these two bits:
    • 00 = Non-relative (HUD based).
    • 01 = Relative to FG camera.
    • 10 = Relative to 1st BG camera.
    • 11 = Relative to 2nd BG camera.
    01, 10, and 11, will subtract the relevant camera's X/Y from the object, and will add $80 (128) to X/Y to ensure that; if the camera is at 0x0 and your object is at 0x0, then the sprites appears on-screen relative to 0x0.

    00 is a special case, I'd call it raw sprite position myself, but some might call it "HUD" position. It is not relative to any camera position, it's fixed into placed, but it will NOT add $80 (128) to X or Y. You have to do that on your own, which is why the HUD and other non-scrolling objects have their X/Y +$80 (or at least their mappings will be).

    The sprite build subroutine is responsible for this.

    Going back to signed vs unsigned, it's merely conceptual. You have to believe a sprite can only go from 000 to 1FF, and going beyond or below this will wrap. An X/Y of -1 (FFFF) becomes 1FF for instance. The problem with higher level lanuages such as C is they assign a variable/constant as something "fixed" when in reality, memory is just memory, and the CPU will usually interpret it in both ways when setting the condition flags (bar exceptions). Because of this, in higher languages you have to resort to casting when you want the compiler to assume a variable/constant is a specific type. In assembly you can treat a condition as both signed and unsigned, a simple test with both condition responses can be used, it's the resulting conditional branch/set that dictates the result, not the test.
     
  7. BenoitRen

    BenoitRen

    Tech Member
    860
    468
    63
    I understand it's an illusion at the assembly level, but like you surmise I'm thinking in C terms.

    As for what I'm trying to do, I'm trying to figure out if, in C, I can use unsigned for the coordinates. It'd simplify things, because bit operations on signed integers are implementation-defined, and thus not portable.
     
  8. MarkeyJester

    MarkeyJester

    Original, No substitute Resident Jester
    2,254
    516
    93
    Japan
    I'm sorry if my post came across as patronising, it wasn't clear in your previous posts what your ultimate goal was.

    Sprites themselves won't be an issue thanks to the 128 area, I'd be more concerned with game logic than rendering. There are a few instances involving negative coordinates, such as objects going off to the left/top of the level where an unsigned X/Y won't allow them to exist partially, even though the sprites themselves have 128 tolerance, the objects don't. Screen wrapping on endless Y wrap levels may also be an issue, or the ability to go above the level in general.

    I suppose using unsigned would only simplify things if casting to signed is less frequent than casting to unsigned for bit operations.
     
  9. Jammin'

    Jammin'

    Extremely into X-Treme Member
    What memory address is the value denoting whether or not you have a character connected to you in Knuckles' Chaotix?
     
  10. RetroKoH

    RetroKoH

    Member
    1,732
    112
    43
    S1Fixed: A successor to ReadySonic
    So, let's talk about LoadTilesFromStart. I removed the stuff at the end in S1Fixed. Nothing seems to be broken:

    Code (Text):
    1. LoadTilesFromStart:
    2.         lea    (vdp_control_port).l,a5
    3.         lea    (vdp_data_port).l,a6
    4.         lea    (v_screenposx).w,a3
    5.         lea    (v_lvllayout).w,a4
    6.         move.w    #$4000,d2
    7.         bsr.s    DrawChunks
    8.         lea    (v_bgscreenposx).w,a3
    9.         lea    (v_lvllayout+$80).w,a4        ; MJ: Load address of layout BG
    10.         move.w    #$6000,d2
    11. ;        tst.b    (v_zone).w
    12. ;        beq.w    Draw_GHz_Bg
    13. ;        cmpi.b    #id_MZ,(v_zone).w
    14. ;        beq.w    Draw_Mz_Bg
    15. ;        cmpi.w    #(id_SBZ<<8)+0,(v_zone).w
    16. ;        beq.w    Draw_SBz_Bg
    17. ;        cmpi.b    #id_EndZ,(v_zone).w
    18. ;        beq.w    Draw_GHz_Bg
    19. ; End of function LoadTilesFromStart
    I know Revision 00 didn't have this. Am I hurting anything if I remove it?
     
  11. Devon

    Devon

    La mer va embrassé moi et délivré moi lakay. Tech Member
    1,491
    1,829
    93
    your mom
    REV01 has quite a bit of zone specific logic for tile drawing, so it probably isn't the best idea to remove those.
     
    Last edited: Nov 27, 2024
  12. Kilo

    Kilo

    Starting new projects every week Tech Member
    1,231
    1,177
    93
    Canada
    Changes with the weather
    So I'm writing a custom DAC driver for a mini project since in 7 years of hacking I haven't touched the Z80 or audio, so I'm forcing myself to do so, and I just had a question about timings.
    I'm looking at Sonic 2's sound driver for reference on this, and I'm a bit confused
    Code (Text):
    1. pcmLoopCounter function sampleRate, pcmLoopCounterBase(sampleRate,146/2) ; 146 is the number of cycles zPlaySegaSound takes to deliver two samples.
    2. dpcmLoopCounter function sampleRate, pcmLoopCounterBase(sampleRate,289/2) ; 289 is the number of cycles zWriteToDAC takes to deliver two samples.
    Where is 146 and 289 coming from? I get they're CPU cycles, but how did these numbers get landed on? What does it mean to deliver 2 samples if the DAC can only play 1 byte of audio at a time?
     
  13. MarkeyJester

    MarkeyJester

    Original, No substitute Resident Jester
    2,254
    516
    93
    Japan
    1 byte of DPCM is 2 samples, one nybble each.

    The sample rate has been chosen for 2 samples because the driver has not been written to playback the audio in a properly steady manner. The time between flushing sample 1 and decoding/flushing sample 2, will not be the same time as between flushing sample 2, looping, collecting the next byte, and decoding/flushing sample 1, so both cycle times are packed together and then divided by 2 to get a mean average.

    As for the numbers themselves, I suspect it would be the total sum cycles of every instruction (hopefully including the delay of reading from the window if applicable), through the entire loop. If you obtain a Z80 manual and sum up the cycles, in that loop of both sample flushes, then you should get that total.
     
    • Informative Informative x 1
    • List
  14. this code should detect if the user is approaching from the top, and in that case bounce them up, and if they are approaching from any other direction, branch to Touch_Enemy. but, for some reason, it always seems to think that we're approaching from the top, and additionally approaching from the back gives the user a huge height boost. I'm not knowledgeable about the collision relation between two objects, can anyone give me a pointer?

    Code (Text):
    1.  
    2. loc_3F9CE:
    3.     sub.w    d0,d5
    4.     cmpi.w    #$80,d5
    5.     bhs.s    BranchTo_Touch_Enemy
    6.     move.w    x_pos(a1),d0
    7.     subq.w    #4,d0
    8.     btst    #0,status(a1)
    9.     beq.s    +
    10.     subi.w    #$2,d0
    11. +
    12.     clr.w    d2
    13.     move.b    width_pixels(a1),d2
    14.     neg.w    d2
    15.     subi.w    #$10,d2
    16.     sub.w    d2,d0
    17.     bcc.s    +
    18.     addi.w    #$18,d0
    19.     subi.w    #$20,y_pos(a0)
    20.     move.w    #-$1000,y_vel(a0)
    21.     bset    #1,status(a0)
    22.     bclr    #3,status(a0)
    23.     move.b    #AniIDSonAni_Spring,anim(a0)
    24.     move.b    #SndID_Spring,d0
    25.     jmp    (PlaySound).l
    26. +
    27.     bra.s    BranchTo_Touch_ChkHurt
    28.  
     
    Last edited: Dec 7, 2024
  15. MarkeyJester

    MarkeyJester

    Original, No substitute Resident Jester
    2,254
    516
    93
    Japan
    Code (Text):
    1.     cmpi.w  #$80,d5
    This is how many pixels from the top of the object, Sonic has to be before the object is treated like a normal badnik.

    Yadrin enemies had this set to 8 pixels, you've got it set to $80 pixels.

    I doubt your object is $80 pixels tall, make this smaller, maybe $10 or 8 or something more modest.
     
  16. wow, I can't believe I've missed that. yes, that's exactly what caused it, thank you very much!
    I've got another issue-- how would I make the Y velocity you get be constant?
    right now, it depends on whether you're holding Jump-- if not, you just get a small bounce; if you don't, I assume the full velocity is being applied as Sonic (and/or Tails) reaches the top of the sky.
     
    Last edited: Dec 8, 2024
  17. MainMemory

    MainMemory

    Kate the Wolf Tech Member
    4,797
    383
    63
    SonLVL
    I believe you would need to switch Sonic from a jumping state to a "falling while rolling" state to disable the check for the jump button being held.
     
  18. in MID2SMPS, my resulting song comes back octaves too high. is there any way to fix this within the program? is the MIDI at fault (every MIDI player I've used plays it correctly)?
    I've had to zip the OGG up to avoid file size errors =P
    note that the tempo is too fast only because I was toying around with M2S's settings a bit. I know how to avoid that.
     

    Attached Files:

  19. RetroKoH

    RetroKoH

    Member
    1,732
    112
    43
    S1Fixed: A successor to ReadySonic
    Question: should I implement dynamic hitboxes in S1Fixed?

    For context, some objects in Sonic 1 use (most of) a single dedicated byte (obColType) that points to a hardcoded width and height for collision with Sonic stored in Touch_Index.

    I am considering having these objects use two bytes to store an immediate height and width, removing the need for a lookup table and allowing for more dynamic object sizing, all while making it easier (in theory) for new users to modify hitboxes.

    I am considering adding an OST byte to allow objects to have one byte dedicated to collision width and one dedicated to collision height.
     
  20. Kilo

    Kilo

    Starting new projects every week Tech Member
    1,231
    1,177
    93
    Canada
    Changes with the weather
    Why not use the pre existing width and height variables they use for tile collisions.