summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Makefile23
-rw-r--r--app.cpp300
-rw-r--r--app.hpp123
-rw-r--r--c2.cpp16
-rw-r--r--debug_env2
-rw-r--r--todo.txt2
7 files changed, 465 insertions, 2 deletions
diff --git a/.gitignore b/.gitignore
index 6e6f69f..337b226 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,3 +6,4 @@ tags
/cfg/libcfg.a
/qstd/libqstd.a
/sc/sc
+/c2
diff --git a/Makefile b/Makefile
index e506470..b9f2151 100644
--- a/Makefile
+++ b/Makefile
@@ -1,11 +1,18 @@
.POSIX:
+target = c2
data_dir = data
shaders = data/triangle.csh
tools = qstd cfg sc
+objects = app.o c2.o
+includes = -Iqstd
+defines = -Dplat_x86 -Dplat_posix -Dplat_x11 -Dallocation_default_alignment=8
+cflags = $(includes) $(defines) $(DEBUG_COMPILE_FLAG)
+libs = -lX11 -lm
+lflags = $(libs) $(DEBUG_LINK_FLAG)
.PHONY: all clean $(tools)
-all: $(shaders) $(tools)
+all: $(target) $(shaders) $(tools) $(objects)
qstd:
$(MAKE) -C qstd
@@ -19,11 +26,25 @@ sc: qstd cfg
data/triangle.csh: intermediate/triangle.glsl | $(data_dir) sc
./sc/sc intermediate/triangle.glsl data/triangle.csh
+app.o: app.cpp app.hpp
+ $(CXX) -c $(cflags) app.cpp -o app.o
+
+c2.o: c2.cpp app.hpp
+ $(CXX) -c $(cflags) c2.cpp -o c2.o
+
+$(target): $(objects) qstd/libqstd.a
+ $(CXX) $(objects) $(lflags) -o $(target) -Lqstd -lqstd
+
+qstd/libqstd.a:
+ $(MAKE) -C qstd
+
$(data_dir):
mkdir -p $(data_dir)
clean:
rm -rf $(data_dir)
+ rm -f $(objects)
+ rm -f $(targets)
make -C qstd clean
make -C cfg clean
make -C sc clean
diff --git a/app.cpp b/app.cpp
new file mode 100644
index 0000000..9c6c458
--- /dev/null
+++ b/app.cpp
@@ -0,0 +1,300 @@
+#include "app.hpp"
+
+extern "C" {
+#include "memory.h"
+}
+
+#ifdef plat_x11
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+
+#include <stdlib.h>
+
+Key key_from_xkey(unsigned key) {
+ switch (key) {
+ case 0x61: return key_A;
+ case 0x62: return key_B;
+ case 0x63: return key_C;
+ case 0x64: return key_D;
+ case 0x65: return key_E;
+ case 0x66: return key_F;
+ case 0x67: return key_G;
+ case 0x68: return key_H;
+ case 0x69: return key_I;
+ case 0x6A: return key_J;
+ case 0x6B: return key_K;
+ case 0x6C: return key_L;
+ case 0x6D: return key_M;
+ case 0x6E: return key_N;
+ case 0x6F: return key_O;
+ case 0x70: return key_P;
+ case 0x71: return key_Q;
+ case 0x72: return key_R;
+ case 0x73: return key_S;
+ case 0x74: return key_T;
+ case 0x75: return key_U;
+ case 0x76: return key_V;
+ case 0x77: return key_W;
+ case 0x78: return key_X;
+ case 0x79: return key_Y;
+ case 0x7A: return key_Z;
+ case XK_F1: return key_f1;
+ case XK_F2: return key_f2;
+ case XK_F3: return key_f3;
+ case XK_F4: return key_f4;
+ case XK_F5: return key_f5;
+ case XK_F6: return key_f6;
+ case XK_F7: return key_f7;
+ case XK_F8: return key_f8;
+ case XK_F9: return key_f9;
+ case XK_F10: return key_f10;
+ case XK_F11: return key_f11;
+ case XK_F12: return key_f12;
+ case XK_Down: return key_down;
+ case XK_Left: return key_left;
+ case XK_Right: return key_right;
+ case XK_Up: return key_up;
+ case XK_Escape: return key_escape;
+ case XK_Return: return key_return;
+ case XK_BackSpace: return key_backspace;
+ case XK_Linefeed: return key_return;
+ case XK_Tab: return key_tab;
+ case XK_Delete: return key_delete;
+ case XK_Home: return key_home;
+ case XK_End: return key_end;
+ case XK_Page_Up: return key_page_up;
+ case XK_Page_Down: return key_page_down;
+ case XK_Insert: return key_insert;
+ case XK_Shift_L: return key_shift;
+ case XK_Shift_R: return key_shift;
+ case XK_Control_L: return key_control;
+ case XK_Control_R: return key_control;
+ case XK_Super_L: return key_super;
+ case XK_Super_R: return key_super;
+ case XK_Alt_L: return key_alt;
+ case XK_Alt_R: return key_alt;
+ case XK_space: return key_space;
+ case XK_period: return key_period;
+ case XK_0: return key_0;
+ case XK_1: return key_1;
+ case XK_2: return key_2;
+ case XK_3: return key_3;
+ case XK_4: return key_4;
+ case XK_5: return key_5;
+ case XK_6: return key_6;
+ case XK_7: return key_7;
+ case XK_8: return key_8;
+ case XK_9: return key_9;
+ default: return key_unknown;
+ }
+}
+
+struct App_Internal {
+ Display* d;
+ Window wi;
+ Atom wm_delete;
+
+ void init(App* app, const char* name) {
+ const int default_w = 1920;
+ const int default_h = 1080;
+ XWindowAttributes wa;
+ XSetWindowAttributes attribs = {
+ .event_mask =
+ ExposureMask |
+ KeyPressMask |
+ KeyReleaseMask |
+ ButtonPressMask |
+ ButtonReleaseMask |
+ PointerMotionMask
+ };
+ Window root;
+ Visual* v;
+ d = XOpenDisplay(0);
+ wm_delete = XInternAtom(
+ d,
+ "WM_DELETE_WINDOW",
+ 0
+ );
+ root = DefaultRootWindow(d);
+ v = XDefaultVisual(d, 0);
+ wi = XCreateWindow(
+ d,
+ root,
+ 0,
+ 0,
+ default_w,
+ default_h,
+ 0,
+ 0,
+ InputOutput,
+ v,
+ CWEventMask,
+ &attribs
+ );
+ XSetWMProtocols(d, wi, &wm_delete, 1);
+ XStoreName(d, wi, name);
+ XMapRaised(d, wi);
+ XGetWindowAttributes(d, wi, &wa);
+ app->w = wa.width;
+ app->h = wa.height;
+ }
+
+ void begin(App* app) {
+ while (XPending(d)) {
+ XEvent e;
+ KeySym sym;
+ Key key;
+ int btn;
+ XNextEvent(d, &e);
+ switch (e.type) {
+ case ClientMessage:
+ if (
+ (Atom)e.xclient.data.l[0] ==
+ wm_delete
+ ) {
+ app->running = 0;
+ }
+ break;
+ case MotionNotify:
+ app->mx = e.xmotion.x;
+ app->my = e.xmotion.y;
+ break;
+ case ButtonPress:
+ switch (e.xbutton.button) {
+ case 1:
+ case 2:
+ case 3:
+ app->mbtn_states[e.xbutton.button - 1] |=
+ key_state_pressed |
+ key_state_just_pressed;
+ break;
+ case 4:
+ app->scrolly++;
+ break;
+ case 5:
+ app->scrolly--;
+ break;
+ case 6:
+ app->scrollx++;
+ break;
+ case 7:
+ app->scrollx--;
+ break;
+ }
+ break;
+ case ButtonRelease:
+ switch (e.xbutton.button) {
+ case 1:
+ case 2:
+ case 3:
+ btn = e.xbutton.button - 1;
+ app->mbtn_states[btn] &= ~key_state_pressed;
+ app->mbtn_states[btn] |= key_state_just_released;
+ break;
+ case 4:
+ app->scrolly++;
+ break;
+ case 5:
+ app->scrolly--;
+ break;
+ case 6:
+ app->scrollx++;
+ break;
+ case 7:
+ app->scrollx--;
+ break;
+ }
+ break;
+ case KeyPress:
+ sym = XLookupKeysym(&e.xkey, 0);
+ key = key_from_xkey(sym);
+ app->key_states[key] |=
+ key_state_pressed |
+ key_state_just_pressed;
+ break;
+ case KeyRelease:
+ sym = XLookupKeysym(&e.xkey, 0);
+ key = key_from_xkey(sym);
+ app->key_states[key] &= ~key_state_pressed;
+ app->key_states[key] |= key_state_just_released;
+ break;
+ }
+ }
+ }
+
+ void end(App* app) {
+ (void)app;
+ }
+};
+
+#endif
+
+App* App::create(const char* name) {
+ App* app;
+ App_Internal* i;
+ char* mem = (char*)malloc(app_memory_size);
+ Arena* a = (Arena*)mem;
+ mem += sizeof *a;
+ init_arena(a, mem, app_memory_size - sizeof *a);
+ app = (App*)arena_alloc(a, sizeof *app + sizeof *i);
+ app->running = 0;
+ app->arena = a;
+ i = (App_Internal*)&app[1];
+ i->init(app, name);
+ return app;
+}
+
+void App::destroy() {
+ free(arena);
+}
+
+void App::begin() {
+ int j;
+ App_Internal* i = (App_Internal*)&this[1];
+ for (j = 0; j < key_count; j++)
+ key_states[j] &= ~(
+ key_state_just_pressed | key_state_just_released
+ );
+ for (j = 0; j < mbtn_count; j++)
+ mbtn_states[j] &= ~(
+ key_state_just_pressed | key_state_just_released
+ );
+ i->begin(this);
+}
+
+void App::end() {
+ App_Internal* i = (App_Internal*)&this[1];
+ i->end(this);
+}
+
+Key_State App::ks(Key k) {
+ return (Key_State)key_states[k];
+}
+
+Key_State App::ms(Mbtn k) {
+ return (Key_State)mbtn_states[k];
+}
+
+bool App::kp(Key k) {
+ return key_states[k] & key_state_pressed;
+}
+
+bool App::kjp(Key k) {
+ return key_states[k] & key_state_just_pressed;
+}
+
+bool App::kjr(Key k) {
+ return key_states[k] & key_state_just_released;
+}
+
+bool App::mp(Mbtn b) {
+ return mbtn_states[b] & key_state_pressed;
+}
+
+bool App::mjp(Mbtn b) {
+ return mbtn_states[b] & key_state_just_pressed;
+}
+
+bool App::mjr(Mbtn b) {
+ return mbtn_states[b] & key_state_just_released;
+}
diff --git a/app.hpp b/app.hpp
new file mode 100644
index 0000000..80d6cb0
--- /dev/null
+++ b/app.hpp
@@ -0,0 +1,123 @@
+#ifndef app_hpp
+#define app_hpp
+
+#define app_memory_size (4096 * 16)
+
+struct Arena;
+
+#define key_xmacro() \
+ x(key_unknown) \
+ x(key_A) \
+ x(key_B) \
+ x(key_C) \
+ x(key_D) \
+ x(key_E) \
+ x(key_F) \
+ x(key_G) \
+ x(key_H) \
+ x(key_I) \
+ x(key_J) \
+ x(key_K) \
+ x(key_L) \
+ x(key_M) \
+ x(key_N) \
+ x(key_O) \
+ x(key_P) \
+ x(key_Q) \
+ x(key_R) \
+ x(key_S) \
+ x(key_T) \
+ x(key_U) \
+ x(key_V) \
+ x(key_W) \
+ x(key_X) \
+ x(key_Y) \
+ x(key_Z) \
+ x(key_f1) \
+ x(key_f2) \
+ x(key_f3) \
+ x(key_f4) \
+ x(key_f5) \
+ x(key_f6) \
+ x(key_f7) \
+ x(key_f8) \
+ x(key_f9) \
+ x(key_f10) \
+ x(key_f11) \
+ x(key_f12) \
+ x(key_down) \
+ x(key_left) \
+ x(key_right) \
+ x(key_up) \
+ x(key_escape) \
+ x(key_return) \
+ x(key_backspace) \
+ x(key_tab) \
+ x(key_delete) \
+ x(key_home) \
+ x(key_end) \
+ x(key_page_up) \
+ x(key_page_down) \
+ x(key_insert) \
+ x(key_shift) \
+ x(key_control) \
+ x(key_super) \
+ x(key_alt) \
+ x(key_space) \
+ x(key_period) \
+ x(key_0) \
+ x(key_1) \
+ x(key_2) \
+ x(key_3) \
+ x(key_4) \
+ x(key_5) \
+ x(key_6) \
+ x(key_7) \
+ x(key_8) \
+ x(key_9) \
+
+enum Key {
+#define x(name) name,
+ key_xmacro()
+#undef x
+ key_count
+};
+
+enum Mbtn {
+ mbtn_left,
+ mbtn_middle,
+ mbtn_right,
+ mbtn_count
+};
+
+enum Key_State {
+ key_state_pressed = 1 << 0,
+ key_state_just_pressed = 1 << 1,
+ key_state_just_released = 1 << 2
+};
+
+struct App {
+ Arena* arena;
+ int running, w, h;
+ int mx, my;
+ int scrollx, scrolly;
+ unsigned char key_states[key_count];
+ unsigned char mbtn_states[mbtn_count];
+
+ static App* create(const char* name);
+ void destroy();
+
+ void begin();
+ void end();
+
+ Key_State ks(Key k);
+ Key_State ms(Mbtn k);
+ bool kp(Key k);
+ bool kjp(Key k);
+ bool kjr(Key k);
+ bool mp(Mbtn k);
+ bool mjp(Mbtn k);
+ bool mjr(Mbtn k);
+};
+
+#endif
diff --git a/c2.cpp b/c2.cpp
new file mode 100644
index 0000000..f6ad356
--- /dev/null
+++ b/c2.cpp
@@ -0,0 +1,16 @@
+#include "app.hpp"
+extern "C" {
+#include "plat.h"
+}
+
+int main() {
+ App* app = App::create("c2");
+ app->running = 1;
+ while (app->running) {
+ app->begin();
+ if (app->mp(mbtn_left))
+ print("%d, %d, %d\n", app->mx, app->my, app->scrolly);
+ app->end();
+ }
+ app->destroy();
+}
diff --git a/debug_env b/debug_env
new file mode 100644
index 0000000..589d7ba
--- /dev/null
+++ b/debug_env
@@ -0,0 +1,2 @@
+export DEBUG_COMPILE_FLAG="-O0 -g -DDEBUG"
+export DEBUG_LINK_FLAG="-g"
diff --git a/todo.txt b/todo.txt
index d85fe76..bb854a8 100644
--- a/todo.txt
+++ b/todo.txt
@@ -1,6 +1,6 @@
todo list
- [x] shader compiling
- - [ ] windowing + input
+ - [x] windowing + input
- [ ] vulkan device and swapchain, etc
- [ ] draw a triangle
- [ ] texture conversion + compression, etc