# Billy the Ball

## Recommended Posts

In case you haven't read the batari BASIC forums, I was working on this. Then a bug came up and I don't know how to get rid of it so I gave up on it. Then I realized I could attempt the same thing on the Intellivision. So that's what I've decided to do. Nothing much here, just Billy bouncing around. It took a few hours and lots of coding, but I think I did it. I think the biggest challenge here will be math. The game is like Qix in which you have to clear a certain percentage of the screen. Right now there are 180 squares to clear. You'd have to clear 135 squares (75% of the board) to clear a level. But how to put the number of squares into a percentage form is way beyond my math skills.

I figured I could do this on INTV because of the 8x8 blocks that make up the screen (as opposed to the 4x8 blocks of Atari 2600 that make up most of it.)

billyint1.zip

##### Share on other sites

I assume you mean converting "N / 180" into a percentage, so you can display it.

One fast way is just to have a lookup table with 180 entries.

If you really want to do math, just multiply by 5 (so the range goes 0 - 900) and divide by 9.

##### Share on other sites

How would a lookup table with 180 entries be faster than multiplying by 5 and dividing by 9?

##### Share on other sites

Look up table takes about 3-8 cycles to grab. Since multiply by 5 and dividing by 9 isn't power of 2s, it has to add the variable 5 times, and then subtract it 9 times to get the percentage, which takes a lot more CPU cycles. I'm not sure if it can do the math in 1 frame without interrupting or slowing down the game play, it's possible to process upon demand instead of being called every frame. Making and typing in a look up table would take time without tools to automate it.

##### Share on other sites

Apparently I was wrong about my game. There are only 162 squares to clear, not 180. After about 7 hours of work and I have the clearing lines thing down pat. Now I must sleep since it's almost 12:30am here.

billyint2.zip

##### Share on other sites

I changed the percentage to squares you must clear. Clear 125 squares to go back to the newly-made title screen. Or die to go back to it.

billyint3.zip

##### Share on other sites

Music! Sound effects! Life counter!

These are just some of the things I've put into the game since the 4:30pm build. I guess this is what happens when you have no life: You have tons of time to work on making video games if you're so inclined.

There is still stuff to do, like add different levels with different stuff in it. In the zip file are instructions on how to play the game in case you are wondering what the yellow bell I've added is.

billyint5.zip

##### Share on other sites

As a fan of Qix in the arcades, I like this game. Simple but fun. A couple of comments on the latest build.

When you die you immediately go back to the title screen, can there be a delay so you see what happened, or a message or something.

It just feels too fast.

Sometimes it's hard to know, if you are in the middle of a big part of the screen, when you fire, is it going to delete squares to the left or to the right,

or above or below your cursor, which makes a big difference to strategy.

Can the cursor be shaped different somehow so you can tell if you are pointing left vs right,

or up vs down.

##### Share on other sites

Look up table takes about 3-8 cycles to grab. Since multiply by 5 and dividing by 9 isn't power of 2s, it has to add the variable 5 times, and then subtract it 9 times to get the percentage, which takes a lot more CPU cycles. I'm not sure if it can do the math in 1 frame without interrupting or slowing down the game play, it's possible to process upon demand instead of being called every frame. Making and typing in a look up table would take time without tools to automate it.

It's closer to 16 cycles for a table lookup, if the index is already in a register.

Multiplying by 5 is around 20 cycles (again if the index is in a register). Dividing by 9 generates a loop in IntyBASIC, and that cost is proportional to the number being divided, so it can be rather expensive. Still, for the range 0 - 900, it would iterate no more than 100 times, so the cost would be around 1500 - 1600 cycles (about 1/9th of a frame time). There's more than enough time to do it.

I would personally use a lookup table here, especially since the number is now known to be 162 rather than 180. For anything but the shortest lookup tables, I nearly always write a script or program in some other language to generate the lookup table. You could use Perl, Python, shell-script, Lua, C, C++, or whatever other language you know that can compute the values and print them out.

Or, if you really want to stay in IntyBASIC, it can compute the values for you.

.

PctCvt:
DATA 0 * 50 / 81
DATA 1 * 50 / 81
DATA 2 * 50 / 81
' ... a bunch more lines
DATA 161 * 50 / 81
DATA 162 * 50 / 81

.

Or, if you don't mind a slight approximation, this should be pretty fast:

.

pct = (squares * 5) / 8

.

That actually computes the percent relative to 160 rather than 162. But, you'd probably never notice, since it's impossible to capture all 162 squares, correct?

##### Share on other sites

Changed it back to percentage wise, but when the board is half-cleared, it shows it as 45% cleared if I go the pct=(squarescleared * 5) / 8 route. I don't see how adding 162 lines of code the program needs to sift through as better than a single line, though (PctCvt in your example.)

I also changed the cursor to an arrow, as you can see here.

billyint6.zip

##### Share on other sites

Changed it back to squares cleared.

billyint7.zip

##### Share on other sites

Those would not be 162 lines of code, but 162 lines of data (or fewer lines if you put multiple values on each line). You would then use an index to pick the value to be printed from the data set. Yes, it would make your program a little bigger (about ~300 bytes, give or take) but you wouldn't need to do the math during execution. Table based lookups are very common shortcuts in retro programming, only in the case you are very tight on ROM/RAM space (depending on where your system stores your program) but have lots of CPU time to burn, running expensive algorithms to calcuate values may be preferred.

##### Share on other sites

How would I tell the program to go to the correct data line?

##### Share on other sites

Also, is there a way to show a score larger than 32,768?

edit: Never mind, I figured it out:

print at 222 color 1, <2>score8bit : print at 224 color 1, <4>#score
Edited by atari2600land

##### Share on other sites

So I put in a table like so:

pcttable:
DATA 0 * 50 / 81
DATA 1 * 50 / 81
...
DATA 128 * 50 / 81
DATA 129 * 50 / 81

And to call it, would I do this?

pct=pcttable(squarescleared)

See, I'm stuck at how to call it is what I need help with because I've never done table lookups before.

##### Share on other sites

Yes, that looks to be correct. Did it not compile or yield the expected results?

As for your other question, 16 bit variables are by default signed with a range of -32768 to +32767. By declaring them unsigned at the beginning of your program, they will instead hold values 0 - 65535. The method you used with an extra byte holding the upper part of the score is useful if you are expecting even larger scores, in the range of hundred of thousand points.

##### Share on other sites

It works fine. Though I am wondering why i should do that because no matter what I do, it still multiplies by 50 and then divides by 81.

billyint9a.zip

##### Share on other sites

Perhaps I'm misunderstanding your question (and I didn't download the latest version yet) but the DATA statements are precalculated at compile time, meaning all the multiplications and divisions are handled by the compiler on your PC and you get 162 values ranging from 0 to 100 which you use to index through to know which percentage to print on screen. That is different from if you would use the variable which means the compiler has to generate code for the Intellivision to do the calculation all the time, using CPU time.

##### Share on other sites

Added a bull after level 2.

billyint10.zip

Edited by atari2600land

##### Share on other sites

This is an interesting game. Kinda Qix but not.

Do you mind if I port this to the TI99? I have a vacation coming up and will have some time to do a little project.

##### Share on other sites

Just as long as you don't like, put it on a cartridge and sell it, or anything.

##### Share on other sites

I have never sold anything in the past... don't see that changing anytime soon.

If I get it going, I'll send you the link to it. You can play in web based emulators.

##### Share on other sites

Changed it back to percentage wise, but when the board is half-cleared, it shows it as 45% cleared if I go the pct=(squarescleared * 5) / 8 route.

What's "squarecleared" equal to when it prints 45%? 80 * 5 = 400, and 400 / 8 = 50. I don't see how the math is wrong.

I don't see how adding 162 lines of code the program needs to sift through as better than a single line, though (PctCvt in your example.

The 162 line lookup table is a static table. It has zero run time cost of its own. You index it as an array. You're not calling it. It isn't code, it's data.

So I put in a table like so:

pcttable:
DATA 0 * 50 / 81
DATA 1 * 50 / 81
...
DATA 128 * 50 / 81
DATA 129 * 50 / 81

And to call it, would I do this?

pct=pcttable(squarescleared)

See, I'm stuck at how to call it is what I need help with because I've never done table lookups before.

That's not actually a call, per se, but rather a lookup. And yes, that looks correct. That looks like it should work.

One word of caution: Don't put a lookup table in the middle of your code. For example, the following is a bad idea:

.

PRINT "Hello"
tbl: DATA 0, 1, 2, 3
PRINT "Goodbye"

.

IntyBASIC, for better or for worse, will put that data table directly between the two PRINT statements, and your program will crash. Put your lookup tables near where you put bitmaps and other data.

##### Share on other sites

As it turns out, I was doing something wrong when I was drawing the line, so it was my fault, not the math's.

## Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

Only 75 emoji are allowed.

×   Your previous content has been restored.   Clear editor

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