⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sdl_driver.c

📁 小型游戏引擎
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * An SDL replacement for BUILD's VESA code. * *  Written by Ryan C. Gordon. (icculus@clutteredmind.org) * * Please do NOT harrass Ken Silverman about any code modifications *  (including this file) to BUILD. *//* * "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman * Ken Silverman's official web site: "http://www.advsys.net/ken" * See the included license file "BUILDLIC.TXT" for license info. * This file IS NOT A PART OF Ken Silverman's original release */#include <stdio.h>#include <stdlib.h>#include <stdarg.h>#include <assert.h>#include <string.h>#include "platform.h"#if (!defined PLATFORM_SUPPORTS_SDL)#error This platform apparently does not use SDL. Do not compile this.#endif#include "SDL.h"#include "build.h"#include "display.h"#include "pragmas.h"#include "engine.h"#if (defined USE_OPENGL)#include "buildgl.h"#endiftypedef enum{    RENDERER_SOFTWARE,    RENDERER_OPENGL3D,    RENDERER_TOTAL} sdl_renderer_type;const char *renderer_name[RENDERER_TOTAL];#define ENVRSTR_RENDERER_SOFTWARE  "software"#define ENVRSTR_RENDERER_OPENGL3D  "opengl3d"static sdl_renderer_type renderer = RENDERER_SOFTWARE;/* !!! ugh. Clean this up. */#if (defined USE_I386_ASM)#if (!defined __WATCOMC__)#include "a.h"#elseextern long setvlinebpl(long);#pragma aux setvlinebpl parm [eax];#endif  /* __WATCOMC__ */#endif  /* USE_I386_ASM */#include "cache1d.h"/* * !!! I'd like this to be temporary. --ryan. * !!!  That is, the self-modifying part, so I can ditch the mprotect() stuff. */#if ((defined PLATFORM_UNIX) && (defined USE_I386_ASM))#include <sys/mman.h>#include <limits.h>#ifndef PAGESIZE#define PAGESIZE 4096#endif#endif/* * !!! remove the surface_end checks, for speed's sake. They are a * !!!  needed safety right now. --ryan. */#define DEFAULT_MAXRESWIDTH  1600#define DEFAULT_MAXRESHEIGHT 1200#define UNLOCK_SURFACE_AND_RETURN  if (SDL_MUSTLOCK(surface)) SDL_UnlockSurface(surface); return;int _argc = 0;char **_argv = NULL;    /* !!! move these elsewhere? */long xres, yres, bytesperline, frameplace, imageSize, maxpages;char *screen, vesachecked;long buffermode, origbuffermode, linearmode;char permanentupdate = 0, vgacompatible;SDL_Surface *surface = NULL; /* This isn't static so that we can use it elsewhere AH */static int debug_hall_of_mirrors = 0;static Uint32 sdl_flags = SDL_HWPALETTE;static long mouse_x = 0;static long mouse_y = 0;static long mouse_relative_x = 0;static long mouse_relative_y = 0;static short mouse_buttons = 0;static int mouse_grabbed = 0;static unsigned int lastkey = 0;static SDL_TimerID primary_timer = NULL;/* so we can make use of setcolor16()... - DDOI */static unsigned char drawpixel_color=0;/* These hold the colors for the 256 color palette when in 16-color mode - DDOI */static char backup_palette[48];static int in_egapalette = 0;/* The standard EGA palette in BUILD format - DDOI */static char egapalette[] = { 0, 0, 0,			    0, 0, 42,			    0, 42, 0,			    0, 42, 42,			    42, 0, 0,			    42, 0, 42,			    42, 21, 0,			    42, 42, 42,			    21, 21, 21,			    21, 21, 63,			    21, 63, 21,			    21, 63, 63,			    63, 21, 21,			    63, 21, 63,			    63, 63, 21,			    63, 63, 63			   };static unsigned int scancodes[SDLK_LAST];static long last_render_ticks = 0;long total_render_time = 1;long total_rendered_frames = 0;static char *titlelong = NULL;static char *titleshort = NULL;void restore256_palette (void);void set16color_palette (void);static FILE *_sdl_debug_file = NULL;static inline void __out_sdldebug(const char *subsystem,                                  const char *fmt, va_list ap){    fprintf(_sdl_debug_file, "%s: ", subsystem);    vfprintf(_sdl_debug_file, fmt, ap);    fprintf(_sdl_debug_file, "\n");    fflush(_sdl_debug_file);} /* __out_sdldebug */static void sdldebug(const char *fmt, ...){    va_list ap;    if (_sdl_debug_file)    {        va_start(ap, fmt);        __out_sdldebug("BUILDSDL", fmt, ap);        va_end(ap);    } /* if */} /* sdldebug */#if (defined USE_OPENGL)void sgldebug(const char *fmt, ...){    va_list ap;    if (_sdl_debug_file)    {        va_start(ap, fmt);        __out_sdldebug("BUILDSDL/GL", fmt, ap);        va_end(ap);    } /* if */} /* sgldebug */#endifstatic void __append_sdl_surface_flag(SDL_Surface *_surface, char *str,                                      size_t strsize, Uint32 flag,                                      const char *flagstr){    if (_surface->flags & flag)    {        if ( (strlen(str) + strlen(flagstr)) >= (strsize - 1) )            strcpy(str + (strsize - 5), " ...");        else            strcat(str, flagstr);    } /* if */} /* append_sdl_surface_flag */#define append_sdl_surface_flag(a, b, c, fl) __append_sdl_surface_flag(a, b, c, fl, " " #fl)#define print_tf_state(str, val) sdldebug("%s: {%s}", str, (val) ? "true" : "false" )static void output_surface_info(SDL_Surface *_surface){    const SDL_VideoInfo *info;    char f[256];    if (!_sdl_debug_file)        return;    if (_surface == NULL)    {        sdldebug("-WARNING- You've got a NULL screen surface!");    }    else    {        f[0] = '\0';        sdldebug("screen surface is (%dx%dx%dbpp).",                _surface->w, _surface->h, _surface->format->BitsPerPixel);        append_sdl_surface_flag(_surface, f, sizeof (f), SDL_SWSURFACE);        append_sdl_surface_flag(_surface, f, sizeof (f), SDL_HWSURFACE);        append_sdl_surface_flag(_surface, f, sizeof (f), SDL_ASYNCBLIT);        append_sdl_surface_flag(_surface, f, sizeof (f), SDL_ANYFORMAT);        append_sdl_surface_flag(_surface, f, sizeof (f), SDL_HWPALETTE);        append_sdl_surface_flag(_surface, f, sizeof (f), SDL_DOUBLEBUF);        append_sdl_surface_flag(_surface, f, sizeof (f), SDL_FULLSCREEN);        append_sdl_surface_flag(_surface, f, sizeof (f), SDL_OPENGL);        append_sdl_surface_flag(_surface, f, sizeof (f), SDL_OPENGLBLIT);        append_sdl_surface_flag(_surface, f, sizeof (f), SDL_RESIZABLE);        append_sdl_surface_flag(_surface, f, sizeof (f), SDL_NOFRAME);        append_sdl_surface_flag(_surface, f, sizeof (f), SDL_HWACCEL);        append_sdl_surface_flag(_surface, f, sizeof (f), SDL_SRCCOLORKEY);        append_sdl_surface_flag(_surface, f, sizeof (f), SDL_RLEACCELOK);        append_sdl_surface_flag(_surface, f, sizeof (f), SDL_RLEACCEL);        append_sdl_surface_flag(_surface, f, sizeof (f), SDL_SRCALPHA);        append_sdl_surface_flag(_surface, f, sizeof (f), SDL_PREALLOC);        if (f[0] == '\0')            strcpy(f, " (none)");        sdldebug("New vidmode flags:%s", f);        info = SDL_GetVideoInfo();        assert(info != NULL);        print_tf_state("hardware surface available", info->hw_available);        print_tf_state("window manager available", info->wm_available);        print_tf_state("accelerated hardware->hardware blits", info->blit_hw);        print_tf_state("accelerated hardware->hardware colorkey blits", info->blit_hw_CC);        print_tf_state("accelerated hardware->hardware alpha blits", info->blit_hw_A);        print_tf_state("accelerated software->hardware blits", info->blit_sw);        print_tf_state("accelerated software->hardware colorkey blits", info->blit_sw_CC);        print_tf_state("accelerated software->hardware alpha blits", info->blit_sw_A);        print_tf_state("accelerated color fills", info->blit_fill);        sdldebug("video memory: (%d)", info->video_mem);    } /* else */} /* output_surface_info */static void output_driver_info(void){    char buffer[256];    if (!_sdl_debug_file)        return;    sdldebug("Using BUILD renderer \"%s\".", renderer_name[renderer]);    if (SDL_VideoDriverName(buffer, sizeof (buffer)) == NULL)    {        sdldebug("-WARNING- SDL_VideoDriverName() returned NULL!");    } /* if */    else    {        sdldebug("Using SDL video driver \"%s\".", buffer);    } /* else */} /* output_driver_info */static Uint8 *get_framebuffer(void){    assert(renderer != RENDERER_OPENGL3D);    if (renderer == RENDERER_SOFTWARE)        return((Uint8 *) surface->pixels);    else if (renderer == RENDERER_OPENGL3D)        return((Uint8 *) frameplace);    return(NULL);} /* get_framebuffer */int using_opengl(void){    return(renderer == RENDERER_OPENGL3D);} /* using_opengl *//* * !!! This is almost an entire copy of the original setgamemode(). * !!!  Figure out what is needed for just 2D mode, and separate that * !!!  out. Then, place the original setgamemode() back into engine.c, * !!!  and remove our simple implementation (and this function.) * !!!  Just be sure to keep the non-DOS things, like the window's * !!!  titlebar caption.   --ryan. */static char screenalloctype = 255;static void init_new_res_vars(int davidoption){    int i = 0;    int j = 0;    setupmouse();    SDL_WM_SetCaption(titlelong, titleshort);    xdim = xres = surface->w;    ydim = yres = surface->h;    bytesperline = surface->w;    vesachecked = 1;    vgacompatible = 1;    linearmode = 1;	qsetmode = surface->h;	activepage = visualpage = 0;    horizlookup = horizlookup2 = NULL;    if (renderer == RENDERER_OPENGL3D)        frameplace = (long) NULL;    else        frameplace = (long) ( ((Uint8 *) surface->pixels) );  	if (screen != NULL)   	{       	if (screenalloctype == 0) kkfree((void *)screen);   	    if (screenalloctype == 1) suckcache((long *)screen);   		screen = NULL;   	} /* if */    if (davidoption != -1)    {    	switch(vidoption)    	{    		case 1:i = xdim*ydim; break;    		case 2: xdim = 320; ydim = 200; i = xdim*ydim; break;    		case 6: xdim = 320; ydim = 200; i = 131072; break;    		default: assert(0);    	}    	j = ydim*4*sizeof(long);  /* Leave room for horizlookup&horizlookup2 */    	screenalloctype = 0;	    if ((screen = (char *)kkmalloc(i+(j<<1))) == NULL)    	{	    	 allocache((long *)&screen,i+(j<<1),&permanentlock);    		 screenalloctype = 1;    	}        /* !!! FIXME: Should screen get allocated above if in opengl3d mode? */        if (renderer == RENDERER_OPENGL3D)            frameplace = (long) NULL;        else        {            frameplace = FP_OFF(screen);          	horizlookup = (long *)(frameplace+i);           	horizlookup2 = (long *)(frameplace+i+j);        } /* else */    } /* if */    j = 0;  	for(i = 0; i <= ydim; i++)    {        ylookup[i] = j;        j += bytesperline;    } /* for */   	horizycent = ((ydim*4)>>1);		/* Force drawrooms to call dosetaspect & recalculate stuff */	oxyaspect = oxdimen = oviewingrange = -1;	setvlinebpl(bytesperline);    if (davidoption != -1)    {    	setview(0L,0L,xdim-1,ydim-1);    	clearallviews(0L);    } /* if */	setbrightness((char) curbrightness, (unsigned char *) &palette[0]);	if (searchx < 0) { searchx = halfxdimen; searchy = (ydimen>>1); }} /* init_new_res_vars */static void go_to_new_vid_mode(int vidoption, int w, int h){    getvalidvesamodes();    SDL_ClearError();    surface = SDL_SetVideoMode(w, h, 8, sdl_flags);    if (surface == NULL)    {        fprintf(stderr, "BUILDSDL: Failed to set %dx%d video mode!\n"                        "BUILDSDL: SDL_Error() says [%s].\n",                        w, h, SDL_GetError());        SDL_Quit();        exit(13);    } /* if */    output_surface_info(surface);    init_new_res_vars(vidoption);} /* go_to_new_vid_mode */static int sdl_mouse_button_filter(SDL_Event const *event){        /*         * What BUILD expects:         *  0	left button pressed if 1         *  1	right button pressed if 1         *  2	middle button pressed if 1         *         *   (That is, this is what Int 33h (AX=0x05) returns...)         */    Uint8 bmask = SDL_GetMouseState(NULL, NULL);    mouse_buttons = 0;    if (bmask & SDL_BUTTON_LMASK) mouse_buttons |= 1;    if (bmask & SDL_BUTTON_RMASK) mouse_buttons |= 2;    if (bmask & SDL_BUTTON_MMASK) mouse_buttons |= 4;    return(0);} /* sdl_mouse_up_filter */static int sdl_mouse_motion_filter(SDL_Event const *event){    if (surface == NULL)        return(0);    if (event->type == SDL_JOYBALLMOTION)    {        mouse_relative_x = event->jball.xrel/100;        mouse_relative_y = event->jball.yrel/100;       	mouse_x += mouse_relative_x;       	mouse_y += mouse_relative_y;    } /* if */    else    {        if (mouse_grabbed)        {          	mouse_relative_x = event->motion.xrel;       	    mouse_relative_y = event->motion.yrel;           	mouse_x += mouse_relative_x;           	mouse_y += mouse_relative_y;        } /* if */        else        {          	mouse_relative_x = event->motion.x - mouse_x;           	mouse_relative_y = event->motion.y - mouse_y;           	mouse_x = event->motion.x;           	mouse_y = event->motion.y;        } /* else */    } /* else */   	if (mouse_x < 0) mouse_x = 0;   	if (mouse_x > surface->w) mouse_x = surface->w;   	if (mouse_y < 0) mouse_y = 0;   	if (mouse_y > surface->h) mouse_y = surface->h;    return(0);} /* sdl_mouse_motion_filter *//** * Attempt to flip the video surface to fullscreen or windowed mode. *  Attempts to maintain the surface's state, but makes no guarantee *  that pointers (i.e., the surface's pixels field) will be the same *  after this call. * * Caveats: Your surface pointers will be changing; if you have any other *           copies laying about, they are invalidated. * *          Do NOT call this from an SDL event filter on Windows. You can *           call it based on the return values from SDL_PollEvent, etc, just *           not during the function you passed to SDL_SetEventFilter(). * *          Thread safe? Likely not. * *   @param surface pointer to surface ptr to toggle. May be different *                  pointer on return. MAY BE NULL ON RETURN IF FAILURE! *   @param flags   pointer to flags to set on surface. The value pointed *                  to will be XOR'd with SDL_FULLSCREEN before use. Actual *                  flags set will be filled into pointer. Contents are *                  undefined on failure. Can be NULL, in which case the *                  surface's current flags are used. *  @return non-zero on success, zero on failure. */static int attempt_fullscreen_toggle(SDL_Surface **surface, Uint32 *flags){    long framesize = 0;    void *pixels = NULL;    SDL_Rect clip;    Uint32 tmpflags = 0;    int w = 0;    int h = 0;    int bpp = 0;    int grabmouse = (SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_ON);    int showmouse = SDL_ShowCursor(-1);#if 0    SDL_Color *palette = NULL;    int ncolors = 0;#endif    sdldebug("attempting to toggle fullscreen flag...");    if ( (!surface) || (!(*surface)) )  /* don't try if there's no surface. */    {        sdldebug("Null surface (?!). Not toggling fullscreen flag.");        return(0);    } /* if */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -