// SDL interface layer // for the Build Engine // by Jonathon Fowler (jonof@edgenetwk.com) // // Use SDL1.2 from http://www.libsdl.org #include #include #ifndef __APPLE__ # include "SDL.h" #endif #include "compat.h" #include "sdlayer.h" #include "cache1d.h" #include "pragmas.h" #include "a.h" #include "build.h" #include "osd.h" #ifdef USE_OPENGL # include "glbuild.h" #endif #if defined __APPLE__ # include # include "osxbits.h" #elif defined HAVE_GTK2 # include "gtkbits.h" #else int startwin_open(void) { return 0; } int startwin_close(void) { return 0; } int startwin_puts(const char *s) { s=s; return 0; } int startwin_idle(void *s) { return 0; } int startwin_settitle(const char *s) { s=s; return 0; } #endif #define SURFACE_FLAGS (SDL_SWSURFACE|SDL_HWPALETTE|SDL_HWACCEL) // undefine to restrict windowed resolutions to conventional sizes #define ANY_WINDOWED_SIZE // fix for mousewheel #define MWHEELTICKS 10 static unsigned int mwheelup, mwheeldown; int _buildargc = 1; const char **_buildargv = NULL; extern int app_main(int argc, const char *argv[]); char quitevent=0, appactive=1; // video static SDL_Surface *sdl_surface; int xres=-1, yres=-1, bpp=0, fullscreen=0, bytesperline, imageSize; int frameplace=0, lockcount=0; char modechange=1; char offscreenrendering=0; char videomodereset = 0; char nofog=0; static unsigned short sysgamma[3][256]; extern int curbrightness, gammabrightness; #ifdef USE_OPENGL // OpenGL stuff static char nogl=0; #endif // input char inputdevices=0; char keystatus[256], keyfifo[KEYFIFOSIZ], keyfifoplc, keyfifoend; unsigned char keyasciififo[KEYFIFOSIZ], keyasciififoplc, keyasciififoend; static unsigned char keynames[256][24]; int mousex=0,mousey=0,mouseb=0; int *joyaxis = NULL, joyb=0, *joyhat = NULL; char joyisgamepad=0, joynumaxes=0, joynumbuttons=0, joynumhats=0; int joyaxespresent=0; void(*keypresscallback)(int,int) = 0; void(*mousepresscallback)(int,int) = 0; void(*joypresscallback)(int,int) = 0; static unsigned char keytranslation[SDLK_LAST]; static int buildkeytranslationtable(void); //static SDL_Surface * loadtarga(const char *fn); // for loading the icon static SDL_Surface * loadappicon(void); int wm_msgbox(char *name, char *fmt, ...) { char buf[2048]; va_list va; va_start(va,fmt); vsprintf(buf,fmt,va); va_end(va); #if defined(__APPLE__) return osx_msgbox(name, buf); #elif defined HAVE_GTK2 if (gtkbuild_msgbox(name, buf) >= 0) return 1; #endif puts(buf); puts(" (press Return or Enter to continue)"); getchar(); return 0; } int wm_ynbox(char *name, char *fmt, ...) { char buf[2048]; char c; va_list va; int r; va_start(va,fmt); vsprintf(buf,fmt,va); va_end(va); #if defined __APPLE__ return osx_ynbox(name, buf); #elif defined HAVE_GTK2 if ((r = gtkbuild_ynbox(name, buf)) >= 0) return r; #endif puts(buf); puts(" (type 'Y' or 'N', and press Return or Enter to continue)"); do c = getchar(); while (c != 'Y' && c != 'y' && c != 'N' && c != 'n'); if (c == 'Y' || c == 'y') return 1; return 0; } void wm_setapptitle(char *name) { if (name) { Bstrncpy(apptitle, name, sizeof(apptitle)-1); apptitle[ sizeof(apptitle)-1 ] = 0; } SDL_WM_SetCaption(apptitle, NULL); startwin_settitle(apptitle); } // // // --------------------------------------- // // System // // --------------------------------------- // // int main(int argc, char *argv[]) { int r; buildkeytranslationtable(); #ifdef HAVE_GTK2 gtkbuild_init(&argc, &argv); #endif startwin_open(); _buildargc = argc; _buildargv = (const char**)argv; baselayer_init(); r = app_main(_buildargc, _buildargv); startwin_close(); #ifdef HAVE_GTK2 gtkbuild_exit(r); #endif return r; } // // initsystem() -- init SDL systems // int initsystem(void) { const SDL_VideoInfo *vid; const SDL_version *linked = SDL_Linked_Version(); SDL_version compiled; char drvname[32]; SDL_VERSION(&compiled); initprintf("Initialising SDL system interface " "(compiled with SDL version %d.%d.%d, DLL version %d.%d.%d)\n", linked->major, linked->minor, linked->patch, compiled.major, compiled.minor, compiled.patch); if (SDL_Init(SDL_INIT_VIDEO //| SDL_INIT_TIMER #ifdef NOSDLPARACHUTE | SDL_INIT_NOPARACHUTE #endif )) { initprintf("Initialisation failed! (%s)\n", SDL_GetError()); return -1; } atexit(uninitsystem); frameplace = 0; lockcount = 0; #ifdef USE_OPENGL if (loadgldriver(getenv("BUILD_GLDRV"))) { initprintf("Failed loading OpenGL driver. GL modes will be unavailable.\n"); nogl = 1; } #endif #ifndef __APPLE__ { SDL_Surface *icon; //icon = loadtarga("icon.tga"); icon = loadappicon(); if (icon) { SDL_WM_SetIcon(icon, 0); SDL_FreeSurface(icon); } } #endif if (SDL_VideoDriverName(drvname, 32)) initprintf("Using \"%s\" video driver\n", drvname); // dump a quick summary of the graphics hardware #ifdef DEBUGGINGAIDS vid = SDL_GetVideoInfo(); initprintf("Video device information:\n"); initprintf(" Can create hardware surfaces? %s\n", (vid->hw_available)?"Yes":"No"); initprintf(" Window manager available? %s\n", (vid->wm_available)?"Yes":"No"); initprintf(" Accelerated hardware blits? %s\n", (vid->blit_hw)?"Yes":"No"); initprintf(" Accelerated hardware colourkey blits? %s\n", (vid->blit_hw_CC)?"Yes":"No"); initprintf(" Accelerated hardware alpha blits? %s\n", (vid->blit_hw_A)?"Yes":"No"); initprintf(" Accelerated software blits? %s\n", (vid->blit_sw)?"Yes":"No"); initprintf(" Accelerated software colourkey blits? %s\n", (vid->blit_sw_CC)?"Yes":"No"); initprintf(" Accelerated software alpha blits? %s\n", (vid->blit_sw_A)?"Yes":"No"); initprintf(" Accelerated colour fills? %s\n", (vid->blit_fill)?"Yes":"No"); initprintf(" Total video memory: %dKB\n", vid->video_mem); #endif return 0; } // // uninitsystem() -- uninit SDL systems // void uninitsystem(void) { uninitinput(); uninitmouse(); uninittimer(); SDL_Quit(); #ifdef USE_OPENGL unloadgldriver(); #endif } // // initprintf() -- prints a string to the intitialization window // void initprintf(const char *f, ...) { va_list va; char buf[1024]; va_start(va, f); vprintf(f,va); va_end(va); va_start(va, f); Bvsnprintf(buf, 1024, f, va); va_end(va); OSD_Printf(buf); startwin_puts(buf); startwin_idle(NULL); } // // debugprintf() -- prints a debug string to stderr // void debugprintf(const char *f, ...) { #ifdef DEBUGGINGAIDS va_list va; va_start(va,f); Bvfprintf(stderr, f, va); va_end(va); #endif } // // // --------------------------------------- // // All things Input // // --------------------------------------- // // static char mouseacquired=0,moustat=0; static int joyblast=0; static SDL_Joystick *joydev = NULL; // // initinput() -- init input system // int initinput(void) { int i,j; #ifdef __APPLE__ // force OS X to operate in >1 button mouse mode so that LMB isn't adulterated if (!getenv("SDL_HAS3BUTTONMOUSE")) putenv("SDL_HAS3BUTTONMOUSE=1"); #endif if (SDL_EnableKeyRepeat(250, 30)) initprintf("Error enabling keyboard repeat.\n"); inputdevices = 1|2; // keyboard (1) and mouse (2) mouseacquired = 0; SDL_EnableUNICODE(1); // let's hope this doesn't hit us too hard memset(keynames,0,sizeof(keynames)); for (i=0; i= 256) return NULL; return keynames[num]; } const unsigned char *getjoyname(int what, int num) { static char tmp[64]; switch (what) { case 0: // axis if ((unsigned)num > (unsigned)joynumaxes) return NULL; sprintf(tmp,"Axis %d",num); return (unsigned char *)tmp; case 1: // button if ((unsigned)num > (unsigned)joynumbuttons) return NULL; sprintf(tmp,"Button %d",num); return (unsigned char *)tmp; case 2: // hat if ((unsigned)num > (unsigned)joynumhats) return NULL; sprintf(tmp,"Hat %d",num); return (unsigned char *)tmp; default: return NULL; } } // // bgetchar, bkbhit, bflushchars -- character-based input functions // unsigned char bgetchar(void) { unsigned char c; if (keyasciififoplc == keyasciififoend) return 0; c = keyasciififo[keyasciififoplc]; keyasciififoplc = ((keyasciififoplc+1)&(KEYFIFOSIZ-1)); return c; } int bkbhit(void) { return (keyasciififoplc != keyasciififoend); } void bflushchars(void) { keyasciififoplc = keyasciififoend = 0; } // // set{key|mouse|joy}presscallback() -- sets a callback which gets notified when keys are pressed // void setkeypresscallback(void(*callback)(int, int)) { keypresscallback = callback; } void setmousepresscallback(void(*callback)(int, int)) { mousepresscallback = callback; } void setjoypresscallback(void(*callback)(int, int)) { joypresscallback = callback; } // // initmouse() -- init mouse input // int initmouse(void) { moustat=1; grabmouse(1); return 0; } // // uninitmouse() -- uninit mouse input // void uninitmouse(void) { grabmouse(0); moustat=0; } // // grabmouse() -- show/hide mouse cursor // void grabmouse(char a) { if (appactive && moustat) { if (a != mouseacquired) { // #ifndef DEBUGGINGAIDS #if 1 SDL_GrabMode g; g = SDL_WM_GrabInput(a ? SDL_GRAB_ON : SDL_GRAB_OFF); mouseacquired = (g == SDL_GRAB_ON); SDL_ShowCursor(mouseacquired ? SDL_DISABLE : SDL_ENABLE); #else mouseacquired = a; #endif } } else { mouseacquired = a; } mousex = mousey = 0; } // // readmousexy() -- return mouse motion information // void readmousexy(int *x, int *y) { if (!mouseacquired || !appactive || !moustat) { *x = *y = 0; return; } *x = mousex; *y = mousey; mousex = mousey = 0; } // // readmousebstatus() -- return mouse button information // void readmousebstatus(int *b) { if (!mouseacquired || !appactive || !moustat) *b = 0; else *b = mouseb; } // // setjoydeadzone() -- sets the dead and saturation zones for the joystick // void setjoydeadzone(int axis, unsigned short dead, unsigned short satur) {} // // getjoydeadzone() -- gets the dead and saturation zones for the joystick // void getjoydeadzone(int axis, unsigned short *dead, unsigned short *satur) { *dead = *satur = 0; } // // releaseallbuttons() // void releaseallbuttons(void) {} // // // --------------------------------------- // // All things Timer // Ken did this // // --------------------------------------- // // static Uint32 timerfreq=0; static Uint32 timerlastsample=0; Uint32 timerticspersec=0; static void(*usertimercallback)(void) = NULL; // // inittimer() -- initialise timer // int inittimer(int tickspersecond) { if (timerfreq) return 0; // already installed // initprintf("Initialising timer\n"); timerfreq = 1000; timerticspersec = tickspersecond; timerlastsample = SDL_GetTicks() * timerticspersec / timerfreq; usertimercallback = NULL; return 0; } // // uninittimer() -- shut down timer // void uninittimer(void) { if (!timerfreq) return; timerfreq=0; } // // sampletimer() -- update totalclock // void sampletimer(void) { Uint32 i; int n; if (!timerfreq) return; i = SDL_GetTicks(); n = (int)(i * timerticspersec / timerfreq) - timerlastsample; if (n>0) { totalclock += n; timerlastsample += n; } if (usertimercallback) for (; n>0; n--) usertimercallback(); } // // getticks() -- returns the sdl ticks count // unsigned int getticks(void) { return (unsigned int)SDL_GetTicks(); } // // gettimerfreq() -- returns the number of ticks per second the timer is configured to generate // int gettimerfreq(void) { return timerticspersec; } // // installusertimercallback() -- set up a callback function to be called when the timer is fired // void(*installusertimercallback(void(*callback)(void)))(void) { void(*oldtimercallback)(void); oldtimercallback = usertimercallback; usertimercallback = callback; return oldtimercallback; } // // // --------------------------------------- // // All things Video // // --------------------------------------- // // // // getvalidmodes() -- figure out what video modes are available // static int sortmodes(const struct validmode_t *a, const struct validmode_t *b) { int x; if ((x = a->fs - b->fs) != 0) return x; if ((x = a->bpp - b->bpp) != 0) return x; if ((x = a->xdim - b->xdim) != 0) return x; if ((x = a->ydim - b->ydim) != 0) return x; return 0; } static char modeschecked=0; void getvalidmodes(void) { static int cdepths[] = { 8, #ifdef USE_OPENGL 16,24,32, #endif 0 }; static int defaultres[][2] = { {1280,1024} ,{1280,960},{1152,864},{1024,768},{800,600},{640,480}, {640,400},{512,384},{480,360},{400,300},{320,240},{320,200},{0,0} }; SDL_Rect **modes; SDL_PixelFormat pf = { NULL, 8, 1, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0 }; int i, j, maxx=0, maxy=0; if (modeschecked) return; validmodecnt=0; initprintf("Detecting video modes:\n"); #define ADDMODE(x,y,c,f) if (validmodecnt 8) continue; #endif pf.BitsPerPixel = cdepths[j]; pf.BytesPerPixel = cdepths[j] >> 3; modes = SDL_ListModes(&pf, SURFACE_FLAGS | SDL_FULLSCREEN); if (modes == (SDL_Rect **)0) { if (cdepths[j] > 8) cdepths[j] = -1; continue; } if (modes == (SDL_Rect **)-1) { for (i=0; defaultres[i][0]; i++) ADDMODE(defaultres[i][0],defaultres[i][1],cdepths[j],1) } else { for (i=0; modes[i]; i++) { if ((modes[i]->w > MAXXDIM) || (modes[i]->h > MAXYDIM)) continue; ADDMODE(modes[i]->w, modes[i]->h, cdepths[j], 1) if ((modes[i]->w > maxx) && (modes[i]->h > maxy)) { maxx = modes[i]->w; maxy = modes[i]->h; } } } } if (maxx == 0 && maxy == 0) { initprintf("No fullscreen modes available!\n"); maxx = MAXXDIM; maxy = MAXYDIM; } // add windowed modes next for (j=0; cdepths[j]; j++) { #ifdef USE_OPENGL if (nogl && cdepths[j] > 8) continue; #endif if (cdepths[j] < 0) continue; for (i=0; defaultres[i][0]; i++) CHECK(defaultres[i][0],defaultres[i][1]) ADDMODE(defaultres[i][0],defaultres[i][1],cdepths[j],0) } #undef CHECK #undef ADDMODE qsort((void*)validmode, validmodecnt, sizeof(struct validmode_t), (int(*)(const void*,const void*))sortmodes); modeschecked=1; } // // checkvideomode() -- makes sure the video mode passed is legal // int checkvideomode(int *x, int *y, int c, int fs, int forced) { int i, nearest=-1, dx, dy, odx=9999, ody=9999; getvalidmodes(); if (c>8 #ifdef USE_OPENGL && nogl #endif ) return -1; // fix up the passed resolution values to be multiples of 8 // and at least 320x200 or at most MAXXDIMxMAXYDIM if (*x < 320) *x = 320; if (*y < 200) *y = 200; if (*x > MAXXDIM) *x = MAXXDIM; if (*y > MAXYDIM) *y = MAXYDIM; *x &= 0xfffffff8l; for (i=0; i 8 && sdl_surface) polymost_glreset(); #endif // restore gamma before we change video modes if it was changed if (sdl_surface && gammabrightness) { SDL_SetGammaRamp(sysgamma[0], sysgamma[1], sysgamma[2]); gammabrightness = 0; // redetect on next mode switch } #if defined(USE_OPENGL) if (c > 8) { int i, j, multisamplecheck = (glmultisample > 0); struct { SDL_GLattr attr; int value; } attributes[] = { #if 0 { SDL_GL_RED_SIZE, 8 }, { SDL_GL_GREEN_SIZE, 8 }, { SDL_GL_BLUE_SIZE, 8 }, { SDL_GL_ALPHA_SIZE, 8 }, { SDL_GL_BUFFER_SIZE, c }, { SDL_GL_STENCIL_SIZE, 0 }, { SDL_GL_ACCUM_RED_SIZE, 0 }, { SDL_GL_ACCUM_GREEN_SIZE, 0 }, { SDL_GL_ACCUM_BLUE_SIZE, 0 }, { SDL_GL_ACCUM_ALPHA_SIZE, 0 }, { SDL_GL_DEPTH_SIZE, 24 }, #endif { SDL_GL_DOUBLEBUFFER, 1 }, { SDL_GL_MULTISAMPLEBUFFERS, glmultisample > 0 }, { SDL_GL_MULTISAMPLESAMPLES, glmultisample }, }; if (nogl) return -1; initprintf("Setting video mode %dx%d (%d-bpp %s)\n", x,y,c, ((fs&1) ? "fullscreen" : "windowed")); do { for (i=0; i < (int)(sizeof(attributes)/sizeof(attributes[0])); i++) { j = attributes[i].value; if (!multisamplecheck && (attributes[i].attr == SDL_GL_MULTISAMPLEBUFFERS || attributes[i].attr == SDL_GL_MULTISAMPLESAMPLES) ) { j = 0; } SDL_GL_SetAttribute(attributes[i].attr, j); } sdl_surface = SDL_SetVideoMode(x, y, c, SDL_OPENGL | ((fs&1)?SDL_FULLSCREEN:0)); if (!sdl_surface) { if (multisamplecheck) { initprintf("Multisample mode not possible. Retrying without multisampling.\n"); glmultisample = 0; continue; } initprintf("Unable to set video mode!\n"); return -1; } } while (multisamplecheck--); } else #endif { initprintf("Setting video mode %dx%d (%d-bpp %s)\n", x,y,c, ((fs&1) ? "fullscreen" : "windowed")); sdl_surface = SDL_SetVideoMode(x, y, c, SURFACE_FLAGS | ((fs&1)?SDL_FULLSCREEN:0)); if (!sdl_surface) { initprintf("Unable to set video mode!\n"); return -1; } } #if 0 { char flags[512] = ""; #define FLAG(x,y) if ((sdl_surface->flags & x) == x) { strcat(flags, y); strcat(flags, " "); } FLAG(SDL_HWSURFACE, "HWSURFACE") else FLAG(SDL_SWSURFACE, "SWSURFACE") FLAG(SDL_ASYNCBLIT, "ASYNCBLIT") FLAG(SDL_ANYFORMAT, "ANYFORMAT") FLAG(SDL_HWPALETTE, "HWPALETTE") FLAG(SDL_DOUBLEBUF, "DOUBLEBUF") FLAG(SDL_FULLSCREEN, "FULLSCREEN") FLAG(SDL_OPENGL, "OPENGL") FLAG(SDL_OPENGLBLIT, "OPENGLBLIT") FLAG(SDL_RESIZABLE, "RESIZABLE") FLAG(SDL_HWACCEL, "HWACCEL") FLAG(SDL_SRCCOLORKEY, "SRCCOLORKEY") FLAG(SDL_RLEACCEL, "RLEACCEL") FLAG(SDL_SRCALPHA, "SRCALPHA") FLAG(SDL_PREALLOC, "PREALLOC") #undef FLAG initprintf("SDL Surface flags: %s\n", flags); } #endif { //static char t[384]; //sprintf(t, "%s (%dx%d %s)", apptitle, x, y, ((fs) ? "fullscreen" : "windowed")); SDL_WM_SetCaption(apptitle, 0); } #ifdef USE_OPENGL if (c > 8) { char *p,*p2,*p3; int i; polymost_glreset(); bglEnable(GL_TEXTURE_2D); bglShadeModel(GL_SMOOTH); //GL_FLAT bglClearColor(0,0,0,0.5); //Black Background bglHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST); //Use FASTEST for ortho! bglHint(GL_LINE_SMOOTH_HINT,GL_NICEST); bglDisable(GL_DITHER); glinfo.vendor = (const char *)bglGetString(GL_VENDOR); glinfo.renderer = (const char *)bglGetString(GL_RENDERER); glinfo.version = (const char *)bglGetString(GL_VERSION); glinfo.extensions = (const char *)bglGetString(GL_EXTENSIONS); glinfo.maxanisotropy = 1.0; glinfo.bgra = 0; glinfo.texcompr = 0; // process the extensions string and flag stuff we recognize p = Bstrdup(glinfo.extensions); p3 = p; while ((p2 = Bstrtoken(p3==p?p:NULL, " ", (char**)&p3, 1)) != NULL) { if (!Bstrcmp(p2, "GL_EXT_texture_filter_anisotropic")) { // supports anisotropy. get the maximum anisotropy level bglGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &glinfo.maxanisotropy); } else if (!Bstrcmp(p2, "GL_EXT_texture_edge_clamp") || !Bstrcmp(p2, "GL_SGIS_texture_edge_clamp")) { // supports GL_CLAMP_TO_EDGE or GL_CLAMP_TO_EDGE_SGIS glinfo.clamptoedge = 1; } else if (!Bstrcmp(p2, "GL_EXT_bgra")) { // support bgra textures glinfo.bgra = 1; } else if (!Bstrcmp(p2, "GL_ARB_texture_compression")) { // support texture compression glinfo.texcompr = 1; } else if (!Bstrcmp(p2, "GL_ARB_texture_non_power_of_two")) { // support non-power-of-two texture sizes glinfo.texnpot = 1; } else if (!Bstrcmp(p2, "WGL_3DFX_gamma_control")) { // 3dfx cards have issues with fog nofog = 1; if (!(warnonce&1)) initprintf("3dfx card detected: OpenGL fog disabled\n"); warnonce |= 1; } else if (!Bstrcmp(p2, "GL_ARB_multisample")) { // supports multisampling glinfo.multisample = 1; } else if (!Bstrcmp(p2, "GL_NV_multisample_filter_hint")) { // supports nvidia's multisample hint extension glinfo.nvmultisamplehint = 1; } else if (!Bstrcmp((char *)p2, "GL_ARB_fragment_program")) { glinfo.arbfp = 1; } else if (!Bstrcmp((char *)p2, "GL_ARB_depth_texture")) { glinfo.depthtex = 1; } else if (!Bstrcmp((char *)p2, "GL_ARB_shadow")) { glinfo.shadow = 1; } else if (!Bstrcmp((char *)p2, "GL_EXT_framebuffer_object")) { glinfo.fbos = 1; } else if (!Bstrcmp((char *)p2, "GL_NV_texture_rectangle") || !Bstrcmp((char *)p2, "GL_EXT_texture_rectangle")) { glinfo.rect = 1; } else if (!Bstrcmp((char *)p2, "GL_ARB_multitexture")) { glinfo.multitex = 1; } else if (!Bstrcmp((char *)p2, "GL_ARB_texture_env_combine")) { glinfo.envcombine = 1; } else if (!Bstrcmp((char *)p2, "GL_ARB_vertex_buffer_object")) { glinfo.vbos = 1; } } Bfree(p); } #endif xres = x; yres = y; bpp = c; fullscreen = fs; //bytesperline = sdl_surface->pitch; //imageSize = bytesperline*yres; numpages = c>8?2:1; frameplace = 0; lockcount = 0; modechange=1; videomodereset = 0; OSD_ResizeDisplay(xres,yres); // save the current system gamma to determine if gamma is available if (!gammabrightness) { float f = 1.0 + ((float)curbrightness / 10.0); if (SDL_GetGammaRamp(sysgamma[0], sysgamma[1], sysgamma[2]) >= 0) gammabrightness = 1; // see if gamma really is working by trying to set the brightness if (gammabrightness && SDL_SetGamma(f,f,f) < 0) gammabrightness = 0; // nope } // setpalettefade will set the palette according to whether gamma worked setpalettefade(palfadergb.r, palfadergb.g, palfadergb.b, palfadedelta); //if (c==8) setpalette(0,256,0); //baselayer_onvideomodechange(c>8); if (regrab) grabmouse(1); return 0; } // // resetvideomode() -- resets the video system // void resetvideomode(void) { videomodereset = 1; modeschecked = 0; } // // begindrawing() -- locks the framebuffer for drawing // void begindrawing(void) { int i,j; if (bpp > 8) { if (offscreenrendering) return; frameplace = 0; bytesperline = 0; imageSize = 0; modechange = 0; return; } // lock the frame if (lockcount++ > 0) return; if (offscreenrendering) return; if (SDL_MUSTLOCK(sdl_surface)) SDL_LockSurface(sdl_surface); frameplace = (int)sdl_surface->pixels; if (sdl_surface->pitch != bytesperline || modechange) { bytesperline = sdl_surface->pitch; imageSize = bytesperline*yres; setvlinebpl(bytesperline); j = 0; for (i=0;i<=ydim;i++) ylookup[i] = j, j += bytesperline; modechange=0; } } // // enddrawing() -- unlocks the framebuffer // void enddrawing(void) { if (bpp > 8) { if (!offscreenrendering) frameplace = 0; return; } if (!frameplace) return; if (lockcount > 1) { lockcount--; return; } if (!offscreenrendering) frameplace = 0; if (lockcount == 0) return; lockcount = 0; if (offscreenrendering) return; if (SDL_MUSTLOCK(sdl_surface)) SDL_UnlockSurface(sdl_surface); } // // showframe() -- update the display // void showframe(int w) { int i,j; #ifdef USE_OPENGL if (bpp > 8) { if (palfadedelta) { bglMatrixMode(GL_PROJECTION); bglPushMatrix(); bglLoadIdentity(); bglMatrixMode(GL_MODELVIEW); bglPushMatrix(); bglLoadIdentity(); bglDisable(GL_DEPTH_TEST); bglDisable(GL_ALPHA_TEST); bglDisable(GL_TEXTURE_2D); bglEnable(GL_BLEND); bglColor4ub(palfadergb.r, palfadergb.g, palfadergb.b, palfadedelta); bglBegin(GL_QUADS); bglVertex2i(-1, -1); bglVertex2i(1, -1); bglVertex2i(1, 1); bglVertex2i(-1, 1); bglEnd(); bglMatrixMode(GL_MODELVIEW); bglPopMatrix(); bglMatrixMode(GL_PROJECTION); bglPopMatrix(); } SDL_GL_SwapBuffers(); return; } #endif if (offscreenrendering) return; if (lockcount) { printf("Frame still locked %d times when showframe() called.\n", lockcount); while (lockcount) enddrawing(); } SDL_Flip(sdl_surface); } // // setpalette() -- set palette values // int setpalette(int start, int num, char *dapal) { SDL_Color pal[256]; int i,n; if (bpp > 8) return 0; // no palette in opengl copybuf(curpalettefaded, pal, 256); for (i=start, n=num; n>0; i++, n--) { /* pal[i].b = dapal[0] << 2; pal[i].g = dapal[1] << 2; pal[i].r = dapal[2] << 2; */ curpalettefaded[i].f = pal[i].unused = 0; dapal += 4; } //return SDL_SetPalette(sdl_surface, SDL_LOGPAL|SDL_PHYSPAL, pal, 0, 256); return SDL_SetColors(sdl_surface, pal, 0, 256); } // // getpalette() -- get palette values // /* int getpalette(int start, int num, char *dapal) { int i; SDL_Palette *pal; // we shouldn't need to lock the surface to get the palette pal = sdl_surface->format->palette; for (i=num; i>0; i--, start++) { dapal[0] = pal->colors[start].b >> 2; dapal[1] = pal->colors[start].g >> 2; dapal[2] = pal->colors[start].r >> 2; dapal += 4; } return 1; } */ // // setgamma // int setgamma(float ro, float go, float bo) { return SDL_SetGamma(ro,go,bo); } #ifndef __APPLE__ extern struct sdlappicon sdlappicon; static SDL_Surface * loadappicon(void) { SDL_Surface *surf; surf = SDL_CreateRGBSurfaceFrom((void*)sdlappicon.pixels, sdlappicon.width, sdlappicon.height, 32, sdlappicon.width*4, 0xffl,0xff00l,0xff0000l,0xff000000l); return surf; } #endif // // // --------------------------------------- // // Miscellany // // --------------------------------------- // // // // handleevents() -- process the SDL message queue // returns !0 if there was an important event worth checking (like quitting) // int handleevents(void) { int code, rv=0, j; SDL_Event ev; #define SetKey(key,state) { \ keystatus[key] = state; \ if (state) { \ keyfifo[keyfifoend] = key; \ keyfifo[(keyfifoend+1)&(KEYFIFOSIZ-1)] = state; \ keyfifoend = ((keyfifoend+2)&(KEYFIFOSIZ-1)); \ } \ } while (SDL_PollEvent(&ev)) { switch (ev.type) { case SDL_KEYDOWN: case SDL_KEYUP: code = keytranslation[ev.key.keysym.sym]; if (ev.key.keysym.unicode != 0 && ev.key.type == SDL_KEYDOWN && (ev.key.keysym.unicode & 0xff80) == 0 && ((keyasciififoend+1)&(KEYFIFOSIZ-1)) != keyasciififoplc) { keyasciififo[keyasciififoend] = ev.key.keysym.unicode & 0x7f; keyasciififoend = ((keyasciififoend+1)&(KEYFIFOSIZ-1)); } // hook in the osd if (OSD_HandleKey(code, (ev.key.type == SDL_KEYDOWN)) == 0) break; if (ev.key.type == SDL_KEYDOWN) { if (!keystatus[code]) { SetKey(code, 1); if (keypresscallback) keypresscallback(code, 1); } } else { SetKey(code, 0); if (keypresscallback) keypresscallback(code, 0); } break; case SDL_ACTIVEEVENT: if (ev.active.state & SDL_APPINPUTFOCUS) { appactive = ev.active.gain; #ifndef DEBUGGINGAIDS if (mouseacquired && moustat) { if (appactive) { SDL_WM_GrabInput(SDL_GRAB_ON); SDL_ShowCursor(SDL_DISABLE); } else { SDL_WM_GrabInput(SDL_GRAB_OFF); SDL_ShowCursor(SDL_ENABLE); } } #endif rv=-1; } break; case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONUP: switch (ev.button.button) { case SDL_BUTTON_LEFT: j = 0; break; case SDL_BUTTON_RIGHT: j = 1; break; case SDL_BUTTON_MIDDLE: j = 2; break; default: j = ev.button.button; break; } if (j<0) break; if (ev.button.state == SDL_PRESSED) { if (ev.button.button == SDL_BUTTON_WHEELUP) { mwheelup = totalclock; } if (ev.button.button == SDL_BUTTON_WHEELDOWN) { mwheeldown = totalclock; } mouseb |= (1< #elif defined __linux || defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__ # include #endif void makeasmwriteable(void) { #ifndef ENGINE_USING_A_C extern int dep_begin, dep_end; # if defined _WIN32 DWORD oldprot; if (!VirtualProtect((LPVOID)&dep_begin, (SIZE_T)&dep_end - (SIZE_T)&dep_begin, PAGE_EXECUTE_READWRITE, &oldprot)) { initprint("Error making code writeable\n"); return; } # elif defined __linux || defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__ int pagesize; size_t dep_begin_page; pagesize = sysconf(_SC_PAGE_SIZE); if (pagesize == -1) { initprintf("Error getting system page size\n"); return; } dep_begin_page = ((size_t)&dep_begin) & ~(pagesize-1); if (mprotect((const void *)dep_begin_page, (size_t)&dep_end - dep_begin_page, PROT_READ|PROT_WRITE) < 0) { initprintf("Error making code writeable (errno=%d)\n", errno); return; } # else # error Don't know how to unprotect the self-modifying assembly on this platform! # endif #endif }