NintendoAge http://nintendoage.com/forum/ -Sqooner Nerdy Nights week 6 http://nintendoage.com/forum/messageview.cfm?catid=22&threadid=8172 2015-11-06T09:57:48 -05.00 bunnyboy 119 Originally posted by: sempressimo

Thanks Mega Mario Man, now I have room switching working. I do get a quick black flash when switching, I know is because I am turning on and off the PPU, just wondering if this is the standard way or if there is a way around this?

Also, if I want to update just some background tiles, like the score for example, can I just update the value in my backgrounds .db(s) directly and that is it? Or does the PPU has to be turned off for this also?

 
Unfortunately, you are going to get the slight moment of black as the PPU is off at that time. When trying to render that many background tiles at one time, you have to disable the PPU.

For shorter lengths, the PPU does not need to be disabled, however, you still have to load the tiles during the NMI. I do this all of the time, especially in my current game I'm writing. These is only 1 8x8 sprite in the game, and its just an arrow to point to who's turn it is.

There is a spot in the game where I write 256 tiles to the background (1/4 of the screen) and I do turn off the PPU for that.

Here is some code from my current game, I never disable the PPU for any of those .db tables:

 LDA #$05
  STA TEXTLENGTH                     ;The length of the text being written to the screen (number of characters being written)
 
  LDA #$0E
  STA TEXTLOWBYTE  
  LDA #$21
  STA TEXTHIGBYTE
 
  LDA #LOW(PauseText)
  STA TextPointer
  LDA #HIGH(PauseText)
  STA TextPointer+1
 
  JSR LoadText
--------------------------------------------------------------------------------------------
LoadText:
  LDA $2002               ; read PPU status to reset the high/low latch
  LDA TEXTHIGBYTE
  STA $2006               ; write the high byte
  LDA TEXTLOWBYTE
  STA $2006               ; write the low byte
  LDY #$00                ; start y out at 0

LoadTextLoop:
  LDA [TextPointer], y     ; load data from address (background + the value in y)
  STA $2007                ; write to PPU
  INY                        ; y = y + 1
  CPY TEXTLENGTH           ; Compare Y to TEXTLENGTH
  BNE LoadTextLoop         ; Branch to LoadTextLoop if compare was Not Equal to zero
  RTS
 
PauseText:
  .db $19,$0A,$1E,$1C,$0E                 ;PAUSE
UnDrawPauseText:
  .db $24,$24,$24,$24,$24,$24,$24,$24     ;Undraw Pause
MissText:
  .db $16,$12,$1C,$1C                      ;MISS
Hit1Text:
  .db $11,$12,$1D,$24,$01                  ;HIT 1
Hit2Text:
  .db $11,$12,$1D,$24,$02                  ;HIT 2
Hit3Text:
  .db $11,$12,$1D,$24,$03                  ;HIT 3 ]]>
Nerdy Nights week 6 http://nintendoage.com/forum/messageview.cfm?catid=22&threadid=8172 2015-11-06T08:58:19 -05.00 bunnyboy 119 Originally posted by: Mega Mario Man
 
Originally posted by: sempressimo

I am using the code in these tutorials to load a full screen background. It works nicely, now I wan to load another "room", (i.e. load the tiles again into the nametable). I repurposed the routine into a subrotine, but the second time I call it, the new "room" won't load properly, instead I get a garbage version of the room;

LoadBackground:

  LDA $2002             ; read PPU status to reset the high/low latch
  LDA #$20
  STA $2006             ; write the high byte of $2000 address
  LDA #$00
  STA $2006             ; write the low byte of $2000 address

  ;LDX room_number       ; grab the actual room pointer
 
  LDA #$00
  STA pointerLo       ; put the low byte of the address of background into pointer
  LDA #HIGH(Room1)
  STA pointerHi       ; put the high byte of the address into pointer
 
  LDX #$00            ; start at pointer + 0
  LDY #$00
OutsideLoop:
 
InsideLoop:
  LDA [pointerLo], y  ; copy one background byte from address in pointer plus Y
  STA $2007           ; this runs 256 * 4 times
 
  INY                 ; inside loop counter
  CPY #$00
  BNE InsideLoop      ; run the inside loop 256 times before continuing down
 
  INC pointerHi       ; low byte went 0 to 256, so high byte needs to be changed now
 
  INX
  CPX #$04
  BNE OutsideLoop     ; run the outside loop 256 times before continuing down       

  LDA #%10010000   ; enable NMI, sprites from Pattern Table 0, background from Pattern Table 1
  STA $2000


  LDA #%00011110   ; enable sprites, enable background, no clipping on left side
  STA $2001

 
  RTS

Can this code be used to re-load the background or I am missing something?

Also can anyone point me to a tutorial on how to show a main screen, and the load the game level, as it should be the same concept I am trying to get working.
Let your NMI enable your PPU. Don't do this in the main code. Doing it in the main code will make it look like garbage (what you are seeing).
   LDA #%00011110   ; enable sprites, enable background, no clipping on left side
   STA $2001

Here is what my NMI looks like:
LDA #%10010000                    ; enable NMI, sprites from Pattern Table 0, background from Pattern Table 1
 STA $2000
 
LDA EnablePPUFlag                   ;Only Enable the PPU when this flag is enabled in the code.
BEQ .SKIP
    LDA #%00011110                   ;enable sprites, enable background, no clipping on left side
    STA $2001
    DEC EnablePPUFlag
  .SKIP:

(This is a Subroutine in my main code. The NMI calls this when I tell it to with the EnablePPUFlag)

EnablePPU:              ;<--------------------***********Subroutine called by the NMI to turn on the PPU
  LDA #%00011110   ; enable sprites, enable background, no clipping on left side
  STA $2001
  RTS



-----------
This is what my code looks like.

LDA #$00        ;<-------------------------**********Turn off the PPU in the Main Code First
STA $2001

  LDA #LOW(PlayingBackground)          ;<-----------------**********Load background routine*************
  STA BackgroundAddr
  LDA #HIGH(PlayingBackground)
  STA BackgroundAddr+1
  JSR LoadBackground
 
  LoadBackground:
  LDA $2002
  LDA #$20
  STA $2006             ; write the high byte of $2000 address
  LDA #$00
  STA $2006             ; write the low byte of $2000 address
 
  LDX #$04              ; Loop X 4 times
  LDY #$00              ; Loop Y 256 times
LoadBackgroundsLoop:
  LDA [BackgroundAddr],y          ;Load background from table in the pointer
  STA $2007                                     ;Write to screen
  INY
  BNE LoadBackgroundsLoop
; Outer loop
  INC BackgroundAddr+1           ; increment high byte of address backg to next 256 byte chunk
  DEX                    ; one chunk done so X = X - 1.
  BNE LoadBackgroundsLoop   ; if X isn't zero, do again
  LoadBackGroundDone:  
  RTS
 
  INC EnablePPUFlag             ;<--------------********This flag will tell the NMI to turn PPU back on*******



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

SIDE NOTE: You don't have to do anything with this code when turning the PPU on and off. That code only belongs in the PPU
  LDA #%10010000   ; enable NMI, sprites from Pattern Table 0, background from Pattern Table 1
  STA $2000



Hope that made sense. Good luck Thanks Mega Mario Man, now I have room switching working. I do get a quick black flash when switching, I know is because I am turning on and off the PPU, just wondering if this is the standard way or if there is a way around this?

Also, if I want to update just some background tiles, like the score for example, can I just update the value in my backgrounds .db(s) directly and that is it? Or does the PPU has to be turned off for this also?

  ]]>
Nerdy Nights week 6 http://nintendoage.com/forum/messageview.cfm?catid=22&threadid=8172 2015-11-03T15:28:41 -05.00 bunnyboy 119 ]]> Nerdy Nights week 6 http://nintendoage.com/forum/messageview.cfm?catid=22&threadid=8172 2015-11-03T14:31:25 -05.00 bunnyboy 119 Originally posted by: sempressimo

I am using the code in these tutorials to load a full screen background. It works nicely, now I wan to load another "room", (i.e. load the tiles again into the nametable). I repurposed the routine into a subrotine, but the second time I call it, the new "room" won't load properly, instead I get a garbage version of the room;

LoadBackground:

  LDA $2002             ; read PPU status to reset the high/low latch
  LDA #$20
  STA $2006             ; write the high byte of $2000 address
  LDA #$00
  STA $2006             ; write the low byte of $2000 address

  ;LDX room_number       ; grab the actual room pointer
 
  LDA #$00
  STA pointerLo       ; put the low byte of the address of background into pointer
  LDA #HIGH(Room1)
  STA pointerHi       ; put the high byte of the address into pointer
 
  LDX #$00            ; start at pointer + 0
  LDY #$00
OutsideLoop:
 
InsideLoop:
  LDA [pointerLo], y  ; copy one background byte from address in pointer plus Y
  STA $2007           ; this runs 256 * 4 times
 
  INY                 ; inside loop counter
  CPY #$00
  BNE InsideLoop      ; run the inside loop 256 times before continuing down
 
  INC pointerHi       ; low byte went 0 to 256, so high byte needs to be changed now
 
  INX
  CPX #$04
  BNE OutsideLoop     ; run the outside loop 256 times before continuing down       

  LDA #%10010000   ; enable NMI, sprites from Pattern Table 0, background from Pattern Table 1
  STA $2000


  LDA #%00011110   ; enable sprites, enable background, no clipping on left side
  STA $2001

 
  RTS

Can this code be used to re-load the background or I am missing something?

Also can anyone point me to a tutorial on how to show a main screen, and the load the game level, as it should be the same concept I am trying to get working. Let your NMI enable your PPU. Don't do this in the main code. Doing it in the main code will make it look like garbage (what you are seeing).
   LDA #%00011110   ; enable sprites, enable background, no clipping on left side
   STA $2001

Here is what my NMI looks like:
LDA #%10010000                    ; enable NMI, sprites from Pattern Table 0, background from Pattern Table 1
 STA $2000
 
LDA EnablePPUFlag                   ;Only Enable the PPU when this flag is enabled in the code.
BEQ .SKIP
    LDA #%00011110                   ;enable sprites, enable background, no clipping on left side
    STA $2001
    DEC EnablePPUFlag
  .SKIP:

(This is a Subroutine in my main code. The NMI calls this when I tell it to with the EnablePPUFlag)

EnablePPU:              ;<--------------------***********Subroutine called by the NMI to turn on the PPU
  LDA #%00011110   ; enable sprites, enable background, no clipping on left side
  STA $2001
  RTS



-----------
This is what my code looks like.

LDA #$00        ;<-------------------------**********Turn off the PPU in the Main Code First
STA $2001

  LDA #LOW(PlayingBackground)          ;<-----------------**********Load background routine*************
  STA BackgroundAddr
  LDA #HIGH(PlayingBackground)
  STA BackgroundAddr+1
  JSR LoadBackground
 
  LoadBackground:
  LDA $2002
  LDA #$20
  STA $2006             ; write the high byte of $2000 address
  LDA #$00
  STA $2006             ; write the low byte of $2000 address
 
  LDX #$04              ; Loop X 4 times
  LDY #$00              ; Loop Y 256 times
LoadBackgroundsLoop:
  LDA [BackgroundAddr],y          ;Load background from table in the pointer
  STA $2007                                     ;Write to screen
  INY
  BNE LoadBackgroundsLoop
; Outer loop
  INC BackgroundAddr+1           ; increment high byte of address backg to next 256 byte chunk
  DEX                    ; one chunk done so X = X - 1.
  BNE LoadBackgroundsLoop   ; if X isn't zero, do again
  LoadBackGroundDone:  
  RTS
 
  INC EnablePPUFlag             ;<--------------********This flag will tell the NMI to turn PPU back on*******



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

SIDE NOTE: You don't have to do anything with this code when turning the PPU on and off. That code only belongs in the PPU
  LDA #%10010000   ; enable NMI, sprites from Pattern Table 0, background from Pattern Table 1
  STA $2000



Hope that made sense. Good luck ]]>
Nerdy Nights week 6 http://nintendoage.com/forum/messageview.cfm?catid=22&threadid=8172 2015-11-03T13:54:04 -05.00 bunnyboy 119
LoadBackground:

  LDA $2002             ; read PPU status to reset the high/low latch
  LDA #$20
  STA $2006             ; write the high byte of $2000 address
  LDA #$00
  STA $2006             ; write the low byte of $2000 address

  ;LDX room_number       ; grab the actual room pointer
 
  LDA #$00
  STA pointerLo       ; put the low byte of the address of background into pointer
  LDA #HIGH(Room1)
  STA pointerHi       ; put the high byte of the address into pointer
 
  LDX #$00            ; start at pointer + 0
  LDY #$00
OutsideLoop:
 
InsideLoop:
  LDA [pointerLo], y  ; copy one background byte from address in pointer plus Y
  STA $2007           ; this runs 256 * 4 times
 
  INY                 ; inside loop counter
  CPY #$00
  BNE InsideLoop      ; run the inside loop 256 times before continuing down
 
  INC pointerHi       ; low byte went 0 to 256, so high byte needs to be changed now
 
  INX
  CPX #$04
  BNE OutsideLoop     ; run the outside loop 256 times before continuing down       

  LDA #%10010000   ; enable NMI, sprites from Pattern Table 0, background from Pattern Table 1
  STA $2000

  LDA #%00011110   ; enable sprites, enable background, no clipping on left side
  STA $2001
 
  RTS

Can this code be used to re-load the background or I am missing something?

Also can anyone point me to a tutorial on how to show a main screen, and the load the game level, as it should be the same concept I am trying to get working. ]]>
Nerdy Nights week 6 http://nintendoage.com/forum/messageview.cfm?catid=22&threadid=8172 2015-04-24T23:13:03 -05.00 bunnyboy 119 Nerdy Nights week 6 http://nintendoage.com/forum/messageview.cfm?catid=22&threadid=8172 2015-04-23T13:47:11 -05.00 bunnyboy 119 Nerdy Nights week 6 http://nintendoage.com/forum/messageview.cfm?catid=22&threadid=8172 2015-04-23T12:47:52 -05.00 bunnyboy 119 Thank you, really interesting reading from some more experienced homebrewers. Exactly what I was looking for as answers to that questions. I consider myself way more talented as a game designer (game concepts, mechanics, and such things) rather than as a good programmer (I learned to program because is needed to develop an idea I have for a game), so when more experienced programmers talk, I am always interested into it, no matter that I'm already skilled enough to understand, or I still need to chew on what I am explained a bit more to fully understand what I am told.

So, thank you for your detailed opinions and proposed alternatives, I'll surely care about read them more then once and understand further the advantages/disadvantages of each.

Nice to know that anyways there is not a "correct way": it seems, from these first replies, that it is more like "it depends" on various factors, as often is in many creative fields.

@Kevin
""" And it makes a lot more sense to try to explain this method to a beginner. Someone who is just trying to figure things out would have a hard time trying to grasp background compression. That's something that is adapted later. """

Indeed. I was talking now on a right next level, for my own interest, giving as done that your previous link fully solved Bullseye needs (which is what I guess).

Thanks All!

- Jack ]]>
Nerdy Nights week 6 http://nintendoage.com/forum/messageview.cfm?catid=22&threadid=8172 2015-04-23T12:28:18 -05.00 bunnyboy 119 Originally posted by: user

How many NES homebrewers actually save a full nametable in the ROM for each background in the game? If you are not targetting cart production, then ROM space is completely free so I don't bother with compression.

If you are targetting carts, then I only use compression to hit important ROM sizes like 128KB and 512KB.  The same chip is used for 80KB and 128KB so smaller data frequently doesn't matter.  I have done compression for CHR (8KB->3-5KB) and RLE for dragon warrior type maps, but I don't think I have done it for nametables. ]]>
Nerdy Nights week 6 http://nintendoage.com/forum/messageview.cfm?catid=22&threadid=8172 2015-04-23T11:39:35 -05.00 bunnyboy 119
The .RLE files can also be opened in NES Screen Tool as nametables just like normal uncompressed nametables.

user: You have to weigh whether making a custom compression/decompression routine for each scenario is beneficial. It may make your data smaller than e.g. RLE could, but by how much, and is it worth the extra time it takes to develop the data format and the algorithm (and possibly to layout the compressed data by hand)? ]]>