This page is a mirror of Tepples' nesdev forum mirror (URL TBD).
Last updated on Oct-18-2019 Download

How do you separate out your asm files?

How do you separate out your asm files?
by on (#125606)
I attempted to search this board for the answer before posting a new question, but couldn't find my answer... not sure if I just suck at searching or I'm searching the wrong term...

I'm just looking for a way to use a separate asm file in my project. I find myself copy/pasting some code that I use to read a controller all the time. Also, can this separate asm file have variables as well?
Re: How do you separate out your asm files?
by on (#125607)
NESASM, ASM6, or ca65? If ca65, my project template shows an example of how to make variables and subroutines from one translation unit (.s file) visible in another translation unit.
Re: How do you separate out your asm files?
by on (#125608)
Apologies, I didn't know there was a difference. I use NESASM3 (I found it online on some tutorial site). I thought at the end of the day though you still use the same asm files?
Re: How do you separate out your asm files?
by on (#125609)
Once you get enough different parts to your program and different controller actions based on the state/mode your program is in, you should start using jump tables for controller code rather than a long compare chain.

eg:
Code:
mode1: .dw Md1ContU, Md1ContD, Md1ContL, Md1ContR, Md1ContSel, Md1ContSta, Md1ContA, Md1ContB
mode2: .dw Md2ContU, Md2ContD, Md2ContL, Md2ContR, DoNothing, Md2ContSta, Md2ContA, Md2ContB
mode3: .dw DoNothing, DoNothing, DoNothing, DoNothing, Md3ContSel, Md3ContSta, Md3ContA, Md3ContB
...


You know, if mode1 is your main game, mode 2 a weapons menu, mode 3 the title screen, etc.

You'll have to figure out how to combine the mode & controller state into an offset that you can put into X, read the address into a variable, then do an indirect jump into that variable. But this does save code listing space.
Re: How do you separate out your asm files?
by on (#125610)
mpaul wrote:
Apologies, I didn't know there was a difference. I use NESASM3 (I found it online on some tutorial site). I thought at the end of the day though you still use the same asm files?
Since I work with NESASM, I understand what is done. If you want to put things in separate files, you will include all such files into one file by using the INCLUDE command. You can also use macros, if that helps.
Re: How do you separate out your asm files?
by on (#125611)
ccovell wrote:
Code:
mode1: .dw Md1ContU, Md1ContD, Md1ContL, Md1ContR, Md1ContSel, Md1ContSta, Md1ContA, Md1ContB
mode2: .dw Md2ContU, Md2ContD, Md2ContL, Md2ContR, DoNothing, Md2ContSta, Md2ContA, Md2ContB
mode3: .dw DoNothing, DoNothing, DoNothing, DoNothing, Md3ContSel, Md3ContSta, Md3ContA, Md3ContB
...

Really? I don't see this working very well for games. One reason being that games often need to detect 2 kinds of button presses: buttons that are currently pressed (used for walking, ducking, etc.) and buttons that have just been pressed (used for shooting, jumping, navigating menus and other things that should be triggered just once no matter how long the button is kept down). With the jump table method you'd have to tell them apart inside the routine itself (or create 8 more handlers per game mode), and you'd be constantly jumping to the shoot button handler just to verify that it was not pressed this frame and you shouldn't do anything.

Another problem is that depending on what's happening you have to prioritize the actions. For example, if you can't duck while jumping, the handlers would have to (again) explicitly check the current game state to decide whether the action assigned to that button should actually be taken. If you detected the jump beforehand, you could completely skip the ducking code. Checking a bunch of game state variables inside each handler seems counter-productive and wasteful IMO.

I prefer to handle my actions in the sequence that is most appropriate at the time (while a jump table would always result in the buttons being processed in the same order) so I can prioritize things and skip unnecessary steps. While coding the engine, I just think of things like "now would be the ideal time to start a jump, because I haven't moved the player horizontally yet", so that's when I'll check the jump button and initialize the jump if it's pressed. Then, when the time to move the player horizontally comes, I'll know that the movement is happening in the air and not on the ground. If the order in which the buttons are handled was hardcoded, you wouldn't be able to prioritize the actions like this, and would sometimes start actions you shouldn't. Each action has its ideal time to be performed because of how the state of your game world is progressively updated.