It is currently Tue Nov 20, 2018 5:36 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 20 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: Tue Oct 30, 2018 2:36 pm 
Offline
User avatar

Joined: Wed Sep 05, 2018 11:13 am
Posts: 146
Location: Colorado
Hi All,

I just put the first cut of Nesteroids on github.

I still need to do a lot of work on it... it's buggy and poorly commented, but if anyone is interested in looking at it that would be great. Will post more as I get further updates.

My goal is to make a video tutorial series on Youtube once it's in a state that is a little less embarrassing

Thanks for all your help everyone

_________________
A few of my web games
https://www.embed.com
Or if you're bored at work
https://www.classicsolitaire.com


Top
 Profile  
 
PostPosted: Tue Oct 30, 2018 3:35 pm 
Offline

Joined: Tue Aug 28, 2018 8:54 am
Posts: 71
Location: Edmonton, Canada
Maybe you shouldn't include cc65 binaries in the repository? it is usually "readme.md" with "Put cc65 here" text inside.

Edit

Game itself looks nice. Thank you for sharing the code. I'm sure someone will find it useful.


Top
 Profile  
 
PostPosted: Tue Oct 30, 2018 3:45 pm 
Offline
User avatar

Joined: Wed Sep 05, 2018 11:13 am
Posts: 146
Location: Colorado
yaros wrote:
Maybe you shouldn't include cc65 binaries in the repository? it is usually "readme.md" with "Put cc65 here" text inside.

Edit

Game itself looks nice. Thank you for sharing the code. I'm sure someone will find it useful.


Thanks. I do need to drop in a readme. This code is still really buggy and I have a lot to fix. I wasn't sure about including or not including the cc65 stuff. Since I want to do some tutorials, I was thinking it might be better to just drop it in. From what I recall it's not that large. It's also my first NES game, so I'm still getting my footing coding for it.

Any constructive criticism would be appreciated.

Thanks

_________________
A few of my web games
https://www.embed.com
Or if you're bored at work
https://www.classicsolitaire.com


Top
 Profile  
 
PostPosted: Tue Oct 30, 2018 5:55 pm 
Offline
User avatar

Joined: Tue Jun 24, 2008 8:38 pm
Posts: 2056
Location: Fukuoka, Japan
I'm browsing, very, very fast your code and is it me or you do not save/restore any registers in your NMI? This is good practice since it could cause "interesting" bug when you overwrite a/x/y that was in use just before NMI was called. You should push them and restore them, always ;)


Top
 Profile  
 
PostPosted: Tue Oct 30, 2018 6:16 pm 
Offline
User avatar

Joined: Wed Sep 05, 2018 11:13 am
Posts: 146
Location: Colorado
Banshaku wrote:
I'm browsing, very, very fast your code and is it me or you do not save/restore any registers in your NMI? This is good practice since it could cause "interesting" bug when you overwrite a/x/y that was in use just before NMI was called. You should push them and restore them, always ;)


So one thing I'm unclear on, is what happens when the NMI returns. Does it go back to where you were in the gameloop before?

Because I wasn't sure, what I did was set a flag nmi_ready or something like that, that only lets the nmi execute if the gameloop has finished. Then I have something similar in gameloop. The intent is basically so that we alternate between gameloop and nmi no matter what. I have no idea if this is good practice, it's just what I came up with.

Thanks

_________________
A few of my web games
https://www.embed.com
Or if you're bored at work
https://www.classicsolitaire.com


Top
 Profile  
 
PostPosted: Tue Oct 30, 2018 7:20 pm 
Offline

Joined: Wed Aug 16, 2017 12:15 am
Posts: 40
Location: Finland
My notes (I played on Nestopia):

Gameplay:
- I like how there can be up to five visible projectiles at the same time. That makes the game perhaps too easy, though.
- I'd like to be able to pause the game.
- The player's score doesn't always reset after game over. It happened once but I couldn't replicate the bug.
- Sometimes the UFO seems to spawn where the player or an asteroid is, killing both.
- When the level changes, flying projectiles don't disappear. Sometimes they instantly hit the new asteroids, which doesn't feel right.

Graphics:
- I like the explosions. However, the big asteroids look too much like cheese.
- The screen flashes green on startup and when pressing start after game over.
- When pressing start at the title screen, the text glitches for a short moment.
- When a sprite's left edge crosses the left edge of the screen, the sprite appears/disappears instantly, which looks glitchy, especially with big asteroids moving left. (Perhaps try clearing bit 2 of $2001 to clip the leftmost column of sprites?)

_________________
My NES utilities and programs on GitHub


Top
 Profile  
 
PostPosted: Tue Oct 30, 2018 7:33 pm 
Offline
User avatar

Joined: Tue Jun 24, 2008 8:38 pm
Posts: 2056
Location: Fukuoka, Japan
battagline wrote:
So one thing I'm unclear on, is what happens when the NMI returns. Does it go back to where you were in the gameloop before?


Not specifically. It will return where the PC (program counter, the address of the last executed instruction) was before the NMI was executed. Which means, even though you check the flag to see in you can execute NMI, checking the flag overwrite A, which mean when you do RTI and return to the location of the previous instruction, if that code was doing some manipulation on A, it will have the content of the NMI flag instead and "bad things will happens" ;) So any register you overwrite must be backed up and restored and the end if NMI/Interrupt. Usually you push them on the stack end restore them at the end.

battagline wrote:
Because I wasn't sure, what I did was set a flag nmi_ready or something like that, that only lets the nmi execute if the gameloop has finished. Then I have something similar in gameloop. The intent is basically so that we alternate between gameloop and nmi no matter what. I have no idea if this is good practice, it's just what I came up with.


there is many gameloop type, it depends what your game do. I prefer that the main gameloop process data/input, buffer it then in the NMI if any data is ready it will push it to OAM, PPU etc. I usually put famitone at the end of NMI too, that way if your main gameloop slow down, the music is not affected. Since you game seem to not do heavy processing (I checked really, really fast ^^;;) maybe this is not an issue in your case.

In brief, there is no "best" way, it depends on your need.


Top
 Profile  
 
PostPosted: Wed Oct 31, 2018 6:53 am 
Offline
User avatar

Joined: Wed Sep 05, 2018 11:13 am
Posts: 146
Location: Colorado
qalle wrote:
My notes (I played on Nestopia):

Gameplay:
- I like how there can be up to five visible projectiles at the same time. That makes the game perhaps too easy, though.
- I'd like to be able to pause the game.
- The player's score doesn't always reset after game over. It happened once but I couldn't replicate the bug.
- Sometimes the UFO seems to spawn where the player or an asteroid is, killing both.
- When the level changes, flying projectiles don't disappear. Sometimes they instantly hit the new asteroids, which doesn't feel right.

Graphics:
- I like the explosions. However, the big asteroids look too much like cheese.
- The screen flashes green on startup and when pressing start after game over.
- When pressing start at the title screen, the text glitches for a short moment.
- When a sprite's left edge crosses the left edge of the screen, the sprite appears/disappears instantly, which looks glitchy, especially with big asteroids moving left. (Perhaps try clearing bit 2 of $2001 to clip the leftmost column of sprites?)


Thanks for the feedback. I'm going to try and fix as many of the bugs as possible. I was going to animate the large asteroid, but the game took WAY longer than I thought so I may not get to that. Also, the palette on the asteroid isn't what I wanted it to be. Will try to fix as many bugs as possible over the next week, but basically I want to wrap this up a week from Friday to move on to other things, so I'll need to prioritize.

Thanks again for all the feedback and bug list :-)

_________________
A few of my web games
https://www.embed.com
Or if you're bored at work
https://www.classicsolitaire.com


Top
 Profile  
 
PostPosted: Wed Oct 31, 2018 7:00 am 
Offline
User avatar

Joined: Wed Sep 05, 2018 11:13 am
Posts: 146
Location: Colorado
Banshaku wrote:
Not specifically. It will return where the PC (program counter, the address of the last executed instruction) was before the NMI was executed. Which means, even though you check the flag to see in you can execute NMI, checking the flag overwrite A, which mean when you do RTI and return to the location of the previous instruction


Ahh, that makes sense. Out of curiosity, what would happen if I didn't rti, but instead did a jmp gameloop?

Thanks

_________________
A few of my web games
https://www.embed.com
Or if you're bored at work
https://www.classicsolitaire.com


Top
 Profile  
 
PostPosted: Wed Oct 31, 2018 7:22 am 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 20789
Location: NE Indiana, USA (NTSC)
I haven't read the code in detail to determine the function of the routine at gameloop. But an NMI handler ending with a JMP to the main thread would somehow need to 1. wrap up whatever the main thread was doing when it was interrupted, and 2. pull the three bytes representing the saved return address and flags from the stack.


Top
 Profile  
 
PostPosted: Wed Oct 31, 2018 7:47 am 
Offline
User avatar

Joined: Wed Sep 05, 2018 11:13 am
Posts: 146
Location: Colorado
tepples wrote:
I haven't read the code in detail to determine the function of the routine at gameloop. But an NMI handler ending with a JMP to the main thread would somehow need to 1. wrap up whatever the main thread was doing when it was interrupted, and 2. pull the three bytes representing the saved return address and flags from the stack.


So I've been thinking about what I have, and I do think it would work. Here's some pseudocode, let me know why it wouldn't work if it doesn't.

Code:
var nmi_can_run = 0
var game_loop_can_run = 0

proc reset
 game_loop_can_run = 1
 call game_loop
endproc

proc game_loop
 while game_loop_can_run == 0
    stay in this loop
 endwhile

 call proc_1
 call proc_2
 call proc_3
 call proc_4

 game_loop_can_run = 0
 nmi_can_run = 1

 return
endproc

proc nmi
 if nmi_can_run == 0
   return
 endif

call do_nmi_stuff_1
call do_nmi_stuff_2
call do_nmi_stuff_3

 nmi_can_run = 0
 game_loop_can_run = 1

endproc




So my thinking is it shouldn't matter if we jump into the nmi when we are between call proc_1 and call proc_2 because we would return immediately back between those two lines in the game loop because our nmi_can_run flag is still set to 0

Am I wrong on that?

Thanks

*edit* I do need to have a pha and a pla in my check of the nmi can run flag

_________________
A few of my web games
https://www.embed.com
Or if you're bored at work
https://www.classicsolitaire.com


Top
 Profile  
 
PostPosted: Wed Oct 31, 2018 8:20 am 
Offline

Joined: Tue Aug 28, 2018 8:54 am
Posts: 71
Location: Edmonton, Canada
battagline wrote:
So my thinking is it shouldn't matter if we jump into the nmi when we are between call proc_1 and call proc_2 because we would return immediately back between those two lines in the game loop because our nmi_can_run flag is still set to 0

Am I wrong on that?

Thanks


You have your gameloop
Code:
lda #0
sta $00


So you should expect 0 to be stored at $00.

No imagine if you have nmi

Code:
gameloop:                    nmi:
lda #0
; <-- NMI happens here       
                             lda #$FF ; now your A register contains #$FF
                             rti
; when you continue your
; code after NMI, #$FF
; is stored instead of #0
sta $00


Because NMI can interrupt your code anywhere, you should save all registers on the stack, so when you return from NMI everything is exactly as it should be. If your nmi occurs before BNE, BEQ instructions, your NMI could change the flags, so status register also should be saved. To be save, you should just salve all registers on the stack.

Code:
nmi:
php ; push flags
pha ; push all regisgters
txa
pha
tya
pha

; Your NMI code here

pla ; pull resiters
tay
pla
tax
pha
plp ; pul flags
rti


Top
 Profile  
 
PostPosted: Wed Oct 31, 2018 8:25 am 
Offline
User avatar

Joined: Thu Mar 31, 2016 11:15 am
Posts: 423
Yaros is correct, but you don't need to push the flags. They're pushed automatically when the interrupt is fired, and they're popped by RTI.

If you want mutexes/semaphores, you have to use atomic ops like INC and DEC. Most NMIs don't need these though.

Also, you shouldn't modify any variables in NMI that can also be modified outside of it.


Top
 Profile  
 
PostPosted: Wed Oct 31, 2018 8:27 am 
Offline

Joined: Tue Aug 28, 2018 8:54 am
Posts: 71
Location: Edmonton, Canada
pubby wrote:
Yaros is correct, but you don't need to push the flags. They're pushed automatically when the interrupt is fired, and they're popped by RTI.


Huh, thank you for the correction. I forgot about this.


Top
 Profile  
 
PostPosted: Wed Oct 31, 2018 8:30 am 
Offline
User avatar

Joined: Wed Sep 05, 2018 11:13 am
Posts: 146
Location: Colorado
pubby wrote:
Yaros is correct, but you don't need to push the flags. They're pushed automatically when the interrupt is fired, and they're popped by RTI.


Ok, I didn't realize that. So there's no need to do a pha at the beginning of the NMI then a pla before the rti?

Thanks

_________________
A few of my web games
https://www.embed.com
Or if you're bored at work
https://www.classicsolitaire.com


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 20 posts ]  Go to page 1, 2  Next

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 1 guest


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