Mercurial > sdl-ios-xcode
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 */ |