Jump to content
IGNORED

Finding more variables


jrok

Recommended Posts

I've noticed that a pretty common complaint during the batariBasic development process seems to be "I'd like to expand gameplay here, but I've run out of variables." Often times that simply isn't the case, and even though you've used a-z, you still have ample reservoirs of RAM that are lying around doing nothing in your program. I thought it would be neat to have a thread devoted to ideas about how to expand the number of variables at your disposal.

 

One thing I've noticed is that the memory map ("2600basic.h" for the standard kernel, "multisprite.h" for multisprite) reserves many addresses for values that you won't necessarily need to change after they've been defined once. If you have instances of these in your own games, you might want to consider making them constants by pointing them to numbers and using their RAM addresses for new variables. For "Charge", I've been having to go to this well fairly often.

 

For instance, many of the "variables" in my score area will actually remain constant thoughout the program. I am using the "pfscore" option in my game to include a health bar and three pixels representing "lives." In includes/multisprite.h, you can see the following addresses reserved for aspects of the score area:

 

statusbarlength = $BF
aux3 = $BF

lifecolor = $C0
pfscorecolor = $C0
aux4 = $C0

 

In my case, I don't need to have my lives or health bar change color, and I am not planning on including a minikernel that would require "statusbarlength." So I can free up $BF and $C0 to use as two extra variables in my game:

 

myextravar1 = $BF
aux3 = $BF

pfscorecolor = #44
myextravar2 = $C0
aux4 = $C0

 

In the above example, the pfscore lives and status bar will always be assigned TIA color 44 (Hex: $2C). Meanwhile, I can have two more free variables ("myextravar1" and "myextravar2") to use for other purposes.

 

When looking at the design of your game as a whole, you'll probably find several instances in your program where a variable reserved in the standard memory map could actually be eliminated, replaced with a constant or co-assigned to the same address. For instance, if you are using the mutlisprite kernel and have several virtual sprites that will always share the same color, you can free up as many as four variables:

 

NewCOLUP1 = $98
_COLUP1 = $98
COLUP2 = $99
COLUP3 = $9A
COLUP4 = $9B
COLUP5 = $9C

 

NewCOLUP1 = $98
_COLUP1 = $98
COLUP2 = $98
COLUP3 = $98
COLUP4 = $98
COLUP5 = $98

somevar1 = $99
somevar2 = $9A
somevar3 = $9B
somevar4 = $9C

 

If anyone else has ideas or tricks for saving, recovering or re-using variables, it would be great to hear about them.

 

Cheers,

Jarod

Edited by jrok
  • Like 1
Link to comment
Share on other sites

I have noticed that many programmers mirror certain system variables with user variables. For example, bB "remembers" player0x after a call to drawscreen, so you do not need to use a user variable, such as x, to hold this value and copy it to player0x every frame. Some system variables/registers do go away after a drawscreen, however, so I tried to address this with the section on "ephemeral registers" in the command reference to help programmers know what variables do and do not need mirroring.

 

I have also noticed that few make judicious use of temp variables, instead wasting user variables for calculations that do not need to be remembered very long. This is understandable as some routines do use some of the temp variables and this may not be well-documented, but in nearly all cases they hold their values for several lines or possibly the entire frame, and you may use them for interim calculations or comparisons without consequence and free up user variables.

Link to comment
Share on other sites

I have also noticed that few make judicious use of temp variables, instead wasting user variables for calculations that do not need to be remembered very long. This is understandable as some routines do use some of the temp variables and this may not be well-documented, but in nearly all cases they hold their values for several lines or possibly the entire frame, and you may use them for interim calculations or comparisons without consequence and free up user variables.

 

That is a great point. I find myself using the temp variables over and over for certain ephemeral tests, like the bounding boxes for virtual sprites. Also, the temp variables seem great for data pointers, especially if I'm accessing a data set to "spawn" a new enemy or set up a new level. In "Charge", I'm using a pair of temp variables to set up a new enemy every time one is destroyed. In sequence, temp5 and temp6 write the enemy's movement speed, color and hitpoints, number/size, and firing frequency. After the spawn completes, I go back to using temp5 and temp6 to define the bounding boxes of the enemy sprite and its weapon.

 

  data waves
 1,64,$005,220,
 1,64,$005,200,
 1,64,$005,180,
 2,162,$005,160,
 2,162,$005,120,
 2,162,$005,120,
 3,178,$007,100
end


SetUpEnemy

 temp5 = wave * 4

 e1speed =  waves[temp5]

 temp6 = temp5 + 1
 COLUP4 = waves[temp6]
 if waves[temp6] = 64 then e1HP1=0 : e1HP2=0
 if waves[temp6] = 162 then e1HP1=1 : e1HP2=0
 if waves[temp6] = 178 then e1HP1=1 : e1HP2=1

 temp6 = temp5 + 2
 NUSIZ4 = waves[temp6]

 temp6 = temp5 + 3
 e1var = waves[temp6]

 return

Link to comment
Share on other sites

If batari can figure out how to make bB use 4-bit variables in a simple, easy-to-understand, easy-to-use way then we'd have even more variables:

 

http://www.atariage.com/forums/index.php?showtopic=133045

 

http://www.randomterrain.com/atari-2600-me...ml#nybblemethis

Link to comment
Share on other sites

I used to use player0x as a variable until I realized I don't need to awhile ago.

 

I guess what I was saying above is that something like player0x already is a variable. But not all games would require a variable to track the x position of Player0. A good example might be something like Demon Attack. In that game, the player sprite only moves left and right, so its Y value never changes. In that case, you could define player0y as an integer in the memory map (i.e. player0y = #16) and free up its address to track something else (the attack strength of an enemy, the frame of an animation, a sound pointer... etc). For instance, in "Charge" I defined the Y values of all the Defender radar objects as constants and used those addresses to track the health of the castles. Hope that makes sense.

Link to comment
Share on other sites

  • 2 weeks later...
...For instance, if you are using the mutlisprite kernel and have several virtual sprites that will always share the same color, you can free up as many as four variables:

 

NewCOLUP1 = $98
_COLUP1 = $98
COLUP2 = $99
COLUP3 = $9A
COLUP4 = $9B
COLUP5 = $9C

 

NewCOLUP1 = $98
_COLUP1 = $98
COLUP2 = $98
COLUP3 = $98
COLUP4 = $98
COLUP5 = $98

somevar1 = $99
somevar2 = $9A
somevar3 = $9B
somevar4 = $9C

 

Okay, I realize now that the above wouldn't do what I thought it would. I assumed (wrongly) that if I assigned two virtual sprite registers to the same address and set one register in my code, both registers would be set to the same value simultaneously. Wrong!

 

Is that because the virtual registers have to be set before each drawscreen? Suppose I want to use COLUP4 and NUSIZ4 to set the number/size and color of both virtual player 5 and virtual player 4? Could I do this in the variable redefs? Also, could someone could help explain what's actually happening when you define two virtual sprite registers at the same address? I think I'm reaching a wrongheaded conclusion about the virtual registers really work.

 

Thanks in advance,

Jarod.

Link to comment
Share on other sites

...For instance, if you are using the mutlisprite kernel and have several virtual sprites that will always share the same color, you can free up as many as four variables:

 

NewCOLUP1 = $98
_COLUP1 = $98
COLUP2 = $99
COLUP3 = $9A
COLUP4 = $9B
COLUP5 = $9C

 

NewCOLUP1 = $98
_COLUP1 = $98
COLUP2 = $98
COLUP3 = $98
COLUP4 = $98
COLUP5 = $98

somevar1 = $99
somevar2 = $9A
somevar3 = $9B
somevar4 = $9C

 

Okay, I realize now that the above wouldn't do what I thought it would. I assumed (wrongly) that if I assigned two virtual sprite registers to the same address and set one register in my code, both registers would be set to the same value simultaneously. Wrong!

 

Is that because the virtual registers have to be set before each drawscreen? Suppose I want to use COLUP4 and NUSIZ4 to set the number/size and color of both virtual player 5 and virtual player 4? Could I do this in the variable redefs? Also, could someone could help explain what's actually happening when you define two virtual sprite registers at the same address? I think I'm reaching a wrongheaded conclusion about the virtual registers really work.

 

Thanks in advance,

Jarod.

I believe the kernel does a read of NewCOLUP1,x to set the sprite color. The labels COLUP2-COLUP5 are just there for user convenience, and changing them will not work.

 

If you want to free up those variables, modify the kernel, and change NewCOLUP1,x to NewCOLUP1.w or something to maintain the cycle count, which should actually free up those variables.

Link to comment
Share on other sites

...For instance, if you are using the mutlisprite kernel and have several virtual sprites that will always share the same color, you can free up as many as four variables:

 

NewCOLUP1 = $98
_COLUP1 = $98
COLUP2 = $99
COLUP3 = $9A
COLUP4 = $9B
COLUP5 = $9C

 

NewCOLUP1 = $98
_COLUP1 = $98
COLUP2 = $98
COLUP3 = $98
COLUP4 = $98
COLUP5 = $98

somevar1 = $99
somevar2 = $9A
somevar3 = $9B
somevar4 = $9C

 

Okay, I realize now that the above wouldn't do what I thought it would. I assumed (wrongly) that if I assigned two virtual sprite registers to the same address and set one register in my code, both registers would be set to the same value simultaneously. Wrong!

 

Is that because the virtual registers have to be set before each drawscreen? Suppose I want to use COLUP4 and NUSIZ4 to set the number/size and color of both virtual player 5 and virtual player 4? Could I do this in the variable redefs? Also, could someone could help explain what's actually happening when you define two virtual sprite registers at the same address? I think I'm reaching a wrongheaded conclusion about the virtual registers really work.

 

Thanks in advance,

Jarod.

I believe the kernel does a read of NewCOLUP1,x to set the sprite color. The labels COLUP2-COLUP5 are just there for user convenience, and changing them will not work.

 

If you want to free up those variables, modify the kernel, and change NewCOLUP1,x to NewCOLUP1.w or something to maintain the cycle count, which should actually free up those variables.

 

Thanks, batari. I tried what you suggested, but I just get a jam instruction when I run the binary. I'm not really sure I'm explaining very well what I'd like to do. I have two virtual sprites that will always write the same sprite registers for color and number/size before every drawscreen, while the other three sprites will have unique registers. I was just wondering if there's a way to set virtual sprite registers for two different identical virtual sprites using the same RAM. In other words, if I have two sprites representing enemies who will always be identical to each other in color and number/size, do I really have to reserve RAM for each of them, or can they share?

 

Thanks,

Jarod

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...