Adding an extra screen of Text

Discussion in 'Discussion and Q&A Archive' started by theocas, May 29, 2010.

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

    theocas #! Member

    Joined:
    Apr 10, 2010
    Messages:
    375
    I have created mappings for an intro screen to be displated before EHZ, and it uses the Level Select Pallete, and the standard font. I trtied copying the Level Select code and changing it, but I failed at doing so. Could anyone point me in the right direction, or even give a code sample?
     
  2. Selbi

    Selbi The Euphonic Mess Member

    Joined:
    Jul 20, 2008
    Messages:
    2,429
    Location:
    Northern Germany
    Could you explain a little bit more what you actually want to do? Just saying "Intro Screen" doesn't really help, at least me.
     
  3. theocas

    theocas #! Member

    Joined:
    Apr 10, 2010
    Messages:
    375
    I made a small screen in PlaneEd listing what you need to do to unlock a special move, and I want to display it right before EHZ, aka when someone presses start on the title screen when 1P is selected. I copied the Level Select code, renamed the label, and changed the MapEni_LevSel to MapEni_IntroScreen, and I binclude'd the corresponding file, but I only get a black screen when doing a jsr to my code. Here's the code I used:




    MenuScreen_IntroScreen:


    lea (Metablock_Table).l,a1


    lea (MapEng_IntroScreen).l,a0


    move.w #0,d0


    bsr.w EniDec


    lea (Metablock_Table).l,a1


    move.l #$40000003,d0


    moveq #$27,d1


    moveq #$1B,d2


    bsr.w JmpTo_ShowVDPGraphics


    moveq #0,d3


    bsr.w loc_965A


    lea ($FFFF08C0).l,a1


    bsr.w JmpTo2_Dynamic_Normal


    moveq #$26,d0


    bsr.w PalLoad1


    lea (Normal_palette_line3).w,a1


    lea (Second_palette_line3).w,a2


    moveq #7,d1


    rts



    It compiles fine and all variables exist, but I just get the black screen when doing a jsr to this code from CheckSumCheck:
     
    Last edited by a moderator: May 29, 2010
  4. vladikcomper

    vladikcomper Well-Known Member Member

    Joined:
    Dec 2, 2009
    Messages:
    415
    In your case, you've just copied a piece of code. If you need to display your screen perfectly, you need clear RAM, palletes, setup VDP registers, clear plane mappings. Look at other screens' code. Let's take for example Sega Screen from Sonic 1:



    SegaScreen: ; XREF: GameModeArray
    move.b #$E4,d0


    bsr.w PlaySound_Special ; stop music


    bsr.w ClearPLC ; clear pattern load cues


    bsr.w Pal_FadeFrom ; fade out pallete


    lea ($C00004).l,a6 ; VDP control port


    ; set VDP registers


    move.w #$8004,(a6)


    move.w #$8230,(a6)


    move.w #$8407,(a6)


    move.w #$8700,(a6)


    move.w #$8B00,(a6)


    clr.b ($FFFFF64E).w ; clear water palette state


    move #$2700,sr


    move.w ($FFFFF60C).w,d0


    andi.b #$BF,d0


    move.w d0,($C00004).l


    bsr.w ClearScreen



    That's how screen should be initialized to work correctly.


    ADDED: but not exactly like this though :angry:
     
    Last edited by a moderator: May 29, 2010
  5. theocas

    theocas #! Member

    Joined:
    Apr 10, 2010
    Messages:
    375
    OK, so I added vladikcomper's code to the top of my code, fixed some out of range errors, and called it again from CheckSumCheck, but the same applies. Either I am being totally retarded, or I screwed something up, or I just fail at fixing out of range errors, or do a simple copy-pasta. Anyways, Here's my code:




    MenuScreen_IntroScreen:


    ;move.b #$E4,d0


    ;bsr.w PlaySound_Special ; stop music


    bsr.w ClearPLC ; clear pattern load cues


    bsr.w Pal_FadeFrom ; fade out pallete


    lea ($C00004).l,a6 ; VDP control port


    ; set VDP registers


    move.w #$8004,(a6)


    move.w #$8230,(a6)


    move.w #$8407,(a6)


    move.w #$8700,(a6)


    move.w #$8B00,(a6)


    clr.b ($FFFFF64E).w ; clear water palette state


    move #$2700,sr


    move.w ($FFFFF60C).w,d0


    andi.b #$BF,d0


    move.w d0,($C00004).l


    jsr ClearScreen


    lea (Metablock_Table).l,a1


    lea (MapEng_IntroScreen).l,a0


    move.w #0,d0


    bsr.w EniDec


    lea (Metablock_Table).l,a1


    move.l #$40000003,d0


    moveq #$27,d1


    moveq #$1B,d2


    bsr.w JmpTo_ShowVDPGraphics


    moveq #0,d3


    ;bsr.w loc_965A


    lea ($FFFF08C0).l,a1


    bsr.w JmpTo2_Dynamic_Normal


    moveq #$26,d0


    bsr.w PalLoad1


    lea (Normal_palette_line3).w,a1


    lea (Second_palette_line3).w,a2


    moveq #7,d1


    rts
     
    Last edited by a moderator: May 29, 2010
  6. vladikcomper

    vladikcomper Well-Known Member Member

    Joined:
    Dec 2, 2009
    Messages:
    415
    You shouldn't call it from CheckSumCheck, because the game isn't completely initialized there, call it from MainGameLoop or GameModeArray (note that I've taken these names from S1's disasm, in S2's one they may be different). Also, it looks like art for your text screen isn't loaded at all, you need fix it as well. Commands to load art must be somewhere in Level Select Screen code, though I don't know exactly because I don't know much about Sonic 2.


    ADDED: Oh, I fogot to say that you have to call Pal_FadeTo subroutine to display the pallete.
     
    Last edited by a moderator: May 29, 2010
  7. theocas

    theocas #! Member

    Joined:
    Apr 10, 2010
    Messages:
    375
    OK, so I got a bit further. This is the output that I get:


    [​IMG]


    And the Code:




    MenuScreen_IntroScreen:


    bsr.w Pal_FadeFrom


    move #$2700,sr


    move.w ($FFFFF60C).w,d0


    andi.b #-$41,d0


    move.w d0,(VDP_control_port).l


    dmaFillVRAM 0,$0000,$40 ; Fill first $40 bytes of VRAM with 0


    dmaFillVRAM 0,$C000,$1000 ; Clear Plane A pattern name table


    dmaFillVRAM 0,$E000,$1000 ; Clear Plane B pattern name table


    clr.l (Vscroll_Factor).w


    clr.l ($FFFFF61A).w


    clearRAM Sprite_Table,$284


    clearRAM Horiz_Scroll_Buf,$404


    lea (VDP_control_port).l,a6


    move.w #$8004,(a6)


    move.w #$8230,(a6)


    move.w #$8407,(a6)


    move.w #$8230,(a6)


    move.w #$8700,(a6)


    move.w #$8C81,(a6)


    move.w #$9001,(a6)


    clearRAM Sprite_Table_Input,$400


    clearRAM Object_RAM,$2000


    clr.w (VDP_Command_Buffer).w


    move.l #VDP_Command_Buffer,(VDP_Command_Buffer_Slot).w


    move.l #$42000000,(VDP_control_port).l


    lea (ArtNem_FontStuff).l,a0


    bsr.w NemDec


    move.l #$4E000000,(VDP_control_port).l


    move.l #$60000003,d0


    moveq #$27,d1


    moveq #$1B,d2


    bsr.w JmpTo_ShowVDPGraphics


    lea (Metablock_Table).l,a1


    lea (MapEng_IntroScreen).l,a0


    move.w #0,d0


    bsr.w EniDec


    lea (Metablock_Table).l,a1


    move.l #$40000003,d0


    moveq #$27,d1


    moveq #$1B,d2


    bsr.w JmpTo_ShowVDPGraphics


    moveq #0,d3


    ;bsr.w loc_965A


    lea ($FFFF08C0).l,a1


    bsr.w JmpTo2_Dynamic_Normal


    moveq #$26,d0


    bsr.w PalLoad1


    lea (Normal_palette_line3).w,a1


    lea (Second_palette_line3).w,a2


    moveq #7,d1


    move.b #-$6F,d0


    bsr.w JmpTo_PlayMusic


    clr.w (Two_player_mode).w


    clr.l (Camera_X_pos).w


    clr.l (Camera_Y_pos).w


    MenuScreen_IntroScreenMisc:


    move.l (a1),(a2)+


    clr.l (a1)+


    dbf d1,MenuScreen_IntroScreenMisc


    move.b #$16,(Delay_Time).w


    bsr.w DelayProgram


    move.w ($FFFFF60C).w,d0


    ori.b #$40,d0


    move.w d0,(VDP_control_port).l


    bsr.w Pal_FadeTo


    jmp MenuScreen_IntroScreenMisc



    I am calling it from Level_MainLoopp. The screen at the top uses the standard level select pallete, but is only on screen for about 1/4 seconds, and then it fades out and the screen is left black. The picture just looks weird 'cause I couldn't get a screenshot fast enough.
     
    Last edited by a moderator: May 30, 2010
  8. vladikcomper

    vladikcomper Well-Known Member Member

    Joined:
    Dec 2, 2009
    Messages:
    415
    I guess the problem is in the last part of your code, in MenuScreen_IntroScreenMisc. There is a cycle that manipulates with the palletes, and code to fade in. But jump command in the end causes all that being run multiple times. After Pal_FadeTo subroutine has worked, registers a0 and a1 contain another data, so first 3 rows from MenuScreen_IntroScreenMisc will work incorrectly on the second run and so on. That's why screen disappears I guess.


    So "jmp MenuScreen_IntroScreenMisc" should be deleted and replaced with a loop like this:



    MenuScreen_Loop:
    move.b #2,($FFFFF62A).w


    bsr.w DelayProgram


    andi.b #$80,($FFFFF605).w ; is Start button pressed?


    beq.sMenuScreen_Loop ; if not, branch


    MenuScreen_End:


    jmp Level



    Though this code looks like for Sonic 1, be sure it'll work in S2 =)

    Not really good idea. Because level is completely loaded there, it's better to call it from GameModesArray.



    GameModesArray: ;;
    bra.w SegaScreen ; $00 SEGA screen mode


    bra.w TitleScreen ; $04 Title screen mode


    bra.w Level ; $08 Demo mode


    bra.w Level ; $0C Zone play mode <----------------


    bra.w SpecialStage ; $10 Special stage play mode


    bra.w ContinueScreen ; $14 Continue mode


    bra.w TwoPlayerResults ; $18 2P results mode


    bra.w LevelSelectMenu2P ; $1C 2P level select mode


    bra.w JmpTo_EndingSequence ; $20 End sequence mode


    bra.w OptionsMenu ; $24 Options mode


    bra.w LevelSelectMenu ; $28 Level select mode



    Just replace the second branch to Level with MenuScreen_IntroScreen. In that case, your screen will be shown exactly before the first level.
     
    Last edited by a moderator: May 31, 2010
  9. theocas

    theocas #! Member

    Joined:
    Apr 10, 2010
    Messages:
    375
    Once I did what vladikcomper suggested, the screen only displays a blue screen, and the level doesn't appear when I press start, but music, and all that stuff is there and it is playable, but the screen is filled with blue stuff.
     
  10. DanielHall

    DanielHall Well-Known Member Member

    Joined:
    Jan 18, 2010
    Messages:
    860
    Location:
    North Wales
    Why don't you try adding another level after menuscreen introscreen in gamemodearray?
     
  11. theocas

    theocas #! Member

    Joined:
    Apr 10, 2010
    Messages:
    375
    I don't understand what you mean exactly. There are 2 entries for Level in the GameModeArray, one for demos and one for the real deal. I replaced the second one with a branch to my code. once the player pressed start, the level starts, just the screen is filled with blue, but I managed to play it through that way. Is it possible that the palletes are wrong, since not even the title cards show up.
     
  12. DanielHall

    DanielHall Well-Known Member Member

    Joined:
    Jan 18, 2010
    Messages:
    860
    Location:
    North Wales
    I mean like this:


    GameModesArray: ;;


    bra.w SegaScreen ; $00 SEGA screen mode


    bra.w TitleScreen ; $04 Title screen mode


    bra.w Level ; $08 Demo mode


    bra.w Menuscreen_introscreen ; $0C Zone play mode


    bra.w Level <------


    bra.w SpecialStage ; $10 Special stage play mode


    bra.w ContinueScreen ; $14 Continue mode


    bra.w TwoPlayerResults ; $18 2P results mode


    bra.w LevelSelectMenu2P ; $1C 2P level select mode


    bra.w JmpTo_EndingSequence ; $20 End sequence mode


    bra.w OptionsMenu ; $24 Options mode


    bra.w LevelSelectMenu ; $28 Level select mode


    Probably won't work, but i'm tossing ideas in. It's worth a try, right?
     
  13. Hanoch

    Hanoch Well-Known Member Member

    Joined:
    Aug 3, 2008
    Messages:
    312
    Location:
    Israel
    It wont work because he needs to align everything to start at the next entry. It would be easier to add the branch to 'Level' at the end.
     
  14. MarkeyJester

    MarkeyJester ♡ ! Member

    Joined:
    Jun 27, 2009
    Messages:
    2,867
    Ah how I love the Megadrive...



    MainGameLoop:
    move.b (Game_Mode).w,d0


    andi.w #$3C,d0


    jsr GameModesArray(pc,d0.w)


    bra.s MainGameLoop


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


    ; loc_3A2:


    GameModesArray: ;;


    bra.w SegaScreen ; $00 SEGA screen mode


    bra.w TitleScreen ; $04 Title screen mode


    bra.w Level ; $08 Demo mode


    bra.w Level ; $0C Zone play mode


    bra.w SpecialStage ; $10 Special stage play mode


    bra.w ContinueScreen ; $14 Continue mode


    bra.w TwoPlayerResults ; $18 2P results mode


    bra.w LevelSelectMenu2P ; $1C 2P level select mode


    bra.w JmpTo_EndingSequence ; $20 End sequence mode


    bra.w OptionsMenu ; $24 Options mode


    bra.w LevelSelectMenu ; $28 Level select mode


    bra.w YourStupidScreen ; $30 Your stupid screen


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



    Add an extra game mode onto the end, though make sure that "andi.w #$3C,d0" is set correctly (In this case it is, so no need to worry).


    This is important, the game mode has been deliberately set this way to prevent stack overflow.


    Everytime a command such as "bsr" or "jsr" is used, it's location is stored in the stack location (a ram space generally, and in this situation, yes), the stack pointer is incremented so it's location is advanced lower down the ram space. Upon hitting an rts, the MC68000 reads from the stack pointer, and obtains the "last" location that was moved to the stack (Presumably a "bsr" or "jsr", though clever programming bastards tend to do special things using the stack), and moves the program counter to that location, basically returning to that last "bsr"/"jsr", this will decrement the stack pointer, raising it's location back up the ram space.


    If the stack pointer is not decremented back to the position from where it started before running through the main game loop, then something wasn't returned ("rts"), that has taken up a long-word of space that is now useless, and the stack pointer is a slight tad further down the ram space than it should be. The more times that screen mode is used, the more further the stack pointer will be incremented without being decremented, and eventually will overflow, go passed it's limit, and start overwritting data in ram spaces it shouldn't, and when the rest of the engine starts tampering with that space also (Like it should), upon returning, it'll read random code from the stack pointer and not a location, sending the program counter to an unwanted place.


    To make things more understandable for you, ALWAYS RETURN FROM A SCREEN MODE, NEVER jump across from one screen mode to another without using the main game loop, It's there for a reason.


    EDIT: Also to sum up, your original mode was missing initation codes for the VDP, Ram spaces, etc, it was also missing the routine used to fade the palettes into the palette buffer, and was also missing a screen "loop" upon which it would remain stuck presenting the same screen over and over until said otherwise.
     
    Last edited by a moderator: Jun 1, 2010
Thread Status:
Not open for further replies.