Clean up resolution fallback logic

Add video settings for G400
Working on composited text
This commit is contained in:
Chris Danford
2003-06-05 19:29:27 +00:00
parent 43819f68c6
commit 428d560a6b
31 changed files with 602 additions and 310 deletions
+108
View File
@@ -0,0 +1,108 @@
#include "global.h"
/*
-----------------------------------------------------------------------------
Class: CompositedText
Desc: See header.
Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved.
Chris Danford
-----------------------------------------------------------------------------
*/
#include "CompositedText.h"
#include "Font.h"
#include "FontManager.h"
#include "RageDisplay.h"
#include "Actor.h"
#include "SDL_video.h"
#include "SDL_utils.h"
SDL_Surface* CreateCompositedText( CString sFontFile, CString sText )
{
// build a font texture
Font* pFont = FONT->LoadFont( sFontFile );
vector<wstring> asTextLines;
split(CStringToWstring(sText), L"\n", asTextLines, false);
/* calculate line lengths and widths */
vector<int> LineWidths;
int iWidestLineWidth = 0;
for( unsigned l=0; l<asTextLines.size(); l++ ) // for each line
{
LineWidths.push_back(pFont->GetLineWidthInSourcePixels( asTextLines[l] ));
iWidestLineWidth = max(iWidestLineWidth, LineWidths.back());
}
int TotalHeight = pFont->GetHeight() * asTextLines.size();
unsigned i;
int MinSpacing = 0;
/* The height (from the origin to the baseline): */
int Padding = max(pFont->GetLineSpacing(), MinSpacing) - pFont->GetHeight();
/* There's padding between every line: */
TotalHeight += Padding * (asTextLines.size()-1);
/* Because of the "draw extra pixels" and the fact that frame height is often
* greater than the line spacing, we need to add some padding around all edges.
* Is there a more elegant way we could be handling this? */
const int PADDING = 32;
int imageWidth = iWidestLineWidth+PADDING;
int imageHeight = TotalHeight+PADDING;
/* Make sure the image size is even to maintain pixel/texel alignment. */
if( imageWidth%2==1 ) imageWidth++;
if( imageHeight%2==1 ) imageHeight++;
/* Allocate surface */
PixelFormat pixfmt = FMT_RGBA8;
const PixelFormatDesc *pfd = DISPLAY->GetPixelFormatDesc(pixfmt);
SDL_Surface *img = SDL_CreateRGBSurfaceSane(SDL_SWSURFACE, imageWidth, imageHeight,
pfd->bpp, pfd->masks[0], pfd->masks[1], pfd->masks[2], pfd->masks[3]);
SDL_FillRect( img, NULL, 0x00000000 );
int iY = PADDING/2;
for( i=0; i<asTextLines.size(); i++ ) // foreach line
{
iY += pFont->GetHeight();
const wstring &sLine = asTextLines[i];
const int iLineWidth = LineWidths[i];
int iX = PADDING/2;
for( unsigned j=0; j<sLine.size(); j++ ) // for each character in the line
{
const glyph &g = pFont->GetGlyph( sLine[j] );
SDL_Rect blitSrc;
blitSrc.x = g.blitSrc.left;
blitSrc.w = g.blitSrc.right - g.blitSrc.left;
blitSrc.y = g.blitSrc.top;
blitSrc.h = g.blitSrc.bottom - g.blitSrc.top;
SDL_Rect blitDst;
blitDst.x = iX+g.hshift;
blitDst.w = g.width;
blitDst.y = iY+g.fp->vshift;
blitDst.h = g.height;
mySDL_BlitSurfaceSmartBlend( g.GetSurface(), &blitSrc, img, &blitDst );
// SDL_SaveBMP( img, "testingText.bmp" );
/* Advance the cursor. */
iX += g.hadvance;
}
/* The amount of padding a line needs: */
iY += Padding;
}
return img;
}
+22
View File
@@ -0,0 +1,22 @@
#ifndef CompositedText_H
#define CompositedText_H
/*
-----------------------------------------------------------------------------
Class: CompositedText
Desc: A little graphic to the left of the song's text banner in the MusicWheel.
Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved.
Chris Danford
-----------------------------------------------------------------------------
*/
#include "Sprite.h"
struct SDL_Surface;
SDL_Surface* CreateCompositedText( CString sFontFile, CString sText );
#endif
-1
View File
@@ -13,7 +13,6 @@
#include "DifficultyMeter.h"
#include "BitmapText.h"
#include "TextBanner.h"
#include "ActorFrame.h"
#include "Sprite.h"
#include "Quad.h"
+64 -39
View File
@@ -24,6 +24,8 @@
#include "GameManager.h"
#include "FontCharmaps.h"
#include "FontCharAliases.h"
#include "SDL_video.h"
#include "SDL_image.h"
/* Last private-use Unicode character: */
const wchar_t Font::DEFAULT_GLYPH = 0xF8FF;
@@ -31,6 +33,7 @@ const wchar_t Font::DEFAULT_GLYPH = 0xF8FF;
FontPage::FontPage()
{
m_pTexture = NULL;
m_pSurface = NULL;
}
void FontPage::Load( FontPageSettings cfg )
@@ -42,7 +45,10 @@ void FontPage::Load( FontPageSettings cfg )
ID.bStretch = true;
m_pTexture = TEXTUREMAN->LoadTexture( ID );
ASSERT( m_pTexture != NULL );
ASSERT( m_pTexture );
m_pSurface = IMG_Load( ID.filename );
ASSERT( m_pSurface );
// load character widths
vector<int> FrameWidths;
@@ -110,49 +116,64 @@ void FontPage::Load( FontPageSettings cfg )
void FontPage::SetTextureCoords(const vector<int> &widths)
{
for(int i = 0; i < m_pTexture->GetNumFrames(); ++i)
for(int y = 0; y < m_pTexture->GetFramesHigh(); ++y)
{
glyph g;
g.fp = this;
/* Make a copy of each texture rect, reducing each to the actual dimensions
* of the character (most characters don't take a full block). */
g.rect = *m_pTexture->GetTextureCoordRect(i);;
/* Set the width and height to the width and line spacing, respectively. */
g.width = float(widths[i]);
g.height = float(m_pTexture->GetSourceFrameHeight());
/* By default, advance one pixel more than the width. (This could be
* an option.) */
g.hadvance = int(g.width + 1);
/* Do the same thing with X. Do this by changing the actual rendered
* rect, instead of shifting it, so we don't render more than we need to. */
g.hshift = 0;
for(int x = 0; x < m_pTexture->GetFramesWide(); ++x)
{
int iPixelsToChopOff = m_pTexture->GetSourceFrameWidth() - widths[i];
if((iPixelsToChopOff % 2) == 1)
int i = y*m_pTexture->GetFramesHigh() + x;
glyph g;
g.fp = this;
/* Make a copy of each texture rect, reducing each to the actual dimensions
* of the character (most characters don't take a full block). */
g.rect = *m_pTexture->GetTextureCoordRect(i);
g.blitSrc = RectI(
m_pTexture->GetSourceFrameWidth()*x,
m_pTexture->GetSourceFrameHeight()*y,
m_pTexture->GetSourceFrameWidth()*(x+1),
m_pTexture->GetSourceFrameHeight()*(y+1) );
/* Set the width and height to the width and line spacing, respectively. */
g.width = float(widths[i]);
g.height = float(m_pTexture->GetSourceFrameHeight());
/* By default, advance one pixel more than the width. (This could be
* an option.) */
g.hadvance = int(g.width + 1);
/* Do the same thing with X. Do this by changing the actual rendered
* rect, instead of shifting it, so we don't render more than we need to. */
g.hshift = 0;
{
/* We don't want to chop off an odd number of pixels, since that'll
* put our texture coordinates between texels and make things blurrier.
* Note that, since we set hadvance above, this merely expands what
* we render; it doesn't advance the cursor further. So, glyphs
* that have an odd width should err to being a pixel offcenter left,
* not right. */
iPixelsToChopOff--;
g.width++;
int iPixelsToChopOff = m_pTexture->GetSourceFrameWidth() - widths[i];
if((iPixelsToChopOff % 2) == 1)
{
/* We don't want to chop off an odd number of pixels, since that'll
* put our texture coordinates between texels and make things blurrier.
* Note that, since we set hadvance above, this merely expands what
* we render; it doesn't advance the cursor further. So, glyphs
* that have an odd width should err to being a pixel offcenter left,
* not right. */
iPixelsToChopOff--;
g.width++;
}
g.blitSrc.left += iPixelsToChopOff/2;
g.blitSrc.right -= iPixelsToChopOff/2;
float fTexCoordsToChopOff = float(iPixelsToChopOff) / m_pTexture->GetSourceWidth();
g.rect.left += fTexCoordsToChopOff/2;
g.rect.right -= fTexCoordsToChopOff/2;
}
float fTexCoordsToChopOff = float(iPixelsToChopOff) / m_pTexture->GetSourceWidth();
g.rect.left += fTexCoordsToChopOff/2;
g.rect.right -= fTexCoordsToChopOff/2;
g.Texture = m_pTexture;
g.Surface = m_pSurface;
glyphs.push_back(g);
}
g.Texture = m_pTexture;
glyphs.push_back(g);
}
}
@@ -179,6 +200,8 @@ void FontPage::SetExtraPixels(int DrawExtraPixelsLeft, int DrawExtraPixelsRight)
float ExtraRight = min( float(DrawExtraPixelsRight), (iFrameWidth-iCharWidth)/2.0f );
/* Move left and expand right. */
glyphs[i].blitSrc.left -= ExtraLeft;
glyphs[i].blitSrc.right += ExtraRight;
glyphs[i].rect.left -= ExtraLeft / m_pTexture->GetSourceWidth();
glyphs[i].rect.right += ExtraRight / m_pTexture->GetSourceWidth();
glyphs[i].hshift -= ExtraLeft;
@@ -188,8 +211,10 @@ void FontPage::SetExtraPixels(int DrawExtraPixelsLeft, int DrawExtraPixelsRight)
FontPage::~FontPage()
{
if( m_pTexture != NULL )
if( m_pTexture )
TEXTUREMAN->UnloadTexture( m_pTexture );
if( m_pSurface )
SDL_FreeSurface( m_pSurface );
}
int Font::GetLineWidthInSourcePixels( const wstring &szLine ) const
+7
View File
@@ -16,11 +16,14 @@
#include "IniFile.h"
class FontPage;
struct SDL_Surface;
struct glyph {
FontPage *fp;
RageTexture *Texture;
RageTexture *GetTexture() const { return const_cast<RageTexture *>(Texture); }
SDL_Surface *Surface;
SDL_Surface *GetSurface() const { return Surface; }
/* Number of pixels to advance horizontally after drawing this character. */
int hadvance;
@@ -33,6 +36,9 @@ struct glyph {
/* Texture coordinate rect. */
RectF rect;
/* rect in pixels */
RectI blitSrc;
};
struct FontPageSettings
@@ -71,6 +77,7 @@ class FontPage
{
public:
RageTexture* m_pTexture;
SDL_Surface* m_pSurface;
CString m_sTexturePath;
+1 -1
View File
@@ -13,10 +13,10 @@
#include "ActorFrame.h"
#include "Banner.h"
#include "TextBanner.h"
#include "GameConstantsAndTypes.h"
#include "RandomSample.h"
#include "Style.h"
#include "BitmapText.h"
class JukeboxMenu: public ActorFrame
+1 -2
View File
@@ -400,8 +400,7 @@ void NoteDisplay::DrawHold( const HoldNote& hn, const bool bActive, const float
const float fYTail = bReverse ? fStartYPos : fEndYPos; // the center the tail
const bool bWavy = GAMESTATE->m_PlayerOptions[m_PlayerNumber].m_fEffects[PlayerOptions::EFFECT_DRUNK] > 0;
const int fYStep = bWavy ? 16 : 16;// causes crash w/ some NoteSkins : 128; // use small steps only if wavy
// If you don't include the 128 you can't compile this code!!!!!!! - Andy.
const int fYStep = 16; //bWavy ? 16 : 128; // use small steps only if wavy
const float fColorScale = 1*fLife + (1-fLife)*cache->m_fHoldNGGrayPercent;
+8 -9
View File
@@ -84,7 +84,7 @@ PrefsManager::PrefsManager()
m_iCoinsPerCredit = 1;
m_bJointPremium = false;
m_iBoostAppPriority = -1;
m_iPolygonRadar = -1;
m_bAntiAliasing = false;
m_ShowSongOptions = YES;
m_bDancePointsForOni = false;
m_bTimestamping = false;
@@ -112,7 +112,7 @@ PrefsManager::PrefsManager()
m_bHiddenSongs = false;
m_bVsync = true;
m_sVideoRenderers = "";
m_sVideoRenderers = ""; // StepMania.cpp sets this on first run
m_sSoundDrivers = DEFAULT_SOUND_DRIVER_LIST;
m_fSoundVolume = DEFAULT_SOUND_VOLUME;
/* This is experimental: let's see if preloading helps people's skipping.
@@ -178,8 +178,6 @@ void PrefsManager::ReadGlobalPrefsFromDisk( bool bSwitchToLastPlayedGame )
ini.GetValueB( "Options", "DelayedScreenLoad", m_bDelayedScreenLoad );
ini.GetValueI( "Options", "MusicWheelUsesSections", (int&)m_MusicWheelUsesSections );
ini.GetValueI( "Options", "MusicWheelSwitchSpeed", m_iMusicWheelSwitchSpeed );
ini.GetValue ( "Options", "VideoRenderers", m_sVideoRenderers );
ini.GetValue ( "Options", "LastSeenVideoDriver", m_sLastSeenVideoDriver );
ini.GetValue ( "Options", "SoundDrivers", m_sSoundDrivers );
ini.GetValueB( "Options", "EasterEggs", m_bEasterEggs );
ini.GetValueB( "Options", "MarvelousTiming", m_bMarvelousTiming );
@@ -189,7 +187,6 @@ void PrefsManager::ReadGlobalPrefsFromDisk( bool bSwitchToLastPlayedGame )
ini.GetValueI( "Options", "CoinsPerCredit", m_iCoinsPerCredit );
ini.GetValueB( "Options", "JointPremium", m_bJointPremium );
ini.GetValueI( "Options", "BoostAppPriority", m_iBoostAppPriority );
ini.GetValueI( "Options", "PolygonRadar", m_iPolygonRadar );
ini.GetValueB( "Options", "PickExtraStage", m_bPickExtraStage );
ini.GetValueF( "Options", "LongVerSeconds", m_fLongVerSongSeconds );
ini.GetValueF( "Options", "MarathonVerSeconds", m_fMarathonVerSongSeconds );
@@ -210,6 +207,9 @@ void PrefsManager::ReadGlobalPrefsFromDisk( bool bSwitchToLastPlayedGame )
ini.GetValueB( "Options", "UseUnlockSystem", m_bUseUnlockSystem );
ini.GetValueB( "Options", "FirstRun", m_bFirstRun );
ini.GetValueB( "Options", "AutoMapJoysticks", m_bAutoMapJoysticks );
ini.GetValue ( "Options", "LastSeenVideoDriver", m_sLastSeenVideoDriver );
ini.GetValue ( "Options", "VideoRenderers", m_sVideoRenderers );
ini.GetValueB( "Options", "AntiAliasing", m_bAntiAliasing );
m_asAdditionalSongFolders.clear();
CString sAdditionalSongFolders;
@@ -278,7 +278,6 @@ void PrefsManager::SaveGlobalPrefsToDisk()
ini.SetValueI( "Options", "CoinsPerCredit", m_iCoinsPerCredit );
ini.SetValueB( "Options", "JointPremium", m_bJointPremium );
ini.SetValueI( "Options", "BoostAppPriority", m_iBoostAppPriority );
ini.SetValueI( "Options", "PolygonRadar", m_iPolygonRadar );
ini.SetValueB( "Options", "PickExtraStage", m_bPickExtraStage );
ini.SetValueF( "Options", "LongVerSeconds", m_fLongVerSongSeconds );
ini.SetValueF( "Options", "MarathonVerSeconds", m_fMarathonVerSongSeconds );
@@ -298,7 +297,9 @@ void PrefsManager::SaveGlobalPrefsToDisk()
ini.SetValueB( "Options", "UseUnlockSystem", m_bUseUnlockSystem );
ini.SetValueB( "Options", "FirstRun", m_bFirstRun );
ini.SetValueB( "Options", "AutoMapJoysticks", m_bAutoMapJoysticks );
ini.SetValue ( "Options", "VideoRenderers", m_sVideoRenderers );
ini.SetValue ( "Options", "LastSeenVideoDriver", m_sLastSeenVideoDriver );
ini.SetValueB( "Options", "AntiAliasing", m_bAntiAliasing );
/* Only write these if they aren't the default. This ensures that we can change
* the default and have it take effect for everyone (except people who
@@ -307,8 +308,6 @@ void PrefsManager::SaveGlobalPrefsToDisk()
ini.SetValue ( "Options", "SoundDrivers", m_sSoundDrivers );
if(m_fSoundVolume != DEFAULT_SOUND_VOLUME)
ini.SetValueF( "Options", "SoundVolume", m_fSoundVolume );
if(m_sVideoRenderers != "")
ini.SetValue ( "Options", "Renderer", m_sVideoRenderers );
ini.SetValue( "Options", "AdditionalSongFolders", join(",", m_asAdditionalSongFolders) );
+2 -4
View File
@@ -85,14 +85,12 @@ public:
/* 0 = no; 1 = yes; -1 = auto (do whatever is appropriate for the arch). */
int m_iBoostAppPriority;
/* 0 = no; 1 = yes; -1 = auto (turn on for known-bad drivers) */
int m_iPolygonRadar;
CStringArray m_asAdditionalSongFolders;
CString m_DWIPath;
CString m_sVideoRenderers;
CString m_sLastSeenVideoDriver;
CString m_sVideoRenderers;
bool m_bAntiAliasing;
CString m_sSoundDrivers;
float m_fSoundVolume;
bool m_bSoundPreloadAll;
+14 -3
View File
@@ -25,6 +25,8 @@
#include "SDL_utils.h"
#include "SDL_dither.h"
#include "CompositedText.h"
#include "RageTimer.h"
static void GetResolutionFromFileName( CString sPath, int &Width, int &Height )
@@ -82,12 +84,21 @@ void RageBitmapTexture::Create()
/* Create (and return) a surface ready to be loaded to OpenGL */
/* Load the image into an SDL surface. */
SDL_Surface *img = IMG_Load(GetFilePath());
SDL_Surface *img;
if( GetID().filename.Right(3).CompareNoCase("ini")==0 )
{
img = CreateCompositedText( GetID().filename, GetID().text );
}
else
{
img = IMG_Load( GetID().filename );
}
/* XXX: Wait, we don't want to throw for all images; in particular, we
* want to tolerate corrupt/unknown background images. */
if(img == NULL)
RageException::Throw( "RageBitmapTexture: Couldn't load %s: %s", GetFilePath().c_str(), SDL_GetError() );
RageException::Throw( "RageBitmapTexture: Couldn't load %s: %s", GetID().filename.c_str(), SDL_GetError() );
if(actualID.bHotPinkColorKey)
{
@@ -111,7 +122,7 @@ void RageBitmapTexture::Create()
}
// look in the file name for a format hints
CString HintString = GetFilePath();
CString HintString = GetID().filename;
HintString.MakeLower();
if( HintString.Find("4alphaonly") != -1 ) actualID.iTransparencyOnly = 4;
+47
View File
@@ -48,6 +48,53 @@ CString PixelFormatToString( PixelFormat pixfmt )
return s[pixfmt];
};
// Return true if device was re-created and we need to reload textures.
bool RageDisplay::SetVideoMode( VideoModeParams p )
{
/* Round to the nearest valid fullscreen resolution */
if( !p.windowed )
{
if( p.width <= 320 ) p.width = 320;
else if( p.width <= 400 ) p.width = 400;
else if( p.width <= 512 ) p.width = 512;
else if( p.width <= 640 ) p.width = 640;
else if( p.width <= 800 ) p.width = 800;
else if( p.width <= 1024 ) p.width = 1024;
else if( p.width <= 1280 ) p.width = 1280;
switch( p.width )
{
case 320: p.height = 240; break;
case 400: p.height = 300; break;
case 512: p.height = 384; break;
case 640: p.height = 480; break;
case 800: p.height = 600; break;
case 1024: p.height = 768; break;
case 1280: p.height = 960; break;
default: ASSERT(0);
}
}
bool bNeedReloadTextures;
if( this->TryVideoMode(p,bNeedReloadTextures) )
return bNeedReloadTextures;
// fall back
p.windowed = false;
if( this->TryVideoMode(p,bNeedReloadTextures) )
return bNeedReloadTextures;
p.bpp = 16;
if( this->TryVideoMode(p,bNeedReloadTextures) )
return bNeedReloadTextures;
p.width = 640;
p.height = 480;
if( this->TryVideoMode(p,bNeedReloadTextures) )
return bNeedReloadTextures;
RageException::Throw( "SetVideoMode failed. Tried to fall back to other modes, but nothing worked." );
}
void RageDisplay::ProcessStatsOnFlip()
{
g_iFramesRenderedSinceLastCheck++;
+51 -7
View File
@@ -59,24 +59,63 @@ class RageDisplay
friend class RageTexture;
public:
struct VideoModeParams
{
// Initialize with a constructor so to guarantee all paramters
// are filled (in case new params are added).
VideoModeParams(
bool _windowed,
int _width,
int _height,
int _bpp,
int _rate,
bool _vsync,
bool _bAntiAliasing,
CString _sWindowTitle,
CString _sIconFile )
{
windowed = _windowed;
width = _width;
height = _height;
bpp = _bpp;
rate = _rate;
vsync = _vsync;
bAntiAliasing = _bAntiAliasing;
sWindowTitle = _sWindowTitle;
sIconFile = _sIconFile;
}
VideoModeParams() {}
bool windowed;
int width;
int height;
int bpp;
int rate;
bool vsync;
bool bAntiAliasing;
CString sWindowTitle;
CString sIconFile;
};
virtual const PixelFormatDesc *GetPixelFormatDesc(PixelFormat pf) const = 0;
// RageDisplay( bool windowed, int width, int height, int bpp, int rate, bool vsync, CString sWindowTitle, CString sIconFile );
virtual ~RageDisplay() { };
virtual void Update(float fDeltaTime) { }
virtual bool IsSoftwareRenderer() = 0;
virtual bool SetVideoMode( bool windowed, int width, int height, int bpp, int rate, bool vsync, CString sWindowTitle, CString sIconFile ) = 0;
// Don't override this. Override TryVideoMode() instead.
// This will set the video mode to be as close as possible to params.
// Return true if device was re-created and we need to reload textures.
bool SetVideoMode( VideoModeParams params );
/* Call this when the resolution has been changed externally: */
virtual void ResolutionChanged() { }
virtual void BeginFrame() = 0;
virtual void EndFrame() = 0;
virtual bool IsWindowed() const = 0;
virtual int GetWidth() const = 0;
virtual int GetHeight() const = 0;
virtual int GetBPP() const = 0;
virtual VideoModeParams GetVideoModeParams() const = 0;
bool IsWindowed() const { return this->GetVideoModeParams().windowed; }
virtual void SetBlendMode( BlendMode mode ) = 0;
@@ -140,6 +179,11 @@ public:
virtual void SaveScreenshot( CString sPath ) = 0;
protected:
// Return true if mode change was successful.
// bNewDeviceOut is set true if a new device was created and textures
// need to be reloaded.
virtual bool TryVideoMode( VideoModeParams params, bool &bNewDeviceOut ) = 0;
virtual void SetViewport(int shift_left, int shift_down) = 0;
void DrawPolyLine(const RageVertex &p1, const RageVertex &p2, float LineWidth );
+31 -73
View File
@@ -56,8 +56,7 @@ D3DCAPS8 g_DeviceCaps;
D3DDISPLAYMODE g_DesktopMode;
D3DPRESENT_PARAMETERS g_d3dpp;
int g_ModelMatrixCnt=0;
bool g_Windowed;
int g_CurrentHeight, g_CurrentWidth, g_CurrentBPP;
RageDisplay::VideoModeParams g_CurrentParams;
/* Direct3D doesn't associate a palette with textures.
* Instead, we load a palette into a slot. We need to keep track
@@ -187,7 +186,7 @@ const PixelFormatDesc *RageDisplay_D3D::GetPixelFormatDesc(PixelFormat pf) const
RageDisplay_D3D::RageDisplay_D3D( bool windowed, int width, int height, int bpp, int rate, bool vsync, CString sWindowTitle, CString sIconFile )
RageDisplay_D3D::RageDisplay_D3D( VideoModeParams p )
{
LOG->Trace( "RageDisplay_D3D::RageDisplay_D3D()" );
LOG->MapLog("renderer", "Current renderer: Direct3D");
@@ -247,8 +246,6 @@ RageDisplay_D3D::RageDisplay_D3D( bool windowed, int width, int height, int bpp,
SDL_EventState(0xFF /*SDL_ALLEVENTS*/, SDL_IGNORE);
SDL_EventState(SDL_VIDEORESIZE, SDL_ENABLE);
g_Windowed = false;
g_PaletteIndex.clear();
for( int i = 0; i < 256; ++i )
g_PaletteIndex.push_back(i);
@@ -256,23 +253,16 @@ RageDisplay_D3D::RageDisplay_D3D( bool windowed, int width, int height, int bpp,
// Save the original desktop format.
g_pd3d->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &g_DesktopMode );
// Create the SDL window
int flags = SDL_RESIZABLE | SDL_SWSURFACE;
SDL_Surface *screen = SDL_SetVideoMode(width, height, bpp, flags);
SDL_Surface *screen = SDL_SetVideoMode(p.width, p.height, p.bpp, flags);
if(!screen)
{
SDL_QuitSubSystem(SDL_INIT_VIDEO); // exit out of full screen. The ~RageDisplay will not be called!
RageException::Throw("SDL_SetVideoMode failed: %s", SDL_GetError());
}
if( SetVideoMode( windowed, width, height, bpp, rate, vsync, sWindowTitle, sIconFile ) )
return;
if( SetVideoMode( false, width, height, bpp, rate, vsync, sWindowTitle, sIconFile ) )
return;
if( SetVideoMode( false, width, height, 16, rate, vsync, sWindowTitle, sIconFile ) )
return;
SetVideoMode( p );
}
void RageDisplay_D3D::Update(float fDeltaTime)
@@ -283,8 +273,8 @@ void RageDisplay_D3D::Update(float fDeltaTime)
switch(event.type)
{
case SDL_VIDEORESIZE:
g_CurrentWidth = event.resize.w;
g_CurrentHeight = event.resize.h;
g_CurrentParams.width = event.resize.w;
g_CurrentParams.height = event.resize.h;
/* Let DISPLAY know that our resolution has changed. */
ResolutionChanged();
@@ -382,41 +372,18 @@ HWND GetHwnd()
/* Set the video mode. */
bool RageDisplay_D3D::SetVideoMode( bool windowed, int width, int height, int bpp, int rate, bool vsync, CString sWindowTitle, CString sIconFile )
bool RageDisplay_D3D::TryVideoMode( VideoModeParams p, bool &bNewDeviceOut )
{
g_CurrentParams = p;
HRESULT hr;
if( FindBackBufferType( windowed, bpp ) == -1 ) // no possible back buffer formats
return false;
if( FindBackBufferType( p.windowed, p.bpp ) == -1 ) // no possible back buffer formats
return false; // failed to set mode
/* Set SDL window title and icon -before- creating the window */
SDL_WM_SetCaption(sWindowTitle, "");
mySDL_WM_SetIcon( sIconFile );
/* Round to the nearest valid fullscreen resolution */
if( !windowed )
{
if( width <= 320 ) width = 320;
else if( width <= 400 ) width = 400;
else if( width <= 512 ) width = 512;
else if( width <= 640 ) width = 640;
else if( width <= 800 ) width = 800;
else if( width <= 1024 ) width = 1024;
else if( width <= 1280 ) width = 1280;
switch( width )
{
case 320: height = 240; break;
case 400: height = 300; break;
case 512: height = 384; break;
case 640: height = 480; break;
case 800: height = 600; break;
case 1024: height = 768; break;
case 1280: height = 960; break;
default: ASSERT(0);
}
}
SDL_WM_SetCaption( p.sWindowTitle, "" );
mySDL_WM_SetIcon( p.sIconFile );
// HACK: On Windows 98, we can't call SDL_SetVideoMode while D3D is full screen.
@@ -424,22 +391,17 @@ bool RageDisplay_D3D::SetVideoMode( bool windowed, int width, int height, int bp
// Not in exclusive access mode". So, we'll Reset the D3D device, then resize the
// SDL window only if we're not fullscreen.
g_Windowed = windowed;
g_CurrentWidth = width;
g_CurrentHeight = height;
g_CurrentBPP = bpp;
SDL_ShowCursor( windowed );
SDL_ShowCursor( p.windowed );
ZeroMemory( &g_d3dpp, sizeof(g_d3dpp) );
g_d3dpp.BackBufferWidth = width;
g_d3dpp.BackBufferHeight = height;
g_d3dpp.BackBufferFormat = FindBackBufferType( windowed, bpp );
g_d3dpp.BackBufferWidth = p.width;
g_d3dpp.BackBufferHeight = p.height;
g_d3dpp.BackBufferFormat = FindBackBufferType( p.windowed, p.bpp );
g_d3dpp.BackBufferCount = 1;
g_d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
g_d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
g_d3dpp.hDeviceWindow = NULL;
g_d3dpp.Windowed = windowed;
g_d3dpp.Windowed = p.windowed;
g_d3dpp.EnableAutoDepthStencil = TRUE;
g_d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
g_d3dpp.Flags = 0;
@@ -447,7 +409,7 @@ bool RageDisplay_D3D::SetVideoMode( bool windowed, int width, int height, int bp
/* Windowed must always use D3DPRESENT_INTERVAL_DEFAULT. */
g_d3dpp.FullScreen_PresentationInterval =
(windowed || vsync) ? D3DPRESENT_INTERVAL_DEFAULT : D3DPRESENT_INTERVAL_IMMEDIATE;
(p.windowed || p.vsync) ? D3DPRESENT_INTERVAL_DEFAULT : D3DPRESENT_INTERVAL_IMMEDIATE;
LOG->Trace( "Present Parameters: %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d",
g_d3dpp.BackBufferWidth, g_d3dpp.BackBufferHeight, g_d3dpp.BackBufferFormat,
@@ -458,10 +420,9 @@ bool RageDisplay_D3D::SetVideoMode( bool windowed, int width, int height, int bp
g_d3dpp.FullScreen_PresentationInterval
);
bool bCreateNewDevice = g_pd3dDevice == NULL;
if( bCreateNewDevice ) // device is not yet created. We need to create it
if( g_pd3dDevice == NULL ) // device is not yet created. We need to create it
{
bNewDeviceOut = true;
hr = g_pd3d->CreateDevice(
D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
@@ -482,6 +443,7 @@ bool RageDisplay_D3D::SetVideoMode( bool windowed, int width, int height, int bp
}
else
{
bNewDeviceOut = false;
hr = g_pd3dDevice->Reset( &g_d3dpp );
if( FAILED(hr) )
{
@@ -490,7 +452,7 @@ bool RageDisplay_D3D::SetVideoMode( bool windowed, int width, int height, int bp
}
}
if( this->IsWindowed() )
if( p.windowed )
{
int flags = SDL_RESIZABLE | SDL_SWSURFACE;
@@ -499,9 +461,9 @@ bool RageDisplay_D3D::SetVideoMode( bool windowed, int width, int height, int bp
// if( !windowed )
// flags |= SDL_FULLSCREEN;
SDL_ShowCursor( g_Windowed );
SDL_ShowCursor( p.windowed );
SDL_Surface *screen = SDL_SetVideoMode(width, height, bpp, flags);
SDL_Surface *screen = SDL_SetVideoMode(p.width, p.height, p.bpp, flags);
if(!screen)
{
SDL_QuitSubSystem(SDL_INIT_VIDEO); // exit out of full screen. The ~RageDisplay will not be called!
@@ -516,7 +478,7 @@ bool RageDisplay_D3D::SetVideoMode( bool windowed, int width, int height, int bp
/* Palettes were lost by Reset(), so mark them unloaded. */
g_TexResourceToPaletteIndex.clear();
return bCreateNewDevice;
return true; // mode change successful
}
void RageDisplay_D3D::ResolutionChanged()
@@ -533,10 +495,10 @@ void RageDisplay_D3D::SetViewport(int shift_left, int shift_down)
{
/* left and down are on a 0..SCREEN_WIDTH, 0..SCREEN_HEIGHT scale.
* Scale them to the actual viewport range. */
shift_left = int( shift_left * float(g_CurrentWidth) / SCREEN_WIDTH );
shift_down = int( shift_down * float(g_CurrentHeight) / SCREEN_HEIGHT );
shift_left = int( shift_left * float(g_CurrentParams.width) / SCREEN_WIDTH );
shift_down = int( shift_down * float(g_CurrentParams.height) / SCREEN_HEIGHT );
D3DVIEWPORT8 viewData = { shift_left, -shift_down, g_CurrentWidth, g_CurrentHeight, 0.f, 1.f };
D3DVIEWPORT8 viewData = { shift_left, -shift_down, g_CurrentParams.width, g_CurrentParams.height, 0.f, 1.f };
g_pd3dDevice->SetViewport( &viewData );
}
@@ -548,7 +510,7 @@ int RageDisplay_D3D::GetMaxTextureSize() const
void RageDisplay_D3D::BeginFrame()
{
if( g_pd3dDevice->TestCooperativeLevel() == D3DERR_DEVICENOTRESET )
SetVideoMode( g_Windowed, g_CurrentWidth, g_CurrentHeight, g_CurrentBPP, 0, 0, "", "" ); // FIXME: preserve prefs
SetVideoMode( g_CurrentParams );
g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,
D3DCOLOR_XRGB(0,0,0), 1.0f, 0x00000000 );
@@ -585,11 +547,7 @@ void RageDisplay_D3D::SaveScreenshot( CString sPath )
#endif
}
bool RageDisplay_D3D::IsWindowed() const { return g_Windowed; }
int RageDisplay_D3D::GetWidth() const { return g_CurrentWidth; }
int RageDisplay_D3D::GetHeight() const { return g_CurrentHeight; }
int RageDisplay_D3D::GetBPP() const { return g_CurrentBPP; }
RageDisplay::VideoModeParams RageDisplay_D3D::GetVideoModeParams() const { return g_CurrentParams; }
#define SEND_CURRENT_MATRICES \
g_pd3dDevice->SetTransform( D3DTS_PROJECTION, (D3DMATRIX*)GetProjection() ); \
+3 -6
View File
@@ -7,21 +7,17 @@ class RageException_D3DNoAcceleration: public exception { };
class RageDisplay_D3D: public RageDisplay
{
public:
RageDisplay_D3D( bool windowed, int width, int height, int bpp, int rate, bool vsync, CString sWindowTitle, CString sIconFile );
RageDisplay_D3D( VideoModeParams params );
~RageDisplay_D3D();
void Update(float fDeltaTime);
bool IsSoftwareRenderer();
bool SetVideoMode( bool windowed, int width, int height, int bpp, int rate, bool vsync, CString sWindowTitle, CString sIconFile );
void ResolutionChanged();
const PixelFormatDesc *GetPixelFormatDesc(PixelFormat pf) const;
void BeginFrame();
void EndFrame();
bool IsWindowed() const;
int GetWidth() const;
int GetHeight() const;
int GetBPP() const;
VideoModeParams GetVideoModeParams() const;
void SetBlendMode( BlendMode mode );
bool SupportsTextureFormat( PixelFormat pixfmt );
unsigned CreateTexture( PixelFormat pixfmt, SDL_Surface*& img );
@@ -68,6 +64,7 @@ public:
void SaveScreenshot( CString sPath );
protected:
bool TryVideoMode( VideoModeParams params, bool &bNewDeviceOut );
void SetViewport(int shift_left, int shift_down);
RageMatrix GetOrthoMatrix( float l, float r, float b, float t, float zn, float zf );
+28 -38
View File
@@ -72,7 +72,6 @@ namespace GLExt {
PWSWAPINTERVALEXTPROC GLExt::wglSwapIntervalEXT = NULL;
PFNGLCOLORTABLEPROC GLExt::glColorTableEXT = NULL;
PFNGLCOLORTABLEPARAMETERIVPROC GLExt::glGetColorTableParameterivEXT = NULL;
bool g_bAALinesBroken = false;
bool g_bEXT_texture_env_combine = true;
/* OpenGL system information that generally doesn't change at runtime. */
@@ -193,14 +192,14 @@ void GetGLExtensions(set<string> &ext)
ext.insert(lst[i]);
}
RageDisplay_OGL::RageDisplay_OGL( bool windowed, int width, int height, int bpp, int rate, bool vsync, CString sWindowTitle, CString sIconFile )
RageDisplay_OGL::RageDisplay_OGL( VideoModeParams p )
{
LOG->Trace( "RageDisplay_OGL::RageDisplay_OGL()" );
LOG->MapLog("renderer", "Current renderer: OpenGL");
wind = MakeLowLevelWindow();
SetVideoMode( windowed, width, height, bpp, rate, vsync, sWindowTitle, sIconFile );
SetVideoMode( p );
// Log driver details
LOG->Info("OGL Vendor: %s", glGetString(GL_VENDOR));
@@ -306,22 +305,11 @@ void SetupExtensions()
GLExt::wglSwapIntervalEXT = (PWSWAPINTERVALEXTPROC) wind->GetProcAddress("wglSwapIntervalEXT");
GLExt::glColorTableEXT = (PFNGLCOLORTABLEPROC) wind->GetProcAddress("glColorTableEXT");
GLExt::glGetColorTableParameterivEXT = (PFNGLCOLORTABLEPARAMETERIVPROC) wind->GetProcAddress("glGetColorTableParameterivEXT");
g_bAALinesBroken = false;
g_bEXT_texture_env_combine = HasExtension("GL_EXT_texture_env_combine");
CheckPalettedTextures();
// Checks for known bad drivers
CString sRenderer = (const char*)glGetString(GL_RENDERER);
if( sRenderer.Left(12) == "3Dfx/Voodoo3" )
{
LOG->Info("Anti-aliased lines are known to cause problems with this driver.");
g_bAALinesBroken = true;
/* Shouldn't be needed anymore.
LOG->Info("Paletted textures are broken with this driver.");
GLExt::glColorTableEXT = NULL;
GLExt::glGetColorTableParameterivEXT = NULL; */
}
}
void DumpOpenGLDebugInfo()
@@ -390,21 +378,23 @@ void DumpOpenGLDebugInfo()
void RageDisplay_OGL::ResolutionChanged()
{
SetViewport(0,0);
SetViewport(0,0);
/* Clear any junk that's in the framebuffer. */
BeginFrame();
EndFrame();
}
/* Set the video mode. In some cases, changing the video mode will reset
* the rendering context; returns true if we need to reload textures. */
bool RageDisplay_OGL::SetVideoMode( bool windowed, int width, int height, int bpp, int rate, bool vsync, CString sWindowTitle, CString sIconFile )
// Return true if mode change was successful.
// bNewDeviceOut is set true if a new device was created and textures
// need to be reloaded.
bool RageDisplay_OGL::TryVideoMode( VideoModeParams p, bool &bNewDeviceOut )
{
// LOG->Trace( "RageDisplay_OGL::SetVideoMode( %d, %d, %d, %d, %d, %d )", windowed, width, height, bpp, rate, vsync );
bool NewOpenGLContext = wind->SetVideoMode( windowed, width, height, bpp, rate, vsync, sWindowTitle, sIconFile );
if( !wind->TryVideoMode( p, bNewDeviceOut ) )
return false; // failed to set video mode
if(NewOpenGLContext)
if( bNewDeviceOut )
{
/* We have a new OpenGL context, so we have to tell our textures that
* their OpenGL texture number is invalid. */
@@ -422,21 +412,21 @@ bool RageDisplay_OGL::SetVideoMode( bool windowed, int width, int height, int bp
/* Set vsync the Windows way, if we can. (What other extensions are there
* to do this, for other archs?) */
if( GLExt::wglSwapIntervalEXT )
GLExt::wglSwapIntervalEXT(vsync);
GLExt::wglSwapIntervalEXT(p.vsync);
ResolutionChanged();
return NewOpenGLContext;
return true; // successfully set mode
}
void RageDisplay_OGL::SetViewport(int shift_left, int shift_down)
{
/* left and down are on a 0..SCREEN_WIDTH, 0..SCREEN_HEIGHT scale.
* Scale them to the actual viewport range. */
shift_left = int( shift_left * float(wind->GetWidth()) / SCREEN_WIDTH );
shift_down = int( shift_down * float(wind->GetHeight()) / SCREEN_HEIGHT );
shift_left = int( shift_left * float(wind->GetVideoModeParams().width) / SCREEN_WIDTH );
shift_down = int( shift_down * float(wind->GetVideoModeParams().height) / SCREEN_HEIGHT );
glViewport(shift_left, -shift_down, wind->GetWidth(), wind->GetHeight());
glViewport(shift_left, -shift_down, wind->GetVideoModeParams().width, wind->GetVideoModeParams().height);
}
int RageDisplay_OGL::GetMaxTextureSize() const
@@ -473,23 +463,26 @@ void RageDisplay_OGL::SaveScreenshot( CString sPath )
{
ASSERT( sPath.Right(3).CompareNoCase("bmp") == 0 ); // we can only save bitmaps
int width = wind->GetVideoModeParams().width;
int height = wind->GetVideoModeParams().height;
SDL_Surface *image = SDL_CreateRGBSurface(
SDL_SWSURFACE, wind->GetWidth(), wind->GetHeight(),
SDL_SWSURFACE, width, height,
24, 0x0000FF, 0x00FF00, 0xFF0000, 0x000000);
SDL_Surface *temp = SDL_CreateRGBSurface(
SDL_SWSURFACE, wind->GetWidth(), wind->GetHeight(),
SDL_SWSURFACE, width, height,
24, 0x0000FF, 0x00FF00, 0xFF0000, 0x000000);
glReadPixels(0, 0, wind->GetWidth(), wind->GetHeight(), GL_RGB,
glReadPixels(0, 0, wind->GetVideoModeParams().width, wind->GetVideoModeParams().height, GL_RGB,
GL_UNSIGNED_BYTE, image->pixels);
// flip vertically
int pitch = image->pitch;
for( int y=0; y<wind->GetHeight(); y++ )
for( int y=0; y<wind->GetVideoModeParams().height; y++ )
memcpy(
(char *)temp->pixels + pitch * y,
(char *)image->pixels + pitch * (wind->GetHeight()-1-y),
3*wind->GetWidth() );
(char *)image->pixels + pitch * (height-1-y),
3*width );
SDL_SaveBMP( temp, sPath );
@@ -498,10 +491,7 @@ void RageDisplay_OGL::SaveScreenshot( CString sPath )
}
bool RageDisplay_OGL::IsWindowed() const { return wind->IsWindowed(); }
int RageDisplay_OGL::GetWidth() const { return wind->GetWidth(); }
int RageDisplay_OGL::GetHeight() const { return wind->GetHeight(); }
int RageDisplay_OGL::GetBPP() const { return wind->GetBPP(); }
RageDisplay::VideoModeParams RageDisplay_OGL::GetVideoModeParams() const { return wind->GetVideoModeParams(); }
static void SetupVertices( const RageVertex v[], int iNumVerts )
{
@@ -631,7 +621,7 @@ void RageDisplay_OGL::DrawLineStrip( const RageVertex v[], int iNumVerts, float
{
ASSERT( iNumVerts >= 2 );
if( g_bAALinesBroken )
if( !GetVideoModeParams().bAntiAliasing )
{
RageDisplay::DrawLineStrip(v, iNumVerts, LineWidth );
return;
@@ -650,8 +640,8 @@ void RageDisplay_OGL::DrawLineStrip( const RageVertex v[], int iNumVerts, float
/* Our line width is wrt the regular internal SCREEN_WIDTHxSCREEN_HEIGHT screen,
* but these width functions actually want raster sizes (that is, actual pixels).
* Scale the line width and point size by the average ratio of the scale. */
float WidthVal = float(wind->GetWidth()) / SCREEN_WIDTH;
float HeightVal = float(wind->GetHeight()) / SCREEN_HEIGHT;
float WidthVal = float(wind->GetVideoModeParams().width) / SCREEN_WIDTH;
float HeightVal = float(wind->GetVideoModeParams().height) / SCREEN_HEIGHT;
LineWidth *= (WidthVal + HeightVal) / 2;
/* Clamp the width to the hardware max for both lines and points (whichever
+3 -6
View File
@@ -4,21 +4,17 @@
class RageDisplay_OGL: public RageDisplay
{
public:
RageDisplay_OGL( bool windowed, int width, int height, int bpp, int rate, bool vsync, CString sWindowTitle, CString sIconFile );
RageDisplay_OGL( VideoModeParams params );
~RageDisplay_OGL();
void Update(float fDeltaTime);
bool IsSoftwareRenderer();
bool SetVideoMode( bool windowed, int width, int height, int bpp, int rate, bool vsync, CString sWindowTitle, CString sIconFile );
void ResolutionChanged();
const PixelFormatDesc *GetPixelFormatDesc(PixelFormat pf) const;
void BeginFrame();
void EndFrame();
bool IsWindowed() const;
int GetWidth() const;
int GetHeight() const;
int GetBPP() const;
VideoModeParams GetVideoModeParams() const;
void SetBlendMode( BlendMode mode );
bool SupportsTextureFormat( PixelFormat pixfmt );
unsigned CreateTexture( PixelFormat pixfmt, SDL_Surface*& img );
@@ -65,6 +61,7 @@ public:
void SaveScreenshot( CString sPath );
protected:
bool TryVideoMode( VideoModeParams params, bool &bNewDeviceOut );
void SetViewport(int shift_left, int shift_down);
RageMatrix GetOrthoMatrix( float l, float r, float b, float t, float zn, float zf );
+2 -2
View File
@@ -223,7 +223,7 @@ void RageMatrixCommand( CString sCommandString, RageMatrix &mat )
CString sError = ssprintf( "Unrecognized matrix command name '%s' in command string '%s'.", sName.c_str(), sCommandString.c_str() );
LOG->Warn( sError );
#if defined(WIN32) && !defined(_XBOX) // XXX arch?
if( DISPLAY->IsWindowed() )
if( DISPLAY->GetVideoModeParams().windowed )
MessageBox(NULL, sError, "MatrixCommand", MB_OK);
#endif
continue;
@@ -235,7 +235,7 @@ void RageMatrixCommand( CString sCommandString, RageMatrix &mat )
CString sError = ssprintf( "Wrong number of parameters in command '%s'. Expected %d but there are %d.", join(",",asTokens).c_str(), iMaxIndexAccessed+1, (int)asTokens.size() );
LOG->Warn( sError );
#if defined(WIN32) // XXX arch?
if( DISPLAY->IsWindowed() )
if( DISPLAY->GetVideoModeParams().windowed )
MessageBox(NULL, sError, "MatrixCommand", MB_OK);
#endif
continue;
+13 -10
View File
@@ -49,6 +49,7 @@ bool RageTextureID::operator<(const RageTextureID &rhs) const
{
#define COMP(a) if(a<rhs.a) return true; if(a>rhs.a) return false;
COMP(filename);
COMP(text);
COMP(iMaxSize);
COMP(iMipMaps);
COMP(iAlphaBits);
@@ -63,16 +64,18 @@ bool RageTextureID::operator<(const RageTextureID &rhs) const
bool RageTextureID::operator==(const RageTextureID &rhs) const
{
#define EQUAL(a) (a==rhs.a)
return
filename == rhs.filename &&
iMaxSize == rhs.iMaxSize &&
iMipMaps == rhs.iMipMaps &&
iAlphaBits == rhs.iAlphaBits &&
iColorDepth == rhs.iColorDepth &&
iTransparencyOnly == rhs.iTransparencyOnly &&
bDither == rhs.bDither &&
bStretch == rhs.bStretch &&
bHotPinkColorKey == rhs.bHotPinkColorKey;
EQUAL(filename) &&
EQUAL(text) &&
EQUAL(iMaxSize) &&
EQUAL(iMipMaps) &&
EQUAL(iAlphaBits) &&
EQUAL(iColorDepth) &&
EQUAL(iTransparencyOnly) &&
EQUAL(bDither) &&
EQUAL(bStretch) &&
EQUAL(bHotPinkColorKey);
}
@@ -114,7 +117,7 @@ RageTexture::~RageTexture()
void RageTexture::CreateFrameRects()
{
GetFrameDimensionsFromFileName( GetFilePath(), &m_iFramesWide, &m_iFramesHigh );
GetFrameDimensionsFromFileName( GetID().filename, &m_iFramesWide, &m_iFramesHigh );
///////////////////////////////////
// Fill in the m_FrameRects with the bounds of each frame in the animation.
+2 -2
View File
@@ -21,7 +21,8 @@
* of these. */
struct RageTextureID
{
CString filename;
CString filename; // font file name if !text.empty()
CString text;
int iMaxSize;
int iMipMaps;
int iAlphaBits;
@@ -82,7 +83,6 @@ public:
const RectF *GetTextureCoordRect( int frameNo ) const;
int GetNumFrames() const { return m_iFramesWide*m_iFramesHigh; }
const CString &GetFilePath() const { return GetID().filename; }
int m_iRefCount;
bool m_bCacheThis;
+63
View File
@@ -602,6 +602,69 @@ void mySDL_WM_SetIcon( CString sIconFile )
SDL_FreeSurface(srf);
}
void mySDL_BlitSurfaceSmartBlend(
SDL_Surface* src, SDL_Rect *srcrect,
SDL_Surface* dst, SDL_Rect *dstrect )
{
/* Can't blit to paletted surfaces. */
ASSERT(dst->format->BytesPerPixel > 1);
/* Rects must be same dimensions. */
ASSERT( srcrect->w==dstrect->w && srcrect->h==dstrect->h );
/* TODO: Add clipping.
* For now, just ASSERT if out of bounds. */
ASSERT(
srcrect->x >= 0 &&
srcrect->x+srcrect->w <= src->w &&
srcrect->y >= 0 &&
srcrect->y+srcrect->h <= src->h );
ASSERT(
dstrect->x >= 0 &&
dstrect->x+dstrect->w <= dst->w &&
dstrect->y >= 0 &&
dstrect->y+dstrect->h <= dst->h );
/* For each row: */
for(int row = 0; row < srcrect->h; ++row)
{
const Uint8 *srcp = (const Uint8 *)src->pixels;
srcp += (srcrect->y+row) * src->pitch;
srcp += srcrect->x * src->format->BytesPerPixel;
Uint8 *dstp = (Uint8 *)dst->pixels;
dstp += (dstrect->y+row) * dst->pitch;
dstp += dstrect->x * dst->format->BytesPerPixel;
/* For each pixel in row: */
for(int col = 0; col < srcrect->w; ++col)
{
Uint8 srcColors[4];
mySDL_GetRGBAV(srcp, src, srcColors);
Uint8 dstColors[4];
mySDL_GetRGBAV(dstp, dst, dstColors);
float fColorWeightSrc = srcColors[3] / (float)(srcColors[3]+dstColors[3]);
float fColorWeightDst = dstColors[3] / (float)(srcColors[3]+dstColors[3]);
Uint32 temp[4];
temp[0] = srcColors[0] * fColorWeightSrc + dstColors[0] * fColorWeightDst;
temp[1] = srcColors[1] * fColorWeightSrc + dstColors[1] * fColorWeightDst;
temp[2] = srcColors[2] * fColorWeightSrc + dstColors[2] * fColorWeightDst;
temp[3] = srcColors[3] + (dstColors[3] * (255-srcColors[3]))/255;
Uint8 blendedColors[4] = { temp[0], temp[1], temp[2], temp[3] };
mySDL_SetRGBAV(dstp, dst, blendedColors);
/* Next column */
srcp += src->format->BytesPerPixel;
dstp += dst->format->BytesPerPixel;
}
}
}
struct SurfaceHeader
{
int width, height, pitch;
+6
View File
@@ -56,6 +56,12 @@ int FindSurfaceTraits(const SDL_Surface *img);
void mySDL_WM_SetIcon( CString sIconFile );
void mySDL_BlitSurfaceSmartBlend(
SDL_Surface* src, SDL_Rect *srcrect,
SDL_Surface* dst, SDL_Rect *dstrect );
bool mySDL_SaveSurface( SDL_Surface *img, CString file );
SDL_Surface *mySDL_LoadSurface( CString file );
+8 -1
View File
@@ -28,7 +28,7 @@ ScreenSandbox::ScreenSandbox() : Screen("ScreenSandbox")
m_quad1.SetDiffuse( RageColor(0,0,1,1) );
m_quad1.SetZ( 0 );
m_quad1.SetUseZBuffer( true );
this->AddChild( &m_quad1 );
// this->AddChild( &m_quad1 );
m_quad2.StretchTo( RectI(SCREEN_LEFT, SCREEN_TOP, SCREEN_RIGHT, SCREEN_BOTTOM) );
m_quad2.SetDiffuse( RageColor(0,1,0,1) );
@@ -48,6 +48,13 @@ ScreenSandbox::ScreenSandbox() : Screen("ScreenSandbox")
// this->AddChild(&m_model);
// m_model.SetEffectSpin( RageVector3(0,90,90) );
RageTextureID ID;
ID.filename = THEME->GetPathToF("MusicWheelItem roulette");
ID.text = "testing,\ntesting,\n1\n2\n3\n\n\n";
m_text.Load( ID );
m_text.SetXY( CENTER_X, CENTER_Y );
this->AddChild( &m_text );
this->AddChild( &m_In );
this->AddChild( &m_Out );
+1
View File
@@ -34,6 +34,7 @@ public:
Quad m_quad2;
Transition m_In;
Transition m_Out;
Sprite m_text;
};
+46 -53
View File
@@ -88,14 +88,16 @@ void ApplyGraphicOptions()
bool bNeedReload = false;
bNeedReload |= DISPLAY->SetVideoMode(
PREFSMAN->m_bWindowed,
PREFSMAN->m_iDisplayWidth,
PREFSMAN->m_iDisplayHeight,
PREFSMAN->m_iDisplayColorDepth,
PREFSMAN->m_iRefreshRate,
PREFSMAN->m_bVsync,
THEME->GetMetric("Common","WindowTitle"),
THEME->GetPathToG("Common window icon") );
RageDisplay::VideoModeParams(
PREFSMAN->m_bWindowed,
PREFSMAN->m_iDisplayWidth,
PREFSMAN->m_iDisplayHeight,
PREFSMAN->m_iDisplayColorDepth,
PREFSMAN->m_iRefreshRate,
PREFSMAN->m_bVsync,
PREFSMAN->m_bAntiAliasing,
THEME->GetMetric("Common","WindowTitle"),
THEME->GetPathToG("Common window icon") ) );
bNeedReload |= TEXTUREMAN->SetPrefs(
PREFSMAN->m_iTextureColorDepth,
PREFSMAN->m_bDelayedTextureDelete,
@@ -104,14 +106,23 @@ void ApplyGraphicOptions()
if( bNeedReload )
TEXTUREMAN->ReloadAll();
SCREENMAN->SystemMessage( ssprintf("%s %dx%d %d color %d texture %dHz %s",
// find out what we actually got
PREFSMAN->m_bWindowed = DISPLAY->GetVideoModeParams().windowed;
PREFSMAN->m_iDisplayWidth = DISPLAY->GetVideoModeParams().width;
PREFSMAN->m_iDisplayHeight = DISPLAY->GetVideoModeParams().height;
PREFSMAN->m_iDisplayColorDepth = DISPLAY->GetVideoModeParams().bpp;
PREFSMAN->m_iRefreshRate = DISPLAY->GetVideoModeParams().rate;
PREFSMAN->m_bVsync = DISPLAY->GetVideoModeParams().vsync;
SCREENMAN->SystemMessage( ssprintf("%s %dx%d %d color %d texture %dHz %s %s",
PREFSMAN->m_bWindowed ? "Windowed" : "Fullscreen",
PREFSMAN->m_iDisplayWidth,
PREFSMAN->m_iDisplayHeight,
PREFSMAN->m_iDisplayColorDepth,
PREFSMAN->m_iTextureColorDepth,
PREFSMAN->m_iRefreshRate,
PREFSMAN->m_bVsync ? "Vsync" : "NoSync" ) );
PREFSMAN->m_bVsync ? "Vsync" : "NoVsync",
PREFSMAN->m_bAntiAliasing? "AA" : "NoAA" ) );
}
void ExitGame()
@@ -215,43 +226,6 @@ static void BoostAppPri()
#include "RageDisplay_OGL.h"
#endif
/* XXX: Passing all of the SetVideoMode arguments to the ctor is cumbersome. */
#if !defined(_XBOX)
static RageDisplay *CreateDisplay_OGL()
{
return new RageDisplay_OGL(
PREFSMAN->m_bWindowed,
PREFSMAN->m_iDisplayWidth,
PREFSMAN->m_iDisplayHeight,
PREFSMAN->m_iDisplayColorDepth,
PREFSMAN->m_iRefreshRate,
PREFSMAN->m_bVsync,
THEME->GetMetric("Common","WindowTitle"),
THEME->GetPathToG("Common window icon") );
}
#endif
#if defined(WIN32)
static RageDisplay *CreateDisplay_D3D()
{
return new RageDisplay_D3D(
PREFSMAN->m_bWindowed,
PREFSMAN->m_iDisplayWidth,
PREFSMAN->m_iDisplayHeight,
PREFSMAN->m_iDisplayColorDepth,
PREFSMAN->m_iRefreshRate,
PREFSMAN->m_bVsync,
THEME->GetMetric("Common","WindowTitle"),
THEME->GetPathToG("Common window icon") );
}
#endif
#if defined(_XBOX)
RageDisplay *CreateDisplay() { return CreateDisplay_D3D(); }
#elif !defined(WIN32)
RageDisplay *CreateDisplay() { return CreateDisplay_OGL(); }
#else
#include "archutils/Win32/VideoDriverInfo.h"
#include "Regex.h"
@@ -314,6 +288,7 @@ RageDisplay *CreateDisplay()
ini.GetValueI( sKey, "Height", PREFSMAN->m_iDisplayHeight );
ini.GetValueI( sKey, "DisplayColor", PREFSMAN->m_iDisplayColorDepth );
ini.GetValueI( sKey, "TextureColor", PREFSMAN->m_iTextureColorDepth );
ini.GetValueB( sKey, "AntiAliasing", PREFSMAN->m_bAntiAliasing );
// Update last seen video card
PREFSMAN->m_sLastSeenVideoDriver = GetPrimaryVideoDriverName();
@@ -322,6 +297,18 @@ RageDisplay *CreateDisplay()
}
}
RageDisplay::VideoModeParams params(
PREFSMAN->m_bWindowed,
PREFSMAN->m_iDisplayWidth,
PREFSMAN->m_iDisplayHeight,
PREFSMAN->m_iDisplayColorDepth,
PREFSMAN->m_iRefreshRate,
PREFSMAN->m_bVsync,
PREFSMAN->m_bAntiAliasing,
THEME->GetMetric("Common","WindowTitle"),
THEME->GetPathToG("Common window icon") );
CString error = "There was an error while initializing your video card.\n\n"
" PLEASE DO NOT FILE THIS ERROR AS A BUG!\n\n"
"Video Driver: "+sVideoDriver+"\n\n";
@@ -334,42 +321,48 @@ RageDisplay *CreateDisplay()
if( sRenderer.CompareNoCase("opengl")==0 )
{
#if !defined(_XBOX)
/* Try to create an OpenGL renderer. This should always succeed. (Actually,
* SDL may throw, but that only happens with broken driver installations, and
* we probably don't want to fall back on D3D in that case anyway.) */
error += "Initializing OpenGL...\n";
RageDisplay *ret = CreateDisplay_OGL();
RageDisplay *ret = new RageDisplay_OGL( params );
if( PREFSMAN->m_bAllowUnacceleratedRenderer || !ret->IsSoftwareRenderer() )
return ret;
else
{
error += "Your system is reporting that OpenGL hardware acceleration is not available. "
"Please obtain an updated driver from your video card manufacturer.";
"Please obtain an updated driver from your video card manufacturer.\n\n";
delete ret;
}
#endif
}
else if( sRenderer.CompareNoCase("d3d")==0 )
{
#if defined(WIN32)
error += "Initializing Direct3D...\n";
try {
return CreateDisplay_D3D();
return new RageDisplay_D3D( params );
} catch(RageException_D3DNotInstalled e) {
error += "DirectX 8.1 or greater is not installed. You can download it from:\n"+D3DURL;
error += "DirectX 8.1 or greater is not installed. You can download it from:\n"+D3DURL+"\n\n";
} catch(RageException_D3DNoAcceleration e) {
error += "Your system is reporting that Direct3D hardware acceleration is not available. "
"Please obtain an updated driver from your video card manufacturer.";
"Please obtain an updated driver from your video card manufacturer.\n\n";
};
#endif
}
else
RageException::Throw("Unknown video renderer value: %s", sRenderer.c_str() );
}
if( asRenderers.empty() )
error += "No video renderers attempted.\n\n";
RageException::Throw( error );
}
#endif
static void RestoreAppPri()
{
+22 -5
View File
@@ -61,10 +61,10 @@ LINK32=link.exe
# SUBTRACT LINK32 /verbose /profile /pdb:none /incremental:no /nodefaultlib
# Begin Special Build Tool
IntDir=.\../Debug6
TargetDir=\temp\stepmania
TargetDir=\stepmania\stepmania
TargetName=StepMania-debug
SOURCE="$(InputPath)"
PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\
PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\
PostBuild_Cmds=disasm\mapconv $(IntDir)\$(TargetName).map $(TargetDir)\StepMania.vdi ia32.vdi
# End Special Build Tool
@@ -100,7 +100,7 @@ XBCP=xbecopy.exe
# ADD BASE XBCP /NOLOGO
# ADD XBCP /NOLOGO
# Begin Special Build Tool
PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\
PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\
PostBuild_Cmds=disasm\mapconv $(IntDir)\$(TargetName).map $(TargetDir)\StepMania.vdi ia32.vdi
# End Special Build Tool
@@ -137,10 +137,10 @@ LINK32=link.exe
# SUBTRACT LINK32 /verbose /pdb:none
# Begin Special Build Tool
IntDir=.\../Release6
TargetDir=\temp\stepmania
TargetDir=\stepmania\stepmania
TargetName=StepMania
SOURCE="$(InputPath)"
PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\
PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\
PostBuild_Cmds=disasm\mapconv $(IntDir)\$(TargetName).map $(TargetDir)\StepMania.vdi ia32.vdi
# End Special Build Tool
@@ -1941,6 +1941,23 @@ SOURCE=.\BitmapText.h
# End Source File
# Begin Source File
SOURCE=.\CompositedText.cpp
!IF "$(CFG)" == "StepMania - Win32 Debug"
!ELSEIF "$(CFG)" == "StepMania - Xbox Debug"
!ELSEIF "$(CFG)" == "StepMania - Win32 Release"
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\CompositedText.h
# End Source File
# Begin Source File
SOURCE=.\mathlib.c
!IF "$(CFG)" == "StepMania - Win32 Debug"
+6
View File
@@ -1661,6 +1661,12 @@ cl /Zl /nologo /c verstub.cpp /Fo&quot;$(IntDir)&quot;\
<File
RelativePath=".\BitmapText.h">
</File>
<File
RelativePath="CompositedText.cpp">
</File>
<File
RelativePath="CompositedText.h">
</File>
<File
RelativePath="Milkshape.h">
</File>
+8
View File
@@ -104,6 +104,14 @@ void TextBanner::LoadFromString(
m_textSubTitle.SetZoom( fSubTitleZoom );
m_textArtist.SetZoom( fArtistZoom );
// RageTextureID ID;
// ID.filename = THEME->GetPathToF("TextBanner");
// ID.text = sDisplayTitle;
// m_textTitle.Load( ID );
// ID.text = sDisplaySubTitle;
// m_textSubTitle.Load( ID );
// ID.text = sDisplayArtist;
// m_textArtist.Load( ID );
m_textTitle.SetTextMaxWidth( g_fWidth, sDisplayTitle, sTranslitTitle );
m_textSubTitle.SetTextMaxWidth( g_fWidth, sDisplaySubTitle, sTranslitSubTitle );
m_textArtist.SetTextMaxWidth( g_fWidth, sDisplayArtist, sTranslitArtist );
+1
View File
@@ -28,6 +28,7 @@ public:
private:
BitmapText m_textTitle, m_textSubTitle, m_textArtist;
//Sprite m_textTitle, m_textSubTitle, m_textArtist;
};
#endif
@@ -4,6 +4,9 @@
/* This handles low-level operations that OGL 1.x doesn't give us. Normally,
* we use SDL. Note that not all SDL operations go here; however, nothing
* outside of this can assume that SDL has VIDEO initialized. */
#include "RageDisplay.h" // for RageDisplay::VideoModeParams
class LowLevelWindow
{
public:
@@ -11,17 +14,15 @@ public:
virtual void *GetProcAddress(CString s) = 0;
/* Set the video mode as close to the requested settings as possible. They're
* hints only; it's better to get the wrong mode than to bail out. */
virtual bool SetVideoMode( bool windowed, int width, int height, int bpp, int rate, bool vsync, CString sWindowTitle, CString sIconFile ) = 0;
// Return true if mode change was successful.
// bNewDeviceOut is set true if a new device was created and textures
// need to be reloaded.
virtual bool TryVideoMode( RageDisplay::VideoModeParams p, bool &bNewDeviceOut ) = 0;
virtual void SwapBuffers() = 0;
virtual void Update(float fDeltaTime) { }
virtual bool IsWindowed() const = 0;
virtual int GetWidth() const = 0;
virtual int GetHeight() const = 0;
virtual int GetBPP() const = 0;
virtual RageDisplay::VideoModeParams GetVideoModeParams() const = 0;
};
#endif
@@ -18,8 +18,6 @@ LowLevelWindow_SDL::LowLevelWindow_SDL()
SDL_EventState(SDL_VIDEORESIZE, SDL_ENABLE);
SDL_EventState(SDL_ACTIVEEVENT, SDL_ENABLE);
Windowed = false;
}
LowLevelWindow_SDL::~LowLevelWindow_SDL()
@@ -34,8 +32,10 @@ void *LowLevelWindow_SDL::GetProcAddress(CString s)
return SDL_GL_GetProcAddress(s);
}
bool LowLevelWindow_SDL::SetVideoMode( bool windowed, int width, int height, int bpp, int rate, bool vsync, CString sWindowTitle, CString sIconFile )
bool LowLevelWindow_SDL::TryVideoMode( RageDisplay::VideoModeParams p, bool &bNewDeviceOut )
{
CurrentParams = p;
/* We need to preserve the event mask and all events, since they're lost by
* SDL_QuitSubSystem(SDL_INIT_VIDEO). */
vector<SDL_Event> events;
@@ -72,21 +72,18 @@ bool LowLevelWindow_SDL::SetVideoMode( bool windowed, int width, int height, int
mySDL_PushEvents(events);
/* Set SDL window title and icon -before- creating the window */
SDL_WM_SetCaption(sWindowTitle, "");
mySDL_WM_SetIcon( sIconFile );
SDL_WM_SetCaption( p.sWindowTitle, "");
mySDL_WM_SetIcon( p.sIconFile );
Windowed = false;
int flags = SDL_RESIZABLE | SDL_OPENGL; // | SDL_DOUBLEBUF; // no need for DirectDraw to be double-buffered
if( !windowed )
if( !p.windowed )
flags |= SDL_FULLSCREEN;
Windowed = windowed;
SDL_ShowCursor( Windowed );
SDL_ShowCursor( p.windowed );
ASSERT( bpp == 16 || bpp == 32 );
switch( bpp )
ASSERT( p.bpp == 16 || p.bpp == 32 );
switch( p.bpp )
{
case 16:
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
@@ -103,25 +100,29 @@ bool LowLevelWindow_SDL::SetVideoMode( bool windowed, int width, int height, int
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, true);
#ifdef SDL_HAS_REFRESH_RATE
if(rate == REFRESH_DEFAULT)
if( p.rate == REFRESH_DEFAULT )
SDL_SM_SetRefreshRate(0);
else
SDL_SM_SetRefreshRate(rate);
SDL_SM_SetRefreshRate(p.rate);
#endif
#if defined(WIN32)
// mySDL_EventState(SDL_OPENGLRESET, SDL_ENABLE);
#endif
SDL_Surface *screen = SDL_SetVideoMode(width, height, bpp, flags);
SDL_Surface *screen = SDL_SetVideoMode(p.width, p.height, p.bpp, flags);
if(!screen)
RageException::Throw("SDL_SetVideoMode failed: %s", SDL_GetError());
{
LOG->Trace("SDL_SetVideoMode failed: %s", SDL_GetError());
return false; // failed to set mode
}
bool NewOpenGLContext = true; // always a new context because we're resetting SDL_Video
bNewDeviceOut = true; // always a new context because we're resetting SDL_Video
/* XXX: This event only exists in the SDL tree, and is only needed in
* Windows. Eventually, it'll probably get upstreamed, and once it's
* in the real branch we can remove this #if. */
/* Why did I comment this out? -Chris */
#if defined(WIN32)
// SDL_Event e;
// if(SDL_GetEvent(e, SDL_OPENGLRESETMASK))
@@ -151,11 +152,7 @@ bool LowLevelWindow_SDL::SetVideoMode( bool windowed, int width, int height, int
colorbits, r, g, b, a, depth, stencil);
}
CurrentWidth = screen->w;
CurrentHeight = screen->h;
CurrentBPP = bpp;
return NewOpenGLContext;
return true; // we set the video mode successfully
}
void LowLevelWindow_SDL::SwapBuffers()
@@ -171,26 +168,18 @@ void LowLevelWindow_SDL::Update(float fDeltaTime)
switch(event.type)
{
case SDL_VIDEORESIZE:
CurrentWidth = event.resize.w;
CurrentHeight = event.resize.h;
CurrentParams.width = event.resize.w;
CurrentParams.height = event.resize.h;
/* Let DISPLAY know that our resolution has changed. */
DISPLAY->ResolutionChanged();
break;
case SDL_ACTIVEEVENT:
if( event.active.gain && // app regaining focus
!DISPLAY->IsWindowed() ) // full screen
!DISPLAY->GetVideoModeParams().windowed ) // full screen
{
// need to reacquire an OGL context
DISPLAY->SetVideoMode(
DISPLAY->IsWindowed(),
DISPLAY->GetWidth(),
DISPLAY->GetHeight(),
DISPLAY->GetBPP(),
0,
0,
"",
"" ); // FIXME: preserve prefs
DISPLAY->SetVideoMode( DISPLAY->GetVideoModeParams() );
}
break;
}
@@ -5,21 +5,17 @@
class LowLevelWindow_SDL: public LowLevelWindow
{
bool Windowed;
int CurrentHeight, CurrentWidth, CurrentBPP;
RageDisplay::VideoModeParams CurrentParams;
public:
LowLevelWindow_SDL();
~LowLevelWindow_SDL();
void *GetProcAddress(CString s);
bool SetVideoMode( bool windowed, int width, int height, int bpp, int rate, bool vsync, CString sWindowTitle, CString sIconFile );
bool TryVideoMode( RageDisplay::VideoModeParams p, bool &bNewDeviceOut );
void SwapBuffers();
void Update(float fDeltaTime);
bool IsWindowed() const { return Windowed; }
int GetWidth() const { return CurrentWidth; }
int GetHeight() const { return CurrentHeight; }
int GetBPP() const { return CurrentBPP; }
RageDisplay::VideoModeParams GetVideoModeParams() const { return CurrentParams; }
};
#undef ARCH_LOW_LEVEL_WINDOW
#define ARCH_LOW_LEVEL_WINDOW LowLevelWindow_SDL