Update svn:eol-style=native ( r1442 ) for Source/*.cpp

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2384 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
LPFaint99
2009-02-23 06:15:48 +00:00
parent 472582022b
commit 578c402d2c
41 changed files with 13757 additions and 13757 deletions

View File

@ -1,56 +1,56 @@
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2008 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0. // the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details. // GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program. // A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/ // If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at // Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
#include "Common.h" #include "Common.h"
#include "ColorUtil.h" #include "ColorUtil.h"
namespace ColorUtil namespace ColorUtil
{ {
const int lut5to8[] = { 0x00,0x08,0x10,0x18,0x20,0x29,0x31,0x39, const int lut5to8[] = { 0x00,0x08,0x10,0x18,0x20,0x29,0x31,0x39,
0x41,0x4A,0x52,0x5A,0x62,0x6A,0x73,0x7B, 0x41,0x4A,0x52,0x5A,0x62,0x6A,0x73,0x7B,
0x83,0x8B,0x94,0x9C,0xA4,0xAC,0xB4,0xBD, 0x83,0x8B,0x94,0x9C,0xA4,0xAC,0xB4,0xBD,
0xC5,0xCD,0xD5,0xDE,0xE6,0xEE,0xF6,0xFF }; 0xC5,0xCD,0xD5,0xDE,0xE6,0xEE,0xF6,0xFF };
const int lut4to8[] = { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77, const int lut4to8[] = { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,
0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF }; 0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF };
const int lut3to8[] = { 0x00,0x24,0x48,0x6D,0x91,0xB6,0xDA,0xFF }; const int lut3to8[] = { 0x00,0x24,0x48,0x6D,0x91,0xB6,0xDA,0xFF };
u32 Decode5A3(u16 val) u32 Decode5A3(u16 val)
{ {
const u32 bg_color = 0x00000000; const u32 bg_color = 0x00000000;
int r, g, b, a; int r, g, b, a;
if (val & 0x8000) if (val & 0x8000)
{ {
r = lut5to8[(val >> 10) & 0x1f]; r = lut5to8[(val >> 10) & 0x1f];
g = lut5to8[(val >> 5) & 0x1f]; g = lut5to8[(val >> 5) & 0x1f];
b = lut5to8[(val) & 0x1f]; b = lut5to8[(val) & 0x1f];
a = 0xFF; a = 0xFF;
} }
else else
{ {
a = lut3to8[(val >> 12) & 0x7]; a = lut3to8[(val >> 12) & 0x7];
r = (lut4to8[(val >> 8) & 0xf] * a + (bg_color & 0xFF) * (255 - a)) / 255; r = (lut4to8[(val >> 8) & 0xf] * a + (bg_color & 0xFF) * (255 - a)) / 255;
g = (lut4to8[(val >> 4) & 0xf] * a + ((bg_color >> 8) & 0xFF) * (255 - a)) / 255; g = (lut4to8[(val >> 4) & 0xf] * a + ((bg_color >> 8) & 0xFF) * (255 - a)) / 255;
b = (lut4to8[(val) & 0xf] * a + ((bg_color >> 16) & 0xFF) * (255 - a)) / 255; b = (lut4to8[(val) & 0xf] * a + ((bg_color >> 16) & 0xFF) * (255 - a)) / 255;
a = 0xFF; a = 0xFF;
} }
return (a << 24) | (r << 16) | (g << 8) | b; return (a << 24) | (r << 16) | (g << 8) | b;
} }
} // namespace } // namespace

View File

@ -1,198 +1,198 @@
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2008 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0. // the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details. // GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program. // A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/ // If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at // Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
// Includes // Includes
#include <string> // System: To be able to add strings with "+" #include <string> // System: To be able to add strings with "+"
#include <stdio.h> #include <stdio.h>
#ifdef _WIN32 #ifdef _WIN32
#include <windows.h> #include <windows.h>
#else #else
#include <stdarg.h> #include <stdarg.h>
#endif #endif
#include "Common.h" #include "Common.h"
#include "ConsoleWindow.h" // Common #include "ConsoleWindow.h" // Common
// Declarations and definitions // Declarations and definitions
namespace Console namespace Console
{ {
// Create handles // Create handles
FILE* __fStdOut = NULL; FILE* __fStdOut = NULL;
#ifdef _WIN32 #ifdef _WIN32
HANDLE __hStdOut = NULL; HANDLE __hStdOut = NULL;
#endif #endif
/* Start console window - width and height is the size of console window, if you enable /* Start console window - width and height is the size of console window, if you enable
File the output will also be written to this file. */ File the output will also be written to this file. */
void Open(int Width, int Height, char * Name, bool File) void Open(int Width, int Height, char * Name, bool File)
{ {
#ifdef _WIN32 #ifdef _WIN32
// Open the console window and create the window handle for GetStdHandle() // Open the console window and create the window handle for GetStdHandle()
AllocConsole(); AllocConsole();
// Save the window handle that AllocConsole() created // Save the window handle that AllocConsole() created
__hStdOut = GetStdHandle(STD_OUTPUT_HANDLE); __hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
// Set the console window title // Set the console window title
SetConsoleTitle(Name); SetConsoleTitle(Name);
// Set the total letter space // Set the total letter space
COORD co = {Width, Height}; COORD co = {Width, Height};
SetConsoleScreenBufferSize(__hStdOut, co); SetConsoleScreenBufferSize(__hStdOut, co);
/* Set the window size in number of letters. The height is hardcoded here because it can /* Set the window size in number of letters. The height is hardcoded here because it can
be changed with MoveWindow() later */ be changed with MoveWindow() later */
SMALL_RECT coo = {0,0, (Width - 1),50}; // Top, left, right, bottom SMALL_RECT coo = {0,0, (Width - 1),50}; // Top, left, right, bottom
SetConsoleWindowInfo(__hStdOut, TRUE, &coo); SetConsoleWindowInfo(__hStdOut, TRUE, &coo);
#endif #endif
// Create a file and a file handle if File is enabled and we don't already have a file handle // Create a file and a file handle if File is enabled and we don't already have a file handle
if(File && !__fStdOut) if(File && !__fStdOut)
{ {
// Edit the log file name // Edit the log file name
std::string FileEnding = ".log"; std::string FileEnding = ".log";
std::string FileName = Name; std::string FileName = Name;
std::string FullFilename = (FileName + FileEnding); std::string FullFilename = (FileName + FileEnding);
// Open the file handle // Open the file handle
__fStdOut = fopen(FullFilename.c_str(), "w"); __fStdOut = fopen(FullFilename.c_str(), "w");
} }
} }
/* Close the console window and close the eventual file handle */ /* Close the console window and close the eventual file handle */
void Close() void Close()
{ {
#ifdef _WIN32 #ifdef _WIN32
FreeConsole(); // Close the console window FreeConsole(); // Close the console window
#endif #endif
if(__fStdOut) fclose(__fStdOut); // Close the file handle if(__fStdOut) fclose(__fStdOut); // Close the file handle
} }
// Print to screen and file // Print to screen and file
int Print(const char *fmt, ...) int Print(const char *fmt, ...)
{ {
// Maximum bytes, mind this value to avoid an overrun // Maximum bytes, mind this value to avoid an overrun
static const int MAX_BYTES = 1024*20; static const int MAX_BYTES = 1024*20;
#if defined(_WIN32) #if defined(_WIN32)
if(__hStdOut) if(__hStdOut)
{ {
#endif #endif
char s[MAX_BYTES]; char s[MAX_BYTES];
va_list argptr; va_list argptr;
int cnt; // To store the vsnprintf return message int cnt; // To store the vsnprintf return message
va_start(argptr, fmt); va_start(argptr, fmt);
cnt = vsnprintf(s, MAX_BYTES, fmt, argptr); cnt = vsnprintf(s, MAX_BYTES, fmt, argptr);
va_end(argptr); va_end(argptr);
#if defined(_WIN32) #if defined(_WIN32)
DWORD cCharsWritten; // We will get a value back here DWORD cCharsWritten; // We will get a value back here
WriteConsole(__hStdOut, s, (DWORD)strlen(s), &cCharsWritten, NULL); WriteConsole(__hStdOut, s, (DWORD)strlen(s), &cCharsWritten, NULL);
#else #else
fprintf(stderr, "%s", s); fprintf(stderr, "%s", s);
#endif #endif
// Write to the file // Write to the file
if(__fStdOut) if(__fStdOut)
{ {
fprintf(__fStdOut, "%s", s); fprintf(__fStdOut, "%s", s);
fflush(__fStdOut); // Write file now, don't wait fflush(__fStdOut); // Write file now, don't wait
} }
return(cnt); return(cnt);
#if defined(_WIN32) #if defined(_WIN32)
} else } else
{ {
return 0; return 0;
} }
#endif #endif
} }
// Clear console screen // Clear console screen
void ClearScreen() void ClearScreen()
{ {
#if defined(_WIN32) #if defined(_WIN32)
if(__hStdOut) // Check that we have a window handle if(__hStdOut) // Check that we have a window handle
{ {
COORD coordScreen = { 0, 0 }; COORD coordScreen = { 0, 0 };
DWORD cCharsWritten; DWORD cCharsWritten;
CONSOLE_SCREEN_BUFFER_INFO csbi; CONSOLE_SCREEN_BUFFER_INFO csbi;
DWORD dwConSize; DWORD dwConSize;
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
GetConsoleScreenBufferInfo(hConsole, &csbi); GetConsoleScreenBufferInfo(hConsole, &csbi);
dwConSize = csbi.dwSize.X * csbi.dwSize.Y; dwConSize = csbi.dwSize.X * csbi.dwSize.Y;
FillConsoleOutputCharacter(hConsole, TEXT(' '), dwConSize, FillConsoleOutputCharacter(hConsole, TEXT(' '), dwConSize,
coordScreen, &cCharsWritten); coordScreen, &cCharsWritten);
GetConsoleScreenBufferInfo(hConsole, &csbi); GetConsoleScreenBufferInfo(hConsole, &csbi);
FillConsoleOutputAttribute(hConsole, csbi.wAttributes, dwConSize, FillConsoleOutputAttribute(hConsole, csbi.wAttributes, dwConSize,
coordScreen, &cCharsWritten); coordScreen, &cCharsWritten);
SetConsoleCursorPosition(hConsole, coordScreen); SetConsoleCursorPosition(hConsole, coordScreen);
} }
#endif #endif
} }
/* Get window handle of console window to be able to resize it. We use /* Get window handle of console window to be able to resize it. We use
GetConsoleTitle() and FindWindow() to locate the console window handle. */ GetConsoleTitle() and FindWindow() to locate the console window handle. */
#if defined(_WIN32) #if defined(_WIN32)
HWND GetHwnd(void) HWND GetHwnd(void)
{ {
#define MY_BUFSIZE 1024 // Buffer size for console window titles #define MY_BUFSIZE 1024 // Buffer size for console window titles
HWND hwndFound; // This is what is returned to the caller HWND hwndFound; // This is what is returned to the caller
char pszNewWindowTitle[MY_BUFSIZE]; // Contains fabricated WindowTitle char pszNewWindowTitle[MY_BUFSIZE]; // Contains fabricated WindowTitle
char pszOldWindowTitle[MY_BUFSIZE]; // Contains original WindowTitle char pszOldWindowTitle[MY_BUFSIZE]; // Contains original WindowTitle
// Fetch current window title. // Fetch current window title.
GetConsoleTitle(pszOldWindowTitle, MY_BUFSIZE); GetConsoleTitle(pszOldWindowTitle, MY_BUFSIZE);
// Format a "unique" NewWindowTitle // Format a "unique" NewWindowTitle
wsprintf(pszNewWindowTitle, "%d/%d", GetTickCount(), GetCurrentProcessId()); wsprintf(pszNewWindowTitle, "%d/%d", GetTickCount(), GetCurrentProcessId());
// Change current window title // Change current window title
SetConsoleTitle(pszNewWindowTitle); SetConsoleTitle(pszNewWindowTitle);
// Ensure window title has been updated // Ensure window title has been updated
Sleep(40); Sleep(40);
// Look for NewWindowTitle // Look for NewWindowTitle
hwndFound = FindWindow(NULL, pszNewWindowTitle); hwndFound = FindWindow(NULL, pszNewWindowTitle);
// Restore original window title // Restore original window title
SetConsoleTitle(pszOldWindowTitle); SetConsoleTitle(pszOldWindowTitle);
return(hwndFound); return(hwndFound);
} }
#endif // _WIN32 #endif // _WIN32
} // namespace } // namespace

View File

@ -1,82 +1,82 @@
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2008 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0. // the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details. // GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program. // A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/ // If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at // Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////
// Include and declarations // Include and declarations
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#include <stdio.h> // System #include <stdio.h> // System
#include "Common.h" // Local #include "Common.h" // Local
#include "StringUtil.h" #include "StringUtil.h"
bool DefaultMsgHandler(const char* caption, const char* text, bool yes_no, int Style); bool DefaultMsgHandler(const char* caption, const char* text, bool yes_no, int Style);
static MsgAlertHandler msg_handler = DefaultMsgHandler; static MsgAlertHandler msg_handler = DefaultMsgHandler;
///////////////////////////// /////////////////////////////
/* Select which of these functions that are used for message boxes. If wxWidgets is enabled /* Select which of these functions that are used for message boxes. If wxWidgets is enabled
we will use wxMsgAlert() that is defined in main.cpp */ we will use wxMsgAlert() that is defined in main.cpp */
void RegisterMsgAlertHandler(MsgAlertHandler handler) void RegisterMsgAlertHandler(MsgAlertHandler handler)
{ {
msg_handler = handler; msg_handler = handler;
} }
///////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////
/* This is the first stop for messages where the log is updated and the correct windows /* This is the first stop for messages where the log is updated and the correct windows
is shown */ is shown */
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
bool MsgAlert(const char* caption, bool yes_no, int Style, const char* format, ...) bool MsgAlert(const char* caption, bool yes_no, int Style, const char* format, ...)
{ {
// --------------------------------- // ---------------------------------
// Read message and write it to the log // Read message and write it to the log
// ----------- // -----------
char buffer[2048]; char buffer[2048];
bool ret = false; bool ret = false;
va_list args; va_list args;
va_start(args, format); va_start(args, format);
CharArrayFromFormatV(buffer, 2047, format, args); CharArrayFromFormatV(buffer, 2047, format, args);
va_end(args); va_end(args);
LOG(MASTER_LOG, "%s: %s", caption, buffer); LOG(MASTER_LOG, "%s: %s", caption, buffer);
// ----------- // -----------
if (msg_handler) { if (msg_handler) {
ret = msg_handler(caption, buffer, yes_no, Style); ret = msg_handler(caption, buffer, yes_no, Style);
} }
return ret; return ret;
} }
///////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////
/* This is used in the No-GUI build */ /* This is used in the No-GUI build */
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
bool DefaultMsgHandler(const char* caption, const char* text, bool yes_no, int Style) bool DefaultMsgHandler(const char* caption, const char* text, bool yes_no, int Style)
{ {
#ifdef _WIN32 #ifdef _WIN32
int STYLE = MB_ICONINFORMATION; int STYLE = MB_ICONINFORMATION;
if (Style == QUESTION) STYLE = MB_ICONQUESTION; if (Style == QUESTION) STYLE = MB_ICONQUESTION;
if (Style == WARNING) STYLE = MB_ICONWARNING; if (Style == WARNING) STYLE = MB_ICONWARNING;
return IDYES == MessageBox(0, text, caption, STYLE | (yes_no ? MB_YESNO : MB_OK)); return IDYES == MessageBox(0, text, caption, STYLE | (yes_no ? MB_YESNO : MB_OK));
#else #else
printf("%s\n", text); printf("%s\n", text);
return true; return true;
#endif #endif
} }

View File

@ -1,279 +1,279 @@
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2008 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0. // the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details. // GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program. // A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/ // If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at // Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
#include "Boot.h" #include "Boot.h"
#include "../PowerPC/PowerPC.h" #include "../PowerPC/PowerPC.h"
#include "../HLE/HLE.h" #include "../HLE/HLE.h"
#include "../HW/Memmap.h" #include "../HW/Memmap.h"
#include "../ConfigManager.h" #include "../ConfigManager.h"
#include "Blob.h" #include "Blob.h"
#include "MappedFile.h" #include "MappedFile.h"
#include "Boot_DOL.h" #include "Boot_DOL.h"
#include "Boot_WiiWAD.h" #include "Boot_WiiWAD.h"
#include "AES/aes.h" #include "AES/aes.h"
#include "MathUtil.h" #include "MathUtil.h"
class CBlobBigEndianReader class CBlobBigEndianReader
{ {
public: public:
CBlobBigEndianReader(DiscIO::IBlobReader& _rReader) : m_rReader(_rReader) {} CBlobBigEndianReader(DiscIO::IBlobReader& _rReader) : m_rReader(_rReader) {}
u32 Read32(u64 _Offset) u32 Read32(u64 _Offset)
{ {
u32 Temp; u32 Temp;
m_rReader.Read(_Offset, 4, (u8*)&Temp); m_rReader.Read(_Offset, 4, (u8*)&Temp);
return(Common::swap32(Temp)); return(Common::swap32(Temp));
} }
private: private:
DiscIO::IBlobReader& m_rReader; DiscIO::IBlobReader& m_rReader;
}; };
std::vector<STileMetaContent> m_TileMetaContent; std::vector<STileMetaContent> m_TileMetaContent;
u16 m_BootIndex = -1; u16 m_BootIndex = -1;
void AESDecode(u8* _pKey, u8* _IV, u8* _pSrc, u32 _Size, u8* _pDest) void AESDecode(u8* _pKey, u8* _IV, u8* _pSrc, u32 _Size, u8* _pDest)
{ {
AES_KEY AESKey; AES_KEY AESKey;
AES_set_decrypt_key(_pKey, 128, &AESKey); AES_set_decrypt_key(_pKey, 128, &AESKey);
AES_cbc_encrypt(_pSrc, _pDest, _Size, &AESKey, _IV, AES_DECRYPT); AES_cbc_encrypt(_pSrc, _pDest, _Size, &AESKey, _IV, AES_DECRYPT);
} }
u8* CreateWADEntry(DiscIO::IBlobReader& _rReader, u32 _Size, u64 _Offset) u8* CreateWADEntry(DiscIO::IBlobReader& _rReader, u32 _Size, u64 _Offset)
{ {
if (_Size > 0) if (_Size > 0)
{ {
u8* pTmpBuffer = new u8[_Size]; u8* pTmpBuffer = new u8[_Size];
_dbg_assert_msg_(BOOT, pTmpBuffer!=0, "WiiWAD: Cant allocate memory for WAD entry"); _dbg_assert_msg_(BOOT, pTmpBuffer!=0, "WiiWAD: Cant allocate memory for WAD entry");
if (!_rReader.Read(_Offset, _Size, pTmpBuffer)) if (!_rReader.Read(_Offset, _Size, pTmpBuffer))
{ {
PanicAlert("WiiWAD: Could not read from file"); PanicAlert("WiiWAD: Could not read from file");
} }
return pTmpBuffer; return pTmpBuffer;
} }
return NULL; return NULL;
} }
void GetKeyFromTicket(u8* pTicket, u8* pTicketKey) void GetKeyFromTicket(u8* pTicket, u8* pTicketKey)
{ {
u8 CommonKey[16]; u8 CommonKey[16];
FILE* pMasterKeyFile = fopen(WII_MASTERKEY_FILE, "rb"); FILE* pMasterKeyFile = fopen(WII_MASTERKEY_FILE, "rb");
_dbg_assert_msg_(BOOT, pMasterKeyFile!=0x0, "WiiWAD: Cant open MasterKeyFile for WII"); _dbg_assert_msg_(BOOT, pMasterKeyFile!=0x0, "WiiWAD: Cant open MasterKeyFile for WII");
if (pMasterKeyFile) if (pMasterKeyFile)
{ {
fread(CommonKey, 16, 1, pMasterKeyFile); fread(CommonKey, 16, 1, pMasterKeyFile);
fclose(pMasterKeyFile); fclose(pMasterKeyFile);
u8 IV[16]; u8 IV[16];
memset(IV, 0, sizeof IV); memset(IV, 0, sizeof IV);
memcpy(IV, pTicket + 0x01dc, 8); memcpy(IV, pTicket + 0x01dc, 8);
AESDecode(CommonKey, IV, pTicket + 0x01bf, 16, pTicketKey); AESDecode(CommonKey, IV, pTicket + 0x01bf, 16, pTicketKey);
} }
} }
bool ParseTMD(u8* pDataApp, u32 pDataAppSize, u8* pTicket, u8* pTMD) bool ParseTMD(u8* pDataApp, u32 pDataAppSize, u8* pTicket, u8* pTMD)
{ {
u8 DecryptTitleKey[16]; u8 DecryptTitleKey[16];
u8 IV[16]; u8 IV[16];
GetKeyFromTicket(pTicket, DecryptTitleKey); GetKeyFromTicket(pTicket, DecryptTitleKey);
u32 numEntries = Common::swap16(pTMD + 0x01de); u32 numEntries = Common::swap16(pTMD + 0x01de);
m_BootIndex = Common::swap16(pTMD + 0x01e0); m_BootIndex = Common::swap16(pTMD + 0x01e0);
u8* p = pDataApp; u8* p = pDataApp;
m_TileMetaContent.resize(numEntries); m_TileMetaContent.resize(numEntries);
for (u32 i=0; i<numEntries; i++) for (u32 i=0; i<numEntries; i++)
{ {
STileMetaContent& rContent = m_TileMetaContent[i]; STileMetaContent& rContent = m_TileMetaContent[i];
rContent.m_ContentID = Common::swap32(pTMD + 0x01e4 + 0x24*i); rContent.m_ContentID = Common::swap32(pTMD + 0x01e4 + 0x24*i);
rContent.m_Index = Common::swap16(pTMD + 0x01e8 + 0x24*i); rContent.m_Index = Common::swap16(pTMD + 0x01e8 + 0x24*i);
rContent.m_Type = Common::swap16(pTMD + 0x01ea + 0x24*i); rContent.m_Type = Common::swap16(pTMD + 0x01ea + 0x24*i);
rContent.m_Size= (u32)ROUND_UP(Common::swap64(pTMD + 0x01ec + 0x24*i), 0x40); rContent.m_Size= (u32)ROUND_UP(Common::swap64(pTMD + 0x01ec + 0x24*i), 0x40);
rContent.m_pData = new u8[rContent.m_Size]; rContent.m_pData = new u8[rContent.m_Size];
memset(IV, 0, sizeof IV); memset(IV, 0, sizeof IV);
memcpy(IV, pTMD + 0x01e8 + 0x24*i, 2); memcpy(IV, pTMD + 0x01e8 + 0x24*i, 2);
AESDecode(DecryptTitleKey, IV, p, rContent.m_Size, rContent.m_pData); AESDecode(DecryptTitleKey, IV, p, rContent.m_Size, rContent.m_pData);
p += rContent.m_Size; p += rContent.m_Size;
} }
return true; return true;
} }
bool ParseWAD(DiscIO::IBlobReader& _rReader) bool ParseWAD(DiscIO::IBlobReader& _rReader)
{ {
CBlobBigEndianReader ReaderBig(_rReader); CBlobBigEndianReader ReaderBig(_rReader);
// get header size // get header size
u32 HeaderSize = ReaderBig.Read32(0); u32 HeaderSize = ReaderBig.Read32(0);
if (HeaderSize != 0x20) if (HeaderSize != 0x20)
{ {
_dbg_assert_msg_(BOOT, (HeaderSize==0x20), "WiiWAD: Header size != 0x20"); _dbg_assert_msg_(BOOT, (HeaderSize==0x20), "WiiWAD: Header size != 0x20");
return false; return false;
} }
// get header // get header
u8 Header[0x20]; u8 Header[0x20];
_rReader.Read(0, HeaderSize, Header); _rReader.Read(0, HeaderSize, Header);
u32 HeaderType = ReaderBig.Read32(0x4); u32 HeaderType = ReaderBig.Read32(0x4);
if ((0x49730000 != HeaderType) && (0x69620000 != HeaderType)) if ((0x49730000 != HeaderType) && (0x69620000 != HeaderType))
return false; return false;
u32 CertificateChainSize = ReaderBig.Read32(0x8); u32 CertificateChainSize = ReaderBig.Read32(0x8);
u32 Reserved = ReaderBig.Read32(0xC); u32 Reserved = ReaderBig.Read32(0xC);
u32 TicketSize = ReaderBig.Read32(0x10); u32 TicketSize = ReaderBig.Read32(0x10);
u32 TMDSize = ReaderBig.Read32(0x14); u32 TMDSize = ReaderBig.Read32(0x14);
u32 DataAppSize = ReaderBig.Read32(0x18); u32 DataAppSize = ReaderBig.Read32(0x18);
u32 FooterSize = ReaderBig.Read32(0x1C); u32 FooterSize = ReaderBig.Read32(0x1C);
_dbg_assert_msg_(BOOT, Reserved==0x00, "WiiWAD: Reserved must be 0x00"); _dbg_assert_msg_(BOOT, Reserved==0x00, "WiiWAD: Reserved must be 0x00");
u32 Offset = 0x40; u32 Offset = 0x40;
u8* pCertificateChain = CreateWADEntry(_rReader, CertificateChainSize, Offset); Offset += ROUND_UP(CertificateChainSize, 0x40); u8* pCertificateChain = CreateWADEntry(_rReader, CertificateChainSize, Offset); Offset += ROUND_UP(CertificateChainSize, 0x40);
u8* pTicket = CreateWADEntry(_rReader, TicketSize, Offset); Offset += ROUND_UP(TicketSize, 0x40); u8* pTicket = CreateWADEntry(_rReader, TicketSize, Offset); Offset += ROUND_UP(TicketSize, 0x40);
u8* pTMD = CreateWADEntry(_rReader, TMDSize, Offset); Offset += ROUND_UP(TMDSize, 0x40); u8* pTMD = CreateWADEntry(_rReader, TMDSize, Offset); Offset += ROUND_UP(TMDSize, 0x40);
u8* pDataApp = CreateWADEntry(_rReader, DataAppSize, Offset); Offset += ROUND_UP(DataAppSize, 0x40); u8* pDataApp = CreateWADEntry(_rReader, DataAppSize, Offset); Offset += ROUND_UP(DataAppSize, 0x40);
u8* pFooter = CreateWADEntry(_rReader, FooterSize, Offset); Offset += ROUND_UP(FooterSize, 0x40); u8* pFooter = CreateWADEntry(_rReader, FooterSize, Offset); Offset += ROUND_UP(FooterSize, 0x40);
bool Result = ParseTMD(pDataApp, DataAppSize, pTicket, pTMD); bool Result = ParseTMD(pDataApp, DataAppSize, pTicket, pTMD);
return Result; return Result;
} }
bool CBoot::IsWiiWAD(const char* _pFileName) bool CBoot::IsWiiWAD(const char* _pFileName)
{ {
DiscIO::IBlobReader* pReader = DiscIO::CreateBlobReader(_pFileName); DiscIO::IBlobReader* pReader = DiscIO::CreateBlobReader(_pFileName);
if (pReader == NULL) if (pReader == NULL)
return false; return false;
CBlobBigEndianReader Reader(*pReader); CBlobBigEndianReader Reader(*pReader);
bool Result = false; bool Result = false;
// check for wii wad // check for wii wad
if (Reader.Read32(0x00) == 0x20) if (Reader.Read32(0x00) == 0x20)
{ {
u32 WADTYpe = Reader.Read32(0x04); u32 WADTYpe = Reader.Read32(0x04);
switch(WADTYpe) switch(WADTYpe)
{ {
case 0x49730000: case 0x49730000:
case 0x69620000: case 0x69620000:
Result = true; Result = true;
} }
} }
delete pReader; delete pReader;
return Result; return Result;
} }
void SetupWiiMem() void SetupWiiMem()
{ {
// //
// TODO: REDUDANT CODE SUX .... // TODO: REDUDANT CODE SUX ....
// //
Memory::Write_U32(0x5d1c9ea3, 0x00000018); // Magic word it is a wii disc Memory::Write_U32(0x5d1c9ea3, 0x00000018); // Magic word it is a wii disc
Memory::Write_U32(0x0D15EA5E, 0x00000020); // Another magic word Memory::Write_U32(0x0D15EA5E, 0x00000020); // Another magic word
Memory::Write_U32(0x00000001, 0x00000024); // Unknown Memory::Write_U32(0x00000001, 0x00000024); // Unknown
Memory::Write_U32(0x01800000, 0x00000028); // MEM1 size 24MB Memory::Write_U32(0x01800000, 0x00000028); // MEM1 size 24MB
Memory::Write_U32(0x00000023, 0x0000002c); // Production Board Model Memory::Write_U32(0x00000023, 0x0000002c); // Production Board Model
Memory::Write_U32(0x00000000, 0x00000030); // Init Memory::Write_U32(0x00000000, 0x00000030); // Init
Memory::Write_U32(0x817FEC60, 0x00000034); // Init Memory::Write_U32(0x817FEC60, 0x00000034); // Init
// 38, 3C should get start, size of FST through apploader // 38, 3C should get start, size of FST through apploader
Memory::Write_U32(0x38a00040, 0x00000060); // Exception init Memory::Write_U32(0x38a00040, 0x00000060); // Exception init
Memory::Write_U32(0x8008f7b8, 0x000000e4); // Thread Init Memory::Write_U32(0x8008f7b8, 0x000000e4); // Thread Init
Memory::Write_U32(0x01800000, 0x000000f0); // "Simulated memory size" (debug mode?) Memory::Write_U32(0x01800000, 0x000000f0); // "Simulated memory size" (debug mode?)
Memory::Write_U32(0x8179b500, 0x000000f4); // __start Memory::Write_U32(0x8179b500, 0x000000f4); // __start
Memory::Write_U32(0x0e7be2c0, 0x000000f8); // Bus speed Memory::Write_U32(0x0e7be2c0, 0x000000f8); // Bus speed
Memory::Write_U32(0x2B73A840, 0x000000fc); // CPU speed Memory::Write_U32(0x2B73A840, 0x000000fc); // CPU speed
Memory::Write_U16(0x0000, 0x000030e6); // Console type Memory::Write_U16(0x0000, 0x000030e6); // Console type
Memory::Write_U32(0x00000000, 0x000030c0); // EXI Memory::Write_U32(0x00000000, 0x000030c0); // EXI
Memory::Write_U32(0x00000000, 0x000030c4); // EXI Memory::Write_U32(0x00000000, 0x000030c4); // EXI
Memory::Write_U32(0x00000000, 0x000030dc); // Time Memory::Write_U32(0x00000000, 0x000030dc); // Time
Memory::Write_U32(0x00000000, 0x000030d8); // Time Memory::Write_U32(0x00000000, 0x000030d8); // Time
Memory::Write_U32(0x00000000, 0x000030f0); // Apploader Memory::Write_U32(0x00000000, 0x000030f0); // Apploader
Memory::Write_U32(0x01800000, 0x00003100); // BAT Memory::Write_U32(0x01800000, 0x00003100); // BAT
Memory::Write_U32(0x01800000, 0x00003104); // BAT Memory::Write_U32(0x01800000, 0x00003104); // BAT
Memory::Write_U32(0x00000000, 0x0000310c); // Init Memory::Write_U32(0x00000000, 0x0000310c); // Init
Memory::Write_U32(0x8179d500, 0x00003110); // Init Memory::Write_U32(0x8179d500, 0x00003110); // Init
Memory::Write_U32(0x04000000, 0x00003118); // Unknown Memory::Write_U32(0x04000000, 0x00003118); // Unknown
Memory::Write_U32(0x04000000, 0x0000311c); // BAT Memory::Write_U32(0x04000000, 0x0000311c); // BAT
Memory::Write_U32(0x93400000, 0x00003120); // BAT Memory::Write_U32(0x93400000, 0x00003120); // BAT
Memory::Write_U32(0x90000800, 0x00003124); // Init - MEM2 low Memory::Write_U32(0x90000800, 0x00003124); // Init - MEM2 low
Memory::Write_U32(0x933e0000, 0x00003128); // Init - MEM2 high Memory::Write_U32(0x933e0000, 0x00003128); // Init - MEM2 high
Memory::Write_U32(0x933e0000, 0x00003130); // IOS MEM2 low Memory::Write_U32(0x933e0000, 0x00003130); // IOS MEM2 low
Memory::Write_U32(0x93400000, 0x00003134); // IOS MEM2 high Memory::Write_U32(0x93400000, 0x00003134); // IOS MEM2 high
Memory::Write_U32(0x00000011, 0x00003138); // Console type Memory::Write_U32(0x00000011, 0x00003138); // Console type
Memory::Write_U64(0x0009020400062507ULL, 0x00003140); // IOS Version Memory::Write_U64(0x0009020400062507ULL, 0x00003140); // IOS Version
Memory::Write_U16(0x0113, 0x0000315e); // Apploader Memory::Write_U16(0x0113, 0x0000315e); // Apploader
Memory::Write_U32(0x0000FF16, 0x00003158); // DDR ram vendor code Memory::Write_U32(0x0000FF16, 0x00003158); // DDR ram vendor code
Memory::Write_U8(0x80, 0x0000315c); // OSInit Memory::Write_U8(0x80, 0x0000315c); // OSInit
Memory::Write_U8(0x00, 0x00000006); // DVDInit Memory::Write_U8(0x00, 0x00000006); // DVDInit
Memory::Write_U8(0x00, 0x00000007); // DVDInit Memory::Write_U8(0x00, 0x00000007); // DVDInit
Memory::Write_U16(0x0000, 0x000030e0); // PADInit Memory::Write_U16(0x0000, 0x000030e0); // PADInit
// Fake the VI Init of the BIOS // Fake the VI Init of the BIOS
Memory::Write_U32(SConfig::GetInstance().m_LocalCoreStartupParameter.bNTSC ? 0 : 1, 0x000000CC); Memory::Write_U32(SConfig::GetInstance().m_LocalCoreStartupParameter.bNTSC ? 0 : 1, 0x000000CC);
// Clear exception handler. Why? Don't we begin with only zeroes? // Clear exception handler. Why? Don't we begin with only zeroes?
for (int i = 0x3000; i <= 0x3038; i += 4) for (int i = 0x3000; i <= 0x3038; i += 4)
{ {
Memory::Write_U32(0x00000000, 0x80000000 + i); Memory::Write_U32(0x00000000, 0x80000000 + i);
} }
/* This is some kind of consistency check that is compared to the 0x00 /* This is some kind of consistency check that is compared to the 0x00
values as the game boots. This location keep the 4 byte ID for as long values as the game boots. This location keep the 4 byte ID for as long
as the game is running. The 6 byte ID at 0x00 is overwritten sometime as the game is running. The 6 byte ID at 0x00 is overwritten sometime
after this check during booting. */ after this check during booting. */
// VolumeHandler::ReadToPtr(Memory::GetPointer(0x3180), 0, 4); // VolumeHandler::ReadToPtr(Memory::GetPointer(0x3180), 0, 4);
// Memory::Write_U8(0x80, 0x00003184); // Memory::Write_U8(0x80, 0x00003184);
// ================ // ================
} }
bool CBoot::Boot_WiiWAD(const char* _pFilename) bool CBoot::Boot_WiiWAD(const char* _pFilename)
{ {
DiscIO::IBlobReader* pReader = DiscIO::CreateBlobReader(_pFilename); DiscIO::IBlobReader* pReader = DiscIO::CreateBlobReader(_pFilename);
if (pReader == NULL) if (pReader == NULL)
return false; return false;
bool Result = ParseWAD(*pReader); bool Result = ParseWAD(*pReader);
delete pReader; delete pReader;
if (!Result) if (!Result)
return false; return false;
SetupWiiMem(); SetupWiiMem();
// DOL // DOL
STileMetaContent& rContent = m_TileMetaContent[m_BootIndex]; STileMetaContent& rContent = m_TileMetaContent[m_BootIndex];
CDolLoader DolLoader(rContent.m_pData, rContent.m_Size); CDolLoader DolLoader(rContent.m_pData, rContent.m_Size);
PC = DolLoader.GetEntryPoint() | 0x80000000; PC = DolLoader.GetEntryPoint() | 0x80000000;
return true; return true;
} }

View File

@ -1,251 +1,251 @@
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2008 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0. // the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details. // GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program. // A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/ // If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at // Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
#include "Setup.h" #include "Setup.h"
#ifdef RERECORDING #ifdef RERECORDING
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Include // Include
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#ifdef _WIN32 #ifdef _WIN32
#include <windows.h> #include <windows.h>
#endif #endif
#include "Thread.h" // Common #include "Thread.h" // Common
#include "Timer.h" #include "Timer.h"
#include "Common.h" #include "Common.h"
#include "ConsoleWindow.h" #include "ConsoleWindow.h"
#include "Console.h" #include "Console.h"
#include "Core.h" #include "Core.h"
#include "CPUDetect.h" #include "CPUDetect.h"
#include "CoreTiming.h" #include "CoreTiming.h"
#include "Boot/Boot.h" #include "Boot/Boot.h"
#include "PatchEngine.h" #include "PatchEngine.h"
#include "HW/Memmap.h" #include "HW/Memmap.h"
#include "HW/PeripheralInterface.h" #include "HW/PeripheralInterface.h"
#include "HW/GPFifo.h" #include "HW/GPFifo.h"
#include "HW/CPU.h" #include "HW/CPU.h"
#include "HW/CPUCompare.h" #include "HW/CPUCompare.h"
#include "HW/HW.h" #include "HW/HW.h"
#include "HW/DSP.h" #include "HW/DSP.h"
#include "HW/GPFifo.h" #include "HW/GPFifo.h"
#include "HW/AudioInterface.h" #include "HW/AudioInterface.h"
#include "HW/VideoInterface.h" #include "HW/VideoInterface.h"
#include "HW/CommandProcessor.h" #include "HW/CommandProcessor.h"
#include "HW/PixelEngine.h" #include "HW/PixelEngine.h"
#include "HW/SystemTimers.h" #include "HW/SystemTimers.h"
#include "PowerPC/PowerPC.h" #include "PowerPC/PowerPC.h"
#include "PluginManager.h" #include "PluginManager.h"
#include "ConfigManager.h" #include "ConfigManager.h"
#include "MemTools.h" #include "MemTools.h"
#include "Host.h" #include "Host.h"
#include "LogManager.h" #include "LogManager.h"
//////////////////////////////////////// ////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
// File description: Rerecording Functions // File description: Rerecording Functions
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> /* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
How the timer works: We measure the time between drawn frames, not when the game is paused. So time How the timer works: We measure the time between drawn frames, not when the game is paused. So time
should be a fairly comparable measure of the time it took to play the game. However the time it takes should be a fairly comparable measure of the time it took to play the game. However the time it takes
to draw a frame will be lower on a fast computer. Therefore we could perhaps measure time as an to draw a frame will be lower on a fast computer. Therefore we could perhaps measure time as an
internal game time that is adjusted by the average time it takes to draw a frame. Also if it only takes internal game time that is adjusted by the average time it takes to draw a frame. Also if it only takes
ten or twenty milliseconds to draw a frame I'm not certain about how accurate the mmsystem timers are for ten or twenty milliseconds to draw a frame I'm not certain about how accurate the mmsystem timers are for
such short periods. such short periods.
//////////////////////////////////////*/ //////////////////////////////////////*/
namespace Core namespace Core
{ {
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
// Declarations and definitions // Declarations and definitions
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
int g_FrameCounter = 0; int g_FrameCounter = 0;
bool g_FrameStep = false; bool g_FrameStep = false;
Common::Timer ReRecTimer; Common::Timer ReRecTimer;
//////////////////////////////////////// ////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
// Control Run, Pause, Stop and the Timer. // Control Run, Pause, Stop and the Timer.
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// Subtract the paused time when we run again // Subtract the paused time when we run again
void Run() void Run()
{ {
ReRecTimer.AddTimeDifference(); ReRecTimer.AddTimeDifference();
} }
// Update the time // Update the time
void Pause() void Pause()
{ {
ReRecTimer.Update(); ReRecTimer.Update();
} }
// Start the timer when a game is booted // Start the timer when a game is booted
void RerecordingStart() void RerecordingStart()
{ {
g_FrameCounter = 0; g_FrameCounter = 0;
ReRecTimer.Start(); ReRecTimer.Start();
// Logging // Logging
//Console::Print("RerecordingStart: %i\n", g_FrameCounter); //Console::Print("RerecordingStart: %i\n", g_FrameCounter);
} }
// Reset the frame counter // Reset the frame counter
void RerecordingStop() void RerecordingStop()
{ {
// Write the final time and Stop the timer // Write the final time and Stop the timer
ReRecTimer.Stop(); ReRecTimer.Stop();
// Update status bar // Update status bar
WriteStatus(); WriteStatus();
} }
/* Wind back the frame counter when a save state is loaded. Currently we don't know what that means in /* Wind back the frame counter when a save state is loaded. Currently we don't know what that means in
time so we just guess that the time is proportional the the number of frames time so we just guess that the time is proportional the the number of frames
Todo: There are many assumptions here: We probably want to replace the time here by the actual time Todo: There are many assumptions here: We probably want to replace the time here by the actual time
that we save together with the save state or the input recording for example. And have it adjusted that we save together with the save state or the input recording for example. And have it adjusted
for full speed playback (whether it's 30 fps or 60 fps or some other speed that the game is natively for full speed playback (whether it's 30 fps or 60 fps or some other speed that the game is natively
capped at). Also the input interrupts do not occur as often as the frame renderings, they occur more capped at). Also the input interrupts do not occur as often as the frame renderings, they occur more
often. So we may want to move the input recording to fram updates, or perhaps sync the input interrupts often. So we may want to move the input recording to fram updates, or perhaps sync the input interrupts
to frame updates. to frame updates.
*/ */
void WindBack(int Counter) void WindBack(int Counter)
{ {
/* Counter should be smaller than g_FrameCounter, however it currently updates faster than the /* Counter should be smaller than g_FrameCounter, however it currently updates faster than the
frames so currently it may not be the same. Therefore I use the abs() function. */ frames so currently it may not be the same. Therefore I use the abs() function. */
int AbsoluteFrameDifference = abs(g_FrameCounter - Counter); int AbsoluteFrameDifference = abs(g_FrameCounter - Counter);
float FractionalFrameDifference = (float) AbsoluteFrameDifference / (float) g_FrameCounter; float FractionalFrameDifference = (float) AbsoluteFrameDifference / (float) g_FrameCounter;
// Update the frame counter // Update the frame counter
g_FrameCounter = Counter; g_FrameCounter = Counter;
// Approximate a time to wind back the clock to // Approximate a time to wind back the clock to
// Get the current time // Get the current time
u64 CurrentTimeMs = ReRecTimer.GetTimeElapsed(); u64 CurrentTimeMs = ReRecTimer.GetTimeElapsed();
// Save the current time in seconds in a new double // Save the current time in seconds in a new double
double CurrentTimeSeconds = (double) (CurrentTimeMs / 1000); double CurrentTimeSeconds = (double) (CurrentTimeMs / 1000);
// Reduce it by the same proportion as the counter was wound back // Reduce it by the same proportion as the counter was wound back
CurrentTimeSeconds = CurrentTimeSeconds * FractionalFrameDifference; CurrentTimeSeconds = CurrentTimeSeconds * FractionalFrameDifference;
// Update the clock // Update the clock
ReRecTimer.WindBackStartingTime((u64)CurrentTimeSeconds * 1000); ReRecTimer.WindBackStartingTime((u64)CurrentTimeSeconds * 1000);
// Logging // Logging
Console::Print("WindBack: %i %u\n", Counter, (u64)CurrentTimeSeconds); Console::Print("WindBack: %i %u\n", Counter, (u64)CurrentTimeSeconds);
} }
//////////////////////////////////////// ////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
// Frame advance // Frame advance
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void FrameAdvance() void FrameAdvance()
{ {
// Update status bar // Update status bar
WriteStatus(); WriteStatus();
// If a game is not started, return // If a game is not started, return
if (Core::GetState() == Core::CORE_UNINITIALIZED) return; if (Core::GetState() == Core::CORE_UNINITIALIZED) return;
// Play to the next frame // Play to the next frame
if (g_FrameStep) if (g_FrameStep)
{ {
Run(); Run();
Core::SetState(Core::CORE_RUN); Core::SetState(Core::CORE_RUN);
} }
} }
// Turn on frame stepping // Turn on frame stepping
void FrameStepOnOff() void FrameStepOnOff()
{ {
/* Turn frame step on or off. If a game is running and we turn this on it means that the game /* Turn frame step on or off. If a game is running and we turn this on it means that the game
will pause after the next frame update */ will pause after the next frame update */
g_FrameStep = !g_FrameStep; g_FrameStep = !g_FrameStep;
// Update status bar // Update status bar
WriteStatus(); WriteStatus();
// If a game is not started, return // If a game is not started, return
if(Core::GetState() == Core::CORE_UNINITIALIZED) return; if(Core::GetState() == Core::CORE_UNINITIALIZED) return;
// Run the emulation if we turned off framestepping // Run the emulation if we turned off framestepping
if (!g_FrameStep) if (!g_FrameStep)
{ {
Run(); Run();
Core::SetState(Core::CORE_RUN); Core::SetState(Core::CORE_RUN);
} }
} }
//////////////////////////////////////// ////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
// General functions // General functions
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// Write to the status bar // Write to the status bar
void WriteStatus() void WriteStatus()
{ {
std::string TmpStr = "Time: " + ReRecTimer.GetTimeElapsedFormatted(); std::string TmpStr = "Time: " + ReRecTimer.GetTimeElapsedFormatted();
TmpStr += StringFromFormat(" Frame: %s", ThS(g_FrameCounter).c_str()); TmpStr += StringFromFormat(" Frame: %s", ThS(g_FrameCounter).c_str());
// The FPS is the total average since the game was booted // The FPS is the total average since the game was booted
TmpStr += StringFromFormat(" FPS: %i", (g_FrameCounter * 1000) / ReRecTimer.GetTimeElapsed()); TmpStr += StringFromFormat(" FPS: %i", (g_FrameCounter * 1000) / ReRecTimer.GetTimeElapsed());
TmpStr += StringFromFormat(" FrameStep: %s", g_FrameStep ? "On" : "Off"); TmpStr += StringFromFormat(" FrameStep: %s", g_FrameStep ? "On" : "Off");
Host_UpdateStatusBar(TmpStr.c_str(), 1); Host_UpdateStatusBar(TmpStr.c_str(), 1);
} }
// When a new frame is drawn // When a new frame is drawn
void FrameUpdate() void FrameUpdate()
{ {
// Write to the status bar // Write to the status bar
WriteStatus(); WriteStatus();
/* I don't think the frequent update has any material speed inpact at all, but should it /* I don't think the frequent update has any material speed inpact at all, but should it
have you can controls the update speed by changing the "% 10" in this line */ have you can controls the update speed by changing the "% 10" in this line */
//if (g_FrameCounter % 10 == 0) WriteStatus(); //if (g_FrameCounter % 10 == 0) WriteStatus();
// Pause if frame stepping is on // Pause if frame stepping is on
if(g_FrameStep) if(g_FrameStep)
{ {
Pause(); Pause();
Core::SetState(Core::CORE_PAUSE); Core::SetState(Core::CORE_PAUSE);
} }
// Count one frame // Count one frame
g_FrameCounter++; g_FrameCounter++;
} }
//////////////////////////////////////// ////////////////////////////////////////
} // Core } // Core
#endif // RERECORDING #endif // RERECORDING

File diff suppressed because it is too large Load Diff

View File

@ -1,97 +1,97 @@
// Copyright (C) 2003-2009 Dolphin Project. // Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0. // the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details. // GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program. // A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/ // If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at // Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
#include "SI_Device.h" #include "SI_Device.h"
#include "SI_DeviceGCController.h" #include "SI_DeviceGCController.h"
#include "SI_DeviceGBA.h" #include "SI_DeviceGBA.h"
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
// --- interface ISIDevice --- // --- interface ISIDevice ---
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
int ISIDevice::RunBuffer(u8* _pBuffer, int _iLength) int ISIDevice::RunBuffer(u8* _pBuffer, int _iLength)
{ {
#ifdef _DEBUG #ifdef _DEBUG
LOG(SERIALINTERFACE, "Send Data Device(%i) - Length(%i) ", ISIDevice::m_iDeviceNumber,_iLength); LOG(SERIALINTERFACE, "Send Data Device(%i) - Length(%i) ", ISIDevice::m_iDeviceNumber,_iLength);
char szTemp[256] = ""; char szTemp[256] = "";
int num = 0; int num = 0;
while(num < _iLength) while(num < _iLength)
{ {
char szTemp2[128] = ""; char szTemp2[128] = "";
sprintf(szTemp2, "0x%02x ", _pBuffer[num^3]); sprintf(szTemp2, "0x%02x ", _pBuffer[num^3]);
strcat(szTemp, szTemp2); strcat(szTemp, szTemp2);
num++; num++;
if ((num % 8) == 0) if ((num % 8) == 0)
{ {
LOG(SERIALINTERFACE, szTemp); LOG(SERIALINTERFACE, szTemp);
szTemp[0] = '\0'; szTemp[0] = '\0';
} }
} }
LOG(SERIALINTERFACE, szTemp); LOG(SERIALINTERFACE, szTemp);
#endif #endif
return 0; return 0;
}; };
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
// --- class CSIDummy --- // --- class CSIDummy ---
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
// Just a dummy that logs reads and writes // Just a dummy that logs reads and writes
// to be used for SI devices we haven't emulated // to be used for SI devices we haven't emulated
class CSIDevice_Dummy : public ISIDevice class CSIDevice_Dummy : public ISIDevice
{ {
public: public:
CSIDevice_Dummy(int _iDeviceNumber) : CSIDevice_Dummy(int _iDeviceNumber) :
ISIDevice(_iDeviceNumber) ISIDevice(_iDeviceNumber)
{} {}
virtual ~CSIDevice_Dummy(){} virtual ~CSIDevice_Dummy(){}
int RunBuffer(u8* _pBuffer, int _iLength) int RunBuffer(u8* _pBuffer, int _iLength)
{ {
// (shuffle2) Logging of this function will be done above, in ISIDevice::RunBuffer // (shuffle2) Logging of this function will be done above, in ISIDevice::RunBuffer
// No device. (shuffle2) Maybe this should be SI_ERROR_NO_RESPONSE? // No device. (shuffle2) Maybe this should be SI_ERROR_NO_RESPONSE?
reinterpret_cast<u32*>(_pBuffer)[0] = 0x00000000; reinterpret_cast<u32*>(_pBuffer)[0] = 0x00000000;
return 4; return 4;
} }
bool GetData(u32& _Hi, u32& _Low) {LOG(SERIALINTERFACE, "SI DUMMY %i GetData", this->m_iDeviceNumber); return false;} bool GetData(u32& _Hi, u32& _Low) {LOG(SERIALINTERFACE, "SI DUMMY %i GetData", this->m_iDeviceNumber); return false;}
void SendCommand(u32 _Cmd) {LOG(SERIALINTERFACE, "SI DUMMY %i SendCommand: %08x", this->m_iDeviceNumber, _Cmd);} void SendCommand(u32 _Cmd) {LOG(SERIALINTERFACE, "SI DUMMY %i SendCommand: %08x", this->m_iDeviceNumber, _Cmd);}
}; };
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
// F A C T O R Y ///////////////////////////////////////////////////////// // F A C T O R Y /////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
ISIDevice* SIDevice_Create(TSIDevices _SIDevice, int _iDeviceNumber) ISIDevice* SIDevice_Create(TSIDevices _SIDevice, int _iDeviceNumber)
{ {
switch(_SIDevice) switch(_SIDevice)
{ {
case SI_DUMMY: case SI_DUMMY:
return new CSIDevice_Dummy(_iDeviceNumber); return new CSIDevice_Dummy(_iDeviceNumber);
break; break;
case SI_GC_CONTROLLER: case SI_GC_CONTROLLER:
return new CSIDevice_GCController(_iDeviceNumber); return new CSIDevice_GCController(_iDeviceNumber);
break; break;
case SI_GBA: case SI_GBA:
return new CSIDevice_GBA(_iDeviceNumber); return new CSIDevice_GBA(_iDeviceNumber);
break; break;
} }
return NULL; return NULL;
} }

View File

@ -1,173 +1,173 @@
// Copyright (C) 2003-2009 Dolphin Project. // Copyright (C) 2003-2009 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0. // the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details. // GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program. // A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/ // If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at // Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include "SI_Device.h" #include "SI_Device.h"
#include "SI_DeviceGCController.h" #include "SI_DeviceGCController.h"
#include "../PluginManager.h" #include "../PluginManager.h"
#include "EXI_Device.h" #include "EXI_Device.h"
#include "EXI_DeviceMic.h" #include "EXI_DeviceMic.h"
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
// --- standard gamecube controller --- // --- standard gamecube controller ---
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
CSIDevice_GCController::CSIDevice_GCController(int _iDeviceNumber) : CSIDevice_GCController::CSIDevice_GCController(int _iDeviceNumber) :
ISIDevice(_iDeviceNumber) ISIDevice(_iDeviceNumber)
{ {
memset(&m_origin, 0, sizeof(SOrigin)); memset(&m_origin, 0, sizeof(SOrigin));
m_origin.uCommand = 0x41; m_origin.uCommand = 0x41;
m_origin.uOriginStickX = 0x80; m_origin.uOriginStickX = 0x80;
m_origin.uOriginStickY = 0x80; m_origin.uOriginStickY = 0x80;
m_origin.uSubStickStickX = 0x80; m_origin.uSubStickStickX = 0x80;
m_origin.uSubStickStickY = 0x80; m_origin.uSubStickStickY = 0x80;
m_origin.uTrigger_L = 0x1F; m_origin.uTrigger_L = 0x1F;
m_origin.uTrigger_R = 0x1F; m_origin.uTrigger_R = 0x1F;
} }
int CSIDevice_GCController::RunBuffer(u8* _pBuffer, int _iLength) int CSIDevice_GCController::RunBuffer(u8* _pBuffer, int _iLength)
{ {
// For debug logging only // For debug logging only
ISIDevice::RunBuffer(_pBuffer, _iLength); ISIDevice::RunBuffer(_pBuffer, _iLength);
int iPosition = 0; int iPosition = 0;
while(iPosition < _iLength) while(iPosition < _iLength)
{ {
// Read the command // Read the command
EBufferCommands command = static_cast<EBufferCommands>(_pBuffer[iPosition ^ 3]); EBufferCommands command = static_cast<EBufferCommands>(_pBuffer[iPosition ^ 3]);
iPosition++; iPosition++;
// Handle it // Handle it
switch(command) switch(command)
{ {
case CMD_RESET: case CMD_RESET:
{ {
*(u32*)&_pBuffer[0] = SI_GC_CONTROLLER; // | SI_GC_NOMOTOR; *(u32*)&_pBuffer[0] = SI_GC_CONTROLLER; // | SI_GC_NOMOTOR;
iPosition = _iLength; // Break the while loop iPosition = _iLength; // Break the while loop
} }
break; break;
case CMD_ORIGIN: case CMD_ORIGIN:
{ {
LOG(SERIALINTERFACE, "PAD - Get Origin"); LOG(SERIALINTERFACE, "PAD - Get Origin");
u8* pCalibration = reinterpret_cast<u8*>(&m_origin); u8* pCalibration = reinterpret_cast<u8*>(&m_origin);
for (int i = 0; i < (int)sizeof(SOrigin); i++) for (int i = 0; i < (int)sizeof(SOrigin); i++)
{ {
_pBuffer[i ^ 3] = *pCalibration++; _pBuffer[i ^ 3] = *pCalibration++;
} }
} }
iPosition = _iLength; iPosition = _iLength;
break; break;
// Recalibrate (FiRES: i am not 100 percent sure about this) // Recalibrate (FiRES: i am not 100 percent sure about this)
case CMD_RECALIBRATE: case CMD_RECALIBRATE:
{ {
LOG(SERIALINTERFACE, "PAD - Recalibrate"); LOG(SERIALINTERFACE, "PAD - Recalibrate");
u8* pCalibration = reinterpret_cast<u8*>(&m_origin); u8* pCalibration = reinterpret_cast<u8*>(&m_origin);
for (int i = 0; i < (int)sizeof(SOrigin); i++) for (int i = 0; i < (int)sizeof(SOrigin); i++)
{ {
_pBuffer[i ^ 3] = *pCalibration++; _pBuffer[i ^ 3] = *pCalibration++;
} }
} }
iPosition = _iLength; iPosition = _iLength;
break; break;
// WII Something // WII Something
case 0xCE: case 0xCE:
LOG(SERIALINTERFACE, "Unknown Wii SI Command"); LOG(SERIALINTERFACE, "Unknown Wii SI Command");
break; break;
// DEFAULT // DEFAULT
default: default:
{ {
LOG(SERIALINTERFACE, "unknown SI command (0x%x)", command); LOG(SERIALINTERFACE, "unknown SI command (0x%x)", command);
PanicAlert("SI: Unknown command"); PanicAlert("SI: Unknown command");
iPosition = _iLength; iPosition = _iLength;
} }
break; break;
} }
} }
return iPosition; return iPosition;
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
// GetData // GetData
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
// Return true on new data (max 7 Bytes and 6 bits ;) // Return true on new data (max 7 Bytes and 6 bits ;)
bool bool
CSIDevice_GCController::GetData(u32& _Hi, u32& _Low) CSIDevice_GCController::GetData(u32& _Hi, u32& _Low)
{ {
SPADStatus PadStatus; SPADStatus PadStatus;
memset(&PadStatus, 0 ,sizeof(PadStatus)); memset(&PadStatus, 0 ,sizeof(PadStatus));
Common::PluginPAD* pad = CPluginManager::GetInstance().GetPad(ISIDevice::m_iDeviceNumber); Common::PluginPAD* pad = CPluginManager::GetInstance().GetPad(ISIDevice::m_iDeviceNumber);
pad->PAD_GetStatus(ISIDevice::m_iDeviceNumber, &PadStatus); pad->PAD_GetStatus(ISIDevice::m_iDeviceNumber, &PadStatus);
_Hi = (u32)((u8)PadStatus.stickY); _Hi = (u32)((u8)PadStatus.stickY);
_Hi |= (u32)((u8)PadStatus.stickX << 8); _Hi |= (u32)((u8)PadStatus.stickX << 8);
_Hi |= (u32)((u16)PadStatus.button << 16); _Hi |= (u32)((u16)PadStatus.button << 16);
_Low = (u8)PadStatus.triggerRight; _Low = (u8)PadStatus.triggerRight;
_Low |= (u32)((u8)PadStatus.triggerLeft << 8); _Low |= (u32)((u8)PadStatus.triggerLeft << 8);
_Low |= (u32)((u8)PadStatus.substickY << 16); _Low |= (u32)((u8)PadStatus.substickY << 16);
_Low |= (u32)((u8)PadStatus.substickX << 24); _Low |= (u32)((u8)PadStatus.substickX << 24);
SetMic(PadStatus.MicButton); // This is dumb and should not be here SetMic(PadStatus.MicButton); // This is dumb and should not be here
// F|RES: // F|RES:
// i dunno if i should force it here // i dunno if i should force it here
// means that the pad must be "combined" with the origin to math the "final" OSPad-Struct // means that the pad must be "combined" with the origin to math the "final" OSPad-Struct
_Hi |= 0x00800000; _Hi |= 0x00800000;
return true; return true;
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
// SendCommand // SendCommand
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
void void
CSIDevice_GCController::SendCommand(u32 _Cmd) CSIDevice_GCController::SendCommand(u32 _Cmd)
{ {
Common::PluginPAD* pad = CPluginManager::GetInstance().GetPad(ISIDevice::m_iDeviceNumber); Common::PluginPAD* pad = CPluginManager::GetInstance().GetPad(ISIDevice::m_iDeviceNumber);
UCommand command(_Cmd); UCommand command(_Cmd);
switch(command.Command) switch(command.Command)
{ {
// Costis sent it in some demos :) // Costis sent it in some demos :)
case 0x00: case 0x00:
break; break;
case CMD_RUMBLE: case CMD_RUMBLE:
{ {
unsigned int uType = command.Parameter1; // 0 = stop, 1 = rumble, 2 = stop hard unsigned int uType = command.Parameter1; // 0 = stop, 1 = rumble, 2 = stop hard
unsigned int uStrength = command.Parameter2; unsigned int uStrength = command.Parameter2;
if (pad->PAD_Rumble) if (pad->PAD_Rumble)
pad->PAD_Rumble(ISIDevice::m_iDeviceNumber, uType, uStrength); pad->PAD_Rumble(ISIDevice::m_iDeviceNumber, uType, uStrength);
} }
break; break;
default: default:
{ {
LOG(SERIALINTERFACE, "unknown direct command (0x%x)", _Cmd); LOG(SERIALINTERFACE, "unknown direct command (0x%x)", _Cmd);
PanicAlert("SI: Unknown direct command"); PanicAlert("SI: Unknown direct command");
} }
break; break;
} }
} }

View File

@ -1,43 +1,43 @@
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2008 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0. // the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details. // GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program. // A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/ // If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at // Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
// HW Address: 0d07xxxx // HW Address: 0d07xxxx
#include "SDInterface.h" #include "SDInterface.h"
namespace SDInterface namespace SDInterface
{ {
bool g_bIsCardInserted = false; bool g_bIsCardInserted = false;
bool g_bIsDumpFile = false; bool g_bIsDumpFile = false;
std::string sourcePath = ""; std::string sourcePath = "";
bool IsCardInserted() bool IsCardInserted()
{ {
return g_bIsCardInserted; return g_bIsCardInserted;
} }
void SetSourceType(bool isDumpFile) void SetSourceType(bool isDumpFile)
{ {
g_bIsDumpFile = isDumpFile; g_bIsDumpFile = isDumpFile;
} }
void SetSourcePath(const std::string path) void SetSourcePath(const std::string path)
{ {
sourcePath = path; sourcePath = path;
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,498 +1,498 @@
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2008 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0. // the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details. // GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program. // A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/ // If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at // Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Include // Include
// ¯¯¯¯¯¯¯¯¯¯ // ¯¯¯¯¯¯¯¯¯¯
#include "Common.h" #include "Common.h"
#include <wx/button.h> #include <wx/button.h>
#include <wx/textctrl.h> #include <wx/textctrl.h>
#include <wx/textdlg.h> #include <wx/textdlg.h>
#include <wx/listctrl.h> #include <wx/listctrl.h>
#include <wx/thread.h> #include <wx/thread.h>
#include <wx/mstream.h> #include <wx/mstream.h>
#include <wx/tipwin.h> #include <wx/tipwin.h>
#include <wx/fontdlg.h> #include <wx/fontdlg.h>
// ugly that this lib included code from the main // ugly that this lib included code from the main
#include "../../DolphinWX/Src/Globals.h" #include "../../DolphinWX/Src/Globals.h"
#include "Host.h" #include "Host.h"
#include "Debugger.h" #include "Debugger.h"
#include "RegisterWindow.h" #include "RegisterWindow.h"
#include "LogWindow.h" #include "LogWindow.h"
#include "BreakpointWindow.h" #include "BreakpointWindow.h"
#include "MemoryWindow.h" #include "MemoryWindow.h"
#include "JitWindow.h" #include "JitWindow.h"
#include "CodeWindow.h" #include "CodeWindow.h"
#include "CodeView.h" #include "CodeView.h"
#include "FileUtil.h" #include "FileUtil.h"
#include "Core.h" #include "Core.h"
#include "HLE/HLE.h" #include "HLE/HLE.h"
#include "Boot/Boot.h" #include "Boot/Boot.h"
#include "LogManager.h" #include "LogManager.h"
#include "HW/CPU.h" #include "HW/CPU.h"
#include "PowerPC/PowerPC.h" #include "PowerPC/PowerPC.h"
#include "Debugger/PPCDebugInterface.h" #include "Debugger/PPCDebugInterface.h"
#include "Debugger/Debugger_SymbolMap.h" #include "Debugger/Debugger_SymbolMap.h"
#include "PowerPC/PPCAnalyst.h" #include "PowerPC/PPCAnalyst.h"
#include "PowerPC/Profiler.h" #include "PowerPC/Profiler.h"
#include "PowerPC/SymbolDB.h" #include "PowerPC/SymbolDB.h"
#include "PowerPC/SignatureDB.h" #include "PowerPC/SignatureDB.h"
#include "PowerPC/PPCTables.h" #include "PowerPC/PPCTables.h"
#include "PowerPC/Jit64/Jit.h" #include "PowerPC/Jit64/Jit.h"
#include "PowerPC/Jit64/JitCache.h" // for ClearCache() #include "PowerPC/Jit64/JitCache.h" // for ClearCache()
#include "PluginManager.h" #include "PluginManager.h"
#include "ConfigManager.h" #include "ConfigManager.h"
extern "C" // Bitmaps extern "C" // Bitmaps
{ {
#include "../resources/toolbar_play.c" #include "../resources/toolbar_play.c"
#include "../resources/toolbar_pause.c" #include "../resources/toolbar_pause.c"
#include "../resources/toolbar_add_memorycheck.c" #include "../resources/toolbar_add_memorycheck.c"
#include "../resources/toolbar_delete.c" #include "../resources/toolbar_delete.c"
#include "../resources/toolbar_add_breakpoint.c" #include "../resources/toolbar_add_breakpoint.c"
} }
/////////////////////////////////// ///////////////////////////////////
void CCodeWindow::CreateSymbolsMenu() void CCodeWindow::CreateSymbolsMenu()
{ {
wxMenu *pSymbolsMenu = new wxMenu; wxMenu *pSymbolsMenu = new wxMenu;
pSymbolsMenu->Append(IDM_CLEARSYMBOLS, _T("&Clear symbols")); pSymbolsMenu->Append(IDM_CLEARSYMBOLS, _T("&Clear symbols"));
// pSymbolsMenu->Append(IDM_CLEANSYMBOLS, _T("&Clean symbols (zz)")); // pSymbolsMenu->Append(IDM_CLEANSYMBOLS, _T("&Clean symbols (zz)"));
pSymbolsMenu->Append(IDM_SCANFUNCTIONS, _T("&Generate symbol map")); pSymbolsMenu->Append(IDM_SCANFUNCTIONS, _T("&Generate symbol map"));
pSymbolsMenu->AppendSeparator(); pSymbolsMenu->AppendSeparator();
pSymbolsMenu->Append(IDM_LOADMAPFILE, _T("&Load symbol map")); pSymbolsMenu->Append(IDM_LOADMAPFILE, _T("&Load symbol map"));
pSymbolsMenu->Append(IDM_SAVEMAPFILE, _T("&Save symbol map")); pSymbolsMenu->Append(IDM_SAVEMAPFILE, _T("&Save symbol map"));
pSymbolsMenu->AppendSeparator(); pSymbolsMenu->AppendSeparator();
pSymbolsMenu->Append(IDM_SAVEMAPFILEWITHCODES, _T("Save code"), pSymbolsMenu->Append(IDM_SAVEMAPFILEWITHCODES, _T("Save code"),
wxString::FromAscii("Save the entire disassembled code. This may take a several seconds" wxString::FromAscii("Save the entire disassembled code. This may take a several seconds"
" and may require between 50 and 100 MB of hard drive space. It will only save code" " and may require between 50 and 100 MB of hard drive space. It will only save code"
" that are in the first 4 MB of memory, if you are debugging a game that load .rel" " that are in the first 4 MB of memory, if you are debugging a game that load .rel"
" files with code to memory you may want to increase that to perhaps 8 MB, you can do" " files with code to memory you may want to increase that to perhaps 8 MB, you can do"
" that from SymbolDB::SaveMap().") " that from SymbolDB::SaveMap().")
); );
pSymbolsMenu->AppendSeparator(); pSymbolsMenu->AppendSeparator();
pSymbolsMenu->Append(IDM_CREATESIGNATUREFILE, _T("&Create signature file...")); pSymbolsMenu->Append(IDM_CREATESIGNATUREFILE, _T("&Create signature file..."));
pSymbolsMenu->Append(IDM_USESIGNATUREFILE, _T("&Use signature file...")); pSymbolsMenu->Append(IDM_USESIGNATUREFILE, _T("&Use signature file..."));
pSymbolsMenu->AppendSeparator(); pSymbolsMenu->AppendSeparator();
pSymbolsMenu->Append(IDM_PATCHHLEFUNCTIONS, _T("&Patch HLE functions")); pSymbolsMenu->Append(IDM_PATCHHLEFUNCTIONS, _T("&Patch HLE functions"));
pMenuBar->Append(pSymbolsMenu, _T("&Symbols")); pMenuBar->Append(pSymbolsMenu, _T("&Symbols"));
wxMenu *pJitMenu = new wxMenu; wxMenu *pJitMenu = new wxMenu;
pJitMenu->Append(IDM_CLEARCODECACHE, _T("&Clear code cache")); pJitMenu->Append(IDM_CLEARCODECACHE, _T("&Clear code cache"));
pJitMenu->Append(IDM_LOGINSTRUCTIONS, _T("&Log JIT instruction coverage")); pJitMenu->Append(IDM_LOGINSTRUCTIONS, _T("&Log JIT instruction coverage"));
pMenuBar->Append(pJitMenu, _T("&JIT")); pMenuBar->Append(pJitMenu, _T("&JIT"));
wxMenu *pProfilerMenu = new wxMenu; wxMenu *pProfilerMenu = new wxMenu;
pProfilerMenu->Append(IDM_PROFILEBLOCKS, _T("&Profile blocks"), wxEmptyString, wxITEM_CHECK); pProfilerMenu->Append(IDM_PROFILEBLOCKS, _T("&Profile blocks"), wxEmptyString, wxITEM_CHECK);
pProfilerMenu->AppendSeparator(); pProfilerMenu->AppendSeparator();
pProfilerMenu->Append(IDM_WRITEPROFILE, _T("&Write to profile.txt, show")); pProfilerMenu->Append(IDM_WRITEPROFILE, _T("&Write to profile.txt, show"));
pMenuBar->Append(pProfilerMenu, _T("&Profiler")); pMenuBar->Append(pProfilerMenu, _T("&Profiler"));
} }
void CCodeWindow::OnProfilerMenu(wxCommandEvent& event) void CCodeWindow::OnProfilerMenu(wxCommandEvent& event)
{ {
if (Core::GetState() == Core::CORE_RUN) { if (Core::GetState() == Core::CORE_RUN) {
event.Skip(); event.Skip();
return; return;
} }
switch (event.GetId()) switch (event.GetId())
{ {
case IDM_PROFILEBLOCKS: case IDM_PROFILEBLOCKS:
jit.ClearCache(); jit.ClearCache();
Profiler::g_ProfileBlocks = GetMenuBar()->IsChecked(IDM_PROFILEBLOCKS); Profiler::g_ProfileBlocks = GetMenuBar()->IsChecked(IDM_PROFILEBLOCKS);
break; break;
case IDM_WRITEPROFILE: case IDM_WRITEPROFILE:
Profiler::WriteProfileResults("profiler.txt"); Profiler::WriteProfileResults("profiler.txt");
File::Launch("profiler.txt"); File::Launch("profiler.txt");
break; break;
} }
} }
void CCodeWindow::OnSymbolsMenu(wxCommandEvent& event) void CCodeWindow::OnSymbolsMenu(wxCommandEvent& event)
{ {
if (Core::GetState() == Core::CORE_UNINITIALIZED) if (Core::GetState() == Core::CORE_UNINITIALIZED)
{ {
// TODO: disable menu items instead :P // TODO: disable menu items instead :P
return; return;
} }
std::string mapfile = CBoot::GenerateMapFilename(); std::string mapfile = CBoot::GenerateMapFilename();
switch (event.GetId()) switch (event.GetId())
{ {
case IDM_CLEARSYMBOLS: case IDM_CLEARSYMBOLS:
g_symbolDB.Clear(); g_symbolDB.Clear();
Host_NotifyMapLoaded(); Host_NotifyMapLoaded();
break; break;
case IDM_CLEANSYMBOLS: case IDM_CLEANSYMBOLS:
g_symbolDB.Clear("zz"); g_symbolDB.Clear("zz");
Host_NotifyMapLoaded(); Host_NotifyMapLoaded();
break; break;
case IDM_SCANFUNCTIONS: case IDM_SCANFUNCTIONS:
{ {
PPCAnalyst::FindFunctions(0x80000000, 0x80400000, &g_symbolDB); PPCAnalyst::FindFunctions(0x80000000, 0x80400000, &g_symbolDB);
SignatureDB db; SignatureDB db;
if (db.Load(TOTALDB_FILE)) if (db.Load(TOTALDB_FILE))
db.Apply(&g_symbolDB); db.Apply(&g_symbolDB);
// HLE::PatchFunctions(); // HLE::PatchFunctions();
NotifyMapLoaded(); NotifyMapLoaded();
break; break;
} }
case IDM_LOADMAPFILE: case IDM_LOADMAPFILE:
if (!File::Exists(mapfile.c_str())) if (!File::Exists(mapfile.c_str()))
{ {
g_symbolDB.Clear(); g_symbolDB.Clear();
PPCAnalyst::FindFunctions(0x80000000, 0x80400000, &g_symbolDB); PPCAnalyst::FindFunctions(0x80000000, 0x80400000, &g_symbolDB);
SignatureDB db; SignatureDB db;
if (db.Load(TOTALDB_FILE)) if (db.Load(TOTALDB_FILE))
db.Apply(&g_symbolDB); db.Apply(&g_symbolDB);
} else { } else {
g_symbolDB.LoadMap(mapfile.c_str()); g_symbolDB.LoadMap(mapfile.c_str());
} }
NotifyMapLoaded(); NotifyMapLoaded();
break; break;
case IDM_SAVEMAPFILE: case IDM_SAVEMAPFILE:
g_symbolDB.SaveMap(mapfile.c_str()); g_symbolDB.SaveMap(mapfile.c_str());
break; break;
case IDM_SAVEMAPFILEWITHCODES: case IDM_SAVEMAPFILEWITHCODES:
g_symbolDB.SaveMap(mapfile.c_str(), true); g_symbolDB.SaveMap(mapfile.c_str(), true);
break; break;
case IDM_CREATESIGNATUREFILE: case IDM_CREATESIGNATUREFILE:
{ {
wxTextEntryDialog input_prefix(this, wxString::FromAscii("Only export symbols with prefix:"), wxGetTextFromUserPromptStr, _T(".")); wxTextEntryDialog input_prefix(this, wxString::FromAscii("Only export symbols with prefix:"), wxGetTextFromUserPromptStr, _T("."));
if (input_prefix.ShowModal() == wxID_OK) { if (input_prefix.ShowModal() == wxID_OK) {
std::string prefix(input_prefix.GetValue().mb_str()); std::string prefix(input_prefix.GetValue().mb_str());
wxString path = wxFileSelector( wxString path = wxFileSelector(
_T("Save signature as"), wxEmptyString, wxEmptyString, wxEmptyString, _T("Save signature as"), wxEmptyString, wxEmptyString, wxEmptyString,
_T("Dolphin Signature File (*.dsy)|*.dsy;"), wxFD_SAVE, _T("Dolphin Signature File (*.dsy)|*.dsy;"), wxFD_SAVE,
this); this);
if (path) { if (path) {
SignatureDB db; SignatureDB db;
db.Initialize(&g_symbolDB, prefix.c_str()); db.Initialize(&g_symbolDB, prefix.c_str());
std::string filename(path.ToAscii()); // PPCAnalyst::SaveSignatureDB( std::string filename(path.ToAscii()); // PPCAnalyst::SaveSignatureDB(
db.Save(path.ToAscii()); db.Save(path.ToAscii());
} }
} }
} }
break; break;
case IDM_USESIGNATUREFILE: case IDM_USESIGNATUREFILE:
{ {
wxString path = wxFileSelector( wxString path = wxFileSelector(
_T("Apply signature file"), wxEmptyString, wxEmptyString, wxEmptyString, _T("Apply signature file"), wxEmptyString, wxEmptyString, wxEmptyString,
_T("Dolphin Signature File (*.dsy)|*.dsy;"), wxFD_OPEN | wxFD_FILE_MUST_EXIST, _T("Dolphin Signature File (*.dsy)|*.dsy;"), wxFD_OPEN | wxFD_FILE_MUST_EXIST,
this); this);
if (path) { if (path) {
SignatureDB db; SignatureDB db;
db.Load(path.ToAscii()); db.Load(path.ToAscii());
db.Apply(&g_symbolDB); db.Apply(&g_symbolDB);
} }
} }
NotifyMapLoaded(); NotifyMapLoaded();
break; break;
case IDM_PATCHHLEFUNCTIONS: case IDM_PATCHHLEFUNCTIONS:
HLE::PatchFunctions(); HLE::PatchFunctions();
Update(); Update();
break; break;
} }
} }
void CCodeWindow::NotifyMapLoaded() void CCodeWindow::NotifyMapLoaded()
{ {
g_symbolDB.FillInCallers(); g_symbolDB.FillInCallers();
//symbols->Show(false); // hide it for faster filling //symbols->Show(false); // hide it for faster filling
symbols->Freeze(); // HyperIris: wx style fast filling symbols->Freeze(); // HyperIris: wx style fast filling
symbols->Clear(); symbols->Clear();
for (SymbolDB::XFuncMap::iterator iter = g_symbolDB.GetIterator(); iter != g_symbolDB.End(); iter++) for (SymbolDB::XFuncMap::iterator iter = g_symbolDB.GetIterator(); iter != g_symbolDB.End(); iter++)
{ {
int idx = symbols->Append(wxString::FromAscii(iter->second.name.c_str())); int idx = symbols->Append(wxString::FromAscii(iter->second.name.c_str()));
symbols->SetClientData(idx, (void*)&iter->second); symbols->SetClientData(idx, (void*)&iter->second);
} }
symbols->Thaw(); symbols->Thaw();
//symbols->Show(true); //symbols->Show(true);
Update(); Update();
} }
void CCodeWindow::OnSymbolListChange(wxCommandEvent& event) void CCodeWindow::OnSymbolListChange(wxCommandEvent& event)
{ {
int index = symbols->GetSelection(); int index = symbols->GetSelection();
if (index >= 0) { if (index >= 0) {
Symbol* pSymbol = static_cast<Symbol *>(symbols->GetClientData(index)); Symbol* pSymbol = static_cast<Symbol *>(symbols->GetClientData(index));
if (pSymbol != NULL) if (pSymbol != NULL)
{ {
if(pSymbol->type == Symbol::SYMBOL_DATA) if(pSymbol->type == Symbol::SYMBOL_DATA)
{ {
if(m_MemoryWindow && m_MemoryWindow->IsVisible()) if(m_MemoryWindow && m_MemoryWindow->IsVisible())
m_MemoryWindow->JumpToAddress(pSymbol->address); m_MemoryWindow->JumpToAddress(pSymbol->address);
} }
else else
{ {
JumpToAddress(pSymbol->address); JumpToAddress(pSymbol->address);
} }
} }
} }
} }
void CCodeWindow::OnSymbolListContextMenu(wxContextMenuEvent& event) void CCodeWindow::OnSymbolListContextMenu(wxContextMenuEvent& event)
{ {
} }
///////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////
// Show and hide windows // Show and hide windows
///////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////
void CCodeWindow::OnToggleLogWindow(wxCommandEvent& event) void CCodeWindow::OnToggleLogWindow(wxCommandEvent& event)
{ {
if (LogManager::Enabled()) if (LogManager::Enabled())
{ {
bool show = GetMenuBar()->IsChecked(event.GetId()); bool show = GetMenuBar()->IsChecked(event.GetId());
if (show) if (show)
{ {
if (!m_LogWindow) if (!m_LogWindow)
{ {
m_LogWindow = new CLogWindow(this); m_LogWindow = new CLogWindow(this);
} }
m_LogWindow->Show(true); m_LogWindow->Show(true);
} }
else // hide else // hide
{ {
// If m_dialog is NULL, then possibly the system // If m_dialog is NULL, then possibly the system
// didn't report the checked menu item status correctly. // didn't report the checked menu item status correctly.
// It should be true just after the menu item was selected, // It should be true just after the menu item was selected,
// if there was no modeless dialog yet. // if there was no modeless dialog yet.
wxASSERT(m_LogWindow != NULL); wxASSERT(m_LogWindow != NULL);
if (m_LogWindow) if (m_LogWindow)
{ {
m_LogWindow->Hide(); m_LogWindow->Hide();
} }
} }
} }
} }
void CCodeWindow::OnToggleRegisterWindow(wxCommandEvent& event) void CCodeWindow::OnToggleRegisterWindow(wxCommandEvent& event)
{ {
bool show = GetMenuBar()->IsChecked(event.GetId()); bool show = GetMenuBar()->IsChecked(event.GetId());
if (show) if (show)
{ {
if (!m_RegisterWindow) if (!m_RegisterWindow)
{ {
m_RegisterWindow = new CRegisterWindow(this); m_RegisterWindow = new CRegisterWindow(this);
} }
m_RegisterWindow->Show(true); m_RegisterWindow->Show(true);
} }
else // hide else // hide
{ {
// If m_dialog is NULL, then possibly the system // If m_dialog is NULL, then possibly the system
// didn't report the checked menu item status correctly. // didn't report the checked menu item status correctly.
// It should be true just after the menu item was selected, // It should be true just after the menu item was selected,
// if there was no modeless dialog yet. // if there was no modeless dialog yet.
wxASSERT(m_RegisterWindow != NULL); wxASSERT(m_RegisterWindow != NULL);
if (m_RegisterWindow) if (m_RegisterWindow)
{ {
m_RegisterWindow->Hide(); m_RegisterWindow->Hide();
} }
} }
} }
// ======================================================================================= // =======================================================================================
// Toggle Sound Debugging Window // Toggle Sound Debugging Window
// ------------ // ------------
void CCodeWindow::OnToggleSoundWindow(wxCommandEvent& event) void CCodeWindow::OnToggleSoundWindow(wxCommandEvent& event)
{ {
bool show = GetMenuBar()->IsChecked(event.GetId()); bool show = GetMenuBar()->IsChecked(event.GetId());
if (show) if (show)
{ {
// TODO: add some kind of if() check here to? // TODO: add some kind of if() check here to?
CPluginManager::GetInstance().OpenDebug( CPluginManager::GetInstance().OpenDebug(
GetHandle(), GetHandle(),
SConfig::GetInstance().m_LocalCoreStartupParameter.m_strDSPPlugin.c_str(), SConfig::GetInstance().m_LocalCoreStartupParameter.m_strDSPPlugin.c_str(),
PLUGIN_TYPE_DSP, true // DSP, show PLUGIN_TYPE_DSP, true // DSP, show
); );
} }
else // hide else // hide
{ {
// Close the sound dll that has an open debugger // Close the sound dll that has an open debugger
CPluginManager::GetInstance().OpenDebug( CPluginManager::GetInstance().OpenDebug(
GetHandle(), GetHandle(),
SConfig::GetInstance().m_LocalCoreStartupParameter.m_strDSPPlugin.c_str(), SConfig::GetInstance().m_LocalCoreStartupParameter.m_strDSPPlugin.c_str(),
PLUGIN_TYPE_DSP, false // DSP, hide PLUGIN_TYPE_DSP, false // DSP, hide
); );
} }
} }
// =========== // ===========
// ======================================================================================= // =======================================================================================
// Toggle Video Debugging Window // Toggle Video Debugging Window
// ------------ // ------------
void CCodeWindow::OnToggleVideoWindow(wxCommandEvent& event) void CCodeWindow::OnToggleVideoWindow(wxCommandEvent& event)
{ {
bool show = GetMenuBar()->IsChecked(event.GetId()); bool show = GetMenuBar()->IsChecked(event.GetId());
//GetMenuBar()->Check(event.GetId(), false); // Turn off //GetMenuBar()->Check(event.GetId(), false); // Turn off
if (show) if (show)
{ {
// It works now, but I'll keep this message in case the problem reappears // It works now, but I'll keep this message in case the problem reappears
/*if(Core::GetState() == Core::CORE_UNINITIALIZED) /*if(Core::GetState() == Core::CORE_UNINITIALIZED)
{ {
wxMessageBox(_T("Warning, opening this window before a game is started \n\ wxMessageBox(_T("Warning, opening this window before a game is started \n\
may cause a crash when a game is later started. Todo: figure out why and fix it."), wxT("OpenGL Debugging Window")); may cause a crash when a game is later started. Todo: figure out why and fix it."), wxT("OpenGL Debugging Window"));
}*/ }*/
// TODO: add some kind of if() check here to? // TODO: add some kind of if() check here to?
CPluginManager::GetInstance().OpenDebug( CPluginManager::GetInstance().OpenDebug(
GetHandle(), GetHandle(),
SConfig::GetInstance().m_LocalCoreStartupParameter.m_strVideoPlugin.c_str(), SConfig::GetInstance().m_LocalCoreStartupParameter.m_strVideoPlugin.c_str(),
PLUGIN_TYPE_VIDEO, true // Video, show PLUGIN_TYPE_VIDEO, true // Video, show
); );
} }
else // hide else // hide
{ {
// Close the video dll that has an open debugger // Close the video dll that has an open debugger
CPluginManager::GetInstance().OpenDebug( CPluginManager::GetInstance().OpenDebug(
GetHandle(), GetHandle(),
SConfig::GetInstance().m_LocalCoreStartupParameter.m_strVideoPlugin.c_str(), SConfig::GetInstance().m_LocalCoreStartupParameter.m_strVideoPlugin.c_str(),
PLUGIN_TYPE_VIDEO, false // Video, hide PLUGIN_TYPE_VIDEO, false // Video, hide
); );
} }
} }
// =========== // ===========
void CCodeWindow::OnToggleJitWindow(wxCommandEvent& event) void CCodeWindow::OnToggleJitWindow(wxCommandEvent& event)
{ {
bool show = GetMenuBar()->IsChecked(event.GetId()); bool show = GetMenuBar()->IsChecked(event.GetId());
if (show) if (show)
{ {
if (!m_JitWindow) if (!m_JitWindow)
{ {
m_JitWindow = new CJitWindow(this); m_JitWindow = new CJitWindow(this);
} }
m_JitWindow->Show(true); m_JitWindow->Show(true);
} }
else // hide else // hide
{ {
// If m_dialog is NULL, then possibly the system // If m_dialog is NULL, then possibly the system
// didn't report the checked menu item status correctly. // didn't report the checked menu item status correctly.
// It should be true just after the menu item was selected, // It should be true just after the menu item was selected,
// if there was no modeless dialog yet. // if there was no modeless dialog yet.
wxASSERT(m_JitWindow != NULL); wxASSERT(m_JitWindow != NULL);
if (m_JitWindow) if (m_JitWindow)
{ {
m_JitWindow->Hide(); m_JitWindow->Hide();
} }
} }
} }
void CCodeWindow::OnToggleBreakPointWindow(wxCommandEvent& event) void CCodeWindow::OnToggleBreakPointWindow(wxCommandEvent& event)
{ {
bool show = GetMenuBar()->IsChecked(event.GetId()); bool show = GetMenuBar()->IsChecked(event.GetId());
if (show) if (show)
{ {
if (!m_BreakpointWindow) if (!m_BreakpointWindow)
{ {
m_BreakpointWindow = new CBreakPointWindow(this, this); m_BreakpointWindow = new CBreakPointWindow(this, this);
} }
m_BreakpointWindow->Show(true); m_BreakpointWindow->Show(true);
} }
else // hide else // hide
{ {
// If m_dialog is NULL, then possibly the system // If m_dialog is NULL, then possibly the system
// didn't report the checked menu item status correctly. // didn't report the checked menu item status correctly.
// It should be true just after the menu item was selected, // It should be true just after the menu item was selected,
// if there was no modeless dialog yet. // if there was no modeless dialog yet.
wxASSERT(m_BreakpointWindow != NULL); wxASSERT(m_BreakpointWindow != NULL);
if (m_BreakpointWindow) if (m_BreakpointWindow)
{ {
m_BreakpointWindow->Hide(); m_BreakpointWindow->Hide();
} }
} }
} }
void CCodeWindow::OnToggleMemoryWindow(wxCommandEvent& event) void CCodeWindow::OnToggleMemoryWindow(wxCommandEvent& event)
{ {
bool show = GetMenuBar()->IsChecked(event.GetId()); bool show = GetMenuBar()->IsChecked(event.GetId());
if (show) if (show)
{ {
if (!m_MemoryWindow) if (!m_MemoryWindow)
{ {
m_MemoryWindow = new CMemoryWindow(this); m_MemoryWindow = new CMemoryWindow(this);
} }
m_MemoryWindow->Show(true); m_MemoryWindow->Show(true);
} }
else // hide else // hide
{ {
// If m_dialog is NULL, then possibly the system // If m_dialog is NULL, then possibly the system
// didn't report the checked menu item status correctly. // didn't report the checked menu item status correctly.
// It should be true just after the menu item was selected, // It should be true just after the menu item was selected,
// if there was no modeless dialog yet. // if there was no modeless dialog yet.
wxASSERT(m_MemoryWindow != NULL); wxASSERT(m_MemoryWindow != NULL);
if (m_MemoryWindow) if (m_MemoryWindow)
{ {
m_MemoryWindow->Hide(); m_MemoryWindow->Hide();
} }
} }
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
// Change the global DebuggerFont // Change the global DebuggerFont
void CCodeWindow::OnChangeFont(wxCommandEvent& event) void CCodeWindow::OnChangeFont(wxCommandEvent& event)
{ {
wxFontData data; wxFontData data;
data.SetInitialFont(GetFont()); data.SetInitialFont(GetFont());
wxFontDialog dialog(this, data); wxFontDialog dialog(this, data);
if ( dialog.ShowModal() == wxID_OK ) if ( dialog.ShowModal() == wxID_OK )
DebuggerFont = dialog.GetFontData().GetChosenFont(); DebuggerFont = dialog.GetFontData().GetChosenFont();
} }

View File

@ -1,145 +1,145 @@
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2008 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0. // the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details. // GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program. // A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/ // If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at // Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
#include "ARCodeAddEdit.h" #include "ARCodeAddEdit.h"
extern std::vector<ActionReplay::ARCode> arCodes; extern std::vector<ActionReplay::ARCode> arCodes;
BEGIN_EVENT_TABLE(CARCodeAddEdit, wxDialog) BEGIN_EVENT_TABLE(CARCodeAddEdit, wxDialog)
EVT_CLOSE(CARCodeAddEdit::OnClose) EVT_CLOSE(CARCodeAddEdit::OnClose)
EVT_BUTTON(wxID_OK, CARCodeAddEdit::SaveCheatData) EVT_BUTTON(wxID_OK, CARCodeAddEdit::SaveCheatData)
EVT_SPIN(ID_ENTRY_SELECT, CARCodeAddEdit::ChangeEntry) EVT_SPIN(ID_ENTRY_SELECT, CARCodeAddEdit::ChangeEntry)
END_EVENT_TABLE() END_EVENT_TABLE()
CARCodeAddEdit::CARCodeAddEdit(int _selection, wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& position, const wxSize& size, long style) CARCodeAddEdit::CARCodeAddEdit(int _selection, wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& position, const wxSize& size, long style)
: wxDialog(parent, id, title, position, size, style) : wxDialog(parent, id, title, position, size, style)
{ {
selection = _selection; selection = _selection;
CreateGUIControls(selection); CreateGUIControls(selection);
} }
CARCodeAddEdit::~CARCodeAddEdit() CARCodeAddEdit::~CARCodeAddEdit()
{ {
} }
void CARCodeAddEdit::CreateGUIControls(int _selection) void CARCodeAddEdit::CreateGUIControls(int _selection)
{ {
wxString currentName = wxT("<Insert name here>"); wxString currentName = wxT("<Insert name here>");
if (_selection == -1) if (_selection == -1)
{ {
tempEntries.name = ""; tempEntries.name = "";
} }
else else
{ {
currentName = wxString::FromAscii(arCodes.at(_selection).name.c_str()); currentName = wxString::FromAscii(arCodes.at(_selection).name.c_str());
tempEntries = arCodes.at(_selection); tempEntries = arCodes.at(_selection);
} }
wxBoxSizer* sEditCheat = new wxBoxSizer(wxVERTICAL); wxBoxSizer* sEditCheat = new wxBoxSizer(wxVERTICAL);
wxStaticBoxSizer* sbEntry = new wxStaticBoxSizer(wxVERTICAL, this, _("Code")); wxStaticBoxSizer* sbEntry = new wxStaticBoxSizer(wxVERTICAL, this, _("Code"));
wxStaticText* EditCheatNameText = new wxStaticText(this, ID_EDITCHEAT_NAME_TEXT, _("Name:"), wxDefaultPosition, wxDefaultSize); wxStaticText* EditCheatNameText = new wxStaticText(this, ID_EDITCHEAT_NAME_TEXT, _("Name:"), wxDefaultPosition, wxDefaultSize);
EditCheatName = new wxTextCtrl(this, ID_EDITCHEAT_NAME, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0); EditCheatName = new wxTextCtrl(this, ID_EDITCHEAT_NAME, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0);
EditCheatName->SetValue(currentName); EditCheatName->SetValue(currentName);
EntrySelection = new wxSpinButton(this, ID_ENTRY_SELECT, wxDefaultPosition, wxDefaultSize, wxVERTICAL); EntrySelection = new wxSpinButton(this, ID_ENTRY_SELECT, wxDefaultPosition, wxDefaultSize, wxVERTICAL);
EntrySelection->SetRange(0, (int)arCodes.size()-1); EntrySelection->SetRange(0, (int)arCodes.size()-1);
EntrySelection->SetValue((int)arCodes.size()-1 - _selection); EntrySelection->SetValue((int)arCodes.size()-1 - _selection);
EditCheatCode = new wxTextCtrl(this, ID_EDITCHEAT_CODE, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE); EditCheatCode = new wxTextCtrl(this, ID_EDITCHEAT_CODE, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE);
UpdateTextCtrl(tempEntries); UpdateTextCtrl(tempEntries);
wxGridBagSizer* sgEntry = new wxGridBagSizer(0, 0); wxGridBagSizer* sgEntry = new wxGridBagSizer(0, 0);
sgEntry->AddGrowableCol(1); sgEntry->AddGrowableCol(1);
sgEntry->AddGrowableRow(1); sgEntry->AddGrowableRow(1);
sgEntry->Add(EditCheatNameText, wxGBPosition(0, 0), wxGBSpan(1, 1), wxALIGN_CENTER_VERTICAL|wxEXPAND|wxALL, 5); sgEntry->Add(EditCheatNameText, wxGBPosition(0, 0), wxGBSpan(1, 1), wxALIGN_CENTER_VERTICAL|wxEXPAND|wxALL, 5);
sgEntry->Add(EditCheatName, wxGBPosition(0, 1), wxGBSpan(1, 1), wxEXPAND|wxALL, 5); sgEntry->Add(EditCheatName, wxGBPosition(0, 1), wxGBSpan(1, 1), wxEXPAND|wxALL, 5);
sgEntry->Add(EntrySelection, wxGBPosition(0, 2), wxGBSpan(2, 1), wxEXPAND|wxALL, 5); sgEntry->Add(EntrySelection, wxGBPosition(0, 2), wxGBSpan(2, 1), wxEXPAND|wxALL, 5);
sgEntry->Add(EditCheatCode, wxGBPosition(1, 0), wxGBSpan(1, 2), wxEXPAND|wxALL, 5); sgEntry->Add(EditCheatCode, wxGBPosition(1, 0), wxGBSpan(1, 2), wxEXPAND|wxALL, 5);
sbEntry->Add(sgEntry, 1, wxEXPAND); sbEntry->Add(sgEntry, 1, wxEXPAND);
sEditCheat->Add(sbEntry, 1, wxEXPAND|wxALL, 5); sEditCheat->Add(sbEntry, 1, wxEXPAND|wxALL, 5);
wxBoxSizer* sEditCheatButtons = new wxBoxSizer(wxHORIZONTAL); wxBoxSizer* sEditCheatButtons = new wxBoxSizer(wxHORIZONTAL);
wxButton* bOK = new wxButton(this, wxID_OK, _("OK"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); wxButton* bOK = new wxButton(this, wxID_OK, _("OK"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
wxButton* bCancel = new wxButton(this, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); wxButton* bCancel = new wxButton(this, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
sEditCheatButtons->Add(0, 0, 1, wxEXPAND, 5); sEditCheatButtons->Add(0, 0, 1, wxEXPAND, 5);
sEditCheatButtons->Add(bOK, 0, wxALL, 5); sEditCheatButtons->Add(bOK, 0, wxALL, 5);
sEditCheatButtons->Add(bCancel, 0, wxALL, 5); sEditCheatButtons->Add(bCancel, 0, wxALL, 5);
sEditCheat->Add(sEditCheatButtons, 0, wxEXPAND, 5); sEditCheat->Add(sEditCheatButtons, 0, wxEXPAND, 5);
this->SetSizer(sEditCheat); this->SetSizer(sEditCheat);
sEditCheat->Layout(); sEditCheat->Layout();
} }
void CARCodeAddEdit::OnClose(wxCloseEvent& WXUNUSED (event)) void CARCodeAddEdit::OnClose(wxCloseEvent& WXUNUSED (event))
{ {
Destroy(); Destroy();
} }
void CARCodeAddEdit::ChangeEntry(wxSpinEvent& event) void CARCodeAddEdit::ChangeEntry(wxSpinEvent& event)
{ {
ActionReplay::ARCode currentCode = arCodes.at((int)arCodes.size()-1 - event.GetPosition()); ActionReplay::ARCode currentCode = arCodes.at((int)arCodes.size()-1 - event.GetPosition());
EditCheatName->SetValue(wxString::FromAscii(currentCode.name.c_str())); EditCheatName->SetValue(wxString::FromAscii(currentCode.name.c_str()));
UpdateTextCtrl(currentCode); UpdateTextCtrl(currentCode);
} }
void CARCodeAddEdit::SaveCheatData(wxCommandEvent& WXUNUSED (event)) void CARCodeAddEdit::SaveCheatData(wxCommandEvent& WXUNUSED (event))
{ {
std::vector<ActionReplay::AREntry> tempEntries; std::vector<ActionReplay::AREntry> tempEntries;
std::string cheatValues = std::string(EditCheatCode->GetValue().mb_str()); std::string cheatValues = std::string(EditCheatCode->GetValue().mb_str());
bool bWhile = true; size_t line = 0; bool bWhile = true; size_t line = 0;
while (bWhile) while (bWhile)
{ {
bWhile = false; bWhile = false;
u32 addr, value; u32 addr, value;
addr = strtol(std::string(cheatValues.substr(line, line+8)).c_str(), NULL, 16); // cmd_addr of ArCode addr = strtol(std::string(cheatValues.substr(line, line+8)).c_str(), NULL, 16); // cmd_addr of ArCode
value = strtol(std::string(cheatValues.substr(line+9, line+17)).c_str(), NULL, 16); // value of ArCode value = strtol(std::string(cheatValues.substr(line+9, line+17)).c_str(), NULL, 16); // value of ArCode
tempEntries.push_back(ActionReplay::AREntry(addr, value)); tempEntries.push_back(ActionReplay::AREntry(addr, value));
line = cheatValues.find("\n", line); line = cheatValues.find("\n", line);
if (line != std::string::npos && cheatValues.length() > (line+17)) if (line != std::string::npos && cheatValues.length() > (line+17))
bWhile = true; // newline found, if not empty, go on bWhile = true; // newline found, if not empty, go on
line++; line++;
} }
if (selection == -1) if (selection == -1)
{ {
ActionReplay::ARCode newCheat; ActionReplay::ARCode newCheat;
newCheat.name = std::string(EditCheatName->GetValue().mb_str()); newCheat.name = std::string(EditCheatName->GetValue().mb_str());
newCheat.ops = tempEntries; newCheat.ops = tempEntries;
newCheat.active = true; newCheat.active = true;
arCodes.push_back(newCheat); arCodes.push_back(newCheat);
} }
else else
{ {
arCodes.at(selection).name = std::string(EditCheatName->GetValue().mb_str()); arCodes.at(selection).name = std::string(EditCheatName->GetValue().mb_str());
arCodes.at(selection).ops = tempEntries; arCodes.at(selection).ops = tempEntries;
} }
AcceptAndClose(); AcceptAndClose();
} }
void CARCodeAddEdit::UpdateTextCtrl(ActionReplay::ARCode arCode) void CARCodeAddEdit::UpdateTextCtrl(ActionReplay::ARCode arCode)
{ {
EditCheatCode->Clear(); EditCheatCode->Clear();
for (u32 i = 0; i < arCode.ops.size(); i++) for (u32 i = 0; i < arCode.ops.size(); i++)
EditCheatCode->AppendText(wxString::Format(wxT("%08X %08X\n"), arCode.ops.at(i).cmd_addr, arCode.ops.at(i).value)); EditCheatCode->AppendText(wxString::Format(wxT("%08X %08X\n"), arCode.ops.at(i).cmd_addr, arCode.ops.at(i).value));
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,484 +1,484 @@
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2008 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0. // the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details. // GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program. // A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/ // If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at // Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////
// Include // Include
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#include "Globals.h" #include "Globals.h"
#include "Frame.h" #include "Frame.h"
#include "FileUtil.h" #include "FileUtil.h"
#include "StringUtil.h" #include "StringUtil.h"
#include "ConsoleWindow.h" #include "ConsoleWindow.h"
#include "GameListCtrl.h" #include "GameListCtrl.h"
#include "BootManager.h" #include "BootManager.h"
#include "Common.h" #include "Common.h"
#include "Setup.h" #include "Setup.h"
#include "ConfigManager.h" #include "ConfigManager.h"
#include "Core.h" #include "Core.h"
#include "State.h" #include "State.h"
#include "ConfigMain.h" #include "ConfigMain.h"
#include "PluginManager.h" #include "PluginManager.h"
#include "MemcardManager.h" #include "MemcardManager.h"
#include "CheatsWindow.h" #include "CheatsWindow.h"
#include "AboutDolphin.h" #include "AboutDolphin.h"
#include <wx/statusbr.h> #include <wx/statusbr.h>
///////////////////////////////////////// /////////////////////////////////////////
namespace WiimoteLeds namespace WiimoteLeds
{ {
int LED_SIZE_X = 8; int LED_SIZE_X = 8;
int LED_SIZE_Y = 8; int LED_SIZE_Y = 8;
int SPEAKER_SIZE_X = 8; int SPEAKER_SIZE_X = 8;
int SPEAKER_SIZE_Y = 8; int SPEAKER_SIZE_Y = 8;
int ConnectionStatusWidth = 103; // These widths need to be revised, for vista at least int ConnectionStatusWidth = 103; // These widths need to be revised, for vista at least
int ConnectionStatusOnlyAdj = 7; int ConnectionStatusOnlyAdj = 7;
int RightmostMargin = 6; int RightmostMargin = 6;
int SpIconMargin = 11; int SpIconMargin = 11;
int LedIconMargin = 11; int LedIconMargin = 11;
// The necessary recording status width, allow Frame to be at last of the form 100,000 // The necessary recording status width, allow Frame to be at last of the form 100,000
#ifdef RERECORDING #ifdef RERECORDING
static const int RerecordingStatusWidth = 340; static const int RerecordingStatusWidth = 340;
#endif #endif
// Leds only // Leds only
static const int LdWidthsOn[] = static const int LdWidthsOn[] =
{ {
-1, -1,
#ifdef RERECORDING #ifdef RERECORDING
RerecordingStatusWidth, RerecordingStatusWidth,
#endif #endif
ConnectionStatusWidth, ConnectionStatusWidth,
(LedIconMargin + LED_SIZE_X) * 4 + RightmostMargin (LedIconMargin + LED_SIZE_X) * 4 + RightmostMargin
}; };
static const int StylesFieldOn[] = { wxSB_NORMAL, wxSB_NORMAL, wxSB_NORMAL }; static const int StylesFieldOn[] = { wxSB_NORMAL, wxSB_NORMAL, wxSB_NORMAL };
// Speakers only // Speakers only
static const int SpWidthsOn[] = static const int SpWidthsOn[] =
{ {
-1, -1,
#ifdef RERECORDING #ifdef RERECORDING
RerecordingStatusWidth, RerecordingStatusWidth,
#endif #endif
ConnectionStatusWidth, ConnectionStatusWidth,
( SpIconMargin + SPEAKER_SIZE_X ) * 3 + RightmostMargin ( SpIconMargin + SPEAKER_SIZE_X ) * 3 + RightmostMargin
}; };
static const int SpStylesFieldOn[] = { wxSB_NORMAL, static const int SpStylesFieldOn[] = { wxSB_NORMAL,
#ifdef RERECORDING #ifdef RERECORDING
wxSB_NORMAL, wxSB_NORMAL,
#endif #endif
wxSB_NORMAL, wxSB_NORMAL }; wxSB_NORMAL, wxSB_NORMAL };
// Both // Both
static const int LdSpWidthsOn[] = static const int LdSpWidthsOn[] =
{ {
-1, -1,
#ifdef RERECORDING #ifdef RERECORDING
RerecordingStatusWidth, RerecordingStatusWidth,
#endif #endif
ConnectionStatusWidth, ConnectionStatusWidth,
(SpIconMargin + SPEAKER_SIZE_X) * 3, (SpIconMargin + SPEAKER_SIZE_X) * 3,
(LedIconMargin + LED_SIZE_X) * 4 + RightmostMargin (LedIconMargin + LED_SIZE_X) * 4 + RightmostMargin
}; };
static const int LdSpStylesFieldOn[] = { wxSB_NORMAL, static const int LdSpStylesFieldOn[] = { wxSB_NORMAL,
#ifdef RERECORDING #ifdef RERECORDING
wxSB_NORMAL, wxSB_NORMAL,
#endif #endif
wxSB_NORMAL, wxSB_NORMAL }; wxSB_NORMAL, wxSB_NORMAL };
// Only the Wiimote connection Status // Only the Wiimote connection Status
static const int WidthsOff[] = static const int WidthsOff[] =
{ {
-1, -1,
#ifdef RERECORDING #ifdef RERECORDING
RerecordingStatusWidth, RerecordingStatusWidth,
#endif #endif
ConnectionStatusWidth + ConnectionStatusOnlyAdj + RightmostMargin ConnectionStatusWidth + ConnectionStatusOnlyAdj + RightmostMargin
}; };
static const int StylesFieldOff[] = { wxSB_NORMAL, static const int StylesFieldOff[] = { wxSB_NORMAL,
#ifdef RERECORDING #ifdef RERECORDING
wxSB_NORMAL, wxSB_NORMAL,
#endif #endif
wxSB_NORMAL }; wxSB_NORMAL };
// GC mode // GC mode
static const int WidthsOffGC[] = { -1 static const int WidthsOffGC[] = { -1
#ifdef RERECORDING #ifdef RERECORDING
, RerecordingStatusWidth , RerecordingStatusWidth
#endif #endif
}; };
static const int StylesFieldOffGC[] = { wxSB_NORMAL static const int StylesFieldOffGC[] = { wxSB_NORMAL
#ifdef RERECORDING #ifdef RERECORDING
, wxSB_NORMAL , wxSB_NORMAL
#endif #endif
}; };
}; };
// ======================================================= // =======================================================
// Modify status bar // Modify status bar
// ------------- // -------------
void CFrame::ModifyStatusBar() void CFrame::ModifyStatusBar()
{ {
// Get settings // Get settings
bool LedsOn = SConfig::GetInstance().m_LocalCoreStartupParameter.bWiiLeds; bool LedsOn = SConfig::GetInstance().m_LocalCoreStartupParameter.bWiiLeds;
bool SpeakersOn = SConfig::GetInstance().m_LocalCoreStartupParameter.bWiiSpeakers; bool SpeakersOn = SConfig::GetInstance().m_LocalCoreStartupParameter.bWiiSpeakers;
// Don't use this for GC games, or before a game is loaded // Don't use this for GC games, or before a game is loaded
if(!SConfig::GetInstance().m_LocalCoreStartupParameter.bWii) if(!SConfig::GetInstance().m_LocalCoreStartupParameter.bWii)
{ LedsOn = false; SpeakersOn = false; } { LedsOn = false; SpeakersOn = false; }
// Declarations // Declarations
int Fields = 0; int Fields = 0;
int *Widths = 0; int *Widths = 0;
int *StylesFields = 0; int *StylesFields = 0;
// --------------------------------------- // ---------------------------------------
// Leds only // Leds only
// ------------- // -------------
if(LedsOn && !SpeakersOn) if(LedsOn && !SpeakersOn)
{ {
Fields = 3; Fields = 3;
Widths = (int*)WiimoteLeds::LdWidthsOn; Widths = (int*)WiimoteLeds::LdWidthsOn;
StylesFields = (int*)WiimoteLeds::StylesFieldOn; StylesFields = (int*)WiimoteLeds::StylesFieldOn;
} }
// --------------------------------------- // ---------------------------------------
// Speaker only // Speaker only
// ------------- // -------------
else if(!LedsOn && SpeakersOn) else if(!LedsOn && SpeakersOn)
{ {
Fields = 3; Fields = 3;
Widths = (int*)WiimoteLeds::SpWidthsOn; Widths = (int*)WiimoteLeds::SpWidthsOn;
StylesFields = (int*)WiimoteLeds::SpStylesFieldOn; StylesFields = (int*)WiimoteLeds::SpStylesFieldOn;
} }
// --------------------------------------- // ---------------------------------------
// Both on // Both on
// ------------- // -------------
else if(LedsOn && SpeakersOn) else if(LedsOn && SpeakersOn)
{ {
Fields = 4; Fields = 4;
Widths = (int*)WiimoteLeds::LdSpWidthsOn; Widths = (int*)WiimoteLeds::LdSpWidthsOn;
StylesFields = (int*)WiimoteLeds::LdSpStylesFieldOn; StylesFields = (int*)WiimoteLeds::LdSpStylesFieldOn;
} }
// --------------------------------------- // ---------------------------------------
// Both off // Both off
// ------------- // -------------
else if(!LedsOn && !SpeakersOn) else if(!LedsOn && !SpeakersOn)
{ {
Fields = 2; Fields = 2;
Widths = (int*)WiimoteLeds::WidthsOff; Widths = (int*)WiimoteLeds::WidthsOff;
StylesFields = (int*)WiimoteLeds::StylesFieldOff; StylesFields = (int*)WiimoteLeds::StylesFieldOff;
// Maybe we should even go down to one field // Maybe we should even go down to one field
if(!SConfig::GetInstance().m_LocalCoreStartupParameter.bWii) if(!SConfig::GetInstance().m_LocalCoreStartupParameter.bWii)
{ {
Fields = 1; Fields = 1;
Widths = (int*)WiimoteLeds::WidthsOffGC; Widths = (int*)WiimoteLeds::WidthsOffGC;
StylesFields = (int*)WiimoteLeds::StylesFieldOffGC; StylesFields = (int*)WiimoteLeds::StylesFieldOffGC;
} }
} }
// Add a filed for the rerecording status // Add a filed for the rerecording status
#ifdef RERECORDING #ifdef RERECORDING
Fields++; Fields++;
#endif #endif
// Update the settings // Update the settings
m_pStatusBar->SetFieldsCount(Fields); m_pStatusBar->SetFieldsCount(Fields);
m_pStatusBar->SetStatusWidths(Fields, Widths); m_pStatusBar->SetStatusWidths(Fields, Widths);
m_pStatusBar->SetStatusStyles(Fields, StylesFields); m_pStatusBar->SetStatusStyles(Fields, StylesFields);
/* Destroy and create all, and check for HaveLeds and HaveSpeakers in case we have /* Destroy and create all, and check for HaveLeds and HaveSpeakers in case we have
gotten a confirmed on or off setting, in which case we don't do anything */ gotten a confirmed on or off setting, in which case we don't do anything */
if(!LedsOn && HaveLeds) CreateDestroy(DESTROYLEDS); if(!LedsOn && HaveLeds) CreateDestroy(DESTROYLEDS);
if(!SpeakersOn && HaveSpeakers) CreateDestroy(DESTROYSPEAKERS); if(!SpeakersOn && HaveSpeakers) CreateDestroy(DESTROYSPEAKERS);
if(LedsOn && !HaveLeds) CreateDestroy(CREATELEDS); if(LedsOn && !HaveLeds) CreateDestroy(CREATELEDS);
if(SpeakersOn && !HaveSpeakers) CreateDestroy(CREATESPEAKERS); if(SpeakersOn && !HaveSpeakers) CreateDestroy(CREATESPEAKERS);
DoMoveIcons(); DoMoveIcons();
m_pStatusBar->Refresh(); // avoid small glitches that can occur m_pStatusBar->Refresh(); // avoid small glitches that can occur
} }
// ======================================================= // =======================================================
// Create and destroy leds and speakers icons // Create and destroy leds and speakers icons
// ------------- // -------------
void CFrame::CreateDestroy(int Case) void CFrame::CreateDestroy(int Case)
{ {
switch(Case) switch(Case)
{ {
case CREATELEDS: case CREATELEDS:
{ {
CreateLeds(); CreateLeds();
UpdateLeds(); UpdateLeds();
HaveLeds = true; HaveLeds = true;
break; break;
} }
case DESTROYLEDS: case DESTROYLEDS:
{ {
for(int i = 0; i < 4; i++) for(int i = 0; i < 4; i++)
{ {
m_StatBmp[i]->Destroy(); m_StatBmp[i]->Destroy();
} }
HaveLeds = false; HaveLeds = false;
break; break;
} }
case CREATESPEAKERS: case CREATESPEAKERS:
{ {
CreateSpeakers(); CreateSpeakers();
HaveSpeakers = true; HaveSpeakers = true;
break; break;
} }
case DESTROYSPEAKERS: case DESTROYSPEAKERS:
{ {
for(int i = 4; i < 7; i++) for(int i = 4; i < 7; i++)
{ {
m_StatBmp[i]->Destroy(); m_StatBmp[i]->Destroy();
} }
HaveSpeakers = false; HaveSpeakers = false;
break; break;
} }
} // end of switch } // end of switch
DoMoveIcons(); DoMoveIcons();
} }
// ============= // =============
// ======================================================= // =======================================================
// Create and update leds // Create and update leds
// ------------- // -------------
void CFrame::CreateLeds() void CFrame::CreateLeds()
{ {
// Begin with blank ones // Begin with blank ones
memset(&g_Leds, 0, sizeof(g_Leds)); memset(&g_Leds, 0, sizeof(g_Leds));
for(int i = 0; i < 4; i++) for(int i = 0; i < 4; i++)
{ {
m_StatBmp[i] = new wxStaticBitmap(m_pStatusBar, wxID_ANY, m_StatBmp[i] = new wxStaticBitmap(m_pStatusBar, wxID_ANY,
CreateBitmapForLeds(g_Leds[i] == 1)); CreateBitmapForLeds(g_Leds[i] == 1));
} }
} }
// Update leds // Update leds
void CFrame::UpdateLeds() void CFrame::UpdateLeds()
{ {
for(int i = 0; i < 4; i++) for(int i = 0; i < 4; i++)
{ {
m_StatBmp[i]->SetBitmap(CreateBitmapForLeds(g_Leds[i] != 0)); m_StatBmp[i]->SetBitmap(CreateBitmapForLeds(g_Leds[i] != 0));
} }
} }
// ============== // ==============
// ======================================================= // =======================================================
// Create and speaker icons // Create and speaker icons
// ------------- // -------------
void CFrame::CreateSpeakers() void CFrame::CreateSpeakers()
{ {
// Begin with blank ones // Begin with blank ones
memset(&g_Speakers, 0, sizeof(g_Speakers)); memset(&g_Speakers, 0, sizeof(g_Speakers));
memset(&g_Speakers_, 0, sizeof(g_Speakers_)); memset(&g_Speakers_, 0, sizeof(g_Speakers_));
for(int i = 0; i < 3; i++) for(int i = 0; i < 3; i++)
{ {
m_StatBmp[i+4] = new wxStaticBitmap(m_pStatusBar, wxID_ANY, m_StatBmp[i+4] = new wxStaticBitmap(m_pStatusBar, wxID_ANY,
CreateBitmapForSpeakers(i, g_Speakers[i] != 0)); CreateBitmapForSpeakers(i, g_Speakers[i] != 0));
} }
} }
// Update icons // Update icons
void CFrame::UpdateSpeakers() void CFrame::UpdateSpeakers()
{ {
/*if(!SConfig::GetInstance().m_LocalCoreStartupParameter.bNTSC) /*if(!SConfig::GetInstance().m_LocalCoreStartupParameter.bNTSC)
{ PanicAlert("Not NTSC");} { PanicAlert("Not NTSC");}
if(!SConfig::GetInstance().m_LocalCoreStartupParameter.bWii) if(!SConfig::GetInstance().m_LocalCoreStartupParameter.bWii)
{ PanicAlert("Not Wii");}*/ { PanicAlert("Not Wii");}*/
for(int i = 0; i < 3; i++) for(int i = 0; i < 3; i++)
{ {
m_StatBmp[i+4]->SetBitmap(CreateBitmapForSpeakers(i, g_Speakers[i] != 0)); m_StatBmp[i+4]->SetBitmap(CreateBitmapForSpeakers(i, g_Speakers[i] != 0));
} }
} }
// ============== // ==============
// ======================================================= // =======================================================
// Create the Leds bitmap // Create the Leds bitmap
// ------------- // -------------
wxBitmap CFrame::CreateBitmapForLeds(bool On) wxBitmap CFrame::CreateBitmapForLeds(bool On)
{ {
wxBitmap bitmap(WiimoteLeds::LED_SIZE_X, WiimoteLeds::LED_SIZE_Y); wxBitmap bitmap(WiimoteLeds::LED_SIZE_X, WiimoteLeds::LED_SIZE_Y);
wxMemoryDC dc; wxMemoryDC dc;
dc.SelectObject(bitmap); dc.SelectObject(bitmap);
// Set outline and fill colors // Set outline and fill colors
wxBrush LightBlueBrush(_T("#0383f0")); wxBrush LightBlueBrush(_T("#0383f0"));
wxPen LightBluePen(_T("#80c5fd")); wxPen LightBluePen(_T("#80c5fd"));
wxPen LightGrayPen(_T("#909090")); wxPen LightGrayPen(_T("#909090"));
dc.SetPen(On ? LightBluePen : LightGrayPen); dc.SetPen(On ? LightBluePen : LightGrayPen);
dc.SetBrush(On ? LightBlueBrush : *wxWHITE_BRUSH); dc.SetBrush(On ? LightBlueBrush : *wxWHITE_BRUSH);
dc.Clear(); dc.Clear();
dc.DrawRectangle(0, 0, WiimoteLeds::LED_SIZE_X, WiimoteLeds::LED_SIZE_Y); dc.DrawRectangle(0, 0, WiimoteLeds::LED_SIZE_X, WiimoteLeds::LED_SIZE_Y);
dc.SelectObject(wxNullBitmap); dc.SelectObject(wxNullBitmap);
return bitmap; return bitmap;
} }
// ======================================================= // =======================================================
// Create the Speaker bitmap // Create the Speaker bitmap
// ------------- // -------------
wxBitmap CFrame::CreateBitmapForSpeakers(int BitmapType, bool On) wxBitmap CFrame::CreateBitmapForSpeakers(int BitmapType, bool On)
{ {
wxBitmap bitmap(WiimoteLeds::LED_SIZE_X, WiimoteLeds::LED_SIZE_Y); wxBitmap bitmap(WiimoteLeds::LED_SIZE_X, WiimoteLeds::LED_SIZE_Y);
wxMemoryDC dc; wxMemoryDC dc;
dc.SelectObject(bitmap); dc.SelectObject(bitmap);
wxBrush BackgroundGrayBrush(_T("#ece9d8")); // the right color in windows wxBrush BackgroundGrayBrush(_T("#ece9d8")); // the right color in windows
switch(BitmapType) switch(BitmapType)
{ {
case 0: // Speaker on case 0: // Speaker on
{ {
// Set outline and fill colors // Set outline and fill colors
dc.SetPen(On ? *wxMEDIUM_GREY_PEN : *wxMEDIUM_GREY_PEN); dc.SetPen(On ? *wxMEDIUM_GREY_PEN : *wxMEDIUM_GREY_PEN);
dc.SetBrush(On ? *wxGREEN_BRUSH : *wxWHITE_BRUSH); dc.SetBrush(On ? *wxGREEN_BRUSH : *wxWHITE_BRUSH);
dc.SetBackground(BackgroundGrayBrush); dc.SetBackground(BackgroundGrayBrush);
dc.Clear(); dc.Clear();
dc.DrawEllipse(0, 0, WiimoteLeds::SPEAKER_SIZE_X, WiimoteLeds::SPEAKER_SIZE_Y); dc.DrawEllipse(0, 0, WiimoteLeds::SPEAKER_SIZE_X, WiimoteLeds::SPEAKER_SIZE_Y);
dc.SelectObject(wxNullBitmap); dc.SelectObject(wxNullBitmap);
return bitmap; return bitmap;
} }
case 1: // Speaker unmuted case 1: // Speaker unmuted
{ {
// Set outline and fill colors // Set outline and fill colors
dc.SetPen(On ? *wxMEDIUM_GREY_PEN : *wxMEDIUM_GREY_PEN); dc.SetPen(On ? *wxMEDIUM_GREY_PEN : *wxMEDIUM_GREY_PEN);
dc.SetBrush(On ? *wxBLUE_BRUSH : *wxWHITE_BRUSH); dc.SetBrush(On ? *wxBLUE_BRUSH : *wxWHITE_BRUSH);
dc.SetBackground(BackgroundGrayBrush); dc.SetBackground(BackgroundGrayBrush);
dc.Clear(); dc.Clear();
dc.DrawEllipse(0, 0, WiimoteLeds::SPEAKER_SIZE_X, WiimoteLeds::SPEAKER_SIZE_Y); dc.DrawEllipse(0, 0, WiimoteLeds::SPEAKER_SIZE_X, WiimoteLeds::SPEAKER_SIZE_Y);
dc.SelectObject(wxNullBitmap); dc.SelectObject(wxNullBitmap);
return bitmap; return bitmap;
} }
case 2: // Speaker activity case 2: // Speaker activity
{ {
// Set outline and fill colors // Set outline and fill colors
dc.SetPen(On ? *wxMEDIUM_GREY_PEN : *wxMEDIUM_GREY_PEN); dc.SetPen(On ? *wxMEDIUM_GREY_PEN : *wxMEDIUM_GREY_PEN);
dc.SetBrush(On ? *wxGREEN_BRUSH : *wxWHITE_BRUSH); dc.SetBrush(On ? *wxGREEN_BRUSH : *wxWHITE_BRUSH);
dc.SetBackground(BackgroundGrayBrush); dc.SetBackground(BackgroundGrayBrush);
dc.Clear(); dc.Clear();
dc.DrawEllipse(0, 0, WiimoteLeds::SPEAKER_SIZE_X, WiimoteLeds::SPEAKER_SIZE_Y); dc.DrawEllipse(0, 0, WiimoteLeds::SPEAKER_SIZE_X, WiimoteLeds::SPEAKER_SIZE_Y);
dc.SelectObject(wxNullBitmap); dc.SelectObject(wxNullBitmap);
return bitmap; return bitmap;
} }
} }
return bitmap; return bitmap;
} }
// ======================================================= // =======================================================
// Move the bitmaps // Move the bitmaps
// ------------- // -------------
void CFrame::DoMoveIcons() void CFrame::DoMoveIcons()
{ {
if(HaveLeds) MoveLeds(); if(HaveLeds) MoveLeds();
if(HaveSpeakers) MoveSpeakers(); if(HaveSpeakers) MoveSpeakers();
// If there is not room for the led icons hide them // If there is not room for the led icons hide them
if(m_pStatusBar->GetFieldsCount() >= 2 && HaveLeds) if(m_pStatusBar->GetFieldsCount() >= 2 && HaveLeds)
{ {
wxRect Rect; wxRect Rect;
#ifdef RERECORDING #ifdef RERECORDING
m_pStatusBar->GetFieldRect((HaveLeds && HaveSpeakers) ? 4 : 3, Rect); m_pStatusBar->GetFieldRect((HaveLeds && HaveSpeakers) ? 4 : 3, Rect);
#else #else
m_pStatusBar->GetFieldRect((HaveLeds && HaveSpeakers) ? 3 : 2, Rect); m_pStatusBar->GetFieldRect((HaveLeds && HaveSpeakers) ? 3 : 2, Rect);
#endif #endif
if(Rect.GetWidth() < 20) if(Rect.GetWidth() < 20)
for (int i = 0; i < 4; i++) m_StatBmp[i]->Hide(); for (int i = 0; i < 4; i++) m_StatBmp[i]->Hide();
else // if(!m_StatBmp[0]->IsShown()) else // if(!m_StatBmp[0]->IsShown())
for (int i = 0; i < 4; i++) m_StatBmp[i]->Show(); for (int i = 0; i < 4; i++) m_StatBmp[i]->Show();
//Console::Print("LED: %i ", Rect.GetWidth()); //Console::Print("LED: %i ", Rect.GetWidth());
} }
// If there is not room for the speaker icons hide them // If there is not room for the speaker icons hide them
if(m_pStatusBar->GetFieldsCount() >= 2 && HaveSpeakers) if(m_pStatusBar->GetFieldsCount() >= 2 && HaveSpeakers)
{ {
wxRect Rect; wxRect Rect;
#ifdef RERECORDING #ifdef RERECORDING
m_pStatusBar->GetFieldRect(3, Rect); m_pStatusBar->GetFieldRect(3, Rect);
#else #else
m_pStatusBar->GetFieldRect(2, Rect); m_pStatusBar->GetFieldRect(2, Rect);
#endif #endif
if(Rect.GetWidth() < 20) if(Rect.GetWidth() < 20)
for(int i = 0; i < 3; i++) m_StatBmp[i + 4]->Hide(); for(int i = 0; i < 3; i++) m_StatBmp[i + 4]->Hide();
else // if(!m_StatBmp[4]->IsShown()) else // if(!m_StatBmp[4]->IsShown())
for (int i = 0; i < 3; i++) m_StatBmp[i + 4]->Show(); for (int i = 0; i < 3; i++) m_StatBmp[i + 4]->Show();
//Console::Print("Speaker: %i\n", Rect.GetWidth()); //Console::Print("Speaker: %i\n", Rect.GetWidth());
} }
} }
void CFrame::MoveLeds() void CFrame::MoveLeds()
{ {
wxRect Rect; wxRect Rect;
// Get the bitmap field coordinates // Get the bitmap field coordinates
#ifdef RERECORDING #ifdef RERECORDING
m_pStatusBar->GetFieldRect((HaveLeds && HaveSpeakers) ? 4 : 3, Rect); m_pStatusBar->GetFieldRect((HaveLeds && HaveSpeakers) ? 4 : 3, Rect);
#else #else
m_pStatusBar->GetFieldRect((HaveLeds && HaveSpeakers) ? 3 : 2, Rect); m_pStatusBar->GetFieldRect((HaveLeds && HaveSpeakers) ? 3 : 2, Rect);
#endif #endif
wxSize Size = m_StatBmp[0]->GetSize(); // Get the bitmap size wxSize Size = m_StatBmp[0]->GetSize(); // Get the bitmap size
//wxMessageBox(wxString::Format("%i", Rect.x)); //wxMessageBox(wxString::Format("%i", Rect.x));
int x = Rect.x + 10; int x = Rect.x + 10;
int Dist = WiimoteLeds::LED_SIZE_X + 7; int Dist = WiimoteLeds::LED_SIZE_X + 7;
int y = Rect.y + (Rect.height - Size.y) / 2; int y = Rect.y + (Rect.height - Size.y) / 2;
for(int i = 0; i < 4; i++) for(int i = 0; i < 4; i++)
{ {
if(i > 0) x = m_StatBmp[i-1]->GetPosition().x + Dist; if(i > 0) x = m_StatBmp[i-1]->GetPosition().x + Dist;
m_StatBmp[i]->Move(x, y); m_StatBmp[i]->Move(x, y);
} }
} }
void CFrame::MoveSpeakers() void CFrame::MoveSpeakers()
{ {
wxRect Rect; wxRect Rect;
// Get the bitmap field coordinates // Get the bitmap field coordinates
#ifdef RERECORDING #ifdef RERECORDING
m_pStatusBar->GetFieldRect(3, Rect); m_pStatusBar->GetFieldRect(3, Rect);
#else #else
m_pStatusBar->GetFieldRect(2, Rect); m_pStatusBar->GetFieldRect(2, Rect);
#endif #endif
// Get the actual bitmap size, currently it's the same as SPEAKER_SIZE_Y // Get the actual bitmap size, currently it's the same as SPEAKER_SIZE_Y
wxSize Size = m_StatBmp[4]->GetSize(); wxSize Size = m_StatBmp[4]->GetSize();
//wxMessageBox(wxString::Format("%i", Rect.x)); //wxMessageBox(wxString::Format("%i", Rect.x));
int x = Rect.x + 9; int x = Rect.x + 9;
int Dist = WiimoteLeds::SPEAKER_SIZE_X + 7; int Dist = WiimoteLeds::SPEAKER_SIZE_X + 7;
int y = Rect.y + (Rect.height - Size.y) / 2; int y = Rect.y + (Rect.height - Size.y) / 2;
for(int i = 0; i < 3; i++) for(int i = 0; i < 3; i++)
{ {
if(i > 0) x = m_StatBmp[i-1+4]->GetPosition().x + Dist; if(i > 0) x = m_StatBmp[i-1+4]->GetPosition().x + Dist;
m_StatBmp[i + 4]->Move(x, y); m_StatBmp[i + 4]->Move(x, y);
} }
} }
// ============== // ==============

View File

@ -1,63 +1,63 @@
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2008 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0. // the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details. // GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program. // A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/ // If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at // Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
#include "SDCardWindow.h" #include "SDCardWindow.h"
#include "Globals.h" #include "Globals.h"
#include "IPC_HLE/HW/SDInterface.h" #include "IPC_HLE/HW/SDInterface.h"
BEGIN_EVENT_TABLE(wxSDCardWindow, wxWindow) BEGIN_EVENT_TABLE(wxSDCardWindow, wxWindow)
EVT_CLOSE( wxSDCardWindow::OnEvent_Window_Close) EVT_CLOSE( wxSDCardWindow::OnEvent_Window_Close)
EVT_BUTTON(ID_BUTTON_CLOSE, wxSDCardWindow::OnEvent_ButtonClose_Press) EVT_BUTTON(ID_BUTTON_CLOSE, wxSDCardWindow::OnEvent_ButtonClose_Press)
END_EVENT_TABLE() END_EVENT_TABLE()
wxSDCardWindow::wxSDCardWindow(wxWindow* parent) : wxSDCardWindow::wxSDCardWindow(wxWindow* parent) :
wxDialog(parent, wxID_ANY, _T("SDCard Mounter"), wxDefaultPosition, wxSize(400, 400), wxDEFAULT_FRAME_STYLE | wxNO_FULL_REPAINT_ON_RESIZE) wxDialog(parent, wxID_ANY, _T("SDCard Mounter"), wxDefaultPosition, wxSize(400, 400), wxDEFAULT_FRAME_STYLE | wxNO_FULL_REPAINT_ON_RESIZE)
{ {
Init_ChildControls(); Init_ChildControls();
Layout(); Layout();
Show(); Show();
} }
wxSDCardWindow::~wxSDCardWindow() wxSDCardWindow::~wxSDCardWindow()
{ {
// On Disposal // On Disposal
} }
void wxSDCardWindow::Init_ChildControls() void wxSDCardWindow::Init_ChildControls()
{ {
// Button Strip // Button Strip
m_Button_Close = new wxButton(this, ID_BUTTON_CLOSE, _T("Close"), wxDefaultPosition, wxDefaultSize); m_Button_Close = new wxButton(this, ID_BUTTON_CLOSE, _T("Close"), wxDefaultPosition, wxDefaultSize);
wxBoxSizer* sButtons = new wxBoxSizer(wxHORIZONTAL); wxBoxSizer* sButtons = new wxBoxSizer(wxHORIZONTAL);
sButtons->Add(m_Button_Close, 0, wxALL, 5); sButtons->Add(m_Button_Close, 0, wxALL, 5);
wxBoxSizer* sMain = new wxBoxSizer(wxVERTICAL); wxBoxSizer* sMain = new wxBoxSizer(wxVERTICAL);
sMain->Add(sButtons, 0, wxALL, 5); sMain->Add(sButtons, 0, wxALL, 5);
SetSizer(sMain); SetSizer(sMain);
Layout(); Layout();
Fit(); Fit();
} }
void wxSDCardWindow::OnEvent_Window_Close(wxCloseEvent& WXUNUSED(event)) void wxSDCardWindow::OnEvent_Window_Close(wxCloseEvent& WXUNUSED(event))
{ {
EndModal(0); EndModal(0);
} }
void wxSDCardWindow::OnEvent_ButtonClose_Press(wxCommandEvent& WXUNUSED(event)) void wxSDCardWindow::OnEvent_ButtonClose_Press(wxCommandEvent& WXUNUSED(event))
{ {
EndModal(0); EndModal(0);
} }

View File

@ -1,252 +1,252 @@
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Project description // Project description
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// Name: Input Configuration and Calibration // Name: Input Configuration and Calibration
// Description: Common SDL Input Functions // Description: Common SDL Input Functions
// //
// Author: Falcon4ever (nJoy@falcon4ever.com, www.multigesture.net), JPeterson etc // Author: Falcon4ever (nJoy@falcon4ever.com, www.multigesture.net), JPeterson etc
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2008 Dolphin Project.
// //
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// //
// Licensetype: GNU General Public License (GPL) // Licensetype: GNU General Public License (GPL)
// //
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0. // the Free Software Foundation, version 2.0.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details. // GNU General Public License 2.0 for more details.
// //
// A copy of the GPL 2.0 should have been included with the program. // A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/ // If not, see http://www.gnu.org/licenses/
// //
// Official SVN repository and contact information can be found at // Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
// //
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Include // Include
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#if defined HAVE_WX && HAVE_WX #if defined HAVE_WX && HAVE_WX
#include <wx/wx.h> #include <wx/wx.h>
#endif #endif
#include "SDL.h" // Local #include "SDL.h" // Local
//////////////////////////////////// ////////////////////////////////////
namespace InputCommon namespace InputCommon
{ {
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Degree to radian and back // Degree to radian and back
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
float Deg2Rad(float Deg) float Deg2Rad(float Deg)
{ {
return Deg * ((float)M_PI / 180.0f); return Deg * ((float)M_PI / 180.0f);
} }
float Rad2Deg(float Rad) float Rad2Deg(float Rad)
{ {
return (Rad * 180.0f) / (float)M_PI; return (Rad * 180.0f) / (float)M_PI;
} }
///////////////////////////////////////// /////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Check if the pad is within the dead zone, we assume the range is 0x8000 // Check if the pad is within the dead zone, we assume the range is 0x8000
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
float CoordinatesToRadius(int x, int y) float CoordinatesToRadius(int x, int y)
{ {
return sqrt(pow((float)x, 2) + pow((float)y, 2)); return sqrt(pow((float)x, 2) + pow((float)y, 2));
} }
bool IsDeadZone(float DeadZone, int x, int y) bool IsDeadZone(float DeadZone, int x, int y)
{ {
// Get the distance from the center // Get the distance from the center
float Distance = CoordinatesToRadius(x, y) / 32767.0f; float Distance = CoordinatesToRadius(x, y) / 32767.0f;
//Console::Print("%f\n", Distance); //Console::Print("%f\n", Distance);
// Check if it's within the dead zone // Check if it's within the dead zone
if (Distance <= DeadZone) if (Distance <= DeadZone)
return true; return true;
else else
return false; return false;
} }
///////////////////////////////////////// /////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Scale down stick values from 0x8000 to 0x80 // Scale down stick values from 0x8000 to 0x80
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> /* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
The value returned by SDL_JoystickGetAxis is a signed integer s16 The value returned by SDL_JoystickGetAxis is a signed integer s16
(-32768 to 32767). The value used for the gamecube controller is an unsigned (-32768 to 32767). The value used for the gamecube controller is an unsigned
char u8 (0 to 255) with neutral at 0x80 (128), so that it's equivalent to a signed char u8 (0 to 255) with neutral at 0x80 (128), so that it's equivalent to a signed
-128 to 127. -128 to 127.
*/ */
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
int Pad_Convert(int _val) int Pad_Convert(int _val)
{ {
/* If the limits on PadState[].axis[] actually is a u16 then we don't need this /* If the limits on PadState[].axis[] actually is a u16 then we don't need this
but if it's not actually limited to that we need to apply these limits */ but if it's not actually limited to that we need to apply these limits */
if(_val > 32767) _val = 32767; // upper limit if(_val > 32767) _val = 32767; // upper limit
if(_val < -32768) _val = -32768; // lower limit if(_val < -32768) _val = -32768; // lower limit
// Convert the range (-0x8000 to 0x7fff) to (0 to 0xffff) // Convert the range (-0x8000 to 0x7fff) to (0 to 0xffff)
_val = 0x8000 +_val; _val = 0x8000 +_val;
// Convert the range (-32768 to 32767) to (-128 to 127) // Convert the range (-32768 to 32767) to (-128 to 127)
_val = _val >> 8; _val = _val >> 8;
//Console::Print("0x%04x %06i\n\n", _val, _val); //Console::Print("0x%04x %06i\n\n", _val, _val);
return _val; return _val;
} }
///////////////////////////////////////// /////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
/* Convert the stick raidus from a square or rounded box to a circular radius. I don't know what /* Convert the stick raidus from a square or rounded box to a circular radius. I don't know what
input values the actual GC controller produce for the GC, it may be a square, a circle or input values the actual GC controller produce for the GC, it may be a square, a circle or
something in between. But one thing that is certain is that PC pads differ in their output something in between. But one thing that is certain is that PC pads differ in their output
(as shown in the list below), so it may be beneficiary to convert whatever radius they (as shown in the list below), so it may be beneficiary to convert whatever radius they
produce to the radius the GC games expect. This is the first implementation of this produce to the radius the GC games expect. This is the first implementation of this
that convert a square radius to a circual radius. Use the advanced settings to enable that convert a square radius to a circual radius. Use the advanced settings to enable
and calibrate it. and calibrate it.
Observed diagonals: Observed diagonals:
Perfect circle: 71% = sin(45) Perfect circle: 71% = sin(45)
Logitech Dual Action: 100% Logitech Dual Action: 100%
PS2 Dual Shock 2 (Original) with Super Dual Box Pro: 90% PS2 Dual Shock 2 (Original) with Super Dual Box Pro: 90%
XBox 360 Wireless: 85% XBox 360 Wireless: 85%
GameCube Controller (Third Party) with EMS Trio Linker Plus II: 60% GameCube Controller (Third Party) with EMS Trio Linker Plus II: 60%
*/ */
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/* Calculate the distance from the outer edges of the box to the outer edges of the circle inside the box /* Calculate the distance from the outer edges of the box to the outer edges of the circle inside the box
at any angle from 0<> to 360<36>. The returned value is 1 + Distance, for example at most sqrt(2) in the at any angle from 0<> to 360<36>. The returned value is 1 + Distance, for example at most sqrt(2) in the
corners and at least 1.0 at the horizontal and vertical angles. */ corners and at least 1.0 at the horizontal and vertical angles. */
float Square2CircleDistance(float deg) float Square2CircleDistance(float deg)
{ {
// See if we have to adjust the angle // See if we have to adjust the angle
deg = abs(deg); deg = abs(deg);
if( (deg > 45 && deg < 135) ) deg = deg - 90; if( (deg > 45 && deg < 135) ) deg = deg - 90;
// Calculate distance from center // Calculate distance from center
float val = abs(cos(Deg2Rad(deg))); float val = abs(cos(Deg2Rad(deg)));
float Distance = 1 / val; float Distance = 1 / val;
//m_frame->m_pStatusBar2->SetLabel(wxString::Format("Deg:%f Val:%f Dist:%f", deg, val, dist)); //m_frame->m_pStatusBar2->SetLabel(wxString::Format("Deg:%f Val:%f Dist:%f", deg, val, dist));
return Distance; return Distance;
} }
// Produce a perfect circle from an original square or rounded box // Produce a perfect circle from an original square or rounded box
std::vector<int> Square2Circle(int _x, int _y, int _pad, std::string SDiagonal, bool Circle2Square) std::vector<int> Square2Circle(int _x, int _y, int _pad, std::string SDiagonal, bool Circle2Square)
{ {
// Do we need this? // Do we need this?
if(_x > 32767) _x = 32767; if(_y > 32767) _y = 32767; // upper limit if(_x > 32767) _x = 32767; if(_y > 32767) _y = 32767; // upper limit
if(_x < -32768) _x = -32768; if(_y < -32768) _y = -32768; // lower limit if(_x < -32768) _x = -32768; if(_y < -32768) _y = -32768; // lower limit
// ==================================== // ====================================
// Convert to circle // Convert to circle
// ----------- // -----------
// Get the manually configured diagonal distance // Get the manually configured diagonal distance
int Tmp = atoi (SDiagonal.substr(0, SDiagonal.length() - 1).c_str()); int Tmp = atoi (SDiagonal.substr(0, SDiagonal.length() - 1).c_str());
float Diagonal = Tmp / 100.0f; float Diagonal = Tmp / 100.0f;
// First make a perfect square in case we don't have one already // First make a perfect square in case we don't have one already
float OrigDist = sqrt( pow((float)_y, 2) + pow((float)_x, 2) ); // Get current distance float OrigDist = sqrt( pow((float)_y, 2) + pow((float)_x, 2) ); // Get current distance
float deg = Rad2Deg(atan2((float)_y, (float)_x)); // Get current angle float deg = Rad2Deg(atan2((float)_y, (float)_x)); // Get current angle
/* Calculate the actual distance between the maxium diagonal values, and the outer edges of the /* Calculate the actual distance between the maxium diagonal values, and the outer edges of the
square. A diagonal of 85% means a maximum distance of 0.85 * sqrt(2) ~1.2 in the diagonals. */ square. A diagonal of 85% means a maximum distance of 0.85 * sqrt(2) ~1.2 in the diagonals. */
float corner_circle_dist = ( Diagonal / sin(Deg2Rad(45)) ); float corner_circle_dist = ( Diagonal / sin(Deg2Rad(45)) );
float SquareDist = Square2CircleDistance(deg); float SquareDist = Square2CircleDistance(deg);
// The original-to-square distance adjustment // The original-to-square distance adjustment
float adj_ratio1; float adj_ratio1;
// The circle-to-square distance adjustment // The circle-to-square distance adjustment
float adj_ratio2 = SquareDist; float adj_ratio2 = SquareDist;
// The resulting distance // The resulting distance
float result_dist; float result_dist;
// Calculate the corner-to-square adjustment ratio // Calculate the corner-to-square adjustment ratio
if(corner_circle_dist < SquareDist) adj_ratio1 = SquareDist / corner_circle_dist; if(corner_circle_dist < SquareDist) adj_ratio1 = SquareDist / corner_circle_dist;
else adj_ratio1 = 1; else adj_ratio1 = 1;
// Calculate the resulting distance // Calculate the resulting distance
if(Circle2Square) if(Circle2Square)
result_dist = OrigDist * adj_ratio1; result_dist = OrigDist * adj_ratio1;
else else
result_dist = OrigDist * adj_ratio1 / adj_ratio2; result_dist = OrigDist * adj_ratio1 / adj_ratio2;
// Calculate x and y and return it // Calculate x and y and return it
float x = result_dist * cos(Deg2Rad(deg)); float x = result_dist * cos(Deg2Rad(deg));
float y = result_dist * sin(Deg2Rad(deg)); float y = result_dist * sin(Deg2Rad(deg));
// Make integers // Make integers
int int_x = (int)floor(x); int int_x = (int)floor(x);
int int_y = (int)floor(y); int int_y = (int)floor(y);
// Boundaries // Boundaries
if (int_x < -32768) int_x = -32768; if (int_x > 32767) int_x = 32767; if (int_x < -32768) int_x = -32768; if (int_x > 32767) int_x = 32767;
if (int_y < -32768) int_y = -32768; if (int_y > 32767) int_y = 32767; if (int_y < -32768) int_y = -32768; if (int_y > 32767) int_y = 32767;
// Return it // Return it
std::vector<int> vec; std::vector<int> vec;
vec.push_back(int_x); vec.push_back(int_x);
vec.push_back(int_y); vec.push_back(int_y);
// Debugging // Debugging
//Console::Print("%f %f %i", corner_circle_dist, Diagonal, Tmp)); //Console::Print("%f %f %i", corner_circle_dist, Diagonal, Tmp));
return vec; return vec;
} }
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Windows Virtual Key Codes Names // Windows Virtual Key Codes Names
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#ifdef _WIN32 #ifdef _WIN32
std::string VKToString(int keycode) std::string VKToString(int keycode)
{ {
#ifdef _WIN32 #ifdef _WIN32
// Default value // Default value
char KeyStr[64] = {0}; char KeyStr[64] = {0};
GetKeyNameText(MapVirtualKey(keycode, MAPVK_VK_TO_VSC) << 16, KeyStr, 64); GetKeyNameText(MapVirtualKey(keycode, MAPVK_VK_TO_VSC) << 16, KeyStr, 64);
std::string KeyString = KeyStr; std::string KeyString = KeyStr;
switch(keycode) switch(keycode)
{ {
// Give it some help with a few keys // Give it some help with a few keys
case VK_END: return "END"; case VK_END: return "END";
case VK_INSERT: return "INS"; case VK_INSERT: return "INS";
case VK_DELETE: return "DEL"; case VK_DELETE: return "DEL";
case VK_PRIOR: return "PGUP"; case VK_PRIOR: return "PGUP";
case VK_NEXT: return "PGDN"; case VK_NEXT: return "PGDN";
case VK_UP: return "UP"; case VK_UP: return "UP";
case VK_DOWN: return "DOWN"; case VK_DOWN: return "DOWN";
case VK_LEFT: return "LEFT"; case VK_LEFT: return "LEFT";
case VK_RIGHT: return "RIGHT"; case VK_RIGHT: return "RIGHT";
case VK_LSHIFT: return "LEFT SHIFT"; case VK_LSHIFT: return "LEFT SHIFT";
case VK_LCONTROL: return "LEFT CTRL"; case VK_LCONTROL: return "LEFT CTRL";
case VK_RCONTROL: return "RIGHT CTRL"; case VK_RCONTROL: return "RIGHT CTRL";
case VK_LMENU: return "LEFT ALT"; case VK_LMENU: return "LEFT ALT";
default: return KeyString; default: return KeyString;
} }
#else #else
// An equivalent name translation can probably be used on other systems to? // An equivalent name translation can probably be used on other systems to?
return ""; return "";
#endif #endif
} }
#endif #endif
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
} }

View File

@ -1,366 +1,366 @@
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Project description // Project description
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// Name: SDL Input // Name: SDL Input
// Description: Common SDL Input Functions // Description: Common SDL Input Functions
// //
// Author: Falcon4ever (nJoy@falcon4ever.com, www.multigesture.net), JPeterson etc // Author: Falcon4ever (nJoy@falcon4ever.com, www.multigesture.net), JPeterson etc
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2008 Dolphin Project.
// //
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// //
// Licensetype: GNU General Public License (GPL) // Licensetype: GNU General Public License (GPL)
// //
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0. // the Free Software Foundation, version 2.0.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details. // GNU General Public License 2.0 for more details.
// //
// A copy of the GPL 2.0 should have been included with the program. // A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/ // If not, see http://www.gnu.org/licenses/
// //
// Official SVN repository and contact information can be found at // Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
// //
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Include // Include
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#define _SDL_MAIN_ // Avoid certain declarations in SDL.h #define _SDL_MAIN_ // Avoid certain declarations in SDL.h
#include "SDL.h" // Local #include "SDL.h" // Local
#include "XInput.h" #include "XInput.h"
//////////////////////////////////// ////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Definitions // Definitions
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
int g_LastPad = 0; int g_LastPad = 0;
//////////////////////////////////// ////////////////////////////////////
namespace InputCommon namespace InputCommon
{ {
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Definitions // Definitions
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//////////////////////////////////// ////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Search attached devices. Populate joyinfo for all attached physical devices. // Search attached devices. Populate joyinfo for all attached physical devices.
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
bool SearchDevices(std::vector<CONTROLLER_INFO> &_joyinfo, int &_NumPads, int &_NumGoodPads) bool SearchDevices(std::vector<CONTROLLER_INFO> &_joyinfo, int &_NumPads, int &_NumGoodPads)
{ {
/* SDL 1.3 use DirectInput instead of the old Microsoft Multimedia API, and with this we need /* SDL 1.3 use DirectInput instead of the old Microsoft Multimedia API, and with this we need
the SDL_INIT_VIDEO flag to */ the SDL_INIT_VIDEO flag to */
if (!SDL_WasInit(0)) if (!SDL_WasInit(0))
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) < 0) if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) < 0)
{ {
PanicAlert("Could not initialize SDL: %s", SDL_GetError()); PanicAlert("Could not initialize SDL: %s", SDL_GetError());
return false; return false;
} }
// Get device status // Get device status
int numjoy = SDL_NumJoysticks(); int numjoy = SDL_NumJoysticks();
for (int i = 0; i < numjoy; i++ ) for (int i = 0; i < numjoy; i++ )
{ {
CONTROLLER_INFO Tmp; CONTROLLER_INFO Tmp;
Tmp.joy = SDL_JoystickOpen(i); Tmp.joy = SDL_JoystickOpen(i);
Tmp.ID = i; Tmp.ID = i;
Tmp.NumAxes = SDL_JoystickNumAxes(Tmp.joy); Tmp.NumAxes = SDL_JoystickNumAxes(Tmp.joy);
Tmp.NumButtons = SDL_JoystickNumButtons(Tmp.joy); Tmp.NumButtons = SDL_JoystickNumButtons(Tmp.joy);
Tmp.NumBalls = SDL_JoystickNumBalls(Tmp.joy); Tmp.NumBalls = SDL_JoystickNumBalls(Tmp.joy);
Tmp.NumHats = SDL_JoystickNumHats(Tmp.joy); Tmp.NumHats = SDL_JoystickNumHats(Tmp.joy);
Tmp.Name = SDL_JoystickName(i); Tmp.Name = SDL_JoystickName(i);
// Check if the device is okay // Check if the device is okay
if ( Tmp.NumAxes == 0 if ( Tmp.NumAxes == 0
&& Tmp.NumBalls == 0 && Tmp.NumBalls == 0
&& Tmp.NumButtons == 0 && Tmp.NumButtons == 0
&& Tmp.NumHats == 0 && Tmp.NumHats == 0
) )
{ {
Tmp.Good = false; Tmp.Good = false;
} }
else else
{ {
_NumGoodPads++; _NumGoodPads++;
Tmp.Good = true; Tmp.Good = true;
} }
_joyinfo.push_back(Tmp); _joyinfo.push_back(Tmp);
// We have now read the values we need so we close the device // We have now read the values we need so we close the device
if (SDL_JoystickOpened(i)) SDL_JoystickClose(_joyinfo[i].joy); if (SDL_JoystickOpened(i)) SDL_JoystickClose(_joyinfo[i].joy);
} }
_NumPads = (int)_joyinfo.size(); _NumPads = (int)_joyinfo.size();
return true; return true;
} }
//////////////////////////////////// ////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Supporting functions // Supporting functions
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// Read current joystick status // Read current joystick status
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> /* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
The value PadMapping[].buttons[] is the number of the assigned joypad button, The value PadMapping[].buttons[] is the number of the assigned joypad button,
PadState[].buttons[] is the status of the button, it becomes 0 (no pressed) or 1 (pressed) */ PadState[].buttons[] is the status of the button, it becomes 0 (no pressed) or 1 (pressed) */
// Read buttons status. Called from GetJoyState(). // Read buttons status. Called from GetJoyState().
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void ReadButton(CONTROLLER_STATE &_PadState, CONTROLLER_MAPPING _PadMapping, int button, int NumButtons) void ReadButton(CONTROLLER_STATE &_PadState, CONTROLLER_MAPPING _PadMapping, int button, int NumButtons)
{ {
int ctl_button = _PadMapping.buttons[button]; int ctl_button = _PadMapping.buttons[button];
if (ctl_button < NumButtons) if (ctl_button < NumButtons)
{ {
_PadState.buttons[button] = SDL_JoystickGetButton(_PadState.joy, ctl_button); _PadState.buttons[button] = SDL_JoystickGetButton(_PadState.joy, ctl_button);
} }
} }
// Request joystick state. // Request joystick state.
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/* Called from: PAD_GetStatus() /* Called from: PAD_GetStatus()
Input: The virtual device 0, 1, 2 or 3 Input: The virtual device 0, 1, 2 or 3
Function: Updates the PadState struct with the current pad status. The input value "controller" is Function: Updates the PadState struct with the current pad status. The input value "controller" is
for a virtual controller 0 to 3. */ for a virtual controller 0 to 3. */
void GetJoyState(CONTROLLER_STATE &_PadState, CONTROLLER_MAPPING _PadMapping, int Controller, int NumButtons) void GetJoyState(CONTROLLER_STATE &_PadState, CONTROLLER_MAPPING _PadMapping, int Controller, int NumButtons)
{ {
// Update the gamepad status // Update the gamepad status
SDL_JoystickUpdate(); SDL_JoystickUpdate();
// Update axis states. It doesn't hurt much if we happen to ask for nonexisting axises here. // Update axis states. It doesn't hurt much if we happen to ask for nonexisting axises here.
_PadState.axis[CTL_MAIN_X] = SDL_JoystickGetAxis(_PadState.joy, _PadMapping.axis[CTL_MAIN_X]); _PadState.axis[CTL_MAIN_X] = SDL_JoystickGetAxis(_PadState.joy, _PadMapping.axis[CTL_MAIN_X]);
_PadState.axis[CTL_MAIN_Y] = SDL_JoystickGetAxis(_PadState.joy, _PadMapping.axis[CTL_MAIN_Y]); _PadState.axis[CTL_MAIN_Y] = SDL_JoystickGetAxis(_PadState.joy, _PadMapping.axis[CTL_MAIN_Y]);
_PadState.axis[CTL_SUB_X] = SDL_JoystickGetAxis(_PadState.joy, _PadMapping.axis[CTL_SUB_X]); _PadState.axis[CTL_SUB_X] = SDL_JoystickGetAxis(_PadState.joy, _PadMapping.axis[CTL_SUB_X]);
_PadState.axis[CTL_SUB_Y] = SDL_JoystickGetAxis(_PadState.joy, _PadMapping.axis[CTL_SUB_Y]); _PadState.axis[CTL_SUB_Y] = SDL_JoystickGetAxis(_PadState.joy, _PadMapping.axis[CTL_SUB_Y]);
// Update the analog trigger axis values // Update the analog trigger axis values
#ifdef _WIN32 #ifdef _WIN32
if (_PadMapping.triggertype == CTL_TRIGGER_SDL) if (_PadMapping.triggertype == CTL_TRIGGER_SDL)
{ {
#endif #endif
// If we are using SDL analog triggers the buttons have to be mapped as 1000 or up, otherwise they are not used // If we are using SDL analog triggers the buttons have to be mapped as 1000 or up, otherwise they are not used
if(_PadMapping.buttons[CTL_L_SHOULDER] >= 1000) _PadState.axis[CTL_L_SHOULDER] = SDL_JoystickGetAxis(_PadState.joy, _PadMapping.buttons[CTL_L_SHOULDER] - 1000); else _PadState.axis[CTL_L_SHOULDER] = 0; if(_PadMapping.buttons[CTL_L_SHOULDER] >= 1000) _PadState.axis[CTL_L_SHOULDER] = SDL_JoystickGetAxis(_PadState.joy, _PadMapping.buttons[CTL_L_SHOULDER] - 1000); else _PadState.axis[CTL_L_SHOULDER] = 0;
if(_PadMapping.buttons[CTL_R_SHOULDER] >= 1000) _PadState.axis[CTL_R_SHOULDER] = SDL_JoystickGetAxis(_PadState.joy, _PadMapping.buttons[CTL_R_SHOULDER] - 1000); else _PadState.axis[CTL_R_SHOULDER] = 0; if(_PadMapping.buttons[CTL_R_SHOULDER] >= 1000) _PadState.axis[CTL_R_SHOULDER] = SDL_JoystickGetAxis(_PadState.joy, _PadMapping.buttons[CTL_R_SHOULDER] - 1000); else _PadState.axis[CTL_R_SHOULDER] = 0;
#ifdef _WIN32 #ifdef _WIN32
} }
else else
{ {
_PadState.axis[CTL_L_SHOULDER] = XInput::GetXI(0, _PadMapping.buttons[CTL_L_SHOULDER] - 1000); _PadState.axis[CTL_L_SHOULDER] = XInput::GetXI(0, _PadMapping.buttons[CTL_L_SHOULDER] - 1000);
_PadState.axis[CTL_R_SHOULDER] = XInput::GetXI(0, _PadMapping.buttons[CTL_R_SHOULDER] - 1000); _PadState.axis[CTL_R_SHOULDER] = XInput::GetXI(0, _PadMapping.buttons[CTL_R_SHOULDER] - 1000);
} }
#endif #endif
// Update button states to on or off // Update button states to on or off
ReadButton(_PadState, _PadMapping, CTL_L_SHOULDER, NumButtons); ReadButton(_PadState, _PadMapping, CTL_L_SHOULDER, NumButtons);
ReadButton(_PadState, _PadMapping, CTL_R_SHOULDER, NumButtons); ReadButton(_PadState, _PadMapping, CTL_R_SHOULDER, NumButtons);
ReadButton(_PadState, _PadMapping, CTL_A_BUTTON, NumButtons); ReadButton(_PadState, _PadMapping, CTL_A_BUTTON, NumButtons);
ReadButton(_PadState, _PadMapping, CTL_B_BUTTON, NumButtons); ReadButton(_PadState, _PadMapping, CTL_B_BUTTON, NumButtons);
ReadButton(_PadState, _PadMapping, CTL_X_BUTTON, NumButtons); ReadButton(_PadState, _PadMapping, CTL_X_BUTTON, NumButtons);
ReadButton(_PadState, _PadMapping, CTL_Y_BUTTON, NumButtons); ReadButton(_PadState, _PadMapping, CTL_Y_BUTTON, NumButtons);
ReadButton(_PadState, _PadMapping, CTL_Z_TRIGGER, NumButtons); ReadButton(_PadState, _PadMapping, CTL_Z_TRIGGER, NumButtons);
ReadButton(_PadState, _PadMapping, CTL_START, NumButtons); ReadButton(_PadState, _PadMapping, CTL_START, NumButtons);
// //
if (_PadMapping.halfpress < NumButtons) if (_PadMapping.halfpress < NumButtons)
_PadState.halfpress = SDL_JoystickGetButton(_PadState.joy, _PadMapping.halfpress); _PadState.halfpress = SDL_JoystickGetButton(_PadState.joy, _PadMapping.halfpress);
// Check if we have an analog or digital joypad // Check if we have an analog or digital joypad
if (_PadMapping.controllertype == CTL_DPAD_HAT) if (_PadMapping.controllertype == CTL_DPAD_HAT)
{ {
_PadState.dpad = SDL_JoystickGetHat(_PadState.joy, _PadMapping.dpad); _PadState.dpad = SDL_JoystickGetHat(_PadState.joy, _PadMapping.dpad);
} }
else else
{ {
/* Only do this if the assigned button is in range (to allow for the current way of saving keyboard /* Only do this if the assigned button is in range (to allow for the current way of saving keyboard
keys in the same array) */ keys in the same array) */
if(_PadMapping.dpad2[CTL_D_PAD_UP] <= NumButtons) if(_PadMapping.dpad2[CTL_D_PAD_UP] <= NumButtons)
_PadState.dpad2[CTL_D_PAD_UP] = SDL_JoystickGetButton(_PadState.joy, _PadMapping.dpad2[CTL_D_PAD_UP]); _PadState.dpad2[CTL_D_PAD_UP] = SDL_JoystickGetButton(_PadState.joy, _PadMapping.dpad2[CTL_D_PAD_UP]);
if(_PadMapping.dpad2[CTL_D_PAD_DOWN] <= NumButtons) if(_PadMapping.dpad2[CTL_D_PAD_DOWN] <= NumButtons)
_PadState.dpad2[CTL_D_PAD_DOWN] = SDL_JoystickGetButton(_PadState.joy, _PadMapping.dpad2[CTL_D_PAD_DOWN]); _PadState.dpad2[CTL_D_PAD_DOWN] = SDL_JoystickGetButton(_PadState.joy, _PadMapping.dpad2[CTL_D_PAD_DOWN]);
if(_PadMapping.dpad2[CTL_D_PAD_LEFT] <= NumButtons) if(_PadMapping.dpad2[CTL_D_PAD_LEFT] <= NumButtons)
_PadState.dpad2[CTL_D_PAD_LEFT] = SDL_JoystickGetButton(_PadState.joy, _PadMapping.dpad2[CTL_D_PAD_LEFT]); _PadState.dpad2[CTL_D_PAD_LEFT] = SDL_JoystickGetButton(_PadState.joy, _PadMapping.dpad2[CTL_D_PAD_LEFT]);
if(_PadMapping.dpad2[CTL_D_PAD_RIGHT] <= NumButtons) if(_PadMapping.dpad2[CTL_D_PAD_RIGHT] <= NumButtons)
_PadState.dpad2[CTL_D_PAD_RIGHT] = SDL_JoystickGetButton(_PadState.joy, _PadMapping.dpad2[CTL_D_PAD_RIGHT]); _PadState.dpad2[CTL_D_PAD_RIGHT] = SDL_JoystickGetButton(_PadState.joy, _PadMapping.dpad2[CTL_D_PAD_RIGHT]);
} }
#ifdef SHOW_PAD_STATUS #ifdef SHOW_PAD_STATUS
// Show the status of all connected pads // Show the status of all connected pads
if ((g_LastPad == 0 && Controller == 0) || Controller < g_LastPad) Console::ClearScreen(); if ((g_LastPad == 0 && Controller == 0) || Controller < g_LastPad) Console::ClearScreen();
g_LastPad = Controller; g_LastPad = Controller;
Console::Print( Console::Print(
"Pad | Number:%i Enabled:%i Handle:%i\n" "Pad | Number:%i Enabled:%i Handle:%i\n"
"Main Stick | X:%03i Y:%03i\n" "Main Stick | X:%03i Y:%03i\n"
"C Stick | X:%03i Y:%03i\n" "C Stick | X:%03i Y:%03i\n"
"Trigger | Type:%s DigitalL:%i DigitalR:%i AnalogL:%03i AnalogR:%03i HalfPress:%i\n" "Trigger | Type:%s DigitalL:%i DigitalR:%i AnalogL:%03i AnalogR:%03i HalfPress:%i\n"
"Buttons | A:%i X:%i\n" "Buttons | A:%i X:%i\n"
"D-Pad | Type:%s Hat:%i U:%i D:%i\n" "D-Pad | Type:%s Hat:%i U:%i D:%i\n"
"======================================================\n", "======================================================\n",
Controller, _PadMapping.enabled, _PadState.joy, Controller, _PadMapping.enabled, _PadState.joy,
_PadState.axis[InputCommon::CTL_MAIN_X], _PadState.axis[InputCommon::CTL_MAIN_Y], _PadState.axis[InputCommon::CTL_MAIN_X], _PadState.axis[InputCommon::CTL_MAIN_Y],
_PadState.axis[InputCommon::CTL_SUB_X], _PadState.axis[InputCommon::CTL_SUB_Y], _PadState.axis[InputCommon::CTL_SUB_X], _PadState.axis[InputCommon::CTL_SUB_Y],
(_PadMapping.triggertype ? "CTL_TRIGGER_XINPUT" : "CTL_TRIGGER_SDL"), (_PadMapping.triggertype ? "CTL_TRIGGER_XINPUT" : "CTL_TRIGGER_SDL"),
_PadState.buttons[InputCommon::CTL_L_SHOULDER], _PadState.buttons[InputCommon::CTL_R_SHOULDER], _PadState.buttons[InputCommon::CTL_L_SHOULDER], _PadState.buttons[InputCommon::CTL_R_SHOULDER],
_PadState.axis[InputCommon::CTL_L_SHOULDER], _PadState.axis[InputCommon::CTL_R_SHOULDER], _PadState.axis[InputCommon::CTL_L_SHOULDER], _PadState.axis[InputCommon::CTL_R_SHOULDER],
_PadState.halfpress, _PadState.halfpress,
_PadState.buttons[InputCommon::CTL_A_BUTTON], _PadState.buttons[InputCommon::CTL_X_BUTTON], _PadState.buttons[InputCommon::CTL_A_BUTTON], _PadState.buttons[InputCommon::CTL_X_BUTTON],
(_PadMapping.controllertype ? "CTL_DPAD_CUSTOM" : "CTL_DPAD_HAT"), (_PadMapping.controllertype ? "CTL_DPAD_CUSTOM" : "CTL_DPAD_HAT"),
_PadState.dpad, _PadState.dpad,
_PadState.dpad2[InputCommon::CTL_D_PAD_UP], _PadState.dpad2[InputCommon::CTL_D_PAD_DOWN] _PadState.dpad2[InputCommon::CTL_D_PAD_UP], _PadState.dpad2[InputCommon::CTL_D_PAD_DOWN]
); );
#endif #endif
} }
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Configure button mapping // Configure button mapping
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// Avoid extreme axis values // Avoid extreme axis values
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/* Function: We have to avoid very big values to becuse some triggers are -0x8000 in the /* Function: We have to avoid very big values to becuse some triggers are -0x8000 in the
unpressed state (and then go from -0x8000 to 0x8000 as they are fully pressed) */ unpressed state (and then go from -0x8000 to 0x8000 as they are fully pressed) */
bool AvoidValues(int value, bool NoTriggerFilter) bool AvoidValues(int value, bool NoTriggerFilter)
{ {
// Avoid detecting very small or very big (for triggers) values // Avoid detecting very small or very big (for triggers) values
if( (value > -0x2000 && value < 0x2000) // Small values if( (value > -0x2000 && value < 0x2000) // Small values
|| ((value < -0x6000 || value > 0x6000) && !NoTriggerFilter)) // Big values || ((value < -0x6000 || value > 0x6000) && !NoTriggerFilter)) // Big values
return true; // Avoid return true; // Avoid
else else
return false; // Keep return false; // Keep
} }
// Detect a pressed button // Detect a pressed button
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void GetButton(SDL_Joystick *joy, int ControllerID, int buttons, int axes, int hats, void GetButton(SDL_Joystick *joy, int ControllerID, int buttons, int axes, int hats,
int &KeyboardKey, int &value, int &type, int &pressed, bool &Succeed, bool &Stop, int &KeyboardKey, int &value, int &type, int &pressed, bool &Succeed, bool &Stop,
bool LeftRight, bool Axis, bool XInput, bool Button, bool Hat, bool NoTriggerFilter) bool LeftRight, bool Axis, bool XInput, bool Button, bool Hat, bool NoTriggerFilter)
{ {
// It needs the wxWidgets excape keycode // It needs the wxWidgets excape keycode
static const int WXK_ESCAPE = 27; static const int WXK_ESCAPE = 27;
// Update the internal status // Update the internal status
SDL_JoystickUpdate(); SDL_JoystickUpdate();
// For the triggers we accept both a digital or an analog button // For the triggers we accept both a digital or an analog button
if(Axis) if(Axis)
{ {
for(int i = 0; i < axes; i++) for(int i = 0; i < axes; i++)
{ {
value = SDL_JoystickGetAxis(joy, i); value = SDL_JoystickGetAxis(joy, i);
if(AvoidValues(value, NoTriggerFilter)) continue; // Avoid values if(AvoidValues(value, NoTriggerFilter)) continue; // Avoid values
pressed = i + (LeftRight ? 1000 : 0); // Identify the analog triggers pressed = i + (LeftRight ? 1000 : 0); // Identify the analog triggers
type = InputCommon::CTL_AXIS; type = InputCommon::CTL_AXIS;
Succeed = true; Succeed = true;
} }
} }
// Check for a hat // Check for a hat
if(Hat) if(Hat)
{ {
for(int i = 0; i < hats; i++) for(int i = 0; i < hats; i++)
{ {
if(SDL_JoystickGetHat(joy, i)) if(SDL_JoystickGetHat(joy, i))
{ {
pressed = i; pressed = i;
type = InputCommon::CTL_HAT; type = InputCommon::CTL_HAT;
Succeed = true; Succeed = true;
} }
} }
} }
// Check for a button // Check for a button
if(Button) if(Button)
{ {
for(int i = 0; i < buttons; i++) for(int i = 0; i < buttons; i++)
{ {
// Some kind of bug in SDL 1.3 would give button 9 and 10 (nonexistent) the value 48 on the 360 pad // Some kind of bug in SDL 1.3 would give button 9 and 10 (nonexistent) the value 48 on the 360 pad
if (SDL_JoystickGetButton(joy, i) > 1) continue; if (SDL_JoystickGetButton(joy, i) > 1) continue;
if(SDL_JoystickGetButton(joy, i)) if(SDL_JoystickGetButton(joy, i))
{ {
pressed = i; pressed = i;
type = InputCommon::CTL_BUTTON; type = InputCommon::CTL_BUTTON;
Succeed = true; Succeed = true;
} }
} }
} }
// Check for a XInput trigger // Check for a XInput trigger
#ifdef _WIN32 #ifdef _WIN32
if(XInput) if(XInput)
{ {
for(int i = 0; i <= InputCommon::XI_TRIGGER_R; i++) for(int i = 0; i <= InputCommon::XI_TRIGGER_R; i++)
{ {
if(XInput::GetXI(0, i)) if(XInput::GetXI(0, i))
{ {
pressed = i + 1000; pressed = i + 1000;
type = InputCommon::CTL_AXIS; type = InputCommon::CTL_AXIS;
Succeed = true; Succeed = true;
} }
} }
} }
#endif #endif
// Check for keyboard action // Check for keyboard action
if (KeyboardKey) if (KeyboardKey)
{ {
if(Button) if(Button)
{ {
// Todo: Add a separate keyboard vector to remove this restriction // Todo: Add a separate keyboard vector to remove this restriction
if(KeyboardKey >= buttons) if(KeyboardKey >= buttons)
{ {
pressed = KeyboardKey; pressed = KeyboardKey;
type = InputCommon::CTL_BUTTON; type = InputCommon::CTL_BUTTON;
Succeed = true; Succeed = true;
KeyboardKey = 0; KeyboardKey = 0;
if(pressed == WXK_ESCAPE) pressed = -1; // Check for the escape key if(pressed == WXK_ESCAPE) pressed = -1; // Check for the escape key
} }
// Else show the error message // Else show the error message
else else
{ {
pressed = KeyboardKey; pressed = KeyboardKey;
KeyboardKey = -1; KeyboardKey = -1;
Stop = true; Stop = true;
} }
} }
// Only accept the escape key // Only accept the escape key
else if (KeyboardKey == WXK_ESCAPE) else if (KeyboardKey == WXK_ESCAPE)
{ {
Succeed = true; Succeed = true;
KeyboardKey = 0; KeyboardKey = 0;
pressed = -1; pressed = -1;
} }
} }
} }
/////////////////////////////////////////////////////////// Configure button mapping /////////////////////////////////////////////////////////// Configure button mapping
} // InputCommon } // InputCommon

View File

@ -1,136 +1,136 @@
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// //
// Licensetype: GNU General Public License (GPL) // Licensetype: GNU General Public License (GPL)
// //
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0. // the Free Software Foundation, version 2.0.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details. // GNU General Public License 2.0 for more details.
// //
// A copy of the GPL 2.0 should have been included with the program. // A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/ // If not, see http://www.gnu.org/licenses/
// //
// Official SVN repository and contact information can be found at // Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
// //
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// File description // File description
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> /* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
Function: This file will get the status of the analog triggers of any connected XInput device. Function: This file will get the status of the analog triggers of any connected XInput device.
This code was made with the help of SimpleController.cpp in the June 2008 Microsoft DirectX SDK This code was made with the help of SimpleController.cpp in the June 2008 Microsoft DirectX SDK
Samples. Samples.
///////////////////////////////////////////////////// */ ///////////////////////////////////////////////////// */
#ifdef _WIN32 #ifdef _WIN32
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Includes // Includes
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#include <windows.h> #include <windows.h>
#include <XInput.h> // XInput API #include <XInput.h> // XInput API
#include "SDL.h" // Local #include "SDL.h" // Local
/////////////////////////////////////////////// ///////////////////////////////////////////////
namespace XInput namespace XInput
{ {
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Declarations // Declarations
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#define MAX_CONTROLLERS 4 // XInput handles up to 4 controllers #define MAX_CONTROLLERS 4 // XInput handles up to 4 controllers
struct CONTROLER_STATE struct CONTROLER_STATE
{ {
XINPUT_STATE state; XINPUT_STATE state;
bool bConnected; bool bConnected;
}; };
CONTROLER_STATE g_Controllers[MAX_CONTROLLERS]; CONTROLER_STATE g_Controllers[MAX_CONTROLLERS];
/////////////////////////////////////////////// ///////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Init // Init
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/* Function: Calculate the number of connected XInput devices /* Function: Calculate the number of connected XInput devices
Todo: Implement this to figure out if there are multiple XInput controllers connected, Todo: Implement this to figure out if there are multiple XInput controllers connected,
we currently only try to connect to XInput device 0 */ we currently only try to connect to XInput device 0 */
void Init() void Init()
{ {
// Init state // Init state
//ZeroMemory( g_Controllers, sizeof( CONTROLER_STATE ) * MAX_CONTROLLERS ); //ZeroMemory( g_Controllers, sizeof( CONTROLER_STATE ) * MAX_CONTROLLERS );
// Declaration // Declaration
DWORD dwResult; DWORD dwResult;
// Calculate the number of connected XInput devices // Calculate the number of connected XInput devices
for( DWORD i = 0; i < MAX_CONTROLLERS; i++ ) for( DWORD i = 0; i < MAX_CONTROLLERS; i++ )
{ {
// Simply get the state of the controller from XInput. // Simply get the state of the controller from XInput.
dwResult = XInputGetState( i, &g_Controllers[i].state ); dwResult = XInputGetState( i, &g_Controllers[i].state );
if( dwResult == ERROR_SUCCESS ) if( dwResult == ERROR_SUCCESS )
g_Controllers[i].bConnected = true; g_Controllers[i].bConnected = true;
else else
g_Controllers[i].bConnected = false; g_Controllers[i].bConnected = false;
} }
} }
/////////////////////////////////////////// ///////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Get the trigger status // Get the trigger status
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
int GetXI(int Controller, int Button) int GetXI(int Controller, int Button)
{ {
// Update the internal status // Update the internal status
DWORD dwResult; DWORD dwResult;
dwResult = XInputGetState( Controller, &g_Controllers[Controller].state ); dwResult = XInputGetState( Controller, &g_Controllers[Controller].state );
if( dwResult != ERROR_SUCCESS ) return -1; if( dwResult != ERROR_SUCCESS ) return -1;
switch(Button) switch(Button)
{ {
case InputCommon::XI_TRIGGER_L: case InputCommon::XI_TRIGGER_L:
return g_Controllers[0].state.Gamepad.bLeftTrigger; return g_Controllers[0].state.Gamepad.bLeftTrigger;
case InputCommon::XI_TRIGGER_R: case InputCommon::XI_TRIGGER_R:
return g_Controllers[0].state.Gamepad.bRightTrigger; return g_Controllers[0].state.Gamepad.bRightTrigger;
default: default:
return 0; return 0;
} }
} }
/////////////////////////////////////////// ///////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Check if a certain controller is connected // Check if a certain controller is connected
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
bool IsConnected(int Controller) bool IsConnected(int Controller)
{ {
DWORD dwResult = XInputGetState( Controller, &g_Controllers[Controller].state ); DWORD dwResult = XInputGetState( Controller, &g_Controllers[Controller].state );
// Update the connected status // Update the connected status
if( dwResult == ERROR_SUCCESS ) if( dwResult == ERROR_SUCCESS )
return true; return true;
else else
return false; return false;
} }
/////////////////////////////////////////// ///////////////////////////////////////////
} // XInput } // XInput
#endif #endif

View File

@ -1,26 +1,26 @@
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2008 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0. // the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details. // GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program. // A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/ // If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at // Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
#include "Common.h" #include "Common.h"
#include "NativeVertexWriter.h" #include "NativeVertexWriter.h"
namespace VertexManager namespace VertexManager
{ {
u8* s_pCurBufferPointer = NULL; u8* s_pCurBufferPointer = NULL;
} }

View File

@ -1,117 +1,117 @@
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2008 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0. // the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details. // GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program. // A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/ // If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at // Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
// -------------------- // --------------------
// Includes // Includes
#include <string> #include <string>
#include <stdio.h> #include <stdio.h>
#include "Common.h" #include "Common.h"
#ifdef _WIN32 #ifdef _WIN32
#include <windows.h> #include <windows.h>
#endif #endif
#if defined(HAVE_WX) && HAVE_WX #if defined(HAVE_WX) && HAVE_WX
#include "../Debugger/Debugger.h" #include "../Debugger/Debugger.h"
extern CDebugger* m_frame; extern CDebugger* m_frame;
#endif #endif
#include "../Debugger/File.h" #include "../Debugger/File.h"
// -------------------- // --------------------
// On and off // On and off
bool g_consoleEnable = true; bool g_consoleEnable = true;
//int gSaveFile = 0; //int gSaveFile = 0;
#define DEBUG_HLE #define DEBUG_HLE
// -------------------- // --------------------
// Create file handles // Create file handles
#ifdef DEBUG_HLE #ifdef DEBUG_HLE
FILE* __fStdOut[nFiles]; FILE* __fStdOut[nFiles];
#endif #endif
// ======================================================================================= // =======================================================================================
/* Open file handles */ /* Open file handles */
// ------------- // -------------
void StartFile(int width, int height, char* fname) void StartFile(int width, int height, char* fname)
{ {
#if defined(DEBUG_HLE) && defined(_WIN32) #if defined(DEBUG_HLE) && defined(_WIN32)
if(fname) if(fname)
{ {
for(int i = 0; i < nFiles; i++) for(int i = 0; i < nFiles; i++)
{ {
// Edit the log file name // Edit the log file name
std::string FileEnding = ".log"; std::string FileEnding = ".log";
std::string FileName = fname; std::string FileName = fname;
char buffer[33]; _itoa(i, buffer, 10); // convert number to string char buffer[33]; _itoa(i, buffer, 10); // convert number to string
std::string FullFilename = (FileName + buffer + FileEnding); std::string FullFilename = (FileName + buffer + FileEnding);
__fStdOut[i] = fopen(FullFilename.c_str(), "w"); __fStdOut[i] = fopen(FullFilename.c_str(), "w");
} }
} }
#endif #endif
} }
// ====================== // ======================
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
/* Close the file handles */ /* Close the file handles */
// ------------- // -------------
void CloseFile() void CloseFile()
{ {
// Close the file handles // Close the file handles
for(int i = 0; i < nFiles; i++) for(int i = 0; i < nFiles; i++)
{ {
if(__fStdOut[i]) fclose(__fStdOut[i]); if(__fStdOut[i]) fclose(__fStdOut[i]);
} }
} }
////////////////////////////// //////////////////////////////
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
// File printf function // File printf function
// ------------- // -------------
int PrintFile(int a, char *fmt, ...) int PrintFile(int a, char *fmt, ...)
{ {
#if defined(DEBUG_HLE) && defined(_WIN32) #if defined(DEBUG_HLE) && defined(_WIN32)
if(m_frame->gSaveFile) if(m_frame->gSaveFile)
{ {
char s[StringSize]; char s[StringSize];
va_list argptr; va_list argptr;
int cnt; int cnt;
va_start(argptr, fmt); va_start(argptr, fmt);
cnt = vsnprintf(s, StringSize, fmt, argptr); cnt = vsnprintf(s, StringSize, fmt, argptr);
va_end(argptr); va_end(argptr);
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
if(__fStdOut[a]) // TODO: make this work, we have to set all default values to NULL if(__fStdOut[a]) // TODO: make this work, we have to set all default values to NULL
// to make it work // to make it work
fprintf(__fStdOut[a], s); fprintf(__fStdOut[a], s);
// ------------- // -------------
return(cnt); return(cnt);
} }
else else
{ {
return 0; return 0;
} }
#else #else
return 0; return 0;
#endif #endif
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,145 +1,145 @@
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2008 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0. // the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details. // GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program. // A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/ // If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at // Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
#include "D3DBase.h" #include "D3DBase.h"
#include "Profiler.h" #include "Profiler.h"
#include "x64Emitter.h" #include "x64Emitter.h"
#include "ABI.h" #include "ABI.h"
#include "MemoryUtil.h" #include "MemoryUtil.h"
#include "VertexShader.h" #include "VertexShader.h"
#include "CPMemory.h" #include "CPMemory.h"
#include "NativeVertexFormat.h" #include "NativeVertexFormat.h"
class D3DVertexFormat : public NativeVertexFormat class D3DVertexFormat : public NativeVertexFormat
{ {
PortableVertexDeclaration vtx_decl; PortableVertexDeclaration vtx_decl;
LPDIRECT3DVERTEXDECLARATION9 d3d_decl; LPDIRECT3DVERTEXDECLARATION9 d3d_decl;
public: public:
D3DVertexFormat(); D3DVertexFormat();
~D3DVertexFormat(); ~D3DVertexFormat();
virtual void Initialize(const PortableVertexDeclaration &_vtx_decl); virtual void Initialize(const PortableVertexDeclaration &_vtx_decl);
virtual void SetupVertexPointers() const; virtual void SetupVertexPointers() const;
}; };
NativeVertexFormat *NativeVertexFormat::Create() NativeVertexFormat *NativeVertexFormat::Create()
{ {
return new D3DVertexFormat(); return new D3DVertexFormat();
} }
D3DVertexFormat::D3DVertexFormat() : d3d_decl(NULL) D3DVertexFormat::D3DVertexFormat() : d3d_decl(NULL)
{ {
} }
D3DVertexFormat::~D3DVertexFormat() D3DVertexFormat::~D3DVertexFormat()
{ {
if (d3d_decl) if (d3d_decl)
{ {
d3d_decl->Release(); d3d_decl->Release();
d3d_decl = NULL; d3d_decl = NULL;
} }
} }
D3DDECLTYPE VarToD3D(VarType t) D3DDECLTYPE VarToD3D(VarType t)
{ {
static const D3DDECLTYPE lookup[5] = static const D3DDECLTYPE lookup[5] =
{ {
D3DDECLTYPE_UBYTE4, D3DDECLTYPE_UBYTE4, D3DDECLTYPE_SHORT4N, D3DDECLTYPE_USHORT4N, D3DDECLTYPE_FLOAT3, D3DDECLTYPE_UBYTE4, D3DDECLTYPE_UBYTE4, D3DDECLTYPE_SHORT4N, D3DDECLTYPE_USHORT4N, D3DDECLTYPE_FLOAT3,
}; };
return lookup[t]; return lookup[t];
} }
// TODO: Ban signed bytes as normals - not likely that ATI supports them natively. // TODO: Ban signed bytes as normals - not likely that ATI supports them natively.
// We probably won't see much of a speed loss, and any speed loss will be regained anyway // We probably won't see much of a speed loss, and any speed loss will be regained anyway
// when we finally compile display lists. // when we finally compile display lists.
void D3DVertexFormat::Initialize(const PortableVertexDeclaration &_vtx_decl) void D3DVertexFormat::Initialize(const PortableVertexDeclaration &_vtx_decl)
{ {
D3DVERTEXELEMENT9 *elems = new D3DVERTEXELEMENT9[32]; D3DVERTEXELEMENT9 *elems = new D3DVERTEXELEMENT9[32];
memset(elems, 0, sizeof(D3DVERTEXELEMENT9) * 32); memset(elems, 0, sizeof(D3DVERTEXELEMENT9) * 32);
// There's only one stream and it's 0, so the above memset takes care of that - no need to set Stream. // There's only one stream and it's 0, so the above memset takes care of that - no need to set Stream.
// Same for method. // Same for method.
// So, here we go. First position: // So, here we go. First position:
int elem_idx = 0; int elem_idx = 0;
elems[elem_idx].Offset = 0; // Positions are always first, at position 0. elems[elem_idx].Offset = 0; // Positions are always first, at position 0.
elems[elem_idx].Type = D3DDECLTYPE_FLOAT3; elems[elem_idx].Type = D3DDECLTYPE_FLOAT3;
elems[elem_idx].Usage = D3DDECLUSAGE_POSITION; elems[elem_idx].Usage = D3DDECLUSAGE_POSITION;
++elem_idx; ++elem_idx;
for (int i = 0; i < 3; i++) for (int i = 0; i < 3; i++)
{ {
if (_vtx_decl.normal_offset[i] >= 0) if (_vtx_decl.normal_offset[i] >= 0)
{ {
elems[elem_idx].Offset = _vtx_decl.normal_offset[i]; elems[elem_idx].Offset = _vtx_decl.normal_offset[i];
elems[elem_idx].Type = VarToD3D(_vtx_decl.normal_gl_type); elems[elem_idx].Type = VarToD3D(_vtx_decl.normal_gl_type);
elems[elem_idx].Usage = D3DDECLUSAGE_NORMAL; elems[elem_idx].Usage = D3DDECLUSAGE_NORMAL;
elems[elem_idx].UsageIndex = i; elems[elem_idx].UsageIndex = i;
++elem_idx; ++elem_idx;
} }
} }
for (int i = 0; i < 2; i++) for (int i = 0; i < 2; i++)
{ {
if (_vtx_decl.color_offset[i] >= 0) if (_vtx_decl.color_offset[i] >= 0)
{ {
elems[elem_idx].Offset = _vtx_decl.color_offset[i]; elems[elem_idx].Offset = _vtx_decl.color_offset[i];
elems[elem_idx].Type = VarToD3D(_vtx_decl.color_gl_type); elems[elem_idx].Type = VarToD3D(_vtx_decl.color_gl_type);
elems[elem_idx].Usage = D3DDECLUSAGE_COLOR; elems[elem_idx].Usage = D3DDECLUSAGE_COLOR;
elems[elem_idx].UsageIndex = i; elems[elem_idx].UsageIndex = i;
++elem_idx; ++elem_idx;
} }
} }
for (int i = 0; i < 8; i++) for (int i = 0; i < 8; i++)
{ {
if (_vtx_decl.texcoord_offset[i] >= 0) if (_vtx_decl.texcoord_offset[i] >= 0)
{ {
elems[elem_idx].Offset = _vtx_decl.texcoord_offset[i]; elems[elem_idx].Offset = _vtx_decl.texcoord_offset[i];
elems[elem_idx].Type = VarToD3D(_vtx_decl.texcoord_gl_type[i]); elems[elem_idx].Type = VarToD3D(_vtx_decl.texcoord_gl_type[i]);
elems[elem_idx].Usage = D3DDECLUSAGE_TEXCOORD; elems[elem_idx].Usage = D3DDECLUSAGE_TEXCOORD;
elems[elem_idx].UsageIndex = i; elems[elem_idx].UsageIndex = i;
++elem_idx; ++elem_idx;
} }
} }
if (vtx_decl.posmtx_offset != -1) if (vtx_decl.posmtx_offset != -1)
{ {
// glVertexAttribPointer(SHADER_POSMTX_ATTRIB, 4, GL_UNSIGNED_BYTE, GL_FALSE, vtx_decl.stride, (void *)vtx_decl.posmtx_offset); // glVertexAttribPointer(SHADER_POSMTX_ATTRIB, 4, GL_UNSIGNED_BYTE, GL_FALSE, vtx_decl.stride, (void *)vtx_decl.posmtx_offset);
elems[elem_idx].Offset = _vtx_decl.posmtx_offset; elems[elem_idx].Offset = _vtx_decl.posmtx_offset;
elems[elem_idx].Usage = D3DDECLUSAGE_BLENDINDICES; elems[elem_idx].Usage = D3DDECLUSAGE_BLENDINDICES;
elems[elem_idx].UsageIndex = 0; elems[elem_idx].UsageIndex = 0;
++elem_idx; ++elem_idx;
} }
if (FAILED(D3D::dev->CreateVertexDeclaration(elems, &d3d_decl))) if (FAILED(D3D::dev->CreateVertexDeclaration(elems, &d3d_decl)))
{ {
PanicAlert("Failed to create D3D vertex declaration!"); PanicAlert("Failed to create D3D vertex declaration!");
return; return;
} }
} }
void D3DVertexFormat::SetupVertexPointers() const void D3DVertexFormat::SetupVertexPointers() const
{ {
D3D::dev->SetVertexDeclaration(d3d_decl); D3D::dev->SetVertexDeclaration(d3d_decl);
} }

View File

@ -1,133 +1,133 @@
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2008 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0. // the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details. // GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program. // A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/ // If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at // Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
#include "D3DBase.h" #include "D3DBase.h"
#include "Statistics.h" #include "Statistics.h"
#include "Utils.h" #include "Utils.h"
#include "Profiler.h" #include "Profiler.h"
#include "PixelShaderCache.h" #include "PixelShaderCache.h"
#include "VertexLoader.h" #include "VertexLoader.h"
#include "BPMemory.h" #include "BPMemory.h"
#include "XFMemory.h" #include "XFMemory.h"
PShaderCache::PSCache PShaderCache::pshaders; PShaderCache::PSCache PShaderCache::pshaders;
//I hope we don't get too many hash collisions :p //I hope we don't get too many hash collisions :p
//all these magic numbers are primes, it should help a bit //all these magic numbers are primes, it should help a bit
tevhash GetCurrentTEV() tevhash GetCurrentTEV()
{ {
u32 hash = bpmem.genMode.numindstages + bpmem.genMode.numtevstages*11 + bpmem.genMode.numtexgens*8*17; u32 hash = bpmem.genMode.numindstages + bpmem.genMode.numtevstages*11 + bpmem.genMode.numtexgens*8*17;
for (int i = 0; i < (int)bpmem.genMode.numtevstages+1; i++) for (int i = 0; i < (int)bpmem.genMode.numtevstages+1; i++)
{ {
hash = _rotl(hash,3) ^ (bpmem.combiners[i].colorC.hex*13); hash = _rotl(hash,3) ^ (bpmem.combiners[i].colorC.hex*13);
hash = _rotl(hash,7) ^ ((bpmem.combiners[i].alphaC.hex&0xFFFFFFFC)*3); hash = _rotl(hash,7) ^ ((bpmem.combiners[i].alphaC.hex&0xFFFFFFFC)*3);
hash = _rotl(hash,9) ^ xfregs.texcoords[i].texmtxinfo.projection*451; hash = _rotl(hash,9) ^ xfregs.texcoords[i].texmtxinfo.projection*451;
} }
for (int i = 0; i < (int)bpmem.genMode.numtevstages/2+1; i++) for (int i = 0; i < (int)bpmem.genMode.numtevstages/2+1; i++)
{ {
hash = _rotl(hash,13) ^ (bpmem.tevorders[i].hex*7); hash = _rotl(hash,13) ^ (bpmem.tevorders[i].hex*7);
} }
for (int i = 0; i < 8; i++) for (int i = 0; i < 8; i++)
{ {
hash = _rotl(hash,3) ^ bpmem.tevksel[i].swap1; hash = _rotl(hash,3) ^ bpmem.tevksel[i].swap1;
hash = _rotl(hash,3) ^ bpmem.tevksel[i].swap2; hash = _rotl(hash,3) ^ bpmem.tevksel[i].swap2;
} }
hash ^= bpmem.dstalpha.enable ^ 0xc0debabe; hash ^= bpmem.dstalpha.enable ^ 0xc0debabe;
hash = _rotl(hash,4) ^ bpmem.alphaFunc.comp0*7; hash = _rotl(hash,4) ^ bpmem.alphaFunc.comp0*7;
hash = _rotl(hash,4) ^ bpmem.alphaFunc.comp1*13; hash = _rotl(hash,4) ^ bpmem.alphaFunc.comp1*13;
hash = _rotl(hash,4) ^ bpmem.alphaFunc.logic*11; hash = _rotl(hash,4) ^ bpmem.alphaFunc.logic*11;
return hash; return hash;
} }
void PShaderCache::Init() void PShaderCache::Init()
{ {
} }
void PShaderCache::Shutdown() void PShaderCache::Shutdown()
{ {
PSCache::iterator iter = pshaders.begin(); PSCache::iterator iter = pshaders.begin();
for (;iter!=pshaders.end();iter++) for (;iter!=pshaders.end();iter++)
iter->second.Destroy(); iter->second.Destroy();
pshaders.clear(); pshaders.clear();
} }
void PShaderCache::SetShader() void PShaderCache::SetShader()
{ {
if (D3D::GetShaderVersion() < 2) if (D3D::GetShaderVersion() < 2)
return; // we are screwed return; // we are screwed
static LPDIRECT3DPIXELSHADER9 lastShader = 0; static LPDIRECT3DPIXELSHADER9 lastShader = 0;
DVSTARTPROFILE(); DVSTARTPROFILE();
tevhash currentHash = GetCurrentTEV(); tevhash currentHash = GetCurrentTEV();
PSCache::iterator iter; PSCache::iterator iter;
iter = pshaders.find(currentHash); iter = pshaders.find(currentHash);
if (iter != pshaders.end()) if (iter != pshaders.end())
{ {
iter->second.frameCount = frameCount; iter->second.frameCount = frameCount;
PSCacheEntry &entry = iter->second; PSCacheEntry &entry = iter->second;
if (!lastShader || entry.shader != lastShader) if (!lastShader || entry.shader != lastShader)
{ {
D3D::dev->SetPixelShader(entry.shader); D3D::dev->SetPixelShader(entry.shader);
lastShader = entry.shader; lastShader = entry.shader;
} }
return; return;
} }
const char *code = GeneratePixelShader(); const char *code = GeneratePixelShader();
LPDIRECT3DPIXELSHADER9 shader = D3D::CompilePShader(code, int(strlen(code))); LPDIRECT3DPIXELSHADER9 shader = D3D::CompilePShader(code, int(strlen(code)));
if (shader) if (shader)
{ {
//Make an entry in the table //Make an entry in the table
PSCacheEntry newentry; PSCacheEntry newentry;
newentry.shader = shader; newentry.shader = shader;
newentry.frameCount = frameCount; newentry.frameCount = frameCount;
pshaders[currentHash] = newentry; pshaders[currentHash] = newentry;
} }
D3D::dev->SetPixelShader(shader); D3D::dev->SetPixelShader(shader);
INCSTAT(stats.numPixelShadersCreated); INCSTAT(stats.numPixelShadersCreated);
SETSTAT(stats.numPixelShadersAlive, (int)pshaders.size()); SETSTAT(stats.numPixelShadersAlive, (int)pshaders.size());
} }
void PShaderCache::Cleanup() void PShaderCache::Cleanup()
{ {
PSCache::iterator iter; PSCache::iterator iter;
iter = pshaders.begin(); iter = pshaders.begin();
while (iter != pshaders.end()) while (iter != pshaders.end())
{ {
PSCacheEntry &entry = iter->second; PSCacheEntry &entry = iter->second;
if (entry.frameCount < frameCount-30) if (entry.frameCount < frameCount-30)
{ {
entry.Destroy(); entry.Destroy();
iter = pshaders.erase(iter); iter = pshaders.erase(iter);
} }
else else
{ {
iter++; iter++;
} }
} }
SETSTAT(stats.numPixelShadersAlive, (int)pshaders.size()); SETSTAT(stats.numPixelShadersAlive, (int)pshaders.size());
} }

View File

@ -1,56 +1,56 @@
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2008 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0. // the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details. // GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program. // A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/ // If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at // Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
#include "VideoCommon.h" #include "VideoCommon.h"
#include "VertexLoader.h" #include "VertexLoader.h"
#include "VertexManager.h" #include "VertexManager.h"
DecodedVArray tempvarray; DecodedVArray tempvarray;
namespace VertexLoaderManager namespace VertexLoaderManager
{ {
void Init() void Init()
{ {
tempvarray.Create(65536*3, 1, 8, 3, 2, 8); tempvarray.Create(65536*3, 1, 8, 3, 2, 8);
} }
void Shutdown() void Shutdown()
{ {
tempvarray.Destroy(); tempvarray.Destroy();
} }
int GetVertexSize(int vat) int GetVertexSize(int vat)
{ {
VertexLoader& vtxLoader = g_VertexLoaders[vat]; VertexLoader& vtxLoader = g_VertexLoaders[vat];
vtxLoader.Setup(); vtxLoader.Setup();
return vtxLoader.GetVertexSize(); return vtxLoader.GetVertexSize();
} }
void RunVertices(int vat, int primitive, int num_vertices) void RunVertices(int vat, int primitive, int num_vertices)
{ {
tempvarray.Reset(); tempvarray.Reset();
VertexLoader::SetVArray(&tempvarray); VertexLoader::SetVArray(&tempvarray);
VertexLoader& vtxLoader = g_VertexLoaders[vat]; VertexLoader& vtxLoader = g_VertexLoaders[vat];
vtxLoader.Setup(); vtxLoader.Setup();
vtxLoader.PrepareRun(); vtxLoader.PrepareRun();
int vsize = vtxLoader.GetVertexSize(); int vsize = vtxLoader.GetVertexSize();
vtxLoader.RunVertices(num_vertices); vtxLoader.RunVertices(num_vertices);
VertexManager::AddVertices(primitive, num_vertices, &tempvarray); VertexManager::AddVertices(primitive, num_vertices, &tempvarray);
} }
} }

View File

@ -1,110 +1,110 @@
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2008 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0. // the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details. // GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program. // A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/ // If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at // Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
#include <map> #include <map>
#include "D3DBase.h" #include "D3DBase.h"
#include "Statistics.h" #include "Statistics.h"
#include "Utils.h" #include "Utils.h"
#include "Profiler.h" #include "Profiler.h"
#include "VertexShaderCache.h" #include "VertexShaderCache.h"
#include "VertexLoader.h" #include "VertexLoader.h"
#include "BPMemory.h" #include "BPMemory.h"
#include "XFMemory.h" #include "XFMemory.h"
VShaderCache::VSCache VShaderCache::vshaders; VShaderCache::VSCache VShaderCache::vshaders;
void VShaderCache::Init() void VShaderCache::Init()
{ {
} }
void VShaderCache::Shutdown() void VShaderCache::Shutdown()
{ {
VSCache::iterator iter = vshaders.begin(); VSCache::iterator iter = vshaders.begin();
for (; iter != vshaders.end(); iter++) for (; iter != vshaders.end(); iter++)
iter->second.Destroy(); iter->second.Destroy();
vshaders.clear(); vshaders.clear();
} }
void VShaderCache::SetShader() void VShaderCache::SetShader()
{ {
static LPDIRECT3DVERTEXSHADER9 shader = NULL; static LPDIRECT3DVERTEXSHADER9 shader = NULL;
if (D3D::GetShaderVersion() < 2) if (D3D::GetShaderVersion() < 2)
return; // we are screwed return; // we are screwed
if (shader) { if (shader) {
//D3D::dev->SetVertexShader(shader); //D3D::dev->SetVertexShader(shader);
return; return;
} }
static LPDIRECT3DVERTEXSHADER9 lastShader = 0; static LPDIRECT3DVERTEXSHADER9 lastShader = 0;
DVSTARTPROFILE(); DVSTARTPROFILE();
u32 currentHash = 0x1337; // GetCurrentTEV(); u32 currentHash = 0x1337; // GetCurrentTEV();
VSCache::iterator iter; VSCache::iterator iter;
iter = vshaders.find(currentHash); iter = vshaders.find(currentHash);
if (iter != vshaders.end()) if (iter != vshaders.end())
{ {
iter->second.frameCount=frameCount; iter->second.frameCount=frameCount;
VSCacheEntry &entry = iter->second; VSCacheEntry &entry = iter->second;
if (!lastShader || entry.shader != lastShader) if (!lastShader || entry.shader != lastShader)
{ {
D3D::dev->SetVertexShader(entry.shader); D3D::dev->SetVertexShader(entry.shader);
lastShader = entry.shader; lastShader = entry.shader;
} }
return; return;
} }
const char *code = GenerateVertexShader(); const char *code = GenerateVertexShader();
shader = D3D::CompileVShader(code, int(strlen(code))); shader = D3D::CompileVShader(code, int(strlen(code)));
if (shader) if (shader)
{ {
//Make an entry in the table //Make an entry in the table
VSCacheEntry entry; VSCacheEntry entry;
entry.shader = shader; entry.shader = shader;
entry.frameCount=frameCount; entry.frameCount=frameCount;
vshaders[currentHash] = entry; vshaders[currentHash] = entry;
} }
D3D::dev->SetVertexShader(shader); D3D::dev->SetVertexShader(shader);
INCSTAT(stats.numVertexShadersCreated); INCSTAT(stats.numVertexShadersCreated);
SETSTAT(stats.numVertexShadersAlive, (int)vshaders.size()); SETSTAT(stats.numVertexShadersAlive, (int)vshaders.size());
} }
void VShaderCache::Cleanup() void VShaderCache::Cleanup()
{ {
for (VSCache::iterator iter = vshaders.begin(); iter != vshaders.end();) for (VSCache::iterator iter = vshaders.begin(); iter != vshaders.end();)
{ {
VSCacheEntry &entry = iter->second; VSCacheEntry &entry = iter->second;
if (entry.frameCount < frameCount - 30) if (entry.frameCount < frameCount - 30)
{ {
entry.Destroy(); entry.Destroy();
iter = vshaders.erase(iter); iter = vshaders.erase(iter);
} }
else else
{ {
++iter; ++iter;
} }
} }
SETSTAT(stats.numVertexShadersAlive, (int)vshaders.size()); SETSTAT(stats.numVertexShadersAlive, (int)vshaders.size());
} }

View File

@ -1,87 +1,87 @@
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2008 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0. // the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details. // GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program. // A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/ // If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at // Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
#include <list> #include <list>
#include "Common.h" #include "Common.h"
#include "GLUtil.h" #include "GLUtil.h"
#include "OnScreenDisplay.h" #include "OnScreenDisplay.h"
#include "Render.h" #include "Render.h"
#include "Timer.h" #include "Timer.h"
namespace OSD namespace OSD
{ {
struct MESSAGE struct MESSAGE
{ {
MESSAGE() {} MESSAGE() {}
MESSAGE(const char* p, u32 dw) { MESSAGE(const char* p, u32 dw) {
strncpy(str, p, 255); strncpy(str, p, 255);
str[255] = '\0'; str[255] = '\0';
dwTimeStamp = dw; dwTimeStamp = dw;
} }
char str[256]; char str[256];
u32 dwTimeStamp; u32 dwTimeStamp;
}; };
static std::list<MESSAGE> s_listMsgs; static std::list<MESSAGE> s_listMsgs;
void AddMessage(const char* pstr, u32 ms) void AddMessage(const char* pstr, u32 ms)
{ {
s_listMsgs.push_back(MESSAGE(pstr, timeGetTime() + ms)); s_listMsgs.push_back(MESSAGE(pstr, timeGetTime() + ms));
} }
void DrawMessages() void DrawMessages()
{ {
GLboolean wasEnabled = glIsEnabled(GL_BLEND); GLboolean wasEnabled = glIsEnabled(GL_BLEND);
if (!wasEnabled) if (!wasEnabled)
glEnable(GL_BLEND); glEnable(GL_BLEND);
if (s_listMsgs.size() > 0) if (s_listMsgs.size() > 0)
{ {
int left = 25, top = 15; int left = 25, top = 15;
std::list<MESSAGE>::iterator it = s_listMsgs.begin(); std::list<MESSAGE>::iterator it = s_listMsgs.begin();
while (it != s_listMsgs.end()) while (it != s_listMsgs.end())
{ {
int time_left = (int)(it->dwTimeStamp - timeGetTime()); int time_left = (int)(it->dwTimeStamp - timeGetTime());
int alpha = 255; int alpha = 255;
if (time_left < 1024) if (time_left < 1024)
{ {
alpha = time_left >> 2; alpha = time_left >> 2;
if (time_left < 0) alpha = 0; if (time_left < 0) alpha = 0;
} }
alpha <<= 24; alpha <<= 24;
Renderer::RenderText(it->str, left+1, top+1, 0x000000|alpha); Renderer::RenderText(it->str, left+1, top+1, 0x000000|alpha);
Renderer::RenderText(it->str, left, top, 0xffff30|alpha); Renderer::RenderText(it->str, left, top, 0xffff30|alpha);
top += 15; top += 15;
if (time_left <= 0) if (time_left <= 0)
it = s_listMsgs.erase(it); it = s_listMsgs.erase(it);
else else
++it; ++it;
} }
} }
if (!wasEnabled) if (!wasEnabled)
glDisable(GL_BLEND); glDisable(GL_BLEND);
} }
} // namespace } // namespace

View File

@ -1,223 +1,223 @@
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2008 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0. // the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details. // GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program. // A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/ // If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at // Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
#include "Globals.h" #include "Globals.h"
#include "Profiler.h" #include "Profiler.h"
#include "GLUtil.h" #include "GLUtil.h"
#include <Cg/cg.h> #include <Cg/cg.h>
#include <Cg/cgGL.h> #include <Cg/cgGL.h>
#include <cmath> #include <cmath>
#include "Statistics.h" #include "Statistics.h"
#include "Config.h" #include "Config.h"
#include "ImageWrite.h" #include "ImageWrite.h"
#include "Common.h" #include "Common.h"
#include "Render.h" #include "Render.h"
#include "VertexShaderGen.h" #include "VertexShaderGen.h"
#include "PixelShaderCache.h" #include "PixelShaderCache.h"
#include "PixelShaderManager.h" #include "PixelShaderManager.h"
static int s_nMaxPixelInstructions; static int s_nMaxPixelInstructions;
static GLuint s_ColorMatrixProgram = 0; static GLuint s_ColorMatrixProgram = 0;
PixelShaderCache::PSCache PixelShaderCache::pshaders; PixelShaderCache::PSCache PixelShaderCache::pshaders;
PIXELSHADERUID PixelShaderCache::s_curuid; PIXELSHADERUID PixelShaderCache::s_curuid;
static FRAGMENTSHADER* pShaderLast = NULL; static FRAGMENTSHADER* pShaderLast = NULL;
void SetPSConstant4f(int const_number, float f1, float f2, float f3, float f4) void SetPSConstant4f(int const_number, float f1, float f2, float f3, float f4)
{ {
glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, const_number, f1, f2, f3, f4); glProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, const_number, f1, f2, f3, f4);
} }
void SetPSConstant4fv(int const_number, const float *f) void SetPSConstant4fv(int const_number, const float *f)
{ {
glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, const_number, f); glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, const_number, f);
} }
void PixelShaderCache::Init() void PixelShaderCache::Init()
{ {
GL_REPORT_ERRORD(); GL_REPORT_ERRORD();
glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB, (GLint *)&s_nMaxPixelInstructions); glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB, (GLint *)&s_nMaxPixelInstructions);
int maxinst, maxattribs; int maxinst, maxattribs;
glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, (GLint *)&maxinst); glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, (GLint *)&maxinst);
glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB, (GLint *)&maxattribs); glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB, (GLint *)&maxattribs);
ERROR_LOG("pixel max_alu=%d, max_inst=%d, max_attrib=%d\n", s_nMaxPixelInstructions, maxinst, maxattribs); ERROR_LOG("pixel max_alu=%d, max_inst=%d, max_attrib=%d\n", s_nMaxPixelInstructions, maxinst, maxattribs);
char pmatrixprog[1024]; char pmatrixprog[1024];
sprintf(pmatrixprog, "!!ARBfp1.0" sprintf(pmatrixprog, "!!ARBfp1.0"
"TEMP R0;\n" "TEMP R0;\n"
"TEMP R1;\n" "TEMP R1;\n"
"TEX R0, fragment.texcoord[0], texture[0], RECT;\n" "TEX R0, fragment.texcoord[0], texture[0], RECT;\n"
"DP4 R1.w, R0, program.env[%d];\n" "DP4 R1.w, R0, program.env[%d];\n"
"DP4 R1.z, R0, program.env[%d];\n" "DP4 R1.z, R0, program.env[%d];\n"
"DP4 R1.x, R0, program.env[%d];\n" "DP4 R1.x, R0, program.env[%d];\n"
"DP4 R1.y, R0, program.env[%d];\n" "DP4 R1.y, R0, program.env[%d];\n"
"ADD result.color, R1, program.env[%d];\n" "ADD result.color, R1, program.env[%d];\n"
"END\n", C_COLORMATRIX+3, C_COLORMATRIX+2, C_COLORMATRIX, C_COLORMATRIX+1, C_COLORMATRIX+4); "END\n", C_COLORMATRIX+3, C_COLORMATRIX+2, C_COLORMATRIX, C_COLORMATRIX+1, C_COLORMATRIX+4);
glGenProgramsARB(1, &s_ColorMatrixProgram); glGenProgramsARB(1, &s_ColorMatrixProgram);
glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, s_ColorMatrixProgram); glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, s_ColorMatrixProgram);
glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei)strlen(pmatrixprog), pmatrixprog); glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei)strlen(pmatrixprog), pmatrixprog);
GLenum err = GL_NO_ERROR; GLenum err = GL_NO_ERROR;
GL_REPORT_ERROR(); GL_REPORT_ERROR();
if (err != GL_NO_ERROR) { if (err != GL_NO_ERROR) {
ERROR_LOG("Failed to create color matrix fragment program\n"); ERROR_LOG("Failed to create color matrix fragment program\n");
glDeleteProgramsARB(1, &s_ColorMatrixProgram); glDeleteProgramsARB(1, &s_ColorMatrixProgram);
s_ColorMatrixProgram = 0; s_ColorMatrixProgram = 0;
} }
} }
void PixelShaderCache::Shutdown() void PixelShaderCache::Shutdown()
{ {
glDeleteProgramsARB(1, &s_ColorMatrixProgram); glDeleteProgramsARB(1, &s_ColorMatrixProgram);
s_ColorMatrixProgram = 0; s_ColorMatrixProgram = 0;
PSCache::iterator iter = pshaders.begin(); PSCache::iterator iter = pshaders.begin();
for (; iter != pshaders.end(); iter++) for (; iter != pshaders.end(); iter++)
iter->second.Destroy(); iter->second.Destroy();
pshaders.clear(); pshaders.clear();
} }
GLuint PixelShaderCache::GetColorMatrixProgram() GLuint PixelShaderCache::GetColorMatrixProgram()
{ {
return s_ColorMatrixProgram; return s_ColorMatrixProgram;
} }
FRAGMENTSHADER* PixelShaderCache::GetShader() FRAGMENTSHADER* PixelShaderCache::GetShader()
{ {
DVSTARTPROFILE(); DVSTARTPROFILE();
PIXELSHADERUID uid; PIXELSHADERUID uid;
u32 zbufrender = (Renderer::GetZBufferTarget() && bpmem.zmode.updateenable) ? 1 : 0; u32 zbufrender = (Renderer::GetZBufferTarget() && bpmem.zmode.updateenable) ? 1 : 0;
u32 zBufRenderToCol0 = Renderer::GetRenderMode() != Renderer::RM_Normal; u32 zBufRenderToCol0 = Renderer::GetRenderMode() != Renderer::RM_Normal;
GetPixelShaderId(uid, PixelShaderManager::GetTextureMask(), zbufrender, zBufRenderToCol0); GetPixelShaderId(uid, PixelShaderManager::GetTextureMask(), zbufrender, zBufRenderToCol0);
PSCache::iterator iter = pshaders.find(uid); PSCache::iterator iter = pshaders.find(uid);
if (iter != pshaders.end()) { if (iter != pshaders.end()) {
iter->second.frameCount = frameCount; iter->second.frameCount = frameCount;
PSCacheEntry &entry = iter->second; PSCacheEntry &entry = iter->second;
if (&entry.shader != pShaderLast) if (&entry.shader != pShaderLast)
{ {
pShaderLast = &entry.shader; pShaderLast = &entry.shader;
} }
return pShaderLast; return pShaderLast;
} }
PSCacheEntry& newentry = pshaders[uid]; PSCacheEntry& newentry = pshaders[uid];
const char *code = GeneratePixelShader(PixelShaderManager::GetTextureMask(), const char *code = GeneratePixelShader(PixelShaderManager::GetTextureMask(),
Renderer::GetZBufferTarget() != 0, Renderer::GetZBufferTarget() != 0,
Renderer::GetRenderMode() != Renderer::RM_Normal); Renderer::GetRenderMode() != Renderer::RM_Normal);
#if defined(_DEBUG) || defined(DEBUGFAST) #if defined(_DEBUG) || defined(DEBUGFAST)
if (g_Config.iLog & CONF_SAVESHADERS && code) { if (g_Config.iLog & CONF_SAVESHADERS && code) {
static int counter = 0; static int counter = 0;
char szTemp[MAX_PATH]; char szTemp[MAX_PATH];
sprintf(szTemp, "%s/ps_%04i.txt", FULL_DUMP_DIR, counter++); sprintf(szTemp, "%s/ps_%04i.txt", FULL_DUMP_DIR, counter++);
SaveData(szTemp, code); SaveData(szTemp, code);
} }
#endif #endif
// printf("Compiling pixel shader. size = %i\n", strlen(code)); // printf("Compiling pixel shader. size = %i\n", strlen(code));
if (!code || !CompilePixelShader(newentry.shader, code)) { if (!code || !CompilePixelShader(newentry.shader, code)) {
ERROR_LOG("failed to create pixel shader\n"); ERROR_LOG("failed to create pixel shader\n");
return NULL; return NULL;
} }
//Make an entry in the table //Make an entry in the table
newentry.frameCount = frameCount; newentry.frameCount = frameCount;
pShaderLast = &newentry.shader; pShaderLast = &newentry.shader;
INCSTAT(stats.numPixelShadersCreated); INCSTAT(stats.numPixelShadersCreated);
SETSTAT(stats.numPixelShadersAlive, pshaders.size()); SETSTAT(stats.numPixelShadersAlive, pshaders.size());
return pShaderLast; return pShaderLast;
} }
void PixelShaderCache::Cleanup() void PixelShaderCache::Cleanup()
{ {
PSCache::iterator iter = pshaders.begin(); PSCache::iterator iter = pshaders.begin();
while (iter != pshaders.end()) { while (iter != pshaders.end()) {
PSCacheEntry &entry = iter->second; PSCacheEntry &entry = iter->second;
if (entry.frameCount < frameCount - 400) { if (entry.frameCount < frameCount - 400) {
entry.Destroy(); entry.Destroy();
#ifdef _WIN32 #ifdef _WIN32
iter = pshaders.erase(iter); iter = pshaders.erase(iter);
#else #else
pshaders.erase(iter++); // (this is gcc standard!) pshaders.erase(iter++); // (this is gcc standard!)
#endif #endif
} }
else else
iter++; iter++;
} }
SETSTAT(stats.numPixelShadersAlive,(int)pshaders.size()); SETSTAT(stats.numPixelShadersAlive,(int)pshaders.size());
} }
bool PixelShaderCache::CompilePixelShader(FRAGMENTSHADER& ps, const char* pstrprogram) bool PixelShaderCache::CompilePixelShader(FRAGMENTSHADER& ps, const char* pstrprogram)
{ {
char stropt[64]; char stropt[64];
sprintf(stropt, "MaxLocalParams=32,NumInstructionSlots=%d", s_nMaxPixelInstructions); sprintf(stropt, "MaxLocalParams=32,NumInstructionSlots=%d", s_nMaxPixelInstructions);
const char* opts[] = {"-profileopts", stropt, "-O2", "-q", NULL}; const char* opts[] = {"-profileopts", stropt, "-O2", "-q", NULL};
CGprogram tempprog = cgCreateProgram(g_cgcontext, CG_SOURCE, pstrprogram, g_cgfProf, "main", opts); CGprogram tempprog = cgCreateProgram(g_cgcontext, CG_SOURCE, pstrprogram, g_cgfProf, "main", opts);
if (!cgIsProgram(tempprog) || cgGetError() != CG_NO_ERROR) { if (!cgIsProgram(tempprog) || cgGetError() != CG_NO_ERROR) {
ERROR_LOG("Failed to create ps %s:\n", cgGetLastListing(g_cgcontext)); ERROR_LOG("Failed to create ps %s:\n", cgGetLastListing(g_cgcontext));
ERROR_LOG(pstrprogram); ERROR_LOG(pstrprogram);
return false; return false;
} }
char *pcompiledprog = (char*)cgGetProgramString(tempprog, CG_COMPILED_PROGRAM); char *pcompiledprog = (char*)cgGetProgramString(tempprog, CG_COMPILED_PROGRAM);
char *plocal = strstr(pcompiledprog, "program.local"); char *plocal = strstr(pcompiledprog, "program.local");
while (plocal != NULL) { while (plocal != NULL) {
const char* penv = " program.env"; const char* penv = " program.env";
memcpy(plocal, penv, 13); memcpy(plocal, penv, 13);
plocal = strstr(plocal+13, "program.local"); plocal = strstr(plocal+13, "program.local");
} }
if (Renderer::IsUsingATIDrawBuffers()) { if (Renderer::IsUsingATIDrawBuffers()) {
// sometimes compilation can use ARB_draw_buffers, which would fail for ATI cards // sometimes compilation can use ARB_draw_buffers, which would fail for ATI cards
// replace the three characters ARB with ATI. TODO - check whether this is fixed in modern ATI drivers. // replace the three characters ARB with ATI. TODO - check whether this is fixed in modern ATI drivers.
char* poptions = strstr(pcompiledprog, "ARB_draw_buffers"); char* poptions = strstr(pcompiledprog, "ARB_draw_buffers");
if (poptions != NULL) { if (poptions != NULL) {
poptions[0] = 'A'; poptions[0] = 'A';
poptions[1] = 'T'; poptions[1] = 'T';
poptions[2] = 'I'; poptions[2] = 'I';
} }
} }
glGenProgramsARB( 1, &ps.glprogid ); glGenProgramsARB( 1, &ps.glprogid );
glBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, ps.glprogid ); glBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, ps.glprogid );
glProgramStringARB( GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei)strlen(pcompiledprog), pcompiledprog); glProgramStringARB( GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei)strlen(pcompiledprog), pcompiledprog);
GLenum err = GL_NO_ERROR; GLenum err = GL_NO_ERROR;
GL_REPORT_ERROR(); GL_REPORT_ERROR();
if (err != GL_NO_ERROR) { if (err != GL_NO_ERROR) {
ERROR_LOG(pstrprogram); ERROR_LOG(pstrprogram);
ERROR_LOG(pcompiledprog); ERROR_LOG(pcompiledprog);
} }
cgDestroyProgram(tempprog); cgDestroyProgram(tempprog);
// printf("Compiled pixel shader %i\n", ps.glprogid); // printf("Compiled pixel shader %i\n", ps.glprogid);
#if defined(_DEBUG) || defined(DEBUGFAST) #if defined(_DEBUG) || defined(DEBUGFAST)
ps.strprog = pstrprogram; ps.strprog = pstrprogram;
#endif #endif
return true; return true;
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,176 +1,176 @@
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2008 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0. // the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details. // GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program. // A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/ // If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at // Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
#include <math.h> #include <math.h>
#include "Globals.h" #include "Globals.h"
#include "Profiler.h" #include "Profiler.h"
#include "Config.h" #include "Config.h"
#include "Statistics.h" #include "Statistics.h"
#include "GLUtil.h" #include "GLUtil.h"
#include <Cg/cg.h> #include <Cg/cg.h>
#include <Cg/cgGL.h> #include <Cg/cgGL.h>
#include "Render.h" #include "Render.h"
#include "VertexShaderGen.h" #include "VertexShaderGen.h"
#include "VertexShaderManager.h" #include "VertexShaderManager.h"
#include "VertexShaderCache.h" #include "VertexShaderCache.h"
#include "VertexManager.h" #include "VertexManager.h"
#include "VertexLoader.h" #include "VertexLoader.h"
#include "XFMemory.h" #include "XFMemory.h"
#include "ImageWrite.h" #include "ImageWrite.h"
VertexShaderCache::VSCache VertexShaderCache::vshaders; VertexShaderCache::VSCache VertexShaderCache::vshaders;
static VERTEXSHADER *pShaderLast = NULL; static VERTEXSHADER *pShaderLast = NULL;
static int s_nMaxVertexInstructions; static int s_nMaxVertexInstructions;
void SetVSConstant4f(int const_number, float f1, float f2, float f3, float f4) void SetVSConstant4f(int const_number, float f1, float f2, float f3, float f4)
{ {
glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, const_number, f1, f2, f3, f4); glProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, const_number, f1, f2, f3, f4);
} }
void SetVSConstant4fv(int const_number, const float *f) void SetVSConstant4fv(int const_number, const float *f)
{ {
glProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, const_number, f); glProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, const_number, f);
} }
void VertexShaderCache::Init() void VertexShaderCache::Init()
{ {
glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, (GLint *)&s_nMaxVertexInstructions); glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, (GLint *)&s_nMaxVertexInstructions);
} }
void VertexShaderCache::Shutdown() void VertexShaderCache::Shutdown()
{ {
for (VSCache::iterator iter = vshaders.begin(); iter != vshaders.end(); iter++) for (VSCache::iterator iter = vshaders.begin(); iter != vshaders.end(); iter++)
iter->second.Destroy(); iter->second.Destroy();
vshaders.clear(); vshaders.clear();
} }
VERTEXSHADER* VertexShaderCache::GetShader(u32 components) VERTEXSHADER* VertexShaderCache::GetShader(u32 components)
{ {
DVSTARTPROFILE(); DVSTARTPROFILE();
VERTEXSHADERUID uid; VERTEXSHADERUID uid;
u32 zbufrender = (bpmem.ztex2.op == ZTEXTURE_ADD) || Renderer::GetZBufferTarget() != 0; u32 zbufrender = (bpmem.ztex2.op == ZTEXTURE_ADD) || Renderer::GetZBufferTarget() != 0;
GetVertexShaderId(uid, components, zbufrender); GetVertexShaderId(uid, components, zbufrender);
VSCache::iterator iter = vshaders.find(uid); VSCache::iterator iter = vshaders.find(uid);
if (iter != vshaders.end()) { if (iter != vshaders.end()) {
iter->second.frameCount = frameCount; iter->second.frameCount = frameCount;
VSCacheEntry &entry = iter->second; VSCacheEntry &entry = iter->second;
if (&entry.shader != pShaderLast) { if (&entry.shader != pShaderLast) {
pShaderLast = &entry.shader; pShaderLast = &entry.shader;
} }
return pShaderLast; return pShaderLast;
} }
VSCacheEntry& entry = vshaders[uid]; VSCacheEntry& entry = vshaders[uid];
const char *code = GenerateVertexShader(components, Renderer::GetZBufferTarget() != 0); const char *code = GenerateVertexShader(components, Renderer::GetZBufferTarget() != 0);
#if defined(_DEBUG) || defined(DEBUGFAST) #if defined(_DEBUG) || defined(DEBUGFAST)
if (g_Config.iLog & CONF_SAVESHADERS && code) { if (g_Config.iLog & CONF_SAVESHADERS && code) {
static int counter = 0; static int counter = 0;
char szTemp[MAX_PATH]; char szTemp[MAX_PATH];
sprintf(szTemp, "%s/vs_%04i.txt", FULL_DUMP_DIR, counter++); sprintf(szTemp, "%s/vs_%04i.txt", FULL_DUMP_DIR, counter++);
SaveData(szTemp, code); SaveData(szTemp, code);
} }
#endif #endif
if (!code || !VertexShaderCache::CompileVertexShader(entry.shader, code)) { if (!code || !VertexShaderCache::CompileVertexShader(entry.shader, code)) {
ERROR_LOG("failed to create vertex shader\n"); ERROR_LOG("failed to create vertex shader\n");
return NULL; return NULL;
} }
//Make an entry in the table //Make an entry in the table
entry.frameCount = frameCount; entry.frameCount = frameCount;
pShaderLast = &entry.shader; pShaderLast = &entry.shader;
INCSTAT(stats.numVertexShadersCreated); INCSTAT(stats.numVertexShadersCreated);
SETSTAT(stats.numVertexShadersAlive, vshaders.size()); SETSTAT(stats.numVertexShadersAlive, vshaders.size());
return pShaderLast; return pShaderLast;
} }
void VertexShaderCache::Cleanup() void VertexShaderCache::Cleanup()
{ {
VSCache::iterator iter = vshaders.begin(); VSCache::iterator iter = vshaders.begin();
while (iter != vshaders.end()) { while (iter != vshaders.end()) {
VSCacheEntry &entry = iter->second; VSCacheEntry &entry = iter->second;
if (entry.frameCount < frameCount - 200) { if (entry.frameCount < frameCount - 200) {
entry.Destroy(); entry.Destroy();
#ifdef _WIN32 #ifdef _WIN32
iter = vshaders.erase(iter); iter = vshaders.erase(iter);
#else #else
vshaders.erase(iter++); vshaders.erase(iter++);
#endif #endif
} }
else { else {
++iter; ++iter;
} }
} }
SETSTAT(stats.numVertexShadersAlive, vshaders.size()); SETSTAT(stats.numVertexShadersAlive, vshaders.size());
} }
bool VertexShaderCache::CompileVertexShader(VERTEXSHADER& vs, const char* pstrprogram) bool VertexShaderCache::CompileVertexShader(VERTEXSHADER& vs, const char* pstrprogram)
{ {
char stropt[64]; char stropt[64];
sprintf(stropt, "MaxLocalParams=256,MaxInstructions=%d", s_nMaxVertexInstructions); sprintf(stropt, "MaxLocalParams=256,MaxInstructions=%d", s_nMaxVertexInstructions);
const char *opts[] = {"-profileopts", stropt, "-O2", "-q", NULL}; const char *opts[] = {"-profileopts", stropt, "-O2", "-q", NULL};
CGprogram tempprog = cgCreateProgram(g_cgcontext, CG_SOURCE, pstrprogram, g_cgvProf, "main", opts); CGprogram tempprog = cgCreateProgram(g_cgcontext, CG_SOURCE, pstrprogram, g_cgvProf, "main", opts);
if (!cgIsProgram(tempprog) || cgGetError() != CG_NO_ERROR) { if (!cgIsProgram(tempprog) || cgGetError() != CG_NO_ERROR) {
ERROR_LOG("Failed to load vs %s:\n", cgGetLastListing(g_cgcontext)); ERROR_LOG("Failed to load vs %s:\n", cgGetLastListing(g_cgcontext));
ERROR_LOG(pstrprogram); ERROR_LOG(pstrprogram);
return false; return false;
} }
//ERROR_LOG(pstrprogram); //ERROR_LOG(pstrprogram);
//ERROR_LOG("id: %d\n", g_Config.iSaveTargetId); //ERROR_LOG("id: %d\n", g_Config.iSaveTargetId);
char* pcompiledprog = (char*)cgGetProgramString(tempprog, CG_COMPILED_PROGRAM); char* pcompiledprog = (char*)cgGetProgramString(tempprog, CG_COMPILED_PROGRAM);
char* plocal = strstr(pcompiledprog, "program.local"); char* plocal = strstr(pcompiledprog, "program.local");
while (plocal != NULL) { while (plocal != NULL) {
const char* penv = " program.env"; const char* penv = " program.env";
memcpy(plocal, penv, 13); memcpy(plocal, penv, 13);
plocal = strstr(plocal+13, "program.local"); plocal = strstr(plocal+13, "program.local");
} }
glGenProgramsARB(1, &vs.glprogid); glGenProgramsARB(1, &vs.glprogid);
glBindProgramARB(GL_VERTEX_PROGRAM_ARB, vs.glprogid); glBindProgramARB(GL_VERTEX_PROGRAM_ARB, vs.glprogid);
glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei)strlen(pcompiledprog), pcompiledprog); glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei)strlen(pcompiledprog), pcompiledprog);
GLenum err = GL_NO_ERROR; GLenum err = GL_NO_ERROR;
GL_REPORT_ERROR(); GL_REPORT_ERROR();
if (err != GL_NO_ERROR) { if (err != GL_NO_ERROR) {
ERROR_LOG(pstrprogram); ERROR_LOG(pstrprogram);
ERROR_LOG(pcompiledprog); ERROR_LOG(pcompiledprog);
} }
cgDestroyProgram(tempprog); cgDestroyProgram(tempprog);
// printf("Compiled vertex shader %i\n", vs.glprogid); // printf("Compiled vertex shader %i\n", vs.glprogid);
#if defined(_DEBUG) || defined(DEBUGFAST) #if defined(_DEBUG) || defined(DEBUGFAST)
vs.strprog = pstrprogram; vs.strprog = pstrprogram;
#endif #endif
return true; return true;
} }

View File

@ -1,236 +1,236 @@
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2008 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0. // the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details. // GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program. // A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/ // If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at // Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
#include "Common.h" #include "Common.h"
#include "Globals.h" #include "Globals.h"
#include "XFMemory.h" #include "XFMemory.h"
#include "VertexManager.h" #include "VertexManager.h"
#include "VertexShaderManager.h" #include "VertexShaderManager.h"
#include "PixelShaderManager.h" #include "PixelShaderManager.h"
// LoadXFReg 0x10 // LoadXFReg 0x10
void LoadXFReg(u32 transferSize, u32 baseAddress, u32 *pData) void LoadXFReg(u32 transferSize, u32 baseAddress, u32 *pData)
{ {
u32 address = baseAddress; u32 address = baseAddress;
for (int i = 0; i < (int)transferSize; i++) for (int i = 0; i < (int)transferSize; i++)
{ {
address = baseAddress + i; address = baseAddress + i;
// Setup a Matrix // Setup a Matrix
if (address < 0x1000) if (address < 0x1000)
{ {
VertexManager::Flush(); VertexManager::Flush();
VertexShaderManager::InvalidateXFRange(address, address + transferSize); VertexShaderManager::InvalidateXFRange(address, address + transferSize);
//PRIM_LOG("xfmem write: 0x%x-0x%x\n", address, address+transferSize); //PRIM_LOG("xfmem write: 0x%x-0x%x\n", address, address+transferSize);
u32* p1 = &xfmem[address]; u32* p1 = &xfmem[address];
memcpy_gc(p1, &pData[i], transferSize*4); memcpy_gc(p1, &pData[i], transferSize*4);
i += transferSize; i += transferSize;
} }
else if (address<0x2000) else if (address<0x2000)
{ {
u32 data = pData[i]; u32 data = pData[i];
switch (address) switch (address)
{ {
case 0x1000: // error case 0x1000: // error
break; break;
case 0x1001: // diagnostics case 0x1001: // diagnostics
break; break;
case 0x1002: // internal state 0 case 0x1002: // internal state 0
break; break;
case 0x1003: // internal state 1 case 0x1003: // internal state 1
break; break;
case 0x1004: // xf_clock case 0x1004: // xf_clock
break; break;
case 0x1005: // clipdisable case 0x1005: // clipdisable
if (data & 1) { // disable clipping detection if (data & 1) { // disable clipping detection
} }
if (data & 2) { // disable trivial rejection if (data & 2) { // disable trivial rejection
} }
if (data & 4) { // disable cpoly clipping acceleration if (data & 4) { // disable cpoly clipping acceleration
} }
break; break;
case 0x1006: //SetGPMetric case 0x1006: //SetGPMetric
break; break;
case 0x1008: //__GXXfVtxSpecs, wrote 0004 case 0x1008: //__GXXfVtxSpecs, wrote 0004
xfregs.hostinfo = *(INVTXSPEC*)&data; xfregs.hostinfo = *(INVTXSPEC*)&data;
break; break;
case 0x1009: //GXSetNumChans (no) case 0x1009: //GXSetNumChans (no)
if ((u32)xfregs.nNumChans != (data&3)) { if ((u32)xfregs.nNumChans != (data&3)) {
VertexManager::Flush(); VertexManager::Flush();
xfregs.nNumChans = data&3; xfregs.nNumChans = data&3;
} }
break; break;
case 0x100a: //GXSetChanAmbientcolor case 0x100a: //GXSetChanAmbientcolor
if (xfregs.colChans[0].ambColor != data) { if (xfregs.colChans[0].ambColor != data) {
VertexManager::Flush(); VertexManager::Flush();
xfregs.colChans[0].ambColor = data; xfregs.colChans[0].ambColor = data;
VertexShaderManager::SetMaterialColor(0, data); VertexShaderManager::SetMaterialColor(0, data);
} }
break; break;
case 0x100b: //GXSetChanAmbientcolor case 0x100b: //GXSetChanAmbientcolor
if (xfregs.colChans[1].ambColor != data) { if (xfregs.colChans[1].ambColor != data) {
VertexManager::Flush(); VertexManager::Flush();
xfregs.colChans[1].ambColor = data; xfregs.colChans[1].ambColor = data;
VertexShaderManager::SetMaterialColor(1, data); VertexShaderManager::SetMaterialColor(1, data);
} }
break; break;
case 0x100c: //GXSetChanMatcolor (rgba) case 0x100c: //GXSetChanMatcolor (rgba)
if (xfregs.colChans[0].matColor != data) { if (xfregs.colChans[0].matColor != data) {
VertexManager::Flush(); VertexManager::Flush();
xfregs.colChans[0].matColor = data; xfregs.colChans[0].matColor = data;
VertexShaderManager::SetMaterialColor(2, data); VertexShaderManager::SetMaterialColor(2, data);
} }
break; break;
case 0x100d: //GXSetChanMatcolor (rgba) case 0x100d: //GXSetChanMatcolor (rgba)
if (xfregs.colChans[1].matColor != data) { if (xfregs.colChans[1].matColor != data) {
VertexManager::Flush(); VertexManager::Flush();
xfregs.colChans[1].matColor = data; xfregs.colChans[1].matColor = data;
VertexShaderManager::SetMaterialColor(3, data); VertexShaderManager::SetMaterialColor(3, data);
} }
break; break;
case 0x100e: // color0 case 0x100e: // color0
if (xfregs.colChans[0].color.hex != (data & 0x7fff) ) { if (xfregs.colChans[0].color.hex != (data & 0x7fff) ) {
VertexManager::Flush(); VertexManager::Flush();
xfregs.colChans[0].color.hex = data; xfregs.colChans[0].color.hex = data;
} }
break; break;
case 0x100f: // color1 case 0x100f: // color1
if (xfregs.colChans[1].color.hex != (data & 0x7fff) ) { if (xfregs.colChans[1].color.hex != (data & 0x7fff) ) {
VertexManager::Flush(); VertexManager::Flush();
xfregs.colChans[1].color.hex = data; xfregs.colChans[1].color.hex = data;
} }
break; break;
case 0x1010: // alpha0 case 0x1010: // alpha0
if (xfregs.colChans[0].alpha.hex != (data & 0x7fff) ) { if (xfregs.colChans[0].alpha.hex != (data & 0x7fff) ) {
VertexManager::Flush(); VertexManager::Flush();
xfregs.colChans[0].alpha.hex = data; xfregs.colChans[0].alpha.hex = data;
} }
break; break;
case 0x1011: // alpha1 case 0x1011: // alpha1
if (xfregs.colChans[1].alpha.hex != (data & 0x7fff) ) { if (xfregs.colChans[1].alpha.hex != (data & 0x7fff) ) {
VertexManager::Flush(); VertexManager::Flush();
xfregs.colChans[1].alpha.hex = data; xfregs.colChans[1].alpha.hex = data;
} }
break; break;
case 0x1012: // dual tex transform case 0x1012: // dual tex transform
if (xfregs.bEnableDualTexTransform != (data & 1)) { if (xfregs.bEnableDualTexTransform != (data & 1)) {
VertexManager::Flush(); VertexManager::Flush();
xfregs.bEnableDualTexTransform = data & 1; xfregs.bEnableDualTexTransform = data & 1;
} }
break; break;
case 0x1013: case 0x1013:
case 0x1014: case 0x1014:
case 0x1015: case 0x1015:
case 0x1016: case 0x1016:
case 0x1017: case 0x1017:
DEBUG_LOG("xf addr: %x=%x\n", address, data); DEBUG_LOG("xf addr: %x=%x\n", address, data);
break; break;
case 0x1018: case 0x1018:
//_assert_msg_(GX_XF, 0, "XF matrixindex0"); //_assert_msg_(GX_XF, 0, "XF matrixindex0");
VertexShaderManager::SetTexMatrixChangedA(data); //? VertexShaderManager::SetTexMatrixChangedA(data); //?
break; break;
case 0x1019: case 0x1019:
//_assert_msg_(GX_XF, 0, "XF matrixindex1"); //_assert_msg_(GX_XF, 0, "XF matrixindex1");
VertexShaderManager::SetTexMatrixChangedB(data); //? VertexShaderManager::SetTexMatrixChangedB(data); //?
break; break;
case 0x101a: case 0x101a:
VertexManager::Flush(); VertexManager::Flush();
VertexShaderManager::SetViewport((float*)&pData[i]); VertexShaderManager::SetViewport((float*)&pData[i]);
PixelShaderManager::SetViewport((float*)&pData[i]); PixelShaderManager::SetViewport((float*)&pData[i]);
i += 6; i += 6;
break; break;
case 0x101c: // paper mario writes 16777216.0f, 1677721.75 case 0x101c: // paper mario writes 16777216.0f, 1677721.75
break; break;
case 0x101f: // paper mario writes 16777216.0f, 5033165.0f case 0x101f: // paper mario writes 16777216.0f, 5033165.0f
break; break;
case 0x1020: case 0x1020:
VertexManager::Flush(); VertexManager::Flush();
VertexShaderManager::SetProjection((float*)&pData[i]); VertexShaderManager::SetProjection((float*)&pData[i]);
i += 7; i += 7;
return; return;
case 0x103f: // GXSetNumTexGens case 0x103f: // GXSetNumTexGens
if ((u32)xfregs.numTexGens != data) { if ((u32)xfregs.numTexGens != data) {
VertexManager::Flush(); VertexManager::Flush();
xfregs.numTexGens = data; xfregs.numTexGens = data;
} }
break; break;
case 0x1040: xfregs.texcoords[0].texmtxinfo.hex = data; break; case 0x1040: xfregs.texcoords[0].texmtxinfo.hex = data; break;
case 0x1041: xfregs.texcoords[1].texmtxinfo.hex = data; break; case 0x1041: xfregs.texcoords[1].texmtxinfo.hex = data; break;
case 0x1042: xfregs.texcoords[2].texmtxinfo.hex = data; break; case 0x1042: xfregs.texcoords[2].texmtxinfo.hex = data; break;
case 0x1043: xfregs.texcoords[3].texmtxinfo.hex = data; break; case 0x1043: xfregs.texcoords[3].texmtxinfo.hex = data; break;
case 0x1044: xfregs.texcoords[4].texmtxinfo.hex = data; break; case 0x1044: xfregs.texcoords[4].texmtxinfo.hex = data; break;
case 0x1045: xfregs.texcoords[5].texmtxinfo.hex = data; break; case 0x1045: xfregs.texcoords[5].texmtxinfo.hex = data; break;
case 0x1046: xfregs.texcoords[6].texmtxinfo.hex = data; break; case 0x1046: xfregs.texcoords[6].texmtxinfo.hex = data; break;
case 0x1047: xfregs.texcoords[7].texmtxinfo.hex = data; break; case 0x1047: xfregs.texcoords[7].texmtxinfo.hex = data; break;
case 0x1048: case 0x1048:
case 0x1049: case 0x1049:
case 0x104a: case 0x104a:
case 0x104b: case 0x104b:
case 0x104c: case 0x104c:
case 0x104d: case 0x104d:
case 0x104e: case 0x104e:
case 0x104f: case 0x104f:
DEBUG_LOG("xf addr: %x=%x\n", address, data); DEBUG_LOG("xf addr: %x=%x\n", address, data);
break; break;
case 0x1050: xfregs.texcoords[0].postmtxinfo.hex = data; break; case 0x1050: xfregs.texcoords[0].postmtxinfo.hex = data; break;
case 0x1051: xfregs.texcoords[1].postmtxinfo.hex = data; break; case 0x1051: xfregs.texcoords[1].postmtxinfo.hex = data; break;
case 0x1052: xfregs.texcoords[2].postmtxinfo.hex = data; break; case 0x1052: xfregs.texcoords[2].postmtxinfo.hex = data; break;
case 0x1053: xfregs.texcoords[3].postmtxinfo.hex = data; break; case 0x1053: xfregs.texcoords[3].postmtxinfo.hex = data; break;
case 0x1054: xfregs.texcoords[4].postmtxinfo.hex = data; break; case 0x1054: xfregs.texcoords[4].postmtxinfo.hex = data; break;
case 0x1055: xfregs.texcoords[5].postmtxinfo.hex = data; break; case 0x1055: xfregs.texcoords[5].postmtxinfo.hex = data; break;
case 0x1056: xfregs.texcoords[6].postmtxinfo.hex = data; break; case 0x1056: xfregs.texcoords[6].postmtxinfo.hex = data; break;
case 0x1057: xfregs.texcoords[7].postmtxinfo.hex = data; break; case 0x1057: xfregs.texcoords[7].postmtxinfo.hex = data; break;
default: default:
DEBUG_LOG("xf addr: %x=%x\n", address, data); DEBUG_LOG("xf addr: %x=%x\n", address, data);
break; break;
} }
} }
else if (address >= 0x4000) else if (address >= 0x4000)
{ {
// MessageBox(NULL, "1", "1", MB_OK); // MessageBox(NULL, "1", "1", MB_OK);
//4010 __GXSetGenMode //4010 __GXSetGenMode
} }
} }
} }
// TODO - verify that it is correct. Seems to work, though. // TODO - verify that it is correct. Seems to work, though.
void LoadIndexedXF(u32 val, int array) void LoadIndexedXF(u32 val, int array)
{ {
int index = val >> 16; int index = val >> 16;
int address = val & 0xFFF; //check mask int address = val & 0xFFF; //check mask
int size = ((val >> 12) & 0xF) + 1; int size = ((val >> 12) & 0xF) + 1;
//load stuff from array to address in xf mem //load stuff from array to address in xf mem
VertexManager::Flush(); VertexManager::Flush();
VertexShaderManager::InvalidateXFRange(address, address + size); VertexShaderManager::InvalidateXFRange(address, address + size);
//PRIM_LOG("xfmem iwrite: 0x%x-0x%x\n", address, address + size); //PRIM_LOG("xfmem iwrite: 0x%x-0x%x\n", address, address + size);
for (int i = 0; i < size; i++) for (int i = 0; i < size; i++)
xfmem[address + i] = Memory_Read_U32(arraybases[array] + arraystrides[array] * index + i * 4); xfmem[address + i] = Memory_Read_U32(arraybases[array] + arraystrides[array] * index + i * 4);
} }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,367 +1,367 @@
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2008 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0. // the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details. // GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program. // A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/ // If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at // Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Includes // Includes
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#include <vector> #include <vector>
#include <string> #include <string>
#include "../../../Core/InputCommon/Src/SDL.h" // Core #include "../../../Core/InputCommon/Src/SDL.h" // Core
#include "../../../Core/InputCommon/Src/XInput.h" #include "../../../Core/InputCommon/Src/XInput.h"
#include "Common.h" // Common #include "Common.h" // Common
#include "MathUtil.h" #include "MathUtil.h"
#include "StringUtil.h" // for ArrayToString() #include "StringUtil.h" // for ArrayToString()
#include "IniFile.h" #include "IniFile.h"
#include "pluginspecs_wiimote.h" #include "pluginspecs_wiimote.h"
#include "EmuDefinitions.h" // Local #include "EmuDefinitions.h" // Local
#include "main.h" #include "main.h"
#include "wiimote_hid.h" #include "wiimote_hid.h"
#include "EmuSubroutines.h" #include "EmuSubroutines.h"
#include "EmuMain.h" #include "EmuMain.h"
#include "Encryption.h" // for extension encryption #include "Encryption.h" // for extension encryption
#include "Logging.h" // for startConsoleWin, Console::Print, GetConsoleHwnd #include "Logging.h" // for startConsoleWin, Console::Print, GetConsoleHwnd
#include "Config.h" // for g_Config #include "Config.h" // for g_Config
//////////////////////////////////// ////////////////////////////////////
namespace WiiMoteEmu namespace WiiMoteEmu
{ {
//****************************************************************************** //******************************************************************************
// Accelerometer functions // Accelerometer functions
//****************************************************************************** //******************************************************************************
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Test the calculations // Test the calculations
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void TiltTest(u8 x, u8 y, u8 z) void TiltTest(u8 x, u8 y, u8 z)
{ {
int Roll, Pitch, RollAdj, PitchAdj; int Roll, Pitch, RollAdj, PitchAdj;
PitchAccelerometerToDegree(x, y, z, Roll, Pitch, RollAdj, PitchAdj); PitchAccelerometerToDegree(x, y, z, Roll, Pitch, RollAdj, PitchAdj);
std::string From = StringFromFormat("From: X:%i Y:%i Z:%i Roll:%s Pitch:%s", x, y, z, std::string From = StringFromFormat("From: X:%i Y:%i Z:%i Roll:%s Pitch:%s", x, y, z,
(Roll >= 0) ? StringFromFormat(" %03i", Roll).c_str() : StringFromFormat("%04i", Roll).c_str(), (Roll >= 0) ? StringFromFormat(" %03i", Roll).c_str() : StringFromFormat("%04i", Roll).c_str(),
(Pitch >= 0) ? StringFromFormat(" %03i", Pitch).c_str() : StringFromFormat("%04i", Pitch).c_str()); (Pitch >= 0) ? StringFromFormat(" %03i", Pitch).c_str() : StringFromFormat("%04i", Pitch).c_str());
float _Roll = (float)Roll, _Pitch = (float)Pitch; float _Roll = (float)Roll, _Pitch = (float)Pitch;
PitchDegreeToAccelerometer(_Roll, _Pitch, x, y, z); PitchDegreeToAccelerometer(_Roll, _Pitch, x, y, z);
std::string To = StringFromFormat("%s\nTo: X:%i Y:%i Z:%i Roll:%s Pitch:%s", From.c_str(), x, y, z, std::string To = StringFromFormat("%s\nTo: X:%i Y:%i Z:%i Roll:%s Pitch:%s", From.c_str(), x, y, z,
(_Roll >= 0) ? StringFromFormat(" %03i", (int)_Roll).c_str() : StringFromFormat("%04i", (int)_Roll).c_str(), (_Roll >= 0) ? StringFromFormat(" %03i", (int)_Roll).c_str() : StringFromFormat("%04i", (int)_Roll).c_str(),
(_Pitch >= 0) ? StringFromFormat(" %03i", (int)_Pitch).c_str() : StringFromFormat("%04i", (int)_Pitch).c_str()); (_Pitch >= 0) ? StringFromFormat(" %03i", (int)_Pitch).c_str() : StringFromFormat("%04i", (int)_Pitch).c_str());
Console::Print("%s\n", To.c_str()); Console::Print("%s\n", To.c_str());
} }
//////////////////////////////////// ////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
/* Angles adjustment for the upside down state when both roll and pitch is used. When the absolute values /* Angles adjustment for the upside down state when both roll and pitch is used. When the absolute values
of the angles go over 90<39> the Wiimote is upside down and these adjustments are needed. */ of the angles go over 90<39> the Wiimote is upside down and these adjustments are needed. */
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void AdjustAngles(float &Roll, float &Pitch) void AdjustAngles(float &Roll, float &Pitch)
{ {
float OldPitch = Pitch; float OldPitch = Pitch;
if (abs(Roll) > 90) if (abs(Roll) > 90)
{ {
if (Pitch >= 0) if (Pitch >= 0)
Pitch = 180 - Pitch; // 15 to 165 Pitch = 180 - Pitch; // 15 to 165
else if (Pitch < 0) else if (Pitch < 0)
Pitch = -180 - Pitch; // -15 to -165 Pitch = -180 - Pitch; // -15 to -165
} }
if (abs(OldPitch) > 90) if (abs(OldPitch) > 90)
{ {
if (Roll >= 0) if (Roll >= 0)
Roll = 180 - Roll; // 15 to 165 Roll = 180 - Roll; // 15 to 165
else if (Roll < 0) else if (Roll < 0)
Roll = -180 - Roll; // -15 to -165 Roll = -180 - Roll; // -15 to -165
} }
} }
//////////////////////////////////// ////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Angles to accelerometer values // Angles to accelerometer values
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void PitchDegreeToAccelerometer(float _Roll, float _Pitch, u8 &_x, u8 &_y, u8 &_z) void PitchDegreeToAccelerometer(float _Roll, float _Pitch, u8 &_x, u8 &_y, u8 &_z)
{ {
// We need radiands for the math functions // We need radiands for the math functions
_Roll = InputCommon::Deg2Rad(_Roll); _Roll = InputCommon::Deg2Rad(_Roll);
_Pitch = InputCommon::Deg2Rad(_Pitch); _Pitch = InputCommon::Deg2Rad(_Pitch);
// We need decimal values // We need decimal values
float x = (float)_x, y = (float)_y, z = (float)_z; float x = (float)_x, y = (float)_y, z = (float)_z;
// In these cases we can use the simple and accurate formula // In these cases we can use the simple and accurate formula
if(g_Config.Trigger.Range.Pitch == 0) if(g_Config.Trigger.Range.Pitch == 0)
{ {
x = sin(_Roll); x = sin(_Roll);
z = cos(_Roll); z = cos(_Roll);
} }
else if (g_Config.Trigger.Range.Roll == 0) else if (g_Config.Trigger.Range.Roll == 0)
{ {
y = sin(_Pitch); y = sin(_Pitch);
z = cos(_Pitch); z = cos(_Pitch);
} }
else else
{ {
// ==================================================== // ====================================================
/* This seems to always produce the exact same combination of x, y, z and Roll and Pitch that the /* This seems to always produce the exact same combination of x, y, z and Roll and Pitch that the
real Wiimote produce. There is an unlimited amount of x, y, z combinations for any combination of real Wiimote produce. There is an unlimited amount of x, y, z combinations for any combination of
Roll and Pitch. But if we select a Z from the smallest of the absolute value of cos(Roll) and Roll and Pitch. But if we select a Z from the smallest of the absolute value of cos(Roll) and
cos (Pitch) we get the right values. */ cos (Pitch) we get the right values. */
// --------- // ---------
if (abs(cos(_Roll)) < abs(cos(_Pitch))) z = cos(_Roll); else z = cos(_Pitch); if (abs(cos(_Roll)) < abs(cos(_Pitch))) z = cos(_Roll); else z = cos(_Pitch);
/* I got these from reversing the calculation in PitchAccelerometerToDegree() in a math program /* I got these from reversing the calculation in PitchAccelerometerToDegree() in a math program
I don't know if we can derive these from some kind of matrix or something */ I don't know if we can derive these from some kind of matrix or something */
float x_num = 2 * tanf(0.5f * _Roll) * z; float x_num = 2 * tanf(0.5f * _Roll) * z;
float x_den = pow2f(tanf(0.5f * _Roll)) - 1; float x_den = pow2f(tanf(0.5f * _Roll)) - 1;
x = - (x_num / x_den); x = - (x_num / x_den);
float y_num = 2 * tanf(0.5f * _Pitch) * z; float y_num = 2 * tanf(0.5f * _Pitch) * z;
float y_den = pow2f(tanf(0.5f * _Pitch)) - 1; float y_den = pow2f(tanf(0.5f * _Pitch)) - 1;
y = - (y_num / y_den); y = - (y_num / y_den);
// ========================= // =========================
} }
// Multiply with the neutral of z and its g // Multiply with the neutral of z and its g
float xg = g_wm.cal_g.x; float xg = g_wm.cal_g.x;
float yg = g_wm.cal_g.y; float yg = g_wm.cal_g.y;
float zg = g_wm.cal_g.z; float zg = g_wm.cal_g.z;
float x_zero = g_wm.cal_zero.x; float x_zero = g_wm.cal_zero.x;
float y_zero = g_wm.cal_zero.y; float y_zero = g_wm.cal_zero.y;
float z_zero = g_wm.cal_zero.z; float z_zero = g_wm.cal_zero.z;
int ix = (int) (x_zero + xg * x); int ix = (int) (x_zero + xg * x);
int iy = (int) (y_zero + yg * y); int iy = (int) (y_zero + yg * y);
int iz = (int) (z_zero + zg * z); int iz = (int) (z_zero + zg * z);
// Boundaries // Boundaries
if (ix < 0) ix = 0; if (ix > 255) ix = 255; if (ix < 0) ix = 0; if (ix > 255) ix = 255;
if (iy < 0) iy = 0; if (iy > 255) iy = 255; if (iy < 0) iy = 0; if (iy > 255) iy = 255;
if (iz < 0) iz = 0; if (iz > 255) iz = 255; if (iz < 0) iz = 0; if (iz > 255) iz = 255;
if(g_Config.Trigger.Range.Roll != 0) _x = ix; if(g_Config.Trigger.Range.Roll != 0) _x = ix;
if(g_Config.Trigger.Range.Pitch != 0) _y = iy; if(g_Config.Trigger.Range.Pitch != 0) _y = iy;
_z = iz; _z = iz;
} }
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Accelerometer to roll and pitch angles // Accelerometer to roll and pitch angles
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
float AccelerometerToG(float Current, float Neutral, float G) float AccelerometerToG(float Current, float Neutral, float G)
{ {
float _G = (Current - Neutral) / G; float _G = (Current - Neutral) / G;
return _G; return _G;
} }
void PitchAccelerometerToDegree(u8 _x, u8 _y, u8 _z, int &_Roll, int &_Pitch, int &_RollAdj, int &_PitchAdj) void PitchAccelerometerToDegree(u8 _x, u8 _y, u8 _z, int &_Roll, int &_Pitch, int &_RollAdj, int &_PitchAdj)
{ {
// Definitions // Definitions
float Roll = 0, Pitch = 0; float Roll = 0, Pitch = 0;
// Calculate how many g we are from the neutral // Calculate how many g we are from the neutral
float x = AccelerometerToG((float)_x, (float)g_wm.cal_zero.x, (float)g_wm.cal_g.x); float x = AccelerometerToG((float)_x, (float)g_wm.cal_zero.x, (float)g_wm.cal_g.x);
float y = AccelerometerToG((float)_y, (float)g_wm.cal_zero.y, (float)g_wm.cal_g.y); float y = AccelerometerToG((float)_y, (float)g_wm.cal_zero.y, (float)g_wm.cal_g.y);
float z = AccelerometerToG((float)_z, (float)g_wm.cal_zero.z, (float)g_wm.cal_g.z); float z = AccelerometerToG((float)_z, (float)g_wm.cal_zero.z, (float)g_wm.cal_g.z);
// If it is over 1g then it is probably accelerating and may not reliable // If it is over 1g then it is probably accelerating and may not reliable
//if (abs(accel->x - ac->cal_zero.x) <= ac->cal_g.x) //if (abs(accel->x - ac->cal_zero.x) <= ac->cal_g.x)
{ {
// Calculate the degree // Calculate the degree
Roll = InputCommon::Rad2Deg(atan2(x, z)); Roll = InputCommon::Rad2Deg(atan2(x, z));
} }
//if (abs(_y - g_wm.cal_zero.y) <= g_wm.cal_g.y) //if (abs(_y - g_wm.cal_zero.y) <= g_wm.cal_g.y)
{ {
// Calculate the degree // Calculate the degree
Pitch = InputCommon::Rad2Deg(atan2(y, z)); Pitch = InputCommon::Rad2Deg(atan2(y, z));
} }
_Roll = (int)Roll; _Roll = (int)Roll;
_Pitch = (int)Pitch; _Pitch = (int)Pitch;
/* Don't allow forces bigger than 1g */ /* Don't allow forces bigger than 1g */
if (x < -1.0) x = -1.0; else if (x > 1.0) x = 1.0; if (x < -1.0) x = -1.0; else if (x > 1.0) x = 1.0;
if (y < -1.0) y = -1.0; else if (y > 1.0) y = 1.0; if (y < -1.0) y = -1.0; else if (y > 1.0) y = 1.0;
if (z < -1.0) z = -1.0; else if (z > 1.0) z = 1.0; if (z < -1.0) z = -1.0; else if (z > 1.0) z = 1.0;
Roll = InputCommon::Rad2Deg(atan2(x, z)); Roll = InputCommon::Rad2Deg(atan2(x, z));
Pitch = InputCommon::Rad2Deg(atan2(y, z)); Pitch = InputCommon::Rad2Deg(atan2(y, z));
_RollAdj = (int)Roll; _RollAdj = (int)Roll;
_PitchAdj = (int)Pitch; _PitchAdj = (int)Pitch;
} }
//****************************************************************************** //******************************************************************************
// IR data functions // IR data functions
//****************************************************************************** //******************************************************************************
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Calculate dot positions from the basic 10 byte IR data // Calculate dot positions from the basic 10 byte IR data
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void IRData2DotsBasic(u8 *Data) void IRData2DotsBasic(u8 *Data)
{ {
struct SDot* Dot = g_Wm.IR.Dot; struct SDot* Dot = g_Wm.IR.Dot;
Dot[0].Rx = 1023 - (Data[0] | ((Data[2] & 0x30) << 4)); Dot[0].Rx = 1023 - (Data[0] | ((Data[2] & 0x30) << 4));
Dot[0].Ry = Data[1] | ((Data[2] & 0xc0) << 2); Dot[0].Ry = Data[1] | ((Data[2] & 0xc0) << 2);
Dot[1].Rx = 1023 - (Data[3] | ((Data[2] & 0x03) << 8)); Dot[1].Rx = 1023 - (Data[3] | ((Data[2] & 0x03) << 8));
Dot[1].Ry = Data[4] | ((Data[2] & 0x0c) << 6); Dot[1].Ry = Data[4] | ((Data[2] & 0x0c) << 6);
Dot[2].Rx = 1023 - (Data[5] | ((Data[7] & 0x30) << 4)); Dot[2].Rx = 1023 - (Data[5] | ((Data[7] & 0x30) << 4));
Dot[2].Ry = Data[6] | ((Data[7] & 0xc0) << 2); Dot[2].Ry = Data[6] | ((Data[7] & 0xc0) << 2);
Dot[3].Rx = 1023 - (Data[8] | ((Data[7] & 0x03) << 8)); Dot[3].Rx = 1023 - (Data[8] | ((Data[7] & 0x03) << 8));
Dot[3].Ry = Data[9] | ((Data[7] & 0x0c) << 6); Dot[3].Ry = Data[9] | ((Data[7] & 0x0c) << 6);
/* set each IR spot to visible if spot is in range */ /* set each IR spot to visible if spot is in range */
for (int i = 0; i < 4; ++i) for (int i = 0; i < 4; ++i)
{ {
if (Dot[i].Ry == 1023) if (Dot[i].Ry == 1023)
{ {
Dot[i].Visible = 0; Dot[i].Visible = 0;
} }
else else
{ {
Dot[i].Visible = 1; Dot[i].Visible = 1;
Dot[i].Size = 0; /* since we don't know the size, set it as 0 */ Dot[i].Size = 0; /* since we don't know the size, set it as 0 */
} }
// For now we let our virtual resolution be the same as the default one // For now we let our virtual resolution be the same as the default one
Dot[i].X = Dot[i].Rx; Dot[i].Y = Dot[i].Ry; Dot[i].X = Dot[i].Rx; Dot[i].Y = Dot[i].Ry;
} }
// Calculate the other values // Calculate the other values
ReorderIRDots(); ReorderIRDots();
IRData2Distance(); IRData2Distance();
} }
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Calculate dot positions from the extented 12 byte IR data // Calculate dot positions from the extented 12 byte IR data
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void IRData2Dots(u8 *Data) void IRData2Dots(u8 *Data)
{ {
struct SDot* Dot = g_Wm.IR.Dot; struct SDot* Dot = g_Wm.IR.Dot;
for (int i = 0; i < 4; ++i) for (int i = 0; i < 4; ++i)
{ {
//Console::Print("Rx: %i\n", Dot[i].Rx); //Console::Print("Rx: %i\n", Dot[i].Rx);
Dot[i].Rx = 1023 - (Data[3*i] | ((Data[(3*i)+2] & 0x30) << 4)); Dot[i].Rx = 1023 - (Data[3*i] | ((Data[(3*i)+2] & 0x30) << 4));
Dot[i].Ry = Data[(3*i)+1] | ((Data[(3*i)+2] & 0xc0) << 2); Dot[i].Ry = Data[(3*i)+1] | ((Data[(3*i)+2] & 0xc0) << 2);
Dot[i].Size = Data[(3*i)+2] & 0x0f; Dot[i].Size = Data[(3*i)+2] & 0x0f;
/* if in range set to visible */ /* if in range set to visible */
if (Dot[i].Ry == 1023) if (Dot[i].Ry == 1023)
Dot[i].Visible = false; Dot[i].Visible = false;
else else
Dot[i].Visible = true; Dot[i].Visible = true;
//Console::Print("Rx: %i\n", Dot[i].Rx); //Console::Print("Rx: %i\n", Dot[i].Rx);
// For now we let our virtual resolution be the same as the default one // For now we let our virtual resolution be the same as the default one
Dot[i].X = Dot[i].Rx; Dot[i].Y = Dot[i].Ry; Dot[i].X = Dot[i].Rx; Dot[i].Y = Dot[i].Ry;
} }
// Calculate the other values // Calculate the other values
ReorderIRDots(); ReorderIRDots();
IRData2Distance(); IRData2Distance();
} }
//////////////////////////////// ////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Reorder the IR dots according to their x-axis value // Reorder the IR dots according to their x-axis value
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void ReorderIRDots() void ReorderIRDots()
{ {
// Create a shortcut // Create a shortcut
struct SDot* Dot = g_Wm.IR.Dot; struct SDot* Dot = g_Wm.IR.Dot;
// Variables // Variables
int i, j, order; int i, j, order;
// Reset the dot ordering to zero // Reset the dot ordering to zero
for (i = 0; i < 4; ++i) for (i = 0; i < 4; ++i)
Dot[i].Order = 0; Dot[i].Order = 0;
for (order = 1; order < 5; ++order) for (order = 1; order < 5; ++order)
{ {
i = 0; i = 0;
// //
for (; !Dot[i].Visible || Dot[i].Order; ++i) for (; !Dot[i].Visible || Dot[i].Order; ++i)
if (i > 4) return; if (i > 4) return;
// //
for (j = 0; j < 4; ++j) for (j = 0; j < 4; ++j)
{ {
if (Dot[j].Visible && !Dot[j].Order && (Dot[j].X < Dot[i].X)) if (Dot[j].Visible && !Dot[j].Order && (Dot[j].X < Dot[i].X))
i = j; i = j;
} }
Dot[i].Order = order; Dot[i].Order = order;
} }
} }
//////////////////////////////// ////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Calculate dot positions from the extented 12 byte IR data // Calculate dot positions from the extented 12 byte IR data
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void IRData2Distance() void IRData2Distance()
{ {
// Create a shortcut // Create a shortcut
struct SDot* Dot = g_Wm.IR.Dot; struct SDot* Dot = g_Wm.IR.Dot;
// Make these ones global // Make these ones global
int i1, i2; int i1, i2;
for (i1 = 0; i1 < 4; ++i1) for (i1 = 0; i1 < 4; ++i1)
if (Dot[i1].Visible) break; if (Dot[i1].Visible) break;
// Only one dot was visible, we can not calculate the distance // Only one dot was visible, we can not calculate the distance
if (i1 == 4) { g_Wm.IR.Distance = 0; return; } if (i1 == 4) { g_Wm.IR.Distance = 0; return; }
// Look at the next dot // Look at the next dot
for (i2 = i1 + 1; i2 < 4; ++i2) for (i2 = i1 + 1; i2 < 4; ++i2)
if (Dot[i2].Visible) break; if (Dot[i2].Visible) break;
// Only one dot was visible, we can not calculate the distance // Only one dot was visible, we can not calculate the distance
if (i2 == 4) { g_Wm.IR.Distance = 0; return; } if (i2 == 4) { g_Wm.IR.Distance = 0; return; }
/* For the emulated Wiimote the y distance is always zero so then the distance is the /* For the emulated Wiimote the y distance is always zero so then the distance is the
simple distance between the x dots, i.e. the sensor bar width */ simple distance between the x dots, i.e. the sensor bar width */
int xd = Dot[i2].X - Dot[i1].X; int xd = Dot[i2].X - Dot[i1].X;
int yd = Dot[i2].Y - Dot[i1].Y; int yd = Dot[i2].Y - Dot[i1].Y;
// Save the distance // Save the distance
g_Wm.IR.Distance = (int)sqrt((float)(xd*xd) + (float)(yd*yd)); g_Wm.IR.Distance = (int)sqrt((float)(xd*xd) + (float)(yd*yd));
} }
//////////////////////////////// ////////////////////////////////
} // WiiMoteEmu } // WiiMoteEmu

View File

@ -1,194 +1,194 @@
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2008 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0. // the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details. // GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program. // A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/ // If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at // Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Includes // Includes
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#include <vector> #include <vector>
#include <string> #include <string>
#include "../../../Core/InputCommon/Src/SDL.h" // Core #include "../../../Core/InputCommon/Src/SDL.h" // Core
#include "../../../Core/InputCommon/Src/XInput.h" #include "../../../Core/InputCommon/Src/XInput.h"
#include "Common.h" // Common #include "Common.h" // Common
#include "StringUtil.h" // for ArrayToString() #include "StringUtil.h" // for ArrayToString()
#include "IniFile.h" #include "IniFile.h"
#include "pluginspecs_wiimote.h" #include "pluginspecs_wiimote.h"
#include "EmuDefinitions.h" // Local #include "EmuDefinitions.h" // Local
#include "main.h" #include "main.h"
#include "wiimote_hid.h" #include "wiimote_hid.h"
#include "EmuSubroutines.h" #include "EmuSubroutines.h"
#include "EmuMain.h" #include "EmuMain.h"
#include "Encryption.h" // for extension encryption #include "Encryption.h" // for extension encryption
#include "Logging.h" // for startConsoleWin, Console::Print, GetConsoleHwnd #include "Logging.h" // for startConsoleWin, Console::Print, GetConsoleHwnd
#include "Config.h" // for g_Config #include "Config.h" // for g_Config
//////////////////////////////////// ////////////////////////////////////
extern SWiimoteInitialize g_WiimoteInitialize; extern SWiimoteInitialize g_WiimoteInitialize;
namespace WiiMoteEmu namespace WiiMoteEmu
{ {
// =================================================== // ===================================================
// Fill joyinfo with the current connected devices // Fill joyinfo with the current connected devices
// ---------------- // ----------------
bool Search_Devices(std::vector<InputCommon::CONTROLLER_INFO> &_joyinfo, int &_NumPads, int &_NumGoodPads) bool Search_Devices(std::vector<InputCommon::CONTROLLER_INFO> &_joyinfo, int &_NumPads, int &_NumGoodPads)
{ {
bool Success = InputCommon::SearchDevices(_joyinfo, _NumPads, _NumGoodPads); bool Success = InputCommon::SearchDevices(_joyinfo, _NumPads, _NumGoodPads);
// Warn the user if no gamepads are detected // Warn the user if no gamepads are detected
if (_NumGoodPads == 0 && g_EmulatorRunning) if (_NumGoodPads == 0 && g_EmulatorRunning)
{ {
//PanicAlert("nJoy: No Gamepad Detected"); //PanicAlert("nJoy: No Gamepad Detected");
//return false; //return false;
} }
// Load PadMapping[] etc // Load PadMapping[] etc
g_Config.Load(); g_Config.Load();
// Update the PadState[].joy handle // Update the PadState[].joy handle
for (int i = 0; i < 1; i++) for (int i = 0; i < 1; i++)
{ {
if (PadMapping[i].enabled && joyinfo.size() > PadMapping[i].ID) if (PadMapping[i].enabled && joyinfo.size() > PadMapping[i].ID)
if(joyinfo.at(PadMapping[i].ID).Good) if(joyinfo.at(PadMapping[i].ID).Good)
PadState[i].joy = SDL_JoystickOpen(PadMapping[i].ID); PadState[i].joy = SDL_JoystickOpen(PadMapping[i].ID);
} }
return Success; return Success;
} }
// =========================== // ===========================
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Return adjusted input values // Return adjusted input values
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void PadStateAdjustments(int &Lx, int &Ly, int &Rx, int &Ry, int &Tl, int &Tr) void PadStateAdjustments(int &Lx, int &Ly, int &Rx, int &Ry, int &Tl, int &Tr)
{ {
// This has to be changed if multiple Wiimotes are to be supported later // This has to be changed if multiple Wiimotes are to be supported later
const int Page = 0; const int Page = 0;
// Copy all states to a local variable // Copy all states to a local variable
Lx = PadState[Page].Axis.Lx; Lx = PadState[Page].Axis.Lx;
Ly = PadState[Page].Axis.Ly; Ly = PadState[Page].Axis.Ly;
Rx = PadState[Page].Axis.Rx; Rx = PadState[Page].Axis.Rx;
Ry = PadState[Page].Axis.Ry; Ry = PadState[Page].Axis.Ry;
Tl = PadState[Page].Axis.Tl; Tl = PadState[Page].Axis.Tl;
Tr = PadState[Page].Axis.Tr; Tr = PadState[Page].Axis.Tr;
// Check the circle to square option // Check the circle to square option
if(PadMapping[Page].bCircle2Square) if(PadMapping[Page].bCircle2Square)
{ {
std::vector<int> main_xy = InputCommon::Square2Circle(Lx, Ly, Page, PadMapping[Page].SDiagonal, true); std::vector<int> main_xy = InputCommon::Square2Circle(Lx, Ly, Page, PadMapping[Page].SDiagonal, true);
Lx = main_xy.at(0); Lx = main_xy.at(0);
Ly = main_xy.at(1); Ly = main_xy.at(1);
} }
// Dead zone adjustment // Dead zone adjustment
float DeadZoneLeft = (float)PadMapping[Page].DeadZoneL / 100.0f; float DeadZoneLeft = (float)PadMapping[Page].DeadZoneL / 100.0f;
float DeadZoneRight = (float)PadMapping[Page].DeadZoneR / 100.0f; float DeadZoneRight = (float)PadMapping[Page].DeadZoneR / 100.0f;
if (InputCommon::IsDeadZone(DeadZoneLeft, Lx, Ly)) if (InputCommon::IsDeadZone(DeadZoneLeft, Lx, Ly))
{ {
Lx = 0; Lx = 0;
Ly = 0; Ly = 0;
} }
if (InputCommon::IsDeadZone(DeadZoneRight, Rx, Ry)) if (InputCommon::IsDeadZone(DeadZoneRight, Rx, Ry))
{ {
Rx = 0; Rx = 0;
Ry = 0; Ry = 0;
} }
// Downsize the values from 0x8000 to 0x80 // Downsize the values from 0x8000 to 0x80
Lx = InputCommon::Pad_Convert(Lx); Lx = InputCommon::Pad_Convert(Lx);
Ly = InputCommon::Pad_Convert(Ly); Ly = InputCommon::Pad_Convert(Ly);
Rx = InputCommon::Pad_Convert(Rx); Rx = InputCommon::Pad_Convert(Rx);
Ry = InputCommon::Pad_Convert(Ry); Ry = InputCommon::Pad_Convert(Ry);
// The XInput range is already 0 to 0x80 // The XInput range is already 0 to 0x80
if (PadMapping[Page].triggertype == InputCommon::CTL_TRIGGER_SDL) if (PadMapping[Page].triggertype == InputCommon::CTL_TRIGGER_SDL)
{ {
Tl = InputCommon::Pad_Convert(PadState[Page].Axis.Tl); Tl = InputCommon::Pad_Convert(PadState[Page].Axis.Tl);
Tr = InputCommon::Pad_Convert(PadState[Page].Axis.Tr); Tr = InputCommon::Pad_Convert(PadState[Page].Axis.Tr);
} }
} }
//////////////////////////////////////////// ////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Request joystick state // Request joystick state
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/* Called from: PAD_GetStatus() /* Called from: PAD_GetStatus()
Input: The virtual device 0, 1, 2 or 3 Input: The virtual device 0, 1, 2 or 3
Function: Updates the PadState struct with the current pad status. The input value "controller" is Function: Updates the PadState struct with the current pad status. The input value "controller" is
for a virtual controller 0 to 3. */ for a virtual controller 0 to 3. */
void GetJoyState(InputCommon::CONTROLLER_STATE_NEW &_PadState, InputCommon::CONTROLLER_MAPPING_NEW _PadMapping, int controller, int NumButtons) void GetJoyState(InputCommon::CONTROLLER_STATE_NEW &_PadState, InputCommon::CONTROLLER_MAPPING_NEW _PadMapping, int controller, int NumButtons)
{ {
// Return if we have no pads // Return if we have no pads
if (NumGoodPads == 0) return; if (NumGoodPads == 0) return;
// Update the gamepad status // Update the gamepad status
SDL_JoystickUpdate(); SDL_JoystickUpdate();
// Update axis states. It doesn't hurt much if we happen to ask for nonexisting axises here. // Update axis states. It doesn't hurt much if we happen to ask for nonexisting axises here.
_PadState.Axis.Lx = SDL_JoystickGetAxis(_PadState.joy, _PadMapping.Axis.Lx); _PadState.Axis.Lx = SDL_JoystickGetAxis(_PadState.joy, _PadMapping.Axis.Lx);
_PadState.Axis.Ly = SDL_JoystickGetAxis(_PadState.joy, _PadMapping.Axis.Ly); _PadState.Axis.Ly = SDL_JoystickGetAxis(_PadState.joy, _PadMapping.Axis.Ly);
_PadState.Axis.Rx = SDL_JoystickGetAxis(_PadState.joy, _PadMapping.Axis.Rx); _PadState.Axis.Rx = SDL_JoystickGetAxis(_PadState.joy, _PadMapping.Axis.Rx);
_PadState.Axis.Ry = SDL_JoystickGetAxis(_PadState.joy, _PadMapping.Axis.Ry); _PadState.Axis.Ry = SDL_JoystickGetAxis(_PadState.joy, _PadMapping.Axis.Ry);
// Update the analog trigger axis values // Update the analog trigger axis values
#ifdef _WIN32 #ifdef _WIN32
if (_PadMapping.triggertype == InputCommon::CTL_TRIGGER_SDL) if (_PadMapping.triggertype == InputCommon::CTL_TRIGGER_SDL)
{ {
#endif #endif
// If we are using SDL analog triggers the buttons have to be mapped as 1000 or up, otherwise they are not used // If we are using SDL analog triggers the buttons have to be mapped as 1000 or up, otherwise they are not used
// We must also check that we are not asking for a negative axis number because SDL_JoystickGetAxis() has // We must also check that we are not asking for a negative axis number because SDL_JoystickGetAxis() has
// no good way of handling that // no good way of handling that
if ((_PadMapping.Axis.Tl - 1000) >= 0) _PadState.Axis.Tl = SDL_JoystickGetAxis(_PadState.joy, _PadMapping.Axis.Tl - 1000); if ((_PadMapping.Axis.Tl - 1000) >= 0) _PadState.Axis.Tl = SDL_JoystickGetAxis(_PadState.joy, _PadMapping.Axis.Tl - 1000);
if ((_PadMapping.Axis.Tr - 1000) >= 0) _PadState.Axis.Tr = SDL_JoystickGetAxis(_PadState.joy, _PadMapping.Axis.Tr - 1000); if ((_PadMapping.Axis.Tr - 1000) >= 0) _PadState.Axis.Tr = SDL_JoystickGetAxis(_PadState.joy, _PadMapping.Axis.Tr - 1000);
#ifdef _WIN32 #ifdef _WIN32
} }
else else
{ {
_PadState.Axis.Tl = XInput::GetXI(0, _PadMapping.Axis.Tl - 1000); _PadState.Axis.Tl = XInput::GetXI(0, _PadMapping.Axis.Tl - 1000);
_PadState.Axis.Tr = XInput::GetXI(0, _PadMapping.Axis.Tr - 1000); _PadState.Axis.Tr = XInput::GetXI(0, _PadMapping.Axis.Tr - 1000);
} }
#endif #endif
/* Debugging /* Debugging
Console::ClearScreen(); Console::ClearScreen();
Console::Print( Console::Print(
"Controller and handle: %i %i\n" "Controller and handle: %i %i\n"
"Triggers:%i %i %i %i %i\n" "Triggers:%i %i %i %i %i\n"
"Analog:%06i %06i \n", "Analog:%06i %06i \n",
controller, (int)_PadState.joy, controller, (int)_PadState.joy,
_PadMapping.triggertype, _PadMapping.triggertype,
_PadMapping.Axis.Tl, _PadMapping.Axis.Tr, _PadMapping.Axis.Tl, _PadMapping.Axis.Tr,
_PadState.Axis.Tl, _PadState.Axis.Tr, _PadState.Axis.Tl, _PadState.Axis.Tr,
_PadState.Axis.Lx, _PadState.Axis.Ly _PadState.Axis.Lx, _PadState.Axis.Ly
);*/ );*/
} }
//////////////////////////////////////////// ////////////////////////////////////////////
} // end of namespace WiiMoteEmu } // end of namespace WiiMoteEmu

View File

@ -1,119 +1,119 @@
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2008 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0. // the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details. // GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program. // A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/ // If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at // Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Includes // Includes
// ------------- // -------------
#include <string> #include <string>
#include <stdio.h> #include <stdio.h>
#ifdef _WIN32 #ifdef _WIN32
#include <windows.h> #include <windows.h>
#endif #endif
#include "StringUtil.h" #include "StringUtil.h"
#define HAVE_WX 1 #define HAVE_WX 1
#if defined(HAVE_WX) && HAVE_WX // wxWidgets #if defined(HAVE_WX) && HAVE_WX // wxWidgets
#include <wx/datetime.h> // for the timestamps #include <wx/datetime.h> // for the timestamps
#endif #endif
/////////////////////////// ///////////////////////////
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Settings // Settings
// ------------- // -------------
// On and off // On and off
bool g_consoleEnable = true; bool g_consoleEnable = true;
bool gSaveFile = true; bool gSaveFile = true;
#define DEBUG_WIIMOTE // On or off #define DEBUG_WIIMOTE // On or off
const int nFiles = 1; const int nFiles = 1;
// Create handles // Create handles
#ifdef DEBUG_WIIMOTE #ifdef DEBUG_WIIMOTE
FILE* __fStdOut[nFiles]; FILE* __fStdOut[nFiles];
#endif #endif
#ifdef _WIN32 #ifdef _WIN32
HANDLE __hStdOut = NULL; HANDLE __hStdOut = NULL;
#endif #endif
////////////////////////////// //////////////////////////////
// ======================================================================================= // =======================================================================================
/* Get Timestamp */ /* Get Timestamp */
// ------------- // -------------
std::string Tm(bool Ms) std::string Tm(bool Ms)
{ {
#if defined(HAVE_WX) && HAVE_WX #if defined(HAVE_WX) && HAVE_WX
std::string Tmp; std::string Tmp;
if(Ms) if(Ms)
{ {
wxDateTime datetime = wxDateTime::UNow(); // Get timestamp wxDateTime datetime = wxDateTime::UNow(); // Get timestamp
Tmp = StringFromFormat("%02i:%02i:%03i", Tmp = StringFromFormat("%02i:%02i:%03i",
datetime.GetMinute(), datetime.GetSecond(), datetime.GetMillisecond()); datetime.GetMinute(), datetime.GetSecond(), datetime.GetMillisecond());
} }
else else
{ {
wxDateTime datetime = wxDateTime::Now(); // Get timestamp wxDateTime datetime = wxDateTime::Now(); // Get timestamp
Tmp = StringFromFormat("%02i:%02i", Tmp = StringFromFormat("%02i:%02i",
datetime.GetMinute(), datetime.GetSecond()); datetime.GetMinute(), datetime.GetSecond());
} }
return Tmp; return Tmp;
#else #else
std::string Tmp = ""; std::string Tmp = "";
return Tmp; return Tmp;
#endif #endif
} }
// =========================== // ===========================
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
// File printf function // File printf function
// --------------- // ---------------
int PrintFile(int a, char *fmt, ...) int PrintFile(int a, char *fmt, ...)
{ {
#if defined(DEBUG_WIIMOTE) && defined(_WIN32) #if defined(DEBUG_WIIMOTE) && defined(_WIN32)
if(gSaveFile) if(gSaveFile)
{ {
char s[500]; // WARNING: mind this value char s[500]; // WARNING: mind this value
va_list argptr; va_list argptr;
int cnt; int cnt;
va_start(argptr, fmt); va_start(argptr, fmt);
cnt = vsnprintf(s, 500, fmt, argptr); // remember to update this value to cnt = vsnprintf(s, 500, fmt, argptr); // remember to update this value to
va_end(argptr); va_end(argptr);
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
if(__fStdOut[a]) // TODO: make this work, we have to set all default values to NULL if(__fStdOut[a]) // TODO: make this work, we have to set all default values to NULL
//to make it work //to make it work
fprintf(__fStdOut[a], s); fprintf(__fStdOut[a], s);
fflush(__fStdOut[0]); // Write file now, don't wait fflush(__fStdOut[0]); // Write file now, don't wait
// ------------- // -------------
return(cnt); return(cnt);
} }
else else
{ {
return 0; return 0;
} }
#else #else
return 0; return 0;
#endif #endif
} }

View File

@ -1,386 +1,386 @@
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2008 Dolphin Project.
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0. // the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details. // GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program. // A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/ // If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at // Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Includes // Includes
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#include <iostream> // System #include <iostream> // System
#include "wiiuse.h" // Externals #include "wiiuse.h" // Externals
#include "ConsoleWindow.h" // Common #include "ConsoleWindow.h" // Common
#include "StringUtil.h" #include "StringUtil.h"
#include "Timer.h" #include "Timer.h"
#include "pluginspecs_wiimote.h" #include "pluginspecs_wiimote.h"
#include "wiimote_real.h" // Local #include "wiimote_real.h" // Local
#include "wiimote_hid.h" #include "wiimote_hid.h"
#include "EmuDefinitions.h" #include "EmuDefinitions.h"
#include "EmuMain.h" #include "EmuMain.h"
#include "main.h" #include "main.h"
#if defined(HAVE_WX) && HAVE_WX #if defined(HAVE_WX) && HAVE_WX
#include "ConfigDlg.h" #include "ConfigDlg.h"
#endif #endif
#include "Config.h" #include "Config.h"
//////////////////////////////////////// ////////////////////////////////////////
namespace WiiMoteReal namespace WiiMoteReal
{ {
int GetReportSize(struct wiimote_t* wm) int GetReportSize(struct wiimote_t* wm)
{ {
// The report size is 0x33 = 18, 0x37 = 22 withouth the leading (a1) byte // The report size is 0x33 = 18, 0x37 = 22 withouth the leading (a1) byte
if(WIIUSE_USING_EXP(wm)) return 22; else return 18; if(WIIUSE_USING_EXP(wm)) return 22; else return 18;
} }
void handle_ctrl_status(struct wiimote_t* wm) void handle_ctrl_status(struct wiimote_t* wm)
{ {
Console::Print("\n\n--- CONTROLLER STATUS [wiimote id %i] ---\n", wm->unid); Console::Print("\n\n--- CONTROLLER STATUS [wiimote id %i] ---\n", wm->unid);
Console::Print("attachment: %i\n", wm->exp.type); Console::Print("attachment: %i\n", wm->exp.type);
Console::Print("speaker: %i\n", WIIUSE_USING_SPEAKER(wm)); Console::Print("speaker: %i\n", WIIUSE_USING_SPEAKER(wm));
Console::Print("ir: %i\n", WIIUSE_USING_IR(wm)); Console::Print("ir: %i\n", WIIUSE_USING_IR(wm));
Console::Print("leds: %i %i %i %i\n", WIIUSE_IS_LED_SET(wm, 1), WIIUSE_IS_LED_SET(wm, 2), WIIUSE_IS_LED_SET(wm, 3), WIIUSE_IS_LED_SET(wm, 4)); Console::Print("leds: %i %i %i %i\n", WIIUSE_IS_LED_SET(wm, 1), WIIUSE_IS_LED_SET(wm, 2), WIIUSE_IS_LED_SET(wm, 3), WIIUSE_IS_LED_SET(wm, 4));
Console::Print("battery: %f %%\n", wm->battery_level); Console::Print("battery: %f %%\n", wm->battery_level);
} }
bool IRDataOK(struct wiimote_t* wm) bool IRDataOK(struct wiimote_t* wm)
{ {
//Console::Print("IRDataOK: "); //Console::Print("IRDataOK: ");
// The report size is 0x33 = 18, 0x37 = 22 withouth the leading (a1) byte // The report size is 0x33 = 18, 0x37 = 22 withouth the leading (a1) byte
int ReportSize = GetReportSize(wm); int ReportSize = GetReportSize(wm);
for(int i = 0; i < ReportSize; i++) for(int i = 0; i < ReportSize; i++)
{ {
//Console::Print("%02x ", wm->event_buf[i]); //Console::Print("%02x ", wm->event_buf[i]);
if (wm->event_buf[i] > 0) if (wm->event_buf[i] > 0)
{ {
//Console::Print("\n"); //Console::Print("\n");
return true; return true;
} }
} }
return false; return false;
} }
void handle_event(struct wiimote_t* wm) void handle_event(struct wiimote_t* wm)
{ {
//Console::Print("\n\n--- EVENT [id %i] ---\n", wm->unid); //Console::Print("\n\n--- EVENT [id %i] ---\n", wm->unid);
// if a button is pressed, report it // if a button is pressed, report it
if (IS_PRESSED(wm, WIIMOTE_BUTTON_A)) Console::Print("A pressed\n"); if (IS_PRESSED(wm, WIIMOTE_BUTTON_A)) Console::Print("A pressed\n");
if (IS_PRESSED(wm, WIIMOTE_BUTTON_B)) Console::Print("B pressed\n"); if (IS_PRESSED(wm, WIIMOTE_BUTTON_B)) Console::Print("B pressed\n");
if (IS_PRESSED(wm, WIIMOTE_BUTTON_UP)) Console::Print("UP pressed\n"); if (IS_PRESSED(wm, WIIMOTE_BUTTON_UP)) Console::Print("UP pressed\n");
if (IS_PRESSED(wm, WIIMOTE_BUTTON_DOWN)) Console::Print("DOWN pressed\n"); if (IS_PRESSED(wm, WIIMOTE_BUTTON_DOWN)) Console::Print("DOWN pressed\n");
if (IS_PRESSED(wm, WIIMOTE_BUTTON_LEFT)) Console::Print("LEFT pressed\n"); if (IS_PRESSED(wm, WIIMOTE_BUTTON_LEFT)) Console::Print("LEFT pressed\n");
if (IS_PRESSED(wm, WIIMOTE_BUTTON_RIGHT)) Console::Print("RIGHT pressed\n"); if (IS_PRESSED(wm, WIIMOTE_BUTTON_RIGHT)) Console::Print("RIGHT pressed\n");
if (IS_PRESSED(wm, WIIMOTE_BUTTON_MINUS)) Console::Print("MINUS pressed\n"); if (IS_PRESSED(wm, WIIMOTE_BUTTON_MINUS)) Console::Print("MINUS pressed\n");
if (IS_PRESSED(wm, WIIMOTE_BUTTON_PLUS)) Console::Print("PLUS pressed\n"); if (IS_PRESSED(wm, WIIMOTE_BUTTON_PLUS)) Console::Print("PLUS pressed\n");
if (IS_PRESSED(wm, WIIMOTE_BUTTON_ONE)) Console::Print("ONE pressed\n"); if (IS_PRESSED(wm, WIIMOTE_BUTTON_ONE)) Console::Print("ONE pressed\n");
//if (IS_PRESSED(wm, WIIMOTE_BUTTON_ONE)) g_Run = false; //if (IS_PRESSED(wm, WIIMOTE_BUTTON_ONE)) g_Run = false;
if (IS_PRESSED(wm, WIIMOTE_BUTTON_TWO)) Console::Print("TWO pressed\n"); if (IS_PRESSED(wm, WIIMOTE_BUTTON_TWO)) Console::Print("TWO pressed\n");
if (IS_PRESSED(wm, WIIMOTE_BUTTON_HOME)) Console::Print("HOME pressed\n"); if (IS_PRESSED(wm, WIIMOTE_BUTTON_HOME)) Console::Print("HOME pressed\n");
// Pressing minus will tell the wiimote we are no longer interested in movement. // Pressing minus will tell the wiimote we are no longer interested in movement.
// This is useful because it saves battery power. // This is useful because it saves battery power.
if (IS_JUST_PRESSED(wm, WIIMOTE_BUTTON_MINUS)) if (IS_JUST_PRESSED(wm, WIIMOTE_BUTTON_MINUS))
{ {
wiiuse_motion_sensing(wm, 0); wiiuse_motion_sensing(wm, 0);
wiiuse_set_ir(wm, 0); wiiuse_set_ir(wm, 0);
g_MotionSensing = false; g_MotionSensing = false;
} }
// Turn aceelerometer and IR reporting on, there is some kind of bug that prevents us from turing these on // Turn aceelerometer and IR reporting on, there is some kind of bug that prevents us from turing these on
// directly after each other, so we have to wait for another wiiuse_poll() this way // directly after each other, so we have to wait for another wiiuse_poll() this way
if (IS_JUST_PRESSED(wm, WIIMOTE_BUTTON_PLUS)) if (IS_JUST_PRESSED(wm, WIIMOTE_BUTTON_PLUS))
{ {
wiiuse_motion_sensing(wm, 1); wiiuse_motion_sensing(wm, 1);
g_MotionSensing = true; g_MotionSensing = true;
} }
// Turn IR reporting on // Turn IR reporting on
if (g_MotionSensing && !WIIUSE_USING_IR(wm)) if (g_MotionSensing && !WIIUSE_USING_IR(wm))
wiiuse_set_ir(wm, 1); wiiuse_set_ir(wm, 1);
// Print battery status // Print battery status
#if defined(HAVE_WX) && HAVE_WX #if defined(HAVE_WX) && HAVE_WX
if(frame && g_Config.bUpdateRealWiimote) if(frame && g_Config.bUpdateRealWiimote)
frame->m_GaugeBattery->SetValue((int)floor((wm->battery_level * 100) + 0.5)); frame->m_GaugeBattery->SetValue((int)floor((wm->battery_level * 100) + 0.5));
#endif #endif
// Create shortcut to the nunchuck // Create shortcut to the nunchuck
struct nunchuk_t* nc = NULL; struct nunchuk_t* nc = NULL;
if (wm->exp.type == EXP_NUNCHUK) if (wm->exp.type == EXP_NUNCHUK)
nc = (nunchuk_t*)&wm->exp.nunchuk; nc = (nunchuk_t*)&wm->exp.nunchuk;
// If the accelerometer is turned on then print angles // If the accelerometer is turned on then print angles
if (WIIUSE_USING_ACC(wm) && WIIUSE_USING_IR(wm)) if (WIIUSE_USING_ACC(wm) && WIIUSE_USING_IR(wm))
{ {
std::string Tmp; std::string Tmp;
Tmp += StringFromFormat("Roll: %2.1f ", wm->orient.roll); Tmp += StringFromFormat("Roll: %2.1f ", wm->orient.roll);
Tmp += StringFromFormat("Pitch: %2.1f ", wm->orient.pitch); Tmp += StringFromFormat("Pitch: %2.1f ", wm->orient.pitch);
Tmp += StringFromFormat("Battery: %1.2f\n", wm->battery_level); Tmp += StringFromFormat("Battery: %1.2f\n", wm->battery_level);
Tmp += StringFromFormat("G-Force x, y, z: %1.2f %1.2f %1.2f\n", wm->gforce.x, wm->gforce.y, wm->gforce.z); Tmp += StringFromFormat("G-Force x, y, z: %1.2f %1.2f %1.2f\n", wm->gforce.x, wm->gforce.y, wm->gforce.z);
Tmp += StringFromFormat("Accel x, y, z: %03i %03i %03i\n", wm->accel.x, wm->accel.y, wm->accel.z); Tmp += StringFromFormat("Accel x, y, z: %03i %03i %03i\n", wm->accel.x, wm->accel.y, wm->accel.z);
// The report size is 0x33 = 18, 0x37 = 22 // The report size is 0x33 = 18, 0x37 = 22
int ReportSize; if(WIIUSE_USING_EXP(wm)) ReportSize = 22; else ReportSize = 18; int ReportSize; if(WIIUSE_USING_EXP(wm)) ReportSize = 22; else ReportSize = 18;
// wm->event_buf is cleared at the end of all wiiuse_poll(), so wm->event_buf will always be zero // wm->event_buf is cleared at the end of all wiiuse_poll(), so wm->event_buf will always be zero
// after that. To get the raw IR data we need to read the wiimote again. This seems to work most of the time, // after that. To get the raw IR data we need to read the wiimote again. This seems to work most of the time,
// it seems to fails with a regular interval about each tenth read. // it seems to fails with a regular interval about each tenth read.
if(wiiuse_io_read(wm)) if(wiiuse_io_read(wm))
{ {
// Check that it's not zero // Check that it's not zero
if (IRDataOK(wm)) memcpy(g_EventBuffer, wm->event_buf, ReportSize); if (IRDataOK(wm)) memcpy(g_EventBuffer, wm->event_buf, ReportSize);
} }
// Go through each of the 4 possible IR sources // Go through each of the 4 possible IR sources
for (int i = 0; i < 4; ++i) for (int i = 0; i < 4; ++i)
{ {
// Check if the source is visible // Check if the source is visible
if (wm->ir.dot[i].visible) if (wm->ir.dot[i].visible)
Tmp += StringFromFormat("IR source %i: (%u, %u)\n", i, wm->ir.dot[i].x, wm->ir.dot[i].y); Tmp += StringFromFormat("IR source %i: (%u, %u)\n", i, wm->ir.dot[i].x, wm->ir.dot[i].y);
} }
Tmp += "\n"; Tmp += "\n";
Tmp += StringFromFormat("IR cursor: (%u, %u)\n", wm->ir.x, wm->ir.y); Tmp += StringFromFormat("IR cursor: (%u, %u)\n", wm->ir.x, wm->ir.y);
Tmp += StringFromFormat("IR z distance: %f\n", wm->ir.z); Tmp += StringFromFormat("IR z distance: %f\n", wm->ir.z);
if(wm->exp.type == EXP_NUNCHUK) if(wm->exp.type == EXP_NUNCHUK)
{ {
Tmp += "\n"; Tmp += "\n";
Tmp += StringFromFormat("Nunchuck accel x, y, z: %03i %03i %03i\n", nc->accel.x, nc->accel.y, nc->accel.z); Tmp += StringFromFormat("Nunchuck accel x, y, z: %03i %03i %03i\n", nc->accel.x, nc->accel.y, nc->accel.z);
} }
//Tmp += "\n"; //Tmp += "\n";
//std::string TmpData = ArrayToString(g_EventBuffer, ReportSize, 0, 30); //std::string TmpData = ArrayToString(g_EventBuffer, ReportSize, 0, 30);
//Tmp += "Data: " + TmpData; //Tmp += "Data: " + TmpData;
//Console::ClearScreen(); //Console::ClearScreen();
//Console::Print("%s\n\n", Tmp.c_str()); //Console::Print("%s\n\n", Tmp.c_str());
#if defined(HAVE_WX) && HAVE_WX #if defined(HAVE_WX) && HAVE_WX
if(frame) if(frame)
{ {
// Produce adjusted accelerometer values // Produce adjusted accelerometer values
float _Gx = (float)(wm->accel.x - wm->accel_calib.cal_zero.x) / (float)wm->accel_calib.cal_g.x; float _Gx = (float)(wm->accel.x - wm->accel_calib.cal_zero.x) / (float)wm->accel_calib.cal_g.x;
float _Gy = (float)(wm->accel.y - wm->accel_calib.cal_zero.y) / (float)wm->accel_calib.cal_g.y; float _Gy = (float)(wm->accel.y - wm->accel_calib.cal_zero.y) / (float)wm->accel_calib.cal_g.y;
float _Gz = (float)(wm->accel.z - wm->accel_calib.cal_zero.z) / (float)wm->accel_calib.cal_g.z; float _Gz = (float)(wm->accel.z - wm->accel_calib.cal_zero.z) / (float)wm->accel_calib.cal_g.z;
// Conver the data to integers // Conver the data to integers
int Gx = (int)(_Gx * 100); int Gx = (int)(_Gx * 100);
int Gy = (int)(_Gy * 100); int Gy = (int)(_Gy * 100);
int Gz = (int)(_Gz * 100); int Gz = (int)(_Gz * 100);
// And for the Nunchuck // And for the Nunchuck
u8 AccelNX = 0, AccelNY = 0, AccelNZ = 0; u8 AccelNX = 0, AccelNY = 0, AccelNZ = 0;
if(wm->exp.type == EXP_NUNCHUK) if(wm->exp.type == EXP_NUNCHUK)
{ {
if((nc->accel.x + g_Config.iAccNunNeutralX) <= 255) AccelNX = nc->accel.x + g_Config.iAccNunNeutralX; if((nc->accel.x + g_Config.iAccNunNeutralX) <= 255) AccelNX = nc->accel.x + g_Config.iAccNunNeutralX;
if((nc->accel.y + g_Config.iAccNunNeutralY) <= 255) AccelNY = nc->accel.y + g_Config.iAccNunNeutralY; if((nc->accel.y + g_Config.iAccNunNeutralY) <= 255) AccelNY = nc->accel.y + g_Config.iAccNunNeutralY;
if((nc->accel.z + g_Config.iAccNunNeutralZ) <= 255) AccelNZ = nc->accel.z + g_Config.iAccNunNeutralZ; if((nc->accel.z + g_Config.iAccNunNeutralZ) <= 255) AccelNZ = nc->accel.z + g_Config.iAccNunNeutralZ;
} }
if(g_Config.bUpdateRealWiimote) if(g_Config.bUpdateRealWiimote)
{ {
// Update gauges // Update gauges
frame->m_GaugeRoll[0]->SetValue(wm->orient.roll + 180); frame->m_GaugeRoll[0]->SetValue(wm->orient.roll + 180);
frame->m_GaugeRoll[1]->SetValue(wm->orient.pitch + 180); frame->m_GaugeRoll[1]->SetValue(wm->orient.pitch + 180);
// Show g. forces between -3 and 3 // Show g. forces between -3 and 3
frame->m_GaugeGForce[0]->SetValue((int)floor((wm->gforce.x * 100) + 300.5)); frame->m_GaugeGForce[0]->SetValue((int)floor((wm->gforce.x * 100) + 300.5));
frame->m_GaugeGForce[1]->SetValue((int)floor((wm->gforce.y * 100) + 300.5)); frame->m_GaugeGForce[1]->SetValue((int)floor((wm->gforce.y * 100) + 300.5));
frame->m_GaugeGForce[2]->SetValue((int)floor((wm->gforce.z * 100) + 300.5)); frame->m_GaugeGForce[2]->SetValue((int)floor((wm->gforce.z * 100) + 300.5));
frame->m_GaugeAccel[0]->SetValue(wm->accel.x); frame->m_GaugeAccel[0]->SetValue(wm->accel.x);
frame->m_GaugeAccel[1]->SetValue(wm->accel.y); frame->m_GaugeAccel[1]->SetValue(wm->accel.y);
frame->m_GaugeAccel[2]->SetValue(wm->accel.z); frame->m_GaugeAccel[2]->SetValue(wm->accel.z);
frame->m_TextIR->SetLabel(wxString::Format( frame->m_TextIR->SetLabel(wxString::Format(
wxT("Cursor: %03u %03u\nDistance:%4.0f"), wm->ir.x, wm->ir.y, wm->ir.z)); wxT("Cursor: %03u %03u\nDistance:%4.0f"), wm->ir.x, wm->ir.y, wm->ir.z));
//frame->m_TextAccNeutralCurrent->SetLabel(wxString::Format( //frame->m_TextAccNeutralCurrent->SetLabel(wxString::Format(
// wxT("Current: %03u %03u %03u"), Gx, Gy, Gz)); // wxT("Current: %03u %03u %03u"), Gx, Gy, Gz));
if(frame->m_bRecording) if(frame->m_bRecording)
Console::Print("Wiiuse Recorded accel x, y, z: %03i %03i %03i\n", Gx, Gy, Gz); Console::Print("Wiiuse Recorded accel x, y, z: %03i %03i %03i\n", Gx, Gy, Gz);
//Console::Print("Wiiuse Recorded accel x, y, z: %02x %02x %02x\n", Gx, Gy, Gz); //Console::Print("Wiiuse Recorded accel x, y, z: %02x %02x %02x\n", Gx, Gy, Gz);
} }
// Send the data to be saved // Send the data to be saved
//const u8* data = (const u8*)wm->event_buf; //const u8* data = (const u8*)wm->event_buf;
frame->DoRecordMovement(Gx, Gy, Gz, (g_EventBuffer + 6), frame->DoRecordMovement(Gx, Gy, Gz, (g_EventBuffer + 6),
(WIIUSE_USING_EXP(wm) ? 10 : 12)); (WIIUSE_USING_EXP(wm) ? 10 : 12));
// Turn recording on and off // Turn recording on and off
if (IS_PRESSED(wm, WIIMOTE_BUTTON_A)) frame->DoRecordA(true); if (IS_PRESSED(wm, WIIMOTE_BUTTON_A)) frame->DoRecordA(true);
else frame->DoRecordA(false); else frame->DoRecordA(false);
// ------------------------------------ // ------------------------------------
// Show roll and pitch in the status box // Show roll and pitch in the status box
// -------------- // --------------
/* /*
if(!g_DebugData) if(!g_DebugData)
{ {
Console::ClearScreen(); Console::ClearScreen();
Console::Print("Roll:%03i Pitch:%03i\n", (int)wm->orient.roll, (int)wm->orient.pitch); Console::Print("Roll:%03i Pitch:%03i\n", (int)wm->orient.roll, (int)wm->orient.pitch);
} }
// Convert Roll and Pitch from 180 to 0x8000 // Convert Roll and Pitch from 180 to 0x8000
int Roll = (int)wm->orient.roll * (0x8000 / 180); int Roll = (int)wm->orient.roll * (0x8000 / 180);
int Pitch = (int)wm->orient.pitch * (0x8000 / 180); int Pitch = (int)wm->orient.pitch * (0x8000 / 180);
// Convert it to the box // Convert it to the box
frame->Convert2Box(Roll); frame->Convert2Box(Roll);
frame->Convert2Box(Pitch); frame->Convert2Box(Pitch);
// Show roll and pitch in the axis boxes // Show roll and pitch in the axis boxes
frame->m_bmpDotRightOut[0]->SetPosition(wxPoint(Roll, Pitch));*/ frame->m_bmpDotRightOut[0]->SetPosition(wxPoint(Roll, Pitch));*/
// --------------------- // ---------------------
} }
#endif #endif
} }
// Otherwise remove the values // Otherwise remove the values
else else
{ {
#if defined(HAVE_WX) && HAVE_WX #if defined(HAVE_WX) && HAVE_WX
if (frame) if (frame)
{ {
frame->m_GaugeRoll[0]->SetValue(0); frame->m_GaugeRoll[0]->SetValue(0);
frame->m_GaugeRoll[1]->SetValue(0); frame->m_GaugeRoll[1]->SetValue(0);
frame->m_GaugeGForce[0]->SetValue(0); frame->m_GaugeGForce[0]->SetValue(0);
frame->m_GaugeGForce[1]->SetValue(0); frame->m_GaugeGForce[1]->SetValue(0);
frame->m_GaugeGForce[2]->SetValue(0); frame->m_GaugeGForce[2]->SetValue(0);
frame->m_GaugeAccel[0]->SetValue(0); frame->m_GaugeAccel[0]->SetValue(0);
frame->m_GaugeAccel[1]->SetValue(0); frame->m_GaugeAccel[1]->SetValue(0);
frame->m_GaugeAccel[2]->SetValue(0); frame->m_GaugeAccel[2]->SetValue(0);
frame->m_TextIR->SetLabel(wxT("Cursor:\nDistance:")); frame->m_TextIR->SetLabel(wxT("Cursor:\nDistance:"));
} }
#endif #endif
} }
} }
void ReadWiimote() void ReadWiimote()
{ {
/* I place this outside wiiuse_poll() to produce a continous recording regardless of the status /* I place this outside wiiuse_poll() to produce a continous recording regardless of the status
change of the Wiimote, wiiuse_poll() is only true if the status has changed. However, this the change of the Wiimote, wiiuse_poll() is only true if the status has changed. However, this the
timing functions for recording playback that checks the time of the recording this should not timing functions for recording playback that checks the time of the recording this should not
be needed. But I still use it becase it seemed like state_changed() or the threshold values or be needed. But I still use it becase it seemed like state_changed() or the threshold values or
something else might fail so that only huge status changed were reported. */ something else might fail so that only huge status changed were reported. */
handle_event(g_WiiMotesFromWiiUse[0]); handle_event(g_WiiMotesFromWiiUse[0]);
// Declaration // Declaration
std::string Temp; std::string Temp;
/* Timeout for data reading. This is used in Initialize() to read the Eeprom, if we have not gotten /* Timeout for data reading. This is used in Initialize() to read the Eeprom, if we have not gotten
what we wanted in the WIIUSE_READ_DATA case we stop this loop and enable the regular what we wanted in the WIIUSE_READ_DATA case we stop this loop and enable the regular
wiiuse_io_read() and wiiuse_io_write() loop again. */ wiiuse_io_read() and wiiuse_io_write() loop again. */
if (g_RunTemporary) if (g_RunTemporary)
{ {
// The SecondsToWait holds if the update rate of wiiuse_poll() is kept at the default value of 10 ms // The SecondsToWait holds if the update rate of wiiuse_poll() is kept at the default value of 10 ms
static const int SecondsToWait = 2; static const int SecondsToWait = 2;
g_RunTemporaryCountdown++; g_RunTemporaryCountdown++;
if(g_RunTemporaryCountdown > (SecondsToWait * 100)) if(g_RunTemporaryCountdown > (SecondsToWait * 100))
{ {
g_RunTemporaryCountdown = 0; g_RunTemporaryCountdown = 0;
g_RunTemporary = false; g_RunTemporary = false;
} }
} }
// Read formatted Wiimote data // Read formatted Wiimote data
if (wiiuse_poll(g_WiiMotesFromWiiUse, MAX_WIIMOTES)) if (wiiuse_poll(g_WiiMotesFromWiiUse, MAX_WIIMOTES))
{ {
/* /*
* This happens if something happened on any wiimote. * This happens if something happened on any wiimote.
* So go through each one and check if anything happened. * So go through each one and check if anything happened.
*/ */
int i = 0; int i = 0;
for (; i < MAX_WIIMOTES; ++i) for (; i < MAX_WIIMOTES; ++i)
{ {
switch (g_WiiMotesFromWiiUse[i]->event) switch (g_WiiMotesFromWiiUse[i]->event)
{ {
case WIIUSE_EVENT: case WIIUSE_EVENT:
/* a generic event occured */ /* a generic event occured */
//handle_event(g_WiiMotesFromWiiUse[i]); //handle_event(g_WiiMotesFromWiiUse[i]);
break; break;
case WIIUSE_STATUS: case WIIUSE_STATUS:
/* a status event occured */ /* a status event occured */
//handle_ctrl_status(g_WiiMotesFromWiiUse[i]); //handle_ctrl_status(g_WiiMotesFromWiiUse[i]);
break; break;
case WIIUSE_DISCONNECT: case WIIUSE_DISCONNECT:
case WIIUSE_UNEXPECTED_DISCONNECT: case WIIUSE_UNEXPECTED_DISCONNECT:
/* the wiimote disconnected */ /* the wiimote disconnected */
//handle_disconnect(wiimotes[i]); //handle_disconnect(wiimotes[i]);
break; break;
case WIIUSE_READ_DATA: case WIIUSE_READ_DATA:
/* /*
* Data we requested to read was returned. * Data we requested to read was returned.
* Take a look at wiimotes[i]->read_req * Take a look at wiimotes[i]->read_req
* for the data. * for the data.
*/ */
if(g_WiiMotesFromWiiUse[0]->read_req->size == sizeof(WiiMoteEmu::EepromData_0) if(g_WiiMotesFromWiiUse[0]->read_req->size == sizeof(WiiMoteEmu::EepromData_0)
&& g_WiiMotesFromWiiUse[0]->read_req->addr == 0) && g_WiiMotesFromWiiUse[0]->read_req->addr == 0)
{ {
Temp = ArrayToString(g_WiiMotesFromWiiUse[0]->read_req->buf, sizeof(WiiMoteEmu::EepromData_0), 0, 30); Temp = ArrayToString(g_WiiMotesFromWiiUse[0]->read_req->buf, sizeof(WiiMoteEmu::EepromData_0), 0, 30);
memcpy(WiiMoteEmu::g_Eeprom, g_WiiMotesFromWiiUse[0]->read_req->buf, sizeof(WiiMoteEmu::EepromData_0)); memcpy(WiiMoteEmu::g_Eeprom, g_WiiMotesFromWiiUse[0]->read_req->buf, sizeof(WiiMoteEmu::EepromData_0));
Console::Print("EEPROM: %s\n", Temp.c_str()); Console::Print("EEPROM: %s\n", Temp.c_str());
WiiMoteEmu::UpdateEeprom(); WiiMoteEmu::UpdateEeprom();
g_RunTemporary = false; g_RunTemporary = false;
} }
break; break;
case WIIUSE_NUNCHUK_INSERTED: case WIIUSE_NUNCHUK_INSERTED:
/* /*
* a nunchuk was inserted * a nunchuk was inserted
* This is a good place to set any nunchuk specific * This is a good place to set any nunchuk specific
* threshold values. By default they are the same * threshold values. By default they are the same
* as the wiimote. * as the wiimote.
*/ */
//wiiuse_set_nunchuk_orient_threshold((struct nunchuk_t*)&wiimotes[i]->exp.nunchuk, 90.0f); //wiiuse_set_nunchuk_orient_threshold((struct nunchuk_t*)&wiimotes[i]->exp.nunchuk, 90.0f);
//wiiuse_set_nunchuk_accel_threshold((struct nunchuk_t*)&wiimotes[i]->exp.nunchuk, 100); //wiiuse_set_nunchuk_accel_threshold((struct nunchuk_t*)&wiimotes[i]->exp.nunchuk, 100);
Console::Print("Nunchuk inserted.\n"); Console::Print("Nunchuk inserted.\n");
break; break;
case WIIUSE_CLASSIC_CTRL_INSERTED: case WIIUSE_CLASSIC_CTRL_INSERTED:
Console::Print("Classic controller inserted.\n"); Console::Print("Classic controller inserted.\n");
break; break;
case WIIUSE_GUITAR_HERO_3_CTRL_INSERTED: case WIIUSE_GUITAR_HERO_3_CTRL_INSERTED:
// some expansion was inserted // some expansion was inserted
//handle_ctrl_status(wiimotes[i]); //handle_ctrl_status(wiimotes[i]);
Console::Print("Guitar Hero 3 controller inserted.\n"); Console::Print("Guitar Hero 3 controller inserted.\n");
break; break;
case WIIUSE_NUNCHUK_REMOVED: case WIIUSE_NUNCHUK_REMOVED:
case WIIUSE_CLASSIC_CTRL_REMOVED: case WIIUSE_CLASSIC_CTRL_REMOVED:
case WIIUSE_GUITAR_HERO_3_CTRL_REMOVED: case WIIUSE_GUITAR_HERO_3_CTRL_REMOVED:
// some expansion was removed // some expansion was removed
//handle_ctrl_status(wiimotes[i]); //handle_ctrl_status(wiimotes[i]);
Console::Print("An expansion was removed.\n"); Console::Print("An expansion was removed.\n");
break; break;
default: default:
break; break;
} }
} }
} }
} }
}; // end of namespace }; // end of namespace

View File

@ -1,277 +1,277 @@
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Project description // Project description
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// Name: nJoy // Name: nJoy
// Description: A Dolphin Compatible Input Plugin // Description: A Dolphin Compatible Input Plugin
// //
// Author: Falcon4ever (nJoy@falcon4ever.com) // Author: Falcon4ever (nJoy@falcon4ever.com)
// Site: www.multigesture.net // Site: www.multigesture.net
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2008 Dolphin Project.
// //
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// //
// Licensetype: GNU General Public License (GPL) // Licensetype: GNU General Public License (GPL)
// //
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0. // the Free Software Foundation, version 2.0.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details. // GNU General Public License 2.0 for more details.
// //
// A copy of the GPL 2.0 should have been included with the program. // A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/ // If not, see http://www.gnu.org/licenses/
// //
// Official SVN repository and contact information can be found at // Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
// //
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
// Include // Include
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#include "nJoy.h" #include "nJoy.h"
#include "Common.h" #include "Common.h"
Config g_Config; Config g_Config;
#if defined(HAVE_WX) && HAVE_WX #if defined(HAVE_WX) && HAVE_WX
extern ConfigBox* m_frame; extern ConfigBox* m_frame;
#endif #endif
////////////////////////////////// //////////////////////////////////
// Run when created // Run when created
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
Config::Config() Config::Config()
{ {
// Clear the memory // Clear the memory
//memset(this, 0, sizeof(Config)); //memset(this, 0, sizeof(Config));
} }
// Enable output log // Enable output log
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void DEBUG_INIT() void DEBUG_INIT()
{ {
if (pFile) if (pFile)
return; return;
#ifdef _WIN32 #ifdef _WIN32
char dateStr [9]; char dateStr [9];
_strdate( dateStr); _strdate( dateStr);
char timeStr [9]; char timeStr [9];
_strtime( timeStr ); _strtime( timeStr );
#endif #endif
pFile = fopen ("nJoy-debug.txt","wt"); pFile = fopen ("nJoy-debug.txt","wt");
fprintf(pFile, "nJoy v"INPUT_VERSION" Debug\n"); fprintf(pFile, "nJoy v"INPUT_VERSION" Debug\n");
#ifdef _WIN32 #ifdef _WIN32
fprintf(pFile, "Date: %s\nTime: %s\n", dateStr, timeStr); fprintf(pFile, "Date: %s\nTime: %s\n", dateStr, timeStr);
#endif #endif
fprintf(pFile, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>\n"); fprintf(pFile, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>\n");
} }
// Disable output log // Disable output log
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void DEBUG_QUIT() void DEBUG_QUIT()
{ {
if (!pFile) if (!pFile)
return; return;
#ifdef _WIN32 #ifdef _WIN32
char timeStr [9]; char timeStr [9];
_strtime(timeStr); _strtime(timeStr);
fprintf(pFile, "_______________\n"); fprintf(pFile, "_______________\n");
fprintf(pFile, "Time: %s", timeStr); fprintf(pFile, "Time: %s", timeStr);
#endif #endif
fclose(pFile); fclose(pFile);
} }
///////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////
// Save settings to file // Save settings to file
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void Config::Save(int Slot) void Config::Save(int Slot)
{ {
// If there are no good pads don't save // If there are no good pads don't save
if (NumGoodPads == 0) return; if (NumGoodPads == 0) return;
// Load ini file // Load ini file
IniFile file; IniFile file;
file.Load("nJoy.ini"); file.Load("nJoy.ini");
// ================================================================== // ==================================================================
// Global settings // Global settings
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
file.Set("General", "ShowAdvanced", g_Config.bShowAdvanced); file.Set("General", "ShowAdvanced", g_Config.bShowAdvanced);
file.Set("General", "SaveByID", g_Config.bSaveByID); file.Set("General", "SaveByID", g_Config.bSaveByID);
file.Set("General", "CheckForFocus", g_Config.bCheckFocus); file.Set("General", "CheckForFocus", g_Config.bCheckFocus);
file.Set("General", "NoTriggerFilter", g_Config.bNoTriggerFilter); file.Set("General", "NoTriggerFilter", g_Config.bNoTriggerFilter);
#ifdef RERECORDING #ifdef RERECORDING
file.Set("General", "Recording", g_Config.bRecording); file.Set("General", "Recording", g_Config.bRecording);
file.Set("General", "Playback", g_Config.bPlayback); file.Set("General", "Playback", g_Config.bPlayback);
#endif #endif
// ======================== // ========================
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
{ {
// Should we save this slot? // Should we save this slot?
if (Slot != -1 && Slot != i) continue; if (Slot != -1 && Slot != i) continue;
// ================================================================== // ==================================================================
// Slot specific settings only // Slot specific settings only
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
std::string SectionName = StringFromFormat("PAD%i", i+1); std::string SectionName = StringFromFormat("PAD%i", i+1);
file.Set(SectionName.c_str(), "enabled", PadMapping[i].enabled); file.Set(SectionName.c_str(), "enabled", PadMapping[i].enabled);
// Save the physical device ID // Save the physical device ID
file.Set(SectionName.c_str(), "joy_id", PadMapping[i].ID); file.Set(SectionName.c_str(), "joy_id", PadMapping[i].ID);
// =================== // ===================
// ================================================================== // ==================================================================
// Joypad or slot specific settings // Joypad or slot specific settings
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// Current joypad device ID: PadMapping[i].ID // Current joypad device ID: PadMapping[i].ID
// Current joypad name: joyinfo[PadMapping[i].ID].Name // Current joypad name: joyinfo[PadMapping[i].ID].Name
if(g_Config.bSaveByID) if(g_Config.bSaveByID)
{ {
/* Save joypad specific settings. Check for "PadMapping[i].ID < SDL_NumJoysticks()" to /* Save joypad specific settings. Check for "PadMapping[i].ID < SDL_NumJoysticks()" to
avoid reading a joyinfo that does't exist */ avoid reading a joyinfo that does't exist */
if(PadMapping[i].ID >= joyinfo.size()) continue; if(PadMapping[i].ID >= joyinfo.size()) continue;
// Create a new section name after the joypad name // Create a new section name after the joypad name
SectionName = joyinfo[PadMapping[i].ID].Name; SectionName = joyinfo[PadMapping[i].ID].Name;
} }
file.Set(SectionName.c_str(), "l_shoulder", PadMapping[i].buttons[InputCommon::CTL_L_SHOULDER]); file.Set(SectionName.c_str(), "l_shoulder", PadMapping[i].buttons[InputCommon::CTL_L_SHOULDER]);
file.Set(SectionName.c_str(), "r_shoulder", PadMapping[i].buttons[InputCommon::CTL_R_SHOULDER]); file.Set(SectionName.c_str(), "r_shoulder", PadMapping[i].buttons[InputCommon::CTL_R_SHOULDER]);
file.Set(SectionName.c_str(), "a_button", PadMapping[i].buttons[InputCommon::CTL_A_BUTTON]); file.Set(SectionName.c_str(), "a_button", PadMapping[i].buttons[InputCommon::CTL_A_BUTTON]);
file.Set(SectionName.c_str(), "b_button", PadMapping[i].buttons[InputCommon::CTL_B_BUTTON]); file.Set(SectionName.c_str(), "b_button", PadMapping[i].buttons[InputCommon::CTL_B_BUTTON]);
file.Set(SectionName.c_str(), "x_button", PadMapping[i].buttons[InputCommon::CTL_X_BUTTON]); file.Set(SectionName.c_str(), "x_button", PadMapping[i].buttons[InputCommon::CTL_X_BUTTON]);
file.Set(SectionName.c_str(), "y_button", PadMapping[i].buttons[InputCommon::CTL_Y_BUTTON]); file.Set(SectionName.c_str(), "y_button", PadMapping[i].buttons[InputCommon::CTL_Y_BUTTON]);
file.Set(SectionName.c_str(), "z_trigger", PadMapping[i].buttons[InputCommon::CTL_Z_TRIGGER]); file.Set(SectionName.c_str(), "z_trigger", PadMapping[i].buttons[InputCommon::CTL_Z_TRIGGER]);
file.Set(SectionName.c_str(), "start_button", PadMapping[i].buttons[InputCommon::CTL_START]); file.Set(SectionName.c_str(), "start_button", PadMapping[i].buttons[InputCommon::CTL_START]);
file.Set(SectionName.c_str(), "dpad", PadMapping[i].dpad); file.Set(SectionName.c_str(), "dpad", PadMapping[i].dpad);
file.Set(SectionName.c_str(), "dpad_up", PadMapping[i].dpad2[InputCommon::CTL_D_PAD_UP]); file.Set(SectionName.c_str(), "dpad_up", PadMapping[i].dpad2[InputCommon::CTL_D_PAD_UP]);
file.Set(SectionName.c_str(), "dpad_down", PadMapping[i].dpad2[InputCommon::CTL_D_PAD_DOWN]); file.Set(SectionName.c_str(), "dpad_down", PadMapping[i].dpad2[InputCommon::CTL_D_PAD_DOWN]);
file.Set(SectionName.c_str(), "dpad_left", PadMapping[i].dpad2[InputCommon::CTL_D_PAD_LEFT]); file.Set(SectionName.c_str(), "dpad_left", PadMapping[i].dpad2[InputCommon::CTL_D_PAD_LEFT]);
file.Set(SectionName.c_str(), "dpad_right", PadMapping[i].dpad2[InputCommon::CTL_D_PAD_RIGHT]); file.Set(SectionName.c_str(), "dpad_right", PadMapping[i].dpad2[InputCommon::CTL_D_PAD_RIGHT]);
file.Set(SectionName.c_str(), "main_x", PadMapping[i].axis[InputCommon::CTL_MAIN_X]); file.Set(SectionName.c_str(), "main_x", PadMapping[i].axis[InputCommon::CTL_MAIN_X]);
file.Set(SectionName.c_str(), "main_y", PadMapping[i].axis[InputCommon::CTL_MAIN_Y]); file.Set(SectionName.c_str(), "main_y", PadMapping[i].axis[InputCommon::CTL_MAIN_Y]);
file.Set(SectionName.c_str(), "sub_x", PadMapping[i].axis[InputCommon::CTL_SUB_X]); file.Set(SectionName.c_str(), "sub_x", PadMapping[i].axis[InputCommon::CTL_SUB_X]);
file.Set(SectionName.c_str(), "sub_y", PadMapping[i].axis[InputCommon::CTL_SUB_Y]); file.Set(SectionName.c_str(), "sub_y", PadMapping[i].axis[InputCommon::CTL_SUB_Y]);
file.Set(SectionName.c_str(), "deadzone", PadMapping[i].deadzone); file.Set(SectionName.c_str(), "deadzone", PadMapping[i].deadzone);
file.Set(SectionName.c_str(), "halfpress", PadMapping[i].halfpress); file.Set(SectionName.c_str(), "halfpress", PadMapping[i].halfpress);
file.Set(SectionName.c_str(), "controllertype", PadMapping[i].controllertype); file.Set(SectionName.c_str(), "controllertype", PadMapping[i].controllertype);
file.Set(SectionName.c_str(), "TriggerType", PadMapping[i].triggertype); file.Set(SectionName.c_str(), "TriggerType", PadMapping[i].triggertype);
file.Set(SectionName.c_str(), "eventnum", PadMapping[i].eventnum); file.Set(SectionName.c_str(), "eventnum", PadMapping[i].eventnum);
file.Set(SectionName.c_str(), "Diagonal", PadMapping[i].SDiagonal); file.Set(SectionName.c_str(), "Diagonal", PadMapping[i].SDiagonal);
file.Set(SectionName.c_str(), "SquareToCircle", PadMapping[i].bSquareToCircle); file.Set(SectionName.c_str(), "SquareToCircle", PadMapping[i].bSquareToCircle);
// ====================================== // ======================================
// Debugging // Debugging
//if(m_frame) m_frame->LogMsg("Saved: %s %i\n", SectionName.c_str(), PadMapping[i].triggertype); //if(m_frame) m_frame->LogMsg("Saved: %s %i\n", SectionName.c_str(), PadMapping[i].triggertype);
} }
Console::Print("%i: Save: %i\n", 0, PadMapping[0].halfpress); Console::Print("%i: Save: %i\n", 0, PadMapping[0].halfpress);
file.Save("nJoy.ini"); file.Save("nJoy.ini");
} }
// Load settings from file // Load settings from file
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void Config::Load(bool ChangePad, bool ChangeSaveByID) void Config::Load(bool ChangePad, bool ChangeSaveByID)
{ {
// If there are no good pads don't load // If there are no good pads don't load
if (NumGoodPads == 0) return; if (NumGoodPads == 0) return;
// Load file // Load file
IniFile file; IniFile file;
file.Load("nJoy.ini"); file.Load("nJoy.ini");
bool Tmp; // Tmp storage bool Tmp; // Tmp storage
// ================================================================== // ==================================================================
// Global settings // Global settings
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
file.Get("General", "ShowAdvanced", &g_Config.bShowAdvanced, false); file.Get("General", "ShowAdvanced", &g_Config.bShowAdvanced, false);
file.Get("General", "CheckForFocus", &g_Config.bCheckFocus, false); file.Get("General", "CheckForFocus", &g_Config.bCheckFocus, false);
file.Get("General", "NoTriggerFilter", &g_Config.bNoTriggerFilter, false); file.Get("General", "NoTriggerFilter", &g_Config.bNoTriggerFilter, false);
#ifdef RERECORDING #ifdef RERECORDING
file.Get("General", "Recording", &g_Config.bRecording, false); file.Get("General", "Recording", &g_Config.bRecording, false);
file.Get("General", "Playback", &g_Config.bPlayback, false); file.Get("General", "Playback", &g_Config.bPlayback, false);
#endif #endif
if(!ChangeSaveByID) if(!ChangeSaveByID)
{ {
file.Get("General", "SaveByID", &Tmp, false); g_Config.bSaveByID = Tmp; file.Get("General", "SaveByID", &Tmp, false); g_Config.bSaveByID = Tmp;
} }
// ============= // =============
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
{ {
std::string SectionName = StringFromFormat("PAD%i", i+1); std::string SectionName = StringFromFormat("PAD%i", i+1);
// Don't update this when we are loading settings from the ConfigBox // Don't update this when we are loading settings from the ConfigBox
if(!ChangePad) if(!ChangePad)
{ {
file.Get(SectionName.c_str(), "joy_id", &PadMapping[i].ID, 0); file.Get(SectionName.c_str(), "joy_id", &PadMapping[i].ID, 0);
file.Get(SectionName.c_str(), "enabled", &PadMapping[i].enabled, 1); file.Get(SectionName.c_str(), "enabled", &PadMapping[i].enabled, 1);
} }
// ================================================================== // ==================================================================
// Joypad or slot specific settings // Joypad or slot specific settings
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// Current joypad device ID: PadMapping[i].ID // Current joypad device ID: PadMapping[i].ID
// Current joypad name: joyinfo[PadMapping[i].ID].Name // Current joypad name: joyinfo[PadMapping[i].ID].Name
if(g_Config.bSaveByID) if(g_Config.bSaveByID)
{ {
/* Prevent a crash from illegal access to joyinfo that will only have values for /* Prevent a crash from illegal access to joyinfo that will only have values for
the current amount of connected pads */ the current amount of connected pads */
if(PadMapping[i].ID >= joyinfo.size()) continue; if(PadMapping[i].ID >= joyinfo.size()) continue;
// Create a section name // Create a section name
SectionName = joyinfo[PadMapping[i].ID].Name; SectionName = joyinfo[PadMapping[i].ID].Name;
} }
file.Get(SectionName.c_str(), "l_shoulder", &PadMapping[i].buttons[InputCommon::CTL_L_SHOULDER], 4); file.Get(SectionName.c_str(), "l_shoulder", &PadMapping[i].buttons[InputCommon::CTL_L_SHOULDER], 4);
file.Get(SectionName.c_str(), "r_shoulder", &PadMapping[i].buttons[InputCommon::CTL_R_SHOULDER], 5); file.Get(SectionName.c_str(), "r_shoulder", &PadMapping[i].buttons[InputCommon::CTL_R_SHOULDER], 5);
file.Get(SectionName.c_str(), "a_button", &PadMapping[i].buttons[InputCommon::CTL_A_BUTTON], 0); file.Get(SectionName.c_str(), "a_button", &PadMapping[i].buttons[InputCommon::CTL_A_BUTTON], 0);
file.Get(SectionName.c_str(), "b_button", &PadMapping[i].buttons[InputCommon::CTL_B_BUTTON], 1); file.Get(SectionName.c_str(), "b_button", &PadMapping[i].buttons[InputCommon::CTL_B_BUTTON], 1);
file.Get(SectionName.c_str(), "x_button", &PadMapping[i].buttons[InputCommon::CTL_X_BUTTON], 3); file.Get(SectionName.c_str(), "x_button", &PadMapping[i].buttons[InputCommon::CTL_X_BUTTON], 3);
file.Get(SectionName.c_str(), "y_button", &PadMapping[i].buttons[InputCommon::CTL_Y_BUTTON], 2); file.Get(SectionName.c_str(), "y_button", &PadMapping[i].buttons[InputCommon::CTL_Y_BUTTON], 2);
file.Get(SectionName.c_str(), "z_trigger", &PadMapping[i].buttons[InputCommon::CTL_Z_TRIGGER], 7); file.Get(SectionName.c_str(), "z_trigger", &PadMapping[i].buttons[InputCommon::CTL_Z_TRIGGER], 7);
file.Get(SectionName.c_str(), "start_button", &PadMapping[i].buttons[InputCommon::CTL_START], 9); file.Get(SectionName.c_str(), "start_button", &PadMapping[i].buttons[InputCommon::CTL_START], 9);
file.Get(SectionName.c_str(), "dpad", &PadMapping[i].dpad, 0); file.Get(SectionName.c_str(), "dpad", &PadMapping[i].dpad, 0);
file.Get(SectionName.c_str(), "dpad_up", &PadMapping[i].dpad2[InputCommon::CTL_D_PAD_UP], 0); file.Get(SectionName.c_str(), "dpad_up", &PadMapping[i].dpad2[InputCommon::CTL_D_PAD_UP], 0);
file.Get(SectionName.c_str(), "dpad_down", &PadMapping[i].dpad2[InputCommon::CTL_D_PAD_DOWN], 0); file.Get(SectionName.c_str(), "dpad_down", &PadMapping[i].dpad2[InputCommon::CTL_D_PAD_DOWN], 0);
file.Get(SectionName.c_str(), "dpad_left", &PadMapping[i].dpad2[InputCommon::CTL_D_PAD_LEFT], 0); file.Get(SectionName.c_str(), "dpad_left", &PadMapping[i].dpad2[InputCommon::CTL_D_PAD_LEFT], 0);
file.Get(SectionName.c_str(), "dpad_right", &PadMapping[i].dpad2[InputCommon::CTL_D_PAD_RIGHT], 0); file.Get(SectionName.c_str(), "dpad_right", &PadMapping[i].dpad2[InputCommon::CTL_D_PAD_RIGHT], 0);
file.Get(SectionName.c_str(), "main_x", &PadMapping[i].axis[InputCommon::CTL_MAIN_X], 0); file.Get(SectionName.c_str(), "main_x", &PadMapping[i].axis[InputCommon::CTL_MAIN_X], 0);
file.Get(SectionName.c_str(), "main_y", &PadMapping[i].axis[InputCommon::CTL_MAIN_Y], 1); file.Get(SectionName.c_str(), "main_y", &PadMapping[i].axis[InputCommon::CTL_MAIN_Y], 1);
file.Get(SectionName.c_str(), "sub_x", &PadMapping[i].axis[InputCommon::CTL_SUB_X], 2); file.Get(SectionName.c_str(), "sub_x", &PadMapping[i].axis[InputCommon::CTL_SUB_X], 2);
file.Get(SectionName.c_str(), "sub_y", &PadMapping[i].axis[InputCommon::CTL_SUB_Y], 3); file.Get(SectionName.c_str(), "sub_y", &PadMapping[i].axis[InputCommon::CTL_SUB_Y], 3);
file.Get(SectionName.c_str(), "deadzone", &PadMapping[i].deadzone, 9); file.Get(SectionName.c_str(), "deadzone", &PadMapping[i].deadzone, 9);
file.Get(SectionName.c_str(), "halfpress", &PadMapping[i].halfpress, -1); file.Get(SectionName.c_str(), "halfpress", &PadMapping[i].halfpress, -1);
file.Get(SectionName.c_str(), "controllertype", &PadMapping[i].controllertype, 0); file.Get(SectionName.c_str(), "controllertype", &PadMapping[i].controllertype, 0);
file.Get(SectionName.c_str(), "TriggerType", &PadMapping[i].triggertype, 0); file.Get(SectionName.c_str(), "TriggerType", &PadMapping[i].triggertype, 0);
file.Get(SectionName.c_str(), "eventnum", &PadMapping[i].eventnum, 0); file.Get(SectionName.c_str(), "eventnum", &PadMapping[i].eventnum, 0);
file.Get(SectionName.c_str(), "Diagonal", &PadMapping[i].SDiagonal, "100%"); file.Get(SectionName.c_str(), "Diagonal", &PadMapping[i].SDiagonal, "100%");
file.Get(SectionName.c_str(), "SquareToCircle", &Tmp, false); PadMapping[i].bSquareToCircle = Tmp; file.Get(SectionName.c_str(), "SquareToCircle", &Tmp, false); PadMapping[i].bSquareToCircle = Tmp;
// ============================= // =============================
// Debugging // Debugging
//if(m_frame) m_frame->LogMsg("%i: Enabled: %i\n", i, PadMapping[i].buttons[CTL_X_BUTTON]); //if(m_frame) m_frame->LogMsg("%i: Enabled: %i\n", i, PadMapping[i].buttons[CTL_X_BUTTON]);
} }
Console::Print("%i: Load: %i\n", 0, PadMapping[0].halfpress); Console::Print("%i: Load: %i\n", 0, PadMapping[0].halfpress);
} }

View File

@ -1,384 +1,384 @@
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Project description // Project description
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// Name: nJoy // Name: nJoy
// Description: A Dolphin Compatible Input Plugin // Description: A Dolphin Compatible Input Plugin
// //
// Author: Falcon4ever (nJoy@falcon4ever.com) // Author: Falcon4ever (nJoy@falcon4ever.com)
// Site: www.multigesture.net // Site: www.multigesture.net
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2008 Dolphin Project.
// //
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// //
// Licensetype: GNU General Public License (GPL) // Licensetype: GNU General Public License (GPL)
// //
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0. // the Free Software Foundation, version 2.0.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details. // GNU General Public License 2.0 for more details.
// //
// A copy of the GPL 2.0 should have been included with the program. // A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/ // If not, see http://www.gnu.org/licenses/
// //
// Official SVN repository and contact information can be found at // Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
// //
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Include // Include
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#include "ConfigBox.h" #include "ConfigBox.h"
#include "../nJoy.h" #include "../nJoy.h"
#include "Images/controller.xpm" #include "Images/controller.xpm"
extern bool g_EmulatorRunning; extern bool g_EmulatorRunning;
//////////////////////// ////////////////////////
/* If we don't use this hack m_MainSizer->GetMinSize().GetWidth() will not change /* If we don't use this hack m_MainSizer->GetMinSize().GetWidth() will not change
when we enable and disable bShowAdvanced */ when we enable and disable bShowAdvanced */
bool StrangeHack = true; bool StrangeHack = true;
// Set PAD status // Set PAD status
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void ConfigBox::PadGetStatus() void ConfigBox::PadGetStatus()
{ {
/* Return if it's not detected. The ID should never be less than zero here, it can only be that /* Return if it's not detected. The ID should never be less than zero here, it can only be that
because of a manual ini file change, but we make that check anway. */ because of a manual ini file change, but we make that check anway. */
if(PadMapping[notebookpage].ID < 0 || PadMapping[notebookpage].ID >= SDL_NumJoysticks()) if(PadMapping[notebookpage].ID < 0 || PadMapping[notebookpage].ID >= SDL_NumJoysticks())
{ {
m_TStatusIn[notebookpage]->SetLabel(wxT("Not connected")); m_TStatusIn[notebookpage]->SetLabel(wxT("Not connected"));
m_TStatusOut[notebookpage]->SetLabel(wxT("Not connected")); m_TStatusOut[notebookpage]->SetLabel(wxT("Not connected"));
m_TStatusTriggers[notebookpage]->SetLabel(wxT("Not connected")); m_TStatusTriggers[notebookpage]->SetLabel(wxT("Not connected"));
return; return;
} }
// Return if it's not enabled // Return if it's not enabled
if (!PadMapping[notebookpage].enabled) if (!PadMapping[notebookpage].enabled)
{ {
m_TStatusIn[notebookpage]->SetLabel(wxT("Not enabled")); m_TStatusIn[notebookpage]->SetLabel(wxT("Not enabled"));
m_TStatusOut[notebookpage]->SetLabel(wxT("Not enabled")); m_TStatusOut[notebookpage]->SetLabel(wxT("Not enabled"));
m_TStatusTriggers[notebookpage]->SetLabel(wxT("Not enabled")); m_TStatusTriggers[notebookpage]->SetLabel(wxT("Not enabled"));
return; return;
} }
// Get physical device status // Get physical device status
int PhysicalDevice = PadMapping[notebookpage].ID; int PhysicalDevice = PadMapping[notebookpage].ID;
int TriggerType = PadMapping[notebookpage].triggertype; int TriggerType = PadMapping[notebookpage].triggertype;
////////////////////////////////////// //////////////////////////////////////
// Analog stick // Analog stick
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// Set Deadzones perhaps out of function // Set Deadzones perhaps out of function
//int deadzone = (int)(((float)(128.00/100.00)) * (float)(PadMapping[_numPAD].deadzone+1)); //int deadzone = (int)(((float)(128.00/100.00)) * (float)(PadMapping[_numPAD].deadzone+1));
//int deadzone2 = (int)(((float)(-128.00/100.00)) * (float)(PadMapping[_numPAD].deadzone+1)); //int deadzone2 = (int)(((float)(-128.00/100.00)) * (float)(PadMapping[_numPAD].deadzone+1));
// Get original values // Get original values
int main_x = PadState[notebookpage].axis[InputCommon::CTL_MAIN_X]; int main_x = PadState[notebookpage].axis[InputCommon::CTL_MAIN_X];
int main_y = PadState[notebookpage].axis[InputCommon::CTL_MAIN_Y]; int main_y = PadState[notebookpage].axis[InputCommon::CTL_MAIN_Y];
//int sub_x = (PadState[_numPAD].axis[CTL_SUB_X]; //int sub_x = (PadState[_numPAD].axis[CTL_SUB_X];
//int sub_y = -(PadState[_numPAD].axis[CTL_SUB_Y]; //int sub_y = -(PadState[_numPAD].axis[CTL_SUB_Y];
// Get adjusted values // Get adjusted values
int main_x_after = main_x, main_y_after = main_y; int main_x_after = main_x, main_y_after = main_y;
if(PadMapping[notebookpage].bSquareToCircle) if(PadMapping[notebookpage].bSquareToCircle)
{ {
std::vector<int> main_xy = InputCommon::Square2Circle(main_x, main_y, notebookpage, PadMapping[notebookpage].SDiagonal); std::vector<int> main_xy = InputCommon::Square2Circle(main_x, main_y, notebookpage, PadMapping[notebookpage].SDiagonal);
main_x_after = main_xy.at(0); main_x_after = main_xy.at(0);
main_y_after = main_xy.at(1); main_y_after = main_xy.at(1);
} }
// //
float f_x = main_x / 32767.0; float f_x = main_x / 32767.0;
float f_y = main_y / 32767.0; float f_y = main_y / 32767.0;
float f_x_aft = main_x_after / 32767.0; float f_x_aft = main_x_after / 32767.0;
float f_y_aft = main_y_after / 32767.0; float f_y_aft = main_y_after / 32767.0;
m_TStatusIn[notebookpage]->SetLabel(wxString::Format( m_TStatusIn[notebookpage]->SetLabel(wxString::Format(
wxT("x:%1.2f y:%1.2f"), wxT("x:%1.2f y:%1.2f"),
f_x, f_y f_x, f_y
)); ));
m_TStatusOut[notebookpage]->SetLabel(wxString::Format( m_TStatusOut[notebookpage]->SetLabel(wxString::Format(
wxT("x:%1.2f y:%1.2f"), wxT("x:%1.2f y:%1.2f"),
f_x_aft, f_y_aft f_x_aft, f_y_aft
)); ));
// Adjust the values for the plot // Adjust the values for the plot
int BoxW_ = BoxW - 2; int BoxH_ = BoxH - 2; // Border adjustment int BoxW_ = BoxW - 2; int BoxH_ = BoxH - 2; // Border adjustment
main_x = (BoxW_ / 2) + (main_x * BoxW_ / (32767 * 2)); main_x = (BoxW_ / 2) + (main_x * BoxW_ / (32767 * 2));
main_y = (BoxH_ / 2) + (main_y * BoxH_ / (32767 * 2)); main_y = (BoxH_ / 2) + (main_y * BoxH_ / (32767 * 2));
int main_x_out = (BoxW_ / 2) + (main_x_after * BoxW_ / (32767 * 2)); int main_x_out = (BoxW_ / 2) + (main_x_after * BoxW_ / (32767 * 2));
int main_y_out = (BoxH_ / 2) + (main_y_after * BoxH_ / (32767 * 2)); int main_y_out = (BoxH_ / 2) + (main_y_after * BoxH_ / (32767 * 2));
// Adjust the dot // Adjust the dot
m_bmpDot[notebookpage]->SetPosition(wxPoint(main_x, main_y)); m_bmpDot[notebookpage]->SetPosition(wxPoint(main_x, main_y));
m_bmpDotOut[notebookpage]->SetPosition(wxPoint(main_x_out, main_y_out)); m_bmpDotOut[notebookpage]->SetPosition(wxPoint(main_x_out, main_y_out));
///////////////////// Analog stick ///////////////////// Analog stick
////////////////////////////////////// //////////////////////////////////////
// Triggers // Triggers
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
int TriggerValue = 255; int TriggerValue = 255;
if (PadState[notebookpage].halfpress) TriggerValue = 100; if (PadState[notebookpage].halfpress) TriggerValue = 100;
// Get the selected keys // Get the selected keys
long Left, Right; long Left, Right;
m_JoyShoulderL[notebookpage]->GetValue().ToLong(&Left); m_JoyShoulderL[notebookpage]->GetValue().ToLong(&Left);
m_JoyShoulderR[notebookpage]->GetValue().ToLong(&Right); m_JoyShoulderR[notebookpage]->GetValue().ToLong(&Right);
// Get the trigger values // Get the trigger values
int TriggerLeft = PadState[notebookpage].axis[InputCommon::CTL_L_SHOULDER]; int TriggerLeft = PadState[notebookpage].axis[InputCommon::CTL_L_SHOULDER];
int TriggerRight = PadState[notebookpage].axis[InputCommon::CTL_R_SHOULDER]; int TriggerRight = PadState[notebookpage].axis[InputCommon::CTL_R_SHOULDER];
// Convert the triggers values // Convert the triggers values
if (PadMapping[notebookpage].triggertype == InputCommon::CTL_TRIGGER_SDL) if (PadMapping[notebookpage].triggertype == InputCommon::CTL_TRIGGER_SDL)
{ {
TriggerLeft = InputCommon::Pad_Convert(TriggerLeft); TriggerLeft = InputCommon::Pad_Convert(TriggerLeft);
TriggerRight = InputCommon::Pad_Convert(TriggerRight); TriggerRight = InputCommon::Pad_Convert(TriggerRight);
} }
// If we don't have any axis selected for the shoulder buttons // If we don't have any axis selected for the shoulder buttons
if(Left < 1000) TriggerLeft = 0; if(Left < 1000) TriggerLeft = 0;
if(Right < 1000) TriggerRight = 0; if(Right < 1000) TriggerRight = 0;
// Get the digital values // Get the digital values
if(Left < 1000 && PadState[notebookpage].buttons[InputCommon::CTL_L_SHOULDER]) TriggerLeft = TriggerValue; if(Left < 1000 && PadState[notebookpage].buttons[InputCommon::CTL_L_SHOULDER]) TriggerLeft = TriggerValue;
if(Right < 1000 && PadState[notebookpage].buttons[InputCommon::CTL_R_SHOULDER]) TriggerRight = TriggerValue; if(Right < 1000 && PadState[notebookpage].buttons[InputCommon::CTL_R_SHOULDER]) TriggerRight = TriggerValue;
m_TStatusTriggers[notebookpage]->SetLabel(wxString::Format( m_TStatusTriggers[notebookpage]->SetLabel(wxString::Format(
wxT("Left:%03i Right:%03i"), wxT("Left:%03i Right:%03i"),
TriggerLeft, TriggerRight TriggerLeft, TriggerRight
)); ));
///////////////////// Triggers ///////////////////// Triggers
} }
// Show the current pad status // Show the current pad status
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
std::string ShowStatus(int VirtualController) std::string ShowStatus(int VirtualController)
{ {
// Check if it's enabled // Check if it's enabled
if (!PadMapping[VirtualController].enabled) return StringFromFormat("%i disabled", VirtualController); if (!PadMapping[VirtualController].enabled) return StringFromFormat("%i disabled", VirtualController);
// Save the physical device // Save the physical device
int PhysicalDevice = PadMapping[VirtualController].ID; int PhysicalDevice = PadMapping[VirtualController].ID;
// Make local shortcut // Make local shortcut
SDL_Joystick *joy = PadState[VirtualController].joy; SDL_Joystick *joy = PadState[VirtualController].joy;
// Make shortcuts for all pads // Make shortcuts for all pads
SDL_Joystick *joy0 = PadState[0].joy; SDL_Joystick *joy0 = PadState[0].joy;
SDL_Joystick *joy1 = PadState[1].joy; SDL_Joystick *joy1 = PadState[1].joy;
SDL_Joystick *joy2 = PadState[2].joy; SDL_Joystick *joy2 = PadState[2].joy;
SDL_Joystick *joy3 = PadState[3].joy; SDL_Joystick *joy3 = PadState[3].joy;
// Temporary storage // Temporary storage
std::string StrAxes, StrHats, StrBut; std::string StrAxes, StrHats, StrBut;
int value; int value;
// Get status // Get status
int Axes = joyinfo[PhysicalDevice].NumAxes; int Axes = joyinfo[PhysicalDevice].NumAxes;
int Balls = joyinfo[PhysicalDevice].NumBalls; int Balls = joyinfo[PhysicalDevice].NumBalls;
int Hats = joyinfo[PhysicalDevice].NumHats; int Hats = joyinfo[PhysicalDevice].NumHats;
int Buttons = joyinfo[PhysicalDevice].NumButtons; int Buttons = joyinfo[PhysicalDevice].NumButtons;
// Get version // Get version
//SDL_version Version; //SDL_version Version;
//SDL_GetVersion(&Version); //SDL_GetVersion(&Version);
// Update the internal values // Update the internal values
SDL_JoystickUpdate(); SDL_JoystickUpdate();
// Go through all axes and read out their values // Go through all axes and read out their values
for(int i = 0; i < Axes; i++) for(int i = 0; i < Axes; i++)
{ {
value = SDL_JoystickGetAxis(joy, i); value = SDL_JoystickGetAxis(joy, i);
StrAxes += StringFromFormat(" %i:%06i", i, value); StrAxes += StringFromFormat(" %i:%06i", i, value);
} }
for(int i = 0;i < Hats; i++) for(int i = 0;i < Hats; i++)
{ {
value = SDL_JoystickGetHat(joy, i); value = SDL_JoystickGetHat(joy, i);
StrHats += StringFromFormat(" %i:%i", i, value); StrHats += StringFromFormat(" %i:%i", i, value);
} }
for(int i = 0;i < Buttons; i++) for(int i = 0;i < Buttons; i++)
{ {
value = SDL_JoystickGetButton(joy, i); value = SDL_JoystickGetButton(joy, i);
StrBut += StringFromFormat(" %i:%i", i+1, value); StrBut += StringFromFormat(" %i:%i", i+1, value);
} }
return StringFromFormat( return StringFromFormat(
//"Version: %i.%i.%i\n" //"Version: %i.%i.%i\n"
"All pads:\n" "All pads:\n"
"Enabled: %i %i %i %i\n" "Enabled: %i %i %i %i\n"
"ID: %i %i %i %i\n" "ID: %i %i %i %i\n"
"Controllertype: %i %i %i %i\n" "Controllertype: %i %i %i %i\n"
"SquareToCircle: %i %i %i %i\n\n" "SquareToCircle: %i %i %i %i\n\n"
#ifdef _WIN32 #ifdef _WIN32
"Handles: %i %i %i %i\n" "Handles: %i %i %i %i\n"
"XInput: %i %i %i\n" "XInput: %i %i %i\n"
#endif #endif
"This pad:\n" "This pad:\n"
"Axes: %s\n" "Axes: %s\n"
"Hats: %s\n" "Hats: %s\n"
"But: %s\n" "But: %s\n"
"Device: Ax: %i Balls:%i Hats:%i But:%i", "Device: Ax: %i Balls:%i Hats:%i But:%i",
//Version.major, Version.minor, Version.patch, //Version.major, Version.minor, Version.patch,
PadMapping[0].enabled, PadMapping[1].enabled, PadMapping[2].enabled, PadMapping[3].enabled, PadMapping[0].enabled, PadMapping[1].enabled, PadMapping[2].enabled, PadMapping[3].enabled,
PadMapping[0].ID, PadMapping[1].ID, PadMapping[2].ID, PadMapping[3].ID, PadMapping[0].ID, PadMapping[1].ID, PadMapping[2].ID, PadMapping[3].ID,
PadMapping[0].controllertype, PadMapping[1].controllertype, PadMapping[2].controllertype, PadMapping[3].controllertype, PadMapping[0].controllertype, PadMapping[1].controllertype, PadMapping[2].controllertype, PadMapping[3].controllertype,
PadMapping[0].bSquareToCircle, PadMapping[1].bSquareToCircle, PadMapping[2].bSquareToCircle, PadMapping[3].bSquareToCircle, PadMapping[0].bSquareToCircle, PadMapping[1].bSquareToCircle, PadMapping[2].bSquareToCircle, PadMapping[3].bSquareToCircle,
#ifdef _WIN32 #ifdef _WIN32
joy0, joy1, joy2, joy3, joy0, joy1, joy2, joy3,
//PadState[PadMapping[0].ID].joy, PadState[PadMapping[1].ID].joy, PadState[PadMapping[2].ID].joy, PadState[PadMapping[3].ID].joy, //PadState[PadMapping[0].ID].joy, PadState[PadMapping[1].ID].joy, PadState[PadMapping[2].ID].joy, PadState[PadMapping[3].ID].joy,
XInput::IsConnected(0), XInput::GetXI(0, InputCommon::XI_TRIGGER_L), XInput::GetXI(0, InputCommon::XI_TRIGGER_R), XInput::IsConnected(0), XInput::GetXI(0, InputCommon::XI_TRIGGER_L), XInput::GetXI(0, InputCommon::XI_TRIGGER_R),
#endif #endif
StrAxes.c_str(), StrHats.c_str(), StrBut.c_str(), StrAxes.c_str(), StrHats.c_str(), StrBut.c_str(),
Axes, Balls, Hats, Buttons Axes, Balls, Hats, Buttons
); );
} }
// Populate the advanced tab // Populate the advanced tab
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void ConfigBox::Update() void ConfigBox::Update()
{ {
// Check that Dolphin is in focus, otherwise don't update the pad status // Check that Dolphin is in focus, otherwise don't update the pad status
/* If the emulator is running and unpaused GetJoyState() is run a little more often than needed, /* If the emulator is running and unpaused GetJoyState() is run a little more often than needed,
but I allow that since it can confuse the user if the input status in the configuration window but I allow that since it can confuse the user if the input status in the configuration window
is not update when the emulator is paused. */ is not update when the emulator is paused. */
if (g_Config.bCheckFocus || IsFocus()) // && !g_EmulatorRunning) if (g_Config.bCheckFocus || IsFocus()) // && !g_EmulatorRunning)
{ {
for (int i = 0; i < joyinfo.size(); i++) for (int i = 0; i < joyinfo.size(); i++)
InputCommon::GetJoyState(PadState[i], PadMapping[i], i, joyinfo[PadMapping[i].ID].NumButtons); InputCommon::GetJoyState(PadState[i], PadMapping[i], i, joyinfo[PadMapping[i].ID].NumButtons);
} }
// Show the current status in a window in the wxPanel // Show the current status in a window in the wxPanel
#ifdef SHOW_PAD_STATUS #ifdef SHOW_PAD_STATUS
m_pStatusBar->SetLabel(wxString::Format( m_pStatusBar->SetLabel(wxString::Format(
"%s", ShowStatus(notebookpage).c_str() "%s", ShowStatus(notebookpage).c_str()
)); ));
#endif #endif
//LogMsg("Abc%s\n", ShowStatus(notebookpage).c_str()); //LogMsg("Abc%s\n", ShowStatus(notebookpage).c_str());
if(StrangeHack) PadGetStatus(); if(StrangeHack) PadGetStatus();
if(!g_Config.bShowAdvanced) StrangeHack = false; else StrangeHack = true; if(!g_Config.bShowAdvanced) StrangeHack = false; else StrangeHack = true;
} }
// Populate the advanced tab // Populate the advanced tab
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void ConfigBox::CreateAdvancedControls(int i) void ConfigBox::CreateAdvancedControls(int i)
{ {
m_TStatusIn[i] = new wxStaticText(m_Controller[i], IDT_STATUS_IN, wxT("In")); m_TStatusIn[i] = new wxStaticText(m_Controller[i], IDT_STATUS_IN, wxT("In"));
m_TStatusOut[i] = new wxStaticText(m_Controller[i], IDT_STATUS_OUT, wxT("Out")); m_TStatusOut[i] = new wxStaticText(m_Controller[i], IDT_STATUS_OUT, wxT("Out"));
m_gStatusIn[i] = new wxStaticBoxSizer( wxHORIZONTAL, m_Controller[i], wxT("Main-stick (In) (Out)")); m_gStatusIn[i] = new wxStaticBoxSizer( wxHORIZONTAL, m_Controller[i], wxT("Main-stick (In) (Out)"));
m_pInStatus[i] = new wxPanel(m_Controller[i], ID_INSTATUS1 + i, wxDefaultPosition, wxDefaultSize); m_pInStatus[i] = new wxPanel(m_Controller[i], ID_INSTATUS1 + i, wxDefaultPosition, wxDefaultSize);
m_bmpSquare[i] = new wxStaticBitmap(m_pInStatus[i], ID_STATUSBMP1 + i, CreateBitmap(), m_bmpSquare[i] = new wxStaticBitmap(m_pInStatus[i], ID_STATUSBMP1 + i, CreateBitmap(),
//wxPoint(4, 15), wxSize(70,70)); //wxPoint(4, 15), wxSize(70,70));
//wxPoint(4, 20), wxDefaultSize); //wxPoint(4, 20), wxDefaultSize);
wxDefaultPosition, wxDefaultSize); wxDefaultPosition, wxDefaultSize);
m_bmpDot[i] = new wxStaticBitmap(m_pInStatus[i], ID_STATUSDOTBMP1 + i, CreateBitmapDot(), m_bmpDot[i] = new wxStaticBitmap(m_pInStatus[i], ID_STATUSDOTBMP1 + i, CreateBitmapDot(),
wxPoint(BoxW / 2, BoxH / 2), wxDefaultSize); wxPoint(BoxW / 2, BoxH / 2), wxDefaultSize);
m_pOutStatus[i] = new wxPanel(m_Controller[i], ID_INSTATUS1 + i, wxDefaultPosition, wxDefaultSize); m_pOutStatus[i] = new wxPanel(m_Controller[i], ID_INSTATUS1 + i, wxDefaultPosition, wxDefaultSize);
m_bmpSquareOut[i] = new wxStaticBitmap(m_pOutStatus[i], ID_STATUSBMP1 + i, CreateBitmap(), m_bmpSquareOut[i] = new wxStaticBitmap(m_pOutStatus[i], ID_STATUSBMP1 + i, CreateBitmap(),
//wxPoint(4, 15), wxSize(70,70)); //wxPoint(4, 15), wxSize(70,70));
//wxPoint(4, 20), wxDefaultSize); //wxPoint(4, 20), wxDefaultSize);
wxDefaultPosition, wxDefaultSize); wxDefaultPosition, wxDefaultSize);
m_bmpDotOut[i] = new wxStaticBitmap(m_pOutStatus[i], ID_STATUSDOTBMP1 + i, CreateBitmapDot(), m_bmpDotOut[i] = new wxStaticBitmap(m_pOutStatus[i], ID_STATUSDOTBMP1 + i, CreateBitmapDot(),
wxPoint(BoxW / 2, BoxH / 2), wxDefaultSize); wxPoint(BoxW / 2, BoxH / 2), wxDefaultSize);
///////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////
// Rerecording // Rerecording
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#ifdef RERECORDING #ifdef RERECORDING
// Create controls // Create controls
m_SizeRecording[i] = new wxStaticBoxSizer(wxVERTICAL, m_Controller[i], wxT("Input Recording")); m_SizeRecording[i] = new wxStaticBoxSizer(wxVERTICAL, m_Controller[i], wxT("Input Recording"));
m_CheckRecording[i] = new wxCheckBox(m_Controller[i], ID_RECORDING, wxT("Record input")); m_CheckRecording[i] = new wxCheckBox(m_Controller[i], ID_RECORDING, wxT("Record input"));
m_CheckPlayback[i] = new wxCheckBox(m_Controller[i], ID_PLAYBACK, wxT("Play back input")); m_CheckPlayback[i] = new wxCheckBox(m_Controller[i], ID_PLAYBACK, wxT("Play back input"));
m_BtnSaveRecording[i] = new wxButton(m_Controller[i], ID_SAVE_RECORDING, wxT("Save recording"), wxDefaultPosition, wxDefaultSize); m_BtnSaveRecording[i] = new wxButton(m_Controller[i], ID_SAVE_RECORDING, wxT("Save recording"), wxDefaultPosition, wxDefaultSize);
// Tool tips // Tool tips
m_CheckRecording[i]->SetToolTip(wxT("Your recording will be saved to pad-record.bin in the Dolphin dir when you stop the game")); m_CheckRecording[i]->SetToolTip(wxT("Your recording will be saved to pad-record.bin in the Dolphin dir when you stop the game"));
m_CheckPlayback[i]->SetToolTip(wxT("Play back the pad-record.bin file from the Dolphin dir")); m_CheckPlayback[i]->SetToolTip(wxT("Play back the pad-record.bin file from the Dolphin dir"));
m_BtnSaveRecording[i]->SetToolTip(wxT( m_BtnSaveRecording[i]->SetToolTip(wxT(
"This will save the current recording to pad-record.bin. Your recording will\n" "This will save the current recording to pad-record.bin. Your recording will\n"
"also be automatically saved every 60 * 10 frames. And when you shut down the\n" "also be automatically saved every 60 * 10 frames. And when you shut down the\n"
"game.")); "game."));
// Sizers // Sizers
m_SizeRecording[i]->Add(m_CheckRecording[i], 0, wxEXPAND | wxALL, 1); m_SizeRecording[i]->Add(m_CheckRecording[i], 0, wxEXPAND | wxALL, 1);
m_SizeRecording[i]->Add(m_CheckPlayback[i], 0, wxEXPAND | wxALL, 1); m_SizeRecording[i]->Add(m_CheckPlayback[i], 0, wxEXPAND | wxALL, 1);
m_SizeRecording[i]->Add(m_BtnSaveRecording[i], 0, wxEXPAND | wxALL, 1); m_SizeRecording[i]->Add(m_BtnSaveRecording[i], 0, wxEXPAND | wxALL, 1);
// Only enable these options for pad 0 // Only enable these options for pad 0
m_CheckRecording[i]->Enable(false); m_CheckRecording[0]->Enable(true); m_CheckRecording[i]->Enable(false); m_CheckRecording[0]->Enable(true);
m_CheckPlayback[i]->Enable(false); m_CheckPlayback[0]->Enable(true); m_CheckPlayback[i]->Enable(false); m_CheckPlayback[0]->Enable(true);
m_BtnSaveRecording[i]->Enable(false); m_BtnSaveRecording[0]->Enable(true); m_BtnSaveRecording[i]->Enable(false); m_BtnSaveRecording[0]->Enable(true);
// Don't allow saving when we are not recording // Don't allow saving when we are not recording
m_BtnSaveRecording[i]->Enable(g_EmulatorRunning && g_Config.bRecording); m_BtnSaveRecording[i]->Enable(g_EmulatorRunning && g_Config.bRecording);
//sDevice[i]->Add(m_SizeRecording[i], 0, wxEXPAND | wxALL, 1); //sDevice[i]->Add(m_SizeRecording[i], 0, wxEXPAND | wxALL, 1);
// Set values // Set values
//m_CheckRecording[0]->SetValue(g_Config.bRecording); //m_CheckRecording[0]->SetValue(g_Config.bRecording);
//m_CheckPlayback[0]->SetValue(g_Config.bPlayback); //m_CheckPlayback[0]->SetValue(g_Config.bPlayback);
//Console::Print("m_CheckRecording: %i\n", g_Config.bRecording, g_Config.bPlayback); //Console::Print("m_CheckRecording: %i\n", g_Config.bRecording, g_Config.bPlayback);
#endif #endif
////////////////////////////////////// //////////////////////////////////////
} }
wxBitmap ConfigBox::CreateBitmap() // Create box wxBitmap ConfigBox::CreateBitmap() // Create box
{ {
BoxW = 70, BoxH = 70; BoxW = 70, BoxH = 70;
wxBitmap bitmap(BoxW, BoxH); wxBitmap bitmap(BoxW, BoxH);
wxMemoryDC dc; wxMemoryDC dc;
dc.SelectObject(bitmap); dc.SelectObject(bitmap);
// Set outline and fill colors // Set outline and fill colors
//wxBrush LightBlueBrush(_T("#0383f0")); //wxBrush LightBlueBrush(_T("#0383f0"));
//wxPen LightBluePen(_T("#80c5fd")); //wxPen LightBluePen(_T("#80c5fd"));
//wxPen LightGrayPen(_T("#909090")); //wxPen LightGrayPen(_T("#909090"));
wxPen LightBluePen(_T("#7f9db9")); // Windows XP color wxPen LightBluePen(_T("#7f9db9")); // Windows XP color
dc.SetPen(LightBluePen); dc.SetPen(LightBluePen);
dc.SetBrush(*wxWHITE_BRUSH); dc.SetBrush(*wxWHITE_BRUSH);
dc.Clear(); dc.Clear();
dc.DrawRectangle(0, 0, BoxW, BoxH); dc.DrawRectangle(0, 0, BoxW, BoxH);
dc.SelectObject(wxNullBitmap); dc.SelectObject(wxNullBitmap);
return bitmap; return bitmap;
} }
wxBitmap ConfigBox::CreateBitmapDot() // Create dot wxBitmap ConfigBox::CreateBitmapDot() // Create dot
{ {
int w = 2, h = 2; int w = 2, h = 2;
wxBitmap bitmap(w, h); wxBitmap bitmap(w, h);
wxMemoryDC dc; wxMemoryDC dc;
dc.SelectObject(bitmap); dc.SelectObject(bitmap);
// Set outline and fill colors // Set outline and fill colors
//wxBrush RedBrush(_T("#0383f0")); //wxBrush RedBrush(_T("#0383f0"));
//wxPen RedPen(_T("#80c5fd")); //wxPen RedPen(_T("#80c5fd"));
//wxPen LightGrayPen(_T("#909090")); //wxPen LightGrayPen(_T("#909090"));
dc.SetPen(*wxRED_PEN); dc.SetPen(*wxRED_PEN);
dc.SetBrush(*wxRED_BRUSH); dc.SetBrush(*wxRED_BRUSH);
dc.Clear(); dc.Clear();
dc.DrawRectangle(0, 0, w, h); dc.DrawRectangle(0, 0, w, h);
dc.SelectObject(wxNullBitmap); dc.SelectObject(wxNullBitmap);
return bitmap; return bitmap;
} }

View File

@ -1,434 +1,434 @@
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Project description // Project description
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// Name: nJoy // Name: nJoy
// Description: A Dolphin Compatible Input Plugin // Description: A Dolphin Compatible Input Plugin
// //
// Author: Falcon4ever (nJoy@falcon4ever.com) // Author: Falcon4ever (nJoy@falcon4ever.com)
// Site: www.multigesture.net // Site: www.multigesture.net
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2008 Dolphin Project.
// //
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// //
// Licensetype: GNU General Public License (GPL) // Licensetype: GNU General Public License (GPL)
// //
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0. // the Free Software Foundation, version 2.0.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details. // GNU General Public License 2.0 for more details.
// //
// A copy of the GPL 2.0 should have been included with the program. // A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/ // If not, see http://www.gnu.org/licenses/
// //
// Official SVN repository and contact information can be found at // Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
// //
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Include // Include
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#include "math.h" // System #include "math.h" // System
#include "ConfigBox.h" // Local #include "ConfigBox.h" // Local
#include "../nJoy.h" #include "../nJoy.h"
#include "Images/controller.xpm" #include "Images/controller.xpm"
extern bool g_EmulatorRunning; extern bool g_EmulatorRunning;
//////////////////////// ////////////////////////
// Set dialog items from saved values // Set dialog items from saved values
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void ConfigBox::UpdateGUIButtonMapping(int controller) void ConfigBox::UpdateGUIButtonMapping(int controller)
{ {
// http://wiki.wxwidgets.org/Converting_everything_to_and_from_wxString // http://wiki.wxwidgets.org/Converting_everything_to_and_from_wxString
wxString tmp; wxString tmp;
// Update selected gamepad // Update selected gamepad
m_Joyname[controller]->SetSelection(PadMapping[controller].ID); m_Joyname[controller]->SetSelection(PadMapping[controller].ID);
// Update the enabled checkbox // Update the enabled checkbox
m_Joyattach[controller]->SetValue(PadMapping[controller].enabled == 1 ? true : false); m_Joyattach[controller]->SetValue(PadMapping[controller].enabled == 1 ? true : false);
tmp << PadMapping[controller].buttons[InputCommon::CTL_L_SHOULDER]; m_JoyShoulderL[controller]->SetValue(tmp); tmp.clear(); tmp << PadMapping[controller].buttons[InputCommon::CTL_L_SHOULDER]; m_JoyShoulderL[controller]->SetValue(tmp); tmp.clear();
tmp << PadMapping[controller].buttons[InputCommon::CTL_R_SHOULDER]; m_JoyShoulderR[controller]->SetValue(tmp); tmp.clear(); tmp << PadMapping[controller].buttons[InputCommon::CTL_R_SHOULDER]; m_JoyShoulderR[controller]->SetValue(tmp); tmp.clear();
tmp << PadMapping[controller].buttons[InputCommon::CTL_A_BUTTON]; m_JoyButtonA[controller]->SetValue(tmp); tmp.clear(); tmp << PadMapping[controller].buttons[InputCommon::CTL_A_BUTTON]; m_JoyButtonA[controller]->SetValue(tmp); tmp.clear();
tmp << PadMapping[controller].buttons[InputCommon::CTL_B_BUTTON]; m_JoyButtonB[controller]->SetValue(tmp); tmp.clear(); tmp << PadMapping[controller].buttons[InputCommon::CTL_B_BUTTON]; m_JoyButtonB[controller]->SetValue(tmp); tmp.clear();
tmp << PadMapping[controller].buttons[InputCommon::CTL_X_BUTTON]; m_JoyButtonX[controller]->SetValue(tmp); tmp.clear(); tmp << PadMapping[controller].buttons[InputCommon::CTL_X_BUTTON]; m_JoyButtonX[controller]->SetValue(tmp); tmp.clear();
tmp << PadMapping[controller].buttons[InputCommon::CTL_Y_BUTTON]; m_JoyButtonY[controller]->SetValue(tmp); tmp.clear(); tmp << PadMapping[controller].buttons[InputCommon::CTL_Y_BUTTON]; m_JoyButtonY[controller]->SetValue(tmp); tmp.clear();
tmp << PadMapping[controller].buttons[InputCommon::CTL_Z_TRIGGER]; m_JoyButtonZ[controller]->SetValue(tmp); tmp.clear(); tmp << PadMapping[controller].buttons[InputCommon::CTL_Z_TRIGGER]; m_JoyButtonZ[controller]->SetValue(tmp); tmp.clear();
tmp << PadMapping[controller].buttons[InputCommon::CTL_START]; m_JoyButtonStart[controller]->SetValue(tmp); tmp.clear(); tmp << PadMapping[controller].buttons[InputCommon::CTL_START]; m_JoyButtonStart[controller]->SetValue(tmp); tmp.clear();
tmp << PadMapping[controller].halfpress; m_JoyButtonHalfpress[controller]->SetValue(tmp); tmp.clear(); tmp << PadMapping[controller].halfpress; m_JoyButtonHalfpress[controller]->SetValue(tmp); tmp.clear();
tmp << PadMapping[controller].axis[InputCommon::CTL_MAIN_X]; m_JoyAnalogMainX[controller]->SetValue(tmp); tmp.clear(); tmp << PadMapping[controller].axis[InputCommon::CTL_MAIN_X]; m_JoyAnalogMainX[controller]->SetValue(tmp); tmp.clear();
tmp << PadMapping[controller].axis[InputCommon::CTL_MAIN_Y]; m_JoyAnalogMainY[controller]->SetValue(tmp); tmp.clear(); tmp << PadMapping[controller].axis[InputCommon::CTL_MAIN_Y]; m_JoyAnalogMainY[controller]->SetValue(tmp); tmp.clear();
tmp << PadMapping[controller].axis[InputCommon::CTL_SUB_X]; m_JoyAnalogSubX[controller]->SetValue(tmp); tmp.clear(); tmp << PadMapping[controller].axis[InputCommon::CTL_SUB_X]; m_JoyAnalogSubX[controller]->SetValue(tmp); tmp.clear();
tmp << PadMapping[controller].axis[InputCommon::CTL_SUB_Y]; m_JoyAnalogSubY[controller]->SetValue(tmp); tmp.clear(); tmp << PadMapping[controller].axis[InputCommon::CTL_SUB_Y]; m_JoyAnalogSubY[controller]->SetValue(tmp); tmp.clear();
// Update the deadzone and controller type controls // Update the deadzone and controller type controls
m_ControlType[controller]->SetSelection(PadMapping[controller].controllertype); m_ControlType[controller]->SetSelection(PadMapping[controller].controllertype);
m_TriggerType[controller]->SetSelection(PadMapping[controller].triggertype); m_TriggerType[controller]->SetSelection(PadMapping[controller].triggertype);
m_Deadzone[controller]->SetSelection(PadMapping[controller].deadzone); m_Deadzone[controller]->SetSelection(PadMapping[controller].deadzone);
m_CoBDiagonal[controller]->SetValue(wxString::FromAscii(PadMapping[controller].SDiagonal.c_str())); m_CoBDiagonal[controller]->SetValue(wxString::FromAscii(PadMapping[controller].SDiagonal.c_str()));
m_CBS_to_C[controller]->SetValue(PadMapping[controller].bSquareToCircle); m_CBS_to_C[controller]->SetValue(PadMapping[controller].bSquareToCircle);
m_AdvancedMapFilter[controller]->SetValue(g_Config.bNoTriggerFilter); m_AdvancedMapFilter[controller]->SetValue(g_Config.bNoTriggerFilter);
#ifdef RERECORDING #ifdef RERECORDING
m_CheckRecording[controller]->SetValue(g_Config.bRecording); m_CheckRecording[controller]->SetValue(g_Config.bRecording);
m_CheckPlayback[controller]->SetValue(g_Config.bPlayback); m_CheckPlayback[controller]->SetValue(g_Config.bPlayback);
#endif #endif
//LogMsg("m_TriggerType[%i] = %i\n", controller, PadMapping[controller].triggertype); //LogMsg("m_TriggerType[%i] = %i\n", controller, PadMapping[controller].triggertype);
// Update D-Pad // Update D-Pad
if(PadMapping[controller].controllertype == InputCommon::CTL_DPAD_HAT) if(PadMapping[controller].controllertype == InputCommon::CTL_DPAD_HAT)
{ {
tmp << PadMapping[controller].dpad; m_JoyDpadDown[controller]->SetValue(tmp); tmp.clear(); tmp << PadMapping[controller].dpad; m_JoyDpadDown[controller]->SetValue(tmp); tmp.clear();
} }
else else
{ {
tmp << PadMapping[controller].dpad2[InputCommon::CTL_D_PAD_UP]; m_JoyDpadUp[controller]->SetValue(tmp); tmp.clear(); tmp << PadMapping[controller].dpad2[InputCommon::CTL_D_PAD_UP]; m_JoyDpadUp[controller]->SetValue(tmp); tmp.clear();
tmp << PadMapping[controller].dpad2[InputCommon::CTL_D_PAD_DOWN]; m_JoyDpadDown[controller]->SetValue(tmp); tmp.clear(); tmp << PadMapping[controller].dpad2[InputCommon::CTL_D_PAD_DOWN]; m_JoyDpadDown[controller]->SetValue(tmp); tmp.clear();
tmp << PadMapping[controller].dpad2[InputCommon::CTL_D_PAD_LEFT]; m_JoyDpadLeft[controller]->SetValue(tmp); tmp.clear(); tmp << PadMapping[controller].dpad2[InputCommon::CTL_D_PAD_LEFT]; m_JoyDpadLeft[controller]->SetValue(tmp); tmp.clear();
tmp << PadMapping[controller].dpad2[InputCommon::CTL_D_PAD_RIGHT]; m_JoyDpadRight[controller]->SetValue(tmp); tmp.clear(); tmp << PadMapping[controller].dpad2[InputCommon::CTL_D_PAD_RIGHT]; m_JoyDpadRight[controller]->SetValue(tmp); tmp.clear();
} }
// Replace "-1" with "" in the GUI controls // Replace "-1" with "" in the GUI controls
//if(ControlsCreated) ToBlank(); //if(ControlsCreated) ToBlank();
} }
/* Populate the PadMapping array with the dialog items settings (for example /* Populate the PadMapping array with the dialog items settings (for example
selected joystick, enabled or disabled status and so on) */ selected joystick, enabled or disabled status and so on) */
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void ConfigBox::SaveButtonMapping(int controller, bool DontChangeId, int FromSlot) void ConfigBox::SaveButtonMapping(int controller, bool DontChangeId, int FromSlot)
{ {
// Temporary storage // Temporary storage
wxString tmp; wxString tmp;
long value; long value;
// Save from or to the same or different slots // Save from or to the same or different slots
if (FromSlot == -1) FromSlot = controller; if (FromSlot == -1) FromSlot = controller;
// Replace "" with "-1" in the GUI controls // Replace "" with "-1" in the GUI controls
ToBlank(false); ToBlank(false);
// Set enabled or disable status and other settings // Set enabled or disable status and other settings
if(!DontChangeId) PadMapping[controller].ID = m_Joyname[FromSlot]->GetSelection(); if(!DontChangeId) PadMapping[controller].ID = m_Joyname[FromSlot]->GetSelection();
if(FromSlot == controller) PadMapping[controller].enabled = m_Joyattach[FromSlot]->GetValue(); // Only enable one if(FromSlot == controller) PadMapping[controller].enabled = m_Joyattach[FromSlot]->GetValue(); // Only enable one
PadMapping[controller].controllertype = m_ControlType[FromSlot]->GetSelection(); PadMapping[controller].controllertype = m_ControlType[FromSlot]->GetSelection();
PadMapping[controller].triggertype = m_TriggerType[FromSlot]->GetSelection(); PadMapping[controller].triggertype = m_TriggerType[FromSlot]->GetSelection();
PadMapping[controller].deadzone = m_Deadzone[FromSlot]->GetSelection(); PadMapping[controller].deadzone = m_Deadzone[FromSlot]->GetSelection();
PadMapping[controller].SDiagonal = m_CoBDiagonal[FromSlot]->GetLabel().mb_str(); PadMapping[controller].SDiagonal = m_CoBDiagonal[FromSlot]->GetLabel().mb_str();
PadMapping[controller].bSquareToCircle = m_CBS_to_C[FromSlot]->IsChecked(); PadMapping[controller].bSquareToCircle = m_CBS_to_C[FromSlot]->IsChecked();
// The analog buttons // The analog buttons
m_JoyAnalogMainX[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].axis[InputCommon::CTL_MAIN_X] = value; tmp.clear(); m_JoyAnalogMainX[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].axis[InputCommon::CTL_MAIN_X] = value; tmp.clear();
m_JoyAnalogMainY[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].axis[InputCommon::CTL_MAIN_Y] = value; tmp.clear(); m_JoyAnalogMainY[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].axis[InputCommon::CTL_MAIN_Y] = value; tmp.clear();
m_JoyAnalogSubX[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].axis[InputCommon::CTL_SUB_X] = value; tmp.clear(); m_JoyAnalogSubX[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].axis[InputCommon::CTL_SUB_X] = value; tmp.clear();
m_JoyAnalogSubY[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].axis[InputCommon::CTL_SUB_Y] = value; tmp.clear(); m_JoyAnalogSubY[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].axis[InputCommon::CTL_SUB_Y] = value; tmp.clear();
// The shoulder buttons // The shoulder buttons
m_JoyShoulderL[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[InputCommon::CTL_L_SHOULDER] = value; m_JoyShoulderL[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[InputCommon::CTL_L_SHOULDER] = value;
m_JoyShoulderR[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[InputCommon::CTL_R_SHOULDER] = value; m_JoyShoulderR[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[InputCommon::CTL_R_SHOULDER] = value;
// The digital buttons // The digital buttons
m_JoyButtonA[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[InputCommon::CTL_A_BUTTON] = value; tmp.clear(); m_JoyButtonA[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[InputCommon::CTL_A_BUTTON] = value; tmp.clear();
m_JoyButtonB[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[InputCommon::CTL_B_BUTTON] = value; tmp.clear(); m_JoyButtonB[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[InputCommon::CTL_B_BUTTON] = value; tmp.clear();
m_JoyButtonX[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[InputCommon::CTL_X_BUTTON] = value; tmp.clear(); m_JoyButtonX[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[InputCommon::CTL_X_BUTTON] = value; tmp.clear();
m_JoyButtonY[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[InputCommon::CTL_Y_BUTTON] = value; tmp.clear(); m_JoyButtonY[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[InputCommon::CTL_Y_BUTTON] = value; tmp.clear();
m_JoyButtonZ[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[InputCommon::CTL_Z_TRIGGER] = value; tmp.clear(); m_JoyButtonZ[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[InputCommon::CTL_Z_TRIGGER] = value; tmp.clear();
m_JoyButtonStart[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[InputCommon::CTL_START] = value; tmp.clear(); m_JoyButtonStart[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].buttons[InputCommon::CTL_START] = value; tmp.clear();
//LogMsg("PadMapping[%i].triggertype = %i, m_TriggerType[%i]->GetSelection() = %i\n", //LogMsg("PadMapping[%i].triggertype = %i, m_TriggerType[%i]->GetSelection() = %i\n",
// controller, PadMapping[controller].triggertype, FromSlot, m_TriggerType[FromSlot]->GetSelection()); // controller, PadMapping[controller].triggertype, FromSlot, m_TriggerType[FromSlot]->GetSelection());
// The halfpress button // The halfpress button
m_JoyButtonHalfpress[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].halfpress = value; tmp.clear(); m_JoyButtonHalfpress[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].halfpress = value; tmp.clear();
// The digital pad // The digital pad
if(PadMapping[controller].controllertype == InputCommon::CTL_DPAD_HAT) if(PadMapping[controller].controllertype == InputCommon::CTL_DPAD_HAT)
{ {
m_JoyDpadDown[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].dpad = value; tmp.clear(); m_JoyDpadDown[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].dpad = value; tmp.clear();
} }
else else
{ {
m_JoyDpadUp[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].dpad2[InputCommon::CTL_D_PAD_UP] = value; tmp.clear(); m_JoyDpadUp[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].dpad2[InputCommon::CTL_D_PAD_UP] = value; tmp.clear();
m_JoyDpadDown[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].dpad2[InputCommon::CTL_D_PAD_DOWN] = value; tmp.clear(); m_JoyDpadDown[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].dpad2[InputCommon::CTL_D_PAD_DOWN] = value; tmp.clear();
m_JoyDpadLeft[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].dpad2[InputCommon::CTL_D_PAD_LEFT] = value; tmp.clear(); m_JoyDpadLeft[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].dpad2[InputCommon::CTL_D_PAD_LEFT] = value; tmp.clear();
m_JoyDpadRight[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].dpad2[InputCommon::CTL_D_PAD_RIGHT] = value; tmp.clear(); m_JoyDpadRight[FromSlot]->GetValue().ToLong(&value); PadMapping[controller].dpad2[InputCommon::CTL_D_PAD_RIGHT] = value; tmp.clear();
} }
// Replace "-1" with "" // Replace "-1" with ""
ToBlank(); ToBlank();
} }
// Update the textbox for the buttons // Update the textbox for the buttons
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void ConfigBox::SetButtonText(int id, char text[128], int Page) void ConfigBox::SetButtonText(int id, char text[128], int Page)
{ {
// Set controller value // Set controller value
int controller; int controller;
if (Page == -1) controller = notebookpage; else controller = Page; if (Page == -1) controller = notebookpage; else controller = Page;
switch(id) switch(id)
{ {
case IDB_DPAD_RIGHT: m_JoyDpadRight[controller]->SetValue(wxString::FromAscii(text)); break; case IDB_DPAD_RIGHT: m_JoyDpadRight[controller]->SetValue(wxString::FromAscii(text)); break;
case IDB_DPAD_UP: m_JoyDpadUp[controller]->SetValue(wxString::FromAscii(text)); break; case IDB_DPAD_UP: m_JoyDpadUp[controller]->SetValue(wxString::FromAscii(text)); break;
case IDB_DPAD_DOWN: m_JoyDpadDown[controller]->SetValue(wxString::FromAscii(text)); break; case IDB_DPAD_DOWN: m_JoyDpadDown[controller]->SetValue(wxString::FromAscii(text)); break;
case IDB_DPAD_LEFT: m_JoyDpadLeft[controller]->SetValue(wxString::FromAscii(text)); break; case IDB_DPAD_LEFT: m_JoyDpadLeft[controller]->SetValue(wxString::FromAscii(text)); break;
case IDB_ANALOG_MAIN_X: m_JoyAnalogMainX[controller]->SetValue(wxString::FromAscii(text)); break; case IDB_ANALOG_MAIN_X: m_JoyAnalogMainX[controller]->SetValue(wxString::FromAscii(text)); break;
case IDB_ANALOG_MAIN_Y: m_JoyAnalogMainY[controller]->SetValue(wxString::FromAscii(text)); break; case IDB_ANALOG_MAIN_Y: m_JoyAnalogMainY[controller]->SetValue(wxString::FromAscii(text)); break;
case IDB_ANALOG_SUB_X: m_JoyAnalogSubX[controller]->SetValue(wxString::FromAscii(text)); break; case IDB_ANALOG_SUB_X: m_JoyAnalogSubX[controller]->SetValue(wxString::FromAscii(text)); break;
case IDB_ANALOG_SUB_Y: m_JoyAnalogSubY[controller]->SetValue(wxString::FromAscii(text)); break; case IDB_ANALOG_SUB_Y: m_JoyAnalogSubY[controller]->SetValue(wxString::FromAscii(text)); break;
case IDB_SHOULDER_L: m_JoyShoulderL[controller]->SetValue(wxString::FromAscii(text)); break; case IDB_SHOULDER_L: m_JoyShoulderL[controller]->SetValue(wxString::FromAscii(text)); break;
case IDB_SHOULDER_R: m_JoyShoulderR[controller]->SetValue(wxString::FromAscii(text)); break; case IDB_SHOULDER_R: m_JoyShoulderR[controller]->SetValue(wxString::FromAscii(text)); break;
case IDB_BUTTON_A: m_JoyButtonA[controller]->SetValue(wxString::FromAscii(text)); break; case IDB_BUTTON_A: m_JoyButtonA[controller]->SetValue(wxString::FromAscii(text)); break;
case IDB_BUTTON_B: m_JoyButtonB[controller]->SetValue(wxString::FromAscii(text)); break; case IDB_BUTTON_B: m_JoyButtonB[controller]->SetValue(wxString::FromAscii(text)); break;
case IDB_BUTTON_X: m_JoyButtonX[controller]->SetValue(wxString::FromAscii(text)); break; case IDB_BUTTON_X: m_JoyButtonX[controller]->SetValue(wxString::FromAscii(text)); break;
case IDB_BUTTON_Y: m_JoyButtonY[controller]->SetValue(wxString::FromAscii(text)); break; case IDB_BUTTON_Y: m_JoyButtonY[controller]->SetValue(wxString::FromAscii(text)); break;
case IDB_BUTTON_Z: m_JoyButtonZ[controller]->SetValue(wxString::FromAscii(text)); break; case IDB_BUTTON_Z: m_JoyButtonZ[controller]->SetValue(wxString::FromAscii(text)); break;
case IDB_BUTTONSTART: m_JoyButtonStart[controller]->SetValue(wxString::FromAscii(text)); break; case IDB_BUTTONSTART: m_JoyButtonStart[controller]->SetValue(wxString::FromAscii(text)); break;
case IDB_BUTTONHALFPRESS: m_JoyButtonHalfpress[controller]->SetValue(wxString::FromAscii(text)); break; case IDB_BUTTONHALFPRESS: m_JoyButtonHalfpress[controller]->SetValue(wxString::FromAscii(text)); break;
default: break; default: break;
} }
} }
// Get the text in the textbox for the buttons // Get the text in the textbox for the buttons
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
wxString ConfigBox::GetButtonText(int id, int Page) wxString ConfigBox::GetButtonText(int id, int Page)
{ {
// Set controller value // Set controller value
int controller; int controller;
if (Page == -1) controller = notebookpage; else controller = Page; if (Page == -1) controller = notebookpage; else controller = Page;
switch(id) switch(id)
{ {
// D-Pad // D-Pad
case IDB_DPAD_RIGHT: return m_JoyDpadRight[controller]->GetValue(); case IDB_DPAD_RIGHT: return m_JoyDpadRight[controller]->GetValue();
case IDB_DPAD_UP: return m_JoyDpadUp[controller]->GetValue(); case IDB_DPAD_UP: return m_JoyDpadUp[controller]->GetValue();
case IDB_DPAD_DOWN: return m_JoyDpadDown[controller]->GetValue(); case IDB_DPAD_DOWN: return m_JoyDpadDown[controller]->GetValue();
case IDB_DPAD_LEFT: return m_JoyDpadLeft[controller]->GetValue(); case IDB_DPAD_LEFT: return m_JoyDpadLeft[controller]->GetValue();
// Analog Stick // Analog Stick
case IDB_ANALOG_MAIN_X: return m_JoyAnalogMainX[controller]->GetValue(); case IDB_ANALOG_MAIN_X: return m_JoyAnalogMainX[controller]->GetValue();
case IDB_ANALOG_MAIN_Y: return m_JoyAnalogMainY[controller]->GetValue(); case IDB_ANALOG_MAIN_Y: return m_JoyAnalogMainY[controller]->GetValue();
case IDB_ANALOG_SUB_X: return m_JoyAnalogSubX[controller]->GetValue(); case IDB_ANALOG_SUB_X: return m_JoyAnalogSubX[controller]->GetValue();
case IDB_ANALOG_SUB_Y: return m_JoyAnalogSubY[controller]->GetValue(); case IDB_ANALOG_SUB_Y: return m_JoyAnalogSubY[controller]->GetValue();
// Shoulder Buttons // Shoulder Buttons
case IDB_SHOULDER_L: return m_JoyShoulderL[controller]->GetValue(); case IDB_SHOULDER_L: return m_JoyShoulderL[controller]->GetValue();
case IDB_SHOULDER_R: return m_JoyShoulderR[controller]->GetValue(); case IDB_SHOULDER_R: return m_JoyShoulderR[controller]->GetValue();
// Buttons // Buttons
case IDB_BUTTON_A: return m_JoyButtonA[controller]->GetValue(); case IDB_BUTTON_A: return m_JoyButtonA[controller]->GetValue();
case IDB_BUTTON_B: return m_JoyButtonB[controller]->GetValue(); case IDB_BUTTON_B: return m_JoyButtonB[controller]->GetValue();
case IDB_BUTTON_X: return m_JoyButtonX[controller]->GetValue(); case IDB_BUTTON_X: return m_JoyButtonX[controller]->GetValue();
case IDB_BUTTON_Y: return m_JoyButtonY[controller]->GetValue(); case IDB_BUTTON_Y: return m_JoyButtonY[controller]->GetValue();
case IDB_BUTTON_Z: return m_JoyButtonZ[controller]->GetValue(); case IDB_BUTTON_Z: return m_JoyButtonZ[controller]->GetValue();
case IDB_BUTTONSTART: return m_JoyButtonStart[controller]->GetValue(); case IDB_BUTTONSTART: return m_JoyButtonStart[controller]->GetValue();
case IDB_BUTTONHALFPRESS: return m_JoyButtonHalfpress[controller]->GetValue(); case IDB_BUTTONHALFPRESS: return m_JoyButtonHalfpress[controller]->GetValue();
default: return wxString(); default: return wxString();
} }
} }
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Configure button mapping // Configure button mapping
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// Wait for button press // Wait for button press
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/* Loop or timer: There are basically two ways to do this. With a while() or for() loop, or with a /* Loop or timer: There are basically two ways to do this. With a while() or for() loop, or with a
timer. The downside with the while() or for() loop is that there is no way to stop it if the user timer. The downside with the while() or for() loop is that there is no way to stop it if the user
should select to configure another button while we are still in an old loop. What will happen then should select to configure another button while we are still in an old loop. What will happen then
is that we start another parallel loop (at least in Windows) that blocks the old loop. And our only is that we start another parallel loop (at least in Windows) that blocks the old loop. And our only
option to wait for the old loop to finish is with a new loop, and that will block the old loop for as option to wait for the old loop to finish is with a new loop, and that will block the old loop for as
long as it's going on. Therefore a timer is easier to control. */ long as it's going on. Therefore a timer is easier to control. */
void ConfigBox::GetButtons(wxCommandEvent& event) void ConfigBox::GetButtons(wxCommandEvent& event)
{ {
DoGetButtons(event.GetId()); DoGetButtons(event.GetId());
} }
void ConfigBox::DoGetButtons(int GetId) void ConfigBox::DoGetButtons(int GetId)
{ {
// ============================================= // =============================================
// Collect the starting values // Collect the starting values
// ---------------- // ----------------
// Get the current controller // Get the current controller
int Controller = notebookpage; int Controller = notebookpage;
int PadID = PadMapping[Controller].ID; int PadID = PadMapping[Controller].ID;
// Create a shortcut for the pad handle // Create a shortcut for the pad handle
SDL_Joystick *joy = PadState[Controller].joy; SDL_Joystick *joy = PadState[Controller].joy;
// Get the number of axes, hats and buttons // Get the number of axes, hats and buttons
int Buttons = SDL_JoystickNumButtons(joy); int Buttons = SDL_JoystickNumButtons(joy);
int Axes = SDL_JoystickNumAxes(joy); int Axes = SDL_JoystickNumAxes(joy);
int Hats = SDL_JoystickNumHats(joy); int Hats = SDL_JoystickNumHats(joy);
Console::Print("PadID: %i Axes: %i\n", PadID, joyinfo[PadID].NumAxes, joyinfo[PadID].joy); Console::Print("PadID: %i Axes: %i\n", PadID, joyinfo[PadID].NumAxes, joyinfo[PadID].joy);
// Get the controller and trigger type // Get the controller and trigger type
int ControllerType = PadMapping[Controller].controllertype; int ControllerType = PadMapping[Controller].controllertype;
int TriggerType = PadMapping[Controller].triggertype; int TriggerType = PadMapping[Controller].triggertype;
// Collect the accepted buttons for this slot // Collect the accepted buttons for this slot
bool LeftRight = (GetId == IDB_SHOULDER_L || GetId == IDB_SHOULDER_R); bool LeftRight = (GetId == IDB_SHOULDER_L || GetId == IDB_SHOULDER_R);
bool Axis = (GetId >= IDB_ANALOG_MAIN_X && GetId <= IDB_SHOULDER_R) bool Axis = (GetId >= IDB_ANALOG_MAIN_X && GetId <= IDB_SHOULDER_R)
// Don't allow SDL input for the triggers when XInput is selected // Don't allow SDL input for the triggers when XInput is selected
&& !(TriggerType == InputCommon::CTL_TRIGGER_XINPUT && (GetId == IDB_SHOULDER_L || GetId == IDB_SHOULDER_R) ); && !(TriggerType == InputCommon::CTL_TRIGGER_XINPUT && (GetId == IDB_SHOULDER_L || GetId == IDB_SHOULDER_R) );
bool XInput = (TriggerType == InputCommon::CTL_TRIGGER_XINPUT); bool XInput = (TriggerType == InputCommon::CTL_TRIGGER_XINPUT);
bool Button = (GetId >= IDB_BUTTON_A && GetId <= IDB_BUTTONHALFPRESS) // All digital buttons bool Button = (GetId >= IDB_BUTTON_A && GetId <= IDB_BUTTONHALFPRESS) // All digital buttons
|| (GetId == IDB_SHOULDER_L || GetId == IDB_SHOULDER_R) // both shoulder buttons || (GetId == IDB_SHOULDER_L || GetId == IDB_SHOULDER_R) // both shoulder buttons
|| (GetId >= IDB_DPAD_UP && GetId <= IDB_DPAD_RIGHT && ControllerType == InputCommon::CTL_DPAD_CUSTOM); // Or the custom hat mode || (GetId >= IDB_DPAD_UP && GetId <= IDB_DPAD_RIGHT && ControllerType == InputCommon::CTL_DPAD_CUSTOM); // Or the custom hat mode
bool Hat = (GetId >= IDB_DPAD_UP && GetId <= IDB_DPAD_RIGHT) // All DPads bool Hat = (GetId >= IDB_DPAD_UP && GetId <= IDB_DPAD_RIGHT) // All DPads
&& (PadMapping[Controller].controllertype == InputCommon::CTL_DPAD_HAT); // Not with the hat option defined && (PadMapping[Controller].controllertype == InputCommon::CTL_DPAD_HAT); // Not with the hat option defined
bool NoTriggerFilter = g_Config.bNoTriggerFilter; bool NoTriggerFilter = g_Config.bNoTriggerFilter;
// Values used in this function // Values used in this function
char format[128]; char format[128];
int Seconds = 4; // Seconds to wait for int Seconds = 4; // Seconds to wait for
int TimesPerSecond = 40; // How often to run the check int TimesPerSecond = 40; // How often to run the check
// Values returned from InputCommon::GetButton() // Values returned from InputCommon::GetButton()
int value; // Axis value int value; // Axis value
int type; // Button type int type; // Button type
int pressed = 0; int pressed = 0;
bool Succeed = false; bool Succeed = false;
bool Stop = false; // Stop the timer bool Stop = false; // Stop the timer
// ======================= // =======================
//Console::Print("Before (%i) Id:%i %i IsRunning:%i\n", //Console::Print("Before (%i) Id:%i %i IsRunning:%i\n",
// GetButtonWaitingTimer, GetButtonWaitingID, GetId, m_ButtonMappingTimer->IsRunning()); // GetButtonWaitingTimer, GetButtonWaitingID, GetId, m_ButtonMappingTimer->IsRunning());
// If the Id has changed or the timer is not running we should start one // If the Id has changed or the timer is not running we should start one
if( GetButtonWaitingID != GetId || !m_ButtonMappingTimer->IsRunning() ) if( GetButtonWaitingID != GetId || !m_ButtonMappingTimer->IsRunning() )
{ {
if(m_ButtonMappingTimer->IsRunning()) if(m_ButtonMappingTimer->IsRunning())
{ {
m_ButtonMappingTimer->Stop(); m_ButtonMappingTimer->Stop();
GetButtonWaitingTimer = 0; GetButtonWaitingTimer = 0;
// Update the old textbox // Update the old textbox
SetButtonText(GetButtonWaitingID, ""); SetButtonText(GetButtonWaitingID, "");
} }
// Save the button Id // Save the button Id
GetButtonWaitingID = GetId; GetButtonWaitingID = GetId;
// Reset the key in case we happen to have an old one // Reset the key in case we happen to have an old one
g_Pressed = 0; g_Pressed = 0;
// Update the text box // Update the text box
sprintf(format, "[%d]", Seconds); sprintf(format, "[%d]", Seconds);
SetButtonText(GetId, format); SetButtonText(GetId, format);
// Start the timer // Start the timer
#if wxUSE_TIMER #if wxUSE_TIMER
m_ButtonMappingTimer->Start( floor((double)(1000 / TimesPerSecond)) ); m_ButtonMappingTimer->Start( floor((double)(1000 / TimesPerSecond)) );
#endif #endif
} }
// =============================================== // ===============================================
// Check for buttons // Check for buttons
// ---------------- // ----------------
// If there is a timer but we should not create a new one // If there is a timer but we should not create a new one
else else
{ {
InputCommon::GetButton( InputCommon::GetButton(
joy, PadID, Buttons, Axes, Hats, joy, PadID, Buttons, Axes, Hats,
g_Pressed, value, type, pressed, Succeed, Stop, g_Pressed, value, type, pressed, Succeed, Stop,
LeftRight, Axis, XInput, Button, Hat, NoTriggerFilter); LeftRight, Axis, XInput, Button, Hat, NoTriggerFilter);
} }
// ========================= Check for keys // ========================= Check for keys
// =============================================== // ===============================================
// Process results // Process results
// ---------------- // ----------------
// Count each time // Count each time
GetButtonWaitingTimer++; GetButtonWaitingTimer++;
// This is run every second // This is run every second
if(GetButtonWaitingTimer % TimesPerSecond == 0) if(GetButtonWaitingTimer % TimesPerSecond == 0)
{ {
// Current time // Current time
int TmpTime = Seconds - (GetButtonWaitingTimer / TimesPerSecond); int TmpTime = Seconds - (GetButtonWaitingTimer / TimesPerSecond);
// Update text // Update text
sprintf(format, "[%d]", TmpTime); sprintf(format, "[%d]", TmpTime);
SetButtonText(GetId, format); SetButtonText(GetId, format);
} }
// Time's up // Time's up
if( (GetButtonWaitingTimer / TimesPerSecond) >= Seconds ) if( (GetButtonWaitingTimer / TimesPerSecond) >= Seconds )
{ {
Stop = true; Stop = true;
// Leave a blank mapping // Leave a blank mapping
if(g_Config.bSaveByID) SetButtonTextAll(GetId, "-1"); else SetButtonText(GetId, "-1"); if(g_Config.bSaveByID) SetButtonTextAll(GetId, "-1"); else SetButtonText(GetId, "-1");
} }
// If we got a button // If we got a button
if(Succeed) if(Succeed)
{ {
Stop = true; Stop = true;
// Write the number of the pressed button to the text box // Write the number of the pressed button to the text box
sprintf(format, "%d", pressed); sprintf(format, "%d", pressed);
if(g_Config.bSaveByID) SetButtonTextAll(GetId, format); else SetButtonText(GetId, format); if(g_Config.bSaveByID) SetButtonTextAll(GetId, format); else SetButtonText(GetId, format);
} }
// Stop the timer // Stop the timer
if(Stop) if(Stop)
{ {
m_ButtonMappingTimer->Stop(); m_ButtonMappingTimer->Stop();
GetButtonWaitingTimer = 0; GetButtonWaitingTimer = 0;
/* Update the button mapping for all slots that use this device. (It doesn't make sense to have several slots /* Update the button mapping for all slots that use this device. (It doesn't make sense to have several slots
controlled by the same device, but several DirectInput instances of different but identical devices may possible controlled by the same device, but several DirectInput instances of different but identical devices may possible
have the same id, I don't know. So we have to do this. The user may also have selected the same device for have the same id, I don't know. So we have to do this. The user may also have selected the same device for
several disabled slots. */ several disabled slots. */
if(g_Config.bSaveByID) SaveButtonMappingAll(Controller); else SaveButtonMapping(Controller); if(g_Config.bSaveByID) SaveButtonMappingAll(Controller); else SaveButtonMapping(Controller);
} }
// If we got a bad button // If we got a bad button
if(g_Pressed == -1) if(g_Pressed == -1)
{ {
// Update text // Update text
if(g_Config.bSaveByID) SetButtonTextAll(GetId, "-1"); else SetButtonText(GetId, "-1"); if(g_Config.bSaveByID) SetButtonTextAll(GetId, "-1"); else SetButtonText(GetId, "-1");
// Notify the user // Notify the user
wxMessageBox(wxString::Format(wxT( wxMessageBox(wxString::Format(wxT(
"You selected a key with a to low key code (%i), please" "You selected a key with a to low key code (%i), please"
" select another key with a higher key code."), pressed) " select another key with a higher key code."), pressed)
, wxT("Notice"), wxICON_INFORMATION); , wxT("Notice"), wxICON_INFORMATION);
} }
// ======================== Process results // ======================== Process results
// Debugging // Debugging
/* /*
Console::Print("Change: %i %i %i %i '%s' '%s' '%s' '%s'\n", Console::Print("Change: %i %i %i %i '%s' '%s' '%s' '%s'\n",
PadMapping[0].halfpress, PadMapping[1].halfpress, PadMapping[2].halfpress, PadMapping[3].halfpress, PadMapping[0].halfpress, PadMapping[1].halfpress, PadMapping[2].halfpress, PadMapping[3].halfpress,
m_JoyButtonHalfpress[0]->GetValue().c_str(), m_JoyButtonHalfpress[1]->GetValue().c_str(), m_JoyButtonHalfpress[2]->GetValue().c_str(), m_JoyButtonHalfpress[3]->GetValue().c_str() m_JoyButtonHalfpress[0]->GetValue().c_str(), m_JoyButtonHalfpress[1]->GetValue().c_str(), m_JoyButtonHalfpress[2]->GetValue().c_str(), m_JoyButtonHalfpress[3]->GetValue().c_str()
);*/ );*/
} }
/////////////////////////////////////////////////////////// Configure button mapping /////////////////////////////////////////////////////////// Configure button mapping

View File

@ -1,195 +1,195 @@
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Project description // Project description
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// Name: nJoy // Name: nJoy
// Description: A Dolphin Compatible Input Plugin // Description: A Dolphin Compatible Input Plugin
// //
// Author: Falcon4ever (nJoy@falcon4ever.com) // Author: Falcon4ever (nJoy@falcon4ever.com)
// Site: www.multigesture.net // Site: www.multigesture.net
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2008 Dolphin Project.
// //
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// //
// Licensetype: GNU General Public License (GPL) // Licensetype: GNU General Public License (GPL)
// //
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0. // the Free Software Foundation, version 2.0.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details. // GNU General Public License 2.0 for more details.
// //
// A copy of the GPL 2.0 should have been included with the program. // A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/ // If not, see http://www.gnu.org/licenses/
// //
// Official SVN repository and contact information can be found at // Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
// //
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// File description // File description
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> /* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
Rerecording options Rerecording options
////////////////////////*/ ////////////////////////*/
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Include // Include
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#include "nJoy.h" #include "nJoy.h"
#include "FileUtil.h" #include "FileUtil.h"
#include "ChunkFile.h" #include "ChunkFile.h"
///////////////////////// /////////////////////////
#ifdef RERECORDING #ifdef RERECORDING
namespace Recording namespace Recording
{ {
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Definitions // Definitions
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// Pre defined maxium storage limit // Pre defined maxium storage limit
#define RECORD_SIZE (1024 * 128) #define RECORD_SIZE (1024 * 128)
SPADStatus RecordBuffer[RECORD_SIZE]; SPADStatus RecordBuffer[RECORD_SIZE];
int count = 0; int count = 0;
//////////////////////////////// ////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Recording functions // Recording functions
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void RecordInput(const SPADStatus& _rPADStatus) void RecordInput(const SPADStatus& _rPADStatus)
{ {
if (count >= RECORD_SIZE) return; if (count >= RECORD_SIZE) return;
RecordBuffer[count++] = _rPADStatus; RecordBuffer[count++] = _rPADStatus;
// Logging // Logging
//u8 TmpData[sizeof(SPADStatus)]; //u8 TmpData[sizeof(SPADStatus)];
//memcpy(TmpData, &RecordBuffer[count - 1], sizeof(SPADStatus)); //memcpy(TmpData, &RecordBuffer[count - 1], sizeof(SPADStatus));
//Console::Print("RecordInput(%i): %s\n", count, ArrayToString(TmpData, sizeof(SPADStatus), 0, 30).c_str()); //Console::Print("RecordInput(%i): %s\n", count, ArrayToString(TmpData, sizeof(SPADStatus), 0, 30).c_str());
// Auto save every ten seconds // Auto save every ten seconds
if (count % (60 * 10) == 0) Save(); if (count % (60 * 10) == 0) Save();
} }
const SPADStatus& Play() const SPADStatus& Play()
{ {
// Logging // Logging
//Console::Print("PlayRecord(%i)\n", count); //Console::Print("PlayRecord(%i)\n", count);
if (count >= RECORD_SIZE) if (count >= RECORD_SIZE)
{ {
// Todo: Make the recording size unlimited? // Todo: Make the recording size unlimited?
//PanicAlert("The recording reached its end"); //PanicAlert("The recording reached its end");
return(RecordBuffer[0]); return(RecordBuffer[0]);
} }
return(RecordBuffer[count++]); return(RecordBuffer[count++]);
} }
void Load() void Load()
{ {
FILE* pStream = fopen("pad-record.bin", "rb"); FILE* pStream = fopen("pad-record.bin", "rb");
if (pStream != NULL) if (pStream != NULL)
{ {
fread(RecordBuffer, 1, RECORD_SIZE * sizeof(SPADStatus), pStream); fread(RecordBuffer, 1, RECORD_SIZE * sizeof(SPADStatus), pStream);
fclose(pStream); fclose(pStream);
} }
else else
{ {
PanicAlert("SimplePad: Could not open pad-record.bin"); PanicAlert("SimplePad: Could not open pad-record.bin");
} }
//Console::Print("LoadRecord()"); //Console::Print("LoadRecord()");
} }
void Save() void Save()
{ {
// Open the file in a way that clears all old data // Open the file in a way that clears all old data
FILE* pStream = fopen("pad-record.bin", "wb"); FILE* pStream = fopen("pad-record.bin", "wb");
if (pStream != NULL) if (pStream != NULL)
{ {
fwrite(RecordBuffer, 1, RECORD_SIZE * sizeof(SPADStatus), pStream); fwrite(RecordBuffer, 1, RECORD_SIZE * sizeof(SPADStatus), pStream);
fclose(pStream); fclose(pStream);
} }
else else
{ {
PanicAlert("NJoy: Could not save pad-record.bin"); PanicAlert("NJoy: Could not save pad-record.bin");
} }
//PanicAlert("SaveRecord()"); //PanicAlert("SaveRecord()");
//Console::Print("SaveRecord()"); //Console::Print("SaveRecord()");
} }
//////////////////////////////// ////////////////////////////////
void Initialize() void Initialize()
{ {
// ------------------------------------------- // -------------------------------------------
// Rerecording // Rerecording
// ---------------------- // ----------------------
#ifdef RERECORDING #ifdef RERECORDING
/* Check if we are starting the pad to record the input, and an old file exists. In that case ask /* Check if we are starting the pad to record the input, and an old file exists. In that case ask
if we really want to start the recording and eventually overwrite the file */ if we really want to start the recording and eventually overwrite the file */
if (g_Config.bRecording && File::Exists("pad-record.bin")) if (g_Config.bRecording && File::Exists("pad-record.bin"))
{ {
if (!AskYesNo("An old version of '%s' aleady exists in your Dolphin directory. You can" if (!AskYesNo("An old version of '%s' aleady exists in your Dolphin directory. You can"
" now make a copy of it before you start a new recording and overwrite the file." " now make a copy of it before you start a new recording and overwrite the file."
" Select Yes to continue and overwrite the file. Select No to turn off the input" " Select Yes to continue and overwrite the file. Select No to turn off the input"
" recording and continue without recording anything.", " recording and continue without recording anything.",
"pad-record.bin")) "pad-record.bin"))
{ {
// Turn off recording and continue // Turn off recording and continue
g_Config.bRecording = false; g_Config.bRecording = false;
} }
} }
// Load recorded input if we are to play it back, otherwise begin with a blank recording // Load recorded input if we are to play it back, otherwise begin with a blank recording
if (g_Config.bPlayback) Recording::Load(); if (g_Config.bPlayback) Recording::Load();
#endif #endif
// ---------------------- // ----------------------
} }
void ShutDown() void ShutDown()
{ {
// Save recording // Save recording
if (g_Config.bRecording) Recording::Save(); if (g_Config.bRecording) Recording::Save();
// Reset the counter // Reset the counter
count = 0; count = 0;
} }
void DoState(unsigned char **ptr, int mode) void DoState(unsigned char **ptr, int mode)
{ {
// Load or save the counter // Load or save the counter
PointerWrap p(ptr, mode); PointerWrap p(ptr, mode);
p.Do(count); p.Do(count);
//Console::Print("count: %i\n", count); //Console::Print("count: %i\n", count);
// Update the frame counter for the sake of the status bar // Update the frame counter for the sake of the status bar
if (mode == PointerWrap::MODE_READ) if (mode == PointerWrap::MODE_READ)
{ {
#ifdef _WIN32 #ifdef _WIN32
// This only works when rendering to the main window, I think // This only works when rendering to the main window, I think
PostMessage(GetParent(g_PADInitialize->hWnd), WM_USER, INPUT_FRAME_COUNTER, count); PostMessage(GetParent(g_PADInitialize->hWnd), WM_USER, INPUT_FRAME_COUNTER, count);
#endif #endif
} }
} }
} // Recording } // Recording
#endif // RERECORDING #endif // RERECORDING

View File

@ -1,394 +1,394 @@
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Project description // Project description
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// Name: nJoy // Name: nJoy
// Description: A Dolphin Compatible Input Plugin // Description: A Dolphin Compatible Input Plugin
// //
// Author: Falcon4ever (nJoy@falcon4ever.com) // Author: Falcon4ever (nJoy@falcon4ever.com)
// Site: www.multigesture.net // Site: www.multigesture.net
// Copyright (C) 2003-2008 Dolphin Project. // Copyright (C) 2003-2008 Dolphin Project.
// //
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// //
// Licensetype: GNU General Public License (GPL) // Licensetype: GNU General Public License (GPL)
// //
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0. // the Free Software Foundation, version 2.0.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details. // GNU General Public License 2.0 for more details.
// //
// A copy of the GPL 2.0 should have been included with the program. // A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/ // If not, see http://www.gnu.org/licenses/
// //
// Official SVN repository and contact information can be found at // Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
// //
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
//////////////////////// ////////////////////////
// Include // Include
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#include "nJoy.h" #include "nJoy.h"
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Enable or disable rumble. Set USE_RUMBLE_DINPUT_HACK in nJoy.h // Enable or disable rumble. Set USE_RUMBLE_DINPUT_HACK in nJoy.h
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#ifdef USE_RUMBLE_DINPUT_HACK #ifdef USE_RUMBLE_DINPUT_HACK
bool g_rumbleEnable = FALSE; bool g_rumbleEnable = FALSE;
#endif #endif
// Rumble in windows // Rumble in windows
#ifdef _WIN32 #ifdef _WIN32
#ifdef USE_RUMBLE_DINPUT_HACK #ifdef USE_RUMBLE_DINPUT_HACK
LPDIRECTINPUT8 g_pDI = NULL; LPDIRECTINPUT8 g_pDI = NULL;
LPDIRECTINPUTDEVICE8 g_pDevice = NULL; LPDIRECTINPUTDEVICE8 g_pDevice = NULL;
LPDIRECTINPUTEFFECT g_pEffect = NULL; LPDIRECTINPUTEFFECT g_pEffect = NULL;
DWORD g_dwNumForceFeedbackAxis = 0; DWORD g_dwNumForceFeedbackAxis = 0;
INT g_nXForce = 0; INT g_nXForce = 0;
INT g_nYForce = 0; INT g_nYForce = 0;
#define SAFE_RELEASE(p) { if (p) { (p)->Release(); (p)=NULL; } } #define SAFE_RELEASE(p) { if (p) { (p)->Release(); (p)=NULL; } }
HRESULT InitDirectInput(HWND hDlg); HRESULT InitDirectInput(HWND hDlg);
//VOID FreeDirectInput(); //VOID FreeDirectInput();
BOOL CALLBACK EnumFFDevicesCallback(const DIDEVICEINSTANCE* pInst, VOID* pContext); BOOL CALLBACK EnumFFDevicesCallback(const DIDEVICEINSTANCE* pInst, VOID* pContext);
BOOL CALLBACK EnumAxesCallback(const DIDEVICEOBJECTINSTANCE* pdidoi, VOID* pContext); BOOL CALLBACK EnumAxesCallback(const DIDEVICEOBJECTINSTANCE* pdidoi, VOID* pContext);
HRESULT SetDeviceForcesXY(); HRESULT SetDeviceForcesXY();
#endif #endif
#elif defined(__linux__) #elif defined(__linux__)
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <fcntl.h> #include <fcntl.h>
int fd; int fd;
char device_file_name[64]; char device_file_name[64];
struct ff_effect effect; struct ff_effect effect;
bool CanRumble = false; bool CanRumble = false;
#endif #endif
////////////////////// //////////////////////
// Set PAD rumble. Explanation: Stop = 0, Rumble = 1 // Set PAD rumble. Explanation: Stop = 0, Rumble = 1
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void PAD_Rumble(u8 _numPAD, unsigned int _uType, unsigned int _uStrength) void PAD_Rumble(u8 _numPAD, unsigned int _uType, unsigned int _uStrength)
{ {
//if (_numPAD > 0) //if (_numPAD > 0)
// return; // return;
// SDL can't rumble the gamepad so we need to use platform specific code // SDL can't rumble the gamepad so we need to use platform specific code
#ifdef _WIN32 #ifdef _WIN32
#ifdef USE_RUMBLE_DINPUT_HACK #ifdef USE_RUMBLE_DINPUT_HACK
static int a = 0; static int a = 0;
if ((_uType == 0) || (_uType == 2)) if ((_uType == 0) || (_uType == 2))
{ {
a = 0; a = 0;
} }
else if (_uType == 1) else if (_uType == 1)
{ {
a = _uStrength > 2 ? 8000 : 0; a = _uStrength > 2 ? 8000 : 0;
} }
a = int ((float)a * 0.96f); a = int ((float)a * 0.96f);
if (!g_rumbleEnable) if (!g_rumbleEnable)
{ {
a = 0; a = 0;
} }
else else
{ {
g_nYForce = a; g_nYForce = a;
SetDeviceForcesXY(); SetDeviceForcesXY();
} }
#endif #endif
#elif defined(__linux__) #elif defined(__linux__)
struct input_event event; struct input_event event;
if (CanRumble) if (CanRumble)
{ {
if (_uType == 1) if (_uType == 1)
{ {
event.type = EV_FF; event.type = EV_FF;
event.code = effect.id; event.code = effect.id;
event.value = 1; event.value = 1;
if (write(fd, (const void*) &event, sizeof(event)) == -1) { if (write(fd, (const void*) &event, sizeof(event)) == -1) {
perror("Play effect"); perror("Play effect");
exit(1); exit(1);
} }
} }
if ((_uType == 0) || (_uType == 2)) if ((_uType == 0) || (_uType == 2))
{ {
event.type = EV_FF; event.type = EV_FF;
event.code = effect.id; event.code = effect.id;
event.value = 0; event.value = 0;
if (write(fd, (const void*) &event, sizeof(event)) == -1) { if (write(fd, (const void*) &event, sizeof(event)) == -1) {
perror("Stop effect"); perror("Stop effect");
exit(1); exit(1);
} }
} }
} }
#endif #endif
} }
// Use PAD rumble // Use PAD rumble
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void Pad_Use_Rumble(u8 _numPAD, SPADStatus* _pPADStatus) void Pad_Use_Rumble(u8 _numPAD, SPADStatus* _pPADStatus)
{ {
#ifdef _WIN32 #ifdef _WIN32
#ifdef USE_RUMBLE_DINPUT_HACK #ifdef USE_RUMBLE_DINPUT_HACK
// Enable or disable rumble // Enable or disable rumble
if (PadState[_numPAD].halfpress) if (PadState[_numPAD].halfpress)
if (!g_pDI) if (!g_pDI)
if (FAILED(InitDirectInput(m_hWnd))) if (FAILED(InitDirectInput(m_hWnd)))
{ {
MessageBox(NULL, SDL_GetError(), "Could not initialize DirectInput!", MB_ICONERROR); MessageBox(NULL, SDL_GetError(), "Could not initialize DirectInput!", MB_ICONERROR);
g_rumbleEnable = FALSE; g_rumbleEnable = FALSE;
//return; //return;
} }
else else
{ {
g_rumbleEnable = TRUE; g_rumbleEnable = TRUE;
} }
if (g_rumbleEnable) if (g_rumbleEnable)
{ {
g_pDevice->Acquire(); g_pDevice->Acquire();
if (g_pEffect) g_pEffect->Start(1, 0); if (g_pEffect) g_pEffect->Start(1, 0);
} }
#endif #endif
#elif defined(__linux__) #elif defined(__linux__)
if (!fd) if (!fd)
{ {
sprintf(device_file_name, "/dev/input/event%d", PadMapping[_numPAD].eventnum); //TODO: Make dynamic // sprintf(device_file_name, "/dev/input/event%d", PadMapping[_numPAD].eventnum); //TODO: Make dynamic //
/* Open device */ /* Open device */
fd = open(device_file_name, O_RDWR); fd = open(device_file_name, O_RDWR);
if (fd == -1) { if (fd == -1) {
perror("Open device file"); perror("Open device file");
//Something wrong, probably permissions, just return now //Something wrong, probably permissions, just return now
return; return;
} }
int n_effects = 0; int n_effects = 0;
if (ioctl(fd, EVIOCGEFFECTS, &n_effects) == -1) { if (ioctl(fd, EVIOCGEFFECTS, &n_effects) == -1) {
perror("Ioctl number of effects"); perror("Ioctl number of effects");
} }
if (n_effects > 0) if (n_effects > 0)
CanRumble = true; CanRumble = true;
else else
return; // Return since we can't do any effects return; // Return since we can't do any effects
/* a strong rumbling effect */ /* a strong rumbling effect */
effect.type = FF_RUMBLE; effect.type = FF_RUMBLE;
effect.id = -1; effect.id = -1;
effect.u.rumble.strong_magnitude = 0x8000; effect.u.rumble.strong_magnitude = 0x8000;
effect.u.rumble.weak_magnitude = 0; effect.u.rumble.weak_magnitude = 0;
effect.replay.length = 5000; // Set to 5 seconds, if a Game needs more for a single rumble event, it is dumb and must be a demo effect.replay.length = 5000; // Set to 5 seconds, if a Game needs more for a single rumble event, it is dumb and must be a demo
effect.replay.delay = 0; effect.replay.delay = 0;
if (ioctl(fd, EVIOCSFF, &effect) == -1) { if (ioctl(fd, EVIOCSFF, &effect) == -1) {
perror("Upload effect"); perror("Upload effect");
CanRumble = false; //We have effects but it doesn't support the rumble we are using. This is basic rumble, should work for most CanRumble = false; //We have effects but it doesn't support the rumble we are using. This is basic rumble, should work for most
} }
} }
#endif #endif
} }
#ifdef _WIN32 #ifdef _WIN32
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Rumble stuff :D! // Rumble stuff :D!
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// //
#ifdef USE_RUMBLE_DINPUT_HACK #ifdef USE_RUMBLE_DINPUT_HACK
HRESULT InitDirectInput( HWND hDlg ) HRESULT InitDirectInput( HWND hDlg )
{ {
DIPROPDWORD dipdw; DIPROPDWORD dipdw;
HRESULT hr; HRESULT hr;
// Register with the DirectInput subsystem and get a pointer to a IDirectInput interface we can use. // Register with the DirectInput subsystem and get a pointer to a IDirectInput interface we can use.
if (FAILED(hr = DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, IID_IDirectInput8, (VOID**)&g_pDI, NULL))) if (FAILED(hr = DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, IID_IDirectInput8, (VOID**)&g_pDI, NULL)))
{ {
return hr; return hr;
} }
// Look for a force feedback device we can use // Look for a force feedback device we can use
if (FAILED(hr = g_pDI->EnumDevices( DI8DEVCLASS_GAMECTRL, EnumFFDevicesCallback, NULL, DIEDFL_ATTACHEDONLY | DIEDFL_FORCEFEEDBACK))) if (FAILED(hr = g_pDI->EnumDevices( DI8DEVCLASS_GAMECTRL, EnumFFDevicesCallback, NULL, DIEDFL_ATTACHEDONLY | DIEDFL_FORCEFEEDBACK)))
{ {
return hr; return hr;
} }
if (NULL == g_pDevice) if (NULL == g_pDevice)
{ {
MessageBox(NULL, "Force feedback device not found. nJoy will now disable rumble." ,"FFConst" , MB_ICONERROR | MB_OK); MessageBox(NULL, "Force feedback device not found. nJoy will now disable rumble." ,"FFConst" , MB_ICONERROR | MB_OK);
g_rumbleEnable = FALSE; g_rumbleEnable = FALSE;
return S_OK; return S_OK;
} }
// Set the data format to "simple joystick" - a predefined data format. A // Set the data format to "simple joystick" - a predefined data format. A
// data format specifies which controls on a device we are interested in, // data format specifies which controls on a device we are interested in,
// and how they should be reported. // and how they should be reported.
// //
// This tells DirectInput that we will be passing a DIJOYSTATE structure to // This tells DirectInput that we will be passing a DIJOYSTATE structure to
// IDirectInputDevice8::GetDeviceState(). Even though we won't actually do // IDirectInputDevice8::GetDeviceState(). Even though we won't actually do
// it in this sample. But setting the data format is important so that the // it in this sample. But setting the data format is important so that the
// DIJOFS_* values work properly. // DIJOFS_* values work properly.
if (FAILED(hr = g_pDevice->SetDataFormat(&c_dfDIJoystick))) if (FAILED(hr = g_pDevice->SetDataFormat(&c_dfDIJoystick)))
return hr; return hr;
// Set the cooperative level to let DInput know how this device should // Set the cooperative level to let DInput know how this device should
// interact with the system and with other DInput applications. // interact with the system and with other DInput applications.
// Exclusive access is required in order to perform force feedback. // Exclusive access is required in order to perform force feedback.
//if (FAILED(hr = g_pDevice->SetCooperativeLevel(hDlg, DISCL_EXCLUSIVE | DISCL_FOREGROUND))) //if (FAILED(hr = g_pDevice->SetCooperativeLevel(hDlg, DISCL_EXCLUSIVE | DISCL_FOREGROUND)))
if (FAILED(hr = g_pDevice->SetCooperativeLevel(hDlg, DISCL_EXCLUSIVE | DISCL_FOREGROUND))) if (FAILED(hr = g_pDevice->SetCooperativeLevel(hDlg, DISCL_EXCLUSIVE | DISCL_FOREGROUND)))
{ {
return hr; return hr;
} }
// Since we will be playing force feedback effects, we should disable the // Since we will be playing force feedback effects, we should disable the
// auto-centering spring. // auto-centering spring.
dipdw.diph.dwSize = sizeof(DIPROPDWORD); dipdw.diph.dwSize = sizeof(DIPROPDWORD);
dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
dipdw.diph.dwObj = 0; dipdw.diph.dwObj = 0;
dipdw.diph.dwHow = DIPH_DEVICE; dipdw.diph.dwHow = DIPH_DEVICE;
dipdw.dwData = FALSE; dipdw.dwData = FALSE;
if (FAILED(hr = g_pDevice->SetProperty(DIPROP_AUTOCENTER, &dipdw.diph))) if (FAILED(hr = g_pDevice->SetProperty(DIPROP_AUTOCENTER, &dipdw.diph)))
return hr; return hr;
// Enumerate and count the axes of the joystick // Enumerate and count the axes of the joystick
if (FAILED(hr = g_pDevice->EnumObjects(EnumAxesCallback, (VOID*)&g_dwNumForceFeedbackAxis, DIDFT_AXIS))) if (FAILED(hr = g_pDevice->EnumObjects(EnumAxesCallback, (VOID*)&g_dwNumForceFeedbackAxis, DIDFT_AXIS)))
return hr; return hr;
// This simple sample only supports one or two axis joysticks // This simple sample only supports one or two axis joysticks
if (g_dwNumForceFeedbackAxis > 2) if (g_dwNumForceFeedbackAxis > 2)
g_dwNumForceFeedbackAxis = 2; g_dwNumForceFeedbackAxis = 2;
// This application needs only one effect: Applying raw forces. // This application needs only one effect: Applying raw forces.
DWORD rgdwAxes[2] = {DIJOFS_X, DIJOFS_Y}; DWORD rgdwAxes[2] = {DIJOFS_X, DIJOFS_Y};
LONG rglDirection[2] = {0, 0}; LONG rglDirection[2] = {0, 0};
DICONSTANTFORCE cf = {0}; DICONSTANTFORCE cf = {0};
DIEFFECT eff; DIEFFECT eff;
ZeroMemory(&eff, sizeof(eff)); ZeroMemory(&eff, sizeof(eff));
eff.dwSize = sizeof(DIEFFECT); eff.dwSize = sizeof(DIEFFECT);
eff.dwFlags = DIEFF_CARTESIAN | DIEFF_OBJECTOFFSETS; eff.dwFlags = DIEFF_CARTESIAN | DIEFF_OBJECTOFFSETS;
eff.dwDuration = INFINITE; eff.dwDuration = INFINITE;
eff.dwSamplePeriod = 0; eff.dwSamplePeriod = 0;
eff.dwGain = DI_FFNOMINALMAX; eff.dwGain = DI_FFNOMINALMAX;
eff.dwTriggerButton = DIEB_NOTRIGGER; eff.dwTriggerButton = DIEB_NOTRIGGER;
eff.dwTriggerRepeatInterval = 0; eff.dwTriggerRepeatInterval = 0;
eff.cAxes = g_dwNumForceFeedbackAxis; eff.cAxes = g_dwNumForceFeedbackAxis;
eff.rgdwAxes = rgdwAxes; eff.rgdwAxes = rgdwAxes;
eff.rglDirection = rglDirection; eff.rglDirection = rglDirection;
eff.lpEnvelope = 0; eff.lpEnvelope = 0;
eff.cbTypeSpecificParams = sizeof( DICONSTANTFORCE ); eff.cbTypeSpecificParams = sizeof( DICONSTANTFORCE );
eff.lpvTypeSpecificParams = &cf; eff.lpvTypeSpecificParams = &cf;
eff.dwStartDelay = 0; eff.dwStartDelay = 0;
// Create the prepared effect // Create the prepared effect
if (FAILED(hr = g_pDevice->CreateEffect(GUID_ConstantForce, &eff, &g_pEffect, NULL))) if (FAILED(hr = g_pDevice->CreateEffect(GUID_ConstantForce, &eff, &g_pEffect, NULL)))
{ {
return hr; return hr;
} }
if (NULL == g_pEffect) if (NULL == g_pEffect)
return E_FAIL; return E_FAIL;
return S_OK; return S_OK;
} }
VOID FreeDirectInput() VOID FreeDirectInput()
{ {
// Unacquire the device one last time just in case // Unacquire the device one last time just in case
// the app tried to exit while the device is still acquired. // the app tried to exit while the device is still acquired.
if (g_pDevice) if (g_pDevice)
g_pDevice->Unacquire(); g_pDevice->Unacquire();
// Release any DirectInput objects. // Release any DirectInput objects.
SAFE_RELEASE(g_pEffect); SAFE_RELEASE(g_pEffect);
SAFE_RELEASE(g_pDevice); SAFE_RELEASE(g_pDevice);
SAFE_RELEASE(g_pDI); SAFE_RELEASE(g_pDI);
} }
BOOL CALLBACK EnumFFDevicesCallback( const DIDEVICEINSTANCE* pInst, VOID* pContext ) BOOL CALLBACK EnumFFDevicesCallback( const DIDEVICEINSTANCE* pInst, VOID* pContext )
{ {
LPDIRECTINPUTDEVICE8 pDevice; LPDIRECTINPUTDEVICE8 pDevice;
HRESULT hr; HRESULT hr;
// Obtain an interface to the enumerated force feedback device. // Obtain an interface to the enumerated force feedback device.
hr = g_pDI->CreateDevice(pInst->guidInstance, &pDevice, NULL); hr = g_pDI->CreateDevice(pInst->guidInstance, &pDevice, NULL);
// If it failed, then we can't use this device for some bizarre reason. // If it failed, then we can't use this device for some bizarre reason.
// (Maybe the user unplugged it while we were in the middle of enumerating it.) So continue enumerating // (Maybe the user unplugged it while we were in the middle of enumerating it.) So continue enumerating
if (FAILED(hr)) if (FAILED(hr))
return DIENUM_CONTINUE; return DIENUM_CONTINUE;
// We successfully created an IDirectInputDevice8. So stop looking for another one. // We successfully created an IDirectInputDevice8. So stop looking for another one.
g_pDevice = pDevice; g_pDevice = pDevice;
return DIENUM_STOP; return DIENUM_STOP;
} }
BOOL CALLBACK EnumAxesCallback(const DIDEVICEOBJECTINSTANCE* pdidoi, VOID* pContext) BOOL CALLBACK EnumAxesCallback(const DIDEVICEOBJECTINSTANCE* pdidoi, VOID* pContext)
{ {
DWORD* pdwNumForceFeedbackAxis = (DWORD*)pContext; DWORD* pdwNumForceFeedbackAxis = (DWORD*)pContext;
if ((pdidoi->dwFlags & DIDOI_FFACTUATOR) != 0) if ((pdidoi->dwFlags & DIDOI_FFACTUATOR) != 0)
(*pdwNumForceFeedbackAxis)++; (*pdwNumForceFeedbackAxis)++;
return DIENUM_CONTINUE; return DIENUM_CONTINUE;
} }
HRESULT SetDeviceForcesXY() HRESULT SetDeviceForcesXY()
{ {
// Modifying an effect is basically the same as creating a new one, except you need only specify the parameters you are modifying // Modifying an effect is basically the same as creating a new one, except you need only specify the parameters you are modifying
LONG rglDirection[2] = { 0, 0 }; LONG rglDirection[2] = { 0, 0 };
DICONSTANTFORCE cf; DICONSTANTFORCE cf;
if (g_dwNumForceFeedbackAxis == 1) if (g_dwNumForceFeedbackAxis == 1)
{ {
// If only one force feedback axis, then apply only one direction and keep the direction at zero // If only one force feedback axis, then apply only one direction and keep the direction at zero
cf.lMagnitude = g_nXForce; cf.lMagnitude = g_nXForce;
rglDirection[0] = 0; rglDirection[0] = 0;
} }
else else
{ {
// If two force feedback axis, then apply magnitude from both directions // If two force feedback axis, then apply magnitude from both directions
rglDirection[0] = g_nXForce; rglDirection[0] = g_nXForce;
rglDirection[1] = g_nYForce; rglDirection[1] = g_nYForce;
cf.lMagnitude = (DWORD)sqrt((double)g_nXForce * (double)g_nXForce + (double)g_nYForce * (double)g_nYForce ); cf.lMagnitude = (DWORD)sqrt((double)g_nXForce * (double)g_nXForce + (double)g_nYForce * (double)g_nYForce );
} }
DIEFFECT eff; DIEFFECT eff;
ZeroMemory(&eff, sizeof(eff)); ZeroMemory(&eff, sizeof(eff));
eff.dwSize = sizeof(DIEFFECT); eff.dwSize = sizeof(DIEFFECT);
eff.dwFlags = DIEFF_CARTESIAN | DIEFF_OBJECTOFFSETS; eff.dwFlags = DIEFF_CARTESIAN | DIEFF_OBJECTOFFSETS;
eff.cAxes = g_dwNumForceFeedbackAxis; eff.cAxes = g_dwNumForceFeedbackAxis;
eff.rglDirection = rglDirection; eff.rglDirection = rglDirection;
eff.lpEnvelope = 0; eff.lpEnvelope = 0;
eff.cbTypeSpecificParams = sizeof(DICONSTANTFORCE); eff.cbTypeSpecificParams = sizeof(DICONSTANTFORCE);
eff.lpvTypeSpecificParams = &cf; eff.lpvTypeSpecificParams = &cf;
eff.dwStartDelay = 0; eff.dwStartDelay = 0;
// Now set the new parameters and start the effect immediately. // Now set the new parameters and start the effect immediately.
return g_pEffect->SetParameters(&eff, DIEP_DIRECTION | DIEP_TYPESPECIFICPARAMS | DIEP_START); return g_pEffect->SetParameters(&eff, DIEP_DIRECTION | DIEP_TYPESPECIFICPARAMS | DIEP_START);
} }
#endif #endif
#endif #endif