Skip to main content

On Sale: GamesAssetsToolsTabletopComics
Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
TagsGame Engines

How to display a large number

A topic by miratha created Oct 16, 2023 Views: 229 Replies: 10
Viewing posts 1 to 7
Submitted

I've read the docs on using BCD to display a single byte in decimal (0 - 255). Is there any code out there to display a number up to 9999 ?

HostSubmitted

You'll need to choose an approach for storing your numbers in multiple bytes. There are various tradeoffs to consider for density vs. ease and speed of arithmetic vs. ease and speed of display. If you store a large number as a single digit per byte it will be quite easy to draw the digits, but e.g. incrementing or adding to that number will be more expensive than if you store two digits per byte.

See also: How Do I Display a Number?

Submitted

In order to do this, you need to write a 16 bit math library: addition, subtraction, multiplication, division. The first two are relativly easy, just add the low and the hight byte and add or subtract the carry bit. For multiplication you may use the russian multipication algorythm (see for example https://www.wikihow.com/Multiply-Using-the-Russian-Peasant-Method) which only works by shifting a binary number and addition. Divison works like you divide on paper. You may convert z80 assembly to chip8. For example from here: https://wikiti.brandonw.net/index.php?title=Z80_Routines:Math:Division or for 6502 (https://llx.com/Neil/a2/mult.html) with good explanation of the algorythm.

Lazy Multiplication by 10 can be done by 
x = x + x ; *2
y = x  
x = x + x ; *4
x = x + x ; * 8
x = x + y;  * 10
You have to use your 16bit addition here and work with two registers. There is no lazy divide by 10

If you have all this, you can start decoding the number to decimal. 
The last digit you get by
1. Divide by 10. 
2. Multiply by 10.
3. Take difference. 
Repeat this until the number is 0

You may also work the other way around.
digit1 = x / 1000
x = x / 10
digit2 = x / 100
x = x / 10
digit3 = x / 10
digit4 = x



HostSubmitted

As a general rule, I'd strongly recommend against starting with a collection of general-purpose routines; they will often do much more work than is actually necessary for a given application, wasting cycles and RAM.

Start with the game concept, and sketch out the design. For all data structures- including number representations- look at the ways your game will use them, and choose representations which make those operations easy.

An efficient program will flow from appropriate choices of data layout and structure. Different design constraints ask for different representations.

Submitted

This code implements a 16 bit unsigned int library in octo. It can read and print 16 bit numbers and has the operations add, sub, mult, div and mod

https://github.com/tquester/J-Octo-Chip8-IDE/blob/main/samples/lib/libMath.8o

Submitted (2 edits) (+1)

A bit late to the party, but this explains the general concepts well if you want to take the calculating road:


But I too think Internet Janitor's idea of storing each digit in its own byte is probably easier to do with less code. Especially if you're just keeping score in a game and you only need to increase your large (0-9999) value by one at a time.

Something like this:

: bump-score
  i := score
  load v3
  v3 += 1
  if v3 == 10 begin
    v3 := 0
    v2 += 1
    if v2 == 10 begin
      v2 := 0
      v1 += 1
      if v1 == 10 begin
        v1 := 0
        v0 += 1
      end
    end
  end
  i := score
  save v3
  return
 
: show-score
  v5 := 0 # Coordinates to draw to
  v6 := 0
  i := score
  load v3
  
  i := bcd-buffer
  bcd v0
  i := bcd-digit
  load v0
  i := hex v0
  sprite v5 v6 5
  v5 += 5
  
  i := bcd-buffer
  bcd v1
  i := bcd-digit
  load v0
  i := hex v0
  sprite v5 v6 5
  v5 += 5
  
  i := bcd-buffer
  bcd v2
  i := bcd-digit
  load v0
  i := hex v0
  sprite v5 v6 5
  v5 += 5
  
  i := bcd-buffer
  bcd v3
  i := bcd-digit
  load v0
  i := hex v0
  sprite v5 v6 5
  
  return
 
: score
  0 0 0 0
: bcd-buffer
  0 0
: bcd-digit
  0
Submitted(+2)

If each memory location contains the number 0..9 than we do not need bcd

: show-score
  v5 := 0 # Coordinates to draw to
  v6 := 0
  i := score
  load v3
  i := hex v0
  sprite v5 v6 5
  v5 += 5
  i := hex v1
  sprite v5 v6 5
  v5 += 5
  i := hex v2
  sprite v5 v6 5
  v5 += 5
  load v3
  i := hex v0
  sprite v5 v6 5
  return

Submitted

Heh, you're absolutely right :) Silly me.

Submitted(+1)

Thank you for all the replies, I've been experimenting and I will put the tips to use for Octojam 11. For now, I'm storing a score with two bytes and displaying the value in hex. I plan to rewrite my game using XO Chip instructions, I'll work on a better score system when I do.

Submitted

Love the result! It runs super smooth, really gives you a feeling of control over your ship. I don't mind the hexadecimal score keeping :)

Submitted

Thank you! I had more ideas, but the code is a bit of a mess. I want to clean it up, switch to XO-Chip, and add some extra features for next year.