passing auto and flip sprite tests

This commit is contained in:
JJ Bliss
2026-04-26 16:00:08 -04:00
parent fc5f41910e
commit 56490a754f
2 changed files with 125 additions and 55 deletions
+40 -11
View File
@@ -10,20 +10,24 @@ use uxn;
def WIDTH = 640; def WIDTH = 640;
def HEIGHT = 480; def HEIGHT = 480;
def DEFAULT_SCALE = 3;
export fn main() void = { export fn main() void = {
sdl3::Init(sdl3::InitFlags::VIDEO | sdl3::InitFlags::EVENTS)!; sdl3::Init(sdl3::InitFlags::VIDEO | sdl3::InitFlags::EVENTS)!;
defer sdl3::Quit(); defer sdl3::Quit();
let scale = DEFAULT_SCALE;
const win = sdl3::CreateWindow( const win = sdl3::CreateWindow(
c::nulstr("Meadow\0"), c::nulstr("Meadow\0"),
WIDTH, HEIGHT, sdl3::WindowFlags::RESIZABLE | WIDTH*scale, HEIGHT*scale, sdl3::WindowFlags::RESIZABLE |
sdl3::WindowFlags::MOUSE_CAPTURE | sdl3::WindowFlags::MOUSE_CAPTURE |
sdl3::WindowFlags::INPUT_FOCUS | sdl3::WindowFlags::INPUT_FOCUS |
sdl3::WindowFlags::MOUSE_FOCUS sdl3::WindowFlags::MOUSE_FOCUS
)!; )!;
defer sdl3::DestroyWindow(win); defer sdl3::DestroyWindow(win);
sdl3::SetWindowMinimumSize(win,0,0)!;
const render = sdl3::CreateRenderer(win, null)!; const render = sdl3::CreateRenderer(win, null)!;
defer sdl3::DestroyRenderer(render); defer sdl3::DestroyRenderer(render);
sdl3::SetRenderDrawColor(render, 0, 0, 128, 255)!; sdl3::SetRenderDrawColor(render, 0, 0, 128, 255)!;
@@ -39,6 +43,7 @@ export fn main() void = {
screen_w, screen_w,
screen_h)!; screen_h)!;
defer sdl3::DestroyTexture(meadow_texture); defer sdl3::DestroyTexture(meadow_texture);
sdl3::SetTextureScaleMode(meadow_texture, sdl3::ScaleMode::NEAREST)!;
// const pixeldata: [WIDTH * HEIGHT]u32 = [0...]; // const pixeldata: [WIDTH * HEIGHT]u32 = [0...];
let pixeldata: *[uxn::MAXWIDTH * uxn::MAXHEIGHT]u16 = alloc([0...])!; //TODO figure out actual size let pixeldata: *[uxn::MAXWIDTH * uxn::MAXHEIGHT]u16 = alloc([0...])!; //TODO figure out actual size
defer free (pixeldata); defer free (pixeldata);
@@ -118,7 +123,7 @@ export fn main() void = {
next_refresh = now + frame_interval; next_refresh = now + frame_interval;
if(state.screen_vector != 0){ if(state.screen_vector != 0){
fmt::println("Executing screen vector")!; // fmt::println("Executing screen vector")!;
uxn::uxn_eval(state.screen_vector, state)!; uxn::uxn_eval(state.screen_vector, state)!;
}; };
}; };
@@ -134,13 +139,14 @@ export fn main() void = {
let h: int = dims.height: int; let h: int = dims.height: int;
fmt::printfln("Setting window to width: {} height: {}", w, h)!; fmt::printfln("Setting window to width: {} height: {}", w, h)!;
sdl3::SetWindowSize(win,w,h)!; sdl3::SetWindowSize(win,w*scale,h*scale)!;
meadow_texture = sdl3::CreateTexture(render, meadow_texture = sdl3::CreateTexture(render,
sdl3::PixelFormat::XRGB4444, sdl3::PixelFormat::XRGB4444,
sdl3::TextureAccess::STATIC, sdl3::TextureAccess::STATIC,
w, w,
h)!; h)!;
sdl3::SetTextureScaleMode(meadow_texture, sdl3::ScaleMode::NEAREST)!;
state.screen_update = true; state.screen_update = true;
}; };
@@ -179,9 +185,17 @@ export fn main() void = {
run = false; run = false;
case sdl3::EventType::WINDOW_RESIZED => case sdl3::EventType::WINDOW_RESIZED =>
let dims = uxn::get_window_size(state); let dims = uxn::get_window_size(state);
let w = ev.window.data1; let w = ev.window.data1 / scale: i32;
let h = ev.window.data2; let h = ev.window.data2 / scale: i32;
if((dims.width != w: u16) || (dims.height != h: u16)){ const wmod = w % scale: i32;
const hmod = h % scale: i32;
if((wmod !=0) || (hmod !=0)){
w = w-wmod;
h = h-hmod;
sdl3::SetWindowSize(win,w,h)!;
};
if((dims.width != w: u16 / scale: u16) || (dims.height != h: u16 / scale: u16)){
// fmt::println("Dimensions not allowed!")!; // fmt::println("Dimensions not allowed!")!;
//TODO handle this maybe //TODO handle this maybe
uxn::set_window_size(w: u16,h: u16,state); uxn::set_window_size(w: u16,h: u16,state);
@@ -191,22 +205,37 @@ export fn main() void = {
let old_w: int = dims.width: int; let old_w: int = dims.width: int;
let old_h: int = dims.height: int; let old_h: int = dims.height: int;
fmt::printfln("User setting window to width: {} height: {}", w, h)!; // fmt::printfln("User setting window to width: {} height: {}", w, h)!;
sdl3::SetWindowSize(win,w,h)!; sdl3::SetWindowSize(win,w*scale: i32,h*scale: i32)!;
meadow_texture = sdl3::CreateTexture(render, meadow_texture = sdl3::CreateTexture(render,
sdl3::PixelFormat::XRGB4444, sdl3::PixelFormat::XRGB4444,
sdl3::TextureAccess::STATIC, sdl3::TextureAccess::STATIC,
w, w,
h)!; h)!;
sdl3::SetTextureScaleMode(meadow_texture, sdl3::ScaleMode::NEAREST)!;
state.screen_update = true; state.screen_update = true;
}; };
case sdl3::EventType::MOUSE_MOTION => case sdl3::EventType::MOUSE_MOTION =>
// fmt::printfln("Mouse Event x: {} y: {}", ev.motion.x, ev.motion.y)!; // fmt::printfln("Mouse Event x: {} y: {}", ev.motion.x, ev.motion.y)!;
uxn::set_mouse_motion(ev.motion.x: u16,ev.motion.y: u16,state); const x = ev.motion.x / scale: f32;
const y = ev.motion.y / scale: f32;
uxn::set_mouse_motion(x: u16,y: u16,state);
uxn::uxn_eval(state.mouse_vector,state)!; uxn::uxn_eval(state.mouse_vector,state)!;
case sdl3::EventType::MOUSE_BUTTON_DOWN =>
// fmt::printfln("Mouse Down: 0x{:x}", ev.button.button: u8 )!;
const b = 1 << (ev.button.button: u8 - 1);
uxn::set_mouse_down(b,state);
uxn::uxn_eval(state.mouse_vector,state)!;
case sdl3::EventType::MOUSE_BUTTON_UP =>
// fmt::printfln("Mouse Up: 0x{:x}", ev.button.button: u8 )!;
const b = 1 << (ev.button.button: u8 - 1);
uxn::set_mouse_up(b,state);
uxn::uxn_eval(state.mouse_vector,state)!;
case sdl3::EventType::MOUSE_WHEEL =>
fmt::printfln("Mouse Wheel!")!;
case sdl3::EventType::WINDOW_EXPOSED => case sdl3::EventType::WINDOW_EXPOSED =>
sdl3::RenderClear(render)!; sdl3::RenderClear(render)!;
sdl3::RenderTexture(render, meadow_texture, null, null)!; sdl3::RenderTexture(render, meadow_texture, null, null)!;
@@ -228,7 +257,8 @@ export fn main() void = {
sdl3::RenderTexture(render, meadow_texture, null, null)!; sdl3::RenderTexture(render, meadow_texture, null, null)!;
sdl3::ShowCursor()!; sdl3::ShowCursor()!;
case => case =>
fmt::printfln("Unhandled SDL event: 0x{:x} , {}", ev.event_type, ev.event_type )!; // fmt::printfln("Unhandled SDL event: 0x{:x} , {}", ev.event_type, ev.event_type )!;
yield;
}; };
}; };
@@ -243,4 +273,3 @@ export fn main() void = {
sdl3::get_error()!; sdl3::get_error()!;
}; };
}; };
+84 -43
View File
@@ -127,6 +127,18 @@ export fn set_mouse_motion(x: u16, y: u16, state: *uxn) void = {
state.dev[0x95] = (y): u8; state.dev[0x95] = (y): u8;
}; };
export fn set_mouse_down(button: u8, state: *uxn) void = {
const cur = state.dev[0x96];
const new = cur | button;
state.dev[0x96] = new;
};
export fn set_mouse_up(button: u8, state: *uxn) void = {
const cur = state.dev[0x96];
const invbutton = 0xff ^ button;
const new = cur & invbutton;
state.dev[0x96] = new;
};
fn regenerate_palettes(state: *uxn) void = { fn regenerate_palettes(state: *uxn) void = {
const r = short_from_bytes(state.dev[0x08],state.dev[0x09]); const r = short_from_bytes(state.dev[0x08],state.dev[0x09]);
const g = short_from_bytes(state.dev[0x0a],state.dev[0x0b]); const g = short_from_bytes(state.dev[0x0a],state.dev[0x0b]);
@@ -215,76 +227,105 @@ fn draw_sprite(value: u8, state: *uxn) void = {
const x = short_from_bytes(state.dev[0x28],state.dev[0x29]); const x = short_from_bytes(state.dev[0x28],state.dev[0x29]);
const y = short_from_bytes(state.dev[0x2a],state.dev[0x2b]); const y = short_from_bytes(state.dev[0x2a],state.dev[0x2b]);
for(let i: u16 = 0; i <= count; i+=1){ if(count == 0){
const addr = short_from_bytes(state.dev[0x2c],state.dev[0x2d]); const addr = short_from_bytes(state.dev[0x2c],state.dev[0x2d]);
const x = x + i * 8; // const x = if(flipx) { yield x - i * 8; } else { yield x + i * 8; };
copy_sprite_to_screen(bpp2,colors,x,y,addr,flipx,flipy,layer1,state); copy_sprite_to_screen(bpp2,colors,x,y,addr,flipx,flipy,layer1,state);
if(auto_a){ if(auto_a){
const new_addr = if(bpp2) { yield addr + 16; } else { yield addr + 8; }; const new_addr = if(bpp2) { yield addr + 16; } else { yield addr + 8; };
state.dev[0x2c] = (new_addr >> 8): u8; state.dev[0x2c] = (new_addr >> 8): u8;
state.dev[0x2d] = (new_addr): u8; state.dev[0x2d] = (new_addr): u8;
}; };
}; if(auto_x) {
if(auto_x) { const new_x = if(flipx) { yield x - 8; } else { yield x + 8; };
const new_x = x + 8; state.dev[0x28] = (new_x >> 8): u8;
state.dev[0x28] = (new_x >> 8): u8; state.dev[0x29] = (new_x): u8;
state.dev[0x29] = (new_x): u8;
};
if(auto_y) {
const new_y = if(flipy) { yield y - 8; } else { yield y + 8; };
state.dev[0x2a] = (new_y >> 8): u8;
state.dev[0x2b] = (new_y): u8;
};
}else {
// fmt::printfln("Multi-Sprite! Auto-x: {} Auto-y: {} Flip-x: {} Flip-y: {}",auto_x,auto_y,flipx,flipy)!;
for(let i: u16 = 0; i <= count; i+=1){
const addr = short_from_bytes(state.dev[0x2c],state.dev[0x2d]);
let x = x;
let y = y;
if(auto_y) {
x = if(flipx) { yield x - i * 8; } else { yield x + i * 8; };
}else if(auto_x) {
y = if(flipy) { yield y - i * 8; } else { yield y + i * 8; };
};
copy_sprite_to_screen(bpp2,colors,x,y,addr,flipx,flipy,layer1,state);
if(auto_a){
const new_addr = if(bpp2) { yield addr + 16; } else { yield addr + 8; };
state.dev[0x2c] = (new_addr >> 8): u8;
state.dev[0x2d] = (new_addr): u8;
};
};
if(auto_y) {
const new_y = if(flipy){ yield y - 8; } else { yield y + 8; };
state.dev[0x2a] = (new_y >> 8): u8;
state.dev[0x2b] = (new_y): u8;
};
if(auto_x) {
const new_x = x + 8;
state.dev[0x28] = (new_x >> 8): u8;
state.dev[0x29] = (new_x): u8;
};
}; };
if(auto_y) {
const new_y = y + 8;
state.dev[0x2a] = (new_y >> 8): u8;
state.dev[0x2b] = (new_y): u8;
};
state.screen_update = true; state.screen_update = true;
}; };
fn copy_sprite_to_screen(bpp2: bool, colors: u8, x: u16, y: u16, addr: u16, flipx: bool, flipy: bool, layer1: bool, state: *uxn) void = { fn copy_sprite_to_screen(bpp2: bool, colors: u8, x: u16, y: u16, addr: u16, flipx: bool, flipy: bool, layer1: bool, state: *uxn) void = {
const bytes_per_sprite = if(bpp2) {yield 16;} else {yield 8;};
let dims = get_window_size(state); let dims = get_window_size(state);
let xoff: u16 = 0; let xoff: u16 = if(flipx){ yield 7; } else { yield 0; };
let yoff: u16 = 0; let yoff: u16 = if(flipy){ yield 7; } else { yield 0; };
if(!bpp2) {
const pixels = get_pixels_from_1bpp_sprite(addr,state); const pixels: []u8 = if(bpp2) { yield get_pixels_from_2bpp_sprite(addr,state); }
for(let p .. pixels){ else {yield get_pixels_from_1bpp_sprite(addr,state);};
const color = if(p == 0) { yield 0:u8;} else {yield colors: u8; };
if((x < MAXWIDTH) && (y < MAXHEIGHT)){ for(let p .. pixels){
if(layer1) { state.screen.1[x+xoff][y+yoff] = color; } const color = if(!bpp2){
else {state.screen.0[x+xoff][y+yoff] = color; }; yield if(p == 0) { yield 0:u8;} else {yield colors: u8; };
};
xoff += 1; } else {
if(xoff >= 8){ yield p;
xoff = 0;
yoff += 1;
};
}; };
}else{ if((x < MAXWIDTH) && (y < MAXHEIGHT)){
const pixels = get_pixels_from_2bpp_sprite(addr,state); if(layer1) { state.screen.1[x+xoff][y+yoff] = color; }
for(let p .. pixels){ else {state.screen.0[x+xoff][y+yoff] = color; };
const color = p; //TODO use colors bits };
// fmt::printfln("x: 0x{:x}, xoff: 0x{:x}, y: 0x{:x}, yoff: 0x{:x}", x,xoff,y,yoff )!;
if((x < MAXWIDTH) && (y < MAXHEIGHT)){
if(layer1) { state.screen.1[x+xoff][y+yoff] = color; } if(flipx){
else {state.screen.0[x+xoff][y+yoff] = color; }; xoff -= 1;
}; }else {
xoff += 1; xoff += 1;
if(xoff >= 8){ };
xoff = 0; if(xoff >= 8){
xoff = if(flipx){ yield 7; } else { yield 0; };
if(flipy){
yoff -=1;
}else{
yoff += 1; yoff += 1;
}; };
// if(yoff >= 8){
// break;
// };
}; };
}; };
}; };
fn get_pixels_from_1bpp_sprite(addr: u16, state: *uxn) []u8 = { fn get_pixels_from_1bpp_sprite(addr: u16, state: *uxn) []u8 = {