#include #include #include #include extern const char *__progname; #include "gl-int.h" #include "sounds.h" static SDL_Surface *s; static int ogl_up = 0; static int ogl_failed = 0; static unsigned int kbdstate; #define KBS_LSHIFT 0x00000001 #define KBS_RSHIFT 0x00000002 #define KBS_SHIFT (KBS_LSHIFT|KBS_RSHIFT) #define KBS_LCTRL 0x00000004 #define KBS_RCTRL 0x00000008 #define KBS_CTRL (KBS_LCTRL|KBS_RCTRL) static int ogl_probe(void) { const SDL_VideoInfo *inf; if (ogl_up) return(1); if (ogl_failed) return(0); ogl_failed = 1; if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO) < 0) { fprintf(stderr,"%s: SDL_Init: %s\n",__progname,SDL_GetError()); return(0); } inf = SDL_GetVideoInfo(); if (! inf) { fprintf(stderr,"%s: SDL_GetVideoInfo: %s\n",__progname,SDL_GetError()); SDL_Quit(); return(0); } XMAXSCREEN = NOMINAL_XSIZE; YMAXSCREEN = NOMINAL_YSIZE; SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,1); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE,1); s = SDL_SetVideoMode(XMAXSCREEN,YMAXSCREEN,8,SDL_OPENGL|SDL_FULLSCREEN|SDL_GL_DOUBLEBUFFER|(inf->hw_available?SDL_HWSURFACE:SDL_SWSURFACE)); if (! s) { fprintf(stderr,"%s: SDL_SetVideoMode: %s\n",__progname,SDL_GetError()); SDL_Quit(); return(0); } SDL_ShowCursor(SDL_DISABLE); PIXELSCALE = 1; glShadeModel(GL_FLAT); glClearColor(0,0,0,0); glViewport(0,0,XMAXSCREEN,YMAXSCREEN); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0,XMAXSCREEN,YMAXSCREEN,0,-1,1); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); ogl_failed = 0; ogl_up = 1; return(1); } static void ogl_shutdown(void) { if (ogl_up) { SDL_Quit(); ogl_up = 0; } } static void keystroke(char updn, unsigned int keycode) { printf("%d %c\n",keycode,updn); if (TSTBIT(devqueued,KEYBD)) { unsigned int c; #define TYPE 0xf0000000 #define CHARS 0x00000000 #define NOTHING 0x10000000 #define FLAG 0x20000000 #define C3(a,b,c) (CHARS+(((c)&0x1ff)<<18)+(((b)&0x1ff)<<9)+((a)&0x1ff)) #define C3a(x) (((x) )&0x1ff) #define C3b(x) (((x)>> 9)&0x1ff) #define C3c(x) (((x)>>18)&0x1ff) #define NIL 0x100 #define STD 0x101 #define FLG(x) (FLAG|(x)) c = NOTHING; switch (keycode) { case SDLK_ESCAPE: c = C3('\33',NIL,NIL); break; case SDLK_1: c = C3('1','!',NIL); break; case SDLK_2: c = C3('2','@','\0'); break; case SDLK_3: c = C3('3','#',NIL); break; case SDLK_4: c = C3('4','$',NIL); break; case SDLK_5: c = C3('5','%',NIL); break; case SDLK_6: c = C3('6','^',NIL); break; case SDLK_7: c = C3('7','&',NIL); break; case SDLK_8: c = C3('8','*',NIL); break; case SDLK_9: c = C3('9','(',NIL); break; case SDLK_0: c = C3('0',')',NIL); break; case SDLK_MINUS: c = C3('-','_','\37'); break; case SDLK_EQUALS: c = C3('=','+',NIL); break; case SDLK_BACKQUOTE: c = C3('`','~','\36'); break; case SDLK_BACKSPACE: c = C3('\b',NIL,NIL); break; case SDLK_TAB: c = C3('\t',NIL,NIL); break; case SDLK_q: c = C3('q',STD,STD); break; case SDLK_w: c = C3('w',STD,STD); break; case SDLK_e: c = C3('e',STD,STD); break; case SDLK_r: c = C3('r',STD,STD); break; case SDLK_t: c = C3('t',STD,STD); break; case SDLK_y: c = C3('y',STD,STD); break; case SDLK_u: c = C3('u',STD,STD); break; case SDLK_i: c = C3('i',STD,STD); break; case SDLK_o: c = C3('o',STD,STD); break; case SDLK_p: c = C3('p',STD,STD); break; case SDLK_LEFTBRACKET: c = C3('[','{',STD); break; case SDLK_RIGHTBRACKET: c = C3(']','}',STD); break; case SDLK_DELETE: c = C3('\177',NIL,NIL); break; case SDLK_LCTRL: c = FLG(KBS_LCTRL); break; case SDLK_RCTRL: c = FLG(KBS_RCTRL); break; case SDLK_a: c = C3('a',STD,STD); break; case SDLK_s: c = C3('s',STD,STD); break; case SDLK_d: c = C3('d',STD,STD); break; case SDLK_f: c = C3('f',STD,STD); break; case SDLK_g: c = C3('g',STD,STD); break; case SDLK_h: c = C3('h',STD,STD); break; case SDLK_j: c = C3('j',STD,STD); break; case SDLK_k: c = C3('k',STD,STD); break; case SDLK_l: c = C3('l',STD,STD); break; case SDLK_SEMICOLON: c = C3(';',':',NIL); break; case SDLK_QUOTE: c = C3('\'','"',NIL); break; case SDLK_BACKSLASH: c = C3('\\','|',STD); break; case SDLK_RETURN: c = C3('\r',NIL,NIL); break; case SDLK_LSHIFT: c = FLG(KBS_LSHIFT); break; case SDLK_z: c = C3('z',STD,STD); break; case SDLK_x: c = C3('x',STD,STD); break; case SDLK_c: c = C3('c',STD,STD); break; case SDLK_v: c = C3('v',STD,STD); break; case SDLK_b: c = C3('b',STD,STD); break; case SDLK_n: c = C3('n',STD,STD); break; case SDLK_m: c = C3('m',STD,STD); break; case SDLK_COMMA: c = C3(',','<',NIL); break; case SDLK_PERIOD: c = C3('.','>',NIL); break; case SDLK_SLASH: c = C3('/','?','\37'); break; case SDLK_RSHIFT: c = FLG(KBS_RSHIFT); break; case SDLK_SPACE: c = C3(' ',NIL,NIL); break; } switch (c & TYPE) { case CHARS: if (updn == 'd') { if ((kbdstate & KBS_CTRL) & (C3c(c) != NIL)) { if (C3c(c) == STD) { makeqentry(KEYBD,C3a(c)&0x1f); } else { makeqentry(KEYBD,C3c(c)); } } else if ((kbdstate & KBS_SHIFT) & (C3b(c) != NIL)) { if (C3b(c) == STD) { makeqentry(KEYBD,C3a(c)^0x20); } else { makeqentry(KEYBD,C3b(c)); } } else { makeqentry(KEYBD,C3a(c)); } } break; case NOTHING: break; case FLAG: switch (updn) { case 'u': kbdstate &= ~(c & ~TYPE); break; case 'd': kbdstate |= (c & ~TYPE); break; } break; } #undef TYPE #undef CHARS #undef NOTHING #undef FLAG #undef C3 #undef C3a #undef C3b #undef C3c #undef NIL #undef STD #undef FLG } { int bit; bit = -1; switch (keycode) { case SDLK_F9: bit = F9KEY; break; case SDLK_RCTRL: bit = RIGHTCTRLKEY; break; case SDLK_ESCAPE: bit = ESCKEY; break; case SDLK_1: bit = ONEKEY; break; case SDLK_2: bit = TWOKEY; break; case SDLK_3: bit = THREEKEY; break; case SDLK_4: bit = FOURKEY; break; case SDLK_5: bit = FIVEKEY; break; case SDLK_6: bit = SIXKEY; break; case SDLK_7: bit = SEVENKEY; break; case SDLK_8: bit = EIGHTKEY; break; case SDLK_9: bit = NINEKEY; break; case SDLK_0: bit = ZEROKEY; break; case SDLK_UP: bit = R8KEY; break; case SDLK_h: bit = HKEY; break; case SDLK_LEFT: bit = R10KEY; break; case SDLK_RIGHT: bit = R12KEY; break; case SDLK_BACKQUOTE: bit = L10KEY; break; case SDLK_LCTRL: bit = LEFTCTRLKEY; break; case SDLK_LALT: bit = LEFTALTKEY; break; case SDLK_LSUPER: bit = LEFTALTKEY; break; case SDLK_SPACE: bit = SPACEKEY; break; case SDLK_RALT: bit = RIGHTALTKEY; break; case SDLK_MENU: bit = RIGHTALTKEY; break; case SDLK_RSUPER: bit = RIGHTALTKEY; break; } if ((bit >= 0) && TSTBIT(devqueued,bit)) { makeqentry(bit,updn=='d'); } } } static void presel( fd_set *rfds __attribute__((__unused__)), fd_set *wfds __attribute__((__unused__)), fd_set *xfds __attribute__((__unused__)), struct timeval *now __attribute__((__unused__)), struct timeval *delay ) { SDL_Event ev; int any; any = 0; while (SDL_PollEvent(&ev)) { any = 1; switch (ev.type) { case SDL_QUIT: ogl_shutdown(); exit(0); break; case SDL_KEYDOWN: keystroke('d',ev.key.keysym.sym); break; case SDL_KEYUP: keystroke('u',ev.key.keysym.sym); break; } } if (any) { delay->tv_sec = 0; delay->tv_usec = 0; } } static int oglo_probe(const char *path __attribute__((__unused__))) { return(ogl_probe()); } static int oglo_setup(const char *path __attribute__((__unused__))) { return(ogl_probe()); } static void oglo_shutdown(void) { ogl_shutdown(); } static void oglo_clear(void) { glClear(GL_COLOR_BUFFER_BIT); glColor3f(1,1,1); } static void oglo_swap(void) { SDL_GL_SwapBuffers(); glFinish(); } static void oglo_line(float a, float b, float c, float d) { glBegin(GL_LINES); glVertex2f(a,b); glVertex2f(c,d); glEnd(); } static void oglo_point(float x, float y) { glBegin(GL_POINTS); glVertex2f(x,y); glEnd(); } static int ogli_probe(const char *path __attribute__((__unused__))) { if (! ogl_probe()) return(0); kbdstate = 0; TICKS_PER_SEC = 50; register_setselect(&presel); return(1); } static int ogli_setup(const char *path __attribute__((__unused__))) { return(ogli_probe(0)); } static void ogli_shutdown(void) { ogl_shutdown(); } static const char *ogli_keyname(int key __attribute__((__unused__))) { return(""); } IDEV idev_opengl = { "opengl", "OpenGL", ogli_probe, ogli_setup, ogli_shutdown, ogli_keyname }; ODEV odev_opengl = { "opengl", "OpenGL display", &oglo_probe, &oglo_setup, &oglo_shutdown, &oglo_clear, &oglo_swap, 0, 0, &oglo_line, &oglo_point }; #if 0 #include typedef struct snd SND; struct snd { SND *link; int id; const signed short int *data; unsigned int len; unsigned int ptr; unsigned int repeat : 1; } ; static SND *playing = 0; static SND *freelist = 0; static int paused = 0; static char repeating[SOUND__N]; static SND *getsnd(int id) { SND *s; if (freelist) { s = freelist; freelist = s->link; } else { s = malloc(sizeof(SND)); } s->id = id; s->data = sound_dat(id); s->len = sound_len(id); s->ptr = 0; return(s); } static void freesnd(SND *s) { s->link = freelist; freelist = s; } static void sound_cb(void *cookie __attribute__((__unused__)), Uint8 *data, int bytes) { int t; SND *s; SND **sp; signed short int v; printf("%d\n",bytes); while (bytes > 1) { t = 0; for (sp=&playing;(s=*sp);) { if (s->repeat) { if (repeating[s->id]) { v = s->data[s->ptr++]; if (s->ptr >= s->len) s->ptr = 0; sp = &s->link; } else { *sp = s->link; freesnd(s); } } else { v = s->data[s->ptr++]; if (s->ptr >= s->len) { *sp = s->link; freesnd(s); } else { sp = &s->link; } } t += v; } t += 32768; if (t < 0) t = 0; else if (t > 65535) t = 65535; t ^= 32768; data[0] = t >> 8; data[1] = t & 0xff; data += 2; bytes -= 2; } } void sound_start(const char *x __attribute__((__unused__))) { SDL_AudioSpec as; if (! ogl_probe()) return; as.freq = 8000; as.format = AUDIO_S16MSB; as.channels = 1; as.samples = 128; as.callback = &sound_cb; as.userdata = 0; /* silence and size are not documented and are not set by the webpage example, even though the SDL_AudioSpec webpage says all fields are used by SDL_OpenAudio. */ if (SDL_OpenAudio(&as,0) < 0) { fprintf(stderr,"%s: SDL_OpenAudio: %s\n",__progname,SDL_GetError()); exit(1); } bzero(&repeating[0],sizeof(repeating)); SDL_PauseAudio(0); } void sound_once(int id) { SND *s; s = getsnd(id); s->repeat = 0; s->link = playing; playing = s; } void sound_repeat(int id, int play) { SND *s; if ((play && repeating[id]) || (!play && !repeating[id])) return; repeating[id] = play ? 1 : 0; if (play) { s = getsnd(id); s->repeat = 1; s->link = playing; playing = s; } } void sound_pause(int stop) { SDL_PauseAudio(stop?1:0); } #else void sound_start(const char *x __attribute__((__unused__))) { } void sound_once(int id __attribute__((__unused__))) { } void sound_repeat(int id __attribute__((__unused__)), int play __attribute__((__unused__))) { } void sound_pause(int stop __attribute__((__unused__))) { } #endif