Routine for handling large scores?
I want to store various numbers for scores and levels etc. Some of these can be very large so will need to be held in multiple bytes. I need to be able to increment and decrement these values. Anyone got some useful z80 routines before I start writing my own?
Post edited by Mr Millside on
Comments
Often scores are increased not by 1,2,3 but by bigger numers - like 100 points for shooting an enemy.
If he last digits are always 0s you don't need to store them as part of actual number. Just print the 0s on the screen and print the part that changes in front on them
By adding 2 dumb zeroes you can have up to 6,5 million score held only in 2 bytes, instead of usual 65536
Then I have a routine that can add two scores together, working from the bottom byte up, and accounting for carrying and to convert '10s' as '0s' before adding to them.
Then I write the additive score into a temporary buffer (which should mostly be zeroes - typically you only set one byte to set a score, e.g. 100), call the add routine, and re-display the score.
The only other thing you might need is a byte-by-byte comparison that can tell if one score is bigger than another. You don't need a full maths library.
- IONIAN-GAMES.com -
At the moment I use this code to increment numbers held in a byte array:
; a = the amount to increase the number block by EG: 1 = '10' 2 = '20' 20 = '200' etc ; hl = points to a column of the score, level or bonus number block IncNumberBlock ld b, 0 add a, (hl) ld (hl), a cp 10 ret c DoDecTen inc b sub 10 cp 10 jp nc, DoDecTen ld (hl), a dec hl ld a, b jp IncNumberBlock ScoreData1 defb 0 ; Start of the Score data block (6 bytes) ScoreData2 defb 0 ScoreData3 defb 0 ScoreData4 defb 0 ScoreData5 defb 0 ScoreData6 defb 0This works fine for increments but I was having problems creating similar code to do a decrement. I thought that I may start from scratch then thought I?d ask here to see if anyone has some code that?ll do what I need.I've seen quite a few games that simply store scores and timers in ASCII. Something like
Jon
i.e.
score bytes 00 00 02 01 00 08 07 (representing 21087)
Add HL=001A (26)
score now= 00 00 02 01 01 01 03 (representing 21113)
simples!:)
Something else you might consider with a byte-per-digit system is, instead of adding or subtracting a number of the same length, write code that can add or subtract one digit at an arbitrary point in the score, and do the carrying. So you can subtract 1 or add 5000 just by targeting one significant digit. Th eonly drawback would be, say, to add 250 you'd need to call it twice - once for the 2 and again for the 5.
- IONIAN-GAMES.com -
I'd recommend having a butcher's at Jonathan Cauldwell's routines via Arjun's chuntey blog. The first one shows using 65535 max but the second one I'm recommending uses the ASCII, here it is in fact:
; Add 250 to the score. ld hl,score+3 ; point to hundreds column. ld b,2 ; 2 hundreds = 200. call uscor ; increment the score. ld hl,score+4 ; point to tens column. ld b,5 ; 5 tens = 50. call uscor ; up the score. ret score defb '000000' uscor ld a,(hl) ; current value of digit. add a,b ; add points to this digit. ld (hl),a ; place new digit back in string. cp 58 ; more than ASCII value '9'? ret c ; no - relax. sub 10 ; subtract 10. ld (hl),a ; put new character back in string. uscor0 dec hl ; previous character in string. inc (hl) ; up this by one. ld a,(hl) ; what's the new value? cp 58 ; gone past ASCII nine? ret c ; no, scoring done. sub 10 ; down by ten. ld (hl),a ; put it back jp uscor0 ; go round again.12 INPUT "operation [+-]: ";o$' "number 1: "'y$' ("plus" AND (o$="+" OR o$<>"-"));("minus" AND o$="-")' "number 2: "'z$: LET o$="+-"((o$="-")+1): LET n$="-+"((o$="-")+1) 15 LET y$=y$( TO 16-(16-LEN y$ AND LEN y$<16)) 16 LET z$=z$( TO 16-(16-LEN z$ AND LEN z$<16)) 20 LET a$="0000000000000000"(TO 16-LEN y$)+y$ 21 LET b$="0000000000000000"(TO 16-LEN z$)+z$ 30 PRINT AT 0,0;a$;TAB 15;o$'b$;TAB 15;"="'',, 40 FOR d=16 TO 2 STEP -1 41 LET aa=CODE a$(d): LET bb=CODE b$(d): LET res=VAL ("aa"+o$+"bb"+n$+"48") 43 IF res<48 THEN LET res=res+10: LET b$(d-1)=CHR$ (CODE b$(d-1)+1) 44 IF res>57 THEN LET res=res-10: LET b$(d-1)=CHR$ (CODE b$(d-1)+1) 45 LET a$(d)=CHR$ res: PRINT AT 4,d-1;a$(d) 49 NEXT d 51 LET aa=CODE a$(d): LET bb=CODE b$(d): LET res=VAL ("aa"+o$+"bb"+n$+"48") 53 IF res<48 THEN LET res=res+10: PRINT FLASH 1; INK 2;"underflow" 54 IF res>57 THEN LET res=res-10: PRINT FLASH 1; INK 2;"overflow" 55 LET a$(d)=CHR$ res: PRINT AT 4,d-1;a$(d) 59 GO TO 12Yep, that's how I did the number printing in Bozxle. :)