New splash screen method

Discussion in 'Tutorials Archive' started by Hitaxas, Oct 31, 2014.

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

    Hitaxas Retro 80's themed Paladins Twich streamer Member

    Joined:
    Aug 13, 2007
    Messages:
    167
    As of November 3rd, I have changed a lot of this guide to work with Retro Graphics Toolkit, which required a slight edit of the code.

     

    I am not sure if this counts as a tutorial rather than a guide to easily add code that's already set to go. But I'm taking a different direction with this one, which I hope helps people in the future.

     

    I recently sat down and thought to myself "Splash screens are neat and all. However most of them are rather lengthy in code and almost all come with something complete they can just slap in there and call it a day. Not all, but most I've seen."

     

    From there I proceeded to write my own, using as few lines as I could.

     

    So today (or tonight for me!) I figured I would release this code. Yes, the code is complete and could simply be slapped into a ROM. BUT there is a difference here, I will provide example files for the code and a compiled ROM for it as well. HOWEVER, this example is purely that. Replacing the art/mappings and palette for the screen will be necessary due to the disclaimer the screen has. =P

    This screen is also static, and does not use any fancy effects or objects, that is up to whoever uses that to do on their own.

     

    ALSO, this was made with Xenowhirl's 2007 disassembly of Sonic 2, and that is what this tutorial will cover. It should be fairly easy to port to any other version of Sonic 2 or Sonic 3 & Knuckles, if you know basic assembly. For a version that works with Sonic 1 2005 Hivebrain disassembly, click HERE!

     

    But enough about that, lets get down to it!

    For this example I will be replacing the SEGA screen, you do not need to implement it this way if you know how to correctly add screen modes and set the code to go the the correct one next. 

     

    First open S2.asm then search and locate the original sega screen at this label: 

    segascreen:

    Once you have located this replace everything (including the original label) with this:

    (Code cleaned and fully commented thanks to MarkeyJester)


    Code:
    ; ============================================================================================
    ; Sega Screen example - This code only works as a replacement for the SEGA screen
    ; For regular Splash screens, read the guide this code comes with!
    ; 2014, Hitaxas
    ; ============================================================================================
    SegaScreen: ; Stop previous music, clear vram and screen to set up this new screen
        moveq  #$FD,d0                  ; set music ID to stop
        jsr    (PlayMusic).w            ; play music ID
        jsr    (Pal_FadeFrom).w         ; fade palette out
        move   #$2700,sr                ; disable interrupts
        move.w ($FFFFF60C).w,d0         ; load VDP register 81XX data
        andi.b #%10111111,d0            ; set display to "disable"
        move.w d0,(VDP_control_port).l  ; save to VDP
        jsr    (ClearPLC).w             ; clear pattern load cues
        jsr    (ClearScreen).w          ; clear VRAM planes, sprite buffer and scroll buffer
        lea    (Metablock_Table).l,a1   ; load dump location
        lea    (MAPS_SEGA).l,a0         ; load compressed mappings address
        move.w #320,d0                  ; prepare pattern index value to patch to mappings
        jsr    (EniDec).w               ; decompress and dump
        move.l #$60000003,d0            ; prepare VRAM write mode address (Plane B E000)
        moveq  #$28-$01,d1              ; set map box draw width
        moveq  #$1E-$01,d2              ; set map box draw height
        bsr.w  ShowVDPGraphics          ; flush mappings to VRAM
        lea    (VDP_control_port).l,a6  ; load VDP control port
        move.l #$68000000,(a6)          ; set VDP to VRAM write mode (Address 2800)
        lea    (ART_SEGA).l,a0          ; load compressed art address
        jsr    (NemDec).w               ; decompress and dump to VDP memory
        lea    (Pal_SEGANew).l,a0          ; load palette address
        lea    (Second_palette).w,a1    ; load palette buffer address
        moveq  #$F,d0                   ; set repeat times
    
    SegaScreen_PalLoop:
        move.l (a0)+,(a1)+              ; copy colours to buffer
        move.l (a0)+,(a1)+              ; ''
        dbf    d0,SegaScreen_PalLoop    ; repeat until done
        move.w ($FFFFF60C).w,d0         ; load VDP register 81XX data
        ori.b  #%01000000,d0            ; set display to "enable"
        move.w d0,(a6)                  ; save to VDP
        jsr    Pal_FadeTo               ; fade palette in
        move.w #3*60,(Demo_Time_left).w ; set delay time (3 seconds on a 60hz system)
    
    Sega_MainLoop:
        move.b #$02,(Delay_Time).w      ; set V-blank routine to run
        jsr    (DelayProgram).w         ; wait for V-blank (decreases "Demo_Time_left")
        tst.b  ($FFFFF605).w            ; has player 1 pressed start button?
        bmi.s  sega_GotoTitle           ; if so, branch
        tst.w  (Demo_Time_left).w       ; has the delay time finished?
        bne.s  Sega_MainLoop            ; if not, branch
    
    sega_GotoTitle:
        move.b #$04,(Game_Mode).w       ; set the screen mode to Title Screen
        rts                             ; return
    
    This is already completely written for this purpose. All that is left is to binclude the files I have provided here

     

    Put these files in a folder in the root of you hack with the name NEWSEGASCREEN

     

    To get these files to load into the game go to the bottom of your S2.ASM and just before the ; end of 'ROM' add these lines:


    Code:
    ART_SEGA: binclude "NEWSEGASCREEN/SEGAARTNEM.bin"
    even
    
    
    MAPS_SEGA: binclude "NEWSEGASCREEN/SEGAMAPSE.bin"
    even
    
    
    Pal_SEGANew: binclude "NEWSEGASCREEN/SEGAPAL.bin"
    even
     

    Now save the asm file and build your ROM, everything should be in working order. 

     

    You will be greeted with a screen that looks almost like this:

    [​IMG]

     

     

    However you will notice a slight difference with which you want to change. You will notice it if you've followed through with this guide.

     

    If you would like to download an already compiled ROM with this screen in it and see what it would look like when you implement it on your own click HERE

     

    From here it is up to you to change the art/mappings/palette. I suggest using a combination of Retro Graphics toolkit and Photoshop to do this, if you know how to use those programs. I will not be walking you through how to do this here.

     

    If you are looking to use this code as a splash screen rather than a replacement for the SEGA screen, you need to make a few changes.

     

    However, since I am too lazy right now, here is the complete code that allows for splash screens AFTER the SEGA screen:


    Code:
    ; ============================================================================================
    ; Sega Screen example
    ; This version is for splash screens that load AFTER the SEGA screen
    ; For A version that replaces the SEGA screen, read the guide this code came from!
    ; 2014, Hitaxas
    ; ============================================================================================
    SegaScreen2:
            move.b  #$FD,d0                         ; set music ID to "stop music"
            jsr     PlayMusic                       ; play ID
            jsr     (Pal_FadeFrom).w                ; fade palettes out
            jsr     (ClearScreen).w                 ; clear the plane mappings
            dmaFillVRAM 0,$0000,$10000              ; fill entire VRAM with 0 | macro used in S2 disassemblies
            ; load art, mappings and the palette
            lea     (Metablock_Table).l,a1          ; load dump location
            lea     (MAPS_SEGA).l,a0                ; load background mappings
    	move.w #320,d0                          ; offset the tilemap by n amount of tiles
    	bsr.w	EniDec
    	lea	(Metablock_Table).l,a1
    	move.l	#$60000002,d0
    	moveq	#39,d1
    	moveq	#30,d2
            bsr.w   ShowVDPGraphics3                ; flush mappings to VRAM
            move.l  #$68000000,(VDP_control_port).l ; set vdp loc
            lea     (ART_SEGA).l,a0                 ; load background art
            jsr     NemDec                          ; run NemDec to decompress art for display
    	lea	(Pal_SEGANew).l,a0                 ; load this palette
    	lea	(Second_palette).l,a1           ; set as line 2
    	move.w	#$F,d0
    
    SegaScreen_PalLoop2:
    	move.l	(a0)+,(a1)+			; copy colours to buffer
    	move.l	(a0)+,(a1)+			; ''
    	dbf	d0,SegaScreen_PalLoop2		; repeat until done
    	jsr	Pal_FadeTo			; fade palette in
            move.w	#3*60,(Demo_Time_left).w	; set delay time (3 seconds on a 60hz system)
    
    Sega_MainLoop2:
            move.b	#$02,(Delay_Time).w		; set V-blank routine to run
    	jsr	(DelayProgram).w		; wait for V-blank (decreases "Demo_Time_left")
    	tst.b	($FFFFF605).w			; has player 1 pressed start button?
    	bmi.s	sega_GotoTitle2			; if so, branch
    	tst.w	(Demo_Time_left).w		; has the delay time finished?
    	bne.s	Sega_MainLoop2			; if not, branch
    
    sega_GotoTitle2:
    	move.b	#$04,(Game_Mode).w		; set the screen mode to Title Screen
    	rts					; return
    In my test this will allow the screen to show up correctly after the stock SEGA screen.
     
    Last edited by a moderator: Nov 6, 2014
  2. AkumaYin

    AkumaYin Well-Known Member Exiled

    Joined:
    Aug 21, 2014
    Messages:
    157
    Oh wow, simply adding an image as a splash screen is something I've been wanting to do for a while. I'll probably give this a go soon.
     
  3. Hitaxas

    Hitaxas Retro 80's themed Paladins Twich streamer Member

    Joined:
    Aug 13, 2007
    Messages:
    167
    If anybody for whatever reason feels obligated to post a tutorial on how to convert images for use with this code, feel free to do so.

    Also any suggestions on how to improve this code, if possible are welcome as well.
     
  4. Pacca

    Pacca Having an online identity crisis since 2019 Member

    Joined:
    Jul 5, 2014
    Messages:
    1,175
    Location:
    Limbo
    If you set the screen to appear after the normal sega screen, it doesn't display anything, instead showing a black screen in place of the required art (my code works if you play it in place of the sega screen, however). I think you need to add something to clear the VDP before hand, or something like that (I'm not very experienced with this).

    Edit: I also have no idea how to make new graphics for it...
     
    Last edited by a moderator: Oct 31, 2014
  5. MarkeyJester

    MarkeyJester ♡ ! Member

    Joined:
    Jun 27, 2009
    Messages:
    2,867
    Code:
    SegaScreen:
    	moveq	#$FD,d0				; set music ID to stop
    	jsr	(PlayMusic).w			; play music ID
    	jsr	(Pal_FadeFrom).w		; fade palette out
    	move	#$2700,sr			; disable interrupts
    	move.w	($FFFFF60C).w,d0		; load VDP register 81XX data
    	andi.b	#%10111111,d0			; set display to "disable"
    	move.w	d0,(VDP_control_port).l		; save to VDP
    	jsr	(ClearPLC).w			; clear pattern load cues
    	jsr	(ClearScreen).w			; clear VRAM planes, sprite buffer and scroll buffer
    	lea	(Metablock_Table).l,a1		; load dump location
    	lea	(MAPS_SEGA).l,a0		; load compressed mappings address
    	move.w	#$2000|($2800/$20),d0		; prepare pattern index value to patch to mappings
    	jsr	(EniDec).w			; decompress and dump
    	move.l	#$60000003,d0			; prepare VRAM write mode address (Plane B E000)
    	moveq	#$28-$01,d1			; set map box draw width 
    	moveq	#$1E-$01,d2			; set map box draw height
    	jsr	ShowVDPGraphics			; flush mappings to VRAM in a square like manner
    	lea	(VDP_control_port).l,a6		; load VDP control port
    	move.l	#$68000000,(a6)			; set VDP to VRAM write mode (Address 2800)
    	lea	(ART_SEGA).l,a0			; load compressed art address
    	jsr	(NemDec).w			; decompress and dump to VDP memory
    	lea	(Pal_SEGANew).l,a0		; load palette address
    	lea	(Second_palette_line2).w,a1	; load palette buffer address
    	moveq	#$03,d0				; set repeat times
    
    SegaScreen_PalLoop:	
    	move.l	(a0)+,(a1)+			; copy colours to buffer
    	move.l	(a0)+,(a1)+			; ''
    	dbf	d0,SegaScreen_PalLoop		; repeat until done
    	move.w	($FFFFF60C).w,d0		; load VDP register 81XX data
    	ori.b	#%01000000,d0			; set display to "enable"
    	move.w	d0,(a6)				; save to VDP
    	jsr	Pal_FadeTo			; fade palette in
            move.w	#3*60,(Demo_Time_left).w	; set delay time (3 seconds on a 60hz system)
    
    Sega_MainLoop:
            move.b	#$02,(Delay_Time).w		; set V-blank routine to run
    	jsr	(DelayProgram).w		; wait for V-blank (decreases "Demo_Time_left")
    	tst.b	($FFFFF605).w			; has player 1 pressed start button?
    	bmi.s	sega_GotoTitle			; if so, branch
    	tst.w	(Demo_Time_left).w		; has the delay time finished?
    	bne.s	Sega_MainLoop			; if not, branch
    
    sega_GotoTitle:
    	move.b	#$04,(Game_Mode).w		; set the screen mode to Title Screen
    	rts					; return
     
  6. N30member

    N30member non-pro user btw Member

    Joined:
    Feb 15, 2014
    Messages:
    216
    Location:
    Kazakhstan
    So, I need to change RAM addresses and bincludes to work on Sonic 1? Can't check since I wrote this post via tablet.
     
  7. Hitaxas

    Hitaxas Retro 80's themed Paladins Twich streamer Member

    Joined:
    Aug 13, 2007
    Messages:
    167
    Pretty much all you'd need to do to get this working for Sonic 1, yes.

    Edit: Updated the original post with the cleaned up code Markey provided, and a fix at the bottom of the post for those looking to use this for a splash screen that follows after the stock SEGA screen.
     
    Last edited by a moderator: Oct 31, 2014
  8. Sonic master

    Sonic master Well-Known Member Member

    Joined:
    Mar 27, 2010
    Messages:
    303
    Good tutorial but ImaGenesis is terrible as even when importing an image that has already been reduced with a better algorithm you will still lose even more colors even if the image already has the proper amount of colors. Here are some nice alternatives

    GUI:

    http:/sonicresearch.org/forums/index.php?showtopic=3480 My own program Retro Graphics Toolkit does color quantization very well and if the image is already reduced will preserve all colors.

    http://jiggawatt.org/badc0de/sixpack/Nice command line program called Sixpack supports some compression formats and can do color quantization but not as well as Retro Graphics toolkit, it is better that you reduce the image then run Sixpack it does keep all colors. Also supports some compression formats and can load PNG files directly.

    http://www.pascalorama.com/article.php?news=28&cat=21another command line program called Genitile program not as fancy as sixpack but just an alternative, it only loads pcx files.

    If anyone knows of any more utilities please do tell. I just think ImaGenesis is not a good program anymore and there is no need to be using it. There are things it does right (user friendliness) but the output it gives makes it not worth it.
     
    Last edited by a moderator: Nov 1, 2014
  9. Hitaxas

    Hitaxas Retro 80's themed Paladins Twich streamer Member

    Joined:
    Aug 13, 2007
    Messages:
    167
    I have figured out for the most part, how to use Retro Graphics toolkit to load an image and reduce its colors, However when exporting everything and building the ROM, I get mostly garbage displayed. This happens no matter what methods of color reduction or edits I did to my own code... It's a shame because being able to take advantage of all 64 colors I could use would prove helpful.
     
    Last edited by a moderator: Nov 1, 2014
  10. Sonic master

    Sonic master Well-Known Member Member

    Joined:
    Mar 27, 2010
    Messages:
    303
    How are you saving the tiles and tilemap and palette? To export the tiles do File->Tiles->Save tiles. To export the tilemap do File->Tilemaps->Save tilemap and if NES attributes and finally to save the palette. File->Palette->Save Palette. I admit if this was were the confusion it was partially my fault for using inconsistent terminology. Also make sure you picked the proper compression and are saving it as a binary file when saving as a file that will be added to the rom using incbin or binclude. Use ASM when you want to copy and paste into your assembly project.

    Here is code that I used in Sonic 1 to display a splash screen

    Code:
    		lea    (sonicTeamTiles).l,a0
    		lea    ($FF0000).l,a1
    		bsr.w    KosDec
    		writeVRAM    $FF0000,1120*32,32
    		lea	($FF0000).l,a1
    		lea	(sonicTeamTileMap).l,a0
    		move.w	#1,d0
    		bsr.w	EniDec
    
    		copyTilemap	$FF0000,$C000,$27,$1B
    
    		writeCRAM	sonicTeamPalette,64*2,0
    
    waitStartSplashScreen:
    		bsr.w	ReadJoypads
    		andi.b	#$80,($FFFFF605).w ; is	Start button pressed?
    		beq.s	waitStartSplashScreen		; if not, branch
    		jsr	ClearScreen
    
    If I had to guess which line is causing you the most trouble it would be this one
    Code:
    	move.w	#$2000|($2800/$20),d0		; prepare pattern index value to patch to mappings
    
    What this does is tell the Enigma decompressor what to add to the tilemap values. This will cause you trouble as Retro Graphics Toolkit sets the palette row for you already so this will cause an overflow. Try replacing that line with
    Code:
    	move.w #320,d0 ; offset the tilemap by n amount of tiles
    
     
    Last edited by a moderator: Nov 1, 2014
  11. Hitaxas

    Hitaxas Retro 80's themed Paladins Twich streamer Member

    Joined:
    Aug 13, 2007
    Messages:
    167
    Holy junk dude. That code you posted is much smaller than what I've posted here. Guess I certainly do not have the smallest routine for this. (Even though mine uses a similar method to what the s2 options screen uses which could help with custom menus)


    Thank you for that information, that will help me a lot in the future.
     
    Last edited by a moderator: Nov 1, 2014
  12. Sonic master

    Sonic master Well-Known Member Member

    Joined:
    Mar 27, 2010
    Messages:
    303
    Your code does more than mine. All this does is display it wait and wait for start. From reading your code it displays it for a set amount of time and then fades the palette. What I am wondering is did changing the line of code I suggested fix the problem with you getting corrupt graphics?
     
  13. Hitaxas

    Hitaxas Retro 80's themed Paladins Twich streamer Member

    Joined:
    Aug 13, 2007
    Messages:
    167
    I was finally able to test that. It did not solve the issue sadly.
     
  14. Sonic master

    Sonic master Well-Known Member Member

    Joined:
    Mar 27, 2010
    Messages:
    303
    Alright so I am wondering what to do next. I do want to address this problem my first guess would be that the data was somehow saved incorrectly however I already mentioned that and there is a low chance you did and you did not say anything that pertains to saving the data so I will assume you did that correctly. Maybe there are too many tiles and that is overwriting the pattern table. If that is the case you can (in Retro Graphics Toolkit) click on Tile Actions->Remove duplicate tiles. After that is done assuming you got rid of enough tiles it may work this time.
     
    Last edited by a moderator: Nov 1, 2014
  15. Hitaxas

    Hitaxas Retro 80's themed Paladins Twich streamer Member

    Joined:
    Aug 13, 2007
    Messages:
    167
    Disregard. I've gotten it to work after I realized that I messed up the lines in the code that control the height and width.
     
    Last edited by a moderator: Nov 1, 2014
  16. Sonic master

    Sonic master Well-Known Member Member

    Joined:
    Mar 27, 2010
    Messages:
    303
    Glad to hear that it works. If you do encounter an issue with Retro Graphics Toolkit I will be happy to help.
     
    Last edited by a moderator: Nov 1, 2014
  17. ProjectFM

    ProjectFM Optimistic and self-dependent Member

    Joined:
    Oct 4, 2014
    Messages:
    912
    Location:
    Orono, Maine
    I tried porting this to Sonic 1 but there is one line for the palette that I can't find a replacement for. Can anyone find a way to fix this?


    ; ============================================================================================
    ; Sega Screen example
    ; 2014, Hitaxas
    ; ============================================================================================
    SegaScreen: ; Stop previous music, clear vram and screen to set up this new screen
    move.b #$E4,d0 ; set music ID to stop
    jsr PlaySound_Special.w ; play music ID
    jsr Pal_FadeFrom.w ; fade palette out
    move #$2700,sr ; disable interrupts
    move.w ($FFFFF60C).w,d0 ; load VDP register 81XX data
    andi.b #%10111111,d0 ; set display to "disable"
    move.l d0,($C00004).l ; save to VDP
    jsr ClearPLC.w ; clear pattern load cues
    jsr ClearScreen.w ; clear VRAM planes, sprite buffer and scroll buffer
    move.l #$40000000,($C00004).l ; load dump location
    lea MAPS_SEGA.l,a0 ; load compressed mappings address
    move.w #$2000|($2800/$20),d0 ; prepare pattern index value to patch to mappings
    jsr EniDec.w ; decompress and dump
    move.l #$60000003,d0 ; prepare VRAM write mode address (Plane B E000)
    moveq #$28-$01,d1 ; set map box draw width
    moveq #$1E-$01,d2 ; set map box draw height
    jsr ShowVDPGraphics ; flush mappings to VRAM in a square like manner
    move.l a6,($C00004).l ; load VDP control port
    move.l #$68000000,(a6) ; set VDP to VRAM write mode (Address 2800)
    lea ART_SEGA.l,a0 ; load compressed art address
    jsr NemDec.w ; decompress and dump to VDP memory
    lea Pal_SEGANew.l,a0 ; load palette address
    lea (Second_palette_line2).w,a1 ; load palette buffer address <-----
    moveq #$03,d0 ; set repeat times

    SegaScreen_PalLoop:
    move.l (a0)+,(a1)+ ; copy colours to buffer
    move.l (a0)+,(a1)+ ; ''
    dbf d0,SegaScreen_PalLoop ; repeat until done
    move.w ($FFFFF60C).w,d0 ; load VDP register 81XX data
    ori.b #%01000000,d0 ; set display to "enable"
    move.w d0,(a6) ; save to VDP
    jsr Pal_FadeTo ; fade palette in
    move.w #3*60,($FFFFF614).w ; set delay time (3 seconds on a 60hz system)

    Sega_MainLoop:
    move.b #2,($FFFFF62A).w ; set V-blank routine to run
    jsr DelayProgram.w ; wait for V-blank (decreases "Demo_Time_left")
    tst.b ($FFFFF605).w ; has player 1 pressed start button?
    bmi.s sega_GotoTitle ; if so, branch
    tst.w ($FFFFF614).w ; has the delay time finished?
    bne.s Sega_MainLoop ; if not, branch

    sega_GotoTitle:
    move.b #$04,($FFFFF600).w ; set the screen mode to Title Screen
    rts ; return

    (The arrow points to the line)
     
  18. Hitaxas

    Hitaxas Retro 80's themed Paladins Twich streamer Member

    Joined:
    Aug 13, 2007
    Messages:
    167
    That line can actually be changed from second_palette_line2 to second_palette, and still function just fine. That happens to be RAM address $FFFFFB80, which is in S1. :)
     
  19. ProjectFM

    ProjectFM Optimistic and self-dependent Member

    Joined:
    Oct 4, 2014
    Messages:
    912
    Location:
    Orono, Maine
    Thank you. Unfortunately, it still goes black instead of showing the splash screen. Is there anything else wrong with my code?
     
  20. Hitaxas

    Hitaxas Retro 80's themed Paladins Twich streamer Member

    Joined:
    Aug 13, 2007
    Messages:
    167
    In order to answer that easier, I must ask. Is this a replacement for the SEGA screen or a new splash screen that follows after? (Keep in mind, I have not personally tested this screen in neither scenario in Sonic 1, as I only worked on this using Sonic 2)

    Although you did remove the parentheses around the names of the art. mappings and palette files, which, while I am not sure if that would affect things, I think those should have been left in.   

    Edit: I have changed the original post, along with the example picture and the files to work with Retro Graphics toolkit. That is what I will be personally using from now on, as it does a much better job at converting images for use with the Genesis.
     
    Last edited by a moderator: Nov 4, 2014
Thread Status:
Not open for further replies.