Add special win32 output handler using directdraw scaled blits
Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1895
This commit is contained in:
parent
7f29fe4b5a
commit
b45019218e
1 changed files with 124 additions and 63 deletions
|
@ -16,7 +16,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* $Id: sdlmain.cpp,v 1.69 2004-07-12 12:42:20 qbix79 Exp $ */
|
||||
/* $Id: sdlmain.cpp,v 1.70 2004-07-24 20:41:09 harekiet Exp $ */
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
|
@ -88,12 +88,19 @@ PFNGLPIXELDATARANGENVPROC glPixelDataRangeNV = NULL;
|
|||
extern char** environ;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef WIN32
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#if defined(HAVE_DDRAW_H)
|
||||
#include <ddraw.h>
|
||||
struct private_hwdata {
|
||||
LPDIRECTDRAWSURFACE3 dd_surface;
|
||||
LPDIRECTDRAWSURFACE3 dd_writebuf;
|
||||
};
|
||||
#endif
|
||||
|
||||
#define STDOUT_FILE TEXT("stdout.txt")
|
||||
#define STDERR_FILE TEXT("stderr.txt")
|
||||
#define DEFAULT_CONFIG_FILE "/dosbox.conf"
|
||||
|
@ -108,6 +115,7 @@ void MAPPER_StartUp(Section * sec);
|
|||
|
||||
enum SCREEN_TYPES {
|
||||
SCREEN_SURFACE,
|
||||
SCREEN_SURFACE_DDRAW,
|
||||
SCREEN_OVERLAY,
|
||||
SCREEN_OPENGL
|
||||
};
|
||||
|
@ -148,6 +156,12 @@ struct SDL_Block {
|
|||
bool pixel_data_range;
|
||||
#endif
|
||||
} opengl;
|
||||
#endif
|
||||
#if defined(HAVE_DDRAW_H) && defined(WIN32)
|
||||
struct {
|
||||
SDL_Surface * surface;
|
||||
RECT rect;
|
||||
} blit;
|
||||
#endif
|
||||
SDL_Rect clip;
|
||||
SDL_Surface * surface;
|
||||
|
@ -204,7 +218,7 @@ static void PauseDOSBox(void) {
|
|||
|
||||
/* Reset the screen with current values in the sdl structure */
|
||||
Bitu GFX_GetBestMode(Bitu flags) {
|
||||
Bitu testbpp,gotbpp,setflags;
|
||||
Bitu testbpp,gotbpp;
|
||||
switch (sdl.desktop.want_type) {
|
||||
case SCREEN_SURFACE:
|
||||
check_surface:
|
||||
|
@ -212,6 +226,7 @@ check_surface:
|
|||
if (flags & LOVE_8) testbpp=8;
|
||||
else if (flags & LOVE_16) testbpp=16;
|
||||
else if (flags & LOVE_32) testbpp=32;
|
||||
check_gotbpp:
|
||||
if (sdl.desktop.fullscreen) gotbpp=SDL_VideoModeOK(640,480,testbpp,SDL_FULLSCREEN|SDL_HWSURFACE|SDL_HWPALETTE);
|
||||
else gotbpp=sdl.desktop.bpp;
|
||||
/* If we can't get our favorite mode check for another working one */
|
||||
|
@ -230,6 +245,14 @@ check_surface:
|
|||
}
|
||||
/* Not a valid display depth found? Let's just hope sdl provides conversions */
|
||||
break;
|
||||
#if defined(HAVE_DDRAW_H) && defined(WIN32)
|
||||
case SCREEN_SURFACE_DDRAW:
|
||||
if (!(flags&CAN_32|CAN_16)) goto check_surface;
|
||||
if (flags & LOVE_16) testbpp=16;
|
||||
else if (flags & LOVE_32) testbpp=32;
|
||||
flags|=HAVE_SCALING;
|
||||
goto check_gotbpp;
|
||||
#endif
|
||||
case SCREEN_OVERLAY:
|
||||
if (flags & NEED_RGB || !(flags&CAN_32)) goto check_surface;
|
||||
flags|=HAVE_SCALING;
|
||||
|
@ -260,6 +283,36 @@ static int int_log2 (int val) {
|
|||
return log;
|
||||
}
|
||||
|
||||
|
||||
static SDL_Surface * GFX_SetupSurfaceScaled(Bit32u sdl_flags,Bit32u bpp) {
|
||||
if (sdl.desktop.fullscreen) {
|
||||
if (sdl.desktop.fixed) {
|
||||
double ratio_w=(double)sdl.desktop.width/(sdl.draw.width*sdl.draw.scalex);
|
||||
double ratio_h=(double)sdl.desktop.height/(sdl.draw.height*sdl.draw.scaley);
|
||||
if ( ratio_w < ratio_h) {
|
||||
sdl.clip.w=(Bit16u)sdl.desktop.width;
|
||||
sdl.clip.h=(Bit16u)(sdl.draw.height*sdl.draw.scaley*ratio_w);
|
||||
} else {
|
||||
sdl.clip.w=(Bit16u)(sdl.draw.width*sdl.draw.scalex*ratio_h);
|
||||
sdl.clip.h=(Bit16u)sdl.desktop.height;
|
||||
}
|
||||
sdl.clip.x=(Sint16)((sdl.desktop.width-sdl.clip.w)/2);
|
||||
sdl.clip.y=(Sint16)((sdl.desktop.height-sdl.clip.h)/2);
|
||||
return sdl.surface=SDL_SetVideoMode(sdl.desktop.width,sdl.desktop.height,bpp,sdl_flags|SDL_FULLSCREEN|SDL_HWSURFACE);
|
||||
} else {
|
||||
sdl.clip.x=0;sdl.clip.y=0;
|
||||
sdl.clip.w=(Bit16u)(sdl.draw.width*sdl.draw.scalex);
|
||||
sdl.clip.h=(Bit16u)(sdl.draw.height*sdl.draw.scaley);
|
||||
return sdl.surface=SDL_SetVideoMode(sdl.clip.w,sdl.clip.h,bpp,sdl_flags|SDL_FULLSCREEN|SDL_HWSURFACE);
|
||||
}
|
||||
} else {
|
||||
sdl.clip.x=0;sdl.clip.y=0;
|
||||
sdl.clip.w=(Bit16u)(sdl.draw.width*sdl.draw.scalex*sdl.desktop.hwscale);
|
||||
sdl.clip.h=(Bit16u)(sdl.draw.height*sdl.draw.scaley*sdl.desktop.hwscale);
|
||||
return sdl.surface=SDL_SetVideoMode(sdl.clip.w,sdl.clip.h,bpp,sdl_flags|SDL_HWSURFACE);
|
||||
}
|
||||
}
|
||||
|
||||
GFX_Modes GFX_SetSize(Bitu width,Bitu height,Bitu flags,double scalex,double scaley,GFX_ResetCallBack reset) {
|
||||
if (sdl.updating) GFX_EndUpdate();
|
||||
sdl.draw.width=width;
|
||||
|
@ -304,38 +357,46 @@ dosurface:
|
|||
break;
|
||||
}
|
||||
break;
|
||||
case SCREEN_OVERLAY:
|
||||
if (sdl.overlay) SDL_FreeYUVOverlay(sdl.overlay);
|
||||
sdl.overlay=0;
|
||||
if (!(flags&CAN_32) || (flags & NEED_RGB)) goto dosurface;
|
||||
if (sdl.desktop.fullscreen) {
|
||||
if (sdl.desktop.fixed) {
|
||||
double ratio_w=(double)sdl.desktop.width/(width*scalex);
|
||||
double ratio_h=(double)sdl.desktop.height/(height*scaley);
|
||||
if ( ratio_w < ratio_h) {
|
||||
sdl.clip.w=(Bit16u)sdl.desktop.width;
|
||||
sdl.clip.h=(Bit16u)(height*scaley*ratio_w);
|
||||
} else {
|
||||
sdl.clip.w=(Bit16u)(width*scalex*ratio_h);
|
||||
sdl.clip.h=(Bit16u)sdl.desktop.height;
|
||||
}
|
||||
sdl.clip.x=(Sint16)((sdl.desktop.width-sdl.clip.w)/2);
|
||||
sdl.clip.y=(Sint16)((sdl.desktop.height-sdl.clip.h)/2);
|
||||
sdl.surface=SDL_SetVideoMode(sdl.desktop.width,sdl.desktop.height,0,
|
||||
SDL_FULLSCREEN|SDL_HWSURFACE);
|
||||
} else {
|
||||
sdl.clip.x=0;sdl.clip.y=0;
|
||||
sdl.clip.w=(Bit16u)(width*scalex);
|
||||
sdl.clip.h=(Bit16u)(height*scaley);
|
||||
sdl.surface=SDL_SetVideoMode(sdl.clip.w,sdl.clip.h,0,
|
||||
SDL_FULLSCREEN|SDL_HWSURFACE);
|
||||
}
|
||||
} else {
|
||||
sdl.clip.x=0;sdl.clip.y=0;
|
||||
sdl.clip.w=(Bit16u)(width*scalex*sdl.desktop.hwscale);
|
||||
sdl.clip.h=(Bit16u)(height*scaley*sdl.desktop.hwscale);
|
||||
sdl.surface=SDL_SetVideoMode(sdl.clip.w,sdl.clip.h,0,SDL_HWSURFACE);
|
||||
#if defined(HAVE_DDRAW_H) && defined(WIN32)
|
||||
case SCREEN_SURFACE_DDRAW:
|
||||
if (flags & CAN_16) bpp=16;
|
||||
if (flags & CAN_32) bpp=32;
|
||||
if (sdl.blit.surface) {
|
||||
SDL_FreeSurface(sdl.blit.surface);
|
||||
sdl.blit.surface=0;
|
||||
}
|
||||
if (!GFX_SetupSurfaceScaled(0,bpp)) goto dosurface;
|
||||
sdl.blit.rect.top=sdl.clip.x;
|
||||
sdl.blit.rect.left=sdl.clip.y;
|
||||
sdl.blit.rect.right=sdl.clip.x+sdl.clip.w-1;
|
||||
sdl.blit.rect.bottom=sdl.clip.y+sdl.clip.h-1;
|
||||
sdl.blit.surface=SDL_CreateRGBSurface(SDL_HWSURFACE,sdl.draw.width,sdl.draw.height,
|
||||
sdl.surface->format->BitsPerPixel,
|
||||
sdl.surface->format->Rmask,
|
||||
sdl.surface->format->Gmask,
|
||||
sdl.surface->format->Bmask,
|
||||
0);
|
||||
if (!sdl.blit.surface || (!sdl.blit.surface->flags&SDL_HWSURFACE)) {
|
||||
LOG_MSG("Failed to create ddraw surface, back to normal surface.");
|
||||
goto dosurface;
|
||||
}
|
||||
switch (sdl.surface->format->BitsPerPixel) {
|
||||
case 15:sdl.draw.mode=GFX_15;break;
|
||||
case 16:sdl.draw.mode=GFX_16;break;
|
||||
case 32:sdl.draw.mode=GFX_32;break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
sdl.desktop.type=SCREEN_SURFACE_DDRAW;
|
||||
break;
|
||||
#endif
|
||||
case SCREEN_OVERLAY:
|
||||
if (sdl.overlay) {
|
||||
SDL_FreeYUVOverlay(sdl.overlay);
|
||||
sdl.overlay=0;
|
||||
}
|
||||
if (!(flags&CAN_32) || (flags & NEED_RGB)) goto dosurface;
|
||||
if (!GFX_SetupSurfaceScaled(0,0)) goto dosurface;
|
||||
sdl.overlay=SDL_CreateYUVOverlay(width*2,height,SDL_UYVY_OVERLAY,sdl.surface);
|
||||
if (!sdl.overlay) {
|
||||
LOG_MSG("SDL:Failed to create overlay, switching back to surface");
|
||||
|
@ -362,35 +423,7 @@ dosurface:
|
|||
goto dosurface;
|
||||
}
|
||||
SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
|
||||
if (sdl.desktop.fullscreen) {
|
||||
if (sdl.desktop.fixed) {
|
||||
double ratio_w=(double)sdl.desktop.width/(width*scalex);
|
||||
double ratio_h=(double)sdl.desktop.height/(height*scaley);
|
||||
if ( ratio_w < ratio_h) {
|
||||
sdl.clip.w=(Bit16u)sdl.desktop.width;
|
||||
sdl.clip.h=(Bit16u)(height*scaley*ratio_w);
|
||||
} else {
|
||||
sdl.clip.w=(Bit16u)(width*scalex*ratio_h);
|
||||
sdl.clip.h=(Bit16u)sdl.desktop.height;
|
||||
}
|
||||
sdl.clip.x=(Sint16)((sdl.desktop.width-sdl.clip.w)/2);
|
||||
sdl.clip.y=(Sint16)((sdl.desktop.height-sdl.clip.h)/2);
|
||||
sdl.surface=SDL_SetVideoMode(sdl.desktop.width,sdl.desktop.height,0,
|
||||
SDL_OPENGL|SDL_FULLSCREEN|SDL_HWSURFACE);
|
||||
} else {
|
||||
sdl.clip.x=0;sdl.clip.y=0;
|
||||
sdl.clip.w=(Bit16u)(width*scalex);
|
||||
sdl.clip.h=(Bit16u)(height*scaley);
|
||||
sdl.surface=SDL_SetVideoMode(sdl.clip.w,sdl.clip.h,0,
|
||||
SDL_OPENGL|SDL_FULLSCREEN|SDL_HWSURFACE);
|
||||
}
|
||||
} else {
|
||||
sdl.clip.x=0;sdl.clip.y=0;
|
||||
sdl.clip.w=(Bit16u)(width*scalex*sdl.desktop.hwscale);
|
||||
sdl.clip.h=(Bit16u)(height*scaley*sdl.desktop.hwscale);
|
||||
sdl.surface=SDL_SetVideoMode(sdl.clip.w,sdl.clip.h,0,
|
||||
SDL_OPENGL|SDL_HWSURFACE);
|
||||
}
|
||||
GFX_SetupSurfaceScaled(SDL_OPENGL,0);
|
||||
if (!sdl.surface || sdl.surface->format->BitsPerPixel<15) {
|
||||
LOG_MSG("SDL:OPENGL:Can't open drawing surface, are you running in 16bpp(or higher) mode?");
|
||||
goto dosurface;
|
||||
|
@ -514,6 +547,17 @@ bool GFX_StartUpdate(Bit8u * & pixels,Bitu & pitch) {
|
|||
pixels+=sdl.clip.x*sdl.surface->format->BytesPerPixel;
|
||||
pitch=sdl.surface->pitch;
|
||||
return true;
|
||||
#if defined(HAVE_DDRAW_H) && defined(WIN32)
|
||||
case SCREEN_SURFACE_DDRAW:
|
||||
if (SDL_LockSurface(sdl.blit.surface)) {
|
||||
LOG_MSG("SDL Lock failed");
|
||||
sdl.updating=false;
|
||||
return false;
|
||||
}
|
||||
pixels=(Bit8u *)sdl.blit.surface->pixels;
|
||||
pitch=sdl.blit.surface->pitch;
|
||||
return true;
|
||||
#endif
|
||||
case SCREEN_OVERLAY:
|
||||
SDL_LockYUVOverlay(sdl.overlay);
|
||||
pixels=(Bit8u *)*(sdl.overlay->pixels);
|
||||
|
@ -539,6 +583,18 @@ void GFX_EndUpdate(void) {
|
|||
}
|
||||
SDL_Flip(sdl.surface);
|
||||
break;
|
||||
#if defined(HAVE_DDRAW_H) && defined(WIN32)
|
||||
case SCREEN_SURFACE_DDRAW:
|
||||
if (SDL_MUSTLOCK(sdl.blit.surface)) {
|
||||
SDL_UnlockSurface(sdl.blit.surface);
|
||||
}
|
||||
IDirectDrawSurface3_Blt(
|
||||
sdl.surface->hwdata->dd_surface,&sdl.blit.rect,
|
||||
sdl.blit.surface->hwdata->dd_surface,0,
|
||||
DDBLT_WAIT, NULL);
|
||||
SDL_Flip(sdl.surface);
|
||||
break;
|
||||
#endif
|
||||
case SCREEN_OVERLAY:
|
||||
SDL_UnlockYUVOverlay(sdl.overlay);
|
||||
SDL_DisplayYUVOverlay(sdl.overlay,&sdl.clip);
|
||||
|
@ -574,6 +630,7 @@ void GFX_SetPalette(Bitu start,Bitu count,GFX_PalEntry * entries) {
|
|||
Bitu GFX_GetRGB(Bit8u red,Bit8u green,Bit8u blue) {
|
||||
switch (sdl.desktop.type) {
|
||||
case SCREEN_SURFACE:
|
||||
case SCREEN_SURFACE_DDRAW:
|
||||
return SDL_MapRGB(sdl.surface->format,red,green,blue);
|
||||
case SCREEN_OVERLAY:
|
||||
{
|
||||
|
@ -652,6 +709,10 @@ static void GUI_StartUp(Section * sec) {
|
|||
const char * output=section->Get_string("output");
|
||||
if (!strcasecmp(output,"surface")) {
|
||||
sdl.desktop.want_type=SCREEN_SURFACE;
|
||||
#if defined(HAVE_DDRAW_H) && defined(WIN32)
|
||||
} else if (!strcasecmp(output,"ddraw")) {
|
||||
sdl.desktop.want_type=SCREEN_SURFACE_DDRAW;
|
||||
#endif
|
||||
} else if (!strcasecmp(output,"overlay")) {
|
||||
sdl.desktop.want_type=SCREEN_OVERLAY;
|
||||
#if C_OPENGL
|
||||
|
|
Loading…
Add table
Reference in a new issue