190 lines
4.6 KiB
Hare
190 lines
4.6 KiB
Hare
use sdl3;
|
|
use sdl3::image;
|
|
use sdl3::ttf;
|
|
use types::c;
|
|
use os;
|
|
use io;
|
|
use fmt;
|
|
use strings;
|
|
use uxn;
|
|
|
|
def WIDTH = 640;
|
|
def HEIGHT = 480;
|
|
|
|
export fn main() void = {
|
|
sdl3::Init(sdl3::InitFlags::VIDEO)!;
|
|
defer sdl3::Quit();
|
|
|
|
const win = sdl3::CreateWindow(
|
|
c::nulstr("Meadow\0"),
|
|
WIDTH, HEIGHT, 0)!;
|
|
defer sdl3::DestroyWindow(win);
|
|
|
|
const render = sdl3::CreateRenderer(win, null)!;
|
|
defer sdl3::DestroyRenderer(render);
|
|
sdl3::SetRenderDrawColor(render, 0, 0, 128, 255)!;
|
|
|
|
const img = image::LoadTexture(render, c::nulstr("./assets/mascot.jpg\0"))!;
|
|
defer sdl3::DestroyTexture(img);
|
|
|
|
let w = 0.0f32, h = 0.0f32;
|
|
sdl3::GetTextureSize(img, &w, &h)!;
|
|
sdl3::get_error()!;
|
|
const w = w: int, h = h: int;
|
|
|
|
let x = 0, y = 0;
|
|
let xd = 1, yd = 1;
|
|
|
|
|
|
const screen_w = WIDTH;
|
|
const screen_h = HEIGHT;
|
|
//Create blank texture for screen
|
|
const meadow_texture = sdl3::CreateTexture(render,
|
|
sdl3::PixelFormat::XRGB8888,
|
|
sdl3::TextureAccess::STATIC,
|
|
screen_w,
|
|
screen_h)!;
|
|
defer sdl3::DestroyTexture(meadow_texture);
|
|
// const pixeldata: [WIDTH * HEIGHT]u32 = [0...];
|
|
let pixeldata: *[uxn::MAXWIDTH * uxn::MAXHEIGHT]u32 = alloc([0...])!; //TODO figure out actual size
|
|
|
|
let run = true;
|
|
let ev = sdl3::Event { ... };
|
|
if(len(os::args) < 2){
|
|
fmt::printf("usage: %s file.rom [args..]\n")!;
|
|
return;
|
|
};
|
|
let path = os::args[1];
|
|
let state: *uxn::uxn = uxn::uxn_init(path)!;
|
|
uxn::uxn_reset(state);
|
|
for (run) {
|
|
//UXN stuff
|
|
if(state.running){
|
|
// fmt::printf("Next Step!\n")!;
|
|
uxn::uxn_step(state)!;
|
|
}else{
|
|
// fmt::printf("Not Running!\n")!;
|
|
if(state.console_vector != 0){
|
|
let args = os::args[2..];
|
|
let i: u8 = 0;
|
|
let argcount = len(args): u8;
|
|
for (let arg .. args){
|
|
// fmt::println("Console input args")!;
|
|
for(let char: u8 .. strings::toutf8(arg)){
|
|
// fmt::printfln("Console input arg char: {:x}", char)!;
|
|
match (uxn::console_input(char,2,state)) {
|
|
case done =>
|
|
yield done;
|
|
case let val: u8 =>
|
|
fmt::fatalf("Unhandled Opcode: {:x}", val);
|
|
};
|
|
};
|
|
let ctype: u8 = if(i == (argcount - 1)){
|
|
yield 4;
|
|
} else {
|
|
yield 3;
|
|
};
|
|
match (uxn::console_input('\n',ctype,state)) {
|
|
case done =>
|
|
yield done;
|
|
case let val: u8 =>
|
|
fmt::fatalf("Unhandled Opcode: {:x}", val);
|
|
};
|
|
i+=1; //TODO using i here seems inelegant
|
|
};
|
|
for( state.dev[0x0f] == 0; i+=1 ){
|
|
let buf: [1]u8 = [0];
|
|
let count = io::read(os::stdin, buf)!;
|
|
// fmt::println("Read input")!;
|
|
if(count != 0) {
|
|
match (uxn::console_input(buf[0],1,state)) {
|
|
case done =>
|
|
yield done;
|
|
case let val: u8 =>
|
|
fmt::fatalf("Unhandled Opcode: {:x}", val);
|
|
};
|
|
// fmt::println("Retuned from console_input")!;
|
|
};
|
|
};
|
|
match (uxn::console_input('\n',4,state)) { //TODO should this run?
|
|
case done =>
|
|
yield done;
|
|
case let val: u8 =>
|
|
fmt::fatalf("Unhandled Opcode: {:x}", val);
|
|
};
|
|
};
|
|
};
|
|
if(state.screen_size_changed){
|
|
let dims = uxn::get_window_size(state);
|
|
fmt::printfln("Setting window to width: {:x} height: {:x}", dims.width, dims.height)!;
|
|
if((dims.width != 0) && (dims.height !=0)){
|
|
//TODO, check current dims
|
|
|
|
sdl3::SetWindowSize(win,dims.width: int,dims.height: int)!;
|
|
};
|
|
|
|
|
|
state.screen_size_changed = false;
|
|
};
|
|
|
|
if(state.screen_update){
|
|
let pcount = 0;
|
|
for(let x: u16 = 0; x < screen_w: u16; x+=1 ){
|
|
for(let y: u16 = 0; y < screen_h: u16; y+=1 ){
|
|
const colshort = uxn::get_color(x,y,state);
|
|
//take 16-bit color and transform to 32-bit number
|
|
//XRGB -> XXRXGXBX
|
|
const r = (colshort & 0x0F00): u32 << (3*4);
|
|
const g = (colshort & 0x00F0): u32 << (2*4);
|
|
const b = (colshort & 0x000F): u32 << (1*4);
|
|
const color: u32 = r | g | b;
|
|
// const data = pixeldata: *[*]u32; //
|
|
pixeldata[pcount] = color;
|
|
pcount +=1;
|
|
};
|
|
};
|
|
state.screen_update = false;
|
|
};
|
|
|
|
|
|
//Render stuff
|
|
for (sdl3::PollEvent(&ev)) {
|
|
if (ev.event_type == sdl3::EventType::QUIT) {
|
|
run = false;
|
|
};
|
|
};
|
|
|
|
sdl3::RenderClear(render)!;
|
|
|
|
sdl3::RenderTexture(render, img, null, &sdl3::FRect {
|
|
x = x: f32,
|
|
y = y: f32,
|
|
w = w: f32,
|
|
h = h: f32,
|
|
})!;
|
|
|
|
sdl3::UpdateTexture(meadow_texture, null, pixeldata: *opaque, 32)!;
|
|
sdl3::RenderTexture(render, meadow_texture, null, null)!;
|
|
|
|
sdl3::RenderPresent(render)!;
|
|
sdl3::Delay(1000 / 60);
|
|
|
|
x += xd;
|
|
y += yd;
|
|
if (x + w >= WIDTH) {
|
|
xd = -1;
|
|
};
|
|
if (x <= 0) {
|
|
xd = 1;
|
|
};
|
|
if (y + h >= HEIGHT) {
|
|
yd = -1;
|
|
};
|
|
if (y <= 0) {
|
|
yd = 1;
|
|
};
|
|
|
|
sdl3::get_error()!;
|
|
};
|
|
};
|