Thank you for taking the time to look at my code. Sometimes it's like pulling teeth to get a code review. Please bear with me while I try to understand the importance of each issue you uncovered.
Espozo wrote:Walker looks a lot more organized because it has huge barricades like this to separate different parts of the code. (The parts you jmp and jsr to.)
Ideally, that's what
.proc is for. But if
.proc isn't noticeable in the default settings of other users' existing favorite text editors, then I might need to put doc comments on all subroutines, even subroutines whose behavior is evident from the name and which takes no arguments. Here's what a doc comment from ppuclear.s looks like:
Code: Select all
;;
; Clears a nametable (2048 bytes) to a constant value.
; @param X starting address of nametable in VRAM (16-bit)
; @param Y value to write (16-bit)
Also, you need to change stuff like this:
My coding convention often includes a blank line
after a "skip forward" type label, roughly corresponding to the
End If of an
If ... Then ... End If block. You are correct that I was missing a blank line.
Why in the world do you even have two different places you can jump to if there's not a single thing in between them?
Because the jumps are for different reasons, one for not having hit the right side wall, and one for being completely done with collision checks for this frame. It helps with inserting additional checks at the right place should they become needed.
And yes, I discovered the same bug that thefox mentioned (a never taken branch that was intended to be always taken), but my laptop's 2 1/2-year-old battery immediately dropped from 35% to like 8% before I could finish this post about having done so. I had changed a
lda #$00 sta to
stz because hey, 65816, but I forgot to change the following branch. Here's what it has become:
Code: Select all
; Test for collision with side walls
; (in actual games, this would involve collision with a tile map)
cmp #28
bcs notHitLeft
lda #28
sta player_xhi
stz player_dxlo
bra doneWallCollision
notHitLeft:
cmp #212
bcc notHitRight
lda #211
sta player_xhi
stz player_dxlo
notHitRight:
; Additional checks for collision, if needed, would go here.
doneWallCollision:
Would this make more sense if I were to indent the "then clause" stuff?
Code: Select all
; Test for collision with side walls
; (in actual games, this would involve collision with a tile map)
cmp #28
bcs notHitLeft
lda #28
sta player_xhi
stz player_dxlo
bra doneWallCollision
notHitLeft:
cmp #212
bcc notHitRight
lda #211
sta player_xhi
stz player_dxlo
notHitRight:
; Additional checks for collision, if needed, would go here.
doneWallCollision:
Also, you seem to have the code that moves the character and checks for collision smack dap in between the code that sets the BG mode and stuff (I think?) and some code that does something with the tile data.
Current order of subroutine:
Top level functions:
nmi_handler,
main
"Game logic" subroutine:
move_player
Graphics subroutines:
draw_player_sprite,
draw_bg
Graphics data
I just think the main problem is that it is not a very clear where something ends and something starts.
In my ca65 coding convention, everything from
.proc to
.endproc can be pulled out and put into another file.
Let me know what other improvements I could add to make this more understandable, and then I can backport them to
the NES version.