Basic Questions and Answers Thread

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

  1. TheStoneBanana

    TheStoneBanana The Bananaman Member

    Joined:
    Nov 27, 2013
    Messages:
    604
    Location:
    The Milky Way Galaxy
    You basically have to handle them yourself within the object's code. There is a routine, known as ObjHitFloor in the Hivebrain 2005 disassembly, that will return the current object's distance from the floor in register d1.
    A basic usage of the routine to check if the object on the floor is as follows:
    Code:
           jsr       ObjHitFloor
           tst.b   d1                       ; is object on the ground?
           bpl.s   .AboveFloor       ; if not, branch
           add.w  d1,$C(a0)         ; assure the object is actually on the ground and not below it
           ...do whatever the object should do on the floor here...
    
    I'll answer the last part first. For each object slot in RAM, there is a reserved portion for X and Y positioning. Depending on the mode of positioning for the object, the reserved area is used slightly differently. If bit 2 of the object's render flags is set to 0, the word value stored at $8(a0) is the X position, $A(a0) is the X subpixel position (you don't really need to worry about this), $C(a0) is the Y position, and $E(a0) is the Y subpixel position. If bit 2 is set to 1, then $8(a0) is the X position, and $A(a0) is the Y position.
    That's kind of longwinded, and all you really need to know for most situations is that the X position is the word at $8(a0), and the Y position is the word at $C(a0).

    To answer your first question, moving left and right aboutt this can be as simple as adding to the X or Y position, and either before or afterwards, doing a check of the position to see if it's where you want it to be. However, it can get even easier than this for you!
    There is two reserved words at $10(a0) and $12(a0) for horizontal and vertical velocity, respectively. If you set velocity, and call a routine known in the Hivebrain 2005 disassembly as SpeedToPos after setting said velocity, the object will be moved for you. Neato, right? You can even apply gravity to the object while moving it using a routine called ObjectFall. You can observe existing objects that use these routines for different applications.

    I must stress that everything I've told you here applies to Sonic 1. I answered this way, as you made mention to the GHZ wrecking ball. The other games are similar, but I believe they use different locations within the object slots to store X and Y positioning and velocity.
     
    Arsen likes this.
  2. Calvin

    Calvin DreamCast Enthusiast with a GameCube Member

    Joined:
    Mar 1, 2014
    Messages:
    245
    Location:
    $C800
    [Nevermind, please trash this.]
     
    Last edited: Apr 2, 2017
    mrcat-pixel likes this.
  3. B. Comet

    B. Comet Is fun still infinite? Member

    Joined:
    Aug 19, 2016
    Messages:
    83
    Location:
    South America Zone
    How I can change that "invisible line" which triggers the stage limits? I know it is something from the original layout but... this thing is just being a pain in the ***. Not letting me work with the layouts, since I want to make the stage something more original without resembling the original Marble Zone too much.

    Okay.
    [​IMG]

    Then the screen start going up and kills Sonic.
    [​IMG]

    If it is something to do within the game's code, someone can please explain to me how to do it? I just messed around with the graphics and the stages layout. I don't know anything about... everything else. lol.
     
  4. DanielHall

    DanielHall Well-Known Member Member

    Joined:
    Jan 18, 2010
    Messages:
    860
    Location:
    North Wales
    IIRC, the routines you are looking for are the resize routines, i.e. Resize_MZ. They typically resize the boundary position based on where Sonic is on the x-axis, for instance:

    Resize_GHZ1:
    move.w #$300,($FFFFF726).w ; set lower y-boundary
    cmpi.w #$1780,($FFFFF700).w ; has the camera reached $1780 on x-axis?
    bcs.s locret_6E08 ; if not, branch
    move.w #$400,($FFFFF726).w ; set lower y-boundary

    locret_6E08:
    rts
     
    B. Comet and Calvin like this.
  5. ProjectFM

    ProjectFM Optimistic and self-dependent Member

    Joined:
    Oct 4, 2014
    Messages:
    799
    Location:
    Portland, Maine
    How would I go about adding plane deformation to the foreground? Would it require more RAM similar to the ones used at $FFFFA800 and/or $FFFFCC00 in Sonic 1? I want to use it for the background I have created for the title screen in my hack because plane A was freed up by using sprites for the title. I know Sonic Megamix 5.0 deforms both planes on its title screen.
     
    Last edited: Apr 17, 2017
  6. MarkeyJester

    MarkeyJester ! % # @ Member

    Joined:
    Jun 27, 2009
    Messages:
    2,788
    No. You will not require more RAM.

    In Sonic 1 for example, CC00 is the scroll buffer, each long-word is a scanline. The first word is the FG plane scroll position, and the second word is the BG plane scroll position.

    It's been there the entire time, Sonic games will load the screen X position into d0, and then place it in the upper word using the "swap" instruction (this is the FG position), and then they'll change the lower word of d0 for the BG position. They'll then write the long-word of d0 (the upper word FG and lower word BG) into the scroll table buffer, writing the scroll positions for both the FG and the BG at the same time. That's why you don't see the FG being altered, it's being constantly forced to the screen's X position in those scroll/deformation loop routines.
     
    Pacca and ProjectFM like this.
  7. Ashuro

    Ashuro Well-Known Member Member

    Joined:
    Sep 27, 2014
    Messages:
    514
    Location:
    France
    Hi my friends!

    How many sprites can i get into my "artunc/sonic.bin" file in Sonic 1?
    And how many animations can i use into my "_anim/sonic.asm" file (in Sonic 1 again)?

    I'm not sure about it, thanks.. :/
     
  8. Ralakimus

    Ralakimus Pour your misery down on me Member

    Joined:
    Aug 26, 2013
    Messages:
    974
    Due to how DPLCs are handled in stock Sonic 1, you can only have up to about $10000 bytes ($800 tiles) for "artunc/sonic.bin". In later games, the code for loading Sonic's art was changed to extend the limit to like twice the amount.

    You can also only have $80 frames of mappings (0-$7F) in stock Sonic 1, unless you modify the code for animations and sprite rendering to make it read more than that.

    As for animations, you can have up to $100 animation IDs (0-$FF).

    Look here if you need to extend the art and frame limits.
     
    Ashuro likes this.
  9. Ashuro

    Ashuro Well-Known Member Member

    Joined:
    Sep 27, 2014
    Messages:
    514
    Location:
    France
    Okay thanks!
     
  10. Ralakimus

    Ralakimus Pour your misery down on me Member

    Joined:
    Aug 26, 2013
    Messages:
    974
    @Ashuro I forgot to mention, that if you already ported the DMA queue (which was found in part 3 of the porting the spindash to S1 tutorial), then you don't need to extend the limit for artunc/sonic.bin, since in the new LoadSonicDynPLC, it already applies the extension to allow for about $20000 bytes.

    Why there was that $10000 byte limit was because in Sonic 1, to mask out the tile count in the DPLC entry, it does a word shift the left 5 times. While it does shift out that value, it also shifts out another bit that could've been in the offset value for the art. Sonic 2 and later uses an AND to mask out the tile count value and then does a longword shift 5 times, so that it includes that missing bit, and thus extends the art limit.
     
    Ashuro likes this.
  11. Ashuro

    Ashuro Well-Known Member Member

    Joined:
    Sep 27, 2014
    Messages:
    514
    Location:
    France
    Sorry for the next question but i search a method to make some actions when one unique Sonic sprite is displayed at screen, but i don't know which i have to use. Sans titre.png
    I know that $1C is for the animation itself, but for a unique SPRITE? :D
     
  12. ProjectFM

    ProjectFM Optimistic and self-dependent Member

    Joined:
    Oct 4, 2014
    Messages:
    799
    Location:
    Portland, Maine
    $1A. Sprite and frame mean pretty much same thing in this context. $1B is how far along in the animation an object is.
     
    Ashuro likes this.
  13. GenesisDoes

    GenesisDoes Wizard of the Sonic Member

    Joined:
    Jan 2, 2016
    Messages:
    133
    Location:
    Pittsburgh, PA
    So I backported the MTZ Nut (object $69) from Sonic 2 Github into Sonic 1 Github, and modified it so that it moves horizontally instead of vertically. Problem is I'm not sure how to modify it in order to collide with walls and stop moving.

    The original nut in Sonic 2 moved vertically and had a routine to check the distance from the floor. When it collides with the floor, it stops moving and releases the player from the move-locking behavior of the nut. It also had IIRC various subtypes to allow for a max movement height. Basically I'm looking for that same behavior, but now when the object collides with walls and without having to use subtypes to determine max movement distance.

    Anyone see how to modify the code to do such?

    EDIT: Knew I forgot something. Video
     

    Attached Files:

  14. TheStoneBanana

    TheStoneBanana The Bananaman Member

    Joined:
    Nov 27, 2013
    Messages:
    604
    Location:
    The Milky Way Galaxy
    The ObjHitWallLeft/Right routines work kinda like the ObjFloorDist routine.

    Essentially, before the routines are called, the object's visible horizontal radius (width_pixels in the disassembly you're using, I think) must be copied to d3. For checking for walls to the right of the object, using the plain horizontal radius will do. However, for left walls, you'll need to use a NOT instruction to get the opposite side of the radius.
    Similarly to ObjFloorDist, the distance from the wall will be returned as a word in d1, and you can use this to determine whether or not the object has collided with the wall.

    Implementation might look something like so:
    Code:
    ...
           moveq #0,d3
           move.b width_pixels(a0),d3
           tst.w x_vel(a0)
           bmi.s .CheckLeftWall
    
    .CheckRightWall:
           jsr ObjHitWallRight
           tst.w d1
           bpl.s .whatever   ; this is where the code leads to if the object has not hit the right wall
           bra.s .StopMovement
    
    .CheckLeftWall:
           not.w d3
           jsr ObjHitWallLeft
           tst.w d1
           bpl.s .whatever    ; this is where the code leads to if the object has not hit the left wall
    
    .StopMovement
           clr.w x_vel(a0)
    ...
    
    Hope this helps.
     
    Natsumi likes this.
  15. Natsumi

    Natsumi Phoenix egg Member

    Joined:
    Oct 7, 2011
    Messages:
    698
    Location:
    Long and dangerous river
    and don't forget to align the x-position after stopping the object.
     
  16. Samey

    Samey Le Bored Hedgie Member

    Joined:
    May 3, 2017
    Messages:
    34
    Ok, I'm trying to change the hud in Sonic 1 and I got (mostly) it all done, but I can't get the Special Stage results screen tiles to use a different palette line. (the word "score" and the "s" on bonus looks odd with the palette line they're using). I attempted to compare it to mappings I've edited in the past and I've also attempted messing with the mappings in the result screen's mappings to see what does what and can't find the little bit that tells it to use a certain palette line.
    I'm using the Hivebrain dissassembly and here's the mappings in question:
    Code:
    ; ---------------------------------------------------------------------------
    ; Sprite mappings - special stage results screen
    ; ---------------------------------------------------------------------------
    Map_obj7E:    dc.w byte_CCAC-Map_obj7E
            dc.w byte_CCEE-Map_obj7E
            dc.w byte_CD0D-Map_obj7E
            dc.w byte_CB47-Map_obj7E
            dc.w byte_CD31-Map_obj7E
            dc.w byte_CD46-Map_obj7E
            dc.w byte_CD5B-Map_obj7E
            dc.w byte_CD6B-Map_obj7E
            dc.w byte_CDA8-Map_obj7E
    byte_CCAC:    dc.b $D            ; "CHAOS EMERALDS"
            dc.b $F8, 5, 0,    8, $90
            dc.b $F8, 5, 0,    $1C, $A0
            dc.b $F8, 5, 0,    0, $B0
            dc.b $F8, 5, 0,    $32, $C0
            dc.b $F8, 5, 0,    $3E, $D0
            dc.b $F8, 5, 0,    $10, $F0
            dc.b $F8, 5, 0,    $2A, 0
            dc.b $F8, 5, 0,    $10, $10
            dc.b $F8, 5, 0,    $3A, $20
            dc.b $F8, 5, 0,    0, $30
            dc.b $F8, 5, 0,    $26, $40
            dc.b $F8, 5, 0,    $C, $50
            dc.b $F8, 5, 0,    $3E, $60
    byte_CCEE:    dc.b 6            ; "SCORE"
            dc.b $F8, $D, 1, $4A, $B0
            dc.b $F8, 1, 1,    $62, $D0
            dc.b $F8, 9, 1,    $64, $18
            dc.b $F8, $D, 1, $6A, $30
            dc.b $F7, 4, 0,    $6E, $CD
            dc.b $FF, 4, $18, $6E, $CD
    byte_CD0D:    dc.b 7
            dc.b $F8, $D, 1, $52, $B0
            dc.b $F8, $D, 0, $66, $D9
            dc.b $F8, 1, 1,    $4A, $F9
            dc.b $F7, 4, 0,    $6E, $F6
            dc.b $FF, 4, $18, $6E, $F6
            dc.b $F8, $D, $FF, $F8,    $28
            dc.b $F8, 1, 1,    $70, $48
    byte_CD31:    dc.b 4
            dc.b $F8, $D, $FF, $D1,    $B0
            dc.b $F8, $D, $FF, $D9,    $D0
            dc.b $F8, 1, $FF, $E1, $F0
            dc.b $F8, 6, $1F, $E3, $40
    byte_CD46:    dc.b 4
            dc.b $F8, $D, $FF, $D1,    $B0
            dc.b $F8, $D, $FF, $D9,    $D0
            dc.b $F8, 1, $FF, $E1, $F0
            dc.b $F8, 6, $1F, $E9, $40
    byte_CD5B:    dc.b 3
            dc.b $F8, $D, $FF, $D1,    $B0
            dc.b $F8, $D, $FF, $D9,    $D0
            dc.b $F8, 1, $FF, $E1, $F0
    byte_CD6B:    dc.b $C            ; "SPECIAL STAGE"
            dc.b $F8, 5, 0,    $3E, $9C
            dc.b $F8, 5, 0,    $36, $AC
            dc.b $F8, 5, 0,    $10, $BC
            dc.b $F8, 5, 0,    8, $CC
            dc.b $F8, 1, 0,    $20, $DC
            dc.b $F8, 5, 0,    0, $E4
            dc.b $F8, 5, 0,    $26, $F4
            dc.b $F8, 5, 0,    $3E, $14
            dc.b $F8, 5, 0,    $42, $24
            dc.b $F8, 5, 0,    0, $34
            dc.b $F8, 5, 0,    $18, $44
            dc.b $F8, 5, 0,    $10, $54
    byte_CDA8:    dc.b $F            ; "SONIC GOT THEM ALL"
            dc.b $F8, 5, 0,    $3E, $88
            dc.b $F8, 5, 0,    $32, $98
            dc.b $F8, 5, 0,    $2E, $A8
            dc.b $F8, 1, 0,    $20, $B8
            dc.b $F8, 5, 0,    8, $C0
            dc.b $F8, 5, 0,    $18, $D8
            dc.b $F8, 5, 0,    $32, $E8
            dc.b $F8, 5, 0,    $42, $F8
            dc.b $F8, 5, 0,    $42, $10
            dc.b $F8, 5, 0,    $1C, $20
            dc.b $F8, 5, 0,    $10, $30
            dc.b $F8, 5, 0,    $2A, $40
            dc.b $F8, 5, 0,    0, $58
            dc.b $F8, 5, 0,    $26, $68
            dc.b $F8, 5, 0,    $26, $78
            even
    I have tried looking up how to edit the Special Stage results screen's mappings but couldn't find anything.
    (maybe I just didn't look hard enough but I don't know honestly...)
     
  17. Ralakimus

    Ralakimus Pour your misery down on me Member

    Joined:
    Aug 26, 2013
    Messages:
    974
    Take a look at this.

    You can also extract the mappings to a separate ASM file and load it in a mapping editor like SonMapEd.
     
    Samey likes this.
  18. Samey

    Samey Le Bored Hedgie Member

    Joined:
    May 3, 2017
    Messages:
    34
    Thanks! Helped a lot!
     
  19. B. Comet

    B. Comet Is fun still infinite? Member

    Joined:
    Aug 19, 2016
    Messages:
    83
    Location:
    South America Zone
    How I can make the Marble Zone lava geyser to work?
    When I tried to make it work with objects, all I got was this:

    An glitched lava pillar falling from the top.
    [​IMG]
     
  20. Samey

    Samey Le Bored Hedgie Member

    Joined:
    May 3, 2017
    Messages:
    34
    When I was messing around with objects in SonLvl, I sorta got the falling lava to turn into the geyser.
    I switched the subtype to zero, and it ended up as the geysor. However, it also simply activated as soon as it was on screen.
    So, I don't think I've helped much besides saying that it's subtype 0 on the lava-fall object...