From c8a9f533efc35ccef24f5b9fc298d712053cd345 Mon Sep 17 00:00:00 2001 From: Dennis Ranke Date: Mon, 3 Apr 2023 23:44:12 +0200 Subject: [PATCH] copy optimized blitSprite impl to grabSprite, add simple docs --- examples/include/microw8-api.cwa | 4 +-- examples/include/microw8-api.wat | 4 +-- platform/bin/loader.wasm | Bin 1282 -> 1282 bytes platform/bin/platform.uw8 | Bin 4146 -> 4097 bytes platform/src/platform.cwa | 50 ++++++++++++++++++++----------- site/content/docs.md | 19 ++++++++++-- uw8-tool/src/base_module.rs | 4 +-- 7 files changed, 56 insertions(+), 25 deletions(-) diff --git a/examples/include/microw8-api.cwa b/examples/include/microw8-api.cwa index 60c9478..f7c7456 100644 --- a/examples/include/microw8-api.cwa +++ b/examples/include/microw8-api.cwa @@ -30,8 +30,8 @@ import "env.printInt" fn printInt(i32); import "env.setTextColor" fn setTextColor(i32); import "env.setBackgroundColor" fn setBackgroundColor(i32); import "env.setCursorPosition" fn setCursorPosition(i32, i32); -import "env.rectangle_outline" fn rectangle_outline(f32, f32, f32, f32, i32); -import "env.circle_outline" fn circle_outline(f32, f32, f32, i32); +import "env.rectangleOutline" fn rectangleOutline(f32, f32, f32, f32, i32); +import "env.circleOutline" fn circleOutline(f32, f32, f32, i32); import "env.exp" fn exp(f32) -> f32; import "env.playNote" fn playNote(i32, i32); import "env.sndGes" fn sndGes(i32) -> f32; diff --git a/examples/include/microw8-api.wat b/examples/include/microw8-api.wat index e006e59..55c43ce 100644 --- a/examples/include/microw8-api.wat +++ b/examples/include/microw8-api.wat @@ -30,8 +30,8 @@ (import "env" "setTextColor" (func $setTextColor (param i32))) (import "env" "setBackgroundColor" (func $setBackgroundColor (param i32))) (import "env" "setCursorPosition" (func $setCursorPosition (param i32) (param i32))) -(import "env" "rectangle_outline" (func $rectangle_outline (param f32) (param f32) (param f32) (param f32) (param i32))) -(import "env" "circle_outline" (func $circle_outline (param f32) (param f32) (param f32) (param i32))) +(import "env" "rectangleOutline" (func $rectangleOutline (param f32) (param f32) (param f32) (param f32) (param i32))) +(import "env" "circleOutline" (func $circleOutline (param f32) (param f32) (param f32) (param i32))) (import "env" "exp" (func $exp (param f32) (result f32))) (import "env" "playNote" (func $playNote (param i32) (param i32))) (import "env" "sndGes" (func $sndGes (param i32) (result f32))) diff --git a/platform/bin/loader.wasm b/platform/bin/loader.wasm index 0055ae6e59db4d745a7fd862e19853f030cd623d..ac3ef2a9f65fc995f60da4cab334e51306687cc9 100644 GIT binary patch delta 503 zcmV{LPtWOyQ3N)W}tNzchanV#;tvmEF91jTCn!I4S|$drk& z#7Id=YQb*OUZysl3xnv5Ude(Q^;G-=vClU~%dQI|^xwaAy9s}Ai$wgGlzy^N{MpG0 zlrB>%tS3Jz0ryWNN#fY}NN$`sZCG$S5o|DZ3*v!;Ax#c~$}g9CSrV(DrwIw!tO}Q| z@hnO1{$Sg89t{i^Cl`6p$e>US1U#QTtf$dhawH$(fx^;JS>Os*A?m1`kNS*Ins-pj zC_Jx59tVM+lK6iRz{<9by_};nxND{TPu#M!=^FDaHXG0Oh>>h!)B4hl^^H7}d!_>7 zpl0LVjue_k?){0n(_+D9r|8W3y7;QZ?QUJ~jjaQ>wMj(*s>c4%B}iD2+iVFsfX(OS zZ3mra^5pPpff{Uo*Ae^rYinS*yjS-rS>GD--3?3y$@6bQk64!?xe+OrWW}^*y5b6g z4ID6R?CgKXCV#0Hjlgmu)P1W?du65K&|8IGZTXsrWO|FmVdR%9_Z7o4rp8oqG9?q9 t#*o|JaA8;c)Un}f@PjazZ+=rEc#D6v8F*jmp z#jNJnTYW~EUb=q~IS2Hh7B>BXZnY(n|4|(0tp3KmKj1^cLmt} zG*!@A7o*;-K}5P52O_SJqTitfI+_0==Np5EmRi_yJOv0$IghWd9;#EH;~0b)2dvBf z$8qm5;2ik;O@?kcbhD#xgv2R(Z@cm6(YG6W>;bD`YSC|P!Y-r{>JA1VVXlTQdAJ;; zY;~Vi#+AOZGJD<%9=FBff<8${l8olj%6=9mD t5`dd|S*(DTTSnnuZbr49(27)dMXB_123q15u>BQZH5dWik7CpOxB5uf{$Bt9 diff --git a/platform/bin/platform.uw8 b/platform/bin/platform.uw8 index 33b8e166afb379b646676d46934033d18a3cdf19..16b588b0380e69117f013b69dcc52c8b3dac69d8 100644 GIT binary patch literal 4097 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 diff --git a/platform/src/platform.cwa b/platform/src/platform.cwa index e211f89..24cd220 100644 --- a/platform/src/platform.cwa +++ b/platform/src/platform.cwa @@ -171,7 +171,7 @@ export fn rectangle(x: f32, y: f32, w: f32, h: f32, col: i32) { } } -export fn rectangle_outline(x: f32, y: f32, w: f32, h: f32, col: i32) { +export fn rectangleOutline(x: f32, y: f32, w: f32, h: f32, col: i32) { let xl = nearest(x) as i32; let xr = nearest(x + w) as i32; let yt = nearest(y) as i32; @@ -212,7 +212,7 @@ export fn circle(cx: f32, cy: f32, radius: f32, col: i32) { } } -export fn circle_outline(cx: f32, cy: f32, radius: f32, col: i32) { +export fn circleOutline(cx: f32, cy: f32, radius: f32, col: i32) { let prev_w: f32; let y = clamp(nearest(cy - radius) as i32, -1, 241); let maxY = clamp(nearest(cy + radius) as i32, -1, 241); @@ -377,30 +377,42 @@ export fn blitSprite(sprite: i32, size: i32, x: i32, y: i32, control: i32) { sprite += (height - 1) * width; } - let srcRow = sprite + x0 * flip_x + y0 * flip_y * width; - let dstRow = x + x0 + (y + y0) * 320; + let spriteRow = sprite + x0 * flip_x + y0 * flip_y * width; + let screenRow = x + x0 + (y + y0) * 320; loop yloop { let lx = 0; loop xloop { - let lazy col = (srcRow + lx * flip_x)?0; + let lazy col = (spriteRow + lx * flip_x)?0; if col != trans { - (dstRow + lx)?120 = col; + (screenRow + lx)?120 = col; } branch_if (lx +:= 1) < numCols: xloop; } - srcRow += width * flip_y; - dstRow += 320; + spriteRow += width * flip_y; + screenRow += 320; branch_if numRows -:= 1: yloop; } } export fn grabSprite(sprite: i32, size: i32, x: i32, y: i32, control: i32) { - let width = size & 65535; - let height = select(size >> 16, size >> 16, width); + let lazy width = size & 65535; + let lazy height = select(size >> 16, size >> 16, width); + + let lazy x0 = select(x < 0, -x, 0); + let lazy x1 = select(x + width > 320, 320 - x, width); + let lazy y0 = select(y < 0, -y, 0); + let lazy y1 = select(y + height > 240, 240 - y, height); + + let lazy numRows = y1 - y0; + let lazy numCols = x1 - x0; + if numRows <= 0 | numCols <= 0 { + return; + } + let trans = (control & 511) - 256; - let flip_x = 1 - ((control >> 8) & 2); - let flip_y = 1 - ((control >> 9) & 2); + let lazy flip_x = 1 - ((control >> 8) & 2); + let lazy flip_y = 1 - ((control >> 9) & 2); if flip_x < 0 { sprite += width - 1; } @@ -408,17 +420,21 @@ export fn grabSprite(sprite: i32, size: i32, x: i32, y: i32, control: i32) { sprite += (height - 1) * width; } - let ly = 0; + let spriteRow = sprite + x0 * flip_x + y0 * flip_y * width; + let screenRow = x + x0 + (y + y0) * 320; + loop yloop { let lx = 0; loop xloop { - let col = getPixel(x + lx, y + ly); + let lazy col = (screenRow + lx)?120; if col != trans { - (sprite + lx * flip_x + ly * flip_y * height)?0 = col; + (spriteRow + lx * flip_x)?0 = col; } - branch_if (lx +:= 1) < width: xloop; + branch_if (lx +:= 1) < numCols: xloop; } - branch_if (ly +:= 1) < height: yloop; + spriteRow += width * flip_y; + screenRow += 320; + branch_if numRows -:= 1: yloop; } } diff --git a/site/content/docs.md b/site/content/docs.md index 71a8f41..1b414f2 100644 --- a/site/content/docs.md +++ b/site/content/docs.md @@ -146,13 +146,13 @@ Fills the circle at `cx, cy` and with `radius` with the given color index. (Sets all pixels where the pixel center lies inside the circle.) -### fn rectangle_outline(x: f32, y: f32, w: f32, h: f32, color: i32) +### fn rectangleOutline(x: f32, y: f32, w: f32, h: f32, color: i32) Draws a one pixel outline on the inside of the given rectangle. (Draws the outermost pixels that are still inside the rectangle area.) -### fn circle_outline(cx: f32, cy: f32, radius: f32, color: i32) +### fn circleOutline(cx: f32, cy: f32, radius: f32, color: i32) Draws a one pixel outline on the inside of the given circle. @@ -162,6 +162,21 @@ Draws a one pixel outline on the inside of the given circle. Draws a line from `x1,y1` to `x2,y2` in the given color index. +### fn blitSprite(spriteData: i32, size: i32, x: i32, y: i32, control: i32) + +Copies the pixel data at `spriteData` onto the screen at `x`, `y`. The size of the sprite is passed as `width | (height << 16)`. +If the height is given as 0, the sprite is is treated as square (width x width). + +The control parameter controls masking and flipping of the sprite: +* bits 0-7: color mask index +* bit 8: switch on masked blit (pixel with color mask index are treated as transparent) +* bit 9: flip sprite x +* bit 10: flip sprite y + +### fn grabSprite(spriteData: i32, size: i32, x: i32, y: i32, control: i32) + +Copies the pixel data on the screen at `x`, `y` to `spriteData`. Parameters are exactly the same as `blitSprite`. + ## Input MicroW8 provides input from a gamepad with one D-Pad and 4 buttons, or a keyboard emulation thereof. diff --git a/uw8-tool/src/base_module.rs b/uw8-tool/src/base_module.rs index afcf077..7192d61 100644 --- a/uw8-tool/src/base_module.rs +++ b/uw8-tool/src/base_module.rs @@ -152,14 +152,14 @@ impl BaseModule { add_function( &mut functions, &type_map, - "rectangle_outline", + "rectangleOutline", &[F32, F32, F32, F32, I32], None, ); add_function( &mut functions, &type_map, - "circle_outline", + "circleOutline", &[F32, F32, F32, I32], None, );