From 56490a754f71eae53a7d84b7eb3d1ee3bd9fc97f Mon Sep 17 00:00:00 2001 From: JJ Bliss Date: Sun, 26 Apr 2026 16:00:08 -0400 Subject: [PATCH] passing auto and flip sprite tests --- src/main.ha | 51 ++++++++++++++++----- uxn/uxn.ha | 129 ++++++++++++++++++++++++++++++++++------------------ 2 files changed, 125 insertions(+), 55 deletions(-) diff --git a/src/main.ha b/src/main.ha index 025a197..eacf131 100644 --- a/src/main.ha +++ b/src/main.ha @@ -10,20 +10,24 @@ use uxn; def WIDTH = 640; def HEIGHT = 480; +def DEFAULT_SCALE = 3; export fn main() void = { sdl3::Init(sdl3::InitFlags::VIDEO | sdl3::InitFlags::EVENTS)!; defer sdl3::Quit(); + let scale = DEFAULT_SCALE; const win = sdl3::CreateWindow( c::nulstr("Meadow\0"), - WIDTH, HEIGHT, sdl3::WindowFlags::RESIZABLE | + WIDTH*scale, HEIGHT*scale, sdl3::WindowFlags::RESIZABLE | sdl3::WindowFlags::MOUSE_CAPTURE | sdl3::WindowFlags::INPUT_FOCUS | sdl3::WindowFlags::MOUSE_FOCUS )!; defer sdl3::DestroyWindow(win); + sdl3::SetWindowMinimumSize(win,0,0)!; + const render = sdl3::CreateRenderer(win, null)!; defer sdl3::DestroyRenderer(render); sdl3::SetRenderDrawColor(render, 0, 0, 128, 255)!; @@ -39,6 +43,7 @@ export fn main() void = { screen_w, screen_h)!; defer sdl3::DestroyTexture(meadow_texture); + sdl3::SetTextureScaleMode(meadow_texture, sdl3::ScaleMode::NEAREST)!; // const pixeldata: [WIDTH * HEIGHT]u32 = [0...]; let pixeldata: *[uxn::MAXWIDTH * uxn::MAXHEIGHT]u16 = alloc([0...])!; //TODO figure out actual size defer free (pixeldata); @@ -118,7 +123,7 @@ export fn main() void = { next_refresh = now + frame_interval; if(state.screen_vector != 0){ - fmt::println("Executing screen vector")!; + // fmt::println("Executing screen vector")!; uxn::uxn_eval(state.screen_vector, state)!; }; }; @@ -134,13 +139,14 @@ export fn main() void = { let h: int = dims.height: int; 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, sdl3::PixelFormat::XRGB4444, sdl3::TextureAccess::STATIC, w, h)!; + sdl3::SetTextureScaleMode(meadow_texture, sdl3::ScaleMode::NEAREST)!; state.screen_update = true; }; @@ -179,9 +185,17 @@ export fn main() void = { run = false; case sdl3::EventType::WINDOW_RESIZED => let dims = uxn::get_window_size(state); - let w = ev.window.data1; - let h = ev.window.data2; - if((dims.width != w: u16) || (dims.height != h: u16)){ + let w = ev.window.data1 / scale: i32; + let h = ev.window.data2 / scale: i32; + 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!")!; //TODO handle this maybe 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_h: int = dims.height: int; - fmt::printfln("User setting window to width: {} height: {}", w, h)!; - sdl3::SetWindowSize(win,w,h)!; + // fmt::printfln("User setting window to width: {} height: {}", w, h)!; + sdl3::SetWindowSize(win,w*scale: i32,h*scale: i32)!; meadow_texture = sdl3::CreateTexture(render, sdl3::PixelFormat::XRGB4444, sdl3::TextureAccess::STATIC, w, h)!; + sdl3::SetTextureScaleMode(meadow_texture, sdl3::ScaleMode::NEAREST)!; state.screen_update = true; }; case sdl3::EventType::MOUSE_MOTION => // 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)!; + 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 => sdl3::RenderClear(render)!; sdl3::RenderTexture(render, meadow_texture, null, null)!; @@ -228,7 +257,8 @@ export fn main() void = { sdl3::RenderTexture(render, meadow_texture, null, null)!; sdl3::ShowCursor()!; 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()!; }; }; - diff --git a/uxn/uxn.ha b/uxn/uxn.ha index 73bcd1f..d83a4fd 100644 --- a/uxn/uxn.ha +++ b/uxn/uxn.ha @@ -127,6 +127,18 @@ export fn set_mouse_motion(x: u16, y: u16, state: *uxn) void = { 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 = { const r = short_from_bytes(state.dev[0x08],state.dev[0x09]); 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 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 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); - 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_x) { - const new_x = x + 8; - state.dev[0x28] = (new_x >> 8): u8; - state.dev[0x29] = (new_x): u8; + if(auto_x) { + const new_x = if(flipx) { yield x - 8; } else { yield 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; + }; + 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; + }; + }; + 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 = { - const bytes_per_sprite = if(bpp2) {yield 16;} else {yield 8;}; let dims = get_window_size(state); - let xoff: u16 = 0; - let yoff: u16 = 0; + let xoff: u16 = if(flipx){ yield 7; } else { yield 0; }; + let yoff: u16 = if(flipy){ yield 7; } else { yield 0; }; - if(!bpp2) { - const pixels = get_pixels_from_1bpp_sprite(addr,state); - for(let p .. pixels){ - const color = if(p == 0) { yield 0:u8;} else {yield colors: u8; }; - if((x < MAXWIDTH) && (y < MAXHEIGHT)){ - if(layer1) { state.screen.1[x+xoff][y+yoff] = color; } - else {state.screen.0[x+xoff][y+yoff] = color; }; - }; - xoff += 1; - if(xoff >= 8){ - xoff = 0; - yoff += 1; - }; + + const pixels: []u8 = if(bpp2) { yield get_pixels_from_2bpp_sprite(addr,state); } + else {yield get_pixels_from_1bpp_sprite(addr,state);}; + + for(let p .. pixels){ + const color = if(!bpp2){ + yield if(p == 0) { yield 0:u8;} else {yield colors: u8; }; + + } else { + yield p; }; - }else{ - const pixels = get_pixels_from_2bpp_sprite(addr,state); - for(let p .. pixels){ - 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; } - else {state.screen.0[x+xoff][y+yoff] = color; }; - }; + if((x < MAXWIDTH) && (y < MAXHEIGHT)){ + if(layer1) { state.screen.1[x+xoff][y+yoff] = color; } + else {state.screen.0[x+xoff][y+yoff] = color; }; + }; + + + if(flipx){ + xoff -= 1; + }else { xoff += 1; - if(xoff >= 8){ - xoff = 0; - yoff += 1; + }; + if(xoff >= 8){ + xoff = if(flipx){ yield 7; } else { yield 0; }; + if(flipy){ + yoff -=1; + }else{ + yoff += 1; }; - // if(yoff >= 8){ - // break; - // }; }; }; + }; fn get_pixels_from_1bpp_sprite(addr: u16, state: *uxn) []u8 = {