Mercurial > sdl-ios-xcode
comparison src/video/xbios/SDL_xbios.c @ 978:3b1ba22f5a28
Add support for OpenGL on Atari using OSMesa, the offscreen rendering driver from Mesa
author | Patrice Mandin <patmandin@gmail.com> |
---|---|
date | Wed, 17 Nov 2004 23:13:15 +0000 |
parents | 15a7d0c44e73 |
children | c9d1ade1fb0b |
comparison
equal
deleted
inserted
replaced
977:9c55b00f8251 | 978:3b1ba22f5a28 |
---|---|
34 #include <stdio.h> | 34 #include <stdio.h> |
35 #include <stdlib.h> | 35 #include <stdlib.h> |
36 #include <string.h> | 36 #include <string.h> |
37 #include <sys/stat.h> | 37 #include <sys/stat.h> |
38 #include <unistd.h> | 38 #include <unistd.h> |
39 | |
40 #ifdef HAVE_OPENGL | |
41 #include <GL/osmesa.h> | |
42 #endif | |
39 | 43 |
40 /* Mint includes */ | 44 /* Mint includes */ |
41 #include <mint/cookie.h> | 45 #include <mint/cookie.h> |
42 #include <mint/osbind.h> | 46 #include <mint/osbind.h> |
43 #include <mint/falcon.h> | 47 #include <mint/falcon.h> |
72 static int XBIOS_FlipHWSurface(_THIS, SDL_Surface *surface); | 76 static int XBIOS_FlipHWSurface(_THIS, SDL_Surface *surface); |
73 static void XBIOS_UnlockHWSurface(_THIS, SDL_Surface *surface); | 77 static void XBIOS_UnlockHWSurface(_THIS, SDL_Surface *surface); |
74 static void XBIOS_FreeHWSurface(_THIS, SDL_Surface *surface); | 78 static void XBIOS_FreeHWSurface(_THIS, SDL_Surface *surface); |
75 static void XBIOS_UpdateRects(_THIS, int numrects, SDL_Rect *rects); | 79 static void XBIOS_UpdateRects(_THIS, int numrects, SDL_Rect *rects); |
76 | 80 |
81 #ifdef HAVE_OPENGL | |
82 /* OpenGL functions */ | |
83 static int XBIOS_GL_LoadLibrary(_THIS, const char *path); | |
84 static void *XBIOS_GL_GetProcAddress(_THIS, const char *proc); | |
85 static int XBIOS_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value); | |
86 static int XBIOS_GL_MakeCurrent(_THIS); | |
87 static void XBIOS_GL_SwapBuffers(_THIS); | |
88 #endif | |
89 | |
77 /* List of video modes */ | 90 /* List of video modes */ |
78 | 91 |
79 /* ST modes */ | 92 /* ST modes */ |
80 static int xbiosnummodes_st=1; | 93 static int xbiosnummodes_st=1; |
81 static xbiosmode_t xbiosmodelist_st[]={ | 94 static xbiosmode_t xbiosmodelist_st[]={ |
91 | 104 |
92 /* Falcon RVB modes */ | 105 /* Falcon RVB modes */ |
93 static int xbiosnummodes_f30rvb=16; | 106 static int xbiosnummodes_f30rvb=16; |
94 static xbiosmode_t xbiosmodelist_f30rvb[]={ | 107 static xbiosmode_t xbiosmodelist_f30rvb[]={ |
95 {BPS16|COL80|OVERSCAN|VERTFLAG,768,480,16,SDL_FALSE}, | 108 {BPS16|COL80|OVERSCAN|VERTFLAG,768,480,16,SDL_FALSE}, |
109 {BPS16|OVERSCAN|VERTFLAG,384,480,16,SDL_FALSE}, | |
110 {BPS16|COL80|VERTFLAG,640,400,16,SDL_FALSE}, | |
111 {BPS16|VERTFLAG,320,400,16,SDL_FALSE}, | |
96 {BPS16|COL80|OVERSCAN,768,240,16,SDL_FALSE}, | 112 {BPS16|COL80|OVERSCAN,768,240,16,SDL_FALSE}, |
97 {BPS16|COL80|VERTFLAG,640,400,16,SDL_FALSE}, | 113 {BPS16|OVERSCAN,384,240,16,SDL_FALSE}, |
98 {BPS16|COL80,640,200,16,SDL_FALSE}, | 114 {BPS16|COL80,640,200,16,SDL_FALSE}, |
99 {BPS16|OVERSCAN|VERTFLAG,384,480,16,SDL_FALSE}, | |
100 {BPS16|OVERSCAN,384,240,16,SDL_FALSE}, | |
101 {BPS16|VERTFLAG,320,400,16,SDL_FALSE}, | |
102 {BPS16,320,200,16,SDL_FALSE}, | 115 {BPS16,320,200,16,SDL_FALSE}, |
103 | 116 |
104 {BPS8|COL80|OVERSCAN|VERTFLAG,768,480,8,SDL_FALSE}, | 117 {BPS8|COL80|OVERSCAN|VERTFLAG,768,480,8,SDL_FALSE}, |
118 {BPS8|OVERSCAN|VERTFLAG,384,480,8,SDL_FALSE}, | |
119 {BPS8|COL80|VERTFLAG,640,400,8,SDL_FALSE}, | |
120 {BPS8|VERTFLAG,320,400,8,SDL_FALSE}, | |
105 {BPS8|COL80|OVERSCAN,768,240,8,SDL_FALSE}, | 121 {BPS8|COL80|OVERSCAN,768,240,8,SDL_FALSE}, |
106 {BPS8|COL80|VERTFLAG,640,400,8,SDL_FALSE}, | 122 {BPS8|OVERSCAN,384,240,8,SDL_FALSE}, |
107 {BPS8|COL80,640,200,8,SDL_FALSE}, | 123 {BPS8|COL80,640,200,8,SDL_FALSE}, |
108 {BPS8|OVERSCAN|VERTFLAG,384,480,8,SDL_FALSE}, | |
109 {BPS8|OVERSCAN,384,240,8,SDL_FALSE}, | |
110 {BPS8|VERTFLAG,320,400,8,SDL_FALSE}, | |
111 {BPS8,320,200,8,SDL_FALSE} | 124 {BPS8,320,200,8,SDL_FALSE} |
112 }; | 125 }; |
113 | 126 |
114 /* Falcon VGA modes */ | 127 /* Falcon VGA modes */ |
115 static int xbiosnummodes_f30vga=6; | 128 static int xbiosnummodes_f30vga=6; |
116 static xbiosmode_t xbiosmodelist_f30vga[]={ | 129 static xbiosmode_t xbiosmodelist_f30vga[]={ |
117 {BPS16,320,480,16,SDL_FALSE}, | 130 {BPS16,320,480,16,SDL_FALSE}, |
118 {BPS16|VERTFLAG,320,240,16,SDL_FALSE}, | 131 {BPS16|VERTFLAG,320,240,16,SDL_FALSE}, |
119 | 132 |
120 {BPS8|COL80,640,480,8,SDL_FALSE}, | 133 {BPS8|COL80,640,480,8,SDL_FALSE}, |
134 {BPS8,320,480,8,SDL_FALSE}, | |
121 {BPS8|COL80|VERTFLAG,640,240,8,SDL_FALSE}, | 135 {BPS8|COL80|VERTFLAG,640,240,8,SDL_FALSE}, |
122 {BPS8,320,480,8,SDL_FALSE}, | |
123 {BPS8|VERTFLAG,320,240,8,SDL_FALSE} | 136 {BPS8|VERTFLAG,320,240,8,SDL_FALSE} |
124 }; | 137 }; |
125 | 138 |
126 /* To setup palette */ | 139 /* To setup palette */ |
127 | 140 |
203 device->AllocHWSurface = XBIOS_AllocHWSurface; | 216 device->AllocHWSurface = XBIOS_AllocHWSurface; |
204 device->LockHWSurface = XBIOS_LockHWSurface; | 217 device->LockHWSurface = XBIOS_LockHWSurface; |
205 device->UnlockHWSurface = XBIOS_UnlockHWSurface; | 218 device->UnlockHWSurface = XBIOS_UnlockHWSurface; |
206 device->FlipHWSurface = XBIOS_FlipHWSurface; | 219 device->FlipHWSurface = XBIOS_FlipHWSurface; |
207 device->FreeHWSurface = XBIOS_FreeHWSurface; | 220 device->FreeHWSurface = XBIOS_FreeHWSurface; |
221 | |
222 #ifdef HAVE_OPENGL | |
223 /* OpenGL functions */ | |
224 device->GL_LoadLibrary = XBIOS_GL_LoadLibrary; | |
225 device->GL_GetProcAddress = XBIOS_GL_GetProcAddress; | |
226 device->GL_GetAttribute = XBIOS_GL_GetAttribute; | |
227 device->GL_MakeCurrent = XBIOS_GL_MakeCurrent; | |
228 device->GL_SwapBuffers = XBIOS_GL_SwapBuffers; | |
229 #endif | |
208 | 230 |
209 /* Events */ | 231 /* Events */ |
210 device->InitOSKeymap = Atari_InitOSKeymap; | 232 device->InitOSKeymap = Atari_InitOSKeymap; |
211 device->PumpEvents = Atari_PumpEvents; | 233 device->PumpEvents = Atari_PumpEvents; |
212 | 234 |
391 this->info.video_mem = (Uint32) Atari_SysMalloc(-1L, MX_STRAM); | 413 this->info.video_mem = (Uint32) Atari_SysMalloc(-1L, MX_STRAM); |
392 | 414 |
393 /* Init chunky to planar routine */ | 415 /* Init chunky to planar routine */ |
394 SDL_Atari_C2pConvert = SDL_Atari_C2pConvert8; | 416 SDL_Atari_C2pConvert = SDL_Atari_C2pConvert8; |
395 | 417 |
418 #ifdef HAVE_OPENGL | |
419 this->gl_config.driver_loaded = 1; | |
420 #endif | |
421 | |
396 /* We're done! */ | 422 /* We're done! */ |
397 return(0); | 423 return(0); |
398 } | 424 } |
399 | 425 |
400 static SDL_Rect **XBIOS_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags) | 426 static SDL_Rect **XBIOS_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags) |
409 } | 435 } |
410 | 436 |
411 static void XBIOS_FreeBuffers(_THIS) | 437 static void XBIOS_FreeBuffers(_THIS) |
412 { | 438 { |
413 int i; | 439 int i; |
440 | |
441 #ifdef HAVE_OPENGL | |
442 /* Shutdown OpenGL context */ | |
443 if (XBIOS_ctx) { | |
444 OSMesaDestroyContext(XBIOS_ctx); | |
445 XBIOS_ctx = NULL; | |
446 } | |
447 #endif | |
414 | 448 |
415 for (i=0;i<2;i++) { | 449 for (i=0;i<2;i++) { |
416 if (XBIOS_screensmem[i]!=NULL) { | 450 if (XBIOS_screensmem[i]!=NULL) { |
417 Mfree(XBIOS_screensmem[i]); | 451 Mfree(XBIOS_screensmem[i]); |
418 XBIOS_screensmem[i]=NULL; | 452 XBIOS_screensmem[i]=NULL; |
501 } | 535 } |
502 memset(XBIOS_screensmem[0], 0, new_screen_size); | 536 memset(XBIOS_screensmem[0], 0, new_screen_size); |
503 | 537 |
504 XBIOS_screens[0]=(void *) (( (long) XBIOS_screensmem[0]+256) & 0xFFFFFF00UL); | 538 XBIOS_screens[0]=(void *) (( (long) XBIOS_screensmem[0]+256) & 0xFFFFFF00UL); |
505 | 539 |
540 #ifdef HAVE_OPENGL | |
541 if (flags & SDL_OPENGL) { | |
542 if (this->gl_config.double_buffer) { | |
543 flags |= SDL_DOUBLEBUF; | |
544 } | |
545 } | |
546 #endif | |
547 | |
506 /* Double buffer ? */ | 548 /* Double buffer ? */ |
507 if (flags & SDL_DOUBLEBUF) { | 549 if (flags & SDL_DOUBLEBUF) { |
508 XBIOS_screensmem[1] = Atari_SysMalloc(new_screen_size, MX_STRAM); | 550 XBIOS_screensmem[1] = Atari_SysMalloc(new_screen_size, MX_STRAM); |
509 | 551 |
510 if (XBIOS_screensmem[1]==NULL) { | 552 if (XBIOS_screensmem[1]==NULL) { |
523 XBIOS_FreeBuffers(this); | 565 XBIOS_FreeBuffers(this); |
524 SDL_SetError("Couldn't allocate new pixel format for requested mode"); | 566 SDL_SetError("Couldn't allocate new pixel format for requested mode"); |
525 return(NULL); | 567 return(NULL); |
526 } | 568 } |
527 | 569 |
528 current->flags = modeflags; | |
529 current->w = XBIOS_width = width; | 570 current->w = XBIOS_width = width; |
530 current->h = XBIOS_height = height; | 571 current->h = XBIOS_height = height; |
531 current->pitch = (width * new_depth)>>3; | 572 current->pitch = (width * new_depth)>>3; |
532 | 573 |
533 /* this is for C2P conversion */ | 574 /* this is for C2P conversion */ |
537 current->pixels = XBIOS_shadowscreen; | 578 current->pixels = XBIOS_shadowscreen; |
538 else | 579 else |
539 current->pixels = XBIOS_screens[0]; | 580 current->pixels = XBIOS_screens[0]; |
540 | 581 |
541 XBIOS_fbnum = 0; | 582 XBIOS_fbnum = 0; |
583 | |
584 #ifdef HAVE_OPENGL | |
585 if (flags & SDL_OPENGL) { | |
586 GLenum format; | |
587 | |
588 /* Init OpenGL context using OSMesa */ | |
589 if (new_depth == 8) { | |
590 format = OSMESA_COLOR_INDEX; | |
591 } else { | |
592 format = OSMESA_RGB_565; | |
593 } | |
594 | |
595 XBIOS_ctx = OSMesaCreateContextExt( format, this->gl_config.depth_size, | |
596 this->gl_config.stencil_size, this->gl_config.accum_red_size + | |
597 this->gl_config.accum_green_size + this->gl_config.accum_blue_size + | |
598 this->gl_config.accum_alpha_size, NULL ); | |
599 if (!XBIOS_ctx) { | |
600 XBIOS_FreeBuffers(this); | |
601 SDL_SetError("OSMesaCreateContext failed"); | |
602 return(NULL); | |
603 } | |
604 | |
605 modeflags |= SDL_OPENGL; | |
606 } | |
607 #endif | |
608 | |
609 current->flags = modeflags; | |
542 | 610 |
543 /* Now set the video mode */ | 611 /* Now set the video mode */ |
544 #ifndef DEBUG_VIDEO_XBIOS | 612 #ifndef DEBUG_VIDEO_XBIOS |
545 Setscreen(-1,XBIOS_screens[0],-1); | 613 Setscreen(-1,XBIOS_screens[0],-1); |
546 #endif | 614 #endif |
696 destx = (XBIOS_width - surface->w) >> 1; | 764 destx = (XBIOS_width - surface->w) >> 1; |
697 destx &= ~15; | 765 destx &= ~15; |
698 destscr += destx; | 766 destscr += destx; |
699 | 767 |
700 /* Convert chunky to planar screen */ | 768 /* Convert chunky to planar screen */ |
701 #ifdef DEBUG_VIDEO_XBIOS | |
702 printf("C2p:\n"); | |
703 printf(" Source: Adr=0x%08x, Pitch=%d\n", surface->pixels, surface->pitch); | |
704 printf(" Dest: Adr=0x%08x, Pitch=%d\n", destscr, XBIOS_pitch); | |
705 printf(" Size: %dx%d, dblline=%d\n", surface->w, surface->h, XBIOS_doubleline); | |
706 fflush(stdout); | |
707 #endif | |
708 SDL_Atari_C2pConvert( | 769 SDL_Atari_C2pConvert( |
709 surface->pixels, | 770 surface->pixels, |
710 destscr, | 771 destscr, |
711 surface->w, | 772 surface->w, |
712 surface->h, | 773 surface->h, |
833 } | 894 } |
834 } | 895 } |
835 | 896 |
836 this->screen->pixels = NULL; | 897 this->screen->pixels = NULL; |
837 } | 898 } |
899 | |
900 #ifdef HAVE_OPENGL | |
901 | |
902 /* OpenGL functions */ | |
903 static int XBIOS_GL_LoadLibrary(_THIS, const char *path) | |
904 { | |
905 /* Library is always opened */ | |
906 this->gl_config.driver_loaded = 1; | |
907 | |
908 return 0; | |
909 } | |
910 | |
911 static void *XBIOS_GL_GetProcAddress(_THIS, const char *proc) | |
912 { | |
913 void *func = NULL; | |
914 | |
915 if (XBIOS_ctx != NULL) { | |
916 func = OSMesaGetProcAddress(proc); | |
917 } | |
918 | |
919 return func; | |
920 } | |
921 | |
922 static int XBIOS_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value) | |
923 { | |
924 GLenum mesa_attrib; | |
925 SDL_Surface *surface; | |
926 | |
927 if (XBIOS_ctx == NULL) { | |
928 return -1; | |
929 } | |
930 | |
931 switch(attrib) { | |
932 case SDL_GL_RED_SIZE: | |
933 mesa_attrib = GL_RED_BITS; | |
934 break; | |
935 case SDL_GL_GREEN_SIZE: | |
936 mesa_attrib = GL_GREEN_BITS; | |
937 break; | |
938 case SDL_GL_BLUE_SIZE: | |
939 mesa_attrib = GL_BLUE_BITS; | |
940 break; | |
941 case SDL_GL_ALPHA_SIZE: | |
942 mesa_attrib = GL_ALPHA_BITS; | |
943 break; | |
944 case SDL_GL_DOUBLEBUFFER: | |
945 surface = this->screen; | |
946 *value = ((surface->flags & SDL_DOUBLEBUF)==SDL_DOUBLEBUF); | |
947 return 0; | |
948 case SDL_GL_DEPTH_SIZE: | |
949 mesa_attrib = GL_DEPTH_BITS; | |
950 break; | |
951 case SDL_GL_STENCIL_SIZE: | |
952 mesa_attrib = GL_STENCIL_BITS; | |
953 break; | |
954 case SDL_GL_ACCUM_RED_SIZE: | |
955 mesa_attrib = GL_ACCUM_RED_BITS; | |
956 break; | |
957 case SDL_GL_ACCUM_GREEN_SIZE: | |
958 mesa_attrib = GL_ACCUM_GREEN_BITS; | |
959 break; | |
960 case SDL_GL_ACCUM_BLUE_SIZE: | |
961 mesa_attrib = GL_ACCUM_BLUE_BITS; | |
962 break; | |
963 case SDL_GL_ACCUM_ALPHA_SIZE: | |
964 mesa_attrib = GL_ACCUM_ALPHA_BITS; | |
965 break; | |
966 default : | |
967 return -1; | |
968 } | |
969 | |
970 glGetIntegerv(mesa_attrib, value); | |
971 return 0; | |
972 } | |
973 | |
974 static int XBIOS_GL_MakeCurrent(_THIS) | |
975 { | |
976 SDL_Surface *surface; | |
977 GLenum type; | |
978 | |
979 if (XBIOS_ctx == NULL) { | |
980 return -1; | |
981 } | |
982 | |
983 surface = this->screen; | |
984 if ((surface->format->BitsPerPixel) == 8) { | |
985 type = GL_UNSIGNED_BYTE; | |
986 } else { | |
987 type = GL_UNSIGNED_SHORT_5_6_5; | |
988 } | |
989 | |
990 if (!OSMesaMakeCurrent(XBIOS_ctx, surface->pixels, type, surface->w, surface->h)) { | |
991 SDL_SetError("Can not make OpenGL context current"); | |
992 return -1; | |
993 } | |
994 | |
995 return 0; | |
996 } | |
997 | |
998 static void XBIOS_GL_SwapBuffers(_THIS) | |
999 { | |
1000 if (XBIOS_ctx == NULL) { | |
1001 return; | |
1002 } | |
1003 | |
1004 XBIOS_FlipHWSurface(this, this->screen); | |
1005 XBIOS_GL_MakeCurrent(this); | |
1006 } | |
1007 | |
1008 #endif |