This commit is contained in:
x1nixmzeng 2018-01-21 13:57:55 +00:00
commit 547d6b04b9
21 changed files with 590 additions and 230 deletions

View File

@ -163,6 +163,7 @@ BEGIN
MENUITEM SEPARATOR
MENUITEM "&About", ID_HELP_ABOUT
END
MENUITEM "LED", ID_LED
END

View File

@ -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");

View File

@ -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;

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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++)

View File

@ -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

View File

@ -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)
// ******************************************************************

View File

@ -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)

View File

@ -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;
}

View File

@ -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?

View File

@ -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;
}
}

View File

@ -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));
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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];
};
// ******************************************************************

View File

@ -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,

View File

@ -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);

View File

@ -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();
}

View File

@ -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)