Annotation of quake2/irix/vid_so.c, revision 1.1.1.1

1.1       root        1: // Main windowed and fullscreen graphics interface module. This module
                      2: // is used for both the software and OpenGL rendering versions of the
                      3: // Quake refresh engine.
                      4: 
                      5: #define SO_FILE "/etc/quake2.conf"
                      6: 
                      7: #include <errno.h>
                      8: #include <assert.h>
                      9: #include <dlfcn.h> // ELF dl loader
                     10: #include <sys/stat.h>
                     11: #include <unistd.h>
                     12: 
                     13: #include "../client/client.h"
                     14: 
                     15: #include "../linux/rw_linux.h"
                     16: 
                     17: // Structure containing functions exported from refresh DLL
                     18: refexport_t    re;
                     19: 
                     20: #ifdef REF_HARD_LINKED
                     21: refexport_t GetRefAPI (refimport_t rimp);
                     22: #endif
                     23: 
                     24: // Console variables that we need to access from this module
                     25: cvar_t         *vid_gamma;
                     26: cvar_t         *vid_ref;                       // Name of Refresh DLL loaded
                     27: cvar_t         *vid_xpos;                      // X coordinate of window position
                     28: cvar_t         *vid_ypos;                      // Y coordinate of window position
                     29: cvar_t         *vid_fullscreen;
                     30: 
                     31: // Global variables used internally by this module
                     32: viddef_t       viddef;                         // global video state; used by other modules
                     33: void           *reflib_library;                // Handle to refresh DLL 
                     34: qboolean       reflib_active = 0;
                     35: 
                     36: #define VID_NUM_MODES ( sizeof( vid_modes ) / sizeof( vid_modes[0] ) )
                     37: 
                     38: /** KEYBOARD **************************************************************/
                     39: 
                     40: void Do_Key_Event(int key, qboolean down);
                     41: 
                     42: void (*KBD_Update_fp)(void);
                     43: void (*KBD_Init_fp)(Key_Event_fp_t fp);
                     44: void (*KBD_Close_fp)(void);
                     45: 
                     46: /** MOUSE *****************************************************************/
                     47: 
                     48: in_state_t in_state;
                     49: 
                     50: void (*RW_IN_Init_fp)(in_state_t *in_state_p);
                     51: void (*RW_IN_Shutdown_fp)(void);
                     52: void (*RW_IN_Activate_fp)(qboolean active);
                     53: void (*RW_IN_Commands_fp)(void);
                     54: void (*RW_IN_Move_fp)(usercmd_t *cmd);
                     55: void (*RW_IN_Frame_fp)(void);
                     56: 
                     57: void Real_IN_Init (void);
                     58: 
                     59: /*
                     60: ==========================================================================
                     61: 
                     62: DLL GLUE
                     63: 
                     64: ==========================================================================
                     65: */
                     66: 
                     67: #define        MAXPRINTMSG     4096
                     68: void VID_Printf (int print_level, char *fmt, ...)
                     69: {
                     70:        va_list         argptr;
                     71:        char            msg[MAXPRINTMSG];
                     72:        static qboolean inupdate;
                     73:        
                     74:        va_start (argptr,fmt);
                     75:        vsprintf (msg,fmt,argptr);
                     76:        va_end (argptr);
                     77: 
                     78:        if (print_level == PRINT_ALL)
                     79:                Com_Printf ("%s", msg);
                     80:        else
                     81:                Com_DPrintf ("%s", msg);
                     82: }
                     83: 
                     84: void VID_Error (int err_level, char *fmt, ...)
                     85: {
                     86:        va_list         argptr;
                     87:        char            msg[MAXPRINTMSG];
                     88:        static qboolean inupdate;
                     89:        
                     90:        va_start (argptr,fmt);
                     91:        vsprintf (msg,fmt,argptr);
                     92:        va_end (argptr);
                     93: 
                     94:        Com_Error (err_level,"%s", msg);
                     95: }
                     96: 
                     97: //==========================================================================
                     98: 
                     99: /*
                    100: ============
                    101: VID_Restart_f
                    102: 
                    103: Console command to re-start the video mode and refresh DLL. We do this
                    104: simply by setting the modified flag for the vid_ref variable, which will
                    105: cause the entire video mode and refresh DLL to be reset on the next frame.
                    106: ============
                    107: */
                    108: void VID_Restart_f (void)
                    109: {
                    110:        vid_ref->modified = true;
                    111: }
                    112: 
                    113: /*
                    114: ** VID_GetModeInfo
                    115: */
                    116: typedef struct vidmode_s
                    117: {
                    118:        const char *description;
                    119:        int         width, height;
                    120:        int         mode;
                    121: } vidmode_t;
                    122: 
                    123: vidmode_t vid_modes[] =
                    124: {
                    125:        { "Mode 0: 320x240",   320, 240,   0 },
                    126:        { "Mode 1: 400x300",   400, 300,   1 },
                    127:        { "Mode 2: 512x384",   512, 384,   2 },
                    128:        { "Mode 3: 640x480",   640, 480,   3 },
                    129:        { "Mode 4: 800x600",   800, 600,   4 },
                    130:        { "Mode 5: 960x720",   960, 720,   5 },
                    131:        { "Mode 6: 1024x768",  1024, 768,  6 },
                    132:        { "Mode 7: 1152x864",  1152, 864,  7 },
                    133:        { "Mode 8: 1280x1024",  1280, 1024, 8 },
                    134:        { "Mode 9: 1600x1200", 1600, 1200, 9 }
                    135: };
                    136: 
                    137: qboolean VID_GetModeInfo( int *width, int *height, int mode )
                    138: {
                    139:        if ( mode < 0 || mode >= VID_NUM_MODES )
                    140:                return false;
                    141: 
                    142:        *width  = vid_modes[mode].width;
                    143:        *height = vid_modes[mode].height;
                    144: 
                    145:        return true;
                    146: }
                    147: 
                    148: /*
                    149: ** VID_NewWindow
                    150: */
                    151: void VID_NewWindow ( int width, int height)
                    152: {
                    153:        viddef.width  = width;
                    154:        viddef.height = height;
                    155: }
                    156: 
                    157: void VID_FreeReflib (void)
                    158: {
                    159:        if (reflib_library) {
                    160:                if (KBD_Close_fp)
                    161:                        KBD_Close_fp();
                    162:                if (RW_IN_Shutdown_fp)
                    163:                        RW_IN_Shutdown_fp();
                    164: #ifndef REF_HARD_LINKED
                    165:                dlclose(reflib_library);
                    166: #endif
                    167:        }
                    168: 
                    169:        KBD_Init_fp = NULL;
                    170:        KBD_Update_fp = NULL;
                    171:        KBD_Close_fp = NULL;
                    172:        RW_IN_Init_fp = NULL;
                    173:        RW_IN_Shutdown_fp = NULL;
                    174:        RW_IN_Activate_fp = NULL;
                    175:        RW_IN_Commands_fp = NULL;
                    176:        RW_IN_Move_fp = NULL;
                    177:        RW_IN_Frame_fp = NULL;
                    178: 
                    179:        memset (&re, 0, sizeof(re));
                    180:        reflib_library = NULL;
                    181:        reflib_active  = false;
                    182: }
                    183: 
                    184: /*
                    185: ==============
                    186: VID_LoadRefresh
                    187: ==============
                    188: */
                    189: qboolean VID_LoadRefresh( char *name )
                    190: {
                    191:        refimport_t     ri;
                    192: #ifndef REF_HARD_LINKED
                    193:        GetRefAPI_t     GetRefAPI;
                    194: #endif
                    195:        char    fn[MAX_OSPATH];
                    196:        struct stat st;
                    197:        extern uid_t saved_euid;
                    198:        FILE *fp;
                    199:        char    *path;
                    200:        char    curpath[MAX_OSPATH];
                    201: 
                    202:        if ( reflib_active )
                    203:        {
                    204:                if (KBD_Close_fp)
                    205:                        KBD_Close_fp();
                    206:                if (RW_IN_Shutdown_fp)
                    207:                        RW_IN_Shutdown_fp();
                    208:                KBD_Close_fp = NULL;
                    209:                RW_IN_Shutdown_fp = NULL;
                    210:                re.Shutdown();
                    211:                VID_FreeReflib ();
                    212:        }
                    213: 
                    214: #ifndef REF_HARD_LINKED
                    215:        getcwd(curpath, sizeof(curpath));
                    216:        
                    217:        Com_Printf( "------- Loading %s -------\n", name );
                    218: 
                    219:        // now run through the search paths
                    220:        path = NULL;
                    221:        while (1)
                    222:        {
                    223:                path = FS_NextPath (path);
                    224:                if (!path)
                    225:                        return NULL;            // couldn't find one anywhere
                    226:                sprintf (fn, "%s/%s/%s", curpath, path, name);
                    227:                Com_Printf ("Trying to load library (%s)\n", fn);
                    228: 
                    229:                reflib_library = dlopen( fn, RTLD_NOW );
                    230:                if (reflib_library)
                    231:                {
                    232:                        Com_DPrintf ("LoadLibrary (%s)\n",name);
                    233:                        break;
                    234:                }
                    235:        }
                    236: 
                    237: #endif
                    238: 
                    239:        ri.Cmd_AddCommand = Cmd_AddCommand;
                    240:        ri.Cmd_RemoveCommand = Cmd_RemoveCommand;
                    241:        ri.Cmd_Argc = Cmd_Argc;
                    242:        ri.Cmd_Argv = Cmd_Argv;
                    243:        ri.Cmd_ExecuteText = Cbuf_ExecuteText;
                    244:        ri.Con_Printf = VID_Printf;
                    245:        ri.Sys_Error = VID_Error;
                    246:        ri.FS_LoadFile = FS_LoadFile;
                    247:        ri.FS_FreeFile = FS_FreeFile;
                    248:        ri.FS_Gamedir = FS_Gamedir;
                    249:        ri.Cvar_Get = Cvar_Get;
                    250:        ri.Cvar_Set = Cvar_Set;
                    251:        ri.Cvar_SetValue = Cvar_SetValue;
                    252:        ri.Vid_GetModeInfo = VID_GetModeInfo;
                    253:        ri.Vid_MenuInit = VID_MenuInit;
                    254:        ri.Vid_NewWindow = VID_NewWindow;
                    255: 
                    256: #ifndef REF_HARD_LINKED
                    257:        if ( ( GetRefAPI = (void *) dlsym( reflib_library, "GetRefAPI" ) ) == 0 )
                    258:                Com_Error( ERR_FATAL, "dlsym failed on %s", name );
                    259: #endif
                    260:        re = GetRefAPI( ri );
                    261: 
                    262:        if (re.api_version != API_VERSION)
                    263:        {
                    264:                VID_FreeReflib ();
                    265:                Com_Error (ERR_FATAL, "%s has incompatible api_version", name);
                    266:        }
                    267: 
                    268:        /* Init IN (Mouse) */
                    269:        in_state.IN_CenterView_fp = IN_CenterView;
                    270:        in_state.Key_Event_fp = Do_Key_Event;
                    271:        in_state.viewangles = cl.viewangles;
                    272:        in_state.in_strafe_state = &in_strafe.state;
                    273: 
                    274: #ifndef REF_HARD_LINKED
                    275:        if ((RW_IN_Init_fp = dlsym(reflib_library, "RW_IN_Init")) == NULL ||
                    276:                (RW_IN_Shutdown_fp = dlsym(reflib_library, "RW_IN_Shutdown")) == NULL ||
                    277:                (RW_IN_Activate_fp = dlsym(reflib_library, "RW_IN_Activate")) == NULL ||
                    278:                (RW_IN_Commands_fp = dlsym(reflib_library, "RW_IN_Commands")) == NULL ||
                    279:                (RW_IN_Move_fp = dlsym(reflib_library, "RW_IN_Move")) == NULL ||
                    280:                (RW_IN_Frame_fp = dlsym(reflib_library, "RW_IN_Frame")) == NULL)
                    281:                Sys_Error("No RW_IN functions in REF.\n");
                    282: #else
                    283:        {
                    284:            void RW_IN_Init(in_state_t *in_state_p);
                    285:            void RW_IN_Shutdown(void);
                    286:            void RW_IN_Commands (void);
                    287:            void RW_IN_Move (usercmd_t *cmd);
                    288:            void RW_IN_Frame (void);
                    289:            void RW_IN_Activate(void);
                    290: 
                    291:            RW_IN_Init_fp = RW_IN_Init;
                    292:            RW_IN_Shutdown_fp = RW_IN_Shutdown;
                    293:            RW_IN_Activate_fp = RW_IN_Activate;
                    294:            RW_IN_Commands_fp = RW_IN_Commands;
                    295:            RW_IN_Move_fp = RW_IN_Move;
                    296:            RW_IN_Frame_fp = RW_IN_Frame;
                    297:        }
                    298: #endif
                    299: 
                    300:        if ( re.Init( 0, 0 ) == -1 )
                    301:        {
                    302:                re.Shutdown();
                    303:                VID_FreeReflib ();
                    304:                return false;
                    305:        }
                    306: 
                    307:        // give up root now
                    308:        setreuid(getuid(), getuid());
                    309:        setegid(getgid());
                    310: 
                    311:        /* Init KBD */
                    312: #ifndef REF_HARD_LINKED
                    313:        if ((KBD_Init_fp = dlsym(reflib_library, "KBD_Init")) == NULL ||
                    314:                (KBD_Update_fp = dlsym(reflib_library, "KBD_Update")) == NULL ||
                    315:                (KBD_Close_fp = dlsym(reflib_library, "KBD_Close")) == NULL)
                    316:                Sys_Error("No KBD functions in REF.\n");
                    317: #else
                    318:        {
                    319:                void KBD_Init(void);
                    320:                void KBD_Update(void);
                    321:                void KBD_Close(void);
                    322: 
                    323:                KBD_Init_fp = KBD_Init;
                    324:                KBD_Update_fp = KBD_Update;
                    325:                KBD_Close_fp = KBD_Close;
                    326:        }
                    327: #endif
                    328:        KBD_Init_fp(Do_Key_Event);
                    329:        Real_IN_Init();
                    330: 
                    331:        Com_Printf( "------------------------------------\n");
                    332:        reflib_active = true;
                    333:        return true;
                    334: }
                    335: 
                    336: /*
                    337: ============
                    338: VID_CheckChanges
                    339: 
                    340: This function gets called once just before drawing each frame, and it's sole purpose in life
                    341: is to check to see if any of the video mode parameters have changed, and if they have to 
                    342: update the rendering DLL and/or video mode to match.
                    343: ============
                    344: */
                    345: void VID_CheckChanges (void)
                    346: {
                    347:        char name[100];
                    348:        cvar_t *sw_mode;
                    349: 
                    350:        if ( vid_ref->modified )
                    351:        {
                    352:                S_StopAllSounds();
                    353:        }
                    354: 
                    355:        while (vid_ref->modified)
                    356:        {
                    357:                /*
                    358:                ** refresh has changed
                    359:                */
                    360:                vid_ref->modified = false;
                    361:                vid_fullscreen->modified = true;
                    362:                cl.refresh_prepped = false;
                    363:                cls.disable_screen = true;
                    364: 
                    365:                sprintf( name, "ref_%s.so", vid_ref->string );
                    366:                if ( !VID_LoadRefresh( name ) )
                    367:                {
                    368:                        if ( strcmp (vid_ref->string, "soft") == 0 ) {
                    369:                                Com_Printf("Refresh failed\n");
                    370:                                sw_mode = Cvar_Get( "sw_mode", "0", 0 );
                    371:                                if (sw_mode->value != 0) {
                    372:                                        Com_Printf("Trying mode 0\n");
                    373:                                        Cvar_SetValue("sw_mode", 0);
                    374:                                        if ( !VID_LoadRefresh( name ) )
                    375:                                                Com_Error (ERR_FATAL, "Couldn't fall back to software refresh!");
                    376:                                } else
                    377:                                        Com_Error (ERR_FATAL, "Couldn't fall back to software refresh!");
                    378:                        }
                    379: 
                    380:                        Cvar_Set( "vid_ref", "soft" );
                    381: 
                    382:                        /*
                    383:                        ** drop the console if we fail to load a refresh
                    384:                        */
                    385:                        if ( cls.key_dest != key_console )
                    386:                        {
                    387:                                Con_ToggleConsole_f();
                    388:                        }
                    389:                }
                    390:                cls.disable_screen = false;
                    391:        }
                    392: 
                    393: }
                    394: 
                    395: /*
                    396: ============
                    397: VID_Init
                    398: ============
                    399: */
                    400: void VID_Init (void)
                    401: {
                    402:        /* Create the video variables so we know how to start the graphics drivers */
                    403:         vid_ref = Cvar_Get ("vid_ref", "soft", CVAR_ARCHIVE);
                    404:        vid_xpos = Cvar_Get ("vid_xpos", "3", CVAR_ARCHIVE);
                    405:        vid_ypos = Cvar_Get ("vid_ypos", "22", CVAR_ARCHIVE);
                    406:        vid_fullscreen = Cvar_Get ("vid_fullscreen", "0", CVAR_ARCHIVE);
                    407:        vid_gamma = Cvar_Get( "vid_gamma", "1", CVAR_ARCHIVE );
                    408: 
                    409:        /* Add some console commands that we want to handle */
                    410:        Cmd_AddCommand ("vid_restart", VID_Restart_f);
                    411: 
                    412:        /* Disable the 3Dfx splash screen */
                    413:        putenv("FX_GLIDE_NO_SPLASH=0");
                    414:                
                    415:        /* Start the graphics mode and load refresh DLL */
                    416:        VID_CheckChanges();
                    417: }
                    418: 
                    419: /*
                    420: ============
                    421: VID_Shutdown
                    422: ============
                    423: */
                    424: void VID_Shutdown (void)
                    425: {
                    426:        if ( reflib_active )
                    427:        {
                    428:                if (KBD_Close_fp)
                    429:                        KBD_Close_fp();
                    430:                if (RW_IN_Shutdown_fp)
                    431:                        RW_IN_Shutdown_fp();
                    432:                KBD_Close_fp = NULL;
                    433:                RW_IN_Shutdown_fp = NULL;
                    434:                re.Shutdown ();
                    435:                VID_FreeReflib ();
                    436:        }
                    437: }
                    438: 
                    439: 
                    440: /*****************************************************************************/
                    441: /* INPUT                                                                     */
                    442: /*****************************************************************************/
                    443: 
                    444: cvar_t *in_joystick;
                    445: 
                    446: // This if fake, it's acutally done by the Refresh load
                    447: void IN_Init (void)
                    448: {
                    449:        in_joystick     = Cvar_Get ("in_joystick", "0", CVAR_ARCHIVE);
                    450: }
                    451: 
                    452: void Real_IN_Init (void)
                    453: {
                    454:        if (RW_IN_Init_fp)
                    455:                RW_IN_Init_fp(&in_state);
                    456: }
                    457: 
                    458: void IN_Shutdown (void)
                    459: {
                    460:        if (RW_IN_Shutdown_fp)
                    461:                RW_IN_Shutdown_fp();
                    462: }
                    463: 
                    464: void IN_Commands (void)
                    465: {
                    466:        if (RW_IN_Commands_fp)
                    467:                RW_IN_Commands_fp();
                    468: }
                    469: 
                    470: void IN_Move (usercmd_t *cmd)
                    471: {
                    472:        if (RW_IN_Move_fp)
                    473:                RW_IN_Move_fp(cmd);
                    474: }
                    475: 
                    476: void IN_Frame (void)
                    477: {
                    478:        if (RW_IN_Frame_fp)
                    479:                RW_IN_Frame_fp();
                    480: }
                    481: 
                    482: void IN_Activate (qboolean active)
                    483: {
                    484:        if (RW_IN_Activate_fp)
                    485:                RW_IN_Activate_fp(active);
                    486: }
                    487: 
                    488: void Do_Key_Event(int key, qboolean down)
                    489: {
                    490:        Key_Event(key, down, Sys_Milliseconds());
                    491: }
                    492: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.