Forums

Sega Master System / Mark III / Game Gear
SG-1000 / SC-3000 / SF-7000 / OMV
Home - Forums - Games - Scans - Maps - Cheats - Credits
Music - Videos - Development - Hacks - Translations - Homebrew

View topic - Subtracting a score

Reply to topic
Author Message
  • Joined: 06 Sep 2015
  • Posts: 268
  • Location: United States
Reply with quote
Subtracting a score
Post Posted: Sat Aug 11, 2018 6:07 am
So I've got a three-digit score that I want to either add to or subtract from. How do I subtract from it? Am I right in assuming there is no actual score variable, and the "score" is just tiles showing numbers? If so, how do I change the tile numbers to subtract from?
  View user's profile Send private message Visit poster's website
  • Joined: 01 Feb 2014
  • Posts: 877
Reply with quote
Post Posted: Sat Aug 11, 2018 6:31 am
It seems you‘re mixing some things up a bit. You‘re right in assuming that there‘s no way to output a score as a string of digits as you might do in a home computer program. There simply isn‘t some sort of text mode on the Master System, everything on screen is either tiles or sprites (which are also tile based).

So you have to create your way of outputting score yourself. Usually that will involve creating tiles showing digits from 0 to 9, then manipulating the name table so the appropriate digits are shown in the place you have reserved for the score display.

Calculating and storing the score naturally takes place within your program. Again, there‘s a number of ways to handle those tasks. Most commonly you will use BCD, which needs some adjusting to but is very flexible with the kind of math you can do. You can‘t easily output the result, though.

Another way is using one byte per score digit, Jonathan Cauldwell style. The advantage is that you can very easily output the score. However, the drawback is that more complex math (anything other than simple addition and subtraction) is complicated to do, and you need to write a subroutine for every value you want to add to or subtract from your score.

You can read up on both methods in the development section of the site.
  View user's profile Send private message
  • Site Admin
  • Joined: 08 Jul 2001
  • Posts: 8649
  • Location: Paris, France
Reply with quote
Post Posted: Sat Aug 11, 2018 8:20 am
Definitively look up at the BCD opcodes of the Z80.
http://www.smspower.org/Development/BinaryCodedDecimal
  View user's profile Send private message Visit poster's website
  • Joined: 06 Sep 2015
  • Posts: 268
  • Location: United States
Reply with quote
Post Posted: Sat Aug 11, 2018 7:26 pm
While fiddling around with the code, I figured out a way to subtract numbers, and it doesn't use BCD at all. What's more, once it goes past 000, it resets to 999. Here's how I did it:

subsco ld a,(hl)           
       sub b
       ld (hl),a         
       cp 10               
       ret c               

       sub 246             
       ld (hl),a           
-      dec hl           
       dec (hl)         
       ld a,(hl)         
       cp 10           
       ret c             

       sub 246             
       ld (hl),a           
       jp -               

       ret
  View user's profile Send private message Visit poster's website
  • Joined: 23 Mar 2013
  • Posts: 611
  • Location: Copenhagen, Denmark
Reply with quote
Post Posted: Sat Aug 11, 2018 7:32 pm
* EDIT: Ha, nice - you beat me to it :)

You might have a look at the scorelib.inc in Astroswab's source code. I have used the Jonathan Cauldwell approach since Kagesan pointed me in his direction some years ago, and it have always worked well for my (simple) scoring needs.

Excerpt from scorelib.inc below:

.struct score_struct
  ten_thousands db                ; Must be the first item in the score struct!
  thousands db                    ; subtract_from_score depends on it.
  hundreds db
  tens db
  ones db
 [...]
.endst
;
[...]
; -----------------------------------------------------------------------------
.section "score and hiscore handling - functions" free
  ;
  add_to_score:
    ; Add a number passed in B to the digit specified in A. Update the other
    ; digits in the score struct as necessary. Credit to Jonathan Cauldwell.
    ; Entry:  A = Digit to add to
    ;         B = Number to add (non-ascii!)
    ;        HL = Pointer to score struct.
    ; Uses: AF, DE, HL
    ld d,0
    add a,score_struct.ten_thousands
    ld e,a
    add hl,de
    ld a,b
    add a,(hl)
    ld (hl),a
    cp ASCII_ZERO+10
    ret c
      sub 10
      ld (hl),a
      -:
        dec hl
        ;inc hl ??
        inc (hl)
        ld a,(hl)
        cp ASCII_ZERO+10
        ret c
          sub 10
          ld (hl),a
      jp -
      ;
  ret
  ;
  subtract_from_score:
    ; New version.
    ; Entry:  A = Digit to subtract from.
    ;         B = Number to subtract (non-ascii!).
    ;        HL = Pointer to score struct.
    ;
    ld c,a
    ld d,0
    ld e,a
    add hl,de
    ;
    ld a,(hl)
    sub b
    ld (hl),a
    cp ASCII_ZERO
    ret nc
      -:
      add a,10
      ld (hl),a
      ld a,c
      cp 0
      jp z,reset_score
        dec a
        ld c,a
        dec hl
        dec (hl)
        ld a,(hl)
        cp ASCII_ZERO
        ret nc
      jp -
  ret
    ;
    reset_score:
      ex de,hl                            ; Switch to destination (DE).
      ld hl,reset_score_data              ; Point to reset data.
      ld bc,SCORE_DIGITS_TOTAL            ; Number of digits to reset.
      ldir                                ; Do it.
    ret
    ;


And the scorekeeping functions are invoked like this (excerpts from astroswablib.inc):

  asteroid_hits_ground:
    ; What happens when an asteroid hits the ground?
    ; Entry: IX points to asteroid object.
    call deactivate_game_object
    ld hl,player_score
    ld a,SCORE_TENS
    ld b,5
    call subtract_from_score
  ret

  handle_bullet_collision:
    ; Function for handling what happens when bullet collides with other
    ; objects.
    ; Entry: IX = bullet.
    ;        IY = game object that collides with bullet.
    ld a,GAME_OBJECT_INACTIVE     ; Start by deactivating bullet.
    ld (ix+game_object.state),a
    ;
    ld a,(iy+game_object.id)      ; Do different stuff depending on id.
    cp SHARD                      ; Does bullet collide with a shard?
    jp nz,+                       ; No? - skip forward to next id test.
      ld a,GAME_OBJECT_INACTIVE
      ld (iy+game_object.state),a
      ld hl,player_score          ; Yes? - award the player some points.
      ld a,SCORE_HUNDREDS
      ld b,2
      call add_to_score
      ret
    +:


This is meant for inspiration and reference only - the code above will not readily work if copy/pasted out of context.
  View user's profile Send private message Visit poster's website
Reply to topic



Back to the top of this page

Back to SMS Power!