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