It is currently Wed Dec 13, 2017 2:33 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 6 posts ] 
Author Message
 Post subject: best game engine methods
PostPosted: Sun Nov 06, 2005 6:21 pm 
Offline

Joined: Sat Oct 02, 2004 12:07 pm
Posts: 163
i have spent today thinking about an engine i was writing for a game i was making a few months back. after a while i started wondering about others possible effective ways that other nes developers might use. so, what methods do you all use for games engines?

the method i have used divides the game up in to... uhh.. states.
each state has its own NMI, MGL (main-game-loop), and INIT subs. a subroutine called change_state will lookup the address for the NMI and MGL and copy it to RAM, then it will jump to the address given to INIT to setup all options (timer, controller options, inital background, data loading,etc) for that state. different flags can be set by the three state subs, such as different timer options, to rest for a vblank, check for zapper hit, update sprites, scrolling, etc.

the basic engine flow is similar to this
Reset:
_normal nes startup stuff
_clear ram
_change_to_state 0
main game loop:
_if(zapper) then check zapper hit
_jump to state's MGL

NMI:
_if(timer) then do timer stuff
_get joypad input
_jump to state's NMI
_if(sprite update) update sprites
_if(scroll) set scroll
_rti


Top
 Profile  
 
 Post subject:
PostPosted: Sun Nov 06, 2005 10:39 pm 
Offline
User avatar

Joined: Sun Jun 05, 2005 2:04 pm
Posts: 2142
Location: Minneapolis, Minnesota, United States
You know, I was going to start a topic about good engines. I am wondering what is the best way to go about things. I was thinking that my methods weren't exactly the best. Back when I discovered this, I was like "Oh, wow! this is great!". What I do is base every little thing on the values of variables. Like this:

keyroutine:
blah code
startkey:
lda titlescreen
cmp #$01
bne routine
blah code
routine:
code that says
when start is
pressed, do whatever
your game does
when you
press start
at the title screen.

I do things like that, but I have like a TON of variables, you know? Like variables like "washit" for when a target was hit. But I do think I have a beautiful routine for the numbering system. This routine I am proud of, even though like anyone could have written it. Here it is:

Code:
scoring:
   lda #$01
   cmp rhit
   bne proceed
   rts

proceed:
   lda #$01
   sta rhit
   lda score1
   cmp #$39
   beq backtoit
   inc score1
   lda #$01
   sta itncr
   jmp lada

lada:
   lda #$20
   sta $2006
   lda #$24
   sta $2006

   lda #$00
   sta $2005
   sta $2005
   lda score1
   sta $2007
   rts

backtoit:
   lda score2
   cmp #$39
   beq increase2
   inc score2

ladad:
   lda #$20
   sta $2006
   lda #$23
   sta $2006

   lda #$00
   sta $2005
   sta $2005
   lda score2
   sta $2007
   jmp strzero
   rts

increase2:
   lda score3
   cmp #$30
   beq maxout
   inc score3

   lda #$20
   sta $2006
   lda #$22
   sta $2006

   lda #$00
   sta $2005
   sta $2005
   lda score3
   sta $2007
   jmp strzero1
   rts

maxout:
   rts
   

strzero:
   lda #$30
   sta score1
   jmp lada
strzero1:
   lda #$30
   sta score2
   jmp ladad


This is a code for a shooter game I made. rhit is a variable for "was hit". So when the bullet x and y is equal to the enemy x and y, #$01 is stored in rhit. score1 is the 1's digit score2 is the 10's digit etc. Well, I just thought I'd at least show that when I had somewhat of an oppertunity. Well, this is my NMI routine:

Code:

nmi:
   lda #3
   sta $4014 ; sprite dma
   jsr keys ; key routine
   jsr itshot ; see if bullet was shot
   jsr seehit ; see if bullet hit enemy
   jsr scoring ;if bullet hit the enemy increase score
   jsr ohhhh ;fire cannon at your character's x and y pos
   jsr wasit ; see if cannon trying to shoot you down missed and reached the top of the screen
   jsr thisroute ; move enemy at bottom of screen around
   inc vbl_count ; increase vblank variable
   rti


I just realized that when I posted that code, I had a whole bunch of those routines in the wrong place. I realized I was jsring to wasit before ohhhh, and if you look, that is bad. Well that's my games engine. It's all about the NMI, I say. I tried doing stuff in my infinate loop, it never works. It always is glitchy. Most stuff you want to do in vblank. Unless... am i wrong? I don't think I am, but I could be...


Top
 Profile  
 
PostPosted: Sun Nov 06, 2005 11:58 pm 
Offline
Site Admin
User avatar

Joined: Mon Sep 20, 2004 6:04 am
Posts: 3487
Location: Indianapolis
WhoaMan wrote:
NMI:
_if(timer) then do timer stuff
_get joypad input
_jump to state's NMI
_if(sprite update) update sprites
_if(scroll) set scroll
_rti


I do the joypad and timer code last (tho the timer first could be useful, if you want to check for and escape from a recursive NMI).

Vblank time is short, so the rule I follow when I want to max out the PPU is to run all the video/sprite updates before anything that can take a variable amount of cpu cycles. That includes checking for sprite updates, heheh, there's no harm in reuploading the same data every frame (actually it makes sense too, since it's DRAM and will die out if you leave it alone for too long).


Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 07, 2005 10:26 am 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7314
Location: Chexbres, VD, Switzerland
Effectivly, setting, no, engine isn't the right word, designing rather how game data is structurated and rendered, but rather programming style, or programming stucture, witch one is better, and well, there is probably no real answer.

Personally, what I ofen do is put some structured PPU updates in my VBlank (for Name and Attribute tables) after doing the standard sprite DMA. Putting some minor stuff in VBlank routine is needed, instead of direct returning to the main code, to avoid repeating some basic PPU updates a lot of times in the main code (like Final Fantasy does). However, input *everything* in VBlank routine and no main code at all (like Mario Bross, Contra, and all Konami games) is probably rather bad, what I'm not even able to try this. This disables you to have any game loop, every frame should have it's pure logic.
Some games, such as Battletoads, or Nes Snake 2, does calculation permanantly. I really can't think how a such thing would be designed, because I really can't see what calculation you could do witout regard to the main timing. Ask Matrizx for more information, he certainly knows how he coded his own game, and, showing the result, the method isn't too bad. Well, using a "bad code structure" could still lead to a good game, but with more difficulties to actually programm it.

_________________
Life is complex: it has both real and imaginary components.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 08, 2005 2:39 am 
Offline

Joined: Sat Oct 23, 2004 4:25 pm
Posts: 19
Location: Norway
In NeSnake 2 i only do VRAM updates and sprite updates in the NMI, then instead of doing other parts of the game engine in NMI, i increase a bunch of frame counters. The NMI quits, then the RESET loop notices the frame counters are >= 1 and does further calculations (and sets up PPU buffers). I dont know, i got used to doing it like that. But i dont like the idea of another VBLANK ocurring while the previous NMI is still doing stuff. (which could happen in an all-NMI-based game). Other of those constant calculations Bregalad mentioned is the random number generator, and the joypad checking routine if i remember. I also do sound in RESET, which takes a deal of time.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 08, 2005 10:52 am 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7314
Location: Chexbres, VD, Switzerland
So the only difference between your coding style and my coding style is that you're not doing sound in VBlank routine, and that you're still doing random number generation/joypad reading or something between VBlank pass check, but I personally rather prefer do only VBlank check, and my random number generation routine is called once at the end of my VBlank routine (actually those are the only two non-PPU stuff I do in my VBlank routine, sound and random number, along with setting VBlank flags).

_________________
Life is complex: it has both real and imaginary components.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 6 posts ] 

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 4 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group