Commit ec2060c8 authored by Sam Lantinga's avatar Sam Lantinga

Fixed bug #84

Actually implemented banked update for SVGAlib

--HG--
extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%401560
parent ac4f3287
...@@ -1072,7 +1072,6 @@ AC_HELP_STRING([--enable-video-svga], [use SVGAlib video driver [default=no]]), ...@@ -1072,7 +1072,6 @@ AC_HELP_STRING([--enable-video-svga], [use SVGAlib video driver [default=no]]),
#include <vga.h> #include <vga.h>
#include <vgamouse.h> #include <vgamouse.h>
#include <vgakeyboard.h> #include <vgakeyboard.h>
#include <vgagl.h>
],[ ],[
if ( SCANCODE_RIGHTWIN && SCANCODE_LEFTWIN ) { if ( SCANCODE_RIGHTWIN && SCANCODE_LEFTWIN ) {
exit(0); exit(0);
...@@ -1084,7 +1083,7 @@ AC_HELP_STRING([--enable-video-svga], [use SVGAlib video driver [default=no]]), ...@@ -1084,7 +1083,7 @@ AC_HELP_STRING([--enable-video-svga], [use SVGAlib video driver [default=no]]),
if test x$video_svga = xyes; then if test x$video_svga = xyes; then
AC_DEFINE(SDL_VIDEO_DRIVER_SVGALIB) AC_DEFINE(SDL_VIDEO_DRIVER_SVGALIB)
SOURCES="$SOURCES $srcdir/src/video/svga/*.c" SOURCES="$SOURCES $srcdir/src/video/svga/*.c"
EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lvga -lvgagl" EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lvga"
have_video=yes have_video=yes
fi fi
fi fi
......
...@@ -40,7 +40,6 @@ ...@@ -40,7 +40,6 @@
#include <vga.h> #include <vga.h>
#include <vgamouse.h> #include <vgamouse.h>
#include <vgakeyboard.h> #include <vgakeyboard.h>
#include <vgagl.h>
#include "SDL_video.h" #include "SDL_video.h"
#include "SDL_mouse.h" #include "SDL_mouse.h"
...@@ -51,9 +50,6 @@ ...@@ -51,9 +50,6 @@
#include "SDL_svgaevents_c.h" #include "SDL_svgaevents_c.h"
#include "SDL_svgamouse_c.h" #include "SDL_svgamouse_c.h"
static GraphicsContext *realgc = NULL;
static GraphicsContext *virtgc = NULL;
/* Initialization/Query functions */ /* Initialization/Query functions */
static int SVGA_VideoInit(_THIS, SDL_PixelFormat *vformat); static int SVGA_VideoInit(_THIS, SDL_PixelFormat *vformat);
static SDL_Rect **SVGA_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags); static SDL_Rect **SVGA_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
...@@ -162,13 +158,12 @@ VideoBootStrap SVGALIB_bootstrap = { ...@@ -162,13 +158,12 @@ VideoBootStrap SVGALIB_bootstrap = {
SVGA_Available, SVGA_CreateDevice SVGA_Available, SVGA_CreateDevice
}; };
static int SVGA_AddMode(_THIS, int mode, int actually_add, int force) static int SVGA_AddMode(_THIS, int mode, int actually_add)
{ {
int i, j;
vga_modeinfo *modeinfo; vga_modeinfo *modeinfo;
modeinfo = vga_getmodeinfo(mode); modeinfo = vga_getmodeinfo(mode);
if ( force || ( modeinfo->flags & CAPABLE_LINEAR ) ) {
int i, j;
i = modeinfo->bytesperpixel-1; i = modeinfo->bytesperpixel-1;
if ( i < 0 ) { if ( i < 0 ) {
...@@ -212,8 +207,7 @@ static int SVGA_AddMode(_THIS, int mode, int actually_add, int force) ...@@ -212,8 +207,7 @@ static int SVGA_AddMode(_THIS, int mode, int actually_add, int force)
} else { } else {
++SDL_nummodes[i]; ++SDL_nummodes[i];
} }
} return(1);
return( force || ( modeinfo->flags & CAPABLE_LINEAR ) );
} }
static void SVGA_UpdateVideoInfo(_THIS) static void SVGA_UpdateVideoInfo(_THIS)
...@@ -221,7 +215,7 @@ static void SVGA_UpdateVideoInfo(_THIS) ...@@ -221,7 +215,7 @@ static void SVGA_UpdateVideoInfo(_THIS)
vga_modeinfo *modeinfo; vga_modeinfo *modeinfo;
this->info.wm_available = 0; this->info.wm_available = 0;
this->info.hw_available = (virtgc ? 0 : 1); this->info.hw_available = (banked ? 0 : 1);
modeinfo = vga_getmodeinfo(vga_getcurrentmode()); modeinfo = vga_getmodeinfo(vga_getcurrentmode());
this->info.video_mem = modeinfo->memory; this->info.video_mem = modeinfo->memory;
/* FIXME: Add hardware accelerated blit information */ /* FIXME: Add hardware accelerated blit information */
...@@ -274,12 +268,12 @@ int SVGA_VideoInit(_THIS, SDL_PixelFormat *vformat) ...@@ -274,12 +268,12 @@ int SVGA_VideoInit(_THIS, SDL_PixelFormat *vformat)
total_modes = 0; total_modes = 0;
for ( mode=vga_lastmodenumber(); mode; --mode ) { for ( mode=vga_lastmodenumber(); mode; --mode ) {
if ( vga_hasmode(mode) ) { if ( vga_hasmode(mode) ) {
if ( SVGA_AddMode(this, mode, 0, 1) ) { if ( SVGA_AddMode(this, mode, 0) ) {
++total_modes; ++total_modes;
} }
} }
} }
if ( SVGA_AddMode(this, G320x200x256, 0, 1) ) ++total_modes; if ( SVGA_AddMode(this, G320x200x256, 0) ) ++total_modes;
if ( total_modes == 0 ) { if ( total_modes == 0 ) {
SDL_SetError("No linear video modes available"); SDL_SetError("No linear video modes available");
return(-1); return(-1);
...@@ -308,10 +302,10 @@ int SVGA_VideoInit(_THIS, SDL_PixelFormat *vformat) ...@@ -308,10 +302,10 @@ int SVGA_VideoInit(_THIS, SDL_PixelFormat *vformat)
} }
for ( mode=vga_lastmodenumber(); mode; --mode ) { for ( mode=vga_lastmodenumber(); mode; --mode ) {
if ( vga_hasmode(mode) ) { if ( vga_hasmode(mode) ) {
SVGA_AddMode(this, mode, 1, 1); SVGA_AddMode(this, mode, 1);
} }
} }
SVGA_AddMode(this, G320x200x256, 1, 1); SVGA_AddMode(this, G320x200x256, 1);
/* Free extra (duplicated) modes */ /* Free extra (duplicated) modes */
for ( i=0; i<NUM_MODELISTS; ++i ) { for ( i=0; i<NUM_MODELISTS; ++i ) {
...@@ -350,16 +344,10 @@ SDL_Surface *SVGA_SetVideoMode(_THIS, SDL_Surface *current, ...@@ -350,16 +344,10 @@ SDL_Surface *SVGA_SetVideoMode(_THIS, SDL_Surface *current,
vga_modeinfo *modeinfo; vga_modeinfo *modeinfo;
int screenpage_len; int screenpage_len;
/* Clean up old video mode data */ /* Free old pixels if we were in banked mode */
if ( realgc ) { if ( banked && current->pixels ) {
free(realgc); free(current->pixels);
realgc = NULL; current->pixels = NULL;
}
if ( virtgc ) {
/* FIXME: Why does this crash?
gl_freecontext(virtgc);*/
free(virtgc);
virtgc = NULL;
} }
/* Try to set the requested linear video mode */ /* Try to set the requested linear video mode */
...@@ -379,15 +367,9 @@ SDL_Surface *SVGA_SetVideoMode(_THIS, SDL_Surface *current, ...@@ -379,15 +367,9 @@ SDL_Surface *SVGA_SetVideoMode(_THIS, SDL_Surface *current,
vga_setpage(0); vga_setpage(0);
if ( (vga_setlinearaddressing() < 0) && (vgamode != G320x200x256) ) { if ( (vga_setlinearaddressing() < 0) && (vgamode != G320x200x256) ) {
gl_setcontextvga(vgamode); banked = 1;
realgc = gl_allocatecontext(); } else {
gl_getcontext(realgc); banked = 0;
gl_setcontextvgavirtual(vgamode);
virtgc = gl_allocatecontext();
gl_getcontext(virtgc);
flags &= ~SDL_DOUBLEBUF;
} }
modeinfo = vga_getmodeinfo(SDL_vgamode[bpp][mode]); modeinfo = vga_getmodeinfo(SDL_vgamode[bpp][mode]);
...@@ -406,9 +388,7 @@ SDL_Surface *SVGA_SetVideoMode(_THIS, SDL_Surface *current, ...@@ -406,9 +388,7 @@ SDL_Surface *SVGA_SetVideoMode(_THIS, SDL_Surface *current,
/* Set up the new mode framebuffer */ /* Set up the new mode framebuffer */
current->flags = SDL_FULLSCREEN; current->flags = SDL_FULLSCREEN;
if ( virtgc ) { if ( !banked ) {
current->flags |= SDL_SWSURFACE;
} else {
current->flags |= SDL_HWSURFACE; current->flags |= SDL_HWSURFACE;
} }
if ( bpp == 8 ) { if ( bpp == 8 ) {
...@@ -418,14 +398,18 @@ SDL_Surface *SVGA_SetVideoMode(_THIS, SDL_Surface *current, ...@@ -418,14 +398,18 @@ SDL_Surface *SVGA_SetVideoMode(_THIS, SDL_Surface *current,
current->w = width; current->w = width;
current->h = height; current->h = height;
current->pitch = modeinfo->linewidth; current->pitch = modeinfo->linewidth;
if ( virtgc ) { if ( banked ) {
current->pixels = virtgc->vbuf; current->pixels = SDL_malloc(current->h * current->pitch);
if ( !current->pixels ) {
SDL_OutOfMemory();
return(NULL);
}
} else { } else {
current->pixels = vga_getgraphmem(); current->pixels = vga_getgraphmem();
} }
/* set double-buffering */ /* set double-buffering */
if ( flags & SDL_DOUBLEBUF ) if ( (flags & SDL_DOUBLEBUF) && !banked )
{ {
/* length of one screen page in bytes */ /* length of one screen page in bytes */
screenpage_len=current->h*modeinfo->linewidth; screenpage_len=current->h*modeinfo->linewidth;
...@@ -453,7 +437,7 @@ SDL_Surface *SVGA_SetVideoMode(_THIS, SDL_Surface *current, ...@@ -453,7 +437,7 @@ SDL_Surface *SVGA_SetVideoMode(_THIS, SDL_Surface *current,
} }
/* Set the blit function */ /* Set the blit function */
if ( virtgc ) { if ( banked ) {
this->UpdateRects = SVGA_BankedUpdate; this->UpdateRects = SVGA_BankedUpdate;
} else { } else {
this->UpdateRects = SVGA_DirectUpdate; this->UpdateRects = SVGA_DirectUpdate;
...@@ -489,7 +473,7 @@ static void SVGA_UnlockHWSurface(_THIS, SDL_Surface *surface) ...@@ -489,7 +473,7 @@ static void SVGA_UnlockHWSurface(_THIS, SDL_Surface *surface)
static int SVGA_FlipHWSurface(_THIS, SDL_Surface *surface) static int SVGA_FlipHWSurface(_THIS, SDL_Surface *surface)
{ {
if ( !virtgc ) { if ( !banked ) {
vga_setdisplaystart(flip_offset[flip_page]); vga_setdisplaystart(flip_offset[flip_page]);
flip_page=!flip_page; flip_page=!flip_page;
surface->pixels=flip_address[flip_page]; surface->pixels=flip_address[flip_page];
...@@ -505,14 +489,50 @@ static void SVGA_DirectUpdate(_THIS, int numrects, SDL_Rect *rects) ...@@ -505,14 +489,50 @@ static void SVGA_DirectUpdate(_THIS, int numrects, SDL_Rect *rects)
static void SVGA_BankedUpdate(_THIS, int numrects, SDL_Rect *rects) static void SVGA_BankedUpdate(_THIS, int numrects, SDL_Rect *rects)
{ {
int i; int i, j;
SDL_Rect *rect; SDL_Rect *rect;
int page, vp;
int x, y, w, h;
unsigned char *src;
unsigned char *dst;
int bpp = this->screen->format->BytesPerPixel;
int pitch = this->screen->pitch;
dst = vga_getgraphmem();
for ( i=0; i < numrects; ++i ) { for ( i=0; i < numrects; ++i ) {
rect = &rects[i]; rect = &rects[i];
gl_copyboxtocontext(rect->x, rect->y, rect->w, rect->h, realgc, rect->x, rect->y); x = rect->x;
y = rect->y;
w = rect->w * bpp;
h = rect->h;
vp = y * pitch + x * bpp;
src = (unsigned char *)this->screen->pixels + vp;
page = vp >> 16;
vp &= 0xffff;
vga_setpage(page);
for (j = 0; j < h; j++) {
if (vp + w > 0x10000) {
if (vp >= 0x10000) {
page++;
vga_setpage(page);
vp &= 0xffff;
} else {
SDL_memcpy(dst + vp, src, 0x10000 - vp);
page++;
vga_setpage(page);
SDL_memcpy(dst, src + 0x10000 - vp,
(vp + w) & 0xffff);
vp = (vp + pitch) & 0xffff;
src += pitch;
continue;
}
}
SDL_memcpy(dst + vp, src, w);
src += pitch;
vp += pitch;
}
} }
return;
} }
int SVGA_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) int SVGA_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
...@@ -537,16 +557,6 @@ void SVGA_VideoQuit(_THIS) ...@@ -537,16 +557,6 @@ void SVGA_VideoQuit(_THIS)
/* Reset the console video mode */ /* Reset the console video mode */
if ( this->screen && (this->screen->w && this->screen->h) ) { if ( this->screen && (this->screen->w && this->screen->h) ) {
if ( realgc ) {
free(realgc);
realgc = NULL;
}
if ( virtgc ) {
/* FIXME: Why does this crash?
gl_freecontext(virtgc);*/
free(virtgc);
virtgc = NULL;
}
vga_setmode(TEXT); vga_setmode(TEXT);
} }
keyboard_close(); keyboard_close();
...@@ -564,8 +574,10 @@ void SVGA_VideoQuit(_THIS) ...@@ -564,8 +574,10 @@ void SVGA_VideoQuit(_THIS)
SDL_vgamode[i] = NULL; SDL_vgamode[i] = NULL;
} }
} }
if ( this->screen && (this->screen->flags & SDL_HWSURFACE) ) { if ( this->screen ) {
/* Direct screen access, no memory buffer */ if ( banked && this->screen->pixels ) {
SDL_free(this->screen->pixels);
}
this->screen->pixels = NULL; this->screen->pixels = NULL;
} }
} }
......
...@@ -41,6 +41,9 @@ struct SDL_PrivateVideoData { ...@@ -41,6 +41,9 @@ struct SDL_PrivateVideoData {
int flip_page; int flip_page;
int flip_offset[2]; int flip_offset[2];
Uint8 *flip_address[2]; Uint8 *flip_address[2];
/* Set to 1 if we're in banked video mode */
int banked;
}; };
/* Old variable names */ /* Old variable names */
#define SDL_nummodes (this->hidden->SDL_nummodes) #define SDL_nummodes (this->hidden->SDL_nummodes)
...@@ -49,6 +52,7 @@ struct SDL_PrivateVideoData { ...@@ -49,6 +52,7 @@ struct SDL_PrivateVideoData {
#define flip_page (this->hidden->flip_page) #define flip_page (this->hidden->flip_page)
#define flip_offset (this->hidden->flip_offset) #define flip_offset (this->hidden->flip_offset)
#define flip_address (this->hidden->flip_address) #define flip_address (this->hidden->flip_address)
#define banked (this->hidden->banked)
#endif /* _SDL_svgavideo_h */ #endif /* _SDL_svgavideo_h */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment