uxn

Varvara Ordinator, written in ANSI C(SDL2)
git clone https://git.eamoncaddigan.net/uxn.git
Log | Files | Refs | README | LICENSE

commit ac08f08a4d7749ee4b76754d448536e4d8d18ecd
parent 408a73835f4f0aa1d1c05b9c80b777f0cd56a066
Author: neauoire <aliceffekt@gmail.com>
Date:   Thu, 18 Feb 2021 18:16:39 -0800

Starting paint example

Diffstat:
Mbuild.sh | 2+-
Memulator.c | 80++++++++++++++++++++++++++++++++++++++++----------------------------------------
Aexamples/paint.usm | 58++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mexamples/test.usm | 10+++++++++-
Duntitled.chr | 0
5 files changed, 108 insertions(+), 42 deletions(-)

diff --git a/build.sh b/build.sh @@ -20,5 +20,5 @@ cc -std=c89 -DDEBUG -Wall -Wno-unknown-pragmas -Wpedantic -Wshadow -Wextra -Werr # cc uxn.c emulator.c -std=c89 -Os -DNDEBUG -g0 -s -Wall -Wno-unknown-pragmas -L/usr/local/lib -lSDL2 -o bin/emulator # run -./bin/assembler examples/test.usm bin/boot.rom +./bin/assembler examples/paint.usm bin/boot.rom ./bin/emulator bin/boot.rom diff --git a/emulator.c b/emulator.c @@ -20,12 +20,13 @@ WITH REGARD TO THIS SOFTWARE. #define RES (HOR * VER * 16) typedef struct { + Uint8 reqdraw; Uint8 bg[RES], fg[RES]; } Screen; int WIDTH = 8 * HOR + 8 * PAD * 2; int HEIGHT = 8 * VER + 8 * PAD * 2; -int FPS = 30, GUIDES = 1, REQDRAW = 0, ZOOM = 2; +int FPS = 30, GUIDES = 1, ZOOM = 2; Uint32 theme[] = { 0x000000, @@ -58,7 +59,15 @@ SDL_Texture *gTexture; Uint32 *pixels; Screen screen; -Device *devconsole, *devscreen, *devmouse, *devkey, *devsprite, *devcontroller, *devfg; +Device *devconsole, *devscreen, *devmouse, *devkey, *devsprite, *devcontroller; + +#pragma mark - Helpers + +int +clamp(int val, int min, int max) +{ + return (val >= min) ? (val <= max) ? val : max : min; +} #pragma mark - Paint @@ -85,12 +94,27 @@ paintpixel(Uint8 *dst, Uint16 x, Uint16 y, Uint8 color) } void -painticn(Uint8 *dst, Uint16 x, Uint16 y, Uint8 *sprite, Uint8 fg) +paintchr(Uint8 *dst, Uint16 x, Uint16 y, Uint8 *sprite) +{ + Uint16 v, h; + for(v = 0; v < 8; v++) + for(h = 0; h < 8; h++) { + Uint8 ch1 = ((sprite[v] >> h) & 0x1); + Uint8 ch2 = (((sprite[v + 8] >> h) & 0x1) << 1); + paintpixel(dst, x + h, y + v, ch1 + ch2); + } +} + +void +painticn(Uint8 *dst, Uint16 x, Uint16 y, Uint8 *sprite, Uint8 fg, Uint8 alpha) { Uint16 v, h; for(v = 0; v < 8; v++) - for(h = 0; h < 8; h++) - paintpixel(dst, x + h, y + v, ((sprite[v] >> (7 - h)) & 0x1) ? fg : 0); + for(h = 0; h < 8; h++) { + Uint8 ch1 = ((sprite[v] >> (7 - h)) & 0x1); + if(!alpha || (alpha && ch1)) + paintpixel(dst, x + h, y + v, ch1 ? fg : 0); + } } #pragma mark - Helpers @@ -175,7 +199,7 @@ redraw(Uint32 *dst, Uxn *u) SDL_RenderClear(gRenderer); SDL_RenderCopy(gRenderer, gTexture, NULL, NULL); SDL_RenderPresent(gRenderer); - REQDRAW = 0; + screen.reqdraw = 0; } void @@ -216,16 +240,8 @@ init(void) void domouse(SDL_Event *event) { - int x = (event->motion.x - PAD * 8 * ZOOM) / ZOOM; - int y = (event->motion.y - PAD * 8 * ZOOM) / ZOOM; - if(x < 0) - x = 0; - else if(x > WIDTH) - x = WIDTH - 1; - if(y < 0) - y = 0; - else if(y > HEIGHT) - y = HEIGHT - 1; + int x = clamp((event->motion.x - PAD * 8 * ZOOM) / ZOOM, 0, WIDTH - 1); + int y = clamp((event->motion.y - PAD * 8 * ZOOM) / ZOOM, 0, HEIGHT - 1); devmouse->mem[0] = (x >> 8) & 0xff; devmouse->mem[1] = x & 0xff; devmouse->mem[2] = (y >> 8) & 0xff; @@ -300,7 +316,7 @@ screenw(Device *d, Memory *m, Uint8 b) (d->mem[0] << 8) + d->mem[1], d->mem[4]); if(d->mem[5] == 1) - REQDRAW = 1; + screen.reqdraw = 1; d->ptr = 0; } (void)m; @@ -311,32 +327,17 @@ Uint8 spritew(Device *d, Memory *m, Uint8 b) { d->mem[d->ptr++] = b; - if(d->ptr == 6) { - int i; - Uint16 x = (d->mem[2] << 8) + d->mem[3]; - Uint16 y = (d->mem[0] << 8) + d->mem[1]; - Uint16 a = (d->mem[4] << 8) + d->mem[5]; - Uint16 key = (x + y * HOR) * 16; - for(i = 0; i < 16; ++i) - screen.bg[key + i] = m->dat[a + i]; - REQDRAW = 1; - d->ptr = 0; - } - return 0; -} - -Uint8 /* TODO: merge this device into screen/sprite */ -fgw(Device *d, Memory *m, Uint8 b) -{ - d->mem[d->ptr++] = b; if(d->ptr == 7) { Uint16 x = (d->mem[2] << 8) + d->mem[3]; Uint16 y = (d->mem[0] << 8) + d->mem[1]; Uint16 a = (d->mem[4] << 8) + d->mem[5]; Uint8 clr = d->mem[6] & 0xf; Uint8 layer = d->mem[6] >> 4 & 0xf; - painticn(layer ? screen.fg : screen.bg, x, y, &m->dat[a], clr); - REQDRAW = 1; + if(clr > 7) + paintchr(layer ? screen.fg : screen.bg, x, y, &m->dat[a]); + else + painticn(layer ? screen.fg : screen.bg, x, y, &m->dat[a], clr % 4, clr > 3); + screen.reqdraw = 1; d->ptr = 0; } return 0; @@ -349,7 +350,7 @@ start(Uxn *u) { int ticknext = 0; evaluxn(u, u->vreset); - if(REQDRAW) + if(screen.reqdraw) redraw(pixels, u); while(1) { int tick = SDL_GetTicks(); @@ -372,7 +373,7 @@ start(Uxn *u) } } evaluxn(u, u->vframe); - if(REQDRAW) + if(screen.reqdraw) redraw(pixels, u); } } @@ -397,7 +398,6 @@ main(int argc, char **argv) devcontroller = portuxn(&u, "controller", defaultrw, defaultrw); devkey = portuxn(&u, "key", defaultrw, consolew); devmouse = portuxn(&u, "mouse", defaultrw, defaultrw); - devfg = portuxn(&u, "fg", defaultrw, fgw); start(&u); quit(); diff --git a/examples/paint.usm b/examples/paint.usm @@ -0,0 +1,58 @@ +( sprite ) + +:dev/r fff8 ( std read port ) +:dev/w fff9 ( std write port ) + +;mousex 2 ;mousey 2 ;lastx 2 ;lasty 2 ;color 1 + +|0100 @RESET + + #05 =dev/r ( set dev/read mouse ) + #02 =dev/w ( set dev/write to sprite ) + + #00 ,rounds_chr #0004 #0004 ,drawsprite JSR + +BRK + +|c000 @FRAME + + #02 =dev/w ( set dev/write to sprite ) + + ( clear last cursor ) + #10 ,clear_icn ~lastx ~lasty ,drawsprite JSR + + ( record mouse values ) + #00 IOR2 =mousex #02 IOR2 =mousey + #04 IOR #11 ADD =color + + ~color ,cursor_icn ~mousex ~mousey ,drawsprite JSR + + ( check paint ) + #04 IOR #00 EQU ,skip ROT JMP? POP2 + #05 ,brush_large ~mousex #0004 SUB2 ~mousey #0004 SUB2 ,drawsprite JSR + @skip + + ~mousex =lastx ~mousey =lasty + +BRK + +@drawsprite + IOW2 ( y byte ) + IOW2 ( x byte ) + IOW2 ( sprite address ) + IOW ( layer-color ) + RTS + +|0200 @SPRITESHEET + +@rounds_chr [ 3844 92aa 9244 3800 0038 7c7c 7c38 0000 ] +@cursor_icn [ 80c0 e0f0 f8e0 1000 ] +@clear_icn [ 0000 0000 0000 0000 ] +@brush_large [ 387c fefe fe7c 3800 ] +@brush_small [ 0038 7c7c 7c38 0000 ] + +BRK + +|d000 @ERROR BRK + +|FFFA .RESET .FRAME .ERROR diff --git a/examples/test.usm b/examples/test.usm @@ -16,7 +16,7 @@ BRK |c000 @FRAME - #06 =dev/w ( set dev/write to sprite ) + #02 =dev/w ( set dev/write to sprite ) ( clear last cursor ) #10 ,clear_icn ~lastx ~lasty ,drawsprite JSR @@ -26,6 +26,12 @@ BRK #04 IOR #11 ADD =color ~color ,cursor_icn ~mousex ~mousey ,drawsprite JSR + + ( check paint ) + #04 IOR #00 EQU ,skip ROT JMP? POP2 + #05 ,brush_large ~mousex #0004 SUB2 ~mousey #0004 SUB2 ,drawsprite JSR + @skip + ~mousex =lastx ~mousey =lasty BRK @@ -42,6 +48,8 @@ BRK @rounds_chr [ 3844 92aa 9244 3800 0038 7c7c 7c38 0000 ] @cursor_icn [ 80c0 e0f0 f8e0 1000 ] @clear_icn [ 0000 0000 0000 0000 ] +@brush_large [ 387c fefe fe7c 3800 ] +@brush_small [ 0038 7c7c 7c38 0000 ] BRK diff --git a/untitled.chr b/untitled.chr Binary files differ.