Emerald Collecting, Master System Style

Discussion in 'Discussion and Q&A Archive' started by Machenstein, Nov 24, 2011.

Thread Status:
Not open for further replies.
  1. Machenstein

    Machenstein Active Member Member

    Joined:
    Aug 10, 2011
    Messages:
    34
    There are two things I want to do with my Sonic 1 hack, and they both involve the Chaos Emeralds.


    1.) I want to move the Chaos Emeralds out of the Special Stages and into the regular stages so Sonic can collect them like in the Master System version of Sonic 1.


    2.) I want to put extra lives in the Special Stages in place of the Chaos Emeralds, giving the player a different incentive to go into the Special Stages.


    How would I do this as someone new to ASM editing?
     
    Last edited by a moderator: Nov 24, 2011
  2. GT Koopa

    GT Koopa Well-Known Member Member

    Joined:
    Mar 9, 2011
    Messages:
    83
    Location:
    Elgin. IL
    So, do you want to make emerald monitors like I did? Or like have an actual emerald out there? Either way it is all counters. When the sprite is collected, the counter goes up one. There is already one for emeralds, but you could set aside a variable for your custom emeralds as well. Also, you need to make room for the art of a emerald within the level, so the space would be used for the art of emeralds the entire game. So...the unused monitor art space? I assume you could just draw an actual emerald there, not put in a monitor, and use it for a emerald object.


    Of course this is all from my asm exploring. There could be a better way others would consider.
     
  3. Machenstein

    Machenstein Active Member Member

    Joined:
    Aug 10, 2011
    Messages:
    34
    I want the actual emerald out there. An emerald for each zone in Act 2.
     
  4. GT Koopa

    GT Koopa Well-Known Member Member

    Joined:
    Mar 9, 2011
    Messages:
    83
    Location:
    Elgin. IL
    DERP HOW DID THAT HAPPEN


    Anyway, yeah. That's how I would do it, apart from showing you actual code. Keep in mind I haven't done any ASM related stuff since last March, and with my laptop out of commission due to a really bad virus it is going to be that away for a while, unless Mac Sonic Hacking has improved since I got my laptop.


    Can't help you with the special stage though. Never looked into how it and objects inside it worked.
     
  5. SpirituInsanum

    SpirituInsanum Well-Known Member Member

    Joined:
    Feb 11, 2010
    Messages:
    642
    Something like this? :p


    [​IMG]


    It can be a little complex for a beginner. You'll need 4 free tiles in VRAM, more if you want to animate it without a DPLC. You can use regen (dump the VRAM) to find a few free tiles. First, experiment with a simple object: make it show on screen, make sure it won't stay forever in RAM (ie destroy it when it's beyond the respawn distance), then make it collectible, and find a way so once it's been collected, it won't reappear.


    As for the life in the special stage, it should be extremely easy. You could modify object 9 to make the life object end the level, then edit the special stage layouts and replace the emerald with a life icon.
     
  6. MarkeyJester

    MarkeyJester ♡ ! Member

    Joined:
    Jun 27, 2009
    Messages:
    2,867
    Both GT Koopa's and SpirituInsanum's statments are both plausible and worth following, I strongly advise both.


    Also, it warms me to see good members helping out without sniping at the guy, a real pleasure =)
     
  7. nineko

    nineko I am the Holy Cat Member

    Joined:
    Mar 24, 2008
    Messages:
    1,902
    Location:
    italy
    Adding a 1-up in the Special Stage would be easy indeed, as the object is already there and working, it's just that none of the existing Special Stages make use of it. With any Special Stage editor out there (such as Puto's or Mercury's) you can easily remove the emeralds and add extra lives instead. To set the 1-up object to end the special stage, you need to add only one line of code. In the Hivebrain 2005 disassembly, look for the Obj09_Get1Up subroutine, and add this line right above the move.w:



    Code:
    		addq.b	#2,$24(a0)	; run routine "Obj09_ExitStage"
    The new code should look like this:

    Code:
    Obj09_Get1Up:
    
    		addq.b	#1,($FFFFFE12).w ; add 1 to number of lives
    
    		addq.b	#1,($FFFFFE1C).w ; add 1 to lives counter
    
    		addq.b	#2,$24(a0)	; run routine "Obj09_ExitStage"
    
    		move.w	#$88,d0
    
    		jsr	(PlaySound).l	; play extra life music
    
    		moveq	#0,d4
    
    		rts
    If you're not using the Hivebrain 2005 disassembly I can't help you instead, sorry.
     
  8. Giga

    Giga Newcomer Member

    Joined:
    Jan 2, 2011
    Messages:
    20
    Location:
    ILLEGAL PLACE 1111!
    :D AWESOME! picture the adding a 1 up idea is genius thats gives plans for hackers.


    The problem is Where to find it (emerald).
     
  9. Machenstein

    Machenstein Active Member Member

    Joined:
    Aug 10, 2011
    Messages:
    34
    I got the second thing done. Now there are extra lives in the Special Stages in place of the Chaos Emeralds and the Special Stages end upon collecting the extra life. Now all I have to left to do is to put the Chaos Emeralds in the regular levels.


    I've downloaded Regen and right now I'm at the RAM Viewer under Tools. Should I dump the entire RAM or just certain parts of it?
     
  10. SpirituInsanum

    SpirituInsanum Well-Known Member Member

    Joined:
    Feb 11, 2010
    Messages:
    642
    Dump the entire VRAM, if possible do it in every zone. Make all dumps show above each other in your favorite image editor, then locate the empty VRAM (really empty, no data at all, there's more there than only graphics).


    If I remember correctly, I had some space after the hud's life icon (which isn't visible in Regen for some reason, therefore the dump), but maybe that's because I removed the 'sonic' text from the life icon, not sure. Anyway, once you located a free area, count the 8x8 tiles from the closest known address, multiply that number by $20 (in hexadecimal) and add that closest known address I was talking about.


    This will give you the address of the free VRAM, which will be useful to display the object (load the art using the PLC and set the starting art block in the object's status table accordingly).


    Then try to load graphics in the right spot (you can still check using regen), create the basic object and make it show in game.


    Once you have your item showing in game, you can consider it's almost done. Just use a basic item of your choice for reference if you aren't sure.
     
  11. nineko

    nineko I am the Holy Cat Member

    Joined:
    Mar 24, 2008
    Messages:
    1,902
    Location:
    italy
    It is possible to free some VRAM by shifting stuff around. There is a very simple optimisation you can do, which will give you exactly the 4 tiles of VRAM you need. See, the life icon and the 1-up monitor use the same picture, but its graphic data is stored twice in the VRAM. You can make the 1-up monitor read the graphic data from the life icon, and store the chaos emerald graphic data in its place (or vice-versa). In my hack I made the 1-up monitor read the life icon graphic data by changing a line in _mapsobj26.asm (still, Hivebrain 2005 disassembly). Change:



    Code:
    byte_A5C9:	dc.b 2			; Sonic	monitor
    
    		dc.b $F5, 5, 0,	$1C, $F8
    
    		dc.b $EF, $F, 0, 0, $F0
    To:

    Code:
    byte_A5C9:	dc.b 2			; Sonic	monitor
    
    		dc.b $F5, 5, 1,	$54, $F8
    
    		dc.b $EF, $F, $20, 0, $F0
    Enjoy your 4 free VRAM tiles.


    Bonus: if you add more characters (Tails, Knuckles, Fancharacter_The_Recolor), their 1-up monitors will already be fine as long as you take care of the different life icon :p
     
    Last edited by a moderator: Nov 24, 2011
  12. Machenstein

    Machenstein Active Member Member

    Joined:
    Aug 10, 2011
    Messages:
    34
    Okay, I've changed byte_A5C9 to make the 1-up monitor read the life icon graphic data. Now what programs would I use to insert the Chaos Emerald object into the game. The only hacking tools I have at my disposal right now are ConTEXT and SonLVL.
     
    Last edited by a moderator: Nov 25, 2011
  13. Animemaster

    Animemaster Lets get to work! Member

    Joined:
    Mar 20, 2009
    Messages:
    1,229
    Location:
    UK
    Ah hm.... well you do this in Asm, and yeah use context for that or word. You may be able to use the emerald object, if not you could create a new one. (But if the emerald is only going to be used in levels then the one done already should be fine). Considering there is art for chaos emerald already, I don't think there will be in need of importing, but it helps to have a program called SonMapED which is good for editing sprite art and maps.


    Head on over to sonicretro and look in the programs section, and if you need to learn how to use it, head over to the "How To:" section for a tutorial on how it operates. You can use it to create the art and maps which you will most likely need to do for the emerald, and take the art of the emeralds from the file. (In the Artnem folder of your disasmembly) I've probly underststood this wrong (its like 1:30am i'm tired =/), so I apologies and feel free to correct me. Also sorry if this was a rubbish explanation.
     
  14. Machenstein

    Machenstein Active Member Member

    Joined:
    Aug 10, 2011
    Messages:
    34
    Correct me if I'm wrong, but are you saying there's already an emerald object I can use outside of the Special Stages? Or are you just talking about the graphics for the emerald object? Either way, thanks for the advice. I'll go ahead and get SonMapED.


    EDIT: I can't locate the art for the emeralds in the Artnem folder... or anywhere. What's the BIN file called anyway?


    I imported the emerald art from a custom image file anyway. It's in place of the 1-up monitor art.


    [​IMG]


    Now what should I do next to make this emerald into an object? Keep in mind that this is my first time adding a new object to a Sonic hack.
     
    Last edited by a moderator: Nov 25, 2011
  15. Machenstein

    Machenstein Active Member Member

    Joined:
    Aug 10, 2011
    Messages:
    34
    Sorry to double post, but here is my progress so far. I've edited "_inc/Object pointers.asm" and put in "Chaos_Emerald" in place of Obj06 (Which was an ObjectFall) as shown here.


    [​IMG]


    Then I went into the main ASM file, made a copy of Obj25 (the ring object) and replaced all instances of Obj25 in the copy with Chaos_Emerald. Is there anything I should do next to make the object display the Emerald art and show up in the object list for SonLVL?
     
    Last edited by a moderator: Nov 26, 2011
  16. Animemaster

    Animemaster Lets get to work! Member

    Joined:
    Mar 20, 2009
    Messages:
    1,229
    Location:
    UK
    You have to include the emerald art file in the pattern load cues(PLC) in the inc folder. Have a look at it to get an idea, the number above the file at the top is how many files are loaded for that part, and the numbers below them are the art locations. So you will most likely need to find a free location, or maybe some how use the special stage emerald location for it.


    Note: I'm guessing you will want an emerald(or different colours) for each zone/act, so you will need to include the file for every act. Then you'll need to change the art tile in your emerald object, it will look something like this "Move.w #$54B,2(a0)" this also needs to be done, but i'm alittle lost about this bit this different to the one in pattern load cues but i'm sure there is away to display it the same. Hopefully someone else will fill in.
     
  17. Machenstein

    Machenstein Active Member Member

    Joined:
    Aug 10, 2011
    Messages:
    34
    So I'm starting over from scratch, but in doing so, I've made a pretty interesting find. I doubt it's anything new, but I still have to mention it anyway.


    Upon looking at ssemeral.bin in SonMapED, there are only three emeralds instead of six. I assume this is because the six emeralds are really just the three seen in ssemeral.bin using different palettes. There is also an extra fourth emerald which is all white, but it's obviously just for the flashing animation of the other three emeralds. One last thing are the sparkles found in ssemstar.bin which must be the sparkles created when Sonic collects the emeralds in the Special Stages, not unlike the sparkles that are created when Sonic collects rings.


    What am I getting at here? Well, the emeralds are already an object that sparkles and disappears when Sonic touches them. Instead of creating a brand new object which is based on the ring object, couldn't I just use the emerald object that's already in the game? If so, then it's only a matter of finding what object number the emeralds are and finding a way to make them an object for the other levels. Is this feasible or would I still have to create a brand new emerald object for the regular levels?
     
    Last edited by a moderator: Dec 3, 2011
  18. SpirituInsanum

    SpirituInsanum Well-Known Member Member

    Joined:
    Feb 11, 2010
    Messages:
    642
    Special stage "objects" aren't regular objects, excepted for Sonic himself. You may know by now all objects are stored between FFD000 and FFEFFF in memory. So, launch the original S1 in Regen, go to the special stage (and pause the emulator), open the RAM viewer and check what's between FFD000 and FFEFFF.


    Hint: the first 40 bytes are Sonic.


    Anyway, you'll learn more by making your own basic object.


    Also, don't forget you don't have a lot of video RAM to play with. You can't really load all those useless graphics in a regular level.
     
  19. Machenstein

    Machenstein Active Member Member

    Joined:
    Aug 10, 2011
    Messages:
    34
    So I'll have to create a new object then.


    Since I have a marginally better understanding of how objects work now, all I need are some step-by-step instructions on what to do next. I have already changed the special stages so that the extra life object ends the special stages, I just need to know what to do next in a specific order. From reading the posts on the last page, I need to find some free VRAM in order to create the new emerald object.


    I'm trying to get this hack released by Christmas and that's why I'm in such a hurry. I'm sorry if this thread is going on too long.


    EDIT: Using Nineko's instructions on how to make the extra life monitors read the life icon graphic data, as well as GT Koopa's advice on replacing the unused monitor art, I've went out of my way to import the art of the three emeralds found in ssemeral.bin using SonMapEd.


    [​IMG]


    Now what would I do to insert the blue Chaos Emerald into Green Hill Zone? It doesn't have to do anything, I just want it to appear in the level.


    EDIT 2: I have assigned Obj10 to be the object for the Chaos Emeralds. Now I just have to find the right code to make the emerald appear in Green Hill Zone as a collectable item.


    EDIT 3: As I previously did before, I made a copy of Obj25, replaced all instances of Obj25 in the copy with Obj10, and all instances of ring with emerald. See the entire code below.



    Obj10: ; XREF: Obj_Index
    moveq #0,d0


    move.b $24(a0),d0


    move.w Obj10_Index(pc,d0.w),d1


    jmp Obj10_Index(pc,d1.w)


    ; ===========================================================================


    Obj10_Index: dc.w Obj10_Main-Obj10_Index


    dc.w Obj10_Animate-Obj10_Index


    dc.w Obj10_Collect-Obj10_Index


    dc.w Obj10_Sparkle-Obj10_Index


    dc.w Obj10_Delete-Obj10_Index


    ; ---------------------------------------------------------------------------


    ; Distances between emeralds (format: horizontal, vertical)


    ; ---------------------------------------------------------------------------


    Obj10_PosData: dc.b $10, 0 ; horizontal tight


    dc.b $18, 0 ; horizontal normal


    dc.b $20, 0 ; horizontal wide


    dc.b 0, $10 ; vertical tight


    dc.b 0, $18 ; vertical normal


    dc.b 0, $20 ; vertical wide


    dc.b $10, $10 ; diagonal


    dc.b $18, $18


    dc.b $20, $20


    dc.b $F0, $10


    dc.b $E8, $18


    dc.b $E0, $20


    dc.b $10, 8


    dc.b $18, $10


    dc.b $F0, 8


    dc.b $E8, $10


    ; ===========================================================================


    Obj10_Main: ; XREF: Obj10_Index


    lea ($FFFFFC00).w,a2


    moveq #0,d0


    move.b $23(a0),d0


    lea 2(a2,d0.w),a2


    move.b (a2),d4


    move.b $28(a0),d1


    move.b d1,d0


    andi.w #7,d1


    cmpi.w #7,d1


    bne.s loc_9B80


    moveq #6,d1


    loc_9B80:


    swap d1


    move.w #0,d1


    lsr.b #4,d0


    add.w d0,d0


    move.b Obj10_PosData(pc,d0.w),d5 ; load emerald spacing data


    ext.w d5


    move.b Obj10_PosData+1(pc,d0.w),d6


    ext.w d6


    movea.l a0,a1


    move.w 8(a0),d2


    move.w $C(a0),d3


    lsr.b #1,d4


    bcs.s loc_9C02


    bclr #7,(a2)


    bra.s loc_9BBA


    ; ===========================================================================


    Obj10_MakeEmeralds:


    swap d1


    lsr.b #1,d4


    bcs.s loc_9C02


    bclr #7,(a2)


    bsr.w SingleObjLoad


    bne.s loc_9C0E


    loc_9BBA: ; XREF: Obj10_Main


    move.b #$25,0(a1) ; load emerald object


    addq.b #2,$24(a1)


    move.w d2,8(a1) ; set x-axis position based on d2


    move.w 8(a0),$32(a1)


    move.w d3,$C(a1) ; set y-axis position based on d3


    move.l #Map_Obj10,4(a1)


    move.w #$27B2,2(a1)


    move.b #4,1(a1)


    move.b #2,$18(a1)


    move.b #$47,$20(a1)


    move.b #8,$19(a1)


    move.b $23(a0),$23(a1)


    move.b d1,$34(a1)


    loc_9C02:


    addq.w #1,d1


    add.w d5,d2 ; add emerald spacing value to d2


    add.w d6,d3 ; add emerald spacing value to d3


    swap d1


    dbf d1,Obj10_MakeEmeralds ; repeat for number of emeralds


    loc_9C0E:


    btst #0,(a2)


    bne.w DeleteObject


    Obj10_Animate: ; XREF: Obj10_Index


    move.b ($FFFFFEC3).w,$1A(a0) ; set frame


    bsr.w DisplaySprite


    move.w $32(a0),d0


    andi.w #$FF80,d0


    move.w ($FFFFF700).w,d1


    subi.w #$80,d1


    andi.w #$FF80,d1


    sub.w d1,d0


    cmpi.w #$280,d0


    bhi.s Obj10_Delete


    rts


    ; ===========================================================================


    Obj10_Collect: ; XREF: Obj10_Index


    addq.b #2,$24(a0)


    move.b #0,$20(a0)


    move.b #1,$18(a0)


    bsr.w CollectEmerald


    lea ($FFFFFC00).w,a2


    moveq #0,d0


    move.b $23(a0),d0


    move.b $34(a0),d1


    bset d1,2(a2,d0.w)


    Obj10_Sparkle: ; XREF: Obj10_Index


    lea (Ani_Obj10).l,a1


    bsr.w AnimateSprite


    bra.w DisplaySprite


    ; ===========================================================================


    Obj10_Delete: ; XREF: Obj10_Index


    bra.w DeleteObject


    ; ||||||||||||||| S U B R O U T I N E |||||||||||||||||||||||||||||||||||||||


    CollectEmerald: ; XREF: Obj10_Collect


    addq.w #1,($FFFFFE20).w ; add 1 to emeralds


    ori.b #1,($FFFFFE1D).w ; update the emeralds counter


    move.w #$B5,d0 ; play emerald sound


    cmpi.w #100,($FFFFFE20).w ; do you have < 100 emeralds?


    bcs.s Obj10_PlaySnd ; if yes, branch


    bset #1,($FFFFFE1B).w ; update lives counter


    beq.s loc_9CA4


    cmpi.w #200,($FFFFFE20).w ; do you have < 200 emeralds?


    bcs.s Obj10_PlaySnd ; if yes, branch


    bset #2,($FFFFFE1B).w ; update lives counter


    bne.s Obj10_PlaySnd


    loc_9CA4:


    addq.b #1,($FFFFFE12).w ; add 1 to the number of lives you have


    addq.b #1,($FFFFFE1C).w ; add 1 to the lives counter


    move.w #$88,d0 ; play extra life music


    Obj10_PlaySnd:


    jmp (PlaySound_Special).l


    ; End of function CollectEmerald



    Is there anything here I should edit to make this object display the graphic data for the blue Chaos Emerald (which is in artnem/monitors.bin) and add 1 to the emerald counter upon being collected?
     
    Last edited by a moderator: Dec 4, 2011
  20. SpirituInsanum

    SpirituInsanum Well-Known Member Member

    Joined:
    Feb 11, 2010
    Messages:
    642
    This: move.w #$27B2,2(a1) means "use art beginning at F640 in VRAM with second palette line". So you definitely want to change it. Also, move.b ($FFFFFEC3).w,$1A(a0) loads the current ring frame to display. All you want for now is frame 1 (or 0 if you don't have a blank frame at the beginning of your mapping).
     
Thread Status:
Not open for further replies.