Jump to content
IGNORED

Changing score_graphics.asm file


atari2600land

Recommended Posts

I'm ready to take the big step into changing the score_graphics.asm file. So I have a couple of questions:

#1: How do you get rid of some numbers in the score?

and

#2: How do you get the modified numbers in the program?

 

As for getting rid of numbers in the score, I need to do that for a game I'm working on. Since there's no room for a life meter, I decided to put the number of lives as the first digit in the score, so instead of making the score 300000, I'd like to make it 3__000.

 

I think I can figure out how to change the way the numbers look, but I don't know how to put the changed numbers into the game. I've modified score_graphics.asm and saved it as score_graphics2.asm. Would you need that file in order for the score to look right when emulating (or burning onto a chip), or would it just look like the normal numbers?

Edited by atari2600land
Link to comment
Share on other sites

I'm ready to take the big step into changing the score_graphics.asm file. So I have a couple of questions:

#1: How do you get rid of some numbers in the score?

and

#2: How do you get the modified numbers in the program?

 

As for getting rid of numbers in the score, I need to do that for a game I'm working on. Since there's no room for a life meter, I decided to put the number of lives as the first digit in the score, so instead of making the score 300000, I'd like to make it 3__000.

 

I think I can figure out how to change the way the numbers look, but I don't know how to put the changed numbers into the game. I've modified score_graphics.asm and saved it as score_graphics2.asm. Would you need that file in order for the score to look right when emulating (or burning onto a chip), or would it just look like the normal numbers?

I think most of this may have been covered in the thread about adding a timer, where I showed you how to add a colon and then display it. In this case (if I understand what you're trying to do), you would add a blank instead of a colon, and always display the blank in place of the second and third digits from the left. I can't help any further until I get home, as I'm heading off to work.

 

MR

Link to comment
Share on other sites

I went back and re-read the timer thread and figured out that SeaGtGruff was using hexadecimal numbers in the sample code, which I have no idea what those are. All I understand are normal and binary. I think the easiest way to answer #1 is to make an eleventh number of a blank space and then insert that in there. I still don't get how to put the modified set into the program itself. It seems like you should tell the .bas file to use score_graphics2.asm (what I re-named the new score_graphics.asm file). I don't understand what $F0 means, but I know $0A is eleven. I'm referring to post #4 in the "making a timer" thread where he explains how to put the new character I created into the program, but I think the roadblocks for me are I don't understand how the program knows to use a different asm file for my program instead of the default, and not knowing hexadecimal numbers. So now what I need to do is insert the blank space twice (for digits two and three) in there. And it looks like I can't use a file called default2.inc, so wouldn't that mess up all the other programs I've saved in the same file folder? So, basically, what I'm asking is how to insert two eleventh digits into a score which I made in a score_graphics2.asm file (which are blanks), and a code explaining how to do so (without hexadecimal numbers, if possible, and if it's impossible, at least convert them back to normal numbers outside the code sample to tell me what they are in normal terms, because I am a layman when it comes to stuff like this.)

Link to comment
Share on other sites

I went back and re-read the timer thread and figured out that SeaGtGruff was using hexadecimal numbers in the sample code, which I have no idea what those are.

Quicky explanation:

 

Hexidecimal is a sixteen digit counting system. Whereas the digits in base-10 (aka decimal, what we're all used to counting in) are 0-9, the digits in base-16 (aka Hexidecimal) are 0-F. The list of digits along with their base-10 values are listed below:

 

0 (0)
1 (1)
2 (2)
3 (3)
4 (4)
5 (5)
6 (6)
7 (7)
8 (8)
9 (9)
A (10)
B (11)
C (12)
D (13)
E (14)
F (15)

 

Just like in base-10 counting, the numbers roll over into the next digit. So F + 1 = 10 in hex. Since that gets a bit confusing (since 10 hex == 16 decimal), we usually prefix hex numbers with either a '$' or '0x'. Both these prefixes mean the same thing: That the value is a hex number. Therefore, we would say that $F + $1 = $10 to prevent confusion.

 

So, now that we understand what Hex is the question is, how is it useful to us? The answer is in binary. What is the largest number that can be represented in 4 bits? (i.e. 1111) The mathematical answer is 2^4 (2 to the power of 4) which equals 16. (2 * 2 * 2 * 2 = 16) However, the number zero takes one of those slots (i.e. 0000), so the largest number is actually 15.

 

Question: What is the largest single digit in hexidecimal?

Answer: Why, 15!

 

As it so happens, $F is equal to 1111! Does this hold true for all the digits? Well, let's see:

 

0 (0000)
1 (0001)
2 (0010)
3 (0011)
4 (0100)
5 (0101)
6 (0110)
7 (0111)
8 (1000)
9 (1001)
A (1010)
B (1011)
C (1100)
D (1101)
E (1110)
F (1111)

As it so happens, yes it does! So we now know that hexidecimal maps directly to four bits of binary! Thus we can represent any 8 bit value with two hex numbers!

 

To pull a value out of the air:

 

1011 0011

 

can be represented as:

 

$B3

 

Understand?

 

Now, Binary Coded Decimal packs each number within four bits. Four bits are required because 3 bits only holds 0-7 (2^3). With four bits we end up with 6 wasted digits, but the decimal numbers fit. So we'd encode 1234 as:

 

0001 0010 0011 00100

 

(Note that I always put spaces between each four digits. This is by convention to make it easier for coders to switch between decimal and hexidecimal.)

 

To get back to the bBASIC issue, each of those numbers has a corresponding sprite in a list. The first sprite is a zero, the second sprite is a one, the third sprite is a two, the fourth sprite is a three, etc, etc, etc. Thus each number that's BCD encoded is simply used to look up its sprite. But since we have extra digits, what happens if someone encodes $A in BCD? There's no corresponding sprite! As a result, bBASIC has code to trap the overflow, and increment the next digit. Thus adding 1 to a score of 9 will still give you 10 rather than $A.

 

As it so happens, we can encode the $A manually, and then add an extra sprite to the list of sprites. That extra sprite could represent whatever we wanted it to represent, be it a colon, a space, an underline, or some flying space-pig. Whatever it may be, it would show up in the score at the bottom.

 

If you understand this, go back and read the timer thread. It should make a lot more sense now.

Link to comment
Share on other sites

OK, now, does that mean that $B3 is 113, seeing as how B is 1011 and 3 is 0011 and those are two digits, or do you add the two together to get 13 or what? (I always sucked at math.)

also:

what does the $F0 represent in this following code from the Timer thread? (not in base-10, but in bBasic language)

 

200 score=0
dim colon = score+1
202 t=t+1 : COLUP0=196
colon = colon && $F0
if t=60 then score=score+1 : t=0
if $60=score[2] then score=score+940
colon = colon || $0A
216 drawscreen
218 if joy0down then goto 220
219 goto 202

 

and also, why is colon score+1? If the score was 2 (i.e. two seconds), why would colon be 3? Here's some code from the secret game I'm working on. (ooh, secret. :D)

 

215 dim blank=score
220 blank=blank && $F0
 if collision(player0,ball) then score=score+1 : n=1 
 blank=blank || $0A
 if n>0 then goto 196

 

What this does is gets rid of the second digit of the score and replaces it with the blank I made in the modified score_graphics.asm file.

So what, in this example, is digit 1 in the score (line 215)? score-1 or what?

Link to comment
Share on other sites

OK, now, does that mean that $B3 is 113, seeing as how B is 1011 and 3 is 0011 and those are two digits, or do you add the two together to get 13 or what? (I always sucked at math.)

Numerically (i.e. converting an 8 bit number to decimal), it's... (whips out Windows Calculator) 179. Encoded as BCD, it's garbage. BCD is binary coded decimal. Which means you're not supposed to have ANY number over 9 in a given nibble*. By manually setting a value to be garbage, you're "hacking" the score counter for your own nefarious purposes. Like all hacks, it can and will bite you in the rear if you don't keep it in mind. Do not do any arithmetic on a hacked score. Doing so could screw your program up royally.

 

what does the $F0 represent in this following code from the Timer thread? (not in base-10, but in bBasic language)

Again, the sprites for each number are in numerical order. $F0 is garbage unless you hack in a sprite for $F. Remeber that in BCD, each digit is encoded in 4 bits. Which means that you can treat each hex digit as a separate number.

 

and also, why is colon score+1?

That's part of the hack. You're not telling bBASIC to add one to the score. You're actually setting the memory address of "colon" to be the memory address of "score" plus one. The score is stored in 3 bytes of memory, thus the need to address a byte beyond what the score is. If you simply reference the "score" variable, bBASIC will do some special logic to intercept the call and work everything into BCD encoding.

 

Here's some code from the secret game I'm working on. (ooh, secret. :D)

 

215 dim blank=score
220 blank=blank && $F0
 if collision(player0,ball) then score=score+1 : n=1 
 blank=blank || $0A
 if n>0 then goto 196

Hmmm... looks like you're messing with the Pong code from AtariOS? ;)

 

What this does is gets rid of the second digit of the score and replaces it with the blank I made in the modified score_graphics.asm file.

So what, in this example, is digit 1 in the score (line 215)? score-1 or what?

I honestly don't know what the score would end up being. You're screwing with things after you've hacked the score. You should first set the score to values you've saved, THEN apply the hack. That will ensure that you always know what each number is. Both AtariOS Pong and Deimos Lander have examples of this technique.

 

* A nibble is four bits.

Link to comment
Share on other sites

Actually, I took the example code from SeaGtGruff's post (#4) from the timer thread and put it in my game I'm working on. I have no idea what the coding for Atari OS & Deimos Lander is. So why would he put in a number that doesn't mean anything ($F0)? If you add a digit into the score, would that mean nothing above $0A means anything in terms of blank equaling anything?

---

edit: To answer my own question: $F0 does mean something but I don't know what, because when I change it in the code above, the score changes. I did set the score to 300000 in line 183, 3 being #of lives left, the second digit being a blank, and the other 4 digits being the score. And even though I set the score to 300000, if I change $F0 in the above code, the first digit changes, even though I set it to be 3 in line 186.

Edited by atari2600land
Link to comment
Share on other sites

So why would he put in a number that doesn't mean anything ($F0)?

As I said, that's the hack. bBASIC has a lookup table of sprites for each number in the BCD encoding. (0-9) If you add more sprites, you can use the 6 digits beyond 9. They just don't mean anything in BCD, and WILL screw stuff up if you try to do calculations with them.

Link to comment
Share on other sites

So how is it possible to do calculations (like increase the score once something happens) with a hacked score? I mean, I can see the problem in my above code since the fifth digit is set to be A (or 10), but that's the fifth digit, so why would it screw anything up in the first 4 digits when they're all set to be from 0-9 with no weird hexadecimal numbers? See, the problem I'm having with this game is most of the time, whenever player0 touches the ball, the score increases by 1, but sometimes it increases by 2 or, on even rarer occasions, 3. Is it because I'm hacking the score_graphics.asm file or is it because I'm setting the ball using random numbers and it's a coincidence because those random numbers happen to be next to each other (like in Ants sometimes).

Link to comment
Share on other sites

Problem not solved after all. Once the score gets past 100, it does its stupid add 2 instead of 1 like I told it to thing again. What are the numbers for each 6 digits in the score? Maybe I can control it that way. Can someone explain the score[1], score[2], score[3] thing? is score[3] the first 2 digits, score[2] the middle 2 digits, and score[1] the end 2 digits or does it go up to score[6]? If I were to do SpiceWare's solution, I need to know what digit to change and how.

Edited by atari2600land
Link to comment
Share on other sites

Problem not solved after all. Once the score gets past 100, it does its stupid add 2 instead of 1 like I told it to thing again. What are the numbers for each 6 digits in the score? Maybe I can control it that way. Can someone explain the score[1], score[2], score[3] thing? is score[3] the first 2 digits, score[2] the middle 2 digits, and score[1] the end 2 digits or does it go up to score[6]? If I were to do SpiceWare's solution, I need to know what digit to change and how.

score holds the left two digits.

score+1 holds the middle two digits.

score+2 holds the right two digits.

 

Here's a short program to demonstrate:

 

  rem * What's the score, dude?

  dim byte_1 = score
  dim byte_2 = score+1
  dim byte_3 = score+2

  byte_1 = $12
  byte_2 = $34
  byte_3 = $56

  scorecolor = $0E

loop
  drawscreen
  goto loop

This program defines three variables, byte_1, byte_2, and byte_3, setting each one to be one of the three bytes of the score. "dim byte_1 = score" tells bB that "byte_1" will be used as another name for the RAM address where "score" is located. "dim byte_2 = score+1" tells bB that "byte_2" will be used as another name for the RAM address that's 1 byte after "score." And "dim byte_3 = score+2" tells bB that "byte_3" will be used as another name for the RAM address that's 2 bytes after "score." If you want, you can use other names, like score_1, score_2, and score_3. When you compile and run the program, the score will read "123456." (Don't worry about trying to convert the hexadecimal values to decimal values, because there's no need to.)

 

Let's say you've created a custom score graphics file that adds a blank as "digit 10" (or hexadecimal $A), and you want to display the blank in the second and third positions of the score. Then you could say something like this:

 

  byte_1 = $1A
  byte_2 = $A1
  byte_3 = $23

This would make the score display as "1__123" (where "_" represents the blank).

 

However, you won't be able to do math on the score, because the blanks will mess up the math (or, if you look at it another way, the math will mess up the blanks). So what you'd need to do is fix the score back to a "legal" value first, then do the math on it, then put the blanks back in the score. For example, you could replace the blanks with the digit 0, then do the math on the score, then change the second and third digits back to blanks, like this:

 

  byte_1 = byte_1 && $F0
  byte_2 = byte_2 && $0F
  score = score + 1
  byte_1 = byte_1 || $0A
  byte_2 = byte_2 $$ $0F
  byte_2 = byte_2 || $A0

This may seem very mysterious, so let's look at it line by line.

 

"byte_1 = byte_1 && $F0" will mask the left two digits of the score so that the first digit of the score gets left alone, but the second digit gets changed to a 0. You could also use binary notation to do this, as follows: "byte_1 = byte_1 && %11110000". What this is doing is telling bB that you want it to perform a "bit-wise AND" on the value in "byte_1." That is, each bit of the final result will be a 1 only if the original bit was a 1 AND the bit in the mask is also a 1. So for example, if byte_1 contains the value $7A, then the binary equivalent is %01111010. If you AND that value with %11110000, you get the following result:

 

01111010
11110000
--------
01110000

The bottom row (result) will have a 0 in a given bit if either one of the bits in the rows above it is a 0, and it will have a 1 in a given bit only if both of the bits in the rows above it are 1. So when you AND the bits with %1111, the bits don't change-- but when you AND the bits with %0000, the bits will end up as %0000.

 

Likewise, "byte_2 = byte_2 && $0F" will change the third digit of the score to a 0, and will leave the fourth digit alone.

 

We don't need to do anything about the fifth and sixth digits in this particular case, since you aren't going to be putting any blanks in them for what you're trying to do, so you don't even need to use a byte_3 variable for your program.

 

After you replace the two blanks with 00, you can add 1 to the score, and the math will be okay. In fact, the first two digits should be unchanged, and only the last four digits will be affected, since the biggest value you'd have would be 900999, and adding 1 to that would give you 901000.

 

After you increment the score, you're ready to put the blanks back into the second and third digits, so you do "byte_1 = byte_1 || $0A" to put the blank in the second digit. "||" is the "bit-wise OR," which changes a bit to 1 only if either bit is a 1. So doing "|| %0000" will leave the four bits alone, and doing "|| %1010" will change the four bits to %1010 (since they started out as %0000).

 

For the third and fourth digits, you first need to make sure you clear the third digit, since it might have been increased to a 1 by the math (as in the example of 900999 + 1 = 901000). So first you do "byte_2 = byte_2 && $0F" to clear the third digit without changing the fourth digit, and then you do "byte_2 = byte_2 || $A0" to set the third digit back to the blank without changing the fourth digit.

 

I realize this is a bit complicated (no pun intended!) if you aren't used to dealing with bit operations, but you can use it without fully understanding it.

 

MR

Link to comment
Share on other sites

I take it the 5th line in your third bit of code should be this:

byte_2 = byte_2 && $0F

Yipes! Yes, you're right, I'd made a bad typo.

 

And that works just fine. I even changed the bit_1 to go down one with this example code and didn't even need to ask how.

 

Thanks, Mike!

You're welcome. I hope all of this isn't completely Greek to you... or that you're slowly learning to program in Greek, whatever the case may be! :)

 

MR

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...