fixed VSync & TripleBuffering behaviour

workaround: VSync will be disabled when the menu is opened in full screen mode
dynamic size for text messages
image will not be rendered to backbuffer but to textured triangle strip
fullScreenStretch will be applied immediately
bBilinear filter was not applied at initialization
minor fixes
This commit is contained in:
spacy51 2007-12-01 10:19:06 +00:00
parent 651091dd8c
commit cb6c92b8ad
3 changed files with 208 additions and 124 deletions

View File

@ -1,4 +1,5 @@
Known Bugs: Known Bugs:
- fsMaxScale = 1 in Direct3D fullscreen results in wrong image size - Direct3D: fsMaxScale = 1 in fullscreen mode with visible menu results in too small height of the image
- Direct3D: Menu toggle takes a little too long - Direct3D: Menu toggle takes a little too long
- Direct3D: VSync will be disabled in full screen mode while the menu is visible in order to work around poor performance

View File

@ -1,19 +1,19 @@
VisualBoyAdvance S1.7.6 VisualBoyAdvance-M
Nintendo Game Boy / Game Boy Advance Emulator Nintendo Game Boy / Game Boy Advance Emulator
Based on official VBA Version 1.7.2
Original Project Homepage: vba.ngemu.com
This program is distributed under the GNU General Public License This program is distributed under the GNU General Public License
http://www.gnu.org/licenses/gpl.html http://www.gnu.org/licenses/gpl.html
VBA Official Version 1.7.2 with changes by Spacy
Spacy51@gmx.de (Write in english or in german)
Special Build Aturhors Homepage: www.spacyhacks.de.vu
Original Project Homepage: vba.ngemu.com
My aim:
I want to make this emulator fit my needs and hopefully the needs of others, Aim:
which want a light-weight small, fast and multimedial emulator for the GBA Combine the best features of the VBA forks in one build.
that makes as much use of the power of modern PCs as possible (but with sense). Multi-platform support.
If you need one of the removed features, just use the original VBA emulator.
Thanks go to: Thanks go to:
suanyuan For help in compilation and other fixes suanyuan For help in compilation and other fixes
@ -21,8 +21,10 @@ Tauwasser For help in assembler
WingX For fixing a linker error WingX For fixing a linker error
The following changes have been made:
-------------------
Changes from VBA-S:
-------------------
S1.7.6: S1.7.6:
Emu: Emu:
- Readded MMX macro - Readded MMX macro

View File

@ -2,6 +2,7 @@
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2004 Forgotten and the VBA development team // Copyright (C) 2004 Forgotten and the VBA development team
// Copyright (C) 2005-2006 VBA development team // Copyright (C) 2005-2006 VBA development team
// Copyright (C) 2007 VBA-M team
// This program is free software; you can redistribute it and/or modify // This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
@ -33,7 +34,7 @@
// Direct3D // Direct3D
#define DIRECT3D_VERSION 0x0900 #define DIRECT3D_VERSION 0x0900
#include <d3d9.h> // main include file #include <d3d9.h> // main include file
#include <D3dx9core.h> // required for font rednering #include <D3dx9core.h> // required for font rendering
#include <Dxerr.h> // contains debug functions #include <Dxerr.h> // contains debug functions
extern int Init_2xSaI(u32); // initializes all pixel filters extern int Init_2xSaI(u32); // initializes all pixel filters
@ -43,6 +44,7 @@ extern int systemSpeed;
#define new DEBUG_NEW #define new DEBUG_NEW
#undef THIS_FILE #undef THIS_FILE
static char THIS_FILE[] = __FILE__; static char THIS_FILE[] = __FILE__;
extern void log(const char *,...);
#endif #endif
#ifdef MMX #ifdef MMX
@ -54,26 +56,34 @@ extern int winVideoModeSelect(CWnd *, GUID **);
class Direct3DDisplay : public IDisplay { class Direct3DDisplay : public IDisplay {
private: private:
bool initializing;
LPDIRECT3D9 pD3D; LPDIRECT3D9 pD3D;
LPDIRECT3DDEVICE9 pDevice; LPDIRECT3DDEVICE9 pDevice;
D3DDISPLAYMODE mode; D3DDISPLAYMODE mode;
D3DPRESENT_PARAMETERS dpp; D3DPRESENT_PARAMETERS dpp;
D3DFORMAT screenFormat; D3DFORMAT screenFormat;
LPDIRECT3DSURFACE9 emulatedImage; LPDIRECT3DTEXTURE9 emulatedImage;
D3DTEXTUREFILTERTYPE filter;
int width; int width;
int height; int height;
RECT destRect; RECT destRect;
bool failed; bool failed;
ID3DXFont *pFont; ID3DXFont *pFont;
struct VERTEX {
FLOAT x, y, z, rhw; // screen coordinates
FLOAT tx, ty; // texture coordinates
} Vertices[4];
// Vertices order:
// 1 3
// 0 2
void createFont(); void createFont();
void destroyFont(); void destroyFont();
void createSurface(); void createTexture();
void destroySurface(); void destroyTexture();
void calculateDestRect(); void calculateDestRect();
bool resetDevice(); bool resetDevice();
void setPresentationType(); void prepareDisplayMode();
public: public:
Direct3DDisplay(); Direct3DDisplay();
@ -95,6 +105,7 @@ public:
Direct3DDisplay::Direct3DDisplay() Direct3DDisplay::Direct3DDisplay()
{ {
initializing = false;
pD3D = NULL; pD3D = NULL;
pDevice = NULL; pDevice = NULL;
screenFormat = D3DFMT_X8R8G8B8; screenFormat = D3DFMT_X8R8G8B8;
@ -103,7 +114,6 @@ Direct3DDisplay::Direct3DDisplay()
failed = false; failed = false;
pFont = NULL; pFont = NULL;
emulatedImage = NULL; emulatedImage = NULL;
filter = D3DTEXF_POINT;
} }
@ -112,35 +122,51 @@ Direct3DDisplay::~Direct3DDisplay()
cleanup(); cleanup();
} }
void Direct3DDisplay::setPresentationType() void Direct3DDisplay::prepareDisplayMode()
{ {
// Change display mode // Change display mode
memset(&dpp, 0, sizeof(dpp)); memset(&dpp, 0, sizeof(dpp));
dpp.Windowed = !(theApp.videoOption>=VIDEO_320x240); dpp.Windowed = !( theApp.videoOption >= VIDEO_320x240 );
if (!dpp.Windowed) if( !dpp.Windowed ) {
dpp.BackBufferFormat = dpp.BackBufferFormat = (theApp.fsColorDepth == 32) ? D3DFMT_X8R8G8B8 : D3DFMT_R5G6B5;
(theApp.fsColorDepth == 32) ? D3DFMT_X8R8G8B8 : D3DFMT_R5G6B5; } else {
else
dpp.BackBufferFormat = mode.Format; dpp.BackBufferFormat = mode.Format;
dpp.BackBufferCount = 3; }
dpp.BackBufferCount = theApp.tripleBuffering ? 2 : 1;
dpp.MultiSampleType = D3DMULTISAMPLE_NONE; dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
dpp.BackBufferWidth = !dpp.Windowed ? theApp.fsWidth : theApp.surfaceSizeX; dpp.BackBufferWidth = !dpp.Windowed ? theApp.fsWidth : theApp.surfaceSizeX;
dpp.BackBufferHeight = !dpp.Windowed ? theApp.fsHeight : theApp.surfaceSizeY; dpp.BackBufferHeight = !dpp.Windowed ? theApp.fsHeight : theApp.surfaceSizeY;
dpp.hDeviceWindow = theApp.m_pMainWnd->GetSafeHwnd(); dpp.hDeviceWindow = theApp.m_pMainWnd->GetSafeHwnd();
dpp.FullScreen_RefreshRateInHz = dpp.Windowed ? 0 : theApp.fsFrequency; dpp.FullScreen_RefreshRateInHz = dpp.Windowed ? 0 : theApp.fsFrequency;
dpp.Flags = theApp.menuToggle ? D3DPRESENTFLAG_LOCKABLE_BACKBUFFER : 0; if( ( dpp.Windowed == FALSE ) && theApp.menuToggle ) {
if (theApp.vsync) dpp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE; // VSync } else {
else dpp.Flags = 0;
dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; // No Sync }
dpp.PresentationInterval = theApp.vsync ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE;
// D3DPRESENT_INTERVAL_ONE means VSync ON
if( theApp.vsync && ( dpp.Windowed == FALSE ) && theApp.menuToggle ) {
// VSync will be disabled when the menu is opened in full screen mode
dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
}
#ifdef _DEBUG
TRACE( _T("prepareDisplayMode:\n") );
TRACE( _T("%i x %i @ %iHz:\n"), dpp.BackBufferWidth, dpp.BackBufferHeight, dpp.FullScreen_RefreshRateInHz );
TRACE( _T("Buffer Count: %i\n"), dpp.BackBufferCount+1 );
TRACE( _T("VSync: %i\n"), dpp.PresentationInterval==D3DPRESENT_INTERVAL_ONE );
TRACE( _T("LOCKABLE_BACKBUFFER: %i\n\n"), dpp.Flags==D3DPRESENTFLAG_LOCKABLE_BACKBUFFER );
#endif
} }
void Direct3DDisplay::cleanup() void Direct3DDisplay::cleanup()
{ {
destroyFont(); destroyFont();
destroySurface(); destroyTexture();
if( pDevice ) { if( pDevice ) {
pDevice->Release(); pDevice->Release();
@ -156,20 +182,23 @@ void Direct3DDisplay::cleanup()
bool Direct3DDisplay::initialize() bool Direct3DDisplay::initialize()
{ {
switch(theApp.cartridgeType) #ifdef _DEBUG
TRACE( _T("Initializing Direct3D renderer {\n") );
#endif
initializing = true;
switch( theApp.cartridgeType )
{ {
case IMAGE_GBA: case IMAGE_GBA:
theApp.sizeX = 240; theApp.sizeX = 240;
theApp.sizeY = 160; theApp.sizeY = 160;
break; break;
case IMAGE_GB: case IMAGE_GB:
if (gbBorderOn) if(gbBorderOn) {
{
theApp.sizeX = 256; theApp.sizeX = 256;
theApp.sizeY = 224; theApp.sizeY = 224;
} } else {
else
{
theApp.sizeX = 160; theApp.sizeX = 160;
theApp.sizeY = 144; theApp.sizeY = 144;
} }
@ -268,7 +297,7 @@ bool Direct3DDisplay::initialize()
NULL, NULL,
0); 0);
if (!(HWND)*pWnd) { if( !((HWND)*pWnd) ) {
DXTRACE_ERR_MSGBOX( _T("Error creating window"), 0 ); DXTRACE_ERR_MSGBOX( _T("Error creating window"), 0 );
return FALSE; return FALSE;
} }
@ -296,19 +325,19 @@ bool Direct3DDisplay::initialize()
D3DDISPLAYMODE dm; D3DDISPLAYMODE dm;
nModes = pD3D->GetAdapterModeCount(theApp.fsAdapter, mode.Format); nModes = pD3D->GetAdapterModeCount(theApp.fsAdapter, mode.Format);
for (i = 0; i<nModes; i++) for( i = 0; i<nModes; i++ )
{ {
if (D3D_OK == pD3D->EnumAdapterModes(theApp.fsAdapter, mode.Format, i, &dm) ) if( D3D_OK == pD3D->EnumAdapterModes(theApp.fsAdapter, mode.Format, i, &dm) )
{ {
if ( (dm.Width == 320) && (dm.Height == 240) ) if( (dm.Width == 320) && (dm.Height == 240) )
theApp.mode320Available = true; theApp.mode320Available = true;
if ( (dm.Width == 640) && (dm.Height == 480) ) if( (dm.Width == 640) && (dm.Height == 480) )
theApp.mode640Available = true; theApp.mode640Available = true;
if ( (dm.Width == 800) && (dm.Height == 600) ) if( (dm.Width == 800) && (dm.Height == 600) )
theApp.mode800Available = true; theApp.mode800Available = true;
if ( (dm.Width == 1024) && (dm.Height == 768) ) if( (dm.Width == 1024) && (dm.Height == 768) )
theApp.mode1024Available = true; theApp.mode1024Available = true;
if ( (dm.Width == 1280) && (dm.Height == 1024) ) if( (dm.Width == 1280) && (dm.Height == 1024) )
theApp.mode1280Available = true; theApp.mode1280Available = true;
} }
} }
@ -366,7 +395,7 @@ bool Direct3DDisplay::initialize()
// create device // create device
setPresentationType(); prepareDisplayMode();
HRESULT hret = pD3D->CreateDevice( HRESULT hret = pD3D->CreateDevice(
D3DADAPTER_DEFAULT, D3DADAPTER_DEFAULT,
@ -381,20 +410,25 @@ bool Direct3DDisplay::initialize()
} }
createFont(); createFont();
createSurface(); createTexture();
setOption( _T("d3dFilter"), theApp.d3dFilter );
calculateDestRect(); calculateDestRect();
setOption( _T("d3dFilter"), theApp.d3dFilter ); initializing = false;
if(failed) return false; if(failed) return false;
#ifdef _DEBUG
TRACE( _T("} Finished Direct3D renderer initialization\n\n") );
#endif
return TRUE; return TRUE;
} }
void Direct3DDisplay::renderMenu() void Direct3DDisplay::renderMenu()
{ {
checkFullScreen(); //checkFullScreen();
if(theApp.m_pMainWnd) { if(theApp.m_pMainWnd) {
theApp.m_pMainWnd->DrawMenuBar(); theApp.m_pMainWnd->DrawMenuBar();
} }
@ -422,8 +456,9 @@ void Direct3DDisplay::render()
// copy pix to emulatedImage and apply pixel filter if selected // copy pix to emulatedImage and apply pixel filter if selected
HRESULT hr; HRESULT hr;
D3DLOCKED_RECT lr; D3DLOCKED_RECT lr;
if( FAILED( hr = emulatedImage->LockRect( &lr, NULL, D3DLOCK_DISCARD ) ) ) {
DXTRACE_ERR_MSGBOX( _T("Can not lock back buffer"), hr ); if( FAILED( hr = emulatedImage->LockRect( 0, &lr, NULL, D3DLOCK_DISCARD ) ) ) {
DXTRACE_ERR_MSGBOX( _T("Can not lock texture"), hr );
return; return;
} else { } else {
if( !theApp.filterFunction ) { if( !theApp.filterFunction ) {
@ -438,35 +473,23 @@ void Direct3DDisplay::render()
theApp.filterWidth, theApp.filterWidth,
theApp.filterHeight); theApp.filterHeight);
} }
emulatedImage->UnlockRect(); emulatedImage->UnlockRect( 0 );
} }
// copy emulatedImage to pBackBuffer and scale with or without aspect ratio // set emulatedImage as active texture
LPDIRECT3DSURFACE9 pBackBuffer; pDevice->SetTexture( 0, emulatedImage );
pDevice->GetBackBuffer( 0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer );
if( theApp.fullScreenStretch ) {
pDevice->StretchRect( emulatedImage, NULL, pBackBuffer, NULL, filter );
} else {
pDevice->StretchRect( emulatedImage, NULL, pBackBuffer, &destRect, filter );
}
pBackBuffer->Release();
pBackBuffer = NULL;
// render textured triangles
pDevice->SetFVF( D3DFVF_XYZRHW | D3DFVF_TEX1 );
pDevice->DrawPrimitiveUP( D3DPT_TRIANGLESTRIP, 2, Vertices, sizeof(VERTEX) );
// render speed and status messages
D3DCOLOR color; D3DCOLOR color;
RECT r; RECT r;
r.left = 4; r.left = 0;
r.right = dpp.BackBufferWidth - 4; r.top = 0;
r.right = dpp.BackBufferWidth - 1;
if( theApp.screenMessage ) { r.bottom = dpp.BackBufferHeight - 1;
color = theApp.showSpeedTransparent ? D3DCOLOR_ARGB(0x7F, 0xFF, 0x00, 0x00) : D3DCOLOR_ARGB(0xFF, 0xFF, 0x00, 0x00);
if( ( ( GetTickCount() - theApp.screenMessageTime ) < 3000 ) && !theApp.disableStatusMessage && pFont ) {
r.top = dpp.BackBufferHeight - 20;
r.bottom = dpp.BackBufferHeight - 4;
pFont->DrawText( NULL, theApp.screenMessageBuffer, -1, &r, 0, color );
} else {
theApp.screenMessage = false;
}
}
if( theApp.showSpeed && ( theApp.videoOption > VIDEO_4X ) ) { if( theApp.showSpeed && ( theApp.videoOption > VIDEO_4X ) ) {
color = theApp.showSpeedTransparent ? D3DCOLOR_ARGB(0x7F, 0x00, 0x00, 0xFF) : D3DCOLOR_ARGB(0xFF, 0x00, 0x00, 0xFF); color = theApp.showSpeedTransparent ? D3DCOLOR_ARGB(0x7F, 0x00, 0x00, 0xFF) : D3DCOLOR_ARGB(0xFF, 0x00, 0x00, 0xFF);
@ -477,9 +500,16 @@ void Direct3DDisplay::render()
sprintf( buffer, "%3d%%(%d, %d fps)", systemSpeed, systemFrameSkip, theApp.showRenderedFrames ); sprintf( buffer, "%3d%%(%d, %d fps)", systemSpeed, systemFrameSkip, theApp.showRenderedFrames );
} }
r.top = 4; pFont->DrawText( NULL, buffer, -1, &r, DT_LEFT | DT_TOP, color );
r.bottom = 20; }
pFont->DrawText( NULL, buffer, -1, &r, 0, color );
if( theApp.screenMessage ) {
color = theApp.showSpeedTransparent ? D3DCOLOR_ARGB(0x7F, 0xFF, 0x00, 0x00) : D3DCOLOR_ARGB(0xFF, 0xFF, 0x00, 0x00);
if( ( ( GetTickCount() - theApp.screenMessageTime ) < 3000 ) && !theApp.disableStatusMessage && pFont ) {
pFont->DrawText( NULL, theApp.screenMessageBuffer, -1, &r, DT_LEFT | DT_BOTTOM, color );
} else {
theApp.screenMessage = false;
}
} }
pDevice->EndScene(); pDevice->EndScene();
@ -495,8 +525,8 @@ bool Direct3DDisplay::changeRenderSize( int w, int h )
if( (w != width) || (h != height) ) { if( (w != width) || (h != height) ) {
width = w; height = h; width = w; height = h;
if( pDevice ) { if( pDevice ) {
destroySurface(); destroyTexture();
createSurface(); createTexture();
calculateDestRect(); calculateDestRect();
} }
} }
@ -506,15 +536,17 @@ bool Direct3DDisplay::changeRenderSize( int w, int h )
void Direct3DDisplay::resize( int w, int h ) void Direct3DDisplay::resize( int w, int h )
{ {
if( initializing ) {
return;
}
if( (w != dpp.BackBufferWidth) || (h != dpp.BackBufferHeight) ) { if( (w != dpp.BackBufferWidth) || (h != dpp.BackBufferHeight) ) {
dpp.BackBufferWidth = (UINT)w;
dpp.BackBufferHeight = (UINT)h;
resetDevice(); resetDevice();
calculateDestRect(); calculateDestRect();
} }
if(theApp.videoOption > VIDEO_4X) if( theApp.videoOption > VIDEO_4X ) {
resetDevice(); resetDevice();
}
} }
@ -529,7 +561,7 @@ void Direct3DDisplay::createFont()
if( !pFont ) { if( !pFont ) {
HRESULT hr = D3DXCreateFont( HRESULT hr = D3DXCreateFont(
pDevice, pDevice,
14, dpp.BackBufferHeight/20, // dynamic font size
0, 0,
FW_BOLD, FW_BOLD,
1, 1,
@ -556,23 +588,24 @@ void Direct3DDisplay::destroyFont()
} }
void Direct3DDisplay::createSurface() void Direct3DDisplay::createTexture()
{ {
if( !emulatedImage ) { if( !emulatedImage ) {
HRESULT hr = pDevice->CreateOffscreenPlainSurface( HRESULT hr = pDevice->CreateTexture(
width, height, width, height, 1, // 1 level, no mipmaps
dpp.BackBufferFormat, D3DUSAGE_DYNAMIC, dpp.BackBufferFormat,
D3DPOOL_DEFAULT, D3DPOOL_DEFAULT, // anything else won't work
&emulatedImage, &emulatedImage,
NULL ); NULL );
if( FAILED( hr ) ) { if( FAILED( hr ) ) {
DXTRACE_ERR_MSGBOX( _T("createSurface failed"), hr ); DXTRACE_ERR_MSGBOX( _T("createTexture failed"), hr );
} }
} }
} }
void Direct3DDisplay::destroySurface() void Direct3DDisplay::destroyTexture()
{ {
if( emulatedImage ) { if( emulatedImage ) {
emulatedImage->Release(); emulatedImage->Release();
@ -583,38 +616,76 @@ void Direct3DDisplay::destroySurface()
void Direct3DDisplay::calculateDestRect() void Direct3DDisplay::calculateDestRect()
{ {
float scaleX = (float)dpp.BackBufferWidth / (float)width; if( theApp.fullScreenStretch ) {
float scaleY = (float)dpp.BackBufferHeight / (float)height; destRect.left = 0;
float min = (scaleX < scaleY) ? scaleX : scaleY; destRect.top = 0;
if( theApp.fsMaxScale && (min > theApp.fsMaxScale) ) { destRect.right = dpp.BackBufferWidth; // for some reason there'l be a black
min = (float)theApp.fsMaxScale; destRect.bottom = dpp.BackBufferHeight; // border line when using -1 at the end
} } else {
destRect.left = 0; // use aspect ratio
destRect.top = 0; float scaleX = (float)dpp.BackBufferWidth / (float)width;
destRect.right = (LONG)(width * min); float scaleY = (float)dpp.BackBufferHeight / (float)height;
destRect.bottom = (LONG)(height * min); float min = (scaleX < scaleY) ? scaleX : scaleY;
if( destRect.right != dpp.BackBufferWidth ) { if( theApp.fsMaxScale && (min > theApp.fsMaxScale) ) {
LONG diff = (dpp.BackBufferWidth - destRect.right) / 2; min = (float)theApp.fsMaxScale;
destRect.left += diff; }
destRect.right += diff; destRect.left = 0;
} destRect.top = 0;
if( destRect.bottom != dpp.BackBufferHeight ) { destRect.right = (LONG)(width * min);
LONG diff = (dpp.BackBufferHeight - destRect.bottom) / 2; destRect.bottom = (LONG)(height * min);
destRect.top += diff; if( destRect.right != dpp.BackBufferWidth ) {
destRect.bottom += diff; LONG diff = (dpp.BackBufferWidth - destRect.right) / 2;
destRect.left += diff;
destRect.right += diff;
}
if( destRect.bottom != dpp.BackBufferHeight ) {
LONG diff = (dpp.BackBufferHeight - destRect.bottom) / 2;
destRect.top += diff;
destRect.bottom += diff;
}
} }
// configure triangles
Vertices[0].x = (FLOAT)destRect.left;
Vertices[0].y = (FLOAT)destRect.bottom;
Vertices[0].z = 0.5f;
Vertices[0].rhw = 1.0f;
Vertices[0].tx = 0.0f;
Vertices[0].ty = 1.0f;
Vertices[1].x = (FLOAT)destRect.left;
Vertices[1].y = (FLOAT)destRect.top;
Vertices[1].z = 0.5f;
Vertices[1].rhw = 1.0f;
Vertices[1].tx = 0.0f;
Vertices[1].ty = 0.0f;
Vertices[2].x = (FLOAT)destRect.right;
Vertices[2].y = (FLOAT)destRect.bottom;
Vertices[2].z = 0.5f;
Vertices[2].rhw = 1.0f;
Vertices[2].tx = 1.0f;
Vertices[2].ty = 1.0f;
Vertices[3].x = (FLOAT)destRect.right;
Vertices[3].y = (FLOAT)destRect.top;
Vertices[3].z = 0.5f;
Vertices[3].rhw = 1.0f;
Vertices[3].tx = 1.0f;
Vertices[3].ty = 0.0f;
} }
void Direct3DDisplay::setOption( const char *option, int value ) void Direct3DDisplay::setOption( const char *option, int value )
{ {
if( !_tcscmp( option, _T("vsync") ) ) { if( !_tcscmp( option, _T("vsync") ) ) {
theApp.vsync = true; // theApp.vsync has already been changed by the menu handler
// 'value' has the same value as theApp.vsync
resetDevice(); resetDevice();
} }
if( !_tcscmp( option, _T("tripleBuffering") ) ) { if( !_tcscmp( option, _T("tripleBuffering") ) ) {
theApp.tripleBuffering = true; // theApp.tripleBuffering has already been changed by the menu handler
// 'value' has the same value as theApp.tripleBuffering
resetDevice(); resetDevice();
} }
@ -622,10 +693,12 @@ void Direct3DDisplay::setOption( const char *option, int value )
switch( value ) switch( value )
{ {
case 0: //point case 0: //point
filter = D3DTEXF_POINT; pDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT );
pDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_POINT );
break; break;
case 1: //linear case 1: //linear
filter = D3DTEXF_LINEAR; pDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
pDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
break; break;
} }
} }
@ -633,6 +706,10 @@ void Direct3DDisplay::setOption( const char *option, int value )
if( !_tcscmp( option, _T("maxScale") ) ) { if( !_tcscmp( option, _T("maxScale") ) ) {
calculateDestRect(); calculateDestRect();
} }
if( !_tcscmp( option, _T("fullScreenStretch") ) ) {
calculateDestRect();
}
} }
@ -642,21 +719,25 @@ bool Direct3DDisplay::resetDevice()
HRESULT hr; HRESULT hr;
destroyFont(); destroyFont();
destroySurface(); destroyTexture();
setPresentationType(); prepareDisplayMode();
if (!theApp.menuToggle)
pDevice->SetDialogBoxMode( FALSE ); if( dpp.Windowed == FALSE ) {
// SetDialogBoxMode needs D3DPRESENTFLAG_LOCKABLE_BACKBUFFER
if( FAILED( hr = pDevice->SetDialogBoxMode( theApp.menuToggle ? TRUE : FALSE ) ) ) {
DXTRACE_ERR( _T("can not switch to dialog box mode"), hr );
}
}
if( FAILED( hr = pDevice->Reset( &dpp ) ) ) { if( FAILED( hr = pDevice->Reset( &dpp ) ) ) {
//DXTRACE_ERR_MSGBOX( _T("pDevice->Reset failed"), hr ); DXTRACE_ERR( _T("pDevice->Reset failed\n"), hr );
failed = true; failed = true;
return false; return false;
} }
if (theApp.menuToggle)
pDevice->SetDialogBoxMode( TRUE );
createFont(); createFont();
createSurface(); createTexture();
setOption( _T("d3dFilter"), theApp.d3dFilter );
failed = false; failed = false;
return true; return true;
} }