Merge https://github.com/Cxbx-Reloaded/Cxbx-Reloaded into cxbx-debugger
This commit is contained in:
commit
547d6b04b9
|
@ -163,6 +163,7 @@ BEGIN
|
|||
MENUITEM SEPARATOR
|
||||
MENUITEM "&About", ID_HELP_ABOUT
|
||||
END
|
||||
MENUITEM "LED", ID_LED
|
||||
END
|
||||
|
||||
|
||||
|
|
|
@ -585,7 +585,7 @@ void Xbe::DumpInformation(FILE *x_file)
|
|||
|
||||
// print init flags
|
||||
{
|
||||
fprintf(x_file, "Init Flags : 0x%.08X ", m_Header.dwInitFlags.bMountUtilityDrive);
|
||||
fprintf(x_file, "Init Flags : 0x%.08X ", m_Header.dwInitFlags_value);
|
||||
|
||||
if(m_Header.dwInitFlags.bMountUtilityDrive)
|
||||
fprintf(x_file, "[Mount Utility Drive] ");
|
||||
|
@ -703,7 +703,7 @@ void Xbe::DumpInformation(FILE *x_file)
|
|||
|
||||
// print flags
|
||||
{
|
||||
fprintf(x_file, "Flags : 0x%.08X ", m_SectionHeader[v].dwFlags.bWritable);
|
||||
fprintf(x_file, "Flags : 0x%.08X ", m_SectionHeader[v].dwFlags_value);
|
||||
|
||||
if(m_SectionHeader[v].dwFlags.bWritable)
|
||||
fprintf(x_file, "(Writable) ");
|
||||
|
@ -773,16 +773,16 @@ void Xbe::DumpInformation(FILE *x_file)
|
|||
|
||||
// print flags
|
||||
{
|
||||
fprintf(x_file, "Flags : ");
|
||||
fprintf(x_file, "Flags : 0x%.04X ", m_LibraryVersion[v].wFlags_value);
|
||||
|
||||
fprintf(x_file, "QFEVersion : 0x%.04X, ", m_LibraryVersion[v].dwFlags.QFEVersion);
|
||||
fprintf(x_file, "QFEVersion : 0x%.04X, ", m_LibraryVersion[v].wFlags.QFEVersion);
|
||||
|
||||
if(m_LibraryVersion[v].dwFlags.bDebugBuild)
|
||||
if(m_LibraryVersion[v].wFlags.bDebugBuild)
|
||||
fprintf(x_file, "Debug, ");
|
||||
else
|
||||
fprintf(x_file, "Retail, ");
|
||||
|
||||
switch(m_LibraryVersion[v].dwFlags.Approved)
|
||||
switch(m_LibraryVersion[v].wFlags.Approved)
|
||||
{
|
||||
case 0:
|
||||
fprintf(x_file, "Unapproved");
|
||||
|
|
|
@ -92,7 +92,7 @@ class Xbe : public Error
|
|||
uint32 dwSections; // 0x011C - number of sections
|
||||
uint32 dwSectionHeadersAddr; // 0x0120 - section headers address
|
||||
|
||||
struct InitFlags // 0x0124 - initialization flags
|
||||
typedef struct
|
||||
{
|
||||
uint32 bMountUtilityDrive : 1; // mount utility drive flag
|
||||
uint32 bFormatUtilityDrive : 1; // format utility drive flag
|
||||
|
@ -102,8 +102,12 @@ class Xbe : public Error
|
|||
uint32 Unused_b1 : 8; // unused (or unknown)
|
||||
uint32 Unused_b2 : 8; // unused (or unknown)
|
||||
uint32 Unused_b3 : 8; // unused (or unknown)
|
||||
}
|
||||
dwInitFlags;
|
||||
} InitFlags;
|
||||
|
||||
union { // 0x0124 - initialization flags
|
||||
InitFlags dwInitFlags;
|
||||
uint32 dwInitFlags_value;
|
||||
};
|
||||
|
||||
uint32 dwEntryAddr; // 0x0128 - entry point address
|
||||
uint32 dwTLSAddr; // 0x012C - thread local storage directory address
|
||||
|
@ -162,7 +166,7 @@ class Xbe : public Error
|
|||
#include "AlignPrefix1.h"
|
||||
struct SectionHeader
|
||||
{
|
||||
struct _Flags
|
||||
typedef struct
|
||||
{
|
||||
uint32 bWritable : 1; // writable flag
|
||||
uint32 bPreload : 1; // preload flag
|
||||
|
@ -175,8 +179,12 @@ class Xbe : public Error
|
|||
uint32 Unused_b1 : 8; // unused (or unknown)
|
||||
uint32 Unused_b2 : 8; // unused (or unknown)
|
||||
uint32 Unused_b3 : 8; // unused (or unknown)
|
||||
}
|
||||
dwFlags;
|
||||
} _Flags;
|
||||
|
||||
union {
|
||||
_Flags dwFlags;
|
||||
uint32 dwFlags_value;
|
||||
};
|
||||
|
||||
uint32 dwVirtualAddr; // virtual address
|
||||
uint32 dwVirtualSize; // virtual size
|
||||
|
@ -200,13 +208,17 @@ class Xbe : public Error
|
|||
uint16 wMinorVersion; // minor version
|
||||
uint16 wBuildVersion; // build version
|
||||
|
||||
struct Flags
|
||||
typedef struct
|
||||
{
|
||||
uint16 QFEVersion : 13; // QFE Version
|
||||
uint16 Approved : 2; // Approved? (0:no, 1:possibly, 2:yes)
|
||||
uint16 bDebugBuild : 1; // Is this a debug build?
|
||||
}
|
||||
dwFlags;
|
||||
} Flags;
|
||||
|
||||
union {
|
||||
Flags wFlags;
|
||||
uint16 wFlags_value;
|
||||
};
|
||||
}
|
||||
#include "AlignPosfix1.h"
|
||||
*m_LibraryVersion, *m_KernelLibraryVersion, *m_XAPILibraryVersion;
|
||||
|
|
|
@ -105,6 +105,7 @@
|
|||
#define ID_EMULATION_STARTDEBUG 40087
|
||||
#define ID_SETTINGS_HACKS 40088
|
||||
#define ID_HACKS_DISABLEPIXELSHADERS 40089
|
||||
#define ID_LED 40090
|
||||
#define IDC_STATIC -1
|
||||
|
||||
// Next default values for new objects
|
||||
|
@ -112,7 +113,7 @@
|
|||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 130
|
||||
#define _APS_NEXT_COMMAND_VALUE 40090
|
||||
#define _APS_NEXT_COMMAND_VALUE 40091
|
||||
#define _APS_NEXT_CONTROL_VALUE 1058
|
||||
#define _APS_NEXT_SYMED_VALUE 104
|
||||
#endif
|
||||
|
|
|
@ -42,12 +42,14 @@
|
|||
#include "ResCxbx.h"
|
||||
#include "CxbxVersion.h"
|
||||
#include "Shlwapi.h"
|
||||
#include <multimon.h>
|
||||
|
||||
#include <io.h>
|
||||
|
||||
#include <sstream> // for std::stringstream
|
||||
#include "CxbxKrnl/xxhash32.h" // for XXHash32::hash
|
||||
|
||||
#define XBOX_LED_FLASH_PERIOD 176 // if you know a more accurate value, put it here
|
||||
#define STBI_ONLY_JPEG
|
||||
#define STBI_NO_LINEAR
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
|
@ -84,6 +86,7 @@ void ClearHLECache()
|
|||
}
|
||||
|
||||
#define TIMERID_FPS 0
|
||||
#define TIMERID_LED 1
|
||||
|
||||
WndMain::WndMain(HINSTANCE x_hInstance) :
|
||||
Wnd(x_hInstance),
|
||||
|
@ -366,6 +369,23 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP
|
|||
|
||||
m_BackBmp = CreateCompatibleBitmap(hDC, m_w, m_h);
|
||||
|
||||
// create Xbox LED bitmap
|
||||
{
|
||||
m_xBmp = GetSystemMetrics(SM_CXMENUCHECK);
|
||||
m_yBmp = GetSystemMetrics(SM_CYMENUCHECK);
|
||||
m_LedDC = CreateCompatibleDC(hDC);
|
||||
m_LedBmp = CreateCompatibleBitmap(hDC, m_xBmp, m_yBmp);
|
||||
m_BrushBlack = CreateSolidBrush(RGB(0, 0, 0));
|
||||
m_BrushRed = CreateSolidBrush(RGB(255, 0, 0));
|
||||
m_BrushGreen = CreateSolidBrush(RGB(0, 255, 0));
|
||||
m_BrushOrange = CreateSolidBrush(RGB(255, 165, 0));
|
||||
m_PenBlack = CreatePen(PS_SOLID, 1, RGB(0, 0, 0));
|
||||
m_PenRed = CreatePen(PS_SOLID, 1, RGB(255, 0, 0));
|
||||
m_PenGreen = CreatePen(PS_SOLID, 1, RGB(0, 255, 0));
|
||||
m_PenOrange = CreatePen(PS_SOLID, 1, RGB(255, 165, 0));
|
||||
DrawLedBitmap(hwnd, true);
|
||||
}
|
||||
|
||||
// decompress jpeg, convert to bitmap resource
|
||||
{
|
||||
HRSRC hSrc = FindResource(NULL, MAKEINTRESOURCE(IDR_JPEG_SPLASH), "JPEG");
|
||||
|
@ -450,9 +470,14 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP
|
|||
if (m_hwndChild == NULL) {
|
||||
float fps = 0;
|
||||
float mspf = 0;
|
||||
bool LedHasChanged = false;
|
||||
int LedSequence[4] = { XBOX_LED_COLOUR_GREEN, XBOX_LED_COLOUR_GREEN, XBOX_LED_COLOUR_GREEN, XBOX_LED_COLOUR_GREEN };
|
||||
g_EmuShared->SetCurrentMSpF(&mspf);
|
||||
g_EmuShared->SetCurrentFPS(&fps);
|
||||
g_EmuShared->SetLedStatus(&LedHasChanged);
|
||||
g_EmuShared->SetLedSequence(LedSequence);
|
||||
SetTimer(hwnd, TIMERID_FPS, 1000, (TIMERPROC)NULL);
|
||||
SetTimer(hwnd, TIMERID_LED, XBOX_LED_FLASH_PERIOD, (TIMERPROC)NULL);
|
||||
m_hwndChild = GetWindow(hwnd, GW_CHILD); // (HWND)HIWORD(wParam) seems to be NULL
|
||||
UpdateCaption();
|
||||
RefreshMenus();
|
||||
|
@ -469,8 +494,10 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP
|
|||
// (HWND)HIWORD(wParam) seems to be NULL, so we can't compare to m_hwndChild
|
||||
if (m_hwndChild != NULL) { // Let's hope this signal originated from the only child window
|
||||
KillTimer(hwnd, TIMERID_FPS);
|
||||
KillTimer(hwnd, TIMERID_LED);
|
||||
m_hwndChild = NULL;
|
||||
StopEmulation();
|
||||
DrawLedBitmap(hwnd, true);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -487,6 +514,12 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP
|
|||
UpdateCaption();
|
||||
}
|
||||
break;
|
||||
|
||||
case TIMERID_LED:
|
||||
{
|
||||
DrawLedBitmap(hwnd, false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -1256,27 +1289,49 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP
|
|||
{
|
||||
FreeConsole();
|
||||
|
||||
HDC hDC = GetDC(hwnd);
|
||||
HDC hDC = GetDC(hwnd);
|
||||
|
||||
SelectObject(m_LogoDC, m_OrigLogo);
|
||||
SelectObject(m_LogoDC, m_OrigLogo);
|
||||
|
||||
SelectObject(m_BackDC, m_OrigBmp);
|
||||
SelectObject(m_BackDC, m_OrigBmp);
|
||||
|
||||
SelectObject(m_GameLogoDC, m_OrigGameLogo);
|
||||
|
||||
DeleteObject(m_LogoDC);
|
||||
SelectObject(m_LedDC, m_OriLed);
|
||||
|
||||
DeleteObject(m_BackDC);
|
||||
DeleteObject(m_LogoDC);
|
||||
|
||||
DeleteObject(m_BackDC);
|
||||
|
||||
DeleteObject(m_GameLogoDC);
|
||||
|
||||
DeleteObject(m_LogoBmp);
|
||||
DeleteObject(m_LedDC);
|
||||
|
||||
DeleteObject(m_BackBmp);
|
||||
DeleteObject(m_LogoBmp);
|
||||
|
||||
DeleteObject(m_BackBmp);
|
||||
|
||||
DeleteObject(m_GameLogoBMP);
|
||||
|
||||
ReleaseDC(hwnd, hDC);
|
||||
DeleteObject(m_LedBmp);
|
||||
|
||||
DeleteObject(m_BrushBlack);
|
||||
|
||||
DeleteObject(m_BrushRed);
|
||||
|
||||
DeleteObject(m_BrushGreen);
|
||||
|
||||
DeleteObject(m_BrushOrange);
|
||||
|
||||
DeleteObject(m_PenBlack);
|
||||
|
||||
DeleteObject(m_PenRed);
|
||||
|
||||
DeleteObject(m_PenGreen);
|
||||
|
||||
DeleteObject(m_PenOrange);
|
||||
|
||||
ReleaseDC(hwnd, hDC);
|
||||
|
||||
delete m_Xbe;
|
||||
|
||||
|
@ -2065,8 +2120,8 @@ void WndMain::CrashMonitor()
|
|||
if (m_bIsStarted) // that's a hard crash, Dr Watson is invoked
|
||||
{
|
||||
KillTimer(m_hwnd, TIMERID_FPS);
|
||||
//KillTimer(m_hwnd, 2); for the LED
|
||||
//DrawDefaultLedBitmap(hwnd); for the LED
|
||||
KillTimer(m_hwnd, TIMERID_LED);
|
||||
DrawLedBitmap(m_hwnd, true);
|
||||
m_hwndChild = NULL;
|
||||
m_bIsStarted = false;
|
||||
UpdateCaption();
|
||||
|
@ -2083,3 +2138,93 @@ void WndMain::CrashMonitor()
|
|||
|
||||
return;
|
||||
}
|
||||
|
||||
// draw Xbox LED bitmap
|
||||
void WndMain::DrawLedBitmap(HWND hwnd, bool bdefault)
|
||||
{
|
||||
HMENU hMenu = GetMenu(hwnd);
|
||||
if (bdefault) // draw default black bitmap
|
||||
{
|
||||
SelectObject(m_LedDC, m_BrushBlack);
|
||||
SelectObject(m_LedDC, m_PenBlack);
|
||||
m_OriLed = (HBITMAP)SelectObject(m_LedDC, m_LedBmp);
|
||||
Rectangle(m_LedDC, 0, 0, m_xBmp, m_yBmp);
|
||||
m_LedBmp = (HBITMAP)SelectObject(m_LedDC, m_OriLed);
|
||||
MENUITEMINFO mii;
|
||||
mii.cbSize = sizeof(mii);
|
||||
mii.fMask = MIIM_BITMAP | MIIM_FTYPE;
|
||||
mii.fType = MFT_RIGHTJUSTIFY;
|
||||
mii.hbmpItem = m_LedBmp;
|
||||
SetMenuItemInfo(hMenu, ID_LED, FALSE, &mii);
|
||||
DrawMenuBar(hwnd);
|
||||
}
|
||||
else // draw colored bitmap
|
||||
{
|
||||
static int LedSequenceOffset = 0;
|
||||
bool bLedHasChanged;
|
||||
int LedSequence[4];
|
||||
|
||||
g_EmuShared->GetLedStatus(&bLedHasChanged);
|
||||
g_EmuShared->GetLedSequence(LedSequence);
|
||||
if (bLedHasChanged)
|
||||
{
|
||||
LedSequenceOffset = 0;
|
||||
bLedHasChanged = false;
|
||||
g_EmuShared->SetLedStatus(&bLedHasChanged);
|
||||
}
|
||||
|
||||
m_OriLed = (HBITMAP)SelectObject(m_LedDC, m_LedBmp);
|
||||
Rectangle(m_LedDC, 0, 0, m_xBmp, m_yBmp);
|
||||
MENUITEMINFO mii;
|
||||
mii.cbSize = sizeof(mii);
|
||||
mii.fMask = MIIM_BITMAP | MIIM_FTYPE;
|
||||
mii.fType = MFT_RIGHTJUSTIFY;
|
||||
mii.hbmpItem = m_LedBmp;
|
||||
|
||||
switch (LedSequence[LedSequenceOffset])
|
||||
{
|
||||
case XBOX_LED_COLOUR_RED:
|
||||
{
|
||||
SelectObject(m_LedDC, m_BrushRed);
|
||||
SelectObject(m_LedDC, m_PenRed);
|
||||
}
|
||||
break;
|
||||
|
||||
case XBOX_LED_COLOUR_GREEN:
|
||||
{
|
||||
SelectObject(m_LedDC, m_BrushGreen);
|
||||
SelectObject(m_LedDC, m_PenGreen);
|
||||
}
|
||||
break;
|
||||
|
||||
case XBOX_LED_COLOUR_ORANGE:
|
||||
{
|
||||
SelectObject(m_LedDC, m_BrushOrange);
|
||||
SelectObject(m_LedDC, m_PenOrange);
|
||||
}
|
||||
break;
|
||||
|
||||
case XBOX_LED_COLOUR_OFF:
|
||||
{
|
||||
SelectObject(m_LedDC, m_BrushBlack);
|
||||
SelectObject(m_LedDC, m_PenBlack);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
m_LedBmp = (HBITMAP)SelectObject(m_LedDC, m_OriLed);
|
||||
if (LedSequenceOffset == 3)
|
||||
{
|
||||
LedSequenceOffset = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
++LedSequenceOffset;
|
||||
}
|
||||
SetMenuItemInfo(hMenu, ID_LED, FALSE, &mii);
|
||||
|
||||
DrawMenuBar(hwnd);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -131,18 +131,35 @@ class WndMain : public Wnd
|
|||
// ******************************************************************
|
||||
void CrashMonitor();
|
||||
|
||||
// ******************************************************************
|
||||
// * drawing information
|
||||
// ******************************************************************
|
||||
HDC m_BackDC;
|
||||
HDC m_LogoDC;
|
||||
// ******************************************************************
|
||||
// * draw Xbox LED bitmap
|
||||
// ******************************************************************
|
||||
void DrawLedBitmap(HWND hwnd, bool boolbDefault);
|
||||
|
||||
// ******************************************************************
|
||||
// * drawing information
|
||||
// ******************************************************************
|
||||
HDC m_BackDC;
|
||||
HDC m_LogoDC;
|
||||
HDC m_GameLogoDC;
|
||||
HBITMAP m_OrigBmp;
|
||||
HBITMAP m_OrigLogo;
|
||||
HDC m_LedDC;
|
||||
HBITMAP m_OrigBmp;
|
||||
HBITMAP m_OrigLogo;
|
||||
HBITMAP m_OrigGameLogo;
|
||||
HBITMAP m_BackBmp;
|
||||
HBITMAP m_LogoBmp;
|
||||
HBITMAP m_OriLed;
|
||||
HBITMAP m_BackBmp;
|
||||
HBITMAP m_LogoBmp;
|
||||
HBITMAP m_GameLogoBMP;
|
||||
HBITMAP m_LedBmp;
|
||||
HBRUSH m_BrushBlack;
|
||||
HBRUSH m_BrushRed;
|
||||
HBRUSH m_BrushGreen;
|
||||
HBRUSH m_BrushOrange;
|
||||
HPEN m_PenBlack;
|
||||
HPEN m_PenRed;
|
||||
HPEN m_PenGreen;
|
||||
HPEN m_PenOrange;
|
||||
int m_xBmp, m_yBmp;
|
||||
|
||||
// ******************************************************************
|
||||
// * Xbe objects
|
||||
|
|
|
@ -66,7 +66,6 @@ namespace xboxkrnl
|
|||
|
||||
#include "Xbox.h" // For InitXboxHardware()
|
||||
#include "EEPROMDevice.h" // For g_EEPROM
|
||||
#include "LED.h" // For LED::Sequence
|
||||
|
||||
/* prevent name collisions */
|
||||
namespace NtDll
|
||||
|
@ -84,7 +83,7 @@ Xbe::Header *CxbxKrnl_XbeHeader = NULL;
|
|||
|
||||
HWND CxbxKrnl_hEmuParent = NULL;
|
||||
DebugMode CxbxKrnl_DebugMode = DebugMode::DM_NONE;
|
||||
char* CxbxKrnl_DebugFileName = NULL;
|
||||
std::string CxbxKrnl_DebugFileName = "";
|
||||
Xbe::Certificate *g_pCertificate = NULL;
|
||||
|
||||
/*! thread handles */
|
||||
|
@ -534,7 +533,7 @@ void CxbxKrnlMain(int argc, char* argv[])
|
|||
}
|
||||
|
||||
// Get KernelDebugFileName :
|
||||
std::string DebugFileName;
|
||||
std::string DebugFileName = "";
|
||||
if (argc > 4) {
|
||||
DebugFileName = argv[5];
|
||||
}
|
||||
|
@ -651,6 +650,7 @@ void CxbxKrnlMain(int argc, char* argv[])
|
|||
}
|
||||
|
||||
CxbxRestoreContiguousMemory(szFilePath_memory_bin);
|
||||
CxbxRestorePersistentMemoryRegions();
|
||||
|
||||
EEPROM = CxbxRestoreEEPROM(szFilePath_EEPROM_bin);
|
||||
if (EEPROM == nullptr)
|
||||
|
@ -687,8 +687,6 @@ void CxbxKrnlMain(int argc, char* argv[])
|
|||
g_VMManager.InitializeChihiroDebug();
|
||||
}
|
||||
|
||||
CxbxRestorePersistentMemoryRegions();
|
||||
|
||||
// Copy over loaded Xbe Headers to specified base address
|
||||
memcpy((void*)CxbxKrnl_Xbe->m_Header.dwBaseAddr, &CxbxKrnl_Xbe->m_Header, sizeof(Xbe::Header));
|
||||
memcpy((void*)(CxbxKrnl_Xbe->m_Header.dwBaseAddr + sizeof(Xbe::Header)), CxbxKrnl_Xbe->m_HeaderEx, CxbxKrnl_Xbe->m_ExSize);
|
||||
|
@ -799,12 +797,6 @@ void LoadXboxKeys(std::string path)
|
|||
EmuWarning("Failed to load Keys.bin. Cxbx-Reloaded will be unable to read Save Data from a real Xbox");
|
||||
}
|
||||
|
||||
void SetLEDSequence(LED::Sequence aLEDSequence)
|
||||
{
|
||||
// TODO : Move to best suited location & implement
|
||||
// See http://xboxdevwiki.net/PIC#The_LED
|
||||
}
|
||||
|
||||
__declspec(noreturn) void CxbxKrnlInit
|
||||
(
|
||||
HWND hwndParent,
|
||||
|
@ -997,13 +989,7 @@ __declspec(noreturn) void CxbxKrnlInit
|
|||
}
|
||||
}
|
||||
|
||||
// duplicate handle in order to retain Suspend/Resume thread rights from a remote thread
|
||||
{
|
||||
HANDLE hDupHandle = NULL;
|
||||
|
||||
DuplicateHandle(g_CurrentProcessHandle, GetCurrentThread(), g_CurrentProcessHandle, &hDupHandle, 0, FALSE, DUPLICATE_SAME_ACCESS);
|
||||
CxbxKrnlRegisterThread(hDupHandle);
|
||||
}
|
||||
CxbxKrnlRegisterThread(GetCurrentThread());
|
||||
|
||||
// Clear critical section list
|
||||
//extern void InitializeSectionStructures(void);
|
||||
|
@ -1130,7 +1116,7 @@ void CxbxRestoreLaunchDataPage()
|
|||
|
||||
if (LaunchDataPAddr)
|
||||
{
|
||||
xboxkrnl::LaunchDataPage = (xboxkrnl::LAUNCH_DATA_PAGE*)CONTIGUOUS_MEMORY_BASE + LaunchDataPAddr;
|
||||
xboxkrnl::LaunchDataPage = (xboxkrnl::LAUNCH_DATA_PAGE*)(CONTIGUOUS_MEMORY_BASE + LaunchDataPAddr);
|
||||
// Mark the launch page as allocated to prevent other allocations from overwriting it
|
||||
xboxkrnl::MmAllocateContiguousMemoryEx(PAGE_SIZE, LaunchDataPAddr, LaunchDataPAddr + PAGE_SIZE - 1, PAGE_SIZE, PAGE_READWRITE);
|
||||
LaunchDataPAddr = NULL;
|
||||
|
@ -1187,6 +1173,19 @@ __declspec(noreturn) void CxbxKrnlCleanup(const char *szErrorMessage, ...)
|
|||
|
||||
void CxbxKrnlRegisterThread(HANDLE hThread)
|
||||
{
|
||||
// we must duplicate this handle in order to retain Suspend/Resume thread rights from a remote thread
|
||||
{
|
||||
HANDLE hDupHandle = NULL;
|
||||
|
||||
if (DuplicateHandle(g_CurrentProcessHandle, hThread, g_CurrentProcessHandle, &hDupHandle, 0, FALSE, DUPLICATE_SAME_ACCESS)) {
|
||||
hThread = hDupHandle; // Thread handle was duplicated, continue registration with the duplicate
|
||||
}
|
||||
else {
|
||||
auto message = CxbxGetLastErrorString("DuplicateHandle");
|
||||
EmuWarning(message.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
int v=0;
|
||||
|
||||
for(v=0;v<MAXIMUM_XBOX_THREADS;v++)
|
||||
|
|
|
@ -221,7 +221,7 @@ extern Xbe *CxbxKrnl_Xbe;
|
|||
/*! parent window handle */
|
||||
extern HWND CxbxKrnl_hEmuParent;
|
||||
extern DebugMode CxbxKrnl_DebugMode;
|
||||
extern char* CxbxKrnl_DebugFileName;
|
||||
extern std::string CxbxKrnl_DebugFileName;
|
||||
|
||||
/*! file paths */
|
||||
extern char szFilePath_CxbxReloaded_Exe[MAX_PATH];
|
||||
|
@ -232,4 +232,7 @@ extern char szFilePath_EEPROM_bin[MAX_PATH];
|
|||
}
|
||||
#endif
|
||||
|
||||
// Returns the last Win32 error, in string format. Returns an empty string if there is no error.
|
||||
extern std::string CxbxGetLastErrorString(char * lpszFunction);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -162,7 +162,7 @@ static XTL::X_VERTEXSHADERCONSTANTMODE g_VertexShaderConstantMode = X_D3DSCM_192
|
|||
XTL::X_D3DTILE XTL::EmuD3DTileCache[0x08] = {0};
|
||||
|
||||
// cached active texture
|
||||
XTL::X_D3DPixelContainer *XTL::EmuD3DActiveTexture[TEXTURE_STAGES] = {0,0,0,0};
|
||||
XTL::X_D3DBaseTexture *XTL::EmuD3DActiveTexture[TEXTURE_STAGES] = {0,0,0,0};
|
||||
|
||||
|
||||
// information passed to the create device proxy thread
|
||||
|
@ -471,14 +471,7 @@ VOID XTL::CxbxInitWindow(Xbe::Header *XbeHeader, uint32 XbeHeaderSize)
|
|||
// We set the priority of this thread a bit higher, to assure reliable timing :
|
||||
SetThreadPriority(hThread, THREAD_PRIORITY_ABOVE_NORMAL);
|
||||
|
||||
// we must duplicate this handle in order to retain Suspend/Resume thread rights from a remote thread
|
||||
{
|
||||
HANDLE hDupHandle = NULL;
|
||||
|
||||
DuplicateHandle(g_CurrentProcessHandle, hThread, g_CurrentProcessHandle, &hDupHandle, 0, FALSE, DUPLICATE_SAME_ACCESS);
|
||||
|
||||
CxbxKrnlRegisterThread(hDupHandle);
|
||||
}
|
||||
CxbxKrnlRegisterThread(hThread);
|
||||
}
|
||||
|
||||
/* TODO : Port this Dxbx code :
|
||||
|
@ -991,12 +984,66 @@ VOID CxbxGetPixelContainerMeasures
|
|||
}
|
||||
}
|
||||
|
||||
bool ConvertD3DTextureToARGBBuffer(
|
||||
XTL::X_D3DFORMAT X_Format,
|
||||
uint8 *pSrc,
|
||||
int SrcWidth, int SrcHeight,
|
||||
uint SrcPitch,
|
||||
uint8 *pDest, int DestPitch,
|
||||
int TextureStage = 0
|
||||
)
|
||||
{
|
||||
const XTL::FormatToARGBRow ConvertRowToARGB = EmuXBFormatComponentConverter(X_Format);
|
||||
if (ConvertRowToARGB == nullptr)
|
||||
return false; // Unhandled conversion
|
||||
|
||||
uint8 *unswizleBuffer = nullptr;
|
||||
if (XTL::EmuXBFormatIsSwizzled(X_Format)) {
|
||||
unswizleBuffer = (uint8*)malloc(SrcPitch * SrcHeight); // TODO : Reuse buffer when performance is important
|
||||
// First we need to unswizzle the texture data
|
||||
XTL::EmuUnswizzleRect(
|
||||
pSrc, SrcWidth, SrcHeight, 1, unswizleBuffer,
|
||||
SrcPitch, {}, {}, EmuXBFormatBytesPerPixel(X_Format)
|
||||
);
|
||||
// Convert colors from the unswizzled buffer
|
||||
pSrc = unswizleBuffer;
|
||||
}
|
||||
|
||||
int AdditionalArgument;
|
||||
if (X_Format == XTL::X_D3DFMT_P8)
|
||||
AdditionalArgument = (int)g_pCurrentPalette[TextureStage];
|
||||
else
|
||||
AdditionalArgument = DestPitch;
|
||||
|
||||
DWORD SrcRowOff = 0;
|
||||
uint8 *pDestRow = pDest;
|
||||
if (EmuXBFormatIsCompressed(X_Format)) {
|
||||
// All compressed formats (DXT1, DXT3 and DXT5) encode blocks of 4 pixels on 4 lines
|
||||
SrcHeight = (SrcHeight + 3) / 4;
|
||||
DestPitch *= 4;
|
||||
}
|
||||
|
||||
for (int y = 0; y < SrcHeight; y++) {
|
||||
*(int*)pDestRow = AdditionalArgument; // Dirty hack, to avoid an extra parameter to all conversion callbacks
|
||||
ConvertRowToARGB(pSrc + SrcRowOff, pDestRow, SrcWidth);
|
||||
SrcRowOff += SrcPitch;
|
||||
pDestRow += DestPitch;
|
||||
}
|
||||
|
||||
if (unswizleBuffer)
|
||||
free(unswizleBuffer);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint8 *XTL::ConvertD3DTextureToARGB(
|
||||
XTL::X_D3DPixelContainer *pXboxPixelContainer,
|
||||
uint8 *pSrc,
|
||||
int *pWidth, int *pHeight
|
||||
int *pWidth, int *pHeight,
|
||||
int TextureStage // default = 0
|
||||
)
|
||||
{
|
||||
// Avoid allocating pDest when ConvertD3DTextureToARGBBuffer will fail anyway
|
||||
XTL::X_D3DFORMAT X_Format = GetXboxPixelContainerFormat(pXboxPixelContainer);
|
||||
const XTL::FormatToARGBRow ConvertRowToARGB = EmuXBFormatComponentConverter(X_Format);
|
||||
if (ConvertRowToARGB == nullptr)
|
||||
|
@ -1012,43 +1059,18 @@ uint8 *XTL::ConvertD3DTextureToARGB(
|
|||
&SrcSize
|
||||
);
|
||||
|
||||
// Now we know ConvertD3DTextureToARGBBuffer will do it's thing, allocate the resulting buffer
|
||||
int DestPitch = *pWidth * sizeof(DWORD);
|
||||
uint8 *pDest = (uint8 *)malloc(DestPitch * *pHeight);
|
||||
|
||||
uint8 *unswizleBuffer = nullptr;
|
||||
if (XTL::EmuXBFormatIsSwizzled(X_Format)) {
|
||||
unswizleBuffer = (uint8*)malloc(SrcPitch * *pHeight); // TODO : Reuse buffer when performance is important
|
||||
// First we need to unswizzle the texture data
|
||||
XTL::EmuUnswizzleRect(
|
||||
pSrc, *pWidth, *pHeight, 1, unswizleBuffer,
|
||||
SrcPitch, {}, {}, EmuXBFormatBytesPerPixel(X_Format)
|
||||
);
|
||||
// Convert colors from the unswizzled buffer
|
||||
pSrc = unswizleBuffer;
|
||||
}
|
||||
|
||||
DWORD SrcRowOff = 0;
|
||||
uint8 *pDestRow = pDest;
|
||||
if (EmuXBFormatIsCompressed(X_Format)) {
|
||||
// All compressed formats (DXT1, DXT3 and DXT5) encode blocks of 4 pixels on 4 lines
|
||||
for (int y = 0; y < *pHeight; y+=4) {
|
||||
*(int*)pDestRow = DestPitch; // Dirty hack, to avoid an extra parameter to all conversion callbacks
|
||||
ConvertRowToARGB(pSrc + SrcRowOff, pDestRow, *pWidth);
|
||||
SrcRowOff += SrcPitch;
|
||||
pDestRow += DestPitch * 4;
|
||||
}
|
||||
}
|
||||
else {
|
||||
while (SrcRowOff < SrcSize) {
|
||||
ConvertRowToARGB(pSrc + SrcRowOff, pDestRow, *pWidth);
|
||||
SrcRowOff += SrcPitch;
|
||||
pDestRow += DestPitch;
|
||||
}
|
||||
}
|
||||
|
||||
if (unswizleBuffer)
|
||||
free(unswizleBuffer);
|
||||
// And convert the source towards that buffer
|
||||
/*ignore result*/ConvertD3DTextureToARGBBuffer(
|
||||
X_Format,
|
||||
pSrc, *pWidth, *pHeight, SrcPitch,
|
||||
pDest, DestPitch,
|
||||
TextureStage);
|
||||
|
||||
// NOTE : Caller must take ownership!
|
||||
return pDest;
|
||||
}
|
||||
|
||||
|
@ -2058,12 +2080,12 @@ static void EmuUnswizzleTextureStages()
|
|||
|
||||
for( int i = 0; i < TEXTURE_STAGES; i++ )
|
||||
{
|
||||
XTL::X_D3DPixelContainer *pPixelContainer = XTL::EmuD3DActiveTexture[i];
|
||||
if (pPixelContainer == NULL)
|
||||
XTL::X_D3DBaseTexture *pBaseTexture = XTL::EmuD3DActiveTexture[i];
|
||||
if (pBaseTexture == NULL)
|
||||
continue;
|
||||
|
||||
HRESULT hRet;
|
||||
XTL::IDirect3DTexture8 *pHostTexture = GetHostTexture(pPixelContainer);
|
||||
XTL::IDirect3DTexture8 *pHostTexture = GetHostTexture(pBaseTexture);
|
||||
if (pHostTexture != nullptr)
|
||||
{
|
||||
if (pHostTexture->GetType() == XTL::D3DRTYPE_CUBETEXTURE) continue; // Prevent exceptions - skip cubes for now
|
||||
|
@ -2071,15 +2093,15 @@ static void EmuUnswizzleTextureStages()
|
|||
DEBUG_D3DRESULT(hRet, "pHostTexture->UnlockRect");
|
||||
}
|
||||
|
||||
if(!IsXboxResourceLocked(pPixelContainer))
|
||||
if(!IsXboxResourceLocked(pBaseTexture))
|
||||
continue;
|
||||
|
||||
XTL::X_D3DFORMAT XBFormat = GetXboxPixelContainerFormat(pPixelContainer);
|
||||
XTL::X_D3DFORMAT XBFormat = GetXboxPixelContainerFormat(pBaseTexture);
|
||||
if(!XTL::EmuXBFormatIsSwizzled(XBFormat))
|
||||
continue;
|
||||
|
||||
DWORD dwBPP = XTL::EmuXBFormatBytesPerPixel(XBFormat);
|
||||
pPixelContainer->Common &= ~X_D3DCOMMON_ISLOCKED;
|
||||
pBaseTexture->Common &= ~X_D3DCOMMON_ISLOCKED;
|
||||
|
||||
// TODO: potentially XXHash32::hash() to see if this surface was actually modified..
|
||||
|
||||
|
@ -3092,7 +3114,7 @@ XTL::X_D3DSurface* WINAPI XTL::EMUPATCH(D3DDevice_GetBackBuffer2)
|
|||
pBackBuffer->Data = X_D3DRESOURCE_DATA_BACK_BUFFER;
|
||||
|
||||
// Increment reference count
|
||||
pBackBuffer->Common++;
|
||||
pBackBuffer->Common++; // EMUPATCH(D3DResource_AddRef)(pBackBuffer);
|
||||
|
||||
return pBackBuffer;
|
||||
}
|
||||
|
@ -3300,7 +3322,8 @@ XTL::X_D3DSurface * WINAPI XTL::EMUPATCH(D3DDevice_GetRenderTarget2)()
|
|||
|
||||
X_D3DSurface *result = g_pCachedRenderTarget;
|
||||
|
||||
EMUPATCH(D3DResource_AddRef)(result);
|
||||
if (result)
|
||||
result->Common++; // EMUPATCH(D3DResource_AddRef)(result);
|
||||
|
||||
RETURN(result);
|
||||
}
|
||||
|
@ -3333,7 +3356,8 @@ XTL::X_D3DSurface * WINAPI XTL::EMUPATCH(D3DDevice_GetDepthStencilSurface2)()
|
|||
|
||||
X_D3DSurface *result = g_pCachedDepthStencil;
|
||||
|
||||
EMUPATCH(D3DResource_AddRef)(result);
|
||||
if (result)
|
||||
result->Common++; // EMUPATCH(D3DResource_AddRef)(result);
|
||||
|
||||
RETURN(result);
|
||||
}
|
||||
|
@ -4433,7 +4457,7 @@ HRESULT WINAPI XTL::EMUPATCH(D3DDevice_SetIndices)
|
|||
VOID WINAPI XTL::EMUPATCH(D3DDevice_SetTexture)
|
||||
(
|
||||
DWORD Stage,
|
||||
X_D3DResource *pTexture
|
||||
X_D3DBaseTexture *pTexture
|
||||
)
|
||||
{
|
||||
FUNC_EXPORTS
|
||||
|
@ -4445,7 +4469,7 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetTexture)
|
|||
|
||||
IDirect3DBaseTexture8 *pHostBaseTexture = nullptr;
|
||||
|
||||
EmuD3DActiveTexture[Stage] = (X_D3DPixelContainer*)pTexture;
|
||||
EmuD3DActiveTexture[Stage] = pTexture;
|
||||
if(pTexture != NULL)
|
||||
{
|
||||
EmuVerifyResourceIsRegistered(pTexture);
|
||||
|
@ -5225,7 +5249,7 @@ VOID WINAPI XTL::EMUPATCH(D3DResource_Register)
|
|||
{
|
||||
// TODO: once this is known to be working, remove the warning
|
||||
EmuWarning("Vertex buffer allocation size unknown");
|
||||
dwSize = 0x2000; // temporarily assign a small buffer, which will be increased later
|
||||
dwSize = PAGE_SIZE; // temporarily assign a small buffer, which will be increased later
|
||||
/*hRet = E_FAIL;
|
||||
goto fail;*/
|
||||
}
|
||||
|
@ -5268,7 +5292,7 @@ VOID WINAPI XTL::EMUPATCH(D3DResource_Register)
|
|||
memcpy(pNativeData, (void*)pBase, dwSize);
|
||||
pNewHostVertexBuffer->Unlock();
|
||||
|
||||
pResource->Data = (DWORD)pNativeData; // For now, give the native buffer memory to Xbox. TODO : g_MemoryManager.AllocateContiguous
|
||||
pResource->Data = (DWORD)pBase; // Set pResource->Data to point to Xbox Vertex buffer memory
|
||||
}
|
||||
|
||||
DbgPrintf("EmuIDirect3DResource8_Register : Successfully Created VertexBuffer (0x%.08X)\n", pNewHostVertexBuffer);
|
||||
|
@ -5311,7 +5335,9 @@ VOID WINAPI XTL::EMUPATCH(D3DResource_Register)
|
|||
DbgPrintf("EmuIDirect3DResource8_Register :-> Texture...\n");
|
||||
}
|
||||
|
||||
X_D3DPixelContainer *pPixelContainer = (X_D3DPixelContainer*)pResource;
|
||||
pBase = (void*)((xbaddr)pBase | MM_SYSTEM_PHYSICAL_MAP);
|
||||
|
||||
X_D3DPixelContainer *pPixelContainer = (X_D3DPixelContainer*)pResource;
|
||||
|
||||
X_D3DFORMAT X_Format = GetXboxPixelContainerFormat(pPixelContainer);
|
||||
D3DFORMAT PCFormat = EmuXB2PC_D3DFormat(X_Format);
|
||||
|
@ -5337,9 +5363,20 @@ VOID WINAPI XTL::EMUPATCH(D3DResource_Register)
|
|||
// Let's try using some 16-bit format instead...
|
||||
if(X_Format == X_D3DFMT_X1R5G5B5 )
|
||||
{
|
||||
#ifdef OLD_COLOR_CONVERSION // Current approach
|
||||
EmuWarning( "X_D3DFMT_X1R5G5B5 -> D3DFMT_R5GB5" );
|
||||
X_Format = X_D3DFMT_R5G6B5;
|
||||
PCFormat = D3DFMT_R5G6B5;
|
||||
#else // Later, convert to ARGB :
|
||||
CacheFormat = PCFormat; // Save this for later
|
||||
PCFormat = D3DFMT_A8R8G8B8; // ARGB
|
||||
}
|
||||
|
||||
// Detect formats that must be converted to ARGB
|
||||
if (EmuXBFormatRequiresConversionToARGB(X_Format)) {
|
||||
CacheFormat = PCFormat; // Save this for later
|
||||
PCFormat = D3DFMT_A8R8G8B8; // ARGB
|
||||
#endif // !OLD_COLOR_CONVERSION
|
||||
}
|
||||
|
||||
DWORD dwWidth, dwHeight, dwBPP, dwDepth = 1, dwPitch = 0, dwMipMapLevels = 1;
|
||||
|
@ -5494,6 +5531,7 @@ VOID WINAPI XTL::EMUPATCH(D3DResource_Register)
|
|||
dwMipMapLevels = 3;
|
||||
}
|
||||
|
||||
#ifdef OLD_COLOR_CONVERSION // Current palette approach - Later, use ______P8ToARGBRow_C()
|
||||
// HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK
|
||||
// Since most modern graphics cards does not support
|
||||
// palette based textures we need to expand it to
|
||||
|
@ -5508,6 +5546,7 @@ VOID WINAPI XTL::EMUPATCH(D3DResource_Register)
|
|||
CacheFormat = PCFormat; // Save this for later
|
||||
PCFormat = D3DFMT_A8R8G8B8; // ARGB
|
||||
}
|
||||
#endif // OLD_COLOR_CONVERSION
|
||||
|
||||
if(bCubemap)
|
||||
{
|
||||
|
@ -5633,6 +5672,39 @@ VOID WINAPI XTL::EMUPATCH(D3DResource_Register)
|
|||
{
|
||||
// TODO: Fix or handle this situation..?
|
||||
}
|
||||
#ifndef OLD_COLOR_CONVERSION // Later, use ConvertD3DTextureToARGBBuffer
|
||||
else if (CacheFormat != 0) // Do we need to convert to ARGB?
|
||||
{
|
||||
EmuWarning("Unsupported texture format, expanding to D3DFMT_A8R8G8B8");
|
||||
|
||||
BYTE *pPixelData = (BYTE*)LockedRect.pBits;
|
||||
DWORD dwDataSize = dwMipWidth*dwMipHeight;
|
||||
DWORD* pExpandedTexture = (DWORD*)malloc(dwDataSize * sizeof(DWORD));
|
||||
|
||||
uint8 *pSrc = pPixelData;
|
||||
uint8 *pDest = (uint8 *)pExpandedTexture;
|
||||
|
||||
DWORD dwSrcPitch = dwMipWidth * dwBPP;//sizeof(DWORD);
|
||||
DWORD dwDestPitch = dwMipWidth * sizeof(DWORD);
|
||||
DWORD dwMipSizeInBytes = dwDataSize;
|
||||
|
||||
// Convert a row at a time, using a libyuv-like callback approach :
|
||||
if (!ConvertD3DTextureToARGBBuffer(
|
||||
X_Format,
|
||||
pSrc, dwMipWidth, dwMipHeight, dwSrcPitch,
|
||||
pDest, dwDestPitch,
|
||||
TextureStage)) {
|
||||
CxbxKrnlCleanup("Unhandled conversion!");
|
||||
}
|
||||
|
||||
//__asm int 3;
|
||||
// Copy the expanded texture back to the buffer
|
||||
memcpy(pPixelData, pExpandedTexture, dwDataSize * sizeof(DWORD));
|
||||
|
||||
// Flush unused data buffers
|
||||
free(pExpandedTexture);
|
||||
}
|
||||
#endif // !OLD_COLOR_CONVERSION
|
||||
else
|
||||
{
|
||||
if (bSwizzled)
|
||||
|
@ -5690,6 +5762,7 @@ VOID WINAPI XTL::EMUPATCH(D3DResource_Register)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef OLD_COLOR_CONVERSION // Currently, convert here. Later, use ConvertD3DTextureToARGBBuffer above
|
||||
if (CacheFormat != 0) // Do we need to convert to ARGB?
|
||||
{
|
||||
EmuWarning("Unsupported texture format, expanding to D3DFMT_A8R8G8B8");
|
||||
|
@ -5730,7 +5803,6 @@ VOID WINAPI XTL::EMUPATCH(D3DResource_Register)
|
|||
}
|
||||
else
|
||||
{
|
||||
#ifdef OLD_COLOR_CONVERSION
|
||||
const ComponentEncodingInfo *encoding = EmuXBFormatComponentEncodingInfo(X_Format);
|
||||
|
||||
for (unsigned int y = 0; y < dwDataSize; y++)
|
||||
|
@ -5757,26 +5829,6 @@ VOID WINAPI XTL::EMUPATCH(D3DResource_Register)
|
|||
w += dwMipWidth * (sizeof(DWORD) - dwBPP);
|
||||
}
|
||||
}
|
||||
#else // !OLD_COLOR_CONVERSION
|
||||
// Convert a row at a time, using a libyuv-like callback approach :
|
||||
const FormatToARGBRow ConvertRowToARGB = EmuXBFormatComponentConverter(X_Format);
|
||||
if (ConvertRowToARGB == nullptr)
|
||||
CxbxKrnlCleanup("Unhandled conversion!");
|
||||
|
||||
uint8 *pSrc = pPixelData;
|
||||
uint8 *pDest = (uint8 *)pExpandedTexture;
|
||||
DWORD dwSrcPitch = dwMipWidth * sizeof(DWORD);
|
||||
DWORD dwDestPitch = dwMipWidth * sizeof(DWORD);
|
||||
DWORD dwMipSizeInBytes = dwDataSize;
|
||||
|
||||
DWORD SrcRowOff = 0;
|
||||
uint8 *pDestRow = (uint8 *)pDest;
|
||||
while (SrcRowOff < dwMipSizeInBytes) {
|
||||
ConvertRowToARGB(((uint8 *)pSrc) + SrcRowOff, pDestRow, dwMipWidth);
|
||||
SrcRowOff += dwSrcPitch;
|
||||
pDestRow += dwDestPitch;
|
||||
}
|
||||
#endif // !OLD_COLOR_CONVERSION
|
||||
}
|
||||
|
||||
//__asm int 3;
|
||||
|
@ -5786,6 +5838,7 @@ VOID WINAPI XTL::EMUPATCH(D3DResource_Register)
|
|||
// Flush unused data buffers
|
||||
free(pExpandedTexture);
|
||||
}
|
||||
#endif // !OLD_COLOR_CONVERSION
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5899,7 +5952,7 @@ ULONG WINAPI XTL::EMUPATCH(D3DResource_AddRef)
|
|||
X_D3DResource *pThis
|
||||
)
|
||||
{
|
||||
FUNC_EXPORTS
|
||||
// FUNC_EXPORTS
|
||||
|
||||
LOG_FUNC_ONE_ARG(pThis);
|
||||
|
||||
|
@ -7883,7 +7936,7 @@ XTL::X_D3DVertexBuffer* WINAPI XTL::EMUPATCH(D3DDevice_GetStreamSource2)
|
|||
pVertexBuffer = g_D3DStreams[StreamNumber];
|
||||
if (pVertexBuffer)
|
||||
{
|
||||
EMUPATCH(D3DResource_AddRef)(pVertexBuffer);
|
||||
pVertexBuffer->Common++; // EMUPATCH(D3DResource_AddRef)(pVertexBuffer);
|
||||
*pStride = g_D3DStreamStrides[StreamNumber];
|
||||
}
|
||||
}
|
||||
|
@ -7944,7 +7997,7 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetStreamSource)
|
|||
#ifdef _DEBUG_TRACK_VB
|
||||
if(pStreamData != NULL)
|
||||
{
|
||||
g_bVBSkipStream = g_VBTrackDisable.exists(GetHostVertexBuffer(pStreamData));
|
||||
g_bVBSkipStream = g_VBTrackDisable.exists(pHostVertexBuffer);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -9619,22 +9672,38 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_KickPushBuffer)()
|
|||
// ******************************************************************
|
||||
// * patch: D3DDevice_GetTexture2
|
||||
// ******************************************************************
|
||||
XTL::X_D3DResource* WINAPI XTL::EMUPATCH(D3DDevice_GetTexture2)(DWORD Stage)
|
||||
XTL::X_D3DBaseTexture* WINAPI XTL::EMUPATCH(D3DDevice_GetTexture2)(DWORD Stage)
|
||||
{
|
||||
FUNC_EXPORTS
|
||||
|
||||
LOG_FUNC_ONE_ARG(Stage);
|
||||
|
||||
// Get the active texture from this stage
|
||||
X_D3DPixelContainer* pRet = EmuD3DActiveTexture[Stage];
|
||||
X_D3DBaseTexture* pRet = EmuD3DActiveTexture[Stage];
|
||||
|
||||
if (pRet) {
|
||||
pRet->Common++;
|
||||
pRet->Common++; // EMUPATCH(D3DResource_AddRef)(pRet);
|
||||
}
|
||||
|
||||
return pRet;
|
||||
}
|
||||
|
||||
// ******************************************************************
|
||||
// * patch: D3DDevice_GetTexture
|
||||
// ******************************************************************
|
||||
VOID WINAPI XTL::EMUPATCH(D3DDevice_GetTexture)
|
||||
(
|
||||
DWORD Stage,
|
||||
XTL::X_D3DBaseTexture **pTexture
|
||||
)
|
||||
{
|
||||
FUNC_EXPORTS
|
||||
|
||||
LOG_FORWARD("D3DDevice_GetTexture2");
|
||||
|
||||
*pTexture = EMUPATCH(D3DDevice_GetTexture2)(Stage);
|
||||
}
|
||||
|
||||
// ******************************************************************
|
||||
// * patch: D3DDevice_SetStateVB (D3D::CDevice::SetStateVB)
|
||||
// ******************************************************************
|
||||
|
|
|
@ -60,7 +60,8 @@ extern VOID CxbxSetPixelContainerHeader
|
|||
extern uint8 *ConvertD3DTextureToARGB(
|
||||
XTL::X_D3DPixelContainer *pXboxPixelContainer,
|
||||
uint8 *pSrc,
|
||||
int *pWidth, int *pHeight
|
||||
int *pWidth, int *pHeight,
|
||||
int TextureStage = 0
|
||||
);
|
||||
|
||||
// initialize direct3d
|
||||
|
@ -73,7 +74,7 @@ extern VOID EmuD3DCleanup();
|
|||
extern X_D3DTILE EmuD3DTileCache[0x08];
|
||||
|
||||
// EmuD3DActiveTexture
|
||||
extern X_D3DPixelContainer *EmuD3DActiveTexture[TEXTURE_STAGES];
|
||||
extern X_D3DBaseTexture *EmuD3DActiveTexture[TEXTURE_STAGES];
|
||||
|
||||
// ******************************************************************
|
||||
// * patch: Direct3D_CreateDevice
|
||||
|
@ -559,7 +560,7 @@ HRESULT WINAPI EMUPATCH(D3DDevice_SetIndices)
|
|||
VOID WINAPI EMUPATCH(D3DDevice_SetTexture)
|
||||
(
|
||||
DWORD Stage,
|
||||
X_D3DResource *pTexture
|
||||
X_D3DBaseTexture *pTexture
|
||||
);
|
||||
|
||||
// ******************************************************************
|
||||
|
@ -1735,7 +1736,16 @@ VOID WINAPI EMUPATCH(D3DDevice_KickPushBuffer)();
|
|||
// ******************************************************************
|
||||
// * patch: D3DDevice_GetTexture2
|
||||
// ******************************************************************
|
||||
X_D3DResource* WINAPI EMUPATCH(D3DDevice_GetTexture2)(DWORD Stage);
|
||||
X_D3DBaseTexture* WINAPI EMUPATCH(D3DDevice_GetTexture2)(DWORD Stage);
|
||||
|
||||
// ******************************************************************
|
||||
// * patch: D3DDevice_GetTexture
|
||||
// ******************************************************************
|
||||
VOID WINAPI EMUPATCH(D3DDevice_GetTexture)
|
||||
(
|
||||
DWORD Stage,
|
||||
X_D3DBaseTexture **pTexture
|
||||
);
|
||||
|
||||
// ******************************************************************
|
||||
// * patch: D3DDevice_SetStateVB (D3D::CDevice::SetStateVB)
|
||||
|
|
|
@ -51,15 +51,15 @@
|
|||
enum _ComponentEncoding {
|
||||
NoCmpnts = 0, // Format doesn't contain any component (ARGB/QWVU)
|
||||
A1R5G5B5,
|
||||
X1R5G5B5,
|
||||
X1R5G5B5, // NOTE : A=255
|
||||
A4R4G4B4,
|
||||
__R5G6B5, // NOTE : A=255
|
||||
A8R8G8B8,
|
||||
X8R8G8B8,
|
||||
X8R8G8B8, // NOTE : A=255
|
||||
____R8B8, // NOTE : A takes R, G takes B
|
||||
____G8B8, // NOTE : A takes G, R takes B
|
||||
______A8,
|
||||
__R6G5B5,
|
||||
______A8, // TEST : R=G=B= 255
|
||||
__R6G5B5, // NOTE : A=255
|
||||
R5G5B5A1,
|
||||
R4G4B4A4,
|
||||
A8B8G8R8,
|
||||
|
@ -754,8 +754,8 @@ enum _FormatStorage {
|
|||
Cmprsd // Compressed
|
||||
};
|
||||
|
||||
enum _FormatSpecial {
|
||||
None = 0,
|
||||
enum _FormatUsage {
|
||||
Texture = 0,
|
||||
RenderTarget,
|
||||
DepthBuffer
|
||||
};
|
||||
|
@ -765,7 +765,7 @@ typedef struct _FormatInfo {
|
|||
_FormatStorage stored;
|
||||
_ComponentEncoding components;
|
||||
XTL::D3DFORMAT pc;
|
||||
_FormatSpecial special;
|
||||
_FormatUsage usage;
|
||||
char *warning;
|
||||
} FormatInfo;
|
||||
|
||||
|
@ -781,7 +781,7 @@ static const FormatInfo FormatInfos[] = {
|
|||
// to ARGB is needed (which is implemented in EMUPATCH(D3DResource_Register).
|
||||
|
||||
/* 0x00 X_D3DFMT_L8 */ { 8, Swzzld, ______L8, XTL::D3DFMT_L8 },
|
||||
/* 0x01 X_D3DFMT_AL8 */ { 8, Swzzld, _____AL8, XTL::D3DFMT_L8 , None, "X_D3DFMT_AL8 -> D3DFMT_L8" },
|
||||
/* 0x01 X_D3DFMT_AL8 */ { 8, Swzzld, _____AL8, XTL::D3DFMT_L8 , Texture, "X_D3DFMT_AL8 -> D3DFMT_L8" },
|
||||
/* 0x02 X_D3DFMT_A1R5G5B5 */ { 16, Swzzld, A1R5G5B5, XTL::D3DFMT_A1R5G5B5 },
|
||||
/* 0x03 X_D3DFMT_X1R5G5B5 */ { 16, Swzzld, X1R5G5B5, XTL::D3DFMT_X1R5G5B5 , RenderTarget },
|
||||
/* 0x04 X_D3DFMT_A4R4G4B4 */ { 16, Swzzld, A4R4G4B4, XTL::D3DFMT_A4R4G4B4 },
|
||||
|
@ -802,12 +802,12 @@ static const FormatInfo FormatInfos[] = {
|
|||
/* 0x13 X_D3DFMT_LIN_L8 */ { 8, Linear, ______L8, XTL::D3DFMT_L8 , RenderTarget },
|
||||
/* 0x14 undefined */ {},
|
||||
/* 0x15 undefined */ {},
|
||||
/* 0x16 X_D3DFMT_LIN_R8B8 */ { 16, Linear, ____R8B8, XTL::D3DFMT_R5G6B5 , None, "X_D3DFMT_LIN_R8B8 -> D3DFMT_R5G6B5" },
|
||||
/* 0x16 X_D3DFMT_LIN_R8B8 */ { 16, Linear, ____R8B8, XTL::D3DFMT_R5G6B5 , Texture, "X_D3DFMT_LIN_R8B8 -> D3DFMT_R5G6B5" },
|
||||
/* 0x17 X_D3DFMT_LIN_G8B8 */ { 16, Linear, ____G8B8, XTL::D3DFMT_R5G6B5 , RenderTarget, "X_D3DFMT_LIN_G8B8 -> D3DFMT_R5G6B5" }, // Alias : X_D3DFMT_LIN_V8U8
|
||||
/* 0x18 undefined */ {},
|
||||
/* 0x19 X_D3DFMT_A8 */ { 8, Swzzld, ______A8, XTL::D3DFMT_A8 },
|
||||
/* 0x1A X_D3DFMT_A8L8 */ { 16, Swzzld, ____A8L8, XTL::D3DFMT_A8L8 },
|
||||
/* 0x1B X_D3DFMT_LIN_AL8 */ { 8, Linear, _____AL8, XTL::D3DFMT_L8 , None, "X_D3DFMT_LIN_AL8 -> D3DFMT_L8" },
|
||||
/* 0x1B X_D3DFMT_LIN_AL8 */ { 8, Linear, _____AL8, XTL::D3DFMT_L8 , Texture, "X_D3DFMT_LIN_AL8 -> D3DFMT_L8" },
|
||||
/* 0x1C X_D3DFMT_LIN_X1R5G5B5 */ { 16, Linear, X1R5G5B5, XTL::D3DFMT_X1R5G5B5 , RenderTarget },
|
||||
/* 0x1D X_D3DFMT_LIN_A4R4G4B4 */ { 16, Linear, A4R4G4B4, XTL::D3DFMT_A4R4G4B4 },
|
||||
/* 0x1E X_D3DFMT_LIN_X8R8G8B8 */ { 32, Linear, X8R8G8B8, XTL::D3DFMT_X8R8G8B8 , RenderTarget }, // Alias : X_D3DFMT_LIN_X8L8V8U8
|
||||
|
@ -821,31 +821,31 @@ static const FormatInfo FormatInfos[] = {
|
|||
/* 0x26 undefined */ {},
|
||||
/* 0x27 X_D3DFMT_L6V5U5 */ { 16, Swzzld, __R6G5B5, XTL::D3DFMT_L6V5U5 }, // Alias : X_D3DFMT_R6G5B5 // XQEMU NOTE : This might be signed
|
||||
/* 0x28 X_D3DFMT_V8U8 */ { 16, Swzzld, ____G8B8, XTL::D3DFMT_V8U8 }, // Alias : X_D3DFMT_G8B8 // XQEMU NOTE : This might be signed
|
||||
/* 0x29 X_D3DFMT_R8B8 */ { 16, Swzzld, ____R8B8, XTL::D3DFMT_R5G6B5 , None, "X_D3DFMT_R8B8 -> D3DFMT_R5G6B5" }, // XQEMU NOTE : This might be signed
|
||||
/* 0x29 X_D3DFMT_R8B8 */ { 16, Swzzld, ____R8B8, XTL::D3DFMT_R5G6B5 , Texture, "X_D3DFMT_R8B8 -> D3DFMT_R5G6B5" }, // XQEMU NOTE : This might be signed
|
||||
/* 0x2A X_D3DFMT_D24S8 */ { 32, Swzzld, NoCmpnts, XTL::D3DFMT_D24S8 , DepthBuffer },
|
||||
/* 0x2B X_D3DFMT_F24S8 */ { 32, Swzzld, NoCmpnts, XTL::D3DFMT_D24S8 , DepthBuffer, "X_D3DFMT_F24S8 -> D3DFMT_D24S8" }, // HACK : PC doesn't have D3DFMT_F24S8 (Float vs Int)
|
||||
/* 0x2C X_D3DFMT_D16 */ { 16, Swzzld, NoCmpnts, XTL::D3DFMT_D16 , DepthBuffer }, // Alias : X_D3DFMT_D16_LOCKABLE // TODO : D3DFMT_D16 is always lockable on Xbox; Should PC use D3DFMT_D16_LOCKABLE instead? Needs testcase.
|
||||
/* 0x2D X_D3DFMT_F16 */ { 16, Swzzld, NoCmpnts, XTL::D3DFMT_D16 , DepthBuffer, "X_D3DFMT_F16 -> D3DFMT_D16" }, // HACK : PC doesn't have D3DFMT_F16 (Float vs Int)
|
||||
/* 0x2C X_D3DFMT_D16 */ { 16, Swzzld, NoCmpnts, XTL::D3DFMT_D16_LOCKABLE, DepthBuffer }, // Alias : X_D3DFMT_D16_LOCKABLE // Note : D3DFMT_D16 is always lockable on Xbox, D3DFMT_D16 on host is not.
|
||||
/* 0x2D X_D3DFMT_F16 */ { 16, Swzzld, NoCmpnts, XTL::D3DFMT_D16_LOCKABLE, DepthBuffer, "X_D3DFMT_F16 -> D3DFMT_D16" }, // HACK : PC doesn't have D3DFMT_F16 (Float vs Int)
|
||||
/* 0x2E X_D3DFMT_LIN_D24S8 */ { 32, Linear, NoCmpnts, XTL::D3DFMT_D24S8 , DepthBuffer },
|
||||
/* 0x2F X_D3DFMT_LIN_F24S8 */ { 32, Linear, NoCmpnts, XTL::D3DFMT_D24S8 , DepthBuffer, "X_D3DFMT_LIN_F24S8 -> D3DFMT_D24S8" }, // HACK : PC doesn't have D3DFMT_F24S8 (Float vs Int)
|
||||
/* 0x30 X_D3DFMT_LIN_D16 */ { 16, Linear, NoCmpnts, XTL::D3DFMT_D16 , DepthBuffer }, // TODO : D3DFMT_D16 is always lockable on Xbox; Should PC use D3DFMT_D16_LOCKABLE instead? Needs testcase.
|
||||
/* 0x31 X_D3DFMT_LIN_F16 */ { 16, Linear, NoCmpnts, XTL::D3DFMT_D16 , DepthBuffer, "X_D3DFMT_LIN_F16 -> D3DFMT_D16" }, // HACK : PC doesn't have D3DFMT_F16 (Float vs Int)
|
||||
/* 0x32 X_D3DFMT_L16 */ { 16, Swzzld, _____L16, XTL::D3DFMT_A8L8 , None, "X_D3DFMT_L16 -> D3DFMT_A8L8" },
|
||||
/* 0x30 X_D3DFMT_LIN_D16 */ { 16, Linear, NoCmpnts, XTL::D3DFMT_D16_LOCKABLE, DepthBuffer }, // Note : D3DFMT_D16 is always lockable on Xbox, D3DFMT_D16 on host is not.
|
||||
/* 0x31 X_D3DFMT_LIN_F16 */ { 16, Linear, NoCmpnts, XTL::D3DFMT_D16_LOCKABLE, DepthBuffer, "X_D3DFMT_LIN_F16 -> D3DFMT_D16" }, // HACK : PC doesn't have D3DFMT_F16 (Float vs Int)
|
||||
/* 0x32 X_D3DFMT_L16 */ { 16, Swzzld, _____L16, XTL::D3DFMT_A8L8 , Texture, "X_D3DFMT_L16 -> D3DFMT_A8L8" },
|
||||
/* 0x33 X_D3DFMT_V16U16 */ { 32, Swzzld, NoCmpnts, XTL::D3DFMT_V16U16 },
|
||||
/* 0x34 undefined */ {},
|
||||
/* 0x35 X_D3DFMT_LIN_L16 */ { 16, Linear, _____L16, XTL::D3DFMT_A8L8 , None, "X_D3DFMT_LIN_L16 -> D3DFMT_A8L8" },
|
||||
/* 0x35 X_D3DFMT_LIN_L16 */ { 16, Linear, _____L16, XTL::D3DFMT_A8L8 , Texture, "X_D3DFMT_LIN_L16 -> D3DFMT_A8L8" },
|
||||
/* 0x36 X_D3DFMT_LIN_V16U16 */ { 32, Linear, NoCmpnts, XTL::D3DFMT_V16U16 },
|
||||
/* 0x37 X_D3DFMT_LIN_L6V5U5 */ { 16, Linear, __R6G5B5, XTL::D3DFMT_L6V5U5 }, // Alias : X_D3DFMT_LIN_R6G5B5
|
||||
/* 0x38 X_D3DFMT_R5G5B5A1 */ { 16, Swzzld, R5G5B5A1, XTL::D3DFMT_A1R5G5B5 , None, "X_D3DFMT_R5G5B5A1 -> D3DFMT_A1R5G5B5" },
|
||||
/* 0x39 X_D3DFMT_R4G4B4A4 */ { 16, Swzzld, R4G4B4A4, XTL::D3DFMT_A4R4G4B4 , None, "X_D3DFMT_R4G4B4A4 -> D3DFMT_A4R4G4B4" },
|
||||
/* 0x38 X_D3DFMT_R5G5B5A1 */ { 16, Swzzld, R5G5B5A1, XTL::D3DFMT_A1R5G5B5 , Texture, "X_D3DFMT_R5G5B5A1 -> D3DFMT_A1R5G5B5" },
|
||||
/* 0x39 X_D3DFMT_R4G4B4A4 */ { 16, Swzzld, R4G4B4A4, XTL::D3DFMT_A4R4G4B4 , Texture, "X_D3DFMT_R4G4B4A4 -> D3DFMT_A4R4G4B4" },
|
||||
/* 0x3A X_D3DFMT_Q8W8V8U8 */ { 32, Swzzld, A8B8G8R8, XTL::D3DFMT_Q8W8V8U8 }, // Alias : X_D3DFMT_A8B8G8R8 // TODO : Needs testcase.
|
||||
/* 0x3B X_D3DFMT_B8G8R8A8 */ { 32, Swzzld, B8G8R8A8, XTL::D3DFMT_A8R8G8B8 , None, "X_D3DFMT_B8G8R8A8 -> D3DFMT_A8R8G8B8" },
|
||||
/* 0x3C X_D3DFMT_R8G8B8A8 */ { 32, Swzzld, R8G8B8A8, XTL::D3DFMT_A8R8G8B8 , None, "X_D3DFMT_R8G8B8A8 -> D3DFMT_A8R8G8B8" },
|
||||
/* 0x3D X_D3DFMT_LIN_R5G5B5A1 */ { 16, Linear, R5G5B5A1, XTL::D3DFMT_A1R5G5B5 , None, "X_D3DFMT_LIN_R5G5B5A1 -> D3DFMT_A1R5G5B5" },
|
||||
/* 0x3E X_D3DFMT_LIN_R4G4B4A4 */ { 16, Linear, R4G4B4A4, XTL::D3DFMT_A4R4G4B4 , None, "X_D3DFMT_LIN_R4G4B4A4 -> D3DFMT_A4R4G4B4" },
|
||||
/* 0x3F X_D3DFMT_LIN_A8B8G8R8 */ { 32, Linear, A8B8G8R8, XTL::D3DFMT_A8R8G8B8 , None, "X_D3DFMT_LIN_A8B8G8R8 -> D3DFMT_A8R8G8B8" },
|
||||
/* 0x40 X_D3DFMT_LIN_B8G8R8A8 */ { 32, Linear, B8G8R8A8, XTL::D3DFMT_A8R8G8B8 , None, "X_D3DFMT_LIN_B8G8R8A8 -> D3DFMT_A8R8G8B8" },
|
||||
/* 0x41 X_D3DFMT_LIN_R8G8B8A8 */ { 32, Linear, R8G8B8A8, XTL::D3DFMT_A8R8G8B8 , None, "X_D3DFMT_LIN_R8G8B8A8 -> D3DFMT_A8R8G8B8" },
|
||||
/* 0x3B X_D3DFMT_B8G8R8A8 */ { 32, Swzzld, B8G8R8A8, XTL::D3DFMT_A8R8G8B8 , Texture, "X_D3DFMT_B8G8R8A8 -> D3DFMT_A8R8G8B8" },
|
||||
/* 0x3C X_D3DFMT_R8G8B8A8 */ { 32, Swzzld, R8G8B8A8, XTL::D3DFMT_A8R8G8B8 , Texture, "X_D3DFMT_R8G8B8A8 -> D3DFMT_A8R8G8B8" },
|
||||
/* 0x3D X_D3DFMT_LIN_R5G5B5A1 */ { 16, Linear, R5G5B5A1, XTL::D3DFMT_A1R5G5B5 , Texture, "X_D3DFMT_LIN_R5G5B5A1 -> D3DFMT_A1R5G5B5" },
|
||||
/* 0x3E X_D3DFMT_LIN_R4G4B4A4 */ { 16, Linear, R4G4B4A4, XTL::D3DFMT_A4R4G4B4 , Texture, "X_D3DFMT_LIN_R4G4B4A4 -> D3DFMT_A4R4G4B4" },
|
||||
/* 0x3F X_D3DFMT_LIN_A8B8G8R8 */ { 32, Linear, A8B8G8R8, XTL::D3DFMT_A8R8G8B8 , Texture, "X_D3DFMT_LIN_A8B8G8R8 -> D3DFMT_A8R8G8B8" },
|
||||
/* 0x40 X_D3DFMT_LIN_B8G8R8A8 */ { 32, Linear, B8G8R8A8, XTL::D3DFMT_A8R8G8B8 , Texture, "X_D3DFMT_LIN_B8G8R8A8 -> D3DFMT_A8R8G8B8" },
|
||||
/* 0x41 X_D3DFMT_LIN_R8G8B8A8 */ { 32, Linear, R8G8B8A8, XTL::D3DFMT_A8R8G8B8 , Texture, "X_D3DFMT_LIN_R8G8B8A8 -> D3DFMT_A8R8G8B8" },
|
||||
#if 0
|
||||
/* 0x42 to 0x63 undefined */ {},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},
|
||||
/* 0x64 X_D3DFMT_VERTEXDATA */ { 8, Linear, NoCmpnts, XTL::D3DFMT_VERTEXDATA },
|
||||
|
@ -883,17 +883,28 @@ const XTL::FormatToARGBRow XTL::EmuXBFormatComponentConverter(X_D3DFORMAT Format
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
// Is there a converter available from the supplied format to ARGB?
|
||||
bool XTL::EmuXBFormatCanBeConvertedToARGB(X_D3DFORMAT Format)
|
||||
{
|
||||
const FormatToARGBRow info = EmuXBFormatComponentConverter(Format);
|
||||
return (info != nullptr);
|
||||
}
|
||||
|
||||
// Returns if convertion to ARGB is required. This is the case when
|
||||
// the format has a warning message and there's a converter present.
|
||||
bool XTL::EmuXBFormatRequiresConversionToARGB(X_D3DFORMAT Format)
|
||||
{
|
||||
#ifdef OLD_COLOR_CONVERSION
|
||||
const ComponentEncodingInfo *info = EmuXBFormatComponentEncodingInfo(Format);
|
||||
#else // !OLD_COLOR_CONVERSION
|
||||
const FormatToARGBRow info = EmuXBFormatComponentConverter(Format);
|
||||
#endif // !OLD_COLOR_CONVERSION
|
||||
// Conversion is required if there's ARGB conversion info present, and the format has a warning message
|
||||
if (info != nullptr)
|
||||
if (FormatInfos[Format].warning != nullptr)
|
||||
return true;
|
||||
#else // !OLD_COLOR_CONVERSION
|
||||
if (FormatInfos[Format].warning != nullptr)
|
||||
if (EmuXBFormatCanBeConvertedToARGB(Format))
|
||||
return true;
|
||||
#endif // !OLD_COLOR_CONVERSION
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -939,7 +950,7 @@ BOOL XTL::EmuXBFormatIsSwizzled(X_D3DFORMAT Format)
|
|||
BOOL XTL::EmuXBFormatIsRenderTarget(X_D3DFORMAT Format)
|
||||
{
|
||||
if (Format <= X_D3DFMT_LIN_R8G8B8A8)
|
||||
return (FormatInfos[Format].special == RenderTarget);
|
||||
return (FormatInfos[Format].usage == RenderTarget);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -947,7 +958,7 @@ BOOL XTL::EmuXBFormatIsRenderTarget(X_D3DFORMAT Format)
|
|||
BOOL XTL::EmuXBFormatIsDepthBuffer(X_D3DFORMAT Format)
|
||||
{
|
||||
if (Format <= X_D3DFMT_LIN_R8G8B8A8)
|
||||
return (FormatInfos[Format].special == DepthBuffer);
|
||||
return (FormatInfos[Format].usage == DepthBuffer);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
|
||||
#include "CxbxKrnl.h"
|
||||
|
||||
#define OLD_COLOR_CONVERSION
|
||||
//#define OLD_COLOR_CONVERSION
|
||||
|
||||
// simple render state encoding lookup table
|
||||
#define X_D3DRSSE_UNK 0x7fffffff
|
||||
|
@ -58,6 +58,8 @@ typedef void(*FormatToARGBRow)(const uint8* src, uint8* dst_argb, int width);
|
|||
|
||||
extern const FormatToARGBRow EmuXBFormatComponentConverter(X_D3DFORMAT Format);
|
||||
|
||||
bool EmuXBFormatCanBeConvertedToARGB(X_D3DFORMAT Format);
|
||||
|
||||
bool EmuXBFormatRequiresConversionToARGB(X_D3DFORMAT Format);
|
||||
|
||||
// how many bits does this format use per pixel?
|
||||
|
|
|
@ -639,18 +639,18 @@ bool XTL::VertexPatcher::NormalizeTexCoords(VertexPatchDesc *pPatchDesc, UINT ui
|
|||
{
|
||||
// Check for active linear textures.
|
||||
bool bHasLinearTex = false, bTexIsLinear[4] = { false };
|
||||
X_D3DPixelContainer *pLinearPixelContainer[4];
|
||||
X_D3DBaseTexture *pLinearBaseTexture[4];
|
||||
|
||||
for(uint08 i = 0; i < 4; i++)
|
||||
{
|
||||
X_D3DPixelContainer *pPixelContainer = EmuD3DActiveTexture[i];
|
||||
if (pPixelContainer)
|
||||
X_D3DBaseTexture *pBaseTexture = EmuD3DActiveTexture[i];
|
||||
if (pBaseTexture)
|
||||
{
|
||||
XTL::X_D3DFORMAT XBFormat = (XTL::X_D3DFORMAT)((pPixelContainer->Format & X_D3DFORMAT_FORMAT_MASK) >> X_D3DFORMAT_FORMAT_SHIFT);
|
||||
XTL::X_D3DFORMAT XBFormat = (XTL::X_D3DFORMAT)((pBaseTexture->Format & X_D3DFORMAT_FORMAT_MASK) >> X_D3DFORMAT_FORMAT_SHIFT);
|
||||
if (EmuXBFormatIsLinear(XBFormat))
|
||||
{
|
||||
bHasLinearTex = bTexIsLinear[i] = true;
|
||||
pLinearPixelContainer[i] = pPixelContainer;
|
||||
pLinearBaseTexture[i] = pBaseTexture;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -741,8 +741,8 @@ bool XTL::VertexPatcher::NormalizeTexCoords(VertexPatchDesc *pPatchDesc, UINT ui
|
|||
{
|
||||
if(bTexIsLinear[0])
|
||||
{
|
||||
((FLOAT*)pUVData)[0] /= ( pLinearPixelContainer[0]->Size & X_D3DSIZE_WIDTH_MASK) + 1;
|
||||
((FLOAT*)pUVData)[1] /= ((pLinearPixelContainer[0]->Size & X_D3DSIZE_HEIGHT_MASK) >> X_D3DSIZE_HEIGHT_SHIFT) + 1;
|
||||
((FLOAT*)pUVData)[0] /= ( pLinearBaseTexture[0]->Size & X_D3DSIZE_WIDTH_MASK) + 1;
|
||||
((FLOAT*)pUVData)[1] /= ((pLinearBaseTexture[0]->Size & X_D3DSIZE_HEIGHT_MASK) >> X_D3DSIZE_HEIGHT_SHIFT) + 1;
|
||||
}
|
||||
pUVData += sizeof(FLOAT) * 2;
|
||||
}
|
||||
|
@ -751,8 +751,8 @@ bool XTL::VertexPatcher::NormalizeTexCoords(VertexPatchDesc *pPatchDesc, UINT ui
|
|||
{
|
||||
if(bTexIsLinear[1])
|
||||
{
|
||||
((FLOAT*)pUVData)[0] /= ( pLinearPixelContainer[1]->Size & X_D3DSIZE_WIDTH_MASK) + 1;
|
||||
((FLOAT*)pUVData)[1] /= ((pLinearPixelContainer[1]->Size & X_D3DSIZE_HEIGHT_MASK) >> X_D3DSIZE_HEIGHT_SHIFT) + 1;
|
||||
((FLOAT*)pUVData)[0] /= ( pLinearBaseTexture[1]->Size & X_D3DSIZE_WIDTH_MASK) + 1;
|
||||
((FLOAT*)pUVData)[1] /= ((pLinearBaseTexture[1]->Size & X_D3DSIZE_HEIGHT_MASK) >> X_D3DSIZE_HEIGHT_SHIFT) + 1;
|
||||
}
|
||||
pUVData += sizeof(FLOAT) * 2;
|
||||
}
|
||||
|
@ -761,16 +761,16 @@ bool XTL::VertexPatcher::NormalizeTexCoords(VertexPatchDesc *pPatchDesc, UINT ui
|
|||
{
|
||||
if(bTexIsLinear[2])
|
||||
{
|
||||
((FLOAT*)pUVData)[0] /= ( pLinearPixelContainer[2]->Size & X_D3DSIZE_WIDTH_MASK) + 1;
|
||||
((FLOAT*)pUVData)[1] /= ((pLinearPixelContainer[2]->Size & X_D3DSIZE_HEIGHT_MASK) >> X_D3DSIZE_HEIGHT_SHIFT) + 1;
|
||||
((FLOAT*)pUVData)[0] /= ( pLinearBaseTexture[2]->Size & X_D3DSIZE_WIDTH_MASK) + 1;
|
||||
((FLOAT*)pUVData)[1] /= ((pLinearBaseTexture[2]->Size & X_D3DSIZE_HEIGHT_MASK) >> X_D3DSIZE_HEIGHT_SHIFT) + 1;
|
||||
}
|
||||
pUVData += sizeof(FLOAT) * 2;
|
||||
}
|
||||
|
||||
if((dwTexN >= 4) && bTexIsLinear[3])
|
||||
{
|
||||
((FLOAT*)pUVData)[0] /= ( pLinearPixelContainer[3]->Size & X_D3DSIZE_WIDTH_MASK) + 1;
|
||||
((FLOAT*)pUVData)[1] /= ((pLinearPixelContainer[3]->Size & X_D3DSIZE_HEIGHT_MASK) >> X_D3DSIZE_HEIGHT_SHIFT) + 1;
|
||||
((FLOAT*)pUVData)[0] /= ( pLinearBaseTexture[3]->Size & X_D3DSIZE_WIDTH_MASK) + 1;
|
||||
((FLOAT*)pUVData)[1] /= ((pLinearBaseTexture[3]->Size & X_D3DSIZE_HEIGHT_MASK) >> X_D3DSIZE_HEIGHT_SHIFT) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -188,8 +188,16 @@ void CxbxFormatPartitionByHandle(HANDLE hFile)
|
|||
// In this case, experimental means that these functions work and are safe
|
||||
// but not officially in the C++ standard yet
|
||||
// Requires a compiler with C++17 support
|
||||
std::experimental::filesystem::remove_all(partitionPath);
|
||||
std::experimental::filesystem::create_directory(partitionPath);
|
||||
try
|
||||
{
|
||||
std::experimental::filesystem::remove_all(partitionPath);
|
||||
std::experimental::filesystem::create_directory(partitionPath);
|
||||
}
|
||||
catch (std::experimental::filesystem::filesystem_error fsException)
|
||||
{
|
||||
printf("std::experimental::filesystem failed with message: %s\n", fsException.what());
|
||||
}
|
||||
|
||||
|
||||
printf("Formatted EmuDisk Partition%d\n", CxbxGetPartitionNumberFromHandle(hFile));
|
||||
}
|
||||
|
|
|
@ -57,6 +57,7 @@ namespace xboxkrnl
|
|||
#include "EmuShared.h"
|
||||
#include "EmuFile.h" // For FindNtSymbolicLinkObjectByDriveLetter
|
||||
|
||||
#include <algorithm> // for std::replace
|
||||
#include <locale>
|
||||
#include <codecvt>
|
||||
|
||||
|
@ -472,7 +473,11 @@ XBSYSAPI EXPORTNUM(49) xboxkrnl::VOID DECLSPEC_NORETURN NTAPI xboxkrnl::HalRetur
|
|||
|
||||
char szArgsBuffer[4096];
|
||||
|
||||
snprintf(szArgsBuffer, 4096, "/load \"%s\" %u %d \"%s\"", XbePath.c_str(), CxbxKrnl_hEmuParent, CxbxKrnl_DebugMode, CxbxKrnl_DebugFileName);
|
||||
// Some titles (Xbox Dashboard) use ";" as a final path seperator
|
||||
// This allows the Xbox Live option on the dashboard to properly launch XOnlinedash.xbe
|
||||
std::replace(XbePath.begin(), XbePath.end(), ';', '\\');
|
||||
|
||||
snprintf(szArgsBuffer, 4096, "/load \"%s\" %u %d \"%s\"", XbePath.c_str(), CxbxKrnl_hEmuParent, CxbxKrnl_DebugMode, CxbxKrnl_DebugFileName.c_str());
|
||||
if ((int)ShellExecute(NULL, "open", szFilePath_CxbxReloaded_Exe, szArgsBuffer, szWorkingDirectoy, SW_SHOWDEFAULT) <= 32)
|
||||
CxbxKrnlCleanup("Could not launch %s", XbePath.c_str());
|
||||
}
|
||||
|
@ -534,7 +539,7 @@ XBSYSAPI EXPORTNUM(50) xboxkrnl::NTSTATUS NTAPI xboxkrnl::HalWriteSMBusValue
|
|||
// Note : GE_HOST_STC triggers ExecuteTransaction, which writes the command to the specified address
|
||||
|
||||
// Check if the command was executed successfully
|
||||
if (g_SMBus->IORead(1, SMB_GLOBAL_STATUS) | GS_PRERR_STS) {
|
||||
if (g_SMBus->IORead(1, SMB_GLOBAL_STATUS) & GS_PRERR_STS) {
|
||||
Status = STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
|
|
|
@ -132,9 +132,12 @@ static unsigned int WINAPI PCSTProxy
|
|||
StartSuspended,
|
||||
hStartedEvent);
|
||||
|
||||
|
||||
// Do minimal thread initialization
|
||||
InitXboxThread(g_CPUXbox);
|
||||
|
||||
SetEvent(hStartedEvent);
|
||||
|
||||
if (StartSuspended == TRUE)
|
||||
// Suspend right before calling the thread notification routines
|
||||
SuspendThread(GetCurrentThread());
|
||||
|
@ -159,8 +162,6 @@ static unsigned int WINAPI PCSTProxy
|
|||
// use the special calling convention
|
||||
__try
|
||||
{
|
||||
SetEvent(hStartedEvent);
|
||||
|
||||
// Given the non-standard calling convention (requiring
|
||||
// the first argument in ebp+4) we need the below __asm.
|
||||
//
|
||||
|
@ -186,9 +187,6 @@ static unsigned int WINAPI PCSTProxy
|
|||
|
||||
callComplete:
|
||||
|
||||
if (hStartedEvent != NULL) {
|
||||
CloseHandle(hStartedEvent);
|
||||
}
|
||||
// This will also handle thread notification :
|
||||
xboxkrnl::PsTerminateSystemThread(STATUS_SUCCESS);
|
||||
|
||||
|
@ -301,6 +299,11 @@ XBSYSAPI EXPORTNUM(255) xboxkrnl::NTSTATUS NTAPI xboxkrnl::PsCreateSystemThreadE
|
|||
{
|
||||
DWORD dwThreadId = 0, dwThreadWait;
|
||||
bool bWait = true;
|
||||
HANDLE hStartedEvent = CreateEvent(NULL, FALSE, FALSE, TEXT("PCSTProxyEvent"));
|
||||
if (hStartedEvent == NULL) {
|
||||
std::string errorMessage = CxbxGetLastErrorString("PsCreateSystemThreadEx could not create PCSTProxyEvent");
|
||||
CxbxKrnlCleanup(errorMessage.c_str());
|
||||
}
|
||||
|
||||
// PCSTProxy is responsible for cleaning up this pointer
|
||||
::PCSTProxyParam *iPCSTProxyParam = new ::PCSTProxyParam();
|
||||
|
@ -309,45 +312,48 @@ XBSYSAPI EXPORTNUM(255) xboxkrnl::NTSTATUS NTAPI xboxkrnl::PsCreateSystemThreadE
|
|||
iPCSTProxyParam->StartContext = StartContext;
|
||||
iPCSTProxyParam->SystemRoutine = SystemRoutine; // NULL, XapiThreadStartup or unknown?
|
||||
iPCSTProxyParam->StartSuspended = CreateSuspended;
|
||||
iPCSTProxyParam->hStartedEvent = CreateEvent(NULL, FALSE, FALSE, TEXT("PCSTProxyEvent"));
|
||||
iPCSTProxyParam->hStartedEvent = hStartedEvent;
|
||||
|
||||
*ThreadHandle = (HANDLE)_beginthreadex(NULL, NULL, PCSTProxy, iPCSTProxyParam, NULL, (uint*)&dwThreadId);
|
||||
// Note : DO NOT use iPCSTProxyParam anymore, since ownership is transferred to the proxy (which frees it too)
|
||||
|
||||
DbgPrintf("KRNL: Waiting for Xbox proxy thread to start...\n");
|
||||
// Give the thread chance to start
|
||||
Sleep(100);
|
||||
|
||||
EmuWarning("KRNL: Waiting for Xbox proxy thread to start...\n");
|
||||
|
||||
while (bWait) {
|
||||
dwThreadWait = WaitForSingleObject(*ThreadHandle, 300);
|
||||
dwThreadWait = WaitForSingleObject(hStartedEvent, 300);
|
||||
switch (dwThreadWait) {
|
||||
// Thread is running
|
||||
case WAIT_TIMEOUT:
|
||||
// Thread is complete
|
||||
case WAIT_OBJECT_0: {
|
||||
// if either of two above is true, don't need to wait.
|
||||
case WAIT_TIMEOUT: { // The time-out interval elapsed, and the object's state is nonsignaled.
|
||||
EmuWarning("KRNL: Timeout while waiting for Xbox proxy thread to start...\n");
|
||||
bWait = false;
|
||||
break;
|
||||
}
|
||||
// A problem has occurred, what should we do?
|
||||
case WAIT_FAILED: {
|
||||
break;
|
||||
}
|
||||
// Unknown wait
|
||||
default:
|
||||
case WAIT_OBJECT_0: { // The state of the specified object is signaled.
|
||||
DbgPrintf("KRNL: Xbox proxy thread is started.\n");
|
||||
bWait = false;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
if (dwThreadWait == WAIT_FAILED) // The function has failed
|
||||
bWait = false;
|
||||
|
||||
std::string ErrorStr = CxbxGetLastErrorString("KRNL: While waiting for Xbox proxy thread to start");
|
||||
EmuWarning("%s\n", ErrorStr.c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Release the event
|
||||
CloseHandle(hStartedEvent);
|
||||
hStartedEvent = NULL;
|
||||
|
||||
// Log ThreadID identical to how GetCurrentThreadID() is rendered :
|
||||
DbgPrintf("KRNL: Created Xbox proxy thread. Handle : 0x%X, ThreadId : [0x%.4X]\n", *ThreadHandle, dwThreadId);
|
||||
EmuWarning("KRNL: Created Xbox proxy thread. Handle : 0x%X, ThreadId : [0x%.4X]\n", *ThreadHandle, dwThreadId);
|
||||
|
||||
// we must duplicate this handle in order to retain Suspend/Resume thread rights from a remote thread
|
||||
{
|
||||
HANDLE hDupHandle = NULL;
|
||||
|
||||
DuplicateHandle(g_CurrentProcessHandle, *ThreadHandle, g_CurrentProcessHandle, &hDupHandle, 0, FALSE, DUPLICATE_SAME_ACCESS);
|
||||
|
||||
CxbxKrnlRegisterThread(hDupHandle);
|
||||
}
|
||||
CxbxKrnlRegisterThread(*ThreadHandle);
|
||||
|
||||
if (ThreadId != NULL)
|
||||
*ThreadId = (xboxkrnl::HANDLE)dwThreadId;
|
||||
|
|
|
@ -41,6 +41,13 @@
|
|||
|
||||
#include <memory.h>
|
||||
|
||||
enum {
|
||||
XBOX_LED_COLOUR_OFF,
|
||||
XBOX_LED_COLOUR_GREEN,
|
||||
XBOX_LED_COLOUR_RED,
|
||||
XBOX_LED_COLOUR_ORANGE,
|
||||
};
|
||||
|
||||
enum {
|
||||
LLE_APU = 1 << 0,
|
||||
LLE_GPU = 1 << 1,
|
||||
|
@ -142,6 +149,30 @@ class EmuShared : public Mutex
|
|||
void GetLaunchDataPAddress(PAddr *value) { Lock(); *value = m_LaunchDataPAddress; Unlock(); }
|
||||
void SetLaunchDataPAddress(PAddr *value) { Lock(); m_LaunchDataPAddress = *value; Unlock(); }
|
||||
|
||||
// ******************************************************************
|
||||
// * Xbox LED values Accessors
|
||||
// ******************************************************************
|
||||
void GetLedStatus(bool *value) { Lock(); *value = m_bLedHasChanged; Unlock(); }
|
||||
void SetLedStatus(bool *value) { Lock(); m_bLedHasChanged = *value; Unlock(); }
|
||||
void GetLedSequence(int *value)
|
||||
{
|
||||
Lock();
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
value[i] = m_LedSequence[i];
|
||||
}
|
||||
Unlock();
|
||||
}
|
||||
void SetLedSequence(int *value)
|
||||
{
|
||||
Lock();
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
m_LedSequence[i] = value[i];
|
||||
}
|
||||
Unlock();
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
// ******************************************************************
|
||||
|
@ -165,6 +196,8 @@ class EmuShared : public Mutex
|
|||
bool m_bMultiXbe;
|
||||
bool m_bDebugging;
|
||||
PAddr m_LaunchDataPAddress;
|
||||
bool m_bLedHasChanged;
|
||||
int m_LedSequence[4];
|
||||
};
|
||||
|
||||
// ******************************************************************
|
||||
|
|
|
@ -176,7 +176,10 @@ OOVPA_END;
|
|||
// * D3D_CommonSetRenderTarget
|
||||
// ******************************************************************
|
||||
#ifndef WIP_LessVertexPatching
|
||||
OOVPA_NO_XREF(D3D_CommonSetRenderTarget, 4627, 12)
|
||||
OOVPA_XREF(D3D_CommonSetRenderTarget, 4627, 12,
|
||||
|
||||
XREF_D3D_CommonSetRenderTarget,
|
||||
XRefZero)
|
||||
#else
|
||||
OOVPA_XREF(D3D_CommonSetRenderTarget, 4627, 1+12,
|
||||
|
||||
|
@ -498,7 +501,10 @@ OOVPA_END;
|
|||
// * D3DDevice_GetDepthStencilSurface2
|
||||
// ******************************************************************
|
||||
#ifndef WIP_LessVertexPatching
|
||||
OOVPA_NO_XREF(D3DDevice_GetDepthStencilSurface2, 4627, 20)
|
||||
OOVPA_XREF(D3DDevice_GetDepthStencilSurface2, 4627, 20,
|
||||
|
||||
XREF_D3DDevice_GetDepthStencilSurface2,
|
||||
XRefZero)
|
||||
#else
|
||||
OOVPA_XREF(D3DDevice_GetDepthStencilSurface2, 4627, 1+20,
|
||||
|
||||
|
|
|
@ -90,5 +90,3 @@ namespace LED {
|
|||
constexpr Sequence FAST_GREEN_ORANGE = Phase0::Green | Phase1::Orange | Phase2::Green | Phase3::Orange;
|
||||
|
||||
}
|
||||
|
||||
extern void SetLEDSequence(LED::Sequence aLEDSequence);
|
||||
|
|
|
@ -24,13 +24,14 @@ void SMBus::Reset()
|
|||
|
||||
void SMBus::ConnectDevice(uint8_t addr, SMDevice *pDevice)
|
||||
{
|
||||
uint8_t dev_addr = (addr >> 1) & 0x7f;
|
||||
|
||||
if (m_Devices.find(addr) != m_Devices.end()) {
|
||||
if (m_Devices.find(dev_addr) != m_Devices.end()) {
|
||||
printf("PCIBus: Attempting to connect two devices to the same device address\n");
|
||||
return;
|
||||
}
|
||||
|
||||
m_Devices[addr] = pDevice;
|
||||
m_Devices[dev_addr] = pDevice;
|
||||
pDevice->Init();
|
||||
}
|
||||
|
||||
|
|
|
@ -35,15 +35,44 @@
|
|||
// ******************************************************************
|
||||
#define _XBOXKRNL_DEFEXTRN_
|
||||
|
||||
#include "SMCDevice.h" // For SMCDevice
|
||||
#include "LED.h"
|
||||
|
||||
/* prevent name collisions */
|
||||
namespace xboxkrnl
|
||||
{
|
||||
#include <xboxkrnl/xboxkrnl.h> // For xbox.h:AV_PACK_HDTV
|
||||
};
|
||||
|
||||
#include "EmuShared.h"
|
||||
#include "SMCDevice.h" // For SMCDevice
|
||||
#include "LED.h"
|
||||
|
||||
void SetLEDSequence(LED::Sequence aLEDSequence)
|
||||
{
|
||||
// See http://xboxdevwiki.net/PIC#The_LED
|
||||
DbgPrintf("SMC : SetLEDSequence : %u\n", (byte)aLEDSequence);
|
||||
|
||||
bool bLedHasChanged = true;
|
||||
|
||||
if (aLEDSequence == LED::GREEN) // Automatic solid green color
|
||||
{
|
||||
int LedSequence[4] = { XBOX_LED_COLOUR_GREEN, XBOX_LED_COLOUR_GREEN, XBOX_LED_COLOUR_GREEN, XBOX_LED_COLOUR_GREEN };
|
||||
|
||||
g_EmuShared->SetLedStatus(&bLedHasChanged);
|
||||
g_EmuShared->SetLedSequence(LedSequence);
|
||||
}
|
||||
else // Draw the color represented by the sequence obtained
|
||||
{
|
||||
int LedSequence[4] = { XBOX_LED_COLOUR_OFF, XBOX_LED_COLOUR_OFF, XBOX_LED_COLOUR_OFF, XBOX_LED_COLOUR_OFF };
|
||||
|
||||
LedSequence[0] = ((aLEDSequence >> 3) & 1) | ((aLEDSequence >> 6) & 2);
|
||||
LedSequence[1] = ((aLEDSequence >> 2) & 1) | ((aLEDSequence >> 5) & 2);
|
||||
LedSequence[2] = ((aLEDSequence >> 1) & 1) | ((aLEDSequence >> 4) & 2);
|
||||
LedSequence[3] = (aLEDSequence & 1) | ((aLEDSequence >> 3) & 2);
|
||||
|
||||
g_EmuShared->SetLedStatus(&bLedHasChanged);
|
||||
g_EmuShared->SetLedSequence(LedSequence);
|
||||
}
|
||||
}
|
||||
|
||||
/* SMCDevice */
|
||||
|
||||
SMCDevice::SMCDevice(HardwareModel hardwareModel)
|
||||
|
@ -153,7 +182,11 @@ void SMCDevice::WriteByte(uint8_t command, uint8_t value)
|
|||
// TODO : Implement the above, SMB_GLOBAL_STATUS should probably get the GS_PRERR_STS flag. But how?
|
||||
return;
|
||||
}
|
||||
// #define SMC_COMMAND_LED_SEQUENCE 0x08 // LED flashing sequence
|
||||
case SMC_COMMAND_LED_SEQUENCE: // 0x08 LED flashing sequence
|
||||
// ergo720: if WriteWord is true the Xbox still sets the LED correctly but it errors with ntstatus
|
||||
// STATUS_IO_DEVICE_ERROR, however WriteWord is not accessible from here
|
||||
// The LED flashing sequence is stored in the buffer of the SMCDevice class, so there's nothing to do here
|
||||
break;
|
||||
//0x0C tray eject(0 = eject; 1 = load)
|
||||
//0x0E another scratch register ? seems like an error code.
|
||||
//0x19 reset on eject(0 = enable; 1 = disable)
|
||||
|
|
Loading…
Reference in New Issue