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