Simple Mini-Game NESASM - ask for deep code analyze

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
sdm
Posts: 315
Joined: Tue Apr 11, 2006 4:08 am
Location: Poland

Simple Mini-Game NESASM - ask for deep code analyze

Post by sdm »

I created a simple mini-game. I asked for analyzing code. What is being done wrong, what to do differently, how fix etc. :)

I know that the code is written chaotic and has probably strange solution, but just trying to learn NES assembly (I am an n00b in these things :oops: :? )
So I have a large request for a deep analysis of the code, with descriptions. :))

Thanks. :)

http://www.youtube.com/watch?v=zO_V-4_Joig
Image
Last edited by sdm on Thu Jan 14, 2016 1:54 am, edited 1 time in total.
User avatar
Bregalad
Posts: 8036
Joined: Fri Nov 12, 2004 2:49 pm
Location: Caen, France

Re: Simple Mini-Game NESASM - ask for deep code analyze

Post by Bregalad »

Well, there's at least one thing you do terribly wrong. You are reading the controller by $4016 and directly take decisions on that. Do not do that ! Instead have a routine that reads all 8 buttons, stores them in a byte (use shift operations), where each bits correspond to a button. This routine is generic and you can use it anywhere in the game.

THEN, you read the buttons variable and take decisions according to it, depending on the state of your game. This is also more useful, if at a later point your game will have more than 1 state, and if you want to act on button presses (0->1 transitions) and releases (1->0 transitions) instead of just button state.

Do never use memory addresses directly in your code, except for hardware registers. Instead use labels, which allows you to re-arrange your variables in memory without breaking your code.
mikaelmoizt
Posts: 120
Joined: Sat Apr 12, 2014 12:11 pm
Location: Gothenburg, Sweden

Re: Simple Mini-Game NESASM - ask for deep code analyze

Post by mikaelmoizt »

After trying really hard to get this to work in asm6 adjusting syntax and layout it sortof worked.

I recognize this "everything I want to happen is gonna go into nmi and I will just sit on an eternal loop until triggered" layout.
Just on top of my head, there are some improvements to be done like moving controller reading routines outside nmi and putting the result into ram.
Also, you might consider keeping nmi a lot shorter by removing stuff like the music player to

Code: Select all

Forever:
acting on a nmi flag instead.

Like

Code: Select all

forever:
 lda nmiflag
 bne playmusic
 beq skipmusic

playmusic:
 jsr playmusicnow

 lda #$00
 sta nmiflag

skipmusic:
 jsr readjoy 
 jmp forever 
or something like that
I´ve got %01100011 problems but the BITs aint one.
sdm
Posts: 315
Joined: Tue Apr 11, 2006 4:08 am
Location: Poland

Re: Simple Mini-Game NESASM - ask for deep code analyze

Post by sdm »

Thank you for the information, this is my first real approach to NESASM. I will try to do anything more with a sense and study more NerdyNights :)

Despite the chaos in the code, I had a chance to run on real hardware. Using EPROM's chips, NROM cart and original Famicom (old CRT TV).Everything works fine and without problems, sometimes the third screen appears with an error but the same thing happens on the emulators.

ImageImage
Image
User avatar
Bregalad
Posts: 8036
Joined: Fri Nov 12, 2004 2:49 pm
Location: Caen, France

Re: Simple Mini-Game NESASM - ask for deep code analyze

Post by Bregalad »

Oh, I think the "do it everything in NMI" is a perfectly valid option, but it's not the easiest. But if you like it or feel like doing it, go ahead this is not something wrong. Most Konami games and early Nintendo games does it this way. (Castlevania, Gradius, SMB, Kid Icarus, Zelda, ...)

The other two options are "do it everything outside of NMI" (seen in Final Fantasy series, FDS BIOS), and the most common, the "Do most of the work outside NMI, but do music, graphics updates in NMI", which is done by the majority of games, including more recent Nintendo games.

Each of those 3 approaches has it's pros and cons so it's your decision. If you feel comfortable with the "everything in NMI" then just go ahead.

Using NESASM is not a very good idea. This assembler is not only limited and has bugs, but is also never updated officially by it's authors. ASM6 seems like a better choice, although personally I use another one but I regret my choice, but it's too late for changing, because once you have some thousands of ASM code for one assembler it's simply not possible to change anymore.

Using the sprites in shadow OAM as a game state is not a very good idea. It works if you are sure that 1) all your sprites are 8x8 and 2) you will never use sprite cycling.

In reality this is almost never the case, so it's better to store the state of your objects somewhere else, and have a routine that draws sprites based on the object's state.
mikaelmoizt
Posts: 120
Joined: Sat Apr 12, 2014 12:11 pm
Location: Gothenburg, Sweden

Re: Simple Mini-Game NESASM - ask for deep code analyze

Post by mikaelmoizt »

Bregalad wrote:Oh, I think the "do it everything in NMI" is a perfectly valid option, but it's not the easiest.
Yeah.. that pretty much sums up my experiences aswell.
Using NESASM is not a very good idea.

Agreed. Asm6 with a good editor really is a nice choice. No more .bank directives, everything falls into place really nicely and syntax is pretty much the same as in NESASM.
The only thing to add into your projects would be an ines header (and possibly some padding)

Like

Code: Select all

byte "NES",$1a            ; basically "NES" plus a terminator
byte $02                     ; 2x16 PRG-ROM block, full NROM 256
byte $01                     ; 1 CHR-ROM block
byte $00                     ; dontcare
byte $00                     ; dontcare
dsb 8                         ; 8 bytes padding

org $8000
I´ve got %01100011 problems but the BITs aint one.
sdm
Posts: 315
Joined: Tue Apr 11, 2006 4:08 am
Location: Poland

Re: Simple Mini-Game NESASM - ask for deep code analyze

Post by sdm »

Bregalad wrote:Using the sprites in shadow OAM as a game state is not a very good idea. It works if you are sure that 1) all your sprites are 8x8 and 2) you will never use sprite cycling.

In reality this is almost never the case, so it's better to store the state of your objects somewhere else, and have a routine that draws sprites based on the object's state.

"shadow OAM" = ram page 0200?

I read NNight some - if you mean something like this (updating sprites)? How best to do that?

Code: Select all

UpdateSprites:
  LDA bally  ;;update all ball sprite info
  STA $0200
  
  LDA #$30
  STA $0201
  
  LDA #$00
  STA $0202
  
  LDA ballx
  STA $0203
  
  ;;update paddle sprites
  RTS
In my program i compare SPR0 horizontal data with two another SPR1/2 ($0203,$0203 and $0207)as simple collision detection (It's badly done, but I got nothing else). How would you do it correctly?


Indicated greater number of errors is greatly appreciated. :) It will be very helpful for the future. (And if shown how to do it properly, it is even more welcome. :oops: )
User avatar
Bregalad
Posts: 8036
Joined: Fri Nov 12, 2004 2:49 pm
Location: Caen, France

Re: Simple Mini-Game NESASM - ask for deep code analyze

Post by Bregalad »

"shadow OAM" = ram page 0200?
Yes. We call it that way because it's a shadow of what is in the actual OAM in PPU.
if you mean something like this (updating sprites)?
Yes exactly
How best to do that?
Well there's a lot of approach. For example, by using $200,X adressing mode, before calling the sprite update routine it's possible to select which of the 64 sprites you're going to use. By selecting this in a different way each frame you get sprite cycling (you don't need it in your example, but should you risk to have more than 8 per line, then this would be needed).
In my program i compare SPR0 horizontal data with two another SPR1/2 ($0203,$0203 and $0207)as simple collision detection (It's badly done, but I got nothing else). How would you do it correctly?
What you are looking for is collision detection.

First don't use shadow OAM for collision detection, this is not good practice. Have dedicated variables for your objects that gets copied to shadow OAM every frame when they are displayed.

You are doing point-to-point collision detection, you should do rectangle-to-rectangle (but it's also possible to "fake" it using rectangle-to-point, but that might not be the best to do it when learning).

Google search for "collision detection" and you'll likely find dozen of tutorials with good graphics, that are better than anything I can write up for a quick post.
Post Reply