uxn

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

commit a62fce63162237837a97f2176bd6de5f8842066f
parent 14bf95ba390f9cb84c23ed084b69787efe253e06
Author: neauoire <aliceffekt@gmail.com>
Date:   Mon, 18 Dec 2023 14:44:36 -0800

Faster screen drawing routines

Diffstat:
Mprojects/examples/demos/cube3d.tal | 6+++---
Mprojects/examples/demos/dvd.tal | 7+++----
Mprojects/examples/demos/hilbert.tal | 74+++++++++++++++++++++++++++++++++-----------------------------------------
Msrc/devices/screen.c | 21+++++++++++----------
Msrc/uxnemu.c | 2+-
5 files changed, 51 insertions(+), 59 deletions(-)

diff --git a/projects/examples/demos/cube3d.tal b/projects/examples/demos/cube3d.tal @@ -26,7 +26,7 @@ ( | clear ) #0000 DUP2 .Screen/x DEO2 .Screen/y DEO2 - #80 .Screen/pixel DEO + [ LIT2 80 -Screen/pixel ] DEO ( | draw ) .timer LDZk INC SWP STZ <draw-cube> @@ -36,7 +36,7 @@ ( | create box ) #0800 &loop ( -- ) - STHk #00 .timer LDZ #00 STHkr INC #07 AND #60 SFT ADD2 #00ff AND2 ;table ADD2 LDA #01 SFT #00 .timer LDZ #00 STHkr #60 SFT ADD2 #00ff AND2 ;table ADD2 LDA #02 SFT #00 STHkr #62 SFT2 ADD2 .cube/v0 STHr DUP ADD ADD STZ2 + STHk [ LIT2 00 -timer ] LDZ #00 STHkr INC #07 AND #60 SFT ADD2 #00ff AND2 ;table ADD2 LDA #01 SFT #00 .timer LDZ #00 STHkr #60 SFT ADD2 #00ff AND2 ;table ADD2 LDA #02 SFT #00 STHkr #62 SFT2 ADD2 .cube/v0 STHr DUP ADD ADD STZ2 INC GTHk ?&loop POP2 ( | vertices ) @@ -65,7 +65,7 @@ #00 SWP #0004 SUB2 .center/y LDZ2 ADD2 .Screen/y DEO2 #00 SWP #0003 SUB2 .center/x LDZ2 ADD2 .Screen/x DEO2 ;&icn .Screen/addr DEO2 - #05 .Screen/sprite DEO + [ LIT2 05 -Screen/sprite ] DEO JMP2r &icn [ 0000 387c 7c7c 3800 ] diff --git a/projects/examples/demos/dvd.tal b/projects/examples/demos/dvd.tal @@ -30,12 +30,12 @@ #00 draw-dvd ( | x ) .dvd/x LDZ2 - ( left ) DUP2 #0000 NEQ2 ?{ #0001 ,&x STR2 } + ( left ) ORAk ?{ #0001 ,&x STR2 } ( right ) DUP2 [ LIT2 &hit-hor $2 ] NEQ2 ?{ #ffff ,&x STR2 } [ LIT2 &x 0001 ] ADD2 .dvd/x STZ2 ( | y ) .dvd/y LDZ2 - ( top ) DUP2 #0000 NEQ2 ?{ #0001 ,&y STR2 } + ( top ) ORAk ?{ #0001 ,&y STR2 } ( bottom ) DUP2 [ LIT2 &hit-ver $2 ] NEQ2 ?{ #ffff ,&y STR2 } [ LIT2 &y 0001 ] ADD2 .dvd/y STZ2 #01 draw-dvd BRK @@ -44,8 +44,7 @@ ;dvd-icn .Screen/addr DEO2 .dvd/x LDZ2 .Screen/x DEO2 .dvd/y LDZ2 .Screen/y DEO2 - .Screen/sprite DEOk - DEO + .Screen/sprite DEOk DEO JMP2r @dvd-icn ( 4 x 2 ) diff --git a/projects/examples/demos/hilbert.tal b/projects/examples/demos/hilbert.tal @@ -1,10 +1,6 @@ |00 @System &vector $2 &wst $1 &rst $1 &eaddr $2 &ecode $1 &pad $1 &r $2 &g $2 &b $2 &debug $1 &halt $1 |20 @Screen &vector $2 &width $2 &height $2 &auto $1 &pad $1 &x $2 &y $2 &addr $2 &pixel $1 &sprite $1 -|00 - - @line &x2 $2 &y2 $2 - |0100 #6f0b .System/r DEO2 @@ -22,7 +18,7 @@ BRK @on-frame ( -> ) [ LIT2 &f $2 ] INC2k ,&f STR2 - INC2k d2xy ROT2 d2xy #01 draw-line + INC2k d2xy ROT2 d2xy #01 <draw-line> BRK @@ -65,43 +61,39 @@ JMP2r JMP2r -@draw-line ( x1* y1* x2* y2* color -- ) - - ( load ) +@<draw-line> ( x1* y1* x2* y2* color -- ) ,&color STR ,&y STR2 ,&x STR2 - .line/y2 STZ2 - .line/x2 STZ2 - - ,&x LDR2 .line/x2 LDZ2 SUB2 abs2 ,&dx STR2 - #0000 ,&y LDR2 .line/y2 LDZ2 SUB2 abs2 SUB2 ,&dy STR2 - - #ffff #00 .line/x2 LDZ2 ,&x LDR2 lts2 DUP2 ADD2 ADD2 ,&sx STR2 - #ffff #00 .line/y2 LDZ2 ,&y LDR2 lts2 DUP2 ADD2 ADD2 ,&sy STR2 - - [ LIT2 &dx $2 ] [ LIT2 &dy $2 ] ADD2 ,&e1 STR2 - - &loop - .line/x2 LDZ2 DUP2 .Screen/x DEO2 [ LIT2 &x $2 ] EQU2 - .line/y2 LDZ2 DUP2 .Screen/y DEO2 [ LIT2 &y $2 ] EQU2 - [ LIT2 &color $1 -Screen/pixel ] DEO - AND ?&end - [ LIT2 &e1 $2 ] DUP2 ADD2 DUP2 - ,&dy LDR2 lts2 ?&skipy - ,&e1 LDR2 ,&dy LDR2 ADD2 ,&e1 STR2 - .line/x2 LDZ2 [ LIT2 &sx $2 ] ADD2 .line/x2 STZ2 - &skipy - ,&dx LDR2 gts2 ?&skipx - ,&e1 LDR2 ,&dx LDR2 ADD2 ,&e1 STR2 - .line/y2 LDZ2 [ LIT2 &sy $2 ] ADD2 .line/y2 STZ2 - &skipx - !&loop - &end - -JMP2r - -@abs2 DUP2 #0f SFT2 EQU #05 JCN #0000 SWP2 SUB2 JMP2r -@lts2 #8000 STH2k ADD2 SWP2 STH2r ADD2 GTH2 JMP2r -@gts2 #8000 STH2k ADD2 SWP2 STH2r ADD2 LTH2 JMP2r + ,&y2 STR2 + ,&x2 STR2 + ,&x LDR2 ,&x2 LDR2 SUB2 abs2 ,&dx STR2 + #0000 ,&y LDR2 ,&y2 LDR2 SUB2 abs2 SUB2 ,&dy STR2 + #ffff [ LIT2 00 _&x2 ] LDR2 ,&x LDR2 lts2 DUP2 ADD2 ADD2 ,&sx STR2 + #ffff [ LIT2 00 _&y2 ] LDR2 ,&y LDR2 lts2 DUP2 ADD2 ADD2 ,&sy STR2 + [ LIT2 &dx $2 ] [ LIT2 &dy $2 ] ADD2 STH2 + &while ( -- ) + [ LIT2 &x2 $2 ] DUP2 .Screen/x DEO2 + [ LIT2 &x $2 ] EQU2 [ LIT2 &y2 $2 ] DUP2 .Screen/y DEO2 + [ LIT2 &y $2 ] EQU2 [ LIT2 &color $1 -Screen/pixel ] DEO + AND ?&end + STH2kr DUP2 ADD2 DUP2 ,&dy LDR2 lts2 ?&skipy + STH2r ,&dy LDR2 ADD2 STH2 + ,&x2 LDR2 [ LIT2 &sx $2 ] ADD2 ,&x2 STR2 + &skipy ( -- ) + ,&dx LDR2 gts2 ?&while + STH2r ,&dx LDR2 ADD2 STH2 + ,&y2 LDR2 [ LIT2 &sy $2 ] ADD2 ,&y2 STR2 + !&while + &end POP2r JMP2r + +@abs2 ( a* -- f ) + DUP2 #0f SFT2 EQU ?{ #0000 SWP2 SUB2 } + JMP2r + +@lts2 ( a* b* -- f ) + #8000 STH2k ADD2 SWP2 STH2r ADD2 GTH2 JMP2r + +@gts2 ( a* b* -- f ) + #8000 STH2k ADD2 SWP2 STH2r ADD2 LTH2 JMP2r diff --git a/src/devices/screen.c b/src/devices/screen.c @@ -19,11 +19,12 @@ UxnScreen uxn_screen; /* c = !ch ? (color % 5 ? color >> 2 : 0) : color % 4 + ch == 1 ? 0 : (ch - 2 + (color & 3)) % 3 + 1; */ -static Uint8 blending[4][16] = { +static Uint8 blending[][16] = { {0, 0, 0, 0, 1, 0, 1, 1, 2, 2, 0, 2, 3, 3, 3, 0}, {0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3}, {1, 2, 3, 1, 1, 2, 3, 1, 1, 2, 3, 1, 1, 2, 3, 1}, - {2, 3, 1, 2, 2, 3, 1, 2, 2, 3, 1, 2, 2, 3, 1, 2}}; + {2, 3, 1, 2, 2, 3, 1, 2, 2, 3, 1, 2, 2, 3, 1, 2}, + {1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0}}; void screen_change(Uint16 x1, Uint16 y1, Uint16 x2, Uint16 y2) @@ -58,15 +59,15 @@ screen_rect(Uint8 *layer, Uint16 x1, Uint16 y1, Uint16 x2, Uint16 y2, int color) static void screen_2bpp(Uint8 *layer, Uint8 *addr, Uint16 x1, Uint16 y1, Uint16 color, int fx, int fy) { - int row, w = uxn_screen.width, h = uxn_screen.height, opaque = (color % 5); + int w = uxn_screen.width, h = uxn_screen.height, opaque = blending[4][color]; Uint16 y, ymod = (fy < 0 ? 7 : 0), ymax = y1 + ymod + fy * 8; Uint16 x, xmod = (fx > 0 ? 7 : 0), xmax = x1 + xmod - fx * 8; for(y = y1 + ymod; y != ymax; y += fy) { - int c = *addr++ | (*(addr + 7) << 8); + int c = *addr++ | (*(addr + 7) << 8), row = y * w; if(y < h) - for(x = x1 + xmod, row = y * w; x != xmax; x -= fx, c >>= 1) { + for(x = x1 + xmod; x != xmax; x -= fx, c >>= 1) { Uint8 ch = (c & 1) | ((c >> 7) & 2); - if((opaque || ch) && x < w) + if(x < w && (opaque || ch)) layer[x + row] = blending[ch][color]; } } @@ -75,15 +76,15 @@ screen_2bpp(Uint8 *layer, Uint8 *addr, Uint16 x1, Uint16 y1, Uint16 color, int f static void screen_1bpp(Uint8 *layer, Uint8 *addr, Uint16 x1, Uint16 y1, Uint16 color, int fx, int fy) { - int row, w = uxn_screen.width, h = uxn_screen.height, opaque = (color % 5); + int w = uxn_screen.width, h = uxn_screen.height, opaque = blending[4][color]; Uint16 y, ymod = (fy < 0 ? 7 : 0), ymax = y1 + ymod + fy * 8; Uint16 x, xmod = (fx > 0 ? 7 : 0), xmax = x1 + xmod - fx * 8; for(y = y1 + ymod; y != ymax; y += fy) { - int c = *addr++; + int c = *addr++, row = y * w; if(y < h) - for(x = x1 + xmod, row = y * w; x != xmax; x -= fx, c >>= 1) { + for(x = x1 + xmod; x != xmax; x -= fx, c >>= 1) { Uint8 ch = c & 1; - if((opaque || ch) && x < w) + if(x < w && (opaque || ch)) layer[x + row] = blending[ch][color]; } } diff --git a/src/uxnemu.c b/src/uxnemu.c @@ -495,7 +495,7 @@ main(int argc, char **argv) /* Read flag. Right now, there can be only one. */ if(argv[i][0] == '-') { if(argv[i][1] == 'v') - return system_version("Uxnemu - Graphical Varvara Emulator", "18 Nov 2023"); + return system_version("Uxnemu - Graphical Varvara Emulator", "18 Dec 2023"); if(argv[i][1] == '-') i++; if(strcmp(argv[i], "-2x") == 0 || strcmp(argv[i], "-3x") == 0)