comparison src/video/svga/SDL_svgavideo.c @ 1554:0ca607a5d173

Fixed bug #84 Date: Sun, 23 Oct 2005 16:39:03 +0200 From: "A. Schmid" <sahib@phreaker.net> Subject: [SDL] no software surfaces with svgalib driver? Hi, I noticed that the SDL (1.2.9) svgalib driver only makes use of linear addressable (framebuffer) video modes. On older systems (like one of mine), linear addressable modes are often not available. Especially for cards with VESA VBE < 2.0 the svgalib vesa driver is unusable, since VESA only supports framebuffering for VBE 2.0 and later. The changes necessary to add support for software surfaces seem to be relatively small. I only had to hack src/video/svga/SDL_svgavideo.c (see attached patch). The code worked fine for me, but it is no more than a proof of concept and should be reviewed (probably has a memory leak when switching modes). It also uses the vgagl library (included in the svgalib package) and needs to be linked against it. -Alex
author Sam Lantinga <slouken@libsdl.org>
date Sun, 19 Mar 2006 12:04:40 +0000
parents 8d9bb0cf2c2a
children 011b633fa0c9
comparison
equal deleted inserted replaced
1553:63fa37538842 1554:0ca607a5d173
38 #error You must choose your operating system here 38 #error You must choose your operating system here
39 #endif 39 #endif
40 #include <vga.h> 40 #include <vga.h>
41 #include <vgamouse.h> 41 #include <vgamouse.h>
42 #include <vgakeyboard.h> 42 #include <vgakeyboard.h>
43 #include <vgagl.h>
43 44
44 #include "SDL_video.h" 45 #include "SDL_video.h"
45 #include "SDL_mouse.h" 46 #include "SDL_mouse.h"
46 #include "../SDL_sysvideo.h" 47 #include "../SDL_sysvideo.h"
47 #include "../SDL_pixels_c.h" 48 #include "../SDL_pixels_c.h"
48 #include "../../events/SDL_events_c.h" 49 #include "../../events/SDL_events_c.h"
49 #include "SDL_svgavideo.h" 50 #include "SDL_svgavideo.h"
50 #include "SDL_svgaevents_c.h" 51 #include "SDL_svgaevents_c.h"
51 #include "SDL_svgamouse_c.h" 52 #include "SDL_svgamouse_c.h"
52 53
54 static GraphicsContext *realgc = NULL;
55 static GraphicsContext *virtgc = NULL;
53 56
54 /* Initialization/Query functions */ 57 /* Initialization/Query functions */
55 static int SVGA_VideoInit(_THIS, SDL_PixelFormat *vformat); 58 static int SVGA_VideoInit(_THIS, SDL_PixelFormat *vformat);
56 static SDL_Rect **SVGA_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags); 59 static SDL_Rect **SVGA_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
57 static SDL_Surface *SVGA_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags); 60 static SDL_Surface *SVGA_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
166 modeinfo = vga_getmodeinfo(mode); 169 modeinfo = vga_getmodeinfo(mode);
167 if ( force || ( modeinfo->flags & CAPABLE_LINEAR ) ) { 170 if ( force || ( modeinfo->flags & CAPABLE_LINEAR ) ) {
168 int i, j; 171 int i, j;
169 172
170 i = modeinfo->bytesperpixel-1; 173 i = modeinfo->bytesperpixel-1;
174 if ( i < 0 ) {
175 return 0;
176 }
171 if ( actually_add ) { 177 if ( actually_add ) {
172 SDL_Rect saved_rect[2]; 178 SDL_Rect saved_rect[2];
173 int saved_mode[2]; 179 int saved_mode[2];
174 int b; 180 int b;
175 181
213 static void SVGA_UpdateVideoInfo(_THIS) 219 static void SVGA_UpdateVideoInfo(_THIS)
214 { 220 {
215 vga_modeinfo *modeinfo; 221 vga_modeinfo *modeinfo;
216 222
217 this->info.wm_available = 0; 223 this->info.wm_available = 0;
218 this->info.hw_available = 1; 224 this->info.hw_available = (virtgc ? 0 : 1);
219 modeinfo = vga_getmodeinfo(vga_getcurrentmode()); 225 modeinfo = vga_getmodeinfo(vga_getcurrentmode());
220 this->info.video_mem = modeinfo->memory; 226 this->info.video_mem = modeinfo->memory;
221 /* FIXME: Add hardware accelerated blit information */ 227 /* FIXME: Add hardware accelerated blit information */
222 #ifdef SVGALIB_DEBUG 228 #ifdef SVGALIB_DEBUG
223 printf("Hardware accelerated blit: %savailable\n", modeinfo->haveblit ? "" : "not "); 229 printf("Hardware accelerated blit: %savailable\n", modeinfo->haveblit ? "" : "not ");
266 272
267 /* Enumerate the available fullscreen modes */ 273 /* Enumerate the available fullscreen modes */
268 total_modes = 0; 274 total_modes = 0;
269 for ( mode=vga_lastmodenumber(); mode; --mode ) { 275 for ( mode=vga_lastmodenumber(); mode; --mode ) {
270 if ( vga_hasmode(mode) ) { 276 if ( vga_hasmode(mode) ) {
271 if ( SVGA_AddMode(this, mode, 0, 0) ) { 277 if ( SVGA_AddMode(this, mode, 0, 1) ) {
272 ++total_modes; 278 ++total_modes;
273 } 279 }
274 } 280 }
275 } 281 }
276 if ( SVGA_AddMode(this, G320x200x256, 0, 1) ) ++total_modes; 282 if ( SVGA_AddMode(this, G320x200x256, 0, 1) ) ++total_modes;
300 } 306 }
301 SDL_modelist[i][j] = NULL; 307 SDL_modelist[i][j] = NULL;
302 } 308 }
303 for ( mode=vga_lastmodenumber(); mode; --mode ) { 309 for ( mode=vga_lastmodenumber(); mode; --mode ) {
304 if ( vga_hasmode(mode) ) { 310 if ( vga_hasmode(mode) ) {
305 SVGA_AddMode(this, mode, 1, 0); 311 SVGA_AddMode(this, mode, 1, 1);
306 } 312 }
307 } 313 }
308 SVGA_AddMode(this, G320x200x256, 1, 1); 314 SVGA_AddMode(this, G320x200x256, 1, 1);
309 315
310 /* Free extra (duplicated) modes */ 316 /* Free extra (duplicated) modes */
341 { 347 {
342 int mode; 348 int mode;
343 int vgamode; 349 int vgamode;
344 vga_modeinfo *modeinfo; 350 vga_modeinfo *modeinfo;
345 int screenpage_len; 351 int screenpage_len;
352
353 /* Clean up old video mode data */
354 if ( realgc ) {
355 free(realgc);
356 realgc = NULL;
357 }
358 if ( virtgc ) {
359 /* FIXME: Why does this crash?
360 gl_freecontext(virtgc);*/
361 free(virtgc);
362 virtgc = NULL;
363 }
346 364
347 /* Try to set the requested linear video mode */ 365 /* Try to set the requested linear video mode */
348 bpp = (bpp+7)/8-1; 366 bpp = (bpp+7)/8-1;
349 for ( mode=0; SDL_modelist[bpp][mode]; ++mode ) { 367 for ( mode=0; SDL_modelist[bpp][mode]; ++mode ) {
350 if ( (SDL_modelist[bpp][mode]->w == width) && 368 if ( (SDL_modelist[bpp][mode]->w == width) &&
354 } 372 }
355 if ( SDL_modelist[bpp][mode] == NULL ) { 373 if ( SDL_modelist[bpp][mode] == NULL ) {
356 SDL_SetError("Couldn't find requested mode in list"); 374 SDL_SetError("Couldn't find requested mode in list");
357 return(NULL); 375 return(NULL);
358 } 376 }
359 vga_setmode(SDL_vgamode[bpp][mode]); 377 vgamode = SDL_vgamode[bpp][mode];
378 vga_setmode(vgamode);
360 vga_setpage(0); 379 vga_setpage(0);
361 380
362 vgamode=SDL_vgamode[bpp][mode]; 381 if ( (vga_setlinearaddressing() < 0) && (vgamode != G320x200x256) ) {
363 if ((vga_setlinearaddressing()<0) && (vgamode!=G320x200x256)) { 382 gl_setcontextvga(vgamode);
364 SDL_SetError("Unable to set linear addressing"); 383 realgc = gl_allocatecontext();
365 return(NULL); 384 gl_getcontext(realgc);
366 } 385
386 gl_setcontextvgavirtual(vgamode);
387 virtgc = gl_allocatecontext();
388 gl_getcontext(virtgc);
389
390 flags &= ~SDL_DOUBLEBUF;
391 }
392
367 modeinfo = vga_getmodeinfo(SDL_vgamode[bpp][mode]); 393 modeinfo = vga_getmodeinfo(SDL_vgamode[bpp][mode]);
368 394
369 /* Update hardware acceleration info */ 395 /* Update hardware acceleration info */
370 SVGA_UpdateVideoInfo(this); 396 SVGA_UpdateVideoInfo(this);
371 397
377 if ( ! SDL_ReallocFormat(current, bpp, 0, 0, 0, 0) ) { 403 if ( ! SDL_ReallocFormat(current, bpp, 0, 0, 0, 0) ) {
378 return(NULL); 404 return(NULL);
379 } 405 }
380 406
381 /* Set up the new mode framebuffer */ 407 /* Set up the new mode framebuffer */
382 current->flags = (SDL_FULLSCREEN|SDL_HWSURFACE); 408 current->flags = SDL_FULLSCREEN;
409 if ( virtgc ) {
410 current->flags |= SDL_SWSURFACE;
411 } else {
412 current->flags |= SDL_HWSURFACE;
413 }
383 if ( bpp == 8 ) { 414 if ( bpp == 8 ) {
384 /* FIXME: What about DirectColor? */ 415 /* FIXME: What about DirectColor? */
385 current->flags |= SDL_HWPALETTE; 416 current->flags |= SDL_HWPALETTE;
386 } 417 }
387 current->w = width; 418 current->w = width;
388 current->h = height; 419 current->h = height;
389 current->pitch = modeinfo->linewidth; 420 current->pitch = modeinfo->linewidth;
390 current->pixels = vga_getgraphmem(); 421 if ( virtgc ) {
422 current->pixels = virtgc->vbuf;
423 } else {
424 current->pixels = vga_getgraphmem();
425 }
391 426
392 /* set double-buffering */ 427 /* set double-buffering */
393 if ( flags & SDL_DOUBLEBUF ) 428 if ( flags & SDL_DOUBLEBUF )
394 { 429 {
395 /* length of one screen page in bytes */ 430 /* length of one screen page in bytes */
416 SVGA_FlipHWSurface(this,current); 451 SVGA_FlipHWSurface(this,current);
417 } 452 }
418 } 453 }
419 454
420 /* Set the blit function */ 455 /* Set the blit function */
421 this->UpdateRects = SVGA_DirectUpdate; 456 if ( virtgc ) {
457 this->UpdateRects = SVGA_BankedUpdate;
458 } else {
459 this->UpdateRects = SVGA_DirectUpdate;
460 }
422 461
423 /* Set up the mouse handler again (buggy SVGAlib 1.40) */ 462 /* Set up the mouse handler again (buggy SVGAlib 1.40) */
424 mouse_seteventhandler(SVGA_mousecallback); 463 mouse_seteventhandler(SVGA_mousecallback);
425 464
426 /* We're done */ 465 /* We're done */
448 return; 487 return;
449 } 488 }
450 489
451 static int SVGA_FlipHWSurface(_THIS, SDL_Surface *surface) 490 static int SVGA_FlipHWSurface(_THIS, SDL_Surface *surface)
452 { 491 {
453 vga_setdisplaystart(flip_offset[flip_page]); 492 if ( !virtgc ) {
454 flip_page=!flip_page; 493 vga_setdisplaystart(flip_offset[flip_page]);
455 surface->pixels=flip_address[flip_page]; 494 flip_page=!flip_page;
456 vga_waitretrace(); 495 surface->pixels=flip_address[flip_page];
496 vga_waitretrace();
497 }
457 return(0); 498 return(0);
458 } 499 }
459 500
460 static void SVGA_DirectUpdate(_THIS, int numrects, SDL_Rect *rects) 501 static void SVGA_DirectUpdate(_THIS, int numrects, SDL_Rect *rects)
461 { 502 {
462 return; 503 return;
463 } 504 }
464 505
465 /* FIXME: Can this be used under SVGAlib? */
466 static void SVGA_BankedUpdate(_THIS, int numrects, SDL_Rect *rects) 506 static void SVGA_BankedUpdate(_THIS, int numrects, SDL_Rect *rects)
467 { 507 {
508 int i;
509 SDL_Rect *rect;
510
511 for ( i=0; i < numrects; ++i ) {
512 rect = &rects[i];
513 gl_copyboxtocontext(rect->x, rect->y, rect->w, rect->h, realgc, rect->x, rect->y);
514 }
468 return; 515 return;
469 } 516 }
470 517
471 int SVGA_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) 518 int SVGA_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
472 { 519 {
488 { 535 {
489 int i, j; 536 int i, j;
490 537
491 /* Reset the console video mode */ 538 /* Reset the console video mode */
492 if ( this->screen && (this->screen->w && this->screen->h) ) { 539 if ( this->screen && (this->screen->w && this->screen->h) ) {
540 if ( realgc ) {
541 free(realgc);
542 realgc = NULL;
543 }
544 if ( virtgc ) {
545 /* FIXME: Why does this crash?
546 gl_freecontext(virtgc);*/
547 free(virtgc);
548 virtgc = NULL;
549 }
493 vga_setmode(TEXT); 550 vga_setmode(TEXT);
494 } 551 }
495 keyboard_close(); 552 keyboard_close();
496 553
497 /* Free video mode lists */ 554 /* Free video mode lists */