Nuts & Milk GFX glitch

Are you new to 6502, NES, or even programming in general? Post any of your questions here. Remember - the only dumb question is the question that remains unasked.

Moderator: Moderators

Post Reply
griever
Posts: 39
Joined: Thu Apr 05, 2007 1:34 pm

Nuts & Milk GFX glitch

Post by griever »

Hello, everybody. If you played 'Nuts & Milk', you may notice a little white
scratch on the top of the screen in NTSC mode. And in PAL emulation it becomes smthng like big arrow... Well, I assume, that it's attrib table data, and maybe it's connected with loopy's document about scrolling:
you can think of bits 5,6,7,8,9 as the "y scroll"(*8). this functions
slightly different from the X. it wraps to 0 and bit 11 is switched when
it's incremented from _29_ instead of 31. there are some odd side effects
from this.. if you manually set the value above 29 (from either 2005 or
2006), the wrapping from 29 obviously won't happen, and attrib data will be used as name table data.
So, the question is: could this white thing be removed?
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post by tepples »

Yes, by hacking the ROM to do negative scrolling properly (start from line 224 of the other nametable, not line 248 of this nametable).
griever
Posts: 39
Joined: Thu Apr 05, 2007 1:34 pm

Post by griever »

Ah, I've mistaken: I mean, the problem is garbage pixel line on top of the screen. And arrow=sprite- it's all right with it.

Hmm. Thanks, but how can it be done? I mean, I can't believe, that Game Developers just forgot to make proper scrolling...
Anyway, sorry for that, but can anybody tell me how to start from line 224 of the other nametable?
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post by tepples »

griever wrote:Ah, I've mistaken: I mean, the problem is garbage pixel line on top of the screen. And arrow=sprite- it's all right with it.
If it's a sprite, then that means the problem is with the way the RAM copy of OAM is being cleared. Clearing OAM to 0 will result in a bunch of overlapping sprites whose upper left corner is (0, 1). These will often (but not always) be hidden by the NTSC overscan. The proper method is to clear OAM to the value $F0, which positions the unused sprites below the screen.
Hmm. Thanks, but how can it be done? I mean, I can't believe, that Game Developers just forgot to make proper scrolling...
Anyway, sorry for that, but can anybody tell me how to start from line 224 of the other nametable?

Code: Select all

PPUCTRL = $2000
PPUSCROLL = $2005

  lda lastPPUCTRL  ; you should have a variable like this
  eor #$02  ; toggle the vertical nametable selection bit
  sta PPUCTRL
  lda #0  ; or whatever other X-scroll value you want
  sta PPUSCROLL
  lda #232  ; or whatever other X-scroll value you want
  sta PPUSCROLL
dvdmth
Posts: 354
Joined: Wed Mar 22, 2006 8:00 am

Post by dvdmth »

Graphical glitches at the top (and bottom) of the screen can go unnoticed because these edges are often cut off due to NTSC overscan. In fact, there are some situations where glitches are unavoidable (for instance, sprites cannot scroll smoothly off the top of the screen).

Developers often do screw things up, causing glitches that are unnecessary. An example is Legend of Zelda's vertical scrolling engine, which (a) doesn't write to $2006 with the correct value (causing a small vertical "shake" at the start/end of the scroll) and (b) writes to $2006 too early, causing a small graphical glitch in the lower-right corner of the status bar. The game also reads twice from $2007 after writing to $2006, which suggests that they really didn't know how the trick worked to begin with.
"Last version was better," says Floyd. "More bugs. Bugs make game fun."
griever
Posts: 39
Joined: Thu Apr 05, 2007 1:34 pm

Post by griever »

So, this code must be executed every scroll refresh? Well, I've made a little hack, but nothing changed...
Plus this sprite - even if it's coordinates=F0 or > it doesn't disappear!
I think, it's just another sprite with same index appeared.
Ah, damn. Well, nevermind - I guess it's just not for my knowledge. Thanks for anwers!
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post by tepples »

griever wrote:So, this code must be executed every scroll refresh? Well, I've made a little hack, but nothing changed...
A graphics engine that draws a varying number of sprites in the scene usually clears out the rest of the display list before sending it to the PPU. For example, Tetramino does this at the end of each frame:

Code: Select all

fill_rest_of_sprites:
  lda sprite_index
  and #%11111100
  tax
  lda #$ef
@loop:
  sta OAM,x
  inx
  inx
  inx
  inx
  bne @loop

  ; setup up sprite 0 at (224, 230)
  lda #230-1
  sta OAM
  lda #$67
  sta OAM+1
  lda #%00100011  ; behind
  sta OAM+2
  lda #224
  sta OAM+3
  ldx #4
  stx sprite_index
  rts
You need to find N&M's corresponding code and hack it so that it clears out unused sprites with y=$EF through $FF instead of y=$00.
Plus this sprite - even if it's coordinates=F0 or > it doesn't disappear!
I think, it's just another sprite with same index appeared.
You have to set all the unused sprites to y=$F0 or lower.
griever
Posts: 39
Joined: Thu Apr 05, 2007 1:34 pm

Post by griever »

ok, maybe, this was covered, but look at this piece of code, which loads palete(it's from cliffhanger game)

Code: Select all

$C012:A9 3F     LDA #$3F                   A:00 X:C2 Y:FF P:nvUbdIZC
$C014:8D 06 20  STA $2006 = #$00           A:3F X:C2 Y:FF P:nvUbdIzC
$C017:A9 00     LDA #$00                   A:3F X:C2 Y:FF P:nvUbdIzC
$C019:8D 06 20  STA $2006 = #$00           A:00 X:C2 Y:FF P:nvUbdIZC
$C01C:A2 CF     LDX #$CF                   A:00 X:C2 Y:FF P:nvUbdIZC
$C01E:20 19 DF  JSR $DF19                  A:00 X:CF Y:FF P:NvUbdIzC
$DF19:B5 75     LDA $75,X @ $0144 = #$00   A:00 X:CF Y:FF P:NvUbdIzC
$DF1B:8D 07 20  STA $2007 = #$00           A:10 X:CF Y:FF P:nvUbdIzC
What the hell? STA $2007 = #$00 A:10 <--!!! where did this 'A=$10' come from :shock:
User avatar
Disch
Posts: 1848
Joined: Wed Nov 10, 2004 6:47 pm

Post by Disch »

griever wrote:

Code: Select all

$DF19:B5 75     LDA $75,X @ $0144 = #$00   A:00 X:CF Y:FF P:NvUbdIzC
$DF1B:8D 07 20  STA $2007 = #$00           A:10 X:CF Y:FF P:nvUbdIzC
What the hell? STA $2007 = #$00 A:10 <--!!! where did this 'A=$10' come from :shock:
Zero Page,X mode wraps to zero page if the addition of X causes it to exceed $00FF. The debugger here is showing an incorrect read address (and thus, an incorrect read value). That LDA is actually reading from $0044... which apparently contains $10.
griever
Posts: 39
Joined: Thu Apr 05, 2007 1:34 pm

Post by griever »

Ah, I see. Thanks a lot :P
Post Reply