|
|
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.