Log In  


Greetings all,

New PICO-8 customer here. I've been going over the manual and I'm a bit confused about something. In the Memory section it says "Colour format (gfx/screen) is 2 pixels per byte," which implies 8-bit. But in the Lua Syntax Primer section it says "Numbers in PICO-8 are all 16:16 fixed point," implying 32 bits. In that case you should be able to store 8 pixels-worth of color data per byte.

So what gives, exactly? Can I POKE 32-bit values into sprite/map slots for extra data storage?



Agree that it seems weird for a 32bits machine to only be addressable by 8bits at a time!
But as you probably noticed, peek/poke/memset are really limited to 8bits :[


So I can have 16:16 fixed point values but I can't store them long-term? I'm not understanding the design philosophy here.


yes I'm missing a "poke a 16:16 fixed point number" thing as well. There is dget and dset, which works on "persistent cart data" (256 bytes) only, so you can only save 64 numbers there.


I don't know how open the dev is to such ideas, but I'd suggest picking either 8-bit or 16-bit and going with it for everything. Having 32-bit for some things and 8-bit for others is jarring and counter-intuitive (and the manual isn't doing a good job of explaining how the two fit together).


All numbers in Lua code are 32-bit. You only have to worry about bytes when you use peek/poke and functions like that. Lua memory is separate from the byte-based memory accessed by peek/poke.


Historic 8-bit computers had data types larger than 8 bits.

For practical reasons they had to handle this for the user. This made math operations slightly slower, but BASIC would have been nearly worthless if it could only handle numbers from 0 to 255. Heck even line numbers routinely went above 255.

I'm sure this was a hassle for people programming in ASM, but that's not really what's being emulated by PICO-8.

(P.S. The word "Byte" virtually always refers to exactly 8-bits, I think you're trying to describe the concept of "word size".)


Btw, how come:

band(0x7fff.ffff,-90.5)!=abs(-90.5)

Where is stored the negative bit in pico fixed values??


It might be Twos Compliment.


You can only peek() and poke() to limited areas of memory, so the "PICO-8 acts like a 32-bit machine" aspect isn't as weird in practice as you'd think.

I believe that the 8-bit peek() and poke() are inspired by BASIC, which had byte-based memory ops even on 16-bit computers like the 8086. (And those 16-bit computers had 32-bit ints, as apLundell points out :)


As apLundell said, pico-8 numbers are two's complement 16.16 fixed-point. To negate the value requires a proper two's-complement negation. Merely flipping the top bit will change its sign but the value will also change, same as it would with an int.

On the bright side, this means you can simply treat them intuitively the same way you'd treat integers, but with 16 bits below the decimal (binimal?) point instead of them all being above it as with regular integers.


For an idea of how it works under the hood, here's a hypothetical and very verbose C function for pico-8's intrinsic SQRT(X) function:

int32_t sqrt_fixed( int32_t value_fixed )
{
    // convert fixed to float
    float value_float = value_fixed / 65536.0f;

    // do math work in float format for this example
    float result_float = sqrtf( value_float );

    // convert back to fixed point
    return (int32_t)(value_float * 65536.0f);
}

And yeah, even a C64 had 16-bit and 32-bit values available in the BASIC interpreter. Integers (e.g. "I%") were signed 16-bit, and floats (e.g. just "F") were a weird almost-32-bit float format that wasn't IEEE and had somewhat less precision, but the basic idea was the same.

It's really not so strange to have an 8-bit memory bus with conceptual operations of larger sizes. See also: 64- and 128-bit integer support in various parts of the Win32 API and compiler.



[Please log in to post a comment]