Pause Fucntion

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems.

Moderator: Moderators

Post Reply
Brian

Pause Fucntion

Post by Brian » Wed Dec 22, 2004 4:25 am

Hi there,

If i wanna add a "pause" function to the game.
What should I do? What i am thinking about is to enter
an infinite loop when a button is pressed; when i press it
again, the game can go on again. If so, where should I put
this piece of code to? within the main game loop? or at some
interrupt routines?

Any idea on this?

Best Regards,

Brian

User avatar
Memblers
Site Admin
Posts: 3880
Joined: Mon Sep 20, 2004 6:04 am
Location: Indianapolis
Contact:

Post by Memblers » Wed Dec 22, 2004 1:01 pm

There's a lot of ways to do it, of course. Normally I have my controller reading code in the NMI, so I'd put the pause loop in the main loop.

User avatar
Bregalad
Posts: 7951
Joined: Fri Nov 12, 2004 2:49 pm
Location: Chexbres, VD, Switzerland

Post by Bregalad » Wed Dec 22, 2004 1:23 pm

This all depends on your code's structure, so what are you calling "game loop".
Useless, lumbering half-wits don't scare us.

J2

An example

Post by J2 » Wed Dec 22, 2004 11:21 pm

It really does depend on your code structure.

Your idea to have an infinite loop that I assume will keep looping the button check routine until start is pressed again could possibly work.
Note: Remember interrupts (uncluding the VBLANK NMI) will trigger no matter what your code is currently doing (althopugh it will wait for the current instruction or DMC sample load to end ).

Example (note: this is a simplified version of something you could do, the code should be more optimized and more complete :-)):

-this assumes everything has been properly initiated + VBLANK NMIs = On
-also, I wrote this off the top of my head so there might be errors

Code: Select all

Main:                           ;main game loop
       jsr CheckButtons  ;checks the controller buttons and stores them
       jsr EnemyAI         ;enemy movement or whatver
       jsr HeroControl     ;Hero movement based upon the pushed buttons
       jmp Main              ;loop back

;---------------------------------------------
CheckButtons:
      ldx #$1     
      stx $4016               ;write 1 to $4016
      dex                     
      stx $4016               ;write 0 to $4016
                                   ;strobe controller 1 port

      lda $4016               ;A
      lda $4016               ;B
      lda $4016               ;Sel
      lda $4016               ;Start  
      and #%00000001
      sta StartButtonStatus  
      rts                    ;button checking routine (checks only for St button)
;--------------------------------------------

EnemyAI:
      ldx EnemyX
      ldy EnemyY
      stx Sp2X
      sty Sp2Y
      rts                       ;EnemyAI here
;-------------------------------------------

HeroControl:
      lda StartButtonStatus
      bne PauseGame            
      rts

PauseGame:
     lda #$0
     sta StartButtonStatus   ;resets start button status

     lda PPUReg1           ;load a ram coopy of $2000
     eor #%10000000    ;toggle nmi bit
     sta $2000         ;NMI = off, asssumes IRQ are turned off already

InfiniteLoop:

     jsr CheckButtons ;loop infinitely until St is pressed
     bne InfiniteLoop
     
     lda PPUReg1
     eor #%10000000
     sta $2000           ;turns NMI back on
     rts
That's just an example, there are many other methods.

Anyway, What are you working on (just curious)? :-)

User avatar
Disch
Posts: 1849
Joined: Wed Nov 10, 2004 6:47 pm

Post by Disch » Thu Dec 23, 2004 10:03 am

If you want the music to keep playing during pause, you'll have to jsr to your music routine even when paused. If you want music to stop... you'll have to silence all audio when the game is paused (otherwise you could be left with ugly hanging notes).

Aside from that... any split screen effects you're doing will still need attention. If you don't split the screen when needed, you'll get scrolling (or other graphic errors) on the display.

Plus you'll probably still have to refresh SPR-RAM every frame ($4014 write).

In fact... when paused, you still have to do EVERYTHING your game normally does. The only thing that's different is you don't allow the player to move/operate... and you stop the world (and enemies) from updating. So I'd say just keep a 'pause' value somewhere in RAM and in the NMI code (or wherever your typical frame code is)... branch over the routines that update the player and world if the game is paused.

User avatar
Bregalad
Posts: 7951
Joined: Fri Nov 12, 2004 2:49 pm
Location: Chexbres, VD, Switzerland

Post by Bregalad » Thu Dec 23, 2004 10:34 am

I guess the better, simpler, more structurated and more logistical thing is :
To have a NMI routine that upload PPU registers, SprRam, etc... from buffers, call the sound code, etc....
Your main programm can just does the actual gameplay things and upload buffer to be read in a NMI.
So you have to check the JoyPad in the main thing, if start if pressed you have to wait it to be released, then wait it to be pressed again, then continius gameplay (otherwise you game will pause and unpause 60 times per seconds, and I guess that's not the thing you want). All NMI thing will of couse be still enabled with and witout pausing.
Useless, lumbering half-wits don't scare us.

J2

Post by J2 » Thu Dec 23, 2004 2:58 pm

If you want the music to keep playing during pause, you'll have to jsr to your music routine even when paused. If you want music to stop... you'll have to silence all audio when the game is paused (otherwise you could be left with ugly hanging notes).
Heh, I forgot about that :? Although I didn't take many things into account because that was just an example for him to go by.
In fact... when paused, you still have to do EVERYTHING your game normally does. The only thing that's different is you don't allow the player to move/operate... and you stop the world (and enemies) from updating. So I'd say just keep a 'pause' value somewhere in RAM and in the NMI code (or wherever your typical frame code is)... branch over the routines that update the player and world if the game is paused.
I was gonna mention that he should just store a ram value and check it during certain routines to see if they can run or not, but then the example would've been too big, and I was going for something simple. And yeah thats a much better way to keep things paused, just set a value nd at certain routines just don't let them run if the value = $01 or something :-)

I guess the better, simpler, more structurated and more logistical thing is :
To have a NMI routine that upload PPU registers, SprRam, etc... from buffers, call the sound code, etc....
Your main programm can just does the actual gameplay things and upload buffer to be read in a NMI.
That would probably work much better for him. That way he could just go into an infinite loop, but all the "necessarry" things willl occure because the NMI keeps going.
So you have to check the JoyPad in the main thing, if start if pressed you have to wait it to be released, then wait it to be pressed again, then continius gameplay (otherwise you game will pause and unpause 60 times per seconds, and I guess that's not the thing you want). All NMI thing will of couse be still enabled with and witout pausing.
Heh, I even left that out in my code example. Eh, it was late. Anyway, he'll defintly need to do that or the pausing will be horrible. He'll prolly need to do something like that for other keys as well (depending on the kind of game he's making).

Post Reply