diff --git a/build.sh b/build.sh index 258424d..2c89f4b 100755 --- a/build.sh +++ b/build.sh @@ -9,10 +9,10 @@ echo "Building.." mkdir -p bin # Build(debug) -gcc -std=c89 -DDEBUG -Wall -Wno-unknown-pragmas -Wpedantic -Wshadow -Wextra -Werror=implicit-int -Werror=incompatible-pointer-types -Werror=int-conversion -Wvla -g -Og -fsanitize=address -fsanitize=undefined src/uxn.c src/devices/system.c src/devices/screen.c src/devices/controller.c src/uxn11.c -o bin/uxn11 -lX11 +gcc -std=c89 -DDEBUG -Wall -Wno-unknown-pragmas -Wpedantic -Wshadow -Wextra -Werror=implicit-int -Werror=incompatible-pointer-types -Werror=int-conversion -Wvla -g -Og -fsanitize=address -fsanitize=undefined src/uxn.c src/devices/system.c src/devices/screen.c src/devices/controller.c src/devices/mouse.c src/devices/datetime.c src/uxn11.c -o bin/uxn11 -lX11 # Build(release) -# gcc src/uxn.c src/devices/system.c src/devices/screen.c src/devices/controller.c src/uxn11.c -o bin/uxn11 -lX11 +# gcc src/uxn.c src/devices/system.c src/devices/screen.c src/devices/controller.c src/devices/mouse.c src/devices/datetime.c src/uxn11.c -o bin/uxn11 -lX11 echo "Running.." bin/uxn11 etc/controller.rom diff --git a/etc/clock.rom b/etc/clock.rom new file mode 100644 index 0000000..e547076 Binary files /dev/null and b/etc/clock.rom differ diff --git a/src/devices/apu.c b/src/devices/apu.c deleted file mode 100644 index 9c55f06..0000000 --- a/src/devices/apu.c +++ /dev/null @@ -1,97 +0,0 @@ -#include "../uxn.h" -#include "apu.h" - -/* -Copyright (c) 2021 Devine Lu Linvega -Copyright (c) 2021 Andrew Alderwick - -Permission to use, copy, modify, and distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE. -*/ - -#define NOTE_PERIOD (SAMPLE_FREQUENCY * 0x4000 / 11025) -#define ADSR_STEP (SAMPLE_FREQUENCY / 0xf) - -/* clang-format off */ - -static Uint32 advances[12] = { - 0x80000, 0x879c8, 0x8facd, 0x9837f, 0xa1451, 0xaadc1, - 0xb504f, 0xbfc88, 0xcb2ff, 0xd7450, 0xe411f, 0xf1a1c -}; - -/* clang-format on */ - -static Sint32 -envelope(Apu *c, Uint32 age) -{ - if(!c->r) return 0x0888; - if(age < c->a) return 0x0888 * age / c->a; - if(age < c->d) return 0x0444 * (2 * c->d - c->a - age) / (c->d - c->a); - if(age < c->s) return 0x0444; - if(age < c->r) return 0x0444 * (c->r - age) / (c->r - c->s); - c->advance = 0; - return 0x0000; -} - -int -apu_render(Apu *c, Sint16 *sample, Sint16 *end) -{ - Sint32 s; - if(!c->advance || !c->period) return 0; - while(sample < end) { - c->count += c->advance; - c->i += c->count / c->period; - c->count %= c->period; - if(c->i >= c->len) { - if(!c->repeat) { - c->advance = 0; - break; - } - c->i %= c->len; - } - s = (Sint8)(c->addr[c->i] + 0x80) * envelope(c, c->age++); - *sample++ += s * c->volume[0] / 0x180; - *sample++ += s * c->volume[1] / 0x180; - } - if(!c->advance) apu_finished_handler(c); - return 1; -} - -void -apu_start(Apu *c, Uint16 adsr, Uint8 pitch) -{ - if(pitch < 108 && c->len) - c->advance = advances[pitch % 12] >> (8 - pitch / 12); - else { - c->advance = 0; - return; - } - c->a = ADSR_STEP * (adsr >> 12); - c->d = ADSR_STEP * (adsr >> 8 & 0xf) + c->a; - c->s = ADSR_STEP * (adsr >> 4 & 0xf) + c->d; - c->r = ADSR_STEP * (adsr >> 0 & 0xf) + c->s; - c->age = 0; - c->i = 0; - if(c->len <= 0x100) /* single cycle mode */ - c->period = NOTE_PERIOD * 337 / 2 / c->len; - else /* sample repeat mode */ - c->period = NOTE_PERIOD; -} - -Uint8 -apu_get_vu(Apu *c) -{ - int i; - Sint32 sum[2] = {0, 0}; - if(!c->advance || !c->period) return 0; - for(i = 0; i < 2; ++i) { - if(!c->volume[i]) continue; - sum[i] = 1 + envelope(c, c->age) * c->volume[i] / 0x800; - if(sum[i] > 0xf) sum[i] = 0xf; - } - return (sum[0] << 4) | sum[1]; -} diff --git a/src/devices/mouse.c b/src/devices/mouse.c new file mode 100644 index 0000000..d96a367 --- /dev/null +++ b/src/devices/mouse.c @@ -0,0 +1,46 @@ +#include "../uxn.h" +#include "mouse.h" + +/* +Copyright (c) 2021 Devine Lu Linvega +Copyright (c) 2021 Andrew Alderwick + +Permission to use, copy, modify, and distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE. +*/ + +void +mouse_down(Device *d, Uint8 mask) +{ + d->dat[6] |= mask; + uxn_eval(d->u, GETVECTOR(d)); +} + +void +mouse_up(Device *d, Uint8 mask) +{ + d->dat[6] &= (~mask); + uxn_eval(d->u, GETVECTOR(d)); +} + +void +mouse_pos(Device *d, Uint16 x, Uint16 y) +{ + DEVPOKE16(0x2, x); + DEVPOKE16(0x4, y); + uxn_eval(d->u, GETVECTOR(d)); +} + +void +mouse_scroll(Device *d, Uint16 x, Uint16 y) +{ + DEVPOKE16(0xa, x); + DEVPOKE16(0xc, -y); + uxn_eval(d->u, GETVECTOR(d)); + DEVPOKE16(0xa, 0); + DEVPOKE16(0xc, 0); +} diff --git a/src/devices/apu.h b/src/devices/mouse.h similarity index 51% rename from src/devices/apu.h rename to src/devices/mouse.h index 019e6e1..c9e133f 100644 --- a/src/devices/apu.h +++ b/src/devices/mouse.h @@ -10,19 +10,7 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE. */ -typedef signed int Sint32; - -#define SAMPLE_FREQUENCY 44100 - -typedef struct { - Uint8 *addr; - Uint32 count, advance, period, age, a, d, s, r; - Uint16 i, len; - Sint8 volume[2]; - Uint8 pitch, repeat; -} Apu; - -int apu_render(Apu *c, Sint16 *sample, Sint16 *end); -void apu_start(Apu *c, Uint16 adsr, Uint8 pitch); -Uint8 apu_get_vu(Apu *c); -void apu_finished_handler(Apu *c); +void mouse_down(Device *d, Uint8 mask); +void mouse_up(Device *d, Uint8 mask); +void mouse_pos(Device *d, Uint16 x, Uint16 y); +void mouse_scroll(Device *d, Uint16 x, Uint16 y); diff --git a/src/uxn11.c b/src/uxn11.c index b02f2ac..c2b1ebb 100644 --- a/src/uxn11.c +++ b/src/uxn11.c @@ -13,8 +13,10 @@ #include "devices/system.h" #include "devices/screen.h" #include "devices/controller.h" +#include "devices/mouse.h" +#include "devices/datetime.h" -static Device *devctrl; +static Device *devscreen, *devctrl, *devmouse; static int error(char *msg, const char *err) @@ -79,6 +81,8 @@ redraw(Display *display, Visual *visual, Window window) /* /usr/include/X11/keysymdef.h */ +#define XK_Escape 0xff1b + #define XK_Left 0xff51 #define XK_Up 0xff52 #define XK_Right 0xff53 @@ -100,6 +104,7 @@ processEvent(Display *display, Visual *visual, Window window) break; case KeyPress: { XKeyPressedEvent *e = (XKeyPressedEvent *)&ev; + if(e->keycode == XKeysymToKeycode(display, XK_Escape)) exit(0); if(e->keycode == XKeysymToKeycode(display, XK_Up)) controller_down(devctrl, 0x10); if(e->keycode == XKeysymToKeycode(display, XK_Down)) controller_down(devctrl, 0x20); if(e->keycode == XKeysymToKeycode(display, XK_Left)) controller_down(devctrl, 0x40); @@ -120,8 +125,19 @@ processEvent(Display *display, Visual *visual, Window window) if(e->keycode == XKeysymToKeycode(display, XK_Shift)) controller_up(devctrl, 0x04); if(e->keycode == XKeysymToKeycode(display, XK_Home)) controller_up(devctrl, 0x08); } break; - case ButtonPress: - exit(0); + case ButtonPress: { + XButtonPressedEvent *e = (XButtonPressedEvent *)&ev; + mouse_down(devmouse, e->button); + } break; + case ButtonRelease: { + XButtonPressedEvent *e = (XButtonPressedEvent *)&ev; + mouse_up(devmouse, e->button); + } break; + + case MotionNotify: { + XMotionEvent *e = (XMotionEvent *)&ev; + mouse_pos(devmouse, e->x, e->y); + } break; } if(uxn_screen.fg.changed || uxn_screen.bg.changed) { redraw(display, visual, window); @@ -135,17 +151,17 @@ start(Uxn *u) return error("Boot", "Failed"); /* system */ uxn_port(u, 0x0, system_dei, system_deo); /* console */ uxn_port(u, 0x1, nil_dei, console_deo); - /* screen */ uxn_port(u, 0x2, screen_dei, screen_deo); + /* screen */ devscreen = uxn_port(u, 0x2, screen_dei, screen_deo); /* empty */ uxn_port(u, 0x3, nil_dei, nil_deo); /* empty */ uxn_port(u, 0x4, nil_dei, nil_deo); /* empty */ uxn_port(u, 0x5, nil_dei, nil_deo); /* empty */ uxn_port(u, 0x6, nil_dei, nil_deo); /* empty */ uxn_port(u, 0x7, nil_dei, nil_deo); /* control */ devctrl = uxn_port(u, 0x8, nil_dei, nil_deo); - /* empty */ uxn_port(u, 0x9, nil_dei, nil_deo); + /* mouse */ devmouse = uxn_port(u, 0x9, nil_dei, nil_deo); /* file */ uxn_port(u, 0xa, nil_dei, nil_deo); /* datetime */ uxn_port(u, 0xb, nil_dei, nil_deo); - /* empty */ uxn_port(u, 0xc, nil_dei, nil_deo); + /* empty */ uxn_port(u, 0xc, datetime_dei, nil_deo); /* empty */ uxn_port(u, 0xd, nil_dei, nil_deo); /* empty */ uxn_port(u, 0xe, nil_dei, nil_deo); /* empty */ uxn_port(u, 0xf, nil_dei, nil_deo); @@ -177,10 +193,12 @@ main(int argc, char **argv) exit(1); } - XSelectInput(display, window, ButtonPressMask | ExposureMask | KeyPressMask | KeyReleaseMask); + XSelectInput(display, window, ButtonPressMask | ButtonReleaseMask | PointerMotionMask | ExposureMask | KeyPressMask | KeyReleaseMask); XMapWindow(display, window); while(1) { processEvent(display, visual, window); + uxn_eval(&u, GETVECTOR(devscreen)); + /* sleep(0.01); */ } return 0; } \ No newline at end of file