Jump to content

Photo

How do we keep a high score?


48 replies to this topic

#26 Random Terrain OFFLINE  

Random Terrain

    Visual batari Basic User

  • Topic Starter
  • 28,797 posts
  • Controlled Randomness
    Replay Value
    Nonlinear
  • Location:North Carolina (USA)

Posted Wed Sep 8, 2010 2:47 PM

This really needed to be done. Great work as always RT.

Thanks, but all I did was ask a question. I knew the big brains around here could figure it out.

#27 SeaGtGruff OFFLINE  

SeaGtGruff

    Quadrunner

  • 5,566 posts
  • Location:South Carolina, USA

Posted Wed Sep 8, 2010 5:51 PM

This really needed to be done. Great work as always RT.

Thanks, but all I did was ask a question. I knew the big brains around here could figure it out.

The one I posted should work fine-- but it also depends on how you've defined the bytes. There's nothing magic about sc1, sc2, sc3-- you can define sc1 as the highest byte or the lowest byte, whichever you want. I was using the variable names from supercat's example. Using your variable names, it should be like this:

   if sc1 < High_Score01 then Skip_High_Score
   if sc2 < High_Score02 then Skip_High_Score
   if sc3 < High_Score03 then Skip_High_Score

   High_Score01 = sc1
   High_Score02 = sc2
   High_Score03 = sc3

Skip_High_Score
This assumes that sc1 is for the two leftmost digits of the current score (the most significant byte), sc2 is the middle byte, and sc3 is the rightmost two digits (the least significant byte). Likewise for High_Score01, High_Score02, and High_Score03.

Michael

#28 Nukey Shay OFFLINE  

Nukey Shay

    Sheik Yerbouti

  • 21,794 posts
  • Location:The land of Gorch

Posted Wed Sep 8, 2010 6:22 PM

The problem is that falling though test 1 allows tests 2 or 3 to take their branch and skip the high score reset -regardless- if the first 2 digits were higher or equal than the argument.

Consider 110000 (current score) vs. 11000 (current highscore)...the branch at the first decision is not taken because 11 is greater than 1. However, the branch is taken on the next test because 0 is less than 10. Incorrectly leaving and not resetting the high score.

This problem will happen regardless of which direction you do the tests.

In assembly, you could follow carry status for each subsequent test as posted above by supercat to eliminate that problem.

#29 GroovyBee OFFLINE  

GroovyBee

    Games Developer

  • 9,821 posts
  • Busy bee!
  • Location:England

Posted Wed Sep 8, 2010 6:36 PM

In assembly, you could follow carry status for each subsequent test as posted above by supercat to eliminate that problem.


Would it not be easier to include that routine in an assembler file? Then game programmers can be told not to use certain bB variables because they are already allocated to the high score. It would make life much easier and the resultant ROM image more compact.

#30 Nukey Shay OFFLINE  

Nukey Shay

    Sheik Yerbouti

  • 21,794 posts
  • Location:The land of Gorch

Posted Wed Sep 8, 2010 6:47 PM

Can't you just use the variable names you chose in an inline routine? It's only 26 bytes.

inline
  lda  High_Score03
  cmp  sc3
  lda  High_Score02
  sbc  sc2
  lda  High_Score01
  sbc  sc1
  bcs  No_High_Score
  lda  sc3
  sta  High_Score03
  lda  sc2
  sta  High_Score02
  lda  sc1
  sta  High_Score01
No_High_Score:
  end


#31 Random Terrain OFFLINE  

Random Terrain

    Visual batari Basic User

  • Topic Starter
  • 28,797 posts
  • Controlled Randomness
    Replay Value
    Nonlinear
  • Location:North Carolina (USA)

Posted Wed Sep 8, 2010 7:07 PM

Would it not be easier to include that routine in an assembler file? Then game programmers can be told not to use certain bB variables because they are already allocated to the high score. It would make life much easier and the resultant ROM image more compact.


The following works fine and it's easy enough for a new batari Basic user to understand:

http://www.atariage....ost__p__2089754
   if sc1 > High_Score01 then New_High_Score
   if sc1 < High_Score01 then Skip_High_Score

   rem  *  First byte equal. Do the next test.

   if sc2 > High_Score02 then New_High_Score
   if sc2 < High_Score02 then Skip_High_Score

   rem  *  Second byte equal. Do the next test.

   if sc3 > High_Score03 then New_High_Score
   if sc3 < High_Score03 then Skip_High_Score

   rem  *  All bytes equal.

   goto Skip_High_Score

New_High_Score

   High_Score01 = sc1 : High_Score02 = sc2 : High_Score03 = sc3

Skip_High_Score

If batari wants, we can start including asm alternatives, but we'll need the bB version too.

#32 SeaGtGruff OFFLINE  

SeaGtGruff

    Quadrunner

  • 5,566 posts
  • Location:South Carolina, USA

Posted Wed Sep 8, 2010 8:37 PM

Consider 110000 (current score) vs. 11000 (current highscore)...the branch at the first decision is not taken because 11 is greater than 1. However, the branch is taken on the next test because 0 is less than 10. Incorrectly leaving and not resetting the high score.

Okay, I see that now. :(

Michael

#33 atari2600land OFFLINE  

atari2600land

    Channel F Viewer

  • 11,521 posts
  • Location:Salem, Oregon

Posted Thu Sep 16, 2010 9:34 AM

The following works fine and it's easy enough for a new batari Basic user to understand:


Um.. no? I put the following into my DK3 game:

 byte1=score

 byte2=score+1

 byte3=score+2

 dim High_Score02=o

 dim High_Score03=t

 dim level=p

 level=1

 n{5}=1

const screenheight=84

title_screen
 if byte2 > High_Score02 then New_High_Score
 if byte2 < High_Score02 then Skip_High_Score

 rem * Second byte equal. Do the next test.

 if byte3 > High_Score03 then New_High_Score
 if byte3 < High_Score03 then Skip_High_Score

 rem * All bytes equal.

 goto Skip_High_Score

New_High_Score

 High_Score02 = byte2 : High_Score03 = byte3

Skip_High_Score
Suppose I get 22 points as a high score. I go in and get a lower amount of points, and it doesn't display 22 at the game over.[/size]

[/font]

Attached Files



#34 GroovyBee OFFLINE  

GroovyBee

    Games Developer

  • 9,821 posts
  • Busy bee!
  • Location:England

Posted Thu Sep 16, 2010 9:46 AM

You aren't including byte1 (the least significant byte of the score) in the high score check.

#35 atari2600land OFFLINE  

atari2600land

    Channel F Viewer

  • 11,521 posts
  • Location:Salem, Oregon

Posted Thu Sep 16, 2010 9:59 AM

You aren't including byte1 (the least significant byte of the score) in the high score check.


But byte1 isn't a part of the score. In this game, it's the lives counter.

#36 GroovyBee OFFLINE  

GroovyBee

    Games Developer

  • 9,821 posts
  • Busy bee!
  • Location:England

Posted Thu Sep 16, 2010 10:38 AM

Where are you initialising the high score to 0 at the start?

#37 atari2600land OFFLINE  

atari2600land

    Channel F Viewer

  • 11,521 posts
  • Location:Salem, Oregon

Posted Thu Sep 16, 2010 10:56 AM

Nowhere. I'm just about ready to give up. If someone else wants to take a crack at adding a high score to this, be my guest and post the code if you do. Otherwise, I guess I won't be adding this feature because bB hates me. I've tried just about everything, added the word "then," adding the values, everything. Argh! Posted Image

Attached Files



#38 Random Terrain OFFLINE  

Random Terrain

    Visual batari Basic User

  • Topic Starter
  • 28,797 posts
  • Controlled Randomness
    Replay Value
    Nonlinear
  • Location:North Carolina (USA)

Posted Thu Sep 16, 2010 5:49 PM

Nowhere. I'm just about ready to give up. If someone else wants to take a crack at adding a high score to this, be my guest and post the code if you do. Otherwise, I guess I won't be adding this feature because bB hates me. I've tried just about everything, added the word "then," adding the values, everything. Argh! Posted Image

The bB page has an example program:

http://www.randomter...ands.html#score

It can't get much simpler than that. If you mangle the code, of course it isn't going to work.

#39 RevEng OFFLINE  

RevEng

    Quadrunner

  • 5,013 posts
  • Bitnik
  • Location:bottom of the stack

Posted Thu Sep 16, 2010 6:45 PM

I took a quick look, and I think atari2600land is missing the part that actually displays the high score.

One way to do that is to set the score variables to the saved high score while displaying the titlepage. Or you can get more fancy and swap the saved high score with the current high score every few seconds.

Edited by RevEng, Thu Sep 16, 2010 6:45 PM.


#40 Random Terrain OFFLINE  

Random Terrain

    Visual batari Basic User

  • Topic Starter
  • 28,797 posts
  • Controlled Randomness
    Replay Value
    Nonlinear
  • Location:North Carolina (USA)

Posted Mon Oct 1, 2018 2:08 PM

An efficient multi-byte comparison requires use of the carry flag for multi-precision arithmetic; a three-byte comparison can be done with six instructions totaling 12 bytes to get the result into the carry flag. If multi-precision arithmetic is not available, the logic should be:

  if score_top > highscore_top then YEP
  if score_top < highscore_top then NOPE
  if score_mid > highscore_mid then YEP
  if score_mid < highscore_mid then NOPE
  if score_bot > highscore_bot then YEP
  if score_bot < highscore_bot then NOPE
Otherwise, optimal 6502 code would be:
   lda highscore_bot
   cmp score_bot
   lda highscore_mid
   sbc score_mid
   lda highscore_top
   sbc score_top
  ; Carry will be clear if score > highscore
The CMP will clear the carry if score_bot > highscore_bot and set it otherwise. Each SBC will clear the carry if the corresponding byte of score is greater than the corresponding byte of highscore, set it if the corresponding byte of score is less than the corresponding byte of highscore, and leave it alone if they're equal. Thus, the state of the flag after earlier comparisons is relevant only if later bytes are equal.

 

 
 If I want to turn that into an asm statement, first, do I have the variable names in the correct order in the asm statement below, then what do I do with the "carry will be clear" part? I don't know how to do an if-then based on that.
 

   ;```````````````````````````````````````````````````````````````
   ;  Remembers the high score until the game is turned off.
   ;
   dim _High_Score1 = v
   dim _High_Score2 = w
   dim _High_Score3 = x

   ;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
   ;```````````````````````````````````````````````````````````````
   ;  Converts 6 digit score to 3 sets of two digits.
   ;
   ;  The 100 thousands and 10 thousands digits are held by _sc1.
   ;  The thousands and hundreds digits are held by _sc2.
   ;  The tens and ones digits are held by _sc3.
   ;
   dim _sc1 = score
   dim _sc2 = score+1
   dim _sc3 = score+2

   asm
   lda _High_Score1
   cmp _sc1
   lda _High_Score2
   sbc _sc2
   lda _High_Score3
   sbc _sc3
   ; Carry will be clear if score > _High_Score
end


#41 Karl G OFFLINE  

Karl G

    Dragonstomper

  • 601 posts

Posted Mon Oct 1, 2018 2:39 PM

 

 
 If I want to turn that into an asm statement, first, do I have the variable names in the correct order in the asm statement below, then what do I do with the "carry will be clear" part? I don't know how to do an if-then based on that.
 

   ;```````````````````````````````````````````````````````````````
   ;  Remembers the high score until the game is turned off.
   ;
   dim _High_Score1 = v
   dim _High_Score2 = w
   dim _High_Score3 = x

   ;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
   ;```````````````````````````````````````````````````````````````
   ;  Converts 6 digit score to 3 sets of two digits.
   ;
   ;  The 100 thousands and 10 thousands digits are held by _sc1.
   ;  The thousands and hundreds digits are held by _sc2.
   ;  The tens and ones digits are held by _sc3.
   ;
   dim _sc1 = score
   dim _sc2 = score+1
   dim _sc3 = score+2

   asm
   lda _High_Score1
   cmp _sc1
   lda _High_Score2
   sbc _sc2
   lda _High_Score3
   sbc _sc3
   ; Carry will be clear if score > _High_Score
end

 

You have the variables in the reverse order.  Just like doing a multi-digit subtraction problem, you start with the smallest and borrow from the next digit (the borrow is the "carry".  At the end of the assembly block before the end, you would add something like this:

   bcc ___New_High_Score ; Branch if Carry Clear (goto ___New_High_Score label if carry not set)

This will go to the  ___New_High_Score label you define where your new high score is.  Alternately you could do:

   bcs ___No_High_Score ; Branch if Carry Set (goto ___No_High_Score label if carry is set)

Go to the ___No_High_Score label you define if the carry is not set (new high score not achieved).



#42 Random Terrain OFFLINE  

Random Terrain

    Visual batari Basic User

  • Topic Starter
  • 28,797 posts
  • Controlled Randomness
    Replay Value
    Nonlinear
  • Location:North Carolina (USA)

Posted Mon Oct 1, 2018 2:43 PM

Do you feel like posting the correct asm so I don't screw it up?



#43 Karl G OFFLINE  

Karl G

    Dragonstomper

  • 601 posts

Posted Mon Oct 1, 2018 2:52 PM

This is untested, but you should be able to do something like this:

   ;```````````````````````````````````````````````````````````````
   ;  Remembers the high score until the game is turned off.
   ;
   dim _High_Score1 = v
   dim _High_Score2 = w
   dim _High_Score3 = x

   ;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
   ;```````````````````````````````````````````````````````````````
   ;  Converts 6 digit score to 3 sets of two digits.
   ;
   ;  The 100 thousands and 10 thousands digits are held by _sc1.
   ;  The thousands and hundreds digits are held by _sc2.
   ;  The tens and ones digits are held by _sc3.
   ;
   dim _sc1 = score
   dim _sc2 = score+1
   dim _sc3 = score+2

   asm
   sed
   lda _High_Score3
   cmp _sc3
   lda _High_Score2
   sbc _sc2
   lda _High_Score1
   sbc _sc1
   cld
   ; Carry will be clear if score > _High_Score
   bcs ___No_High_Score ; Branch if Carry Set (goto ___No_High_Score label if carry is set)
end

   ; New High Score code - this is skipped if we goto  ___No_High_Score
   _High_Score1 = _sc1
   _High_Score2 = _sc2
   _High_Score3 = _sc3

___No_High_Score
   ; (more bB code)


#44 Random Terrain OFFLINE  

Random Terrain

    Visual batari Basic User

  • Topic Starter
  • 28,797 posts
  • Controlled Randomness
    Replay Value
    Nonlinear
  • Location:North Carolina (USA)

Posted Mon Oct 1, 2018 3:00 PM

Thanks. I'll try it tonight after I get done doing the bills and eating supper. If it works great, I'll add it to the bB page with credit to you and supercat.



#45 bogax OFFLINE  

bogax

    Dragonstomper

  • 782 posts

Posted Mon Oct 1, 2018 3:13 PM

 

This is untested, but you should be able to do something like this:

   ;```````````````````````````````````````````````````````````````
   ;  Remembers the high score until the game is turned off.
   ;
   dim _High_Score1 = v
   dim _High_Score2 = w
   dim _High_Score3 = x

   ;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
   ;```````````````````````````````````````````````````````````````
   ;  Converts 6 digit score to 3 sets of two digits.
   ;
   ;  The 100 thousands and 10 thousands digits are held by _sc1.
   ;  The thousands and hundreds digits are held by _sc2.
   ;  The tens and ones digits are held by _sc3.
   ;
   dim _sc1 = score
   dim _sc2 = score+1
   dim _sc3 = score+2

   asm
   lda _High_Score3
   cmp _sc3
   lda _High_Score2
   sbc _sc2
   lda _High_Score1
   sbc _sc1
   ; Carry will be clear if score > _High_Score
   bcs ___No_High_Score ; Branch if Carry Set (goto ___No_High_Score label if carry is set)
end

   ; New High Score code - this is skipped if we goto  ___No_High_Score
   _High_Score1 = _sc1
   _High_Score2 = _sc2
   _High_Score3 = _sc3

___No_High_Score
   ; (more bB code)

 

you need decimal mode



#46 Karl G OFFLINE  

Karl G

    Dragonstomper

  • 601 posts

Posted Mon Oct 1, 2018 3:28 PM

 

you need decimal mode

 

Oops!  I edited my post to fix that.



#47 bogax OFFLINE  

bogax

    Dragonstomper

  • 782 posts

Posted Mon Oct 1, 2018 4:08 PM

forgot, bB prepends a "." to labels

 

here's RT's/your code slightly modified and your/RT's code stuffed in to a macro

 

just supply the first byte of high score as a parameter

 ;```````````````````````````````````````````````````````````````
   ;  Remembers the high score until the game is turned off.
   ;
   dim _High_Score1 = v
   dim _High_Score2 = w
   dim _High_Score3 = x
 
   ;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
   ;```````````````````````````````````````````````````````````````
   ;  Converts 6 digit score to 3 sets of two digits.
   ;
   ;  The 100 thousands and 10 thousands digits are held by _sc1.
   ;  The thousands and hundreds digits are held by _sc2.
   ;  The tens and ones digits are held by _sc3.
   ;
   dim _sc1 = score
   dim _sc2 = score+1
   dim _sc3 = score+2
 
mk0
 
   asm
   sed
   lda _High_Score3
   cmp _sc3
   lda _High_Score2
   sbc _sc2
   lda _High_Score1
   sbc _sc1
   cld

   ; Carry will be clear if score > _High_Score
 
   ; need to prepend a . to the label as bB does
   bcs .No_High_Score ; Branch if Carry Set (goto ___No_High_Score label if carry is set)
end
 
   ; New High Score code - this is skipped if we goto  ___No_High_Score
   _High_Score1 = _sc1
   _High_Score2 = _sc2
   _High_Score3 = _sc3
 
No_High_Score
 
   ; (more bB code)
 
mk1
 
 
  def do_hiscore = callmacro _nh
 
  macro _nh
 
   asm
   sed
   lda {1} + 2
   cmp score + 2
   lda {1} + 1
   sbc score + 1
   lda {1}
   sbc score
   cld
   ; Carry will be clear if score > _High_Score
   bcs *+12 ; Branch if Carry Set (goto ___No_High_Score label if carry is set)
   lda score
   sta {1}
   lda score + 1
   sta {1} + 1
   lda score + 2
   sta {1} + 2
end
end
 
  do_hiscore _High_Score1

edit now I left out the sed   :P  (now fixed)


Edited by bogax, Mon Oct 1, 2018 4:57 PM.


#48 Random Terrain OFFLINE  

Random Terrain

    Visual batari Basic User

  • Topic Starter
  • 28,797 posts
  • Controlled Randomness
    Replay Value
    Nonlinear
  • Location:North Carolina (USA)

Posted Mon Oct 1, 2018 4:55 PM

Thanks. Done with the bills, now it's time to eat. I'll be back.



#49 Random Terrain OFFLINE  

Random Terrain

    Visual batari Basic User

  • Topic Starter
  • 28,797 posts
  • Controlled Randomness
    Replay Value
    Nonlinear
  • Location:North Carolina (USA)

Posted Fri Oct 5, 2018 4:42 PM

This is untested, but you should be able to do something like this:


bB was choking on the label, so I had to add a period:
 

   ;***************************************************************
   ;
   ;  High score check using asm.
   ;
   ;  The original supercat code was adapted by Karl G with input
   ;  from bogax.
   ;
   asm
   sed
   lda _High_Score3
   cmp _sc3
   lda _High_Score2
   sbc _sc2
   lda _High_Score1
   sbc _sc1
   cld
   bcs .__Skip_High_Score ; Branch if Carry Set (goto __Skip_High_Score label if carry is set)
end

   ;```````````````````````````````````````````````````````````````
   ;  New high score!
   ;
   _High_Score1 = _sc1 : _High_Score2 = _sc2 : _High_Score3 = _sc3

__Skip_High_Score

 

It seems to be working correctly so far. See if you can break it:

 

Attached File  ex_shoot_with_scrolling_2018y_10m_05d_1757t_asm_highscore.bin   4KB   13 downloads

 

 

It's on the bB page now:

 

randomterrain.com/atari-2600-memories-batari-basic-commands.html#asm_savehighscore






0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users