Game project help and progress thread
Moderator: Moderators
Game project help and progress thread
In this thread I'll be sharing progress and asking help if there is something I can't figure out.
Right now I have few questions:
1. What would be the best way to do a fade in/out with a single routine?
2. What would be a good way to make main loop recognize the game's state (title, paused, main game, cutscene etc.)? Should I put a short code at the beginning of the main loop that checks a variable for game state and then jumps to that part of the main loop?
3. How do I make indirect jump with NESASM3? Most places seem to use JMP (address), but it doesn't seem to work. NESASM seems to convert it to a absolute jump.
Right now I have few questions:
1. What would be the best way to do a fade in/out with a single routine?
2. What would be a good way to make main loop recognize the game's state (title, paused, main game, cutscene etc.)? Should I put a short code at the beginning of the main loop that checks a variable for game state and then jumps to that part of the main loop?
3. How do I make indirect jump with NESASM3? Most places seem to use JMP (address), but it doesn't seem to work. NESASM seems to convert it to a absolute jump.
UP SIDE DOWN A B A B B A B A Hidari migi
L R L R STOP & DASH & UP & TALK Ijou nashi
L R L R STOP & DASH & UP & TALK Ijou nashi
Re: Game project help and progress thread
1. What do you mean by "single routine"?
You'll have to compute the faded palette and then write it to the PPU during vblank. Which step are you looking for?
3. NESASM requires the nonstandard JMP [address] for indirection.
You'll have to compute the faded palette and then write it to the PPU during vblank. Which step are you looking for?
3. NESASM requires the nonstandard JMP [address] for indirection.
Re: Game project help and progress thread
1. Basically you need to keep a buffer with the internal state of the palette, and darkens the values that sits here before writing them to the hardware palette. Fading out means substracting $10 from all entries, and using $0f whenever an entry becomes negative. Fading in is more complicated and there is several approaches you could use (personally I don't fade the palette in )
2. Normally the PC (program counter) holds the game's state. Only if you are going in a "everything in NMI" type of code architecture will you have to do something like what you described, whenever you want to do that is up to you.
2. Normally the PC (program counter) holds the game's state. Only if you are going in a "everything in NMI" type of code architecture will you have to do something like what you described, whenever you want to do that is up to you.
Re: Game project help and progress thread
The only reason I want the fade is because in title screen when you press start, the screen will start wobbling a little and fades out before the game starts. I don't have other plans for fading yet, but If I can make it work as a routine that checks variables for what it should do etc., I could use it elsewhere too.Bregalad wrote:1. Basically you need to keep a buffer with the internal state of the palette, and darkens the values that sits here before writing them to the hardware palette. Fading out means substracting $10 from all entries, and using $0f whenever an entry becomes negative. Fading in is more complicated and there is several approaches you could use (personally I don't fade the palette in )
How does the program counter do that? I haven't heard of it begin able to do that.Bregalad wrote:2. Normally the PC (program counter) holds the game's state. Only if you are going in a "everything in NMI" type of code architecture will you have to do something like what you described, whenever you want to do that is up to you.
UP SIDE DOWN A B A B B A B A Hidari migi
L R L R STOP & DASH & UP & TALK Ijou nashi
L R L R STOP & DASH & UP & TALK Ijou nashi
Re: Game project help and progress thread
Mmh, a good idea would be to keep a "darkness" level, where 0 = normal, 1 = a little dark, 2 = medium dark, 3 = completely dark, 4 = black.
Then, you substract (darkness << 4) from each palette and use $0f whenever the result is negative as you update the palette, without writing the result back in the palette buffer. That would allow both fade in, out, and darkness changes anytime during gameplay. The main problem is that it would not allow to have lightness greater than normal, but that is not what you asked for.
For the program counter it's completely transparent. You just have different parts of your game coded as different routines (or different parts of the main routine), and the PC keeps tracks of this, because that's how the 6502 works. It couldn't get simpler really.
Then, you substract (darkness << 4) from each palette and use $0f whenever the result is negative as you update the palette, without writing the result back in the palette buffer. That would allow both fade in, out, and darkness changes anytime during gameplay. The main problem is that it would not allow to have lightness greater than normal, but that is not what you asked for.
For the program counter it's completely transparent. You just have different parts of your game coded as different routines (or different parts of the main routine), and the PC keeps tracks of this, because that's how the 6502 works. It couldn't get simpler really.
Re: Game project help and progress thread
So, do you mean that I need to have something like this:Bregalad wrote: For the program counter it's completely transparent. You just have different parts of your game coded as different routines (or different parts of the main routine), and the PC keeps tracks of this, because that's how the 6502 works. It couldn't get simpler really.
Code: Select all
MainLoopTitle:
; Code
SleepTitle:
; Check for "sleep" variable
JMP MainLoopTitle
MainLoopGame:
; Code
SleepGame:
; Check for "sleep" variable
JMP MainLoopGame
MainLoopPaused:
; Code
SleepPaused:
; Check for "sleep" variable
JMP MainLoopPaused
MainLoopScene:
; Code
SleepScene:
; Check for "sleep" variable
JMP MainLoopScene
; And so on...
UP SIDE DOWN A B A B B A B A Hidari migi
L R L R STOP & DASH & UP & TALK Ijou nashi
L R L R STOP & DASH & UP & TALK Ijou nashi
Re: Game project help and progress thread
No. I don't even know what is your sleep variable. Why would you want multiple main loops ? Just one is enough. However if you do it differently than me, if it works and if it makes more sense for you by all means go for it.
Re: Game project help and progress thread
I like to keep a copy of the unmodified palette in RAM, and have a routine generate a darkened copy of it based on a global brightness level. Pretty much what Bregalad said, except I'm not a big fan of the 4-step fade because it looks very jerky unless you animate it really fast, which kinda defeats the purpose of having a fading routine, which is to make transitions smoother. I prefer to simulate more brightness levels in some way, like darkening the colors one frame, moving them towards blue the other frame, or darkening colors of different brightness at different times ($0x colors become black, then $1x colors become $0x, and so on, until they're all black). You can use whatever darkening method you like in the fading function.Tsutarja wrote:1. What would be the best way to do a fade in/out with a single routine?
I vote for different loops for different states. In fact, all the different states in my programs have an entry point, where any necessary initialization takes place, followed by the loop itself. This way I can switch to another game mode simply by JMPing to its entry point.2. What would be a good way to make main loop recognize the game's state (title, paused, main game, cutscene etc.)? Should I put a short code at the beginning of the main loop that checks a variable for game state and then jumps to that part of the main loop?
Code: Select all
InitializeTitleScreen:
;initialize variables, draw the name table, etc.
UpdateTitleScreen:
;read controllers, move the cursor, etc.
jmp UpdateTitleScreen
InitializeGameplay:
;initialize variables, decode a level, set up the pattern tables, etc.
UpdateGameplay:
;read the controllers, process game objects, etc.
jmp UpdateGameplay
In my projects I even allow custom NMI routines for the different states. My NMI checks the high byte of a pointer in RAM, and if that byte isn't 0, it jumps to that address. If the byte is 0, it just sets a flag indicating that VBlank has started, so that simpler game states can use the good old "wait for VBlank" structure.
Re: Game project help and progress thread
I also have no idea what the sleep variable is, but multiple main loops help keep the program organized and the different parts independent from each other. Personally I'd prefer that over spaghetti code with multiple game states mixed together any day. If separate game states happen to share a lot of code, you can consider merging them or turning the shared code into subroutines.Bregalad wrote:No. I don't even know what is your sleep variable. Why would you want multiple main loops ?
Re: Game project help and progress thread
Oh, the method tokumaru posted looks quite organized and powerful. Personally I just don't work with "states" at all. To pause the game, well I just read the controller until start is pressed again and then return. Same for the title screen, I have a loop and when start is pressed, it continues down into the main program. It is just logical for me. However, it might not be as organized.
I think what I describe above could be considered multiple game loops. However, all of them are implicit, they are just natural, because I don't leave a routine (or part of a routine) until some event happen that makes me leave it with the rts instruction.
I think what I describe above could be considered multiple game loops. However, all of them are implicit, they are just natural, because I don't leave a routine (or part of a routine) until some event happen that makes me leave it with the rts instruction.
Re: Game project help and progress thread
I don't think this is bad as long as the states aren't very complex. A pause screen that does nothing but wait for the game to be unpaused certainly doesn't deserve its own state. The same goes for a title screen that only waits for start. But once you have states that allow navigation and so on, I think it becomes important to separate things, otherwise the code might become hell to maintain.Bregalad wrote:Personally I just don't work with "states" at all. To pause the game, well I just read the controller until start is pressed again and then return. Same for the title screen, I have a loop and when start is pressed, it continues down into the main program. It is just logical for me.
Yeah, I guess it's not that different.I think what I describe above could be considered multiple game loops. However, all of them are implicit, they are just natural, because I don't leave a routine (or part of a routine) until some event happen that makes me leave it with the rts instruction.
Re: Game project help and progress thread
The sleep variable is what prevents main loop from running more than once per frame. I have seen a lot of people use this name for it.
UP SIDE DOWN A B A B B A B A Hidari migi
L R L R STOP & DASH & UP & TALK Ijou nashi
L R L R STOP & DASH & UP & TALK Ijou nashi
Re: Game project help and progress thread
In other words, it's a wait for VBlank.Tsutarja wrote:The sleep variable is what prevents main loop from running more than once per frame.
Re: Game project help and progress thread
When using NESASM, remember these feature of its syntax:
- For zero page addressing, put < before the address or label (for example LDA <var0 if your variable in the zero page is called var0).
- For indirection in all cases, you must use square brackets rather than parentheses.
(Free Hero Mesh - FOSS puzzle game engine)
Re: Game project help and progress thread
Is there a syntax guide for NESASM somewhere? I haven't been able to find one. I feel like there might be some functions in NESASM that I don't know about.zzo38 wrote:When using NESASM, remember these feature of its syntax:Some people (including myself) prefer this nonstandard syntax, although still remember it is nonstandard and many documents don't use it.
- For zero page addressing, put < before the address or label (for example LDA <var0 if your variable in the zero page is called var0).
- For indirection in all cases, you must use square brackets rather than parentheses.
UP SIDE DOWN A B A B B A B A Hidari migi
L R L R STOP & DASH & UP & TALK Ijou nashi
L R L R STOP & DASH & UP & TALK Ijou nashi