return;
#endif
+ case 'q':
+ if(modkeys & KEY_MOD_CTRL) {
+ app_quit();
+ return;
+ }
+ break;
+
case '\n':
case '\r':
if(modkeys & KEY_MOD_ALT) {
/*
DOS interrupt-based keyboard driver.
-Copyright (C) 2013 John Tsiombikas <nuclear@member.fsf.org>
+Copyright (C) 2013-2023 John Tsiombikas <nuclear@member.fsf.org>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
static void INTERRUPT kbintr();
-static int *buffer;
-static int buffer_size, buf_ridx, buf_widx;
+#define BUFSIZE 64
+static int buffer[BUFSIZE];
+static int buf_ridx, buf_widx;
static int last_key;
static unsigned int num_pressed;
-static unsigned char keystate[256];
+static unsigned char keystate[512];
-#define ADVANCE(x) ((x) = ((x) + 1) % buffer_size)
+#define ADVANCE(x) ((x) = ((x) + 1) & (BUFSIZE - 1))
-int kb_init(int bufsz)
+void kb_init(void)
{
if(DONE_INIT) {
fprintf(stderr, "keyboard driver already initialized!\n");
- return 0;
+ return;
}
- buffer_size = bufsz;
- if(buffer_size && !(buffer = malloc(buffer_size * sizeof *buffer))) {
- fprintf(stderr, "failed to allocate input buffer, continuing without\n");
- buffer_size = 0;
- }
buf_ridx = buf_widx = 0;
last_key = -1;
_go32_dpmi_set_protected_mode_interrupt_vector(KEY_INTR, &intr);
#endif
_enable();
-
- return 0;
}
void kb_shutdown(void)
_go32_dpmi_free_iret_wrapper(&intr);
#endif
_enable();
-
- free(buffer);
}
int kb_isdown(int key)
case KEY_CTRL:
return keystate[KEY_LCTRL] + keystate[KEY_RCTRL];
+
+ case KEY_SHIFT:
+ return keystate[KEY_LSHIFT] + keystate[KEY_RSHIFT];
}
if(isalpha(key)) {
if(buffer) {
/* go back a place */
if(--buf_ridx < 0) {
- buf_ridx += buffer_size;
+ buf_ridx += BUFSIZE;
}
/* if the write end hasn't caught up with us, go back one place
if(press) {
/* append to buffer */
last_key = c;
- if(buffer_size > 0) {
- buffer[buf_widx] = c;
- ADVANCE(buf_widx);
- /* if the write end overtook the read end, advance the read end
- * too, to discard the oldest keypress from the buffer
- */
- if(buf_widx == buf_ridx) {
- ADVANCE(buf_ridx);
- }
+ buffer[buf_widx] = c;
+ ADVANCE(buf_widx);
+ /* if the write end overtook the read end, advance the read end
+ * too, to discard the oldest keypress from the buffer
+ */
+ if(buf_widx == buf_ridx) {
+ ADVANCE(buf_ridx);
}
}
/*
DOS interrupt-based keyboard driver.
-Copyright (C) 2013 John Tsiombikas <nuclear@member.fsf.org>
+Copyright (C) 2013-2023 John Tsiombikas <nuclear@member.fsf.org>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
extern "C" {
#endif
-int kb_init(int bufsz); /* bufsz can be 0 for no buffered keys */
+void kb_init(void);
void kb_shutdown(void); /* don't forget to call this at the end! */
/* Boolean predicate for testing the current state of a particular key.
int i;
int vmidx;
int mx, my, bnstate, bndiff;
- static int prev_mx, prev_my, prev_bnstate;
+ static int prev_mx = -1, prev_my, prev_bnstate;
#ifdef __DJGPP__
__djgpp_nearptr_enable();
print_cpuid(&cpuid);
}
- kb_init(32);
+ kb_init();
if(!have_mouse()) {
fprintf(stderr, "No mouse detected. Make sure the mouse driver is installed\n");
disp_pending = 1;
app_reshape(win_width, win_height);
- read_mouse(&mx, &my);
+ mx = win_width / 2;
+ my = win_height / 2;
+ set_mouse(mx, my);
for(;;) {
int key;
+ modkeys = 0;
if(kb_isdown(KEY_ALT)) {
modkeys |= KEY_MOD_ALT;
}
if(quit) goto break_evloop;
}
- draw_cursor(mx, my);
-
bnstate = read_mouse(&mx, &my);
bndiff = bnstate ^ prev_bnstate;
prev_bnstate = bnstate;
+ if(bndiff) {
+ dbgmsg("bndiff: %04x\n", bndiff);
+ }
+
if(bndiff & 1) app_mouse(0, bnstate & 1, mx, my);
if(bndiff & 2) app_mouse(1, bnstate & 2, mx, my);
if(bndiff & 4) app_mouse(3, bnstate & 4, mx, my);
+ if(prev_my == -1) {
+ prev_mx = mx;
+ prev_my = my;
+ } else {
+ draw_cursor(prev_mx, prev_my);
+ }
+ if((mx ^ prev_mx) | (my ^ prev_my)) {
+ app_motion(mx, my);
+ }
+
if(disp_pending) {
disp_pending = 0;
app_display();
}
draw_cursor(mx, my);
+ prev_mx = mx;
+ prev_my = my;
app_swap_buffers();
}
static void draw_grid(void);
static void tbn_callback(rtk_widget *w, void *cls);
+static void act_settool(int tidx);
+static void act_addobj(void);
+static void act_rmobj(void);
+
static void draw_rband(void);
static void primray(cgm_ray *ray, int x, int y);
static void moveobj(struct object *obj, int px0, int py0, int px1, int py1);
app_redisplay();
return;
}
+
+ if(press) {
+ switch(key) {
+ case 27:
+ act_settool(TOOL_SEL);
+ break;
+ case 'g':
+ act_settool(TOOL_MOVE);
+ break;
+ case 'r':
+ act_settool(TOOL_ROT);
+ break;
+ case 's':
+ act_settool(TOOL_SCALE);
+ break;
+
+ case KEY_DEL:
+ act_rmobj();
+ break;
+
+ default:
+ break;
+ }
+ }
}
static int vpdrag;
static void tbn_callback(rtk_widget *w, void *cls)
{
- int i, id = (intptr_t)cls;
+ int id = (intptr_t)cls;
int idx;
switch(id) {
case TBN_DIFF:
idx = id - TBN_UNION + TOOL_UNION;
}
- cur_tool = idx;
- for(i=0; i<NUM_TOOLS; i++) {
- if(i != cur_tool) {
- rtk_set_value(tools[i], 0);
- }
- }
+ act_settool(idx);
break;
case TBN_ADD:
- idx = scn_num_objects(scn);
- add_sphere();
- selobj = idx;
+ act_addobj();
break;
case TBN_RM:
- if(selobj >= 0) {
- scn_rm_object(scn, selobj);
- selobj = -1;
- app_redisplay();
- }
+ act_rmobj();
break;
default:
}
}
+static void act_settool(int tidx)
+{
+ int i;
+ cur_tool = tidx;
+ for(i=0; i<NUM_TOOLS; i++) {
+ if(i == cur_tool) {
+ rtk_set_value(tools[i], 1);
+ } else {
+ rtk_set_value(tools[i], 0);
+ }
+ }
+ app_redisplay();
+}
+
+static void act_addobj(void)
+{
+ int idx = scn_num_objects(scn);
+ add_sphere();
+ selobj = idx;
+
+ app_redisplay();
+}
+
+static void act_rmobj(void)
+{
+ if(selobj >= 0) {
+ scn_rm_object(scn, selobj);
+ selobj = -1;
+ app_redisplay();
+ }
+}
+
static void draw_rband(void)
{
int i, x, y, w, h;