diff --git a/360/file_browser.c b/360/file_browser.c
index 716a9c4c47..baae8e60ba 100644
--- a/360/file_browser.c
+++ b/360/file_browser.c
@@ -30,6 +30,16 @@ static const char * filebrowser_get_extension(const char * filename)
return "";
}
+static void filebrowser_clear_current_entries(filebrowser_t * filebrowser)
+{
+ for(uint32_t i = 0; i < MAX_FILE_LIMIT; i++)
+ {
+ filebrowser->cur[filebrowser->file_count].d_type = 0;
+ filebrowser->cur[filebrowser->file_count].d_namlen = 0;
+ strcpy(filebrowser->cur[filebrowser->file_count].d_name, "\0");
+ }
+}
+
void filebrowser_parse_directory(filebrowser_t * filebrowser, const char * path, const char *extensions)
{
int error = FALSE;
@@ -60,6 +70,7 @@ void filebrowser_parse_directory(filebrowser_t * filebrowser, const char * path,
do
{
+ strcpy(filebrowser->dir[filebrowser->directory_stack_size], path);
bool found_dir = false;
if(!(ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
{
@@ -100,4 +111,22 @@ error:
SSNES_ERR("Failed to open directory: \"%s\"\n", path);
}
FindClose(hFind);
+}
+
+void filebrowser_new(filebrowser_t * filebrowser, const char * start_dir, const char * extensions)
+{
+ filebrowser_clear_current_entries(filebrowser);
+ filebrowser->directory_stack_size = 0;
+ strcpy(filebrowser->extensions, extensions);
+
+ filebrowser_parse_directory(filebrowser, start_dir, filebrowser->extensions);
+}
+
+void filebrowser_push_directory(filebrowser_t * filebrowser, const char * path, bool with_extension)
+{
+ filebrowser->directory_stack_size++;
+ if(with_extension)
+ filebrowser_parse_directory(filebrowser, path, filebrowser->extensions);
+ else
+ filebrowser_parse_directory(filebrowser, path, "empty");
}
\ No newline at end of file
diff --git a/360/file_browser.h b/360/file_browser.h
index 70f251c5e3..6d3afcd6d2 100644
--- a/360/file_browser.h
+++ b/360/file_browser.h
@@ -16,18 +16,28 @@
* If not, see .
*/
+#include
+
#define FATX_MAX_FILE_LIMIT 4096
+#define MAX_FILE_LIMIT FATX_MAX_FILE_LIMIT
typedef struct {
unsigned d_type;
+ unsigned d_namlen;
CHAR d_name[MAX_PATH];
} DirectoryEntry;
typedef struct {
unsigned file_count; // amount of files in current directory
unsigned currently_selected; // currently selected browser entry
- DirectoryEntry cur[FATX_MAX_FILE_LIMIT]; // current file listing
+ uint32_t directory_stack_size;
+ char dir[128][2048]; /* info on the current directory */
+ DirectoryEntry cur[MAX_FILE_LIMIT]; // current file listing
char extensions[512]; // allowed file extensions
} filebrowser_t;
-void filebrowser_parse_directory(filebrowser_t * filebrowser, const char * path, const char *extensions);
\ No newline at end of file
+void filebrowser_new(filebrowser_t * filebrowser, const char * start_dir, const char * extensions);
+void filebrowser_parse_directory(filebrowser_t * filebrowser, const char * path, const char *extensions);
+void filebrowser_push_directory(filebrowser_t * filebrowser, const char * path, bool with_extension);
+
+#define FILEBROWSER_GET_CURRENT_DIRECTORY_NAME(filebrowser) (filebrowser.dir[filebrowser.directory_stack_size])
\ No newline at end of file
diff --git a/360/xdk360_video_debugfonts.cpp b/360/fonts.cpp
similarity index 56%
rename from 360/xdk360_video_debugfonts.cpp
rename to 360/fonts.cpp
index e9e02e1f0d..d307894534 100644
--- a/360/xdk360_video_debugfonts.cpp
+++ b/360/fonts.cpp
@@ -17,11 +17,229 @@
*/
#include
-#include
+#include
#include "xdk360_video.h"
-#include "xdk360_video_debugfonts.h"
+#include "fonts.h"
#include "../general.h"
+static video_console_t video_console;
+static xdk360_video_font_t m_Font;
+
+void xdk360_console_draw(void)
+{
+ xdk360_video_t *vid = (xdk360_video_t*)g_d3d;
+ D3DDevice *m_pd3dDevice = vid->xdk360_render_device;
+
+ // The top line
+ unsigned int nTextLine = ( video_console.m_nCurLine -
+ video_console.m_cScreenHeight + video_console.m_cScreenHeightVirtual -
+ video_console.m_nScrollOffset + 1 )
+ % video_console.m_cScreenHeightVirtual;
+
+ xdk360_video_font_begin(&m_Font);
+
+ for( unsigned int nScreenLine = 0; nScreenLine < video_console.m_cScreenHeight; nScreenLine++ )
+ {
+ xdk360_video_font_draw_text(&m_Font, (float)( video_console.m_cxSafeAreaOffset ),
+ (float)( video_console.m_cySafeAreaOffset +
+ video_console.m_fLineHeight * nScreenLine ),
+ video_console.m_colTextColor,
+ video_console.m_Lines[nTextLine], 0.0f );
+
+ nTextLine = ( nTextLine + 1 ) % video_console.m_cScreenHeightVirtual;
+ }
+
+ xdk360_video_font_end(&m_Font);
+}
+
+HRESULT xdk360_console_init( LPCSTR strFontFileName, unsigned long colBackColor,
+ unsigned long colTextColor)
+{
+ xdk360_video_t *vid = (xdk360_video_t*)g_d3d;
+ D3DDevice *m_pd3dDevice = vid->xdk360_render_device;
+
+ video_console.first_message = true;
+ video_console.m_Buffer = NULL;
+ video_console.m_Lines = NULL;
+ video_console.m_nScrollOffset = 0;
+
+ // Calculate the safe area
+ unsigned int uiSafeAreaPct = vid->video_mode.fIsHiDef ? SAFE_AREA_PCT_HDTV
+ : SAFE_AREA_PCT_4x3;
+
+ video_console.m_cxSafeArea = ( vid->d3dpp.BackBufferWidth * uiSafeAreaPct ) / 100;
+ video_console.m_cySafeArea = ( vid->d3dpp.BackBufferHeight * uiSafeAreaPct ) / 100;
+
+ video_console.m_cxSafeAreaOffset = ( vid->d3dpp.BackBufferWidth - video_console.m_cxSafeArea ) / 2;
+ video_console.m_cySafeAreaOffset = ( vid->d3dpp.BackBufferHeight - video_console.m_cySafeArea ) / 2;
+
+ // Create the font
+ HRESULT hr = xdk360_video_font_init(&m_Font, strFontFileName );
+ if( FAILED( hr ) )
+ {
+ SSNES_ERR( "Could not create font.\n" );
+ return -1;
+ }
+
+ // Save the colors
+ video_console.m_colBackColor = colBackColor;
+ video_console.m_colTextColor = colTextColor;
+
+ // Calculate the number of lines on the screen
+ float fCharWidth, fCharHeight;
+ xdk360_video_font_get_text_width(&m_Font, L"i", &fCharWidth, &fCharHeight, FALSE);
+
+ video_console.m_cScreenHeight = (unsigned int)( video_console.m_cySafeArea / fCharHeight );
+ video_console.m_cScreenWidth = (unsigned int)( video_console.m_cxSafeArea / fCharWidth );
+
+ video_console.m_cScreenHeightVirtual = video_console.m_cScreenHeight;
+
+ video_console.m_fLineHeight = fCharHeight;
+
+ // Allocate memory to hold the lines
+ video_console.m_Buffer = new wchar_t[ video_console.m_cScreenHeightVirtual * ( video_console.m_cScreenWidth + 1 ) ];
+ video_console.m_Lines = new wchar_t *[ video_console.m_cScreenHeightVirtual ];
+
+ // Set the line pointers as indexes into the buffer
+ for( unsigned int i = 0; i < video_console.m_cScreenHeightVirtual; i++ )
+ video_console.m_Lines[ i ] = video_console.m_Buffer + ( video_console.m_cScreenWidth + 1 ) * i;
+
+ video_console.m_nCurLine = 0;
+ video_console.m_cCurLineLength = 0;
+ memset( video_console.m_Buffer, 0, video_console.m_cScreenHeightVirtual * ( video_console.m_cScreenWidth + 1 ) * sizeof( wchar_t ) );
+ xdk360_console_draw();
+
+ return hr;
+}
+
+void xdk360_console_deinit()
+{
+ // Delete the memory we've allocated
+ if(video_console.m_Lines)
+ {
+ delete[] video_console.m_Lines;
+ video_console.m_Lines = NULL;
+ }
+
+ if(video_console.m_Buffer)
+ {
+ delete[] video_console.m_Buffer;
+ video_console.m_Buffer = NULL;
+ }
+
+ // Destroy the font
+ xdk360_video_font_deinit(&m_Font);
+}
+
+void xdk360_console_add( wchar_t wch )
+{
+ // If this is a newline, just increment lines and move on
+ if( wch == L'\n' )
+ {
+ video_console.m_nCurLine = ( video_console.m_nCurLine + 1 )
+ % video_console.m_cScreenHeightVirtual;
+ video_console.m_cCurLineLength = 0;
+ memset(video_console.m_Lines[video_console.m_nCurLine], 0,
+ ( video_console.m_cScreenWidth + 1 ) * sizeof( wchar_t ) );
+ return;
+ }
+
+ int bIncrementLine = FALSE; // Whether to wrap to the next line
+
+ if( video_console.m_cCurLineLength == video_console.m_cScreenWidth )
+ bIncrementLine = TRUE;
+ else
+ {
+ // Try to append the character to the line
+ video_console.m_Lines[ video_console.m_nCurLine ]
+ [ video_console.m_cCurLineLength ] = wch;
+
+ float fTextWidth, fTextHeight;
+ xdk360_video_font_get_text_width(&m_Font, video_console.m_Lines[ video_console.m_nCurLine ], &fTextWidth, &fTextHeight, 0);
+ if( fTextHeight > video_console.m_cxSafeArea )
+ {
+ // The line is too long, we need to wrap the character to the next line
+ video_console.m_Lines[video_console.m_nCurLine]
+ [ video_console.m_cCurLineLength ] = L'\0';
+ bIncrementLine = TRUE;
+ }
+ }
+
+ // If we need to skip to the next line, do so
+ if( bIncrementLine )
+ {
+ video_console.m_nCurLine = ( video_console.m_nCurLine + 1 )
+ % video_console.m_cScreenHeightVirtual;
+ video_console.m_cCurLineLength = 0;
+ memset( video_console.m_Lines[video_console.m_nCurLine],
+ 0, ( video_console.m_cScreenWidth + 1 ) * sizeof( wchar_t ) );
+ video_console.m_Lines[video_console.m_nCurLine ][0] = wch;
+ }
+
+ video_console.m_cCurLineLength++;
+}
+
+void xdk360_console_format(_In_z_ _Printf_format_string_ LPCSTR strFormat, ... )
+{
+ video_console.m_nCurLine = 0;
+ video_console.m_cCurLineLength = 0;
+ memset( video_console.m_Buffer, 0,
+ video_console.m_cScreenHeightVirtual *
+ ( video_console.m_cScreenWidth + 1 ) * sizeof( wchar_t ) );
+
+ va_list pArgList;
+ va_start( pArgList, strFormat );
+
+ // Count the required length of the string
+ unsigned long dwStrLen = _vscprintf( strFormat, pArgList ) + 1;
+ // +1 = null terminator
+ char * strMessage = ( char * )_malloca( dwStrLen );
+ vsprintf_s( strMessage, dwStrLen, strFormat, pArgList );
+
+ // Output the string to the console
+ unsigned long uStringLength = strlen( strMessage );
+ for( unsigned long i = 0; i < uStringLength; i++ )
+ {
+ wchar_t wch;
+ int ret = MultiByteToWideChar( CP_ACP, // ANSI code page
+ 0, // No flags
+ &strMessage[i], // Character to convert
+ 1, // Convert one byte
+ &wch, // Target wide character buffer
+ 1 ); // One wide character
+ xdk360_console_add( wch );
+ }
+
+ _freea( strMessage );
+
+ va_end( pArgList );
+}
+
+void xdk360_console_format_w(_In_z_ _Printf_format_string_ LPCWSTR wstrFormat, ... )
+{
+ video_console.m_nCurLine = 0;
+ video_console.m_cCurLineLength = 0;
+ memset( video_console.m_Buffer, 0, video_console.m_cScreenHeightVirtual
+ * ( video_console.m_cScreenWidth + 1 ) * sizeof( wchar_t ) );
+
+ va_list pArgList;
+ va_start( pArgList, wstrFormat );
+
+ // Count the required length of the string
+ unsigned long dwStrLen = _vscwprintf( wstrFormat, pArgList ) + 1; // +1 = null terminator
+ wchar_t * strMessage = ( wchar_t * )_malloca( dwStrLen * sizeof( wchar_t ) );
+ vswprintf_s( strMessage, dwStrLen, wstrFormat, pArgList );
+
+ // Output the string to the console
+ unsigned long uStringLength = wcslen( strMessage );
+ for( unsigned long i = 0; i < uStringLength; i++ )
+ xdk360_console_add( strMessage[i] );
+
+ _freea( strMessage );
+
+ va_end( pArgList );
+}
+
#define CALCFONTFILEHEADERSIZE(x) ( sizeof(unsigned long) + (sizeof(float)* 4) + sizeof(unsigned short) + (sizeof(wchar_t)*(x)) )
#define FONTFILEVERSION 5
@@ -44,11 +262,8 @@ typedef struct FontFileStrikesImage_t {
GLYPH_ATTR m_Glyphs[1]; // Array of font strike uv's etc... NOTE: It's m_dwNumGlyphs in size
} FontFileStrikesImage_t;
-//--------------------------------------------------------------------------------------
-// Vertex and pixel shaders for font rendering
-// Please note the removal of comment or dead lines...
-// They are commented out because the shader compiler has no use for them.
-//--------------------------------------------------------------------------------------
+static PackedResource m_xprResource;
+
static const char g_strFontShader[] =
"struct VS_IN\n"
"{\n"
@@ -56,7 +271,6 @@ static const char g_strFontShader[] =
"float2 Tex : TEXCOORD0;\n"
"float4 ChannelSelector : TEXCOORD1;\n"
"};\n"
-// "\n"
"struct VS_OUT\n"
"{\n"
"float4 Position : POSITION;\n"
@@ -64,12 +278,9 @@ static const char g_strFontShader[] =
"float2 TexCoord0 : TEXCOORD0;\n"
"float4 ChannelSelector : TEXCOORD1;\n"
"};\n"
-// "\n"
"uniform float4 Color : register(c1);\n"
"uniform float2 TexScale : register(c2);\n"
-// "\n"
"sampler FontTexture : register(s0);\n"
-// "\n"
"VS_OUT FontVertexShader( VS_IN In )\n"
"{\n"
"VS_OUT Out;\n"
@@ -83,36 +294,15 @@ static const char g_strFontShader[] =
"Out.ChannelSelector = In.ChannelSelector;\n"
"return Out;\n"
"}\n"
- // "\n"
"float4 FontPixelShader( VS_OUT In ) : COLOR0\n"
"{\n"
-// "// Fetch a texel from the font texture\n"
"float4 FontTexel = tex2D( FontTexture, In.TexCoord0 );\n"
-// "\n"
"if( dot( In.ChannelSelector, float4(1,1,1,1) ) )\n"
"{\n"
-// "// Select the color from the channel\n"
"float value = dot( FontTexel, In.ChannelSelector );\n"
-// "\n"
-// "// For white pixels, the high bit is 1 and the low\n"
-// "// bits are luminance, so r0.a will be > 0.5. For the\n"
-// "// RGB channel, we want to lop off the msb and shift\n"
-// "// the lower bits up one bit. This is simple to do\n"
-// "// with the _bx2 modifier. Since these pixels are\n"
-// "// opaque, we emit a 1 for the alpha channel (which\n"
-// "// is 0.5 x2 ).\n"
-// "\n"
-// "// For black pixels, the high bit is 0 and the low\n"
-// "// bits are alpha, so r0.a will be < 0.5. For the RGB\n"
-// "// channel, we emit zero. For the alpha channel, we\n"
-// "// just use the x2 modifier to scale up the low bits\n"
-// "// of the alpha.\n"
"float4 Color;\n"
"Color.rgb = ( value > 0.5f ? 2*value-1 : 0.0f );\n"
"Color.a = 2 * ( value > 0.5f ? 1.0f : value );\n"
-// "\n"
-// "// Return the texture color modulated with the vertex\n"
-// "// color\n"
"return Color * In.Diffuse;\n"
"}\n"
"else\n"
@@ -130,12 +320,7 @@ typedef struct AtgFont_Locals_t {
// All elements are defaulted to NULL
static AtgFont_Locals_t s_AtgFontLocals; // Global static instance
-//--------------------------------------------------------------------------------------
-// Name: CreateFontShaders()
-// Desc: Creates the global font shaders
-//--------------------------------------------------------------------------------------
-
-HRESULT XdkFont::CreateFontShaders()
+static HRESULT xdk360_video_font_create_shaders (xdk360_video_font_t * font)
{
//
// There are only two states the globals could be in,
@@ -232,53 +417,26 @@ HRESULT XdkFont::CreateFontShaders()
return hr; // Return the error code if any
}
-//--------------------------------------------------------------------------------------
-// Name: Font()
-// Desc: Constructor
-//--------------------------------------------------------------------------------------
-XdkFont::XdkFont()
+void xdk360_video_font_set_size(xdk360_video_font_t * font, float x, float y)
{
- m_pFontTexture = NULL;
-
- m_dwNumGlyphs = 0L;
- m_Glyphs = NULL;
-
- m_fCursorX = 0.0f;
- m_fCursorY = 0.0f;
-
- m_fXScaleFactor = 2.0f;
- m_fYScaleFactor = 2.0f;
-
- m_cMaxGlyph = 0;
- m_TranslatorTable = NULL;
-
- m_dwNestedBeginCount = 0L;
+ font->m_fXScaleFactor = x;
+ font->m_fYScaleFactor = y;
}
-
-//--------------------------------------------------------------------------------------
-// Name: ~Font()
-// Desc: Destructor
-//--------------------------------------------------------------------------------------
-XdkFont::~XdkFont()
+HRESULT xdk360_video_font_init(xdk360_video_font_t * font, const char * strFontFileName)
{
- Destroy();
-}
-
-void XdkFont::SetFontSize(float x, float y)
-{
- m_fXScaleFactor = x;
- m_fYScaleFactor = y;
-}
-
-//--------------------------------------------------------------------------------------
-// Name: Create()
-// Desc: Create the font's internal objects (texture and array of glyph info)
-// using the XPR packed resource file
-//--------------------------------------------------------------------------------------
-HRESULT XdkFont::Create( const char * strFontFileName )
-{
- // Create the font
+ font->m_pFontTexture = NULL;
+ font->m_dwNumGlyphs = 0L;
+ font->m_Glyphs = NULL;
+ font->m_fCursorX = 0.0f;
+ font->m_fCursorY = 0.0f;
+ font->m_fXScaleFactor = 2.0f;
+ font->m_fYScaleFactor = 2.0f;
+ font->m_cMaxGlyph = 0;
+ font->m_TranslatorTable = NULL;
+ font->m_dwNestedBeginCount = 0L;
+
+ // Create the font
if( FAILED( m_xprResource.Create( strFontFileName ) ) )
return E_FAIL;
@@ -286,7 +444,7 @@ HRESULT XdkFont::Create( const char * strFontFileName )
const void * pFontData = m_xprResource.GetData( "FontData");
// Save a copy of the texture
- m_pFontTexture = pFontTexture;
+ font->m_pFontTexture = pFontTexture;
// Check version of file (to make sure it matches up with the FontMaker tool)
const unsigned char * pData = static_cast(pFontData);
@@ -294,21 +452,21 @@ HRESULT XdkFont::Create( const char * strFontFileName )
if( dwFileVersion == FONTFILEVERSION )
{
- m_fFontHeight = reinterpret_cast(pData)->m_fFontHeight;
- m_fFontTopPadding = reinterpret_cast(pData)->m_fFontTopPadding;
- m_fFontBottomPadding = reinterpret_cast(pData)->m_fFontBottomPadding;
- m_fFontYAdvance = reinterpret_cast(pData)->m_fFontYAdvance;
+ font->m_fFontHeight = reinterpret_cast(pData)->m_fFontHeight;
+ font->m_fFontTopPadding = reinterpret_cast(pData)->m_fFontTopPadding;
+ font->m_fFontBottomPadding = reinterpret_cast(pData)->m_fFontBottomPadding;
+ font->m_fFontYAdvance = reinterpret_cast(pData)->m_fFontYAdvance;
// Point to the translator string which immediately follows the 4 floats
- m_cMaxGlyph = reinterpret_cast(pData)->m_cMaxGlyph;
+ font->m_cMaxGlyph = reinterpret_cast(pData)->m_cMaxGlyph;
- m_TranslatorTable = const_cast(reinterpret_cast(pData))->m_TranslatorTable;
+ font->m_TranslatorTable = const_cast(reinterpret_cast(pData))->m_TranslatorTable;
- pData += CALCFONTFILEHEADERSIZE( m_cMaxGlyph + 1 );
+ pData += CALCFONTFILEHEADERSIZE( font->m_cMaxGlyph + 1 );
// Read the glyph attributes from the file
- m_dwNumGlyphs = reinterpret_cast(pData)->m_dwNumGlyphs;
- m_Glyphs = reinterpret_cast(pData)->m_Glyphs; // Pointer
+ font->m_dwNumGlyphs = reinterpret_cast(pData)->m_dwNumGlyphs;
+ font->m_Glyphs = reinterpret_cast(pData)->m_Glyphs; // Pointer
}
else
{
@@ -317,7 +475,7 @@ HRESULT XdkFont::Create( const char * strFontFileName )
}
// Create the vertex and pixel shaders for rendering the font
- if( FAILED( CreateFontShaders() ) )
+ if( FAILED( xdk360_video_font_create_shaders(font) ) )
{
SSNES_ERR( "Could not create font shaders.\n" );
return E_FAIL;
@@ -329,29 +487,25 @@ HRESULT XdkFont::Create( const char * strFontFileName )
// Initialize the window
D3DDISPLAYMODE DisplayMode;
pd3dDevice->GetDisplayMode( 0, &DisplayMode );
- m_rcWindow.x1 = 0;
- m_rcWindow.y1 = 0;
- m_rcWindow.x2 = DisplayMode.Width;
- m_rcWindow.y2 = DisplayMode.Height;
+ font->m_rcWindow.x1 = 0;
+ font->m_rcWindow.y1 = 0;
+ font->m_rcWindow.x2 = DisplayMode.Width;
+ font->m_rcWindow.y2 = DisplayMode.Height;
// Determine whether we should save/restore state
- m_bSaveState = TRUE;
+ font->m_bSaveState = TRUE;
return S_OK;
}
-//--------------------------------------------------------------------------------------
-// Name: Destroy()
-// Desc: Destroy the font object
-//--------------------------------------------------------------------------------------
-void XdkFont::Destroy()
+void xdk360_video_font_deinit(xdk360_video_font_t * font)
{
- m_pFontTexture = NULL;
- m_dwNumGlyphs = 0L;
- m_Glyphs = NULL;
- m_cMaxGlyph = 0;
- m_TranslatorTable = NULL;
- m_dwNestedBeginCount = 0L;
+ font->m_pFontTexture = NULL;
+ font->m_dwNumGlyphs = 0L;
+ font->m_Glyphs = NULL;
+ font->m_cMaxGlyph = 0;
+ font->m_TranslatorTable = NULL;
+ font->m_dwNestedBeginCount = 0L;
// Safely release shaders
// NOTE: They are released in reverse order of creation
@@ -368,25 +522,15 @@ void XdkFont::Destroy()
m_xprResource.Destroy();
}
-//--------------------------------------------------------------------------------------
-// Name: SetCursorPosition()
-// Desc: Sets the cursor position for drawing text
-//--------------------------------------------------------------------------------------
-void XdkFont::SetCursorPosition( float fCursorX, float fCursorY )
+void xdk360_video_font_set_cursor_position(xdk360_video_font_t *font, float fCursorX, float fCursorY )
{
- m_fCursorX = floorf( fCursorX );
- m_fCursorY = floorf( fCursorY );
+ font->m_fCursorX = floorf( fCursorX );
+ font->m_fCursorY = floorf( fCursorY );
}
-//--------------------------------------------------------------------------------------
-// Name: GetTextExtent()
-// Desc: Get the dimensions of a text string
-//--------------------------------------------------------------------------------------
-
-void XdkFont::GetTextExtent( const wchar_t * strText, float * pWidth,
- float * pHeight, int bFirstLineOnly ) const
+void xdk360_video_font_get_text_width(xdk360_video_font_t * font, const wchar_t * strText, float * pWidth, float * pHeight, int bFirstLineOnly)
{
- // Set default text extent in output parameters
+ // Set default text extent in output parameters
int iWidth = 0;
float fHeight = 0.0f;
@@ -394,7 +538,7 @@ void XdkFont::GetTextExtent( const wchar_t * strText, float * pWidth,
{
// Initialize counters that keep track of text extent
int ix = 0;
- float fy = m_fFontHeight; // One character high to start
+ float fy = font->m_fFontHeight; // One character high to start
if( fy > fHeight )
fHeight = fy;
@@ -410,7 +554,7 @@ void XdkFont::GetTextExtent( const wchar_t * strText, float * pWidth,
if( bFirstLineOnly )
break;
ix = 0;
- fy += m_fFontYAdvance;
+ fy += font->m_fFontYAdvance;
// since the height has changed, test against the height extent
if( fy > fHeight )
fHeight = fy;
@@ -424,12 +568,12 @@ void XdkFont::GetTextExtent( const wchar_t * strText, float * pWidth,
// Translate unprintable characters
const GLYPH_ATTR* pGlyph;
- if( letter > m_cMaxGlyph )
+ if( letter > font->m_cMaxGlyph )
letter = 0; // Out of bounds?
else
- letter = m_TranslatorTable[letter]; // Remap ASCII to glyph
+ letter = font->m_TranslatorTable[letter]; // Remap ASCII to glyph
- pGlyph = &m_Glyphs[letter]; // Get the requested glyph
+ pGlyph = &font->m_Glyphs[letter]; // Get the requested glyph
// Get text extent for this character's glyph
ix += pGlyph->wOffset;
@@ -445,72 +589,54 @@ void XdkFont::GetTextExtent( const wchar_t * strText, float * pWidth,
// Convert the width to a float here, load/hit/store. :(
float fWidth = static_cast(iWidth); // Delay the use if fWidth to reduce LHS pain
// Apply the scale factor to the result
- fHeight *= m_fYScaleFactor;
+ fHeight *= font->m_fYScaleFactor;
// Store the final results
*pHeight = fHeight;
- fWidth *= m_fXScaleFactor;
+ fWidth *= font->m_fXScaleFactor;
*pWidth = fWidth;
}
-//--------------------------------------------------------------------------------------
-// Name: GetTextWidth()
-// Desc: Returns the width in pixels of a text string
-//--------------------------------------------------------------------------------------
-float XdkFont::GetTextWidth( const wchar_t * strText ) const
+void xdk360_video_font_begin (xdk360_video_font_t * font)
{
- float fTextWidth, fTextHeight;
- GetTextExtent( strText, &fTextWidth, &fTextHeight );
- return fTextWidth;
-}
-
-
-//--------------------------------------------------------------------------------------
-// Name: Begin()
-// Desc: Prepares the font vertex buffers for rendering.
-//--------------------------------------------------------------------------------------
-VOID XdkFont::Begin()
-{
- PIXBeginNamedEvent( 0, "Text Rendering" );
-
// Set state on the first call
- if( m_dwNestedBeginCount == 0 )
+ if( font->m_dwNestedBeginCount == 0 )
{
// Cache the global pointer into a register
xdk360_video_t *vid = (xdk360_video_t*)g_d3d;
D3DDevice *pD3dDevice = vid->xdk360_render_device;
// Save state
- if( m_bSaveState )
+ if( font->m_bSaveState )
{
// Note, we are not saving the texture, vertex, or pixel shader,
// since it's not worth the performance. We're more interested
// in saving state that would cause hard to find problems.
pD3dDevice->GetRenderState( D3DRS_ALPHABLENDENABLE,
- &m_dwSavedState[ SAVEDSTATE_D3DRS_ALPHABLENDENABLE ] );
- pD3dDevice->GetRenderState( D3DRS_SRCBLEND, &m_dwSavedState[ SAVEDSTATE_D3DRS_SRCBLEND ] );
- pD3dDevice->GetRenderState( D3DRS_DESTBLEND, &m_dwSavedState[ SAVEDSTATE_D3DRS_DESTBLEND ] );
- pD3dDevice->GetRenderState( D3DRS_BLENDOP, &m_dwSavedState[ SAVEDSTATE_D3DRS_BLENDOP ] );
- pD3dDevice->GetRenderState( D3DRS_ALPHATESTENABLE, &m_dwSavedState[ SAVEDSTATE_D3DRS_ALPHATESTENABLE ] );
- pD3dDevice->GetRenderState( D3DRS_ALPHAREF, &m_dwSavedState[ SAVEDSTATE_D3DRS_ALPHAREF ] );
- pD3dDevice->GetRenderState( D3DRS_ALPHAFUNC, &m_dwSavedState[ SAVEDSTATE_D3DRS_ALPHAFUNC ] );
- pD3dDevice->GetRenderState( D3DRS_FILLMODE, &m_dwSavedState[ SAVEDSTATE_D3DRS_FILLMODE ] );
- pD3dDevice->GetRenderState( D3DRS_CULLMODE, &m_dwSavedState[ SAVEDSTATE_D3DRS_CULLMODE ] );
- pD3dDevice->GetRenderState( D3DRS_ZENABLE, &m_dwSavedState[ SAVEDSTATE_D3DRS_ZENABLE ] );
- pD3dDevice->GetRenderState( D3DRS_STENCILENABLE, &m_dwSavedState[ SAVEDSTATE_D3DRS_STENCILENABLE ] );
- pD3dDevice->GetRenderState( D3DRS_VIEWPORTENABLE, &m_dwSavedState[ SAVEDSTATE_D3DRS_VIEWPORTENABLE ] );
- pD3dDevice->GetSamplerState( 0, D3DSAMP_MINFILTER, &m_dwSavedState[ SAVEDSTATE_D3DSAMP_MINFILTER ] );
- pD3dDevice->GetSamplerState( 0, D3DSAMP_MAGFILTER, &m_dwSavedState[ SAVEDSTATE_D3DSAMP_MAGFILTER ] );
- pD3dDevice->GetSamplerState( 0, D3DSAMP_ADDRESSU, &m_dwSavedState[ SAVEDSTATE_D3DSAMP_ADDRESSU ] );
- pD3dDevice->GetSamplerState( 0, D3DSAMP_ADDRESSV, &m_dwSavedState[ SAVEDSTATE_D3DSAMP_ADDRESSV ] );
+ &font->m_dwSavedState[ SAVEDSTATE_D3DRS_ALPHABLENDENABLE ] );
+ pD3dDevice->GetRenderState( D3DRS_SRCBLEND, &font->m_dwSavedState[ SAVEDSTATE_D3DRS_SRCBLEND ] );
+ pD3dDevice->GetRenderState( D3DRS_DESTBLEND, &font->m_dwSavedState[ SAVEDSTATE_D3DRS_DESTBLEND ] );
+ pD3dDevice->GetRenderState( D3DRS_BLENDOP, &font->m_dwSavedState[ SAVEDSTATE_D3DRS_BLENDOP ] );
+ pD3dDevice->GetRenderState( D3DRS_ALPHATESTENABLE, &font->m_dwSavedState[ SAVEDSTATE_D3DRS_ALPHATESTENABLE ] );
+ pD3dDevice->GetRenderState( D3DRS_ALPHAREF, &font->m_dwSavedState[ SAVEDSTATE_D3DRS_ALPHAREF ] );
+ pD3dDevice->GetRenderState( D3DRS_ALPHAFUNC, &font->m_dwSavedState[ SAVEDSTATE_D3DRS_ALPHAFUNC ] );
+ pD3dDevice->GetRenderState( D3DRS_FILLMODE, &font->m_dwSavedState[ SAVEDSTATE_D3DRS_FILLMODE ] );
+ pD3dDevice->GetRenderState( D3DRS_CULLMODE, &font->m_dwSavedState[ SAVEDSTATE_D3DRS_CULLMODE ] );
+ pD3dDevice->GetRenderState( D3DRS_ZENABLE, &font->m_dwSavedState[ SAVEDSTATE_D3DRS_ZENABLE ] );
+ pD3dDevice->GetRenderState( D3DRS_STENCILENABLE, &font->m_dwSavedState[ SAVEDSTATE_D3DRS_STENCILENABLE ] );
+ pD3dDevice->GetRenderState( D3DRS_VIEWPORTENABLE, &font->m_dwSavedState[ SAVEDSTATE_D3DRS_VIEWPORTENABLE ] );
+ pD3dDevice->GetSamplerState( 0, D3DSAMP_MINFILTER, &font->m_dwSavedState[ SAVEDSTATE_D3DSAMP_MINFILTER ] );
+ pD3dDevice->GetSamplerState( 0, D3DSAMP_MAGFILTER, &font->m_dwSavedState[ SAVEDSTATE_D3DSAMP_MAGFILTER ] );
+ pD3dDevice->GetSamplerState( 0, D3DSAMP_ADDRESSU, &font->m_dwSavedState[ SAVEDSTATE_D3DSAMP_ADDRESSU ] );
+ pD3dDevice->GetSamplerState( 0, D3DSAMP_ADDRESSV, &font->m_dwSavedState[ SAVEDSTATE_D3DSAMP_ADDRESSV ] );
}
// Set the texture scaling factor as a vertex shader constant
D3DSURFACE_DESC TextureDesc;
- m_pFontTexture->GetLevelDesc( 0, &TextureDesc ); // Get the description
+ font->m_pFontTexture->GetLevelDesc( 0, &TextureDesc ); // Get the description
// Set render state
- pD3dDevice->SetTexture( 0, m_pFontTexture );
+ pD3dDevice->SetTexture( 0, font->m_pFontTexture );
// Read the TextureDesc here to ensure no load/hit/store from GetLevelDesc()
float vTexScale[4];
@@ -546,42 +672,52 @@ VOID XdkFont::Begin()
}
// Keep track of the nested begin/end calls.
- m_dwNestedBeginCount++;
+ font->m_dwNestedBeginCount++;
}
-
-//--------------------------------------------------------------------------------------
-// Name: DrawText()
-// Desc: Draws text as textured polygons
-//--------------------------------------------------------------------------------------
-VOID XdkFont::DrawText( unsigned long dwColor, const wchar_t * strText,
- unsigned long dwFlags, float fMaxPixelWidth )
+void xdk360_video_font_end(xdk360_video_font_t * font)
{
- DrawText( m_fCursorX, m_fCursorY, dwColor, strText, dwFlags, fMaxPixelWidth );
+ if( --font->m_dwNestedBeginCount > 0 )
+ return;
+
+ // Restore state
+ if( font->m_bSaveState )
+ {
+ // Cache the global pointer into a register
+ xdk360_video_t *vid = (xdk360_video_t*)g_d3d;
+ D3DDevice *pD3dDevice = vid->xdk360_render_device;
+
+ pD3dDevice->SetTexture( 0, NULL );
+ pD3dDevice->SetVertexDeclaration( NULL );
+ pD3dDevice->SetVertexShader( NULL );
+ pD3dDevice->SetPixelShader( NULL );
+ pD3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, font->m_dwSavedState[ SAVEDSTATE_D3DRS_ALPHABLENDENABLE ] );
+ pD3dDevice->SetRenderState( D3DRS_SRCBLEND, font->m_dwSavedState[ SAVEDSTATE_D3DRS_SRCBLEND ] );
+ pD3dDevice->SetRenderState( D3DRS_DESTBLEND, font->m_dwSavedState[ SAVEDSTATE_D3DRS_DESTBLEND ] );
+ pD3dDevice->SetRenderState( D3DRS_BLENDOP, font->m_dwSavedState[ SAVEDSTATE_D3DRS_BLENDOP ] );
+ pD3dDevice->SetRenderState( D3DRS_ALPHATESTENABLE, font->m_dwSavedState[ SAVEDSTATE_D3DRS_ALPHATESTENABLE ] );
+ pD3dDevice->SetRenderState( D3DRS_ALPHAREF, font->m_dwSavedState[ SAVEDSTATE_D3DRS_ALPHAREF ] );
+ pD3dDevice->SetRenderState( D3DRS_ALPHAFUNC, font->m_dwSavedState[ SAVEDSTATE_D3DRS_ALPHAFUNC ] );
+ pD3dDevice->SetRenderState( D3DRS_FILLMODE, font->m_dwSavedState[ SAVEDSTATE_D3DRS_FILLMODE ] );
+ pD3dDevice->SetRenderState( D3DRS_CULLMODE, font->m_dwSavedState[ SAVEDSTATE_D3DRS_CULLMODE ] );
+ pD3dDevice->SetRenderState( D3DRS_ZENABLE, font->m_dwSavedState[ SAVEDSTATE_D3DRS_ZENABLE ] );
+ pD3dDevice->SetRenderState( D3DRS_STENCILENABLE, font->m_dwSavedState[ SAVEDSTATE_D3DRS_STENCILENABLE ] );
+ pD3dDevice->SetRenderState( D3DRS_VIEWPORTENABLE, font->m_dwSavedState[ SAVEDSTATE_D3DRS_VIEWPORTENABLE ] );
+ pD3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, font->m_dwSavedState[ SAVEDSTATE_D3DSAMP_MINFILTER ] );
+ pD3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, font->m_dwSavedState[ SAVEDSTATE_D3DSAMP_MAGFILTER ] );
+ pD3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSU, font->m_dwSavedState[ SAVEDSTATE_D3DSAMP_ADDRESSU ] );
+ pD3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSV, font->m_dwSavedState[ SAVEDSTATE_D3DSAMP_ADDRESSV ] );
+ }
}
-
-//--------------------------------------------------------------------------------------
-// Name: DrawText()
-// Desc: Draws text as textured polygons
-// TODO: This function should use the Begin/SetVertexData/End() API when it
-// becomes available.
-//--------------------------------------------------------------------------------------
-VOID XdkFont::DrawText( float fOriginX, float fOriginY, unsigned long dwColor,
- const wchar_t * strText, unsigned long dwFlags, float fMaxPixelWidth )
+void xdk360_video_font_draw_text(xdk360_video_font_t * font, float fOriginX, float fOriginY, unsigned long dwColor,
+ const wchar_t * strText, float fMaxPixelWidth )
{
- if( strText == NULL )
- return;
- if( L'\0' == strText[0] )
+ if( strText == NULL || strText[0] == L'\0')
return;
xdk360_video_t *vid = (xdk360_video_t*)g_d3d;
D3DDevice *pd3dDevice = vid->xdk360_render_device;
-
- // Create a PIX user-defined event that encapsulates all of the text draw calls.
- // This makes DrawText calls easier to recognize in PIX captures, and it makes
- // them take up fewer entries in the event list.
- PIXBeginNamedEvent( dwColor, "DrawText: %S", strText );
// Set the color as a vertex shader constant
float vColor[4];
@@ -591,7 +727,7 @@ VOID XdkFont::DrawText( float fOriginX, float fOriginY, unsigned long dwColor,
vColor[3] = ( ( dwColor & 0xff000000 ) >> 24L ) / 255.0F;
// Set up stuff to prepare for drawing text
- Begin();
+ xdk360_video_font_begin(font);
// Perform the actual storing of the color constant here to prevent
// a load-hit-store by inserting work between the store and the use of
@@ -599,56 +735,24 @@ VOID XdkFont::DrawText( float fOriginX, float fOriginY, unsigned long dwColor,
pd3dDevice->SetVertexShaderConstantF( 1, vColor, 1 );
// Set the starting screen position
- if( ( fOriginX < 0.0f ) || ( ( dwFlags & FONT_RIGHT ) && ( fOriginX <= 0.0f ) ) )
- fOriginX += ( m_rcWindow.x2 - m_rcWindow.x1 );
+ if((fOriginX < 0.0f))
+ fOriginX += font->m_rcWindow.x2;
if( fOriginY < 0.0f )
- fOriginY += ( m_rcWindow.y2 - m_rcWindow.y1 );
+ fOriginY += font->m_rcWindow.y2;
- m_fCursorX = floorf( fOriginX );
- m_fCursorY = floorf( fOriginY );
+ font->m_fCursorX = floorf( fOriginX );
+ font->m_fCursorY = floorf( fOriginY );
// Adjust for padding
- fOriginY -= m_fFontTopPadding;
-
- float fEllipsesPixelWidth = m_fXScaleFactor * 3.0f * ( m_Glyphs[m_TranslatorTable[L'.']].wOffset +
- m_Glyphs[m_TranslatorTable[L'.']].wAdvance );
-
- if( dwFlags & FONT_TRUNCATED )
- {
- // Check if we will really need to truncate the string
- if( fMaxPixelWidth <= 0.0f )
- dwFlags &= ( ~FONT_TRUNCATED );
- else
- {
- float w, h;
- GetTextExtent( strText, &w, &h, TRUE );
-
- // If not, then clear the flag
- if( w <= fMaxPixelWidth )
- dwFlags &= ( ~FONT_TRUNCATED );
- }
- }
-
- // If vertically centered, offset the starting m_fCursorY value
- if( dwFlags & FONT_CENTER_Y )
- {
- float w, h;
- GetTextExtent( strText, &w, &h );
- m_fCursorY = floorf( m_fCursorY - (h * 0.5f) );
- }
+ fOriginY -= font->m_fFontTopPadding;
// Add window offsets
- float Winx = static_cast(m_rcWindow.x1);
- float Winy = static_cast(m_rcWindow.y1);
+ float Winx = 0.0f;
+ float Winy = 0.0f;
fOriginX += Winx;
fOriginY += Winy;
- m_fCursorX += Winx;
- m_fCursorY += Winy;
-
- // Set a flag so we can determine initial justification effects
- BOOL bStartingNewLine = TRUE;
-
- unsigned long dwNumEllipsesToDraw = 0;
+ font->m_fCursorX += Winx;
+ font->m_fCursorY += Winy;
// Begin drawing the vertices
@@ -658,7 +762,7 @@ VOID XdkFont::DrawText( float fOriginX, float fOriginY, unsigned long dwColor,
volatile float * pVertex;
- unsigned long dwNumChars = wcslen( strText ) + ( dwFlags & FONT_TRUNCATED ? 3 : 0 );
+ unsigned long dwNumChars = wcslen(strText);
HRESULT hr = pd3dDevice->BeginVertices( D3DPT_QUADLIST, 4 * dwNumChars, sizeof( XMFLOAT4 ) ,
( VOID** )&pVertex );
// The ring buffer may run out of space when tiling, doing z-prepasses,
@@ -666,87 +770,42 @@ VOID XdkFont::DrawText( float fOriginX, float fOriginY, unsigned long dwColor,
if( FAILED( hr ) )
SSNES_ERR( "Ring buffer out of memory.\n" );
- bStartingNewLine = TRUE;
-
// Draw four vertices for each glyph
while( *strText )
{
wchar_t letter;
- if( dwNumEllipsesToDraw )
- letter = L'.';
- else
+ // Get the current letter in the string
+ letter = *strText++;
+
+ // Handle the newline character
+ if( letter == L'\n' )
{
- // If starting text on a new line, determine justification effects
- if( bStartingNewLine )
- {
- if( dwFlags & ( FONT_RIGHT | FONT_CENTER_X ) )
- {
- // Get the extent of this line
- float w, h;
- GetTextExtent( strText, &w, &h, TRUE );
-
- // Offset this line's starting m_fCursorX value
- if( dwFlags & FONT_RIGHT )
- m_fCursorX = floorf( fOriginX - w );
- if( dwFlags & FONT_CENTER_X )
- m_fCursorX = floorf( fOriginX - w * 0.5f );
- }
- bStartingNewLine = FALSE;
- }
-
- // Get the current letter in the string
- letter = *strText++;
-
- // Handle the newline character
- if( letter == L'\n' )
- {
- m_fCursorX = fOriginX;
- m_fCursorY += m_fFontYAdvance * m_fYScaleFactor;
- bStartingNewLine = TRUE;
- continue;
- }
-
- // Handle carriage return characters by ignoring them. This helps when
- // displaying text from a file.
- if( letter == L'\r' )
- continue;
+ font->m_fCursorX = fOriginX;
+ font->m_fCursorY += font->m_fFontYAdvance * font->m_fYScaleFactor;
+ continue;
}
// Translate unprintable characters
- const GLYPH_ATTR * pGlyph = &m_Glyphs[ ( letter <= m_cMaxGlyph ) ? m_TranslatorTable[letter] : 0 ];
+ const GLYPH_ATTR * pGlyph = &font->m_Glyphs[ ( letter <= font->m_cMaxGlyph ) ? font->m_TranslatorTable[letter] : 0 ];
- float fOffset = m_fXScaleFactor * (float)pGlyph->wOffset;
- float fAdvance = m_fXScaleFactor * (float)pGlyph->wAdvance;
- float fWidth = m_fXScaleFactor * (float)pGlyph->wWidth;
- float fHeight = m_fYScaleFactor * m_fFontHeight;
-
- if( 0 == dwNumEllipsesToDraw )
- {
- if( dwFlags & FONT_TRUNCATED )
- {
- // Check if we will be exceeded the max allowed width
- if( m_fCursorX + fOffset + fWidth + fEllipsesPixelWidth > fOriginX + fMaxPixelWidth )
- {
- // Yup, draw the three ellipses dots instead
- dwNumEllipsesToDraw = 3;
- continue;
- }
- }
- }
+ float fOffset = font->m_fXScaleFactor * (float)pGlyph->wOffset;
+ float fAdvance = font->m_fXScaleFactor * (float)pGlyph->wAdvance;
+ float fWidth = font->m_fXScaleFactor * (float)pGlyph->wWidth;
+ float fHeight = font->m_fYScaleFactor * font->m_fFontHeight;
// Setup the screen coordinates
- m_fCursorX += fOffset;
- float X4 = m_fCursorX;
+ font->m_fCursorX += fOffset;
+ float X4 = font->m_fCursorX;
float X1 = X4;
float X3 = X4 + fWidth;
float X2 = X1 + fWidth;
- float Y1 = m_fCursorY;
+ float Y1 = font->m_fCursorY;
float Y3 = Y1 + fHeight;
float Y2 = Y1;
float Y4 = Y3;
- m_fCursorX += fAdvance;
+ font->m_fCursorX += fAdvance;
// Select the RGBA channel that the compressed glyph is stored in
// Takes a 4 bit per pixel ARGB value and expand it to an 8 bit per pixel ARGB value
@@ -795,13 +854,6 @@ VOID XdkFont::DrawText( float fOriginX, float fOriginY, unsigned long dwColor,
reinterpret_cast(pVertex)[15] = dwChannelSelector;
pVertex+=16;
- // If drawing ellipses, exit when they're all drawn
- if( dwNumEllipsesToDraw )
- {
- if( --dwNumEllipsesToDraw == 0 )
- break;
- }
-
dwNumChars--;
}
@@ -833,57 +885,9 @@ VOID XdkFont::DrawText( float fOriginX, float fOriginY, unsigned long dwColor,
pd3dDevice->EndVertices();
// Undo window offsets
- m_fCursorX -= Winx;
- m_fCursorY -= Winy;
+ font->m_fCursorX -= Winx;
+ font->m_fCursorY -= Winy;
// Call End() to complete the begin/end pair for drawing text
- End();
-
- // Close off the user-defined event opened with PIXBeginNamedEvent.
- PIXEndNamedEvent();
-}
-
-
-//--------------------------------------------------------------------------------------
-// Name: End()
-// Desc: Paired call that restores state set in the Begin() call.
-//--------------------------------------------------------------------------------------
-VOID XdkFont::End()
-{
- if( --m_dwNestedBeginCount > 0 )
- {
- PIXEndNamedEvent();
- return;
- }
-
- // Restore state
- if( m_bSaveState )
- {
- // Cache the global pointer into a register
- xdk360_video_t *vid = (xdk360_video_t*)g_d3d;
- D3DDevice *pD3dDevice = vid->xdk360_render_device;
-
- pD3dDevice->SetTexture( 0, NULL );
- pD3dDevice->SetVertexDeclaration( NULL );
- pD3dDevice->SetVertexShader( NULL );
- pD3dDevice->SetPixelShader( NULL );
- pD3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, m_dwSavedState[ SAVEDSTATE_D3DRS_ALPHABLENDENABLE ] );
- pD3dDevice->SetRenderState( D3DRS_SRCBLEND, m_dwSavedState[ SAVEDSTATE_D3DRS_SRCBLEND ] );
- pD3dDevice->SetRenderState( D3DRS_DESTBLEND, m_dwSavedState[ SAVEDSTATE_D3DRS_DESTBLEND ] );
- pD3dDevice->SetRenderState( D3DRS_BLENDOP, m_dwSavedState[ SAVEDSTATE_D3DRS_BLENDOP ] );
- pD3dDevice->SetRenderState( D3DRS_ALPHATESTENABLE, m_dwSavedState[ SAVEDSTATE_D3DRS_ALPHATESTENABLE ] );
- pD3dDevice->SetRenderState( D3DRS_ALPHAREF, m_dwSavedState[ SAVEDSTATE_D3DRS_ALPHAREF ] );
- pD3dDevice->SetRenderState( D3DRS_ALPHAFUNC, m_dwSavedState[ SAVEDSTATE_D3DRS_ALPHAFUNC ] );
- pD3dDevice->SetRenderState( D3DRS_FILLMODE, m_dwSavedState[ SAVEDSTATE_D3DRS_FILLMODE ] );
- pD3dDevice->SetRenderState( D3DRS_CULLMODE, m_dwSavedState[ SAVEDSTATE_D3DRS_CULLMODE ] );
- pD3dDevice->SetRenderState( D3DRS_ZENABLE, m_dwSavedState[ SAVEDSTATE_D3DRS_ZENABLE ] );
- pD3dDevice->SetRenderState( D3DRS_STENCILENABLE, m_dwSavedState[ SAVEDSTATE_D3DRS_STENCILENABLE ] );
- pD3dDevice->SetRenderState( D3DRS_VIEWPORTENABLE, m_dwSavedState[ SAVEDSTATE_D3DRS_VIEWPORTENABLE ] );
- pD3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, m_dwSavedState[ SAVEDSTATE_D3DSAMP_MINFILTER ] );
- pD3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, m_dwSavedState[ SAVEDSTATE_D3DSAMP_MAGFILTER ] );
- pD3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSU, m_dwSavedState[ SAVEDSTATE_D3DSAMP_ADDRESSU ] );
- pD3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSV, m_dwSavedState[ SAVEDSTATE_D3DSAMP_ADDRESSV ] );
- }
-
- PIXEndNamedEvent();
+ xdk360_video_font_end(font);
}
\ No newline at end of file
diff --git a/360/fonts.h b/360/fonts.h
new file mode 100644
index 0000000000..c4f1e7b780
--- /dev/null
+++ b/360/fonts.h
@@ -0,0 +1,121 @@
+/* SSNES - A Super Nintendo Entertainment System (SNES) Emulator frontend for libsnes.
+ * Copyright (C) 2010-2012 - Hans-Kristian Arntzen
+ * Copyright (C) 2011-2012 - Daniel De Matteis
+ *
+ * Some code herein may be based on code found in BSNES.
+ *
+ * SSNES is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Found-
+ * ation, either version 3 of the License, or (at your option) any later version.
+ *
+ * SSNES is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with SSNES.
+ * If not, see .
+ */
+
+#ifndef SSNES_360_FONTS_H
+#define SSNES_360_FONTS_H
+
+#include "xdk360_video_resources.h"
+
+#define PAGE_UP (255)
+#define PAGE_DOWN (-255)
+
+#define SCREEN_SIZE_X_DEFAULT 640
+#define SCREEN_SIZE_Y_DEFAULT 480
+
+#define SAFE_AREA_PCT_4x3 85
+#define SAFE_AREA_PCT_HDTV 90
+
+typedef struct
+{
+ float m_fLineHeight; // height of a single line in pixels
+ unsigned int m_nScrollOffset; // offset to display text (in lines)
+ unsigned int first_message;
+ unsigned int m_cxSafeArea;
+ unsigned int m_cySafeArea;
+ unsigned int m_cxSafeAreaOffset;
+ unsigned int m_cySafeAreaOffset;
+ unsigned int m_nCurLine; // index of current line being written to
+ unsigned int m_cCurLineLength; // length of the current line
+ unsigned long m_colBackColor;
+ unsigned long m_colTextColor;
+ unsigned int m_cScreenHeight; // height in lines of screen area
+ unsigned int m_cScreenHeightVirtual; // height in lines of text storage buffer
+ unsigned int m_cScreenWidth; // width in characters
+ wchar_t * m_Buffer; // buffer big enough to hold a full screen
+ wchar_t ** m_Lines; // pointers to individual lines
+} video_console_t;
+
+typedef struct GLYPH_ATTR
+{
+ unsigned short tu1, tv1, tu2, tv2; // Texture coordinates for the image
+ short wOffset; // Pixel offset for glyph start
+ short wWidth; // Pixel width of the glyph
+ short wAdvance; // Pixels to advance after the glyph
+ unsigned short wMask; // Channel mask
+} GLYPH_ATTR;
+
+enum SavedStates
+{
+ SAVEDSTATE_D3DRS_ALPHABLENDENABLE,
+ SAVEDSTATE_D3DRS_SRCBLEND,
+ SAVEDSTATE_D3DRS_DESTBLEND,
+ SAVEDSTATE_D3DRS_BLENDOP,
+ SAVEDSTATE_D3DRS_ALPHATESTENABLE,
+ SAVEDSTATE_D3DRS_ALPHAREF,
+ SAVEDSTATE_D3DRS_ALPHAFUNC,
+ SAVEDSTATE_D3DRS_FILLMODE,
+ SAVEDSTATE_D3DRS_CULLMODE,
+ SAVEDSTATE_D3DRS_ZENABLE,
+ SAVEDSTATE_D3DRS_STENCILENABLE,
+ SAVEDSTATE_D3DRS_VIEWPORTENABLE,
+ SAVEDSTATE_D3DSAMP_MINFILTER,
+ SAVEDSTATE_D3DSAMP_MAGFILTER,
+ SAVEDSTATE_D3DSAMP_ADDRESSU,
+ SAVEDSTATE_D3DSAMP_ADDRESSV,
+
+ SAVEDSTATE_COUNT
+};
+
+typedef struct
+{
+ unsigned int m_bSaveState;
+ unsigned long m_dwSavedState[ SAVEDSTATE_COUNT ];
+ unsigned long m_dwNestedBeginCount;
+ unsigned long m_cMaxGlyph; // Number of entries in the translator table
+ unsigned long m_dwNumGlyphs; // Number of valid glyphs
+ float m_fFontHeight; // Height of the font strike in pixels
+ float m_fFontTopPadding; // Padding above the strike zone
+ float m_fFontBottomPadding; // Padding below the strike zone
+ float m_fFontYAdvance; // Number of pixels to move the cursor for a line feed
+ float m_fXScaleFactor; // Scaling constants
+ float m_fYScaleFactor;
+ float m_fCursorX; // Current text cursor
+ float m_fCursorY;
+ D3DRECT m_rcWindow; // Bounds rect of the text window, modify via accessors only!
+ wchar_t * m_TranslatorTable; // ASCII to glyph lookup table
+ D3DTexture* m_pFontTexture;
+ const GLYPH_ATTR* m_Glyphs; // Array of glyphs
+} xdk360_video_font_t;
+
+HRESULT xdk360_console_init ( LPCSTR strFontFileName, D3DCOLOR colBackColor, D3DCOLOR colTextColor);
+void xdk360_console_deinit (void);
+void xdk360_console_format (_In_z_ _Printf_format_string_ LPCSTR strFormat, ... );
+void xdk360_console_format_w (_In_z_ _Printf_format_string_ LPCWSTR wstrFormat, ... );
+void xdk360_console_draw (void);
+
+HRESULT xdk360_video_font_init(xdk360_video_font_t * font, const char * strFontFileName);
+void xdk360_video_font_get_text_width(xdk360_video_font_t * font, const wchar_t * strText, float * pWidth, float * pHeight, int bFirstLineOnly);
+void xdk360_video_font_deinit(xdk360_video_font_t * font);
+void xdk360_video_font_set_cursor_position(xdk360_video_font_t *font, float fCursorX, float fCursorY );
+void xdk360_video_font_begin (xdk360_video_font_t * font);
+void xdk360_video_font_end (xdk360_video_font_t * font);
+void xdk360_video_font_set_size(float x, float y);
+void xdk360_video_font_draw_text(xdk360_video_font_t * font, float fOriginX, float fOriginY, unsigned long dwColor,
+ const wchar_t * strText, float fMaxPixelWidth );
+
+#endif
diff --git a/360/menu.cpp b/360/menu.cpp
index 023d588932..7fdde89560 100644
--- a/360/menu.cpp
+++ b/360/menu.cpp
@@ -69,7 +69,7 @@ HRESULT CSSNES::UnregisterXuiClasses (void)
static void filebrowser_fetch_directory_entries(const char *path, CXuiList * romlist,
CXuiTextElement * rompath_title)
{
- filebrowser_parse_directory(&browser, path, ssnes_console_get_rom_ext());
+ filebrowser_push_directory(&browser, path, true);
unsigned long dwNum_rompath = MultiByteToWideChar(CP_ACP, 0, path, -1, NULL, 0);
wchar_t * rompath_name = new wchar_t[dwNum_rompath];
@@ -232,6 +232,8 @@ HRESULT CSSNESMain::OnInit(XUIMessageInit * pInitData, BOOL& bHandled)
HRESULT CSSNESFileBrowser::OnNotifyPress( HXUIOBJ hObjPressed, BOOL& bHandled )
{
+ char path[MAX_PATH_LENGTH];
+
if(hObjPressed == m_romlist)
{
int index = m_romlist.GetCurSel();
@@ -240,7 +242,7 @@ HRESULT CSSNESFileBrowser::OnNotifyPress( HXUIOBJ hObjPressed, BOOL& bHandled )
memset(strbuffer, 0, sizeof(strbuffer));
wcstombs(strbuffer, (const wchar_t *)m_romlist.GetText(index), sizeof(strbuffer));
memset(g_console.rom_path, 0, sizeof(g_console.rom_path));
- sprintf(g_console.rom_path, "%s%s", g_console.default_rom_startup_dir, strbuffer);
+ sprintf(g_console.rom_path, "%s%s", FILEBROWSER_GET_CURRENT_DIRECTORY_NAME(browser), strbuffer);
return_to_game();
g_console.initialize_ssnes_enable = 1;
@@ -249,9 +251,8 @@ HRESULT CSSNESFileBrowser::OnNotifyPress( HXUIOBJ hObjPressed, BOOL& bHandled )
{
memset(strbuffer, 0, sizeof(strbuffer));
wcstombs(strbuffer, (const wchar_t *)m_romlist.GetText(index), sizeof(strbuffer));
- char strbuf[512];
- snprintf(strbuf, sizeof(strbuf), "%s%s", g_console.default_rom_startup_dir, strbuffer);
- filebrowser_fetch_directory_entries(strbuf, &m_romlist, &m_rompathtitle);
+ snprintf(path, sizeof(path), "%s%s\\", FILEBROWSER_GET_CURRENT_DIRECTORY_NAME(browser), strbuffer);
+ filebrowser_fetch_directory_entries(path, &m_romlist, &m_rompathtitle);
}
}
else if(hObjPressed == m_back)
@@ -358,6 +359,8 @@ int menu_init (void)
XuiSceneNavigateFirst(app.GetRootObj(), app.hMainScene, XUSER_INDEX_FOCUS);
+ filebrowser_new(&browser, g_console.default_rom_startup_dir, ssnes_console_get_rom_ext());
+
return 0;
}
diff --git a/360/xdk360_video.cpp b/360/xdk360_video.cpp
index c10776607f..048ccd6e6b 100644
--- a/360/xdk360_video.cpp
+++ b/360/xdk360_video.cpp
@@ -22,6 +22,7 @@
#include "xdk360_video.h"
#include "../general.h"
+#include "../message.h"
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -71,7 +72,6 @@ static bool g_quitting;
static bool g_first_msg;
unsigned g_frame_count;
void *g_d3d;
-Console g_screen_console;
static void xdk360_gfx_free(void * data)
{
@@ -283,12 +283,12 @@ static bool xdk360_gfx_frame(void *data, const void *frame,
{
if(IS_TIMER_EXPIRED() || g_first_msg)
{
- g_screen_console.Format(true, msg);
+ xdk360_console_format(msg);
g_first_msg = 0;
- SET_TIMER_EXPIRATION(60);
+ SET_TIMER_EXPIRATION(30);
}
- g_screen_console.Render();
+ xdk360_console_draw();
}
if(!vid->block_swap)
@@ -363,7 +363,7 @@ void xdk360_video_init(void)
g_first_msg = true;
- HRESULT hr = g_screen_console.Create("game:\\media\\Arial_12.xpr",
+ HRESULT hr = xdk360_console_init("game:\\media\\Arial_12.xpr",
0xff000000, 0xffffffff );
if(FAILED(hr))
{
@@ -375,6 +375,7 @@ void xdk360_video_deinit(void)
{
void *data = g_d3d;
g_d3d = NULL;
+ xdk360_console_deinit();
xdk360_gfx_free(data);
}
diff --git a/360/xdk360_video.h b/360/xdk360_video.h
index 8e0fec84b1..89af5bb764 100644
--- a/360/xdk360_video.h
+++ b/360/xdk360_video.h
@@ -19,7 +19,7 @@
#ifndef _XDK360_VIDEO_H
#define _XDK360_VIDEO_H
-#include "xdk360_video_console.h"
+#include "fonts.h"
typedef struct {
float x;
@@ -58,7 +58,6 @@ void xdk360_video_init(void);
void xdk360_video_deinit(void);
void xdk360_video_set_vsync(bool vsync);
-extern Console g_screen_console;
extern unsigned g_frame_count;
extern void *g_d3d;
diff --git a/360/xdk360_video_console.cpp b/360/xdk360_video_console.cpp
deleted file mode 100644
index ee075f0877..0000000000
--- a/360/xdk360_video_console.cpp
+++ /dev/null
@@ -1,285 +0,0 @@
-/* SSNES - A Super Nintendo Entertainment System (SNES) Emulator frontend for libsnes.
- * Copyright (C) 2010-2012 - Hans-Kristian Arntzen
- * Copyright (C) 2011-2012 - Daniel De Matteis
- *
- * Some code herein may be based on code found in BSNES.
- *
- * SSNES is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Found-
- * ation, either version 3 of the License, or (at your option) any later version.
- *
- * SSNES is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with SSNES.
- * If not, see .
- */
-
-#include
-#include
-#include "xdk360_video.h"
-#include "xdk360_video_console.h"
-#include "xdk360_video_debugfonts.h"
-#include "../general.h"
-
-Console::Console()
-{
- first_message = true;
- m_Buffer = NULL;
- m_Lines = NULL;
- m_nScrollOffset = 0;
-}
-
-Console::~Console()
-{
- Destroy();
-}
-
-HRESULT Console::Create( LPCSTR strFontFileName, unsigned long colBackColor,
- unsigned long colTextColor, unsigned int nLines )
-{
- xdk360_video_t *vid = (xdk360_video_t*)g_d3d;
- D3DDevice *m_pd3dDevice = vid->xdk360_render_device;
-
- // Calculate the safe area
- unsigned int uiSafeAreaPct = vid->video_mode.fIsHiDef ? SAFE_AREA_PCT_HDTV
- : SAFE_AREA_PCT_4x3;
-
- m_cxSafeArea = ( vid->d3dpp.BackBufferWidth * uiSafeAreaPct ) / 100;
- m_cySafeArea = ( vid->d3dpp.BackBufferHeight * uiSafeAreaPct ) / 100;
-
- m_cxSafeAreaOffset = ( vid->d3dpp.BackBufferWidth - m_cxSafeArea ) / 2;
- m_cySafeAreaOffset = ( vid->d3dpp.BackBufferHeight - m_cySafeArea ) / 2;
-
- // Create the font
- HRESULT hr = m_Font.Create( strFontFileName );
- if( FAILED( hr ) )
- {
- SSNES_ERR( "Could not create font.\n" );
- return -1;
- }
-
- // Save the colors
- m_colBackColor = colBackColor;
- m_colTextColor = colTextColor;
-
- // Calculate the number of lines on the screen
- float fCharWidth, fCharHeight;
- m_Font.GetTextExtent( L"i", &fCharWidth, &fCharHeight, FALSE );
-
- m_cScreenHeight = (unsigned int)( m_cySafeArea / fCharHeight );
- m_cScreenWidth = (unsigned int)( m_cxSafeArea / fCharWidth );
-
- m_cScreenHeightVirtual = max( m_cScreenHeight, nLines );
-
- m_fLineHeight = fCharHeight;
-
- // Allocate memory to hold the lines
- m_Buffer = new wchar_t[ m_cScreenHeightVirtual * ( m_cScreenWidth + 1 ) ];
- m_Lines = new wchar_t *[ m_cScreenHeightVirtual ];
-
- // Set the line pointers as indexes into the buffer
- for( unsigned int i = 0; i < m_cScreenHeightVirtual; i++ )
- m_Lines[ i ] = m_Buffer + ( m_cScreenWidth + 1 ) * i;
-
- m_nCurLine = 0;
- m_cCurLineLength = 0;
- memset( m_Buffer, 0, m_cScreenHeightVirtual * ( m_cScreenWidth + 1 ) * sizeof( wchar_t ) );
- Render();
-
- return hr;
-}
-
-//--------------------------------------------------------------------------------------
-// Name: Destroy()
-// Desc: Tear everything down
-//--------------------------------------------------------------------------------------
-void Console::Destroy()
-{
- // Delete the memory we've allocated
- if( m_Lines )
- {
- delete[] m_Lines;
- m_Lines = NULL;
- }
-
- if( m_Buffer )
- {
- delete[] m_Buffer;
- m_Buffer = NULL;
- }
-
- // Destroy the font
- m_Font.Destroy();
-}
-
-
-//--------------------------------------------------------------------------------------
-// Name: Render()
-// Desc: Render the console to the screen
-//--------------------------------------------------------------------------------------
-void Console::Render()
-{
- xdk360_video_t *vid = (xdk360_video_t*)g_d3d;
- D3DDevice *m_pd3dDevice = vid->xdk360_render_device;
-
- // The top line
- unsigned int nTextLine = ( m_nCurLine - m_cScreenHeight + m_cScreenHeightVirtual - m_nScrollOffset + 1 )
- % m_cScreenHeightVirtual;
-
- m_Font.Begin();
-
- for( unsigned int nScreenLine = 0; nScreenLine < m_cScreenHeight; nScreenLine++ )
- {
- m_Font.DrawText( (float)( m_cxSafeAreaOffset ),
- (float)( m_cySafeAreaOffset + m_fLineHeight * nScreenLine ),
- m_colTextColor, m_Lines[nTextLine] );
-
- nTextLine = ( nTextLine + 1 ) % m_cScreenHeightVirtual;
- }
-
- m_Font.End();
-}
-
-
-//--------------------------------------------------------------------------------------
-// Name: Add( CHAR )
-// Desc: Convert ANSI to WCHAR and add to the current line
-//--------------------------------------------------------------------------------------
-void Console::Add( char ch )
-{
- wchar_t wch;
-
- int ret = MultiByteToWideChar( CP_ACP, // ANSI code page
- 0, // No flags
- &ch, // Character to convert
- 1, // Convert one byte
- &wch, // Target wide character buffer
- 1 ); // One wide character
-
- Add( wch );
-}
-
-
-
-//--------------------------------------------------------------------------------------
-// Name: Add( WCHAR )
-// Desc: Add a wide character to the current line
-//--------------------------------------------------------------------------------------
-void Console::Add( wchar_t wch )
-{
- // If this is a newline, just increment lines and move on
- if( wch == L'\n' )
- {
- m_nCurLine = ( m_nCurLine + 1 ) % m_cScreenHeightVirtual;
- m_cCurLineLength = 0;
- memset( m_Lines[m_nCurLine], 0, ( m_cScreenWidth + 1 ) * sizeof( wchar_t ) );
- return;
- }
-
- int bIncrementLine = FALSE; // Whether to wrap to the next line
-
- if( m_cCurLineLength == m_cScreenWidth )
- bIncrementLine = TRUE;
- else
- {
- // Try to append the character to the line
- m_Lines[ m_nCurLine ][ m_cCurLineLength ] = wch;
-
- if( m_Font.GetTextWidth( m_Lines[ m_nCurLine ] ) > m_cxSafeArea )
- {
- // The line is too long, we need to wrap the character to the next line
- m_Lines[ m_nCurLine][ m_cCurLineLength ] = L'\0';
- bIncrementLine = TRUE;
- }
- }
-
- // If we need to skip to the next line, do so
- if( bIncrementLine )
- {
- m_nCurLine = ( m_nCurLine + 1 ) % m_cScreenHeightVirtual;
- m_cCurLineLength = 0;
- memset( m_Lines[m_nCurLine], 0, ( m_cScreenWidth + 1 ) * sizeof( wchar_t ) );
- m_Lines[ m_nCurLine ][0] = wch;
- }
-
- if(IS_TIMER_EXPIRED())
- m_cCurLineLength++;
-}
-
-
-//--------------------------------------------------------------------------------------
-// Name: Format()
-// Desc: Output a variable argument list using a format string
-//--------------------------------------------------------------------------------------
-void Console::Format(int clear_screen, _In_z_ _Printf_format_string_ LPCSTR strFormat, ... )
-{
- if(clear_screen)
- {
- m_nCurLine = 0;
- m_cCurLineLength = 0;
- memset( m_Buffer, 0, m_cScreenHeightVirtual * ( m_cScreenWidth + 1 ) * sizeof( wchar_t ) );
- }
-
- va_list pArgList;
- va_start( pArgList, strFormat );
- FormatV( strFormat, pArgList );
- va_end( pArgList );
-
- // Render the output
- Render();
-}
-
-void Console::Format(int clear_screen, _In_z_ _Printf_format_string_ LPCWSTR wstrFormat, ... )
-{
- if(clear_screen)
- {
- m_nCurLine = 0;
- m_cCurLineLength = 0;
- memset( m_Buffer, 0, m_cScreenHeightVirtual * ( m_cScreenWidth + 1 ) * sizeof( wchar_t ) );
- }
-
- va_list pArgList;
- va_start( pArgList, wstrFormat );
- FormatV( wstrFormat, pArgList );
- va_end( pArgList );
-
- // Render the output
- Render();
-}
-
-
-//--------------------------------------------------------------------------------------
-// Name: FormatV()
-// Desc: Output a va_list using a format string
-//--------------------------------------------------------------------------------------
-void Console::FormatV( _In_z_ _Printf_format_string_ LPCSTR strFormat, va_list pArgList )
-{
- // Count the required length of the string
- unsigned long dwStrLen = _vscprintf( strFormat, pArgList ) + 1; // +1 = null terminator
- char * strMessage = ( char * )_malloca( dwStrLen );
- vsprintf_s( strMessage, dwStrLen, strFormat, pArgList );
-
- // Output the string to the console
- unsigned long uStringLength = strlen( strMessage );
- for( unsigned long i = 0; i < uStringLength; i++ )
- Add( strMessage[i] );
-
- _freea( strMessage );
-}
-
-void Console::FormatV( _In_z_ _Printf_format_string_ LPCWSTR wstrFormat, va_list pArgList )
-{
- // Count the required length of the string
- unsigned long dwStrLen = _vscwprintf( wstrFormat, pArgList ) + 1; // +1 = null terminator
- wchar_t * strMessage = ( wchar_t * )_malloca( dwStrLen * sizeof( wchar_t ) );
- vswprintf_s( strMessage, dwStrLen, wstrFormat, pArgList );
-
- // Output the string to the console
- unsigned long uStringLength = wcslen( strMessage );
- for( unsigned long i = 0; i < uStringLength; i++ )
- Add( strMessage[i] );
-
- _freea( strMessage );
-}
diff --git a/360/xdk360_video_console.h b/360/xdk360_video_console.h
deleted file mode 100644
index a436b23677..0000000000
--- a/360/xdk360_video_console.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/* SSNES - A Super Nintendo Entertainment System (SNES) Emulator frontend for libsnes.
- * Copyright (C) 2010-2012 - Hans-Kristian Arntzen
- * Copyright (C) 2011-2012 - Daniel De Matteis
- *
- * Some code herein may be based on code found in BSNES.
- *
- * SSNES is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Found-
- * ation, either version 3 of the License, or (at your option) any later version.
- *
- * SSNES is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with SSNES.
- * If not, see .
- */
-
-#pragma once
-#ifndef SSNES360_CONSOLE_H
-#define SSNES360_CONSOLE_H
-
-#include
-#include "xdk360_video_debugfonts.h"
-
-#define PAGE_UP (255)
-#define PAGE_DOWN (-255)
-
-#define SCREEN_SIZE_X_DEFAULT 640
-#define SCREEN_SIZE_Y_DEFAULT 480
-
-#define SAFE_AREA_PCT_4x3 85
-#define SAFE_AREA_PCT_HDTV 90
-
-//--------------------------------------------------------------------------------------
-// Name: class Console
-// Desc: Class to implement the console.
-//--------------------------------------------------------------------------------------
-class Console
-{
-public:
- Console();
- ~Console();
-
- // Initialization
- HRESULT Create( LPCSTR strFontFileName,
- D3DCOLOR colBackColor,
- D3DCOLOR colTextColor,
- unsigned int nLines = 0 );
-
- void Destroy();
-
- // Console output
- void Format(int clear_screen, _In_z_ _Printf_format_string_ LPCSTR strFormat, ... );
- void Format(int clear_screen, _In_z_ _Printf_format_string_ LPCWSTR wstrFormat, ... );
- void FormatV( _In_z_ _Printf_format_string_ LPCSTR strFormat, va_list pArgList );
- void FormatV( _In_z_ _Printf_format_string_ LPCWSTR wstrFormat, va_list pArgList );
-
- // method for rendering the console
- void Render();
- // Font for rendering text
- XdkFont m_Font;
-private:
- int first_message;
- // Safe area dimensions
- unsigned int m_cxSafeArea;
- unsigned int m_cySafeArea;
-
- unsigned int m_cxSafeAreaOffset;
- unsigned int m_cySafeAreaOffset;
-
- // Colors
- unsigned long m_colBackColor;
- unsigned long m_colTextColor;
-
- // Text Buffers
- unsigned int m_cScreenHeight; // height in lines of screen area
- unsigned int m_cScreenHeightVirtual; // height in lines of text storage buffer
- unsigned int m_cScreenWidth; // width in characters
- float m_fLineHeight; // height of a single line in pixels
-
- wchar_t * m_Buffer; // buffer big enough to hold a full screen
- wchar_t ** m_Lines; // pointers to individual lines
- unsigned int m_nCurLine; // index of current line being written to
- unsigned int m_cCurLineLength; // length of the current line
- int m_nScrollOffset; // offset to display text (in lines)
-
- // Add a character to the current line
- void Add( char ch );
- void Add( wchar_t wch );
-};
-
-#endif
diff --git a/360/xdk360_video_debugfonts.h b/360/xdk360_video_debugfonts.h
deleted file mode 100644
index df0370e9e5..0000000000
--- a/360/xdk360_video_debugfonts.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/* SSNES - A Super Nintendo Entertainment System (SNES) Emulator frontend for libsnes.
- * Copyright (C) 2010-2012 - Hans-Kristian Arntzen
- * Copyright (C) 2011-2012 - Daniel De Matteis
- *
- * Some code herein may be based on code found in BSNES.
- *
- * SSNES is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Found-
- * ation, either version 3 of the License, or (at your option) any later version.
- *
- * SSNES is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with SSNES.
- * If not, see .
- */
-
-#ifndef _SSNES360_DEBUG_FONTS_H
-#define _SSNES360_DEBUG_FONTS_H
-
-#include "xdk360_video_resources.h"
-
-typedef struct GLYPH_ATTR
-{
- unsigned short tu1, tv1, tu2, tv2; // Texture coordinates for the image
- short wOffset; // Pixel offset for glyph start
- short wWidth; // Pixel width of the glyph
- short wAdvance; // Pixels to advance after the glyph
- unsigned short wMask; // Channel mask
-} GLYPH_ATTR;
-
-#define FONT_LEFT 0x00000000
-#define FONT_RIGHT 0x00000001
-#define FONT_CENTER_X 0x00000002
-#define FONT_CENTER_Y 0x00000004
-#define FONT_TRUNCATED 0x00000008
-
-enum SavedStates
-{
- SAVEDSTATE_D3DRS_ALPHABLENDENABLE,
- SAVEDSTATE_D3DRS_SRCBLEND,
- SAVEDSTATE_D3DRS_DESTBLEND,
- SAVEDSTATE_D3DRS_BLENDOP,
- SAVEDSTATE_D3DRS_ALPHATESTENABLE,
- SAVEDSTATE_D3DRS_ALPHAREF,
- SAVEDSTATE_D3DRS_ALPHAFUNC,
- SAVEDSTATE_D3DRS_FILLMODE,
- SAVEDSTATE_D3DRS_CULLMODE,
- SAVEDSTATE_D3DRS_ZENABLE,
- SAVEDSTATE_D3DRS_STENCILENABLE,
- SAVEDSTATE_D3DRS_VIEWPORTENABLE,
- SAVEDSTATE_D3DSAMP_MINFILTER,
- SAVEDSTATE_D3DSAMP_MAGFILTER,
- SAVEDSTATE_D3DSAMP_ADDRESSU,
- SAVEDSTATE_D3DSAMP_ADDRESSV,
-
- SAVEDSTATE_COUNT
-};
-
-class XdkFont
-{
-public:
- PackedResource m_xprResource;
-
- // Font vertical dimensions taken from the font file
- float m_fFontHeight; // Height of the font strike in pixels
- float m_fFontTopPadding; // Padding above the strike zone
- float m_fFontBottomPadding; // Padding below the strike zone
- float m_fFontYAdvance; // Number of pixels to move the cursor for a line feed
-
- float m_fXScaleFactor; // Scaling constants
- float m_fYScaleFactor;
-
- D3DRECT m_rcWindow; // Bounds rect if the text window, modify via accessors only!
- float m_fCursorX; // Current text cursor
- float m_fCursorY;
-
- // Translator table for supporting unicode ranges
- unsigned long m_cMaxGlyph; // Number of entries in the translator table
- wchar_t * m_TranslatorTable; // ASCII to glyph lookup table
-
- // Glyph data for the font
- unsigned long m_dwNumGlyphs; // Number of valid glyphs
- const GLYPH_ATTR* m_Glyphs; // Array of glyphs
-
- // D3D rendering objects
- D3DTexture* m_pFontTexture;
-
- // Saved state for rendering (if not using a pure device)
- unsigned long m_dwSavedState[ SAVEDSTATE_COUNT ];
- unsigned long m_dwNestedBeginCount;
- int m_bSaveState;
-public:
- XdkFont();
- ~XdkFont();
-
- // Functions to create and destroy the internal objects
- HRESULT Create( const char * strFontFileName );
- void Destroy();
-
- // Returns the dimensions of a text string
- void GetTextExtent( const wchar_t * strText, float * pWidth,
- float * pHeight, int bFirstLineOnly=FALSE ) const;
- float GetTextWidth( const wchar_t * strText ) const;
- void SetCursorPosition( float fCursorX, float fCursorY );
- void SetFontSize(float x, float y);
-
- // Public calls to render text. Callers can simply call DrawText(), but for
- // performance, they should batch multiple calls together, bracketed by calls to
- // Begin() and End().
- void Begin();
- void DrawText( unsigned long dwColor, const wchar_t * strText, unsigned long dwFlags=0L,
- float fMaxPixelWidth = 0.0f );
- void DrawText( float sx, float sy, unsigned long dwColor, const wchar_t * strText,
- unsigned long dwFlags=0L, float fMaxPixelWidth = 0.0f );
- void End();
-
-private:
- // Internal helper functions
- HRESULT CreateFontShaders();
-};
-
-#endif
\ No newline at end of file
diff --git a/360/xdk360_video_resources.cpp b/360/xdk360_video_resources.cpp
index 104058f575..e518caab08 100644
--- a/360/xdk360_video_resources.cpp
+++ b/360/xdk360_video_resources.cpp
@@ -33,7 +33,6 @@ struct XPR_HEADER
};
#define XPR2_MAGIC_VALUE (0x58505232)
-#define eXALLOCAllocatorId_AtgResource eXALLOCAllocatorId_GameMax
//--------------------------------------------------------------------------------------
// Name: PackedResource
@@ -120,7 +119,7 @@ HRESULT PackedResource::Create( const char * strFilename )
m_dwSysMemDataSize = 0;
return E_FAIL;
}
- m_pVidMemData = ( BYTE* )XMemAlloc( m_dwVidMemDataSize, MAKE_XALLOC_ATTRIBUTES( 0, 0, 0, 0, eXALLOCAllocatorId_AtgResource,
+ m_pVidMemData = ( BYTE* )XMemAlloc( m_dwVidMemDataSize, MAKE_XALLOC_ATTRIBUTES( 0, 0, 0, 0, eXALLOCAllocatorId_GameMax,
XALLOC_PHYSICAL_ALIGNMENT_4K, XALLOC_MEMPROTECT_WRITECOMBINE, 0, XALLOC_MEMTYPE_PHYSICAL ) );
if( m_pVidMemData == NULL )
@@ -160,9 +159,6 @@ HRESULT PackedResource::Create( const char * strFilename )
D3DTexture* pTexture = ( D3DTexture* )&m_pSysMemData[m_pResourceTags[i].dwOffset];
// Adjust Base address according to where memory was allocated
XGOffsetBaseTextureAddress( pTexture, m_pVidMemData, m_pVidMemData );
-
- // Let PIX know the name of the texture
- PIXSetTextureName(pTexture, m_pResourceTags[i].strName);
}
}
@@ -182,7 +178,7 @@ void PackedResource::Destroy()
m_dwSysMemDataSize = 0L;
if( m_pVidMemData != NULL )
- XMemFree( m_pVidMemData, MAKE_XALLOC_ATTRIBUTES( 0, 0, 0, 0, eXALLOCAllocatorId_AtgResource,
+ XMemFree( m_pVidMemData, MAKE_XALLOC_ATTRIBUTES( 0, 0, 0, 0, eXALLOCAllocatorId_GameMax,
0, 0, 0, XALLOC_MEMTYPE_PHYSICAL ) );
m_pVidMemData = NULL;
diff --git a/file.c b/file.c
index 95f9533c19..12ce830781 100644
--- a/file.c
+++ b/file.c
@@ -550,23 +550,17 @@ void save_ram_file(const char *path, int type)
}
}
-#ifdef HAVE_XML
static char *load_xml_map(const char *path)
{
char *xml_buf = NULL;
if (*path)
{
- if (!read_file_string(path, &xml_buf))
- SSNES_LOG("Did not find XML memory map in \"%s\"\n", path);
- else
+ if (read_file_string(path, &xml_buf))
SSNES_LOG("Found XML memory map in \"%s\"\n", path);
}
return xml_buf;
}
-#else
-#define load_xml_map(xml_name) (NULL)
-#endif
static bool load_sgb_rom(void)
{
diff --git a/input/sdl_input.c b/input/sdl_input.c
index 3ce051f393..3cb38b828e 100644
--- a/input/sdl_input.c
+++ b/input/sdl_input.c
@@ -150,23 +150,28 @@ static void *sdl_input_init(void)
if (g_settings.input.joypad_map[i] < 0)
continue;
- if (sdl->num_joysticks > (unsigned)g_settings.input.joypad_map[i])
- {
- sdl->joysticks[i] = SDL_JoystickOpen(g_settings.input.joypad_map[i]);
- if (!sdl->joysticks[i])
- {
- SSNES_ERR("Couldn't open SDL joystick #%u on SNES port %u\n", g_settings.input.joypad_map[i], i + 1);
- free(sdl);
- SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
- return NULL;
- }
+ unsigned port = g_settings.input.joypad_map[i];
- SSNES_LOG("Opened Joystick: %s #%u on port %u\n",
- SDL_JoystickName(g_settings.input.joypad_map[i]), g_settings.input.joypad_map[i], i + 1);
- sdl->num_axes[i] = SDL_JoystickNumAxes(sdl->joysticks[i]);
- sdl->num_buttons[i] = SDL_JoystickNumButtons(sdl->joysticks[i]);
- sdl->num_hats[i] = SDL_JoystickNumHats(sdl->joysticks[i]);
+ if (sdl->num_joysticks <= port)
+ continue;
+
+ sdl->joysticks[i] = SDL_JoystickOpen(port);
+ if (!sdl->joysticks[i])
+ {
+ SSNES_ERR("Couldn't open SDL joystick #%u on SNES port %u\n", port, i + 1);
+ free(sdl);
+ SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
+ return NULL;
}
+
+ SSNES_LOG("Opened Joystick: %s (#%u) on port %u\n",
+ SDL_JoystickName(port), port, i + 1);
+
+ sdl->num_axes[i] = SDL_JoystickNumAxes(sdl->joysticks[i]);
+ sdl->num_buttons[i] = SDL_JoystickNumButtons(sdl->joysticks[i]);
+ sdl->num_hats[i] = SDL_JoystickNumHats(sdl->joysticks[i]);
+ SSNES_LOG("Joypad has: %u axes, %u buttons, %u hats.\n",
+ sdl->num_axes[i], sdl->num_buttons[i], sdl->num_hats[i]);
}
#endif
@@ -188,39 +193,32 @@ static bool sdl_joykey_pressed(sdl_input_t *sdl, int port_num, uint16_t joykey)
// Check hat.
if (GET_HAT_DIR(joykey))
{
- int hat = GET_HAT(joykey);
- if (hat < (int)sdl->num_hats[port_num])
+ uint16_t hat = GET_HAT(joykey);
+ if (hat >= sdl->num_hats[port_num])
+ return false;
+
+ Uint8 dir = SDL_JoystickGetHat(sdl->joysticks[port_num], hat);
+ switch (GET_HAT_DIR(joykey))
{
- Uint8 dir = SDL_JoystickGetHat(sdl->joysticks[port_num], hat);
- switch (GET_HAT_DIR(joykey))
- {
- case HAT_UP_MASK:
- if (dir & SDL_HAT_UP)
- return true;
- break;
- case HAT_DOWN_MASK:
- if (dir & SDL_HAT_DOWN)
- return true;
- break;
- case HAT_LEFT_MASK:
- if (dir & SDL_HAT_LEFT)
- return true;
- break;
- case HAT_RIGHT_MASK:
- if (dir & SDL_HAT_RIGHT)
- return true;
- break;
- default:
- break;
- }
+ case HAT_UP_MASK:
+ return dir & SDL_HAT_UP;
+ case HAT_DOWN_MASK:
+ return dir & SDL_HAT_DOWN;
+ case HAT_LEFT_MASK:
+ return dir & SDL_HAT_LEFT;
+ case HAT_RIGHT_MASK:
+ return dir & SDL_HAT_RIGHT;
+ default:
+ return false;
}
}
else // Check the button
{
if (joykey < sdl->num_buttons[port_num] && SDL_JoystickGetButton(sdl->joysticks[port_num], joykey))
return true;
+
+ return false;
}
- return false;
}
static bool sdl_axis_pressed(sdl_input_t *sdl, int port_num, uint32_t joyaxis)
diff --git a/msvc-360/SSNES-360/SSNES-360.vcxproj b/msvc-360/SSNES-360/SSNES-360.vcxproj
index 7e325822d7..d78cfd81a6 100644
--- a/msvc-360/SSNES-360/SSNES-360.vcxproj
+++ b/msvc-360/SSNES-360/SSNES-360.vcxproj
@@ -283,13 +283,12 @@
+
-
-
diff --git a/msvc-360/SSNES-360/SSNES-360.vcxproj.filters b/msvc-360/SSNES-360/SSNES-360.vcxproj.filters
index 3ac3d35f3b..16aa724cae 100644
--- a/msvc-360/SSNES-360/SSNES-360.vcxproj.filters
+++ b/msvc-360/SSNES-360/SSNES-360.vcxproj.filters
@@ -131,13 +131,10 @@
Source Files\console
-
- Source Files\360
-
Source Files\360
-
+
Source Files\360
diff --git a/settings.c b/settings.c
index 5980071922..fc39b0c408 100644
--- a/settings.c
+++ b/settings.c
@@ -418,7 +418,7 @@ bool config_load_file(const char *path)
for (unsigned i = 0; i < MAX_PLAYERS; i++)
{
char buf[64];
- snprintf(buf, sizeof(buf), "input_player%u_joypad_index", i);
+ snprintf(buf, sizeof(buf), "input_player%u_joypad_index", i + 1);
CONFIG_GET_INT(input.joypad_map[i], buf);
}
@@ -697,27 +697,30 @@ static void read_keybinds_keyboard(config_file_t *conf, unsigned player, unsigne
static void parse_hat(struct snes_keybind *bind, const char *str)
{
- if (isdigit(*str))
+ if (!isdigit(*str))
+ return;
+
+ char *dir = NULL;
+ uint16_t hat = strtoul(str, &dir, 0);
+ uint16_t hat_dir = 0;
+
+ if (!dir)
{
- char *dir = NULL;
- int hat = strtol(str, &dir, 0);
- int hat_dir = 0;
-
- if (dir)
- {
- if (strcasecmp(str, "up") == 0)
- hat_dir = HAT_UP_MASK;
- else if (strcasecmp(str, "down") == 0)
- hat_dir = HAT_DOWN_MASK;
- else if (strcasecmp(str, "left") == 0)
- hat_dir = HAT_LEFT_MASK;
- else if (strcasecmp(str, "right") == 0)
- hat_dir = HAT_RIGHT_MASK;
-
- if (hat_dir)
- bind->joykey = HAT_MAP(hat, hat_dir);
- }
+ SSNES_WARN("Found invalid hat in config!\n");
+ return;
}
+
+ if (strcasecmp(dir, "up") == 0)
+ hat_dir = HAT_UP_MASK;
+ else if (strcasecmp(dir, "down") == 0)
+ hat_dir = HAT_DOWN_MASK;
+ else if (strcasecmp(dir, "left") == 0)
+ hat_dir = HAT_LEFT_MASK;
+ else if (strcasecmp(dir, "right") == 0)
+ hat_dir = HAT_RIGHT_MASK;
+
+ if (hat_dir)
+ bind->joykey = HAT_MAP(hat, hat_dir);
}
static void read_keybinds_button(config_file_t *conf, unsigned player, unsigned index, struct snes_keybind *bind)
diff --git a/ssnes.c b/ssnes.c
index cbf22d6acf..389e767512 100644
--- a/ssnes.c
+++ b/ssnes.c
@@ -419,9 +419,7 @@ static void print_features(void)
_PSUPP(al, "OpenAL", "audio driver");
_PSUPP(dylib, "External", "External filter and driver support");
_PSUPP(cg, "Cg", "Cg pixel shaders");
-#ifdef HAVE_XML
_PSUPP(xml, "XML", "bSNES XML pixel shaders");
-#endif
_PSUPP(sdl_image, "SDL_image", "SDL_image image loading");
_PSUPP(fbo, "FBO", "OpenGL render-to-texture (multi-pass shaders)");
_PSUPP(dynamic, "Dynamic", "Dynamic run-time loading of libsnes library");
@@ -512,9 +510,7 @@ static void print_help(void)
puts("\t-v/--verbose: Verbose logging.");
puts("\t-U/--ups: Specifies path for UPS patch that will be applied to ROM.");
puts("\t--bps: Specifies path for BPS patch that will be applied to ROM.");
-#ifdef HAVE_XML
puts("\t-X/--xml: Specifies path to XML memory map.");
-#endif
puts("\t-D/--detach: Detach SSNES from the running console. Not relevant for all platforms.\n");
}
@@ -661,9 +657,7 @@ static void parse_input(int argc, char *argv[])
#endif
{ "ups", 1, NULL, 'U' },
{ "bps", 1, &val, 'B' },
-#ifdef HAVE_XML
{ "xml", 1, NULL, 'X' },
-#endif
{ "detach", 0, NULL, 'D' },
{ "features", 0, &val, 'f' },
{ NULL, 0, NULL, 0 }
@@ -856,11 +850,10 @@ static void parse_input(int argc, char *argv[])
strlcpy(g_extern.ups_name, optarg, sizeof(g_extern.ups_name));
g_extern.ups_pref = true;
break;
-#ifdef HAVE_XML
+
case 'X':
strlcpy(g_extern.xml_name, optarg, sizeof(g_extern.xml_name));
break;
-#endif
case 'D':
#if defined(_WIN32) && !defined(_XBOX)
@@ -1492,10 +1485,8 @@ static void fill_pathnames(void)
if (!(*g_extern.bps_name))
fill_pathname_noext(g_extern.bps_name, g_extern.basename, ".bps", sizeof(g_extern.bps_name));
-#ifdef HAVE_XML
if (!(*g_extern.xml_name))
fill_pathname_noext(g_extern.xml_name, g_extern.basename, ".xml", sizeof(g_extern.xml_name));
-#endif
if (!(*g_settings.screenshot_directory))
{