2003-02-08 22:25:08 +00:00
// ******************************************************************
// *
// * .,-::::: .,:: .::::::::. .,:: .:
// * ,;;;'````' `;;;, .,;; ;;;'';;' `;;;, .,;;
// * [[[ '[[,,[[' [[[__[[\. '[[,,[['
// * $$$ Y$$$P $$""""Y$$ Y$$$P
// * `88bo,__,o, oP"``"Yo, _88o,,od8P oP"``"Yo,
// * "YUMMMMMP",m" "Mm,""YUMMMP" ,m" "Mm,
// *
2003-03-27 06:23:58 +00:00
// * Cxbx->Win32->CxbxKrnl->Emu.cpp
2003-02-08 22:25:08 +00:00
// *
// * This file is part of the Cxbx project.
// *
// * Cxbx and Cxbe are free software; you can redistribute them
// * and/or modify them under the terms of the GNU General Public
// * License as published by the Free Software Foundation; either
// * version 2 of the license, or (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have recieved a copy of the GNU General Public License
// * along with this program; see the file COPYING.
// * If not, write to the Free Software Foundation, Inc.,
// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA.
// *
// * (c) 2002-2003 Aaron Robinson <caustik@caustik.com>
// *
// * All rights reserved
// *
// ******************************************************************
2003-03-07 22:01:44 +00:00
# define _CXBXKRNL_INTERNAL
2003-02-08 22:25:08 +00:00
# define _XBOXKRNL_LOCAL_
2003-03-07 22:01:44 +00:00
// ******************************************************************
// * prevent name collisions
// ******************************************************************
2003-04-02 02:23:30 +00:00
namespace xboxkrnl
2003-02-08 22:25:08 +00:00
{
2003-04-02 02:23:30 +00:00
# include <xboxkrnl/xboxkrnl.h>
2003-02-08 22:25:08 +00:00
} ;
2003-04-02 02:23:30 +00:00
# include "Emu.h"
# include "EmuFS.h"
2003-05-21 03:03:05 +00:00
// ******************************************************************
// * prevent name collisions
// ******************************************************************
2003-07-02 20:14:15 +00:00
namespace XTL
2003-05-21 03:03:05 +00:00
{
2003-07-02 20:14:15 +00:00
# include "EmuXTL.h"
2003-05-23 02:55:39 +00:00
} ;
2003-05-23 22:04:21 +00:00
# include <locale.h>
2003-04-01 07:11:07 +00:00
# include "EmuShared.h"
2003-04-02 02:23:30 +00:00
# include "HLEDataBase.h"
2003-04-01 07:11:07 +00:00
2003-03-27 05:56:08 +00:00
// ******************************************************************
2003-03-27 06:33:57 +00:00
// * global / static
2003-02-08 22:25:08 +00:00
// ******************************************************************
2003-06-05 23:42:45 +00:00
Xbe : : TLS * g_pTLS = NULL ;
void * g_pTLSData = NULL ;
Xbe : : Header * g_pXbeHeader = NULL ;
HANDLE g_hCurDir = NULL ;
2003-06-25 02:01:51 +00:00
HANDLE g_hTDrive = NULL ;
HANDLE g_hUDrive = NULL ;
2003-04-26 08:57:51 +00:00
// ******************************************************************
// * static
// ******************************************************************
2003-05-04 19:55:25 +00:00
static void * EmuLocateFunction ( OOVPA * Oovpa , uint32 lower , uint32 upper ) ;
static void EmuInstallWrappers ( OOVPATable * OovpaTable , uint32 OovpaTableSize , void ( * Entry ) ( ) , Xbe : : Header * pXbeHeader ) ;
2003-07-01 23:52:07 +00:00
static void EmuXRefFailure ( ) ;
2003-05-04 19:55:25 +00:00
static int ExitException ( LPEXCEPTION_POINTERS e ) ;
2003-04-06 00:25:30 +00:00
2003-03-27 05:56:08 +00:00
// ******************************************************************
// * func: DllMain
// ******************************************************************
BOOL WINAPI DllMain ( HINSTANCE hinstDLL , DWORD fdwReason , LPVOID lpvReserved )
{
if ( fdwReason = = DLL_PROCESS_ATTACH )
2003-04-04 03:31:43 +00:00
EmuShared : : Init ( ) ;
2003-03-27 05:56:08 +00:00
if ( fdwReason = = DLL_PROCESS_DETACH )
2003-04-04 03:31:43 +00:00
EmuShared : : Cleanup ( ) ;
2003-03-27 05:56:08 +00:00
return TRUE ;
}
2003-02-08 22:25:08 +00:00
// ******************************************************************
2003-03-27 06:23:58 +00:00
// * func: EmuNoFunc
2003-02-08 22:25:08 +00:00
// ******************************************************************
2003-04-02 02:23:30 +00:00
extern " C " CXBXKRNL_API void NTAPI EmuNoFunc ( )
2003-03-27 06:23:58 +00:00
{
EmuSwapFS ( ) ; // Win2k/XP FS
2003-05-23 02:55:39 +00:00
printf ( " Emu (0x%X): EmuNoFunc() \n " , GetCurrentThreadId ( ) ) ;
2003-03-27 06:23:58 +00:00
EmuSwapFS ( ) ; // XBox FS
}
2003-04-27 04:56:09 +00:00
// ******************************************************************
// * func: EmuCleanThread
// ******************************************************************
2003-05-20 21:39:25 +00:00
extern " C " CXBXKRNL_API void NTAPI EmuCleanThread ( )
2003-04-27 04:56:09 +00:00
{
if ( EmuIsXboxFS ( ) )
EmuSwapFS ( ) ; // Win2k/XP FS
EmuCleanupFS ( ) ;
2003-05-03 08:29:37 +00:00
TerminateThread ( GetCurrentThread ( ) , 0 ) ;
2003-04-27 04:56:09 +00:00
}
2003-03-27 06:23:58 +00:00
// ******************************************************************
// * func: EmuInit
// ******************************************************************
2003-05-03 08:29:37 +00:00
extern " C " CXBXKRNL_API void NTAPI EmuInit
(
2003-05-04 19:55:25 +00:00
void * pTLSData ,
2003-05-03 08:29:37 +00:00
Xbe : : TLS * pTLS ,
Xbe : : LibraryVersion * pLibraryVersion ,
DebugMode DbgMode ,
char * szDebugFilename ,
Xbe : : Header * pXbeHeader ,
uint32 dwXbeHeaderSize ,
void ( * Entry ) ( ) )
2003-02-08 22:25:08 +00:00
{
2003-05-21 03:03:05 +00:00
g_pTLS = pTLS ;
g_pTLSData = pTLSData ;
g_pXbeHeader = pXbeHeader ;
2003-04-06 00:25:30 +00:00
2003-05-23 22:04:21 +00:00
// For Unicode Conversions
setlocale ( LC_ALL , " English " ) ;
2003-02-08 22:25:08 +00:00
// ******************************************************************
// * debug console allocation (if configured)
// ******************************************************************
2003-04-04 04:35:00 +00:00
if ( DbgMode = = DM_CONSOLE )
2003-02-08 22:25:08 +00:00
{
if ( AllocConsole ( ) )
{
freopen ( " CONOUT$ " , " wt " , stdout ) ;
2003-02-15 08:56:40 +00:00
SetConsoleTitle ( " Cxbx : Kernel Debug Console " ) ;
2003-02-09 09:11:52 +00:00
2003-02-09 09:40:37 +00:00
SetConsoleTextAttribute ( GetStdHandle ( STD_OUTPUT_HANDLE ) , FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED ) ;
2003-05-23 02:55:39 +00:00
printf ( " Emu (0x%X): Debug console allocated (DM_CONSOLE). \n " , GetCurrentThreadId ( ) ) ;
2003-02-08 22:25:08 +00:00
}
}
2003-04-04 04:35:00 +00:00
else if ( DbgMode = = DM_FILE )
2003-02-08 22:25:08 +00:00
{
FreeConsole ( ) ;
2003-04-04 04:35:00 +00:00
freopen ( szDebugFilename , " wt " , stdout ) ;
2003-02-08 22:25:08 +00:00
2003-05-23 02:55:39 +00:00
printf ( " Emu (0x%X): Debug console allocated (DM_FILE). \n " , GetCurrentThreadId ( ) ) ;
2003-02-08 22:25:08 +00:00
}
2003-04-15 08:08:53 +00:00
else
{
FreeConsole ( ) ;
2003-05-03 08:29:37 +00:00
char buffer [ 16 ] ;
if ( GetConsoleTitle ( buffer , 16 ) ! = NULL )
freopen ( " nul " , " w " , stdout ) ;
2003-04-15 08:08:53 +00:00
}
2003-02-08 22:25:08 +00:00
// ******************************************************************
// * debug trace
// ******************************************************************
{
2003-03-28 20:14:48 +00:00
# ifdef _DEBUG_TRACE
2003-05-23 02:55:39 +00:00
printf ( " Emu (0x%X): Debug Trace Enabled. \n " , GetCurrentThreadId ( ) ) ;
2003-03-28 20:14:48 +00:00
2003-05-23 02:55:39 +00:00
printf ( " Emu (0x%X): EmuInit \n "
2003-02-09 08:35:33 +00:00
" ( \n "
2003-05-04 19:55:25 +00:00
" pTLSData : 0x%.08X \n "
2003-05-03 08:29:37 +00:00
" pTLS : 0x%.08X \n "
" pLibraryVersion : 0x%.08X \n "
2003-02-09 08:35:33 +00:00
" DebugConsole : 0x%.08X \n "
" DebugFilename : \" %s \" \n "
2003-05-03 08:29:37 +00:00
" pXBEHeader : 0x%.08X \n "
" pXBEHeaderSize : 0x%.08X \n "
2003-02-09 08:35:33 +00:00
" Entry : 0x%.08X \n "
" ); \n " ,
2003-05-21 03:03:05 +00:00
GetCurrentThreadId ( ) , pTLSData , pTLS , pLibraryVersion , DbgMode , szDebugFilename , pXbeHeader , dwXbeHeaderSize , Entry ) ;
2003-03-28 20:14:48 +00:00
# else
2003-05-23 02:55:39 +00:00
printf ( " Emu (0x%X): Debug Trace Disabled. \n " , GetCurrentThreadId ( ) ) ;
2003-03-28 20:14:48 +00:00
# endif
2003-02-08 22:25:08 +00:00
}
// ******************************************************************
2003-04-08 03:34:05 +00:00
// * Load the necessary pieces of XBEHeader
2003-02-08 22:25:08 +00:00
// ******************************************************************
{
2003-04-08 03:34:05 +00:00
Xbe : : Header * MemXbeHeader = ( Xbe : : Header * ) 0x00010000 ;
uint32 old_protection = 0 ;
VirtualProtect ( MemXbeHeader , 0x1000 , PAGE_READWRITE , & old_protection ) ;
// we sure hope we aren't corrupting anything necessary for an .exe to survive :]
2003-05-03 08:29:37 +00:00
MemXbeHeader - > dwSizeofHeaders = pXbeHeader - > dwSizeofHeaders ;
MemXbeHeader - > dwCertificateAddr = pXbeHeader - > dwCertificateAddr ;
MemXbeHeader - > dwPeHeapReserve = pXbeHeader - > dwPeHeapReserve ;
MemXbeHeader - > dwPeHeapCommit = pXbeHeader - > dwPeHeapCommit ;
memcpy ( & MemXbeHeader - > dwInitFlags , & pXbeHeader - > dwInitFlags , sizeof ( pXbeHeader - > dwInitFlags ) ) ;
2003-04-08 03:34:05 +00:00
2003-05-03 08:29:37 +00:00
memcpy ( ( void * ) pXbeHeader - > dwCertificateAddr , & ( ( uint08 * ) pXbeHeader ) [ pXbeHeader - > dwCertificateAddr - 0x00010000 ] , sizeof ( Xbe : : Certificate ) ) ;
2003-04-08 03:34:05 +00:00
}
// ******************************************************************
2003-05-23 02:55:39 +00:00
// * Initialize current directory
2003-04-08 03:34:05 +00:00
// ******************************************************************
2003-05-23 02:55:39 +00:00
{
char szBuffer [ 260 ] ;
2003-04-08 03:34:05 +00:00
2003-05-23 02:55:39 +00:00
GetModuleFileName ( NULL , szBuffer , 260 ) ;
sint32 spot = - 1 ;
for ( int v = 0 ; v < 260 ; v + + )
{
if ( szBuffer [ v ] = = ' \\ ' )
spot = v ;
else if ( szBuffer [ v ] = = ' \0 ' )
break ;
}
if ( spot ! = - 1 )
szBuffer [ spot ] = ' \0 ' ;
SetCurrentDirectory ( szBuffer ) ;
2003-05-28 22:54:38 +00:00
g_hCurDir = CreateFile ( szBuffer , GENERIC_READ , FILE_SHARE_READ , NULL , OPEN_EXISTING , FILE_FLAG_BACKUP_SEMANTICS , NULL ) ;
2003-06-25 02:01:51 +00:00
if ( g_hCurDir = = INVALID_HANDLE_VALUE )
2003-05-28 22:54:38 +00:00
EmuCleanup ( " Could not map D: \\ \n " ) ;
2003-05-23 02:55:39 +00:00
}
2003-04-08 03:34:05 +00:00
2003-06-25 02:01:51 +00:00
// ******************************************************************
// * Initialize T:\ and U:\ directories
// ******************************************************************
{
char szBuffer [ 260 ] ;
# ifdef _DEBUG
GetModuleFileName ( GetModuleHandle ( " CxbxKrnl.dll " ) , szBuffer , 260 ) ;
# else
GetModuleFileName ( GetModuleHandle ( " Cxbx.dll " ) , szBuffer , 260 ) ;
# endif
sint32 spot = - 1 ;
for ( int v = 0 ; v < 260 ; v + + )
{
if ( szBuffer [ v ] = = ' \\ ' )
spot = v ;
else if ( szBuffer [ v ] = = ' \0 ' )
break ;
}
if ( spot ! = - 1 )
szBuffer [ spot ] = ' \0 ' ;
2003-07-01 00:06:34 +00:00
Xbe : : Certificate * pCertificate = ( Xbe : : Certificate * ) pXbeHeader - > dwCertificateAddr ;
2003-06-26 23:55:09 +00:00
// Create TData Directory
{
strcpy ( & szBuffer [ spot ] , " \\ TDATA " ) ;
2003-06-25 02:01:51 +00:00
2003-06-26 23:55:09 +00:00
CreateDirectory ( szBuffer , NULL ) ;
2003-06-25 02:01:51 +00:00
2003-07-01 00:06:34 +00:00
sprintf ( & szBuffer [ spot + 6 ] , " \\ %08x " , pCertificate - > dwTitleId ) ;
CreateDirectory ( szBuffer , NULL ) ;
2003-06-26 23:55:09 +00:00
g_hTDrive = CreateFile ( szBuffer , GENERIC_READ , FILE_SHARE_READ , NULL , OPEN_EXISTING , FILE_FLAG_BACKUP_SEMANTICS , NULL ) ;
2003-06-25 02:01:51 +00:00
2003-06-26 23:55:09 +00:00
if ( g_hTDrive = = INVALID_HANDLE_VALUE )
EmuCleanup ( " Could not map T: \\ \n " ) ;
}
2003-06-25 02:01:51 +00:00
2003-06-26 23:55:09 +00:00
// Create UData Directory
{
strcpy ( & szBuffer [ spot ] , " \\ UDATA " ) ;
2003-06-25 02:01:51 +00:00
2003-06-26 23:55:09 +00:00
CreateDirectory ( szBuffer , NULL ) ;
2003-06-25 02:01:51 +00:00
2003-07-01 00:06:34 +00:00
sprintf ( & szBuffer [ spot + 6 ] , " \\ %08x " , pCertificate - > dwTitleId ) ;
CreateDirectory ( szBuffer , NULL ) ;
2003-06-26 23:55:09 +00:00
g_hUDrive = CreateFile ( szBuffer , GENERIC_READ , FILE_SHARE_READ , NULL , OPEN_EXISTING , FILE_FLAG_BACKUP_SEMANTICS , NULL ) ;
2003-06-25 02:01:51 +00:00
2003-06-26 23:55:09 +00:00
if ( g_hUDrive = = INVALID_HANDLE_VALUE )
EmuCleanup ( " Could not map U: \\ \n " ) ;
}
2003-06-25 02:01:51 +00:00
}
2003-04-08 03:34:05 +00:00
// ******************************************************************
// * Initialize OpenXDK emulation
// ******************************************************************
2003-05-03 08:29:37 +00:00
if ( pLibraryVersion = = 0 )
2003-05-23 02:55:39 +00:00
printf ( " Emu (0x%X): Detected OpenXDK application... \n " , GetCurrentThreadId ( ) ) ;
2003-04-08 03:34:05 +00:00
// ******************************************************************
// * Initialize Microsoft XDK emulation
// ******************************************************************
2003-05-03 08:29:37 +00:00
if ( pLibraryVersion ! = 0 )
2003-04-08 03:34:05 +00:00
{
2003-05-23 02:55:39 +00:00
printf ( " Emu (0x%X): Detected Microsoft XDK application... \n " , GetCurrentThreadId ( ) ) ;
2003-04-08 03:34:05 +00:00
2003-05-03 08:29:37 +00:00
uint32 dwLibraryVersions = pXbeHeader - > dwLibraryVersions ;
2003-02-19 20:53:33 +00:00
uint32 dwHLEEntries = HLEDataBaseSize / sizeof ( HLEData ) ;
2003-02-15 22:48:07 +00:00
2003-07-03 21:42:52 +00:00
uint32 LastUnResolvedXRefs = UnResolvedXRefs + 1 ;
2003-07-03 05:09:28 +00:00
uint32 OrigUnResolvedXRefs = UnResolvedXRefs ;
2003-07-01 23:52:07 +00:00
2003-07-03 05:09:28 +00:00
for ( int p = 0 ; UnResolvedXRefs < LastUnResolvedXRefs ; p + + )
2003-02-19 20:53:33 +00:00
{
2003-07-03 05:09:28 +00:00
printf ( " Emu (0x%X): Beginning HLE Pass %d... \n " , GetCurrentThreadId ( ) , p ) ;
2003-07-01 23:52:07 +00:00
LastUnResolvedXRefs = UnResolvedXRefs ;
2003-02-22 07:49:02 +00:00
2003-07-01 23:52:07 +00:00
bool bFoundD3D = false ;
for ( uint32 v = 0 ; v < dwLibraryVersions ; v + + )
{
uint16 MajorVersion = pLibraryVersion [ v ] . wMajorVersion ;
uint16 MinorVersion = pLibraryVersion [ v ] . wMinorVersion ;
uint16 BuildVersion = pLibraryVersion [ v ] . wBuildVersion ;
2003-02-19 20:53:33 +00:00
2003-07-01 23:52:07 +00:00
char szLibraryName [ 9 ] = { 0 } ;
2003-02-19 20:53:33 +00:00
2003-07-01 23:52:07 +00:00
for ( uint32 c = 0 ; c < 8 ; c + + )
szLibraryName [ c ] = pLibraryVersion [ v ] . szName [ c ] ;
2003-02-19 20:53:33 +00:00
2003-07-01 23:52:07 +00:00
printf ( " Emu (0x%X): Locating HLE Information for %s %d.%d.%d... " , GetCurrentThreadId ( ) , szLibraryName , MajorVersion , MinorVersion , BuildVersion ) ;
2003-06-25 23:55:50 +00:00
2003-07-01 23:52:07 +00:00
// TODO: HACK: These libraries are packed into one database
if ( strcmp ( szLibraryName , " D3DX8 " ) = = 0 )
strcpy ( szLibraryName , " D3D8 " ) ;
2003-02-22 07:49:02 +00:00
2003-07-01 23:52:07 +00:00
if ( strcmp ( szLibraryName , " D3D8 " ) = = 0 )
{
if ( bFoundD3D )
{
printf ( " Redundant \n " ) ;
continue ;
}
2003-02-22 07:49:02 +00:00
2003-07-01 23:52:07 +00:00
bFoundD3D = true ;
}
2003-02-19 20:53:33 +00:00
2003-07-01 23:52:07 +00:00
bool found = false ;
2003-02-19 20:53:33 +00:00
2003-07-01 23:52:07 +00:00
for ( uint32 d = 0 ; d < dwHLEEntries ; d + + )
{
if ( BuildVersion ! = HLEDataBase [ d ] . BuildVersion | | MinorVersion ! = HLEDataBase [ d ] . MinorVersion | | MajorVersion ! = HLEDataBase [ d ] . MajorVersion | | strcmp ( szLibraryName , HLEDataBase [ d ] . Library ) ! = 0 )
continue ;
2003-05-04 19:55:25 +00:00
2003-07-01 23:52:07 +00:00
found = true ;
2003-05-23 02:55:39 +00:00
2003-07-01 23:52:07 +00:00
printf ( " Found \n " ) ;
2003-05-23 02:55:39 +00:00
2003-07-01 23:52:07 +00:00
EmuInstallWrappers ( HLEDataBase [ d ] . OovpaTable , HLEDataBase [ d ] . OovpaTableSize , Entry , pXbeHeader ) ;
}
2003-05-24 06:06:35 +00:00
2003-07-01 23:52:07 +00:00
if ( ! found )
printf ( " Skipped \n " ) ;
2003-06-20 16:42:31 +00:00
2003-07-03 05:09:28 +00:00
if ( bXRefFirstPass )
2003-06-13 00:37:41 +00:00
{
2003-07-03 05:09:28 +00:00
if ( strcmp ( " XAPILIB " , szLibraryName ) = = 0 & & MajorVersion = = 1 & & MinorVersion = = 0 & & ( BuildVersion = = 4627 | | BuildVersion = = 4361 | | BuildVersion = = 4034 | | BuildVersion = = 3911 ) )
2003-07-01 00:06:34 +00:00
{
2003-07-03 05:09:28 +00:00
uint32 lower = pXbeHeader - > dwBaseAddr ;
uint32 upper = pXbeHeader - > dwBaseAddr + pXbeHeader - > dwSizeofImage ;
// ******************************************************************
// * Locate XapiProcessHeap
// ******************************************************************
if ( BuildVersion = = 4361 | | BuildVersion = = 4627 )
{
void * pFunc = EmuLocateFunction ( ( OOVPA * ) & XapiInitProcess_1_0_4361 , lower , upper ) ;
if ( pFunc ! = 0 )
{
XTL : : EmuXapiProcessHeap = * ( PVOID * * ) ( ( uint32 ) pFunc + 0x3E ) ;
XTL : : g_pRtlCreateHeap = * ( XTL : : pfRtlCreateHeap * ) ( ( uint32 ) pFunc + 0x37 ) ;
XTL : : g_pRtlCreateHeap = ( XTL : : pfRtlCreateHeap ) ( ( uint32 ) pFunc + ( uint32 ) XTL : : g_pRtlCreateHeap + 0x37 + 0x04 ) ;
printf ( " Emu (0x%X): 0x%.08X -> EmuXapiProcessHeap \n " , GetCurrentThreadId ( ) , XTL : : EmuXapiProcessHeap ) ;
printf ( " Emu (0x%X): 0x%.08X -> RtlCreateHeap \n " , GetCurrentThreadId ( ) , XTL : : g_pRtlCreateHeap ) ;
}
}
2003-07-01 00:06:34 +00:00
}
2003-07-03 05:09:28 +00:00
else if ( strcmp ( " D3D8 " , szLibraryName ) = = 0 & & MajorVersion = = 1 & & MinorVersion = = 0 & & ( BuildVersion = = 4361 | | BuildVersion = = 4627 ) )
{
uint32 lower = pXbeHeader - > dwBaseAddr ;
uint32 upper = pXbeHeader - > dwBaseAddr + pXbeHeader - > dwSizeofImage ;
2003-07-01 23:52:07 +00:00
2003-07-03 05:09:28 +00:00
void * pFunc = EmuLocateFunction ( ( OOVPA * ) & IDirect3DDevice8_SetRenderState_CullMode_1_0_4361 , lower , upper ) ;
2003-07-01 23:52:07 +00:00
2003-07-03 05:09:28 +00:00
// ******************************************************************
// * Locate D3DDeferredRenderState
// ******************************************************************
if ( pFunc ! = 0 & & ( BuildVersion = = 4361 | | BuildVersion = = 4627 ) )
2003-07-01 23:52:07 +00:00
{
2003-07-03 05:09:28 +00:00
if ( BuildVersion = = 4361 )
XTL : : EmuD3DDeferredRenderState = ( DWORD * ) ( * ( DWORD * ) ( ( uint32 ) pFunc + 0x2B ) - 0x200 + 82 * 4 ) ;
else if ( BuildVersion = = 4627 )
XTL : : EmuD3DDeferredRenderState = ( DWORD * ) ( * ( DWORD * ) ( ( uint32 ) pFunc + 0x2B ) - 0x24C + 92 * 4 ) ;
2003-07-01 23:52:07 +00:00
2003-07-03 05:09:28 +00:00
for ( int v = 0 ; v < 146 ; v + + )
XTL : : EmuD3DDeferredRenderState [ v ] = X_D3DRS_UNK ;
2003-07-01 23:52:07 +00:00
2003-07-03 05:09:28 +00:00
printf ( " Emu (0x%X): 0x%.08X -> EmuD3DDeferredRenderState \n " , GetCurrentThreadId ( ) , XTL : : EmuD3DDeferredRenderState ) ;
2003-07-01 23:52:07 +00:00
}
else
{
2003-07-03 05:09:28 +00:00
XTL : : EmuD3DDeferredRenderState = 0 ;
printf ( " Emu (0x%X): *Warning* EmuD3DDeferredRenderState not found! \n " , GetCurrentThreadId ( ) ) ;
2003-07-01 23:52:07 +00:00
}
2003-07-03 05:09:28 +00:00
// ******************************************************************
// * Locate D3DDeferredTextureState
// ******************************************************************
{
if ( BuildVersion = = 4361 )
pFunc = EmuLocateFunction ( ( OOVPA * ) & IDirect3DDevice8_SetTextureState_TexCoordIndex_1_0_4361 , lower , upper ) ;
else if ( BuildVersion = = 4627 )
pFunc = EmuLocateFunction ( ( OOVPA * ) & IDirect3DDevice8_SetTextureState_TexCoordIndex_1_0_4627 , lower , upper ) ;
if ( pFunc ! = 0 )
{
XTL : : EmuD3DDeferredTextureState = ( DWORD * ) ( * ( DWORD * ) ( ( uint32 ) pFunc + 0x19 ) - 0x70 ) ;
for ( int v = 0 ; v < 32 * 4 ; v + + )
XTL : : EmuD3DDeferredTextureState [ v ] = X_D3DTSS_UNK ;
printf ( " Emu (0x%X): 0x%.08X -> EmuD3DDeferredTextureState \n " , GetCurrentThreadId ( ) , XTL : : EmuD3DDeferredTextureState ) ;
}
else
{
XTL : : EmuD3DDeferredTextureState = 0 ;
printf ( " Emu (0x%X): *Warning* EmuD3DDeferredTextureState not found! \n " , GetCurrentThreadId ( ) ) ;
}
}
}
}
2003-07-01 23:52:07 +00:00
}
bXRefFirstPass = false ;
2003-02-19 20:53:33 +00:00
}
2003-07-01 23:52:07 +00:00
// ******************************************************************
// * Display XRef Summary
// ******************************************************************
2003-07-03 05:09:28 +00:00
printf ( " Emu (0x%X): Resolved %d cross reference(s) \n " , GetCurrentThreadId ( ) , OrigUnResolvedXRefs - UnResolvedXRefs ) ;
2003-02-08 22:25:08 +00:00
}
2003-05-23 02:55:39 +00:00
// ******************************************************************
// * Initialize FS Emulation
// ******************************************************************
{
EmuInitFS ( ) ;
EmuGenerateFS ( pTLS , pTLSData ) ;
}
2003-06-28 00:26:36 +00:00
printf ( " Emu (0x%X): Initializing Direct3D. \n " , GetCurrentThreadId ( ) ) ;
2003-07-02 20:14:15 +00:00
XTL : : EmuD3DInit ( pXbeHeader , dwXbeHeaderSize ) ;
2003-06-28 00:26:36 +00:00
2003-05-23 02:55:39 +00:00
printf ( " Emu (0x%X): Initial thread starting. \n " , GetCurrentThreadId ( ) ) ;
2003-04-08 03:34:05 +00:00
2003-02-08 22:25:08 +00:00
// ******************************************************************
2003-04-08 03:34:05 +00:00
// * Entry Point
2003-02-08 22:25:08 +00:00
// ******************************************************************
2003-04-08 03:34:05 +00:00
__try
2003-02-08 22:25:08 +00:00
{
2003-04-08 03:34:05 +00:00
EmuSwapFS ( ) ; // XBox FS
2003-02-08 22:25:08 +00:00
2003-06-18 05:15:02 +00:00
// _USE_XGMATH Disabled in mesh :[
2003-07-03 21:42:52 +00:00
//_asm int 3
2003-06-16 16:43:50 +00:00
2003-05-30 02:08:25 +00:00
Entry ( ) ;
2003-02-08 22:25:08 +00:00
2003-04-08 03:34:05 +00:00
EmuSwapFS ( ) ; // Win2k/XP FS
2003-02-08 22:25:08 +00:00
}
2003-04-08 03:34:05 +00:00
__except ( EmuException ( GetExceptionInformation ( ) ) )
2003-02-08 22:25:08 +00:00
{
2003-04-08 03:34:05 +00:00
printf ( " Emu: WARNING!! Problem with ExceptionFilter \n " ) ;
2003-02-15 22:16:14 +00:00
}
2003-05-23 02:55:39 +00:00
printf ( " Emu (0x%X): Initial thread ended. \n " , GetCurrentThreadId ( ) ) ;
2003-02-08 22:25:08 +00:00
fflush ( stdout ) ;
2003-04-27 04:56:09 +00:00
EmuCleanThread ( ) ;
2003-04-26 07:30:21 +00:00
2003-04-27 04:56:09 +00:00
return ;
2003-04-26 07:30:21 +00:00
}
2003-04-16 19:06:20 +00:00
// ******************************************************************
// * func: EmuCleanup
// ******************************************************************
2003-06-10 08:18:43 +00:00
extern " C " CXBXKRNL_API void NTAPI EmuCleanup ( const char * szErrorMessage , . . . )
2003-04-16 19:06:20 +00:00
{
2003-04-26 08:57:51 +00:00
// ******************************************************************
// * Print out ErrorMessage (if exists)
// ******************************************************************
if ( szErrorMessage ! = NULL )
{
2003-06-10 08:18:43 +00:00
char szBuffer1 [ 255 ] ;
char szBuffer2 [ 255 ] ;
2003-04-26 08:57:51 +00:00
2003-06-10 08:18:43 +00:00
va_list argp ;
2003-04-26 08:57:51 +00:00
2003-06-10 08:18:43 +00:00
sprintf ( szBuffer1 , " Emu (0x%X): Recieved Fatal Message -> \n \n " , GetCurrentThreadId ( ) ) ;
2003-04-26 08:57:51 +00:00
2003-06-10 08:18:43 +00:00
va_start ( argp , szErrorMessage ) ;
vsprintf ( szBuffer2 , szErrorMessage , argp ) ;
va_end ( argp ) ;
strcat ( szBuffer1 , szBuffer2 ) ;
2003-06-28 00:26:36 +00:00
printf ( " %s \n " , szBuffer1 ) ;
2003-06-10 08:18:43 +00:00
MessageBox ( NULL , szBuffer1 , " CxbxKrnl " , MB_OK | MB_ICONEXCLAMATION ) ;
2003-04-26 08:57:51 +00:00
}
2003-05-02 05:43:21 +00:00
printf ( " CxbxKrnl: Terminating Process \n " ) ;
fflush ( stdout ) ;
2003-05-02 02:42:29 +00:00
// ******************************************************************
// * Cleanup debug output
// ******************************************************************
{
FreeConsole ( ) ;
2003-05-03 08:29:37 +00:00
char buffer [ 16 ] ;
2003-05-02 02:42:29 +00:00
2003-05-03 08:29:37 +00:00
if ( GetConsoleTitle ( buffer , 16 ) ! = NULL )
freopen ( " nul " , " w " , stdout ) ;
2003-04-27 23:08:42 +00:00
}
2003-04-16 19:06:20 +00:00
2003-05-03 08:29:37 +00:00
TerminateProcess ( GetCurrentProcess ( ) , 0 ) ;
2003-04-16 19:06:20 +00:00
return ;
}
2003-02-08 22:25:08 +00:00
// ******************************************************************
2003-03-27 06:23:58 +00:00
// * func: EmuPanic
2003-02-08 22:25:08 +00:00
// ******************************************************************
2003-04-02 02:23:30 +00:00
extern " C " CXBXKRNL_API void NTAPI EmuPanic ( )
2003-02-08 22:25:08 +00:00
{
2003-04-12 11:21:35 +00:00
if ( EmuIsXboxFS ( ) )
EmuSwapFS ( ) ; // Win2k/XP FS
2003-02-08 22:25:08 +00:00
2003-05-23 02:55:39 +00:00
printf ( " Emu (0x%X): EmuPanic() \n " , GetCurrentThreadId ( ) ) ;
2003-02-08 22:25:08 +00:00
2003-04-26 04:32:46 +00:00
EmuCleanup ( " Kernel Panic! " ) ;
2003-04-12 11:21:35 +00:00
2003-03-27 06:23:58 +00:00
EmuSwapFS ( ) ; // XBox FS
2003-02-08 22:25:08 +00:00
}
2003-02-09 08:35:33 +00:00
// ******************************************************************
2003-03-27 06:23:58 +00:00
// * func: EmuInstallWrapper
2003-02-09 08:35:33 +00:00
// ******************************************************************
2003-03-27 06:23:58 +00:00
inline void EmuInstallWrapper ( void * FunctionAddr , void * WrapperAddr )
2003-02-09 08:35:33 +00:00
{
uint08 * FuncBytes = ( uint08 * ) FunctionAddr ;
* ( uint08 * ) & FuncBytes [ 0 ] = 0xE9 ;
* ( uint32 * ) & FuncBytes [ 1 ] = ( uint32 ) WrapperAddr - ( uint32 ) FunctionAddr - 5 ;
}
2003-02-08 22:25:08 +00:00
// ******************************************************************
2003-05-04 19:55:25 +00:00
// * func: EmuLocateFunction
2003-02-08 22:25:08 +00:00
// ******************************************************************
2003-05-04 19:55:25 +00:00
void * EmuLocateFunction ( OOVPA * Oovpa , uint32 lower , uint32 upper )
2003-02-08 22:25:08 +00:00
{
2003-05-04 19:55:25 +00:00
uint32 count = Oovpa - > Count ;
2003-07-01 23:52:07 +00:00
// Skip out if this is an unnecessary search
if ( ! bXRefFirstPass & & Oovpa - > XRefCount = = 0 & & Oovpa - > XRefSaveIndex = = ( uint08 ) - 1 )
return 0 ;
2003-02-08 22:25:08 +00:00
// ******************************************************************
2003-05-04 19:55:25 +00:00
// * Large
2003-02-08 22:25:08 +00:00
// ******************************************************************
2003-05-04 19:55:25 +00:00
if ( Oovpa - > Large = = 1 )
2003-02-08 22:25:08 +00:00
{
2003-05-04 19:55:25 +00:00
LOOVPA < 1 > * Loovpa = ( LOOVPA < 1 > * ) Oovpa ;
2003-02-21 04:51:03 +00:00
2003-05-04 19:55:25 +00:00
upper - = Loovpa - > Lovp [ count - 1 ] . Offset ;
2003-02-09 08:35:33 +00:00
2003-02-15 22:16:14 +00:00
// ******************************************************************
2003-05-04 19:55:25 +00:00
// * Search all of the image memory
2003-02-15 22:16:14 +00:00
// ******************************************************************
2003-05-04 19:55:25 +00:00
for ( uint32 cur = lower ; cur < upper ; cur + + )
2003-02-15 22:16:14 +00:00
{
2003-07-01 23:52:07 +00:00
uint32 v ;
// ******************************************************************
// * check all cross references
// ******************************************************************
for ( v = 0 ; v < Loovpa - > XRefCount ; v + + )
{
uint32 Offset = Loovpa - > Lovp [ v ] . Offset ;
uint32 Value = Loovpa - > Lovp [ v ] . Value ;
uint32 RealValue = * ( uint32 * ) ( cur + Offset ) ;
if ( XRefDataBase [ Value ] = = - 1 )
2003-07-03 05:09:28 +00:00
goto skipout_L ; // Unsatisfied XRef is not acceptable
2003-07-01 23:52:07 +00:00
if ( RealValue + cur + Offset + 4 ! = XRefDataBase [ Value ] )
break ;
}
2003-02-22 07:49:02 +00:00
2003-02-20 08:07:52 +00:00
// ******************************************************************
2003-05-04 19:55:25 +00:00
// * check all pairs, moving on if any do not match
2003-02-20 08:07:52 +00:00
// ******************************************************************
2003-05-04 19:55:25 +00:00
for ( v = 0 ; v < count ; v + + )
2003-02-20 08:07:52 +00:00
{
2003-05-04 19:55:25 +00:00
uint32 Offset = Loovpa - > Lovp [ v ] . Offset ;
uint32 Value = Loovpa - > Lovp [ v ] . Value ;
2003-02-20 08:07:52 +00:00
2003-05-04 19:55:25 +00:00
uint08 RealValue = * ( uint08 * ) ( cur + Offset ) ;
2003-02-22 07:49:02 +00:00
2003-05-04 19:55:25 +00:00
if ( RealValue ! = Value )
2003-02-20 08:07:52 +00:00
break ;
2003-02-22 07:49:02 +00:00
}
2003-02-21 04:51:03 +00:00
2003-02-22 07:49:02 +00:00
// ******************************************************************
2003-05-04 19:55:25 +00:00
// * success if we found all pairs
2003-02-22 07:49:02 +00:00
// ******************************************************************
2003-05-04 19:55:25 +00:00
if ( v = = count )
2003-07-01 23:52:07 +00:00
{
2003-07-03 05:09:28 +00:00
if ( Loovpa - > XRefSaveIndex ! = ( uint08 ) - 1 )
2003-07-01 23:52:07 +00:00
{
2003-07-03 05:09:28 +00:00
if ( XRefDataBase [ Loovpa - > XRefSaveIndex ] = = - 1 )
{
UnResolvedXRefs - - ;
XRefDataBase [ Loovpa - > XRefSaveIndex ] = cur ;
return ( void * ) cur ;
}
else
return 0 ; // Already Found, no bother patching again
2003-07-01 23:52:07 +00:00
}
2003-05-04 19:55:25 +00:00
return ( void * ) cur ;
2003-07-01 23:52:07 +00:00
}
2003-07-03 05:09:28 +00:00
skipout_L : ;
2003-02-15 22:16:14 +00:00
}
2003-05-04 19:55:25 +00:00
}
// ******************************************************************
// * Small
// ******************************************************************
else
{
SOOVPA < 1 > * Soovpa = ( SOOVPA < 1 > * ) Oovpa ;
upper - = Soovpa - > Sovp [ count - 1 ] . Offset ;
2003-02-15 22:16:14 +00:00
// ******************************************************************
2003-05-04 19:55:25 +00:00
// * Search all of the image memory
2003-02-15 22:16:14 +00:00
// ******************************************************************
2003-05-04 19:55:25 +00:00
for ( uint32 cur = lower ; cur < upper ; cur + + )
2003-02-09 08:35:33 +00:00
{
2003-07-01 23:52:07 +00:00
uint32 v ;
// ******************************************************************
// * check all cross references
// ******************************************************************
for ( v = 0 ; v < Soovpa - > XRefCount ; v + + )
{
uint32 Offset = Soovpa - > Sovp [ v ] . Offset ;
uint32 Value = Soovpa - > Sovp [ v ] . Value ;
uint32 RealValue = * ( uint32 * ) ( cur + Offset ) ;
if ( XRefDataBase [ Value ] = = - 1 )
2003-07-03 05:09:28 +00:00
goto skipout_S ; // Unsatisfied XRef is not acceptable
2003-07-01 23:52:07 +00:00
2003-07-03 05:09:28 +00:00
if ( ( RealValue + cur + Offset + 4 ! = XRefDataBase [ Value ] ) )
2003-07-01 23:52:07 +00:00
break ;
}
2003-02-22 07:49:02 +00:00
2003-02-15 22:16:14 +00:00
// ******************************************************************
2003-05-04 19:55:25 +00:00
// * check all pairs, moving on if any do not match
2003-02-15 22:16:14 +00:00
// ******************************************************************
2003-07-01 23:52:07 +00:00
for ( ; v < count ; v + + )
2003-02-15 06:54:56 +00:00
{
2003-05-04 19:55:25 +00:00
uint32 Offset = Soovpa - > Sovp [ v ] . Offset ;
uint32 Value = Soovpa - > Sovp [ v ] . Value ;
2003-02-08 22:25:08 +00:00
2003-05-04 19:55:25 +00:00
uint08 RealValue = * ( uint08 * ) ( cur + Offset ) ;
2003-02-15 04:48:21 +00:00
2003-05-04 19:55:25 +00:00
if ( RealValue ! = Value )
break ;
}
2003-02-15 04:48:21 +00:00
2003-05-04 19:55:25 +00:00
// ******************************************************************
// * success if we found all pairs
// ******************************************************************
if ( v = = count )
2003-07-01 23:52:07 +00:00
{
if ( Soovpa - > XRefSaveIndex ! = ( uint08 ) - 1 )
{
2003-07-03 05:09:28 +00:00
if ( XRefDataBase [ Soovpa - > XRefSaveIndex ] = = - 1 )
{
UnResolvedXRefs - - ;
XRefDataBase [ Soovpa - > XRefSaveIndex ] = cur ;
return ( void * ) cur ;
}
else
return 0 ; // Already Found, no bother patching again
2003-07-01 23:52:07 +00:00
}
2003-05-04 19:55:25 +00:00
return ( void * ) cur ;
2003-07-01 23:52:07 +00:00
}
2003-07-03 05:09:28 +00:00
skipout_S : ;
2003-05-04 19:55:25 +00:00
}
}
2003-02-15 04:48:21 +00:00
2003-05-04 19:55:25 +00:00
return 0 ;
}
2003-02-15 04:48:21 +00:00
2003-05-04 19:55:25 +00:00
// ******************************************************************
// * func: EmuInstallWrappers
// ******************************************************************
void EmuInstallWrappers ( OOVPATable * OovpaTable , uint32 OovpaTableSize , void ( * Entry ) ( ) , Xbe : : Header * pXbeHeader )
{
uint32 lower = pXbeHeader - > dwBaseAddr ;
uint32 upper = pXbeHeader - > dwBaseAddr + pXbeHeader - > dwSizeofImage ;
2003-02-15 04:55:31 +00:00
2003-05-04 19:55:25 +00:00
// ******************************************************************
// * traverse the full OOVPA table
// ******************************************************************
for ( uint32 a = 0 ; a < OovpaTableSize / sizeof ( OOVPATable ) ; a + + )
{
OOVPA * Oovpa = OovpaTable [ a ] . Oovpa ;
2003-02-21 04:51:03 +00:00
2003-05-04 19:55:25 +00:00
void * pFunc = EmuLocateFunction ( Oovpa , lower , upper ) ;
if ( pFunc ! = 0 )
{
# ifdef _DEBUG_TRACE
2003-05-23 02:55:39 +00:00
printf ( " Emu (0x%X): 0x%.08X -> %s \n " , GetCurrentThreadId ( ) , pFunc , OovpaTable [ a ] . szFuncName ) ;
2003-05-04 19:55:25 +00:00
# endif
2003-07-01 23:52:07 +00:00
if ( OovpaTable [ a ] . lpRedirect = = 0 )
EmuInstallWrapper ( pFunc , EmuXRefFailure ) ;
else
EmuInstallWrapper ( pFunc , OovpaTable [ a ] . lpRedirect ) ;
2003-05-04 19:55:25 +00:00
}
2003-02-08 22:25:08 +00:00
}
2003-04-08 03:34:05 +00:00
}
2003-02-15 22:16:14 +00:00
2003-07-01 23:52:07 +00:00
// ******************************************************************
// * func: EmuXRefFailure
// ******************************************************************
void EmuXRefFailure ( )
{
EmuSwapFS ( ) ; // Win2k/XP FS
EmuCleanup ( " XRef-only function body reached. Fatal Error. " ) ;
}
2003-04-08 03:34:05 +00:00
// ******************************************************************
// * func: EmuException
2003-04-25 23:49:58 +00:00
// ******************************************************************
2003-04-08 03:34:05 +00:00
int EmuException ( LPEXCEPTION_POINTERS e )
{
2003-06-26 23:55:09 +00:00
if ( EmuIsXboxFS ( ) )
EmuSwapFS ( ) ;
2003-05-30 02:08:25 +00:00
// ******************************************************************
2003-04-25 23:49:58 +00:00
// * Debugging Information
// ******************************************************************
{
2003-05-23 02:55:39 +00:00
printf ( " Emu (0x%X): * * * * * EXCEPTION * * * * * \n " , GetCurrentThreadId ( ) ) ;
2003-06-13 00:37:41 +00:00
printf ( " Emu (0x%X): Recieved Exception [0x%.08X]@0x%.08X \n " , GetCurrentThreadId ( ) , e - > ExceptionRecord - > ExceptionCode , e - > ContextRecord - > Eip ) ;
2003-05-23 02:55:39 +00:00
printf ( " Emu (0x%X): * * * * * EXCEPTION * * * * * \n " , GetCurrentThreadId ( ) ) ;
2003-04-25 23:49:58 +00:00
}
2003-06-19 05:37:16 +00:00
fflush ( stdout ) ;
2003-04-25 23:49:58 +00:00
// ******************************************************************
// * Notify User
// ******************************************************************
{
char buffer [ 256 ] ;
2003-06-13 00:37:41 +00:00
sprintf ( buffer , " Recieved Exception [0x%.08X]@0x%.08X \n \n Press 'OK' to terminate emulation. \n Press 'Cancel' to debug. " , e - > ExceptionRecord - > ExceptionCode , e - > ContextRecord - > Eip ) ;
2003-04-25 23:49:58 +00:00
2003-07-02 20:14:15 +00:00
if ( MessageBox ( XTL : : g_hEmuWindow , buffer , " Cxbx " , MB_ICONSTOP | MB_OKCANCEL ) = = IDOK )
2003-04-25 23:49:58 +00:00
ExitProcess ( 1 ) ;
2003-04-25 16:55:24 +00:00
}
2003-04-08 03:34:05 +00:00
return EXCEPTION_CONTINUE_SEARCH ;
}
2003-04-27 23:08:42 +00:00
// ******************************************************************
// * func: ExitException
// ******************************************************************
int ExitException ( LPEXCEPTION_POINTERS e )
{
2003-06-26 23:55:09 +00:00
if ( EmuIsXboxFS ( ) )
EmuSwapFS ( ) ;
2003-04-27 23:08:42 +00:00
static int count = 0 ;
// ******************************************************************
// * Debugging Information
// ******************************************************************
{
2003-05-23 02:55:39 +00:00
printf ( " Emu (0x%X): * * * * * EXCEPTION * * * * * \n " , GetCurrentThreadId ( ) ) ;
2003-06-13 00:37:41 +00:00
printf ( " Emu (0x%X): Recieved Exception [0x%.08X]@0x%.08X \n " , GetCurrentThreadId ( ) , e - > ExceptionRecord - > ExceptionCode , e - > ContextRecord - > Eip ) ;
2003-05-23 02:55:39 +00:00
printf ( " Emu (0x%X): * * * * * EXCEPTION * * * * * \n " , GetCurrentThreadId ( ) ) ;
2003-04-27 23:08:42 +00:00
}
2003-06-19 05:37:16 +00:00
fflush ( stdout ) ;
2003-07-02 20:14:15 +00:00
MessageBox ( XTL : : g_hEmuWindow , " Warning: Could not safely terminate process! " , " Cxbx " , MB_OK ) ;
2003-04-29 03:30:58 +00:00
2003-04-27 23:08:42 +00:00
count + + ;
if ( count > 1 )
{
2003-07-02 20:14:15 +00:00
MessageBox ( XTL : : g_hEmuWindow , " Warning: Multiple Problems! " , " Cxbx " , MB_OK ) ;
2003-04-27 23:08:42 +00:00
return EXCEPTION_CONTINUE_SEARCH ;
}
ExitProcess ( 1 ) ;
return EXCEPTION_CONTINUE_SEARCH ;
}