|
|
1.1 ! root 1: #include <stdlib.h> /* getenv()/exit()/atexit() */ ! 2: #include <stdio.h> /* NULL */ ! 3: ! 4: #include <SDL.h> ! 5: #ifndef main ! 6: #define USE_REAL_MAIN ! 7: #endif ! 8: #include "gen_defs.h" ! 9: #ifdef USE_REAL_MAIN ! 10: #undef main ! 11: #endif ! 12: #include "sdlfuncs.h" ! 13: ! 14: #ifndef _WIN32 ! 15: struct sdlfuncs sdl; ! 16: #endif ! 17: ! 18: /* Make xp_dl do static linking */ ! 19: #ifdef STATIC_SDL ! 20: #define STATIC_LINK ! 21: #endif ! 22: #include <xp_dl.h> ! 23: ! 24: static int sdl_funcs_loaded=0; ! 25: static int sdl_initialized=0; ! 26: static int sdl_audio_initialized=0; ! 27: static int sdl_video_initialized=0; ! 28: static int (*sdl_drawing_thread)(void *data)=NULL; ! 29: static void (*sdl_exit_drawing_thread)(void)=NULL; ! 30: static int main_returned=0; ! 31: static SDL_sem *sdl_main_sem; ! 32: SDL_sem *sdl_exit_sem; ! 33: ! 34: int CIOLIB_main(int argc, char **argv, char **enviro); ! 35: ! 36: int load_sdl_funcs(struct sdlfuncs *sdlf) ! 37: { ! 38: dll_handle sdl_dll; ! 39: const char *libnames[]={"SDL", "SDL-1.2", "SDL-1.1", NULL}; ! 40: ! 41: putenv("SDL_VIDEO_ALLOW_SCREENSAVER=1"); ! 42: sdlf->gotfuncs=0; ! 43: if((sdl_dll=xp_dlopen(libnames,RTLD_LAZY|RTLD_GLOBAL,SDL_PATCHLEVEL))==NULL) ! 44: return(-1); ! 45: ! 46: #ifdef _WIN32 ! 47: if((sdlf->SetModuleHandle=xp_dlsym(sdl_dll, SDL_SetModuleHandle))==NULL) { ! 48: xp_dlclose(sdl_dll); ! 49: return(-1); ! 50: } ! 51: #endif ! 52: if((sdlf->Init=xp_dlsym(sdl_dll, SDL_Init))==NULL) { ! 53: xp_dlclose(sdl_dll); ! 54: return(-1); ! 55: } ! 56: if((sdlf->Quit=xp_dlsym(sdl_dll, SDL_Quit))==NULL) { ! 57: xp_dlclose(sdl_dll); ! 58: return(-1); ! 59: } ! 60: if((sdlf->mutexP=xp_dlsym(sdl_dll, SDL_mutexP))==NULL) { ! 61: xp_dlclose(sdl_dll); ! 62: return(-1); ! 63: } ! 64: if((sdlf->mutexV=xp_dlsym(sdl_dll, SDL_mutexV))==NULL) { ! 65: xp_dlclose(sdl_dll); ! 66: return(-1); ! 67: } ! 68: if((sdlf->PeepEvents=xp_dlsym(sdl_dll, SDL_PeepEvents))==NULL) { ! 69: xp_dlclose(sdl_dll); ! 70: return(-1); ! 71: } ! 72: if((sdlf->VideoDriverName=xp_dlsym(sdl_dll, SDL_VideoDriverName))==NULL) { ! 73: xp_dlclose(sdl_dll); ! 74: return(-1); ! 75: } ! 76: if((sdlf->SemWait=xp_dlsym(sdl_dll, SDL_SemWait))==NULL) { ! 77: xp_dlclose(sdl_dll); ! 78: return(-1); ! 79: } ! 80: if((sdlf->SemPost=xp_dlsym(sdl_dll, SDL_SemPost))==NULL) { ! 81: xp_dlclose(sdl_dll); ! 82: return(-1); ! 83: } ! 84: if((sdlf->EventState=xp_dlsym(sdl_dll, SDL_EventState))==NULL) { ! 85: xp_dlclose(sdl_dll); ! 86: return(-1); ! 87: } ! 88: if((sdlf->CreateRGBSurface=xp_dlsym(sdl_dll, SDL_CreateRGBSurface))==NULL) { ! 89: xp_dlclose(sdl_dll); ! 90: return(-1); ! 91: } ! 92: if((sdlf->CreateRGBSurfaceFrom=xp_dlsym(sdl_dll, SDL_CreateRGBSurfaceFrom))==NULL) { ! 93: xp_dlclose(sdl_dll); ! 94: return(-1); ! 95: } ! 96: if((sdlf->FillRect=xp_dlsym(sdl_dll, SDL_FillRect))==NULL) { ! 97: xp_dlclose(sdl_dll); ! 98: return(-1); ! 99: } ! 100: if((sdlf->SetColors=xp_dlsym(sdl_dll, SDL_SetColors))==NULL) { ! 101: xp_dlclose(sdl_dll); ! 102: return(-1); ! 103: } ! 104: if((sdlf->BlitSurface=xp_dlsym(sdl_dll, SDL_UpperBlit))==NULL) { ! 105: xp_dlclose(sdl_dll); ! 106: return(-1); ! 107: } ! 108: if((sdlf->UpdateRects=xp_dlsym(sdl_dll, SDL_UpdateRects))==NULL) { ! 109: xp_dlclose(sdl_dll); ! 110: return(-1); ! 111: } ! 112: if((sdlf->UpdateRect=xp_dlsym(sdl_dll, SDL_UpdateRect))==NULL) { ! 113: xp_dlclose(sdl_dll); ! 114: return(-1); ! 115: } ! 116: if((sdlf->SDL_CreateSemaphore=xp_dlsym(sdl_dll, SDL_CreateSemaphore))==NULL) { ! 117: xp_dlclose(sdl_dll); ! 118: return(-1); ! 119: } ! 120: if((sdlf->SDL_DestroySemaphore=xp_dlsym(sdl_dll, SDL_DestroySemaphore))==NULL) { ! 121: xp_dlclose(sdl_dll); ! 122: return(-1); ! 123: } ! 124: if((sdlf->SDL_CreateMutex=xp_dlsym(sdl_dll, SDL_CreateMutex))==NULL) { ! 125: xp_dlclose(sdl_dll); ! 126: return(-1); ! 127: } ! 128: if((sdlf->CreateThread=xp_dlsym(sdl_dll, SDL_CreateThread))==NULL) { ! 129: xp_dlclose(sdl_dll); ! 130: return(-1); ! 131: } ! 132: if((sdlf->KillThread=xp_dlsym(sdl_dll, SDL_KillThread))==NULL) { ! 133: xp_dlclose(sdl_dll); ! 134: return(-1); ! 135: } ! 136: if((sdlf->WaitThread=xp_dlsym(sdl_dll, SDL_WaitThread))==NULL) { ! 137: xp_dlclose(sdl_dll); ! 138: return(-1); ! 139: } ! 140: if((sdlf->WaitEvent=xp_dlsym(sdl_dll, SDL_WaitEvent))==NULL) { ! 141: xp_dlclose(sdl_dll); ! 142: return(-1); ! 143: } ! 144: if((sdlf->SetVideoMode=xp_dlsym(sdl_dll, SDL_SetVideoMode))==NULL) { ! 145: xp_dlclose(sdl_dll); ! 146: return(-1); ! 147: } ! 148: if((sdlf->FreeSurface=xp_dlsym(sdl_dll, SDL_FreeSurface))==NULL) { ! 149: xp_dlclose(sdl_dll); ! 150: return(-1); ! 151: } ! 152: if((sdlf->WM_SetCaption=xp_dlsym(sdl_dll, SDL_WM_SetCaption))==NULL) { ! 153: xp_dlclose(sdl_dll); ! 154: return(-1); ! 155: } ! 156: if((sdlf->WM_SetIcon=xp_dlsym(sdl_dll, SDL_WM_SetIcon))==NULL) { ! 157: xp_dlclose(sdl_dll); ! 158: return(-1); ! 159: } ! 160: if((sdlf->ShowCursor=xp_dlsym(sdl_dll, SDL_ShowCursor))==NULL) { ! 161: xp_dlclose(sdl_dll); ! 162: return(-1); ! 163: } ! 164: if((sdlf->WasInit=xp_dlsym(sdl_dll, SDL_WasInit))==NULL) { ! 165: xp_dlclose(sdl_dll); ! 166: return(-1); ! 167: } ! 168: if((sdlf->EnableUNICODE=xp_dlsym(sdl_dll, SDL_EnableUNICODE))==NULL) { ! 169: xp_dlclose(sdl_dll); ! 170: return(-1); ! 171: } ! 172: if((sdlf->EnableKeyRepeat=xp_dlsym(sdl_dll, SDL_EnableKeyRepeat))==NULL) { ! 173: xp_dlclose(sdl_dll); ! 174: return(-1); ! 175: } ! 176: if((sdlf->GetWMInfo=xp_dlsym(sdl_dll, SDL_GetWMInfo))==NULL) { ! 177: xp_dlclose(sdl_dll); ! 178: return(-1); ! 179: } ! 180: if((sdlf->GetError=xp_dlsym(sdl_dll, SDL_GetError))==NULL) { ! 181: xp_dlclose(sdl_dll); ! 182: return(-1); ! 183: } ! 184: if((sdlf->InitSubSystem=xp_dlsym(sdl_dll, SDL_InitSubSystem))==NULL) { ! 185: xp_dlclose(sdl_dll); ! 186: return(-1); ! 187: } ! 188: if((sdlf->QuitSubSystem=xp_dlsym(sdl_dll, SDL_QuitSubSystem))==NULL) { ! 189: xp_dlclose(sdl_dll); ! 190: return(-1); ! 191: } ! 192: if((sdlf->OpenAudio=xp_dlsym(sdl_dll, SDL_OpenAudio))==NULL) { ! 193: xp_dlclose(sdl_dll); ! 194: return(-1); ! 195: } ! 196: if((sdlf->CloseAudio=xp_dlsym(sdl_dll, SDL_CloseAudio))==NULL) { ! 197: xp_dlclose(sdl_dll); ! 198: return(-1); ! 199: } ! 200: if((sdlf->PauseAudio=xp_dlsym(sdl_dll, SDL_PauseAudio))==NULL) { ! 201: xp_dlclose(sdl_dll); ! 202: return(-1); ! 203: } ! 204: if((sdlf->LockAudio=xp_dlsym(sdl_dll, SDL_LockAudio))==NULL) { ! 205: xp_dlclose(sdl_dll); ! 206: return(-1); ! 207: } ! 208: if((sdlf->UnlockAudio=xp_dlsym(sdl_dll, SDL_UnlockAudio))==NULL) { ! 209: xp_dlclose(sdl_dll); ! 210: return(-1); ! 211: } ! 212: if((sdlf->GetAudioStatus=xp_dlsym(sdl_dll, SDL_GetAudioStatus))==NULL) { ! 213: xp_dlclose(sdl_dll); ! 214: return(-1); ! 215: } ! 216: if((sdlf->MapRGB=xp_dlsym(sdl_dll, SDL_MapRGB))==NULL) { ! 217: xp_dlclose(sdl_dll); ! 218: return(-1); ! 219: } ! 220: if((sdlf->LockSurface=xp_dlsym(sdl_dll, SDL_LockSurface))==NULL) { ! 221: xp_dlclose(sdl_dll); ! 222: return(-1); ! 223: } ! 224: if((sdlf->UnlockSurface=xp_dlsym(sdl_dll, SDL_UnlockSurface))==NULL) { ! 225: xp_dlclose(sdl_dll); ! 226: return(-1); ! 227: } ! 228: if((sdlf->DisplayFormat=xp_dlsym(sdl_dll, SDL_DisplayFormat))==NULL) { ! 229: xp_dlclose(sdl_dll); ! 230: return(-1); ! 231: } ! 232: if((sdlf->Flip=xp_dlsym(sdl_dll, SDL_Flip))==NULL) { ! 233: xp_dlclose(sdl_dll); ! 234: return(-1); ! 235: } ! 236: if((sdlf->CreateYUVOverlay=xp_dlsym(sdl_dll, SDL_CreateYUVOverlay))==NULL) { ! 237: xp_dlclose(sdl_dll); ! 238: return(-1); ! 239: } ! 240: if((sdlf->DisplayYUVOverlay=xp_dlsym(sdl_dll, SDL_DisplayYUVOverlay))==NULL) { ! 241: xp_dlclose(sdl_dll); ! 242: return(-1); ! 243: } ! 244: if((sdlf->FreeYUVOverlay=xp_dlsym(sdl_dll, SDL_FreeYUVOverlay))==NULL) { ! 245: xp_dlclose(sdl_dll); ! 246: return(-1); ! 247: } ! 248: if((sdlf->LockYUVOverlay=xp_dlsym(sdl_dll, SDL_LockYUVOverlay))==NULL) { ! 249: xp_dlclose(sdl_dll); ! 250: return(-1); ! 251: } ! 252: if((sdlf->UnlockYUVOverlay=xp_dlsym(sdl_dll, SDL_UnlockYUVOverlay))==NULL) { ! 253: xp_dlclose(sdl_dll); ! 254: return(-1); ! 255: } ! 256: if((sdlf->GetVideoInfo=xp_dlsym(sdl_dll, SDL_GetVideoInfo))==NULL) { ! 257: xp_dlclose(sdl_dll); ! 258: return(-1); ! 259: } ! 260: if((sdlf->Linked_Version=xp_dlsym(sdl_dll, SDL_Linked_Version))==NULL) { ! 261: xp_dlclose(sdl_dll); ! 262: return(-1); ! 263: } ! 264: sdlf->gotfuncs=1; ! 265: sdl_funcs_loaded=1; ! 266: return(0); ! 267: } ! 268: ! 269: int init_sdl_video(void) ! 270: { ! 271: /* This is all handled in SDL_main_env() */ ! 272: if(sdl_video_initialized) ! 273: return(0); ! 274: else ! 275: return(-1); ! 276: } ! 277: ! 278: int init_sdl_audio(void) ! 279: { ! 280: if(!sdl_initialized) ! 281: return(-1); ! 282: if(sdl_audio_initialized) ! 283: return(0); ! 284: if(sdl.InitSubSystem(SDL_INIT_AUDIO)==0) { ! 285: sdl_audio_initialized=TRUE; ! 286: return(0); ! 287: } ! 288: return(-1); ! 289: } ! 290: ! 291: struct main_args { ! 292: int argc; ! 293: char **argv; ! 294: char **enviro; ! 295: }; ! 296: ! 297: static int sdl_run_main(void *data) ! 298: { ! 299: struct main_args *args; ! 300: int ret; ! 301: ! 302: args=data; ! 303: ret=CIOLIB_main(args->argc, args->argv, args->enviro); ! 304: main_returned=1; ! 305: sdl.SemPost(sdl_main_sem); ! 306: if(sdl_exit_drawing_thread!=NULL) ! 307: sdl_exit_drawing_thread(); ! 308: sdl.SemPost(sdl_exit_sem); ! 309: return(ret); ! 310: } ! 311: ! 312: void run_sdl_drawing_thread(int (*drawing_thread)(void *data), void (*exit_drawing_thread)(void)) ! 313: { ! 314: sdl_drawing_thread=drawing_thread; ! 315: sdl_exit_drawing_thread=exit_drawing_thread; ! 316: sdl.SemPost(sdl_main_sem); ! 317: } ! 318: ! 319: #ifndef main ! 320: int main(int argc, char **argv, char **env) ! 321: #else ! 322: int SDL_main_env(int argc, char **argv, char **env) ! 323: #endif ! 324: { ! 325: char drivername[64]; ! 326: struct main_args ma; ! 327: SDL_Thread *main_thread; ! 328: int main_ret; ! 329: int use_sdl_video=FALSE; ! 330: #ifdef _WIN32 ! 331: char *driver_env=NULL; ! 332: #endif ! 333: ! 334: ma.argc=argc; ! 335: ma.argv=argv; ! 336: ma.enviro=env; ! 337: #ifndef _WIN32 ! 338: load_sdl_funcs(&sdl); ! 339: #endif ! 340: ! 341: if(sdl.gotfuncs) { ! 342: use_sdl_video=TRUE; ! 343: ! 344: #ifdef _WIN32 ! 345: /* Fail to windib (ie: No mouse attached) */ ! 346: if(sdl.Init(SDL_INIT_VIDEO)) { ! 347: driver_env=getenv("SDL_VIDEODRIVER"); ! 348: if(driver_env==NULL || strcmp(driver_env,"windib")) { ! 349: putenv("SDL_VIDEODRIVER=windib"); ! 350: WinExec(GetCommandLine(), SW_SHOWDEFAULT); ! 351: return(0); ! 352: } ! 353: /* Sure ,we can't use video, but audio is still valid! */ ! 354: if(sdl.Init(0)==0) ! 355: sdl_initialized=TRUE; ! 356: } ! 357: else { ! 358: sdl_video_initialized=TRUE; ! 359: sdl_initialized=TRUE; ! 360: } ! 361: #else ! 362: /* ! 363: * On Linux, SDL doesn't properly detect availability of the ! 364: * framebuffer apparently. This results in remote connections ! 365: * displaying on the local framebuffer... a definate no-no. ! 366: * This ugly hack attempts to prevent this... of course, remote X11 ! 367: * connections must still be allowed. ! 368: */ ! 369: if((!use_sdl_video) || ((getenv("REMOTEHOST")!=NULL || getenv("SSH_CLIENT")!=NULL) && getenv("DISPLAY")==NULL)) { ! 370: /* Sure ,we can't use video, but audio is still valid! */ ! 371: if(sdl.Init(0)==0) ! 372: sdl_initialized=TRUE; ! 373: } ! 374: else { ! 375: if(sdl.Init(SDL_INIT_VIDEO)==0) { ! 376: sdl_initialized=TRUE; ! 377: sdl_video_initialized=TRUE; ! 378: } ! 379: else { ! 380: /* Sure ,we can't use video, but audio is still valid! */ ! 381: if(sdl.Init(0)==0) ! 382: sdl_initialized=TRUE; ! 383: } ! 384: } ! 385: #endif ! 386: if(sdl_video_initialized && sdl.VideoDriverName(drivername, sizeof(drivername))!=NULL) { ! 387: /* Unacceptable drivers */ ! 388: if((!strcmp(drivername, "caca")) || (!strcmp(drivername,"aalib")) || (!strcmp(drivername,"dummy"))) { ! 389: sdl.QuitSubSystem(SDL_INIT_VIDEO); ! 390: sdl_video_initialized=FALSE; ! 391: } ! 392: else { ! 393: const SDL_VideoInfo *initial=sdl.GetVideoInfo(); ! 394: ! 395: /* Save initial video mode */ ! 396: if(initial) ! 397: sdl.initial_videoinfo=*initial; ! 398: else ! 399: memset(&sdl.initial_videoinfo, 0, sizeof(sdl.initial_videoinfo)); ! 400: sdl_video_initialized=TRUE; ! 401: } ! 402: } ! 403: } ! 404: if(sdl_video_initialized) { ! 405: atexit(sdl.Quit); ! 406: sdl_main_sem=sdl.SDL_CreateSemaphore(0); ! 407: sdl_exit_sem=sdl.SDL_CreateSemaphore(0); ! 408: main_thread=sdl.CreateThread(sdl_run_main,&ma); ! 409: sdl.SemWait(sdl_main_sem); ! 410: if(sdl_drawing_thread!=NULL) { ! 411: sdl_drawing_thread(NULL); ! 412: sdl_exit_drawing_thread=NULL; ! 413: if(!main_returned) { ! 414: main_ret=0; ! 415: } ! 416: } ! 417: sdl.SemWait(sdl_exit_sem); ! 418: if(main_returned) ! 419: sdl.WaitThread(main_thread, &main_ret); ! 420: } ! 421: else ! 422: main_ret=CIOLIB_main(argc, argv, env); ! 423: return(main_ret); ! 424: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.