Files
microw8/platform/src/platform.cwa
T

389 lines
8.9 KiB
Plaintext

import "env.memory" memory(4);
import "env.cos" fn cos(f32) -> f32;
export fn time() -> f32 {
(0!64) as f32 / 1000 as f32
}
///////////
// INPUT //
///////////
export fn isButtonPressed(btn: i32) -> i32 {
(68!0 >> btn) & 1
}
export fn isButtonTriggered(btn: i32) -> i32 {
((68!0 & (-1 - 68!4)) >> btn) & 1
}
////////////
// RANDOM //
////////////
global mut randomState: i64 = 37i64;
export fn random() -> i32 {
(random64() >> 32i64) as i32
}
export fn random64() -> i64 {
let state: i64;
randomState = (state := (
state := randomState ^ (randomState #>> 12i64)
) ^ (state << 25i64)
) ^ (state #>> 27i64);
randomState * 0x2545f4914f6cdd1di64
}
export fn randomf() -> f32 {
f32.reinterpret_i32(0x3f800000 | (random() #>> 9)) - 1 as f32
}
export fn randomSeed(s: i32) {
randomState = (s as i64 << 32i64) ^ ((63 - s) as i64);
randomState = random64();
randomState = random64();
}
export fn fmod(a: f32, b: f32) -> f32 {
a - floor(a / b) * b
}
/////////////
// DRAWING //
/////////////
export fn cls(col: i32) {
let i: i32;
textCursorX = 0;
textCursorY = 0;
graphicsText = 0;
col = (col & 255) * 0x1010101;
loop pixels {
i!120 = col;
branch_if (i := i + 4) < 320*240: pixels;
}
}
export fn setPixel(x: i32, y: i32, col: i32) {
if x #< 320 & y #< 240 {
(x + y * 320)?120 = col
}
}
export fn getPixel(x: i32, y: i32) -> i32 {
if x #< 320 & y #< 240 {
(x + y * 320)?120
} else {
0
}
}
fn clamp(v: i32, min: i32, max: i32) -> i32 {
select(v < min, min, select(v > max, max, v))
}
export fn hline(x1: i32, x2: i32, y: i32, col: i32) {
x1 = clamp(x1, 0, 320);
x2 = clamp(x2, 0, 320);
if x1 < x2 & y #< 240 {
let ptr = y * 320 + x1;
let end = ptr + x2 - x1;
loop pixels {
ptr?120 = col;
branch_if (ptr := ptr + 1) < end: pixels;
}
}
}
export fn rectangle(x: f32, y: f32, w: f32, h: f32, col: i32) {
if abs(w) == w & abs(h) == h {
let x1 = nearest(x) as i32;
let y1 = clamp(nearest(y) as i32, 0, 240);
let x2 = nearest(x + w) as i32;
let y2 = clamp(nearest(y + h) as i32, 0, 240);
block done {
loop lines {
branch_if y1 >= y2: done;
hline(x1, x2, y1, col);
y1 = y1 + 1;
branch lines;
}
}
}
}
export fn circle(cx: f32, cy: f32, radius: f32, col: i32) {
let y = clamp(nearest(cy - radius) as i32, 0, 240);
let maxY = clamp(nearest(cy + radius) as i32, 0, 240);
block done {
loop lines {
branch_if y >= maxY: done;
let lazy dy = y as f32 - cy + 0.5;
let lazy q = radius * radius - dy * dy;
if abs(q) == q {
let lazy w = sqrt(q);
hline(nearest(cx - w) as i32, nearest(cx + w) as i32, y, col);
}
y = y + 1;
branch lines;
}
}
}
export fn line(x1: f32, y1: f32, x2: f32, y2: f32, col: i32) {
let swapTmp: f32;
if x1 > x2 {
swapTmp = x1;
x1 = x2;
x2 = swapTmp;
swapTmp = y1;
y1 = y2;
y2 = swapTmp;
}
if x1 < 0 as f32 & x2 >= 0 as f32 {
y1 = y1 + (y2 - y1) * -x1 / (x2 - x1);
x1 = 0 as f32;
}
if x1 < 320 as f32 & x2 >= 320 as f32 {
y2 = y2 + (y2 - y1) * (320 as f32 - x2) / (x2 - x1);
x2 = 320 as f32;
}
if y1 > y2 {
swapTmp = x1;
x1 = x2;
x2 = swapTmp;
swapTmp = y1;
y1 = y2;
y2 = swapTmp;
}
if y1 < 0 as f32 & y2 >= 0 as f32 {
x1 = x1 + (x2 - x1) * -y1 / (y2 - y1);
y1 = 0 as f32;
}
if y1 < 240 as f32 & y2 >= 240 as f32 {
x2 = x2 + (x2 - x1) * (240 as f32 - y2) / (y2 - y1);
y2 = 240 as f32;
}
let lazy dx = x2 - x1;
let lazy dy = y2 - y1;
let max_axis: f32;
let p: f32;
if abs(dx) >= dy {
max_axis = dx;
p = x1;
} else {
max_axis = dy;
p = y1;
}
let steps = floor(p + max_axis) as i32 - floor(p) as i32;
p = floor(p) + 0.5 - p;
if max_axis < 0 as f32 {
steps = -steps;
p = -p;
max_axis = -max_axis;
}
dx = dx / max_axis;
dy = dy / max_axis;
let f = min(max_axis, max(0 as f32, p));
setPixel((x1 + f * dx) as i32, (y1 + f * dy) as i32, col);
if !steps {
return;
}
x1 = x1 + (1 as f32 + p) * dx;
y1 = y1 + (1 as f32 + p) * dy;
p = p + steps as f32;
loop pixels {
if steps := steps - 1 {
setPixel(x1 as i32, y1 as i32, col);
x1 = x1 + dx;
y1 = y1 + dy;
branch pixels;
}
}
f = min(max_axis, p) - p;
setPixel((x1 + f * dx) as i32, (y1 + f * dy) as i32, col);
}
//////////
// TEXT //
//////////
global mut textCursorX = 0;
global mut textCursorY = 0;
global mut textColor = 15;
global mut bgColor = 0;
global mut graphicsText = 0;
export fn printChar(char: i32) {
loop chars {
printSingleChar(char & 255);
branch_if (char := char #>> 8): chars;
}
}
fn printSingleChar(char: i32) {
if char == 4 | char == 5 {
graphicsText = char == 5;
return;
}
if char == 10 | (!graphicsText & textCursorX >= 320) {
textCursorX = 0;
textCursorY = textCursorY + 8;
if !graphicsText & textCursorY >= 240 {
textCursorY = 240 - 8;
let i: i32;
loop scroll_copy {
i!120 = i!(120 + 320 * 8);
branch_if (i := i + 4) < 320 * (240 - 8): scroll_copy;
}
rectangle(0 as f32, (240 - 8) as f32, 320 as f32, 8 as f32, bgColor);
}
return;
}
let y: i32;
loop rows {
let bits = (char * 8 + y)?0x13400;
let x = 0;
if graphicsText {
loop pixels {
if (bits := bits << 1) & 256 {
setPixel(textCursorX + x, textCursorY + y, textColor);
}
branch_if (x := x + 1) < 8: pixels;
}
} else {
loop pixels {
setPixel(textCursorX + x, textCursorY + y, select((bits := bits << 1) & 256, textColor, bgColor));
branch_if (x := x + 1) < 8: pixels;
}
}
branch_if (y := y + 1) < 8: rows;
}
textCursorX = textCursorX + 8;
}
export fn printString(ptr: i32) {
loop chars {
let lazy char = ptr?0;
if char {
printChar(char);
ptr = ptr + 1;
branch chars;
}
}
}
export fn printInt(num: i32) {
let lazy p = 0x12fff;
p?0 = 0;
if num < 0 {
printChar(45);
num = -num;
}
loop digits {
(p := p - 1)?0 = 48 + num #% 10;
branch_if (num := num #/ 10): digits;
}
printString(p);
}
export fn setTextColor(col: i32) {
textColor = col;
}
export fn setBackgroundColor(col: i32) {
bgColor = col;
}
export fn setCursorPosition(x: i32, y: i32) {
let lazy scale = select(graphicsText, 1, 8);
textCursorX = x * scale;
textCursorY = y * scale;
}
///////////
// SETUP //
///////////
export fn endFrame() {
68!4 = 68!0;
}
start fn setup() {
let i: i32 = 12*16*3-1;
let avg: f32;
loop gradients {
let lazy scale = (i % 48) as f32 / 48 as f32;
let inline angle = i as f32 * (3.1416 / 1.5 - 3.1416 / (11.0 * 16.0 * 1.5));
let lazy c = 0.4 - cos(angle);
let inline ulimit = avg + 0.8;
let inline llimit = avg - 0.8;
let lazy a = max(llimit, min(ulimit, c)) * (scale + 0.05);
let lazy b = scale * scale * 0.8;
let inline v = (select(i < 11*16*3, max(0 as f32, min(a + b - a * b, 1 as f32)), scale) * 255 as f32) as i32;
(i%3 + i/3*4)?0x13000 = v;
avg = (avg + c) * 0.5;
branch_if i := i - 1: gradients;
}
i = 255;
loop expand_sweetie {
let lazy channel = i & 3;
let lazy index = i >> 2;
let lazy first_step = index >= 32;
let inline src1 = select(first_step, index % 32 / 2, index * 2);
let inline src2 = select(first_step, (index + 1) % 32 / 2, index * 2 + 1);
let inline c1 = (src1 * 4 + channel)?(0x13000+192*4);
let inline c2 = (src2 * 4 + channel)?(0x13000+192*4);
i?(0x13000+192*4) = (c1 + c2) * (3 + first_step) / 8;
branch_if (i := i - 1) >= 0: expand_sweetie;
}
cls(0);
randomSeed(random());
}
data 0x13000+192*4 {
i32(
0x2c1c1a,
0x5d275d,
0x533eb1,
0x577def,
0x75cdff,
0x70f0a7,
0x64b738,
0x797125,
0x6f3629,
0xc95d3b,
0xf6a641,
0xf7ef73,
0xf4f4f4,
0xc2b094,
0x866c56,
0x573c33
)
}
data 0x13400 {
file("../target/font.bin")
}