set svn:eol-style=native for Plugins/**.cpp

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@1441 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
bushing 2008-12-08 05:25:12 +00:00
parent 9146b9b261
commit 901fe7c00f
142 changed files with 43834 additions and 43834 deletions

View File

@ -1,59 +1,59 @@
// 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 "IniFile.h" #include "IniFile.h"
#include "Config.h" #include "Config.h"
CConfig g_Config; CConfig g_Config;
CConfig::CConfig() CConfig::CConfig()
{ {
Load(); Load();
} }
void CConfig::LoadDefaults() void CConfig::LoadDefaults()
{ {
m_EnableHLEAudio = true; m_EnableHLEAudio = true;
m_EnableDTKMusic = true; m_EnableDTKMusic = true;
m_Interpolation = true; m_Interpolation = true;
} }
void CConfig::Load() void CConfig::Load()
{ {
// first load defaults // first load defaults
LoadDefaults(); LoadDefaults();
IniFile file; IniFile file;
file.Load(FULL_CONFIG_DIR "DSP.ini"); file.Load(FULL_CONFIG_DIR "DSP.ini");
file.Get("Config", "EnableHLEAudio", &m_EnableHLEAudio, true); // Sound Settings file.Get("Config", "EnableHLEAudio", &m_EnableHLEAudio, true); // Sound Settings
file.Get("Config", "EnableDTKMusic", &m_EnableDTKMusic, true); file.Get("Config", "EnableDTKMusic", &m_EnableDTKMusic, true);
file.Get("Config", "EnableThrottle", &m_EnableThrottle, true); file.Get("Config", "EnableThrottle", &m_EnableThrottle, true);
file.Get("Config", "Interpolation", &m_Interpolation, true); file.Get("Config", "Interpolation", &m_Interpolation, true);
} }
void CConfig::Save() void CConfig::Save()
{ {
IniFile file; IniFile file;
file.Load(FULL_CONFIG_DIR "DSP.ini"); file.Load(FULL_CONFIG_DIR "DSP.ini");
file.Set("Config", "EnableHLEAudio", m_EnableHLEAudio); // Sound Settings file.Set("Config", "EnableHLEAudio", m_EnableHLEAudio); // Sound Settings
file.Set("Config", "EnableDTKMusic", m_EnableDTKMusic); file.Set("Config", "EnableDTKMusic", m_EnableDTKMusic);
file.Set("Config", "EnableThrottle", m_EnableThrottle); file.Set("Config", "EnableThrottle", m_EnableThrottle);
file.Set("Config", "Interpolation", m_Interpolation); file.Set("Config", "Interpolation", m_Interpolation);
file.Save(FULL_CONFIG_DIR "DSP.ini"); file.Save(FULL_CONFIG_DIR "DSP.ini");
} }

View File

@ -1,85 +1,85 @@
// 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 "resource.h" #include "resource.h"
#include "Config.h" #include "Config.h"
#include "ConfigDlg.h" #include "ConfigDlg.h"
LRESULT LRESULT
CConfigDlg::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) CConfigDlg::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{ {
// Load config settings // Load config settings
g_Config.Load(); g_Config.Load();
// Center window // Center window
//CenterWindow(this->GetParent()); //CenterWindow(this->GetParent());
CenterWindow(GetParent()); CenterWindow(GetParent());
// Get button handles // Get button handles
m_buttonEnableHLEAudio = GetDlgItem(IDC_ENABLE_HLE_AUDIO); m_buttonEnableHLEAudio = GetDlgItem(IDC_ENABLE_HLE_AUDIO);
m_buttonEnableDTKMusic = GetDlgItem(IDC_ENABLE_DTK_MUSIC); m_buttonEnableDTKMusic = GetDlgItem(IDC_ENABLE_DTK_MUSIC);
m_buttonEnableThrottle = GetDlgItem(IDC_ENABLE_THROTTLE); m_buttonEnableThrottle = GetDlgItem(IDC_ENABLE_THROTTLE);
m_comboSampleRate = GetDlgItem(IDC_SAMPLERATE); m_comboSampleRate = GetDlgItem(IDC_SAMPLERATE);
// Update checkboxes // Update checkboxes
m_buttonEnableHLEAudio.SetCheck(g_Config.m_EnableHLEAudio ? BST_CHECKED : BST_UNCHECKED); m_buttonEnableHLEAudio.SetCheck(g_Config.m_EnableHLEAudio ? BST_CHECKED : BST_UNCHECKED);
m_buttonEnableDTKMusic.SetCheck(g_Config.m_EnableDTKMusic ? BST_CHECKED : BST_UNCHECKED); m_buttonEnableDTKMusic.SetCheck(g_Config.m_EnableDTKMusic ? BST_CHECKED : BST_UNCHECKED);
m_buttonEnableThrottle.SetCheck(g_Config.m_EnableThrottle ? BST_CHECKED : BST_UNCHECKED); m_buttonEnableThrottle.SetCheck(g_Config.m_EnableThrottle ? BST_CHECKED : BST_UNCHECKED);
m_comboSampleRate.AddString("44100"); m_comboSampleRate.AddString("44100");
m_comboSampleRate.AddString("48000"); m_comboSampleRate.AddString("48000");
m_comboSampleRate.SetCurSel(g_Config.m_SampleRate == 44100 ? 0 : 1); m_comboSampleRate.SetCurSel(g_Config.m_SampleRate == 44100 ? 0 : 1);
// Add tooltips // Add tooltips
CToolTipCtrl ToolTips; CToolTipCtrl ToolTips;
ToolTips.Create(m_hWnd); ToolTips.Create(m_hWnd);
ToolTips.Activate(true); ToolTips.Activate(true);
ToolTips.SetMaxTipWidth(220); // limit the width ToolTips.SetMaxTipWidth(220); // limit the width
ToolTips.SetDelayTime(TTDT_AUTOPOP, 20 * 1000); // give us time to read it ToolTips.SetDelayTime(TTDT_AUTOPOP, 20 * 1000); // give us time to read it
CToolInfo tiHLE(TTF_SUBCLASS, m_buttonEnableHLEAudio, 0, NULL, CToolInfo tiHLE(TTF_SUBCLASS, m_buttonEnableHLEAudio, 0, NULL,
"This is the most common sound type"); "This is the most common sound type");
CToolInfo tiDTK(TTF_SUBCLASS, m_buttonEnableDTKMusic, 0, NULL, CToolInfo tiDTK(TTF_SUBCLASS, m_buttonEnableDTKMusic, 0, NULL,
"This is sometimes used to play music tracks from the disc"); "This is sometimes used to play music tracks from the disc");
CToolInfo tiOther(TTF_SUBCLASS, m_buttonEnableThrottle, 0, NULL, CToolInfo tiOther(TTF_SUBCLASS, m_buttonEnableThrottle, 0, NULL,
"This is sometimes used together with pre-rendered movies. Disabling this" "This is sometimes used together with pre-rendered movies. Disabling this"
" also disables the speed throttle that is causes. Meaning that" " also disables the speed throttle that is causes. Meaning that"
" there will be no upper limit on your FPS."); " there will be no upper limit on your FPS.");
ToolTips.AddTool(tiHLE); ToolTips.AddTool(tiHLE);
ToolTips.AddTool(tiDTK); ToolTips.AddTool(tiDTK);
ToolTips.AddTool(tiOther); ToolTips.AddTool(tiOther);
return(TRUE); return(TRUE);
} }
LRESULT LRESULT
CConfigDlg::OnCloseCmd(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/) CConfigDlg::OnCloseCmd(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{ {
// Save settings // Save settings
if (wID == IDOK) if (wID == IDOK)
{ {
g_Config.m_EnableHLEAudio = (m_buttonEnableHLEAudio.GetCheck() == BST_CHECKED) ? true : false; g_Config.m_EnableHLEAudio = (m_buttonEnableHLEAudio.GetCheck() == BST_CHECKED) ? true : false;
g_Config.m_EnableDTKMusic = (m_buttonEnableDTKMusic.GetCheck() == BST_CHECKED) ? true : false; g_Config.m_EnableDTKMusic = (m_buttonEnableDTKMusic.GetCheck() == BST_CHECKED) ? true : false;
g_Config.m_EnableThrottle = (m_buttonEnableThrottle.GetCheck() == BST_CHECKED) ? true : false; g_Config.m_EnableThrottle = (m_buttonEnableThrottle.GetCheck() == BST_CHECKED) ? true : false;
g_Config.m_SampleRate = (m_comboSampleRate.GetCurSel() == 0 ? 44100 : 48000); g_Config.m_SampleRate = (m_comboSampleRate.GetCurSel() == 0 ? 44100 : 48000);
g_Config.Save(); g_Config.Save();
} }
EndDialog(wID); EndDialog(wID);
g_Config.Save(); g_Config.Save();
return(0); return(0);
} }

View File

@ -1,90 +1,90 @@
// 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/
#ifdef _WIN32 #ifdef _WIN32
#include "PCHW/DSoundStream.h" #include "PCHW/DSoundStream.h"
#endif #endif
#include "DSPHandler.h" #include "DSPHandler.h"
CDSPHandler* CDSPHandler::m_pInstance = NULL; CDSPHandler* CDSPHandler::m_pInstance = NULL;
CDSPHandler::CDSPHandler() CDSPHandler::CDSPHandler()
: m_pUCode(NULL), : m_pUCode(NULL),
m_bHalt(false), m_bHalt(false),
m_bAssertInt(false) m_bAssertInt(false)
{ {
SetUCode(UCODE_ROM); SetUCode(UCODE_ROM);
m_DSPControl.DSPHalt = 1; m_DSPControl.DSPHalt = 1;
m_DSPControl.DSPInit = 1; m_DSPControl.DSPInit = 1;
} }
CDSPHandler::~CDSPHandler() CDSPHandler::~CDSPHandler()
{ {
delete m_pUCode; delete m_pUCode;
m_pUCode = NULL; m_pUCode = NULL;
} }
void CDSPHandler::Update() void CDSPHandler::Update()
{ {
if (m_pUCode != NULL) if (m_pUCode != NULL)
m_pUCode->Update(); m_pUCode->Update();
} }
unsigned short CDSPHandler::WriteControlRegister(unsigned short _Value) unsigned short CDSPHandler::WriteControlRegister(unsigned short _Value)
{ {
UDSPControl Temp(_Value); UDSPControl Temp(_Value);
if (Temp.DSPReset) if (Temp.DSPReset)
{ {
SetUCode(UCODE_ROM); SetUCode(UCODE_ROM);
Temp.DSPReset = 0; Temp.DSPReset = 0;
} }
if (Temp.DSPInit == 0) if (Temp.DSPInit == 0)
{ {
// copy 128 byte from ARAM 0x000000 to IMEM // copy 128 byte from ARAM 0x000000 to IMEM
SetUCode(UCODE_INIT_AUDIO_SYSTEM); SetUCode(UCODE_INIT_AUDIO_SYSTEM);
Temp.DSPInitCode = 0; Temp.DSPInitCode = 0;
// MessageBox(NULL, "UCODE_INIT_AUDIO_SYSTEM", "DSP-HLE", MB_OK); // MessageBox(NULL, "UCODE_INIT_AUDIO_SYSTEM", "DSP-HLE", MB_OK);
} }
m_DSPControl.Hex = Temp.Hex; m_DSPControl.Hex = Temp.Hex;
return m_DSPControl.Hex; return m_DSPControl.Hex;
} }
unsigned short CDSPHandler::ReadControlRegister() unsigned short CDSPHandler::ReadControlRegister()
{ {
return m_DSPControl.Hex; return m_DSPControl.Hex;
} }
void CDSPHandler::SendMailToDSP(u32 _uMail) void CDSPHandler::SendMailToDSP(u32 _uMail)
{ {
if (m_pUCode != NULL) if (m_pUCode != NULL)
m_pUCode->HandleMail(_uMail); m_pUCode->HandleMail(_uMail);
} }
IUCode* CDSPHandler::GetUCode() IUCode* CDSPHandler::GetUCode()
{ {
return m_pUCode; return m_pUCode;
} }
void CDSPHandler::SetUCode(u32 _crc) void CDSPHandler::SetUCode(u32 _crc)
{ {
delete m_pUCode; delete m_pUCode;
m_pUCode = NULL; m_pUCode = NULL;
m_MailHandler.Clear(); m_MailHandler.Clear();
m_pUCode = UCodeFactory(_crc, m_MailHandler); m_pUCode = UCodeFactory(_crc, m_MailHandler);
} }

View File

@ -1,85 +1,85 @@
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// //
// 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/
// //
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// includes // includes
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
#include <sstream> #include <sstream>
#ifndef _WIN32 #ifndef _WIN32
#include <stdlib.h> #include <stdlib.h>
#endif #endif
#include "Debugger.h" #include "Debugger.h"
#include "PBView.h" #include "PBView.h"
#include "IniFile.h" #include "IniFile.h"
#include "FileUtil.h" #include "FileUtil.h"
#include "StringUtil.h" #include "StringUtil.h"
#include "FileSearch.h" #include "FileSearch.h"
#include "../Logging/Console.h" // open and close console #include "../Logging/Console.h" // open and close console
// Make the wxTextCtrls scroll with each other // Make the wxTextCtrls scroll with each other
void CDebugger::DoScrollBlocks() void CDebugger::DoScrollBlocks()
{ {
// ShowPosition = in letters // ShowPosition = in letters
// GetScrollPos = number of lines from the top // GetScrollPos = number of lines from the top
// GetLineLength = letters in one line // GetLineLength = letters in one line
// SetScrollPos = only set the scrollbar, doesn't update the text, // SetScrollPos = only set the scrollbar, doesn't update the text,
// Update() or Refresh() doesn't help // Update() or Refresh() doesn't help
double pos = m_bl95->GetScrollPos(wxVERTICAL)*(m_bl95->GetLineLength(0)+12.95); // annoying :( double pos = m_bl95->GetScrollPos(wxVERTICAL)*(m_bl95->GetLineLength(0)+12.95); // annoying :(
m_bl0->ShowPosition((int)pos); m_bl0->ShowPosition((int)pos);
/* /*
if(GetAsyncKeyState(VK_NUMPAD1)) if(GetAsyncKeyState(VK_NUMPAD1))
A -= 0.1; A -= 0.1;
else if(GetAsyncKeyState(VK_NUMPAD2)) else if(GetAsyncKeyState(VK_NUMPAD2))
A += 0.11; A += 0.11;
wprintf("GetScrollPos:%i GetScrollRange:%i GetPosition:%i GetLastPosition:%i GetMaxWidth:%i \ wprintf("GetScrollPos:%i GetScrollRange:%i GetPosition:%i GetLastPosition:%i GetMaxWidth:%i \
GetLineLength:%i XYToPosition:%i\n \ GetLineLength:%i XYToPosition:%i\n \
GetScrollPos * GetLineLength + GetScrollRange:%i A:%f\n", GetScrollPos * GetLineLength + GetScrollRange:%i A:%f\n",
m_bl95->GetScrollPos(wxVERTICAL), m_bl95->GetScrollRange(wxVERTICAL), m_bl95->GetScrollPos(wxVERTICAL), m_bl95->GetScrollRange(wxVERTICAL),
m_bl95->GetPosition().y, m_bl95->GetLastPosition(), m_bl95->GetMaxWidth(), m_bl95->GetPosition().y, m_bl95->GetLastPosition(), m_bl95->GetMaxWidth(),
m_bl95->GetLineLength(0), m_bl95->XYToPosition(0,25), m_bl95->GetLineLength(0), m_bl95->XYToPosition(0,25),
pos, A pos, A
); );
for (int i = 0; i < 127; ++i) for (int i = 0; i < 127; ++i)
{ {
m_bl0->AppendText(wxString::Format("%02i|68 : 01a70144\n", i)); m_bl0->AppendText(wxString::Format("%02i|68 : 01a70144\n", i));
m_bl95->AppendText(wxString::Format("%i Mouse\n", i)); m_bl95->AppendText(wxString::Format("%i Mouse\n", i));
}*/ }*/
} }
void CDebugger::ScrollBlocksMouse(wxMouseEvent& event) void CDebugger::ScrollBlocksMouse(wxMouseEvent& event)
{ {
DoScrollBlocks(); DoScrollBlocks();
event.Skip(); // otherwise we remove the regular behavior, for example scrolling event.Skip(); // otherwise we remove the regular behavior, for example scrolling
} }
void CDebugger::ScrollBlocksCursor(wxScrollWinEvent& event) void CDebugger::ScrollBlocksCursor(wxScrollWinEvent& event)
{ {
DoScrollBlocks(); DoScrollBlocks();
event.Skip(); // otherwise we remove the regular behavior, for example scrolling event.Skip(); // otherwise we remove the regular behavior, for example scrolling
} }
// ============== // ==============

File diff suppressed because it is too large Load Diff

View File

@ -1,288 +1,288 @@
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// //
// 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/
// //
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// includes // includes
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
#include <sstream> #include <sstream>
#ifndef _WIN32 #ifndef _WIN32
#include <stdlib.h> #include <stdlib.h>
#endif #endif
#include "Debugger.h" #include "Debugger.h"
#include "PBView.h" #include "PBView.h"
#include "IniFile.h" #include "IniFile.h"
#include "FileUtil.h" #include "FileUtil.h"
#include "StringUtil.h" #include "StringUtil.h"
#include "FileSearch.h" #include "FileSearch.h"
#include "../Logging/Console.h" // open and close console #include "../Logging/Console.h" // open and close console
extern std::vector<std::string> sMailLog, sMailTime; extern std::vector<std::string> sMailLog, sMailTime;
extern CDebugger* m_frame; extern CDebugger* m_frame;
// ======================================================================================= // =======================================================================================
// Update mail window // Update mail window
// -------------- // --------------
void CDebugger::DoUpdateMail() void CDebugger::DoUpdateMail()
{ {
//wprintf("i %i %i\n", sFullMail.size(), sMailLog.size()); //wprintf("i %i %i\n", sFullMail.size(), sMailLog.size());
if(sFullMail.size() > 0 && sMailLog.size() > 0) if(sFullMail.size() > 0 && sMailLog.size() > 0)
{ {
m_log->SetValue(wxString::FromAscii(sFullMail.at(m_RadioBox[3]->GetSelection()).c_str())); m_log->SetValue(wxString::FromAscii(sFullMail.at(m_RadioBox[3]->GetSelection()).c_str()));
m_log->SetDefaultStyle(wxTextAttr(*wxBLUE)); // doesn't work because of the current wx m_log->SetDefaultStyle(wxTextAttr(*wxBLUE)); // doesn't work because of the current wx
m_log1->SetValue(wxString::FromAscii(sMailLog.at(m_RadioBox[3]->GetSelection()).c_str())); m_log1->SetValue(wxString::FromAscii(sMailLog.at(m_RadioBox[3]->GetSelection()).c_str()));
m_log1->AppendText(wxT("\n\n")); m_log1->AppendText(wxT("\n\n"));
} }
} }
void CDebugger::UpdateMail(wxNotebookEvent& event) void CDebugger::UpdateMail(wxNotebookEvent& event)
{ {
DoUpdateMail(); DoUpdateMail();
/* This may be called before m_frame is fully created through the /* This may be called before m_frame is fully created through the
EVT_NOTEBOOK_PAGE_CHANGED, in that case it will crash because this EVT_NOTEBOOK_PAGE_CHANGED, in that case it will crash because this
is accessing members of it */ is accessing members of it */
if(StoreMails && m_frame) ReadDir(); if(StoreMails && m_frame) ReadDir();
} }
// Change mail from radio button change // Change mail from radio button change
void CDebugger::ChangeMail(wxCommandEvent& event) void CDebugger::ChangeMail(wxCommandEvent& event)
{ {
//wprintf("abc"); //wprintf("abc");
DoUpdateMail(); DoUpdateMail();
//if(StoreMails) ReadDir(); //if(StoreMails) ReadDir();
} }
// ============== // ==============
// ======================================================================================= // =======================================================================================
// Read out mails from dir // Read out mails from dir
// -------------- // --------------
void CDebugger::ReadDir() void CDebugger::ReadDir()
{ {
CFileSearch::XStringVector Directories; CFileSearch::XStringVector Directories;
//Directories.push_back("Logs/Mail"); //Directories.push_back("Logs/Mail");
Directories.push_back(FULL_MAIL_LOGS_DIR); Directories.push_back(FULL_MAIL_LOGS_DIR);
CFileSearch::XStringVector Extensions; CFileSearch::XStringVector Extensions;
Extensions.push_back("*.log"); Extensions.push_back("*.log");
CFileSearch FileSearch(Extensions, Directories); CFileSearch FileSearch(Extensions, Directories);
const CFileSearch::XStringVector& rFilenames = FileSearch.GetFileNames(); const CFileSearch::XStringVector& rFilenames = FileSearch.GetFileNames();
//m_gc->Show(false); //m_gc->Show(false);
//m_gc->Append(wxT("SSBM ffffix")); //m_gc->Append(wxT("SSBM ffffix"));
//m_gc->Show(true); //m_gc->Show(true);
// Clear in case we already did this earlier // Clear in case we already did this earlier
all_all_files.clear(); all_all_files.clear();
if (rFilenames.size() > 0 && m_gc && m_wii) if (rFilenames.size() > 0 && m_gc && m_wii)
{ {
for (u32 i = 0; i < rFilenames.size(); i++) for (u32 i = 0; i < rFilenames.size(); i++)
{ {
std::string FileName; std::string FileName;
SplitPath(rFilenames[i], NULL, &FileName, NULL); // place the filename in FileName SplitPath(rFilenames[i], NULL, &FileName, NULL); // place the filename in FileName
//std::string FileName = StripSpaces(*FileName); //std::string FileName = StripSpaces(*FileName);
std::vector<std::string> pieces; std::vector<std::string> pieces;
SplitString(FileName, "_sep", pieces); // split string SplitString(FileName, "_sep", pieces); // split string
// Save all filenames heres // Save all filenames heres
if(pieces[2] == "0") all_all_files.push_back(pieces[0]); if(pieces[2] == "0") all_all_files.push_back(pieces[0]);
// Cut to size // Cut to size
std::string cut; std::string cut;
if(pieces[0].length() > 18) if(pieces[0].length() > 18)
cut = pieces[0].substr(0, 18) + "..."; cut = pieces[0].substr(0, 18) + "...";
else else
cut = pieces[0]; cut = pieces[0];
//wprintf("%s %s %s\n", pieces[0].c_str(), pieces[1].c_str(), //wprintf("%s %s %s\n", pieces[0].c_str(), pieces[1].c_str(),
// pieces[2].c_str(), pieces[3].c_str()); // pieces[2].c_str(), pieces[3].c_str());
if (NoDuplicate(pieces[0]) && pieces.size() >= 3) if (NoDuplicate(pieces[0]) && pieces.size() >= 3)
{ {
all_files.push_back(pieces[0]); all_files.push_back(pieces[0]);
if (pieces[3] == "GC") if (pieces[3] == "GC")
{ {
gc_files.push_back(pieces[0]); gc_files.push_back(pieces[0]);
m_gc->Append(wxString::FromAscii(cut.c_str())); m_gc->Append(wxString::FromAscii(cut.c_str()));
} }
else else
{ {
wii_files.push_back(pieces[0]); wii_files.push_back(pieces[0]);
m_wii->Append(wxString::FromAscii(cut.c_str())); m_wii->Append(wxString::FromAscii(cut.c_str()));
} }
} }
} }
} }
} }
// ======================================================================================= // =======================================================================================
// Check for duplicates and count files from all_all_files // Check for duplicates and count files from all_all_files
// -------------- // --------------
bool CDebugger::NoDuplicate(std::string FileName) bool CDebugger::NoDuplicate(std::string FileName)
{ {
for (u32 i = 0; i < all_files.size(); i++) for (u32 i = 0; i < all_files.size(); i++)
{ {
if(all_files.at(i) == FileName) if(all_files.at(i) == FileName)
return false; return false;
} }
return true; return true;
} }
// Count the number of files for each game // Count the number of files for each game
u32 CDebugger::CountFiles(std::string FileName) u32 CDebugger::CountFiles(std::string FileName)
{ {
int match = 0; int match = 0;
for (u32 i = 0; i < all_all_files.size(); i++) for (u32 i = 0; i < all_all_files.size(); i++)
{ {
//wprintf("CountFiles %i %s\n", i, all_all_files[i].c_str()); //wprintf("CountFiles %i %s\n", i, all_all_files[i].c_str());
if(all_all_files[i] == FileName) if(all_all_files[i] == FileName)
match++; match++;
} }
//wprintf("We found %i files for this game\n", match); //wprintf("We found %i files for this game\n", match);
return match; return match;
} }
// ============== // ==============
// ======================================================================================= // =======================================================================================
// Read file from harddrive // Read file from harddrive
// -------------- // --------------
std::string CDebugger::Readfile_(std::string FileName) std::string CDebugger::Readfile_(std::string FileName)
{ {
char c; // declare a char variable char c; // declare a char variable
FILE *file; // declare a FILE pointer FILE *file; // declare a FILE pointer
std::string sz = ""; std::string sz = "";
if(File::Exists(FileName.c_str())) if(File::Exists(FileName.c_str()))
file = fopen(FileName.c_str(), "r"); // open a text file for reading file = fopen(FileName.c_str(), "r"); // open a text file for reading
else else
return ""; return "";
if(file == NULL) if(file == NULL)
{ {
// file could not be opened // file could not be opened
} }
else else
{ {
while(1) // looping through file while(1) // looping through file
{ {
c = fgetc(file); c = fgetc(file);
if(c != EOF) if(c != EOF)
sz += c; // print the file one character at a time sz += c; // print the file one character at a time
else else
break; // break when EOF is reached break; // break when EOF is reached
} }
fclose(file); fclose(file);
} }
return sz; return sz;
} }
// Read file // Read file
void CDebugger::Readfile(std::string FileName, bool GC) void CDebugger::Readfile(std::string FileName, bool GC)
{ {
u32 n = CountFiles(FileName); // count how many mails we have u32 n = CountFiles(FileName); // count how many mails we have
u32 curr_n = 0; u32 curr_n = 0;
std::ifstream file; std::ifstream file;
for (u32 i = 0; i < m_RadioBox[3]->GetCount(); i++) for (u32 i = 0; i < m_RadioBox[3]->GetCount(); i++)
{ {
if(m_RadioBox[3]->IsItemEnabled(i)) curr_n++; if(m_RadioBox[3]->IsItemEnabled(i)) curr_n++;
m_RadioBox[3]->Enable(i, false); // disable all m_RadioBox[3]->Enable(i, false); // disable all
} }
//wprintf("Disabled all: n %i\n", n); //wprintf("Disabled all: n %i\n", n);
for (u32 i = 0; i < n; i++) for (u32 i = 0; i < n; i++)
{ {
m_RadioBox[3]->Enable(i, true); // then anble the right ones m_RadioBox[3]->Enable(i, true); // then anble the right ones
//wprintf("m_RadioBox[3] enabled: %i\n", i); //wprintf("m_RadioBox[3] enabled: %i\n", i);
std::string sz = ""; std::string sz = "";
std::ostringstream ci; std::ostringstream ci;
ci << i; ci << i;
std::string f0 = FULL_MAIL_LOGS_DIR + FileName + "_sep" + ci.str() + "_sep" + "0_sep" + (GC ? "GC" : "Wii") + "_sep.log"; std::string f0 = FULL_MAIL_LOGS_DIR + FileName + "_sep" + ci.str() + "_sep" + "0_sep" + (GC ? "GC" : "Wii") + "_sep.log";
std::string f1 = FULL_MAIL_LOGS_DIR + FileName + "_sep" + ci.str() + "_sep" + "1_sep" + (GC ? "GC" : "Wii") + "_sep.log"; std::string f1 = FULL_MAIL_LOGS_DIR + FileName + "_sep" + ci.str() + "_sep" + "1_sep" + (GC ? "GC" : "Wii") + "_sep.log";
//wprintf("ifstream %s %s\n", f0.c_str(), f1.c_str()); //wprintf("ifstream %s %s\n", f0.c_str(), f1.c_str());
if(sFullMail.size() <= i) sFullMail.resize(sFullMail.size() + 1); if(sFullMail.size() <= i) sFullMail.resize(sFullMail.size() + 1);
if(sMailLog.size() <= i) sMailLog.resize(sMailLog.size() + 1); if(sMailLog.size() <= i) sMailLog.resize(sMailLog.size() + 1);
if(Readfile_(f0).length() > 0) sFullMail.at(i) = Readfile_(f0); if(Readfile_(f0).length() > 0) sFullMail.at(i) = Readfile_(f0);
else sFullMail.at(i) = ""; else sFullMail.at(i) = "";
if(Readfile_(f1).length() > 0) sMailLog.at(i) = Readfile_(f1); if(Readfile_(f1).length() > 0) sMailLog.at(i) = Readfile_(f1);
else sMailLog.at(i) = ""; else sMailLog.at(i) = "";
} }
if(n < curr_n) m_RadioBox[3]->Select(n - 1); if(n < curr_n) m_RadioBox[3]->Select(n - 1);
//wprintf("Select: %i | n %i curr_n %i\n", n - 1, n, curr_n); //wprintf("Select: %i | n %i curr_n %i\n", n - 1, n, curr_n);
DoUpdateMail(); DoUpdateMail();
} }
// ============== // ==============
// ======================================================================================= // =======================================================================================
// Read the file to the text window // Read the file to the text window
// --------------- // ---------------
void CDebugger::OnGameChange(wxCommandEvent& event) void CDebugger::OnGameChange(wxCommandEvent& event)
{ {
if(event.GetId() == 2006) if(event.GetId() == 2006)
{ {
// Only allow one selected game at a time // Only allow one selected game at a time
for (u32 i = 0; i < m_gc->GetCount(); ++i) for (u32 i = 0; i < m_gc->GetCount(); ++i)
if(i != (u32)event.GetInt()) m_gc->Check(i, false); if(i != (u32)event.GetInt()) m_gc->Check(i, false);
for (u32 i = 0; i < m_wii->GetCount(); ++i) for (u32 i = 0; i < m_wii->GetCount(); ++i)
m_wii->Check(i, false); m_wii->Check(i, false);
Readfile(gc_files[event.GetInt()], true); Readfile(gc_files[event.GetInt()], true);
} }
else else
{ {
for (u32 i = 0; i < m_gc->GetCount(); ++i) for (u32 i = 0; i < m_gc->GetCount(); ++i)
m_gc->Check(i, false); m_gc->Check(i, false);
for (u32 i = 0; i < m_wii->GetCount(); ++i) for (u32 i = 0; i < m_wii->GetCount(); ++i)
if(i != (u32)event.GetInt()) m_wii->Check(i, false); if(i != (u32)event.GetInt()) m_wii->Check(i, false);
Readfile(wii_files[event.GetInt()], false); Readfile(wii_files[event.GetInt()], false);
} }
} }
// Settings // Settings
void CDebugger::MailSettings(wxCommandEvent& event) void CDebugger::MailSettings(wxCommandEvent& event)
{ {
//for (int i = 0; i < all_all_files.size(); ++i) //for (int i = 0; i < all_all_files.size(); ++i)
//wprintf("s: %s \n", all_all_files.at(i).c_str()); //wprintf("s: %s \n", all_all_files.at(i).c_str());
ScanMails = m_gcwiiset->IsChecked(0); ScanMails = m_gcwiiset->IsChecked(0);
StoreMails = m_gcwiiset->IsChecked(1); StoreMails = m_gcwiiset->IsChecked(1);
} }

View File

@ -1,168 +1,168 @@
// 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 "PBView.h" #include "PBView.h"
#include <iostream> #include <iostream>
#include <string> #include <string>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
// external declarations // external declarations
extern const char* GetGRPName(unsigned int index); extern const char* GetGRPName(unsigned int index);
// No buttons or events so far // No buttons or events so far
BEGIN_EVENT_TABLE(CPBView, wxListCtrl) BEGIN_EVENT_TABLE(CPBView, wxListCtrl)
END_EVENT_TABLE() END_EVENT_TABLE()
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
CPBView::CPBView(wxWindow* parent, const wxWindowID id, const wxPoint& pos, const wxSize& size, long style) CPBView::CPBView(wxWindow* parent, const wxWindowID id, const wxPoint& pos, const wxSize& size, long style)
: wxListCtrl(parent, id, pos, size, style) : wxListCtrl(parent, id, pos, size, style)
{ {
InsertColumn(1, wxT("upd4"), wxLIST_FORMAT_LEFT, 90); InsertColumn(1, wxT("upd4"), wxLIST_FORMAT_LEFT, 90);
InsertColumn(1, wxT("upd3"), wxLIST_FORMAT_LEFT, 90); InsertColumn(1, wxT("upd3"), wxLIST_FORMAT_LEFT, 90);
InsertColumn(1, wxT("upd2"), wxLIST_FORMAT_LEFT, 90); InsertColumn(1, wxT("upd2"), wxLIST_FORMAT_LEFT, 90);
InsertColumn(1, wxT("upd1"), wxLIST_FORMAT_LEFT, 90); InsertColumn(1, wxT("upd1"), wxLIST_FORMAT_LEFT, 90);
InsertColumn(1, wxT("upd0"), wxLIST_FORMAT_LEFT, 90); InsertColumn(1, wxT("upd0"), wxLIST_FORMAT_LEFT, 90);
InsertColumn(1, wxT("r_lo"), wxLIST_FORMAT_LEFT, 90); InsertColumn(1, wxT("r_lo"), wxLIST_FORMAT_LEFT, 90);
InsertColumn(1, wxT("r_hi"), wxLIST_FORMAT_LEFT, 90); InsertColumn(1, wxT("r_hi"), wxLIST_FORMAT_LEFT, 90);
InsertColumn(1, wxT("ratio"), wxLIST_FORMAT_LEFT, 90); InsertColumn(1, wxT("ratio"), wxLIST_FORMAT_LEFT, 90);
InsertColumn(1, wxT("frac"), wxLIST_FORMAT_LEFT, 90); InsertColumn(1, wxT("frac"), wxLIST_FORMAT_LEFT, 90);
InsertColumn(1, wxT("coef"), wxLIST_FORMAT_LEFT, 90); InsertColumn(1, wxT("coef"), wxLIST_FORMAT_LEFT, 90);
InsertColumn(1, wxT("src_t"), wxLIST_FORMAT_LEFT, 90); InsertColumn(1, wxT("src_t"), wxLIST_FORMAT_LEFT, 90);
InsertColumn(1, wxT("form"), wxLIST_FORMAT_LEFT, 90); InsertColumn(1, wxT("form"), wxLIST_FORMAT_LEFT, 90);
InsertColumn(1, wxT("isstr"), wxLIST_FORMAT_LEFT, 90); InsertColumn(1, wxT("isstr"), wxLIST_FORMAT_LEFT, 90);
InsertColumn(1, wxT("yn2"), wxLIST_FORMAT_LEFT, 90); InsertColumn(1, wxT("yn2"), wxLIST_FORMAT_LEFT, 90);
InsertColumn(1, wxT("yn1"), wxLIST_FORMAT_LEFT, 90); InsertColumn(1, wxT("yn1"), wxLIST_FORMAT_LEFT, 90);
InsertColumn(1, wxT("pred_s"), wxLIST_FORMAT_LEFT, 90); InsertColumn(1, wxT("pred_s"), wxLIST_FORMAT_LEFT, 90);
InsertColumn(1, wxT("isloop"), wxLIST_FORMAT_LEFT, 90); InsertColumn(1, wxT("isloop"), wxLIST_FORMAT_LEFT, 90);
InsertColumn(1, wxT("volr"), wxLIST_FORMAT_LEFT, 90); InsertColumn(1, wxT("volr"), wxLIST_FORMAT_LEFT, 90);
InsertColumn(1, wxT("voll"), wxLIST_FORMAT_LEFT, 90); InsertColumn(1, wxT("voll"), wxLIST_FORMAT_LEFT, 90);
InsertColumn(1, wxT("loopto"), wxLIST_FORMAT_LEFT, 90); InsertColumn(1, wxT("loopto"), wxLIST_FORMAT_LEFT, 90);
InsertColumn(1, wxT("end"), wxLIST_FORMAT_LEFT, 90); InsertColumn(1, wxT("end"), wxLIST_FORMAT_LEFT, 90);
InsertColumn(0, wxT("pos"), wxLIST_FORMAT_LEFT, 90); InsertColumn(0, wxT("pos"), wxLIST_FORMAT_LEFT, 90);
InsertColumn(0, wxT("run"), wxLIST_FORMAT_RIGHT, 50); InsertColumn(0, wxT("run"), wxLIST_FORMAT_RIGHT, 50);
InsertColumn(0, wxT("Block"), wxLIST_FORMAT_CENTER, 40); InsertColumn(0, wxT("Block"), wxLIST_FORMAT_CENTER, 40);
SetFont(wxFont(8, wxSWISS, wxNORMAL, wxNORMAL, false, wxT("Segoe UI"))); SetFont(wxFont(8, wxSWISS, wxNORMAL, wxNORMAL, false, wxT("Segoe UI")));
for (int i = 0; i < 64; i++) for (int i = 0; i < 64; i++)
{ {
// Print values from 0 to 63 // Print values from 0 to 63
char buffer [33]; char buffer [33];
sprintf(buffer, "%02i", i); sprintf(buffer, "%02i", i);
int Item = InsertItem(0, wxString::FromAscii(buffer)); int Item = InsertItem(0, wxString::FromAscii(buffer));
wxListItem item; wxListItem item;
item.SetId(Item); item.SetId(Item);
item.SetBackgroundColour(0xFFFFFF); item.SetBackgroundColour(0xFFFFFF);
item.SetData(i); item.SetData(i);
SetItem(item); SetItem(item);
} }
// This is a wx call that leads to MSWDrawSubItem // This is a wx call that leads to MSWDrawSubItem
Refresh(); Refresh();
} }
void void
CPBView::Update() CPBView::Update()
{ {
Refresh(); Refresh();
} }
bool bool
CPBView::MSWDrawSubItem(wxPaintDC& rPainDC, int item, int subitem) CPBView::MSWDrawSubItem(wxPaintDC& rPainDC, int item, int subitem)
{ {
bool Result = false; bool Result = false;
// don't change 0, it has the block values // don't change 0, it has the block values
if(subitem > 0) if(subitem > 0)
{ {
#ifdef __WXMSW__ // what's this? should I use that? #ifdef __WXMSW__ // what's this? should I use that?
const wxChar* bgColor = _T("#ffffff"); const wxChar* bgColor = _T("#ffffff");
wxBrush bgBrush(bgColor); wxBrush bgBrush(bgColor);
wxPen bgPen(bgColor); wxPen bgPen(bgColor);
wxRect SubItemRect; wxRect SubItemRect;
this->GetSubItemRect(item, subitem, SubItemRect); this->GetSubItemRect(item, subitem, SubItemRect);
rPainDC.SetBrush(bgBrush); rPainDC.SetBrush(bgBrush);
rPainDC.SetPen(bgPen); rPainDC.SetPen(bgPen);
rPainDC.DrawRectangle(SubItemRect); rPainDC.DrawRectangle(SubItemRect);
#endif #endif
// A somewhat primitive attempt to show the playing history for a certain block. // A somewhat primitive attempt to show the playing history for a certain block.
wxString text; wxString text;
if(subitem == 1) if(subitem == 1)
{ {
char cbuff [33]; char cbuff [33];
sprintf(cbuff, "%08i", m_CachedRegs[subitem][item]); sprintf(cbuff, "%08i", m_CachedRegs[subitem][item]);
std::string c = cbuff; std::string c = cbuff;
int n[8]; int n[8];
for (int j = 0; j < 8; j++) for (int j = 0; j < 8; j++)
{ {
n[j] = atoi( c.substr(j, 1).c_str()); n[j] = atoi( c.substr(j, 1).c_str());
// 149 = dot, 160 = space // 149 = dot, 160 = space
if (n[j] == 1){ if (n[j] == 1){
n[j] = 149;} else {n[j] = 160;} n[j] = 149;} else {n[j] = 160;}
} }
// pretty neat huh? // pretty neat huh?
text.Printf(wxT("%c%c%c%c%c%c%c%c"), n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]); text.Printf(wxT("%c%c%c%c%c%c%c%c"), n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]);
} }
else else
{ {
text.Printf(wxT("0x%08x"), m_CachedRegs[subitem][item]); text.Printf(wxT("0x%08x"), m_CachedRegs[subitem][item]);
} }
#ifdef __WXMSW__ #ifdef __WXMSW__
rPainDC.DrawText(text, SubItemRect.GetLeft() + 10, SubItemRect.GetTop() + 4); rPainDC.DrawText(text, SubItemRect.GetLeft() + 10, SubItemRect.GetTop() + 4);
#else #else
// May not show up pretty in !Win32 // May not show up pretty in !Win32
rPainDC.DrawText(text, 10, 4); rPainDC.DrawText(text, 10, 4);
#endif #endif
return(true); return(true);
} }
else else
{ {
// what does this mean? // what does this mean?
return(Result); return(Result);
} }
} }

View File

@ -1,85 +1,85 @@
// 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 <stdarg.h> #include <stdarg.h>
#include <stdio.h> #include <stdio.h>
#include "Globals.h" #include "Globals.h"
#include "Common.h" #include "Common.h"
void __Log(int, const char *fmt, ...) void __Log(int, const char *fmt, ...)
{ {
DebugLog(fmt); DebugLog(fmt);
} }
void __Log_(int v, const char *fmt, ...) void __Log_(int v, const char *fmt, ...)
{ {
char Msg[512]; char Msg[512];
va_list ap; va_list ap;
va_start(ap, fmt); va_start(ap, fmt);
vsprintf(Msg, fmt, ap); vsprintf(Msg, fmt, ap);
va_end(ap); va_end(ap);
g_dspInitialize.pLog(Msg, v); g_dspInitialize.pLog(Msg, v);
} }
void DebugLog(const char* _fmt, ...) void DebugLog(const char* _fmt, ...)
{ {
#if defined(_DEBUG) || defined(DEBUGFAST) #if defined(_DEBUG) || defined(DEBUGFAST)
//if(strncmp (_fmt, "AX", 2)) // match = 0, in that case this is ignored //if(strncmp (_fmt, "AX", 2)) // match = 0, in that case this is ignored
{ {
char Msg[512]; char Msg[512];
va_list ap; va_list ap;
va_start(ap, _fmt); va_start(ap, _fmt);
vsprintf(Msg, _fmt, ap); vsprintf(Msg, _fmt, ap);
va_end(ap); va_end(ap);
g_dspInitialize.pLog(Msg, 0); g_dspInitialize.pLog(Msg, 0);
} }
#endif #endif
} }
extern u8* g_pMemory; extern u8* g_pMemory;
// TODO: Wii support? Most likely audio data still must be in the old 24MB TRAM. // TODO: Wii support? Most likely audio data still must be in the old 24MB TRAM.
#define RAM_MASK 0x1FFFFFF #define RAM_MASK 0x1FFFFFF
u8 Memory_Read_U8(u32 _uAddress) u8 Memory_Read_U8(u32 _uAddress)
{ {
_uAddress &= RAM_MASK; _uAddress &= RAM_MASK;
return g_pMemory[_uAddress]; return g_pMemory[_uAddress];
} }
u16 Memory_Read_U16(u32 _uAddress) u16 Memory_Read_U16(u32 _uAddress)
{ {
_uAddress &= RAM_MASK; _uAddress &= RAM_MASK;
return Common::swap16(*(u16*)&g_pMemory[_uAddress]); return Common::swap16(*(u16*)&g_pMemory[_uAddress]);
} }
u32 Memory_Read_U32(u32 _uAddress) u32 Memory_Read_U32(u32 _uAddress)
{ {
_uAddress &= RAM_MASK; _uAddress &= RAM_MASK;
return Common::swap32(*(u32*)&g_pMemory[_uAddress]); return Common::swap32(*(u32*)&g_pMemory[_uAddress]);
} }
float Memory_Read_Float(u32 _uAddress) float Memory_Read_Float(u32 _uAddress)
{ {
u32 uTemp = Memory_Read_U32(_uAddress); u32 uTemp = Memory_Read_U32(_uAddress);
return *(float*)&uTemp; return *(float*)&uTemp;
} }

View File

@ -1,226 +1,226 @@
// 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 "../Debugger/Debugger.h" #include "../Debugger/Debugger.h"
extern CDebugger* m_frame; extern CDebugger* m_frame;
// -------------------- // --------------------
// 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
// -------------------- // --------------------
// Settings // Settings
int nFiles = 4; int nFiles = 4;
// -------------------- // --------------------
// Create handles // Create handles
#ifdef DEBUG_HLE #ifdef DEBUG_HLE
FILE* __fStdOut[4]; // you have to update this manually, we can't place a nFiles in there FILE* __fStdOut[4]; // you have to update this manually, we can't place a nFiles in there
#endif #endif
#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 specify /* Start console window - width and height is the size of console window, if you specify
fname, the output will also be written to this file. TODO: Close the file pointer when the app fname, the output will also be written to this file. TODO: Close the file pointer when the app
is closed */ is closed */
// ------------- // -------------
void startConsoleWin(int width, int height, char* fname) void startConsoleWin(int width, int height, char* fname)
{ {
#if defined(DEBUG_HLE) && defined(_WIN32) #if defined(DEBUG_HLE) && defined(_WIN32)
AllocConsole(); AllocConsole();
SetConsoleTitle(fname); SetConsoleTitle(fname);
__hStdOut = GetStdHandle(STD_OUTPUT_HANDLE); __hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
COORD co = {width,height}; COORD co = {width,height};
SetConsoleScreenBufferSize(__hStdOut, co); SetConsoleScreenBufferSize(__hStdOut, co);
SMALL_RECT coo = {0,0,(width - 1),70}; // top, left, right, bottom SMALL_RECT coo = {0,0,(width - 1),70}; // top, left, right, bottom
SetConsoleWindowInfo(__hStdOut, TRUE, &coo); SetConsoleWindowInfo(__hStdOut, TRUE, &coo);
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
// Write to a file // Write to a file
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
} }
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
// File printf function // File printf function
int aprintf(int a, char *fmt, ...) int aprintf(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[5000]; // WARNING: mind this value char s[5000]; // 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, 5000, fmt, argptr); // remember to update this value to cnt = vsnprintf(s, 5000, 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);
// ------------- // -------------
return(cnt); return(cnt);
} }
else else
{ {
return 0; return 0;
} }
#else #else
return 0; return 0;
#endif #endif
} }
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
// Printf to screen function // Printf to screen function
int wprintf(const char *fmt, ...) int wprintf(const char *fmt, ...)
{ {
#if defined(DEBUG_HLE) && defined(_WIN32) #if defined(DEBUG_HLE) && defined(_WIN32)
char s[1024*20]; // Warning, mind this value char s[1024*20]; // 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, 1024*20, fmt, argptr); cnt = vsnprintf(s, 1024*20, fmt, argptr);
va_end(argptr); va_end(argptr);
DWORD cCharsWritten; DWORD cCharsWritten;
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
if(__hStdOut) if(__hStdOut)
{ {
WriteConsole(__hStdOut, s, strlen(s), &cCharsWritten, NULL); WriteConsole(__hStdOut, s, strlen(s), &cCharsWritten, NULL);
} }
// ------------- // -------------
return(cnt); return(cnt);
#else #else
return 0; return 0;
#endif #endif
} }
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
// Clear console screen // Clear console screen
void ClearScreen() void ClearScreen()
{ {
#if defined(DEBUG_HLE) && defined(_WIN32) #if defined(DEBUG_HLE) && defined(_WIN32)
if(g_consoleEnable) if(g_consoleEnable)
{ {
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 // Get window handle of console window to be able to resize it
#if defined(DEBUG_HLE) && defined(_WIN32) #if defined(DEBUG_HLE) && defined(_WIN32)
HWND GetConsoleHwnd(void) HWND GetConsoleHwnd(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 char pszNewWindowTitle[MY_BUFSIZE]; // Contains fabricated
// WindowTitle. // WindowTitle.
char pszOldWindowTitle[MY_BUFSIZE]; // Contains original char pszOldWindowTitle[MY_BUFSIZE]; // Contains original
// WindowTitle. // 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", wsprintf(pszNewWindowTitle,"%d/%d",
GetTickCount(), GetTickCount(),
GetCurrentProcessId()); 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

File diff suppressed because it is too large Load Diff

View File

@ -1,96 +1,96 @@
// 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 "MailHandler.h" #include "MailHandler.h"
CMailHandler::CMailHandler() CMailHandler::CMailHandler()
{ {
} }
CMailHandler::~CMailHandler() CMailHandler::~CMailHandler()
{ {
Clear(); Clear();
} }
void CMailHandler::PushMail(u32 _Mail) void CMailHandler::PushMail(u32 _Mail)
{ {
m_Mails.push(_Mail); m_Mails.push(_Mail);
Update(); Update();
} }
u16 CMailHandler::ReadDSPMailboxHigh() u16 CMailHandler::ReadDSPMailboxHigh()
{ {
// check if we have a mail for the core // check if we have a mail for the core
if (!m_Mails.empty()) if (!m_Mails.empty())
{ {
u16 result = (m_Mails.front() >> 16) & 0xFFFF; u16 result = (m_Mails.front() >> 16) & 0xFFFF;
Update(); Update();
return result; return result;
} }
return 0x00; return 0x00;
} }
u16 CMailHandler::ReadDSPMailboxLow() u16 CMailHandler::ReadDSPMailboxLow()
{ {
// check if we have a mail for the core // check if we have a mail for the core
if (!m_Mails.empty()) if (!m_Mails.empty())
{ {
u16 result = m_Mails.front() & 0xFFFF; u16 result = m_Mails.front() & 0xFFFF;
m_Mails.pop(); m_Mails.pop();
Update(); Update();
return(result); return(result);
} }
return 0x00; return 0x00;
} }
void CMailHandler::Clear() void CMailHandler::Clear()
{ {
while (!m_Mails.empty()) while (!m_Mails.empty())
m_Mails.pop(); m_Mails.pop();
} }
bool CMailHandler::IsEmpty() bool CMailHandler::IsEmpty()
{ {
return m_Mails.empty(); return m_Mails.empty();
} }
void CMailHandler::Halt(bool _Halt) void CMailHandler::Halt(bool _Halt)
{ {
if (_Halt) if (_Halt)
{ {
Clear(); Clear();
m_Mails.push(0x80544348); m_Mails.push(0x80544348);
} }
Update(); Update();
} }
void CMailHandler::Update() void CMailHandler::Update()
{ {
if (!IsEmpty()) if (!IsEmpty())
{ {
// g_dspInitialize.pGenerateDSPInterrupt(); // g_dspInitialize.pGenerateDSPInterrupt();
} }
} }

View File

@ -1,248 +1,248 @@
// 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 "stdafx.h" #include "stdafx.h"
#include <mmsystem.h> #include <mmsystem.h>
#include <dsound.h> #include <dsound.h>
#include "DSoundStream.h" #include "DSoundStream.h"
namespace DSound namespace DSound
{ {
#define BUFSIZE 32768 #define BUFSIZE 32768
#define MAXWAIT 70 //ms #define MAXWAIT 70 //ms
CRITICAL_SECTION soundCriticalSection; CRITICAL_SECTION soundCriticalSection;
HANDLE soundSyncEvent; HANDLE soundSyncEvent;
HANDLE hThread; HANDLE hThread;
StreamCallback callback; StreamCallback callback;
IDirectSound8* ds; IDirectSound8* ds;
IDirectSoundBuffer* dsBuffer; IDirectSoundBuffer* dsBuffer;
int bufferSize; //i bytes int bufferSize; //i bytes
int totalRenderedBytes; int totalRenderedBytes;
int sampleRate; int sampleRate;
// playback position // playback position
int currentPos; int currentPos;
int lastPos; int lastPos;
short realtimeBuffer[1024 * 1024]; short realtimeBuffer[1024 * 1024];
// We set this to shut down the sound thread. // We set this to shut down the sound thread.
// 0=keep playing, 1=stop playing NOW. // 0=keep playing, 1=stop playing NOW.
volatile int threadData; volatile int threadData;
inline int FIX128(int x) inline int FIX128(int x)
{ {
return(x & (~127)); return(x & (~127));
} }
int DSound_GetSampleRate() int DSound_GetSampleRate()
{ {
return(sampleRate); return(sampleRate);
} }
bool CreateBuffer() bool CreateBuffer()
{ {
PCMWAVEFORMAT pcmwf; PCMWAVEFORMAT pcmwf;
DSBUFFERDESC dsbdesc; DSBUFFERDESC dsbdesc;
memset(&pcmwf, 0, sizeof(PCMWAVEFORMAT)); memset(&pcmwf, 0, sizeof(PCMWAVEFORMAT));
memset(&dsbdesc, 0, sizeof(DSBUFFERDESC)); memset(&dsbdesc, 0, sizeof(DSBUFFERDESC));
pcmwf.wf.wFormatTag = WAVE_FORMAT_PCM; pcmwf.wf.wFormatTag = WAVE_FORMAT_PCM;
pcmwf.wf.nChannels = 2; pcmwf.wf.nChannels = 2;
pcmwf.wf.nSamplesPerSec = sampleRate; pcmwf.wf.nSamplesPerSec = sampleRate;
pcmwf.wf.nBlockAlign = 4; pcmwf.wf.nBlockAlign = 4;
pcmwf.wf.nAvgBytesPerSec = pcmwf.wf.nSamplesPerSec * pcmwf.wf.nBlockAlign; pcmwf.wf.nAvgBytesPerSec = pcmwf.wf.nSamplesPerSec * pcmwf.wf.nBlockAlign;
pcmwf.wBitsPerSample = 16; pcmwf.wBitsPerSample = 16;
//buffer description //buffer description
dsbdesc.dwSize = sizeof(DSBUFFERDESC); dsbdesc.dwSize = sizeof(DSBUFFERDESC);
dsbdesc.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_STICKYFOCUS; //VIKTIGT //DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLFREQUENCY; dsbdesc.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_STICKYFOCUS; //VIKTIGT //DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLFREQUENCY;
dsbdesc.dwBufferBytes = bufferSize = BUFSIZE; dsbdesc.dwBufferBytes = bufferSize = BUFSIZE;
dsbdesc.lpwfxFormat = (WAVEFORMATEX*)&pcmwf; dsbdesc.lpwfxFormat = (WAVEFORMATEX*)&pcmwf;
if (SUCCEEDED(ds->CreateSoundBuffer(&dsbdesc, &dsBuffer, NULL))) if (SUCCEEDED(ds->CreateSoundBuffer(&dsbdesc, &dsBuffer, NULL)))
{ {
dsBuffer->SetCurrentPosition(0); dsBuffer->SetCurrentPosition(0);
return(true); return(true);
} }
else else
{ {
// Failed. // Failed.
dsBuffer = NULL; dsBuffer = NULL;
return(false); return(false);
} }
} }
bool WriteDataToBuffer(DWORD dwOffset, // Our own write cursor. bool WriteDataToBuffer(DWORD dwOffset, // Our own write cursor.
char* soundData, // Start of our data. char* soundData, // Start of our data.
DWORD dwSoundBytes) // Size of block to copy. DWORD dwSoundBytes) // Size of block to copy.
{ {
void* ptr1, * ptr2; void* ptr1, * ptr2;
DWORD numBytes1, numBytes2; DWORD numBytes1, numBytes2;
// Obtain memory address of write block. This will be in two parts if the block wraps around. // Obtain memory address of write block. This will be in two parts if the block wraps around.
HRESULT hr = dsBuffer->Lock(dwOffset, dwSoundBytes, &ptr1, &numBytes1, &ptr2, &numBytes2, 0); HRESULT hr = dsBuffer->Lock(dwOffset, dwSoundBytes, &ptr1, &numBytes1, &ptr2, &numBytes2, 0);
// If the buffer was lost, restore and retry lock. // If the buffer was lost, restore and retry lock.
if (DSERR_BUFFERLOST == hr) if (DSERR_BUFFERLOST == hr)
{ {
dsBuffer->Restore(); dsBuffer->Restore();
hr = dsBuffer->Lock(dwOffset, dwSoundBytes, &ptr1, &numBytes1, &ptr2, &numBytes2, 0); hr = dsBuffer->Lock(dwOffset, dwSoundBytes, &ptr1, &numBytes1, &ptr2, &numBytes2, 0);
} }
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
memcpy(ptr1, soundData, numBytes1); memcpy(ptr1, soundData, numBytes1);
if (ptr2 != 0) if (ptr2 != 0)
{ {
memcpy(ptr2, soundData + numBytes1, numBytes2); memcpy(ptr2, soundData + numBytes1, numBytes2);
} }
// Release the data back to DirectSound. // Release the data back to DirectSound.
dsBuffer->Unlock(ptr1, numBytes1, ptr2, numBytes2); dsBuffer->Unlock(ptr1, numBytes1, ptr2, numBytes2);
return(true); return(true);
} }
return(false); return(false);
} }
inline int ModBufferSize(int x) inline int ModBufferSize(int x)
{ {
return((x + bufferSize) % bufferSize); return((x + bufferSize) % bufferSize);
} }
// The audio thread. // The audio thread.
DWORD WINAPI soundThread(void*) DWORD WINAPI soundThread(void*)
{ {
currentPos = 0; currentPos = 0;
lastPos = 0; lastPos = 0;
// Prefill buffer? // Prefill buffer?
//writeDataToBuffer(0,realtimeBuffer,bufferSize); //writeDataToBuffer(0,realtimeBuffer,bufferSize);
// dsBuffer->Lock(0, bufferSize, (void **)&p1, &num1, (void **)&p2, &num2, 0); // dsBuffer->Lock(0, bufferSize, (void **)&p1, &num1, (void **)&p2, &num2, 0);
dsBuffer->Play(0, 0, DSBPLAY_LOOPING); dsBuffer->Play(0, 0, DSBPLAY_LOOPING);
while (!threadData) while (!threadData)
{ {
// No blocking inside the csection // No blocking inside the csection
EnterCriticalSection(&soundCriticalSection); EnterCriticalSection(&soundCriticalSection);
dsBuffer->GetCurrentPosition((DWORD*)&currentPos, 0); dsBuffer->GetCurrentPosition((DWORD*)&currentPos, 0);
int numBytesToRender = FIX128(ModBufferSize(currentPos - lastPos)); int numBytesToRender = FIX128(ModBufferSize(currentPos - lastPos));
if (numBytesToRender >= 256) if (numBytesToRender >= 256)
{ {
if (numBytesToRender > sizeof(realtimeBuffer)) if (numBytesToRender > sizeof(realtimeBuffer))
MessageBox(0,"soundThread: too big render call",0,0); MessageBox(0,"soundThread: too big render call",0,0);
(*callback)(realtimeBuffer, numBytesToRender >> 2, 16, sampleRate, 2); (*callback)(realtimeBuffer, numBytesToRender >> 2, 16, sampleRate, 2);
WriteDataToBuffer(lastPos, (char*)realtimeBuffer, numBytesToRender); WriteDataToBuffer(lastPos, (char*)realtimeBuffer, numBytesToRender);
currentPos = ModBufferSize(lastPos + numBytesToRender); currentPos = ModBufferSize(lastPos + numBytesToRender);
totalRenderedBytes += numBytesToRender; totalRenderedBytes += numBytesToRender;
lastPos = currentPos; lastPos = currentPos;
} }
LeaveCriticalSection(&soundCriticalSection); LeaveCriticalSection(&soundCriticalSection);
WaitForSingleObject(soundSyncEvent, MAXWAIT); WaitForSingleObject(soundSyncEvent, MAXWAIT);
} }
dsBuffer->Stop(); dsBuffer->Stop();
return(0); //hurra! return(0); //hurra!
} }
bool DSound_StartSound(HWND window, int _sampleRate, StreamCallback _callback) bool DSound_StartSound(HWND window, int _sampleRate, StreamCallback _callback)
{ {
callback = _callback; callback = _callback;
threadData = 0; threadData = 0;
sampleRate = _sampleRate; sampleRate = _sampleRate;
//no security attributes, automatic resetting, init state nonset, untitled //no security attributes, automatic resetting, init state nonset, untitled
soundSyncEvent = CreateEvent(0, false, false, 0); soundSyncEvent = CreateEvent(0, false, false, 0);
//vi initierar den........... //vi initierar den...........
InitializeCriticalSection(&soundCriticalSection); InitializeCriticalSection(&soundCriticalSection);
//vi vill ha access till DSOUND så... //vi vill ha access till DSOUND så...
if (FAILED(DirectSoundCreate8(0, &ds, 0))) if (FAILED(DirectSoundCreate8(0, &ds, 0)))
return false; return false;
ds->SetCooperativeLevel(window, DSSCL_NORMAL); ds->SetCooperativeLevel(window, DSSCL_NORMAL);
if (!CreateBuffer()) if (!CreateBuffer())
{ {
return false; return false;
} }
DWORD num1; DWORD num1;
short* p1; short* p1;
dsBuffer->Lock(0, bufferSize, (void* *)&p1, &num1, 0, 0, 0); dsBuffer->Lock(0, bufferSize, (void* *)&p1, &num1, 0, 0, 0);
memset(p1, 0, num1); memset(p1, 0, num1);
dsBuffer->Unlock(p1, num1, 0, 0); dsBuffer->Unlock(p1, num1, 0, 0);
totalRenderedBytes = -bufferSize; totalRenderedBytes = -bufferSize;
DWORD h; DWORD h;
hThread = CreateThread(0, 0, soundThread, 0, 0, &h); hThread = CreateThread(0, 0, soundThread, 0, 0, &h);
SetThreadPriority(hThread, THREAD_PRIORITY_ABOVE_NORMAL); SetThreadPriority(hThread, THREAD_PRIORITY_ABOVE_NORMAL);
return true; return true;
} }
void DSound_UpdateSound() void DSound_UpdateSound()
{ {
SetEvent(soundSyncEvent); SetEvent(soundSyncEvent);
} }
void DSound_StopSound() void DSound_StopSound()
{ {
EnterCriticalSection(&soundCriticalSection); EnterCriticalSection(&soundCriticalSection);
threadData = 1; threadData = 1;
// kick the thread if it's waiting // kick the thread if it's waiting
SetEvent(soundSyncEvent); SetEvent(soundSyncEvent);
LeaveCriticalSection(&soundCriticalSection); LeaveCriticalSection(&soundCriticalSection);
WaitForSingleObject(hThread, INFINITE); WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread); CloseHandle(hThread);
dsBuffer->Release(); dsBuffer->Release();
ds->Release(); ds->Release();
CloseHandle(soundSyncEvent); CloseHandle(soundSyncEvent);
soundSyncEvent = INVALID_HANDLE_VALUE; soundSyncEvent = INVALID_HANDLE_VALUE;
hThread = INVALID_HANDLE_VALUE; hThread = INVALID_HANDLE_VALUE;
} }
int DSound_GetCurSample() int DSound_GetCurSample()
{ {
EnterCriticalSection(&soundCriticalSection); EnterCriticalSection(&soundCriticalSection);
int playCursor; int playCursor;
dsBuffer->GetCurrentPosition((DWORD*)&playCursor, 0); dsBuffer->GetCurrentPosition((DWORD*)&playCursor, 0);
playCursor = ModBufferSize(playCursor - lastPos) + totalRenderedBytes; playCursor = ModBufferSize(playCursor - lastPos) + totalRenderedBytes;
LeaveCriticalSection(&soundCriticalSection); LeaveCriticalSection(&soundCriticalSection);
return(playCursor); return(playCursor);
} }
float DSound_GetTimer() float DSound_GetTimer()
{ {
return((float)DSound_GetCurSample() * (1.0f / (4.0f * sampleRate))); return((float)DSound_GetCurSample() * (1.0f / (4.0f * sampleRate)));
} }
} // namespace } // namespace

View File

@ -1,183 +1,183 @@
// 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/
// This queue solution is temporary. I'll implement something more efficient later. // This queue solution is temporary. I'll implement something more efficient later.
#include <queue> #include <queue>
#include "../Config.h" #include "../Config.h"
#include "../Globals.h" #include "../Globals.h"
#include "../DSPHandler.h" #include "../DSPHandler.h"
#include "../Logging/Console.h" #include "../Logging/Console.h"
#include "Thread.h" #include "Thread.h"
#include "Mixer.h" #include "Mixer.h"
#include "FixedSizeQueue.h" #include "FixedSizeQueue.h"
#ifdef _WIN32 #ifdef _WIN32
#include "../PCHW/DSoundStream.h" #include "../PCHW/DSoundStream.h"
#endif #endif
namespace { namespace {
Common::CriticalSection push_sync; Common::CriticalSection push_sync;
// On real hardware, this fifo is much, much smaller. But timing is also tighter than under Windows, so... // On real hardware, this fifo is much, much smaller. But timing is also tighter than under Windows, so...
const int queue_minlength = 1024 * 4; const int queue_minlength = 1024 * 4;
const int queue_maxlength = 1024 * 28; const int queue_maxlength = 1024 * 28;
FixedSizeQueue<s16, queue_maxlength> sample_queue; FixedSizeQueue<s16, queue_maxlength> sample_queue;
} // namespace } // namespace
volatile bool mixer_HLEready = false; volatile bool mixer_HLEready = false;
volatile int queue_size = 0; volatile int queue_size = 0;
void Mixer(short *buffer, int numSamples, int bits, int rate, int channels) void Mixer(short *buffer, int numSamples, int bits, int rate, int channels)
{ {
// silence // silence
memset(buffer, 0, numSamples * 2 * sizeof(short)); memset(buffer, 0, numSamples * 2 * sizeof(short));
// first get the DTK Music // first get the DTK Music
if (g_Config.m_EnableDTKMusic) if (g_Config.m_EnableDTKMusic)
{ {
g_dspInitialize.pGetAudioStreaming(buffer, numSamples); g_dspInitialize.pGetAudioStreaming(buffer, numSamples);
} }
//if this was called directly from the HLE, and not by timeout //if this was called directly from the HLE, and not by timeout
if (g_Config.m_EnableHLEAudio && mixer_HLEready) if (g_Config.m_EnableHLEAudio && mixer_HLEready)
{ {
IUCode* pUCode = CDSPHandler::GetInstance().GetUCode(); IUCode* pUCode = CDSPHandler::GetInstance().GetUCode();
if (pUCode != NULL) if (pUCode != NULL)
pUCode->MixAdd(buffer, numSamples); pUCode->MixAdd(buffer, numSamples);
} }
push_sync.Enter(); push_sync.Enter();
int count = 0; int count = 0;
while (queue_size > queue_minlength && count < numSamples * 2) { while (queue_size > queue_minlength && count < numSamples * 2) {
int x = buffer[count]; int x = buffer[count];
x += sample_queue.front(); x += sample_queue.front();
if (x > 32767) x = 32767; if (x > 32767) x = 32767;
if (x < -32767) x = -32767; if (x < -32767) x = -32767;
buffer[count++] = x; buffer[count++] = x;
sample_queue.pop(); sample_queue.pop();
x = buffer[count]; x = buffer[count];
x += sample_queue.front(); x += sample_queue.front();
if (x > 32767) x = 32767; if (x > 32767) x = 32767;
if (x < -32767) x = -32767; if (x < -32767) x = -32767;
buffer[count++] = x; buffer[count++] = x;
sample_queue.pop(); sample_queue.pop();
queue_size-=2; queue_size-=2;
} }
push_sync.Leave(); push_sync.Leave();
} }
void Mixer_PushSamples(short *buffer, int num_stereo_samples, int sample_rate) { void Mixer_PushSamples(short *buffer, int num_stereo_samples, int sample_rate) {
// static FILE *f; // static FILE *f;
// if (!f) // if (!f)
// f = fopen("d:\\hello.raw", "wb"); // f = fopen("d:\\hello.raw", "wb");
// fwrite(buffer, num_stereo_samples * 4, 1, f); // fwrite(buffer, num_stereo_samples * 4, 1, f);
if (queue_size == 0) if (queue_size == 0)
{ {
queue_size = queue_minlength; queue_size = queue_minlength;
for (int i = 0; i < queue_minlength; i++) for (int i = 0; i < queue_minlength; i++)
sample_queue.push((s16)0); sample_queue.push((s16)0);
} }
static int PV1l=0,PV2l=0,PV3l=0,PV4l=0; static int PV1l=0,PV2l=0,PV3l=0,PV4l=0;
static int PV1r=0,PV2r=0,PV3r=0,PV4r=0; static int PV1r=0,PV2r=0,PV3r=0,PV4r=0;
static int acc=0; static int acc=0;
#ifdef _WIN32 #ifdef _WIN32
if (! (GetAsyncKeyState(VK_TAB)) && g_Config.m_EnableThrottle) { if (! (GetAsyncKeyState(VK_TAB)) && g_Config.m_EnableThrottle) {
/* This is only needed for non-AX sound, currently directly streamed and /* This is only needed for non-AX sound, currently directly streamed and
DTK sound. For AX we call DSound_UpdateSound in AXTask() for example. */ DTK sound. For AX we call DSound_UpdateSound in AXTask() for example. */
while (queue_size > queue_maxlength / 2) { while (queue_size > queue_maxlength / 2) {
DSound::DSound_UpdateSound(); DSound::DSound_UpdateSound();
Sleep(0); Sleep(0);
} }
} else { } else {
return; return;
} }
#else #else
while (queue_size > queue_maxlength) { while (queue_size > queue_maxlength) {
sleep(0); sleep(0);
} }
#endif #endif
//convert into config option? //convert into config option?
const int mode = 2; const int mode = 2;
push_sync.Enter(); push_sync.Enter();
while (num_stereo_samples) while (num_stereo_samples)
{ {
acc += sample_rate; acc += sample_rate;
while (num_stereo_samples && (acc >= 48000)) while (num_stereo_samples && (acc >= 48000))
{ {
PV4l=PV3l; PV4l=PV3l;
PV3l=PV2l; PV3l=PV2l;
PV2l=PV1l; PV2l=PV1l;
PV1l=*(buffer++); //32bit processing PV1l=*(buffer++); //32bit processing
PV4r=PV3r; PV4r=PV3r;
PV3r=PV2r; PV3r=PV2r;
PV2r=PV1r; PV2r=PV1r;
PV1r=*(buffer++); //32bit processing PV1r=*(buffer++); //32bit processing
num_stereo_samples--; num_stereo_samples--;
acc-=48000; acc-=48000;
} }
// defaults to nearest // defaults to nearest
s32 DataL = PV1l; s32 DataL = PV1l;
s32 DataR = PV1r; s32 DataR = PV1r;
if (mode == 1) //linear if (mode == 1) //linear
{ {
DataL = PV1l + ((PV2l - PV1l)*acc)/48000; DataL = PV1l + ((PV2l - PV1l)*acc)/48000;
DataR = PV1r + ((PV2r - PV1r)*acc)/48000; DataR = PV1r + ((PV2r - PV1r)*acc)/48000;
} }
else if (mode == 2) //cubic else if (mode == 2) //cubic
{ {
s32 a0l = PV1l - PV2l - PV4l + PV3l; s32 a0l = PV1l - PV2l - PV4l + PV3l;
s32 a0r = PV1r - PV2r - PV4r + PV3r; s32 a0r = PV1r - PV2r - PV4r + PV3r;
s32 a1l = PV4l - PV3l - a0l; s32 a1l = PV4l - PV3l - a0l;
s32 a1r = PV4r - PV3r - a0r; s32 a1r = PV4r - PV3r - a0r;
s32 a2l = PV1l - PV4l; s32 a2l = PV1l - PV4l;
s32 a2r = PV1r - PV4r; s32 a2r = PV1r - PV4r;
s32 a3l = PV2l; s32 a3l = PV2l;
s32 a3r = PV2r; s32 a3r = PV2r;
s32 t0l = ((a0l )*acc)/48000; s32 t0l = ((a0l )*acc)/48000;
s32 t0r = ((a0r )*acc)/48000; s32 t0r = ((a0r )*acc)/48000;
s32 t1l = ((t0l+a1l)*acc)/48000; s32 t1l = ((t0l+a1l)*acc)/48000;
s32 t1r = ((t0r+a1r)*acc)/48000; s32 t1r = ((t0r+a1r)*acc)/48000;
s32 t2l = ((t1l+a2l)*acc)/48000; s32 t2l = ((t1l+a2l)*acc)/48000;
s32 t2r = ((t1r+a2r)*acc)/48000; s32 t2r = ((t1r+a2r)*acc)/48000;
s32 t3l = ((t2l+a3l)); s32 t3l = ((t2l+a3l));
s32 t3r = ((t2r+a3r)); s32 t3r = ((t2r+a3r));
DataL = t3l; DataL = t3l;
DataR = t3r; DataR = t3r;
} }
int l = DataL, r = DataR; int l = DataL, r = DataR;
if (l < -32767) l = -32767; if (l < -32767) l = -32767;
if (r < -32767) r = -32767; if (r < -32767) r = -32767;
if (l > 32767) l = 32767; if (l > 32767) l = 32767;
if (r > 32767) r = 32767; if (r > 32767) r = 32767;
sample_queue.push(l); sample_queue.push(l);
sample_queue.push(r); sample_queue.push(r);
queue_size += 2; queue_size += 2;
} }
push_sync.Leave(); push_sync.Leave();
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,432 +1,432 @@
// 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 "StringUtil.h" #include "StringUtil.h"
#include "../Debugger/Debugger.h" #include "../Debugger/Debugger.h"
#include "../Logging/Console.h" // for aprintf #include "../Logging/Console.h" // for aprintf
#ifdef _WIN32 #ifdef _WIN32
#include "../PCHW/DSoundStream.h" #include "../PCHW/DSoundStream.h"
#endif #endif
#include "../PCHW/Mixer.h" #include "../PCHW/Mixer.h"
#include "../MailHandler.h" #include "../MailHandler.h"
#include "UCodes.h" #include "UCodes.h"
#include "UCode_AXStructs.h" #include "UCode_AXStructs.h"
#include "UCode_AX.h" // for some functions in CUCode_AX #include "UCode_AX.h" // for some functions in CUCode_AX
#include "UCode_AXWii.h" #include "UCode_AXWii.h"
#include "UCode_AX_Voice.h" #include "UCode_AX_Voice.h"
// ------------------------------------------------------------------ // ------------------------------------------------------------------
// Declarations // Declarations
// ----------- // -----------
extern bool gSequenced; extern bool gSequenced;
extern CDebugger * m_frame; extern CDebugger * m_frame;
// ----------- // -----------
CUCode_AXWii::CUCode_AXWii(CMailHandler& _rMailHandler, u32 l_CRC) CUCode_AXWii::CUCode_AXWii(CMailHandler& _rMailHandler, u32 l_CRC)
: IUCode(_rMailHandler) : IUCode(_rMailHandler)
, m_addressPBs(0xFFFFFFFF) , m_addressPBs(0xFFFFFFFF)
, _CRC(l_CRC) , _CRC(l_CRC)
{ {
// we got loaded // we got loaded
m_rMailHandler.PushMail(0xDCD10000); m_rMailHandler.PushMail(0xDCD10000);
m_rMailHandler.PushMail(0x80000000); // handshake ??? only (crc == 0xe2136399) needs it ... m_rMailHandler.PushMail(0x80000000); // handshake ??? only (crc == 0xe2136399) needs it ...
templbuffer = new int[1024 * 1024]; templbuffer = new int[1024 * 1024];
temprbuffer = new int[1024 * 1024]; temprbuffer = new int[1024 * 1024];
lCUCode_AX = new CUCode_AX(_rMailHandler); lCUCode_AX = new CUCode_AX(_rMailHandler);
lCUCode_AX->_CRC = l_CRC; lCUCode_AX->_CRC = l_CRC;
} }
CUCode_AXWii::~CUCode_AXWii() CUCode_AXWii::~CUCode_AXWii()
{ {
m_rMailHandler.Clear(); m_rMailHandler.Clear();
delete [] templbuffer; delete [] templbuffer;
delete [] temprbuffer; delete [] temprbuffer;
} }
void CUCode_AXWii::HandleMail(u32 _uMail) void CUCode_AXWii::HandleMail(u32 _uMail)
{ {
if ((_uMail & 0xFFFF0000) == MAIL_AX_ALIST) if ((_uMail & 0xFFFF0000) == MAIL_AX_ALIST)
{ {
// a new List // a new List
} }
else else
{ {
AXTask(_uMail); AXTask(_uMail);
} }
} }
void CUCode_AXWii::MixAdd(short* _pBuffer, int _iSize) void CUCode_AXWii::MixAdd(short* _pBuffer, int _iSize)
{ {
if(_CRC == 0xfa450138) if(_CRC == 0xfa450138)
{ {
AXParamBlockWii PBs[NUMBER_OF_PBS]; AXParamBlockWii PBs[NUMBER_OF_PBS];
MixAdd_( _pBuffer, _iSize, PBs); MixAdd_( _pBuffer, _iSize, PBs);
} }
else else
{ {
AXParamBlockWii_ PBs[NUMBER_OF_PBS]; AXParamBlockWii_ PBs[NUMBER_OF_PBS];
MixAdd_(_pBuffer, _iSize, PBs); MixAdd_(_pBuffer, _iSize, PBs);
} }
} }
template<class ParamBlockType> template<class ParamBlockType>
void CUCode_AXWii::MixAdd_(short* _pBuffer, int _iSize, ParamBlockType &PBs) void CUCode_AXWii::MixAdd_(short* _pBuffer, int _iSize, ParamBlockType &PBs)
{ {
//AXParamBlockWii PBs[NUMBER_OF_PBS]; //AXParamBlockWii PBs[NUMBER_OF_PBS];
// read out pbs // read out pbs
int numberOfPBs = ReadOutPBsWii(m_addressPBs, PBs, NUMBER_OF_PBS); int numberOfPBs = ReadOutPBsWii(m_addressPBs, PBs, NUMBER_OF_PBS);
if (_iSize > 1024 * 1024) if (_iSize > 1024 * 1024)
_iSize = 1024 * 1024; _iSize = 1024 * 1024;
// write zeroes to the beginning of templbuffer // write zeroes to the beginning of templbuffer
memset(templbuffer, 0, _iSize * sizeof(int)); memset(templbuffer, 0, _iSize * sizeof(int));
memset(temprbuffer, 0, _iSize * sizeof(int)); memset(temprbuffer, 0, _iSize * sizeof(int));
// ------------------------------------------- // -------------------------------------------
// write logging data to debugger // write logging data to debugger
if (m_frame) if (m_frame)
{ {
lCUCode_AX->Logging(_pBuffer, _iSize, 0, true); lCUCode_AX->Logging(_pBuffer, _iSize, 0, true);
// ------------------------------------------- // -------------------------------------------
// Write the first block values // Write the first block values
int p = numberOfPBs - 1; int p = numberOfPBs - 1;
if(numberOfPBs > p) if(numberOfPBs > p)
{ {
if(PBs[p].running && !m_frame->upd95) if(PBs[p].running && !m_frame->upd95)
{ {
const u32 blockAddr = (u32)(PBs[p].this_pb_hi<< 16) | PBs[p].this_pb_lo; const u32 blockAddr = (u32)(PBs[p].this_pb_hi<< 16) | PBs[p].this_pb_lo;
const short *pSrc = (const short *)g_dspInitialize.pGetMemoryPointer(blockAddr); const short *pSrc = (const short *)g_dspInitialize.pGetMemoryPointer(blockAddr);
for (u32 i = 0; i < sizeof(AXParamBlockWii) / 2; i+=2) for (u32 i = 0; i < sizeof(AXParamBlockWii) / 2; i+=2)
{ {
if(i == 10 || i == 34 || i == 41 || i == 46 || i == 46 || i == 58 || i == 60 if(i == 10 || i == 34 || i == 41 || i == 46 || i == 46 || i == 58 || i == 60
|| i == 68 || i == 88 || i == 95) || i == 68 || i == 88 || i == 95)
{m_frame->str0 += "\n"; m_frame->str95 += "\n";} {m_frame->str0 += "\n"; m_frame->str95 += "\n";}
std::string line = StringFromFormat("%02i|%02i : %s : %s", std::string line = StringFromFormat("%02i|%02i : %s : %s",
i/2, i, i/2, i,
m_frame->PBn[i].c_str(), m_frame->PBp[i].c_str() m_frame->PBn[i].c_str(), m_frame->PBp[i].c_str()
); );
for (u32 j = 0; j < 50 - line.length(); ++j) for (u32 j = 0; j < 50 - line.length(); ++j)
line += " "; line += " ";
m_frame->str0 += line; m_frame->str0 += line;
m_frame->str0 += "\n"; m_frame->str0 += "\n";
m_frame->str95 += StringFromFormat(" : %02i|%02i : %04x%04x\n", m_frame->str95 += StringFromFormat(" : %02i|%02i : %04x%04x\n",
i/2, i, i/2, i,
Common::swap16(pSrc[i]), Common::swap16(pSrc[i+1])); Common::swap16(pSrc[i]), Common::swap16(pSrc[i+1]));
} }
m_frame->m_bl95->AppendText(wxString::FromAscii(m_frame->str95.c_str())); m_frame->m_bl95->AppendText(wxString::FromAscii(m_frame->str95.c_str()));
m_frame->m_bl0->AppendText(wxString::FromAscii(m_frame->str0.c_str())); m_frame->m_bl0->AppendText(wxString::FromAscii(m_frame->str0.c_str()));
m_frame->upd95 = true; m_frame->upd95 = true;
} }
} }
} }
// ----------------- // -----------------
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
/* Make the updates we are told to do. See comments to the GC version in UCode_AX.cpp */ /* Make the updates we are told to do. See comments to the GC version in UCode_AX.cpp */
// ------------ // ------------
for (int i = 0; i < numberOfPBs; i++) for (int i = 0; i < numberOfPBs; i++)
{ {
u16 *pDest = (u16 *)&PBs[i]; u16 *pDest = (u16 *)&PBs[i];
u16 upd0 = pDest[41]; u16 upd1 = pDest[42]; u16 upd2 = pDest[43]; // num_updates u16 upd0 = pDest[41]; u16 upd1 = pDest[42]; u16 upd2 = pDest[43]; // num_updates
u16 upd_hi = pDest[44]; // update addr u16 upd_hi = pDest[44]; // update addr
u16 upd_lo = pDest[45]; u16 upd_lo = pDest[45];
int numupd = upd0 + upd1 + upd2; int numupd = upd0 + upd1 + upd2;
if(numupd > 64) numupd = 64; // prevent to high values if(numupd > 64) numupd = 64; // prevent to high values
const u32 updaddr = (u32)(upd_hi << 16) | upd_lo; const u32 updaddr = (u32)(upd_hi << 16) | upd_lo;
int on = false, off = false; int on = false, off = false;
for (int j = 0; j < numupd; j++) // make alll updates for (int j = 0; j < numupd; j++) // make alll updates
{ {
const u16 updpar = Memory_Read_U16(updaddr); const u16 updpar = Memory_Read_U16(updaddr);
const u16 upddata = Memory_Read_U16(updaddr + 2); const u16 upddata = Memory_Read_U16(updaddr + 2);
// some safety checks, I hope it's enough // some safety checks, I hope it's enough
if( ( (updaddr > 0x80000000 && updaddr < 0x817fffff) if( ( (updaddr > 0x80000000 && updaddr < 0x817fffff)
|| (updaddr > 0x90000000 && updaddr < 0x93ffffff) ) || (updaddr > 0x90000000 && updaddr < 0x93ffffff) )
&& updpar < 127 && updpar > 3 && upddata >= 0 // updpar > 3 because we don't want to change && updpar < 127 && updpar > 3 && upddata >= 0 // updpar > 3 because we don't want to change
// 0-3, those are important // 0-3, those are important
//&& (upd0 || upd1 || upd2) // We should use these in some way to I think //&& (upd0 || upd1 || upd2) // We should use these in some way to I think
// but I don't know how or when // but I don't know how or when
&& gSequenced) // on and off option && gSequenced) // on and off option
{ {
//PanicAlert("Update %i: %i = %04x", i, updpar, upddata); //PanicAlert("Update %i: %i = %04x", i, updpar, upddata);
//DebugLog("Update: %i = %04x", updpar, upddata); //DebugLog("Update: %i = %04x", updpar, upddata);
pDest[updpar] = upddata; pDest[updpar] = upddata;
} }
if (updpar == 7 && upddata == 1) on++; if (updpar == 7 && upddata == 1) on++;
if (updpar == 7 && upddata == 1) off++; if (updpar == 7 && upddata == 1) off++;
} }
// hack: if we get both an on and an off select on rather than off // hack: if we get both an on and an off select on rather than off
if (on > 0 && off > 0) pDest[7] = 1; if (on > 0 && off > 0) pDest[7] = 1;
} }
//aprintf(1, "%08x %04x %04x\n", updaddr, updpar, upddata); //aprintf(1, "%08x %04x %04x\n", updaddr, updpar, upddata);
// ------------ // ------------
for (int i = 0; i < numberOfPBs; i++) for (int i = 0; i < numberOfPBs; i++)
{ {
MixAddVoice(PBs[i], templbuffer, temprbuffer, _iSize, true); MixAddVoice(PBs[i], templbuffer, temprbuffer, _iSize, true);
} }
WriteBackPBsWii(m_addressPBs, PBs, numberOfPBs); WriteBackPBsWii(m_addressPBs, PBs, numberOfPBs);
// We write the sound to _pBuffer // We write the sound to _pBuffer
for (int i = 0; i < _iSize; i++) for (int i = 0; i < _iSize; i++)
{ {
// Clamp into 16-bit. Maybe we should add a volume compressor here. // Clamp into 16-bit. Maybe we should add a volume compressor here.
int left = templbuffer[i] + _pBuffer[0]; int left = templbuffer[i] + _pBuffer[0];
int right = temprbuffer[i] + _pBuffer[1]; int right = temprbuffer[i] + _pBuffer[1];
if (left < -32767) left = -32767; if (left < -32767) left = -32767;
if (left > 32767) left = 32767; if (left > 32767) left = 32767;
if (right < -32767) right = -32767; if (right < -32767) right = -32767;
if (right > 32767) right = 32767; if (right > 32767) right = 32767;
*_pBuffer++ = left; *_pBuffer++ = left;
*_pBuffer++ = right; *_pBuffer++ = right;
} }
// write logging data to debugger again after the update // write logging data to debugger again after the update
if (m_frame) if (m_frame)
{ {
lCUCode_AX->Logging(_pBuffer, _iSize, 1, true); lCUCode_AX->Logging(_pBuffer, _iSize, 1, true);
} }
} }
void CUCode_AXWii::Update() void CUCode_AXWii::Update()
{ {
// check if we have to sent something // check if we have to sent something
if (!m_rMailHandler.IsEmpty()) if (!m_rMailHandler.IsEmpty())
{ {
g_dspInitialize.pGenerateDSPInterrupt(); g_dspInitialize.pGenerateDSPInterrupt();
} }
} }
// Shortcut // Shortcut
void CUCode_AXWii::SaveLog(const char* _fmt, ...) void CUCode_AXWii::SaveLog(const char* _fmt, ...)
{ {
va_list ap; va_start(ap, _fmt); if(m_frame) lCUCode_AX->SaveLog_(true, _fmt, ap); va_end(ap); va_list ap; va_start(ap, _fmt); if(m_frame) lCUCode_AX->SaveLog_(true, _fmt, ap); va_end(ap);
} }
// AX seems to bootup one task only and waits for resume-callbacks // AX seems to bootup one task only and waits for resume-callbacks
// everytime the DSP has "spare time" it sends a resume-mail to the CPU // everytime the DSP has "spare time" it sends a resume-mail to the CPU
// and the __DSPHandler calls a AX-Callback which generates a new AXFrame // and the __DSPHandler calls a AX-Callback which generates a new AXFrame
bool CUCode_AXWii::AXTask(u32& _uMail) bool CUCode_AXWii::AXTask(u32& _uMail)
{ {
u32 uAddress = _uMail; u32 uAddress = _uMail;
SaveLog("Begin"); SaveLog("Begin");
SaveLog("====================================================================="); SaveLog("=====================================================================");
SaveLog("%08x: AXTask - AXCommandList-Addr", uAddress); SaveLog("%08x: AXTask - AXCommandList-Addr", uAddress);
u32 Addr__AXStudio; u32 Addr__AXStudio;
u32 Addr__AXOutSBuffer; u32 Addr__AXOutSBuffer;
// u32 Addr__AXOutSBuffer_1; // u32 Addr__AXOutSBuffer_1;
// u32 Addr__AXOutSBuffer_2; // u32 Addr__AXOutSBuffer_2;
u32 Addr__A; u32 Addr__A;
// u32 Addr__12; // u32 Addr__12;
u32 Addr__5_1; u32 Addr__5_1;
u32 Addr__5_2; u32 Addr__5_2;
u32 Addr__6; u32 Addr__6;
// u32 Addr__9; // u32 Addr__9;
bool bExecuteList = true; bool bExecuteList = true;
if(m_frame) lCUCode_AX->SaveMail(true, uAddress); // Save mail for debugging if(m_frame) lCUCode_AX->SaveMail(true, uAddress); // Save mail for debugging
if (false) if (false)
{ {
// PanicAlert("%i", sizeof(AXParamBlockWii)); // 252 ?? // PanicAlert("%i", sizeof(AXParamBlockWii)); // 252 ??
FILE *f = fopen("D:\\axdump.txt", "a"); FILE *f = fopen("D:\\axdump.txt", "a");
if (!f) if (!f)
f = fopen("D:\\axdump.txt", "w"); f = fopen("D:\\axdump.txt", "w");
u32 addr = uAddress; u32 addr = uAddress;
for (int i = 0; i < 100; i++) { for (int i = 0; i < 100; i++) {
fprintf(f, "%02x\n", Memory_Read_U16(addr + i * 2)); fprintf(f, "%02x\n", Memory_Read_U16(addr + i * 2));
} }
fprintf(f, "===========------------------------------------------------=\n"); fprintf(f, "===========------------------------------------------------=\n");
fclose(f); fclose(f);
} }
else else
{ {
// PanicAlert("%i", sizeof(AXParamBlock)); // 192 // PanicAlert("%i", sizeof(AXParamBlock)); // 192
} }
while (bExecuteList) while (bExecuteList)
{ {
static int last_valid_command = 0; static int last_valid_command = 0;
u16 iCommand = Memory_Read_U16(uAddress); u16 iCommand = Memory_Read_U16(uAddress);
uAddress += 2; uAddress += 2;
switch (iCommand) switch (iCommand)
{ {
case 0x0000: //00 case 0x0000: //00
Addr__AXStudio = Memory_Read_U32(uAddress); Addr__AXStudio = Memory_Read_U32(uAddress);
uAddress += 4; uAddress += 4;
SaveLog("%08x : AXLIST studio address: %08x", uAddress, Addr__AXStudio); SaveLog("%08x : AXLIST studio address: %08x", uAddress, Addr__AXStudio);
break; break;
case 0x0001: case 0x0001:
{ {
u32 address = Memory_Read_U32(uAddress); u32 address = Memory_Read_U32(uAddress);
uAddress += 4; uAddress += 4;
SaveLog("%08x : AXLIST 1: %08x", uAddress, address); SaveLog("%08x : AXLIST 1: %08x", uAddress, address);
} }
break; break;
case 0x0003: case 0x0003:
{ {
u32 address = Memory_Read_U32(uAddress); u32 address = Memory_Read_U32(uAddress);
uAddress += 4; uAddress += 4;
SaveLog("%08x : AXLIST 3: %08x", uAddress, address); SaveLog("%08x : AXLIST 3: %08x", uAddress, address);
} }
break; break;
case 0x0004: // PBs are here now case 0x0004: // PBs are here now
m_addressPBs = Memory_Read_U32(uAddress); m_addressPBs = Memory_Read_U32(uAddress);
lCUCode_AX->m_addressPBs = m_addressPBs; // for the sake of logging lCUCode_AX->m_addressPBs = m_addressPBs; // for the sake of logging
mixer_HLEready = true; mixer_HLEready = true;
SaveLog("%08x : AXLIST PB address: %08x", uAddress, m_addressPBs); SaveLog("%08x : AXLIST PB address: %08x", uAddress, m_addressPBs);
#ifdef _WIN32 #ifdef _WIN32
//DebugLog("Update the SoundThread to be in sync"); //DebugLog("Update the SoundThread to be in sync");
DSound::DSound_UpdateSound(); //do it in this thread to avoid sync problems DSound::DSound_UpdateSound(); //do it in this thread to avoid sync problems
#endif #endif
uAddress += 4; uAddress += 4;
break; break;
case 0x0005: case 0x0005:
if(Memory_Read_U16(uAddress) > 25) // this occured in Wii Sports if(Memory_Read_U16(uAddress) > 25) // this occured in Wii Sports
{ {
Addr__5_1 = Memory_Read_U32(uAddress); Addr__5_1 = Memory_Read_U32(uAddress);
uAddress += 4; uAddress += 4;
Addr__5_2 = Memory_Read_U32(uAddress); Addr__5_2 = Memory_Read_U32(uAddress);
uAddress += 4; uAddress += 4;
uAddress += 2; uAddress += 2;
SaveLog("%08x : AXLIST 5_1 5_2 addresses: %08x %08x", uAddress, Addr__5_1, Addr__5_2); SaveLog("%08x : AXLIST 5_1 5_2 addresses: %08x %08x", uAddress, Addr__5_1, Addr__5_2);
} }
else else
{ {
uAddress += 2; uAddress += 2;
SaveLog("%08x : AXLIST Empty 0x0005", uAddress); SaveLog("%08x : AXLIST Empty 0x0005", uAddress);
} }
break; break;
case 0x0006: case 0x0006:
Addr__6 = Memory_Read_U32(uAddress); Addr__6 = Memory_Read_U32(uAddress);
uAddress += 10; uAddress += 10;
SaveLog("%08x : AXLIST 6 address: %08x", uAddress, Addr__6); SaveLog("%08x : AXLIST 6 address: %08x", uAddress, Addr__6);
break; break;
/**/ case 0x0007: // AXLIST_SBUFFER /**/ case 0x0007: // AXLIST_SBUFFER
Addr__AXOutSBuffer = Memory_Read_U32(uAddress); Addr__AXOutSBuffer = Memory_Read_U32(uAddress);
uAddress += 10; uAddress += 10;
// uAddress += 12; // uAddress += 12;
SaveLog("%08x : AXLIST OutSBuffer (0x0007) address: %08x", uAddress, Addr__AXOutSBuffer); SaveLog("%08x : AXLIST OutSBuffer (0x0007) address: %08x", uAddress, Addr__AXOutSBuffer);
break; break;
/* case 0x0009: /* case 0x0009:
Addr__9 = Memory_Read_U32(uAddress); Addr__9 = Memory_Read_U32(uAddress);
uAddress += 4; uAddress += 4;
DebugLog("AXLIST 6 address: %08x", Addr__9); DebugLog("AXLIST 6 address: %08x", Addr__9);
break;*/ break;*/
case 0x000a: // AXLIST_COMPRESSORTABLE case 0x000a: // AXLIST_COMPRESSORTABLE
Addr__A = Memory_Read_U32(uAddress); Addr__A = Memory_Read_U32(uAddress);
uAddress += 4; uAddress += 4;
//Addr__A = Memory_Read_U32(uAddress); //Addr__A = Memory_Read_U32(uAddress);
uAddress += 4; uAddress += 4;
SaveLog("%08x : AXLIST CompressorTable address: %08x", uAddress, Addr__A); SaveLog("%08x : AXLIST CompressorTable address: %08x", uAddress, Addr__A);
break; break;
case 0x000b: case 0x000b:
uAddress += 2; // one 0x8000 in rabbids uAddress += 2; // one 0x8000 in rabbids
uAddress += 4 * 2; // then two RAM addressses uAddress += 4 * 2; // then two RAM addressses
break; break;
case 0x000c: case 0x000c:
uAddress += 2; // one 0x8000 in rabbids uAddress += 2; // one 0x8000 in rabbids
uAddress += 4 * 2; // then two RAM addressses uAddress += 4 * 2; // then two RAM addressses
break; break;
case 0x000d: case 0x000d:
uAddress += 4 * 4; uAddress += 4 * 4;
break; break;
case 0x000e: case 0x000e:
// This is the end. // This is the end.
bExecuteList = false; bExecuteList = false;
SaveLog("%08x : AXLIST end, wii stylee.", uAddress); SaveLog("%08x : AXLIST end, wii stylee.", uAddress);
break; break;
default: default:
{ {
static bool bFirst = true; static bool bFirst = true;
if (bFirst == true) if (bFirst == true)
{ {
// A little more descreet way to say that there is a problem, that also let you // A little more descreet way to say that there is a problem, that also let you
// take a look at the mail (and possible previous mails) in the debugger // take a look at the mail (and possible previous mails) in the debugger
SaveLog("%08x : Unknown AX-Command 0x%04x", uAddress, iCommand); SaveLog("%08x : Unknown AX-Command 0x%04x", uAddress, iCommand);
bExecuteList = false; bExecuteList = false;
break; break;
char szTemp[2048]; char szTemp[2048];
sprintf(szTemp, "Unknown AX-Command 0x%04x (address: 0x%08x). Last valid: %02x\n", sprintf(szTemp, "Unknown AX-Command 0x%04x (address: 0x%08x). Last valid: %02x\n",
iCommand, uAddress - 2, last_valid_command); iCommand, uAddress - 2, last_valid_command);
int num = -32; int num = -32;
while (num < 64+32) while (num < 64+32)
{ {
char szTemp2[128] = ""; char szTemp2[128] = "";
sprintf(szTemp2, "%s0x%04x\n", num == 0 ? ">>" : " ", Memory_Read_U16(uAddress + num)); sprintf(szTemp2, "%s0x%04x\n", num == 0 ? ">>" : " ", Memory_Read_U16(uAddress + num));
strcat(szTemp, szTemp2); strcat(szTemp, szTemp2);
num += 2; num += 2;
} }
// Wii AX will always show this // Wii AX will always show this
PanicAlert(szTemp); PanicAlert(szTemp);
// bFirst = false; // bFirst = false;
} }
// unknown command so stop the execution of this TaskList // unknown command so stop the execution of this TaskList
bExecuteList = false; bExecuteList = false;
} }
break; break;
} }
if (bExecuteList) if (bExecuteList)
last_valid_command = iCommand; last_valid_command = iCommand;
} }
SaveLog("AXTask - done, send resume"); SaveLog("AXTask - done, send resume");
SaveLog("====================================================================="); SaveLog("=====================================================================");
SaveLog("End"); SaveLog("End");
// i hope resume is okay AX // i hope resume is okay AX
m_rMailHandler.PushMail(0xDCD10001); m_rMailHandler.PushMail(0xDCD10001);
return true; return true;
} }

View File

@ -1,62 +1,62 @@
// 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 "../DSPHandler.h" #include "../DSPHandler.h"
#include "UCodes.h" #include "UCodes.h"
#include "UCode_CARD.h" #include "UCode_CARD.h"
CUCode_CARD::CUCode_CARD(CMailHandler& _rMailHandler) CUCode_CARD::CUCode_CARD(CMailHandler& _rMailHandler)
: IUCode(_rMailHandler) : IUCode(_rMailHandler)
{ {
DebugLog("CUCode_CARD - initialized"); DebugLog("CUCode_CARD - initialized");
m_rMailHandler.PushMail(DSP_INIT); m_rMailHandler.PushMail(DSP_INIT);
} }
CUCode_CARD::~CUCode_CARD() CUCode_CARD::~CUCode_CARD()
{ {
m_rMailHandler.Clear(); m_rMailHandler.Clear();
} }
void CUCode_CARD::Update() void CUCode_CARD::Update()
{ {
// check if we have to sent something // check if we have to sent something
if (!m_rMailHandler.IsEmpty()) if (!m_rMailHandler.IsEmpty())
{ {
g_dspInitialize.pGenerateDSPInterrupt(); g_dspInitialize.pGenerateDSPInterrupt();
} }
} }
void CUCode_CARD::HandleMail(u32 _uMail) void CUCode_CARD::HandleMail(u32 _uMail)
{ {
if (_uMail == 0xFF000000) // unlock card if (_uMail == 0xFF000000) // unlock card
{ {
// m_Mails.push(0x00000001); // ACK (actualy anything != 0) // m_Mails.push(0x00000001); // ACK (actualy anything != 0)
} }
else else
{ {
DebugLog("CUCode_CARD - unknown cmd: %x (size %i)", _uMail); DebugLog("CUCode_CARD - unknown cmd: %x (size %i)", _uMail);
} }
m_rMailHandler.PushMail(DSP_DONE); m_rMailHandler.PushMail(DSP_DONE);
CDSPHandler::GetInstance().SetUCode(UCODE_ROM); CDSPHandler::GetInstance().SetUCode(UCODE_ROM);
} }

View File

@ -1,53 +1,53 @@
// 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 "../DSPHandler.h" #include "../DSPHandler.h"
#include "UCodes.h" #include "UCodes.h"
#include "UCode_InitAudioSystem.h" #include "UCode_InitAudioSystem.h"
CUCode_InitAudioSystem::CUCode_InitAudioSystem(CMailHandler& _rMailHandler) CUCode_InitAudioSystem::CUCode_InitAudioSystem(CMailHandler& _rMailHandler)
: IUCode(_rMailHandler) : IUCode(_rMailHandler)
, m_BootTask_numSteps(0) , m_BootTask_numSteps(0)
, m_NextParameter(0) , m_NextParameter(0)
, IsInitialized(false) , IsInitialized(false)
{ {
DebugLog("CUCode_InitAudioSystem - initialized"); DebugLog("CUCode_InitAudioSystem - initialized");
} }
CUCode_InitAudioSystem::~CUCode_InitAudioSystem() CUCode_InitAudioSystem::~CUCode_InitAudioSystem()
{} {}
void CUCode_InitAudioSystem::Init() void CUCode_InitAudioSystem::Init()
{} {}
void CUCode_InitAudioSystem::Update() void CUCode_InitAudioSystem::Update()
{ {
if (m_rMailHandler.IsEmpty()) if (m_rMailHandler.IsEmpty())
{ {
m_rMailHandler.PushMail(0x80544348); m_rMailHandler.PushMail(0x80544348);
// HALT // HALT
} }
} }
void CUCode_InitAudioSystem::HandleMail(u32 _uMail) void CUCode_InitAudioSystem::HandleMail(u32 _uMail)
{} {}

View File

@ -1,161 +1,161 @@
// 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 "UCodes.h" #include "UCodes.h"
#include "UCode_Jac.h" #include "UCode_Jac.h"
#include "../MailHandler.h" #include "../MailHandler.h"
CUCode_Jac::CUCode_Jac(CMailHandler& _rMailHandler) CUCode_Jac::CUCode_Jac(CMailHandler& _rMailHandler)
: IUCode(_rMailHandler) : IUCode(_rMailHandler)
, m_bListInProgress(false) , m_bListInProgress(false)
{ {
DebugLog("CUCode_Jac: init"); DebugLog("CUCode_Jac: init");
m_rMailHandler.PushMail(0xDCD10000); m_rMailHandler.PushMail(0xDCD10000);
m_rMailHandler.PushMail(0x80000000); m_rMailHandler.PushMail(0x80000000);
} }
CUCode_Jac::~CUCode_Jac() CUCode_Jac::~CUCode_Jac()
{ {
m_rMailHandler.Clear(); m_rMailHandler.Clear();
} }
void CUCode_Jac::HandleMail(u32 _uMail) void CUCode_Jac::HandleMail(u32 _uMail)
{ {
// this is prolly totally bullshit and should work like the zelda one... // this is prolly totally bullshit and should work like the zelda one...
// but i am to lazy to change it atm // but i am to lazy to change it atm
if (m_bListInProgress == false) if (m_bListInProgress == false)
{ {
// get the command to find out how much steps it has // get the command to find out how much steps it has
switch (_uMail & 0xFFFF) switch (_uMail & 0xFFFF)
{ {
// release halt // release halt
case 0x00: case 0x00:
// m_Mails.push(0x80000000); // m_Mails.push(0x80000000);
g_dspInitialize.pGenerateDSPInterrupt(); g_dspInitialize.pGenerateDSPInterrupt();
break; break;
case 0x40: case 0x40:
m_step = 0; m_step = 0;
((u32*)m_Buffer)[m_step++] = _uMail; ((u32*)m_Buffer)[m_step++] = _uMail;
m_bListInProgress = true; m_bListInProgress = true;
m_numSteps = 5; m_numSteps = 5;
break; break;
case 0x2000: case 0x2000:
case 0x4000: case 0x4000:
m_step = 0; m_step = 0;
((u32*)m_Buffer)[m_step++] = _uMail; ((u32*)m_Buffer)[m_step++] = _uMail;
m_bListInProgress = true; m_bListInProgress = true;
m_numSteps = 3; m_numSteps = 3;
break; break;
default: default:
PanicAlert("UCode Jac"); PanicAlert("UCode Jac");
DebugLog("UCode Jac - unknown cmd: %x", _uMail & 0xFFFF); DebugLog("UCode Jac - unknown cmd: %x", _uMail & 0xFFFF);
break; break;
} }
} }
else else
{ {
((u32*)m_Buffer)[m_step] = _uMail; ((u32*)m_Buffer)[m_step] = _uMail;
m_step++; m_step++;
if (m_step == m_numSteps) if (m_step == m_numSteps)
{ {
ExecuteList(); ExecuteList();
m_bListInProgress = false; m_bListInProgress = false;
} }
} }
} }
void CUCode_Jac::Update() void CUCode_Jac::Update()
{ {
// check if we have to sent something // check if we have to sent something
/* if (!g_MailHandler.empty()) /* if (!g_MailHandler.empty())
{ {
g_dspInitialize.pGenerateDSPInterrupt(); g_dspInitialize.pGenerateDSPInterrupt();
}*/ }*/
} }
void CUCode_Jac::ExecuteList() void CUCode_Jac::ExecuteList()
{ {
// begin with the list // begin with the list
m_readOffset = 0; m_readOffset = 0;
u16 cmd = Read16(); u16 cmd = Read16();
u16 sync = Read16(); u16 sync = Read16();
DebugLog("=============================================================================="); DebugLog("==============================================================================");
DebugLog("UCode Jac - execute dlist (cmd: 0x%04x : sync: 0x%04x)", cmd, sync); DebugLog("UCode Jac - execute dlist (cmd: 0x%04x : sync: 0x%04x)", cmd, sync);
switch (cmd) switch (cmd)
{ {
// ============================================================================== // ==============================================================================
// DsetupTable // DsetupTable
// ============================================================================== // ==============================================================================
case 0x40: case 0x40:
{ {
u32 tmp[4]; u32 tmp[4];
tmp[0] = Read32(); tmp[0] = Read32();
tmp[1] = Read32(); tmp[1] = Read32();
tmp[2] = Read32(); tmp[2] = Read32();
tmp[3] = Read32(); tmp[3] = Read32();
DebugLog("DsetupTable"); DebugLog("DsetupTable");
DebugLog("???: 0x%08x", tmp[0]); DebugLog("???: 0x%08x", tmp[0]);
DebugLog("DSPRES_FILTER (size: 0x40): 0x%08x", tmp[1]); DebugLog("DSPRES_FILTER (size: 0x40): 0x%08x", tmp[1]);
DebugLog("DSPADPCM_FILTER (size: 0x500): 0x%08x", tmp[2]); DebugLog("DSPADPCM_FILTER (size: 0x500): 0x%08x", tmp[2]);
DebugLog("???: 0x%08x", tmp[3]); DebugLog("???: 0x%08x", tmp[3]);
} }
break; break;
// ============================================================================== // ==============================================================================
// UpdateDSPChannel // UpdateDSPChannel
// ============================================================================== // ==============================================================================
case 0x2000: case 0x2000:
case 0x4000: // animal crossing case 0x4000: // animal crossing
{ {
u32 tmp[3]; u32 tmp[3];
tmp[0] = Read32(); tmp[0] = Read32();
tmp[1] = Read32(); tmp[1] = Read32();
tmp[2] = Read32(); tmp[2] = Read32();
DebugLog("UpdateDSPChannel"); DebugLog("UpdateDSPChannel");
DebugLog("audiomemory: 0x%08x", tmp[0]); DebugLog("audiomemory: 0x%08x", tmp[0]);
DebugLog("audiomemory: 0x%08x", tmp[1]); DebugLog("audiomemory: 0x%08x", tmp[1]);
DebugLog("DSPADPCM_FILTER (size: 0x40): 0x%08x", tmp[2]); DebugLog("DSPADPCM_FILTER (size: 0x40): 0x%08x", tmp[2]);
} }
break; break;
default: default:
PanicAlert("UCode Jac unknown cmd: %s (size %i)", cmd, m_numSteps); PanicAlert("UCode Jac unknown cmd: %s (size %i)", cmd, m_numSteps);
DebugLog("Jac UCode - unknown cmd: %x (size %i)", cmd, m_numSteps); DebugLog("Jac UCode - unknown cmd: %x (size %i)", cmd, m_numSteps);
break; break;
} }
// sync, we are rdy // sync, we are rdy
m_rMailHandler.PushMail(DSP_SYNC); m_rMailHandler.PushMail(DSP_SYNC);
m_rMailHandler.PushMail(0xF3550000 | sync); m_rMailHandler.PushMail(0xF3550000 | sync);
} }

View File

@ -1,112 +1,112 @@
// 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 "../DSPHandler.h" #include "../DSPHandler.h"
#include "UCodes.h" #include "UCodes.h"
#include "UCode_ROM.h" #include "UCode_ROM.h"
CUCode_Rom::CUCode_Rom(CMailHandler& _rMailHandler) CUCode_Rom::CUCode_Rom(CMailHandler& _rMailHandler)
: IUCode(_rMailHandler) : IUCode(_rMailHandler)
, m_BootTask_numSteps(0) , m_BootTask_numSteps(0)
, m_NextParameter(0) , m_NextParameter(0)
{ {
DebugLog("UCode_Rom - initialized"); DebugLog("UCode_Rom - initialized");
m_rMailHandler.Clear(); m_rMailHandler.Clear();
m_rMailHandler.PushMail(0x8071FEED); m_rMailHandler.PushMail(0x8071FEED);
} }
CUCode_Rom::~CUCode_Rom() CUCode_Rom::~CUCode_Rom()
{} {}
void CUCode_Rom::Update() void CUCode_Rom::Update()
{} {}
void CUCode_Rom::HandleMail(u32 _uMail) void CUCode_Rom::HandleMail(u32 _uMail)
{ {
if (m_NextParameter == 0) if (m_NextParameter == 0)
{ {
// wait for beginning of UCode // wait for beginning of UCode
if ((_uMail & 0xFFFF0000) != 0x80F30000) if ((_uMail & 0xFFFF0000) != 0x80F30000)
{ {
u32 Message = 0xFEEE0000 | (_uMail & 0xFFFF); u32 Message = 0xFEEE0000 | (_uMail & 0xFFFF);
m_rMailHandler.PushMail(Message); m_rMailHandler.PushMail(Message);
} }
else else
{ {
m_NextParameter = _uMail; m_NextParameter = _uMail;
} }
} }
else else
{ {
switch (m_NextParameter) switch (m_NextParameter)
{ {
case 0x80F3A001: case 0x80F3A001:
m_CurrentUCode.m_RAMAddress = _uMail; m_CurrentUCode.m_RAMAddress = _uMail;
break; break;
case 0x80F3A002: case 0x80F3A002:
m_CurrentUCode.m_Length = _uMail; m_CurrentUCode.m_Length = _uMail;
break; break;
case 0x80F3C002: case 0x80F3C002:
m_CurrentUCode.m_IMEMAddress = _uMail; m_CurrentUCode.m_IMEMAddress = _uMail;
break; break;
case 0x80F3B002: case 0x80F3B002:
m_CurrentUCode.m_Unk = _uMail; m_CurrentUCode.m_Unk = _uMail;
break; break;
case 0x80F3D001: case 0x80F3D001:
{ {
m_CurrentUCode.m_StartPC = _uMail; m_CurrentUCode.m_StartPC = _uMail;
BootUCode(); BootUCode();
return; // FIXES THE OVERWRITE return; // FIXES THE OVERWRITE
} }
break; break;
} }
// THE GODDAMN OVERWRITE WAS HERE. Without the return above, since BootUCode may delete "this", well ... // THE GODDAMN OVERWRITE WAS HERE. Without the return above, since BootUCode may delete "this", well ...
m_NextParameter = 0; m_NextParameter = 0;
} }
} }
void CUCode_Rom::BootUCode() void CUCode_Rom::BootUCode()
{ {
// simple non-scientific crc invented by ector :P // simple non-scientific crc invented by ector :P
// too annoying to change now, and probably good enough anyway // too annoying to change now, and probably good enough anyway
u32 crc = 0; u32 crc = 0;
for (u32 i = 0; i < m_CurrentUCode.m_Length; i++) for (u32 i = 0; i < m_CurrentUCode.m_Length; i++)
{ {
crc ^= Memory_Read_U8(m_CurrentUCode.m_RAMAddress + i); crc ^= Memory_Read_U8(m_CurrentUCode.m_RAMAddress + i);
//let's rol //let's rol
crc = (crc << 3) | (crc >> 29); crc = (crc << 3) | (crc >> 29);
} }
DebugLog("CurrentUCode SOURCE Addr: 0x%08x", m_CurrentUCode.m_RAMAddress); DebugLog("CurrentUCode SOURCE Addr: 0x%08x", m_CurrentUCode.m_RAMAddress);
DebugLog("CurrentUCode Length: 0x%08x", m_CurrentUCode.m_Length); DebugLog("CurrentUCode Length: 0x%08x", m_CurrentUCode.m_Length);
DebugLog("CurrentUCode DEST Addr: 0x%08x", m_CurrentUCode.m_IMEMAddress); DebugLog("CurrentUCode DEST Addr: 0x%08x", m_CurrentUCode.m_IMEMAddress);
DebugLog("CurrentUCode ???: 0x%08x", m_CurrentUCode.m_Unk); DebugLog("CurrentUCode ???: 0x%08x", m_CurrentUCode.m_Unk);
DebugLog("CurrentUCode init_vector: 0x%08x", m_CurrentUCode.m_StartPC); DebugLog("CurrentUCode init_vector: 0x%08x", m_CurrentUCode.m_StartPC);
DebugLog("CurrentUCode CRC: 0x%08x", crc); DebugLog("CurrentUCode CRC: 0x%08x", crc);
DebugLog("BootTask - done"); DebugLog("BootTask - done");
CDSPHandler::GetInstance().SetUCode(crc); CDSPHandler::GetInstance().SetUCode(crc);
} }

View File

@ -1,181 +1,181 @@
// 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/
// Games that uses this UCode: // Games that uses this UCode:
// Zelda: The Windwaker, Mario Sunshine, Mario Kart, Twilight Princess // Zelda: The Windwaker, Mario Sunshine, Mario Kart, Twilight Princess
#include "../Globals.h" #include "../Globals.h"
#include "UCodes.h" #include "UCodes.h"
#include "UCode_Zelda.h" #include "UCode_Zelda.h"
#include "../MailHandler.h" #include "../MailHandler.h"
#ifdef _WIN32 #ifdef _WIN32
#include "../PCHW/DSoundStream.h" #include "../PCHW/DSoundStream.h"
#endif #endif
#include "../PCHW/Mixer.h" #include "../PCHW/Mixer.h"
CUCode_Zelda::CUCode_Zelda(CMailHandler& _rMailHandler) CUCode_Zelda::CUCode_Zelda(CMailHandler& _rMailHandler)
: IUCode(_rMailHandler) : IUCode(_rMailHandler)
, m_numSteps(0) , m_numSteps(0)
, m_bListInProgress(false) , m_bListInProgress(false)
, m_step(0) , m_step(0)
, m_readOffset(0) , m_readOffset(0)
{ {
DebugLog("UCode_Zelda - add boot mails for handshake"); DebugLog("UCode_Zelda - add boot mails for handshake");
m_rMailHandler.PushMail(DSP_INIT); m_rMailHandler.PushMail(DSP_INIT);
m_rMailHandler.PushMail(0x80000000); // handshake m_rMailHandler.PushMail(0x80000000); // handshake
memset(m_Buffer, 0, sizeof(m_Buffer)); memset(m_Buffer, 0, sizeof(m_Buffer));
} }
CUCode_Zelda::~CUCode_Zelda() CUCode_Zelda::~CUCode_Zelda()
{ {
m_rMailHandler.Clear(); m_rMailHandler.Clear();
} }
void CUCode_Zelda::Update() void CUCode_Zelda::Update()
{ {
// check if we have to sent something // check if we have to sent something
if (!m_rMailHandler.IsEmpty()) if (!m_rMailHandler.IsEmpty())
g_dspInitialize.pGenerateDSPInterrupt(); g_dspInitialize.pGenerateDSPInterrupt();
} }
void CUCode_Zelda::HandleMail(u32 _uMail) void CUCode_Zelda::HandleMail(u32 _uMail)
{ {
if (m_bListInProgress == false) if (m_bListInProgress == false)
{ {
m_bListInProgress = true; m_bListInProgress = true;
m_numSteps = _uMail; m_numSteps = _uMail;
m_step = 0; m_step = 0;
} }
else else
{ {
if (m_step < 0 || m_step >= sizeof(m_Buffer)/4) if (m_step < 0 || m_step >= sizeof(m_Buffer)/4)
PanicAlert("m_step out of range"); PanicAlert("m_step out of range");
((u32*)m_Buffer)[m_step] = _uMail; ((u32*)m_Buffer)[m_step] = _uMail;
m_step++; m_step++;
if (m_step == m_numSteps) if (m_step == m_numSteps)
{ {
ExecuteList(); ExecuteList();
m_bListInProgress = false; m_bListInProgress = false;
} }
} }
} }
void CUCode_Zelda::MixAdd(short* buffer, int size) void CUCode_Zelda::MixAdd(short* buffer, int size)
{ {
//TODO(XK): Zelda UCode MixAdd? //TODO(XK): Zelda UCode MixAdd?
} }
void CUCode_Zelda::ExecuteList() void CUCode_Zelda::ExecuteList()
{ {
// begin with the list // begin with the list
m_readOffset = 0; m_readOffset = 0;
u32 Temp = Read32(); u32 Temp = Read32();
u32 Command = (Temp >> 24) & 0x7f; u32 Command = (Temp >> 24) & 0x7f;
u32 Sync = Temp >> 16; u32 Sync = Temp >> 16;
DebugLog("=============================================================================="); DebugLog("==============================================================================");
DebugLog("Zelda UCode - execute dlist (cmd: 0x%04x : sync: 0x%04x)", Command, Sync); DebugLog("Zelda UCode - execute dlist (cmd: 0x%04x : sync: 0x%04x)", Command, Sync);
switch (Command) switch (Command)
{ {
// DsetupTable ... zelda ww jumps to 0x0095 // DsetupTable ... zelda ww jumps to 0x0095
case 0x01: case 0x01:
{ {
u32 tmp[4]; u32 tmp[4];
tmp[0] = Read32(); tmp[0] = Read32();
tmp[1] = Read32(); tmp[1] = Read32();
tmp[2] = Read32(); tmp[2] = Read32();
tmp[3] = Read32(); tmp[3] = Read32();
DebugLog("DsetupTable"); DebugLog("DsetupTable");
DebugLog("???: 0x%08x", tmp[0]); DebugLog("???: 0x%08x", tmp[0]);
DebugLog("DSPRES_FILTER (size: 0x40): 0x%08x", tmp[1]); DebugLog("DSPRES_FILTER (size: 0x40): 0x%08x", tmp[1]);
DebugLog("DSPADPCM_FILTER (size: 0x500): 0x%08x", tmp[2]); DebugLog("DSPADPCM_FILTER (size: 0x500): 0x%08x", tmp[2]);
DebugLog("???: 0x%08x", tmp[3]); DebugLog("???: 0x%08x", tmp[3]);
} }
break; break;
// SyncFrame ... zelda ww jumps to 0x0243 // SyncFrame ... zelda ww jumps to 0x0243
case 0x02: case 0x02:
{ {
u32 tmp[3]; u32 tmp[3];
tmp[0] = Read32(); tmp[0] = Read32();
tmp[1] = Read32(); tmp[1] = Read32();
tmp[2] = Read32(); tmp[2] = Read32();
// We're ready to mix // We're ready to mix
mixer_HLEready = true; mixer_HLEready = true;
#ifdef _WIN32 #ifdef _WIN32
DebugLog("Update the SoundThread to be in sync"); DebugLog("Update the SoundThread to be in sync");
DSound::DSound_UpdateSound(); //do it in this thread to avoid sync problems DSound::DSound_UpdateSound(); //do it in this thread to avoid sync problems
#endif #endif
DebugLog("DsyncFrame"); DebugLog("DsyncFrame");
DebugLog("???: 0x%08x", tmp[0]); DebugLog("???: 0x%08x", tmp[0]);
DebugLog("???: 0x%08x", tmp[1]); DebugLog("???: 0x%08x", tmp[1]);
DebugLog("DSPADPCM_FILTER (size: 0x500): 0x%08x", tmp[2]); DebugLog("DSPADPCM_FILTER (size: 0x500): 0x%08x", tmp[2]);
} }
break; break;
/* /*
case 0x03: break; // dunno ... zelda ww jmps to 0x0073 case 0x03: break; // dunno ... zelda ww jmps to 0x0073
case 0x04: break; // dunno ... zelda ww jmps to 0x0580 case 0x04: break; // dunno ... zelda ww jmps to 0x0580
case 0x05: break; // dunno ... zelda ww jmps to 0x0592 case 0x05: break; // dunno ... zelda ww jmps to 0x0592
case 0x06: break; // dunno ... zelda ww jmps to 0x0469 case 0x06: break; // dunno ... zelda ww jmps to 0x0469
case 0x07: break; // dunno ... zelda ww jmps to 0x044d case 0x07: break; // dunno ... zelda ww jmps to 0x044d
case 0x08: break; // Mixer ... zelda ww jmps to 0x0485 case 0x08: break; // Mixer ... zelda ww jmps to 0x0485
case 0x09: break; // dunno ... zelda ww jmps to 0x044d case 0x09: break; // dunno ... zelda ww jmps to 0x044d
*/ */
// DsetDolbyDelay ... zelda ww jumps to 0x00b2 // DsetDolbyDelay ... zelda ww jumps to 0x00b2
case 0x0d: case 0x0d:
{ {
u32 tmp[2]; u32 tmp[2];
tmp[0] = Read32(); tmp[0] = Read32();
tmp[1] = Read32(); tmp[1] = Read32();
DebugLog("DSetDolbyDelay"); DebugLog("DSetDolbyDelay");
DebugLog("DOLBY2_DELAY_BUF (size 0x960): 0x%08x", tmp[0]); DebugLog("DOLBY2_DELAY_BUF (size 0x960): 0x%08x", tmp[0]);
DebugLog("DSPRES_FILTER (size 0x500): 0x%08x", tmp[1]); DebugLog("DSPRES_FILTER (size 0x500): 0x%08x", tmp[1]);
} }
break; break;
// Set VARAM // Set VARAM
case 0x0e: case 0x0e:
// MessageBox(NULL, "Zelda VARAM", "cmd", MB_OK); // MessageBox(NULL, "Zelda VARAM", "cmd", MB_OK);
break; break;
// default ... zelda ww jumps to 0x0043 // default ... zelda ww jumps to 0x0043
default: default:
PanicAlert("Zelda UCode - unknown cmd: %x (size %i)", Command, m_numSteps); PanicAlert("Zelda UCode - unknown cmd: %x (size %i)", Command, m_numSteps);
break; break;
} }
// sync, we are rdy // sync, we are rdy
m_rMailHandler.PushMail(DSP_SYNC); m_rMailHandler.PushMail(DSP_SYNC);
m_rMailHandler.PushMail(0xF3550000 | Sync); m_rMailHandler.PushMail(0xF3550000 | Sync);
} }

View File

@ -1,90 +1,90 @@
// 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 "UCodes.h" #include "UCodes.h"
#include "UCode_AX.h" #include "UCode_AX.h"
#include "UCode_AXWii.h" #include "UCode_AXWii.h"
#include "UCode_Zelda.h" #include "UCode_Zelda.h"
#include "UCode_Jac.h" #include "UCode_Jac.h"
#include "UCode_ROM.h" #include "UCode_ROM.h"
#include "UCode_CARD.h" #include "UCode_CARD.h"
#include "UCode_InitAudioSystem.h" #include "UCode_InitAudioSystem.h"
IUCode* UCodeFactory(u32 _CRC, CMailHandler& _rMailHandler) IUCode* UCodeFactory(u32 _CRC, CMailHandler& _rMailHandler)
{ {
switch (_CRC) switch (_CRC)
{ {
case UCODE_ROM: case UCODE_ROM:
return new CUCode_Rom(_rMailHandler); return new CUCode_Rom(_rMailHandler);
case UCODE_INIT_AUDIO_SYSTEM: case UCODE_INIT_AUDIO_SYSTEM:
return new CUCode_InitAudioSystem(_rMailHandler); return new CUCode_InitAudioSystem(_rMailHandler);
case 0x65d6cc6f: // CARD case 0x65d6cc6f: // CARD
return new CUCode_CARD(_rMailHandler); return new CUCode_CARD(_rMailHandler);
case 0x088e38a5: // IPL - JAP case 0x088e38a5: // IPL - JAP
case 0xd73338cf: // IPL case 0xd73338cf: // IPL
case 0x42f64ac4: // Luigi (after fix) case 0x42f64ac4: // Luigi (after fix)
case 0x4be6a5cb: // AC, Pikmin (after fix) case 0x4be6a5cb: // AC, Pikmin (after fix)
printf("JAC ucode chosen"); printf("JAC ucode chosen");
return new CUCode_Jac(_rMailHandler); return new CUCode_Jac(_rMailHandler);
case 0x3ad3b7ac: // Naruto3 case 0x3ad3b7ac: // Naruto3
case 0x3daf59b9: // Alien Hominid case 0x3daf59b9: // Alien Hominid
case 0x4e8a8b21: // spdemo, ctaxi, 18 wheeler, disney, monkeyball2,cubivore,puzzlecollection,wario, case 0x4e8a8b21: // spdemo, ctaxi, 18 wheeler, disney, monkeyball2,cubivore,puzzlecollection,wario,
// capcom vs snk, naruto2, lost kingdoms, star fox, mario party 4, mortal kombat, // capcom vs snk, naruto2, lost kingdoms, star fox, mario party 4, mortal kombat,
// smugglers run warzone, smash brothers, sonic mega collection, ZooCube // smugglers run warzone, smash brothers, sonic mega collection, ZooCube
// nddemo, starfox // nddemo, starfox
case 0x07f88145: // bustamove, ikaruga, fzero, robotech battle cry, star soldier, soul calibur2, case 0x07f88145: // bustamove, ikaruga, fzero, robotech battle cry, star soldier, soul calibur2,
// Zelda:OOT, Tony hawk, viewtiful joe // Zelda:OOT, Tony hawk, viewtiful joe
case 0xe2136399: // billy hatcher, dragonballz, mario party 5, TMNT, ava1080 case 0xe2136399: // billy hatcher, dragonballz, mario party 5, TMNT, ava1080
printf("AX ucode chosen, yay!"); printf("AX ucode chosen, yay!");
return new CUCode_AX(_rMailHandler); return new CUCode_AX(_rMailHandler);
case 0x6CA33A6D: // DK Jungle Beat case 0x6CA33A6D: // DK Jungle Beat
case 0x86840740: // zelda case 0x86840740: // zelda
case 0x56d36052: // mario case 0x56d36052: // mario
case 0x2fcdf1ec: // mariokart, zelda 4 swords case 0x2fcdf1ec: // mariokart, zelda 4 swords
printf("Zelda ucode chosen"); printf("Zelda ucode chosen");
return new CUCode_Zelda(_rMailHandler); return new CUCode_Zelda(_rMailHandler);
// WII CRCs // WII CRCs
case 0x6c3f6f94: // zelda - PAL case 0x6c3f6f94: // zelda - PAL
case 0xd643001f: // mario galaxy - PAL case 0xd643001f: // mario galaxy - PAL
printf("Zelda Wii ucode chosen"); printf("Zelda Wii ucode chosen");
return new CUCode_Zelda(_rMailHandler); return new CUCode_Zelda(_rMailHandler);
case 0x5ef56da3: // AX demo case 0x5ef56da3: // AX demo
case 0x347112ba: // raving rabbits case 0x347112ba: // raving rabbits
case 0xfa450138: // wii sports - PAL case 0xfa450138: // wii sports - PAL
case 0xadbc06bd: // Elebits case 0xadbc06bd: // Elebits
printf("Wii - AXWii chosen"); printf("Wii - AXWii chosen");
return new CUCode_AXWii(_rMailHandler, _CRC); return new CUCode_AXWii(_rMailHandler, _CRC);
default: default:
PanicAlert("Unknown ucode (CRC = %08x) - forcing AX", _CRC); PanicAlert("Unknown ucode (CRC = %08x) - forcing AX", _CRC);
return new CUCode_AX(_rMailHandler); return new CUCode_AX(_rMailHandler);
} }
return NULL; return NULL;
} }

View File

@ -1,357 +1,357 @@
// 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 "Debugger/Debugger.h" // for the CDebugger class #include "Debugger/Debugger.h" // for the CDebugger class
#include "ChunkFile.h" #include "ChunkFile.h"
#include "WaveFile.h" #include "WaveFile.h"
#include "resource.h" #include "resource.h"
#ifdef _WIN32 #ifdef _WIN32
#include "PCHW/DSoundStream.h" #include "PCHW/DSoundStream.h"
#include "ConfigDlg.h" #include "ConfigDlg.h"
#else #else
#include "PCHW/AOSoundStream.h" #include "PCHW/AOSoundStream.h"
#endif #endif
#include "PCHW/Mixer.h" #include "PCHW/Mixer.h"
#include "DSPHandler.h" #include "DSPHandler.h"
#include "Config.h" #include "Config.h"
#include "Logging/Console.h" // for startConsoleWin, wprintf, GetConsoleHwnd #include "Logging/Console.h" // for startConsoleWin, wprintf, GetConsoleHwnd
DSPInitialize g_dspInitialize; DSPInitialize g_dspInitialize;
u8* g_pMemory; u8* g_pMemory;
extern std::vector<std::string> sMailLog, sMailTime; extern std::vector<std::string> sMailLog, sMailTime;
std::string gpName; std::string gpName;
// Set this if you want to log audio. search for log_ai in this file to see the filename. // Set this if you want to log audio. search for log_ai in this file to see the filename.
static bool log_ai = false; static bool log_ai = false;
static WaveFileWriter g_wave_writer; static WaveFileWriter g_wave_writer;
struct DSPState struct DSPState
{ {
u32 CPUMailbox; u32 CPUMailbox;
bool CPUMailbox_Written[2]; bool CPUMailbox_Written[2];
u32 DSPMailbox; u32 DSPMailbox;
bool DSPMailbox_Read[2]; bool DSPMailbox_Read[2];
DSPState() DSPState()
{ {
CPUMailbox = 0x00000000; CPUMailbox = 0x00000000;
CPUMailbox_Written[0] = false; CPUMailbox_Written[0] = false;
CPUMailbox_Written[1] = false; CPUMailbox_Written[1] = false;
DSPMailbox = 0x00000000; DSPMailbox = 0x00000000;
DSPMailbox_Read[0] = true; DSPMailbox_Read[0] = true;
DSPMailbox_Read[1] = true; DSPMailbox_Read[1] = true;
} }
}; };
DSPState g_dspState; DSPState g_dspState;
// ==================== // ====================
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// wxWidgets - Some kind of stuff wx needs // wxWidgets - Some kind of stuff wx needs
// ¯¯¯¯¯¯¯¯¯ // ¯¯¯¯¯¯¯¯¯
class wxDLLApp : public wxApp class wxDLLApp : public wxApp
{ {
bool OnInit() bool OnInit()
{ {
return true; return true;
} }
}; };
IMPLEMENT_APP_NO_MAIN(wxDLLApp) IMPLEMENT_APP_NO_MAIN(wxDLLApp)
WXDLLIMPEXP_BASE void wxSetInstance(HINSTANCE hInst); WXDLLIMPEXP_BASE void wxSetInstance(HINSTANCE hInst);
/////////////////// ///////////////////
#ifdef _WIN32 #ifdef _WIN32
HINSTANCE g_hInstance = NULL; HINSTANCE g_hInstance = NULL;
BOOL APIENTRY DllMain(HINSTANCE hinstDLL, // DLL module handle BOOL APIENTRY DllMain(HINSTANCE hinstDLL, // DLL module handle
DWORD dwReason, // reason called DWORD dwReason, // reason called
LPVOID lpvReserved) // reserved LPVOID lpvReserved) // reserved
{ {
switch (dwReason) switch (dwReason)
{ {
case DLL_PROCESS_ATTACH: case DLL_PROCESS_ATTACH:
{ {
// more stuff wx needs // more stuff wx needs
wxSetInstance((HINSTANCE)hinstDLL); wxSetInstance((HINSTANCE)hinstDLL);
int argc = 0; int argc = 0;
char **argv = NULL; char **argv = NULL;
wxEntryStart(argc, argv); wxEntryStart(argc, argv);
// This is for ? // This is for ?
if ( !wxTheApp || !wxTheApp->CallOnInit() ) if ( !wxTheApp || !wxTheApp->CallOnInit() )
return FALSE; return FALSE;
} }
break; break;
case DLL_PROCESS_DETACH: case DLL_PROCESS_DETACH:
wxEntryCleanup(); // use this or get a crash wxEntryCleanup(); // use this or get a crash
break; break;
default: default:
break; break;
} }
g_hInstance = hinstDLL; g_hInstance = hinstDLL;
return(TRUE); return(TRUE);
} }
#endif #endif
// ======================================================================================= // =======================================================================================
// Open and close console // Open and close console
// ------------------- // -------------------
void OpenConsole() void OpenConsole()
{ {
#if defined (_WIN32) #if defined (_WIN32)
startConsoleWin(155, 100, "Sound Debugging"); // give room for 100 rows startConsoleWin(155, 100, "Sound Debugging"); // give room for 100 rows
wprintf("OpenConsole > Console opened\n"); wprintf("OpenConsole > Console opened\n");
MoveWindow(GetConsoleHwnd(), 0,400, 1280,550, true); // move window, TODO: make this MoveWindow(GetConsoleHwnd(), 0,400, 1280,550, true); // move window, TODO: make this
// adjustable from the debugging window // adjustable from the debugging window
#endif #endif
} }
void CloseConsole() void CloseConsole()
{ {
#if defined (_WIN32) #if defined (_WIN32)
FreeConsole(); FreeConsole();
#endif #endif
} }
// =================== // ===================
// ======================================================================================= // =======================================================================================
// Create debugging window - We could use use wxWindow win; new CDebugger(win) like nJoy but I don't // Create debugging window - We could use use wxWindow win; new CDebugger(win) like nJoy but I don't
// know why it would be better. - There's a lockup problem with ShowModal(), but Show() doesn't work // know why it would be better. - There's a lockup problem with ShowModal(), but Show() doesn't work
// because then DLL_PROCESS_DETACH is called immediately after DLL_PROCESS_ATTACH. // because then DLL_PROCESS_DETACH is called immediately after DLL_PROCESS_ATTACH.
// ------------------- // -------------------
CDebugger* m_frame; CDebugger* m_frame;
void DllDebugger(HWND _hParent, bool Show) void DllDebugger(HWND _hParent, bool Show)
{ {
if(m_frame && Show) // if we have created it, let us show it again if(m_frame && Show) // if we have created it, let us show it again
{ {
m_frame->DoShow(); m_frame->DoShow();
} }
else if(!m_frame && Show) else if(!m_frame && Show)
{ {
m_frame = new CDebugger(NULL); m_frame = new CDebugger(NULL);
m_frame->Show(); m_frame->Show();
} }
else if(m_frame && !Show) else if(m_frame && !Show)
{ {
m_frame->DoHide(); m_frame->DoHide();
} }
} }
// =================== // ===================
void GetDllInfo(PLUGIN_INFO* _PluginInfo) void GetDllInfo(PLUGIN_INFO* _PluginInfo)
{ {
_PluginInfo->Version = 0x0100; _PluginInfo->Version = 0x0100;
_PluginInfo->Type = PLUGIN_TYPE_DSP; _PluginInfo->Type = PLUGIN_TYPE_DSP;
#ifdef DEBUGFAST #ifdef DEBUGFAST
sprintf(_PluginInfo->Name, "Dolphin DSP-HLE Plugin (DebugFast) "); sprintf(_PluginInfo->Name, "Dolphin DSP-HLE Plugin (DebugFast) ");
#else #else
#ifndef _DEBUG #ifndef _DEBUG
sprintf(_PluginInfo->Name, "Dolphin DSP-HLE Plugin "); sprintf(_PluginInfo->Name, "Dolphin DSP-HLE Plugin ");
#else #else
sprintf(_PluginInfo ->Name, "Dolphin DSP-HLE Plugin (Debug) "); sprintf(_PluginInfo ->Name, "Dolphin DSP-HLE Plugin (Debug) ");
#endif #endif
#endif #endif
} }
void DllConfig(HWND _hParent) void DllConfig(HWND _hParent)
{ {
#ifdef _WIN32 #ifdef _WIN32
CConfigDlg configDlg; CConfigDlg configDlg;
configDlg.DoModal(_hParent); configDlg.DoModal(_hParent);
#endif #endif
} }
void DSP_Initialize(DSPInitialize _dspInitialize) void DSP_Initialize(DSPInitialize _dspInitialize)
{ {
g_Config.LoadDefaults(); g_Config.LoadDefaults();
g_Config.Load(); g_Config.Load();
g_dspInitialize = _dspInitialize; g_dspInitialize = _dspInitialize;
g_pMemory = g_dspInitialize.pGetMemoryPointer(0); g_pMemory = g_dspInitialize.pGetMemoryPointer(0);
#if defined(_DEBUG) || defined(DEBUGFAST) #if defined(_DEBUG) || defined(DEBUGFAST)
gpName = g_dspInitialize.pName(); // save the game name globally gpName = g_dspInitialize.pName(); // save the game name globally
for (int i = 0; i < gpName.length(); ++i) // and fix it for (int i = 0; i < gpName.length(); ++i) // and fix it
{ {
wprintf("%c", gpName[i]); wprintf("%c", gpName[i]);
std::cout << gpName[i]; std::cout << gpName[i];
if (gpName[i] == ':') gpName[i] = ' '; if (gpName[i] == ':') gpName[i] = ' ';
} }
wprintf("\n"); wprintf("\n");
#endif #endif
CDSPHandler::CreateInstance(); CDSPHandler::CreateInstance();
#ifdef _WIN32 #ifdef _WIN32
#ifdef _DEBUG #ifdef _DEBUG
int tmpflag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); int tmpflag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
tmpflag |= _CRTDBG_DELAY_FREE_MEM_DF; tmpflag |= _CRTDBG_DELAY_FREE_MEM_DF;
_CrtSetDbgFlag(tmpflag); _CrtSetDbgFlag(tmpflag);
#endif #endif
if (log_ai) { if (log_ai) {
g_wave_writer.Start("D:\\ai_log.wav"); g_wave_writer.Start("D:\\ai_log.wav");
g_wave_writer.SetSkipSilence(false); g_wave_writer.SetSkipSilence(false);
} }
DSound::DSound_StartSound((HWND)g_dspInitialize.hWnd, 48000, Mixer); DSound::DSound_StartSound((HWND)g_dspInitialize.hWnd, 48000, Mixer);
#else #else
AOSound::AOSound_StartSound(48000, Mixer); AOSound::AOSound_StartSound(48000, Mixer);
#endif #endif
} }
void DSP_Shutdown() void DSP_Shutdown()
{ {
if (log_ai) if (log_ai)
g_wave_writer.Stop(); g_wave_writer.Stop();
// delete the UCodes // delete the UCodes
#ifdef _WIN32 #ifdef _WIN32
DSound::DSound_StopSound(); DSound::DSound_StopSound();
#else #else
AOSound::AOSound_StopSound(); AOSound::AOSound_StopSound();
#endif #endif
CDSPHandler::Destroy(); CDSPHandler::Destroy();
// Reset mails // Reset mails
if(m_frame) if(m_frame)
{ {
sMailLog.clear(); sMailLog.clear();
sMailTime.clear(); sMailTime.clear();
m_frame->sMail.clear(); m_frame->sMail.clear();
m_frame->sMailEnd.clear(); m_frame->sMailEnd.clear();
} }
} }
void DSP_DoState(unsigned char **ptr, int mode) { void DSP_DoState(unsigned char **ptr, int mode) {
PointerWrap p(ptr, mode); PointerWrap p(ptr, mode);
} }
unsigned short DSP_ReadMailboxHigh(bool _CPUMailbox) unsigned short DSP_ReadMailboxHigh(bool _CPUMailbox)
{ {
if (_CPUMailbox) if (_CPUMailbox)
{ {
return (g_dspState.CPUMailbox >> 16) & 0xFFFF; return (g_dspState.CPUMailbox >> 16) & 0xFFFF;
} }
else else
{ {
return CDSPHandler::GetInstance().AccessMailHandler().ReadDSPMailboxHigh(); return CDSPHandler::GetInstance().AccessMailHandler().ReadDSPMailboxHigh();
} }
} }
unsigned short DSP_ReadMailboxLow(bool _CPUMailbox) unsigned short DSP_ReadMailboxLow(bool _CPUMailbox)
{ {
if (_CPUMailbox) if (_CPUMailbox)
{ {
return g_dspState.CPUMailbox & 0xFFFF; return g_dspState.CPUMailbox & 0xFFFF;
} }
else else
{ {
return CDSPHandler::GetInstance().AccessMailHandler().ReadDSPMailboxLow(); return CDSPHandler::GetInstance().AccessMailHandler().ReadDSPMailboxLow();
} }
} }
void Update_DSP_WriteRegister() void Update_DSP_WriteRegister()
{ {
// check if the whole message is complete and if we can send it // check if the whole message is complete and if we can send it
if (g_dspState.CPUMailbox_Written[0] && g_dspState.CPUMailbox_Written[1]) if (g_dspState.CPUMailbox_Written[0] && g_dspState.CPUMailbox_Written[1])
{ {
CDSPHandler::GetInstance().SendMailToDSP(g_dspState.CPUMailbox); CDSPHandler::GetInstance().SendMailToDSP(g_dspState.CPUMailbox);
g_dspState.CPUMailbox_Written[0] = g_dspState.CPUMailbox_Written[1] = false; g_dspState.CPUMailbox_Written[0] = g_dspState.CPUMailbox_Written[1] = false;
g_dspState.CPUMailbox = 0; // Mail sent so clear it to show that it is progressed g_dspState.CPUMailbox = 0; // Mail sent so clear it to show that it is progressed
} }
} }
void DSP_WriteMailboxHigh(bool _CPUMailbox, unsigned short _Value) void DSP_WriteMailboxHigh(bool _CPUMailbox, unsigned short _Value)
{ {
if (_CPUMailbox) if (_CPUMailbox)
{ {
g_dspState.CPUMailbox = (g_dspState.CPUMailbox & 0xFFFF) | (_Value << 16); g_dspState.CPUMailbox = (g_dspState.CPUMailbox & 0xFFFF) | (_Value << 16);
g_dspState.CPUMailbox_Written[0] = true; g_dspState.CPUMailbox_Written[0] = true;
Update_DSP_WriteRegister(); Update_DSP_WriteRegister();
} }
else else
{ {
PanicAlert("CPU can't write %08x to DSP mailbox", _Value); PanicAlert("CPU can't write %08x to DSP mailbox", _Value);
} }
} }
void DSP_WriteMailboxLow(bool _CPUMailbox, unsigned short _Value) void DSP_WriteMailboxLow(bool _CPUMailbox, unsigned short _Value)
{ {
if (_CPUMailbox) if (_CPUMailbox)
{ {
g_dspState.CPUMailbox = (g_dspState.CPUMailbox & 0xFFFF0000) | _Value; g_dspState.CPUMailbox = (g_dspState.CPUMailbox & 0xFFFF0000) | _Value;
g_dspState.CPUMailbox_Written[1] = true; g_dspState.CPUMailbox_Written[1] = true;
Update_DSP_WriteRegister(); Update_DSP_WriteRegister();
} }
else else
{ {
PanicAlert("CPU can't write %08x to DSP mailbox", _Value); PanicAlert("CPU can't write %08x to DSP mailbox", _Value);
} }
} }
unsigned short DSP_WriteControlRegister(unsigned short _Value) unsigned short DSP_WriteControlRegister(unsigned short _Value)
{ {
return CDSPHandler::GetInstance().WriteControlRegister(_Value); return CDSPHandler::GetInstance().WriteControlRegister(_Value);
} }
unsigned short DSP_ReadControlRegister() unsigned short DSP_ReadControlRegister()
{ {
return CDSPHandler::GetInstance().ReadControlRegister(); return CDSPHandler::GetInstance().ReadControlRegister();
} }
void DSP_Update(int cycles) void DSP_Update(int cycles)
{ {
CDSPHandler::GetInstance().Update(); CDSPHandler::GetInstance().Update();
} }
void DSP_SendAIBuffer(unsigned int address, int sample_rate) void DSP_SendAIBuffer(unsigned int address, int sample_rate)
{ {
short samples[16] = {0}; // interleaved stereo short samples[16] = {0}; // interleaved stereo
if (address) { if (address) {
for (int i = 0; i < 16; i++) { for (int i = 0; i < 16; i++) {
samples[i] = Memory_Read_U16(address + i * 2); samples[i] = Memory_Read_U16(address + i * 2);
} }
if (log_ai) if (log_ai)
g_wave_writer.AddStereoSamples(samples, 8); g_wave_writer.AddStereoSamples(samples, 8);
} }
Mixer_PushSamples(samples, 32 / 4, sample_rate); Mixer_PushSamples(samples, 32 / 4, sample_rate);
static int counter = 0; static int counter = 0;
counter++; counter++;
#ifdef _WIN32 #ifdef _WIN32
if ((counter & 255) == 0) if ((counter & 255) == 0)
DSound::DSound_UpdateSound(); DSound::DSound_UpdateSound();
#endif #endif
} }

View File

@ -1,19 +1,19 @@
// 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 "stdafx.h" #include "stdafx.h"

View File

@ -1,280 +1,280 @@
// 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 "stdafx.h" #include "stdafx.h"
#include <mmsystem.h> #include <mmsystem.h>
#include <dsound.h> #include <dsound.h>
#include "DSoundStream.h" #include "DSoundStream.h"
namespace DSound namespace DSound
{ {
#define BUFSIZE 32768 #define BUFSIZE 32768
#define MAXWAIT 70 //ms #define MAXWAIT 70 //ms
//THE ROCK SOLID SYNCED DSOUND ENGINE :) //THE ROCK SOLID SYNCED DSOUND ENGINE :)
//våran kritiska sektion och vår syncevent-handle //våran kritiska sektion och vår syncevent-handle
CRITICAL_SECTION soundCriticalSection; CRITICAL_SECTION soundCriticalSection;
HANDLE soundSyncEvent; HANDLE soundSyncEvent;
HANDLE hThread; HANDLE hThread;
StreamCallback callback; StreamCallback callback;
//lite mojs //lite mojs
IDirectSound8* ds; IDirectSound8* ds;
IDirectSoundBuffer* dsBuffer; IDirectSoundBuffer* dsBuffer;
//tja.. behövs //tja.. behövs
int bufferSize; //i bytes int bufferSize; //i bytes
int totalRenderedBytes; int totalRenderedBytes;
int sampleRate; int sampleRate;
//med den här synkar vi stängning.. //med den här synkar vi stängning..
//0=vi spelar oväsen, 1=stäng tråden NU! 2=japp,tråden är stängd så fortsätt //0=vi spelar oväsen, 1=stäng tråden NU! 2=japp,tråden är stängd så fortsätt
volatile int threadData; volatile int threadData;
//ser till så X kan delas med 32 //ser till så X kan delas med 32
inline int FIX32(int x) inline int FIX32(int x)
{ {
return(x & (~127)); return(x & (~127));
} }
int DSound_GetSampleRate() int DSound_GetSampleRate()
{ {
return(sampleRate); return(sampleRate);
} }
//Dags att skapa vår directsound buffert //Dags att skapa vår directsound buffert
bool createBuffer() bool createBuffer()
{ {
PCMWAVEFORMAT pcmwf; PCMWAVEFORMAT pcmwf;
DSBUFFERDESC dsbdesc; DSBUFFERDESC dsbdesc;
//ljudformatet //ljudformatet
memset(&pcmwf, 0, sizeof(PCMWAVEFORMAT)); memset(&pcmwf, 0, sizeof(PCMWAVEFORMAT));
memset(&dsbdesc, 0, sizeof(DSBUFFERDESC)); memset(&dsbdesc, 0, sizeof(DSBUFFERDESC));
pcmwf.wf.wFormatTag = WAVE_FORMAT_PCM; pcmwf.wf.wFormatTag = WAVE_FORMAT_PCM;
pcmwf.wf.nChannels = 2; pcmwf.wf.nChannels = 2;
pcmwf.wf.nSamplesPerSec = sampleRate; pcmwf.wf.nSamplesPerSec = sampleRate;
pcmwf.wf.nBlockAlign = 4; pcmwf.wf.nBlockAlign = 4;
pcmwf.wf.nAvgBytesPerSec = pcmwf.wf.nSamplesPerSec * pcmwf.wf.nBlockAlign; pcmwf.wf.nAvgBytesPerSec = pcmwf.wf.nSamplesPerSec * pcmwf.wf.nBlockAlign;
pcmwf.wBitsPerSample = 16; pcmwf.wBitsPerSample = 16;
//buffer description //buffer description
dsbdesc.dwSize = sizeof(DSBUFFERDESC); dsbdesc.dwSize = sizeof(DSBUFFERDESC);
dsbdesc.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_STICKYFOCUS; //VIKTIGT //DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLFREQUENCY; dsbdesc.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_STICKYFOCUS; //VIKTIGT //DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLFREQUENCY;
dsbdesc.dwBufferBytes = bufferSize = BUFSIZE; //FIX32(pcmwf.wf.nAvgBytesPerSec); //ändra för att ställa in bufferstorlek dsbdesc.dwBufferBytes = bufferSize = BUFSIZE; //FIX32(pcmwf.wf.nAvgBytesPerSec); //ändra för att ställa in bufferstorlek
dsbdesc.lpwfxFormat = (WAVEFORMATEX*)&pcmwf; dsbdesc.lpwfxFormat = (WAVEFORMATEX*)&pcmwf;
// nu skapar vi bufferjäveln // nu skapar vi bufferjäveln
if (SUCCEEDED(ds->CreateSoundBuffer(&dsbdesc, &dsBuffer, NULL))) if (SUCCEEDED(ds->CreateSoundBuffer(&dsbdesc, &dsBuffer, NULL)))
{ {
dsBuffer->SetCurrentPosition(0); dsBuffer->SetCurrentPosition(0);
return(true); return(true);
} }
else else
{ {
// Failed. // Failed.
dsBuffer = NULL; dsBuffer = NULL;
return(false); return(false);
} }
} }
bool writeDataToBuffer(DWORD dwOffset, // Our own write cursor. bool writeDataToBuffer(DWORD dwOffset, // Our own write cursor.
char* soundData, // Start of our data. char* soundData, // Start of our data.
DWORD dwSoundBytes) // Size of block to copy. DWORD dwSoundBytes) // Size of block to copy.
{ {
void* ptr1, * ptr2; void* ptr1, * ptr2;
DWORD numBytes1, numBytes2; DWORD numBytes1, numBytes2;
// Obtain memory address of write block. This will be in two parts if the block wraps around. // Obtain memory address of write block. This will be in two parts if the block wraps around.
HRESULT hr = dsBuffer->Lock(dwOffset, dwSoundBytes, &ptr1, &numBytes1, &ptr2, &numBytes2, 0); HRESULT hr = dsBuffer->Lock(dwOffset, dwSoundBytes, &ptr1, &numBytes1, &ptr2, &numBytes2, 0);
// If the buffer was lost, restore and retry lock. // If the buffer was lost, restore and retry lock.
if (DSERR_BUFFERLOST == hr) if (DSERR_BUFFERLOST == hr)
{ {
dsBuffer->Restore(); dsBuffer->Restore();
hr = dsBuffer->Lock(dwOffset, dwSoundBytes, &ptr1, &numBytes1, &ptr2, &numBytes2, 0); hr = dsBuffer->Lock(dwOffset, dwSoundBytes, &ptr1, &numBytes1, &ptr2, &numBytes2, 0);
} }
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
memcpy(ptr1, soundData, numBytes1); memcpy(ptr1, soundData, numBytes1);
if (ptr2 != 0) if (ptr2 != 0)
{ {
memcpy(ptr2, soundData + numBytes1, numBytes2); memcpy(ptr2, soundData + numBytes1, numBytes2);
} }
// Release the data back to DirectSound. // Release the data back to DirectSound.
dsBuffer->Unlock(ptr1, numBytes1, ptr2, numBytes2); dsBuffer->Unlock(ptr1, numBytes1, ptr2, numBytes2);
return(true); return(true);
} /* } /*
else else
{ {
char temp[8]; char temp[8];
sprintf(temp,"%i\n",hr); sprintf(temp,"%i\n",hr);
OutputDebugString(temp); OutputDebugString(temp);
}*/ }*/
return(false); return(false);
} }
inline int ModBufferSize(int x) inline int ModBufferSize(int x)
{ {
return((x + bufferSize) % bufferSize); return((x + bufferSize) % bufferSize);
} }
int currentPos; int currentPos;
int lastPos; int lastPos;
short realtimeBuffer[1024 * 1024]; short realtimeBuffer[1024 * 1024];
DWORD WINAPI soundThread(void*) DWORD WINAPI soundThread(void*)
{ {
currentPos = 0; currentPos = 0;
lastPos = 0; lastPos = 0;
//writeDataToBuffer(0,realtimeBuffer,bufferSize); //writeDataToBuffer(0,realtimeBuffer,bufferSize);
// dsBuffer->Lock(0, bufferSize, (void **)&p1, &num1, (void **)&p2, &num2, 0); // dsBuffer->Lock(0, bufferSize, (void **)&p1, &num1, (void **)&p2, &num2, 0);
dsBuffer->Play(0, 0, DSBPLAY_LOOPING); dsBuffer->Play(0, 0, DSBPLAY_LOOPING);
while (!threadData) while (!threadData)
{ {
EnterCriticalSection(&soundCriticalSection); EnterCriticalSection(&soundCriticalSection);
dsBuffer->GetCurrentPosition((DWORD*)&currentPos, 0); dsBuffer->GetCurrentPosition((DWORD*)&currentPos, 0);
int numBytesToRender = FIX32(ModBufferSize(currentPos - lastPos)); int numBytesToRender = FIX32(ModBufferSize(currentPos - lastPos));
//renderStuff(numBytesToRender/2); //renderStuff(numBytesToRender/2);
//if (numBytesToRender>bufferSize/2) numBytesToRender=0; //if (numBytesToRender>bufferSize/2) numBytesToRender=0;
if (numBytesToRender >= 256) if (numBytesToRender >= 256)
{ {
(*callback)(realtimeBuffer, numBytesToRender >> 2, 16, 44100, 2); (*callback)(realtimeBuffer, numBytesToRender >> 2, 16, 44100, 2);
writeDataToBuffer(lastPos, (char*)realtimeBuffer, numBytesToRender); writeDataToBuffer(lastPos, (char*)realtimeBuffer, numBytesToRender);
currentPos = ModBufferSize(lastPos + numBytesToRender); currentPos = ModBufferSize(lastPos + numBytesToRender);
totalRenderedBytes += numBytesToRender; totalRenderedBytes += numBytesToRender;
lastPos = currentPos; lastPos = currentPos;
} }
LeaveCriticalSection(&soundCriticalSection); LeaveCriticalSection(&soundCriticalSection);
WaitForSingleObject(soundSyncEvent, MAXWAIT); WaitForSingleObject(soundSyncEvent, MAXWAIT);
} }
dsBuffer->Stop(); dsBuffer->Stop();
threadData = 2; threadData = 2;
return(0); //hurra! return(0); //hurra!
} }
bool DSound_StartSound(HWND window, int _sampleRate, StreamCallback _callback) bool DSound_StartSound(HWND window, int _sampleRate, StreamCallback _callback)
{ {
callback = _callback; callback = _callback;
threadData = 0; threadData = 0;
sampleRate = _sampleRate; sampleRate = _sampleRate;
//no security attributes, automatic resetting, init state nonset, untitled //no security attributes, automatic resetting, init state nonset, untitled
soundSyncEvent = CreateEvent(0, false, false, 0); soundSyncEvent = CreateEvent(0, false, false, 0);
//vi initierar den........... //vi initierar den...........
InitializeCriticalSection(&soundCriticalSection); InitializeCriticalSection(&soundCriticalSection);
//vi vill ha access till DSOUND så... //vi vill ha access till DSOUND så...
if (FAILED(DirectSoundCreate8(0, &ds, 0))) if (FAILED(DirectSoundCreate8(0, &ds, 0)))
{ {
return(false); return(false);
} }
//samarbetsvillig? nää :) //samarbetsvillig? nää :)
ds->SetCooperativeLevel(window, DSSCL_NORMAL); //DSSCL_PRIORITY? ds->SetCooperativeLevel(window, DSSCL_NORMAL); //DSSCL_PRIORITY?
//så.. skapa buffern //så.. skapa buffern
if (!createBuffer()) if (!createBuffer())
{ {
return(false); return(false);
} }
//rensa den.. ? //rensa den.. ?
DWORD num1; DWORD num1;
short* p1; short* p1;
dsBuffer->Lock(0, bufferSize, (void* *)&p1, &num1, 0, 0, 0); dsBuffer->Lock(0, bufferSize, (void* *)&p1, &num1, 0, 0, 0);
memset(p1, 0, num1); memset(p1, 0, num1);
dsBuffer->Unlock(p1, num1, 0, 0); dsBuffer->Unlock(p1, num1, 0, 0);
totalRenderedBytes = -bufferSize; totalRenderedBytes = -bufferSize;
DWORD h; DWORD h;
hThread = CreateThread(0, 0, soundThread, 0, 0, &h); hThread = CreateThread(0, 0, soundThread, 0, 0, &h);
SetThreadPriority(hThread, THREAD_PRIORITY_ABOVE_NORMAL); SetThreadPriority(hThread, THREAD_PRIORITY_ABOVE_NORMAL);
return(true); return(true);
} }
void DSound_UpdateSound() void DSound_UpdateSound()
{ {
SetEvent(soundSyncEvent); SetEvent(soundSyncEvent);
} }
void DSound_StopSound() void DSound_StopSound()
{ {
EnterCriticalSection(&soundCriticalSection); EnterCriticalSection(&soundCriticalSection);
threadData = 1; threadData = 1;
//kick the thread if it's waiting //kick the thread if it's waiting
SetEvent(soundSyncEvent); SetEvent(soundSyncEvent);
LeaveCriticalSection(&soundCriticalSection); LeaveCriticalSection(&soundCriticalSection);
WaitForSingleObject(hThread, INFINITE); WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread); CloseHandle(hThread);
dsBuffer->Release(); dsBuffer->Release();
ds->Release(); ds->Release();
CloseHandle(soundSyncEvent); CloseHandle(soundSyncEvent);
} }
int DSound_GetCurSample() int DSound_GetCurSample()
{ {
EnterCriticalSection(&soundCriticalSection); EnterCriticalSection(&soundCriticalSection);
int playCursor; int playCursor;
dsBuffer->GetCurrentPosition((DWORD*)&playCursor, 0); dsBuffer->GetCurrentPosition((DWORD*)&playCursor, 0);
playCursor = ModBufferSize(playCursor - lastPos) + totalRenderedBytes; playCursor = ModBufferSize(playCursor - lastPos) + totalRenderedBytes;
LeaveCriticalSection(&soundCriticalSection); LeaveCriticalSection(&soundCriticalSection);
return(playCursor); return(playCursor);
} }
float DSound_GetTimer() float DSound_GetTimer()
{ {
return((float)DSound_GetCurSample() * (1.0f / (4.0f * 44100.0f))); return((float)DSound_GetCurSample() * (1.0f / (4.0f * 44100.0f)));
} }
} }

File diff suppressed because it is too large Load Diff

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 <iostream> // I hope this doesn't break anything #include <iostream> // I hope this doesn't break anything
#include <stdio.h> #include <stdio.h>
#include <stdarg.h> #include <stdarg.h>
#include "Common.h" // for Common::swap #include "Common.h" // for Common::swap
#include "Globals.h" #include "Globals.h"
#include "gdsp_interpreter.h" #include "gdsp_interpreter.h"
// ======================================================================================= // =======================================================================================
// This is to verbose, it has to be turned on manually for now // This is to verbose, it has to be turned on manually for now
// -------------- // --------------
void DebugLog(const char* _fmt, ...) void DebugLog(const char* _fmt, ...)
{ {
#if defined(_DEBUG) || defined(DEBUGFAST) #if defined(_DEBUG) || defined(DEBUGFAST)
char Msg[512]; char Msg[512];
va_list ap; va_list ap;
va_start( ap, _fmt ); va_start( ap, _fmt );
vsprintf( Msg, _fmt, ap ); vsprintf( Msg, _fmt, ap );
va_end( ap ); va_end( ap );
// Only show certain messages // Only show certain messages
std::string sMsg = Msg; std::string sMsg = Msg;
if(sMsg.find("Mail") != -1 || sMsg.find("AX") != -1) if(sMsg.find("Mail") != -1 || sMsg.find("AX") != -1)
// no match = -1 // no match = -1
{ {
OutputDebugString(Msg); OutputDebugString(Msg);
g_dspInitialize.pLog(Msg,0); g_dspInitialize.pLog(Msg,0);
} }
#endif #endif
} }
// ============= // =============
void ErrorLog(const char* _fmt, ...) void ErrorLog(const char* _fmt, ...)
{ {
char Msg[512]; char Msg[512];
va_list ap; va_list ap;
va_start(ap, _fmt); va_start(ap, _fmt);
vsprintf(Msg, _fmt, ap); vsprintf(Msg, _fmt, ap);
va_end(ap); va_end(ap);
g_dspInitialize.pLog(Msg,0); g_dspInitialize.pLog(Msg,0);
#ifdef _WIN32 #ifdef _WIN32
::MessageBox(NULL, Msg, "Error", MB_OK); ::MessageBox(NULL, Msg, "Error", MB_OK);
#endif #endif
DSP_DebugBreak(); // NOTICE: we also break the emulation if this happens DSP_DebugBreak(); // NOTICE: we also break the emulation if this happens
} }
// ======================================================================================= // =======================================================================================
// For PB address detection // For PB address detection
// -------------- // --------------
u32 RAM_MASK = 0x1FFFFFF; u32 RAM_MASK = 0x1FFFFFF;
u16 Memory_Read_U16(u32 _uAddress) u16 Memory_Read_U16(u32 _uAddress)
{ {
_uAddress &= RAM_MASK; _uAddress &= RAM_MASK;
return Common::swap16(*(u16*)&g_dsp.cpu_ram[_uAddress]); return Common::swap16(*(u16*)&g_dsp.cpu_ram[_uAddress]);
} }
u32 Memory_Read_U32(u32 _uAddress) u32 Memory_Read_U32(u32 _uAddress)
{ {
_uAddress &= RAM_MASK; _uAddress &= RAM_MASK;
return Common::swap32(*(u32*)&g_dsp.cpu_ram[_uAddress]); return Common::swap32(*(u32*)&g_dsp.cpu_ram[_uAddress]);
} }
#if PROFILE #if PROFILE
#define PROFILE_MAP_SIZE 0x10000 #define PROFILE_MAP_SIZE 0x10000
u64 g_profileMap[PROFILE_MAP_SIZE]; u64 g_profileMap[PROFILE_MAP_SIZE];
bool g_profile = false; bool g_profile = false;
void ProfilerStart() void ProfilerStart()
{ {
g_profile = true; g_profile = true;
} }
void ProfilerAddDelta(int _addr, int _delta) void ProfilerAddDelta(int _addr, int _delta)
{ {
if (g_profile) if (g_profile)
{ {
g_profileMap[_addr] += _delta; g_profileMap[_addr] += _delta;
} }
} }
void ProfilerInit() void ProfilerInit()
{ {
memset(g_profileMap, 0, sizeof(g_profileMap)); memset(g_profileMap, 0, sizeof(g_profileMap));
} }
void ProfilerDump(uint64 count) void ProfilerDump(uint64 count)
{ {
FILE* pFile = fopen("c:\\_\\DSP_Prof.txt", "wt"); FILE* pFile = fopen("c:\\_\\DSP_Prof.txt", "wt");
if (pFile != NULL) if (pFile != NULL)
{ {
fprintf(pFile, "Number of DSP steps: %llu\n\n", count); fprintf(pFile, "Number of DSP steps: %llu\n\n", count);
for (int i=0; i<PROFILE_MAP_SIZE;i++) for (int i=0; i<PROFILE_MAP_SIZE;i++)
{ {
if (g_profileMap[i] > 0) if (g_profileMap[i] > 0)
{ {
fprintf(pFile, "0x%04X: %llu\n", i, g_profileMap[i]); fprintf(pFile, "0x%04X: %llu\n", i, g_profileMap[i]);
} }
} }
fclose(pFile); fclose(pFile);
} }
} }
#endif #endif

File diff suppressed because it is too large Load Diff

View File

@ -1,37 +1,37 @@
// 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/
#ifdef _WIN32 #ifdef _WIN32
#include "stdafx.h" #include "stdafx.h"
#endif #endif
#include "Globals.h" #include "Globals.h"
#include "gdsp_interpreter.h" #include "gdsp_interpreter.h"
#include "gdsp_memory.h" #include "gdsp_memory.h"
#include "gdsp_opcodes_helper.h" #include "gdsp_opcodes_helper.h"
bool WriteDMEM(uint16 addr, uint16 val) bool WriteDMEM(uint16 addr, uint16 val)
{ {
return dsp_dmem_write(addr, val); return dsp_dmem_write(addr, val);
} }
uint16 ReadDMEM(uint16 addr) uint16 ReadDMEM(uint16 addr)
{ {
return dsp_dmem_read(addr); return dsp_dmem_read(addr);
} }

View File

@ -1,100 +1,100 @@
// 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 "Common.h" #include "Common.h"
extern u32 m_addressPBs; extern u32 m_addressPBs;
// ======================================================================================= // =======================================================================================
// Get the parameter block location - Example SSBM: We get the addr 8049cf00, first we // Get the parameter block location - Example SSBM: We get the addr 8049cf00, first we
// always get 0 and go to AXLIST_STUDIOADDR, then we end up at AXLIST_PBADDR. // always get 0 and go to AXLIST_STUDIOADDR, then we end up at AXLIST_PBADDR.
// -------------- // --------------
bool AXTask(u32& _uMail) bool AXTask(u32& _uMail)
{ {
u32 uAddress = _uMail; u32 uAddress = _uMail;
DebugLog("AXTask - ================================================================"); DebugLog("AXTask - ================================================================");
DebugLog("AXTask - AXCommandList-Addr: 0x%08x", uAddress); DebugLog("AXTask - AXCommandList-Addr: 0x%08x", uAddress);
bool bExecuteList = true; bool bExecuteList = true;
while (bExecuteList) while (bExecuteList)
{ {
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
// SSBM: We get the addr 8049cf00, first we always get 0 // SSBM: We get the addr 8049cf00, first we always get 0
u16 iCommand = Memory_Read_U16(uAddress); u16 iCommand = Memory_Read_U16(uAddress);
uAddress += 2; uAddress += 2;
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
switch (iCommand) switch (iCommand)
{ {
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
// ? // ?
case 0: // AXLIST_STUDIOADDR: //00 case 0: // AXLIST_STUDIOADDR: //00
{ {
uAddress += 4; uAddress += 4;
DebugLog("AXLIST AXLIST_SBUFFER: %08x", uAddress); DebugLog("AXLIST AXLIST_SBUFFER: %08x", uAddress);
} }
break; break;
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
case 2: // AXLIST_PBADDR: // 02 case 2: // AXLIST_PBADDR: // 02
{ {
m_addressPBs = Memory_Read_U32(uAddress); m_addressPBs = Memory_Read_U32(uAddress);
uAddress += 4; uAddress += 4;
DebugLog("AXLIST PB address: %08x", m_addressPBs); DebugLog("AXLIST PB address: %08x", m_addressPBs);
bExecuteList = false; bExecuteList = false;
} }
break; break;
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
case 7: // AXLIST_SBUFFER: // 7 case 7: // AXLIST_SBUFFER: // 7
{ {
// Hopefully this is where in main ram to write. // Hopefully this is where in main ram to write.
uAddress += 4; uAddress += 4;
DebugLog("AXLIST AXLIST_SBUFFER: %08x", uAddress); DebugLog("AXLIST AXLIST_SBUFFER: %08x", uAddress);
} }
break; break;
default: default:
{ {
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
// Stop the execution of this TaskList // Stop the execution of this TaskList
DebugLog("AXLIST default: %08x", uAddress); DebugLog("AXLIST default: %08x", uAddress);
bExecuteList = false; bExecuteList = false;
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
} }
break; break;
} // end of switch } // end of switch
} }
DebugLog("AXTask - done, send resume"); DebugLog("AXTask - done, send resume");
DebugLog("AXTask - ================================================================"); DebugLog("AXTask - ================================================================");
// now resume // now resume
return true; return true;
} }
// ======================================================================================= // =======================================================================================

View File

@ -1,197 +1,197 @@
// 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/
#ifdef _WIN32 #ifdef _WIN32
// ======================================================================================= // =======================================================================================
// Includes // Includes
// -------------- // --------------
#include <string> #include <string>
#include <stdio.h> #include <stdio.h>
#include <windows.h> #include <windows.h>
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
// Defines and settings // Defines and settings
// -------------- // --------------
bool g_consoleEnable = true; bool g_consoleEnable = true;
#define DEBUGG #define DEBUGG
//#define DEBUGG_FILEONLY //#define DEBUGG_FILEONLY
//#define DEBUGG_NOFILE //#define DEBUGG_NOFILE
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
// Handles // Handles
// -------------- // --------------
#ifdef DEBUGG #ifdef DEBUGG
FILE* __fStdOut = NULL; FILE* __fStdOut = NULL;
#endif #endif
#ifndef DEBUGG_FILEONLY #ifndef DEBUGG_FILEONLY
HANDLE __hStdOut = NULL; HANDLE __hStdOut = NULL;
#endif #endif
// ============== // ==============
// ======================================================================================= // =======================================================================================
// Width and height is the size of console window, if you specify fname, // Width and height is the size of console window, if you specify fname,
// the output will also be writton to this file. The file pointer is automatically closed // the output will also be writton to this file. The file pointer is automatically closed
// when you close the app // when you close the app
// -------------- // --------------
void startConsoleWin(int width, int height, char* fname) void startConsoleWin(int width, int height, char* fname)
{ {
#ifdef DEBUGG #ifdef DEBUGG
#ifndef DEBUGG_FILEONLY #ifndef DEBUGG_FILEONLY
AllocConsole(); AllocConsole();
SetConsoleTitle(fname); SetConsoleTitle(fname);
__hStdOut = GetStdHandle(STD_OUTPUT_HANDLE); __hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
COORD co = {width,height}; COORD co = {width,height};
SetConsoleScreenBufferSize(__hStdOut, co); SetConsoleScreenBufferSize(__hStdOut, co);
SMALL_RECT coo = {0,0,(width - 1),70}; // top, left, right, bottom SMALL_RECT coo = {0,0,(width - 1),70}; // top, left, right, bottom
SetConsoleWindowInfo(__hStdOut, TRUE, &coo); SetConsoleWindowInfo(__hStdOut, TRUE, &coo);
#endif #endif
#ifndef DEBUGG_NOFILE #ifndef DEBUGG_NOFILE
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
// Write to a file // Write to a file
if(fname) if(fname)
{ {
// 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;
std::string FullFilename = (FileName + FileEnding); std::string FullFilename = (FileName + FileEnding);
__fStdOut = fopen(FullFilename.c_str(), "w"); __fStdOut = fopen(FullFilename.c_str(), "w");
} }
// ----------------- // -----------------
#endif #endif
#endif #endif
} }
void ClearScreen(); void ClearScreen();
int wprintf(char *fmt, ...) int wprintf(char *fmt, ...)
{ {
#ifdef DEBUGG #ifdef DEBUGG
char s[6000]; // WARNING: mind this value char s[6000]; // 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, 3000, fmt, argptr); cnt = vsnprintf(s, 3000, fmt, argptr);
va_end(argptr); va_end(argptr);
DWORD cCharsWritten; DWORD cCharsWritten;
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
#ifndef DEBUGG_FILEONLY #ifndef DEBUGG_FILEONLY
if(__hStdOut) if(__hStdOut)
{ {
WriteConsole(__hStdOut, s, strlen(s), &cCharsWritten, NULL); WriteConsole(__hStdOut, s, strlen(s), &cCharsWritten, NULL);
} }
#endif #endif
#ifndef DEBUGG_NOFILE #ifndef DEBUGG_NOFILE
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
if(__fStdOut) if(__fStdOut)
fprintf(__fStdOut, s); fprintf(__fStdOut, s);
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
#endif #endif
return(cnt); return(cnt);
#else #else
return 0; return 0;
#endif #endif
} }
// ======================================================================================= // =======================================================================================
// Clear screen // Clear screen
// -------------- // --------------
void ClearScreen() void ClearScreen()
{ {
if(g_consoleEnable) if(g_consoleEnable)
{ {
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);
//HANDLE hConsole = __hStdOut; //HANDLE hConsole = __hStdOut;
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);
} }
} }
// ======================================================================================= // =======================================================================================
// Get console HWND to be able to use MoveWindow() // Get console HWND to be able to use MoveWindow()
// -------------- // --------------
HWND GetConsoleHwnd(void) HWND GetConsoleHwnd(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 char pszNewWindowTitle[MY_BUFSIZE]; // Contains fabricated
// WindowTitle. // WindowTitle.
char pszOldWindowTitle[MY_BUFSIZE]; // Contains original char pszOldWindowTitle[MY_BUFSIZE]; // Contains original
// WindowTitle. // 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", wsprintf(pszNewWindowTitle,"%d/%d",
GetTickCount(), GetTickCount(),
GetCurrentProcessId()); 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 #endif

View File

@ -1,380 +1,380 @@
// 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/
#ifdef _WIN32 #ifdef _WIN32
// ======================================================================================= // =======================================================================================
// Includes // Includes
// -------------- // --------------
#include <iostream> #include <iostream>
#include <vector> #include <vector>
#include <string> // So that we can test if std::string == abc #include <string> // So that we can test if std::string == abc
#include <windows.h> #include <windows.h>
#include "Common.h" #include "Common.h"
#include "UCode_AXStructs.h" // they are only in a virtual dir called UCodes AX #include "UCode_AXStructs.h" // they are only in a virtual dir called UCodes AX
#include "Console.h" // For wprintf, ClearScreen #include "Console.h" // For wprintf, ClearScreen
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
// Declarations // Declarations
// -------------- // --------------
#define NUMBER_OF_PBS 64 // Todo: move this to a logging class #define NUMBER_OF_PBS 64 // Todo: move this to a logging class
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
// Externals // Externals
// -------------- // --------------
extern u32 m_addressPBs; extern u32 m_addressPBs;
float ratioFactor; float ratioFactor;
int globaliSize; int globaliSize;
short globalpBuffer; short globalpBuffer;
u32 gLastBlock; u32 gLastBlock;
// -------------- // --------------
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
// Vectors and other stuff // Vectors and other stuff
// -------------- // --------------
std::vector<u32> gloopPos(64); std::vector<u32> gloopPos(64);
std::vector<u32> gsampleEnd(64); std::vector<u32> gsampleEnd(64);
std::vector<u32> gsamplePos(64); std::vector<u32> gsamplePos(64);
std::vector<u32> gratio(64); std::vector<u32> gratio(64);
std::vector<u32> gratiohi(64); std::vector<u32> gratiohi(64);
std::vector<u32> gratiolo(64); std::vector<u32> gratiolo(64);
std::vector<u32> gfrac(64); std::vector<u32> gfrac(64);
std::vector<u32> gcoef(64); std::vector<u32> gcoef(64);
// PBSampleRateConverter mixer // PBSampleRateConverter mixer
std::vector<u16> gvolume_left(64); std::vector<u16> gvolume_left(64);
std::vector<u16> gvolume_right(64); std::vector<u16> gvolume_right(64);
std::vector<u16> gmixer_control(64); std::vector<u16> gmixer_control(64);
std::vector<u16> gcur_volume(64); std::vector<u16> gcur_volume(64);
std::vector<u16> gcur_volume_delta(64); std::vector<u16> gcur_volume_delta(64);
std::vector<u16> gaudioFormat(64); std::vector<u16> gaudioFormat(64);
std::vector<u16> glooping(64); std::vector<u16> glooping(64);
std::vector<u16> gsrc_type(64); std::vector<u16> gsrc_type(64);
std::vector<u16> gis_stream(64); std::vector<u16> gis_stream(64);
// loop // loop
std::vector<u16> gloop1(64); std::vector<u16> gloop1(64);
std::vector<u16> gloop2(64); std::vector<u16> gloop2(64);
std::vector<u16> gloop3(64); std::vector<u16> gloop3(64);
std::vector<u16> gadloop1(64); std::vector<u16> gadloop1(64);
std::vector<u16> gadloop2(64); std::vector<u16> gadloop2(64);
std::vector<u16> gadloop3(64); std::vector<u16> gadloop3(64);
// updates // updates
std::vector<u16> gupdates1(64); std::vector<u16> gupdates1(64);
std::vector<u16> gupdates2(64); std::vector<u16> gupdates2(64);
std::vector<u16> gupdates3(64); std::vector<u16> gupdates3(64);
std::vector<u16> gupdates4(64); std::vector<u16> gupdates4(64);
std::vector<u16> gupdates5(64); std::vector<u16> gupdates5(64);
std::vector<u32> gupdates_addr(64); std::vector<u32> gupdates_addr(64);
// other stuff // other stuff
std::vector<u16> Jump(64); // this is 1 or 0 std::vector<u16> Jump(64); // this is 1 or 0
std::vector<int> musicLength(64); std::vector<int> musicLength(64);
std::vector< std::vector<int> > vector1(64, std::vector<int>(100,0)); std::vector< std::vector<int> > vector1(64, std::vector<int>(100,0));
std::vector<int> numberRunning(64); std::vector<int> numberRunning(64);
int j = 0; int j = 0;
int k = 0; int k = 0;
__int64 l = 0; __int64 l = 0;
int iupd = 0; int iupd = 0;
bool iupdonce = false; bool iupdonce = false;
std::vector<u16> viupd(15); // the length of the update frequency bar std::vector<u16> viupd(15); // the length of the update frequency bar
int vectorLength = 15; // the length of the playback history bar and how long int vectorLength = 15; // the length of the playback history bar and how long
// old blocks are shown // old blocks are shown
std::vector<u16> vector62(vectorLength); std::vector<u16> vector62(vectorLength);
std::vector<u16> vector63(vectorLength); std::vector<u16> vector63(vectorLength);
int ReadOutPBs(AXParamBlock * _pPBs, int _num); int ReadOutPBs(AXParamBlock * _pPBs, int _num);
// =========== // ===========
// ======================================================================================= // =======================================================================================
// Main logging function // Main logging function
// -------------- // --------------
void Logging() void Logging()
{ {
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
// Control how often the screen is updated // Control how often the screen is updated
j++; j++;
l++; l++;
if (j>1000000) // TODO: make the update frequency adjustable from the logging window if (j>1000000) // TODO: make the update frequency adjustable from the logging window
{ {
AXParamBlock PBs[NUMBER_OF_PBS]; AXParamBlock PBs[NUMBER_OF_PBS];
int numberOfPBs = ReadOutPBs(PBs, NUMBER_OF_PBS); int numberOfPBs = ReadOutPBs(PBs, NUMBER_OF_PBS);
// ======================================================================================= // =======================================================================================
// Vector1 is a vector1[64][100] vector // Vector1 is a vector1[64][100] vector
/* /*
Move all items back like this Move all items back like this
1 to 2 1 to 2
2 3 2 3
3 ... 3 ...
*/ */
// ---------------- // ----------------
for (int i = 0; i < 64; i++) for (int i = 0; i < 64; i++)
{ {
for (int j = 1; j < vectorLength; j++) for (int j = 1; j < vectorLength; j++)
{ {
vector1.at(i).at(j-1) = vector1.at(i).at(j); vector1.at(i).at(j-1) = vector1.at(i).at(j);
} }
} }
// ================= // =================
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
// Enter the latest value // Enter the latest value
for (int i = 0; i < numberOfPBs; i++) for (int i = 0; i < numberOfPBs; i++)
{ {
vector1.at(i).at(vectorLength-1) = PBs[i].running; vector1.at(i).at(vectorLength-1) = PBs[i].running;
} }
// ----------------- // -----------------
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
// Count how many blocks we have running now // Count how many blocks we have running now
int jj = 0; int jj = 0;
for (int i = 0; i < 64; i++) for (int i = 0; i < 64; i++)
{ {
for (int j = 0; j < vectorLength-1; j++) for (int j = 0; j < vectorLength-1; j++)
{ {
if (vector1.at(i).at(j) == 1) if (vector1.at(i).at(j) == 1)
{ {
jj++; jj++;
} }
numberRunning.at(i) = jj; numberRunning.at(i) = jj;
} }
} }
// -------------- // --------------
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
// Write the first row // Write the first row
char buffer [1000] = ""; char buffer [1000] = "";
std::string sbuff; std::string sbuff;
//sbuff = sbuff + " Nr | | frac ratio | old new \n"; // 5 //sbuff = sbuff + " Nr | | frac ratio | old new \n"; // 5
sbuff = sbuff + " Nr pos / end lpos | voll volr curv vold mix | isl[pre yn1 yn2] iss | frac ratio[hi lo] | 1 2 3 4 5\n"; sbuff = sbuff + " Nr pos / end lpos | voll volr curv vold mix | isl[pre yn1 yn2] iss | frac ratio[hi lo] | 1 2 3 4 5\n";
// -------------- // --------------
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
// Read out values for all blocks // Read out values for all blocks
for (int i = 0; i < numberOfPBs; i++) for (int i = 0; i < numberOfPBs; i++)
{ {
if (numberRunning.at(i) > 0) if (numberRunning.at(i) > 0)
{ {
// ======================================================================================= // =======================================================================================
// Write the playback bar // Write the playback bar
// ------------- // -------------
for (int j = 0; j < vectorLength; j++) for (int j = 0; j < vectorLength; j++)
{ {
if(vector1.at(i).at(j) == 0) if(vector1.at(i).at(j) == 0)
{ {
sbuff = sbuff + " "; sbuff = sbuff + " ";
} }
else else
{ {
sprintf(buffer, "%c", 177); sprintf(buffer, "%c", 177);
sbuff = sbuff + buffer; strcpy(buffer, ""); sbuff = sbuff + buffer; strcpy(buffer, "");
} }
} }
// ============== // ==============
// ================================================================================================ // ================================================================================================
int sampleJump; int sampleJump;
int loopJump; int loopJump;
//if (PBs[i].running && PBs[i].adpcm_loop_info.yn1 && PBs[i].mixer.volume_left) //if (PBs[i].running && PBs[i].adpcm_loop_info.yn1 && PBs[i].mixer.volume_left)
if (true) if (true)
{ {
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
// AXPB base // AXPB base
//int running = pb.running; //int running = pb.running;
gcoef[i] = PBs[i].unknown1; gcoef[i] = PBs[i].unknown1;
sampleJump = ((PBs[i].audio_addr.cur_addr_hi << 16) | PBs[i].audio_addr.cur_addr_lo) - gsamplePos[i]; sampleJump = ((PBs[i].audio_addr.cur_addr_hi << 16) | PBs[i].audio_addr.cur_addr_lo) - gsamplePos[i];
loopJump = ((PBs[i].audio_addr.loop_addr_hi << 16) | PBs[i].audio_addr.loop_addr_lo) - gloopPos[i]; loopJump = ((PBs[i].audio_addr.loop_addr_hi << 16) | PBs[i].audio_addr.loop_addr_lo) - gloopPos[i];
gloopPos[i] = (PBs[i].audio_addr.loop_addr_hi << 16) | PBs[i].audio_addr.loop_addr_lo; gloopPos[i] = (PBs[i].audio_addr.loop_addr_hi << 16) | PBs[i].audio_addr.loop_addr_lo;
gsampleEnd[i] = (PBs[i].audio_addr.end_addr_hi << 16) | PBs[i].audio_addr.end_addr_lo; gsampleEnd[i] = (PBs[i].audio_addr.end_addr_hi << 16) | PBs[i].audio_addr.end_addr_lo;
gsamplePos[i] = (PBs[i].audio_addr.cur_addr_hi << 16) | PBs[i].audio_addr.cur_addr_lo; gsamplePos[i] = (PBs[i].audio_addr.cur_addr_hi << 16) | PBs[i].audio_addr.cur_addr_lo;
// PBSampleRateConverter src // PBSampleRateConverter src
gratio[i] = (u32)(((PBs[i].src.ratio_hi << 16) + PBs[i].src.ratio_lo) * ratioFactor); gratio[i] = (u32)(((PBs[i].src.ratio_hi << 16) + PBs[i].src.ratio_lo) * ratioFactor);
gratiohi[i] = PBs[i].src.ratio_hi; gratiohi[i] = PBs[i].src.ratio_hi;
gratiolo[i] = PBs[i].src.ratio_lo; gratiolo[i] = PBs[i].src.ratio_lo;
gfrac[i] = PBs[i].src.cur_addr_frac; gfrac[i] = PBs[i].src.cur_addr_frac;
// adpcm_loop_info // adpcm_loop_info
gadloop1[i] = PBs[i].adpcm.pred_scale; gadloop1[i] = PBs[i].adpcm.pred_scale;
gadloop2[i] = PBs[i].adpcm.yn1; gadloop2[i] = PBs[i].adpcm.yn1;
gadloop3[i] = PBs[i].adpcm.yn2; gadloop3[i] = PBs[i].adpcm.yn2;
gloop1[i] = PBs[i].adpcm_loop_info.pred_scale; gloop1[i] = PBs[i].adpcm_loop_info.pred_scale;
gloop2[i] = PBs[i].adpcm_loop_info.yn1; gloop2[i] = PBs[i].adpcm_loop_info.yn1;
gloop3[i] = PBs[i].adpcm_loop_info.yn2; gloop3[i] = PBs[i].adpcm_loop_info.yn2;
// updates // updates
gupdates1[i] = PBs[i].updates.num_updates[0]; gupdates1[i] = PBs[i].updates.num_updates[0];
gupdates2[i] = PBs[i].updates.num_updates[1]; gupdates2[i] = PBs[i].updates.num_updates[1];
gupdates3[i] = PBs[i].updates.num_updates[2]; gupdates3[i] = PBs[i].updates.num_updates[2];
gupdates4[i] = PBs[i].updates.num_updates[3]; gupdates4[i] = PBs[i].updates.num_updates[3];
gupdates5[i] = PBs[i].updates.num_updates[4]; gupdates5[i] = PBs[i].updates.num_updates[4];
gupdates_addr[i] = (PBs[i].updates.data_hi << 16) | PBs[i].updates.data_lo; gupdates_addr[i] = (PBs[i].updates.data_hi << 16) | PBs[i].updates.data_lo;
gaudioFormat[i] = PBs[i].audio_addr.sample_format; gaudioFormat[i] = PBs[i].audio_addr.sample_format;
glooping[i] = PBs[i].audio_addr.looping; glooping[i] = PBs[i].audio_addr.looping;
gsrc_type[i] = PBs[i].src_type; gsrc_type[i] = PBs[i].src_type;
gis_stream[i] = PBs[i].is_stream; gis_stream[i] = PBs[i].is_stream;
// mixer // mixer
gvolume_left[i] = PBs[i].mixer.volume_left; gvolume_left[i] = PBs[i].mixer.volume_left;
gvolume_right[i] = PBs[i].mixer.volume_right; gvolume_right[i] = PBs[i].mixer.volume_right;
gmixer_control[i] = PBs[i].mixer_control; gmixer_control[i] = PBs[i].mixer_control;
gcur_volume[i] = PBs[i].vol_env.cur_volume; gcur_volume[i] = PBs[i].vol_env.cur_volume;
gcur_volume_delta[i] = PBs[i].vol_env.cur_volume_delta; gcur_volume_delta[i] = PBs[i].vol_env.cur_volume_delta;
// other stuff // other stuff
Jump[i] = (gfrac[i] >> 16); // This is 1 or 0 Jump[i] = (gfrac[i] >> 16); // This is 1 or 0
musicLength[i] = gsampleEnd[i] - gloopPos[i]; musicLength[i] = gsampleEnd[i] - gloopPos[i];
} }
// ================================================================================================ // ================================================================================================
// ======================================================================================= // =======================================================================================
// PRESETS // PRESETS
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
/* /*
/" Nr pos / end lpos | voll volr curv vold mix | isl[pre yn1 yn2] iss | frac ratio[hi lo] | 1 2 3 4 5\n"; /" Nr pos / end lpos | voll volr curv vold mix | isl[pre yn1 yn2] iss | frac ratio[hi lo] | 1 2 3 4 5\n";
"---------------|00 12341234/12341234 12341234 | 00000 00000 00000 0000 00000 | 0[000 00000 00000] 0 | 00000 00000[0 00000] | "---------------|00 12341234/12341234 12341234 | 00000 00000 00000 0000 00000 | 0[000 00000 00000] 0 | 00000 00000[0 00000] |
*/ */
sprintf(buffer,"%c%i %08i/%08i %08i | %05i %05i %05i %04i %05i | %i[%03i %05i %05i] %i | %05i %05i[%i %05i] | %i %i %i %i %i", sprintf(buffer,"%c%i %08i/%08i %08i | %05i %05i %05i %04i %05i | %i[%03i %05i %05i] %i | %05i %05i[%i %05i] | %i %i %i %i %i",
223, i, gsamplePos[i], gsampleEnd[i], gloopPos[i], 223, i, gsamplePos[i], gsampleEnd[i], gloopPos[i],
gvolume_left[i], gvolume_right[i], gcur_volume[i], gcur_volume_delta[i], gmixer_control[i], gvolume_left[i], gvolume_right[i], gcur_volume[i], gcur_volume_delta[i], gmixer_control[i],
glooping[i], gloop1[i], gloop2[i], gloop3[i], gis_stream[i], glooping[i], gloop1[i], gloop2[i], gloop3[i], gis_stream[i],
gfrac[i], gratio[i], gratiohi[i], gratiolo[i], gfrac[i], gratio[i], gratiohi[i], gratiolo[i],
gupdates1[i], gupdates2[i], gupdates3[i], gupdates4[i], gupdates5[i] gupdates1[i], gupdates2[i], gupdates3[i], gupdates4[i], gupdates5[i]
); );
// ======================================================================================= // =======================================================================================
// write a new line // write a new line
sbuff = sbuff + buffer; strcpy(buffer, ""); sbuff = sbuff + buffer; strcpy(buffer, "");
sbuff = sbuff + "\n"; sbuff = sbuff + "\n";
} // end of if (true) } // end of if (true)
} // end of big loop - for (int i = 0; i < numberOfPBs; i++) } // end of big loop - for (int i = 0; i < numberOfPBs; i++)
// ======================================================================================= // =======================================================================================
// Write global values // Write global values
sprintf(buffer, "\nParameter blocks span from %08x | to %08x | distance %i %i\n", m_addressPBs, gLastBlock, (gLastBlock-m_addressPBs), (gLastBlock-m_addressPBs) / 192); sprintf(buffer, "\nParameter blocks span from %08x | to %08x | distance %i %i\n", m_addressPBs, gLastBlock, (gLastBlock-m_addressPBs), (gLastBlock-m_addressPBs) / 192);
sbuff = sbuff + buffer; strcpy(buffer, ""); sbuff = sbuff + buffer; strcpy(buffer, "");
// ============== // ==============
// ======================================================================================= // =======================================================================================
// Show update frequency // Show update frequency
// --------------- // ---------------
sbuff = sbuff + "\n"; sbuff = sbuff + "\n";
if(!iupdonce) if(!iupdonce)
{ {
/* /*
for (int i = 0; i < 10; i++) for (int i = 0; i < 10; i++)
{ {
viupd.at(i) == 0; viupd.at(i) == 0;
} }
*/ */
viupd.at(0) = 1; viupd.at(0) = 1;
viupd.at(1) = 1; viupd.at(1) = 1;
viupd.at(2) = 1; viupd.at(2) = 1;
iupdonce = true; iupdonce = true;
} }
for (int i = 0; i < viupd.size(); i++) // 0, 1,..., 9 for (int i = 0; i < viupd.size(); i++) // 0, 1,..., 9
{ {
if (i < viupd.size()-1) if (i < viupd.size()-1)
{ {
viupd.at(viupd.size()-i-1) = viupd.at(viupd.size()-i-2); // move all forward viupd.at(viupd.size()-i-1) = viupd.at(viupd.size()-i-2); // move all forward
} }
else else
{ {
viupd.at(0) = viupd.at(viupd.size()-1); viupd.at(0) = viupd.at(viupd.size()-1);
} }
// Correction // Correction
if (viupd.at(viupd.size()-3) == 1 && viupd.at(viupd.size()-2) == 1 && viupd.at(viupd.size()-1) == 1) if (viupd.at(viupd.size()-3) == 1 && viupd.at(viupd.size()-2) == 1 && viupd.at(viupd.size()-1) == 1)
{ {
viupd.at(0) = 0; viupd.at(0) = 0;
} }
if(viupd.at(0) == 0 && viupd.at(1) == 1 && viupd.at(2) == 1 && viupd.at(3) == 0) if(viupd.at(0) == 0 && viupd.at(1) == 1 && viupd.at(2) == 1 && viupd.at(3) == 0)
{ {
viupd.at(0) = 1; viupd.at(0) = 1;
} }
} }
for (int i = 0; i < viupd.size(); i++) for (int i = 0; i < viupd.size(); i++)
{ {
if(viupd.at(i) == 0) if(viupd.at(i) == 0)
sbuff = sbuff + " "; sbuff = sbuff + " ";
else else
sbuff = sbuff + "."; sbuff = sbuff + ".";
} }
// ================ // ================
// ======================================================================================= // =======================================================================================
// Print // Print
// --------------- // ---------------
ClearScreen(); ClearScreen();
wprintf("%s", sbuff.c_str()); wprintf("%s", sbuff.c_str());
sbuff.clear(); strcpy(buffer, ""); sbuff.clear(); strcpy(buffer, "");
// --------------- // ---------------
k=0; k=0;
j=0; j=0;
// --------------- // ---------------
} }
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
} }
// ======================================================================================= // =======================================================================================
#endif #endif

View File

@ -1,115 +1,115 @@
// 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/
// Turn on and off logging modes // Turn on and off logging modes
// -------------- // --------------
//#define LOG1 // writes selected parameters only and with more readable formatting //#define LOG1 // writes selected parameters only and with more readable formatting
//#define LOG2 // writes all parameters //#define LOG2 // writes all parameters
#include "Common.h" #include "Common.h"
#include "../Globals.h" #include "../Globals.h"
#include "CommonTypes.h" // Pluginspecs #include "CommonTypes.h" // Pluginspecs
#include "UCode_AXStructs.h" // For the AXParamBlock structure #include "UCode_AXStructs.h" // For the AXParamBlock structure
#include "Console.h" // For wprintf, ClearScreen #include "Console.h" // For wprintf, ClearScreen
u32 m_addressPBs = 0; u32 m_addressPBs = 0;
extern u32 gLastBlock; extern u32 gLastBlock;
#ifdef _WIN32 #ifdef _WIN32
int m = 0; int m = 0;
int n = 0; int n = 0;
#ifdef LOG2 #ifdef LOG2
bool logall = true; bool logall = true;
#else #else
bool logall = false; bool logall = false;
#endif #endif
int ReadOutPBs(AXParamBlock * _pPBs, int _num) int ReadOutPBs(AXParamBlock * _pPBs, int _num)
{ {
int count = 0; int count = 0;
u32 blockAddr = m_addressPBs; u32 blockAddr = m_addressPBs;
u32 OldblockAddr = blockAddr; u32 OldblockAddr = blockAddr;
u32 paraAddr = blockAddr; u32 paraAddr = blockAddr;
// reading and 'halfword' swap // reading and 'halfword' swap
n++; n++;
if (n > 20 && logall) {ClearScreen();} if (n > 20 && logall) {ClearScreen();}
for (int i = 0; i < _num; i++) for (int i = 0; i < _num; i++)
{ {
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
// Check if there is something here. // Check if there is something here.
const short * pSrc = (const short *)g_dspInitialize.pGetMemoryPointer(blockAddr); const short * pSrc = (const short *)g_dspInitialize.pGetMemoryPointer(blockAddr);
// ------------- // -------------
if (pSrc != NULL) // only read non-blank blocks if (pSrc != NULL) // only read non-blank blocks
{ {
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
// Create a shortcut that let us update struct members // Create a shortcut that let us update struct members
short * pDest = (short *) & _pPBs[i]; short * pDest = (short *) & _pPBs[i];
if (n > 20 && logall) {wprintf("%c%i:", 223, i);} // logging if (n > 20 && logall) {wprintf("%c%i:", 223, i);} // logging
// -------------- // --------------
// Here we update the PB. We do it by going through all 192 / 2 = 96 u16 values // Here we update the PB. We do it by going through all 192 / 2 = 96 u16 values
for (size_t p = 0; p < sizeof(AXParamBlock) / 2; p++) for (size_t p = 0; p < sizeof(AXParamBlock) / 2; p++)
{ {
paraAddr += 2; paraAddr += 2;
if(pSrc != NULL) if(pSrc != NULL)
{ {
if (pSrc[p] != 0 && n > 20 && logall) if (pSrc[p] != 0 && n > 20 && logall)
{ {
wprintf("%i %04x | ", p, Common::swap16(pSrc[p])); wprintf("%i %04x | ", p, Common::swap16(pSrc[p]));
} }
} }
pDest[p] = Common::swap16(pSrc[p]); pDest[p] = Common::swap16(pSrc[p]);
} }
if(n > 20 && logall) {wprintf("\n");} // logging if(n > 20 && logall) {wprintf("\n");} // logging
// -------------- // --------------
// Here we update the block address to the starting point of the next PB // Here we update the block address to the starting point of the next PB
blockAddr = (_pPBs[i].next_pb_hi << 16) | _pPBs[i].next_pb_lo; blockAddr = (_pPBs[i].next_pb_hi << 16) | _pPBs[i].next_pb_lo;
// -------------- // --------------
// save some values // save some values
count++; count++;
gLastBlock = paraAddr; // blockAddr gLastBlock = paraAddr; // blockAddr
// ============ // ============
} }
else else
{ {
break; break;
} }
} // end of the big loop } // end of the big loop
if (n > 20) {n = 0;} // for logging if (n > 20) {n = 0;} // for logging
// return the number of readed PBs // return the number of readed PBs
return count; return count;
} }
// ======================================================================================= // =======================================================================================
#endif #endif

View File

@ -1,164 +1,164 @@
// 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/
// This queue solution is temporary. I'll implement something more efficient later. // This queue solution is temporary. I'll implement something more efficient later.
#include <queue> #include <queue>
#include "Thread.h" #include "Thread.h"
#include "Mixer.h" #include "Mixer.h"
#include "FixedSizeQueue.h" #include "FixedSizeQueue.h"
#ifdef _WIN32 #ifdef _WIN32
#include "DSoundStream.h" #include "DSoundStream.h"
#else #else
#include <unistd.h> #include <unistd.h>
#endif #endif
namespace { namespace {
Common::CriticalSection push_sync; Common::CriticalSection push_sync;
// On real hardware, this fifo is much, much smaller. But timing is also tighter than under Windows, so... // On real hardware, this fifo is much, much smaller. But timing is also tighter than under Windows, so...
const int queue_minlength = 1024 * 4; const int queue_minlength = 1024 * 4;
const int queue_maxlength = 1024 * 28; const int queue_maxlength = 1024 * 28;
FixedSizeQueue<s16, queue_maxlength> sample_queue; FixedSizeQueue<s16, queue_maxlength> sample_queue;
} // namespace } // namespace
volatile bool mixer_HLEready = false; volatile bool mixer_HLEready = false;
volatile int queue_size = 0; volatile int queue_size = 0;
void Mixer(short *buffer, int numSamples, int bits, int rate, int channels) void Mixer(short *buffer, int numSamples, int bits, int rate, int channels)
{ {
// silence // silence
memset(buffer, 0, numSamples * 2 * sizeof(short)); memset(buffer, 0, numSamples * 2 * sizeof(short));
push_sync.Enter(); push_sync.Enter();
int count = 0; int count = 0;
while (queue_size > queue_minlength && count < numSamples * 2) { while (queue_size > queue_minlength && count < numSamples * 2) {
int x = buffer[count]; int x = buffer[count];
x += sample_queue.front(); x += sample_queue.front();
if (x > 32767) x = 32767; if (x > 32767) x = 32767;
if (x < -32767) x = -32767; if (x < -32767) x = -32767;
buffer[count++] = x; buffer[count++] = x;
sample_queue.pop(); sample_queue.pop();
x = buffer[count]; x = buffer[count];
x += sample_queue.front(); x += sample_queue.front();
if (x > 32767) x = 32767; if (x > 32767) x = 32767;
if (x < -32767) x = -32767; if (x < -32767) x = -32767;
buffer[count++] = x; buffer[count++] = x;
sample_queue.pop(); sample_queue.pop();
queue_size-=2; queue_size-=2;
} }
push_sync.Leave(); push_sync.Leave();
} }
void Mixer_PushSamples(short *buffer, int num_stereo_samples, int sample_rate) { void Mixer_PushSamples(short *buffer, int num_stereo_samples, int sample_rate) {
// static FILE *f; // static FILE *f;
// if (!f) // if (!f)
// f = fopen("d:\\hello.raw", "wb"); // f = fopen("d:\\hello.raw", "wb");
// fwrite(buffer, num_stereo_samples * 4, 1, f); // fwrite(buffer, num_stereo_samples * 4, 1, f);
if (queue_size == 0) if (queue_size == 0)
{ {
queue_size = queue_minlength; queue_size = queue_minlength;
for (int i = 0; i < queue_minlength; i++) for (int i = 0; i < queue_minlength; i++)
sample_queue.push((s16)0); sample_queue.push((s16)0);
} }
static int PV1l=0,PV2l=0,PV3l=0,PV4l=0; static int PV1l=0,PV2l=0,PV3l=0,PV4l=0;
static int PV1r=0,PV2r=0,PV3r=0,PV4r=0; static int PV1r=0,PV2r=0,PV3r=0,PV4r=0;
static int acc=0; static int acc=0;
#ifdef _WIN32 #ifdef _WIN32
if (!GetAsyncKeyState(VK_TAB)) { if (!GetAsyncKeyState(VK_TAB)) {
while (queue_size > queue_maxlength / 2) { while (queue_size > queue_maxlength / 2) {
DSound::DSound_UpdateSound(); DSound::DSound_UpdateSound();
Sleep(0); Sleep(0);
} }
} else { } else {
return; return;
} }
#else #else
while (queue_size > queue_maxlength) { while (queue_size > queue_maxlength) {
sleep(0); sleep(0);
} }
#endif #endif
//convert into config option? //convert into config option?
const int mode = 2; const int mode = 2;
push_sync.Enter(); push_sync.Enter();
while (num_stereo_samples) while (num_stereo_samples)
{ {
acc += sample_rate; acc += sample_rate;
while (num_stereo_samples && (acc >= 48000)) while (num_stereo_samples && (acc >= 48000))
{ {
PV4l=PV3l; PV4l=PV3l;
PV3l=PV2l; PV3l=PV2l;
PV2l=PV1l; PV2l=PV1l;
PV1l=*(buffer++); //32bit processing PV1l=*(buffer++); //32bit processing
PV4r=PV3r; PV4r=PV3r;
PV3r=PV2r; PV3r=PV2r;
PV2r=PV1r; PV2r=PV1r;
PV1r=*(buffer++); //32bit processing PV1r=*(buffer++); //32bit processing
num_stereo_samples--; num_stereo_samples--;
acc-=48000; acc-=48000;
} }
// defaults to nearest // defaults to nearest
s32 DataL = PV1l; s32 DataL = PV1l;
s32 DataR = PV1r; s32 DataR = PV1r;
if (mode == 1) //linear if (mode == 1) //linear
{ {
DataL = PV1l + ((PV2l - PV1l)*acc)/48000; DataL = PV1l + ((PV2l - PV1l)*acc)/48000;
DataR = PV1r + ((PV2r - PV1r)*acc)/48000; DataR = PV1r + ((PV2r - PV1r)*acc)/48000;
} }
else if (mode == 2) //cubic else if (mode == 2) //cubic
{ {
s32 a0l = PV1l - PV2l - PV4l + PV3l; s32 a0l = PV1l - PV2l - PV4l + PV3l;
s32 a0r = PV1r - PV2r - PV4r + PV3r; s32 a0r = PV1r - PV2r - PV4r + PV3r;
s32 a1l = PV4l - PV3l - a0l; s32 a1l = PV4l - PV3l - a0l;
s32 a1r = PV4r - PV3r - a0r; s32 a1r = PV4r - PV3r - a0r;
s32 a2l = PV1l - PV4l; s32 a2l = PV1l - PV4l;
s32 a2r = PV1r - PV4r; s32 a2r = PV1r - PV4r;
s32 a3l = PV2l; s32 a3l = PV2l;
s32 a3r = PV2r; s32 a3r = PV2r;
s32 t0l = ((a0l )*acc)/48000; s32 t0l = ((a0l )*acc)/48000;
s32 t0r = ((a0r )*acc)/48000; s32 t0r = ((a0r )*acc)/48000;
s32 t1l = ((t0l+a1l)*acc)/48000; s32 t1l = ((t0l+a1l)*acc)/48000;
s32 t1r = ((t0r+a1r)*acc)/48000; s32 t1r = ((t0r+a1r)*acc)/48000;
s32 t2l = ((t1l+a2l)*acc)/48000; s32 t2l = ((t1l+a2l)*acc)/48000;
s32 t2r = ((t1r+a2r)*acc)/48000; s32 t2r = ((t1r+a2r)*acc)/48000;
s32 t3l = ((t2l+a3l)); s32 t3l = ((t2l+a3l));
s32 t3r = ((t2r+a3r)); s32 t3r = ((t2r+a3r));
DataL = t3l; DataL = t3l;
DataR = t3r; DataR = t3r;
} }
int l = DataL, r = DataR; int l = DataL, r = DataR;
if (l < -32767) l = -32767; if (l < -32767) l = -32767;
if (r < -32767) r = -32767; if (r < -32767) r = -32767;
if (l > 32767) l = 32767; if (l > 32767) l = 32767;
if (r > 32767) r = 32767; if (r > 32767) r = 32767;
sample_queue.push(l); sample_queue.push(l);
sample_queue.push(r); sample_queue.push(r);
} }
push_sync.Leave(); push_sync.Leave();
} }

View File

@ -1,274 +1,274 @@
// RegSettings.cpp // RegSettings.cpp
// //
// Copyright (c) 2001 Magomed Abdurakhmanov // Copyright (c) 2001 Magomed Abdurakhmanov
// maq@hotbox.ru, http://mickels.iwt.ru/en // maq@hotbox.ru, http://mickels.iwt.ru/en
// //
// //
// //
// No warranties are given. Use at your own risk. // No warranties are given. Use at your own risk.
// //
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
#include "stdafx.h" #include "stdafx.h"
#include "RegSettings.h" #include "RegSettings.h"
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
// CWindowSettings // CWindowSettings
#define S_WINDOW_PLACEMENT_VAL _T("WindowPlacement") #define S_WINDOW_PLACEMENT_VAL _T("WindowPlacement")
CWindowSettings::CWindowSettings() CWindowSettings::CWindowSettings()
{ {
m_WindowPlacement.length = sizeof(m_WindowPlacement); m_WindowPlacement.length = sizeof(m_WindowPlacement);
m_WindowPlacement.flags = 0; m_WindowPlacement.flags = 0;
m_WindowPlacement.ptMinPosition.x = 0; m_WindowPlacement.ptMinPosition.x = 0;
m_WindowPlacement.ptMinPosition.y = 0; m_WindowPlacement.ptMinPosition.y = 0;
m_WindowPlacement.ptMaxPosition.x = 0; m_WindowPlacement.ptMaxPosition.x = 0;
m_WindowPlacement.ptMaxPosition.y = 0; m_WindowPlacement.ptMaxPosition.y = 0;
CRect rc; CRect rc;
SystemParametersInfo(SPI_GETWORKAREA, 0, rc, 0); SystemParametersInfo(SPI_GETWORKAREA, 0, rc, 0);
rc.DeflateRect(100, 100); rc.DeflateRect(100, 100);
m_WindowPlacement.rcNormalPosition = rc; m_WindowPlacement.rcNormalPosition = rc;
m_WindowPlacement.showCmd = SW_SHOWNORMAL; m_WindowPlacement.showCmd = SW_SHOWNORMAL;
} }
bool CWindowSettings::Load(LPCTSTR szRegKey, LPCTSTR szPrefix, HKEY hkRootKey /* = HKEY_CURRENT_USER*/) bool CWindowSettings::Load(LPCTSTR szRegKey, LPCTSTR szPrefix, HKEY hkRootKey /* = HKEY_CURRENT_USER*/)
{ {
CRegKey reg; CRegKey reg;
DWORD err = reg.Open(hkRootKey, szRegKey, KEY_READ); DWORD err = reg.Open(hkRootKey, szRegKey, KEY_READ);
if (err == ERROR_SUCCESS) if (err == ERROR_SUCCESS)
{ {
DWORD dwType = NULL; DWORD dwType = NULL;
DWORD dwSize = sizeof(m_WindowPlacement); DWORD dwSize = sizeof(m_WindowPlacement);
err = RegQueryValueEx(reg.m_hKey, CString(szPrefix) + S_WINDOW_PLACEMENT_VAL, NULL, &dwType, err = RegQueryValueEx(reg.m_hKey, CString(szPrefix) + S_WINDOW_PLACEMENT_VAL, NULL, &dwType,
(LPBYTE)&m_WindowPlacement, &dwSize); (LPBYTE)&m_WindowPlacement, &dwSize);
} }
return(err == ERROR_SUCCESS); return(err == ERROR_SUCCESS);
} }
bool CWindowSettings::Save(LPCTSTR szRegKey, LPCTSTR szPrefix, HKEY hkRootKey /* = HKEY_CURRENT_USER*/) const bool CWindowSettings::Save(LPCTSTR szRegKey, LPCTSTR szPrefix, HKEY hkRootKey /* = HKEY_CURRENT_USER*/) const
{ {
CRegKey reg; CRegKey reg;
DWORD err = reg.Create(hkRootKey, szRegKey); DWORD err = reg.Create(hkRootKey, szRegKey);
if (err == ERROR_SUCCESS) if (err == ERROR_SUCCESS)
{ {
err = RegSetValueEx(reg.m_hKey, CString(szPrefix) + S_WINDOW_PLACEMENT_VAL, NULL, REG_BINARY, err = RegSetValueEx(reg.m_hKey, CString(szPrefix) + S_WINDOW_PLACEMENT_VAL, NULL, REG_BINARY,
(LPBYTE)&m_WindowPlacement, sizeof(m_WindowPlacement)); (LPBYTE)&m_WindowPlacement, sizeof(m_WindowPlacement));
} }
return(err == ERROR_SUCCESS); return(err == ERROR_SUCCESS);
} }
void CWindowSettings::GetFrom(CWindow& Wnd) void CWindowSettings::GetFrom(CWindow& Wnd)
{ {
ATLASSERT(Wnd.IsWindow()); ATLASSERT(Wnd.IsWindow());
Wnd.GetWindowPlacement(&m_WindowPlacement); Wnd.GetWindowPlacement(&m_WindowPlacement);
} }
void CWindowSettings::ApplyTo(CWindow& Wnd, int nCmdShow /* = SW_SHOWNORMAL*/) const void CWindowSettings::ApplyTo(CWindow& Wnd, int nCmdShow /* = SW_SHOWNORMAL*/) const
{ {
ATLASSERT(Wnd.IsWindow()); ATLASSERT(Wnd.IsWindow());
Wnd.SetWindowPlacement(&m_WindowPlacement); Wnd.SetWindowPlacement(&m_WindowPlacement);
if (SW_SHOWNORMAL != nCmdShow) if (SW_SHOWNORMAL != nCmdShow)
{ {
Wnd.ShowWindow(nCmdShow); Wnd.ShowWindow(nCmdShow);
} }
else else
if (m_WindowPlacement.showCmd == SW_MINIMIZE || m_WindowPlacement.showCmd == SW_SHOWMINIMIZED) if (m_WindowPlacement.showCmd == SW_MINIMIZE || m_WindowPlacement.showCmd == SW_SHOWMINIMIZED)
{ {
Wnd.ShowWindow(SW_SHOWNORMAL); Wnd.ShowWindow(SW_SHOWNORMAL);
} }
} }
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
// CReBarSettings // CReBarSettings
#define S_BAR_BANDCOUNT _T("BandCount") #define S_BAR_BANDCOUNT _T("BandCount")
#define S_BAR_ID_VAL _T("ID") #define S_BAR_ID_VAL _T("ID")
#define S_BAR_CX_VAL _T("CX") #define S_BAR_CX_VAL _T("CX")
#define S_BAR_BREAKLINE_VAL _T("BreakLine") #define S_BAR_BREAKLINE_VAL _T("BreakLine")
CReBarSettings::CReBarSettings() CReBarSettings::CReBarSettings()
{ {
m_pBands = NULL; m_pBands = NULL;
m_cbBandCount = 0; m_cbBandCount = 0;
} }
CReBarSettings::~CReBarSettings() CReBarSettings::~CReBarSettings()
{ {
if (m_pBands != NULL) if (m_pBands != NULL)
{ {
delete[] m_pBands; delete[] m_pBands;
m_pBands = NULL; m_pBands = NULL;
} }
} }
bool CReBarSettings::Load(LPCTSTR szRegKey, LPCTSTR szPrefix, HKEY hkRootKey /* = HKEY_CURRENT_USER*/) bool CReBarSettings::Load(LPCTSTR szRegKey, LPCTSTR szPrefix, HKEY hkRootKey /* = HKEY_CURRENT_USER*/)
{ {
if (m_pBands != NULL) if (m_pBands != NULL)
{ {
delete[] m_pBands; delete[] m_pBands;
m_pBands = NULL; m_pBands = NULL;
} }
m_pBands = NULL; m_pBands = NULL;
m_cbBandCount = 0; m_cbBandCount = 0;
CRegKey reg; CRegKey reg;
DWORD err = reg.Open(hkRootKey, szRegKey, KEY_READ); DWORD err = reg.Open(hkRootKey, szRegKey, KEY_READ);
if (err == ERROR_SUCCESS) if (err == ERROR_SUCCESS)
{ {
reg.QueryDWORDValue(CString(szPrefix) + S_BAR_BANDCOUNT, m_cbBandCount); reg.QueryDWORDValue(CString(szPrefix) + S_BAR_BANDCOUNT, m_cbBandCount);
if (m_cbBandCount > 0) if (m_cbBandCount > 0)
{ {
m_pBands = new BandInfo[m_cbBandCount]; m_pBands = new BandInfo[m_cbBandCount];
} }
for (DWORD i = 0; i < m_cbBandCount; i++) for (DWORD i = 0; i < m_cbBandCount; i++)
{ {
CString s; CString s;
s.Format(_T("%s%i_"), szPrefix, i); s.Format(_T("%s%i_"), szPrefix, i);
reg.QueryDWORDValue(s + S_BAR_ID_VAL, m_pBands[i].ID); reg.QueryDWORDValue(s + S_BAR_ID_VAL, m_pBands[i].ID);
reg.QueryDWORDValue(s + S_BAR_CX_VAL, m_pBands[i].cx); reg.QueryDWORDValue(s + S_BAR_CX_VAL, m_pBands[i].cx);
DWORD dw; DWORD dw;
reg.QueryDWORDValue(s + S_BAR_BREAKLINE_VAL, dw); reg.QueryDWORDValue(s + S_BAR_BREAKLINE_VAL, dw);
m_pBands[i].BreakLine = dw != 0; m_pBands[i].BreakLine = dw != 0;
} }
} }
return(err == ERROR_SUCCESS); return(err == ERROR_SUCCESS);
} }
bool CReBarSettings::Save(LPCTSTR szRegKey, LPCTSTR szPrefix, HKEY hkRootKey /* = HKEY_CURRENT_USER*/) const bool CReBarSettings::Save(LPCTSTR szRegKey, LPCTSTR szPrefix, HKEY hkRootKey /* = HKEY_CURRENT_USER*/) const
{ {
CRegKey reg; CRegKey reg;
DWORD err = reg.Create(hkRootKey, szRegKey); DWORD err = reg.Create(hkRootKey, szRegKey);
if (err == ERROR_SUCCESS) if (err == ERROR_SUCCESS)
{ {
reg.SetDWORDValue(CString(szPrefix) + S_BAR_BANDCOUNT, m_cbBandCount); reg.SetDWORDValue(CString(szPrefix) + S_BAR_BANDCOUNT, m_cbBandCount);
for (DWORD i = 0; i < m_cbBandCount; i++) for (DWORD i = 0; i < m_cbBandCount; i++)
{ {
CString s; CString s;
s.Format(_T("%s%i_"), szPrefix, i); s.Format(_T("%s%i_"), szPrefix, i);
reg.SetDWORDValue(s + S_BAR_ID_VAL, m_pBands[i].ID); reg.SetDWORDValue(s + S_BAR_ID_VAL, m_pBands[i].ID);
reg.SetDWORDValue(s + S_BAR_CX_VAL, m_pBands[i].cx); reg.SetDWORDValue(s + S_BAR_CX_VAL, m_pBands[i].cx);
DWORD dw = m_pBands[i].BreakLine; DWORD dw = m_pBands[i].BreakLine;
reg.SetDWORDValue(s + S_BAR_BREAKLINE_VAL, dw); reg.SetDWORDValue(s + S_BAR_BREAKLINE_VAL, dw);
} }
} }
return(err == ERROR_SUCCESS); return(err == ERROR_SUCCESS);
} }
void CReBarSettings::GetFrom(CReBarCtrl& ReBar) void CReBarSettings::GetFrom(CReBarCtrl& ReBar)
{ {
ATLASSERT(ReBar.IsWindow()); ATLASSERT(ReBar.IsWindow());
if (m_pBands != NULL) if (m_pBands != NULL)
{ {
delete[] m_pBands; delete[] m_pBands;
} }
m_pBands = NULL; m_pBands = NULL;
m_cbBandCount = ReBar.GetBandCount(); m_cbBandCount = ReBar.GetBandCount();
if (m_cbBandCount > 0) if (m_cbBandCount > 0)
{ {
m_pBands = new BandInfo[m_cbBandCount]; m_pBands = new BandInfo[m_cbBandCount];
} }
for (UINT i = 0; i < m_cbBandCount; i++) for (UINT i = 0; i < m_cbBandCount; i++)
{ {
REBARBANDINFO rbi; REBARBANDINFO rbi;
rbi.cbSize = sizeof(rbi); rbi.cbSize = sizeof(rbi);
rbi.fMask = RBBIM_ID | RBBIM_SIZE | RBBIM_STYLE; rbi.fMask = RBBIM_ID | RBBIM_SIZE | RBBIM_STYLE;
ReBar.GetBandInfo(i, &rbi); ReBar.GetBandInfo(i, &rbi);
m_pBands[i].ID = rbi.wID; m_pBands[i].ID = rbi.wID;
m_pBands[i].cx = rbi.cx; m_pBands[i].cx = rbi.cx;
m_pBands[i].BreakLine = (rbi.fStyle & RBBS_BREAK) != 0; m_pBands[i].BreakLine = (rbi.fStyle & RBBS_BREAK) != 0;
} }
} }
void CReBarSettings::ApplyTo(CReBarCtrl& ReBar) const void CReBarSettings::ApplyTo(CReBarCtrl& ReBar) const
{ {
ATLASSERT(ReBar.IsWindow()); ATLASSERT(ReBar.IsWindow());
for (UINT i = 0; i < m_cbBandCount; i++) for (UINT i = 0; i < m_cbBandCount; i++)
{ {
ReBar.MoveBand(ReBar.IdToIndex(m_pBands[i].ID), i); ReBar.MoveBand(ReBar.IdToIndex(m_pBands[i].ID), i);
REBARBANDINFO rbi; REBARBANDINFO rbi;
rbi.cbSize = sizeof(rbi); rbi.cbSize = sizeof(rbi);
rbi.fMask = RBBIM_ID | RBBIM_SIZE | RBBIM_STYLE; rbi.fMask = RBBIM_ID | RBBIM_SIZE | RBBIM_STYLE;
ReBar.GetBandInfo(i, &rbi); ReBar.GetBandInfo(i, &rbi);
rbi.cx = m_pBands[i].cx; rbi.cx = m_pBands[i].cx;
if (m_pBands[i].BreakLine) if (m_pBands[i].BreakLine)
{ {
rbi.fStyle |= RBBS_BREAK; rbi.fStyle |= RBBS_BREAK;
} }
else else
{ {
rbi.fStyle &= (~RBBS_BREAK); rbi.fStyle &= (~RBBS_BREAK);
} }
ReBar.SetBandInfo(i, &rbi); ReBar.SetBandInfo(i, &rbi);
} }
} }
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
// CSplitterSettings // CSplitterSettings
#define S_SPLITTER_POS _T("SplitterPos") #define S_SPLITTER_POS _T("SplitterPos")
bool CSplitterSettings::Load(LPCTSTR szRegKey, LPCTSTR szPrefix, HKEY hkRootKey /* = HKEY_CURRENT_USER*/) bool CSplitterSettings::Load(LPCTSTR szRegKey, LPCTSTR szPrefix, HKEY hkRootKey /* = HKEY_CURRENT_USER*/)
{ {
CRegKey reg; CRegKey reg;
DWORD err = reg.Open(hkRootKey, szRegKey, KEY_READ); DWORD err = reg.Open(hkRootKey, szRegKey, KEY_READ);
if (err == ERROR_SUCCESS) if (err == ERROR_SUCCESS)
{ {
reg.QueryDWORDValue(CString(szPrefix) + S_SPLITTER_POS, m_dwPos); reg.QueryDWORDValue(CString(szPrefix) + S_SPLITTER_POS, m_dwPos);
} }
return(err == ERROR_SUCCESS); return(err == ERROR_SUCCESS);
} }
bool CSplitterSettings::Save(LPCTSTR szRegKey, LPCTSTR szPrefix, HKEY hkRootKey /* = HKEY_CURRENT_USER*/) const bool CSplitterSettings::Save(LPCTSTR szRegKey, LPCTSTR szPrefix, HKEY hkRootKey /* = HKEY_CURRENT_USER*/) const
{ {
CRegKey reg; CRegKey reg;
DWORD err = reg.Create(hkRootKey, szRegKey); DWORD err = reg.Create(hkRootKey, szRegKey);
if (err == ERROR_SUCCESS) if (err == ERROR_SUCCESS)
{ {
reg.SetDWORDValue(CString(szPrefix) + S_SPLITTER_POS, m_dwPos); reg.SetDWORDValue(CString(szPrefix) + S_SPLITTER_POS, m_dwPos);
} }
return(err == ERROR_SUCCESS); return(err == ERROR_SUCCESS);
} }

View File

@ -1,207 +1,207 @@
// 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 "../res/resource.h" #include "../res/resource.h"
#include "RegisterDlg.h" #include "RegisterDlg.h"
#include "disassemble.h" #include "disassemble.h"
#include "gdsp_interpreter.h" #include "gdsp_interpreter.h"
#include "RegSettings.h" #include "RegSettings.h"
CRegisterDlg::CRegisterDlg() CRegisterDlg::CRegisterDlg()
: m_CachedCounter(-1) : m_CachedCounter(-1)
{} {}
BOOL CRegisterDlg::PreTranslateMessage(MSG* pMsg) BOOL CRegisterDlg::PreTranslateMessage(MSG* pMsg)
{ {
return(IsDialogMessage(pMsg)); return(IsDialogMessage(pMsg));
} }
BOOL CRegisterDlg::OnIdle() BOOL CRegisterDlg::OnIdle()
{ {
return(FALSE); return(FALSE);
} }
LRESULT CRegisterDlg::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) LRESULT CRegisterDlg::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{ {
CWindowSettings ws; CWindowSettings ws;
if (ws.Load("Software\\Dolphin\\DSP", "Register")) if (ws.Load("Software\\Dolphin\\DSP", "Register"))
{ {
ws.ApplyTo(CWindow(m_hWnd), SW_SHOW); ws.ApplyTo(CWindow(m_hWnd), SW_SHOW);
} }
m_RegisterListViewCtrl.m_hWnd = GetDlgItem(IDC_DISASM_LIST); m_RegisterListViewCtrl.m_hWnd = GetDlgItem(IDC_DISASM_LIST);
UIAddChildWindowContainer(m_hWnd); UIAddChildWindowContainer(m_hWnd);
m_RegisterListViewCtrl.AddColumn(_T("General"), 0); m_RegisterListViewCtrl.AddColumn(_T("General"), 0);
m_RegisterListViewCtrl.AddColumn(_T(" "), 1); m_RegisterListViewCtrl.AddColumn(_T(" "), 1);
m_RegisterListViewCtrl.AddColumn(_T("Special"), 2); m_RegisterListViewCtrl.AddColumn(_T("Special"), 2);
m_RegisterListViewCtrl.AddColumn(_T("0"), 3); m_RegisterListViewCtrl.AddColumn(_T("0"), 3);
m_RegisterListViewCtrl.SetColumnWidth(0, 50); m_RegisterListViewCtrl.SetColumnWidth(0, 50);
m_RegisterListViewCtrl.SetColumnWidth(1, 100); m_RegisterListViewCtrl.SetColumnWidth(1, 100);
m_RegisterListViewCtrl.SetColumnWidth(2, 60); m_RegisterListViewCtrl.SetColumnWidth(2, 60);
m_RegisterListViewCtrl.SetColumnWidth(3, 100); m_RegisterListViewCtrl.SetColumnWidth(3, 100);
m_RegisterListViewCtrl.SetExtendedListViewStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES); m_RegisterListViewCtrl.SetExtendedListViewStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);
m_RegisterListViewCtrl.SetTextBkColor(GetSysColor(COLOR_3DLIGHT)); m_RegisterListViewCtrl.SetTextBkColor(GetSysColor(COLOR_3DLIGHT));
for (uint16 i = 0; i < 16; i++) for (uint16 i = 0; i < 16; i++)
{ {
// 0-15 // 0-15
int Item = m_RegisterListViewCtrl.AddItem(0, 0, gd_dis_get_reg_name(i)); int Item = m_RegisterListViewCtrl.AddItem(0, 0, gd_dis_get_reg_name(i));
// 16-31 // 16-31
m_RegisterListViewCtrl.AddItem(Item, 2, gd_dis_get_reg_name(16 + i)); m_RegisterListViewCtrl.AddItem(Item, 2, gd_dis_get_reg_name(16 + i));
// just for easy sort // just for easy sort
m_RegisterListViewCtrl.SetItemData(Item, i); m_RegisterListViewCtrl.SetItemData(Item, i);
} }
m_RegisterListViewCtrl.SortItems(CompareFunc, (LPARAM) this); m_RegisterListViewCtrl.SortItems(CompareFunc, (LPARAM) this);
UpdateRegisterListView(); UpdateRegisterListView();
return(TRUE); return(TRUE);
} }
LRESULT CRegisterDlg::OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) LRESULT CRegisterDlg::OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{ {
CWindowSettings ws; CWindowSettings ws;
ws.GetFrom(CWindow(m_hWnd)); ws.GetFrom(CWindow(m_hWnd));
ws.Save("Software\\Dolphin\\DSP", "Register"); ws.Save("Software\\Dolphin\\DSP", "Register");
return(0); return(0);
} }
void CRegisterDlg::UpdateRegisterListView() void CRegisterDlg::UpdateRegisterListView()
{ {
if (m_CachedCounter == g_dsp.step_counter) if (m_CachedCounter == g_dsp.step_counter)
{ {
return; return;
} }
m_CachedCounter = g_dsp.step_counter; m_CachedCounter = g_dsp.step_counter;
char Temp[256]; char Temp[256];
for (uint16 i = 0; i < 16; i++) for (uint16 i = 0; i < 16; i++)
{ {
// 0-15 // 0-15
if (m_CachedRegs[i] != g_dsp.r[i]) if (m_CachedRegs[i] != g_dsp.r[i])
{ {
m_CachedRegHasChanged[i] = true; m_CachedRegHasChanged[i] = true;
} }
else else
{ {
m_CachedRegHasChanged[i] = false; m_CachedRegHasChanged[i] = false;
} }
m_CachedRegs[i] = g_dsp.r[i]; m_CachedRegs[i] = g_dsp.r[i];
sprintf_s(Temp, 256, "0x%04x", g_dsp.r[i]); sprintf_s(Temp, 256, "0x%04x", g_dsp.r[i]);
m_RegisterListViewCtrl.SetItemText(i, 1, Temp); m_RegisterListViewCtrl.SetItemText(i, 1, Temp);
// 16-31 // 16-31
if (m_CachedRegs[16 + i] != g_dsp.r[16 + i]) if (m_CachedRegs[16 + i] != g_dsp.r[16 + i])
{ {
m_CachedRegHasChanged[16 + i] = true; m_CachedRegHasChanged[16 + i] = true;
} }
else else
{ {
m_CachedRegHasChanged[16 + i] = false; m_CachedRegHasChanged[16 + i] = false;
} }
m_CachedRegs[16 + i] = g_dsp.r[16 + i]; m_CachedRegs[16 + i] = g_dsp.r[16 + i];
sprintf_s(Temp, 256, "0x%04x", g_dsp.r[16 + i]); sprintf_s(Temp, 256, "0x%04x", g_dsp.r[16 + i]);
m_RegisterListViewCtrl.SetItemText(i, 3, Temp); m_RegisterListViewCtrl.SetItemText(i, 3, Temp);
} }
} }
int CALLBACK CRegisterDlg::CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) int CALLBACK CRegisterDlg::CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{ {
return(lParam1 > lParam2); return(lParam1 > lParam2);
} }
LRESULT CRegisterDlg::OnCustomDraw(int /*idCtrl*/, LPNMHDR pnmh, BOOL& _bHandled) LRESULT CRegisterDlg::OnCustomDraw(int /*idCtrl*/, LPNMHDR pnmh, BOOL& _bHandled)
{ {
int result = CDRF_DODEFAULT; int result = CDRF_DODEFAULT;
NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>(pnmh); NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>(pnmh);
switch (pLVCD->nmcd.dwDrawStage) switch (pLVCD->nmcd.dwDrawStage)
{ {
case CDDS_PREPAINT: case CDDS_PREPAINT:
result = CDRF_NOTIFYITEMDRAW; result = CDRF_NOTIFYITEMDRAW;
break; break;
case CDDS_ITEMPREPAINT: case CDDS_ITEMPREPAINT:
result = CDRF_NOTIFYSUBITEMDRAW; result = CDRF_NOTIFYSUBITEMDRAW;
break; break;
case (CDDS_ITEMPREPAINT | CDDS_SUBITEM): case (CDDS_ITEMPREPAINT | CDDS_SUBITEM):
{ {
pLVCD->nmcd.uItemState &= ~(CDIS_SELECTED | CDIS_FOCUS); pLVCD->nmcd.uItemState &= ~(CDIS_SELECTED | CDIS_FOCUS);
int Offset = static_cast<int>(m_RegisterListViewCtrl.GetItemData((int)pLVCD->nmcd.dwItemSpec)); int Offset = static_cast<int>(m_RegisterListViewCtrl.GetItemData((int)pLVCD->nmcd.dwItemSpec));
size_t Register = -1; size_t Register = -1;
if (pLVCD->iSubItem == 1) if (pLVCD->iSubItem == 1)
{ {
Register = Offset; Register = Offset;
} }
else if (pLVCD->iSubItem == 3) else if (pLVCD->iSubItem == 3)
{ {
Register = Offset + 16; Register = Offset + 16;
} }
if (Register != -1) if (Register != -1)
{ {
if (m_CachedRegHasChanged[Register]) if (m_CachedRegHasChanged[Register])
{ {
pLVCD->clrTextBk = RGB(0xFF, 192, 192); pLVCD->clrTextBk = RGB(0xFF, 192, 192);
} }
else else
{ {
pLVCD->clrTextBk = RGB(0xF0, 0xF0, 0xF0); pLVCD->clrTextBk = RGB(0xF0, 0xF0, 0xF0);
} }
} }
else else
{ {
pLVCD->clrTextBk = RGB(192, 224, 192); pLVCD->clrTextBk = RGB(192, 224, 192);
} }
// uint16 CurrentAddress = static_cast<uint16>(m_DisAsmListViewCtrl.GetItemData((int)pLVCD->nmcd.dwItemSpec)); // uint16 CurrentAddress = static_cast<uint16>(m_DisAsmListViewCtrl.GetItemData((int)pLVCD->nmcd.dwItemSpec));
} }
break; break;
} }
return(result); return(result);
} }

View File

@ -1,93 +1,93 @@
// 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 <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include "Common.h" #include "Common.h"
#include "Globals.h" #include "Globals.h"
#include "gdsp_interpreter.h" #include "gdsp_interpreter.h"
bool DumpDSPCode(uint32 _Address, uint32 _Length, uint32 crc) bool DumpDSPCode(uint32 _Address, uint32 _Length, uint32 crc)
{ {
char szFilename[MAX_PATH]; char szFilename[MAX_PATH];
sprintf(szFilename, "c:\\_\\DSP_UC_%08X.bin", crc); sprintf(szFilename, "c:\\_\\DSP_UC_%08X.bin", crc);
FILE* pFile = fopen(szFilename, "wb"); FILE* pFile = fopen(szFilename, "wb");
if (pFile != NULL) if (pFile != NULL)
{ {
fwrite(g_dspInitialize.pGetMemoryPointer(_Address), _Length, 1, pFile); fwrite(g_dspInitialize.pGetMemoryPointer(_Address), _Length, 1, pFile);
fclose(pFile); fclose(pFile);
return(true); return(true);
} }
else else
{ {
PanicAlert("Cant open file (%s) to dump UCode!!", szFilename); PanicAlert("Cant open file (%s) to dump UCode!!", szFilename);
} }
return(false); return(false);
} }
uint32 GenerateCRC(const unsigned char* _pBuffer, int _pLength) uint32 GenerateCRC(const unsigned char* _pBuffer, int _pLength)
{ {
unsigned long CRC = 0xFFFFFFFF; unsigned long CRC = 0xFFFFFFFF;
while (_pLength--) while (_pLength--)
{ {
unsigned long Temp = (unsigned long)((CRC & 0xFF) ^ *_pBuffer++); unsigned long Temp = (unsigned long)((CRC & 0xFF) ^ *_pBuffer++);
for (int j = 0; j < 8; j++) for (int j = 0; j < 8; j++)
{ {
if (Temp & 0x1) if (Temp & 0x1)
{ {
Temp = (Temp >> 1) ^ 0xEDB88320; Temp = (Temp >> 1) ^ 0xEDB88320;
} }
else else
{ {
Temp >>= 1; Temp >>= 1;
} }
} }
CRC = (CRC >> 8) ^ Temp; CRC = (CRC >> 8) ^ Temp;
} }
return(CRC ^ 0xFFFFFFFF); return(CRC ^ 0xFFFFFFFF);
} }
bool DumpCWCode(uint32 _Address, uint32 _Length) bool DumpCWCode(uint32 _Address, uint32 _Length)
{ {
FILE* pFile = fopen("d:\\DSP_UCode.bin", "wb"); FILE* pFile = fopen("d:\\DSP_UCode.bin", "wb");
if (pFile != NULL) if (pFile != NULL)
{ {
for (size_t i = _Address; i < _Address + _Length; i++) for (size_t i = _Address; i < _Address + _Length; i++)
{ {
uint16 val = Common::swap16(g_dsp.iram[i]); uint16 val = Common::swap16(g_dsp.iram[i]);
fprintf(pFile, " cw 0x%04x \n", val); fprintf(pFile, " cw 0x%04x \n", val);
} }
fclose(pFile); fclose(pFile);
return(true); return(true);
} }
return(false); return(false);
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,113 +1,113 @@
// 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 "gdsp_interface.h" #include "gdsp_interface.h"
extern uint16 dsp_swap16(uint16 x); extern uint16 dsp_swap16(uint16 x);
// The hardware adpcm decoder :) // The hardware adpcm decoder :)
sint16 ADPCM_Step(uint32& _rSamplePos, uint32 _BaseAddress) sint16 ADPCM_Step(uint32& _rSamplePos, uint32 _BaseAddress)
{ {
sint16* pCoefTable = (sint16*)&gdsp_ifx_regs[DSP_COEF_A1_0]; sint16* pCoefTable = (sint16*)&gdsp_ifx_regs[DSP_COEF_A1_0];
if (((_rSamplePos) & 15) == 0) if (((_rSamplePos) & 15) == 0)
{ {
gdsp_ifx_regs[DSP_PRED_SCALE] = g_dspInitialize.pARAM_Read_U8((_rSamplePos & ~15) >> 1); gdsp_ifx_regs[DSP_PRED_SCALE] = g_dspInitialize.pARAM_Read_U8((_rSamplePos & ~15) >> 1);
_rSamplePos += 2; _rSamplePos += 2;
} }
int scale = 1 << (gdsp_ifx_regs[DSP_PRED_SCALE] & 0xF); int scale = 1 << (gdsp_ifx_regs[DSP_PRED_SCALE] & 0xF);
int coef_idx = gdsp_ifx_regs[DSP_PRED_SCALE] >> 4; int coef_idx = gdsp_ifx_regs[DSP_PRED_SCALE] >> 4;
sint32 coef1 = pCoefTable[coef_idx * 2 + 0]; sint32 coef1 = pCoefTable[coef_idx * 2 + 0];
sint32 coef2 = pCoefTable[coef_idx * 2 + 1]; sint32 coef2 = pCoefTable[coef_idx * 2 + 1];
int temp = (_rSamplePos & 1) ? int temp = (_rSamplePos & 1) ?
(g_dspInitialize.pARAM_Read_U8(_rSamplePos >> 1) & 0xF) : (g_dspInitialize.pARAM_Read_U8(_rSamplePos >> 1) & 0xF) :
(g_dspInitialize.pARAM_Read_U8(_rSamplePos >> 1) >> 4); (g_dspInitialize.pARAM_Read_U8(_rSamplePos >> 1) >> 4);
if (temp >= 8) if (temp >= 8)
temp -= 16; temp -= 16;
// 0x400 = 0.5 in 11-bit fixed point // 0x400 = 0.5 in 11-bit fixed point
int val = (scale * temp) + ((0x400 + coef1 * (sint16)gdsp_ifx_regs[DSP_YN1] + coef2 * (sint16)gdsp_ifx_regs[DSP_YN2]) >> 11); int val = (scale * temp) + ((0x400 + coef1 * (sint16)gdsp_ifx_regs[DSP_YN1] + coef2 * (sint16)gdsp_ifx_regs[DSP_YN2]) >> 11);
// Clamp values. // Clamp values.
if (val > 0x7FFF) if (val > 0x7FFF)
val = 0x7FFF; val = 0x7FFF;
else if (val < -0x7FFF) else if (val < -0x7FFF)
val = -0x7FFF; val = -0x7FFF;
gdsp_ifx_regs[DSP_YN2] = gdsp_ifx_regs[DSP_YN1]; gdsp_ifx_regs[DSP_YN2] = gdsp_ifx_regs[DSP_YN1];
gdsp_ifx_regs[DSP_YN1] = val; gdsp_ifx_regs[DSP_YN1] = val;
_rSamplePos++; _rSamplePos++;
// The advanced interpolation (linear, polyphase,...) is done by the UCode, so we don't // The advanced interpolation (linear, polyphase,...) is done by the UCode, so we don't
// need to bother with it here. // need to bother with it here.
return val; return val;
} }
extern void gdsp_generate_exception(uint8 level); extern void gdsp_generate_exception(uint8 level);
uint16 dsp_read_aram() uint16 dsp_read_aram()
{ {
// uint32 BaseAddress = (gdsp_ifx_regs[DSP_ACSAH] << 16) | gdsp_ifx_regs[DSP_ACSAL]; // uint32 BaseAddress = (gdsp_ifx_regs[DSP_ACSAH] << 16) | gdsp_ifx_regs[DSP_ACSAL];
uint32 EndAddress = (gdsp_ifx_regs[DSP_ACEAH] << 16) | gdsp_ifx_regs[DSP_ACEAL]; uint32 EndAddress = (gdsp_ifx_regs[DSP_ACEAH] << 16) | gdsp_ifx_regs[DSP_ACEAL];
uint32 Address = (gdsp_ifx_regs[DSP_ACCAH] << 16) | gdsp_ifx_regs[DSP_ACCAL]; uint32 Address = (gdsp_ifx_regs[DSP_ACCAH] << 16) | gdsp_ifx_regs[DSP_ACCAL];
uint16 val; uint16 val;
// lets the "hardware" decode // lets the "hardware" decode
switch (gdsp_ifx_regs[DSP_FORMAT]) switch (gdsp_ifx_regs[DSP_FORMAT])
{ {
case 0x00: case 0x00:
val = ADPCM_Step(Address, EndAddress); val = ADPCM_Step(Address, EndAddress);
break; break;
case 0x0A: case 0x0A:
val = (g_dspInitialize.pARAM_Read_U8(Address) << 8) | g_dspInitialize.pARAM_Read_U8(Address + 1); val = (g_dspInitialize.pARAM_Read_U8(Address) << 8) | g_dspInitialize.pARAM_Read_U8(Address + 1);
gdsp_ifx_regs[DSP_YN2] = gdsp_ifx_regs[DSP_YN1]; gdsp_ifx_regs[DSP_YN2] = gdsp_ifx_regs[DSP_YN1];
gdsp_ifx_regs[DSP_YN1] = val; gdsp_ifx_regs[DSP_YN1] = val;
Address += 2; Address += 2;
break; break;
default: default:
val = (g_dspInitialize.pARAM_Read_U8(Address) << 8) | g_dspInitialize.pARAM_Read_U8(Address + 1); val = (g_dspInitialize.pARAM_Read_U8(Address) << 8) | g_dspInitialize.pARAM_Read_U8(Address + 1);
Address += 2; Address += 2;
ErrorLog("Unknown DSP Format %i", gdsp_ifx_regs[DSP_FORMAT]); ErrorLog("Unknown DSP Format %i", gdsp_ifx_regs[DSP_FORMAT]);
break; break;
} }
// check for loop // check for loop
if (Address > EndAddress) if (Address > EndAddress)
{ {
Address = (gdsp_ifx_regs[DSP_ACSAH] << 16) | gdsp_ifx_regs[DSP_ACSAL]; Address = (gdsp_ifx_regs[DSP_ACSAH] << 16) | gdsp_ifx_regs[DSP_ACSAL];
gdsp_generate_exception(3); gdsp_generate_exception(3);
gdsp_generate_exception(5); gdsp_generate_exception(5);
// Somehow, YN1 and YN2 must be initialized with their "loop" values, so yeah, // Somehow, YN1 and YN2 must be initialized with their "loop" values, so yeah,
// it seems likely that we should raise an exception to let the DSP program do that, // it seems likely that we should raise an exception to let the DSP program do that,
// at least if DSP_FORMAT == 0x0A. // at least if DSP_FORMAT == 0x0A.
} }
gdsp_ifx_regs[DSP_ACCAH] = Address >> 16; gdsp_ifx_regs[DSP_ACCAH] = Address >> 16;
gdsp_ifx_regs[DSP_ACCAL] = Address & 0xffff; gdsp_ifx_regs[DSP_ACCAL] = Address & 0xffff;
return(val); return(val);
} }

View File

@ -1,284 +1,284 @@
/*==================================================================== /*====================================================================
filename: opcodes.h filename: opcodes.h
project: GameCube DSP Tool (gcdsp) project: GameCube DSP Tool (gcdsp)
created: 2005.03.04 created: 2005.03.04
mail: duddie@walla.com mail: duddie@walla.com
Copyright (c) 2005 Duddie Copyright (c) 2005 Duddie
This program is free software; you can redistribute it and/or This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2 as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version. of the License, or (at your option) any later version.
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 for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
====================================================================*/ ====================================================================*/
// //
// //
// At the moment just ls and sl are using the prolog // At the moment just ls and sl are using the prolog
// perhaps all actions on r03 must be in the prolog // perhaps all actions on r03 must be in the prolog
// //
#include "Globals.h" #include "Globals.h"
#include "gdsp_opcodes_helper.h" #include "gdsp_opcodes_helper.h"
// //
void dsp_op_ext_r_epi(uint16 _Opcode) void dsp_op_ext_r_epi(uint16 _Opcode)
{ {
uint8 op = (_Opcode >> 2) & 0x3; uint8 op = (_Opcode >> 2) & 0x3;
uint8 reg = _Opcode & 0x3; uint8 reg = _Opcode & 0x3;
switch (op) switch (op)
{ {
case 0x00: case 0x00:
ErrorLog("dsp_op_ext_r_epi"); ErrorLog("dsp_op_ext_r_epi");
break; break;
case 0x01: case 0x01:
g_dsp.r[reg]--; g_dsp.r[reg]--;
break; break;
case 0x02: case 0x02:
g_dsp.r[reg]++; g_dsp.r[reg]++;
break; break;
case 0x03: case 0x03:
g_dsp.r[reg] += g_dsp.r[reg + 4]; g_dsp.r[reg] += g_dsp.r[reg + 4];
break; break;
} }
} }
void dsp_op_ext_mv(uint16 _Opcode) void dsp_op_ext_mv(uint16 _Opcode)
{ {
uint8 sreg = _Opcode & 0x3; uint8 sreg = _Opcode & 0x3;
uint8 dreg = ((_Opcode >> 2) & 0x3); uint8 dreg = ((_Opcode >> 2) & 0x3);
g_dsp.r[dreg + 0x18] = g_dsp.r[sreg + 0x1c]; g_dsp.r[dreg + 0x18] = g_dsp.r[sreg + 0x1c];
} }
void dsp_op_ext_s(uint16 _Opcode) void dsp_op_ext_s(uint16 _Opcode)
{ {
uint8 dreg = _Opcode & 0x3; uint8 dreg = _Opcode & 0x3;
uint8 sreg = ((_Opcode >> 3) & 0x3) + 0x1c; uint8 sreg = ((_Opcode >> 3) & 0x3) + 0x1c;
dsp_dmem_write(g_dsp.r[dreg], g_dsp.r[sreg]); dsp_dmem_write(g_dsp.r[dreg], g_dsp.r[sreg]);
if (_Opcode & 0x04) if (_Opcode & 0x04)
{ {
g_dsp.r[dreg] += g_dsp.r[dreg + 4]; g_dsp.r[dreg] += g_dsp.r[dreg + 4];
} }
else else
{ {
g_dsp.r[dreg]++; g_dsp.r[dreg]++;
} }
} }
void dsp_op_ext_l(uint16 _Opcode) void dsp_op_ext_l(uint16 _Opcode)
{ {
uint8 sreg = _Opcode & 0x3; uint8 sreg = _Opcode & 0x3;
uint8 dreg = ((_Opcode >> 3) & 0x7) + 0x18; uint8 dreg = ((_Opcode >> 3) & 0x7) + 0x18;
uint16 val = dsp_dmem_read(g_dsp.r[sreg]); uint16 val = dsp_dmem_read(g_dsp.r[sreg]);
g_dsp.r[dreg] = val; g_dsp.r[dreg] = val;
if (_Opcode & 0x04) if (_Opcode & 0x04)
{ {
g_dsp.r[sreg] += g_dsp.r[sreg + 4]; g_dsp.r[sreg] += g_dsp.r[sreg + 4];
} }
else else
{ {
g_dsp.r[sreg]++; g_dsp.r[sreg]++;
} }
} }
void dsp_op_ext_ls_pro(uint16 _Opcode) void dsp_op_ext_ls_pro(uint16 _Opcode)
{ {
uint8 areg = (_Opcode & 0x1) + 0x1e; uint8 areg = (_Opcode & 0x1) + 0x1e;
dsp_dmem_write(g_dsp.r[0x03], g_dsp.r[areg]); dsp_dmem_write(g_dsp.r[0x03], g_dsp.r[areg]);
if (_Opcode & 0x8) if (_Opcode & 0x8)
{ {
g_dsp.r[0x03] += g_dsp.r[0x07]; g_dsp.r[0x03] += g_dsp.r[0x07];
} }
else else
{ {
g_dsp.r[0x03]++; g_dsp.r[0x03]++;
} }
} }
void dsp_op_ext_ls_epi(uint16 _Opcode) void dsp_op_ext_ls_epi(uint16 _Opcode)
{ {
uint8 dreg = ((_Opcode >> 4) & 0x3) + 0x18; uint8 dreg = ((_Opcode >> 4) & 0x3) + 0x18;
uint16 val = dsp_dmem_read(g_dsp.r[0x00]); uint16 val = dsp_dmem_read(g_dsp.r[0x00]);
dsp_op_write_reg(dreg, val); dsp_op_write_reg(dreg, val);
if (_Opcode & 0x4) if (_Opcode & 0x4)
{ {
g_dsp.r[0x00] += g_dsp.r[0x04]; g_dsp.r[0x00] += g_dsp.r[0x04];
} }
else else
{ {
g_dsp.r[0x00]++; g_dsp.r[0x00]++;
} }
} }
void dsp_op_ext_sl_pro(uint16 _Opcode) void dsp_op_ext_sl_pro(uint16 _Opcode)
{ {
uint8 areg = (_Opcode & 0x1) + 0x1e; uint8 areg = (_Opcode & 0x1) + 0x1e;
dsp_dmem_write(g_dsp.r[0x00], g_dsp.r[areg]); dsp_dmem_write(g_dsp.r[0x00], g_dsp.r[areg]);
if (_Opcode & 0x4) if (_Opcode & 0x4)
{ {
g_dsp.r[0x00] += g_dsp.r[0x04]; g_dsp.r[0x00] += g_dsp.r[0x04];
} }
else else
{ {
g_dsp.r[0x00]++; g_dsp.r[0x00]++;
} }
} }
void dsp_op_ext_sl_epi(uint16 _Opcode) void dsp_op_ext_sl_epi(uint16 _Opcode)
{ {
uint8 dreg = ((_Opcode >> 4) & 0x3) + 0x18; uint8 dreg = ((_Opcode >> 4) & 0x3) + 0x18;
uint16 val = dsp_dmem_read(g_dsp.r[0x03]); uint16 val = dsp_dmem_read(g_dsp.r[0x03]);
dsp_op_write_reg(dreg, val); dsp_op_write_reg(dreg, val);
if (_Opcode & 0x8) if (_Opcode & 0x8)
{ {
g_dsp.r[0x03] += g_dsp.r[0x07]; g_dsp.r[0x03] += g_dsp.r[0x07];
} }
else else
{ {
g_dsp.r[0x03]++; g_dsp.r[0x03]++;
} }
} }
void dsp_op_ext_ld(uint16 _Opcode) void dsp_op_ext_ld(uint16 _Opcode)
{ {
uint8 dreg1 = (((_Opcode >> 5) & 0x1) << 1) + 0x18; uint8 dreg1 = (((_Opcode >> 5) & 0x1) << 1) + 0x18;
uint8 dreg2 = (((_Opcode >> 4) & 0x1) << 1) + 0x19; uint8 dreg2 = (((_Opcode >> 4) & 0x1) << 1) + 0x19;
uint8 sreg = _Opcode & 0x3; uint8 sreg = _Opcode & 0x3;
g_dsp.r[dreg1] = dsp_dmem_read(g_dsp.r[sreg]); g_dsp.r[dreg1] = dsp_dmem_read(g_dsp.r[sreg]);
g_dsp.r[dreg2] = dsp_dmem_read(g_dsp.r[0x03]); g_dsp.r[dreg2] = dsp_dmem_read(g_dsp.r[0x03]);
if (_Opcode & 0x04) if (_Opcode & 0x04)
{ {
g_dsp.r[sreg] += g_dsp.r[sreg + 0x04]; g_dsp.r[sreg] += g_dsp.r[sreg + 0x04];
} }
else else
{ {
g_dsp.r[sreg]++; g_dsp.r[sreg]++;
} }
if (_Opcode & 0x08) if (_Opcode & 0x08)
{ {
g_dsp.r[0x03] += g_dsp.r[0x07]; g_dsp.r[0x03] += g_dsp.r[0x07];
} }
else else
{ {
g_dsp.r[0x03]++; g_dsp.r[0x03]++;
} }
} }
// ================================================================================ // ================================================================================
// //
// //
// //
// ================================================================================ // ================================================================================
void dsp_op_ext_ops_pro(uint16 _Opcode) void dsp_op_ext_ops_pro(uint16 _Opcode)
{ {
if ((_Opcode & 0xFF) == 0){return;} if ((_Opcode & 0xFF) == 0){return;}
switch ((_Opcode >> 4) & 0xf) switch ((_Opcode >> 4) & 0xf)
{ {
case 0x00: case 0x00:
dsp_op_ext_r_epi(_Opcode); dsp_op_ext_r_epi(_Opcode);
break; break;
case 0x01: case 0x01:
dsp_op_ext_mv(_Opcode); dsp_op_ext_mv(_Opcode);
break; break;
case 0x02: case 0x02:
case 0x03: case 0x03:
dsp_op_ext_s(_Opcode); dsp_op_ext_s(_Opcode);
break; break;
case 0x04: case 0x04:
case 0x05: case 0x05:
case 0x06: case 0x06:
case 0x07: case 0x07:
dsp_op_ext_l(_Opcode); dsp_op_ext_l(_Opcode);
break; break;
case 0x08: case 0x08:
case 0x09: case 0x09:
case 0x0a: case 0x0a:
case 0x0b: case 0x0b:
if (_Opcode & 0x2) if (_Opcode & 0x2)
{ {
dsp_op_ext_sl_pro(_Opcode); dsp_op_ext_sl_pro(_Opcode);
} }
else else
{ {
dsp_op_ext_ls_pro(_Opcode); dsp_op_ext_ls_pro(_Opcode);
} }
return; return;
case 0x0c: case 0x0c:
case 0x0d: case 0x0d:
case 0x0e: case 0x0e:
case 0x0f: case 0x0f:
dsp_op_ext_ld(_Opcode); dsp_op_ext_ld(_Opcode);
break; break;
} }
} }
void dsp_op_ext_ops_epi(uint16 _Opcode) void dsp_op_ext_ops_epi(uint16 _Opcode)
{ {
if ((_Opcode & 0xFF) == 0){return;} if ((_Opcode & 0xFF) == 0){return;}
switch ((_Opcode >> 4) & 0xf) switch ((_Opcode >> 4) & 0xf)
{ {
case 0x08: case 0x08:
case 0x09: case 0x09:
case 0x0a: case 0x0a:
case 0x0b: case 0x0b:
if (_Opcode & 0x2) if (_Opcode & 0x2)
{ {
dsp_op_ext_sl_epi(_Opcode); dsp_op_ext_sl_epi(_Opcode);
} }
else else
{ {
dsp_op_ext_ls_epi(_Opcode); dsp_op_ext_ls_epi(_Opcode);
} }
return; return;
} }
} }

View File

@ -1,357 +1,357 @@
/*==================================================================== /*====================================================================
filename: gdsp_interface.h filename: gdsp_interface.h
project: GCemu project: GCemu
created: 2004-6-18 created: 2004-6-18
mail: duddie@walla.com mail: duddie@walla.com
Copyright (c) 2005 Duddie & Tratax Copyright (c) 2005 Duddie & Tratax
This program is free software; you can redistribute it and/or This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2 as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version. of the License, or (at your option) any later version.
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 for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
====================================================================*/ ====================================================================*/
#include <stdlib.h> #include <stdlib.h>
#include "Globals.h" #include "Globals.h"
#include "Thread.h" #include "Thread.h"
#include "gdsp_aram.h" #include "gdsp_aram.h"
#include "gdsp_interpreter.h" #include "gdsp_interpreter.h"
#include "gdsp_interface.h" #include "gdsp_interface.h"
#include "Tools.h" #include "Tools.h"
#ifndef NULL #ifndef NULL
#define NULL 0 #define NULL 0
#endif #endif
#ifndef _WIN32 #ifndef _WIN32
#undef WITH_DSP_ON_THREAD #undef WITH_DSP_ON_THREAD
//TODO FIX //TODO FIX
#endif #endif
const char* reg_names[] = const char* reg_names[] =
{ {
// a0 // a0
"COEF_A1_0", "COEF_A2_0", "COEF_A1_1", "COEF_A2_1", "COEF_A1_2", "COEF_A2_2", "COEF_A1_3", "COEF_A2_3", "COEF_A1_0", "COEF_A2_0", "COEF_A1_1", "COEF_A2_1", "COEF_A1_2", "COEF_A2_2", "COEF_A1_3", "COEF_A2_3",
"COEF_A1_4", "COEF_A2_4", "COEF_A1_5", "COEF_A2_5", "COEF_A1_6", "COEF_A2_6", "COEF_A1_7", "COEF_A2_7", "COEF_A1_4", "COEF_A2_4", "COEF_A1_5", "COEF_A2_5", "COEF_A1_6", "COEF_A2_6", "COEF_A1_7", "COEF_A2_7",
// b0 // b0
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
// c0 // c0
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, "DSCR", NULL, "DSBL", NULL, "DSPA", "DSMAH", "DSMAL", NULL, "DSCR", NULL, "DSBL", NULL, "DSPA", "DSMAH", "DSMAL",
// d0 // d0
NULL, "SampleFormat", NULL, NULL, "ACSAH", "ACSAL", "ACEAH", "ACEAL", NULL, "SampleFormat", NULL, NULL, "ACSAH", "ACSAL", "ACEAH", "ACEAL",
"ACCAH", "ACCAL", "PRED_SCALE", "YN1", "YN2", "ARAM", "GAIN", NULL, "ACCAH", "ACCAL", "PRED_SCALE", "YN1", "YN2", "ARAM", "GAIN", NULL,
// e0 // e0
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, "AMDM", NULL, NULL, NULL, NULL, NULL, NULL, NULL, "AMDM",
// f0 // f0
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, "DMBH", "DMBL", "CMBH", "CMBL", NULL, NULL, NULL, NULL, "DMBH", "DMBL", "CMBH", "CMBL",
}; };
void gdsp_dma(); void gdsp_dma();
#ifdef WITH_DSP_ON_THREAD #ifdef WITH_DSP_ON_THREAD
Common::CriticalSection g_CriticalSection; Common::CriticalSection g_CriticalSection;
#endif #endif
static volatile uint16 gdsp_mbox[2][2]; static volatile uint16 gdsp_mbox[2][2];
uint16 gdsp_ifx_regs[256]; uint16 gdsp_ifx_regs[256];
void gdsp_ifx_init() void gdsp_ifx_init()
{ {
int i; int i;
for (i = 0; i < 256; i++) for (i = 0; i < 256; i++)
{ {
gdsp_ifx_regs[i] = 0; gdsp_ifx_regs[i] = 0;
} }
gdsp_mbox[0][0] = 0; gdsp_mbox[0][0] = 0;
gdsp_mbox[0][1] = 0; gdsp_mbox[0][1] = 0;
gdsp_mbox[1][0] = 0; gdsp_mbox[1][0] = 0;
gdsp_mbox[1][1] = 0; gdsp_mbox[1][1] = 0;
} }
uint32 gdsp_mbox_peek(uint8 mbx) uint32 gdsp_mbox_peek(uint8 mbx)
{ {
#if WITH_DSP_ON_THREAD #if WITH_DSP_ON_THREAD
g_CriticalSection.Enter(); g_CriticalSection.Enter();
#endif #endif
uint32 value = ((gdsp_mbox[mbx][0] << 16) | gdsp_mbox[mbx][1]); uint32 value = ((gdsp_mbox[mbx][0] << 16) | gdsp_mbox[mbx][1]);
#if WITH_DSP_ON_THREAD #if WITH_DSP_ON_THREAD
g_CriticalSection.Leave(); g_CriticalSection.Leave();
#endif #endif
return value; return value;
} }
void gdsp_mbox_write_h(uint8 mbx, uint16 val) void gdsp_mbox_write_h(uint8 mbx, uint16 val)
{ {
#if WITH_DSP_ON_THREAD #if WITH_DSP_ON_THREAD
g_CriticalSection.Enter(); g_CriticalSection.Enter();
#endif #endif
gdsp_mbox[mbx][0] = val & 0x7fff; gdsp_mbox[mbx][0] = val & 0x7fff;
#if WITH_DSP_ON_THREAD #if WITH_DSP_ON_THREAD
g_CriticalSection.Leave(); g_CriticalSection.Leave();
#endif #endif
} }
void gdsp_mbox_write_l(uint8 mbx, uint16 val) void gdsp_mbox_write_l(uint8 mbx, uint16 val)
{ {
#if WITH_DSP_ON_THREAD #if WITH_DSP_ON_THREAD
g_CriticalSection.Enter(); g_CriticalSection.Enter();
#endif #endif
gdsp_mbox[mbx][1] = val; gdsp_mbox[mbx][1] = val;
gdsp_mbox[mbx][0] |= 0x8000; gdsp_mbox[mbx][0] |= 0x8000;
#if WITH_DSP_ON_THREAD #if WITH_DSP_ON_THREAD
g_CriticalSection.Leave(); g_CriticalSection.Leave();
#endif #endif
if (mbx == GDSP_MBOX_DSP) if (mbx == GDSP_MBOX_DSP)
{ {
DebugLog("- Write DSP Mail: 0x%08x (pc=0x%04x)\n", gdsp_mbox_peek(GDSP_MBOX_DSP), g_dsp.err_pc); DebugLog("- Write DSP Mail: 0x%08x (pc=0x%04x)\n", gdsp_mbox_peek(GDSP_MBOX_DSP), g_dsp.err_pc);
} }
} }
uint16 gdsp_mbox_read_h(uint8 mbx) uint16 gdsp_mbox_read_h(uint8 mbx)
{ {
return (gdsp_mbox[mbx][0]); return (gdsp_mbox[mbx][0]);
} }
uint16 gdsp_mbox_read_l(uint8 mbx) uint16 gdsp_mbox_read_l(uint8 mbx)
{ {
uint16 val; uint16 val;
#if WITH_DSP_ON_THREAD #if WITH_DSP_ON_THREAD
g_CriticalSection.Enter(); g_CriticalSection.Enter();
#endif #endif
val = gdsp_mbox[mbx][1]; val = gdsp_mbox[mbx][1];
gdsp_mbox[mbx][0] &= ~0x8000; gdsp_mbox[mbx][0] &= ~0x8000;
#if WITH_DSP_ON_THREAD #if WITH_DSP_ON_THREAD
g_CriticalSection.Leave(); g_CriticalSection.Leave();
#endif #endif
return(val); return(val);
} }
void gdsp_ifx_write(uint16 addr, uint16 val) void gdsp_ifx_write(uint16 addr, uint16 val)
{ {
addr &= 0xff; addr &= 0xff;
switch (addr & 0xff) switch (addr & 0xff)
{ {
case 0xfb: // DIRQ case 0xfb: // DIRQ
if (val & 0x1) if (val & 0x1)
{ {
g_dsp.irq_request(); g_dsp.irq_request();
} }
break; break;
case 0xfc: // DMBH case 0xfc: // DMBH
gdsp_mbox_write_h(GDSP_MBOX_DSP, val); gdsp_mbox_write_h(GDSP_MBOX_DSP, val);
break; break;
case 0xfd: // DMBL case 0xfd: // DMBL
gdsp_mbox_write_l(GDSP_MBOX_DSP, val); gdsp_mbox_write_l(GDSP_MBOX_DSP, val);
break; break;
case 0xcb: // DSBL case 0xcb: // DSBL
gdsp_ifx_regs[addr] = val; gdsp_ifx_regs[addr] = val;
gdsp_dma(); gdsp_dma();
gdsp_ifx_regs[DSP_DSCR] &= ~0x0004; gdsp_ifx_regs[DSP_DSCR] &= ~0x0004;
break; break;
case 0xcd: case 0xcd:
case 0xce: case 0xce:
case 0xcf: case 0xcf:
case 0xc9: case 0xc9:
gdsp_ifx_regs[addr] = val; gdsp_ifx_regs[addr] = val;
break; break;
default: default:
/* if ((addr & 0xff) >= 0xa0 && reg_names[addr - 0xa0]) /* if ((addr & 0xff) >= 0xa0 && reg_names[addr - 0xa0])
DebugLog("%04x MW %s (%04x)\n", g_dsp.pc, reg_names[addr - 0xa0], val); DebugLog("%04x MW %s (%04x)\n", g_dsp.pc, reg_names[addr - 0xa0], val);
else else
DebugLog("%04x MW %04x (%04x)\n", g_dsp.pc, addr, val);*/ DebugLog("%04x MW %04x (%04x)\n", g_dsp.pc, addr, val);*/
gdsp_ifx_regs[addr] = val; gdsp_ifx_regs[addr] = val;
break; break;
} }
} }
uint16 gdsp_ifx_read(uint16 addr) uint16 gdsp_ifx_read(uint16 addr)
{ {
uint16 val; uint16 val;
addr &= 0xff; addr &= 0xff;
switch (addr & 0xff) switch (addr & 0xff)
{ {
case 0xfc: // DMBH case 0xfc: // DMBH
val = gdsp_mbox_read_h(GDSP_MBOX_DSP); val = gdsp_mbox_read_h(GDSP_MBOX_DSP);
break; break;
case 0xfe: // CMBH case 0xfe: // CMBH
val = gdsp_mbox_read_h(GDSP_MBOX_CPU); val = gdsp_mbox_read_h(GDSP_MBOX_CPU);
break; break;
case 0xff: // CMBL case 0xff: // CMBL
val = gdsp_mbox_read_l(GDSP_MBOX_CPU); val = gdsp_mbox_read_l(GDSP_MBOX_CPU);
break; break;
case 0xc9: case 0xc9:
val = gdsp_ifx_regs[addr]; val = gdsp_ifx_regs[addr];
break; break;
case 0xdd: case 0xdd:
val = dsp_read_aram(); val = dsp_read_aram();
break; break;
default: default:
val = gdsp_ifx_regs[addr]; val = gdsp_ifx_regs[addr];
/* if ((addr & 0xff) >= 0xc0 && reg_names[addr & 0x3f]) /* if ((addr & 0xff) >= 0xc0 && reg_names[addr & 0x3f])
printf("%04x MR %s (%04x)\n", g_dsp.pc, reg_names[addr & 0x3f], val); printf("%04x MR %s (%04x)\n", g_dsp.pc, reg_names[addr & 0x3f], val);
else else
printf("%04x MR %04x (%04x)\n", g_dsp.pc, addr, val);*/ printf("%04x MR %04x (%04x)\n", g_dsp.pc, addr, val);*/
break; break;
} }
return(val); return(val);
} }
void gdsp_idma_in(uint16 dsp_addr, uint32 addr, uint32 size) void gdsp_idma_in(uint16 dsp_addr, uint32 addr, uint32 size)
{ {
uint8* dst = ((uint8*)g_dsp.iram); uint8* dst = ((uint8*)g_dsp.iram);
for (uint32 i = 0; i < size; i += 2) for (uint32 i = 0; i < size; i += 2)
{ {
*(uint16*)&dst[dsp_addr + i] = *(uint16*)&g_dsp.cpu_ram[(addr + i) & 0x0fffffff]; *(uint16*)&dst[dsp_addr + i] = *(uint16*)&g_dsp.cpu_ram[(addr + i) & 0x0fffffff];
} }
g_dsp.iram_crc = GenerateCRC(g_dsp.cpu_ram + (addr & 0x0fffffff), size); g_dsp.iram_crc = GenerateCRC(g_dsp.cpu_ram + (addr & 0x0fffffff), size);
DebugLog("*** Copy new UCode from 0x%08x to 0x%04x (crc: %8x)\n", addr, dsp_addr, g_dsp.iram_crc); DebugLog("*** Copy new UCode from 0x%08x to 0x%04x (crc: %8x)\n", addr, dsp_addr, g_dsp.iram_crc);
#if DUMP_DSP_IMEM #if DUMP_DSP_IMEM
DumpDSPCode(addr, size, g_dsp.iram_crc ); DumpDSPCode(addr, size, g_dsp.iram_crc );
#endif #endif
} }
void gdsp_idma_out(uint16 dsp_addr, uint32 addr, uint32 size) void gdsp_idma_out(uint16 dsp_addr, uint32 addr, uint32 size)
{ {
ErrorLog("*** idma_out IRAM_DSP (0x%04x) -> RAM (0x%08x) : size (0x%08x)\n", dsp_addr / 2, addr, size); ErrorLog("*** idma_out IRAM_DSP (0x%04x) -> RAM (0x%08x) : size (0x%08x)\n", dsp_addr / 2, addr, size);
} }
void gdsp_ddma_in(uint16 dsp_addr, uint32 addr, uint32 size) void gdsp_ddma_in(uint16 dsp_addr, uint32 addr, uint32 size)
{ {
if ((addr & 0x7FFFFFFF) > 0x01FFFFFF) if ((addr & 0x7FFFFFFF) > 0x01FFFFFF)
{ {
ErrorLog("*** ddma_in read from invalid addr (0x%08x)\n", addr); ErrorLog("*** ddma_in read from invalid addr (0x%08x)\n", addr);
return; return;
} }
uint8* dst = ((uint8*)g_dsp.dram); uint8* dst = ((uint8*)g_dsp.dram);
for (uint32 i = 0; i < size; i += 2) for (uint32 i = 0; i < size; i += 2)
{ {
*(uint16*)&dst[dsp_addr + i] = *(uint16*)&g_dsp.cpu_ram[(addr + i) & 0x7FFFFFFF]; *(uint16*)&dst[dsp_addr + i] = *(uint16*)&g_dsp.cpu_ram[(addr + i) & 0x7FFFFFFF];
} }
DebugLog("*** ddma_in RAM (0x%08x) -> DRAM_DSP (0x%04x) : size (0x%08x)\n", addr, dsp_addr / 2, size); DebugLog("*** ddma_in RAM (0x%08x) -> DRAM_DSP (0x%04x) : size (0x%08x)\n", addr, dsp_addr / 2, size);
} }
void gdsp_ddma_out(uint16 dsp_addr, uint32 addr, uint32 size) void gdsp_ddma_out(uint16 dsp_addr, uint32 addr, uint32 size)
{ {
if ((addr & 0x7FFFFFFF) > 0x01FFFFFF) if ((addr & 0x7FFFFFFF) > 0x01FFFFFF)
{ {
ErrorLog("*** gdsp_ddma_out to invalid addr (0x%08x)\n", addr); ErrorLog("*** gdsp_ddma_out to invalid addr (0x%08x)\n", addr);
return; return;
} }
uint8* src = ((uint8*)g_dsp.dram); uint8* src = ((uint8*)g_dsp.dram);
for (uint32 i = 0; i < size; i += 2) for (uint32 i = 0; i < size; i += 2)
{ {
*(uint16*)&g_dsp.cpu_ram[(addr + i) & 0x7FFFFFFF] = *(uint16*)&src[dsp_addr + i]; *(uint16*)&g_dsp.cpu_ram[(addr + i) & 0x7FFFFFFF] = *(uint16*)&src[dsp_addr + i];
} }
DebugLog("*** ddma_out DRAM_DSP (0x%04x) -> RAM (0x%08x) : size (0x%08x)\n", dsp_addr / 2, addr, size); DebugLog("*** ddma_out DRAM_DSP (0x%04x) -> RAM (0x%08x) : size (0x%08x)\n", dsp_addr / 2, addr, size);
} }
#define DSP_CR_IMEM (2) #define DSP_CR_IMEM (2)
#define DSP_CR_DMEM (0) #define DSP_CR_DMEM (0)
#define DSP_CR_TO_CPU (1) #define DSP_CR_TO_CPU (1)
#define DSP_CR_FROM_CPU (0) #define DSP_CR_FROM_CPU (0)
void gdsp_dma() void gdsp_dma()
{ {
uint16 ctl; uint16 ctl;
uint32 addr; uint32 addr;
uint16 dsp_addr; uint16 dsp_addr;
uint16 len; uint16 len;
addr = (gdsp_ifx_regs[DSP_DSMAH] << 16) | gdsp_ifx_regs[DSP_DSMAL]; addr = (gdsp_ifx_regs[DSP_DSMAH] << 16) | gdsp_ifx_regs[DSP_DSMAL];
ctl = gdsp_ifx_regs[DSP_DSCR]; ctl = gdsp_ifx_regs[DSP_DSCR];
dsp_addr = gdsp_ifx_regs[DSP_DSPA] * 2; dsp_addr = gdsp_ifx_regs[DSP_DSPA] * 2;
len = gdsp_ifx_regs[DSP_DSBL]; len = gdsp_ifx_regs[DSP_DSBL];
if ((ctl > 3) || (len > 0x4000)) if ((ctl > 3) || (len > 0x4000))
{ {
ErrorLog("DMA ERROR pc: %04x ctl: %04x addr: %08x da: %04x size: %04x\n", g_dsp.pc, ctl, addr, dsp_addr, len); ErrorLog("DMA ERROR pc: %04x ctl: %04x addr: %08x da: %04x size: %04x\n", g_dsp.pc, ctl, addr, dsp_addr, len);
exit(0); exit(0);
} }
switch (ctl & 0x3) switch (ctl & 0x3)
{ {
case (DSP_CR_DMEM | DSP_CR_TO_CPU): case (DSP_CR_DMEM | DSP_CR_TO_CPU):
gdsp_ddma_out(dsp_addr, addr, len); gdsp_ddma_out(dsp_addr, addr, len);
break; break;
case (DSP_CR_DMEM | DSP_CR_FROM_CPU): case (DSP_CR_DMEM | DSP_CR_FROM_CPU):
gdsp_ddma_in(dsp_addr, addr, len); gdsp_ddma_in(dsp_addr, addr, len);
break; break;
case (DSP_CR_IMEM | DSP_CR_TO_CPU): case (DSP_CR_IMEM | DSP_CR_TO_CPU):
gdsp_idma_out(dsp_addr, addr, len); gdsp_idma_out(dsp_addr, addr, len);
break; break;
case (DSP_CR_IMEM | DSP_CR_FROM_CPU): case (DSP_CR_IMEM | DSP_CR_FROM_CPU):
gdsp_idma_in(dsp_addr, addr, len); gdsp_idma_in(dsp_addr, addr, len);
break; break;
} }
} }

View File

@ -1,444 +1,444 @@
/*==================================================================== /*====================================================================
filename: gdsp_interpreter.cpp filename: gdsp_interpreter.cpp
project: GCemu project: GCemu
created: 2004-6-18 created: 2004-6-18
mail: duddie@walla.com mail: duddie@walla.com
Copyright (c) 2005 Duddie & Tratax Copyright (c) 2005 Duddie & Tratax
This program is free software; you can redistribute it and/or This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2 as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version. of the License, or (at your option) any later version.
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 for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
====================================================================*/ ====================================================================*/
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include "gdsp_interface.h" #include "gdsp_interface.h"
#include "gdsp_opcodes_helper.h" #include "gdsp_opcodes_helper.h"
#include "Tools.h" #include "Tools.h"
//------------------------------------------------------------------------------- //-------------------------------------------------------------------------------
SDSP g_dsp; SDSP g_dsp;
uint16 SDSP::r[32]; uint16 SDSP::r[32];
uint16 SDSP::pc = 0; uint16 SDSP::pc = 0;
uint16 SDSP::err_pc = 0; uint16 SDSP::err_pc = 0;
uint16* SDSP::iram = 0; uint16* SDSP::iram = 0;
uint16* SDSP::dram = 0; uint16* SDSP::dram = 0;
uint16* SDSP::irom = 0; uint16* SDSP::irom = 0;
uint16* SDSP::drom = 0; uint16* SDSP::drom = 0;
uint16* SDSP::coef = 0; uint16* SDSP::coef = 0;
uint8* SDSP::cpu_ram = 0; uint8* SDSP::cpu_ram = 0;
uint16 SDSP::cr = 0; uint16 SDSP::cr = 0;
uint8 SDSP::reg_stack_ptr[4]; uint8 SDSP::reg_stack_ptr[4];
// lets make stack depth to 32 for now // lets make stack depth to 32 for now
uint16 SDSP::reg_stack[4][DSP_STACK_DEPTH]; uint16 SDSP::reg_stack[4][DSP_STACK_DEPTH];
void (*SDSP::irq_request)() = NULL; void (*SDSP::irq_request)() = NULL;
bool SDSP::exception_in_progress_hack = false; bool SDSP::exception_in_progress_hack = false;
// for debugger only // for debugger only
uint32 SDSP::iram_crc = 0; uint32 SDSP::iram_crc = 0;
uint64 SDSP::step_counter = 0; uint64 SDSP::step_counter = 0;
//------------------------------------------------------------------------------- //-------------------------------------------------------------------------------
static bool CR_HALT = true; static bool CR_HALT = true;
static bool CR_EXTERNAL_INT = false; static bool CR_EXTERNAL_INT = false;
void UpdateCachedCR() void UpdateCachedCR()
{ {
CR_HALT = (g_dsp.cr & 0x4) != 0; CR_HALT = (g_dsp.cr & 0x4) != 0;
CR_EXTERNAL_INT = (g_dsp.cr & 0x02) != 0; CR_EXTERNAL_INT = (g_dsp.cr & 0x02) != 0;
} }
//------------------------------------------------------------------------------- //-------------------------------------------------------------------------------
void (*dsp_op[])(uint16 opc) = void (*dsp_op[])(uint16 opc) =
{ {
dsp_op0, dsp_op1, dsp_op2, dsp_op3, dsp_op0, dsp_op1, dsp_op2, dsp_op3,
dsp_op4, dsp_op5, dsp_op6, dsp_op7, dsp_op4, dsp_op5, dsp_op6, dsp_op7,
dsp_op8, dsp_op9, dsp_opab, dsp_opab, dsp_op8, dsp_op9, dsp_opab, dsp_opab,
dsp_opcd, dsp_opcd, dsp_ope, dsp_opf, dsp_opcd, dsp_opcd, dsp_ope, dsp_opf,
}; };
void dbg_error(char* err_msg) void dbg_error(char* err_msg)
{ {
return; return;
} }
void gdsp_init() void gdsp_init()
{ {
g_dsp.irom = (uint16*)malloc(DSP_IROM_SIZE * sizeof(uint16)); g_dsp.irom = (uint16*)malloc(DSP_IROM_SIZE * sizeof(uint16));
g_dsp.iram = (uint16*)malloc(DSP_IRAM_SIZE * sizeof(uint16)); g_dsp.iram = (uint16*)malloc(DSP_IRAM_SIZE * sizeof(uint16));
g_dsp.drom = (uint16*)malloc(DSP_DROM_SIZE * sizeof(uint16)); g_dsp.drom = (uint16*)malloc(DSP_DROM_SIZE * sizeof(uint16));
g_dsp.dram = (uint16*)malloc(DSP_DRAM_SIZE * sizeof(uint16)); g_dsp.dram = (uint16*)malloc(DSP_DRAM_SIZE * sizeof(uint16));
g_dsp.coef = (uint16*)malloc(DSP_COEF_SIZE * sizeof(uint16)); g_dsp.coef = (uint16*)malloc(DSP_COEF_SIZE * sizeof(uint16));
for (int i = 0; i < DSP_IRAM_SIZE; i++) for (int i = 0; i < DSP_IRAM_SIZE; i++)
{ {
g_dsp.iram[i] = 0x0021; // HALT opcode g_dsp.iram[i] = 0x0021; // HALT opcode
} }
for (int i = 0; i < DSP_DRAM_SIZE; i++) for (int i = 0; i < DSP_DRAM_SIZE; i++)
{ {
g_dsp.dram[i] = 0x0021; // HALT opcode g_dsp.dram[i] = 0x0021; // HALT opcode
} }
for (int i = 0; i < 32; i++) for (int i = 0; i < 32; i++)
{ {
g_dsp.r[i] = 0; g_dsp.r[i] = 0;
} }
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
{ {
g_dsp.reg_stack_ptr[i] = 0; g_dsp.reg_stack_ptr[i] = 0;
for (int j = 0; j < DSP_STACK_DEPTH; j++) for (int j = 0; j < DSP_STACK_DEPTH; j++)
{ {
g_dsp.reg_stack[i][j] = 0; g_dsp.reg_stack[i][j] = 0;
} }
} }
// copied from a real console after the custom UCode has been loaded // copied from a real console after the custom UCode has been loaded
g_dsp.r[0x08] = 0xffff; g_dsp.r[0x08] = 0xffff;
g_dsp.r[0x09] = 0xffff; g_dsp.r[0x09] = 0xffff;
g_dsp.r[0x0a] = 0xffff; g_dsp.r[0x0a] = 0xffff;
g_dsp.r[0x0b] = 0xffff; g_dsp.r[0x0b] = 0xffff;
g_dsp.cr = 0x804; g_dsp.cr = 0x804;
gdsp_ifx_init(); gdsp_ifx_init();
UpdateCachedCR(); UpdateCachedCR();
} }
void gdsp_reset() void gdsp_reset()
{ {
// _assert_msg_(0, "gdsp_reset()"); // _assert_msg_(0, "gdsp_reset()");
_assert_msg_(MASTER_LOG, !g_dsp.exception_in_progress_hack, "assert while exception"); _assert_msg_(MASTER_LOG, !g_dsp.exception_in_progress_hack, "assert while exception");
g_dsp.pc = DSP_RESET_VECTOR; g_dsp.pc = DSP_RESET_VECTOR;
g_dsp.exception_in_progress_hack = false; g_dsp.exception_in_progress_hack = false;
} }
uint8 gdsp_exceptions = 0; uint8 gdsp_exceptions = 0;
void gdsp_generate_exception(uint8 level) void gdsp_generate_exception(uint8 level)
{ {
gdsp_exceptions |= 1 << level; gdsp_exceptions |= 1 << level;
} }
bool gdsp_load_rom(char* fname) bool gdsp_load_rom(char* fname)
{ {
FILE* pFile = fopen(fname, "rb"); FILE* pFile = fopen(fname, "rb");
if (pFile) if (pFile)
{ {
fread(g_dsp.irom, 1, DSP_IRAM_SIZE, pFile); fread(g_dsp.irom, 1, DSP_IRAM_SIZE, pFile);
fclose(pFile); fclose(pFile);
return(true); return(true);
} }
return(false); return(false);
} }
bool gdsp_load_coef(char* fname) bool gdsp_load_coef(char* fname)
{ {
FILE* pFile = fopen(fname, "rb"); FILE* pFile = fopen(fname, "rb");
if (pFile) if (pFile)
{ {
fread(g_dsp.coef, 1, DSP_COEF_SIZE, pFile); fread(g_dsp.coef, 1, DSP_COEF_SIZE, pFile);
fclose(pFile); fclose(pFile);
return(true); return(true);
} }
return(false); return(false);
} }
void gdsp_write_cr(uint16 val) void gdsp_write_cr(uint16 val)
{ {
// reset // reset
if (val & 0x0001) if (val & 0x0001)
{ {
gdsp_reset(); gdsp_reset();
} }
val &= ~0x0001; val &= ~0x0001;
// update cr // update cr
g_dsp.cr = val; g_dsp.cr = val;
UpdateCachedCR(); UpdateCachedCR();
} }
uint16 gdsp_read_cr() uint16 gdsp_read_cr()
{ {
if (g_dsp.pc & 0x8000) if (g_dsp.pc & 0x8000)
{ {
g_dsp.cr |= 0x800; g_dsp.cr |= 0x800;
} }
else else
{ {
g_dsp.cr &= ~0x800; g_dsp.cr &= ~0x800;
} }
UpdateCachedCR(); UpdateCachedCR();
return(g_dsp.cr); return(g_dsp.cr);
} }
// special loop step.. because exception in loop or loopi fails // special loop step.. because exception in loop or loopi fails
// dunno how we have to fix it // dunno how we have to fix it
// atm we execute this instructions directly inside the loop command // atm we execute this instructions directly inside the loop command
// so it cant be interrupted by an exception // so it cant be interrupted by an exception
void gdsp_loop_step() void gdsp_loop_step()
{ {
g_dsp.err_pc = g_dsp.pc; g_dsp.err_pc = g_dsp.pc;
uint16 opc = dsp_fetch_code(); uint16 opc = dsp_fetch_code();
dsp_op[opc >> 12](opc); dsp_op[opc >> 12](opc);
} }
u16 HLE_ROM_80E7_81F8(); u16 HLE_ROM_80E7_81F8();
void hacks(); void hacks();
void gdsp_step() void gdsp_step()
{ {
g_dsp.step_counter++; g_dsp.step_counter++;
if (g_dsp.pc == 0x80e7) if (g_dsp.pc == 0x80e7)
{ {
//g_dsp.pc = HLE_ROM_80E7_81F8(); //g_dsp.pc = HLE_ROM_80E7_81F8();
} }
g_dsp.err_pc = g_dsp.pc; g_dsp.err_pc = g_dsp.pc;
#if PROFILE #if PROFILE
ProfilerAddDelta(g_dsp.err_pc, 1); ProfilerAddDelta(g_dsp.err_pc, 1);
if (g_dsp.step_counter == 1) if (g_dsp.step_counter == 1)
{ {
ProfilerInit(); ProfilerInit();
} }
if ((g_dsp.step_counter & 0xFFFFF) == 0) if ((g_dsp.step_counter & 0xFFFFF) == 0)
{ {
ProfilerDump(g_dsp.step_counter); ProfilerDump(g_dsp.step_counter);
} }
#endif #endif
uint16 opc = dsp_fetch_code(); uint16 opc = dsp_fetch_code();
dsp_op[opc >> 12](opc); dsp_op[opc >> 12](opc);
uint16& rLoopCounter = g_dsp.r[DSP_REG_ST0 + 3]; uint16& rLoopCounter = g_dsp.r[DSP_REG_ST0 + 3];
if (rLoopCounter > 0) if (rLoopCounter > 0)
{ {
const uint16& rCallAddress = g_dsp.r[DSP_REG_ST0 + 0]; const uint16& rCallAddress = g_dsp.r[DSP_REG_ST0 + 0];
const uint16& rLoopAddress = g_dsp.r[DSP_REG_ST0 + 2]; const uint16& rLoopAddress = g_dsp.r[DSP_REG_ST0 + 2];
if (g_dsp.pc == (rLoopAddress + 1)) if (g_dsp.pc == (rLoopAddress + 1))
{ {
rLoopCounter--; rLoopCounter--;
if (rLoopCounter > 0) if (rLoopCounter > 0)
{ {
g_dsp.pc = rCallAddress; g_dsp.pc = rCallAddress;
} }
else else
{ {
// end of loop // end of loop
dsp_reg_load_stack(0); dsp_reg_load_stack(0);
dsp_reg_load_stack(2); dsp_reg_load_stack(2);
dsp_reg_load_stack(3); dsp_reg_load_stack(3);
} }
} }
} }
// check if there is an external interrupt // check if there is an external interrupt
if (CR_EXTERNAL_INT) if (CR_EXTERNAL_INT)
{ {
if (dsp_SR_is_flag_set(FLAG_ENABLE_INTERUPT) && (g_dsp.exception_in_progress_hack == false)) if (dsp_SR_is_flag_set(FLAG_ENABLE_INTERUPT) && (g_dsp.exception_in_progress_hack == false))
{ {
// level 7 is the interrupt exception // level 7 is the interrupt exception
gdsp_generate_exception(7); gdsp_generate_exception(7);
g_dsp.cr &= ~0x0002; g_dsp.cr &= ~0x0002;
UpdateCachedCR(); UpdateCachedCR();
} }
} }
// check exceptions // check exceptions
if ((gdsp_exceptions > 0) && (!g_dsp.exception_in_progress_hack)) if ((gdsp_exceptions > 0) && (!g_dsp.exception_in_progress_hack))
{ {
for (uint8 i=0; i<8; i++) for (uint8 i=0; i<8; i++)
{ {
if (gdsp_exceptions & (1<<i)) if (gdsp_exceptions & (1<<i))
{ {
_assert_msg_(MASTER_LOG, !g_dsp.exception_in_progress_hack, "assert while exception"); _assert_msg_(MASTER_LOG, !g_dsp.exception_in_progress_hack, "assert while exception");
dsp_reg_store_stack(DSP_STACK_C, g_dsp.pc); dsp_reg_store_stack(DSP_STACK_C, g_dsp.pc);
dsp_reg_store_stack(DSP_STACK_D, g_dsp.r[R_SR]); dsp_reg_store_stack(DSP_STACK_D, g_dsp.r[R_SR]);
g_dsp.pc = i * 2; g_dsp.pc = i * 2;
gdsp_exceptions &= ~(1<<i); gdsp_exceptions &= ~(1<<i);
g_dsp.exception_in_progress_hack = true; g_dsp.exception_in_progress_hack = true;
break; break;
} }
} }
} }
} }
bool gdsp_running; bool gdsp_running;
extern volatile uint32 dsp_running; extern volatile uint32 dsp_running;
bool gdsp_run() bool gdsp_run()
{ {
gdsp_running = true; gdsp_running = true;
while (!CR_HALT) while (!CR_HALT)
{ {
gdsp_step(); gdsp_step();
} }
gdsp_running = false; gdsp_running = false;
return(true); return(true);
} }
bool gdsp_runx(uint16 cnt) bool gdsp_runx(uint16 cnt)
{ {
gdsp_running = true; gdsp_running = true;
while (!(g_dsp.cr & 0x4) && gdsp_running) while (!(g_dsp.cr & 0x4) && gdsp_running)
{ {
gdsp_step(); gdsp_step();
cnt--; cnt--;
if (cnt == 0) if (cnt == 0)
{ {
break; break;
} }
} }
gdsp_running = false; gdsp_running = false;
return(true); return(true);
} }
void gdsp_stop() void gdsp_stop()
{ {
gdsp_running = false; gdsp_running = false;
} }
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// //
// From fires for fires :) // From fires for fires :)
// //
// //
#include "disassemble.h" #include "disassemble.h"
#include "WaveFile.h" #include "WaveFile.h"
#include "Mixer.h" #include "Mixer.h"
uint16 r30 = 0, r31 = 0; uint16 r30 = 0, r31 = 0;
void PanicAlert(const char* text, ...); void PanicAlert(const char* text, ...);
extern WaveFileWriter g_wave_writer; extern WaveFileWriter g_wave_writer;
extern uint16 dsp_swap16(uint16 x); extern uint16 dsp_swap16(uint16 x);
void Hacks() void Hacks()
{ {
// if (g_wave_writer.GetAudioSize() > 1024*1024*1) // if (g_wave_writer.GetAudioSize() > 1024*1024*1)
/* if (g_dsp.pc == 0x165) /* if (g_dsp.pc == 0x165)
{ {
PanicAlert("Opcode_06"); PanicAlert("Opcode_06");
} }
if (g_dsp.pc == 0x43b) if (g_dsp.pc == 0x43b)
{ {
PanicAlert("Opcode_14"); PanicAlert("Opcode_14");
} }
if (g_dsp.pc == 0xb37) if (g_dsp.pc == 0xb37)
{ {
PanicAlert("Opcode_08"); PanicAlert("Opcode_08");
}*/ }*/
/* if (g_dsp.pc == 0x1bc) /* if (g_dsp.pc == 0x1bc)
{ {
r30 = g_dsp.r[30]; r30 = g_dsp.r[30];
r31 = g_dsp.r[31]; r31 = g_dsp.r[31];
} }
else if (g_dsp.pc == 0x384) else if (g_dsp.pc == 0x384)
{ {
// if ((r30 == 0x1bc) && (r31 == 0xaff)) // if ((r30 == 0x1bc) && (r31 == 0xaff))
{ {
//PanicAlert("%x, %x", r30, r31); //PanicAlert("%x, %x", r30, r31);
const int numSamples = 0x280; const int numSamples = 0x280;
static short Buffer[numSamples]; static short Buffer[numSamples];
uint16 bufferAddr = 0x280; //dsp_dmem_read(0xe44); uint16 bufferAddr = 0x280; //dsp_dmem_read(0xe44);
for (int i=0; i<numSamples; i++) for (int i=0; i<numSamples; i++)
{ {
Buffer[i] = dsp_dmem_read(bufferAddr+i); Buffer[i] = dsp_dmem_read(bufferAddr+i);
} }
g_wave_writer.AddStereoSamples(Buffer, numSamples/2); // 2 channels g_wave_writer.AddStereoSamples(Buffer, numSamples/2); // 2 channels
if (g_wave_writer.GetAudioSize() > 1024*1024*2) if (g_wave_writer.GetAudioSize() > 1024*1024*2)
{ {
//PanicAlert("%x", bufferAddr); //PanicAlert("%x", bufferAddr);
g_wave_writer.Stop(); g_wave_writer.Stop();
exit(1); exit(1);
} }
} }
} */ } */
if (g_dsp.pc == 0x468) if (g_dsp.pc == 0x468)
{ {
int numSamples = g_dsp.r[25] / 2; int numSamples = g_dsp.r[25] / 2;
uint16 bufferAddr = g_dsp.r[27]; uint16 bufferAddr = g_dsp.r[27];
// PanicAlert("%x %x", bufferAddr, numSamples); // PanicAlert("%x %x", bufferAddr, numSamples);
short samples[1024]; short samples[1024];
for (int i=0; i<numSamples; i++) for (int i=0; i<numSamples; i++)
{ {
samples[i] = dsp_dmem_read(bufferAddr+i); samples[i] = dsp_dmem_read(bufferAddr+i);
} }
Mixer_PushSamples(samples, numSamples / 2, 32000); //sample_rate); Mixer_PushSamples(samples, numSamples / 2, 32000); //sample_rate);
g_wave_writer.AddStereoSamples(samples, numSamples/2); // 2 channels g_wave_writer.AddStereoSamples(samples, numSamples/2); // 2 channels
if (g_wave_writer.GetAudioSize() > 1024*1024*2) if (g_wave_writer.GetAudioSize() > 1024*1024*2)
{ {
//PanicAlert("%x", bufferAddr); //PanicAlert("%x", bufferAddr);
g_wave_writer.Stop(); g_wave_writer.Stop();
exit(1); exit(1);
} }
} }
} }

View File

@ -1,156 +1,156 @@
/*==================================================================== /*====================================================================
filename: gdsp_memory.cpp filename: gdsp_memory.cpp
project: GCemu project: GCemu
created: 2004-6-18 created: 2004-6-18
mail: duddie@walla.com mail: duddie@walla.com
Copyright (c) 2005 Duddie & Tratax Copyright (c) 2005 Duddie & Tratax
This program is free software; you can redistribute it and/or This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2 as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version. of the License, or (at your option) any later version.
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 for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
====================================================================*/ ====================================================================*/
#include <stdio.h> #include <stdio.h>
#include "Globals.h" #include "Globals.h"
#include "gdsp_interpreter.h" #include "gdsp_interpreter.h"
#include "gdsp_memory.h" #include "gdsp_memory.h"
#include "gdsp_ifx.h" #include "gdsp_ifx.h"
uint16 dsp_swap16(uint16 x) uint16 dsp_swap16(uint16 x)
{ {
return((x >> 8) | (x << 8)); return((x >> 8) | (x << 8));
} }
uint16* gdsp_get_iram(void) uint16* gdsp_get_iram(void)
{ {
return(g_dsp.iram); return(g_dsp.iram);
} }
uint16* gdsp_get_irom(void) uint16* gdsp_get_irom(void)
{ {
return(g_dsp.irom); return(g_dsp.irom);
} }
uint16* gdsp_get_dram(void) uint16* gdsp_get_dram(void)
{ {
return(g_dsp.dram); return(g_dsp.dram);
} }
uint16* gdsp_get_drom(void) uint16* gdsp_get_drom(void)
{ {
return(g_dsp.drom); return(g_dsp.drom);
} }
uint16 dsp_imem_read(uint16 addr) uint16 dsp_imem_read(uint16 addr)
{ {
uint16 opc; uint16 opc;
if (g_dsp.pc & 0x8000) if (g_dsp.pc & 0x8000)
{ {
opc = g_dsp.irom[addr & DSP_IROM_MASK]; opc = g_dsp.irom[addr & DSP_IROM_MASK];
} }
else else
{ {
opc = g_dsp.iram[addr & DSP_IRAM_MASK]; opc = g_dsp.iram[addr & DSP_IRAM_MASK];
} }
return(dsp_swap16(opc)); return(dsp_swap16(opc));
} }
uint16 dsp_dmem_read(uint16 addr) uint16 dsp_dmem_read(uint16 addr)
{ {
uint16 val; uint16 val;
switch (addr >> 12) switch (addr >> 12)
{ {
case 0x0: // 0xxx DRAM case 0x0: // 0xxx DRAM
val = g_dsp.dram[addr & DSP_DRAM_MASK]; val = g_dsp.dram[addr & DSP_DRAM_MASK];
val = dsp_swap16(val); val = dsp_swap16(val);
break; break;
case 0x8: // 8xxx DROM case 0x8: // 8xxx DROM
DebugLog("someone reads from ROM\n"); DebugLog("someone reads from ROM\n");
val = g_dsp.drom[addr & DSP_DROM_MASK]; val = g_dsp.drom[addr & DSP_DROM_MASK];
val = dsp_swap16(val); val = dsp_swap16(val);
break; break;
case 0x1: // 1xxx COEF case 0x1: // 1xxx COEF
val = g_dsp.coef[addr & DSP_DROM_MASK]; val = g_dsp.coef[addr & DSP_DROM_MASK];
val = dsp_swap16(val); val = dsp_swap16(val);
break; break;
case 0xf: // Fxxx HW regs case 0xf: // Fxxx HW regs
val = gdsp_ifx_read(addr); val = gdsp_ifx_read(addr);
break; break;
default: // error default: // error
// ErrorLog("%04x DSP ERROR: Read from UNKNOWN (%04x) memory\n", g_dsp.pc, addr); // ErrorLog("%04x DSP ERROR: Read from UNKNOWN (%04x) memory\n", g_dsp.pc, addr);
val = 0; val = 0;
break; break;
} }
return(val); return(val);
} }
bool dsp_dmem_write(uint16 addr, uint16 val) bool dsp_dmem_write(uint16 addr, uint16 val)
{ {
switch (addr >> 12) switch (addr >> 12)
{ {
case 0x8: // 8xxx DROM case 0x8: // 8xxx DROM
DebugLog("someone writes to ROM\n"); DebugLog("someone writes to ROM\n");
/* val = dsp_swap16(val); /* val = dsp_swap16(val);
g_dsp.drom[addr & DSP_DROM_MASK] = val;*/ g_dsp.drom[addr & DSP_DROM_MASK] = val;*/
break; break;
case 0xf: // Fxxx HW regs case 0xf: // Fxxx HW regs
gdsp_ifx_write(addr, val); gdsp_ifx_write(addr, val);
break; break;
case 0x0: // 0xxx DRAM case 0x0: // 0xxx DRAM
val = dsp_swap16(val); val = dsp_swap16(val);
g_dsp.dram[addr & DSP_DRAM_MASK] = val; g_dsp.dram[addr & DSP_DRAM_MASK] = val;
break; break;
default: // error default: // error
DebugLog("%04x DSP ERROR: Write to UNKNOWN (%04x) memory\n", g_dsp.pc, addr); DebugLog("%04x DSP ERROR: Write to UNKNOWN (%04x) memory\n", g_dsp.pc, addr);
break; break;
} }
return(true); return(true);
} }
uint16 dsp_fetch_code(void) uint16 dsp_fetch_code(void)
{ {
uint16 opc = dsp_imem_read(g_dsp.pc); uint16 opc = dsp_imem_read(g_dsp.pc);
g_dsp.pc++; g_dsp.pc++;
return(opc); return(opc);
} }
uint16 dsp_peek_code(void) uint16 dsp_peek_code(void)
{ {
return(dsp_imem_read(g_dsp.pc)); return(dsp_imem_read(g_dsp.pc));
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,62 +1,62 @@
/*==================================================================== /*====================================================================
filename: gdsp_registers.cpp filename: gdsp_registers.cpp
project: GCemu project: GCemu
created: 2004-6-18 created: 2004-6-18
mail: duddie@walla.com mail: duddie@walla.com
Copyright (c) 2005 Duddie & Tratax Copyright (c) 2005 Duddie & Tratax
This program is free software; you can redistribute it and/or This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2 as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version. of the License, or (at your option) any later version.
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 for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
====================================================================*/ ====================================================================*/
#include "Globals.h" #include "Globals.h"
#include "gdsp_registers.h" #include "gdsp_registers.h"
#include "gdsp_interpreter.h" #include "gdsp_interpreter.h"
void dsp_reg_stack_push(uint8 stack_reg) void dsp_reg_stack_push(uint8 stack_reg)
{ {
g_dsp.reg_stack_ptr[stack_reg]++; g_dsp.reg_stack_ptr[stack_reg]++;
g_dsp.reg_stack_ptr[stack_reg] &= DSP_STACK_MASK; g_dsp.reg_stack_ptr[stack_reg] &= DSP_STACK_MASK;
g_dsp.reg_stack[stack_reg][g_dsp.reg_stack_ptr[stack_reg]] = g_dsp.r[DSP_REG_ST0 + stack_reg]; g_dsp.reg_stack[stack_reg][g_dsp.reg_stack_ptr[stack_reg]] = g_dsp.r[DSP_REG_ST0 + stack_reg];
} }
void dsp_reg_stack_pop(uint8 stack_reg) void dsp_reg_stack_pop(uint8 stack_reg)
{ {
g_dsp.r[DSP_REG_ST0 + stack_reg] = g_dsp.reg_stack[stack_reg][g_dsp.reg_stack_ptr[stack_reg]]; g_dsp.r[DSP_REG_ST0 + stack_reg] = g_dsp.reg_stack[stack_reg][g_dsp.reg_stack_ptr[stack_reg]];
g_dsp.reg_stack_ptr[stack_reg]--; g_dsp.reg_stack_ptr[stack_reg]--;
g_dsp.reg_stack_ptr[stack_reg] &= DSP_STACK_MASK; g_dsp.reg_stack_ptr[stack_reg] &= DSP_STACK_MASK;
} }
void dsp_reg_store_stack(uint8 stack_reg, uint16 val) void dsp_reg_store_stack(uint8 stack_reg, uint16 val)
{ {
dsp_reg_stack_push(stack_reg); dsp_reg_stack_push(stack_reg);
g_dsp.r[DSP_REG_ST0 + stack_reg] = val; g_dsp.r[DSP_REG_ST0 + stack_reg] = val;
} }
uint16 dsp_reg_load_stack(uint8 stack_reg) uint16 dsp_reg_load_stack(uint8 stack_reg)
{ {
uint16 val = g_dsp.r[DSP_REG_ST0 + stack_reg]; uint16 val = g_dsp.r[DSP_REG_ST0 + stack_reg];
dsp_reg_stack_pop(stack_reg); dsp_reg_stack_pop(stack_reg);
return(val); return(val);
} }

View File

@ -1,432 +1,432 @@
// 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 "WaveFile.h" #include "WaveFile.h"
#include "CommonTypes.h" #include "CommonTypes.h"
#include "Mixer.h" #include "Mixer.h"
#include "gdsp_interpreter.h" #include "gdsp_interpreter.h"
#include "gdsp_interface.h" #include "gdsp_interface.h"
#include "disassemble.h" #include "disassemble.h"
#ifdef _WIN32 #ifdef _WIN32
#include "DisAsmDlg.h" #include "DisAsmDlg.h"
#include "DSoundStream.h" #include "DSoundStream.h"
#include "Logging/Console.h" // For wprintf, ClearScreen #include "Logging/Console.h" // For wprintf, ClearScreen
#include "Logging/Logging.h" // For Logging #include "Logging/Logging.h" // For Logging
HINSTANCE g_hInstance = NULL; HINSTANCE g_hInstance = NULL;
HANDLE g_hDSPThread = NULL; HANDLE g_hDSPThread = NULL;
CRITICAL_SECTION g_CriticalSection; CRITICAL_SECTION g_CriticalSection;
CDisAsmDlg g_Dialog; CDisAsmDlg g_Dialog;
#else #else
#define WINAPI #define WINAPI
#define LPVOID void* #define LPVOID void*
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <pthread.h> #include <pthread.h>
#include "AOSoundStream.h" #include "AOSoundStream.h"
pthread_t g_hDSPThread = NULL; pthread_t g_hDSPThread = NULL;
#endif #endif
#include "ChunkFile.h" #include "ChunkFile.h"
// ======================================================================================= // =======================================================================================
// Globals // Globals
// -------------- // --------------
DSPInitialize g_dspInitialize; DSPInitialize g_dspInitialize;
#define GDSP_MBOX_CPU 0 #define GDSP_MBOX_CPU 0
#define GDSP_MBOX_DSP 1 #define GDSP_MBOX_DSP 1
uint32 g_LastDMAAddress = 0; uint32 g_LastDMAAddress = 0;
uint32 g_LastDMASize = 0; uint32 g_LastDMASize = 0;
extern u32 m_addressPBs; extern u32 m_addressPBs;
bool AXTask(u32& _uMail); bool AXTask(u32& _uMail);
bool bCanWork = false; bool bCanWork = false;
// Set this if you want to log audio. search for log_ai in this file to see the filename. // Set this if you want to log audio. search for log_ai in this file to see the filename.
static bool log_ai = false; static bool log_ai = false;
WaveFileWriter g_wave_writer; WaveFileWriter g_wave_writer;
// ============== // ==============
#ifdef _WIN32 #ifdef _WIN32
BOOL APIENTRY DllMain(HINSTANCE hinstDLL, // DLL module handle BOOL APIENTRY DllMain(HINSTANCE hinstDLL, // DLL module handle
DWORD dwReason, // reason called DWORD dwReason, // reason called
LPVOID lpvReserved) // reserved LPVOID lpvReserved) // reserved
{ {
switch (dwReason) switch (dwReason)
{ {
case DLL_PROCESS_ATTACH: case DLL_PROCESS_ATTACH:
break; break;
case DLL_PROCESS_DETACH: case DLL_PROCESS_DETACH:
break; break;
default: default:
break; break;
} }
g_hInstance = hinstDLL; g_hInstance = hinstDLL;
return(TRUE); return(TRUE);
} }
#endif #endif
void GetDllInfo(PLUGIN_INFO* _PluginInfo) void GetDllInfo(PLUGIN_INFO* _PluginInfo)
{ {
_PluginInfo->Version = 0x0100; _PluginInfo->Version = 0x0100;
_PluginInfo->Type = PLUGIN_TYPE_DSP; _PluginInfo->Type = PLUGIN_TYPE_DSP;
#ifdef DEBUGFAST #ifdef DEBUGFAST
sprintf(_PluginInfo->Name, "Dolphin DSP-LLE Plugin (DebugFast)"); sprintf(_PluginInfo->Name, "Dolphin DSP-LLE Plugin (DebugFast)");
#else #else
#ifndef _DEBUG #ifndef _DEBUG
sprintf(_PluginInfo->Name, "Dolphin DSP-LLE Plugin"); sprintf(_PluginInfo->Name, "Dolphin DSP-LLE Plugin");
#else #else
sprintf(_PluginInfo->Name, "Dolphin DSP-LLE Plugin (Debug)"); sprintf(_PluginInfo->Name, "Dolphin DSP-LLE Plugin (Debug)");
#endif #endif
#endif #endif
} }
void DllAbout(HWND _hParent) void DllAbout(HWND _hParent)
{} {}
void DllConfig(HWND _hParent) void DllConfig(HWND _hParent)
{} {}
void DSP_DoState(unsigned char **ptr, int mode) { void DSP_DoState(unsigned char **ptr, int mode) {
PointerWrap p(ptr, mode); PointerWrap p(ptr, mode);
} }
void DllDebugger(HWND _hParent, bool Show) void DllDebugger(HWND _hParent, bool Show)
{ {
#ifdef _WIN32 #ifdef _WIN32
#if defined (_DEBUG) || defined (DEBUGFAST) #if defined (_DEBUG) || defined (DEBUGFAST)
g_Dialog.Create(NULL); //_hParent); g_Dialog.Create(NULL); //_hParent);
g_Dialog.ShowWindow(SW_SHOW); g_Dialog.ShowWindow(SW_SHOW);
MoveWindow(g_Dialog.m_hWnd, 450,0, 780,530, true); MoveWindow(g_Dialog.m_hWnd, 450,0, 780,530, true);
// Open the console window // Open the console window
startConsoleWin(155, 100, "Sound Debugging"); // give room for 100 rows startConsoleWin(155, 100, "Sound Debugging"); // give room for 100 rows
wprintf("DllDebugger > Console opened\n"); wprintf("DllDebugger > Console opened\n");
// TODO: Make this adjustable from the Debugging window // TODO: Make this adjustable from the Debugging window
MoveWindow(GetConsoleHwnd(), 0,400, 1280,500, true); MoveWindow(GetConsoleHwnd(), 0,400, 1280,500, true);
#else #else
MessageBox(0, "Can't open debugging window in Release build of this plugin.", "DSP LLE", 0); MessageBox(0, "Can't open debugging window in Release build of this plugin.", "DSP LLE", 0);
#endif #endif
#endif #endif
} }
// ======================================================================================= // =======================================================================================
// Regular thread // Regular thread
// -------------- // --------------
#ifdef _WIN32 #ifdef _WIN32
DWORD WINAPI dsp_thread(LPVOID lpParameter) DWORD WINAPI dsp_thread(LPVOID lpParameter)
#else #else
void* dsp_thread(void* lpParameter) void* dsp_thread(void* lpParameter)
#endif #endif
{ {
while (1) while (1)
{ {
if (!gdsp_run()) if (!gdsp_run())
{ {
ErrorLog("*** DSP: CRITICAL ERROR ***\n"); ErrorLog("*** DSP: CRITICAL ERROR ***\n");
//return 0; //return 0;
exit(0); exit(0);
} }
} }
} }
// ============== // ==============
// ======================================================================================= // =======================================================================================
// Debug thread // Debug thread
// -------------- // --------------
#ifdef _WIN32 #ifdef _WIN32
DWORD WINAPI dsp_thread_debug(LPVOID lpParameter) DWORD WINAPI dsp_thread_debug(LPVOID lpParameter)
#else #else
void* dsp_thread_debug(void* lpParameter) void* dsp_thread_debug(void* lpParameter)
#endif #endif
{ {
//if (g_hDSPThread) //if (g_hDSPThread)
//{ //{
// return NULL; // enable this to disable the plugin // return NULL; // enable this to disable the plugin
//} //}
#ifdef _WIN32 #ifdef _WIN32
while (1) while (1)
{ {
Logging(); // logging Logging(); // logging
if (g_Dialog.CanDoStep()) if (g_Dialog.CanDoStep())
{ {
gdsp_runx(1); gdsp_runx(1);
} }
else else
{ {
Sleep(100); Sleep(100);
} }
} }
#endif #endif
return NULL; return NULL;
} }
// ============== // ==============
void DSP_DebugBreak() void DSP_DebugBreak()
{ {
#ifdef _WIN32 #ifdef _WIN32
#if defined(_DEBUG) || defined(DEBUGFAST) #if defined(_DEBUG) || defined(DEBUGFAST)
g_Dialog.DebugBreak(); g_Dialog.DebugBreak();
#endif #endif
#endif #endif
} }
void dspi_req_dsp_irq() void dspi_req_dsp_irq()
{ {
g_dspInitialize.pGenerateDSPInterrupt(); g_dspInitialize.pGenerateDSPInterrupt();
} }
void DSP_Initialize(DSPInitialize _dspInitialize) void DSP_Initialize(DSPInitialize _dspInitialize)
{ {
bCanWork = true; bCanWork = true;
g_dspInitialize = _dspInitialize; g_dspInitialize = _dspInitialize;
gdsp_init(); gdsp_init();
g_dsp.step_counter = 0; g_dsp.step_counter = 0;
g_dsp.cpu_ram = g_dspInitialize.pGetMemoryPointer(0); g_dsp.cpu_ram = g_dspInitialize.pGetMemoryPointer(0);
g_dsp.irq_request = dspi_req_dsp_irq; g_dsp.irq_request = dspi_req_dsp_irq;
gdsp_reset(); gdsp_reset();
if (!gdsp_load_rom((char *)DSP_ROM_FILE)) if (!gdsp_load_rom((char *)DSP_ROM_FILE))
{ {
bCanWork = false; bCanWork = false;
PanicAlert("No DSP ROM"); PanicAlert("No DSP ROM");
ErrorLog("Cannot load DSP ROM\n"); ErrorLog("Cannot load DSP ROM\n");
} }
if (!gdsp_load_coef((char *)DSP_COEF_FILE)) if (!gdsp_load_coef((char *)DSP_COEF_FILE))
{ {
bCanWork = false; bCanWork = false;
PanicAlert("No DSP COEF"); PanicAlert("No DSP COEF");
ErrorLog("Cannot load DSP COEF\n"); ErrorLog("Cannot load DSP COEF\n");
} }
if(!bCanWork) if(!bCanWork)
return; // TODO: Don't let it work return; // TODO: Don't let it work
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
// First create DSP_UCode.bin by setting "#define DUMP_DSP_IMEM 1" in Globals.h. Then // First create DSP_UCode.bin by setting "#define DUMP_DSP_IMEM 1" in Globals.h. Then
// make the disassembled file here. // make the disassembled file here.
// -------------- // --------------
// Dump UCode to file... // Dump UCode to file...
FILE* t = fopen("C:\\_\\DSP_UC_09CD143F.txt", "wb"); FILE* t = fopen("C:\\_\\DSP_UC_09CD143F.txt", "wb");
if (t != NULL) if (t != NULL)
{ {
gd_globals_t gdg; gd_globals_t gdg;
gd_dis_file(&gdg, (char *)"C:\\_\\DSP_UC_09CD143F.bin", t); gd_dis_file(&gdg, (char *)"C:\\_\\DSP_UC_09CD143F.bin", t);
fclose(t); fclose(t);
} }
// -------------- // --------------
#ifdef _WIN32 #ifdef _WIN32
#if defined(_DEBUG) || defined(DEBUGFAST) #if defined(_DEBUG) || defined(DEBUGFAST)
g_hDSPThread = CreateThread(NULL, 0, dsp_thread_debug, 0, 0, NULL); g_hDSPThread = CreateThread(NULL, 0, dsp_thread_debug, 0, 0, NULL);
#else #else
g_hDSPThread = CreateThread(NULL, 0, dsp_thread, 0, 0, NULL); g_hDSPThread = CreateThread(NULL, 0, dsp_thread, 0, 0, NULL);
#endif // DEBUG #endif // DEBUG
#else #else
#if _DEBUG #if _DEBUG
pthread_create(&g_hDSPThread, NULL, dsp_thread_debug, (void *)NULL); pthread_create(&g_hDSPThread, NULL, dsp_thread_debug, (void *)NULL);
#else #else
pthread_create(&g_hDSPThread, NULL, dsp_thread, (void *)NULL); pthread_create(&g_hDSPThread, NULL, dsp_thread, (void *)NULL);
#endif // DEBUG #endif // DEBUG
#endif // WIN32 #endif // WIN32
if (log_ai) { if (log_ai) {
g_wave_writer.Start("C:\\_\\ai_log.wav"); g_wave_writer.Start("C:\\_\\ai_log.wav");
g_wave_writer.SetSkipSilence(false); g_wave_writer.SetSkipSilence(false);
} }
#ifdef _WIN32 #ifdef _WIN32
InitializeCriticalSection(&g_CriticalSection); InitializeCriticalSection(&g_CriticalSection);
DSound::DSound_StartSound((HWND)g_dspInitialize.hWnd, 48000, Mixer); DSound::DSound_StartSound((HWND)g_dspInitialize.hWnd, 48000, Mixer);
#else #else
AOSound::AOSound_StartSound(48000, Mixer); AOSound::AOSound_StartSound(48000, Mixer);
#endif #endif
} }
void DSP_Shutdown(void) void DSP_Shutdown(void)
{ {
if (log_ai) if (log_ai)
g_wave_writer.Stop(); g_wave_writer.Stop();
#ifdef _WIN32 #ifdef _WIN32
if (g_hDSPThread != NULL) if (g_hDSPThread != NULL)
{ {
TerminateThread(g_hDSPThread, 0); TerminateThread(g_hDSPThread, 0);
} }
#else #else
pthread_cancel(g_hDSPThread); pthread_cancel(g_hDSPThread);
#endif #endif
} }
u16 DSP_WriteControlRegister(u16 _uFlag) u16 DSP_WriteControlRegister(u16 _uFlag)
{ {
gdsp_write_cr(_uFlag); gdsp_write_cr(_uFlag);
return(gdsp_read_cr()); return(gdsp_read_cr());
} }
u16 DSP_ReadControlRegister() u16 DSP_ReadControlRegister()
{ {
return(gdsp_read_cr()); return(gdsp_read_cr());
} }
u16 DSP_ReadMailboxHigh(bool _CPUMailbox) u16 DSP_ReadMailboxHigh(bool _CPUMailbox)
{ {
if (_CPUMailbox) if (_CPUMailbox)
{ {
return(gdsp_mbox_read_h(GDSP_MBOX_CPU)); return(gdsp_mbox_read_h(GDSP_MBOX_CPU));
} }
else else
{ {
return(gdsp_mbox_read_h(GDSP_MBOX_DSP)); return(gdsp_mbox_read_h(GDSP_MBOX_DSP));
} }
} }
u16 DSP_ReadMailboxLow(bool _CPUMailbox) u16 DSP_ReadMailboxLow(bool _CPUMailbox)
{ {
if (_CPUMailbox) if (_CPUMailbox)
{ {
return(gdsp_mbox_read_l(GDSP_MBOX_CPU)); return(gdsp_mbox_read_l(GDSP_MBOX_CPU));
} }
else else
{ {
return(gdsp_mbox_read_l(GDSP_MBOX_DSP)); return(gdsp_mbox_read_l(GDSP_MBOX_DSP));
} }
} }
void DSP_WriteMailboxHigh(bool _CPUMailbox, u16 _uHighMail) void DSP_WriteMailboxHigh(bool _CPUMailbox, u16 _uHighMail)
{ {
if (_CPUMailbox) if (_CPUMailbox)
{ {
if (gdsp_mbox_peek(GDSP_MBOX_CPU) & 0x80000000) if (gdsp_mbox_peek(GDSP_MBOX_CPU) & 0x80000000)
{ {
ErrorLog("Mailbox isnt empty ... strange"); ErrorLog("Mailbox isnt empty ... strange");
} }
#if PROFILE #if PROFILE
if ((_uHighMail) == 0xBABE) if ((_uHighMail) == 0xBABE)
{ {
ProfilerStart(); ProfilerStart();
} }
#endif #endif
gdsp_mbox_write_h(GDSP_MBOX_CPU, _uHighMail); gdsp_mbox_write_h(GDSP_MBOX_CPU, _uHighMail);
} }
else else
{ {
ErrorLog("CPU cant write to DSP mailbox"); ErrorLog("CPU cant write to DSP mailbox");
} }
} }
void DSP_WriteMailboxLow(bool _CPUMailbox, u16 _uLowMail) void DSP_WriteMailboxLow(bool _CPUMailbox, u16 _uLowMail)
{ {
if (_CPUMailbox) if (_CPUMailbox)
{ {
gdsp_mbox_write_l(GDSP_MBOX_CPU, _uLowMail); gdsp_mbox_write_l(GDSP_MBOX_CPU, _uLowMail);
u32 uAddress = gdsp_mbox_peek(GDSP_MBOX_CPU); u32 uAddress = gdsp_mbox_peek(GDSP_MBOX_CPU);
u16 errpc = g_dsp.err_pc; u16 errpc = g_dsp.err_pc;
DebugLog("Write CPU Mail: 0x%08x (pc=0x%04x)\n", uAddress, errpc); DebugLog("Write CPU Mail: 0x%08x (pc=0x%04x)\n", uAddress, errpc);
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
// I couldn't find any better way to detect the AX mails so this had to do. Please feel free // I couldn't find any better way to detect the AX mails so this had to do. Please feel free
// to change it. // to change it.
// -------------- // --------------
if ((errpc == 0x0054 || errpc == 0x0055) && m_addressPBs == 0) if ((errpc == 0x0054 || errpc == 0x0055) && m_addressPBs == 0)
{ {
DebugLog("AXTask ======== 0x%08x (pc=0x%04x)", uAddress, errpc); DebugLog("AXTask ======== 0x%08x (pc=0x%04x)", uAddress, errpc);
AXTask(uAddress); AXTask(uAddress);
} }
} }
else else
{ {
ErrorLog("CPU cant write to DSP mailbox"); ErrorLog("CPU cant write to DSP mailbox");
} }
} }
void DSP_Update(int cycles) void DSP_Update(int cycles)
{ {
if (g_hDSPThread) if (g_hDSPThread)
{ {
return; return;
} }
#ifdef _WIN32 #ifdef _WIN32
if (g_Dialog.CanDoStep()) if (g_Dialog.CanDoStep())
{ {
gdsp_runx(100); // cycles gdsp_runx(100); // cycles
} }
#endif #endif
} }
void DSP_SendAIBuffer(unsigned int address, int sample_rate) void DSP_SendAIBuffer(unsigned int address, int sample_rate)
{ {
short samples[16] = {0}; // interleaved stereo short samples[16] = {0}; // interleaved stereo
if (address) { if (address) {
for (int i = 0; i < 16; i++) { for (int i = 0; i < 16; i++) {
samples[i] = Memory_Read_U16(address + i * 2); samples[i] = Memory_Read_U16(address + i * 2);
} }
if (log_ai) if (log_ai)
g_wave_writer.AddStereoSamples(samples, 8); g_wave_writer.AddStereoSamples(samples, 8);
} }
Mixer_PushSamples(samples, 32 / 4, sample_rate); Mixer_PushSamples(samples, 32 / 4, sample_rate);
static int counter = 0; static int counter = 0;
counter++; counter++;
#ifdef _WIN32 #ifdef _WIN32
if ((counter & 255) == 0) if ((counter & 255) == 0)
DSound::DSound_UpdateSound(); DSound::DSound_UpdateSound();
#endif #endif
} }
void __Log(int, const char *fmt, ...) void __Log(int, const char *fmt, ...)
{ {
//DebugLog(fmt); //DebugLog(fmt);
} }

View File

@ -1,237 +1,237 @@
/*==================================================================== /*====================================================================
filename: opcodes.cpp filename: opcodes.cpp
project: GameCube DSP Tool (gcdsp) project: GameCube DSP Tool (gcdsp)
created: 2005.03.04 created: 2005.03.04
mail: duddie@walla.com mail: duddie@walla.com
Copyright (c) 2005 Duddie Copyright (c) 2005 Duddie
This program is free software; you can redistribute it and/or This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2 as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version. of the License, or (at your option) any later version.
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 for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
====================================================================*/ ====================================================================*/
#include "Globals.h" #include "Globals.h"
#include "opcodes.h" #include "opcodes.h"
opc_t opcodes[] = opc_t opcodes[] =
{ {
{"NOP", 0x0000, 0xffff, 1, 0, {},}, {"NOP", 0x0000, 0xffff, 1, 0, {},},
{"HALT", 0x0021, 0xffff, 1, 0, {},}, {"HALT", 0x0021, 0xffff, 1, 0, {},},
{"RET", 0x02df, 0xffff, 1, 0, {},}, {"RET", 0x02df, 0xffff, 1, 0, {},},
{"RETEQ", 0x02d5, 0xffff, 1, 0, {},}, {"RETEQ", 0x02d5, 0xffff, 1, 0, {},},
{"RETNZ", 0x02dd, 0xffff, 1, 0, {},}, {"RETNZ", 0x02dd, 0xffff, 1, 0, {},},
{"RTI", 0x02ff, 0xffff, 1, 0, {},}, {"RTI", 0x02ff, 0xffff, 1, 0, {},},
{"CALL", 0x02bf, 0xffff, 2, 1, {{P_VAL, 2, 1, 0, 0xffff}},}, {"CALL", 0x02bf, 0xffff, 2, 1, {{P_VAL, 2, 1, 0, 0xffff}},},
{"CALLNE", 0x02b4, 0xffff, 2, 1, {{P_VAL, 2, 1, 0, 0xffff}},}, {"CALLNE", 0x02b4, 0xffff, 2, 1, {{P_VAL, 2, 1, 0, 0xffff}},},
{"IF_0", 0x0270, 0xffff, 1, 0, {},}, {"IF_0", 0x0270, 0xffff, 1, 0, {},},
{"IF_1", 0x0271, 0xffff, 1, 0, {},}, {"IF_1", 0x0271, 0xffff, 1, 0, {},},
{"IF_2", 0x0272, 0xffff, 1, 0, {},}, {"IF_2", 0x0272, 0xffff, 1, 0, {},},
{"IF_3", 0x0273, 0xffff, 1, 0, {},}, {"IF_3", 0x0273, 0xffff, 1, 0, {},},
{"IF_E", 0x0274, 0xffff, 1, 0, {},}, {"IF_E", 0x0274, 0xffff, 1, 0, {},},
{"IF_Q", 0x0275, 0xffff, 1, 0, {},}, {"IF_Q", 0x0275, 0xffff, 1, 0, {},},
{"IF_R", 0x027c, 0xffff, 1, 0, {},}, {"IF_R", 0x027c, 0xffff, 1, 0, {},},
{"IF_Z", 0x027d, 0xffff, 1, 0, {},}, {"IF_Z", 0x027d, 0xffff, 1, 0, {},},
{"IF_P", 0x027f, 0xffff, 1, 0, {},}, {"IF_P", 0x027f, 0xffff, 1, 0, {},},
{"JX0", 0x0290, 0xffff, 2, 1, {{P_VAL, 2, 1, 0, 0xffff}},}, {"JX0", 0x0290, 0xffff, 2, 1, {{P_VAL, 2, 1, 0, 0xffff}},},
{"JX1", 0x0291, 0xffff, 2, 1, {{P_VAL, 2, 1, 0, 0xffff}},}, {"JX1", 0x0291, 0xffff, 2, 1, {{P_VAL, 2, 1, 0, 0xffff}},},
{"JX2", 0x0292, 0xffff, 2, 1, {{P_VAL, 2, 1, 0, 0xffff}},}, {"JX2", 0x0292, 0xffff, 2, 1, {{P_VAL, 2, 1, 0, 0xffff}},},
{"JX3", 0x0293, 0xffff, 2, 1, {{P_VAL, 2, 1, 0, 0xffff}},}, {"JX3", 0x0293, 0xffff, 2, 1, {{P_VAL, 2, 1, 0, 0xffff}},},
{"JNE", 0x0294, 0xffff, 2, 1, {{P_VAL, 2, 1, 0, 0xffff}},}, {"JNE", 0x0294, 0xffff, 2, 1, {{P_VAL, 2, 1, 0, 0xffff}},},
{"JEQ", 0x0295, 0xffff, 2, 1, {{P_VAL, 2, 1, 0, 0xffff}},}, {"JEQ", 0x0295, 0xffff, 2, 1, {{P_VAL, 2, 1, 0, 0xffff}},},
{"JZR", 0x029c, 0xffff, 2, 1, {{P_VAL, 2, 1, 0, 0xffff}},}, {"JZR", 0x029c, 0xffff, 2, 1, {{P_VAL, 2, 1, 0, 0xffff}},},
{"JNZ", 0x029d, 0xffff, 2, 1, {{P_VAL, 2, 1, 0, 0xffff}},}, {"JNZ", 0x029d, 0xffff, 2, 1, {{P_VAL, 2, 1, 0, 0xffff}},},
{"JMP", 0x029f, 0xffff, 2, 1, {{P_VAL, 2, 1, 0, 0xffff}},}, {"JMP", 0x029f, 0xffff, 2, 1, {{P_VAL, 2, 1, 0, 0xffff}},},
{"DAR", 0x0004, 0xfffc, 1, 1, {{P_REG, 1, 0, 0, 0x0003}},}, {"DAR", 0x0004, 0xfffc, 1, 1, {{P_REG, 1, 0, 0, 0x0003}},},
{"IAR", 0x0008, 0xfffc, 1, 1, {{P_REG, 1, 0, 0, 0x0003}},}, {"IAR", 0x0008, 0xfffc, 1, 1, {{P_REG, 1, 0, 0, 0x0003}},},
{"CALLR", 0x171f, 0xff1f, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}},}, {"CALLR", 0x171f, 0xff1f, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}},},
{"JMPR", 0x170f, 0xff1f, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}},}, {"JMPR", 0x170f, 0xff1f, 1, 1, {{P_REG, 1, 0, 5, 0x00e0}},},
{"SBCLR", 0x1200, 0xfff8, 1, 1, {{P_IMM, 1, 0, 0, 0x0007}},}, {"SBCLR", 0x1200, 0xfff8, 1, 1, {{P_IMM, 1, 0, 0, 0x0007}},},
{"SBSET", 0x1300, 0xfff8, 1, 1, {{P_IMM, 1, 0, 0, 0x0007}},}, {"SBSET", 0x1300, 0xfff8, 1, 1, {{P_IMM, 1, 0, 0, 0x0007}},},
{"LSL", 0x1400, 0xfec0, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x003f}},}, {"LSL", 0x1400, 0xfec0, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x003f}},},
{"LSR", 0x1440, 0xfec0, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x003f}},}, {"LSR", 0x1440, 0xfec0, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x003f}},},
{"ASL", 0x1480, 0xfec0, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x007f}},}, {"ASL", 0x1480, 0xfec0, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x007f}},},
{"ASR", 0x14c0, 0xfec0, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x007f}},}, {"ASR", 0x14c0, 0xfec0, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x007f}},},
{"LRI", 0x0080, 0xffe0, 2, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_IMM, 2, 1, 0, 0xffff}},}, {"LRI", 0x0080, 0xffe0, 2, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_IMM, 2, 1, 0, 0xffff}},},
{"LR", 0x00c0, 0xffe0, 2, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_MEM, 2, 1, 0, 0xffff}},}, {"LR", 0x00c0, 0xffe0, 2, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_MEM, 2, 1, 0, 0xffff}},},
{"SR", 0x00e0, 0xffe0, 2, 2, {{P_MEM, 2, 1, 0, 0xffff}, {P_REG, 1, 0, 0, 0x001f}},}, {"SR", 0x00e0, 0xffe0, 2, 2, {{P_MEM, 2, 1, 0, 0xffff}, {P_REG, 1, 0, 0, 0x001f}},},
{"MRR", 0x1c00, 0xfc00, 1, 2, {{P_REG, 1, 0, 5, 0x03e0}, {P_REG, 1, 0, 0, 0x001f}},}, {"MRR", 0x1c00, 0xfc00, 1, 2, {{P_REG, 1, 0, 5, 0x03e0}, {P_REG, 1, 0, 0, 0x001f}},},
{"SI", 0x1600, 0xff00, 2, 2, {{P_MEM, 1, 0, 0, 0x00ff}, {P_IMM, 2, 1, 0, 0xffff}},}, {"SI", 0x1600, 0xff00, 2, 2, {{P_MEM, 1, 0, 0, 0x00ff}, {P_IMM, 2, 1, 0, 0xffff}},},
{"LRS", 0x2000, 0xf800, 1, 2, {{P_REG18, 1, 0, 8, 0x0700}, {P_MEM, 1, 0, 0, 0x00ff}},}, {"LRS", 0x2000, 0xf800, 1, 2, {{P_REG18, 1, 0, 8, 0x0700}, {P_MEM, 1, 0, 0, 0x00ff}},},
{"SRS", 0x2800, 0xf800, 1, 2, {{P_MEM, 1, 0, 0, 0x00ff}, {P_REG18, 1, 0, 8, 0x0700}},}, {"SRS", 0x2800, 0xf800, 1, 2, {{P_MEM, 1, 0, 0, 0x00ff}, {P_REG18, 1, 0, 8, 0x0700}},},
{"LRIS", 0x0800, 0xf800, 1, 2, {{P_REG18, 1, 0, 8, 0x0700}, {P_IMM, 1, 0, 0, 0x00ff}},}, {"LRIS", 0x0800, 0xf800, 1, 2, {{P_REG18, 1, 0, 8, 0x0700}, {P_IMM, 1, 0, 0, 0x00ff}},},
{"ADDIS", 0x0400, 0xfe00, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x00ff}},}, {"ADDIS", 0x0400, 0xfe00, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x00ff}},},
{"CMPIS", 0x0600, 0xfe00, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x00ff}},}, {"CMPIS", 0x0600, 0xfe00, 1, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 1, 0, 0, 0x00ff}},},
{"ANDI", 0x0240, 0xfeff, 2, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}},}, {"ANDI", 0x0240, 0xfeff, 2, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}},},
{"ANDF", 0x02c0, 0xfeff, 2, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}},}, {"ANDF", 0x02c0, 0xfeff, 2, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}},},
{"XORI", 0x0220, 0xfeff, 2, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}},}, {"XORI", 0x0220, 0xfeff, 2, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}},},
{"ANDCF", 0x02a0, 0xfeff, 2, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}},}, {"ANDCF", 0x02a0, 0xfeff, 2, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}},},
{"ORI", 0x0260, 0xfeff, 2, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}},}, {"ORI", 0x0260, 0xfeff, 2, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}},},
{"ORF", 0x02e0, 0xfeff, 2, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}},}, {"ORF", 0x02e0, 0xfeff, 2, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}},},
{"ADDI", 0x0200, 0xfeff, 2, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}},}, // missing S64 {"ADDI", 0x0200, 0xfeff, 2, 2, {{P_ACC, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}},}, // missing S64
{"CMPI", 0x0280, 0xfeff, 2, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}},}, // missing S64 {"CMPI", 0x0280, 0xfeff, 2, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}},}, // missing S64
{"ILRR", 0x0210, 0xfedc, 1, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_PRG, 1, 0, 0, 0x0003}},}, {"ILRR", 0x0210, 0xfedc, 1, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_PRG, 1, 0, 0, 0x0003}},},
{"ILRRI", 0x0218, 0xfedc, 1, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_PRG, 1, 0, 0, 0x0003}},}, {"ILRRI", 0x0218, 0xfedc, 1, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_PRG, 1, 0, 0, 0x0003}},},
// load and store value pointed by indexing reg and increment; LRR/SRR variants // load and store value pointed by indexing reg and increment; LRR/SRR variants
{"LRRI", 0x1900, 0xff80, 1, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_PRG, 1, 0, 5, 0x0060}},}, {"LRRI", 0x1900, 0xff80, 1, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_PRG, 1, 0, 5, 0x0060}},},
{"LRRD", 0x1880, 0xff80, 1, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_PRG, 1, 0, 5, 0x0060}},}, {"LRRD", 0x1880, 0xff80, 1, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_PRG, 1, 0, 5, 0x0060}},},
{"LRRN", 0x1980, 0xff80, 1, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_PRG, 1, 0, 5, 0x0060}},}, {"LRRN", 0x1980, 0xff80, 1, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_PRG, 1, 0, 5, 0x0060}},},
{"LRR", 0x1800, 0xff80, 1, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_PRG, 1, 0, 5, 0x0060}},}, {"LRR", 0x1800, 0xff80, 1, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_PRG, 1, 0, 5, 0x0060}},},
{"SRRI", 0x1b00, 0xff80, 1, 2, {{P_PRG, 1, 0, 5, 0x0060}, {P_REG, 1, 0, 0, 0x001f}},}, {"SRRI", 0x1b00, 0xff80, 1, 2, {{P_PRG, 1, 0, 5, 0x0060}, {P_REG, 1, 0, 0, 0x001f}},},
{"SRRD", 0x1a80, 0xff80, 1, 2, {{P_PRG, 1, 0, 5, 0x0060}, {P_REG, 1, 0, 0, 0x001f}},}, {"SRRD", 0x1a80, 0xff80, 1, 2, {{P_PRG, 1, 0, 5, 0x0060}, {P_REG, 1, 0, 0, 0x001f}},},
{"SRRN", 0x1b80, 0xff80, 1, 2, {{P_PRG, 1, 0, 5, 0x0060}, {P_REG, 1, 0, 0, 0x001f}},}, {"SRRN", 0x1b80, 0xff80, 1, 2, {{P_PRG, 1, 0, 5, 0x0060}, {P_REG, 1, 0, 0, 0x001f}},},
{"SRR", 0x1a00, 0xff80, 1, 2, {{P_PRG, 1, 0, 5, 0x0060}, {P_REG, 1, 0, 0, 0x001f}},}, {"SRR", 0x1a00, 0xff80, 1, 2, {{P_PRG, 1, 0, 5, 0x0060}, {P_REG, 1, 0, 0, 0x001f}},},
{"LOOPI", 0x1000, 0xff00, 1, 1, {{P_IMM, 1, 0, 0, 0x00ff}},}, {"LOOPI", 0x1000, 0xff00, 1, 1, {{P_IMM, 1, 0, 0, 0x00ff}},},
{"BLOOPI", 0x1100, 0xff00, 2, 2, {{P_IMM, 1, 0, 0, 0x00ff}, {P_VAL, 2, 1, 0, 0xffff}},}, {"BLOOPI", 0x1100, 0xff00, 2, 2, {{P_IMM, 1, 0, 0, 0x00ff}, {P_VAL, 2, 1, 0, 0xffff}},},
{"LOOP", 0x0040, 0xffe0, 1, 1, {{P_REG, 1, 0, 0, 0x001f}},}, {"LOOP", 0x0040, 0xffe0, 1, 1, {{P_REG, 1, 0, 0, 0x001f}},},
{"BLOOP", 0x0060, 0xffe0, 2, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_VAL, 2, 1, 0, 0xffff}},}, {"BLOOP", 0x0060, 0xffe0, 2, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_VAL, 2, 1, 0, 0xffff}},},
// opcodes that can be extended // opcodes that can be extended
// extended opcodes, note size of opcode will be set to 0 // extended opcodes, note size of opcode will be set to 0
{"NX", 0x8000, 0xffff, 1 | P_EXT, 0, {},}, {"NX", 0x8000, 0xffff, 1 | P_EXT, 0, {},},
{"S40", 0x8e00, 0xffff, 1 | P_EXT, 0, {},}, {"S40", 0x8e00, 0xffff, 1 | P_EXT, 0, {},},
{"S16", 0x8f00, 0xffff, 1 | P_EXT, 0, {},}, {"S16", 0x8f00, 0xffff, 1 | P_EXT, 0, {},},
{"M2", 0x8a00, 0xffff, 1 | P_EXT, 0, {},}, {"M2", 0x8a00, 0xffff, 1 | P_EXT, 0, {},},
{"M0", 0x8b00, 0xffff, 1 | P_EXT, 0, {},}, {"M0", 0x8b00, 0xffff, 1 | P_EXT, 0, {},},
{"CLR15", 0x8c00, 0xffff, 1 | P_EXT, 0, {},}, {"CLR15", 0x8c00, 0xffff, 1 | P_EXT, 0, {},},
{"SET15", 0x8d00, 0xffff, 1 | P_EXT, 0, {},}, {"SET15", 0x8d00, 0xffff, 1 | P_EXT, 0, {},},
{"DECM", 0x7800, 0xfeff, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}},}, {"DECM", 0x7800, 0xfeff, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}},},
{"INCM", 0x7400, 0xfeff, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}},}, {"INCM", 0x7400, 0xfeff, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}},},
{"DEC", 0x7a00, 0xfeff, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}},}, {"DEC", 0x7a00, 0xfeff, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}},},
{"INC", 0x7600, 0xfeff, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}},}, {"INC", 0x7600, 0xfeff, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}},},
{"NEG", 0x7c00, 0xfeff, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}},}, {"NEG", 0x7c00, 0xfeff, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}},},
{"TST", 0xb100, 0xf7ff, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 11, 0x0800}},}, {"TST", 0xb100, 0xf7ff, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 11, 0x0800}},},
{"TSTAXH", 0x8600, 0xfeff, 1 | P_EXT, 1, {{P_REG1A, 1, 0, 8, 0x0100}},}, {"TSTAXH", 0x8600, 0xfeff, 1 | P_EXT, 1, {{P_REG1A, 1, 0, 8, 0x0100}},},
{"CMP", 0x8200, 0xffff, 1 | P_EXT, 0, {},}, {"CMP", 0x8200, 0xffff, 1 | P_EXT, 0, {},},
{"CMPAXH", 0xc100, 0xe7ff, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 12, 0x1000}, {P_REG1A, 1, 0, 11, 0x0800}},}, {"CMPAXH", 0xc100, 0xe7ff, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 12, 0x1000}, {P_REG1A, 1, 0, 11, 0x0800}},},
{"CLR", 0x8100, 0xf7ff, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 11, 0x0800}},}, {"CLR", 0x8100, 0xf7ff, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 11, 0x0800}},},
{"CLRP", 0x8400, 0xffff, 1 | P_EXT, 0, {},}, {"CLRP", 0x8400, 0xffff, 1 | P_EXT, 0, {},},
{"MOV", 0x6c00, 0xfeff, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_ACCM_D, 1, 0, 8, 0x0100}},}, {"MOV", 0x6c00, 0xfeff, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_ACCM_D, 1, 0, 8, 0x0100}},},
{"MOVAX", 0x6800, 0xfcff, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG18, 1, 0, 9, 0x0200}},}, {"MOVAX", 0x6800, 0xfcff, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG18, 1, 0, 9, 0x0200}},},
{"MOVR", 0x6000, 0xf8ff, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG18, 1, 0, 9, 0x0600}},}, {"MOVR", 0x6000, 0xf8ff, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG18, 1, 0, 9, 0x0600}},},
{"MOVP", 0x6e00, 0xfeff, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}},}, {"MOVP", 0x6e00, 0xfeff, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}},},
{"MOVPZ", 0xfe00, 0xfeff, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}},}, {"MOVPZ", 0xfe00, 0xfeff, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}},},
{"ADDPAXZ", 0xf800, 0xfcff, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 9, 0x0200}, {P_REG1A, 1, 0, 8, 0x0100}},}, {"ADDPAXZ", 0xf800, 0xfcff, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 9, 0x0200}, {P_REG1A, 1, 0, 8, 0x0100}},},
{"ADDP", 0x4e00, 0xfeff, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}},}, {"ADDP", 0x4e00, 0xfeff, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}},},
{"LSL16", 0xf000, 0xfeff, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}},}, {"LSL16", 0xf000, 0xfeff, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}},},
{"LSR16", 0xf400, 0xfeff, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}},}, {"LSR16", 0xf400, 0xfeff, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}},},
{"ASR16", 0x9100, 0xf7ff, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 11, 0x0800}},}, {"ASR16", 0x9100, 0xf7ff, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 11, 0x0800}},},
{"XORR", 0x3000, 0xfcff, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG1A, 1, 0, 9, 0x0200}},}, {"XORR", 0x3000, 0xfcff, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG1A, 1, 0, 9, 0x0200}},},
{"ANDR", 0x3400, 0xfcff, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG1A, 1, 0, 9, 0x0200}},}, {"ANDR", 0x3400, 0xfcff, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG1A, 1, 0, 9, 0x0200}},},
{"ORR", 0x3800, 0xfcff, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG1A, 1, 0, 9, 0x0200}},}, {"ORR", 0x3800, 0xfcff, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG1A, 1, 0, 9, 0x0200}},},
{"ANDC", 0x3C00, 0xfeff, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}},}, {"ANDC", 0x3C00, 0xfeff, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}},},
{"ORC", 0x3E00, 0xfeff, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}},}, {"ORC", 0x3E00, 0xfeff, 1 | P_EXT, 1, {{P_ACCM, 1, 0, 8, 0x0100}},},
{"MULX", 0xa000, 0xe7ff, 1 | P_EXT, 2, {{P_REG18, 1, 0, 11, 0x1000}, {P_REG19, 1, 0, 10, 0x0800}},}, {"MULX", 0xa000, 0xe7ff, 1 | P_EXT, 2, {{P_REG18, 1, 0, 11, 0x1000}, {P_REG19, 1, 0, 10, 0x0800}},},
{"MULXAC", 0xa400, 0xe6ff, 1 | P_EXT, 3, {{P_REG18, 1, 0, 11, 0x1000}, {P_REG19, 1, 0, 10, 0x0800}, {P_ACCM, 1, 0, 8, 0x0100}},}, {"MULXAC", 0xa400, 0xe6ff, 1 | P_EXT, 3, {{P_REG18, 1, 0, 11, 0x1000}, {P_REG19, 1, 0, 10, 0x0800}, {P_ACCM, 1, 0, 8, 0x0100}},},
{"MULXMV", 0xa600, 0xe6ff, 1 | P_EXT, 3, {{P_REG18, 1, 0, 11, 0x1000}, {P_REG19, 1, 0, 10, 0x0800}, {P_ACCM, 1, 0, 8, 0x0100}},}, {"MULXMV", 0xa600, 0xe6ff, 1 | P_EXT, 3, {{P_REG18, 1, 0, 11, 0x1000}, {P_REG19, 1, 0, 10, 0x0800}, {P_ACCM, 1, 0, 8, 0x0100}},},
{"MULXMVZ", 0xa200, 0xe6ff, 1 | P_EXT, 3, {{P_REG18, 1, 0, 11, 0x1000}, {P_REG19, 1, 0, 10, 0x0800}, {P_ACCM, 1, 0, 8, 0x0100}},}, {"MULXMVZ", 0xa200, 0xe6ff, 1 | P_EXT, 3, {{P_REG18, 1, 0, 11, 0x1000}, {P_REG19, 1, 0, 10, 0x0800}, {P_ACCM, 1, 0, 8, 0x0100}},},
{"MUL", 0x9000, 0xf7ff, 1 | P_EXT, 2, {{P_REG18, 1, 0, 11, 0x0800}, {P_REG1A, 1, 0, 11, 0x0800}},}, {"MUL", 0x9000, 0xf7ff, 1 | P_EXT, 2, {{P_REG18, 1, 0, 11, 0x0800}, {P_REG1A, 1, 0, 11, 0x0800}},},
{"MULAC", 0x9400, 0xf6ff, 1 | P_EXT, 3, {{P_REG18, 1, 0, 11, 0x0800}, {P_REG1A, 1, 0, 11, 0x0800}, {P_ACCM, 1, 0, 8, 0x0100}},}, {"MULAC", 0x9400, 0xf6ff, 1 | P_EXT, 3, {{P_REG18, 1, 0, 11, 0x0800}, {P_REG1A, 1, 0, 11, 0x0800}, {P_ACCM, 1, 0, 8, 0x0100}},},
{"MULMV", 0x9600, 0xf6ff, 1 | P_EXT, 3, {{P_REG18, 1, 0, 11, 0x0800}, {P_REG1A, 1, 0, 11, 0x0800}, {P_ACCM, 1, 0, 8, 0x0100}},}, {"MULMV", 0x9600, 0xf6ff, 1 | P_EXT, 3, {{P_REG18, 1, 0, 11, 0x0800}, {P_REG1A, 1, 0, 11, 0x0800}, {P_ACCM, 1, 0, 8, 0x0100}},},
{"MULMVZ", 0x9200, 0xf6ff, 1 | P_EXT, 3, {{P_REG18, 1, 0, 11, 0x0800}, {P_REG1A, 1, 0, 11, 0x0800}, {P_ACCM, 1, 0, 8, 0x0100}},}, {"MULMVZ", 0x9200, 0xf6ff, 1 | P_EXT, 3, {{P_REG18, 1, 0, 11, 0x0800}, {P_REG1A, 1, 0, 11, 0x0800}, {P_ACCM, 1, 0, 8, 0x0100}},},
{"MULC", 0xc000, 0xe7ff, 1 | P_EXT, 2, {{P_REG1A, 1, 0, 11, 0x0800}, {P_ACCM, 1, 0, 12, 0x1000}},}, {"MULC", 0xc000, 0xe7ff, 1 | P_EXT, 2, {{P_REG1A, 1, 0, 11, 0x0800}, {P_ACCM, 1, 0, 12, 0x1000}},},
{"MULCAC", 0xc400, 0xe6ff, 1 | P_EXT, 3, {{P_REG1A, 1, 0, 11, 0x0800}, {P_ACCM, 1, 0, 12, 0x1000}, {P_ACCM, 1, 0, 8, 0x0100}},}, {"MULCAC", 0xc400, 0xe6ff, 1 | P_EXT, 3, {{P_REG1A, 1, 0, 11, 0x0800}, {P_ACCM, 1, 0, 12, 0x1000}, {P_ACCM, 1, 0, 8, 0x0100}},},
{"MULCMV", 0xc600, 0xe6ff, 1 | P_EXT, 3, {{P_REG1A, 1, 0, 11, 0x0800}, {P_ACCM, 1, 0, 12, 0x1000}, {P_ACCM, 1, 0, 8, 0x0100}},}, {"MULCMV", 0xc600, 0xe6ff, 1 | P_EXT, 3, {{P_REG1A, 1, 0, 11, 0x0800}, {P_ACCM, 1, 0, 12, 0x1000}, {P_ACCM, 1, 0, 8, 0x0100}},},
{"MULCMVZ", 0xc200, 0xe6ff, 1 | P_EXT, 3, {{P_REG1A, 1, 0, 11, 0x0800}, {P_ACCM, 1, 0, 12, 0x1000}, {P_ACCM, 1, 0, 8, 0x0100}},}, {"MULCMVZ", 0xc200, 0xe6ff, 1 | P_EXT, 3, {{P_REG1A, 1, 0, 11, 0x0800}, {P_ACCM, 1, 0, 12, 0x1000}, {P_ACCM, 1, 0, 8, 0x0100}},},
{"ADDR", 0x4000, 0xf8ff, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG18, 1, 0, 9, 0x0600}},}, {"ADDR", 0x4000, 0xf8ff, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG18, 1, 0, 9, 0x0600}},},
{"ADDAX", 0x4800, 0xfcff, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG18, 1, 0, 9, 0x0200}},}, {"ADDAX", 0x4800, 0xfcff, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG18, 1, 0, 9, 0x0200}},},
{"ADD", 0x4c00, 0xfeff, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_ACCM_D, 1, 0, 8, 0x0100}},}, {"ADD", 0x4c00, 0xfeff, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_ACCM_D, 1, 0, 8, 0x0100}},},
{"ADDAXL", 0x7000, 0xfcff, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG18, 1, 0, 9, 0x0200}},}, {"ADDAXL", 0x7000, 0xfcff, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG18, 1, 0, 9, 0x0200}},},
{"SUBR", 0x5000, 0xf8ff, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG18, 1, 0, 9, 0x0600}},}, {"SUBR", 0x5000, 0xf8ff, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG18, 1, 0, 9, 0x0600}},},
{"SUBAX", 0x5800, 0xfcff, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG18, 1, 0, 9, 0x0200}},}, {"SUBAX", 0x5800, 0xfcff, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_REG18, 1, 0, 9, 0x0200}},},
{"SUB", 0x5c00, 0xfeff, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_ACCM_D, 1, 0, 8, 0x0100}},}, {"SUB", 0x5c00, 0xfeff, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_ACCM_D, 1, 0, 8, 0x0100}},},
{"MADD", 0xf200, 0xfeff, 1 | P_EXT, 2, {{P_REG18, 1, 0, 8, 0x0100}, {P_REG1A, 1, 0, 8, 0x0100}},}, {"MADD", 0xf200, 0xfeff, 1 | P_EXT, 2, {{P_REG18, 1, 0, 8, 0x0100}, {P_REG1A, 1, 0, 8, 0x0100}},},
{"MSUB", 0xf600, 0xfeff, 1 | P_EXT, 2, {{P_REG18, 1, 0, 8, 0x0100}, {P_REG1A, 1, 0, 8, 0x0100}},}, {"MSUB", 0xf600, 0xfeff, 1 | P_EXT, 2, {{P_REG18, 1, 0, 8, 0x0100}, {P_REG1A, 1, 0, 8, 0x0100}},},
{"MADDX", 0xe000, 0xfcff, 1 | P_EXT, 2, {{P_REG18, 1, 0, 8, 0x0200}, {P_REG19, 1, 0, 7, 0x0100}},}, {"MADDX", 0xe000, 0xfcff, 1 | P_EXT, 2, {{P_REG18, 1, 0, 8, 0x0200}, {P_REG19, 1, 0, 7, 0x0100}},},
{"MSUBX", 0xe400, 0xfcff, 1 | P_EXT, 2, {{P_REG18, 1, 0, 8, 0x0200}, {P_REG19, 1, 0, 7, 0x0100}},}, {"MSUBX", 0xe400, 0xfcff, 1 | P_EXT, 2, {{P_REG18, 1, 0, 8, 0x0200}, {P_REG19, 1, 0, 7, 0x0100}},},
{"MADDC", 0xe800, 0xfcff, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 9, 0x0200}, {P_REG19, 1, 0, 7, 0x0100}},}, {"MADDC", 0xe800, 0xfcff, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 9, 0x0200}, {P_REG19, 1, 0, 7, 0x0100}},},
{"MSUBC", 0xec00, 0xfcff, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 9, 0x0200}, {P_REG19, 1, 0, 7, 0x0100}},}, {"MSUBC", 0xec00, 0xfcff, 1 | P_EXT, 2, {{P_ACCM, 1, 0, 9, 0x0200}, {P_REG19, 1, 0, 7, 0x0100}},},
// assemble CW // assemble CW
{"CW", 0x0000, 0xffff, 1, 1, {{P_VAL, 2, 0, 0, 0xffff}},}, {"CW", 0x0000, 0xffff, 1, 1, {{P_VAL, 2, 0, 0, 0xffff}},},
// unknown opcode for disassemble // unknown opcode for disassemble
{"CW", 0x0000, 0x0000, 1, 1, {{P_VAL, 2, 0, 0, 0xffff}},}, {"CW", 0x0000, 0x0000, 1, 1, {{P_VAL, 2, 0, 0, 0xffff}},},
}; };
opc_t opcodes_ext[] = opc_t opcodes_ext[] =
{ {
{"L", 0x0040, 0x00c4, 1, 2, {{P_REG18, 1, 0, 3, 0x0038}, {P_PRG, 1, 0, 0, 0x0003}},}, {"L", 0x0040, 0x00c4, 1, 2, {{P_REG18, 1, 0, 3, 0x0038}, {P_PRG, 1, 0, 0, 0x0003}},},
{"LN", 0x0044, 0x00c4, 1, 2, {{P_REG18, 1, 0, 3, 0x0038}, {P_PRG, 1, 0, 0, 0x0003}},}, {"LN", 0x0044, 0x00c4, 1, 2, {{P_REG18, 1, 0, 3, 0x0038}, {P_PRG, 1, 0, 0, 0x0003}},},
{"LS", 0x0080, 0x00ce, 1, 2, {{P_REG18, 1, 0, 4, 0x0030}, {P_ACCM, 1, 0, 0, 0x0001}},}, {"LS", 0x0080, 0x00ce, 1, 2, {{P_REG18, 1, 0, 4, 0x0030}, {P_ACCM, 1, 0, 0, 0x0001}},},
{"LSN", 0x0084, 0x00ce, 1, 2, {{P_REG18, 1, 0, 4, 0x0030}, {P_ACCM, 1, 0, 0, 0x0001}},}, {"LSN", 0x0084, 0x00ce, 1, 2, {{P_REG18, 1, 0, 4, 0x0030}, {P_ACCM, 1, 0, 0, 0x0001}},},
{"LSM", 0x0088, 0x00ce, 1, 2, {{P_REG18, 1, 0, 4, 0x0030}, {P_ACCM, 1, 0, 0, 0x0001}},}, {"LSM", 0x0088, 0x00ce, 1, 2, {{P_REG18, 1, 0, 4, 0x0030}, {P_ACCM, 1, 0, 0, 0x0001}},},
{"LSNM", 0x008c, 0x00ce, 1, 2, {{P_REG18, 1, 0, 4, 0x0030}, {P_ACCM, 1, 0, 0, 0x0001}},}, {"LSNM", 0x008c, 0x00ce, 1, 2, {{P_REG18, 1, 0, 4, 0x0030}, {P_ACCM, 1, 0, 0, 0x0001}},},
{"SL", 0x0082, 0x00ce, 1, 2, {{P_ACCM, 1, 0, 0, 0x0001}, {P_REG18, 1, 0, 4, 0x0030}},}, {"SL", 0x0082, 0x00ce, 1, 2, {{P_ACCM, 1, 0, 0, 0x0001}, {P_REG18, 1, 0, 4, 0x0030}},},
{"SLN", 0x0086, 0x00ce, 1, 2, {{P_ACCM, 1, 0, 0, 0x0001}, {P_REG18, 1, 0, 4, 0x0030}},}, {"SLN", 0x0086, 0x00ce, 1, 2, {{P_ACCM, 1, 0, 0, 0x0001}, {P_REG18, 1, 0, 4, 0x0030}},},
{"SLM", 0x008a, 0x00ce, 1, 2, {{P_ACCM, 1, 0, 0, 0x0001}, {P_REG18, 1, 0, 4, 0x0030}},}, {"SLM", 0x008a, 0x00ce, 1, 2, {{P_ACCM, 1, 0, 0, 0x0001}, {P_REG18, 1, 0, 4, 0x0030}},},
{"SLNM", 0x008e, 0x00ce, 1, 2, {{P_ACCM, 1, 0, 0, 0x0001}, {P_REG18, 1, 0, 4, 0x0030}},}, {"SLNM", 0x008e, 0x00ce, 1, 2, {{P_ACCM, 1, 0, 0, 0x0001}, {P_REG18, 1, 0, 4, 0x0030}},},
{"S", 0x0020, 0x00e4, 1, 2, {{P_PRG, 1, 0, 0, 0x0003}, {P_REG1C, 1, 0, 3, 0x0018}},}, {"S", 0x0020, 0x00e4, 1, 2, {{P_PRG, 1, 0, 0, 0x0003}, {P_REG1C, 1, 0, 3, 0x0018}},},
{"SN", 0x0024, 0x00e4, 1, 2, {{P_PRG, 1, 0, 0, 0x0003}, {P_REG1C, 1, 0, 3, 0x0018}},}, {"SN", 0x0024, 0x00e4, 1, 2, {{P_PRG, 1, 0, 0, 0x0003}, {P_REG1C, 1, 0, 3, 0x0018}},},
{"LDX", 0x00c0, 0x00cf, 1, 3, {{P_REG18, 1, 0, 4, 0x0010}, {P_REG1A, 1, 0, 4, 0x0010}, {P_PRG, 1, 0, 5, 0x0020}},}, {"LDX", 0x00c0, 0x00cf, 1, 3, {{P_REG18, 1, 0, 4, 0x0010}, {P_REG1A, 1, 0, 4, 0x0010}, {P_PRG, 1, 0, 5, 0x0020}},},
{"LDXN", 0x00c4, 0x00cf, 1, 3, {{P_REG18, 1, 0, 4, 0x0010}, {P_REG1A, 1, 0, 4, 0x0010}, {P_PRG, 1, 0, 5, 0x0020}},}, {"LDXN", 0x00c4, 0x00cf, 1, 3, {{P_REG18, 1, 0, 4, 0x0010}, {P_REG1A, 1, 0, 4, 0x0010}, {P_PRG, 1, 0, 5, 0x0020}},},
{"LDXM", 0x00c8, 0x00cf, 1, 3, {{P_REG18, 1, 0, 4, 0x0010}, {P_REG1A, 1, 0, 4, 0x0010}, {P_PRG, 1, 0, 5, 0x0020}},}, {"LDXM", 0x00c8, 0x00cf, 1, 3, {{P_REG18, 1, 0, 4, 0x0010}, {P_REG1A, 1, 0, 4, 0x0010}, {P_PRG, 1, 0, 5, 0x0020}},},
{"LDXNM", 0x00cc, 0x00cf, 1, 3, {{P_REG18, 1, 0, 4, 0x0010}, {P_REG1A, 1, 0, 4, 0x0010}, {P_PRG, 1, 0, 5, 0x0020}},}, {"LDXNM", 0x00cc, 0x00cf, 1, 3, {{P_REG18, 1, 0, 4, 0x0010}, {P_REG1A, 1, 0, 4, 0x0010}, {P_PRG, 1, 0, 5, 0x0020}},},
{"LD", 0x00c0, 0x00cc, 1, 3, {{P_REG18, 1, 0, 4, 0x0020}, {P_REG19, 1, 0, 3, 0x0010}, {P_PRG, 1, 0, 0, 0x0003}},}, {"LD", 0x00c0, 0x00cc, 1, 3, {{P_REG18, 1, 0, 4, 0x0020}, {P_REG19, 1, 0, 3, 0x0010}, {P_PRG, 1, 0, 0, 0x0003}},},
{"LDN", 0x00c4, 0x00cc, 1, 3, {{P_REG18, 1, 0, 4, 0x0020}, {P_REG19, 1, 0, 3, 0x0010}, {P_PRG, 1, 0, 0, 0x0003}},}, {"LDN", 0x00c4, 0x00cc, 1, 3, {{P_REG18, 1, 0, 4, 0x0020}, {P_REG19, 1, 0, 3, 0x0010}, {P_PRG, 1, 0, 0, 0x0003}},},
{"LDM", 0x00c8, 0x00cc, 1, 3, {{P_REG18, 1, 0, 4, 0x0020}, {P_REG19, 1, 0, 3, 0x0010}, {P_PRG, 1, 0, 0, 0x0003}},}, {"LDM", 0x00c8, 0x00cc, 1, 3, {{P_REG18, 1, 0, 4, 0x0020}, {P_REG19, 1, 0, 3, 0x0010}, {P_PRG, 1, 0, 0, 0x0003}},},
{"LDNM", 0x00cc, 0x00cc, 1, 3, {{P_REG18, 1, 0, 4, 0x0020}, {P_REG19, 1, 0, 3, 0x0010}, {P_PRG, 1, 0, 0, 0x0003}},}, {"LDNM", 0x00cc, 0x00cc, 1, 3, {{P_REG18, 1, 0, 4, 0x0020}, {P_REG19, 1, 0, 3, 0x0010}, {P_PRG, 1, 0, 0, 0x0003}},},
{"MV", 0x0010, 0x00f0, 1, 2, {{P_REG18, 1, 0, 2, 0x000c}, {P_REG1C, 1, 0, 0, 0x0003}},}, {"MV", 0x0010, 0x00f0, 1, 2, {{P_REG18, 1, 0, 2, 0x000c}, {P_REG1C, 1, 0, 0, 0x0003}},},
{"DR", 0x0004, 0x00fc, 1, 1, {{P_REG, 1, 0, 0, 0x0003}},}, {"DR", 0x0004, 0x00fc, 1, 1, {{P_REG, 1, 0, 0, 0x0003}},},
{"IR", 0x0008, 0x00fc, 1, 1, {{P_REG, 1, 0, 0, 0x0003}},}, {"IR", 0x0008, 0x00fc, 1, 1, {{P_REG, 1, 0, 0, 0x0003}},},
{"NR", 0x000c, 0x00fc, 1, 1, {{P_REG, 1, 0, 0, 0x0003}},}, {"NR", 0x000c, 0x00fc, 1, 1, {{P_REG, 1, 0, 0, 0x0003}},},
{"XXX", 0x0000, 0x0000, 1, 1, {{P_VAL, 1, 0, 0, 0x00ff}},}, {"XXX", 0x0000, 0x0000, 1, 1, {{P_VAL, 1, 0, 0, 0x00ff}},},
}; };
const uint32 opcodes_size = sizeof(opcodes) / sizeof(opc_t); const uint32 opcodes_size = sizeof(opcodes) / sizeof(opc_t);
const uint32 opcodes_ext_size = sizeof(opcodes_ext) / sizeof(opc_t); const uint32 opcodes_ext_size = sizeof(opcodes_ext) / sizeof(opc_t);

View File

@ -1,19 +1,19 @@
// 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 "stdafx.h" #include "stdafx.h"

View File

@ -1,86 +1,86 @@
// 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 "DSPHandler.h" #include "DSPHandler.h"
CDSPHandler* CDSPHandler::m_pInstance = NULL; CDSPHandler* CDSPHandler::m_pInstance = NULL;
CDSPHandler::CDSPHandler() CDSPHandler::CDSPHandler()
: m_pUCode(NULL), : m_pUCode(NULL),
m_bHalt(false), m_bHalt(false),
m_bAssertInt(false) m_bAssertInt(false)
{ {
SetUCode(UCODE_ROM); SetUCode(UCODE_ROM);
m_DSPControl.DSPHalt = 1; m_DSPControl.DSPHalt = 1;
m_DSPControl.DSPInit = 1; m_DSPControl.DSPInit = 1;
} }
CDSPHandler::~CDSPHandler() CDSPHandler::~CDSPHandler()
{ {
delete m_pUCode; delete m_pUCode;
m_pUCode = NULL; m_pUCode = NULL;
} }
void CDSPHandler::Update() void CDSPHandler::Update()
{ {
if (m_pUCode != NULL) if (m_pUCode != NULL)
m_pUCode->Update(); m_pUCode->Update();
} }
unsigned short CDSPHandler::WriteControlRegister(unsigned short _Value) unsigned short CDSPHandler::WriteControlRegister(unsigned short _Value)
{ {
UDSPControl Temp(_Value); UDSPControl Temp(_Value);
if (Temp.DSPReset) if (Temp.DSPReset)
{ {
SetUCode(UCODE_ROM); SetUCode(UCODE_ROM);
Temp.DSPReset = 0; Temp.DSPReset = 0;
} }
if (Temp.DSPInit == 0) if (Temp.DSPInit == 0)
{ {
// copy 128 byte from ARAM 0x000000 to IMEM // copy 128 byte from ARAM 0x000000 to IMEM
SetUCode(UCODE_INIT_AUDIO_SYSTEM); SetUCode(UCODE_INIT_AUDIO_SYSTEM);
Temp.DSPInitCode = 0; Temp.DSPInitCode = 0;
// MessageBox(NULL, "UCODE_INIT_AUDIO_SYSTEM", "DSP-HLE", MB_OK); // MessageBox(NULL, "UCODE_INIT_AUDIO_SYSTEM", "DSP-HLE", MB_OK);
} }
m_DSPControl.Hex = Temp.Hex; m_DSPControl.Hex = Temp.Hex;
return m_DSPControl.Hex; return m_DSPControl.Hex;
} }
unsigned short CDSPHandler::ReadControlRegister() unsigned short CDSPHandler::ReadControlRegister()
{ {
return m_DSPControl.Hex; return m_DSPControl.Hex;
} }
void CDSPHandler::SendMailToDSP(u32 _uMail) void CDSPHandler::SendMailToDSP(u32 _uMail)
{ {
if (m_pUCode != NULL) if (m_pUCode != NULL)
m_pUCode->HandleMail(_uMail); m_pUCode->HandleMail(_uMail);
} }
IUCode* CDSPHandler::GetUCode() IUCode* CDSPHandler::GetUCode()
{ {
return m_pUCode; return m_pUCode;
} }
void CDSPHandler::SetUCode(u32 _crc) void CDSPHandler::SetUCode(u32 _crc)
{ {
delete m_pUCode; delete m_pUCode;
m_pUCode = NULL; m_pUCode = NULL;
m_MailHandler.Clear(); m_MailHandler.Clear();
m_pUCode = UCodeFactory(_crc, m_MailHandler); m_pUCode = UCodeFactory(_crc, m_MailHandler);
} }

View File

@ -1,53 +1,53 @@
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h> #include <stdio.h>
#include "Common.h" #include "Common.h"
#include "Globals.h" #include "Globals.h"
void __Log(int, const char *fmt, ...) void __Log(int, const char *fmt, ...)
{ {
DebugLog(fmt); DebugLog(fmt);
} }
void DebugLog(const char* _fmt, ...) void DebugLog(const char* _fmt, ...)
{ {
#ifdef _DEBUG #ifdef _DEBUG
char Msg[512]; char Msg[512];
va_list ap; va_list ap;
va_start(ap, _fmt); va_start(ap, _fmt);
vsprintf(Msg, _fmt, ap); vsprintf(Msg, _fmt, ap);
va_end(ap); va_end(ap);
g_dspInitialize.pLog(Msg, FALSE); g_dspInitialize.pLog(Msg, FALSE);
#endif #endif
} }
extern u8* g_pMemory; extern u8* g_pMemory;
// TODO: Wii support? Most likely audio data still must be in the old 24MB TRAM. // TODO: Wii support? Most likely audio data still must be in the old 24MB TRAM.
#define RAM_MASK 0x1FFFFFF #define RAM_MASK 0x1FFFFFF
u8 Memory_Read_U8(u32 _uAddress) u8 Memory_Read_U8(u32 _uAddress)
{ {
_uAddress &= RAM_MASK; _uAddress &= RAM_MASK;
return g_pMemory[_uAddress]; return g_pMemory[_uAddress];
} }
u16 Memory_Read_U16(u32 _uAddress) u16 Memory_Read_U16(u32 _uAddress)
{ {
_uAddress &= RAM_MASK; _uAddress &= RAM_MASK;
return Common::swap16(*(u16*)&g_pMemory[_uAddress]); return Common::swap16(*(u16*)&g_pMemory[_uAddress]);
} }
u32 Memory_Read_U32(u32 _uAddress) u32 Memory_Read_U32(u32 _uAddress)
{ {
_uAddress &= RAM_MASK; _uAddress &= RAM_MASK;
return Common::swap32(*(u32*)&g_pMemory[_uAddress]); return Common::swap32(*(u32*)&g_pMemory[_uAddress]);
} }
float Memory_Read_Float(u32 _uAddress) float Memory_Read_Float(u32 _uAddress)
{ {
u32 uTemp = Memory_Read_U32(_uAddress); u32 uTemp = Memory_Read_U32(_uAddress);
return *(float*)&uTemp; return *(float*)&uTemp;
} }

View File

@ -1,96 +1,96 @@
// 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 "MailHandler.h" #include "MailHandler.h"
CMailHandler::CMailHandler() CMailHandler::CMailHandler()
{ {
} }
CMailHandler::~CMailHandler() CMailHandler::~CMailHandler()
{ {
Clear(); Clear();
} }
void CMailHandler::PushMail(u32 _Mail) void CMailHandler::PushMail(u32 _Mail)
{ {
m_Mails.push(_Mail); m_Mails.push(_Mail);
Update(); Update();
} }
u16 CMailHandler::ReadDSPMailboxHigh() u16 CMailHandler::ReadDSPMailboxHigh()
{ {
// check if we have a mail for the core // check if we have a mail for the core
if (!m_Mails.empty()) if (!m_Mails.empty())
{ {
u16 result = (m_Mails.front() >> 16) & 0xFFFF; u16 result = (m_Mails.front() >> 16) & 0xFFFF;
Update(); Update();
return result; return result;
} }
return 0x00; return 0x00;
} }
u16 CMailHandler::ReadDSPMailboxLow() u16 CMailHandler::ReadDSPMailboxLow()
{ {
// check if we have a mail for the core // check if we have a mail for the core
if (!m_Mails.empty()) if (!m_Mails.empty())
{ {
u16 result = m_Mails.front() & 0xFFFF; u16 result = m_Mails.front() & 0xFFFF;
m_Mails.pop(); m_Mails.pop();
Update(); Update();
return(result); return(result);
} }
return 0x00; return 0x00;
} }
void CMailHandler::Clear() void CMailHandler::Clear()
{ {
while (!m_Mails.empty()) while (!m_Mails.empty())
m_Mails.pop(); m_Mails.pop();
} }
bool CMailHandler::IsEmpty() bool CMailHandler::IsEmpty()
{ {
return m_Mails.empty(); return m_Mails.empty();
} }
void CMailHandler::Halt(bool _Halt) void CMailHandler::Halt(bool _Halt)
{ {
if (_Halt) if (_Halt)
{ {
Clear(); Clear();
m_Mails.push(0x80544348); m_Mails.push(0x80544348);
} }
Update(); Update();
} }
void CMailHandler::Update() void CMailHandler::Update()
{ {
if (!IsEmpty()) if (!IsEmpty())
{ {
// g_dspInitialize.pGenerateDSPInterrupt(); // g_dspInitialize.pGenerateDSPInterrupt();
} }
} }

File diff suppressed because it is too large Load Diff

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 "Common.h" #include "Common.h"
#include "../Globals.h" #include "../Globals.h"
#include "../DSPHandler.h" #include "../DSPHandler.h"
#include "UCodes.h" #include "UCodes.h"
#include "UCode_CARD.h" #include "UCode_CARD.h"
CUCode_CARD::CUCode_CARD(CMailHandler& _rMailHandler) CUCode_CARD::CUCode_CARD(CMailHandler& _rMailHandler)
: IUCode(_rMailHandler) : IUCode(_rMailHandler)
{ {
DebugLog("CUCode_CARD - initialized"); DebugLog("CUCode_CARD - initialized");
m_rMailHandler.PushMail(DSP_INIT); m_rMailHandler.PushMail(DSP_INIT);
} }
CUCode_CARD::~CUCode_CARD() CUCode_CARD::~CUCode_CARD()
{ {
m_rMailHandler.Clear(); m_rMailHandler.Clear();
} }
void CUCode_CARD::Update() void CUCode_CARD::Update()
{ {
// check if we have to sent something // check if we have to sent something
if (!m_rMailHandler.IsEmpty()) if (!m_rMailHandler.IsEmpty())
{ {
g_dspInitialize.pGenerateDSPInterrupt(); g_dspInitialize.pGenerateDSPInterrupt();
} }
} }
void CUCode_CARD::HandleMail(u32 _uMail) void CUCode_CARD::HandleMail(u32 _uMail)
{ {
if (_uMail == 0xFF000000) // unlock card if (_uMail == 0xFF000000) // unlock card
{ {
// m_Mails.push(0x00000001); // ACK (actualy anything != 0) // m_Mails.push(0x00000001); // ACK (actualy anything != 0)
} }
else else
{ {
DebugLog("CUCode_CARD - unknown cmd: %x (size %i)", _uMail); DebugLog("CUCode_CARD - unknown cmd: %x (size %i)", _uMail);
} }
m_rMailHandler.PushMail(DSP_DONE); m_rMailHandler.PushMail(DSP_DONE);
CDSPHandler::GetInstance().SetUCode(UCODE_ROM); CDSPHandler::GetInstance().SetUCode(UCODE_ROM);
} }

View File

@ -1,54 +1,54 @@
// 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 "../DSPHandler.h" #include "../DSPHandler.h"
#include "UCodes.h" #include "UCodes.h"
#include "UCode_InitAudioSystem.h" #include "UCode_InitAudioSystem.h"
CUCode_InitAudioSystem::CUCode_InitAudioSystem(CMailHandler& _rMailHandler) CUCode_InitAudioSystem::CUCode_InitAudioSystem(CMailHandler& _rMailHandler)
: IUCode(_rMailHandler) : IUCode(_rMailHandler)
, m_BootTask_numSteps(0) , m_BootTask_numSteps(0)
, m_NextParameter(0) , m_NextParameter(0)
, IsInitialized(false) , IsInitialized(false)
{ {
DebugLog("CUCode_InitAudioSystem - initialized"); DebugLog("CUCode_InitAudioSystem - initialized");
} }
CUCode_InitAudioSystem::~CUCode_InitAudioSystem() CUCode_InitAudioSystem::~CUCode_InitAudioSystem()
{} {}
void CUCode_InitAudioSystem::Init() void CUCode_InitAudioSystem::Init()
{} {}
void CUCode_InitAudioSystem::Update() void CUCode_InitAudioSystem::Update()
{ {
if (m_rMailHandler.IsEmpty()) if (m_rMailHandler.IsEmpty())
{ {
m_rMailHandler.PushMail(0x80544348); m_rMailHandler.PushMail(0x80544348);
// HALT // HALT
} }
} }
void CUCode_InitAudioSystem::HandleMail(u32 _uMail) void CUCode_InitAudioSystem::HandleMail(u32 _uMail)
{} {}

View File

@ -1,162 +1,162 @@
// 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 "UCodes.h" #include "UCodes.h"
#include "UCode_Jac.h" #include "UCode_Jac.h"
#include "../MailHandler.h" #include "../MailHandler.h"
CUCode_Jac::CUCode_Jac(CMailHandler& _rMailHandler) CUCode_Jac::CUCode_Jac(CMailHandler& _rMailHandler)
: IUCode(_rMailHandler) : IUCode(_rMailHandler)
, m_bListInProgress(false) , m_bListInProgress(false)
{ {
DebugLog("CUCode_Jac: init"); DebugLog("CUCode_Jac: init");
m_rMailHandler.PushMail(0xDCD10000); m_rMailHandler.PushMail(0xDCD10000);
m_rMailHandler.PushMail(0x80000000); m_rMailHandler.PushMail(0x80000000);
} }
CUCode_Jac::~CUCode_Jac() CUCode_Jac::~CUCode_Jac()
{ {
m_rMailHandler.Clear(); m_rMailHandler.Clear();
} }
void CUCode_Jac::HandleMail(u32 _uMail) void CUCode_Jac::HandleMail(u32 _uMail)
{ {
// this is prolly totally bullshit and should work like the zelda one... // this is prolly totally bullshit and should work like the zelda one...
// but i am to lazy to change it atm // but i am to lazy to change it atm
if (m_bListInProgress == false) if (m_bListInProgress == false)
{ {
// get the command to find out how much steps it has // get the command to find out how much steps it has
switch (_uMail & 0xFFFF) switch (_uMail & 0xFFFF)
{ {
// release halt // release halt
case 0x00: case 0x00:
// m_Mails.push(0x80000000); // m_Mails.push(0x80000000);
g_dspInitialize.pGenerateDSPInterrupt(); g_dspInitialize.pGenerateDSPInterrupt();
break; break;
case 0x40: case 0x40:
m_step = 0; m_step = 0;
((u32*)m_Buffer)[m_step++] = _uMail; ((u32*)m_Buffer)[m_step++] = _uMail;
m_bListInProgress = true; m_bListInProgress = true;
m_numSteps = 5; m_numSteps = 5;
break; break;
case 0x2000: case 0x2000:
case 0x4000: case 0x4000:
m_step = 0; m_step = 0;
((u32*)m_Buffer)[m_step++] = _uMail; ((u32*)m_Buffer)[m_step++] = _uMail;
m_bListInProgress = true; m_bListInProgress = true;
m_numSteps = 3; m_numSteps = 3;
break; break;
default: default:
PanicAlert("UCode Jac"); PanicAlert("UCode Jac");
DebugLog("UCode Jac - unknown cmd: %x", _uMail & 0xFFFF); DebugLog("UCode Jac - unknown cmd: %x", _uMail & 0xFFFF);
break; break;
} }
} }
else else
{ {
((u32*)m_Buffer)[m_step] = _uMail; ((u32*)m_Buffer)[m_step] = _uMail;
m_step++; m_step++;
if (m_step == m_numSteps) if (m_step == m_numSteps)
{ {
ExecuteList(); ExecuteList();
m_bListInProgress = false; m_bListInProgress = false;
} }
} }
} }
void CUCode_Jac::Update() void CUCode_Jac::Update()
{ {
// check if we have to sent something // check if we have to sent something
/* if (!g_MailHandler.empty()) /* if (!g_MailHandler.empty())
{ {
g_dspInitialize.pGenerateDSPInterrupt(); g_dspInitialize.pGenerateDSPInterrupt();
}*/ }*/
} }
void CUCode_Jac::ExecuteList() void CUCode_Jac::ExecuteList()
{ {
// begin with the list // begin with the list
m_readOffset = 0; m_readOffset = 0;
u16 cmd = Read16(); u16 cmd = Read16();
u16 sync = Read16(); u16 sync = Read16();
DebugLog("=============================================================================="); DebugLog("==============================================================================");
DebugLog("UCode Jac - execute dlist (cmd: 0x%04x : sync: 0x%04x)", cmd, sync); DebugLog("UCode Jac - execute dlist (cmd: 0x%04x : sync: 0x%04x)", cmd, sync);
switch (cmd) switch (cmd)
{ {
// ============================================================================== // ==============================================================================
// DsetupTable // DsetupTable
// ============================================================================== // ==============================================================================
case 0x40: case 0x40:
{ {
u32 tmp[4]; u32 tmp[4];
tmp[0] = Read32(); tmp[0] = Read32();
tmp[1] = Read32(); tmp[1] = Read32();
tmp[2] = Read32(); tmp[2] = Read32();
tmp[3] = Read32(); tmp[3] = Read32();
DebugLog("DsetupTable"); DebugLog("DsetupTable");
DebugLog("???: 0x%08x", tmp[0]); DebugLog("???: 0x%08x", tmp[0]);
DebugLog("DSPRES_FILTER (size: 0x40): 0x%08x", tmp[1]); DebugLog("DSPRES_FILTER (size: 0x40): 0x%08x", tmp[1]);
DebugLog("DSPADPCM_FILTER (size: 0x500): 0x%08x", tmp[2]); DebugLog("DSPADPCM_FILTER (size: 0x500): 0x%08x", tmp[2]);
DebugLog("???: 0x%08x", tmp[3]); DebugLog("???: 0x%08x", tmp[3]);
} }
break; break;
// ============================================================================== // ==============================================================================
// UpdateDSPChannel // UpdateDSPChannel
// ============================================================================== // ==============================================================================
case 0x2000: case 0x2000:
case 0x4000: // animal crossing case 0x4000: // animal crossing
{ {
u32 tmp[3]; u32 tmp[3];
tmp[0] = Read32(); tmp[0] = Read32();
tmp[1] = Read32(); tmp[1] = Read32();
tmp[2] = Read32(); tmp[2] = Read32();
DebugLog("UpdateDSPChannel"); DebugLog("UpdateDSPChannel");
DebugLog("audiomemory: 0x%08x", tmp[0]); DebugLog("audiomemory: 0x%08x", tmp[0]);
DebugLog("audiomemory: 0x%08x", tmp[1]); DebugLog("audiomemory: 0x%08x", tmp[1]);
DebugLog("DSPADPCM_FILTER (size: 0x40): 0x%08x", tmp[2]); DebugLog("DSPADPCM_FILTER (size: 0x40): 0x%08x", tmp[2]);
} }
break; break;
default: default:
PanicAlert("UCode Jac unknown cmd: %s (size %)", cmd, m_numSteps); PanicAlert("UCode Jac unknown cmd: %s (size %)", cmd, m_numSteps);
DebugLog("Jac UCode - unknown cmd: %x (size %i)", cmd, m_numSteps); DebugLog("Jac UCode - unknown cmd: %x (size %i)", cmd, m_numSteps);
break; break;
} }
// sync, we are rdy // sync, we are rdy
m_rMailHandler.PushMail(DSP_SYNC); m_rMailHandler.PushMail(DSP_SYNC);
m_rMailHandler.PushMail(0xF3550000 | sync); m_rMailHandler.PushMail(0xF3550000 | sync);
} }

View File

@ -1,113 +1,113 @@
// 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 "../DSPHandler.h" #include "../DSPHandler.h"
#include "UCodes.h" #include "UCodes.h"
#include "UCode_ROM.h" #include "UCode_ROM.h"
CUCode_Rom::CUCode_Rom(CMailHandler& _rMailHandler) CUCode_Rom::CUCode_Rom(CMailHandler& _rMailHandler)
: IUCode(_rMailHandler) : IUCode(_rMailHandler)
, m_BootTask_numSteps(0) , m_BootTask_numSteps(0)
, m_NextParameter(0) , m_NextParameter(0)
{ {
DebugLog("UCode_Rom - initialized"); DebugLog("UCode_Rom - initialized");
m_rMailHandler.Clear(); m_rMailHandler.Clear();
m_rMailHandler.PushMail(0x8071FEED); m_rMailHandler.PushMail(0x8071FEED);
} }
CUCode_Rom::~CUCode_Rom() CUCode_Rom::~CUCode_Rom()
{} {}
void CUCode_Rom::Update() void CUCode_Rom::Update()
{} {}
void CUCode_Rom::HandleMail(u32 _uMail) void CUCode_Rom::HandleMail(u32 _uMail)
{ {
if (m_NextParameter == 0) if (m_NextParameter == 0)
{ {
// wait for beginning of UCode // wait for beginning of UCode
if ((_uMail & 0xFFFF0000) != 0x80F30000) if ((_uMail & 0xFFFF0000) != 0x80F30000)
{ {
u32 Message = 0xFEEE0000 | (_uMail & 0xFFFF); u32 Message = 0xFEEE0000 | (_uMail & 0xFFFF);
m_rMailHandler.PushMail(Message); m_rMailHandler.PushMail(Message);
} }
else else
{ {
m_NextParameter = _uMail; m_NextParameter = _uMail;
} }
} }
else else
{ {
switch (m_NextParameter) switch (m_NextParameter)
{ {
case 0x80F3A001: case 0x80F3A001:
m_CurrentUCode.m_RAMAddress = _uMail; m_CurrentUCode.m_RAMAddress = _uMail;
break; break;
case 0x80F3A002: case 0x80F3A002:
m_CurrentUCode.m_Length = _uMail; m_CurrentUCode.m_Length = _uMail;
break; break;
case 0x80F3C002: case 0x80F3C002:
m_CurrentUCode.m_IMEMAddress = _uMail; m_CurrentUCode.m_IMEMAddress = _uMail;
break; break;
case 0x80F3B002: case 0x80F3B002:
m_CurrentUCode.m_Unk = _uMail; m_CurrentUCode.m_Unk = _uMail;
break; break;
case 0x80F3D001: case 0x80F3D001:
{ {
m_CurrentUCode.m_StartPC = _uMail; m_CurrentUCode.m_StartPC = _uMail;
BootUCode(); BootUCode();
return; // FIXES THE OVERWRITE return; // FIXES THE OVERWRITE
} }
break; break;
} }
// THE GODDAMN OVERWRITE WAS HERE. Without the return above, since BootUCode may delete "this", well ... // THE GODDAMN OVERWRITE WAS HERE. Without the return above, since BootUCode may delete "this", well ...
m_NextParameter = 0; m_NextParameter = 0;
} }
} }
void CUCode_Rom::BootUCode() void CUCode_Rom::BootUCode()
{ {
// simple non-scientific crc invented by ector :P // simple non-scientific crc invented by ector :P
// too annoying to change now, and probably good enough anyway // too annoying to change now, and probably good enough anyway
u32 crc = 0; u32 crc = 0;
for (u32 i = 0; i < m_CurrentUCode.m_Length; i++) for (u32 i = 0; i < m_CurrentUCode.m_Length; i++)
{ {
crc ^= Memory_Read_U8(m_CurrentUCode.m_RAMAddress + i); crc ^= Memory_Read_U8(m_CurrentUCode.m_RAMAddress + i);
//let's rol //let's rol
crc = (crc << 3) | (crc >> 29); crc = (crc << 3) | (crc >> 29);
} }
DebugLog("CurrentUCode SOURCE Addr: 0x%08x", m_CurrentUCode.m_RAMAddress); DebugLog("CurrentUCode SOURCE Addr: 0x%08x", m_CurrentUCode.m_RAMAddress);
DebugLog("CurrentUCode Length: 0x%08x", m_CurrentUCode.m_Length); DebugLog("CurrentUCode Length: 0x%08x", m_CurrentUCode.m_Length);
DebugLog("CurrentUCode DEST Addr: 0x%08x", m_CurrentUCode.m_IMEMAddress); DebugLog("CurrentUCode DEST Addr: 0x%08x", m_CurrentUCode.m_IMEMAddress);
DebugLog("CurrentUCode ???: 0x%08x", m_CurrentUCode.m_Unk); DebugLog("CurrentUCode ???: 0x%08x", m_CurrentUCode.m_Unk);
DebugLog("CurrentUCode init_vector: 0x%08x", m_CurrentUCode.m_StartPC); DebugLog("CurrentUCode init_vector: 0x%08x", m_CurrentUCode.m_StartPC);
DebugLog("CurrentUCode CRC: 0x%08x", crc); DebugLog("CurrentUCode CRC: 0x%08x", crc);
DebugLog("BootTask - done"); DebugLog("BootTask - done");
CDSPHandler::GetInstance().SetUCode(crc); CDSPHandler::GetInstance().SetUCode(crc);
} }

View File

@ -1,166 +1,166 @@
// 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/
// Games that uses this UCode: // Games that uses this UCode:
// Zelda: The Windwaker, Mario Sunshine, Mario Kart // Zelda: The Windwaker, Mario Sunshine, Mario Kart
#include "Common.h" #include "Common.h"
#include "../Globals.h" #include "../Globals.h"
#include "UCodes.h" #include "UCodes.h"
#include "UCode_Zelda.h" #include "UCode_Zelda.h"
#include "../MailHandler.h" #include "../MailHandler.h"
CUCode_Zelda::CUCode_Zelda(CMailHandler& _rMailHandler) CUCode_Zelda::CUCode_Zelda(CMailHandler& _rMailHandler)
: IUCode(_rMailHandler) : IUCode(_rMailHandler)
, m_numSteps(0) , m_numSteps(0)
, m_bListInProgress(false) , m_bListInProgress(false)
, m_step(0) , m_step(0)
, m_readOffset(0) , m_readOffset(0)
{ {
DebugLog("UCode_Zelda - add boot mails for handshake"); DebugLog("UCode_Zelda - add boot mails for handshake");
m_rMailHandler.PushMail(DSP_INIT); m_rMailHandler.PushMail(DSP_INIT);
m_rMailHandler.PushMail(0x80000000); // handshake m_rMailHandler.PushMail(0x80000000); // handshake
memset(m_Buffer, 0, sizeof(m_Buffer)); memset(m_Buffer, 0, sizeof(m_Buffer));
} }
CUCode_Zelda::~CUCode_Zelda() CUCode_Zelda::~CUCode_Zelda()
{ {
m_rMailHandler.Clear(); m_rMailHandler.Clear();
} }
void CUCode_Zelda::Update() void CUCode_Zelda::Update()
{ {
// check if we have to sent something // check if we have to sent something
if (!m_rMailHandler.IsEmpty()) if (!m_rMailHandler.IsEmpty())
g_dspInitialize.pGenerateDSPInterrupt(); g_dspInitialize.pGenerateDSPInterrupt();
} }
void CUCode_Zelda::HandleMail(u32 _uMail) void CUCode_Zelda::HandleMail(u32 _uMail)
{ {
if (m_bListInProgress == false) if (m_bListInProgress == false)
{ {
m_bListInProgress = true; m_bListInProgress = true;
m_numSteps = _uMail; m_numSteps = _uMail;
m_step = 0; m_step = 0;
} }
else else
{ {
if (m_step < 0 || m_step >= sizeof(m_Buffer)/4) if (m_step < 0 || m_step >= sizeof(m_Buffer)/4)
PanicAlert("m_step out of range"); PanicAlert("m_step out of range");
((u32*)m_Buffer)[m_step] = _uMail; ((u32*)m_Buffer)[m_step] = _uMail;
m_step++; m_step++;
if (m_step == m_numSteps) if (m_step == m_numSteps)
{ {
ExecuteList(); ExecuteList();
m_bListInProgress = false; m_bListInProgress = false;
} }
} }
} }
void CUCode_Zelda::ExecuteList() void CUCode_Zelda::ExecuteList()
{ {
// begin with the list // begin with the list
m_readOffset = 0; m_readOffset = 0;
u32 Temp = Read32(); u32 Temp = Read32();
u32 Command = (Temp >> 24) & 0x7f; u32 Command = (Temp >> 24) & 0x7f;
u32 Sync = Temp >> 16; u32 Sync = Temp >> 16;
DebugLog("=============================================================================="); DebugLog("==============================================================================");
DebugLog("Zelda UCode - execute dlist (cmd: 0x%04x : sync: 0x%04x)", Command, Sync); DebugLog("Zelda UCode - execute dlist (cmd: 0x%04x : sync: 0x%04x)", Command, Sync);
switch (Command) switch (Command)
{ {
// DsetupTable ... zelda ww jumps to 0x0095 // DsetupTable ... zelda ww jumps to 0x0095
case 0x01: case 0x01:
{ {
u32 tmp[4]; u32 tmp[4];
tmp[0] = Read32(); tmp[0] = Read32();
tmp[1] = Read32(); tmp[1] = Read32();
tmp[2] = Read32(); tmp[2] = Read32();
tmp[3] = Read32(); tmp[3] = Read32();
DebugLog("DsetupTable"); DebugLog("DsetupTable");
DebugLog("???: 0x%08x", tmp[0]); DebugLog("???: 0x%08x", tmp[0]);
DebugLog("DSPRES_FILTER (size: 0x40): 0x%08x", tmp[1]); DebugLog("DSPRES_FILTER (size: 0x40): 0x%08x", tmp[1]);
DebugLog("DSPADPCM_FILTER (size: 0x500): 0x%08x", tmp[2]); DebugLog("DSPADPCM_FILTER (size: 0x500): 0x%08x", tmp[2]);
DebugLog("???: 0x%08x", tmp[3]); DebugLog("???: 0x%08x", tmp[3]);
} }
break; break;
// SyncFrame ... zelda ww jumps to 0x0243 // SyncFrame ... zelda ww jumps to 0x0243
case 0x02: case 0x02:
{ {
u32 tmp[3]; u32 tmp[3];
tmp[0] = Read32(); tmp[0] = Read32();
tmp[1] = Read32(); tmp[1] = Read32();
tmp[2] = Read32(); tmp[2] = Read32();
DebugLog("DsyncFrame"); DebugLog("DsyncFrame");
DebugLog("???: 0x%08x", tmp[0]); DebugLog("???: 0x%08x", tmp[0]);
DebugLog("???: 0x%08x", tmp[1]); DebugLog("???: 0x%08x", tmp[1]);
DebugLog("DSPADPCM_FILTER (size: 0x500): 0x%08x", tmp[2]); DebugLog("DSPADPCM_FILTER (size: 0x500): 0x%08x", tmp[2]);
} }
break; break;
/* /*
case 0x03: break; // dunno ... zelda ww jmps to 0x0073 case 0x03: break; // dunno ... zelda ww jmps to 0x0073
case 0x04: break; // dunno ... zelda ww jmps to 0x0580 case 0x04: break; // dunno ... zelda ww jmps to 0x0580
case 0x05: break; // dunno ... zelda ww jmps to 0x0592 case 0x05: break; // dunno ... zelda ww jmps to 0x0592
case 0x06: break; // dunno ... zelda ww jmps to 0x0469 case 0x06: break; // dunno ... zelda ww jmps to 0x0469
case 0x07: break; // dunno ... zelda ww jmps to 0x044d case 0x07: break; // dunno ... zelda ww jmps to 0x044d
case 0x08: break; // Mixer ... zelda ww jmps to 0x0485 case 0x08: break; // Mixer ... zelda ww jmps to 0x0485
case 0x09: break; // dunno ... zelda ww jmps to 0x044d case 0x09: break; // dunno ... zelda ww jmps to 0x044d
*/ */
// DsetDolbyDelay ... zelda ww jumps to 0x00b2 // DsetDolbyDelay ... zelda ww jumps to 0x00b2
case 0x0d: case 0x0d:
{ {
u32 tmp[2]; u32 tmp[2];
tmp[0] = Read32(); tmp[0] = Read32();
tmp[1] = Read32(); tmp[1] = Read32();
DebugLog("DSetDolbyDelay"); DebugLog("DSetDolbyDelay");
DebugLog("DOLBY2_DELAY_BUF (size 0x960): 0x%08x", tmp[0]); DebugLog("DOLBY2_DELAY_BUF (size 0x960): 0x%08x", tmp[0]);
DebugLog("DSPRES_FILTER (size 0x500): 0x%08x", tmp[1]); DebugLog("DSPRES_FILTER (size 0x500): 0x%08x", tmp[1]);
} }
break; break;
// Set VARAM // Set VARAM
case 0x0e: case 0x0e:
// MessageBox(NULL, "Zelda VARAM", "cmd", MB_OK); // MessageBox(NULL, "Zelda VARAM", "cmd", MB_OK);
break; break;
// default ... zelda ww jumps to 0x0043 // default ... zelda ww jumps to 0x0043
default: default:
PanicAlert("Zelda UCode - unknown cmd: %x (size %i)", Command, m_numSteps); PanicAlert("Zelda UCode - unknown cmd: %x (size %i)", Command, m_numSteps);
break; break;
} }
// sync, we are rdy // sync, we are rdy
m_rMailHandler.PushMail(DSP_SYNC); m_rMailHandler.PushMail(DSP_SYNC);
m_rMailHandler.PushMail(0xF3550000 | Sync); m_rMailHandler.PushMail(0xF3550000 | Sync);
} }

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 "Common.h" #include "Common.h"
#include "../Globals.h" #include "../Globals.h"
#include "UCodes.h" #include "UCodes.h"
#include "UCode_AX.h" #include "UCode_AX.h"
#include "UCode_Zelda.h" #include "UCode_Zelda.h"
#include "UCode_Jac.h" #include "UCode_Jac.h"
#include "UCode_ROM.h" #include "UCode_ROM.h"
#include "UCode_CARD.h" #include "UCode_CARD.h"
#include "UCode_InitAudioSystem.h" #include "UCode_InitAudioSystem.h"
IUCode* UCodeFactory(u32 _CRC, CMailHandler& _rMailHandler) IUCode* UCodeFactory(u32 _CRC, CMailHandler& _rMailHandler)
{ {
switch (_CRC) switch (_CRC)
{ {
case UCODE_ROM: case UCODE_ROM:
return new CUCode_Rom(_rMailHandler); return new CUCode_Rom(_rMailHandler);
case UCODE_INIT_AUDIO_SYSTEM: case UCODE_INIT_AUDIO_SYSTEM:
return new CUCode_InitAudioSystem(_rMailHandler); return new CUCode_InitAudioSystem(_rMailHandler);
case 0x65d6cc6f: // CARD case 0x65d6cc6f: // CARD
return new CUCode_CARD(_rMailHandler); return new CUCode_CARD(_rMailHandler);
case 0x088e38a5: // IPL - JAP case 0x088e38a5: // IPL - JAP
case 0xd73338cf: // IPL case 0xd73338cf: // IPL
case 0x42f64ac4: // Luigi (after fix) case 0x42f64ac4: // Luigi (after fix)
case 0x4be6a5cb: // AC, Pikmin (after fix) case 0x4be6a5cb: // AC, Pikmin (after fix)
DebugLog("JAC ucode chosen"); DebugLog("JAC ucode chosen");
return new CUCode_Jac(_rMailHandler); return new CUCode_Jac(_rMailHandler);
case 0x3ad3b7ac: // Naruto3 case 0x3ad3b7ac: // Naruto3
case 0x3daf59b9: // Alien Hominid case 0x3daf59b9: // Alien Hominid
case 0x4e8a8b21: // spdemo, ctaxi, 18 wheeler, disney, monkeyball2,cubivore,puzzlecollection,wario, case 0x4e8a8b21: // spdemo, ctaxi, 18 wheeler, disney, monkeyball2,cubivore,puzzlecollection,wario,
// capcom vs snk, naruto2, lost kingdoms, star fox, mario party 4, mortal kombat, // capcom vs snk, naruto2, lost kingdoms, star fox, mario party 4, mortal kombat,
// smugglers run warzone, smash brothers, sonic mega collection, ZooCube // smugglers run warzone, smash brothers, sonic mega collection, ZooCube
// nddemo, starfox // nddemo, starfox
case 0x07f88145: // bustamove, ikaruga, fzero, robotech battle cry, star soldier, soul calibur2, case 0x07f88145: // bustamove, ikaruga, fzero, robotech battle cry, star soldier, soul calibur2,
// Zelda:OOT, Tony hawk, viewtiful joe // Zelda:OOT, Tony hawk, viewtiful joe
case 0xe2136399: // billy hatcher, dragonballz, mario party 5, TMNT, ava1080 case 0xe2136399: // billy hatcher, dragonballz, mario party 5, TMNT, ava1080
DebugLog("AX ucode chosen, yay!"); DebugLog("AX ucode chosen, yay!");
return new CUCode_AX(_rMailHandler); return new CUCode_AX(_rMailHandler);
case 0x6CA33A6D: // DK Jungle Beat case 0x6CA33A6D: // DK Jungle Beat
case 0x86840740: // zelda case 0x86840740: // zelda
case 0x56d36052: // mario case 0x56d36052: // mario
case 0x2fcdf1ec: // mariokart, zelda 4 swords case 0x2fcdf1ec: // mariokart, zelda 4 swords
DebugLog("Zelda ucode chosen"); DebugLog("Zelda ucode chosen");
return new CUCode_Zelda(_rMailHandler); return new CUCode_Zelda(_rMailHandler);
// WII CRCs // WII CRCs
case 0x6c3f6f94: // zelda - PAL case 0x6c3f6f94: // zelda - PAL
case 0xd643001f: // mario galaxy - PAL case 0xd643001f: // mario galaxy - PAL
DebugLog("Zelda Wii ucode chosen"); DebugLog("Zelda Wii ucode chosen");
return new CUCode_Zelda(_rMailHandler); return new CUCode_Zelda(_rMailHandler);
case 0x347112ba: // raving rabbits case 0x347112ba: // raving rabbits
DebugLog("Wii - AX chosen"); DebugLog("Wii - AX chosen");
return new CUCode_AX(_rMailHandler, true); return new CUCode_AX(_rMailHandler, true);
default: default:
PanicAlert("Unknown ucode (CRC = %08x) - forcing AX", _CRC); PanicAlert("Unknown ucode (CRC = %08x) - forcing AX", _CRC);
return new CUCode_AX(_rMailHandler); return new CUCode_AX(_rMailHandler);
} }
return NULL; return NULL;
} }

View File

@ -1,203 +1,203 @@
// 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 "ChunkFile.h" #include "ChunkFile.h"
#include "pluginspecs_dsp.h" #include "pluginspecs_dsp.h"
#include "DSPHandler.h" #include "DSPHandler.h"
DSPInitialize g_dspInitialize; DSPInitialize g_dspInitialize;
u8* g_pMemory; u8* g_pMemory;
struct DSPState struct DSPState
{ {
u32 CPUMailbox; u32 CPUMailbox;
bool CPUMailbox_Written[2]; bool CPUMailbox_Written[2];
u32 DSPMailbox; u32 DSPMailbox;
bool DSPMailbox_Read[2]; bool DSPMailbox_Read[2];
DSPState() DSPState()
{ {
CPUMailbox = 0x00000000; CPUMailbox = 0x00000000;
CPUMailbox_Written[0] = false; CPUMailbox_Written[0] = false;
CPUMailbox_Written[1] = false; CPUMailbox_Written[1] = false;
DSPMailbox = 0x00000000; DSPMailbox = 0x00000000;
DSPMailbox_Read[0] = true; DSPMailbox_Read[0] = true;
DSPMailbox_Read[1] = true; DSPMailbox_Read[1] = true;
} }
}; };
DSPState g_dspState; DSPState g_dspState;
#ifdef _WIN32 #ifdef _WIN32
HINSTANCE g_hInstance = NULL; HINSTANCE g_hInstance = NULL;
BOOL APIENTRY DllMain(HINSTANCE hinstDLL, // DLL module handle BOOL APIENTRY DllMain(HINSTANCE hinstDLL, // DLL module handle
DWORD dwReason, // reason called DWORD dwReason, // reason called
LPVOID lpvReserved) // reserved LPVOID lpvReserved) // reserved
{ {
switch (dwReason) switch (dwReason)
{ {
case DLL_PROCESS_ATTACH: case DLL_PROCESS_ATTACH:
break; break;
case DLL_PROCESS_DETACH: case DLL_PROCESS_DETACH:
break; break;
default: default:
break; break;
} }
g_hInstance = hinstDLL; g_hInstance = hinstDLL;
return(TRUE); return(TRUE);
} }
#endif #endif
void DllDebugger(HWND _hParent) void DllDebugger(HWND _hParent)
{ {
// TODO: implement // TODO: implement
} }
void GetDllInfo(PLUGIN_INFO* _PluginInfo) void GetDllInfo(PLUGIN_INFO* _PluginInfo)
{ {
_PluginInfo->Version = 0x0100; _PluginInfo->Version = 0x0100;
_PluginInfo->Type = PLUGIN_TYPE_DSP; _PluginInfo->Type = PLUGIN_TYPE_DSP;
#ifdef DEBUGFAST #ifdef DEBUGFAST
sprintf(_PluginInfo->Name, "Dolphin DSP-NULL Plugin (DebugFast) "); sprintf(_PluginInfo->Name, "Dolphin DSP-NULL Plugin (DebugFast) ");
#else #else
#ifndef _DEBUG #ifndef _DEBUG
sprintf(_PluginInfo->Name, "Dolphin DSP-NULL Plugin "); sprintf(_PluginInfo->Name, "Dolphin DSP-NULL Plugin ");
#else #else
sprintf(_PluginInfo->Name, "Dolphin DSP-NULL Plugin (Debug) "); sprintf(_PluginInfo->Name, "Dolphin DSP-NULL Plugin (Debug) ");
#endif #endif
#endif #endif
} }
void DllAbout(HWND _hParent) void DllAbout(HWND _hParent)
{ {
} }
void DllConfig(HWND _hParent) void DllConfig(HWND _hParent)
{ {
} }
void DSP_Initialize(DSPInitialize _dspInitialize) void DSP_Initialize(DSPInitialize _dspInitialize)
{ {
g_dspInitialize = _dspInitialize; g_dspInitialize = _dspInitialize;
g_pMemory = g_dspInitialize.pGetMemoryPointer(0); g_pMemory = g_dspInitialize.pGetMemoryPointer(0);
CDSPHandler::CreateInstance(); CDSPHandler::CreateInstance();
} }
void DSP_Shutdown() void DSP_Shutdown()
{ {
CDSPHandler::Destroy(); CDSPHandler::Destroy();
} }
void DSP_DoState(unsigned char **ptr, int mode) { void DSP_DoState(unsigned char **ptr, int mode) {
PointerWrap p(ptr, mode); PointerWrap p(ptr, mode);
} }
unsigned short DSP_ReadMailboxHigh(bool _CPUMailbox) unsigned short DSP_ReadMailboxHigh(bool _CPUMailbox)
{ {
if (_CPUMailbox) if (_CPUMailbox)
{ {
return (g_dspState.CPUMailbox >> 16) & 0xFFFF; return (g_dspState.CPUMailbox >> 16) & 0xFFFF;
} }
else else
{ {
return CDSPHandler::GetInstance().AccessMailHandler().ReadDSPMailboxHigh(); return CDSPHandler::GetInstance().AccessMailHandler().ReadDSPMailboxHigh();
} }
} }
unsigned short DSP_ReadMailboxLow(bool _CPUMailbox) unsigned short DSP_ReadMailboxLow(bool _CPUMailbox)
{ {
if (_CPUMailbox) if (_CPUMailbox)
{ {
return g_dspState.CPUMailbox & 0xFFFF; return g_dspState.CPUMailbox & 0xFFFF;
} }
else else
{ {
return CDSPHandler::GetInstance().AccessMailHandler().ReadDSPMailboxLow(); return CDSPHandler::GetInstance().AccessMailHandler().ReadDSPMailboxLow();
} }
} }
void Update_DSP_WriteRegister() void Update_DSP_WriteRegister()
{ {
// check if the whole message is complete and if we can send it // check if the whole message is complete and if we can send it
if (g_dspState.CPUMailbox_Written[0] && g_dspState.CPUMailbox_Written[1]) if (g_dspState.CPUMailbox_Written[0] && g_dspState.CPUMailbox_Written[1])
{ {
CDSPHandler::GetInstance().SendMailToDSP(g_dspState.CPUMailbox); CDSPHandler::GetInstance().SendMailToDSP(g_dspState.CPUMailbox);
g_dspState.CPUMailbox_Written[0] = g_dspState.CPUMailbox_Written[1] = false; g_dspState.CPUMailbox_Written[0] = g_dspState.CPUMailbox_Written[1] = false;
g_dspState.CPUMailbox = 0; // Mail sent so clear it to show that it is progressed g_dspState.CPUMailbox = 0; // Mail sent so clear it to show that it is progressed
} }
} }
void DSP_WriteMailboxHigh(bool _CPUMailbox, unsigned short _Value) void DSP_WriteMailboxHigh(bool _CPUMailbox, unsigned short _Value)
{ {
if (_CPUMailbox) if (_CPUMailbox)
{ {
g_dspState.CPUMailbox = (g_dspState.CPUMailbox & 0xFFFF) | (_Value << 16); g_dspState.CPUMailbox = (g_dspState.CPUMailbox & 0xFFFF) | (_Value << 16);
g_dspState.CPUMailbox_Written[0] = true; g_dspState.CPUMailbox_Written[0] = true;
Update_DSP_WriteRegister(); Update_DSP_WriteRegister();
} }
else else
{ {
PanicAlert("CPU can't write %08x to DSP mailbox", _Value); PanicAlert("CPU can't write %08x to DSP mailbox", _Value);
} }
} }
void DSP_WriteMailboxLow(bool _CPUMailbox, unsigned short _Value) void DSP_WriteMailboxLow(bool _CPUMailbox, unsigned short _Value)
{ {
if (_CPUMailbox) if (_CPUMailbox)
{ {
g_dspState.CPUMailbox = (g_dspState.CPUMailbox & 0xFFFF0000) | _Value; g_dspState.CPUMailbox = (g_dspState.CPUMailbox & 0xFFFF0000) | _Value;
g_dspState.CPUMailbox_Written[1] = true; g_dspState.CPUMailbox_Written[1] = true;
Update_DSP_WriteRegister(); Update_DSP_WriteRegister();
} }
else else
{ {
PanicAlert("CPU can't write %08x to DSP mailbox", _Value); PanicAlert("CPU can't write %08x to DSP mailbox", _Value);
} }
} }
unsigned short DSP_WriteControlRegister(unsigned short _Value) unsigned short DSP_WriteControlRegister(unsigned short _Value)
{ {
return CDSPHandler::GetInstance().WriteControlRegister(_Value); return CDSPHandler::GetInstance().WriteControlRegister(_Value);
} }
unsigned short DSP_ReadControlRegister() unsigned short DSP_ReadControlRegister()
{ {
return CDSPHandler::GetInstance().ReadControlRegister(); return CDSPHandler::GetInstance().ReadControlRegister();
} }
void DSP_Update(int cycles) void DSP_Update(int cycles)
{ {
CDSPHandler::GetInstance().Update(); CDSPHandler::GetInstance().Update();
} }
void DSP_SendAIBuffer(unsigned int address, int sample_rate) void DSP_SendAIBuffer(unsigned int address, int sample_rate)
{ {
} }

View File

@ -1,189 +1,189 @@
// 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 "stdafx.h" #include "stdafx.h"
#include "DirectInputBase.h" #include "DirectInputBase.h"
DInput::DInput() DInput::DInput()
: g_pDI(NULL), : g_pDI(NULL),
g_pKeyboard(NULL) g_pKeyboard(NULL)
{} {}
DInput::~DInput() DInput::~DInput()
{ {
Free(); Free();
} }
void DInput::DIKToString(unsigned int keycode, char *keyStr) void DInput::DIKToString(unsigned int keycode, char *keyStr)
{ {
switch(keycode) { switch(keycode) {
case DIK_RETURN: case DIK_RETURN:
sprintf(keyStr, "Enter"); sprintf(keyStr, "Enter");
break; break;
case DIK_UP: case DIK_UP:
sprintf(keyStr, "Up"); sprintf(keyStr, "Up");
break; break;
case DIK_DOWN: case DIK_DOWN:
sprintf(keyStr, "Down"); sprintf(keyStr, "Down");
break; break;
case DIK_LEFT: case DIK_LEFT:
sprintf(keyStr, "Left"); sprintf(keyStr, "Left");
break; break;
case DIK_RIGHT: case DIK_RIGHT:
sprintf(keyStr, "Right"); sprintf(keyStr, "Right");
break; break;
case DIK_HOME: case DIK_HOME:
strcpy(keyStr, "Home"); strcpy(keyStr, "Home");
break; break;
case DIK_END: case DIK_END:
strcpy(keyStr, "End"); strcpy(keyStr, "End");
break; break;
case DIK_INSERT: case DIK_INSERT:
strcpy(keyStr, "Ins"); strcpy(keyStr, "Ins");
break; break;
case DIK_DELETE: case DIK_DELETE:
strcpy(keyStr, "Del"); strcpy(keyStr, "Del");
break; break;
case DIK_PGUP: case DIK_PGUP:
strcpy(keyStr, "PgUp"); strcpy(keyStr, "PgUp");
break; break;
case DIK_PGDN: case DIK_PGDN:
strcpy(keyStr, "PgDn"); strcpy(keyStr, "PgDn");
break; break;
case DIK_NUMPAD0: case DIK_NUMPAD0:
strcpy(keyStr, "Num 0"); strcpy(keyStr, "Num 0");
break; break;
case DIK_NUMPAD1: case DIK_NUMPAD1:
strcpy(keyStr, "Num 1"); strcpy(keyStr, "Num 1");
break; break;
case DIK_NUMPAD2: case DIK_NUMPAD2:
strcpy(keyStr, "Num 2"); strcpy(keyStr, "Num 2");
break; break;
case DIK_NUMPAD3: case DIK_NUMPAD3:
strcpy(keyStr, "Num 3"); strcpy(keyStr, "Num 3");
break; break;
case DIK_NUMPAD4: case DIK_NUMPAD4:
strcpy(keyStr, "Num 4"); strcpy(keyStr, "Num 4");
break; break;
case DIK_NUMPAD5: case DIK_NUMPAD5:
strcpy(keyStr, "Num 5"); strcpy(keyStr, "Num 5");
break; break;
case DIK_NUMPAD6: case DIK_NUMPAD6:
strcpy(keyStr, "Num 6"); strcpy(keyStr, "Num 6");
break; break;
case DIK_NUMPAD7: case DIK_NUMPAD7:
strcpy(keyStr, "Num 7"); strcpy(keyStr, "Num 7");
break; break;
case DIK_NUMPAD8: case DIK_NUMPAD8:
strcpy(keyStr, "Num 8"); strcpy(keyStr, "Num 8");
break; break;
case DIK_NUMPAD9: case DIK_NUMPAD9:
strcpy(keyStr, "Num 9"); strcpy(keyStr, "Num 9");
break; break;
case DIK_NUMPADSLASH: case DIK_NUMPADSLASH:
strcpy(keyStr, "Num /"); strcpy(keyStr, "Num /");
break; break;
default: default:
GetKeyNameText(keycode << 16, keyStr, 64); GetKeyNameText(keycode << 16, keyStr, 64);
break; break;
} }
} }
HRESULT DInput::Init(HWND hWnd) HRESULT DInput::Init(HWND hWnd)
{ {
HRESULT hr; HRESULT hr;
DWORD dwCoopFlags; DWORD dwCoopFlags;
dwCoopFlags = DISCL_FOREGROUND | DISCL_NOWINKEY; dwCoopFlags = DISCL_FOREGROUND | DISCL_NOWINKEY;
// Create a DInput object // Create a DInput object
if (FAILED(hr = DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, if (FAILED(hr = DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION,
IID_IDirectInput8, (VOID* *)&g_pDI, NULL))) IID_IDirectInput8, (VOID* *)&g_pDI, NULL)))
{ {
MessageBox(0, "Direct Input Create Failed", 0, MB_ICONERROR); MessageBox(0, "Direct Input Create Failed", 0, MB_ICONERROR);
return(hr); return(hr);
} }
if (FAILED(hr = g_pDI->CreateDevice(GUID_SysKeyboard, &g_pKeyboard, NULL))) if (FAILED(hr = g_pDI->CreateDevice(GUID_SysKeyboard, &g_pKeyboard, NULL)))
{ {
MessageBox(0, "Couldn't access keyboard", 0, MB_ICONERROR); MessageBox(0, "Couldn't access keyboard", 0, MB_ICONERROR);
Free(); Free();
return(hr); return(hr);
} }
g_pKeyboard->SetDataFormat(&c_dfDIKeyboard); g_pKeyboard->SetDataFormat(&c_dfDIKeyboard);
g_pKeyboard->SetCooperativeLevel(hWnd, dwCoopFlags); g_pKeyboard->SetCooperativeLevel(hWnd, dwCoopFlags);
g_pKeyboard->Acquire(); g_pKeyboard->Acquire();
return(S_OK); return(S_OK);
} }
void DInput::Free() void DInput::Free()
{ {
if (g_pKeyboard) if (g_pKeyboard)
{ {
g_pKeyboard->Unacquire(); g_pKeyboard->Unacquire();
g_pKeyboard->Release(); g_pKeyboard->Release();
g_pKeyboard = 0; g_pKeyboard = 0;
} }
if (g_pDI) if (g_pDI)
{ {
g_pDI->Release(); g_pDI->Release();
g_pDI = 0; g_pDI = 0;
} }
} }
// Desc: Read the input device's state when in immediate mode and display it. // Desc: Read the input device's state when in immediate mode and display it.
HRESULT DInput::Read() HRESULT DInput::Read()
{ {
HRESULT hr; HRESULT hr;
if (NULL == g_pKeyboard) if (NULL == g_pKeyboard)
{ {
return(S_OK); return(S_OK);
} }
// Get the input's device state, and put the state in dims // Get the input's device state, and put the state in dims
ZeroMemory(diks, sizeof(diks)); ZeroMemory(diks, sizeof(diks));
hr = g_pKeyboard->GetDeviceState(sizeof(diks), diks); hr = g_pKeyboard->GetDeviceState(sizeof(diks), diks);
//for (int i=0; i<256; i++) //for (int i=0; i<256; i++)
// if (diks[i])MessageBox(0,"DSFJDKSF|",0,0); // if (diks[i])MessageBox(0,"DSFJDKSF|",0,0);
if (FAILED(hr)) if (FAILED(hr))
{ {
// DirectInput may be telling us that the input stream has been // DirectInput may be telling us that the input stream has been
// interrupted. We aren't tracking any state between polls, so // interrupted. We aren't tracking any state between polls, so
// we don't have any special reset that needs to be done. // we don't have any special reset that needs to be done.
// We just re-acquire and try again. // We just re-acquire and try again.
// If input is lost then acquire and keep trying // If input is lost then acquire and keep trying
hr = g_pKeyboard->Acquire(); hr = g_pKeyboard->Acquire();
while (hr == DIERR_INPUTLOST) while (hr == DIERR_INPUTLOST)
{ {
hr = g_pKeyboard->Acquire(); hr = g_pKeyboard->Acquire();
} }
// hr may be DIERR_OTHERAPPHASPRIO or other errors. This // hr may be DIERR_OTHERAPPHASPRIO or other errors. This
// may occur when the app is minimized or in the process of // may occur when the app is minimized or in the process of
// switching, so just try again later // switching, so just try again later
return(S_OK); return(S_OK);
} }
return(S_OK); return(S_OK);
} }

View File

@ -1,339 +1,339 @@
// 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 "ConfigDlg.h" #include "ConfigDlg.h"
#include "../PadSimple.h" #include "../PadSimple.h"
#ifdef _WIN32 #ifdef _WIN32
#include "XInput.h" #include "XInput.h"
#include "../DirectInputBase.h" #include "../DirectInputBase.h"
DInput m_dinput; DInput m_dinput;
#endif #endif
BEGIN_EVENT_TABLE(ConfigDialog,wxDialog) BEGIN_EVENT_TABLE(ConfigDialog,wxDialog)
EVT_CLOSE(ConfigDialog::OnClose) EVT_CLOSE(ConfigDialog::OnClose)
EVT_BUTTON(ID_CLOSE,ConfigDialog::OnCloseClick) EVT_BUTTON(ID_CLOSE,ConfigDialog::OnCloseClick)
EVT_BUTTON(ID_PAD_ABOUT,ConfigDialog::DllAbout) EVT_BUTTON(ID_PAD_ABOUT,ConfigDialog::DllAbout)
EVT_CHECKBOX(ID_ATTACHED,ConfigDialog::ControllerSettingsChanged) EVT_CHECKBOX(ID_ATTACHED,ConfigDialog::ControllerSettingsChanged)
EVT_CHECKBOX(ID_X360PAD,ConfigDialog::ControllerSettingsChanged) EVT_CHECKBOX(ID_X360PAD,ConfigDialog::ControllerSettingsChanged)
EVT_CHOICE(ID_X360PAD_CHOICE,ConfigDialog::ControllerSettingsChanged) EVT_CHOICE(ID_X360PAD_CHOICE,ConfigDialog::ControllerSettingsChanged)
EVT_CHECKBOX(ID_RUMBLE,ConfigDialog::ControllerSettingsChanged) EVT_CHECKBOX(ID_RUMBLE,ConfigDialog::ControllerSettingsChanged)
EVT_CHECKBOX(ID_DISABLE,ConfigDialog::ControllerSettingsChanged) EVT_CHECKBOX(ID_DISABLE,ConfigDialog::ControllerSettingsChanged)
EVT_BUTTON(CTL_A,ConfigDialog::OnButtonClick) EVT_BUTTON(CTL_A,ConfigDialog::OnButtonClick)
EVT_BUTTON(CTL_B,ConfigDialog::OnButtonClick) EVT_BUTTON(CTL_B,ConfigDialog::OnButtonClick)
EVT_BUTTON(CTL_X,ConfigDialog::OnButtonClick) EVT_BUTTON(CTL_X,ConfigDialog::OnButtonClick)
EVT_BUTTON(CTL_Y,ConfigDialog::OnButtonClick) EVT_BUTTON(CTL_Y,ConfigDialog::OnButtonClick)
EVT_BUTTON(CTL_Z,ConfigDialog::OnButtonClick) EVT_BUTTON(CTL_Z,ConfigDialog::OnButtonClick)
EVT_BUTTON(CTL_START,ConfigDialog::OnButtonClick) EVT_BUTTON(CTL_START,ConfigDialog::OnButtonClick)
EVT_BUTTON(CTL_L,ConfigDialog::OnButtonClick) EVT_BUTTON(CTL_L,ConfigDialog::OnButtonClick)
EVT_BUTTON(CTL_R,ConfigDialog::OnButtonClick) EVT_BUTTON(CTL_R,ConfigDialog::OnButtonClick)
EVT_BUTTON(CTL_MAINUP,ConfigDialog::OnButtonClick) EVT_BUTTON(CTL_MAINUP,ConfigDialog::OnButtonClick)
EVT_BUTTON(CTL_MAINDOWN,ConfigDialog::OnButtonClick) EVT_BUTTON(CTL_MAINDOWN,ConfigDialog::OnButtonClick)
EVT_BUTTON(CTL_MAINLEFT,ConfigDialog::OnButtonClick) EVT_BUTTON(CTL_MAINLEFT,ConfigDialog::OnButtonClick)
EVT_BUTTON(CTL_MAINRIGHT,ConfigDialog::OnButtonClick) EVT_BUTTON(CTL_MAINRIGHT,ConfigDialog::OnButtonClick)
EVT_BUTTON(CTL_SUBUP,ConfigDialog::OnButtonClick) EVT_BUTTON(CTL_SUBUP,ConfigDialog::OnButtonClick)
EVT_BUTTON(CTL_SUBDOWN,ConfigDialog::OnButtonClick) EVT_BUTTON(CTL_SUBDOWN,ConfigDialog::OnButtonClick)
EVT_BUTTON(CTL_SUBLEFT,ConfigDialog::OnButtonClick) EVT_BUTTON(CTL_SUBLEFT,ConfigDialog::OnButtonClick)
EVT_BUTTON(CTL_SUBRIGHT,ConfigDialog::OnButtonClick) EVT_BUTTON(CTL_SUBRIGHT,ConfigDialog::OnButtonClick)
EVT_BUTTON(CTL_DPADUP,ConfigDialog::OnButtonClick) EVT_BUTTON(CTL_DPADUP,ConfigDialog::OnButtonClick)
EVT_BUTTON(CTL_DPADDOWN,ConfigDialog::OnButtonClick) EVT_BUTTON(CTL_DPADDOWN,ConfigDialog::OnButtonClick)
EVT_BUTTON(CTL_DPADLEFT,ConfigDialog::OnButtonClick) EVT_BUTTON(CTL_DPADLEFT,ConfigDialog::OnButtonClick)
EVT_BUTTON(CTL_DPADRIGHT,ConfigDialog::OnButtonClick) EVT_BUTTON(CTL_DPADRIGHT,ConfigDialog::OnButtonClick)
EVT_BUTTON(CTL_HALFPRESS,ConfigDialog::OnButtonClick) EVT_BUTTON(CTL_HALFPRESS,ConfigDialog::OnButtonClick)
END_EVENT_TABLE() END_EVENT_TABLE()
ConfigDialog::ConfigDialog(wxWindow *parent, wxWindowID id, const wxString &title, const wxPoint &position, const wxSize& size, long style) ConfigDialog::ConfigDialog(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)
{ {
#ifdef _WIN32 #ifdef _WIN32
m_dinput.Init((HWND)parent); m_dinput.Init((HWND)parent);
#endif #endif
clickedButton = NULL; clickedButton = NULL;
CreateGUIControls(); CreateGUIControls();
Fit(); Fit();
} }
ConfigDialog::~ConfigDialog() ConfigDialog::~ConfigDialog()
{ {
} }
inline void AddControl(wxPanel *pan, wxButton **button, wxStaticBoxSizer *sizer, inline void AddControl(wxPanel *pan, wxButton **button, wxStaticBoxSizer *sizer,
const char *name, int ctl, int controller) const char *name, int ctl, int controller)
{ {
wxBoxSizer *hButton = new wxBoxSizer(wxHORIZONTAL); wxBoxSizer *hButton = new wxBoxSizer(wxHORIZONTAL);
char keyStr[10] = {0}; char keyStr[10] = {0};
hButton->Add(new wxStaticText(pan, 0, wxString::FromAscii(name), hButton->Add(new wxStaticText(pan, 0, wxString::FromAscii(name),
wxDefaultPosition, wxDefaultSize), 0, wxDefaultPosition, wxDefaultSize), 0,
wxALIGN_CENTER_VERTICAL|wxALL); wxALIGN_CENTER_VERTICAL|wxALL);
#ifdef _WIN32 #ifdef _WIN32
DInput::DIKToString(pad[controller].keyForControl[ctl], keyStr); DInput::DIKToString(pad[controller].keyForControl[ctl], keyStr);
#else #else
XKeyToString(pad[controller].keyForControl[ctl], keyStr); XKeyToString(pad[controller].keyForControl[ctl], keyStr);
#endif #endif
*button = new wxButton(pan, ctl, wxString::FromAscii(keyStr), *button = new wxButton(pan, ctl, wxString::FromAscii(keyStr),
wxDefaultPosition, wxDefaultSize, wxWANTS_CHARS); wxDefaultPosition, wxDefaultSize, wxWANTS_CHARS);
hButton->Add(*button, 0, wxALIGN_RIGHT|wxALL); hButton->Add(*button, 0, wxALIGN_RIGHT|wxALL);
sizer->Add(hButton, 0, wxALIGN_RIGHT|wxALL); sizer->Add(hButton, 0, wxALIGN_RIGHT|wxALL);
} }
void ConfigDialog::CreateGUIControls() void ConfigDialog::CreateGUIControls()
{ {
// Notebook // Notebook
m_Notebook = new wxNotebook(this, ID_NOTEBOOK, wxDefaultPosition, wxDefaultSize); m_Notebook = new wxNotebook(this, ID_NOTEBOOK, wxDefaultPosition, wxDefaultSize);
// Controller pages // Controller pages
m_Controller[0] = new wxPanel(m_Notebook, ID_CONTROLLERPAGE1, wxDefaultPosition, wxDefaultSize); m_Controller[0] = new wxPanel(m_Notebook, ID_CONTROLLERPAGE1, wxDefaultPosition, wxDefaultSize);
m_Notebook->AddPage(m_Controller[0], wxT("Controller 1")); m_Notebook->AddPage(m_Controller[0], wxT("Controller 1"));
m_Controller[1] = new wxPanel(m_Notebook, ID_CONTROLLERPAGE2, wxDefaultPosition, wxDefaultSize); m_Controller[1] = new wxPanel(m_Notebook, ID_CONTROLLERPAGE2, wxDefaultPosition, wxDefaultSize);
m_Notebook->AddPage(m_Controller[1], wxT("Controller 2")); m_Notebook->AddPage(m_Controller[1], wxT("Controller 2"));
m_Controller[2] = new wxPanel(m_Notebook, ID_CONTROLLERPAGE3, wxDefaultPosition, wxDefaultSize); m_Controller[2] = new wxPanel(m_Notebook, ID_CONTROLLERPAGE3, wxDefaultPosition, wxDefaultSize);
m_Notebook->AddPage(m_Controller[2], wxT("Controller 3")); m_Notebook->AddPage(m_Controller[2], wxT("Controller 3"));
m_Controller[3] = new wxPanel(m_Notebook, ID_CONTROLLERPAGE4, wxDefaultPosition, wxDefaultSize); m_Controller[3] = new wxPanel(m_Notebook, ID_CONTROLLERPAGE4, wxDefaultPosition, wxDefaultSize);
m_Notebook->AddPage(m_Controller[3], wxT("Controller 4")); m_Notebook->AddPage(m_Controller[3], wxT("Controller 4"));
// Standard buttons // Standard buttons
m_Close = new wxButton(this, ID_CLOSE, wxT("Close"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); m_Close = new wxButton(this, ID_CLOSE, wxT("Close"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
m_About = new wxButton(this, ID_PAD_ABOUT, wxT("About"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); m_About = new wxButton(this, ID_PAD_ABOUT, wxT("About"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
// Put notebook and standard buttons in sizers // Put notebook and standard buttons in sizers
wxBoxSizer* sSButtons; wxBoxSizer* sSButtons;
sSButtons = new wxBoxSizer(wxHORIZONTAL); sSButtons = new wxBoxSizer(wxHORIZONTAL);
sSButtons->Add(m_About,0,wxALL, 5); sSButtons->Add(m_About,0,wxALL, 5);
sSButtons->Add(0, 0, 1, wxEXPAND, 5); sSButtons->Add(0, 0, 1, wxEXPAND, 5);
sSButtons->Add(m_Close, 0, wxALL, 5); sSButtons->Add(m_Close, 0, wxALL, 5);
wxBoxSizer* sMain; wxBoxSizer* sMain;
sMain = new wxBoxSizer(wxVERTICAL); sMain = new wxBoxSizer(wxVERTICAL);
sMain->Add(m_Notebook, 1, wxEXPAND|wxALL, 5); sMain->Add(m_Notebook, 1, wxEXPAND|wxALL, 5);
sMain->Add(sSButtons, 0, wxEXPAND, 5); sMain->Add(sSButtons, 0, wxEXPAND, 5);
this->SetSizer(sMain); this->SetSizer(sMain);
this->Layout(); this->Layout();
#ifdef _WIN32 #ifdef _WIN32
// Add connected XPads // Add connected XPads
for (int x = 0; x < 4; x++) for (int x = 0; x < 4; x++)
{ {
XINPUT_STATE xstate; XINPUT_STATE xstate;
DWORD xresult = XInputGetState(x, &xstate); DWORD xresult = XInputGetState(x, &xstate);
if (xresult == ERROR_SUCCESS) if (xresult == ERROR_SUCCESS)
{ {
arrayStringFor_X360Pad.Add(wxString::Format("%i", x+1)); arrayStringFor_X360Pad.Add(wxString::Format("%i", x+1));
} }
} }
#endif #endif
for(int i = 0; i < 4; i++) for(int i = 0; i < 4; i++)
{ {
sbDevice[i] = new wxStaticBoxSizer(wxVERTICAL, m_Controller[i], wxT("Controller Settings")); sbDevice[i] = new wxStaticBoxSizer(wxVERTICAL, m_Controller[i], wxT("Controller Settings"));
sDevice[i] = new wxBoxSizer(wxHORIZONTAL); sDevice[i] = new wxBoxSizer(wxHORIZONTAL);
m_Attached[i] = new wxCheckBox(m_Controller[i], ID_ATTACHED, wxT("Controller attached"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); m_Attached[i] = new wxCheckBox(m_Controller[i], ID_ATTACHED, wxT("Controller attached"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
#ifdef _WIN32 #ifdef _WIN32
m_X360Pad[i] = new wxCheckBox(m_Controller[i], ID_X360PAD, wxT("Enable X360Pad"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); m_X360Pad[i] = new wxCheckBox(m_Controller[i], ID_X360PAD, wxT("Enable X360Pad"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
m_X360PadC[i] = new wxChoice(m_Controller[i], ID_X360PAD_CHOICE, wxDefaultPosition, wxDefaultSize, arrayStringFor_X360Pad, 0, wxDefaultValidator); m_X360PadC[i] = new wxChoice(m_Controller[i], ID_X360PAD_CHOICE, wxDefaultPosition, wxDefaultSize, arrayStringFor_X360Pad, 0, wxDefaultValidator);
m_Rumble[i] = new wxCheckBox(m_Controller[i], ID_RUMBLE, wxT("Enable rumble"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); m_Rumble[i] = new wxCheckBox(m_Controller[i], ID_RUMBLE, wxT("Enable rumble"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
#endif #endif
m_Disable[i] = new wxCheckBox(m_Controller[i], ID_DISABLE, wxT("Disable when Dolphin is not in focus"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); m_Disable[i] = new wxCheckBox(m_Controller[i], ID_DISABLE, wxT("Disable when Dolphin is not in focus"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
m_Attached[i]->SetValue(pad[i].bAttached); m_Attached[i]->SetValue(pad[i].bAttached);
#ifdef _WIN32 #ifdef _WIN32
if (arrayStringFor_X360Pad.IsEmpty()) if (arrayStringFor_X360Pad.IsEmpty())
{ {
m_X360Pad[i]->SetLabel(wxT("Enable X360Pad - No pad connected")); m_X360Pad[i]->SetLabel(wxT("Enable X360Pad - No pad connected"));
m_X360Pad[i]->SetValue(false); m_X360Pad[i]->SetValue(false);
m_X360Pad[i]->Enable(false); m_X360Pad[i]->Enable(false);
pad[i].bEnableXPad = false; pad[i].bEnableXPad = false;
m_X360PadC[i]->Hide(); m_X360PadC[i]->Hide();
m_Rumble[i]->Hide(); m_Rumble[i]->Hide();
} }
else else
{ {
m_X360Pad[i]->SetValue(pad[i].bEnableXPad); m_X360Pad[i]->SetValue(pad[i].bEnableXPad);
m_X360PadC[i]->SetSelection(pad[i].XPadPlayer); m_X360PadC[i]->SetSelection(pad[i].XPadPlayer);
m_X360PadC[i]->Enable(m_X360Pad[i]->IsChecked()); m_X360PadC[i]->Enable(m_X360Pad[i]->IsChecked());
m_Rumble[i]->SetValue(pad[i].bRumble); m_Rumble[i]->SetValue(pad[i].bRumble);
m_Rumble[i]->Enable(m_X360Pad[i]->IsChecked()); m_Rumble[i]->Enable(m_X360Pad[i]->IsChecked());
} }
#endif #endif
m_Disable[i]->SetValue(pad[i].bDisable); m_Disable[i]->SetValue(pad[i].bDisable);
sDevice[i]->Add(m_Attached[i], 0, wxEXPAND|wxALL, 1); sDevice[i]->Add(m_Attached[i], 0, wxEXPAND|wxALL, 1);
sDevice[i]->AddStretchSpacer(); sDevice[i]->AddStretchSpacer();
#ifdef _WIN32 #ifdef _WIN32
sDevice[i]->Add(m_X360Pad[i], 0, wxEXPAND|wxALL, 1); sDevice[i]->Add(m_X360Pad[i], 0, wxEXPAND|wxALL, 1);
sDevice[i]->Add(m_X360PadC[i], 0, wxEXPAND|wxALL, 1); sDevice[i]->Add(m_X360PadC[i], 0, wxEXPAND|wxALL, 1);
sDevice[i]->Add(m_Rumble[i], 0, wxEXPAND|wxALL, 1); sDevice[i]->Add(m_Rumble[i], 0, wxEXPAND|wxALL, 1);
sDevice[i]->AddStretchSpacer(); sDevice[i]->AddStretchSpacer();
#endif #endif
sDevice[i]->Add(m_Disable[i], 0, wxEXPAND|wxALL, 1); sDevice[i]->Add(m_Disable[i], 0, wxEXPAND|wxALL, 1);
sbDevice[i]->Add(sDevice[i], 0, wxEXPAND|wxALL, 1); sbDevice[i]->Add(sDevice[i], 0, wxEXPAND|wxALL, 1);
sButtons[i] = new wxStaticBoxSizer(wxVERTICAL, m_Controller[i], wxT("Buttons")); sButtons[i] = new wxStaticBoxSizer(wxVERTICAL, m_Controller[i], wxT("Buttons"));
AddControl(m_Controller[i], &(m_ButtonA[i]), sButtons[i], "A: ", CTL_A, i); AddControl(m_Controller[i], &(m_ButtonA[i]), sButtons[i], "A: ", CTL_A, i);
AddControl(m_Controller[i], &(m_ButtonB[i]), sButtons[i], "B: ", CTL_B, i); AddControl(m_Controller[i], &(m_ButtonB[i]), sButtons[i], "B: ", CTL_B, i);
AddControl(m_Controller[i], &(m_ButtonX[i]), sButtons[i], "X: ", CTL_X, i); AddControl(m_Controller[i], &(m_ButtonX[i]), sButtons[i], "X: ", CTL_X, i);
AddControl(m_Controller[i], &(m_ButtonY[i]), sButtons[i], "Y: ", CTL_Y, i); AddControl(m_Controller[i], &(m_ButtonY[i]), sButtons[i], "Y: ", CTL_Y, i);
AddControl(m_Controller[i], &(m_ButtonZ[i]), sButtons[i], "Z: ", CTL_Z, i); AddControl(m_Controller[i], &(m_ButtonZ[i]), sButtons[i], "Z: ", CTL_Z, i);
AddControl(m_Controller[i], &(m_ButtonStart[i]), sButtons[i], "Start: ", CTL_START, i); AddControl(m_Controller[i], &(m_ButtonStart[i]), sButtons[i], "Start: ", CTL_START, i);
sTriggers[i] = new wxStaticBoxSizer(wxVERTICAL, m_Controller[i], wxT("Triggers")); sTriggers[i] = new wxStaticBoxSizer(wxVERTICAL, m_Controller[i], wxT("Triggers"));
AddControl(m_Controller[i], &(m_ButtonL[i]), sTriggers[i], " L: ", CTL_L, i); AddControl(m_Controller[i], &(m_ButtonL[i]), sTriggers[i], " L: ", CTL_L, i);
AddControl(m_Controller[i], &(m_ButtonR[i]), sTriggers[i], " R: ", CTL_R, i); AddControl(m_Controller[i], &(m_ButtonR[i]), sTriggers[i], " R: ", CTL_R, i);
sModifiers[i] = new wxStaticBoxSizer(wxVERTICAL, m_Controller[i], wxT("Modifiers")); sModifiers[i] = new wxStaticBoxSizer(wxVERTICAL, m_Controller[i], wxT("Modifiers"));
AddControl(m_Controller[i], &(m_HalfPress[i]), sModifiers[i], "1/2 Press: ", CTL_HALFPRESS, i); AddControl(m_Controller[i], &(m_HalfPress[i]), sModifiers[i], "1/2 Press: ", CTL_HALFPRESS, i);
sStick[i] = new wxStaticBoxSizer(wxVERTICAL, m_Controller[i], wxT("Main Stick")); sStick[i] = new wxStaticBoxSizer(wxVERTICAL, m_Controller[i], wxT("Main Stick"));
AddControl(m_Controller[i], &(m_StickUp[i]), sStick[i], "Up: ", CTL_MAINUP, i); AddControl(m_Controller[i], &(m_StickUp[i]), sStick[i], "Up: ", CTL_MAINUP, i);
AddControl(m_Controller[i], &(m_StickDown[i]), sStick[i], "Down: ", CTL_MAINDOWN, i); AddControl(m_Controller[i], &(m_StickDown[i]), sStick[i], "Down: ", CTL_MAINDOWN, i);
AddControl(m_Controller[i], &(m_StickLeft[i]), sStick[i], "Left: ", CTL_MAINLEFT, i); AddControl(m_Controller[i], &(m_StickLeft[i]), sStick[i], "Left: ", CTL_MAINLEFT, i);
AddControl(m_Controller[i], &(m_StickRight[i]), sStick[i], "Right: ", CTL_MAINRIGHT, i); AddControl(m_Controller[i], &(m_StickRight[i]), sStick[i], "Right: ", CTL_MAINRIGHT, i);
sDPad[i] = new wxStaticBoxSizer(wxVERTICAL, m_Controller[i], wxT("D-Pad")); sDPad[i] = new wxStaticBoxSizer(wxVERTICAL, m_Controller[i], wxT("D-Pad"));
AddControl(m_Controller[i], &(m_DPadUp[i]), sDPad[i], "Up: ", CTL_DPADUP, i); AddControl(m_Controller[i], &(m_DPadUp[i]), sDPad[i], "Up: ", CTL_DPADUP, i);
AddControl(m_Controller[i], &(m_DPadDown[i]), sDPad[i], "Down: ", CTL_DPADDOWN, i); AddControl(m_Controller[i], &(m_DPadDown[i]), sDPad[i], "Down: ", CTL_DPADDOWN, i);
AddControl(m_Controller[i], &(m_DPadLeft[i]), sDPad[i], "Left: ", CTL_DPADLEFT, i); AddControl(m_Controller[i], &(m_DPadLeft[i]), sDPad[i], "Left: ", CTL_DPADLEFT, i);
AddControl(m_Controller[i], &(m_DPadRight[i]), sDPad[i], "Right: ", CTL_DPADRIGHT, i); AddControl(m_Controller[i], &(m_DPadRight[i]), sDPad[i], "Right: ", CTL_DPADRIGHT, i);
sCStick[i] = new wxStaticBoxSizer(wxVERTICAL, m_Controller[i], wxT("C-Stick")); sCStick[i] = new wxStaticBoxSizer(wxVERTICAL, m_Controller[i], wxT("C-Stick"));
AddControl(m_Controller[i], &(m_CStickUp[i]), sCStick[i], "Up: ", CTL_SUBUP, i); AddControl(m_Controller[i], &(m_CStickUp[i]), sCStick[i], "Up: ", CTL_SUBUP, i);
AddControl(m_Controller[i], &(m_CStickDown[i]), sCStick[i], "Down: ", CTL_SUBDOWN, i); AddControl(m_Controller[i], &(m_CStickDown[i]), sCStick[i], "Down: ", CTL_SUBDOWN, i);
AddControl(m_Controller[i], &(m_CStickLeft[i]), sCStick[i], "Left: ", CTL_SUBLEFT, i); AddControl(m_Controller[i], &(m_CStickLeft[i]), sCStick[i], "Left: ", CTL_SUBLEFT, i);
AddControl(m_Controller[i], &(m_CStickRight[i]), sCStick[i], "Right: ", CTL_SUBRIGHT, i); AddControl(m_Controller[i], &(m_CStickRight[i]), sCStick[i], "Right: ", CTL_SUBRIGHT, i);
sPage[i] = new wxGridBagSizer(0, 0); sPage[i] = new wxGridBagSizer(0, 0);
sPage[i]->SetFlexibleDirection(wxBOTH); sPage[i]->SetFlexibleDirection(wxBOTH);
sPage[i]->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED); sPage[i]->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED);
sPage[i]->Add(sbDevice[i], wxGBPosition(0, 0), wxGBSpan(1, 5), wxEXPAND|wxALL, 1); sPage[i]->Add(sbDevice[i], wxGBPosition(0, 0), wxGBSpan(1, 5), wxEXPAND|wxALL, 1);
sPage[i]->Add(sButtons[i], wxGBPosition(1, 0), wxGBSpan(2, 1), wxALL, 1); sPage[i]->Add(sButtons[i], wxGBPosition(1, 0), wxGBSpan(2, 1), wxALL, 1);
sPage[i]->Add(sTriggers[i], wxGBPosition(1, 1), wxGBSpan(1, 1), wxEXPAND|wxALL, 1); sPage[i]->Add(sTriggers[i], wxGBPosition(1, 1), wxGBSpan(1, 1), wxEXPAND|wxALL, 1);
sPage[i]->Add(sModifiers[i], wxGBPosition(2, 1), wxGBSpan(1, 1), wxALL, 1); sPage[i]->Add(sModifiers[i], wxGBPosition(2, 1), wxGBSpan(1, 1), wxALL, 1);
sPage[i]->Add(sStick[i], wxGBPosition(1, 2), wxGBSpan(2, 1), wxALL, 1); sPage[i]->Add(sStick[i], wxGBPosition(1, 2), wxGBSpan(2, 1), wxALL, 1);
sPage[i]->Add(sDPad[i], wxGBPosition(1, 3), wxGBSpan(2, 1), wxALL, 1); sPage[i]->Add(sDPad[i], wxGBPosition(1, 3), wxGBSpan(2, 1), wxALL, 1);
sPage[i]->Add(sCStick[i], wxGBPosition(1, 4), wxGBSpan(2, 1), wxALL, 1); sPage[i]->Add(sCStick[i], wxGBPosition(1, 4), wxGBSpan(2, 1), wxALL, 1);
m_Controller[i]->SetSizer(sPage[i]); m_Controller[i]->SetSizer(sPage[i]);
sPage[i]->Layout(); sPage[i]->Layout();
} }
} }
void ConfigDialog::OnClose(wxCloseEvent& event) void ConfigDialog::OnClose(wxCloseEvent& event)
{ {
#ifdef _WIN32 #ifdef _WIN32
m_dinput.Free(); m_dinput.Free();
#endif #endif
EndModal(0); EndModal(0);
} }
void ConfigDialog::OnKeyDown(wxKeyEvent& event) void ConfigDialog::OnKeyDown(wxKeyEvent& event)
{ {
if(clickedButton != NULL) if(clickedButton != NULL)
{ {
int page = m_Notebook->GetSelection(); int page = m_Notebook->GetSelection();
#ifdef _WIN32 #ifdef _WIN32
m_dinput.Read(); m_dinput.Read();
for(int i = 0; i < 255; i++) for(int i = 0; i < 255; i++)
{ {
if(m_dinput.diks[i]) if(m_dinput.diks[i])
{ {
char keyStr[10] = {0}; char keyStr[10] = {0};
pad[page].keyForControl[clickedButton->GetId()] = i; pad[page].keyForControl[clickedButton->GetId()] = i;
DInput::DIKToString(i, keyStr); DInput::DIKToString(i, keyStr);
clickedButton->SetLabel(wxString::FromAscii(keyStr)); clickedButton->SetLabel(wxString::FromAscii(keyStr));
break; break;
} }
} }
#else #else
pad[page].keyForControl[clickedButton->GetId()] = wxCharCodeWXToX(event.GetKeyCode()); pad[page].keyForControl[clickedButton->GetId()] = wxCharCodeWXToX(event.GetKeyCode());
clickedButton->SetLabel(wxString::Format(_T("%c"), event.GetKeyCode())); clickedButton->SetLabel(wxString::Format(_T("%c"), event.GetKeyCode()));
#endif #endif
clickedButton->Disconnect(); clickedButton->Disconnect();
} }
clickedButton = NULL; clickedButton = NULL;
event.Skip(); event.Skip();
} }
void ConfigDialog::OnCloseClick(wxCommandEvent& event) void ConfigDialog::OnCloseClick(wxCommandEvent& event)
{ {
Close(); Close();
} }
void ConfigDialog::ControllerSettingsChanged(wxCommandEvent& event) void ConfigDialog::ControllerSettingsChanged(wxCommandEvent& event)
{ {
int page = m_Notebook->GetSelection(); int page = m_Notebook->GetSelection();
switch (event.GetId()) switch (event.GetId())
{ {
case ID_ATTACHED: case ID_ATTACHED:
pad[page].bAttached = m_Attached[page]->GetValue(); pad[page].bAttached = m_Attached[page]->GetValue();
break; break;
case ID_X360PAD: case ID_X360PAD:
pad[page].bEnableXPad = event.IsChecked(); pad[page].bEnableXPad = event.IsChecked();
m_Rumble[page]->Enable(event.IsChecked()); m_Rumble[page]->Enable(event.IsChecked());
m_X360PadC[page]->Enable(event.IsChecked()); m_X360PadC[page]->Enable(event.IsChecked());
break; break;
case ID_X360PAD_CHOICE: case ID_X360PAD_CHOICE:
pad[page].XPadPlayer = event.GetSelection(); pad[page].XPadPlayer = event.GetSelection();
break; break;
case ID_RUMBLE: case ID_RUMBLE:
pad[page].bRumble = m_Rumble[page]->GetValue(); pad[page].bRumble = m_Rumble[page]->GetValue();
break; break;
case ID_DISABLE: case ID_DISABLE:
pad[page].bDisable = m_Disable[page]->GetValue(); pad[page].bDisable = m_Disable[page]->GetValue();
break; break;
} }
} }
void ConfigDialog::OnButtonClick(wxCommandEvent& event) void ConfigDialog::OnButtonClick(wxCommandEvent& event)
{ {
if(clickedButton) if(clickedButton)
{ {
clickedButton->SetLabel(oldLabel); clickedButton->SetLabel(oldLabel);
} }
clickedButton = (wxButton *)event.GetEventObject(); clickedButton = (wxButton *)event.GetEventObject();
oldLabel = clickedButton->GetLabel(); oldLabel = clickedButton->GetLabel();
clickedButton->SetLabel(_("Press Key")); clickedButton->SetLabel(_("Press Key"));
clickedButton->Connect(wxID_ANY, wxEVT_KEY_DOWN, clickedButton->Connect(wxID_ANY, wxEVT_KEY_DOWN,
wxKeyEventHandler(ConfigDialog::OnKeyDown), wxKeyEventHandler(ConfigDialog::OnKeyDown),
(wxObject*)NULL, this); (wxObject*)NULL, this);
} }
void ConfigDialog::DllAbout(wxCommandEvent& event) void ConfigDialog::DllAbout(wxCommandEvent& event)
{ {
wxString message; wxString message;
#ifdef _WIN32 #ifdef _WIN32
message = _("A simple keyboard and XInput plugin for dolphin."); message = _("A simple keyboard and XInput plugin for dolphin.");
#else #else
message = _("A simple keyboard plugin for dolphin."); message = _("A simple keyboard plugin for dolphin.");
#endif #endif
wxMessageBox(_T("Dolphin PadSimple Plugin\nBy ector and F|RES\n\n" + message), wxMessageBox(_T("Dolphin PadSimple Plugin\nBy ector and F|RES\n\n" + message),
_T("Dolphin PadSimple"), wxOK, this); _T("Dolphin PadSimple"), wxOK, this);
} }

View File

@ -1,18 +1,18 @@
// 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 "stdafx.h" #include "stdafx.h"

File diff suppressed because it is too large Load Diff

View File

@ -1,76 +1,76 @@
// 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 <stdio.h> #include <stdio.h>
#include "CPStructs.h" #include "CPStructs.h"
#include "XFStructs.h" #include "XFStructs.h"
#include "TransformEngine.h" #include "TransformEngine.h"
#include "VertexManager.h" #include "VertexManager.h"
#include "VertexLoader.h" #include "VertexLoader.h"
// PROBLEM - matrix switching within vbuffers may be stateful! // PROBLEM - matrix switching within vbuffers may be stateful!
void CPUpdateMatricesA() void CPUpdateMatricesA()
{ {
float *flipmem = (float *)xfmem; float *flipmem = (float *)xfmem;
CTransformEngine::SetPosNormalMatrix( CTransformEngine::SetPosNormalMatrix(
flipmem + MatrixIndexA.PosNormalMtxIdx * 4, //CHECK flipmem + MatrixIndexA.PosNormalMtxIdx * 4, //CHECK
flipmem + 0x400 + 3 * (MatrixIndexA.PosNormalMtxIdx & 31)); //CHECK flipmem + 0x400 + 3 * (MatrixIndexA.PosNormalMtxIdx & 31)); //CHECK
CTransformEngine::SetTexMatrix(0,flipmem + MatrixIndexA.Tex0MtxIdx * 4); CTransformEngine::SetTexMatrix(0,flipmem + MatrixIndexA.Tex0MtxIdx * 4);
CTransformEngine::SetTexMatrix(1,flipmem + MatrixIndexA.Tex1MtxIdx * 4); CTransformEngine::SetTexMatrix(1,flipmem + MatrixIndexA.Tex1MtxIdx * 4);
CTransformEngine::SetTexMatrix(2,flipmem + MatrixIndexA.Tex2MtxIdx * 4); CTransformEngine::SetTexMatrix(2,flipmem + MatrixIndexA.Tex2MtxIdx * 4);
CTransformEngine::SetTexMatrix(3,flipmem + MatrixIndexA.Tex3MtxIdx * 4); CTransformEngine::SetTexMatrix(3,flipmem + MatrixIndexA.Tex3MtxIdx * 4);
} }
void CPUpdateMatricesB() void CPUpdateMatricesB()
{ {
float *flipmem = (float *)xfmem; float *flipmem = (float *)xfmem;
CTransformEngine::SetTexMatrix(4,flipmem + MatrixIndexB.Tex4MtxIdx * 4); CTransformEngine::SetTexMatrix(4,flipmem + MatrixIndexB.Tex4MtxIdx * 4);
CTransformEngine::SetTexMatrix(5,flipmem + MatrixIndexB.Tex5MtxIdx * 4); CTransformEngine::SetTexMatrix(5,flipmem + MatrixIndexB.Tex5MtxIdx * 4);
CTransformEngine::SetTexMatrix(6,flipmem + MatrixIndexB.Tex6MtxIdx * 4); CTransformEngine::SetTexMatrix(6,flipmem + MatrixIndexB.Tex6MtxIdx * 4);
CTransformEngine::SetTexMatrix(7,flipmem + MatrixIndexB.Tex7MtxIdx * 4); CTransformEngine::SetTexMatrix(7,flipmem + MatrixIndexB.Tex7MtxIdx * 4);
} }
void LoadCPReg(u32 SubCmd, u32 Value) void LoadCPReg(u32 SubCmd, u32 Value)
{ {
switch (SubCmd & 0xF0) switch (SubCmd & 0xF0)
{ {
case 0x30: case 0x30:
MatrixIndexA.Hex = Value; MatrixIndexA.Hex = Value;
CPUpdateMatricesA(); CPUpdateMatricesA();
break; break;
case 0x40: case 0x40:
MatrixIndexB.Hex = Value; MatrixIndexB.Hex = Value;
CPUpdateMatricesB(); CPUpdateMatricesB();
break; break;
case 0x50: case 0x50:
VertexManager::Flush(); VertexLoader::SetVtxDesc_Lo(Value); VertexManager::Flush(); VertexLoader::SetVtxDesc_Lo(Value);
break; break;
case 0x60: case 0x60:
VertexManager::Flush(); VertexLoader::SetVtxDesc_Hi(Value); VertexManager::Flush(); VertexLoader::SetVtxDesc_Hi(Value);
break; break;
case 0x70: g_VertexLoaders[SubCmd & 7].SetVAT_group0(Value); _assert_((SubCmd & 0x0F) < 8); break; case 0x70: g_VertexLoaders[SubCmd & 7].SetVAT_group0(Value); _assert_((SubCmd & 0x0F) < 8); break;
case 0x80: g_VertexLoaders[SubCmd & 7].SetVAT_group1(Value); _assert_((SubCmd & 0x0F) < 8); break; case 0x80: g_VertexLoaders[SubCmd & 7].SetVAT_group1(Value); _assert_((SubCmd & 0x0F) < 8); break;
case 0x90: g_VertexLoaders[SubCmd & 7].SetVAT_group2(Value); _assert_((SubCmd & 0x0F) < 8); break; case 0x90: g_VertexLoaders[SubCmd & 7].SetVAT_group2(Value); _assert_((SubCmd & 0x0F) < 8); break;
case 0xA0: arraybases[SubCmd & 0xF] = Value & 0xFFFFFFFF; break; case 0xA0: arraybases[SubCmd & 0xF] = Value & 0xFFFFFFFF; break;
case 0xB0: arraystrides[SubCmd & 0xF] = Value & 0xFF; break; case 0xB0: arraystrides[SubCmd & 0xF] = Value & 0xFF; break;
} }
} }

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 "Config.h" #include "Config.h"
#include "IniFile.h" #include "IniFile.h"
Config g_Config; Config g_Config;
Config::Config() Config::Config()
{ {
} }
void Config::Load() void Config::Load()
{ {
IniFile iniFile; IniFile iniFile;
iniFile.Load(FULL_CONFIG_DIR "gfx_dx9.ini"); iniFile.Load(FULL_CONFIG_DIR "gfx_dx9.ini");
iniFile.Get("Hardware", "Adapter", &iAdapter, 0); iniFile.Get("Hardware", "Adapter", &iAdapter, 0);
iniFile.Get("Hardware", "WindowedRes", &iWindowedRes, 0); iniFile.Get("Hardware", "WindowedRes", &iWindowedRes, 0);
iniFile.Get("Hardware", "FullscreenRes", &iFSResolution, 0); iniFile.Get("Hardware", "FullscreenRes", &iFSResolution, 0);
iniFile.Get("Hardware", "Fullscreen", &bFullscreen, 0); iniFile.Get("Hardware", "Fullscreen", &bFullscreen, 0);
iniFile.Get("Hardware", "RenderInMainframe", &renderToMainframe, false); iniFile.Get("Hardware", "RenderInMainframe", &renderToMainframe, false);
iniFile.Get("Hardware", "VSync", &bVsync, 0); iniFile.Get("Hardware", "VSync", &bVsync, 0);
if (iAdapter == -1) if (iAdapter == -1)
iAdapter = 0; iAdapter = 0;
iniFile.Get("Settings", "OverlayStats", &bOverlayStats, false); iniFile.Get("Settings", "OverlayStats", &bOverlayStats, false);
iniFile.Get("Settings", "Postprocess", &iPostprocessEffect, 0); iniFile.Get("Settings", "Postprocess", &iPostprocessEffect, 0);
iniFile.Get("Settings", "DLOptimize", &iCompileDLsLevel, 0); iniFile.Get("Settings", "DLOptimize", &iCompileDLsLevel, 0);
iniFile.Get("Settings", "DumpTextures", &bDumpTextures, 0); iniFile.Get("Settings", "DumpTextures", &bDumpTextures, 0);
iniFile.Get("Settings", "ShowShaderErrors", &bShowShaderErrors, 0); iniFile.Get("Settings", "ShowShaderErrors", &bShowShaderErrors, 0);
iniFile.Get("Settings", "Multisample", &iMultisampleMode, 0); iniFile.Get("Settings", "Multisample", &iMultisampleMode, 0);
iniFile.Get("Settings", "TexDumpPath", &texDumpPath, 0); iniFile.Get("Settings", "TexDumpPath", &texDumpPath, 0);
iniFile.Get("Settings", "TexFmtOverlayEnable", &bTexFmtOverlayEnable, 0); iniFile.Get("Settings", "TexFmtOverlayEnable", &bTexFmtOverlayEnable, 0);
iniFile.Get("Settings", "TexFmtOverlayCenter", &bTexFmtOverlayCenter, 0); iniFile.Get("Settings", "TexFmtOverlayCenter", &bTexFmtOverlayCenter, 0);
iniFile.Get("Enhancements", "ForceFiltering", &bForceFiltering, 0); iniFile.Get("Enhancements", "ForceFiltering", &bForceFiltering, 0);
iniFile.Get("Enhancements", "ForceMaxAniso", &bForceMaxAniso, 0); iniFile.Get("Enhancements", "ForceMaxAniso", &bForceMaxAniso, 0);
} }
void Config::Save() void Config::Save()
{ {
IniFile iniFile; IniFile iniFile;
iniFile.Load(FULL_CONFIG_DIR "gfx_dx9.ini"); iniFile.Load(FULL_CONFIG_DIR "gfx_dx9.ini");
iniFile.Set("Hardware", "Adapter", iAdapter); iniFile.Set("Hardware", "Adapter", iAdapter);
iniFile.Set("Hardware", "WindowedRes", iWindowedRes); iniFile.Set("Hardware", "WindowedRes", iWindowedRes);
iniFile.Set("Hardware", "FullscreenRes", iFSResolution); iniFile.Set("Hardware", "FullscreenRes", iFSResolution);
iniFile.Set("Hardware", "Fullscreen", bFullscreen); iniFile.Set("Hardware", "Fullscreen", bFullscreen);
iniFile.Set("Hardware", "VSync", bVsync); iniFile.Set("Hardware", "VSync", bVsync);
iniFile.Set("Hardware", "RenderInMainframe", renderToMainframe); iniFile.Set("Hardware", "RenderInMainframe", renderToMainframe);
iniFile.Set("Settings", "OverlayStats", bOverlayStats); iniFile.Set("Settings", "OverlayStats", bOverlayStats);
iniFile.Set("Settings", "OverlayStats", bOverlayStats); iniFile.Set("Settings", "OverlayStats", bOverlayStats);
iniFile.Set("Settings", "Postprocess", iPostprocessEffect); iniFile.Set("Settings", "Postprocess", iPostprocessEffect);
iniFile.Set("Settings", "DLOptimize", iCompileDLsLevel); iniFile.Set("Settings", "DLOptimize", iCompileDLsLevel);
iniFile.Set("Settings", "DumpTextures", bDumpTextures); iniFile.Set("Settings", "DumpTextures", bDumpTextures);
iniFile.Set("Settings", "ShowShaderErrors", bShowShaderErrors); iniFile.Set("Settings", "ShowShaderErrors", bShowShaderErrors);
iniFile.Set("Settings", "Multisample", iMultisampleMode); iniFile.Set("Settings", "Multisample", iMultisampleMode);
iniFile.Set("Settings", "TexDumpPath", texDumpPath); iniFile.Set("Settings", "TexDumpPath", texDumpPath);
iniFile.Set("Settings", "TexFmtOverlayEnable", bTexFmtOverlayEnable); iniFile.Set("Settings", "TexFmtOverlayEnable", bTexFmtOverlayEnable);
iniFile.Set("Settings", "TexFmtOverlayCenter", bTexFmtOverlayCenter); iniFile.Set("Settings", "TexFmtOverlayCenter", bTexFmtOverlayCenter);
iniFile.Set("Enhancements", "ForceFiltering", bForceFiltering); iniFile.Set("Enhancements", "ForceFiltering", bForceFiltering);
iniFile.Set("Enhancements", "ForceMaxAniso", bForceMaxAniso); iniFile.Set("Enhancements", "ForceMaxAniso", bForceMaxAniso);
iniFile.Save(FULL_CONFIG_DIR "gfx_dx9.ini"); iniFile.Save(FULL_CONFIG_DIR "gfx_dx9.ini");
} }

View File

@ -1,389 +1,389 @@
// 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 "Render.h" #include "Render.h"
namespace D3D namespace D3D
{ {
bool fullScreen = false, nextFullScreen=false; bool fullScreen = false, nextFullScreen=false;
LPDIRECT3D9 D3D = NULL; // Used to create the D3DDevice LPDIRECT3D9 D3D = NULL; // Used to create the D3DDevice
LPDIRECT3DDEVICE9 dev = NULL; // Our rendering device LPDIRECT3DDEVICE9 dev = NULL; // Our rendering device
LPDIRECT3DSURFACE9 backBuffer; LPDIRECT3DSURFACE9 backBuffer;
D3DCAPS9 caps; D3DCAPS9 caps;
int multisample; int multisample;
int resolution; int resolution;
#define VENDOR_NVIDIA 4318 #define VENDOR_NVIDIA 4318
RECT client; RECT client;
HWND hWnd; HWND hWnd;
int xres, yres; int xres, yres;
int cur_adapter; int cur_adapter;
Shader Ps; Shader Ps;
Shader Vs; Shader Vs;
bool bFrameInProgress = false; bool bFrameInProgress = false;
//enum shit //enum shit
Adapter adapters[4]; Adapter adapters[4];
int numAdapters; int numAdapters;
void Enumerate(); void Enumerate();
int GetNumAdapters() int GetNumAdapters()
{ {
return numAdapters; return numAdapters;
} }
const Adapter &GetAdapter(int i) const Adapter &GetAdapter(int i)
{ {
return adapters[i]; return adapters[i];
} }
const Adapter &GetCurAdapter() const Adapter &GetCurAdapter()
{ {
return adapters[cur_adapter]; return adapters[cur_adapter];
} }
HRESULT Init() HRESULT Init()
{ {
// Create the D3D object, which is needed to create the D3DDevice. // Create the D3D object, which is needed to create the D3DDevice.
if( NULL == ( D3D = Direct3DCreate9( D3D_SDK_VERSION ) ) ) if( NULL == ( D3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
return E_FAIL; return E_FAIL;
Enumerate(); Enumerate();
return S_OK; return S_OK;
} }
void EnableAlphaToCoverage() void EnableAlphaToCoverage()
{ {
// dev->SetRenderState(D3DRS_ADAPTIVETESS_Y, (D3DFORMAT)MAKEFOURCC('A', 'T', 'O', 'C')); // dev->SetRenderState(D3DRS_ADAPTIVETESS_Y, (D3DFORMAT)MAKEFOURCC('A', 'T', 'O', 'C'));
Renderer::SetRenderState( D3DRS_ADAPTIVETESS_Y, (D3DFORMAT)MAKEFOURCC('A', 'T', 'O', 'C') ); Renderer::SetRenderState( D3DRS_ADAPTIVETESS_Y, (D3DFORMAT)MAKEFOURCC('A', 'T', 'O', 'C') );
} }
void InitPP(int adapter, int resolution, int aa_mode, D3DPRESENT_PARAMETERS *pp) void InitPP(int adapter, int resolution, int aa_mode, D3DPRESENT_PARAMETERS *pp)
{ {
int FSResX = adapters[adapter].resolutions[resolution].xres; int FSResX = adapters[adapter].resolutions[resolution].xres;
int FSResY = adapters[adapter].resolutions[resolution].yres; int FSResY = adapters[adapter].resolutions[resolution].yres;
ZeroMemory(pp, sizeof(D3DPRESENT_PARAMETERS)); ZeroMemory(pp, sizeof(D3DPRESENT_PARAMETERS));
pp->hDeviceWindow = hWnd; pp->hDeviceWindow = hWnd;
pp->EnableAutoDepthStencil = TRUE; pp->EnableAutoDepthStencil = TRUE;
pp->AutoDepthStencilFormat = D3DFMT_D24S8; pp->AutoDepthStencilFormat = D3DFMT_D24S8;
pp->BackBufferFormat = D3DFMT_A8R8G8B8; pp->BackBufferFormat = D3DFMT_A8R8G8B8;
if (aa_mode >= (int)adapters[adapter].aa_levels.size()) if (aa_mode >= (int)adapters[adapter].aa_levels.size())
aa_mode = 0; aa_mode = 0;
pp->MultiSampleType = adapters[adapter].aa_levels[aa_mode].ms_setting; pp->MultiSampleType = adapters[adapter].aa_levels[aa_mode].ms_setting;
pp->MultiSampleQuality = adapters[adapter].aa_levels[aa_mode].qual_setting; pp->MultiSampleQuality = adapters[adapter].aa_levels[aa_mode].qual_setting;
pp->Flags = D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL; pp->Flags = D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL;
//D3DPRESENTFLAG_LOCKABLE_BACKBUFFER //D3DPRESENTFLAG_LOCKABLE_BACKBUFFER
if (fullScreen) if (fullScreen)
{ {
xres = pp->BackBufferWidth = FSResX; xres = pp->BackBufferWidth = FSResX;
yres = pp->BackBufferHeight = FSResY; yres = pp->BackBufferHeight = FSResY;
pp->SwapEffect = D3DSWAPEFFECT_DISCARD; pp->SwapEffect = D3DSWAPEFFECT_DISCARD;
pp->Windowed = FALSE; pp->Windowed = FALSE;
} }
else else
{ {
GetClientRect(hWnd, &client); GetClientRect(hWnd, &client);
xres = pp->BackBufferWidth = client.right - client.left; xres = pp->BackBufferWidth = client.right - client.left;
yres = pp->BackBufferHeight = client.bottom - client.top; yres = pp->BackBufferHeight = client.bottom - client.top;
pp->SwapEffect = D3DSWAPEFFECT_DISCARD; pp->SwapEffect = D3DSWAPEFFECT_DISCARD;
pp->PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; pp->PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
pp->Windowed = TRUE; pp->Windowed = TRUE;
} }
} }
void Enumerate() void Enumerate()
{ {
numAdapters = D3D::D3D->GetAdapterCount(); numAdapters = D3D::D3D->GetAdapterCount();
for (int i=0; i<numAdapters; i++) for (int i=0; i<numAdapters; i++)
{ {
Adapter &a = adapters[i]; Adapter &a = adapters[i];
D3D::D3D->GetAdapterIdentifier(i, 0, &a.ident); D3D::D3D->GetAdapterIdentifier(i, 0, &a.ident);
bool isNvidia = a.ident.VendorId == VENDOR_NVIDIA; bool isNvidia = a.ident.VendorId == VENDOR_NVIDIA;
// Add multisample modes // Add multisample modes
a.aa_levels.push_back(AALevel("None", D3DMULTISAMPLE_NONE, 0)); a.aa_levels.push_back(AALevel("None", D3DMULTISAMPLE_NONE, 0));
DWORD qlevels = 0; DWORD qlevels = 0;
if (D3DERR_NOTAVAILABLE != D3D::D3D->CheckDeviceMultiSampleType( if (D3DERR_NOTAVAILABLE != D3D::D3D->CheckDeviceMultiSampleType(
i, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, &qlevels)) i, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, &qlevels))
if (qlevels > 0) if (qlevels > 0)
a.aa_levels.push_back(AALevel("2x MSAA", D3DMULTISAMPLE_2_SAMPLES, 0)); a.aa_levels.push_back(AALevel("2x MSAA", D3DMULTISAMPLE_2_SAMPLES, 0));
if (D3DERR_NOTAVAILABLE != D3D::D3D->CheckDeviceMultiSampleType( if (D3DERR_NOTAVAILABLE != D3D::D3D->CheckDeviceMultiSampleType(
i, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, &qlevels)) i, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_2_SAMPLES, &qlevels))
if (qlevels > 0) if (qlevels > 0)
a.aa_levels.push_back(AALevel("4x MSAA", D3DMULTISAMPLE_4_SAMPLES, 0)); a.aa_levels.push_back(AALevel("4x MSAA", D3DMULTISAMPLE_4_SAMPLES, 0));
if (D3DERR_NOTAVAILABLE != D3D::D3D->CheckDeviceMultiSampleType( if (D3DERR_NOTAVAILABLE != D3D::D3D->CheckDeviceMultiSampleType(
i, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_8_SAMPLES, &qlevels)) i, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_8_SAMPLES, &qlevels))
if (qlevels > 0) if (qlevels > 0)
a.aa_levels.push_back(AALevel("8x MSAA", D3DMULTISAMPLE_8_SAMPLES, 0)); a.aa_levels.push_back(AALevel("8x MSAA", D3DMULTISAMPLE_8_SAMPLES, 0));
if (isNvidia) if (isNvidia)
{ {
// CSAA support // CSAA support
if (D3DERR_NOTAVAILABLE != D3D::D3D->CheckDeviceMultiSampleType( if (D3DERR_NOTAVAILABLE != D3D::D3D->CheckDeviceMultiSampleType(
i, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_4_SAMPLES, &qlevels)) i, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_4_SAMPLES, &qlevels))
{ {
if (qlevels > 2) if (qlevels > 2)
{ {
// 8x, 8xQ are available // 8x, 8xQ are available
// See http://developer.nvidia.com/object/coverage-sampled-aa.html // See http://developer.nvidia.com/object/coverage-sampled-aa.html
a.aa_levels.push_back(AALevel("8x CSAA", D3DMULTISAMPLE_4_SAMPLES, 2)); a.aa_levels.push_back(AALevel("8x CSAA", D3DMULTISAMPLE_4_SAMPLES, 2));
a.aa_levels.push_back(AALevel("8xQ CSAA", D3DMULTISAMPLE_8_SAMPLES, 0)); a.aa_levels.push_back(AALevel("8xQ CSAA", D3DMULTISAMPLE_8_SAMPLES, 0));
} }
} }
if (D3DERR_NOTAVAILABLE != D3D::D3D->CheckDeviceMultiSampleType( if (D3DERR_NOTAVAILABLE != D3D::D3D->CheckDeviceMultiSampleType(
i, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_8_SAMPLES, &qlevels)) i, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, TRUE, D3DMULTISAMPLE_8_SAMPLES, &qlevels))
{ {
if (qlevels > 2) if (qlevels > 2)
{ {
// 8x, 8xQ are available // 8x, 8xQ are available
// See http://developer.nvidia.com/object/coverage-sampled-aa.html // See http://developer.nvidia.com/object/coverage-sampled-aa.html
a.aa_levels.push_back(AALevel("16x CSAA", D3DMULTISAMPLE_4_SAMPLES, 4)); a.aa_levels.push_back(AALevel("16x CSAA", D3DMULTISAMPLE_4_SAMPLES, 4));
a.aa_levels.push_back(AALevel("16xQ CSAA", D3DMULTISAMPLE_8_SAMPLES, 2)); a.aa_levels.push_back(AALevel("16xQ CSAA", D3DMULTISAMPLE_8_SAMPLES, 2));
} }
} }
} }
if (a.aa_levels.size() == 1) if (a.aa_levels.size() == 1)
{ {
strcpy(a.aa_levels[0].name, "(Not supported on this device)"); strcpy(a.aa_levels[0].name, "(Not supported on this device)");
} }
int numModes = D3D::D3D->GetAdapterModeCount(i, D3DFMT_X8R8G8B8); int numModes = D3D::D3D->GetAdapterModeCount(i, D3DFMT_X8R8G8B8);
for (int m = 0; m < numModes; m++) for (int m = 0; m < numModes; m++)
{ {
D3DDISPLAYMODE mode; D3DDISPLAYMODE mode;
D3D::D3D->EnumAdapterModes(i, D3DFMT_X8R8G8B8, m, &mode); D3D::D3D->EnumAdapterModes(i, D3DFMT_X8R8G8B8, m, &mode);
int found = -1; int found = -1;
for (int x = 0; x < (int)a.resolutions.size(); x++) for (int x = 0; x < (int)a.resolutions.size(); x++)
{ {
if (a.resolutions[x].xres == mode.Width && a.resolutions[x].yres == mode.Height) if (a.resolutions[x].xres == mode.Width && a.resolutions[x].yres == mode.Height)
{ {
found = x; found = x;
break; break;
} }
} }
Resolution temp; Resolution temp;
Resolution &r = found==-1 ? temp : a.resolutions[found]; Resolution &r = found==-1 ? temp : a.resolutions[found];
sprintf(r.name, "%ix%i", mode.Width, mode.Height); sprintf(r.name, "%ix%i", mode.Width, mode.Height);
r.bitdepths.insert(mode.Format); r.bitdepths.insert(mode.Format);
r.refreshes.insert(mode.RefreshRate); r.refreshes.insert(mode.RefreshRate);
if (found == -1 && mode.Width >= 640 && mode.Height >= 480) if (found == -1 && mode.Width >= 640 && mode.Height >= 480)
{ {
r.xres = mode.Width; r.xres = mode.Width;
r.yres = mode.Height; r.yres = mode.Height;
a.resolutions.push_back(r); a.resolutions.push_back(r);
} }
} }
} }
} }
HRESULT Create(int adapter, HWND wnd, bool _fullscreen, int _resolution, int aa_mode) HRESULT Create(int adapter, HWND wnd, bool _fullscreen, int _resolution, int aa_mode)
{ {
hWnd = wnd; hWnd = wnd;
fullScreen = _fullscreen; fullScreen = _fullscreen;
nextFullScreen = _fullscreen; nextFullScreen = _fullscreen;
multisample = aa_mode; multisample = aa_mode;
resolution = _resolution; resolution = _resolution;
cur_adapter = adapter; cur_adapter = adapter;
D3DPRESENT_PARAMETERS d3dpp; D3DPRESENT_PARAMETERS d3dpp;
InitPP(adapter, resolution, aa_mode, &d3dpp); InitPP(adapter, resolution, aa_mode, &d3dpp);
if( FAILED( D3D->CreateDevice( if( FAILED( D3D->CreateDevice(
adapter, adapter,
D3DDEVTYPE_HAL, D3DDEVTYPE_HAL,
wnd, wnd,
D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED, D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED,
// |D3DCREATE_MULTITHREADED /* | D3DCREATE_PUREDEVICE*/, // |D3DCREATE_MULTITHREADED /* | D3DCREATE_PUREDEVICE*/,
//D3DCREATE_SOFTWARE_VERTEXPROCESSING , //D3DCREATE_SOFTWARE_VERTEXPROCESSING ,
&d3dpp, &dev ) ) ) &d3dpp, &dev ) ) )
{ {
MessageBox(wnd, MessageBox(wnd,
"Sorry, but it looks like your 3D accelerator is too old,\n" "Sorry, but it looks like your 3D accelerator is too old,\n"
"or doesn't support features that Dolphin requires.\n" "or doesn't support features that Dolphin requires.\n"
"Falling back to software vertex processing.\n", "Falling back to software vertex processing.\n",
"Dolphin Direct3D plugin", MB_OK | MB_ICONERROR); "Dolphin Direct3D plugin", MB_OK | MB_ICONERROR);
if( FAILED( D3D->CreateDevice( if( FAILED( D3D->CreateDevice(
adapter, adapter,
D3DDEVTYPE_HAL, D3DDEVTYPE_HAL,
wnd, wnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED, D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED,
// |D3DCREATE_MULTITHREADED /* | D3DCREATE_PUREDEVICE*/, // |D3DCREATE_MULTITHREADED /* | D3DCREATE_PUREDEVICE*/,
//D3DCREATE_SOFTWARE_VERTEXPROCESSING , //D3DCREATE_SOFTWARE_VERTEXPROCESSING ,
&d3dpp, &dev ) ) ) &d3dpp, &dev ) ) )
{ {
MessageBox(wnd, MessageBox(wnd,
"Software VP failed too. Upgrade your graphics card.", "Software VP failed too. Upgrade your graphics card.",
"Dolphin Direct3D plugin", MB_OK | MB_ICONERROR); "Dolphin Direct3D plugin", MB_OK | MB_ICONERROR);
return E_FAIL; return E_FAIL;
} }
} }
dev->GetDeviceCaps(&caps); dev->GetDeviceCaps(&caps);
dev->GetRenderTarget(0,&backBuffer); dev->GetRenderTarget(0,&backBuffer);
Ps.Major = (D3D::caps.PixelShaderVersion >> 8) & 0xFF; Ps.Major = (D3D::caps.PixelShaderVersion >> 8) & 0xFF;
Ps.Minor = (D3D::caps.PixelShaderVersion) & 0xFF; Ps.Minor = (D3D::caps.PixelShaderVersion) & 0xFF;
Vs.Major = (D3D::caps.VertexShaderVersion >>8) & 0xFF; Vs.Major = (D3D::caps.VertexShaderVersion >>8) & 0xFF;
Vs.Minor = (D3D::caps.VertexShaderVersion) & 0xFF; Vs.Minor = (D3D::caps.VertexShaderVersion) & 0xFF;
// Device state would normally be set here // Device state would normally be set here
return S_OK; return S_OK;
} }
ShaderVersion GetShaderVersion() ShaderVersion GetShaderVersion()
{ {
if (Ps.Major < 2) if (Ps.Major < 2)
{ {
return PSNONE; return PSNONE;
} }
//good enough estimate - we really only //good enough estimate - we really only
//care about zero shader vs ps20 //care about zero shader vs ps20
return (ShaderVersion)Ps.Major; return (ShaderVersion)Ps.Major;
} }
void Close() void Close()
{ {
dev->Release(); dev->Release();
dev = 0; dev = 0;
} }
void Shutdown() void Shutdown()
{ {
D3D->Release(); D3D->Release();
D3D = 0; D3D = 0;
} }
const D3DCAPS9 &GetCaps() const D3DCAPS9 &GetCaps()
{ {
return caps; return caps;
} }
LPDIRECT3DSURFACE9 GetBackBufferSurface() LPDIRECT3DSURFACE9 GetBackBufferSurface()
{ {
return backBuffer; return backBuffer;
} }
void ShowD3DError(HRESULT err) void ShowD3DError(HRESULT err)
{ {
switch (err) switch (err)
{ {
case D3DERR_DEVICELOST: case D3DERR_DEVICELOST:
MessageBox(0, "Device Lost", "D3D ERROR", 0); MessageBox(0, "Device Lost", "D3D ERROR", 0);
break; break;
case D3DERR_INVALIDCALL: case D3DERR_INVALIDCALL:
MessageBox(0, "Invalid Call", "D3D ERROR", 0); MessageBox(0, "Invalid Call", "D3D ERROR", 0);
break; break;
case D3DERR_DRIVERINTERNALERROR: case D3DERR_DRIVERINTERNALERROR:
MessageBox(0, "Driver Internal Error", "D3D ERROR", 0); MessageBox(0, "Driver Internal Error", "D3D ERROR", 0);
break; break;
case D3DERR_OUTOFVIDEOMEMORY: case D3DERR_OUTOFVIDEOMEMORY:
MessageBox(0, "Out of vid mem", "D3D ERROR", 0); MessageBox(0, "Out of vid mem", "D3D ERROR", 0);
break; break;
default: default:
// MessageBox(0,"Other error or success","ERROR",0); // MessageBox(0,"Other error or success","ERROR",0);
break; break;
} }
} }
void Reset() void Reset()
{ {
if (dev) if (dev)
{ {
D3DPRESENT_PARAMETERS d3dpp; D3DPRESENT_PARAMETERS d3dpp;
InitPP(cur_adapter, resolution, multisample, &d3dpp); InitPP(cur_adapter, resolution, multisample, &d3dpp);
HRESULT hr = dev->Reset(&d3dpp); HRESULT hr = dev->Reset(&d3dpp);
ShowD3DError(hr); ShowD3DError(hr);
} }
} }
bool IsFullscreen() bool IsFullscreen()
{ {
return fullScreen; return fullScreen;
} }
int GetDisplayWidth() int GetDisplayWidth()
{ {
return xres; return xres;
} }
int GetDisplayHeight() int GetDisplayHeight()
{ {
return yres; return yres;
} }
void SwitchFullscreen(bool fullscreen) void SwitchFullscreen(bool fullscreen)
{ {
nextFullScreen = fullscreen; nextFullScreen = fullscreen;
} }
bool BeginFrame(bool clear, u32 color, float z) bool BeginFrame(bool clear, u32 color, float z)
{ {
if (bFrameInProgress) if (bFrameInProgress)
{ {
return false; return false;
} }
bFrameInProgress = true; bFrameInProgress = true;
if (dev) if (dev)
{ {
if (clear) if (clear)
dev->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER|D3DCLEAR_STENCIL, (DWORD)color, z, 0 ); dev->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER|D3DCLEAR_STENCIL, (DWORD)color, z, 0 );
dev->BeginScene(); dev->BeginScene();
return true; return true;
} }
else else
return false; return false;
} }
void EndFrame() void EndFrame()
{ {
if (!bFrameInProgress) if (!bFrameInProgress)
return; return;
bFrameInProgress = false; bFrameInProgress = false;
if (dev) if (dev)
{ {
dev->EndScene(); dev->EndScene();
dev->Present( NULL, NULL, NULL, NULL ); dev->Present( NULL, NULL, NULL, NULL );
} }
if (fullScreen != nextFullScreen) if (fullScreen != nextFullScreen)
{ {
fullScreen = nextFullScreen; fullScreen = nextFullScreen;
Reset(); Reset();
} }
} }
} }

View File

@ -1,294 +1,294 @@
// 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 "D3DBase.h" #include "D3DBase.h"
#include "D3DTexture.h" #include "D3DTexture.h"
#include "D3DUtil.h" #include "D3DUtil.h"
#include "Config.h" #include "Config.h"
#include "Render.h" #include "Render.h"
using namespace D3D; using namespace D3D;
namespace Postprocess namespace Postprocess
{ {
LPDIRECT3DSURFACE9 displayColorBuffer; LPDIRECT3DSURFACE9 displayColorBuffer;
LPDIRECT3DSURFACE9 displayZStencilBuffer; LPDIRECT3DSURFACE9 displayZStencilBuffer;
LPDIRECT3DTEXTURE9 mainColorBufferTexture; LPDIRECT3DTEXTURE9 mainColorBufferTexture;
LPDIRECT3DSURFACE9 mainColorBuffer; LPDIRECT3DSURFACE9 mainColorBuffer;
LPDIRECT3DSURFACE9 mainZStencilBuffer; LPDIRECT3DSURFACE9 mainZStencilBuffer;
const int numScratch = 2; const int numScratch = 2;
LPDIRECT3DTEXTURE9 scratch[numScratch]; LPDIRECT3DTEXTURE9 scratch[numScratch];
LPDIRECT3DSURFACE9 scratchSurface[numScratch]; LPDIRECT3DSURFACE9 scratchSurface[numScratch];
const int mainWidth = 640, mainHeight=480; const int mainWidth = 640, mainHeight=480;
const int scratchWidth = 256, scratchHeight=256; const int scratchWidth = 256, scratchHeight=256;
int displayWidth, displayHeight; int displayWidth, displayHeight;
bool initialized; bool initialized;
int GetWidth() { int GetWidth() {
return initialized ? mainWidth : displayWidth; return initialized ? mainWidth : displayWidth;
} }
int GetHeight() { int GetHeight() {
return initialized ? mainHeight : displayHeight; return initialized ? mainHeight : displayHeight;
} }
void CreateStuff() void CreateStuff()
{ {
mainColorBufferTexture = D3D::CreateRenderTarget(mainWidth,mainHeight); mainColorBufferTexture = D3D::CreateRenderTarget(mainWidth,mainHeight);
mainColorBufferTexture->GetSurfaceLevel(0,&mainColorBuffer); mainColorBufferTexture->GetSurfaceLevel(0,&mainColorBuffer);
mainZStencilBuffer = D3D::CreateDepthStencilSurface(mainWidth,mainHeight); mainZStencilBuffer = D3D::CreateDepthStencilSurface(mainWidth,mainHeight);
for (int i=0; i<numScratch; i++) for (int i=0; i<numScratch; i++)
{ {
scratch[i]=D3D::CreateRenderTarget(scratchWidth,scratchHeight); scratch[i]=D3D::CreateRenderTarget(scratchWidth,scratchHeight);
scratch[i]->GetSurfaceLevel(0,&(scratchSurface[i])); scratch[i]->GetSurfaceLevel(0,&(scratchSurface[i]));
} }
initialized=true; initialized=true;
} }
void DestroyStuff() void DestroyStuff()
{ {
SAFE_RELEASE(mainColorBuffer); SAFE_RELEASE(mainColorBuffer);
SAFE_RELEASE(mainColorBufferTexture); SAFE_RELEASE(mainColorBufferTexture);
SAFE_RELEASE(mainZStencilBuffer); SAFE_RELEASE(mainZStencilBuffer);
for (int i=0; i<numScratch; i++) for (int i=0; i<numScratch; i++)
{ {
SAFE_RELEASE(scratch[i]); SAFE_RELEASE(scratch[i]);
SAFE_RELEASE(scratchSurface[i]); SAFE_RELEASE(scratchSurface[i]);
} }
initialized=false; initialized=false;
} }
void Initialize() void Initialize()
{ {
dev->GetRenderTarget(0,&displayColorBuffer); dev->GetRenderTarget(0,&displayColorBuffer);
dev->GetDepthStencilSurface(&displayZStencilBuffer); dev->GetDepthStencilSurface(&displayZStencilBuffer);
D3DSURFACE_DESC desc; D3DSURFACE_DESC desc;
displayColorBuffer->GetDesc(&desc); displayColorBuffer->GetDesc(&desc);
displayWidth = desc.Width; displayWidth = desc.Width;
displayHeight = desc.Height; displayHeight = desc.Height;
if (g_Config.iPostprocessEffect) if (g_Config.iPostprocessEffect)
CreateStuff(); CreateStuff();
} }
void Cleanup() void Cleanup()
{ {
DestroyStuff(); DestroyStuff();
SAFE_RELEASE(displayColorBuffer); SAFE_RELEASE(displayColorBuffer);
SAFE_RELEASE(displayZStencilBuffer); SAFE_RELEASE(displayZStencilBuffer);
} }
void BeginFrame() void BeginFrame()
{ {
if (g_Config.iPostprocessEffect) if (g_Config.iPostprocessEffect)
{ {
if (!initialized) if (!initialized)
CreateStuff(); CreateStuff();
dev->SetRenderTarget(0,mainColorBuffer); dev->SetRenderTarget(0,mainColorBuffer);
dev->SetDepthStencilSurface(mainZStencilBuffer); dev->SetDepthStencilSurface(mainZStencilBuffer);
// dev->SetRenderState(D3DRS_ZENABLE,TRUE); // dev->SetRenderState(D3DRS_ZENABLE,TRUE);
Renderer::SetRenderState( D3DRS_ZENABLE, TRUE ); Renderer::SetRenderState( D3DRS_ZENABLE, TRUE );
dev->Clear(0,0,D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,0,1,0); dev->Clear(0,0,D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,0,1,0);
} }
else else
{ {
if (initialized) if (initialized)
{ {
dev->SetRenderTarget(0,displayColorBuffer); dev->SetRenderTarget(0,displayColorBuffer);
dev->SetDepthStencilSurface(displayZStencilBuffer); dev->SetDepthStencilSurface(displayZStencilBuffer);
DestroyStuff(); DestroyStuff();
} }
// dev->SetRenderState(D3DRS_ZENABLE,TRUE); // dev->SetRenderState(D3DRS_ZENABLE,TRUE);
Renderer::SetRenderState( D3DRS_ZENABLE, TRUE ); Renderer::SetRenderState( D3DRS_ZENABLE, TRUE );
} }
} }
int filterKernel[8] = {0x40,0x80,0xc0,0xFF,0xFF,0xc0,0x80,0x40}; //good looking almost Gaussian int filterKernel[8] = {0x40,0x80,0xc0,0xFF,0xFF,0xc0,0x80,0x40}; //good looking almost Gaussian
//int filterKernel[8] = {0xFF,0xc0,0x80,0x40,0x40,0x80,0xc0,0xFF,}; //crazy filter //int filterKernel[8] = {0xFF,0xc0,0x80,0x40,0x40,0x80,0xc0,0xFF,}; //crazy filter
void NightGlow(bool intense, bool original) void NightGlow(bool intense, bool original)
{ {
// dev->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_SUBTRACT); // dev->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_SUBTRACT);
// dev->SetRenderState(D3DRS_ALPHABLENDENABLE,TRUE); // dev->SetRenderState(D3DRS_ALPHABLENDENABLE,TRUE);
// dev->SetRenderState(D3DRS_SRCBLEND,D3DBLEND_ONE); // dev->SetRenderState(D3DRS_SRCBLEND,D3DBLEND_ONE);
// dev->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_ONE); // dev->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_ONE);
Renderer::SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT ); Renderer::SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SUBTRACT );
Renderer::SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE ); Renderer::SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
Renderer::SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ONE ); Renderer::SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ONE );
Renderer::SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE ); Renderer::SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE );
dev->SetDepthStencilSurface(0); dev->SetDepthStencilSurface(0);
//dev->SetTexture(0,mainColorBufferTexture); //dev->SetTexture(0,mainColorBufferTexture);
Renderer::SetTexture( 0, mainColorBufferTexture ); Renderer::SetTexture( 0, mainColorBufferTexture );
dev->SetRenderTarget(0,scratchSurface[0]); dev->SetRenderTarget(0,scratchSurface[0]);
dev->SetSamplerState(0,D3DSAMP_ADDRESSU,D3DTADDRESS_CLAMP); dev->SetSamplerState(0,D3DSAMP_ADDRESSU,D3DTADDRESS_CLAMP);
dev->SetSamplerState(0,D3DSAMP_ADDRESSV,D3DTADDRESS_CLAMP); dev->SetSamplerState(0,D3DSAMP_ADDRESSV,D3DTADDRESS_CLAMP);
dev->SetSamplerState(0,D3DSAMP_MAGFILTER,D3DTEXF_LINEAR); dev->SetSamplerState(0,D3DSAMP_MAGFILTER,D3DTEXF_LINEAR);
dev->SetSamplerState(0,D3DSAMP_MINFILTER,D3DTEXF_LINEAR); dev->SetSamplerState(0,D3DSAMP_MINFILTER,D3DTEXF_LINEAR);
dev->SetSamplerState(0,D3DSAMP_MIPFILTER,D3DTEXF_LINEAR); dev->SetSamplerState(0,D3DSAMP_MIPFILTER,D3DTEXF_LINEAR);
dev->Clear(0,0,D3DCLEAR_TARGET,0,0,0); dev->Clear(0,0,D3DCLEAR_TARGET,0,0,0);
POINT pt; POINT pt;
GetCursorPos(&pt); GetCursorPos(&pt);
//dev->SetSamplerState(0,D3DSAMP_MIPMAPLODBIAS,1.0f); //dev->SetSamplerState(0,D3DSAMP_MIPMAPLODBIAS,1.0f);
#define QOFF(xoff,yoff,col) quad2d(-0.0f,-0.0f,scratchWidth-0.0f,scratchHeight-0.0f,col,0+xoff,0+yoff,1+xoff,1+yoff); #define QOFF(xoff,yoff,col) quad2d(-0.0f,-0.0f,scratchWidth-0.0f,scratchHeight-0.0f,col,0+xoff,0+yoff,1+xoff,1+yoff);
float f=0.008f; float f=0.008f;
QOFF(0,0,0xa0a0a0a0); QOFF(0,0,0xa0a0a0a0);
// dev->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_MODULATE); // dev->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_MODULATE);
//dev->SetTexture(0,scratch[0]); //dev->SetTexture(0,scratch[0]);
Renderer::SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE ); Renderer::SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
Renderer::SetTexture( 0, scratch[0] ); Renderer::SetTexture( 0, scratch[0] );
dev->SetRenderTarget(0,scratchSurface[1]); dev->SetRenderTarget(0,scratchSurface[1]);
dev->Clear(0,0,D3DCLEAR_TARGET,0,0,0); dev->Clear(0,0,D3DCLEAR_TARGET,0,0,0);
float yMul = 1.33333333333f; float yMul = 1.33333333333f;
for (int i=0; i<8; i++) for (int i=0; i<8; i++)
{ {
DWORD c=filterKernel[i]/2; DWORD c=filterKernel[i]/2;
c|=c<<8; c|=c<<8;
c|=c<<16; c|=c<<16;
QOFF(0,(i-3.5f) * f * yMul,c); QOFF(0,(i-3.5f) * f * yMul,c);
} }
//dev->SetTexture(0,scratch[1]); //dev->SetTexture(0,scratch[1]);
Renderer::SetTexture( 0, scratch[1] ); Renderer::SetTexture( 0, scratch[1] );
dev->SetRenderTarget(0,scratchSurface[0]); dev->SetRenderTarget(0,scratchSurface[0]);
dev->Clear(0,0,D3DCLEAR_TARGET,0,0,0); dev->Clear(0,0,D3DCLEAR_TARGET,0,0,0);
for (int i=0; i<8; i++) for (int i=0; i<8; i++)
{ {
DWORD c=filterKernel[i]/(intense?3:2); DWORD c=filterKernel[i]/(intense?3:2);
c|=c<<8; c|=c<<8;
c|=c<<16; c|=c<<16;
QOFF((i-3.5f) * f,0,c); QOFF((i-3.5f) * f,0,c);
} }
// dev->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_MODULATE); // dev->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_MODULATE);
Renderer::SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE ); Renderer::SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
if (intense) if (intense)
{ {
// dev->SetRenderState(D3DRS_SRCBLEND,D3DBLEND_ONE); // dev->SetRenderState(D3DRS_SRCBLEND,D3DBLEND_ONE);
// dev->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_SRCALPHA); // dev->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_SRCALPHA);
Renderer::SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ONE ); Renderer::SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ONE );
Renderer::SetRenderState( D3DRS_DESTBLEND, D3DBLEND_SRCALPHA ); Renderer::SetRenderState( D3DRS_DESTBLEND, D3DBLEND_SRCALPHA );
} }
else else
{ {
// dev->SetRenderState(D3DRS_SRCBLEND,D3DBLEND_INVDESTCOLOR); // dev->SetRenderState(D3DRS_SRCBLEND,D3DBLEND_INVDESTCOLOR);
// dev->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_ONE); // dev->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_ONE);
Renderer::SetRenderState( D3DRS_SRCBLEND, D3DBLEND_INVDESTCOLOR ); Renderer::SetRenderState( D3DRS_SRCBLEND, D3DBLEND_INVDESTCOLOR );
Renderer::SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE ); Renderer::SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE );
} }
// dev->SetTexture(0,scratch[0]); // dev->SetTexture(0,scratch[0]);
Renderer::SetTexture( 0, scratch[0] ); Renderer::SetTexture( 0, scratch[0] );
dev->SetRenderTarget(0,mainColorBuffer); dev->SetRenderTarget(0,mainColorBuffer);
quad2d(0,0,(float)mainWidth,(float)mainHeight,original?0xCFFFFFFF:0xFFFFFFFF,0,0,1,1); quad2d(0,0,(float)mainWidth,(float)mainHeight,original?0xCFFFFFFF:0xFFFFFFFF,0,0,1,1);
// dev->SetRenderState(D3DRS_ALPHABLENDENABLE,FALSE); // dev->SetRenderState(D3DRS_ALPHABLENDENABLE,FALSE);
Renderer::SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE ); Renderer::SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
dev->SetSamplerState(0,D3DSAMP_ADDRESSU,D3DTADDRESS_WRAP); dev->SetSamplerState(0,D3DSAMP_ADDRESSU,D3DTADDRESS_WRAP);
dev->SetSamplerState(0,D3DSAMP_ADDRESSV,D3DTADDRESS_WRAP); dev->SetSamplerState(0,D3DSAMP_ADDRESSV,D3DTADDRESS_WRAP);
//dev->SetSamplerState(0,D3DSAMP_MIPMAPLODBIAS,0); //dev->SetSamplerState(0,D3DSAMP_MIPMAPLODBIAS,0);
} }
const char **GetPostprocessingNames() const char **GetPostprocessingNames()
{ {
static const char *names[] = { static const char *names[] = {
"None", "None",
"Night Glow 1", "Night Glow 1",
"Night Glow 2", "Night Glow 2",
"Night Glow 3", "Night Glow 3",
0, 0,
}; };
return names; return names;
} }
void FinalizeFrame() void FinalizeFrame()
{ {
if (initialized) if (initialized)
{ {
// dev->SetRenderState(D3DRS_CULLMODE,D3DCULL_NONE); // dev->SetRenderState(D3DRS_CULLMODE,D3DCULL_NONE);
// dev->SetRenderState(D3DRS_ZENABLE,FALSE); // dev->SetRenderState(D3DRS_ZENABLE,FALSE);
// dev->SetRenderState(D3DRS_FOGENABLE,FALSE); // dev->SetRenderState(D3DRS_FOGENABLE,FALSE);
// dev->SetTextureStageState(0,D3DTSS_COLORARG1,D3DTA_TEXTURE); // dev->SetTextureStageState(0,D3DTSS_COLORARG1,D3DTA_TEXTURE);
// dev->SetTextureStageState(0,D3DTSS_COLORARG2,D3DTA_DIFFUSE); // dev->SetTextureStageState(0,D3DTSS_COLORARG2,D3DTA_DIFFUSE);
// dev->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_MODULATE); // dev->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_MODULATE);
// dev->SetTextureStageState(0,D3DTSS_ALPHAARG1,D3DTA_TEXTURE); // dev->SetTextureStageState(0,D3DTSS_ALPHAARG1,D3DTA_TEXTURE);
// dev->SetTextureStageState(0,D3DTSS_ALPHAARG2,D3DTA_DIFFUSE); // dev->SetTextureStageState(0,D3DTSS_ALPHAARG2,D3DTA_DIFFUSE);
// dev->SetTextureStageState(0,D3DTSS_ALPHAOP,D3DTOP_SELECTARG2); // dev->SetTextureStageState(0,D3DTSS_ALPHAOP,D3DTOP_SELECTARG2);
Renderer::SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE ); Renderer::SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
Renderer::SetRenderState( D3DRS_ZENABLE, FALSE ); Renderer::SetRenderState( D3DRS_ZENABLE, FALSE );
Renderer::SetRenderState( D3DRS_FOGENABLE, FALSE ); Renderer::SetRenderState( D3DRS_FOGENABLE, FALSE );
Renderer::SetTextureStageState(0,D3DTSS_COLORARG1,D3DTA_TEXTURE); Renderer::SetTextureStageState(0,D3DTSS_COLORARG1,D3DTA_TEXTURE);
Renderer::SetTextureStageState(0,D3DTSS_COLORARG2,D3DTA_DIFFUSE); Renderer::SetTextureStageState(0,D3DTSS_COLORARG2,D3DTA_DIFFUSE);
Renderer::SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_MODULATE); Renderer::SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_MODULATE);
Renderer::SetTextureStageState(0,D3DTSS_ALPHAARG1,D3DTA_TEXTURE); Renderer::SetTextureStageState(0,D3DTSS_ALPHAARG1,D3DTA_TEXTURE);
Renderer::SetTextureStageState(0,D3DTSS_ALPHAARG2,D3DTA_DIFFUSE); Renderer::SetTextureStageState(0,D3DTSS_ALPHAARG2,D3DTA_DIFFUSE);
Renderer::SetTextureStageState(0,D3DTSS_ALPHAOP,D3DTOP_SELECTARG2); Renderer::SetTextureStageState(0,D3DTSS_ALPHAOP,D3DTOP_SELECTARG2);
switch(g_Config.iPostprocessEffect) { switch(g_Config.iPostprocessEffect) {
case 1: case 1:
NightGlow(true,true); NightGlow(true,true);
case 2: case 2:
NightGlow(false,true); NightGlow(false,true);
break; break;
case 3: case 3:
NightGlow(false,false); NightGlow(false,false);
break; break;
} }
dev->SetRenderTarget(0,displayColorBuffer); dev->SetRenderTarget(0,displayColorBuffer);
dev->SetDepthStencilSurface(displayZStencilBuffer); dev->SetDepthStencilSurface(displayZStencilBuffer);
// dev->SetTexture(0,mainColorBufferTexture); // dev->SetTexture(0,mainColorBufferTexture);
Renderer::SetTexture( 0, mainColorBufferTexture ); Renderer::SetTexture( 0, mainColorBufferTexture );
quad2d(0, 0, (float)displayWidth, (float)displayHeight, 0xFFFFFFFF); quad2d(0, 0, (float)displayWidth, (float)displayHeight, 0xFFFFFFFF);
} }
} }
} }

View File

@ -1,108 +1,108 @@
// 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 <d3dx9.h> #include <d3dx9.h>
#include <string> #include <string>
#include "Config.h" #include "Config.h"
#include "D3DShader.h" #include "D3DShader.h"
namespace D3D namespace D3D
{ {
LPDIRECT3DVERTEXSHADER9 CompileVShader(const char *code, int len) LPDIRECT3DVERTEXSHADER9 CompileVShader(const char *code, int len)
{ {
//try to compile //try to compile
LPD3DXBUFFER shaderBuffer = 0, errorBuffer = 0; LPD3DXBUFFER shaderBuffer = 0, errorBuffer = 0;
LPDIRECT3DVERTEXSHADER9 vShader = 0; LPDIRECT3DVERTEXSHADER9 vShader = 0;
HRESULT hr = D3DXCompileShader(code,len,0,0,"main","vs_1_1",0,&shaderBuffer,&errorBuffer,0); HRESULT hr = D3DXCompileShader(code,len,0,0,"main","vs_1_1",0,&shaderBuffer,&errorBuffer,0);
if (FAILED(hr)) if (FAILED(hr))
{ {
//let's try 2.0 //let's try 2.0
hr = D3DXCompileShader(code,len,0,0,"main","vs_2_0",0,&shaderBuffer,&errorBuffer,0); hr = D3DXCompileShader(code,len,0,0,"main","vs_2_0",0,&shaderBuffer,&errorBuffer,0);
} }
if (FAILED(hr)) if (FAILED(hr))
{ {
//compilation error //compilation error
std::string hello = (char*)errorBuffer->GetBufferPointer(); std::string hello = (char*)errorBuffer->GetBufferPointer();
hello += "\n\n"; hello += "\n\n";
hello += code; hello += code;
if (g_Config.bShowShaderErrors) if (g_Config.bShowShaderErrors)
MessageBox(0, hello.c_str(), "Error compiling vertex shader", MB_ICONERROR); MessageBox(0, hello.c_str(), "Error compiling vertex shader", MB_ICONERROR);
vShader = 0; vShader = 0;
} }
else if (SUCCEEDED(hr)) else if (SUCCEEDED(hr))
{ {
//create it //create it
HRESULT hr = E_FAIL; HRESULT hr = E_FAIL;
if (shaderBuffer) if (shaderBuffer)
hr = D3D::dev->CreateVertexShader((DWORD *)shaderBuffer->GetBufferPointer(), &vShader); hr = D3D::dev->CreateVertexShader((DWORD *)shaderBuffer->GetBufferPointer(), &vShader);
if (FAILED(hr) || vShader == 0) if (FAILED(hr) || vShader == 0)
{ {
if (g_Config.bShowShaderErrors) if (g_Config.bShowShaderErrors)
MessageBox(0,code,(char*)errorBuffer->GetBufferPointer(),MB_ICONERROR); MessageBox(0,code,(char*)errorBuffer->GetBufferPointer(),MB_ICONERROR);
} }
} }
//cleanup //cleanup
if (shaderBuffer) if (shaderBuffer)
shaderBuffer->Release(); shaderBuffer->Release();
if (errorBuffer) if (errorBuffer)
errorBuffer->Release(); errorBuffer->Release();
return vShader; return vShader;
} }
LPDIRECT3DPIXELSHADER9 CompilePShader(const char *code, int len) LPDIRECT3DPIXELSHADER9 CompilePShader(const char *code, int len)
{ {
LPD3DXBUFFER shaderBuffer = 0, errorBuffer = 0; LPD3DXBUFFER shaderBuffer = 0, errorBuffer = 0;
LPDIRECT3DPIXELSHADER9 pShader = 0; LPDIRECT3DPIXELSHADER9 pShader = 0;
static char *versions[6] = {"ERROR","ps_1_1","ps_1_4","ps_2_0","ps_3_0","ps_4_0"}; static char *versions[6] = {"ERROR","ps_1_1","ps_1_4","ps_2_0","ps_3_0","ps_4_0"};
HRESULT hr = D3DXCompileShader(code,len,0,0, HRESULT hr = D3DXCompileShader(code,len,0,0,
"main","ps_2_0", // Pixel Shader 2.0 is enough for all we do "main","ps_2_0", // Pixel Shader 2.0 is enough for all we do
0,&shaderBuffer,&errorBuffer,0); 0,&shaderBuffer,&errorBuffer,0);
if (FAILED(hr)) if (FAILED(hr))
{ {
std::string hello = (char*)errorBuffer->GetBufferPointer(); std::string hello = (char*)errorBuffer->GetBufferPointer();
hello += "\n\n"; hello += "\n\n";
hello += code; hello += code;
if (g_Config.bShowShaderErrors) if (g_Config.bShowShaderErrors)
MessageBox(0, hello.c_str(), "Error compiling pixel shader", MB_ICONERROR); MessageBox(0, hello.c_str(), "Error compiling pixel shader", MB_ICONERROR);
pShader = 0; pShader = 0;
} }
else else
{ {
//create it //create it
HRESULT hr = D3D::dev->CreatePixelShader((DWORD *)shaderBuffer->GetBufferPointer(), &pShader); HRESULT hr = D3D::dev->CreatePixelShader((DWORD *)shaderBuffer->GetBufferPointer(), &pShader);
if (FAILED(hr) || pShader == 0) if (FAILED(hr) || pShader == 0)
{ {
if (g_Config.bShowShaderErrors) if (g_Config.bShowShaderErrors)
MessageBox(0,"damn","error creating pixelshader",MB_ICONERROR); MessageBox(0,"damn","error creating pixelshader",MB_ICONERROR);
} }
} }
//cleanup //cleanup
if (shaderBuffer) if (shaderBuffer)
shaderBuffer->Release(); shaderBuffer->Release();
if (errorBuffer) if (errorBuffer)
errorBuffer->Release(); errorBuffer->Release();
return pShader; return pShader;
} }
} }

View File

@ -1,115 +1,115 @@
// 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 "D3DTexture.h" #include "D3DTexture.h"
namespace D3D namespace D3D
{ {
LPDIRECT3DTEXTURE9 CreateTexture2D(const u8* buffer, const int width, const int height,const int pitch, D3DFORMAT fmt) LPDIRECT3DTEXTURE9 CreateTexture2D(const u8* buffer, const int width, const int height,const int pitch, D3DFORMAT fmt)
{ {
u32* pBuffer = (u32*)buffer; u32* pBuffer = (u32*)buffer;
LPDIRECT3DTEXTURE9 pTexture; LPDIRECT3DTEXTURE9 pTexture;
// crazy bitmagic // crazy bitmagic
bool isPow2 = !((width&(width-1)) || (height&(height-1))); bool isPow2 = !((width&(width-1)) || (height&(height-1)));
HRESULT hr; HRESULT hr;
// TODO(ector): allow mipmaps for non-pow textures on newer cards? // TODO(ector): allow mipmaps for non-pow textures on newer cards?
if (!isPow2) if (!isPow2)
hr = dev->CreateTexture(width, height, 1, 0, fmt, D3DPOOL_MANAGED, &pTexture, NULL); hr = dev->CreateTexture(width, height, 1, 0, fmt, D3DPOOL_MANAGED, &pTexture, NULL);
else else
hr = dev->CreateTexture(width, height, 0, D3DUSAGE_AUTOGENMIPMAP, fmt, D3DPOOL_MANAGED, &pTexture, NULL); hr = dev->CreateTexture(width, height, 0, D3DUSAGE_AUTOGENMIPMAP, fmt, D3DPOOL_MANAGED, &pTexture, NULL);
if(FAILED(hr)) if(FAILED(hr))
return 0; return 0;
int level = 0; int level = 0;
D3DLOCKED_RECT Lock; D3DLOCKED_RECT Lock;
pTexture->LockRect(level, &Lock, NULL, 0 ); pTexture->LockRect(level, &Lock, NULL, 0 );
u32* pIn = pBuffer; u32* pIn = pBuffer;
switch(fmt) switch(fmt)
{ {
case D3DFMT_A8R8G8B8: case D3DFMT_A8R8G8B8:
{ {
for (int y = 0; y < height; y++) for (int y = 0; y < height; y++)
{ {
u32* pBits = (u32*)((u8*)Lock.pBits + (y * Lock.Pitch)); u32* pBits = (u32*)((u8*)Lock.pBits + (y * Lock.Pitch));
memcpy(pBits, pIn, width * 4); memcpy(pBits, pIn, width * 4);
pIn += pitch; pIn += pitch;
} }
} }
break; break;
case D3DFMT_DXT1: case D3DFMT_DXT1:
memcpy(Lock.pBits,buffer,(width/4)*(height/4)*8); memcpy(Lock.pBits,buffer,(width/4)*(height/4)*8);
break; break;
} }
pTexture->UnlockRect(level); pTexture->UnlockRect(level);
return pTexture; return pTexture;
} }
void ReplaceTexture2D(LPDIRECT3DTEXTURE9 pTexture, const u8* buffer, const int width, const int height,const int pitch, D3DFORMAT fmt) void ReplaceTexture2D(LPDIRECT3DTEXTURE9 pTexture, const u8* buffer, const int width, const int height,const int pitch, D3DFORMAT fmt)
{ {
u32* pBuffer = (u32*)buffer; u32* pBuffer = (u32*)buffer;
int level = 0; int level = 0;
D3DLOCKED_RECT Lock; D3DLOCKED_RECT Lock;
pTexture->LockRect(level, &Lock, NULL, 0 ); pTexture->LockRect(level, &Lock, NULL, 0 );
u32* pIn = pBuffer; u32* pIn = pBuffer;
switch(fmt) switch(fmt)
{ {
case D3DFMT_A8R8G8B8: case D3DFMT_A8R8G8B8:
{ {
for (int y = 0; y < height; y++) for (int y = 0; y < height; y++)
{ {
u32* pBits = (u32*)((u8*)Lock.pBits + (y * Lock.Pitch)); u32* pBits = (u32*)((u8*)Lock.pBits + (y * Lock.Pitch));
memcpy(pBits,pIn, width*4); memcpy(pBits,pIn, width*4);
pIn += pitch; pIn += pitch;
} }
} }
break; break;
case D3DFMT_DXT1: case D3DFMT_DXT1:
memcpy(Lock.pBits,buffer,(width/4)*(height/4)*8); memcpy(Lock.pBits,buffer,(width/4)*(height/4)*8);
break; break;
} }
pTexture->UnlockRect(level); pTexture->UnlockRect(level);
} }
LPDIRECT3DTEXTURE9 CreateRenderTarget(const int width, const int height) LPDIRECT3DTEXTURE9 CreateRenderTarget(const int width, const int height)
{ {
LPDIRECT3DTEXTURE9 tex; LPDIRECT3DTEXTURE9 tex;
HRESULT hr = dev->CreateTexture(width,height,0,D3DUSAGE_RENDERTARGET | D3DUSAGE_AUTOGENMIPMAP,D3DFMT_A8R8G8B8,D3DPOOL_DEFAULT,&tex,NULL); HRESULT hr = dev->CreateTexture(width,height,0,D3DUSAGE_RENDERTARGET | D3DUSAGE_AUTOGENMIPMAP,D3DFMT_A8R8G8B8,D3DPOOL_DEFAULT,&tex,NULL);
if (FAILED(hr)) if (FAILED(hr))
return 0; return 0;
else else
return tex; return tex;
} }
LPDIRECT3DSURFACE9 CreateDepthStencilSurface(const int width, const int height) LPDIRECT3DSURFACE9 CreateDepthStencilSurface(const int width, const int height)
{ {
LPDIRECT3DSURFACE9 surf; LPDIRECT3DSURFACE9 surf;
HRESULT hr = dev->CreateDepthStencilSurface(width,height,D3DFMT_D24S8,D3DMULTISAMPLE_NONE,0,0,&surf,0); HRESULT hr = dev->CreateDepthStencilSurface(width,height,D3DFMT_D24S8,D3DMULTISAMPLE_NONE,0,0,&surf,0);
if (FAILED(hr)) if (FAILED(hr))
return 0; return 0;
else else
return surf; return surf;
} }
} }

View File

@ -1,397 +1,397 @@
// 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 "D3DBase.h" #include "D3DBase.h"
#include "D3DUtil.h" #include "D3DUtil.h"
#include "Render.h" #include "Render.h"
namespace D3D namespace D3D
{ {
CD3DFont font; CD3DFont font;
#define MAX_NUM_VERTICES 50*6 #define MAX_NUM_VERTICES 50*6
struct FONT2DVERTEX { struct FONT2DVERTEX {
float x,y,z; float x,y,z;
float rhw; float rhw;
u32 color; u32 color;
float tu, tv; float tu, tv;
}; };
#define D3DFVF_FONT2DVERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE|D3DFVF_TEX1) #define D3DFVF_FONT2DVERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE|D3DFVF_TEX1)
#define D3DFVF_FONT3DVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_NORMAL|D3DFVF_TEX1) #define D3DFVF_FONT3DVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_NORMAL|D3DFVF_TEX1)
inline FONT2DVERTEX InitFont2DVertex( float x, float y, u32 color, float tu, float tv ) inline FONT2DVERTEX InitFont2DVertex( float x, float y, u32 color, float tu, float tv )
{ {
FONT2DVERTEX v; v.x=x; v.y=y; v.z=0; v.rhw=1.0f; v.color = color; v.tu = tu; v.tv = tv; FONT2DVERTEX v; v.x=x; v.y=y; v.z=0; v.rhw=1.0f; v.color = color; v.tu = tu; v.tv = tv;
return v; return v;
} }
CD3DFont::CD3DFont() CD3DFont::CD3DFont()
{ {
m_pTexture = NULL; m_pTexture = NULL;
m_pVB = NULL; m_pVB = NULL;
} }
enum {m_dwTexWidth = 512, m_dwTexHeight = 512}; enum {m_dwTexWidth = 512, m_dwTexHeight = 512};
int CD3DFont::Init() int CD3DFont::Init()
{ {
int hr; int hr;
m_fTextScale = 1.0f; // Draw fonts into texture without scaling m_fTextScale = 1.0f; // Draw fonts into texture without scaling
// Create a new texture for the font // Create a new texture for the font
hr = dev->CreateTexture( m_dwTexWidth, m_dwTexHeight, 1, 0, D3DFMT_A4R4G4B4, D3DPOOL_MANAGED, &m_pTexture, NULL ); hr = dev->CreateTexture( m_dwTexWidth, m_dwTexHeight, 1, 0, D3DFMT_A4R4G4B4, D3DPOOL_MANAGED, &m_pTexture, NULL );
if( FAILED(hr) ) if( FAILED(hr) )
return hr; return hr;
// Prepare to create a bitmap // Prepare to create a bitmap
int *pBitmapBits; int *pBitmapBits;
BITMAPINFO bmi; BITMAPINFO bmi;
ZeroMemory( &bmi.bmiHeader, sizeof(BITMAPINFOHEADER) ); ZeroMemory( &bmi.bmiHeader, sizeof(BITMAPINFOHEADER) );
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biWidth = (int)m_dwTexWidth; bmi.bmiHeader.biWidth = (int)m_dwTexWidth;
bmi.bmiHeader.biHeight = -(int)m_dwTexHeight; bmi.bmiHeader.biHeight = -(int)m_dwTexHeight;
bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biCompression = BI_RGB; bmi.bmiHeader.biCompression = BI_RGB;
bmi.bmiHeader.biBitCount = 32; bmi.bmiHeader.biBitCount = 32;
// Create a DC and a bitmap for the font // Create a DC and a bitmap for the font
HDC hDC = CreateCompatibleDC( NULL ); HDC hDC = CreateCompatibleDC( NULL );
HBITMAP hbmBitmap = CreateDIBSection( hDC, &bmi, DIB_RGB_COLORS, HBITMAP hbmBitmap = CreateDIBSection( hDC, &bmi, DIB_RGB_COLORS,
(VOID**)&pBitmapBits, NULL, 0 ); (VOID**)&pBitmapBits, NULL, 0 );
SetMapMode( hDC, MM_TEXT ); SetMapMode( hDC, MM_TEXT );
// Create a font. By specifying ANTIALIASED_QUALITY, we might get an // Create a font. By specifying ANTIALIASED_QUALITY, we might get an
// antialiased font, but this is not guaranteed. // antialiased font, but this is not guaranteed.
// We definitely don't want to get it cleartype'd, anyway. // We definitely don't want to get it cleartype'd, anyway.
int m_dwFontHeight = 36; int m_dwFontHeight = 36;
int nHeight = -MulDiv( m_dwFontHeight, int(GetDeviceCaps(hDC, LOGPIXELSY) * m_fTextScale), 72 ); int nHeight = -MulDiv( m_dwFontHeight, int(GetDeviceCaps(hDC, LOGPIXELSY) * m_fTextScale), 72 );
int dwBold = FW_NORMAL; ///FW_BOLD int dwBold = FW_NORMAL; ///FW_BOLD
HFONT hFont = CreateFont( nHeight, 0, 0, 0, dwBold, 0, HFONT hFont = CreateFont( nHeight, 0, 0, 0, dwBold, 0,
FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY, CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY,
VARIABLE_PITCH, "Tahoma"); VARIABLE_PITCH, "Tahoma");
if (NULL == hFont) if (NULL == hFont)
return E_FAIL; return E_FAIL;
HGDIOBJ hOldbmBitmap = SelectObject( hDC, hbmBitmap ); HGDIOBJ hOldbmBitmap = SelectObject( hDC, hbmBitmap );
HGDIOBJ hOldFont = SelectObject( hDC, hFont ); HGDIOBJ hOldFont = SelectObject( hDC, hFont );
// Set text properties // Set text properties
SetTextColor( hDC, 0xFFFFFF ); SetTextColor( hDC, 0xFFFFFF );
SetBkColor ( hDC, 0 ); SetBkColor ( hDC, 0 );
SetTextAlign( hDC, TA_TOP ); SetTextAlign( hDC, TA_TOP );
// Loop through all printable character and output them to the bitmap.. // Loop through all printable character and output them to the bitmap..
// Meanwhile, keep track of the corresponding tex coords for each character. // Meanwhile, keep track of the corresponding tex coords for each character.
int x = 0, y = 0; int x = 0, y = 0;
char str[2] = "\0"; char str[2] = "\0";
SIZE size; SIZE size;
for( char c=0; c<127-32; c++ ) for( char c=0; c<127-32; c++ )
{ {
str[0] = c+32; str[0] = c+32;
GetTextExtentPoint32( hDC, str, 1, &size ); GetTextExtentPoint32( hDC, str, 1, &size );
if( (int)(x+size.cx+1) > m_dwTexWidth ) if( (int)(x+size.cx+1) > m_dwTexWidth )
{ {
x = 0; x = 0;
y += size.cy+1; y += size.cy+1;
} }
ExtTextOut( hDC, x+1, y+0, ETO_OPAQUE | ETO_CLIPPED, NULL, str, 1, NULL ); ExtTextOut( hDC, x+1, y+0, ETO_OPAQUE | ETO_CLIPPED, NULL, str, 1, NULL );
m_fTexCoords[c][0] = ((float)(x+0))/m_dwTexWidth; m_fTexCoords[c][0] = ((float)(x+0))/m_dwTexWidth;
m_fTexCoords[c][1] = ((float)(y+0))/m_dwTexHeight; m_fTexCoords[c][1] = ((float)(y+0))/m_dwTexHeight;
m_fTexCoords[c][2] = ((float)(x+0+size.cx))/m_dwTexWidth; m_fTexCoords[c][2] = ((float)(x+0+size.cx))/m_dwTexWidth;
m_fTexCoords[c][3] = ((float)(y+0+size.cy))/m_dwTexHeight; m_fTexCoords[c][3] = ((float)(y+0+size.cy))/m_dwTexHeight;
x += size.cx+3; //3 to avoid annoying ij conflict (part of the j ends up with the i) x += size.cx+3; //3 to avoid annoying ij conflict (part of the j ends up with the i)
} }
// Lock the surface and write the alpha values for the set pixels // Lock the surface and write the alpha values for the set pixels
D3DLOCKED_RECT d3dlr; D3DLOCKED_RECT d3dlr;
m_pTexture->LockRect( 0, &d3dlr, 0, 0 ); m_pTexture->LockRect( 0, &d3dlr, 0, 0 );
unsigned short* pDst16 = (unsigned short*)d3dlr.pBits; unsigned short* pDst16 = (unsigned short*)d3dlr.pBits;
int bAlpha; // 4-bit measure of pixel intensity int bAlpha; // 4-bit measure of pixel intensity
for( y=0; y < m_dwTexHeight; y++ ) for( y=0; y < m_dwTexHeight; y++ )
{ {
for( x=0; x < m_dwTexWidth; x++ ) for( x=0; x < m_dwTexWidth; x++ )
{ {
bAlpha = ((pBitmapBits[m_dwTexWidth*y + x] & 0xff) >> 4); bAlpha = ((pBitmapBits[m_dwTexWidth*y + x] & 0xff) >> 4);
*pDst16++ = (bAlpha << 12) | 0x0fff; *pDst16++ = (bAlpha << 12) | 0x0fff;
} }
} }
// Done updating texture, so clean up used objects // Done updating texture, so clean up used objects
m_pTexture->UnlockRect(0); m_pTexture->UnlockRect(0);
SelectObject( hDC, hOldbmBitmap ); SelectObject( hDC, hOldbmBitmap );
DeleteObject( hbmBitmap ); DeleteObject( hbmBitmap );
SelectObject( hDC, hOldFont ); SelectObject( hDC, hOldFont );
DeleteObject( hFont ); DeleteObject( hFont );
// Create vertex buffer for the letters // Create vertex buffer for the letters
if( FAILED( hr = dev->CreateVertexBuffer( MAX_NUM_VERTICES*sizeof(FONT2DVERTEX), if( FAILED( hr = dev->CreateVertexBuffer( MAX_NUM_VERTICES*sizeof(FONT2DVERTEX),
D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC, 0, D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC, 0,
D3DPOOL_DEFAULT, &m_pVB,NULL ) ) ) D3DPOOL_DEFAULT, &m_pVB,NULL ) ) )
{ {
return hr; return hr;
} }
return S_OK; return S_OK;
} }
int CD3DFont::Shutdown() int CD3DFont::Shutdown()
{ {
SAFE_RELEASE( m_pVB ); SAFE_RELEASE( m_pVB );
SAFE_RELEASE( m_pTexture ); SAFE_RELEASE( m_pTexture );
return S_OK; return S_OK;
} }
const int RS[6][2] = const int RS[6][2] =
{ {
{ D3DRS_ALPHABLENDENABLE, TRUE }, { D3DRS_ALPHABLENDENABLE, TRUE },
{ D3DRS_SRCBLEND, D3DBLEND_SRCALPHA }, { D3DRS_SRCBLEND, D3DBLEND_SRCALPHA },
{ D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA }, { D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA },
{ D3DRS_CULLMODE, D3DCULL_NONE }, { D3DRS_CULLMODE, D3DCULL_NONE },
{ D3DRS_ZENABLE, FALSE }, { D3DRS_ZENABLE, FALSE },
{ D3DRS_FOGENABLE, FALSE }, { D3DRS_FOGENABLE, FALSE },
}; };
const int TS[6][2] = const int TS[6][2] =
{ {
{D3DTSS_COLOROP, D3DTOP_MODULATE}, {D3DTSS_COLOROP, D3DTOP_MODULATE},
{D3DTSS_COLORARG1, D3DTA_TEXTURE}, {D3DTSS_COLORARG1, D3DTA_TEXTURE},
{D3DTSS_COLORARG2, D3DTA_DIFFUSE }, {D3DTSS_COLORARG2, D3DTA_DIFFUSE },
{D3DTSS_ALPHAOP, D3DTOP_MODULATE }, {D3DTSS_ALPHAOP, D3DTOP_MODULATE },
{D3DTSS_ALPHAARG1, D3DTA_TEXTURE }, {D3DTSS_ALPHAARG1, D3DTA_TEXTURE },
{D3DTSS_ALPHAARG2, D3DTA_DIFFUSE }, {D3DTSS_ALPHAARG2, D3DTA_DIFFUSE },
}; };
static DWORD RS_old[6]; static DWORD RS_old[6];
static DWORD TS_old[6]; static DWORD TS_old[6];
static LPDIRECT3DBASETEXTURE9 texture_old; static LPDIRECT3DBASETEXTURE9 texture_old;
static DWORD FVF_old; static DWORD FVF_old;
static LPDIRECT3DVERTEXDECLARATION9 decl_old; static LPDIRECT3DVERTEXDECLARATION9 decl_old;
static LPDIRECT3DPIXELSHADER9 ps_old; static LPDIRECT3DPIXELSHADER9 ps_old;
static LPDIRECT3DVERTEXSHADER9 vs_old; static LPDIRECT3DVERTEXSHADER9 vs_old;
void SaveRenderStates() void SaveRenderStates()
{ {
for (int i = 0; i < 6; i++) { for (int i = 0; i < 6; i++) {
dev->GetRenderState((_D3DRENDERSTATETYPE)RS[i][0], &(RS_old[i])); dev->GetRenderState((_D3DRENDERSTATETYPE)RS[i][0], &(RS_old[i]));
dev->GetTextureStageState(0, (_D3DTEXTURESTAGESTATETYPE)int(TS[i][0]), &(TS_old[i])); dev->GetTextureStageState(0, (_D3DTEXTURESTAGESTATETYPE)int(TS[i][0]), &(TS_old[i]));
} }
dev->GetTexture(0, &texture_old); dev->GetTexture(0, &texture_old);
dev->GetPixelShader(&ps_old); dev->GetPixelShader(&ps_old);
dev->GetVertexShader(&vs_old); dev->GetVertexShader(&vs_old);
dev->GetVertexDeclaration(&decl_old); dev->GetVertexDeclaration(&decl_old);
dev->GetFVF(&FVF_old); dev->GetFVF(&FVF_old);
} }
void CD3DFont::SetRenderStates() void CD3DFont::SetRenderStates()
{ {
// dev->SetTexture(0, m_pTexture); // dev->SetTexture(0, m_pTexture);
Renderer::SetTexture( 0, m_pTexture ); Renderer::SetTexture( 0, m_pTexture );
dev->SetPixelShader(0); dev->SetPixelShader(0);
dev->SetVertexShader(0); dev->SetVertexShader(0);
dev->SetVertexDeclaration(0); dev->SetVertexDeclaration(0);
// dev->SetFVF(D3DFVF_FONT2DVERTEX); // dev->SetFVF(D3DFVF_FONT2DVERTEX);
Renderer::SetFVF(D3DFVF_FONT2DVERTEX); Renderer::SetFVF(D3DFVF_FONT2DVERTEX);
for (int i = 0; i < 6; i++) { for (int i = 0; i < 6; i++) {
// dev->SetRenderState((_D3DRENDERSTATETYPE)RS[i][0],RS[i][1]); // dev->SetRenderState((_D3DRENDERSTATETYPE)RS[i][0],RS[i][1]);
// dev->SetTextureStageState(0, (_D3DTEXTURESTAGESTATETYPE)int(TS[i][0]), TS[i][1]); // dev->SetTextureStageState(0, (_D3DTEXTURESTAGESTATETYPE)int(TS[i][0]), TS[i][1]);
Renderer::SetRenderState( (_D3DRENDERSTATETYPE)RS[i][0], RS[i][1] ); Renderer::SetRenderState( (_D3DRENDERSTATETYPE)RS[i][0], RS[i][1] );
Renderer::SetTextureStageState( 0, (_D3DTEXTURESTAGESTATETYPE)int(TS[i][0]), TS[i][1] ); Renderer::SetTextureStageState( 0, (_D3DTEXTURESTAGESTATETYPE)int(TS[i][0]), TS[i][1] );
} }
} }
void RestoreRenderStates() void RestoreRenderStates()
{ {
// dev->SetTexture(0, texture_old); // dev->SetTexture(0, texture_old);
Renderer::SetTexture( 0, texture_old ); Renderer::SetTexture( 0, texture_old );
dev->SetPixelShader(ps_old); dev->SetPixelShader(ps_old);
dev->SetVertexShader(vs_old); dev->SetVertexShader(vs_old);
dev->SetVertexDeclaration(decl_old); dev->SetVertexDeclaration(decl_old);
// dev->SetFVF(FVF_old); // dev->SetFVF(FVF_old);
Renderer::SetFVF(FVF_old); Renderer::SetFVF(FVF_old);
for (int i = 0; i < 6; i++) for (int i = 0; i < 6; i++)
{ {
// dev->SetRenderState((_D3DRENDERSTATETYPE)RS[i][0], RS_old[i]); // dev->SetRenderState((_D3DRENDERSTATETYPE)RS[i][0], RS_old[i]);
// dev->SetTextureStageState(0, (_D3DTEXTURESTAGESTATETYPE)int(TS[i][0]), TS_old[i]); // dev->SetTextureStageState(0, (_D3DTEXTURESTAGESTATETYPE)int(TS[i][0]), TS_old[i]);
Renderer::SetRenderState( (_D3DRENDERSTATETYPE)RS[i][0], RS_old[i] ); Renderer::SetRenderState( (_D3DRENDERSTATETYPE)RS[i][0], RS_old[i] );
Renderer::SetTextureStageState( 0, (_D3DTEXTURESTAGESTATETYPE)int(TS[i][0]), TS_old[i] ); Renderer::SetTextureStageState( 0, (_D3DTEXTURESTAGESTATETYPE)int(TS[i][0]), TS_old[i] );
} }
} }
int CD3DFont::DrawTextScaled( float x, float y, float fXScale, float fYScale, float spacing, u32 dwColor, const char* strText, bool center ) int CD3DFont::DrawTextScaled( float x, float y, float fXScale, float fYScale, float spacing, u32 dwColor, const char* strText, bool center )
{ {
SaveRenderStates(); SaveRenderStates();
SetRenderStates(); SetRenderStates();
dev->SetStreamSource( 0, m_pVB, 0, sizeof(FONT2DVERTEX) ); dev->SetStreamSource( 0, m_pVB, 0, sizeof(FONT2DVERTEX) );
float vpWidth = 1; float vpWidth = 1;
float vpHeight = 1; float vpHeight = 1;
float sx = x*vpWidth-0.5f; float sx = x*vpWidth-0.5f;
float sy = y*vpHeight-0.5f; float sy = y*vpHeight-0.5f;
float fStartX = sx; float fStartX = sx;
float invLineHeight = 1.0f / (( m_fTexCoords[0][3] - m_fTexCoords[0][1] ) * m_dwTexHeight); float invLineHeight = 1.0f / (( m_fTexCoords[0][3] - m_fTexCoords[0][1] ) * m_dwTexHeight);
// Fill vertex buffer // Fill vertex buffer
FONT2DVERTEX* pVertices; FONT2DVERTEX* pVertices;
int dwNumTriangles = 0L; int dwNumTriangles = 0L;
m_pVB->Lock( 0, 0, (void**)&pVertices, D3DLOCK_DISCARD ); m_pVB->Lock( 0, 0, (void**)&pVertices, D3DLOCK_DISCARD );
const char *oldstrText=strText; const char *oldstrText=strText;
//First, let's measure the text //First, let's measure the text
float tw=0; float tw=0;
float mx=0; float mx=0;
float maxx=0; float maxx=0;
while( *strText ) while( *strText )
{ {
char c = *strText++; char c = *strText++;
if( c == ('\n') ) if( c == ('\n') )
mx=0; mx=0;
if( c < (' ') ) if( c < (' ') )
continue; continue;
float tx1 = m_fTexCoords[c-32][0]; float tx1 = m_fTexCoords[c-32][0];
float tx2 = m_fTexCoords[c-32][2]; float tx2 = m_fTexCoords[c-32][2];
float w = (tx2-tx1)*m_dwTexWidth; float w = (tx2-tx1)*m_dwTexWidth;
w *= (fXScale*vpHeight)*invLineHeight; w *= (fXScale*vpHeight)*invLineHeight;
mx += w + spacing*fXScale*vpWidth; mx += w + spacing*fXScale*vpWidth;
if (mx>maxx) maxx=mx; if (mx>maxx) maxx=mx;
} }
float offset=-maxx/2; float offset=-maxx/2;
strText = oldstrText; strText = oldstrText;
//Then let's draw it //Then let's draw it
if (center) if (center)
{ {
sx+=offset; sx+=offset;
fStartX+=offset; fStartX+=offset;
} }
float wScale=(fXScale*vpHeight)*invLineHeight; float wScale=(fXScale*vpHeight)*invLineHeight;
float hScale=(fYScale*vpHeight)*invLineHeight; float hScale=(fYScale*vpHeight)*invLineHeight;
while( *strText ) while( *strText )
{ {
char c = *strText++; char c = *strText++;
if( c == ('\n') ) if( c == ('\n') )
{ {
sx = fStartX; sx = fStartX;
sy += fYScale*vpHeight; sy += fYScale*vpHeight;
} }
if( c < (' ') ) if( c < (' ') )
continue; continue;
c-=32; c-=32;
float tx1 = m_fTexCoords[c][0]; float tx1 = m_fTexCoords[c][0];
float ty1 = m_fTexCoords[c][1]; float ty1 = m_fTexCoords[c][1];
float tx2 = m_fTexCoords[c][2]; float tx2 = m_fTexCoords[c][2];
float ty2 = m_fTexCoords[c][3]; float ty2 = m_fTexCoords[c][3];
float w = (tx2-tx1)*m_dwTexWidth; float w = (tx2-tx1)*m_dwTexWidth;
float h = (ty2-ty1)*m_dwTexHeight; float h = (ty2-ty1)*m_dwTexHeight;
w *= wScale; w *= wScale;
h *= hScale; h *= hScale;
FONT2DVERTEX v[6]; FONT2DVERTEX v[6];
v[0]=InitFont2DVertex(sx, sy+h, dwColor, tx1, ty2); v[0]=InitFont2DVertex(sx, sy+h, dwColor, tx1, ty2);
v[1]=InitFont2DVertex(sx, sy, dwColor, tx1, ty1); v[1]=InitFont2DVertex(sx, sy, dwColor, tx1, ty1);
v[2]=InitFont2DVertex(sx+w, sy+h, dwColor, tx2, ty2); v[2]=InitFont2DVertex(sx+w, sy+h, dwColor, tx2, ty2);
v[3]=InitFont2DVertex(sx+w, sy, dwColor, tx2, ty1); v[3]=InitFont2DVertex(sx+w, sy, dwColor, tx2, ty1);
v[4]=v[2]; v[4]=v[2];
v[5]=v[1]; v[5]=v[1];
memcpy(pVertices,v,6*sizeof(FONT2DVERTEX)); memcpy(pVertices,v,6*sizeof(FONT2DVERTEX));
pVertices+=6; pVertices+=6;
dwNumTriangles += 2; dwNumTriangles += 2;
if( dwNumTriangles * 3 > (MAX_NUM_VERTICES-6) ) if( dwNumTriangles * 3 > (MAX_NUM_VERTICES-6) )
{ {
// Unlock, render, and relock the vertex buffer // Unlock, render, and relock the vertex buffer
m_pVB->Unlock(); m_pVB->Unlock();
// dev->DrawPrimitive( D3DPT_TRIANGLELIST, 0, dwNumTriangles ); // dev->DrawPrimitive( D3DPT_TRIANGLELIST, 0, dwNumTriangles );
Renderer::DrawPrimitive( D3DPT_TRIANGLELIST, 0, dwNumTriangles ); Renderer::DrawPrimitive( D3DPT_TRIANGLELIST, 0, dwNumTriangles );
m_pVB->Lock( 0, 0, (void**)&pVertices, D3DLOCK_DISCARD ); m_pVB->Lock( 0, 0, (void**)&pVertices, D3DLOCK_DISCARD );
dwNumTriangles = 0; dwNumTriangles = 0;
} }
sx += w + spacing*fXScale*vpWidth; sx += w + spacing*fXScale*vpWidth;
} }
// Unlock and render the vertex buffer // Unlock and render the vertex buffer
m_pVB->Unlock(); m_pVB->Unlock();
if( dwNumTriangles > 0 ) if( dwNumTriangles > 0 )
{ {
// dev->DrawPrimitive( D3DPT_TRIANGLELIST, 0, dwNumTriangles ); // dev->DrawPrimitive( D3DPT_TRIANGLELIST, 0, dwNumTriangles );
Renderer::DrawPrimitive( D3DPT_TRIANGLELIST, 0, dwNumTriangles ); Renderer::DrawPrimitive( D3DPT_TRIANGLELIST, 0, dwNumTriangles );
} }
RestoreRenderStates(); RestoreRenderStates();
return S_OK; return S_OK;
} }
void quad2d(float x1, float y1, float x2, float y2, u32 color, float u1, float v1, float u2, float v2) void quad2d(float x1, float y1, float x2, float y2, u32 color, float u1, float v1, float u2, float v2)
{ {
SaveRenderStates(); SaveRenderStates();
struct Q2DVertex { float x,y,z,rhw; u32 color; float u, v; } coords[4] = { struct Q2DVertex { float x,y,z,rhw; u32 color; float u, v; } coords[4] = {
{x1-0.5f, y1-0.5f, 0, 1, color, u1, v1}, {x1-0.5f, y1-0.5f, 0, 1, color, u1, v1},
{x2-0.5f, y1-0.5f, 0, 1, color, u2, v1}, {x2-0.5f, y1-0.5f, 0, 1, color, u2, v1},
{x2-0.5f, y2-0.5f, 0, 1, color, u2, v2}, {x2-0.5f, y2-0.5f, 0, 1, color, u2, v2},
{x1-0.5f, y2-0.5f, 0, 1, color, u1, v2}, {x1-0.5f, y2-0.5f, 0, 1, color, u1, v2},
}; };
dev->SetPixelShader(0); dev->SetPixelShader(0);
dev->SetVertexShader(0); dev->SetVertexShader(0);
dev->SetVertexDeclaration(0); dev->SetVertexDeclaration(0);
// dev->SetFVF(D3DFVF_XYZRHW|D3DFVF_DIFFUSE|D3DFVF_TEX1); // dev->SetFVF(D3DFVF_XYZRHW|D3DFVF_DIFFUSE|D3DFVF_TEX1);
// dev->DrawPrimitiveUP(D3DPT_TRIANGLEFAN,2,coords,sizeof(Q2DVertex)); // dev->DrawPrimitiveUP(D3DPT_TRIANGLEFAN,2,coords,sizeof(Q2DVertex));
Renderer::SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1); Renderer::SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1);
Renderer::DrawPrimitiveUP(D3DPT_TRIANGLEFAN,2,coords,sizeof(Q2DVertex)); Renderer::DrawPrimitiveUP(D3DPT_TRIANGLEFAN,2,coords,sizeof(Q2DVertex));
RestoreRenderStates(); RestoreRenderStates();
} }
} }

View File

@ -1,468 +1,468 @@
#include "stdafx.h" #include "stdafx.h"
#if 0 #if 0
#include "OpcodeDecoding.h" #include "OpcodeDecoding.h"
#include "VertexLoader.h" #include "VertexLoader.h"
#include "VertexHandler.h" #include "VertexHandler.h"
#include "DataReader.h" #include "DataReader.h"
#include "BPStructs.h" #include "BPStructs.h"
#include "CPStructs.h" #include "CPStructs.h"
#include "XFStructs.h" #include "XFStructs.h"
#include "DLCompiler.h" #include "DLCompiler.h"
#include "x86.h" #include "x86.h"
#include "main.h" #include "main.h"
#include "Utils.h" #include "Utils.h"
CompiledDList::CompiledDList(u32 _addr, u32 _size) CompiledDList::CompiledDList(u32 _addr, u32 _size)
{ {
dataSize = 0; dataSize = 0;
data = 0; data = 0;
code = 0; code = 0;
addr = _addr; addr = _addr;
size = _size; size = _size;
pass = 0; pass = 0;
numBatches = 0; numBatches = 0;
batches = 0; batches = 0;
} }
CompiledDList::~CompiledDList() CompiledDList::~CompiledDList()
{ {
if (data) if (data)
delete [] data; delete [] data;
if (code) if (code)
delete [] code; delete [] code;
if (batches) if (batches)
delete [] batches; delete [] batches;
} }
bool CompiledDList::Call() bool CompiledDList::Call()
{ {
switch(pass) { switch(pass) {
case 0: // First compiling pass : find data size case 0: // First compiling pass : find data size
if (Pass1()) if (Pass1())
{ {
pass = 1; pass = 1;
return true; return true;
} }
else else
return false; return false;
case 1: // Second compiling pass : actually compile case 1: // Second compiling pass : actually compile
//if pass1 succeeded, pass2 will too //if pass1 succeeded, pass2 will too
Pass2(); Pass2();
pass = 2; pass = 2;
return true; return true;
case 2: // Run pass - we have a compiled dlist, just call it case 2: // Run pass - we have a compiled dlist, just call it
Run(); Run();
return true; return true;
default: default:
//ERROR //ERROR
return false; return false;
} }
} }
bool CompiledDList::Pass1() bool CompiledDList::Pass1()
{ {
/* //find the size of code + data, if the dlist is worth recompiling etc /* //find the size of code + data, if the dlist is worth recompiling etc
// at the same time, do the ordinary stuff // at the same time, do the ordinary stuff
g_pDataReader = &dlistReader; g_pDataReader = &dlistReader;
OpcodeReaders::SetDListReader(addr, addr+size); OpcodeReaders::SetDListReader(addr, addr+size);
dataSize = 0; dataSize = 0;
codeSize = 0; codeSize = 0;
numBatches = 0; numBatches = 0;
bool lastIsPrim = false; bool lastIsPrim = false;
while (OpcodeReaders::IsDListOKToRead()) while (OpcodeReaders::IsDListOKToRead())
{ {
int Cmd = g_pDataReader->Read8(); int Cmd = g_pDataReader->Read8();
switch(Cmd) switch(Cmd)
{ {
case GX_LOAD_CP_REG: //0x08 case GX_LOAD_CP_REG: //0x08
{ {
u32 SubCmd = g_pDataReader->Read8(); u32 SubCmd = g_pDataReader->Read8();
u32 Value = g_pDataReader->Read32(); u32 Value = g_pDataReader->Read32();
LoadCPReg(SubCmd,Value); LoadCPReg(SubCmd,Value);
//COMPILER //COMPILER
codeSize+=13; codeSize+=13;
} }
break; break;
case GX_LOAD_XF_REG: case GX_LOAD_XF_REG:
{ {
u32 Cmd2 = g_pDataReader->Read32(); u32 Cmd2 = g_pDataReader->Read32();
int dwTransferSize = ((Cmd2>>16)&15) + 1; int dwTransferSize = ((Cmd2>>16)&15) + 1;
DWORD dwAddress = Cmd2 & 0xFFFF; DWORD dwAddress = Cmd2 & 0xFFFF;
static u32 pData[16]; static u32 pData[16];
for (int i=0; i<dwTransferSize; i++) for (int i=0; i<dwTransferSize; i++)
pData[i] = g_pDataReader->Read32(); pData[i] = g_pDataReader->Read32();
LoadXFReg(dwTransferSize,dwAddress,pData); LoadXFReg(dwTransferSize,dwAddress,pData);
//COMPILER //COMPILER
dataSize+=dwTransferSize; dataSize+=dwTransferSize;
codeSize+=17; codeSize+=17;
} }
break; break;
case GX_LOAD_BP_REG: //0x61 case GX_LOAD_BP_REG: //0x61
{ {
u32 cmd=g_pDataReader->Read32(); u32 cmd=g_pDataReader->Read32();
LoadBPReg(cmd); LoadBPReg(cmd);
codeSize+=9; codeSize+=9;
} }
break; break;
case GX_LOAD_INDX_A: //used for position matrices case GX_LOAD_INDX_A: //used for position matrices
LoadIndexedXF(g_pDataReader->Read32(),0xC); LoadIndexedXF(g_pDataReader->Read32(),0xC);
codeSize+=13; codeSize+=13;
break; break;
case GX_LOAD_INDX_B: //used for normal matrices case GX_LOAD_INDX_B: //used for normal matrices
LoadIndexedXF(g_pDataReader->Read32(),0xD); LoadIndexedXF(g_pDataReader->Read32(),0xD);
codeSize+=13; codeSize+=13;
break; break;
case GX_LOAD_INDX_C: //used for postmatrices case GX_LOAD_INDX_C: //used for postmatrices
LoadIndexedXF(g_pDataReader->Read32(),0xE); LoadIndexedXF(g_pDataReader->Read32(),0xE);
codeSize+=13; codeSize+=13;
break; break;
case GX_LOAD_INDX_D: //used for lights case GX_LOAD_INDX_D: //used for lights
LoadIndexedXF(g_pDataReader->Read32(),0xF); LoadIndexedXF(g_pDataReader->Read32(),0xF);
codeSize+=13; codeSize+=13;
break; break;
case GX_CMD_CALL_DL: case GX_CMD_CALL_DL:
MessageBox(0,"Display lists can't recurse!!","error",0); MessageBox(0,"Display lists can't recurse!!","error",0);
break; break;
case GX_CMD_INVL_VC:// Invalidate (vertex cache?) case GX_CMD_INVL_VC:// Invalidate (vertex cache?)
break; break;
case GX_NOP: case GX_NOP:
break; break;
default: default:
if (Cmd&0x80) if (Cmd&0x80)
{ {
int primitive = (Cmd&GX_PRIMITIVE_MASK) >> GX_PRIMITIVE_SHIFT; int primitive = (Cmd&GX_PRIMITIVE_MASK) >> GX_PRIMITIVE_SHIFT;
if (lastIsPrim) if (lastIsPrim)
{ {
//join to last //join to last
} }
else else
{ {
//finish up last and commit //finish up last and commit
} }
u16 numVertices = g_pDataReader->Read16(); u16 numVertices = g_pDataReader->Read16();
tempvarray.Reset(); tempvarray.Reset();
VertexLoader::SetVArray(&tempvarray); VertexLoader::SetVArray(&tempvarray);
VertexLoader *loader = &VertexLoader[Cmd&GX_VAT_MASK]; VertexLoader *loader = &VertexLoader[Cmd&GX_VAT_MASK];
loader->Setup(); loader->Setup();
loader->PrepareRun(); loader->PrepareRun();
int vsize = loader->GetVertexSize(); int vsize = loader->GetVertexSize();
loader->RunVertices(numVertices); loader->RunVertices(numVertices);
CVertexHandler::DrawVertices(primitive, numVertices, &tempvarray); CVertexHandler::DrawVertices(primitive, numVertices, &tempvarray);
CVertexHandler::Flush(); CVertexHandler::Flush();
//COMPILER //COMPILER
codeSize+=21; codeSize+=21;
numBatches++; numBatches++;
lastIsPrim = true; lastIsPrim = true;
} }
break; break;
} }
} }
if (lastIsPrim) if (lastIsPrim)
{ {
//finish up last and commit //finish up last and commit
} }
codeSize*=2;*/ codeSize*=2;*/
return true; return true;
} }
void CompiledDList::Pass2() void CompiledDList::Pass2()
{ {
/* OpcodeReaders::SetDListReader(addr, addr+size); /* OpcodeReaders::SetDListReader(addr, addr+size);
data = new u32[dataSize]; data = new u32[dataSize];
code = new u8[codeSize]; //at least code = new u8[codeSize]; //at least
batches = new Batch[numBatches]; batches = new Batch[numBatches];
int batchCount = 0; int batchCount = 0;
u32 *dataptr = data; u32 *dataptr = data;
x86Init(); x86Init();
x86SetPtr((s8*)code); x86SetPtr((s8*)code);
//WC8(0xCC); //WC8(0xCC);
//actually do the recompiling, emit code and data, protect the memory //actually do the recompiling, emit code and data, protect the memory
// but again, at the same time do the ordinary stuff // but again, at the same time do the ordinary stuff
// so the compiled display list won't be run until the third time actually // so the compiled display list won't be run until the third time actually
bool dump = false,lastIsGeom=false; bool dump = false,lastIsGeom=false;
FILE *f; FILE *f;
#ifndef TEASER #ifndef TEASER
if (dump) if (dump)
{ {
f=fopen("D:\\dlistlogs.txt","a"); f=fopen("D:\\dlistlogs.txt","a");
fprintf(f,"===========================================\n"); fprintf(f,"===========================================\n");
} }
#endif #endif
while (OpcodeReaders::IsDListOKToRead()) while (OpcodeReaders::IsDListOKToRead())
{ {
int Cmd = g_pDataReader->Read8(); int Cmd = g_pDataReader->Read8();
switch(Cmd) switch(Cmd)
{ {
case GX_LOAD_CP_REG: //0x08 case GX_LOAD_CP_REG: //0x08
{ {
lastIsGeom = false; lastIsGeom = false;
u32 SubCmd = g_pDataReader->Read8(); u32 SubCmd = g_pDataReader->Read8();
u32 Value = g_pDataReader->Read32(); u32 Value = g_pDataReader->Read32();
if (dump) if (dump)
fprintf(f,"CP | %02x %08x\n",SubCmd,Value); fprintf(f,"CP | %02x %08x\n",SubCmd,Value);
LoadCPReg(SubCmd,Value); LoadCPReg(SubCmd,Value);
//COMPILER //COMPILER
PUSH_WordToStack(Value); PUSH_WordToStack(Value);
PUSH_WordToStack(SubCmd); PUSH_WordToStack(SubCmd);
CALLFunc((u32)LoadCPReg); CALLFunc((u32)LoadCPReg);
} }
break; break;
case GX_LOAD_XF_REG: case GX_LOAD_XF_REG:
{ {
lastIsGeom = false; lastIsGeom = false;
u32 Cmd2 = g_pDataReader->Read32(); u32 Cmd2 = g_pDataReader->Read32();
int dwTransferSize = ((Cmd2>>16)&15) + 1; int dwTransferSize = ((Cmd2>>16)&15) + 1;
u32 dwAddress = Cmd2 & 0xFFFF; u32 dwAddress = Cmd2 & 0xFFFF;
static u32 pData[16]; static u32 pData[16];
u32 *oldDataPtr = dataptr; u32 *oldDataPtr = dataptr;
if (dump) if (dump)
{ {
fprintf(f,"XF | %01xx %04x\n",dwTransferSize,dwAddress); fprintf(f,"XF | %01xx %04x\n",dwTransferSize,dwAddress);
for (int i=0; i<dwTransferSize; i++) for (int i=0; i<dwTransferSize; i++)
fprintf(f, "%08x | %f\n",oldDataPtr[i], *((float*)oldDataPtr+i)); fprintf(f, "%08x | %f\n",oldDataPtr[i], *((float*)oldDataPtr+i));
} }
for (int i=0; i<dwTransferSize; i++) // a little compiler here too for (int i=0; i<dwTransferSize; i++) // a little compiler here too
*dataptr++ = g_pDataReader->Read32(); *dataptr++ = g_pDataReader->Read32();
LoadXFReg(dwTransferSize,dwAddress,oldDataPtr); LoadXFReg(dwTransferSize,dwAddress,oldDataPtr);
//COMPILER //COMPILER
PUSH_WordToStack((u32)oldDataPtr); PUSH_WordToStack((u32)oldDataPtr);
PUSH_WordToStack(dwAddress); PUSH_WordToStack(dwAddress);
PUSH_WordToStack(dwTransferSize); PUSH_WordToStack(dwTransferSize);
CALLFunc((u32)LoadXFReg); CALLFunc((u32)LoadXFReg);
} }
break; break;
case GX_LOAD_BP_REG: //0x61 case GX_LOAD_BP_REG: //0x61
{ {
lastIsGeom = false; lastIsGeom = false;
u32 cmd=g_pDataReader->Read32(); u32 cmd=g_pDataReader->Read32();
if (dump) if (dump)
fprintf(f,"BP | %08x\n",cmd); fprintf(f,"BP | %08x\n",cmd);
LoadBPReg(cmd); LoadBPReg(cmd);
//COMPILER //COMPILER
PUSH_WordToStack(cmd); PUSH_WordToStack(cmd);
CALLFunc((u32)LoadBPReg); CALLFunc((u32)LoadBPReg);
} }
break; break;
case GX_LOAD_INDX_A: //usually used for position matrices case GX_LOAD_INDX_A: //usually used for position matrices
{ {
lastIsGeom = false; lastIsGeom = false;
u32 value = g_pDataReader->Read32(); u32 value = g_pDataReader->Read32();
LoadIndexedXF(value,0xC); LoadIndexedXF(value,0xC);
//COMPILER //COMPILER
PUSH_WordToStack(0xC); PUSH_WordToStack(0xC);
PUSH_WordToStack(value); PUSH_WordToStack(value);
CALLFunc((u32)LoadIndexedXF); CALLFunc((u32)LoadIndexedXF);
if (dump) if (dump)
fprintf(f,"LOADINDEXA | pos matrix\n"); fprintf(f,"LOADINDEXA | pos matrix\n");
} }
break; break;
case GX_LOAD_INDX_B: //usually used for normal matrices case GX_LOAD_INDX_B: //usually used for normal matrices
{ {
lastIsGeom = false; lastIsGeom = false;
u32 value = g_pDataReader->Read32(); u32 value = g_pDataReader->Read32();
LoadIndexedXF(value,0xD); LoadIndexedXF(value,0xD);
//COMPILER //COMPILER
PUSH_WordToStack(0xD); PUSH_WordToStack(0xD);
PUSH_WordToStack(value); PUSH_WordToStack(value);
CALLFunc((u32)LoadIndexedXF); CALLFunc((u32)LoadIndexedXF);
if (dump) if (dump)
fprintf(f,"LOADINDEXB | nrm matrix\n"); fprintf(f,"LOADINDEXB | nrm matrix\n");
} }
break; break;
case GX_LOAD_INDX_C: //usually used for postmatrices case GX_LOAD_INDX_C: //usually used for postmatrices
{ {
lastIsGeom = false; lastIsGeom = false;
u32 value = g_pDataReader->Read32(); u32 value = g_pDataReader->Read32();
LoadIndexedXF(value,0xE); LoadIndexedXF(value,0xE);
//COMPILER //COMPILER
PUSH_WordToStack(0xE); PUSH_WordToStack(0xE);
PUSH_WordToStack(value); PUSH_WordToStack(value);
CALLFunc((u32)LoadIndexedXF); CALLFunc((u32)LoadIndexedXF);
if (dump) if (dump)
fprintf(f,"LOADINDEXC | post matrix\n"); fprintf(f,"LOADINDEXC | post matrix\n");
} }
break; break;
case GX_LOAD_INDX_D: //usually used for lights case GX_LOAD_INDX_D: //usually used for lights
{ {
lastIsGeom = false; lastIsGeom = false;
u32 value = g_pDataReader->Read32(); u32 value = g_pDataReader->Read32();
LoadIndexedXF(value,0xF); LoadIndexedXF(value,0xF);
//COMPILER //COMPILER
PUSH_WordToStack(0xF); PUSH_WordToStack(0xF);
PUSH_WordToStack(value); PUSH_WordToStack(value);
CALLFunc((u32)LoadIndexedXF); CALLFunc((u32)LoadIndexedXF);
if (dump) if (dump)
fprintf(f,"LOADINDEXD | light\n"); fprintf(f,"LOADINDEXD | light\n");
} }
break; break;
case GX_CMD_CALL_DL: case GX_CMD_CALL_DL:
// ERORRR // ERORRR
break; break;
case GX_CMD_INVL_VC:// Invalidate (vertex cache?) case GX_CMD_INVL_VC:// Invalidate (vertex cache?)
if (dump) if (dump)
fprintf(f,"invalidate vc\n"); fprintf(f,"invalidate vc\n");
break; break;
case GX_NOP: case GX_NOP:
if (dump) if (dump)
fprintf(f,"nop\n"); fprintf(f,"nop\n");
break; break;
default: default:
if (Cmd&0x80) if (Cmd&0x80)
{ {
int primitive = (Cmd&GX_PRIMITIVE_MASK) >> GX_PRIMITIVE_SHIFT; int primitive = (Cmd&GX_PRIMITIVE_MASK) >> GX_PRIMITIVE_SHIFT;
//if (lastIsGeom) INCSTAT(stats.numJoins); //if (lastIsGeom) INCSTAT(stats.numJoins);
u16 numVertices = g_pDataReader->Read16(); u16 numVertices = g_pDataReader->Read16();
if (dump) if (dump)
fprintf(f,"DP: prim=%02x numv=%i\n",primitive,numVertices); fprintf(f,"DP: prim=%02x numv=%i\n",primitive,numVertices);
DecodedVArray &va = batches[batchCount].varray; DecodedVArray &va = batches[batchCount].varray;
VertexLoader *loader = &VertexLoader[Cmd&GX_VAT_MASK]; VertexLoader *loader = &VertexLoader[Cmd&GX_VAT_MASK];
TVtxDesc &vd = loader->GetVtxDesc(); TVtxDesc &vd = loader->GetVtxDesc();
VertexLoader::SetVArray(&va); VertexLoader::SetVArray(&va);
loader->Setup(); loader->Setup();
loader->PrepareRun(); loader->PrepareRun();
// va.numColors = loader->GetNumColors(); // va.numColors = loader->GetNumColors();
// va.numUVs = loader->GetNumTCs(); // va.numUVs = loader->GetNumTCs();
// va.numNormals = loader->GetNumNormals(); // va.numNormals = loader->GetNumNormals();
//va.num //va.num
va.Create(numVertices,vd.PosMatIdx, va.Create(numVertices,vd.PosMatIdx,
vd.Tex0MatIdx+vd.Tex1MatIdx+vd.Tex2MatIdx+vd.Tex3MatIdx+ vd.Tex0MatIdx+vd.Tex1MatIdx+vd.Tex2MatIdx+vd.Tex3MatIdx+
vd.Tex4MatIdx+vd.Tex5MatIdx+vd.Tex6MatIdx+vd.Tex7MatIdx, vd.Tex4MatIdx+vd.Tex5MatIdx+vd.Tex6MatIdx+vd.Tex7MatIdx,
va.numNormals, va.numColors, va.numTCs); va.numNormals, va.numColors, va.numTCs);
int vsize = loader->GetVertexSize(); int vsize = loader->GetVertexSize();
loader->RunVertices(numVertices); loader->RunVertices(numVertices);
CVertexHandler::DrawVertices(primitive, numVertices, &va); CVertexHandler::DrawVertices(primitive, numVertices, &va);
CVertexHandler::Flush(); CVertexHandler::Flush();
// YES we have now filled our varray // YES we have now filled our varray
//LETS COMPILE //LETS COMPILE
PUSH_WordToStack(primitive); PUSH_WordToStack(primitive);
PUSH_WordToStack(batchCount); PUSH_WordToStack(batchCount);
PUSH_WordToStack((u32)this); PUSH_WordToStack((u32)this);
CALLFunc((u32)DrawHelperHelper); CALLFunc((u32)DrawHelperHelper);
batchCount++; batchCount++;
lastIsGeom = true; lastIsGeom = true;
if (dump) if (dump)
fprintf(f,"DRAW PRIMITIVE: prim=%02x numv=%i\n",primitive,numVertices); fprintf(f,"DRAW PRIMITIVE: prim=%02x numv=%i\n",primitive,numVertices);
} }
break; break;
} }
} }
if (dump) if (dump)
{ {
fprintf(f,"***************************************\n\n\n"); fprintf(f,"***************************************\n\n\n");
} }
RET(); RET();
if (dump) if (dump)
fclose(f);*/ fclose(f);*/
//we're done, next time just kick the compiled list off, much much faster than interpreting! //we're done, next time just kick the compiled list off, much much faster than interpreting!
} }
void CompiledDList::DrawHelperHelper(CompiledDList *dl, int vno, int prim) void CompiledDList::DrawHelperHelper(CompiledDList *dl, int vno, int prim)
{ {
Batch &b = dl->batches[vno]; Batch &b = dl->batches[vno];
CVertexHandler::DrawVertices(prim, b.varray.GetSize(), &b.varray); CVertexHandler::DrawVertices(prim, b.varray.GetSize(), &b.varray);
} }
void CompiledDList::Run() void CompiledDList::Run()
{ {
//run the code //run the code
((void (*)())(code))(); ((void (*)())(code))();
CVertexHandler::Flush(); CVertexHandler::Flush();
} }
DListCache::DLCache DListCache::dlists; DListCache::DLCache DListCache::dlists;
void DListCache::Init() void DListCache::Init()
{ {
} }
void DListCache::Shutdown() void DListCache::Shutdown()
{ {
DLCache::iterator iter = dlists.begin(); DLCache::iterator iter = dlists.begin();
for (;iter!=dlists.end();iter++) for (;iter!=dlists.end();iter++)
iter->second.Destroy(); iter->second.Destroy();
dlists.clear(); dlists.clear();
} }
void DListCache::Call(u32 _addr, u32 _size) void DListCache::Call(u32 _addr, u32 _size)
{ {
DLCache::iterator iter; DLCache::iterator iter;
iter = dlists.find(_addr); iter = dlists.find(_addr);
if (iter != dlists.end()) if (iter != dlists.end())
{ {
if (iter->second.size == _size) if (iter->second.size == _size)
{ {
iter->second.dlist->Call(); iter->second.dlist->Call();
return; return;
} }
else // wrong size, need to recompile else // wrong size, need to recompile
{ {
iter->second.Destroy(); iter->second.Destroy();
iter=dlists.erase(iter); iter=dlists.erase(iter);
} }
} }
//Make an entry in the table //Make an entry in the table
DLCacheEntry entry; DLCacheEntry entry;
entry.dlist = new CompiledDList(_addr, _size); entry.dlist = new CompiledDList(_addr, _size);
entry.dlist->Call(); entry.dlist->Call();
entry.frameCount = frameCount; entry.frameCount = frameCount;
entry.size = _size; entry.size = _size;
dlists[_addr] = entry; dlists[_addr] = entry;
INCSTAT(stats.numDListsCreated); INCSTAT(stats.numDListsCreated);
SETSTAT(stats.numDListsAlive,(int)dlists.size()); SETSTAT(stats.numDListsAlive,(int)dlists.size());
} }
void DListCache::Cleanup() void DListCache::Cleanup()
{ {
for (DLCache::iterator iter=dlists.begin(); iter!=dlists.end();iter++) for (DLCache::iterator iter=dlists.begin(); iter!=dlists.end();iter++)
{ {
DLCacheEntry &entry = iter->second; DLCacheEntry &entry = iter->second;
if (entry.frameCount<frameCount-80) if (entry.frameCount<frameCount-80)
{ {
entry.Destroy(); entry.Destroy();
iter = dlists.erase(iter); iter = dlists.erase(iter);
} }
} }
SETSTAT(stats.numDListsAlive,(int)dlists.size()); SETSTAT(stats.numDListsAlive,(int)dlists.size());
} }
#endif #endif

View File

@ -1,92 +1,92 @@
// 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 "stdafx.h" #include "stdafx.h"
#include "DecodedVArray.h" #include "DecodedVArray.h"
#include "main.h" #include "main.h"
DecodedVArray::DecodedVArray() DecodedVArray::DecodedVArray()
{ {
Zero(); Zero();
} }
DecodedVArray::~DecodedVArray() DecodedVArray::~DecodedVArray()
{ {
Destroy(); Destroy();
} }
void DecodedVArray::Zero() void DecodedVArray::Zero()
{ {
size = 0; size = 0;
count = 0; count = 0;
components = 0; components = 0;
positions = 0; positions = 0;
posMtxInds = 0; posMtxInds = 0;
for (int i=0; i<3; i++) for (int i=0; i<3; i++)
normals[i] = 0; normals[i] = 0;
for (int i=0; i<2; i++) for (int i=0; i<2; i++)
colors[i] = 0; colors[i] = 0;
for (int i=0; i<8; i++) for (int i=0; i<8; i++)
{ {
texMtxInds[i] = 0; texMtxInds[i] = 0;
uvs[i] = 0; uvs[i] = 0;
} }
} }
void DecodedVArray::Destroy() void DecodedVArray::Destroy()
{ {
//,, //,,
delete [] positions; delete [] positions;
delete [] posMtxInds; delete [] posMtxInds;
for (int i=0; i<3; i++) for (int i=0; i<3; i++)
delete [] normals[i]; delete [] normals[i];
for (int i=0; i<2; i++) for (int i=0; i<2; i++)
delete [] colors[i]; delete [] colors[i];
for (int i=0; i<8; i++) for (int i=0; i<8; i++)
{ {
delete [] uvs[i]; delete [] uvs[i];
delete [] texMtxInds[i]; delete [] texMtxInds[i];
} }
Zero(); Zero();
} }
void DecodedVArray::Create(int _size, int pmcount, int tmcount, int nrmcount, int colcount, int tccount) void DecodedVArray::Create(int _size, int pmcount, int tmcount, int nrmcount, int colcount, int tccount)
{ {
size = _size; size = _size;
// position matrix indices // position matrix indices
if (pmcount) if (pmcount)
posMtxInds = new DecMtxInd[size]; posMtxInds = new DecMtxInd[size];
// texture matrix indices // texture matrix indices
if (tmcount) if (tmcount)
for (int i=0; i<tmcount; i++) for (int i=0; i<tmcount; i++)
texMtxInds[i] = new DecMtxInd[size]; texMtxInds[i] = new DecMtxInd[size];
// positions (always) // positions (always)
positions = new DecPos[size]; positions = new DecPos[size];
// normals // normals
if (nrmcount) if (nrmcount)
for (int i=0; i<nrmcount; i++) for (int i=0; i<nrmcount; i++)
normals[i] = new DecNormal[size]; normals[i] = new DecNormal[size];
// colors // colors
if (colcount) if (colcount)
for (int i=0; i<colcount; i++) for (int i=0; i<colcount; i++)
colors[i] = new DecColor[size]; colors[i] = new DecColor[size];
if (tccount) if (tccount)
for (int i=0; i<tccount; i++) for (int i=0; i<tccount; i++)
uvs[i] = new DecUV[size]; uvs[i] = new DecUV[size];
} }

View File

@ -1,246 +1,246 @@
// 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 <windowsx.h> #include <windowsx.h>
#include "resource.h" #include "resource.h"
#include "W32Util/PropertySheet.h" #include "W32Util/PropertySheet.h"
#include "W32Util/ShellUtil.h" #include "W32Util/ShellUtil.h"
#include "D3DBase.h" #include "D3DBase.h"
#include "D3DPostprocess.h" #include "D3DPostprocess.h"
#include "Config.h" #include "Config.h"
#include "TextureCache.h" #include "TextureCache.h"
#define NUMWNDRES 6 #define NUMWNDRES 6
int g_Res[NUMWNDRES][2] = int g_Res[NUMWNDRES][2] =
{ {
{640,480}, {640,480},
{800,600}, {800,600},
{1024,768}, {1024,768},
{1280,960}, {1280,960},
{1280,1024}, {1280,1024},
{1600,1200}, {1600,1200},
}; };
struct TabDirect3D : public W32Util::Tab struct TabDirect3D : public W32Util::Tab
{ {
void Init(HWND hDlg) void Init(HWND hDlg)
{ {
for (int i=0; i<D3D::GetNumAdapters(); i++) for (int i=0; i<D3D::GetNumAdapters(); i++)
{ {
const D3D::Adapter &adapter = D3D::GetAdapter(i); const D3D::Adapter &adapter = D3D::GetAdapter(i);
ComboBox_AddString(GetDlgItem(hDlg,IDC_ADAPTER),adapter.ident.Description); ComboBox_AddString(GetDlgItem(hDlg,IDC_ADAPTER),adapter.ident.Description);
} }
const D3D::Adapter &adapter = D3D::GetAdapter(g_Config.iAdapter); const D3D::Adapter &adapter = D3D::GetAdapter(g_Config.iAdapter);
ComboBox_SetCurSel(GetDlgItem(hDlg, IDC_ADAPTER),g_Config.iAdapter); ComboBox_SetCurSel(GetDlgItem(hDlg, IDC_ADAPTER),g_Config.iAdapter);
for (int i = 0; i < (int)adapter.aa_levels.size(); i++) for (int i = 0; i < (int)adapter.aa_levels.size(); i++)
{ {
ComboBox_AddString(GetDlgItem(hDlg, IDC_ANTIALIASMODE), adapter.aa_levels[i].name); ComboBox_AddString(GetDlgItem(hDlg, IDC_ANTIALIASMODE), adapter.aa_levels[i].name);
} }
ComboBox_SetCurSel(GetDlgItem(hDlg, IDC_ANTIALIASMODE), g_Config.iMultisampleMode); ComboBox_SetCurSel(GetDlgItem(hDlg, IDC_ANTIALIASMODE), g_Config.iMultisampleMode);
if (adapter.aa_levels.size() == 1) if (adapter.aa_levels.size() == 1)
{ {
EnableWindow(GetDlgItem(hDlg, IDC_ANTIALIASMODE), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_ANTIALIASMODE), FALSE);
} }
for (int i = 0; i < (int)adapter.resolutions.size(); i++) for (int i = 0; i < (int)adapter.resolutions.size(); i++)
{ {
const D3D::Resolution &r = adapter.resolutions[i]; const D3D::Resolution &r = adapter.resolutions[i];
ComboBox_AddString(GetDlgItem(hDlg,IDC_RESOLUTION), r.name); ComboBox_AddString(GetDlgItem(hDlg,IDC_RESOLUTION), r.name);
} }
ComboBox_SetCurSel(GetDlgItem(hDlg,IDC_RESOLUTION), g_Config.iFSResolution); ComboBox_SetCurSel(GetDlgItem(hDlg,IDC_RESOLUTION), g_Config.iFSResolution);
for (int i = 0; i < NUMWNDRES; i++) for (int i = 0; i < NUMWNDRES; i++)
{ {
char temp[256]; char temp[256];
sprintf(temp,"%ix%i",g_Res[i][0],g_Res[i][1]); sprintf(temp,"%ix%i",g_Res[i][0],g_Res[i][1]);
ComboBox_AddString(GetDlgItem(hDlg,IDC_RESOLUTIONWINDOWED),temp); ComboBox_AddString(GetDlgItem(hDlg,IDC_RESOLUTIONWINDOWED),temp);
} }
ComboBox_SetCurSel(GetDlgItem(hDlg,IDC_RESOLUTIONWINDOWED),g_Config.iWindowedRes); ComboBox_SetCurSel(GetDlgItem(hDlg,IDC_RESOLUTIONWINDOWED),g_Config.iWindowedRes);
CheckDlgButton(hDlg, IDC_FULLSCREENENABLE, g_Config.bFullscreen ? TRUE : FALSE); CheckDlgButton(hDlg, IDC_FULLSCREENENABLE, g_Config.bFullscreen ? TRUE : FALSE);
CheckDlgButton(hDlg, IDC_VSYNC, g_Config.bVsync ? TRUE : FALSE); CheckDlgButton(hDlg, IDC_VSYNC, g_Config.bVsync ? TRUE : FALSE);
CheckDlgButton(hDlg, IDC_RENDER_TO_MAINWINDOW, g_Config.renderToMainframe ? TRUE : FALSE); CheckDlgButton(hDlg, IDC_RENDER_TO_MAINWINDOW, g_Config.renderToMainframe ? TRUE : FALSE);
} }
void Command(HWND hDlg,WPARAM wParam) void Command(HWND hDlg,WPARAM wParam)
{ {
/* /*
switch (LOWORD(wParam)) switch (LOWORD(wParam))
{ {
default: default:
break; break;
} }
*/ */
} }
void Apply(HWND hDlg) void Apply(HWND hDlg)
{ {
g_Config.iAdapter = ComboBox_GetCurSel(GetDlgItem(hDlg, IDC_ADAPTER)); g_Config.iAdapter = ComboBox_GetCurSel(GetDlgItem(hDlg, IDC_ADAPTER));
g_Config.iWindowedRes = ComboBox_GetCurSel(GetDlgItem(hDlg, IDC_RESOLUTIONWINDOWED)); g_Config.iWindowedRes = ComboBox_GetCurSel(GetDlgItem(hDlg, IDC_RESOLUTIONWINDOWED));
g_Config.iMultisampleMode = ComboBox_GetCurSel(GetDlgItem(hDlg, IDC_ANTIALIASMODE)); g_Config.iMultisampleMode = ComboBox_GetCurSel(GetDlgItem(hDlg, IDC_ANTIALIASMODE));
g_Config.iFSResolution = ComboBox_GetCurSel(GetDlgItem(hDlg,IDC_RESOLUTION)); g_Config.iFSResolution = ComboBox_GetCurSel(GetDlgItem(hDlg,IDC_RESOLUTION));
g_Config.bFullscreen = Button_GetCheck(GetDlgItem(hDlg, IDC_FULLSCREENENABLE)) ? true : false; g_Config.bFullscreen = Button_GetCheck(GetDlgItem(hDlg, IDC_FULLSCREENENABLE)) ? true : false;
g_Config.bVsync = Button_GetCheck(GetDlgItem(hDlg, IDC_VSYNC)) ? true : false; g_Config.bVsync = Button_GetCheck(GetDlgItem(hDlg, IDC_VSYNC)) ? true : false;
g_Config.renderToMainframe = Button_GetCheck(GetDlgItem(hDlg, IDC_RENDER_TO_MAINWINDOW)) ? true : false; g_Config.renderToMainframe = Button_GetCheck(GetDlgItem(hDlg, IDC_RENDER_TO_MAINWINDOW)) ? true : false;
g_Config.Save(); g_Config.Save();
} }
}; };
struct TabAdvanced : public W32Util::Tab struct TabAdvanced : public W32Util::Tab
{ {
void Init(HWND hDlg) void Init(HWND hDlg)
{ {
HWND opt = GetDlgItem(hDlg,IDC_DLOPTLEVEL); HWND opt = GetDlgItem(hDlg,IDC_DLOPTLEVEL);
ComboBox_AddString(opt,"0: Interpret (slowest, most compatible)"); ComboBox_AddString(opt,"0: Interpret (slowest, most compatible)");
ComboBox_AddString(opt,"1: Compile lists and decode vertex lists"); ComboBox_AddString(opt,"1: Compile lists and decode vertex lists");
//ComboBox_AddString(opt,"2: Compile+decode to vbufs and use hw xform"); //ComboBox_AddString(opt,"2: Compile+decode to vbufs and use hw xform");
//ComboBox_AddString(opt,"Recompile to vbuffers and shaders"); //ComboBox_AddString(opt,"Recompile to vbuffers and shaders");
ComboBox_SetCurSel(opt,g_Config.iCompileDLsLevel); ComboBox_SetCurSel(opt,g_Config.iCompileDLsLevel);
Button_SetCheck(GetDlgItem(hDlg,IDC_OVERLAYSTATS), g_Config.bOverlayStats); Button_SetCheck(GetDlgItem(hDlg,IDC_OVERLAYSTATS), g_Config.bOverlayStats);
Button_SetCheck(GetDlgItem(hDlg,IDC_WIREFRAME), g_Config.bWireFrame); Button_SetCheck(GetDlgItem(hDlg,IDC_WIREFRAME), g_Config.bWireFrame);
Button_SetCheck(GetDlgItem(hDlg,IDC_TEXDUMP), g_Config.bDumpTextures); Button_SetCheck(GetDlgItem(hDlg,IDC_TEXDUMP), g_Config.bDumpTextures);
Button_SetCheck(GetDlgItem(hDlg,IDC_SHOWSHADERERRORS), g_Config.bShowShaderErrors); Button_SetCheck(GetDlgItem(hDlg,IDC_SHOWSHADERERRORS), g_Config.bShowShaderErrors);
Button_SetCheck(GetDlgItem(hDlg,IDC_TEXFMT_OVERLAY), g_Config.bTexFmtOverlayEnable); Button_SetCheck(GetDlgItem(hDlg,IDC_TEXFMT_OVERLAY), g_Config.bTexFmtOverlayEnable);
Button_SetCheck(GetDlgItem(hDlg,IDC_TEXFMT_CENTER), g_Config.bTexFmtOverlayCenter); Button_SetCheck(GetDlgItem(hDlg,IDC_TEXFMT_CENTER), g_Config.bTexFmtOverlayCenter);
Button_GetCheck(GetDlgItem(hDlg,IDC_TEXFMT_OVERLAY)) ? Button_Enable(GetDlgItem(hDlg,IDC_TEXFMT_CENTER), true) : Button_Enable(GetDlgItem(hDlg,IDC_TEXFMT_CENTER), false); Button_GetCheck(GetDlgItem(hDlg,IDC_TEXFMT_OVERLAY)) ? Button_Enable(GetDlgItem(hDlg,IDC_TEXFMT_CENTER), true) : Button_Enable(GetDlgItem(hDlg,IDC_TEXFMT_CENTER), false);
SetWindowText(GetDlgItem(hDlg,IDC_TEXDUMPPATH),g_Config.texDumpPath.c_str()); SetWindowText(GetDlgItem(hDlg,IDC_TEXDUMPPATH),g_Config.texDumpPath.c_str());
Edit_LimitText(GetDlgItem(hDlg,IDC_TEXDUMPPATH),255); Edit_LimitText(GetDlgItem(hDlg,IDC_TEXDUMPPATH),255);
} }
void Command(HWND hDlg,WPARAM wParam) void Command(HWND hDlg,WPARAM wParam)
{ {
switch (LOWORD(wParam)) switch (LOWORD(wParam))
{ {
case IDC_BROWSETEXDUMPPATH: case IDC_BROWSETEXDUMPPATH:
{ {
std::string path = W32Util::BrowseForFolder(hDlg,"Choose texture dump path:"); std::string path = W32Util::BrowseForFolder(hDlg,"Choose texture dump path:");
SetWindowText(GetDlgItem(hDlg,IDC_TEXDUMPPATH),path.c_str()); SetWindowText(GetDlgItem(hDlg,IDC_TEXDUMPPATH),path.c_str());
} }
break; break;
case IDC_TEXFMT_OVERLAY: case IDC_TEXFMT_OVERLAY:
{ {
Button_GetCheck(GetDlgItem(hDlg,IDC_TEXFMT_OVERLAY)) ? Button_Enable(GetDlgItem(hDlg,IDC_TEXFMT_CENTER), true) : Button_Enable(GetDlgItem(hDlg,IDC_TEXFMT_CENTER), false); Button_GetCheck(GetDlgItem(hDlg,IDC_TEXFMT_OVERLAY)) ? Button_Enable(GetDlgItem(hDlg,IDC_TEXFMT_CENTER), true) : Button_Enable(GetDlgItem(hDlg,IDC_TEXFMT_CENTER), false);
} }
break; break;
default: default:
break; break;
} }
} }
void Apply(HWND hDlg) void Apply(HWND hDlg)
{ {
g_Config.bTexFmtOverlayEnable = Button_GetCheck(GetDlgItem(hDlg,IDC_TEXFMT_OVERLAY)) ? true : false; g_Config.bTexFmtOverlayEnable = Button_GetCheck(GetDlgItem(hDlg,IDC_TEXFMT_OVERLAY)) ? true : false;
g_Config.bTexFmtOverlayCenter = Button_GetCheck(GetDlgItem(hDlg,IDC_TEXFMT_CENTER)) ? true : false; g_Config.bTexFmtOverlayCenter = Button_GetCheck(GetDlgItem(hDlg,IDC_TEXFMT_CENTER)) ? true : false;
g_Config.bOverlayStats = Button_GetCheck(GetDlgItem(hDlg,IDC_OVERLAYSTATS)) ? true : false; g_Config.bOverlayStats = Button_GetCheck(GetDlgItem(hDlg,IDC_OVERLAYSTATS)) ? true : false;
g_Config.bWireFrame = Button_GetCheck(GetDlgItem(hDlg,IDC_WIREFRAME)) ? true : false; g_Config.bWireFrame = Button_GetCheck(GetDlgItem(hDlg,IDC_WIREFRAME)) ? true : false;
g_Config.bDumpTextures = Button_GetCheck(GetDlgItem(hDlg,IDC_TEXDUMP)) ? true : false; g_Config.bDumpTextures = Button_GetCheck(GetDlgItem(hDlg,IDC_TEXDUMP)) ? true : false;
g_Config.iCompileDLsLevel = (int)ComboBox_GetCurSel(GetDlgItem(hDlg,IDC_DLOPTLEVEL)); g_Config.iCompileDLsLevel = (int)ComboBox_GetCurSel(GetDlgItem(hDlg,IDC_DLOPTLEVEL));
g_Config.bShowShaderErrors = Button_GetCheck(GetDlgItem(hDlg,IDC_SHOWSHADERERRORS)) ? true : false; g_Config.bShowShaderErrors = Button_GetCheck(GetDlgItem(hDlg,IDC_SHOWSHADERERRORS)) ? true : false;
char temp[MAX_PATH]; char temp[MAX_PATH];
GetWindowText(GetDlgItem(hDlg,IDC_TEXDUMPPATH), temp, MAX_PATH); GetWindowText(GetDlgItem(hDlg,IDC_TEXDUMPPATH), temp, MAX_PATH);
g_Config.texDumpPath = temp; g_Config.texDumpPath = temp;
} }
}; };
struct TabDebug : public W32Util::Tab struct TabDebug : public W32Util::Tab
{ {
void Init(HWND hDlg) void Init(HWND hDlg)
{ {
} }
void Command(HWND hDlg,WPARAM wParam) void Command(HWND hDlg,WPARAM wParam)
{ {
/* /*
switch (LOWORD(wParam)) switch (LOWORD(wParam))
{ {
default: default:
break; break;
} }
*/ */
} }
void Apply(HWND hDlg) void Apply(HWND hDlg)
{ {
} }
}; };
struct TabEnhancements : public W32Util::Tab struct TabEnhancements : public W32Util::Tab
{ {
void Init(HWND hDlg) void Init(HWND hDlg)
{ {
Button_SetCheck(GetDlgItem(hDlg,IDC_FORCEFILTERING),g_Config.bForceFiltering); Button_SetCheck(GetDlgItem(hDlg,IDC_FORCEFILTERING),g_Config.bForceFiltering);
Button_SetCheck(GetDlgItem(hDlg,IDC_FORCEANISOTROPY),g_Config.bForceMaxAniso); Button_SetCheck(GetDlgItem(hDlg,IDC_FORCEANISOTROPY),g_Config.bForceMaxAniso);
HWND pp = GetDlgItem(hDlg,IDC_POSTPROCESSEFFECT); HWND pp = GetDlgItem(hDlg,IDC_POSTPROCESSEFFECT);
const char **names = Postprocess::GetPostprocessingNames(); const char **names = Postprocess::GetPostprocessingNames();
int i = 0; int i = 0;
while (true) while (true)
{ {
if (!names[i]) if (!names[i])
break; break;
ComboBox_AddString(pp, names[i]); ComboBox_AddString(pp, names[i]);
i++; i++;
} }
ComboBox_SetCurSel(pp, g_Config.iPostprocessEffect); ComboBox_SetCurSel(pp, g_Config.iPostprocessEffect);
} }
void Command(HWND hDlg,WPARAM wParam) void Command(HWND hDlg,WPARAM wParam)
{ {
/* /*
switch (LOWORD(wParam)) switch (LOWORD(wParam))
{ {
default: default:
break; break;
} }
*/ */
} }
void Apply(HWND hDlg) void Apply(HWND hDlg)
{ {
g_Config.bForceMaxAniso = Button_GetCheck(GetDlgItem(hDlg, IDC_FORCEANISOTROPY)) ? true : false; g_Config.bForceMaxAniso = Button_GetCheck(GetDlgItem(hDlg, IDC_FORCEANISOTROPY)) ? true : false;
g_Config.bForceFiltering = Button_GetCheck(GetDlgItem(hDlg,IDC_FORCEFILTERING)) ? true : false; g_Config.bForceFiltering = Button_GetCheck(GetDlgItem(hDlg,IDC_FORCEFILTERING)) ? true : false;
g_Config.iPostprocessEffect = ComboBox_GetCurSel(GetDlgItem(hDlg,IDC_POSTPROCESSEFFECT)); g_Config.iPostprocessEffect = ComboBox_GetCurSel(GetDlgItem(hDlg,IDC_POSTPROCESSEFFECT));
} }
}; };
void DlgSettings_Show(HINSTANCE hInstance, HWND _hParent) void DlgSettings_Show(HINSTANCE hInstance, HWND _hParent)
{ {
bool tfoe = g_Config.bTexFmtOverlayEnable; bool tfoe = g_Config.bTexFmtOverlayEnable;
bool tfoc = g_Config.bTexFmtOverlayCenter; bool tfoc = g_Config.bTexFmtOverlayCenter;
g_Config.Load(); g_Config.Load();
W32Util::PropSheet sheet; W32Util::PropSheet sheet;
sheet.Add(new TabDirect3D,(LPCTSTR)IDD_SETTINGS,"Direct3D"); sheet.Add(new TabDirect3D,(LPCTSTR)IDD_SETTINGS,"Direct3D");
sheet.Add(new TabEnhancements,(LPCTSTR)IDD_ENHANCEMENTS,"Enhancements"); sheet.Add(new TabEnhancements,(LPCTSTR)IDD_ENHANCEMENTS,"Enhancements");
sheet.Add(new TabAdvanced,(LPCTSTR)IDD_ADVANCED,"Advanced"); sheet.Add(new TabAdvanced,(LPCTSTR)IDD_ADVANCED,"Advanced");
//sheet.Add(new TabDebug,(LPCTSTR)IDD_DEBUGGER,"Debugger"); //sheet.Add(new TabDebug,(LPCTSTR)IDD_DEBUGGER,"Debugger");
sheet.Show(hInstance,_hParent,"Graphics Plugin"); sheet.Show(hInstance,_hParent,"Graphics Plugin");
g_Config.Save(); g_Config.Save();
if(( tfoe != g_Config.bTexFmtOverlayEnable) || if(( tfoe != g_Config.bTexFmtOverlayEnable) ||
((g_Config.bTexFmtOverlayEnable) && ( tfoc != g_Config.bTexFmtOverlayCenter))) ((g_Config.bTexFmtOverlayEnable) && ( tfoc != g_Config.bTexFmtOverlayCenter)))
{ {
TextureCache::Invalidate(); TextureCache::Invalidate();
} }
} }

View File

@ -1,173 +1,173 @@
#include <windows.h> #include <windows.h>
#include "../../Core/Src/Core.h" #include "../../Core/Src/Core.h"
#include "Config.h" #include "Config.h"
#include "main.h" #include "main.h"
#include "EmuWindow.h" #include "EmuWindow.h"
namespace EmuWindow namespace EmuWindow
{ {
HWND m_hWnd = NULL; HWND m_hWnd = NULL;
HWND m_hParent = NULL; HWND m_hParent = NULL;
HINSTANCE m_hInstance = NULL; HINSTANCE m_hInstance = NULL;
WNDCLASSEX wndClass; WNDCLASSEX wndClass;
const TCHAR m_szClassName[] = "DolphinEmuWnd"; const TCHAR m_szClassName[] = "DolphinEmuWnd";
int g_winstyle; int g_winstyle;
HWND GetWnd() HWND GetWnd()
{ {
return m_hWnd; return m_hWnd;
} }
HWND GetParentWnd() HWND GetParentWnd()
{ {
return m_hParent; return m_hParent;
} }
LRESULT CALLBACK WndProc( HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam ) LRESULT CALLBACK WndProc( HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam )
{ {
HDC hdc; HDC hdc;
PAINTSTRUCT ps; PAINTSTRUCT ps;
switch( iMsg ) switch( iMsg )
{ {
case WM_PAINT: case WM_PAINT:
hdc = BeginPaint( hWnd, &ps ); hdc = BeginPaint( hWnd, &ps );
EndPaint( hWnd, &ps ); EndPaint( hWnd, &ps );
return 0; return 0;
case WM_KEYDOWN: case WM_KEYDOWN:
switch( LOWORD( wParam )) switch( LOWORD( wParam ))
{ {
case VK_ESCAPE: /* Pressing esc quits */ case VK_ESCAPE: /* Pressing esc quits */
//DestroyWindow(hWnd); //DestroyWindow(hWnd);
//PostQuitMessage(0); //PostQuitMessage(0);
break; break;
/* /*
case MY_KEYS: case MY_KEYS:
hypotheticalScene->sendMessage(KEYDOWN...); hypotheticalScene->sendMessage(KEYDOWN...);
*/ */
} }
g_VideoInitialize.pKeyPress(LOWORD(wParam), GetAsyncKeyState(VK_SHIFT) != 0, GetAsyncKeyState(VK_CONTROL) != 0); g_VideoInitialize.pKeyPress(LOWORD(wParam), GetAsyncKeyState(VK_SHIFT) != 0, GetAsyncKeyState(VK_CONTROL) != 0);
break; break;
case WM_CLOSE: case WM_CLOSE:
//Core::SetState(Core::CORE_UNINITIALIZED); //Core::SetState(Core::CORE_UNINITIALIZED);
return 0; return 0;
case WM_DESTROY: case WM_DESTROY:
//Shutdown(); //Shutdown();
//PostQuitMessage( 0 ); //PostQuitMessage( 0 );
break; break;
case WM_SIZE: case WM_SIZE:
// Reset the D3D Device here // Reset the D3D Device here
// Also make damn sure that this is not called from inside rendering a frame :P // Also make damn sure that this is not called from inside rendering a frame :P
break; break;
case WM_SYSCOMMAND: case WM_SYSCOMMAND:
switch (wParam) switch (wParam)
{ {
case SC_SCREENSAVE: case SC_SCREENSAVE:
case SC_MONITORPOWER: case SC_MONITORPOWER:
return 0; return 0;
} }
break; break;
} }
return DefWindowProc(hWnd, iMsg, wParam, lParam); return DefWindowProc(hWnd, iMsg, wParam, lParam);
} }
HWND OpenWindow(HWND parent, HINSTANCE hInstance, int width, int height, const TCHAR *title) HWND OpenWindow(HWND parent, HINSTANCE hInstance, int width, int height, const TCHAR *title)
{ {
wndClass.cbSize = sizeof( wndClass ); wndClass.cbSize = sizeof( wndClass );
wndClass.style = CS_HREDRAW | CS_VREDRAW; wndClass.style = CS_HREDRAW | CS_VREDRAW;
wndClass.lpfnWndProc = WndProc; wndClass.lpfnWndProc = WndProc;
wndClass.cbClsExtra = 0; wndClass.cbClsExtra = 0;
wndClass.cbWndExtra = 0; wndClass.cbWndExtra = 0;
wndClass.hInstance = hInstance; wndClass.hInstance = hInstance;
wndClass.hIcon = LoadIcon( NULL, IDI_APPLICATION ); wndClass.hIcon = LoadIcon( NULL, IDI_APPLICATION );
wndClass.hCursor = LoadCursor( NULL, IDC_ARROW ); wndClass.hCursor = LoadCursor( NULL, IDC_ARROW );
wndClass.hbrBackground = (HBRUSH)GetStockObject( BLACK_BRUSH ); wndClass.hbrBackground = (HBRUSH)GetStockObject( BLACK_BRUSH );
wndClass.lpszMenuName = NULL; wndClass.lpszMenuName = NULL;
wndClass.lpszClassName = m_szClassName; wndClass.lpszClassName = m_szClassName;
wndClass.hIconSm = LoadIcon( NULL, IDI_APPLICATION ); wndClass.hIconSm = LoadIcon( NULL, IDI_APPLICATION );
m_hInstance = hInstance; m_hInstance = hInstance;
RegisterClassEx( &wndClass ); RegisterClassEx( &wndClass );
if (parent) if (parent)
{ {
m_hWnd = CreateWindow(m_szClassName, title, m_hWnd = CreateWindow(m_szClassName, title,
WS_CHILD, WS_CHILD,
CW_USEDEFAULT, CW_USEDEFAULT,CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,CW_USEDEFAULT, CW_USEDEFAULT,
parent, NULL, hInstance, NULL ); parent, NULL, hInstance, NULL );
m_hParent = parent; m_hParent = parent;
ShowWindow(m_hWnd, SW_SHOWMAXIMIZED); ShowWindow(m_hWnd, SW_SHOWMAXIMIZED);
} }
else else
{ {
DWORD style = g_Config.bFullscreen ? WS_POPUP : WS_OVERLAPPEDWINDOW; DWORD style = g_Config.bFullscreen ? WS_POPUP : WS_OVERLAPPEDWINDOW;
RECT rc = {0, 0, width, height}; RECT rc = {0, 0, width, height};
AdjustWindowRect(&rc, style, false); AdjustWindowRect(&rc, style, false);
int w = rc.right - rc.left; int w = rc.right - rc.left;
int h = rc.bottom - rc.top; int h = rc.bottom - rc.top;
rc.left = (1280 - w)/2; rc.left = (1280 - w)/2;
rc.right = rc.left + w; rc.right = rc.left + w;
rc.top = (1024 - h)/2; rc.top = (1024 - h)/2;
rc.bottom = rc.top + h; rc.bottom = rc.top + h;
m_hWnd = CreateWindow(m_szClassName, title, m_hWnd = CreateWindow(m_szClassName, title,
style, style,
rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top,
parent, NULL, hInstance, NULL ); parent, NULL, hInstance, NULL );
g_winstyle = GetWindowLong( m_hWnd, GWL_STYLE ); g_winstyle = GetWindowLong( m_hWnd, GWL_STYLE );
g_winstyle &= ~WS_MAXIMIZE & ~WS_MINIMIZE; // remove minimize/maximize style g_winstyle &= ~WS_MAXIMIZE & ~WS_MINIMIZE; // remove minimize/maximize style
} }
return m_hWnd; return m_hWnd;
} }
void Show() void Show()
{ {
ShowWindow(m_hWnd, SW_SHOW); ShowWindow(m_hWnd, SW_SHOW);
BringWindowToTop(m_hWnd); BringWindowToTop(m_hWnd);
UpdateWindow(m_hWnd); UpdateWindow(m_hWnd);
} }
HWND Create(HWND hParent, HINSTANCE hInstance, const TCHAR *title) HWND Create(HWND hParent, HINSTANCE hInstance, const TCHAR *title)
{ {
return OpenWindow(hParent, hInstance, 640, 480, title); return OpenWindow(hParent, hInstance, 640, 480, title);
} }
void Close() void Close()
{ {
DestroyWindow(m_hWnd); DestroyWindow(m_hWnd);
UnregisterClass(m_szClassName, m_hInstance); UnregisterClass(m_szClassName, m_hInstance);
} }
void SetSize(int width, int height) void SetSize(int width, int height)
{ {
RECT rc = {0, 0, width, height}; RECT rc = {0, 0, width, height};
AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, false); AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, false);
int w = rc.right - rc.left; int w = rc.right - rc.left;
int h = rc.bottom - rc.top; int h = rc.bottom - rc.top;
rc.left = (1280 - w)/2; rc.left = (1280 - w)/2;
rc.right = rc.left + w; rc.right = rc.left + w;
rc.top = (1024 - h)/2; rc.top = (1024 - h)/2;
rc.bottom = rc.top + h; rc.bottom = rc.top + h;
::MoveWindow(m_hWnd, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, TRUE); ::MoveWindow(m_hWnd, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, TRUE);
} }
} }

View File

@ -1,130 +1,130 @@
// 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 "stdafx.h" #include "stdafx.h"
#include "IndexGenerator.h" #include "IndexGenerator.h"
/* /*
* *
QUAD simulator QUAD simulator
0 2 4 6 0 2 4 6
1 3 5 7 1 3 5 7
021231 243453 021231 243453
*/ */
void IndexGenerator::Start(unsigned short *startptr) void IndexGenerator::Start(unsigned short *startptr)
{ {
ptr=startptr; ptr=startptr;
index=0; index=0;
numPrims=0; numPrims=0;
} }
void IndexGenerator::AddList(int numVerts) void IndexGenerator::AddList(int numVerts)
{ {
int numTris = numVerts/3; int numTris = numVerts/3;
if (numTris<=0) return; if (numTris<=0) return;
for (int i=0; i<numTris; i++) for (int i=0; i<numTris; i++)
{ {
*ptr++ = index+i*3; *ptr++ = index+i*3;
*ptr++ = index+i*3+1; *ptr++ = index+i*3+1;
*ptr++ = index+i*3+2; *ptr++ = index+i*3+2;
} }
index += numVerts; index += numVerts;
numPrims += numTris; numPrims += numTris;
} }
void IndexGenerator::AddStrip(int numVerts) void IndexGenerator::AddStrip(int numVerts)
{ {
int numTris = numVerts-2; int numTris = numVerts-2;
if (numTris<=0) return; if (numTris<=0) return;
bool wind = false; bool wind = false;
for (int i=0; i<numTris; i++) for (int i=0; i<numTris; i++)
{ {
*ptr++ = index+i; *ptr++ = index+i;
*ptr++ = index+i+(wind?2:1); *ptr++ = index+i+(wind?2:1);
*ptr++ = index+i+(wind?1:2); *ptr++ = index+i+(wind?1:2);
wind = !wind; wind = !wind;
} }
index += numVerts; index += numVerts;
numPrims += numTris; numPrims += numTris;
} }
void IndexGenerator::AddLineList(int numVerts) void IndexGenerator::AddLineList(int numVerts)
{ {
int numLines= numVerts/2; int numLines= numVerts/2;
if (numLines<=0) return; if (numLines<=0) return;
for (int i=0; i<numLines; i++) for (int i=0; i<numLines; i++)
{ {
*ptr++ = index+i*2; *ptr++ = index+i*2;
*ptr++ = index+i*2+1; *ptr++ = index+i*2+1;
} }
index += numVerts; index += numVerts;
numPrims += numLines; numPrims += numLines;
} }
void IndexGenerator::AddLineStrip(int numVerts) void IndexGenerator::AddLineStrip(int numVerts)
{ {
int numLines = numVerts-1; int numLines = numVerts-1;
if (numLines<=0) return; if (numLines<=0) return;
for (int i=0; i<numLines; i++) for (int i=0; i<numLines; i++)
{ {
*ptr++ = index+i; *ptr++ = index+i;
*ptr++ = index+i+1; *ptr++ = index+i+1;
} }
index += numVerts; index += numVerts;
numPrims += numLines; numPrims += numLines;
} }
void IndexGenerator::AddFan(int numVerts) void IndexGenerator::AddFan(int numVerts)
{ {
int numTris = numVerts-2; int numTris = numVerts-2;
if (numTris<=0) return; if (numTris<=0) return;
for (int i=0; i<numTris; i++) for (int i=0; i<numTris; i++)
{ {
*ptr++ = index; *ptr++ = index;
*ptr++ = index+i+1; *ptr++ = index+i+1;
*ptr++ = index+i+2; *ptr++ = index+i+2;
} }
index += numVerts; index += numVerts;
numPrims += numTris; numPrims += numTris;
} }
void IndexGenerator::AddQuads(int numVerts) void IndexGenerator::AddQuads(int numVerts)
{ {
int numTris = (numVerts/4)*2; int numTris = (numVerts/4)*2;
if (numTris<=0) return; if (numTris<=0) return;
for (int i=0; i<numTris/2; i++) for (int i=0; i<numTris/2; i++)
{ {
*ptr++=index+i*4; *ptr++=index+i*4;
*ptr++=index+i*4+1; *ptr++=index+i*4+1;
*ptr++=index+i*4+3; *ptr++=index+i*4+3;
*ptr++=index+i*4+1; *ptr++=index+i*4+1;
*ptr++=index+i*4+2; *ptr++=index+i*4+2;
*ptr++=index+i*4+3; *ptr++=index+i*4+3;
} }
index += numVerts; index += numVerts;
numPrims += numTris; numPrims += numTris;
} }
void IndexGenerator::AddPointList(int numVerts) void IndexGenerator::AddPointList(int numVerts)
{ {
index += numVerts; index += numVerts;
} }

View File

@ -1,354 +1,354 @@
// 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/
//DL facts: //DL facts:
// Ikaruga uses (nearly) NO display lists! // Ikaruga uses (nearly) NO display lists!
// Zelda WW uses TONS of display lists // Zelda WW uses TONS of display lists
// Zelda TP uses almost 100% display lists except menus (we like this!) // Zelda TP uses almost 100% display lists except menus (we like this!)
// Note that it IS NOT GENERALLY POSSIBLE to precompile display lists! You can compile them as they are // Note that it IS NOT GENERALLY POSSIBLE to precompile display lists! You can compile them as they are
// and hope that the vertex format doesn't change, though, if you do it just when they are // and hope that the vertex format doesn't change, though, if you do it just when they are
// called. The reason is that the vertex format affects the sizes of the vertices. // called. The reason is that the vertex format affects the sizes of the vertices.
#include "D3DBase.h" #include "D3DBase.h"
#include "Common.h" #include "Common.h"
#include "Statistics.h" #include "Statistics.h"
#include "Profiler.h" #include "Profiler.h"
#include "VertexManager.h" #include "VertexManager.h"
#include "TransformEngine.h" #include "TransformEngine.h"
#include "OpcodeDecoding.h" #include "OpcodeDecoding.h"
#include "TextureCache.h" #include "TextureCache.h"
#include "ShaderManager.h" #include "ShaderManager.h"
#include "BPStructs.h" #include "BPStructs.h"
#include "XFStructs.h" #include "XFStructs.h"
#include "Utils.h" #include "Utils.h"
#include "Fifo.h" #include "Fifo.h"
#include "DataReader.h" #include "DataReader.h"
DecodedVArray tempvarray; DecodedVArray tempvarray;
u8 *g_pVideoData = 0; u8 *g_pVideoData = 0;
extern u8* FAKE_GetFifoStartPtr(); extern u8* FAKE_GetFifoStartPtr();
extern u8* FAKE_GetFifoEndPtr(); extern u8* FAKE_GetFifoEndPtr();
static void Decode(); static void Decode();
static void ExecuteDisplayList(u32 address, u32 size) static void ExecuteDisplayList(u32 address, u32 size)
{ {
u8* old_pVideoData = g_pVideoData; u8* old_pVideoData = g_pVideoData;
u8* startAddress = Memory_GetPtr(address); u8* startAddress = Memory_GetPtr(address);
//Avoid the crash if Memory_GetPtr failed .. //Avoid the crash if Memory_GetPtr failed ..
if (startAddress!=0) if (startAddress!=0)
{ {
g_pVideoData = startAddress; g_pVideoData = startAddress;
// temporarily swap dl and non-dl(small "hack" for the stats) // temporarily swap dl and non-dl(small "hack" for the stats)
Statistics::SwapDL(); Statistics::SwapDL();
while((u32)(g_pVideoData - startAddress) < size) while((u32)(g_pVideoData - startAddress) < size)
{ {
Decode(); Decode();
} }
INCSTAT(stats.numDListsCalled); INCSTAT(stats.numDListsCalled);
INCSTAT(stats.thisFrame.numDListsCalled); INCSTAT(stats.thisFrame.numDListsCalled);
// un-swap // un-swap
Statistics::SwapDL(); Statistics::SwapDL();
// reset to the old pointer // reset to the old pointer
g_pVideoData = old_pVideoData; g_pVideoData = old_pVideoData;
} }
} }
bool FifoCommandRunnable() bool FifoCommandRunnable()
{ {
u32 iBufferSize = (u32)(FAKE_GetFifoEndPtr()-g_pVideoData); u32 iBufferSize = (u32)(FAKE_GetFifoEndPtr()-g_pVideoData);
if (iBufferSize == 0) if (iBufferSize == 0)
return false; // can't peek return false; // can't peek
u8 Cmd = DataPeek8(0); u8 Cmd = DataPeek8(0);
u32 iCommandSize = 0; u32 iCommandSize = 0;
switch(Cmd) switch(Cmd)
{ {
case GX_NOP: case GX_NOP:
// Hm, this means that we scan over nop streams pretty slowly... // Hm, this means that we scan over nop streams pretty slowly...
iCommandSize = 1; iCommandSize = 1;
break; break;
case GX_LOAD_CP_REG: case GX_LOAD_CP_REG:
iCommandSize = 6; iCommandSize = 6;
break; break;
case GX_LOAD_INDX_A: case GX_LOAD_INDX_A:
case GX_LOAD_INDX_B: case GX_LOAD_INDX_B:
case GX_LOAD_INDX_C: case GX_LOAD_INDX_C:
case GX_LOAD_INDX_D: case GX_LOAD_INDX_D:
iCommandSize = 5; iCommandSize = 5;
break; break;
case GX_CMD_CALL_DL: case GX_CMD_CALL_DL:
iCommandSize = 9; iCommandSize = 9;
break; break;
case 0x44: case 0x44:
iCommandSize = 1; iCommandSize = 1;
// zelda 4 swords calls it and checks the metrics registers after that // zelda 4 swords calls it and checks the metrics registers after that
break; break;
case GX_CMD_INVL_VC: // invalid vertex cache - no parameter? case GX_CMD_INVL_VC: // invalid vertex cache - no parameter?
iCommandSize = 1; iCommandSize = 1;
break; break;
case GX_LOAD_BP_REG: case GX_LOAD_BP_REG:
iCommandSize = 5; iCommandSize = 5;
break; break;
case GX_LOAD_XF_REG: case GX_LOAD_XF_REG:
{ {
// check if we can read the header // check if we can read the header
if (iBufferSize >= 5) if (iBufferSize >= 5)
{ {
iCommandSize = 1 + 4; iCommandSize = 1 + 4;
u32 Cmd2 = DataPeek32(1); u32 Cmd2 = DataPeek32(1);
int dwTransferSize = ((Cmd2 >> 16) & 15) + 1; int dwTransferSize = ((Cmd2 >> 16) & 15) + 1;
iCommandSize += dwTransferSize * 4; iCommandSize += dwTransferSize * 4;
} }
else else
{ {
return false; return false;
} }
} }
break; break;
default: default:
if (Cmd&0x80) if (Cmd&0x80)
{ {
// check if we can read the header // check if we can read the header
if (iBufferSize >= 3) if (iBufferSize >= 3)
{ {
iCommandSize = 1 + 2; iCommandSize = 1 + 2;
u16 numVertices = DataPeek16(1); u16 numVertices = DataPeek16(1);
VertexLoader& vtxLoader = g_VertexLoaders[Cmd & GX_VAT_MASK]; VertexLoader& vtxLoader = g_VertexLoaders[Cmd & GX_VAT_MASK];
vtxLoader.Setup(); vtxLoader.Setup();
int vsize = vtxLoader.GetVertexSize(); int vsize = vtxLoader.GetVertexSize();
iCommandSize += numVertices * vsize; iCommandSize += numVertices * vsize;
} }
else else
{ {
return false; return false;
} }
} }
else else
{ {
char szTemp[1024]; char szTemp[1024];
sprintf(szTemp, "GFX: Unknown Opcode (0x%x).\n" sprintf(szTemp, "GFX: Unknown Opcode (0x%x).\n"
"This means one of the following:\n" "This means one of the following:\n"
"* The emulated GPU got desynced, disabling dual core can help\n" "* The emulated GPU got desynced, disabling dual core can help\n"
"* Command stream corrupted by some spurious memory bug\n" "* Command stream corrupted by some spurious memory bug\n"
"* This really is an unknown opcode (unlikely)\n\n" "* This really is an unknown opcode (unlikely)\n\n"
"* Some other sort of bug\n\n" "* Some other sort of bug\n\n"
"Dolphin will now likely crash or hang. Enjoy.", Cmd); "Dolphin will now likely crash or hang. Enjoy.", Cmd);
MessageBox(NULL, szTemp, "Video-Plugin", MB_OK); MessageBox(NULL, szTemp, "Video-Plugin", MB_OK);
g_VideoInitialize.pLog(szTemp, TRUE); g_VideoInitialize.pLog(szTemp, TRUE);
{ {
SCPFifoStruct &fifo = *g_VideoInitialize.pCPFifo; SCPFifoStruct &fifo = *g_VideoInitialize.pCPFifo;
char szTmp[256]; char szTmp[256];
// sprintf(szTmp, "Illegal command %02x (at %08x)",Cmd,g_pDataReader->GetPtr()); // sprintf(szTmp, "Illegal command %02x (at %08x)",Cmd,g_pDataReader->GetPtr());
sprintf(szTmp, "Illegal command %02x\n" sprintf(szTmp, "Illegal command %02x\n"
"CPBase: 0x%08x\n" "CPBase: 0x%08x\n"
"CPEnd: 0x%08x\n" "CPEnd: 0x%08x\n"
"CPHiWatermark: 0x%08x\n" "CPHiWatermark: 0x%08x\n"
"CPLoWatermark: 0x%08x\n" "CPLoWatermark: 0x%08x\n"
"CPReadWriteDistance: 0x%08x\n" "CPReadWriteDistance: 0x%08x\n"
"CPWritePointer: 0x%08x\n" "CPWritePointer: 0x%08x\n"
"CPReadPointer: 0x%08x\n" "CPReadPointer: 0x%08x\n"
"CPBreakpoint: 0x%08x\n" "CPBreakpoint: 0x%08x\n"
"bFF_GPReadEnable: %s\n" "bFF_GPReadEnable: %s\n"
"bFF_BPEnable: %s\n" "bFF_BPEnable: %s\n"
"bFF_GPLinkEnable: %s\n" "bFF_GPLinkEnable: %s\n"
"bFF_Breakpoint: %s\n" "bFF_Breakpoint: %s\n"
,Cmd, fifo.CPBase, fifo.CPEnd, fifo.CPHiWatermark, fifo.CPLoWatermark, fifo.CPReadWriteDistance ,Cmd, fifo.CPBase, fifo.CPEnd, fifo.CPHiWatermark, fifo.CPLoWatermark, fifo.CPReadWriteDistance
,fifo.CPWritePointer, fifo.CPReadPointer, fifo.CPBreakpoint, fifo.bFF_GPReadEnable ? "true" : "false" ,fifo.CPWritePointer, fifo.CPReadPointer, fifo.CPBreakpoint, fifo.bFF_GPReadEnable ? "true" : "false"
,fifo.bFF_BPEnable ? "true" : "false" ,fifo.bFF_GPLinkEnable ? "true" : "false" ,fifo.bFF_BPEnable ? "true" : "false" ,fifo.bFF_GPLinkEnable ? "true" : "false"
,fifo.bFF_Breakpoint ? "true" : "false"); ,fifo.bFF_Breakpoint ? "true" : "false");
g_VideoInitialize.pLog(szTmp, TRUE); g_VideoInitialize.pLog(szTmp, TRUE);
MessageBox(0,szTmp,"GFX ERROR",0); MessageBox(0,szTmp,"GFX ERROR",0);
// _assert_msg_(0,szTmp,""); // _assert_msg_(0,szTmp,"");
} }
} }
break; break;
} }
if (iCommandSize > iBufferSize) if (iCommandSize > iBufferSize)
return false; return false;
#ifdef _DEBUG #ifdef _DEBUG
char temp[256]; char temp[256];
sprintf(temp, "OP detected: Cmd 0x%x size %i buffer %i",Cmd, iCommandSize, iBufferSize); sprintf(temp, "OP detected: Cmd 0x%x size %i buffer %i",Cmd, iCommandSize, iBufferSize);
g_VideoInitialize.pLog(temp, FALSE); g_VideoInitialize.pLog(temp, FALSE);
#endif #endif
return true; return true;
} }
static void Decode(void) static void Decode(void)
{ {
int Cmd = DataReadU8(); int Cmd = DataReadU8();
switch (Cmd) switch (Cmd)
{ {
case GX_NOP: case GX_NOP:
break; break;
case GX_LOAD_CP_REG: case GX_LOAD_CP_REG:
{ {
u32 SubCmd = DataReadU8(); u32 SubCmd = DataReadU8();
u32 Value = DataReadU32(); u32 Value = DataReadU32();
LoadCPReg(SubCmd,Value); LoadCPReg(SubCmd,Value);
} }
break; break;
case GX_LOAD_XF_REG: case GX_LOAD_XF_REG:
{ {
u32 Cmd2 = DataReadU32(); u32 Cmd2 = DataReadU32();
int dwTransferSize = ((Cmd2>>16)&15) + 1; int dwTransferSize = ((Cmd2>>16)&15) + 1;
u32 dwAddress = Cmd2 & 0xFFFF; u32 dwAddress = Cmd2 & 0xFFFF;
static u32 pData[16]; static u32 pData[16];
for (int i=0; i<dwTransferSize; i++) for (int i=0; i<dwTransferSize; i++)
pData[i] = DataReadU32(); pData[i] = DataReadU32();
LoadXFReg(dwTransferSize,dwAddress,pData); LoadXFReg(dwTransferSize,dwAddress,pData);
} }
break; break;
case GX_LOAD_INDX_A: //used for position matrices case GX_LOAD_INDX_A: //used for position matrices
LoadIndexedXF(DataReadU32(),0xC); LoadIndexedXF(DataReadU32(),0xC);
break; break;
case GX_LOAD_INDX_B: //used for normal matrices case GX_LOAD_INDX_B: //used for normal matrices
LoadIndexedXF(DataReadU32(),0xD); LoadIndexedXF(DataReadU32(),0xD);
break; break;
case GX_LOAD_INDX_C: //used for postmatrices case GX_LOAD_INDX_C: //used for postmatrices
LoadIndexedXF(DataReadU32(),0xE); LoadIndexedXF(DataReadU32(),0xE);
break; break;
case GX_LOAD_INDX_D: //used for lights case GX_LOAD_INDX_D: //used for lights
LoadIndexedXF(DataReadU32(),0xF); LoadIndexedXF(DataReadU32(),0xF);
break; break;
case GX_CMD_CALL_DL: case GX_CMD_CALL_DL:
{ {
u32 dwAddr = DataReadU32(); u32 dwAddr = DataReadU32();
u32 dwCount = DataReadU32(); u32 dwCount = DataReadU32();
ExecuteDisplayList(dwAddr, dwCount); ExecuteDisplayList(dwAddr, dwCount);
} }
break; break;
case 0x44: case 0x44:
// zelda 4 swords calls it and checks the metrics registers after that // zelda 4 swords calls it and checks the metrics registers after that
break; break;
case GX_CMD_INVL_VC:// Invalidate (vertex cache?) case GX_CMD_INVL_VC:// Invalidate (vertex cache?)
DebugLog("Invalidate (vertex cache?)"); DebugLog("Invalidate (vertex cache?)");
break; break;
case GX_LOAD_BP_REG: //0x61 case GX_LOAD_BP_REG: //0x61
{ {
u32 cmd = DataReadU32(); u32 cmd = DataReadU32();
LoadBPReg(cmd); LoadBPReg(cmd);
} }
break; break;
// draw primitives // draw primitives
default: default:
if (Cmd&0x80) if (Cmd&0x80)
{ {
// load vertices // load vertices
u16 numVertices = DataReadU16(); u16 numVertices = DataReadU16();
tempvarray.Reset(); tempvarray.Reset();
VertexLoader::SetVArray(&tempvarray); VertexLoader::SetVArray(&tempvarray);
VertexLoader& vtxLoader = g_VertexLoaders[Cmd & GX_VAT_MASK]; VertexLoader& vtxLoader = g_VertexLoaders[Cmd & GX_VAT_MASK];
vtxLoader.Setup(); vtxLoader.Setup();
vtxLoader.PrepareRun(); vtxLoader.PrepareRun();
int vsize = vtxLoader.GetVertexSize(); int vsize = vtxLoader.GetVertexSize();
vtxLoader.RunVertices(numVertices); vtxLoader.RunVertices(numVertices);
// add vertices // add vertices
int primitive = (Cmd & GX_PRIMITIVE_MASK) >> GX_PRIMITIVE_SHIFT; int primitive = (Cmd & GX_PRIMITIVE_MASK) >> GX_PRIMITIVE_SHIFT;
VertexManager::AddVertices(primitive, numVertices, &tempvarray); VertexManager::AddVertices(primitive, numVertices, &tempvarray);
} }
else else
{ {
SCPFifoStruct &fifo = *g_VideoInitialize.pCPFifo; SCPFifoStruct &fifo = *g_VideoInitialize.pCPFifo;
char szTmp[256]; char szTmp[256];
// sprintf(szTmp, "Illegal command %02x (at %08x)",Cmd,g_pDataReader->GetPtr()); // sprintf(szTmp, "Illegal command %02x (at %08x)",Cmd,g_pDataReader->GetPtr());
sprintf(szTmp, "Illegal command %02x\n" sprintf(szTmp, "Illegal command %02x\n"
"CPBase: 0x%08x\n" "CPBase: 0x%08x\n"
"CPEnd: 0x%08x\n" "CPEnd: 0x%08x\n"
"CPHiWatermark: 0x%08x\n" "CPHiWatermark: 0x%08x\n"
"CPLoWatermark: 0x%08x\n" "CPLoWatermark: 0x%08x\n"
"CPReadWriteDistance: 0x%08x\n" "CPReadWriteDistance: 0x%08x\n"
"CPWritePointer: 0x%08x\n" "CPWritePointer: 0x%08x\n"
"CPReadPointer: 0x%08x\n" "CPReadPointer: 0x%08x\n"
"CPBreakpoint: 0x%08x\n" "CPBreakpoint: 0x%08x\n"
"bFF_GPReadEnable: %s\n" "bFF_GPReadEnable: %s\n"
"bFF_BPEnable: %s\n" "bFF_BPEnable: %s\n"
"bFF_GPLinkEnable: %s\n" "bFF_GPLinkEnable: %s\n"
"bFF_Breakpoint: %s\n" "bFF_Breakpoint: %s\n"
,Cmd, fifo.CPBase, fifo.CPEnd, fifo.CPHiWatermark, fifo.CPLoWatermark, fifo.CPReadWriteDistance ,Cmd, fifo.CPBase, fifo.CPEnd, fifo.CPHiWatermark, fifo.CPLoWatermark, fifo.CPReadWriteDistance
,fifo.CPWritePointer, fifo.CPReadPointer, fifo.CPBreakpoint, fifo.bFF_GPReadEnable ? "true" : "false" ,fifo.CPWritePointer, fifo.CPReadPointer, fifo.CPBreakpoint, fifo.bFF_GPReadEnable ? "true" : "false"
,fifo.bFF_BPEnable ? "true" : "false" ,fifo.bFF_GPLinkEnable ? "true" : "false" ,fifo.bFF_BPEnable ? "true" : "false" ,fifo.bFF_GPLinkEnable ? "true" : "false"
,fifo.bFF_Breakpoint ? "true" : "false"); ,fifo.bFF_Breakpoint ? "true" : "false");
g_VideoInitialize.pLog(szTmp, TRUE); g_VideoInitialize.pLog(szTmp, TRUE);
MessageBox(0,szTmp,"GFX ERROR",0); MessageBox(0,szTmp,"GFX ERROR",0);
// _assert_msg_(0,szTmp,""); // _assert_msg_(0,szTmp,"");
break; break;
} }
break; break;
} }
} }
void OpcodeDecoder_Init() void OpcodeDecoder_Init()
{ {
g_pVideoData = FAKE_GetFifoStartPtr(); g_pVideoData = FAKE_GetFifoStartPtr();
tempvarray.Create(65536*3, 1, 8, 3, 2, 8); tempvarray.Create(65536*3, 1, 8, 3, 2, 8);
} }
void OpcodeDecoder_Shutdown() void OpcodeDecoder_Shutdown()
{ {
//VirtualFree((LPVOID)buffer,0,MEM_RELEASE); //VirtualFree((LPVOID)buffer,0,MEM_RELEASE);
tempvarray.Destroy(); tempvarray.Destroy();
} }
void OpcodeDecoder_Run() void OpcodeDecoder_Run()
{ {
DVSTARTPROFILE(); DVSTARTPROFILE();
while (FifoCommandRunnable()) while (FifoCommandRunnable())
{ {
Decode(); Decode();
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,451 +1,451 @@
// 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 <d3dx9.h> #include <d3dx9.h>
#include "Common.h" #include "Common.h"
#include "Statistics.h" #include "Statistics.h"
#include "Config.h" #include "Config.h"
#include "main.h" #include "main.h"
#include "VertexManager.h" #include "VertexManager.h"
#include "Render.h" #include "Render.h"
#include "OpcodeDecoding.h" #include "OpcodeDecoding.h"
#include "BPStructs.h" #include "BPStructs.h"
#include "XFStructs.h" #include "XFStructs.h"
#include "D3DPostprocess.h" #include "D3DPostprocess.h"
#include "D3DUtil.h" #include "D3DUtil.h"
#include "ShaderManager.h" #include "ShaderManager.h"
#include "TextureCache.h" #include "TextureCache.h"
#include "Utils.h" #include "Utils.h"
#include "EmuWindow.h" #include "EmuWindow.h"
#include <list> #include <list>
float Renderer::m_x,Renderer::m_y,Renderer::m_width, Renderer::m_height, Renderer::xScale,Renderer::yScale; float Renderer::m_x,Renderer::m_y,Renderer::m_width, Renderer::m_height, Renderer::xScale,Renderer::yScale;
std::vector<LPDIRECT3DBASETEXTURE9> Renderer::m_Textures; std::vector<LPDIRECT3DBASETEXTURE9> Renderer::m_Textures;
DWORD Renderer::m_RenderStates[MaxRenderStates]; DWORD Renderer::m_RenderStates[MaxRenderStates];
DWORD Renderer::m_TextureStageStates[MaxTextureStages][MaxTextureTypes]; DWORD Renderer::m_TextureStageStates[MaxTextureStages][MaxTextureTypes];
DWORD Renderer::m_SamplerStates[MaxSamplerSize][MaxSamplerTypes]; DWORD Renderer::m_SamplerStates[MaxSamplerSize][MaxSamplerTypes];
DWORD Renderer::m_FVF; DWORD Renderer::m_FVF;
#define NUMWNDRES 6 #define NUMWNDRES 6
extern int g_Res[NUMWNDRES][2]; extern int g_Res[NUMWNDRES][2];
struct Message struct Message
{ {
Message(const std::string &msg, u32 dw) : message( msg ), dwTimeStamp( dw ) Message(const std::string &msg, u32 dw) : message( msg ), dwTimeStamp( dw )
{ {
} }
std::string message; std::string message;
u32 dwTimeStamp; u32 dwTimeStamp;
}; };
static std::list<Message> s_listMsgs; static std::list<Message> s_listMsgs;
void Renderer::Init(SVideoInitialize &_VideoInitialize) void Renderer::Init(SVideoInitialize &_VideoInitialize)
{ {
EmuWindow::SetSize(g_Res[g_Config.iWindowedRes][0], g_Res[g_Config.iWindowedRes][1]); EmuWindow::SetSize(g_Res[g_Config.iWindowedRes][0], g_Res[g_Config.iWindowedRes][1]);
D3D::Create(g_Config.iAdapter, EmuWindow::GetWnd(), g_Config.bFullscreen, g_Config.iFSResolution, g_Config.iMultisampleMode); D3D::Create(g_Config.iAdapter, EmuWindow::GetWnd(), g_Config.bFullscreen, g_Config.iFSResolution, g_Config.iMultisampleMode);
D3DVIEWPORT9 vp; D3DVIEWPORT9 vp;
D3D::dev->GetViewport(&vp); D3D::dev->GetViewport(&vp);
m_x = 0; m_x = 0;
m_y = 0; m_y = 0;
m_width = (float)vp.Width; m_width = (float)vp.Width;
m_height = (float)vp.Height; m_height = (float)vp.Height;
xScale = 640.0f / (float)vp.Width; xScale = 640.0f / (float)vp.Width;
yScale = 480.0f / (float)vp.Height; yScale = 480.0f / (float)vp.Height;
D3D::font.Init(); D3D::font.Init();
Initialize(); Initialize();
} }
void Renderer::Shutdown(void) void Renderer::Shutdown(void)
{ {
D3D::font.Shutdown(); D3D::font.Shutdown();
D3D::EndFrame(); D3D::EndFrame();
D3D::Close(); D3D::Close();
} }
void Renderer::Initialize(void) void Renderer::Initialize(void)
{ {
m_FVF = 0; m_FVF = 0;
m_Textures.reserve( MaxTextureStages ); m_Textures.reserve( MaxTextureStages );
for ( int i = 0; i < MaxTextureStages; i++ ) for ( int i = 0; i < MaxTextureStages; i++ )
{ {
m_Textures.push_back( NULL ); m_Textures.push_back( NULL );
} }
for (int i=0; i<8; i++) for (int i=0; i<8; i++)
{ {
D3D::dev->SetSamplerState(i, D3DSAMP_MAXANISOTROPY, 16); D3D::dev->SetSamplerState(i, D3DSAMP_MAXANISOTROPY, 16);
} }
ReinitView(); ReinitView();
Postprocess::Initialize(); Postprocess::Initialize();
Postprocess::BeginFrame(); Postprocess::BeginFrame();
D3D::BeginFrame(true, 0); D3D::BeginFrame(true, 0);
VertexManager::BeginFrame(); VertexManager::BeginFrame();
} }
void Renderer::AddMessage(const std::string &message, u32 ms) void Renderer::AddMessage(const std::string &message, u32 ms)
{ {
s_listMsgs.push_back(Message(message, timeGetTime()+ms)); s_listMsgs.push_back(Message(message, timeGetTime()+ms));
} }
void Renderer::ProcessMessages() void Renderer::ProcessMessages()
{ {
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;
RenderText(it->message, left+1, top+1, 0x000000|alpha); RenderText(it->message, left+1, top+1, 0x000000|alpha);
RenderText(it->message, left, top, 0xffff30|alpha); RenderText(it->message, 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 ++it; else ++it;
} }
} }
} }
void Renderer::RenderText(const std::string &text, int left, int top, u32 color) void Renderer::RenderText(const std::string &text, int left, int top, u32 color)
{ {
D3D::font.DrawTextScaled((float)left, (float)top, 20, 20, 0.0f, color, text.c_str(), false); D3D::font.DrawTextScaled((float)left, (float)top, 20, 20, 0.0f, color, text.c_str(), false);
} }
void dumpMatrix(D3DXMATRIX &mtx) void dumpMatrix(D3DXMATRIX &mtx)
{ {
for (int y=0; y<4; y++) for (int y=0; y<4; y++)
{ {
char temp[256]; char temp[256];
sprintf(temp,"%4.4f %4.4f %4.4f %4.4f",mtx.m[y][0],mtx.m[y][1],mtx.m[y][2],mtx.m[y][3]); sprintf(temp,"%4.4f %4.4f %4.4f %4.4f",mtx.m[y][0],mtx.m[y][1],mtx.m[y][2],mtx.m[y][3]);
g_VideoInitialize.pLog(temp, FALSE); g_VideoInitialize.pLog(temp, FALSE);
} }
} }
void Renderer::ReinitView() void Renderer::ReinitView()
{ {
D3DXMATRIX mtx; D3DXMATRIX mtx;
D3DXMatrixIdentity(&mtx); D3DXMatrixIdentity(&mtx);
D3D::dev->SetTransform(D3DTS_VIEW,&mtx); D3D::dev->SetTransform(D3DTS_VIEW,&mtx);
D3D::dev->SetTransform(D3DTS_WORLD,&mtx); D3D::dev->SetTransform(D3DTS_WORLD,&mtx);
float width = (float)D3D::GetDisplayWidth(); float width = (float)D3D::GetDisplayWidth();
float height = (float)D3D::GetDisplayHeight(); float height = (float)D3D::GetDisplayHeight();
xScale = width/640.0f; xScale = width/640.0f;
yScale = height/480.0f; yScale = height/480.0f;
RECT rc = { RECT rc = {
(LONG)(m_x*xScale), (LONG)(m_y*yScale), (LONG)(m_width*xScale), (LONG)(m_height*yScale) (LONG)(m_x*xScale), (LONG)(m_y*yScale), (LONG)(m_width*xScale), (LONG)(m_height*yScale)
}; };
} }
void Renderer::SwapBuffers(void) void Renderer::SwapBuffers(void)
{ {
// center window again // center window again
if (EmuWindow::GetParentWnd()) if (EmuWindow::GetParentWnd())
{ {
RECT rcWindow; RECT rcWindow;
GetWindowRect(EmuWindow::GetParentWnd(), &rcWindow); GetWindowRect(EmuWindow::GetParentWnd(), &rcWindow);
int width = rcWindow.right - rcWindow.left; int width = rcWindow.right - rcWindow.left;
int height = rcWindow.bottom - rcWindow.top; int height = rcWindow.bottom - rcWindow.top;
::MoveWindow(EmuWindow::GetWnd(), 0,0,width,height, FALSE); ::MoveWindow(EmuWindow::GetWnd(), 0,0,width,height, FALSE);
// nBackbufferWidth = width; // nBackbufferWidth = width;
// nBackbufferHeight = height; // nBackbufferHeight = height;
} }
//Finish up the current frame, print some stats //Finish up the current frame, print some stats
Postprocess::FinalizeFrame(); Postprocess::FinalizeFrame();
if (g_Config.bOverlayStats) if (g_Config.bOverlayStats)
{ {
char st[2048]; char st[2048];
char *p = st; char *p = st;
p+=sprintf(p,"Num textures created: %i\n",stats.numTexturesCreated); p+=sprintf(p,"Num textures created: %i\n",stats.numTexturesCreated);
p+=sprintf(p,"Num textures alive: %i\n",stats.numTexturesAlive); p+=sprintf(p,"Num textures alive: %i\n",stats.numTexturesAlive);
p+=sprintf(p,"Num pshaders created: %i\n",stats.numPixelShadersCreated); p+=sprintf(p,"Num pshaders created: %i\n",stats.numPixelShadersCreated);
p+=sprintf(p,"Num pshaders alive: %i\n",stats.numPixelShadersAlive); p+=sprintf(p,"Num pshaders alive: %i\n",stats.numPixelShadersAlive);
p+=sprintf(p,"Num vshaders created: %i\n",stats.numVertexShadersCreated); p+=sprintf(p,"Num vshaders created: %i\n",stats.numVertexShadersCreated);
p+=sprintf(p,"Num vshaders alive: %i\n",stats.numVertexShadersAlive); p+=sprintf(p,"Num vshaders alive: %i\n",stats.numVertexShadersAlive);
p+=sprintf(p,"Num dlists called: %i\n",stats.numDListsCalled); p+=sprintf(p,"Num dlists called: %i\n",stats.numDListsCalled);
p+=sprintf(p,"Num dlists created: %i\n",stats.numDListsCreated); p+=sprintf(p,"Num dlists created: %i\n",stats.numDListsCreated);
p+=sprintf(p,"Num dlists alive: %i\n",stats.numDListsAlive); p+=sprintf(p,"Num dlists alive: %i\n",stats.numDListsAlive);
p+=sprintf(p,"Num primitives: %i\n",stats.thisFrame.numPrims); p+=sprintf(p,"Num primitives: %i\n",stats.thisFrame.numPrims);
p+=sprintf(p,"Num primitive joins: %i\n",stats.thisFrame.numPrimitiveJoins); p+=sprintf(p,"Num primitive joins: %i\n",stats.thisFrame.numPrimitiveJoins);
p+=sprintf(p,"Num primitives (DL): %i\n",stats.thisFrame.numDLPrims); p+=sprintf(p,"Num primitives (DL): %i\n",stats.thisFrame.numDLPrims);
p+=sprintf(p,"Num XF loads: %i\n",stats.thisFrame.numXFLoads); p+=sprintf(p,"Num XF loads: %i\n",stats.thisFrame.numXFLoads);
p+=sprintf(p,"Num XF loads (DL): %i\n",stats.thisFrame.numXFLoadsInDL); p+=sprintf(p,"Num XF loads (DL): %i\n",stats.thisFrame.numXFLoadsInDL);
p+=sprintf(p,"Num CP loads: %i\n",stats.thisFrame.numCPLoads); p+=sprintf(p,"Num CP loads: %i\n",stats.thisFrame.numCPLoads);
p+=sprintf(p,"Num CP loads (DL): %i\n",stats.thisFrame.numCPLoadsInDL); p+=sprintf(p,"Num CP loads (DL): %i\n",stats.thisFrame.numCPLoadsInDL);
p+=sprintf(p,"Num BP loads: %i\n",stats.thisFrame.numBPLoads); p+=sprintf(p,"Num BP loads: %i\n",stats.thisFrame.numBPLoads);
p+=sprintf(p,"Num BP loads (DL): %i\n",stats.thisFrame.numBPLoadsInDL); p+=sprintf(p,"Num BP loads (DL): %i\n",stats.thisFrame.numBPLoadsInDL);
D3D::font.DrawTextScaled(0,30,20,20,0.0f,0xFF00FFFF,st,false); D3D::font.DrawTextScaled(0,30,20,20,0.0f,0xFF00FFFF,st,false);
//end frame //end frame
} }
ProcessMessages(); ProcessMessages();
#if defined(DVPROFILE) #if defined(DVPROFILE)
if( g_bWriteProfile ) { if( g_bWriteProfile ) {
//g_bWriteProfile = 0; //g_bWriteProfile = 0;
static int framenum = 0; static int framenum = 0;
const int UPDATE_FRAMES = 8; const int UPDATE_FRAMES = 8;
if( ++framenum >= UPDATE_FRAMES ) { if( ++framenum >= UPDATE_FRAMES ) {
DVProfWrite("prof.txt", UPDATE_FRAMES); DVProfWrite("prof.txt", UPDATE_FRAMES);
DVProfClear(); DVProfClear();
framenum = 0; framenum = 0;
} }
} }
#endif #endif
D3D::EndFrame(); D3D::EndFrame();
//D3D frame is now over //D3D frame is now over
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
//clean out old stuff from caches //clean out old stuff from caches
frameCount++; frameCount++;
PShaderCache::Cleanup(); PShaderCache::Cleanup();
VShaderCache::Cleanup(); VShaderCache::Cleanup();
TextureCache::Cleanup(); TextureCache::Cleanup();
//DListCache::Cleanup(); //DListCache::Cleanup();
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
//Begin new frame //Begin new frame
//Set default viewport and scissor, for the clear to work correctly //Set default viewport and scissor, for the clear to work correctly
stats.ResetFrame(); stats.ResetFrame();
D3DVIEWPORT9 vp; D3DVIEWPORT9 vp;
vp.X = 0; vp.X = 0;
vp.Y = 0; vp.Y = 0;
vp.Width = (DWORD)m_width; vp.Width = (DWORD)m_width;
vp.Height = (DWORD)m_height; vp.Height = (DWORD)m_height;
vp.MinZ = 0; vp.MinZ = 0;
vp.MaxZ = 0; vp.MaxZ = 0;
D3D::dev->SetViewport(&vp); D3D::dev->SetViewport(&vp);
RECT rc; RECT rc;
rc.left = 0; rc.left = 0;
rc.top = 0; rc.top = 0;
rc.right = (LONG)m_width; rc.right = (LONG)m_width;
rc.bottom = (LONG)m_height; rc.bottom = (LONG)m_height;
D3D::dev->SetScissorRect(&rc); D3D::dev->SetScissorRect(&rc);
u32 clearColor = (bpmem.clearcolorAR<<16)|bpmem.clearcolorGB; u32 clearColor = (bpmem.clearcolorAR<<16)|bpmem.clearcolorGB;
// clearColor |= 0x003F003F; // clearColor |= 0x003F003F;
// D3D::BeginFrame(true,clearColor,1.0f); // D3D::BeginFrame(true,clearColor,1.0f);
D3D::BeginFrame(false,clearColor,1.0f); D3D::BeginFrame(false,clearColor,1.0f);
// D3D::EnableAlphaToCoverage(); // D3D::EnableAlphaToCoverage();
Postprocess::BeginFrame(); Postprocess::BeginFrame();
VertexManager::BeginFrame(); VertexManager::BeginFrame();
if (g_Config.bOldCard) if (g_Config.bOldCard)
D3D::font.SetRenderStates(); //compatibility with low end cards D3D::font.SetRenderStates(); //compatibility with low end cards
} }
void Renderer::Flush(void) void Renderer::Flush(void)
{ {
// render the rest of the vertex buffer // render the rest of the vertex buffer
//only to be used for debugging purposes //only to be used for debugging purposes
//D3D::EndFrame(); //D3D::EndFrame();
//D3D::BeginFrame(false,0); //D3D::BeginFrame(false,0);
} }
void Renderer::SetViewport(float* _Viewport) void Renderer::SetViewport(float* _Viewport)
{ {
Viewport* pViewport = (Viewport*)_Viewport; Viewport* pViewport = (Viewport*)_Viewport;
D3DVIEWPORT9 vp; D3DVIEWPORT9 vp;
float x=(pViewport->xOrig-662)*2; float x=(pViewport->xOrig-662)*2;
float y=(pViewport->yOrig-582)*2; //something is wrong, but what?? float y=(pViewport->yOrig-582)*2; //something is wrong, but what??
y-=16; y-=16;
float w=pViewport->wd*2; //multiply up to real size float w=pViewport->wd*2; //multiply up to real size
float h=pViewport->ht*-2; //why is this negative? oh well.. float h=pViewport->ht*-2; //why is this negative? oh well..
if (x < 0.0f) x = 0.0f; if (x < 0.0f) x = 0.0f;
if (y < 0.0f) y = 0.0f; if (y < 0.0f) y = 0.0f;
if (x > 640.0f) x = 639.0f; if (x > 640.0f) x = 639.0f;
if (y > 480.0f) y = 479.0f; if (y > 480.0f) y = 479.0f;
if (w < 0) w=1; if (w < 0) w=1;
if (h < 0) h=1; if (h < 0) h=1;
if (x+w > 640.0f) w=640-x; if (x+w > 640.0f) w=640-x;
if (y+h > 480.0f) h=480-y; if (y+h > 480.0f) h=480-y;
//x=y=0; //x=y=0;
//if(w>0.0f) w=0.0f; //if(w>0.0f) w=0.0f;
//if(h<0.0f) h=0.0f; //if(h<0.0f) h=0.0f;
vp.X = (DWORD)(x*xScale); vp.X = (DWORD)(x*xScale);
vp.Y = (DWORD)(y*yScale); vp.Y = (DWORD)(y*yScale);
vp.Width = (DWORD)(w*xScale); vp.Width = (DWORD)(w*xScale);
vp.Height = (DWORD)(h*yScale); vp.Height = (DWORD)(h*yScale);
vp.MinZ = 0.0f; vp.MinZ = 0.0f;
vp.MaxZ = 1.0f; vp.MaxZ = 1.0f;
// char temp[256]; // char temp[256];
// sprintf(temp,"Viewport: %i %i %i %i %f %f",vp.X,vp.Y,vp.Width,vp.Height,vp.MinZ,vp.MaxZ); // sprintf(temp,"Viewport: %i %i %i %i %f %f",vp.X,vp.Y,vp.Width,vp.Height,vp.MinZ,vp.MaxZ);
// g_VideoInitialize.pLog(temp, FALSE); // g_VideoInitialize.pLog(temp, FALSE);
D3D::dev->SetViewport(&vp); D3D::dev->SetViewport(&vp);
} }
void Renderer::SetScissorBox(RECT &rc) void Renderer::SetScissorBox(RECT &rc)
{ {
rc.left = (int)(rc.left * xScale); rc.left = (int)(rc.left * xScale);
rc.top = (int)(rc.top * yScale); rc.top = (int)(rc.top * yScale);
rc.right = (int)(rc.right * xScale); rc.right = (int)(rc.right * xScale);
rc.bottom = (int)(rc.bottom * yScale); rc.bottom = (int)(rc.bottom * yScale);
if (rc.right >= rc.left && rc.bottom >= rc.top) if (rc.right >= rc.left && rc.bottom >= rc.top)
D3D::dev->SetScissorRect(&rc); D3D::dev->SetScissorRect(&rc);
else else
g_VideoInitialize.pLog("SCISSOR ERROR", FALSE); g_VideoInitialize.pLog("SCISSOR ERROR", FALSE);
} }
void Renderer::SetProjection(float* pMatrix, int constantIndex) void Renderer::SetProjection(float* pMatrix, int constantIndex)
{ {
D3DXMATRIX mtx; D3DXMATRIX mtx;
if (pMatrix[6] == 0) if (pMatrix[6] == 0)
{ {
mtx.m[0][0] = pMatrix[0]; mtx.m[0][0] = pMatrix[0];
mtx.m[1][0] = 0.0f; mtx.m[1][0] = 0.0f;
mtx.m[2][0] = pMatrix[1]; mtx.m[2][0] = pMatrix[1];
mtx.m[3][0] = -0.5f/m_width; mtx.m[3][0] = -0.5f/m_width;
mtx.m[0][1] = 0.0f; mtx.m[0][1] = 0.0f;
mtx.m[1][1] = pMatrix[2]; mtx.m[1][1] = pMatrix[2];
mtx.m[2][1] = pMatrix[3]; mtx.m[2][1] = pMatrix[3];
mtx.m[3][1] = +0.5f/m_height; mtx.m[3][1] = +0.5f/m_height;
mtx.m[0][2] = 0.0f; mtx.m[0][2] = 0.0f;
mtx.m[1][2] = 0.0f; mtx.m[1][2] = 0.0f;
mtx.m[2][2] = -(1-pMatrix[4]); mtx.m[2][2] = -(1-pMatrix[4]);
mtx.m[3][2] = pMatrix[5]; mtx.m[3][2] = pMatrix[5];
mtx.m[0][3] = 0.0f; mtx.m[0][3] = 0.0f;
mtx.m[1][3] = 0.0f; mtx.m[1][3] = 0.0f;
mtx.m[2][3] = -1.0f; mtx.m[2][3] = -1.0f;
mtx.m[3][3] = 0.0f; mtx.m[3][3] = 0.0f;
} }
else else
{ {
mtx.m[0][0] = pMatrix[0]; mtx.m[0][0] = pMatrix[0];
mtx.m[1][0] = 0.0f; mtx.m[1][0] = 0.0f;
mtx.m[2][0] = 0.0f; mtx.m[2][0] = 0.0f;
mtx.m[3][0] = pMatrix[1]-0.5f/m_width; // fix d3d pixel center mtx.m[3][0] = pMatrix[1]-0.5f/m_width; // fix d3d pixel center
mtx.m[0][1] = 0.0f; mtx.m[0][1] = 0.0f;
mtx.m[1][1] = pMatrix[2]; mtx.m[1][1] = pMatrix[2];
mtx.m[2][1] = 0.0f; mtx.m[2][1] = 0.0f;
mtx.m[3][1] = pMatrix[3]+0.5f/m_height; // fix d3d pixel center mtx.m[3][1] = pMatrix[3]+0.5f/m_height; // fix d3d pixel center
mtx.m[0][2] = 0.0f; mtx.m[0][2] = 0.0f;
mtx.m[1][2] = 0.0f; mtx.m[1][2] = 0.0f;
mtx.m[2][2] = pMatrix[4]; mtx.m[2][2] = pMatrix[4];
mtx.m[3][2] = -(-1 - pMatrix[5]); mtx.m[3][2] = -(-1 - pMatrix[5]);
mtx.m[0][3] = 0; mtx.m[0][3] = 0;
mtx.m[1][3] = 0; mtx.m[1][3] = 0;
mtx.m[2][3] = 0.0f; mtx.m[2][3] = 0.0f;
mtx.m[3][3] = 1.0f; mtx.m[3][3] = 1.0f;
} }
D3D::dev->SetVertexShaderConstantF(constantIndex, mtx, 4); D3D::dev->SetVertexShaderConstantF(constantIndex, mtx, 4);
} }
void Renderer::SetTexture( DWORD Stage, LPDIRECT3DBASETEXTURE9 pTexture ) void Renderer::SetTexture( DWORD Stage, LPDIRECT3DBASETEXTURE9 pTexture )
{ {
if ( m_Textures[Stage] != pTexture ) if ( m_Textures[Stage] != pTexture )
{ {
m_Textures[Stage] = pTexture; m_Textures[Stage] = pTexture;
D3D::dev->SetTexture( Stage, pTexture ); D3D::dev->SetTexture( Stage, pTexture );
} }
} }
void Renderer::SetFVF( DWORD FVF ) void Renderer::SetFVF( DWORD FVF )
{ {
if ( m_FVF != FVF ) if ( m_FVF != FVF )
{ {
m_FVF = FVF; m_FVF = FVF;
D3D::dev->SetFVF( FVF ); D3D::dev->SetFVF( FVF );
} }
} }
void Renderer::SetRenderState( D3DRENDERSTATETYPE State, DWORD Value ) void Renderer::SetRenderState( D3DRENDERSTATETYPE State, DWORD Value )
{ {
if ( m_RenderStates[State] != Value ) if ( m_RenderStates[State] != Value )
{ {
m_RenderStates[State] = Value; m_RenderStates[State] = Value;
D3D::dev->SetRenderState( State, Value ); D3D::dev->SetRenderState( State, Value );
} }
} }
void Renderer::SetTextureStageState( DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value ) void Renderer::SetTextureStageState( DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value )
{ {
if ( m_TextureStageStates[Stage][Type] != Value ) if ( m_TextureStageStates[Stage][Type] != Value )
{ {
m_TextureStageStates[Stage][Type] = Value; m_TextureStageStates[Stage][Type] = Value;
D3D::dev->SetTextureStageState( Stage, Type, Value ); D3D::dev->SetTextureStageState( Stage, Type, Value );
} }
} }
void Renderer::SetSamplerState( DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value ) void Renderer::SetSamplerState( DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value )
{ {
if ( m_SamplerStates[Sampler][Type] != Value ) if ( m_SamplerStates[Sampler][Type] != Value )
{ {
m_SamplerStates[Sampler][Type] = Value; m_SamplerStates[Sampler][Type] = Value;
D3D::dev->SetSamplerState( Sampler, Type, Value ); D3D::dev->SetSamplerState( Sampler, Type, Value );
} }
} }
void Renderer::DrawPrimitiveUP( D3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount, const void* pVertexStreamZeroData, UINT VertexStreamZeroStride ) void Renderer::DrawPrimitiveUP( D3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount, const void* pVertexStreamZeroData, UINT VertexStreamZeroStride )
{ {
D3D::dev->DrawPrimitiveUP( PrimitiveType, PrimitiveCount, pVertexStreamZeroData, VertexStreamZeroStride ); D3D::dev->DrawPrimitiveUP( PrimitiveType, PrimitiveCount, pVertexStreamZeroData, VertexStreamZeroStride );
} }
void Renderer::DrawPrimitive( D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount ) void Renderer::DrawPrimitive( D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount )
{ {
D3D::dev->DrawPrimitive( PrimitiveType, StartVertex, PrimitiveCount ); D3D::dev->DrawPrimitive( PrimitiveType, StartVertex, PrimitiveCount );
} }

View File

@ -1,218 +1,218 @@
// 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 "ShaderManager.h" #include "ShaderManager.h"
#include "VertexLoader.h" #include "VertexLoader.h"
#include "BPMemory.h" #include "BPMemory.h"
#include "XFMemory.h" #include "XFMemory.h"
//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;
} }
PShaderCache::PSCache PShaderCache::pshaders; PShaderCache::PSCache PShaderCache::pshaders;
VShaderCache::VSCache VShaderCache::vshaders; VShaderCache::VSCache VShaderCache::vshaders;
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());
} }
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();
tevhash currentHash = GetCurrentTEV(); tevhash currentHash = 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,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 <d3dx9.h> #include <d3dx9.h>
#include "Common.h" #include "Common.h"
#include "Statistics.h" #include "Statistics.h"
#include "D3DBase.h" #include "D3DBase.h"
#include "D3DTexture.h" #include "D3DTexture.h"
#include "Render.h" #include "Render.h"
#include "TextureDecoder.h" #include "TextureDecoder.h"
#include "TextureCache.h" #include "TextureCache.h"
#include "Config.h" #include "Config.h"
#include "main.h" #include "main.h"
u8 *TextureCache::temp = NULL; u8 *TextureCache::temp = NULL;
TextureCache::TexCache TextureCache::textures; TextureCache::TexCache TextureCache::textures;
extern int frameCount; extern int frameCount;
#define TEMP_SIZE (1024*1024*4) #define TEMP_SIZE (1024*1024*4)
void TextureCache::TCacheEntry::Destroy() void TextureCache::TCacheEntry::Destroy()
{ {
if (texture) if (texture)
texture->Release(); texture->Release();
texture = 0; texture = 0;
if (!isRenderTarget) { if (!isRenderTarget) {
u32 *ptr = (u32*)g_VideoInitialize.pGetMemoryPointer(addr + hashoffset*4); u32 *ptr = (u32*)g_VideoInitialize.pGetMemoryPointer(addr + hashoffset*4);
if (*ptr == hash) if (*ptr == hash)
*ptr = oldpixel; *ptr = oldpixel;
} }
} }
void TextureCache::Init() void TextureCache::Init()
{ {
temp = (u8*)VirtualAlloc(0,TEMP_SIZE,MEM_COMMIT,PAGE_READWRITE); temp = (u8*)VirtualAlloc(0,TEMP_SIZE,MEM_COMMIT,PAGE_READWRITE);
TexDecoder_SetTexFmtOverlayOptions(g_Config.bTexFmtOverlayEnable, g_Config.bTexFmtOverlayCenter); TexDecoder_SetTexFmtOverlayOptions(g_Config.bTexFmtOverlayEnable, g_Config.bTexFmtOverlayCenter);
} }
void TextureCache::Invalidate() void TextureCache::Invalidate()
{ {
TexCache::iterator iter = textures.begin(); TexCache::iterator iter = textures.begin();
for (; iter != textures.end(); iter++) for (; iter != textures.end(); iter++)
iter->second.Destroy(); iter->second.Destroy();
textures.clear(); textures.clear();
TexDecoder_SetTexFmtOverlayOptions(g_Config.bTexFmtOverlayEnable, g_Config.bTexFmtOverlayCenter); TexDecoder_SetTexFmtOverlayOptions(g_Config.bTexFmtOverlayEnable, g_Config.bTexFmtOverlayCenter);
} }
void TextureCache::Shutdown() void TextureCache::Shutdown()
{ {
Invalidate(); Invalidate();
if (temp != NULL) if (temp != NULL)
{ {
VirtualFree(temp, 0, MEM_RELEASE); VirtualFree(temp, 0, MEM_RELEASE);
temp = NULL; temp = NULL;
} }
} }
void TextureCache::Cleanup() void TextureCache::Cleanup()
{ {
TexCache::iterator iter=textures.begin(); TexCache::iterator iter=textures.begin();
while(iter != textures.end()) while(iter != textures.end())
{ {
if (frameCount>20+iter->second.frameCount) if (frameCount>20+iter->second.frameCount)
{ {
if (!iter->second.isRenderTarget) if (!iter->second.isRenderTarget)
{ {
iter->second.Destroy(); iter->second.Destroy();
iter = textures.erase(iter); iter = textures.erase(iter);
} }
else else
{ {
iter++; iter++;
} }
} }
else else
{ {
iter++; iter++;
} }
} }
} }
void TextureCache::Load(int stage, u32 address, int width, int height, int format, int tlutaddr, int tlutfmt) void TextureCache::Load(int stage, u32 address, int width, int height, int format, int tlutaddr, int tlutfmt)
{ {
if (address == 0) if (address == 0)
return; return;
TexCache::iterator iter = textures.find(address); TexCache::iterator iter = textures.find(address);
u8 *ptr = g_VideoInitialize.pGetMemoryPointer(address); u8 *ptr = g_VideoInitialize.pGetMemoryPointer(address);
int palSize = TexDecoder_GetPaletteSize(format); int palSize = TexDecoder_GetPaletteSize(format);
u32 palhash = 0xc0debabe; u32 palhash = 0xc0debabe;
if (palSize) if (palSize)
{ {
if (palSize>16) if (palSize>16)
palSize = 16; //let's not do excessive amount of checking palSize = 16; //let's not do excessive amount of checking
u8 *pal = g_VideoInitialize.pGetMemoryPointer(tlutaddr); u8 *pal = g_VideoInitialize.pGetMemoryPointer(tlutaddr);
if (pal != 0) if (pal != 0)
{ {
for (int i=0; i<palSize; i++) for (int i=0; i<palSize; i++)
{ {
palhash = _rotl(palhash,13); palhash = _rotl(palhash,13);
palhash ^= pal[i]; palhash ^= pal[i];
palhash += 31; palhash += 31;
} }
} }
} }
static LPDIRECT3DTEXTURE9 lastTexture[8] = {0,0,0,0,0,0,0,0}; static LPDIRECT3DTEXTURE9 lastTexture[8] = {0,0,0,0,0,0,0,0};
if (iter != textures.end()) if (iter != textures.end())
{ {
TCacheEntry &entry = iter->second; TCacheEntry &entry = iter->second;
if (entry.isRenderTarget || (((u32 *)ptr)[entry.hashoffset] == entry.hash && palhash == entry.paletteHash)) //stupid, improve if (entry.isRenderTarget || (((u32 *)ptr)[entry.hashoffset] == entry.hash && palhash == entry.paletteHash)) //stupid, improve
{ {
iter->second.frameCount = frameCount; iter->second.frameCount = frameCount;
if (lastTexture[stage] == iter->second.texture) if (lastTexture[stage] == iter->second.texture)
{ {
return; return;
} }
lastTexture[stage] = iter->second.texture; lastTexture[stage] = iter->second.texture;
// D3D::dev->SetTexture(stage,iter->second.texture); // D3D::dev->SetTexture(stage,iter->second.texture);
Renderer::SetTexture( stage, iter->second.texture ); Renderer::SetTexture( stage, iter->second.texture );
return; return;
} }
else else
{ {
TCacheEntry &entry = iter->second; TCacheEntry &entry = iter->second;
/* if (width == iter->second.w && height==entry.h && format==entry.fmt) /* if (width == iter->second.w && height==entry.h && format==entry.fmt)
{ {
LPDIRECT3DTEXTURE9 tex = entry.texture; LPDIRECT3DTEXTURE9 tex = entry.texture;
int bs = TexDecoder_GetBlockWidthInTexels(format)-1; //TexelSizeInNibbles(format)*width*height/16; int bs = TexDecoder_GetBlockWidthInTexels(format)-1; //TexelSizeInNibbles(format)*width*height/16;
int expandedWidth = (width+bs) & (~bs); int expandedWidth = (width+bs) & (~bs);
D3DFORMAT dfmt = TexDecoder_Decode(temp,ptr,expandedWidth,height,format, tlutaddr, tlutfmt); D3DFORMAT dfmt = TexDecoder_Decode(temp,ptr,expandedWidth,height,format, tlutaddr, tlutfmt);
D3D::ReplaceTexture2D(tex,temp,width,height,expandedWidth,dfmt); D3D::ReplaceTexture2D(tex,temp,width,height,expandedWidth,dfmt);
D3D::dev->SetTexture(stage,tex); D3D::dev->SetTexture(stage,tex);
return; return;
} }
else else
{*/ {*/
iter->second.Destroy(); iter->second.Destroy();
textures.erase(iter); textures.erase(iter);
//} //}
} }
} }
int bs = TexDecoder_GetBlockWidthInTexels(format)-1; //TexelSizeInNibbles(format)*width*height/16; int bs = TexDecoder_GetBlockWidthInTexels(format)-1; //TexelSizeInNibbles(format)*width*height/16;
int expandedWidth = (width+bs) & (~bs); int expandedWidth = (width+bs) & (~bs);
PC_TexFormat pcfmt = TexDecoder_Decode(temp,ptr,expandedWidth,height,format, tlutaddr, tlutfmt); PC_TexFormat pcfmt = TexDecoder_Decode(temp,ptr,expandedWidth,height,format, tlutaddr, tlutfmt);
D3DFORMAT d3d_fmt; D3DFORMAT d3d_fmt;
switch (pcfmt) { switch (pcfmt) {
case PC_TEX_FMT_BGRA32: case PC_TEX_FMT_BGRA32:
d3d_fmt = D3DFMT_A8R8G8B8; d3d_fmt = D3DFMT_A8R8G8B8;
break; break;
} }
//Make an entry in the table //Make an entry in the table
TCacheEntry entry; TCacheEntry entry;
entry.hashoffset = 0; entry.hashoffset = 0;
entry.hash = (u32)(((double)rand() / RAND_MAX) * 0xFFFFFFFF); entry.hash = (u32)(((double)rand() / RAND_MAX) * 0xFFFFFFFF);
entry.paletteHash = palhash; entry.paletteHash = palhash;
entry.oldpixel = ((u32 *)ptr)[entry.hashoffset]; entry.oldpixel = ((u32 *)ptr)[entry.hashoffset];
((u32 *)ptr)[entry.hashoffset] = entry.hash; ((u32 *)ptr)[entry.hashoffset] = entry.hash;
entry.addr = address; entry.addr = address;
entry.isRenderTarget=false; entry.isRenderTarget=false;
entry.isNonPow2 = ((width&(width-1)) || (height&(height-1))); entry.isNonPow2 = ((width&(width-1)) || (height&(height-1)));
entry.texture = D3D::CreateTexture2D((BYTE*)temp, width, height, expandedWidth, d3d_fmt); entry.texture = D3D::CreateTexture2D((BYTE*)temp, width, height, expandedWidth, d3d_fmt);
entry.frameCount = frameCount; entry.frameCount = frameCount;
entry.w=width; entry.w=width;
entry.h=height; entry.h=height;
entry.fmt=format; entry.fmt=format;
textures[address] = entry; textures[address] = entry;
if (g_Config.bDumpTextures) if (g_Config.bDumpTextures)
{ // dump texture to file { // dump texture to file
static int counter = 0; static int counter = 0;
char szTemp[MAX_PATH]; char szTemp[MAX_PATH];
sprintf(szTemp, "%s\\txt_%04i_%i.png", g_Config.texDumpPath.c_str(), counter++, format); sprintf(szTemp, "%s\\txt_%04i_%i.png", g_Config.texDumpPath.c_str(), counter++, format);
D3DXSaveTextureToFile(szTemp,D3DXIFF_BMP,entry.texture,0); D3DXSaveTextureToFile(szTemp,D3DXIFF_BMP,entry.texture,0);
} }
INCSTAT(stats.numTexturesCreated); INCSTAT(stats.numTexturesCreated);
SETSTAT(stats.numTexturesAlive, (int)textures.size()); SETSTAT(stats.numTexturesAlive, (int)textures.size());
//Set the texture! //Set the texture!
// D3D::dev->SetTexture(stage,entry.texture); // D3D::dev->SetTexture(stage,entry.texture);
Renderer::SetTexture( stage, entry.texture ); Renderer::SetTexture( stage, entry.texture );
lastTexture[stage] = entry.texture; lastTexture[stage] = entry.texture;
} }
void TextureCache::CopyEFBToRenderTarget(u32 address, RECT *source) void TextureCache::CopyEFBToRenderTarget(u32 address, RECT *source)
{ {
TexCache::iterator iter; TexCache::iterator iter;
LPDIRECT3DTEXTURE9 tex; LPDIRECT3DTEXTURE9 tex;
iter = textures.find(address); iter = textures.find(address);
if (iter != textures.end()) if (iter != textures.end())
{ {
if (!iter->second.isRenderTarget) if (!iter->second.isRenderTarget)
{ {
g_VideoInitialize.pLog("Using non-rendertarget texture as render target!!! WTF?", FALSE); g_VideoInitialize.pLog("Using non-rendertarget texture as render target!!! WTF?", FALSE);
//TODO: remove it and recreate it as a render target //TODO: remove it and recreate it as a render target
} }
tex = iter->second.texture; tex = iter->second.texture;
iter->second.frameCount=frameCount; iter->second.frameCount=frameCount;
} }
else else
{ {
TCacheEntry entry; TCacheEntry entry;
entry.isRenderTarget=true; entry.isRenderTarget=true;
entry.hash = 0; entry.hash = 0;
entry.hashoffset = 0; entry.hashoffset = 0;
entry.frameCount = frameCount; entry.frameCount = frameCount;
// TODO(ector): infer this size in some sensible way // TODO(ector): infer this size in some sensible way
D3D::dev->CreateTexture(512,512,1,D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &entry.texture, 0); D3D::dev->CreateTexture(512,512,1,D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &entry.texture, 0);
textures[address] = entry; textures[address] = entry;
tex = entry.texture; tex = entry.texture;
} }
LPDIRECT3DSURFACE9 srcSurface,destSurface; LPDIRECT3DSURFACE9 srcSurface,destSurface;
tex->GetSurfaceLevel(0,&destSurface); tex->GetSurfaceLevel(0,&destSurface);
srcSurface = D3D::GetBackBufferSurface(); srcSurface = D3D::GetBackBufferSurface();
D3D::dev->StretchRect(srcSurface,source,destSurface,0,D3DTEXF_NONE); D3D::dev->StretchRect(srcSurface,source,destSurface,0,D3DTEXF_NONE);
destSurface->Release(); destSurface->Release();
} }

View File

@ -1,372 +1,372 @@
// 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 <fvec.h> #include <fvec.h>
#include "Common.h" #include "Common.h"
#include "Profiler.h" #include "Profiler.h"
// #include "Globals.h" // #include "Globals.h"
#include "Vec3.h" #include "Vec3.h"
#include "TransformEngine.h" #include "TransformEngine.h"
#include "VertexManager.h" #include "VertexManager.h"
#include "VertexLoader.h" #include "VertexLoader.h"
#include "BPStructs.h" #include "BPStructs.h"
#include "XFStructs.h" #include "XFStructs.h"
#include "Utils.h" #include "Utils.h"
#include "RGBAFloat.h" #include "RGBAFloat.h"
float *CTransformEngine::m_pPosMatrix; float *CTransformEngine::m_pPosMatrix;
float *CTransformEngine::m_pNormalMatrix; float *CTransformEngine::m_pNormalMatrix;
float *CTransformEngine::m_pTexMatrix[8]; float *CTransformEngine::m_pTexMatrix[8];
float *CTransformEngine::m_pTexPostMatrix[8]; float *CTransformEngine::m_pTexPostMatrix[8];
const Light *GetLight(int i) const Light *GetLight(int i)
{ {
return (const Light *)(xfmem + XFMEM_LIGHTS) + i; return (const Light *)(xfmem + XFMEM_LIGHTS) + i;
} }
float DoLighting(const Light *light, const LitChannel &chan, const Vec3 &pos, const Vec3 &normal) float DoLighting(const Light *light, const LitChannel &chan, const Vec3 &pos, const Vec3 &normal)
{ {
float val; float val;
if (chan.attnfunc == 0 || chan.attnfunc == 2) //no attn if (chan.attnfunc == 0 || chan.attnfunc == 2) //no attn
{ {
Vec3 ldir = (Vec3(light->dpos) - pos); Vec3 ldir = (Vec3(light->dpos) - pos);
val = ldir.normalized() * normal; val = ldir.normalized() * normal;
} }
else else
{ {
float aattn = 0; float aattn = 0;
float d; float d;
float mul = 1.0f; float mul = 1.0f;
if (chan.attnfunc == 3) if (chan.attnfunc == 3)
{ {
Vec3 ldir = (Vec3(light->dpos) - pos); Vec3 ldir = (Vec3(light->dpos) - pos);
d = ldir.length(); d = ldir.length();
Vec3 ldirNorm = ldir / d; //normalize Vec3 ldirNorm = ldir / d; //normalize
float l = ldirNorm * normal; float l = ldirNorm * normal;
aattn = Vec3(light->ddir) * ldirNorm; aattn = Vec3(light->ddir) * ldirNorm;
mul = l; mul = l;
} }
else if (chan.attnfunc == 1) else if (chan.attnfunc == 1)
{ {
d = aattn = Vec3(light->shalfangle) * normal; d = aattn = Vec3(light->shalfangle) * normal;
mul = (Vec3(light->sdir) * normal > 0) ? (normal * Vec3(light->shalfangle)) : 0; mul = (Vec3(light->sdir) * normal > 0) ? (normal * Vec3(light->shalfangle)) : 0;
if (mul < 0) if (mul < 0)
mul = 0; mul = 0;
} }
float spot = (light->a2*aattn*aattn + light->a1*aattn + light->a0); float spot = (light->a2*aattn*aattn + light->a1*aattn + light->a0);
float dist = 1.0f/(light->k2*d*d + light->k1*d + light->k0); float dist = 1.0f/(light->k2*d*d + light->k1*d + light->k0);
if (spot<0) if (spot<0)
spot=0; spot=0;
val = mul * spot * dist; val = mul * spot * dist;
} }
if (val < 0 && chan.diffusefunc == 2) // clamp if (val < 0 && chan.diffusefunc == 2) // clamp
val = 0; val = 0;
return val; return val;
} }
void VtxMulMtx43T(Vec3 &out, const Vec3 &in, const float pMatrix[12]) void VtxMulMtx43T(Vec3 &out, const Vec3 &in, const float pMatrix[12])
{ {
out.x = in.x * pMatrix[0] + in.y * pMatrix[1] + in.z * pMatrix[2] + 1 * pMatrix[3]; out.x = in.x * pMatrix[0] + in.y * pMatrix[1] + in.z * pMatrix[2] + 1 * pMatrix[3];
out.y = in.x * pMatrix[4] + in.y * pMatrix[5] + in.z * pMatrix[6] + 1 * pMatrix[7]; out.y = in.x * pMatrix[4] + in.y * pMatrix[5] + in.z * pMatrix[6] + 1 * pMatrix[7];
out.z = in.x * pMatrix[8] + in.y * pMatrix[9] + in.z * pMatrix[10] + 1 * pMatrix[11]; out.z = in.x * pMatrix[8] + in.y * pMatrix[9] + in.z * pMatrix[10] + 1 * pMatrix[11];
} }
void VtxMulMtx43(Vec3 &out, const Vec3 &in, const float pMatrix[12]) void VtxMulMtx43(Vec3 &out, const Vec3 &in, const float pMatrix[12])
{ {
VtxMulMtx43T(out,in,pMatrix); VtxMulMtx43T(out,in,pMatrix);
//TODO(XK): Turns out that SSE2 computations are slower... Can anyone do //TODO(XK): Turns out that SSE2 computations are slower... Can anyone do
// anything about it? // anything about it?
/* /*
F32vec4 a(in.x, in.y, in.z, 1), b(pMatrix[0], pMatrix[1], pMatrix[2], pMatrix[3]); F32vec4 a(in.x, in.y, in.z, 1), b(pMatrix[0], pMatrix[1], pMatrix[2], pMatrix[3]);
out.x = add_horizontal(a * b); out.x = add_horizontal(a * b);
b[0] = pMatrix[4]; b[1] = pMatrix[5]; b[2] = pMatrix[6]; b[3] = pMatrix[7]; b[0] = pMatrix[4]; b[1] = pMatrix[5]; b[2] = pMatrix[6]; b[3] = pMatrix[7];
out.y = add_horizontal(a * b); out.y = add_horizontal(a * b);
b[0] = pMatrix[8]; b[1] = pMatrix[9]; b[2] = pMatrix[10]; b[3] = pMatrix[11]; b[0] = pMatrix[8]; b[1] = pMatrix[9]; b[2] = pMatrix[10]; b[3] = pMatrix[11];
out.z = add_horizontal(a * b); out.z = add_horizontal(a * b);
*/ */
} }
void VtxMulMtx42(Vec3 &out, const Vec3 &in, const float pMatrix[8]) void VtxMulMtx42(Vec3 &out, const Vec3 &in, const float pMatrix[8])
{ {
out.x = in.x * pMatrix[0] + in.y * pMatrix[1] + in.z * pMatrix[2] + 1 * pMatrix[3]; out.x = in.x * pMatrix[0] + in.y * pMatrix[1] + in.z * pMatrix[2] + 1 * pMatrix[3];
out.y = in.x * pMatrix[4] + in.y * pMatrix[5] + in.z * pMatrix[6] + 1 * pMatrix[7]; out.y = in.x * pMatrix[4] + in.y * pMatrix[5] + in.z * pMatrix[6] + 1 * pMatrix[7];
} }
void VtxMulMtx33(Vec3 &out, const Vec3 &in, const float pMatrix[9]) void VtxMulMtx33(Vec3 &out, const Vec3 &in, const float pMatrix[9])
{ {
out.x = in.x * pMatrix[0] + in.y * pMatrix[1] + in.z * pMatrix[2]; out.x = in.x * pMatrix[0] + in.y * pMatrix[1] + in.z * pMatrix[2];
out.y = in.x * pMatrix[3] + in.y * pMatrix[4] + in.z * pMatrix[5]; out.y = in.x * pMatrix[3] + in.y * pMatrix[4] + in.z * pMatrix[5];
out.z = in.x * pMatrix[6] + in.y * pMatrix[7] + in.z * pMatrix[8]; out.z = in.x * pMatrix[6] + in.y * pMatrix[7] + in.z * pMatrix[8];
} }
void CTransformEngine::TransformVertices(int _numVertices, const DecodedVArray *varray, D3DVertex *vbuffer) void CTransformEngine::TransformVertices(int _numVertices, const DecodedVArray *varray, D3DVertex *vbuffer)
{ {
if (vbuffer == 0) if (vbuffer == 0)
{ {
MessageBox(0,"TransformVertices : vbuffer == 0","WTF",0); MessageBox(0,"TransformVertices : vbuffer == 0","WTF",0);
} }
DVSTARTPROFILE(); DVSTARTPROFILE();
RGBAFloat lightColors[8]; RGBAFloat lightColors[8];
RGBAFloat lightVals[8]; RGBAFloat lightVals[8];
RGBAFloat chans[2]; RGBAFloat chans[2];
u32 components = varray->GetComponents(); u32 components = varray->GetComponents();
// TODO: only for active lights // TODO: only for active lights
for (int i=0; i<8; i++) for (int i=0; i<8; i++)
lightColors[i].convert_GC(GetLight(i)->color); lightColors[i].convert_GC(GetLight(i)->color);
for (int i=0; i<_numVertices; i++) for (int i=0; i<_numVertices; i++)
{ {
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
//Step 1: xform position and normal //Step 1: xform position and normal
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
Vec3 OrigPos = varray->GetPos(i); Vec3 OrigPos = varray->GetPos(i);
if (varray->hasPosMatIdx) if (varray->hasPosMatIdx)
{ {
int index = varray->GetPosMtxInd(i); int index = varray->GetPosMtxInd(i);
SetPosNormalMatrix( SetPosNormalMatrix(
(float*)xfmem + (index & 63) * 4, //CHECK (float*)xfmem + (index & 63) * 4, //CHECK
(float*)xfmem + 0x400 + 3 * (index & 31)); //CHECK (float*)xfmem + 0x400 + 3 * (index & 31)); //CHECK
} }
for (int j = 0; j < 8; j++) for (int j = 0; j < 8; j++)
{ {
if (varray->hasTexMatIdx[j]) if (varray->hasTexMatIdx[j])
{ {
float *flipmem = (float *)xfmem; float *flipmem = (float *)xfmem;
int index = varray->GetTexMtxInd(j, i); int index = varray->GetTexMtxInd(j, i);
SetTexMatrix(j, flipmem + index * 4); SetTexMatrix(j, flipmem + index * 4);
} }
} }
Vec3 TempPos; Vec3 TempPos;
// m_pPosMatrix can be switched out, through matrixindex vertex components // m_pPosMatrix can be switched out, through matrixindex vertex components
VtxMulMtx43(TempPos, OrigPos, m_pPosMatrix); VtxMulMtx43(TempPos, OrigPos, m_pPosMatrix);
Vec3 TempNormal; Vec3 TempNormal;
Vec3 OrigNormal; Vec3 OrigNormal;
if (varray->hasNrm) if (varray->hasNrm)
{ {
OrigNormal = varray->GetNormal(0, i); OrigNormal = varray->GetNormal(0, i);
VtxMulMtx33(TempNormal, OrigNormal, m_pNormalMatrix); VtxMulMtx33(TempNormal, OrigNormal, m_pNormalMatrix);
TempNormal.normalize(); TempNormal.normalize();
} }
else else
{ {
OrigNormal.setZero(); OrigNormal.setZero();
TempNormal.setZero(); TempNormal.setZero();
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
//Step 2: Light! //Step 2: Light!
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
//find all used lights //find all used lights
u32 lightMask = u32 lightMask =
xfregs.colChans[0].color.GetFullLightMask() | xfregs.colChans[0].alpha.GetFullLightMask() | xfregs.colChans[0].color.GetFullLightMask() | xfregs.colChans[0].alpha.GetFullLightMask() |
xfregs.colChans[1].color.GetFullLightMask() | xfregs.colChans[1].alpha.GetFullLightMask(); xfregs.colChans[1].color.GetFullLightMask() | xfregs.colChans[1].alpha.GetFullLightMask();
float r0=0,g0=0,b0=0,a0=0; float r0=0,g0=0,b0=0,a0=0;
//go through them and compute the lit colors //go through them and compute the lit colors
//Sum lighting for both two color channels if they're active //Sum lighting for both two color channels if they're active
for (int j = 0; j < (int)bpmem.genMode.numcolchans; j++) for (int j = 0; j < (int)bpmem.genMode.numcolchans; j++)
{ {
RGBAFloat material; RGBAFloat material;
RGBAFloat lightSum(0,0,0,0); RGBAFloat lightSum(0,0,0,0);
bool hasColorJ = (components & (VertexLoader::VB_HAS_COL0 << j)) != 0; bool hasColorJ = (components & (VertexLoader::VB_HAS_COL0 << j)) != 0;
//get basic material color from appropriate sources (this would compile nicely!:) //get basic material color from appropriate sources (this would compile nicely!:)
if (xfregs.colChans[j].color.matsource == GX_SRC_REG) if (xfregs.colChans[j].color.matsource == GX_SRC_REG)
material.convertRGB_GC(xfregs.colChans[j].matColor); material.convertRGB_GC(xfregs.colChans[j].matColor);
else else
{ {
if (hasColorJ) if (hasColorJ)
material.convertRGB(varray->GetColor(j, i)); material.convertRGB(varray->GetColor(j, i));
else else
material.r=material.g=material.b=1.0f; material.r=material.g=material.b=1.0f;
} }
if (xfregs.colChans[j].alpha.matsource == GX_SRC_REG) if (xfregs.colChans[j].alpha.matsource == GX_SRC_REG)
material.convertA_GC(xfregs.colChans[j].matColor); material.convertA_GC(xfregs.colChans[j].matColor);
else else
{ {
if (hasColorJ) if (hasColorJ)
material.convertA(varray->GetColor(j, i)); material.convertA(varray->GetColor(j, i));
else else
material.a=1.0f; material.a=1.0f;
} }
//combine together the light values from the lights that affect the color //combine together the light values from the lights that affect the color
if (xfregs.colChans[j].color.enablelighting) if (xfregs.colChans[j].color.enablelighting)
{ {
//choose ambient source and start our lightsum accumulator with its value.. //choose ambient source and start our lightsum accumulator with its value..
if (xfregs.colChans[j].color.ambsource == GX_SRC_REG) if (xfregs.colChans[j].color.ambsource == GX_SRC_REG)
lightSum.convertRGB_GC(xfregs.colChans[j].ambColor); //ambient lightSum.convertRGB_GC(xfregs.colChans[j].ambColor); //ambient
else else
{ {
if (hasColorJ) if (hasColorJ)
lightSum.convertRGB(varray->GetColor(j, i)); lightSum.convertRGB(varray->GetColor(j, i));
else else
{ {
lightSum.r=0.0f;lightSum.g=0.0f;lightSum.b=0.0f; lightSum.r=0.0f;lightSum.g=0.0f;lightSum.b=0.0f;
} }
} }
//accumulate light colors //accumulate light colors
int cmask = xfregs.colChans[j].color.GetFullLightMask(); int cmask = xfregs.colChans[j].color.GetFullLightMask();
for (int l=0; l<8; l++) for (int l=0; l<8; l++)
{ {
if (cmask&1) if (cmask&1)
{ {
float val = DoLighting(GetLight(l), xfregs.colChans[j].color, TempPos, TempNormal); float val = DoLighting(GetLight(l), xfregs.colChans[j].color, TempPos, TempNormal);
float r = lightColors[l].r * val; float r = lightColors[l].r * val;
float g = lightColors[l].g * val; float g = lightColors[l].g * val;
float b = lightColors[l].b * val; float b = lightColors[l].b * val;
lightSum.r += r; lightSum.r += r;
lightSum.g += g; lightSum.g += g;
lightSum.b += b; lightSum.b += b;
} }
cmask >>= 1; cmask >>= 1;
} }
} }
else else
{ {
lightSum.r = lightSum.g = lightSum.b = 1.0f; lightSum.r = lightSum.g = lightSum.b = 1.0f;
} }
//combine together the light values from the lights that affect alpha (should be rare) //combine together the light values from the lights that affect alpha (should be rare)
if (xfregs.colChans[j].alpha.enablelighting) if (xfregs.colChans[j].alpha.enablelighting)
{ {
//choose ambient source.. //choose ambient source..
if (xfregs.colChans[j].alpha.ambsource==GX_SRC_REG) if (xfregs.colChans[j].alpha.ambsource==GX_SRC_REG)
lightSum.convertA_GC(xfregs.colChans[j].ambColor); lightSum.convertA_GC(xfregs.colChans[j].ambColor);
else else
{ {
if (hasColorJ) if (hasColorJ)
lightSum.convertA(varray->GetColor(j, i)); lightSum.convertA(varray->GetColor(j, i));
else else
lightSum.a=0.0f; lightSum.a=0.0f;
} }
//accumulate light alphas //accumulate light alphas
int amask = xfregs.colChans[j].alpha.GetFullLightMask(); int amask = xfregs.colChans[j].alpha.GetFullLightMask();
for (int l = 0; l < 8; l++) for (int l = 0; l < 8; l++)
{ {
if (amask&1) if (amask&1)
{ {
float val = DoLighting(GetLight(l), xfregs.colChans[j].alpha, TempPos, TempNormal); float val = DoLighting(GetLight(l), xfregs.colChans[j].alpha, TempPos, TempNormal);
float a = lightColors[l].a * val; float a = lightColors[l].a * val;
lightSum.a += a; lightSum.a += a;
} }
amask >>= 1; amask >>= 1;
} }
} }
else else
{ {
lightSum.a=1.0f; lightSum.a=1.0f;
} }
chans[j] = lightSum * material; chans[j] = lightSum * material;
chans[j].clamp(); chans[j].clamp();
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
//Step 3: Generate texture coordinates! //Step 3: Generate texture coordinates!
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
Vec3 TempUVs[8]; Vec3 TempUVs[8];
for (int j = 0; j < xfregs.numTexGens; j++) for (int j = 0; j < xfregs.numTexGens; j++)
{ {
Vec3 t; Vec3 t;
switch (xfregs.texcoords[j].texmtxinfo.sourcerow) { switch (xfregs.texcoords[j].texmtxinfo.sourcerow) {
case XF_SRCGEOM_INROW: t = OrigPos; break; //HACK WTFF??? case XF_SRCGEOM_INROW: t = OrigPos; break; //HACK WTFF???
case XF_SRCNORMAL_INROW: t = OrigNormal; break; case XF_SRCNORMAL_INROW: t = OrigNormal; break;
case XF_SRCCOLORS_INROW: break; //set uvs to something? case XF_SRCCOLORS_INROW: break; //set uvs to something?
case XF_SRCBINORMAL_T_INROW: t=Vec3(0,0,0);break; case XF_SRCBINORMAL_T_INROW: t=Vec3(0,0,0);break;
case XF_SRCBINORMAL_B_INROW: t=Vec3(0,0,0);break; case XF_SRCBINORMAL_B_INROW: t=Vec3(0,0,0);break;
default: default:
{ {
int c = xfregs.texcoords[j].texmtxinfo.sourcerow - XF_SRCTEX0_INROW; int c = xfregs.texcoords[j].texmtxinfo.sourcerow - XF_SRCTEX0_INROW;
bool hasTCC = (components & (VertexLoader::VB_HAS_UV0 << c)) != 0; bool hasTCC = (components & (VertexLoader::VB_HAS_UV0 << c)) != 0;
if (c >= 0 && c <= 7 && hasTCC) if (c >= 0 && c <= 7 && hasTCC)
{ {
const DecUV &uv = varray->GetUV(c, i); const DecUV &uv = varray->GetUV(c, i);
t = Vec3(uv.u, uv.v, 1); t = Vec3(uv.u, uv.v, 1);
} }
} }
} }
Vec3 out,out2; Vec3 out,out2;
switch (xfregs.texcoords[j].texmtxinfo.texgentype) switch (xfregs.texcoords[j].texmtxinfo.texgentype)
{ {
case XF_TEXGEN_COLOR_STRGBC0: case XF_TEXGEN_COLOR_STRGBC0:
out = Vec3(chans[0].r*255, chans[0].g*255, 1)/255.0f; out = Vec3(chans[0].r*255, chans[0].g*255, 1)/255.0f;
break; break;
case XF_TEXGEN_COLOR_STRGBC1: case XF_TEXGEN_COLOR_STRGBC1:
out = Vec3(chans[1].r*255, chans[1].g*255, 1)/255.0f; //FIX: take color1 instead out = Vec3(chans[1].r*255, chans[1].g*255, 1)/255.0f; //FIX: take color1 instead
break; break;
case XF_TEXGEN_REGULAR: case XF_TEXGEN_REGULAR:
if (xfregs.texcoords[j].texmtxinfo.projection) if (xfregs.texcoords[j].texmtxinfo.projection)
VtxMulMtx43(out, t, m_pTexMatrix[j]); VtxMulMtx43(out, t, m_pTexMatrix[j]);
else else
VtxMulMtx42(out, t, m_pTexMatrix[j]); VtxMulMtx42(out, t, m_pTexMatrix[j]);
break; break;
} }
if (xfregs.texcoords[j].postmtxinfo.normalize) if (xfregs.texcoords[j].postmtxinfo.normalize)
out.normalize(); out.normalize();
int postMatrix = xfregs.texcoords[j].postmtxinfo.index; int postMatrix = xfregs.texcoords[j].postmtxinfo.index;
float *pmtx = ((float*)xfmem) + 0x500 + postMatrix * 4; //CHECK float *pmtx = ((float*)xfmem) + 0x500 + postMatrix * 4; //CHECK
//multiply with postmatrix //multiply with postmatrix
VtxMulMtx43(TempUVs[j], out, pmtx); VtxMulMtx43(TempUVs[j], out, pmtx);
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
//Step 4: Output the vertex! //Step 4: Output the vertex!
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
for (int j = 0; j < 2; j++) for (int j = 0; j < 2; j++)
chans[j].convertToD3DColor(vbuffer[i].colors[j]); chans[j].convertToD3DColor(vbuffer[i].colors[j]);
vbuffer[i].pos = TempPos; vbuffer[i].pos = TempPos;
vbuffer[i].normal = TempNormal; vbuffer[i].normal = TempNormal;
for (int j = 0; j < (int)bpmem.genMode.numtexgens; j++) for (int j = 0; j < (int)bpmem.genMode.numtexgens; j++)
{ {
vbuffer[i].uv[j].u = TempUVs[j].x; vbuffer[i].uv[j].u = TempUVs[j].x;
vbuffer[i].uv[j].v = TempUVs[j].y; vbuffer[i].uv[j].v = TempUVs[j].y;
vbuffer[i].uv[j].w = TempUVs[j].z; vbuffer[i].uv[j].w = TempUVs[j].z;
} }
} }
} }

View File

@ -1,45 +1,45 @@
// 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/
#ifdef _WIN32 #ifdef _WIN32
#include "W32Util/Misc.h" #include "W32Util/Misc.h"
#endif #endif
#include "Common.h" #include "Common.h"
#include <assert.h> #include <assert.h>
int frameCount; int frameCount;
// Message handler for about box. // Message handler for about box.
LRESULT CALLBACK AboutProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM /*lParam*/) LRESULT CALLBACK AboutProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM /*lParam*/)
{ {
switch (message) switch (message)
{ {
case WM_INITDIALOG: case WM_INITDIALOG:
W32Util::CenterWindow(hDlg); W32Util::CenterWindow(hDlg);
return TRUE; return TRUE;
case WM_COMMAND: case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{ {
EndDialog(hDlg, LOWORD(wParam)); EndDialog(hDlg, LOWORD(wParam));
return TRUE; return TRUE;
} }
break; break;
} }
return FALSE; return FALSE;
} }

View File

@ -1,363 +1,363 @@
// 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 <stdio.h> #include <stdio.h>
#include "x64Emitter.h" #include "x64Emitter.h"
#include "Common.h" #include "Common.h"
#include "LookUpTables.h" #include "LookUpTables.h"
#include "Profiler.h" #include "Profiler.h"
#include "VertexManager.h" #include "VertexManager.h"
#include "VertexLoader.h" #include "VertexLoader.h"
#include "XFStructs.h" #include "XFStructs.h"
#include "BPStructs.h" #include "BPStructs.h"
#include "DataReader.h" #include "DataReader.h"
#include "DecodedVArray.h" #include "DecodedVArray.h"
//these don't need to be saved //these don't need to be saved
float posScale; float posScale;
float tcScale[8]; float tcScale[8];
int tcElements[8]; int tcElements[8];
int tcFormat[8]; int tcFormat[8];
int colElements[2]; int colElements[2];
float tcScaleU[8]; float tcScaleU[8];
float tcScaleV[8]; float tcScaleV[8];
int tcIndex; int tcIndex;
int colIndex; int colIndex;
u32 addr; u32 addr;
DecodedVArray *varray; DecodedVArray *varray;
int ComputeVertexSize(u32 comp) int ComputeVertexSize(u32 comp)
{ {
int size = 0; int size = 0;
if (comp & VertexLoader::VB_HAS_POSMTXIDX) if (comp & VertexLoader::VB_HAS_POSMTXIDX)
size += 4; size += 4;
if (comp & (VertexLoader::VB_HAS_TEXMTXIDX0 | VertexLoader::VB_HAS_TEXMTXIDX1 | VertexLoader::VB_HAS_TEXMTXIDX2 | VertexLoader::VB_HAS_TEXMTXIDX3)) if (comp & (VertexLoader::VB_HAS_TEXMTXIDX0 | VertexLoader::VB_HAS_TEXMTXIDX1 | VertexLoader::VB_HAS_TEXMTXIDX2 | VertexLoader::VB_HAS_TEXMTXIDX3))
size += 4; size += 4;
if (comp & (VertexLoader::VB_HAS_TEXMTXIDX4 | VertexLoader::VB_HAS_TEXMTXIDX5 | VertexLoader::VB_HAS_TEXMTXIDX6 | VertexLoader::VB_HAS_TEXMTXIDX7)) if (comp & (VertexLoader::VB_HAS_TEXMTXIDX4 | VertexLoader::VB_HAS_TEXMTXIDX5 | VertexLoader::VB_HAS_TEXMTXIDX6 | VertexLoader::VB_HAS_TEXMTXIDX7))
size += 4; size += 4;
if (comp & VertexLoader::VB_HAS_NRM0) if (comp & VertexLoader::VB_HAS_NRM0)
size += 4; size += 4;
if (comp & (VertexLoader::VB_HAS_NRM1 | VertexLoader::VB_HAS_NRM2)) //combine into single check for speed if (comp & (VertexLoader::VB_HAS_NRM1 | VertexLoader::VB_HAS_NRM2)) //combine into single check for speed
size += 8; size += 8;
if (comp & VertexLoader::VB_HAS_COL0) if (comp & VertexLoader::VB_HAS_COL0)
size += 4; size += 4;
if (comp & VertexLoader::VB_HAS_COL1) if (comp & VertexLoader::VB_HAS_COL1)
size += 4; size += 4;
for (int i = 0; i < 8; i++) for (int i = 0; i < 8; i++)
if (comp & (VertexLoader::VB_HAS_UV0 << i)) if (comp & (VertexLoader::VB_HAS_UV0 << i))
size += 8; size += 8;
return size; return size;
} }
void VertexLoader::SetVArray(DecodedVArray *_varray) void VertexLoader::SetVArray(DecodedVArray *_varray)
{ {
varray = _varray; varray = _varray;
} }
#include "VertexLoader_MtxIndex.h" #include "VertexLoader_MtxIndex.h"
#include "VertexLoader_Position.h" #include "VertexLoader_Position.h"
#include "VertexLoader_Normal.h" #include "VertexLoader_Normal.h"
#include "VertexLoader_Color.h" #include "VertexLoader_Color.h"
#include "VertexLoader_TextCoord.h" #include "VertexLoader_TextCoord.h"
VertexLoader g_VertexLoaders[8]; VertexLoader g_VertexLoaders[8];
TVtxDesc VertexLoader::m_VtxDesc; TVtxDesc VertexLoader::m_VtxDesc;
bool VertexLoader::m_DescDirty = true; bool VertexLoader::m_DescDirty = true;
VertexLoader::VertexLoader() VertexLoader::VertexLoader()
{ {
m_numPipelineStates = 0; m_numPipelineStates = 0;
m_VertexSize = 0; m_VertexSize = 0;
m_AttrDirty = true; m_AttrDirty = true;
VertexLoader_Normal::Init(); VertexLoader_Normal::Init();
} }
VertexLoader::~VertexLoader() VertexLoader::~VertexLoader()
{ {
} }
void VertexLoader::Setup() void VertexLoader::Setup()
{ {
if (!m_AttrDirty && !m_DescDirty) if (!m_AttrDirty && !m_DescDirty)
return; return;
DVSTARTPROFILE(); DVSTARTPROFILE();
// Reset pipeline // Reset pipeline
m_VertexSize = 0; m_VertexSize = 0;
m_numPipelineStates = 0; m_numPipelineStates = 0;
m_components = 0; m_components = 0;
// Position Matrix Index // Position Matrix Index
if (m_VtxDesc.PosMatIdx) if (m_VtxDesc.PosMatIdx)
{ {
m_PipelineStates[m_numPipelineStates++] = PosMtx_ReadDirect_UByte; m_PipelineStates[m_numPipelineStates++] = PosMtx_ReadDirect_UByte;
m_VertexSize += 1; m_VertexSize += 1;
m_components |= VB_HAS_POSMTXIDX; m_components |= VB_HAS_POSMTXIDX;
} }
// Texture matrix indices // Texture matrix indices
if (m_VtxDesc.Tex0MatIdx) {m_components|=VB_HAS_TEXMTXIDX0; WriteCall(TexMtx_ReadDirect_UByte); m_VertexSize+=1;} if (m_VtxDesc.Tex0MatIdx) {m_components|=VB_HAS_TEXMTXIDX0; WriteCall(TexMtx_ReadDirect_UByte); m_VertexSize+=1;}
if (m_VtxDesc.Tex1MatIdx) {m_components|=VB_HAS_TEXMTXIDX1; WriteCall(TexMtx_ReadDirect_UByte); m_VertexSize+=1;} if (m_VtxDesc.Tex1MatIdx) {m_components|=VB_HAS_TEXMTXIDX1; WriteCall(TexMtx_ReadDirect_UByte); m_VertexSize+=1;}
if (m_VtxDesc.Tex2MatIdx) {m_components|=VB_HAS_TEXMTXIDX2; WriteCall(TexMtx_ReadDirect_UByte); m_VertexSize+=1;} if (m_VtxDesc.Tex2MatIdx) {m_components|=VB_HAS_TEXMTXIDX2; WriteCall(TexMtx_ReadDirect_UByte); m_VertexSize+=1;}
if (m_VtxDesc.Tex3MatIdx) {m_components|=VB_HAS_TEXMTXIDX3; WriteCall(TexMtx_ReadDirect_UByte); m_VertexSize+=1;} if (m_VtxDesc.Tex3MatIdx) {m_components|=VB_HAS_TEXMTXIDX3; WriteCall(TexMtx_ReadDirect_UByte); m_VertexSize+=1;}
if (m_VtxDesc.Tex4MatIdx) {m_components|=VB_HAS_TEXMTXIDX4; WriteCall(TexMtx_ReadDirect_UByte); m_VertexSize+=1;} if (m_VtxDesc.Tex4MatIdx) {m_components|=VB_HAS_TEXMTXIDX4; WriteCall(TexMtx_ReadDirect_UByte); m_VertexSize+=1;}
if (m_VtxDesc.Tex5MatIdx) {m_components|=VB_HAS_TEXMTXIDX5; WriteCall(TexMtx_ReadDirect_UByte); m_VertexSize+=1;} if (m_VtxDesc.Tex5MatIdx) {m_components|=VB_HAS_TEXMTXIDX5; WriteCall(TexMtx_ReadDirect_UByte); m_VertexSize+=1;}
if (m_VtxDesc.Tex6MatIdx) {m_components|=VB_HAS_TEXMTXIDX6; WriteCall(TexMtx_ReadDirect_UByte); m_VertexSize+=1;} if (m_VtxDesc.Tex6MatIdx) {m_components|=VB_HAS_TEXMTXIDX6; WriteCall(TexMtx_ReadDirect_UByte); m_VertexSize+=1;}
if (m_VtxDesc.Tex7MatIdx) {m_components|=VB_HAS_TEXMTXIDX7; WriteCall(TexMtx_ReadDirect_UByte); m_VertexSize+=1;} if (m_VtxDesc.Tex7MatIdx) {m_components|=VB_HAS_TEXMTXIDX7; WriteCall(TexMtx_ReadDirect_UByte); m_VertexSize+=1;}
// Position // Position
switch (m_VtxDesc.Position) switch (m_VtxDesc.Position)
{ {
case NOT_PRESENT: {_assert_msg_(0,"Vertex descriptor without position!","WTF?");} break; case NOT_PRESENT: {_assert_msg_(0,"Vertex descriptor without position!","WTF?");} break;
case DIRECT: case DIRECT:
{ {
int SizePro = 0; int SizePro = 0;
switch (m_VtxAttr.PosFormat) switch (m_VtxAttr.PosFormat)
{ {
case FORMAT_UBYTE: SizePro=1; WriteCall(Pos_ReadDirect_UByte); break; case FORMAT_UBYTE: SizePro=1; WriteCall(Pos_ReadDirect_UByte); break;
case FORMAT_BYTE: SizePro=1; WriteCall(Pos_ReadDirect_Byte); break; case FORMAT_BYTE: SizePro=1; WriteCall(Pos_ReadDirect_Byte); break;
case FORMAT_USHORT: SizePro=2; WriteCall(Pos_ReadDirect_UShort); break; case FORMAT_USHORT: SizePro=2; WriteCall(Pos_ReadDirect_UShort); break;
case FORMAT_SHORT: SizePro=2; WriteCall(Pos_ReadDirect_Short); break; case FORMAT_SHORT: SizePro=2; WriteCall(Pos_ReadDirect_Short); break;
case FORMAT_FLOAT: SizePro=4; WriteCall(Pos_ReadDirect_Float); break; case FORMAT_FLOAT: SizePro=4; WriteCall(Pos_ReadDirect_Float); break;
default: _assert_(0); break; default: _assert_(0); break;
} }
if (m_VtxAttr.PosElements == 1) if (m_VtxAttr.PosElements == 1)
m_VertexSize += SizePro * 3; m_VertexSize += SizePro * 3;
else else
m_VertexSize += SizePro * 2; m_VertexSize += SizePro * 2;
} }
break; break;
case INDEX8: case INDEX8:
m_VertexSize+=1; m_VertexSize+=1;
switch (m_VtxAttr.PosFormat) switch (m_VtxAttr.PosFormat)
{ {
case FORMAT_UBYTE: WriteCall(Pos_ReadIndex8_UByte); break; //WTF? case FORMAT_UBYTE: WriteCall(Pos_ReadIndex8_UByte); break; //WTF?
case FORMAT_BYTE: WriteCall(Pos_ReadIndex8_Byte); break; case FORMAT_BYTE: WriteCall(Pos_ReadIndex8_Byte); break;
case FORMAT_USHORT: WriteCall(Pos_ReadIndex8_UShort); break; case FORMAT_USHORT: WriteCall(Pos_ReadIndex8_UShort); break;
case FORMAT_SHORT: WriteCall(Pos_ReadIndex8_Short); break; case FORMAT_SHORT: WriteCall(Pos_ReadIndex8_Short); break;
case FORMAT_FLOAT: WriteCall(Pos_ReadIndex8_Float); break; case FORMAT_FLOAT: WriteCall(Pos_ReadIndex8_Float); break;
default: _assert_(0); break; default: _assert_(0); break;
} }
break; break;
case INDEX16: case INDEX16:
m_VertexSize+=2; m_VertexSize+=2;
switch (m_VtxAttr.PosFormat) switch (m_VtxAttr.PosFormat)
{ {
case FORMAT_UBYTE: WriteCall(Pos_ReadIndex16_UByte); break; case FORMAT_UBYTE: WriteCall(Pos_ReadIndex16_UByte); break;
case FORMAT_BYTE: WriteCall(Pos_ReadIndex16_Byte); break; case FORMAT_BYTE: WriteCall(Pos_ReadIndex16_Byte); break;
case FORMAT_USHORT: WriteCall(Pos_ReadIndex16_UShort); break; case FORMAT_USHORT: WriteCall(Pos_ReadIndex16_UShort); break;
case FORMAT_SHORT: WriteCall(Pos_ReadIndex16_Short); break; case FORMAT_SHORT: WriteCall(Pos_ReadIndex16_Short); break;
case FORMAT_FLOAT: WriteCall(Pos_ReadIndex16_Float); break; case FORMAT_FLOAT: WriteCall(Pos_ReadIndex16_Float); break;
default: _assert_(0); break; default: _assert_(0); break;
} }
break; break;
} }
// Normals // Normals
if (m_VtxDesc.Normal != NOT_PRESENT) if (m_VtxDesc.Normal != NOT_PRESENT)
{ {
VertexLoader_Normal::index3 = m_VtxAttr.NormalIndex3 ? true : false; VertexLoader_Normal::index3 = m_VtxAttr.NormalIndex3 ? true : false;
unsigned int uSize = VertexLoader_Normal::GetSize(m_VtxDesc.Normal, m_VtxAttr.NormalFormat, m_VtxAttr.NormalElements); unsigned int uSize = VertexLoader_Normal::GetSize(m_VtxDesc.Normal, m_VtxAttr.NormalFormat, m_VtxAttr.NormalElements);
TPipelineFunction pFunc = VertexLoader_Normal::GetFunction(m_VtxDesc.Normal, m_VtxAttr.NormalFormat, m_VtxAttr.NormalElements); TPipelineFunction pFunc = VertexLoader_Normal::GetFunction(m_VtxDesc.Normal, m_VtxAttr.NormalFormat, m_VtxAttr.NormalElements);
if (pFunc == 0) if (pFunc == 0)
{ {
char temp[256]; char temp[256];
sprintf(temp,"%i %i %i", m_VtxDesc.Normal, m_VtxAttr.NormalFormat, m_VtxAttr.NormalElements); sprintf(temp,"%i %i %i", m_VtxDesc.Normal, m_VtxAttr.NormalFormat, m_VtxAttr.NormalElements);
MessageBox(0,"VertexLoader_Normal::GetFunction returned zero!",temp,0); MessageBox(0,"VertexLoader_Normal::GetFunction returned zero!",temp,0);
} }
WriteCall(pFunc); WriteCall(pFunc);
m_VertexSize += uSize; m_VertexSize += uSize;
int m_numNormals = (m_VtxAttr.NormalElements == 1) ? NRM_THREE : NRM_ONE; int m_numNormals = (m_VtxAttr.NormalElements == 1) ? NRM_THREE : NRM_ONE;
m_components |= VB_HAS_NRM0; m_components |= VB_HAS_NRM0;
if (m_numNormals == NRM_THREE) if (m_numNormals == NRM_THREE)
m_components |= VB_HAS_NRM1 | VB_HAS_NRM2; m_components |= VB_HAS_NRM1 | VB_HAS_NRM2;
} }
// Colors // Colors
int col[2] = {m_VtxDesc.Color0, m_VtxDesc.Color1}; int col[2] = {m_VtxDesc.Color0, m_VtxDesc.Color1};
for (int i = 0; i < 2; i++) for (int i = 0; i < 2; i++)
SetupColor(i,col[i], m_VtxAttr.color[i].Comp, m_VtxAttr.color[i].Elements); SetupColor(i,col[i], m_VtxAttr.color[i].Comp, m_VtxAttr.color[i].Elements);
// TextureCoord // TextureCoord
// Since m_VtxDesc.Text7Coord is broken across a 32 bit word boundary, retrieve its value manually. // Since m_VtxDesc.Text7Coord is broken across a 32 bit word boundary, retrieve its value manually.
// If we didn't do this, the vertex format would be read as one bit offset from where it should be, making // If we didn't do this, the vertex format would be read as one bit offset from where it should be, making
// 01 become 00, and 10/11 become 01 // 01 become 00, and 10/11 become 01
int tc[8] = { int tc[8] = {
m_VtxDesc.Tex0Coord, m_VtxDesc.Tex1Coord, m_VtxDesc.Tex2Coord, m_VtxDesc.Tex3Coord, m_VtxDesc.Tex0Coord, m_VtxDesc.Tex1Coord, m_VtxDesc.Tex2Coord, m_VtxDesc.Tex3Coord,
m_VtxDesc.Tex4Coord, m_VtxDesc.Tex5Coord, m_VtxDesc.Tex6Coord, (m_VtxDesc.Hex >> 31) & 3 m_VtxDesc.Tex4Coord, m_VtxDesc.Tex5Coord, m_VtxDesc.Tex6Coord, (m_VtxDesc.Hex >> 31) & 3
}; };
for (int i = 0; i < 8; i++) for (int i = 0; i < 8; i++)
SetupTexCoord(i, tc[i], SetupTexCoord(i, tc[i],
m_VtxAttr.texCoord[i].Format, m_VtxAttr.texCoord[i].Format,
m_VtxAttr.texCoord[i].Elements, m_VtxAttr.texCoord[i].Elements,
m_VtxAttr.texCoord[i].Frac); m_VtxAttr.texCoord[i].Frac);
} }
void VertexLoader::SetupColor(int num, int mode, int format, int elements) void VertexLoader::SetupColor(int num, int mode, int format, int elements)
{ {
m_components |= VB_HAS_COL0 << num; m_components |= VB_HAS_COL0 << num;
switch (mode) switch (mode)
{ {
case NOT_PRESENT: case NOT_PRESENT:
m_components &= ~(VB_HAS_COL0 << num); m_components &= ~(VB_HAS_COL0 << num);
break; break;
case DIRECT: case DIRECT:
switch (format) switch (format)
{ {
case FORMAT_16B_565: m_VertexSize+=2; WriteCall(Color_ReadDirect_16b_565); break; case FORMAT_16B_565: m_VertexSize+=2; WriteCall(Color_ReadDirect_16b_565); break;
case FORMAT_24B_888: m_VertexSize+=3; WriteCall(Color_ReadDirect_24b_888); break; case FORMAT_24B_888: m_VertexSize+=3; WriteCall(Color_ReadDirect_24b_888); break;
case FORMAT_32B_888x: m_VertexSize+=4; WriteCall(Color_ReadDirect_32b_888x); break; case FORMAT_32B_888x: m_VertexSize+=4; WriteCall(Color_ReadDirect_32b_888x); break;
case FORMAT_16B_4444: m_VertexSize+=2; WriteCall(Color_ReadDirect_16b_4444); break; case FORMAT_16B_4444: m_VertexSize+=2; WriteCall(Color_ReadDirect_16b_4444); break;
case FORMAT_24B_6666: m_VertexSize+=3; WriteCall(Color_ReadDirect_24b_6666); break; case FORMAT_24B_6666: m_VertexSize+=3; WriteCall(Color_ReadDirect_24b_6666); break;
case FORMAT_32B_8888: m_VertexSize+=4; WriteCall(Color_ReadDirect_32b_8888); break; case FORMAT_32B_8888: m_VertexSize+=4; WriteCall(Color_ReadDirect_32b_8888); break;
default: _assert_(0); break; default: _assert_(0); break;
} }
break; break;
case INDEX8: case INDEX8:
switch (format) switch (format)
{ {
case FORMAT_16B_565: WriteCall(Color_ReadIndex8_16b_565); break; case FORMAT_16B_565: WriteCall(Color_ReadIndex8_16b_565); break;
case FORMAT_24B_888: WriteCall(Color_ReadIndex8_24b_888); break; case FORMAT_24B_888: WriteCall(Color_ReadIndex8_24b_888); break;
case FORMAT_32B_888x: WriteCall(Color_ReadIndex8_32b_888x); break; case FORMAT_32B_888x: WriteCall(Color_ReadIndex8_32b_888x); break;
case FORMAT_16B_4444: WriteCall(Color_ReadIndex8_16b_4444); break; case FORMAT_16B_4444: WriteCall(Color_ReadIndex8_16b_4444); break;
case FORMAT_24B_6666: WriteCall(Color_ReadIndex8_24b_6666); break; case FORMAT_24B_6666: WriteCall(Color_ReadIndex8_24b_6666); break;
case FORMAT_32B_8888: WriteCall(Color_ReadIndex8_32b_8888); break; case FORMAT_32B_8888: WriteCall(Color_ReadIndex8_32b_8888); break;
default: _assert_(0); break; default: _assert_(0); break;
} }
m_VertexSize+=1; m_VertexSize+=1;
break; break;
case INDEX16: case INDEX16:
switch (format) switch (format)
{ {
case FORMAT_16B_565: WriteCall(Color_ReadIndex16_16b_565); break; case FORMAT_16B_565: WriteCall(Color_ReadIndex16_16b_565); break;
case FORMAT_24B_888: WriteCall(Color_ReadIndex16_24b_888); break; case FORMAT_24B_888: WriteCall(Color_ReadIndex16_24b_888); break;
case FORMAT_32B_888x: WriteCall(Color_ReadIndex16_32b_888x); break; case FORMAT_32B_888x: WriteCall(Color_ReadIndex16_32b_888x); break;
case FORMAT_16B_4444: WriteCall(Color_ReadIndex16_16b_4444); break; case FORMAT_16B_4444: WriteCall(Color_ReadIndex16_16b_4444); break;
case FORMAT_24B_6666: WriteCall(Color_ReadIndex16_24b_6666); break; case FORMAT_24B_6666: WriteCall(Color_ReadIndex16_24b_6666); break;
case FORMAT_32B_8888: WriteCall(Color_ReadIndex16_32b_8888); break; case FORMAT_32B_8888: WriteCall(Color_ReadIndex16_32b_8888); break;
default: _assert_(0); break; default: _assert_(0); break;
} }
m_VertexSize+=2; m_VertexSize+=2;
break; break;
} }
} }
void VertexLoader::SetupTexCoord(int num, int mode, int format, int elements, int _iFrac) void VertexLoader::SetupTexCoord(int num, int mode, int format, int elements, int _iFrac)
{ {
m_components |= VB_HAS_UV0 << num; m_components |= VB_HAS_UV0 << num;
switch (mode) switch (mode)
{ {
case NOT_PRESENT: case NOT_PRESENT:
m_components &= ~(VB_HAS_UV0 << num); m_components &= ~(VB_HAS_UV0 << num);
break; break;
case DIRECT: case DIRECT:
{ {
int sizePro=0; int sizePro=0;
switch (format) switch (format)
{ {
case FORMAT_UBYTE: sizePro = 1; WriteCall(TexCoord_ReadDirect_UByte); break; case FORMAT_UBYTE: sizePro = 1; WriteCall(TexCoord_ReadDirect_UByte); break;
case FORMAT_BYTE: sizePro = 1; WriteCall(TexCoord_ReadDirect_Byte); break; case FORMAT_BYTE: sizePro = 1; WriteCall(TexCoord_ReadDirect_Byte); break;
case FORMAT_USHORT: sizePro = 2; WriteCall(TexCoord_ReadDirect_UShort); break; case FORMAT_USHORT: sizePro = 2; WriteCall(TexCoord_ReadDirect_UShort); break;
case FORMAT_SHORT: sizePro = 2; WriteCall(TexCoord_ReadDirect_Short); break; case FORMAT_SHORT: sizePro = 2; WriteCall(TexCoord_ReadDirect_Short); break;
case FORMAT_FLOAT: sizePro = 4; WriteCall(TexCoord_ReadDirect_Float); break; case FORMAT_FLOAT: sizePro = 4; WriteCall(TexCoord_ReadDirect_Float); break;
default: _assert_(0); break; default: _assert_(0); break;
} }
m_VertexSize += sizePro * (elements ? 2 : 1); m_VertexSize += sizePro * (elements ? 2 : 1);
} }
break; break;
case INDEX8: case INDEX8:
switch (format) switch (format)
{ {
case FORMAT_UBYTE: WriteCall(TexCoord_ReadIndex8_UByte); break; case FORMAT_UBYTE: WriteCall(TexCoord_ReadIndex8_UByte); break;
case FORMAT_BYTE: WriteCall(TexCoord_ReadIndex8_Byte); break; case FORMAT_BYTE: WriteCall(TexCoord_ReadIndex8_Byte); break;
case FORMAT_USHORT: WriteCall(TexCoord_ReadIndex8_UShort); break; case FORMAT_USHORT: WriteCall(TexCoord_ReadIndex8_UShort); break;
case FORMAT_SHORT: WriteCall(TexCoord_ReadIndex8_Short); break; case FORMAT_SHORT: WriteCall(TexCoord_ReadIndex8_Short); break;
case FORMAT_FLOAT: WriteCall(TexCoord_ReadIndex8_Float); break; case FORMAT_FLOAT: WriteCall(TexCoord_ReadIndex8_Float); break;
default: _assert_(0); break; default: _assert_(0); break;
} }
m_VertexSize+=1; m_VertexSize+=1;
break; break;
case INDEX16: case INDEX16:
switch (format) switch (format)
{ {
case FORMAT_UBYTE: WriteCall(TexCoord_ReadIndex16_UByte); break; case FORMAT_UBYTE: WriteCall(TexCoord_ReadIndex16_UByte); break;
case FORMAT_BYTE: WriteCall(TexCoord_ReadIndex16_Byte); break; case FORMAT_BYTE: WriteCall(TexCoord_ReadIndex16_Byte); break;
case FORMAT_USHORT: WriteCall(TexCoord_ReadIndex16_UShort); break; case FORMAT_USHORT: WriteCall(TexCoord_ReadIndex16_UShort); break;
case FORMAT_SHORT: WriteCall(TexCoord_ReadIndex16_Short); break; case FORMAT_SHORT: WriteCall(TexCoord_ReadIndex16_Short); break;
case FORMAT_FLOAT: WriteCall(TexCoord_ReadIndex16_Float); break; case FORMAT_FLOAT: WriteCall(TexCoord_ReadIndex16_Float); break;
default: _assert_(0); default: _assert_(0);
} }
m_VertexSize+=2; m_VertexSize+=2;
break; break;
} }
} }
void VertexLoader::WriteCall(TPipelineFunction func) void VertexLoader::WriteCall(TPipelineFunction func)
{ {
m_PipelineStates[m_numPipelineStates++] = func; m_PipelineStates[m_numPipelineStates++] = func;
} }
using namespace Gen; using namespace Gen;
void VertexLoader::PrepareRun() void VertexLoader::PrepareRun()
{ {
posScale = shiftLookup[m_VtxAttr.PosFrac]; posScale = shiftLookup[m_VtxAttr.PosFrac];
for (int i = 0; i < 8; i++) for (int i = 0; i < 8; i++)
{ {
tcScaleU[i] = shiftLookup[m_VtxAttr.texCoord[i].Frac]; tcScaleU[i] = shiftLookup[m_VtxAttr.texCoord[i].Frac];
tcScaleV[i] = shiftLookup[m_VtxAttr.texCoord[i].Frac]; tcScaleV[i] = shiftLookup[m_VtxAttr.texCoord[i].Frac];
tcElements[i] = m_VtxAttr.texCoord[i].Elements; tcElements[i] = m_VtxAttr.texCoord[i].Elements;
tcFormat[i] = m_VtxAttr.texCoord[i].Format; tcFormat[i] = m_VtxAttr.texCoord[i].Format;
} }
for (int i = 0; i < 2; i++) for (int i = 0; i < 2; i++)
colElements[i] = m_VtxAttr.color[i].Elements; colElements[i] = m_VtxAttr.color[i].Elements;
varray->SetComponents(m_components); varray->SetComponents(m_components);
} }
void VertexLoader::RunVertices(int count) void VertexLoader::RunVertices(int count)
{ {
DVSTARTPROFILE(); DVSTARTPROFILE();
for (int v = 0; v < count; v++) for (int v = 0; v < count; v++)
{ {
tcIndex = 0; tcIndex = 0;
colIndex = 0; colIndex = 0;
s_texmtxread = 0; s_texmtxread = 0;
for (int i = 0; i < m_numPipelineStates; i++) for (int i = 0; i < m_numPipelineStates; i++)
{ {
m_PipelineStates[i](&m_VtxAttr); m_PipelineStates[i](&m_VtxAttr);
} }
varray->Next(); varray->Next();
} }
/* /*
This is not the bottleneck ATM, so compiling etc doesn't really help. This is not the bottleneck ATM, so compiling etc doesn't really help.
At least not when all we do is compile it to a list of function calls. At least not when all we do is compile it to a list of function calls.
Should help more when we inline, but this requires the new vertex format. Should help more when we inline, but this requires the new vertex format.
Maybe later, and with smarter caching. Maybe later, and with smarter caching.
if (count) if (count)
{ {
this->m_counter = count; this->m_counter = count;
((void (*)())((void*)&m_compiledCode[0]))(); ((void (*)())((void*)&m_compiledCode[0]))();
}*/ }*/
} }

View File

@ -1,488 +1,488 @@
// 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 "main.h" #include "main.h"
#include "Utils.h" #include "Utils.h"
#include "DecodedVArray.h" #include "DecodedVArray.h"
#include "VertexLoader.h" #include "VertexLoader.h"
#include "VertexLoader_Normal.h" #include "VertexLoader_Normal.h"
u8 VertexLoader_Normal::m_sizeTable[NUM_NRM_TYPE][NUM_NRM_FORMAT][NUM_NRM_ELEMENTS]; u8 VertexLoader_Normal::m_sizeTable[NUM_NRM_TYPE][NUM_NRM_FORMAT][NUM_NRM_ELEMENTS];
TPipelineFunction VertexLoader_Normal::m_funcTable[NUM_NRM_TYPE][NUM_NRM_FORMAT][NUM_NRM_ELEMENTS]; TPipelineFunction VertexLoader_Normal::m_funcTable[NUM_NRM_TYPE][NUM_NRM_FORMAT][NUM_NRM_ELEMENTS];
bool VertexLoader_Normal::index3; bool VertexLoader_Normal::index3;
// __________________________________________________________________________________________________ // __________________________________________________________________________________________________
// Init // Init
// //
void VertexLoader_Normal::Init(void) void VertexLoader_Normal::Init(void)
{ {
// size table // size table
m_sizeTable[NRM_DIRECT][FORMAT_UBYTE] [NRM_NBT] = 3; m_sizeTable[NRM_DIRECT][FORMAT_UBYTE] [NRM_NBT] = 3;
m_sizeTable[NRM_DIRECT][FORMAT_BYTE] [NRM_NBT] = 3; m_sizeTable[NRM_DIRECT][FORMAT_BYTE] [NRM_NBT] = 3;
m_sizeTable[NRM_DIRECT][FORMAT_USHORT][NRM_NBT] = 6; m_sizeTable[NRM_DIRECT][FORMAT_USHORT][NRM_NBT] = 6;
m_sizeTable[NRM_DIRECT][FORMAT_SHORT] [NRM_NBT] = 6; m_sizeTable[NRM_DIRECT][FORMAT_SHORT] [NRM_NBT] = 6;
m_sizeTable[NRM_DIRECT][FORMAT_FLOAT] [NRM_NBT] = 12; m_sizeTable[NRM_DIRECT][FORMAT_FLOAT] [NRM_NBT] = 12;
m_sizeTable[NRM_DIRECT][FORMAT_UBYTE] [NRM_NBT3] = 9; m_sizeTable[NRM_DIRECT][FORMAT_UBYTE] [NRM_NBT3] = 9;
m_sizeTable[NRM_DIRECT][FORMAT_BYTE] [NRM_NBT3] = 9; m_sizeTable[NRM_DIRECT][FORMAT_BYTE] [NRM_NBT3] = 9;
m_sizeTable[NRM_DIRECT][FORMAT_USHORT][NRM_NBT3] = 18; m_sizeTable[NRM_DIRECT][FORMAT_USHORT][NRM_NBT3] = 18;
m_sizeTable[NRM_DIRECT][FORMAT_SHORT] [NRM_NBT3] = 18; m_sizeTable[NRM_DIRECT][FORMAT_SHORT] [NRM_NBT3] = 18;
m_sizeTable[NRM_DIRECT][FORMAT_FLOAT] [NRM_NBT3] = 36; m_sizeTable[NRM_DIRECT][FORMAT_FLOAT] [NRM_NBT3] = 36;
m_sizeTable[NRM_INDEX8][FORMAT_UBYTE] [NRM_NBT] = 1; m_sizeTable[NRM_INDEX8][FORMAT_UBYTE] [NRM_NBT] = 1;
m_sizeTable[NRM_INDEX8][FORMAT_BYTE] [NRM_NBT] = 1; m_sizeTable[NRM_INDEX8][FORMAT_BYTE] [NRM_NBT] = 1;
m_sizeTable[NRM_INDEX8][FORMAT_USHORT][NRM_NBT] = 1; m_sizeTable[NRM_INDEX8][FORMAT_USHORT][NRM_NBT] = 1;
m_sizeTable[NRM_INDEX8][FORMAT_SHORT] [NRM_NBT] = 1; m_sizeTable[NRM_INDEX8][FORMAT_SHORT] [NRM_NBT] = 1;
m_sizeTable[NRM_INDEX8][FORMAT_FLOAT] [NRM_NBT] = 1; m_sizeTable[NRM_INDEX8][FORMAT_FLOAT] [NRM_NBT] = 1;
m_sizeTable[NRM_INDEX8][FORMAT_UBYTE] [NRM_NBT3] = 3; m_sizeTable[NRM_INDEX8][FORMAT_UBYTE] [NRM_NBT3] = 3;
m_sizeTable[NRM_INDEX8][FORMAT_BYTE] [NRM_NBT3] = 3; m_sizeTable[NRM_INDEX8][FORMAT_BYTE] [NRM_NBT3] = 3;
m_sizeTable[NRM_INDEX8][FORMAT_USHORT][NRM_NBT3] = 3; m_sizeTable[NRM_INDEX8][FORMAT_USHORT][NRM_NBT3] = 3;
m_sizeTable[NRM_INDEX8][FORMAT_SHORT] [NRM_NBT3] = 3; m_sizeTable[NRM_INDEX8][FORMAT_SHORT] [NRM_NBT3] = 3;
m_sizeTable[NRM_INDEX8][FORMAT_FLOAT] [NRM_NBT3] = 3; m_sizeTable[NRM_INDEX8][FORMAT_FLOAT] [NRM_NBT3] = 3;
m_sizeTable[NRM_INDEX16][FORMAT_UBYTE] [NRM_NBT] = 2; m_sizeTable[NRM_INDEX16][FORMAT_UBYTE] [NRM_NBT] = 2;
m_sizeTable[NRM_INDEX16][FORMAT_BYTE] [NRM_NBT] = 2; m_sizeTable[NRM_INDEX16][FORMAT_BYTE] [NRM_NBT] = 2;
m_sizeTable[NRM_INDEX16][FORMAT_USHORT][NRM_NBT] = 2; m_sizeTable[NRM_INDEX16][FORMAT_USHORT][NRM_NBT] = 2;
m_sizeTable[NRM_INDEX16][FORMAT_SHORT] [NRM_NBT] = 2; m_sizeTable[NRM_INDEX16][FORMAT_SHORT] [NRM_NBT] = 2;
m_sizeTable[NRM_INDEX16][FORMAT_FLOAT] [NRM_NBT] = 2; m_sizeTable[NRM_INDEX16][FORMAT_FLOAT] [NRM_NBT] = 2;
m_sizeTable[NRM_INDEX16][FORMAT_UBYTE] [NRM_NBT3] = 6; m_sizeTable[NRM_INDEX16][FORMAT_UBYTE] [NRM_NBT3] = 6;
m_sizeTable[NRM_INDEX16][FORMAT_BYTE] [NRM_NBT3] = 6; m_sizeTable[NRM_INDEX16][FORMAT_BYTE] [NRM_NBT3] = 6;
m_sizeTable[NRM_INDEX16][FORMAT_USHORT][NRM_NBT3] = 6; m_sizeTable[NRM_INDEX16][FORMAT_USHORT][NRM_NBT3] = 6;
m_sizeTable[NRM_INDEX16][FORMAT_SHORT] [NRM_NBT3] = 6; m_sizeTable[NRM_INDEX16][FORMAT_SHORT] [NRM_NBT3] = 6;
m_sizeTable[NRM_INDEX16][FORMAT_FLOAT] [NRM_NBT3] = 6; m_sizeTable[NRM_INDEX16][FORMAT_FLOAT] [NRM_NBT3] = 6;
// function table // function table
m_funcTable[NRM_DIRECT][FORMAT_UBYTE] [NRM_NBT] = Normal_DirectByte; //HACK m_funcTable[NRM_DIRECT][FORMAT_UBYTE] [NRM_NBT] = Normal_DirectByte; //HACK
m_funcTable[NRM_DIRECT][FORMAT_BYTE] [NRM_NBT] = Normal_DirectByte; m_funcTable[NRM_DIRECT][FORMAT_BYTE] [NRM_NBT] = Normal_DirectByte;
m_funcTable[NRM_DIRECT][FORMAT_USHORT][NRM_NBT] = Normal_DirectShort; //HACK m_funcTable[NRM_DIRECT][FORMAT_USHORT][NRM_NBT] = Normal_DirectShort; //HACK
m_funcTable[NRM_DIRECT][FORMAT_SHORT] [NRM_NBT] = Normal_DirectShort; m_funcTable[NRM_DIRECT][FORMAT_SHORT] [NRM_NBT] = Normal_DirectShort;
m_funcTable[NRM_DIRECT][FORMAT_FLOAT] [NRM_NBT] = Normal_DirectFloat; m_funcTable[NRM_DIRECT][FORMAT_FLOAT] [NRM_NBT] = Normal_DirectFloat;
m_funcTable[NRM_DIRECT][FORMAT_UBYTE] [NRM_NBT3] = Normal_DirectByte3; //HACK m_funcTable[NRM_DIRECT][FORMAT_UBYTE] [NRM_NBT3] = Normal_DirectByte3; //HACK
m_funcTable[NRM_DIRECT][FORMAT_BYTE] [NRM_NBT3] = Normal_DirectByte3; m_funcTable[NRM_DIRECT][FORMAT_BYTE] [NRM_NBT3] = Normal_DirectByte3;
m_funcTable[NRM_DIRECT][FORMAT_USHORT][NRM_NBT3] = Normal_DirectShort3; //HACK m_funcTable[NRM_DIRECT][FORMAT_USHORT][NRM_NBT3] = Normal_DirectShort3; //HACK
m_funcTable[NRM_DIRECT][FORMAT_SHORT] [NRM_NBT3] = Normal_DirectShort3; m_funcTable[NRM_DIRECT][FORMAT_SHORT] [NRM_NBT3] = Normal_DirectShort3;
m_funcTable[NRM_DIRECT][FORMAT_FLOAT] [NRM_NBT3] = Normal_DirectFloat3; m_funcTable[NRM_DIRECT][FORMAT_FLOAT] [NRM_NBT3] = Normal_DirectFloat3;
m_funcTable[NRM_INDEX8][FORMAT_UBYTE] [NRM_NBT] = Normal_Index8_Byte; //HACK m_funcTable[NRM_INDEX8][FORMAT_UBYTE] [NRM_NBT] = Normal_Index8_Byte; //HACK
m_funcTable[NRM_INDEX8][FORMAT_BYTE] [NRM_NBT] = Normal_Index8_Byte; m_funcTable[NRM_INDEX8][FORMAT_BYTE] [NRM_NBT] = Normal_Index8_Byte;
m_funcTable[NRM_INDEX8][FORMAT_USHORT][NRM_NBT] = Normal_Index8_Short; //HACK m_funcTable[NRM_INDEX8][FORMAT_USHORT][NRM_NBT] = Normal_Index8_Short; //HACK
m_funcTable[NRM_INDEX8][FORMAT_SHORT] [NRM_NBT] = Normal_Index8_Short; m_funcTable[NRM_INDEX8][FORMAT_SHORT] [NRM_NBT] = Normal_Index8_Short;
m_funcTable[NRM_INDEX8][FORMAT_FLOAT] [NRM_NBT] = Normal_Index8_Float; m_funcTable[NRM_INDEX8][FORMAT_FLOAT] [NRM_NBT] = Normal_Index8_Float;
m_funcTable[NRM_INDEX8][FORMAT_UBYTE] [NRM_NBT3] = Normal_Index8_Byte3; //HACK m_funcTable[NRM_INDEX8][FORMAT_UBYTE] [NRM_NBT3] = Normal_Index8_Byte3; //HACK
m_funcTable[NRM_INDEX8][FORMAT_BYTE] [NRM_NBT3] = Normal_Index8_Byte3; m_funcTable[NRM_INDEX8][FORMAT_BYTE] [NRM_NBT3] = Normal_Index8_Byte3;
m_funcTable[NRM_INDEX8][FORMAT_USHORT][NRM_NBT3] = Normal_Index8_Short3; //HACK m_funcTable[NRM_INDEX8][FORMAT_USHORT][NRM_NBT3] = Normal_Index8_Short3; //HACK
m_funcTable[NRM_INDEX8][FORMAT_SHORT] [NRM_NBT3] = Normal_Index8_Short3; m_funcTable[NRM_INDEX8][FORMAT_SHORT] [NRM_NBT3] = Normal_Index8_Short3;
m_funcTable[NRM_INDEX8][FORMAT_FLOAT] [NRM_NBT3] = Normal_Index8_Float3; m_funcTable[NRM_INDEX8][FORMAT_FLOAT] [NRM_NBT3] = Normal_Index8_Float3;
m_funcTable[NRM_INDEX16][FORMAT_UBYTE] [NRM_NBT] = Normal_Index16_Byte; //HACK m_funcTable[NRM_INDEX16][FORMAT_UBYTE] [NRM_NBT] = Normal_Index16_Byte; //HACK
m_funcTable[NRM_INDEX16][FORMAT_BYTE] [NRM_NBT] = Normal_Index16_Byte; m_funcTable[NRM_INDEX16][FORMAT_BYTE] [NRM_NBT] = Normal_Index16_Byte;
m_funcTable[NRM_INDEX16][FORMAT_USHORT][NRM_NBT] = Normal_Index16_Short; //HACK m_funcTable[NRM_INDEX16][FORMAT_USHORT][NRM_NBT] = Normal_Index16_Short; //HACK
m_funcTable[NRM_INDEX16][FORMAT_SHORT] [NRM_NBT] = Normal_Index16_Short; m_funcTable[NRM_INDEX16][FORMAT_SHORT] [NRM_NBT] = Normal_Index16_Short;
m_funcTable[NRM_INDEX16][FORMAT_FLOAT] [NRM_NBT] = Normal_Index16_Float; m_funcTable[NRM_INDEX16][FORMAT_FLOAT] [NRM_NBT] = Normal_Index16_Float;
m_funcTable[NRM_INDEX16][FORMAT_UBYTE] [NRM_NBT3] = Normal_Index16_Byte3; //HACK m_funcTable[NRM_INDEX16][FORMAT_UBYTE] [NRM_NBT3] = Normal_Index16_Byte3; //HACK
m_funcTable[NRM_INDEX16][FORMAT_BYTE] [NRM_NBT3] = Normal_Index16_Byte3; m_funcTable[NRM_INDEX16][FORMAT_BYTE] [NRM_NBT3] = Normal_Index16_Byte3;
m_funcTable[NRM_INDEX16][FORMAT_USHORT][NRM_NBT3] = Normal_Index16_Short3; //HACK m_funcTable[NRM_INDEX16][FORMAT_USHORT][NRM_NBT3] = Normal_Index16_Short3; //HACK
m_funcTable[NRM_INDEX16][FORMAT_SHORT] [NRM_NBT3] = Normal_Index16_Short3; m_funcTable[NRM_INDEX16][FORMAT_SHORT] [NRM_NBT3] = Normal_Index16_Short3;
m_funcTable[NRM_INDEX16][FORMAT_FLOAT] [NRM_NBT3] = Normal_Index16_Float3; m_funcTable[NRM_INDEX16][FORMAT_FLOAT] [NRM_NBT3] = Normal_Index16_Float3;
} }
// __________________________________________________________________________________________________ // __________________________________________________________________________________________________
// GetSize // GetSize
// //
unsigned int unsigned int
VertexLoader_Normal::GetSize(unsigned int _type, unsigned int _format, unsigned int _elements) VertexLoader_Normal::GetSize(unsigned int _type, unsigned int _format, unsigned int _elements)
{ {
return m_sizeTable[_type][_format][_elements]; return m_sizeTable[_type][_format][_elements];
} }
// __________________________________________________________________________________________________ // __________________________________________________________________________________________________
// GetFunction // GetFunction
// //
TPipelineFunction TPipelineFunction
VertexLoader_Normal::GetFunction(unsigned int _type, unsigned int _format, unsigned int _elements) VertexLoader_Normal::GetFunction(unsigned int _type, unsigned int _format, unsigned int _elements)
{ {
TPipelineFunction pFunc = m_funcTable[_type][_format][_elements]; TPipelineFunction pFunc = m_funcTable[_type][_format][_elements];
return pFunc; return pFunc;
} }
///////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// --- Direct --- // --- Direct ---
// //
///////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////
// __________________________________________________________________________________________________ // __________________________________________________________________________________________________
// Normal_DirectByte // Normal_DirectByte
// //
void LOADERDECL void LOADERDECL
VertexLoader_Normal::Normal_DirectByte(const void* _p) VertexLoader_Normal::Normal_DirectByte(const void* _p)
{ {
varray->SetNormalX(0, ((float)(signed char)DataReadU8()+0.5f) / 127.5f); varray->SetNormalX(0, ((float)(signed char)DataReadU8()+0.5f) / 127.5f);
varray->SetNormalY(0, ((float)(signed char)DataReadU8()+0.5f) / 127.5f); varray->SetNormalY(0, ((float)(signed char)DataReadU8()+0.5f) / 127.5f);
varray->SetNormalZ(0, ((float)(signed char)DataReadU8()+0.5f) / 127.5f); varray->SetNormalZ(0, ((float)(signed char)DataReadU8()+0.5f) / 127.5f);
} }
// __________________________________________________________________________________________________ // __________________________________________________________________________________________________
// Normal_DirectShort // Normal_DirectShort
// //
void LOADERDECL void LOADERDECL
VertexLoader_Normal::Normal_DirectShort(const void* _p) VertexLoader_Normal::Normal_DirectShort(const void* _p)
{ {
varray->SetNormalX(0, ((float)(signed short)DataReadU16()+0.5f) / 32767.5f); varray->SetNormalX(0, ((float)(signed short)DataReadU16()+0.5f) / 32767.5f);
varray->SetNormalY(0, ((float)(signed short)DataReadU16()+0.5f) / 32767.5f); varray->SetNormalY(0, ((float)(signed short)DataReadU16()+0.5f) / 32767.5f);
varray->SetNormalZ(0, ((float)(signed short)DataReadU16()+0.5f) / 32767.5f); varray->SetNormalZ(0, ((float)(signed short)DataReadU16()+0.5f) / 32767.5f);
} }
// __________________________________________________________________________________________________ // __________________________________________________________________________________________________
// Normal_DirectFloat // Normal_DirectFloat
// //
void LOADERDECL void LOADERDECL
VertexLoader_Normal::Normal_DirectFloat(const void* _p) VertexLoader_Normal::Normal_DirectFloat(const void* _p)
{ {
varray->SetNormalX(0, DataReadF32()); varray->SetNormalX(0, DataReadF32());
varray->SetNormalY(0, DataReadF32()); varray->SetNormalY(0, DataReadF32());
varray->SetNormalZ(0, DataReadF32()); varray->SetNormalZ(0, DataReadF32());
} }
// __________________________________________________________________________________________________ // __________________________________________________________________________________________________
// Normal_DirectByte3 // Normal_DirectByte3
// //
void LOADERDECL void LOADERDECL
VertexLoader_Normal::Normal_DirectByte3(const void* _p) VertexLoader_Normal::Normal_DirectByte3(const void* _p)
{ {
for (int i=0; i<3; i++) for (int i=0; i<3; i++)
{ {
varray->SetNormalX(i, ((float)(signed char)DataReadU8()+0.5f) / 127.5f); varray->SetNormalX(i, ((float)(signed char)DataReadU8()+0.5f) / 127.5f);
varray->SetNormalY(i, ((float)(signed char)DataReadU8()+0.5f) / 127.5f); varray->SetNormalY(i, ((float)(signed char)DataReadU8()+0.5f) / 127.5f);
varray->SetNormalZ(i, ((float)(signed char)DataReadU8()+0.5f) / 127.5f); varray->SetNormalZ(i, ((float)(signed char)DataReadU8()+0.5f) / 127.5f);
} }
} }
// __________________________________________________________________________________________________ // __________________________________________________________________________________________________
// Normal_DirectShort3 // Normal_DirectShort3
// //
void LOADERDECL void LOADERDECL
VertexLoader_Normal::Normal_DirectShort3(const void* _p) VertexLoader_Normal::Normal_DirectShort3(const void* _p)
{ {
for (int i=0; i<3; i++) for (int i=0; i<3; i++)
{ {
varray->SetNormalX(i, ((float)(signed short)DataReadU16()+0.5f) / 32767.5f); varray->SetNormalX(i, ((float)(signed short)DataReadU16()+0.5f) / 32767.5f);
varray->SetNormalY(i, ((float)(signed short)DataReadU16()+0.5f) / 32767.5f); varray->SetNormalY(i, ((float)(signed short)DataReadU16()+0.5f) / 32767.5f);
varray->SetNormalZ(i, ((float)(signed short)DataReadU16()+0.5f) / 32767.5f); varray->SetNormalZ(i, ((float)(signed short)DataReadU16()+0.5f) / 32767.5f);
} }
} }
// __________________________________________________________________________________________________ // __________________________________________________________________________________________________
// Normal_DirectFloat3 // Normal_DirectFloat3
// //
void LOADERDECL void LOADERDECL
VertexLoader_Normal::Normal_DirectFloat3(const void* _p) VertexLoader_Normal::Normal_DirectFloat3(const void* _p)
{ {
for (int i=0; i<3; i++) for (int i=0; i<3; i++)
{ {
varray->SetNormalX(i, DataReadF32()); varray->SetNormalX(i, DataReadF32());
varray->SetNormalY(i, DataReadF32()); varray->SetNormalY(i, DataReadF32());
varray->SetNormalZ(i, DataReadF32()); varray->SetNormalZ(i, DataReadF32());
} }
} }
///////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// --- Index8 --- // --- Index8 ---
// //
///////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////
// __________________________________________________________________________________________________ // __________________________________________________________________________________________________
// Normal_Index8_Byte // Normal_Index8_Byte
// //
void LOADERDECL void LOADERDECL
VertexLoader_Normal::Normal_Index8_Byte(const void* _p) VertexLoader_Normal::Normal_Index8_Byte(const void* _p)
{ {
u8 Index = DataReadU8(); u8 Index = DataReadU8();
u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]); u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]);
varray->SetNormalX(0, ((float)(signed char)Memory_Read_U8(iAddress )+0.5f) / 127.5f); varray->SetNormalX(0, ((float)(signed char)Memory_Read_U8(iAddress )+0.5f) / 127.5f);
varray->SetNormalY(0, ((float)(signed char)Memory_Read_U8(iAddress+1)+0.5f) / 127.5f); varray->SetNormalY(0, ((float)(signed char)Memory_Read_U8(iAddress+1)+0.5f) / 127.5f);
varray->SetNormalZ(0, ((float)(signed char)Memory_Read_U8(iAddress+2)+0.5f) / 127.5f); varray->SetNormalZ(0, ((float)(signed char)Memory_Read_U8(iAddress+2)+0.5f) / 127.5f);
} }
// __________________________________________________________________________________________________ // __________________________________________________________________________________________________
// Normal_Index8_Short // Normal_Index8_Short
// //
void LOADERDECL void LOADERDECL
VertexLoader_Normal::Normal_Index8_Short(const void* _p) VertexLoader_Normal::Normal_Index8_Short(const void* _p)
{ {
u8 Index = DataReadU8(); u8 Index = DataReadU8();
u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]); u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]);
varray->SetNormalX(0, ((float)(signed short)Memory_Read_U16(iAddress )+0.5f) / 32767.5f); varray->SetNormalX(0, ((float)(signed short)Memory_Read_U16(iAddress )+0.5f) / 32767.5f);
varray->SetNormalY(0, ((float)(signed short)Memory_Read_U16(iAddress+2)+0.5f) / 32767.5f); varray->SetNormalY(0, ((float)(signed short)Memory_Read_U16(iAddress+2)+0.5f) / 32767.5f);
varray->SetNormalZ(0, ((float)(signed short)Memory_Read_U16(iAddress+4)+0.5f) / 32767.5f); varray->SetNormalZ(0, ((float)(signed short)Memory_Read_U16(iAddress+4)+0.5f) / 32767.5f);
} }
// __________________________________________________________________________________________________ // __________________________________________________________________________________________________
// Normal_Index8_Float // Normal_Index8_Float
// //
void LOADERDECL void LOADERDECL
VertexLoader_Normal::Normal_Index8_Float(const void* _p) VertexLoader_Normal::Normal_Index8_Float(const void* _p)
{ {
u8 Index = DataReadU8(); u8 Index = DataReadU8();
u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]); u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]);
varray->SetNormalX(0, Memory_Read_Float(iAddress)); varray->SetNormalX(0, Memory_Read_Float(iAddress));
varray->SetNormalY(0, Memory_Read_Float(iAddress+4)); varray->SetNormalY(0, Memory_Read_Float(iAddress+4));
varray->SetNormalZ(0, Memory_Read_Float(iAddress+8)); varray->SetNormalZ(0, Memory_Read_Float(iAddress+8));
} }
// __________________________________________________________________________________________________ // __________________________________________________________________________________________________
// Normal_Index8_Byte3 // Normal_Index8_Byte3
// //
void LOADERDECL void LOADERDECL
VertexLoader_Normal::Normal_Index8_Byte3(const void* _p) VertexLoader_Normal::Normal_Index8_Byte3(const void* _p)
{ {
if (index3) if (index3)
{ {
for (int i=0; i<3; i++) for (int i=0; i<3; i++)
{ {
u8 Index = DataReadU8(); u8 Index = DataReadU8();
u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]) + 1*3*i; u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]) + 1*3*i;
varray->SetNormalX(i, ((float)(signed char)Memory_Read_U8(iAddress )+0.5f) / 127.5f); varray->SetNormalX(i, ((float)(signed char)Memory_Read_U8(iAddress )+0.5f) / 127.5f);
varray->SetNormalY(i, ((float)(signed char)Memory_Read_U8(iAddress+1)+0.5f) / 127.5f); varray->SetNormalY(i, ((float)(signed char)Memory_Read_U8(iAddress+1)+0.5f) / 127.5f);
varray->SetNormalZ(i, ((float)(signed char)Memory_Read_U8(iAddress+2)+0.5f) / 127.5f); varray->SetNormalZ(i, ((float)(signed char)Memory_Read_U8(iAddress+2)+0.5f) / 127.5f);
} }
} }
else else
{ {
u8 Index = DataReadU8(); u8 Index = DataReadU8();
for (int i=0; i<3; i++) for (int i=0; i<3; i++)
{ {
u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]) + 1*3*i; u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]) + 1*3*i;
varray->SetNormalX(i, ((float)(signed char)Memory_Read_U8(iAddress )+0.5f) / 127.5f); varray->SetNormalX(i, ((float)(signed char)Memory_Read_U8(iAddress )+0.5f) / 127.5f);
varray->SetNormalY(i, ((float)(signed char)Memory_Read_U8(iAddress+1)+0.5f) / 127.5f); varray->SetNormalY(i, ((float)(signed char)Memory_Read_U8(iAddress+1)+0.5f) / 127.5f);
varray->SetNormalZ(i, ((float)(signed char)Memory_Read_U8(iAddress+2)+0.5f) / 127.5f); varray->SetNormalZ(i, ((float)(signed char)Memory_Read_U8(iAddress+2)+0.5f) / 127.5f);
} }
} }
} }
// __________________________________________________________________________________________________ // __________________________________________________________________________________________________
// Normal_Index8_Short3 // Normal_Index8_Short3
// //
void LOADERDECL void LOADERDECL
VertexLoader_Normal::Normal_Index8_Short3(const void* _p) VertexLoader_Normal::Normal_Index8_Short3(const void* _p)
{ {
if (index3) if (index3)
{ {
for (int i=0; i<3; i++) for (int i=0; i<3; i++)
{ {
u8 Index = DataReadU8(); u8 Index = DataReadU8();
u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]) + 2*3*i; u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]) + 2*3*i;
varray->SetNormalX(i, ((float)(signed short)Memory_Read_U16(iAddress )+0.5f) / 32767.5f); varray->SetNormalX(i, ((float)(signed short)Memory_Read_U16(iAddress )+0.5f) / 32767.5f);
varray->SetNormalY(i, ((float)(signed short)Memory_Read_U16(iAddress+2)+0.5f) / 32767.5f); varray->SetNormalY(i, ((float)(signed short)Memory_Read_U16(iAddress+2)+0.5f) / 32767.5f);
varray->SetNormalZ(i, ((float)(signed short)Memory_Read_U16(iAddress+4)+0.5f) / 32767.5f); varray->SetNormalZ(i, ((float)(signed short)Memory_Read_U16(iAddress+4)+0.5f) / 32767.5f);
} }
} }
else else
{ {
u8 Index = DataReadU8(); u8 Index = DataReadU8();
for (int i=0; i<3; i++) for (int i=0; i<3; i++)
{ {
u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]) + 2*3*i; u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]) + 2*3*i;
varray->SetNormalX(i, ((float)(signed short)Memory_Read_U16(iAddress )+0.5f) / 32767.5f); varray->SetNormalX(i, ((float)(signed short)Memory_Read_U16(iAddress )+0.5f) / 32767.5f);
varray->SetNormalY(i, ((float)(signed short)Memory_Read_U16(iAddress+2)+0.5f) / 32767.5f); varray->SetNormalY(i, ((float)(signed short)Memory_Read_U16(iAddress+2)+0.5f) / 32767.5f);
varray->SetNormalZ(i, ((float)(signed short)Memory_Read_U16(iAddress+4)+0.5f) / 32767.5f); varray->SetNormalZ(i, ((float)(signed short)Memory_Read_U16(iAddress+4)+0.5f) / 32767.5f);
} }
} }
} }
// __________________________________________________________________________________________________ // __________________________________________________________________________________________________
// Normal_Index8_Float3 // Normal_Index8_Float3
// //
void LOADERDECL void LOADERDECL
VertexLoader_Normal::Normal_Index8_Float3(const void* _p) VertexLoader_Normal::Normal_Index8_Float3(const void* _p)
{ {
if (index3) if (index3)
{ {
for (int i=0; i<3; i++) for (int i=0; i<3; i++)
{ {
u8 Index = DataReadU8(); u8 Index = DataReadU8();
u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]) + 4*3*i; u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]) + 4*3*i;
varray->SetNormalX(i, Memory_Read_Float(iAddress)); varray->SetNormalX(i, Memory_Read_Float(iAddress));
varray->SetNormalY(i, Memory_Read_Float(iAddress+4)); varray->SetNormalY(i, Memory_Read_Float(iAddress+4));
varray->SetNormalZ(i, Memory_Read_Float(iAddress+8)); varray->SetNormalZ(i, Memory_Read_Float(iAddress+8));
} }
} }
else else
{ {
u8 Index = DataReadU8(); u8 Index = DataReadU8();
for (int i=0; i<3; i++) for (int i=0; i<3; i++)
{ {
u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]) + 4*3*i; u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]) + 4*3*i;
varray->SetNormalX(i, Memory_Read_Float(iAddress)); varray->SetNormalX(i, Memory_Read_Float(iAddress));
varray->SetNormalY(i, Memory_Read_Float(iAddress+4)); varray->SetNormalY(i, Memory_Read_Float(iAddress+4));
varray->SetNormalZ(i, Memory_Read_Float(iAddress+8)); varray->SetNormalZ(i, Memory_Read_Float(iAddress+8));
} }
} }
} }
///////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////
// //
// --- Index16 --- // --- Index16 ---
// //
///////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////
// __________________________________________________________________________________________________ // __________________________________________________________________________________________________
// Normal_Index16_Byte // Normal_Index16_Byte
// //
void LOADERDECL void LOADERDECL
VertexLoader_Normal::Normal_Index16_Byte(const void* _p) VertexLoader_Normal::Normal_Index16_Byte(const void* _p)
{ {
u16 Index = DataReadU16(); u16 Index = DataReadU16();
u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]); u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]);
varray->SetNormalX(0, ((float)(signed char)Memory_Read_U8(iAddress )+0.5f) / 127.5f); varray->SetNormalX(0, ((float)(signed char)Memory_Read_U8(iAddress )+0.5f) / 127.5f);
varray->SetNormalY(0, ((float)(signed char)Memory_Read_U8(iAddress+1)+0.5f) / 127.5f); varray->SetNormalY(0, ((float)(signed char)Memory_Read_U8(iAddress+1)+0.5f) / 127.5f);
varray->SetNormalZ(0, ((float)(signed char)Memory_Read_U8(iAddress+2)+0.5f) / 127.5f); varray->SetNormalZ(0, ((float)(signed char)Memory_Read_U8(iAddress+2)+0.5f) / 127.5f);
} }
// __________________________________________________________________________________________________ // __________________________________________________________________________________________________
// Normal_Index16_Short // Normal_Index16_Short
// //
void LOADERDECL void LOADERDECL
VertexLoader_Normal::Normal_Index16_Short(const void* _p) VertexLoader_Normal::Normal_Index16_Short(const void* _p)
{ {
u16 Index = DataReadU16(); u16 Index = DataReadU16();
u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]); u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]);
varray->SetNormalX(0, ((float)(signed short)Memory_Read_U16(iAddress )+0.5f) / 32767.5f); varray->SetNormalX(0, ((float)(signed short)Memory_Read_U16(iAddress )+0.5f) / 32767.5f);
varray->SetNormalY(0, ((float)(signed short)Memory_Read_U16(iAddress+2)+0.5f) / 32767.5f); varray->SetNormalY(0, ((float)(signed short)Memory_Read_U16(iAddress+2)+0.5f) / 32767.5f);
varray->SetNormalZ(0, ((float)(signed short)Memory_Read_U16(iAddress+4)+0.5f) / 32767.5f); varray->SetNormalZ(0, ((float)(signed short)Memory_Read_U16(iAddress+4)+0.5f) / 32767.5f);
} }
// __________________________________________________________________________________________________ // __________________________________________________________________________________________________
// Normal_Index8_Float // Normal_Index8_Float
// //
void LOADERDECL void LOADERDECL
VertexLoader_Normal::Normal_Index16_Float(const void* _p) VertexLoader_Normal::Normal_Index16_Float(const void* _p)
{ {
u16 Index = DataReadU16(); u16 Index = DataReadU16();
u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]); u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]);
varray->SetNormalX(0, Memory_Read_Float(iAddress)); varray->SetNormalX(0, Memory_Read_Float(iAddress));
varray->SetNormalY(0, Memory_Read_Float(iAddress+4)); varray->SetNormalY(0, Memory_Read_Float(iAddress+4));
varray->SetNormalZ(0, Memory_Read_Float(iAddress+8)); varray->SetNormalZ(0, Memory_Read_Float(iAddress+8));
} }
// __________________________________________________________________________________________________ // __________________________________________________________________________________________________
// Normal_Index16_Byte3 // Normal_Index16_Byte3
// //
void LOADERDECL void LOADERDECL
VertexLoader_Normal::Normal_Index16_Byte3(const void* _p) VertexLoader_Normal::Normal_Index16_Byte3(const void* _p)
{ {
if (index3) if (index3)
{ {
for (int i=0; i<3; i++) for (int i=0; i<3; i++)
{ {
u16 Index = DataReadU16(); u16 Index = DataReadU16();
u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]) + 1*3*i; u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]) + 1*3*i;
varray->SetNormalX(i, ((float)(signed char)Memory_Read_U8(iAddress )+0.5f) / 127.5f); varray->SetNormalX(i, ((float)(signed char)Memory_Read_U8(iAddress )+0.5f) / 127.5f);
varray->SetNormalY(i, ((float)(signed char)Memory_Read_U8(iAddress+1)+0.5f) / 127.5f); varray->SetNormalY(i, ((float)(signed char)Memory_Read_U8(iAddress+1)+0.5f) / 127.5f);
varray->SetNormalZ(i, ((float)(signed char)Memory_Read_U8(iAddress+2)+0.5f) / 127.5f); varray->SetNormalZ(i, ((float)(signed char)Memory_Read_U8(iAddress+2)+0.5f) / 127.5f);
} }
} }
else else
{ {
u16 Index = DataReadU16(); u16 Index = DataReadU16();
for (int i=0; i<3; i++) for (int i=0; i<3; i++)
{ {
u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]) + 1*3*i; u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]) + 1*3*i;
varray->SetNormalX(i, ((float)(signed char)Memory_Read_U8(iAddress )+0.5f) / 127.5f); varray->SetNormalX(i, ((float)(signed char)Memory_Read_U8(iAddress )+0.5f) / 127.5f);
varray->SetNormalY(i, ((float)(signed char)Memory_Read_U8(iAddress+1)+0.5f) / 127.5f); varray->SetNormalY(i, ((float)(signed char)Memory_Read_U8(iAddress+1)+0.5f) / 127.5f);
varray->SetNormalZ(i, ((float)(signed char)Memory_Read_U8(iAddress+2)+0.5f) / 127.5f); varray->SetNormalZ(i, ((float)(signed char)Memory_Read_U8(iAddress+2)+0.5f) / 127.5f);
} }
} }
} }
// __________________________________________________________________________________________________ // __________________________________________________________________________________________________
// Normal_Index16_Short3 // Normal_Index16_Short3
// //
void LOADERDECL void LOADERDECL
VertexLoader_Normal::Normal_Index16_Short3(const void* _p) VertexLoader_Normal::Normal_Index16_Short3(const void* _p)
{ {
if (index3) if (index3)
{ {
for (int i=0; i<3; i++) for (int i=0; i<3; i++)
{ {
u16 Index = DataReadU16(); u16 Index = DataReadU16();
u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]) + 2*3*i; u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]) + 2*3*i;
varray->SetNormalX(i, ((float)(signed short)Memory_Read_U16(iAddress )+0.5f) / 32767.5f); varray->SetNormalX(i, ((float)(signed short)Memory_Read_U16(iAddress )+0.5f) / 32767.5f);
varray->SetNormalY(i, ((float)(signed short)Memory_Read_U16(iAddress+2)+0.5f) / 32767.5f); varray->SetNormalY(i, ((float)(signed short)Memory_Read_U16(iAddress+2)+0.5f) / 32767.5f);
varray->SetNormalZ(i, ((float)(signed short)Memory_Read_U16(iAddress+4)+0.5f) / 32767.5f); varray->SetNormalZ(i, ((float)(signed short)Memory_Read_U16(iAddress+4)+0.5f) / 32767.5f);
} }
} }
else else
{ {
u16 Index = DataReadU16(); u16 Index = DataReadU16();
for (int i=0; i<3; i++) for (int i=0; i<3; i++)
{ {
u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]) + 2*3*i; u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]) + 2*3*i;
varray->SetNormalX(i, ((float)(signed short)Memory_Read_U16(iAddress )+0.5f) / 32767.5f); varray->SetNormalX(i, ((float)(signed short)Memory_Read_U16(iAddress )+0.5f) / 32767.5f);
varray->SetNormalY(i, ((float)(signed short)Memory_Read_U16(iAddress+2)+0.5f) / 32767.5f); varray->SetNormalY(i, ((float)(signed short)Memory_Read_U16(iAddress+2)+0.5f) / 32767.5f);
varray->SetNormalZ(i, ((float)(signed short)Memory_Read_U16(iAddress+4)+0.5f) / 32767.5f); varray->SetNormalZ(i, ((float)(signed short)Memory_Read_U16(iAddress+4)+0.5f) / 32767.5f);
} }
} }
} }
// __________________________________________________________________________________________________ // __________________________________________________________________________________________________
// Normal_Index16_Float3 // Normal_Index16_Float3
// //
void LOADERDECL void LOADERDECL
VertexLoader_Normal::Normal_Index16_Float3(const void* _p) VertexLoader_Normal::Normal_Index16_Float3(const void* _p)
{ {
if (index3) if (index3)
{ {
for (int i=0; i<3; i++) for (int i=0; i<3; i++)
{ {
u16 Index = DataReadU16(); u16 Index = DataReadU16();
u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]) + 4*3*i; u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]) + 4*3*i;
varray->SetNormalX(i, Memory_Read_Float(iAddress )); varray->SetNormalX(i, Memory_Read_Float(iAddress ));
varray->SetNormalY(i, Memory_Read_Float(iAddress+4)); varray->SetNormalY(i, Memory_Read_Float(iAddress+4));
varray->SetNormalZ(i, Memory_Read_Float(iAddress+8)); varray->SetNormalZ(i, Memory_Read_Float(iAddress+8));
} }
} }
else else
{ {
u16 Index = DataReadU16(); u16 Index = DataReadU16();
for (int i=0; i<3; i++) for (int i=0; i<3; i++)
{ {
u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]) + 4*3*i; u32 iAddress = arraybases[ARRAY_NORMAL] + (Index * arraystrides[ARRAY_NORMAL]) + 4*3*i;
varray->SetNormalX(i, Memory_Read_Float(iAddress )); varray->SetNormalX(i, Memory_Read_Float(iAddress ));
varray->SetNormalY(i, Memory_Read_Float(iAddress+4)); varray->SetNormalY(i, Memory_Read_Float(iAddress+4));
varray->SetNormalZ(i, Memory_Read_Float(iAddress+8)); varray->SetNormalZ(i, Memory_Read_Float(iAddress+8));
} }
} }
} }

View File

@ -1,234 +1,234 @@
// 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 "D3DBase.h" #include "D3DBase.h"
#include "Statistics.h" #include "Statistics.h"
#include "Profiler.h" #include "Profiler.h"
#include "VertexManager.h" #include "VertexManager.h"
#include "OpcodeDecoding.h" #include "OpcodeDecoding.h"
#include "TransformEngine.h" #include "TransformEngine.h"
#include "IndexGenerator.h" #include "IndexGenerator.h"
#include "BPStructs.h" #include "BPStructs.h"
#include "XFStructs.h" #include "XFStructs.h"
#include "ShaderManager.h" #include "ShaderManager.h"
#include "Utils.h" #include "Utils.h"
using namespace D3D; using namespace D3D;
namespace VertexManager namespace VertexManager
{ {
static IndexGenerator indexGen; static IndexGenerator indexGen;
static Collection collection; static Collection collection;
static LPDIRECT3DVERTEXDECLARATION9 vDecl; static LPDIRECT3DVERTEXDECLARATION9 vDecl;
static D3DVertex *fakeVBuffer; static D3DVertex *fakeVBuffer;
static u16 *fakeIBuffer; static u16 *fakeIBuffer;
#define MAXVBUFFERSIZE 65536*3 #define MAXVBUFFERSIZE 65536*3
#define MAXIBUFFERSIZE 65536*3 #define MAXIBUFFERSIZE 65536*3
const D3DVERTEXELEMENT9 decl[] = const D3DVERTEXELEMENT9 decl[] =
{ {
{ 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 }, { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
{ 0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0 }, { 0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0 },
{ 0, 24, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0 }, { 0, 24, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0 },
{ 0, 28, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1 }, { 0, 28, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1 },
{ 0, 32+12*0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 }, { 0, 32+12*0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
{ 0, 32+12*1, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1 }, { 0, 32+12*1, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1 },
{ 0, 32+12*2, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2 }, { 0, 32+12*2, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2 },
{ 0, 32+12*3, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 3 }, { 0, 32+12*3, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 3 },
{ 0, 32+12*4, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 4 }, { 0, 32+12*4, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 4 },
{ 0, 32+12*5, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 5 }, { 0, 32+12*5, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 5 },
{ 0, 32+12*6, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 6 }, { 0, 32+12*6, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 6 },
{ 0, 32+12*7, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 7 }, { 0, 32+12*7, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 7 },
D3DDECL_END() D3DDECL_END()
}; };
bool Init() bool Init()
{ {
collection = C_NOTHING; collection = C_NOTHING;
fakeVBuffer = new D3DVertex[65536]; fakeVBuffer = new D3DVertex[65536];
fakeIBuffer = new u16[65536]; fakeIBuffer = new u16[65536];
CreateDeviceObjects(); CreateDeviceObjects();
return true; return true;
} }
void Shutdown() void Shutdown()
{ {
DestroyDeviceObjects(); DestroyDeviceObjects();
delete [] fakeVBuffer; delete [] fakeVBuffer;
delete [] fakeIBuffer; delete [] fakeIBuffer;
} }
void CreateDeviceObjects() void CreateDeviceObjects()
{ {
HRESULT hr; HRESULT hr;
if (FAILED(hr = D3D::dev->CreateVertexDeclaration(decl, &vDecl))) if (FAILED(hr = D3D::dev->CreateVertexDeclaration(decl, &vDecl)))
{ {
MessageBox(0,"Failed to create vertex declaration","sdfsd",0); MessageBox(0,"Failed to create vertex declaration","sdfsd",0);
return; return;
} }
} }
void BeginFrame() void BeginFrame()
{ {
D3D::dev->SetVertexDeclaration(vDecl); D3D::dev->SetVertexDeclaration(vDecl);
//D3D::dev->SetStreamSource(0,vBuffer,0,sizeof(D3DVertex)); //D3D::dev->SetStreamSource(0,vBuffer,0,sizeof(D3DVertex));
} }
void DestroyDeviceObjects() void DestroyDeviceObjects()
{ {
if (vDecl) if (vDecl)
vDecl->Release(); vDecl->Release();
vDecl = 0; vDecl = 0;
} }
void AddIndices(int _primitive, int _numVertices) void AddIndices(int _primitive, int _numVertices)
{ {
switch(_primitive) { switch(_primitive) {
case GX_DRAW_QUADS: indexGen.AddQuads(_numVertices); return; case GX_DRAW_QUADS: indexGen.AddQuads(_numVertices); return;
case GX_DRAW_TRIANGLES: indexGen.AddList(_numVertices); return; case GX_DRAW_TRIANGLES: indexGen.AddList(_numVertices); return;
case GX_DRAW_TRIANGLE_STRIP: indexGen.AddStrip(_numVertices); return; case GX_DRAW_TRIANGLE_STRIP: indexGen.AddStrip(_numVertices); return;
case GX_DRAW_TRIANGLE_FAN: indexGen.AddFan(_numVertices); return; case GX_DRAW_TRIANGLE_FAN: indexGen.AddFan(_numVertices); return;
case GX_DRAW_LINE_STRIP: indexGen.AddLineStrip(_numVertices); return; case GX_DRAW_LINE_STRIP: indexGen.AddLineStrip(_numVertices); return;
case GX_DRAW_LINES: indexGen.AddLineList(_numVertices); return; case GX_DRAW_LINES: indexGen.AddLineList(_numVertices); return;
case GX_DRAW_POINTS: indexGen.AddPointList(_numVertices); return; case GX_DRAW_POINTS: indexGen.AddPointList(_numVertices); return;
} }
} }
const Collection collectionTypeLUT[8] = const Collection collectionTypeLUT[8] =
{ {
C_TRIANGLES,//quads C_TRIANGLES,//quads
C_NOTHING, //nothing C_NOTHING, //nothing
C_TRIANGLES,//triangles C_TRIANGLES,//triangles
C_TRIANGLES,//strip C_TRIANGLES,//strip
C_TRIANGLES,//fan C_TRIANGLES,//fan
C_LINES, //lines C_LINES, //lines
C_LINES, //linestrip C_LINES, //linestrip
C_POINTS //guess :P C_POINTS //guess :P
}; };
D3DVertex *vbufferwrite; D3DVertex *vbufferwrite;
void AddVertices(int _primitive, int _numVertices, const DecodedVArray *varray) void AddVertices(int _primitive, int _numVertices, const DecodedVArray *varray)
{ {
if (_numVertices <= 0) //This check is pretty stupid... if (_numVertices <= 0) //This check is pretty stupid...
return; return;
Collection type = collectionTypeLUT[_primitive]; Collection type = collectionTypeLUT[_primitive];
if (type == C_NOTHING) if (type == C_NOTHING)
return; return;
DVSTARTPROFILE(); DVSTARTPROFILE();
_assert_msg_(type != C_NOTHING, "type == C_NOTHING!!", "WTF"); _assert_msg_(type != C_NOTHING, "type == C_NOTHING!!", "WTF");
if (indexGen.GetNumVerts() > 1000) // TODO(ector): Raise? if (indexGen.GetNumVerts() > 1000) // TODO(ector): Raise?
Flush(); Flush();
ADDSTAT(stats.thisFrame.numPrims, _numVertices); ADDSTAT(stats.thisFrame.numPrims, _numVertices);
if (collection != type) if (collection != type)
{ {
//We are NOT collecting the right type. //We are NOT collecting the right type.
Flush(); Flush();
collection = type; collection = type;
u16 *ptr = 0; u16 *ptr = 0;
if (type != C_POINTS) if (type != C_POINTS)
{ {
ptr = fakeIBuffer; ptr = fakeIBuffer;
indexGen.Start((unsigned short*)ptr); indexGen.Start((unsigned short*)ptr);
AddIndices(_primitive,_numVertices); AddIndices(_primitive,_numVertices);
} }
vbufferwrite = fakeVBuffer; vbufferwrite = fakeVBuffer;
if (_numVertices >= MAXVBUFFERSIZE) if (_numVertices >= MAXVBUFFERSIZE)
MessageBox(NULL, "To much vertices for the buffer", "Video.DLL", MB_OK); MessageBox(NULL, "To much vertices for the buffer", "Video.DLL", MB_OK);
CTransformEngine::TransformVertices(_numVertices, varray, vbufferwrite); CTransformEngine::TransformVertices(_numVertices, varray, vbufferwrite);
} }
else //We are collecting the right type, keep going else //We are collecting the right type, keep going
{ {
_assert_msg_(vbufferwrite!=0, "collecting: vbufferwrite == 0!","WTF"); _assert_msg_(vbufferwrite!=0, "collecting: vbufferwrite == 0!","WTF");
INCSTAT(stats.thisFrame.numPrimitiveJoins); INCSTAT(stats.thisFrame.numPrimitiveJoins);
//Success, keep adding to unlocked buffer //Success, keep adding to unlocked buffer
int last = indexGen.GetNumVerts(); int last = indexGen.GetNumVerts();
AddIndices(_primitive, _numVertices); AddIndices(_primitive, _numVertices);
if (_numVertices >= MAXVBUFFERSIZE) if (_numVertices >= MAXVBUFFERSIZE)
MessageBox(NULL, "Too many vertices for the buffer", "Video.DLL", MB_OK); MessageBox(NULL, "Too many vertices for the buffer", "Video.DLL", MB_OK);
CTransformEngine::TransformVertices(_numVertices, varray, vbufferwrite + last); CTransformEngine::TransformVertices(_numVertices, varray, vbufferwrite + last);
} }
} }
const D3DPRIMITIVETYPE pts[3] = const D3DPRIMITIVETYPE pts[3] =
{ {
D3DPT_POINTLIST, //DUMMY D3DPT_POINTLIST, //DUMMY
D3DPT_TRIANGLELIST, D3DPT_TRIANGLELIST,
D3DPT_LINELIST, D3DPT_LINELIST,
}; };
void Flush() void Flush()
{ {
DVSTARTPROFILE(); DVSTARTPROFILE();
if (collection != C_NOTHING) if (collection != C_NOTHING)
{ {
ActivateTextures(); ActivateTextures();
int numVertices = indexGen.GetNumVerts(); int numVertices = indexGen.GetNumVerts();
if (numVertices != 0) if (numVertices != 0)
{ {
PShaderCache::SetShader(); // TODO(ector): only do this if shader has changed PShaderCache::SetShader(); // TODO(ector): only do this if shader has changed
VShaderCache::SetShader(); // TODO(ector): only do this if shader has changed VShaderCache::SetShader(); // TODO(ector): only do this if shader has changed
if (collection != C_POINTS) if (collection != C_POINTS)
{ {
int numPrimitives = indexGen.GetNumPrims(); int numPrimitives = indexGen.GetNumPrims();
D3D::dev->DrawIndexedPrimitiveUP(pts[(int)collection], D3D::dev->DrawIndexedPrimitiveUP(pts[(int)collection],
0, 0,
numVertices, numVertices,
numPrimitives, numPrimitives,
fakeIBuffer, fakeIBuffer,
D3DFMT_INDEX16, D3DFMT_INDEX16,
fakeVBuffer, fakeVBuffer,
sizeof(D3DVertex)); sizeof(D3DVertex));
} }
else else
{ {
D3D::dev->SetIndices(0); D3D::dev->SetIndices(0);
// D3D::dev->DrawPrimitiveUP(D3DPT_POINTLIST, // D3D::dev->DrawPrimitiveUP(D3DPT_POINTLIST,
// numVertices, // numVertices,
// fakeVBuffer, // fakeVBuffer,
// sizeof(D3DVertex)); // sizeof(D3DVertex));
Renderer::DrawPrimitiveUP( D3DPT_POINTLIST, numVertices, fakeVBuffer, sizeof(D3DVertex) ); Renderer::DrawPrimitiveUP( D3DPT_POINTLIST, numVertices, fakeVBuffer, sizeof(D3DVertex) );
} }
} }
collection = C_NOTHING; collection = C_NOTHING;
} }
} }
} // namespace } // namespace

View File

@ -1,142 +1,142 @@
// 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 "stdafx.h" #include "stdafx.h"
#include "D3DShader.h" #include "D3DShader.h"
#include "VertexShader.h" #include "VertexShader.h"
#include "BPStructs.h" #include "BPStructs.h"
static const char *genericVS = "// Generic Vertex Shader\ static const char *genericVS = "// Generic Vertex Shader\
\n\ \n\
struct VS_INPUT {\n\ struct VS_INPUT {\n\
float4 pos : POSITION;\n\ float4 pos : POSITION;\n\
float3 normal : NORMAL;\n\ float3 normal : NORMAL;\n\
float4 colors[2] : COLOR0;\n\ float4 colors[2] : COLOR0;\n\
float3 uv[8] : TEXCOORD0;\n\ float3 uv[8] : TEXCOORD0;\n\
};\n\ };\n\
\n\ \n\
struct VS_OUTPUT {\n\ struct VS_OUTPUT {\n\
float4 pos : POSITION;\n\ float4 pos : POSITION;\n\
float4 colors[2] : COLOR0;\n\ float4 colors[2] : COLOR0;\n\
//numtexgen\n\ //numtexgen\n\
float4 uv[5] : TEXCOORD0;\n\ float4 uv[5] : TEXCOORD0;\n\
};\n\ };\n\
\n\ \n\
uniform matrix matWorldViewProj : register(c0);\n\ uniform matrix matWorldViewProj : register(c0);\n\
\n\ \n\
VS_OUTPUT main(const VS_INPUT input)\n\ VS_OUTPUT main(const VS_INPUT input)\n\
{\n\ {\n\
VS_OUTPUT output;\n\ VS_OUTPUT output;\n\
\n\ \n\
output.pos = mul(matWorldViewProj, input.pos);\n\ output.pos = mul(matWorldViewProj, input.pos);\n\
// texgen\n\ // texgen\n\
for (int i=0; i<5; i++)\n\ for (int i=0; i<5; i++)\n\
output.uv[i] = float4(input.uv[i].xyz,1);\n\ output.uv[i] = float4(input.uv[i].xyz,1);\n\
\n\ \n\
for (int i=0; i<2; i++)\n output.colors[i] = input.colors[i];\n\ for (int i=0; i<2; i++)\n output.colors[i] = input.colors[i];\n\
return output;\n\ return output;\n\
}\0"; }\0";
const char *GenerateVertexShader() { const char *GenerateVertexShader() {
return genericVS; return genericVS;
} }
/* /*
char text2[65536]; char text2[65536];
#define WRITE p+=sprintf #define WRITE p+=sprintf
void WriteTexgen(char *&p, int n); void WriteTexgen(char *&p, int n);
const char *GenerateVertexShader() const char *GenerateVertexShader()
{ {
int numColors = 2; int numColors = 2;
int numUV = 8; int numUV = 8;
int numTexgen = bpmem.genMode.numtexgens; int numTexgen = bpmem.genMode.numtexgens;
int numNormals = 3; int numNormals = 3;
bool fogEnable = false; bool fogEnable = false;
bool hasNormal = true; bool hasNormal = true;
char *p = text2; char *p = text2;
WRITE(p,"//Vertex Shader\n"); WRITE(p,"//Vertex Shader\n");
WRITE(p,"//%i uv->%i texgens, %i colors\n",numUV,numTexgen,numColors); WRITE(p,"//%i uv->%i texgens, %i colors\n",numUV,numTexgen,numColors);
WRITE(p,"\n"); WRITE(p,"\n");
WRITE(p,"struct VS_INPUT {\n"); WRITE(p,"struct VS_INPUT {\n");
WRITE(p," float4 pos : POSITION;\n"); WRITE(p," float4 pos : POSITION;\n");
WRITE(p," float3 normal : NORMAL;\n"); WRITE(p," float3 normal : NORMAL;\n");
if (numColors) if (numColors)
WRITE(p," float4 colors[%i] : COLOR0;\n",numColors); WRITE(p," float4 colors[%i] : COLOR0;\n",numColors);
if (numUV) if (numUV)
WRITE(p," float3 uv[%i] : TEXCOORD0;\n",numUV); WRITE(p," float3 uv[%i] : TEXCOORD0;\n",numUV);
WRITE(p,"};\n"); WRITE(p,"};\n");
WRITE(p,"\n"); WRITE(p,"\n");
WRITE(p,"struct VS_OUTPUT {\n"); WRITE(p,"struct VS_OUTPUT {\n");
WRITE(p," float4 pos : POSITION;\n"); WRITE(p," float4 pos : POSITION;\n");
WRITE(p," float4 colors[%i] : COLOR0;\n",numColors); WRITE(p," float4 colors[%i] : COLOR0;\n",numColors);
if (numTexgen) if (numTexgen)
WRITE(p," float4 uv[%i] : TEXCOORD0;\n",numTexgen); WRITE(p," float4 uv[%i] : TEXCOORD0;\n",numTexgen);
if (fogEnable) if (fogEnable)
WRITE(p," float fog : FOG;\n",numTexgen); WRITE(p," float fog : FOG;\n",numTexgen);
WRITE(p,"};\n"); WRITE(p,"};\n");
WRITE(p,"\n"); WRITE(p,"\n");
WRITE(p,"uniform matrix matWorldViewProj : register(c0);\n"); WRITE(p,"uniform matrix matWorldViewProj : register(c0);\n");
WRITE(p,"\n"); WRITE(p,"\n");
WRITE(p,"VS_OUTPUT main(const VS_INPUT input)\n"); WRITE(p,"VS_OUTPUT main(const VS_INPUT input)\n");
WRITE(p,"{\n"); WRITE(p,"{\n");
WRITE(p," VS_OUTPUT output;"); WRITE(p," VS_OUTPUT output;");
WRITE(p,"\n"); WRITE(p,"\n");
WRITE(p," output.pos = mul(matWorldViewProj, input.pos);\n"); WRITE(p," output.pos = mul(matWorldViewProj, input.pos);\n");
for (int i = 0; i < (int)bpmem.genMode.numtexgens; i++) for (int i = 0; i < (int)bpmem.genMode.numtexgens; i++)
{ {
//build the equation for this stage //build the equation for this stage
WriteTexgen(p,i); WriteTexgen(p,i);
} }
WRITE(p," for (int i=0; i<2; i++)\n output.colors[i] = input.colors[i];\n"); WRITE(p," for (int i=0; i<2; i++)\n output.colors[i] = input.colors[i];\n");
//WRITE(p," output.fog = 0.0f;"); //WRITE(p," output.fog = 0.0f;");
WRITE(p,"return output;\n"); WRITE(p,"return output;\n");
WRITE(p,"}\n"); WRITE(p,"}\n");
WRITE(p,"\0"); WRITE(p,"\0");
// MessageBox(0,text2,0,0); // MessageBox(0,text2,0,0);
return text2; return text2;
} }
/* /*
* xform->vertexshader ideas * xform->vertexshader ideas
*//* *//*
void WriteTexgen(char *&p, int n) void WriteTexgen(char *&p, int n)
{ {
WRITE(p," output.uv[%i] = float4(input.uv[%i].xy,0,input.uv[%i].z);\n",n,n,n); WRITE(p," output.uv[%i] = float4(input.uv[%i].xy,0,input.uv[%i].z);\n",n,n,n);
} }
void WriteLight(int color, int component) void WriteLight(int color, int component)
{ {
} */ } */

View File

@ -1,29 +1,29 @@
#include <windows.h> #include <windows.h>
#include <vector> #include <vector>
#include "DialogManager.h" #include "DialogManager.h"
typedef std::vector <HWND> WindowList; typedef std::vector <HWND> WindowList;
WindowList dialogs; WindowList dialogs;
void DialogManager::AddDlg(HWND hDialog) void DialogManager::AddDlg(HWND hDialog)
{ {
dialogs.push_back(hDialog); dialogs.push_back(hDialog);
} }
bool DialogManager::IsDialogMessage(LPMSG message) bool DialogManager::IsDialogMessage(LPMSG message)
{ {
WindowList::iterator iter; WindowList::iterator iter;
for (iter=dialogs.begin(); iter!=dialogs.end(); iter++) for (iter=dialogs.begin(); iter!=dialogs.end(); iter++)
{ {
if (::IsDialogMessage(*iter,message)) if (::IsDialogMessage(*iter,message))
return true; return true;
} }
return false; return false;
} }
void DialogManager::EnableAll(BOOL enable) void DialogManager::EnableAll(BOOL enable)
{ {
WindowList::iterator iter; WindowList::iterator iter;
for (iter=dialogs.begin(); iter!=dialogs.end(); iter++) for (iter=dialogs.begin(); iter!=dialogs.end(); iter++)
EnableWindow(*iter,enable); EnableWindow(*iter,enable);
} }

View File

@ -1,148 +1,148 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include "File.h" #include "File.h"
namespace W32Util namespace W32Util
{ {
File::File() File::File()
{ {
fileHandle = INVALID_HANDLE_VALUE; fileHandle = INVALID_HANDLE_VALUE;
isOpen=false; isOpen=false;
} }
File::~File() File::~File()
{ {
} }
bool File::Open(const TCHAR *filename, eFileMode _mode) bool File::Open(const TCHAR *filename, eFileMode _mode)
{ {
mode = _mode; mode = _mode;
//it's time to open the file //it's time to open the file
fileHandle = CreateFile(filename, fileHandle = CreateFile(filename,
mode==FILE_READ ? GENERIC_READ : GENERIC_WRITE, //open mode mode==FILE_READ ? GENERIC_READ : GENERIC_WRITE, //open mode
mode == FILE_READ ? FILE_SHARE_READ : NULL, //sharemode mode == FILE_READ ? FILE_SHARE_READ : NULL, //sharemode
NULL, //security NULL, //security
mode==FILE_READ ? OPEN_EXISTING : CREATE_ALWAYS, //create mode mode==FILE_READ ? OPEN_EXISTING : CREATE_ALWAYS, //create mode
FILE_ATTRIBUTE_NORMAL, //atrributes FILE_ATTRIBUTE_NORMAL, //atrributes
NULL); //template NULL); //template
if (fileHandle == INVALID_HANDLE_VALUE) if (fileHandle == INVALID_HANDLE_VALUE)
isOpen=false; isOpen=false;
else else
isOpen=true; isOpen=true;
return isOpen; return isOpen;
} }
void File::Close() void File::Close()
{ {
if (isOpen) if (isOpen)
{ {
//close the file and reset variables //close the file and reset variables
CloseHandle(fileHandle); CloseHandle(fileHandle);
fileHandle=INVALID_HANDLE_VALUE; fileHandle=INVALID_HANDLE_VALUE;
isOpen=false; isOpen=false;
} }
} }
int File::GetSize() int File::GetSize()
{ {
if (!isOpen) //of course if (!isOpen) //of course
return 0; return 0;
else else
return GetFileSize(fileHandle,0); return GetFileSize(fileHandle,0);
} }
int File::Write(void *data, int size) //let's do some writing int File::Write(void *data, int size) //let's do some writing
{ {
if (isOpen) if (isOpen)
{ {
DWORD written; DWORD written;
WriteFile(fileHandle, data, size, &written,0); WriteFile(fileHandle, data, size, &written,0);
return written; //we return the number of bytes that actually got written return written; //we return the number of bytes that actually got written
} }
else else
{ {
return 0; return 0;
} }
} }
int File::Read(void *data, int size) int File::Read(void *data, int size)
{ {
if (isOpen) if (isOpen)
{ {
DWORD wasRead; DWORD wasRead;
ReadFile(fileHandle, data, size, &wasRead,0); ReadFile(fileHandle, data, size, &wasRead,0);
return wasRead; //we return the number of bytes that actually was read return wasRead; //we return the number of bytes that actually was read
} }
else else
{ {
return 0; return 0;
} }
} }
int File::WR(void *data, int size) int File::WR(void *data, int size)
{ {
if (mode==FILE_READ) if (mode==FILE_READ)
return Read(data,size); return Read(data,size);
else else
return Write(data,size); return Write(data,size);
} }
bool File::MagicCookie(int cookie) bool File::MagicCookie(int cookie)
{ {
if (mode==FILE_READ) if (mode==FILE_READ)
{ {
if (ReadInt()!=cookie) if (ReadInt()!=cookie)
{ {
char mojs[5],temp[256]; char mojs[5],temp[256];
mojs[4]=0; mojs[4]=0;
*(int*)mojs=cookie; *(int*)mojs=cookie;
sprintf(temp,"W32Util::File: Magic Cookie %s is bad!",mojs); sprintf(temp,"W32Util::File: Magic Cookie %s is bad!",mojs);
MessageBox(0,temp,"Error reading file",MB_ICONERROR); MessageBox(0,temp,"Error reading file",MB_ICONERROR);
return false; return false;
} }
else else
return true; return true;
} }
else if (mode==FILE_WRITE) else if (mode==FILE_WRITE)
{ {
WriteInt(cookie); WriteInt(cookie);
return true; return true;
} }
return false; return false;
} }
int File::ReadInt() int File::ReadInt()
{ {
int temp; int temp;
if (Read(&temp, sizeof(int))) if (Read(&temp, sizeof(int)))
return temp; return temp;
else else
return 0; return 0;
} }
void File::WriteInt(int i) void File::WriteInt(int i)
{ {
Write(&i,sizeof(int)); Write(&i,sizeof(int));
} }
char File::ReadChar() char File::ReadChar()
{ {
char temp; char temp;
if (Read(&temp, sizeof(char))) if (Read(&temp, sizeof(char)))
return temp; return temp;
else else
return 0; return 0;
} }
void File::WriteChar(char i) void File::WriteChar(char i)
{ {
Write(&i,sizeof(char)); Write(&i,sizeof(char));
} }
} }

View File

@ -1,102 +1,102 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include "Misc.h" #include "Misc.h"
namespace W32Util namespace W32Util
{ {
//shamelessly taken from http://www.catch22.org.uk/tuts/tips.asp //shamelessly taken from http://www.catch22.org.uk/tuts/tips.asp
void CenterWindow(HWND hwnd) void CenterWindow(HWND hwnd)
{ {
HWND hwndParent; HWND hwndParent;
RECT rect, rectP; RECT rect, rectP;
int width, height; int width, height;
int screenwidth, screenheight; int screenwidth, screenheight;
int x, y; int x, y;
//make the window relative to its parent //make the window relative to its parent
hwndParent = GetParent(hwnd); hwndParent = GetParent(hwnd);
if (!hwndParent) if (!hwndParent)
return; return;
GetWindowRect(hwnd, &rect); GetWindowRect(hwnd, &rect);
GetWindowRect(hwndParent, &rectP); GetWindowRect(hwndParent, &rectP);
width = rect.right - rect.left; width = rect.right - rect.left;
height = rect.bottom - rect.top; height = rect.bottom - rect.top;
x = ((rectP.right-rectP.left) - width) / 2 + rectP.left; x = ((rectP.right-rectP.left) - width) / 2 + rectP.left;
y = ((rectP.bottom-rectP.top) - height) / 2 + rectP.top; y = ((rectP.bottom-rectP.top) - height) / 2 + rectP.top;
screenwidth = GetSystemMetrics(SM_CXSCREEN); screenwidth = GetSystemMetrics(SM_CXSCREEN);
screenheight = GetSystemMetrics(SM_CYSCREEN); screenheight = GetSystemMetrics(SM_CYSCREEN);
//make sure that the dialog box never moves outside of //make sure that the dialog box never moves outside of
//the screen //the screen
if(x < 0) x = 0; if(x < 0) x = 0;
if(y < 0) y = 0; if(y < 0) y = 0;
if(x + width > screenwidth) x = screenwidth - width; if(x + width > screenwidth) x = screenwidth - width;
if(y + height > screenheight) y = screenheight - height; if(y + height > screenheight) y = screenheight - height;
MoveWindow(hwnd, x, y, width, height, FALSE); MoveWindow(hwnd, x, y, width, height, FALSE);
} }
HBITMAP CreateBitmapFromARGB(HWND someHwnd, DWORD *image, int w, int h) HBITMAP CreateBitmapFromARGB(HWND someHwnd, DWORD *image, int w, int h)
{ {
BITMAPINFO *bitmap_header; BITMAPINFO *bitmap_header;
static char bitmapbuffer[sizeof(BITMAPINFO)+16]; static char bitmapbuffer[sizeof(BITMAPINFO)+16];
memset(bitmapbuffer,0,sizeof(BITMAPINFO)+16); memset(bitmapbuffer,0,sizeof(BITMAPINFO)+16);
bitmap_header=(BITMAPINFO *)bitmapbuffer; bitmap_header=(BITMAPINFO *)bitmapbuffer;
bitmap_header->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bitmap_header->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bitmap_header->bmiHeader.biPlanes = 1; bitmap_header->bmiHeader.biPlanes = 1;
bitmap_header->bmiHeader.biBitCount = 32; bitmap_header->bmiHeader.biBitCount = 32;
bitmap_header->bmiHeader.biCompression = BI_RGB; bitmap_header->bmiHeader.biCompression = BI_RGB;
bitmap_header->bmiHeader.biWidth = w; bitmap_header->bmiHeader.biWidth = w;
bitmap_header->bmiHeader.biHeight = -h; bitmap_header->bmiHeader.biHeight = -h;
((unsigned long *)bitmap_header->bmiColors)[0] = 0x00FF0000; ((unsigned long *)bitmap_header->bmiColors)[0] = 0x00FF0000;
((unsigned long *)bitmap_header->bmiColors)[1] = 0x0000FF00; ((unsigned long *)bitmap_header->bmiColors)[1] = 0x0000FF00;
((unsigned long *)bitmap_header->bmiColors)[2] = 0x000000FF; ((unsigned long *)bitmap_header->bmiColors)[2] = 0x000000FF;
HDC dc = GetDC(someHwnd); HDC dc = GetDC(someHwnd);
HBITMAP bitmap = CreateDIBitmap(dc,&bitmap_header->bmiHeader,CBM_INIT,image,bitmap_header,DIB_RGB_COLORS); HBITMAP bitmap = CreateDIBitmap(dc,&bitmap_header->bmiHeader,CBM_INIT,image,bitmap_header,DIB_RGB_COLORS);
ReleaseDC(someHwnd,dc); ReleaseDC(someHwnd,dc);
return bitmap; return bitmap;
} }
void NiceSizeFormat(size_t size, char *out) void NiceSizeFormat(size_t size, char *out)
{ {
char *sizes[] = {"b","KB","MB","GB","TB","PB","EB"}; char *sizes[] = {"b","KB","MB","GB","TB","PB","EB"};
int s = 0; int s = 0;
int frac = 0; int frac = 0;
while (size>1024) while (size>1024)
{ {
s++; s++;
frac = (int)size & 1023; frac = (int)size & 1023;
size /= 1024; size /= 1024;
} }
float f = (float)size + ((float)frac / 1024.0f); float f = (float)size + ((float)frac / 1024.0f);
sprintf(out,"%3.1f %s",f,sizes[s]); sprintf(out,"%3.1f %s",f,sizes[s]);
} }
BOOL CopyTextToClipboard(HWND hwnd, TCHAR *text) BOOL CopyTextToClipboard(HWND hwnd, TCHAR *text)
{ {
OpenClipboard(hwnd); OpenClipboard(hwnd);
EmptyClipboard(); EmptyClipboard();
HANDLE hglbCopy = GlobalAlloc(GMEM_MOVEABLE, (strlen(text) + 1) * sizeof(TCHAR)); HANDLE hglbCopy = GlobalAlloc(GMEM_MOVEABLE, (strlen(text) + 1) * sizeof(TCHAR));
if (hglbCopy == NULL) if (hglbCopy == NULL)
{ {
CloseClipboard(); CloseClipboard();
return FALSE; return FALSE;
} }
// Lock the handle and copy the text to the buffer. // Lock the handle and copy the text to the buffer.
TCHAR *lptstrCopy = (TCHAR *)GlobalLock(hglbCopy); TCHAR *lptstrCopy = (TCHAR *)GlobalLock(hglbCopy);
strcpy(lptstrCopy, text); strcpy(lptstrCopy, text);
lptstrCopy[strlen(text)] = (TCHAR) 0; // null character lptstrCopy[strlen(text)] = (TCHAR) 0; // null character
GlobalUnlock(hglbCopy); GlobalUnlock(hglbCopy);
SetClipboardData(CF_TEXT,hglbCopy); SetClipboardData(CF_TEXT,hglbCopy);
CloseClipboard(); CloseClipboard();
return TRUE; return TRUE;
} }
} }

View File

@ -1,225 +1,225 @@
#include "Misc.h" #include "Misc.h"
#include "PropertySheet.h" #include "PropertySheet.h"
namespace W32Util namespace W32Util
{ {
bool centered; bool centered;
PropSheet::PropSheet() PropSheet::PropSheet()
{ {
watermark = 0; watermark = 0;
header = 0; header = 0;
icon = 0; icon = 0;
} }
int CALLBACK PropSheet::Callback(HWND hwndDlg, UINT uMsg, LPARAM lParam) int CALLBACK PropSheet::Callback(HWND hwndDlg, UINT uMsg, LPARAM lParam)
{ {
switch (uMsg) { switch (uMsg) {
case PSCB_PRECREATE: case PSCB_PRECREATE:
{ {
if (uMsg == PSCB_PRECREATE) if (uMsg == PSCB_PRECREATE)
{ {
/* /*
if (lParam) if (lParam)
{ {
DLGTEMPLATE *pDlgTemplate; DLGTEMPLATE *pDlgTemplate;
DLGTEMPLATEEX *pDlgTemplateEx; DLGTEMPLATEEX *pDlgTemplateEx;
pDlgTemplateEx = (DLGTEMPLATEEX *)lParam; pDlgTemplateEx = (DLGTEMPLATEEX *)lParam;
if (pDlgTemplateEx->signature == 0xFFFF) if (pDlgTemplateEx->signature == 0xFFFF)
{ {
// pDlgTemplateEx points to an extended // pDlgTemplateEx points to an extended
// dialog template structure. // dialog template structure.
//pDlgTemplate->style |= DS_SETFONT; //pDlgTemplate->style |= DS_SETFONT;
u8 *tmp1 = (u8*)&pDlgTemplateEx + sizeof(DLGTEMPLATEEX); u8 *tmp1 = (u8*)&pDlgTemplateEx + sizeof(DLGTEMPLATEEX);
u16 *tmp = (u16*)tmp1; u16 *tmp = (u16*)tmp1;
tmp++; //skip menu tmp++; //skip menu
tmp++; //skip dlg class tmp++; //skip dlg class
//Crash(); //Crash();
//Here we should bash in Segoe UI //Here we should bash in Segoe UI
//It turns out to be way complicated though //It turns out to be way complicated though
//Not worth it //Not worth it
} }
else else
{ {
// This is a standard dialog template // This is a standard dialog template
// structure. // structure.
pDlgTemplate = (DLGTEMPLATE *)lParam; pDlgTemplate = (DLGTEMPLATE *)lParam;
} }
} */ } */
} }
} }
break; break;
case PSCB_INITIALIZED: case PSCB_INITIALIZED:
{ {
} }
return 0; return 0;
} }
return 0; return 0;
} }
void PropSheet::Show(HINSTANCE hInstance, HWND hParent, std::string title, int startpage, bool floating, bool wizard) void PropSheet::Show(HINSTANCE hInstance, HWND hParent, std::string title, int startpage, bool floating, bool wizard)
{ {
HPROPSHEETPAGE *pages = new HPROPSHEETPAGE[list.size()]; HPROPSHEETPAGE *pages = new HPROPSHEETPAGE[list.size()];
PROPSHEETPAGE page; PROPSHEETPAGE page;
//common settings //common settings
memset((void*)&page,0,sizeof(PROPSHEETPAGE)); memset((void*)&page,0,sizeof(PROPSHEETPAGE));
page.dwSize = sizeof(PROPSHEETPAGE); page.dwSize = sizeof(PROPSHEETPAGE);
page.hInstance = hInstance; page.hInstance = hInstance;
int i=0; int i=0;
for (DlgList::iterator iter = list.begin(); iter != list.end(); iter++, i++) for (DlgList::iterator iter = list.begin(); iter != list.end(); iter++, i++)
{ {
if (wizard) if (wizard)
{ {
if (i == 0 || i == list.size()-1) if (i == 0 || i == list.size()-1)
page.dwFlags = PSP_HIDEHEADER; page.dwFlags = PSP_HIDEHEADER;
else else
page.dwFlags = PSP_USEHEADERTITLE|PSP_USEHEADERSUBTITLE; page.dwFlags = PSP_USEHEADERTITLE|PSP_USEHEADERSUBTITLE;
} }
else else
{ {
page.dwFlags = PSP_USETITLE; page.dwFlags = PSP_USETITLE;
} }
page.pszTemplate = iter->resource; page.pszTemplate = iter->resource;
page.pfnDlgProc = Tab::TabDlgProc; page.pfnDlgProc = Tab::TabDlgProc;
page.pszTitle = iter->title; page.pszTitle = iter->title;
page.pszHeaderTitle = wizard?iter->title:0; page.pszHeaderTitle = wizard?iter->title:0;
page.pszHeaderSubTitle = wizard?iter->hdrSubTitle:0; page.pszHeaderSubTitle = wizard?iter->hdrSubTitle:0;
page.lParam = (LPARAM)iter->tab; page.lParam = (LPARAM)iter->tab;
pages[i] = CreatePropertySheetPage(&page); pages[i] = CreatePropertySheetPage(&page);
} }
PROPSHEETHEADER sheet; PROPSHEETHEADER sheet;
memset(&sheet,0,sizeof(sheet)); memset(&sheet,0,sizeof(sheet));
sheet.dwSize = sizeof(PROPSHEETHEADER); sheet.dwSize = sizeof(PROPSHEETHEADER);
sheet.hInstance = hInstance; sheet.hInstance = hInstance;
sheet.hwndParent = hParent; sheet.hwndParent = hParent;
sheet.pszbmWatermark = watermark; sheet.pszbmWatermark = watermark;
sheet.pszbmHeader = header; sheet.pszbmHeader = header;
if (icon) if (icon)
sheet.hIcon = icon; sheet.hIcon = icon;
if (wizard) if (wizard)
sheet.dwFlags = PSH_USECALLBACK | PSH_WIZARD97 | (watermark?PSH_WATERMARK:0) | (header?PSH_HEADER:0); sheet.dwFlags = PSH_USECALLBACK | PSH_WIZARD97 | (watermark?PSH_WATERMARK:0) | (header?PSH_HEADER:0);
else else
sheet.dwFlags = PSH_USECALLBACK | PSH_PROPTITLE; sheet.dwFlags = PSH_USECALLBACK | PSH_PROPTITLE;
sheet.dwFlags |= PSH_NOCONTEXTHELP; sheet.dwFlags |= PSH_NOCONTEXTHELP;
if (floating) if (floating)
sheet.dwFlags |= PSH_MODELESS; sheet.dwFlags |= PSH_MODELESS;
//else //else
// sheet.dwFlags |= PSH_NOAPPLYNOW; // sheet.dwFlags |= PSH_NOAPPLYNOW;
if (icon) if (icon)
sheet.dwFlags |= PSH_USEHICON; sheet.dwFlags |= PSH_USEHICON;
sheet.pszCaption = title.c_str(); sheet.pszCaption = title.c_str();
sheet.nPages = (UINT)list.size(); sheet.nPages = (UINT)list.size();
sheet.phpage = pages; sheet.phpage = pages;
sheet.nStartPage = startpage; sheet.nStartPage = startpage;
sheet.pfnCallback = (PFNPROPSHEETCALLBACK)Callback; sheet.pfnCallback = (PFNPROPSHEETCALLBACK)Callback;
NONCLIENTMETRICS ncm = {0}; NONCLIENTMETRICS ncm = {0};
ncm.cbSize = sizeof(ncm); ncm.cbSize = sizeof(ncm);
SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0); SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
hDialogFont = CreateFontIndirect(&ncm.lfMessageFont); hDialogFont = CreateFontIndirect(&ncm.lfMessageFont);
if (wizard) if (wizard)
{ {
//Create the intro/end title font //Create the intro/end title font
LOGFONT TitleLogFont = ncm.lfMessageFont; LOGFONT TitleLogFont = ncm.lfMessageFont;
TitleLogFont.lfWeight = FW_BOLD; TitleLogFont.lfWeight = FW_BOLD;
lstrcpy(TitleLogFont.lfFaceName, TEXT("Verdana Bold")); lstrcpy(TitleLogFont.lfFaceName, TEXT("Verdana Bold"));
//StringCchCopy(TitleLogFont.lfFaceName, 32, TEXT("Verdana Bold")); //StringCchCopy(TitleLogFont.lfFaceName, 32, TEXT("Verdana Bold"));
HDC hdc = GetDC(NULL); //gets the screen DC HDC hdc = GetDC(NULL); //gets the screen DC
int FontSize = 12; int FontSize = 12;
TitleLogFont.lfHeight = 0 - GetDeviceCaps(hdc, LOGPIXELSY) * FontSize / 72; TitleLogFont.lfHeight = 0 - GetDeviceCaps(hdc, LOGPIXELSY) * FontSize / 72;
hTitleFont = CreateFontIndirect(&TitleLogFont); hTitleFont = CreateFontIndirect(&TitleLogFont);
ReleaseDC(NULL, hdc); ReleaseDC(NULL, hdc);
} }
else else
hTitleFont = 0; hTitleFont = 0;
centered=false; centered=false;
PropertySheet(&sheet); PropertySheet(&sheet);
if (!floating) if (!floating)
{ {
for (DlgList::iterator iter = list.begin(); iter != list.end(); iter++) for (DlgList::iterator iter = list.begin(); iter != list.end(); iter++)
{ {
delete iter->tab; delete iter->tab;
} }
DeleteObject(hTitleFont); DeleteObject(hTitleFont);
} }
DeleteObject(hDialogFont); DeleteObject(hDialogFont);
delete [] pages; delete [] pages;
} }
void PropSheet::Add(Tab *tab, LPCTSTR resource, LPCTSTR title, LPCTSTR subtitle) void PropSheet::Add(Tab *tab, LPCTSTR resource, LPCTSTR title, LPCTSTR subtitle)
{ {
tab->sheet = this; tab->sheet = this;
list.push_back(Page(tab,resource,title,subtitle)); list.push_back(Page(tab,resource,title,subtitle));
} }
void WizExteriorPage::Init(HWND hDlg) void WizExteriorPage::Init(HWND hDlg)
{ {
HWND hwndControl = GetDlgItem(hDlg, captionID); HWND hwndControl = GetDlgItem(hDlg, captionID);
//SetWindowFont(hwndControl, sheet->GetTitleFont(), TRUE); //SetWindowFont(hwndControl, sheet->GetTitleFont(), TRUE);
SendMessage(hwndControl,WM_SETFONT,(WPARAM)sheet->GetTitleFont(),0); SendMessage(hwndControl,WM_SETFONT,(WPARAM)sheet->GetTitleFont(),0);
} }
INT_PTR Tab::TabDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) INT_PTR Tab::TabDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{ {
Tab *tab = (Tab *)GetWindowLongPtr(hDlg, GWLP_USERDATA); Tab *tab = (Tab *)GetWindowLongPtr(hDlg, GWLP_USERDATA);
switch(message) switch(message)
{ {
case WM_INITDIALOG: case WM_INITDIALOG:
{ {
if (!centered) //HACK if (!centered) //HACK
{ {
CenterWindow(GetParent(hDlg)); CenterWindow(GetParent(hDlg));
centered=true; centered=true;
} }
LPARAM l = ((LPPROPSHEETPAGE)lParam)->lParam; LPARAM l = ((LPPROPSHEETPAGE)lParam)->lParam;
tab = (Tab *)l; tab = (Tab *)l;
SetWindowLongPtr(hDlg, GWLP_USERDATA, (DWORD_PTR)l); SetWindowLongPtr(hDlg, GWLP_USERDATA, (DWORD_PTR)l);
tab->Init(hDlg); tab->Init(hDlg);
} }
break; break;
case WM_COMMAND: case WM_COMMAND:
tab->Command(hDlg,wParam); tab->Command(hDlg,wParam);
break; break;
case WM_NOTIFY: case WM_NOTIFY:
{ {
LPPSHNOTIFY lppsn = (LPPSHNOTIFY) lParam; LPPSHNOTIFY lppsn = (LPPSHNOTIFY) lParam;
HWND sheet = lppsn->hdr.hwndFrom; HWND sheet = lppsn->hdr.hwndFrom;
switch(lppsn->hdr.code) { switch(lppsn->hdr.code) {
case PSN_APPLY: case PSN_APPLY:
tab->Apply(hDlg); tab->Apply(hDlg);
break; break;
case PSN_SETACTIVE: case PSN_SETACTIVE:
PropSheet_SetWizButtons(GetParent(hDlg), PropSheet_SetWizButtons(GetParent(hDlg),
(tab->HasPrev()?PSWIZB_BACK:0) | (tab->HasPrev()?PSWIZB_BACK:0) |
(tab->HasNext()?PSWIZB_NEXT:0) | (tab->HasNext()?PSWIZB_NEXT:0) |
(tab->HasFinish()?PSWIZB_FINISH:0)); (tab->HasFinish()?PSWIZB_FINISH:0));
break; break;
case PSN_WIZNEXT: case PSN_WIZNEXT:
tab->Apply(hDlg); //maybe not always good tab->Apply(hDlg); //maybe not always good
break; break;
case PSN_WIZBACK: case PSN_WIZBACK:
case PSN_RESET: //cancel case PSN_RESET: //cancel
break; break;
} }
} }
break; break;
} }
return 0; return 0;
} }
} }

View File

@ -1,124 +1,124 @@
#include <shlobj.h> #include <shlobj.h>
#include <xstring> #include <xstring>
#include <string> #include <string>
#include "ShellUtil.h" #include "ShellUtil.h"
namespace W32Util namespace W32Util
{ {
std::string BrowseForFolder(HWND parent, char *title) std::string BrowseForFolder(HWND parent, char *title)
{ {
BROWSEINFO info; BROWSEINFO info;
memset(&info,0,sizeof(info)); memset(&info,0,sizeof(info));
info.hwndOwner = parent; info.hwndOwner = parent;
info.lpszTitle = title; info.lpszTitle = title;
info.ulFlags = BIF_EDITBOX | BIF_RETURNONLYFSDIRS; info.ulFlags = BIF_EDITBOX | BIF_RETURNONLYFSDIRS;
//info.pszDisplayName //info.pszDisplayName
LPCITEMIDLIST idList = SHBrowseForFolder(&info); LPCITEMIDLIST idList = SHBrowseForFolder(&info);
char temp[MAX_PATH]; char temp[MAX_PATH];
SHGetPathFromIDList(idList, temp); SHGetPathFromIDList(idList, temp);
if (strlen(temp)) if (strlen(temp))
{ {
return temp; return temp;
} }
else else
return ""; return "";
} }
//--------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------
// function WinBrowseForFileName // function WinBrowseForFileName
//--------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------
bool BrowseForFileName (bool _bLoad, HWND _hParent, const char *_pTitle, bool BrowseForFileName (bool _bLoad, HWND _hParent, const char *_pTitle,
const char *_pInitialFolder,const char *_pFilter,const char *_pExtension, const char *_pInitialFolder,const char *_pFilter,const char *_pExtension,
std::string& _strFileName) std::string& _strFileName)
{ {
char szFile [MAX_PATH+1]; char szFile [MAX_PATH+1];
char szFileTitle [MAX_PATH+1]; char szFileTitle [MAX_PATH+1];
strcpy (szFile,""); strcpy (szFile,"");
strcpy (szFileTitle,""); strcpy (szFileTitle,"");
OPENFILENAME ofn; OPENFILENAME ofn;
ZeroMemory (&ofn,sizeof (ofn)); ZeroMemory (&ofn,sizeof (ofn));
ofn.lStructSize = sizeof (OPENFILENAME); ofn.lStructSize = sizeof (OPENFILENAME);
ofn.lpstrInitialDir = _pInitialFolder; ofn.lpstrInitialDir = _pInitialFolder;
ofn.lpstrFilter = _pFilter; ofn.lpstrFilter = _pFilter;
ofn.nMaxFile = sizeof (szFile); ofn.nMaxFile = sizeof (szFile);
ofn.lpstrFile = szFile; ofn.lpstrFile = szFile;
ofn.lpstrFileTitle = szFileTitle; ofn.lpstrFileTitle = szFileTitle;
ofn.nMaxFileTitle = sizeof (szFileTitle); ofn.nMaxFileTitle = sizeof (szFileTitle);
ofn.lpstrDefExt = _pExtension; ofn.lpstrDefExt = _pExtension;
ofn.hwndOwner = _hParent; ofn.hwndOwner = _hParent;
ofn.Flags = OFN_NOCHANGEDIR | OFN_EXPLORER | OFN_HIDEREADONLY; ofn.Flags = OFN_NOCHANGEDIR | OFN_EXPLORER | OFN_HIDEREADONLY;
if (_strFileName.size () != 0) if (_strFileName.size () != 0)
ofn.lpstrFile = (char *)_strFileName.c_str(); ofn.lpstrFile = (char *)_strFileName.c_str();
if (((_bLoad)?GetOpenFileName (&ofn):GetSaveFileName (&ofn))) if (((_bLoad)?GetOpenFileName (&ofn):GetSaveFileName (&ofn)))
{ {
_strFileName = ofn.lpstrFile; _strFileName = ofn.lpstrFile;
return true; return true;
} }
else else
return false; return false;
} }
std::vector<std::string> BrowseForFileNameMultiSelect(bool _bLoad, HWND _hParent, const char *_pTitle, std::vector<std::string> BrowseForFileNameMultiSelect(bool _bLoad, HWND _hParent, const char *_pTitle,
const char *_pInitialFolder,const char *_pFilter,const char *_pExtension) const char *_pInitialFolder,const char *_pFilter,const char *_pExtension)
{ {
char szFile [MAX_PATH+1+2048*2]; char szFile [MAX_PATH+1+2048*2];
char szFileTitle [MAX_PATH+1]; char szFileTitle [MAX_PATH+1];
strcpy (szFile,""); strcpy (szFile,"");
strcpy (szFileTitle,""); strcpy (szFileTitle,"");
OPENFILENAME ofn; OPENFILENAME ofn;
ZeroMemory (&ofn,sizeof (ofn)); ZeroMemory (&ofn,sizeof (ofn));
ofn.lStructSize = sizeof (OPENFILENAME); ofn.lStructSize = sizeof (OPENFILENAME);
ofn.lpstrInitialDir = _pInitialFolder; ofn.lpstrInitialDir = _pInitialFolder;
ofn.lpstrFilter = _pFilter; ofn.lpstrFilter = _pFilter;
ofn.nMaxFile = sizeof (szFile); ofn.nMaxFile = sizeof (szFile);
ofn.lpstrFile = szFile; ofn.lpstrFile = szFile;
ofn.lpstrFileTitle = szFileTitle; ofn.lpstrFileTitle = szFileTitle;
ofn.nMaxFileTitle = sizeof (szFileTitle); ofn.nMaxFileTitle = sizeof (szFileTitle);
ofn.lpstrDefExt = _pExtension; ofn.lpstrDefExt = _pExtension;
ofn.hwndOwner = _hParent; ofn.hwndOwner = _hParent;
ofn.Flags = OFN_NOCHANGEDIR | OFN_EXPLORER | OFN_HIDEREADONLY | OFN_ALLOWMULTISELECT ; ofn.Flags = OFN_NOCHANGEDIR | OFN_EXPLORER | OFN_HIDEREADONLY | OFN_ALLOWMULTISELECT ;
std::vector<std::string> files; std::vector<std::string> files;
if (((_bLoad)?GetOpenFileName (&ofn):GetSaveFileName (&ofn))) if (((_bLoad)?GetOpenFileName (&ofn):GetSaveFileName (&ofn)))
{ {
std::string directory = ofn.lpstrFile; std::string directory = ofn.lpstrFile;
char *temp = ofn.lpstrFile; char *temp = ofn.lpstrFile;
char *oldtemp = temp; char *oldtemp = temp;
temp+=strlen(temp)+1; temp+=strlen(temp)+1;
if (*temp==0) if (*temp==0)
{ {
//we only got one file //we only got one file
files.push_back(std::string(oldtemp)); files.push_back(std::string(oldtemp));
} }
else else
{ {
while (*temp) while (*temp)
{ {
files.push_back(directory+"\\"+std::string(temp)); files.push_back(directory+"\\"+std::string(temp));
temp+=strlen(temp)+1; temp+=strlen(temp)+1;
} }
} }
return files; return files;
} }
else else
return std::vector<std::string>(); // empty vector; return std::vector<std::string>(); // empty vector;
} }
} }

View File

@ -1,94 +1,94 @@
#include <commctrl.h> #include <commctrl.h>
#include "TabControl.h" #include "TabControl.h"
namespace W32Util namespace W32Util
{ {
// __________________________________________________________________________________________________ // __________________________________________________________________________________________________
// constructor // constructor
// //
TabControl::TabControl(HINSTANCE _hInstance, HWND _hTabCtrl,DLGPROC _lpDialogFunc) : TabControl::TabControl(HINSTANCE _hInstance, HWND _hTabCtrl,DLGPROC _lpDialogFunc) :
m_hInstance(_hInstance), m_hInstance(_hInstance),
m_hTabCtrl(_hTabCtrl), m_hTabCtrl(_hTabCtrl),
m_numDialogs(0) m_numDialogs(0)
{ {
for (int i=0; i<MAX_WIN_DIALOGS; i++) for (int i=0; i<MAX_WIN_DIALOGS; i++)
m_WinDialogs[i] = NULL; m_WinDialogs[i] = NULL;
} }
// __________________________________________________________________________________________________ // __________________________________________________________________________________________________
// destructor // destructor
// //
TabControl::~TabControl(void) TabControl::~TabControl(void)
{} {}
// __________________________________________________________________________________________________ // __________________________________________________________________________________________________
// AddItem // AddItem
// //
HWND TabControl::AddItem (char* _szText,int _iResource,DLGPROC _lpDialogFunc) HWND TabControl::AddItem (char* _szText,int _iResource,DLGPROC _lpDialogFunc)
{ {
TCITEM tcItem; TCITEM tcItem;
ZeroMemory (&tcItem,sizeof (tcItem)); ZeroMemory (&tcItem,sizeof (tcItem));
tcItem.mask = TCIF_TEXT | TCIF_IMAGE; tcItem.mask = TCIF_TEXT | TCIF_IMAGE;
tcItem.dwState = 0; tcItem.dwState = 0;
tcItem.pszText = _szText; tcItem.pszText = _szText;
tcItem.cchTextMax = sizeof (_szText); tcItem.cchTextMax = sizeof (_szText);
tcItem.iImage = -1; tcItem.iImage = -1;
int nResult = TabCtrl_InsertItem (m_hTabCtrl,TabCtrl_GetItemCount (m_hTabCtrl),&tcItem); int nResult = TabCtrl_InsertItem (m_hTabCtrl,TabCtrl_GetItemCount (m_hTabCtrl),&tcItem);
HWND hDialog = CreateDialog(m_hInstance,(LPCSTR)_iResource,m_hTabCtrl,_lpDialogFunc); HWND hDialog = CreateDialog(m_hInstance,(LPCSTR)_iResource,m_hTabCtrl,_lpDialogFunc);
RECT rectInnerWindow = {0,0,0,0}; RECT rectInnerWindow = {0,0,0,0};
GetWindowRect (m_hTabCtrl,&rectInnerWindow); GetWindowRect (m_hTabCtrl,&rectInnerWindow);
TabCtrl_AdjustRect (m_hTabCtrl,FALSE,&rectInnerWindow); TabCtrl_AdjustRect (m_hTabCtrl,FALSE,&rectInnerWindow);
POINT pntPosition = {rectInnerWindow.left,rectInnerWindow.top}; POINT pntPosition = {rectInnerWindow.left,rectInnerWindow.top};
ScreenToClient(m_hTabCtrl, &pntPosition); ScreenToClient(m_hTabCtrl, &pntPosition);
SetWindowPos(hDialog, 0, SetWindowPos(hDialog, 0,
pntPosition.x, pntPosition.y, pntPosition.x, pntPosition.y,
rectInnerWindow.right - rectInnerWindow.left,rectInnerWindow.bottom - rectInnerWindow.top,0); rectInnerWindow.right - rectInnerWindow.left,rectInnerWindow.bottom - rectInnerWindow.top,0);
ShowWindow(hDialog,SW_NORMAL); ShowWindow(hDialog,SW_NORMAL);
m_WinDialogs[m_numDialogs] = hDialog; m_WinDialogs[m_numDialogs] = hDialog;
m_numDialogs++; m_numDialogs++;
SelectDialog (0); SelectDialog (0);
return hDialog; return hDialog;
} }
// __________________________________________________________________________________________________ // __________________________________________________________________________________________________
// SelectDialog // SelectDialog
// //
void TabControl::SelectDialog (int _nDialogId) void TabControl::SelectDialog (int _nDialogId)
{ {
for (int i = 0 ; i < m_numDialogs ; i ++) for (int i = 0 ; i < m_numDialogs ; i ++)
if (m_WinDialogs[i] != NULL) if (m_WinDialogs[i] != NULL)
ShowWindow(m_WinDialogs[i],i == _nDialogId ? SW_NORMAL : SW_HIDE); ShowWindow(m_WinDialogs[i],i == _nDialogId ? SW_NORMAL : SW_HIDE);
} }
// __________________________________________________________________________________________________ // __________________________________________________________________________________________________
// MessageHandler // MessageHandler
// //
void TabControl::MessageHandler(UINT message, WPARAM wParam, LPARAM lParam) void TabControl::MessageHandler(UINT message, WPARAM wParam, LPARAM lParam)
{ {
if (message == WM_NOTIFY) if (message == WM_NOTIFY)
{ {
NMHDR* pNotifyMessage = NULL; NMHDR* pNotifyMessage = NULL;
pNotifyMessage = (LPNMHDR)lParam; pNotifyMessage = (LPNMHDR)lParam;
if (pNotifyMessage->hwndFrom == m_hTabCtrl) if (pNotifyMessage->hwndFrom == m_hTabCtrl)
{ {
int iPage = TabCtrl_GetCurSel (m_hTabCtrl); int iPage = TabCtrl_GetCurSel (m_hTabCtrl);
SelectDialog (iPage); SelectDialog (iPage);
} }
} }
} }
} }

View File

@ -1,82 +1,82 @@
#include "Thread.h" #include "Thread.h"
namespace W32Util namespace W32Util
{ {
// __________________________________________________________________________________________________ // __________________________________________________________________________________________________
// Constructor // Constructor
// //
Thread::Thread ( DWORD (WINAPI * pFun) (void* arg), void* pArg) Thread::Thread ( DWORD (WINAPI * pFun) (void* arg), void* pArg)
{ {
_handle = CreateThread ( _handle = CreateThread (
0, // Security attributes 0, // Security attributes
0, // Stack size 0, // Stack size
pFun, pFun,
pArg, pArg,
CREATE_SUSPENDED, CREATE_SUSPENDED,
&_tid); &_tid);
} }
// __________________________________________________________________________________________________ // __________________________________________________________________________________________________
// Destructor // Destructor
// //
Thread::~Thread (void) Thread::~Thread (void)
{ {
if (_handle != NULL) if (_handle != NULL)
{ {
if (CloseHandle (_handle) == FALSE) if (CloseHandle (_handle) == FALSE)
{ {
Terminate(); Terminate();
} }
} }
} }
// __________________________________________________________________________________________________ // __________________________________________________________________________________________________
// Resume // Resume
// //
void void
Thread::Resume (void) Thread::Resume (void)
{ {
if (_handle != NULL) if (_handle != NULL)
ResumeThread (_handle); ResumeThread (_handle);
} }
// __________________________________________________________________________________________________ // __________________________________________________________________________________________________
// WaitForDeath // WaitForDeath
// //
void void
Thread::WaitForDeath (void) Thread::WaitForDeath (void)
{ {
if (_handle != NULL) if (_handle != NULL)
WaitForSingleObject (_handle, 100); WaitForSingleObject (_handle, 100);
} }
// __________________________________________________________________________________________________ // __________________________________________________________________________________________________
// Terminate // Terminate
// //
void void
Thread::Terminate (void) Thread::Terminate (void)
{ {
if (_handle != NULL) if (_handle != NULL)
TerminateThread (_handle, 0); TerminateThread (_handle, 0);
_handle = NULL; _handle = NULL;
} }
// __________________________________________________________________________________________________ // __________________________________________________________________________________________________
// SetPriority // SetPriority
// //
void void
Thread::SetPriority (int _nPriority) Thread::SetPriority (int _nPriority)
{ {
if (_handle != NULL) if (_handle != NULL)
SetThreadPriority(_handle, _nPriority); SetThreadPriority(_handle, _nPriority);
} }
// __________________________________________________________________________________________________ // __________________________________________________________________________________________________
// Suspend // Suspend
// //
void void
Thread::Suspend (void) Thread::Suspend (void)
{ {
if (_handle != NULL) if (_handle != NULL)
SuspendThread(_handle); SuspendThread(_handle);
} }
} }

View File

@ -1,136 +1,136 @@
// 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 "stdafx.h" #include "stdafx.h"
#include "Profiler.h" #include "Profiler.h"
#include "XFStructs.h" #include "XFStructs.h"
#include "Render.h" #include "Render.h"
#include "main.h" #include "main.h"
#include "VertexManager.h" #include "VertexManager.h"
#include "Utils.h" #include "Utils.h"
// LoadXFReg 0x10 // LoadXFReg 0x10
void LoadXFReg(u32 transferSize, u32 baseAddress, u32 *pData) void LoadXFReg(u32 transferSize, u32 baseAddress, u32 *pData)
{ {
DVSTARTPROFILE(); DVSTARTPROFILE();
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)
{ {
u32* p1 = &xfmem[address]; u32* p1 = &xfmem[address];
memcpy(p1, &pData[i], transferSize*4); memcpy(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 0x1006: case 0x1006:
//SetGPMetric //SetGPMetric
break; break;
case 0x1008: //__GXXfVtxSpecs, wrote 0004 case 0x1008: //__GXXfVtxSpecs, wrote 0004
break; break;
case 0x1009: //GXSetNumChans (no) case 0x1009: //GXSetNumChans (no)
break; break;
case 0x100a: xfregs.colChans[0].ambColor = data; break; //GXSetChanAmbientcolor case 0x100a: xfregs.colChans[0].ambColor = data; break; //GXSetChanAmbientcolor
case 0x100b: xfregs.colChans[1].ambColor = data; break; //GXSetChanAmbientcolor case 0x100b: xfregs.colChans[1].ambColor = data; break; //GXSetChanAmbientcolor
case 0x100c: xfregs.colChans[0].matColor = data; break; //GXSetChanMatcolor (rgba) case 0x100c: xfregs.colChans[0].matColor = data; break; //GXSetChanMatcolor (rgba)
case 0x100d: xfregs.colChans[1].matColor = data; break; //GXSetChanMatcolor (rgba) case 0x100d: xfregs.colChans[1].matColor = data; break; //GXSetChanMatcolor (rgba)
case 0x100e: xfregs.colChans[0].color.hex = data; break; //color0 case 0x100e: xfregs.colChans[0].color.hex = data; break; //color0
case 0x100f: xfregs.colChans[1].color.hex = data; break; //color1 case 0x100f: xfregs.colChans[1].color.hex = data; break; //color1
case 0x1010: xfregs.colChans[0].alpha.hex = data; break; //alpha0 case 0x1010: xfregs.colChans[0].alpha.hex = data; break; //alpha0
case 0x1011: xfregs.colChans[1].alpha.hex = data; break; //alpha1 case 0x1011: xfregs.colChans[1].alpha.hex = data; break; //alpha1
case 0x1018: case 0x1018:
break; break;
case 0x101a: case 0x101a:
VertexManager::Flush(); VertexManager::Flush();
memcpy(xfregs.rawViewport, &pData[i], sizeof(xfregs.rawViewport)); memcpy(xfregs.rawViewport, &pData[i], sizeof(xfregs.rawViewport));
XFUpdateVP(); XFUpdateVP();
i += 6; i += 6;
break; break;
case 0x1020: case 0x1020:
VertexManager::Flush(); VertexManager::Flush();
memcpy(xfregs.rawProjection, &pData[i], sizeof(xfregs.rawProjection)); memcpy(xfregs.rawProjection, &pData[i], sizeof(xfregs.rawProjection));
XFUpdatePJ(); XFUpdatePJ();
i += 7; i += 7;
return; return;
case 0x103f: case 0x103f:
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 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:
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
} }
} }
} }
// Check docs for this sucker... // Check docs for this sucker...
void LoadIndexedXF(u32 val, int array) void LoadIndexedXF(u32 val, int array)
{ {
DVSTARTPROFILE(); DVSTARTPROFILE();
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
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);
} }
void XFUpdateVP() void XFUpdateVP()
{ {
Renderer::SetViewport(xfregs.rawViewport); Renderer::SetViewport(xfregs.rawViewport);
} }
void XFUpdatePJ() void XFUpdatePJ()
{ {
Renderer::SetProjection(xfregs.rawProjection, 0); Renderer::SetProjection(xfregs.rawProjection, 0);
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,322 +1,322 @@
// 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 <tchar.h> #include <tchar.h>
#include <windows.h> #include <windows.h>
#include <d3dx9.h> #include <d3dx9.h>
#include "Common.h" #include "Common.h"
#include "svnrev.h" #include "svnrev.h"
#include "resource.h" #include "resource.h"
#include "main.h" #include "main.h"
#include "Config.h" #include "Config.h"
#include "Fifo.h" #include "Fifo.h"
#include "OpcodeDecoding.h" #include "OpcodeDecoding.h"
#include "TextureCache.h" #include "TextureCache.h"
#include "BPStructs.h" #include "BPStructs.h"
#include "VertexManager.h" #include "VertexManager.h"
#include "TransformEngine.h" #include "TransformEngine.h"
#include "DlgSettings.h" #include "DlgSettings.h"
#include "D3DPostprocess.h" #include "D3DPostprocess.h"
#include "D3DTexture.h" #include "D3DTexture.h"
#include "D3DUtil.h" #include "D3DUtil.h"
#include "W32Util/Misc.h" #include "W32Util/Misc.h"
#include "EmuWindow.h" #include "EmuWindow.h"
#include "VideoState.h" #include "VideoState.h"
#include "XFBConvert.h" #include "XFBConvert.h"
#include "Utils.h" #include "Utils.h"
HINSTANCE g_hInstance = NULL; HINSTANCE g_hInstance = NULL;
SVideoInitialize g_VideoInitialize; SVideoInitialize g_VideoInitialize;
int initCount = 0; int initCount = 0;
void DllDebugger(HWND _hParent, bool Show) void DllDebugger(HWND _hParent, bool Show)
{ {
// TODO: implement // TODO: implement
} }
BOOL APIENTRY DllMain( HINSTANCE hinstDLL, // DLL module handle BOOL APIENTRY DllMain( HINSTANCE hinstDLL, // DLL module handle
DWORD dwReason, // reason called DWORD dwReason, // reason called
LPVOID lpvReserved) // reserved LPVOID lpvReserved) // reserved
{ {
switch (dwReason) switch (dwReason)
{ {
case DLL_PROCESS_ATTACH: case DLL_PROCESS_ATTACH:
break; break;
case DLL_PROCESS_DETACH: case DLL_PROCESS_DETACH:
break; break;
default: default:
break; break;
} }
g_hInstance = hinstDLL; g_hInstance = hinstDLL;
return TRUE; return TRUE;
} }
BOOL Callback_PeekMessages() BOOL Callback_PeekMessages()
{ {
//TODO: peek message //TODO: peek message
MSG msg; MSG msg;
while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
{ {
if (msg.message == WM_QUIT) if (msg.message == WM_QUIT)
return FALSE; return FALSE;
TranslateMessage(&msg); TranslateMessage(&msg);
DispatchMessage(&msg); DispatchMessage(&msg);
} }
return TRUE; return TRUE;
} }
void UpdateFPSDisplay(const char *text) void UpdateFPSDisplay(const char *text)
{ {
char temp[512]; char temp[512];
sprintf_s(temp, 512, "SVN R%i: DX9: %s", SVN_REV, text); sprintf_s(temp, 512, "SVN R%i: DX9: %s", SVN_REV, text);
SetWindowText( EmuWindow::GetWnd(), temp); SetWindowText( EmuWindow::GetWnd(), temp);
} }
bool Init() bool Init()
{ {
g_Config.Load(); g_Config.Load();
if (initCount == 0) if (initCount == 0)
{ {
// create the window // create the window
if ( !g_Config.renderToMainframe || g_VideoInitialize.pWindowHandle == NULL ) // ignore parent for this plugin if ( !g_Config.renderToMainframe || g_VideoInitialize.pWindowHandle == NULL ) // ignore parent for this plugin
{ {
g_VideoInitialize.pWindowHandle = (void*)EmuWindow::Create(NULL, g_hInstance, "Loading - Please wait."); g_VideoInitialize.pWindowHandle = (void*)EmuWindow::Create(NULL, g_hInstance, "Loading - Please wait.");
} }
else else
{ {
g_VideoInitialize.pWindowHandle = (void*)EmuWindow::Create((HWND)g_VideoInitialize.pWindowHandle, g_hInstance, "Loading - Please wait."); g_VideoInitialize.pWindowHandle = (void*)EmuWindow::Create((HWND)g_VideoInitialize.pWindowHandle, g_hInstance, "Loading - Please wait.");
} }
if ( g_VideoInitialize.pWindowHandle == NULL ) if ( g_VideoInitialize.pWindowHandle == NULL )
{ {
MessageBox(GetActiveWindow(), "An error has occurred while trying to create the window.", "Fatal Error", MB_OK); MessageBox(GetActiveWindow(), "An error has occurred while trying to create the window.", "Fatal Error", MB_OK);
return false; return false;
} }
EmuWindow::Show(); EmuWindow::Show();
g_VideoInitialize.pPeekMessages = Callback_PeekMessages; g_VideoInitialize.pPeekMessages = Callback_PeekMessages;
g_VideoInitialize.pUpdateFPSDisplay = UpdateFPSDisplay; g_VideoInitialize.pUpdateFPSDisplay = UpdateFPSDisplay;
if (FAILED(D3D::Init())) if (FAILED(D3D::Init()))
{ {
MessageBox(GetActiveWindow(), "Unable to initialize Direct3D. Please make sure that you have DirectX 9.0c correctly installed.", "Fatal Error", MB_OK); MessageBox(GetActiveWindow(), "Unable to initialize Direct3D. Please make sure that you have DirectX 9.0c correctly installed.", "Fatal Error", MB_OK);
return false; return false;
} }
InitLUTs(); InitLUTs();
InitXFBConvTables(); InitXFBConvTables();
} }
initCount++; initCount++;
return true; return true;
} }
void DeInit() void DeInit()
{ {
initCount--; initCount--;
if (initCount==0) if (initCount==0)
{ {
D3D::Shutdown(); D3D::Shutdown();
EmuWindow::Close(); EmuWindow::Close();
} }
} }
// ==================================================================================== // ====================================================================================
void GetDllInfo (PLUGIN_INFO* _PluginInfo) void GetDllInfo (PLUGIN_INFO* _PluginInfo)
{ {
_PluginInfo->Version = 0x0100; _PluginInfo->Version = 0x0100;
_PluginInfo->Type = PLUGIN_TYPE_VIDEO; _PluginInfo->Type = PLUGIN_TYPE_VIDEO;
#ifdef DEBUGFAST #ifdef DEBUGFAST
sprintf_s(_PluginInfo->Name, 100, "Dolphin Video Plugin DebugFast (DX9)"); sprintf_s(_PluginInfo->Name, 100, "Dolphin Video Plugin DebugFast (DX9)");
#else #else
#ifndef _DEBUG #ifndef _DEBUG
sprintf_s(_PluginInfo->Name, 100, "Dolphin Video Plugin (DX9)"); sprintf_s(_PluginInfo->Name, 100, "Dolphin Video Plugin (DX9)");
#else #else
sprintf_s(_PluginInfo->Name, 100, "Dolphin Video Plugin Debug (DX9)"); sprintf_s(_PluginInfo->Name, 100, "Dolphin Video Plugin Debug (DX9)");
#endif #endif
#endif #endif
} }
void DllAbout(HWND _hParent) void DllAbout(HWND _hParent)
{ {
DialogBox(g_hInstance,(LPCSTR)IDD_ABOUT,_hParent,(DLGPROC)AboutProc); DialogBox(g_hInstance,(LPCSTR)IDD_ABOUT,_hParent,(DLGPROC)AboutProc);
} }
void DllConfig(HWND _hParent) void DllConfig(HWND _hParent)
{ {
if (Init()) if (Init())
{ {
DlgSettings_Show(g_hInstance,_hParent); DlgSettings_Show(g_hInstance,_hParent);
DeInit(); DeInit();
} }
} }
void Video_Initialize(SVideoInitialize* _pVideoInitialize) void Video_Initialize(SVideoInitialize* _pVideoInitialize)
{ {
if (_pVideoInitialize == NULL) if (_pVideoInitialize == NULL)
return; return;
frameCount = 0; frameCount = 0;
g_VideoInitialize = *_pVideoInitialize; g_VideoInitialize = *_pVideoInitialize;
Init(); Init();
_pVideoInitialize->pPeekMessages = g_VideoInitialize.pPeekMessages; _pVideoInitialize->pPeekMessages = g_VideoInitialize.pPeekMessages;
_pVideoInitialize->pUpdateFPSDisplay = g_VideoInitialize.pUpdateFPSDisplay; _pVideoInitialize->pUpdateFPSDisplay = g_VideoInitialize.pUpdateFPSDisplay;
_pVideoInitialize->pWindowHandle = g_VideoInitialize.pWindowHandle; _pVideoInitialize->pWindowHandle = g_VideoInitialize.pWindowHandle;
Renderer::AddMessage("Dolphin Direct3D9 Video Plugin.",5000); Renderer::AddMessage("Dolphin Direct3D9 Video Plugin.",5000);
} }
void Video_DoState(unsigned char **ptr, int mode) { void Video_DoState(unsigned char **ptr, int mode) {
// Clear all caches // Clear all caches
TextureCache::Invalidate(); TextureCache::Invalidate();
PointerWrap p(ptr, mode); PointerWrap p(ptr, mode);
VideoCommon_DoState(p); VideoCommon_DoState(p);
//PanicAlert("Saving/Loading state from DirectX9"); //PanicAlert("Saving/Loading state from DirectX9");
} }
void Video_EnterLoop() void Video_EnterLoop()
{ {
Fifo_EnterLoop(g_VideoInitialize); Fifo_EnterLoop(g_VideoInitialize);
} }
void Video_Prepare(void) void Video_Prepare(void)
{ {
Renderer::Init(g_VideoInitialize); Renderer::Init(g_VideoInitialize);
TextureCache::Init(); TextureCache::Init();
BPInit(); BPInit();
VertexManager::Init(); VertexManager::Init();
Fifo_Init(); Fifo_Init();
OpcodeDecoder_Init(); OpcodeDecoder_Init();
} }
void Video_Shutdown(void) void Video_Shutdown(void)
{ {
Fifo_Shutdown(); Fifo_Shutdown();
VertexManager::Shutdown(); VertexManager::Shutdown();
TextureCache::Shutdown(); TextureCache::Shutdown();
Renderer::Shutdown(); Renderer::Shutdown();
OpcodeDecoder_Shutdown(); OpcodeDecoder_Shutdown();
DeInit(); DeInit();
} }
void Video_Stop(void) void Video_Stop(void)
{ {
} }
void Video_UpdateXFB(u8* /*_pXFB*/, u32 /*_dwWidth*/, u32 /*_dwHeight*/, s32 /*_dwYOffset*/) void Video_UpdateXFB(u8* /*_pXFB*/, u32 /*_dwWidth*/, u32 /*_dwHeight*/, s32 /*_dwYOffset*/)
{ {
/* /*
ConvertXFB(tempBuffer, _pXFB, _dwWidth, _dwHeight); ConvertXFB(tempBuffer, _pXFB, _dwWidth, _dwHeight);
// blubb // blubb
static LPDIRECT3DTEXTURE9 pTexture = D3D::CreateTexture2D((BYTE*)tempBuffer, _dwWidth, _dwHeight, _dwWidth, D3DFMT_A8R8G8B8); static LPDIRECT3DTEXTURE9 pTexture = D3D::CreateTexture2D((BYTE*)tempBuffer, _dwWidth, _dwHeight, _dwWidth, D3DFMT_A8R8G8B8);
D3D::ReplaceTexture2D(pTexture, (BYTE*)tempBuffer, _dwWidth, _dwHeight, _dwWidth, D3DFMT_A8R8G8B8); D3D::ReplaceTexture2D(pTexture, (BYTE*)tempBuffer, _dwWidth, _dwHeight, _dwWidth, D3DFMT_A8R8G8B8);
D3D::dev->SetTexture(0, pTexture); D3D::dev->SetTexture(0, pTexture);
D3D::quad2d(0,0,(float)Postprocess::GetWidth(),(float)Postprocess::GetHeight(), 0xFFFFFFFF); D3D::quad2d(0,0,(float)Postprocess::GetWidth(),(float)Postprocess::GetHeight(), 0xFFFFFFFF);
D3D::EndFrame(); D3D::EndFrame();
D3D::BeginFrame();*/ D3D::BeginFrame();*/
} }
void DebugLog(const char* _fmt, ...) void DebugLog(const char* _fmt, ...)
{ {
#ifdef _DEBUG #ifdef _DEBUG
char Msg[512]; char Msg[512];
va_list ap; va_list ap;
va_start( ap, _fmt ); va_start( ap, _fmt );
vsprintf( Msg, _fmt, ap ); vsprintf( Msg, _fmt, ap );
va_end( ap ); va_end( ap );
g_VideoInitialize.pLog(Msg, FALSE); g_VideoInitialize.pLog(Msg, FALSE);
#endif #endif
} }
void __Log(int log, const char *format, ...) void __Log(int log, const char *format, ...)
{ {
// char temp[512]; // char temp[512];
//va_list args; //va_list args;
//va_start(args, format); //va_start(args, format);
//CharArrayFromFormatV(temp, 512, format, args); //CharArrayFromFormatV(temp, 512, format, args);
//va_end(args); //va_end(args);
DebugLog(format); //"%s", temp); DebugLog(format); //"%s", temp);
} }
HRESULT ScreenShot(TCHAR *File) HRESULT ScreenShot(TCHAR *File)
{ {
if (D3D::dev == NULL) if (D3D::dev == NULL)
return S_FALSE; return S_FALSE;
D3DDISPLAYMODE DisplayMode; D3DDISPLAYMODE DisplayMode;
if (FAILED(D3D::dev->GetDisplayMode(0, &DisplayMode))) if (FAILED(D3D::dev->GetDisplayMode(0, &DisplayMode)))
return S_FALSE; return S_FALSE;
LPDIRECT3DSURFACE9 surf; LPDIRECT3DSURFACE9 surf;
if (FAILED(D3D::dev->CreateOffscreenPlainSurface(DisplayMode.Width, DisplayMode.Height, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf, NULL))) if (FAILED(D3D::dev->CreateOffscreenPlainSurface(DisplayMode.Width, DisplayMode.Height, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surf, NULL)))
return S_FALSE; return S_FALSE;
if (FAILED(D3D::dev->GetFrontBufferData(0, surf))) if (FAILED(D3D::dev->GetFrontBufferData(0, surf)))
{ {
surf->Release(); surf->Release();
return S_FALSE; return S_FALSE;
} }
RECT rect; RECT rect;
::GetWindowRect(EmuWindow::GetWnd(), &rect); ::GetWindowRect(EmuWindow::GetWnd(), &rect);
if (FAILED(D3DXSaveSurfaceToFile(File, D3DXIFF_JPG, surf, NULL, &rect))) if (FAILED(D3DXSaveSurfaceToFile(File, D3DXIFF_JPG, surf, NULL, &rect)))
{ {
surf->Release(); surf->Release();
return S_FALSE; return S_FALSE;
} }
surf->Release(); surf->Release();
return S_OK; return S_OK;
} }
BOOL Video_Screenshot(TCHAR* _szFilename) BOOL Video_Screenshot(TCHAR* _szFilename)
{ {
if (ScreenShot(_szFilename) == S_OK) if (ScreenShot(_szFilename) == S_OK)
return TRUE; return TRUE;
return FALSE; return FALSE;
} }
void Video_AddMessage(const char* pstr, u32 milliseconds) void Video_AddMessage(const char* pstr, u32 milliseconds)
{ {
Renderer::AddMessage(pstr,milliseconds); Renderer::AddMessage(pstr,milliseconds);
} }

View File

@ -1,18 +1,18 @@
// 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 "stdafx.h" #include "stdafx.h"

File diff suppressed because it is too large Load Diff

View File

@ -1,122 +1,122 @@
// 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 "Common.h" #include "Common.h"
#include "IniFile.h" #include "IniFile.h"
#include "Config.h" #include "Config.h"
Config g_Config; Config g_Config;
Config::Config() Config::Config()
{ {
memset(this, 0, sizeof(Config)); memset(this, 0, sizeof(Config));
} }
void Config::Load() void Config::Load()
{ {
std::string temp; std::string temp;
IniFile iniFile; IniFile iniFile;
iniFile.Load(FULL_CONFIG_DIR "gfx_opengl.ini"); iniFile.Load(FULL_CONFIG_DIR "gfx_opengl.ini");
// get resolution // get resolution
iniFile.Get("Hardware", "WindowedRes", &temp, 0); iniFile.Get("Hardware", "WindowedRes", &temp, 0);
if(temp.empty()) if(temp.empty())
temp = "640x480"; temp = "640x480";
strcpy(iWindowedRes, temp.c_str()); strcpy(iWindowedRes, temp.c_str());
iniFile.Get("Hardware", "FullscreenRes", &temp, 0); iniFile.Get("Hardware", "FullscreenRes", &temp, 0);
if(temp.empty()) if(temp.empty())
temp = "640x480"; temp = "640x480";
strcpy(iFSResolution, temp.c_str()); strcpy(iFSResolution, temp.c_str());
iniFile.Get("Hardware", "Fullscreen", &bFullscreen, 0); // Hardware iniFile.Get("Hardware", "Fullscreen", &bFullscreen, 0); // Hardware
iniFile.Get("Hardware", "RenderToMainframe", &renderToMainframe, 0); iniFile.Get("Hardware", "RenderToMainframe", &renderToMainframe, 0);
iniFile.Get("Settings", "StretchToFit", &bStretchToFit, false); iniFile.Get("Settings", "StretchToFit", &bStretchToFit, false);
iniFile.Get("Settings", "KeepAR", &bKeepAR, false); iniFile.Get("Settings", "KeepAR", &bKeepAR, false);
iniFile.Get("Settings", "HideCursor", &bHideCursor, false); iniFile.Get("Settings", "HideCursor", &bHideCursor, false);
iniFile.Get("Settings", "SafeTextureCache", &bSafeTextureCache, false); // Settings iniFile.Get("Settings", "SafeTextureCache", &bSafeTextureCache, false); // Settings
iniFile.Get("Settings", "ShowFPS", &bShowFPS, false); // Settings iniFile.Get("Settings", "ShowFPS", &bShowFPS, false); // Settings
iniFile.Get("Settings", "OverlayStats", &bOverlayStats, false); iniFile.Get("Settings", "OverlayStats", &bOverlayStats, false);
iniFile.Get("Settings", "DLOptimize", &iCompileDLsLevel, 0); iniFile.Get("Settings", "DLOptimize", &iCompileDLsLevel, 0);
iniFile.Get("Settings", "DumpTextures", &bDumpTextures, 0); iniFile.Get("Settings", "DumpTextures", &bDumpTextures, 0);
iniFile.Get("Settings", "ShowShaderErrors", &bShowShaderErrors, 0); iniFile.Get("Settings", "ShowShaderErrors", &bShowShaderErrors, 0);
iniFile.Get("Settings", "Multisample", &iMultisampleMode, 0); iniFile.Get("Settings", "Multisample", &iMultisampleMode, 0);
if (iMultisampleMode == 0) if (iMultisampleMode == 0)
iMultisampleMode = 1; iMultisampleMode = 1;
std::string s; std::string s;
iniFile.Get("Settings", "TexDumpPath", &s, 0); iniFile.Get("Settings", "TexDumpPath", &s, 0);
if (s.size() < sizeof(texDumpPath) ) if (s.size() < sizeof(texDumpPath) )
strcpy(texDumpPath, s.c_str()); strcpy(texDumpPath, s.c_str());
else { else {
strncpy(texDumpPath, s.c_str(), sizeof(texDumpPath)-1); strncpy(texDumpPath, s.c_str(), sizeof(texDumpPath)-1);
texDumpPath[sizeof(texDumpPath)-1] = 0; texDumpPath[sizeof(texDumpPath)-1] = 0;
} }
iniFile.Get("Settings", "TexFmtOverlayEnable", &bTexFmtOverlayEnable, 0); iniFile.Get("Settings", "TexFmtOverlayEnable", &bTexFmtOverlayEnable, 0);
iniFile.Get("Settings", "TexFmtOverlayCenter", &bTexFmtOverlayCenter, 0); iniFile.Get("Settings", "TexFmtOverlayCenter", &bTexFmtOverlayCenter, 0);
iniFile.Get("Settings", "UseXFB", &bUseXFB, 0); iniFile.Get("Settings", "UseXFB", &bUseXFB, 0);
iniFile.Get("Settings", "WireFrame", &bWireFrame, 0); iniFile.Get("Settings", "WireFrame", &bWireFrame, 0);
iniFile.Get("Settings", "DisableLighting", &bDisableLighting, 0); iniFile.Get("Settings", "DisableLighting", &bDisableLighting, 0);
iniFile.Get("Settings", "DisableTexturing", &bDisableTexturing, 0); iniFile.Get("Settings", "DisableTexturing", &bDisableTexturing, 0);
iniFile.Get("Enhancements", "ForceFiltering", &bForceFiltering, 0); iniFile.Get("Enhancements", "ForceFiltering", &bForceFiltering, 0);
iniFile.Get("Enhancements", "MaxAnisotropy", &iMaxAnisotropy, 3); // NOTE - this is x in (1 << x) iniFile.Get("Enhancements", "MaxAnisotropy", &iMaxAnisotropy, 3); // NOTE - this is x in (1 << x)
iniFile.Get("Hacks", "EFBToTextureDisable", &bEFBToTextureDisable, 0); iniFile.Get("Hacks", "EFBToTextureDisable", &bEFBToTextureDisable, 0);
iniFile.Get("Hacks", "EFBToTextureDisableHotKey", &bEFBToTextureDisableHotKey, 0); iniFile.Get("Hacks", "EFBToTextureDisableHotKey", &bEFBToTextureDisableHotKey, 0);
iniFile.Get("Hacks", "ProjectionHax1", &bProjectionHax1, 0); iniFile.Get("Hacks", "ProjectionHax1", &bProjectionHax1, 0);
iniFile.Get("Hacks", "ProjectionHax2", &bProjectionHax2, 0); iniFile.Get("Hacks", "ProjectionHax2", &bProjectionHax2, 0);
} }
void Config::Save() void Config::Save()
{ {
IniFile iniFile; IniFile iniFile;
iniFile.Load(FULL_CONFIG_DIR "gfx_opengl.ini"); iniFile.Load(FULL_CONFIG_DIR "gfx_opengl.ini");
iniFile.Set("Hardware", "WindowedRes", iWindowedRes); iniFile.Set("Hardware", "WindowedRes", iWindowedRes);
iniFile.Set("Hardware", "FullscreenRes", iFSResolution); iniFile.Set("Hardware", "FullscreenRes", iFSResolution);
iniFile.Set("Hardware", "Fullscreen", bFullscreen); iniFile.Set("Hardware", "Fullscreen", bFullscreen);
iniFile.Set("Hardware", "RenderToMainframe", renderToMainframe); iniFile.Set("Hardware", "RenderToMainframe", renderToMainframe);
iniFile.Set("Settings", "StretchToFit", bStretchToFit); iniFile.Set("Settings", "StretchToFit", bStretchToFit);
iniFile.Set("Settings", "KeepAR", bKeepAR); iniFile.Set("Settings", "KeepAR", bKeepAR);
iniFile.Set("Settings", "HideCursor", bHideCursor); iniFile.Set("Settings", "HideCursor", bHideCursor);
iniFile.Set("Settings", "SafeTextureCache", bSafeTextureCache); iniFile.Set("Settings", "SafeTextureCache", bSafeTextureCache);
iniFile.Set("Settings", "ShowFPS", bShowFPS); iniFile.Set("Settings", "ShowFPS", bShowFPS);
iniFile.Set("Settings", "OverlayStats", bOverlayStats); iniFile.Set("Settings", "OverlayStats", bOverlayStats);
iniFile.Set("Settings", "DLOptimize", iCompileDLsLevel); iniFile.Set("Settings", "DLOptimize", iCompileDLsLevel);
iniFile.Set("Settings", "DumpTextures", bDumpTextures); iniFile.Set("Settings", "DumpTextures", bDumpTextures);
iniFile.Set("Settings", "ShowShaderErrors", bShowShaderErrors); iniFile.Set("Settings", "ShowShaderErrors", bShowShaderErrors);
iniFile.Set("Settings", "Multisample", iMultisampleMode); iniFile.Set("Settings", "Multisample", iMultisampleMode);
iniFile.Set("Settings", "TexDumpPath", texDumpPath); iniFile.Set("Settings", "TexDumpPath", texDumpPath);
iniFile.Set("Settings", "TexFmtOverlayEnable", bTexFmtOverlayEnable); iniFile.Set("Settings", "TexFmtOverlayEnable", bTexFmtOverlayEnable);
iniFile.Set("Settings", "TexFmtOverlayCenter", bTexFmtOverlayCenter); iniFile.Set("Settings", "TexFmtOverlayCenter", bTexFmtOverlayCenter);
iniFile.Set("Settings", "UseXFB", bUseXFB); iniFile.Set("Settings", "UseXFB", bUseXFB);
iniFile.Set("Settings", "Wireframe", bWireFrame); iniFile.Set("Settings", "Wireframe", bWireFrame);
iniFile.Set("Settings", "DisableLighting", bDisableLighting); iniFile.Set("Settings", "DisableLighting", bDisableLighting);
iniFile.Set("Settings", "DisableTexturing", bDisableTexturing); iniFile.Set("Settings", "DisableTexturing", bDisableTexturing);
iniFile.Set("Enhancements", "ForceFiltering", bForceFiltering); iniFile.Set("Enhancements", "ForceFiltering", bForceFiltering);
iniFile.Set("Enhancements", "MaxAnisotropy", iMaxAnisotropy); iniFile.Set("Enhancements", "MaxAnisotropy", iMaxAnisotropy);
iniFile.Set("Hacks", "EFBToTextureDisable", bEFBToTextureDisable); iniFile.Set("Hacks", "EFBToTextureDisable", bEFBToTextureDisable);
iniFile.Set("Hacks", "EFBToTextureDisableHotKey", bEFBToTextureDisableHotKey); iniFile.Set("Hacks", "EFBToTextureDisableHotKey", bEFBToTextureDisableHotKey);
iniFile.Set("Hacks", "ProjectionHax1", bProjectionHax1); iniFile.Set("Hacks", "ProjectionHax1", bProjectionHax1);
iniFile.Set("Hacks", "ProjectionHax2", bProjectionHax2); iniFile.Set("Hacks", "ProjectionHax2", bProjectionHax2);
iniFile.Save(FULL_CONFIG_DIR "gfx_opengl.ini"); iniFile.Save(FULL_CONFIG_DIR "gfx_opengl.ini");
} }

View File

@ -1,482 +1,482 @@
// 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 "IniFile.h" // Common files #include "IniFile.h" // Common files
#include "../Config.h" // Config settings #include "../Config.h" // Config settings
#include "PBView.h" // Debugger files #include "PBView.h" // Debugger files
#include "Debugger.h" #include "Debugger.h"
#include "../Logging/Console.h" // open and close console #include "../Logging/Console.h" // open and close console
// externals // externals
extern int gSaveFile; // make this an int to allow multiple save file options extern int gSaveFile; // make this an int to allow multiple save file options
extern int gPreset; extern int gPreset;
int A, B; int A, B;
// ======================================================================================= // =======================================================================================
// Declare events // Declare events
BEGIN_EVENT_TABLE(CDebugger,wxDialog) BEGIN_EVENT_TABLE(CDebugger,wxDialog)
EVT_SHOW(CDebugger::OnShow) EVT_SHOW(CDebugger::OnShow)
EVT_CLOSE(CDebugger::OnClose) EVT_CLOSE(CDebugger::OnClose)
EVT_BUTTON(ID_UPD,CDebugger::OnUpdate) EVT_BUTTON(ID_UPD,CDebugger::OnUpdate)
EVT_CHECKBOX(ID_SAVETOFILE,CDebugger::GeneralSettings) // General settings EVT_CHECKBOX(ID_SAVETOFILE,CDebugger::GeneralSettings) // General settings
EVT_CHECKBOX(ID_SHOWCONSOLE,CDebugger::GeneralSettings) EVT_CHECKBOX(ID_SHOWCONSOLE,CDebugger::GeneralSettings)
EVT_CHECKLISTBOX(ID_CHECKLIST1, CDebugger::LogSettings) // Check list box EVT_CHECKLISTBOX(ID_CHECKLIST1, CDebugger::LogSettings) // Check list box
EVT_RADIOBOX(IDC_RADIO1, CDebugger::ChangeFrequency) // Update freq. EVT_RADIOBOX(IDC_RADIO1, CDebugger::ChangeFrequency) // Update freq.
EVT_BUTTON(ID_AP,CDebugger::Ap) EVT_BUTTON(ID_AP,CDebugger::Ap)
EVT_BUTTON(ID_AM,CDebugger::Am) EVT_BUTTON(ID_AM,CDebugger::Am)
EVT_BUTTON(ID_BP,CDebugger::Bp) EVT_BUTTON(ID_BP,CDebugger::Bp)
EVT_BUTTON(ID_BM,CDebugger::Bm) EVT_BUTTON(ID_BM,CDebugger::Bm)
END_EVENT_TABLE() END_EVENT_TABLE()
// ======================================================================================= // =======================================================================================
CDebugger::CDebugger(wxWindow *parent, wxWindowID id, const wxString &title, CDebugger::CDebugger(wxWindow *parent, wxWindowID id, const wxString &title,
const wxPoint &position, const wxSize& size, long style) const wxPoint &position, const wxSize& size, long style)
: wxDialog(parent, id, title, position, size, style) : wxDialog(parent, id, title, position, size, style)
, m_GPRListView(NULL) , m_GPRListView(NULL)
{ {
CreateGUIControls(); CreateGUIControls();
// load ini... // load ini...
IniFile file; IniFile file;
file.Load(DEBUGGER_CONFIG_FILE); file.Load(DEBUGGER_CONFIG_FILE);
this->Load(file); this->Load(file);
} }
CDebugger::~CDebugger() CDebugger::~CDebugger()
{ {
// empty // empty
IniFile file; IniFile file;
file.Load(DEBUGGER_CONFIG_FILE); file.Load(DEBUGGER_CONFIG_FILE);
this->Save(file); this->Save(file);
file.Save(DEBUGGER_CONFIG_FILE); file.Save(DEBUGGER_CONFIG_FILE);
} }
void CDebugger::Save(IniFile& _IniFile) const void CDebugger::Save(IniFile& _IniFile) const
{ {
// TODO1: make this work when we close the entire program to, currently on total close we get // TODO1: make this work when we close the entire program to, currently on total close we get
// weird values, perhaps because of some conflict with the rendering window // weird values, perhaps because of some conflict with the rendering window
// TODO2: get the screen resolution and make limits from that // TODO2: get the screen resolution and make limits from that
if(GetPosition().x < 1000 && GetPosition().y < 1000 if(GetPosition().x < 1000 && GetPosition().y < 1000
&& GetSize().GetWidth() < 1000 && GetSize().GetHeight() < 1000 && GetSize().GetWidth() < 1000 && GetSize().GetHeight() < 1000
) )
{ {
_IniFile.Set("VideoWindow", "x", GetPosition().x); _IniFile.Set("VideoWindow", "x", GetPosition().x);
_IniFile.Set("VideoWindow", "y", GetPosition().y); _IniFile.Set("VideoWindow", "y", GetPosition().y);
_IniFile.Set("VideoWindow", "w", GetSize().GetWidth()); _IniFile.Set("VideoWindow", "w", GetSize().GetWidth());
_IniFile.Set("VideoWindow", "h", GetSize().GetHeight()); _IniFile.Set("VideoWindow", "h", GetSize().GetHeight());
} }
_IniFile.Set("VideoWindow", "Console", m_Check[2]->IsChecked()); // save settings _IniFile.Set("VideoWindow", "Console", m_Check[2]->IsChecked()); // save settings
_IniFile.Set("VideoWindow", "UpdateFrequency", m_RadioBox[1]->GetSelection()); _IniFile.Set("VideoWindow", "UpdateFrequency", m_RadioBox[1]->GetSelection());
_IniFile.Set("VideoWindow", "LogLevel", g_Config.iLog); _IniFile.Set("VideoWindow", "LogLevel", g_Config.iLog);
} }
void CDebugger::Load(IniFile& _IniFile) void CDebugger::Load(IniFile& _IniFile)
{ {
int x,y,w,h; int x,y,w,h;
_IniFile.Get("VideoWindow", "x", &x, GetPosition().x); _IniFile.Get("VideoWindow", "x", &x, GetPosition().x);
_IniFile.Get("VideoWindow", "y", &y, GetPosition().y); _IniFile.Get("VideoWindow", "y", &y, GetPosition().y);
_IniFile.Get("VideoWindow", "w", &w, GetSize().GetWidth()); _IniFile.Get("VideoWindow", "w", &w, GetSize().GetWidth());
_IniFile.Get("VideoWindow", "h", &h, GetSize().GetHeight()); _IniFile.Get("VideoWindow", "h", &h, GetSize().GetHeight());
SetSize(x, y, w, h); SetSize(x, y, w, h);
// saved settings // saved settings
bool Console; bool Console;
_IniFile.Get("VideoWindow", "Console", &Console, m_Check[2]->IsChecked()); _IniFile.Get("VideoWindow", "Console", &Console, m_Check[2]->IsChecked());
m_Check[2]->SetValue(Console); m_Check[2]->SetValue(Console);
DoShowHideConsole(); DoShowHideConsole();
_IniFile.Get("VideoWindow", "UpdateFrequency", &gUpdFreq, m_RadioBox[1]->GetSelection()); _IniFile.Get("VideoWindow", "UpdateFrequency", &gUpdFreq, m_RadioBox[1]->GetSelection());
m_RadioBox[1]->SetSelection(gUpdFreq); m_RadioBox[1]->SetSelection(gUpdFreq);
DoChangeFrequency(); DoChangeFrequency();
_IniFile.Get("VideoWindow", "LogLevel", &g_Config.iLog, 0); _IniFile.Get("VideoWindow", "LogLevel", &g_Config.iLog, 0);
m_settings->Check(g_Config.iLog - 1, true); m_settings->Check(g_Config.iLog - 1, true);
} }
void CDebugger::CreateGUIControls() void CDebugger::CreateGUIControls()
{ {
// Basic settings // Basic settings
SetTitle(wxT("OpenGL Debugging")); SetTitle(wxT("OpenGL Debugging"));
SetIcon(wxNullIcon); SetIcon(wxNullIcon);
SetSize(8, 8, 200, 100); // these will become the minimin sizes allowed by resizing SetSize(8, 8, 200, 100); // these will become the minimin sizes allowed by resizing
Center(); Center();
// Declarations // Declarations
wxBoxSizer *sMain, *sGeneral; wxBoxSizer *sMain, *sGeneral;
wxButton* m_Upd; wxButton* m_Upd;
wxButton* m_Ap; wxButton* m_Am; wxButton* m_Ap; wxButton* m_Am;
wxButton* m_Bp; wxButton* m_Bm; wxButton* m_Bp; wxButton* m_Bm;
wxStaticBoxSizer* sLeft; wxStaticBoxSizer* sLeft;
// Notebook ----------------------------------------------------- // Notebook -----------------------------------------------------
m_Notebook = new wxNotebook(this, ID_NOTEBOOK, wxDefaultPosition, wxDefaultSize); m_Notebook = new wxNotebook(this, ID_NOTEBOOK, wxDefaultPosition, wxDefaultSize);
m_PageMain = new wxPanel(m_Notebook, ID_PAGEMAIN, wxDefaultPosition, wxDefaultSize); m_PageMain = new wxPanel(m_Notebook, ID_PAGEMAIN, wxDefaultPosition, wxDefaultSize);
m_Notebook->AddPage(m_PageMain, wxT("Main")); m_Notebook->AddPage(m_PageMain, wxT("Main"));
// =================================================================== // ===================================================================
// Main Page // Main Page
// Buttons ----------------------------------------------------- // Buttons -----------------------------------------------------
wxStaticBoxSizer * m_updSizer = new wxStaticBoxSizer (wxVERTICAL, m_PageMain, wxT("Update")); wxStaticBoxSizer * m_updSizer = new wxStaticBoxSizer (wxVERTICAL, m_PageMain, wxT("Update"));
m_Upd = new wxButton(m_PageMain, ID_UPD, wxT("Update"), m_Upd = new wxButton(m_PageMain, ID_UPD, wxT("Update"),
wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
m_updSizer->Add(m_Upd, 0, 0, 5); m_updSizer->Add(m_Upd, 0, 0, 5);
// ------------------------ // ------------------------
// Variables ----------------------------------------------------- // Variables -----------------------------------------------------
wxStaticBoxSizer * m_buttonSizer = new wxStaticBoxSizer (wxVERTICAL, m_PageMain, wxT("Variables")); wxStaticBoxSizer * m_buttonSizer = new wxStaticBoxSizer (wxVERTICAL, m_PageMain, wxT("Variables"));
m_Ap = new wxButton(m_PageMain, ID_AP, wxT("A +"), m_Ap = new wxButton(m_PageMain, ID_AP, wxT("A +"),
wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
//m_SelC->Enable(false); //m_SelC->Enable(false);
m_Am = new wxButton(m_PageMain, ID_AM, wxT("A -"), m_Am = new wxButton(m_PageMain, ID_AM, wxT("A -"),
wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
//m_Presets->Enable(false); //m_Presets->Enable(false);
m_Bp = new wxButton(m_PageMain, ID_BP, wxT("B +"), m_Bp = new wxButton(m_PageMain, ID_BP, wxT("B +"),
wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
m_Bm = new wxButton(m_PageMain, ID_BM, wxT("B -"), m_Bm = new wxButton(m_PageMain, ID_BM, wxT("B -"),
wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
m_buttonSizer->Add(m_Ap, 0, 0, 5); m_buttonSizer->Add(m_Ap, 0, 0, 5);
m_buttonSizer->Add(m_Am, 0, 0, 5); m_buttonSizer->Add(m_Am, 0, 0, 5);
m_buttonSizer->Add(m_Bp, 0, 0, 5); m_buttonSizer->Add(m_Bp, 0, 0, 5);
m_buttonSizer->Add(m_Bm, 0, 0, 5); m_buttonSizer->Add(m_Bm, 0, 0, 5);
// ------------------------ // ------------------------
// -------------------------------------------------------------------- // --------------------------------------------------------------------
// m_PageMain: Options // m_PageMain: Options
// ------------------------- // -------------------------
wxStaticBoxSizer * m_optionsSizer = new wxStaticBoxSizer(wxVERTICAL, m_PageMain, wxT("Options")); wxStaticBoxSizer * m_optionsSizer = new wxStaticBoxSizer(wxVERTICAL, m_PageMain, wxT("Options"));
//m_Label[0] = new wxStaticBox(m_PageMain, IDG_LABEL1, wxT("Options"), //m_Label[0] = new wxStaticBox(m_PageMain, IDG_LABEL1, wxT("Options"),
// wxDefaultPosition, wxDefaultSize, 0); // wxDefaultPosition, wxDefaultSize, 0);
//wxStaticBoxSizer * m_checkSizer3 = new wxStaticBoxSizer (m_Label[0], wxVERTICAL); //wxStaticBoxSizer * m_checkSizer3 = new wxStaticBoxSizer (m_Label[0], wxVERTICAL);
// checkboxes // checkboxes
m_Check[0] = new wxCheckBox(m_PageMain, ID_SAVETOFILE, wxT("Save to file"), m_Check[0] = new wxCheckBox(m_PageMain, ID_SAVETOFILE, wxT("Save to file"),
wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
m_Check[2] = new wxCheckBox(m_PageMain, ID_SHOWCONSOLE, wxT("Show console"), m_Check[2] = new wxCheckBox(m_PageMain, ID_SHOWCONSOLE, wxT("Show console"),
wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator); wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
m_optionsSizer->Add(m_Check[0], 0, 0, 5); m_optionsSizer->Add(m_Check[0], 0, 0, 5);
m_optionsSizer->Add(m_Check[2], 0, 0, 5); m_optionsSizer->Add(m_Check[2], 0, 0, 5);
// ------------------------ // ------------------------
// -------------------------------------------------------------------- // --------------------------------------------------------------------
// m_PageMain: Log settings checkboxes // m_PageMain: Log settings checkboxes
// ------------------------- // -------------------------
wxStaticBoxSizer * m_logSizer = new wxStaticBoxSizer(wxVERTICAL, m_PageMain, wxT("Log setting")); wxStaticBoxSizer * m_logSizer = new wxStaticBoxSizer(wxVERTICAL, m_PageMain, wxT("Log setting"));
m_settings = new wxCheckListBox(m_PageMain, ID_CHECKLIST1, wxDefaultPosition, wxDefaultSize, m_settings = new wxCheckListBox(m_PageMain, ID_CHECKLIST1, wxDefaultPosition, wxDefaultSize,
0, NULL, wxNO_BORDER); 0, NULL, wxNO_BORDER);
m_settings->Append(wxT("Info log")); m_settings->Append(wxT("Info log"));
m_settings->Append(wxT("Primary log")); m_settings->Append(wxT("Primary log"));
m_settings->Check(0, bInfoLog); m_settings->Check(0, bInfoLog);
m_settings->Check(1, bPrimLog); m_settings->Check(1, bPrimLog);
// because the wxCheckListBox is a little underdeveloped we have to help it with this // because the wxCheckListBox is a little underdeveloped we have to help it with this
// to bad there's no windows xp styles for the checkboxes // to bad there's no windows xp styles for the checkboxes
m_settings->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE)); m_settings->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE));
m_settings->SetMinSize(wxSize(m_settings->GetSize().GetWidth() - 40, m_settings->SetMinSize(wxSize(m_settings->GetSize().GetWidth() - 40,
m_settings->GetCount() * 15)); m_settings->GetCount() * 15));
m_logSizer->Add(m_settings, 0, 0, 0); m_logSizer->Add(m_settings, 0, 0, 0);
// ------------------------ // ------------------------
// -------------------------------------------------------------------- // --------------------------------------------------------------------
// m_PageMain: Radio boxes // m_PageMain: Radio boxes
// ------------------------- // -------------------------
int m_radioBoxNChoices[3]; int m_radioBoxNChoices[3];
wxString m_radioBoxChoices0[] = { wxT("Show base 10"), wxT("Show base 16") }; wxString m_radioBoxChoices0[] = { wxT("Show base 10"), wxT("Show base 16") };
m_radioBoxNChoices[0] = sizeof( m_radioBoxChoices0 ) / sizeof( wxString ); m_radioBoxNChoices[0] = sizeof( m_radioBoxChoices0 ) / sizeof( wxString );
m_RadioBox[0] = new wxRadioBox( m_PageMain, IDC_RADIO0, wxT("Show base"), m_RadioBox[0] = new wxRadioBox( m_PageMain, IDC_RADIO0, wxT("Show base"),
wxDefaultPosition, wxDefaultSize, m_radioBoxNChoices[0], m_radioBoxChoices0, 1, wxRA_SPECIFY_COLS); wxDefaultPosition, wxDefaultSize, m_radioBoxNChoices[0], m_radioBoxChoices0, 1, wxRA_SPECIFY_COLS);
m_RadioBox[0]->Enable(false); m_RadioBox[0]->Enable(false);
wxString m_radioBoxChoices1[] = { wxT("Never"), wxT("5 times/s"), wxT("15 times/s"), wxT("30 times/s") }; wxString m_radioBoxChoices1[] = { wxT("Never"), wxT("5 times/s"), wxT("15 times/s"), wxT("30 times/s") };
m_radioBoxNChoices[1] = sizeof( m_radioBoxChoices1 ) / sizeof( wxString ); m_radioBoxNChoices[1] = sizeof( m_radioBoxChoices1 ) / sizeof( wxString );
m_RadioBox[1] = new wxRadioBox( m_PageMain, IDC_RADIO1, wxT("Update freq."), m_RadioBox[1] = new wxRadioBox( m_PageMain, IDC_RADIO1, wxT("Update freq."),
wxDefaultPosition, wxDefaultSize, m_radioBoxNChoices[1], m_radioBoxChoices1, 1, wxRA_SPECIFY_COLS); wxDefaultPosition, wxDefaultSize, m_radioBoxNChoices[1], m_radioBoxChoices1, 1, wxRA_SPECIFY_COLS);
wxString m_radioBoxChoices2[] = { wxT("Win stretch") }; wxString m_radioBoxChoices2[] = { wxT("Win stretch") };
m_radioBoxNChoices[2] = sizeof( m_radioBoxChoices2 ) / sizeof( wxString ); m_radioBoxNChoices[2] = sizeof( m_radioBoxChoices2 ) / sizeof( wxString );
m_RadioBox[2] = new wxRadioBox( m_PageMain, IDC_RADIO2, wxT("Presets"), m_RadioBox[2] = new wxRadioBox( m_PageMain, IDC_RADIO2, wxT("Presets"),
wxDefaultPosition, wxDefaultSize, m_radioBoxNChoices[2], m_radioBoxChoices2, 1, wxRA_SPECIFY_COLS); wxDefaultPosition, wxDefaultSize, m_radioBoxNChoices[2], m_radioBoxChoices2, 1, wxRA_SPECIFY_COLS);
// ------------------------ // ------------------------
// -------------------------------------------------------------------- // --------------------------------------------------------------------
// Main: Left buttons and checkboxes // Main: Left buttons and checkboxes
// ------------------------ // ------------------------
wxBoxSizer* sButtons = new wxBoxSizer(wxVERTICAL); wxBoxSizer* sButtons = new wxBoxSizer(wxVERTICAL);
//sButtons->AddStretchSpacer(1); //sButtons->AddStretchSpacer(1);
sButtons->Add(m_updSizer, 0, 0, 5); // update button sButtons->Add(m_updSizer, 0, 0, 5); // update button
sButtons->Add(m_buttonSizer, 0, 0, 5); // variables buttons sButtons->Add(m_buttonSizer, 0, 0, 5); // variables buttons
sButtons->Add(m_logSizer, 0, 0, 5); // log settings sButtons->Add(m_logSizer, 0, 0, 5); // log settings
sButtons->Add(m_optionsSizer, 0, 2, 5); // Log options, show console etc. sButtons->Add(m_optionsSizer, 0, 2, 5); // Log options, show console etc.
// -------------------------------------------------------------------- // --------------------------------------------------------------------
// Main: Right buttons and checkboxes // Main: Right buttons and checkboxes
// ------------------------ // ------------------------
wxBoxSizer* sButtons2 = new wxBoxSizer(wxVERTICAL); wxBoxSizer* sButtons2 = new wxBoxSizer(wxVERTICAL);
sButtons2->Add(m_RadioBox[0], 0, 0, 5); // Show base sButtons2->Add(m_RadioBox[0], 0, 0, 5); // Show base
sButtons2->Add(m_RadioBox[1], 0, 0, 5); // Update frequency sButtons2->Add(m_RadioBox[1], 0, 0, 5); // Update frequency
sButtons2->Add(m_RadioBox[2], 0, 0, 5); // Preset views sButtons2->Add(m_RadioBox[2], 0, 0, 5); // Preset views
//sButtons2->AddStretchSpacer(1); //sButtons2->AddStretchSpacer(1);
//sButtons2->Add(m_checkSizer2, 0, 2, 5); //sButtons2->Add(m_checkSizer2, 0, 2, 5);
// -------------------------------------------------------------------- // --------------------------------------------------------------------
// Main: Parameter tables view, the big window // Main: Parameter tables view, the big window
sLeft = new wxStaticBoxSizer(wxVERTICAL, m_PageMain, wxT("Current Status")); sLeft = new wxStaticBoxSizer(wxVERTICAL, m_PageMain, wxT("Current Status"));
m_GPRListView = new CPBView(m_PageMain, ID_GPR, wxDefaultPosition, GetSize(), m_GPRListView = new CPBView(m_PageMain, ID_GPR, wxDefaultPosition, GetSize(),
wxLC_REPORT | wxSUNKEN_BORDER | wxLC_ALIGN_LEFT | wxLC_SINGLE_SEL | wxLC_SORT_ASCENDING); wxLC_REPORT | wxSUNKEN_BORDER | wxLC_ALIGN_LEFT | wxLC_SINGLE_SEL | wxLC_SORT_ASCENDING);
sLeft->Add(m_GPRListView, 1, wxEXPAND|wxALL, 5); sLeft->Add(m_GPRListView, 1, wxEXPAND|wxALL, 5);
// -------------------------------------------------------------------- // --------------------------------------------------------------------
// General container // General container
// ----------------------------- // -----------------------------
sGeneral = new wxBoxSizer(wxHORIZONTAL); sGeneral = new wxBoxSizer(wxHORIZONTAL);
sGeneral->Add(sLeft, 1, wxEXPAND | wxALL, 5); sGeneral->Add(sLeft, 1, wxEXPAND | wxALL, 5);
sGeneral->Add(sButtons, 0, wxEXPAND | (wxUP | wxDOWN), 5); sGeneral->Add(sButtons, 0, wxEXPAND | (wxUP | wxDOWN), 5);
sGeneral->Add(sButtons2, 0, wxEXPAND | (wxUP | wxDOWN | wxRIGHT | wxLEFT), 5); sGeneral->Add(sButtons2, 0, wxEXPAND | (wxUP | wxDOWN | wxRIGHT | wxLEFT), 5);
// -------------------------------------------------------------------- // --------------------------------------------------------------------
// Main container // Main container
// ----------------------------- // -----------------------------
sMain = new wxBoxSizer(wxVERTICAL); sMain = new wxBoxSizer(wxVERTICAL);
sMain->Add(m_Notebook, 1, wxEXPAND | wxALL, 5); sMain->Add(m_Notebook, 1, wxEXPAND | wxALL, 5);
m_PageMain->SetSizer(sGeneral); m_PageMain->SetSizer(sGeneral);
this->SetSizer(sMain); this->SetSizer(sMain);
//sGeneral->SetSizeHints(this); //sGeneral->SetSizeHints(this);
//NotifyUpdate(); //NotifyUpdate();
//Freeze(); // unfreeze this if you want to use it //Freeze(); // unfreeze this if you want to use it
} }
// ========================================================================== // ==========================================================================
// System functions // System functions
// -------------- // --------------
void CDebugger::OnShow(wxShowEvent& /*event*/) void CDebugger::OnShow(wxShowEvent& /*event*/)
{ {
// bring the console back to // bring the console back to
if(m_Check[2]->IsChecked()) if(m_Check[2]->IsChecked())
{ {
OpenConsole(); OpenConsole();
#ifdef _WIN32 #ifdef _WIN32
MoveWindow(GetConsoleHwnd(), 0,400, 1280,500, true); // Move window TODO: make this MoveWindow(GetConsoleHwnd(), 0,400, 1280,500, true); // Move window TODO: make this
// adjustable from the debugging window // adjustable from the debugging window
#endif #endif
} }
} }
void CDebugger::OnClose(wxCloseEvent& /*event*/) void CDebugger::OnClose(wxCloseEvent& /*event*/)
{ {
// save the window position when we hide the window to // save the window position when we hide the window to
IniFile file; IniFile file;
file.Load(DEBUGGER_CONFIG_FILE); file.Load(DEBUGGER_CONFIG_FILE);
this->Save(file); this->Save(file);
file.Save(DEBUGGER_CONFIG_FILE); file.Save(DEBUGGER_CONFIG_FILE);
EndModal(0); // it seems like this works for Show() to, not just ShowModal(); EndModal(0); // it seems like this works for Show() to, not just ShowModal();
CloseConsole(); // The console goes with the wx window CloseConsole(); // The console goes with the wx window
} }
void CDebugger::DoHide() void CDebugger::DoHide()
{ {
Hide(); Hide();
CloseConsole(); // The console goes with the wx window CloseConsole(); // The console goes with the wx window
} }
void CDebugger::DoShow() void CDebugger::DoShow()
{ {
Show(); Show();
DoShowHideConsole(); // The console goes with the wx window DoShowHideConsole(); // The console goes with the wx window
} }
void CDebugger::OnUpdate(wxCommandEvent& /*event*/) void CDebugger::OnUpdate(wxCommandEvent& /*event*/)
{ {
this->NotifyUpdate(); this->NotifyUpdate();
} }
// =============== // ===============
// ======================================================================================= // =======================================================================================
// Change preset // Change preset
// -------------- // --------------
void CDebugger::ChangePreset(wxCommandEvent& event) void CDebugger::ChangePreset(wxCommandEvent& event)
{ {
DoChangePreset(); DoChangePreset();
} }
void CDebugger::DoChangePreset() void CDebugger::DoChangePreset()
{ {
if(m_RadioBox[2]->GetSelection() == 0) if(m_RadioBox[2]->GetSelection() == 0)
gPreset = 0; gPreset = 0;
else if(m_RadioBox[2]->GetSelection() == 1) else if(m_RadioBox[2]->GetSelection() == 1)
gPreset = 1; gPreset = 1;
else if(m_RadioBox[2]->GetSelection() == 2) else if(m_RadioBox[2]->GetSelection() == 2)
gPreset = 2; gPreset = 2;
else if(m_RadioBox[2]->GetSelection() == 3) else if(m_RadioBox[2]->GetSelection() == 3)
gPreset = 3; gPreset = 3;
} }
// ============== // ==============
// ======================================================================================= // =======================================================================================
// Control variables // Control variables
// -------------- // --------------
void CDebugger::Ap(wxCommandEvent& event) void CDebugger::Ap(wxCommandEvent& event)
{ {
A += 50; A += 50;
//MessageBox(0, "", "", 0); //MessageBox(0, "", "", 0);
__Log("%i", A); __Log("%i", A);
} }
void CDebugger::Am(wxCommandEvent& event) void CDebugger::Am(wxCommandEvent& event)
{ {
A -= 50; A -= 50;
} }
void CDebugger::Bp(wxCommandEvent& event) void CDebugger::Bp(wxCommandEvent& event)
{ {
B += 50; B += 50;
} }
void CDebugger::Bm(wxCommandEvent& event) void CDebugger::Bm(wxCommandEvent& event)
{ {
B -= 50; B -= 50;
} }
// ============== // ==============
// ======================================================================================= // =======================================================================================
// Change update frequency // Change update frequency
// -------------- // --------------
void CDebugger::ChangeFrequency(wxCommandEvent& event) void CDebugger::ChangeFrequency(wxCommandEvent& event)
{ {
DoChangeFrequency(); DoChangeFrequency();
} }
void CDebugger::DoChangeFrequency() void CDebugger::DoChangeFrequency()
{ {
if(m_RadioBox[1]->GetSelection() == 0) if(m_RadioBox[1]->GetSelection() == 0)
gUpdFreq = 0; gUpdFreq = 0;
else if(m_RadioBox[1]->GetSelection() == 1) else if(m_RadioBox[1]->GetSelection() == 1)
gUpdFreq = 5; gUpdFreq = 5;
else if(m_RadioBox[1]->GetSelection() == 2) else if(m_RadioBox[1]->GetSelection() == 2)
gUpdFreq = 15; gUpdFreq = 15;
else else
gUpdFreq = 30; gUpdFreq = 30;
} }
// ============== // ==============
// ======================================================================================= // =======================================================================================
// General settings // General settings
// -------------- // --------------
void CDebugger::GeneralSettings(wxCommandEvent& event) void CDebugger::GeneralSettings(wxCommandEvent& event)
{ {
switch (event.GetId()) switch (event.GetId())
{ {
case ID_SAVETOFILE: // Save to file case ID_SAVETOFILE: // Save to file
gSaveFile = m_Check[0]->IsChecked(); gSaveFile = m_Check[0]->IsChecked();
break; break;
case ID_SHOWCONSOLE: case ID_SHOWCONSOLE:
DoShowHideConsole(); DoShowHideConsole();
break; break;
} }
} }
// ============== // ==============
// ======================================================================================= // =======================================================================================
// Show or hide console window // Show or hide console window
// -------------- // --------------
void CDebugger::DoShowHideConsole() void CDebugger::DoShowHideConsole()
{ {
if(m_Check[2]->IsChecked()) if(m_Check[2]->IsChecked())
{ {
OpenConsole(); OpenConsole();
#ifdef _WIN32 #ifdef _WIN32
MoveWindow(GetConsoleHwnd(), 0,400, 1280,500, true); // move window, TODO: make this MoveWindow(GetConsoleHwnd(), 0,400, 1280,500, true); // move window, TODO: make this
// adjustable from the debugging window // adjustable from the debugging window
#endif #endif
} }
else else
{ {
CloseConsole(); CloseConsole();
} }
} }
// ============== // ==============
// ======================================================================================= // =======================================================================================
// Enable or disable logs // Enable or disable logs
// -------------- // --------------
void CDebugger::LogSettings(wxCommandEvent& event) void CDebugger::LogSettings(wxCommandEvent& event)
{ {
// Only allow one selected log at a time // Only allow one selected log at a time
for (u32 i = 0; i < m_settings->GetCount(); ++i) for (u32 i = 0; i < m_settings->GetCount(); ++i)
if(i != (u32)event.GetInt()) m_settings->Check(i, false); if(i != (u32)event.GetInt()) m_settings->Check(i, false);
if(m_settings->IsChecked(0)) g_Config.iLog = CONF_LOG; if(m_settings->IsChecked(0)) g_Config.iLog = CONF_LOG;
else if(m_settings->IsChecked(1)) g_Config.iLog = CONF_PRIMLOG; else if(m_settings->IsChecked(1)) g_Config.iLog = CONF_PRIMLOG;
else g_Config.iLog = 0; else g_Config.iLog = 0;
} }
// ============== // ==============
// ======================================================================================= // =======================================================================================
// Update the wxListCtrl // Update the wxListCtrl
// -------------- // --------------
void CDebugger::NotifyUpdate() void CDebugger::NotifyUpdate()
{ {
if (m_GPRListView != NULL) if (m_GPRListView != NULL)
{ {
m_GPRListView->Update(); m_GPRListView->Update();
} }
} }
// ============== // ==============

View File

@ -1,124 +1,124 @@
// 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 "PBView.h" #include "PBView.h"
#include <iostream> #include <iostream>
#include <string> #include <string>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
extern const char* GetGRPName(unsigned int index); extern const char* GetGRPName(unsigned int index);
BEGIN_EVENT_TABLE(CPBView, wxListCtrl) BEGIN_EVENT_TABLE(CPBView, wxListCtrl)
END_EVENT_TABLE() END_EVENT_TABLE()
CPBView::CPBView(wxWindow* parent, const wxWindowID id, const wxPoint& pos, const wxSize& size, long style) CPBView::CPBView(wxWindow* parent, const wxWindowID id, const wxPoint& pos, const wxSize& size, long style)
: wxListCtrl(parent, id, pos, size, style) : wxListCtrl(parent, id, pos, size, style)
{ {
InsertColumn(0, wxT("Block"), wxLIST_FORMAT_CENTER, 40); InsertColumn(0, wxT("Block"), wxLIST_FORMAT_CENTER, 40);
SetFont(wxFont(8, wxSWISS, wxNORMAL, wxNORMAL, false, wxT("Segoe UI"))); SetFont(wxFont(8, wxSWISS, wxNORMAL, wxNORMAL, false, wxT("Segoe UI")));
for (int i = 0; i < 1; i++) for (int i = 0; i < 1; i++)
{ {
// Print values from 0 to 63 // Print values from 0 to 63
char buffer [33]; char buffer [33];
sprintf(buffer, "%02i", i); sprintf(buffer, "%02i", i);
int Item = InsertItem(0, wxString::FromAscii(buffer)); int Item = InsertItem(0, wxString::FromAscii(buffer));
wxListItem item; wxListItem item;
item.SetId(Item); item.SetId(Item);
item.SetBackgroundColour(0xFFFFFF); item.SetBackgroundColour(0xFFFFFF);
item.SetData(i); item.SetData(i);
SetItem(item); SetItem(item);
} }
// This is a wx call that leads to MSWDrawSubItem // This is a wx call that leads to MSWDrawSubItem
Refresh(); Refresh();
} }
void CPBView::Update() void CPBView::Update()
{ {
Refresh(); Refresh();
} }
#ifdef _WIN32 #ifdef _WIN32
bool CPBView::MSWDrawSubItem(wxPaintDC& rPainDC, int item, int subitem) bool CPBView::MSWDrawSubItem(wxPaintDC& rPainDC, int item, int subitem)
{ {
bool Result = false; bool Result = false;
// don't change 0, it has the block values // don't change 0, it has the block values
if(subitem > 0) if(subitem > 0)
{ {
#ifdef __WXMSW__ // what's this? should I use that? #ifdef __WXMSW__ // what's this? should I use that?
const wxChar* bgColor = _T("#ffffff"); const wxChar* bgColor = _T("#ffffff");
wxBrush bgBrush(bgColor); wxBrush bgBrush(bgColor);
wxPen bgPen(bgColor); wxPen bgPen(bgColor);
wxRect SubItemRect; wxRect SubItemRect;
this->GetSubItemRect(item, subitem, SubItemRect); this->GetSubItemRect(item, subitem, SubItemRect);
rPainDC.SetBrush(bgBrush); rPainDC.SetBrush(bgBrush);
rPainDC.SetPen(bgPen); rPainDC.SetPen(bgPen);
rPainDC.DrawRectangle(SubItemRect); rPainDC.DrawRectangle(SubItemRect);
#endif #endif
// A somewhat primitive attempt to show the playing history for a certain block. // A somewhat primitive attempt to show the playing history for a certain block.
wxString text; wxString text;
if(subitem == 1) if(subitem == 1)
{ {
char cbuff [33]; char cbuff [33];
sprintf(cbuff, "%08i", m_CachedRegs[subitem][item]); sprintf(cbuff, "%08i", m_CachedRegs[subitem][item]);
std::string c = cbuff; std::string c = cbuff;
int n[8]; int n[8];
for (int j = 0; j < 8; j++) for (int j = 0; j < 8; j++)
{ {
n[j] = atoi( c.substr(j, 1).c_str()); n[j] = atoi( c.substr(j, 1).c_str());
// 149 = dot, 160 = space // 149 = dot, 160 = space
if (n[j] == 1){ if (n[j] == 1){
n[j] = 149;} else {n[j] = 160;} n[j] = 149;} else {n[j] = 160;}
} }
// pretty neat huh? // pretty neat huh?
text.Printf(wxT("%c%c%c%c%c%c%c%c"), n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]); text.Printf(wxT("%c%c%c%c%c%c%c%c"), n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7]);
} }
else else
{ {
text.Printf(wxT("0x%08x"), m_CachedRegs[subitem][item]); text.Printf(wxT("0x%08x"), m_CachedRegs[subitem][item]);
} }
#ifdef __WXMSW__ #ifdef __WXMSW__
rPainDC.DrawText(text, SubItemRect.GetLeft() + 10, SubItemRect.GetTop() + 4); rPainDC.DrawText(text, SubItemRect.GetLeft() + 10, SubItemRect.GetTop() + 4);
#else #else
// May not show up pretty in !Win32 // May not show up pretty in !Win32
rPainDC.DrawText(text, 10, 4); rPainDC.DrawText(text, 10, 4);
#endif #endif
return true; return true;
} }
else else
{ {
// what does this mean? // what does this mean?
return Result; return Result;
} }
} }
#endif #endif

Some files were not shown because too many files have changed in this diff Show More