From 7cfe0fef400c412f8039bba8c842b5235b3719d2 Mon Sep 17 00:00:00 2001 From: freakdave Date: Sun, 15 Jul 2012 20:49:34 +0200 Subject: [PATCH 01/51] (Xbox 1) Fixed debug output not showing correctly on HDTV's (Xbox 1) Fixed debug output in debug mode not showing the second line (FPS/Frames) --- msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj | 6 +++--- xbox1/xdk_d3d8.cpp | 19 ++++++++++++++----- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj b/msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj index a0736faea7..463b0679ef 100644 --- a/msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj +++ b/msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj @@ -19,18 +19,18 @@ CharacterSet="2"> + DebugInformationFormat="3"/> d3d_render_device->SetViewport(&vp); + font_x = vp.X; + font_y = vp.Y; + //if(gl->overscan_enable && !force_full) //{ // m_left = -gl->overscan_amount/2; @@ -346,6 +350,9 @@ static void *xdk_d3d_init(const video_info_t *video, const input_driver_t **inpu d3d->debug_font->SetBkColor(D3DCOLOR_ARGB(100,0,0,0)); d3d->debug_font->SetTextHeight(14); d3d->debug_font->SetTextAntialiasLevel(d3d->debug_font->GetTextAntialiasLevel()); + + font_x = 0; + font_y = 0; #endif return d3d; @@ -448,10 +455,10 @@ static bool xdk_d3d_frame(void *data, const void *frame, bool ret = false; sprintf(buf, "%.2f MB free / %.2f MB total", stat.dwAvailPhys/(1024.0f*1024.0f), stat.dwTotalPhys/(1024.0f*1024.0f)); rarch_convert_char_to_wchar(strw_buffer, buf, sizeof(strw_buffer)); - d3d->debug_font->TextOut(d3d->pFrontBuffer, strw_buffer, (unsigned)-1, 30, 50 ); - d3d->debug_font->TextOut(d3d->pBackBuffer, strw_buffer, (unsigned)-1, 30, 50 ); + d3d->debug_font->TextOut(d3d->pFrontBuffer, strw_buffer, (unsigned)-1, font_x + 30, font_y + 50 ); + d3d->debug_font->TextOut(d3d->pBackBuffer, strw_buffer, (unsigned)-1, font_x + 30, font_y + 50 ); - if(ret = gfx_window_title(buf2, sizeof(buf2)) || buf_fps_last) + if(ret = gfx_window_title(buf2, sizeof(buf2)) || sizeof(buf_fps_last)) { if(ret) { @@ -459,10 +466,12 @@ static bool xdk_d3d_frame(void *data, const void *frame, rarch_convert_char_to_wchar(strw_buffer, buf2, sizeof(strw_buffer)); } else if(buf_fps_last) + { rarch_convert_char_to_wchar(strw_buffer, buf_fps_last, sizeof(strw_buffer)); + } - d3d->debug_font->TextOut(d3d->pFrontBuffer, strw_buffer, (unsigned)-1, 30, 70 ); - d3d->debug_font->TextOut(d3d->pBackBuffer, strw_buffer, (unsigned)-1, 30, 70 ); + d3d->debug_font->TextOut(d3d->pFrontBuffer, strw_buffer, (unsigned)-1, font_x + 30, font_y + 70 ); + d3d->debug_font->TextOut(d3d->pBackBuffer, strw_buffer, (unsigned)-1, font_x + 30, font_y + 70 ); d3d->pFrontBuffer->Release(); d3d->pBackBuffer->Release(); } From 64378ea0725634a81f3d542518d5f41dc80fa48f Mon Sep 17 00:00:00 2001 From: freakdave Date: Thu, 19 Jul 2012 16:53:24 +0200 Subject: [PATCH 02/51] (Xbox 1) Fixed low volume issue --- audio/dsound.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/audio/dsound.c b/audio/dsound.c index c4b5bdae89..d3668cf037 100644 --- a/audio/dsound.c +++ b/audio/dsound.c @@ -21,6 +21,18 @@ // The caller does not have the priority level required for the function to // succeed #define DSERR_PRIOLEVELNEEDED MAKE_DSHRESULT(70) +// Send the audio signal (stereo, without attenuation) to all existing speakers +DSMIXBINVOLUMEPAIR dsmbvp[8] = { + {DSMIXBIN_FRONT_LEFT, DSBVOLUME_MAX}, + {DSMIXBIN_FRONT_RIGHT, DSBVOLUME_MAX}, + {DSMIXBIN_FRONT_CENTER, DSBVOLUME_MAX}, + {DSMIXBIN_FRONT_CENTER, DSBVOLUME_MAX}, + {DSMIXBIN_BACK_LEFT, DSBVOLUME_MAX}, + {DSMIXBIN_BACK_RIGHT, DSBVOLUME_MAX}, + {DSMIXBIN_LOW_FREQUENCY, DSBVOLUME_MAX}, + {DSMIXBIN_LOW_FREQUENCY, DSBVOLUME_MAX}}; + +DSMIXBINS dsmb; #endif #include "../driver.h" @@ -338,6 +350,16 @@ static void *dsound_init(const char *device, unsigned rate, unsigned latency) if (IDirectSound_CreateSoundBuffer(ds->ds, &bufdesc, &ds->dsb, 0) != DS_OK) goto error; + IDirectSoundBuffer_SetVolume(ds->dsb, DSBVOLUME_MAX); + +#ifdef _XBOX + dsmb.dwMixBinCount = 8; + dsmb.lpMixBinVolumePairs = dsmbvp; + + IDirectSoundBuffer_SetHeadroom(ds->dsb, DSBHEADROOM_MIN); + IDirectSoundBuffer_SetMixBins(ds->dsb, &dsmb); +#endif + IDirectSoundBuffer_SetCurrentPosition(ds->dsb, 0); dsound_clear_buffer(ds); From 41de6da14ee18ce5401aacf6cbc9b95238117c6d Mon Sep 17 00:00:00 2001 From: freakdave Date: Sun, 22 Jul 2012 19:54:04 +0200 Subject: [PATCH 03/51] (Xbox 1) Added a simple GUI, right now it browses and lists all files contained in the "roms" folder. The selected rom (its filename) is saved into T:\\tmp.retro. Press start and core.xbe will be launched. If you want to apply changes to the launching code, take a look into MenuMain.cpp. (Xbox 1) Todo: Pass arguments (filename, settings, etc.. ?) into core.xbe or read tmp.retro and get the filename / settings from there --- xbox1/RetroLaunch/Debug.cpp | 83 + xbox1/RetroLaunch/Debug.h | 41 + xbox1/RetroLaunch/Font.cpp | 229 ++ xbox1/RetroLaunch/Font.h | 53 + xbox1/RetroLaunch/Global.h | 53 + xbox1/RetroLaunch/IniFile.cpp | 152 + xbox1/RetroLaunch/IniFile.h | 98 + xbox1/RetroLaunch/Input.cpp | 328 ++ xbox1/RetroLaunch/Input.h | 171 + xbox1/RetroLaunch/IoSupport.cpp | 261 ++ xbox1/RetroLaunch/IoSupport.h | 53 + xbox1/RetroLaunch/Launcher.cpp | 72 + xbox1/RetroLaunch/MenuMain.cpp | 241 ++ xbox1/RetroLaunch/MenuMain.h | 99 + xbox1/RetroLaunch/MenuManager.cpp | 98 + xbox1/RetroLaunch/MenuManager.h | 50 + xbox1/RetroLaunch/RetroLaunch.sln | 33 + xbox1/RetroLaunch/RetroLaunch.vcproj | 447 +++ xbox1/RetroLaunch/Rom.cpp | 76 + xbox1/RetroLaunch/Rom.h | 44 + xbox1/RetroLaunch/RomList.cpp | 309 ++ xbox1/RetroLaunch/RomList.h | 72 + xbox1/RetroLaunch/SimpleIni.h | 3262 +++++++++++++++++ xbox1/RetroLaunch/Surface.cpp | 255 ++ xbox1/RetroLaunch/Surface.h | 90 + xbox1/RetroLaunch/Undocumented.h | 1373 +++++++ xbox1/RetroLaunch/Video.cpp | 138 + xbox1/RetroLaunch/Video.h | 53 + xbox1/RetroLaunch/dist/Media/arial.ttf | Bin 0 -> 65692 bytes xbox1/RetroLaunch/dist/Media/menuMainBG.png | Bin 0 -> 6415 bytes .../dist/Media/menuMainRomSelectPanel.png | Bin 0 -> 3206 bytes xbox1/RetroLaunch/dist/Roms/Add roms here.txt | 0 xbox1/RetroLaunch/retroarch.h | 5 + xbox1/RetroLaunch/titleimage.jpg | Bin 0 -> 8865 bytes 34 files changed, 8239 insertions(+) create mode 100644 xbox1/RetroLaunch/Debug.cpp create mode 100644 xbox1/RetroLaunch/Debug.h create mode 100644 xbox1/RetroLaunch/Font.cpp create mode 100644 xbox1/RetroLaunch/Font.h create mode 100644 xbox1/RetroLaunch/Global.h create mode 100644 xbox1/RetroLaunch/IniFile.cpp create mode 100644 xbox1/RetroLaunch/IniFile.h create mode 100644 xbox1/RetroLaunch/Input.cpp create mode 100644 xbox1/RetroLaunch/Input.h create mode 100644 xbox1/RetroLaunch/IoSupport.cpp create mode 100644 xbox1/RetroLaunch/IoSupport.h create mode 100644 xbox1/RetroLaunch/Launcher.cpp create mode 100644 xbox1/RetroLaunch/MenuMain.cpp create mode 100644 xbox1/RetroLaunch/MenuMain.h create mode 100644 xbox1/RetroLaunch/MenuManager.cpp create mode 100644 xbox1/RetroLaunch/MenuManager.h create mode 100644 xbox1/RetroLaunch/RetroLaunch.sln create mode 100644 xbox1/RetroLaunch/RetroLaunch.vcproj create mode 100644 xbox1/RetroLaunch/Rom.cpp create mode 100644 xbox1/RetroLaunch/Rom.h create mode 100644 xbox1/RetroLaunch/RomList.cpp create mode 100644 xbox1/RetroLaunch/RomList.h create mode 100644 xbox1/RetroLaunch/SimpleIni.h create mode 100644 xbox1/RetroLaunch/Surface.cpp create mode 100644 xbox1/RetroLaunch/Surface.h create mode 100644 xbox1/RetroLaunch/Undocumented.h create mode 100644 xbox1/RetroLaunch/Video.cpp create mode 100644 xbox1/RetroLaunch/Video.h create mode 100644 xbox1/RetroLaunch/dist/Media/arial.ttf create mode 100644 xbox1/RetroLaunch/dist/Media/menuMainBG.png create mode 100644 xbox1/RetroLaunch/dist/Media/menuMainRomSelectPanel.png create mode 100644 xbox1/RetroLaunch/dist/Roms/Add roms here.txt create mode 100644 xbox1/RetroLaunch/retroarch.h create mode 100644 xbox1/RetroLaunch/titleimage.jpg diff --git a/xbox1/RetroLaunch/Debug.cpp b/xbox1/RetroLaunch/Debug.cpp new file mode 100644 index 0000000000..1f94d72466 --- /dev/null +++ b/xbox1/RetroLaunch/Debug.cpp @@ -0,0 +1,83 @@ +/** + * RetroLaunch 2012 + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. This program 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 this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. To contact the + * authors: Surreal64 CE Team (http://www.emuxtras.net) + */ + +#include "Global.h" +#include "Debug.h" + +CDebug g_debug; + +CDebug::CDebug(void) +{ + iLine = 1; + m_bFileOpen = false; +} + +CDebug::~CDebug(void) +{ +} + +void CDebug::Print(char *szMessage, ...) +{ + char szMsg[512]; + va_list vaArgList; + string szDebugFile ("D:\\debug.log");//(FixPath(PathRoot() + "debug.log")); + + va_start(vaArgList, szMessage); + vsprintf(szMsg, szMessage, vaArgList); + va_end(vaArgList); + + OutputDebugStringA(IntToString(iLine).c_str()); + OutputDebugStringA(": "); + OutputDebugStringA(szMsg); + OutputDebugStringA("\n\n"); + +#ifdef WIN32 + cout << IntToString(iLine)<< ": " << szMsg << endl << endl; +#endif + +//#ifdef _LOG + //Open the log file, create one if it does not exist, append the data + if(!m_bFileOpen) + { + fp = fopen(szDebugFile.c_str(), "w+"); + m_bFileOpen = true; + } + else + { + fp = fopen(szDebugFile.c_str(), "a+"); + } + + //print the data to the log file + fprintf(fp, IntToString(iLine).c_str()); + fprintf(fp, ": "); + fprintf(fp, szMsg); + fprintf(fp, "\r\n\r\n"); + + //close the file + fclose(fp); +//#endif //_LOG + + iLine ++; +} + + +string CDebug::IntToString(int value) +{ + stringstream ss; + + ss << value; + + return ss.str(); +} diff --git a/xbox1/RetroLaunch/Debug.h b/xbox1/RetroLaunch/Debug.h new file mode 100644 index 0000000000..5506100f44 --- /dev/null +++ b/xbox1/RetroLaunch/Debug.h @@ -0,0 +1,41 @@ +/** + * RetroLaunch 2012 + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. This program 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 this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. To contact the + * authors: Surreal64 CE Team (http://www.emuxtras.net) + */ + +#ifndef _DEBUG_H__DASH_ +#define _DEBUG_H__DASH_ + +#if _MSC_VER > 1000 +#pragma once +#endif //_MSC_VER > 1000 + +class CDebug +{ +public: + CDebug(); + ~CDebug(); + + void Print(char *szMessage, ...); + string IntToString(int value); + +private: + int iLine; + FILE *fp; + bool m_bFileOpen; + +}; + +extern CDebug g_debug; + +#endif //_DEBUG_H__DASH_ \ No newline at end of file diff --git a/xbox1/RetroLaunch/Font.cpp b/xbox1/RetroLaunch/Font.cpp new file mode 100644 index 0000000000..e217735a8f --- /dev/null +++ b/xbox1/RetroLaunch/Font.cpp @@ -0,0 +1,229 @@ +/** + * RetroLaunch 2012 + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. This program 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 this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. To contact the + * authors: Surreal64 CE Team (http://www.emuxtras.net) + */ + + +#ifdef _XBOX +#include "Font.h" + +#include + +Font g_font; + +Font::Font(void) +{ + m_pFont = NULL; +} + +Font::~Font(void) +{ + if (m_pFont) + m_pFont->Release(); +} + +bool Font::Create() +{ //Hardcoded + return Create("D:\\Media\\arial.ttf"); +} + +bool Font::Create(const string &szTTFFilename) +{ + if (m_pFont) + m_pFont->Release(); + + word *wcPathBuf = StringToWChar(szTTFFilename); + g_hResult = XFONT_OpenTrueTypeFont(wcPathBuf, 256 * 1024, &m_pFont); + + delete [] wcPathBuf; + + if (FAILED(g_hResult)) + return false; + + return true; +} + +void Font::Render(const string &str, int x, int y, dword height, dword style, D3DXCOLOR color, int maxWidth, bool fade, Align alignment) +{ + CSurface texture; + RenderToTexture(texture, str, height, style, color, maxWidth, fade); + + if (alignment != Left) + { + word *wcBuf = StringToWChar(str); + dword dwRequiredWidth; + m_pFont->GetTextExtent(wcBuf, -1, &dwRequiredWidth); + delete [] wcBuf; + + if (alignment == Center) + { + x -= (dwRequiredWidth / 2); + } + else if (alignment == Right) + { + x -= dwRequiredWidth; + } + } + + texture.Render(x, y); +} + +void Font::RenderToTexture(CSurface &texture, const string &str, dword height, dword style, D3DXCOLOR color, int maxWidth, bool fade) +{ + if (m_pFont == NULL) + return; + + m_pFont->SetTextHeight(height); + m_pFont->SetTextStyle(style); + m_pFont->SetTextColor(color); + + dword dwMaxWidth = (maxWidth <= 0) ? 1000 : maxWidth; + + // get the exact width and height required to display the string + dword dwRequiredWidth = GetRequiredWidth(str, height, style); + dword dwRequiredHeight = GetRequiredHeight(str, height, style);; + + // calculate the texture width and height needed to display the font + dword dwTextureWidth = dwRequiredWidth * 2; + dword dwTextureHeight = dwRequiredHeight * 2; + { + // because the textures are swizzled we make sure + // the dimensions are a power of two + for(dword wmask = 1; dwTextureWidth &(dwTextureWidth - 1); wmask = (wmask << 1 ) + 1) + { + dwTextureWidth = (dwTextureWidth + wmask) & ~wmask; + } + for(dword hmask = 1; dwTextureHeight &(dwTextureHeight - 1); hmask = (hmask << 1) + 1) + { + dwTextureHeight = ( dwTextureHeight + hmask ) & ~hmask; + } + + // also enforce a minimum pitch of 64 bytes + dwTextureWidth = max(64 / XGBytesPerPixelFromFormat(D3DFMT_A8R8G8B8), dwTextureWidth); + } + + // create an temporary image surface to render to + D3DSurface *pTempSurface; + g_video.m_pD3DDevice->CreateImageSurface(dwTextureWidth, dwTextureHeight, D3DFMT_LIN_A8R8G8B8, &pTempSurface); + + // clear the temporary surface + { + D3DLOCKED_RECT tmpLr; + pTempSurface->LockRect(&tmpLr, NULL, 0); + memset(tmpLr.pBits, 0, dwTextureWidth * dwTextureHeight * XGBytesPerPixelFromFormat(D3DFMT_A8R8G8B8)); + pTempSurface->UnlockRect(); + } + + // render the text to the temporary surface + word *wcBuf = StringToWChar(str); + m_pFont->TextOut(pTempSurface, wcBuf, -1, 0, 0); + delete [] wcBuf; + + // create the texture that will be drawn to the screen + texture.Destroy(); + texture.Create(dwTextureWidth, dwTextureHeight); + + // copy from the temporary surface to the final texture + { + D3DLOCKED_RECT tmpLr; + D3DLOCKED_RECT txtLr; + + pTempSurface->LockRect(&tmpLr, NULL, 0); + texture.GetTexture()->LockRect(0, &txtLr, NULL, 0); + + if (fade) + { + // draw the last 35 pixels of the string fading out to max width or texture width + dword dwMinFadeDistance = min(static_cast(dwTextureWidth * 0.35), 35); + dword dwFadeStart = min(dwTextureWidth, dwMaxWidth - dwMinFadeDistance); + dword dwFadeEnd = min(dwTextureWidth, dwMaxWidth); + dword dwFadeDistance = dwFadeEnd - dwFadeStart; + + for (dword h = 0; h < dwTextureHeight; h++) + { + for (dword w = 0; w < dwFadeDistance; w++) + { + dword *pColor = reinterpret_cast(tmpLr.pBits); + dword offset = (h * dwTextureWidth) + (dwFadeStart + w); + + D3DXCOLOR color = D3DXCOLOR(pColor[offset]); + color.a = color.a * (1.0f - static_cast(w) / static_cast(dwFadeDistance)); + pColor[offset] = color; + } + } + } + + // dont draw anything > than max width + for (dword h = 0; h < dwTextureHeight; h++) + { + for (dword w = min(dwTextureWidth, dwMaxWidth); w < dwTextureWidth; w++) + { + dword *pColor = reinterpret_cast(tmpLr.pBits); + dword offset = (h * dwTextureWidth) + w; + + D3DXCOLOR color = D3DXCOLOR(pColor[offset]); + color.a = 0.0; + pColor[offset] = color; + } + } + + // copy and swizzle the linear surface to the swizzled texture + XGSwizzleRect(tmpLr.pBits, tmpLr.Pitch, NULL, txtLr.pBits, dwTextureWidth, dwTextureHeight, NULL, 4); + + texture.GetTexture()->UnlockRect(0); + pTempSurface->UnlockRect(); + } + + pTempSurface->Release(); +} + +int Font::GetRequiredWidth(const string &str, dword height, dword style) +{ + word *wcBuf = StringToWChar(str); + dword reqWidth; + + m_pFont->SetTextHeight(height); + m_pFont->SetTextStyle(style); + m_pFont->GetTextExtent(wcBuf, -1, &reqWidth); + + delete [] wcBuf; + + return reqWidth; +} + +int Font::GetRequiredHeight(const string &str, dword height, dword style) +{ + word *wcBuf = StringToWChar(str); + dword reqHeight; + + m_pFont->SetTextHeight(height); + m_pFont->SetTextStyle(style); + m_pFont->GetFontMetrics(&reqHeight, NULL); + + delete [] wcBuf; + + return reqHeight; +} + + +word *Font::StringToWChar(const string &str) +{ + word *retVal = new word[(str.length() + 1) * 2]; + memset(retVal, 0, (str.length() + 1) * 2 * sizeof(word)); + + if (str.length() > 0) + mbstowcs(retVal, str.c_str(), str.length()); + + return retVal; +} +#endif \ No newline at end of file diff --git a/xbox1/RetroLaunch/Font.h b/xbox1/RetroLaunch/Font.h new file mode 100644 index 0000000000..3126ee2c9d --- /dev/null +++ b/xbox1/RetroLaunch/Font.h @@ -0,0 +1,53 @@ +/** + * RetroLaunch 2012 + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. This program 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 this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. To contact the + * authors: Surreal64 CE Team (http://www.emuxtras.net) + */ + +#pragma once +#ifdef _XBOX +#include "Global.h" +#include "Surface.h" + +#define XFONT_TRUETYPE // use true type fonts +#include + +enum Align +{ + Left, + Center, + Right +}; + +class Font +{ +public: + Font(void); + ~Font(void); + + bool Create(); + bool Create(const string &szTTFFilename); + + void Render(const string &str, int x, int y, dword height, dword style = XFONT_NORMAL, D3DXCOLOR color = D3DCOLOR_XRGB(0, 0, 0), int dwMaxWidth = -1, bool fade = false, Align alignment = Left); + void RenderToTexture(CSurface &texture, const string &str, dword height, dword style = XFONT_NORMAL, D3DXCOLOR color = D3DCOLOR_XRGB(0, 0, 0), int maxWidth = -1, bool fade = false); + + int GetRequiredWidth(const string &str, dword height, dword style); + int GetRequiredHeight(const string &str, dword height, dword style); + + word *StringToWChar(const string &str); + +private: + XFONT *m_pFont; +}; + +extern Font g_font; +#endif \ No newline at end of file diff --git a/xbox1/RetroLaunch/Global.h b/xbox1/RetroLaunch/Global.h new file mode 100644 index 0000000000..f84ba2529f --- /dev/null +++ b/xbox1/RetroLaunch/Global.h @@ -0,0 +1,53 @@ +/** + * RetroLaunch 2012 + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. This program 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 this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. To contact the + * authors: Surreal64 CE Team (http://www.emuxtras.net) + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef _XBOX + #include + #include +#else + #pragma comment(lib,"d3d8.lib") + #pragma comment(lib,"d3dx8.lib") + #pragma comment(lib,"DxErr8.lib") + #define WIN32_LEAN_AND_MEAN + #include + #include + #include + #include +#endif + + +using namespace std; + +#define XBUILD "Launcher CE" + +typedef unsigned __int8 byte; +typedef unsigned __int16 word; +typedef unsigned __int32 dword; +typedef unsigned __int64 qword; + + diff --git a/xbox1/RetroLaunch/IniFile.cpp b/xbox1/RetroLaunch/IniFile.cpp new file mode 100644 index 0000000000..cfa7e04bbc --- /dev/null +++ b/xbox1/RetroLaunch/IniFile.cpp @@ -0,0 +1,152 @@ +/** + * RetroLaunch 2012 + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. This program 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 this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. To contact the + * authors: Surreal64 CE Team (http://www.emuxtras.net) + */ + +#include "SimpleIni.h" +#include "IniFile.h" + + +IniFile g_iniFile; + +//FIXME: SCREEN XPOS, YPOS, XSCALE, YSCALE should be floats! +//FIXME: Path for WIN32 + +IniFile::IniFile(void) +{ +} + +IniFile::~IniFile(void) +{ +} + +bool IniFile::Save(const string &szIniFileName) +{ + CSimpleIniA ini; + SI_Error rc; + ini.SetUnicode(true); + ini.SetMultiKey(true); + ini.SetMultiLine(true); + + //GENERAL SETTINGS + ini.SetBoolValue("GENERAL SETTINGS", "SHOW DEBUG INFO", m_currentIniEntry.bShowDebugInfo); + + //VIDEO SETTINGS + ini.SetBoolValue("VIDEO SETTINGS", "AUTOMATIC FRAME SKIP", m_currentIniEntry.bAutomaticFrameSkip); + + rc = ini.SaveFile(szIniFileName.c_str()); + + OutputDebugStringA(szIniFileName.c_str()); + + if (rc < 0) + { + OutputDebugStringA(" failed to save!\n"); + return false; + } + + OutputDebugStringA(" saved successfully!\n"); + return true; +} + +bool IniFile::Load(const string &szIniFileName) +{ + CSimpleIniA ini; + SI_Error rc; + ini.SetUnicode(true); + ini.SetMultiKey(true); + ini.SetMultiLine(true); + + rc = ini.LoadFile(szIniFileName.c_str()); + + if (rc < 0) + { + OutputDebugString("Failed to load "); + OutputDebugString(szIniFileName.c_str()); + OutputDebugString("\n"); + return false; + } + + OutputDebugStringA("Successfully loaded "); + OutputDebugString(szIniFileName.c_str()); + OutputDebugString("\n"); + + //GENERAL SETTINGS + m_currentIniEntry.bShowDebugInfo = ini.GetBoolValue("GENERAL SETTINGS", "SHOW DEBUG INFO", NULL ); + + //VIDEO SETTINGS + m_currentIniEntry.bAutomaticFrameSkip = ini.GetBoolValue("VIDEO SETTINGS", "AUTOMATIC FRAME SKIP", NULL ); + + return true; +} + +bool IniFile::CreateAndSaveDefaultIniEntry() +{ + //GENERAL SETTINGS + m_defaultIniEntry.bShowDebugInfo = false; + + //VIDEO SETTINGS + m_defaultIniEntry.bAutomaticFrameSkip = true; + + // our current ini is now the default ini + m_currentIniEntry = m_defaultIniEntry; + + // save the default ini + // FIXME! -> CD/DVD -> utility drive X: + Save("D:\\retrolaunch.ini"); + + return true; +} + + +bool IniFile::CheckForIniEntry() +{ + // try to load our ini file + if(!Load("D:\\retrolaunch.ini")) + { + // create a new one, if it doesn't exist + CreateAndSaveDefaultIniEntry(); + } + + return true; +} + + +bool IniFile::SaveTempRomFileName(const string &szFileName) +{ + CSimpleIniA ini; + SI_Error rc; + ini.SetUnicode(true); + ini.SetMultiKey(true); + ini.SetMultiLine(true); + + ini.SetValue("LAUNCHER", "ROM", szFileName.c_str()); + + DeleteFile("T:\\tmp.retro"); + rc = ini.SaveFile("T:\\tmp.retro"); + + OutputDebugStringA("T:\\tmp.retro"); + + if (rc < 0) + { + OutputDebugStringA(" failed to save!\n"); + return false; + } + + OutputDebugStringA(" saved successfully!\n"); + return true; + +} + + + + diff --git a/xbox1/RetroLaunch/IniFile.h b/xbox1/RetroLaunch/IniFile.h new file mode 100644 index 0000000000..dcc28505e7 --- /dev/null +++ b/xbox1/RetroLaunch/IniFile.h @@ -0,0 +1,98 @@ +/** + * RetroLaunch 2012 + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. This program 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 this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. To contact the + * authors: Surreal64 CE Team (http://www.emuxtras.net) + */ + +#pragma once +#include "Global.h" + +struct IniFileEntry +{ + //debug output + bool bShowDebugInfo; + + //automatic frame skip method + bool bAutomaticFrameSkip; + + //manual frame skip method (throttlespeed) + bool bManualFrameSkip; + + //number of frames to skip + dword dwNumFrameSkips; + + //sync audio to video + bool bSyncAudioToVideo; + + //vertical synchronization + bool bVSync; + + //flicker filter + dword dwFlickerFilter; + + //soft display filter + bool bSoftDisplayFilter; + + //texture filter + DWORD dwTextureFilter; + + //screen xpos + dword dwXPOS; + //screen ypos + dword dwYPOS; + //screen xscale + dword dwXWIDTH; + //screen yscale + dword dwYHEIGHT; + + //hide normal scroll 0 + bool bHideNBG0; + //hide normal scroll 1 + bool bHideNBG1; + //hide normal scroll 2 + bool bHideNBG2; + //hide normal scroll 3 + bool bHideNBG3; + //hide rotation scroll 0 + bool bHideRBG0; + //hide VDP1 + bool bHideVDP1; +}; + + +class IniFile +{ +public: + IniFile(); + ~IniFile(); + + bool Save(const string &szIniFileName); + bool SaveTempRomFileName(const string &szFileName); + bool Load(const string &szIniFileName); + bool CreateAndSaveDefaultIniEntry(); + bool CheckForIniEntry(); + + IniFileEntry m_currentIniEntry; + +private: + IniFileEntry m_defaultIniEntry; + + string szRomFileName; + +}; + +extern IniFile g_iniFile; + + + + + diff --git a/xbox1/RetroLaunch/Input.cpp b/xbox1/RetroLaunch/Input.cpp new file mode 100644 index 0000000000..fc79b5357c --- /dev/null +++ b/xbox1/RetroLaunch/Input.cpp @@ -0,0 +1,328 @@ +/** + * RetroLaunch 2012 + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. This program 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 this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. To contact the + * authors: Surreal64 CE Team (http://www.emuxtras.net) + */ + +#ifdef _XBOX +#include "Input.h" + +Input g_input; + +Input::Input(void) +{ + m_pollingParameters.fAutoPoll = TRUE; + m_pollingParameters.fInterruptOut = TRUE; + m_pollingParameters.bInputInterval = 8; + m_pollingParameters.bOutputInterval = 8; + m_lastTick = GetTickCount(); + m_buttonDelay = XBINPUT_PRESS_BUTTON_DELAY; + m_triggerDelay = XBINPUT_PRESS_TRIGGER_DELAY; + m_buttonPressed = false; +} + +Input::~Input(void) +{ +} + +bool Input::Create() +{ + XInitDevices(0, NULL); + + // get a mask of all currently available devices + dword dwDeviceMask = XGetDevices(XDEVICE_TYPE_GAMEPAD); + + // open the devices + for(dword i = 0; i < XGetPortCount(); i++) + { + ZeroMemory(&m_inputStates[i], sizeof(XINPUT_STATE)); + ZeroMemory(&m_gamepads[i], sizeof(XBGAMEPAD)); + + if(dwDeviceMask & (1 << i)) + { + // get a handle to the device + m_gamepads[i].hDevice = XInputOpen(XDEVICE_TYPE_GAMEPAD, i, + XDEVICE_NO_SLOT, &m_pollingParameters); + + // store capabilities of the device + XInputGetCapabilities(m_gamepads[i].hDevice, &m_gamepads[i].caps); + + // initialize last pressed buttons + XInputGetState(m_gamepads[i].hDevice, &m_inputStates[i]); + + m_gamepads[i].wLastButtons = m_inputStates[i].Gamepad.wButtons; + + for(dword b = 0; b < 8; b++) + { + m_gamepads[i].bLastAnalogButtons[b] = + // Turn the 8-bit polled value into a boolean value + (m_inputStates[i].Gamepad.bAnalogButtons[b] > XINPUT_GAMEPAD_MAX_CROSSTALK); + } + } + } + + return true; +} + +void Input::RefreshDevices() +{ + dword dwInsertions, dwRemovals; + + XGetDeviceChanges(XDEVICE_TYPE_GAMEPAD, reinterpret_cast(&dwInsertions), reinterpret_cast(&dwRemovals)); + + // loop through all gamepads + for(dword i = 0; i < XGetPortCount(); i++) + { + // handle removed devices + m_gamepads[i].bRemoved = (dwRemovals & (1 << i)) ? true : false; + + if(m_gamepads[i].bRemoved) + { + // if the controller was removed after XGetDeviceChanges but before + // XInputOpen, the device handle will be NULL + if(m_gamepads[i].hDevice) + XInputClose(m_gamepads[i].hDevice); + + m_gamepads[i].hDevice = NULL; + m_gamepads[i].Feedback.Rumble.wLeftMotorSpeed = 0; + m_gamepads[i].Feedback.Rumble.wRightMotorSpeed = 0; + } + + // handle inserted devices + m_gamepads[i].bInserted = (dwInsertions & (1 << i)) ? true : false; + + if(m_gamepads[i].bInserted) + { + m_gamepads[i].hDevice = XInputOpen(XDEVICE_TYPE_GAMEPAD, i, + XDEVICE_NO_SLOT, &m_pollingParameters ); + + // if the controller is removed after XGetDeviceChanges but before + // XInputOpen, the device handle will be NULL + if(m_gamepads[i].hDevice) + { + XInputGetCapabilities(m_gamepads[i].hDevice, &m_gamepads[i].caps); + + // initialize last pressed buttons + XInputGetState(m_gamepads[i].hDevice, &m_inputStates[i]); + + m_gamepads[i].wLastButtons = m_inputStates[i].Gamepad.wButtons; + + for(dword b = 0; b < 8; b++) + { + m_gamepads[i].bLastAnalogButtons[b] = + // Turn the 8-bit polled value into a boolean value + (m_inputStates[i].Gamepad.bAnalogButtons[b] > XINPUT_GAMEPAD_MAX_CROSSTALK); + } + } + } + } +} + +void Input::GetInput() +{ + RefreshDevices(); + + if (m_buttonPressed) + { + m_lastTick = GetTickCount(); + m_buttonPressed = false; + } + + // loop through all gamepads + for(dword i = 0; i < XGetPortCount(); i++) + { + // if we have a valid device, poll it's state and track button changes + if(m_gamepads[i].hDevice) + { + // read the input state + XInputGetState(m_gamepads[i].hDevice, &m_inputStates[i]); + + // copy gamepad to local structure + memcpy(&m_gamepads[i], &m_inputStates[i].Gamepad, sizeof(XINPUT_GAMEPAD)); + + // put xbox device input for the gamepad into our custom format + float fX1 = (m_gamepads[i].sThumbLX + 0.5f) / 32767.5f; + m_gamepads[i].fX1 = (fX1 >= 0.0f ? 1.0f : -1.0f) * + max(0.0f, (fabsf(fX1) - XBINPUT_DEADZONE) / (1.0f - XBINPUT_DEADZONE)); + + float fY1 = (m_gamepads[i].sThumbLY + 0.5f) / 32767.5f; + m_gamepads[i].fY1 = (fY1 >= 0.0f ? 1.0f : -1.0f) * + max(0.0f, (fabsf(fY1) - XBINPUT_DEADZONE) / (1.0f - XBINPUT_DEADZONE)); + + float fX2 = (m_gamepads[i].sThumbRX + 0.5f) / 32767.5f; + m_gamepads[i].fX2 = (fX2 >= 0.0f ? 1.0f : -1.0f) * + max(0.0f, (fabsf(fX2) - XBINPUT_DEADZONE) / (1.0f - XBINPUT_DEADZONE)); + + float fY2 = (m_gamepads[i].sThumbRY + 0.5f) / 32767.5f; + m_gamepads[i].fY2 = (fY2 >= 0.0f ? 1.0f : -1.0f) * + max(0.0f, (fabsf(fY2) - XBINPUT_DEADZONE) / (1.0f - XBINPUT_DEADZONE)); + + // get the boolean buttons that have been pressed since the last + // call. each button is represented by one bit. + m_gamepads[i].wPressedButtons = (m_gamepads[i].wLastButtons ^ m_gamepads[i].wButtons) & m_gamepads[i].wButtons; + m_gamepads[i].wLastButtons = m_gamepads[i].wButtons; + + // get the analog buttons that have been pressed or released since + // the last call. + for(dword b = 0; b < 8; b++) + { + // turn the 8-bit polled value into a boolean value + bool bPressed = (m_gamepads[i].bAnalogButtons[b] > XINPUT_GAMEPAD_MAX_CROSSTALK); + + if(bPressed) + m_gamepads[i].bPressedAnalogButtons[b] = !m_gamepads[i].bLastAnalogButtons[b]; + else + m_gamepads[i].bPressedAnalogButtons[b] = false; + + // store the current state for the next time + m_gamepads[i].bLastAnalogButtons[b] = bPressed; + } + } + } +} + +bool Input::IsButtonPressed(XboxButton button) +{ + if (m_lastTick + m_buttonDelay > GetTickCount()) + return false; + + bool buttonDown = false; + + switch (button) + { + case XboxLeftThumbLeft: + buttonDown = (m_gamepads[0].fX1 < -0.5); + break; + case XboxLeftThumbRight: + buttonDown = (m_gamepads[0].fX1 > 0.5); + break; + case XboxLeftThumbUp: + buttonDown = (m_gamepads[0].fY1 > 0.5); + break; + case XboxLeftThumbDown: + buttonDown = (m_gamepads[0].fY1 < -0.5); + break; + case XboxRightThumbLeft: + buttonDown = (m_gamepads[0].fX2 < -0.5); + break; + case XboxRightThumbRight: + buttonDown = (m_gamepads[0].fX2 > 0.5); + break; + case XboxRightThumbUp: + buttonDown = (m_gamepads[0].fY2 > 0.5); + break; + case XboxRightThumbDown: + buttonDown = (m_gamepads[0].fY2 < -0.5); + break; + case XboxDPadLeft: + buttonDown = ((m_gamepads[0].wButtons & XINPUT_GAMEPAD_DPAD_LEFT) != 0); + break; + case XboxDPadRight: + buttonDown = ((m_gamepads[0].wButtons & XINPUT_GAMEPAD_DPAD_RIGHT) != 0); + break; + case XboxDPadUp: + buttonDown = ((m_gamepads[0].wButtons & XINPUT_GAMEPAD_DPAD_UP) != 0); + break; + case XboxDPadDown: + buttonDown = ((m_gamepads[0].wButtons & XINPUT_GAMEPAD_DPAD_DOWN) != 0); + break; + case XboxStart: + buttonDown = ((m_gamepads[0].wButtons & XINPUT_GAMEPAD_START) != 0); + break; + case XboxBack: + buttonDown = ((m_gamepads[0].wButtons & XINPUT_GAMEPAD_BACK) != 0); + break; + case XboxA: + buttonDown = (m_gamepads[0].bAnalogButtons[XINPUT_GAMEPAD_A] > 30); + break; + case XboxB: + buttonDown = (m_gamepads[0].bAnalogButtons[XINPUT_GAMEPAD_B] > 30); + break; + case XboxX: + buttonDown = (m_gamepads[0].bAnalogButtons[XINPUT_GAMEPAD_X] > 30); + break; + case XboxY: + buttonDown = (m_gamepads[0].bAnalogButtons[XINPUT_GAMEPAD_Y] > 30); + break; + case XboxWhite: + buttonDown = (m_gamepads[0].bAnalogButtons[XINPUT_GAMEPAD_WHITE] > 30); + break; + case XboxBlack: + buttonDown = (m_gamepads[0].bAnalogButtons[XINPUT_GAMEPAD_BLACK] > 30); + break; + case XboxLeftThumbButton: + buttonDown = ((m_gamepads[0].wButtons & XINPUT_GAMEPAD_LEFT_THUMB) != 0); + break; + case XboxRightThumbButton: + buttonDown = ((m_gamepads[0].wButtons & XINPUT_GAMEPAD_RIGHT_THUMB) != 0); + break; + default: + return false; + } + + if (buttonDown) + { + m_buttonPressed = true; + return true; + } + + return false; +} + +byte Input::IsLTriggerPressed() +{ + if (m_lastTick + m_triggerDelay > GetTickCount()) + return 0; + + if (m_gamepads[0].bAnalogButtons[XINPUT_GAMEPAD_LEFT_TRIGGER] < 30) + return 0; + else + { + m_buttonPressed = true; + return m_gamepads[0].bAnalogButtons[XINPUT_GAMEPAD_LEFT_TRIGGER]; + } +} + +byte Input::IsRTriggerPressed() +{ + if (m_lastTick + m_triggerDelay > GetTickCount()) + return 0; + + if (m_gamepads[0].bAnalogButtons[XINPUT_GAMEPAD_RIGHT_TRIGGER] < 30) + return 0; + else + { + m_buttonPressed = true; + return m_gamepads[0].bAnalogButtons[XINPUT_GAMEPAD_RIGHT_TRIGGER]; + } +} + +DWORD Input::GetButtonDelay() +{ + return m_buttonDelay; +} + +void Input::SetButtonDelay(DWORD milliseconds) +{ + m_buttonDelay = milliseconds; +} + +DWORD Input::GetTriggerDelay() +{ + return m_triggerDelay; +} + +void Input::SetTriggerDelay(DWORD milliseconds) +{ + m_triggerDelay = milliseconds; +} +#endif \ No newline at end of file diff --git a/xbox1/RetroLaunch/Input.h b/xbox1/RetroLaunch/Input.h new file mode 100644 index 0000000000..c20ae81868 --- /dev/null +++ b/xbox1/RetroLaunch/Input.h @@ -0,0 +1,171 @@ +/** + * RetroLaunch 2012 + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. This program 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 this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. To contact the + * authors: Surreal64 CE Team (http://www.emuxtras.net) + */ + +#pragma once +#ifdef _XBOX +#include "Global.h" + +#define XBINPUT_DEADZONE 0.24f +#define XBINPUT_PRESS_BUTTON_DELAY 200 +#define XBINPUT_PRESS_TRIGGER_DELAY 100 + +struct XBGAMEPAD : public XINPUT_GAMEPAD +{ + // thumb stick values converted to range [-1,+1] + float fX1; + float fY1; + float fX2; + float fY2; + + // state of buttons tracked since last poll + word wLastButtons; + bool bLastAnalogButtons[8]; + word wPressedButtons; + bool bPressedAnalogButtons[8]; + + // rumble properties + XINPUT_RUMBLE Rumble; + XINPUT_FEEDBACK Feedback; + + // device properties + XINPUT_CAPABILITIES caps; + HANDLE hDevice; + + // flags for whether game pad was just inserted or removed + bool bInserted; + bool bRemoved; +}; + +#define XBOX_BUTTON_COUNT 23 + +enum XboxButton +{ + XboxLeftThumbLeft, + XboxLeftThumbRight, + XboxLeftThumbUp, + XboxLeftThumbDown, + + XboxRightThumbLeft, + XboxRightThumbRight, + XboxRightThumbUp, + XboxRightThumbDown, + + XboxDPadLeft, + XboxDPadRight, + XboxDPadUp, + XboxDPadDown, + + XboxStart, + XboxBack, + + XboxLeftThumbButton, + XboxRightThumbButton, + + XboxA, + XboxB, + XboxX, + XboxY, + + XboxBlack, + XboxWhite, + + XboxLeftTrigger, + XboxRightTrigger, +}; + +enum N64Button +{ + N64ThumbLeft, + N64ThumbRight, + N64ThumbUp, + N64ThumbDown, + + N64DPadLeft, + N64DPadRight, + N64DPadUp, + N64DPadDown, + + N64CButtonLeft, + N64CButtonRight, + N64CButtonUp, + N64CButtonDown, + + N64Start, + + N64A, + N64B, + + N64ZTrigger, + N64LeftTrigger, + N64RightTrigger +}; + + +enum SATURNButton +{ + SATURNDPadLeft, + SATURNDPadRight, + SATURNDPadUp, + SATURNDPadDown, + + SATURNA, + SATURNB, + SATURNX, + SATURNY, + SATURNC, + SATURNZ, + + SATURNStart, + + SATURNRightTrigger, + SATURNLeftTrigger +}; + +class Input +{ +public: + Input(void); + ~Input(void); + + bool Create(); + void GetInput(); + + bool IsButtonPressed(XboxButton button); + + byte IsLTriggerPressed(); + byte IsRTriggerPressed(); + + DWORD GetButtonDelay(); + void SetButtonDelay(DWORD milliseconds); + + DWORD GetTriggerDelay(); + void SetTriggerDelay(DWORD milliseconds); + +private: + void RefreshDevices(); + +private: + XINPUT_POLLING_PARAMETERS m_pollingParameters; + XINPUT_STATE m_inputStates[4]; + XBGAMEPAD m_gamepads[4]; + + bool m_buttonPressed; + DWORD m_buttonDelay; + DWORD m_triggerDelay; + DWORD m_lastTick; +}; + +extern Input g_input; +#endif \ No newline at end of file diff --git a/xbox1/RetroLaunch/IoSupport.cpp b/xbox1/RetroLaunch/IoSupport.cpp new file mode 100644 index 0000000000..0885ed76c2 --- /dev/null +++ b/xbox1/RetroLaunch/IoSupport.cpp @@ -0,0 +1,261 @@ +// IoSupport.cpp: implementation of the CIoSupport class. +// +////////////////////////////////////////////////////////////////////// +#ifdef _XBOX +#include "iosupport.h" +#include "undocumented.h" + +#include + +#define CTLCODE(DeviceType, Function, Method, Access) ( ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) ) +#define FSCTL_DISMOUNT_VOLUME CTLCODE( FILE_DEVICE_FILE_SYSTEM, 0x08, METHOD_BUFFERED, FILE_ANY_ACCESS ) + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +CIoSupport g_IOSupport; + +CIoSupport::CIoSupport() +{ + m_dwLastTrayState = 0; +} + +CIoSupport::~CIoSupport() +{ + +} + +// szDrive e.g. "D:" +// szDevice e.g. "Cdrom0" or "Harddisk0\Partition6" + +HRESULT CIoSupport::Mount(CHAR* szDrive, CHAR* szDevice) +{ + CHAR szSourceDevice[48]; + CHAR szDestinationDrive[16]; + + sprintf(szSourceDevice, "\\Device\\%s", szDevice); + sprintf(szDestinationDrive, "\\??\\%s", szDrive); + + STRING DeviceName = + { + strlen(szSourceDevice), + strlen(szSourceDevice) + 1, + szSourceDevice + }; + + STRING LinkName = + { + strlen(szDestinationDrive), + strlen(szDestinationDrive) + 1, + szDestinationDrive + }; + + IoCreateSymbolicLink(&LinkName, &DeviceName); + + return S_OK; +} + + + +// szDrive e.g. "D:" + +HRESULT CIoSupport::Unmount(CHAR* szDrive) +{ + char szDestinationDrive[16]; + sprintf(szDestinationDrive, "\\??\\%s", szDrive); + + STRING LinkName = + { + strlen(szDestinationDrive), + strlen(szDestinationDrive) + 1, + szDestinationDrive + }; + + IoDeleteSymbolicLink(&LinkName); + + return S_OK; +} + + + + + +HRESULT CIoSupport::Remount(CHAR* szDrive, CHAR* szDevice) +{ + CHAR szSourceDevice[48]; + sprintf(szSourceDevice, "\\Device\\%s", szDevice); + + Unmount(szDrive); + + ANSI_STRING filename; + OBJECT_ATTRIBUTES attributes; + IO_STATUS_BLOCK status; + HANDLE hDevice; + NTSTATUS error; + DWORD dummy; + + RtlInitAnsiString(&filename, szSourceDevice); + InitializeObjectAttributes(&attributes, &filename, OBJ_CASE_INSENSITIVE, NULL); + + if (!NT_SUCCESS(error = NtCreateFile(&hDevice, GENERIC_READ | + SYNCHRONIZE | FILE_READ_ATTRIBUTES, &attributes, &status, NULL, 0, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OPEN, + FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT))) + { + return E_FAIL; + } + + if (!DeviceIoControl(hDevice, FSCTL_DISMOUNT_VOLUME, NULL, 0, NULL, 0, &dummy, NULL)) + { + CloseHandle(hDevice); + return E_FAIL; + } + + CloseHandle(hDevice); + Mount(szDrive, szDevice); + + return S_OK; +} + +HRESULT CIoSupport::Remap(CHAR* szMapping) +{ + char szMap[32]; + strcpy(szMap, szMapping ); + + char* pComma = strstr(szMap, ","); + if (pComma) + { + *pComma = 0; + + // map device to drive letter + Unmount(szMap); + Mount(szMap, &pComma[1]); + return S_OK; + } + + return E_FAIL; +} + + +HRESULT CIoSupport::EjectTray() +{ + HalWriteSMBusValue(0x20, 0x0C, FALSE, 0); // eject tray + return S_OK; +} + +HRESULT CIoSupport::CloseTray() +{ + HalWriteSMBusValue(0x20, 0x0C, FALSE, 1); // close tray + return S_OK; +} + +DWORD CIoSupport::GetTrayState() +{ + HalReadSMCTrayState(&m_dwTrayState, &m_dwTrayCount); + + if(m_dwTrayState == TRAY_CLOSED_MEDIA_PRESENT) + { + if (m_dwLastTrayState != TRAY_CLOSED_MEDIA_PRESENT) + { + m_dwLastTrayState = m_dwTrayState; + return DRIVE_CLOSED_MEDIA_PRESENT; + } + else + { + return DRIVE_READY; + } + } + else if(m_dwTrayState == TRAY_CLOSED_NO_MEDIA) + { + m_dwLastTrayState = m_dwTrayState; + return DRIVE_CLOSED_NO_MEDIA; + } + else if(m_dwTrayState == TRAY_OPEN) + { + m_dwLastTrayState = m_dwTrayState; + return DRIVE_OPEN; + } + else + { + m_dwLastTrayState = m_dwTrayState; + } + + return DRIVE_NOT_READY; +} + +HRESULT CIoSupport::Shutdown() +{ + HalInitiateShutdown(); + return S_OK; +} + +HANDLE CIoSupport::CreateFile() +{ + ANSI_STRING filename; + OBJECT_ATTRIBUTES attributes; + IO_STATUS_BLOCK status; + HANDLE hDevice; + NTSTATUS error; + + RtlInitAnsiString(&filename, "\\Device\\Cdrom0"); + InitializeObjectAttributes(&attributes, &filename, OBJ_CASE_INSENSITIVE, NULL); + + if (!NT_SUCCESS(error = NtCreateFile(&hDevice, GENERIC_READ | + SYNCHRONIZE | FILE_READ_ATTRIBUTES, &attributes, &status, NULL, 0, + FILE_SHARE_READ, FILE_OPEN, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT))) + { + return NULL; + } + + return hDevice; +} + +BOOL CIoSupport::GetFirstFile(CHAR* szFilename) +{ + ANSI_STRING filename; + OBJECT_ATTRIBUTES attributes; + IO_STATUS_BLOCK status; + HANDLE hDevice; + NTSTATUS error; + + RtlInitAnsiString(&filename, "\\Device\\Cdrom0"); + InitializeObjectAttributes(&attributes, &filename, OBJ_CASE_INSENSITIVE, NULL); + + if (!NT_SUCCESS(error = NtCreateFile(&hDevice, GENERIC_READ | + SYNCHRONIZE | FILE_READ_ATTRIBUTES, &attributes, &status, NULL, 0, + FILE_SHARE_READ, FILE_OPEN, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT))) + { + OutputDebugString("Unable to open Cdrom0.\n"); + return FALSE; + } + + + CHAR* szBuffer = new CHAR[2048]; + DWORD dwRead = 0; + + SetFilePointer(hDevice, 19 * 2048, NULL, FILE_BEGIN); + if (!ReadFile(hDevice, szBuffer, 2048, &dwRead, NULL)) + { + OutputDebugString("Unable to read ISO9660 root directory.\n"); + CloseHandle(hDevice); + return FALSE; + } + + CloseHandle(hDevice); + szBuffer[2047] = 0; + + int offset = 0; + while (szBuffer[offset] == 0x22) offset += 0x22; + offset += 33; // jump to start of filename + + strcpy(szFilename, "#"); + strcat(szFilename, &szBuffer[offset]); + + if (szBuffer) + delete [] szBuffer; + + return TRUE; +} + +#endif \ No newline at end of file diff --git a/xbox1/RetroLaunch/IoSupport.h b/xbox1/RetroLaunch/IoSupport.h new file mode 100644 index 0000000000..2319c1b3ed --- /dev/null +++ b/xbox1/RetroLaunch/IoSupport.h @@ -0,0 +1,53 @@ +// IoSupport.h: interface for the CIoSupport class. +// +////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_IOSUPPORT_H__F084A488_BD6E_49D5_8CD3_0BE62149DB40__INCLUDED_) +#define AFX_IOSUPPORT_H__F084A488_BD6E_49D5_8CD3_0BE62149DB40__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 +#ifdef _XBOX +#include +#include "global.h" + +#define TRAY_OPEN 16 +#define TRAY_CLOSED_NO_MEDIA 64 +#define TRAY_CLOSED_MEDIA_PRESENT 96 + +#define DRIVE_OPEN 0 // Open... +#define DRIVE_NOT_READY 1 // Opening.. Closing... +#define DRIVE_READY 2 +#define DRIVE_CLOSED_NO_MEDIA 3 // CLOSED...but no media in drive +#define DRIVE_CLOSED_MEDIA_PRESENT 4 // Will be send once when the drive just have closed + +class CIoSupport +{ +public: + CIoSupport(); + virtual ~CIoSupport(); + + HRESULT Mount(CHAR* szDrive, CHAR* szDevice); + HRESULT Unmount(CHAR* szDrive); + + HRESULT Remount(CHAR* szDrive, CHAR* szDevice); + HRESULT Remap(CHAR* szMapping); + + DWORD GetTrayState(); + HRESULT EjectTray(); + HRESULT CloseTray(); + HRESULT Shutdown(); + + HANDLE CreateFile(); + BOOL GetFirstFile(CHAR* szFilename); + +private: + DWORD m_dwTrayState; + DWORD m_dwTrayCount; + DWORD m_dwLastTrayState; +}; + +extern CIoSupport g_IOSupport; +#endif +#endif // !defined(AFX_IOSUPPORT_H__F084A488_BD6E_49D5_8CD3_0BE62149DB40__INCLUDED_) diff --git a/xbox1/RetroLaunch/Launcher.cpp b/xbox1/RetroLaunch/Launcher.cpp new file mode 100644 index 0000000000..4b28736f7b --- /dev/null +++ b/xbox1/RetroLaunch/Launcher.cpp @@ -0,0 +1,72 @@ +/** + * RetroLaunch 2012 + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. This program 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 this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. To contact the + * authors: Surreal64 CE Team (http://www.emuxtras.net) + */ + +#include "Global.h" +#include "Video.h" +#include "IniFile.h" +#include "IoSupport.h" +#include "Input.h" +#include "Debug.h" +#include "Font.h" +#include "MenuManager.h" +#include "RomList.h" + +bool g_bExit = false; + +void __cdecl main() +{ + g_debug.Print("Starting Launcher CE\n"); + + // Set file cache size + XSetFileCacheSize(8 * 1024 * 1024); + + // Mount drives + g_IOSupport.Mount("A:", "cdrom0"); + g_IOSupport.Mount("E:", "Harddisk0\\Partition1"); + g_IOSupport.Mount("Z:", "Harddisk0\\Partition2"); + g_IOSupport.Mount("F:", "Harddisk0\\Partition6"); + g_IOSupport.Mount("G:", "Harddisk0\\Partition7"); + + + // Initialize Direct3D + if (!g_video.Create(NULL, false)) + return; + + // Parse ini file for settings + g_iniFile.CheckForIniEntry(); + + // Load the rom list if it isn't already loaded + if (!g_romList.IsLoaded()) { + g_romList.Load(); + } + + // Init input here + g_input.Create(); + + // Load the font here + g_font.Create(); + + // Build menu here (Menu state -> Main Menu) + g_menuManager.Create(); + + // Loop the app + while (!g_bExit) + { + g_video.BeginRender(); + g_input.GetInput(); + g_menuManager.Update(); + g_video.EndRender(); + } +} diff --git a/xbox1/RetroLaunch/MenuMain.cpp b/xbox1/RetroLaunch/MenuMain.cpp new file mode 100644 index 0000000000..5ee4114d5e --- /dev/null +++ b/xbox1/RetroLaunch/MenuMain.cpp @@ -0,0 +1,241 @@ +/** + * RetroLaunch 2012 + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. This program 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 this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. To contact the + * authors: Surreal64 CE Team (http://www.emuxtras.net) + */ + +#include "MenuMain.h" +#include "Debug.h" +#include "Font.h" +#include "RomList.h" +#include "Input.h" + + +CMenuMain g_menuMain; + +CMenuMain::CMenuMain() +{ + // we think that the rom list is unloaded until we know otherwise + m_bRomListLoadedState = false; + + ifstream stateFile; + stateFile.open("T:\\RomlistState.dat"); + + if (stateFile.is_open()) + { + int baseIndex; + int romListMode; + + stateFile >> baseIndex; + stateFile >> romListMode; + stateFile >> m_displayMode; + + g_romList.SetRomListMode(romListMode); + g_romList.m_iBaseIndex = baseIndex; + + stateFile.close(); + } + else + { + m_displayMode = List; + } +} + +CMenuMain::~CMenuMain() +{ + ofstream stateFile; + stateFile.open("T:\\RomlistState.dat"); + + stateFile << g_romList.GetBaseIndex() << endl; + stateFile << g_romList.GetRomListMode() << endl; + stateFile << m_displayMode << endl; + + stateFile.close(); +} + +bool CMenuMain::Create() +{ + g_debug.Print("CMenuMain::Create()"); + + // Title coords with color + m_menuMainTitle_x = 305; + m_menuMainTitle_y = 30; + m_menuMainTitle_c = 0xFFFFFFFF; + + // Load background image + m_menuMainBG.Create("Media\\menuMainBG.png"); + m_menuMainBG_x = 0; + m_menuMainBG_y = 0; + m_menuMainBG_w = 640; + m_menuMainBG_h = 480; + + // Init rom list coords + m_menuMainRomListPos_x = 100; + m_menuMainRomListPos_y = 100; + m_menuMainRomListSpacing = 20; + + // Load rom selector panel + m_menuMainRomSelectPanel.Create("Media\\menuMainRomSelectPanel.png"); + m_menuMainRomSelectPanel_x = m_menuMainRomListPos_x - 5; + m_menuMainRomSelectPanel_y = m_menuMainRomListPos_y - 2; + m_menuMainRomSelectPanel_w = 440; + m_menuMainRomSelectPanel_h = 20; + + m_romListSelectedRom = 0; + + //The first element in the romlist to render + m_romListBeginRender = 0; + + //The last element in the romlist to render + m_romListEndRender = 18; + + //The offset in the romlist + m_romListOffset = 0; + + if(m_romListEndRender > g_romList.GetRomListSize() - 1) + { + m_romListEndRender = g_romList.GetRomListSize() - 1; + } + + //Generate the rom list textures only once + vector::iterator i; + dword y = 0; + for (i = g_romList.m_romList.begin(); i != g_romList.m_romList.end(); i++) + { + Rom *rom = *i; + g_font.RenderToTexture(rom->GetTexture(), rom->GetFileName(), 18, XFONT_BOLD, 0xff808080, -1, false); + } + + return true; +} + + +void CMenuMain::Render() +{ + //CheckRomListState(); + + //Render background image + m_menuMainBG.Render(m_menuMainBG_x, m_menuMainBG_y); + + //Display some text + //g_font.Render("Retro Arch", m_menuMainTitle_x, m_menuMainTitle_y, 20, XFONT_NORMAL, m_menuMainTitle_c); + g_font.Render("Press RIGHT ANALOG STICK to exit. Press START to launch a rom.", 65, 450, 16, XFONT_NORMAL, m_menuMainTitle_c); + + //Begin with the rom selector panel + //FIXME: Width/Height needs to be current Rom texture width/height (or should we just leave it at a fixed size?) + m_menuMainRomSelectPanel.Render(m_menuMainRomSelectPanel_x, m_menuMainRomSelectPanel_y, m_menuMainRomSelectPanel_w, m_menuMainRomSelectPanel_h); + + dword dwSpacing = 0; + + for (int i = m_romListBeginRender; i <= m_romListEndRender; i++) + { + g_romList.GetRomAt(i + m_romListOffset)->GetTexture().Render(m_menuMainRomListPos_x, m_menuMainRomListPos_y + dwSpacing); + dwSpacing += m_menuMainRomListSpacing; + } +} + + +void CMenuMain::ProcessInput() +{ + //FIXME: The calculations might be wrong :-/ + if(g_input.IsButtonPressed(XboxDPadDown) || g_input.IsButtonPressed(XboxLeftThumbDown) || g_input.IsRTriggerPressed()) + { + + if(m_romListSelectedRom < g_romList.GetRomListSize()) + { + + if(m_menuMainRomSelectPanel_y < (m_menuMainRomListPos_y + (m_menuMainRomListSpacing * m_romListEndRender))) + { + m_menuMainRomSelectPanel_y += m_menuMainRomListSpacing; + m_romListSelectedRom++; + g_debug.Print("SELECTED ROM: "); g_debug.Print("%d", m_romListSelectedRom); + } + + if(m_menuMainRomSelectPanel_y > (m_menuMainRomListPos_y + (m_menuMainRomListSpacing * (m_romListEndRender)))) + { + m_menuMainRomSelectPanel_y -= m_menuMainRomListSpacing; + m_romListSelectedRom++; + if(m_romListSelectedRom > g_romList.GetRomListSize() - 1) + { + m_romListSelectedRom = g_romList.GetRomListSize() - 1; + } + + + g_debug.Print("SELECTED ROM AFTER CORRECTION: "); g_debug.Print("%d", m_romListSelectedRom); + + if(m_romListSelectedRom < g_romList.GetRomListSize() - 1 && m_romListOffset < g_romList.GetRomListSize() - 1 - m_romListEndRender - 1) { + m_romListOffset++; + g_debug.Print("OFFSET: "); g_debug.Print("%d", m_romListOffset); + } + } + +///////////////////////////////////////////// + + } + } + + // Go up and stop if less than 0 (item 0) + if(g_input.IsButtonPressed(XboxDPadUp) || g_input.IsButtonPressed(XboxLeftThumbUp) || g_input.IsLTriggerPressed()) + { + if(m_romListSelectedRom > -1) + { + if(m_menuMainRomSelectPanel_y > (m_menuMainRomListPos_y - m_menuMainRomListSpacing)) + { + m_menuMainRomSelectPanel_y -= m_menuMainRomListSpacing; + m_romListSelectedRom--; + g_debug.Print("SELECTED ROM: "); g_debug.Print("%d", m_romListSelectedRom); + } + + if(m_menuMainRomSelectPanel_y < (m_menuMainRomListPos_y - m_menuMainRomListSpacing)) + { + m_menuMainRomSelectPanel_y += m_menuMainRomListSpacing; + m_romListSelectedRom--; + if(m_romListSelectedRom < 0) + { + m_romListSelectedRom = 0; + } + + + g_debug.Print("SELECTED ROM AFTER CORRECTION: "); g_debug.Print("%d", m_romListSelectedRom); + + if(m_romListSelectedRom > 0 && m_romListOffset > 0) { + m_romListOffset--; + g_debug.Print("OFFSET: "); g_debug.Print("%d", m_romListOffset); + } + } + } + + + + } + + // Press A to launch, selected rom filename is saved into T:\\tmp.retro + if(g_input.IsButtonPressed(XboxA)) + { + //OutputDebugString(g_romList.GetRomAt(m_romListSelectedRom)->GetFileName().c_str()); + //OutputDebugString("\n"); + g_iniFile.SaveTempRomFileName(g_romList.GetRomAt(m_romListSelectedRom)->GetFileName()); + XLaunchNewImage("D:\\core.xbe", NULL); + } + + if (g_input.IsButtonPressed(XboxStart)) + { + XLaunchNewImage("D:\\core.xbe", NULL); + } + + if (g_input.IsButtonPressed(XboxRightThumbButton)) + { + LD_LAUNCH_DASHBOARD LaunchData = { XLD_LAUNCH_DASHBOARD_MAIN_MENU }; + XLaunchNewImage( NULL, (LAUNCH_DATA*)&LaunchData ); + } +} + diff --git a/xbox1/RetroLaunch/MenuMain.h b/xbox1/RetroLaunch/MenuMain.h new file mode 100644 index 0000000000..c8d9135fbd --- /dev/null +++ b/xbox1/RetroLaunch/MenuMain.h @@ -0,0 +1,99 @@ +/** + * RetroLaunch 2012 + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. This program 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 this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. To contact the + * authors: Surreal64 CE Team (http://www.emuxtras.net) + */ + +#pragma once +#include "Global.h" +#include "Surface.h" + +enum DisplayMode +{ + Box, + List +}; + +class CMenuMain +{ +public: +CMenuMain(); +~CMenuMain(); + +bool Create(); + +void Render(); + +void ProcessInput(); + +private: +/* +Texture, +_x = xpos, +_y = ypos, +_w = width, +_h = height, +_c = color, +*/ + +// Background image with coords +CSurface m_menuMainBG; +int m_menuMainBG_x; +int m_menuMainBG_y; +dword m_menuMainBG_w; +dword m_menuMainBG_h; + +// Rom selector panel with coords +CSurface m_menuMainRomSelectPanel; +int m_menuMainRomSelectPanel_x; +int m_menuMainRomSelectPanel_y; +dword m_menuMainRomSelectPanel_w; +dword m_menuMainRomSelectPanel_h; + +// Title coords with color +int m_menuMainTitle_x; +int m_menuMainTitle_y; +dword m_menuMainTitle_c; + +// Rom list coords +int m_menuMainRomListPos_x; +int m_menuMainRomListPos_y; +int m_menuMainRomListSpacing; + + + + +/** +* The Rom List menu buttons. The size can be variable so we use a list +*/ +//list m_romListButtons;//list +//no menu buttons, we will use plain textures +list m_romListButtons; + +/** +* The current mode the rom list is in +*/ +int m_displayMode; + +/** +* The current loaded state the rom list is in +*/ +bool m_bRomListLoadedState; + +int m_romListBeginRender; +int m_romListEndRender; +int m_romListSelectedRom; +int m_romListOffset; + +}; + +extern CMenuMain g_menuMain; diff --git a/xbox1/RetroLaunch/MenuManager.cpp b/xbox1/RetroLaunch/MenuManager.cpp new file mode 100644 index 0000000000..ef0853003f --- /dev/null +++ b/xbox1/RetroLaunch/MenuManager.cpp @@ -0,0 +1,98 @@ +/** + * RetroLaunch 2012 + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. This program 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 this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. To contact the + * authors: Surreal64 CE Team (http://www.emuxtras.net) + */ + +#include "MenuManager.h" +#include "MenuMain.h" +#include "Debug.h" +#include "Input.h" + + +CMenuManager g_menuManager; + +CMenuManager::CMenuManager() +{ +} + +CMenuManager::~CMenuManager() +{ +} + +bool CMenuManager::Create() +{ + //Create the MenuManager, set to Main Menu + g_debug.Print("Create MenuManager, set state to MENU_MAIN"); + SetMenuState(MENU_MAIN); + + return true; +} + +bool CMenuManager::SetMenuState(int nMenuID) +{ + m_pMenuID = nMenuID; + + switch (m_pMenuID) { + case MENU_MAIN: + //Create the Main Menu + g_menuMain.Create(); + break; + } + return true; +} + +void CMenuManager::Update() +{ + //Process overall input + ProcessInput(); + + switch (m_pMenuID) { + case MENU_MAIN: + + // Process menu specific input + g_menuMain.ProcessInput(); + + // Render the Main Menu + g_menuMain.Render(); + break; + } + +} + + +void CMenuManager::ProcessInput() +{ + //ADD: ProcessTarget -> switch to another menu + + //Return to Dashboard + if(g_input.IsLTriggerPressed() && + g_input.IsRTriggerPressed() && + g_input.IsButtonPressed(XboxBlack) && + g_input.IsButtonPressed(XboxWhite) && + g_input.IsButtonPressed(XboxBack) && + g_input.IsButtonPressed(XboxStart)) + { + + LD_LAUNCH_DASHBOARD LaunchData = { XLD_LAUNCH_DASHBOARD_MAIN_MENU }; + XLaunchNewImage( NULL, (LAUNCH_DATA*)&LaunchData ); + + } +} + + + +int CMenuManager::GetMenuState() +{ + return m_pMenuID; +} + diff --git a/xbox1/RetroLaunch/MenuManager.h b/xbox1/RetroLaunch/MenuManager.h new file mode 100644 index 0000000000..0e888299aa --- /dev/null +++ b/xbox1/RetroLaunch/MenuManager.h @@ -0,0 +1,50 @@ +/** + * RetroLaunch 2012 + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. This program 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 this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. To contact the + * authors: Surreal64 CE Team (http://www.emuxtras.net) + */ + +#pragma once + +#include "Global.h" + +enum eMenuState +{ + MENU_MAIN = 0, + MENU_SETTINGS_SELECT, + MENU_SETTINGS_EMU, + MENU_SETTINGS_AUDIO, + MENU_SETTINGS_SKIN, + MENU_LAUNCHER +}; + + +class CMenuManager +{ +public: +CMenuManager(); +~CMenuManager(); + +bool Create(); +bool SetMenuState(int nMenuID); +int GetMenuState(); +bool Destroy(); +void Update(); +void ProcessInput(); + + +private: +int m_pMenuID; + +}; + +extern CMenuManager g_menuManager; \ No newline at end of file diff --git a/xbox1/RetroLaunch/RetroLaunch.sln b/xbox1/RetroLaunch/RetroLaunch.sln new file mode 100644 index 0000000000..d2b910dcca --- /dev/null +++ b/xbox1/RetroLaunch/RetroLaunch.sln @@ -0,0 +1,33 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RetroLaunch", "RetroLaunch.vcproj", "{14134C4E-7FD3-46F0-AD16-C32D952978EA}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + Debug = Debug + Profile = Profile + Profile_FastCap = Profile_FastCap + Release = Release + Release_LTCG = Release_LTCG + ReleaseTest = ReleaseTest + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {14134C4E-7FD3-46F0-AD16-C32D952978EA}.Debug.ActiveCfg = Debug|Xbox + {14134C4E-7FD3-46F0-AD16-C32D952978EA}.Debug.Build.0 = Debug|Xbox + {14134C4E-7FD3-46F0-AD16-C32D952978EA}.Profile.ActiveCfg = Profile|Xbox + {14134C4E-7FD3-46F0-AD16-C32D952978EA}.Profile.Build.0 = Profile|Xbox + {14134C4E-7FD3-46F0-AD16-C32D952978EA}.Profile_FastCap.ActiveCfg = Profile_FastCap|Xbox + {14134C4E-7FD3-46F0-AD16-C32D952978EA}.Profile_FastCap.Build.0 = Profile_FastCap|Xbox + {14134C4E-7FD3-46F0-AD16-C32D952978EA}.Release.ActiveCfg = Release|Xbox + {14134C4E-7FD3-46F0-AD16-C32D952978EA}.Release.Build.0 = Release|Xbox + {14134C4E-7FD3-46F0-AD16-C32D952978EA}.Release_LTCG.ActiveCfg = Release_LTCG|Xbox + {14134C4E-7FD3-46F0-AD16-C32D952978EA}.Release_LTCG.Build.0 = Release_LTCG|Xbox + {14134C4E-7FD3-46F0-AD16-C32D952978EA}.ReleaseTest.ActiveCfg = ReleaseTest|Xbox + {14134C4E-7FD3-46F0-AD16-C32D952978EA}.ReleaseTest.Build.0 = ReleaseTest|Xbox + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/xbox1/RetroLaunch/RetroLaunch.vcproj b/xbox1/RetroLaunch/RetroLaunch.vcproj new file mode 100644 index 0000000000..f2f561e265 --- /dev/null +++ b/xbox1/RetroLaunch/RetroLaunch.vcproj @@ -0,0 +1,447 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xbox1/RetroLaunch/Rom.cpp b/xbox1/RetroLaunch/Rom.cpp new file mode 100644 index 0000000000..c05c93818c --- /dev/null +++ b/xbox1/RetroLaunch/Rom.cpp @@ -0,0 +1,76 @@ +/** + * Surreal 64 Launcher (C) 2003 + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. This program 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 this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. To contact the + * authors: email: buttza@hotmail.com, lantus@lantus-x.com + */ + +#include "Rom.h" +//#include "BoxArtTable.h" + +Rom::Rom() +{ + m_bLoaded = false; +} + +Rom::~Rom(void) +{ +} + +bool Rom::Load(const string &szFilename) +{ + if (m_bLoaded) + return true; + + m_szFilename = szFilename; + + // get the filename for the box art image + //FIXME: Add BoxArtTable.cpp/h, open iso file, grab header, extract ID ie. T-6003G, use for boxartfilename + { + m_szBoxArtFilename = "D:\\boxart\\default.jpg"; //g_boxArtTable.GetBoxArtFilename(m_dwCrc1); + } + + m_bLoaded = true; + + return true; +} + +bool Rom::LoadFromCache(const string &szFilename, const string &szBoxArtFilename) +{ + m_szFilename = szFilename; + m_szBoxArtFilename = szBoxArtFilename; + + m_bLoaded = true; + + return true; +} + +string Rom::GetFileName() +{ + return m_szFilename; +} + +string Rom::GetBoxArtFilename() +{ + return m_szBoxArtFilename; +} + +string Rom::GetComments() +{ + //return string(m_iniEntry->szComments); + return "blah"; +} + + +CSurface &Rom::GetTexture() +{ + return m_texture; +} \ No newline at end of file diff --git a/xbox1/RetroLaunch/Rom.h b/xbox1/RetroLaunch/Rom.h new file mode 100644 index 0000000000..11dce13713 --- /dev/null +++ b/xbox1/RetroLaunch/Rom.h @@ -0,0 +1,44 @@ +/** + * Surreal 64 Launcher (C) 2003 + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. This program 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 this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. To contact the + * authors: email: buttza@hotmail.com, lantus@lantus-x.com + */ + +#pragma once + +#include "Global.h" +#include "IniFile.h" +#include "Surface.h" + +class Rom +{ +public: + Rom(); + ~Rom(); + + bool Load(const string &szFilename); + bool LoadFromCache(const string &szFilename, const string &szBoxArtFilename); + + string GetFileName(); + string GetBoxArtFilename(); + string GetComments(); + + CSurface &GetTexture(); + +private: + string m_szFilename; + string m_szBoxArtFilename; + + bool m_bLoaded; + + CSurface m_texture; +}; diff --git a/xbox1/RetroLaunch/RomList.cpp b/xbox1/RetroLaunch/RomList.cpp new file mode 100644 index 0000000000..b22381959a --- /dev/null +++ b/xbox1/RetroLaunch/RomList.cpp @@ -0,0 +1,309 @@ +/** + * RetroLaunch 2012 + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. This program 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 this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. To contact the + * authors: Surreal64 CE Team (http://www.emuxtras.net) + */ + +#include "RomList.h" + +RomList g_romList; + +bool RLessThan(Rom *elem1, Rom *elem2) +{ + return (elem1->GetFileName() < elem2->GetFileName()); +} + +RomList::RomList(void) +{ + m_romListMode = All; + m_iBaseIndex = 0; + m_bLoaded = false; + m_szRomPath = "D:\\Roms\\"; +} + +RomList::~RomList(void) +{ + Destroy(); +} + +void RomList::Load() +{ + ifstream cacheFile; + + cacheFile.open("T:\\RomlistCache.dat"); + + // try and open the cache file, if it doesnt exist, generate the rom list + if (!cacheFile.is_open()) + { + Build(); + } + else + { + while (!cacheFile.eof()) + { + string szFilename; + string szBoxArtFilename; + + getline(cacheFile, szFilename); + getline(cacheFile, szBoxArtFilename); + + Rom *rom = new Rom(); + + bool bSuccess = rom->LoadFromCache(szFilename, szBoxArtFilename); + + if (bSuccess) + m_romList.push_back(rom); + else + delete rom; + } + + cacheFile.close(); + } + + m_bLoaded = true; +} + +void RomList::Save() +{ + vector::iterator i; + ofstream cacheFile; + + // open/overwrite the rom cache + cacheFile.open("T:\\RomlistCache.dat"); + + for (i = m_romList.begin(); i != m_romList.end(); i++) + { + Rom *rom = *i; + + cacheFile << rom->GetFileName() << endl; + cacheFile << rom->GetBoxArtFilename() << endl; + } + + cacheFile.close(); +} + +void RomList::Refresh() +{ + Destroy(); + DeleteFile("T:\\RomlistCache.dat"); + DeleteFile("T:\\RomlistState.dat"); +} + +bool RomList::IsLoaded() +{ + return m_bLoaded; +} + +void RomList::SetRomListMode(int mode) +{ + m_iBaseIndex = 0; + m_romListMode = mode; +} + +int RomList::GetRomListMode() +{ + return m_romListMode; +} + +void RomList::AddRomToList(Rom *rom, int mode) +{ + vector *pList; + + switch (mode) + { + case All: + pList = &m_romList; + break; + default: + return; + } + + // look to see if the rom is already in the list, we dont want duplicates + for (int i = 0; i < static_cast(pList->size()); i++) + { + if (rom == (*pList)[i]) + return; + } + + pList->push_back(rom); + sort(pList->begin(), pList->end(), RLessThan); +} + +void RomList::RemoveRomFromList(Rom *rom, int mode) +{ + vector *pList; + + switch (mode) + { + case All: + pList = &m_romList; + break; + default: + return; + } + + vector::iterator i; + + // look to see if the rom is already in the list, we dont want duplicates + for (i = pList->begin(); i != pList->end(); i++) + { + if (rom == *i) + { + pList->erase(i); + return; + } + } +} + +int RomList::GetBaseIndex() +{ + if (m_iBaseIndex > GetRomListSize() - 1) + m_iBaseIndex = GetRomListSize() - 1; + if (m_iBaseIndex < 0) + m_iBaseIndex = 0; + + return m_iBaseIndex; +} + +void RomList::SetBaseIndex(int index) +{ + if (index > GetRomListSize() - 1) + index = GetRomListSize() - 1; + if (index < 0) + index = 0; + + m_iBaseIndex = index; +} + +int RomList::GetRomListSize() +{ + switch (m_romListMode) + { + case All: + return m_romList.size(); + } + + return 0; +} + +Rom *RomList::GetRomAt(int index) +{ + switch (m_romListMode) + { + case All: + return m_romList[index]; + } + + return 0; +} + +int RomList::FindRom(Rom *rom, int mode) +{ + vector *pList; + + switch (mode) + { + case All: + pList = &m_romList; + break; + default: + return -1; + } + + for (int i = 0; i < static_cast(pList->size()); i++) + { + if (rom == (*pList)[i]) + return i; + } + + return -1; +} + +void RomList::CleanUpTextures() +{ + if (!IsLoaded()) + return; + + // keep the 25 textures above and below the base index + for (int i = 0; i < m_iBaseIndex - 25; i++) + { + m_romList[i]->GetTexture().Destroy(); + } + + for (int i = m_iBaseIndex + 25; i < GetRomListSize(); i++) + { + m_romList[i]->GetTexture().Destroy(); + } +} + +void RomList::DestroyAllTextures() +{ + vector::iterator i; + + for (i = m_romList.begin(); i != m_romList.end(); i++) + { + Rom *rom = *i; + rom->GetTexture().Destroy(); + } +} + +void RomList::Build() +{ + WIN32_FIND_DATA fd; + + HANDLE hFF = FindFirstFile((m_szRomPath + "*.*").c_str(), &fd); + + do + { + char ext[_MAX_EXT]; + + // get the filename extension + _splitpath((m_szRomPath + fd.cFileName).c_str(), + NULL, NULL, NULL, ext); + + if ( + stricmp(ext, ".bin") == 0 + || stricmp(ext, ".cue") == 0 + || stricmp(ext, ".iso") == 0 + || stricmp(ext, ".mdf") == 0 + || stricmp(ext, ".gba") == 0 + ) + { + Rom *rom = new Rom(); + bool bSuccess = rom->Load((m_szRomPath + fd.cFileName).c_str()); + + if (bSuccess) + m_romList.push_back(rom); + else + delete rom; + } + } while (FindNextFile(hFF, &fd)); + + sort(m_romList.begin(), m_romList.end(), RLessThan); + + m_bLoaded = true; +} + +void RomList::Destroy() +{ + m_bLoaded = false; + m_iBaseIndex = 0; + + vector::iterator i; + + for (i = m_romList.begin(); i != m_romList.end(); i++) + { + delete *i; + } + + m_romList.clear(); +} diff --git a/xbox1/RetroLaunch/RomList.h b/xbox1/RetroLaunch/RomList.h new file mode 100644 index 0000000000..3fa19615d4 --- /dev/null +++ b/xbox1/RetroLaunch/RomList.h @@ -0,0 +1,72 @@ +/** + * RetroLaunch 2012 + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. This program 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 this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. To contact the + * authors: Surreal64 CE Team (http://www.emuxtras.net) + */ + +#pragma once + +#include "Global.h" +#include "Rom.h" + +enum RomListMode +{ + All +}; + +class RomList +{ +public: + RomList(void); + virtual ~RomList(void); + + void Load(); + void Save(); + void Refresh(); + + bool IsLoaded(); + + void SetRomListMode(int mode); + int GetRomListMode(); + + void AddRomToList(Rom *rom, int mode); + void RemoveRomFromList(Rom *rom, int mode); + + int GetBaseIndex(); + void SetBaseIndex(int index); + + int GetRomListSize(); + + Rom *GetRomAt(int index); + int FindRom(Rom *rom, int mode); + + void CleanUpTextures(); + void DestroyAllTextures(); + + int m_iBaseIndex; + + vector m_romList; + +private: + void Build(); + void Destroy(); + +private: + + bool m_bLoaded; + + int m_romListMode; + + string m_szRomPath; +}; + +extern RomList g_romList; \ No newline at end of file diff --git a/xbox1/RetroLaunch/SimpleIni.h b/xbox1/RetroLaunch/SimpleIni.h new file mode 100644 index 0000000000..882289f6fc --- /dev/null +++ b/xbox1/RetroLaunch/SimpleIni.h @@ -0,0 +1,3262 @@ +/** @mainpage + + +
Library SimpleIni +
File SimpleIni.h +
Author Brodie Thiesfield [code at jellycan dot com] +
Source http://code.jellycan.com/simpleini/ +
Version 4.13 +
+ + Jump to the @link CSimpleIniTempl CSimpleIni @endlink interface documentation. + + @section intro INTRODUCTION + + This component allows an INI-style configuration file to be used on both + Windows and Linux/Unix. It is fast, simple and source code using this + component will compile unchanged on either OS. + + + @section features FEATURES + + - MIT Licence allows free use in all software (including GPL and commercial) + - multi-platform (Windows 95/98/ME/NT/2K/XP/2003, Windows CE, Linux, Unix) + - loading and saving of INI-style configuration files + - configuration files can have any newline format on all platforms + - liberal acceptance of file format + - key/values with no section + - removal of whitespace around sections, keys and values + - support for multi-line values (values with embedded newline characters) + - optional support for multiple keys with the same name + - optional case-insensitive sections and keys (for ASCII characters only) + - saves files with sections and keys in the same order as they were loaded + - preserves comments on the file, section and keys where possible. + - supports both char or wchar_t programming interfaces + - supports both MBCS (system locale) and UTF-8 file encodings + - system locale does not need to be UTF-8 on Linux/Unix to load UTF-8 file + - support for non-ASCII characters in section, keys, values and comments + - support for non-standard character types or file encodings + via user-written converter classes + - support for adding/modifying values programmatically + - compiles cleanly in the following compilers: + - Windows/VC6 (warning level 3) + - Windows/VC.NET 2003 (warning level 4) + - Windows/VC 2005 (warning level 4) + - Linux/gcc (-Wall) + + + @section usage USAGE SUMMARY + + -# Define the appropriate symbol for the converter you wish to use and + include the SimpleIni.h header file. If no specific converter is defined + then the default converter is used. The default conversion mode uses + SI_CONVERT_WIN32 on Windows and SI_CONVERT_GENERIC on all other + platforms. If you are using ICU then SI_CONVERT_ICU is supported on all + platforms. + -# Declare an instance the appropriate class. Note that the following + definitions are just shortcuts for commonly used types. Other types + (PRUnichar, unsigned short, unsigned char) are also possible. + +
Interface Case-sensitive Load UTF-8 Load MBCS Typedef +
SI_CONVERT_GENERIC +
char No Yes Yes #1 CSimpleIniA +
char Yes Yes Yes CSimpleIniCaseA +
wchar_t No Yes Yes CSimpleIniW +
wchar_t Yes Yes Yes CSimpleIniCaseW +
SI_CONVERT_WIN32 +
char No No #2 Yes CSimpleIniA +
char Yes Yes Yes CSimpleIniCaseA +
wchar_t No Yes Yes CSimpleIniW +
wchar_t Yes Yes Yes CSimpleIniCaseW +
SI_CONVERT_ICU +
char No Yes Yes CSimpleIniA +
char Yes Yes Yes CSimpleIniCaseA +
UChar No Yes Yes CSimpleIniW +
UChar Yes Yes Yes CSimpleIniCaseW +
+ #1 On Windows you are better to use CSimpleIniA with SI_CONVERT_WIN32.
+ #2 Only affects Windows. On Windows this uses MBCS functions and + so may fold case incorrectly leading to uncertain results. + -# Call Load() or LoadFile() to load and parse the INI configuration file + -# Access and modify the data of the file using the following functions + +
GetAllSections Return all section names +
GetAllKeys Return all key names within a section +
GetAllValues Return all values within a section & key +
GetSection Return all key names and values in a section +
GetSectionSize Return the number of keys in a section +
GetValue Return a value for a section & key +
SetValue Add or update a value for a section & key +
Delete Remove a section, or a key from a section +
+ -# Call Save() or SaveFile() to save the INI configuration data + + @section iostreams IO STREAMS + + SimpleIni supports reading from and writing to STL IO streams. Enable this + by defining SI_SUPPORT_IOSTREAMS before including the SimpleIni.h header + file. Ensure that if the streams are backed by a file (e.g. ifstream or + ofstream) then the flag ios_base::binary has been used when the file was + opened. + + @section multiline MULTI-LINE VALUES + + Values that span multiple lines are created using the following format. + +
+        key = <<
+
+    Note the following:
+    - The text used for ENDTAG can be anything and is used to find
+      where the multi-line text ends.
+    - The newline after ENDTAG in the start tag, and the newline
+      before ENDTAG in the end tag is not included in the data value.
+    - The ending tag must be on it's own line with no whitespace before
+      or after it.
+    - The multi-line value is modified at load so that each line in the value
+      is delimited by a single '\\n' character on all platforms. At save time
+      it will be converted into the newline format used by the current
+      platform.
+
+    @section comments COMMENTS
+
+    Comments are preserved in the file within the following restrictions:
+    - Every file may have a single "file comment". It must start with the
+      first character in the file, and will end with the first non-comment
+      line in the file.
+    - Every section may have a single "section comment". It will start
+      with the first comment line following the file comment, or the last
+      data entry. It ends at the beginning of the section.
+    - Every key may have a single "key comment". This comment will start
+      with the first comment line following the section start, or the file
+      comment if there is no section name.
+    - Comments are set at the time that the file, section or key is first
+      created. The only way to modify a comment on a section or a key is to
+      delete that entry and recreate it with the new comment. There is no
+      way to change the file comment.
+
+    @section save SAVE ORDER
+
+    The sections and keys are written out in the same order as they were
+    read in from the file. Sections and keys added to the data after the
+    file has been loaded will be added to the end of the file when it is
+    written. There is no way to specify the location of a section or key
+    other than in first-created, first-saved order.
+
+    @section notes NOTES
+
+    - To load UTF-8 data on Windows 95, you need to use Microsoft Layer for
+      Unicode, or SI_CONVERT_GENERIC, or SI_CONVERT_ICU.
+    - When using SI_CONVERT_GENERIC, ConvertUTF.c must be compiled and linked.
+    - When using SI_CONVERT_ICU, ICU header files must be on the include
+      path and icuuc.lib must be linked in.
+    - To load a UTF-8 file on Windows AND expose it with SI_CHAR == char,
+      you should use SI_CONVERT_GENERIC.
+    - The collation (sorting) order used for sections and keys returned from
+      iterators is NOT DEFINED. If collation order of the text is important
+      then it should be done yourself by either supplying a replacement
+      SI_STRLESS class, or by sorting the strings external to this library.
+    - Usage of the  header on Windows can be disabled by defining
+      SI_NO_MBCS. This is defined automatically on Windows CE platforms.
+
+
+    @section licence MIT LICENCE
+
+    The licence text below is the boilerplate "MIT Licence" used from:
+    http://www.opensource.org/licenses/mit-license.php
+
+    Copyright (c) 2006-2008, Brodie Thiesfield
+
+    Permission is hereby granted, free of charge, to any person obtaining a copy
+    of this software and associated documentation files (the "Software"), to deal
+    in the Software without restriction, including without limitation the rights
+    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+    copies of the Software, and to permit persons to whom the Software is furnished
+    to do so, subject to the following conditions:
+
+    The above copyright notice and this permission notice shall be included in
+    all copies or substantial portions of the Software.
+
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+    FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+    COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+    IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+    CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef INCLUDED_SimpleIni_h
+#define INCLUDED_SimpleIni_h
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+// Disable these warnings in MSVC:
+//  4127 "conditional expression is constant" as the conversion classes trigger
+//  it with the statement if (sizeof(SI_CHAR) == sizeof(char)). This test will
+//  be optimized away in a release build.
+//  4503 'insert' : decorated name length exceeded, name was truncated
+//  4702 "unreachable code" as the MS STL header causes it in release mode.
+//  Again, the code causing the warning will be cleaned up by the compiler.
+//  4786 "identifier truncated to 256 characters" as this is thrown hundreds
+//  of times VC6 as soon as STL is used.
+#ifdef _MSC_VER
+# pragma warning (push)
+# pragma warning (disable: 4127 4503 4702 4786)
+#endif
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#ifdef SI_SUPPORT_IOSTREAMS
+# include 
+#endif // SI_SUPPORT_IOSTREAMS
+
+#ifdef _DEBUG
+# ifndef assert
+#  include 
+# endif
+# define SI_ASSERT(x)   assert(x)
+#else
+# define SI_ASSERT(x)
+#endif
+
+enum SI_Error {
+    SI_OK       =  0,   //!< No error
+    SI_UPDATED  =  1,   //!< An existing value was updated
+    SI_INSERTED =  2,   //!< A new value was inserted
+
+    // note: test for any error with (retval < 0)
+    SI_FAIL     = -1,   //!< Generic failure
+    SI_NOMEM    = -2,   //!< Out of memory error
+    SI_FILE     = -3    //!< File error (see errno for detail error)
+};
+
+#define SI_UTF8_SIGNATURE     "\xEF\xBB\xBF"
+
+#ifdef _WIN32
+# define SI_NEWLINE_A   "\r\n"
+# define SI_NEWLINE_W   L"\r\n"
+#else // !_WIN32
+# define SI_NEWLINE_A   "\n"
+# define SI_NEWLINE_W   L"\n"
+#endif // _WIN32
+
+#if defined(SI_CONVERT_ICU)
+# include 
+#endif
+
+#if defined(_WIN32)
+# define SI_HAS_WIDE_FILE
+# define SI_WCHAR_T     wchar_t
+#elif defined(SI_CONVERT_ICU)
+# define SI_HAS_WIDE_FILE
+# define SI_WCHAR_T     UChar
+#endif
+
+
+// ---------------------------------------------------------------------------
+//                              MAIN TEMPLATE CLASS
+// ---------------------------------------------------------------------------
+
+/** Simple INI file reader.
+
+    This can be instantiated with the choice of unicode or native characterset,
+    and case sensitive or insensitive comparisons of section and key names.
+    The supported combinations are pre-defined with the following typedefs:
+
+    
+        
Interface Case-sensitive Typedef +
char No CSimpleIniA +
char Yes CSimpleIniCaseA +
wchar_t No CSimpleIniW +
wchar_t Yes CSimpleIniCaseW +
+ + Note that using other types for the SI_CHAR is supported. For instance, + unsigned char, unsigned short, etc. Note that where the alternative type + is a different size to char/wchar_t you may need to supply new helper + classes for SI_STRLESS and SI_CONVERTER. + */ +template +class CSimpleIniTempl +{ +public: + /** key entry */ + struct Entry { + const SI_CHAR * pItem; + const SI_CHAR * pComment; + int nOrder; + + Entry(const SI_CHAR * a_pszItem = NULL, int a_nOrder = 0) + : pItem(a_pszItem) + , pComment(NULL) + , nOrder(a_nOrder) + { } + Entry(const SI_CHAR * a_pszItem, const SI_CHAR * a_pszComment, int a_nOrder) + : pItem(a_pszItem) + , pComment(a_pszComment) + , nOrder(a_nOrder) + { } + Entry(const Entry & rhs) { operator=(rhs); } + Entry & operator=(const Entry & rhs) { + pItem = rhs.pItem; + pComment = rhs.pComment; + nOrder = rhs.nOrder; + return *this; + } + +#if defined(_MSC_VER) && _MSC_VER <= 1200 + /** STL of VC6 doesn't allow me to specify my own comparator for list::sort() */ + bool operator<(const Entry & rhs) const { return LoadOrder()(*this, rhs); } + bool operator>(const Entry & rhs) const { return LoadOrder()(rhs, *this); } +#endif + + /** Strict less ordering by name of key only */ + struct KeyOrder : std::binary_function { + bool operator()(const Entry & lhs, const Entry & rhs) const { + const static SI_STRLESS isLess = SI_STRLESS(); + return isLess(lhs.pItem, rhs.pItem); + } + }; + + /** Strict less ordering by order, and then name of key */ + struct LoadOrder : std::binary_function { + bool operator()(const Entry & lhs, const Entry & rhs) const { + if (lhs.nOrder != rhs.nOrder) { + return lhs.nOrder < rhs.nOrder; + } + return KeyOrder()(lhs.pItem, rhs.pItem); + } + }; + }; + + /** map keys to values */ + typedef std::multimap TKeyVal; + + /** map sections to key/value map */ + typedef std::map TSection; + + /** set of dependent string pointers. Note that these pointers are + dependent on memory owned by CSimpleIni. + */ + typedef std::list TNamesDepend; + + /** interface definition for the OutputWriter object to pass to Save() + in order to output the INI file data. + */ + class OutputWriter { + public: + OutputWriter() { } + virtual ~OutputWriter() { } + virtual void Write(const char * a_pBuf) = 0; + private: + OutputWriter(const OutputWriter &); // disable + OutputWriter & operator=(const OutputWriter &); // disable + }; + + /** OutputWriter class to write the INI data to a file */ + class FileWriter : public OutputWriter { + FILE * m_file; + public: + FileWriter(FILE * a_file) : m_file(a_file) { } + void Write(const char * a_pBuf) { + fputs(a_pBuf, m_file); + } + private: + FileWriter(const FileWriter &); // disable + FileWriter & operator=(const FileWriter &); // disable + }; + + /** OutputWriter class to write the INI data to a string */ + class StringWriter : public OutputWriter { + std::string & m_string; + public: + StringWriter(std::string & a_string) : m_string(a_string) { } + void Write(const char * a_pBuf) { + m_string.append(a_pBuf); + } + private: + StringWriter(const StringWriter &); // disable + StringWriter & operator=(const StringWriter &); // disable + }; + +#ifdef SI_SUPPORT_IOSTREAMS + /** OutputWriter class to write the INI data to an ostream */ + class StreamWriter : public OutputWriter { + std::ostream & m_ostream; + public: + StreamWriter(std::ostream & a_ostream) : m_ostream(a_ostream) { } + void Write(const char * a_pBuf) { + m_ostream << a_pBuf; + } + private: + StreamWriter(const StreamWriter &); // disable + StreamWriter & operator=(const StreamWriter &); // disable + }; +#endif // SI_SUPPORT_IOSTREAMS + + /** Characterset conversion utility class to convert strings to the + same format as is used for the storage. + */ + class Converter : private SI_CONVERTER { + public: + Converter(bool a_bStoreIsUtf8) : SI_CONVERTER(a_bStoreIsUtf8) { + m_scratch.resize(1024); + } + Converter(const Converter & rhs) { operator=(rhs); } + Converter & operator=(const Converter & rhs) { + m_scratch = rhs.m_scratch; + return *this; + } + bool ConvertToStore(const SI_CHAR * a_pszString) { + size_t uLen = SizeToStore(a_pszString); + if (uLen == (size_t)(-1)) { + return false; + } + while (uLen > m_scratch.size()) { + m_scratch.resize(m_scratch.size() * 2); + } + return SI_CONVERTER::ConvertToStore( + a_pszString, + const_cast(m_scratch.data()), + m_scratch.size()); + } + const char * Data() { return m_scratch.data(); } + private: + std::string m_scratch; + }; + +public: + /*-----------------------------------------------------------------------*/ + + /** Default constructor. + + @param a_bIsUtf8 See the method SetUnicode() for details. + @param a_bMultiKey See the method SetMultiKey() for details. + @param a_bMultiLine See the method SetMultiLine() for details. + */ + CSimpleIniTempl( + bool a_bIsUtf8 = false, + bool a_bMultiKey = false, + bool a_bMultiLine = false + ); + + /** Destructor */ + ~CSimpleIniTempl(); + + /** Deallocate all memory stored by this object */ + void Reset(); + + /*-----------------------------------------------------------------------*/ + /** @{ @name Settings */ + + /** Set the storage format of the INI data. This affects both the loading + and saving of the INI data using all of the Load/Save API functions. + This value cannot be changed after any INI data has been loaded. + + If the file is not set to Unicode (UTF-8), then the data encoding is + assumed to be the OS native encoding. This encoding is the system + locale on Linux/Unix and the legacy MBCS encoding on Windows NT/2K/XP. + If the storage format is set to Unicode then the file will be loaded + as UTF-8 encoded data regardless of the native file encoding. If + SI_CHAR == char then all of the char* parameters take and return UTF-8 + encoded data regardless of the system locale. + + \param a_bIsUtf8 Assume UTF-8 encoding for the source? + */ + void SetUnicode(bool a_bIsUtf8 = true) { + if (!m_pData) m_bStoreIsUtf8 = a_bIsUtf8; + } + + /** Get the storage format of the INI data. */ + bool IsUnicode() const { return m_bStoreIsUtf8; } + + /** Should multiple identical keys be permitted in the file. If set to false + then the last value encountered will be used as the value of the key. + If set to true, then all values will be available to be queried. For + example, with the following input: + +
+        [section]
+        test=value1
+        test=value2
+        
+ + Then with SetMultiKey(true), both of the values "value1" and "value2" + will be returned for the key test. If SetMultiKey(false) is used, then + the value for "test" will only be "value2". This value may be changed + at any time. + + \param a_bAllowMultiKey Allow multi-keys in the source? + */ + void SetMultiKey(bool a_bAllowMultiKey = true) { + m_bAllowMultiKey = a_bAllowMultiKey; + } + + /** Get the storage format of the INI data. */ + bool IsMultiKey() const { return m_bAllowMultiKey; } + + /** Should data values be permitted to span multiple lines in the file. If + set to false then the multi-line construct << + SI_CHAR FORMAT + char same format as when loaded (MBCS or UTF-8) + wchar_t UTF-8 + other UTF-8 + + + Note that comments from the original data is preserved as per the + documentation on comments. The order of the sections and values + from the original file will be preserved. + + Any data prepended or appended to the output device must use the the + same format (MBCS or UTF-8). You may use the GetConverter() method to + convert text to the correct format regardless of the output format + being used by SimpleIni. + + To add a BOM to UTF-8 data, write it out manually at the very beginning + like is done in SaveFile when a_bUseBOM is true. + + @param a_oOutput Output writer to write the data to. + + @param a_bAddSignature Prepend the UTF-8 BOM if the output data is in + UTF-8 format. If it is not UTF-8 then this value is + ignored. Do not set this to true if anything has + already been written to the OutputWriter. + + @return SI_Error See error definitions + */ + SI_Error Save( + OutputWriter & a_oOutput, + bool a_bAddSignature = false + ) const; + +#ifdef SI_SUPPORT_IOSTREAMS + /** Save the INI data to an ostream. See Save() for details. + + @param a_ostream String to have the INI data appended to. + + @param a_bAddSignature Prepend the UTF-8 BOM if the output data is in + UTF-8 format. If it is not UTF-8 then this value is + ignored. Do not set this to true if anything has + already been written to the stream. + + @return SI_Error See error definitions + */ + SI_Error Save( + std::ostream & a_ostream, + bool a_bAddSignature = false + ) const + { + StreamWriter writer(a_ostream); + return Save(writer, a_bAddSignature); + } +#endif // SI_SUPPORT_IOSTREAMS + + /** Append the INI data to a string. See Save() for details. + + @param a_sBuffer String to have the INI data appended to. + + @param a_bAddSignature Prepend the UTF-8 BOM if the output data is in + UTF-8 format. If it is not UTF-8 then this value is + ignored. Do not set this to true if anything has + already been written to the string. + + @return SI_Error See error definitions + */ + SI_Error Save( + std::string & a_sBuffer, + bool a_bAddSignature = false + ) const + { + StringWriter writer(a_sBuffer); + return Save(writer, a_bAddSignature); + } + + /*-----------------------------------------------------------------------*/ + /** @} + @{ @name Accessing INI Data */ + + /** Retrieve all section names. The list is returned as an STL vector of + names and can be iterated or searched as necessary. Note that the + sort order of the returned strings is NOT DEFINED. You can sort + the names into the load order if desired. Search this file for ".sort" + for an example. + + NOTE! This structure contains only pointers to strings. The actual + string data is stored in memory owned by CSimpleIni. Ensure that the + CSimpleIni object is not destroyed or Reset() while these pointers + are in use! + + @param a_names Vector that will receive all of the section + names. See note above! + */ + void GetAllSections( + TNamesDepend & a_names + ) const; + + /** Retrieve all unique key names in a section. The sort order of the + returned strings is NOT DEFINED. You can sort the names into the load + order if desired. Search this file for ".sort" for an example. Only + unique key names are returned. + + NOTE! This structure contains only pointers to strings. The actual + string data is stored in memory owned by CSimpleIni. Ensure that the + CSimpleIni object is not destroyed or Reset() while these strings + are in use! + + @param a_pSection Section to request data for + @param a_names List that will receive all of the key + names. See note above! + + @return true Section was found. + @return false Matching section was not found. + */ + bool GetAllKeys( + const SI_CHAR * a_pSection, + TNamesDepend & a_names + ) const; + + /** Retrieve all values for a specific key. This method can be used when + multiple keys are both enabled and disabled. Note that the sort order + of the returned strings is NOT DEFINED. You can sort the names into + the load order if desired. Search this file for ".sort" for an example. + + NOTE! The returned values are pointers to string data stored in memory + owned by CSimpleIni. Ensure that the CSimpleIni object is not destroyed + or Reset while you are using this pointer! + + @param a_pSection Section to search + @param a_pKey Key to search for + @param a_values List to return if the key is not found + + @return true Key was found. + @return false Matching section/key was not found. + */ + bool GetAllValues( + const SI_CHAR * a_pSection, + const SI_CHAR * a_pKey, + TNamesDepend & a_values + ) const; + + /** Query the number of keys in a specific section. Note that if multiple + keys are enabled, then this value may be different to the number of + keys returned by GetAllKeys. + + @param a_pSection Section to request data for + + @return -1 Section does not exist in the file + @return >=0 Number of keys in the section + */ + int GetSectionSize( + const SI_CHAR * a_pSection + ) const; + + /** Retrieve all key and value pairs for a section. The data is returned + as a pointer to an STL map and can be iterated or searched as + desired. Note that multiple entries for the same key may exist when + multiple keys have been enabled. + + NOTE! This structure contains only pointers to strings. The actual + string data is stored in memory owned by CSimpleIni. Ensure that the + CSimpleIni object is not destroyed or Reset() while these strings + are in use! + + @param a_pSection Name of the section to return + @return boolean Was a section matching the supplied + name found. + */ + const TKeyVal * GetSection( + const SI_CHAR * a_pSection + ) const; + + /** Retrieve the value for a specific key. If multiple keys are enabled + (see SetMultiKey) then only the first value associated with that key + will be returned, see GetAllValues for getting all values with multikey. + + NOTE! The returned value is a pointer to string data stored in memory + owned by CSimpleIni. Ensure that the CSimpleIni object is not destroyed + or Reset while you are using this pointer! + + @param a_pSection Section to search + @param a_pKey Key to search for + @param a_pDefault Value to return if the key is not found + @param a_pHasMultiple Optionally receive notification of if there are + multiple entries for this key. + + @return a_pDefault Key was not found in the section + @return other Value of the key + */ + const SI_CHAR * GetValue( + const SI_CHAR * a_pSection, + const SI_CHAR * a_pKey, + const SI_CHAR * a_pDefault = NULL, + bool * a_pHasMultiple = NULL + ) const; + + /** Retrieve a numeric value for a specific key. If multiple keys are enabled + (see SetMultiKey) then only the first value associated with that key + will be returned, see GetAllValues for getting all values with multikey. + + @param a_pSection Section to search + @param a_pKey Key to search for + @param a_nDefault Value to return if the key is not found + @param a_pHasMultiple Optionally receive notification of if there are + multiple entries for this key. + + @return a_nDefault Key was not found in the section + @return other Value of the key + */ + long GetLongValue( + const SI_CHAR * a_pSection, + const SI_CHAR * a_pKey, + long a_nDefault = 0, + bool * a_pHasMultiple = NULL + ) const; + + /** Retrieve a boolean value for a specific key. If multiple keys are enabled + (see SetMultiKey) then only the first value associated with that key + will be returned, see GetAllValues for getting all values with multikey. + + Strings starting with "t", "y", "on" or "1" are returned as logically true. + Strings starting with "f", "n", "of" or "0" are returned as logically false. + For all other values the default is returned. Character comparisons are + case-insensitive. + + @param a_pSection Section to search + @param a_pKey Key to search for + @param a_bDefault Value to return if the key is not found + @param a_pHasMultiple Optionally receive notification of if there are + multiple entries for this key. + + @return a_nDefault Key was not found in the section + @return other Value of the key + */ + bool GetBoolValue( + const SI_CHAR * a_pSection, + const SI_CHAR * a_pKey, + bool a_bDefault = false, + bool * a_pHasMultiple = NULL + ) const; + + /** Add or update a section or value. This will always insert + when multiple keys are enabled. + + @param a_pSection Section to add or update + @param a_pKey Key to add or update. Set to NULL to + create an empty section. + @param a_pValue Value to set. Set to NULL to create an + empty section. + @param a_pComment Comment to be associated with the section or the + key. If a_pKey is NULL then it will be associated + with the section, otherwise the key. Note that a + comment may be set ONLY when the section or key is + first created (i.e. when this function returns the + value SI_INSERTED). If you wish to create a section + with a comment then you need to create the section + separately to the key. The comment string must be + in full comment form already (have a comment + character starting every line). + @param a_bForceReplace Should all existing values in a multi-key INI + file be replaced with this entry. This option has + no effect if not using multi-key files. The + difference between Delete/SetValue and SetValue + with a_bForceReplace = true, is that the load + order and comment will be preserved this way. + + @return SI_Error See error definitions + @return SI_UPDATED Value was updated + @return SI_INSERTED Value was inserted + */ + SI_Error SetValue( + const SI_CHAR * a_pSection, + const SI_CHAR * a_pKey, + const SI_CHAR * a_pValue, + const SI_CHAR * a_pComment = NULL, + bool a_bForceReplace = false + ) + { + return AddEntry(a_pSection, a_pKey, a_pValue, a_pComment, a_bForceReplace, true); + } + + /** Add or update a numeric value. This will always insert + when multiple keys are enabled. + + @param a_pSection Section to add or update + @param a_pKey Key to add or update. + @param a_nValue Value to set. + @param a_pComment Comment to be associated with the key. See the + notes on SetValue() for comments. + @param a_bUseHex By default the value will be written to the file + in decimal format. Set this to true to write it + as hexadecimal. + @param a_bForceReplace Should all existing values in a multi-key INI + file be replaced with this entry. This option has + no effect if not using multi-key files. The + difference between Delete/SetLongValue and + SetLongValue with a_bForceReplace = true, is that + the load order and comment will be preserved this + way. + + @return SI_Error See error definitions + @return SI_UPDATED Value was updated + @return SI_INSERTED Value was inserted + */ + SI_Error SetLongValue( + const SI_CHAR * a_pSection, + const SI_CHAR * a_pKey, + long a_nValue, + const SI_CHAR * a_pComment = NULL, + bool a_bUseHex = false, + bool a_bForceReplace = false + ); + + /** Add or update a boolean value. This will always insert + when multiple keys are enabled. + + @param a_pSection Section to add or update + @param a_pKey Key to add or update. + @param a_bValue Value to set. + @param a_pComment Comment to be associated with the key. See the + notes on SetValue() for comments. + @param a_bForceReplace Should all existing values in a multi-key INI + file be replaced with this entry. This option has + no effect if not using multi-key files. The + difference between Delete/SetBoolValue and + SetBoolValue with a_bForceReplace = true, is that + the load order and comment will be preserved this + way. + + @return SI_Error See error definitions + @return SI_UPDATED Value was updated + @return SI_INSERTED Value was inserted + */ + SI_Error SetBoolValue( + const SI_CHAR * a_pSection, + const SI_CHAR * a_pKey, + bool a_bValue, + const SI_CHAR * a_pComment = NULL, + bool a_bForceReplace = false + ); + + /** Delete an entire section, or a key from a section. Note that the + data returned by GetSection is invalid and must not be used after + anything has been deleted from that section using this method. + Note when multiple keys is enabled, this will delete all keys with + that name; there is no way to selectively delete individual key/values + in this situation. + + @param a_pSection Section to delete key from, or if + a_pKey is NULL, the section to remove. + @param a_pKey Key to remove from the section. Set to + NULL to remove the entire section. + @param a_bRemoveEmpty If the section is empty after this key has + been deleted, should the empty section be + removed? + + @return true Key or section was deleted. + @return false Key or section was not found. + */ + bool Delete( + const SI_CHAR * a_pSection, + const SI_CHAR * a_pKey, + bool a_bRemoveEmpty = false + ); + + /*-----------------------------------------------------------------------*/ + /** @} + @{ @name Converter */ + + /** Return a conversion object to convert text to the same encoding + as is used by the Save(), SaveFile() and SaveString() functions. + Use this to prepare the strings that you wish to append or prepend + to the output INI data. + */ + Converter GetConverter() const { + return Converter(m_bStoreIsUtf8); + } + + /*-----------------------------------------------------------------------*/ + /** @} */ + +private: + // copying is not permitted + CSimpleIniTempl(const CSimpleIniTempl &); // disabled + CSimpleIniTempl & operator=(const CSimpleIniTempl &); // disabled + + /** Parse the data looking for a file comment and store it if found. + */ + SI_Error FindFileComment( + SI_CHAR *& a_pData, + bool a_bCopyStrings + ); + + /** Parse the data looking for the next valid entry. The memory pointed to + by a_pData is modified by inserting NULL characters. The pointer is + updated to the current location in the block of text. + */ + bool FindEntry( + SI_CHAR *& a_pData, + const SI_CHAR *& a_pSection, + const SI_CHAR *& a_pKey, + const SI_CHAR *& a_pVal, + const SI_CHAR *& a_pComment + ) const; + + /** Add the section/key/value to our data. + + @param a_pSection Section name. Sections will be created if they + don't already exist. + @param a_pKey Key name. May be NULL to create an empty section. + Existing entries will be updated. New entries will + be created. + @param a_pValue Value for the key. + @param a_pComment Comment to be associated with the section or the + key. If a_pKey is NULL then it will be associated + with the section, otherwise the key. This must be + a string in full comment form already (have a + comment character starting every line). + @param a_bForceReplace Should all existing values in a multi-key INI + file be replaced with this entry. This option has + no effect if not using multi-key files. The + difference between Delete/AddEntry and AddEntry + with a_bForceReplace = true, is that the load + order and comment will be preserved this way. + @param a_bCopyStrings Should copies of the strings be made or not. + If false then the pointers will be used as is. + */ + SI_Error AddEntry( + const SI_CHAR * a_pSection, + const SI_CHAR * a_pKey, + const SI_CHAR * a_pValue, + const SI_CHAR * a_pComment, + bool a_bForceReplace, + bool a_bCopyStrings + ); + + /** Is the supplied character a whitespace character? */ + inline bool IsSpace(SI_CHAR ch) const { + return (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n'); + } + + /** Does the supplied character start a comment line? */ + inline bool IsComment(SI_CHAR ch) const { + return (ch == ';' || ch == '#'); + } + + + /** Skip over a newline character (or characters) for either DOS or UNIX */ + inline void SkipNewLine(SI_CHAR *& a_pData) const { + a_pData += (*a_pData == '\r' && *(a_pData+1) == '\n') ? 2 : 1; + } + + /** Make a copy of the supplied string, replacing the original pointer */ + SI_Error CopyString(const SI_CHAR *& a_pString); + + /** Delete a string from the copied strings buffer if necessary */ + void DeleteString(const SI_CHAR * a_pString); + + /** Internal use of our string comparison function */ + bool IsLess(const SI_CHAR * a_pLeft, const SI_CHAR * a_pRight) const { + const static SI_STRLESS isLess = SI_STRLESS(); + return isLess(a_pLeft, a_pRight); + } + + bool IsMultiLineTag(const SI_CHAR * a_pData) const; + bool IsMultiLineData(const SI_CHAR * a_pData) const; + bool LoadMultiLineText( + SI_CHAR *& a_pData, + const SI_CHAR *& a_pVal, + const SI_CHAR * a_pTagName, + bool a_bAllowBlankLinesInComment = false + ) const; + bool IsNewLineChar(SI_CHAR a_c) const; + + bool OutputMultiLineText( + OutputWriter & a_oOutput, + Converter & a_oConverter, + const SI_CHAR * a_pText + ) const; + +private: + /** Copy of the INI file data in our character format. This will be + modified when parsed to have NULL characters added after all + interesting string entries. All of the string pointers to sections, + keys and values point into this block of memory. + */ + SI_CHAR * m_pData; + + /** Length of the data that we have stored. Used when deleting strings + to determine if the string is stored here or in the allocated string + buffer. + */ + size_t m_uDataLen; + + /** File comment for this data, if one exists. */ + const SI_CHAR * m_pFileComment; + + /** Parsed INI data. Section -> (Key -> Value). */ + TSection m_data; + + /** This vector stores allocated memory for copies of strings that have + been supplied after the file load. It will be empty unless SetValue() + has been called. + */ + TNamesDepend m_strings; + + /** Is the format of our datafile UTF-8 or MBCS? */ + bool m_bStoreIsUtf8; + + /** Are multiple values permitted for the same key? */ + bool m_bAllowMultiKey; + + /** Are data values permitted to span multiple lines? */ + bool m_bAllowMultiLine; + + /** Should spaces be written out surrounding the equals sign? */ + bool m_bSpaces; + + /** Next order value, used to ensure sections and keys are output in the + same order that they are loaded/added. + */ + int m_nOrder; +}; + +// --------------------------------------------------------------------------- +// IMPLEMENTATION +// --------------------------------------------------------------------------- + +template +CSimpleIniTempl::CSimpleIniTempl( + bool a_bIsUtf8, + bool a_bAllowMultiKey, + bool a_bAllowMultiLine + ) + : m_pData(0) + , m_uDataLen(0) + , m_pFileComment(NULL) + , m_bStoreIsUtf8(a_bIsUtf8) + , m_bAllowMultiKey(a_bAllowMultiKey) + , m_bAllowMultiLine(a_bAllowMultiLine) + , m_bSpaces(true) + , m_nOrder(0) +{ } + +template +CSimpleIniTempl::~CSimpleIniTempl() +{ + Reset(); +} + +template +void +CSimpleIniTempl::Reset() +{ + // remove all data + delete[] m_pData; + m_pData = NULL; + m_uDataLen = 0; + m_pFileComment = NULL; + if (!m_data.empty()) { + m_data.erase(m_data.begin(), m_data.end()); + } + + // remove all strings + if (!m_strings.empty()) { + typename TNamesDepend::iterator i = m_strings.begin(); + for (; i != m_strings.end(); ++i) { + delete[] const_cast(i->pItem); + } + m_strings.erase(m_strings.begin(), m_strings.end()); + } +} + +template +SI_Error +CSimpleIniTempl::LoadFile( + const char * a_pszFile + ) +{ + FILE * fp = NULL; +#if __STDC_WANT_SECURE_LIB__ && !_WIN32_WCE + fopen_s(&fp, a_pszFile, "rb"); +#else // !__STDC_WANT_SECURE_LIB__ + fp = fopen(a_pszFile, "rb"); +#endif // __STDC_WANT_SECURE_LIB__ + if (!fp) { + return SI_FILE; + } + SI_Error rc = LoadFile(fp); + fclose(fp); + return rc; +} + +#ifdef SI_HAS_WIDE_FILE +template +SI_Error +CSimpleIniTempl::LoadFile( + const SI_WCHAR_T * a_pwszFile + ) +{ +#ifdef _WIN32 + FILE * fp = NULL; +#if __STDC_WANT_SECURE_LIB__ && !_WIN32_WCE + _wfopen_s(&fp, a_pwszFile, L"rb"); +#else // !__STDC_WANT_SECURE_LIB__ + fp = _wfopen(a_pwszFile, L"rb"); +#endif // __STDC_WANT_SECURE_LIB__ + if (!fp) return SI_FILE; + SI_Error rc = LoadFile(fp); + fclose(fp); + return rc; +#else // !_WIN32 (therefore SI_CONVERT_ICU) + char szFile[256]; + u_austrncpy(szFile, a_pwszFile, sizeof(szFile)); + return LoadFile(szFile); +#endif // _WIN32 +} +#endif // SI_HAS_WIDE_FILE + +template +SI_Error +CSimpleIniTempl::LoadFile( + FILE * a_fpFile + ) +{ + // load the raw file data + int retval = fseek(a_fpFile, 0, SEEK_END); + if (retval != 0) { + return SI_FILE; + } + long lSize = ftell(a_fpFile); + if (lSize < 0) { + return SI_FILE; + } + if (lSize == 0) { + return SI_OK; + } + char * pData = new char[lSize]; + if (!pData) { + return SI_NOMEM; + } + fseek(a_fpFile, 0, SEEK_SET); + size_t uRead = fread(pData, sizeof(char), lSize, a_fpFile); + if (uRead != (size_t) lSize) { + delete[] pData; + return SI_FILE; + } + + // convert the raw data to unicode + SI_Error rc = Load(pData, uRead); + delete[] pData; + return rc; +} + +template +SI_Error +CSimpleIniTempl::Load( + const char * a_pData, + size_t a_uDataLen + ) +{ + SI_CONVERTER converter(m_bStoreIsUtf8); + + if (a_uDataLen == 0) { + return SI_OK; + } + + // consume the UTF-8 BOM if it exists + if (m_bStoreIsUtf8 && a_uDataLen >= 3) { + if (memcmp(a_pData, SI_UTF8_SIGNATURE, 3) == 0) { + a_pData += 3; + a_uDataLen -= 3; + } + } + + // determine the length of the converted data + size_t uLen = converter.SizeFromStore(a_pData, a_uDataLen); + if (uLen == (size_t)(-1)) { + return SI_FAIL; + } + + // allocate memory for the data, ensure that there is a NULL + // terminator wherever the converted data ends + SI_CHAR * pData = new SI_CHAR[uLen+1]; + if (!pData) { + return SI_NOMEM; + } + memset(pData, 0, sizeof(SI_CHAR)*(uLen+1)); + + // convert the data + if (!converter.ConvertFromStore(a_pData, a_uDataLen, pData, uLen)) { + delete[] pData; + return SI_FAIL; + } + + // parse it + const static SI_CHAR empty = 0; + SI_CHAR * pWork = pData; + const SI_CHAR * pSection = ∅ + const SI_CHAR * pItem = NULL; + const SI_CHAR * pVal = NULL; + const SI_CHAR * pComment = NULL; + + // We copy the strings if we are loading data into this class when we + // already have stored some. + bool bCopyStrings = (m_pData != NULL); + + // find a file comment if it exists, this is a comment that starts at the + // beginning of the file and continues until the first blank line. + SI_Error rc = FindFileComment(pWork, bCopyStrings); + if (rc < 0) return rc; + + // add every entry in the file to the data table + while (FindEntry(pWork, pSection, pItem, pVal, pComment)) { + rc = AddEntry(pSection, pItem, pVal, pComment, false, bCopyStrings); + if (rc < 0) return rc; + } + + // store these strings if we didn't copy them + if (bCopyStrings) { + delete[] pData; + } + else { + m_pData = pData; + m_uDataLen = uLen+1; + } + + return SI_OK; +} + +#ifdef SI_SUPPORT_IOSTREAMS +template +SI_Error +CSimpleIniTempl::Load( + std::istream & a_istream + ) +{ + std::string strData; + char szBuf[512]; + do { + a_istream.get(szBuf, sizeof(szBuf), '\0'); + strData.append(szBuf); + } + while (a_istream.good()); + return Load(strData); +} +#endif // SI_SUPPORT_IOSTREAMS + +template +SI_Error +CSimpleIniTempl::FindFileComment( + SI_CHAR *& a_pData, + bool a_bCopyStrings + ) +{ + // there can only be a single file comment + if (m_pFileComment) { + return SI_OK; + } + + // Load the file comment as multi-line text, this will modify all of + // the newline characters to be single \n chars + if (!LoadMultiLineText(a_pData, m_pFileComment, NULL, false)) { + return SI_OK; + } + + // copy the string if necessary + if (a_bCopyStrings) { + SI_Error rc = CopyString(m_pFileComment); + if (rc < 0) return rc; + } + + return SI_OK; +} + +template +bool +CSimpleIniTempl::FindEntry( + SI_CHAR *& a_pData, + const SI_CHAR *& a_pSection, + const SI_CHAR *& a_pKey, + const SI_CHAR *& a_pVal, + const SI_CHAR *& a_pComment + ) const +{ + a_pComment = NULL; + + SI_CHAR * pTrail = NULL; + while (*a_pData) { + // skip spaces and empty lines + while (*a_pData && IsSpace(*a_pData)) { + ++a_pData; + } + if (!*a_pData) { + break; + } + + // skip processing of comment lines but keep a pointer to + // the start of the comment. + if (IsComment(*a_pData)) { + LoadMultiLineText(a_pData, a_pComment, NULL, true); + continue; + } + + // process section names + if (*a_pData == '[') { + // skip leading spaces + ++a_pData; + while (*a_pData && IsSpace(*a_pData)) { + ++a_pData; + } + + // find the end of the section name (it may contain spaces) + // and convert it to lowercase as necessary + a_pSection = a_pData; + while (*a_pData && *a_pData != ']' && !IsNewLineChar(*a_pData)) { + ++a_pData; + } + + // if it's an invalid line, just skip it + if (*a_pData != ']') { + continue; + } + + // remove trailing spaces from the section + pTrail = a_pData - 1; + while (pTrail >= a_pSection && IsSpace(*pTrail)) { + --pTrail; + } + ++pTrail; + *pTrail = 0; + + // skip to the end of the line + ++a_pData; // safe as checked that it == ']' above + while (*a_pData && !IsNewLineChar(*a_pData)) { + ++a_pData; + } + + a_pKey = NULL; + a_pVal = NULL; + return true; + } + + // find the end of the key name (it may contain spaces) + // and convert it to lowercase as necessary + a_pKey = a_pData; + while (*a_pData && *a_pData != '=' && !IsNewLineChar(*a_pData)) { + ++a_pData; + } + + // if it's an invalid line, just skip it + if (*a_pData != '=') { + continue; + } + + // empty keys are invalid + if (a_pKey == a_pData) { + while (*a_pData && !IsNewLineChar(*a_pData)) { + ++a_pData; + } + continue; + } + + // remove trailing spaces from the key + pTrail = a_pData - 1; + while (pTrail >= a_pKey && IsSpace(*pTrail)) { + --pTrail; + } + ++pTrail; + *pTrail = 0; + + // skip leading whitespace on the value + ++a_pData; // safe as checked that it == '=' above + while (*a_pData && !IsNewLineChar(*a_pData) && IsSpace(*a_pData)) { + ++a_pData; + } + + // find the end of the value which is the end of this line + a_pVal = a_pData; + while (*a_pData && !IsNewLineChar(*a_pData)) { + ++a_pData; + } + + // remove trailing spaces from the value + pTrail = a_pData - 1; + if (*a_pData) { // prepare for the next round + SkipNewLine(a_pData); + } + while (pTrail >= a_pVal && IsSpace(*pTrail)) { + --pTrail; + } + ++pTrail; + *pTrail = 0; + + // check for multi-line entries + if (m_bAllowMultiLine && IsMultiLineTag(a_pVal)) { + // skip the "<<<" to get the tag that will end the multiline + const SI_CHAR * pTagName = a_pVal + 3; + return LoadMultiLineText(a_pData, a_pVal, pTagName); + } + + // return the standard entry + return true; + } + + return false; +} + +template +bool +CSimpleIniTempl::IsMultiLineTag( + const SI_CHAR * a_pVal + ) const +{ + // check for the "<<<" prefix for a multi-line entry + if (*a_pVal++ != '<') return false; + if (*a_pVal++ != '<') return false; + if (*a_pVal++ != '<') return false; + return true; +} + +template +bool +CSimpleIniTempl::IsMultiLineData( + const SI_CHAR * a_pData + ) const +{ + // data is multi-line if it has any of the following features: + // * whitespace prefix + // * embedded newlines + // * whitespace suffix + + // empty string + if (!*a_pData) { + return false; + } + + // check for prefix + if (IsSpace(*a_pData)) { + return true; + } + + // embedded newlines + while (*a_pData) { + if (IsNewLineChar(*a_pData)) { + return true; + } + ++a_pData; + } + + // check for suffix + if (IsSpace(*--a_pData)) { + return true; + } + + return false; +} + +template +bool +CSimpleIniTempl::IsNewLineChar( + SI_CHAR a_c + ) const +{ + return (a_c == '\n' || a_c == '\r'); +} + +template +bool +CSimpleIniTempl::LoadMultiLineText( + SI_CHAR *& a_pData, + const SI_CHAR *& a_pVal, + const SI_CHAR * a_pTagName, + bool a_bAllowBlankLinesInComment + ) const +{ + // we modify this data to strip all newlines down to a single '\n' + // character. This means that on Windows we need to strip out some + // characters which will make the data shorter. + // i.e. LINE1-LINE1\r\nLINE2-LINE2\0 will become + // LINE1-LINE1\nLINE2-LINE2\0 + // The pDataLine entry is the pointer to the location in memory that + // the current line needs to start to run following the existing one. + // This may be the same as pCurrLine in which case no move is needed. + SI_CHAR * pDataLine = a_pData; + SI_CHAR * pCurrLine; + + // value starts at the current line + a_pVal = a_pData; + + // find the end tag. This tag must start in column 1 and be + // followed by a newline. No whitespace removal is done while + // searching for this tag. + SI_CHAR cEndOfLineChar = *a_pData; + for(;;) { + // if we are loading comments then we need a comment character as + // the first character on every line + if (!a_pTagName && !IsComment(*a_pData)) { + // if we aren't allowing blank lines then we're done + if (!a_bAllowBlankLinesInComment) { + break; + } + + // if we are allowing blank lines then we only include them + // in this comment if another comment follows, so read ahead + // to find out. + SI_CHAR * pCurr = a_pData; + int nNewLines = 0; + while (IsSpace(*pCurr)) { + if (IsNewLineChar(*pCurr)) { + ++nNewLines; + SkipNewLine(pCurr); + } + else { + ++pCurr; + } + } + + // we have a comment, add the blank lines to the output + // and continue processing from here + if (IsComment(*pCurr)) { + for (; nNewLines > 0; --nNewLines) *pDataLine++ = '\n'; + a_pData = pCurr; + continue; + } + + // the comment ends here + break; + } + + // find the end of this line + pCurrLine = a_pData; + while (*a_pData && !IsNewLineChar(*a_pData)) ++a_pData; + + // move this line down to the location that it should be if necessary + if (pDataLine < pCurrLine) { + size_t nLen = (size_t) (a_pData - pCurrLine); + memmove(pDataLine, pCurrLine, nLen * sizeof(SI_CHAR)); + pDataLine[nLen] = '\0'; + } + + // end the line with a NULL + cEndOfLineChar = *a_pData; + *a_pData = 0; + + // if are looking for a tag then do the check now. This is done before + // checking for end of the data, so that if we have the tag at the end + // of the data then the tag is removed correctly. + if (a_pTagName && + (!IsLess(pDataLine, a_pTagName) && !IsLess(a_pTagName, pDataLine))) + { + break; + } + + // if we are at the end of the data then we just automatically end + // this entry and return the current data. + if (!cEndOfLineChar) { + return true; + } + + // otherwise we need to process this newline to ensure that it consists + // of just a single \n character. + pDataLine += (a_pData - pCurrLine); + *a_pData = cEndOfLineChar; + SkipNewLine(a_pData); + *pDataLine++ = '\n'; + } + + // if we didn't find a comment at all then return false + if (a_pVal == a_pData) { + a_pVal = NULL; + return false; + } + + // the data (which ends at the end of the last line) needs to be + // null-terminated BEFORE before the newline character(s). If the + // user wants a new line in the multi-line data then they need to + // add an empty line before the tag. + *--pDataLine = '\0'; + + // if looking for a tag and if we aren't at the end of the data, + // then move a_pData to the start of the next line. + if (a_pTagName && cEndOfLineChar) { + SI_ASSERT(IsNewLineChar(cEndOfLineChar)); + *a_pData = cEndOfLineChar; + SkipNewLine(a_pData); + } + + return true; +} + +template +SI_Error +CSimpleIniTempl::CopyString( + const SI_CHAR *& a_pString + ) +{ + size_t uLen = 0; + if (sizeof(SI_CHAR) == sizeof(char)) { + uLen = strlen((const char *)a_pString); + } + else if (sizeof(SI_CHAR) == sizeof(wchar_t)) { + uLen = wcslen((const wchar_t *)a_pString); + } + else { + for ( ; a_pString[uLen]; ++uLen) /*loop*/ ; + } + ++uLen; // NULL character + SI_CHAR * pCopy = new SI_CHAR[uLen]; + if (!pCopy) { + return SI_NOMEM; + } + memcpy(pCopy, a_pString, sizeof(SI_CHAR)*uLen); + m_strings.push_back(pCopy); + a_pString = pCopy; + return SI_OK; +} + +template +SI_Error +CSimpleIniTempl::AddEntry( + const SI_CHAR * a_pSection, + const SI_CHAR * a_pKey, + const SI_CHAR * a_pValue, + const SI_CHAR * a_pComment, + bool a_bForceReplace, + bool a_bCopyStrings + ) +{ + SI_Error rc; + bool bInserted = false; + + SI_ASSERT(!a_pComment || IsComment(*a_pComment)); + + // if we are copying strings then make a copy of the comment now + // because we will need it when we add the entry. + if (a_bCopyStrings && a_pComment) { + rc = CopyString(a_pComment); + if (rc < 0) return rc; + } + + // create the section entry if necessary + typename TSection::iterator iSection = m_data.find(a_pSection); + if (iSection == m_data.end()) { + // if the section doesn't exist then we need a copy as the + // string needs to last beyond the end of this function + if (a_bCopyStrings) { + rc = CopyString(a_pSection); + if (rc < 0) return rc; + } + + // only set the comment if this is a section only entry + Entry oSection(a_pSection, ++m_nOrder); + if (a_pComment && (!a_pKey || !a_pValue)) { + oSection.pComment = a_pComment; + } + + typename TSection::value_type oEntry(oSection, TKeyVal()); + typedef typename TSection::iterator SectionIterator; + std::pair i = m_data.insert(oEntry); + iSection = i.first; + bInserted = true; + } + if (!a_pKey || !a_pValue) { + // section only entries are specified with pItem and pVal as NULL + return bInserted ? SI_INSERTED : SI_UPDATED; + } + + // check for existence of the key + TKeyVal & keyval = iSection->second; + typename TKeyVal::iterator iKey = keyval.find(a_pKey); + + // remove all existing entries but save the load order and + // comment of the first entry + int nLoadOrder = ++m_nOrder; + if (iKey != keyval.end() && m_bAllowMultiKey && a_bForceReplace) { + const SI_CHAR * pComment = NULL; + while (iKey != keyval.end() && !IsLess(a_pKey, iKey->first.pItem)) { + if (iKey->first.nOrder < nLoadOrder) { + nLoadOrder = iKey->first.nOrder; + pComment = iKey->first.pComment; + } + ++iKey; + } + if (pComment) { + DeleteString(a_pComment); + a_pComment = pComment; + CopyString(a_pComment); + } + Delete(a_pSection, a_pKey); + iKey = keyval.end(); + } + + // make string copies if necessary + bool bForceCreateNewKey = m_bAllowMultiKey && !a_bForceReplace; + if (a_bCopyStrings) { + if (bForceCreateNewKey || iKey == keyval.end()) { + // if the key doesn't exist then we need a copy as the + // string needs to last beyond the end of this function + // because we will be inserting the key next + rc = CopyString(a_pKey); + if (rc < 0) return rc; + } + + // we always need a copy of the value + rc = CopyString(a_pValue); + if (rc < 0) return rc; + } + + // create the key entry + if (iKey == keyval.end() || bForceCreateNewKey) { + Entry oKey(a_pKey, nLoadOrder); + if (a_pComment) { + oKey.pComment = a_pComment; + } + typename TKeyVal::value_type oEntry(oKey, (const SI_CHAR *) NULL); + iKey = keyval.insert(oEntry); + bInserted = true; + } + iKey->second = a_pValue; + return bInserted ? SI_INSERTED : SI_UPDATED; +} + +template +const SI_CHAR * +CSimpleIniTempl::GetValue( + const SI_CHAR * a_pSection, + const SI_CHAR * a_pKey, + const SI_CHAR * a_pDefault, + bool * a_pHasMultiple + ) const +{ + if (a_pHasMultiple) { + *a_pHasMultiple = false; + } + if (!a_pSection || !a_pKey) { + return a_pDefault; + } + typename TSection::const_iterator iSection = m_data.find(a_pSection); + if (iSection == m_data.end()) { + return a_pDefault; + } + typename TKeyVal::const_iterator iKeyVal = iSection->second.find(a_pKey); + if (iKeyVal == iSection->second.end()) { + return a_pDefault; + } + + // check for multiple entries with the same key + if (m_bAllowMultiKey && a_pHasMultiple) { + typename TKeyVal::const_iterator iTemp = iKeyVal; + if (++iTemp != iSection->second.end()) { + if (!IsLess(a_pKey, iTemp->first.pItem)) { + *a_pHasMultiple = true; + } + } + } + + return iKeyVal->second; +} + +template +long +CSimpleIniTempl::GetLongValue( + const SI_CHAR * a_pSection, + const SI_CHAR * a_pKey, + long a_nDefault, + bool * a_pHasMultiple + ) const +{ + // return the default if we don't have a value + const SI_CHAR * pszValue = GetValue(a_pSection, a_pKey, NULL, a_pHasMultiple); + if (!pszValue || !*pszValue) return a_nDefault; + + // convert to UTF-8/MBCS which for a numeric value will be the same as ASCII + char szValue[64] = { 0 }; + SI_CONVERTER c(m_bStoreIsUtf8); + if (!c.ConvertToStore(pszValue, szValue, sizeof(szValue))) { + return a_nDefault; + } + + // handle the value as hex if prefaced with "0x" + long nValue = a_nDefault; + char * pszSuffix = szValue; + if (szValue[0] == '0' && (szValue[1] == 'x' || szValue[1] == 'X')) { + if (!szValue[2]) return a_nDefault; + nValue = strtol(&szValue[2], &pszSuffix, 16); + } + else { + nValue = strtol(szValue, &pszSuffix, 10); + } + + // any invalid strings will return the default value + if (*pszSuffix) { + return a_nDefault; + } + + return nValue; +} + +template +SI_Error +CSimpleIniTempl::SetLongValue( + const SI_CHAR * a_pSection, + const SI_CHAR * a_pKey, + long a_nValue, + const SI_CHAR * a_pComment, + bool a_bUseHex, + bool a_bForceReplace + ) +{ + // use SetValue to create sections + if (!a_pSection || !a_pKey) return SI_FAIL; + + // convert to an ASCII string + char szInput[64]; +#if __STDC_WANT_SECURE_LIB__ && !_WIN32_WCE + sprintf_s(szInput, a_bUseHex ? "0x%lx" : "%ld", a_nValue); +#else // !__STDC_WANT_SECURE_LIB__ + sprintf(szInput, a_bUseHex ? "0x%lx" : "%ld", a_nValue); +#endif // __STDC_WANT_SECURE_LIB__ + + // convert to output text + SI_CHAR szOutput[64]; + SI_CONVERTER c(m_bStoreIsUtf8); + c.ConvertFromStore(szInput, strlen(szInput) + 1, + szOutput, sizeof(szOutput) / sizeof(SI_CHAR)); + + // actually add it + return AddEntry(a_pSection, a_pKey, szOutput, a_pComment, a_bForceReplace, true); +} + +template +bool +CSimpleIniTempl::GetBoolValue( + const SI_CHAR * a_pSection, + const SI_CHAR * a_pKey, + bool a_bDefault, + bool * a_pHasMultiple + ) const +{ + // return the default if we don't have a value + const SI_CHAR * pszValue = GetValue(a_pSection, a_pKey, NULL, a_pHasMultiple); + if (!pszValue || !*pszValue) return a_bDefault; + + // we only look at the minimum number of characters + switch (pszValue[0]) { + case 't': case 'T': // true + case 'y': case 'Y': // yes + case '1': // 1 (one) + return true; + + case 'f': case 'F': // false + case 'n': case 'N': // no + case '0': // 0 (zero) + return false; + + case 'o': case 'O': + if (pszValue[1] == 'n' || pszValue[1] == 'N') return true; // on + if (pszValue[1] == 'f' || pszValue[1] == 'F') return false; // off + break; + } + + // no recognized value, return the default + return a_bDefault; +} + +template +SI_Error +CSimpleIniTempl::SetBoolValue( + const SI_CHAR * a_pSection, + const SI_CHAR * a_pKey, + bool a_bValue, + const SI_CHAR * a_pComment, + bool a_bForceReplace + ) +{ + // use SetValue to create sections + if (!a_pSection || !a_pKey) return SI_FAIL; + + // convert to an ASCII string + const char * pszInput = a_bValue ? "true" : "false"; + + // convert to output text + SI_CHAR szOutput[64]; + SI_CONVERTER c(m_bStoreIsUtf8); + c.ConvertFromStore(pszInput, strlen(pszInput) + 1, + szOutput, sizeof(szOutput) / sizeof(SI_CHAR)); + + // actually add it + return AddEntry(a_pSection, a_pKey, szOutput, a_pComment, a_bForceReplace, true); +} + +template +bool +CSimpleIniTempl::GetAllValues( + const SI_CHAR * a_pSection, + const SI_CHAR * a_pKey, + TNamesDepend & a_values + ) const +{ + a_values.clear(); + + if (!a_pSection || !a_pKey) { + return false; + } + typename TSection::const_iterator iSection = m_data.find(a_pSection); + if (iSection == m_data.end()) { + return false; + } + typename TKeyVal::const_iterator iKeyVal = iSection->second.find(a_pKey); + if (iKeyVal == iSection->second.end()) { + return false; + } + + // insert all values for this key + a_values.push_back(Entry(iKeyVal->second, iKeyVal->first.pComment, iKeyVal->first.nOrder)); + if (m_bAllowMultiKey) { + ++iKeyVal; + while (iKeyVal != iSection->second.end() && !IsLess(a_pKey, iKeyVal->first.pItem)) { + a_values.push_back(Entry(iKeyVal->second, iKeyVal->first.pComment, iKeyVal->first.nOrder)); + ++iKeyVal; + } + } + + return true; +} + +template +int +CSimpleIniTempl::GetSectionSize( + const SI_CHAR * a_pSection + ) const +{ + if (!a_pSection) { + return -1; + } + + typename TSection::const_iterator iSection = m_data.find(a_pSection); + if (iSection == m_data.end()) { + return -1; + } + const TKeyVal & section = iSection->second; + + // if multi-key isn't permitted then the section size is + // the number of keys that we have. + if (!m_bAllowMultiKey || section.empty()) { + return (int) section.size(); + } + + // otherwise we need to count them + int nCount = 0; + const SI_CHAR * pLastKey = NULL; + typename TKeyVal::const_iterator iKeyVal = section.begin(); + for (int n = 0; iKeyVal != section.end(); ++iKeyVal, ++n) { + if (!pLastKey || IsLess(pLastKey, iKeyVal->first.pItem)) { + ++nCount; + pLastKey = iKeyVal->first.pItem; + } + } + return nCount; +} + +template +const typename CSimpleIniTempl::TKeyVal * +CSimpleIniTempl::GetSection( + const SI_CHAR * a_pSection + ) const +{ + if (a_pSection) { + typename TSection::const_iterator i = m_data.find(a_pSection); + if (i != m_data.end()) { + return &(i->second); + } + } + return 0; +} + +template +void +CSimpleIniTempl::GetAllSections( + TNamesDepend & a_names + ) const +{ + a_names.clear(); + typename TSection::const_iterator i = m_data.begin(); + for (int n = 0; i != m_data.end(); ++i, ++n ) { + a_names.push_back(i->first); + } +} + +template +bool +CSimpleIniTempl::GetAllKeys( + const SI_CHAR * a_pSection, + TNamesDepend & a_names + ) const +{ + a_names.clear(); + + if (!a_pSection) { + return false; + } + + typename TSection::const_iterator iSection = m_data.find(a_pSection); + if (iSection == m_data.end()) { + return false; + } + + const TKeyVal & section = iSection->second; + const SI_CHAR * pLastKey = NULL; + typename TKeyVal::const_iterator iKeyVal = section.begin(); + for (int n = 0; iKeyVal != section.end(); ++iKeyVal, ++n ) { + if (!pLastKey || IsLess(pLastKey, iKeyVal->first.pItem)) { + a_names.push_back(iKeyVal->first); + pLastKey = iKeyVal->first.pItem; + } + } + + return true; +} + +template +SI_Error +CSimpleIniTempl::SaveFile( + const char * a_pszFile, + bool a_bAddSignature + ) const +{ + FILE * fp = NULL; +#if __STDC_WANT_SECURE_LIB__ && !_WIN32_WCE + fopen_s(&fp, a_pszFile, "wb"); +#else // !__STDC_WANT_SECURE_LIB__ + fp = fopen(a_pszFile, "wb"); +#endif // __STDC_WANT_SECURE_LIB__ + if (!fp) return SI_FILE; + SI_Error rc = SaveFile(fp, a_bAddSignature); + fclose(fp); + return rc; +} + +#ifdef SI_HAS_WIDE_FILE +template +SI_Error +CSimpleIniTempl::SaveFile( + const SI_WCHAR_T * a_pwszFile, + bool a_bAddSignature + ) const +{ +#ifdef _WIN32 + FILE * fp = NULL; +#if __STDC_WANT_SECURE_LIB__ && !_WIN32_WCE + _wfopen_s(&fp, a_pwszFile, L"wb"); +#else // !__STDC_WANT_SECURE_LIB__ + fp = _wfopen(a_pwszFile, L"wb"); +#endif // __STDC_WANT_SECURE_LIB__ + if (!fp) return SI_FILE; + SI_Error rc = SaveFile(fp, a_bAddSignature); + fclose(fp); + return rc; +#else // !_WIN32 (therefore SI_CONVERT_ICU) + char szFile[256]; + u_austrncpy(szFile, a_pwszFile, sizeof(szFile)); + return SaveFile(szFile, a_bAddSignature); +#endif // _WIN32 +} +#endif // SI_HAS_WIDE_FILE + +template +SI_Error +CSimpleIniTempl::SaveFile( + FILE * a_pFile, + bool a_bAddSignature + ) const +{ + FileWriter writer(a_pFile); + return Save(writer, a_bAddSignature); +} + +template +SI_Error +CSimpleIniTempl::Save( + OutputWriter & a_oOutput, + bool a_bAddSignature + ) const +{ + Converter convert(m_bStoreIsUtf8); + + // add the UTF-8 signature if it is desired + if (m_bStoreIsUtf8 && a_bAddSignature) { + a_oOutput.Write(SI_UTF8_SIGNATURE); + } + + // get all of the sections sorted in load order + TNamesDepend oSections; + GetAllSections(oSections); +#if defined(_MSC_VER) && _MSC_VER <= 1200 + oSections.sort(); +#elif defined(__BORLANDC__) + oSections.sort(Entry::LoadOrder()); +#else + oSections.sort(typename Entry::LoadOrder()); +#endif + + // write the file comment if we have one + bool bNeedNewLine = false; + if (m_pFileComment) { + if (!OutputMultiLineText(a_oOutput, convert, m_pFileComment)) { + return SI_FAIL; + } + bNeedNewLine = true; + } + + // iterate through our sections and output the data + typename TNamesDepend::const_iterator iSection = oSections.begin(); + for ( ; iSection != oSections.end(); ++iSection ) { + // write out the comment if there is one + if (iSection->pComment) { + if (bNeedNewLine) { + a_oOutput.Write(SI_NEWLINE_A); + a_oOutput.Write(SI_NEWLINE_A); + } + if (!OutputMultiLineText(a_oOutput, convert, iSection->pComment)) { + return SI_FAIL; + } + bNeedNewLine = false; + } + + if (bNeedNewLine) { + a_oOutput.Write(SI_NEWLINE_A); + a_oOutput.Write(SI_NEWLINE_A); + bNeedNewLine = false; + } + + // write the section (unless there is no section name) + if (*iSection->pItem) { + if (!convert.ConvertToStore(iSection->pItem)) { + return SI_FAIL; + } + a_oOutput.Write("["); + a_oOutput.Write(convert.Data()); + a_oOutput.Write("]"); + a_oOutput.Write(SI_NEWLINE_A); + } + + // get all of the keys sorted in load order + TNamesDepend oKeys; + GetAllKeys(iSection->pItem, oKeys); +#if defined(_MSC_VER) && _MSC_VER <= 1200 + oKeys.sort(); +#elif defined(__BORLANDC__) + oKeys.sort(Entry::LoadOrder()); +#else + oKeys.sort(typename Entry::LoadOrder()); +#endif + + // write all keys and values + typename TNamesDepend::const_iterator iKey = oKeys.begin(); + for ( ; iKey != oKeys.end(); ++iKey) { + // get all values for this key + TNamesDepend oValues; + GetAllValues(iSection->pItem, iKey->pItem, oValues); + + typename TNamesDepend::const_iterator iValue = oValues.begin(); + for ( ; iValue != oValues.end(); ++iValue) { + // write out the comment if there is one + if (iValue->pComment) { + a_oOutput.Write(SI_NEWLINE_A); + if (!OutputMultiLineText(a_oOutput, convert, iValue->pComment)) { + return SI_FAIL; + } + } + + // write the key + if (!convert.ConvertToStore(iKey->pItem)) { + return SI_FAIL; + } + a_oOutput.Write(convert.Data()); + + // write the value + if (!convert.ConvertToStore(iValue->pItem)) { + return SI_FAIL; + } + a_oOutput.Write(m_bSpaces ? " = " : "="); + if (m_bAllowMultiLine && IsMultiLineData(iValue->pItem)) { + // multi-line data needs to be processed specially to ensure + // that we use the correct newline format for the current system + a_oOutput.Write("<<pItem)) { + return SI_FAIL; + } + a_oOutput.Write("SI-END-OF-MULTILINE-TEXT"); + } + else { + a_oOutput.Write(convert.Data()); + } + a_oOutput.Write(SI_NEWLINE_A); + } + } + + bNeedNewLine = true; + } + + return SI_OK; +} + +template +bool +CSimpleIniTempl::OutputMultiLineText( + OutputWriter & a_oOutput, + Converter & a_oConverter, + const SI_CHAR * a_pText + ) const +{ + const SI_CHAR * pEndOfLine; + SI_CHAR cEndOfLineChar = *a_pText; + while (cEndOfLineChar) { + // find the end of this line + pEndOfLine = a_pText; + for (; *pEndOfLine && *pEndOfLine != '\n'; ++pEndOfLine) /*loop*/ ; + cEndOfLineChar = *pEndOfLine; + + // temporarily null terminate, convert and output the line + *const_cast(pEndOfLine) = 0; + if (!a_oConverter.ConvertToStore(a_pText)) { + return false; + } + *const_cast(pEndOfLine) = cEndOfLineChar; + a_pText += (pEndOfLine - a_pText) + 1; + a_oOutput.Write(a_oConverter.Data()); + a_oOutput.Write(SI_NEWLINE_A); + } + return true; +} + +template +bool +CSimpleIniTempl::Delete( + const SI_CHAR * a_pSection, + const SI_CHAR * a_pKey, + bool a_bRemoveEmpty + ) +{ + if (!a_pSection) { + return false; + } + + typename TSection::iterator iSection = m_data.find(a_pSection); + if (iSection == m_data.end()) { + return false; + } + + // remove a single key if we have a keyname + if (a_pKey) { + typename TKeyVal::iterator iKeyVal = iSection->second.find(a_pKey); + if (iKeyVal == iSection->second.end()) { + return false; + } + + // remove any copied strings and then the key + typename TKeyVal::iterator iDelete; + do { + iDelete = iKeyVal++; + + DeleteString(iDelete->first.pItem); + DeleteString(iDelete->second); + iSection->second.erase(iDelete); + } + while (iKeyVal != iSection->second.end() + && !IsLess(a_pKey, iKeyVal->first.pItem)); + + // done now if the section is not empty or we are not pruning away + // the empty sections. Otherwise let it fall through into the section + // deletion code + if (!a_bRemoveEmpty || !iSection->second.empty()) { + return true; + } + } + else { + // delete all copied strings from this section. The actual + // entries will be removed when the section is removed. + typename TKeyVal::iterator iKeyVal = iSection->second.begin(); + for ( ; iKeyVal != iSection->second.end(); ++iKeyVal) { + DeleteString(iKeyVal->first.pItem); + DeleteString(iKeyVal->second); + } + } + + // delete the section itself + DeleteString(iSection->first.pItem); + m_data.erase(iSection); + + return true; +} + +template +void +CSimpleIniTempl::DeleteString( + const SI_CHAR * a_pString + ) +{ + // strings may exist either inside the data block, or they will be + // individually allocated and stored in m_strings. We only physically + // delete those stored in m_strings. + if (a_pString < m_pData || a_pString >= m_pData + m_uDataLen) { + typename TNamesDepend::iterator i = m_strings.begin(); + for (;i != m_strings.end(); ++i) { + if (a_pString == i->pItem) { + delete[] const_cast(i->pItem); + m_strings.erase(i); + break; + } + } + } +} + +// --------------------------------------------------------------------------- +// CONVERSION FUNCTIONS +// --------------------------------------------------------------------------- + +// Defines the conversion classes for different libraries. Before including +// SimpleIni.h, set the converter that you wish you use by defining one of the +// following symbols. +// +// SI_CONVERT_GENERIC Use the Unicode reference conversion library in +// the accompanying files ConvertUTF.h/c +// SI_CONVERT_ICU Use the IBM ICU conversion library. Requires +// ICU headers on include path and icuuc.lib +// SI_CONVERT_WIN32 Use the Win32 API functions for conversion. + +#if !defined(SI_CONVERT_GENERIC) && !defined(SI_CONVERT_WIN32) && !defined(SI_CONVERT_ICU) +# ifdef _WIN32 +# define SI_CONVERT_WIN32 +# else +# define SI_CONVERT_GENERIC +# endif +#endif + +/** + * Generic case-sensitive less than comparison. This class returns numerically + * ordered ASCII case-sensitive text for all possible sizes and types of + * SI_CHAR. + */ +template +struct SI_GenericCase { + bool operator()(const SI_CHAR * pLeft, const SI_CHAR * pRight) const { + long cmp; + for ( ;*pLeft && *pRight; ++pLeft, ++pRight) { + cmp = (long) *pLeft - (long) *pRight; + if (cmp != 0) { + return cmp < 0; + } + } + return *pRight != 0; + } +}; + +/** + * Generic ASCII case-insensitive less than comparison. This class returns + * numerically ordered ASCII case-insensitive text for all possible sizes + * and types of SI_CHAR. It is not safe for MBCS text comparison where + * ASCII A-Z characters are used in the encoding of multi-byte characters. + */ +template +struct SI_GenericNoCase { + inline SI_CHAR locase(SI_CHAR ch) const { + return (ch < 'A' || ch > 'Z') ? ch : (ch - 'A' + 'a'); + } + bool operator()(const SI_CHAR * pLeft, const SI_CHAR * pRight) const { + long cmp; + for ( ;*pLeft && *pRight; ++pLeft, ++pRight) { + cmp = (long) locase(*pLeft) - (long) locase(*pRight); + if (cmp != 0) { + return cmp < 0; + } + } + return *pRight != 0; + } +}; + +/** + * Null conversion class for MBCS/UTF-8 to char (or equivalent). + */ +template +class SI_ConvertA { + bool m_bStoreIsUtf8; +protected: + SI_ConvertA() { } +public: + SI_ConvertA(bool a_bStoreIsUtf8) : m_bStoreIsUtf8(a_bStoreIsUtf8) { } + + /* copy and assignment */ + SI_ConvertA(const SI_ConvertA & rhs) { operator=(rhs); } + SI_ConvertA & operator=(const SI_ConvertA & rhs) { + m_bStoreIsUtf8 = rhs.m_bStoreIsUtf8; + return *this; + } + + /** Calculate the number of SI_CHAR required for converting the input + * from the storage format. The storage format is always UTF-8 or MBCS. + * + * @param a_pInputData Data in storage format to be converted to SI_CHAR. + * @param a_uInputDataLen Length of storage format data in bytes. This + * must be the actual length of the data, including + * NULL byte if NULL terminated string is required. + * @return Number of SI_CHAR required by the string when + * converted. If there are embedded NULL bytes in the + * input data, only the string up and not including + * the NULL byte will be converted. + * @return -1 cast to size_t on a conversion error. + */ + size_t SizeFromStore( + const char * a_pInputData, + size_t a_uInputDataLen) + { + (void)a_pInputData; + SI_ASSERT(a_uInputDataLen != (size_t) -1); + + // ASCII/MBCS/UTF-8 needs no conversion + return a_uInputDataLen; + } + + /** Convert the input string from the storage format to SI_CHAR. + * The storage format is always UTF-8 or MBCS. + * + * @param a_pInputData Data in storage format to be converted to SI_CHAR. + * @param a_uInputDataLen Length of storage format data in bytes. This + * must be the actual length of the data, including + * NULL byte if NULL terminated string is required. + * @param a_pOutputData Pointer to the output buffer to received the + * converted data. + * @param a_uOutputDataSize Size of the output buffer in SI_CHAR. + * @return true if all of the input data was successfully + * converted. + */ + bool ConvertFromStore( + const char * a_pInputData, + size_t a_uInputDataLen, + SI_CHAR * a_pOutputData, + size_t a_uOutputDataSize) + { + // ASCII/MBCS/UTF-8 needs no conversion + if (a_uInputDataLen > a_uOutputDataSize) { + return false; + } + memcpy(a_pOutputData, a_pInputData, a_uInputDataLen); + return true; + } + + /** Calculate the number of char required by the storage format of this + * data. The storage format is always UTF-8 or MBCS. + * + * @param a_pInputData NULL terminated string to calculate the number of + * bytes required to be converted to storage format. + * @return Number of bytes required by the string when + * converted to storage format. This size always + * includes space for the terminating NULL character. + * @return -1 cast to size_t on a conversion error. + */ + size_t SizeToStore( + const SI_CHAR * a_pInputData) + { + // ASCII/MBCS/UTF-8 needs no conversion + return strlen((const char *)a_pInputData) + 1; + } + + /** Convert the input string to the storage format of this data. + * The storage format is always UTF-8 or MBCS. + * + * @param a_pInputData NULL terminated source string to convert. All of + * the data will be converted including the + * terminating NULL character. + * @param a_pOutputData Pointer to the buffer to receive the converted + * string. + * @param a_uOutputDataSize Size of the output buffer in char. + * @return true if all of the input data, including the + * terminating NULL character was successfully + * converted. + */ + bool ConvertToStore( + const SI_CHAR * a_pInputData, + char * a_pOutputData, + size_t a_uOutputDataSize) + { + // calc input string length (SI_CHAR type and size independent) + size_t uInputLen = strlen((const char *)a_pInputData) + 1; + if (uInputLen > a_uOutputDataSize) { + return false; + } + + // ascii/UTF-8 needs no conversion + memcpy(a_pOutputData, a_pInputData, uInputLen); + return true; + } +}; + + +// --------------------------------------------------------------------------- +// SI_CONVERT_GENERIC +// --------------------------------------------------------------------------- +#ifdef SI_CONVERT_GENERIC + +#define SI_Case SI_GenericCase +#define SI_NoCase SI_GenericNoCase + +#include +#include "ConvertUTF.h" + +/** + * Converts UTF-8 to a wchar_t (or equivalent) using the Unicode reference + * library functions. This can be used on all platforms. + */ +template +class SI_ConvertW { + bool m_bStoreIsUtf8; +protected: + SI_ConvertW() { } +public: + SI_ConvertW(bool a_bStoreIsUtf8) : m_bStoreIsUtf8(a_bStoreIsUtf8) { } + + /* copy and assignment */ + SI_ConvertW(const SI_ConvertW & rhs) { operator=(rhs); } + SI_ConvertW & operator=(const SI_ConvertW & rhs) { + m_bStoreIsUtf8 = rhs.m_bStoreIsUtf8; + return *this; + } + + /** Calculate the number of SI_CHAR required for converting the input + * from the storage format. The storage format is always UTF-8 or MBCS. + * + * @param a_pInputData Data in storage format to be converted to SI_CHAR. + * @param a_uInputDataLen Length of storage format data in bytes. This + * must be the actual length of the data, including + * NULL byte if NULL terminated string is required. + * @return Number of SI_CHAR required by the string when + * converted. If there are embedded NULL bytes in the + * input data, only the string up and not including + * the NULL byte will be converted. + * @return -1 cast to size_t on a conversion error. + */ + size_t SizeFromStore( + const char * a_pInputData, + size_t a_uInputDataLen) + { + SI_ASSERT(a_uInputDataLen != (size_t) -1); + + if (m_bStoreIsUtf8) { + // worst case scenario for UTF-8 to wchar_t is 1 char -> 1 wchar_t + // so we just return the same number of characters required as for + // the source text. + return a_uInputDataLen; + } + else { + return mbstowcs(NULL, a_pInputData, a_uInputDataLen); + } + } + + /** Convert the input string from the storage format to SI_CHAR. + * The storage format is always UTF-8 or MBCS. + * + * @param a_pInputData Data in storage format to be converted to SI_CHAR. + * @param a_uInputDataLen Length of storage format data in bytes. This + * must be the actual length of the data, including + * NULL byte if NULL terminated string is required. + * @param a_pOutputData Pointer to the output buffer to received the + * converted data. + * @param a_uOutputDataSize Size of the output buffer in SI_CHAR. + * @return true if all of the input data was successfully + * converted. + */ + bool ConvertFromStore( + const char * a_pInputData, + size_t a_uInputDataLen, + SI_CHAR * a_pOutputData, + size_t a_uOutputDataSize) + { + if (m_bStoreIsUtf8) { + // This uses the Unicode reference implementation to do the + // conversion from UTF-8 to wchar_t. The required files are + // ConvertUTF.h and ConvertUTF.c which should be included in + // the distribution but are publically available from unicode.org + // at http://www.unicode.org/Public/PROGRAMS/CVTUTF/ + ConversionResult retval; + const UTF8 * pUtf8 = (const UTF8 *) a_pInputData; + if (sizeof(wchar_t) == sizeof(UTF32)) { + UTF32 * pUtf32 = (UTF32 *) a_pOutputData; + retval = ConvertUTF8toUTF32( + &pUtf8, pUtf8 + a_uInputDataLen, + &pUtf32, pUtf32 + a_uOutputDataSize, + lenientConversion); + } + else if (sizeof(wchar_t) == sizeof(UTF16)) { + UTF16 * pUtf16 = (UTF16 *) a_pOutputData; + retval = ConvertUTF8toUTF16( + &pUtf8, pUtf8 + a_uInputDataLen, + &pUtf16, pUtf16 + a_uOutputDataSize, + lenientConversion); + } + return retval == conversionOK; + } + else { + size_t retval = mbstowcs(a_pOutputData, + a_pInputData, a_uOutputDataSize); + return retval != (size_t)(-1); + } + } + + /** Calculate the number of char required by the storage format of this + * data. The storage format is always UTF-8 or MBCS. + * + * @param a_pInputData NULL terminated string to calculate the number of + * bytes required to be converted to storage format. + * @return Number of bytes required by the string when + * converted to storage format. This size always + * includes space for the terminating NULL character. + * @return -1 cast to size_t on a conversion error. + */ + size_t SizeToStore( + const SI_CHAR * a_pInputData) + { + if (m_bStoreIsUtf8) { + // worst case scenario for wchar_t to UTF-8 is 1 wchar_t -> 6 char + size_t uLen = 0; + while (a_pInputData[uLen]) { + ++uLen; + } + return (6 * uLen) + 1; + } + else { + size_t uLen = wcstombs(NULL, a_pInputData, 0); + if (uLen == (size_t)(-1)) { + return uLen; + } + return uLen + 1; // include NULL terminator + } + } + + /** Convert the input string to the storage format of this data. + * The storage format is always UTF-8 or MBCS. + * + * @param a_pInputData NULL terminated source string to convert. All of + * the data will be converted including the + * terminating NULL character. + * @param a_pOutputData Pointer to the buffer to receive the converted + * string. + * @param a_uOutputDataSize Size of the output buffer in char. + * @return true if all of the input data, including the + * terminating NULL character was successfully + * converted. + */ + bool ConvertToStore( + const SI_CHAR * a_pInputData, + char * a_pOutputData, + size_t a_uOutputDataSize + ) + { + if (m_bStoreIsUtf8) { + // calc input string length (SI_CHAR type and size independent) + size_t uInputLen = 0; + while (a_pInputData[uInputLen]) { + ++uInputLen; + } + ++uInputLen; // include the NULL char + + // This uses the Unicode reference implementation to do the + // conversion from wchar_t to UTF-8. The required files are + // ConvertUTF.h and ConvertUTF.c which should be included in + // the distribution but are publically available from unicode.org + // at http://www.unicode.org/Public/PROGRAMS/CVTUTF/ + ConversionResult retval; + UTF8 * pUtf8 = (UTF8 *) a_pOutputData; + if (sizeof(wchar_t) == sizeof(UTF32)) { + const UTF32 * pUtf32 = (const UTF32 *) a_pInputData; + retval = ConvertUTF32toUTF8( + &pUtf32, pUtf32 + uInputLen, + &pUtf8, pUtf8 + a_uOutputDataSize, + lenientConversion); + } + else if (sizeof(wchar_t) == sizeof(UTF16)) { + const UTF16 * pUtf16 = (const UTF16 *) a_pInputData; + retval = ConvertUTF16toUTF8( + &pUtf16, pUtf16 + uInputLen, + &pUtf8, pUtf8 + a_uOutputDataSize, + lenientConversion); + } + return retval == conversionOK; + } + else { + size_t retval = wcstombs(a_pOutputData, + a_pInputData, a_uOutputDataSize); + return retval != (size_t) -1; + } + } +}; + +#endif // SI_CONVERT_GENERIC + + +// --------------------------------------------------------------------------- +// SI_CONVERT_ICU +// --------------------------------------------------------------------------- +#ifdef SI_CONVERT_ICU + +#define SI_Case SI_GenericCase +#define SI_NoCase SI_GenericNoCase + +#include + +/** + * Converts MBCS/UTF-8 to UChar using ICU. This can be used on all platforms. + */ +template +class SI_ConvertW { + const char * m_pEncoding; + UConverter * m_pConverter; +protected: + SI_ConvertW() : m_pEncoding(NULL), m_pConverter(NULL) { } +public: + SI_ConvertW(bool a_bStoreIsUtf8) : m_pConverter(NULL) { + m_pEncoding = a_bStoreIsUtf8 ? "UTF-8" : NULL; + } + + /* copy and assignment */ + SI_ConvertW(const SI_ConvertW & rhs) { operator=(rhs); } + SI_ConvertW & operator=(const SI_ConvertW & rhs) { + m_pEncoding = rhs.m_pEncoding; + m_pConverter = NULL; + return *this; + } + ~SI_ConvertW() { if (m_pConverter) ucnv_close(m_pConverter); } + + /** Calculate the number of UChar required for converting the input + * from the storage format. The storage format is always UTF-8 or MBCS. + * + * @param a_pInputData Data in storage format to be converted to UChar. + * @param a_uInputDataLen Length of storage format data in bytes. This + * must be the actual length of the data, including + * NULL byte if NULL terminated string is required. + * @return Number of UChar required by the string when + * converted. If there are embedded NULL bytes in the + * input data, only the string up and not including + * the NULL byte will be converted. + * @return -1 cast to size_t on a conversion error. + */ + size_t SizeFromStore( + const char * a_pInputData, + size_t a_uInputDataLen) + { + SI_ASSERT(a_uInputDataLen != (size_t) -1); + + UErrorCode nError; + + if (!m_pConverter) { + nError = U_ZERO_ERROR; + m_pConverter = ucnv_open(m_pEncoding, &nError); + if (U_FAILURE(nError)) { + return (size_t) -1; + } + } + + nError = U_ZERO_ERROR; + ucnv_resetToUnicode(m_pConverter); + int32_t nLen = ucnv_toUChars(m_pConverter, NULL, 0, + a_pInputData, (int32_t) a_uInputDataLen, &nError); + if (nError != U_BUFFER_OVERFLOW_ERROR) { + return (size_t) -1; + } + + return (size_t) nLen; + } + + /** Convert the input string from the storage format to UChar. + * The storage format is always UTF-8 or MBCS. + * + * @param a_pInputData Data in storage format to be converted to UChar. + * @param a_uInputDataLen Length of storage format data in bytes. This + * must be the actual length of the data, including + * NULL byte if NULL terminated string is required. + * @param a_pOutputData Pointer to the output buffer to received the + * converted data. + * @param a_uOutputDataSize Size of the output buffer in UChar. + * @return true if all of the input data was successfully + * converted. + */ + bool ConvertFromStore( + const char * a_pInputData, + size_t a_uInputDataLen, + UChar * a_pOutputData, + size_t a_uOutputDataSize) + { + UErrorCode nError; + + if (!m_pConverter) { + nError = U_ZERO_ERROR; + m_pConverter = ucnv_open(m_pEncoding, &nError); + if (U_FAILURE(nError)) { + return false; + } + } + + nError = U_ZERO_ERROR; + ucnv_resetToUnicode(m_pConverter); + ucnv_toUChars(m_pConverter, + a_pOutputData, (int32_t) a_uOutputDataSize, + a_pInputData, (int32_t) a_uInputDataLen, &nError); + if (U_FAILURE(nError)) { + return false; + } + + return true; + } + + /** Calculate the number of char required by the storage format of this + * data. The storage format is always UTF-8 or MBCS. + * + * @param a_pInputData NULL terminated string to calculate the number of + * bytes required to be converted to storage format. + * @return Number of bytes required by the string when + * converted to storage format. This size always + * includes space for the terminating NULL character. + * @return -1 cast to size_t on a conversion error. + */ + size_t SizeToStore( + const UChar * a_pInputData) + { + UErrorCode nError; + + if (!m_pConverter) { + nError = U_ZERO_ERROR; + m_pConverter = ucnv_open(m_pEncoding, &nError); + if (U_FAILURE(nError)) { + return (size_t) -1; + } + } + + nError = U_ZERO_ERROR; + ucnv_resetFromUnicode(m_pConverter); + int32_t nLen = ucnv_fromUChars(m_pConverter, NULL, 0, + a_pInputData, -1, &nError); + if (nError != U_BUFFER_OVERFLOW_ERROR) { + return (size_t) -1; + } + + return (size_t) nLen + 1; + } + + /** Convert the input string to the storage format of this data. + * The storage format is always UTF-8 or MBCS. + * + * @param a_pInputData NULL terminated source string to convert. All of + * the data will be converted including the + * terminating NULL character. + * @param a_pOutputData Pointer to the buffer to receive the converted + * string. + * @param a_pOutputDataSize Size of the output buffer in char. + * @return true if all of the input data, including the + * terminating NULL character was successfully + * converted. + */ + bool ConvertToStore( + const UChar * a_pInputData, + char * a_pOutputData, + size_t a_uOutputDataSize) + { + UErrorCode nError; + + if (!m_pConverter) { + nError = U_ZERO_ERROR; + m_pConverter = ucnv_open(m_pEncoding, &nError); + if (U_FAILURE(nError)) { + return false; + } + } + + nError = U_ZERO_ERROR; + ucnv_resetFromUnicode(m_pConverter); + ucnv_fromUChars(m_pConverter, + a_pOutputData, (int32_t) a_uOutputDataSize, + a_pInputData, -1, &nError); + if (U_FAILURE(nError)) { + return false; + } + + return true; + } +}; + +#endif // SI_CONVERT_ICU + + +// --------------------------------------------------------------------------- +// SI_CONVERT_WIN32 +// --------------------------------------------------------------------------- +#ifdef SI_CONVERT_WIN32 + +#define SI_Case SI_GenericCase + +// Windows CE doesn't have errno or MBCS libraries +#ifdef _WIN32_WCE +# ifndef SI_NO_MBCS +# define SI_NO_MBCS +# endif +#endif +#ifdef _XBOX +#include +#else +#include +#endif + +#ifdef SI_NO_MBCS +# define SI_NoCase SI_GenericNoCase +#else // !SI_NO_MBCS +/** + * Case-insensitive comparison class using Win32 MBCS functions. This class + * returns a case-insensitive semi-collation order for MBCS text. It may not + * be safe for UTF-8 text returned in char format as we don't know what + * characters will be folded by the function! Therefore, if you are using + * SI_CHAR == char and SetUnicode(true), then you need to use the generic + * SI_NoCase class instead. + */ +#include +template +struct SI_NoCase { + bool operator()(const SI_CHAR * pLeft, const SI_CHAR * pRight) const { + if (sizeof(SI_CHAR) == sizeof(char)) { + return _mbsicmp((const unsigned char *)pLeft, + (const unsigned char *)pRight) < 0; + } + if (sizeof(SI_CHAR) == sizeof(wchar_t)) { + return _wcsicmp((const wchar_t *)pLeft, + (const wchar_t *)pRight) < 0; + } + return SI_GenericNoCase()(pLeft, pRight); + } +}; +#endif // SI_NO_MBCS + +/** + * Converts MBCS and UTF-8 to a wchar_t (or equivalent) on Windows. This uses + * only the Win32 functions and doesn't require the external Unicode UTF-8 + * conversion library. It will not work on Windows 95 without using Microsoft + * Layer for Unicode in your application. + */ +template +class SI_ConvertW { + UINT m_uCodePage; +protected: + SI_ConvertW() { } +public: + SI_ConvertW(bool a_bStoreIsUtf8) { + m_uCodePage = a_bStoreIsUtf8 ? CP_UTF8 : CP_ACP; + } + + /* copy and assignment */ + SI_ConvertW(const SI_ConvertW & rhs) { operator=(rhs); } + SI_ConvertW & operator=(const SI_ConvertW & rhs) { + m_uCodePage = rhs.m_uCodePage; + return *this; + } + + /** Calculate the number of SI_CHAR required for converting the input + * from the storage format. The storage format is always UTF-8 or MBCS. + * + * @param a_pInputData Data in storage format to be converted to SI_CHAR. + * @param a_uInputDataLen Length of storage format data in bytes. This + * must be the actual length of the data, including + * NULL byte if NULL terminated string is required. + * @return Number of SI_CHAR required by the string when + * converted. If there are embedded NULL bytes in the + * input data, only the string up and not including + * the NULL byte will be converted. + * @return -1 cast to size_t on a conversion error. + */ + size_t SizeFromStore( + const char * a_pInputData, + size_t a_uInputDataLen) + { + SI_ASSERT(a_uInputDataLen != (size_t) -1); + + int retval = MultiByteToWideChar( + m_uCodePage, 0, + a_pInputData, (int) a_uInputDataLen, + 0, 0); + return (size_t)(retval > 0 ? retval : -1); + } + + /** Convert the input string from the storage format to SI_CHAR. + * The storage format is always UTF-8 or MBCS. + * + * @param a_pInputData Data in storage format to be converted to SI_CHAR. + * @param a_uInputDataLen Length of storage format data in bytes. This + * must be the actual length of the data, including + * NULL byte if NULL terminated string is required. + * @param a_pOutputData Pointer to the output buffer to received the + * converted data. + * @param a_uOutputDataSize Size of the output buffer in SI_CHAR. + * @return true if all of the input data was successfully + * converted. + */ + bool ConvertFromStore( + const char * a_pInputData, + size_t a_uInputDataLen, + SI_CHAR * a_pOutputData, + size_t a_uOutputDataSize) + { + int nSize = MultiByteToWideChar( + m_uCodePage, 0, + a_pInputData, (int) a_uInputDataLen, + (wchar_t *) a_pOutputData, (int) a_uOutputDataSize); + return (nSize > 0); + } + + /** Calculate the number of char required by the storage format of this + * data. The storage format is always UTF-8. + * + * @param a_pInputData NULL terminated string to calculate the number of + * bytes required to be converted to storage format. + * @return Number of bytes required by the string when + * converted to storage format. This size always + * includes space for the terminating NULL character. + * @return -1 cast to size_t on a conversion error. + */ + size_t SizeToStore( + const SI_CHAR * a_pInputData) + { + int retval = WideCharToMultiByte( + m_uCodePage, 0, + (const wchar_t *) a_pInputData, -1, + 0, 0, 0, 0); + return (size_t) (retval > 0 ? retval : -1); + } + + /** Convert the input string to the storage format of this data. + * The storage format is always UTF-8 or MBCS. + * + * @param a_pInputData NULL terminated source string to convert. All of + * the data will be converted including the + * terminating NULL character. + * @param a_pOutputData Pointer to the buffer to receive the converted + * string. + * @param a_pOutputDataSize Size of the output buffer in char. + * @return true if all of the input data, including the + * terminating NULL character was successfully + * converted. + */ + bool ConvertToStore( + const SI_CHAR * a_pInputData, + char * a_pOutputData, + size_t a_uOutputDataSize) + { + int retval = WideCharToMultiByte( + m_uCodePage, 0, + (const wchar_t *) a_pInputData, -1, + a_pOutputData, (int) a_uOutputDataSize, 0, 0); + return retval > 0; + } +}; + +#endif // SI_CONVERT_WIN32 + + +// --------------------------------------------------------------------------- +// TYPE DEFINITIONS +// --------------------------------------------------------------------------- + +typedef CSimpleIniTempl,SI_ConvertA > CSimpleIniA; +typedef CSimpleIniTempl,SI_ConvertA > CSimpleIniCaseA; + +#if defined(SI_CONVERT_ICU) +typedef CSimpleIniTempl,SI_ConvertW > CSimpleIniW; +typedef CSimpleIniTempl,SI_ConvertW > CSimpleIniCaseW; +#else +typedef CSimpleIniTempl,SI_ConvertW > CSimpleIniW; +typedef CSimpleIniTempl,SI_ConvertW > CSimpleIniCaseW; +#endif + +#ifdef _UNICODE +# define CSimpleIni CSimpleIniW +# define CSimpleIniCase CSimpleIniCaseW +# define SI_NEWLINE SI_NEWLINE_W +#else // !_UNICODE +# define CSimpleIni CSimpleIniA +# define CSimpleIniCase CSimpleIniCaseA +# define SI_NEWLINE SI_NEWLINE_A +#endif // _UNICODE + +#ifdef _MSC_VER +# pragma warning (pop) +#endif + +#endif // INCLUDED_SimpleIni_h + diff --git a/xbox1/RetroLaunch/Surface.cpp b/xbox1/RetroLaunch/Surface.cpp new file mode 100644 index 0000000000..f4ca398534 --- /dev/null +++ b/xbox1/RetroLaunch/Surface.cpp @@ -0,0 +1,255 @@ +/** + * Surreal 64 Launcher (C) 2003 + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. This program 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 this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. To contact the + * authors: email: buttza@hotmail.com, lantus@lantus-x.com + * + * Additional code and cleanups: Surreal64 CE Team (http://www.emuxtras.net) + */ + +#include "Surface.h" +#include "Debug.h" + +CSurface::CSurface() +{ + m_pTexture = NULL; + m_pVertexBuffer = NULL; + m_byOpacity = 255; + m_byR = 255; + m_byG = 255; + m_byB = 255; + m_bLoaded = false; + m_x = 0; + m_y = 0; +} + +CSurface::CSurface(const string &szFilename) +{ + CSurface(); + Create(szFilename); +} + +CSurface::~CSurface() +{ + Destroy(); +} + +bool CSurface::Create(const string &szFilename) +{ + if (m_bLoaded) + Destroy(); + + g_hResult = D3DXCreateTextureFromFileExA(g_video.m_pD3DDevice, // d3d device + ("D:\\" + szFilename).c_str(), // filename + D3DX_DEFAULT, D3DX_DEFAULT, // width/height + D3DX_DEFAULT, // mipmaps + 0, // usage + D3DFMT_A8R8G8B8, // format + D3DPOOL_MANAGED, // memory class + D3DX_DEFAULT, // texture filter + D3DX_DEFAULT, // mipmapping + 0, // colorkey + &m_imageInfo, // image info + NULL, // pallete + &m_pTexture); // texture + + if (FAILED(g_hResult)) + { + g_debug.Print("Failed: D3DXCreateTextureFromFileExA()\n"); + return false; + } + + // create a vertex buffer for the quad that will display the texture + g_hResult = g_video.m_pD3DDevice->CreateVertexBuffer(4 * sizeof(CustomVertex), + D3DUSAGE_WRITEONLY, + D3DFVF_CUSTOMVERTEX, + D3DPOOL_MANAGED, &m_pVertexBuffer); + if (FAILED(g_hResult)) + { + g_debug.Print("Failed: CreateVertexBuffer()\n"); + m_pTexture->Release(); + return false; + } + + m_bLoaded = true; + + return true; +} + +bool CSurface::Create(dword width, dword height) +{ + if (m_bLoaded) + Destroy(); + + g_hResult = g_video.m_pD3DDevice->CreateTexture(width, height, 1, 0, + D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, + &m_pTexture); + + if (FAILED(g_hResult)) + { + g_debug.Print("Failed: CreateTexture()\n"); + return false; + } + + m_imageInfo.Width = width; + m_imageInfo.Height = height; + m_imageInfo.Format = D3DFMT_A8R8G8B8; + + // create a vertex buffer for the quad that will display the texture + g_hResult = g_video.m_pD3DDevice->CreateVertexBuffer(4 * sizeof(CustomVertex), + D3DUSAGE_WRITEONLY, + D3DFVF_CUSTOMVERTEX, + D3DPOOL_MANAGED, &m_pVertexBuffer); + if (FAILED(g_hResult)) + { + g_debug.Print("Failed: CreateVertexBuffer()\n"); + m_pTexture->Release(); + return false; + } + + m_bLoaded = true; + + return true; +} + +void CSurface::Destroy() +{ + // free the vertex buffer + if (m_pVertexBuffer) + { + m_pVertexBuffer->Release(); + m_pVertexBuffer = NULL; + } + + // free the texture + if (m_pTexture) + { + m_pTexture->Release(); + m_pTexture = NULL; + } + + m_bLoaded = false; +} + +bool CSurface::IsLoaded() +{ + return m_bLoaded; +} + +bool CSurface::Render() +{ + return Render(m_x, m_y); +} + +bool CSurface::Render(int x, int y) +{ + return Render(x, y, m_imageInfo.Width, m_imageInfo.Height); +} + +bool CSurface::Render(int x, int y, dword w, dword h) +{ + if (m_pTexture == NULL || m_pVertexBuffer == NULL || m_bLoaded == false) + return false; + + float fX = static_cast(x); + float fY = static_cast(y); + + // create the new vertices + CustomVertex newVerts[] = + { + // x, y, z, color, u ,v + {fX, fY, 0.0f, D3DCOLOR_ARGB(m_byOpacity, m_byR, m_byG, m_byB), 0, 0}, + {fX + w, fY, 0.0f, D3DCOLOR_ARGB(m_byOpacity, m_byR, m_byG, m_byB), 1, 0}, + {fX + w, fY + h, 0.0f, D3DCOLOR_ARGB(m_byOpacity, m_byR, m_byG, m_byB), 1, 1}, + {fX, fY + h, 0.0f, D3DCOLOR_ARGB(m_byOpacity, m_byR, m_byG, m_byB), 0, 1} + }; + + // load the existing vertices + CustomVertex *pCurVerts; + + g_hResult = m_pVertexBuffer->Lock(0, 0, (byte **)&pCurVerts, 0); + + if (FAILED(g_hResult)) + { + g_debug.Print("Failed: m_pVertexBuffer->Lock()\n"); + return false; + } + // copy the new verts over the old verts + memcpy(pCurVerts, newVerts, 4 * sizeof(CustomVertex)); + + m_pVertexBuffer->Unlock(); + + + g_video.m_pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + g_video.m_pD3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + g_video.m_pD3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); + + // also blend the texture with the set alpha value + g_video.m_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); + g_video.m_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE); + g_video.m_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TEXTURE); + + // draw the quad + g_video.m_pD3DDevice->SetTexture(0, m_pTexture); + g_video.m_pD3DDevice->SetStreamSource(0, m_pVertexBuffer, sizeof(CustomVertex)); + g_video.m_pD3DDevice->SetVertexShader(D3DFVF_CUSTOMVERTEX); +#ifdef _XBOX + g_video.m_pD3DDevice->DrawPrimitive(D3DPT_QUADLIST, 0, 1); +#else + //FIXME: vertices order ! + g_video.m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2); +#endif + return true; +} + +void CSurface::SetOpacity(byte opacity) +{ + m_byOpacity = opacity; +} + +void CSurface::SetTint(byte r, byte g, byte b) +{ + m_byR = r; + m_byG = g; + m_byB = b; +} + +void CSurface::MoveTo(int x, int y) +{ + m_x = x; + m_y = y; +} + +dword CSurface::GetWidth() +{ + if (m_pTexture == NULL || m_pVertexBuffer == NULL) + return 0; + + return m_imageInfo.Width; +} + +dword CSurface::GetHeight() +{ + if (m_pTexture == NULL || m_pVertexBuffer == NULL) + return 0; + + return m_imageInfo.Height; +} + +byte CSurface::GetOpacity() +{ + return m_byOpacity; +} + +IDirect3DTexture8 *CSurface::GetTexture() +{ + return m_pTexture; +} diff --git a/xbox1/RetroLaunch/Surface.h b/xbox1/RetroLaunch/Surface.h new file mode 100644 index 0000000000..752ee12f93 --- /dev/null +++ b/xbox1/RetroLaunch/Surface.h @@ -0,0 +1,90 @@ +/** + * Surreal 64 Launcher (C) 2003 + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. This program 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 this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. To contact the + * authors: email: buttza@hotmail.com, lantus@lantus-x.com + * + * Additional code and cleanups: Surreal64 CE Team (http://www.emuxtras.net) + */ + +#pragma once + +#include "Global.h" +#include "Video.h" + +class CSurface +{ +public: + CSurface(); + CSurface(const string &szFilename); + ~CSurface(); + + /** + * Do functions + */ + bool Create(const string &szFilename); + bool Create(dword width, dword height); + void Destroy(); + + bool IsLoaded(); + + bool Render(); + bool Render(int x, int y); + bool Render(int x, int y, dword w, dword h); + + /** + * Set functions + */ + void SetOpacity(byte opacity); + void SetTint(byte r, byte g, byte b); + + void MoveTo(int x, int y); + + /** + * Get functions + */ + dword GetWidth(); + dword GetHeight(); + + byte GetOpacity(); + + IDirect3DTexture8 *GetTexture(); + +private: + /** + * A d3d texture object that will contain the loaded texture + * and a d3d vertex buffer object that will contain the vertex + * buffer for the quad which will display the texture + */ + IDirect3DTexture8 *m_pTexture; + IDirect3DVertexBuffer8 *m_pVertexBuffer; + + /** + * The default render position of the texture + */ + int m_x, m_y; + + /** + * The width and height of the texture + */ + D3DXIMAGE_INFO m_imageInfo; + + /** + * The opacity of the texture + */ + byte m_byOpacity; + byte m_byR, m_byG, m_byB; + + /** + * Whether the texture has been created or not + */ + bool m_bLoaded; +}; diff --git a/xbox1/RetroLaunch/Undocumented.h b/xbox1/RetroLaunch/Undocumented.h new file mode 100644 index 0000000000..927280241d --- /dev/null +++ b/xbox1/RetroLaunch/Undocumented.h @@ -0,0 +1,1373 @@ +// Thanks and credit to everlame, Team Evox, and Woodoo. +// +// This file contains declarations for accessing the internal NT API. +// Some calls have changed from NT, so be careful! +// +// For the most part, all NT calls use ANSI instead of Unicode strings now. +// +// It is not known which flags work. You will have to experiment. + +#ifndef __XBOX_INTERNAL_H__ +#define __XBOX_INTERNAL_H__ + +#include + +// Do extern "C" for C++ +#if defined(__cplusplus) && !defined(XBOXINTERNAL_NO_EXTERN_C) +extern "C" { +#endif // __cplusplus + + +// Don't do __declspec(dllimport) for things like emulators +#if defined(NTSYSAPI) && defined(DONT_IMPORT_INTERNAL) +#undef NTSYSAPI +#endif +#ifdef DONT_IMPORT_INTERNAL +#define NTSYSAPI +#endif + +// The normal headers don't have this...? +#define FASTCALL __fastcall + +// The usual NTSTATUS +typedef LONG NTSTATUS; + +// The usual NT_SUCCESS +#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0) + +// Just for documentation +#define EXPORTNUM(x) + + +// Needed for object structures and related things +typedef CONST SHORT CSHORT; + + +// String types +typedef CHAR *PSZ; +typedef CONST CHAR *PCSZ; + +// ANSI_STRING +// Differences from NT: None. +typedef struct _STRING { + USHORT Length; + USHORT MaximumLength; + PCHAR Buffer; +} STRING; +typedef STRING *PSTRING; + +typedef STRING ANSI_STRING; +typedef PSTRING PANSI_STRING; + + +// IO Status Block type (UNVERIFIED) +// Differences from NT: None. +typedef struct _IO_STATUS_BLOCK { + union { + NTSTATUS Status; + PVOID Pointer; + }; + + ULONG_PTR Information; +} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK; + +// APC routine +typedef +VOID +(NTAPI *PIO_APC_ROUTINE) ( + IN PVOID ApcContext, + IN PIO_STATUS_BLOCK IoStatusBlock, + IN ULONG Reserved + ); + + +// Header for dispatcher objects +// Differences from NT: None. +typedef struct _DISPATCHER_HEADER { + UCHAR Type; + UCHAR Absolute; + UCHAR Size; + UCHAR Inserted; + LONG SignalState; + LIST_ENTRY WaitListHead; +} DISPATCHER_HEADER; + + +// Object types +#define NotificationTimerObject 8 +#define SynchronizationTimerObject 9 +#define DpcObject 19 + + +// Object Attributes type +// Differences from NT: There are no Length, SecurityDescriptor, or +// SecurityQualityOfService fields. Also, ObjectName is ANSI, not +// Unicode. +typedef struct _OBJECT_ATTRIBUTES { + HANDLE RootDirectory; + PANSI_STRING ObjectName; + ULONG Attributes; +} OBJECT_ATTRIBUTES; +typedef OBJECT_ATTRIBUTES *POBJECT_ATTRIBUTES; + +// Flags for OBJECT_ATTRIBUTES::Attributes +#define OBJ_INHERIT 0x00000002L +#define OBJ_PERMANENT 0x00000010L +#define OBJ_EXCLUSIVE 0x00000020L +#define OBJ_CASE_INSENSITIVE 0x00000040L +#define OBJ_OPENIF 0x00000080L +#define OBJ_OPENLINK 0x00000100L +#define OBJ_KERNEL_HANDLE 0x00000200L +#define OBJ_VALID_ATTRIBUTES 0x000003F2L + +// Initializes an OBJECT_ATTRIBUTES. +// Works as if it were this function: +// VOID +// InitializeObjectAttributes( +// OUT POBJECT_ATTRIBUTES p, +// IN PANSI_STRING n, +// IN ULONG a, +// IN HANDLE r +// ) +// Differences from NT: SECURITY_DESCRIPTOR support is gone. +#define InitializeObjectAttributes( p, n, a, r ) { \ + (p)->RootDirectory = r; \ + (p)->Attributes = a; \ + (p)->ObjectName = n; \ + } + + +// CreateDisposition values for NtCreateFile() +#define FILE_SUPERSEDE 0x00000000 +#define FILE_OPEN 0x00000001 +#define FILE_CREATE 0x00000002 +#define FILE_OPEN_IF 0x00000003 +#define FILE_OVERWRITE 0x00000004 +#define FILE_OVERWRITE_IF 0x00000005 +#define FILE_MAXIMUM_DISPOSITION 0x00000005 + +// CreateOption values for NtCreateFile() +// FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT is what CreateFile +// uses for most things when translating to NtCreateFile. +#define FILE_DIRECTORY_FILE 0x00000001 +#define FILE_WRITE_THROUGH 0x00000002 +#define FILE_SEQUENTIAL_ONLY 0x00000004 +#define FILE_NO_INTERMEDIATE_BUFFERING 0x00000008 +#define FILE_SYNCHRONOUS_IO_ALERT 0x00000010 +#define FILE_SYNCHRONOUS_IO_NONALERT 0x00000020 +#define FILE_NON_DIRECTORY_FILE 0x00000040 +#define FILE_CREATE_TREE_CONNECTION 0x00000080 +#define FILE_COMPLETE_IF_OPLOCKED 0x00000100 +#define FILE_NO_EA_KNOWLEDGE 0x00000200 +#define FILE_OPEN_FOR_RECOVERY 0x00000400 +#define FILE_RANDOM_ACCESS 0x00000800 +#define FILE_DELETE_ON_CLOSE 0x00001000 +#define FILE_OPEN_BY_FILE_ID 0x00002000 +#define FILE_OPEN_FOR_BACKUP_INTENT 0x00004000 +#define FILE_NO_COMPRESSION 0x00008000 +#define FILE_RESERVE_OPFILTER 0x00100000 +#define FILE_OPEN_REPARSE_POINT 0x00200000 +#define FILE_OPEN_NO_RECALL 0x00400000 +#define FILE_OPEN_FOR_FREE_SPACE_QUERY 0x00800000 +#define FILE_COPY_STRUCTURED_STORAGE 0x00000041 +#define FILE_STRUCTURED_STORAGE 0x00000441 +#define FILE_VALID_OPTION_FLAGS 0x00ffffff +#define FILE_VALID_PIPE_OPTION_FLAGS 0x00000032 +#define FILE_VALID_MAILSLOT_OPTION_FLAGS 0x00000032 +#define FILE_VALID_SET_FLAGS 0x00000036 + + +// NtQueryVolumeInformation / NtSetVolumeInformation stuff +// Type of information to retrieve; FileFsSizeInformation and +// FileFsDeviceInformation are the only ones confirmed to work. +typedef enum _FSINFOCLASS { + FileFsVolumeInformation = 1, + FileFsLabelInformation, + FileFsSizeInformation, + FileFsDeviceInformation, + FileFsAttributeInformation, + FileFsControlInformation, + FileFsFullSizeInformation, + FileFsObjectInformation +} FS_INFORMATION_CLASS, *PFS_INFORMATION_CLASS; + +// Structure of FileFsSizeInformation +typedef struct _FILE_FS_SIZE_INFORMATION { + LARGE_INTEGER TotalAllocationUnits; + LARGE_INTEGER AvailableAllocationUnits; + ULONG SectorsPerAllocationUnit; + ULONG BytesPerSector; +} FILE_FS_SIZE_INFORMATION, *PFILE_FS_SIZE_INFORMATION; + +#define DEVICE_TYPE ULONG + +// Structure of FileFsDeviceInformation +typedef struct _FILE_FS_DEVICE_INFORMATION { + DEVICE_TYPE DeviceType; + ULONG Characteristics; +} FILE_FS_DEVICE_INFORMATION, *PFILE_FS_DEVICE_INFORMATION; + +// DEVICE_TYPEs (I took a guess as to which the XBOX might have.) +#define FILE_DEVICE_CD_ROM 0x00000002 +#define FILE_DEVICE_CD_ROM_FILE_SYSTEM 0x00000003 +#define FILE_DEVICE_CONTROLLER 0x00000004 +#define FILE_DEVICE_DISK 0x00000007 +#define FILE_DEVICE_DISK_FILE_SYSTEM 0x00000008 +#define FILE_DEVICE_FILE_SYSTEM 0x00000009 +#define FILE_DEVICE_NULL 0x00000015 +#define FILE_DEVICE_SCREEN 0x0000001c +#define FILE_DEVICE_SOUND 0x0000001d +#define FILE_DEVICE_UNKNOWN 0x00000022 +#define FILE_DEVICE_VIDEO 0x00000023 +#define FILE_DEVICE_VIRTUAL_DISK 0x00000024 +#define FILE_DEVICE_FULLSCREEN_VIDEO 0x00000034 + +// Characteristics +#define FILE_REMOVABLE_MEDIA 0x00000001 +#define FILE_READ_ONLY_DEVICE 0x00000002 +#define FILE_FLOPPY_DISKETTE 0x00000004 +#define FILE_WRITE_ONCE_MEDIA 0x00000008 +#define FILE_REMOTE_DEVICE 0x00000010 +#define FILE_DEVICE_IS_MOUNTED 0x00000020 +#define FILE_VIRTUAL_VOLUME 0x00000040 +#define FILE_AUTOGENERATED_DEVICE_NAME 0x00000080 +#define FILE_DEVICE_SECURE_OPEN 0x00000100 + + + +// Physical address +// Differences from NT: 32 bit address instead of 64. +typedef ULONG PHYSICAL_ADDRESS, *PPHYSICAL_ADDRESS; + + +// NtCreateFile/NtOpenFile stuff +#define FILE_SUPERSEDED 0x00000000 +#define FILE_OPENED 0x00000001 +#define FILE_CREATED 0x00000002 +#define FILE_OVERWRITTEN 0x00000003 +#define FILE_EXISTS 0x00000004 +#define FILE_DOES_NOT_EXIST 0x00000005 + +// NtReadFile/NtWriteFile stuff +#define FILE_WRITE_TO_END_OF_FILE 0xffffffff +#define FILE_USE_FILE_POINTER_POSITION 0xfffffffe + + + +// DeviceIoControl stuff + +// Device types +#define FILE_DEVICE_CD_ROM 0x00000002 +#define FILE_DEVICE_CD_ROM_FILE_SYSTEM 0x00000003 +#define FILE_DEVICE_CONTROLLER 0x00000004 +#define FILE_DEVICE_SCSI FILE_DEVICE_CONTROLLER +#define IOCTL_SCSI_BASE FILE_DEVICE_CONTROLLER +#define FILE_DEVICE_DISK 0x00000007 +#define FILE_DEVICE_DISK_FILE_SYSTEM 0x00000008 +#define FILE_DEVICE_DVD 0x00000033 + +// Access types +#define FILE_ANY_ACCESS 0 +#define FILE_READ_ACCESS ( 0x0001 ) // file & pipe +#define FILE_WRITE_ACCESS ( 0x0002 ) // file & pipe + +// Method types +#define METHOD_BUFFERED 0 +#define METHOD_IN_DIRECT 1 +#define METHOD_OUT_DIRECT 2 +#define METHOD_NEITHER 3 + +// The all-important CTL_CODE +#define CTL_CODE( DeviceType, Function, Method, Access ) ( \ + ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \ +) + +// IDE/SCSI codes +// IOCTL_SCSI_PASS_THROUGH_DIRECT is the only one known to be used. +// Differences from NT: None. +#define IOCTL_SCSI_PASS_THROUGH CTL_CODE(IOCTL_SCSI_BASE, 0x0401, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) +#define IOCTL_SCSI_MINIPORT CTL_CODE(IOCTL_SCSI_BASE, 0x0402, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) +#define IOCTL_SCSI_GET_INQUIRY_DATA CTL_CODE(IOCTL_SCSI_BASE, 0x0403, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_SCSI_GET_CAPABILITIES CTL_CODE(IOCTL_SCSI_BASE, 0x0404, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_SCSI_PASS_THROUGH_DIRECT CTL_CODE(IOCTL_SCSI_BASE, 0x0405, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) +#define IOCTL_SCSI_GET_ADDRESS CTL_CODE(IOCTL_SCSI_BASE, 0x0406, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_SCSI_RESCAN_BUS CTL_CODE(IOCTL_SCSI_BASE, 0x0407, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_SCSI_GET_DUMP_POINTERS CTL_CODE(IOCTL_SCSI_BASE, 0x0408, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_SCSI_FREE_DUMP_POINTERS CTL_CODE(IOCTL_SCSI_BASE, 0x0409, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_IDE_PASS_THROUGH CTL_CODE(IOCTL_SCSI_BASE, 0x040a, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) + +// Special XBOX code? +#define IOCTL_CDROM_AUTHENTICATE_DISK CTL_CODE(FILE_DEVICE_CD_ROM, 0x0020, METHOD_BUFFERED, FILE_READ_ACCESS) + +// Structure for IOCTL_SCSI_PASS_THROUGH_DIRECT +// Differences from NT: None, believe it or not. +typedef struct _SCSI_PASS_THROUGH_DIRECT { + /*000*/ USHORT Length; + /*002*/ UCHAR ScsiStatus; + /*003*/ UCHAR PathId; + /*004*/ UCHAR TargetId; + /*005*/ UCHAR Lun; + /*006*/ UCHAR CdbLength; + /*007*/ UCHAR SenseInfoLength; + /*008*/ UCHAR DataIn; + /*00C*/ ULONG DataTransferLength; + /*010*/ ULONG TimeOutValue; + /*014*/ PVOID DataBuffer; + /*018*/ ULONG SenseInfoOffset; + /*01C*/ UCHAR Cdb[16]; +}SCSI_PASS_THROUGH_DIRECT, *PSCSI_PASS_THROUGH_DIRECT; + +// DataIn fields for IOCTL_SCSI_PASS_THROUGH_DIRECT +#define SCSI_IOCTL_DATA_OUT 0 +#define SCSI_IOCTL_DATA_IN 1 +#define SCSI_IOCTL_DATA_UNSPECIFIED 2 + +// Kernel object type (unsure about the structure...) +typedef struct _OBJECT_TYPE +{ + // Same prototype as ExAllocatePoolWithTag, because that's the usual one + PVOID + (NTAPI *AllocationFunction)( + SIZE_T NumberOfBytes, + ULONG Tag + ); + + // Same prototype as ExFreePool, because that's the usual one + VOID + (NTAPI *FreeFunction)( + IN PVOID P + ); + + // The prototypes of these are unknown + void *CloseFunction; + void *DeleteFunction; + void *ParseFunction; + + // Unknown DWORD... Size of this object type maybe? + void *DefaultObjectMaybe; + + // 4 letter tag for this object type + CHAR Tag[4]; +} OBJECT_TYPE; +typedef OBJECT_TYPE *POBJECT_TYPE; + +// Object types +extern POBJECT_TYPE IoFileObjectType; +extern POBJECT_TYPE ExEventObjectType; +extern POBJECT_TYPE ExSemaphoreObjectType; +extern POBJECT_TYPE IoCompletionObjectType; +extern POBJECT_TYPE IoDeviceObjectType; + + +// *_OBJECT and related structures (mostly opaque since I'm lazy) +typedef struct _DRIVER_OBJECT { + CSHORT Type; + CSHORT Size; + struct _DEVICE_OBJECT *DeviceObject; + // ... +} DRIVER_OBJECT; +typedef DRIVER_OBJECT *PDRIVER_OBJECT; + +typedef struct _DEVICE_OBJECT { + CSHORT Type; + USHORT Size; + LONG ReferenceCount; + PDRIVER_OBJECT DriverObject; + // ... +} DEVICE_OBJECT; +typedef DEVICE_OBJECT *PDEVICE_OBJECT; + +typedef struct _FILE_OBJECT { + CSHORT Type; + CSHORT Size; + PDEVICE_OBJECT DeviceObject; + // ... +} FILE_OBJECT; +typedef FILE_OBJECT *PFILE_OBJECT; + + +// Thread information structures + +// IRQL +typedef UCHAR KIRQL, *PKIRQL; +#define PASSIVE_LEVEL 0 // Passive release level +#define LOW_LEVEL 0 // Lowest interrupt level +#define APC_LEVEL 1 // APC interrupt level +#define DISPATCH_LEVEL 2 // Dispatcher level + +// Thread entry point +// NOTE: This is not a standard call! You can't call this function from C code! +// You push registers like stdcall, but ebp + 4 must point to the first argument before the call! +// +// Differences from NT: 2 parameters instead of 1; strange calling convention +typedef +VOID +(NTAPI *PKSTART_ROUTINE) ( + IN PVOID StartContext1, + IN PVOID StartContext2 + ); + +// Structure of a critical section +// Same as the XBOX's RTL_CRITICAL_SECTION, but with the more explicit header +typedef struct _KCRITICAL_SECTION +{ + // 000 Dispatcher header + DISPATCHER_HEADER Header; + // 010 Lock count of the critical section + LONG LockCount; + // 014 Recursion count of the critical section + LONG RecursionCount; + // 018 Thread ID of the thread that currently owns this critical section + ULONG OwningThread; +} KCRITICAL_SECTION, *PKCRITICAL_SECTION; + +// Structure of a thread object +typedef struct _KTHREAD +{ + // 000 Dispatcher header + DISPATCHER_HEADER Header; + // 010 Unknown + BYTE unknown[0x18]; + // 028 Pointer to TLS data + PVOID TlsData; + // ??? just padding - real size is unknown + BYTE unknown2[0x100]; +} KTHREAD, *PKTHREAD; + +// Structure of the data at FS +typedef struct _FS_STRUCTURE +{ + // 000 Current exception handler information + PVOID *ExceptionFrame; + // 004 Pointer to current TLS data top + PVOID TlsDataTop; + // 008 + BYTE unknown2[0x1C]; + // 024 Current IRQL of the OS + KIRQL CurrentIrql; + // 028 Thread structure of the current thread + PKTHREAD ThreadObject; + // ??? just padding - real size is unknown + BYTE unknown3[0x100]; +} FS_STRUCTURE, *PFS_STRUCTURE; + +// DPC routine +typedef +VOID +(*PKDEFERRED_ROUTINE) ( + IN struct _KDPC *Dpc, + IN PVOID DeferredContext, + IN PVOID SystemArgument1, + IN PVOID SystemArgument2 + ); + +// DPC information +// It's not known which of these fields are used on XBOX. +typedef struct _KDPC { + CSHORT Type; + UCHAR Number; + UCHAR Importance; + LIST_ENTRY DpcListEntry; + PKDEFERRED_ROUTINE DeferredRoutine; + PVOID DeferredContext; + PVOID SystemArgument1; + PVOID SystemArgument2; + PULONG_PTR Lock; +} KDPC, *PKDPC; + + +// Timers +typedef enum _TIMER_TYPE { + NotificationTimer, + SynchronizationTimer + } TIMER_TYPE; + +typedef struct _KTIMER { + DISPATCHER_HEADER Header; + ULARGE_INTEGER DueTime; + LIST_ENTRY TimerListEntry; + struct _KDPC *Dpc; + LONG Period; +} KTIMER, *PKTIMER; + + + +// XBE stuff +// Not used in any exported kernel calls, but still useful. + + +// XBE header information +typedef struct _XBE_HEADER { + // 000 "XBEH" + CHAR Magic[4]; + // 004 RSA digital signature of the entire header area + UCHAR HeaderSignature[256]; + // 104 Base address of XBE image (must be 0x00010000?) + PVOID BaseAddress; + // 108 Size of all headers combined - other headers must be within this + ULONG HeaderSize; + // 10C Size of entire image + ULONG ImageSize; + // 110 Size of this header (always 0x178?) + ULONG XbeHeaderSize; + // 114 Image timestamp - unknown format + ULONG Timestamp; + // 118 Pointer to certificate data (must be within HeaderSize) + struct _XBE_CERTIFICATE *Certificate; + // 11C Number of sections + DWORD NumSections; + // 120 Pointer to section headers (must be within HeaderSize) + struct _XBE_SECTION *Sections; + // 124 Initialization flags + ULONG InitFlags; + // 128 Entry point (XOR'd; see xboxhacker.net) + PVOID EntryPoint; + // 12C Pointer to TLS directory + struct _XBE_TLS_DIRECTORY *TlsDirectory; + // 130 Stack commit size + ULONG StackCommit; + // 134 Heap reserve size + ULONG HeapReserve; + // 138 Heap commit size + ULONG HeapCommit; + // 13C PE base address (?) + PVOID PeBaseAddress; + // 140 PE image size (?) + ULONG PeImageSize; + // 144 PE checksum (?) + ULONG PeChecksum; + // 148 PE timestamp (?) + ULONG PeTimestamp; + // 14C PC path and filename to EXE file from which XBE is derived + PCSZ PcExePath; + // 150 PC filename (last part of PcExePath) from which XBE is derived + PCSZ PcExeFilename; + // 154 PC filename (Unicode version of PcExeFilename) + PWSTR PcExeFilenameUnicode; + // 158 Pointer to kernel thunk table (XOR'd; EFB1F152 debug) + ULONG_PTR *KernelThunkTable; + // 15C Non-kernel import table (debug only) + PVOID DebugImportTable; + // 160 Number of library headers + ULONG NumLibraries; + // 164 Pointer to library headers + struct _XBE_LIBRARY *Libraries; + // 168 Pointer to kernel library header + struct _XBE_LIBRARY *KernelLibrary; + // 16C Pointer to XAPI library + struct _XBE_LIBRARY *XapiLibrary; + // 170 Pointer to logo bitmap (NULL = use default of Microsoft) + PVOID LogoBitmap; + // 174 Size of logo bitmap + ULONG LogoBitmapSize; + // 178 +} XBE_HEADER, *PXBE_HEADER; + +// Certificate structure +typedef struct _XBE_CERTIFICATE { + // 000 Size of certificate + ULONG Size; + // 004 Certificate timestamp (unknown format) + ULONG Timestamp; + // 008 Title ID + ULONG TitleId; + // 00C Name of the game (Unicode) + WCHAR TitleName[40]; + // 05C Alternate title ID's (0-terminated) + ULONG AlternateTitleIds[16]; + // 09C Allowed media types - 1 bit match between XBE and media = boots + ULONG MediaTypes; + // 0A0 Allowed game regions - 1 bit match between this and XBOX = boots + ULONG GameRegion; + // 0A4 Allowed game ratings - 1 bit match between this and XBOX = boots + ULONG GameRating; + // 0A8 Disk number (?) + ULONG DiskNumber; + // 0AC Version (?) + ULONG Version; + // 0B0 LAN key for this game + UCHAR LanKey[16]; + // 0C0 Signature key for this game + UCHAR SignatureKey[16]; + // 0D0 Signature keys for the alternate title ID's + UCHAR AlternateSignatureKeys[16][16]; + // 1D0 +} XBE_CERTIFICATE, *PXBE_CERTIFICATE; + +// Section headers +typedef struct _XBE_SECTION { + // 000 Flags + ULONG Flags; + // 004 Virtual address (where this section loads in RAM) + PVOID VirtualAddress; + // 008 Virtual size (size of section in RAM; after FileSize it's 00'd) + ULONG VirtualSize; + // 00C File address (where in the file from which this section comes) + ULONG FileAddress; + // 010 File size (size of the section in the XBE file) + ULONG FileSize; + // 014 Pointer to section name + PCSZ SectionName; + // 018 Section reference count - when >= 1, section is loaded + LONG SectionReferenceCount; + // 01C Pointer to head shared page reference count + WORD *HeadReferenceCount; + // 020 Pointer to tail shared page reference count + WORD *TailReferenceCount; + // 024 SHA hash. Hash DWORD containing FileSize, then hash section. + DWORD ShaHash[5]; + // 038 +} XBE_SECTION, *PXBE_SECTION; + +// TLS directory information needed later +// Library version data needed later + +// Initialization flags +#define XBE_INIT_MOUNT_UTILITY 0x00000001 +#define XBE_INIT_FORMAT_UTILITY 0x00000002 +#define XBE_INIT_64M_RAM_ONLY 0x00000004 +#define XBE_INIT_DONT_SETUP_HDD 0x00000008 + +// Region codes +#define XBE_REGION_US_CANADA 0x00000001 +#define XBE_REGION_JAPAN 0x00000002 +#define XBE_REGION_ELSEWHERE 0x00000004 +#define XBE_REGION_DEBUG 0x80000000 + +// Media types +#define XBE_MEDIA_HDD 0x00000001 +#define XBE_MEDIA_XBOX_DVD 0x00000002 +#define XBE_MEDIA_ANY_CD_OR_DVD 0x00000004 +#define XBE_MEDIA_CD 0x00000008 +#define XBE_MEDIA_1LAYER_DVDROM 0x00000010 +#define XBE_MEDIA_2LAYER_DVDROM 0x00000020 +#define XBE_MEDIA_1LAYER_DVDR 0x00000040 +#define XBE_MEDIA_2LAYER_DVDR 0x00000080 +#define XBE_MEDIA_USB 0x00000100 +#define XBE_MEDIA_ALLOW_UNLOCKED_HDD 0x40000000 + +// Section flags +#define XBE_SEC_WRITABLE 0x00000001 +#define XBE_SEC_PRELOAD 0x00000002 +#define XBE_SEC_EXECUTABLE 0x00000004 +#define XBE_SEC_INSERTED_FILE 0x00000008 +#define XBE_SEC_RO_HEAD_PAGE 0x00000010 +#define XBE_SEC_RO_TAIL_PAGE 0x00000020 + + +// x86 page size +#define PAGE_SIZE 0x1000 + + +// Native NT API calls on the XBOX + + +// PAGE_ALIGN: +// Returns an address rounded down to the nearest page boundary. +// +// Differences from NT: None. +#define PAGE_ALIGN(Va) ((PVOID)((ULONG_PTR)(Va) & ~(PAGE_SIZE - 1))) + + +// RtlInitAnsiString: +// Fills an ANSI_STRING structure to use the specified string. +// +// Differences from NT: None. +NTSYSAPI +EXPORTNUM(289) +VOID +NTAPI +RtlInitAnsiString( + OUT PANSI_STRING DestinationString, + IN PCSZ SourceString + ); + + +// NtCreateFile: +// Creates or opens a file or device object. +// +// Differences from NT: The EaBuffer and EaLength options are gone. +// OBJECT_ATTRIBUTES uses ANSI_STRING, so only ANSI filenames work. +NTSYSAPI +EXPORTNUM(190) +NTSTATUS +NTAPI +NtCreateFile( + OUT PHANDLE FileHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes, + OUT PIO_STATUS_BLOCK IoStatusBlock, + IN PLARGE_INTEGER AllocationSize OPTIONAL, + IN ULONG FileAttributes, + IN ULONG ShareAccess, + IN ULONG CreateDisposition, + IN ULONG CreateOptions + ); + +// NtOpenFile: +// Opens a file or device object. Same as calling: +// NtCreateFile(FileHandle, DesiredAccess, ObjectAttributes, +// IoStatusBlock, NULL, 0, ShareAccess, OPEN_EXISTING, OpenOptions); +// +// Differences from NT: See NtCreateFile. +NTSYSAPI +EXPORTNUM(202) +NTSTATUS +NTAPI +NtOpenFile( + OUT PHANDLE FileHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes, + OUT PIO_STATUS_BLOCK IoStatusBlock, + IN ULONG ShareAccess, + IN ULONG OpenOptions + ); + +// NtReadFile: +// Reads a file. +// +// Differences from NT: There is no Key parameter. +NTSYSAPI +EXPORTNUM(219) +NTSTATUS +NTAPI +NtReadFile( + IN HANDLE FileHandle, + IN HANDLE Event OPTIONAL, + IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, + IN PVOID ApcContext OPTIONAL, + OUT PIO_STATUS_BLOCK IoStatusBlock, + OUT PVOID Buffer, + IN ULONG Length, + IN PLARGE_INTEGER ByteOffset + ); + +// NtWriteFile: +// Writes a file. +// +// Differences from NT: There is no Key parameter. +NTSYSAPI +EXPORTNUM(236) +NTSTATUS +NTAPI +NtWriteFile( + IN HANDLE FileHandle, + IN HANDLE Event OPTIONAL, + IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, + IN PVOID ApcContext OPTIONAL, + OUT PIO_STATUS_BLOCK IoStatusBlock, + IN PVOID Buffer, + IN ULONG Length, + IN PLARGE_INTEGER ByteOffset + ); + +// NtQueryVolumeInformation: +// Queries information about a file system. This is not documented by +// Microsoft even under NT. +// +// Differences from NT: None known. +NTSYSAPI +EXPORTNUM(218) +NTSTATUS +NTAPI +NtQueryVolumeInformationFile( + IN HANDLE FileHandle, + OUT PIO_STATUS_BLOCK IoStatusBlock, + OUT PVOID VolumeInformation, + IN ULONG VolumeInformationLength, + IN FS_INFORMATION_CLASS VolumeInformationClass + ); + +// NtDeviceIoControl: +// Does an IOCTL on a device. +// +// Differences from NT: None known. +NTSYSAPI +EXPORTNUM(196) +NTSTATUS +NTAPI +NtDeviceIoControlFile( + IN HANDLE FileHandle, + IN HANDLE Event OPTIONAL, + IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, + IN PVOID ApcContext OPTIONAL, + OUT PIO_STATUS_BLOCK IoStatusBlock, + IN ULONG IoControlCode, + IN PVOID InputBuffer OPTIONAL, + IN ULONG InputBufferLength, + OUT PVOID OutputBuffer OPTIONAL, + IN ULONG OutputBufferLength + ); + +// NtClose: +// Closes a file or other handle. +// +// Differences from NT: None. +NTSYSAPI +EXPORTNUM(187) +NTSTATUS +NTAPI +NtClose( + IN HANDLE Handle + ); + +// NtAllocateVirtualMemory: +// Allocates virtual memory. +// +// Differences from NT: There is no ProcessHandle parameter. +NTSYSAPI +EXPORTNUM(184) +NTSTATUS +NTAPI +NtAllocateVirtualMemory( + IN OUT PVOID *BaseAddress, + IN ULONG ZeroBits, + IN OUT PULONG AllocationSize, + IN ULONG AllocationType, + IN ULONG Protect + ); + +// NtFreeVirtualMemory: +// Frees virtual memory. +// +// Differences from NT: There is no ProcessHandle parameter. +NTSYSAPI +EXPORTNUM(199) +NTSTATUS +NTAPI +NtFreeVirtualMemory( + IN OUT PVOID *BaseAddress, + IN OUT PULONG FreeSize, + IN ULONG FreeType + ); + + +// Kernel-level routines + + +// KeBugCheck: +// Bug checks the kernel. +// Same as KeBugCheckEx(BugCheckCode, 0, 0, 0, 0); +// +// Differences from NT: None, other than the reaction. +NTSYSAPI +EXPORTNUM(95) +VOID +NTAPI +KeBugCheck( + IN ULONG BugCheckCode + ); + +// KeBugCheckEx: +// Bug checks the kernel. +// +// Differences from NT: None, other than the reaction. +NTSYSAPI +EXPORTNUM(96) +VOID +NTAPI +KeBugCheckEx( + IN ULONG BugCheckCode, + IN ULONG_PTR BugCheckParameter1, + IN ULONG_PTR BugCheckParameter2, + IN ULONG_PTR BugCheckParameter3, + IN ULONG_PTR BugCheckParameter4 + ); + +// KeInitializeDpc: +// Initializes a DPC structure. +// +// Differences from NT: This function sets less fields than the NT version. +NTSYSAPI +EXPORTNUM(107) +VOID +NTAPI +KeInitializeDpc( + IN PKDPC Dpc, + IN PKDEFERRED_ROUTINE DeferredRoutine, + IN PVOID DeferredContext + ); + +// KeInitializeTimerEx: +// Initializes a timer. +// +// Differences from NT: None. +NTSYSAPI +EXPORTNUM(113) +VOID +KeInitializeTimerEx( + IN OUT PKTIMER Timer, + IN TIMER_TYPE Type + ); + +// KeRaiseIrql: +// Raises IRQL to some value. +// +// Differences from NT: None. +#define KeRaiseIrql KfRaiseIrql +NTSYSAPI +EXPORTNUM(190) +VOID +__fastcall +KfRaiseIrql( + IN KIRQL NewIrql, + OUT PKIRQL OldIrql + ); + +// KeRaiseIrqlToDpcLevel: +// Raises IRQL to DISPATCH_LEVEL. Like KeRaiseIrql except returns old level directly. +// +// Differences from NT: None. +NTSYSAPI +EXPORTNUM(129) +KIRQL +NTAPI +KeRaiseIrqlToDpcLevel( + VOID + ); + +// KeLowerIrql: +// Lowers IRQL. +#define KeLowerIrql KfLowerIrql +NTSYSAPI +EXPORTNUM(161) +VOID +__fastcall +KfLowerIrql( + IN KIRQL NewIrql + ); + + +// MmMapIoSpace: +// Maps a physical address area into the virtual address space. +// DO NOT USE MEMORY MAPPED WITH THIS AS A BUFFER TO OTHER CALLS. For +// example, don't WriteFile or NtWriteFile these buffers. Copy them first. +// +// Differences from NT: PhysicalAddress is 32 bit, not 64. ProtectionType +// specifies the page protections, but it's a Win32 PAGE_ macro instead +// of the normal NT enumeration. PAGE_READWRITE is probably what you +// want... +NTSYSAPI +EXPORTNUM(177) +PVOID +NTAPI +MmMapIoSpace( + IN PHYSICAL_ADDRESS PhysicalAddress, + IN ULONG NumberOfBytes, + IN ULONG ProtectionType + ); + +// MmGetPhysicalAddress: +// Translates a virtual address into a physical address. +// +// Differences from NT: PhysicalAddress is 32 bit, not 64. +NTSYSAPI +EXPORTNUM(173) +PHYSICAL_ADDRESS +NTAPI +MmGetPhysicalAddress( + IN PVOID BaseAddress + ); + +// MmUnmapIoSpace: +// Unmaps a virtual address mapping made by MmMapIoSpace. +// +// Differences from NT: None. +NTSYSAPI +EXPORTNUM(183) +PVOID +NTAPI +MmUnmapIoSpace( + IN PVOID BaseAddress, + IN ULONG NumberOfBytes + ); + +// MmAllocateContiguousMemory: +// Allocates a range of physically contiguous, cache-aligned memory from the +// non-paged pool (= main pool on XBOX). +// +// Differences from NT: HighestAcceptableAddress was deleted, opting instead +// to not care about the highest address. +NTSYSAPI +EXPORTNUM(165) +PVOID +NTAPI +MmAllocateContiguousMemory( + IN ULONG NumberOfBytes + ); + +// MmFreeContiguousMemory: +// Frees memory allocated with MmAllocateContiguousMemory. +// +// Differences from NT: None. +NTSYSAPI +EXPORTNUM(171) +VOID +NTAPI +MmFreeContiguousMemory( + IN PVOID BaseAddress + ); + + +// DbgPrint +// Displays a message on the debugger. +// +// Differences from NT: Only how this information is displayed changed. +NTSYSAPI +EXPORTNUM(8) +ULONG +__cdecl +DbgPrint( + IN PCSZ Format, + ... + ); + + +// ExAllocatePoolWithTag: +// Allocates memory from the memory pool. The Tag parameter is a 4-letter +// character constant to which to associate the allocation. +// +// Differences from NT: There is no PoolType field, as the XBOX only has 1 +// pool, the non-paged pool. +NTSYSAPI +EXPORTNUM(15) +PVOID +NTAPI +ExAllocatePoolWithTag( + IN SIZE_T NumberOfBytes, + IN ULONG Tag + ); + +// ExFreePool: +// Frees memory allocated by ExAllocatePool* functions. +// +// Differences from NT: None. +NTSYSAPI +EXPORTNUM(17) +VOID +NTAPI +ExFreePool( + IN PVOID P + ); + + +// IoCreateSymbolicLink: +// Creates a symbolic link in the object namespace. +// NtCreateSymbolicLinkObject is much harder to use than this simple +// function, so just use this one. +// +// Differences from NT: Uses ANSI_STRING instead of UNICODE_STRING. +NTSYSAPI +EXPORTNUM(67) +NTSTATUS +NTAPI +IoCreateSymbolicLink( + IN PANSI_STRING SymbolicLinkName, + IN PANSI_STRING DeviceName + ); + +// IoDeleteSymbolicLink: +// Creates a symbolic link in the object namespace. Deleting symbolic links +// through the Nt* functions is a pain, so use this instead. +// +// Differences from NT: Uses ANSI_STRING instead of UNICODE_STRING. +NTSYSAPI +EXPORTNUM(69) +NTSTATUS +NTAPI +IoDeleteSymbolicLink( + IN PANSI_STRING SymbolicLinkName + ); + + +// ObReferenceObjectByHandle: +// Turns a handle into a kernel object pointer. The ObjectType parameter +// specifies what type of object it is. This function also increments the +// object's reference count. +// +// Differences from NT: There are no DesiredAccess, AccessMode, or +// HandleInformation parameters. +NTSYSAPI +EXPORTNUM(246) +NTSTATUS +NTAPI +ObReferenceObjectByHandle( + IN HANDLE Handle, + IN POBJECT_TYPE ObjectType OPTIONAL, + OUT PVOID *Object + ); + +// ObfReferenceObject/ObReferenceObject: +// Increments the object's reference count. +// +// Differences from NT: None. +#define ObReferenceObject(Object) ObfReferenceObject(Object) +NTSYSAPI +EXPORTNUM(251) +VOID +FASTCALL +ObfReferenceObject( + IN PVOID Object + ); + +// ObfDereferenceObject/ObDereferenceObject: +// Decrements the object's reference count, deleting it if it is now unused. +// +// Differences from NT: None. +#define ObDereferenceObject(a) ObfDereferenceObject(a) +NTSYSAPI +EXPORTNUM(250) +VOID +FASTCALL +ObfDereferenceObject( + IN PVOID Object + ); + + +// PsTerminateSystemThread: +// Exits the current system thread. Must be called from a system thread. +// +// Differences from NT: None. +NTSYSAPI +EXPORTNUM(258) +__declspec(noreturn) +NTSTATUS +PsTerminateSystemThread( + NTSTATUS ExitCode + ); + + + +// Kernel routines only in the XBOX + +// IoSynchronousDeviceIoControlRequest: +// NICE. Makes kernel driver stuff sooooo much easier. This does a +// blocking IOCTL on the specified device. +// +// New to the XBOX. +NTSYSAPI +EXPORTNUM(84) +NTSTATUS +NTAPI +IoSynchronousDeviceIoControlRequest( + IN ULONG IoControlCode, + IN PDEVICE_OBJECT DeviceObject, + IN PVOID InputBuffer OPTIONAL, + IN ULONG InputBufferLength, + OUT PVOID OutputBuffer OPTIONAL, + IN ULONG OutputBufferLength, + OUT PDWORD unknown_use_zero OPTIONAL, + IN BOOLEAN InternalDeviceIoControl + ); + +// ExQueryNonVolatileSettings +// Queries saved information, such as the region code. +// +// New to the XBOX. +NTSYSAPI +EXPORTNUM(24) +NTSTATUS +NTAPI +ExQueryNonVolatileSetting( + IN ULONG ValueIndex, + OUT PULONG Type, + OUT PVOID Value, + IN ULONG ValueLength, + OUT PULONG ResultLength OPTIONAL + ); + +// ExSaveNonVolatileSettings +// Writes saved information, such as the region code. +// +// New to the XBOX. +NTSYSAPI +EXPORTNUM(29) +NTSTATUS +NTAPI +ExSaveNonVolatileSetting( + IN ULONG ValueIndex, + IN PULONG Type OPTIONAL, + IN PVOID Value, + IN ULONG ValueLength + ); + +// HalEnableSecureTrayEject: +// Notifies the SMBUS that ejecting the DVD-ROM should not reset the system. +// Note that this function can't really be called directly... +// +// New to the XBOX. +NTSYSAPI +EXPORTNUM(365) +VOID +NTAPI +HalEnableSecureTrayEject( + VOID + ); + +// XeLoadSection: +// Adds one to the reference count of the specified section and loads if the +// count is now above zero. +// +// New to the XBOX. +NTSYSAPI +EXPORTNUM(327) +NTSTATUS +NTAPI +XeLoadSection( + IN OUT PXBE_SECTION section + ); + +// XeUnloadSection: +// Subtracts one from the reference count of the specified section and loads +// if the count is now below zero. +// +// New to the XBOX. +NTSYSAPI +EXPORTNUM(328) +NTSTATUS +NTAPI +XeUnloadSection( + IN OUT PXBE_SECTION section + ); + +// RtlRip: +// Traps to the debugger with a certain message, then crashes. +// +// New to the XBOX. +NTSYSAPI +EXPORTNUM(352) +VOID +NTAPI +RtlRip( + IN PCSZ Part1, + IN PCSZ Part2, + IN PCSZ Part3 + ); + +// PsCreateSystemThread: +// Creates a system thread. Same as: +// PsCreateSystemThreadEx(ThreadHandle, NULL, 0x3000, 0, ThreadId, StartContext1, +// StartContext2, FALSE, DebugStack, PspSystemThreadStartup); +// +// New to the XBOX. (It is too different from NT to be considered the same) +NTSYSAPI +EXPORTNUM(254) +NTSTATUS +NTAPI +PsCreateSystemThread( + OUT PHANDLE ThreadHandle, + OUT PULONG ThreadId OPTIONAL, + IN PVOID StartContext1, + IN PVOID StartContext2, + IN BOOLEAN DebugStack + ); + +// PsCreateSystemThreadEx: +// Creates a system thread. +// ThreadHandle: Receives the thread handle +// ObjectAttributes: Unsure how this works (everything I've seen uses NULL) +// KernelStackSize: Size of the allocation for both stack and TLS data +// TlsDataSize: Size within KernelStackSize to use as TLS data +// ThreadId: Receives the thread ID number +// StartContext1: Parameter 1 to StartRoutine +// StartContext2: Parameter 2 to StartRoutine +// CreateSuspended: TRUE to create the thread as a suspended thread +// DebugStack: TRUE to allocate the stack from Debug Kit memory +// StartRoutine: Called when the thread is created +// +// New to the XBOX. +NTSYSAPI +EXPORTNUM(255) +NTSTATUS +NTAPI +PsCreateSystemThreadEx( + OUT PHANDLE ThreadHandle, + IN PVOID ObjectAttributes OPTIONAL, + IN ULONG KernelStackSize, + IN ULONG TlsDataSize, + OUT PULONG ThreadId OPTIONAL, + IN PVOID StartContext1, + IN PVOID StartContext2, + IN BOOLEAN CreateSuspended, + IN BOOLEAN DebugStack, + IN PKSTART_ROUTINE StartRoutine + ); + + + +// Error codes +#define STATUS_SUCCESS 0x00000000 +#define STATUS_UNSUCCESSFUL 0xC0000001 +#define STATUS_UNRECOGNIZED_MEDIA 0xC0000014 +// The SCSI input buffer was too large (not necessarily an error!) +#define STATUS_DATA_OVERRUN 0xC000003C +#define STATUS_INVALID_IMAGE_FORMAT 0xC000007B +#define STATUS_INSUFFICIENT_RESOURCES 0xC000009A +#define STATUS_TOO_MANY_SECRETS 0xC0000156 +#define STATUS_REGION_MISMATCH 0xC0050001 + +// End extern "C" for C++ +#if defined(__cplusplus) && !defined(XBOXINTERNAL_NO_EXTERN_C) +}; +#endif // __cplusplus + +#include + +// Thanks and credit go to Team Evox +typedef struct +{ + DWORD Data_00; // Check Block Start + DWORD Data_04; + DWORD Data_08; + DWORD Data_0c; + DWORD Data_10; // Check Block End + + DWORD V1_IP; // 0x14 + DWORD V1_Subnetmask; // 0x18 + DWORD V1_Defaultgateway; // 0x1c + DWORD V1_DNS1; // 0x20 + DWORD V1_DNS2; // 0x24 + + DWORD Data_28; // Check Block Start + DWORD Data_2c; + DWORD Data_30; + DWORD Data_34; + DWORD Data_38; // Check Block End + + DWORD V2_Tag; // V2 Tag "XBV2" + + DWORD Flag; // 0x40 + DWORD Data_44; + + DWORD V2_IP; // 0x48 + DWORD V2_Subnetmask; // 0x4c + DWORD V2_Defaultgateway; // 0x50 + DWORD V2_DNS1; // 0x54 + DWORD V2_DNS2; // 0x58 + + DWORD Data_xx[0x200-0x5c]; + +} TXNetConfigParams,*PTXNetConfigParams; + + +extern "C" +{ + // Thanks and credit go to Woodoo + extern VOID WINAPI HalInitiateShutdown(VOID); + extern VOID WINAPI HalWriteSMBusValue(BYTE, BYTE, BOOL, BYTE); + extern VOID WINAPI HalReadSMCTrayState(DWORD* state, DWORD* count); + + // Thanks and credit go to Team Evox + extern VOID WINAPI HalReturnToFirmware(DWORD); + + extern INT WINAPI XNetLoadConfigParams(LPBYTE); + extern INT WINAPI XNetSaveConfigParams(LPBYTE); + + extern INT WINAPI XWriteTitleInfoNoReboot(LPVOID,LPVOID,DWORD,DWORD,LPVOID); + + extern DWORD* LaunchDataPage; +} + + + +#endif // __XBOX_INTERNAL_H__ diff --git a/xbox1/RetroLaunch/Video.cpp b/xbox1/RetroLaunch/Video.cpp new file mode 100644 index 0000000000..04dfbd8e2a --- /dev/null +++ b/xbox1/RetroLaunch/Video.cpp @@ -0,0 +1,138 @@ +/** + * RetroLaunch 2012 + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. This program 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 this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. To contact the + * authors: Surreal64 CE Team (http://www.emuxtras.net) + */ + + +#include "Video.h" +#include "IniFile.h" +#include "Debug.h" + +CVideo g_video; +HRESULT g_hResult; + +CVideo::CVideo(void) +{ +} + +CVideo::~CVideo(void) +{ +} + +bool CVideo::Create(HWND hDeviceWindow, bool bWindowed) +{ + // Create the Direct3D object (leave it DX8 or should we try DX9 for WIN32 ?) + m_pD3D = Direct3DCreate8(D3D_SDK_VERSION); + + if (m_pD3D == NULL) + return false; + + // set up the structure used to create the d3d device + D3DPRESENT_PARAMETERS d3dpp; + ZeroMemory(&d3dpp, sizeof(d3dpp)); + + d3dpp.BackBufferWidth = 640; + d3dpp.BackBufferHeight = 480; + d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8; + d3dpp.BackBufferCount = 1; + //d3dpp.AutoDepthStencilFormat = D3DFMT_D16; + //d3dpp.EnableAutoDepthStencil = false; + d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; + + //Fullscreen only + if(!bWindowed) + { + if(!g_iniFile.m_currentIniEntry.bVSync) { + d3dpp.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; + }else{ + d3dpp.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_ONE; + } + } + + +#ifdef _XBOX + g_hResult = m_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, NULL, + D3DCREATE_HARDWARE_VERTEXPROCESSING, + &d3dpp, &m_pD3DDevice); +#else //WIN32 + + D3DDISPLAYMODE d3ddm; + g_hResult = m_pD3D->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &d3ddm ); + d3dpp.BackBufferFormat = d3ddm.Format; + d3dpp.Windowed = bWindowed; + d3dpp.hDeviceWindow = hDeviceWindow; + + g_hResult = m_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hDeviceWindow, + D3DCREATE_HARDWARE_VERTEXPROCESSING, + &d3dpp, &m_pD3DDevice); +#endif //#ifdef _XBOX + + if (FAILED(g_hResult)) + { + g_debug.Print("Error: D3DCreate(), CreateDevice()"); +#ifndef _XBOX + DXTrace(__FILE__, __LINE__, g_hResult, "D3DCreate(), CreateDevice()", TRUE); +#endif + return false; + } + // use an orthogonal matrix for the projection matrix + D3DXMATRIX mat; + + D3DXMatrixOrthoOffCenterLH(&mat, 0.0f, 640.0f, 480.0f, 0.0f, 0.0f, 1.0f); + + m_pD3DDevice->SetTransform(D3DTS_PROJECTION, &mat); + + // use an identity matrix for the world and view matrices + D3DXMatrixIdentity(&mat); + m_pD3DDevice->SetTransform(D3DTS_WORLD, &mat); + m_pD3DDevice->SetTransform(D3DTS_VIEW, &mat); + + // disable lighting + m_pD3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE); + + // disable z-buffer (see autodepthstencil) + m_pD3DDevice->SetRenderState(D3DRS_ZENABLE, FALSE ); + + return true; +} + + +void CVideo::BeginRender() +{ + m_pD3DDevice->Clear(0, NULL, D3DCLEAR_TARGET, + D3DCOLOR_XRGB(0, 0, 0), + 1.0f, 0); + + m_pD3DDevice->BeginScene(); +#ifdef _XBOX + m_pD3DDevice->SetFlickerFilter(g_iniFile.m_currentIniEntry.dwFlickerFilter); + m_pD3DDevice->SetSoftDisplayFilter(g_iniFile.m_currentIniEntry.bSoftDisplayFilter); +#endif +} + +void CVideo::EndRender() +{ + m_pD3DDevice->EndScene(); + + m_pD3DDevice->Present(NULL, NULL, NULL, NULL); + +} + +void CVideo::CleanUp() +{ + if( m_pD3DDevice != NULL) + m_pD3DDevice->Release(); + + if( m_pD3D != NULL) + m_pD3D->Release(); +} diff --git a/xbox1/RetroLaunch/Video.h b/xbox1/RetroLaunch/Video.h new file mode 100644 index 0000000000..500a2d205b --- /dev/null +++ b/xbox1/RetroLaunch/Video.h @@ -0,0 +1,53 @@ +/** + * RetroLaunch 2012 + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. This program 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 this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. To contact the + * authors: Surreal64 CE Team (http://www.emuxtras.net) + */ + +#pragma once + +#include "Global.h" + +#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1) + +typedef struct CustomVertex +{ + float x, y, z; + dword color; + float u, v; + //float rhw; +}CustomVertex; + + +class CVideo +{ +public: + CVideo(void); + ~CVideo(void); + + bool Create(HWND hDeviceWindow, bool bWindowed); //Device creation + + void BeginRender(); + void EndRender(); + void CleanUp(); + +public: + /*Direct3D*/IDirect3D8 *m_pD3D; //D3D object + /*D3DDevice*/IDirect3DDevice8 *m_pD3DDevice; //D3D device + +private: + + //nothing +}; + +extern CVideo g_video; +extern HRESULT g_hResult; diff --git a/xbox1/RetroLaunch/dist/Media/arial.ttf b/xbox1/RetroLaunch/dist/Media/arial.ttf new file mode 100644 index 0000000000000000000000000000000000000000..25769bbf1b0751c727fcab04da0f84fa517ec61f GIT binary patch literal 65692 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 literal 0 HcmV?d00001 diff --git a/xbox1/RetroLaunch/dist/Media/menuMainBG.png b/xbox1/RetroLaunch/dist/Media/menuMainBG.png new file mode 100644 index 0000000000000000000000000000000000000000..8e6d54eee7e13d6a95fe8586631affe6465d3fd6 GIT binary patch literal 6415 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 literal 0 HcmV?d00001 diff --git a/xbox1/RetroLaunch/dist/Media/menuMainRomSelectPanel.png b/xbox1/RetroLaunch/dist/Media/menuMainRomSelectPanel.png new file mode 100644 index 0000000000000000000000000000000000000000..377a9bae5bce8227d0721fbc9a73919b824d9c21 GIT binary patch literal 3206 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 V33Da-#&v;nGt@QHse(B^`!_dA#9jaZ literal 0 HcmV?d00001 diff --git a/xbox1/RetroLaunch/dist/Roms/Add roms here.txt b/xbox1/RetroLaunch/dist/Roms/Add roms here.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/xbox1/RetroLaunch/retroarch.h b/xbox1/RetroLaunch/retroarch.h new file mode 100644 index 0000000000..a751129251 --- /dev/null +++ b/xbox1/RetroLaunch/retroarch.h @@ -0,0 +1,5 @@ +// Automatically generated by the bundler tool from retroarch.jpg + +#define retroarch_NUM_RESOURCES 1UL + +#define retroarch_OFFSET 0UL diff --git a/xbox1/RetroLaunch/titleimage.jpg b/xbox1/RetroLaunch/titleimage.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1b0bc9586da2660ba3f1cd09fb18ce5ebd01f6c8 GIT binary patch literal 8865 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 O-z~}huk$g?&;J2#&AQP5 literal 0 HcmV?d00001 From 7fe5059267496abf17b78d51f13950c315dd3e8f Mon Sep 17 00:00:00 2001 From: freakdave Date: Sun, 22 Jul 2012 20:12:11 +0200 Subject: [PATCH 04/51] (Xbox 1) Just a quick fix ^^ --- xbox1/RetroLaunch/Launcher.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xbox1/RetroLaunch/Launcher.cpp b/xbox1/RetroLaunch/Launcher.cpp index 4b28736f7b..7b34511db9 100644 --- a/xbox1/RetroLaunch/Launcher.cpp +++ b/xbox1/RetroLaunch/Launcher.cpp @@ -27,7 +27,7 @@ bool g_bExit = false; void __cdecl main() { - g_debug.Print("Starting Launcher CE\n"); + g_debug.Print("Starting RetroLaunch\n"); // Set file cache size XSetFileCacheSize(8 * 1024 * 1024); From 772ff6005f139ef6596f7ade1ff2884e57e57141 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 22 Jul 2012 22:32:54 +0200 Subject: [PATCH 05/51] (Xbox 1) Move bottom text to 'safe area' for SDTV screens --- xbox1/RetroLaunch/MenuMain.cpp | 2 +- xbox1/RetroLaunch/RomList.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/xbox1/RetroLaunch/MenuMain.cpp b/xbox1/RetroLaunch/MenuMain.cpp index 5ee4114d5e..1cb6deab6d 100644 --- a/xbox1/RetroLaunch/MenuMain.cpp +++ b/xbox1/RetroLaunch/MenuMain.cpp @@ -128,7 +128,7 @@ void CMenuMain::Render() //Display some text //g_font.Render("Retro Arch", m_menuMainTitle_x, m_menuMainTitle_y, 20, XFONT_NORMAL, m_menuMainTitle_c); - g_font.Render("Press RIGHT ANALOG STICK to exit. Press START to launch a rom.", 65, 450, 16, XFONT_NORMAL, m_menuMainTitle_c); + g_font.Render("Press RIGHT ANALOG STICK to exit. Press START to launch a rom.", 65, 430, 16, XFONT_NORMAL, m_menuMainTitle_c); //Begin with the rom selector panel //FIXME: Width/Height needs to be current Rom texture width/height (or should we just leave it at a fixed size?) diff --git a/xbox1/RetroLaunch/RomList.cpp b/xbox1/RetroLaunch/RomList.cpp index b22381959a..5ee25a2071 100644 --- a/xbox1/RetroLaunch/RomList.cpp +++ b/xbox1/RetroLaunch/RomList.cpp @@ -27,7 +27,7 @@ RomList::RomList(void) m_romListMode = All; m_iBaseIndex = 0; m_bLoaded = false; - m_szRomPath = "D:\\Roms\\"; + m_szRomPath = "D:\\"; } RomList::~RomList(void) From c79dbebc909fde34f88f538d5a6757ab4ba1d23f Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 23 Jul 2012 10:15:17 +0200 Subject: [PATCH 06/51] (Xbox 1) Minor changes to RetroLaunch --- xbox1/RetroLaunch/Global.h | 15 ++------------- xbox1/RetroLaunch/Surface.cpp | 5 ----- xbox1/RetroLaunch/Video.cpp | 19 ------------------- 3 files changed, 2 insertions(+), 37 deletions(-) diff --git a/xbox1/RetroLaunch/Global.h b/xbox1/RetroLaunch/Global.h index f84ba2529f..087fd8c68c 100644 --- a/xbox1/RetroLaunch/Global.h +++ b/xbox1/RetroLaunch/Global.h @@ -26,19 +26,8 @@ #include #include #include -#ifdef _XBOX - #include - #include -#else - #pragma comment(lib,"d3d8.lib") - #pragma comment(lib,"d3dx8.lib") - #pragma comment(lib,"DxErr8.lib") - #define WIN32_LEAN_AND_MEAN - #include - #include - #include - #include -#endif +#include +#include using namespace std; diff --git a/xbox1/RetroLaunch/Surface.cpp b/xbox1/RetroLaunch/Surface.cpp index f4ca398534..e0ac7b8e98 100644 --- a/xbox1/RetroLaunch/Surface.cpp +++ b/xbox1/RetroLaunch/Surface.cpp @@ -201,12 +201,7 @@ bool CSurface::Render(int x, int y, dword w, dword h) g_video.m_pD3DDevice->SetTexture(0, m_pTexture); g_video.m_pD3DDevice->SetStreamSource(0, m_pVertexBuffer, sizeof(CustomVertex)); g_video.m_pD3DDevice->SetVertexShader(D3DFVF_CUSTOMVERTEX); -#ifdef _XBOX g_video.m_pD3DDevice->DrawPrimitive(D3DPT_QUADLIST, 0, 1); -#else - //FIXME: vertices order ! - g_video.m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2); -#endif return true; } diff --git a/xbox1/RetroLaunch/Video.cpp b/xbox1/RetroLaunch/Video.cpp index 04dfbd8e2a..28d5ba67fc 100644 --- a/xbox1/RetroLaunch/Video.cpp +++ b/xbox1/RetroLaunch/Video.cpp @@ -59,30 +59,13 @@ bool CVideo::Create(HWND hDeviceWindow, bool bWindowed) } } - -#ifdef _XBOX g_hResult = m_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, NULL, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &m_pD3DDevice); -#else //WIN32 - - D3DDISPLAYMODE d3ddm; - g_hResult = m_pD3D->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &d3ddm ); - d3dpp.BackBufferFormat = d3ddm.Format; - d3dpp.Windowed = bWindowed; - d3dpp.hDeviceWindow = hDeviceWindow; - - g_hResult = m_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hDeviceWindow, - D3DCREATE_HARDWARE_VERTEXPROCESSING, - &d3dpp, &m_pD3DDevice); -#endif //#ifdef _XBOX if (FAILED(g_hResult)) { g_debug.Print("Error: D3DCreate(), CreateDevice()"); -#ifndef _XBOX - DXTrace(__FILE__, __LINE__, g_hResult, "D3DCreate(), CreateDevice()", TRUE); -#endif return false; } // use an orthogonal matrix for the projection matrix @@ -114,10 +97,8 @@ void CVideo::BeginRender() 1.0f, 0); m_pD3DDevice->BeginScene(); -#ifdef _XBOX m_pD3DDevice->SetFlickerFilter(g_iniFile.m_currentIniEntry.dwFlickerFilter); m_pD3DDevice->SetSoftDisplayFilter(g_iniFile.m_currentIniEntry.bSoftDisplayFilter); -#endif } void CVideo::EndRender() From 009addb8d521743f8271024b11fbe92acac9d99f Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 23 Jul 2012 10:18:32 +0200 Subject: [PATCH 07/51] (360) remove redundant code in main.c --- xdk/frontend/main.c | 112 -------------------------------------------- 1 file changed, 112 deletions(-) diff --git a/xdk/frontend/main.c b/xdk/frontend/main.c index 12f88a38b4..dd2a675e22 100644 --- a/xdk/frontend/main.c +++ b/xdk/frontend/main.c @@ -41,105 +41,13 @@ #include "../../file.h" #include "../../general.h" -#define DEVICE_MEMORY_UNIT0 1 -#define DEVICE_MEMORY_UNIT1 2 -#define DEVICE_MEMORY_ONBOARD 3 -#define DEVICE_CDROM0 4 -#define DEVICE_HARDISK0_PART1 5 -#define DEVICE_HARDISK0_SYSPART 6 -#define DEVICE_USB0 7 -#define DEVICE_USB1 8 -#define DEVICE_USB2 9 -#define DEVICE_TEST 10 -#define DEVICE_CACHE 11 - -typedef struct _STRING { - unsigned short Length; - unsigned short MaximumLength; - char * Buffer; -} STRING; - char DEFAULT_SHADER_FILE[PATH_MAX]; char SYS_CONFIG_FILE[PATH_MAX]; -#ifdef _XBOX360 -extern "C" int __stdcall ObCreateSymbolicLink( STRING*, STRING*); -#endif - -int Mounted[20]; - int rarch_main(int argc, char *argv[]); #undef main -#ifdef _XBOX360 -static int DriveMounted(std::string path) -{ - WIN32_FIND_DATA findFileData; - memset(&findFileData,0,sizeof(WIN32_FIND_DATA)); - std::string searchcmd = path + "\\*.*"; - HANDLE hFind = FindFirstFile(searchcmd.c_str(), &findFileData); - - if (hFind == INVALID_HANDLE_VALUE) - return 0; - - FindClose(hFind); - - return 1; -} - -static int Mount( int Device, char* MountPoint ) -{ - char MountConv[260]; - char * SysPath = NULL; - - snprintf( MountConv, sizeof(MountConv), "\\??\\%s", MountPoint ); - - switch( Device ) - { - case DEVICE_MEMORY_UNIT0: - SysPath = "\\Device\\Mu0"; - break; - case DEVICE_MEMORY_UNIT1: - SysPath = "\\Device\\Mu1"; - break; - case DEVICE_MEMORY_ONBOARD: - SysPath = "\\Device\\BuiltInMuSfc"; - break; - case DEVICE_CDROM0: - SysPath = "\\Device\\Cdrom0"; - break; - case DEVICE_HARDISK0_PART1: - SysPath = "\\Device\\Harddisk0\\Partition1"; - break; - case DEVICE_HARDISK0_SYSPART: - SysPath = "\\Device\\Harddisk0\\SystemPartition"; - break; - case DEVICE_USB0: - SysPath = "\\Device\\Mass0"; - break; - case DEVICE_USB1: - SysPath = "\\Device\\Mass1"; - break; - case DEVICE_USB2: - SysPath = "\\Device\\Mass2"; - break; - case DEVICE_CACHE: - SysPath = "\\Device\\Harddisk0\\Cache0"; - break; - } - - STRING sSysPath = { (USHORT)strlen( SysPath ), (USHORT)strlen( SysPath ) + 1, SysPath }; - STRING sMountConv = { (USHORT)strlen( MountConv ), (USHORT)strlen( MountConv ) + 1, MountConv }; - int res = ObCreateSymbolicLink( &sMountConv, &sSysPath ); - - if (res != 0) - return res; - - return DriveMounted(MountPoint); -} -#endif - static void set_default_settings (void) { //g_settings @@ -184,26 +92,6 @@ static void set_default_settings (void) static void get_environment_settings (void) { -#ifdef _XBOX360 - DWORD ret; - - //for devkits only, we will need to mount all partitions for retail - //in a different way - //DmMapDevkitDrive(); - - memset(&Mounted, 0, 20); - - Mounted[DEVICE_USB0] = Mount(DEVICE_USB0,"Usb0:"); - Mounted[DEVICE_USB1] = Mount(DEVICE_USB1,"Usb1:"); - Mounted[DEVICE_USB2] = Mount(DEVICE_USB2,"Usb2:"); - Mounted[DEVICE_HARDISK0_PART1] = Mount(DEVICE_HARDISK0_PART1,"Hdd1:"); - Mounted[DEVICE_HARDISK0_SYSPART] = Mount(DEVICE_HARDISK0_SYSPART,"HddX:"); - Mounted[DEVICE_MEMORY_UNIT0] = Mount(DEVICE_MEMORY_UNIT0,"Memunit0:"); - Mounted[DEVICE_MEMORY_UNIT1] = Mount(DEVICE_MEMORY_UNIT1,"Memunit1:"); - Mounted[DEVICE_MEMORY_ONBOARD] = Mount(DEVICE_MEMORY_ONBOARD,"OnBoardMU:"); - Mounted[DEVICE_CDROM0] = Mount(DEVICE_CDROM0,"Dvd:"); -#endif - #ifdef HAVE_HDD_CACHE_PARTITION ret = XSetFileCacheSize(0x100000); From c800df6fd59ca722c056a1e93cd40c42951634a5 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 23 Jul 2012 10:23:27 +0200 Subject: [PATCH 08/51] (360) Quick compile fix --- xdk/frontend/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/xdk/frontend/main.c b/xdk/frontend/main.c index dd2a675e22..fc6b40646c 100644 --- a/xdk/frontend/main.c +++ b/xdk/frontend/main.c @@ -92,6 +92,7 @@ static void set_default_settings (void) static void get_environment_settings (void) { + HRESULT ret; #ifdef HAVE_HDD_CACHE_PARTITION ret = XSetFileCacheSize(0x100000); From bf746281bd9cc8484c002a7e432b13a5436e6961 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Mon, 23 Jul 2012 11:09:36 +0200 Subject: [PATCH 09/51] (PS3) Cleaned up RGL code + fixed ifdef error in Salamander --- Makefile.ps3.retroarch | 2 + Makefile.ps3.rgl | 2 + console/rgl/ps3/device_ctx.cpp | 66 ++++++++++++++++---------------- console/rgl/ps3/private.h | 12 ------ console/rgl/ps3/rgl.cpp | 69 ++++++++++++++-------------------- console/rgl/ps3/rgl.h | 16 -------- console/rgl/ps3/vector | 4 -- console/salamander/main.c | 2 +- 8 files changed, 66 insertions(+), 107 deletions(-) diff --git a/Makefile.ps3.retroarch b/Makefile.ps3.retroarch index f39189d309..31ca1f83ee 100644 --- a/Makefile.ps3.retroarch +++ b/Makefile.ps3.retroarch @@ -41,6 +41,8 @@ else PPU_CXXLD = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-ld.exe endif +PPU_RANLIB = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-ranlib.exe + DEFINES += -DHAVE_DEFAULT_RETROPAD_INPUT -DHAVE_THREAD -DRARCH_CONSOLE -DHAVE_OPENGL -DHAVE_OPENGL_TEXREF -DHAVE_HEADSET -DHAVE_VID_CONTEXT -DHAVE_OPENGLES11 -DHAVE_CG -DHAVE_CG_MENU -DHAVE_FILEBROWSER -DHAVE_HDD_CACHE_PARTITION -DHAVE_FBO -DHAVE_RARCH_MAIN_WRAP -DHAVE_SYSMODULES -DHAVE_SYSUTILS -DHAVE_RARCH_EXEC -DHAVE_RGL -DHAVE_LIBRETRO_MANAGEMENT -DHAVE_RSOUND -DHAVE_ZLIB -D__CELLOS_LV2__ -DHAVE_CONFIGFILE=1 -DHAVE_NETPLAY=1 -DHAVE_SOCKET_LEGACY=1 -DHAVE_OSKUTIL -DHAVE_MOUSE -DHAVE_GRIFFIN=1 -DHAVE_MULTIMAN=1 -DPACKAGE_VERSION=\"$(RARCH_VERSION)\" -Dmain=rarch_main -DPC_DEVELOPMENT_IP_ADDRESS=\"$(PC_DEVELOPMENT_IP_ADDRESS)\" -DPC_DEVELOPMENT_UDP_PORT=$(PC_DEVELOPMENT_UDP_PORT) ifeq ($(DEBUG), 1) diff --git a/Makefile.ps3.rgl b/Makefile.ps3.rgl index 7fa4d70fc9..124a37a73a 100644 --- a/Makefile.ps3.rgl +++ b/Makefile.ps3.rgl @@ -34,6 +34,8 @@ else PPU_AR = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-ar.exe endif +PPU_RANLIB = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-ranlib.exe + PPU_LDLIBS = -lio_stub diff --git a/console/rgl/ps3/device_ctx.cpp b/console/rgl/ps3/device_ctx.cpp index 967a51f911..90aeeb3e5a 100644 --- a/console/rgl/ps3/device_ctx.cpp +++ b/console/rgl/ps3/device_ctx.cpp @@ -18,6 +18,8 @@ #include #endif +#include "../../../general.h" + using namespace cell::Gcm; #define _RGL_MAX_TILED_REGIONS 15 @@ -307,7 +309,7 @@ GLboolean _RGLInit( PSGLinitOptions* options, RGLResource *resource ) { if ( !_RGLInitFromRM( resource ) ) { - fprintf( stderr, "PSGL GCM failed initialisation" ); + RARCH_ERR("RGL GCM failed initialisation.\n"); return GL_FALSE; } @@ -318,7 +320,7 @@ GLboolean _RGLInit( PSGLinitOptions* options, RGLResource *resource ) resource->hostMemoryBase + resource->hostMemoryReserved, resource->hostMemorySize - resource->hostMemoryReserved ) == GMM_ERROR ) { - fprintf( stderr, "Could not init GPU memory manager" ); + RARCH_ERR("Could not initialize GPU memory manager.\n"); _RGLDestroy(); return GL_FALSE; } @@ -405,7 +407,7 @@ const VideoMode *_RGLDetectVideoMode (void) int ret = cellVideoOutGetState( CELL_VIDEO_OUT_PRIMARY, 0, &videoState ); if ( ret < 0 ) { - printf("RGL WARN: couldn't read the video configuration, using a default 720p resolution.\n"); + RARCH_WARN("Couldn't read the video configuration, using a default 720p resolution.\n"); videoState.displayMode.scanMode = CELL_VIDEO_OUT_SCAN_MODE_PROGRESSIVE; videoState.displayMode.resolutionId = CELL_VIDEO_OUT_RESOLUTION_720; } @@ -538,15 +540,15 @@ void _RGLGraphicsHandler( const uint32_t head ) uint32_t *tmp = ( uint32_t * )(( char* )fifo->dmaPushBufferBegin - fifo->dmaPushBufferOffset + ( *(( volatile GLuint* ) & fifo->dmaControl->Get ) ) ); if (( tmp >= fifo->begin ) && ( tmp <= fifo->end ) ) fifo->lastGetRead = tmp; - printf("RGL: Current PSGL FIFO info \n" ); - printf("RGL: Fifo Begin %p End %p Current %p and Get %p \n", + RARCH_ERR("Current PSGL FIFO info:\n" ); + RARCH_ERR("FIFO Begin %p End %p Current %p and Get %p \n", _RGLState.fifo.begin, _RGLState.fifo.end, _RGLState.fifo.current, _RGLState.fifo.lastGetRead ); - printf("RGL: Last 10 words of the PSGL Fifo from the ppu put/current position \n" ); + RARCH_ERR("Last 10 words of the PSGL Fifo from the ppu put/current position \n" ); _RGLPrintFifoFromPut( 10 ); - printf("RGL: Last 10 words of the PSGL Fifo from the gpu get position \n" ); + RARCH_ERR("Last 10 words of the PSGL Fifo from the gpu get position \n" ); _RGLPrintFifoFromGet( 10 ); } @@ -565,7 +567,7 @@ static int _RGLInitRM( RGLResource *gcmResource, unsigned int hostMemorySize, in if ( cellGcmInit( _RGL_FIFO_SIZE, gcmResource->hostMemorySize, gcmResource->hostMemoryBase ) != 0 ) { - printf("RGL: RSXIF failed initialization\n" ); + RARCH_ERR("RSXIF failed initialization.\n"); return GL_FALSE; } @@ -595,13 +597,14 @@ static int _RGLInitRM( RGLResource *gcmResource, unsigned int hostMemorySize, in gCellGcmCurrentContext->callback = ( CellGcmContextCallback )_RGLOutOfSpaceCallback; - - printf( "RGL: MClk: %f Mhz NVClk: %f Mhz\n", ( float )gcmResource->MemoryClock / 1E6, ( float )gcmResource->GraphicsClock / 1E6 ); - printf( "RGL: Video Memory: %i MB\n", gcmResource->localSize / ( 1024*1024 ) ); - printf( "RGL: localAddress mapped at %p\n", gcmResource->localAddress ); - printf( "RGL: push buffer at %p - %p (size = 0x%X), offset=0x%lx\n", - gcmResource->dmaPushBuffer, ( char* )gcmResource->dmaPushBuffer + gcmResource->dmaPushBufferSize, gcmResource->dmaPushBufferSize, gcmResource->dmaPushBufferOffset ); - printf( "RGL: dma control at %p\n", gcmResource->dmaControl ); +#ifdef LOG_VERBOSE + RARCH_LOG("MClk: %f Mhz NVClk: %f Mhz.\n", ( float )gcmResource->MemoryClock / 1E6, ( float )gcmResource->GraphicsClock / 1E6 ); + RARCH_LOG("Video Memory: %i MB.\n", gcmResource->localSize / ( 1024*1024 ) ); + RARCH_LOG("Local address mapped at %p.\n", gcmResource->localAddress ); + RARCH_LOG("Push buffer at %p - %p (size = 0x%X), offset=0x%lx.\n", + gcmResource->dmaPushBuffer, ( char* )gcmResource->dmaPushBuffer + gcmResource->dmaPushBufferSize, gcmResource->dmaPushBufferSize, gcmResource->dmaPushBufferOffset ); + RARCH_LOG("DMA control at %p.\n", gcmResource->dmaControl ); +#endif return 1; } @@ -621,7 +624,7 @@ void _RGLDeviceInit( PSGLinitOptions* options ) if ( !_RGLInitRM( &_RGLResource, hostSize, 0, fifoSize ) ) { - printf("RGL: RM resource failed initialisation\n" ); + RARCH_ERR("RM resource failed initialization.\n" ); return; } @@ -714,7 +717,9 @@ GLboolean _RGLAllocateColorSurface( *pitchAllocated = 0; } else - printf("RGL: Allocating GPU memory (tiled): %d bytes allocated at id 0x%08x.\n", *bytesAllocated, *id ); + { + RARCH_LOG("Allocating GPU memory (tiled): %d bytes allocated at id 0x%08x.\n", *bytesAllocated, *id ); + } return *bytesAllocated > 0; } @@ -731,8 +736,7 @@ GLboolean _RGLAllocateColorSurface( static void rescInit( const PSGLdeviceParameters* params, RGLDevice *gcmDevice ) { - printf("RGL WARN: RESC is enabled.\n"); - GLboolean result = 0; + RARCH_WARN("RESC is enabled.\n"); CellRescBufferMode dstBufferMode; if ( params->width == 720 && params->height == 480 ) dstBufferMode = CELL_RESC_720x480; @@ -742,7 +746,7 @@ static void rescInit( const PSGLdeviceParameters* params, RGLDevice *gcmDevice ) else { dstBufferMode = CELL_RESC_720x480; - printf("RGL: Invalid display resolution for resolution conversion: %ux%u. Defaulting to 720x480...\n", params->width, params->height ); + RARCH_ERR("Invalid display resolution for resolution conversion: %ux%u. Defaulting to 720x480...\n", params->width, params->height ); } CellRescInitConfig conf; @@ -763,7 +767,7 @@ static void rescInit( const PSGLdeviceParameters* params, RGLDevice *gcmDevice ) GLuint colorBuffersPitch; uint32_t numColorBuffers = cellRescGetNumColorBuffers( dstBufferMode, ( CellRescPalTemporalMode )conf.palTemporalMode, 0 ); - result = _RGLAllocateColorSurface( params->width, params->height * numColorBuffers, + _RGLAllocateColorSurface( params->width, params->height * numColorBuffers, 4*8, &(gcmDevice->RescColorBuffersId), &colorBuffersPitch, &size ); CellRescDsts dsts = { CELL_RESC_SURFACE_A8R8G8B8, colorBuffersPitch, 1 }; @@ -814,13 +818,10 @@ static int _RGLPlatformCreateDevice( PSGLdevice* device ) jsTiledMemoryManager* mm = &_RGLTiledMemoryManager; _RGLDuringDestroyDevice = GL_FALSE; - GLboolean result = 0; - - int32_t retVal; memset( mm->region, 0, sizeof( mm->region ) ); for ( int i = 0;i < _RGL_MAX_TILED_REGIONS;++i ) - retVal = cellGcmUnbindTile( i ); + cellGcmUnbindTile( i ); const VideoMode *vm = NULL; @@ -873,7 +874,7 @@ static int _RGLPlatformCreateDevice( PSGLdevice* device ) gcmDevice->color[i].pool = _RGL_SURFACE_POOL_LINEAR; GLuint size; - result = _RGLAllocateColorSurface(width, height, + _RGLAllocateColorSurface(width, height, gcmDevice->color[i].bpp*8, &gcmDevice->color[i].dataId, &gcmDevice->color[i].pitch, &size ); } @@ -961,7 +962,7 @@ static int _RGLPlatformCreateDevice( PSGLdevice* device ) if ( cellRescSetSrc( i, &rescSrc ) != CELL_OK ) { - printf("RGL: Registering display buffer %d failed\n", i ); + RARCH_ERR("Registering display buffer %d failed.\n", i ); return -1; } } @@ -978,7 +979,7 @@ static int _RGLPlatformCreateDevice( PSGLdevice* device ) { if ( cellGcmSetDisplayBuffer( i, gmmIdToOffset( gcmDevice->color[i].dataId ), gcmDevice->color[i].pitch , width, height ) != CELL_OK ) { - printf("RGL: Registering display buffer %d failed\n", i ); + RARCH_ERR("Registering display buffer %d failed.\n", i ); return -1; } } @@ -1221,7 +1222,7 @@ GLAPI void psglSwap( void ) int32_t res = cellRescSetConvertAndFlip(( uint8_t ) drawBuffer ); if ( res != CELL_OK ) { - printf("RGL WARN: RESC cellRescSetConvertAndFlip returned error code %d.\n", res); + RARCH_WARN("RESC cellRescSetConvertAndFlip returned error code %d.\n", res); if ( _CurrentContext ) _CurrentContext->needValidate |= PSGL_VALIDATE_FRAMEBUFFER; return; } @@ -1301,7 +1302,6 @@ static inline void _RGLUtilWaitForIdle (void) GLboolean _RGLTryResizeTileRegion( GLuint address, GLuint size, void* data ) { jsTiledRegion* region = ( jsTiledRegion* )data; - int32_t retVal = 0; if ( size == 0 ) { @@ -1312,7 +1312,7 @@ GLboolean _RGLTryResizeTileRegion( GLuint address, GLuint size, void* data ) if ( ! _RGLDuringDestroyDevice ) { _RGLUtilWaitForIdle(); - retVal = cellGcmUnbindTile( region->id ); + cellGcmUnbindTile( region->id ); _RGLFifoFinish( &_RGLState.fifo ); } return GL_TRUE; @@ -1322,11 +1322,11 @@ GLboolean _RGLTryResizeTileRegion( GLuint address, GLuint size, void* data ) _RGLUtilWaitForIdle(); - retVal = cellGcmSetTileInfo(region->id, CELL_GCM_LOCATION_LOCAL, + cellGcmSetTileInfo(region->id, CELL_GCM_LOCATION_LOCAL, region->offset, region->size, region->pitch, CELL_GCM_COMPMODE_DISABLED, 0, region->bank ); - retVal = cellGcmBindTile( region->id ); + cellGcmBindTile( region->id ); _RGLFifoFinish( &_RGLState.fifo ); diff --git a/console/rgl/ps3/private.h b/console/rgl/ps3/private.h index e368a9ec14..13886d0a8d 100644 --- a/console/rgl/ps3/private.h +++ b/console/rgl/ps3/private.h @@ -307,24 +307,16 @@ static inline GLuint _RGLMapMinTextureFilter( GLenum filter ) { case GL_NEAREST: return CELL_GCM_TEXTURE_NEAREST; - break; case GL_LINEAR: return CELL_GCM_TEXTURE_LINEAR; - break; case GL_NEAREST_MIPMAP_NEAREST: return CELL_GCM_TEXTURE_NEAREST_NEAREST; - break; case GL_NEAREST_MIPMAP_LINEAR: return CELL_GCM_TEXTURE_NEAREST_LINEAR; - break; case GL_LINEAR_MIPMAP_NEAREST: return CELL_GCM_TEXTURE_LINEAR_NEAREST; - break; case GL_LINEAR_MIPMAP_LINEAR: return CELL_GCM_TEXTURE_LINEAR_LINEAR; - break; - default: - return 0; } return filter; } @@ -335,12 +327,8 @@ static inline GLuint _RGLMapMagTextureFilter( GLenum filter ) { case GL_NEAREST: return CELL_GCM_TEXTURE_NEAREST; - break; case GL_LINEAR: return CELL_GCM_TEXTURE_LINEAR; - break; - default: - return 0; } return filter; } diff --git a/console/rgl/ps3/rgl.cpp b/console/rgl/ps3/rgl.cpp index 9967431270..807a260f60 100644 --- a/console/rgl/ps3/rgl.cpp +++ b/console/rgl/ps3/rgl.cpp @@ -21,6 +21,7 @@ #include #include "../../../compat/strl.h" +#include "../../../general.h" #define RGL_ALIGN_FAST_TRANSFER 128 @@ -933,7 +934,7 @@ static GLenum _RGLPlatformFramebufferCheckStatus( jsFramebuffer* framebuffer ) { if ( !_RGLTextureIsValid( colorTexture ) ) { - printf("RGL ERR: Framebuffer color attachment texture is not complete.\n"); + RARCH_ERR("Framebuffer color attachment texture is not complete.\n"); return GL_FRAMEBUFFER_UNSUPPORTED_OES; } @@ -941,7 +942,7 @@ static GLenum _RGLPlatformFramebufferCheckStatus( jsFramebuffer* framebuffer ) if ( colorFormat && colorFormat != image[nBuffers]->internalFormat ) { - printf("RGL ERR: Framebuffer attachments have inconsistent color formats.\n" ); + RARCH_ERR("Framebuffer attachments have inconsistent color formats.\n" ); return GL_FRAMEBUFFER_INCOMPLETE_FORMATS_OES; } colorFormat = image[nBuffers]->internalFormat; @@ -952,7 +953,7 @@ static GLenum _RGLPlatformFramebufferCheckStatus( jsFramebuffer* framebuffer ) if ( nBuffers && colorFormat != RGL_ARGB8) { - printf("RGL: Color attachment to framebuffer must be a supported drawable format (GL_ARGB_SCE)\n"); + RARCH_ERR("Color attachment to framebuffer must be a supported drawable format (GL_ARGB_SCE)\n"); return GL_FRAMEBUFFER_UNSUPPORTED_OES; } @@ -4813,7 +4814,7 @@ static GLboolean _RGLPlatformTexturePBOImage( LContext->unpackAlignment ); if (( pboPitch&3 ) != 0 ) { - printf("RGL WARN: PBO image pitch not a multiple of 4, using slow path.\n" ); + RARCH_WARN("PBO image pitch not a multiple of 4, using slow path.\n" ); return GL_FALSE; } @@ -4822,7 +4823,7 @@ static GLboolean _RGLPlatformTexturePBOImage( if ( gmmIdToOffset(gpuId)+gpuIdOffset & 63 ) { - printf("RGL: PBO offset not 64-byte aligned, using slow path.\n"); + RARCH_WARN("PBO offset not 64-byte aligned, using slow path.\n"); return GL_FALSE; } @@ -4850,13 +4851,13 @@ static GLboolean _RGLPlatformTexturePBOImage( if ( !formatOK ) { - printf("RGL: PBO format/type requires conversion to texture internal format, using slow path.\n"); + RARCH_WARN("PBO format/type requires conversion to texture internal format, using slow path.\n"); return GL_FALSE; } if ( !_RGLTextureIsValid( texture ) ) { - printf("RGL: PBO transfering to incomplete texture, using slow path.\n"); + RARCH_WARN("PBO transfering to incomplete texture, using slow path.\n"); return GL_FALSE; } @@ -6083,7 +6084,7 @@ static GLboolean _RGLPlatformNeedsConversion( const jsAttributeState* as, GLuint default: break; } - printf("RGL WARN: Attribute %d needs conversion. Slow path ahead.\n", index); + RARCH_WARN("Attribute %d needs conversion. Slow path ahead.\n", index); return GL_TRUE; } @@ -7004,7 +7005,7 @@ CG_API CGprogram cgCreateProgram( CGcontext ctx, } else { - printf("RGL ERR: The CG runtime compiler hasn't been setup. cgRTCgcInit() should be called prior to this function.\n" ); + RARCH_ERR("The CG runtime compiler hasn't been setup. cgRTCgcInit() should be called prior to this function.\n" ); _RGLCgRaiseError( CG_INVALID_ENUMERANT_ERROR ); return NULL; } @@ -7026,7 +7027,7 @@ CG_API CGprogram cgCreateProgram( CGcontext ctx, // don't throw the warning if it was source, cause clearly that would have been on purpose. if ( program_type == CG_BINARY ) { - printf("RGL WARN: A binary shader is being loaded using a deprecated binary format. Please use the cgnv2elf tool to convert to the new, memory-saving, faster-loading format.\n"); + RARCH_WARN("A binary shader is being loaded using a deprecated binary format. Please use the cgnv2elf tool to convert to the new, memory-saving, faster-loading format.\n"); } //convert from NV format to the runtime format @@ -7048,7 +7049,7 @@ CG_API CGprogram cgCreateProgram( CGcontext ctx, int res = convertNvToElfFromMemory( binaryBuffer, totalSize, 2, 0, ( void** ) & runtimeElfShader, &compiled_program_size, stringTableArray, defaultValuesArray ); if ( res != 0 ) { - printf("RGL ERR: invalid CG binary program.\n"); + RARCH_ERR("Invalid CG binary program.\n"); _RGLCgRaiseError( CG_COMPILER_ERROR ); if ( compiled_program ) _cgRTCgcFreeCompiledProgramHook( compiled_program ); @@ -7098,20 +7099,20 @@ CG_API CGprogram cgCreateProgram( CGcontext ctx, CGELFProgram elfProgram; if ((( intptr_t )binaryBuffer ) & 15 ) { - printf("RGL ERR: CG Binary not aligned on 16 bytes, needed for ucode section.\n"); + RARCH_ERR("CG Binary not aligned on 16 bytes, needed for ucode section.\n"); _RGLCgRaiseError( CG_PROGRAM_LOAD_ERROR ); return NULL; } bool res = cgOpenElf( binaryBuffer, 0, &elfBinary ); if ( !res ) { - printf("RGL ERR: not a valid ELF.\n"); + RARCH_ERR("Not a valid ELF.\n"); _RGLCgRaiseError( CG_PROGRAM_LOAD_ERROR ); return NULL; } if ( !cgGetElfProgramByName( &elfBinary, entry, &elfProgram ) ) { - printf("RGL ERR: couldn't find the shader entry in the CG binary.\n"); + RARCH_ERR("Couldn't find the shader entry in the CG binary.\n"); return NULL; } @@ -7227,7 +7228,7 @@ CG_API CGprogram cgCreateProgramFromFile( CGcontext ctx, int index = _RGLCgGetProgramIndex( group, entry ); if ( index == -1 ) { - printf("RGL ERR: couldn't find the shader entry in the CG binary.\n"); + RARCH_ERR("Couldn't find the shader entry in the CG binary.\n"); } else { @@ -7691,39 +7692,26 @@ CG_API CGprofile cgGetProfile( const char* profile_string ) return CG_PROFILE_UNKNOWN; } -CG_API CGerror cgGetError( void ) +CG_API CGerror cgGetError(void) { - CGerror err = _CurrentContext->RGLcgLastError; - _CurrentContext->RGLcgLastError = CG_NO_ERROR; - return err; + CGerror err = _CurrentContext->RGLcgLastError; + _CurrentContext->RGLcgLastError = CG_NO_ERROR; + return err; } + CG_API const char* cgGetErrorString( CGerror error ) { - return "cgGetErrorString: N/A\n"; -} - -CG_API const char* cgGetLastErrorString( CGerror* error ) -{ - return "cgGetErrorString: N/A\n"; -} - -CG_API void cgSetErrorCallback( CGerrorCallbackFunc func ) -{ - _CurrentContext->RGLcgErrorCallbackFunction = func; -} - - -CG_API CGerrorCallbackFunc cgGetErrorCallback( void ) -{ - return _CurrentContext->RGLcgErrorCallbackFunction; + static char strbuf[256]; + snprintf(strbuf, sizeof(strbuf), "%d", error); + return strbuf; } void _RGLCgDestroyContextParam( CgRuntimeParameter* ptr ) { - if ( _cgParameterDestroyHook ) _cgParameterDestroyHook( ptr ); - _RGLEraseName( &_CurrentContext->cgParameterNameSpace, ( jsName )( ptr->id ) ); - free( ptr ); + if ( _cgParameterDestroyHook ) _cgParameterDestroyHook( ptr ); + _RGLEraseName( &_CurrentContext->cgParameterNameSpace, ( jsName )( ptr->id ) ); + free( ptr ); } static int _RGLGetSizeofSubArray( const short *dimensions, int count ) @@ -8400,8 +8388,7 @@ void _RGLCgRaiseError( CGerror error ) { _CurrentContext->RGLcgLastError = error; - - printf("RGL: Cg error:%s.\n", cgGetErrorString( error ) ); + RARCH_ERR("Cg error: %d.\n", error); if ( _CurrentContext->RGLcgErrorCallbackFunction ) _CurrentContext->RGLcgErrorCallbackFunction(); diff --git a/console/rgl/ps3/rgl.h b/console/rgl/ps3/rgl.h index b85fd5303a..db7d77489d 100644 --- a/console/rgl/ps3/rgl.h +++ b/console/rgl/ps3/rgl.h @@ -620,26 +620,10 @@ typedef struct #pragma warning ( pop ) #endif -#ifndef MSVC -#define MAX(A,B) ({ \ - __typeof__(A) At=(A); \ - __typeof__(B) Bt=(B); \ - At>Bt?At:Bt; }) - -#define MIN(A,B) ({ \ - __typeof__(A) At=(A); \ - __typeof__(B) Bt=(B); \ - At(B)?(A):(B)) #define MIN(A,B) ((A)<(B)?(A):(B)) #define RGL_LIKELY(COND) (COND) #define RGL_UNLIKELY(COND) (COND) -#endif #define _RGL_ALLOC_FIRST_FIT 0 #define _RGL_ALLOC_BEST_FIT 1 diff --git a/console/rgl/ps3/vector b/console/rgl/ps3/vector index d375ac48a2..ee56f4b5fd 100644 --- a/console/rgl/ps3/vector +++ b/console/rgl/ps3/vector @@ -1,10 +1,6 @@ -// vector standard header - #ifndef _VECTOR_ #define _VECTOR_ -#define RGL_STD_VECTOR - #include #include diff --git a/console/salamander/main.c b/console/salamander/main.c index 8502316d09..cfd179e603 100644 --- a/console/salamander/main.c +++ b/console/salamander/main.c @@ -171,7 +171,7 @@ static void init_settings(void) char core_executable[1024]; #if defined(_XBOX360) snprintf(core_executable, sizeof(core_executable), "game:\\CORE.xex"); -#if defined(_XBOX1) +#elif defined(_XBOX1) snprintf(core_executable, sizeof(core_executable), "D:\\CORE.xbe"); #elif defined(__CELLOS_LV2__) snprintf(core_executable, sizeof(core_executable), "%s/CORE.SELF", LIBRETRO_DIR_PATH); From 2b0bbb9fa1817ee1bf987f1c17c8ca5b3706c439 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Mon, 23 Jul 2012 12:27:43 +0200 Subject: [PATCH 10/51] (RGL) Make RGL more compatible with PSL1GHT --- console/rgl/ps3/device_ctx.cpp | 2 + console/rgl/ps3/rgl.h | 5 ++ ps3/sdk_defines.h | 116 ++++++++++++++++++++++++++++++++- 3 files changed, 120 insertions(+), 3 deletions(-) diff --git a/console/rgl/ps3/device_ctx.cpp b/console/rgl/ps3/device_ctx.cpp index 90aeeb3e5a..b64d6aec3f 100644 --- a/console/rgl/ps3/device_ctx.cpp +++ b/console/rgl/ps3/device_ctx.cpp @@ -20,7 +20,9 @@ #include "../../../general.h" +#ifndef __PSL1GHT__ using namespace cell::Gcm; +#endif #define _RGL_MAX_TILED_REGIONS 15 diff --git a/console/rgl/ps3/rgl.h b/console/rgl/ps3/rgl.h index db7d77489d..14da606342 100644 --- a/console/rgl/ps3/rgl.h +++ b/console/rgl/ps3/rgl.h @@ -7,6 +7,11 @@ #ifdef __PSL1GHT__ #include +#include +#include "../../../ps3/sdk_defines.h" +#define CGerror int +typedef void (* CGerrorCallbackFunc)(void); +typedef struct _CGcontext *CGcontext; #else #include #endif diff --git a/ps3/sdk_defines.h b/ps3/sdk_defines.h index 35c36c1988..389e79b46b 100644 --- a/ps3/sdk_defines.h +++ b/ps3/sdk_defines.h @@ -56,6 +56,7 @@ #define param_attrib attrib #define sys_lwmutex_attribute_t sys_lwmutex_attr_t #define sys_lwcond_attribute_t sys_lwcond_attr_t +#define sys_semaphore_t sys_sem_t #else #define numChannels nChannel @@ -318,17 +319,111 @@ #define CELL_GCM_FALSE GCM_FALSE #define CELL_GCM_TRUE GCM_TRUE -#define CELL_GCM_TEXTURE_NEAREST GCM_TEXTURE_NEAREST - #define CELL_GCM_ONE GCM_ONE #define CELL_GCM_ZERO GCM_ZERO +#define CELL_GCM_ALWAYS GCM_ALWAYS -#define CELL_GCM_SMOOTH GCM_SMOOTH +#define CELL_GCM_LOCATION_LOCAL GCM_LOCATION_RSX +#define CELL_GCM_LOCATION_MAIN GCM_LOCATION_CELL + +#define CELL_GCM_MAX_RT_DIMENSION (4096) + +#define CELL_GCM_TEXTURE_LINEAR_NEAREST GCM_TEXTURE_LINEAR_MIPMAP_NEAREST +#define CELL_GCM_TEXTURE_LINEAR_LINEAR GCM_TEXTURE_LINEAR_MIPMAP_LINEAR +#define CELL_GCM_TEXTURE_NEAREST_LINEAR GCM_TEXTURE_NEAREST_MIPMAP_LINEAR +#define CELL_GCM_TEXTURE_NEAREST_NEAREST GCM_TEXTURE_NEAREST_MIPMAP_NEAREST +#define CELL_GCM_TEXTURE_NEAREST GCM_TEXTURE_NEAREST +#define CELL_GCM_TEXTURE_LINEAR GCM_TEXTURE_LINEAR + +#define CELL_GCM_TEXTURE_A8R8G8B8 GCM_TEXTURE_FORMAT_A8R8G8B8 +#define CELL_GCM_TEXTURE_R5G6B5 GCM_TEXTURE_FORMAT_R5G6B5 +#define CELL_GCM_TEXTURE_A1R5G5B5 GCM_TEXTURE_FORMAT_A1R5G5B5 + +#define CELL_GCM_TEXTURE_CLAMP_TO_EDGE GCM_TEXTURE_CLAMP_TO_EDGE + +#define CELL_GCM_TEXTURE_MAX_ANISO_1 GCM_TEXTURE_MAX_ANISO_1 +#define CELL_GCM_TEXTURE_CONVOLUTION_QUINCUNX GCM_TEXTURE_CONVOLUTION_QUINCUNX +#define CELL_GCM_TEXTURE_ZFUNC_NEVER GCM_TEXTURE_ZFUNC_NEVER + +#define CELL_GCM_DISPLAY_HSYNC GCM_FLIP_HSYNC +#define CELL_GCM_DISPLAY_VSYNC GCM_FLIP_VSYNC + +#define CELL_GCM_CLEAR_R GCM_CLEAR_R +#define CELL_GCM_CLEAR_G GCM_CLEAR_G +#define CELL_GCM_CLEAR_B GCM_CLEAR_B +#define CELL_GCM_CLEAR_A GCM_CLEAR_A + +#define CELL_GCM_FUNC_ADD GCM_FUNC_ADD + +#define CELL_RESC_720x480 RESC_720x480 +#define CELL_RESC_720x576 RESC_720x576 +#define CELL_RESC_1280x720 RESC_1280x720 +#define CELL_RESC_1920x1080 RESC_1920x1080 + +#define CELL_RESC_FULLSCREEN RESC_FULLSCREEN +#define CELL_RESC_PANSCAN RESC_PANSCAN +#define CELL_RESC_LETTERBOX RESC_LETTERBOX +#define CELL_RESC_CONSTANT_VRAM RESC_CONSTANT_VRAM +#define CELL_RESC_MINIMUM_GPU_LOAD RESC_MINIMUM_GPU_LOAD + +#define CELL_RESC_PAL_50 RESC_PAL_50 +#define CELL_RESC_PAL_60_DROP RESC_PAL_60_DROP +#define CELL_RESC_PAL_60_INTERPOLATE RESC_PAL_60_INTERPOLATE +#define CELL_RESC_PAL_60_INTERPOLATE_30_DROP RESC_PAL_60_INTERPOLATE_30_DROP +#define CELL_RESC_PAL_60_INTERPOLATE_DROP_FLEXIBLE RESC_PAL_60_INTERPOLATE_DROP_FLEXIBLE + +#define CELL_RESC_INTERLACE_FILTER RESC_INTERLACE_FILTER +#define CELL_RESC_NORMAL_BILINEAR RESC_NORMAL_BILINEAR + +#define CELL_RESC_ELEMENT_HALF RESC_ELEMENT_HALF + +#define CELL_VIDEO_OUT_ASPECT_AUTO VIDEO_ASPECT_AUTO +#define CELL_VIDEO_OUT_ASPECT_4_3 VIDEO_ASPECT_4_3 +#define CELL_VIDEO_OUT_ASPECT_16_9 VIDEO_ASPECT_16_9 + +#define CELL_VIDEO_OUT_RESOLUTION_480 VIDEO_RESOLUTION_480 +#define CELL_VIDEO_OUT_RESOLUTION_576 VIDEO_RESOLUTION_576 +#define CELL_VIDEO_OUT_RESOLUTION_720 VIDEO_RESOLUTION_720 +#define CELL_VIDEO_OUT_RESOLUTION_1080 VIDEO_RESOLUTION_1080 +#define CELL_VIDEO_OUT_RESOLUTION_960x1080 VIDEO_RESOLUTION_960x1080 +#define CELL_VIDEO_OUT_RESOLUTION_1280x1080 VIDEO_RESOLUTION_1280x1080 +#define CELL_VIDEO_OUT_RESOLUTION_1440x1080 VIDEO_RESOLUTION_1440x1080 +#define CELL_VIDEO_OUT_RESOLUTION_1600x1080 VIDEO_RESOLUTION_1600x1080 + +#define CELL_VIDEO_OUT_SCAN_MODE_PROGRESSIVE VIDEO_SCANMODE_PROGRESSIVE + +#define CELL_VIDEO_OUT_PRIMARY VIDEO_PRIMARY + +#define CELL_VIDEO_OUT_BUFFER_COLOR_FORMAT_X8R8G8B8 VIDEO_BUFFER_FORMAT_XRGB +#define CELL_VIDEO_OUT_BUFFER_COLOR_FORMAT_R16G16B16X16_FLOAT VIDEO_BUFFER_FORMAT_FLOAT #define CellGcmSurface gcmSurface #define CellGcmTexture gcmTexture +#define CellGcmContextData _gcmCtxData +#define CellGcmConfig gcmConfiguration +#define CellVideoOutConfiguration videoConfiguration +#define CellVideoOutResolution videoResolution +#define CellVideoOutState videoState +#define CellRescPalTemporalMode rescPalTemporalMode +#define CellRescInitConfig rescInitConfig +#define CellRescSrc rescSrc +#define CellRescBufferMode rescBufferMode + +#define resolutionId resolution +#define memoryFrequency memoryFreq +#define coreFrequency coreFreq + +#define cellGcmGetFlipStatus gcmGetFlipStatus +#define cellGcmResetFlipStatus gcmResetFlipStatus #define cellGcmSetWaitFlip gcmSetWaitFlip +#define cellGcmSetDebugOutputLevel gcmSetDebugOutputLevel +#define cellGcmSetDisplayBuffer gcmSetDisplayBuffer +#define cellGcmSetGraphicsHandler gcmSetGraphicsHandler +#define cellGcmSetFlipHandler gcmSetFlipHandler +#define cellGcmSetVBlankHandler gcmSetVBlankHandler +#define cellGcmGetConfiguration gcmGetConfiguration +#define cellGcmSetJumpCommand gcmSetJumpCommand #define cellGcmFlush rsxFlushBuffer #define cellGcmSetFlipMode gcmSetFlipMode #define cellGcmSetFlip gcmSetFlip @@ -337,6 +432,21 @@ #define cellGcmBindTile gcmBindTile #define cellGcmSetTileInfo gcmSetTileInfo #define cellGcmAddressToOffset gcmAddressToOffset + +#define cellRescGetFlipStatus rescGetFlipStatus +#define cellRescResetFlipStatus rescResetFlipStatus +#define cellRescSetConvertAndFlip rescSetConvertAndFlip +#define cellRescSetVBlankHandler rescSetVBlankHandler +#define cellRescSetFlipHandler rescSetFlipHandler +#define cellRescAdjustAspectRatio rescAdjustAspectRatio +#define cellRescSetWaitFlip rescSetWaitFlip +#define cellRescSetSrc rescSetSrc +#define cellRescInit rescInit +#define cellRescExit rescExit + +#define cellVideoOutConfigure videoConfigure +#define cellVideoOutGetState videoGetState +#define cellVideoOutGetResolution videoGetResolution #endif #endif From ec827d862bf394bb7de374092b0d7973aeb581f6 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Mon, 23 Jul 2012 14:14:38 +0200 Subject: [PATCH 11/51] (RGL) Cleanups --- Makefile.psl1ght | 2 +- console/rgl/ps3/cgbio.hpp | 105 +-- console/rgl/ps3/cgnv2rt.h | 78 +- console/rgl/ps3/device_ctx.cpp | 3 +- console/rgl/ps3/gl.h | 90 +-- console/rgl/ps3/glext.h | 36 +- console/rgl/ps3/private.h | 339 ++++----- console/rgl/ps3/readelf.h | 68 +- console/rgl/ps3/rgl.cpp | 491 +++++------- console/rgl/ps3/rgl.h | 1295 ++++++++++++++++---------------- ps3/sdk_defines.h | 8 + 11 files changed, 1191 insertions(+), 1324 deletions(-) diff --git a/Makefile.psl1ght b/Makefile.psl1ght index 885b01a8f4..0d8c29b044 100644 --- a/Makefile.psl1ght +++ b/Makefile.psl1ght @@ -26,7 +26,7 @@ LIBS := -lretro_psl1ght -laudio -lEGL -lGL -lio -lm -ljpgdec -lpngdec -lsysutil OBJ = console/griffin/griffin.o console/rzlib/rzlib.o -#OBJ += console/rgl/ps3/device_ctx.o console/rgl/ps3/rgl.o console/rgl/ps3/cgbio.o console/rgl/ps3/cgnv2rt.o +OBJ += console/rgl/ps3/device_ctx.o console/rgl/ps3/rgl.o console/rgl/ps3/cgbio.o console/rgl/ps3/cgnv2rt.o ifeq ($(HAVE_LOGGER), 1) CFLAGS += -DHAVE_LOGGER diff --git a/console/rgl/ps3/cgbio.hpp b/console/rgl/ps3/cgbio.hpp index 69a8525710..53b3915841 100644 --- a/console/rgl/ps3/cgbio.hpp +++ b/console/rgl/ps3/cgbio.hpp @@ -14,16 +14,17 @@ typedef size_t ptrdiff_t; typedef size_t ptrdiff_t; -typedef struct _Elf32_cgParameter { - unsigned int cgp_name; - unsigned int cgp_semantic; - unsigned short cgp_default; - unsigned short cgp_reloc; - unsigned short cgp_resource; - unsigned short cgp_resource_index; - unsigned char cgp_type; - unsigned short cgp_info; - unsigned char unused; +typedef struct _Elf32_cgParameter +{ + unsigned int cgp_name; + unsigned int cgp_semantic; + unsigned short cgp_default; + unsigned short cgp_reloc; + unsigned short cgp_resource; + unsigned short cgp_resource_index; + unsigned char cgp_type; + unsigned short cgp_info; + unsigned char unused; } Elf32_cgParameter; #define ET_NONE 0 @@ -173,21 +174,22 @@ typedef struct _Elf32_cgParameter { #define R_RSX_NONE 0 #define R_RSX_FLOAT4 1 -struct Elf32_Ehdr { - unsigned char e_ident[EI_NIDENT]; - unsigned short e_type; - unsigned short e_machine; - unsigned int e_version; - unsigned int e_entry; - unsigned int e_phoff; - unsigned int e_shoff; - unsigned int e_flags; - unsigned short e_ehsize; - unsigned short e_phentsize; - unsigned short e_phnum; - unsigned short e_shentsize; - unsigned short e_shnum; - unsigned short e_shstrndx; +struct Elf32_Ehdr +{ + unsigned char e_ident[EI_NIDENT]; + unsigned short e_type; + unsigned short e_machine; + unsigned int e_version; + unsigned int e_entry; + unsigned int e_phoff; + unsigned int e_shoff; + unsigned int e_flags; + unsigned short e_ehsize; + unsigned short e_phentsize; + unsigned short e_phnum; + unsigned short e_shentsize; + unsigned short e_shnum; + unsigned short e_shstrndx; }; struct Elf32_Shdr { @@ -223,30 +225,31 @@ struct Elf32_Sym { unsigned short st_shndx; }; -struct Elf32_Note { - unsigned int n_namesz; /* Name size */ - unsigned int n_descsz; /* Content size */ - unsigned int n_type; /* Content type */ +struct Elf32_Note +{ + unsigned int n_namesz; /* Name size */ + unsigned int n_descsz; /* Content size */ + unsigned int n_type; /* Content type */ }; struct Elf32_Rel { - unsigned int r_offset; - unsigned int r_info; + unsigned int r_offset; + unsigned int r_info; }; struct Elf32_Rela { - unsigned int r_offset; - unsigned int r_info; - signed int r_addend; + unsigned int r_offset; + unsigned int r_info; + signed int r_addend; }; struct Elf32_Dyn { - signed int d_tag; - union { - unsigned int d_val; - unsigned int d_ptr; - } d_un; + signed int d_tag; + union { + unsigned int d_val; + unsigned int d_ptr; + } d_un; }; using std::istream; @@ -255,21 +258,21 @@ namespace cgc { namespace bio { enum CGBIO_ERROR { - CGBIO_ERROR_NO_ERROR, - CGBIO_ERROR_LOADED, - CGBIO_ERROR_FILEIO, - CGBIO_ERROR_FORMAT, - CGBIO_ERROR_INDEX, - CGBIO_ERROR_MEMORY, - CGBIO_ERROR_RELOC, - CGBIO_ERROR_SYMBOL, - CGBIO_ERROR_UNKNOWN_TYPE + CGBIO_ERROR_NO_ERROR, + CGBIO_ERROR_LOADED, + CGBIO_ERROR_FILEIO, + CGBIO_ERROR_FORMAT, + CGBIO_ERROR_INDEX, + CGBIO_ERROR_MEMORY, + CGBIO_ERROR_RELOC, + CGBIO_ERROR_SYMBOL, + CGBIO_ERROR_UNKNOWN_TYPE }; typedef enum { - CGBIODATANONE = ELFDATANONE, - CGBIODATALSB = ELFDATA2LSB, - CGBIODATAMSB = ELFDATA2MSB + CGBIODATANONE = ELFDATANONE, + CGBIODATALSB = ELFDATA2LSB, + CGBIODATAMSB = ELFDATA2MSB } HOST_ENDIANNESS; class elf_reader diff --git a/console/rgl/ps3/cgnv2rt.h b/console/rgl/ps3/cgnv2rt.h index 7f015cfae1..dae42e632f 100644 --- a/console/rgl/ps3/cgnv2rt.h +++ b/console/rgl/ps3/cgnv2rt.h @@ -20,59 +20,61 @@ static unsigned int stringTableAdd( STL_NAMESPACE vector &stringTable, const char* str ) { - unsigned int ret = (unsigned int)stringTable.size(); + unsigned int ret = (unsigned int)stringTable.size(); - if ( ret == 0 ) - { - stringTable.push_back('\0'); - ret = 1; - } + if ( ret == 0 ) + { + stringTable.push_back('\0'); + ret = 1; + } - size_t stringLength = strlen(str) + 1; - stringTable.resize(ret + stringLength); - memcpy(&stringTable[0] + ret,str,stringLength); + size_t stringLength = strlen(str) + 1; + stringTable.resize(ret + stringLength); + memcpy(&stringTable[0] + ret,str,stringLength); - return ret; + return ret; } static unsigned int stringTableFind( STL_NAMESPACE vector &stringTable, const char* str ) { - const char* data = &stringTable[0]; - size_t size = stringTable.size(); - const char *end = data + size; + const char* data = &stringTable[0]; + size_t size = stringTable.size(); + const char *end = data + size; - size_t length = strlen(str); - if (length+1 > size) - return 0; - data += length; + size_t length = strlen(str); - const char *p = (char*)memchr(data,'\0',end-data); - while (p && (end-data)>0) - { - if (!memcmp(p - length, str, length)) - { - return (unsigned int)(p - length - &stringTable[0]); - } - data = p+1; - p = (char*)memchr(data,'\0',end-data); - } - return 0; + if (length+1 > size) + return 0; + + data += length; + + const char *p = (char*)memchr(data,'\0',end-data); + while (p && (end-data)>0) + { + if (!memcmp(p - length, str, length)) + return (unsigned int)(p - length - &stringTable[0]); + + data = p+1; + p = (char*)memchr(data,'\0',end-data); + } + return 0; } static unsigned int stringTableAddUnique( STL_NAMESPACE vector &stringTable, const char* str ) { - if ( stringTable.size() == 0 ) - stringTable.push_back('\0'); - unsigned int ret = stringTableFind(stringTable, str); - if (ret == 0 && str[0] != '\0') - ret = stringTableAdd(stringTable, str); - return ret; + if ( stringTable.size() == 0 ) + stringTable.push_back('\0'); + + unsigned int ret = stringTableFind(stringTable, str); + + if (ret == 0 && str[0] != '\0') + ret = stringTableAdd(stringTable, str); + + return ret; } -int convertNvToElfFromFile(const char *sourceFile, int endianness, int constTableOffset, void **binaryShader, int *size, - STL_NAMESPACE vector &stringTable, STL_NAMESPACE vector &defaultValues); -int convertNvToElfFromMemory(const void *sourceData, size_t size, int endianness, int constTableOffset, void **binaryShader, int *binarySize, - STL_NAMESPACE vector &stringTable, STL_NAMESPACE vector &defaultValues); +int convertNvToElfFromFile(const char *sourceFile, int endianness, int constTableOffset, void **binaryShader, int *size, STL_NAMESPACE vector &stringTable, STL_NAMESPACE vector &defaultValues); +int convertNvToElfFromMemory(const void *sourceData, size_t size, int endianness, int constTableOffset, void **binaryShader, int *binarySize, STL_NAMESPACE vector &stringTable, STL_NAMESPACE vector &defaultValues); int convertNvToElfFreeBinaryShader(void *binaryShader); diff --git a/console/rgl/ps3/device_ctx.cpp b/console/rgl/ps3/device_ctx.cpp index b64d6aec3f..cbd08e8c44 100644 --- a/console/rgl/ps3/device_ctx.cpp +++ b/console/rgl/ps3/device_ctx.cpp @@ -477,9 +477,8 @@ static unsigned int findValidPitch( unsigned int pitch ) else { for ( GLuint i = 0;i < validPitchCount - 1;++i ) - { if (( pitch > validPitch[i] ) && ( pitch <= validPitch[i+1] ) ) return validPitch[i+1]; - } + return validPitch[validPitchCount-1]; } } diff --git a/console/rgl/ps3/gl.h b/console/rgl/ps3/gl.h index dea55764a1..bfba05e1ca 100644 --- a/console/rgl/ps3/gl.h +++ b/console/rgl/ps3/gl.h @@ -57,22 +57,22 @@ extern "C" #define GLAPI extern #endif - typedef unsigned int GLenum; - typedef unsigned char GLboolean; - typedef unsigned int GLbitfield; - typedef signed char GLbyte; - typedef short GLshort; - typedef int GLint; - typedef int GLsizei; - typedef unsigned char GLubyte; - typedef unsigned short GLushort; - typedef unsigned int GLuint; - typedef float GLfloat; - typedef float GLclampf; - typedef void GLvoid; - typedef int GLfixed; - typedef int GLclampx; - typedef void( *_GLfuncptr )(); +typedef unsigned int GLenum; +typedef unsigned char GLboolean; +typedef unsigned int GLbitfield; +typedef signed char GLbyte; +typedef short GLshort; +typedef int GLint; +typedef int GLsizei; +typedef unsigned char GLubyte; +typedef unsigned short GLushort; +typedef unsigned int GLuint; +typedef float GLfloat; +typedef float GLclampf; +typedef void GLvoid; +typedef int GLfixed; +typedef int GLclampx; +typedef void( *_GLfuncptr )(); #define GL_OES_VERSION_1_0 1 #define GL_OES_read_format 1 @@ -290,35 +290,35 @@ extern "C" #define GL_REPEAT 0x2901 #define GL_CLAMP_TO_EDGE 0x812F - GLAPI void APIENTRY glActiveTexture( GLenum texture ); - GLAPI void APIENTRY glBindTexture( GLenum target, GLuint texture ); - GLAPI void APIENTRY glBlendFunc( GLenum sfactor, GLenum dfactor ); - GLAPI void APIENTRY glClear( GLbitfield mask ); - GLAPI void APIENTRY glClearColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha ); - GLAPI void APIENTRY glClearColorx( GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha ); - GLAPI void APIENTRY glClientActiveTexture( GLenum texture ); - GLAPI void APIENTRY glColorPointer( GLint size, GLenum type, GLsizei stride, const GLvoid *pointer ); - GLAPI void APIENTRY glCopyTexSubImage2D( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height ); - GLAPI void APIENTRY glDeleteTextures( GLsizei n, const GLuint *textures ); - GLAPI void APIENTRY glDisable( GLenum cap ); - GLAPI void APIENTRY glDisableClientState( GLenum array ); - GLAPI void APIENTRY glDrawArrays( GLenum mode, GLint first, GLsizei count ); - GLAPI void APIENTRY glEnable( GLenum cap ); - GLAPI void APIENTRY glEnableClientState( GLenum array ); - GLAPI void APIENTRY glFinish( void ); - GLAPI void APIENTRY glFlush( void ); - GLAPI void APIENTRY glGenTextures( GLsizei n, GLuint *textures ); - GLAPI GLenum APIENTRY glGetError( void ); - GLAPI const GLubyte * APIENTRY glGetString( GLenum name ); - GLAPI void APIENTRY glLoadIdentity( void ); - GLAPI void APIENTRY glMatrixMode( GLenum mode ); - GLAPI void APIENTRY glOrthof( GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar ); - GLAPI void APIENTRY glRotatef( GLfloat angle, GLfloat x, GLfloat y, GLfloat z ); - GLAPI void APIENTRY glPixelStorei( GLenum pname, GLint param ); - GLAPI void APIENTRY glTexCoordPointer( GLint size, GLenum type, GLsizei stride, const GLvoid *pointer ); - GLAPI void APIENTRY glTexImage2D( GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels ); - GLAPI void APIENTRY glVertexPointer( GLint size, GLenum type, GLsizei stride, const GLvoid *pointer ); - GLAPI void APIENTRY glViewport( GLint x, GLint y, GLsizei width, GLsizei height ); +GLAPI void APIENTRY glActiveTexture( GLenum texture ); +GLAPI void APIENTRY glBindTexture( GLenum target, GLuint texture ); +GLAPI void APIENTRY glBlendFunc( GLenum sfactor, GLenum dfactor ); +GLAPI void APIENTRY glClear( GLbitfield mask ); +GLAPI void APIENTRY glClearColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha ); +GLAPI void APIENTRY glClearColorx( GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha ); +GLAPI void APIENTRY glClientActiveTexture( GLenum texture ); +GLAPI void APIENTRY glColorPointer( GLint size, GLenum type, GLsizei stride, const GLvoid *pointer ); +GLAPI void APIENTRY glCopyTexSubImage2D( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height ); +GLAPI void APIENTRY glDeleteTextures( GLsizei n, const GLuint *textures ); +GLAPI void APIENTRY glDisable( GLenum cap ); +GLAPI void APIENTRY glDisableClientState( GLenum array ); +GLAPI void APIENTRY glDrawArrays( GLenum mode, GLint first, GLsizei count ); +GLAPI void APIENTRY glEnable( GLenum cap ); +GLAPI void APIENTRY glEnableClientState( GLenum array ); +GLAPI void APIENTRY glFinish( void ); +GLAPI void APIENTRY glFlush( void ); +GLAPI void APIENTRY glGenTextures( GLsizei n, GLuint *textures ); +GLAPI GLenum APIENTRY glGetError( void ); +GLAPI const GLubyte * APIENTRY glGetString( GLenum name ); +GLAPI void APIENTRY glLoadIdentity( void ); +GLAPI void APIENTRY glMatrixMode( GLenum mode ); +GLAPI void APIENTRY glOrthof( GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar ); +GLAPI void APIENTRY glRotatef( GLfloat angle, GLfloat x, GLfloat y, GLfloat z ); +GLAPI void APIENTRY glPixelStorei( GLenum pname, GLint param ); +GLAPI void APIENTRY glTexCoordPointer( GLint size, GLenum type, GLsizei stride, const GLvoid *pointer ); +GLAPI void APIENTRY glTexImage2D( GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels ); +GLAPI void APIENTRY glVertexPointer( GLint size, GLenum type, GLsizei stride, const GLvoid *pointer ); +GLAPI void APIENTRY glViewport( GLint x, GLint y, GLsizei width, GLsizei height ); #ifdef __cplusplus } diff --git a/console/rgl/ps3/glext.h b/console/rgl/ps3/glext.h index e2d87c6418..5561075f09 100644 --- a/console/rgl/ps3/glext.h +++ b/console/rgl/ps3/glext.h @@ -12,9 +12,9 @@ extern "C" { #endif - typedef intptr_t GLintptr; - typedef intptr_t GLsizeiptr; - typedef unsigned short GLhalfARB; +typedef intptr_t GLintptr; +typedef intptr_t GLsizeiptr; +typedef unsigned short GLhalfARB; #define GL_QUADS 0x0007 #define GL_QUAD_STRIP 0x0008 @@ -248,24 +248,24 @@ extern "C" #define GL_BUFFER_SIZE 0x8764 #define GL_BUFFER_PITCH_SCE 0x6041 - GLAPI void APIENTRY glBlendEquation( GLenum mode ); - GLAPI void APIENTRY glBlendColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha ); - GLAPI void APIENTRY glGetFloatv( GLenum pname, GLfloat* params ); - GLAPI void APIENTRY glTexParameteri( GLenum target, GLenum pname, GLint param ); +GLAPI void APIENTRY glBlendEquation( GLenum mode ); +GLAPI void APIENTRY glBlendColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha ); +GLAPI void APIENTRY glGetFloatv( GLenum pname, GLfloat* params ); +GLAPI void APIENTRY glTexParameteri( GLenum target, GLenum pname, GLint param ); - GLAPI void APIENTRY glBindBuffer( GLenum target, GLuint name ); - GLAPI void APIENTRY glDeleteBuffers( GLsizei n, const GLuint *buffers ); - GLAPI void APIENTRY glGenBuffers( GLsizei n, GLuint *buffers ); - GLAPI void APIENTRY glBufferData( GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage ); - GLAPI void APIENTRY glBufferSubData( GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data ); +GLAPI void APIENTRY glBindBuffer( GLenum target, GLuint name ); +GLAPI void APIENTRY glDeleteBuffers( GLsizei n, const GLuint *buffers ); +GLAPI void APIENTRY glGenBuffers( GLsizei n, GLuint *buffers ); +GLAPI void APIENTRY glBufferData( GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage ); +GLAPI void APIENTRY glBufferSubData( GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data ); - GLAPI void APIENTRY glBindFramebufferOES( GLenum, GLuint ); - GLAPI void APIENTRY glDeleteFramebuffersOES( GLsizei, const GLuint * ); - GLAPI void APIENTRY glGenFramebuffersOES( GLsizei, GLuint * ); - GLAPI GLenum APIENTRY glCheckFramebufferStatusOES( GLenum ); - GLAPI void APIENTRY glFramebufferTexture2DOES( GLenum, GLenum, GLenum, GLuint, GLint ); +GLAPI void APIENTRY glBindFramebufferOES( GLenum, GLuint ); +GLAPI void APIENTRY glDeleteFramebuffersOES( GLsizei, const GLuint * ); +GLAPI void APIENTRY glGenFramebuffersOES( GLsizei, GLuint * ); +GLAPI GLenum APIENTRY glCheckFramebufferStatusOES( GLenum ); +GLAPI void APIENTRY glFramebufferTexture2DOES( GLenum, GLenum, GLenum, GLuint, GLint ); - GLAPI void APIENTRY glTextureReferenceSCE( GLenum target, GLuint levels, GLuint baseWidth, GLuint baseHeight, GLuint baseDepth, GLenum internalFormat, GLuint pitch, GLintptr offset ); +GLAPI void APIENTRY glTextureReferenceSCE( GLenum target, GLuint levels, GLuint baseWidth, GLuint baseHeight, GLuint baseDepth, GLenum internalFormat, GLuint pitch, GLintptr offset ); #ifdef __cplusplus } diff --git a/console/rgl/ps3/private.h b/console/rgl/ps3/private.h index 13886d0a8d..7faf1d6acf 100644 --- a/console/rgl/ps3/private.h +++ b/console/rgl/ps3/private.h @@ -12,7 +12,6 @@ extern "C" { #endif - #ifdef __cplusplus #define _RGL_EXTERN_C extern "C" #else @@ -52,8 +51,8 @@ extern PSGLdevice *_CurrentDevice; typedef union { - unsigned int i; - float f; + unsigned int i; + float f; } jsIntAndFloat; static const jsIntAndFloat _RGLNan = {i: 0x7fc00000U}; @@ -63,39 +62,36 @@ static const jsIntAndFloat _RGLInfinity = {i: 0x7f800000U}; typedef struct RGLRenderTargetEx RGLRenderTargetEx; struct RGLRenderTargetEx { - RGLEnum colorFormat; - GLuint colorBufferCount; - GLuint colorId[RGL_SETRENDERTARGET_MAXCOUNT]; - GLuint colorIdOffset[RGL_SETRENDERTARGET_MAXCOUNT]; - GLuint colorPitch[RGL_SETRENDERTARGET_MAXCOUNT]; - GLboolean yInverted; - GLuint xOffset; - GLuint yOffset; - GLuint width; - GLuint height; + RGLEnum colorFormat; + GLuint colorBufferCount; + GLuint colorId[RGL_SETRENDERTARGET_MAXCOUNT]; + GLuint colorIdOffset[RGL_SETRENDERTARGET_MAXCOUNT]; + GLuint colorPitch[RGL_SETRENDERTARGET_MAXCOUNT]; + GLboolean yInverted; + GLuint xOffset; + GLuint yOffset; + GLuint width; + GLuint height; }; struct jsPlatformFramebuffer: public jsFramebuffer { - RGLRenderTargetEx rt; - GLuint colorBufferMask; - GLboolean complete; - jsPlatformFramebuffer(): jsFramebuffer() - { - memset( &rt, 0, sizeof( rt ) ); - }; - virtual ~jsPlatformFramebuffer() {}; + RGLRenderTargetEx rt; + GLuint colorBufferMask; + GLboolean complete; + jsPlatformFramebuffer(): jsFramebuffer() { memset( &rt, 0, sizeof( rt ) ); }; + virtual ~jsPlatformFramebuffer() {}; }; typedef struct _RGLDriver_ { - RGLRenderTargetEx rt; - GLuint colorBufferMask; - GLboolean rtValid; - GLboolean invalidateVertexCache; - GLuint flushBufferCount; - GLuint fpLoadProgramId; - GLuint fpLoadProgramOffset; + RGLRenderTargetEx rt; + GLuint colorBufferMask; + GLboolean rtValid; + GLboolean invalidateVertexCache; + GLuint flushBufferCount; + GLuint fpLoadProgramId; + GLuint fpLoadProgramOffset; } RGLDriver; @@ -142,99 +138,99 @@ typedef struct typedef struct { - GLenum pool; - RGLTextureMethodParams gcmMethods; - CellGcmTexture gcmTexture; - GLuint gpuAddressId; - GLuint gpuAddressIdOffset; - GLuint gpuSize; - RGLTextureLayout gpuLayout; - jsBufferObject* pbo; + GLenum pool; + RGLTextureMethodParams gcmMethods; + CellGcmTexture gcmTexture; + GLuint gpuAddressId; + GLuint gpuAddressIdOffset; + GLuint gpuSize; + RGLTextureLayout gpuLayout; + jsBufferObject* pbo; } RGLTexture; typedef struct _tagMODESTRUC { - GLushort wHorizVisible; - GLushort wVertVisible; - GLushort wInterlacedMode; - GLushort wRefresh; - GLushort wHorizTotal; - GLushort wHorizBlankStart; - GLushort wHorizSyncStart; - GLushort wHorizSyncEnd; - GLushort wHorizBlankEnd; - GLushort wVertTotal; - GLushort wVertBlankStart; - GLushort wVertSyncStart; - GLushort wVertSyncEnd; - GLushort wVertBlankEnd; - GLuint dwDotClock; - GLushort wHSyncPolarity; - GLushort wVSyncPolarity; + GLushort wHorizVisible; + GLushort wVertVisible; + GLushort wInterlacedMode; + GLushort wRefresh; + GLushort wHorizTotal; + GLushort wHorizBlankStart; + GLushort wHorizSyncStart; + GLushort wHorizSyncEnd; + GLushort wHorizBlankEnd; + GLushort wVertTotal; + GLushort wVertBlankStart; + GLushort wVertSyncStart; + GLushort wVertSyncEnd; + GLushort wVertBlankEnd; + GLuint dwDotClock; + GLushort wHSyncPolarity; + GLushort wVSyncPolarity; } MODESTRUC; enum { - _RGL_SURFACE_SOURCE_TEMPORARY, - _RGL_SURFACE_SOURCE_DEVICE, - _RGL_SURFACE_SOURCE_TEXTURE, - _RGL_SURFACE_SOURCE_PBO, + _RGL_SURFACE_SOURCE_TEMPORARY, + _RGL_SURFACE_SOURCE_DEVICE, + _RGL_SURFACE_SOURCE_TEXTURE, + _RGL_SURFACE_SOURCE_PBO, }; enum { - _RGL_SURFACE_POOL_NONE, - _RGL_SURFACE_POOL_LINEAR, - _RGL_SURFACE_POOL_SYSTEM, + _RGL_SURFACE_POOL_NONE, + _RGL_SURFACE_POOL_LINEAR, + _RGL_SURFACE_POOL_SYSTEM, }; typedef struct { - GLenum source; - GLuint width, height; - GLuint bpp; - GLuint pitch; - RGLEnum format; - GLenum pool; - char* ppuData; - GLuint dataId; - GLuint dataIdOffset; + GLenum source; + GLuint width, height; + GLuint bpp; + GLuint pitch; + RGLEnum format; + GLenum pool; + char* ppuData; + GLuint dataId; + GLuint dataIdOffset; } RGLSurface; typedef struct { - RGLRenderTargetEx rt; - RGLSurface color[3]; - GLuint drawBuffer; - GLuint scanBuffer; - GLuint RescColorBuffersId; - GLuint RescVertexArrayId; - GLuint RescFragmentShaderId; + RGLRenderTargetEx rt; + RGLSurface color[3]; + GLuint drawBuffer; + GLuint scanBuffer; + GLuint RescColorBuffersId; + GLuint RescVertexArrayId; + GLuint RescFragmentShaderId; - const MODESTRUC *ms; - GLboolean vsync; - GLenum deviceType; - GLenum TVStandard; - GLenum TVFormat; - GLuint swapFifoRef; - GLuint swapFifoRef2; - GLboolean setOffset; - GLboolean signal; - GLuint semaValue; - unsigned int syncMethod; + const MODESTRUC *ms; + GLboolean vsync; + GLenum deviceType; + GLenum TVStandard; + GLenum TVFormat; + GLuint swapFifoRef; + GLuint swapFifoRef2; + GLboolean setOffset; + GLboolean signal; + GLuint semaValue; + unsigned int syncMethod; } RGLDevice; int32_t _RGLOutOfSpaceCallback( struct CellGcmContextData *con, uint32_t space ); typedef struct _RGLShader_ { - GLuint loadAddressId; - CgBinaryProgram __attribute__(( aligned( 16 ) ) ) program; + GLuint loadAddressId; + CgBinaryProgram __attribute__(( aligned( 16 ) ) ) program; } RGLShader; -void _RGLFifoFinish( RGLFifo *fifo ); +void _RGLFifoFinish( RGLFifo *fifo ); #define _RGLFifoFlush(fifo) \ { \ @@ -249,17 +245,16 @@ void _RGLFifoFinish( RGLFifo *fifo ); #define RGL_PAGE_SIZE 0x1000 #define RGL_LM_MAX_TOTAL_QUERIES 800 - - typedef struct RGLTextureState RGLTextureState; + struct RGLTextureState { - GLuint hwTexAddress; - GLuint hwTexFilter; - GLuint hwTexControl0; + GLuint hwTexAddress; + GLuint hwTexFilter; + GLuint hwTexControl0; }; -void _RGLDestroy( void ); +void _RGLDestroy( void ); typedef void( * RGLcontextHookFunction )( PSGLcontext *context ); extern RGLcontextHookFunction _RGLContextCreateHook; @@ -283,22 +278,23 @@ extern void _RGLDeviceExit (void); static inline GLuint RGL_QUICK_FLOAT2UINT( const GLfloat f ) { - union - { - GLfloat f; - GLuint ui; - } t; - t.f = f + RGL_F0_DOT_0; - return t.ui & 0xffff; + union + { + GLfloat f; + GLuint ui; + } t; + t.f = f + RGL_F0_DOT_0; + return t.ui & 0xffff; } -static inline void RGL_CALC_COLOR_LE_ARGB8( GLuint *color0, const GLfloat r, const GLfloat g, const GLfloat b, const GLfloat a ) +static inline void RGL_CALC_COLOR_LE_ARGB8( GLuint *color0, const GLfloat r, +const GLfloat g, const GLfloat b, const GLfloat a ) { - GLuint r2 = RGL_QUICK_FLOAT2UINT( r * 255.0f ); - GLuint g2 = RGL_QUICK_FLOAT2UINT( g * 255.0f ); - GLuint b2 = RGL_QUICK_FLOAT2UINT( b * 255.0f ); - GLuint a2 = RGL_QUICK_FLOAT2UINT( a * 255.0f ); - *color0 = ( a2 << 24 ) | ( r2 << 16 ) | ( g2 << 8 ) | ( b2 << 0 ); + GLuint r2 = RGL_QUICK_FLOAT2UINT( r * 255.0f ); + GLuint g2 = RGL_QUICK_FLOAT2UINT( g * 255.0f ); + GLuint b2 = RGL_QUICK_FLOAT2UINT( b * 255.0f ); + GLuint a2 = RGL_QUICK_FLOAT2UINT( a * 255.0f ); + *color0 = ( a2 << 24 ) | ( r2 << 16 ) | ( g2 << 8 ) | ( b2 << 0 ); } static inline GLuint _RGLMapMinTextureFilter( GLenum filter ) @@ -323,14 +319,14 @@ static inline GLuint _RGLMapMinTextureFilter( GLenum filter ) static inline GLuint _RGLMapMagTextureFilter( GLenum filter ) { - switch ( filter ) - { - case GL_NEAREST: - return CELL_GCM_TEXTURE_NEAREST; - case GL_LINEAR: - return CELL_GCM_TEXTURE_LINEAR; - } - return filter; + switch ( filter ) + { + case GL_NEAREST: + return CELL_GCM_TEXTURE_NEAREST; + case GL_LINEAR: + return CELL_GCM_TEXTURE_LINEAR; + } + return filter; } static inline void _RGLMapTextureFormat( GLuint internalFormat, uint8_t & gcmFormat, uint32_t & remap ) @@ -339,71 +335,58 @@ static inline void _RGLMapTextureFormat( GLuint internalFormat, uint8_t & gcmFor switch ( internalFormat ) { - case RGL_ALPHA8: // in_rgba = xxAx, out_rgba = 000A - { - gcmFormat = CELL_GCM_TEXTURE_B8; - remap = CELL_GCM_REMAP_MODE( - CELL_GCM_TEXTURE_REMAP_ORDER_XYXY, - CELL_GCM_TEXTURE_REMAP_FROM_B, - CELL_GCM_TEXTURE_REMAP_FROM_R, - CELL_GCM_TEXTURE_REMAP_FROM_B, - CELL_GCM_TEXTURE_REMAP_FROM_B, - CELL_GCM_TEXTURE_REMAP_REMAP, - CELL_GCM_TEXTURE_REMAP_ZERO, - CELL_GCM_TEXTURE_REMAP_ZERO, - CELL_GCM_TEXTURE_REMAP_ZERO ); + case RGL_ALPHA8: // in_rgba = xxAx, out_rgba = 000A + gcmFormat = CELL_GCM_TEXTURE_B8; + remap = CELL_GCM_REMAP_MODE( + CELL_GCM_TEXTURE_REMAP_ORDER_XYXY, + CELL_GCM_TEXTURE_REMAP_FROM_B, + CELL_GCM_TEXTURE_REMAP_FROM_R, + CELL_GCM_TEXTURE_REMAP_FROM_B, + CELL_GCM_TEXTURE_REMAP_FROM_B, + CELL_GCM_TEXTURE_REMAP_REMAP, + CELL_GCM_TEXTURE_REMAP_ZERO, + CELL_GCM_TEXTURE_REMAP_ZERO, + CELL_GCM_TEXTURE_REMAP_ZERO ); - } break; - case RGL_ARGB8: // in_rgba = RGBA, out_rgba = RGBA - { - gcmFormat = CELL_GCM_TEXTURE_A8R8G8B8; - remap = CELL_GCM_REMAP_MODE( - CELL_GCM_TEXTURE_REMAP_ORDER_XYXY, - CELL_GCM_TEXTURE_REMAP_FROM_A, - CELL_GCM_TEXTURE_REMAP_FROM_R, - CELL_GCM_TEXTURE_REMAP_FROM_G, - CELL_GCM_TEXTURE_REMAP_FROM_B, - CELL_GCM_TEXTURE_REMAP_REMAP, - CELL_GCM_TEXTURE_REMAP_REMAP, - CELL_GCM_TEXTURE_REMAP_REMAP, - CELL_GCM_TEXTURE_REMAP_REMAP ); - - } + case RGL_ARGB8: // in_rgba = RGBA, out_rgba = RGBA + gcmFormat = CELL_GCM_TEXTURE_A8R8G8B8; + remap = CELL_GCM_REMAP_MODE( + CELL_GCM_TEXTURE_REMAP_ORDER_XYXY, + CELL_GCM_TEXTURE_REMAP_FROM_A, + CELL_GCM_TEXTURE_REMAP_FROM_R, + CELL_GCM_TEXTURE_REMAP_FROM_G, + CELL_GCM_TEXTURE_REMAP_FROM_B, + CELL_GCM_TEXTURE_REMAP_REMAP, + CELL_GCM_TEXTURE_REMAP_REMAP, + CELL_GCM_TEXTURE_REMAP_REMAP, + CELL_GCM_TEXTURE_REMAP_REMAP ); break; - case RGL_RGB5_A1_SCE: // in_rgba = RGBA, out_rgba = RGBA - { - gcmFormat = CELL_GCM_TEXTURE_A1R5G5B5; - remap = CELL_GCM_REMAP_MODE( - CELL_GCM_TEXTURE_REMAP_ORDER_XXXY, - CELL_GCM_TEXTURE_REMAP_FROM_A, - CELL_GCM_TEXTURE_REMAP_FROM_R, - CELL_GCM_TEXTURE_REMAP_FROM_G, - CELL_GCM_TEXTURE_REMAP_FROM_B, - CELL_GCM_TEXTURE_REMAP_REMAP, - CELL_GCM_TEXTURE_REMAP_REMAP, - CELL_GCM_TEXTURE_REMAP_REMAP, - CELL_GCM_TEXTURE_REMAP_REMAP ); - - } + case RGL_RGB5_A1_SCE: // in_rgba = RGBA, out_rgba = RGBA + gcmFormat = CELL_GCM_TEXTURE_A1R5G5B5; + remap = CELL_GCM_REMAP_MODE( + CELL_GCM_TEXTURE_REMAP_ORDER_XXXY, + CELL_GCM_TEXTURE_REMAP_FROM_A, + CELL_GCM_TEXTURE_REMAP_FROM_R, + CELL_GCM_TEXTURE_REMAP_FROM_G, + CELL_GCM_TEXTURE_REMAP_FROM_B, + CELL_GCM_TEXTURE_REMAP_REMAP, + CELL_GCM_TEXTURE_REMAP_REMAP, + CELL_GCM_TEXTURE_REMAP_REMAP, + CELL_GCM_TEXTURE_REMAP_REMAP ); break; - case RGL_RGB565_SCE: // in_rgba = RGBA, out_rgba = RGBA - { - gcmFormat = CELL_GCM_TEXTURE_R5G6B5; - remap = CELL_GCM_REMAP_MODE( - CELL_GCM_TEXTURE_REMAP_ORDER_XXXY, - CELL_GCM_TEXTURE_REMAP_FROM_A, - CELL_GCM_TEXTURE_REMAP_FROM_R, - CELL_GCM_TEXTURE_REMAP_FROM_G, - CELL_GCM_TEXTURE_REMAP_FROM_B, - CELL_GCM_TEXTURE_REMAP_ONE, - CELL_GCM_TEXTURE_REMAP_REMAP, - CELL_GCM_TEXTURE_REMAP_REMAP, - CELL_GCM_TEXTURE_REMAP_REMAP ); - - } - break; - default: + case RGL_RGB565_SCE: // in_rgba = RGBA, out_rgba = RGBA + gcmFormat = CELL_GCM_TEXTURE_R5G6B5; + remap = CELL_GCM_REMAP_MODE( + CELL_GCM_TEXTURE_REMAP_ORDER_XXXY, + CELL_GCM_TEXTURE_REMAP_FROM_A, + CELL_GCM_TEXTURE_REMAP_FROM_R, + CELL_GCM_TEXTURE_REMAP_FROM_G, + CELL_GCM_TEXTURE_REMAP_FROM_B, + CELL_GCM_TEXTURE_REMAP_ONE, + CELL_GCM_TEXTURE_REMAP_REMAP, + CELL_GCM_TEXTURE_REMAP_REMAP, + CELL_GCM_TEXTURE_REMAP_REMAP ); break; }; diff --git a/console/rgl/ps3/readelf.h b/console/rgl/ps3/readelf.h index c33dd3373b..21c65c72d8 100644 --- a/console/rgl/ps3/readelf.h +++ b/console/rgl/ps3/readelf.h @@ -9,61 +9,61 @@ extern "C" { typedef struct _ELF_section_t { - Elf32_Shdr header; - const char* name; - char* data; + Elf32_Shdr header; + const char *name; + char *data; } ELF_section_t; typedef struct _ELF_segment_t { - Elf32_Phdr header; - unsigned char* pointer; - unsigned char* data; + Elf32_Phdr header; + unsigned char *pointer; + unsigned char *data; } ELF_segment_t; typedef struct { - const char* name; - unsigned int vma; - unsigned int size; - int section; - unsigned char resolved; - unsigned char foreign; + const char *name; + unsigned int vma; + unsigned int size; + int section; + unsigned char resolved; + unsigned char foreign; } ELF_symbol_t; typedef struct _ELF_t { - unsigned int endian; - unsigned int relocatable; - unsigned int sectionCount; - unsigned int segmentCount; - unsigned int symbolCount; - unsigned int entrypoint; - ELF_section_t* sections; - ELF_segment_t* segments; - ELF_symbol_t* symbols; - unsigned int symbolsSection; - unsigned int symbolNamesSection; - unsigned int paramSection; + unsigned int endian; + unsigned int relocatable; + unsigned int sectionCount; + unsigned int segmentCount; + unsigned int symbolCount; + unsigned int entrypoint; + ELF_section_t *sections; + ELF_segment_t *segments; + ELF_symbol_t *symbols; + unsigned int symbolsSection; + unsigned int symbolNamesSection; + unsigned int paramSection; } ELF_t; typedef struct { - unsigned int relative; - unsigned int shift; - unsigned int size; - unsigned int position; - unsigned int mask; + unsigned int relative; + unsigned int shift; + unsigned int size; + unsigned int position; + unsigned int mask; } ELF_rel_type_t; -ELF_section_t* findSection(const ELF_t* elf,const char* name); -int lookupSymbol(const ELF_t* elf,const char* name); -const Elf32_Sym* getSymbolByIndex(const ELF_t* elf,int idx); +ELF_section_t *findSection(const ELF_t *elf, const char *name); +int lookupSymbol(const ELF_t *elf, const char *name); +const Elf32_Sym *getSymbolByIndex(const ELF_t *elf, int idx); const char *findSectionInPlace(const char* memory,unsigned int size,const char *name,size_t *sectionSize); const char *findSymbolSectionInPlace(const char *memory, unsigned int size, size_t *symbolSize, size_t *symbolCount, const char **symbolstrtab); -int lookupSymbolValueInPlace(const char* symbolSection, size_t symbolSize, size_t symbolCount, const char *symbolstrtab, const char *name); -const char *getSymbolByIndexInPlace(const char* symbolSection, size_t symbolSize, size_t symbolCount, const char *symbolstrtab, int index); +int lookupSymbolValueInPlace(const char *symbolSection, size_t symbolSize, size_t symbolCount, const char *symbolstrtab, const char *name); +const char *getSymbolByIndexInPlace(const char *symbolSection, size_t symbolSize, size_t symbolCount, const char *symbolstrtab, int index); #ifdef __cplusplus } diff --git a/console/rgl/ps3/rgl.cpp b/console/rgl/ps3/rgl.cpp index 807a260f60..a27fedf933 100644 --- a/console/rgl/ps3/rgl.cpp +++ b/console/rgl/ps3/rgl.cpp @@ -133,9 +133,9 @@ typedef GLhalfARB type_GL_HALF_FLOAT_ARB; static const char *_getStringTable(const Elf32_Ehdr *ehdr) { - const char *sectionHeaderStart = (const char*)ehdr + ehdr->e_shoff; - const Elf32_Shdr *shstrtabHeader = (const Elf32_Shdr*)sectionHeaderStart + ehdr->e_shstrndx; - return (const char*)ehdr + shstrtabHeader->sh_offset; + const char *sectionHeaderStart = (const char*)ehdr + ehdr->e_shoff; + const Elf32_Shdr *shstrtabHeader = (const Elf32_Shdr*)sectionHeaderStart + ehdr->e_shstrndx; + return (const char*)ehdr + shstrtabHeader->sh_offset; } const char *findSectionInPlace(const char* memory,unsigned int /*size*/,const char *name, size_t *sectionSize) @@ -205,14 +205,14 @@ const char *getSymbolByIndexInPlace(const char* symbolSection, size_t symbolSize static inline type_GL_HALF_FLOAT_ARB _RGLFloatTo_GL_HALF_FLOAT_ARB( float x ) { - jsIntAndFloat V = {f: x}; - unsigned int S = ( V.i >> 31 ) & 1; - int E = (( V.i >> 23 ) & 0xff ) - 0x7f; - unsigned int M = V.i & 0x007fffff; - if (( E == 0x80 ) && ( M ) ) return 0x7fff; - else if ( E >= 15 ) return( S << 15 ) | 0x7c00; - else if ( E <= -14 ) return( S << 15 ) | (( 0x800000 + M ) >> ( -14 - E ) ); - else return( S << 15 ) | ((( E + 15 )&0x1f ) << 10 ) | ( M >> 13 ); + jsIntAndFloat V = {f: x}; + unsigned int S = ( V.i >> 31 ) & 1; + int E = (( V.i >> 23 ) & 0xff ) - 0x7f; + unsigned int M = V.i & 0x007fffff; + if (( E == 0x80 ) && ( M ) ) return 0x7fff; + else if ( E >= 15 ) return( S << 15 ) | 0x7c00; + else if ( E <= -14 ) return( S << 15 ) | (( 0x800000 + M ) >> ( -14 - E ) ); + else return( S << 15 ) | ((( E + 15 )&0x1f ) << 10 ) | ( M >> 13 ); } static inline float _RGLFloatFrom_GL_HALF_FLOAT_ARB( type_GL_HALF_FLOAT_ARB x ) @@ -1912,7 +1912,7 @@ void _RGLFreeNameSpace( jsNameSpace * ns ) jsName _RGLCreateName( jsNameSpace * ns, void* object ) { - if ( NULL == ns->firstFree ) + if ( ns->firstFree == NULL ) { int newCapacity = ns->capacity + NAME_INCREMENT; @@ -1946,7 +1946,7 @@ jsName _RGLCreateName( jsNameSpace * ns, void* object ) unsigned int _RGLIsName( jsNameSpace* ns, jsName name ) { - if ( RGL_UNLIKELY( 0 == name ) ) + if ( RGL_UNLIKELY( name == 0 ) ) return 0; --name; @@ -1956,7 +1956,7 @@ unsigned int _RGLIsName( jsNameSpace* ns, jsName name ) void** value = ( void** )ns->data[name]; - if ( RGL_UNLIKELY( NULL == value || + if ( RGL_UNLIKELY( value == NULL || ( value >= ns->data && value < ns->data + ns->capacity ) ) ) return 0; @@ -2060,7 +2060,7 @@ void _RGLTexNameSpaceDeleteNames( jsTexNameSpace *ns, GLsizei n, const GLuint *n static inline unsigned int endianSwapWordByHalf( unsigned int v ) { - return ( v&0xffff ) << 16 | v >> 16; + return ( v&0xffff ) << 16 | v >> 16; } static uint32_t gmmInitFixedAllocator (void) @@ -2132,97 +2132,52 @@ static uint8_t gmmSizeToFreeIndex( ) { if (size >= GMM_FREE_BIN_0 && size < GMM_FREE_BIN_1) - { return 0; - } else if (size >= GMM_FREE_BIN_1 && size < GMM_FREE_BIN_2) - { return 1; - } else if (size >= GMM_FREE_BIN_2 && size < GMM_FREE_BIN_3) - { return 2; - } else if (size >= GMM_FREE_BIN_3 && size < GMM_FREE_BIN_4) - { return 3; - } else if (size >= GMM_FREE_BIN_4 && size < GMM_FREE_BIN_5) - { return 4; - } else if (size >= GMM_FREE_BIN_5 && size < GMM_FREE_BIN_6) - { return 5; - } else if (size >= GMM_FREE_BIN_6 && size < GMM_FREE_BIN_7) - { return 6; - } else if (size >= GMM_FREE_BIN_7 && size < GMM_FREE_BIN_8) - { return 7; - } else if (size >= GMM_FREE_BIN_8 && size < GMM_FREE_BIN_9) - { return 8; - } else if (size >= GMM_FREE_BIN_9 && size < GMM_FREE_BIN_10) - { return 9; - } else if (size >= GMM_FREE_BIN_10 && size < GMM_FREE_BIN_11) - { return 10; - } else if (size >= GMM_FREE_BIN_11 && size < GMM_FREE_BIN_12) - { return 11; - } else if (size >= GMM_FREE_BIN_12 && size < GMM_FREE_BIN_13) - { return 12; - } else if (size >= GMM_FREE_BIN_13 && size < GMM_FREE_BIN_14) - { return 13; - } else if (size >= GMM_FREE_BIN_14 && size < GMM_FREE_BIN_15) - { return 14; - } else if (size >= GMM_FREE_BIN_15 && size < GMM_FREE_BIN_16) - { return 15; - } else if (size >= GMM_FREE_BIN_16 && size < GMM_FREE_BIN_17) - { return 16; - } else if (size >= GMM_FREE_BIN_17 && size < GMM_FREE_BIN_18) - { return 17; - } else if (size >= GMM_FREE_BIN_18 && size < GMM_FREE_BIN_19) - { return 18; - } else if (size >= GMM_FREE_BIN_19 && size < GMM_FREE_BIN_20) - { return 19; - } else if (size >= GMM_FREE_BIN_20 && size < GMM_FREE_BIN_21) - { return 20; - } else return 21; } -static void gmmAddFree( - GmmAllocator *pAllocator, - GmmBlock *pBlock -) +static void gmmAddFree(GmmAllocator *pAllocator, GmmBlock *pBlock) { uint8_t freeIndex = gmmSizeToFreeIndex(pBlock->base.size); @@ -2432,22 +2387,18 @@ uint32_t gmmInit( return gmmInitFixedAllocator(); } -void gmmSetTileAttrib( - const uint32_t id, - const uint32_t tag, - void *pData -) +void gmmSetTileAttrib(const uint32_t id, const uint32_t tag, void *pData) { - GmmTileBlock *pTileBlock = (GmmTileBlock *)id; + GmmTileBlock *pTileBlock = (GmmTileBlock *)id; - pTileBlock->tileTag = tag; - pTileBlock->pData = pData; + pTileBlock->tileTag = tag; + pTileBlock->pData = pData; } uint32_t gmmIdToOffset(const uint32_t id) { - GmmBaseBlock *pBaseBlock = (GmmBaseBlock *)id; - return gmmAddressToOffset(pBaseBlock->address, pBaseBlock->isMain); + GmmBaseBlock *pBaseBlock = (GmmBaseBlock *)id; + return gmmAddressToOffset(pBaseBlock->address, pBaseBlock->isMain); } char *gmmIdToAddress(const uint32_t id) @@ -2577,9 +2528,7 @@ static GmmTileBlock *gmmCreateTileBlock( if (pAllocator->pTail && pAllocator->pTail->base.address + pAllocator->pTail->base.size > address) - { return NULL; - } pAllocator->size = address - pAllocator->startAddress; pAllocator->tileSize = pAllocator->tileStartAddress + pAllocator->tileSize - address; @@ -2587,9 +2536,7 @@ static GmmTileBlock *gmmCreateTileBlock( pNewBlock = (GmmTileBlock *)gmmAllocFixed(1); if (pNewBlock == NULL) - { return NULL; - } memset(pNewBlock, 0, sizeof(GmmTileBlock)); @@ -2600,15 +2547,11 @@ static GmmTileBlock *gmmCreateTileBlock( pNewBlock->pNext = pAllocator->pTileHead; if (pAllocator->pTileHead) - { pAllocator->pTileHead->pPrev = pNewBlock; - pAllocator->pTileHead = pNewBlock; - } else - { - pAllocator->pTileHead = pNewBlock; pAllocator->pTileTail = pNewBlock; - } + + pAllocator->pTileHead = pNewBlock; return pNewBlock; } @@ -2764,9 +2707,7 @@ static GmmTileBlock *gmmAllocTileBlock( return pBlock; } -static void gmmFreeBlock( - GmmBlock *pBlock -) +static void gmmFreeBlock (GmmBlock *pBlock) { GmmAllocator *pAllocator; @@ -2852,7 +2793,6 @@ uint32_t gmmFree(const uint32_t freeId) { GmmBaseBlock *pBaseBlock = (GmmBaseBlock *)freeId; - if (pBaseBlock->isTile) { GmmTileBlock *pTileBlock = (GmmTileBlock *)pBaseBlock; @@ -2966,18 +2906,16 @@ static inline void gmmLocalMemcpy( static inline void gmmMemcpy(const uint32_t dstOffset, const uint32_t srcOffset, const uint32_t moveSize) { - if (dstOffset + moveSize <= srcOffset) - { - gmmLocalMemcpy(dstOffset, srcOffset, moveSize); - } - else - { - uint32_t moveBlockSize = srcOffset-dstOffset; - uint32_t iterations = (moveSize+moveBlockSize-1)/moveBlockSize; + if (dstOffset + moveSize <= srcOffset) + gmmLocalMemcpy(dstOffset, srcOffset, moveSize); + else + { + uint32_t moveBlockSize = srcOffset-dstOffset; + uint32_t iterations = (moveSize+moveBlockSize-1)/moveBlockSize; - for (uint32_t i=0; ipNextFree; } else if (++freeIndex < GMM_NUM_FREE_BINS) - { pBlock = pAllocator->pFreeHead[freeIndex]; - } } if (found) @@ -3248,10 +3184,10 @@ static uint32_t gmmFindFreeBlock( pNewBlock->base.size = pBlock->base.size - size; pNewBlock->pNext = pBlock->pNext; pNewBlock->pPrev = pBlock; + if (pBlock->pNext) - { pBlock->pNext->pPrev = pNewBlock; - } + pBlock->pNext = pNewBlock; if (pBlock == pAllocator->pTail) @@ -3376,22 +3312,10 @@ RGLparamUID getParamUIDByIndex( const RGLparamUIDTable* st, int index ) return st->uids[index]; } -void _RGLPlatformSetVertexRegister4fv( unsigned int reg, const float * __restrict v ) -{ -} - -void _RGLPlatformSetVertexRegisterBlock( unsigned int reg, unsigned int count, const float * __restrict v ) -{ -} - - -void _RGLPlatformSetFragmentRegister4fv( unsigned int reg, const float * __restrict v ) -{ -} - -void _RGLPlatformSetFragmentRegisterBlock( unsigned int reg, unsigned int count, const float * __restrict v ) -{ -} +void _RGLPlatformSetVertexRegister4fv( unsigned int reg, const float * __restrict v ) {} +void _RGLPlatformSetVertexRegisterBlock( unsigned int reg, unsigned int count, const float * __restrict v ) {} +void _RGLPlatformSetFragmentRegister4fv( unsigned int reg, const float * __restrict v ) {} +void _RGLPlatformSetFragmentRegisterBlock( unsigned int reg, unsigned int count, const float * __restrict v ) {} template inline static void swapandsetfp( int ucodeSize, unsigned int loadProgramId, unsigned int loadProgramOffset, unsigned short *ec, const unsigned int * __restrict v ) { @@ -3431,13 +3355,10 @@ template static void setVectorTypefp( CgRuntimeParameter* __restrict p } } -template static void setVectorTypeSharedfpIndex( CgRuntimeParameter* __restrict ptr, const void* __restrict v, const int ) -{ -} +template static void setVectorTypeSharedfpIndex( CgRuntimeParameter* __restrict ptr, const void* __restrict v, const int ) {} + +template static void setVectorTypeSharedfpIndexArray( CgRuntimeParameter* __restrict ptr, const void* __restrict v, const int index ) {} -template static void setVectorTypeSharedfpIndexArray( CgRuntimeParameter* __restrict ptr, const void* __restrict v, const int index ) -{ -} template static void setVectorTypeSharedvpIndex( CgRuntimeParameter* __restrict ptr, const void* __restrict v, const int ) { const float * __restrict f = ( const float * __restrict )v; @@ -4479,11 +4400,6 @@ int _RGLPlatformCopyProgram( _CGprogram* source, _CGprogram* destination ) return _RGLGenerateProgram( destination, profileIndex, &source->header, source->ucode, ¶meterHeader, source->parametersEntries, source->stringTable, source->defaultValues ); } - - - - - static char *_RGLPlatformBufferObjectMap( jsBufferObject* bufferObject, GLenum access ) { RGLBufferObject *jsBuffer = ( RGLBufferObject * )bufferObject->platformBufferObject; @@ -4712,21 +4628,21 @@ static void _RGLPlatformExpandInternalFormat( GLenum internalFormat, GLenum *for static GLenum _RGLPlatformChooseInternalStorage( jsImage* image, GLenum internalFormat ) { - image->storageSize = 0; + image->storageSize = 0; - GLenum platformInternalFormat = _RGLPlatformChooseInternalFormat( internalFormat ); + GLenum platformInternalFormat = _RGLPlatformChooseInternalFormat( internalFormat ); - if ( platformInternalFormat == GL_INVALID_ENUM ) - return GL_INVALID_ENUM; + if ( platformInternalFormat == GL_INVALID_ENUM ) + return GL_INVALID_ENUM; - image->internalFormat = platformInternalFormat; - _RGLPlatformExpandInternalFormat( platformInternalFormat, &image->format, &image->type ); + image->internalFormat = platformInternalFormat; + _RGLPlatformExpandInternalFormat( platformInternalFormat, &image->format, &image->type ); - image->storageSize = _RGLGetStorageSize( - image->format, image->type, - image->width, image->height, 1 ); + image->storageSize = _RGLGetStorageSize( + image->format, image->type, + image->width, image->height, 1 ); - return GL_NO_ERROR; + return GL_NO_ERROR; } static inline GLuint _RGLGetBufferObjectOrigin( GLuint buffer ) @@ -4884,7 +4800,7 @@ static GLboolean _RGLPlatformTexturePBOImage( const GLuint bytesPerPixel = newLayout.pixelBits / 8; RGLSurface src = { -source: _RGL_SURFACE_SOURCE_PBO, + source: _RGL_SURFACE_SOURCE_PBO, width: image->width, height: image->height, bpp: bytesPerPixel, @@ -4901,7 +4817,7 @@ source: _RGL_SURFACE_SOURCE_PBO, RGLSurface dst = { -source: _RGL_SURFACE_SOURCE_TEXTURE, + source: _RGL_SURFACE_SOURCE_TEXTURE, width: image->width, height: image->height, bpp: bytesPerPixel, @@ -5064,9 +4980,7 @@ void _RGLFifoGlSetRenderTarget( RGLRenderTargetEx const * const args ) cellGcmSetDepthTestEnableInline( &_RGLState.fifo, CELL_GCM_FALSE); } -void _RGLSetError( GLenum error ) -{ -} +void _RGLSetError( GLenum error ) {} GLAPI GLenum APIENTRY glGetError() { @@ -5367,17 +5281,17 @@ PSGLcontext *psglGetCurrentContext() const GLfloat _RGLIdentityMatrixf[ELEMENTS_IN_MATRIX] = { - 1.f, 0.f, 0.f, 0.f, - 0.f, 1.f, 0.f, 0.f, - 0.f, 0.f, 1.f, 0.f, - 0.f, 0.f, 0.f, 1.f + 1.f, 0.f, 0.f, 0.f, + 0.f, 1.f, 0.f, 0.f, + 0.f, 0.f, 1.f, 0.f, + 0.f, 0.f, 0.f, 1.f }; static void _RGLMatrixStackReset( jsMatrixStack* LMatrixStack ) { - LMatrixStack->MatrixStackPtr = 0; - memcpy( LMatrixStack->MatrixStackf, _RGLIdentityMatrixf, jsMATRIX_SIZEf ); - LMatrixStack->dirty = GL_TRUE; + LMatrixStack->MatrixStackPtr = 0; + memcpy( LMatrixStack->MatrixStackf, _RGLIdentityMatrixf, jsMATRIX_SIZEf ); + LMatrixStack->dirty = GL_TRUE; } static void _RGLResetContext( PSGLcontext *LContext ) @@ -5601,7 +5515,8 @@ PSGLcontext* psglCreateContext (void) _RGLResetContext( LContext ); - if ( _RGLContextCreateHook ) _RGLContextCreateHook( LContext ); + if ( _RGLContextCreateHook ) + _RGLContextCreateHook( LContext ); return( LContext ); } @@ -5960,19 +5875,19 @@ void psglExit (void) GLAPI void APIENTRY glLoadIdentity() { - PSGLcontext* LContext = _CurrentContext; - jsMatrixStack* LMatrixStack = NULL; + PSGLcontext* LContext = _CurrentContext; + jsMatrixStack* LMatrixStack = NULL; - jsContextGetMatrixStack(LContext, LContext->MatrixMode, LMatrixStack); - memcpy( LMatrixStack->MatrixStackf + LMatrixStack->MatrixStackPtr*ELEMENTS_IN_MATRIX, _RGLIdentityMatrixf, jsMATRIX_SIZEf ); + jsContextGetMatrixStack(LContext, LContext->MatrixMode, LMatrixStack); + memcpy( LMatrixStack->MatrixStackf + LMatrixStack->MatrixStackPtr*ELEMENTS_IN_MATRIX, _RGLIdentityMatrixf, jsMATRIX_SIZEf ); - LMatrixStack->dirty = GL_TRUE; + LMatrixStack->dirty = GL_TRUE; } GLAPI void APIENTRY glMatrixMode( GLenum mode ) { - PSGLcontext* LContext = _CurrentContext; - LContext->MatrixMode = mode; + PSGLcontext* LContext = _CurrentContext; + LContext->MatrixMode = mode; } GLAPI void APIENTRY glOrthof( GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar ) @@ -6289,11 +6204,13 @@ GLAPI void APIENTRY glDrawArrays( GLenum mode, GLint first, GLsizei count ) if ( RGL_UNLIKELY( ! RGLBIT_GET( LContext->attribs->EnabledMask, _RGL_ATTRIB_POSITION_INDEX ) ) ) return; - uint32_t _tmp_clear_loop = c_rounded_size_of_RGLDrawParams>>7; + uint32_t _tmp_clear_loop = c_rounded_size_of_RGLDrawParams >> 7; + do{ - --_tmp_clear_loop; - __dcbz(s_dparams_buff+(_tmp_clear_loop<<7)); + --_tmp_clear_loop; + __dcbz(s_dparams_buff+(_tmp_clear_loop << 7)); }while(_tmp_clear_loop); + jsDrawParams *dparams = (jsDrawParams *)s_dparams_buff; dparams->mode = mode; dparams->firstVertex = first; @@ -6307,6 +6224,9 @@ GLAPI void APIENTRY glDrawArrays( GLenum mode, GLint first, GLsizei count ) { for ( int i = 0; i < _RGL_MAX_VERTEX_ATTRIBS; ++i ) { + dparams->attribXferOffset[i] = 0; + dparams->attribXferSize[i] = 0; + if ( clientSideMask & ( 1 << i ) ) { jsAttribute* attrib = as->attrib + i; @@ -6324,11 +6244,6 @@ GLAPI void APIENTRY glDrawArrays( GLenum mode, GLint first, GLsizei count ) dparams->xferTotalSize += numBytesPadded; dparams->attribXferTotalSize += numBytesPadded; } - else - { - dparams->attribXferOffset[i] = 0; - dparams->attribXferSize[i] = 0; - } } } @@ -6338,12 +6253,11 @@ GLAPI void APIENTRY glDrawArrays( GLenum mode, GLint first, GLsizei count ) GLboolean isMain = 0; if ( LContext->attribSetDirty && LContext->attribSetName ) - { - jsAttribSet* attribSet = _RGLGetAttribSet( LContext->attribSetName ); - } + jsAttribSet* attribSet = _RGLGetAttribSet( LContext->attribSetName ); + uint32_t totalXfer = 0; for ( GLuint i = 0; i < _RGL_MAX_VERTEX_ATTRIBS; ++i ) - totalXfer += dparams->attribXferSize[i]; + totalXfer += dparams->attribXferSize[i]; GLuint gpuOffset = _RGLValidateAttributesSlow( dparams, &isMain ); (void)gpuOffset; @@ -6611,43 +6525,43 @@ GLAPI void APIENTRY glPixelStorei( GLenum pname, GLint param ) GLAPI void APIENTRY glTextureReferenceSCE( GLenum target, GLuint levels, GLuint baseWidth, GLuint baseHeight, GLuint baseDepth, GLenum internalFormat, GLuint pitch, GLintptr offset ) { - PSGLcontext* LContext = _CurrentContext; + PSGLcontext* LContext = _CurrentContext; - jsTexture *texture = _RGLGetCurrentTexture( LContext->CurrentImageUnit, GL_TEXTURE_2D); - jsBufferObject *bufferObject = _RGLGetBufferObject( LContext, LContext->TextureBuffer ); - _RGLReallocateImages( texture, MAX( baseWidth, MAX( baseHeight, baseDepth ) ) ); + jsTexture *texture = _RGLGetCurrentTexture( LContext->CurrentImageUnit, GL_TEXTURE_2D); + jsBufferObject *bufferObject = _RGLGetBufferObject( LContext, LContext->TextureBuffer ); + _RGLReallocateImages( texture, MAX( baseWidth, MAX( baseHeight, baseDepth ) ) ); - GLuint width = baseWidth; - GLuint height = baseHeight; - _RGLSetImage(texture->image, GL_RGB5_A1, width, height, 0, LContext->unpackAlignment, - 0, 0, NULL ); - width = MAX( 1U, width / 2 ); - height = MAX( 1U, height / 2 ); - texture->usage = GL_TEXTURE_LINEAR_GPU_SCE; + GLuint width = baseWidth; + GLuint height = baseHeight; + _RGLSetImage(texture->image, GL_RGB5_A1, width, height, 0, LContext->unpackAlignment, + 0, 0, NULL ); + width = MAX( 1U, width / 2 ); + height = MAX( 1U, height / 2 ); + texture->usage = GL_TEXTURE_LINEAR_GPU_SCE; - GLboolean r = _RGLPlatformTextureReference( texture, pitch, bufferObject, offset ); + GLboolean r = _RGLPlatformTextureReference( texture, pitch, bufferObject, offset ); - if(!r) - return; + if(!r) + return; - bufferObject->textureReferences.pushBack( texture ); - texture->referenceBuffer = bufferObject; - texture->offset = offset; - _RGLTextureTouchFBOs( texture ); - LContext->needValidate |= PSGL_VALIDATE_TEXTURES_USED | PSGL_VALIDATE_VERTEX_TEXTURES_USED ; + bufferObject->textureReferences.pushBack( texture ); + texture->referenceBuffer = bufferObject; + texture->offset = offset; + _RGLTextureTouchFBOs( texture ); + LContext->needValidate |= PSGL_VALIDATE_TEXTURES_USED | PSGL_VALIDATE_VERTEX_TEXTURES_USED ; } GLAPI void APIENTRY glViewport( GLint x, GLint y, GLsizei width, GLsizei height ) { + PSGLcontext* LContext = _CurrentContext; - PSGLcontext* LContext = _CurrentContext; + LContext->ViewPort.X = x; + LContext->ViewPort.Y = y; + LContext->ViewPort.XSize = width; + LContext->ViewPort.YSize = height; - LContext->ViewPort.X = x; - LContext->ViewPort.Y = y; - LContext->ViewPort.XSize = width; - LContext->ViewPort.YSize = height; - _RGLFifoGlViewport(LContext->ViewPort.X, LContext->ViewPort.Y, - LContext->ViewPort.XSize, LContext->ViewPort.YSize, 0.0f, 1.0f); + _RGLFifoGlViewport(LContext->ViewPort.X, LContext->ViewPort.Y, + LContext->ViewPort.XSize, LContext->ViewPort.YSize, 0.0f, 1.0f); } jsTexture *_RGLGetCurrentTexture( const jsTextureImageUnit *unit, GLenum target ) @@ -6677,30 +6591,27 @@ CgparameterHookFunction _cgParameterDestroyHook = NULL; typedef struct RGLcgProfileMapType { - CGprofile id; - char* string; - int is_vertex_program; -} -RGLcgProfileMapType; + CGprofile id; + char* string; + int is_vertex_program; +} RGLcgProfileMapType; static void _RGLCgProgramPushFront( _CGcontext* ctx, _CGprogram* prog ) { - prog->next = ctx->programList; - ctx->programList = prog; - prog->parentContext = ctx; - ctx->programCount++; + prog->next = ctx->programList; + ctx->programList = prog; + prog->parentContext = ctx; + ctx->programCount++; } static _CGprogram* _RGLCgProgramFindPrev( _CGcontext* ctx, _CGprogram* prog ) { - _CGprogram* ptr = ctx->programList; + _CGprogram* ptr = ctx->programList; - while ( NULL != ptr && prog != ptr->next ) - { - ptr = ptr->next; - } + while ( NULL != ptr && prog != ptr->next ) + ptr = ptr->next; - return ptr; + return ptr; } void _RGLCgProgramErase( _CGprogram* prog ) @@ -6761,32 +6672,30 @@ bool _RGLCgCreateProgramChecks( CGcontext ctx, CGprofile profile, CGenum program typedef struct { - const char* elfFile; - size_t elfFileSize; + const char* elfFile; + size_t elfFileSize; - const char *symtab; - size_t symbolSize; - size_t symbolCount; - const char *symbolstrtab; + const char *symtab; + size_t symbolSize; + size_t symbolCount; + const char *symbolstrtab; - const char* shadertab; - size_t shadertabSize; - const char* strtab; - size_t strtabSize; - const char* consttab; - size_t consttabSize; -} -CGELFBinary; + const char* shadertab; + size_t shadertabSize; + const char* strtab; + size_t strtabSize; + const char* consttab; + size_t consttabSize; +} CGELFBinary; typedef struct { - const char *texttab; - size_t texttabSize; - const char *paramtab; - size_t paramtabSize; - int index; -} -CGELFProgram; + const char *texttab; + size_t texttabSize; + const char *paramtab; + size_t paramtabSize; + int index; +} CGELFProgram; static bool cgOpenElf( const void *ptr, size_t size, CGELFBinary *elfBinary ) { @@ -6882,7 +6791,7 @@ static CGprogram _RGLCgCreateProgram( CGcontext ctx, CGprofile profile, const Cg // The parameters and the actual program are generated from the ABI specific calls. _CGprogram* prog = ( _CGprogram* )malloc( sizeof( _CGprogram ) ); - if ( NULL == prog ) + if ( prog == NULL ) { _RGLCgRaiseError( CG_MEMORY_ALLOC_ERROR ); return NULL; @@ -6935,7 +6844,7 @@ static CGprogram _RGLCgCreateProgram( CGcontext ctx, CGprofile profile, const Cg // if the creation failed, free all resources. // the error was raised when the error was encoutered. - if ( 0 == success ) + if ( success == 0 ) { // free the program object free( prog ); @@ -7011,9 +6920,7 @@ CG_API CGprogram cgCreateProgram( CGcontext ctx, } } else - { binaryBuffer = program; - } bool bConvertedToElf = false; @@ -7134,8 +7041,6 @@ CG_API CGprogram cgCreateProgram( CGcontext ctx, return prog; } - - CG_API CGprogram cgCreateProgramFromFile( CGcontext ctx, CGenum program_type, const char* program_file, @@ -7192,7 +7097,7 @@ CG_API CGprogram cgCreateProgramFromFile( CGcontext ctx, { fp = fopen( program_file, "rb" ); - if ( NULL == fp ) + if ( fp == NULL ) { _RGLCgRaiseError( CG_FILE_READ_ERROR ); return ( CGprogram )NULL; @@ -7244,7 +7149,7 @@ CG_API CGprogram cgCreateProgramFromFile( CGcontext ctx, if ( !fp ) { fp = fopen( program_file, "rb" ); - if ( NULL == fp ) + if ( fp == NULL ) { _RGLCgRaiseError( CG_FILE_READ_ERROR ); return ( CGprogram )NULL; @@ -7257,7 +7162,7 @@ CG_API CGprogram cgCreateProgramFromFile( CGcontext ctx, rewind( fp ); char* ptr = ( char* )malloc( file_size + 1 ); - if ( NULL == ptr ) + if ( ptr == NULL ) { _RGLCgRaiseError( CG_MEMORY_ALLOC_ERROR ); fclose( fp ); @@ -7287,7 +7192,7 @@ CG_API CGprogram cgCopyProgram( CGprogram program ) return NULL; } _CGprogram* prog = _cgGetProgPtr( program ); - if ( NULL == prog ) + if ( prog == NULL ) { _RGLCgRaiseError( CG_INVALID_PROGRAM_HANDLE_ERROR ); return ( CGprogram )NULL; @@ -7308,7 +7213,7 @@ CG_API CGprogram cgCopyProgram( CGprogram program ) newprog = ( _CGprogram* )malloc( sizeof( _CGprogram ) ); } - if ( NULL == newprog ) + if ( newprog == NULL ) { _RGLCgRaiseError( CG_MEMORY_ALLOC_ERROR ); return ( CGprogram )NULL; @@ -7371,7 +7276,7 @@ CG_API void cgDestroyProgram( CGprogram program ) return; } _CGprogram* ptr = _cgGetProgPtr( program ); - if ( NULL == ptr ) + if ( ptr == NULL ) { _RGLCgRaiseError( CG_INVALID_PROGRAM_HANDLE_ERROR ); return; @@ -7489,7 +7394,7 @@ CGprogramGroup _RGLCgCreateProgramGroupFromFile( CGcontext ctx, const char *grou { FILE* fp = fopen( group_file, "rb" ); - if ( NULL == fp ) + if ( fp == NULL ) { _RGLCgRaiseError( CG_FILE_READ_ERROR ); return ( CGprogramGroup )NULL; @@ -7501,7 +7406,7 @@ CGprogramGroup _RGLCgCreateProgramGroupFromFile( CGcontext ctx, const char *grou rewind( fp ); char* ptr = ( char* )malloc( file_size + 1 ); - if ( NULL == ptr ) + if ( ptr == NULL ) { _RGLCgRaiseError( CG_MEMORY_ALLOC_ERROR ); return ( CGprogramGroup )NULL; @@ -7651,16 +7556,14 @@ int _RGLCgGetProgramCount( CGprogramGroup group ) } static const RGLcgProfileMapType RGLcgProfileMap[] = - { - {( CGprofile )6144, "CG_PROFILE_START", 1 }, - {( CGprofile )6145, "unknown", 1 }, - +{ + {( CGprofile )6144, "CG_PROFILE_START", 1 }, + {( CGprofile )6145, "unknown", 1 }, #define CG_PROFILE_MACRO(name, compiler_id, compiler_id_caps, compiler_opt,int_id,vertex_profile) \ - {CG_PROFILE_ ## compiler_id_caps, compiler_opt, vertex_profile}, + {CG_PROFILE_ ## compiler_id_caps, compiler_opt, vertex_profile}, #include - - {( CGprofile )0, "", 0 } - }; + {( CGprofile )0, "", 0 } +}; CG_API const char* cgGetProfileString( CGprofile profile ) { @@ -7683,7 +7586,7 @@ CG_API CGprofile cgGetProfile( const char* profile_string ) unsigned int i = 0; while ( i < arraysize ) { - if ( 0 == strcmp( RGLcgProfileMap[i].string, profile_string ) ) + if ( strcmp( RGLcgProfileMap[i].string, profile_string ) == 0 ) { return RGLcgProfileMap[i].id; } @@ -8063,7 +7966,7 @@ CGGL_API void cgGLLoadProgram( CGprogram program ) CGGL_API CGbool cgGLIsProgramLoaded( CGprogram program ) { - return CG_TRUE; + return CG_TRUE; } @@ -8132,43 +8035,34 @@ CGGL_API void cgGLUnbindProgram( CGprofile profile ) CGGL_API GLuint cgGLGetProgramID( CGprogram program ) { - - return 0; -} - -CGGL_API void cgGLEnableProgramProfiles( CGprogram program ) -{ - return; -} - -CGGL_API void cgGLDisableProgramProfiles( CGprogram program ) -{ - return; + return 0; } +CGGL_API void cgGLEnableProgramProfiles( CGprogram program ) {} +CGGL_API void cgGLDisableProgramProfiles( CGprogram program ) {} CGGL_API void cgGLSetParameter1f( CGparameter param, float x ) { + CgRuntimeParameter *ptr = _RGLCgGLTestParameter( param ); - CgRuntimeParameter *ptr = _RGLCgGLTestParameter( param ); - - float v[4] = {x, x, x, x}; - ptr->setterIndex( ptr, v, CG_GETINDEX( param ) ); + float v[4] = {x, x, x, x}; + ptr->setterIndex( ptr, v, CG_GETINDEX( param ) ); } CGGL_API void cgGLSetParameter2f( CGparameter param, float x, float y ) { - CgRuntimeParameter *ptr = _RGLCgGLTestParameter( param ); + CgRuntimeParameter *ptr = _RGLCgGLTestParameter( param ); - float v[4] = {x, y, y, y}; - ptr->setterIndex( ptr, v, CG_GETINDEX( param ) ); + float v[4] = {x, y, y, y}; + ptr->setterIndex( ptr, v, CG_GETINDEX( param ) ); } -CGGL_API void cgGLSetParameterPointer( CGparameter param, - GLint fsize, - GLenum type, - GLsizei stride, - const GLvoid *pointer ) +CGGL_API void cgGLSetParameterPointer +( CGparameter param, + GLint fsize, + GLenum type, + GLsizei stride, + const GLvoid *pointer ) { CgRuntimeParameter *_ptr = _RGLCgGLTestParameter( param ); @@ -8187,13 +8081,12 @@ CGGL_API void cgGLSetParameterPointer( CGparameter param, CGGL_API void cgGLEnableClientState( CGparameter param ) { + CgRuntimeParameter *_ptr = _RGLCgGLTestParameter( param ); - CgRuntimeParameter *_ptr = _RGLCgGLTestParameter( param ); + const CgParameterResource *parameterResource = _RGLGetParameterResource( _ptr->program, _ptr->parameterEntry ); - const CgParameterResource *parameterResource = _RGLGetParameterResource( _ptr->program, _ptr->parameterEntry ); - - GLuint index = ( GLuint )( parameterResource->resource - CG_ATTR0 ); - _RGLEnableVertexAttribArrayNV( index ); + GLuint index = ( GLuint )( parameterResource->resource - CG_ATTR0 ); + _RGLEnableVertexAttribArrayNV( index ); } CGGL_API void cgGLDisableClientState( CGparameter param ) @@ -8278,9 +8171,8 @@ CGGL_API void cgGLEnableTextureParameter( CGparameter param ) static void _RGLCgContextZero( _CGcontext* p ) { - memset( p, 0, sizeof( *p ) ); - p->compileType = CG_UNKNOWN; - + memset( p, 0, sizeof( *p ) ); + p->compileType = CG_UNKNOWN; } static void _RGLCgContextPushFront( _CGcontext* ctx ) @@ -8306,7 +8198,7 @@ CG_API CGcontext cgCreateContext( void ) _CGcontext* ptr = NULL; ptr = ( _CGcontext* )malloc( sizeof( _CGcontext ) ); - if ( NULL == ptr ) + if ( ptr == NULL ) { _RGLCgRaiseError( CG_MEMORY_ALLOC_ERROR ); return ( CGcontext )NULL; @@ -8608,33 +8500,30 @@ unsigned int _RGLCountFloatsInCgType( CGtype type ) void _cgRaiseInvalidParam( CgRuntimeParameter*p, const void*v ) { - _RGLCgRaiseError( CG_INVALID_PARAMETER_ERROR ); + _RGLCgRaiseError( CG_INVALID_PARAMETER_ERROR ); } void _cgRaiseInvalidParamIndex( CgRuntimeParameter*p, const void*v, const int index ) { - _RGLCgRaiseError( CG_INVALID_PARAMETER_ERROR ); + _RGLCgRaiseError( CG_INVALID_PARAMETER_ERROR ); } void _cgRaiseNotMatrixParam( CgRuntimeParameter*p, const void*v ) { - _RGLCgRaiseError( CG_NOT_MATRIX_PARAM_ERROR ); -} -void _cgRaiseNotMatrixParamIndex( CgRuntimeParameter*p, const void*v, const int index ) -{ - _RGLCgRaiseError( CG_NOT_MATRIX_PARAM_ERROR ); + _RGLCgRaiseError( CG_NOT_MATRIX_PARAM_ERROR ); } -void _cgIgnoreSetParam( CgRuntimeParameter*p, const void*v ) -{ -} -void _cgIgnoreSetParamIndex( CgRuntimeParameter*p, const void*v, const int index ) +void _cgRaiseNotMatrixParamIndex( CgRuntimeParameter*p, const void*v, const int index ) { + _RGLCgRaiseError( CG_NOT_MATRIX_PARAM_ERROR ); } +void _cgIgnoreSetParam( CgRuntimeParameter*p, const void*v ) {} +void _cgIgnoreSetParamIndex( CgRuntimeParameter*p, const void*v, const int index ) {} + CgRuntimeParameter* _cgGLTestTextureParameter( CGparameter param ) { - CgRuntimeParameter* ptr = _RGLCgGLTestParameter( param ); - return ptr; + CgRuntimeParameter* ptr = _RGLCgGLTestParameter( param ); + return ptr; } diff --git a/console/rgl/ps3/rgl.h b/console/rgl/ps3/rgl.h index 14da606342..632f719cbd 100644 --- a/console/rgl/ps3/rgl.h +++ b/console/rgl/ps3/rgl.h @@ -6,8 +6,10 @@ #include "base.hpp" #ifdef __PSL1GHT__ +#include #include #include +#include #include "../../../ps3/sdk_defines.h" #define CGerror int typedef void (* CGerrorCallbackFunc)(void); @@ -30,104 +32,104 @@ extern "C" typedef enum RGLEnum { - RGL_NONE = 0x0000, - RGL_COLOR_BUFFER_BIT = 0x4000, - RGL_ZERO = 0, - RGL_ONE = 1, - RGL_SRC_COLOR = 0x0300, - RGL_ONE_MINUS_SRC_COLOR = 0x0301, - RGL_SRC_ALPHA = 0x0302, - RGL_ONE_MINUS_SRC_ALPHA = 0x0303, - RGL_DST_ALPHA = 0x0304, - RGL_ONE_MINUS_DST_ALPHA = 0x0305, - RGL_DST_COLOR = 0x0306, - RGL_ONE_MINUS_DST_COLOR = 0x0307, - RGL_SRC_ALPHA_SATURATE = 0x0308, - RGL_ONE_MINUS_CONSTANT_COLOR = 0x8002, - RGL_CONSTANT_ALPHA = 0x8003, - RGL_ONE_MINUS_CONSTANT_ALPHA = 0x8004, - RGL_MIN = 0x8007, - RGL_MAX = 0x8008, - RGL_FUNC_SUBTRACT = 0x800A, - RGL_FUNC_REVERSE_SUBTRACT = 0x800B, - RGL_LUMINANCE8 = 0x8040, - RGL_LUMINANCE16 = 0x8042, - RGL_ALPHA8 = 0x803C, - RGL_ALPHA16 = 0x803E, - RGL_INTENSITY8 = 0x804B, - RGL_INTENSITY16 = 0x804D, - RGL_LUMINANCE8_ALPHA8 = 0x8045, - RGL_LUMINANCE16_ALPHA16 = 0x8048, - RGL_HILO8 = 0x885E, - RGL_HILO16 = 0x86F8, - RGL_ARGB8 = 0x6007, - RGL_BGRA8 = 0xff01, - RGL_RGBA8 = 0x8058, - RGL_ABGR8 = 0xff02, - RGL_XBGR8 = 0xff03, - RGL_RGBX8 = 0xff07, - RGL_FLOAT_R32 = 0x8885, - RGL_FLOAT_RGBA16 = 0x888A, - RGL_FLOAT_RGBA32 = 0x888B, - RGL_FLOAT_RGBX16 = 0xff04, - RGL_FLOAT_RGBX32 = 0xff05, - RGL_LUMINANCE32F_ARB = 0x8818, - RGL_ALPHA_LUMINANCE16F_SCE = 0x600B, - RGL_RGB5_A1_SCE = 0x600C, - RGL_RGB565_SCE = 0x600D, - RGL_DITHER = 0x0bd0, - RGL_PSHADER_SRGB_REMAPPING = 0xff06, - RGL_VERTEX_ATTRIB_ARRAY0 = 0x8650, - RGL_VERTEX_ATTRIB_ARRAY1 = 0x8651, - RGL_VERTEX_ATTRIB_ARRAY2 = 0x8652, - RGL_VERTEX_ATTRIB_ARRAY3 = 0x8653, - RGL_VERTEX_ATTRIB_ARRAY4 = 0x8654, - RGL_VERTEX_ATTRIB_ARRAY5 = 0x8655, - RGL_VERTEX_ATTRIB_ARRAY6 = 0x8656, - RGL_VERTEX_ATTRIB_ARRAY7 = 0x8657, - RGL_VERTEX_ATTRIB_ARRAY8 = 0x8658, - RGL_VERTEX_ATTRIB_ARRAY9 = 0x8659, - RGL_VERTEX_ATTRIB_ARRAY10 = 0x865a, - RGL_VERTEX_ATTRIB_ARRAY11 = 0x865b, - RGL_VERTEX_ATTRIB_ARRAY12 = 0x865c, - RGL_VERTEX_ATTRIB_ARRAY13 = 0x865d, - RGL_VERTEX_ATTRIB_ARRAY14 = 0x865e, - RGL_VERTEX_ATTRIB_ARRAY15 = 0x865f, - RGL_CLAMP = 0x2900, - RGL_REPEAT = 0x2901, - RGL_CLAMP_TO_EDGE = 0x812F, - RGL_CLAMP_TO_BORDER = 0x812D, - RGL_MIRRORED_REPEAT = 0x8370, - RGL_MIRROR_CLAMP = 0x8742, - RGL_MIRROR_CLAMP_TO_EDGE = 0x8743, - RGL_MIRROR_CLAMP_TO_BORDER = 0x8912, - RGL_GAMMA_REMAP_RED_BIT = 0x0001, - RGL_GAMMA_REMAP_GREEN_BIT = 0x0002, - RGL_GAMMA_REMAP_BLUE_BIT = 0x0004, - RGL_GAMMA_REMAP_ALPHA_BIT = 0x0008, - RGL_TEXTURE_WRAP_S = 0x2802, - RGL_TEXTURE_WRAP_T = 0x2803, - RGL_TEXTURE_WRAP_R = 0x8072, - RGL_TEXTURE_MIN_FILTER = 0x2801, - RGL_TEXTURE_MAG_FILTER = 0x2800, - RGL_TEXTURE_MAX_ANISOTROPY = 0x84FE, - RGL_TEXTURE_COMPARE_FUNC = 0x884D, - RGL_TEXTURE_MIN_LOD = 0x813A, - RGL_TEXTURE_MAX_LOD = 0x813B, - RGL_TEXTURE_LOD_BIAS = 0x8501, - RGL_TEXTURE_BORDER_COLOR = 0x1004, - RGL_TEXTURE_GAMMA_REMAP = 0xff30, - RGL_VERTEX_PROGRAM = 0x8620, - RGL_FRAGMENT_PROGRAM = 0x8804, - RGL_FLOAT = 0x1406, - RGL_HALF_FLOAT = 0x140B, - RGL_SHORT = 0x1402, - RGL_UNSIGNED_BYTE = 0x1401, - RGL_UNSIGNED_SHORT = 0x1403, - RGL_UNSIGNED_INT = 0x1405, - RGL_BYTE = 0x1400, - RGL_INT = 0x1404, - RGL_CMP = 0x6020, + RGL_NONE = 0x0000, + RGL_COLOR_BUFFER_BIT = 0x4000, + RGL_ZERO = 0, + RGL_ONE = 1, + RGL_SRC_COLOR = 0x0300, + RGL_ONE_MINUS_SRC_COLOR = 0x0301, + RGL_SRC_ALPHA = 0x0302, + RGL_ONE_MINUS_SRC_ALPHA = 0x0303, + RGL_DST_ALPHA = 0x0304, + RGL_ONE_MINUS_DST_ALPHA = 0x0305, + RGL_DST_COLOR = 0x0306, + RGL_ONE_MINUS_DST_COLOR = 0x0307, + RGL_SRC_ALPHA_SATURATE = 0x0308, + RGL_ONE_MINUS_CONSTANT_COLOR = 0x8002, + RGL_CONSTANT_ALPHA = 0x8003, + RGL_ONE_MINUS_CONSTANT_ALPHA = 0x8004, + RGL_MIN = 0x8007, + RGL_MAX = 0x8008, + RGL_FUNC_SUBTRACT = 0x800A, + RGL_FUNC_REVERSE_SUBTRACT = 0x800B, + RGL_LUMINANCE8 = 0x8040, + RGL_LUMINANCE16 = 0x8042, + RGL_ALPHA8 = 0x803C, + RGL_ALPHA16 = 0x803E, + RGL_INTENSITY8 = 0x804B, + RGL_INTENSITY16 = 0x804D, + RGL_LUMINANCE8_ALPHA8 = 0x8045, + RGL_LUMINANCE16_ALPHA16 = 0x8048, + RGL_HILO8 = 0x885E, + RGL_HILO16 = 0x86F8, + RGL_ARGB8 = 0x6007, + RGL_BGRA8 = 0xff01, + RGL_RGBA8 = 0x8058, + RGL_ABGR8 = 0xff02, + RGL_XBGR8 = 0xff03, + RGL_RGBX8 = 0xff07, + RGL_FLOAT_R32 = 0x8885, + RGL_FLOAT_RGBA16 = 0x888A, + RGL_FLOAT_RGBA32 = 0x888B, + RGL_FLOAT_RGBX16 = 0xff04, + RGL_FLOAT_RGBX32 = 0xff05, + RGL_LUMINANCE32F_ARB = 0x8818, + RGL_ALPHA_LUMINANCE16F_SCE = 0x600B, + RGL_RGB5_A1_SCE = 0x600C, + RGL_RGB565_SCE = 0x600D, + RGL_DITHER = 0x0bd0, + RGL_PSHADER_SRGB_REMAPPING = 0xff06, + RGL_VERTEX_ATTRIB_ARRAY0 = 0x8650, + RGL_VERTEX_ATTRIB_ARRAY1 = 0x8651, + RGL_VERTEX_ATTRIB_ARRAY2 = 0x8652, + RGL_VERTEX_ATTRIB_ARRAY3 = 0x8653, + RGL_VERTEX_ATTRIB_ARRAY4 = 0x8654, + RGL_VERTEX_ATTRIB_ARRAY5 = 0x8655, + RGL_VERTEX_ATTRIB_ARRAY6 = 0x8656, + RGL_VERTEX_ATTRIB_ARRAY7 = 0x8657, + RGL_VERTEX_ATTRIB_ARRAY8 = 0x8658, + RGL_VERTEX_ATTRIB_ARRAY9 = 0x8659, + RGL_VERTEX_ATTRIB_ARRAY10 = 0x865a, + RGL_VERTEX_ATTRIB_ARRAY11 = 0x865b, + RGL_VERTEX_ATTRIB_ARRAY12 = 0x865c, + RGL_VERTEX_ATTRIB_ARRAY13 = 0x865d, + RGL_VERTEX_ATTRIB_ARRAY14 = 0x865e, + RGL_VERTEX_ATTRIB_ARRAY15 = 0x865f, + RGL_CLAMP = 0x2900, + RGL_REPEAT = 0x2901, + RGL_CLAMP_TO_EDGE = 0x812F, + RGL_CLAMP_TO_BORDER = 0x812D, + RGL_MIRRORED_REPEAT = 0x8370, + RGL_MIRROR_CLAMP = 0x8742, + RGL_MIRROR_CLAMP_TO_EDGE = 0x8743, + RGL_MIRROR_CLAMP_TO_BORDER = 0x8912, + RGL_GAMMA_REMAP_RED_BIT = 0x0001, + RGL_GAMMA_REMAP_GREEN_BIT = 0x0002, + RGL_GAMMA_REMAP_BLUE_BIT = 0x0004, + RGL_GAMMA_REMAP_ALPHA_BIT = 0x0008, + RGL_TEXTURE_WRAP_S = 0x2802, + RGL_TEXTURE_WRAP_T = 0x2803, + RGL_TEXTURE_WRAP_R = 0x8072, + RGL_TEXTURE_MIN_FILTER = 0x2801, + RGL_TEXTURE_MAG_FILTER = 0x2800, + RGL_TEXTURE_MAX_ANISOTROPY = 0x84FE, + RGL_TEXTURE_COMPARE_FUNC = 0x884D, + RGL_TEXTURE_MIN_LOD = 0x813A, + RGL_TEXTURE_MAX_LOD = 0x813B, + RGL_TEXTURE_LOD_BIAS = 0x8501, + RGL_TEXTURE_BORDER_COLOR = 0x1004, + RGL_TEXTURE_GAMMA_REMAP = 0xff30, + RGL_VERTEX_PROGRAM = 0x8620, + RGL_FRAGMENT_PROGRAM = 0x8804, + RGL_FLOAT = 0x1406, + RGL_HALF_FLOAT = 0x140B, + RGL_SHORT = 0x1402, + RGL_UNSIGNED_BYTE = 0x1401, + RGL_UNSIGNED_SHORT = 0x1403, + RGL_UNSIGNED_INT = 0x1405, + RGL_BYTE = 0x1400, + RGL_INT = 0x1404, + RGL_CMP = 0x6020, } RGLEnum; typedef struct PSGLdevice PSGLdevice; @@ -138,30 +140,26 @@ extern RGLState _RGLState; struct RGLViewportState { - GLint x, y, w, h; - - GLfloat xScale, xCenter; - GLfloat yScale, yCenter; + GLint x, y, w, h; + GLfloat xScale, xCenter; + GLfloat yScale, yCenter; }; struct jsFramebufferAttachment { - GLenum type; - GLuint name; - GLenum textureTarget; - jsFramebufferAttachment(): type( GL_NONE ), name( 0 ), textureTarget( GL_NONE ) - {}; + GLenum type; + GLuint name; + GLenum textureTarget; + jsFramebufferAttachment(): type( GL_NONE ), name( 0 ), textureTarget( GL_NONE ) {}; }; struct jsFramebuffer { - jsFramebufferAttachment color[_RGL_MAX_COLOR_ATTACHMENTS]; - GLboolean needValidate; - jsFramebuffer(): needValidate( GL_TRUE ) - {}; - virtual ~jsFramebuffer() - {}; + jsFramebufferAttachment color[_RGL_MAX_COLOR_ATTACHMENTS]; + GLboolean needValidate; + jsFramebuffer(): needValidate( GL_TRUE ) {}; + virtual ~jsFramebuffer() {}; }; #define RGLBIT_GET(f,n) ((f) & (1<<(n))) @@ -170,125 +168,115 @@ struct jsFramebuffer #define RGLBIT_ASSIGN(f,n,val) do { if(val) RGLBIT_TRUE(f,n); else RGLBIT_FALSE(f,n); } while(0) #ifndef MSVC - #define ALIGN16 __attribute__((aligned (16))) #define _RGL_RESTRICT __restrict - -#if defined(_WIN64) - typedef __int64 RGLintptr; - typedef __int64 RGLsizeiptr; #else - typedef long RGLintptr; - typedef long RGLsizeiptr; -#endif - -#else - #define ALIGN16 #define _RGL_RESTRICT #pragma warning( push ) #pragma warning ( disable : 4200 ) - typedef intptr_t RGLintptr; - typedef size_t RGLsizeiptr; #endif +typedef intptr_t RGLintptr; +typedef size_t RGLsizeiptr; + typedef struct { - GLfloat X, Y , Z, W; + GLfloat X, Y , Z, W; } jsPositionXYZW; typedef struct { - GLfloat X, Y , Z; + GLfloat X, Y , Z; } jsPositionXYZ; typedef struct { - GLfloat R, G, B, A; + GLfloat R, G, B, A; } jsColorRGBAf; typedef struct { - GLfloat * MatrixStackf; - int MatrixStackPtr; - GLboolean dirty; + GLfloat * MatrixStackf; + int MatrixStackPtr; + GLboolean dirty; } jsMatrixStack; typedef struct { - int X, Y, XSize, YSize; + int X, Y, XSize, YSize; } jsViewPort; #define _RGL_IMAGE_STORAGE_RASTER 0 #define _RGL_IMAGE_STORAGE_BLOCK 1 enum { - _RGL_IMAGE_DATASTATE_UNSET = 0x0, - _RGL_IMAGE_DATASTATE_HOST = 0x1, - _RGL_IMAGE_DATASTATE_GPU = 0x2 + _RGL_IMAGE_DATASTATE_UNSET = 0x0, + _RGL_IMAGE_DATASTATE_HOST = 0x1, + _RGL_IMAGE_DATASTATE_GPU = 0x2 }; typedef struct jsImage_ { - GLboolean isSet; + GLboolean isSet; - GLenum internalFormat; - GLenum format; - GLenum type; - GLsizei width; - GLsizei height; - GLsizei alignment; + GLenum internalFormat; + GLenum format; + GLenum type; + GLsizei width; + GLsizei height; + GLsizei alignment; - GLsizei storageSize; - GLsizei xstride, ystride; - GLuint xblk, yblk; + GLsizei storageSize; + GLsizei xstride, ystride; + GLuint xblk, yblk; - char *data; - char *mallocData; - GLsizei mallocStorageSize; - GLenum dataState; + char *data; + char *mallocData; + GLsizei mallocStorageSize; + GLenum dataState; } jsImage; typedef struct { - GLenum format; - GLenum type; - GLsizei width; - GLsizei height; - GLsizei xstride; - GLsizei ystride; - void* data; + GLenum format; + GLenum type; + GLsizei width; + GLsizei height; + GLsizei xstride; + GLsizei ystride; + void* data; } jsRaster; #define _RGL_TEXTURE_REVALIDATE_LAYOUT 0x01 #define _RGL_TEXTURE_REVALIDATE_IMAGES 0x02 #define _RGL_TEXTURE_REVALIDATE_PARAMETERS 0x04 - typedef struct jsBufferObject jsBufferObject; +typedef struct jsBufferObject jsBufferObject; - typedef struct - { - GLuint revalidate; - GLuint target; +typedef struct +{ + GLuint revalidate; + GLuint target; - GLuint minFilter; - GLuint magFilter; - GLuint gammaRemap; - GLenum usage; + GLuint minFilter; + GLuint magFilter; + GLuint gammaRemap; + GLenum usage; - GLboolean isRenderTarget; - GLboolean isComplete; + GLboolean isRenderTarget; + GLboolean isComplete; - jsBufferObject *referenceBuffer; - GLintptr offset; + jsBufferObject *referenceBuffer; + GLintptr offset; - RGL::Vector framebuffers; + RGL::Vector framebuffers; - GLuint imageCount; - jsImage* image; - void * platformTexture[]; - } - jsTexture; + GLuint imageCount; + jsImage* image; + void * platformTexture[]; +} +jsTexture; #define _RGL_MAX_TEXTURE_COORDS 8 #define _RGL_MAX_TEXTURE_IMAGE_UNITS 16 @@ -308,146 +296,145 @@ typedef struct typedef struct { - GLuint bound2D; + GLuint bound2D; - jsTexture* default2D; + jsTexture* default2D; - GLenum fragmentTarget; + GLenum fragmentTarget; - GLenum envMode; - jsColorRGBAf envColor; + GLenum envMode; + jsColorRGBAf envColor; - jsTexture* currentTexture; + jsTexture* currentTexture; } jsTextureImageUnit; typedef struct { - GLuint revalidate; - jsMatrixStack TextureMatrixStack; + GLuint revalidate; + jsMatrixStack TextureMatrixStack; } jsTextureCoordsUnit; enum { - _RGL_FRAMEBUFFER_ATTACHMENT_NONE, - _RGL_FRAMEBUFFER_ATTACHMENT_RENDERBUFFER, - _RGL_FRAMEBUFFER_ATTACHMENT_TEXTURE, + _RGL_FRAMEBUFFER_ATTACHMENT_NONE, + _RGL_FRAMEBUFFER_ATTACHMENT_RENDERBUFFER, + _RGL_FRAMEBUFFER_ATTACHMENT_TEXTURE, }; typedef enum PSGLtvStandard { - PSGL_TV_STANDARD_NONE, - PSGL_TV_STANDARD_NTSC_M, - PSGL_TV_STANDARD_NTSC_J, - PSGL_TV_STANDARD_PAL_M, - PSGL_TV_STANDARD_PAL_B, - PSGL_TV_STANDARD_PAL_D, - PSGL_TV_STANDARD_PAL_G, - PSGL_TV_STANDARD_PAL_H, - PSGL_TV_STANDARD_PAL_I, - PSGL_TV_STANDARD_PAL_N, - PSGL_TV_STANDARD_PAL_NC, - PSGL_TV_STANDARD_HD480I, - PSGL_TV_STANDARD_HD480P, - PSGL_TV_STANDARD_HD576I, - PSGL_TV_STANDARD_HD576P, - PSGL_TV_STANDARD_HD720P, - PSGL_TV_STANDARD_HD1080I, - PSGL_TV_STANDARD_HD1080P, - PSGL_TV_STANDARD_1280x720_ON_VESA_1280x768 = 128, - PSGL_TV_STANDARD_1280x720_ON_VESA_1280x1024, - PSGL_TV_STANDARD_1920x1080_ON_VESA_1920x1200, + PSGL_TV_STANDARD_NONE, + PSGL_TV_STANDARD_NTSC_M, + PSGL_TV_STANDARD_NTSC_J, + PSGL_TV_STANDARD_PAL_M, + PSGL_TV_STANDARD_PAL_B, + PSGL_TV_STANDARD_PAL_D, + PSGL_TV_STANDARD_PAL_G, + PSGL_TV_STANDARD_PAL_H, + PSGL_TV_STANDARD_PAL_I, + PSGL_TV_STANDARD_PAL_N, + PSGL_TV_STANDARD_PAL_NC, + PSGL_TV_STANDARD_HD480I, + PSGL_TV_STANDARD_HD480P, + PSGL_TV_STANDARD_HD576I, + PSGL_TV_STANDARD_HD576P, + PSGL_TV_STANDARD_HD720P, + PSGL_TV_STANDARD_HD1080I, + PSGL_TV_STANDARD_HD1080P, + PSGL_TV_STANDARD_1280x720_ON_VESA_1280x768 = 128, + PSGL_TV_STANDARD_1280x720_ON_VESA_1280x1024, + PSGL_TV_STANDARD_1920x1080_ON_VESA_1920x1200, } PSGLtvStandard; typedef enum PSGLdeviceConnector { - PSGL_DEVICE_CONNECTOR_NONE, - PSGL_DEVICE_CONNECTOR_VGA, - PSGL_DEVICE_CONNECTOR_DVI, - PSGL_DEVICE_CONNECTOR_HDMI, - PSGL_DEVICE_CONNECTOR_COMPOSITE, - PSGL_DEVICE_CONNECTOR_SVIDEO, - PSGL_DEVICE_CONNECTOR_COMPONENT, + PSGL_DEVICE_CONNECTOR_NONE, + PSGL_DEVICE_CONNECTOR_VGA, + PSGL_DEVICE_CONNECTOR_DVI, + PSGL_DEVICE_CONNECTOR_HDMI, + PSGL_DEVICE_CONNECTOR_COMPOSITE, + PSGL_DEVICE_CONNECTOR_SVIDEO, + PSGL_DEVICE_CONNECTOR_COMPONENT, } PSGLdeviceConnector; typedef enum PSGLbufferingMode { - PSGL_BUFFERING_MODE_SINGLE = 1, - PSGL_BUFFERING_MODE_DOUBLE = 2, - PSGL_BUFFERING_MODE_TRIPLE = 3, + PSGL_BUFFERING_MODE_SINGLE = 1, + PSGL_BUFFERING_MODE_DOUBLE = 2, + PSGL_BUFFERING_MODE_TRIPLE = 3, } PSGLbufferingMode; typedef enum RescRatioMode { - RESC_RATIO_MODE_FULLSCREEN, - RESC_RATIO_MODE_LETTERBOX, - RESC_RATIO_MODE_PANSCAN, + RESC_RATIO_MODE_FULLSCREEN, + RESC_RATIO_MODE_LETTERBOX, + RESC_RATIO_MODE_PANSCAN, } RescRatioMode; typedef enum RescPalTemporalMode { - RESC_PAL_TEMPORAL_MODE_50_NONE, - RESC_PAL_TEMPORAL_MODE_60_DROP, - RESC_PAL_TEMPORAL_MODE_60_INTERPOLATE, - RESC_PAL_TEMPORAL_MODE_60_INTERPOLATE_30_DROP, - RESC_PAL_TEMPORAL_MODE_60_INTERPOLATE_DROP_FLEXIBLE, + RESC_PAL_TEMPORAL_MODE_50_NONE, + RESC_PAL_TEMPORAL_MODE_60_DROP, + RESC_PAL_TEMPORAL_MODE_60_INTERPOLATE, + RESC_PAL_TEMPORAL_MODE_60_INTERPOLATE_30_DROP, + RESC_PAL_TEMPORAL_MODE_60_INTERPOLATE_DROP_FLEXIBLE, } RescPalTemporalMode; typedef enum RescInterlaceMode { - RESC_INTERLACE_MODE_NORMAL_BILINEAR, - RESC_INTERLACE_MODE_INTERLACE_FILTER, + RESC_INTERLACE_MODE_NORMAL_BILINEAR, + RESC_INTERLACE_MODE_INTERLACE_FILTER, } RescInterlaceMode; typedef struct { - GLuint enable; - GLenum colorFormat; - GLenum depthFormat; - GLenum multisamplingMode; - PSGLtvStandard TVStandard; - PSGLdeviceConnector connector; - PSGLbufferingMode bufferingMode; - GLuint width; - GLuint height; - GLuint renderWidth; - GLuint renderHeight; - RescRatioMode rescRatioMode; - RescPalTemporalMode rescPalTemporalMode; - RescInterlaceMode rescInterlaceMode; - GLfloat horizontalScale; - GLfloat verticalScale; + GLuint enable; + GLenum colorFormat; + GLenum depthFormat; + GLenum multisamplingMode; + PSGLtvStandard TVStandard; + PSGLdeviceConnector connector; + PSGLbufferingMode bufferingMode; + GLuint width; + GLuint height; + GLuint renderWidth; + GLuint renderHeight; + RescRatioMode rescRatioMode; + RescPalTemporalMode rescPalTemporalMode; + RescInterlaceMode rescInterlaceMode; + GLfloat horizontalScale; + GLfloat verticalScale; } PSGLdeviceParameters; struct PSGLdevice { - PSGLdeviceParameters deviceParameters; - - GLvoid* rasterDriver; - char platformDevice[]; + PSGLdeviceParameters deviceParameters; + GLvoid* rasterDriver; + char platformDevice[]; }; typedef struct { - GLenum mode; - GLint firstVertex; - GLsizei vertexCount; + GLenum mode; + GLint firstVertex; + GLsizei vertexCount; - GLuint xferTotalSize; - GLuint indexXferOffset; - GLuint indexXferSize; - GLuint attribXferTotalSize; - GLuint attribXferOffset[_RGL_MAX_VERTEX_ATTRIBS]; - GLuint attribXferSize[_RGL_MAX_VERTEX_ATTRIBS]; + GLuint xferTotalSize; + GLuint indexXferOffset; + GLuint indexXferSize; + GLuint attribXferTotalSize; + GLuint attribXferOffset[_RGL_MAX_VERTEX_ATTRIBS]; + GLuint attribXferSize[_RGL_MAX_VERTEX_ATTRIBS]; } jsDrawParams; #define _RGL_ATTRIB_POSITION_INDEX 0 -#define _RGL_ATTRIB_WEIGHT_INDEX 1 -#define _RGL_ATTRIB_NORMAL_INDEX 2 -#define _RGL_ATTRIB_PRIMARY_COLOR_INDEX 3 -#define _RGL_ATTRIB_SECONDARY_COLOR_INDEX 4 +#define _RGL_ATTRIB_WEIGHT_INDEX 1 +#define _RGL_ATTRIB_NORMAL_INDEX 2 +#define _RGL_ATTRIB_PRIMARY_COLOR_INDEX 3 +#define _RGL_ATTRIB_SECONDARY_COLOR_INDEX 4 #define _RGL_ATTRIB_FOG_COORD_INDEX 5 #define _RGL_ATTRIB_POINT_SIZE_INDEX 6 -#define _RGL_ATTRIB_BLEND_INDICES_INDEX 7 +#define _RGL_ATTRIB_BLEND_INDICES_INDEX 7 #define _RGL_ATTRIB_TEX_COORD0_INDEX 8 #define _RGL_ATTRIB_TEX_COORD1_INDEX 9 #define _RGL_ATTRIB_TEX_COORD2_INDEX 10 @@ -457,54 +444,53 @@ typedef struct #define _RGL_ATTRIB_TEX_COORD6_INDEX 14 #define _RGL_ATTRIB_TEX_COORD7_INDEX 15 - typedef struct - { - GLvoid* clientData; - GLuint clientSize; - GLenum clientType; - GLsizei clientStride; - GLuint arrayBuffer; - GLfloat value[4]; - GLuint frequency; - GLboolean normalized; - } - ALIGN16 jsAttribute; +typedef struct +{ + GLvoid* clientData; + GLuint clientSize; + GLenum clientType; + GLsizei clientStride; + GLuint arrayBuffer; + GLfloat value[4]; + GLuint frequency; + GLboolean normalized; +} +ALIGN16 jsAttribute; - typedef struct - { - jsAttribute attrib[_RGL_MAX_VERTEX_ATTRIBS]; - unsigned int DirtyMask; - unsigned int EnabledMask; - unsigned int NeedsConversionMask; - unsigned int HasVBOMask; - unsigned int ModuloMask; - } - ALIGN16 jsAttributeState; +typedef struct +{ + jsAttribute attrib[_RGL_MAX_VERTEX_ATTRIBS]; + unsigned int DirtyMask; + unsigned int EnabledMask; + unsigned int NeedsConversionMask; + unsigned int HasVBOMask; + unsigned int ModuloMask; +} +ALIGN16 jsAttributeState; - typedef struct - { - jsAttributeState attribs; - GLboolean dirty; - unsigned int beenUpdatedMask; - GLvoid* cmdBuffer; - GLuint cmdNumWords; - } - ALIGN16 jsAttribSet; - - struct jsBufferObject - { - GLuint refCount; - GLsizeiptr size; - GLenum usage; - GLboolean mapped; - GLenum internalFormat; - GLuint width; - GLuint height; - RGL::Vector textureReferences; - RGL::Vector attribSets; - void *platformBufferObject[]; - }; +typedef struct +{ + jsAttributeState attribs; + GLboolean dirty; + unsigned int beenUpdatedMask; + GLvoid* cmdBuffer; + GLuint cmdNumWords; +} +ALIGN16 jsAttribSet; +struct jsBufferObject +{ + GLuint refCount; + GLsizeiptr size; + GLenum usage; + GLboolean mapped; + GLenum internalFormat; + GLuint width; + GLuint height; + RGL::Vector textureReferences; + RGL::Vector attribSets; + void *platformBufferObject[]; +}; #define _RGL_CONTEXT_RED_MASK 0x01 #define _RGL_CONTEXT_GREEN_MASK 0x02 @@ -515,86 +501,86 @@ typedef struct #define ELEMENTS_IN_MATRIX 16 - typedef struct jsNameSpace - { - void** data; - void** firstFree; - unsigned long capacity; - } - jsNameSpace; +typedef struct jsNameSpace +{ + void** data; + void** firstFree; + unsigned long capacity; +} +jsNameSpace; - typedef void *( *jsTexNameSpaceCreateFunction )( void ); - typedef void( *jsTexNameSpaceDestroyFunction )( void * ); +typedef void *( *jsTexNameSpaceCreateFunction )( void ); +typedef void( *jsTexNameSpaceDestroyFunction )( void * ); - typedef struct jsTexNameSpace - { - void** data; - GLuint capacity; - jsTexNameSpaceCreateFunction create; - jsTexNameSpaceDestroyFunction destroy; - } - jsTexNameSpace; +typedef struct jsTexNameSpace +{ + void** data; + GLuint capacity; + jsTexNameSpaceCreateFunction create; + jsTexNameSpaceDestroyFunction destroy; +} +jsTexNameSpace; - struct PSGLcontext - { - GLenum error; - int MatrixMode; - jsMatrixStack ModelViewMatrixStack; - jsMatrixStack ProjectionMatrixStack; - GLfloat LocalToScreenMatrixf[ELEMENTS_IN_MATRIX]; - GLfloat InverseModelViewMatrixf[ELEMENTS_IN_MATRIX]; - GLboolean InverseModelViewValid; - GLfloat ScalingFactor; - jsViewPort ViewPort; - jsAttributeState defaultAttribs0; - jsAttributeState *attribs; - jsTexNameSpace attribSetNameSpace; - GLuint attribSetName; - GLboolean attribSetDirty; - jsColorRGBAf ClearColor; - jsColorRGBAf AccumClearColor; - GLboolean ShaderSRGBRemap; - GLboolean Blending; - GLboolean BlendingMrt[3]; - GLenum BlendEquationRGB; - GLenum BlendEquationAlpha; - GLenum BlendFactorSrcRGB; - GLenum BlendFactorDestRGB; - GLenum BlendFactorSrcAlpha; - GLenum BlendFactorDestAlpha; - jsColorRGBAf BlendColor; - GLboolean Dithering; - jsTexNameSpace textureNameSpace; - GLuint ActiveTexture; - GLuint CS_ActiveTexture; - jsTextureImageUnit TextureImageUnits[_RGL_MAX_TEXTURE_IMAGE_UNITS]; - jsTextureImageUnit* CurrentImageUnit; - jsTextureCoordsUnit TextureCoordsUnits[_RGL_MAX_TEXTURE_COORDS]; - jsTextureCoordsUnit* CurrentCoordsUnit; - jsTexture *VertexTextureImages[_RGL_MAX_VERTEX_TEXTURE_IMAGE_UNITS]; - GLsizei packAlignment; - GLsizei unpackAlignment; - jsTexNameSpace bufferObjectNameSpace; - GLuint ArrayBuffer; - GLuint PixelUnpackBuffer; - GLuint TextureBuffer; - GLuint framebuffer; - jsTexNameSpace framebufferNameSpace; - GLboolean VertexProgram; - struct _CGprogram* BoundVertexProgram; - GLboolean FragmentProgram; - struct _CGprogram* BoundFragmentProgram; - GLboolean AllowTXPDemotion; - GLboolean VSync; - GLuint needValidate; - GLboolean everAttached; - CGerror RGLcgLastError; - CGerrorCallbackFunc RGLcgErrorCallbackFunction; - CGcontext RGLcgContextHead; - jsNameSpace cgContextNameSpace; - jsNameSpace cgProgramNameSpace; - jsNameSpace cgParameterNameSpace; - }; +struct PSGLcontext +{ + GLenum error; + int MatrixMode; + jsMatrixStack ModelViewMatrixStack; + jsMatrixStack ProjectionMatrixStack; + GLfloat LocalToScreenMatrixf[ELEMENTS_IN_MATRIX]; + GLfloat InverseModelViewMatrixf[ELEMENTS_IN_MATRIX]; + GLboolean InverseModelViewValid; + GLfloat ScalingFactor; + jsViewPort ViewPort; + jsAttributeState defaultAttribs0; + jsAttributeState *attribs; + jsTexNameSpace attribSetNameSpace; + GLuint attribSetName; + GLboolean attribSetDirty; + jsColorRGBAf ClearColor; + jsColorRGBAf AccumClearColor; + GLboolean ShaderSRGBRemap; + GLboolean Blending; + GLboolean BlendingMrt[3]; + GLenum BlendEquationRGB; + GLenum BlendEquationAlpha; + GLenum BlendFactorSrcRGB; + GLenum BlendFactorDestRGB; + GLenum BlendFactorSrcAlpha; + GLenum BlendFactorDestAlpha; + jsColorRGBAf BlendColor; + GLboolean Dithering; + jsTexNameSpace textureNameSpace; + GLuint ActiveTexture; + GLuint CS_ActiveTexture; + jsTextureImageUnit TextureImageUnits[_RGL_MAX_TEXTURE_IMAGE_UNITS]; + jsTextureImageUnit* CurrentImageUnit; + jsTextureCoordsUnit TextureCoordsUnits[_RGL_MAX_TEXTURE_COORDS]; + jsTextureCoordsUnit* CurrentCoordsUnit; + jsTexture *VertexTextureImages[_RGL_MAX_VERTEX_TEXTURE_IMAGE_UNITS]; + GLsizei packAlignment; + GLsizei unpackAlignment; + jsTexNameSpace bufferObjectNameSpace; + GLuint ArrayBuffer; + GLuint PixelUnpackBuffer; + GLuint TextureBuffer; + GLuint framebuffer; + jsTexNameSpace framebufferNameSpace; + GLboolean VertexProgram; + struct _CGprogram* BoundVertexProgram; + GLboolean FragmentProgram; + struct _CGprogram* BoundFragmentProgram; + GLboolean AllowTXPDemotion; + GLboolean VSync; + GLuint needValidate; + GLboolean everAttached; + CGerror RGLcgLastError; + CGerrorCallbackFunc RGLcgErrorCallbackFunction; + CGcontext RGLcgContextHead; + jsNameSpace cgContextNameSpace; + jsNameSpace cgProgramNameSpace; + jsNameSpace cgParameterNameSpace; +}; #define jsContextGetMatrixStack(mContext, mMatrixMode, mMatrixStack) do \ {\ @@ -633,74 +619,73 @@ typedef struct #define _RGL_ALLOC_FIRST_FIT 0 #define _RGL_ALLOC_BEST_FIT 1 - static inline float _RGLClampf( const float value ) - { - return MAX( MIN( value, 1.f ), 0.f ); - } +static inline float _RGLClampf( const float value ) +{ + return MAX( MIN( value, 1.f ), 0.f ); +} - static inline unsigned int endianSwapWord( unsigned int v ) - { - return ( v&0xff ) << 24 | ( v&0xff00 ) << 8 | - ( v&0xff0000 ) >> 8 | ( v&0xff000000 ) >> 24; - } +static inline unsigned int endianSwapWord( unsigned int v ) +{ + return ( v&0xff ) << 24 | ( v&0xff00 ) << 8 | + ( v&0xff0000 ) >> 8 | ( v&0xff000000 ) >> 24; +} - static inline int _RGLLog2( unsigned int i ) - { - int l = 0; - while ( i ) - { - ++l; - i >>= 1; - } - return l -1; - } +static inline int _RGLLog2( unsigned int i ) +{ + int l = 0; + while ( i ) + { + ++l; + i >>= 1; + } + return l -1; +} - static inline unsigned long _RGLPad( unsigned long x, unsigned long pad ) - { - return ( x + pad - 1 ) / pad*pad; - } +static inline unsigned long _RGLPad( unsigned long x, unsigned long pad ) +{ + return ( x + pad - 1 ) / pad*pad; +} - static inline char* _RGLPadPtr( const char* p, unsigned int pad ) - { - RGLintptr x = ( RGLintptr )p; - x = ( x + pad - 1 ) / pad * pad; - return ( char* )x; - } +static inline char* _RGLPadPtr( const char* p, unsigned int pad ) +{ + RGLintptr x = ( RGLintptr )p; + x = ( x + pad - 1 ) / pad * pad; + return ( char* )x; +} - typedef struct MemoryBlockManager_t_ - { - char *memory; - GLuint size; - GLuint minAlignment; - GLenum method; - GLuint *book; - GLint bookSize; - GLint bookAlloc; - } - MemoryBlockManager_t; +typedef struct MemoryBlockManager_t_ +{ + char *memory; + GLuint size; + GLuint minAlignment; + GLenum method; + GLuint *book; + GLint bookSize; + GLint bookAlloc; +} MemoryBlockManager_t; +typedef unsigned long jsName; - typedef unsigned long jsName; +void _RGLInitNameSpace( struct jsNameSpace * name ); +void _RGLFreeNameSpace( struct jsNameSpace * name ); +jsName _RGLCreateName( struct jsNameSpace * ns, void* object ); +unsigned int _RGLIsName( struct jsNameSpace* ns, jsName name ); +void _RGLEraseName( struct jsNameSpace* ns, jsName name ); - void _RGLInitNameSpace( struct jsNameSpace * name ); - void _RGLFreeNameSpace( struct jsNameSpace * name ); - jsName _RGLCreateName( struct jsNameSpace * ns, void* object ); - unsigned int _RGLIsName( struct jsNameSpace* ns, jsName name ); - void _RGLEraseName( struct jsNameSpace* ns, jsName name ); - static inline void * _RGLGetNamedValue( struct jsNameSpace* ns, jsName name ) - { - return ns->data[name - 1]; - } +static inline void * _RGLGetNamedValue( struct jsNameSpace* ns, jsName name ) +{ + return ns->data[name - 1]; +} - void _RGLTexNameSpaceInit( jsTexNameSpace *ns, jsTexNameSpaceCreateFunction create, jsTexNameSpaceDestroyFunction destroy ); - void _RGLTexNameSpaceFree( jsTexNameSpace *ns ); - void _RGLTexNameSpaceResetNames( jsTexNameSpace *ns ); - GLuint _RGLTexNameSpaceGetFree( jsTexNameSpace *ns ); - GLboolean _RGLTexNameSpaceCreateNameLazy( jsTexNameSpace *ns, GLuint name ); - GLboolean _RGLTexNameSpaceIsName( jsTexNameSpace *ns, GLuint name ); - void _RGLTexNameSpaceGenNames( jsTexNameSpace *ns, GLsizei n, GLuint *names ); - void _RGLTexNameSpaceDeleteNames( jsTexNameSpace *ns, GLsizei n, const GLuint *names ); - void _RGLTexNameSpaceReinit( jsTexNameSpace * saved, jsTexNameSpace * active ); +void _RGLTexNameSpaceInit( jsTexNameSpace *ns, jsTexNameSpaceCreateFunction create, jsTexNameSpaceDestroyFunction destroy ); +void _RGLTexNameSpaceFree( jsTexNameSpace *ns ); +void _RGLTexNameSpaceResetNames( jsTexNameSpace *ns ); +GLuint _RGLTexNameSpaceGetFree( jsTexNameSpace *ns ); +GLboolean _RGLTexNameSpaceCreateNameLazy( jsTexNameSpace *ns, GLuint name ); +GLboolean _RGLTexNameSpaceIsName( jsTexNameSpace *ns, GLuint name ); +void _RGLTexNameSpaceGenNames( jsTexNameSpace *ns, GLsizei n, GLuint *names ); +void _RGLTexNameSpaceDeleteNames( jsTexNameSpace *ns, GLsizei n, const GLuint *names ); +void _RGLTexNameSpaceReinit( jsTexNameSpace * saved, jsTexNameSpace * active ); #define RGL_MEMORY_ALLOC_ERROR 0 @@ -738,62 +723,63 @@ typedef struct typedef struct GmmFixedAllocData { - char **ppBlockList[2]; - uint16_t **ppFreeBlockList[2]; - uint16_t *pBlocksUsed[2]; - uint16_t BlockListCount[2]; -}GmmFixedAllocData; + char **ppBlockList[2]; + uint16_t **ppFreeBlockList[2]; + uint16_t *pBlocksUsed[2]; + uint16_t BlockListCount[2]; +} GmmFixedAllocData; typedef struct GmmBaseBlock { - uint8_t isTile; - uint8_t isMain; - uint32_t address; - uint32_t size; -}GmmBaseBlock; + uint8_t isTile; + uint8_t isMain; + uint32_t address; + uint32_t size; +} GmmBaseBlock; typedef struct GmmBlock { - GmmBaseBlock base; - struct GmmBlock *pPrev; - struct GmmBlock *pNext; - uint8_t isPinned; - struct GmmBlock *pPrevFree; - struct GmmBlock *pNextFree; - uint32_t fence; -}GmmBlock; + GmmBaseBlock base; + struct GmmBlock *pPrev; + struct GmmBlock *pNext; + uint8_t isPinned; + struct GmmBlock *pPrevFree; + struct GmmBlock *pNextFree; + uint32_t fence; +} GmmBlock; typedef struct GmmTileBlock { - GmmBaseBlock base; - struct GmmTileBlock *pPrev; - struct GmmTileBlock *pNext; + GmmBaseBlock base; + struct GmmTileBlock *pPrev; + struct GmmTileBlock *pNext; - uint32_t tileTag; - void *pData; -}GmmTileBlock; + uint32_t tileTag; + void *pData; +} GmmTileBlock; -typedef struct GmmAllocator{ - uint32_t memoryBase; +typedef struct GmmAllocator +{ + uint32_t memoryBase; - uint32_t startAddress; - uint32_t size; - uint32_t freeAddress; + uint32_t startAddress; + uint32_t size; + uint32_t freeAddress; - GmmBlock *pHead; - GmmBlock *pTail; - GmmBlock *pSweepHead; - uint32_t freedSinceSweep; - uint32_t tileStartAddress; - uint32_t tileSize; - GmmTileBlock *pTileHead; - GmmTileBlock *pTileTail; - GmmBlock *pPendingFreeHead; - GmmBlock *pPendingFreeTail; - GmmBlock *pFreeHead[GMM_NUM_FREE_BINS]; - GmmBlock *pFreeTail[GMM_NUM_FREE_BINS]; - uint32_t totalSize; -}GmmAllocator; + GmmBlock *pHead; + GmmBlock *pTail; + GmmBlock *pSweepHead; + uint32_t freedSinceSweep; + uint32_t tileStartAddress; + uint32_t tileSize; + GmmTileBlock *pTileHead; + GmmTileBlock *pTileTail; + GmmBlock *pPendingFreeHead; + GmmBlock *pPendingFreeTail; + GmmBlock *pFreeHead[GMM_NUM_FREE_BINS]; + GmmBlock *pFreeTail[GMM_NUM_FREE_BINS]; + uint32_t totalSize; +} GmmAllocator; uint32_t gmmInit( const void *localMemoryBase, @@ -865,73 +851,73 @@ void gmmSetTileAttrib( typedef struct PSGLinitOptions { - GLuint enable; - int errorConsole; - GLuint fifoSize; - GLuint hostMemorySize; + GLuint enable; + int errorConsole; + GLuint fifoSize; + GLuint hostMemorySize; } PSGLinitOptions; struct RGLSemaphore { - GLuint val; - GLuint pad0; - GLuint pad1; - GLuint pad2; + GLuint val; + GLuint pad0; + GLuint pad1; + GLuint pad2; }; struct RGLSemaphoreMemory { - RGLSemaphore userSemaphores[256]; + RGLSemaphore userSemaphores[256]; }; struct RGLResource { - char *localAddress; - GLuint localSize; - GLuint MemoryClock; - GLuint GraphicsClock; - char * hostMemoryBase; - GLuint hostMemorySize; - GLuint hostMemoryReserved; - unsigned long dmaPushBufferOffset; - char * dmaPushBuffer; - GLuint dmaPushBufferSize; - void* dmaControl; - RGLSemaphoreMemory *semaphores; + char *localAddress; + GLuint localSize; + GLuint MemoryClock; + GLuint GraphicsClock; + char * hostMemoryBase; + GLuint hostMemorySize; + GLuint hostMemoryReserved; + unsigned long dmaPushBufferOffset; + char * dmaPushBuffer; + GLuint dmaPushBufferSize; + void* dmaControl; + RGLSemaphoreMemory *semaphores; }; typedef volatile struct { - GLuint Ignored00[0x010]; - GLuint Put; - GLuint Get; - GLuint Reference; - GLuint Ignored01[0x1]; - GLuint SetReference; - GLuint TopLevelGet; - GLuint Ignored02[0x2]; - GLuint SetContextDmaSemaphore; - GLuint SetSemaphoreOffset; - GLuint SetSemaphoreAcquire; - GLuint SetSemaphoreRelease; - GLuint Ignored03[0x7e4]; + GLuint Ignored00[0x010]; + GLuint Put; + GLuint Get; + GLuint Reference; + GLuint Ignored01[0x1]; + GLuint SetReference; + GLuint TopLevelGet; + GLuint Ignored02[0x2]; + GLuint SetContextDmaSemaphore; + GLuint SetSemaphoreOffset; + GLuint SetSemaphoreAcquire; + GLuint SetSemaphoreRelease; + GLuint Ignored03[0x7e4]; } RGLControlDma; struct RGLFifo: public CellGcmContextData { - RGLControlDma *dmaControl; - uint32_t *dmaPushBufferBegin; - uint32_t *dmaPushBufferEnd; - GLuint fifoBlockSize; - unsigned long dmaPushBufferOffset; - GLuint dmaPushBufferSizeInWords; - uint32_t *lastPutWritten; - uint32_t *lastGetRead; - GLuint lastSWReferenceWritten; - GLuint lastSWReferenceFlushed; - GLuint lastHWReferenceRead; - uint32_t *dmaPushBufferGPU; - int spuid; + RGLControlDma *dmaControl; + uint32_t *dmaPushBufferBegin; + uint32_t *dmaPushBufferEnd; + GLuint fifoBlockSize; + unsigned long dmaPushBufferOffset; + GLuint dmaPushBufferSizeInWords; + uint32_t *lastPutWritten; + uint32_t *lastGetRead; + GLuint lastSWReferenceWritten; + GLuint lastSWReferenceFlushed; + GLuint lastHWReferenceRead; + uint32_t *dmaPushBufferGPU; + int spuid; }; typedef struct RGLRenderTarget RGLRenderTarget; @@ -941,44 +927,42 @@ typedef struct RGLInterpolantState RGLInterpolantState; struct RGLInterpolantState { - GLuint vertexProgramAttribMask; - GLuint fragmentProgramAttribMask; + GLuint vertexProgramAttribMask; + GLuint fragmentProgramAttribMask; }; struct RGLBlendState { - GLuint alphaFunc; - GLfloat alphaRef; + GLuint alphaFunc; + GLfloat alphaRef; }; struct RGLRenderTarget { - GLuint colorFormat; - GLuint colorBufferCount; - - GLuint yInverted; - - CellGcmSurface gcmRenderTarget; + GLuint colorFormat; + GLuint colorBufferCount; + GLuint yInverted; + CellGcmSurface gcmRenderTarget; }; struct RGLCachedState { - RGLBlendState blend; - RGLViewportState viewport; - RGLInterpolantState interpolant; + RGLBlendState blend; + RGLViewportState viewport; + RGLInterpolantState interpolant; }; struct RGLState { - char *localAddress; - void *hostMemoryBase; - GLuint hostMemorySize; - RGLSemaphoreMemory *semaphores; - RGLFifo fifo; - RGLRenderTarget renderTarget; - RGLCachedState state; - CellGcmConfig config; - GLuint labelValue; + char *localAddress; + void *hostMemoryBase; + GLuint hostMemorySize; + RGLSemaphoreMemory *semaphores; + RGLFifo fifo; + RGLRenderTarget renderTarget; + RGLCachedState state; + CellGcmConfig config; + GLuint labelValue; }; GLboolean _RGLInit( PSGLinitOptions* options, RGLResource *resource ); @@ -991,99 +975,101 @@ void _RGLIncFenceRef( GLuint* ref ); typedef struct { - GLenum pool; - unsigned int bufferId; - unsigned int bufferSize; - unsigned int pitch; + GLenum pool; + unsigned int bufferId; + unsigned int bufferSize; + unsigned int pitch; - GLuint mapCount; - GLenum mapAccess; + GLuint mapCount; + GLenum mapAccess; } RGLBufferObject; void _RGLSetNativeCgVertexProgram( const void *header ); void _RGLSetNativeCgFragmentProgram( const void *header ); - GLboolean _RGLTryResizeTileRegion( GLuint address, GLuint size, void* data ); - void _RGLGetTileRegionInfo( void* data, GLuint *address, GLuint *size ); +GLboolean _RGLTryResizeTileRegion( GLuint address, GLuint size, void* data ); +void _RGLGetTileRegionInfo( void* data, GLuint *address, GLuint *size ); - static inline GLuint _RGLPlatformGetBitsPerPixel( GLenum internalFormat ) - { - switch ( internalFormat ) - { - case RGL_HILO8: - case RGL_RGB5_A1_SCE: - case RGL_RGB565_SCE: - return 16; - case RGL_ALPHA8: - return 8; - case RGL_RGBX8: - case RGL_RGBA8: - case RGL_ABGR8: - case RGL_ARGB8: - case RGL_BGRA8: - return 32; - default: - return 0; - } - } +static inline GLuint _RGLPlatformGetBitsPerPixel( GLenum internalFormat ) +{ + switch ( internalFormat ) + { + case RGL_HILO8: + case RGL_RGB5_A1_SCE: + case RGL_RGB565_SCE: + return 16; + case RGL_ALPHA8: + return 8; + case RGL_RGBX8: + case RGL_RGBA8: + case RGL_ABGR8: + case RGL_ARGB8: + case RGL_BGRA8: + return 32; + default: + return 0; + } +} - void static inline _RGLFifoGlViewport( GLint x, GLint y, GLsizei width, GLsizei height, GLclampf zNear = 0.0f, GLclampf zFar = 1.0f ) - { - RGLViewportState *vp = &_RGLState.state.viewport; - RGLRenderTarget *rt = &_RGLState.renderTarget; - GLint clipX0, clipX1, clipY0, clipY1; +void static inline _RGLFifoGlViewport( GLint x, GLint y, GLsizei width, GLsizei height, GLclampf zNear = 0.0f, GLclampf zFar = 1.0f ) +{ + RGLViewportState *vp = &_RGLState.state.viewport; + RGLRenderTarget *rt = &_RGLState.renderTarget; + GLint clipX0, clipX1, clipY0, clipY1; - vp->x = x; - vp->y = y; - vp->w = width; - vp->h = height; + vp->x = x; + vp->y = y; + vp->w = width; + vp->h = height; - clipX0 = x; - clipX1 = x + width; - clipY0 = y; - clipY1 = y + height; + clipX0 = x; + clipX1 = x + width; + clipY0 = y; + clipY1 = y + height; - if ( rt->yInverted ) - { - clipY0 = rt->gcmRenderTarget.height - ( y + height ); - clipY1 = rt->gcmRenderTarget.height - y; - } + if ( rt->yInverted ) + { + clipY0 = rt->gcmRenderTarget.height - ( y + height ); + clipY1 = rt->gcmRenderTarget.height - y; + } - if ( clipX0 < 0 ) - clipX0 = 0; + if ( clipX0 < 0 ) + clipX0 = 0; - if ( clipY0 < 0 ) - clipY0 = 0; + if ( clipY0 < 0 ) + clipY0 = 0; - if ( clipX1 >= CELL_GCM_MAX_RT_DIMENSION ) - clipX1 = CELL_GCM_MAX_RT_DIMENSION; + if ( clipX1 >= CELL_GCM_MAX_RT_DIMENSION ) + clipX1 = CELL_GCM_MAX_RT_DIMENSION; - if ( clipY1 >= CELL_GCM_MAX_RT_DIMENSION ) - clipY1 = CELL_GCM_MAX_RT_DIMENSION; + if ( clipY1 >= CELL_GCM_MAX_RT_DIMENSION ) + clipY1 = CELL_GCM_MAX_RT_DIMENSION; - if (( clipX1 <= clipX0 ) || ( clipY1 <= clipY0 ) ) - clipX0 = clipY0 = clipX1 = clipY1 = 0; + if (( clipX1 <= clipX0 ) || ( clipY1 <= clipY0 ) ) + clipX0 = clipY0 = clipX1 = clipY1 = 0; - vp->xScale = width * 0.5f; - vp->xCenter = ( GLfloat )( x + vp->xScale + RGL_SUBPIXEL_ADJUST ); - if ( rt->yInverted ) - { - vp->yScale = height * -0.5f; - vp->yCenter = ( GLfloat )( rt->gcmRenderTarget.height - RGL_VIEWPORT_EPSILON - y + vp->yScale + RGL_SUBPIXEL_ADJUST ); - } - else - { - vp->yScale = height * 0.5f; - vp->yCenter = ( GLfloat )( y + vp->yScale + RGL_SUBPIXEL_ADJUST ); - } + vp->xScale = width * 0.5f; + vp->xCenter = ( GLfloat )( x + vp->xScale + RGL_SUBPIXEL_ADJUST ); + vp->yScale = height; - float scale[4] = { vp->xScale, vp->yScale, 0.5f, 0.0f }; - float offset[4] = { vp->xCenter, vp->yCenter, 0.5f, 0.0f }; + if ( rt->yInverted ) + { + vp->yScale *= -0.5f; + vp->yCenter = ( GLfloat )( rt->gcmRenderTarget.height - RGL_VIEWPORT_EPSILON - y + vp->yScale + RGL_SUBPIXEL_ADJUST ); + } + else + { + vp->yScale *= 0.5f; + vp->yCenter = ( GLfloat )( y + vp->yScale + RGL_SUBPIXEL_ADJUST ); + } - cellGcmSetViewportInline( &_RGLState.fifo, clipX0, clipY0, clipX1 - clipX0, - clipY1 - clipY0, zNear, zFar, scale, offset ); - } + float scale[4] = { vp->xScale, vp->yScale, 0.5f, 0.0f }; + float offset[4] = { vp->xCenter, vp->yCenter, 0.5f, 0.0f }; + + cellGcmSetViewportInline( &_RGLState.fifo, clipX0, clipY0, clipX1 - clipX0, + clipY1 - clipY0, zNear, zFar, scale, offset ); +} #define PSGL_DEVICE_PARAMETERS_COLOR_FORMAT 0x0001 #define PSGL_DEVICE_PARAMETERS_DEPTH_FORMAT 0x0002 @@ -1103,35 +1089,35 @@ void _RGLSetNativeCgFragmentProgram( const void *header ); #define PSGL_VALIDATE_FRAMEBUFFER 0x00000001 #define PSGL_VALIDATE_TEXTURES_USED 0x00000002 #define PSGL_VALIDATE_VERTEX_PROGRAM 0x00000004 -#define PSGL_VALIDATE_VERTEX_CONSTANTS 0x00000008 -#define PSGL_VALIDATE_VERTEX_TEXTURES_USED 0x00000010 -#define PSGL_VALIDATE_FFX_VERTEX_PROGRAM 0x00000020 -#define PSGL_VALIDATE_FRAGMENT_PROGRAM 0x00000040 -#define PSGL_VALIDATE_FFX_FRAGMENT_PROGRAM 0x00000080 -#define PSGL_VALIDATE_VIEWPORT 0x00000200 -#define PSGL_VALIDATE_FACE_CULL 0x00010000 -#define PSGL_VALIDATE_BLENDING 0x00020000 -#define PSGL_VALIDATE_POINT_RASTER 0x00040000 -#define PSGL_VALIDATE_LINE_RASTER 0x00080000 -#define PSGL_VALIDATE_POLYGON_OFFSET 0x00100000 -#define PSGL_VALIDATE_SHADE_MODEL 0x00200000 -#define PSGL_VALIDATE_LOGIC_OP 0x00400000 -#define PSGL_VALIDATE_MULTISAMPLING 0x00800000 -#define PSGL_VALIDATE_POLYGON_MODE 0x01000000 -#define PSGL_VALIDATE_PRIMITIVE_RESTART 0x02000000 -#define PSGL_VALIDATE_CLIP_PLANES 0x04000000 -#define PSGL_VALIDATE_SHADER_SRGB_REMAP 0x08000000 -#define PSGL_VALIDATE_POINT_SPRITE 0x10000000 -#define PSGL_VALIDATE_TWO_SIDE_COLOR 0x20000000 -#define PSGL_VALIDATE_ALL 0x3FFFFFFF +#define PSGL_VALIDATE_VERTEX_CONSTANTS 0x00000008 +#define PSGL_VALIDATE_VERTEX_TEXTURES_USED 0x00000010 +#define PSGL_VALIDATE_FFX_VERTEX_PROGRAM 0x00000020 +#define PSGL_VALIDATE_FRAGMENT_PROGRAM 0x00000040 +#define PSGL_VALIDATE_FFX_FRAGMENT_PROGRAM 0x00000080 +#define PSGL_VALIDATE_VIEWPORT 0x00000200 +#define PSGL_VALIDATE_FACE_CULL 0x00010000 +#define PSGL_VALIDATE_BLENDING 0x00020000 +#define PSGL_VALIDATE_POINT_RASTER 0x00040000 +#define PSGL_VALIDATE_LINE_RASTER 0x00080000 +#define PSGL_VALIDATE_POLYGON_OFFSET 0x00100000 +#define PSGL_VALIDATE_SHADE_MODEL 0x00200000 +#define PSGL_VALIDATE_LOGIC_OP 0x00400000 +#define PSGL_VALIDATE_MULTISAMPLING 0x00800000 +#define PSGL_VALIDATE_POLYGON_MODE 0x01000000 +#define PSGL_VALIDATE_PRIMITIVE_RESTART 0x02000000 +#define PSGL_VALIDATE_CLIP_PLANES 0x04000000 +#define PSGL_VALIDATE_SHADER_SRGB_REMAP 0x08000000 +#define PSGL_VALIDATE_POINT_SPRITE 0x10000000 +#define PSGL_VALIDATE_TWO_SIDE_COLOR 0x20000000 +#define PSGL_VALIDATE_ALL 0x3FFFFFFF #define PSGL_INIT_PERSISTENT_MEMORY_SIZE 0x0004 -#define PSGL_INIT_TRANSIENT_MEMORY_SIZE 0x0008 +#define PSGL_INIT_TRANSIENT_MEMORY_SIZE 0x0008 #define PSGL_INIT_ERROR_CONSOLE 0x0010 -#define PSGL_INIT_FIFO_SIZE 0x0020 -#define PSGL_INIT_HOST_MEMORY_SIZE 0x0040 -#define PSGL_INIT_USE_PMQUERIES 0x0080 +#define PSGL_INIT_FIFO_SIZE 0x0020 +#define PSGL_INIT_HOST_MEMORY_SIZE 0x0040 +#define PSGL_INIT_USE_PMQUERIES 0x0080 extern void psglInit( PSGLinitOptions* options ); @@ -1152,9 +1138,6 @@ PSGLcontext* psglGetCurrentContext(); PSGLdevice* psglGetCurrentDevice(); void psglSwap( void ); -static inline void psglRescAdjustAspectRatio( const float horizontalScale, const float verticalScale ) - { cellRescAdjustAspectRatio( horizontalScale, verticalScale ); } - #ifdef __cplusplus } #endif diff --git a/ps3/sdk_defines.h b/ps3/sdk_defines.h index 389e79b46b..ad30eee473 100644 --- a/ps3/sdk_defines.h +++ b/ps3/sdk_defines.h @@ -289,6 +289,14 @@ #endif +/*============================================================ + TIMER PROTOTYPES +============================================================ */ + +#ifdef __PSL1GHT__ +#define sys_timer_usleep usleep +#endif + /*============================================================ THREADING PROTOTYPES ============================================================ */ From 3b7da4c0204cc5bd3c497da168663459cb932427 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 23 Jul 2012 14:58:41 +0200 Subject: [PATCH 12/51] (Xbox 1) Add media files to xbox1 dir --- msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj | 20 +++++++++++++++----- xbox1/media/arial.ttf | Bin 0 -> 65692 bytes xbox1/media/menuMainBG.png | Bin 0 -> 6415 bytes xbox1/media/menuMainRomSelectPanel.png | Bin 0 -> 3206 bytes xbox1/media/titleimage.jpg | Bin 0 -> 8865 bytes 5 files changed, 15 insertions(+), 5 deletions(-) create mode 100644 xbox1/media/arial.ttf create mode 100644 xbox1/media/menuMainBG.png create mode 100644 xbox1/media/menuMainRomSelectPanel.png create mode 100644 xbox1/media/titleimage.jpg diff --git a/msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj b/msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj index 463b0679ef..70c05b3e2c 100644 --- a/msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj +++ b/msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj @@ -51,7 +51,9 @@ Name="VCPreLinkEventTool"/> + RemotePath="xe:\$(SolutionName)\CORE.xbe" + AdditionalFiles="..\..\xbox1\Media;roms;system" + ForceCopy="TRUE"/> + RemotePath="xe:\$(SolutionName)\CORE.xbe" + AdditionalFiles="..\..\xbox1\Media;roms;system" + ForceCopy="TRUE"/> + RemotePath="xe:\$(SolutionName)\CORE.xbe" + AdditionalFiles="..\..\xbox1\Media;roms;system" + ForceCopy="TRUE"/> + RemotePath="xe:\$(SolutionName)\CORE.xbe" + AdditionalFiles="..\..\xbox1\Media;roms;system" + ForceCopy="TRUE"/> @@ -265,7 +273,9 @@ Name="VCPreLinkEventTool"/> + RemotePath="xe:\$(SolutionName)\CORE.xbe" + AdditionalFiles="..\..\xbox1\Media;roms;system" + ForceCopy="TRUE"/> diff --git a/xbox1/media/arial.ttf b/xbox1/media/arial.ttf new file mode 100644 index 0000000000000000000000000000000000000000..25769bbf1b0751c727fcab04da0f84fa517ec61f GIT binary patch literal 65692 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 literal 0 HcmV?d00001 diff --git a/xbox1/media/menuMainBG.png b/xbox1/media/menuMainBG.png new file mode 100644 index 0000000000000000000000000000000000000000..8e6d54eee7e13d6a95fe8586631affe6465d3fd6 GIT binary patch literal 6415 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 literal 0 HcmV?d00001 diff --git a/xbox1/media/menuMainRomSelectPanel.png b/xbox1/media/menuMainRomSelectPanel.png new file mode 100644 index 0000000000000000000000000000000000000000..377a9bae5bce8227d0721fbc9a73919b824d9c21 GIT binary patch literal 3206 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 V33Da-#&v;nGt@QHse(B^`!_dA#9jaZ literal 0 HcmV?d00001 diff --git a/xbox1/media/titleimage.jpg b/xbox1/media/titleimage.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1b0bc9586da2660ba3f1cd09fb18ce5ebd01f6c8 GIT binary patch literal 8865 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 O-z~}huk$g?&;J2#&AQP5 literal 0 HcmV?d00001 From cecc7613db8f85a216f07a2dc682746b55daff93 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Mon, 23 Jul 2012 14:49:33 +0200 Subject: [PATCH 13/51] (Xbox 1) Add system and roms dir --- msvc/RetroArch-Xbox1/roms/.empty | 0 msvc/RetroArch-Xbox1/system/.empty | 0 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 msvc/RetroArch-Xbox1/roms/.empty create mode 100644 msvc/RetroArch-Xbox1/system/.empty diff --git a/msvc/RetroArch-Xbox1/roms/.empty b/msvc/RetroArch-Xbox1/roms/.empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/msvc/RetroArch-Xbox1/system/.empty b/msvc/RetroArch-Xbox1/system/.empty new file mode 100644 index 0000000000..e69de29bb2 From baa25cdaa28eaa3fe254f14f18742d852fafb006 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 23 Jul 2012 15:11:15 +0200 Subject: [PATCH 14/51] (Xbox 1) Included RetroLaunch into the solution - not yet working though --- msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj | 50 ++++++++++++-- xbox1/RetroLaunch/Launcher.cpp | 72 --------------------- xbox1/RetroLaunch/Video.h | 1 + xdk/frontend/main.c | 58 ++++++++++++++++- 4 files changed, 103 insertions(+), 78 deletions(-) diff --git a/msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj b/msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj index 70c05b3e2c..2bf7de34f7 100644 --- a/msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj +++ b/msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj @@ -327,33 +327,73 @@ Name="Debug|Xbox"> + CompileAs="1"/> + CompileAs="1"/> + CompileAs="1"/> + CompileAs="1"/> + CompileAs="1"/> + + + + + + + + + + + + + + + + + + + + + + + + + + Main Menu) - g_menuManager.Create(); - - // Loop the app - while (!g_bExit) - { - g_video.BeginRender(); - g_input.GetInput(); - g_menuManager.Update(); - g_video.EndRender(); - } -} diff --git a/xbox1/RetroLaunch/Video.h b/xbox1/RetroLaunch/Video.h index 500a2d205b..451ef8067e 100644 --- a/xbox1/RetroLaunch/Video.h +++ b/xbox1/RetroLaunch/Video.h @@ -17,6 +17,7 @@ #include "Global.h" +#undef D3DFVF_CUSTOMVERTEX #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1) typedef struct CustomVertex diff --git a/xdk/frontend/main.c b/xdk/frontend/main.c index fc6b40646c..a0e627b8a7 100644 --- a/xdk/frontend/main.c +++ b/xdk/frontend/main.c @@ -166,11 +166,67 @@ static void configure_libretro(const char *path_prefix, const char * extension) } #ifdef _XBOX1 -static void menu_init(void) {} +#include "../../xbox1/RetroLaunch/Global.h" +#include "../../xbox1/RetroLaunch/Video.h" +#include "../../xbox1/RetroLaunch/IniFile.h" +#include "../../xbox1/RetroLaunch/IoSupport.h" +#include "../../xbox1/RetroLaunch/Input.h" +#include "../../xbox1/RetroLaunch/Debug.h" +#include "../../xbox1/RetroLaunch/Font.h" +#include "../../xbox1/RetroLaunch/MenuManager.h" +#include "../../xbox1/RetroLaunch/RomList.h" + +bool g_bExit = false; + +static void menu_init(void) +{ + //g_debug.Print("Starting RetroLaunch\n"); + + //// Set file cache size + //XSetFileCacheSize(8 * 1024 * 1024); + + //// Mount drives + //g_IOSupport.Mount("A:", "cdrom0"); + //g_IOSupport.Mount("E:", "Harddisk0\\Partition1"); + //g_IOSupport.Mount("Z:", "Harddisk0\\Partition2"); + //g_IOSupport.Mount("F:", "Harddisk0\\Partition6"); + //g_IOSupport.Mount("G:", "Harddisk0\\Partition7"); + + + //// Initialize Direct3D + //if (!g_video.Create(NULL, false)) + // return; + + //// Parse ini file for settings + //g_iniFile.CheckForIniEntry(); + + //// Load the rom list if it isn't already loaded + //if (!g_romList.IsLoaded()) { + // g_romList.Load(); + //} + + //// Init input here + //g_input.Create(); + + //// Load the font here + //g_font.Create(); + + //// Build menu here (Menu state -> Main Menu) + //g_menuManager.Create(); +} + static void menu_free(void) {} static void menu_loop(void) { rarch_console_load_game("D:\\ssf2x.gba"); + // Loop the app + //while (!g_bExit) + //{ + // g_video.BeginRender(); + // g_input.GetInput(); + // g_menuManager.Update(); + // g_video.EndRender(); + //} } #endif From 99b8b40ab2b3924ac912dedc7b921f9c4463da0b Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 23 Jul 2012 15:22:08 +0200 Subject: [PATCH 15/51] (Xbox 1) Rename 'media' folder to 'Media' folder --- xbox1/{media => Media}/arial.ttf | Bin xbox1/{media => Media}/menuMainBG.png | Bin xbox1/{media => Media}/menuMainRomSelectPanel.png | Bin xbox1/{media => Media}/titleimage.jpg | Bin 4 files changed, 0 insertions(+), 0 deletions(-) rename xbox1/{media => Media}/arial.ttf (100%) rename xbox1/{media => Media}/menuMainBG.png (100%) rename xbox1/{media => Media}/menuMainRomSelectPanel.png (100%) rename xbox1/{media => Media}/titleimage.jpg (100%) diff --git a/xbox1/media/arial.ttf b/xbox1/Media/arial.ttf similarity index 100% rename from xbox1/media/arial.ttf rename to xbox1/Media/arial.ttf diff --git a/xbox1/media/menuMainBG.png b/xbox1/Media/menuMainBG.png similarity index 100% rename from xbox1/media/menuMainBG.png rename to xbox1/Media/menuMainBG.png diff --git a/xbox1/media/menuMainRomSelectPanel.png b/xbox1/Media/menuMainRomSelectPanel.png similarity index 100% rename from xbox1/media/menuMainRomSelectPanel.png rename to xbox1/Media/menuMainRomSelectPanel.png diff --git a/xbox1/media/titleimage.jpg b/xbox1/Media/titleimage.jpg similarity index 100% rename from xbox1/media/titleimage.jpg rename to xbox1/Media/titleimage.jpg From 7395c805e6ecb072a8232afeb0a205359cd6e315 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 23 Jul 2012 15:42:31 +0200 Subject: [PATCH 16/51] (Xbox 1) For testing --- xdk/frontend/main.c | 64 ++++++++++++++++++++++----------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/xdk/frontend/main.c b/xdk/frontend/main.c index a0e627b8a7..a3379a964f 100644 --- a/xdk/frontend/main.c +++ b/xdk/frontend/main.c @@ -180,53 +180,53 @@ bool g_bExit = false; static void menu_init(void) { - //g_debug.Print("Starting RetroLaunch\n"); + g_debug.Print("Starting RetroLaunch\n"); - //// Set file cache size - //XSetFileCacheSize(8 * 1024 * 1024); + // Set file cache size + XSetFileCacheSize(8 * 1024 * 1024); - //// Mount drives - //g_IOSupport.Mount("A:", "cdrom0"); - //g_IOSupport.Mount("E:", "Harddisk0\\Partition1"); - //g_IOSupport.Mount("Z:", "Harddisk0\\Partition2"); - //g_IOSupport.Mount("F:", "Harddisk0\\Partition6"); - //g_IOSupport.Mount("G:", "Harddisk0\\Partition7"); + // Mount drives + g_IOSupport.Mount("A:", "cdrom0"); + g_IOSupport.Mount("E:", "Harddisk0\\Partition1"); + g_IOSupport.Mount("Z:", "Harddisk0\\Partition2"); + g_IOSupport.Mount("F:", "Harddisk0\\Partition6"); + g_IOSupport.Mount("G:", "Harddisk0\\Partition7"); - //// Initialize Direct3D - //if (!g_video.Create(NULL, false)) - // return; + // Initialize Direct3D + if (!g_video.Create(NULL, false)) + return; - //// Parse ini file for settings - //g_iniFile.CheckForIniEntry(); + // Parse ini file for settings + g_iniFile.CheckForIniEntry(); - //// Load the rom list if it isn't already loaded - //if (!g_romList.IsLoaded()) { - // g_romList.Load(); - //} + // Load the rom list if it isn't already loaded + if (!g_romList.IsLoaded()) { + g_romList.Load(); + } - //// Init input here - //g_input.Create(); + // Init input here + g_input.Create(); - //// Load the font here - //g_font.Create(); + // Load the font here + g_font.Create(); - //// Build menu here (Menu state -> Main Menu) - //g_menuManager.Create(); + // Build menu here (Menu state -> Main Menu) + g_menuManager.Create(); } static void menu_free(void) {} static void menu_loop(void) { - rarch_console_load_game("D:\\ssf2x.gba"); + //rarch_console_load_game("D:\\ssf2x.gba"); // Loop the app - //while (!g_bExit) - //{ - // g_video.BeginRender(); - // g_input.GetInput(); - // g_menuManager.Update(); - // g_video.EndRender(); - //} + while (!g_bExit) + { + g_video.BeginRender(); + g_input.GetInput(); + g_menuManager.Update(); + g_video.EndRender(); + } } #endif From fe4b07d8b117033dc88315b64ed596648fe7411c Mon Sep 17 00:00:00 2001 From: freakdave Date: Mon, 23 Jul 2012 16:05:16 +0200 Subject: [PATCH 17/51] (Xbox 1) Modified RetroLaunch to use RetroArch's D3D device (!NOT TESTED!) --- xbox1/RetroLaunch/Surface.cpp | 21 +++++++++++---------- xbox1/RetroLaunch/Video.cpp | 9 ++++++++- xbox1/RetroLaunch/Video.h | 6 ++++-- xdk/frontend/main.c | 9 +++++++-- 4 files changed, 30 insertions(+), 15 deletions(-) diff --git a/xbox1/RetroLaunch/Surface.cpp b/xbox1/RetroLaunch/Surface.cpp index e0ac7b8e98..f8718ef968 100644 --- a/xbox1/RetroLaunch/Surface.cpp +++ b/xbox1/RetroLaunch/Surface.cpp @@ -17,6 +17,7 @@ #include "Surface.h" #include "Debug.h" +#include "../xdk_d3d8.h" CSurface::CSurface() { @@ -68,7 +69,7 @@ bool CSurface::Create(const string &szFilename) } // create a vertex buffer for the quad that will display the texture - g_hResult = g_video.m_pD3DDevice->CreateVertexBuffer(4 * sizeof(CustomVertex), + g_hResult = g_video.m_pD3DDevice->CreateVertexBuffer(4 * sizeof(DrawVerticeFormats), D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEX, D3DPOOL_MANAGED, &m_pVertexBuffer); @@ -104,7 +105,7 @@ bool CSurface::Create(dword width, dword height) m_imageInfo.Format = D3DFMT_A8R8G8B8; // create a vertex buffer for the quad that will display the texture - g_hResult = g_video.m_pD3DDevice->CreateVertexBuffer(4 * sizeof(CustomVertex), + g_hResult = g_video.m_pD3DDevice->CreateVertexBuffer(4 * sizeof(DrawVerticeFormats), D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEX, D3DPOOL_MANAGED, &m_pVertexBuffer); @@ -163,17 +164,17 @@ bool CSurface::Render(int x, int y, dword w, dword h) float fY = static_cast(y); // create the new vertices - CustomVertex newVerts[] = + /*CustomVertex*/DrawVerticeFormats newVerts[] = { // x, y, z, color, u ,v - {fX, fY, 0.0f, D3DCOLOR_ARGB(m_byOpacity, m_byR, m_byG, m_byB), 0, 0}, - {fX + w, fY, 0.0f, D3DCOLOR_ARGB(m_byOpacity, m_byR, m_byG, m_byB), 1, 0}, - {fX + w, fY + h, 0.0f, D3DCOLOR_ARGB(m_byOpacity, m_byR, m_byG, m_byB), 1, 1}, - {fX, fY + h, 0.0f, D3DCOLOR_ARGB(m_byOpacity, m_byR, m_byG, m_byB), 0, 1} + {fX, fY, 0.0f, /*D3DCOLOR_ARGB(m_byOpacity, m_byR, m_byG, m_byB),*/ 0, 0}, + {fX + w, fY, 0.0f, /*D3DCOLOR_ARGB(m_byOpacity, m_byR, m_byG, m_byB),*/ 1, 0}, + {fX + w, fY + h, 0.0f, /*D3DCOLOR_ARGB(m_byOpacity, m_byR, m_byG, m_byB),*/ 1, 1}, + {fX, fY + h, 0.0f, /*D3DCOLOR_ARGB(m_byOpacity, m_byR, m_byG, m_byB),*/ 0, 1} }; // load the existing vertices - CustomVertex *pCurVerts; + /*CustomVertex*/DrawVerticeFormats *pCurVerts; g_hResult = m_pVertexBuffer->Lock(0, 0, (byte **)&pCurVerts, 0); @@ -183,7 +184,7 @@ bool CSurface::Render(int x, int y, dword w, dword h) return false; } // copy the new verts over the old verts - memcpy(pCurVerts, newVerts, 4 * sizeof(CustomVertex)); + memcpy(pCurVerts, newVerts, 4 * sizeof(DrawVerticeFormats)); m_pVertexBuffer->Unlock(); @@ -199,7 +200,7 @@ bool CSurface::Render(int x, int y, dword w, dword h) // draw the quad g_video.m_pD3DDevice->SetTexture(0, m_pTexture); - g_video.m_pD3DDevice->SetStreamSource(0, m_pVertexBuffer, sizeof(CustomVertex)); + g_video.m_pD3DDevice->SetStreamSource(0, m_pVertexBuffer, sizeof(DrawVerticeFormats)); g_video.m_pD3DDevice->SetVertexShader(D3DFVF_CUSTOMVERTEX); g_video.m_pD3DDevice->DrawPrimitive(D3DPT_QUADLIST, 0, 1); return true; diff --git a/xbox1/RetroLaunch/Video.cpp b/xbox1/RetroLaunch/Video.cpp index 28d5ba67fc..35f3c403bc 100644 --- a/xbox1/RetroLaunch/Video.cpp +++ b/xbox1/RetroLaunch/Video.cpp @@ -29,8 +29,15 @@ CVideo::~CVideo(void) { } +bool CVideo::SetDevice(IDirect3DDevice8 *D3D_Device) +{ + m_pD3DDevice = D3D_Device; + return true; +} + bool CVideo::Create(HWND hDeviceWindow, bool bWindowed) { + /* // Create the Direct3D object (leave it DX8 or should we try DX9 for WIN32 ?) m_pD3D = Direct3DCreate8(D3D_SDK_VERSION); @@ -85,7 +92,7 @@ bool CVideo::Create(HWND hDeviceWindow, bool bWindowed) // disable z-buffer (see autodepthstencil) m_pD3DDevice->SetRenderState(D3DRS_ZENABLE, FALSE ); - +*/ return true; } diff --git a/xbox1/RetroLaunch/Video.h b/xbox1/RetroLaunch/Video.h index 451ef8067e..fc9c80e155 100644 --- a/xbox1/RetroLaunch/Video.h +++ b/xbox1/RetroLaunch/Video.h @@ -18,8 +18,9 @@ #include "Global.h" #undef D3DFVF_CUSTOMVERTEX -#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1) +//#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1) +/* typedef struct CustomVertex { float x, y, z; @@ -27,7 +28,7 @@ typedef struct CustomVertex float u, v; //float rhw; }CustomVertex; - +*/ class CVideo { @@ -36,6 +37,7 @@ public: ~CVideo(void); bool Create(HWND hDeviceWindow, bool bWindowed); //Device creation + bool SetDevice(IDirect3DDevice8 *D3D_Device); void BeginRender(); void EndRender(); diff --git a/xdk/frontend/main.c b/xdk/frontend/main.c index a3379a964f..ef0cfc2d95 100644 --- a/xdk/frontend/main.c +++ b/xdk/frontend/main.c @@ -192,10 +192,15 @@ static void menu_init(void) g_IOSupport.Mount("F:", "Harddisk0\\Partition6"); g_IOSupport.Mount("G:", "Harddisk0\\Partition7"); + // Get RetroArch's native d3d device + xdk_d3d_video_t *d3d = (xdk_d3d_video_t*)driver.video_data; // Initialize Direct3D - if (!g_video.Create(NULL, false)) - return; + //if (!g_video.Create(NULL, false)) + //return; + + if(!g_video.SetDevice(d3d->d3d_render_device)) + return; // Parse ini file for settings g_iniFile.CheckForIniEntry(); From 2f51da40342bdc0ac8b98e57be4b208ad4bb138d Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 23 Jul 2012 16:38:29 +0200 Subject: [PATCH 18/51] (Xbox 1) Remove Video.cpp from RetroLaunch - still black --- msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj | 6 - xbox1/RetroLaunch/Font.cpp | 8 +- xbox1/RetroLaunch/Launcher.cpp | 0 xbox1/RetroLaunch/Surface.cpp | 35 +++--- xbox1/RetroLaunch/Surface.h | 1 - xbox1/RetroLaunch/Video.cpp | 126 -------------------- xbox1/RetroLaunch/Video.h | 56 --------- xdk/frontend/main.c | 26 ++-- 8 files changed, 40 insertions(+), 218 deletions(-) delete mode 100644 xbox1/RetroLaunch/Launcher.cpp delete mode 100644 xbox1/RetroLaunch/Video.cpp delete mode 100644 xbox1/RetroLaunch/Video.h diff --git a/msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj b/msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj index 2bf7de34f7..969ec5feee 100644 --- a/msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj +++ b/msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj @@ -372,9 +372,6 @@ - - @@ -390,9 +387,6 @@ - - +#include "../../general.h" +#include "../xdk_d3d8.h" Font g_font; @@ -43,7 +44,7 @@ bool Font::Create(const string &szTTFFilename) m_pFont->Release(); word *wcPathBuf = StringToWChar(szTTFFilename); - g_hResult = XFONT_OpenTrueTypeFont(wcPathBuf, 256 * 1024, &m_pFont); + HRESULT g_hResult = XFONT_OpenTrueTypeFont(wcPathBuf, 256 * 1024, &m_pFont); delete [] wcPathBuf; @@ -80,6 +81,7 @@ void Font::Render(const string &str, int x, int y, dword height, dword style, D3 void Font::RenderToTexture(CSurface &texture, const string &str, dword height, dword style, D3DXCOLOR color, int maxWidth, bool fade) { + xdk_d3d_video_t *d3d = (xdk_d3d_video_t*)driver.video_data; if (m_pFont == NULL) return; @@ -114,7 +116,7 @@ void Font::RenderToTexture(CSurface &texture, const string &str, dword height, d // create an temporary image surface to render to D3DSurface *pTempSurface; - g_video.m_pD3DDevice->CreateImageSurface(dwTextureWidth, dwTextureHeight, D3DFMT_LIN_A8R8G8B8, &pTempSurface); + d3d->d3d_render_device->CreateImageSurface(dwTextureWidth, dwTextureHeight, D3DFMT_LIN_A8R8G8B8, &pTempSurface); // clear the temporary surface { diff --git a/xbox1/RetroLaunch/Launcher.cpp b/xbox1/RetroLaunch/Launcher.cpp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/xbox1/RetroLaunch/Surface.cpp b/xbox1/RetroLaunch/Surface.cpp index f8718ef968..0f6c1aa94d 100644 --- a/xbox1/RetroLaunch/Surface.cpp +++ b/xbox1/RetroLaunch/Surface.cpp @@ -17,6 +17,8 @@ #include "Surface.h" #include "Debug.h" + +#include "../../general.h" #include "../xdk_d3d8.h" CSurface::CSurface() @@ -45,10 +47,11 @@ CSurface::~CSurface() bool CSurface::Create(const string &szFilename) { + xdk_d3d_video_t *d3d = (xdk_d3d_video_t*)driver.video_data; if (m_bLoaded) Destroy(); - g_hResult = D3DXCreateTextureFromFileExA(g_video.m_pD3DDevice, // d3d device + HRESULT g_hResult = D3DXCreateTextureFromFileExA(d3d->d3d_render_device, // d3d device ("D:\\" + szFilename).c_str(), // filename D3DX_DEFAULT, D3DX_DEFAULT, // width/height D3DX_DEFAULT, // mipmaps @@ -69,7 +72,7 @@ bool CSurface::Create(const string &szFilename) } // create a vertex buffer for the quad that will display the texture - g_hResult = g_video.m_pD3DDevice->CreateVertexBuffer(4 * sizeof(DrawVerticeFormats), + g_hResult = d3d->d3d_render_device->CreateVertexBuffer(4 * sizeof(DrawVerticeFormats), D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEX, D3DPOOL_MANAGED, &m_pVertexBuffer); @@ -87,10 +90,11 @@ bool CSurface::Create(const string &szFilename) bool CSurface::Create(dword width, dword height) { + xdk_d3d_video_t *d3d = (xdk_d3d_video_t*)driver.video_data; if (m_bLoaded) Destroy(); - g_hResult = g_video.m_pD3DDevice->CreateTexture(width, height, 1, 0, + HRESULT g_hResult = d3d->d3d_render_device->CreateTexture(width, height, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &m_pTexture); @@ -105,7 +109,7 @@ bool CSurface::Create(dword width, dword height) m_imageInfo.Format = D3DFMT_A8R8G8B8; // create a vertex buffer for the quad that will display the texture - g_hResult = g_video.m_pD3DDevice->CreateVertexBuffer(4 * sizeof(DrawVerticeFormats), + g_hResult = d3d->d3d_render_device->CreateVertexBuffer(4 * sizeof(DrawVerticeFormats), D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEX, D3DPOOL_MANAGED, &m_pVertexBuffer); @@ -157,6 +161,7 @@ bool CSurface::Render(int x, int y) bool CSurface::Render(int x, int y, dword w, dword h) { + xdk_d3d_video_t *d3d = (xdk_d3d_video_t*)driver.video_data; if (m_pTexture == NULL || m_pVertexBuffer == NULL || m_bLoaded == false) return false; @@ -176,7 +181,7 @@ bool CSurface::Render(int x, int y, dword w, dword h) // load the existing vertices /*CustomVertex*/DrawVerticeFormats *pCurVerts; - g_hResult = m_pVertexBuffer->Lock(0, 0, (byte **)&pCurVerts, 0); + HRESULT g_hResult = m_pVertexBuffer->Lock(0, 0, (byte **)&pCurVerts, 0); if (FAILED(g_hResult)) { @@ -189,20 +194,20 @@ bool CSurface::Render(int x, int y, dword w, dword h) m_pVertexBuffer->Unlock(); - g_video.m_pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); - g_video.m_pD3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); - g_video.m_pD3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); + d3d->d3d_render_device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + d3d->d3d_render_device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + d3d->d3d_render_device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); // also blend the texture with the set alpha value - g_video.m_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); - g_video.m_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE); - g_video.m_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TEXTURE); + d3d->d3d_render_device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); + d3d->d3d_render_device->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE); + d3d->d3d_render_device->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TEXTURE); // draw the quad - g_video.m_pD3DDevice->SetTexture(0, m_pTexture); - g_video.m_pD3DDevice->SetStreamSource(0, m_pVertexBuffer, sizeof(DrawVerticeFormats)); - g_video.m_pD3DDevice->SetVertexShader(D3DFVF_CUSTOMVERTEX); - g_video.m_pD3DDevice->DrawPrimitive(D3DPT_QUADLIST, 0, 1); + d3d->d3d_render_device->SetTexture(0, m_pTexture); + d3d->d3d_render_device->SetStreamSource(0, m_pVertexBuffer, sizeof(DrawVerticeFormats)); + d3d->d3d_render_device->SetVertexShader(D3DFVF_CUSTOMVERTEX); + d3d->d3d_render_device->DrawPrimitive(D3DPT_QUADLIST, 0, 1); return true; } diff --git a/xbox1/RetroLaunch/Surface.h b/xbox1/RetroLaunch/Surface.h index 752ee12f93..e9b6b42068 100644 --- a/xbox1/RetroLaunch/Surface.h +++ b/xbox1/RetroLaunch/Surface.h @@ -18,7 +18,6 @@ #pragma once #include "Global.h" -#include "Video.h" class CSurface { diff --git a/xbox1/RetroLaunch/Video.cpp b/xbox1/RetroLaunch/Video.cpp deleted file mode 100644 index 35f3c403bc..0000000000 --- a/xbox1/RetroLaunch/Video.cpp +++ /dev/null @@ -1,126 +0,0 @@ -/** - * RetroLaunch 2012 - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. This program 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 this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. To contact the - * authors: Surreal64 CE Team (http://www.emuxtras.net) - */ - - -#include "Video.h" -#include "IniFile.h" -#include "Debug.h" - -CVideo g_video; -HRESULT g_hResult; - -CVideo::CVideo(void) -{ -} - -CVideo::~CVideo(void) -{ -} - -bool CVideo::SetDevice(IDirect3DDevice8 *D3D_Device) -{ - m_pD3DDevice = D3D_Device; - return true; -} - -bool CVideo::Create(HWND hDeviceWindow, bool bWindowed) -{ - /* - // Create the Direct3D object (leave it DX8 or should we try DX9 for WIN32 ?) - m_pD3D = Direct3DCreate8(D3D_SDK_VERSION); - - if (m_pD3D == NULL) - return false; - - // set up the structure used to create the d3d device - D3DPRESENT_PARAMETERS d3dpp; - ZeroMemory(&d3dpp, sizeof(d3dpp)); - - d3dpp.BackBufferWidth = 640; - d3dpp.BackBufferHeight = 480; - d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8; - d3dpp.BackBufferCount = 1; - //d3dpp.AutoDepthStencilFormat = D3DFMT_D16; - //d3dpp.EnableAutoDepthStencil = false; - d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; - - //Fullscreen only - if(!bWindowed) - { - if(!g_iniFile.m_currentIniEntry.bVSync) { - d3dpp.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; - }else{ - d3dpp.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_ONE; - } - } - - g_hResult = m_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, NULL, - D3DCREATE_HARDWARE_VERTEXPROCESSING, - &d3dpp, &m_pD3DDevice); - - if (FAILED(g_hResult)) - { - g_debug.Print("Error: D3DCreate(), CreateDevice()"); - return false; - } - // use an orthogonal matrix for the projection matrix - D3DXMATRIX mat; - - D3DXMatrixOrthoOffCenterLH(&mat, 0.0f, 640.0f, 480.0f, 0.0f, 0.0f, 1.0f); - - m_pD3DDevice->SetTransform(D3DTS_PROJECTION, &mat); - - // use an identity matrix for the world and view matrices - D3DXMatrixIdentity(&mat); - m_pD3DDevice->SetTransform(D3DTS_WORLD, &mat); - m_pD3DDevice->SetTransform(D3DTS_VIEW, &mat); - - // disable lighting - m_pD3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE); - - // disable z-buffer (see autodepthstencil) - m_pD3DDevice->SetRenderState(D3DRS_ZENABLE, FALSE ); -*/ - return true; -} - - -void CVideo::BeginRender() -{ - m_pD3DDevice->Clear(0, NULL, D3DCLEAR_TARGET, - D3DCOLOR_XRGB(0, 0, 0), - 1.0f, 0); - - m_pD3DDevice->BeginScene(); - m_pD3DDevice->SetFlickerFilter(g_iniFile.m_currentIniEntry.dwFlickerFilter); - m_pD3DDevice->SetSoftDisplayFilter(g_iniFile.m_currentIniEntry.bSoftDisplayFilter); -} - -void CVideo::EndRender() -{ - m_pD3DDevice->EndScene(); - - m_pD3DDevice->Present(NULL, NULL, NULL, NULL); - -} - -void CVideo::CleanUp() -{ - if( m_pD3DDevice != NULL) - m_pD3DDevice->Release(); - - if( m_pD3D != NULL) - m_pD3D->Release(); -} diff --git a/xbox1/RetroLaunch/Video.h b/xbox1/RetroLaunch/Video.h deleted file mode 100644 index fc9c80e155..0000000000 --- a/xbox1/RetroLaunch/Video.h +++ /dev/null @@ -1,56 +0,0 @@ -/** - * RetroLaunch 2012 - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. This program 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 this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. To contact the - * authors: Surreal64 CE Team (http://www.emuxtras.net) - */ - -#pragma once - -#include "Global.h" - -#undef D3DFVF_CUSTOMVERTEX -//#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1) - -/* -typedef struct CustomVertex -{ - float x, y, z; - dword color; - float u, v; - //float rhw; -}CustomVertex; -*/ - -class CVideo -{ -public: - CVideo(void); - ~CVideo(void); - - bool Create(HWND hDeviceWindow, bool bWindowed); //Device creation - bool SetDevice(IDirect3DDevice8 *D3D_Device); - - void BeginRender(); - void EndRender(); - void CleanUp(); - -public: - /*Direct3D*/IDirect3D8 *m_pD3D; //D3D object - /*D3DDevice*/IDirect3DDevice8 *m_pD3DDevice; //D3D device - -private: - - //nothing -}; - -extern CVideo g_video; -extern HRESULT g_hResult; diff --git a/xdk/frontend/main.c b/xdk/frontend/main.c index ef0cfc2d95..c200967f18 100644 --- a/xdk/frontend/main.c +++ b/xdk/frontend/main.c @@ -93,6 +93,7 @@ static void set_default_settings (void) static void get_environment_settings (void) { HRESULT ret; + (void)ret; #ifdef HAVE_HDD_CACHE_PARTITION ret = XSetFileCacheSize(0x100000); @@ -167,7 +168,6 @@ static void configure_libretro(const char *path_prefix, const char * extension) #ifdef _XBOX1 #include "../../xbox1/RetroLaunch/Global.h" -#include "../../xbox1/RetroLaunch/Video.h" #include "../../xbox1/RetroLaunch/IniFile.h" #include "../../xbox1/RetroLaunch/IoSupport.h" #include "../../xbox1/RetroLaunch/Input.h" @@ -193,14 +193,6 @@ static void menu_init(void) g_IOSupport.Mount("G:", "Harddisk0\\Partition7"); // Get RetroArch's native d3d device - xdk_d3d_video_t *d3d = (xdk_d3d_video_t*)driver.video_data; - - // Initialize Direct3D - //if (!g_video.Create(NULL, false)) - //return; - - if(!g_video.SetDevice(d3d->d3d_render_device)) - return; // Parse ini file for settings g_iniFile.CheckForIniEntry(); @@ -218,19 +210,31 @@ static void menu_init(void) // Build menu here (Menu state -> Main Menu) g_menuManager.Create(); + + g_console.mode_switch = MODE_MENU; } static void menu_free(void) {} static void menu_loop(void) { + xdk_d3d_video_t *d3d = (xdk_d3d_video_t*)driver.video_data; //rarch_console_load_game("D:\\ssf2x.gba"); // Loop the app while (!g_bExit) { - g_video.BeginRender(); + d3d->d3d_render_device->Clear(0, NULL, D3DCLEAR_TARGET, + D3DCOLOR_XRGB(0, 0, 0), + 1.0f, 0); + + d3d->d3d_render_device->BeginScene(); + d3d->d3d_render_device->SetFlickerFilter(g_iniFile.m_currentIniEntry.dwFlickerFilter); + d3d->d3d_render_device->SetSoftDisplayFilter(g_iniFile.m_currentIniEntry.bSoftDisplayFilter); + g_input.GetInput(); g_menuManager.Update(); - g_video.EndRender(); + + d3d->d3d_render_device->EndScene(); + d3d->d3d_render_device->Present(NULL, NULL, NULL, NULL); } } #endif From 0e6e563b08d10f98ee0929b17dc2dd34d7da7ee2 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Mon, 23 Jul 2012 18:17:50 +0200 Subject: [PATCH 19/51] (PS3/360/Xbox 1) Create and use default_paths struct --- console/retroarch_console.c | 2 + console/retroarch_console.h | 18 + gfx/gl.c | 4 +- gfx/gles.c | 1292 ------------------------ ps3/frontend/main.c | 73 +- ps3/frontend/menu.c | 36 +- ps3/frontend/shared.h | 9 - ps3/pkg/USRDIR/cores/savestates/.empty | 0 ps3/pkg/USRDIR/cores/sram/.empty | 0 xdk/frontend/main.c | 23 +- 10 files changed, 83 insertions(+), 1374 deletions(-) delete mode 100644 gfx/gles.c create mode 100644 ps3/pkg/USRDIR/cores/savestates/.empty create mode 100644 ps3/pkg/USRDIR/cores/sram/.empty diff --git a/console/retroarch_console.c b/console/retroarch_console.c index 8bcd6b610e..9c72d76ab4 100644 --- a/console/retroarch_console.c +++ b/console/retroarch_console.c @@ -47,6 +47,8 @@ ROM EXTENSIONS ============================================================ */ +default_paths_t default_paths; + void rarch_console_load_game(const char *path) { snprintf(g_console.rom_path, sizeof(g_console.rom_path), path); diff --git a/console/retroarch_console.h b/console/retroarch_console.h index 5a0e161131..130ad992cf 100644 --- a/console/retroarch_console.h +++ b/console/retroarch_console.h @@ -134,6 +134,24 @@ enum /*============================================================ ROM EXTENSIONS ============================================================ */ +typedef struct +{ + char border_file[PATH_MAX]; + char border_dir[PATH_MAX]; + char config_file[PATH_MAX]; + char core_dir[PATH_MAX]; + char port_dir[PATH_MAX]; + char savestate_dir[PATH_MAX]; +#if defined(HAVE_CG) || defined(HAVE_HLSL) || defined(HAVE_GLSL) + char menu_shader_file[PATH_MAX]; + char shader_file[PATH_MAX]; + char shader_dir[PATH_MAX]; +#endif + char sram_dir[PATH_MAX]; + char system_dir[PATH_MAX]; +} default_paths_t; + +extern default_paths_t default_paths; void rarch_console_load_game(const char *path); diff --git a/gfx/gl.c b/gfx/gl.c index a97cbb19ce..93494a1e94 100644 --- a/gfx/gl.c +++ b/gfx/gl.c @@ -1065,9 +1065,9 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo RARCH_LOG("GL: Using resolution %ux%u\n", gl->win_width, gl->win_height); -#ifdef HAVE_CG_MENU +#if defined(HAVE_CG_MENU) && defined(RARCH_CONSOLE) RARCH_LOG("Initializing menu shader ...\n"); - gl_cg_set_menu_shader(DEFAULT_MENU_SHADER_FILE); + gl_cg_set_menu_shader(default_paths.menu_shader_file); #endif if (!gl_shader_init()) diff --git a/gfx/gles.c b/gfx/gles.c deleted file mode 100644 index 69e3527f9a..0000000000 --- a/gfx/gles.c +++ /dev/null @@ -1,1292 +0,0 @@ -/* RetroArch - A frontend for libretro. - * Copyright (C) 2010-2012 - Hans-Kristian Arntzen - * - * RetroArch 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. - * - * RetroArch 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 RetroArch. - * If not, see . - */ - -/* Non-FF OpenGL 3 / OpenGL ES 2.0 driver */ - -#include "../driver.h" - -#include -#include "../libretro.h" -#include -#include -#include "../general.h" -#include - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "gl_common.h" -#include "gl_font.h" -#include "gfx_common.h" -#include "gfx_context.h" -#include "../compat/strl.h" - -#ifdef HAVE_SDL -#define NO_SDL_GLEXT -#include "context/sdl_ctx.h" -#include "../input/rarch_sdl_input.h" -#endif - -#ifdef HAVE_CG -#include "shader_cg.h" -#endif - -#ifdef HAVE_XML -#include "shader_glsl.h" -#endif - -extern const GLfloat vertexes_flipped[]; -extern const GLfloat white_color[]; - -// Used for the last pass when rendering to the back buffer. -const GLfloat vertexes_flipped[] = { - 0, 0, - 0, 1, - 1, 1, - 1, 0 -}; - -// Used when rendering to an FBO. -// Texture coords have to be aligned with vertex coordinates. -static const GLfloat vertexes[] = { - 0, 1, - 0, 0, - 1, 0, - 1, 1 -}; - -static const GLfloat tex_coords[] = { - 0, 1, - 0, 0, - 1, 0, - 1, 1 -}; - -const GLfloat white_color[] = { - 1, 1, 1, 1, - 1, 1, 1, 1, - 1, 1, 1, 1, - 1, 1, 1, 1, -}; - -const GLfloat *vertex_ptr = vertexes_flipped; -const GLfloat *default_vertex_ptr = vertexes_flipped; - -#ifdef HAVE_SDL -#define LOAD_SYM(sym) if (!p##sym) { SDL_SYM_WRAP(p##sym, #sym) } -#endif - -#ifdef HAVE_FBO -#if defined(_WIN32) && !defined(RARCH_CONSOLE) -static PFNGLGENFRAMEBUFFERSPROC pglGenFramebuffers = NULL; -static PFNGLBINDFRAMEBUFFERPROC pglBindFramebuffer = NULL; -static PFNGLFRAMEBUFFERTEXTURE2DPROC pglFramebufferTexture2D = NULL; -static PFNGLCHECKFRAMEBUFFERSTATUSPROC pglCheckFramebufferStatus = NULL; -static PFNGLDELETEFRAMEBUFFERSPROC pglDeleteFramebuffers = NULL; - -static bool load_fbo_proc(void) -{ - LOAD_SYM(glGenFramebuffers); - LOAD_SYM(glBindFramebuffer); - LOAD_SYM(glFramebufferTexture2D); - LOAD_SYM(glCheckFramebufferStatus); - LOAD_SYM(glDeleteFramebuffers); - - return pglGenFramebuffers && pglBindFramebuffer && pglFramebufferTexture2D && - pglCheckFramebufferStatus && pglDeleteFramebuffers; -} -#elif defined(HAVE_OPENGLES) -#define pglGenFramebuffers glGenFramebuffersOES -#define pglBindFramebuffer glBindFramebufferOES -#define pglFramebufferTexture2D glFramebufferTexture2DOES -#define pglCheckFramebufferStatus glCheckFramebufferStatusOES -#define pglDeleteFramebuffers glDeleteFramebuffersOES -#define GL_FRAMEBUFFER GL_FRAMEBUFFER_OES -#define GL_COLOR_ATTACHMENT0 GL_COLOR_ATTACHMENT0_EXT -#define GL_FRAMEBUFFER_COMPLETE GL_FRAMEBUFFER_COMPLETE_OES -#define glOrtho glOrthof -static bool load_fbo_proc(void) { return true; } -#else -#define pglGenFramebuffers glGenFramebuffers -#define pglBindFramebuffer glBindFramebuffer -#define pglFramebufferTexture2D glFramebufferTexture2D -#define pglCheckFramebufferStatus glCheckFramebufferStatus -#define pglDeleteFramebuffers glDeleteFramebuffers -static bool load_fbo_proc(void) { return true; } -#endif -#endif - -#if (defined(HAVE_XML) || defined(HAVE_CG)) && defined(_WIN32) -PFNGLCLIENTACTIVETEXTUREPROC pglClientActiveTexture = NULL; -PFNGLACTIVETEXTUREPROC pglActiveTexture = NULL; -static inline bool load_gl_proc(void) -{ - LOAD_SYM(glClientActiveTexture); - LOAD_SYM(glActiveTexture); - return pglClientActiveTexture && pglActiveTexture; -} -#else -static inline bool load_gl_proc(void) { return true; } -#endif - -////////////////// Shaders -static bool gl_shader_init(void) -{ - switch (g_settings.video.shader_type) - { - case RARCH_SHADER_AUTO: - { - if (*g_settings.video.cg_shader_path && *g_settings.video.bsnes_shader_path) - RARCH_WARN("Both Cg and bSNES XML shader are defined in config file. Cg shader will be selected by default.\n"); - -#ifdef HAVE_CG - if (*g_settings.video.cg_shader_path) - return gl_cg_init(g_settings.video.cg_shader_path); -#endif - -#ifdef HAVE_XML - if (*g_settings.video.bsnes_shader_path) - return gl_glsl_init(g_settings.video.bsnes_shader_path); -#endif - break; - } - -#ifdef HAVE_CG - case RARCH_SHADER_CG: - return gl_cg_init(g_settings.video.cg_shader_path); -#endif - -#ifdef HAVE_XML - case RARCH_SHADER_BSNES: - return gl_glsl_init(g_settings.video.bsnes_shader_path); -#endif - - default: - break; - } - - return true; -} - -void gl_shader_use(unsigned index) -{ -#ifdef HAVE_CG - gl_cg_use(index); -#endif - -#ifdef HAVE_XML - gl_glsl_use(index); -#endif -} - -static inline void gl_shader_deinit(void) -{ -#ifdef HAVE_CG - gl_cg_deinit(); -#endif - -#ifdef HAVE_XML - gl_glsl_deinit(); -#endif -} - -static inline void gl_shader_set_proj_matrix(void) -{ -#ifdef HAVE_CG - gl_cg_set_proj_matrix(); -#endif - -#ifdef HAVE_XML - gl_glsl_set_proj_matrix(); -#endif -} - -static inline void gl_shader_set_params(unsigned width, unsigned height, - unsigned tex_width, unsigned tex_height, - unsigned out_width, unsigned out_height, - unsigned frame_count, - const struct gl_tex_info *info, - const struct gl_tex_info *prev_info, - const struct gl_tex_info *fbo_info, unsigned fbo_info_cnt) -{ -#ifdef HAVE_CG - gl_cg_set_params(width, height, - tex_width, tex_height, - out_width, out_height, - frame_count, info, prev_info, fbo_info, fbo_info_cnt); -#endif - -#ifdef HAVE_XML - gl_glsl_set_params(width, height, - tex_width, tex_height, - out_width, out_height, - frame_count, info, prev_info, fbo_info, fbo_info_cnt); -#endif -} - -static unsigned gl_shader_num(void) -{ -#ifdef HAVE_CG - unsigned cg_num = gl_cg_num(); - if (cg_num) - return cg_num; -#endif - -#ifdef HAVE_XML - unsigned glsl_num = gl_glsl_num(); - if (glsl_num) - return glsl_num; -#endif - - return 0; -} - -static bool gl_shader_filter_type(unsigned index, bool *smooth) -{ - bool valid = false; - -#ifdef HAVE_CG - if (!valid) - valid = gl_cg_filter_type(index, smooth); -#endif - -#ifdef HAVE_XML - if (!valid) - valid = gl_glsl_filter_type(index, smooth); -#endif - - return valid; -} - -#ifdef HAVE_FBO -static void gl_shader_scale(unsigned index, struct gl_fbo_scale *scale) -{ - scale->valid = false; - -#ifdef HAVE_CG - if (!scale->valid) - gl_cg_shader_scale(index, scale); -#endif - -#ifdef HAVE_XML - if (!scale->valid) - gl_glsl_shader_scale(index, scale); -#endif -} -#endif -/////////////////// - - -#ifdef HAVE_FBO -static void gl_compute_fbo_geometry(gl_t *gl, unsigned width, unsigned height, - unsigned vp_width, unsigned vp_height); - -static void gl_create_fbo_textures(gl_t *gl) -{ - glGenTextures(gl->fbo_pass, gl->fbo_texture); - - GLuint base_filt = g_settings.video.second_pass_smooth ? GL_LINEAR : GL_NEAREST; - for (int i = 0; i < gl->fbo_pass; i++) - { - glBindTexture(GL_TEXTURE_2D, gl->fbo_texture[i]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); - - GLuint filter_type = base_filt; - bool smooth = false; - if (gl_shader_filter_type(i + 2, &smooth)) - filter_type = smooth ? GL_LINEAR : GL_NEAREST; - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter_type); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter_type); - - glTexImage2D(GL_TEXTURE_2D, - 0, RARCH_GL_INTERNAL_FORMAT, gl->fbo_rect[i].width, gl->fbo_rect[i].height, - 0, RARCH_GL_TEXTURE_TYPE, - RARCH_GL_FORMAT32, NULL); - } - - glBindTexture(GL_TEXTURE_2D, 0); -} - -static bool gl_create_fbo_targets(gl_t *gl) -{ - pglGenFramebuffers(gl->fbo_pass, gl->fbo); - for (int i = 0; i < gl->fbo_pass; i++) - { - pglBindFramebuffer(GL_FRAMEBUFFER, gl->fbo[i]); - pglFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gl->fbo_texture[i], 0); - - GLenum status = pglCheckFramebufferStatus(GL_FRAMEBUFFER); - if (status != GL_FRAMEBUFFER_COMPLETE) - goto error; - } - - return true; - -error: - pglDeleteFramebuffers(gl->fbo_pass, gl->fbo); - RARCH_ERR("Failed to set up frame buffer objects. Multi-pass shading will not work.\n"); - return false; -} - -void gl_deinit_fbo(gl_t *gl) -{ - if (gl->fbo_inited) - { - glDeleteTextures(gl->fbo_pass, gl->fbo_texture); - pglDeleteFramebuffers(gl->fbo_pass, gl->fbo); - memset(gl->fbo_texture, 0, sizeof(gl->fbo_texture)); - memset(gl->fbo, 0, sizeof(gl->fbo)); - gl->fbo_inited = false; - gl->render_to_tex = false; - gl->fbo_pass = 0; - } -} - -void gl_init_fbo(gl_t *gl, unsigned width, unsigned height) -{ - // No need to use FBOs. - if (!g_settings.video.render_to_texture && gl_shader_num() == 0) - return; - - struct gl_fbo_scale scale, scale_last; - gl_shader_scale(1, &scale); - gl_shader_scale(gl_shader_num(), &scale_last); - - // No need to use FBOs. - if (gl_shader_num() == 1 && !scale.valid && !g_settings.video.render_to_texture) - return; - - if (!load_fbo_proc()) - { - RARCH_ERR("Failed to locate FBO functions. Won't be able to use render-to-texture.\n"); - return; - } - - gl->fbo_pass = gl_shader_num() - 1; - if (scale_last.valid) - gl->fbo_pass++; - - if (gl->fbo_pass <= 0) - gl->fbo_pass = 1; - - if (!scale.valid) - { - scale.scale_x = g_settings.video.fbo_scale_x; - scale.scale_y = g_settings.video.fbo_scale_y; - scale.type_x = scale.type_y = RARCH_SCALE_INPUT; - scale.valid = true; - } - - gl->fbo_scale[0] = scale; - - for (int i = 1; i < gl->fbo_pass; i++) - { - gl_shader_scale(i + 1, &gl->fbo_scale[i]); - - if (!gl->fbo_scale[i].valid) - { - gl->fbo_scale[i].scale_x = gl->fbo_scale[i].scale_y = 1.0f; - gl->fbo_scale[i].type_x = gl->fbo_scale[i].type_y = RARCH_SCALE_INPUT; - gl->fbo_scale[i].valid = true; - } - } - - gl_compute_fbo_geometry(gl, width, height, gl->win_width, gl->win_height); - - for (int i = 0; i < gl->fbo_pass; i++) - { - gl->fbo_rect[i].width = next_pow2(gl->fbo_rect[i].img_width); - gl->fbo_rect[i].height = next_pow2(gl->fbo_rect[i].img_height); - RARCH_LOG("Creating FBO %d @ %ux%u\n", i, gl->fbo_rect[i].width, gl->fbo_rect[i].height); - } - - gl_create_fbo_textures(gl); - if (!gl_create_fbo_targets(gl)) - { - glDeleteTextures(gl->fbo_pass, gl->fbo_texture); - return; - } - - gl->fbo_inited = true; -} -#endif - -//////////// - -void gl_set_projection(gl_t *gl, struct gl_ortho *ortho, bool allow_rotate) -{ -#ifdef RARCH_CONSOLE - if (g_console.overscan_enable) - { - ortho->left = -g_console.overscan_amount / 2; - ortho->right = 1 + g_console.overscan_amount / 2; - ortho->bottom = -g_console.overscan_amount / 2; - } -#endif - - gfx_ctx_set_projection(gl, ortho, allow_rotate); - gl_shader_set_proj_matrix(); -} - -void gl_set_viewport(gl_t *gl, unsigned width, unsigned height, bool force_full, bool allow_rotate) -{ - unsigned x = 0, y = 0; - struct gl_ortho ortho = {0, 1, 0, 1, -1, 1}; - - if (gl->keep_aspect && !force_full) - { - float desired_aspect = g_settings.video.aspect_ratio; - float device_aspect = (float)width / height; - float delta; - -#ifdef RARCH_CONSOLE - if (g_console.aspect_ratio_index == ASPECT_RATIO_CUSTOM) - { - x = g_console.viewports.custom_vp.x; - y = g_console.viewports.custom_vp.y; - width = g_console.viewports.custom_vp.width; - height = g_console.viewports.custom_vp.height; - } - else -#endif - { - if (fabs(device_aspect - desired_aspect) < 0.0001) - { - // If the aspect ratios of screen and desired aspect ratio are sufficiently equal (floating point stuff), - // assume they are actually equal. - } - else if (device_aspect > desired_aspect) - { - delta = (desired_aspect / device_aspect - 1.0) / 2.0 + 0.5; - x = (unsigned)(width * (0.5 - delta)); - width = (unsigned)(2.0 * width * delta); - } - else - { - delta = (device_aspect / desired_aspect - 1.0) / 2.0 + 0.5; - y = (unsigned)(height * (0.5 - delta)); - height = (unsigned)(2.0 * height * delta); - } - } - } - - glViewport(x, y, width, height); - - gl_set_projection(gl, &ortho, allow_rotate); - - gl->vp_width = width; - gl->vp_height = height; - - // Set last backbuffer viewport. - if (!force_full) - { - gl->vp_out_width = width; - gl->vp_out_height = height; - } - - //RARCH_LOG("Setting viewport @ %ux%u\n", width, height); -} - -static void gl_set_rotation(void *data, unsigned rotation) -{ - struct gl_ortho ortho = {0, 1, 0, 1, -1, 1}; - - gl_t *gl = (gl_t*)driver.video_data; - gl->rotation = 90 * rotation; - gl_set_projection(gl, &ortho, true); -} - -static inline void set_lut_texture_coords(const GLfloat *coords) -{ -#if defined(HAVE_XML) || defined(HAVE_CG) - // For texture images. - pglClientActiveTexture(GL_TEXTURE1); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, 0, coords); - pglClientActiveTexture(GL_TEXTURE0); -#else - (void)coords; -#endif -} - -static inline void set_texture_coords(GLfloat *coords, GLfloat xamt, GLfloat yamt) -{ - coords[1] = yamt; - coords[4] = xamt; - coords[6] = xamt; - coords[7] = yamt; -} - -#ifdef HAVE_FBO -static void gl_compute_fbo_geometry(gl_t *gl, unsigned width, unsigned height, - unsigned vp_width, unsigned vp_height) -{ - unsigned last_width = width; - unsigned last_height = height; - unsigned last_max_width = gl->tex_w; - unsigned last_max_height = gl->tex_h; - // Calculate viewports for FBOs. - for (int i = 0; i < gl->fbo_pass; i++) - { - switch (gl->fbo_scale[i].type_x) - { - case RARCH_SCALE_INPUT: - gl->fbo_rect[i].img_width = last_width * gl->fbo_scale[i].scale_x; - gl->fbo_rect[i].max_img_width = last_max_width * gl->fbo_scale[i].scale_x; - break; - - case RARCH_SCALE_ABSOLUTE: - gl->fbo_rect[i].img_width = gl->fbo_rect[i].max_img_width = gl->fbo_scale[i].abs_x; - break; - - case RARCH_SCALE_VIEWPORT: - gl->fbo_rect[i].img_width = gl->fbo_rect[i].max_img_width = gl->fbo_scale[i].scale_x * vp_width; - break; - - default: - break; - } - - switch (gl->fbo_scale[i].type_y) - { - case RARCH_SCALE_INPUT: - gl->fbo_rect[i].img_height = last_height * gl->fbo_scale[i].scale_y; - gl->fbo_rect[i].max_img_height = last_max_height * gl->fbo_scale[i].scale_y; - break; - - case RARCH_SCALE_ABSOLUTE: - gl->fbo_rect[i].img_height = gl->fbo_rect[i].max_img_height = gl->fbo_scale[i].abs_y; - break; - - case RARCH_SCALE_VIEWPORT: - gl->fbo_rect[i].img_height = gl->fbo_rect[i].max_img_height = gl->fbo_scale[i].scale_y * vp_height; - break; - - default: - break; - } - - last_width = gl->fbo_rect[i].img_width; - last_height = gl->fbo_rect[i].img_height; - last_max_width = gl->fbo_rect[i].max_img_width; - last_max_height = gl->fbo_rect[i].max_img_height; - } -} - -static inline void gl_start_frame_fbo(gl_t *gl) -{ - glBindTexture(GL_TEXTURE_2D, gl->texture[gl->tex_index]); - pglBindFramebuffer(GL_FRAMEBUFFER, gl->fbo[0]); - gl->render_to_tex = true; - gl_set_viewport(gl, gl->fbo_rect[0].img_width, gl->fbo_rect[0].img_height, true, false); - - // Need to preserve the "flipped" state when in FBO as well to have - // consistent texture coordinates. - // We will "flip" it in place on last pass. - if (gl->render_to_tex) - glVertexPointer(2, GL_FLOAT, 0, vertexes); -} - -static void gl_check_fbo_dimensions(gl_t *gl) -{ - // Check if we have to recreate our FBO textures. - for (int i = 0; i < gl->fbo_pass; i++) - { - // Check proactively since we might suddently get sizes of tex_w width or tex_h height. - if (gl->fbo_rect[i].max_img_width > gl->fbo_rect[i].width || - gl->fbo_rect[i].max_img_height > gl->fbo_rect[i].height) - { - unsigned img_width = gl->fbo_rect[i].max_img_width; - unsigned img_height = gl->fbo_rect[i].max_img_height; - unsigned max = img_width > img_height ? img_width : img_height; - unsigned pow2_size = next_pow2(max); - gl->fbo_rect[i].width = gl->fbo_rect[i].height = pow2_size; - - pglBindFramebuffer(GL_FRAMEBUFFER, gl->fbo[i]); - glBindTexture(GL_TEXTURE_2D, gl->fbo_texture[i]); - glTexImage2D(GL_TEXTURE_2D, - 0, RARCH_GL_INTERNAL_FORMAT, gl->fbo_rect[i].width, gl->fbo_rect[i].height, - 0, RARCH_GL_TEXTURE_TYPE, - RARCH_GL_FORMAT32, NULL); - - pglFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gl->fbo_texture[i], 0); - - GLenum status = pglCheckFramebufferStatus(GL_FRAMEBUFFER); - if (status != GL_FRAMEBUFFER_COMPLETE) - RARCH_WARN("Failed to reinit FBO texture.\n"); - - RARCH_LOG("Recreating FBO texture #%d: %ux%u\n", i, gl->fbo_rect[i].width, gl->fbo_rect[i].height); - } - } -} - -static void gl_frame_fbo(gl_t *gl, const struct gl_tex_info *tex_info) -{ - GLfloat fbo_tex_coords[8] = {0.0f}; - - // Render the rest of our passes. - glTexCoordPointer(2, GL_FLOAT, 0, fbo_tex_coords); - - // It's kinda handy ... :) - const struct gl_fbo_rect *prev_rect; - const struct gl_fbo_rect *rect; - struct gl_tex_info *fbo_info; - - struct gl_tex_info fbo_tex_info[MAX_SHADERS]; - unsigned fbo_tex_info_cnt = 0; - - // Calculate viewports, texture coordinates etc, and render all passes from FBOs, to another FBO. - for (int i = 1; i < gl->fbo_pass; i++) - { - prev_rect = &gl->fbo_rect[i - 1]; - rect = &gl->fbo_rect[i]; - fbo_info = &fbo_tex_info[i - 1]; - - GLfloat xamt = (GLfloat)prev_rect->img_width / prev_rect->width; - GLfloat yamt = (GLfloat)prev_rect->img_height / prev_rect->height; - - set_texture_coords(fbo_tex_coords, xamt, yamt); - - fbo_info->tex = gl->fbo_texture[i - 1]; - fbo_info->input_size[0] = prev_rect->img_width; - fbo_info->input_size[1] = prev_rect->img_height; - fbo_info->tex_size[0] = prev_rect->width; - fbo_info->tex_size[1] = prev_rect->height; - memcpy(fbo_info->coord, fbo_tex_coords, sizeof(fbo_tex_coords)); - - pglBindFramebuffer(GL_FRAMEBUFFER, gl->fbo[i]); - gl_shader_use(i + 1); - glBindTexture(GL_TEXTURE_2D, gl->fbo_texture[i - 1]); - - glClear(GL_COLOR_BUFFER_BIT); - - // Render to FBO with certain size. - gl_set_viewport(gl, rect->img_width, rect->img_height, true, false); - gl_shader_set_params(prev_rect->img_width, prev_rect->img_height, - prev_rect->width, prev_rect->height, - gl->vp_width, gl->vp_height, gl->frame_count, - tex_info, gl->prev_info, fbo_tex_info, fbo_tex_info_cnt); - - glDrawArrays(GL_QUADS, 0, 4); - - fbo_tex_info_cnt++; - } - - // Render our last FBO texture directly to screen. - prev_rect = &gl->fbo_rect[gl->fbo_pass - 1]; - GLfloat xamt = (GLfloat)prev_rect->img_width / prev_rect->width; - GLfloat yamt = (GLfloat)prev_rect->img_height / prev_rect->height; - - set_texture_coords(fbo_tex_coords, xamt, yamt); - - // Render our FBO texture to back buffer. - pglBindFramebuffer(GL_FRAMEBUFFER, 0); - gl_shader_use(gl->fbo_pass + 1); - - glBindTexture(GL_TEXTURE_2D, gl->fbo_texture[gl->fbo_pass - 1]); - - glClear(GL_COLOR_BUFFER_BIT); - gl->render_to_tex = false; - gl_set_viewport(gl, gl->win_width, gl->win_height, false, true); - gl_shader_set_params(prev_rect->img_width, prev_rect->img_height, - prev_rect->width, prev_rect->height, - gl->vp_width, gl->vp_height, gl->frame_count, - tex_info, gl->prev_info, fbo_tex_info, fbo_tex_info_cnt); - - glVertexPointer(2, GL_FLOAT, 0, vertex_ptr); - glDrawArrays(GL_QUADS, 0, 4); - - glTexCoordPointer(2, GL_FLOAT, 0, gl->tex_coords); -} -#endif - -static void gl_update_resize(gl_t *gl) -{ -#ifdef HAVE_FBO - if (!gl->render_to_tex) - gl_set_viewport(gl, gl->win_width, gl->win_height, false, true); - else - { - gl_check_fbo_dimensions(gl); - - // Go back to what we're supposed to do, render to FBO #0 :D - gl_start_frame_fbo(gl); - } -#else - gl_set_viewport(gl, gl->win_width, gl->win_height, false, true); -#endif -} - -static void gl_update_input_size(gl_t *gl, unsigned width, unsigned height, unsigned pitch) -{ - // Res change. Need to clear out texture. - if ((width != gl->last_width[gl->tex_index] || height != gl->last_height[gl->tex_index]) && gl->empty_buf) - { - gl->last_width[gl->tex_index] = width; - gl->last_height[gl->tex_index] = height; - - glPixelStorei(GL_UNPACK_ALIGNMENT, get_alignment(pitch)); - glPixelStorei(GL_UNPACK_ROW_LENGTH, gl->tex_w); - - glTexSubImage2D(GL_TEXTURE_2D, - 0, 0, 0, gl->tex_w, gl->tex_h, gl->texture_type, - gl->texture_fmt, gl->empty_buf); - - GLfloat xamt = (GLfloat)width / gl->tex_w; - GLfloat yamt = (GLfloat)height / gl->tex_h; - - set_texture_coords(gl->tex_coords, xamt, yamt); - } - // We might have used different texture coordinates last frame. Edge case if resolution changes very rapidly. - else if (width != gl->last_width[(gl->tex_index - 1) & TEXTURES_MASK] || - height != gl->last_height[(gl->tex_index - 1) & TEXTURES_MASK]) - { - GLfloat xamt = (GLfloat)width / gl->tex_w; - GLfloat yamt = (GLfloat)height / gl->tex_h; - set_texture_coords(gl->tex_coords, xamt, yamt); - } -} - -static inline void gl_copy_frame(gl_t *gl, const void *frame, unsigned width, unsigned height, unsigned pitch) -{ - glPixelStorei(GL_UNPACK_ROW_LENGTH, pitch / gl->base_size); - glTexSubImage2D(GL_TEXTURE_2D, - 0, 0, 0, width, height, gl->texture_type, - gl->texture_fmt, frame); -} - -static void gl_init_textures(gl_t *gl) -{ - glGenTextures(TEXTURES, gl->texture); - for (unsigned i = 0; i < TEXTURES; i++) - { - glBindTexture(GL_TEXTURE_2D, gl->texture[i]); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl->tex_filter); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl->tex_filter); - - glPixelStorei(GL_UNPACK_ROW_LENGTH, gl->tex_w); - glTexImage2D(GL_TEXTURE_2D, - 0, RARCH_GL_INTERNAL_FORMAT, gl->tex_w, gl->tex_h, 0, gl->texture_type, - gl->texture_fmt, gl->empty_buf ? gl->empty_buf : NULL); - } - glBindTexture(GL_TEXTURE_2D, gl->texture[gl->tex_index]); -} - -static inline void gl_next_texture_index(gl_t *gl, const struct gl_tex_info *tex_info) -{ - memmove(gl->prev_info + 1, gl->prev_info, sizeof(*tex_info) * (TEXTURES - 1)); - memcpy(&gl->prev_info[0], tex_info, sizeof(*tex_info)); - gl->tex_index = (gl->tex_index + 1) & TEXTURES_MASK; -} - -#ifdef HAVE_CG_MENU -static void gl_render_menu(gl_t *gl) -{ - gl_shader_use(RARCH_CG_MENU_SHADER_INDEX); - - gl_shader_set_params(gl->win_width, gl->win_height, gl->win_width, - gl->win_height, gl->win_width, gl->win_height, gl->frame_count, - NULL, NULL, NULL, 0); - - gl_set_viewport(gl, gl->win_width, gl->win_height, true, false); - - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, gl->menu_texture_id); - - glVertexPointer(2, GL_FLOAT, 0, default_vertex_ptr); - glDrawArrays(GL_QUADS, 0, 4); - glBindTexture(GL_TEXTURE_2D, gl->texture[gl->tex_index]); -} -#endif - -static bool gl_frame(void *data, const void *frame, unsigned width, unsigned height, unsigned pitch, const char *msg) -{ - gl_t *gl = (gl_t*)data; - - gl_shader_use(1); - gl->frame_count++; - - glBindTexture(GL_TEXTURE_2D, gl->texture[gl->tex_index]); - -#ifdef HAVE_FBO - // Render to texture in first pass. - if (gl->fbo_inited) - { - // Recompute FBO geometry. - // When width/height changes or window sizes change, we have to recalcuate geometry of our FBO. - gl_compute_fbo_geometry(gl, width, height, gl->vp_out_width, gl->vp_out_height); - gl_start_frame_fbo(gl); - } -#endif - - if (gl->should_resize) - { - gl->should_resize = false; - gfx_ctx_set_resize(gl->win_width, gl->win_height); - - // On resize, we might have to recreate our FBOs due to "Viewport" scale, and set a new viewport. - gl_update_resize(gl); - } - - if (frame) // Can be NULL for frame dupe / NULL render. - { - gl_update_input_size(gl, width, height, pitch); - gl_copy_frame(gl, frame, width, height, pitch); - } - - struct gl_tex_info tex_info = {0}; - tex_info.tex = gl->texture[gl->tex_index]; - tex_info.input_size[0] = width; - tex_info.input_size[1] = height; - tex_info.tex_size[0] = gl->tex_w; - tex_info.tex_size[1] = gl->tex_h; - - memcpy(tex_info.coord, gl->tex_coords, sizeof(gl->tex_coords)); - - glClear(GL_COLOR_BUFFER_BIT); - gl_shader_set_params(width, height, - gl->tex_w, gl->tex_h, - gl->vp_width, gl->vp_height, - gl->frame_count, - &tex_info, gl->prev_info, NULL, 0); - - glDrawArrays(GL_QUADS, 0, 4); - -#ifdef HAVE_FBO - if (gl->fbo_inited) - gl_frame_fbo(gl, &tex_info); -#endif - - gl_next_texture_index(gl, &tex_info); - - if (msg) - { - gl_render_msg(gl, msg); - gl_render_msg_post(gl); - } - -#ifndef RARCH_CONSOLE - gfx_ctx_update_window_title(false); -#endif - -#ifdef RARCH_CONSOLE - if (!gl->block_swap) -#endif - gfx_ctx_swap_buffers(); - -#ifdef HAVE_CG_MENU - if (gl->menu_render) - gl_render_menu(gl); -#endif - - return true; -} - -static void gl_free(void *data) -{ -#ifdef RARCH_CONSOLE - if (driver.video_data) - return; -#endif - - gl_t *gl = (gl_t*)data; - - gl_deinit_font(gl); - gl_shader_deinit(); - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); - glDeleteTextures(TEXTURES, gl->texture); - -#ifdef HAVE_FBO - gl_deinit_fbo(gl); -#endif - - gfx_ctx_destroy(); - - if (gl->empty_buf) - free(gl->empty_buf); - - free(gl); -} - -static void gl_set_nonblock_state(void *data, bool state) -{ - gl_t *gl = (gl_t*)data; - if (gl->vsync) - { - RARCH_LOG("GL VSync => %s\n", state ? "off" : "on"); - gfx_ctx_set_swap_interval(state ? 0 : 1, true); - } -} - -static void *gl_init(const video_info_t *video, const input_driver_t **input, void **input_data) -{ -#ifdef _WIN32 - gfx_set_dwm(); -#endif - -#ifdef RARCH_CONSOLE - if (driver.video_data) - return driver.video_data; -#endif - - gl_t *gl = (gl_t*)calloc(1, sizeof(gl_t)); - if (!gl) - return NULL; - - if (!gfx_ctx_init()) - { - free(gl); - return NULL; - } - - unsigned full_x = 0, full_y = 0; - gfx_ctx_get_video_size(&full_x, &full_y); - RARCH_LOG("Detecting resolution %ux%u.\n", full_x, full_y); - - gfx_ctx_set_swap_interval(video->vsync ? 1 : 0, false); - - unsigned win_width = video->width; - unsigned win_height = video->height; - if (video->fullscreen && (win_width == 0) && (win_height == 0)) - { - win_width = full_x; - win_height = full_y; - } - - if (!gfx_ctx_set_video_mode(win_width, win_height, - g_settings.video.force_16bit ? 15 : 0, video->fullscreen)) - { - free(gl); - return NULL; - } - -#ifndef RARCH_CONSOLE - gfx_ctx_update_window_title(true); - - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); -#endif - -#if (defined(HAVE_XML) || defined(HAVE_CG)) && defined(_WIN32) - // Win32 GL lib doesn't have some functions needed for XML shaders. - // Need to load dynamically :( - if (!load_gl_proc()) - { - gfx_ctx_destroy(); - free(gl); - return NULL; - } -#endif - - gl->vsync = video->vsync; - gl->fullscreen = video->fullscreen; - - gl->full_x = full_x; - gl->full_y = full_y; - gl->win_width = win_width; - gl->win_height = win_height; - - RARCH_LOG("GL: Using resolution %ux%u\n", gl->win_width, gl->win_height); - -#ifdef HAVE_CG_MENU - RARCH_LOG("Initializing menu shader ...\n"); - gl_cg_set_menu_shader(DEFAULT_MENU_SHADER_FILE); -#endif - - if (!gl_shader_init()) - { - RARCH_ERR("Shader init failed.\n"); - gfx_ctx_destroy(); - free(gl); - return NULL; - } - - RARCH_LOG("GL: Loaded %u program(s).\n", gl_shader_num()); - -#ifdef HAVE_FBO - // Set up render to texture. - gl_init_fbo(gl, RARCH_SCALE_BASE * video->input_scale, - RARCH_SCALE_BASE * video->input_scale); -#endif - - gl->keep_aspect = video->force_aspect; - - // Apparently need to set viewport for passes when we aren't using FBOs. - gl_shader_use(0); - gl_set_viewport(gl, gl->win_width, gl->win_height, false, true); - gl_shader_use(1); - gl_set_viewport(gl, gl->win_width, gl->win_height, false, true); - - bool force_smooth = false; - if (gl_shader_filter_type(1, &force_smooth)) - gl->tex_filter = force_smooth ? GL_LINEAR : GL_NEAREST; - else - gl->tex_filter = video->smooth ? GL_LINEAR : GL_NEAREST; - - gl->texture_type = RARCH_GL_TEXTURE_TYPE; - gl->texture_fmt = video->rgb32 ? RARCH_GL_FORMAT32 : RARCH_GL_FORMAT16; - gl->base_size = video->rgb32 ? sizeof(uint32_t) : sizeof(uint16_t); - - glEnable(GL_TEXTURE_2D); - glDisable(GL_DEPTH_TEST); - glDisable(GL_DITHER); - glClearColor(0, 0, 0, 1); - - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - glVertexPointer(2, GL_FLOAT, 0, vertex_ptr); - - memcpy(gl->tex_coords, tex_coords, sizeof(tex_coords)); - glTexCoordPointer(2, GL_FLOAT, 0, gl->tex_coords); - glColorPointer(4, GL_FLOAT, 0, white_color); - - set_lut_texture_coords(tex_coords); - - gl->tex_w = RARCH_SCALE_BASE * video->input_scale; - gl->tex_h = RARCH_SCALE_BASE * video->input_scale; - - // Empty buffer that we use to clear out the texture with on res change. - gl->empty_buf = calloc(gl->tex_w * gl->tex_h, gl->base_size); - gl_init_textures(gl); - - for (unsigned i = 0; i < TEXTURES; i++) - { - gl->last_width[i] = gl->tex_w; - gl->last_height[i] = gl->tex_h; - } - - for (unsigned i = 0; i < TEXTURES; i++) - { - gl->prev_info[i].tex = gl->texture[(gl->tex_index - (i + 1)) & TEXTURES_MASK]; - gl->prev_info[i].input_size[0] = gl->tex_w; - gl->prev_info[i].tex_size[0] = gl->tex_w; - gl->prev_info[i].input_size[1] = gl->tex_h; - gl->prev_info[i].tex_size[1] = gl->tex_h; - memcpy(gl->prev_info[i].coord, tex_coords, sizeof(tex_coords)); - } - - gfx_ctx_input_driver(input, input_data); - gl_init_font(gl, g_settings.video.font_path, g_settings.video.font_size); - - if (!gl_check_error()) - { - gfx_ctx_destroy(); - free(gl); - return NULL; - } - - return gl; -} - -static bool gl_alive(void *data) -{ - gl_t *gl = (gl_t*)data; - bool quit, resize; - - gfx_ctx_check_window(&quit, - &resize, &gl->win_width, &gl->win_height, - gl->frame_count); - - if (quit) - gl->quitting = true; - else if (resize) - gl->should_resize = true; - - return !gl->quitting; -} - -static bool gl_focus(void *data) -{ - (void)data; - return gfx_ctx_window_has_focus(); -} - -#ifdef HAVE_XML -static bool gl_xml_shader(void *data, const char *path) -{ - gl_t *gl = (gl_t*)data; - -#ifdef HAVE_FBO - gl_deinit_fbo(gl); - glBindTexture(GL_TEXTURE_2D, gl->texture[gl->tex_index]); -#endif - - gl_shader_deinit(); - - if (!gl_glsl_init(path)) - return false; - -#ifdef HAVE_FBO - // Set up render to texture again. - gl_init_fbo(gl, gl->tex_w, gl->tex_h); -#endif - - // Apparently need to set viewport for passes when we aren't using FBOs. - gl_shader_use(0); - gl_set_viewport(gl, gl->win_width, gl->win_height, false, true); - gl_shader_use(1); - gl_set_viewport(gl, gl->win_width, gl->win_height, false, true); - - return true; -} -#endif - -#ifndef HAVE_RGL -static void gl_viewport_size(void *data, unsigned *width, unsigned *height) -{ - (void)data; - - GLint vp[4]; - glGetIntegerv(GL_VIEWPORT, vp); - - *width = vp[2]; - *height = vp[3]; -} - -static bool gl_read_viewport(void *data, uint8_t *buffer) -{ - (void)data; - - GLint vp[4]; - glGetIntegerv(GL_VIEWPORT, vp); - - glPixelStorei(GL_PACK_ALIGNMENT, get_alignment(vp[2])); - glPixelStorei(GL_PACK_ROW_LENGTH, vp[2]); - - glReadPixels(vp[0], vp[1], - vp[2], vp[3], - GL_BGR, GL_UNSIGNED_BYTE, buffer); - - return true; -} -#endif - -#ifdef RARCH_CONSOLE -static void gl_start(void) -{ - video_info_t video_info = {0}; - - // Might have to supply correct values here. - video_info.vsync = g_settings.video.vsync; - video_info.force_aspect = false; - video_info.smooth = g_settings.video.smooth; - video_info.input_scale = 2; - video_info.fullscreen = true; - if (g_console.aspect_ratio_index == ASPECT_RATIO_CUSTOM) - { - video_info.width = g_console.viewports.custom_vp.width; - video_info.height = g_console.viewports.custom_vp.height; - } - driver.video_data = gl_init(&video_info, NULL, NULL); - -#ifdef HAVE_FBO - gfx_ctx_set_fbo(g_console.fbo_enabled); -#endif - - gfx_ctx_get_available_resolutions(); - -#ifdef HAVE_CG_MENU - gfx_ctx_menu_init(); -#endif -} - -static void gl_stop(void) -{ - void *data = driver.video_data; - driver.video_data = NULL; - gl_free(data); -} - -static void gl_restart(void) -{ -#ifdef HAVE_CG_MENU - bool should_menu_render; -#endif -#ifdef RARCH_CONSOLE - bool should_block_swap; -#endif - gl_t *gl = driver.video_data; - - if (!gl) - return; - -#ifdef RARCH_CONSOLE - should_block_swap = gl->block_swap; -#endif -#ifdef HAVE_CG_MENU - should_menu_render = gl->menu_render; -#endif - - gl_stop(); - gl_cg_invalidate_context(); - gl_start(); - -#ifdef HAVE_CG_MENU - gl->menu_render = should_menu_render; -#endif - - gl->frame_count = 0; - -#ifdef RARCH_CONSOLE - gl->block_swap = should_block_swap; - SET_TIMER_EXPIRATION(gl, 30); -#endif -} -#endif - -const video_driver_t video_gl = { - gl_init, - gl_frame, - gl_set_nonblock_state, - gl_alive, - gl_focus, - -#ifdef HAVE_XML - gl_xml_shader, -#else - NULL, -#endif - - gl_free, - "gles", - -#ifdef RARCH_CONSOLE - gl_start, - gl_stop, - gl_restart, -#endif - - gl_set_rotation, - -#ifndef HAVE_RGL - gl_viewport_size, - gl_read_viewport, -#else - NULL, - NULL, -#endif -}; - diff --git a/ps3/frontend/main.c b/ps3/frontend/main.c index 1a14e5b68f..d6cb4239c6 100644 --- a/ps3/frontend/main.c +++ b/ps3/frontend/main.c @@ -56,25 +56,15 @@ #include "menu.h" #define EMULATOR_CONTENT_DIR "SSNE10000" -#define EMULATOR_CORE_DIR "cores" #define CACHE_ID "ABCD12345" #define NP_POOL_SIZE (128*1024) static uint8_t np_pool[NP_POOL_SIZE]; -char systemDirPath[PATH_MAX]; -char usrDirPath[PATH_MAX]; char DEFAULT_PRESET_FILE[PATH_MAX]; -char DEFAULT_BORDER_FILE[PATH_MAX]; char DEFAULT_MENU_BORDER_FILE[PATH_MAX]; char PRESETS_DIR_PATH[PATH_MAX]; char INPUT_PRESETS_DIR_PATH[PATH_MAX]; -char BORDERS_DIR_PATH[PATH_MAX]; -char SHADERS_DIR_PATH[PATH_MAX]; -char LIBRETRO_DIR_PATH[PATH_MAX]; -char DEFAULT_SHADER_FILE[PATH_MAX]; -char DEFAULT_MENU_SHADER_FILE[PATH_MAX]; -char SYS_CONFIG_FILE[PATH_MAX]; char EMULATOR_CORE_SELF[PATH_MAX]; #ifdef HAVE_MULTIMAN char MULTIMAN_EXECUTABLE[PATH_MAX]; @@ -89,18 +79,18 @@ SYS_PROCESS_PARAM(1001, 0x200000) static void set_default_settings(void) { // g_settings - strlcpy(g_settings.cheat_database, usrDirPath, sizeof(g_settings.cheat_database)); + strlcpy(g_settings.cheat_database, default_paths.port_dir, sizeof(g_settings.cheat_database)); g_settings.rewind_enable = false; - strlcpy(g_settings.video.cg_shader_path, DEFAULT_SHADER_FILE, sizeof(g_settings.video.cg_shader_path)); + strlcpy(g_settings.video.cg_shader_path, default_paths.shader_file, sizeof(g_settings.video.cg_shader_path)); g_settings.video.fbo_scale_x = 2.0f; g_settings.video.fbo_scale_y = 2.0f; g_settings.video.render_to_texture = true; - strlcpy(g_settings.video.second_pass_shader, DEFAULT_SHADER_FILE, sizeof(g_settings.video.second_pass_shader)); + strlcpy(g_settings.video.second_pass_shader, default_paths.shader_file, sizeof(g_settings.video.second_pass_shader)); g_settings.video.second_pass_smooth = true; g_settings.video.smooth = true; g_settings.video.vsync = true; - strlcpy(g_settings.cheat_database, usrDirPath, sizeof(g_settings.cheat_database)); - strlcpy(g_settings.system_directory, systemDirPath, sizeof(g_settings.system_directory)); + strlcpy(g_settings.cheat_database, default_paths.port_dir, sizeof(g_settings.cheat_database)); + strlcpy(g_settings.system_directory, default_paths.system_dir, sizeof(g_settings.system_directory)); g_settings.video.msg_pos_x = 0.05f; g_settings.video.msg_pos_y = 0.90f; g_settings.video.aspect_ratio = -1.0f; @@ -122,8 +112,8 @@ static void set_default_settings(void) g_console.screen_orientation = ORIENTATION_NORMAL; g_console.current_resolution_id = 0; strlcpy(g_console.default_rom_startup_dir, "/", sizeof(g_console.default_rom_startup_dir)); - strlcpy(g_console.default_savestate_dir, usrDirPath, sizeof(g_console.default_savestate_dir)); - strlcpy(g_console.default_sram_dir, usrDirPath, sizeof(g_console.default_sram_dir)); + strlcpy(g_console.default_savestate_dir, default_paths.savestate_dir, sizeof(g_console.default_savestate_dir)); + strlcpy(g_console.default_sram_dir, default_paths.sram_dir, sizeof(g_console.default_sram_dir)); g_console.aspect_ratio_index = 0; g_console.menu_font_size = 1.0f; g_console.overscan_enable = false; @@ -242,13 +232,13 @@ static void get_environment_settings(int argc, char *argv[]) if((get_attributes & CELL_GAME_ATTRIBUTE_APP_HOME) == CELL_GAME_ATTRIBUTE_APP_HOME) RARCH_LOG("RetroArch was launched from host machine (APP_HOME).\n"); - ret = cellGameContentPermit(contentInfoPath, usrDirPath); + ret = cellGameContentPermit(contentInfoPath, default_paths.port_dir); #ifdef HAVE_MULTIMAN if(g_console.external_launcher_support == EXTERN_LAUNCHER_MULTIMAN) { snprintf(contentInfoPath, sizeof(contentInfoPath), "/dev_hdd0/game/%s", EMULATOR_CONTENT_DIR); - snprintf(usrDirPath, sizeof(usrDirPath), "/dev_hdd0/game/%s/USRDIR", EMULATOR_CONTENT_DIR); + snprintf(default_paths.port_dir, sizeof(default_paths.port_dir), "/dev_hdd0/game/%s/USRDIR", EMULATOR_CONTENT_DIR); } #endif @@ -260,23 +250,26 @@ static void get_environment_settings(int argc, char *argv[]) { RARCH_LOG("cellGameContentPermit() OK.\n"); RARCH_LOG("contentInfoPath : [%s].\n", contentInfoPath); - RARCH_LOG("usrDirPath : [%s].\n", usrDirPath); + RARCH_LOG("usrDirPath : [%s].\n", default_paths.port_dir); } - snprintf(systemDirPath, sizeof(systemDirPath), "%s/%s/system", usrDirPath, EMULATOR_CORE_DIR); + snprintf(default_paths.core_dir, sizeof(default_paths.core_dir), "%s/cores", default_paths.port_dir); + snprintf(default_paths.savestate_dir, sizeof(default_paths.savestate_dir), "%s/savestates", default_paths.core_dir); + snprintf(default_paths.sram_dir, sizeof(default_paths.sram_dir), "%s/sram", default_paths.core_dir); + + snprintf(default_paths.system_dir, sizeof(default_paths.system_dir), "%s/system", default_paths.core_dir); /* now we fill in all the variables */ - snprintf(DEFAULT_PRESET_FILE, sizeof(DEFAULT_PRESET_FILE), "%s/%s/presets/stock.conf", usrDirPath, EMULATOR_CORE_DIR); - snprintf(DEFAULT_BORDER_FILE, sizeof(DEFAULT_BORDER_FILE), "%s/%s/borders/Centered-1080p/mega-man-2.png", usrDirPath, EMULATOR_CORE_DIR); - snprintf(DEFAULT_MENU_BORDER_FILE, sizeof(DEFAULT_MENU_BORDER_FILE), "%s/%s/borders/Menu/main-menu.png", usrDirPath, EMULATOR_CORE_DIR); - snprintf(PRESETS_DIR_PATH, sizeof(PRESETS_DIR_PATH), "%s/%s/presets", usrDirPath, EMULATOR_CORE_DIR); + snprintf(DEFAULT_PRESET_FILE, sizeof(DEFAULT_PRESET_FILE), "%s/presets/stock.conf", default_paths.core_dir); + snprintf(default_paths.border_file, sizeof(default_paths.border_file), "%s/borders/Centered-1080p/mega-man-2.png", default_paths.core_dir); + snprintf(DEFAULT_MENU_BORDER_FILE, sizeof(DEFAULT_MENU_BORDER_FILE), "%s/borders/Menu/main-menu.png", default_paths.core_dir); + snprintf(PRESETS_DIR_PATH, sizeof(PRESETS_DIR_PATH), "%s/presets", default_paths.core_dir); snprintf(INPUT_PRESETS_DIR_PATH, sizeof(INPUT_PRESETS_DIR_PATH), "%s/input", PRESETS_DIR_PATH); - snprintf(LIBRETRO_DIR_PATH, sizeof(LIBRETRO_DIR_PATH), "%s/%s", usrDirPath, EMULATOR_CORE_DIR); - snprintf(BORDERS_DIR_PATH, sizeof(BORDERS_DIR_PATH), "%s/%s/borders", usrDirPath, EMULATOR_CORE_DIR); - snprintf(SHADERS_DIR_PATH, sizeof(SHADERS_DIR_PATH), "%s/%s/shaders", usrDirPath, EMULATOR_CORE_DIR); - snprintf(DEFAULT_SHADER_FILE, sizeof(DEFAULT_SHADER_FILE), "%s/%s/shaders/stock.cg", usrDirPath, EMULATOR_CORE_DIR); - snprintf(DEFAULT_MENU_SHADER_FILE, sizeof(DEFAULT_MENU_SHADER_FILE), "%s/%s/shaders/Borders/Menu/border-only-rarch.cg", usrDirPath, EMULATOR_CORE_DIR); - snprintf(SYS_CONFIG_FILE, sizeof(SYS_CONFIG_FILE), "%s/retroarch.cfg", usrDirPath); + snprintf(default_paths.border_dir, sizeof(default_paths.border_dir), "%s/borders", default_paths.core_dir); + snprintf(default_paths.shader_dir, sizeof(default_paths.shader_dir), "%s/shaders", default_paths.core_dir); + snprintf(default_paths.shader_file, sizeof(default_paths.shader_file), "%s/shaders/stock.cg", default_paths.core_dir); + snprintf(default_paths.menu_shader_file, sizeof(default_paths.menu_shader_file), "%s/shaders/Borders/Menu/border-only-rarch.cg", default_paths.core_dir); + snprintf(default_paths.config_file, sizeof(default_paths.config_file), "%s/retroarch.cfg", default_paths.port_dir); } g_extern.verbose = false; @@ -314,14 +307,14 @@ int main(int argc, char *argv[]) config_set_defaults(); char full_path[1024], tmp_path[1024]; - snprintf(full_path, sizeof(full_path), "%s/%s/CORE.SELF", usrDirPath, EMULATOR_CORE_DIR); - snprintf(tmp_path, sizeof(tmp_path), "%s/%s/", usrDirPath, EMULATOR_CORE_DIR); + snprintf(full_path, sizeof(full_path), "%s/CORE.SELF", default_paths.core_dir); + snprintf(tmp_path, sizeof(tmp_path), "%s/", default_paths.core_dir); - bool find_libretro_file = rarch_configure_libretro_core(full_path, tmp_path, LIBRETRO_DIR_PATH, - SYS_CONFIG_FILE, ".SELF"); + bool find_libretro_file = rarch_configure_libretro_core(full_path, tmp_path, default_paths.core_dir, + default_paths.config_file, ".SELF"); set_default_settings(); - rarch_config_load(SYS_CONFIG_FILE, LIBRETRO_DIR_PATH, ".SELF", find_libretro_file); + rarch_config_load(default_paths.config_file, default_paths.core_dir, ".SELF", find_libretro_file); init_libretro_sym(); #if(CELL_SDK_VERSION > 0x340000) @@ -367,7 +360,7 @@ int main(int argc, char *argv[]) RARCH_LOG("Started from multiMAN, will auto-start game.\n"); strlcpy(g_console.rom_path, argv[1], sizeof(g_console.rom_path)); rarch_settings_change(S_START_RARCH); - rarch_startup(SYS_CONFIG_FILE); + rarch_startup(default_paths.config_file); break; #endif default: @@ -390,7 +383,7 @@ begin_loop: else if(g_console.mode_switch == MODE_MENU) { menu_loop(); - rarch_startup(SYS_CONFIG_FILE); + rarch_startup(default_paths.config_file); } else goto begin_shutdown; @@ -398,8 +391,8 @@ begin_loop: goto begin_loop; begin_shutdown: - if(path_file_exists(SYS_CONFIG_FILE)) - rarch_config_save(SYS_CONFIG_FILE); + if(path_file_exists(default_paths.config_file)) + rarch_config_save(default_paths.config_file); if(g_console.emulator_initialized) rarch_main_deinit(); diff --git a/ps3/frontend/menu.c b/ps3/frontend/menu.c index c846f520e0..bd70101d00 100644 --- a/ps3/frontend/menu.c +++ b/ps3/frontend/menu.c @@ -104,13 +104,13 @@ static void set_setting_label(menu * menu_obj, unsigned currentsetting) case SETTING_SHADER: fill_pathname_base(fname, g_settings.video.cg_shader_path, sizeof(fname)); snprintf(items_generalsettings[currentsetting].setting_text, sizeof(items_generalsettings[currentsetting].setting_text), "%s", fname); - set_setting_label_color(strcmp(g_settings.video.cg_shader_path,DEFAULT_SHADER_FILE) == 0, + set_setting_label_color(strcmp(g_settings.video.cg_shader_path, default_paths.shader_file) == 0, currentsetting); break; case SETTING_SHADER_2: fill_pathname_base(fname, g_settings.video.second_pass_shader, sizeof(fname)); snprintf(items_generalsettings[currentsetting].setting_text, sizeof(items_generalsettings[currentsetting].setting_text), "%s", fname); - set_setting_label_color(strcmp(g_settings.video.second_pass_shader,DEFAULT_SHADER_FILE) == 0, + set_setting_label_color(strcmp(g_settings.video.second_pass_shader, default_paths.shader_file) == 0, currentsetting); break; case SETTING_FONT_SIZE: @@ -239,19 +239,19 @@ static void set_setting_label(menu * menu_obj, unsigned currentsetting) snprintf(items_generalsettings[currentsetting].setting_text, sizeof(items_generalsettings[currentsetting].setting_text), g_console.default_rom_startup_dir); break; case SETTING_PATH_SAVESTATES_DIRECTORY: - set_setting_label_color(!(strcmp(g_console.default_savestate_dir, usrDirPath)), currentsetting); + set_setting_label_color(!(strcmp(g_console.default_savestate_dir, default_paths.port_dir)), currentsetting); snprintf(items_generalsettings[currentsetting].setting_text, sizeof(items_generalsettings[currentsetting].setting_text), g_console.default_savestate_dir); break; case SETTING_PATH_SRAM_DIRECTORY: - set_setting_label_color(!(strcmp(g_console.default_sram_dir, usrDirPath)), currentsetting); + set_setting_label_color(!(strcmp(g_console.default_sram_dir, default_paths.port_dir)), currentsetting); snprintf(items_generalsettings[currentsetting].setting_text, sizeof(items_generalsettings[currentsetting].setting_text), g_console.default_sram_dir); break; case SETTING_PATH_CHEATS: - set_setting_label_color(!(strcmp(g_settings.cheat_database, usrDirPath)), currentsetting); + set_setting_label_color(!(strcmp(g_settings.cheat_database, default_paths.port_dir)), currentsetting); snprintf(items_generalsettings[currentsetting].setting_text, sizeof(items_generalsettings[currentsetting].setting_text), g_settings.cheat_database); break; case SETTING_PATH_SYSTEM: - set_setting_label_color(!(strcmp(g_settings.system_directory, systemDirPath)), currentsetting); + set_setting_label_color(!(strcmp(g_settings.system_directory, default_paths.system_dir)), currentsetting); snprintf(items_generalsettings[currentsetting].setting_text, sizeof(items_generalsettings[currentsetting].setting_text), g_settings.system_directory); break; case SETTING_ENABLE_SRAM_PATH: @@ -394,7 +394,7 @@ static void menu_stack_push(unsigned stack_idx, unsigned menu_id) menuStack[stack_idx].category_id = CATEGORY_FILEBROWSER; menu_stack_refresh(items_generalsettings, stack_idx); strlcpy(tmpBrowser.extensions, "self|SELF|bin|BIN", sizeof(tmpBrowser.extensions)); - filebrowser_set_root(&tmpBrowser, LIBRETRO_DIR_PATH); + filebrowser_set_root(&tmpBrowser, default_paths.core_dir); filebrowser_iterate(&tmpBrowser, FILEBROWSER_ACTION_RESET); break; case PRESET_CHOICE: @@ -427,7 +427,7 @@ static void menu_stack_push(unsigned stack_idx, unsigned menu_id) menuStack[stack_idx].category_id = CATEGORY_FILEBROWSER; menu_stack_refresh(items_generalsettings, stack_idx); strlcpy(tmpBrowser.extensions, "cg|CG", sizeof(tmpBrowser.extensions)); - filebrowser_set_root(&tmpBrowser, SHADERS_DIR_PATH); + filebrowser_set_root(&tmpBrowser, default_paths.shader_dir); filebrowser_iterate(&tmpBrowser, FILEBROWSER_ACTION_RESET); break; case BORDER_CHOICE: @@ -438,7 +438,7 @@ static void menu_stack_push(unsigned stack_idx, unsigned menu_id) menuStack[stack_idx].category_id = CATEGORY_FILEBROWSER; menu_stack_refresh(items_generalsettings, stack_idx); strlcpy(tmpBrowser.extensions, "png|PNG|jpg|JPG|JPEG|jpeg", sizeof(tmpBrowser.extensions)); - filebrowser_set_root(&tmpBrowser, BORDERS_DIR_PATH); + filebrowser_set_root(&tmpBrowser, default_paths.border_dir); filebrowser_iterate(&tmpBrowser, FILEBROWSER_ACTION_RESET); break; case PATH_DEFAULT_ROM_DIR_CHOICE: @@ -868,7 +868,7 @@ static void select_directory(void) } else if (input_state & (1 << RETRO_DEVICE_ID_JOYPAD_X)) { - strlcpy(path, usrDirPath, sizeof(path)); + strlcpy(path, default_paths.port_dir, sizeof(path)); switch(menu_id) { case PATH_SAVESTATES_DIR_CHOICE: @@ -1072,7 +1072,7 @@ static void producesettingentry(menu * menu_obj, unsigned switchvalue) if(input_state & (1 << RETRO_DEVICE_ID_JOYPAD_START)) { rarch_load_shader(1, NULL); - strlcpy(g_settings.video.cg_shader_path, DEFAULT_SHADER_FILE, sizeof(g_settings.video.cg_shader_path)); + strlcpy(g_settings.video.cg_shader_path, default_paths.shader_file, sizeof(g_settings.video.cg_shader_path)); menu_stack_refresh(items_generalsettings, menuStackindex); } break; @@ -1086,7 +1086,7 @@ static void producesettingentry(menu * menu_obj, unsigned switchvalue) if(input_state & (1 << RETRO_DEVICE_ID_JOYPAD_START)) { rarch_load_shader(2, NULL); - strlcpy(g_settings.video.second_pass_shader, DEFAULT_SHADER_FILE, sizeof(g_settings.video.second_pass_shader)); + strlcpy(g_settings.video.second_pass_shader, default_paths.shader_file, sizeof(g_settings.video.second_pass_shader)); menu_stack_refresh(items_generalsettings, menuStackindex); } break; @@ -1403,7 +1403,7 @@ static void producesettingentry(menu * menu_obj, unsigned switchvalue) } if(input_state & (1 << RETRO_DEVICE_ID_JOYPAD_START)) - strlcpy(g_console.default_savestate_dir, usrDirPath, sizeof(g_console.default_savestate_dir)); + strlcpy(g_console.default_savestate_dir, default_paths.savestate_dir, sizeof(g_console.default_savestate_dir)); break; case SETTING_PATH_SRAM_DIRECTORY: @@ -1414,7 +1414,7 @@ static void producesettingentry(menu * menu_obj, unsigned switchvalue) } if(input_state & (1 << RETRO_DEVICE_ID_JOYPAD_START)) - strlcpy(g_console.default_sram_dir, "", sizeof(g_console.default_sram_dir)); + strlcpy(g_console.default_sram_dir, default_paths.sram_dir, sizeof(g_console.default_sram_dir)); break; case SETTING_PATH_CHEATS: if((input_state & (1 << RETRO_DEVICE_ID_JOYPAD_LEFT)) || (input_state & (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT)) || (input_state & (1 << RETRO_DEVICE_ID_JOYPAD_B))) @@ -1424,7 +1424,7 @@ static void producesettingentry(menu * menu_obj, unsigned switchvalue) } if(input_state & (1 << RETRO_DEVICE_ID_JOYPAD_START)) - strlcpy(g_settings.cheat_database, usrDirPath, sizeof(g_settings.cheat_database)); + strlcpy(g_settings.cheat_database, default_paths.port_dir, sizeof(g_settings.cheat_database)); break; case SETTING_PATH_SYSTEM: if((input_state & (1 << RETRO_DEVICE_ID_JOYPAD_LEFT)) || (input_state & (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT)) || (input_state & (1 << RETRO_DEVICE_ID_JOYPAD_B))) @@ -1434,7 +1434,7 @@ static void producesettingentry(menu * menu_obj, unsigned switchvalue) } if(input_state & (1 << RETRO_DEVICE_ID_JOYPAD_START)) - strlcpy(g_settings.system_directory, systemDirPath, sizeof(g_settings.system_directory)); + strlcpy(g_settings.system_directory, default_paths.system_dir, sizeof(g_settings.system_directory)); break; case SETTING_ENABLE_SRAM_PATH: if((input_state & (1 << RETRO_DEVICE_ID_JOYPAD_LEFT)) || (input_state & (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT))) @@ -1464,8 +1464,8 @@ static void producesettingentry(menu * menu_obj, unsigned switchvalue) if((input_state & (1 << RETRO_DEVICE_ID_JOYPAD_LEFT)) || (input_state & (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT)) || (input_state & (1 << RETRO_DEVICE_ID_JOYPAD_B)) || (input_state & (1 << RETRO_DEVICE_ID_JOYPAD_START))) { strlcpy(g_console.default_rom_startup_dir, "/", sizeof(g_console.default_rom_startup_dir)); - strlcpy(g_console.default_savestate_dir, usrDirPath, sizeof(g_console.default_savestate_dir)); - strlcpy(g_settings.cheat_database, usrDirPath, sizeof(g_settings.cheat_database)); + strlcpy(g_console.default_savestate_dir, default_paths.port_dir, sizeof(g_console.default_savestate_dir)); + strlcpy(g_settings.cheat_database, default_paths.port_dir, sizeof(g_settings.cheat_database)); strlcpy(g_console.default_sram_dir, "", sizeof(g_console.default_sram_dir)); menu_stack_refresh(items_generalsettings, menuStackindex); diff --git a/ps3/frontend/shared.h b/ps3/frontend/shared.h index 3432973ba2..e1c572f06e 100644 --- a/ps3/frontend/shared.h +++ b/ps3/frontend/shared.h @@ -17,19 +17,10 @@ #ifndef _PS3_SHARED_H #define _PS3_SHARED_H -extern char usrDirPath[PATH_MAX]; -extern char systemDirPath[PATH_MAX]; extern char DEFAULT_PRESET_FILE[PATH_MAX]; -extern char DEFAULT_BORDER_FILE[PATH_MAX]; extern char DEFAULT_MENU_BORDER_FILE[PATH_MAX]; extern char PRESETS_DIR_PATH[PATH_MAX]; extern char INPUT_PRESETS_DIR_PATH[PATH_MAX]; -extern char BORDERS_DIR_PATH[PATH_MAX]; -extern char SHADERS_DIR_PATH[PATH_MAX]; -extern char DEFAULT_SHADER_FILE[PATH_MAX]; -extern char DEFAULT_MENU_SHADER_FILE[PATH_MAX]; -extern char LIBRETRO_DIR_PATH[PATH_MAX]; -extern char SYS_CONFIG_FILE[PATH_MAX]; extern char MULTIMAN_EXECUTABLE[PATH_MAX]; #endif diff --git a/ps3/pkg/USRDIR/cores/savestates/.empty b/ps3/pkg/USRDIR/cores/savestates/.empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/ps3/pkg/USRDIR/cores/sram/.empty b/ps3/pkg/USRDIR/cores/sram/.empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/xdk/frontend/main.c b/xdk/frontend/main.c index c200967f18..d0ed8a6edf 100644 --- a/xdk/frontend/main.c +++ b/xdk/frontend/main.c @@ -41,9 +41,6 @@ #include "../../file.h" #include "../../general.h" -char DEFAULT_SHADER_FILE[PATH_MAX]; -char SYS_CONFIG_FILE[PATH_MAX]; - int rarch_main(int argc, char *argv[]); #undef main @@ -52,11 +49,11 @@ static void set_default_settings (void) { //g_settings g_settings.rewind_enable = false; - strlcpy(g_settings.video.cg_shader_path, DEFAULT_SHADER_FILE, sizeof(g_settings.video.cg_shader_path)); + strlcpy(g_settings.video.cg_shader_path, default_paths.shader_file, sizeof(g_settings.video.cg_shader_path)); g_settings.video.fbo_scale_x = 2.0f; g_settings.video.fbo_scale_y = 2.0f; g_settings.video.render_to_texture = true; - strlcpy(g_settings.video.second_pass_shader, DEFAULT_SHADER_FILE, sizeof(g_settings.video.second_pass_shader)); + strlcpy(g_settings.video.second_pass_shader, default_paths.shader_file, sizeof(g_settings.video.second_pass_shader)); g_settings.video.second_pass_smooth = true; g_settings.video.smooth = true; g_settings.video.vsync = true; @@ -142,13 +139,13 @@ static void get_environment_settings (void) } #endif - strlcpy(DEFAULT_SHADER_FILE, "game:\\media\\shaders\\stock.cg", sizeof(DEFAULT_SHADER_FILE)); + strlcpy(default_paths.shader_file, "game:\\media\\shaders\\stock.cg", sizeof(default_paths.shader_file)); #ifdef _XBOX1 /* FIXME: Hardcoded */ - strlcpy(SYS_CONFIG_FILE, "D:\\retroarch.cfg", sizeof(SYS_CONFIG_FILE)); + strlcpy(default_paths.config_file, "D:\\retroarch.cfg", sizeof(default_paths.config_file)); strlcpy(g_settings.system_directory, "D:\\system\\", sizeof(g_settings.system_directory)); #else - strlcpy(SYS_CONFIG_FILE, "game:\\retroarch.cfg", sizeof(SYS_CONFIG_FILE)); + strlcpy(default_paths.config_file, "game:\\retroarch.cfg", sizeof(default_paths.config_file)); strlcpy(g_settings.system_directory, "game:\\system\\", sizeof(g_settings.system_directory)); #endif } @@ -159,10 +156,10 @@ static void configure_libretro(const char *path_prefix, const char * extension) snprintf(full_path, sizeof(full_path), "%sCORE%s", path_prefix, extension); bool find_libretro_file = rarch_configure_libretro_core(full_path, path_prefix, path_prefix, - SYS_CONFIG_FILE, extension); + default_paths.config_file, extension); set_default_settings(); - rarch_config_load(SYS_CONFIG_FILE, path_prefix, extension, find_libretro_file); + rarch_config_load(default_paths.config_file, path_prefix, extension, find_libretro_file); init_libretro_sym(); } @@ -279,7 +276,7 @@ begin_loop: else if(g_console.mode_switch == MODE_MENU) { menu_loop(); - rarch_startup(SYS_CONFIG_FILE); + rarch_startup(default_paths.config_file); } else goto begin_shutdown; @@ -287,8 +284,8 @@ begin_loop: goto begin_loop; begin_shutdown: - if(path_file_exists(SYS_CONFIG_FILE)) - rarch_config_save(SYS_CONFIG_FILE); + if(path_file_exists(default_paths.config_file)) + rarch_config_save(default_paths.config_file); menu_free(); #if defined(HAVE_D3D8) || defined(HAVE_D3D9) From 0fb0b26838786f15224fc8822c29f489763641b6 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Mon, 23 Jul 2012 18:29:41 +0200 Subject: [PATCH 20/51] (RARCH_CONSOLE) Clean up ZIP extraction error/warning messages --- console/retroarch_console.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/console/retroarch_console.c b/console/retroarch_console.c index 9c72d76ab4..b4069c65a0 100644 --- a/console/retroarch_console.c +++ b/console/retroarch_console.c @@ -118,7 +118,7 @@ static int rarch_extract_currentfile_in_zip(unzFile uf) if (err != UNZ_OK) { - RARCH_ERR("Error %d with ZIP file in unzGetCurrentFileInfo.\n", err); + RARCH_ERR("Error %d while trying to get ZIP file information.\n", err); return err; } @@ -126,7 +126,7 @@ static int rarch_extract_currentfile_in_zip(unzFile uf) void *buf = malloc(size_buf); if (!buf) { - RARCH_ERR("Error allocating memory\n"); + RARCH_ERR("Error allocating memory for ZIP extract operation.\n"); return UNZ_INTERNALERROR; } @@ -144,7 +144,7 @@ static int rarch_extract_currentfile_in_zip(unzFile uf) err = unzOpenCurrentFile(uf); if (err != UNZ_OK) - RARCH_ERR("Error %d with ZIP file in unzOpenCurrentFile.\n", err); + RARCH_ERR("Error %d while trying to open ZIP file.\n", err); else { /* success */ @@ -156,14 +156,14 @@ static int rarch_extract_currentfile_in_zip(unzFile uf) if (fout) { - RARCH_LOG("Extracting: %s\n", write_filename); + RARCH_LOG("Extracting: %s..\n", write_filename); do { err = unzReadCurrentFile(uf, buf, size_buf); if (err < 0) { - RARCH_ERR("error %d with ZIP file in unzReadCurrentFile.\n", err); + RARCH_ERR("Error %d while reading from ZIP file.\n", err); break; } @@ -171,7 +171,7 @@ static int rarch_extract_currentfile_in_zip(unzFile uf) { if (fwrite(buf, err, 1, fout) != 1) { - RARCH_ERR("Error in writing extracted file.\n"); + RARCH_ERR("Error while extracting file(s) from ZIP.\n"); err = UNZ_ERRNO; break; } @@ -186,7 +186,7 @@ static int rarch_extract_currentfile_in_zip(unzFile uf) { err = unzCloseCurrentFile (uf); if (err != UNZ_OK) - RARCH_ERR("Error %d with ZIP file in unzCloseCurrentFile.\n", err); + RARCH_ERR("Error %d while trying to close ZIP file.\n", err); } else unzCloseCurrentFile(uf); @@ -202,7 +202,7 @@ int rarch_extract_zipfile(const char *zip_path) unz_global_info gi; int err = unzGetGlobalInfo(uf, &gi); if (err != UNZ_OK) - RARCH_ERR("error %d with ZIP file in unzGetGlobalInfo \n",err); + RARCH_ERR("Error %d while trying to get ZIP file global info.\n",err); for (unsigned i = 0; i < gi.number_entry; i++) { @@ -214,7 +214,7 @@ int rarch_extract_zipfile(const char *zip_path) err = unzGoToNextFile(uf); if (err != UNZ_OK) { - RARCH_ERR("error %d with ZIP file in unzGoToNextFile\n",err); + RARCH_ERR("Error %d while trying to go to the next file in the ZIP archive.\n",err); break; } } @@ -600,10 +600,10 @@ struct aspect_ratio_elem aspectratio_lut[ASPECT_RATIO_END] = { char rotation_lut[ASPECT_RATIO_END][PATH_MAX] = { - "Normal", - "Vertical", - "Flipped", - "Flipped Rotated" + "Normal", + "Vertical", + "Flipped", + "Flipped Rotated" }; void rarch_set_auto_viewport(unsigned width, unsigned height) @@ -888,7 +888,7 @@ void rarch_config_load(const char * conf_name, const char * libretro_dir_path, c CONFIG_GET_BOOL(video.render_to_texture, "video_render_to_texture"); CONFIG_GET_BOOL(video.second_pass_smooth, "video_second_pass_smooth"); #endif -#ifdef _XBOX +#ifdef _XBOX360 CONFIG_GET_BOOL_CONSOLE(gamma_correction_enable, "gamma_correction_enable"); CONFIG_GET_INT_CONSOLE(color_format, "color_format"); #endif From 7a7488673042fdfbe2867d54108cb026818652b7 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 23 Jul 2012 18:52:58 +0200 Subject: [PATCH 21/51] (Xbox 1) Split up Xbox 1-specific code into xbox1/frontend/menu.cpp --- 360/frontend-xdk/menu.h | 4 -- console/griffin/griffin.c | 2 + xbox1/frontend/menu.cpp | 89 +++++++++++++++++++++++++++++++++++++++ xdk/frontend/main.c | 80 +++-------------------------------- xdk/menu_shared.h | 24 +++++++++++ 5 files changed, 121 insertions(+), 78 deletions(-) create mode 100644 xbox1/frontend/menu.cpp create mode 100644 xdk/menu_shared.h diff --git a/360/frontend-xdk/menu.h b/360/frontend-xdk/menu.h index be612e44eb..055efe2257 100644 --- a/360/frontend-xdk/menu.h +++ b/360/frontend-xdk/menu.h @@ -220,8 +220,4 @@ class CRetroArchControls: public CXuiSceneImpl extern CRetroArch app; #endif -int menu_init (void); -void menu_free (void); -void menu_loop (void); - #endif diff --git a/console/griffin/griffin.c b/console/griffin/griffin.c index 2cd9fc6b4d..c3c213757e 100644 --- a/console/griffin/griffin.c +++ b/console/griffin/griffin.c @@ -259,6 +259,8 @@ MENU ============================================================ */ #if defined(_XBOX360) #include "../../360/frontend-xdk/menu.cpp" +#elif defined(_XBOX1) +#include "../../xbox1/frontend/menu.cpp" #elif defined(GEKKO) #include "../../wii/frontend/rgui.c" #include "../../wii/frontend/list.c" diff --git a/xbox1/frontend/menu.cpp b/xbox1/frontend/menu.cpp new file mode 100644 index 0000000000..de9b223efc --- /dev/null +++ b/xbox1/frontend/menu.cpp @@ -0,0 +1,89 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2012 - Hans-Kristian Arntzen + * Copyright (C) 2011-2012 - Daniel De Matteis + * + * RetroArch 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. + * + * RetroArch 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 RetroArch. + * If not, see . + */ + +#include "../../xbox1/RetroLaunch/Global.h" +#include "../../xbox1/RetroLaunch/IniFile.h" +#include "../../xbox1/RetroLaunch/IoSupport.h" +#include "../../xbox1/RetroLaunch/Input.h" +#include "../../xbox1/RetroLaunch/Debug.h" +#include "../../xbox1/RetroLaunch/Font.h" +#include "../../xbox1/RetroLaunch/MenuManager.h" +#include "../../xbox1/RetroLaunch/RomList.h" + +bool g_bExit = false; + +int menu_init(void) +{ + g_debug.Print("Starting RetroLaunch\n"); + + // Set file cache size + XSetFileCacheSize(8 * 1024 * 1024); + + // Mount drives + g_IOSupport.Mount("A:", "cdrom0"); + g_IOSupport.Mount("E:", "Harddisk0\\Partition1"); + g_IOSupport.Mount("Z:", "Harddisk0\\Partition2"); + g_IOSupport.Mount("F:", "Harddisk0\\Partition6"); + g_IOSupport.Mount("G:", "Harddisk0\\Partition7"); + + // Get RetroArch's native d3d device + + // Parse ini file for settings + g_iniFile.CheckForIniEntry(); + + // Load the rom list if it isn't already loaded + if (!g_romList.IsLoaded()) + g_romList.Load(); + + // Init input here + g_input.Create(); + + // Load the font here + g_font.Create(); + + // Build menu here (Menu state -> Main Menu) + g_menuManager.Create(); + + g_console.mode_switch = MODE_MENU; + + return 0; +} + +void menu_free(void) {} + +void menu_loop(void) +{ + xdk_d3d_video_t *d3d = (xdk_d3d_video_t*)driver.video_data; + //rarch_console_load_game("D:\\ssf2x.gba"); + + // Loop the app + while (!g_bExit) + { + d3d->d3d_render_device->Clear(0, NULL, D3DCLEAR_TARGET, + D3DCOLOR_XRGB(0, 0, 0), + 1.0f, 0); + + d3d->d3d_render_device->BeginScene(); + d3d->d3d_render_device->SetFlickerFilter(g_iniFile.m_currentIniEntry.dwFlickerFilter); + d3d->d3d_render_device->SetSoftDisplayFilter(g_iniFile.m_currentIniEntry.bSoftDisplayFilter); + + g_input.GetInput(); + g_menuManager.Update(); + + d3d->d3d_render_device->EndScene(); + d3d->d3d_render_device->Present(NULL, NULL, NULL, NULL); + } +} diff --git a/xdk/frontend/main.c b/xdk/frontend/main.c index d0ed8a6edf..af27ba5593 100644 --- a/xdk/frontend/main.c +++ b/xdk/frontend/main.c @@ -20,6 +20,8 @@ #include #include +#include "../../xdk/menu_shared.h" + #ifdef _XBOX360 #include #include "../../360/frontend-xdk/menu.h" @@ -49,11 +51,13 @@ static void set_default_settings (void) { //g_settings g_settings.rewind_enable = false; +#ifdef _XBOX360 strlcpy(g_settings.video.cg_shader_path, default_paths.shader_file, sizeof(g_settings.video.cg_shader_path)); + strlcpy(g_settings.video.second_pass_shader, default_paths.shader_file, sizeof(g_settings.video.second_pass_shader)); +#endif g_settings.video.fbo_scale_x = 2.0f; g_settings.video.fbo_scale_y = 2.0f; g_settings.video.render_to_texture = true; - strlcpy(g_settings.video.second_pass_shader, default_paths.shader_file, sizeof(g_settings.video.second_pass_shader)); g_settings.video.second_pass_smooth = true; g_settings.video.smooth = true; g_settings.video.vsync = true; @@ -139,12 +143,12 @@ static void get_environment_settings (void) } #endif - strlcpy(default_paths.shader_file, "game:\\media\\shaders\\stock.cg", sizeof(default_paths.shader_file)); #ifdef _XBOX1 /* FIXME: Hardcoded */ strlcpy(default_paths.config_file, "D:\\retroarch.cfg", sizeof(default_paths.config_file)); strlcpy(g_settings.system_directory, "D:\\system\\", sizeof(g_settings.system_directory)); #else + strlcpy(default_paths.shader_file, "game:\\media\\shaders\\stock.cg", sizeof(default_paths.shader_file)); strlcpy(default_paths.config_file, "game:\\retroarch.cfg", sizeof(default_paths.config_file)); strlcpy(g_settings.system_directory, "game:\\system\\", sizeof(g_settings.system_directory)); #endif @@ -163,78 +167,6 @@ static void configure_libretro(const char *path_prefix, const char * extension) init_libretro_sym(); } -#ifdef _XBOX1 -#include "../../xbox1/RetroLaunch/Global.h" -#include "../../xbox1/RetroLaunch/IniFile.h" -#include "../../xbox1/RetroLaunch/IoSupport.h" -#include "../../xbox1/RetroLaunch/Input.h" -#include "../../xbox1/RetroLaunch/Debug.h" -#include "../../xbox1/RetroLaunch/Font.h" -#include "../../xbox1/RetroLaunch/MenuManager.h" -#include "../../xbox1/RetroLaunch/RomList.h" - -bool g_bExit = false; - -static void menu_init(void) -{ - g_debug.Print("Starting RetroLaunch\n"); - - // Set file cache size - XSetFileCacheSize(8 * 1024 * 1024); - - // Mount drives - g_IOSupport.Mount("A:", "cdrom0"); - g_IOSupport.Mount("E:", "Harddisk0\\Partition1"); - g_IOSupport.Mount("Z:", "Harddisk0\\Partition2"); - g_IOSupport.Mount("F:", "Harddisk0\\Partition6"); - g_IOSupport.Mount("G:", "Harddisk0\\Partition7"); - - // Get RetroArch's native d3d device - - // Parse ini file for settings - g_iniFile.CheckForIniEntry(); - - // Load the rom list if it isn't already loaded - if (!g_romList.IsLoaded()) { - g_romList.Load(); - } - - // Init input here - g_input.Create(); - - // Load the font here - g_font.Create(); - - // Build menu here (Menu state -> Main Menu) - g_menuManager.Create(); - - g_console.mode_switch = MODE_MENU; -} - -static void menu_free(void) {} -static void menu_loop(void) -{ - xdk_d3d_video_t *d3d = (xdk_d3d_video_t*)driver.video_data; - //rarch_console_load_game("D:\\ssf2x.gba"); - // Loop the app - while (!g_bExit) - { - d3d->d3d_render_device->Clear(0, NULL, D3DCLEAR_TARGET, - D3DCOLOR_XRGB(0, 0, 0), - 1.0f, 0); - - d3d->d3d_render_device->BeginScene(); - d3d->d3d_render_device->SetFlickerFilter(g_iniFile.m_currentIniEntry.dwFlickerFilter); - d3d->d3d_render_device->SetSoftDisplayFilter(g_iniFile.m_currentIniEntry.bSoftDisplayFilter); - - g_input.GetInput(); - g_menuManager.Update(); - - d3d->d3d_render_device->EndScene(); - d3d->d3d_render_device->Present(NULL, NULL, NULL, NULL); - } -} -#endif int main(int argc, char *argv[]) { diff --git a/xdk/menu_shared.h b/xdk/menu_shared.h new file mode 100644 index 0000000000..9487fea619 --- /dev/null +++ b/xdk/menu_shared.h @@ -0,0 +1,24 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2012 - Hans-Kristian Arntzen + * Copyright (C) 2011-2012 - Daniel De Matteis + * + * RetroArch 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. + * + * RetroArch 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 RetroArch. + * If not, see . + */ + +#ifndef _XDK_MENU_SHARED_H +#define _XDK_MENU_SHARED_H + +int menu_init (void); +void menu_free (void); +void menu_loop (void); + +#endif From 463b43724cecea11b0b661610b6725546324d695 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Tue, 24 Jul 2012 00:15:07 +0200 Subject: [PATCH 22/51] (PS3) Added entries to default_paths --- console/retroarch_console.h | 6 ++++++ gfx/context/ps3_ctx.c | 3 +-- ps3/frontend/main.c | 25 +++++++------------------ ps3/frontend/menu.c | 15 +++++++-------- ps3/frontend/shared.h | 26 -------------------------- 5 files changed, 21 insertions(+), 54 deletions(-) delete mode 100644 ps3/frontend/shared.h diff --git a/console/retroarch_console.h b/console/retroarch_console.h index 130ad992cf..e3d5f18eb9 100644 --- a/console/retroarch_console.h +++ b/console/retroarch_console.h @@ -136,10 +136,16 @@ enum ============================================================ */ typedef struct { + char menu_border_file[PATH_MAX]; char border_file[PATH_MAX]; char border_dir[PATH_MAX]; + char cgp_dir[PATH_MAX]; char config_file[PATH_MAX]; char core_dir[PATH_MAX]; + char input_presets_dir[PATH_MAX]; +#ifdef HAVE_MULTIMAN + char multiman_self_file[PATH_MAX]; +#endif char port_dir[PATH_MAX]; char savestate_dir[PATH_MAX]; #if defined(HAVE_CG) || defined(HAVE_HLSL) || defined(HAVE_GLSL) diff --git a/gfx/context/ps3_ctx.c b/gfx/context/ps3_ctx.c index 44e1e55cbd..3d4b307cc2 100644 --- a/gfx/context/ps3_ctx.c +++ b/gfx/context/ps3_ctx.c @@ -26,7 +26,6 @@ #include "../gl_common.h" #include "../image.h" -#include "../../ps3/frontend/shared.h" #include "ps3_ctx.h" @@ -137,7 +136,7 @@ bool gfx_ctx_menu_init(void) glGenTextures(1, &gl->menu_texture_id); RARCH_LOG("Loading texture image for menu...\n"); - if (!texture_image_load(DEFAULT_MENU_BORDER_FILE, &menu_texture)) + if (!texture_image_load(default_paths.menu_border_file, &menu_texture)) { RARCH_ERR("Failed to load texture image for menu.\n"); return false; diff --git a/ps3/frontend/main.c b/ps3/frontend/main.c index d6cb4239c6..785f3b55b9 100644 --- a/ps3/frontend/main.c +++ b/ps3/frontend/main.c @@ -51,8 +51,6 @@ #include "../../general.h" #include "../../file.h" -#include "shared.h" - #include "menu.h" #define EMULATOR_CONTENT_DIR "SSNE10000" @@ -61,14 +59,6 @@ #define NP_POOL_SIZE (128*1024) static uint8_t np_pool[NP_POOL_SIZE]; -char DEFAULT_PRESET_FILE[PATH_MAX]; -char DEFAULT_MENU_BORDER_FILE[PATH_MAX]; -char PRESETS_DIR_PATH[PATH_MAX]; -char INPUT_PRESETS_DIR_PATH[PATH_MAX]; -char EMULATOR_CORE_SELF[PATH_MAX]; -#ifdef HAVE_MULTIMAN -char MULTIMAN_EXECUTABLE[PATH_MAX]; -#endif int rarch_main(int argc, char *argv[]); @@ -185,16 +175,16 @@ static void get_environment_settings(int argc, char *argv[]) if(argc > 1) { /* launched from external launcher */ - strlcpy(MULTIMAN_EXECUTABLE, argv[2], sizeof(MULTIMAN_EXECUTABLE)); + strlcpy(default_paths.multiman_self_file, argv[2], sizeof(default_paths.multiman_self_file)); } else { /* not launched from external launcher, set default path */ - strlcpy(MULTIMAN_EXECUTABLE, "/dev_hdd0/game/BLES80608/USRDIR/RELOAD.SELF", - sizeof(MULTIMAN_EXECUTABLE)); + strlcpy(default_paths.multiman_self_file, "/dev_hdd0/game/BLES80608/USRDIR/RELOAD.SELF", + sizeof(default_paths.multiman_self_file)); } - if(path_file_exists(MULTIMAN_EXECUTABLE) && argc > 1 && path_file_exists(argv[1])) + if(path_file_exists(default_paths.multiman_self_file) && argc > 1 && path_file_exists(argv[1])) { g_console.external_launcher_support = EXTERN_LAUNCHER_MULTIMAN; RARCH_LOG("Started from multiMAN, auto-game start enabled.\n"); @@ -260,11 +250,10 @@ static void get_environment_settings(int argc, char *argv[]) snprintf(default_paths.system_dir, sizeof(default_paths.system_dir), "%s/system", default_paths.core_dir); /* now we fill in all the variables */ - snprintf(DEFAULT_PRESET_FILE, sizeof(DEFAULT_PRESET_FILE), "%s/presets/stock.conf", default_paths.core_dir); snprintf(default_paths.border_file, sizeof(default_paths.border_file), "%s/borders/Centered-1080p/mega-man-2.png", default_paths.core_dir); - snprintf(DEFAULT_MENU_BORDER_FILE, sizeof(DEFAULT_MENU_BORDER_FILE), "%s/borders/Menu/main-menu.png", default_paths.core_dir); - snprintf(PRESETS_DIR_PATH, sizeof(PRESETS_DIR_PATH), "%s/presets", default_paths.core_dir); - snprintf(INPUT_PRESETS_DIR_PATH, sizeof(INPUT_PRESETS_DIR_PATH), "%s/input", PRESETS_DIR_PATH); + snprintf(default_paths.menu_border_file, sizeof(default_paths.menu_border_file), "%s/borders/Menu/main-menu.png", default_paths.core_dir); + snprintf(default_paths.cgp_dir, sizeof(default_paths.cgp_dir), "%s/presets", default_paths.core_dir); + snprintf(default_paths.input_presets_dir, sizeof(default_paths.input_presets_dir), "%s/input", default_paths.cgp_dir); snprintf(default_paths.border_dir, sizeof(default_paths.border_dir), "%s/borders", default_paths.core_dir); snprintf(default_paths.shader_dir, sizeof(default_paths.shader_dir), "%s/shaders", default_paths.core_dir); snprintf(default_paths.shader_file, sizeof(default_paths.shader_file), "%s/shaders/stock.cg", default_paths.core_dir); diff --git a/ps3/frontend/menu.c b/ps3/frontend/menu.c index bd70101d00..004a13fa79 100644 --- a/ps3/frontend/menu.c +++ b/ps3/frontend/menu.c @@ -34,7 +34,6 @@ #include "../../gfx/context/ps3_ctx.h" #include "../../gfx/shader_cg.h" -#include "shared.h" #include "../../file.h" #include "../../general.h" @@ -97,7 +96,7 @@ static void set_setting_label(menu * menu_obj, unsigned currentsetting) snprintf(items_generalsettings[currentsetting].setting_text, sizeof(items_generalsettings[currentsetting].setting_text), ps3_get_resolution_label(g_console.supported_resolutions[g_console.current_resolution_index])); break; case SETTING_SHADER_PRESETS: - set_setting_label_color(g_console.cgp_path == DEFAULT_PRESET_FILE, currentsetting); + set_setting_label_color(true, currentsetting); fill_pathname_base(fname, g_console.cgp_path, sizeof(fname)); snprintf(items_generalsettings[currentsetting].setting_text, sizeof(items_generalsettings[currentsetting].setting_text), fname); break; @@ -405,7 +404,7 @@ static void menu_stack_push(unsigned stack_idx, unsigned menu_id) menuStack[stack_idx].category_id = CATEGORY_FILEBROWSER; menu_stack_refresh(items_generalsettings, stack_idx); strlcpy(tmpBrowser.extensions, "cgp|CGP", sizeof(tmpBrowser.extensions)); - filebrowser_set_root(&tmpBrowser, PRESETS_DIR_PATH); + filebrowser_set_root(&tmpBrowser, default_paths.cgp_dir); filebrowser_iterate(&tmpBrowser, FILEBROWSER_ACTION_RESET); break; case INPUT_PRESET_CHOICE: @@ -416,7 +415,7 @@ static void menu_stack_push(unsigned stack_idx, unsigned menu_id) menuStack[stack_idx].category_id = CATEGORY_FILEBROWSER; menu_stack_refresh(items_generalsettings, stack_idx); strlcpy(tmpBrowser.extensions, "cfg|CFG", sizeof(tmpBrowser.extensions)); - filebrowser_set_root(&tmpBrowser, INPUT_PRESETS_DIR_PATH); + filebrowser_set_root(&tmpBrowser, default_paths.input_presets_dir); filebrowser_iterate(&tmpBrowser, FILEBROWSER_ACTION_RESET); break; case SHADER_CHOICE: @@ -952,10 +951,10 @@ static void rarch_filename_input_and_save (unsigned filename_type) case CONFIG_FILE: break; case SHADER_PRESET_FILE: - snprintf(filepath, sizeof(filepath), "%s/%s.cgp", PRESETS_DIR_PATH, filename_tmp); + snprintf(filepath, sizeof(filepath), "%s/%s.cgp", default_paths.cgp_dir, filename_tmp); break; case INPUT_PRESET_FILE: - snprintf(filepath, sizeof(filepath), "%s/%s.cfg", INPUT_PRESETS_DIR_PATH, filename_tmp); + snprintf(filepath, sizeof(filepath), "%s/%s.cfg", default_paths.input_presets_dir, filename_tmp); break; } @@ -1988,9 +1987,9 @@ static void ingame_menu(void) case MENU_ITEM_RETURN_TO_MULTIMAN: if(input_state & (1 << RETRO_DEVICE_ID_JOYPAD_B)) { - if(path_file_exists(MULTIMAN_EXECUTABLE)) + if(path_file_exists(default_paths.multiman_self_file)) { - strlcpy(g_console.launch_app_on_exit, MULTIMAN_EXECUTABLE, + strlcpy(g_console.launch_app_on_exit, default_paths.multiman_self_file, sizeof(g_console.launch_app_on_exit)); rarch_settings_change(S_RETURN_TO_DASHBOARD); diff --git a/ps3/frontend/shared.h b/ps3/frontend/shared.h deleted file mode 100644 index e1c572f06e..0000000000 --- a/ps3/frontend/shared.h +++ /dev/null @@ -1,26 +0,0 @@ -/* RetroArch - A frontend for libretro. - * Copyright (C) 2010-2012 - Hans-Kristian Arntzen - * Copyright (C) 2011-2012 - Daniel De Matteis - * - * RetroArch 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. - * - * RetroArch 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 RetroArch. - * If not, see . - */ - -#ifndef _PS3_SHARED_H -#define _PS3_SHARED_H - -extern char DEFAULT_PRESET_FILE[PATH_MAX]; -extern char DEFAULT_MENU_BORDER_FILE[PATH_MAX]; -extern char PRESETS_DIR_PATH[PATH_MAX]; -extern char INPUT_PRESETS_DIR_PATH[PATH_MAX]; -extern char MULTIMAN_EXECUTABLE[PATH_MAX]; - -#endif From 83ae89dc4c19695589a9116f5a0d892d4e3cf5b8 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Tue, 24 Jul 2012 09:57:34 +0200 Subject: [PATCH 23/51] (RARCH_CONSOLE) Create more helper functions for RARCH_CONSOLE --- console/console_settings.c | 73 +++++++++++++++++++++++++++++++++++++ console/console_settings.h | 1 + console/libretro_mgmt.c | 13 +++++++ console/libretro_mgmt.h | 1 + console/retroarch_console.h | 2 + ps3/frontend/main.c | 69 ++--------------------------------- xdk/frontend/main.c | 68 +++------------------------------- 7 files changed, 99 insertions(+), 128 deletions(-) diff --git a/console/console_settings.c b/console/console_settings.c index 63cd2fab83..d494e40611 100644 --- a/console/console_settings.c +++ b/console/console_settings.c @@ -295,3 +295,76 @@ void rarch_settings_create_menu_item_label(char * str, unsigned setting, size_t break; } } + +void rarch_settings_set_default (void) +{ + // g_settings + g_settings.rewind_enable = false; + strlcpy(g_settings.cheat_database, default_paths.port_dir, sizeof(g_settings.cheat_database)); + +#if defined(HAVE_CG) || defined(HAVE_HLSL) || defined(HAVE_GLSL) + strlcpy(g_settings.video.cg_shader_path, default_paths.shader_file, sizeof(g_settings.video.cg_shader_path)); + strlcpy(g_settings.video.second_pass_shader, default_paths.shader_file, sizeof(g_settings.video.second_pass_shader)); + g_settings.video.second_pass_smooth = true; +#endif + +#ifdef HAVE_FBO + g_settings.video.fbo_scale_x = 2.0f; + g_settings.video.fbo_scale_y = 2.0f; +#endif + + g_settings.video.render_to_texture = true; + g_settings.video.smooth = true; + g_settings.video.vsync = true; + + strlcpy(g_settings.system_directory, default_paths.system_dir, sizeof(g_settings.system_directory)); + + g_settings.video.msg_pos_x = 0.05f; + g_settings.video.msg_pos_y = 0.90f; + g_settings.video.aspect_ratio = -1.0f; + + rarch_input_set_controls_default(); + + // g_console + g_console.block_config_read = true; + g_console.frame_advance_enable = false; + g_console.emulator_initialized = 0; + g_console.screenshots_enable = true; + g_console.throttle_enable = true; + g_console.initialize_rarch_enable = false; + g_console.triple_buffering_enable = true; + g_console.default_savestate_dir_enable = false; + g_console.default_sram_dir_enable = false; + +#ifdef HAVE_FBO + g_console.fbo_enabled = true; +#else + g_console.fbo_enabled = false; +#endif + + g_console.mode_switch = MODE_MENU; + g_console.screen_orientation = ORIENTATION_NORMAL; + g_console.current_resolution_id = 0; + strlcpy(g_console.default_rom_startup_dir, default_paths.filesystem_root_dir, sizeof(g_console.default_rom_startup_dir)); + strlcpy(g_console.default_savestate_dir, default_paths.savestate_dir, sizeof(g_console.default_savestate_dir)); + strlcpy(g_console.default_sram_dir, default_paths.sram_dir, sizeof(g_console.default_sram_dir)); + g_console.aspect_ratio_index = 0; + g_console.menu_font_size = 1.0f; + g_console.overscan_enable = false; + g_console.overscan_amount = 0.0f; + g_console.sound_mode = SOUND_MODE_NORMAL; + g_console.viewports.custom_vp.width = 0; + g_console.viewports.custom_vp.height = 0; + g_console.viewports.custom_vp.x = 0; + g_console.viewports.custom_vp.y = 0; + g_console.custom_bgm_enable = true; + g_console.info_msg_enable = true; +#ifdef _XBOX360 + g_console.color_format = 0; +#endif + + // g_extern + g_extern.state_slot = 0; + g_extern.audio_data.mute = 0; + g_extern.verbose = true; +} diff --git a/console/console_settings.h b/console/console_settings.h index 824ce68df0..a7022cfe32 100644 --- a/console/console_settings.h +++ b/console/console_settings.h @@ -105,6 +105,7 @@ enum void rarch_settings_change(unsigned setting); void rarch_settings_default(unsigned setting); void rarch_settings_msg(unsigned setting, unsigned delay); +void rarch_settings_set_default (void); void rarch_settings_create_menu_item_label(char * str, unsigned setting, size_t size); void rarch_settings_create_menu_item_label_w(wchar_t *strwbuf, unsigned setting, size_t size); diff --git a/console/libretro_mgmt.c b/console/libretro_mgmt.c index 45aca72c18..3dd0ef9958 100644 --- a/console/libretro_mgmt.c +++ b/console/libretro_mgmt.c @@ -139,3 +139,16 @@ void rarch_manage_libretro_set_first_file(char *first_file, size_t size_of_first end: dir_list_free(dir_list); } + +void rarch_configure_libretro(const char *path_prefix, const char * extension) +{ + char full_path[1024]; + snprintf(full_path, sizeof(full_path), "%sCORE%s", path_prefix, extension); + + bool find_libretro_file = rarch_configure_libretro_core(full_path, path_prefix, path_prefix, + default_paths.config_file, extension); + + rarch_settings_set_default(); + rarch_config_load(default_paths.config_file, path_prefix, extension, find_libretro_file); + init_libretro_sym(); +} diff --git a/console/libretro_mgmt.h b/console/libretro_mgmt.h index 0ec47db851..936f31106b 100644 --- a/console/libretro_mgmt.h +++ b/console/libretro_mgmt.h @@ -30,5 +30,6 @@ enum void rarch_manage_libretro_set_first_file(char *first_file, size_t size_of_first_file, const char *libretro_path, const char * exe_ext); bool rarch_configure_libretro_core(const char *full_path, const char *tmp_path, const char *libretro_path, const char *config_path, const char *extension); +void rarch_configure_libretro(const char *path_prefix, const char * extension); #endif diff --git a/console/retroarch_console.h b/console/retroarch_console.h index e3d5f18eb9..cb8184cbda 100644 --- a/console/retroarch_console.h +++ b/console/retroarch_console.h @@ -142,6 +142,8 @@ typedef struct char cgp_dir[PATH_MAX]; char config_file[PATH_MAX]; char core_dir[PATH_MAX]; + char executable_extension[PATH_MAX]; + char filesystem_root_dir[PATH_MAX]; char input_presets_dir[PATH_MAX]; #ifdef HAVE_MULTIMAN char multiman_self_file[PATH_MAX]; diff --git a/ps3/frontend/main.c b/ps3/frontend/main.c index 785f3b55b9..fa15f3ddf5 100644 --- a/ps3/frontend/main.c +++ b/ps3/frontend/main.c @@ -66,62 +66,6 @@ SYS_PROCESS_PARAM(1001, 0x200000) #undef main -static void set_default_settings(void) -{ - // g_settings - strlcpy(g_settings.cheat_database, default_paths.port_dir, sizeof(g_settings.cheat_database)); - g_settings.rewind_enable = false; - strlcpy(g_settings.video.cg_shader_path, default_paths.shader_file, sizeof(g_settings.video.cg_shader_path)); - g_settings.video.fbo_scale_x = 2.0f; - g_settings.video.fbo_scale_y = 2.0f; - g_settings.video.render_to_texture = true; - strlcpy(g_settings.video.second_pass_shader, default_paths.shader_file, sizeof(g_settings.video.second_pass_shader)); - g_settings.video.second_pass_smooth = true; - g_settings.video.smooth = true; - g_settings.video.vsync = true; - strlcpy(g_settings.cheat_database, default_paths.port_dir, sizeof(g_settings.cheat_database)); - strlcpy(g_settings.system_directory, default_paths.system_dir, sizeof(g_settings.system_directory)); - g_settings.video.msg_pos_x = 0.05f; - g_settings.video.msg_pos_y = 0.90f; - g_settings.video.aspect_ratio = -1.0f; - - rarch_input_set_controls_default(); - - // g_console - g_console.block_config_read = true; - g_console.frame_advance_enable = false; - g_console.emulator_initialized = 0; - g_console.screenshots_enable = true; - g_console.throttle_enable = true; - g_console.initialize_rarch_enable = false; - g_console.triple_buffering_enable = true; - g_console.default_savestate_dir_enable = false; - g_console.default_sram_dir_enable = false; - g_console.fbo_enabled = true; - g_console.mode_switch = MODE_MENU; - g_console.screen_orientation = ORIENTATION_NORMAL; - g_console.current_resolution_id = 0; - strlcpy(g_console.default_rom_startup_dir, "/", sizeof(g_console.default_rom_startup_dir)); - strlcpy(g_console.default_savestate_dir, default_paths.savestate_dir, sizeof(g_console.default_savestate_dir)); - strlcpy(g_console.default_sram_dir, default_paths.sram_dir, sizeof(g_console.default_sram_dir)); - g_console.aspect_ratio_index = 0; - g_console.menu_font_size = 1.0f; - g_console.overscan_enable = false; - g_console.overscan_amount = 0.0f; - g_console.sound_mode = SOUND_MODE_NORMAL; - g_console.viewports.custom_vp.width = 0; - g_console.viewports.custom_vp.height = 0; - g_console.viewports.custom_vp.x = 0; - g_console.viewports.custom_vp.y = 0; - g_console.custom_bgm_enable = true; - g_console.info_msg_enable = true; - - // g_extern - g_extern.state_slot = 0; - g_extern.audio_data.mute = 0; - g_extern.verbose = true; -} - #ifdef HAVE_SYSUTILS static void callback_sysutil_exit(uint64_t status, uint64_t param, void *userdata) { @@ -244,7 +188,9 @@ static void get_environment_settings(int argc, char *argv[]) } snprintf(default_paths.core_dir, sizeof(default_paths.core_dir), "%s/cores", default_paths.port_dir); + snprintf(default_paths.executable_extension, sizeof(default_paths.executable_extension), ".SELF"); snprintf(default_paths.savestate_dir, sizeof(default_paths.savestate_dir), "%s/savestates", default_paths.core_dir); + snprintf(default_paths.filesystem_root_dir, sizeof(default_paths.filesystem_root_dir), "/"); snprintf(default_paths.sram_dir, sizeof(default_paths.sram_dir), "%s/sram", default_paths.core_dir); snprintf(default_paths.system_dir, sizeof(default_paths.system_dir), "%s/system", default_paths.core_dir); @@ -295,16 +241,9 @@ int main(int argc, char *argv[]) config_set_defaults(); - char full_path[1024], tmp_path[1024]; - snprintf(full_path, sizeof(full_path), "%s/CORE.SELF", default_paths.core_dir); + char tmp_path[PATH_MAX]; snprintf(tmp_path, sizeof(tmp_path), "%s/", default_paths.core_dir); - - bool find_libretro_file = rarch_configure_libretro_core(full_path, tmp_path, default_paths.core_dir, - default_paths.config_file, ".SELF"); - - set_default_settings(); - rarch_config_load(default_paths.config_file, default_paths.core_dir, ".SELF", find_libretro_file); - init_libretro_sym(); + rarch_configure_libretro(tmp_path, default_paths.executable_extension); #if(CELL_SDK_VERSION > 0x340000) if (g_console.screenshots_enable) diff --git a/xdk/frontend/main.c b/xdk/frontend/main.c index af27ba5593..a66adc334c 100644 --- a/xdk/frontend/main.c +++ b/xdk/frontend/main.c @@ -47,50 +47,6 @@ int rarch_main(int argc, char *argv[]); #undef main -static void set_default_settings (void) -{ - //g_settings - g_settings.rewind_enable = false; -#ifdef _XBOX360 - strlcpy(g_settings.video.cg_shader_path, default_paths.shader_file, sizeof(g_settings.video.cg_shader_path)); - strlcpy(g_settings.video.second_pass_shader, default_paths.shader_file, sizeof(g_settings.video.second_pass_shader)); -#endif - g_settings.video.fbo_scale_x = 2.0f; - g_settings.video.fbo_scale_y = 2.0f; - g_settings.video.render_to_texture = true; - g_settings.video.second_pass_smooth = true; - g_settings.video.smooth = true; - g_settings.video.vsync = true; - strlcpy(g_settings.cheat_database, "game:", sizeof(g_settings.cheat_database)); - g_settings.video.aspect_ratio = -1.0f; - - rarch_input_set_controls_default(); - - //g_console - g_console.block_config_read = true; - g_console.frame_advance_enable = false; - g_console.emulator_initialized = 0; - g_console.gamma_correction_enable = true; - g_console.initialize_rarch_enable = false; - g_console.fbo_enabled = true; - g_console.mode_switch = MODE_MENU; - g_console.screen_orientation = ORIENTATION_NORMAL; - g_console.throttle_enable = true; - g_console.aspect_ratio_index = 0; - strlcpy(g_console.default_rom_startup_dir, "game:", sizeof(g_console.default_rom_startup_dir)); - g_console.viewports.custom_vp.width = 0; - g_console.viewports.custom_vp.height = 0; - g_console.viewports.custom_vp.x = 0; - g_console.viewports.custom_vp.y = 0; - g_console.color_format = 0; - g_console.info_msg_enable = true; - - //g_extern - g_extern.state_slot = 0; - g_extern.audio_data.mute = 0; - g_extern.verbose = true; -} - static void get_environment_settings (void) { HRESULT ret; @@ -147,27 +103,17 @@ static void get_environment_settings (void) /* FIXME: Hardcoded */ strlcpy(default_paths.config_file, "D:\\retroarch.cfg", sizeof(default_paths.config_file)); strlcpy(g_settings.system_directory, "D:\\system\\", sizeof(g_settings.system_directory)); + strlcpy(default_paths.filesystem_root_dir, "D:\\", sizeof(default_paths.filesystem_root_dir)); + strlcpy(default_paths.executable_extension, ".xbe", sizeof(default_paths.executable_extension)); #else + strlcpy(default_paths.filesystem_root_dir, "game:\\", sizeof(default_paths.filesystem_root_dir)); strlcpy(default_paths.shader_file, "game:\\media\\shaders\\stock.cg", sizeof(default_paths.shader_file)); strlcpy(default_paths.config_file, "game:\\retroarch.cfg", sizeof(default_paths.config_file)); strlcpy(g_settings.system_directory, "game:\\system\\", sizeof(g_settings.system_directory)); + strlcpy(default_paths.executable_extension, ".xex", sizeof(default_paths.executable_extension)); #endif } -static void configure_libretro(const char *path_prefix, const char * extension) -{ - char full_path[1024]; - snprintf(full_path, sizeof(full_path), "%sCORE%s", path_prefix, extension); - - bool find_libretro_file = rarch_configure_libretro_core(full_path, path_prefix, path_prefix, - default_paths.config_file, extension); - - set_default_settings(); - rarch_config_load(default_paths.config_file, path_prefix, extension, find_libretro_file); - init_libretro_sym(); -} - - int main(int argc, char *argv[]) { rarch_main_clear_state(); @@ -175,11 +121,7 @@ int main(int argc, char *argv[]) config_set_defaults(); -#ifdef _XBOX1 - configure_libretro("D:\\", ".xbe"); -#else - configure_libretro("game:\\", ".xex"); -#endif + rarch_configure_libretro(default_paths.filesystem_root_dir, default_paths.executable_extension); #if defined(HAVE_D3D8) || defined(HAVE_D3D9) video_xdk_d3d.start(); From 7b01393941b9133d966b995e91221674b5b536ab Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Tue, 24 Jul 2012 10:36:32 +0200 Subject: [PATCH 24/51] (PSL1GHT/RGL) Add PSL1GHT defines for GCM method macros --- ps3/sdk_defines.h | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/ps3/sdk_defines.h b/ps3/sdk_defines.h index ad30eee473..0264488543 100644 --- a/ps3/sdk_defines.h +++ b/ps3/sdk_defines.h @@ -431,7 +431,7 @@ #define cellGcmSetFlipHandler gcmSetFlipHandler #define cellGcmSetVBlankHandler gcmSetVBlankHandler #define cellGcmGetConfiguration gcmGetConfiguration -#define cellGcmSetJumpCommand gcmSetJumpCommand +#define cellGcmSetJumpCommand rsxSetJumpCommand #define cellGcmFlush rsxFlushBuffer #define cellGcmSetFlipMode gcmSetFlipMode #define cellGcmSetFlip gcmSetFlip @@ -455,6 +455,22 @@ #define cellVideoOutConfigure videoConfigure #define cellVideoOutGetState videoGetState #define cellVideoOutGetResolution videoGetResolution + +#define cellGcmSetViewportInline rsxSetViewport +#define cellGcmSetReferenceCommandInline rsxSetReferenceCommand +#define cellGcmSetBlendEquationInline rsxSetBlendEquation +#define cellGcmSetWriteBackEndLabelInline rsxSetWriteBackendLabel +#define cellGcmSetWaitLabelInline rsxSetWaitLabel +#define cellGcmSetDepthTestEnableInline rsxSetDepthTestEnable +#define cellGcmSetScissorInline rsxSetScissor +#define cellGcmSetBlendEnableInline rsxSetBlendEnable +#define cellGcmSetClearColorInline rsxSetClearColor +#define cellGcmSetBlendFuncInline rsxSetBlendFunc +#define cellGcmSetBlendColorInline rsxSetBlendColor +#define cellGcmSetTextureFilterInline rsxTextureFilter +#define cellGcmSetTextureControlInline rsxTextureControl +#define cellGcmSetCullFaceEnableInline rsxSetCullFaceEnable +#define cellGcmSetShadeModeInline rxSetShadeModel #endif #endif From 58a3c8ac862df8bffe1e2932d9cd7aae1f0ab773 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Tue, 24 Jul 2012 11:58:11 +0200 Subject: [PATCH 25/51] (Xbox 1) Menu shows (corrupted) screen now --- xbox1/frontend/menu.cpp | 34 +++++++++++++++++----------------- xbox1/xdk_d3d8.h | 3 +-- 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/xbox1/frontend/menu.cpp b/xbox1/frontend/menu.cpp index de9b223efc..c9764d5fe0 100644 --- a/xbox1/frontend/menu.cpp +++ b/xbox1/frontend/menu.cpp @@ -49,7 +49,7 @@ int menu_init(void) g_romList.Load(); // Init input here - g_input.Create(); + //g_input.Create(); // Load the font here g_font.Create(); @@ -67,23 +67,23 @@ void menu_free(void) {} void menu_loop(void) { xdk_d3d_video_t *d3d = (xdk_d3d_video_t*)driver.video_data; - //rarch_console_load_game("D:\\ssf2x.gba"); + rarch_console_load_game("D:\\ssf2x.gba"); // Loop the app - while (!g_bExit) - { - d3d->d3d_render_device->Clear(0, NULL, D3DCLEAR_TARGET, - D3DCOLOR_XRGB(0, 0, 0), - 1.0f, 0); - - d3d->d3d_render_device->BeginScene(); - d3d->d3d_render_device->SetFlickerFilter(g_iniFile.m_currentIniEntry.dwFlickerFilter); - d3d->d3d_render_device->SetSoftDisplayFilter(g_iniFile.m_currentIniEntry.bSoftDisplayFilter); + //while (!g_bExit) + //{ + // d3d->d3d_render_device->Clear(0, NULL, D3DCLEAR_TARGET, + // D3DCOLOR_XRGB(0, 0, 0), + // 1.0f, 0); + // + // d3d->d3d_render_device->BeginScene(); + // d3d->d3d_render_device->SetFlickerFilter(g_iniFile.m_currentIniEntry.dwFlickerFilter); + // d3d->d3d_render_device->SetSoftDisplayFilter(g_iniFile.m_currentIniEntry.bSoftDisplayFilter); - g_input.GetInput(); - g_menuManager.Update(); - - d3d->d3d_render_device->EndScene(); - d3d->d3d_render_device->Present(NULL, NULL, NULL, NULL); - } + // //g_input.GetInput(); + // g_menuManager.Update(); + // + // d3d->d3d_render_device->EndScene(); + // d3d->d3d_render_device->Present(NULL, NULL, NULL, NULL); + //} } diff --git a/xbox1/xdk_d3d8.h b/xbox1/xdk_d3d8.h index 64e720d58a..402a2eb4af 100644 --- a/xbox1/xdk_d3d8.h +++ b/xbox1/xdk_d3d8.h @@ -25,8 +25,7 @@ #define SHOW_DEBUG_INFO #define DFONT_MAX 4096 -#define PRIM_FVF (D3DFVF_XYZRHW | D3DFVF_TEX1) -#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ | D3DFVF_NORMAL) +#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW | D3DFVF_TEX1) #define MIN_SCALING_FACTOR (1.0f) #define MAX_SCALING_FACTOR (2.0f) From 199871955c38f381ad8b6fb03ce0ebf2393bbbe6 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Tue, 24 Jul 2012 12:04:26 +0200 Subject: [PATCH 26/51] (Xbox 1) Shows menu now --- xbox1/RetroLaunch/Surface.cpp | 8 ++++---- xbox1/frontend/menu.cpp | 32 ++++++++++++++++---------------- xbox1/xdk_d3d8.h | 1 + 3 files changed, 21 insertions(+), 20 deletions(-) diff --git a/xbox1/RetroLaunch/Surface.cpp b/xbox1/RetroLaunch/Surface.cpp index 0f6c1aa94d..aabebebfe0 100644 --- a/xbox1/RetroLaunch/Surface.cpp +++ b/xbox1/RetroLaunch/Surface.cpp @@ -172,10 +172,10 @@ bool CSurface::Render(int x, int y, dword w, dword h) /*CustomVertex*/DrawVerticeFormats newVerts[] = { // x, y, z, color, u ,v - {fX, fY, 0.0f, /*D3DCOLOR_ARGB(m_byOpacity, m_byR, m_byG, m_byB),*/ 0, 0}, - {fX + w, fY, 0.0f, /*D3DCOLOR_ARGB(m_byOpacity, m_byR, m_byG, m_byB),*/ 1, 0}, - {fX + w, fY + h, 0.0f, /*D3DCOLOR_ARGB(m_byOpacity, m_byR, m_byG, m_byB),*/ 1, 1}, - {fX, fY + h, 0.0f, /*D3DCOLOR_ARGB(m_byOpacity, m_byR, m_byG, m_byB),*/ 0, 1} + {fX, fY, 0.0f, /*D3DCOLOR_ARGB(m_byOpacity, m_byR, m_byG, m_byB),*/ 0, 0, 0}, + {fX + w, fY, 0.0f, /*D3DCOLOR_ARGB(m_byOpacity, m_byR, m_byG, m_byB),*/ 0, 1, 0}, + {fX + w, fY + h, 0.0f, /*D3DCOLOR_ARGB(m_byOpacity, m_byR, m_byG, m_byB),*/ 0, 1, 1}, + {fX, fY + h, 0.0f, /*D3DCOLOR_ARGB(m_byOpacity, m_byR, m_byG, m_byB),*/ 0, 0, 1} }; // load the existing vertices diff --git a/xbox1/frontend/menu.cpp b/xbox1/frontend/menu.cpp index c9764d5fe0..16ea97b817 100644 --- a/xbox1/frontend/menu.cpp +++ b/xbox1/frontend/menu.cpp @@ -67,23 +67,23 @@ void menu_free(void) {} void menu_loop(void) { xdk_d3d_video_t *d3d = (xdk_d3d_video_t*)driver.video_data; - rarch_console_load_game("D:\\ssf2x.gba"); + //rarch_console_load_game("D:\\ssf2x.gba"); // Loop the app - //while (!g_bExit) - //{ - // d3d->d3d_render_device->Clear(0, NULL, D3DCLEAR_TARGET, - // D3DCOLOR_XRGB(0, 0, 0), - // 1.0f, 0); - // - // d3d->d3d_render_device->BeginScene(); - // d3d->d3d_render_device->SetFlickerFilter(g_iniFile.m_currentIniEntry.dwFlickerFilter); - // d3d->d3d_render_device->SetSoftDisplayFilter(g_iniFile.m_currentIniEntry.bSoftDisplayFilter); + while (!g_bExit) + { + d3d->d3d_render_device->Clear(0, NULL, D3DCLEAR_TARGET, + D3DCOLOR_XRGB(0, 0, 0), + 1.0f, 0); + + d3d->d3d_render_device->BeginScene(); + d3d->d3d_render_device->SetFlickerFilter(g_iniFile.m_currentIniEntry.dwFlickerFilter); + d3d->d3d_render_device->SetSoftDisplayFilter(g_iniFile.m_currentIniEntry.bSoftDisplayFilter); - // //g_input.GetInput(); - // g_menuManager.Update(); - // - // d3d->d3d_render_device->EndScene(); - // d3d->d3d_render_device->Present(NULL, NULL, NULL, NULL); - //} + //g_input.GetInput(); + g_menuManager.Update(); + + d3d->d3d_render_device->EndScene(); + d3d->d3d_render_device->Present(NULL, NULL, NULL, NULL); + } } diff --git a/xbox1/xdk_d3d8.h b/xbox1/xdk_d3d8.h index 402a2eb4af..7ce1a84c84 100644 --- a/xbox1/xdk_d3d8.h +++ b/xbox1/xdk_d3d8.h @@ -43,6 +43,7 @@ typedef struct typedef struct DrawVerticeFormats { float x, y, z; + float rhw; float u, v; } DrawVerticeFormats; From 79bd5a844b575ea36b8ae8d3131c2d53cc7d3e95 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Tue, 24 Jul 2012 12:27:49 +0200 Subject: [PATCH 27/51] (Xbox 1) Replaced Debug.cpp code with calls to RARCH_LOG/RARCH_WARN/ RARCH_ERR --- msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj | 3 - xbox1/RetroLaunch/Debug.cpp | 83 --------------------- xbox1/RetroLaunch/Debug.h | 41 ---------- xbox1/RetroLaunch/IniFile.cpp | 21 ++---- xbox1/RetroLaunch/MenuMain.cpp | 16 ++-- xbox1/RetroLaunch/MenuManager.cpp | 5 +- xbox1/RetroLaunch/Surface.cpp | 11 ++- xbox1/frontend/menu.cpp | 3 +- 8 files changed, 24 insertions(+), 159 deletions(-) delete mode 100644 xbox1/RetroLaunch/Debug.cpp delete mode 100644 xbox1/RetroLaunch/Debug.h diff --git a/msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj b/msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj index 969ec5feee..19ccc56a7f 100644 --- a/msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj +++ b/msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj @@ -357,9 +357,6 @@ - - diff --git a/xbox1/RetroLaunch/Debug.cpp b/xbox1/RetroLaunch/Debug.cpp deleted file mode 100644 index 1f94d72466..0000000000 --- a/xbox1/RetroLaunch/Debug.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/** - * RetroLaunch 2012 - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. This program 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 this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. To contact the - * authors: Surreal64 CE Team (http://www.emuxtras.net) - */ - -#include "Global.h" -#include "Debug.h" - -CDebug g_debug; - -CDebug::CDebug(void) -{ - iLine = 1; - m_bFileOpen = false; -} - -CDebug::~CDebug(void) -{ -} - -void CDebug::Print(char *szMessage, ...) -{ - char szMsg[512]; - va_list vaArgList; - string szDebugFile ("D:\\debug.log");//(FixPath(PathRoot() + "debug.log")); - - va_start(vaArgList, szMessage); - vsprintf(szMsg, szMessage, vaArgList); - va_end(vaArgList); - - OutputDebugStringA(IntToString(iLine).c_str()); - OutputDebugStringA(": "); - OutputDebugStringA(szMsg); - OutputDebugStringA("\n\n"); - -#ifdef WIN32 - cout << IntToString(iLine)<< ": " << szMsg << endl << endl; -#endif - -//#ifdef _LOG - //Open the log file, create one if it does not exist, append the data - if(!m_bFileOpen) - { - fp = fopen(szDebugFile.c_str(), "w+"); - m_bFileOpen = true; - } - else - { - fp = fopen(szDebugFile.c_str(), "a+"); - } - - //print the data to the log file - fprintf(fp, IntToString(iLine).c_str()); - fprintf(fp, ": "); - fprintf(fp, szMsg); - fprintf(fp, "\r\n\r\n"); - - //close the file - fclose(fp); -//#endif //_LOG - - iLine ++; -} - - -string CDebug::IntToString(int value) -{ - stringstream ss; - - ss << value; - - return ss.str(); -} diff --git a/xbox1/RetroLaunch/Debug.h b/xbox1/RetroLaunch/Debug.h deleted file mode 100644 index 5506100f44..0000000000 --- a/xbox1/RetroLaunch/Debug.h +++ /dev/null @@ -1,41 +0,0 @@ -/** - * RetroLaunch 2012 - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. This program 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 this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. To contact the - * authors: Surreal64 CE Team (http://www.emuxtras.net) - */ - -#ifndef _DEBUG_H__DASH_ -#define _DEBUG_H__DASH_ - -#if _MSC_VER > 1000 -#pragma once -#endif //_MSC_VER > 1000 - -class CDebug -{ -public: - CDebug(); - ~CDebug(); - - void Print(char *szMessage, ...); - string IntToString(int value); - -private: - int iLine; - FILE *fp; - bool m_bFileOpen; - -}; - -extern CDebug g_debug; - -#endif //_DEBUG_H__DASH_ \ No newline at end of file diff --git a/xbox1/RetroLaunch/IniFile.cpp b/xbox1/RetroLaunch/IniFile.cpp index cfa7e04bbc..81ef3a226e 100644 --- a/xbox1/RetroLaunch/IniFile.cpp +++ b/xbox1/RetroLaunch/IniFile.cpp @@ -16,6 +16,7 @@ #include "SimpleIni.h" #include "IniFile.h" +#include "../../general.h" IniFile g_iniFile; @@ -46,15 +47,13 @@ bool IniFile::Save(const string &szIniFileName) rc = ini.SaveFile(szIniFileName.c_str()); - OutputDebugStringA(szIniFileName.c_str()); - if (rc < 0) { - OutputDebugStringA(" failed to save!\n"); + RARCH_ERR("Failed to save RetroLaunch INI file: %s.\n", szIniFileName.c_str()); return false; } - OutputDebugStringA(" saved successfully!\n"); + RARCH_LOG("Saved RetroLaunch INI file: %s.\n", szIniFileName.c_str()); return true; } @@ -70,15 +69,11 @@ bool IniFile::Load(const string &szIniFileName) if (rc < 0) { - OutputDebugString("Failed to load "); - OutputDebugString(szIniFileName.c_str()); - OutputDebugString("\n"); + RARCH_ERR("Failed to load RetroLaunch INI file: %s.\n", szIniFileName.c_str()); return false; } - OutputDebugStringA("Successfully loaded "); - OutputDebugString(szIniFileName.c_str()); - OutputDebugString("\n"); + RARCH_LOG("Successfully loaded RetroLaunch INI file: %s.\n", szIniFileName.c_str()); //GENERAL SETTINGS m_currentIniEntry.bShowDebugInfo = ini.GetBoolValue("GENERAL SETTINGS", "SHOW DEBUG INFO", NULL ); @@ -134,15 +129,13 @@ bool IniFile::SaveTempRomFileName(const string &szFileName) DeleteFile("T:\\tmp.retro"); rc = ini.SaveFile("T:\\tmp.retro"); - OutputDebugStringA("T:\\tmp.retro"); - if (rc < 0) { - OutputDebugStringA(" failed to save!\n"); + RARCH_ERR("Failed to save temporary ROM file: %s.\n", "T:\\tmp.retro"); return false; } - OutputDebugStringA(" saved successfully!\n"); + RARCH_LOG("Successfully saved temporary ROM file %s.\n", "T:\\tmp.retro"); return true; } diff --git a/xbox1/RetroLaunch/MenuMain.cpp b/xbox1/RetroLaunch/MenuMain.cpp index 1cb6deab6d..af88cf552f 100644 --- a/xbox1/RetroLaunch/MenuMain.cpp +++ b/xbox1/RetroLaunch/MenuMain.cpp @@ -14,11 +14,11 @@ */ #include "MenuMain.h" -#include "Debug.h" #include "Font.h" #include "RomList.h" #include "Input.h" +#include "../../general.h" CMenuMain g_menuMain; @@ -64,7 +64,7 @@ CMenuMain::~CMenuMain() bool CMenuMain::Create() { - g_debug.Print("CMenuMain::Create()"); + RARCH_LOG("CMenuMain::Create()."); // Title coords with color m_menuMainTitle_x = 305; @@ -157,7 +157,7 @@ void CMenuMain::ProcessInput() { m_menuMainRomSelectPanel_y += m_menuMainRomListSpacing; m_romListSelectedRom++; - g_debug.Print("SELECTED ROM: "); g_debug.Print("%d", m_romListSelectedRom); + RARCH_LOG("SELECTED ROM: %d.\n", m_romListSelectedRom); } if(m_menuMainRomSelectPanel_y > (m_menuMainRomListPos_y + (m_menuMainRomListSpacing * (m_romListEndRender)))) @@ -170,11 +170,11 @@ void CMenuMain::ProcessInput() } - g_debug.Print("SELECTED ROM AFTER CORRECTION: "); g_debug.Print("%d", m_romListSelectedRom); + RARCH_LOG("SELECTED ROM AFTER CORRECTION: %d.\n", m_romListSelectedRom); if(m_romListSelectedRom < g_romList.GetRomListSize() - 1 && m_romListOffset < g_romList.GetRomListSize() - 1 - m_romListEndRender - 1) { m_romListOffset++; - g_debug.Print("OFFSET: "); g_debug.Print("%d", m_romListOffset); + RARCH_LOG("OFFSET: %d.\n", m_romListOffset); } } @@ -192,7 +192,7 @@ void CMenuMain::ProcessInput() { m_menuMainRomSelectPanel_y -= m_menuMainRomListSpacing; m_romListSelectedRom--; - g_debug.Print("SELECTED ROM: "); g_debug.Print("%d", m_romListSelectedRom); + RARCH_LOG("SELECTED ROM: %d.\n", m_romListSelectedRom); } if(m_menuMainRomSelectPanel_y < (m_menuMainRomListPos_y - m_menuMainRomListSpacing)) @@ -205,11 +205,11 @@ void CMenuMain::ProcessInput() } - g_debug.Print("SELECTED ROM AFTER CORRECTION: "); g_debug.Print("%d", m_romListSelectedRom); + RARCH_LOG("SELECTED ROM AFTER CORRECTION: %d.\n", m_romListSelectedRom); if(m_romListSelectedRom > 0 && m_romListOffset > 0) { m_romListOffset--; - g_debug.Print("OFFSET: "); g_debug.Print("%d", m_romListOffset); + RARCH_LOG("OFFSET: %d.\n", m_romListOffset); } } } diff --git a/xbox1/RetroLaunch/MenuManager.cpp b/xbox1/RetroLaunch/MenuManager.cpp index ef0853003f..9faaa9169c 100644 --- a/xbox1/RetroLaunch/MenuManager.cpp +++ b/xbox1/RetroLaunch/MenuManager.cpp @@ -15,9 +15,10 @@ #include "MenuManager.h" #include "MenuMain.h" -#include "Debug.h" #include "Input.h" +#include "../../general.h" + CMenuManager g_menuManager; @@ -32,7 +33,7 @@ CMenuManager::~CMenuManager() bool CMenuManager::Create() { //Create the MenuManager, set to Main Menu - g_debug.Print("Create MenuManager, set state to MENU_MAIN"); + RARCH_LOG("Create MenuManager, set state to MENU_MAIN.\n"); SetMenuState(MENU_MAIN); return true; diff --git a/xbox1/RetroLaunch/Surface.cpp b/xbox1/RetroLaunch/Surface.cpp index aabebebfe0..7df8d7ee4a 100644 --- a/xbox1/RetroLaunch/Surface.cpp +++ b/xbox1/RetroLaunch/Surface.cpp @@ -16,7 +16,6 @@ */ #include "Surface.h" -#include "Debug.h" #include "../../general.h" #include "../xdk_d3d8.h" @@ -67,7 +66,7 @@ bool CSurface::Create(const string &szFilename) if (FAILED(g_hResult)) { - g_debug.Print("Failed: D3DXCreateTextureFromFileExA()\n"); + RARCH_ERR("Error occurred during D3DXCreateTextureFromFileExA().\n"); return false; } @@ -78,7 +77,7 @@ bool CSurface::Create(const string &szFilename) D3DPOOL_MANAGED, &m_pVertexBuffer); if (FAILED(g_hResult)) { - g_debug.Print("Failed: CreateVertexBuffer()\n"); + RARCH_ERR("Error occurred during CreateVertexBuffer().\n"); m_pTexture->Release(); return false; } @@ -100,7 +99,7 @@ bool CSurface::Create(dword width, dword height) if (FAILED(g_hResult)) { - g_debug.Print("Failed: CreateTexture()\n"); + RARCH_ERR("Error occurred during CreateTexture().\n"); return false; } @@ -115,7 +114,7 @@ bool CSurface::Create(dword width, dword height) D3DPOOL_MANAGED, &m_pVertexBuffer); if (FAILED(g_hResult)) { - g_debug.Print("Failed: CreateVertexBuffer()\n"); + RARCH_ERR("Error occurred during CreateVertexBuffer().\n"); m_pTexture->Release(); return false; } @@ -185,7 +184,7 @@ bool CSurface::Render(int x, int y, dword w, dword h) if (FAILED(g_hResult)) { - g_debug.Print("Failed: m_pVertexBuffer->Lock()\n"); + RARCH_ERR("Error occurred during m_pVertexBuffer->Lock().\n"); return false; } // copy the new verts over the old verts diff --git a/xbox1/frontend/menu.cpp b/xbox1/frontend/menu.cpp index 16ea97b817..d0401f9962 100644 --- a/xbox1/frontend/menu.cpp +++ b/xbox1/frontend/menu.cpp @@ -18,7 +18,6 @@ #include "../../xbox1/RetroLaunch/IniFile.h" #include "../../xbox1/RetroLaunch/IoSupport.h" #include "../../xbox1/RetroLaunch/Input.h" -#include "../../xbox1/RetroLaunch/Debug.h" #include "../../xbox1/RetroLaunch/Font.h" #include "../../xbox1/RetroLaunch/MenuManager.h" #include "../../xbox1/RetroLaunch/RomList.h" @@ -27,7 +26,7 @@ bool g_bExit = false; int menu_init(void) { - g_debug.Print("Starting RetroLaunch\n"); + RARCH_LOG("Starting RetroLaunch.\n"); // Set file cache size XSetFileCacheSize(8 * 1024 * 1024); From 3e82330132b3ef6c0dc1b427a901525ec541a10c Mon Sep 17 00:00:00 2001 From: twinaphex Date: Tue, 24 Jul 2012 16:00:59 +0200 Subject: [PATCH 28/51] (Xbox 1) Controls now work in menu - very twitchy - will be fixed --- msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj | 3 - xbox1/RetroLaunch/IniFile.cpp | 145 -------------------- xbox1/RetroLaunch/IniFile.h | 98 ------------- xbox1/RetroLaunch/MenuMain.cpp | 43 +++--- xbox1/RetroLaunch/Rom.h | 1 - xbox1/frontend/menu.cpp | 25 +--- 6 files changed, 26 insertions(+), 289 deletions(-) delete mode 100644 xbox1/RetroLaunch/IniFile.cpp delete mode 100644 xbox1/RetroLaunch/IniFile.h diff --git a/msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj b/msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj index 19ccc56a7f..891e953c05 100644 --- a/msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj +++ b/msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj @@ -360,9 +360,6 @@ - - diff --git a/xbox1/RetroLaunch/IniFile.cpp b/xbox1/RetroLaunch/IniFile.cpp deleted file mode 100644 index 81ef3a226e..0000000000 --- a/xbox1/RetroLaunch/IniFile.cpp +++ /dev/null @@ -1,145 +0,0 @@ -/** - * RetroLaunch 2012 - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. This program 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 this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. To contact the - * authors: Surreal64 CE Team (http://www.emuxtras.net) - */ - -#include "SimpleIni.h" -#include "IniFile.h" - -#include "../../general.h" - -IniFile g_iniFile; - -//FIXME: SCREEN XPOS, YPOS, XSCALE, YSCALE should be floats! -//FIXME: Path for WIN32 - -IniFile::IniFile(void) -{ -} - -IniFile::~IniFile(void) -{ -} - -bool IniFile::Save(const string &szIniFileName) -{ - CSimpleIniA ini; - SI_Error rc; - ini.SetUnicode(true); - ini.SetMultiKey(true); - ini.SetMultiLine(true); - - //GENERAL SETTINGS - ini.SetBoolValue("GENERAL SETTINGS", "SHOW DEBUG INFO", m_currentIniEntry.bShowDebugInfo); - - //VIDEO SETTINGS - ini.SetBoolValue("VIDEO SETTINGS", "AUTOMATIC FRAME SKIP", m_currentIniEntry.bAutomaticFrameSkip); - - rc = ini.SaveFile(szIniFileName.c_str()); - - if (rc < 0) - { - RARCH_ERR("Failed to save RetroLaunch INI file: %s.\n", szIniFileName.c_str()); - return false; - } - - RARCH_LOG("Saved RetroLaunch INI file: %s.\n", szIniFileName.c_str()); - return true; -} - -bool IniFile::Load(const string &szIniFileName) -{ - CSimpleIniA ini; - SI_Error rc; - ini.SetUnicode(true); - ini.SetMultiKey(true); - ini.SetMultiLine(true); - - rc = ini.LoadFile(szIniFileName.c_str()); - - if (rc < 0) - { - RARCH_ERR("Failed to load RetroLaunch INI file: %s.\n", szIniFileName.c_str()); - return false; - } - - RARCH_LOG("Successfully loaded RetroLaunch INI file: %s.\n", szIniFileName.c_str()); - - //GENERAL SETTINGS - m_currentIniEntry.bShowDebugInfo = ini.GetBoolValue("GENERAL SETTINGS", "SHOW DEBUG INFO", NULL ); - - //VIDEO SETTINGS - m_currentIniEntry.bAutomaticFrameSkip = ini.GetBoolValue("VIDEO SETTINGS", "AUTOMATIC FRAME SKIP", NULL ); - - return true; -} - -bool IniFile::CreateAndSaveDefaultIniEntry() -{ - //GENERAL SETTINGS - m_defaultIniEntry.bShowDebugInfo = false; - - //VIDEO SETTINGS - m_defaultIniEntry.bAutomaticFrameSkip = true; - - // our current ini is now the default ini - m_currentIniEntry = m_defaultIniEntry; - - // save the default ini - // FIXME! -> CD/DVD -> utility drive X: - Save("D:\\retrolaunch.ini"); - - return true; -} - - -bool IniFile::CheckForIniEntry() -{ - // try to load our ini file - if(!Load("D:\\retrolaunch.ini")) - { - // create a new one, if it doesn't exist - CreateAndSaveDefaultIniEntry(); - } - - return true; -} - - -bool IniFile::SaveTempRomFileName(const string &szFileName) -{ - CSimpleIniA ini; - SI_Error rc; - ini.SetUnicode(true); - ini.SetMultiKey(true); - ini.SetMultiLine(true); - - ini.SetValue("LAUNCHER", "ROM", szFileName.c_str()); - - DeleteFile("T:\\tmp.retro"); - rc = ini.SaveFile("T:\\tmp.retro"); - - if (rc < 0) - { - RARCH_ERR("Failed to save temporary ROM file: %s.\n", "T:\\tmp.retro"); - return false; - } - - RARCH_LOG("Successfully saved temporary ROM file %s.\n", "T:\\tmp.retro"); - return true; - -} - - - - diff --git a/xbox1/RetroLaunch/IniFile.h b/xbox1/RetroLaunch/IniFile.h deleted file mode 100644 index dcc28505e7..0000000000 --- a/xbox1/RetroLaunch/IniFile.h +++ /dev/null @@ -1,98 +0,0 @@ -/** - * RetroLaunch 2012 - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. This program 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 this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. To contact the - * authors: Surreal64 CE Team (http://www.emuxtras.net) - */ - -#pragma once -#include "Global.h" - -struct IniFileEntry -{ - //debug output - bool bShowDebugInfo; - - //automatic frame skip method - bool bAutomaticFrameSkip; - - //manual frame skip method (throttlespeed) - bool bManualFrameSkip; - - //number of frames to skip - dword dwNumFrameSkips; - - //sync audio to video - bool bSyncAudioToVideo; - - //vertical synchronization - bool bVSync; - - //flicker filter - dword dwFlickerFilter; - - //soft display filter - bool bSoftDisplayFilter; - - //texture filter - DWORD dwTextureFilter; - - //screen xpos - dword dwXPOS; - //screen ypos - dword dwYPOS; - //screen xscale - dword dwXWIDTH; - //screen yscale - dword dwYHEIGHT; - - //hide normal scroll 0 - bool bHideNBG0; - //hide normal scroll 1 - bool bHideNBG1; - //hide normal scroll 2 - bool bHideNBG2; - //hide normal scroll 3 - bool bHideNBG3; - //hide rotation scroll 0 - bool bHideRBG0; - //hide VDP1 - bool bHideVDP1; -}; - - -class IniFile -{ -public: - IniFile(); - ~IniFile(); - - bool Save(const string &szIniFileName); - bool SaveTempRomFileName(const string &szFileName); - bool Load(const string &szIniFileName); - bool CreateAndSaveDefaultIniEntry(); - bool CheckForIniEntry(); - - IniFileEntry m_currentIniEntry; - -private: - IniFileEntry m_defaultIniEntry; - - string szRomFileName; - -}; - -extern IniFile g_iniFile; - - - - - diff --git a/xbox1/RetroLaunch/MenuMain.cpp b/xbox1/RetroLaunch/MenuMain.cpp index af88cf552f..b9cb79e3d5 100644 --- a/xbox1/RetroLaunch/MenuMain.cpp +++ b/xbox1/RetroLaunch/MenuMain.cpp @@ -18,6 +18,7 @@ #include "RomList.h" #include "Input.h" +#include "../../console/retroarch_console.h" #include "../../general.h" CMenuMain g_menuMain; @@ -127,8 +128,7 @@ void CMenuMain::Render() m_menuMainBG.Render(m_menuMainBG_x, m_menuMainBG_y); //Display some text - //g_font.Render("Retro Arch", m_menuMainTitle_x, m_menuMainTitle_y, 20, XFONT_NORMAL, m_menuMainTitle_c); - g_font.Render("Press RIGHT ANALOG STICK to exit. Press START to launch a rom.", 65, 430, 16, XFONT_NORMAL, m_menuMainTitle_c); + g_font.Render("Press RSTICK THUMB to exit. Press START and/or A to launch a rom.", 65, 430, 16, XFONT_NORMAL, m_menuMainTitle_c); //Begin with the rom selector panel //FIXME: Width/Height needs to be current Rom texture width/height (or should we just leave it at a fixed size?) @@ -143,13 +143,23 @@ void CMenuMain::Render() } } +static uint16_t old_input_state = 0; void CMenuMain::ProcessInput() { - //FIXME: The calculations might be wrong :-/ - if(g_input.IsButtonPressed(XboxDPadDown) || g_input.IsButtonPressed(XboxLeftThumbDown) || g_input.IsRTriggerPressed()) - { + uint16_t input_state = 0; + input_xinput.poll(NULL); + for (unsigned i = 0; i < RARCH_FIRST_META_KEY; i++) + { + input_state |= input_xinput.input_state(NULL, NULL, false, + RETRO_DEVICE_JOYPAD, 0, i) ? (1 << i) : 0; + } + + uint16_t trigger_state = input_state & ~old_input_state; + + if(trigger_state & (1 << RETRO_DEVICE_ID_JOYPAD_DOWN)) + { if(m_romListSelectedRom < g_romList.GetRomListSize()) { @@ -177,14 +187,10 @@ void CMenuMain::ProcessInput() RARCH_LOG("OFFSET: %d.\n", m_romListOffset); } } - -///////////////////////////////////////////// - } } - // Go up and stop if less than 0 (item 0) - if(g_input.IsButtonPressed(XboxDPadUp) || g_input.IsButtonPressed(XboxLeftThumbUp) || g_input.IsLTriggerPressed()) + if(trigger_state & (1 << RETRO_DEVICE_ID_JOYPAD_UP)) { if(m_romListSelectedRom > -1) { @@ -213,26 +219,15 @@ void CMenuMain::ProcessInput() } } } - - - } // Press A to launch, selected rom filename is saved into T:\\tmp.retro - if(g_input.IsButtonPressed(XboxA)) + if(trigger_state & (1 << RETRO_DEVICE_ID_JOYPAD_B) || trigger_state & (1 << RETRO_DEVICE_ID_JOYPAD_START)) { - //OutputDebugString(g_romList.GetRomAt(m_romListSelectedRom)->GetFileName().c_str()); - //OutputDebugString("\n"); - g_iniFile.SaveTempRomFileName(g_romList.GetRomAt(m_romListSelectedRom)->GetFileName()); - XLaunchNewImage("D:\\core.xbe", NULL); + rarch_console_load_game(g_romList.GetRomAt(m_romListSelectedRom)->GetFileName().c_str()); } - if (g_input.IsButtonPressed(XboxStart)) - { - XLaunchNewImage("D:\\core.xbe", NULL); - } - - if (g_input.IsButtonPressed(XboxRightThumbButton)) + if (trigger_state & (1 << RETRO_DEVICE_ID_JOYPAD_R3)) { LD_LAUNCH_DASHBOARD LaunchData = { XLD_LAUNCH_DASHBOARD_MAIN_MENU }; XLaunchNewImage( NULL, (LAUNCH_DATA*)&LaunchData ); diff --git a/xbox1/RetroLaunch/Rom.h b/xbox1/RetroLaunch/Rom.h index 11dce13713..b1df6f22fa 100644 --- a/xbox1/RetroLaunch/Rom.h +++ b/xbox1/RetroLaunch/Rom.h @@ -16,7 +16,6 @@ #pragma once #include "Global.h" -#include "IniFile.h" #include "Surface.h" class Rom diff --git a/xbox1/frontend/menu.cpp b/xbox1/frontend/menu.cpp index d0401f9962..e9fc148608 100644 --- a/xbox1/frontend/menu.cpp +++ b/xbox1/frontend/menu.cpp @@ -15,15 +15,12 @@ */ #include "../../xbox1/RetroLaunch/Global.h" -#include "../../xbox1/RetroLaunch/IniFile.h" #include "../../xbox1/RetroLaunch/IoSupport.h" #include "../../xbox1/RetroLaunch/Input.h" #include "../../xbox1/RetroLaunch/Font.h" #include "../../xbox1/RetroLaunch/MenuManager.h" #include "../../xbox1/RetroLaunch/RomList.h" -bool g_bExit = false; - int menu_init(void) { RARCH_LOG("Starting RetroLaunch.\n"); @@ -38,18 +35,10 @@ int menu_init(void) g_IOSupport.Mount("F:", "Harddisk0\\Partition6"); g_IOSupport.Mount("G:", "Harddisk0\\Partition7"); - // Get RetroArch's native d3d device - - // Parse ini file for settings - g_iniFile.CheckForIniEntry(); - // Load the rom list if it isn't already loaded if (!g_romList.IsLoaded()) g_romList.Load(); - // Init input here - //g_input.Create(); - // Load the font here g_font.Create(); @@ -66,23 +55,23 @@ void menu_free(void) {} void menu_loop(void) { xdk_d3d_video_t *d3d = (xdk_d3d_video_t*)driver.video_data; - //rarch_console_load_game("D:\\ssf2x.gba"); - // Loop the app - while (!g_bExit) + g_console.menu_enable = true; + + do { d3d->d3d_render_device->Clear(0, NULL, D3DCLEAR_TARGET, - D3DCOLOR_XRGB(0, 0, 0), + D3DCOLOR_ARGB(0, 0, 0, 0), 1.0f, 0); d3d->d3d_render_device->BeginScene(); - d3d->d3d_render_device->SetFlickerFilter(g_iniFile.m_currentIniEntry.dwFlickerFilter); - d3d->d3d_render_device->SetSoftDisplayFilter(g_iniFile.m_currentIniEntry.bSoftDisplayFilter); + d3d->d3d_render_device->SetFlickerFilter(5); + d3d->d3d_render_device->SetSoftDisplayFilter(1); //g_input.GetInput(); g_menuManager.Update(); d3d->d3d_render_device->EndScene(); d3d->d3d_render_device->Present(NULL, NULL, NULL, NULL); - } + }while(g_console.menu_enable); } From c0e7511d045089c42dfe67ba777fdb5f12178333 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Tue, 24 Jul 2012 16:06:16 +0200 Subject: [PATCH 29/51] (Xbox 1) RetroLaunch's Input.cpp deleted too --- msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj | 3 - xbox1/RetroLaunch/Input.cpp | 328 -------------------- xbox1/RetroLaunch/Input.h | 171 ---------- xbox1/RetroLaunch/MenuMain.cpp | 1 - xbox1/RetroLaunch/MenuManager.cpp | 16 - xbox1/frontend/menu.cpp | 1 - 6 files changed, 520 deletions(-) delete mode 100644 xbox1/RetroLaunch/Input.cpp delete mode 100644 xbox1/RetroLaunch/Input.h diff --git a/msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj b/msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj index 891e953c05..1cdfc9bb5f 100644 --- a/msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj +++ b/msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj @@ -360,9 +360,6 @@ - - diff --git a/xbox1/RetroLaunch/Input.cpp b/xbox1/RetroLaunch/Input.cpp deleted file mode 100644 index fc79b5357c..0000000000 --- a/xbox1/RetroLaunch/Input.cpp +++ /dev/null @@ -1,328 +0,0 @@ -/** - * RetroLaunch 2012 - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. This program 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 this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. To contact the - * authors: Surreal64 CE Team (http://www.emuxtras.net) - */ - -#ifdef _XBOX -#include "Input.h" - -Input g_input; - -Input::Input(void) -{ - m_pollingParameters.fAutoPoll = TRUE; - m_pollingParameters.fInterruptOut = TRUE; - m_pollingParameters.bInputInterval = 8; - m_pollingParameters.bOutputInterval = 8; - m_lastTick = GetTickCount(); - m_buttonDelay = XBINPUT_PRESS_BUTTON_DELAY; - m_triggerDelay = XBINPUT_PRESS_TRIGGER_DELAY; - m_buttonPressed = false; -} - -Input::~Input(void) -{ -} - -bool Input::Create() -{ - XInitDevices(0, NULL); - - // get a mask of all currently available devices - dword dwDeviceMask = XGetDevices(XDEVICE_TYPE_GAMEPAD); - - // open the devices - for(dword i = 0; i < XGetPortCount(); i++) - { - ZeroMemory(&m_inputStates[i], sizeof(XINPUT_STATE)); - ZeroMemory(&m_gamepads[i], sizeof(XBGAMEPAD)); - - if(dwDeviceMask & (1 << i)) - { - // get a handle to the device - m_gamepads[i].hDevice = XInputOpen(XDEVICE_TYPE_GAMEPAD, i, - XDEVICE_NO_SLOT, &m_pollingParameters); - - // store capabilities of the device - XInputGetCapabilities(m_gamepads[i].hDevice, &m_gamepads[i].caps); - - // initialize last pressed buttons - XInputGetState(m_gamepads[i].hDevice, &m_inputStates[i]); - - m_gamepads[i].wLastButtons = m_inputStates[i].Gamepad.wButtons; - - for(dword b = 0; b < 8; b++) - { - m_gamepads[i].bLastAnalogButtons[b] = - // Turn the 8-bit polled value into a boolean value - (m_inputStates[i].Gamepad.bAnalogButtons[b] > XINPUT_GAMEPAD_MAX_CROSSTALK); - } - } - } - - return true; -} - -void Input::RefreshDevices() -{ - dword dwInsertions, dwRemovals; - - XGetDeviceChanges(XDEVICE_TYPE_GAMEPAD, reinterpret_cast(&dwInsertions), reinterpret_cast(&dwRemovals)); - - // loop through all gamepads - for(dword i = 0; i < XGetPortCount(); i++) - { - // handle removed devices - m_gamepads[i].bRemoved = (dwRemovals & (1 << i)) ? true : false; - - if(m_gamepads[i].bRemoved) - { - // if the controller was removed after XGetDeviceChanges but before - // XInputOpen, the device handle will be NULL - if(m_gamepads[i].hDevice) - XInputClose(m_gamepads[i].hDevice); - - m_gamepads[i].hDevice = NULL; - m_gamepads[i].Feedback.Rumble.wLeftMotorSpeed = 0; - m_gamepads[i].Feedback.Rumble.wRightMotorSpeed = 0; - } - - // handle inserted devices - m_gamepads[i].bInserted = (dwInsertions & (1 << i)) ? true : false; - - if(m_gamepads[i].bInserted) - { - m_gamepads[i].hDevice = XInputOpen(XDEVICE_TYPE_GAMEPAD, i, - XDEVICE_NO_SLOT, &m_pollingParameters ); - - // if the controller is removed after XGetDeviceChanges but before - // XInputOpen, the device handle will be NULL - if(m_gamepads[i].hDevice) - { - XInputGetCapabilities(m_gamepads[i].hDevice, &m_gamepads[i].caps); - - // initialize last pressed buttons - XInputGetState(m_gamepads[i].hDevice, &m_inputStates[i]); - - m_gamepads[i].wLastButtons = m_inputStates[i].Gamepad.wButtons; - - for(dword b = 0; b < 8; b++) - { - m_gamepads[i].bLastAnalogButtons[b] = - // Turn the 8-bit polled value into a boolean value - (m_inputStates[i].Gamepad.bAnalogButtons[b] > XINPUT_GAMEPAD_MAX_CROSSTALK); - } - } - } - } -} - -void Input::GetInput() -{ - RefreshDevices(); - - if (m_buttonPressed) - { - m_lastTick = GetTickCount(); - m_buttonPressed = false; - } - - // loop through all gamepads - for(dword i = 0; i < XGetPortCount(); i++) - { - // if we have a valid device, poll it's state and track button changes - if(m_gamepads[i].hDevice) - { - // read the input state - XInputGetState(m_gamepads[i].hDevice, &m_inputStates[i]); - - // copy gamepad to local structure - memcpy(&m_gamepads[i], &m_inputStates[i].Gamepad, sizeof(XINPUT_GAMEPAD)); - - // put xbox device input for the gamepad into our custom format - float fX1 = (m_gamepads[i].sThumbLX + 0.5f) / 32767.5f; - m_gamepads[i].fX1 = (fX1 >= 0.0f ? 1.0f : -1.0f) * - max(0.0f, (fabsf(fX1) - XBINPUT_DEADZONE) / (1.0f - XBINPUT_DEADZONE)); - - float fY1 = (m_gamepads[i].sThumbLY + 0.5f) / 32767.5f; - m_gamepads[i].fY1 = (fY1 >= 0.0f ? 1.0f : -1.0f) * - max(0.0f, (fabsf(fY1) - XBINPUT_DEADZONE) / (1.0f - XBINPUT_DEADZONE)); - - float fX2 = (m_gamepads[i].sThumbRX + 0.5f) / 32767.5f; - m_gamepads[i].fX2 = (fX2 >= 0.0f ? 1.0f : -1.0f) * - max(0.0f, (fabsf(fX2) - XBINPUT_DEADZONE) / (1.0f - XBINPUT_DEADZONE)); - - float fY2 = (m_gamepads[i].sThumbRY + 0.5f) / 32767.5f; - m_gamepads[i].fY2 = (fY2 >= 0.0f ? 1.0f : -1.0f) * - max(0.0f, (fabsf(fY2) - XBINPUT_DEADZONE) / (1.0f - XBINPUT_DEADZONE)); - - // get the boolean buttons that have been pressed since the last - // call. each button is represented by one bit. - m_gamepads[i].wPressedButtons = (m_gamepads[i].wLastButtons ^ m_gamepads[i].wButtons) & m_gamepads[i].wButtons; - m_gamepads[i].wLastButtons = m_gamepads[i].wButtons; - - // get the analog buttons that have been pressed or released since - // the last call. - for(dword b = 0; b < 8; b++) - { - // turn the 8-bit polled value into a boolean value - bool bPressed = (m_gamepads[i].bAnalogButtons[b] > XINPUT_GAMEPAD_MAX_CROSSTALK); - - if(bPressed) - m_gamepads[i].bPressedAnalogButtons[b] = !m_gamepads[i].bLastAnalogButtons[b]; - else - m_gamepads[i].bPressedAnalogButtons[b] = false; - - // store the current state for the next time - m_gamepads[i].bLastAnalogButtons[b] = bPressed; - } - } - } -} - -bool Input::IsButtonPressed(XboxButton button) -{ - if (m_lastTick + m_buttonDelay > GetTickCount()) - return false; - - bool buttonDown = false; - - switch (button) - { - case XboxLeftThumbLeft: - buttonDown = (m_gamepads[0].fX1 < -0.5); - break; - case XboxLeftThumbRight: - buttonDown = (m_gamepads[0].fX1 > 0.5); - break; - case XboxLeftThumbUp: - buttonDown = (m_gamepads[0].fY1 > 0.5); - break; - case XboxLeftThumbDown: - buttonDown = (m_gamepads[0].fY1 < -0.5); - break; - case XboxRightThumbLeft: - buttonDown = (m_gamepads[0].fX2 < -0.5); - break; - case XboxRightThumbRight: - buttonDown = (m_gamepads[0].fX2 > 0.5); - break; - case XboxRightThumbUp: - buttonDown = (m_gamepads[0].fY2 > 0.5); - break; - case XboxRightThumbDown: - buttonDown = (m_gamepads[0].fY2 < -0.5); - break; - case XboxDPadLeft: - buttonDown = ((m_gamepads[0].wButtons & XINPUT_GAMEPAD_DPAD_LEFT) != 0); - break; - case XboxDPadRight: - buttonDown = ((m_gamepads[0].wButtons & XINPUT_GAMEPAD_DPAD_RIGHT) != 0); - break; - case XboxDPadUp: - buttonDown = ((m_gamepads[0].wButtons & XINPUT_GAMEPAD_DPAD_UP) != 0); - break; - case XboxDPadDown: - buttonDown = ((m_gamepads[0].wButtons & XINPUT_GAMEPAD_DPAD_DOWN) != 0); - break; - case XboxStart: - buttonDown = ((m_gamepads[0].wButtons & XINPUT_GAMEPAD_START) != 0); - break; - case XboxBack: - buttonDown = ((m_gamepads[0].wButtons & XINPUT_GAMEPAD_BACK) != 0); - break; - case XboxA: - buttonDown = (m_gamepads[0].bAnalogButtons[XINPUT_GAMEPAD_A] > 30); - break; - case XboxB: - buttonDown = (m_gamepads[0].bAnalogButtons[XINPUT_GAMEPAD_B] > 30); - break; - case XboxX: - buttonDown = (m_gamepads[0].bAnalogButtons[XINPUT_GAMEPAD_X] > 30); - break; - case XboxY: - buttonDown = (m_gamepads[0].bAnalogButtons[XINPUT_GAMEPAD_Y] > 30); - break; - case XboxWhite: - buttonDown = (m_gamepads[0].bAnalogButtons[XINPUT_GAMEPAD_WHITE] > 30); - break; - case XboxBlack: - buttonDown = (m_gamepads[0].bAnalogButtons[XINPUT_GAMEPAD_BLACK] > 30); - break; - case XboxLeftThumbButton: - buttonDown = ((m_gamepads[0].wButtons & XINPUT_GAMEPAD_LEFT_THUMB) != 0); - break; - case XboxRightThumbButton: - buttonDown = ((m_gamepads[0].wButtons & XINPUT_GAMEPAD_RIGHT_THUMB) != 0); - break; - default: - return false; - } - - if (buttonDown) - { - m_buttonPressed = true; - return true; - } - - return false; -} - -byte Input::IsLTriggerPressed() -{ - if (m_lastTick + m_triggerDelay > GetTickCount()) - return 0; - - if (m_gamepads[0].bAnalogButtons[XINPUT_GAMEPAD_LEFT_TRIGGER] < 30) - return 0; - else - { - m_buttonPressed = true; - return m_gamepads[0].bAnalogButtons[XINPUT_GAMEPAD_LEFT_TRIGGER]; - } -} - -byte Input::IsRTriggerPressed() -{ - if (m_lastTick + m_triggerDelay > GetTickCount()) - return 0; - - if (m_gamepads[0].bAnalogButtons[XINPUT_GAMEPAD_RIGHT_TRIGGER] < 30) - return 0; - else - { - m_buttonPressed = true; - return m_gamepads[0].bAnalogButtons[XINPUT_GAMEPAD_RIGHT_TRIGGER]; - } -} - -DWORD Input::GetButtonDelay() -{ - return m_buttonDelay; -} - -void Input::SetButtonDelay(DWORD milliseconds) -{ - m_buttonDelay = milliseconds; -} - -DWORD Input::GetTriggerDelay() -{ - return m_triggerDelay; -} - -void Input::SetTriggerDelay(DWORD milliseconds) -{ - m_triggerDelay = milliseconds; -} -#endif \ No newline at end of file diff --git a/xbox1/RetroLaunch/Input.h b/xbox1/RetroLaunch/Input.h deleted file mode 100644 index c20ae81868..0000000000 --- a/xbox1/RetroLaunch/Input.h +++ /dev/null @@ -1,171 +0,0 @@ -/** - * RetroLaunch 2012 - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. This program 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 this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. To contact the - * authors: Surreal64 CE Team (http://www.emuxtras.net) - */ - -#pragma once -#ifdef _XBOX -#include "Global.h" - -#define XBINPUT_DEADZONE 0.24f -#define XBINPUT_PRESS_BUTTON_DELAY 200 -#define XBINPUT_PRESS_TRIGGER_DELAY 100 - -struct XBGAMEPAD : public XINPUT_GAMEPAD -{ - // thumb stick values converted to range [-1,+1] - float fX1; - float fY1; - float fX2; - float fY2; - - // state of buttons tracked since last poll - word wLastButtons; - bool bLastAnalogButtons[8]; - word wPressedButtons; - bool bPressedAnalogButtons[8]; - - // rumble properties - XINPUT_RUMBLE Rumble; - XINPUT_FEEDBACK Feedback; - - // device properties - XINPUT_CAPABILITIES caps; - HANDLE hDevice; - - // flags for whether game pad was just inserted or removed - bool bInserted; - bool bRemoved; -}; - -#define XBOX_BUTTON_COUNT 23 - -enum XboxButton -{ - XboxLeftThumbLeft, - XboxLeftThumbRight, - XboxLeftThumbUp, - XboxLeftThumbDown, - - XboxRightThumbLeft, - XboxRightThumbRight, - XboxRightThumbUp, - XboxRightThumbDown, - - XboxDPadLeft, - XboxDPadRight, - XboxDPadUp, - XboxDPadDown, - - XboxStart, - XboxBack, - - XboxLeftThumbButton, - XboxRightThumbButton, - - XboxA, - XboxB, - XboxX, - XboxY, - - XboxBlack, - XboxWhite, - - XboxLeftTrigger, - XboxRightTrigger, -}; - -enum N64Button -{ - N64ThumbLeft, - N64ThumbRight, - N64ThumbUp, - N64ThumbDown, - - N64DPadLeft, - N64DPadRight, - N64DPadUp, - N64DPadDown, - - N64CButtonLeft, - N64CButtonRight, - N64CButtonUp, - N64CButtonDown, - - N64Start, - - N64A, - N64B, - - N64ZTrigger, - N64LeftTrigger, - N64RightTrigger -}; - - -enum SATURNButton -{ - SATURNDPadLeft, - SATURNDPadRight, - SATURNDPadUp, - SATURNDPadDown, - - SATURNA, - SATURNB, - SATURNX, - SATURNY, - SATURNC, - SATURNZ, - - SATURNStart, - - SATURNRightTrigger, - SATURNLeftTrigger -}; - -class Input -{ -public: - Input(void); - ~Input(void); - - bool Create(); - void GetInput(); - - bool IsButtonPressed(XboxButton button); - - byte IsLTriggerPressed(); - byte IsRTriggerPressed(); - - DWORD GetButtonDelay(); - void SetButtonDelay(DWORD milliseconds); - - DWORD GetTriggerDelay(); - void SetTriggerDelay(DWORD milliseconds); - -private: - void RefreshDevices(); - -private: - XINPUT_POLLING_PARAMETERS m_pollingParameters; - XINPUT_STATE m_inputStates[4]; - XBGAMEPAD m_gamepads[4]; - - bool m_buttonPressed; - DWORD m_buttonDelay; - DWORD m_triggerDelay; - DWORD m_lastTick; -}; - -extern Input g_input; -#endif \ No newline at end of file diff --git a/xbox1/RetroLaunch/MenuMain.cpp b/xbox1/RetroLaunch/MenuMain.cpp index b9cb79e3d5..4bd84c7cc2 100644 --- a/xbox1/RetroLaunch/MenuMain.cpp +++ b/xbox1/RetroLaunch/MenuMain.cpp @@ -16,7 +16,6 @@ #include "MenuMain.h" #include "Font.h" #include "RomList.h" -#include "Input.h" #include "../../console/retroarch_console.h" #include "../../general.h" diff --git a/xbox1/RetroLaunch/MenuManager.cpp b/xbox1/RetroLaunch/MenuManager.cpp index 9faaa9169c..4c25c7d485 100644 --- a/xbox1/RetroLaunch/MenuManager.cpp +++ b/xbox1/RetroLaunch/MenuManager.cpp @@ -15,7 +15,6 @@ #include "MenuManager.h" #include "MenuMain.h" -#include "Input.h" #include "../../general.h" @@ -73,21 +72,6 @@ void CMenuManager::Update() void CMenuManager::ProcessInput() { - //ADD: ProcessTarget -> switch to another menu - - //Return to Dashboard - if(g_input.IsLTriggerPressed() && - g_input.IsRTriggerPressed() && - g_input.IsButtonPressed(XboxBlack) && - g_input.IsButtonPressed(XboxWhite) && - g_input.IsButtonPressed(XboxBack) && - g_input.IsButtonPressed(XboxStart)) - { - - LD_LAUNCH_DASHBOARD LaunchData = { XLD_LAUNCH_DASHBOARD_MAIN_MENU }; - XLaunchNewImage( NULL, (LAUNCH_DATA*)&LaunchData ); - - } } diff --git a/xbox1/frontend/menu.cpp b/xbox1/frontend/menu.cpp index e9fc148608..6119ff253e 100644 --- a/xbox1/frontend/menu.cpp +++ b/xbox1/frontend/menu.cpp @@ -16,7 +16,6 @@ #include "../../xbox1/RetroLaunch/Global.h" #include "../../xbox1/RetroLaunch/IoSupport.h" -#include "../../xbox1/RetroLaunch/Input.h" #include "../../xbox1/RetroLaunch/Font.h" #include "../../xbox1/RetroLaunch/MenuManager.h" #include "../../xbox1/RetroLaunch/RomList.h" From 5930c85321747631989a76091ae2d2b6fd5bdffc Mon Sep 17 00:00:00 2001 From: twinaphex Date: Tue, 24 Jul 2012 16:09:01 +0200 Subject: [PATCH 30/51] (Xbox 1) RetroLaunch- remove unnneeded files --- xbox1/RetroLaunch/RetroLaunch.sln | 33 - xbox1/RetroLaunch/RetroLaunch.vcproj | 447 --- xbox1/RetroLaunch/SimpleIni.h | 3262 ----------------- xbox1/RetroLaunch/dist/Media/arial.ttf | Bin 65692 -> 0 bytes xbox1/RetroLaunch/dist/Media/menuMainBG.png | Bin 6415 -> 0 bytes .../dist/Media/menuMainRomSelectPanel.png | Bin 3206 -> 0 bytes xbox1/RetroLaunch/dist/Roms/Add roms here.txt | 0 7 files changed, 3742 deletions(-) delete mode 100644 xbox1/RetroLaunch/RetroLaunch.sln delete mode 100644 xbox1/RetroLaunch/RetroLaunch.vcproj delete mode 100644 xbox1/RetroLaunch/SimpleIni.h delete mode 100644 xbox1/RetroLaunch/dist/Media/arial.ttf delete mode 100644 xbox1/RetroLaunch/dist/Media/menuMainBG.png delete mode 100644 xbox1/RetroLaunch/dist/Media/menuMainRomSelectPanel.png delete mode 100644 xbox1/RetroLaunch/dist/Roms/Add roms here.txt diff --git a/xbox1/RetroLaunch/RetroLaunch.sln b/xbox1/RetroLaunch/RetroLaunch.sln deleted file mode 100644 index d2b910dcca..0000000000 --- a/xbox1/RetroLaunch/RetroLaunch.sln +++ /dev/null @@ -1,33 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 8.00 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RetroLaunch", "RetroLaunch.vcproj", "{14134C4E-7FD3-46F0-AD16-C32D952978EA}" - ProjectSection(ProjectDependencies) = postProject - EndProjectSection -EndProject -Global - GlobalSection(SolutionConfiguration) = preSolution - Debug = Debug - Profile = Profile - Profile_FastCap = Profile_FastCap - Release = Release - Release_LTCG = Release_LTCG - ReleaseTest = ReleaseTest - EndGlobalSection - GlobalSection(ProjectConfiguration) = postSolution - {14134C4E-7FD3-46F0-AD16-C32D952978EA}.Debug.ActiveCfg = Debug|Xbox - {14134C4E-7FD3-46F0-AD16-C32D952978EA}.Debug.Build.0 = Debug|Xbox - {14134C4E-7FD3-46F0-AD16-C32D952978EA}.Profile.ActiveCfg = Profile|Xbox - {14134C4E-7FD3-46F0-AD16-C32D952978EA}.Profile.Build.0 = Profile|Xbox - {14134C4E-7FD3-46F0-AD16-C32D952978EA}.Profile_FastCap.ActiveCfg = Profile_FastCap|Xbox - {14134C4E-7FD3-46F0-AD16-C32D952978EA}.Profile_FastCap.Build.0 = Profile_FastCap|Xbox - {14134C4E-7FD3-46F0-AD16-C32D952978EA}.Release.ActiveCfg = Release|Xbox - {14134C4E-7FD3-46F0-AD16-C32D952978EA}.Release.Build.0 = Release|Xbox - {14134C4E-7FD3-46F0-AD16-C32D952978EA}.Release_LTCG.ActiveCfg = Release_LTCG|Xbox - {14134C4E-7FD3-46F0-AD16-C32D952978EA}.Release_LTCG.Build.0 = Release_LTCG|Xbox - {14134C4E-7FD3-46F0-AD16-C32D952978EA}.ReleaseTest.ActiveCfg = ReleaseTest|Xbox - {14134C4E-7FD3-46F0-AD16-C32D952978EA}.ReleaseTest.Build.0 = ReleaseTest|Xbox - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - EndGlobalSection - GlobalSection(ExtensibilityAddIns) = postSolution - EndGlobalSection -EndGlobal diff --git a/xbox1/RetroLaunch/RetroLaunch.vcproj b/xbox1/RetroLaunch/RetroLaunch.vcproj deleted file mode 100644 index f2f561e265..0000000000 --- a/xbox1/RetroLaunch/RetroLaunch.vcproj +++ /dev/null @@ -1,447 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/xbox1/RetroLaunch/SimpleIni.h b/xbox1/RetroLaunch/SimpleIni.h deleted file mode 100644 index 882289f6fc..0000000000 --- a/xbox1/RetroLaunch/SimpleIni.h +++ /dev/null @@ -1,3262 +0,0 @@ -/** @mainpage - - -
Library SimpleIni -
File SimpleIni.h -
Author Brodie Thiesfield [code at jellycan dot com] -
Source http://code.jellycan.com/simpleini/ -
Version 4.13 -
- - Jump to the @link CSimpleIniTempl CSimpleIni @endlink interface documentation. - - @section intro INTRODUCTION - - This component allows an INI-style configuration file to be used on both - Windows and Linux/Unix. It is fast, simple and source code using this - component will compile unchanged on either OS. - - - @section features FEATURES - - - MIT Licence allows free use in all software (including GPL and commercial) - - multi-platform (Windows 95/98/ME/NT/2K/XP/2003, Windows CE, Linux, Unix) - - loading and saving of INI-style configuration files - - configuration files can have any newline format on all platforms - - liberal acceptance of file format - - key/values with no section - - removal of whitespace around sections, keys and values - - support for multi-line values (values with embedded newline characters) - - optional support for multiple keys with the same name - - optional case-insensitive sections and keys (for ASCII characters only) - - saves files with sections and keys in the same order as they were loaded - - preserves comments on the file, section and keys where possible. - - supports both char or wchar_t programming interfaces - - supports both MBCS (system locale) and UTF-8 file encodings - - system locale does not need to be UTF-8 on Linux/Unix to load UTF-8 file - - support for non-ASCII characters in section, keys, values and comments - - support for non-standard character types or file encodings - via user-written converter classes - - support for adding/modifying values programmatically - - compiles cleanly in the following compilers: - - Windows/VC6 (warning level 3) - - Windows/VC.NET 2003 (warning level 4) - - Windows/VC 2005 (warning level 4) - - Linux/gcc (-Wall) - - - @section usage USAGE SUMMARY - - -# Define the appropriate symbol for the converter you wish to use and - include the SimpleIni.h header file. If no specific converter is defined - then the default converter is used. The default conversion mode uses - SI_CONVERT_WIN32 on Windows and SI_CONVERT_GENERIC on all other - platforms. If you are using ICU then SI_CONVERT_ICU is supported on all - platforms. - -# Declare an instance the appropriate class. Note that the following - definitions are just shortcuts for commonly used types. Other types - (PRUnichar, unsigned short, unsigned char) are also possible. - -
Interface Case-sensitive Load UTF-8 Load MBCS Typedef -
SI_CONVERT_GENERIC -
char No Yes Yes #1 CSimpleIniA -
char Yes Yes Yes CSimpleIniCaseA -
wchar_t No Yes Yes CSimpleIniW -
wchar_t Yes Yes Yes CSimpleIniCaseW -
SI_CONVERT_WIN32 -
char No No #2 Yes CSimpleIniA -
char Yes Yes Yes CSimpleIniCaseA -
wchar_t No Yes Yes CSimpleIniW -
wchar_t Yes Yes Yes CSimpleIniCaseW -
SI_CONVERT_ICU -
char No Yes Yes CSimpleIniA -
char Yes Yes Yes CSimpleIniCaseA -
UChar No Yes Yes CSimpleIniW -
UChar Yes Yes Yes CSimpleIniCaseW -
- #1 On Windows you are better to use CSimpleIniA with SI_CONVERT_WIN32.
- #2 Only affects Windows. On Windows this uses MBCS functions and - so may fold case incorrectly leading to uncertain results. - -# Call Load() or LoadFile() to load and parse the INI configuration file - -# Access and modify the data of the file using the following functions - -
GetAllSections Return all section names -
GetAllKeys Return all key names within a section -
GetAllValues Return all values within a section & key -
GetSection Return all key names and values in a section -
GetSectionSize Return the number of keys in a section -
GetValue Return a value for a section & key -
SetValue Add or update a value for a section & key -
Delete Remove a section, or a key from a section -
- -# Call Save() or SaveFile() to save the INI configuration data - - @section iostreams IO STREAMS - - SimpleIni supports reading from and writing to STL IO streams. Enable this - by defining SI_SUPPORT_IOSTREAMS before including the SimpleIni.h header - file. Ensure that if the streams are backed by a file (e.g. ifstream or - ofstream) then the flag ios_base::binary has been used when the file was - opened. - - @section multiline MULTI-LINE VALUES - - Values that span multiple lines are created using the following format. - -
-        key = <<
-
-    Note the following:
-    - The text used for ENDTAG can be anything and is used to find
-      where the multi-line text ends.
-    - The newline after ENDTAG in the start tag, and the newline
-      before ENDTAG in the end tag is not included in the data value.
-    - The ending tag must be on it's own line with no whitespace before
-      or after it.
-    - The multi-line value is modified at load so that each line in the value
-      is delimited by a single '\\n' character on all platforms. At save time
-      it will be converted into the newline format used by the current
-      platform.
-
-    @section comments COMMENTS
-
-    Comments are preserved in the file within the following restrictions:
-    - Every file may have a single "file comment". It must start with the
-      first character in the file, and will end with the first non-comment
-      line in the file.
-    - Every section may have a single "section comment". It will start
-      with the first comment line following the file comment, or the last
-      data entry. It ends at the beginning of the section.
-    - Every key may have a single "key comment". This comment will start
-      with the first comment line following the section start, or the file
-      comment if there is no section name.
-    - Comments are set at the time that the file, section or key is first
-      created. The only way to modify a comment on a section or a key is to
-      delete that entry and recreate it with the new comment. There is no
-      way to change the file comment.
-
-    @section save SAVE ORDER
-
-    The sections and keys are written out in the same order as they were
-    read in from the file. Sections and keys added to the data after the
-    file has been loaded will be added to the end of the file when it is
-    written. There is no way to specify the location of a section or key
-    other than in first-created, first-saved order.
-
-    @section notes NOTES
-
-    - To load UTF-8 data on Windows 95, you need to use Microsoft Layer for
-      Unicode, or SI_CONVERT_GENERIC, or SI_CONVERT_ICU.
-    - When using SI_CONVERT_GENERIC, ConvertUTF.c must be compiled and linked.
-    - When using SI_CONVERT_ICU, ICU header files must be on the include
-      path and icuuc.lib must be linked in.
-    - To load a UTF-8 file on Windows AND expose it with SI_CHAR == char,
-      you should use SI_CONVERT_GENERIC.
-    - The collation (sorting) order used for sections and keys returned from
-      iterators is NOT DEFINED. If collation order of the text is important
-      then it should be done yourself by either supplying a replacement
-      SI_STRLESS class, or by sorting the strings external to this library.
-    - Usage of the  header on Windows can be disabled by defining
-      SI_NO_MBCS. This is defined automatically on Windows CE platforms.
-
-
-    @section licence MIT LICENCE
-
-    The licence text below is the boilerplate "MIT Licence" used from:
-    http://www.opensource.org/licenses/mit-license.php
-
-    Copyright (c) 2006-2008, Brodie Thiesfield
-
-    Permission is hereby granted, free of charge, to any person obtaining a copy
-    of this software and associated documentation files (the "Software"), to deal
-    in the Software without restriction, including without limitation the rights
-    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-    copies of the Software, and to permit persons to whom the Software is furnished
-    to do so, subject to the following conditions:
-
-    The above copyright notice and this permission notice shall be included in
-    all copies or substantial portions of the Software.
-
-    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-    FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-    COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-    IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-    CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-#ifndef INCLUDED_SimpleIni_h
-#define INCLUDED_SimpleIni_h
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1020)
-# pragma once
-#endif
-
-// Disable these warnings in MSVC:
-//  4127 "conditional expression is constant" as the conversion classes trigger
-//  it with the statement if (sizeof(SI_CHAR) == sizeof(char)). This test will
-//  be optimized away in a release build.
-//  4503 'insert' : decorated name length exceeded, name was truncated
-//  4702 "unreachable code" as the MS STL header causes it in release mode.
-//  Again, the code causing the warning will be cleaned up by the compiler.
-//  4786 "identifier truncated to 256 characters" as this is thrown hundreds
-//  of times VC6 as soon as STL is used.
-#ifdef _MSC_VER
-# pragma warning (push)
-# pragma warning (disable: 4127 4503 4702 4786)
-#endif
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-
-#ifdef SI_SUPPORT_IOSTREAMS
-# include 
-#endif // SI_SUPPORT_IOSTREAMS
-
-#ifdef _DEBUG
-# ifndef assert
-#  include 
-# endif
-# define SI_ASSERT(x)   assert(x)
-#else
-# define SI_ASSERT(x)
-#endif
-
-enum SI_Error {
-    SI_OK       =  0,   //!< No error
-    SI_UPDATED  =  1,   //!< An existing value was updated
-    SI_INSERTED =  2,   //!< A new value was inserted
-
-    // note: test for any error with (retval < 0)
-    SI_FAIL     = -1,   //!< Generic failure
-    SI_NOMEM    = -2,   //!< Out of memory error
-    SI_FILE     = -3    //!< File error (see errno for detail error)
-};
-
-#define SI_UTF8_SIGNATURE     "\xEF\xBB\xBF"
-
-#ifdef _WIN32
-# define SI_NEWLINE_A   "\r\n"
-# define SI_NEWLINE_W   L"\r\n"
-#else // !_WIN32
-# define SI_NEWLINE_A   "\n"
-# define SI_NEWLINE_W   L"\n"
-#endif // _WIN32
-
-#if defined(SI_CONVERT_ICU)
-# include 
-#endif
-
-#if defined(_WIN32)
-# define SI_HAS_WIDE_FILE
-# define SI_WCHAR_T     wchar_t
-#elif defined(SI_CONVERT_ICU)
-# define SI_HAS_WIDE_FILE
-# define SI_WCHAR_T     UChar
-#endif
-
-
-// ---------------------------------------------------------------------------
-//                              MAIN TEMPLATE CLASS
-// ---------------------------------------------------------------------------
-
-/** Simple INI file reader.
-
-    This can be instantiated with the choice of unicode or native characterset,
-    and case sensitive or insensitive comparisons of section and key names.
-    The supported combinations are pre-defined with the following typedefs:
-
-    
-        
Interface Case-sensitive Typedef -
char No CSimpleIniA -
char Yes CSimpleIniCaseA -
wchar_t No CSimpleIniW -
wchar_t Yes CSimpleIniCaseW -
- - Note that using other types for the SI_CHAR is supported. For instance, - unsigned char, unsigned short, etc. Note that where the alternative type - is a different size to char/wchar_t you may need to supply new helper - classes for SI_STRLESS and SI_CONVERTER. - */ -template -class CSimpleIniTempl -{ -public: - /** key entry */ - struct Entry { - const SI_CHAR * pItem; - const SI_CHAR * pComment; - int nOrder; - - Entry(const SI_CHAR * a_pszItem = NULL, int a_nOrder = 0) - : pItem(a_pszItem) - , pComment(NULL) - , nOrder(a_nOrder) - { } - Entry(const SI_CHAR * a_pszItem, const SI_CHAR * a_pszComment, int a_nOrder) - : pItem(a_pszItem) - , pComment(a_pszComment) - , nOrder(a_nOrder) - { } - Entry(const Entry & rhs) { operator=(rhs); } - Entry & operator=(const Entry & rhs) { - pItem = rhs.pItem; - pComment = rhs.pComment; - nOrder = rhs.nOrder; - return *this; - } - -#if defined(_MSC_VER) && _MSC_VER <= 1200 - /** STL of VC6 doesn't allow me to specify my own comparator for list::sort() */ - bool operator<(const Entry & rhs) const { return LoadOrder()(*this, rhs); } - bool operator>(const Entry & rhs) const { return LoadOrder()(rhs, *this); } -#endif - - /** Strict less ordering by name of key only */ - struct KeyOrder : std::binary_function { - bool operator()(const Entry & lhs, const Entry & rhs) const { - const static SI_STRLESS isLess = SI_STRLESS(); - return isLess(lhs.pItem, rhs.pItem); - } - }; - - /** Strict less ordering by order, and then name of key */ - struct LoadOrder : std::binary_function { - bool operator()(const Entry & lhs, const Entry & rhs) const { - if (lhs.nOrder != rhs.nOrder) { - return lhs.nOrder < rhs.nOrder; - } - return KeyOrder()(lhs.pItem, rhs.pItem); - } - }; - }; - - /** map keys to values */ - typedef std::multimap TKeyVal; - - /** map sections to key/value map */ - typedef std::map TSection; - - /** set of dependent string pointers. Note that these pointers are - dependent on memory owned by CSimpleIni. - */ - typedef std::list TNamesDepend; - - /** interface definition for the OutputWriter object to pass to Save() - in order to output the INI file data. - */ - class OutputWriter { - public: - OutputWriter() { } - virtual ~OutputWriter() { } - virtual void Write(const char * a_pBuf) = 0; - private: - OutputWriter(const OutputWriter &); // disable - OutputWriter & operator=(const OutputWriter &); // disable - }; - - /** OutputWriter class to write the INI data to a file */ - class FileWriter : public OutputWriter { - FILE * m_file; - public: - FileWriter(FILE * a_file) : m_file(a_file) { } - void Write(const char * a_pBuf) { - fputs(a_pBuf, m_file); - } - private: - FileWriter(const FileWriter &); // disable - FileWriter & operator=(const FileWriter &); // disable - }; - - /** OutputWriter class to write the INI data to a string */ - class StringWriter : public OutputWriter { - std::string & m_string; - public: - StringWriter(std::string & a_string) : m_string(a_string) { } - void Write(const char * a_pBuf) { - m_string.append(a_pBuf); - } - private: - StringWriter(const StringWriter &); // disable - StringWriter & operator=(const StringWriter &); // disable - }; - -#ifdef SI_SUPPORT_IOSTREAMS - /** OutputWriter class to write the INI data to an ostream */ - class StreamWriter : public OutputWriter { - std::ostream & m_ostream; - public: - StreamWriter(std::ostream & a_ostream) : m_ostream(a_ostream) { } - void Write(const char * a_pBuf) { - m_ostream << a_pBuf; - } - private: - StreamWriter(const StreamWriter &); // disable - StreamWriter & operator=(const StreamWriter &); // disable - }; -#endif // SI_SUPPORT_IOSTREAMS - - /** Characterset conversion utility class to convert strings to the - same format as is used for the storage. - */ - class Converter : private SI_CONVERTER { - public: - Converter(bool a_bStoreIsUtf8) : SI_CONVERTER(a_bStoreIsUtf8) { - m_scratch.resize(1024); - } - Converter(const Converter & rhs) { operator=(rhs); } - Converter & operator=(const Converter & rhs) { - m_scratch = rhs.m_scratch; - return *this; - } - bool ConvertToStore(const SI_CHAR * a_pszString) { - size_t uLen = SizeToStore(a_pszString); - if (uLen == (size_t)(-1)) { - return false; - } - while (uLen > m_scratch.size()) { - m_scratch.resize(m_scratch.size() * 2); - } - return SI_CONVERTER::ConvertToStore( - a_pszString, - const_cast(m_scratch.data()), - m_scratch.size()); - } - const char * Data() { return m_scratch.data(); } - private: - std::string m_scratch; - }; - -public: - /*-----------------------------------------------------------------------*/ - - /** Default constructor. - - @param a_bIsUtf8 See the method SetUnicode() for details. - @param a_bMultiKey See the method SetMultiKey() for details. - @param a_bMultiLine See the method SetMultiLine() for details. - */ - CSimpleIniTempl( - bool a_bIsUtf8 = false, - bool a_bMultiKey = false, - bool a_bMultiLine = false - ); - - /** Destructor */ - ~CSimpleIniTempl(); - - /** Deallocate all memory stored by this object */ - void Reset(); - - /*-----------------------------------------------------------------------*/ - /** @{ @name Settings */ - - /** Set the storage format of the INI data. This affects both the loading - and saving of the INI data using all of the Load/Save API functions. - This value cannot be changed after any INI data has been loaded. - - If the file is not set to Unicode (UTF-8), then the data encoding is - assumed to be the OS native encoding. This encoding is the system - locale on Linux/Unix and the legacy MBCS encoding on Windows NT/2K/XP. - If the storage format is set to Unicode then the file will be loaded - as UTF-8 encoded data regardless of the native file encoding. If - SI_CHAR == char then all of the char* parameters take and return UTF-8 - encoded data regardless of the system locale. - - \param a_bIsUtf8 Assume UTF-8 encoding for the source? - */ - void SetUnicode(bool a_bIsUtf8 = true) { - if (!m_pData) m_bStoreIsUtf8 = a_bIsUtf8; - } - - /** Get the storage format of the INI data. */ - bool IsUnicode() const { return m_bStoreIsUtf8; } - - /** Should multiple identical keys be permitted in the file. If set to false - then the last value encountered will be used as the value of the key. - If set to true, then all values will be available to be queried. For - example, with the following input: - -
-        [section]
-        test=value1
-        test=value2
-        
- - Then with SetMultiKey(true), both of the values "value1" and "value2" - will be returned for the key test. If SetMultiKey(false) is used, then - the value for "test" will only be "value2". This value may be changed - at any time. - - \param a_bAllowMultiKey Allow multi-keys in the source? - */ - void SetMultiKey(bool a_bAllowMultiKey = true) { - m_bAllowMultiKey = a_bAllowMultiKey; - } - - /** Get the storage format of the INI data. */ - bool IsMultiKey() const { return m_bAllowMultiKey; } - - /** Should data values be permitted to span multiple lines in the file. If - set to false then the multi-line construct << - SI_CHAR FORMAT - char same format as when loaded (MBCS or UTF-8) - wchar_t UTF-8 - other UTF-8 - - - Note that comments from the original data is preserved as per the - documentation on comments. The order of the sections and values - from the original file will be preserved. - - Any data prepended or appended to the output device must use the the - same format (MBCS or UTF-8). You may use the GetConverter() method to - convert text to the correct format regardless of the output format - being used by SimpleIni. - - To add a BOM to UTF-8 data, write it out manually at the very beginning - like is done in SaveFile when a_bUseBOM is true. - - @param a_oOutput Output writer to write the data to. - - @param a_bAddSignature Prepend the UTF-8 BOM if the output data is in - UTF-8 format. If it is not UTF-8 then this value is - ignored. Do not set this to true if anything has - already been written to the OutputWriter. - - @return SI_Error See error definitions - */ - SI_Error Save( - OutputWriter & a_oOutput, - bool a_bAddSignature = false - ) const; - -#ifdef SI_SUPPORT_IOSTREAMS - /** Save the INI data to an ostream. See Save() for details. - - @param a_ostream String to have the INI data appended to. - - @param a_bAddSignature Prepend the UTF-8 BOM if the output data is in - UTF-8 format. If it is not UTF-8 then this value is - ignored. Do not set this to true if anything has - already been written to the stream. - - @return SI_Error See error definitions - */ - SI_Error Save( - std::ostream & a_ostream, - bool a_bAddSignature = false - ) const - { - StreamWriter writer(a_ostream); - return Save(writer, a_bAddSignature); - } -#endif // SI_SUPPORT_IOSTREAMS - - /** Append the INI data to a string. See Save() for details. - - @param a_sBuffer String to have the INI data appended to. - - @param a_bAddSignature Prepend the UTF-8 BOM if the output data is in - UTF-8 format. If it is not UTF-8 then this value is - ignored. Do not set this to true if anything has - already been written to the string. - - @return SI_Error See error definitions - */ - SI_Error Save( - std::string & a_sBuffer, - bool a_bAddSignature = false - ) const - { - StringWriter writer(a_sBuffer); - return Save(writer, a_bAddSignature); - } - - /*-----------------------------------------------------------------------*/ - /** @} - @{ @name Accessing INI Data */ - - /** Retrieve all section names. The list is returned as an STL vector of - names and can be iterated or searched as necessary. Note that the - sort order of the returned strings is NOT DEFINED. You can sort - the names into the load order if desired. Search this file for ".sort" - for an example. - - NOTE! This structure contains only pointers to strings. The actual - string data is stored in memory owned by CSimpleIni. Ensure that the - CSimpleIni object is not destroyed or Reset() while these pointers - are in use! - - @param a_names Vector that will receive all of the section - names. See note above! - */ - void GetAllSections( - TNamesDepend & a_names - ) const; - - /** Retrieve all unique key names in a section. The sort order of the - returned strings is NOT DEFINED. You can sort the names into the load - order if desired. Search this file for ".sort" for an example. Only - unique key names are returned. - - NOTE! This structure contains only pointers to strings. The actual - string data is stored in memory owned by CSimpleIni. Ensure that the - CSimpleIni object is not destroyed or Reset() while these strings - are in use! - - @param a_pSection Section to request data for - @param a_names List that will receive all of the key - names. See note above! - - @return true Section was found. - @return false Matching section was not found. - */ - bool GetAllKeys( - const SI_CHAR * a_pSection, - TNamesDepend & a_names - ) const; - - /** Retrieve all values for a specific key. This method can be used when - multiple keys are both enabled and disabled. Note that the sort order - of the returned strings is NOT DEFINED. You can sort the names into - the load order if desired. Search this file for ".sort" for an example. - - NOTE! The returned values are pointers to string data stored in memory - owned by CSimpleIni. Ensure that the CSimpleIni object is not destroyed - or Reset while you are using this pointer! - - @param a_pSection Section to search - @param a_pKey Key to search for - @param a_values List to return if the key is not found - - @return true Key was found. - @return false Matching section/key was not found. - */ - bool GetAllValues( - const SI_CHAR * a_pSection, - const SI_CHAR * a_pKey, - TNamesDepend & a_values - ) const; - - /** Query the number of keys in a specific section. Note that if multiple - keys are enabled, then this value may be different to the number of - keys returned by GetAllKeys. - - @param a_pSection Section to request data for - - @return -1 Section does not exist in the file - @return >=0 Number of keys in the section - */ - int GetSectionSize( - const SI_CHAR * a_pSection - ) const; - - /** Retrieve all key and value pairs for a section. The data is returned - as a pointer to an STL map and can be iterated or searched as - desired. Note that multiple entries for the same key may exist when - multiple keys have been enabled. - - NOTE! This structure contains only pointers to strings. The actual - string data is stored in memory owned by CSimpleIni. Ensure that the - CSimpleIni object is not destroyed or Reset() while these strings - are in use! - - @param a_pSection Name of the section to return - @return boolean Was a section matching the supplied - name found. - */ - const TKeyVal * GetSection( - const SI_CHAR * a_pSection - ) const; - - /** Retrieve the value for a specific key. If multiple keys are enabled - (see SetMultiKey) then only the first value associated with that key - will be returned, see GetAllValues for getting all values with multikey. - - NOTE! The returned value is a pointer to string data stored in memory - owned by CSimpleIni. Ensure that the CSimpleIni object is not destroyed - or Reset while you are using this pointer! - - @param a_pSection Section to search - @param a_pKey Key to search for - @param a_pDefault Value to return if the key is not found - @param a_pHasMultiple Optionally receive notification of if there are - multiple entries for this key. - - @return a_pDefault Key was not found in the section - @return other Value of the key - */ - const SI_CHAR * GetValue( - const SI_CHAR * a_pSection, - const SI_CHAR * a_pKey, - const SI_CHAR * a_pDefault = NULL, - bool * a_pHasMultiple = NULL - ) const; - - /** Retrieve a numeric value for a specific key. If multiple keys are enabled - (see SetMultiKey) then only the first value associated with that key - will be returned, see GetAllValues for getting all values with multikey. - - @param a_pSection Section to search - @param a_pKey Key to search for - @param a_nDefault Value to return if the key is not found - @param a_pHasMultiple Optionally receive notification of if there are - multiple entries for this key. - - @return a_nDefault Key was not found in the section - @return other Value of the key - */ - long GetLongValue( - const SI_CHAR * a_pSection, - const SI_CHAR * a_pKey, - long a_nDefault = 0, - bool * a_pHasMultiple = NULL - ) const; - - /** Retrieve a boolean value for a specific key. If multiple keys are enabled - (see SetMultiKey) then only the first value associated with that key - will be returned, see GetAllValues for getting all values with multikey. - - Strings starting with "t", "y", "on" or "1" are returned as logically true. - Strings starting with "f", "n", "of" or "0" are returned as logically false. - For all other values the default is returned. Character comparisons are - case-insensitive. - - @param a_pSection Section to search - @param a_pKey Key to search for - @param a_bDefault Value to return if the key is not found - @param a_pHasMultiple Optionally receive notification of if there are - multiple entries for this key. - - @return a_nDefault Key was not found in the section - @return other Value of the key - */ - bool GetBoolValue( - const SI_CHAR * a_pSection, - const SI_CHAR * a_pKey, - bool a_bDefault = false, - bool * a_pHasMultiple = NULL - ) const; - - /** Add or update a section or value. This will always insert - when multiple keys are enabled. - - @param a_pSection Section to add or update - @param a_pKey Key to add or update. Set to NULL to - create an empty section. - @param a_pValue Value to set. Set to NULL to create an - empty section. - @param a_pComment Comment to be associated with the section or the - key. If a_pKey is NULL then it will be associated - with the section, otherwise the key. Note that a - comment may be set ONLY when the section or key is - first created (i.e. when this function returns the - value SI_INSERTED). If you wish to create a section - with a comment then you need to create the section - separately to the key. The comment string must be - in full comment form already (have a comment - character starting every line). - @param a_bForceReplace Should all existing values in a multi-key INI - file be replaced with this entry. This option has - no effect if not using multi-key files. The - difference between Delete/SetValue and SetValue - with a_bForceReplace = true, is that the load - order and comment will be preserved this way. - - @return SI_Error See error definitions - @return SI_UPDATED Value was updated - @return SI_INSERTED Value was inserted - */ - SI_Error SetValue( - const SI_CHAR * a_pSection, - const SI_CHAR * a_pKey, - const SI_CHAR * a_pValue, - const SI_CHAR * a_pComment = NULL, - bool a_bForceReplace = false - ) - { - return AddEntry(a_pSection, a_pKey, a_pValue, a_pComment, a_bForceReplace, true); - } - - /** Add or update a numeric value. This will always insert - when multiple keys are enabled. - - @param a_pSection Section to add or update - @param a_pKey Key to add or update. - @param a_nValue Value to set. - @param a_pComment Comment to be associated with the key. See the - notes on SetValue() for comments. - @param a_bUseHex By default the value will be written to the file - in decimal format. Set this to true to write it - as hexadecimal. - @param a_bForceReplace Should all existing values in a multi-key INI - file be replaced with this entry. This option has - no effect if not using multi-key files. The - difference between Delete/SetLongValue and - SetLongValue with a_bForceReplace = true, is that - the load order and comment will be preserved this - way. - - @return SI_Error See error definitions - @return SI_UPDATED Value was updated - @return SI_INSERTED Value was inserted - */ - SI_Error SetLongValue( - const SI_CHAR * a_pSection, - const SI_CHAR * a_pKey, - long a_nValue, - const SI_CHAR * a_pComment = NULL, - bool a_bUseHex = false, - bool a_bForceReplace = false - ); - - /** Add or update a boolean value. This will always insert - when multiple keys are enabled. - - @param a_pSection Section to add or update - @param a_pKey Key to add or update. - @param a_bValue Value to set. - @param a_pComment Comment to be associated with the key. See the - notes on SetValue() for comments. - @param a_bForceReplace Should all existing values in a multi-key INI - file be replaced with this entry. This option has - no effect if not using multi-key files. The - difference between Delete/SetBoolValue and - SetBoolValue with a_bForceReplace = true, is that - the load order and comment will be preserved this - way. - - @return SI_Error See error definitions - @return SI_UPDATED Value was updated - @return SI_INSERTED Value was inserted - */ - SI_Error SetBoolValue( - const SI_CHAR * a_pSection, - const SI_CHAR * a_pKey, - bool a_bValue, - const SI_CHAR * a_pComment = NULL, - bool a_bForceReplace = false - ); - - /** Delete an entire section, or a key from a section. Note that the - data returned by GetSection is invalid and must not be used after - anything has been deleted from that section using this method. - Note when multiple keys is enabled, this will delete all keys with - that name; there is no way to selectively delete individual key/values - in this situation. - - @param a_pSection Section to delete key from, or if - a_pKey is NULL, the section to remove. - @param a_pKey Key to remove from the section. Set to - NULL to remove the entire section. - @param a_bRemoveEmpty If the section is empty after this key has - been deleted, should the empty section be - removed? - - @return true Key or section was deleted. - @return false Key or section was not found. - */ - bool Delete( - const SI_CHAR * a_pSection, - const SI_CHAR * a_pKey, - bool a_bRemoveEmpty = false - ); - - /*-----------------------------------------------------------------------*/ - /** @} - @{ @name Converter */ - - /** Return a conversion object to convert text to the same encoding - as is used by the Save(), SaveFile() and SaveString() functions. - Use this to prepare the strings that you wish to append or prepend - to the output INI data. - */ - Converter GetConverter() const { - return Converter(m_bStoreIsUtf8); - } - - /*-----------------------------------------------------------------------*/ - /** @} */ - -private: - // copying is not permitted - CSimpleIniTempl(const CSimpleIniTempl &); // disabled - CSimpleIniTempl & operator=(const CSimpleIniTempl &); // disabled - - /** Parse the data looking for a file comment and store it if found. - */ - SI_Error FindFileComment( - SI_CHAR *& a_pData, - bool a_bCopyStrings - ); - - /** Parse the data looking for the next valid entry. The memory pointed to - by a_pData is modified by inserting NULL characters. The pointer is - updated to the current location in the block of text. - */ - bool FindEntry( - SI_CHAR *& a_pData, - const SI_CHAR *& a_pSection, - const SI_CHAR *& a_pKey, - const SI_CHAR *& a_pVal, - const SI_CHAR *& a_pComment - ) const; - - /** Add the section/key/value to our data. - - @param a_pSection Section name. Sections will be created if they - don't already exist. - @param a_pKey Key name. May be NULL to create an empty section. - Existing entries will be updated. New entries will - be created. - @param a_pValue Value for the key. - @param a_pComment Comment to be associated with the section or the - key. If a_pKey is NULL then it will be associated - with the section, otherwise the key. This must be - a string in full comment form already (have a - comment character starting every line). - @param a_bForceReplace Should all existing values in a multi-key INI - file be replaced with this entry. This option has - no effect if not using multi-key files. The - difference between Delete/AddEntry and AddEntry - with a_bForceReplace = true, is that the load - order and comment will be preserved this way. - @param a_bCopyStrings Should copies of the strings be made or not. - If false then the pointers will be used as is. - */ - SI_Error AddEntry( - const SI_CHAR * a_pSection, - const SI_CHAR * a_pKey, - const SI_CHAR * a_pValue, - const SI_CHAR * a_pComment, - bool a_bForceReplace, - bool a_bCopyStrings - ); - - /** Is the supplied character a whitespace character? */ - inline bool IsSpace(SI_CHAR ch) const { - return (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n'); - } - - /** Does the supplied character start a comment line? */ - inline bool IsComment(SI_CHAR ch) const { - return (ch == ';' || ch == '#'); - } - - - /** Skip over a newline character (or characters) for either DOS or UNIX */ - inline void SkipNewLine(SI_CHAR *& a_pData) const { - a_pData += (*a_pData == '\r' && *(a_pData+1) == '\n') ? 2 : 1; - } - - /** Make a copy of the supplied string, replacing the original pointer */ - SI_Error CopyString(const SI_CHAR *& a_pString); - - /** Delete a string from the copied strings buffer if necessary */ - void DeleteString(const SI_CHAR * a_pString); - - /** Internal use of our string comparison function */ - bool IsLess(const SI_CHAR * a_pLeft, const SI_CHAR * a_pRight) const { - const static SI_STRLESS isLess = SI_STRLESS(); - return isLess(a_pLeft, a_pRight); - } - - bool IsMultiLineTag(const SI_CHAR * a_pData) const; - bool IsMultiLineData(const SI_CHAR * a_pData) const; - bool LoadMultiLineText( - SI_CHAR *& a_pData, - const SI_CHAR *& a_pVal, - const SI_CHAR * a_pTagName, - bool a_bAllowBlankLinesInComment = false - ) const; - bool IsNewLineChar(SI_CHAR a_c) const; - - bool OutputMultiLineText( - OutputWriter & a_oOutput, - Converter & a_oConverter, - const SI_CHAR * a_pText - ) const; - -private: - /** Copy of the INI file data in our character format. This will be - modified when parsed to have NULL characters added after all - interesting string entries. All of the string pointers to sections, - keys and values point into this block of memory. - */ - SI_CHAR * m_pData; - - /** Length of the data that we have stored. Used when deleting strings - to determine if the string is stored here or in the allocated string - buffer. - */ - size_t m_uDataLen; - - /** File comment for this data, if one exists. */ - const SI_CHAR * m_pFileComment; - - /** Parsed INI data. Section -> (Key -> Value). */ - TSection m_data; - - /** This vector stores allocated memory for copies of strings that have - been supplied after the file load. It will be empty unless SetValue() - has been called. - */ - TNamesDepend m_strings; - - /** Is the format of our datafile UTF-8 or MBCS? */ - bool m_bStoreIsUtf8; - - /** Are multiple values permitted for the same key? */ - bool m_bAllowMultiKey; - - /** Are data values permitted to span multiple lines? */ - bool m_bAllowMultiLine; - - /** Should spaces be written out surrounding the equals sign? */ - bool m_bSpaces; - - /** Next order value, used to ensure sections and keys are output in the - same order that they are loaded/added. - */ - int m_nOrder; -}; - -// --------------------------------------------------------------------------- -// IMPLEMENTATION -// --------------------------------------------------------------------------- - -template -CSimpleIniTempl::CSimpleIniTempl( - bool a_bIsUtf8, - bool a_bAllowMultiKey, - bool a_bAllowMultiLine - ) - : m_pData(0) - , m_uDataLen(0) - , m_pFileComment(NULL) - , m_bStoreIsUtf8(a_bIsUtf8) - , m_bAllowMultiKey(a_bAllowMultiKey) - , m_bAllowMultiLine(a_bAllowMultiLine) - , m_bSpaces(true) - , m_nOrder(0) -{ } - -template -CSimpleIniTempl::~CSimpleIniTempl() -{ - Reset(); -} - -template -void -CSimpleIniTempl::Reset() -{ - // remove all data - delete[] m_pData; - m_pData = NULL; - m_uDataLen = 0; - m_pFileComment = NULL; - if (!m_data.empty()) { - m_data.erase(m_data.begin(), m_data.end()); - } - - // remove all strings - if (!m_strings.empty()) { - typename TNamesDepend::iterator i = m_strings.begin(); - for (; i != m_strings.end(); ++i) { - delete[] const_cast(i->pItem); - } - m_strings.erase(m_strings.begin(), m_strings.end()); - } -} - -template -SI_Error -CSimpleIniTempl::LoadFile( - const char * a_pszFile - ) -{ - FILE * fp = NULL; -#if __STDC_WANT_SECURE_LIB__ && !_WIN32_WCE - fopen_s(&fp, a_pszFile, "rb"); -#else // !__STDC_WANT_SECURE_LIB__ - fp = fopen(a_pszFile, "rb"); -#endif // __STDC_WANT_SECURE_LIB__ - if (!fp) { - return SI_FILE; - } - SI_Error rc = LoadFile(fp); - fclose(fp); - return rc; -} - -#ifdef SI_HAS_WIDE_FILE -template -SI_Error -CSimpleIniTempl::LoadFile( - const SI_WCHAR_T * a_pwszFile - ) -{ -#ifdef _WIN32 - FILE * fp = NULL; -#if __STDC_WANT_SECURE_LIB__ && !_WIN32_WCE - _wfopen_s(&fp, a_pwszFile, L"rb"); -#else // !__STDC_WANT_SECURE_LIB__ - fp = _wfopen(a_pwszFile, L"rb"); -#endif // __STDC_WANT_SECURE_LIB__ - if (!fp) return SI_FILE; - SI_Error rc = LoadFile(fp); - fclose(fp); - return rc; -#else // !_WIN32 (therefore SI_CONVERT_ICU) - char szFile[256]; - u_austrncpy(szFile, a_pwszFile, sizeof(szFile)); - return LoadFile(szFile); -#endif // _WIN32 -} -#endif // SI_HAS_WIDE_FILE - -template -SI_Error -CSimpleIniTempl::LoadFile( - FILE * a_fpFile - ) -{ - // load the raw file data - int retval = fseek(a_fpFile, 0, SEEK_END); - if (retval != 0) { - return SI_FILE; - } - long lSize = ftell(a_fpFile); - if (lSize < 0) { - return SI_FILE; - } - if (lSize == 0) { - return SI_OK; - } - char * pData = new char[lSize]; - if (!pData) { - return SI_NOMEM; - } - fseek(a_fpFile, 0, SEEK_SET); - size_t uRead = fread(pData, sizeof(char), lSize, a_fpFile); - if (uRead != (size_t) lSize) { - delete[] pData; - return SI_FILE; - } - - // convert the raw data to unicode - SI_Error rc = Load(pData, uRead); - delete[] pData; - return rc; -} - -template -SI_Error -CSimpleIniTempl::Load( - const char * a_pData, - size_t a_uDataLen - ) -{ - SI_CONVERTER converter(m_bStoreIsUtf8); - - if (a_uDataLen == 0) { - return SI_OK; - } - - // consume the UTF-8 BOM if it exists - if (m_bStoreIsUtf8 && a_uDataLen >= 3) { - if (memcmp(a_pData, SI_UTF8_SIGNATURE, 3) == 0) { - a_pData += 3; - a_uDataLen -= 3; - } - } - - // determine the length of the converted data - size_t uLen = converter.SizeFromStore(a_pData, a_uDataLen); - if (uLen == (size_t)(-1)) { - return SI_FAIL; - } - - // allocate memory for the data, ensure that there is a NULL - // terminator wherever the converted data ends - SI_CHAR * pData = new SI_CHAR[uLen+1]; - if (!pData) { - return SI_NOMEM; - } - memset(pData, 0, sizeof(SI_CHAR)*(uLen+1)); - - // convert the data - if (!converter.ConvertFromStore(a_pData, a_uDataLen, pData, uLen)) { - delete[] pData; - return SI_FAIL; - } - - // parse it - const static SI_CHAR empty = 0; - SI_CHAR * pWork = pData; - const SI_CHAR * pSection = ∅ - const SI_CHAR * pItem = NULL; - const SI_CHAR * pVal = NULL; - const SI_CHAR * pComment = NULL; - - // We copy the strings if we are loading data into this class when we - // already have stored some. - bool bCopyStrings = (m_pData != NULL); - - // find a file comment if it exists, this is a comment that starts at the - // beginning of the file and continues until the first blank line. - SI_Error rc = FindFileComment(pWork, bCopyStrings); - if (rc < 0) return rc; - - // add every entry in the file to the data table - while (FindEntry(pWork, pSection, pItem, pVal, pComment)) { - rc = AddEntry(pSection, pItem, pVal, pComment, false, bCopyStrings); - if (rc < 0) return rc; - } - - // store these strings if we didn't copy them - if (bCopyStrings) { - delete[] pData; - } - else { - m_pData = pData; - m_uDataLen = uLen+1; - } - - return SI_OK; -} - -#ifdef SI_SUPPORT_IOSTREAMS -template -SI_Error -CSimpleIniTempl::Load( - std::istream & a_istream - ) -{ - std::string strData; - char szBuf[512]; - do { - a_istream.get(szBuf, sizeof(szBuf), '\0'); - strData.append(szBuf); - } - while (a_istream.good()); - return Load(strData); -} -#endif // SI_SUPPORT_IOSTREAMS - -template -SI_Error -CSimpleIniTempl::FindFileComment( - SI_CHAR *& a_pData, - bool a_bCopyStrings - ) -{ - // there can only be a single file comment - if (m_pFileComment) { - return SI_OK; - } - - // Load the file comment as multi-line text, this will modify all of - // the newline characters to be single \n chars - if (!LoadMultiLineText(a_pData, m_pFileComment, NULL, false)) { - return SI_OK; - } - - // copy the string if necessary - if (a_bCopyStrings) { - SI_Error rc = CopyString(m_pFileComment); - if (rc < 0) return rc; - } - - return SI_OK; -} - -template -bool -CSimpleIniTempl::FindEntry( - SI_CHAR *& a_pData, - const SI_CHAR *& a_pSection, - const SI_CHAR *& a_pKey, - const SI_CHAR *& a_pVal, - const SI_CHAR *& a_pComment - ) const -{ - a_pComment = NULL; - - SI_CHAR * pTrail = NULL; - while (*a_pData) { - // skip spaces and empty lines - while (*a_pData && IsSpace(*a_pData)) { - ++a_pData; - } - if (!*a_pData) { - break; - } - - // skip processing of comment lines but keep a pointer to - // the start of the comment. - if (IsComment(*a_pData)) { - LoadMultiLineText(a_pData, a_pComment, NULL, true); - continue; - } - - // process section names - if (*a_pData == '[') { - // skip leading spaces - ++a_pData; - while (*a_pData && IsSpace(*a_pData)) { - ++a_pData; - } - - // find the end of the section name (it may contain spaces) - // and convert it to lowercase as necessary - a_pSection = a_pData; - while (*a_pData && *a_pData != ']' && !IsNewLineChar(*a_pData)) { - ++a_pData; - } - - // if it's an invalid line, just skip it - if (*a_pData != ']') { - continue; - } - - // remove trailing spaces from the section - pTrail = a_pData - 1; - while (pTrail >= a_pSection && IsSpace(*pTrail)) { - --pTrail; - } - ++pTrail; - *pTrail = 0; - - // skip to the end of the line - ++a_pData; // safe as checked that it == ']' above - while (*a_pData && !IsNewLineChar(*a_pData)) { - ++a_pData; - } - - a_pKey = NULL; - a_pVal = NULL; - return true; - } - - // find the end of the key name (it may contain spaces) - // and convert it to lowercase as necessary - a_pKey = a_pData; - while (*a_pData && *a_pData != '=' && !IsNewLineChar(*a_pData)) { - ++a_pData; - } - - // if it's an invalid line, just skip it - if (*a_pData != '=') { - continue; - } - - // empty keys are invalid - if (a_pKey == a_pData) { - while (*a_pData && !IsNewLineChar(*a_pData)) { - ++a_pData; - } - continue; - } - - // remove trailing spaces from the key - pTrail = a_pData - 1; - while (pTrail >= a_pKey && IsSpace(*pTrail)) { - --pTrail; - } - ++pTrail; - *pTrail = 0; - - // skip leading whitespace on the value - ++a_pData; // safe as checked that it == '=' above - while (*a_pData && !IsNewLineChar(*a_pData) && IsSpace(*a_pData)) { - ++a_pData; - } - - // find the end of the value which is the end of this line - a_pVal = a_pData; - while (*a_pData && !IsNewLineChar(*a_pData)) { - ++a_pData; - } - - // remove trailing spaces from the value - pTrail = a_pData - 1; - if (*a_pData) { // prepare for the next round - SkipNewLine(a_pData); - } - while (pTrail >= a_pVal && IsSpace(*pTrail)) { - --pTrail; - } - ++pTrail; - *pTrail = 0; - - // check for multi-line entries - if (m_bAllowMultiLine && IsMultiLineTag(a_pVal)) { - // skip the "<<<" to get the tag that will end the multiline - const SI_CHAR * pTagName = a_pVal + 3; - return LoadMultiLineText(a_pData, a_pVal, pTagName); - } - - // return the standard entry - return true; - } - - return false; -} - -template -bool -CSimpleIniTempl::IsMultiLineTag( - const SI_CHAR * a_pVal - ) const -{ - // check for the "<<<" prefix for a multi-line entry - if (*a_pVal++ != '<') return false; - if (*a_pVal++ != '<') return false; - if (*a_pVal++ != '<') return false; - return true; -} - -template -bool -CSimpleIniTempl::IsMultiLineData( - const SI_CHAR * a_pData - ) const -{ - // data is multi-line if it has any of the following features: - // * whitespace prefix - // * embedded newlines - // * whitespace suffix - - // empty string - if (!*a_pData) { - return false; - } - - // check for prefix - if (IsSpace(*a_pData)) { - return true; - } - - // embedded newlines - while (*a_pData) { - if (IsNewLineChar(*a_pData)) { - return true; - } - ++a_pData; - } - - // check for suffix - if (IsSpace(*--a_pData)) { - return true; - } - - return false; -} - -template -bool -CSimpleIniTempl::IsNewLineChar( - SI_CHAR a_c - ) const -{ - return (a_c == '\n' || a_c == '\r'); -} - -template -bool -CSimpleIniTempl::LoadMultiLineText( - SI_CHAR *& a_pData, - const SI_CHAR *& a_pVal, - const SI_CHAR * a_pTagName, - bool a_bAllowBlankLinesInComment - ) const -{ - // we modify this data to strip all newlines down to a single '\n' - // character. This means that on Windows we need to strip out some - // characters which will make the data shorter. - // i.e. LINE1-LINE1\r\nLINE2-LINE2\0 will become - // LINE1-LINE1\nLINE2-LINE2\0 - // The pDataLine entry is the pointer to the location in memory that - // the current line needs to start to run following the existing one. - // This may be the same as pCurrLine in which case no move is needed. - SI_CHAR * pDataLine = a_pData; - SI_CHAR * pCurrLine; - - // value starts at the current line - a_pVal = a_pData; - - // find the end tag. This tag must start in column 1 and be - // followed by a newline. No whitespace removal is done while - // searching for this tag. - SI_CHAR cEndOfLineChar = *a_pData; - for(;;) { - // if we are loading comments then we need a comment character as - // the first character on every line - if (!a_pTagName && !IsComment(*a_pData)) { - // if we aren't allowing blank lines then we're done - if (!a_bAllowBlankLinesInComment) { - break; - } - - // if we are allowing blank lines then we only include them - // in this comment if another comment follows, so read ahead - // to find out. - SI_CHAR * pCurr = a_pData; - int nNewLines = 0; - while (IsSpace(*pCurr)) { - if (IsNewLineChar(*pCurr)) { - ++nNewLines; - SkipNewLine(pCurr); - } - else { - ++pCurr; - } - } - - // we have a comment, add the blank lines to the output - // and continue processing from here - if (IsComment(*pCurr)) { - for (; nNewLines > 0; --nNewLines) *pDataLine++ = '\n'; - a_pData = pCurr; - continue; - } - - // the comment ends here - break; - } - - // find the end of this line - pCurrLine = a_pData; - while (*a_pData && !IsNewLineChar(*a_pData)) ++a_pData; - - // move this line down to the location that it should be if necessary - if (pDataLine < pCurrLine) { - size_t nLen = (size_t) (a_pData - pCurrLine); - memmove(pDataLine, pCurrLine, nLen * sizeof(SI_CHAR)); - pDataLine[nLen] = '\0'; - } - - // end the line with a NULL - cEndOfLineChar = *a_pData; - *a_pData = 0; - - // if are looking for a tag then do the check now. This is done before - // checking for end of the data, so that if we have the tag at the end - // of the data then the tag is removed correctly. - if (a_pTagName && - (!IsLess(pDataLine, a_pTagName) && !IsLess(a_pTagName, pDataLine))) - { - break; - } - - // if we are at the end of the data then we just automatically end - // this entry and return the current data. - if (!cEndOfLineChar) { - return true; - } - - // otherwise we need to process this newline to ensure that it consists - // of just a single \n character. - pDataLine += (a_pData - pCurrLine); - *a_pData = cEndOfLineChar; - SkipNewLine(a_pData); - *pDataLine++ = '\n'; - } - - // if we didn't find a comment at all then return false - if (a_pVal == a_pData) { - a_pVal = NULL; - return false; - } - - // the data (which ends at the end of the last line) needs to be - // null-terminated BEFORE before the newline character(s). If the - // user wants a new line in the multi-line data then they need to - // add an empty line before the tag. - *--pDataLine = '\0'; - - // if looking for a tag and if we aren't at the end of the data, - // then move a_pData to the start of the next line. - if (a_pTagName && cEndOfLineChar) { - SI_ASSERT(IsNewLineChar(cEndOfLineChar)); - *a_pData = cEndOfLineChar; - SkipNewLine(a_pData); - } - - return true; -} - -template -SI_Error -CSimpleIniTempl::CopyString( - const SI_CHAR *& a_pString - ) -{ - size_t uLen = 0; - if (sizeof(SI_CHAR) == sizeof(char)) { - uLen = strlen((const char *)a_pString); - } - else if (sizeof(SI_CHAR) == sizeof(wchar_t)) { - uLen = wcslen((const wchar_t *)a_pString); - } - else { - for ( ; a_pString[uLen]; ++uLen) /*loop*/ ; - } - ++uLen; // NULL character - SI_CHAR * pCopy = new SI_CHAR[uLen]; - if (!pCopy) { - return SI_NOMEM; - } - memcpy(pCopy, a_pString, sizeof(SI_CHAR)*uLen); - m_strings.push_back(pCopy); - a_pString = pCopy; - return SI_OK; -} - -template -SI_Error -CSimpleIniTempl::AddEntry( - const SI_CHAR * a_pSection, - const SI_CHAR * a_pKey, - const SI_CHAR * a_pValue, - const SI_CHAR * a_pComment, - bool a_bForceReplace, - bool a_bCopyStrings - ) -{ - SI_Error rc; - bool bInserted = false; - - SI_ASSERT(!a_pComment || IsComment(*a_pComment)); - - // if we are copying strings then make a copy of the comment now - // because we will need it when we add the entry. - if (a_bCopyStrings && a_pComment) { - rc = CopyString(a_pComment); - if (rc < 0) return rc; - } - - // create the section entry if necessary - typename TSection::iterator iSection = m_data.find(a_pSection); - if (iSection == m_data.end()) { - // if the section doesn't exist then we need a copy as the - // string needs to last beyond the end of this function - if (a_bCopyStrings) { - rc = CopyString(a_pSection); - if (rc < 0) return rc; - } - - // only set the comment if this is a section only entry - Entry oSection(a_pSection, ++m_nOrder); - if (a_pComment && (!a_pKey || !a_pValue)) { - oSection.pComment = a_pComment; - } - - typename TSection::value_type oEntry(oSection, TKeyVal()); - typedef typename TSection::iterator SectionIterator; - std::pair i = m_data.insert(oEntry); - iSection = i.first; - bInserted = true; - } - if (!a_pKey || !a_pValue) { - // section only entries are specified with pItem and pVal as NULL - return bInserted ? SI_INSERTED : SI_UPDATED; - } - - // check for existence of the key - TKeyVal & keyval = iSection->second; - typename TKeyVal::iterator iKey = keyval.find(a_pKey); - - // remove all existing entries but save the load order and - // comment of the first entry - int nLoadOrder = ++m_nOrder; - if (iKey != keyval.end() && m_bAllowMultiKey && a_bForceReplace) { - const SI_CHAR * pComment = NULL; - while (iKey != keyval.end() && !IsLess(a_pKey, iKey->first.pItem)) { - if (iKey->first.nOrder < nLoadOrder) { - nLoadOrder = iKey->first.nOrder; - pComment = iKey->first.pComment; - } - ++iKey; - } - if (pComment) { - DeleteString(a_pComment); - a_pComment = pComment; - CopyString(a_pComment); - } - Delete(a_pSection, a_pKey); - iKey = keyval.end(); - } - - // make string copies if necessary - bool bForceCreateNewKey = m_bAllowMultiKey && !a_bForceReplace; - if (a_bCopyStrings) { - if (bForceCreateNewKey || iKey == keyval.end()) { - // if the key doesn't exist then we need a copy as the - // string needs to last beyond the end of this function - // because we will be inserting the key next - rc = CopyString(a_pKey); - if (rc < 0) return rc; - } - - // we always need a copy of the value - rc = CopyString(a_pValue); - if (rc < 0) return rc; - } - - // create the key entry - if (iKey == keyval.end() || bForceCreateNewKey) { - Entry oKey(a_pKey, nLoadOrder); - if (a_pComment) { - oKey.pComment = a_pComment; - } - typename TKeyVal::value_type oEntry(oKey, (const SI_CHAR *) NULL); - iKey = keyval.insert(oEntry); - bInserted = true; - } - iKey->second = a_pValue; - return bInserted ? SI_INSERTED : SI_UPDATED; -} - -template -const SI_CHAR * -CSimpleIniTempl::GetValue( - const SI_CHAR * a_pSection, - const SI_CHAR * a_pKey, - const SI_CHAR * a_pDefault, - bool * a_pHasMultiple - ) const -{ - if (a_pHasMultiple) { - *a_pHasMultiple = false; - } - if (!a_pSection || !a_pKey) { - return a_pDefault; - } - typename TSection::const_iterator iSection = m_data.find(a_pSection); - if (iSection == m_data.end()) { - return a_pDefault; - } - typename TKeyVal::const_iterator iKeyVal = iSection->second.find(a_pKey); - if (iKeyVal == iSection->second.end()) { - return a_pDefault; - } - - // check for multiple entries with the same key - if (m_bAllowMultiKey && a_pHasMultiple) { - typename TKeyVal::const_iterator iTemp = iKeyVal; - if (++iTemp != iSection->second.end()) { - if (!IsLess(a_pKey, iTemp->first.pItem)) { - *a_pHasMultiple = true; - } - } - } - - return iKeyVal->second; -} - -template -long -CSimpleIniTempl::GetLongValue( - const SI_CHAR * a_pSection, - const SI_CHAR * a_pKey, - long a_nDefault, - bool * a_pHasMultiple - ) const -{ - // return the default if we don't have a value - const SI_CHAR * pszValue = GetValue(a_pSection, a_pKey, NULL, a_pHasMultiple); - if (!pszValue || !*pszValue) return a_nDefault; - - // convert to UTF-8/MBCS which for a numeric value will be the same as ASCII - char szValue[64] = { 0 }; - SI_CONVERTER c(m_bStoreIsUtf8); - if (!c.ConvertToStore(pszValue, szValue, sizeof(szValue))) { - return a_nDefault; - } - - // handle the value as hex if prefaced with "0x" - long nValue = a_nDefault; - char * pszSuffix = szValue; - if (szValue[0] == '0' && (szValue[1] == 'x' || szValue[1] == 'X')) { - if (!szValue[2]) return a_nDefault; - nValue = strtol(&szValue[2], &pszSuffix, 16); - } - else { - nValue = strtol(szValue, &pszSuffix, 10); - } - - // any invalid strings will return the default value - if (*pszSuffix) { - return a_nDefault; - } - - return nValue; -} - -template -SI_Error -CSimpleIniTempl::SetLongValue( - const SI_CHAR * a_pSection, - const SI_CHAR * a_pKey, - long a_nValue, - const SI_CHAR * a_pComment, - bool a_bUseHex, - bool a_bForceReplace - ) -{ - // use SetValue to create sections - if (!a_pSection || !a_pKey) return SI_FAIL; - - // convert to an ASCII string - char szInput[64]; -#if __STDC_WANT_SECURE_LIB__ && !_WIN32_WCE - sprintf_s(szInput, a_bUseHex ? "0x%lx" : "%ld", a_nValue); -#else // !__STDC_WANT_SECURE_LIB__ - sprintf(szInput, a_bUseHex ? "0x%lx" : "%ld", a_nValue); -#endif // __STDC_WANT_SECURE_LIB__ - - // convert to output text - SI_CHAR szOutput[64]; - SI_CONVERTER c(m_bStoreIsUtf8); - c.ConvertFromStore(szInput, strlen(szInput) + 1, - szOutput, sizeof(szOutput) / sizeof(SI_CHAR)); - - // actually add it - return AddEntry(a_pSection, a_pKey, szOutput, a_pComment, a_bForceReplace, true); -} - -template -bool -CSimpleIniTempl::GetBoolValue( - const SI_CHAR * a_pSection, - const SI_CHAR * a_pKey, - bool a_bDefault, - bool * a_pHasMultiple - ) const -{ - // return the default if we don't have a value - const SI_CHAR * pszValue = GetValue(a_pSection, a_pKey, NULL, a_pHasMultiple); - if (!pszValue || !*pszValue) return a_bDefault; - - // we only look at the minimum number of characters - switch (pszValue[0]) { - case 't': case 'T': // true - case 'y': case 'Y': // yes - case '1': // 1 (one) - return true; - - case 'f': case 'F': // false - case 'n': case 'N': // no - case '0': // 0 (zero) - return false; - - case 'o': case 'O': - if (pszValue[1] == 'n' || pszValue[1] == 'N') return true; // on - if (pszValue[1] == 'f' || pszValue[1] == 'F') return false; // off - break; - } - - // no recognized value, return the default - return a_bDefault; -} - -template -SI_Error -CSimpleIniTempl::SetBoolValue( - const SI_CHAR * a_pSection, - const SI_CHAR * a_pKey, - bool a_bValue, - const SI_CHAR * a_pComment, - bool a_bForceReplace - ) -{ - // use SetValue to create sections - if (!a_pSection || !a_pKey) return SI_FAIL; - - // convert to an ASCII string - const char * pszInput = a_bValue ? "true" : "false"; - - // convert to output text - SI_CHAR szOutput[64]; - SI_CONVERTER c(m_bStoreIsUtf8); - c.ConvertFromStore(pszInput, strlen(pszInput) + 1, - szOutput, sizeof(szOutput) / sizeof(SI_CHAR)); - - // actually add it - return AddEntry(a_pSection, a_pKey, szOutput, a_pComment, a_bForceReplace, true); -} - -template -bool -CSimpleIniTempl::GetAllValues( - const SI_CHAR * a_pSection, - const SI_CHAR * a_pKey, - TNamesDepend & a_values - ) const -{ - a_values.clear(); - - if (!a_pSection || !a_pKey) { - return false; - } - typename TSection::const_iterator iSection = m_data.find(a_pSection); - if (iSection == m_data.end()) { - return false; - } - typename TKeyVal::const_iterator iKeyVal = iSection->second.find(a_pKey); - if (iKeyVal == iSection->second.end()) { - return false; - } - - // insert all values for this key - a_values.push_back(Entry(iKeyVal->second, iKeyVal->first.pComment, iKeyVal->first.nOrder)); - if (m_bAllowMultiKey) { - ++iKeyVal; - while (iKeyVal != iSection->second.end() && !IsLess(a_pKey, iKeyVal->first.pItem)) { - a_values.push_back(Entry(iKeyVal->second, iKeyVal->first.pComment, iKeyVal->first.nOrder)); - ++iKeyVal; - } - } - - return true; -} - -template -int -CSimpleIniTempl::GetSectionSize( - const SI_CHAR * a_pSection - ) const -{ - if (!a_pSection) { - return -1; - } - - typename TSection::const_iterator iSection = m_data.find(a_pSection); - if (iSection == m_data.end()) { - return -1; - } - const TKeyVal & section = iSection->second; - - // if multi-key isn't permitted then the section size is - // the number of keys that we have. - if (!m_bAllowMultiKey || section.empty()) { - return (int) section.size(); - } - - // otherwise we need to count them - int nCount = 0; - const SI_CHAR * pLastKey = NULL; - typename TKeyVal::const_iterator iKeyVal = section.begin(); - for (int n = 0; iKeyVal != section.end(); ++iKeyVal, ++n) { - if (!pLastKey || IsLess(pLastKey, iKeyVal->first.pItem)) { - ++nCount; - pLastKey = iKeyVal->first.pItem; - } - } - return nCount; -} - -template -const typename CSimpleIniTempl::TKeyVal * -CSimpleIniTempl::GetSection( - const SI_CHAR * a_pSection - ) const -{ - if (a_pSection) { - typename TSection::const_iterator i = m_data.find(a_pSection); - if (i != m_data.end()) { - return &(i->second); - } - } - return 0; -} - -template -void -CSimpleIniTempl::GetAllSections( - TNamesDepend & a_names - ) const -{ - a_names.clear(); - typename TSection::const_iterator i = m_data.begin(); - for (int n = 0; i != m_data.end(); ++i, ++n ) { - a_names.push_back(i->first); - } -} - -template -bool -CSimpleIniTempl::GetAllKeys( - const SI_CHAR * a_pSection, - TNamesDepend & a_names - ) const -{ - a_names.clear(); - - if (!a_pSection) { - return false; - } - - typename TSection::const_iterator iSection = m_data.find(a_pSection); - if (iSection == m_data.end()) { - return false; - } - - const TKeyVal & section = iSection->second; - const SI_CHAR * pLastKey = NULL; - typename TKeyVal::const_iterator iKeyVal = section.begin(); - for (int n = 0; iKeyVal != section.end(); ++iKeyVal, ++n ) { - if (!pLastKey || IsLess(pLastKey, iKeyVal->first.pItem)) { - a_names.push_back(iKeyVal->first); - pLastKey = iKeyVal->first.pItem; - } - } - - return true; -} - -template -SI_Error -CSimpleIniTempl::SaveFile( - const char * a_pszFile, - bool a_bAddSignature - ) const -{ - FILE * fp = NULL; -#if __STDC_WANT_SECURE_LIB__ && !_WIN32_WCE - fopen_s(&fp, a_pszFile, "wb"); -#else // !__STDC_WANT_SECURE_LIB__ - fp = fopen(a_pszFile, "wb"); -#endif // __STDC_WANT_SECURE_LIB__ - if (!fp) return SI_FILE; - SI_Error rc = SaveFile(fp, a_bAddSignature); - fclose(fp); - return rc; -} - -#ifdef SI_HAS_WIDE_FILE -template -SI_Error -CSimpleIniTempl::SaveFile( - const SI_WCHAR_T * a_pwszFile, - bool a_bAddSignature - ) const -{ -#ifdef _WIN32 - FILE * fp = NULL; -#if __STDC_WANT_SECURE_LIB__ && !_WIN32_WCE - _wfopen_s(&fp, a_pwszFile, L"wb"); -#else // !__STDC_WANT_SECURE_LIB__ - fp = _wfopen(a_pwszFile, L"wb"); -#endif // __STDC_WANT_SECURE_LIB__ - if (!fp) return SI_FILE; - SI_Error rc = SaveFile(fp, a_bAddSignature); - fclose(fp); - return rc; -#else // !_WIN32 (therefore SI_CONVERT_ICU) - char szFile[256]; - u_austrncpy(szFile, a_pwszFile, sizeof(szFile)); - return SaveFile(szFile, a_bAddSignature); -#endif // _WIN32 -} -#endif // SI_HAS_WIDE_FILE - -template -SI_Error -CSimpleIniTempl::SaveFile( - FILE * a_pFile, - bool a_bAddSignature - ) const -{ - FileWriter writer(a_pFile); - return Save(writer, a_bAddSignature); -} - -template -SI_Error -CSimpleIniTempl::Save( - OutputWriter & a_oOutput, - bool a_bAddSignature - ) const -{ - Converter convert(m_bStoreIsUtf8); - - // add the UTF-8 signature if it is desired - if (m_bStoreIsUtf8 && a_bAddSignature) { - a_oOutput.Write(SI_UTF8_SIGNATURE); - } - - // get all of the sections sorted in load order - TNamesDepend oSections; - GetAllSections(oSections); -#if defined(_MSC_VER) && _MSC_VER <= 1200 - oSections.sort(); -#elif defined(__BORLANDC__) - oSections.sort(Entry::LoadOrder()); -#else - oSections.sort(typename Entry::LoadOrder()); -#endif - - // write the file comment if we have one - bool bNeedNewLine = false; - if (m_pFileComment) { - if (!OutputMultiLineText(a_oOutput, convert, m_pFileComment)) { - return SI_FAIL; - } - bNeedNewLine = true; - } - - // iterate through our sections and output the data - typename TNamesDepend::const_iterator iSection = oSections.begin(); - for ( ; iSection != oSections.end(); ++iSection ) { - // write out the comment if there is one - if (iSection->pComment) { - if (bNeedNewLine) { - a_oOutput.Write(SI_NEWLINE_A); - a_oOutput.Write(SI_NEWLINE_A); - } - if (!OutputMultiLineText(a_oOutput, convert, iSection->pComment)) { - return SI_FAIL; - } - bNeedNewLine = false; - } - - if (bNeedNewLine) { - a_oOutput.Write(SI_NEWLINE_A); - a_oOutput.Write(SI_NEWLINE_A); - bNeedNewLine = false; - } - - // write the section (unless there is no section name) - if (*iSection->pItem) { - if (!convert.ConvertToStore(iSection->pItem)) { - return SI_FAIL; - } - a_oOutput.Write("["); - a_oOutput.Write(convert.Data()); - a_oOutput.Write("]"); - a_oOutput.Write(SI_NEWLINE_A); - } - - // get all of the keys sorted in load order - TNamesDepend oKeys; - GetAllKeys(iSection->pItem, oKeys); -#if defined(_MSC_VER) && _MSC_VER <= 1200 - oKeys.sort(); -#elif defined(__BORLANDC__) - oKeys.sort(Entry::LoadOrder()); -#else - oKeys.sort(typename Entry::LoadOrder()); -#endif - - // write all keys and values - typename TNamesDepend::const_iterator iKey = oKeys.begin(); - for ( ; iKey != oKeys.end(); ++iKey) { - // get all values for this key - TNamesDepend oValues; - GetAllValues(iSection->pItem, iKey->pItem, oValues); - - typename TNamesDepend::const_iterator iValue = oValues.begin(); - for ( ; iValue != oValues.end(); ++iValue) { - // write out the comment if there is one - if (iValue->pComment) { - a_oOutput.Write(SI_NEWLINE_A); - if (!OutputMultiLineText(a_oOutput, convert, iValue->pComment)) { - return SI_FAIL; - } - } - - // write the key - if (!convert.ConvertToStore(iKey->pItem)) { - return SI_FAIL; - } - a_oOutput.Write(convert.Data()); - - // write the value - if (!convert.ConvertToStore(iValue->pItem)) { - return SI_FAIL; - } - a_oOutput.Write(m_bSpaces ? " = " : "="); - if (m_bAllowMultiLine && IsMultiLineData(iValue->pItem)) { - // multi-line data needs to be processed specially to ensure - // that we use the correct newline format for the current system - a_oOutput.Write("<<pItem)) { - return SI_FAIL; - } - a_oOutput.Write("SI-END-OF-MULTILINE-TEXT"); - } - else { - a_oOutput.Write(convert.Data()); - } - a_oOutput.Write(SI_NEWLINE_A); - } - } - - bNeedNewLine = true; - } - - return SI_OK; -} - -template -bool -CSimpleIniTempl::OutputMultiLineText( - OutputWriter & a_oOutput, - Converter & a_oConverter, - const SI_CHAR * a_pText - ) const -{ - const SI_CHAR * pEndOfLine; - SI_CHAR cEndOfLineChar = *a_pText; - while (cEndOfLineChar) { - // find the end of this line - pEndOfLine = a_pText; - for (; *pEndOfLine && *pEndOfLine != '\n'; ++pEndOfLine) /*loop*/ ; - cEndOfLineChar = *pEndOfLine; - - // temporarily null terminate, convert and output the line - *const_cast(pEndOfLine) = 0; - if (!a_oConverter.ConvertToStore(a_pText)) { - return false; - } - *const_cast(pEndOfLine) = cEndOfLineChar; - a_pText += (pEndOfLine - a_pText) + 1; - a_oOutput.Write(a_oConverter.Data()); - a_oOutput.Write(SI_NEWLINE_A); - } - return true; -} - -template -bool -CSimpleIniTempl::Delete( - const SI_CHAR * a_pSection, - const SI_CHAR * a_pKey, - bool a_bRemoveEmpty - ) -{ - if (!a_pSection) { - return false; - } - - typename TSection::iterator iSection = m_data.find(a_pSection); - if (iSection == m_data.end()) { - return false; - } - - // remove a single key if we have a keyname - if (a_pKey) { - typename TKeyVal::iterator iKeyVal = iSection->second.find(a_pKey); - if (iKeyVal == iSection->second.end()) { - return false; - } - - // remove any copied strings and then the key - typename TKeyVal::iterator iDelete; - do { - iDelete = iKeyVal++; - - DeleteString(iDelete->first.pItem); - DeleteString(iDelete->second); - iSection->second.erase(iDelete); - } - while (iKeyVal != iSection->second.end() - && !IsLess(a_pKey, iKeyVal->first.pItem)); - - // done now if the section is not empty or we are not pruning away - // the empty sections. Otherwise let it fall through into the section - // deletion code - if (!a_bRemoveEmpty || !iSection->second.empty()) { - return true; - } - } - else { - // delete all copied strings from this section. The actual - // entries will be removed when the section is removed. - typename TKeyVal::iterator iKeyVal = iSection->second.begin(); - for ( ; iKeyVal != iSection->second.end(); ++iKeyVal) { - DeleteString(iKeyVal->first.pItem); - DeleteString(iKeyVal->second); - } - } - - // delete the section itself - DeleteString(iSection->first.pItem); - m_data.erase(iSection); - - return true; -} - -template -void -CSimpleIniTempl::DeleteString( - const SI_CHAR * a_pString - ) -{ - // strings may exist either inside the data block, or they will be - // individually allocated and stored in m_strings. We only physically - // delete those stored in m_strings. - if (a_pString < m_pData || a_pString >= m_pData + m_uDataLen) { - typename TNamesDepend::iterator i = m_strings.begin(); - for (;i != m_strings.end(); ++i) { - if (a_pString == i->pItem) { - delete[] const_cast(i->pItem); - m_strings.erase(i); - break; - } - } - } -} - -// --------------------------------------------------------------------------- -// CONVERSION FUNCTIONS -// --------------------------------------------------------------------------- - -// Defines the conversion classes for different libraries. Before including -// SimpleIni.h, set the converter that you wish you use by defining one of the -// following symbols. -// -// SI_CONVERT_GENERIC Use the Unicode reference conversion library in -// the accompanying files ConvertUTF.h/c -// SI_CONVERT_ICU Use the IBM ICU conversion library. Requires -// ICU headers on include path and icuuc.lib -// SI_CONVERT_WIN32 Use the Win32 API functions for conversion. - -#if !defined(SI_CONVERT_GENERIC) && !defined(SI_CONVERT_WIN32) && !defined(SI_CONVERT_ICU) -# ifdef _WIN32 -# define SI_CONVERT_WIN32 -# else -# define SI_CONVERT_GENERIC -# endif -#endif - -/** - * Generic case-sensitive less than comparison. This class returns numerically - * ordered ASCII case-sensitive text for all possible sizes and types of - * SI_CHAR. - */ -template -struct SI_GenericCase { - bool operator()(const SI_CHAR * pLeft, const SI_CHAR * pRight) const { - long cmp; - for ( ;*pLeft && *pRight; ++pLeft, ++pRight) { - cmp = (long) *pLeft - (long) *pRight; - if (cmp != 0) { - return cmp < 0; - } - } - return *pRight != 0; - } -}; - -/** - * Generic ASCII case-insensitive less than comparison. This class returns - * numerically ordered ASCII case-insensitive text for all possible sizes - * and types of SI_CHAR. It is not safe for MBCS text comparison where - * ASCII A-Z characters are used in the encoding of multi-byte characters. - */ -template -struct SI_GenericNoCase { - inline SI_CHAR locase(SI_CHAR ch) const { - return (ch < 'A' || ch > 'Z') ? ch : (ch - 'A' + 'a'); - } - bool operator()(const SI_CHAR * pLeft, const SI_CHAR * pRight) const { - long cmp; - for ( ;*pLeft && *pRight; ++pLeft, ++pRight) { - cmp = (long) locase(*pLeft) - (long) locase(*pRight); - if (cmp != 0) { - return cmp < 0; - } - } - return *pRight != 0; - } -}; - -/** - * Null conversion class for MBCS/UTF-8 to char (or equivalent). - */ -template -class SI_ConvertA { - bool m_bStoreIsUtf8; -protected: - SI_ConvertA() { } -public: - SI_ConvertA(bool a_bStoreIsUtf8) : m_bStoreIsUtf8(a_bStoreIsUtf8) { } - - /* copy and assignment */ - SI_ConvertA(const SI_ConvertA & rhs) { operator=(rhs); } - SI_ConvertA & operator=(const SI_ConvertA & rhs) { - m_bStoreIsUtf8 = rhs.m_bStoreIsUtf8; - return *this; - } - - /** Calculate the number of SI_CHAR required for converting the input - * from the storage format. The storage format is always UTF-8 or MBCS. - * - * @param a_pInputData Data in storage format to be converted to SI_CHAR. - * @param a_uInputDataLen Length of storage format data in bytes. This - * must be the actual length of the data, including - * NULL byte if NULL terminated string is required. - * @return Number of SI_CHAR required by the string when - * converted. If there are embedded NULL bytes in the - * input data, only the string up and not including - * the NULL byte will be converted. - * @return -1 cast to size_t on a conversion error. - */ - size_t SizeFromStore( - const char * a_pInputData, - size_t a_uInputDataLen) - { - (void)a_pInputData; - SI_ASSERT(a_uInputDataLen != (size_t) -1); - - // ASCII/MBCS/UTF-8 needs no conversion - return a_uInputDataLen; - } - - /** Convert the input string from the storage format to SI_CHAR. - * The storage format is always UTF-8 or MBCS. - * - * @param a_pInputData Data in storage format to be converted to SI_CHAR. - * @param a_uInputDataLen Length of storage format data in bytes. This - * must be the actual length of the data, including - * NULL byte if NULL terminated string is required. - * @param a_pOutputData Pointer to the output buffer to received the - * converted data. - * @param a_uOutputDataSize Size of the output buffer in SI_CHAR. - * @return true if all of the input data was successfully - * converted. - */ - bool ConvertFromStore( - const char * a_pInputData, - size_t a_uInputDataLen, - SI_CHAR * a_pOutputData, - size_t a_uOutputDataSize) - { - // ASCII/MBCS/UTF-8 needs no conversion - if (a_uInputDataLen > a_uOutputDataSize) { - return false; - } - memcpy(a_pOutputData, a_pInputData, a_uInputDataLen); - return true; - } - - /** Calculate the number of char required by the storage format of this - * data. The storage format is always UTF-8 or MBCS. - * - * @param a_pInputData NULL terminated string to calculate the number of - * bytes required to be converted to storage format. - * @return Number of bytes required by the string when - * converted to storage format. This size always - * includes space for the terminating NULL character. - * @return -1 cast to size_t on a conversion error. - */ - size_t SizeToStore( - const SI_CHAR * a_pInputData) - { - // ASCII/MBCS/UTF-8 needs no conversion - return strlen((const char *)a_pInputData) + 1; - } - - /** Convert the input string to the storage format of this data. - * The storage format is always UTF-8 or MBCS. - * - * @param a_pInputData NULL terminated source string to convert. All of - * the data will be converted including the - * terminating NULL character. - * @param a_pOutputData Pointer to the buffer to receive the converted - * string. - * @param a_uOutputDataSize Size of the output buffer in char. - * @return true if all of the input data, including the - * terminating NULL character was successfully - * converted. - */ - bool ConvertToStore( - const SI_CHAR * a_pInputData, - char * a_pOutputData, - size_t a_uOutputDataSize) - { - // calc input string length (SI_CHAR type and size independent) - size_t uInputLen = strlen((const char *)a_pInputData) + 1; - if (uInputLen > a_uOutputDataSize) { - return false; - } - - // ascii/UTF-8 needs no conversion - memcpy(a_pOutputData, a_pInputData, uInputLen); - return true; - } -}; - - -// --------------------------------------------------------------------------- -// SI_CONVERT_GENERIC -// --------------------------------------------------------------------------- -#ifdef SI_CONVERT_GENERIC - -#define SI_Case SI_GenericCase -#define SI_NoCase SI_GenericNoCase - -#include -#include "ConvertUTF.h" - -/** - * Converts UTF-8 to a wchar_t (or equivalent) using the Unicode reference - * library functions. This can be used on all platforms. - */ -template -class SI_ConvertW { - bool m_bStoreIsUtf8; -protected: - SI_ConvertW() { } -public: - SI_ConvertW(bool a_bStoreIsUtf8) : m_bStoreIsUtf8(a_bStoreIsUtf8) { } - - /* copy and assignment */ - SI_ConvertW(const SI_ConvertW & rhs) { operator=(rhs); } - SI_ConvertW & operator=(const SI_ConvertW & rhs) { - m_bStoreIsUtf8 = rhs.m_bStoreIsUtf8; - return *this; - } - - /** Calculate the number of SI_CHAR required for converting the input - * from the storage format. The storage format is always UTF-8 or MBCS. - * - * @param a_pInputData Data in storage format to be converted to SI_CHAR. - * @param a_uInputDataLen Length of storage format data in bytes. This - * must be the actual length of the data, including - * NULL byte if NULL terminated string is required. - * @return Number of SI_CHAR required by the string when - * converted. If there are embedded NULL bytes in the - * input data, only the string up and not including - * the NULL byte will be converted. - * @return -1 cast to size_t on a conversion error. - */ - size_t SizeFromStore( - const char * a_pInputData, - size_t a_uInputDataLen) - { - SI_ASSERT(a_uInputDataLen != (size_t) -1); - - if (m_bStoreIsUtf8) { - // worst case scenario for UTF-8 to wchar_t is 1 char -> 1 wchar_t - // so we just return the same number of characters required as for - // the source text. - return a_uInputDataLen; - } - else { - return mbstowcs(NULL, a_pInputData, a_uInputDataLen); - } - } - - /** Convert the input string from the storage format to SI_CHAR. - * The storage format is always UTF-8 or MBCS. - * - * @param a_pInputData Data in storage format to be converted to SI_CHAR. - * @param a_uInputDataLen Length of storage format data in bytes. This - * must be the actual length of the data, including - * NULL byte if NULL terminated string is required. - * @param a_pOutputData Pointer to the output buffer to received the - * converted data. - * @param a_uOutputDataSize Size of the output buffer in SI_CHAR. - * @return true if all of the input data was successfully - * converted. - */ - bool ConvertFromStore( - const char * a_pInputData, - size_t a_uInputDataLen, - SI_CHAR * a_pOutputData, - size_t a_uOutputDataSize) - { - if (m_bStoreIsUtf8) { - // This uses the Unicode reference implementation to do the - // conversion from UTF-8 to wchar_t. The required files are - // ConvertUTF.h and ConvertUTF.c which should be included in - // the distribution but are publically available from unicode.org - // at http://www.unicode.org/Public/PROGRAMS/CVTUTF/ - ConversionResult retval; - const UTF8 * pUtf8 = (const UTF8 *) a_pInputData; - if (sizeof(wchar_t) == sizeof(UTF32)) { - UTF32 * pUtf32 = (UTF32 *) a_pOutputData; - retval = ConvertUTF8toUTF32( - &pUtf8, pUtf8 + a_uInputDataLen, - &pUtf32, pUtf32 + a_uOutputDataSize, - lenientConversion); - } - else if (sizeof(wchar_t) == sizeof(UTF16)) { - UTF16 * pUtf16 = (UTF16 *) a_pOutputData; - retval = ConvertUTF8toUTF16( - &pUtf8, pUtf8 + a_uInputDataLen, - &pUtf16, pUtf16 + a_uOutputDataSize, - lenientConversion); - } - return retval == conversionOK; - } - else { - size_t retval = mbstowcs(a_pOutputData, - a_pInputData, a_uOutputDataSize); - return retval != (size_t)(-1); - } - } - - /** Calculate the number of char required by the storage format of this - * data. The storage format is always UTF-8 or MBCS. - * - * @param a_pInputData NULL terminated string to calculate the number of - * bytes required to be converted to storage format. - * @return Number of bytes required by the string when - * converted to storage format. This size always - * includes space for the terminating NULL character. - * @return -1 cast to size_t on a conversion error. - */ - size_t SizeToStore( - const SI_CHAR * a_pInputData) - { - if (m_bStoreIsUtf8) { - // worst case scenario for wchar_t to UTF-8 is 1 wchar_t -> 6 char - size_t uLen = 0; - while (a_pInputData[uLen]) { - ++uLen; - } - return (6 * uLen) + 1; - } - else { - size_t uLen = wcstombs(NULL, a_pInputData, 0); - if (uLen == (size_t)(-1)) { - return uLen; - } - return uLen + 1; // include NULL terminator - } - } - - /** Convert the input string to the storage format of this data. - * The storage format is always UTF-8 or MBCS. - * - * @param a_pInputData NULL terminated source string to convert. All of - * the data will be converted including the - * terminating NULL character. - * @param a_pOutputData Pointer to the buffer to receive the converted - * string. - * @param a_uOutputDataSize Size of the output buffer in char. - * @return true if all of the input data, including the - * terminating NULL character was successfully - * converted. - */ - bool ConvertToStore( - const SI_CHAR * a_pInputData, - char * a_pOutputData, - size_t a_uOutputDataSize - ) - { - if (m_bStoreIsUtf8) { - // calc input string length (SI_CHAR type and size independent) - size_t uInputLen = 0; - while (a_pInputData[uInputLen]) { - ++uInputLen; - } - ++uInputLen; // include the NULL char - - // This uses the Unicode reference implementation to do the - // conversion from wchar_t to UTF-8. The required files are - // ConvertUTF.h and ConvertUTF.c which should be included in - // the distribution but are publically available from unicode.org - // at http://www.unicode.org/Public/PROGRAMS/CVTUTF/ - ConversionResult retval; - UTF8 * pUtf8 = (UTF8 *) a_pOutputData; - if (sizeof(wchar_t) == sizeof(UTF32)) { - const UTF32 * pUtf32 = (const UTF32 *) a_pInputData; - retval = ConvertUTF32toUTF8( - &pUtf32, pUtf32 + uInputLen, - &pUtf8, pUtf8 + a_uOutputDataSize, - lenientConversion); - } - else if (sizeof(wchar_t) == sizeof(UTF16)) { - const UTF16 * pUtf16 = (const UTF16 *) a_pInputData; - retval = ConvertUTF16toUTF8( - &pUtf16, pUtf16 + uInputLen, - &pUtf8, pUtf8 + a_uOutputDataSize, - lenientConversion); - } - return retval == conversionOK; - } - else { - size_t retval = wcstombs(a_pOutputData, - a_pInputData, a_uOutputDataSize); - return retval != (size_t) -1; - } - } -}; - -#endif // SI_CONVERT_GENERIC - - -// --------------------------------------------------------------------------- -// SI_CONVERT_ICU -// --------------------------------------------------------------------------- -#ifdef SI_CONVERT_ICU - -#define SI_Case SI_GenericCase -#define SI_NoCase SI_GenericNoCase - -#include - -/** - * Converts MBCS/UTF-8 to UChar using ICU. This can be used on all platforms. - */ -template -class SI_ConvertW { - const char * m_pEncoding; - UConverter * m_pConverter; -protected: - SI_ConvertW() : m_pEncoding(NULL), m_pConverter(NULL) { } -public: - SI_ConvertW(bool a_bStoreIsUtf8) : m_pConverter(NULL) { - m_pEncoding = a_bStoreIsUtf8 ? "UTF-8" : NULL; - } - - /* copy and assignment */ - SI_ConvertW(const SI_ConvertW & rhs) { operator=(rhs); } - SI_ConvertW & operator=(const SI_ConvertW & rhs) { - m_pEncoding = rhs.m_pEncoding; - m_pConverter = NULL; - return *this; - } - ~SI_ConvertW() { if (m_pConverter) ucnv_close(m_pConverter); } - - /** Calculate the number of UChar required for converting the input - * from the storage format. The storage format is always UTF-8 or MBCS. - * - * @param a_pInputData Data in storage format to be converted to UChar. - * @param a_uInputDataLen Length of storage format data in bytes. This - * must be the actual length of the data, including - * NULL byte if NULL terminated string is required. - * @return Number of UChar required by the string when - * converted. If there are embedded NULL bytes in the - * input data, only the string up and not including - * the NULL byte will be converted. - * @return -1 cast to size_t on a conversion error. - */ - size_t SizeFromStore( - const char * a_pInputData, - size_t a_uInputDataLen) - { - SI_ASSERT(a_uInputDataLen != (size_t) -1); - - UErrorCode nError; - - if (!m_pConverter) { - nError = U_ZERO_ERROR; - m_pConverter = ucnv_open(m_pEncoding, &nError); - if (U_FAILURE(nError)) { - return (size_t) -1; - } - } - - nError = U_ZERO_ERROR; - ucnv_resetToUnicode(m_pConverter); - int32_t nLen = ucnv_toUChars(m_pConverter, NULL, 0, - a_pInputData, (int32_t) a_uInputDataLen, &nError); - if (nError != U_BUFFER_OVERFLOW_ERROR) { - return (size_t) -1; - } - - return (size_t) nLen; - } - - /** Convert the input string from the storage format to UChar. - * The storage format is always UTF-8 or MBCS. - * - * @param a_pInputData Data in storage format to be converted to UChar. - * @param a_uInputDataLen Length of storage format data in bytes. This - * must be the actual length of the data, including - * NULL byte if NULL terminated string is required. - * @param a_pOutputData Pointer to the output buffer to received the - * converted data. - * @param a_uOutputDataSize Size of the output buffer in UChar. - * @return true if all of the input data was successfully - * converted. - */ - bool ConvertFromStore( - const char * a_pInputData, - size_t a_uInputDataLen, - UChar * a_pOutputData, - size_t a_uOutputDataSize) - { - UErrorCode nError; - - if (!m_pConverter) { - nError = U_ZERO_ERROR; - m_pConverter = ucnv_open(m_pEncoding, &nError); - if (U_FAILURE(nError)) { - return false; - } - } - - nError = U_ZERO_ERROR; - ucnv_resetToUnicode(m_pConverter); - ucnv_toUChars(m_pConverter, - a_pOutputData, (int32_t) a_uOutputDataSize, - a_pInputData, (int32_t) a_uInputDataLen, &nError); - if (U_FAILURE(nError)) { - return false; - } - - return true; - } - - /** Calculate the number of char required by the storage format of this - * data. The storage format is always UTF-8 or MBCS. - * - * @param a_pInputData NULL terminated string to calculate the number of - * bytes required to be converted to storage format. - * @return Number of bytes required by the string when - * converted to storage format. This size always - * includes space for the terminating NULL character. - * @return -1 cast to size_t on a conversion error. - */ - size_t SizeToStore( - const UChar * a_pInputData) - { - UErrorCode nError; - - if (!m_pConverter) { - nError = U_ZERO_ERROR; - m_pConverter = ucnv_open(m_pEncoding, &nError); - if (U_FAILURE(nError)) { - return (size_t) -1; - } - } - - nError = U_ZERO_ERROR; - ucnv_resetFromUnicode(m_pConverter); - int32_t nLen = ucnv_fromUChars(m_pConverter, NULL, 0, - a_pInputData, -1, &nError); - if (nError != U_BUFFER_OVERFLOW_ERROR) { - return (size_t) -1; - } - - return (size_t) nLen + 1; - } - - /** Convert the input string to the storage format of this data. - * The storage format is always UTF-8 or MBCS. - * - * @param a_pInputData NULL terminated source string to convert. All of - * the data will be converted including the - * terminating NULL character. - * @param a_pOutputData Pointer to the buffer to receive the converted - * string. - * @param a_pOutputDataSize Size of the output buffer in char. - * @return true if all of the input data, including the - * terminating NULL character was successfully - * converted. - */ - bool ConvertToStore( - const UChar * a_pInputData, - char * a_pOutputData, - size_t a_uOutputDataSize) - { - UErrorCode nError; - - if (!m_pConverter) { - nError = U_ZERO_ERROR; - m_pConverter = ucnv_open(m_pEncoding, &nError); - if (U_FAILURE(nError)) { - return false; - } - } - - nError = U_ZERO_ERROR; - ucnv_resetFromUnicode(m_pConverter); - ucnv_fromUChars(m_pConverter, - a_pOutputData, (int32_t) a_uOutputDataSize, - a_pInputData, -1, &nError); - if (U_FAILURE(nError)) { - return false; - } - - return true; - } -}; - -#endif // SI_CONVERT_ICU - - -// --------------------------------------------------------------------------- -// SI_CONVERT_WIN32 -// --------------------------------------------------------------------------- -#ifdef SI_CONVERT_WIN32 - -#define SI_Case SI_GenericCase - -// Windows CE doesn't have errno or MBCS libraries -#ifdef _WIN32_WCE -# ifndef SI_NO_MBCS -# define SI_NO_MBCS -# endif -#endif -#ifdef _XBOX -#include -#else -#include -#endif - -#ifdef SI_NO_MBCS -# define SI_NoCase SI_GenericNoCase -#else // !SI_NO_MBCS -/** - * Case-insensitive comparison class using Win32 MBCS functions. This class - * returns a case-insensitive semi-collation order for MBCS text. It may not - * be safe for UTF-8 text returned in char format as we don't know what - * characters will be folded by the function! Therefore, if you are using - * SI_CHAR == char and SetUnicode(true), then you need to use the generic - * SI_NoCase class instead. - */ -#include -template -struct SI_NoCase { - bool operator()(const SI_CHAR * pLeft, const SI_CHAR * pRight) const { - if (sizeof(SI_CHAR) == sizeof(char)) { - return _mbsicmp((const unsigned char *)pLeft, - (const unsigned char *)pRight) < 0; - } - if (sizeof(SI_CHAR) == sizeof(wchar_t)) { - return _wcsicmp((const wchar_t *)pLeft, - (const wchar_t *)pRight) < 0; - } - return SI_GenericNoCase()(pLeft, pRight); - } -}; -#endif // SI_NO_MBCS - -/** - * Converts MBCS and UTF-8 to a wchar_t (or equivalent) on Windows. This uses - * only the Win32 functions and doesn't require the external Unicode UTF-8 - * conversion library. It will not work on Windows 95 without using Microsoft - * Layer for Unicode in your application. - */ -template -class SI_ConvertW { - UINT m_uCodePage; -protected: - SI_ConvertW() { } -public: - SI_ConvertW(bool a_bStoreIsUtf8) { - m_uCodePage = a_bStoreIsUtf8 ? CP_UTF8 : CP_ACP; - } - - /* copy and assignment */ - SI_ConvertW(const SI_ConvertW & rhs) { operator=(rhs); } - SI_ConvertW & operator=(const SI_ConvertW & rhs) { - m_uCodePage = rhs.m_uCodePage; - return *this; - } - - /** Calculate the number of SI_CHAR required for converting the input - * from the storage format. The storage format is always UTF-8 or MBCS. - * - * @param a_pInputData Data in storage format to be converted to SI_CHAR. - * @param a_uInputDataLen Length of storage format data in bytes. This - * must be the actual length of the data, including - * NULL byte if NULL terminated string is required. - * @return Number of SI_CHAR required by the string when - * converted. If there are embedded NULL bytes in the - * input data, only the string up and not including - * the NULL byte will be converted. - * @return -1 cast to size_t on a conversion error. - */ - size_t SizeFromStore( - const char * a_pInputData, - size_t a_uInputDataLen) - { - SI_ASSERT(a_uInputDataLen != (size_t) -1); - - int retval = MultiByteToWideChar( - m_uCodePage, 0, - a_pInputData, (int) a_uInputDataLen, - 0, 0); - return (size_t)(retval > 0 ? retval : -1); - } - - /** Convert the input string from the storage format to SI_CHAR. - * The storage format is always UTF-8 or MBCS. - * - * @param a_pInputData Data in storage format to be converted to SI_CHAR. - * @param a_uInputDataLen Length of storage format data in bytes. This - * must be the actual length of the data, including - * NULL byte if NULL terminated string is required. - * @param a_pOutputData Pointer to the output buffer to received the - * converted data. - * @param a_uOutputDataSize Size of the output buffer in SI_CHAR. - * @return true if all of the input data was successfully - * converted. - */ - bool ConvertFromStore( - const char * a_pInputData, - size_t a_uInputDataLen, - SI_CHAR * a_pOutputData, - size_t a_uOutputDataSize) - { - int nSize = MultiByteToWideChar( - m_uCodePage, 0, - a_pInputData, (int) a_uInputDataLen, - (wchar_t *) a_pOutputData, (int) a_uOutputDataSize); - return (nSize > 0); - } - - /** Calculate the number of char required by the storage format of this - * data. The storage format is always UTF-8. - * - * @param a_pInputData NULL terminated string to calculate the number of - * bytes required to be converted to storage format. - * @return Number of bytes required by the string when - * converted to storage format. This size always - * includes space for the terminating NULL character. - * @return -1 cast to size_t on a conversion error. - */ - size_t SizeToStore( - const SI_CHAR * a_pInputData) - { - int retval = WideCharToMultiByte( - m_uCodePage, 0, - (const wchar_t *) a_pInputData, -1, - 0, 0, 0, 0); - return (size_t) (retval > 0 ? retval : -1); - } - - /** Convert the input string to the storage format of this data. - * The storage format is always UTF-8 or MBCS. - * - * @param a_pInputData NULL terminated source string to convert. All of - * the data will be converted including the - * terminating NULL character. - * @param a_pOutputData Pointer to the buffer to receive the converted - * string. - * @param a_pOutputDataSize Size of the output buffer in char. - * @return true if all of the input data, including the - * terminating NULL character was successfully - * converted. - */ - bool ConvertToStore( - const SI_CHAR * a_pInputData, - char * a_pOutputData, - size_t a_uOutputDataSize) - { - int retval = WideCharToMultiByte( - m_uCodePage, 0, - (const wchar_t *) a_pInputData, -1, - a_pOutputData, (int) a_uOutputDataSize, 0, 0); - return retval > 0; - } -}; - -#endif // SI_CONVERT_WIN32 - - -// --------------------------------------------------------------------------- -// TYPE DEFINITIONS -// --------------------------------------------------------------------------- - -typedef CSimpleIniTempl,SI_ConvertA > CSimpleIniA; -typedef CSimpleIniTempl,SI_ConvertA > CSimpleIniCaseA; - -#if defined(SI_CONVERT_ICU) -typedef CSimpleIniTempl,SI_ConvertW > CSimpleIniW; -typedef CSimpleIniTempl,SI_ConvertW > CSimpleIniCaseW; -#else -typedef CSimpleIniTempl,SI_ConvertW > CSimpleIniW; -typedef CSimpleIniTempl,SI_ConvertW > CSimpleIniCaseW; -#endif - -#ifdef _UNICODE -# define CSimpleIni CSimpleIniW -# define CSimpleIniCase CSimpleIniCaseW -# define SI_NEWLINE SI_NEWLINE_W -#else // !_UNICODE -# define CSimpleIni CSimpleIniA -# define CSimpleIniCase CSimpleIniCaseA -# define SI_NEWLINE SI_NEWLINE_A -#endif // _UNICODE - -#ifdef _MSC_VER -# pragma warning (pop) -#endif - -#endif // INCLUDED_SimpleIni_h - diff --git a/xbox1/RetroLaunch/dist/Media/arial.ttf b/xbox1/RetroLaunch/dist/Media/arial.ttf deleted file mode 100644 index 25769bbf1b0751c727fcab04da0f84fa517ec61f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 65692 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 diff --git a/xbox1/RetroLaunch/dist/Media/menuMainBG.png b/xbox1/RetroLaunch/dist/Media/menuMainBG.png deleted file mode 100644 index 8e6d54eee7e13d6a95fe8586631affe6465d3fd6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6415 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 diff --git a/xbox1/RetroLaunch/dist/Media/menuMainRomSelectPanel.png b/xbox1/RetroLaunch/dist/Media/menuMainRomSelectPanel.png deleted file mode 100644 index 377a9bae5bce8227d0721fbc9a73919b824d9c21..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3206 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 V33Da-#&v;nGt@QHse(B^`!_dA#9jaZ diff --git a/xbox1/RetroLaunch/dist/Roms/Add roms here.txt b/xbox1/RetroLaunch/dist/Roms/Add roms here.txt deleted file mode 100644 index e69de29bb2..0000000000 From 37f57993028edd938b6800c867a754c7ca3ac1fb Mon Sep 17 00:00:00 2001 From: twinaphex Date: Tue, 24 Jul 2012 16:17:50 +0200 Subject: [PATCH 31/51] (Xbox 1) Remove retroarch.h header file --- xbox1/RetroLaunch/retroarch.h | 5 ----- xbox1/frontend/menu.cpp | 2 ++ 2 files changed, 2 insertions(+), 5 deletions(-) delete mode 100644 xbox1/RetroLaunch/retroarch.h diff --git a/xbox1/RetroLaunch/retroarch.h b/xbox1/RetroLaunch/retroarch.h deleted file mode 100644 index a751129251..0000000000 --- a/xbox1/RetroLaunch/retroarch.h +++ /dev/null @@ -1,5 +0,0 @@ -// Automatically generated by the bundler tool from retroarch.jpg - -#define retroarch_NUM_RESOURCES 1UL - -#define retroarch_OFFSET 0UL diff --git a/xbox1/frontend/menu.cpp b/xbox1/frontend/menu.cpp index 6119ff253e..8cf2ed99be 100644 --- a/xbox1/frontend/menu.cpp +++ b/xbox1/frontend/menu.cpp @@ -73,4 +73,6 @@ void menu_loop(void) d3d->d3d_render_device->EndScene(); d3d->d3d_render_device->Present(NULL, NULL, NULL, NULL); }while(g_console.menu_enable); + + g_console.ingame_menu_enable = false; } From 53c5ff80ed568eac29af62129d6f496731d697fb Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Tue, 24 Jul 2012 16:09:48 +0200 Subject: [PATCH 32/51] (Xbox 1) Resize title image to 128x128 --- xbox1/RetroLaunch/titleimage.bmp | Bin 0 -> 49274 bytes xbox1/RetroLaunch/titleimage.jpg | Bin 8865 -> 0 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 xbox1/RetroLaunch/titleimage.bmp delete mode 100644 xbox1/RetroLaunch/titleimage.jpg diff --git a/xbox1/RetroLaunch/titleimage.bmp b/xbox1/RetroLaunch/titleimage.bmp new file mode 100644 index 0000000000000000000000000000000000000000..a7d3e62ff64e363f86c23a41432ab7f99441e8cd GIT binary patch literal 49274 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 literal 0 HcmV?d00001 diff --git a/xbox1/RetroLaunch/titleimage.jpg b/xbox1/RetroLaunch/titleimage.jpg deleted file mode 100644 index 1b0bc9586da2660ba3f1cd09fb18ce5ebd01f6c8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8865 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 O-z~}huk$g?&;J2#&AQP5 From 2240e96b20aa67a4c0dd895ef5c0abb6a0212b1c Mon Sep 17 00:00:00 2001 From: twinaphex Date: Tue, 24 Jul 2012 17:00:24 +0200 Subject: [PATCH 33/51] (Xbox 1) RetroLaunch - complexity cleanups --- xbox1/RetroLaunch/Font.cpp | 18 +- xbox1/RetroLaunch/Font.h | 4 +- xbox1/RetroLaunch/IoSupport.cpp | 73 +------- xbox1/RetroLaunch/IoSupport.h | 4 - xbox1/RetroLaunch/MenuMain.cpp | 269 ++++++++++++++---------------- xbox1/RetroLaunch/MenuMain.h | 21 --- xbox1/RetroLaunch/MenuManager.cpp | 50 +++--- xbox1/RetroLaunch/MenuManager.h | 3 +- xbox1/RetroLaunch/Rom.cpp | 17 +- xbox1/RetroLaunch/Rom.h | 10 +- xbox1/RetroLaunch/RomList.cpp | 64 +------ xbox1/RetroLaunch/RomList.h | 12 -- xbox1/RetroLaunch/Surface.cpp | 7 - xbox1/RetroLaunch/Surface.h | 1 - 14 files changed, 164 insertions(+), 389 deletions(-) diff --git a/xbox1/RetroLaunch/Font.cpp b/xbox1/RetroLaunch/Font.cpp index 2b246a51b7..51b2bda691 100644 --- a/xbox1/RetroLaunch/Font.cpp +++ b/xbox1/RetroLaunch/Font.cpp @@ -34,16 +34,11 @@ Font::~Font(void) } bool Font::Create() -{ //Hardcoded - return Create("D:\\Media\\arial.ttf"); -} - -bool Font::Create(const string &szTTFFilename) { if (m_pFont) m_pFont->Release(); - word *wcPathBuf = StringToWChar(szTTFFilename); + word *wcPathBuf = StringToWChar("D:\\Media\\arial.ttf"); HRESULT g_hResult = XFONT_OpenTrueTypeFont(wcPathBuf, 256 * 1024, &m_pFont); delete [] wcPathBuf; @@ -67,13 +62,9 @@ void Font::Render(const string &str, int x, int y, dword height, dword style, D3 delete [] wcBuf; if (alignment == Center) - { x -= (dwRequiredWidth / 2); - } else if (alignment == Right) - { x -= dwRequiredWidth; - } } texture.Render(x, y); @@ -102,13 +93,10 @@ void Font::RenderToTexture(CSurface &texture, const string &str, dword height, d // because the textures are swizzled we make sure // the dimensions are a power of two for(dword wmask = 1; dwTextureWidth &(dwTextureWidth - 1); wmask = (wmask << 1 ) + 1) - { dwTextureWidth = (dwTextureWidth + wmask) & ~wmask; - } + for(dword hmask = 1; dwTextureHeight &(dwTextureHeight - 1); hmask = (hmask << 1) + 1) - { dwTextureHeight = ( dwTextureHeight + hmask ) & ~hmask; - } // also enforce a minimum pitch of 64 bytes dwTextureWidth = max(64 / XGBytesPerPixelFromFormat(D3DFMT_A8R8G8B8), dwTextureWidth); @@ -228,4 +216,4 @@ word *Font::StringToWChar(const string &str) return retVal; } -#endif \ No newline at end of file +#endif diff --git a/xbox1/RetroLaunch/Font.h b/xbox1/RetroLaunch/Font.h index 3126ee2c9d..96e3dd2049 100644 --- a/xbox1/RetroLaunch/Font.h +++ b/xbox1/RetroLaunch/Font.h @@ -35,7 +35,6 @@ public: ~Font(void); bool Create(); - bool Create(const string &szTTFFilename); void Render(const string &str, int x, int y, dword height, dword style = XFONT_NORMAL, D3DXCOLOR color = D3DCOLOR_XRGB(0, 0, 0), int dwMaxWidth = -1, bool fade = false, Align alignment = Left); void RenderToTexture(CSurface &texture, const string &str, dword height, dword style = XFONT_NORMAL, D3DXCOLOR color = D3DCOLOR_XRGB(0, 0, 0), int maxWidth = -1, bool fade = false); @@ -44,10 +43,9 @@ public: int GetRequiredHeight(const string &str, dword height, dword style); word *StringToWChar(const string &str); - private: XFONT *m_pFont; }; extern Font g_font; -#endif \ No newline at end of file +#endif diff --git a/xbox1/RetroLaunch/IoSupport.cpp b/xbox1/RetroLaunch/IoSupport.cpp index 0885ed76c2..cfeea542f5 100644 --- a/xbox1/RetroLaunch/IoSupport.cpp +++ b/xbox1/RetroLaunch/IoSupport.cpp @@ -1,7 +1,6 @@ // IoSupport.cpp: implementation of the CIoSupport class. // ////////////////////////////////////////////////////////////////////// -#ifdef _XBOX #include "iosupport.h" #include "undocumented.h" @@ -188,74 +187,4 @@ HRESULT CIoSupport::Shutdown() { HalInitiateShutdown(); return S_OK; -} - -HANDLE CIoSupport::CreateFile() -{ - ANSI_STRING filename; - OBJECT_ATTRIBUTES attributes; - IO_STATUS_BLOCK status; - HANDLE hDevice; - NTSTATUS error; - - RtlInitAnsiString(&filename, "\\Device\\Cdrom0"); - InitializeObjectAttributes(&attributes, &filename, OBJ_CASE_INSENSITIVE, NULL); - - if (!NT_SUCCESS(error = NtCreateFile(&hDevice, GENERIC_READ | - SYNCHRONIZE | FILE_READ_ATTRIBUTES, &attributes, &status, NULL, 0, - FILE_SHARE_READ, FILE_OPEN, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT))) - { - return NULL; - } - - return hDevice; -} - -BOOL CIoSupport::GetFirstFile(CHAR* szFilename) -{ - ANSI_STRING filename; - OBJECT_ATTRIBUTES attributes; - IO_STATUS_BLOCK status; - HANDLE hDevice; - NTSTATUS error; - - RtlInitAnsiString(&filename, "\\Device\\Cdrom0"); - InitializeObjectAttributes(&attributes, &filename, OBJ_CASE_INSENSITIVE, NULL); - - if (!NT_SUCCESS(error = NtCreateFile(&hDevice, GENERIC_READ | - SYNCHRONIZE | FILE_READ_ATTRIBUTES, &attributes, &status, NULL, 0, - FILE_SHARE_READ, FILE_OPEN, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT))) - { - OutputDebugString("Unable to open Cdrom0.\n"); - return FALSE; - } - - - CHAR* szBuffer = new CHAR[2048]; - DWORD dwRead = 0; - - SetFilePointer(hDevice, 19 * 2048, NULL, FILE_BEGIN); - if (!ReadFile(hDevice, szBuffer, 2048, &dwRead, NULL)) - { - OutputDebugString("Unable to read ISO9660 root directory.\n"); - CloseHandle(hDevice); - return FALSE; - } - - CloseHandle(hDevice); - szBuffer[2047] = 0; - - int offset = 0; - while (szBuffer[offset] == 0x22) offset += 0x22; - offset += 33; // jump to start of filename - - strcpy(szFilename, "#"); - strcat(szFilename, &szBuffer[offset]); - - if (szBuffer) - delete [] szBuffer; - - return TRUE; -} - -#endif \ No newline at end of file +} \ No newline at end of file diff --git a/xbox1/RetroLaunch/IoSupport.h b/xbox1/RetroLaunch/IoSupport.h index 2319c1b3ed..14268e6b25 100644 --- a/xbox1/RetroLaunch/IoSupport.h +++ b/xbox1/RetroLaunch/IoSupport.h @@ -38,10 +38,6 @@ public: HRESULT EjectTray(); HRESULT CloseTray(); HRESULT Shutdown(); - - HANDLE CreateFile(); - BOOL GetFirstFile(CHAR* szFilename); - private: DWORD m_dwTrayState; DWORD m_dwTrayCount; diff --git a/xbox1/RetroLaunch/MenuMain.cpp b/xbox1/RetroLaunch/MenuMain.cpp index 4bd84c7cc2..c934496565 100644 --- a/xbox1/RetroLaunch/MenuMain.cpp +++ b/xbox1/RetroLaunch/MenuMain.cpp @@ -24,122 +24,108 @@ CMenuMain g_menuMain; CMenuMain::CMenuMain() { - // we think that the rom list is unloaded until we know otherwise - m_bRomListLoadedState = false; + // we think that the rom list is unloaded until we know otherwise + m_bRomListLoadedState = false; - ifstream stateFile; - stateFile.open("T:\\RomlistState.dat"); + ifstream stateFile; + stateFile.open("T:\\RomlistState.dat"); - if (stateFile.is_open()) - { - int baseIndex; - int romListMode; + if (stateFile.is_open()) + { + int baseIndex; - stateFile >> baseIndex; - stateFile >> romListMode; - stateFile >> m_displayMode; + stateFile >> baseIndex; - g_romList.SetRomListMode(romListMode); - g_romList.m_iBaseIndex = baseIndex; + g_romList.m_iBaseIndex = baseIndex; - stateFile.close(); - } - else - { - m_displayMode = List; - } + stateFile.close(); + } } CMenuMain::~CMenuMain() { - ofstream stateFile; - stateFile.open("T:\\RomlistState.dat"); + ofstream stateFile; + stateFile.open("T:\\RomlistState.dat"); - stateFile << g_romList.GetBaseIndex() << endl; - stateFile << g_romList.GetRomListMode() << endl; - stateFile << m_displayMode << endl; + stateFile << g_romList.GetBaseIndex() << endl; - stateFile.close(); + stateFile.close(); } bool CMenuMain::Create() { - RARCH_LOG("CMenuMain::Create()."); + RARCH_LOG("CMenuMain::Create()."); - // Title coords with color - m_menuMainTitle_x = 305; - m_menuMainTitle_y = 30; - m_menuMainTitle_c = 0xFFFFFFFF; + // Title coords with color + m_menuMainTitle_x = 305; + m_menuMainTitle_y = 30; + m_menuMainTitle_c = 0xFFFFFFFF; - // Load background image - m_menuMainBG.Create("Media\\menuMainBG.png"); - m_menuMainBG_x = 0; - m_menuMainBG_y = 0; - m_menuMainBG_w = 640; - m_menuMainBG_h = 480; + // Load background image + m_menuMainBG.Create("Media\\menuMainBG.png"); + m_menuMainBG_x = 0; + m_menuMainBG_y = 0; + m_menuMainBG_w = 640; + m_menuMainBG_h = 480; - // Init rom list coords - m_menuMainRomListPos_x = 100; - m_menuMainRomListPos_y = 100; - m_menuMainRomListSpacing = 20; + // Init rom list coords + m_menuMainRomListPos_x = 100; + m_menuMainRomListPos_y = 100; + m_menuMainRomListSpacing = 20; - // Load rom selector panel - m_menuMainRomSelectPanel.Create("Media\\menuMainRomSelectPanel.png"); - m_menuMainRomSelectPanel_x = m_menuMainRomListPos_x - 5; - m_menuMainRomSelectPanel_y = m_menuMainRomListPos_y - 2; - m_menuMainRomSelectPanel_w = 440; - m_menuMainRomSelectPanel_h = 20; + // Load rom selector panel + m_menuMainRomSelectPanel.Create("Media\\menuMainRomSelectPanel.png"); + m_menuMainRomSelectPanel_x = m_menuMainRomListPos_x - 5; + m_menuMainRomSelectPanel_y = m_menuMainRomListPos_y - 2; + m_menuMainRomSelectPanel_w = 440; + m_menuMainRomSelectPanel_h = 20; - m_romListSelectedRom = 0; + m_romListSelectedRom = 0; - //The first element in the romlist to render - m_romListBeginRender = 0; + //The first element in the romlist to render + m_romListBeginRender = 0; - //The last element in the romlist to render - m_romListEndRender = 18; + //The last element in the romlist to render + m_romListEndRender = 18; - //The offset in the romlist - m_romListOffset = 0; + //The offset in the romlist + m_romListOffset = 0; - if(m_romListEndRender > g_romList.GetRomListSize() - 1) - { - m_romListEndRender = g_romList.GetRomListSize() - 1; - } + if(m_romListEndRender > g_romList.GetRomListSize() - 1) + m_romListEndRender = g_romList.GetRomListSize() - 1; - //Generate the rom list textures only once - vector::iterator i; - dword y = 0; - for (i = g_romList.m_romList.begin(); i != g_romList.m_romList.end(); i++) - { - Rom *rom = *i; - g_font.RenderToTexture(rom->GetTexture(), rom->GetFileName(), 18, XFONT_BOLD, 0xff808080, -1, false); - } + //Generate the rom list textures only once + vector::iterator i; + dword y = 0; + for (i = g_romList.m_romList.begin(); i != g_romList.m_romList.end(); i++) + { + Rom *rom = *i; + g_font.RenderToTexture(rom->GetTexture(), rom->GetFileName(), 18, XFONT_BOLD, 0xff808080, -1, false); + } - return true; + return true; } void CMenuMain::Render() { - //CheckRomListState(); + //Render background image + m_menuMainBG.Render(m_menuMainBG_x, m_menuMainBG_y); - //Render background image - m_menuMainBG.Render(m_menuMainBG_x, m_menuMainBG_y); + //Display some text + g_font.Render("Press RSTICK THUMB to exit. Press START and/or A to launch a rom.", 65, 430, 16, XFONT_NORMAL, m_menuMainTitle_c); - //Display some text - g_font.Render("Press RSTICK THUMB to exit. Press START and/or A to launch a rom.", 65, 430, 16, XFONT_NORMAL, m_menuMainTitle_c); + //Begin with the rom selector panel + //FIXME: Width/Height needs to be current Rom texture width/height (or should we just leave it at a fixed size?) + m_menuMainRomSelectPanel.Render(m_menuMainRomSelectPanel_x, m_menuMainRomSelectPanel_y, m_menuMainRomSelectPanel_w, m_menuMainRomSelectPanel_h); - //Begin with the rom selector panel - //FIXME: Width/Height needs to be current Rom texture width/height (or should we just leave it at a fixed size?) - m_menuMainRomSelectPanel.Render(m_menuMainRomSelectPanel_x, m_menuMainRomSelectPanel_y, m_menuMainRomSelectPanel_w, m_menuMainRomSelectPanel_h); + dword dwSpacing = 0; - dword dwSpacing = 0; - - for (int i = m_romListBeginRender; i <= m_romListEndRender; i++) - { - g_romList.GetRomAt(i + m_romListOffset)->GetTexture().Render(m_menuMainRomListPos_x, m_menuMainRomListPos_y + dwSpacing); - dwSpacing += m_menuMainRomListSpacing; - } + for (int i = m_romListBeginRender; i <= m_romListEndRender; i++) + { + g_romList.GetRomAt(i + m_romListOffset)->GetTexture().Render(m_menuMainRomListPos_x, m_menuMainRomListPos_y + dwSpacing); + dwSpacing += m_menuMainRomListSpacing; + } } static uint16_t old_input_state = 0; @@ -157,79 +143,72 @@ void CMenuMain::ProcessInput() uint16_t trigger_state = input_state & ~old_input_state; - if(trigger_state & (1 << RETRO_DEVICE_ID_JOYPAD_DOWN)) - { - if(m_romListSelectedRom < g_romList.GetRomListSize()) - { + if(trigger_state & (1 << RETRO_DEVICE_ID_JOYPAD_DOWN)) + { + if(m_romListSelectedRom < g_romList.GetRomListSize()) + { + if(m_menuMainRomSelectPanel_y < (m_menuMainRomListPos_y + (m_menuMainRomListSpacing * m_romListEndRender))) + { + m_menuMainRomSelectPanel_y += m_menuMainRomListSpacing; + m_romListSelectedRom++; + RARCH_LOG("SELECTED ROM: %d.\n", m_romListSelectedRom); + } - if(m_menuMainRomSelectPanel_y < (m_menuMainRomListPos_y + (m_menuMainRomListSpacing * m_romListEndRender))) - { - m_menuMainRomSelectPanel_y += m_menuMainRomListSpacing; - m_romListSelectedRom++; - RARCH_LOG("SELECTED ROM: %d.\n", m_romListSelectedRom); - } + if(m_menuMainRomSelectPanel_y > (m_menuMainRomListPos_y + (m_menuMainRomListSpacing * (m_romListEndRender)))) + { + m_menuMainRomSelectPanel_y -= m_menuMainRomListSpacing; + m_romListSelectedRom++; + if(m_romListSelectedRom > g_romList.GetRomListSize() - 1) + m_romListSelectedRom = g_romList.GetRomListSize() - 1; - if(m_menuMainRomSelectPanel_y > (m_menuMainRomListPos_y + (m_menuMainRomListSpacing * (m_romListEndRender)))) - { - m_menuMainRomSelectPanel_y -= m_menuMainRomListSpacing; - m_romListSelectedRom++; - if(m_romListSelectedRom > g_romList.GetRomListSize() - 1) - { - m_romListSelectedRom = g_romList.GetRomListSize() - 1; - } + RARCH_LOG("SELECTED ROM AFTER CORRECTION: %d.\n", m_romListSelectedRom); + if(m_romListSelectedRom < g_romList.GetRomListSize() - 1 && m_romListOffset < g_romList.GetRomListSize() - 1 - m_romListEndRender - 1) + { + m_romListOffset++; + RARCH_LOG("OFFSET: %d.\n", m_romListOffset); + } + } + } + } - RARCH_LOG("SELECTED ROM AFTER CORRECTION: %d.\n", m_romListSelectedRom); + if(trigger_state & (1 << RETRO_DEVICE_ID_JOYPAD_UP)) + { + if(m_romListSelectedRom > -1) + { + if(m_menuMainRomSelectPanel_y > (m_menuMainRomListPos_y - m_menuMainRomListSpacing)) + { + m_menuMainRomSelectPanel_y -= m_menuMainRomListSpacing; + m_romListSelectedRom--; + RARCH_LOG("SELECTED ROM: %d.\n", m_romListSelectedRom); + } - if(m_romListSelectedRom < g_romList.GetRomListSize() - 1 && m_romListOffset < g_romList.GetRomListSize() - 1 - m_romListEndRender - 1) { - m_romListOffset++; - RARCH_LOG("OFFSET: %d.\n", m_romListOffset); - } - } - } - } + if(m_menuMainRomSelectPanel_y < (m_menuMainRomListPos_y - m_menuMainRomListSpacing)) + { + m_menuMainRomSelectPanel_y += m_menuMainRomListSpacing; + m_romListSelectedRom--; + if(m_romListSelectedRom < 0) + m_romListSelectedRom = 0; - if(trigger_state & (1 << RETRO_DEVICE_ID_JOYPAD_UP)) - { - if(m_romListSelectedRom > -1) - { - if(m_menuMainRomSelectPanel_y > (m_menuMainRomListPos_y - m_menuMainRomListSpacing)) - { - m_menuMainRomSelectPanel_y -= m_menuMainRomListSpacing; - m_romListSelectedRom--; - RARCH_LOG("SELECTED ROM: %d.\n", m_romListSelectedRom); - } + RARCH_LOG("SELECTED ROM AFTER CORRECTION: %d.\n", m_romListSelectedRom); - if(m_menuMainRomSelectPanel_y < (m_menuMainRomListPos_y - m_menuMainRomListSpacing)) - { - m_menuMainRomSelectPanel_y += m_menuMainRomListSpacing; - m_romListSelectedRom--; - if(m_romListSelectedRom < 0) - { - m_romListSelectedRom = 0; - } + if(m_romListSelectedRom > 0 && m_romListOffset > 0) + { + m_romListOffset--; + RARCH_LOG("OFFSET: %d.\n", m_romListOffset); + } + } + } + } - - RARCH_LOG("SELECTED ROM AFTER CORRECTION: %d.\n", m_romListSelectedRom); - - if(m_romListSelectedRom > 0 && m_romListOffset > 0) { - m_romListOffset--; - RARCH_LOG("OFFSET: %d.\n", m_romListOffset); - } - } - } - } - - // Press A to launch, selected rom filename is saved into T:\\tmp.retro - if(trigger_state & (1 << RETRO_DEVICE_ID_JOYPAD_B) || trigger_state & (1 << RETRO_DEVICE_ID_JOYPAD_START)) - { + // Press A to launch, selected rom filename is saved into T:\\tmp.retro + if (trigger_state & (1 << RETRO_DEVICE_ID_JOYPAD_B) || trigger_state & (1 << RETRO_DEVICE_ID_JOYPAD_START)) rarch_console_load_game(g_romList.GetRomAt(m_romListSelectedRom)->GetFileName().c_str()); - } - if (trigger_state & (1 << RETRO_DEVICE_ID_JOYPAD_R3)) - { - LD_LAUNCH_DASHBOARD LaunchData = { XLD_LAUNCH_DASHBOARD_MAIN_MENU }; - XLaunchNewImage( NULL, (LAUNCH_DATA*)&LaunchData ); - } + if (trigger_state & (1 << RETRO_DEVICE_ID_JOYPAD_R3)) + { + LD_LAUNCH_DASHBOARD LaunchData = { XLD_LAUNCH_DASHBOARD_MAIN_MENU }; + XLaunchNewImage( NULL, (LAUNCH_DATA*)&LaunchData ); + } } diff --git a/xbox1/RetroLaunch/MenuMain.h b/xbox1/RetroLaunch/MenuMain.h index c8d9135fbd..d131da2f2e 100644 --- a/xbox1/RetroLaunch/MenuMain.h +++ b/xbox1/RetroLaunch/MenuMain.h @@ -17,12 +17,6 @@ #include "Global.h" #include "Surface.h" -enum DisplayMode -{ - Box, - List -}; - class CMenuMain { public: @@ -69,21 +63,6 @@ int m_menuMainRomListPos_x; int m_menuMainRomListPos_y; int m_menuMainRomListSpacing; - - - -/** -* The Rom List menu buttons. The size can be variable so we use a list -*/ -//list m_romListButtons;//list -//no menu buttons, we will use plain textures -list m_romListButtons; - -/** -* The current mode the rom list is in -*/ -int m_displayMode; - /** * The current loaded state the rom list is in */ diff --git a/xbox1/RetroLaunch/MenuManager.cpp b/xbox1/RetroLaunch/MenuManager.cpp index 4c25c7d485..2c68f6912a 100644 --- a/xbox1/RetroLaunch/MenuManager.cpp +++ b/xbox1/RetroLaunch/MenuManager.cpp @@ -31,42 +31,38 @@ CMenuManager::~CMenuManager() bool CMenuManager::Create() { - //Create the MenuManager, set to Main Menu - RARCH_LOG("Create MenuManager, set state to MENU_MAIN.\n"); - SetMenuState(MENU_MAIN); + //Create the MenuManager, set to Main Menu + RARCH_LOG("Create MenuManager, set state to MENU_MAIN.\n"); + SetMenuState(MENU_MAIN); - return true; + return true; } bool CMenuManager::SetMenuState(int nMenuID) { - m_pMenuID = nMenuID; + m_pMenuID = nMenuID; - switch (m_pMenuID) { - case MENU_MAIN: - //Create the Main Menu - g_menuMain.Create(); - break; - } - return true; + switch (m_pMenuID) + { + case MENU_MAIN: + //Create the Main Menu + g_menuMain.Create(); + break; + } + return true; } void CMenuManager::Update() { - //Process overall input - ProcessInput(); - - switch (m_pMenuID) { - case MENU_MAIN: - - // Process menu specific input - g_menuMain.ProcessInput(); - - // Render the Main Menu - g_menuMain.Render(); - break; - } + ProcessInput(); + switch (m_pMenuID) + { + case MENU_MAIN: + g_menuMain.ProcessInput(); + g_menuMain.Render(); + break; + } } @@ -74,10 +70,8 @@ void CMenuManager::ProcessInput() { } - - int CMenuManager::GetMenuState() { - return m_pMenuID; + return m_pMenuID; } diff --git a/xbox1/RetroLaunch/MenuManager.h b/xbox1/RetroLaunch/MenuManager.h index 0e888299aa..6f287b5c55 100644 --- a/xbox1/RetroLaunch/MenuManager.h +++ b/xbox1/RetroLaunch/MenuManager.h @@ -27,7 +27,6 @@ enum eMenuState MENU_LAUNCHER }; - class CMenuManager { public: @@ -47,4 +46,4 @@ int m_pMenuID; }; -extern CMenuManager g_menuManager; \ No newline at end of file +extern CMenuManager g_menuManager; diff --git a/xbox1/RetroLaunch/Rom.cpp b/xbox1/RetroLaunch/Rom.cpp index c05c93818c..4a58a724a6 100644 --- a/xbox1/RetroLaunch/Rom.cpp +++ b/xbox1/RetroLaunch/Rom.cpp @@ -14,7 +14,6 @@ */ #include "Rom.h" -//#include "BoxArtTable.h" Rom::Rom() { @@ -25,28 +24,21 @@ Rom::~Rom(void) { } -bool Rom::Load(const string &szFilename) +bool Rom::Load(const char *szFilename) { if (m_bLoaded) return true; m_szFilename = szFilename; - // get the filename for the box art image - //FIXME: Add BoxArtTable.cpp/h, open iso file, grab header, extract ID ie. T-6003G, use for boxartfilename - { - m_szBoxArtFilename = "D:\\boxart\\default.jpg"; //g_boxArtTable.GetBoxArtFilename(m_dwCrc1); - } - m_bLoaded = true; return true; } -bool Rom::LoadFromCache(const string &szFilename, const string &szBoxArtFilename) +bool Rom::LoadFromCache(const string &szFilename) { m_szFilename = szFilename; - m_szBoxArtFilename = szBoxArtFilename; m_bLoaded = true; @@ -58,11 +50,6 @@ string Rom::GetFileName() return m_szFilename; } -string Rom::GetBoxArtFilename() -{ - return m_szBoxArtFilename; -} - string Rom::GetComments() { //return string(m_iniEntry->szComments); diff --git a/xbox1/RetroLaunch/Rom.h b/xbox1/RetroLaunch/Rom.h index b1df6f22fa..37321695a0 100644 --- a/xbox1/RetroLaunch/Rom.h +++ b/xbox1/RetroLaunch/Rom.h @@ -24,20 +24,14 @@ public: Rom(); ~Rom(); - bool Load(const string &szFilename); - bool LoadFromCache(const string &szFilename, const string &szBoxArtFilename); + bool Load(const char *szFilename); + bool LoadFromCache(const string &szFilename); string GetFileName(); - string GetBoxArtFilename(); string GetComments(); - CSurface &GetTexture(); - private: string m_szFilename; - string m_szBoxArtFilename; - bool m_bLoaded; - CSurface m_texture; }; diff --git a/xbox1/RetroLaunch/RomList.cpp b/xbox1/RetroLaunch/RomList.cpp index 5ee25a2071..f87db7a01a 100644 --- a/xbox1/RetroLaunch/RomList.cpp +++ b/xbox1/RetroLaunch/RomList.cpp @@ -24,7 +24,6 @@ bool RLessThan(Rom *elem1, Rom *elem2) RomList::RomList(void) { - m_romListMode = All; m_iBaseIndex = 0; m_bLoaded = false; m_szRomPath = "D:\\"; @@ -51,14 +50,12 @@ void RomList::Load() while (!cacheFile.eof()) { string szFilename; - string szBoxArtFilename; getline(cacheFile, szFilename); - getline(cacheFile, szBoxArtFilename); Rom *rom = new Rom(); - bool bSuccess = rom->LoadFromCache(szFilename, szBoxArtFilename); + bool bSuccess = rom->LoadFromCache(szFilename); if (bSuccess) m_romList.push_back(rom); @@ -85,7 +82,6 @@ void RomList::Save() Rom *rom = *i; cacheFile << rom->GetFileName() << endl; - cacheFile << rom->GetBoxArtFilename() << endl; } cacheFile.close(); @@ -103,29 +99,11 @@ bool RomList::IsLoaded() return m_bLoaded; } -void RomList::SetRomListMode(int mode) -{ - m_iBaseIndex = 0; - m_romListMode = mode; -} - -int RomList::GetRomListMode() -{ - return m_romListMode; -} - void RomList::AddRomToList(Rom *rom, int mode) { vector *pList; - switch (mode) - { - case All: - pList = &m_romList; - break; - default: - return; - } + pList = &m_romList; // look to see if the rom is already in the list, we dont want duplicates for (int i = 0; i < static_cast(pList->size()); i++) @@ -141,15 +119,8 @@ void RomList::AddRomToList(Rom *rom, int mode) void RomList::RemoveRomFromList(Rom *rom, int mode) { vector *pList; - - switch (mode) - { - case All: - pList = &m_romList; - break; - default: - return; - } + + pList = &m_romList; vector::iterator i; @@ -186,38 +157,19 @@ void RomList::SetBaseIndex(int index) int RomList::GetRomListSize() { - switch (m_romListMode) - { - case All: - return m_romList.size(); - } - - return 0; + return m_romList.size(); } Rom *RomList::GetRomAt(int index) { - switch (m_romListMode) - { - case All: - return m_romList[index]; - } - - return 0; + return m_romList[index]; } int RomList::FindRom(Rom *rom, int mode) { vector *pList; - - switch (mode) - { - case All: - pList = &m_romList; - break; - default: - return -1; - } + + pList = &m_romList; for (int i = 0; i < static_cast(pList->size()); i++) { diff --git a/xbox1/RetroLaunch/RomList.h b/xbox1/RetroLaunch/RomList.h index 3fa19615d4..5f151f1a53 100644 --- a/xbox1/RetroLaunch/RomList.h +++ b/xbox1/RetroLaunch/RomList.h @@ -18,11 +18,6 @@ #include "Global.h" #include "Rom.h" -enum RomListMode -{ - All -}; - class RomList { public: @@ -35,9 +30,6 @@ public: bool IsLoaded(); - void SetRomListMode(int mode); - int GetRomListMode(); - void AddRomToList(Rom *rom, int mode); void RemoveRomFromList(Rom *rom, int mode); @@ -61,11 +53,7 @@ private: void Destroy(); private: - bool m_bLoaded; - - int m_romListMode; - string m_szRomPath; }; diff --git a/xbox1/RetroLaunch/Surface.cpp b/xbox1/RetroLaunch/Surface.cpp index 7df8d7ee4a..e389a45526 100644 --- a/xbox1/RetroLaunch/Surface.cpp +++ b/xbox1/RetroLaunch/Surface.cpp @@ -215,13 +215,6 @@ void CSurface::SetOpacity(byte opacity) m_byOpacity = opacity; } -void CSurface::SetTint(byte r, byte g, byte b) -{ - m_byR = r; - m_byG = g; - m_byB = b; -} - void CSurface::MoveTo(int x, int y) { m_x = x; diff --git a/xbox1/RetroLaunch/Surface.h b/xbox1/RetroLaunch/Surface.h index e9b6b42068..c8df7a06fc 100644 --- a/xbox1/RetroLaunch/Surface.h +++ b/xbox1/RetroLaunch/Surface.h @@ -43,7 +43,6 @@ public: * Set functions */ void SetOpacity(byte opacity); - void SetTint(byte r, byte g, byte b); void MoveTo(int x, int y); From a82d0c7a9ecc94cae03a6f69c6b1b78c64a05bd5 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Tue, 24 Jul 2012 17:45:28 +0200 Subject: [PATCH 34/51] (Xbox 1) Freed up some more memory (32MB to 36MB free in VBA Next) --- xbox1/RetroLaunch/Font.cpp | 5 +--- xbox1/RetroLaunch/MenuMain.cpp | 20 ------------- xbox1/RetroLaunch/MenuManager.cpp | 6 ++-- xbox1/RetroLaunch/Rom.cpp | 16 ---------- xbox1/RetroLaunch/Rom.h | 2 -- xbox1/RetroLaunch/RomList.cpp | 50 +------------------------------ xbox1/RetroLaunch/RomList.h | 3 +- 7 files changed, 6 insertions(+), 96 deletions(-) diff --git a/xbox1/RetroLaunch/Font.cpp b/xbox1/RetroLaunch/Font.cpp index 51b2bda691..6ea617d7a0 100644 --- a/xbox1/RetroLaunch/Font.cpp +++ b/xbox1/RetroLaunch/Font.cpp @@ -38,10 +38,7 @@ bool Font::Create() if (m_pFont) m_pFont->Release(); - word *wcPathBuf = StringToWChar("D:\\Media\\arial.ttf"); - HRESULT g_hResult = XFONT_OpenTrueTypeFont(wcPathBuf, 256 * 1024, &m_pFont); - - delete [] wcPathBuf; + HRESULT g_hResult = XFONT_OpenTrueTypeFont(L"D:\\Media\\arial.ttf", 256 * 1024, &m_pFont); if (FAILED(g_hResult)) return false; diff --git a/xbox1/RetroLaunch/MenuMain.cpp b/xbox1/RetroLaunch/MenuMain.cpp index c934496565..f25952f92d 100644 --- a/xbox1/RetroLaunch/MenuMain.cpp +++ b/xbox1/RetroLaunch/MenuMain.cpp @@ -26,30 +26,10 @@ CMenuMain::CMenuMain() { // we think that the rom list is unloaded until we know otherwise m_bRomListLoadedState = false; - - ifstream stateFile; - stateFile.open("T:\\RomlistState.dat"); - - if (stateFile.is_open()) - { - int baseIndex; - - stateFile >> baseIndex; - - g_romList.m_iBaseIndex = baseIndex; - - stateFile.close(); - } } CMenuMain::~CMenuMain() { - ofstream stateFile; - stateFile.open("T:\\RomlistState.dat"); - - stateFile << g_romList.GetBaseIndex() << endl; - - stateFile.close(); } bool CMenuMain::Create() diff --git a/xbox1/RetroLaunch/MenuManager.cpp b/xbox1/RetroLaunch/MenuManager.cpp index 2c68f6912a..ae2550e010 100644 --- a/xbox1/RetroLaunch/MenuManager.cpp +++ b/xbox1/RetroLaunch/MenuManager.cpp @@ -47,7 +47,7 @@ bool CMenuManager::SetMenuState(int nMenuID) case MENU_MAIN: //Create the Main Menu g_menuMain.Create(); - break; + break; } return true; } @@ -60,8 +60,8 @@ void CMenuManager::Update() { case MENU_MAIN: g_menuMain.ProcessInput(); - g_menuMain.Render(); - break; + g_menuMain.Render(); + break; } } diff --git a/xbox1/RetroLaunch/Rom.cpp b/xbox1/RetroLaunch/Rom.cpp index 4a58a724a6..cf7505d91d 100644 --- a/xbox1/RetroLaunch/Rom.cpp +++ b/xbox1/RetroLaunch/Rom.cpp @@ -36,27 +36,11 @@ bool Rom::Load(const char *szFilename) return true; } -bool Rom::LoadFromCache(const string &szFilename) -{ - m_szFilename = szFilename; - - m_bLoaded = true; - - return true; -} - string Rom::GetFileName() { return m_szFilename; } -string Rom::GetComments() -{ - //return string(m_iniEntry->szComments); - return "blah"; -} - - CSurface &Rom::GetTexture() { return m_texture; diff --git a/xbox1/RetroLaunch/Rom.h b/xbox1/RetroLaunch/Rom.h index 37321695a0..c0bf815e28 100644 --- a/xbox1/RetroLaunch/Rom.h +++ b/xbox1/RetroLaunch/Rom.h @@ -25,10 +25,8 @@ public: ~Rom(); bool Load(const char *szFilename); - bool LoadFromCache(const string &szFilename); string GetFileName(); - string GetComments(); CSurface &GetTexture(); private: string m_szFilename; diff --git a/xbox1/RetroLaunch/RomList.cpp b/xbox1/RetroLaunch/RomList.cpp index f87db7a01a..bca48369d1 100644 --- a/xbox1/RetroLaunch/RomList.cpp +++ b/xbox1/RetroLaunch/RomList.cpp @@ -36,62 +36,14 @@ RomList::~RomList(void) void RomList::Load() { - ifstream cacheFile; - - cacheFile.open("T:\\RomlistCache.dat"); - - // try and open the cache file, if it doesnt exist, generate the rom list - if (!cacheFile.is_open()) - { - Build(); - } - else - { - while (!cacheFile.eof()) - { - string szFilename; - - getline(cacheFile, szFilename); - - Rom *rom = new Rom(); - - bool bSuccess = rom->LoadFromCache(szFilename); - - if (bSuccess) - m_romList.push_back(rom); - else - delete rom; - } - - cacheFile.close(); - } + Build(); m_bLoaded = true; } -void RomList::Save() -{ - vector::iterator i; - ofstream cacheFile; - - // open/overwrite the rom cache - cacheFile.open("T:\\RomlistCache.dat"); - - for (i = m_romList.begin(); i != m_romList.end(); i++) - { - Rom *rom = *i; - - cacheFile << rom->GetFileName() << endl; - } - - cacheFile.close(); -} - void RomList::Refresh() { Destroy(); - DeleteFile("T:\\RomlistCache.dat"); - DeleteFile("T:\\RomlistState.dat"); } bool RomList::IsLoaded() diff --git a/xbox1/RetroLaunch/RomList.h b/xbox1/RetroLaunch/RomList.h index 5f151f1a53..a2bf9562c2 100644 --- a/xbox1/RetroLaunch/RomList.h +++ b/xbox1/RetroLaunch/RomList.h @@ -22,10 +22,9 @@ class RomList { public: RomList(void); - virtual ~RomList(void); + ~RomList(void); void Load(); - void Save(); void Refresh(); bool IsLoaded(); From 5d22842f7522bd4f2baa63dbba79eec7bb8e3d32 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Tue, 24 Jul 2012 18:03:55 +0200 Subject: [PATCH 35/51] (Xbox 1) Slimming down of RetroLaunch --- xbox1/RetroLaunch/MenuMain.cpp | 4 ++-- xbox1/RetroLaunch/RomList.cpp | 28 ---------------------------- xbox1/RetroLaunch/RomList.h | 4 +--- xbox1/RetroLaunch/Surface.cpp | 10 ++-------- xbox1/RetroLaunch/Surface.h | 3 +-- xbox1/frontend/menu.cpp | 2 +- 6 files changed, 7 insertions(+), 44 deletions(-) diff --git a/xbox1/RetroLaunch/MenuMain.cpp b/xbox1/RetroLaunch/MenuMain.cpp index f25952f92d..ba7dc1d869 100644 --- a/xbox1/RetroLaunch/MenuMain.cpp +++ b/xbox1/RetroLaunch/MenuMain.cpp @@ -42,7 +42,7 @@ bool CMenuMain::Create() m_menuMainTitle_c = 0xFFFFFFFF; // Load background image - m_menuMainBG.Create("Media\\menuMainBG.png"); + m_menuMainBG.Create("D:\\Media\\menuMainBG.png"); m_menuMainBG_x = 0; m_menuMainBG_y = 0; m_menuMainBG_w = 640; @@ -54,7 +54,7 @@ bool CMenuMain::Create() m_menuMainRomListSpacing = 20; // Load rom selector panel - m_menuMainRomSelectPanel.Create("Media\\menuMainRomSelectPanel.png"); + m_menuMainRomSelectPanel.Create("D:\\Media\\menuMainRomSelectPanel.png"); m_menuMainRomSelectPanel_x = m_menuMainRomListPos_x - 5; m_menuMainRomSelectPanel_y = m_menuMainRomListPos_y - 2; m_menuMainRomSelectPanel_w = 440; diff --git a/xbox1/RetroLaunch/RomList.cpp b/xbox1/RetroLaunch/RomList.cpp index bca48369d1..c563173704 100644 --- a/xbox1/RetroLaunch/RomList.cpp +++ b/xbox1/RetroLaunch/RomList.cpp @@ -34,13 +34,6 @@ RomList::~RomList(void) Destroy(); } -void RomList::Load() -{ - Build(); - - m_bLoaded = true; -} - void RomList::Refresh() { Destroy(); @@ -117,21 +110,6 @@ Rom *RomList::GetRomAt(int index) return m_romList[index]; } -int RomList::FindRom(Rom *rom, int mode) -{ - vector *pList; - - pList = &m_romList; - - for (int i = 0; i < static_cast(pList->size()); i++) - { - if (rom == (*pList)[i]) - return i; - } - - return -1; -} - void RomList::CleanUpTextures() { if (!IsLoaded()) @@ -139,14 +117,10 @@ void RomList::CleanUpTextures() // keep the 25 textures above and below the base index for (int i = 0; i < m_iBaseIndex - 25; i++) - { m_romList[i]->GetTexture().Destroy(); - } for (int i = m_iBaseIndex + 25; i < GetRomListSize(); i++) - { m_romList[i]->GetTexture().Destroy(); - } } void RomList::DestroyAllTextures() @@ -205,9 +179,7 @@ void RomList::Destroy() vector::iterator i; for (i = m_romList.begin(); i != m_romList.end(); i++) - { delete *i; - } m_romList.clear(); } diff --git a/xbox1/RetroLaunch/RomList.h b/xbox1/RetroLaunch/RomList.h index a2bf9562c2..d7c0171256 100644 --- a/xbox1/RetroLaunch/RomList.h +++ b/xbox1/RetroLaunch/RomList.h @@ -24,8 +24,8 @@ public: RomList(void); ~RomList(void); - void Load(); void Refresh(); + void Build(); bool IsLoaded(); @@ -38,7 +38,6 @@ public: int GetRomListSize(); Rom *GetRomAt(int index); - int FindRom(Rom *rom, int mode); void CleanUpTextures(); void DestroyAllTextures(); @@ -48,7 +47,6 @@ public: vector m_romList; private: - void Build(); void Destroy(); private: diff --git a/xbox1/RetroLaunch/Surface.cpp b/xbox1/RetroLaunch/Surface.cpp index e389a45526..87ffb917e9 100644 --- a/xbox1/RetroLaunch/Surface.cpp +++ b/xbox1/RetroLaunch/Surface.cpp @@ -33,25 +33,19 @@ CSurface::CSurface() m_y = 0; } -CSurface::CSurface(const string &szFilename) -{ - CSurface(); - Create(szFilename); -} - CSurface::~CSurface() { Destroy(); } -bool CSurface::Create(const string &szFilename) +bool CSurface::Create(const char *szFilename) { xdk_d3d_video_t *d3d = (xdk_d3d_video_t*)driver.video_data; if (m_bLoaded) Destroy(); HRESULT g_hResult = D3DXCreateTextureFromFileExA(d3d->d3d_render_device, // d3d device - ("D:\\" + szFilename).c_str(), // filename + szFilename, // filename D3DX_DEFAULT, D3DX_DEFAULT, // width/height D3DX_DEFAULT, // mipmaps 0, // usage diff --git a/xbox1/RetroLaunch/Surface.h b/xbox1/RetroLaunch/Surface.h index c8df7a06fc..13766af62f 100644 --- a/xbox1/RetroLaunch/Surface.h +++ b/xbox1/RetroLaunch/Surface.h @@ -23,13 +23,12 @@ class CSurface { public: CSurface(); - CSurface(const string &szFilename); ~CSurface(); /** * Do functions */ - bool Create(const string &szFilename); + bool Create(const char *szFilename); bool Create(dword width, dword height); void Destroy(); diff --git a/xbox1/frontend/menu.cpp b/xbox1/frontend/menu.cpp index 8cf2ed99be..41c9f49a1d 100644 --- a/xbox1/frontend/menu.cpp +++ b/xbox1/frontend/menu.cpp @@ -36,7 +36,7 @@ int menu_init(void) // Load the rom list if it isn't already loaded if (!g_romList.IsLoaded()) - g_romList.Load(); + g_romList.Build(); // Load the font here g_font.Create(); From e88c6b5cfec6f694e757a3f1fb80fd7c87c85db1 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Tue, 24 Jul 2012 18:16:03 +0200 Subject: [PATCH 36/51] (Xbox 1) Add Griffin-like wrapper file for the RetroLaunch source files --- msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj | 28 ++------------- xbox1/retrolaunch.cpp | 38 +++++++++++++++++++++ 2 files changed, 41 insertions(+), 25 deletions(-) create mode 100644 xbox1/retrolaunch.cpp diff --git a/msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj b/msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj index 1cdfc9bb5f..de75501705 100644 --- a/msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj +++ b/msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj @@ -321,6 +321,9 @@ CompileAs="2"/> + + - - - - - - - - - - - - - - - - . +*/ + +/** + * RetroLaunch 2012 + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. This program 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 this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. To contact the + * authors: Surreal64 CE Team (http://www.emuxtras.net) + */ + +#include "RetroLaunch/Font.cpp" +#include "RetroLaunch/IoSupport.cpp" +#include "RetroLaunch/MenuMain.cpp" +#include "RetroLaunch/MenuManager.cpp" +#include "RetroLaunch/Rom.cpp" +#include "RetroLaunch/RomList.cpp" +#include "RetroLaunch/Surface.cpp" \ No newline at end of file From c29a7e80c90ee3dbc82544f7311a6892a6b36a23 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Tue, 24 Jul 2012 18:35:29 +0200 Subject: [PATCH 37/51] (Xbox 1) Get rid of retrolaunch.cpp wrapper file - put include lines in griffin.c instead --- console/griffin/griffin.c | 7 ++++ msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj | 3 -- xbox1/{ => frontend}/RetroLaunch/Font.cpp | 6 +-- xbox1/{ => frontend}/RetroLaunch/Font.h | 5 --- xbox1/{ => frontend}/RetroLaunch/Global.h | 1 - .../{ => frontend}/RetroLaunch/IoSupport.cpp | 0 xbox1/{ => frontend}/RetroLaunch/IoSupport.h | 0 xbox1/{ => frontend}/RetroLaunch/MenuMain.cpp | 0 xbox1/{ => frontend}/RetroLaunch/MenuMain.h | 0 .../RetroLaunch/MenuManager.cpp | 0 .../{ => frontend}/RetroLaunch/MenuManager.h | 0 xbox1/{ => frontend}/RetroLaunch/Rom.cpp | 0 xbox1/{ => frontend}/RetroLaunch/Rom.h | 0 xbox1/{ => frontend}/RetroLaunch/RomList.cpp | 0 xbox1/{ => frontend}/RetroLaunch/RomList.h | 0 xbox1/{ => frontend}/RetroLaunch/Surface.cpp | 4 +- xbox1/{ => frontend}/RetroLaunch/Surface.h | 0 .../{ => frontend}/RetroLaunch/Undocumented.h | 0 .../{ => frontend}/RetroLaunch/titleimage.bmp | Bin xbox1/frontend/menu.cpp | 10 ++--- xbox1/retrolaunch.cpp | 38 ------------------ xbox1/xdk_d3d8.h | 5 +++ 22 files changed, 21 insertions(+), 58 deletions(-) rename xbox1/{ => frontend}/RetroLaunch/Font.cpp (98%) rename xbox1/{ => frontend}/RetroLaunch/Font.h (94%) rename xbox1/{ => frontend}/RetroLaunch/Global.h (99%) rename xbox1/{ => frontend}/RetroLaunch/IoSupport.cpp (100%) rename xbox1/{ => frontend}/RetroLaunch/IoSupport.h (100%) rename xbox1/{ => frontend}/RetroLaunch/MenuMain.cpp (100%) rename xbox1/{ => frontend}/RetroLaunch/MenuMain.h (100%) rename xbox1/{ => frontend}/RetroLaunch/MenuManager.cpp (100%) rename xbox1/{ => frontend}/RetroLaunch/MenuManager.h (100%) rename xbox1/{ => frontend}/RetroLaunch/Rom.cpp (100%) rename xbox1/{ => frontend}/RetroLaunch/Rom.h (100%) rename xbox1/{ => frontend}/RetroLaunch/RomList.cpp (100%) rename xbox1/{ => frontend}/RetroLaunch/RomList.h (100%) rename xbox1/{ => frontend}/RetroLaunch/Surface.cpp (99%) rename xbox1/{ => frontend}/RetroLaunch/Surface.h (100%) rename xbox1/{ => frontend}/RetroLaunch/Undocumented.h (100%) rename xbox1/{ => frontend}/RetroLaunch/titleimage.bmp (100%) delete mode 100644 xbox1/retrolaunch.cpp diff --git a/console/griffin/griffin.c b/console/griffin/griffin.c index c3c213757e..ecfd7be085 100644 --- a/console/griffin/griffin.c +++ b/console/griffin/griffin.c @@ -261,6 +261,13 @@ MENU #include "../../360/frontend-xdk/menu.cpp" #elif defined(_XBOX1) #include "../../xbox1/frontend/menu.cpp" +#include "../../xbox1/frontend/RetroLaunch/Font.cpp" +#include "../../xbox1/frontend/RetroLaunch/IoSupport.cpp" +#include "../../xbox1/frontend/RetroLaunch/MenuMain.cpp" +#include "../../xbox1/frontend/RetroLaunch/MenuManager.cpp" +#include "../../xbox1/frontend/RetroLaunch/Rom.cpp" +#include "../../xbox1/frontend/RetroLaunch/RomList.cpp" +#include "../../xbox1/frontend/RetroLaunch/Surface.cpp" #elif defined(GEKKO) #include "../../wii/frontend/rgui.c" #include "../../wii/frontend/list.c" diff --git a/msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj b/msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj index de75501705..8d947bc6c6 100644 --- a/msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj +++ b/msvc/RetroArch-Xbox1/RetroArch-Xbox1.vcproj @@ -321,9 +321,6 @@ CompileAs="2"/> - - - enum Align { Left, @@ -48,4 +44,3 @@ private: }; extern Font g_font; -#endif diff --git a/xbox1/RetroLaunch/Global.h b/xbox1/frontend/RetroLaunch/Global.h similarity index 99% rename from xbox1/RetroLaunch/Global.h rename to xbox1/frontend/RetroLaunch/Global.h index 087fd8c68c..4e16968715 100644 --- a/xbox1/RetroLaunch/Global.h +++ b/xbox1/frontend/RetroLaunch/Global.h @@ -29,7 +29,6 @@ #include #include - using namespace std; #define XBUILD "Launcher CE" diff --git a/xbox1/RetroLaunch/IoSupport.cpp b/xbox1/frontend/RetroLaunch/IoSupport.cpp similarity index 100% rename from xbox1/RetroLaunch/IoSupport.cpp rename to xbox1/frontend/RetroLaunch/IoSupport.cpp diff --git a/xbox1/RetroLaunch/IoSupport.h b/xbox1/frontend/RetroLaunch/IoSupport.h similarity index 100% rename from xbox1/RetroLaunch/IoSupport.h rename to xbox1/frontend/RetroLaunch/IoSupport.h diff --git a/xbox1/RetroLaunch/MenuMain.cpp b/xbox1/frontend/RetroLaunch/MenuMain.cpp similarity index 100% rename from xbox1/RetroLaunch/MenuMain.cpp rename to xbox1/frontend/RetroLaunch/MenuMain.cpp diff --git a/xbox1/RetroLaunch/MenuMain.h b/xbox1/frontend/RetroLaunch/MenuMain.h similarity index 100% rename from xbox1/RetroLaunch/MenuMain.h rename to xbox1/frontend/RetroLaunch/MenuMain.h diff --git a/xbox1/RetroLaunch/MenuManager.cpp b/xbox1/frontend/RetroLaunch/MenuManager.cpp similarity index 100% rename from xbox1/RetroLaunch/MenuManager.cpp rename to xbox1/frontend/RetroLaunch/MenuManager.cpp diff --git a/xbox1/RetroLaunch/MenuManager.h b/xbox1/frontend/RetroLaunch/MenuManager.h similarity index 100% rename from xbox1/RetroLaunch/MenuManager.h rename to xbox1/frontend/RetroLaunch/MenuManager.h diff --git a/xbox1/RetroLaunch/Rom.cpp b/xbox1/frontend/RetroLaunch/Rom.cpp similarity index 100% rename from xbox1/RetroLaunch/Rom.cpp rename to xbox1/frontend/RetroLaunch/Rom.cpp diff --git a/xbox1/RetroLaunch/Rom.h b/xbox1/frontend/RetroLaunch/Rom.h similarity index 100% rename from xbox1/RetroLaunch/Rom.h rename to xbox1/frontend/RetroLaunch/Rom.h diff --git a/xbox1/RetroLaunch/RomList.cpp b/xbox1/frontend/RetroLaunch/RomList.cpp similarity index 100% rename from xbox1/RetroLaunch/RomList.cpp rename to xbox1/frontend/RetroLaunch/RomList.cpp diff --git a/xbox1/RetroLaunch/RomList.h b/xbox1/frontend/RetroLaunch/RomList.h similarity index 100% rename from xbox1/RetroLaunch/RomList.h rename to xbox1/frontend/RetroLaunch/RomList.h diff --git a/xbox1/RetroLaunch/Surface.cpp b/xbox1/frontend/RetroLaunch/Surface.cpp similarity index 99% rename from xbox1/RetroLaunch/Surface.cpp rename to xbox1/frontend/RetroLaunch/Surface.cpp index 87ffb917e9..d4be34b64f 100644 --- a/xbox1/RetroLaunch/Surface.cpp +++ b/xbox1/frontend/RetroLaunch/Surface.cpp @@ -17,8 +17,8 @@ #include "Surface.h" -#include "../../general.h" -#include "../xdk_d3d8.h" +#include "../../../general.h" +#include "../../xdk_d3d8.h" CSurface::CSurface() { diff --git a/xbox1/RetroLaunch/Surface.h b/xbox1/frontend/RetroLaunch/Surface.h similarity index 100% rename from xbox1/RetroLaunch/Surface.h rename to xbox1/frontend/RetroLaunch/Surface.h diff --git a/xbox1/RetroLaunch/Undocumented.h b/xbox1/frontend/RetroLaunch/Undocumented.h similarity index 100% rename from xbox1/RetroLaunch/Undocumented.h rename to xbox1/frontend/RetroLaunch/Undocumented.h diff --git a/xbox1/RetroLaunch/titleimage.bmp b/xbox1/frontend/RetroLaunch/titleimage.bmp similarity index 100% rename from xbox1/RetroLaunch/titleimage.bmp rename to xbox1/frontend/RetroLaunch/titleimage.bmp diff --git a/xbox1/frontend/menu.cpp b/xbox1/frontend/menu.cpp index 41c9f49a1d..20ec4efba5 100644 --- a/xbox1/frontend/menu.cpp +++ b/xbox1/frontend/menu.cpp @@ -14,11 +14,11 @@ * If not, see . */ -#include "../../xbox1/RetroLaunch/Global.h" -#include "../../xbox1/RetroLaunch/IoSupport.h" -#include "../../xbox1/RetroLaunch/Font.h" -#include "../../xbox1/RetroLaunch/MenuManager.h" -#include "../../xbox1/RetroLaunch/RomList.h" +#include "RetroLaunch/Global.h" +#include "RetroLaunch/IoSupport.h" +#include "RetroLaunch/Font.h" +#include "RetroLaunch/MenuManager.h" +#include "RetroLaunch/RomList.h" int menu_init(void) { diff --git a/xbox1/retrolaunch.cpp b/xbox1/retrolaunch.cpp deleted file mode 100644 index dd1bf8283f..0000000000 --- a/xbox1/retrolaunch.cpp +++ /dev/null @@ -1,38 +0,0 @@ -/* RetroArch - A frontend for libretro. -* Copyright (C) 2010-2012 - Hans-Kristian Arntzen -* Copyright (C) 2011-2012 - Daniel De Matteis -* -* RetroArch 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. -* -* RetroArch 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 RetroArch. -* If not, see . -*/ - -/** - * RetroLaunch 2012 - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free Software - * Foundation; either version 2 of the License, or (at your option) any later - * version. This program 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 this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. To contact the - * authors: Surreal64 CE Team (http://www.emuxtras.net) - */ - -#include "RetroLaunch/Font.cpp" -#include "RetroLaunch/IoSupport.cpp" -#include "RetroLaunch/MenuMain.cpp" -#include "RetroLaunch/MenuManager.cpp" -#include "RetroLaunch/Rom.cpp" -#include "RetroLaunch/RomList.cpp" -#include "RetroLaunch/Surface.cpp" \ No newline at end of file diff --git a/xbox1/xdk_d3d8.h b/xbox1/xdk_d3d8.h index 7ce1a84c84..a6e867d9e1 100644 --- a/xbox1/xdk_d3d8.h +++ b/xbox1/xdk_d3d8.h @@ -18,6 +18,11 @@ #define _XDK_VIDEO_H #include + +#ifdef _XBOX1 +#define XFONT_TRUETYPE // use true type fonts +#endif + #include #include "../xdk/xdk_defines.h" From 19c611bf427cff3ec54a18229caf657024a87c82 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Tue, 24 Jul 2012 19:58:49 +0200 Subject: [PATCH 38/51] (Xbox 1) Dehardcoded controls --- xbox1/frontend/RetroLaunch/MenuMain.cpp | 13 +++- xbox1/xinput_xbox_input.c | 83 +++++++------------------ 2 files changed, 36 insertions(+), 60 deletions(-) diff --git a/xbox1/frontend/RetroLaunch/MenuMain.cpp b/xbox1/frontend/RetroLaunch/MenuMain.cpp index ba7dc1d869..942a491400 100644 --- a/xbox1/frontend/RetroLaunch/MenuMain.cpp +++ b/xbox1/frontend/RetroLaunch/MenuMain.cpp @@ -115,9 +115,20 @@ void CMenuMain::ProcessInput() uint16_t input_state = 0; input_xinput.poll(NULL); + static const struct retro_keybind *binds[MAX_PLAYERS] = { + g_settings.input.binds[0], + g_settings.input.binds[1], + g_settings.input.binds[2], + g_settings.input.binds[3], + g_settings.input.binds[4], + g_settings.input.binds[5], + g_settings.input.binds[6], + g_settings.input.binds[7], + }; + for (unsigned i = 0; i < RARCH_FIRST_META_KEY; i++) { - input_state |= input_xinput.input_state(NULL, NULL, false, + input_state |= input_xinput.input_state(NULL, binds, false, RETRO_DEVICE_JOYPAD, 0, i) ? (1 << i) : 0; } diff --git a/xbox1/xinput_xbox_input.c b/xbox1/xinput_xbox_input.c index 7947a0aabc..aef3fdd1cf 100644 --- a/xbox1/xinput_xbox_input.c +++ b/xbox1/xinput_xbox_input.c @@ -27,6 +27,7 @@ #include "xinput_xbox_input.h" static XINPUT_STATE state[4]; +static uint64_t real_state[4]; HANDLE gamepads[4]; DWORD dwDeviceMask; bool bInserted[4]; @@ -48,6 +49,7 @@ static void xinput_input_poll(void *data) for (unsigned i = 0; i < 4; i++) { + real_state[i] = 0; // handle removed devices bRemoved[i] = (dwRemovals & (1< DEADZONE) ? XINPUT1_GAMEPAD_DPAD_RIGHT : 0); + real_state[i] |= ((state[i].Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP) || (state[i].Gamepad.sThumbLY > DEADZONE) ? XINPUT1_GAMEPAD_DPAD_UP : 0); + real_state[i] |= ((state[i].Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN)|| (state[i].Gamepad.sThumbLY < -DEADZONE) ? XINPUT1_GAMEPAD_DPAD_DOWN : 0); + real_state[i] |= ((state[i].Gamepad.wButtons & XINPUT_GAMEPAD_START) ? XINPUT1_GAMEPAD_START : 0); + real_state[i] |= ((state[i].Gamepad.wButtons & XINPUT_GAMEPAD_BACK) ? XINPUT1_GAMEPAD_BACK : 0); + real_state[i] |= ((state[i].Gamepad.bAnalogButtons[XINPUT_GAMEPAD_LEFT_TRIGGER]) ? XINPUT1_GAMEPAD_LEFT_TRIGGER : 0); + real_state[i] |= ((state[i].Gamepad.bAnalogButtons[XINPUT_GAMEPAD_RIGHT_TRIGGER]) ? XINPUT1_GAMEPAD_RIGHT_TRIGGER : 0); + real_state[i] |= ((state[i].Gamepad.bAnalogButtons[XINPUT_GAMEPAD_WHITE]) ? XINPUT1_GAMEPAD_WHITE : 0); + real_state[i] |= ((state[i].Gamepad.bAnalogButtons[XINPUT_GAMEPAD_BLACK]) ? XINPUT1_GAMEPAD_BLACK : 0); + real_state[i] |= ((state[i].Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_THUMB) ? XINPUT1_GAMEPAD_LEFT_THUMB : 0); + real_state[i] |= ((state[i].Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_THUMB) ? XINPUT1_GAMEPAD_RIGHT_THUMB : 0); + } } } } @@ -93,65 +114,9 @@ static int16_t xinput_input_state(void *data, const struct retro_keybind **binds { (void)data; unsigned player = port; - DWORD button = binds[player][id].joykey; - int16_t retval = 0; + uint64_t button = binds[player][id].joykey; - //FIXME: Hardcoded binds - switch(id) - { - case RETRO_DEVICE_ID_JOYPAD_A: - retval = (state[player].Gamepad.bAnalogButtons[XINPUT_GAMEPAD_B]) ? 1 : 0; - break; - case RETRO_DEVICE_ID_JOYPAD_B: - retval = (state[player].Gamepad.bAnalogButtons[XINPUT_GAMEPAD_A]) ? 1 : 0; - break; - case RETRO_DEVICE_ID_JOYPAD_X: - retval = (state[player].Gamepad.bAnalogButtons[XINPUT_GAMEPAD_Y]) ? 1 : 0; - break; - case RETRO_DEVICE_ID_JOYPAD_Y: - retval = (state[player].Gamepad.bAnalogButtons[XINPUT_GAMEPAD_X]) ? 1 : 0; - break; - case RETRO_DEVICE_ID_JOYPAD_LEFT: - retval = (state[player].Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT) || (state[player].Gamepad.sThumbLX < -DEADZONE) ? 1 : 0; - break; - case RETRO_DEVICE_ID_JOYPAD_RIGHT: - retval = (state[player].Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT) || (state[player].Gamepad.sThumbLX > DEADZONE) ? 1 : 0; - break; - case RETRO_DEVICE_ID_JOYPAD_UP: - retval = (state[player].Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP) || (state[player].Gamepad.sThumbLY > DEADZONE) ? 1 : 0; - break; - case RETRO_DEVICE_ID_JOYPAD_DOWN: - retval = (state[player].Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN)|| (state[player].Gamepad.sThumbLY < -DEADZONE) ? 1 : 0; - break; - case RETRO_DEVICE_ID_JOYPAD_START: - retval = (state[player].Gamepad.wButtons & XINPUT_GAMEPAD_START) ? 1 : 0; - break; - case RETRO_DEVICE_ID_JOYPAD_SELECT: - retval = (state[player].Gamepad.wButtons & XINPUT_GAMEPAD_BACK) ? 1 : 0; - break; - case RETRO_DEVICE_ID_JOYPAD_L: - retval = (state[player].Gamepad.bAnalogButtons[XINPUT_GAMEPAD_LEFT_TRIGGER]) ? 1 : 0; - break; - case RETRO_DEVICE_ID_JOYPAD_R: - retval = (state[player].Gamepad.bAnalogButtons[XINPUT_GAMEPAD_RIGHT_TRIGGER]) ? 1 : 0; - break; - case RETRO_DEVICE_ID_JOYPAD_L2: - retval = (state[player].Gamepad.bAnalogButtons[XINPUT_GAMEPAD_WHITE]) ? 1 : 0; - break; - case RETRO_DEVICE_ID_JOYPAD_R2: - retval = (state[player].Gamepad.bAnalogButtons[XINPUT_GAMEPAD_BLACK]) ? 1 : 0; - break; - case RETRO_DEVICE_ID_JOYPAD_L3: - retval = (state[player].Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_THUMB) ? 1 : 0; - break; - case RETRO_DEVICE_ID_JOYPAD_R3: - retval = (state[player].Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_THUMB) ? 1 : 0; - break; - default: - break; - } - - return retval; + return (real_state[player] & button) ? 1 : 0; } static void xinput_input_free_input(void *data) From 04e6ef4719dec5a2ae6fd800ac59dc3620aabb8b Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Tue, 24 Jul 2012 19:50:12 +0200 Subject: [PATCH 39/51] (Xbox 1) Change around default keybinds for Xbox 1 --- console/retroarch_console.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/console/retroarch_console.c b/console/retroarch_console.c index b4069c65a0..e6b455dcf7 100644 --- a/console/retroarch_console.c +++ b/console/retroarch_console.c @@ -515,10 +515,17 @@ void rarch_input_set_controls_default (void) rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_RIGHT] = platform_keys[XDK_DEVICE_ID_JOYPAD_RIGHT].joykey; rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_A] = platform_keys[XDK_DEVICE_ID_JOYPAD_B].joykey; rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_X] = platform_keys[XDK_DEVICE_ID_JOYPAD_Y].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_L] = platform_keys[XDK_DEVICE_ID_JOYPAD_LB].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_R] = platform_keys[XDK_DEVICE_ID_JOYPAD_RB].joykey; +#if defined(_XBOX1) + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_L] = platform_keys[XDK_DEVICE_ID_JOYPAD_LEFT_TRIGGER].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_R] = platform_keys[XDK_DEVICE_ID_JOYPAD_RIGHT_TRIGGER].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_L2] = platform_keys[XDK_DEVICE_ID_JOYPAD_LB].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_R2] = platform_keys[XDK_DEVICE_ID_JOYPAD_RB].joykey; +#elif defined(_XBOX360) + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_L] = platform_keys[XDK_DEVICE_ID_JOYPAD_LB].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_R] = platform_keys[XDK_DEVICE_ID_JOYPAD_RB].joykey; rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_L2] = platform_keys[XDK_DEVICE_ID_JOYPAD_LEFT_TRIGGER].joykey; rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_R2] = platform_keys[XDK_DEVICE_ID_JOYPAD_RIGHT_TRIGGER].joykey; +#endif rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_L3] = platform_keys[XDK_DEVICE_ID_LSTICK_THUMB].joykey; rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_R3] = platform_keys[XDK_DEVICE_ID_RSTICK_THUMB].joykey; #endif From eb0b1f932750342927f3b1dc4994ecd5e806666b Mon Sep 17 00:00:00 2001 From: twinaphex Date: Tue, 24 Jul 2012 20:04:42 +0200 Subject: [PATCH 40/51] (Xbox 1) Cleanups to Xinput 1 driver --- xbox1/xinput_xbox_input.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xbox1/xinput_xbox_input.c b/xbox1/xinput_xbox_input.c index aef3fdd1cf..df0a7ab40a 100644 --- a/xbox1/xinput_xbox_input.c +++ b/xbox1/xinput_xbox_input.c @@ -26,13 +26,11 @@ #include "../libretro.h" #include "xinput_xbox_input.h" -static XINPUT_STATE state[4]; static uint64_t real_state[4]; HANDLE gamepads[4]; DWORD dwDeviceMask; bool bInserted[4]; bool bRemoved[4]; -XINPUT_CAPABILITIES caps[4]; #define DEADZONE (16000) @@ -49,6 +47,8 @@ static void xinput_input_poll(void *data) for (unsigned i = 0; i < 4; i++) { + XINPUT_STATE state[4]; + XINPUT_CAPABILITIES caps[4]; real_state[i] = 0; // handle removed devices bRemoved[i] = (dwRemovals & (1< Date: Wed, 25 Jul 2012 14:11:00 +0200 Subject: [PATCH 41/51] (360) Get rid of ifdefs in 360-specific input driver --- 360/xinput_360_input.c | 8 -------- 360/xinput_360_input.h | 2 -- 2 files changed, 10 deletions(-) diff --git a/360/xinput_360_input.c b/360/xinput_360_input.c index 2d6515375c..0345e6c5c6 100644 --- a/360/xinput_360_input.c +++ b/360/xinput_360_input.c @@ -17,9 +17,7 @@ #include #include -#ifdef _XBOX #include -#endif #include "../driver.h" #include "../general.h" @@ -73,7 +71,6 @@ static void xinput_input_free_input(void *data) (void)data; } -#ifdef _XBOX360 #include "../console/retroarch_console.h" void xdk360_input_map_dpad_to_stick(uint32_t map_dpad_enum, uint32_t controller_id) @@ -100,14 +97,11 @@ void xdk360_input_map_dpad_to_stick(uint32_t map_dpad_enum, uint32_t controller_ break; } } -#endif static void* xinput_input_init(void) { -#ifdef _XBOX360 for(unsigned i = 0; i < 4; i++) xdk360_input_map_dpad_to_stick(g_settings.input.dpad_emulation[i], i); -#endif return (void*)-1; } @@ -116,7 +110,6 @@ static bool xinput_input_key_pressed(void *data, int key) { (void)data; bool retval = false; -#ifdef _XBOX360 XINPUT_STATE state; xdk_d3d_video_t *d3d = (xdk_d3d_video_t*)driver.video_data; @@ -163,7 +156,6 @@ static bool xinput_input_key_pressed(void *data, int key) retval = g_console.ingame_menu_enable ? g_console.ingame_menu_enable : g_console.menu_enable; } } -#endif return retval; } diff --git a/360/xinput_360_input.h b/360/xinput_360_input.h index 53efa72f74..229aafb025 100644 --- a/360/xinput_360_input.h +++ b/360/xinput_360_input.h @@ -32,8 +32,6 @@ enum { #define DEADZONE (16000) -#ifdef _XBOX extern void xdk360_input_map_dpad_to_stick(uint32_t map_dpad_enum, uint32_t controller_id); -#endif #endif From 3c1a55dce4826f31cf587052bf2c6c524fd04336 Mon Sep 17 00:00:00 2001 From: freakdave Date: Wed, 25 Jul 2012 14:23:59 +0200 Subject: [PATCH 42/51] (Xbox 1) Fixed rom list/text position in 720p (Xbox 1) Fixed 720p background image problem (loads native 720p image now) --- xbox1/Media/menuMainBG_720p.png | Bin 0 -> 20341 bytes xbox1/frontend/RetroLaunch/MenuMain.cpp | 35 +++++++++++++++++++----- xbox1/frontend/RetroLaunch/MenuMain.h | 4 +++ xbox1/frontend/menu.cpp | 2 +- 4 files changed, 33 insertions(+), 8 deletions(-) create mode 100644 xbox1/Media/menuMainBG_720p.png diff --git a/xbox1/Media/menuMainBG_720p.png b/xbox1/Media/menuMainBG_720p.png new file mode 100644 index 0000000000000000000000000000000000000000..2bd9482cc13556020cdbdeff58ea4eb8e4f4ebe5 GIT binary patch literal 20341 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 literal 0 HcmV?d00001 diff --git a/xbox1/frontend/RetroLaunch/MenuMain.cpp b/xbox1/frontend/RetroLaunch/MenuMain.cpp index 942a491400..eed2cad4f9 100644 --- a/xbox1/frontend/RetroLaunch/MenuMain.cpp +++ b/xbox1/frontend/RetroLaunch/MenuMain.cpp @@ -36,21 +36,38 @@ bool CMenuMain::Create() { RARCH_LOG("CMenuMain::Create()."); + xdk_d3d_video_t *d3d = (xdk_d3d_video_t*)driver.video_data; + + width = d3d->d3dpp.BackBufferWidth; + //height = d3d->d3dpp.BackBufferHeight; + // Title coords with color m_menuMainTitle_x = 305; m_menuMainTitle_y = 30; m_menuMainTitle_c = 0xFFFFFFFF; - // Load background image - m_menuMainBG.Create("D:\\Media\\menuMainBG.png"); m_menuMainBG_x = 0; m_menuMainBG_y = 0; - m_menuMainBG_w = 640; - m_menuMainBG_h = 480; + //m_menuMainBG_w = width; + //m_menuMainBG_h = height; + // Quick hack to properly center the romlist in 720p, + // it might need more work though (font size and rom selector size -> needs more memory) // Init rom list coords - m_menuMainRomListPos_x = 100; - m_menuMainRomListPos_y = 100; + // Load background image + if(width == 640) + { + m_menuMainBG.Create("D:\\Media\\menuMainBG.png"); + m_menuMainRomListPos_x = 100; + m_menuMainRomListPos_y = 100; + } + else if(width == 1280) + { + m_menuMainBG.Create("D:\\Media\\menuMainBG_720p.png"); + m_menuMainRomListPos_x = 400; + m_menuMainRomListPos_y = 150; + } + m_menuMainRomListSpacing = 20; // Load rom selector panel @@ -93,7 +110,11 @@ void CMenuMain::Render() m_menuMainBG.Render(m_menuMainBG_x, m_menuMainBG_y); //Display some text - g_font.Render("Press RSTICK THUMB to exit. Press START and/or A to launch a rom.", 65, 430, 16, XFONT_NORMAL, m_menuMainTitle_c); + //Center the text (hardcoded) + int xpos = width == 640 ? 65 : 400; + int ypos = width == 640 ? 430 : 670; + + g_font.Render("Press RSTICK THUMB to exit. Press START and/or A to launch a rom.", xpos, ypos, 16, XFONT_NORMAL, m_menuMainTitle_c); //Begin with the rom selector panel //FIXME: Width/Height needs to be current Rom texture width/height (or should we just leave it at a fixed size?) diff --git a/xbox1/frontend/RetroLaunch/MenuMain.h b/xbox1/frontend/RetroLaunch/MenuMain.h index d131da2f2e..22c16ebfcc 100644 --- a/xbox1/frontend/RetroLaunch/MenuMain.h +++ b/xbox1/frontend/RetroLaunch/MenuMain.h @@ -73,6 +73,10 @@ int m_romListEndRender; int m_romListSelectedRom; int m_romListOffset; +// Backbuffer width, height +int width; +int height; + }; extern CMenuMain g_menuMain; diff --git a/xbox1/frontend/menu.cpp b/xbox1/frontend/menu.cpp index 20ec4efba5..d16015ae30 100644 --- a/xbox1/frontend/menu.cpp +++ b/xbox1/frontend/menu.cpp @@ -64,7 +64,7 @@ void menu_loop(void) 1.0f, 0); d3d->d3d_render_device->BeginScene(); - d3d->d3d_render_device->SetFlickerFilter(5); + d3d->d3d_render_device->SetFlickerFilter(1); d3d->d3d_render_device->SetSoftDisplayFilter(1); //g_input.GetInput(); From 86067e3aeb5f4871af4c693e3efb4599190b2f79 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Wed, 25 Jul 2012 19:03:01 +0200 Subject: [PATCH 43/51] (RARCH_CONSOLE) Split up rzlib helper functions into separate file --- console/griffin/griffin.c | 5 ++ console/retroarch_console.c | 131 -------------------------------- console/retroarch_console.h | 4 - console/retroarch_rzlib.c | 145 ++++++++++++++++++++++++++++++++++++ console/retroarch_rzlib.h | 26 +++++++ ps3/frontend/menu.c | 4 + 6 files changed, 180 insertions(+), 135 deletions(-) create mode 100644 console/retroarch_rzlib.c create mode 100644 console/retroarch_rzlib.h diff --git a/console/griffin/griffin.c b/console/griffin/griffin.c index ecfd7be085..ce0e65a102 100644 --- a/console/griffin/griffin.c +++ b/console/griffin/griffin.c @@ -22,6 +22,11 @@ CONSOLE EXTENSIONS ============================================================ */ #include "../retroarch_console.c" + +#ifdef HAVE_ZLIB +#include "../retroarch_rzlib.c" +#endif + #include "../console_settings.c" #ifdef HAVE_LIBRETRO_MANAGEMENT diff --git a/console/retroarch_console.c b/console/retroarch_console.c index e6b455dcf7..8417e2d917 100644 --- a/console/retroarch_console.c +++ b/console/retroarch_console.c @@ -32,11 +32,6 @@ #include "../conf/config_file_macros.h" #endif -#ifdef HAVE_ZLIB -#include "rzlib/zlib.h" -#define WRITEBUFFERSIZE (1024 * 512) -#endif - #ifdef _WIN32 #include "../compat/posix_string.h" #endif @@ -105,132 +100,6 @@ void rarch_console_name_from_id(char *name, size_t size) } } -#ifdef HAVE_ZLIB -static int rarch_extract_currentfile_in_zip(unzFile uf) -{ - char filename_inzip[PATH_MAX]; - FILE *fout = NULL; - - unz_file_info file_info; - int err = unzGetCurrentFileInfo(uf, - &file_info, filename_inzip, sizeof(filename_inzip), - NULL, 0, NULL, 0); - - if (err != UNZ_OK) - { - RARCH_ERR("Error %d while trying to get ZIP file information.\n", err); - return err; - } - - size_t size_buf = WRITEBUFFERSIZE; - void *buf = malloc(size_buf); - if (!buf) - { - RARCH_ERR("Error allocating memory for ZIP extract operation.\n"); - return UNZ_INTERNALERROR; - } - - char write_filename[PATH_MAX]; - -#ifdef HAVE_HDD_CACHE_PARTITION - -#if defined(__CELLOS_LV2__) - snprintf(write_filename, sizeof(write_filename), "/dev_hdd1/%s", filename_inzip); -#elif defined(_XBOX) - snprintf(write_filename, sizeof(write_filename), "cache:\\%s", filename_inzip); -#endif - -#endif - - err = unzOpenCurrentFile(uf); - if (err != UNZ_OK) - RARCH_ERR("Error %d while trying to open ZIP file.\n", err); - else - { - /* success */ - fout = fopen(write_filename, "wb"); - - if (!fout) - RARCH_ERR("Error opening %s.\n", write_filename); - } - - if (fout) - { - RARCH_LOG("Extracting: %s..\n", write_filename); - - do - { - err = unzReadCurrentFile(uf, buf, size_buf); - if (err < 0) - { - RARCH_ERR("Error %d while reading from ZIP file.\n", err); - break; - } - - if (err > 0) - { - if (fwrite(buf, err, 1, fout) != 1) - { - RARCH_ERR("Error while extracting file(s) from ZIP.\n"); - err = UNZ_ERRNO; - break; - } - } - } while (err > 0); - - if (fout) - fclose(fout); - } - - if (err == UNZ_OK) - { - err = unzCloseCurrentFile (uf); - if (err != UNZ_OK) - RARCH_ERR("Error %d while trying to close ZIP file.\n", err); - } - else - unzCloseCurrentFile(uf); - - free(buf); - return err; -} - -int rarch_extract_zipfile(const char *zip_path) -{ - unzFile uf = unzOpen(zip_path); - - unz_global_info gi; - int err = unzGetGlobalInfo(uf, &gi); - if (err != UNZ_OK) - RARCH_ERR("Error %d while trying to get ZIP file global info.\n",err); - - for (unsigned i = 0; i < gi.number_entry; i++) - { - if (rarch_extract_currentfile_in_zip(uf) != UNZ_OK) - break; - - if ((i + 1) < gi.number_entry) - { - err = unzGoToNextFile(uf); - if (err != UNZ_OK) - { - RARCH_ERR("Error %d while trying to go to the next file in the ZIP archive.\n",err); - break; - } - } - } - -#ifdef HAVE_HDD_CACHE_PARTITION - if(g_console.info_msg_enable) - rarch_settings_msg(S_MSG_EXTRACTED_ZIPFILE, S_DELAY_180); -#endif - - return 0; -} - -#endif - - /*============================================================ INPUT EXTENSIONS ============================================================ */ diff --git a/console/retroarch_console.h b/console/retroarch_console.h index cb8184cbda..3de981fd1f 100644 --- a/console/retroarch_console.h +++ b/console/retroarch_console.h @@ -170,10 +170,6 @@ const char *rarch_console_get_rom_ext(void); // Transforms a library id to a name suitable as a pathname. void rarch_console_name_from_id(char *name, size_t size); -#ifdef HAVE_ZLIB -int rarch_extract_zipfile(const char *zip_path); -#endif - /*============================================================ INPUT EXTENSIONS ============================================================ */ diff --git a/console/retroarch_rzlib.c b/console/retroarch_rzlib.c new file mode 100644 index 0000000000..97b9facb26 --- /dev/null +++ b/console/retroarch_rzlib.c @@ -0,0 +1,145 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2012 - Hans-Kristian Arntzen + * Copyright (C) 2011-2012 - Daniel De Matteis + * + * RetroArch 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. + * + * RetroArch 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 RetroArch. + * If not, see . + */ + +#include +#include +#include +#include +#include "../boolean.h" + +#include "retroarch_rzlib.h" + +static int rarch_extract_currentfile_in_zip(unzFile uf) +{ + char filename_inzip[PATH_MAX]; + FILE *file_out = NULL; + + unz_file_info file_info; + int err = unzGetCurrentFileInfo(uf, + &file_info, filename_inzip, sizeof(filename_inzip), + NULL, 0, NULL, 0); + + if (err != UNZ_OK) + { + RARCH_ERR("Error %d while trying to get ZIP file information.\n", err); + return err; + } + + size_t size_buf = WRITEBUFFERSIZE; + void *buf = malloc(size_buf); + if (!buf) + { + RARCH_ERR("Error allocating memory for ZIP extract operation.\n"); + return UNZ_INTERNALERROR; + } + + char write_filename[PATH_MAX]; + +#ifdef HAVE_HDD_CACHE_PARTITION + +#if defined(__CELLOS_LV2__) + snprintf(write_filename, sizeof(write_filename), "/dev_hdd1/%s", filename_inzip); +#elif defined(_XBOX) + snprintf(write_filename, sizeof(write_filename), "cache:\\%s", filename_inzip); +#endif + +#endif + + err = unzOpenCurrentFile(uf); + if (err != UNZ_OK) + RARCH_ERR("Error %d while trying to open ZIP file.\n", err); + else + { + /* success */ + file_out = fopen(write_filename, "wb"); + + if (!file_out) + RARCH_ERR("Error opening %s.\n", write_filename); + } + + if (file_out) + { + RARCH_LOG("Extracting: %s..\n", write_filename); + + do + { + err = unzReadCurrentFile(uf, buf, size_buf); + if (err < 0) + { + RARCH_ERR("Error %d while reading from ZIP file.\n", err); + break; + } + + if (err > 0) + { + if (fwrite(buf, err, 1, file_out) != 1) + { + RARCH_ERR("Error while extracting file(s) from ZIP.\n"); + err = UNZ_ERRNO; + break; + } + } + }while (err > 0); + + if (file_out) + fclose(file_out); + } + + if (err == UNZ_OK) + { + err = unzCloseCurrentFile (uf); + if (err != UNZ_OK) + RARCH_ERR("Error %d while trying to close ZIP file.\n", err); + } + else + unzCloseCurrentFile(uf); + + free(buf); + return err; +} + +int rarch_extract_zipfile(const char *zip_path) +{ + unzFile uf = unzOpen(zip_path); + + unz_global_info gi; + int err = unzGetGlobalInfo(uf, &gi); + if (err != UNZ_OK) + RARCH_ERR("Error %d while trying to get ZIP file global info.\n",err); + + for (unsigned i = 0; i < gi.number_entry; i++) + { + if (rarch_extract_currentfile_in_zip(uf) != UNZ_OK) + break; + + if ((i + 1) < gi.number_entry) + { + err = unzGoToNextFile(uf); + if (err != UNZ_OK) + { + RARCH_ERR("Error %d while trying to go to the next file in the ZIP archive.\n",err); + break; + } + } + } + +#ifdef HAVE_HDD_CACHE_PARTITION + if(g_console.info_msg_enable) + rarch_settings_msg(S_MSG_EXTRACTED_ZIPFILE, S_DELAY_180); +#endif + + return 0; +} diff --git a/console/retroarch_rzlib.h b/console/retroarch_rzlib.h new file mode 100644 index 0000000000..440384d10a --- /dev/null +++ b/console/retroarch_rzlib.h @@ -0,0 +1,26 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2012 - Hans-Kristian Arntzen + * Copyright (C) 2011-2012 - Daniel De Matteis + * + * RetroArch 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. + * + * RetroArch 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 RetroArch. + * If not, see . + */ + +#ifndef _RARCH_CONSOLE_RZLIB_H +#define _RARCH_CONSOLE_RZLIB_H + +#include "rzlib/zlib.h" + +#define WRITEBUFFERSIZE (1024 * 512) + +int rarch_extract_zipfile(const char *zip_path); + +#endif diff --git a/ps3/frontend/menu.c b/ps3/frontend/menu.c index 004a13fa79..bc0e559c41 100644 --- a/ps3/frontend/menu.c +++ b/ps3/frontend/menu.c @@ -28,6 +28,10 @@ #include "../../console/retroarch_console.h" +#ifdef HAVE_ZLIB +#include "../../console/retroarch_rzlib.h" +#endif + #include "../../gfx/gl_common.h" #include "../../gfx/gl_font.h" #include "../../gfx/gfx_context.h" From 4ed249fe182064d1e9301652a1ec9697830e463e Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Wed, 25 Jul 2012 19:35:21 +0200 Subject: [PATCH 44/51] (RARCH_CONSOLE) Split up input code into retroarch_console_input.c - beter segregation of input code --- 360/xinput_360_input.c | 37 ++++ console/griffin/griffin.c | 1 + console/retroarch_console.c | 340 ------------------------------ console/retroarch_console.h | 21 -- console/retroarch_console_input.c | 222 +++++++++++++++++++ console/retroarch_console_input.h | 16 ++ ps3/ps3_input.c | 37 ++++ wii/input.c | 34 +++ xbox1/xinput_xbox_input.c | 37 ++++ 9 files changed, 384 insertions(+), 361 deletions(-) create mode 100644 console/retroarch_console_input.c diff --git a/360/xinput_360_input.c b/360/xinput_360_input.c index 0345e6c5c6..71da9458e2 100644 --- a/360/xinput_360_input.c +++ b/360/xinput_360_input.c @@ -27,6 +27,43 @@ static uint64_t state[4]; static unsigned pads_connected; +const struct platform_bind platform_keys[] = { + { XINPUT_GAMEPAD_B, "B button" }, + { XINPUT_GAMEPAD_A, "A button" }, + { XINPUT_GAMEPAD_Y, "Y button" }, + { XINPUT_GAMEPAD_X, "X button" }, + { XINPUT_GAMEPAD_DPAD_UP, "D-Pad Up" }, + { XINPUT_GAMEPAD_DPAD_DOWN, "D-Pad Down" }, + { XINPUT_GAMEPAD_DPAD_LEFT, "D-Pad Left" }, + { XINPUT_GAMEPAD_DPAD_RIGHT, "D-Pad Right" }, + { XINPUT_GAMEPAD_BACK, "Back button" }, + { XINPUT_GAMEPAD_START, "Start button" }, + { XINPUT_GAMEPAD_LEFT_SHOULDER, "Left Shoulder" }, + { XINPUT_GAMEPAD_LEFT_TRIGGER, "Left Trigger" }, + { XINPUT_GAMEPAD_LEFT_THUMB, "Left Thumb" }, + { XINPUT_GAMEPAD_RIGHT_SHOULDER, "Right Shoulder" }, + { XINPUT_GAMEPAD_RIGHT_TRIGGER, "Right Trigger" }, + { XINPUT_GAMEPAD_RIGHT_THUMB, "Right Thumb" }, + { XINPUT_GAMEPAD_LSTICK_LEFT_MASK, "LStick Left" }, + { XINPUT_GAMEPAD_LSTICK_RIGHT_MASK, "LStick Right" }, + { XINPUT_GAMEPAD_LSTICK_UP_MASK, "LStick Up" }, + { XINPUT_GAMEPAD_LSTICK_DOWN_MASK, "LStick Down" }, + { XINPUT_GAMEPAD_DPAD_LEFT | XINPUT_GAMEPAD_LSTICK_LEFT_MASK, "LStick D-Pad Left" }, + { XINPUT_GAMEPAD_DPAD_RIGHT | XINPUT_GAMEPAD_LSTICK_RIGHT_MASK, "LStick D-Pad Right" }, + { XINPUT_GAMEPAD_DPAD_UP | XINPUT_GAMEPAD_LSTICK_UP_MASK, "LStick D-Pad Up" }, + { XINPUT_GAMEPAD_DPAD_DOWN | XINPUT_GAMEPAD_LSTICK_DOWN_MASK, "LStick D-Pad Down" }, + { XINPUT_GAMEPAD_RSTICK_LEFT_MASK, "RStick Left" }, + { XINPUT_GAMEPAD_RSTICK_RIGHT_MASK, "RStick Right" }, + { XINPUT_GAMEPAD_RSTICK_UP_MASK, "RStick Up" }, + { XINPUT_GAMEPAD_RSTICK_DOWN_MASK, "RStick Down" }, + { XINPUT_GAMEPAD_DPAD_LEFT | XINPUT_GAMEPAD_RSTICK_LEFT_MASK, "RStick D-Pad Left" }, + { XINPUT_GAMEPAD_DPAD_RIGHT | XINPUT_GAMEPAD_RSTICK_RIGHT_MASK, "RStick D-Pad Right" }, + { XINPUT_GAMEPAD_DPAD_UP | XINPUT_GAMEPAD_RSTICK_UP_MASK, "RStick D-Pad Up" }, + { XINPUT_GAMEPAD_DPAD_DOWN | XINPUT_GAMEPAD_RSTICK_DOWN_MASK, "RStick D-Pad Down" }, +}; + +const unsigned int platform_keys_size = sizeof(platform_keys); + static void xinput_input_poll(void *data) { (void)data; diff --git a/console/griffin/griffin.c b/console/griffin/griffin.c index ce0e65a102..0b5c308209 100644 --- a/console/griffin/griffin.c +++ b/console/griffin/griffin.c @@ -22,6 +22,7 @@ CONSOLE EXTENSIONS ============================================================ */ #include "../retroarch_console.c" +#include "../retroarch_console_input.c" #ifdef HAVE_ZLIB #include "../retroarch_rzlib.c" diff --git a/console/retroarch_console.c b/console/retroarch_console.c index 8417e2d917..ff51d33af2 100644 --- a/console/retroarch_console.c +++ b/console/retroarch_console.c @@ -100,346 +100,6 @@ void rarch_console_name_from_id(char *name, size_t size) } } -/*============================================================ - INPUT EXTENSIONS -============================================================ */ - -#include "retroarch_console_input.h" - -struct platform_bind -{ - uint64_t joykey; - const char *label; -}; - -uint64_t rarch_default_keybind_lut[RARCH_FIRST_META_KEY]; - -char rarch_default_libretro_keybind_name_lut[RARCH_FIRST_META_KEY][256] = { - "RetroPad Button B", /* RETRO_DEVICE_ID_JOYPAD_B */ - "RetroPad Button Y", /* RETRO_DEVICE_ID_JOYPAD_Y */ - "RetroPad Button Select", /* RETRO_DEVICE_ID_JOYPAD_SELECT */ - "RetroPad Button Start", /* RETRO_DEVICE_ID_JOYPAD_START */ - "RetroPad D-Pad Up", /* RETRO_DEVICE_ID_JOYPAD_UP */ - "RetroPad D-Pad Down", /* RETRO_DEVICE_ID_JOYPAD_DOWN */ - "RetroPad D-Pad Left", /* RETRO_DEVICE_ID_JOYPAD_LEFT */ - "RetroPad D-Pad Right", /* RETRO_DEVICE_ID_JOYPAD_RIGHT */ - "RetroPad Button A", /* RETRO_DEVICE_ID_JOYPAD_A */ - "RetroPad Button X", /* RETRO_DEVICE_ID_JOYPAD_X */ - "RetroPad Button L1", /* RETRO_DEVICE_ID_JOYPAD_L */ - "RetroPad Button R1", /* RETRO_DEVICE_ID_JOYPAD_R */ - "RetroPad Button L2", /* RETRO_DEVICE_ID_JOYPAD_L2 */ - "RetroPad Button R2", /* RETRO_DEVICE_ID_JOYPAD_R2 */ - "RetroPad Button L3", /* RETRO_DEVICE_ID_JOYPAD_L3 */ - "RetroPad Button R3", /* RETRO_DEVICE_ID_JOYPAD_R3 */ -}; - -#if defined(__CELLOS_LV2__) -static const struct platform_bind platform_keys[] = { - { CTRL_CIRCLE_MASK, "Circle button" }, - { CTRL_CROSS_MASK, "Cross button" }, - { CTRL_TRIANGLE_MASK, "Triangle button" }, - { CTRL_SQUARE_MASK, "Square button" }, - { CTRL_UP_MASK, "D-Pad Up" }, - { CTRL_DOWN_MASK, "D-Pad Down" }, - { CTRL_LEFT_MASK, "D-Pad Left" }, - { CTRL_RIGHT_MASK, "D-Pad Right" }, - { CTRL_SELECT_MASK, "Select button" }, - { CTRL_START_MASK, "Start button" }, - { CTRL_L1_MASK, "L1 button" }, - { CTRL_L2_MASK, "L2 button" }, - { CTRL_L3_MASK, "L3 button" }, - { CTRL_R1_MASK, "R1 button" }, - { CTRL_R2_MASK, "R2 button" }, - { CTRL_R3_MASK, "R3 button" }, - { CTRL_LSTICK_LEFT_MASK, "LStick Left" }, - { CTRL_LSTICK_RIGHT_MASK, "LStick Right" }, - { CTRL_LSTICK_UP_MASK, "LStick Up" }, - { CTRL_LSTICK_DOWN_MASK, "LStick Down" }, - { CTRL_LEFT_MASK | CTRL_LSTICK_LEFT_MASK, "LStick D-Pad Left" }, - { CTRL_RIGHT_MASK | CTRL_LSTICK_RIGHT_MASK, "LStick D-Pad Right" }, - { CTRL_UP_MASK | CTRL_LSTICK_UP_MASK, "LStick D-Pad Up" }, - { CTRL_DOWN_MASK | CTRL_LSTICK_DOWN_MASK, "LStick D-Pad Down" }, - { CTRL_RSTICK_LEFT_MASK, "RStick Left" }, - { CTRL_RSTICK_RIGHT_MASK, "RStick Right" }, - { CTRL_RSTICK_UP_MASK, "RStick Up" }, - { CTRL_RSTICK_DOWN_MASK, "RStick Down" }, - { CTRL_LEFT_MASK | CTRL_RSTICK_LEFT_MASK, "RStick D-Pad Left" }, - { CTRL_RIGHT_MASK | CTRL_RSTICK_RIGHT_MASK, "RStick D-Pad Right" }, - { CTRL_UP_MASK | CTRL_RSTICK_UP_MASK, "RStick D-Pad Up" }, - { CTRL_DOWN_MASK | CTRL_RSTICK_DOWN_MASK, "RStick D-Pad Down" }, -}; -#elif defined(_XBOX360) -static const struct platform_bind platform_keys[] = { - { XINPUT_GAMEPAD_B, "B button" }, - { XINPUT_GAMEPAD_A, "A button" }, - { XINPUT_GAMEPAD_Y, "Y button" }, - { XINPUT_GAMEPAD_X, "X button" }, - { XINPUT_GAMEPAD_DPAD_UP, "D-Pad Up" }, - { XINPUT_GAMEPAD_DPAD_DOWN, "D-Pad Down" }, - { XINPUT_GAMEPAD_DPAD_LEFT, "D-Pad Left" }, - { XINPUT_GAMEPAD_DPAD_RIGHT, "D-Pad Right" }, - { XINPUT_GAMEPAD_BACK, "Back button" }, - { XINPUT_GAMEPAD_START, "Start button" }, - { XINPUT_GAMEPAD_LEFT_SHOULDER, "Left Shoulder" }, - { XINPUT_GAMEPAD_LEFT_TRIGGER, "Left Trigger" }, - { XINPUT_GAMEPAD_LEFT_THUMB, "Left Thumb" }, - { XINPUT_GAMEPAD_RIGHT_SHOULDER, "Right Shoulder" }, - { XINPUT_GAMEPAD_RIGHT_TRIGGER, "Right Trigger" }, - { XINPUT_GAMEPAD_RIGHT_THUMB, "Right Thumb" }, - { XINPUT_GAMEPAD_LSTICK_LEFT_MASK, "LStick Left" }, - { XINPUT_GAMEPAD_LSTICK_RIGHT_MASK, "LStick Right" }, - { XINPUT_GAMEPAD_LSTICK_UP_MASK, "LStick Up" }, - { XINPUT_GAMEPAD_LSTICK_DOWN_MASK, "LStick Down" }, - { XINPUT_GAMEPAD_DPAD_LEFT | XINPUT_GAMEPAD_LSTICK_LEFT_MASK, "LStick D-Pad Left" }, - { XINPUT_GAMEPAD_DPAD_RIGHT | XINPUT_GAMEPAD_LSTICK_RIGHT_MASK, "LStick D-Pad Right" }, - { XINPUT_GAMEPAD_DPAD_UP | XINPUT_GAMEPAD_LSTICK_UP_MASK, "LStick D-Pad Up" }, - { XINPUT_GAMEPAD_DPAD_DOWN | XINPUT_GAMEPAD_LSTICK_DOWN_MASK, "LStick D-Pad Down" }, - { XINPUT_GAMEPAD_RSTICK_LEFT_MASK, "RStick Left" }, - { XINPUT_GAMEPAD_RSTICK_RIGHT_MASK, "RStick Right" }, - { XINPUT_GAMEPAD_RSTICK_UP_MASK, "RStick Up" }, - { XINPUT_GAMEPAD_RSTICK_DOWN_MASK, "RStick Down" }, - { XINPUT_GAMEPAD_DPAD_LEFT | XINPUT_GAMEPAD_RSTICK_LEFT_MASK, "RStick D-Pad Left" }, - { XINPUT_GAMEPAD_DPAD_RIGHT | XINPUT_GAMEPAD_RSTICK_RIGHT_MASK, "RStick D-Pad Right" }, - { XINPUT_GAMEPAD_DPAD_UP | XINPUT_GAMEPAD_RSTICK_UP_MASK, "RStick D-Pad Up" }, - { XINPUT_GAMEPAD_DPAD_DOWN | XINPUT_GAMEPAD_RSTICK_DOWN_MASK, "RStick D-Pad Down" }, -}; -#elif defined(_XBOX1) -static const struct platform_bind platform_keys[] = { - { XINPUT1_GAMEPAD_B, "B button" }, - { XINPUT1_GAMEPAD_A, "A button" }, - { XINPUT1_GAMEPAD_Y, "Y button" }, - { XINPUT1_GAMEPAD_X, "X button" }, - { XINPUT1_GAMEPAD_DPAD_UP, "D-Pad Up" }, - { XINPUT1_GAMEPAD_DPAD_DOWN, "D-Pad Down" }, - { XINPUT1_GAMEPAD_DPAD_LEFT, "D-Pad Left" }, - { XINPUT1_GAMEPAD_DPAD_RIGHT, "D-Pad Right" }, - { XINPUT1_GAMEPAD_BACK, "Back button" }, - { XINPUT1_GAMEPAD_START, "Start button" }, - { XINPUT1_GAMEPAD_WHITE, "White button" }, - { XINPUT1_GAMEPAD_LEFT_TRIGGER, "Left Trigger" }, - { XINPUT1_GAMEPAD_LEFT_THUMB, "Left Thumb" }, - { XINPUT1_GAMEPAD_BLACK, "Black button" }, - { XINPUT1_GAMEPAD_RIGHT_TRIGGER, "Right Trigger" }, - { XINPUT1_GAMEPAD_RIGHT_THUMB, "Right Thumb" }, - { XINPUT1_GAMEPAD_LSTICK_LEFT_MASK, "LStick Left" }, - { XINPUT1_GAMEPAD_LSTICK_RIGHT_MASK, "LStick Right" }, - { XINPUT1_GAMEPAD_LSTICK_UP_MASK, "LStick Up" }, - { XINPUT1_GAMEPAD_LSTICK_DOWN_MASK, "LStick Down" }, - { XINPUT1_GAMEPAD_DPAD_LEFT | XINPUT1_GAMEPAD_LSTICK_LEFT_MASK, "LStick D-Pad Left" }, - { XINPUT1_GAMEPAD_DPAD_RIGHT | XINPUT1_GAMEPAD_LSTICK_RIGHT_MASK, "LStick D-Pad Right" }, - { XINPUT1_GAMEPAD_DPAD_UP | XINPUT1_GAMEPAD_LSTICK_UP_MASK, "LStick D-Pad Up" }, - { XINPUT1_GAMEPAD_DPAD_DOWN | XINPUT1_GAMEPAD_LSTICK_DOWN_MASK, "LStick D-Pad Down" }, - { XINPUT1_GAMEPAD_RSTICK_LEFT_MASK, "RStick Left" }, - { XINPUT1_GAMEPAD_RSTICK_RIGHT_MASK, "RStick Right" }, - { XINPUT1_GAMEPAD_RSTICK_UP_MASK, "RStick Up" }, - { XINPUT1_GAMEPAD_RSTICK_DOWN_MASK, "RStick Down" }, - { XINPUT1_GAMEPAD_DPAD_LEFT | XINPUT1_GAMEPAD_RSTICK_LEFT_MASK, "RStick D-Pad Left" }, - { XINPUT1_GAMEPAD_DPAD_RIGHT | XINPUT1_GAMEPAD_RSTICK_RIGHT_MASK, "RStick D-Pad Right" }, - { XINPUT1_GAMEPAD_DPAD_UP | XINPUT1_GAMEPAD_RSTICK_UP_MASK, "RStick D-Pad Up" }, - { XINPUT1_GAMEPAD_DPAD_DOWN | XINPUT1_GAMEPAD_RSTICK_DOWN_MASK, "RStick D-Pad Down" }, -}; -#elif defined(GEKKO) -static const struct platform_bind platform_keys[] = { - { PAD_BUTTON_B, "(NGC) B button" }, - { PAD_BUTTON_A, "(NGC) A button" }, - { PAD_BUTTON_Y, "(NGC) Y button" }, - { PAD_BUTTON_X, "(NGC) X button" }, - { PAD_BUTTON_UP, "(NGC) D-Pad Up" }, - { PAD_BUTTON_DOWN, "(NGC) D-Pad Down" }, - { PAD_BUTTON_LEFT, "(NGC) D-Pad Left" }, - { PAD_BUTTON_RIGHT, "(NGC) D-Pad Right" }, - { PAD_TRIGGER_Z, "(NGC) Z trigger" }, - { PAD_BUTTON_START, "(NGC) Start button" }, - { PAD_TRIGGER_L, "(NGC) Left Trigger" }, - { PAD_TRIGGER_R, "(NGC) Right Trigger" }, -#ifdef HW_RVL - { WPAD_CLASSIC_BUTTON_B, "(Wii Classici) B button" }, - { WPAD_CLASSIC_BUTTON_A, "(Wii Classic) A button" }, - { WPAD_CLASSIC_BUTTON_Y, "(Wii Classic) Y button" }, - { WPAD_CLASSIC_BUTTON_X, "(Wii Classic) X button" }, - { WPAD_CLASSIC_BUTTON_UP, "(Wii Classic) D-Pad Up" }, - { WPAD_CLASSIC_BUTTON_DOWN, "(Wii Classic) D-Pad Down" }, - { WPAD_CLASSIC_BUTTON_LEFT, "(Wii Classic) D-Pad Left" }, - { WPAD_CLASSIC_BUTTON_RIGHT, "(Wii Classic) D-Pad Right" }, - { WPAD_CLASSIC_BUTTON_MINUS, "(Wii Classic) Select/Minus button" }, - { WPAD_CLASSIC_BUTTON_PLUS, "(Wii Classic) Start/Plus button" }, - { WPAD_CLASSIC_BUTTON_HOME, "(Wii Classic) Home button" }, - { WPAD_CLASSIC_BUTTON_FULL_L, "(Wii Classic) Left Trigger" }, - { WPAD_CLASSIC_BUTTON_FULL_R, "(Wii Classic) Right Trigger" }, - { WPAD_CLASSIC_BUTTON_ZL, "(Wii Classic) ZL button" }, - { WPAD_CLASSIC_BUTTON_ZR, "(Wii Classic) ZR button" }, -#endif -}; -#endif - -#ifdef HAVE_DEFAULT_RETROPAD_INPUT - -uint64_t rarch_input_find_previous_platform_key(uint64_t joykey) -{ - size_t arr_size = sizeof(platform_keys) / sizeof(platform_keys[0]); - - if (platform_keys[0].joykey == joykey) - return joykey; - - for (size_t i = 1; i < arr_size; i++) - { - if (platform_keys[i].joykey == joykey) - return platform_keys[i - 1].joykey; - } - - return NO_BTN; -} - -uint64_t rarch_input_find_next_platform_key(uint64_t joykey) -{ - size_t arr_size = sizeof(platform_keys) / sizeof(platform_keys[0]); - if (platform_keys[arr_size - 1].joykey == joykey) - return joykey; - - for (size_t i = 0; i < arr_size - 1; i++) - { - if (platform_keys[i].joykey == joykey) - return platform_keys[i + 1].joykey; - } - - return NO_BTN; -} - -const char *rarch_input_find_platform_key_label(uint64_t joykey) -{ - if (joykey == NO_BTN) - return "No button"; - - size_t arr_size = sizeof(platform_keys) / sizeof(platform_keys[0]); - for (size_t i = 0; i < arr_size; i++) - { - if (platform_keys[i].joykey == joykey) - return platform_keys[i].label; - } - - return "Unknown"; -} - - -void rarch_input_set_keybind(unsigned player, unsigned keybind_action, uint64_t default_retro_joypad_id) -{ - uint64_t *key = &g_settings.input.binds[player][default_retro_joypad_id].joykey; - - switch (keybind_action) - { - case KEYBIND_DECREMENT: - *key = rarch_input_find_previous_platform_key(*key); - break; - - case KEYBIND_INCREMENT: - *key = rarch_input_find_next_platform_key(*key); - break; - - case KEYBIND_DEFAULT: - *key = rarch_default_keybind_lut[default_retro_joypad_id]; - break; - - default: - break; - } -} - -void rarch_input_set_default_keybinds(unsigned player) -{ - for (unsigned i = 0; i < RARCH_FIRST_META_KEY; i++) - { - g_settings.input.binds[player][i].id = i; - g_settings.input.binds[player][i].joykey = rarch_default_keybind_lut[i]; - } - g_settings.input.dpad_emulation[player] = DPAD_EMULATION_LSTICK; -} - -void rarch_input_set_controls_default (void) -{ -#if defined(__CELLOS_LV2__) - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_B] = platform_keys[PS3_DEVICE_ID_JOYPAD_CROSS].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_Y] = platform_keys[PS3_DEVICE_ID_JOYPAD_SQUARE].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_SELECT] = platform_keys[PS3_DEVICE_ID_JOYPAD_SELECT].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_START] = platform_keys[PS3_DEVICE_ID_JOYPAD_START].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_UP] = platform_keys[PS3_DEVICE_ID_JOYPAD_UP].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_DOWN] = platform_keys[PS3_DEVICE_ID_JOYPAD_DOWN].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_LEFT] = platform_keys[PS3_DEVICE_ID_JOYPAD_LEFT].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_RIGHT] = platform_keys[PS3_DEVICE_ID_JOYPAD_RIGHT].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_A] = platform_keys[PS3_DEVICE_ID_JOYPAD_CIRCLE].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_X] = platform_keys[PS3_DEVICE_ID_JOYPAD_TRIANGLE].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_L] = platform_keys[PS3_DEVICE_ID_JOYPAD_L1].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_R] = platform_keys[PS3_DEVICE_ID_JOYPAD_R1].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_R2] = platform_keys[PS3_DEVICE_ID_JOYPAD_R2].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_R3] = platform_keys[PS3_DEVICE_ID_JOYPAD_R3].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_L2] = platform_keys[PS3_DEVICE_ID_JOYPAD_L2].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_L3] = platform_keys[PS3_DEVICE_ID_JOYPAD_L3].joykey; -#elif defined(_XBOX) - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_B] = platform_keys[XDK_DEVICE_ID_JOYPAD_A].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_Y] = platform_keys[XDK_DEVICE_ID_JOYPAD_X].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_SELECT] = platform_keys[XDK_DEVICE_ID_JOYPAD_BACK].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_START] = platform_keys[XDK_DEVICE_ID_JOYPAD_START].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_UP] = platform_keys[XDK_DEVICE_ID_JOYPAD_UP].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_DOWN] = platform_keys[XDK_DEVICE_ID_JOYPAD_DOWN].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_LEFT] = platform_keys[XDK_DEVICE_ID_JOYPAD_LEFT].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_RIGHT] = platform_keys[XDK_DEVICE_ID_JOYPAD_RIGHT].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_A] = platform_keys[XDK_DEVICE_ID_JOYPAD_B].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_X] = platform_keys[XDK_DEVICE_ID_JOYPAD_Y].joykey; -#if defined(_XBOX1) - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_L] = platform_keys[XDK_DEVICE_ID_JOYPAD_LEFT_TRIGGER].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_R] = platform_keys[XDK_DEVICE_ID_JOYPAD_RIGHT_TRIGGER].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_L2] = platform_keys[XDK_DEVICE_ID_JOYPAD_LB].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_R2] = platform_keys[XDK_DEVICE_ID_JOYPAD_RB].joykey; -#elif defined(_XBOX360) - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_L] = platform_keys[XDK_DEVICE_ID_JOYPAD_LB].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_R] = platform_keys[XDK_DEVICE_ID_JOYPAD_RB].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_L2] = platform_keys[XDK_DEVICE_ID_JOYPAD_LEFT_TRIGGER].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_R2] = platform_keys[XDK_DEVICE_ID_JOYPAD_RIGHT_TRIGGER].joykey; -#endif - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_L3] = platform_keys[XDK_DEVICE_ID_LSTICK_THUMB].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_R3] = platform_keys[XDK_DEVICE_ID_RSTICK_THUMB].joykey; -#endif - for(uint32_t x = 0; x < MAX_PLAYERS; x++) - rarch_input_set_default_keybinds(x); -} - -const char *rarch_input_get_default_keybind_name(unsigned id) -{ - return rarch_default_libretro_keybind_name_lut[id]; -} - -#endif - -void rarch_input_set_default_keybind_names_for_emulator(void) -{ - struct retro_system_info info; -#ifdef ANDROID - pretro_get_system_info(&info); -#else - retro_get_system_info(&info); -#endif - const char *id = info.library_name ? info.library_name : "Unknown"; - - // Genesis Plus GX/Next - if (strstr(id, "Genesis Plus GX")) - { - strlcpy(rarch_default_libretro_keybind_name_lut[RETRO_DEVICE_ID_JOYPAD_B], - "B button", sizeof(rarch_default_libretro_keybind_name_lut[RETRO_DEVICE_ID_JOYPAD_B])); - strlcpy(rarch_default_libretro_keybind_name_lut[RETRO_DEVICE_ID_JOYPAD_A], - "C button", sizeof(rarch_default_libretro_keybind_name_lut[RETRO_DEVICE_ID_JOYPAD_A])); - strlcpy(rarch_default_libretro_keybind_name_lut[RETRO_DEVICE_ID_JOYPAD_X], - "Y button", sizeof(rarch_default_libretro_keybind_name_lut[RETRO_DEVICE_ID_JOYPAD_X])); - strlcpy(rarch_default_libretro_keybind_name_lut[RETRO_DEVICE_ID_JOYPAD_Y], - "A button", sizeof(rarch_default_libretro_keybind_name_lut[RETRO_DEVICE_ID_JOYPAD_Y])); - strlcpy(rarch_default_libretro_keybind_name_lut[RETRO_DEVICE_ID_JOYPAD_L], - "X button", sizeof(rarch_default_libretro_keybind_name_lut[RETRO_DEVICE_ID_JOYPAD_L])); - strlcpy(rarch_default_libretro_keybind_name_lut[RETRO_DEVICE_ID_JOYPAD_R], - "Z button", sizeof(rarch_default_libretro_keybind_name_lut[RETRO_DEVICE_ID_JOYPAD_R])); - strlcpy(rarch_default_libretro_keybind_name_lut[RETRO_DEVICE_ID_JOYPAD_SELECT], - "Mode button", sizeof(rarch_default_libretro_keybind_name_lut[RETRO_DEVICE_ID_JOYPAD_SELECT])); - } -} - - /*============================================================ VIDEO EXTENSIONS ============================================================ */ diff --git a/console/retroarch_console.h b/console/retroarch_console.h index 3de981fd1f..4de103b1af 100644 --- a/console/retroarch_console.h +++ b/console/retroarch_console.h @@ -170,27 +170,6 @@ const char *rarch_console_get_rom_ext(void); // Transforms a library id to a name suitable as a pathname. void rarch_console_name_from_id(char *name, size_t size); -/*============================================================ - INPUT EXTENSIONS -============================================================ */ - -#ifdef HAVE_DEFAULT_RETROPAD_INPUT -const char *rarch_input_find_platform_key_label(uint64_t joykey); -uint64_t rarch_input_find_previous_platform_key(uint64_t joykey); -uint64_t rarch_input_find_next_platform_key(uint64_t joykey); - -// Sets custom default keybind names (some systems emulated by the emulator -// will need different keybind names for buttons, etc.) -void rarch_input_set_default_keybind_names_for_emulator(void); -void rarch_input_set_default_keybinds(unsigned player); - -void rarch_input_set_keybind(unsigned player, unsigned keybind_action, uint64_t default_retro_joypad_id); - -void rarch_input_set_controls_default (void); -const char *rarch_input_get_default_keybind_name (unsigned id); -#endif - - /*============================================================ RetroArch ============================================================ */ diff --git a/console/retroarch_console_input.c b/console/retroarch_console_input.c new file mode 100644 index 0000000000..3ac556add0 --- /dev/null +++ b/console/retroarch_console_input.c @@ -0,0 +1,222 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2012 - Hans-Kristian Arntzen + * Copyright (C) 2011-2012 - Daniel De Matteis + * + * RetroArch 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. + * + * RetroArch 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 RetroArch. + * If not, see . + */ + +#include +#include +#include +#include +#include "../boolean.h" +#include "retroarch_console_input.h" + +struct platform_bind +{ + uint64_t joykey; + const char *label; +}; + +uint64_t rarch_default_keybind_lut[RARCH_FIRST_META_KEY]; + +char rarch_default_libretro_keybind_name_lut[RARCH_FIRST_META_KEY][256] = { + "RetroPad Button B", /* RETRO_DEVICE_ID_JOYPAD_B */ + "RetroPad Button Y", /* RETRO_DEVICE_ID_JOYPAD_Y */ + "RetroPad Button Select", /* RETRO_DEVICE_ID_JOYPAD_SELECT */ + "RetroPad Button Start", /* RETRO_DEVICE_ID_JOYPAD_START */ + "RetroPad D-Pad Up", /* RETRO_DEVICE_ID_JOYPAD_UP */ + "RetroPad D-Pad Down", /* RETRO_DEVICE_ID_JOYPAD_DOWN */ + "RetroPad D-Pad Left", /* RETRO_DEVICE_ID_JOYPAD_LEFT */ + "RetroPad D-Pad Right", /* RETRO_DEVICE_ID_JOYPAD_RIGHT */ + "RetroPad Button A", /* RETRO_DEVICE_ID_JOYPAD_A */ + "RetroPad Button X", /* RETRO_DEVICE_ID_JOYPAD_X */ + "RetroPad Button L1", /* RETRO_DEVICE_ID_JOYPAD_L */ + "RetroPad Button R1", /* RETRO_DEVICE_ID_JOYPAD_R */ + "RetroPad Button L2", /* RETRO_DEVICE_ID_JOYPAD_L2 */ + "RetroPad Button R2", /* RETRO_DEVICE_ID_JOYPAD_R2 */ + "RetroPad Button L3", /* RETRO_DEVICE_ID_JOYPAD_L3 */ + "RetroPad Button R3", /* RETRO_DEVICE_ID_JOYPAD_R3 */ +}; + +#ifdef HAVE_DEFAULT_RETROPAD_INPUT + +extern const struct platform_bind platform_keys[]; +extern const unsigned int platform_keys_size; + +uint64_t rarch_input_find_previous_platform_key(uint64_t joykey) +{ + size_t arr_size = platform_keys_size / sizeof(platform_keys[0]); + + if (platform_keys[0].joykey == joykey) + return joykey; + + for (size_t i = 1; i < arr_size; i++) + { + if (platform_keys[i].joykey == joykey) + return platform_keys[i - 1].joykey; + } + + return NO_BTN; +} + +uint64_t rarch_input_find_next_platform_key(uint64_t joykey) +{ + size_t arr_size = platform_keys_size / sizeof(platform_keys[0]); + + if (platform_keys[arr_size - 1].joykey == joykey) + return joykey; + + for (size_t i = 0; i < arr_size - 1; i++) + { + if (platform_keys[i].joykey == joykey) + return platform_keys[i + 1].joykey; + } + + return NO_BTN; +} + +const char *rarch_input_find_platform_key_label(uint64_t joykey) +{ + if (joykey == NO_BTN) + return "No button"; + + size_t arr_size = platform_keys_size / sizeof(platform_keys[0]); + for (size_t i = 0; i < arr_size; i++) + { + if (platform_keys[i].joykey == joykey) + return platform_keys[i].label; + } + + return "Unknown"; +} + + +void rarch_input_set_keybind(unsigned player, unsigned keybind_action, uint64_t default_retro_joypad_id) +{ + uint64_t *key = &g_settings.input.binds[player][default_retro_joypad_id].joykey; + + switch (keybind_action) + { + case KEYBIND_DECREMENT: + *key = rarch_input_find_previous_platform_key(*key); + break; + + case KEYBIND_INCREMENT: + *key = rarch_input_find_next_platform_key(*key); + break; + + case KEYBIND_DEFAULT: + *key = rarch_default_keybind_lut[default_retro_joypad_id]; + break; + + default: + break; + } +} + +void rarch_input_set_default_keybinds(unsigned player) +{ + for (unsigned i = 0; i < RARCH_FIRST_META_KEY; i++) + { + g_settings.input.binds[player][i].id = i; + g_settings.input.binds[player][i].joykey = rarch_default_keybind_lut[i]; + } + g_settings.input.dpad_emulation[player] = DPAD_EMULATION_LSTICK; +} + +void rarch_input_set_controls_default (void) +{ +#if defined(__CELLOS_LV2__) + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_B] = platform_keys[PS3_DEVICE_ID_JOYPAD_CROSS].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_Y] = platform_keys[PS3_DEVICE_ID_JOYPAD_SQUARE].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_SELECT] = platform_keys[PS3_DEVICE_ID_JOYPAD_SELECT].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_START] = platform_keys[PS3_DEVICE_ID_JOYPAD_START].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_UP] = platform_keys[PS3_DEVICE_ID_JOYPAD_UP].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_DOWN] = platform_keys[PS3_DEVICE_ID_JOYPAD_DOWN].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_LEFT] = platform_keys[PS3_DEVICE_ID_JOYPAD_LEFT].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_RIGHT] = platform_keys[PS3_DEVICE_ID_JOYPAD_RIGHT].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_A] = platform_keys[PS3_DEVICE_ID_JOYPAD_CIRCLE].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_X] = platform_keys[PS3_DEVICE_ID_JOYPAD_TRIANGLE].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_L] = platform_keys[PS3_DEVICE_ID_JOYPAD_L1].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_R] = platform_keys[PS3_DEVICE_ID_JOYPAD_R1].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_R2] = platform_keys[PS3_DEVICE_ID_JOYPAD_R2].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_R3] = platform_keys[PS3_DEVICE_ID_JOYPAD_R3].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_L2] = platform_keys[PS3_DEVICE_ID_JOYPAD_L2].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_L3] = platform_keys[PS3_DEVICE_ID_JOYPAD_L3].joykey; +#elif defined(_XBOX) + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_B] = platform_keys[XDK_DEVICE_ID_JOYPAD_A].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_Y] = platform_keys[XDK_DEVICE_ID_JOYPAD_X].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_SELECT] = platform_keys[XDK_DEVICE_ID_JOYPAD_BACK].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_START] = platform_keys[XDK_DEVICE_ID_JOYPAD_START].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_UP] = platform_keys[XDK_DEVICE_ID_JOYPAD_UP].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_DOWN] = platform_keys[XDK_DEVICE_ID_JOYPAD_DOWN].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_LEFT] = platform_keys[XDK_DEVICE_ID_JOYPAD_LEFT].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_RIGHT] = platform_keys[XDK_DEVICE_ID_JOYPAD_RIGHT].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_A] = platform_keys[XDK_DEVICE_ID_JOYPAD_B].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_X] = platform_keys[XDK_DEVICE_ID_JOYPAD_Y].joykey; +#if defined(_XBOX1) + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_L] = platform_keys[XDK_DEVICE_ID_JOYPAD_LEFT_TRIGGER].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_R] = platform_keys[XDK_DEVICE_ID_JOYPAD_RIGHT_TRIGGER].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_L2] = platform_keys[XDK_DEVICE_ID_JOYPAD_LB].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_R2] = platform_keys[XDK_DEVICE_ID_JOYPAD_RB].joykey; +#elif defined(_XBOX360) + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_L] = platform_keys[XDK_DEVICE_ID_JOYPAD_LB].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_R] = platform_keys[XDK_DEVICE_ID_JOYPAD_RB].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_L2] = platform_keys[XDK_DEVICE_ID_JOYPAD_LEFT_TRIGGER].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_R2] = platform_keys[XDK_DEVICE_ID_JOYPAD_RIGHT_TRIGGER].joykey; +#endif + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_L3] = platform_keys[XDK_DEVICE_ID_LSTICK_THUMB].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_R3] = platform_keys[XDK_DEVICE_ID_RSTICK_THUMB].joykey; +#endif + for(uint32_t x = 0; x < MAX_PLAYERS; x++) + rarch_input_set_default_keybinds(x); +} + +const char *rarch_input_get_default_keybind_name(unsigned id) +{ + return rarch_default_libretro_keybind_name_lut[id]; +} + +#endif + +/* TODO: Hackish, try to do this in a cleaner, more extensible and less hardcoded way */ + +void rarch_input_set_default_keybind_names_for_emulator(void) +{ + struct retro_system_info info; +#ifdef ANDROID + pretro_get_system_info(&info); +#else + retro_get_system_info(&info); +#endif + const char *id = info.library_name ? info.library_name : "Unknown"; + + // Genesis Plus GX/Next + if (strstr(id, "Genesis Plus GX")) + { + strlcpy(rarch_default_libretro_keybind_name_lut[RETRO_DEVICE_ID_JOYPAD_B], + "B button", sizeof(rarch_default_libretro_keybind_name_lut[RETRO_DEVICE_ID_JOYPAD_B])); + strlcpy(rarch_default_libretro_keybind_name_lut[RETRO_DEVICE_ID_JOYPAD_A], + "C button", sizeof(rarch_default_libretro_keybind_name_lut[RETRO_DEVICE_ID_JOYPAD_A])); + strlcpy(rarch_default_libretro_keybind_name_lut[RETRO_DEVICE_ID_JOYPAD_X], + "Y button", sizeof(rarch_default_libretro_keybind_name_lut[RETRO_DEVICE_ID_JOYPAD_X])); + strlcpy(rarch_default_libretro_keybind_name_lut[RETRO_DEVICE_ID_JOYPAD_Y], + "A button", sizeof(rarch_default_libretro_keybind_name_lut[RETRO_DEVICE_ID_JOYPAD_Y])); + strlcpy(rarch_default_libretro_keybind_name_lut[RETRO_DEVICE_ID_JOYPAD_L], + "X button", sizeof(rarch_default_libretro_keybind_name_lut[RETRO_DEVICE_ID_JOYPAD_L])); + strlcpy(rarch_default_libretro_keybind_name_lut[RETRO_DEVICE_ID_JOYPAD_R], + "Z button", sizeof(rarch_default_libretro_keybind_name_lut[RETRO_DEVICE_ID_JOYPAD_R])); + strlcpy(rarch_default_libretro_keybind_name_lut[RETRO_DEVICE_ID_JOYPAD_SELECT], + "Mode button", sizeof(rarch_default_libretro_keybind_name_lut[RETRO_DEVICE_ID_JOYPAD_SELECT])); + } +} diff --git a/console/retroarch_console_input.h b/console/retroarch_console_input.h index bf4af5ad86..206c2ca76f 100644 --- a/console/retroarch_console_input.h +++ b/console/retroarch_console_input.h @@ -138,4 +138,20 @@ enum xdk_device_id extern uint64_t rarch_default_keybind_lut[RARCH_FIRST_META_KEY]; extern char rarch_default_libretro_keybind_name_lut[RARCH_FIRST_META_KEY][256]; +#ifdef HAVE_DEFAULT_RETROPAD_INPUT +const char *rarch_input_find_platform_key_label(uint64_t joykey); +uint64_t rarch_input_find_previous_platform_key(uint64_t joykey); +uint64_t rarch_input_find_next_platform_key(uint64_t joykey); + +// Sets custom default keybind names (some systems emulated by the emulator +// will need different keybind names for buttons, etc.) +void rarch_input_set_default_keybind_names_for_emulator(void); +void rarch_input_set_default_keybinds(unsigned player); + +void rarch_input_set_keybind(unsigned player, unsigned keybind_action, uint64_t default_retro_joypad_id); + +void rarch_input_set_controls_default (void); +const char *rarch_input_get_default_keybind_name (unsigned id); +#endif + #endif diff --git a/ps3/ps3_input.c b/ps3/ps3_input.c index 24b1511367..232063661c 100644 --- a/ps3/ps3_input.c +++ b/ps3/ps3_input.c @@ -97,6 +97,43 @@ CellMouseData ps3_mouse_input_poll_device(uint32_t id) #define MAP(x) (x & 0xFF) +const struct platform_bind platform_keys[] = { + { CTRL_CIRCLE_MASK, "Circle button" }, + { CTRL_CROSS_MASK, "Cross button" }, + { CTRL_TRIANGLE_MASK, "Triangle button" }, + { CTRL_SQUARE_MASK, "Square button" }, + { CTRL_UP_MASK, "D-Pad Up" }, + { CTRL_DOWN_MASK, "D-Pad Down" }, + { CTRL_LEFT_MASK, "D-Pad Left" }, + { CTRL_RIGHT_MASK, "D-Pad Right" }, + { CTRL_SELECT_MASK, "Select button" }, + { CTRL_START_MASK, "Start button" }, + { CTRL_L1_MASK, "L1 button" }, + { CTRL_L2_MASK, "L2 button" }, + { CTRL_L3_MASK, "L3 button" }, + { CTRL_R1_MASK, "R1 button" }, + { CTRL_R2_MASK, "R2 button" }, + { CTRL_R3_MASK, "R3 button" }, + { CTRL_LSTICK_LEFT_MASK, "LStick Left" }, + { CTRL_LSTICK_RIGHT_MASK, "LStick Right" }, + { CTRL_LSTICK_UP_MASK, "LStick Up" }, + { CTRL_LSTICK_DOWN_MASK, "LStick Down" }, + { CTRL_LEFT_MASK | CTRL_LSTICK_LEFT_MASK, "LStick D-Pad Left" }, + { CTRL_RIGHT_MASK | CTRL_LSTICK_RIGHT_MASK, "LStick D-Pad Right" }, + { CTRL_UP_MASK | CTRL_LSTICK_UP_MASK, "LStick D-Pad Up" }, + { CTRL_DOWN_MASK | CTRL_LSTICK_DOWN_MASK, "LStick D-Pad Down" }, + { CTRL_RSTICK_LEFT_MASK, "RStick Left" }, + { CTRL_RSTICK_RIGHT_MASK, "RStick Right" }, + { CTRL_RSTICK_UP_MASK, "RStick Up" }, + { CTRL_RSTICK_DOWN_MASK, "RStick Down" }, + { CTRL_LEFT_MASK | CTRL_RSTICK_LEFT_MASK, "RStick D-Pad Left" }, + { CTRL_RIGHT_MASK | CTRL_RSTICK_RIGHT_MASK, "RStick D-Pad Right" }, + { CTRL_UP_MASK | CTRL_RSTICK_UP_MASK, "RStick D-Pad Up" }, + { CTRL_DOWN_MASK | CTRL_RSTICK_DOWN_MASK, "RStick D-Pad Down" }, +}; + +const unsigned int platform_keys_size = sizeof(platform_keys); + static uint64_t state[MAX_PADS]; static unsigned pads_connected; #ifdef HAVE_MOUSE diff --git a/wii/input.c b/wii/input.c index f1a4ca8a52..6fe63fc4a0 100644 --- a/wii/input.c +++ b/wii/input.c @@ -30,6 +30,40 @@ static bool pad_state[5][RARCH_FIRST_META_KEY]; /* Gamecube pads */ static bool wpad_state[5][RARCH_FIRST_META_KEY]; /* Wii Classic pads */ #endif +const struct platform_bind platform_keys[] = { + { PAD_BUTTON_B, "(NGC) B button" }, + { PAD_BUTTON_A, "(NGC) A button" }, + { PAD_BUTTON_Y, "(NGC) Y button" }, + { PAD_BUTTON_X, "(NGC) X button" }, + { PAD_BUTTON_UP, "(NGC) D-Pad Up" }, + { PAD_BUTTON_DOWN, "(NGC) D-Pad Down" }, + { PAD_BUTTON_LEFT, "(NGC) D-Pad Left" }, + { PAD_BUTTON_RIGHT, "(NGC) D-Pad Right" }, + { PAD_TRIGGER_Z, "(NGC) Z trigger" }, + { PAD_BUTTON_START, "(NGC) Start button" }, + { PAD_TRIGGER_L, "(NGC) Left Trigger" }, + { PAD_TRIGGER_R, "(NGC) Right Trigger" }, +#ifdef HW_RVL + { WPAD_CLASSIC_BUTTON_B, "(Wii Classici) B button" }, + { WPAD_CLASSIC_BUTTON_A, "(Wii Classic) A button" }, + { WPAD_CLASSIC_BUTTON_Y, "(Wii Classic) Y button" }, + { WPAD_CLASSIC_BUTTON_X, "(Wii Classic) X button" }, + { WPAD_CLASSIC_BUTTON_UP, "(Wii Classic) D-Pad Up" }, + { WPAD_CLASSIC_BUTTON_DOWN, "(Wii Classic) D-Pad Down" }, + { WPAD_CLASSIC_BUTTON_LEFT, "(Wii Classic) D-Pad Left" }, + { WPAD_CLASSIC_BUTTON_RIGHT, "(Wii Classic) D-Pad Right" }, + { WPAD_CLASSIC_BUTTON_MINUS, "(Wii Classic) Select/Minus button" }, + { WPAD_CLASSIC_BUTTON_PLUS, "(Wii Classic) Start/Plus button" }, + { WPAD_CLASSIC_BUTTON_HOME, "(Wii Classic) Home button" }, + { WPAD_CLASSIC_BUTTON_FULL_L, "(Wii Classic) Left Trigger" }, + { WPAD_CLASSIC_BUTTON_FULL_R, "(Wii Classic) Right Trigger" }, + { WPAD_CLASSIC_BUTTON_ZL, "(Wii Classic) ZL button" }, + { WPAD_CLASSIC_BUTTON_ZR, "(Wii Classic) ZR button" }, +#endif +}; + +const unsigned int platform_keys_size = sizeof(platform_keys); + static bool g_quit; static int16_t wii_input_state(void *data, const struct retro_keybind **binds, diff --git a/xbox1/xinput_xbox_input.c b/xbox1/xinput_xbox_input.c index df0a7ab40a..5510a7163d 100644 --- a/xbox1/xinput_xbox_input.c +++ b/xbox1/xinput_xbox_input.c @@ -32,6 +32,43 @@ DWORD dwDeviceMask; bool bInserted[4]; bool bRemoved[4]; +const struct platform_bind platform_keys[] = { + { XINPUT1_GAMEPAD_B, "B button" }, + { XINPUT1_GAMEPAD_A, "A button" }, + { XINPUT1_GAMEPAD_Y, "Y button" }, + { XINPUT1_GAMEPAD_X, "X button" }, + { XINPUT1_GAMEPAD_DPAD_UP, "D-Pad Up" }, + { XINPUT1_GAMEPAD_DPAD_DOWN, "D-Pad Down" }, + { XINPUT1_GAMEPAD_DPAD_LEFT, "D-Pad Left" }, + { XINPUT1_GAMEPAD_DPAD_RIGHT, "D-Pad Right" }, + { XINPUT1_GAMEPAD_BACK, "Back button" }, + { XINPUT1_GAMEPAD_START, "Start button" }, + { XINPUT1_GAMEPAD_WHITE, "White button" }, + { XINPUT1_GAMEPAD_LEFT_TRIGGER, "Left Trigger" }, + { XINPUT1_GAMEPAD_LEFT_THUMB, "Left Thumb" }, + { XINPUT1_GAMEPAD_BLACK, "Black button" }, + { XINPUT1_GAMEPAD_RIGHT_TRIGGER, "Right Trigger" }, + { XINPUT1_GAMEPAD_RIGHT_THUMB, "Right Thumb" }, + { XINPUT1_GAMEPAD_LSTICK_LEFT_MASK, "LStick Left" }, + { XINPUT1_GAMEPAD_LSTICK_RIGHT_MASK, "LStick Right" }, + { XINPUT1_GAMEPAD_LSTICK_UP_MASK, "LStick Up" }, + { XINPUT1_GAMEPAD_LSTICK_DOWN_MASK, "LStick Down" }, + { XINPUT1_GAMEPAD_DPAD_LEFT | XINPUT1_GAMEPAD_LSTICK_LEFT_MASK, "LStick D-Pad Left" }, + { XINPUT1_GAMEPAD_DPAD_RIGHT | XINPUT1_GAMEPAD_LSTICK_RIGHT_MASK, "LStick D-Pad Right" }, + { XINPUT1_GAMEPAD_DPAD_UP | XINPUT1_GAMEPAD_LSTICK_UP_MASK, "LStick D-Pad Up" }, + { XINPUT1_GAMEPAD_DPAD_DOWN | XINPUT1_GAMEPAD_LSTICK_DOWN_MASK, "LStick D-Pad Down" }, + { XINPUT1_GAMEPAD_RSTICK_LEFT_MASK, "RStick Left" }, + { XINPUT1_GAMEPAD_RSTICK_RIGHT_MASK, "RStick Right" }, + { XINPUT1_GAMEPAD_RSTICK_UP_MASK, "RStick Up" }, + { XINPUT1_GAMEPAD_RSTICK_DOWN_MASK, "RStick Down" }, + { XINPUT1_GAMEPAD_DPAD_LEFT | XINPUT1_GAMEPAD_RSTICK_LEFT_MASK, "RStick D-Pad Left" }, + { XINPUT1_GAMEPAD_DPAD_RIGHT | XINPUT1_GAMEPAD_RSTICK_RIGHT_MASK, "RStick D-Pad Right" }, + { XINPUT1_GAMEPAD_DPAD_UP | XINPUT1_GAMEPAD_RSTICK_UP_MASK, "RStick D-Pad Up" }, + { XINPUT1_GAMEPAD_DPAD_DOWN | XINPUT1_GAMEPAD_RSTICK_DOWN_MASK, "RStick D-Pad Down" }, +}; + +const unsigned int platform_keys_size = sizeof(platform_keys); + #define DEADZONE (16000) static unsigned pads_connected; From 811abcf6122b0c42849b61553ac9daed95aaf08a Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Wed, 25 Jul 2012 21:02:01 +0200 Subject: [PATCH 45/51] (RARCH_CONSOLE) Further Input rewrite for console ports --- 360/xinput_360_input.c | 28 +++++++++ 360/xinput_360_input.h | 38 ++++++++++++ console/console_settings.c | 4 +- console/console_settings.h | 2 +- console/libretro_mgmt.c | 4 +- console/libretro_mgmt.h | 3 +- console/retroarch_console_input.c | 46 +-------------- console/retroarch_console_input.h | 96 +------------------------------ driver.h | 3 + input/null.c | 5 ++ ps3/frontend/main.c | 4 +- ps3/ps3_input.c | 21 +++++++ ps3/ps3_input.h | 38 ++++++++++++ wii/input.c | 6 +- xbox1/xinput_xbox_input.c | 28 +++++++++ xbox1/xinput_xbox_input.h | 38 ++++++++++++ xdk/frontend/main.c | 4 +- 17 files changed, 219 insertions(+), 149 deletions(-) diff --git a/360/xinput_360_input.c b/360/xinput_360_input.c index 71da9458e2..7b9b6aed62 100644 --- a/360/xinput_360_input.c +++ b/360/xinput_360_input.c @@ -197,6 +197,33 @@ static bool xinput_input_key_pressed(void *data, int key) return retval; } +static void xinput_set_default_keybind_lut(void) +{ + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_B] = platform_keys[XDK_DEVICE_ID_JOYPAD_A].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_Y] = platform_keys[XDK_DEVICE_ID_JOYPAD_X].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_SELECT] = platform_keys[XDK_DEVICE_ID_JOYPAD_BACK].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_START] = platform_keys[XDK_DEVICE_ID_JOYPAD_START].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_UP] = platform_keys[XDK_DEVICE_ID_JOYPAD_UP].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_DOWN] = platform_keys[XDK_DEVICE_ID_JOYPAD_DOWN].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_LEFT] = platform_keys[XDK_DEVICE_ID_JOYPAD_LEFT].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_RIGHT] = platform_keys[XDK_DEVICE_ID_JOYPAD_RIGHT].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_A] = platform_keys[XDK_DEVICE_ID_JOYPAD_B].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_X] = platform_keys[XDK_DEVICE_ID_JOYPAD_Y].joykey; +#if defined(_XBOX1) + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_L] = platform_keys[XDK_DEVICE_ID_JOYPAD_LEFT_TRIGGER].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_R] = platform_keys[XDK_DEVICE_ID_JOYPAD_RIGHT_TRIGGER].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_L2] = platform_keys[XDK_DEVICE_ID_JOYPAD_LB].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_R2] = platform_keys[XDK_DEVICE_ID_JOYPAD_RB].joykey; +#elif defined(_XBOX360) + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_L] = platform_keys[XDK_DEVICE_ID_JOYPAD_LB].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_R] = platform_keys[XDK_DEVICE_ID_JOYPAD_RB].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_L2] = platform_keys[XDK_DEVICE_ID_JOYPAD_LEFT_TRIGGER].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_R2] = platform_keys[XDK_DEVICE_ID_JOYPAD_RIGHT_TRIGGER].joykey; +#endif + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_L3] = platform_keys[XDK_DEVICE_ID_LSTICK_THUMB].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_R3] = platform_keys[XDK_DEVICE_ID_RSTICK_THUMB].joykey; +} + const input_driver_t input_xinput = { xinput_input_init, @@ -204,5 +231,6 @@ const input_driver_t input_xinput = xinput_input_state, xinput_input_key_pressed, xinput_input_free_input, + xinput_set_default_keybind_lut, "xinput" }; diff --git a/360/xinput_360_input.h b/360/xinput_360_input.h index 229aafb025..1c83129cd7 100644 --- a/360/xinput_360_input.h +++ b/360/xinput_360_input.h @@ -30,6 +30,44 @@ enum { XINPUT_GAMEPAD_RIGHT_TRIGGER = 1 << 25 }; +enum xdk_device_id +{ + XDK_DEVICE_ID_JOYPAD_B = 0, + XDK_DEVICE_ID_JOYPAD_A, + XDK_DEVICE_ID_JOYPAD_Y, + XDK_DEVICE_ID_JOYPAD_X, + XDK_DEVICE_ID_JOYPAD_UP, + XDK_DEVICE_ID_JOYPAD_DOWN, + XDK_DEVICE_ID_JOYPAD_LEFT, + XDK_DEVICE_ID_JOYPAD_RIGHT, + XDK_DEVICE_ID_JOYPAD_BACK, + XDK_DEVICE_ID_JOYPAD_START, + XDK_DEVICE_ID_JOYPAD_LB, + XDK_DEVICE_ID_JOYPAD_LEFT_TRIGGER, + XDK_DEVICE_ID_LSTICK_THUMB, + XDK_DEVICE_ID_JOYPAD_RB, + XDK_DEVICE_ID_JOYPAD_RIGHT_TRIGGER, + XDK_DEVICE_ID_RSTICK_THUMB, + XDK_DEVICE_ID_LSTICK_LEFT, + XDK_DEVICE_ID_LSTICK_RIGHT, + XDK_DEVICE_ID_LSTICK_UP, + XDK_DEVICE_ID_LSTICK_DOWN, + XDK_DEVICE_ID_LSTICK_LEFT_DPAD, + XDK_DEVICE_ID_LSTICK_RIGHT_DPAD, + XDK_DEVICE_ID_LSTICK_UP_DPAD, + XDK_DEVICE_ID_LSTICK_DOWN_DPAD, + XDK_DEVICE_ID_RSTICK_LEFT, + XDK_DEVICE_ID_RSTICK_RIGHT, + XDK_DEVICE_ID_RSTICK_UP, + XDK_DEVICE_ID_RSTICK_DOWN, + XDK_DEVICE_ID_RSTICK_LEFT_DPAD, + XDK_DEVICE_ID_RSTICK_RIGHT_DPAD, + XDK_DEVICE_ID_RSTICK_UP_DPAD, + XDK_DEVICE_ID_RSTICK_DOWN_DPAD, + + RARCH_LAST_PLATFORM_KEY +}; + #define DEADZONE (16000) extern void xdk360_input_map_dpad_to_stick(uint32_t map_dpad_enum, uint32_t controller_id); diff --git a/console/console_settings.c b/console/console_settings.c index d494e40611..8d5fe67323 100644 --- a/console/console_settings.c +++ b/console/console_settings.c @@ -296,7 +296,7 @@ void rarch_settings_create_menu_item_label(char * str, unsigned setting, size_t } } -void rarch_settings_set_default (void) +void rarch_settings_set_default (const input_driver_t *input) { // g_settings g_settings.rewind_enable = false; @@ -323,7 +323,7 @@ void rarch_settings_set_default (void) g_settings.video.msg_pos_y = 0.90f; g_settings.video.aspect_ratio = -1.0f; - rarch_input_set_controls_default(); + rarch_input_set_controls_default(input); // g_console g_console.block_config_read = true; diff --git a/console/console_settings.h b/console/console_settings.h index a7022cfe32..fa0affb200 100644 --- a/console/console_settings.h +++ b/console/console_settings.h @@ -105,7 +105,7 @@ enum void rarch_settings_change(unsigned setting); void rarch_settings_default(unsigned setting); void rarch_settings_msg(unsigned setting, unsigned delay); -void rarch_settings_set_default (void); +void rarch_settings_set_default (const input_driver_t *input); void rarch_settings_create_menu_item_label(char * str, unsigned setting, size_t size); void rarch_settings_create_menu_item_label_w(wchar_t *strwbuf, unsigned setting, size_t size); diff --git a/console/libretro_mgmt.c b/console/libretro_mgmt.c index 3dd0ef9958..3362be5ff5 100644 --- a/console/libretro_mgmt.c +++ b/console/libretro_mgmt.c @@ -140,7 +140,7 @@ end: dir_list_free(dir_list); } -void rarch_configure_libretro(const char *path_prefix, const char * extension) +void rarch_configure_libretro(const input_driver_t *input, const char *path_prefix, const char * extension) { char full_path[1024]; snprintf(full_path, sizeof(full_path), "%sCORE%s", path_prefix, extension); @@ -148,7 +148,7 @@ void rarch_configure_libretro(const char *path_prefix, const char * extension) bool find_libretro_file = rarch_configure_libretro_core(full_path, path_prefix, path_prefix, default_paths.config_file, extension); - rarch_settings_set_default(); + rarch_settings_set_default(input); rarch_config_load(default_paths.config_file, path_prefix, extension, find_libretro_file); init_libretro_sym(); } diff --git a/console/libretro_mgmt.h b/console/libretro_mgmt.h index 936f31106b..e7713f07eb 100644 --- a/console/libretro_mgmt.h +++ b/console/libretro_mgmt.h @@ -18,6 +18,7 @@ #define LIBRETRO_MGMT_H__ #include "../boolean.h" +#include "../driver.h" enum { @@ -30,6 +31,6 @@ enum void rarch_manage_libretro_set_first_file(char *first_file, size_t size_of_first_file, const char *libretro_path, const char * exe_ext); bool rarch_configure_libretro_core(const char *full_path, const char *tmp_path, const char *libretro_path, const char *config_path, const char *extension); -void rarch_configure_libretro(const char *path_prefix, const char * extension); +void rarch_configure_libretro(const input_driver_t *input, const char *path_prefix, const char * extension); #endif diff --git a/console/retroarch_console_input.c b/console/retroarch_console_input.c index 3ac556add0..a86977449a 100644 --- a/console/retroarch_console_input.c +++ b/console/retroarch_console_input.c @@ -134,50 +134,10 @@ void rarch_input_set_default_keybinds(unsigned player) g_settings.input.dpad_emulation[player] = DPAD_EMULATION_LSTICK; } -void rarch_input_set_controls_default (void) +void rarch_input_set_controls_default (const input_driver_t *input) { -#if defined(__CELLOS_LV2__) - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_B] = platform_keys[PS3_DEVICE_ID_JOYPAD_CROSS].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_Y] = platform_keys[PS3_DEVICE_ID_JOYPAD_SQUARE].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_SELECT] = platform_keys[PS3_DEVICE_ID_JOYPAD_SELECT].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_START] = platform_keys[PS3_DEVICE_ID_JOYPAD_START].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_UP] = platform_keys[PS3_DEVICE_ID_JOYPAD_UP].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_DOWN] = platform_keys[PS3_DEVICE_ID_JOYPAD_DOWN].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_LEFT] = platform_keys[PS3_DEVICE_ID_JOYPAD_LEFT].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_RIGHT] = platform_keys[PS3_DEVICE_ID_JOYPAD_RIGHT].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_A] = platform_keys[PS3_DEVICE_ID_JOYPAD_CIRCLE].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_X] = platform_keys[PS3_DEVICE_ID_JOYPAD_TRIANGLE].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_L] = platform_keys[PS3_DEVICE_ID_JOYPAD_L1].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_R] = platform_keys[PS3_DEVICE_ID_JOYPAD_R1].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_R2] = platform_keys[PS3_DEVICE_ID_JOYPAD_R2].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_R3] = platform_keys[PS3_DEVICE_ID_JOYPAD_R3].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_L2] = platform_keys[PS3_DEVICE_ID_JOYPAD_L2].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_L3] = platform_keys[PS3_DEVICE_ID_JOYPAD_L3].joykey; -#elif defined(_XBOX) - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_B] = platform_keys[XDK_DEVICE_ID_JOYPAD_A].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_Y] = platform_keys[XDK_DEVICE_ID_JOYPAD_X].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_SELECT] = platform_keys[XDK_DEVICE_ID_JOYPAD_BACK].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_START] = platform_keys[XDK_DEVICE_ID_JOYPAD_START].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_UP] = platform_keys[XDK_DEVICE_ID_JOYPAD_UP].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_DOWN] = platform_keys[XDK_DEVICE_ID_JOYPAD_DOWN].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_LEFT] = platform_keys[XDK_DEVICE_ID_JOYPAD_LEFT].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_RIGHT] = platform_keys[XDK_DEVICE_ID_JOYPAD_RIGHT].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_A] = platform_keys[XDK_DEVICE_ID_JOYPAD_B].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_X] = platform_keys[XDK_DEVICE_ID_JOYPAD_Y].joykey; -#if defined(_XBOX1) - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_L] = platform_keys[XDK_DEVICE_ID_JOYPAD_LEFT_TRIGGER].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_R] = platform_keys[XDK_DEVICE_ID_JOYPAD_RIGHT_TRIGGER].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_L2] = platform_keys[XDK_DEVICE_ID_JOYPAD_LB].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_R2] = platform_keys[XDK_DEVICE_ID_JOYPAD_RB].joykey; -#elif defined(_XBOX360) - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_L] = platform_keys[XDK_DEVICE_ID_JOYPAD_LB].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_R] = platform_keys[XDK_DEVICE_ID_JOYPAD_RB].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_L2] = platform_keys[XDK_DEVICE_ID_JOYPAD_LEFT_TRIGGER].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_R2] = platform_keys[XDK_DEVICE_ID_JOYPAD_RIGHT_TRIGGER].joykey; -#endif - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_L3] = platform_keys[XDK_DEVICE_ID_LSTICK_THUMB].joykey; - rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_R3] = platform_keys[XDK_DEVICE_ID_RSTICK_THUMB].joykey; -#endif + input->set_default_keybind_lut(); + for(uint32_t x = 0; x < MAX_PLAYERS; x++) rarch_input_set_default_keybinds(x); } diff --git a/console/retroarch_console_input.h b/console/retroarch_console_input.h index 206c2ca76f..3063bf57a8 100644 --- a/console/retroarch_console_input.h +++ b/console/retroarch_console_input.h @@ -41,100 +41,6 @@ enum DPAD_EMULATION_RSTICK }; -#ifdef _XBOX360 -#include "../360/xinput_360_input.h" -#endif - -#if defined(__CELLOS_LV2__) -#include "../ps3/ps3_input.h" -enum ps3_device_id -{ - PS3_DEVICE_ID_JOYPAD_CIRCLE = 0, - PS3_DEVICE_ID_JOYPAD_CROSS, - PS3_DEVICE_ID_JOYPAD_TRIANGLE, - PS3_DEVICE_ID_JOYPAD_SQUARE, - PS3_DEVICE_ID_JOYPAD_UP, - PS3_DEVICE_ID_JOYPAD_DOWN, - PS3_DEVICE_ID_JOYPAD_LEFT, - PS3_DEVICE_ID_JOYPAD_RIGHT, - PS3_DEVICE_ID_JOYPAD_SELECT, - PS3_DEVICE_ID_JOYPAD_START, - PS3_DEVICE_ID_JOYPAD_L1, - PS3_DEVICE_ID_JOYPAD_L2, - PS3_DEVICE_ID_JOYPAD_L3, - PS3_DEVICE_ID_JOYPAD_R1, - PS3_DEVICE_ID_JOYPAD_R2, - PS3_DEVICE_ID_JOYPAD_R3, - PS3_DEVICE_ID_LSTICK_LEFT, - PS3_DEVICE_ID_LSTICK_RIGHT, - PS3_DEVICE_ID_LSTICK_UP, - PS3_DEVICE_ID_LSTICK_DOWN, - PS3_DEVICE_ID_LSTICK_LEFT_DPAD, - PS3_DEVICE_ID_LSTICK_RIGHT_DPAD, - PS3_DEVICE_ID_LSTICK_UP_DPAD, - PS3_DEVICE_ID_LSTICK_DOWN_DPAD, - PS3_DEVICE_ID_RSTICK_LEFT, - PS3_DEVICE_ID_RSTICK_RIGHT, - PS3_DEVICE_ID_RSTICK_UP, - PS3_DEVICE_ID_RSTICK_DOWN, - PS3_DEVICE_ID_RSTICK_LEFT_DPAD, - PS3_DEVICE_ID_RSTICK_RIGHT_DPAD, - PS3_DEVICE_ID_RSTICK_UP_DPAD, - PS3_DEVICE_ID_RSTICK_DOWN_DPAD, - - RARCH_LAST_PLATFORM_KEY -}; - -#elif defined(_XBOX) - -enum xdk_device_id -{ - XDK_DEVICE_ID_JOYPAD_B = 0, - XDK_DEVICE_ID_JOYPAD_A, - XDK_DEVICE_ID_JOYPAD_Y, - XDK_DEVICE_ID_JOYPAD_X, - XDK_DEVICE_ID_JOYPAD_UP, - XDK_DEVICE_ID_JOYPAD_DOWN, - XDK_DEVICE_ID_JOYPAD_LEFT, - XDK_DEVICE_ID_JOYPAD_RIGHT, - XDK_DEVICE_ID_JOYPAD_BACK, - XDK_DEVICE_ID_JOYPAD_START, - XDK_DEVICE_ID_JOYPAD_LB, - XDK_DEVICE_ID_JOYPAD_LEFT_TRIGGER, - XDK_DEVICE_ID_LSTICK_THUMB, - XDK_DEVICE_ID_JOYPAD_RB, - XDK_DEVICE_ID_JOYPAD_RIGHT_TRIGGER, - XDK_DEVICE_ID_RSTICK_THUMB, - XDK_DEVICE_ID_LSTICK_LEFT, - XDK_DEVICE_ID_LSTICK_RIGHT, - XDK_DEVICE_ID_LSTICK_UP, - XDK_DEVICE_ID_LSTICK_DOWN, - XDK_DEVICE_ID_LSTICK_LEFT_DPAD, - XDK_DEVICE_ID_LSTICK_RIGHT_DPAD, - XDK_DEVICE_ID_LSTICK_UP_DPAD, - XDK_DEVICE_ID_LSTICK_DOWN_DPAD, - XDK_DEVICE_ID_RSTICK_LEFT, - XDK_DEVICE_ID_RSTICK_RIGHT, - XDK_DEVICE_ID_RSTICK_UP, - XDK_DEVICE_ID_RSTICK_DOWN, - XDK_DEVICE_ID_RSTICK_LEFT_DPAD, - XDK_DEVICE_ID_RSTICK_RIGHT_DPAD, - XDK_DEVICE_ID_RSTICK_UP_DPAD, - XDK_DEVICE_ID_RSTICK_DOWN_DPAD, - - RARCH_LAST_PLATFORM_KEY -}; - -#ifdef _XBOX1 -#include "../xbox1/xinput_xbox_input.h" -#endif -#elif defined(GEKKO) -#include -#ifdef HW_RVL -#include -#endif -#endif - extern uint64_t rarch_default_keybind_lut[RARCH_FIRST_META_KEY]; extern char rarch_default_libretro_keybind_name_lut[RARCH_FIRST_META_KEY][256]; @@ -150,7 +56,7 @@ void rarch_input_set_default_keybinds(unsigned player); void rarch_input_set_keybind(unsigned player, unsigned keybind_action, uint64_t default_retro_joypad_id); -void rarch_input_set_controls_default (void); +void rarch_input_set_controls_default (const input_driver_t *input); const char *rarch_input_get_default_keybind_name (unsigned id); #endif diff --git a/driver.h b/driver.h index 3399e22196..3fdf20befe 100644 --- a/driver.h +++ b/driver.h @@ -159,6 +159,9 @@ typedef struct input_driver int16_t (*input_state)(void *data, const struct retro_keybind **retro_keybinds, unsigned port, unsigned device, unsigned index, unsigned id); bool (*key_pressed)(void *data, int key); void (*free)(void *data); +#ifdef RARCH_CONSOLE + void (*set_default_keybind_lut)(void); +#endif const char *ident; } input_driver_t; diff --git a/input/null.c b/input/null.c index a861b63d4b..4b228b4ad0 100644 --- a/input/null.c +++ b/input/null.c @@ -51,12 +51,17 @@ static void null_input_free(void *data) (void)data; } +static void null_set_default_keybind_lut(void) { } + const input_driver_t input_null = { null_input_init, null_input_poll, null_input_state, null_input_key_pressed, null_input_free, +#ifdef RARCH_CONSOLE + null_set_default_keybind_lut, +#endif "null", }; diff --git a/ps3/frontend/main.c b/ps3/frontend/main.c index fa15f3ddf5..082c82fb95 100644 --- a/ps3/frontend/main.c +++ b/ps3/frontend/main.c @@ -240,10 +240,11 @@ int main(int argc, char *argv[]) get_environment_settings(argc, argv); config_set_defaults(); + input_ps3.init(); char tmp_path[PATH_MAX]; snprintf(tmp_path, sizeof(tmp_path), "%s/", default_paths.core_dir); - rarch_configure_libretro(tmp_path, default_paths.executable_extension); + rarch_configure_libretro(&input_ps3, tmp_path, default_paths.executable_extension); #if(CELL_SDK_VERSION > 0x340000) if (g_console.screenshots_enable) @@ -268,7 +269,6 @@ int main(int argc, char *argv[]) video_gl.start(); - input_ps3.init(); #ifdef HAVE_OSKUTIL oskutil_init(&g_console.oskutil_handle, 0); diff --git a/ps3/ps3_input.c b/ps3/ps3_input.c index 232063661c..9a6454a484 100644 --- a/ps3/ps3_input.c +++ b/ps3/ps3_input.c @@ -470,12 +470,33 @@ static bool ps3_key_pressed(void *data, int key) } } +static void ps3_set_default_keybind_lut(void) +{ + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_B] = platform_keys[PS3_DEVICE_ID_JOYPAD_CROSS].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_Y] = platform_keys[PS3_DEVICE_ID_JOYPAD_SQUARE].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_SELECT] = platform_keys[PS3_DEVICE_ID_JOYPAD_SELECT].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_START] = platform_keys[PS3_DEVICE_ID_JOYPAD_START].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_UP] = platform_keys[PS3_DEVICE_ID_JOYPAD_UP].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_DOWN] = platform_keys[PS3_DEVICE_ID_JOYPAD_DOWN].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_LEFT] = platform_keys[PS3_DEVICE_ID_JOYPAD_LEFT].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_RIGHT] = platform_keys[PS3_DEVICE_ID_JOYPAD_RIGHT].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_A] = platform_keys[PS3_DEVICE_ID_JOYPAD_CIRCLE].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_X] = platform_keys[PS3_DEVICE_ID_JOYPAD_TRIANGLE].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_L] = platform_keys[PS3_DEVICE_ID_JOYPAD_L1].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_R] = platform_keys[PS3_DEVICE_ID_JOYPAD_R1].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_R2] = platform_keys[PS3_DEVICE_ID_JOYPAD_R2].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_R3] = platform_keys[PS3_DEVICE_ID_JOYPAD_R3].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_L2] = platform_keys[PS3_DEVICE_ID_JOYPAD_L2].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_L3] = platform_keys[PS3_DEVICE_ID_JOYPAD_L3].joykey; +} + const input_driver_t input_ps3 = { .init = ps3_input_initialize, .poll = ps3_input_poll, .input_state = ps3_input_state, .key_pressed = ps3_key_pressed, .free = ps3_free_input, + .set_default_keybind_lut = ps3_set_default_keybind_lut, .ident = "ps3", }; diff --git a/ps3/ps3_input.h b/ps3/ps3_input.h index 66cdb5c7b1..5e4436168a 100644 --- a/ps3/ps3_input.h +++ b/ps3/ps3_input.h @@ -156,6 +156,44 @@ typedef struct CellOskDialogParam dialogParam; } oskutil_params; +enum ps3_device_id +{ + PS3_DEVICE_ID_JOYPAD_CIRCLE = 0, + PS3_DEVICE_ID_JOYPAD_CROSS, + PS3_DEVICE_ID_JOYPAD_TRIANGLE, + PS3_DEVICE_ID_JOYPAD_SQUARE, + PS3_DEVICE_ID_JOYPAD_UP, + PS3_DEVICE_ID_JOYPAD_DOWN, + PS3_DEVICE_ID_JOYPAD_LEFT, + PS3_DEVICE_ID_JOYPAD_RIGHT, + PS3_DEVICE_ID_JOYPAD_SELECT, + PS3_DEVICE_ID_JOYPAD_START, + PS3_DEVICE_ID_JOYPAD_L1, + PS3_DEVICE_ID_JOYPAD_L2, + PS3_DEVICE_ID_JOYPAD_L3, + PS3_DEVICE_ID_JOYPAD_R1, + PS3_DEVICE_ID_JOYPAD_R2, + PS3_DEVICE_ID_JOYPAD_R3, + PS3_DEVICE_ID_LSTICK_LEFT, + PS3_DEVICE_ID_LSTICK_RIGHT, + PS3_DEVICE_ID_LSTICK_UP, + PS3_DEVICE_ID_LSTICK_DOWN, + PS3_DEVICE_ID_LSTICK_LEFT_DPAD, + PS3_DEVICE_ID_LSTICK_RIGHT_DPAD, + PS3_DEVICE_ID_LSTICK_UP_DPAD, + PS3_DEVICE_ID_LSTICK_DOWN_DPAD, + PS3_DEVICE_ID_RSTICK_LEFT, + PS3_DEVICE_ID_RSTICK_RIGHT, + PS3_DEVICE_ID_RSTICK_UP, + PS3_DEVICE_ID_RSTICK_DOWN, + PS3_DEVICE_ID_RSTICK_LEFT_DPAD, + PS3_DEVICE_ID_RSTICK_RIGHT_DPAD, + PS3_DEVICE_ID_RSTICK_UP_DPAD, + PS3_DEVICE_ID_RSTICK_DOWN_DPAD, + + RARCH_LAST_PLATFORM_KEY +}; + void oskutil_write_message(oskutil_params *params, const wchar_t* msg); void oskutil_write_initial_message(oskutil_params *params, const wchar_t* msg); void oskutil_init(oskutil_params *params, unsigned int containersize); diff --git a/wii/input.c b/wii/input.c index 6fe63fc4a0..219e97ba82 100644 --- a/wii/input.c +++ b/wii/input.c @@ -188,12 +188,16 @@ static bool wii_key_pressed(void *data, int key) } } +static void wii_set_default_keybind_lut(void) +{ +} + const input_driver_t input_wii = { .init = wii_input_initialize, .poll = wii_input_poll, .input_state = wii_input_state, .key_pressed = wii_key_pressed, .free = wii_free_input, + .set_default_keybind_lut = wii_set_default_keybind_lut, .ident = "wii", }; - diff --git a/xbox1/xinput_xbox_input.c b/xbox1/xinput_xbox_input.c index 5510a7163d..c680c5072d 100644 --- a/xbox1/xinput_xbox_input.c +++ b/xbox1/xinput_xbox_input.c @@ -191,6 +191,33 @@ static bool xinput_input_key_pressed(void *data, int key) return retval; } +static void xinput_set_default_keybind_lut(void) +{ + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_B] = platform_keys[XDK_DEVICE_ID_JOYPAD_A].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_Y] = platform_keys[XDK_DEVICE_ID_JOYPAD_X].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_SELECT] = platform_keys[XDK_DEVICE_ID_JOYPAD_BACK].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_START] = platform_keys[XDK_DEVICE_ID_JOYPAD_START].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_UP] = platform_keys[XDK_DEVICE_ID_JOYPAD_UP].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_DOWN] = platform_keys[XDK_DEVICE_ID_JOYPAD_DOWN].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_LEFT] = platform_keys[XDK_DEVICE_ID_JOYPAD_LEFT].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_RIGHT] = platform_keys[XDK_DEVICE_ID_JOYPAD_RIGHT].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_A] = platform_keys[XDK_DEVICE_ID_JOYPAD_B].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_X] = platform_keys[XDK_DEVICE_ID_JOYPAD_Y].joykey; +#if defined(_XBOX1) + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_L] = platform_keys[XDK_DEVICE_ID_JOYPAD_LEFT_TRIGGER].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_R] = platform_keys[XDK_DEVICE_ID_JOYPAD_RIGHT_TRIGGER].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_L2] = platform_keys[XDK_DEVICE_ID_JOYPAD_LB].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_R2] = platform_keys[XDK_DEVICE_ID_JOYPAD_RB].joykey; +#elif defined(_XBOX360) + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_L] = platform_keys[XDK_DEVICE_ID_JOYPAD_LB].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_R] = platform_keys[XDK_DEVICE_ID_JOYPAD_RB].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_L2] = platform_keys[XDK_DEVICE_ID_JOYPAD_LEFT_TRIGGER].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_R2] = platform_keys[XDK_DEVICE_ID_JOYPAD_RIGHT_TRIGGER].joykey; +#endif + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_L3] = platform_keys[XDK_DEVICE_ID_LSTICK_THUMB].joykey; + rarch_default_keybind_lut[RETRO_DEVICE_ID_JOYPAD_R3] = platform_keys[XDK_DEVICE_ID_RSTICK_THUMB].joykey; +} + const input_driver_t input_xinput = { xinput_input_init, @@ -198,5 +225,6 @@ const input_driver_t input_xinput = xinput_input_state, xinput_input_key_pressed, xinput_input_free_input, + xinput_set_default_keybind_lut, "xinput" }; diff --git a/xbox1/xinput_xbox_input.h b/xbox1/xinput_xbox_input.h index 34bf1a8719..be7bc64782 100644 --- a/xbox1/xinput_xbox_input.h +++ b/xbox1/xinput_xbox_input.h @@ -44,4 +44,42 @@ enum { XINPUT1_GAMEPAD_RSTICK_DOWN_MASK = 1 << 23, }; +enum xdk_device_id +{ + XDK_DEVICE_ID_JOYPAD_B = 0, + XDK_DEVICE_ID_JOYPAD_A, + XDK_DEVICE_ID_JOYPAD_Y, + XDK_DEVICE_ID_JOYPAD_X, + XDK_DEVICE_ID_JOYPAD_UP, + XDK_DEVICE_ID_JOYPAD_DOWN, + XDK_DEVICE_ID_JOYPAD_LEFT, + XDK_DEVICE_ID_JOYPAD_RIGHT, + XDK_DEVICE_ID_JOYPAD_BACK, + XDK_DEVICE_ID_JOYPAD_START, + XDK_DEVICE_ID_JOYPAD_LB, + XDK_DEVICE_ID_JOYPAD_LEFT_TRIGGER, + XDK_DEVICE_ID_LSTICK_THUMB, + XDK_DEVICE_ID_JOYPAD_RB, + XDK_DEVICE_ID_JOYPAD_RIGHT_TRIGGER, + XDK_DEVICE_ID_RSTICK_THUMB, + XDK_DEVICE_ID_LSTICK_LEFT, + XDK_DEVICE_ID_LSTICK_RIGHT, + XDK_DEVICE_ID_LSTICK_UP, + XDK_DEVICE_ID_LSTICK_DOWN, + XDK_DEVICE_ID_LSTICK_LEFT_DPAD, + XDK_DEVICE_ID_LSTICK_RIGHT_DPAD, + XDK_DEVICE_ID_LSTICK_UP_DPAD, + XDK_DEVICE_ID_LSTICK_DOWN_DPAD, + XDK_DEVICE_ID_RSTICK_LEFT, + XDK_DEVICE_ID_RSTICK_RIGHT, + XDK_DEVICE_ID_RSTICK_UP, + XDK_DEVICE_ID_RSTICK_DOWN, + XDK_DEVICE_ID_RSTICK_LEFT_DPAD, + XDK_DEVICE_ID_RSTICK_RIGHT_DPAD, + XDK_DEVICE_ID_RSTICK_UP_DPAD, + XDK_DEVICE_ID_RSTICK_DOWN_DPAD, + + RARCH_LAST_PLATFORM_KEY +}; + #endif diff --git a/xdk/frontend/main.c b/xdk/frontend/main.c index a66adc334c..59c33fcf75 100644 --- a/xdk/frontend/main.c +++ b/xdk/frontend/main.c @@ -121,14 +121,14 @@ int main(int argc, char *argv[]) config_set_defaults(); - rarch_configure_libretro(default_paths.filesystem_root_dir, default_paths.executable_extension); + input_xinput.init(); + rarch_configure_libretro(&input_xinput, default_paths.filesystem_root_dir, default_paths.executable_extension); #if defined(HAVE_D3D8) || defined(HAVE_D3D9) video_xdk_d3d.start(); #else video_null.start(); #endif - input_xinput.init(); rarch_input_set_default_keybind_names_for_emulator(); From 2ab5f84e5c3b09fc8bafd56ff262ac69df106072 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Wed, 25 Jul 2012 21:46:22 +0200 Subject: [PATCH 46/51] (360/PS3) Ports that support HAVE_HDD_CACHE_PARTITION will fill in default_paths member with path to cache dir --- console/retroarch_console.h | 3 +++ console/retroarch_rzlib.c | 8 +------- ps3/frontend/main.c | 3 +++ xdk/frontend/main.c | 7 +++++-- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/console/retroarch_console.h b/console/retroarch_console.h index 4de103b1af..9174f5d010 100644 --- a/console/retroarch_console.h +++ b/console/retroarch_console.h @@ -139,6 +139,9 @@ typedef struct char menu_border_file[PATH_MAX]; char border_file[PATH_MAX]; char border_dir[PATH_MAX]; +#ifdef HAVE_HDD_CACHE_PARTITION + char cache_dir[PATH_MAX]; +#endif char cgp_dir[PATH_MAX]; char config_file[PATH_MAX]; char core_dir[PATH_MAX]; diff --git a/console/retroarch_rzlib.c b/console/retroarch_rzlib.c index 97b9facb26..5576f0f97d 100644 --- a/console/retroarch_rzlib.c +++ b/console/retroarch_rzlib.c @@ -49,13 +49,7 @@ static int rarch_extract_currentfile_in_zip(unzFile uf) char write_filename[PATH_MAX]; #ifdef HAVE_HDD_CACHE_PARTITION - -#if defined(__CELLOS_LV2__) - snprintf(write_filename, sizeof(write_filename), "/dev_hdd1/%s", filename_inzip); -#elif defined(_XBOX) - snprintf(write_filename, sizeof(write_filename), "cache:\\%s", filename_inzip); -#endif - + snprintf(write_filename, sizeof(write_filename), "%s%s", default_paths.cache_dir, filename_inzip); #endif err = unzOpenCurrentFile(uf); diff --git a/ps3/frontend/main.c b/ps3/frontend/main.c index 082c82fb95..800aae82f9 100644 --- a/ps3/frontend/main.c +++ b/ps3/frontend/main.c @@ -187,6 +187,9 @@ static void get_environment_settings(int argc, char *argv[]) RARCH_LOG("usrDirPath : [%s].\n", default_paths.port_dir); } +#ifdef HAVE_HDD_CACHE_PARTITION + snprintf(default_paths.cache_dir, sizeof(default_paths.cache_dir), "/dev_hdd1/"); +#endif snprintf(default_paths.core_dir, sizeof(default_paths.core_dir), "%s/cores", default_paths.port_dir); snprintf(default_paths.executable_extension, sizeof(default_paths.executable_extension), ".SELF"); snprintf(default_paths.savestate_dir, sizeof(default_paths.savestate_dir), "%s/savestates", default_paths.core_dir); diff --git a/xdk/frontend/main.c b/xdk/frontend/main.c index 59c33fcf75..4d3c5ee3ba 100644 --- a/xdk/frontend/main.c +++ b/xdk/frontend/main.c @@ -99,13 +99,16 @@ static void get_environment_settings (void) } #endif -#ifdef _XBOX1 +#if defined(_XBOX1) /* FIXME: Hardcoded */ strlcpy(default_paths.config_file, "D:\\retroarch.cfg", sizeof(default_paths.config_file)); strlcpy(g_settings.system_directory, "D:\\system\\", sizeof(g_settings.system_directory)); strlcpy(default_paths.filesystem_root_dir, "D:\\", sizeof(default_paths.filesystem_root_dir)); strlcpy(default_paths.executable_extension, ".xbe", sizeof(default_paths.executable_extension)); -#else +#elif defined(_XBOX360) +#ifdef HAVE_HDD_CACHE_PARTITION + strlcpy(default_paths.cache_dir, "cache:\\", sizeof(default_paths.cache_dir)); +#endif strlcpy(default_paths.filesystem_root_dir, "game:\\", sizeof(default_paths.filesystem_root_dir)); strlcpy(default_paths.shader_file, "game:\\media\\shaders\\stock.cg", sizeof(default_paths.shader_file)); strlcpy(default_paths.config_file, "game:\\retroarch.cfg", sizeof(default_paths.config_file)); From bfb933d98da9ea48d0702295c60f9b3126b276e1 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Wed, 25 Jul 2012 23:09:36 +0200 Subject: [PATCH 47/51] (PS3) Split up more code in retroarch_console.c --- console/griffin/griffin.c | 6 + console/libretro_mgmt.c | 2 +- console/libretro_mgmt.h | 2 - console/retroarch_config.c | 188 +++++++++++++++++++++++ console/retroarch_config.h | 31 ++++ console/retroarch_console.c | 238 ------------------------------ console/retroarch_console.h | 28 +--- console/retroarch_console_input.h | 7 - console/retroarch_rom_ext.c | 80 ++++++++++ console/retroarch_rom_ext.h | 29 ++++ ps3/frontend/main.c | 2 + ps3/frontend/menu.c | 3 + xdk/frontend/main.c | 1 + 13 files changed, 344 insertions(+), 273 deletions(-) create mode 100644 console/retroarch_config.c create mode 100644 console/retroarch_config.h create mode 100644 console/retroarch_rom_ext.c create mode 100644 console/retroarch_rom_ext.h diff --git a/console/griffin/griffin.c b/console/griffin/griffin.c index 0b5c308209..90ddaab09c 100644 --- a/console/griffin/griffin.c +++ b/console/griffin/griffin.c @@ -21,7 +21,13 @@ /*============================================================ CONSOLE EXTENSIONS ============================================================ */ +#include "../retroarch_rom_ext.c" #include "../retroarch_console.c" + +#ifdef HAVE_CONFIGFILE +#include "../retroarch_config.c" +#endif + #include "../retroarch_console_input.c" #ifdef HAVE_ZLIB diff --git a/console/libretro_mgmt.c b/console/libretro_mgmt.c index 3362be5ff5..87844ef4e3 100644 --- a/console/libretro_mgmt.c +++ b/console/libretro_mgmt.c @@ -65,7 +65,7 @@ static bool rarch_manage_libretro_install(char *libretro_core_installed, size_t return ret; } -bool rarch_configure_libretro_core(const char *full_path, const char *tmp_path, +static bool rarch_configure_libretro_core(const char *full_path, const char *tmp_path, const char *libretro_path, const char *config_path, const char *extension) { bool libretro_core_was_installed = false; diff --git a/console/libretro_mgmt.h b/console/libretro_mgmt.h index e7713f07eb..07e486e8df 100644 --- a/console/libretro_mgmt.h +++ b/console/libretro_mgmt.h @@ -29,8 +29,6 @@ enum }; void rarch_manage_libretro_set_first_file(char *first_file, size_t size_of_first_file, const char *libretro_path, const char * exe_ext); -bool rarch_configure_libretro_core(const char *full_path, const char *tmp_path, - const char *libretro_path, const char *config_path, const char *extension); void rarch_configure_libretro(const input_driver_t *input, const char *path_prefix, const char * extension); #endif diff --git a/console/retroarch_config.c b/console/retroarch_config.c new file mode 100644 index 0000000000..e8e71b3317 --- /dev/null +++ b/console/retroarch_config.c @@ -0,0 +1,188 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2012 - Hans-Kristian Arntzen + * Copyright (C) 2011-2012 - Daniel De Matteis + * + * RetroArch 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. + * + * RetroArch 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 RetroArch. + * If not, see . + */ + +#include + +#include "retroarch_config.h" + +#include "../conf/config_file.h" +#include "../conf/config_file_macros.h" + +void rarch_config_create_default(const char * conf_name) +{ + FILE * f; + RARCH_WARN("Config file \"%s\" doesn't exist. Creating...\n", conf_name); + f = fopen(conf_name, "w"); + fclose(f); +} + +void rarch_config_load(const char * conf_name, const char * libretro_dir_path, const char * exe_ext, bool find_libretro_path) +{ + if(!path_file_exists(conf_name)) + rarch_config_create_default(conf_name); + else + { + config_file_t * conf = config_file_new(conf_name); + + // g_settings + +#ifdef HAVE_LIBRETRO_MANAGEMENT + if(find_libretro_path) + { + CONFIG_GET_STRING(libretro, "libretro_path"); + + if(strcmp(g_settings.libretro, "") == 0) + { + char first_file[PATH_MAX]; + rarch_manage_libretro_set_first_file(first_file, sizeof(first_file), libretro_dir_path, exe_ext); + if(first_file != NULL) + strlcpy(g_settings.libretro, first_file, sizeof(g_settings.libretro)); + } + } +#endif + + CONFIG_GET_STRING(system_directory, "system_directory"); + CONFIG_GET_STRING(cheat_database, "cheat_database"); + CONFIG_GET_BOOL(rewind_enable, "rewind_enable"); + CONFIG_GET_STRING(video.cg_shader_path, "video_cg_shader"); +#ifdef HAVE_FBO + CONFIG_GET_STRING(video.second_pass_shader, "video_second_pass_shader"); + CONFIG_GET_FLOAT(video.fbo_scale_x, "video_fbo_scale_x"); + CONFIG_GET_FLOAT(video.fbo_scale_y, "video_fbo_scale_y"); + CONFIG_GET_BOOL(video.render_to_texture, "video_render_to_texture"); + CONFIG_GET_BOOL(video.second_pass_smooth, "video_second_pass_smooth"); +#endif +#ifdef _XBOX360 + CONFIG_GET_BOOL_CONSOLE(gamma_correction_enable, "gamma_correction_enable"); + CONFIG_GET_INT_CONSOLE(color_format, "color_format"); +#endif + CONFIG_GET_BOOL(video.smooth, "video_smooth"); + CONFIG_GET_BOOL(video.vsync, "video_vsync"); + CONFIG_GET_FLOAT(video.aspect_ratio, "video_aspect_ratio"); + CONFIG_GET_STRING(audio.device, "audio_device"); + + for (unsigned i = 0; i < 7; i++) + { + char cfg[64]; + snprintf(cfg, sizeof(cfg), "input_dpad_emulation_p%u", i + 1); + CONFIG_GET_INT(input.dpad_emulation[i], cfg); + } + + // g_console + +#ifdef HAVE_FBO + CONFIG_GET_BOOL_CONSOLE(fbo_enabled, "fbo_enabled"); +#endif +#ifdef __CELLOS_LV2__ + CONFIG_GET_BOOL_CONSOLE(custom_bgm_enable, "custom_bgm_enable"); +#endif + CONFIG_GET_BOOL_CONSOLE(overscan_enable, "overscan_enable"); + CONFIG_GET_BOOL_CONSOLE(screenshots_enable, "screenshots_enable"); + CONFIG_GET_BOOL_CONSOLE(throttle_enable, "throttle_enable"); + CONFIG_GET_BOOL_CONSOLE(triple_buffering_enable, "triple_buffering_enable"); + CONFIG_GET_BOOL_CONSOLE(info_msg_enable, "info_msg_enable"); + CONFIG_GET_INT_CONSOLE(aspect_ratio_index, "aspect_ratio_index"); + CONFIG_GET_INT_CONSOLE(current_resolution_id, "current_resolution_id"); + CONFIG_GET_INT_CONSOLE(viewports.custom_vp.x, "custom_viewport_x"); + CONFIG_GET_INT_CONSOLE(viewports.custom_vp.y, "custom_viewport_y"); + CONFIG_GET_INT_CONSOLE(viewports.custom_vp.width, "custom_viewport_width"); + CONFIG_GET_INT_CONSOLE(viewports.custom_vp.height, "custom_viewport_height"); + CONFIG_GET_INT_CONSOLE(screen_orientation, "screen_orientation"); + CONFIG_GET_INT_CONSOLE(sound_mode, "sound_mode"); + CONFIG_GET_STRING_CONSOLE(default_rom_startup_dir, "default_rom_startup_dir"); + CONFIG_GET_FLOAT_CONSOLE(menu_font_size, "menu_font_size"); + CONFIG_GET_FLOAT_CONSOLE(overscan_amount, "overscan_amount"); + + // g_extern + CONFIG_GET_INT_EXTERN(state_slot, "state_slot"); + CONFIG_GET_INT_EXTERN(audio_data.mute, "audio_mute"); + } +} + +void rarch_config_save(const char * conf_name) +{ + if(!path_file_exists(conf_name)) + rarch_config_create_default(conf_name); + else + { + config_file_t * conf = config_file_new(conf_name); + + if(conf == NULL) + conf = config_file_new(NULL); + + // g_settings + config_set_string(conf, "libretro_path", g_settings.libretro); +#ifdef HAVE_XML + config_set_string(conf, "cheat_database_path", g_settings.cheat_database); +#endif + config_set_bool(conf, "rewind_enable", g_settings.rewind_enable); + config_set_string(conf, "video_cg_shader", g_settings.video.cg_shader_path); + config_set_float(conf, "video_aspect_ratio", g_settings.video.aspect_ratio); +#ifdef HAVE_FBO + config_set_float(conf, "video_fbo_scale_x", g_settings.video.fbo_scale_x); + config_set_float(conf, "video_fbo_scale_y", g_settings.video.fbo_scale_y); + config_set_string(conf, "video_second_pass_shader", g_settings.video.second_pass_shader); + config_set_bool(conf, "video_render_to_texture", g_settings.video.render_to_texture); + config_set_bool(conf, "video_second_pass_smooth", g_settings.video.second_pass_smooth); +#endif + config_set_bool(conf, "video_smooth", g_settings.video.smooth); + config_set_bool(conf, "video_vsync", g_settings.video.vsync); + config_set_string(conf, "audio_device", g_settings.audio.device); + + for (unsigned i = 0; i < 7; i++) + { + char cfg[64]; + snprintf(cfg, sizeof(cfg), "input_dpad_emulation_p%u", i + 1); + config_set_int(conf, cfg, g_settings.input.dpad_emulation[i]); + } + +#ifdef RARCH_CONSOLE + config_set_bool(conf, "fbo_enabled", g_console.fbo_enabled); +#ifdef __CELLOS_LV2__ + config_set_bool(conf, "custom_bgm_enable", g_console.custom_bgm_enable); +#endif + config_set_bool(conf, "overscan_enable", g_console.overscan_enable); + config_set_bool(conf, "screenshots_enable", g_console.screenshots_enable); +#ifdef _XBOX + config_set_bool(conf, "gamma_correction_enable", g_console.gamma_correction_enable); + config_set_int(conf, "color_format", g_console.color_format); +#endif + config_set_bool(conf, "throttle_enable", g_console.throttle_enable); + config_set_bool(conf, "triple_buffering_enable", g_console.triple_buffering_enable); + config_set_bool(conf, "info_msg_enable", g_console.info_msg_enable); + config_set_int(conf, "sound_mode", g_console.sound_mode); + config_set_int(conf, "aspect_ratio_index", g_console.aspect_ratio_index); + config_set_int(conf, "current_resolution_id", g_console.current_resolution_id); + config_set_int(conf, "custom_viewport_width", g_console.viewports.custom_vp.width); + config_set_int(conf, "custom_viewport_height", g_console.viewports.custom_vp.height); + config_set_int(conf, "custom_viewport_x", g_console.viewports.custom_vp.x); + config_set_int(conf, "custom_viewport_y", g_console.viewports.custom_vp.y); + config_set_int(conf, "screen_orientation", g_console.screen_orientation); + config_set_string(conf, "default_rom_startup_dir", g_console.default_rom_startup_dir); + config_set_float(conf, "menu_font_size", g_console.menu_font_size); + config_set_float(conf, "overscan_amount", g_console.overscan_amount); +#endif + + // g_extern + config_set_int(conf, "state_slot", g_extern.state_slot); + config_set_int(conf, "audio_mute", g_extern.audio_data.mute); + + if (!config_file_write(conf, conf_name)) + RARCH_ERR("Failed to write config file to \"%s\". Check permissions.\n", conf_name); + + free(conf); + } +} diff --git a/console/retroarch_config.h b/console/retroarch_config.h new file mode 100644 index 0000000000..1ed691b422 --- /dev/null +++ b/console/retroarch_config.h @@ -0,0 +1,31 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2012 - Hans-Kristian Arntzen + * Copyright (C) 2011-2012 - Daniel De Matteis + * + * RetroArch 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. + * + * RetroArch 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 RetroArch. + * If not, see . + */ + +#ifndef _RARCH_CONSOLE_CONFIG_H +#define _RARCH_CONSOLE_CONFIG_H + +enum +{ + CONFIG_FILE, + SHADER_PRESET_FILE, + INPUT_PRESET_FILE +}; + +void rarch_config_create_default(const char * conf_name); +void rarch_config_load(const char * conf_name, const char * libretro_dir_path, const char * exe_ext, bool find_libretro_path); +void rarch_config_save(const char * conf_name); + +#endif diff --git a/console/retroarch_console.c b/console/retroarch_console.c index ff51d33af2..62ab43d73e 100644 --- a/console/retroarch_console.c +++ b/console/retroarch_console.c @@ -18,7 +18,6 @@ #include #include #include -#include #include "../boolean.h" #include "../compat/strl.h" #include "../libretro.h" @@ -27,79 +26,14 @@ #include "retroarch_console.h" #include "../file.h" -#ifdef HAVE_CONFIGFILE -#include "../conf/config_file.h" -#include "../conf/config_file_macros.h" -#endif - #ifdef _WIN32 #include "../compat/posix_string.h" #endif #define MAX_ARGS 32 -/*============================================================ - ROM EXTENSIONS -============================================================ */ - default_paths_t default_paths; -void rarch_console_load_game(const char *path) -{ - snprintf(g_console.rom_path, sizeof(g_console.rom_path), path); - rarch_settings_change(S_START_RARCH); -} - -const char *rarch_console_get_rom_ext(void) -{ - const char *retval = NULL; - - struct retro_system_info info; -#ifdef ANDROID - pretro_get_system_info(&info); -#else - retro_get_system_info(&info); -#endif - - if (info.valid_extensions) - retval = info.valid_extensions; - else - retval = "ZIP|zip"; - - return retval; -} - -void rarch_console_name_from_id(char *name, size_t size) -{ - if (size == 0) - return; - - struct retro_system_info info; -#ifdef ANDROID - pretro_get_system_info(&info); -#else - retro_get_system_info(&info); -#endif - const char *id = info.library_name ? info.library_name : "Unknown"; - - if (!id || strlen(id) >= size) - { - name[0] = '\0'; - return; - } - - name[strlen(id)] = '\0'; - - for (size_t i = 0; id[i] != '\0'; i++) - { - char c = id[i]; - if (isspace(c) || isblank(c)) - name[i] = '_'; - else - name[i] = tolower(c); - } -} - /*============================================================ VIDEO EXTENSIONS ============================================================ */ @@ -374,175 +308,3 @@ const char * rarch_convert_wchar_to_const_char(const wchar_t * wstr) wcstombs(str, wstr, sizeof(str)); return str; } - -/*============================================================ - CONFIG - ============================================================ */ - -#ifdef HAVE_CONFIGFILE -void rarch_config_create_default(const char * conf_name) -{ - FILE * f; - RARCH_WARN("Config file \"%s\" doesn't exist. Creating...\n", conf_name); - f = fopen(conf_name, "w"); - fclose(f); -} - -void rarch_config_load(const char * conf_name, const char * libretro_dir_path, const char * exe_ext, bool find_libretro_path) -{ - if(!path_file_exists(conf_name)) - rarch_config_create_default(conf_name); - else - { - config_file_t * conf = config_file_new(conf_name); - - // g_settings - -#ifdef HAVE_LIBRETRO_MANAGEMENT - if(find_libretro_path) - { - CONFIG_GET_STRING(libretro, "libretro_path"); - - if(strcmp(g_settings.libretro, "") == 0) - { - char first_file[PATH_MAX]; - rarch_manage_libretro_set_first_file(first_file, sizeof(first_file), libretro_dir_path, exe_ext); - if(first_file != NULL) - strlcpy(g_settings.libretro, first_file, sizeof(g_settings.libretro)); - } - } -#endif - - CONFIG_GET_STRING(system_directory, "system_directory"); - CONFIG_GET_STRING(cheat_database, "cheat_database"); - CONFIG_GET_BOOL(rewind_enable, "rewind_enable"); - CONFIG_GET_STRING(video.cg_shader_path, "video_cg_shader"); -#ifdef HAVE_FBO - CONFIG_GET_STRING(video.second_pass_shader, "video_second_pass_shader"); - CONFIG_GET_FLOAT(video.fbo_scale_x, "video_fbo_scale_x"); - CONFIG_GET_FLOAT(video.fbo_scale_y, "video_fbo_scale_y"); - CONFIG_GET_BOOL(video.render_to_texture, "video_render_to_texture"); - CONFIG_GET_BOOL(video.second_pass_smooth, "video_second_pass_smooth"); -#endif -#ifdef _XBOX360 - CONFIG_GET_BOOL_CONSOLE(gamma_correction_enable, "gamma_correction_enable"); - CONFIG_GET_INT_CONSOLE(color_format, "color_format"); -#endif - CONFIG_GET_BOOL(video.smooth, "video_smooth"); - CONFIG_GET_BOOL(video.vsync, "video_vsync"); - CONFIG_GET_FLOAT(video.aspect_ratio, "video_aspect_ratio"); - CONFIG_GET_STRING(audio.device, "audio_device"); - - for (unsigned i = 0; i < 7; i++) - { - char cfg[64]; - snprintf(cfg, sizeof(cfg), "input_dpad_emulation_p%u", i + 1); - CONFIG_GET_INT(input.dpad_emulation[i], cfg); - } - - // g_console - -#ifdef HAVE_FBO - CONFIG_GET_BOOL_CONSOLE(fbo_enabled, "fbo_enabled"); -#endif -#ifdef __CELLOS_LV2__ - CONFIG_GET_BOOL_CONSOLE(custom_bgm_enable, "custom_bgm_enable"); -#endif - CONFIG_GET_BOOL_CONSOLE(overscan_enable, "overscan_enable"); - CONFIG_GET_BOOL_CONSOLE(screenshots_enable, "screenshots_enable"); - CONFIG_GET_BOOL_CONSOLE(throttle_enable, "throttle_enable"); - CONFIG_GET_BOOL_CONSOLE(triple_buffering_enable, "triple_buffering_enable"); - CONFIG_GET_BOOL_CONSOLE(info_msg_enable, "info_msg_enable"); - CONFIG_GET_INT_CONSOLE(aspect_ratio_index, "aspect_ratio_index"); - CONFIG_GET_INT_CONSOLE(current_resolution_id, "current_resolution_id"); - CONFIG_GET_INT_CONSOLE(viewports.custom_vp.x, "custom_viewport_x"); - CONFIG_GET_INT_CONSOLE(viewports.custom_vp.y, "custom_viewport_y"); - CONFIG_GET_INT_CONSOLE(viewports.custom_vp.width, "custom_viewport_width"); - CONFIG_GET_INT_CONSOLE(viewports.custom_vp.height, "custom_viewport_height"); - CONFIG_GET_INT_CONSOLE(screen_orientation, "screen_orientation"); - CONFIG_GET_INT_CONSOLE(sound_mode, "sound_mode"); - CONFIG_GET_STRING_CONSOLE(default_rom_startup_dir, "default_rom_startup_dir"); - CONFIG_GET_FLOAT_CONSOLE(menu_font_size, "menu_font_size"); - CONFIG_GET_FLOAT_CONSOLE(overscan_amount, "overscan_amount"); - - // g_extern - CONFIG_GET_INT_EXTERN(state_slot, "state_slot"); - CONFIG_GET_INT_EXTERN(audio_data.mute, "audio_mute"); - } -} - -void rarch_config_save(const char * conf_name) -{ - if(!path_file_exists(conf_name)) - rarch_config_create_default(conf_name); - else - { - config_file_t * conf = config_file_new(conf_name); - - if(conf == NULL) - conf = config_file_new(NULL); - - // g_settings - config_set_string(conf, "libretro_path", g_settings.libretro); -#ifdef HAVE_XML - config_set_string(conf, "cheat_database_path", g_settings.cheat_database); -#endif - config_set_bool(conf, "rewind_enable", g_settings.rewind_enable); - config_set_string(conf, "video_cg_shader", g_settings.video.cg_shader_path); - config_set_float(conf, "video_aspect_ratio", g_settings.video.aspect_ratio); -#ifdef HAVE_FBO - config_set_float(conf, "video_fbo_scale_x", g_settings.video.fbo_scale_x); - config_set_float(conf, "video_fbo_scale_y", g_settings.video.fbo_scale_y); - config_set_string(conf, "video_second_pass_shader", g_settings.video.second_pass_shader); - config_set_bool(conf, "video_render_to_texture", g_settings.video.render_to_texture); - config_set_bool(conf, "video_second_pass_smooth", g_settings.video.second_pass_smooth); -#endif - config_set_bool(conf, "video_smooth", g_settings.video.smooth); - config_set_bool(conf, "video_vsync", g_settings.video.vsync); - config_set_string(conf, "audio_device", g_settings.audio.device); - - for (unsigned i = 0; i < 7; i++) - { - char cfg[64]; - snprintf(cfg, sizeof(cfg), "input_dpad_emulation_p%u", i + 1); - config_set_int(conf, cfg, g_settings.input.dpad_emulation[i]); - } - -#ifdef RARCH_CONSOLE - config_set_bool(conf, "fbo_enabled", g_console.fbo_enabled); -#ifdef __CELLOS_LV2__ - config_set_bool(conf, "custom_bgm_enable", g_console.custom_bgm_enable); -#endif - config_set_bool(conf, "overscan_enable", g_console.overscan_enable); - config_set_bool(conf, "screenshots_enable", g_console.screenshots_enable); -#ifdef _XBOX - config_set_bool(conf, "gamma_correction_enable", g_console.gamma_correction_enable); - config_set_int(conf, "color_format", g_console.color_format); -#endif - config_set_bool(conf, "throttle_enable", g_console.throttle_enable); - config_set_bool(conf, "triple_buffering_enable", g_console.triple_buffering_enable); - config_set_bool(conf, "info_msg_enable", g_console.info_msg_enable); - config_set_int(conf, "sound_mode", g_console.sound_mode); - config_set_int(conf, "aspect_ratio_index", g_console.aspect_ratio_index); - config_set_int(conf, "current_resolution_id", g_console.current_resolution_id); - config_set_int(conf, "custom_viewport_width", g_console.viewports.custom_vp.width); - config_set_int(conf, "custom_viewport_height", g_console.viewports.custom_vp.height); - config_set_int(conf, "custom_viewport_x", g_console.viewports.custom_vp.x); - config_set_int(conf, "custom_viewport_y", g_console.viewports.custom_vp.y); - config_set_int(conf, "screen_orientation", g_console.screen_orientation); - config_set_string(conf, "default_rom_startup_dir", g_console.default_rom_startup_dir); - config_set_float(conf, "menu_font_size", g_console.menu_font_size); - config_set_float(conf, "overscan_amount", g_console.overscan_amount); -#endif - - // g_extern - config_set_int(conf, "state_slot", g_extern.state_slot); - config_set_int(conf, "audio_mute", g_extern.audio_data.mute); - - if (!config_file_write(conf, conf_name)) - RARCH_ERR("Failed to write config file to \"%s\". Check permissions.\n", conf_name); - - free(conf); - } -} -#endif diff --git a/console/retroarch_console.h b/console/retroarch_console.h index 9174f5d010..7931eac951 100644 --- a/console/retroarch_console.h +++ b/console/retroarch_console.h @@ -114,12 +114,6 @@ extern struct aspect_ratio_elem aspectratio_lut[ASPECT_RATIO_END]; extern void rarch_set_auto_viewport(unsigned width, unsigned height); extern void rarch_load_shader(unsigned slot, const char *path); -#include "retroarch_console_input.h" - -/*============================================================ - SOUND -============================================================ */ - enum { SOUND_MODE_NORMAL, @@ -131,9 +125,6 @@ enum #endif }; -/*============================================================ - ROM EXTENSIONS -============================================================ */ typedef struct { char menu_border_file[PATH_MAX]; @@ -164,15 +155,6 @@ typedef struct extern default_paths_t default_paths; -void rarch_console_load_game(const char *path); - -// Get rom extensions for current library. -// Returns NULL if library doesn't have any preferences in particular. -const char *rarch_console_get_rom_ext(void); - -// Transforms a library id to a name suitable as a pathname. -void rarch_console_name_from_id(char *name, size_t size); - /*============================================================ RetroArch ============================================================ */ @@ -230,13 +212,9 @@ const char * rarch_convert_wchar_to_const_char(const wchar_t * wstr); enum { - CONFIG_FILE, - SHADER_PRESET_FILE, - INPUT_PRESET_FILE + MODE_EMULATION = 0, + MODE_MENU, + MODE_EXIT }; -void rarch_config_create_default(const char * conf_name); -void rarch_config_load(const char * conf_name, const char * libretro_dir_path, const char * exe_ext, bool find_libretro_path); -void rarch_config_save(const char * conf_name); - #endif diff --git a/console/retroarch_console_input.h b/console/retroarch_console_input.h index 3063bf57a8..4f2e86890c 100644 --- a/console/retroarch_console_input.h +++ b/console/retroarch_console_input.h @@ -27,13 +27,6 @@ enum keybind_set_id KEYBIND_DEFAULT }; -enum -{ - MODE_EMULATION = 0, - MODE_MENU, - MODE_EXIT -}; - enum { DPAD_EMULATION_NONE = 0, diff --git a/console/retroarch_rom_ext.c b/console/retroarch_rom_ext.c new file mode 100644 index 0000000000..eb4e3b163f --- /dev/null +++ b/console/retroarch_rom_ext.c @@ -0,0 +1,80 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2012 - Hans-Kristian Arntzen + * Copyright (C) 2011-2012 - Daniel De Matteis + * + * RetroArch 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. + * + * RetroArch 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 RetroArch. + * If not, see . + */ + +#include +#include + +#include "../general.h" + +#include "console_settings.h" + +#include "retroarch_rom_ext.h" + +void rarch_console_load_game(const char *path) +{ + snprintf(g_console.rom_path, sizeof(g_console.rom_path), path); + rarch_settings_change(S_START_RARCH); +} + +const char *rarch_console_get_rom_ext(void) +{ + const char *retval = NULL; + + struct retro_system_info info; +#ifdef ANDROID + pretro_get_system_info(&info); +#else + retro_get_system_info(&info); +#endif + + if (info.valid_extensions) + retval = info.valid_extensions; + else + retval = "ZIP|zip"; + + return retval; +} + +void rarch_console_name_from_id(char *name, size_t size) +{ + if (size == 0) + return; + + struct retro_system_info info; +#ifdef ANDROID + pretro_get_system_info(&info); +#else + retro_get_system_info(&info); +#endif + const char *id = info.library_name ? info.library_name : "Unknown"; + + if (!id || strlen(id) >= size) + { + name[0] = '\0'; + return; + } + + name[strlen(id)] = '\0'; + + for (size_t i = 0; id[i] != '\0'; i++) + { + char c = id[i]; + if (isspace(c) || isblank(c)) + name[i] = '_'; + else + name[i] = tolower(c); + } +} diff --git a/console/retroarch_rom_ext.h b/console/retroarch_rom_ext.h new file mode 100644 index 0000000000..92a56a5e32 --- /dev/null +++ b/console/retroarch_rom_ext.h @@ -0,0 +1,29 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2012 - Hans-Kristian Arntzen + * Copyright (C) 2011-2012 - Daniel De Matteis + * + * RetroArch 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. + * + * RetroArch 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 RetroArch. + * If not, see . + */ + +#ifndef RARCH_ROM_EXT_H__ +#define RARCH_ROM_EXT_H__ + +void rarch_console_load_game(const char *path); + +// Get rom extensions for current library. +// Returns NULL if library doesn't have any preferences in particular. +const char *rarch_console_get_rom_ext(void); + +// Transforms a library id to a name suitable as a pathname. +void rarch_console_name_from_id(char *name, size_t size); + +#endif diff --git a/ps3/frontend/main.c b/ps3/frontend/main.c index 800aae82f9..4cf8691ca9 100644 --- a/ps3/frontend/main.c +++ b/ps3/frontend/main.c @@ -46,6 +46,8 @@ #include "../../gfx/gl_common.h" #include "../../console/retroarch_console.h" +#include "../../console/retroarch_console_input.h" +#include "../../console/retroarch_config.h" #include "../../conf/config_file.h" #include "../../conf/config_file_macros.h" #include "../../general.h" diff --git a/ps3/frontend/menu.c b/ps3/frontend/menu.c index bc0e559c41..26c02f5052 100644 --- a/ps3/frontend/menu.c +++ b/ps3/frontend/menu.c @@ -27,6 +27,9 @@ #include "../../console/fileio/file_browser.h" #include "../../console/retroarch_console.h" +#include "../../console/retroarch_rom_ext.h" +#include "../../console/retroarch_console_input.h" +#include "../../console/retroarch_config.h" #ifdef HAVE_ZLIB #include "../../console/retroarch_rzlib.h" diff --git a/xdk/frontend/main.c b/xdk/frontend/main.c index 4d3c5ee3ba..82baaaba7e 100644 --- a/xdk/frontend/main.c +++ b/xdk/frontend/main.c @@ -38,6 +38,7 @@ #endif #include "../../console/retroarch_console.h" +#include "../../console/retroarch_config.h" #include "../../conf/config_file.h" #include "../../conf/config_file_macros.h" #include "../../file.h" From 5087d9f69c7b20a5ad56210c11d8c1382fb7106a Mon Sep 17 00:00:00 2001 From: twinaphex Date: Wed, 25 Jul 2012 23:24:38 +0200 Subject: [PATCH 48/51] (Xbox 1) build fix --- console/retroarch_console.c | 4 ---- console/retroarch_rom_ext.c | 4 ++++ xbox1/xinput_xbox_input.c | 1 + 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/console/retroarch_console.c b/console/retroarch_console.c index 62ab43d73e..30497ba745 100644 --- a/console/retroarch_console.c +++ b/console/retroarch_console.c @@ -26,10 +26,6 @@ #include "retroarch_console.h" #include "../file.h" -#ifdef _WIN32 -#include "../compat/posix_string.h" -#endif - #define MAX_ARGS 32 default_paths_t default_paths; diff --git a/console/retroarch_rom_ext.c b/console/retroarch_rom_ext.c index eb4e3b163f..d49fa84a83 100644 --- a/console/retroarch_rom_ext.c +++ b/console/retroarch_rom_ext.c @@ -17,6 +17,10 @@ #include #include +#ifdef _WIN32 +#include "../compat/posix_string.h" +#endif + #include "../general.h" #include "console_settings.h" diff --git a/xbox1/xinput_xbox_input.c b/xbox1/xinput_xbox_input.c index c680c5072d..f9af267ba2 100644 --- a/xbox1/xinput_xbox_input.c +++ b/xbox1/xinput_xbox_input.c @@ -86,6 +86,7 @@ static void xinput_input_poll(void *data) { XINPUT_STATE state[4]; XINPUT_CAPABILITIES caps[4]; + (void)caps; real_state[i] = 0; // handle removed devices bRemoved[i] = (dwRemovals & (1< Date: Wed, 25 Jul 2012 23:31:15 +0200 Subject: [PATCH 49/51] (PS3) Small cleanup in ps3_audio.c --- ps3/ps3_audio.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/ps3/ps3_audio.c b/ps3/ps3_audio.c index 993906e0a4..7c53fde37f 100644 --- a/ps3/ps3_audio.c +++ b/ps3/ps3_audio.c @@ -136,9 +136,7 @@ static void *ps3_audio_init(const char *device, unsigned rate, unsigned latency) sys_lwmutex_attribute_t lock_attr; sys_lwmutex_attribute_t cond_lock_attr; sys_lwcond_attribute_t cond_attr; -#endif -#ifndef __PSL1GHT__ sys_lwmutex_attribute_initialize(lock_attr); sys_lwmutex_attribute_initialize(cond_lock_attr); sys_lwcond_attribute_initialize(cond_attr); From 19836d5f4c4eab0f7701075ef3053c62d5d1eed4 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Thu, 26 Jul 2012 00:35:51 +0200 Subject: [PATCH 50/51] (RGL) Tweaks --- console/rgl/ps3/device_ctx.cpp | 9 ++------- ps3/sdk_defines.h | 8 +++++++- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/console/rgl/ps3/device_ctx.cpp b/console/rgl/ps3/device_ctx.cpp index cbd08e8c44..34e3b2757e 100644 --- a/console/rgl/ps3/device_ctx.cpp +++ b/console/rgl/ps3/device_ctx.cpp @@ -189,8 +189,6 @@ void _RGLFifoFinish( RGLFifo *fifo ) { if ( !_RGLFifoReferenceInUse( fifo, ref ) ) break; - - sys_timer_usleep( 10 ); } } @@ -225,7 +223,6 @@ static void _RGLFifoInit( RGLFifo *fifo, void *dmaControl, unsigned long dmaPush { if ( _RGLFifoReadReference( fifo ) == 0 ) break; - sys_timer_usleep( 10 ); } } fifo->dmaPushBufferGPU = dmaPushBuffer; @@ -521,7 +518,6 @@ int32_t _RGLOutOfSpaceCallback( struct CellGcmContextData* fifoContext, uint32_t || (get < fifo->dmaPushBufferOffset) || (get > fifo->dmaPushBufferOffset + fifo->dmaPushBufferSizeInWords*sizeof(uint32_t))) { - sys_timer_usleep(30); get = fifo->dmaControl->Get; } @@ -586,7 +582,7 @@ static int _RGLInitRM( RGLResource *gcmResource, unsigned int hostMemorySize, in gcmResource->semaphores = ( RGLSemaphoreMemory * )cellGcmGetLabelAddress( 0 ); gcmResource->dmaControl = ( char* ) cellGcmGetControlRegister() - (( char * ) & (( RGLControlDma* )0 )->Put - ( char * )0 ); - cellGcmFinish( 1 ); + cellGcmFinish(1); gcmResource->hostMemorySize -= dmaPushBufferSize + _RGL_DMA_PUSH_BUFFER_PREFETCH_PADDING; gcmResource->dmaPushBuffer = gcmResource->hostMemoryBase + gcmResource->hostMemorySize; @@ -1294,8 +1290,7 @@ static inline void _RGLUtilWaitForIdle (void) cellGcmSetWriteBackEndLabelInline( &_RGLState.fifo, RGL_UTIL_LABEL_INDEX, _RGLState.labelValue); cellGcmFlush(); - while( *(cellGcmGetLabelAddress( RGL_UTIL_LABEL_INDEX)) != _RGLState.labelValue) - sys_timer_usleep(30); + while( *(cellGcmGetLabelAddress( RGL_UTIL_LABEL_INDEX)) != _RGLState.labelValue); _RGLState.labelValue++; } diff --git a/ps3/sdk_defines.h b/ps3/sdk_defines.h index 0264488543..72c5570d95 100644 --- a/ps3/sdk_defines.h +++ b/ps3/sdk_defines.h @@ -413,7 +413,6 @@ #define CellVideoOutResolution videoResolution #define CellVideoOutState videoState -#define CellRescPalTemporalMode rescPalTemporalMode #define CellRescInitConfig rescInitConfig #define CellRescSrc rescSrc #define CellRescBufferMode rescBufferMode @@ -422,6 +421,8 @@ #define memoryFrequency memoryFreq #define coreFrequency coreFreq +#define cellGcmFinish rsxFinish + #define cellGcmGetFlipStatus gcmGetFlipStatus #define cellGcmResetFlipStatus gcmResetFlipStatus #define cellGcmSetWaitFlip gcmSetWaitFlip @@ -441,6 +442,11 @@ #define cellGcmSetTileInfo gcmSetTileInfo #define cellGcmAddressToOffset gcmAddressToOffset +#define cellRescCreateInterlaceTable rescCreateInterlaceTable +#define cellRescSetDisplayMode rescSetDisplayMode +#define cellRescGetNumColorBuffers rescGetNumColorBuffers +#define cellRescGetBufferSize rescGetBufferSize +#define cellRescSetBufferAddress rescSetBufferAddress #define cellRescGetFlipStatus rescGetFlipStatus #define cellRescResetFlipStatus rescResetFlipStatus #define cellRescSetConvertAndFlip rescSetConvertAndFlip From 61c5bef909a45c23b83edc97fe974fc0fa4dc95a Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Thu, 26 Jul 2012 00:49:09 +0200 Subject: [PATCH 51/51] (RGL PS3) Get rid of 30 microsecond sleep --- console/rgl/ps3/rgl.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/console/rgl/ps3/rgl.cpp b/console/rgl/ps3/rgl.cpp index a27fedf933..6c3ce76112 100644 --- a/console/rgl/ps3/rgl.cpp +++ b/console/rgl/ps3/rgl.cpp @@ -2414,8 +2414,6 @@ char *gmmIdToAddress(const uint32_t id) if (cachedLockValue == 0) break; - - sys_timer_usleep(30); }while(1); return (char *)pBaseBlock->address;