Spliting UXN devices into seperate files
This commit is contained in:
@@ -0,0 +1,13 @@
|
|||||||
|
|
||||||
|
|
||||||
|
export fn console_input(c: u8, ctype: u8, state: *uxn) (done | error) = {
|
||||||
|
state.dev[0x12] = c;
|
||||||
|
state.dev[0x17] = ctype;
|
||||||
|
if(state.console_vector != 0){
|
||||||
|
// fmt::println("Evaluating Console Vector")!;
|
||||||
|
uxn_eval(state.console_vector, state)?;
|
||||||
|
// fmt::println("Done Evaluating Console Vector")!;
|
||||||
|
}; //TODO implement eval
|
||||||
|
return done;
|
||||||
|
};
|
||||||
|
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
|
||||||
|
export fn set_controller_down(button: u8, state: *uxn) void = {
|
||||||
|
const cur = state.dev[0x82];
|
||||||
|
const new = cur | button;
|
||||||
|
state.dev[0x82] = new;
|
||||||
|
};
|
||||||
|
export fn set_controller_up(button: u8, state: *uxn) void = {
|
||||||
|
const cur = state.dev[0x82];
|
||||||
|
const invbutton = 0xff ^ button;
|
||||||
|
const new = cur & invbutton;
|
||||||
|
state.dev[0x82] = new;
|
||||||
|
};
|
||||||
|
|
||||||
|
export fn set_key_down(key: u8, state: *uxn) void = {
|
||||||
|
state.dev[0x83] = key;
|
||||||
|
};
|
||||||
|
export fn clear_key_down(state: *uxn) void = {
|
||||||
|
state.dev[0x83] = 0;
|
||||||
|
};
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
|
||||||
|
|
||||||
|
export fn set_mouse_motion(x: u16, y: u16, state: *uxn) void = {
|
||||||
|
state.dev[0x92] = (x >> 8): u8;
|
||||||
|
state.dev[0x93] = (x): u8;
|
||||||
|
state.dev[0x94] = (y >> 8): 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;
|
||||||
|
};
|
||||||
+233
@@ -0,0 +1,233 @@
|
|||||||
|
|
||||||
|
fn draw_pixel(value: u8, state: *uxn) void = {
|
||||||
|
//TODO handle fill
|
||||||
|
const color = value & 0b00000011;
|
||||||
|
const x = short_from_bytes(state.dev[0x28],state.dev[0x29]);
|
||||||
|
const y = short_from_bytes(state.dev[0x2a],state.dev[0x2b]);
|
||||||
|
const fill: bool = (value & 0b10000000) != 0;
|
||||||
|
const layer1: bool = (value & 0b01000000) != 0;
|
||||||
|
const flipy: bool = (value & 0b00100000) != 0;
|
||||||
|
const flipx: bool = (value & 0b00010000) != 0;
|
||||||
|
|
||||||
|
if(!fill){
|
||||||
|
// fmt::printfln("Pixel at x: {:x} y: {:x} color: {:x}", x, y, color)!;
|
||||||
|
const auto = state.dev[0x26];
|
||||||
|
let count = ((auto & 0xf0) >> 4): i8;
|
||||||
|
const auto_x = (auto & 0b00000001) != 0;
|
||||||
|
const auto_y = (auto & 0b00000010) != 0;
|
||||||
|
const auto_a = (auto & 0b00000100) != 0;
|
||||||
|
if(!layer1){
|
||||||
|
state.screen.0[x][y] = color;
|
||||||
|
} else {
|
||||||
|
state.screen.1[x][y] = color;
|
||||||
|
};
|
||||||
|
if(auto_x) {
|
||||||
|
const new_x = x + 1;
|
||||||
|
state.dev[0x28] = (new_x >> 8): u8;
|
||||||
|
state.dev[0x29] = (new_x): u8;
|
||||||
|
|
||||||
|
};
|
||||||
|
if(auto_y) {
|
||||||
|
const new_y = y + 1;
|
||||||
|
state.dev[0x2a] = (new_y >> 8): u8;
|
||||||
|
state.dev[0x2b] = (new_y): u8;
|
||||||
|
|
||||||
|
};
|
||||||
|
}else{
|
||||||
|
//TODO see if auto still happens with fill
|
||||||
|
// fmt::println("Doing Fill")!;
|
||||||
|
const dims = get_window_size(state);
|
||||||
|
const startx: u16 = if(flipx) {yield 0; }else{ yield x; };
|
||||||
|
const starty: u16 = if(flipy) {yield 0; }else{ yield y; };
|
||||||
|
const endx: u16 = if(flipx) {yield x; }else{ yield dims.width; };
|
||||||
|
const endy: u16 = if(flipy) {yield y; }else{ yield dims.height; };
|
||||||
|
|
||||||
|
// fmt::printfln("Fill startx: {:x} endx: {:x} starty: {:x} endy: {:x}", startx, endx, starty, endy)!;
|
||||||
|
for(let xl = startx; xl < endx; xl+=1){
|
||||||
|
for(let yl = starty; yl < endy; yl+=1){
|
||||||
|
// fmt::printfln("Filling at x: {:x} y: {:x} color: {:x}", xl, yl, color)!;
|
||||||
|
if(!layer1){
|
||||||
|
state.screen.0[xl][yl] = color;
|
||||||
|
} else {
|
||||||
|
state.screen.1[xl][yl] = color;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
state.screen_update = true;
|
||||||
|
};
|
||||||
|
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]);
|
||||||
|
const b = short_from_bytes(state.dev[0x0c],state.dev[0x0d]);
|
||||||
|
|
||||||
|
|
||||||
|
state.palette[0] = ((r & 0xf000) >> 4) | ((g & 0xf000) >> 8) | ((b & 0xf000) >> 12);
|
||||||
|
state.palette[1] = ((r & 0x0f00) >> 0) | ((g & 0x0f00) >> 4) | ((b & 0x0f00) >> 8);
|
||||||
|
state.palette[2] = ((r & 0x00f0) << 4) | ((g & 0x00f0) >> 0) | ((b & 0x00f0) >> 4);
|
||||||
|
state.palette[3] = ((r & 0x000f) << 8) | ((g & 0x000f) << 4) | ((b & 0x000f) >> 0);
|
||||||
|
// fmt::printfln("Palette Color0: {:x} Color1: {:x} Color2: {:x} Color3: {:x}", state.palette[0], state.palette[1],state.palette[2],state.palette[3])!;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
fn draw_sprite(value: u8, state: *uxn) void = {
|
||||||
|
//TODO handle fill
|
||||||
|
const colors = value & 0b00001111;
|
||||||
|
const auto = state.dev[0x26];
|
||||||
|
let count = ((auto & 0xf0) >> 4): u8;
|
||||||
|
const auto_x = (auto & 0b00000001) != 0;
|
||||||
|
const auto_y = (auto & 0b00000010) != 0;
|
||||||
|
const auto_a = (auto & 0b00000100) != 0;
|
||||||
|
const bpp2: bool = (value & 0b10000000) != 0;
|
||||||
|
const layer1: bool = (value & 0b01000000) != 0;
|
||||||
|
const flipy: bool = (value & 0b00100000) != 0;
|
||||||
|
const flipx: bool = (value & 0b00010000) != 0;
|
||||||
|
|
||||||
|
const x = short_from_bytes(state.dev[0x28],state.dev[0x29]);
|
||||||
|
const y = short_from_bytes(state.dev[0x2a],state.dev[0x2b]);
|
||||||
|
if(count == 0){
|
||||||
|
const addr = short_from_bytes(state.dev[0x2c],state.dev[0x2d]);
|
||||||
|
// 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 = 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 = 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 = {
|
||||||
|
let dims = get_window_size(state);
|
||||||
|
|
||||||
|
let xoff: u16 = if(flipx){ yield 7; } else { yield 0; };
|
||||||
|
let yoff: u16 = if(flipy){ yield 7; } else { yield 0; };
|
||||||
|
const drawZero = ((colors%5 != 0));
|
||||||
|
|
||||||
|
|
||||||
|
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){
|
||||||
|
let color = colormodes[p][colors];
|
||||||
|
|
||||||
|
|
||||||
|
if(drawZero || p > 0){
|
||||||
|
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 = if(flipx){ yield 7; } else { yield 0; };
|
||||||
|
if(flipy){
|
||||||
|
yoff -=1;
|
||||||
|
}else{
|
||||||
|
yoff += 1;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
fn get_pixels_from_1bpp_sprite(addr: u16, state: *uxn) []u8 = {
|
||||||
|
let pixels: [64]u8 = [0...];
|
||||||
|
|
||||||
|
for(let i = 0; i < 8; i+=1){
|
||||||
|
let data: u8 = state.ram[addr + i: u16];
|
||||||
|
pixels[i*8 +0] = (data & 0b10000000) >> 7;
|
||||||
|
pixels[i*8 +1] = (data & 0b01000000) >> 6;
|
||||||
|
pixels[i*8 +2] = (data & 0b00100000) >> 5;
|
||||||
|
pixels[i*8 +3] = (data & 0b00010000) >> 4;
|
||||||
|
pixels[i*8 +4] = (data & 0b00001000) >> 3;
|
||||||
|
pixels[i*8 +5] = (data & 0b00000100) >> 2;
|
||||||
|
pixels[i*8 +6] = (data & 0b00000010) >> 1;
|
||||||
|
pixels[i*8 +7] = (data & 0b00000001) >> 0;
|
||||||
|
};
|
||||||
|
return pixels;
|
||||||
|
};
|
||||||
|
fn get_pixels_from_2bpp_sprite(addr: u16, state: *uxn) []u8 = {
|
||||||
|
let pixels: [64]u8 = [0...];
|
||||||
|
|
||||||
|
for(let i = 0; i < 8; i+=1){
|
||||||
|
const data1: u8 = state.ram[addr + i: u16];
|
||||||
|
const data2: u8 = state.ram[addr + i:u16 + 8];
|
||||||
|
pixels[i*8 +0] = ((data2 & 0b10000000) >> 6) | ((data1 & 0b10000000) >> 7);
|
||||||
|
pixels[i*8 +1] = ((data2 & 0b01000000) >> 5) | ((data1 & 0b01000000) >> 6);
|
||||||
|
pixels[i*8 +2] = ((data2 & 0b00100000) >> 4) | ((data1 & 0b00100000) >> 5);
|
||||||
|
pixels[i*8 +3] = ((data2 & 0b00010000) >> 3) | ((data1 & 0b00010000) >> 4);
|
||||||
|
pixels[i*8 +4] = ((data2 & 0b00001000) >> 2) | ((data1 & 0b00001000) >> 3);
|
||||||
|
pixels[i*8 +5] = ((data2 & 0b00000100) >> 1) | ((data1 & 0b00000100) >> 2);
|
||||||
|
pixels[i*8 +6] = ((data2 & 0b00000010) >> 0) | ((data1 & 0b00000010) >> 1);
|
||||||
|
pixels[i*8 +7] = ((data2 & 0b00000001) << 1) | ((data1 & 0b00000001) >> 0);
|
||||||
|
};
|
||||||
|
return pixels;
|
||||||
|
};
|
||||||
|
|
||||||
|
export fn get_color(x: u16, y: u16, state: *uxn) u16 = {
|
||||||
|
// check layer 1
|
||||||
|
let color = state.screen.1[x][y] & 0b00000011;
|
||||||
|
if(color == 0){
|
||||||
|
color = state.screen.0[x][y] & 0b00000011;
|
||||||
|
};
|
||||||
|
return state.palette[color];
|
||||||
|
};
|
||||||
+89
-370
@@ -274,275 +274,6 @@ fn deo_expansion(addr: u16, state: *uxn) void = {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export fn set_mouse_motion(x: u16, y: u16, state: *uxn) void = {
|
|
||||||
state.dev[0x92] = (x >> 8): u8;
|
|
||||||
state.dev[0x93] = (x): u8;
|
|
||||||
state.dev[0x94] = (y >> 8): 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;
|
|
||||||
};
|
|
||||||
export fn set_controller_down(button: u8, state: *uxn) void = {
|
|
||||||
const cur = state.dev[0x82];
|
|
||||||
const new = cur | button;
|
|
||||||
state.dev[0x82] = new;
|
|
||||||
};
|
|
||||||
export fn set_controller_up(button: u8, state: *uxn) void = {
|
|
||||||
const cur = state.dev[0x82];
|
|
||||||
const invbutton = 0xff ^ button;
|
|
||||||
const new = cur & invbutton;
|
|
||||||
state.dev[0x82] = new;
|
|
||||||
};
|
|
||||||
|
|
||||||
export fn set_key_down(key: u8, state: *uxn) void = {
|
|
||||||
state.dev[0x83] = key;
|
|
||||||
};
|
|
||||||
export fn clear_key_down(state: *uxn) void = {
|
|
||||||
state.dev[0x83] = 0;
|
|
||||||
};
|
|
||||||
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]);
|
|
||||||
const b = short_from_bytes(state.dev[0x0c],state.dev[0x0d]);
|
|
||||||
|
|
||||||
|
|
||||||
state.palette[0] = ((r & 0xf000) >> 4) | ((g & 0xf000) >> 8) | ((b & 0xf000) >> 12);
|
|
||||||
state.palette[1] = ((r & 0x0f00) >> 0) | ((g & 0x0f00) >> 4) | ((b & 0x0f00) >> 8);
|
|
||||||
state.palette[2] = ((r & 0x00f0) << 4) | ((g & 0x00f0) >> 0) | ((b & 0x00f0) >> 4);
|
|
||||||
state.palette[3] = ((r & 0x000f) << 8) | ((g & 0x000f) << 4) | ((b & 0x000f) >> 0);
|
|
||||||
// fmt::printfln("Palette Color0: {:x} Color1: {:x} Color2: {:x} Color3: {:x}", state.palette[0], state.palette[1],state.palette[2],state.palette[3])!;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
fn draw_pixel(value: u8, state: *uxn) void = {
|
|
||||||
//TODO handle fill
|
|
||||||
const color = value & 0b00000011;
|
|
||||||
const x = short_from_bytes(state.dev[0x28],state.dev[0x29]);
|
|
||||||
const y = short_from_bytes(state.dev[0x2a],state.dev[0x2b]);
|
|
||||||
const fill: bool = (value & 0b10000000) != 0;
|
|
||||||
const layer1: bool = (value & 0b01000000) != 0;
|
|
||||||
const flipy: bool = (value & 0b00100000) != 0;
|
|
||||||
const flipx: bool = (value & 0b00010000) != 0;
|
|
||||||
|
|
||||||
if(!fill){
|
|
||||||
// fmt::printfln("Pixel at x: {:x} y: {:x} color: {:x}", x, y, color)!;
|
|
||||||
const auto = state.dev[0x26];
|
|
||||||
let count = ((auto & 0xf0) >> 4): i8;
|
|
||||||
const auto_x = (auto & 0b00000001) != 0;
|
|
||||||
const auto_y = (auto & 0b00000010) != 0;
|
|
||||||
const auto_a = (auto & 0b00000100) != 0;
|
|
||||||
if(!layer1){
|
|
||||||
state.screen.0[x][y] = color;
|
|
||||||
} else {
|
|
||||||
state.screen.1[x][y] = color;
|
|
||||||
};
|
|
||||||
if(auto_x) {
|
|
||||||
const new_x = x + 1;
|
|
||||||
state.dev[0x28] = (new_x >> 8): u8;
|
|
||||||
state.dev[0x29] = (new_x): u8;
|
|
||||||
|
|
||||||
};
|
|
||||||
if(auto_y) {
|
|
||||||
const new_y = y + 1;
|
|
||||||
state.dev[0x2a] = (new_y >> 8): u8;
|
|
||||||
state.dev[0x2b] = (new_y): u8;
|
|
||||||
|
|
||||||
};
|
|
||||||
}else{
|
|
||||||
//TODO see if auto still happens with fill
|
|
||||||
// fmt::println("Doing Fill")!;
|
|
||||||
const dims = get_window_size(state);
|
|
||||||
const startx: u16 = if(flipx) {yield 0; }else{ yield x; };
|
|
||||||
const starty: u16 = if(flipy) {yield 0; }else{ yield y; };
|
|
||||||
const endx: u16 = if(flipx) {yield x; }else{ yield dims.width; };
|
|
||||||
const endy: u16 = if(flipy) {yield y; }else{ yield dims.height; };
|
|
||||||
|
|
||||||
// fmt::printfln("Fill startx: {:x} endx: {:x} starty: {:x} endy: {:x}", startx, endx, starty, endy)!;
|
|
||||||
for(let xl = startx; xl < endx; xl+=1){
|
|
||||||
for(let yl = starty; yl < endy; yl+=1){
|
|
||||||
// fmt::printfln("Filling at x: {:x} y: {:x} color: {:x}", xl, yl, color)!;
|
|
||||||
if(!layer1){
|
|
||||||
state.screen.0[xl][yl] = color;
|
|
||||||
} else {
|
|
||||||
state.screen.1[xl][yl] = color;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
state.screen_update = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
fn draw_sprite(value: u8, state: *uxn) void = {
|
|
||||||
//TODO handle fill
|
|
||||||
const colors = value & 0b00001111;
|
|
||||||
const auto = state.dev[0x26];
|
|
||||||
let count = ((auto & 0xf0) >> 4): u8;
|
|
||||||
const auto_x = (auto & 0b00000001) != 0;
|
|
||||||
const auto_y = (auto & 0b00000010) != 0;
|
|
||||||
const auto_a = (auto & 0b00000100) != 0;
|
|
||||||
const bpp2: bool = (value & 0b10000000) != 0;
|
|
||||||
const layer1: bool = (value & 0b01000000) != 0;
|
|
||||||
const flipy: bool = (value & 0b00100000) != 0;
|
|
||||||
const flipx: bool = (value & 0b00010000) != 0;
|
|
||||||
|
|
||||||
const x = short_from_bytes(state.dev[0x28],state.dev[0x29]);
|
|
||||||
const y = short_from_bytes(state.dev[0x2a],state.dev[0x2b]);
|
|
||||||
if(count == 0){
|
|
||||||
const addr = short_from_bytes(state.dev[0x2c],state.dev[0x2d]);
|
|
||||||
// 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 = 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 = 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 = {
|
|
||||||
let dims = get_window_size(state);
|
|
||||||
|
|
||||||
let xoff: u16 = if(flipx){ yield 7; } else { yield 0; };
|
|
||||||
let yoff: u16 = if(flipy){ yield 7; } else { yield 0; };
|
|
||||||
const drawZero = ((colors%5 != 0));
|
|
||||||
|
|
||||||
|
|
||||||
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){
|
|
||||||
let color = colormodes[p][colors];
|
|
||||||
|
|
||||||
|
|
||||||
if(drawZero || p > 0){
|
|
||||||
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 = if(flipx){ yield 7; } else { yield 0; };
|
|
||||||
if(flipy){
|
|
||||||
yoff -=1;
|
|
||||||
}else{
|
|
||||||
yoff += 1;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
fn get_pixels_from_1bpp_sprite(addr: u16, state: *uxn) []u8 = {
|
|
||||||
let pixels: [64]u8 = [0...];
|
|
||||||
|
|
||||||
for(let i = 0; i < 8; i+=1){
|
|
||||||
let data: u8 = state.ram[addr + i: u16];
|
|
||||||
pixels[i*8 +0] = (data & 0b10000000) >> 7;
|
|
||||||
pixels[i*8 +1] = (data & 0b01000000) >> 6;
|
|
||||||
pixels[i*8 +2] = (data & 0b00100000) >> 5;
|
|
||||||
pixels[i*8 +3] = (data & 0b00010000) >> 4;
|
|
||||||
pixels[i*8 +4] = (data & 0b00001000) >> 3;
|
|
||||||
pixels[i*8 +5] = (data & 0b00000100) >> 2;
|
|
||||||
pixels[i*8 +6] = (data & 0b00000010) >> 1;
|
|
||||||
pixels[i*8 +7] = (data & 0b00000001) >> 0;
|
|
||||||
};
|
|
||||||
return pixels;
|
|
||||||
};
|
|
||||||
fn get_pixels_from_2bpp_sprite(addr: u16, state: *uxn) []u8 = {
|
|
||||||
let pixels: [64]u8 = [0...];
|
|
||||||
|
|
||||||
for(let i = 0; i < 8; i+=1){
|
|
||||||
const data1: u8 = state.ram[addr + i: u16];
|
|
||||||
const data2: u8 = state.ram[addr + i:u16 + 8];
|
|
||||||
pixels[i*8 +0] = ((data2 & 0b10000000) >> 6) | ((data1 & 0b10000000) >> 7);
|
|
||||||
pixels[i*8 +1] = ((data2 & 0b01000000) >> 5) | ((data1 & 0b01000000) >> 6);
|
|
||||||
pixels[i*8 +2] = ((data2 & 0b00100000) >> 4) | ((data1 & 0b00100000) >> 5);
|
|
||||||
pixels[i*8 +3] = ((data2 & 0b00010000) >> 3) | ((data1 & 0b00010000) >> 4);
|
|
||||||
pixels[i*8 +4] = ((data2 & 0b00001000) >> 2) | ((data1 & 0b00001000) >> 3);
|
|
||||||
pixels[i*8 +5] = ((data2 & 0b00000100) >> 1) | ((data1 & 0b00000100) >> 2);
|
|
||||||
pixels[i*8 +6] = ((data2 & 0b00000010) >> 0) | ((data1 & 0b00000010) >> 1);
|
|
||||||
pixels[i*8 +7] = ((data2 & 0b00000001) << 1) | ((data1 & 0b00000001) >> 0);
|
|
||||||
};
|
|
||||||
return pixels;
|
|
||||||
};
|
|
||||||
|
|
||||||
export fn get_color(x: u16, y: u16, state: *uxn) u16 = {
|
|
||||||
// check layer 1
|
|
||||||
let color = state.screen.1[x][y] & 0b00000011;
|
|
||||||
if(color == 0){
|
|
||||||
color = state.screen.0[x][y] & 0b00000011;
|
|
||||||
};
|
|
||||||
return state.palette[color];
|
|
||||||
};
|
|
||||||
|
|
||||||
export type evalerror = !void;
|
export type evalerror = !void;
|
||||||
export type unhandled = !u8;
|
export type unhandled = !u8;
|
||||||
export type quit = void;
|
export type quit = void;
|
||||||
@@ -1229,18 +960,6 @@ export fn uxn_step(state: *uxn) (done | error) = {
|
|||||||
return done;
|
return done;
|
||||||
};
|
};
|
||||||
|
|
||||||
export fn console_input(c: u8, ctype: u8, state: *uxn) (done | error) = {
|
|
||||||
state.dev[0x12] = c;
|
|
||||||
state.dev[0x17] = ctype;
|
|
||||||
if(state.console_vector != 0){
|
|
||||||
// fmt::println("Evaluating Console Vector")!;
|
|
||||||
uxn_eval(state.console_vector, state)?;
|
|
||||||
// fmt::println("Done Evaluating Console Vector")!;
|
|
||||||
}; //TODO implement eval
|
|
||||||
return done;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Converts an error into a user-friendly string
|
// Converts an error into a user-friendly string
|
||||||
export fn strerror(err: error) str = {
|
export fn strerror(err: error) str = {
|
||||||
@@ -1291,94 +1010,94 @@ export fn uxn_reset(state: *uxn) void = {
|
|||||||
state.running = true;
|
state.running = true;
|
||||||
uxn_eval(reset_vector,state)!;
|
uxn_eval(reset_vector,state)!;
|
||||||
};
|
};
|
||||||
export fn uxnrun() void = {
|
// export fn uxnrun() void = {
|
||||||
if(len(os::args) < 2){
|
// if(len(os::args) < 2){
|
||||||
fmt::printf("usage: %s file.rom [args..]\n")!;
|
// fmt::printf("usage: %s file.rom [args..]\n")!;
|
||||||
return;
|
// return;
|
||||||
};
|
// };
|
||||||
let path = os::args[1];
|
// let path = os::args[1];
|
||||||
//Open rom file
|
// //Open rom file
|
||||||
let romfile = match (os::open(path,fs::flag::RDONLY)) {
|
// let romfile = match (os::open(path,fs::flag::RDONLY)) {
|
||||||
case let file: io::file =>
|
// case let file: io::file =>
|
||||||
yield file;
|
// yield file;
|
||||||
case let err: fs::error =>
|
// case let err: fs::error =>
|
||||||
fmt::fatalf("Error opening {}: {}", path, fs::strerror(err));
|
// fmt::fatalf("Error opening {}: {}", path, fs::strerror(err));
|
||||||
};
|
// };
|
||||||
let state: *uxn = initialize_uxn_mem();
|
// let state: *uxn = initialize_uxn_mem();
|
||||||
//Copy rom into ram
|
// //Copy rom into ram
|
||||||
let bytesread = match (io::read(romfile,state.ram[0x100..0xff00])){
|
// let bytesread = match (io::read(romfile,state.ram[0x100..0xff00])){
|
||||||
case let bytes: size =>
|
// case let bytes: size =>
|
||||||
yield bytes;
|
// yield bytes;
|
||||||
case let eof: io::EOF =>
|
// case let eof: io::EOF =>
|
||||||
fmt::fatalf("Empty Rom");
|
// fmt::fatalf("Empty Rom");
|
||||||
case let err: io::error =>
|
// case let err: io::error =>
|
||||||
fmt::fatalf("Error reading: {}", io::strerror(err));
|
// fmt::fatalf("Error reading: {}", io::strerror(err));
|
||||||
};
|
// };
|
||||||
io::close(romfile)!; //TODO, isn't there some kind of oversized roms?
|
// io::close(romfile)!; //TODO, isn't there some kind of oversized roms?
|
||||||
// fread(&ram[0x100], 0xff00, 1, f), fclose(f);
|
// // fread(&ram[0x100], 0xff00, 1, f), fclose(f);
|
||||||
let hasargs = len(os::args) > 2;
|
// let hasargs = len(os::args) > 2;
|
||||||
if(hasargs){
|
// if(hasargs){
|
||||||
state.dev[0x17] = 1;
|
// state.dev[0x17] = 1;
|
||||||
};
|
// };
|
||||||
// dev[0x17] = argc > 2;
|
// // dev[0x17] = argc > 2;
|
||||||
|
|
||||||
let eval = match (uxn_eval(0x100, state)) {
|
// let eval = match (uxn_eval(0x100, state)) {
|
||||||
case done =>
|
// case done =>
|
||||||
yield done;
|
// yield done;
|
||||||
case let val: u8 =>
|
// case let val: u8 =>
|
||||||
fmt::fatalf("Unhandled Opcode: {:x}", val);
|
// fmt::fatalf("Unhandled Opcode: {:x}", val);
|
||||||
};
|
// };
|
||||||
//TODO see if the above needs to not run if console vector not set
|
// //TODO see if the above needs to not run if console vector not set
|
||||||
if(state.console_vector != 0){
|
// if(state.console_vector != 0){
|
||||||
let args = os::args[2..];
|
// let args = os::args[2..];
|
||||||
let i: u8 = 0;
|
// let i: u8 = 0;
|
||||||
let argcount = len(args): u8;
|
// let argcount = len(args): u8;
|
||||||
for (let arg .. args){
|
// for (let arg .. args){
|
||||||
// fmt::println("Console input args")!;
|
// // fmt::println("Console input args")!;
|
||||||
for(let char: u8 .. strings::toutf8(arg)){
|
// for(let char: u8 .. strings::toutf8(arg)){
|
||||||
// fmt::printfln("Console input arg char: {:x}", char)!;
|
// // fmt::printfln("Console input arg char: {:x}", char)!;
|
||||||
match (console_input(char,2,state)) {
|
// match (console_input(char,2,state)) {
|
||||||
case done =>
|
// case done =>
|
||||||
yield done;
|
// yield done;
|
||||||
case let val: u8 =>
|
// case let val: u8 =>
|
||||||
fmt::fatalf("Unhandled Opcode: {:x}", val);
|
// fmt::fatalf("Unhandled Opcode: {:x}", val);
|
||||||
};
|
// };
|
||||||
};
|
// };
|
||||||
let ctype: u8 = if(i == (argcount - 1)){
|
// let ctype: u8 = if(i == (argcount - 1)){
|
||||||
yield 4;
|
// yield 4;
|
||||||
} else {
|
// } else {
|
||||||
yield 3;
|
// yield 3;
|
||||||
};
|
// };
|
||||||
match (console_input('\n',ctype,state)) {
|
// match (console_input('\n',ctype,state)) {
|
||||||
case done =>
|
// case done =>
|
||||||
yield done;
|
// yield done;
|
||||||
case let val: u8 =>
|
// case let val: u8 =>
|
||||||
fmt::fatalf("Unhandled Opcode: {:x}", val);
|
// fmt::fatalf("Unhandled Opcode: {:x}", val);
|
||||||
};
|
// };
|
||||||
i+=1; //TODO using i here seems inelegant
|
// i+=1; //TODO using i here seems inelegant
|
||||||
};
|
// };
|
||||||
for( state.dev[0x0f] == 0; i+=1 ){
|
// for( state.dev[0x0f] == 0; i+=1 ){
|
||||||
let buf: [1]u8 = [0];
|
// let buf: [1]u8 = [0];
|
||||||
let count = io::read(os::stdin, buf)!;
|
// let count = io::read(os::stdin, buf)!;
|
||||||
// fmt::println("Read input")!;
|
// // fmt::println("Read input")!;
|
||||||
if(count != 0) {
|
// if(count != 0) {
|
||||||
match (console_input(buf[0],1,state)) {
|
// match (console_input(buf[0],1,state)) {
|
||||||
case done =>
|
// case done =>
|
||||||
yield done;
|
// yield done;
|
||||||
case let val: u8 =>
|
// case let val: u8 =>
|
||||||
fmt::fatalf("Unhandled Opcode: {:x}", val);
|
// fmt::fatalf("Unhandled Opcode: {:x}", val);
|
||||||
};
|
// };
|
||||||
// fmt::println("Retuned from console_input")!;
|
// // fmt::println("Retuned from console_input")!;
|
||||||
};
|
// };
|
||||||
};
|
// };
|
||||||
// match (console_input('\n',4,state)) { //TODO should this run?
|
// // match (console_input('\n',4,state)) { //TODO should this run?
|
||||||
// case done =>
|
// // case done =>
|
||||||
// yield done;
|
// // yield done;
|
||||||
// case let val: u8 =>
|
// // case let val: u8 =>
|
||||||
// fmt::fatalf("Unhandled Opcode: {:x}", val);
|
// // fmt::fatalf("Unhandled Opcode: {:x}", val);
|
||||||
// };
|
// // };
|
||||||
};
|
// };
|
||||||
fmt::println("Done with uxn")!;
|
// fmt::println("Done with uxn")!;
|
||||||
|
|
||||||
return;
|
// return;
|
||||||
};
|
// };
|
||||||
|
|||||||
Reference in New Issue
Block a user