It is currently Wed Jan 18, 2017 4:58 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 7 posts ] 
Author Message
PostPosted: Thu Dec 15, 2016 1:43 pm 
Offline

Joined: Wed Sep 21, 2016 12:08 pm
Posts: 4
Work slowly continues on the development of an IDE (integrated development environment) for programming games for the NES.

I finished laying out the Universal NES Game Engine and have converted it to 6502 Assembly Code below. I will be building my own compiler in the IDE, so there may be some non-traditional formatting.

Attachment:
File comment: Flow diagram of game engine
NES Game Engine.pdf [243.19 KiB]
Downloaded 36 times


Code:
--------------------------------------------------------------------
HEADER:
--------------------------------------------------------------------

.inesprg 1   ; 1x 16KB PRG code
.ineschr 1   ; 1x  8KB CHR data
.inesmap 0   ; mapper 0 = NROM, no bank swapping
.inesmir 1   ; background mirroring

--------------------------------------------------------------------
VARIABLES:
--------------------------------------------------------------------

VAR.Scene

VAR.Scene.Next

VAR.Frame

VAR.GameState
//  0 = Initialize
//  1 = Construct
//  2 = Update
//  3 = Deconstruct

TBL.GameState
//  LBL.GameState.Initialize - 1
//  LBL.GameState.Construct - 1
//  LBL.GameState.Update - 1
//  LBL.GameState.Deconstruct - 1

VAR.NMIState
//  0 = DisableRendering
//  1 = LoadPaletes
//  2 = EnableRendering
//  3 = Wait
//  4 = Normal

TBL.NMIState
//  LBL.NMI.DisableRendering - 1
//  LBL.NMI.LoadPalettes - 1
//  LBL.NMI.EnableRendering - 1
//  LBL.NMI.Wait - 1
//  LBL.NMI.Normal - 1

TBL.Scene.Initialize
//  LBL.Scene0.Initialize - 1
//  LBL.Scene1.Initialize - 1
//  LBL.Scene2.Initialize - 1
//  ...
//  LBL.SceneN.Initialize - 1

TBL.Scene.Update
//  LBL.Scene0.Update - 1
//  LBL.Scene1.Update - 1
//  LBL.Scene2.Update - 1
//  ...
//  LBL.SceneN.Update - 1

TBL.Scene.Deconstruct
//  LBL.Scene0.Deconstruct - 1
//  LBL.Scene1.Deconstruct - 1
//  LBL.Scene2.Deconstruct - 1
//  ...
//  LBL.SceneN.Deconstruct - 1


PTR.Background

PTR.Background.Palette

PTR.Sprites

PTR.Sprites.Palette

BUF.Sprites  ($0200 - $02FF)
//+------+----------+--------------------------------------+
// Byte | Bits     | Description                          |
//+------+----------+--------------------------------------+
//|  0   | YYYYYYYY | Y Coordinate - 1. Consider the coor- |
//|      |          | dinate the upper-left corner of the  |
//|      |          | sprite itself.                       |
//|  1   | IIIIIIII | Tile Index #                         |
//|  2   | vhp000cc | Attributes                           |
//|      |          |   v = Vertical Flip   (1=Flip)       |
//|      |          |   h = Horizontal Flip (1=Flip)       |
//|      |          |   p = Background Priority            |
//|      |          |         0 = In front                 |
//|      |          |         1 = Behind                   |
//|      |          |   c = Upper two (2) bits of colour   |
//|  3   | XXXXXXXX | X Coordinate (upper-left corner)     |
//+------+----------+--------------------------------------+

VAR.PPUStack.Size ($0100)
BUF.PPUStack.High ($0101 - $0185)
BUF.PPUStack.Low  ($0186 - $01A0)
BUF.PPUStack.Value ($01A1 - $01FF)
// Buffer Allows for space for 85 PPU changes
// VBlank may only allow 64

VAR.PPUStack.High.Temp
VAR.PPUStack.Low.Temp
VAR.PPUStack.Value.Temp

VAR.Controller1
VAR.Controller2

VAR.Controller1.Old
VAR.Controller2.Old

VAR.Controller1.Pressed
VAR.Controller2.Pressed

VAR.Controller1.Released
VAR.Controller2.Released

--------------------------------------------------------------------
CODE:  Main Loop
--------------------------------------------------------------------

.bank 0
.org $8000

RESET:
  SEI          ; disable IRQs
  CLD          ; disable decimal mode

  LDX #$40
  STX $4017    ; disable APU frame IRQ
 
  LDX #$00
  STX $4010    ; disable DMC IRQs
  STA $2001    ; disable rendering

  STA VAR.Controller1.Old
  STA VAR.Controller2.Old

  LDA VAR.NMIState.Wait
  STA VAR.NMIState

  BIT $2002

  JSR LBL.VBlankWait
  JSR LBL.ClearRAM 
  JSR LBL.VBlankWait

  LDA #$00      ; Start Game at Scene 0
  STA VAR.Scene
  LDA VAR.GameState.Initialize
  STA VAR.GameState

LBL.Main

  JSR LBL.GameState.Launcher
  JMP LBL.Main

--------------------------------------------------------------------
CODE:  Main Subroutines
--------------------------------------------------------------------

LBL.ClearRAM
  LDA #$00
  STA $0000, x
  STA $0100, x
  STA $0200, x
  STA $0300, x
  STA $0400, x
  STA $0500, x
  STA $0600, x
  STA $0700, x
  INX
  BNE LBL.ClearRAM
  RTS

--------------------------------------------------------------------

LBL.VBlankWait:
  BIT $2002
  BPL LBL.VBlankWait
  RTS
 
--------------------------------------------------------------------

LBL.GameState.Launcher:
  LDA VAR.GameState
  ASL
  TAX
  LDA TBL.GameState + 1, x
  PHA
  LDA TBL.GameState, x
  PHA
  RTS

--------------------------------------------------------------------

LBL.GameState.Initialize
  JSR LBL.Scene.Initialize.Launcher
  LDA GameState.Construct
  STA GameState
  RTS

--------------------------------------------------------------------

LBL.Scene.Initialize.Launcher
  LDA VAR.Scene
  ASL
  TAX
  LDA TBL.Scene.Initialize + 1, x
  PHA
  LDA TBL.Scene.Initialize, x
  PHA
  RTS

--------------------------------------------------------------------

LBL.GameState.Construct
  LDA NMI.State.DisableRendering
  STA NMI.State
  JSR LBL.WaitForNMIChange

  JSR LBL.LoadBackground
  JSR LBL.LoadSprites

  LDA NMI.State.LoadPalettes
  STA NMI.State
  JSR LBL.WaitForNMIChange

  LDA NMI.State.EnableRendering
  STA NMI.State
  JSR LBL.WaitForNMIChange

  LDA #$00
  STA VAR.Frame

  LDA NMI.State.Normal
  STA NMI.State
 
  LDA GameState.Update
  STA GameState

  LDA #$00
  STA VAR.Controller1.Old

  LDA #$00
  STA VAR.Controller2.Old

  RTS
 
--------------------------------------------------------------------

LBL.WaitForNMIChange
  LDA NMI.State
  CMP NMI.State
  BNE LBL.WaitForNMIChange
  RTS

--------------------------------------------------------------------

LBL.GameState.Update
  JSR LBL.WaitForNMIChange
  JSR LBL.ReadControllers
  JSR LBL.Scene.Update.Launcher
  LDA VAR.Scene
  CMP VAR.Scene.Next
  BNE LBL.GameState.Update.Transition
  RTS

LBL.GameState.Update.Transition
  LDA VAR.GameState.Deconstruct
  STA VAR.GameState
  RTS

--------------------------------------------------------------------

LBL.GameState.Deconstruct
  JSR LBL.Scene.Deconstruct.Launcher
  LDA VAR.Scene.Next
  STA VAR.Scene
  LDA VAR.GameState.Initialize
  STA VAR.GameState
  RTS
 
--------------------------------------------------------------------

LBL.ReadControllers
  LDA #$01
  STA $4016
  LDA #$00
  STA $4016
  LDX #$08

  // bit:       7     6     5     4     3     2     1     0
  // button:    A     B   select start  up   down  left right

  LDA VAR.Controller1;
  STA VAR.Controller1.Old;
 
  LDA VAR.Controller2;
  STA VAR.Controller2.Old;

LBL.ReadController1.Loop
  LDA $4016
  LSR A
  ROL VAR.Controller1
  DEX
  BNE LBL.ReadController.Loop

LBL.ReadController2.Loop
  LDA $4017
  LSR A
  ROL VAR.Controller2
  DEX
  BNE LBL.ReadController2.Loop

  LDA VAR.Controller1
  EOR #$FF
  AND VAR.Controller1.Old
  STA VAR.Controller1.Released

  LDA VAR.Controller1.Old
  EOR #$FF
  AND VAR.Controller1
  STA VAR.Controller1.Pressed

  LDA VAR.Controller2
  EOR #$FF
  AND VAR.Controller2.Old
  STA VAR.Controller2.Released

  LDA VAR.Controller2.Old
  EOR #$FF
  AND VAR.Controller2
  STA VAR.Controller2.Pressed

  RTS

--------------------------------------------------------------------

LBL.LoadBackground
  LDA #$20;
  STA $2006
  LDY #$00;
  STY $2006
 
  LDX #$04

LBL.LoadBackground.Loop 
  LDA PTR.Background, y
  STA $2007
  INY
  BNE LBL.LoadBackground.Loop
  DEX
  INC PTR.Background + 1
  BNE LBL.LoadBackground.Loop
  RTS

--------------------------------------------------------------------

LBL.LoadSprites:
  LDX PTR.Sprites

LBL.LoadSprites.Loop:
  LDA PTR.Sprites, X
  STA BUF.Sprites, X
  DEX
  BNE LBL.LoadSprites.Loop
 
  RTS

--------------------------------------------------------------------

LBL.PushPPUStack:

  INC VAR.PPUStack.Size
  LDX VAR.PPUStack.Size

  LDA VAR.PPUStack.High
  STA BUF.PPUStack.High, x

  LDA VAR.PPUStack.Low
  STA BUF.PPUStack.Low, x

  LDA VAR.PPUStack.Value
  STA BUF.PPUStack.Value, x

  RTS

--------------------------------------------------------------------
CODE:  NMI
--------------------------------------------------------------------

LBL.NMI
  JSR LBL.SaveRegisters
  JSR LBL.NMIState.Launcher
  JSR LBL.RestoreRegisters
  RTI

--------------------------------------------------------------------
CODE:  NMI Subroutines
--------------------------------------------------------------------

LBL_NMI_SaveRegisters:
  PHA
  TXA
  PHA
  TYA
  PHA
  RTS

--------------------------------------------------------------------

LBL_NMI_RestoreRegisters:
  PLA
  TAY
  PLA
  TAX
  PLA
  RTS

--------------------------------------------------------------------

LBL.NMIState.Launcher:
  LDA VAR.NMIState
  ASL
  TAX
  LDA TBL.NMIState + 1, x
  PHA
  LDA TBL.NMIState, x
  PHA
  RTS

--------------------------------------------------------------------

LBL.NMI.DisableRendering
  LDA #$00   ;Disable Rendering
  STA $2001   ;Disable Rendering
  LDA VAR.NMIState.Wait
  STA VAR.NMIState
  RTS

--------------------------------------------------------------------

LBL.NMI.LoadPalettes

  LDA $2002 ; reset High/Low Bit in PPU
  LDA #$3F
  STA $2006
  LDA #$00
  STA $2006

  LDX #$00

LBL.NMI.LoadPalettes.BackgroundLoop:
  LDA PTR.Background.Palettes, x
  STA $2007
  INX
  CPX #$10
  BNE LBL.NMI.LoadPalettes.BackgroundLoop

  LDX #$00

LBL.NMI.LoadPalettes.SpriteLoop:
  LDA PTR.Sprite.Palettes, x
  STA $2007
  INX
  CPX #$10
  BNE LBL.NMI.LoadPalettes.SpriteLoop

  LDA VAR.NMIState.Wait
  STA VAR.NMIState

  RTS

--------------------------------------------------------------------

LBL.NMI.EnableRendering
  LDA #%00011110
  STA $2001
  LDA VAR.NMIState.Wait
  STA VAR.NMIState
  RTS

--------------------------------------------------------------------

LBL.NMI.Wait
  RTS

--------------------------------------------------------------------

LBL.NMI.Normal
  JSR LBL.CopySprites
  JSR LBL.BurnStack
  INC VAR.Frame
  RTS

--------------------------------------------------------------------

LBL.CopySprites
  LDA HIGH(BUF.Sprite)
  STA $4014
  RTS

--------------------------------------------------------------------

LBL.BurnStack
  LDA $2002
  LDX VAR.PPUStack.Size

LBL.BurnStack.Loop:
  LDA VAR.PPUStack.High,x
  STA $2006
  LDA VAR.PPUStack.Low,x
  STA $2006
  LDA VAR.PPUStack.Value,x
  STA $2007
  DEX
  BNE LBL.BurnStack.Loop

  RTS


Last edited by Lucradan on Tue Jan 10, 2017 3:04 pm, edited 3 times in total.

Top
 Profile  
 
PostPosted: Thu Dec 15, 2016 9:18 pm 
Offline
User avatar

Joined: Mon Jan 03, 2005 10:36 am
Posts: 2749
Location: Tampere, Finland
PDF would be preferable to .pptx.

_________________
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: kkfos.aspekt.fi


Top
 Profile  
 
PostPosted: Tue Jan 10, 2017 3:03 pm 
Offline

Joined: Wed Sep 21, 2016 12:08 pm
Posts: 4
Here is an example of a the code for a "Scene".

Code:
--------------------------------------------------------------------
SCENE 1:  Sprite Animation Test
--------------------------------------------------------------------

DESCRIPTION:

This scene will test a sprite animation.  Pressing left will slow down the animation.  Pressing right will speed up the animation. Pressing Start will return to the Menu Scene

--------------------------------------------------------------------
VARIABLES:
--------------------------------------------------------------------

DAT.Scene1.Background
DAT.Scene1.Background.Palette
DAT.Scene1.Sprite
DAT.Scene1.Sprite.Palette

VAR.Scene1.Animation.Redraw

VAR.Scene1.Animation.Timer
VAR.Scene1.Animation.Speed
CON.Scene1.Animation.Speed.Minimum
CON.Scene1.Animation.Speed.Maximum

VAR.Scene1.Animation.Current
VAR.Scene1.Animation.Next

VAR.Scene1.Ticker.High
VAR.Scene1.Ticker.Low

CON.Scene1.Ticker.High.Location.HighByte
CON.Scene1.Ticker.High.Location.LowByte

CON.Scene1.Ticker.Low.Location.HighByte
CON.Scene1.Ticker.Low.Location.LowByte


VAR.Scene1.Temp

DAT.Scene1.Animation
//  Contains the frames of the sprite animation
//  BYTE1:    Next Frame Index
//  BYTE2:    Frame 1, Sprite 1, Y
//  BYTE3:    Frame 1, Sprite 1, Tile Index
//  BYTE4:    Frame 1, Sprite 1, Attribute
//  BYTE5:    Frame 1, Sprite 1, X
//  BYTE6:    Frame 1, Sprite 2, Y
//  BYTE7:    Frame 1, Sprite 2, Tile Index
//  BYTE8:    Frame 1, Sprite 2, Attribute
//  BYTE9:    Frame 1, Sprite 2, X 
//  ...       
//  ...       Next Frame Index
//  ...       Frame 2, Sprite 1, Y
//  ...



--------------------------------------------------------------------
SCENE 1:  CODE
--------------------------------------------------------------------

LBL.Scene1.Initialize
 
  LDA LOW(DAT.Scene1.Background)
  STA PTR.Background
  LDA HIGH(DAT.Scene1.Background)
  STA PTR.Background + 1

  LDA LOW(DAT.Scene1.Background.Palette)
  STA PTR.Background.Palette
  LDA HIGH(DAT.Scene1.Background.Palette)
  STA PTR.Background.Palette + 1

  LDA LOW(DAT.Scene1.Sprite)
  STA PTR.Sprite
  LDA HIGH(DAT.Scene1.Sprite)
  STA PTR.Sprite + 1

  LDA LOW(DAT.Scene1.Sprite.Palette)
  STA PTR.Sprite.Palette
  LDA HIGH(DAT.Scene1.Sprite.Palette)
  STA PTR.Sprite.Palette + 1

  LDA CST.Scene1.Animation.Speed.Minimum
  STA VAR.Scene1.Animation.Speed

  LDA #$00
  STA VAR.Scene1.Animation.Timer
 
  LDA #$00
  STA VAR.Scene1.Animation.Current

  LDA DAT.Scene1.Animation
  STA VAR.Scene1.Animation.Next

 RTS

--------------------------------------------------------------------
LBL.Scene1.Update

  INC VAR.Scene1.Animation.Timer
  CMP VAR.Scene1.Animation.Speed
  BNE LBL.Scene1.Update.ControllerCheck

    LDA #$00
    STA VAR.Scene1.Animation.Timer

    LDA VAR.Scene1.Animation.Next
    STA VAR.Scene1.Animation.Current
    TAX
    LDA DAT.Scene1.Animation,X
    STA VAR.Scene1.Animation.Next

    LDA VAR.Scene1.Animation.Next
    STA VAR.Scene1.Temp

    LDA VAR.Scene1.Animation.Current
    CMP VAR.Scene1.Animation.Next

    BCS LBL.Scene1.Update.IsLastFrame
    JMP LBL.Scene1.Update.Increment

LBL.Scene1.Update.IsLastFrame:
    LDA DAT.Scene1.Animation.Size
    STA VAR.Scene1.Temp

LBL.Scene1.Update.Increment: 
    LDX VAR.Scene1.Animation.Current
    LDY #$00

LBL.Scene1.Update.Sprite.CopyLoop
    INX
    INY
    CPX VAR.Scene1.Temp
    BEQ LBL.Scene1.Update.ControllerCheck
     
      LDA DAT.Scene1.Animation,x
      STA BUF.Sprites,y
      JMP LBL.Scene1.Update.Sprite.CopyLoop

LBL.Scene1.Update.ControllerCheck:

LDA VAR.Controller1.Pressed
LBL.Scene1.Pressed.Left:
  CMP #%00000010
  BNE LBL.Scene1.Pressed.Right
    INC VAR.Scene1.Animation.Speed
    CMP VAR.Scene1.Animation.Speed.Maximum+1
    BNE LBL.Scene1.Update.Ticker
      LDA VAR.Scene1.Animation.Speed.Maximum
      STA VAR.Scene1.Animation.Speed
      JMP LBL.Scene1.Update.Ticker

LBL.Scene1.Pressed.Right:
  CMP #%00000001
  BNE LBL.Scene1.Pressed.Start
    DEC VAR.Scene1.Animation.Speed
    CMP VAR.Scene1.Animation.Speed.Minimum-1
    BNE LBL.Scene1.Update.Ticker
      LDA VAR.Scene1.Animation.Speed.Minimum
      STA VAR.Scene1.Animation.Speed

LBL.Scene1.Update.Ticker:
   LDA VAR.Scene1.Animation.Speed
   AND #%00001111
   STA VAR.Scene1.Ticker.Low

   LDA VAR.Scene1.Animation.Speed
   LSR A
   LSR A
   LSR A
   LSR A
   STA VAR.Scene1.Ticker.High

   LDA VAR.Scene1.Ticker.Low
   STA VAR.PPUStack.Value.Temp
   LDA CON.Scene1.Ticker.Low.Location.LowByte
   STA VAR.PPUStack.Low.Temp
   LDA CON.Scene1.Ticker.Low.Location.HighByte
   STA VAR.PPUStack.High.Temp
   JSR LBL.PushPPUStack

   LDA VAR.Scene1.Ticker.High
   STA VAR.PPUStack.Value.Temp
   LDA CON.Scene1.Ticker.High.Location.LowByte
   STA VAR.PPUStack.Low.Temp
   LDA CON.Scene1.Ticker.High.Location.HighByte
   STA VAR.PPUStack.High.Temp
   JSR LBL.PushPPUStack
   JMP LBL.Scene1.Update.Exit:
   
LBL.Scene1.Pressed.Start:
  CMP  #%00010000
  BNE  LBL.Scene1.Update.Exit
     LDA #$00
     STA VAR.Scene.Next
     LDA VAR.GameState.Deconstruct
     STA VAR.GameState   

LBL.Scene1.Update.Exit:
  RTS

--------------------------------------------------------------------
LBL.Scene1.Deconstruct
  RTS


Top
 Profile  
 
PostPosted: Tue Jan 10, 2017 7:40 pm 
Offline
User avatar

Joined: Mon Sep 15, 2014 4:35 pm
Posts: 2821
Location: Nacogdoches, Texas
Damn, The game engine I'm making for the SNES is about to hit 2000 lines...


Top
 Profile  
 
PostPosted: Thu Jan 12, 2017 5:23 pm 
Offline

Joined: Tue May 28, 2013 5:49 am
Posts: 406
Location: Sweden
What exactly is a "Scene", in this context, in the first place?


Top
 Profile  
 
PostPosted: Fri Jan 13, 2017 2:15 pm 
Offline

Joined: Wed Sep 21, 2016 12:08 pm
Posts: 4
Pokun wrote:
What exactly is a "Scene", in this context, in the first place?


A Scene doesn't have an official definition, and is more of a way I can break down a game into it's smallest programmable parts.

If I think about Legend of Zelda, then each square of the map could be it's own scene along with the item select menu.

A Scene does have some properties properties that define it and are used in the Initialization subroutine
1. A Background
2. A Background Palette
3. A Set of Sprites
4. A Sprite Palette

Some of this could be reused from other scenes (hence the use of pointers).

My vision is to use this structure so that a person can create NES game through a IDE and not have to worry about 6502 assembly (all is done through a user friendly GUI, much like Mario Maker)

Here is a list of things I will be tackling at a future date:

1. Scrolling
2. Menu / Status Bars.


Top
 Profile  
 
PostPosted: Sat Jan 14, 2017 12:32 am 
Offline

Joined: Tue May 28, 2013 5:49 am
Posts: 406
Location: Sweden
I see.


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

All times are UTC - 7 hours


Who is online

Users browsing this forum: Google [Bot] and 3 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