Fixed bug #84
Actually implemented banked update for SVGAlib --HG-- extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%401560
This commit is contained in:
parent
ac4f328755
commit
ec2060c825
3 changed files with 114 additions and 99 deletions
|
@ -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]]),
|
||||||
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 @@
|
||||||
#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 @@
|
||||||
#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,58 +158,56 @@ 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 ) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
if ( actually_add ) {
|
|
||||||
SDL_Rect saved_rect[2];
|
|
||||||
int saved_mode[2];
|
|
||||||
int b;
|
|
||||||
|
|
||||||
/* Add the mode, sorted largest to smallest */
|
|
||||||
b = 0;
|
|
||||||
j = 0;
|
|
||||||
while ( (SDL_modelist[i][j]->w > modeinfo->width) ||
|
|
||||||
(SDL_modelist[i][j]->h > modeinfo->height) ) {
|
|
||||||
++j;
|
|
||||||
}
|
|
||||||
/* Skip modes that are already in our list */
|
|
||||||
if ( (SDL_modelist[i][j]->w == modeinfo->width) &&
|
|
||||||
(SDL_modelist[i][j]->h == modeinfo->height) ) {
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
/* Insert the new mode */
|
|
||||||
saved_rect[b] = *SDL_modelist[i][j];
|
|
||||||
saved_mode[b] = SDL_vgamode[i][j];
|
|
||||||
SDL_modelist[i][j]->w = modeinfo->width;
|
|
||||||
SDL_modelist[i][j]->h = modeinfo->height;
|
|
||||||
SDL_vgamode[i][j] = mode;
|
|
||||||
/* Everybody scoot down! */
|
|
||||||
if ( saved_rect[b].w && saved_rect[b].h ) {
|
|
||||||
for ( ++j; SDL_modelist[i][j]->w; ++j ) {
|
|
||||||
saved_rect[!b] = *SDL_modelist[i][j];
|
|
||||||
saved_mode[!b] = SDL_vgamode[i][j];
|
|
||||||
*SDL_modelist[i][j] = saved_rect[b];
|
|
||||||
SDL_vgamode[i][j] = saved_mode[b];
|
|
||||||
b = !b;
|
|
||||||
}
|
|
||||||
*SDL_modelist[i][j] = saved_rect[b];
|
|
||||||
SDL_vgamode[i][j] = saved_mode[b];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
++SDL_nummodes[i];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return( force || ( modeinfo->flags & CAPABLE_LINEAR ) );
|
if ( actually_add ) {
|
||||||
|
SDL_Rect saved_rect[2];
|
||||||
|
int saved_mode[2];
|
||||||
|
int b;
|
||||||
|
|
||||||
|
/* Add the mode, sorted largest to smallest */
|
||||||
|
b = 0;
|
||||||
|
j = 0;
|
||||||
|
while ( (SDL_modelist[i][j]->w > modeinfo->width) ||
|
||||||
|
(SDL_modelist[i][j]->h > modeinfo->height) ) {
|
||||||
|
++j;
|
||||||
|
}
|
||||||
|
/* Skip modes that are already in our list */
|
||||||
|
if ( (SDL_modelist[i][j]->w == modeinfo->width) &&
|
||||||
|
(SDL_modelist[i][j]->h == modeinfo->height) ) {
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
/* Insert the new mode */
|
||||||
|
saved_rect[b] = *SDL_modelist[i][j];
|
||||||
|
saved_mode[b] = SDL_vgamode[i][j];
|
||||||
|
SDL_modelist[i][j]->w = modeinfo->width;
|
||||||
|
SDL_modelist[i][j]->h = modeinfo->height;
|
||||||
|
SDL_vgamode[i][j] = mode;
|
||||||
|
/* Everybody scoot down! */
|
||||||
|
if ( saved_rect[b].w && saved_rect[b].h ) {
|
||||||
|
for ( ++j; SDL_modelist[i][j]->w; ++j ) {
|
||||||
|
saved_rect[!b] = *SDL_modelist[i][j];
|
||||||
|
saved_mode[!b] = SDL_vgamode[i][j];
|
||||||
|
*SDL_modelist[i][j] = saved_rect[b];
|
||||||
|
SDL_vgamode[i][j] = saved_mode[b];
|
||||||
|
b = !b;
|
||||||
|
}
|
||||||
|
*SDL_modelist[i][j] = saved_rect[b];
|
||||||
|
SDL_vgamode[i][j] = saved_mode[b];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
++SDL_nummodes[i];
|
||||||
|
}
|
||||||
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SVGA_UpdateVideoInfo(_THIS)
|
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)
|
||||||
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)
|
||||||
}
|
}
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
|
|
||||||
/* 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,
|
||||||
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,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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)
|
||||||
|
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
|
|
||||||
/* 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)
|
||||||
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 {
|
||||||
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 {
|
||||||
#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 */
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue