Log In  


3D Rendering with depth buffer!
[ :: Read More :: ]

Cart #rgb_transition-0 | 2024-06-07 | Embed ▽ | License: CC4-BY-NC-SA

This is a simple transition, that should be fairly easy to use. All the code is in rgb_transition.lua. Simply call rgb_transition_setup() when starting the transition, and then on each frame, after the game is drawn, call rgb_transition(). It takes one argument: Whether the transition should be fading in or out. True fades out. In this test cart, press X to reverse the transition.

P#149607 2024-06-07 23:23

[ :: Read More :: ]

Cart #dbuf_test-2 | 2024-06-07 | Embed ▽ | License: CC4-BY-NC-SA

This is mainly a tech demo for a 3d engine with a depth buffer. This is not finished, but I wanted to share it.


  • Optimisations maybe?
  • BSP - currently model faces aren't sorted, so concave models will work weirdly. The depth buffer is only for interactions between models.
  • Maybe lower the resolution for better performance?
  • Some sort of culling?
  • Better use of depth buffer resolution, make it more linear maybe?

(The depth buffer works with the use of colour tables, in a few passes. If anyone wants more detail, I can provide it.)

Oh yeah, controls:
WASD: Move
QE: Up/Down (relative to look dir)
Arrows: Rotate camera

Z/C: Toggle depth rendering

Thanks @freds72 and @Maeve for advice on the memory issue, I hope it's gone once and for all! (Memory still rises rapidly, so I'll look into what could be causing that too)

P#149396 2024-06-03 19:07 ( Edited 2024-06-07 04:53)

[ :: Read More :: ]

I've encountered a bug where vectors and f64 userdata doesn't get saved in the pod format.

This code:

local foo = vec(10, 10)

print(tostr(foo), 10, 10, 7)

print(pod(foo), 10, 20, 7)

print(tostr(unpod(pod(foo))), 10, 30, 7)

local bar = userdata("f64", 2)
bar.x = 10
bar.y = 10

print(tostr(bar), 10, 50, 7)

print(pod(bar), 10, 60, 7)

print(tostr(unpod(pod(bar))), 10, 70, 7)


(10.00000, 10.00000)
(0.00000, 0.00000)

(10.00000, 10.00000)
(0.00000, 0.00000)

You can see that pod() doesn't save the values for the userdata.

P#148835 2024-05-23 06:47

[ :: Read More :: ]

When switching to picotron or pico-8 by clicking on the icon when it's in fullscreen mode, I encounter a short freeze. Only about a second, but it's pretty annoying. @zep, do you know why this happens? Is it possible to remove?

P#148795 2024-05-22 02:56

[ :: Read More :: ]

Hello. I was playing around with pods, and I noticed that create_diff isn't defined. here's the code (I'm 99% sure I didn't do something really stupid):

local a = {"a", "b", "c"}

local b = {"a", "c", "d"}

local pa = pod(a)

local pb = pod(b)

local pd = create_diff(pa, pb)

@zep was the function removed? it's in https://www.lexaloffle.com/dl/docs/picotron_pod.html#POD_Diffs, but maybe that's outdated.

EDIT: Never mind, it's called create_delta!

P#147670 2024-04-30 19:31 ( Edited 2024-04-30 19:41)

[ :: Read More :: ]

Cart #cgol-2 | 2024-04-23 | Embed ▽ | License: CC4-BY-NC-SA

Here is Conway's Game of Life in Picotron, using the colour tables as a fast way to count all the pixels at once.
This version does not work in the web player, because input is not detected ( @zep pls fix!)

Up: Increase simulation speed
Down: Decrease simulation speed
Space: Pause
F: Step one frame
C: Clear screen
R: Randomise screen
L-Click: Draw pixels
R-Click: Erase Pixels
L: Toggle large cursor

Basic code:

function _init()
    frame = 0

    -- Set up userdata so we can draw the screen to itself
    -- by using memcpy() to a memmapped region of memory.
    -- The userdata is now the contents of the previous frame,
    -- and it is now possible to modify the current frame.
    -- We can also call spr() with userdata
    -- to draw the previous frame to the current one

    screen = userdata("u8", 480, 270)
    memmap(0x30000, screen)

function set_col_table(new, current, col)
    poke(0x8000 + 64*new + current, col)

function _draw()
    frame += 1

    if frame == 1 then
        -- Randomise the screen for the first frame.
        for y=0,269 do
            for x=0,479 do
                if (rnd() < 0.2) pset(x, y, 7)

        -- Copy the current screen to the buffer, just for the first frame
        memcpy(0x30000, 0x10000, 0x20000)


    --if (frame % 32 > 0) return


    -- White cells drawn onto colour 0 will set the colour to 1, white onto 1 will be 2
    -- and so on. This counts the number of neighbouring cells very quickly
    for i=0, 7 do
        set_col_table(7, i, i+1)

    -- Draw the screen 8 times in a ring, for each neighbour. The colour tables
    -- do the counting
    for y=-1,1 do
        for x=-1,1 do
            if (x!=0 or y!=0) spr(screen, x, y)

    -- Set up colour tables to turn the "counted" screen into the next frame
    -- Set every colour to black except for drawing black onto 3 (brought back alive)
    -- and 2 or 3 neighbours for alive (stay alive)
    for i=0, 9 do
        set_col_table(0, i, 0)
        set_col_table(7, i, 0)
    set_col_table(0, 3, 7)
    set_col_table(7, 2, 7)
    set_col_table(7, 3, 7)

    -- Draw the screen to the "counted" version, with the rules set above
    spr(screen, 0, 0)

    -- Reset the draw state to make sure we have a predictable next frame

    -- Copy the screen to the buffer for the next frame,
    -- before we pollute it with the FPS counter
    memcpy(0x30000, 0x10000, 0x20000)

    -- FPS counter
    if key("x") then
        rectfill(0, 0, 44, 8, 0)
        print("FPS: "..stat(7), 1, 1, 8)


P#147143 2024-04-22 21:15 ( Edited 2024-04-23 21:37)