Merge pull request #50 from x1nixmzeng/remove-exe-support
Removed all EXE support
This commit is contained in:
commit
ece663f6fe
|
@ -163,7 +163,6 @@
|
|||
<ClInclude Include="..\..\src\CxbxKrnl\EmuD3D8Types.h" />
|
||||
<ClInclude Include="..\..\src\CxbxKrnl\EmuDInput.h" />
|
||||
<ClInclude Include="..\..\src\CxbxKrnl\EmuDSound.h" />
|
||||
<ClInclude Include="..\..\src\Cxbx\EmuExe.h" />
|
||||
<ClInclude Include="..\..\src\CxbxKrnl\EmuShared.h" />
|
||||
<ClInclude Include="..\..\src\CxbxKrnl\EmuXapi.h" />
|
||||
<ClInclude Include="..\..\src\CxbxKrnl\EmuXG.h" />
|
||||
|
@ -177,6 +176,7 @@
|
|||
<ClInclude Include="..\..\src\CxbxKrnl\EmuD3D8\State.h" />
|
||||
<ClInclude Include="..\..\src\CxbxKrnl\EmuD3D8\VertexBuffer.h" />
|
||||
<ClInclude Include="..\..\src\CxbxKrnl\EmuD3D8\VertexShader.h" />
|
||||
<ClInclude Include="..\..\src\Cxbx\ResCxbx.h" />
|
||||
<ClInclude Include="..\..\src\Cxbx\Wnd.h" />
|
||||
<ClInclude Include="..\..\src\Cxbx\WndAbout.h" />
|
||||
<ClInclude Include="..\..\src\Cxbx\WndMain.h" />
|
||||
|
@ -215,12 +215,6 @@
|
|||
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\Cxbx\EmuExe.cpp">
|
||||
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\Common\Error.cpp">
|
||||
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
|
|
Binary file not shown.
|
@ -9,21 +9,15 @@
|
|||
//
|
||||
#include "WinResrc.h"
|
||||
|
||||
#ifndef IDC_STATIC
|
||||
#define IDC_STATIC -1
|
||||
#endif // IDC_STATIC
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// English (U.S.) resources
|
||||
// English (United States) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
#pragma code_page(1252)
|
||||
#endif //_WIN32
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
@ -53,7 +47,6 @@ END
|
|||
|
||||
3 TEXTINCLUDE
|
||||
BEGIN
|
||||
"\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
|
@ -72,15 +65,12 @@ IDB_LOGO BITMAP "Logo.bmp"
|
|||
// Menu
|
||||
//
|
||||
|
||||
IDR_MAINMENU MENU
|
||||
IDR_MAINMENU MENU
|
||||
BEGIN
|
||||
POPUP "&File"
|
||||
BEGIN
|
||||
MENUITEM "&Open Xbe...", ID_FILE_OPEN_XBE
|
||||
MENUITEM "&Close xbe", ID_FILE_CLOSE_XBE, GRAYED
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "&Import Exe...", ID_FILE_IMPORTFROMEXE
|
||||
MENUITEM "&Export Exe...", ID_FILE_EXPORTTOEXE, GRAYED
|
||||
MENUITEM "&Close Xbe", ID_FILE_CLOSE_XBE, GRAYED
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "&Save Xbe", ID_FILE_SAVEXBEFILE, GRAYED
|
||||
MENUITEM "Save Xbe &As...", ID_FILE_SAVEXBEFILEAS, GRAYED
|
||||
|
@ -98,19 +88,6 @@ BEGIN
|
|||
MENUITEM "&8 : Recent Placeholder", ID_FILE_RXBE_8
|
||||
MENUITEM "&9 : Recent Placeholder", ID_FILE_RXBE_9
|
||||
END
|
||||
POPUP "Recent Exe &Files"
|
||||
BEGIN
|
||||
MENUITEM "&0 : Recent Placeholder", ID_FILE_REXE_0
|
||||
MENUITEM "&1 : Recent Placeholder", ID_FILE_REXE_1
|
||||
MENUITEM "&2 : Recent Placeholder", ID_FILE_REXE_2
|
||||
MENUITEM "&3 : Recent Placeholder", ID_FILE_REXE_3
|
||||
MENUITEM "&4 : Recent Placeholder", ID_FILE_REXE_4
|
||||
MENUITEM "&5 : Recent Placeholder", ID_FILE_REXE_5
|
||||
MENUITEM "&6 : Recent Placeholder", ID_FILE_REXE_6
|
||||
MENUITEM "&7 : Recent Placeholder", ID_FILE_REXE_7
|
||||
MENUITEM "&8 : Recent Placeholder", ID_FILE_REXE_8
|
||||
MENUITEM "&9 : Recent Placeholder", ID_FILE_REXE_9
|
||||
END
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "E&xit", ID_FILE_EXIT
|
||||
END
|
||||
|
@ -151,13 +128,6 @@ BEGIN
|
|||
MENUITEM "Config &Controller...", ID_SETTINGS_CONFIG_CONTROLLER
|
||||
MENUITEM "Config &Audio...", ID_SETTINGS_CONFIGURESOUND, GRAYED
|
||||
MENUITEM "Config &Video...", ID_SETTINGS_CONFIG_VIDEO
|
||||
MENUITEM SEPARATOR
|
||||
POPUP "Executable &Generation"
|
||||
BEGIN
|
||||
MENUITEM "&Automatic (&Windows Temp)", ID_SETTINGS_GENWT
|
||||
MENUITEM "Automatic (&Xbe Path)", ID_SETTINGS_GENXP
|
||||
MENUITEM "&Manual", ID_SETTINGS_GENMA
|
||||
END
|
||||
END
|
||||
POPUP "E&mulation"
|
||||
BEGIN
|
||||
|
@ -179,7 +149,7 @@ END
|
|||
//
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
GUIDELINES DESIGNINFO
|
||||
GUIDELINES DESIGNINFO
|
||||
BEGIN
|
||||
IDD_CONTROLLER_CFG, DIALOG
|
||||
BEGIN
|
||||
|
@ -273,18 +243,7 @@ END
|
|||
|
||||
IDR_JPEG_ABOUT JPEG "About.jpg"
|
||||
IDR_JPEG_SPLASH JPEG "Splash.jpg"
|
||||
#endif // English (U.S.) resources
|
||||
#endif // English (United States) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
||||
|
|
|
@ -32,7 +32,6 @@
|
|||
// *
|
||||
// ******************************************************************
|
||||
#include "Xbe.h"
|
||||
#include "Exe.h"
|
||||
#include "CxbxUtil.h"
|
||||
|
||||
#include <memory.h>
|
||||
|
@ -322,500 +321,6 @@ cleanup:
|
|||
return;
|
||||
}
|
||||
|
||||
// construct via Exe file object
|
||||
Xbe::Xbe(class Exe *x_Exe, const char *x_szTitle, bool x_bRetail)
|
||||
{
|
||||
ConstructorInit();
|
||||
|
||||
time_t CurrentTime;
|
||||
|
||||
time(&CurrentTime);
|
||||
|
||||
printf("Xbe::Xbe: Pass 1 (Simple Pass)...");
|
||||
|
||||
// pass 1
|
||||
{
|
||||
// standard Xbe magic number
|
||||
m_Header.dwMagic = *(uint32*)"XBEH";
|
||||
|
||||
// nobody has the private key yet, so zero this out
|
||||
memset(m_Header.pbDigitalSignature, 0, 256);
|
||||
|
||||
// we'll only allow 0x00010000 for now
|
||||
m_Header.dwBaseAddr = 0x00010000;
|
||||
|
||||
// this is a constant value
|
||||
m_Header.dwSizeofImageHeader = sizeof(m_Header);
|
||||
|
||||
// we'll have the same number of sections as the Exe
|
||||
m_Header.dwSections = x_Exe->m_Header.m_sections;
|
||||
|
||||
// TODO: allow configuration
|
||||
{
|
||||
memset(&m_Header.dwInitFlags, 0, sizeof(m_Header.dwInitFlags));
|
||||
|
||||
m_Header.dwInitFlags.bLimit64MB = 1;
|
||||
m_Header.dwInitFlags.bDontSetupHarddisk = 0;
|
||||
m_Header.dwInitFlags.bMountUtilityDrive = 1;
|
||||
}
|
||||
|
||||
// various PE copies
|
||||
{
|
||||
m_Header.dwPeStackCommit = 0x00010000; //x_Exe->m_OptionalHeader.m_sizeof_stack_commit;
|
||||
m_Header.dwPeHeapReserve = x_Exe->m_OptionalHeader.m_sizeof_heap_reserve;
|
||||
m_Header.dwPeHeapCommit = x_Exe->m_OptionalHeader.m_sizeof_heap_commit;
|
||||
m_Header.dwPeSizeofImage = x_Exe->m_OptionalHeader.m_sizeof_image;
|
||||
m_Header.dwPeChecksum = 0x00000000;
|
||||
m_Header.dwPeTimeDate = x_Exe->m_Header.m_timedate;
|
||||
}
|
||||
|
||||
// build time/date
|
||||
m_Header.dwTimeDate = (uint32)CurrentTime;
|
||||
|
||||
// TODO: generate valid addr if necessary
|
||||
m_Header.dwNonKernelImportDirAddr = 0;
|
||||
|
||||
// TODO: generate these values
|
||||
m_Header.dwLibraryVersions = 0;
|
||||
m_Header.dwLibraryVersionsAddr = 0;
|
||||
m_Header.dwKernelLibraryVersionAddr = 0;
|
||||
m_Header.dwXAPILibraryVersionAddr = 0;
|
||||
}
|
||||
|
||||
printf("OK\n");
|
||||
|
||||
printf("Xbe::Xbe: Pass 2 (Calculating Requirements)...");
|
||||
|
||||
// pass 2
|
||||
{
|
||||
// make-room cursor
|
||||
uint32 mrc = m_Header.dwBaseAddr + sizeof(m_Header);
|
||||
|
||||
// make room for certificate
|
||||
{
|
||||
m_Header.dwCertificateAddr = mrc;
|
||||
|
||||
mrc += sizeof(m_Certificate);
|
||||
}
|
||||
|
||||
// make room for section headers
|
||||
{
|
||||
m_Header.dwSectionHeadersAddr = mrc;
|
||||
|
||||
mrc += m_Header.dwSections * (sizeof(*m_SectionHeader));
|
||||
|
||||
// make room for head/tail reference count words
|
||||
mrc += (m_Header.dwSections+1)*2;
|
||||
|
||||
// make room for section names
|
||||
for(uint32 v=0;v<m_Header.dwSections;v++)
|
||||
{
|
||||
uint32 s = 0;
|
||||
|
||||
while(s < 8 && x_Exe->m_SectionHeader[v].m_name[s] != '\0')
|
||||
s++;
|
||||
|
||||
mrc += s + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: make room for library versions
|
||||
{
|
||||
}
|
||||
|
||||
// make room for debug path / debug file names
|
||||
{
|
||||
// TODO: allow this to be configured, right now we will just null out these values
|
||||
m_Header.dwDebugUnicodeFilenameAddr = mrc;
|
||||
m_Header.dwDebugPathnameAddr = mrc;
|
||||
m_Header.dwDebugFilenameAddr = mrc;
|
||||
|
||||
mrc += 2;
|
||||
}
|
||||
|
||||
// make room for largest possible logo bitmap
|
||||
{
|
||||
mrc = RoundUp(mrc, 0x10);
|
||||
|
||||
m_Header.dwLogoBitmapAddr = mrc;
|
||||
m_Header.dwSizeofLogoBitmap = 100*17; // Max Possible
|
||||
|
||||
mrc += m_Header.dwSizeofLogoBitmap;
|
||||
}
|
||||
|
||||
// update size of headers
|
||||
m_Header.dwSizeofHeaders = mrc - m_Header.dwBaseAddr;
|
||||
}
|
||||
|
||||
printf("OK\n");
|
||||
|
||||
printf("Xbe::Xbe: Pass 3 (Generating Xbe)...\n");
|
||||
|
||||
// pass 3
|
||||
{
|
||||
m_Header.dwPeBaseAddr = m_Header.dwBaseAddr + RoundUp(m_Header.dwSizeofHeaders, 0x1000) - x_Exe->m_SectionHeader[0].m_virtual_addr;
|
||||
|
||||
// encode entry point
|
||||
{
|
||||
printf("Xbe::Xbe: Encoding %s Entry Point...", x_bRetail?"Retail":"Debug");
|
||||
|
||||
uint32 ep = x_Exe->m_OptionalHeader.m_entry + m_Header.dwPeBaseAddr;
|
||||
|
||||
if(x_bRetail)
|
||||
ep ^= XOR_EP_RETAIL;
|
||||
else
|
||||
ep ^= XOR_EP_DEBUG;
|
||||
|
||||
m_Header.dwEntryAddr = ep;
|
||||
|
||||
printf("OK (0x%.08X)\n", ep);
|
||||
}
|
||||
|
||||
// header write cursor
|
||||
uint32 hwc = m_Header.dwBaseAddr + sizeof(m_Header);
|
||||
|
||||
// check if we need to store extra header bytes (we always will)
|
||||
if(m_Header.dwSizeofHeaders > sizeof(m_Header))
|
||||
{
|
||||
printf("Xbe::Xbe: Found Extra Header Bytes...");
|
||||
|
||||
uint32 ExSize = RoundUp(m_Header.dwSizeofHeaders - sizeof(m_Header), 0x1000);
|
||||
|
||||
m_HeaderEx = new char[ExSize];
|
||||
|
||||
printf("OK\n");
|
||||
}
|
||||
|
||||
// start a write buffer inside of m_HeaderEx
|
||||
char *szBuffer = m_HeaderEx;
|
||||
|
||||
// write certificate
|
||||
{
|
||||
// certificate size is a constant
|
||||
m_Certificate.dwSize = sizeof(m_Certificate);
|
||||
|
||||
m_Certificate.dwTimeDate = (uint32)CurrentTime;
|
||||
|
||||
// TODO: generate in the form CX-9999
|
||||
m_Certificate.dwTitleId = 0xFFFF0002;
|
||||
|
||||
// title name
|
||||
memset(m_Certificate.wszTitleName, 0, 40 * sizeof(wchar_t));
|
||||
mbstowcs(m_Certificate.wszTitleName, x_szTitle, 40);
|
||||
|
||||
// zero out alternate ids
|
||||
{
|
||||
for(uint32 c=0;c<0x10;c++)
|
||||
m_Certificate.dwAlternateTitleId[c] = 0;
|
||||
}
|
||||
|
||||
// for now we'll just allow any media you could want
|
||||
m_Certificate.dwAllowedMedia = XBEIMAGE_MEDIA_TYPE_HARD_DISK | XBEIMAGE_MEDIA_TYPE_DVD_CD | XBEIMAGE_MEDIA_TYPE_MEDIA_BOARD;
|
||||
|
||||
// TODO: allow configuration
|
||||
m_Certificate.dwGameRegion = XBEIMAGE_GAME_REGION_MANUFACTURING | XBEIMAGE_GAME_REGION_NA | XBEIMAGE_GAME_REGION_JAPAN | XBEIMAGE_GAME_REGION_RESTOFWORLD;
|
||||
|
||||
// TODO: allow configuration
|
||||
m_Certificate.dwGameRatings = 0xFFFFFFFF;
|
||||
|
||||
// always disk 0, AFAIK
|
||||
m_Certificate.dwDiskNumber = 0;
|
||||
|
||||
// TODO: allow configuration
|
||||
m_Certificate.dwVersion = 0;
|
||||
|
||||
// generate blank LAN, signature, and alternate signature keys
|
||||
{
|
||||
for(uint32 v=0;v<0x10;v++)
|
||||
m_Certificate.bzLanKey[v] = m_Certificate.bzSignatureKey[v] = 0;
|
||||
|
||||
for(uint32 x=0;x<0x10;x++)
|
||||
for(uint32 y=0;y<0x10;y++)
|
||||
m_Certificate.bzTitleAlternateSignatureKey[x][y] = 0;
|
||||
|
||||
}
|
||||
|
||||
// write certificate
|
||||
{
|
||||
memcpy(szBuffer, &m_Certificate, sizeof(m_Certificate));
|
||||
|
||||
szBuffer += sizeof(m_Certificate);
|
||||
|
||||
hwc += sizeof(m_Certificate);
|
||||
}
|
||||
}
|
||||
|
||||
// generate ascii title from certificate title name
|
||||
setlocale( LC_ALL, "English" );
|
||||
wcstombs(m_szAsciiTitle, m_Certificate.wszTitleName, 40);
|
||||
|
||||
// write section headers / section names
|
||||
{
|
||||
m_szSectionName = new char[m_Header.dwSections][9];
|
||||
|
||||
m_SectionHeader = new SectionHeader[m_Header.dwSections];
|
||||
|
||||
uint32 SectionCursor = RoundUp(m_Header.dwSizeofHeaders, 0x1000);
|
||||
|
||||
// head/tail reference count write buffer
|
||||
uint16 *htrc = (uint16*)(szBuffer + m_Header.dwSections*sizeof(*m_SectionHeader));
|
||||
|
||||
// section write buffer
|
||||
char *secn = (char*)((uint32)htrc + (m_Header.dwSections+1)*2);
|
||||
|
||||
// head/tail reference count write cursor
|
||||
uint32 hwc_htrc = hwc + m_Header.dwSections*sizeof(*m_SectionHeader);
|
||||
|
||||
// section write cursor
|
||||
uint32 hwc_secn = hwc_htrc + (m_Header.dwSections+1)*2;
|
||||
|
||||
printf("Xbe::Xbe: Generating Section Headers...\n");
|
||||
|
||||
for(uint32 v=0;v<m_Header.dwSections;v++)
|
||||
{
|
||||
printf("Xbe::Xbe: Generating Section Header %.04X...", v);
|
||||
|
||||
uint32 characteristics = x_Exe->m_SectionHeader[v].m_characteristics;
|
||||
|
||||
memset(&m_SectionHeader[v].dwFlags, 0, sizeof(m_SectionHeader->dwFlags));
|
||||
|
||||
if(characteristics & IMAGE_SCN_MEM_WRITE)
|
||||
m_SectionHeader[v].dwFlags.bWritable = 1;
|
||||
|
||||
if( (characteristics & IMAGE_SCN_MEM_EXECUTE) || (characteristics & IMAGE_SCN_CNT_CODE) )
|
||||
m_SectionHeader[v].dwFlags.bExecutable = 1;
|
||||
|
||||
m_SectionHeader[v].dwFlags.bPreload = 1;
|
||||
m_SectionHeader[v].dwVirtualAddr = x_Exe->m_SectionHeader[v].m_virtual_addr + m_Header.dwPeBaseAddr;
|
||||
|
||||
if(v < m_Header.dwSections-1)
|
||||
m_SectionHeader[v].dwVirtualSize = x_Exe->m_SectionHeader[v+1].m_virtual_addr - x_Exe->m_SectionHeader[v].m_virtual_addr;
|
||||
else
|
||||
m_SectionHeader[v].dwVirtualSize = RoundUp(x_Exe->m_SectionHeader[v].m_virtual_size, 4);
|
||||
|
||||
m_SectionHeader[v].dwRawAddr = SectionCursor;
|
||||
|
||||
// calculate sizeof_raw by locating the last non-zero value in the raw section data
|
||||
{
|
||||
uint32 r = x_Exe->m_SectionHeader[v].m_sizeof_raw - 1;
|
||||
|
||||
while(r > 0)
|
||||
{
|
||||
if(x_Exe->m_bzSection[v][r--] != 0)
|
||||
break;
|
||||
}
|
||||
|
||||
// word aligned
|
||||
m_SectionHeader[v].dwSizeofRaw = RoundUp(r+2, 4);
|
||||
}
|
||||
|
||||
SectionCursor += RoundUp(m_SectionHeader[v].dwSizeofRaw, 0x1000);
|
||||
|
||||
// head/tail reference count
|
||||
{
|
||||
m_SectionHeader[v].dwHeadSharedRefCountAddr = hwc_htrc;
|
||||
htrc[v] = 0;
|
||||
|
||||
hwc_htrc += 2;
|
||||
|
||||
m_SectionHeader[v].dwTailSharedRefCountAddr = hwc_htrc;
|
||||
htrc[v+1] = 0;
|
||||
}
|
||||
|
||||
// section name
|
||||
{
|
||||
uint32 s = 0;
|
||||
|
||||
memset(secn, 0, 8);
|
||||
|
||||
m_SectionHeader[v].dwSectionNameAddr = hwc_secn;
|
||||
while(s < 8 && x_Exe->m_SectionHeader[v].m_name[s] != '\0')
|
||||
{
|
||||
m_szSectionName[v][s] = secn[s] = x_Exe->m_SectionHeader[v].m_name[s];
|
||||
s++;
|
||||
}
|
||||
|
||||
m_szSectionName[v][s] = '\0';
|
||||
|
||||
secn += s+1;
|
||||
hwc_secn += s+1;
|
||||
}
|
||||
|
||||
m_SectionHeader[v].dwSectionRefCount = 0;
|
||||
|
||||
// write section digest (just zeros)
|
||||
memset(m_SectionHeader[v].bzSectionDigest, 0, 20);
|
||||
|
||||
// write section header
|
||||
memcpy(szBuffer, &m_SectionHeader[v], sizeof(*m_SectionHeader));
|
||||
|
||||
szBuffer += sizeof(*m_SectionHeader);
|
||||
|
||||
printf("OK\n");
|
||||
}
|
||||
|
||||
hwc = hwc_secn;
|
||||
}
|
||||
|
||||
// write debug path / debug file names
|
||||
{
|
||||
*(uint16*)szBuffer = 0x0000;
|
||||
|
||||
szBuffer += 2;
|
||||
hwc += 2;
|
||||
}
|
||||
|
||||
// write default "OpenXDK" logo bitmap
|
||||
{
|
||||
printf("Xbe::Xbe: Generating \"OpenXDK\" Logo Bitmap...");
|
||||
|
||||
uint08 *RawAddr = GetAddr(m_Header.dwLogoBitmapAddr);
|
||||
|
||||
memset(RawAddr, 0, 100*17);
|
||||
|
||||
memcpy(RawAddr, OpenXDK, dwSizeOfOpenXDK);
|
||||
|
||||
m_Header.dwSizeofLogoBitmap = dwSizeOfOpenXDK;
|
||||
|
||||
printf("OK\n");
|
||||
}
|
||||
|
||||
// write sections
|
||||
{
|
||||
printf("Xbe::Xbe: Generating Sections...\n");
|
||||
|
||||
m_bzSection = new uint08*[m_Header.dwSections];
|
||||
|
||||
memset(m_bzSection, 0, m_Header.dwSections);
|
||||
|
||||
for(uint32 v=0;v<m_Header.dwSections;v++)
|
||||
{
|
||||
printf("Xbe::Xbe: Generating Section %.04X...", v);
|
||||
|
||||
uint32 RawSize = m_SectionHeader[v].dwSizeofRaw;
|
||||
|
||||
m_bzSection[v] = new uint08[RawSize];
|
||||
|
||||
memcpy(m_bzSection[v], x_Exe->m_bzSection[v], RawSize);
|
||||
|
||||
printf("OK\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printf("Xbe::Xbe: Pass 4 (Finalizing)...\n");
|
||||
|
||||
// pass 4
|
||||
{
|
||||
m_Header.dwSizeofImage = m_SectionHeader[m_Header.dwSections-1].dwVirtualAddr + m_SectionHeader[m_Header.dwSections-1].dwVirtualSize - m_Header.dwBaseAddr;
|
||||
|
||||
m_Header.dwTLSAddr = 0;
|
||||
|
||||
// relocate to base : 0x00010000
|
||||
{
|
||||
printf("Xbe::Xbe: Relocating to Base 0x00010000...");
|
||||
|
||||
uint32 fixCount = 0;
|
||||
|
||||
uint32 relo_addr = x_Exe->m_OptionalHeader.m_image_data_directory[5].m_virtual_addr;
|
||||
uint32 relo_size = x_Exe->m_OptionalHeader.m_image_data_directory[5].m_size;
|
||||
|
||||
uint32 dwBaseDiff = m_Header.dwPeBaseAddr - x_Exe->m_OptionalHeader.m_image_base;
|
||||
|
||||
uint08 *reloc = GetAddr(relo_addr + m_Header.dwPeBaseAddr);
|
||||
|
||||
// relocate, if necessary
|
||||
if(reloc != 0)
|
||||
{
|
||||
uint32 v = 0;
|
||||
|
||||
// relocate each relocation block
|
||||
while(v < relo_size)
|
||||
{
|
||||
uint32 block_addr = *(uint32 *)&reloc[v+0];
|
||||
uint32 block_stop = *(uint32 *)&reloc[v+4] + v;
|
||||
|
||||
v += 8;
|
||||
|
||||
// relocate each rva
|
||||
while(v < block_stop && v < relo_size)
|
||||
{
|
||||
uint16 data = *(uint16 *)&reloc[v];
|
||||
|
||||
uint32 type = (data & 0xF000) >> 12;
|
||||
|
||||
if(type == 0)
|
||||
{
|
||||
v+=2;
|
||||
break;
|
||||
}
|
||||
|
||||
// 32-bit field relocation
|
||||
if(type == IMAGE_REL_BASED_HIGHLOW)
|
||||
{
|
||||
fixCount++;
|
||||
|
||||
uint32 dwFixAddr = block_addr + (data & 0x0FFF) + m_Header.dwPeBaseAddr;
|
||||
|
||||
uint08 *bzModRVA = GetAddr(dwFixAddr);
|
||||
|
||||
if(bzModRVA != 0)
|
||||
*(uint32*)bzModRVA += dwBaseDiff;
|
||||
}
|
||||
else
|
||||
{
|
||||
SetError("Unsupported relocation type", true);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
v+=2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printf("OK (%d Fixups)\n", fixCount);
|
||||
}
|
||||
|
||||
// locate kernel thunk table
|
||||
{
|
||||
// unfortunately, GCC doesn't populate the IAT entry in the data directory
|
||||
// so if the value is 0, then it could mean there are no imports, or it
|
||||
// could mean the EXE was compiled by GCC
|
||||
uint32 ktRVA = x_Exe->m_OptionalHeader.m_image_data_directory[12].m_virtual_addr;
|
||||
|
||||
if(ktRVA == 0)
|
||||
{
|
||||
// lets check to see if there is an import section. if so, look at offset 16
|
||||
// for the RVA of the Import Address Table
|
||||
uint32 importRVA = x_Exe->m_OptionalHeader.m_image_data_directory[1].m_virtual_addr;
|
||||
|
||||
if(importRVA != 0)
|
||||
{
|
||||
uint08 *importSection = GetAddr(importRVA + m_Header.dwPeBaseAddr);
|
||||
|
||||
ktRVA = *(uint32 *)&importSection[16];
|
||||
}
|
||||
}
|
||||
|
||||
uint32 kt = ktRVA + m_Header.dwPeBaseAddr;
|
||||
|
||||
kt ^= (x_bRetail ? XOR_KT_RETAIL : XOR_KT_DEBUG );
|
||||
|
||||
m_Header.dwKernelImageThunkAddr = kt;
|
||||
}
|
||||
}
|
||||
|
||||
cleanup:
|
||||
|
||||
if(GetError() != 0)
|
||||
{
|
||||
printf("FAILED!\n");
|
||||
printf("Xbe::Xbe: ERROR -> %s\n", GetError());
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// deconstructor
|
||||
Xbe::~Xbe()
|
||||
{
|
||||
|
|
|
@ -49,10 +49,7 @@ class Xbe : public Error
|
|||
public:
|
||||
// construct via Xbe file
|
||||
Xbe(const char *x_szFilename);
|
||||
|
||||
// construct via Exe file object
|
||||
Xbe(class Exe *x_Exe, const char *x_szTitle, bool x_bRetail);
|
||||
|
||||
|
||||
// deconstructor
|
||||
~Xbe();
|
||||
|
||||
|
|
|
@ -1,702 +0,0 @@
|
|||
// ******************************************************************
|
||||
// *
|
||||
// * .,-::::: .,:: .::::::::. .,:: .:
|
||||
// * ,;;;'````' `;;;, .,;; ;;;'';;' `;;;, .,;;
|
||||
// * [[[ '[[,,[[' [[[__[[\. '[[,,[['
|
||||
// * $$$ Y$$$P $$""""Y$$ Y$$$P
|
||||
// * `88bo,__,o, oP"``"Yo, _88o,,od8P oP"``"Yo,
|
||||
// * "YUMMMMMP",m" "Mm,""YUMMMP" ,m" "Mm,
|
||||
// *
|
||||
// * Cxbx->Win32->Cxbx->EmuExe.cpp
|
||||
// *
|
||||
// * 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
|
||||
// *
|
||||
// ******************************************************************
|
||||
|
||||
#include "EmuExe.h"
|
||||
#include "Prolog.h"
|
||||
#include "CxbxUtil.h"
|
||||
#include "CxbxKrnl/CxbxKrnl.h"
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
// ******************************************************************
|
||||
// * constructor
|
||||
// ******************************************************************
|
||||
EmuExe::EmuExe(Xbe *x_Xbe, DebugMode x_debug_mode, char *x_debug_filename, HWND hwndParent) : Exe()
|
||||
{
|
||||
ConstructorInit();
|
||||
|
||||
printf("EmuExe::EmuExe: Generating Exe file...\n");
|
||||
|
||||
// ******************************************************************
|
||||
// * generate pe header
|
||||
// ******************************************************************
|
||||
{
|
||||
printf("EmuExe::EmuExe: Generating PE header...");
|
||||
|
||||
m_Header.m_magic = *(uint32 *)"PE\0\0"; // magic number : "PE\0\0"
|
||||
m_Header.m_machine = IMAGE_FILE_MACHINE_I386; // machine type : i386
|
||||
m_Header.m_sections = (uint16)(x_Xbe->m_Header.dwSections + 2); // xbe sections + .cxbximp + .cxbxplg
|
||||
m_Header.m_timedate = x_Xbe->m_Header.dwTimeDate; // time/date stamp
|
||||
m_Header.m_symbol_table_addr = 0; // unused
|
||||
m_Header.m_symbols = 0; // unused
|
||||
m_Header.m_sizeof_optional_header = sizeof(OptionalHeader); // size of optional header
|
||||
m_Header.m_characteristics = 0x012F; // should be fine..
|
||||
|
||||
printf("OK\n");
|
||||
}
|
||||
|
||||
// ******************************************************************
|
||||
// * generate optional header
|
||||
// ******************************************************************
|
||||
{
|
||||
printf("EmuExe::EmuExe: Generating Optional Header...");
|
||||
|
||||
m_OptionalHeader.m_magic = 0x010B; // magic number : 0x010B
|
||||
|
||||
// ******************************************************************
|
||||
// * abitrary linker version : 6.0
|
||||
// ******************************************************************
|
||||
m_OptionalHeader.m_linker_version_major = 0x06;
|
||||
m_OptionalHeader.m_linker_version_minor = 0x00;
|
||||
|
||||
// ******************************************************************
|
||||
// * size of headers
|
||||
// ******************************************************************
|
||||
m_OptionalHeader.m_sizeof_headers = sizeof(bzDOSStub) + sizeof(m_Header);
|
||||
m_OptionalHeader.m_sizeof_headers += sizeof(m_OptionalHeader) + sizeof(*m_SectionHeader)*m_Header.m_sections;
|
||||
m_OptionalHeader.m_sizeof_headers = RoundUp(m_OptionalHeader.m_sizeof_headers, PE_FILE_ALIGN);
|
||||
|
||||
m_OptionalHeader.m_image_base = x_Xbe->m_Header.dwBaseAddr;
|
||||
|
||||
m_OptionalHeader.m_section_alignment = PE_SEGM_ALIGN;
|
||||
m_OptionalHeader.m_file_alignment = PE_FILE_ALIGN;
|
||||
|
||||
// ******************************************************************
|
||||
// * OS version : 4.0
|
||||
// ******************************************************************
|
||||
m_OptionalHeader.m_os_version_major = 0x0004;
|
||||
m_OptionalHeader.m_os_version_minor = 0x0000;
|
||||
|
||||
// ******************************************************************
|
||||
// * image version : 0.0
|
||||
// ******************************************************************
|
||||
m_OptionalHeader.m_image_version_major = 0x0000;
|
||||
m_OptionalHeader.m_image_version_minor = 0x0000;
|
||||
|
||||
// ******************************************************************
|
||||
// * subsystem version : 4.0
|
||||
// ******************************************************************
|
||||
m_OptionalHeader.m_subsystem_version_major = 0x0004;
|
||||
m_OptionalHeader.m_subsystem_version_minor = 0x0000;
|
||||
|
||||
m_OptionalHeader.m_win32_version = 0x00000000;
|
||||
m_OptionalHeader.m_checksum = 0x00000000;
|
||||
m_OptionalHeader.m_subsystem = IMAGE_SUBSYSTEM_WINDOWS_GUI;
|
||||
|
||||
// ******************************************************************
|
||||
// * no special dll characteristics are necessary
|
||||
// ******************************************************************
|
||||
m_OptionalHeader.m_dll_characteristics = 0x0000;
|
||||
|
||||
// ******************************************************************
|
||||
// * TODO: for each of these, check for bad values and correct them
|
||||
// ******************************************************************
|
||||
m_OptionalHeader.m_sizeof_stack_reserve = 0x00100000;
|
||||
m_OptionalHeader.m_sizeof_stack_commit = x_Xbe->m_Header.dwPeStackCommit;
|
||||
m_OptionalHeader.m_sizeof_heap_reserve = x_Xbe->m_Header.dwPeHeapReserve;
|
||||
m_OptionalHeader.m_sizeof_heap_commit = x_Xbe->m_Header.dwPeHeapCommit;
|
||||
|
||||
// ******************************************************************
|
||||
// * this member is obsolete, so we'll just set it to zero
|
||||
// ******************************************************************
|
||||
m_OptionalHeader.m_loader_flags = 0x00000000;
|
||||
|
||||
// ******************************************************************
|
||||
// * we'll set this to the typical 0x10 (16)
|
||||
// ******************************************************************
|
||||
m_OptionalHeader.m_data_directories = 0x10;
|
||||
|
||||
// ******************************************************************
|
||||
// * clear all data directories (we'll setup some later)
|
||||
// ******************************************************************
|
||||
for(uint32 d=0;d<m_OptionalHeader.m_data_directories;d++)
|
||||
{
|
||||
m_OptionalHeader.m_image_data_directory[d].m_virtual_addr = 0;
|
||||
m_OptionalHeader.m_image_data_directory[d].m_size = 0;
|
||||
}
|
||||
|
||||
printf("OK\n");
|
||||
}
|
||||
|
||||
// ******************************************************************
|
||||
// * generate section headers
|
||||
// ******************************************************************
|
||||
{
|
||||
printf("EmuExe::EmuExe: Generating Section Headers...\n");
|
||||
|
||||
m_SectionHeader = new SectionHeader[m_Header.m_sections];
|
||||
|
||||
// ******************************************************************
|
||||
// * start appending section headers at this point
|
||||
// ******************************************************************
|
||||
uint32 dwSectionCursor = x_Xbe->m_SectionHeader[0].dwRawAddr;
|
||||
|
||||
// ******************************************************************
|
||||
// * generate xbe section headers
|
||||
// ******************************************************************
|
||||
{
|
||||
for(uint32 v=0;v<x_Xbe->m_Header.dwSections;v++)
|
||||
{
|
||||
printf("EmuExe::EmuExe: Generating Section Header 0x%.04X...", v);
|
||||
|
||||
// ******************************************************************
|
||||
// * generate xbe section name
|
||||
// ******************************************************************
|
||||
{
|
||||
memset(m_SectionHeader[v].m_name, 0, 8);
|
||||
|
||||
for(int c=0;c<8;c++)
|
||||
{
|
||||
m_SectionHeader[v].m_name[c] = x_Xbe->m_szSectionName[v][c];
|
||||
|
||||
if(m_SectionHeader[v].m_name[c] == '\0')
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// ******************************************************************
|
||||
// * generate xbe section virtual size / addr
|
||||
// ******************************************************************
|
||||
{
|
||||
uint32 VirtSize = x_Xbe->m_SectionHeader[v].dwVirtualSize;
|
||||
uint32 VirtAddr = x_Xbe->m_SectionHeader[v].dwVirtualAddr - x_Xbe->m_Header.dwBaseAddr;
|
||||
|
||||
m_SectionHeader[v].m_virtual_size = VirtSize;
|
||||
m_SectionHeader[v].m_virtual_addr = VirtAddr;
|
||||
}
|
||||
|
||||
// ******************************************************************
|
||||
// * generate xbe section raw size / addr
|
||||
// ******************************************************************
|
||||
{
|
||||
// TODO: get this working such that m_sizeof_raw can be the actual raw size, not virtual size
|
||||
uint32 RawSize = RoundUp(x_Xbe->m_SectionHeader[v].dwVirtualSize, PE_FILE_ALIGN);
|
||||
uint32 RawAddr = dwSectionCursor;
|
||||
|
||||
m_SectionHeader[v].m_sizeof_raw = RawSize;
|
||||
m_SectionHeader[v].m_raw_addr = RawAddr;
|
||||
|
||||
dwSectionCursor += RawSize;
|
||||
}
|
||||
|
||||
// ******************************************************************
|
||||
// * relocation / line numbers will not exist
|
||||
// ******************************************************************
|
||||
{
|
||||
m_SectionHeader[v].m_relocations_addr = 0;
|
||||
m_SectionHeader[v].m_linenumbers_addr = 0;
|
||||
|
||||
m_SectionHeader[v].m_relocations = 0;
|
||||
m_SectionHeader[v].m_linenumbers = 0;
|
||||
}
|
||||
|
||||
// ******************************************************************
|
||||
// * generate flags for this xbe section
|
||||
// ******************************************************************
|
||||
{
|
||||
uint32 flags = IMAGE_SCN_MEM_READ;
|
||||
|
||||
if(x_Xbe->m_SectionHeader[v].dwFlags.bExecutable)
|
||||
{
|
||||
flags |= IMAGE_SCN_MEM_EXECUTE;
|
||||
flags |= IMAGE_SCN_CNT_CODE;
|
||||
}
|
||||
else
|
||||
{
|
||||
flags |= IMAGE_SCN_CNT_INITIALIZED_DATA;
|
||||
}
|
||||
|
||||
if(x_Xbe->m_SectionHeader[v].dwFlags.bWritable)
|
||||
flags |= IMAGE_SCN_MEM_WRITE;
|
||||
|
||||
m_SectionHeader[v].m_characteristics = flags;
|
||||
}
|
||||
|
||||
printf("OK\n");
|
||||
}
|
||||
}
|
||||
|
||||
// ******************************************************************
|
||||
// * generate .cxbximp section header
|
||||
// ******************************************************************
|
||||
{
|
||||
uint32 i = m_Header.m_sections - 2;
|
||||
|
||||
printf("EmuExe::EmuExe: Generating Section Header 0x%.04X (.cxbximp)...", i);
|
||||
|
||||
memcpy(m_SectionHeader[i].m_name, ".cxbximp", 8);
|
||||
|
||||
// ******************************************************************
|
||||
// * generate .cxbximp section virtual size / addr
|
||||
// ******************************************************************
|
||||
{
|
||||
uint32 virt_size = RoundUp(0x6E, PE_SEGM_ALIGN);
|
||||
uint32 virt_addr = RoundUp(m_SectionHeader[i-1].m_virtual_addr + m_SectionHeader[i-1].m_virtual_size, PE_SEGM_ALIGN);
|
||||
|
||||
m_SectionHeader[i].m_virtual_size = virt_size;
|
||||
m_SectionHeader[i].m_virtual_addr = virt_addr;
|
||||
}
|
||||
|
||||
// ******************************************************************
|
||||
// * generate .cxbximp section raw size / addr
|
||||
// ******************************************************************
|
||||
{
|
||||
uint32 raw_size = RoundUp(m_SectionHeader[i].m_virtual_size, PE_FILE_ALIGN);
|
||||
|
||||
m_SectionHeader[i].m_sizeof_raw = raw_size;
|
||||
m_SectionHeader[i].m_raw_addr = dwSectionCursor;
|
||||
|
||||
dwSectionCursor += raw_size;
|
||||
}
|
||||
|
||||
// ******************************************************************
|
||||
// * relocation / line numbers will not exist
|
||||
// ******************************************************************
|
||||
{
|
||||
m_SectionHeader[i].m_relocations_addr = 0;
|
||||
m_SectionHeader[i].m_linenumbers_addr = 0;
|
||||
|
||||
m_SectionHeader[i].m_relocations = 0;
|
||||
m_SectionHeader[i].m_linenumbers = 0;
|
||||
}
|
||||
|
||||
// ******************************************************************
|
||||
// * make this section readable initialized data
|
||||
// ******************************************************************
|
||||
m_SectionHeader[i].m_characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA;
|
||||
|
||||
// ******************************************************************
|
||||
// * update import table directory entry
|
||||
// ******************************************************************
|
||||
m_OptionalHeader.m_image_data_directory[IMAGE_DIRECTORY_ENTRY_IMPORT].m_virtual_addr = m_SectionHeader[i].m_virtual_addr + 0x08;
|
||||
m_OptionalHeader.m_image_data_directory[IMAGE_DIRECTORY_ENTRY_IMPORT].m_size = 0x28;
|
||||
|
||||
// ******************************************************************
|
||||
// * update import address table directory entry
|
||||
// ******************************************************************
|
||||
m_OptionalHeader.m_image_data_directory[IMAGE_DIRECTORY_ENTRY_IAT].m_virtual_addr = m_SectionHeader[i].m_virtual_addr;
|
||||
m_OptionalHeader.m_image_data_directory[IMAGE_DIRECTORY_ENTRY_IAT].m_size = 0x08;
|
||||
|
||||
printf("OK\n");
|
||||
}
|
||||
|
||||
// ******************************************************************
|
||||
// * generate .cxbxplg section header
|
||||
// ******************************************************************
|
||||
{
|
||||
uint32 i = m_Header.m_sections - 1;
|
||||
|
||||
printf("EmuExe::EmuExe: Generating Section Header 0x%.04X (.cxbxplg)...", i);
|
||||
|
||||
memcpy(m_SectionHeader[i].m_name, ".cxbxplg", 8);
|
||||
|
||||
// ******************************************************************
|
||||
// * generate .cxbxplg section virtual size / addr
|
||||
// ******************************************************************
|
||||
{
|
||||
uint32 virt_size = RoundUp(m_OptionalHeader.m_image_base + 0x100 + x_Xbe->m_Header.dwSizeofHeaders + 260
|
||||
+ sizeof(Xbe::LibraryVersion) * x_Xbe->m_Header.dwLibraryVersions + sizeof(Xbe::TLS)
|
||||
+ (x_Xbe->m_TLS->dwDataEndAddr - x_Xbe->m_TLS->dwDataStartAddr), 0x1000);
|
||||
uint32 virt_addr = RoundUp(m_SectionHeader[i-1].m_virtual_addr + m_SectionHeader[i-1].m_virtual_size, PE_SEGM_ALIGN);
|
||||
|
||||
m_SectionHeader[i].m_virtual_size = virt_size;
|
||||
m_SectionHeader[i].m_virtual_addr = virt_addr;
|
||||
|
||||
// our entry point should be the first bytes in this section
|
||||
m_OptionalHeader.m_entry = virt_addr;
|
||||
}
|
||||
|
||||
// ******************************************************************
|
||||
// * generate .cxbxplg section raw size / addr
|
||||
// ******************************************************************
|
||||
{
|
||||
uint32 raw_size = RoundUp(m_SectionHeader[i].m_virtual_size, PE_FILE_ALIGN);
|
||||
|
||||
m_SectionHeader[i].m_sizeof_raw = raw_size;
|
||||
m_SectionHeader[i].m_raw_addr = dwSectionCursor;
|
||||
|
||||
dwSectionCursor += raw_size;
|
||||
}
|
||||
|
||||
// ******************************************************************
|
||||
// * relocation / line numbers will not exist
|
||||
// ******************************************************************
|
||||
{
|
||||
m_SectionHeader[i].m_relocations_addr = 0;
|
||||
m_SectionHeader[i].m_linenumbers_addr = 0;
|
||||
|
||||
m_SectionHeader[i].m_relocations = 0;
|
||||
m_SectionHeader[i].m_linenumbers = 0;
|
||||
}
|
||||
|
||||
// ******************************************************************
|
||||
// * make this section readable and executable
|
||||
// ******************************************************************
|
||||
m_SectionHeader[i].m_characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_CNT_CODE;
|
||||
|
||||
printf("OK\n");
|
||||
}
|
||||
}
|
||||
|
||||
// ******************************************************************
|
||||
// * generate sections
|
||||
// ******************************************************************
|
||||
{
|
||||
printf("EmuExe::EmuExe: Generating Sections...\n");
|
||||
|
||||
m_bzSection = new uint08*[m_Header.m_sections];
|
||||
|
||||
// ******************************************************************
|
||||
// * generate xbe sections
|
||||
// ******************************************************************
|
||||
{
|
||||
uint32 kt = x_Xbe->m_Header.dwKernelImageThunkAddr;
|
||||
|
||||
// ******************************************************************
|
||||
// * decode kernel thunk address
|
||||
// ******************************************************************
|
||||
{
|
||||
if((kt ^ XOR_KT_DEBUG) > 0x01000000)
|
||||
kt ^= XOR_KT_RETAIL;
|
||||
else
|
||||
kt ^= XOR_KT_DEBUG;
|
||||
}
|
||||
|
||||
// ******************************************************************
|
||||
// * generate xbe sections
|
||||
// ******************************************************************
|
||||
for(uint32 v=0;v<x_Xbe->m_Header.dwSections;v++)
|
||||
{
|
||||
printf("EmuExe::EmuExe: Generating Section 0x%.04X...", v);
|
||||
|
||||
uint32 SectionSize = m_SectionHeader[v].m_sizeof_raw;
|
||||
|
||||
m_bzSection[v] = new uint08[SectionSize];
|
||||
|
||||
memset(m_bzSection[v], 0, SectionSize);
|
||||
|
||||
memcpy(m_bzSection[v], x_Xbe->m_bzSection[v], x_Xbe->m_SectionHeader[v].dwSizeofRaw);
|
||||
|
||||
printf("OK\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// ******************************************************************
|
||||
// * generate .cxbximp section
|
||||
// ******************************************************************
|
||||
{
|
||||
uint32 i = m_Header.m_sections - 2;
|
||||
|
||||
printf("EmuExe::EmuExe: Generating Section 0x%.04X (.cxbximp)...", i);
|
||||
|
||||
uint32 dwVirtAddr = m_SectionHeader[i].m_virtual_addr;
|
||||
|
||||
uint32 dwRawSize = m_SectionHeader[i].m_sizeof_raw;
|
||||
|
||||
m_bzSection[i] = new uint08[dwRawSize];
|
||||
|
||||
memset(m_bzSection[i], 0, dwRawSize);
|
||||
|
||||
*(uint32*)&m_bzSection[i][0x00] = dwVirtAddr + 0x38;
|
||||
*(uint32*)&m_bzSection[i][0x04] = 0;
|
||||
*(uint32*)&m_bzSection[i][0x08] = dwVirtAddr + 0x30;
|
||||
*(uint32*)&m_bzSection[i][0x0C] = 0;
|
||||
|
||||
*(uint32*)&m_bzSection[i][0x10] = 0;
|
||||
*(uint32*)&m_bzSection[i][0x14] = dwVirtAddr + 0x4A;
|
||||
*(uint32*)&m_bzSection[i][0x18] = dwVirtAddr + 0x00;
|
||||
*(uint32*)&m_bzSection[i][0x1C] = 0;
|
||||
|
||||
*(uint32*)&m_bzSection[i][0x20] = 0;
|
||||
*(uint32*)&m_bzSection[i][0x24] = 0;
|
||||
*(uint32*)&m_bzSection[i][0x28] = 0;
|
||||
*(uint32*)&m_bzSection[i][0x2C] = 0;
|
||||
|
||||
*(uint32*)&m_bzSection[i][0x30] = dwVirtAddr + 0x38;
|
||||
*(uint32*)&m_bzSection[i][0x34] = 0;
|
||||
*(uint16*)&m_bzSection[i][0x38] = 0x0001;
|
||||
|
||||
memcpy(&m_bzSection[i][0x3A], "CxbxKrnlNoFunc\0\0CxbxKrnl.dll\0\0", 30);
|
||||
|
||||
printf("OK\n");
|
||||
}
|
||||
|
||||
// ******************************************************************
|
||||
// * generate .cxbxplg section
|
||||
// ******************************************************************
|
||||
{
|
||||
uint32 ep = x_Xbe->m_Header.dwEntryAddr;
|
||||
uint32 i = m_Header.m_sections - 1;
|
||||
|
||||
printf("EmuExe::EmuExe: Generating Section 0x%.04X (.cxbxplg)...", i);
|
||||
|
||||
// ******************************************************************
|
||||
// * decode entry point
|
||||
// ******************************************************************
|
||||
if( (ep ^ XOR_EP_RETAIL) > 0x01000000)
|
||||
ep ^= XOR_EP_DEBUG;
|
||||
else
|
||||
ep ^= XOR_EP_RETAIL;
|
||||
|
||||
m_bzSection[i] = new uint08[m_SectionHeader[i].m_sizeof_raw];
|
||||
|
||||
uint08 *pWriteCursor = m_bzSection[i];
|
||||
|
||||
// ******************************************************************
|
||||
// * append prolog section
|
||||
// ******************************************************************
|
||||
memcpy(pWriteCursor, Prolog, 0x1000);
|
||||
pWriteCursor += 0x100;
|
||||
|
||||
// ******************************************************************
|
||||
// * append xbe header
|
||||
// ******************************************************************
|
||||
memcpy(pWriteCursor, &x_Xbe->m_Header, sizeof(Xbe::Header));
|
||||
pWriteCursor += sizeof(Xbe::Header);
|
||||
|
||||
// ******************************************************************
|
||||
// * append xbe extra header bytes
|
||||
// ******************************************************************
|
||||
memcpy(pWriteCursor, x_Xbe->m_HeaderEx, x_Xbe->m_Header.dwSizeofHeaders - sizeof(Xbe::Header));
|
||||
pWriteCursor -= sizeof(Xbe::Header);
|
||||
pWriteCursor += x_Xbe->m_Header.dwSizeofHeaders;
|
||||
|
||||
// ******************************************************************
|
||||
// * append x_debug_filename
|
||||
// ******************************************************************
|
||||
memcpy(pWriteCursor, x_debug_filename, 260);
|
||||
pWriteCursor += 260;
|
||||
|
||||
// ******************************************************************
|
||||
// * append library versions
|
||||
// ******************************************************************
|
||||
if(x_Xbe->m_LibraryVersion != 0)
|
||||
{
|
||||
memcpy(pWriteCursor, x_Xbe->m_LibraryVersion, sizeof(Xbe::LibraryVersion) * x_Xbe->m_Header.dwLibraryVersions);
|
||||
pWriteCursor += sizeof(Xbe::LibraryVersion) * x_Xbe->m_Header.dwLibraryVersions;
|
||||
}
|
||||
|
||||
// ******************************************************************
|
||||
// * append TLS data
|
||||
// ******************************************************************
|
||||
if(x_Xbe->m_TLS != 0)
|
||||
{
|
||||
memcpy(pWriteCursor, x_Xbe->m_TLS, sizeof(Xbe::TLS));
|
||||
pWriteCursor += sizeof(Xbe::TLS);
|
||||
memcpy(pWriteCursor, x_Xbe->GetTLSData(), x_Xbe->m_TLS->dwDataEndAddr - x_Xbe->m_TLS->dwDataStartAddr);
|
||||
pWriteCursor += x_Xbe->m_TLS->dwDataEndAddr - x_Xbe->m_TLS->dwDataStartAddr;
|
||||
}
|
||||
|
||||
// ******************************************************************
|
||||
// * patch prolog function parameters
|
||||
// ******************************************************************
|
||||
uint32 WriteCursor = m_SectionHeader[i].m_virtual_addr + m_OptionalHeader.m_image_base + 0x100;
|
||||
|
||||
// Function Pointer
|
||||
*(uint32 *)((uint32)m_bzSection[i] + 1) = (uint32)CxbxKrnlInit;
|
||||
|
||||
// Param 8 : Entry
|
||||
*(uint32 *)((uint32)m_bzSection[i] + 6) = (uint32)ep;
|
||||
|
||||
// Param 7 : dwXbeHeaderSize
|
||||
*(uint32 *)((uint32)m_bzSection[i] + 11) = (uint32)x_Xbe->m_Header.dwSizeofHeaders;
|
||||
|
||||
// Param 6 : pXbeHeader
|
||||
*(uint32 *)((uint32)m_bzSection[i] + 16) = WriteCursor;
|
||||
WriteCursor += x_Xbe->m_Header.dwSizeofHeaders;
|
||||
|
||||
// Param 5 : szDebugFilename
|
||||
*(uint32 *)((uint32)m_bzSection[i] + 21) = WriteCursor;
|
||||
WriteCursor += 260;
|
||||
|
||||
// Param 4 : DbgMode
|
||||
*(uint32 *)((uint32)m_bzSection[i] + 26) = x_debug_mode;
|
||||
|
||||
// Param 3 : pLibraryVersion
|
||||
if(x_Xbe->m_LibraryVersion != 0)
|
||||
{
|
||||
*(uint32 *)((uint32)m_bzSection[i] + 31) = WriteCursor;
|
||||
WriteCursor += sizeof(Xbe::LibraryVersion) * x_Xbe->m_Header.dwLibraryVersions;
|
||||
}
|
||||
else
|
||||
{
|
||||
*(uint32 *)((uint32)m_bzSection[i] + 31) = 0;
|
||||
}
|
||||
|
||||
// Param 2 : pTLS
|
||||
if(x_Xbe->m_TLS != 0)
|
||||
{
|
||||
*(uint32 *)((uint32)m_bzSection[i] + 36) = WriteCursor;
|
||||
WriteCursor += sizeof(Xbe::TLS);
|
||||
}
|
||||
else
|
||||
{
|
||||
*(uint32 *)((uint32)m_bzSection[i] + 36) = 0;
|
||||
}
|
||||
|
||||
// Param 1 : pTLSData
|
||||
if(x_Xbe->m_TLS != 0)
|
||||
{
|
||||
*(uint32 *)((uint32)m_bzSection[i] + 41) = WriteCursor;
|
||||
WriteCursor += x_Xbe->m_TLS->dwDataEndAddr - x_Xbe->m_TLS->dwDataStartAddr;
|
||||
}
|
||||
else
|
||||
{
|
||||
*(uint32 *)((uint32)m_bzSection[i] + 41) = 0;
|
||||
}
|
||||
|
||||
// Param 0 : hwndParent
|
||||
*(uint32 *)((uint32)m_bzSection[i] + 46) = (uint32)hwndParent;
|
||||
|
||||
printf("OK\n");
|
||||
}
|
||||
}
|
||||
|
||||
// ******************************************************************
|
||||
// * patch kernel thunk table
|
||||
// ******************************************************************
|
||||
{
|
||||
printf("EmuExe::EmuExe: Hijacking Kernel Imports...\n");
|
||||
|
||||
uint32 kt = x_Xbe->m_Header.dwKernelImageThunkAddr;
|
||||
|
||||
// ******************************************************************
|
||||
// * decode kernel thunk address
|
||||
// ******************************************************************
|
||||
{
|
||||
if( (kt ^ XOR_KT_DEBUG) > 0x01000000)
|
||||
kt ^= XOR_KT_RETAIL;
|
||||
else
|
||||
kt ^= XOR_KT_DEBUG;
|
||||
}
|
||||
|
||||
// ******************************************************************
|
||||
// * locate section containing kernel thunk table
|
||||
// ******************************************************************
|
||||
for(uint32 v=0;v<x_Xbe->m_Header.dwSections;v++)
|
||||
{
|
||||
uint32 imag_base = m_OptionalHeader.m_image_base;
|
||||
|
||||
uint32 virt_addr = m_SectionHeader[v].m_virtual_addr;
|
||||
uint32 virt_size = m_SectionHeader[v].m_virtual_size;
|
||||
|
||||
// ******************************************************************
|
||||
// * modify kernel thunk table, if found
|
||||
// ******************************************************************
|
||||
if(kt >= virt_addr + imag_base && kt < virt_addr + virt_size + imag_base)
|
||||
{
|
||||
printf("EmuExe::EmuExe: Located Thunk Table in Section 0x%.04X (0x%.08X)...\n", v, kt);
|
||||
|
||||
uint32 *kt_tbl = (uint32*)&m_bzSection[v][kt - virt_addr - imag_base];
|
||||
|
||||
for(int k=0;kt_tbl[k] != 0;k++)
|
||||
{
|
||||
int t = kt_tbl[k] & 0x7FFFFFFF;
|
||||
|
||||
kt_tbl[k] = CxbxKrnl_KernelThunkTable[t];
|
||||
|
||||
if(t != -1)
|
||||
printf("EmuExe::EmuExe: Thunk %.03d : *0x%.08X := 0x%.08X\n", t, kt + k*4, kt_tbl[k]);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ******************************************************************
|
||||
// * update imcomplete header fields
|
||||
// ******************************************************************
|
||||
{
|
||||
printf("EmuExe::EmuExe: Finalizing Exe file...");
|
||||
|
||||
// ******************************************************************
|
||||
// * calculate size of code / data / image
|
||||
// ******************************************************************
|
||||
{
|
||||
uint32 sizeof_code = 0;
|
||||
uint32 sizeof_data = 0;
|
||||
uint32 sizeof_undata = 0;
|
||||
uint32 sizeof_image = 0;
|
||||
|
||||
for(uint32 v=0;v<m_Header.m_sections;v++)
|
||||
{
|
||||
uint32 characteristics = m_SectionHeader[v].m_characteristics;
|
||||
|
||||
if( (characteristics & IMAGE_SCN_MEM_EXECUTE) || (characteristics & IMAGE_SCN_CNT_CODE) )
|
||||
sizeof_code += m_SectionHeader[v].m_sizeof_raw;
|
||||
|
||||
if( (characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA) )
|
||||
sizeof_data += m_SectionHeader[v].m_sizeof_raw;
|
||||
}
|
||||
|
||||
// ******************************************************************
|
||||
// * calculate size of image
|
||||
// ******************************************************************
|
||||
sizeof_image = sizeof_undata + sizeof_data + sizeof_code + m_OptionalHeader.m_sizeof_headers;
|
||||
sizeof_image = RoundUp(sizeof_image, PE_SEGM_ALIGN);
|
||||
|
||||
// ******************************************************************
|
||||
// * update optional header as necessary
|
||||
// ******************************************************************
|
||||
m_OptionalHeader.m_sizeof_code = sizeof_code;
|
||||
m_OptionalHeader.m_sizeof_initialized_data = sizeof_data;
|
||||
m_OptionalHeader.m_sizeof_uninitialized_data = sizeof_undata;
|
||||
m_OptionalHeader.m_sizeof_image = sizeof_image;
|
||||
}
|
||||
|
||||
// ******************************************************************
|
||||
// * we'll set code base as the virtual address of the first section
|
||||
// ******************************************************************
|
||||
m_OptionalHeader.m_code_base = m_SectionHeader[0].m_virtual_addr;
|
||||
|
||||
// ******************************************************************
|
||||
// * we'll set data base as the virtual address of the first section
|
||||
// * that is not marked as containing code or being executable
|
||||
// ******************************************************************
|
||||
for(uint32 v=0;v<m_Header.m_sections;v++)
|
||||
{
|
||||
uint32 characteristics = m_SectionHeader[v].m_characteristics;
|
||||
|
||||
if( !(characteristics & IMAGE_SCN_MEM_EXECUTE) || !(characteristics & IMAGE_SCN_CNT_CODE) )
|
||||
{
|
||||
m_OptionalHeader.m_data_base = m_SectionHeader[v].m_virtual_addr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
printf("OK\n");
|
||||
}
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
// ******************************************************************
|
||||
// *
|
||||
// * .,-::::: .,:: .::::::::. .,:: .:
|
||||
// * ,;;;'````' `;;;, .,;; ;;;'';;' `;;;, .,;;
|
||||
// * [[[ '[[,,[[' [[[__[[\. '[[,,[['
|
||||
// * $$$ Y$$$P $$""""Y$$ Y$$$P
|
||||
// * `88bo,__,o, oP"``"Yo, _88o,,od8P oP"``"Yo,
|
||||
// * "YUMMMMMP",m" "Mm,""YUMMMP" ,m" "Mm,
|
||||
// *
|
||||
// * Cxbx->Win32->Cxbx->EmuExe.h
|
||||
// *
|
||||
// * 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
|
||||
// *
|
||||
// ******************************************************************
|
||||
#ifndef EMUEXE_H
|
||||
#define EMUEXE_H
|
||||
|
||||
#include "Common/Exe.h"
|
||||
#include <windows.h>
|
||||
|
||||
// ******************************************************************
|
||||
// * class : EmuExe
|
||||
// ******************************************************************
|
||||
class EmuExe : public Exe
|
||||
{
|
||||
public:
|
||||
// ******************************************************************
|
||||
// * Construct via Xbe file object
|
||||
// ******************************************************************
|
||||
EmuExe(class Xbe *x_Xbe, DebugMode x_debug_mode, char *x_debug_filename, HWND hwndParent = NULL);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,6 +1,6 @@
|
|||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Visual C++ generated include file.
|
||||
// Used by C:\Users\Brandon\Desktop\Cxbx\dstien\wip\resource\Cxbx.rc
|
||||
// Used by S:\GitHub\Cxbx-Reloaded\resource\Cxbx.rc
|
||||
//
|
||||
#define IDI_CXBX 101
|
||||
#define IDB_SPLASH 102
|
||||
|
@ -52,7 +52,6 @@
|
|||
#define ID_FILE_EXIT 40005
|
||||
#define ID_HELP_ABOUT 40008
|
||||
#define ID_EMULATION_START 40009
|
||||
#define ID_FILE_EXPORTTOEXE 40011
|
||||
#define ID_FILE_OPEN_XBE 40013
|
||||
#define ID_FILE_CLOSE_XBE 40014
|
||||
#define ID_HELP_HOMEPAGE 40019
|
||||
|
@ -62,7 +61,6 @@
|
|||
#define ID_EDIT_LOGOBITMAP_IMPORT 40026
|
||||
#define ID_EDIT_PATCH_ALLOW64MB 40027
|
||||
#define ID_EDIT_PATCH_DEBUGMODE 40031
|
||||
#define ID_FILE_IMPORTFROMEXE 40032
|
||||
#define ID_EMULATION_DEBUGOUTPUTGUI_CONSOLE 40035
|
||||
#define ID_EMULATION_DEBUGOUTPUTGUI_FILE 40036
|
||||
#define ID_EMULATION_DEBUGOUTPUTKERNEL_CONSOLE 40037
|
||||
|
@ -80,22 +78,10 @@
|
|||
#define ID_FILE_RXBE_7 40057
|
||||
#define ID_FILE_RXBE_8 40058
|
||||
#define ID_FILE_RXBE_9 40059
|
||||
#define ID_FILE_REXE_0 40060
|
||||
#define ID_FILE_REXE_1 40061
|
||||
#define ID_FILE_REXE_2 40062
|
||||
#define ID_FILE_REXE_3 40063
|
||||
#define ID_FILE_REXE_4 40064
|
||||
#define ID_FILE_REXE_5 40065
|
||||
#define ID_FILE_REXE_6 40066
|
||||
#define ID_FILE_REXE_7 40067
|
||||
#define ID_FILE_REXE_8 40068
|
||||
#define ID_FILE_REXE_9 40069
|
||||
#define ID_EDIT_DUMPXBEINFOTO_FILE 40071
|
||||
#define ID_EDIT_DUMPXBEINFOTO_DEBUGCONSOLE 40072
|
||||
#define ID_SETTINGS_GENXP 40078
|
||||
#define ID_SETTINGS_GENWT 40079
|
||||
#define ID_SETTINGS_GENMA 40080
|
||||
#define ID_EMULATION_STOP 40082
|
||||
#define IDC_STATIC -1
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
|
|
|
@ -34,8 +34,6 @@
|
|||
|
||||
#include "WndMain.h"
|
||||
|
||||
#include "Cxbx/EmuExe.h"
|
||||
|
||||
#include "CxbxKrnl/CxbxKrnl.h"
|
||||
#include "CxbxKrnl/Emu.h"
|
||||
#include "CxbxKrnl/EmuShared.h"
|
||||
|
@ -73,7 +71,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
|||
{
|
||||
MainWindow->OpenXbe(__argv[1]);
|
||||
|
||||
MainWindow->StartEmulation(AUTO_CONVERT_WINDOWS_TEMP, MainWindow->GetHwnd());
|
||||
MainWindow->StartEmulation(MainWindow->GetHwnd());
|
||||
}
|
||||
|
||||
/*! wait for window to be closed, or failure */
|
||||
|
|
|
@ -37,7 +37,6 @@
|
|||
#include "DlgVideoConfig.h"
|
||||
#include "CxbxKrnl/EmuShared.h"
|
||||
#include "ResCxbx.h"
|
||||
#include "EmuExe.h"
|
||||
#include "jpegdec/jpegdec.h"
|
||||
|
||||
#include <io.h>
|
||||
|
@ -48,7 +47,7 @@
|
|||
FILE _iob[] = { *stdin, *stdout, *stderr };
|
||||
extern "C" FILE * __cdecl __iob_func(void) { return _iob; }
|
||||
|
||||
WndMain::WndMain(HINSTANCE x_hInstance) : Wnd(x_hInstance), m_bCreated(false), m_Xbe(0), m_Exe(0), m_bExeChanged(false), m_bXbeChanged(false), m_bCanStart(true), m_hwndChild(NULL), m_AutoConvertToExe(AUTO_CONVERT_WINDOWS_TEMP), m_KrnlDebug(DM_NONE), m_CxbxDebug(DM_NONE), m_dwRecentXbe(0), m_dwRecentExe(0)
|
||||
WndMain::WndMain(HINSTANCE x_hInstance) : Wnd(x_hInstance), m_bCreated(false), m_Xbe(0), m_bXbeChanged(false), m_bCanStart(true), m_hwndChild(NULL), m_KrnlDebug(DM_NONE), m_CxbxDebug(DM_NONE), m_dwRecentXbe(0)
|
||||
{
|
||||
// initialize members
|
||||
{
|
||||
|
@ -58,19 +57,13 @@ WndMain::WndMain(HINSTANCE x_hInstance) : Wnd(x_hInstance), m_bCreated(false), m
|
|||
m_w = 640;
|
||||
m_h = 480;
|
||||
|
||||
m_ExeFilename = (char*)calloc(1, MAX_PATH);
|
||||
m_XbeFilename = (char*)calloc(1, MAX_PATH);
|
||||
|
||||
m_CxbxDebugFilename = (char*)calloc(1, MAX_PATH);
|
||||
m_KrnlDebugFilename = (char*)calloc(1, MAX_PATH);
|
||||
|
||||
int v=0;
|
||||
|
||||
for(v=0;v<RECENT_XBE_SIZE;v++)
|
||||
for(int v=0;v<RECENT_XBE_SIZE;v++)
|
||||
m_szRecentXbe[v] = 0;
|
||||
|
||||
for(v=0;v<RECENT_EXE_SIZE;v++)
|
||||
m_szRecentExe[v] = 0;
|
||||
}
|
||||
|
||||
// center to desktop
|
||||
|
@ -99,12 +92,6 @@ WndMain::WndMain(HINSTANCE x_hInstance) : Wnd(x_hInstance), m_bCreated(false), m
|
|||
dwType = REG_DWORD; dwSize = sizeof(DWORD);
|
||||
RegQueryValueEx(hKey, "RecentXbe", NULL, &dwType, (PBYTE)&m_dwRecentXbe, &dwSize);
|
||||
|
||||
dwType = REG_DWORD; dwSize = sizeof(DWORD);
|
||||
RegQueryValueEx(hKey, "RecentExe", NULL, &dwType, (PBYTE)&m_dwRecentExe, &dwSize);
|
||||
|
||||
dwType = REG_DWORD; dwSize = sizeof(DWORD);
|
||||
RegQueryValueEx(hKey, "AutoConvertToExe", NULL, &dwType, (PBYTE)&m_AutoConvertToExe, &dwSize);
|
||||
|
||||
dwType = REG_SZ; dwSize = MAX_PATH;
|
||||
RegQueryValueEx(hKey, "CxbxDebugFilename", NULL, &dwType, (PBYTE)m_CxbxDebugFilename, &dwSize);
|
||||
|
||||
|
@ -125,18 +112,6 @@ WndMain::WndMain(HINSTANCE x_hInstance) : Wnd(x_hInstance), m_bCreated(false), m
|
|||
RegQueryValueEx(hKey, buffer, NULL, &dwType, (PBYTE)m_szRecentXbe[v], &dwSize);
|
||||
}
|
||||
|
||||
for(v=0;v<m_dwRecentExe;v++)
|
||||
{
|
||||
char buffer[32];
|
||||
|
||||
sprintf(buffer, "RecentExe%d", v);
|
||||
|
||||
m_szRecentExe[v] = (char*)calloc(1, MAX_PATH);
|
||||
|
||||
dwType = REG_SZ; dwSize = MAX_PATH;
|
||||
RegQueryValueEx(hKey, buffer, NULL, &dwType, (PBYTE)m_szRecentExe[v], &dwSize);
|
||||
}
|
||||
|
||||
RegCloseKey(hKey);
|
||||
}
|
||||
}
|
||||
|
@ -168,19 +143,6 @@ WndMain::~WndMain()
|
|||
free(m_szRecentXbe[v]);
|
||||
}
|
||||
|
||||
for(v=0;v<m_dwRecentExe;v++)
|
||||
{
|
||||
char buffer[32];
|
||||
|
||||
sprintf(buffer, "RecentExe%d", v);
|
||||
|
||||
dwType = REG_SZ; dwSize = MAX_PATH;
|
||||
|
||||
RegSetValueEx(hKey, buffer, 0, dwType, (PBYTE)m_szRecentExe[v], dwSize);
|
||||
|
||||
free(m_szRecentExe[v]);
|
||||
}
|
||||
|
||||
dwType = REG_DWORD; dwSize = sizeof(DWORD);
|
||||
RegSetValueEx(hKey, "CxbxDebug", 0, dwType, (PBYTE)&m_CxbxDebug, dwSize);
|
||||
|
||||
|
@ -190,12 +152,6 @@ WndMain::~WndMain()
|
|||
dwType = REG_DWORD; dwSize = sizeof(DWORD);
|
||||
RegSetValueEx(hKey, "RecentXbe", 0, dwType, (PBYTE)&m_dwRecentXbe, dwSize);
|
||||
|
||||
dwType = REG_DWORD; dwSize = sizeof(DWORD);
|
||||
RegSetValueEx(hKey, "RecentExe", 0, dwType, (PBYTE)&m_dwRecentExe, dwSize);
|
||||
|
||||
dwType = REG_DWORD; dwSize = sizeof(DWORD);
|
||||
RegSetValueEx(hKey, "AutoConvertToExe", 0, dwType, (PBYTE)&m_AutoConvertToExe, dwSize);
|
||||
|
||||
dwType = REG_SZ; dwSize = MAX_PATH;
|
||||
RegSetValueEx(hKey, "CxbxDebugFilename", 0, dwType, (PBYTE)m_CxbxDebugFilename, dwSize);
|
||||
|
||||
|
@ -207,10 +163,8 @@ WndMain::~WndMain()
|
|||
// cleanup allocations
|
||||
{
|
||||
delete m_Xbe;
|
||||
delete m_Exe;
|
||||
|
||||
free(m_XbeFilename);
|
||||
free(m_ExeFilename);
|
||||
|
||||
free(m_CxbxDebugFilename);
|
||||
free(m_KrnlDebugFilename);
|
||||
|
@ -413,7 +367,7 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP
|
|||
if(m_Xbe != 0 && (m_hwndChild == NULL) && m_bCanStart)
|
||||
{
|
||||
m_bCanStart = false;
|
||||
StartEmulation(m_AutoConvertToExe, hwnd);
|
||||
StartEmulation(hwnd);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -489,42 +443,6 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP
|
|||
SaveXbeAs();
|
||||
break;
|
||||
|
||||
case ID_FILE_IMPORTFROMEXE:
|
||||
{
|
||||
m_ExeFilename[0] = '\0';
|
||||
|
||||
OPENFILENAME ofn = {0};
|
||||
|
||||
char filename[MAX_PATH] = {0};
|
||||
|
||||
ofn.lStructSize = sizeof(OPENFILENAME);
|
||||
ofn.hwndOwner = m_hwnd;
|
||||
ofn.lpstrFilter = "Windows Executables (*.exe)\0*.exe\0";
|
||||
ofn.lpstrFile = filename;
|
||||
ofn.nMaxFile = MAX_PATH;
|
||||
ofn.nFilterIndex = 1;
|
||||
ofn.lpstrFileTitle = NULL;
|
||||
ofn.nMaxFileTitle = 0;
|
||||
ofn.lpstrInitialDir = NULL;
|
||||
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
|
||||
|
||||
if(GetOpenFileName(&ofn) == TRUE)
|
||||
{
|
||||
if(m_Xbe != 0)
|
||||
CloseXbe();
|
||||
|
||||
if(m_Xbe != 0)
|
||||
break;
|
||||
|
||||
ImportExe(ofn.lpstrFile);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ID_FILE_EXPORTTOEXE:
|
||||
ConvertToExe(NULL, true, hwnd);
|
||||
break;
|
||||
|
||||
case ID_FILE_RXBE_0:
|
||||
case ID_FILE_RXBE_1:
|
||||
case ID_FILE_RXBE_2:
|
||||
|
@ -544,7 +462,7 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP
|
|||
|
||||
HMENU menu = GetMenu(m_hwnd);
|
||||
HMENU file_menu = GetSubMenu(menu, 0);
|
||||
HMENU rxbe_menu = GetSubMenu(file_menu, 9);
|
||||
HMENU rxbe_menu = GetSubMenu(file_menu, 6);
|
||||
|
||||
char szBuffer[270];
|
||||
|
||||
|
@ -556,37 +474,6 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP
|
|||
}
|
||||
break;
|
||||
|
||||
case ID_FILE_REXE_0:
|
||||
case ID_FILE_REXE_1:
|
||||
case ID_FILE_REXE_2:
|
||||
case ID_FILE_REXE_3:
|
||||
case ID_FILE_REXE_4:
|
||||
case ID_FILE_REXE_5:
|
||||
case ID_FILE_REXE_6:
|
||||
case ID_FILE_REXE_7:
|
||||
case ID_FILE_REXE_8:
|
||||
case ID_FILE_REXE_9:
|
||||
{
|
||||
if(m_Xbe != 0)
|
||||
CloseXbe();
|
||||
|
||||
if(m_Xbe != 0)
|
||||
break;
|
||||
|
||||
HMENU menu = GetMenu(m_hwnd);
|
||||
HMENU file_menu = GetSubMenu(menu, 0);
|
||||
HMENU rexe_menu = GetSubMenu(file_menu, 10);
|
||||
|
||||
char szBuffer[270];
|
||||
|
||||
GetMenuString(rexe_menu, LOWORD(wParam), szBuffer, 269, MF_BYCOMMAND);
|
||||
|
||||
char *szFilename = (char*)((uint32)szBuffer + 5);
|
||||
|
||||
ImportExe(szFilename);
|
||||
}
|
||||
break;
|
||||
|
||||
case ID_FILE_EXIT:
|
||||
SendMessage(hwnd, WM_CLOSE, 0, 0);
|
||||
break;
|
||||
|
@ -790,7 +677,6 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP
|
|||
}
|
||||
else
|
||||
{
|
||||
m_bExeChanged = true;
|
||||
m_bXbeChanged = true;
|
||||
|
||||
LoadLogo();
|
||||
|
@ -810,7 +696,6 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP
|
|||
|
||||
case ID_EDIT_PATCH_ALLOW64MB:
|
||||
{
|
||||
m_bExeChanged = true;
|
||||
m_bXbeChanged = true;
|
||||
|
||||
m_Xbe->m_Header.dwInitFlags.bLimit64MB = !m_Xbe->m_Header.dwInitFlags.bLimit64MB;
|
||||
|
@ -826,7 +711,6 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP
|
|||
|
||||
case ID_EDIT_PATCH_DEBUGMODE:
|
||||
{
|
||||
m_bExeChanged = true;
|
||||
m_bXbeChanged = true;
|
||||
|
||||
// patch to/from debug mode
|
||||
|
@ -957,8 +841,6 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP
|
|||
|
||||
MessageBox(m_hwnd, "This will not take effect until the next time emulation is started.\n", "Cxbx-Reloaded", MB_OK);
|
||||
|
||||
m_bExeChanged = true;
|
||||
|
||||
RefreshMenus();
|
||||
|
||||
UpdateDebugConsoles();
|
||||
|
@ -999,8 +881,6 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP
|
|||
|
||||
strncpy(m_KrnlDebugFilename, ofn.lpstrFile, MAX_PATH-1);
|
||||
|
||||
m_bExeChanged = true;
|
||||
|
||||
m_KrnlDebug = DM_FILE;
|
||||
|
||||
RefreshMenus();
|
||||
|
@ -1068,37 +948,13 @@ LRESULT CALLBACK WndMain::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP
|
|||
break;
|
||||
|
||||
case ID_EMULATION_START:
|
||||
StartEmulation(m_AutoConvertToExe, hwnd);
|
||||
StartEmulation(hwnd);
|
||||
break;
|
||||
|
||||
case ID_EMULATION_STOP:
|
||||
StopEmulation();
|
||||
break;
|
||||
|
||||
case ID_SETTINGS_GENWT:
|
||||
{
|
||||
m_AutoConvertToExe = AUTO_CONVERT_WINDOWS_TEMP;
|
||||
|
||||
RefreshMenus();
|
||||
}
|
||||
break;
|
||||
|
||||
case ID_SETTINGS_GENXP:
|
||||
{
|
||||
m_AutoConvertToExe = AUTO_CONVERT_XBE_PATH;
|
||||
|
||||
RefreshMenus();
|
||||
}
|
||||
break;
|
||||
|
||||
case ID_SETTINGS_GENMA:
|
||||
{
|
||||
m_AutoConvertToExe = AUTO_CONVERT_MANUAL;
|
||||
|
||||
RefreshMenus();
|
||||
}
|
||||
break;
|
||||
|
||||
case ID_HELP_ABOUT:
|
||||
{
|
||||
WndAbout *AboutWnd = new WndAbout(m_hInstance, m_hwnd);
|
||||
|
@ -1239,27 +1095,15 @@ void WndMain::RefreshMenus()
|
|||
|
||||
// enable/disable save .xbe file as
|
||||
EnableMenuItem(file_menu, ID_FILE_SAVEXBEFILEAS, MF_BYCOMMAND | ((m_Xbe == 0) ? MF_GRAYED : MF_ENABLED));
|
||||
|
||||
// enable/disable export to .exe
|
||||
EnableMenuItem(file_menu, ID_FILE_EXPORTTOEXE, MF_BYCOMMAND | ((m_Xbe == 0) ? MF_GRAYED : MF_ENABLED));
|
||||
|
||||
|
||||
// recent xbe files menu
|
||||
{
|
||||
HMENU rxbe_menu = GetSubMenu(file_menu, 9);
|
||||
HMENU rxbe_menu = GetSubMenu(file_menu, 6);
|
||||
|
||||
int max = m_dwRecentXbe;
|
||||
for(int v=0;v<max;v++)
|
||||
EnableMenuItem(rxbe_menu, ID_FILE_RXBE_0 + v, MF_BYCOMMAND | MF_ENABLED);
|
||||
}
|
||||
|
||||
// recent exe files menu
|
||||
{
|
||||
HMENU rexe_menu = GetSubMenu(file_menu, 10);
|
||||
|
||||
int max = m_dwRecentExe;
|
||||
for(int v=0;v<max;v++)
|
||||
EnableMenuItem(rexe_menu, ID_FILE_REXE_0 + v, MF_BYCOMMAND | MF_ENABLED);
|
||||
}
|
||||
}
|
||||
|
||||
// edit menu
|
||||
|
@ -1337,32 +1181,6 @@ void WndMain::RefreshMenus()
|
|||
}
|
||||
}
|
||||
|
||||
// settings menu
|
||||
{
|
||||
HMENU sett_menu = GetSubMenu(menu, 3);
|
||||
HMENU auto_menu = GetSubMenu(sett_menu, 4);
|
||||
|
||||
// check appropriate choice
|
||||
if(m_AutoConvertToExe == AUTO_CONVERT_WINDOWS_TEMP)
|
||||
{
|
||||
CheckMenuItem(auto_menu, ID_SETTINGS_GENWT, MF_BYCOMMAND | MF_CHECKED);
|
||||
CheckMenuItem(auto_menu, ID_SETTINGS_GENXP, MF_BYCOMMAND | MF_UNCHECKED);
|
||||
CheckMenuItem(auto_menu, ID_SETTINGS_GENMA, MF_BYCOMMAND | MF_UNCHECKED);
|
||||
}
|
||||
else if(m_AutoConvertToExe == AUTO_CONVERT_XBE_PATH)
|
||||
{
|
||||
CheckMenuItem(auto_menu, ID_SETTINGS_GENWT, MF_BYCOMMAND | MF_UNCHECKED);
|
||||
CheckMenuItem(auto_menu, ID_SETTINGS_GENXP, MF_BYCOMMAND | MF_CHECKED);
|
||||
CheckMenuItem(auto_menu, ID_SETTINGS_GENMA, MF_BYCOMMAND | MF_UNCHECKED);
|
||||
}
|
||||
else
|
||||
{
|
||||
CheckMenuItem(auto_menu, ID_SETTINGS_GENWT, MF_BYCOMMAND | MF_UNCHECKED);
|
||||
CheckMenuItem(auto_menu, ID_SETTINGS_GENXP, MF_BYCOMMAND | MF_UNCHECKED);
|
||||
CheckMenuItem(auto_menu, ID_SETTINGS_GENMA, MF_BYCOMMAND | MF_CHECKED);
|
||||
}
|
||||
}
|
||||
|
||||
// emulation menu
|
||||
{
|
||||
HMENU emul_menu = GetSubMenu(menu, 4);
|
||||
|
@ -1417,8 +1235,7 @@ void WndMain::UpdateDebugConsoles()
|
|||
void WndMain::UpdateRecentFiles()
|
||||
{
|
||||
HMENU FileMenu = GetSubMenu(GetMenu(m_hwnd), 0);
|
||||
HMENU RXbeMenu = GetSubMenu(FileMenu, 9);
|
||||
HMENU RExeMenu = GetSubMenu(FileMenu, 10);
|
||||
HMENU RXbeMenu = GetSubMenu(FileMenu, 6);
|
||||
|
||||
// clear existing menu items
|
||||
{
|
||||
|
@ -1427,10 +1244,6 @@ void WndMain::UpdateRecentFiles()
|
|||
max = GetMenuItemCount(RXbeMenu);
|
||||
for(v=0;v<max;v++)
|
||||
RemoveMenu(RXbeMenu, 0, MF_BYPOSITION);
|
||||
|
||||
max = GetMenuItemCount(RExeMenu);
|
||||
for(v=0;v<max;v++)
|
||||
RemoveMenu(RExeMenu, 0, MF_BYPOSITION);
|
||||
}
|
||||
|
||||
// insert recent xbe files
|
||||
|
@ -1453,27 +1266,6 @@ void WndMain::UpdateRecentFiles()
|
|||
AppendMenu(RXbeMenu, MF_STRING, ID_FILE_RXBE_0 + v, szBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
// insert recent exe files
|
||||
{
|
||||
char szBuffer[270];
|
||||
|
||||
int max = m_dwRecentExe;
|
||||
|
||||
// if there are no recent files, throw in a disabled "(none)"
|
||||
if(max == 0)
|
||||
{
|
||||
AppendMenu(RExeMenu, MF_STRING, ID_FILE_REXE_0, "(none)");
|
||||
EnableMenuItem(RExeMenu, ID_FILE_REXE_0, MF_BYCOMMAND | MF_GRAYED);
|
||||
}
|
||||
|
||||
// NOTE: Resource defines ID_FILE_REXE_0 through ID_FILE_REXE_9 must be in order
|
||||
for(int v=0;v<max;v++)
|
||||
{
|
||||
sprintf(szBuffer, "&%d : %s", v, m_szRecentExe[v]);
|
||||
AppendMenu(RExeMenu, MF_STRING, ID_FILE_REXE_0 + v, szBuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// open an xbe file
|
||||
|
@ -1482,8 +1274,6 @@ void WndMain::OpenXbe(const char *x_filename)
|
|||
if(m_Xbe != 0)
|
||||
return;
|
||||
|
||||
m_ExeFilename[0] = '\0';
|
||||
|
||||
strcpy(m_XbeFilename, x_filename);
|
||||
|
||||
m_Xbe = new Xbe(m_XbeFilename);
|
||||
|
@ -1656,160 +1446,8 @@ void WndMain::SaveXbeAs()
|
|||
SaveXbe(ofn.lpstrFile);
|
||||
}
|
||||
|
||||
// import an exe file
|
||||
void WndMain::ImportExe(const char *x_filename)
|
||||
{
|
||||
m_XbeFilename[0] = '\0';
|
||||
|
||||
Exe *i_exe = new Exe(x_filename);
|
||||
|
||||
if(i_exe->GetError() != 0)
|
||||
{
|
||||
MessageBox(m_hwnd, i_exe->GetError(), "Cxbx-Reloaded", MB_ICONSTOP | MB_OK);
|
||||
|
||||
delete i_exe;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
m_Xbe = new Xbe(i_exe, "Untitled", true);
|
||||
|
||||
if(m_Xbe->GetError() != 0)
|
||||
{
|
||||
MessageBox(m_hwnd, m_Xbe->GetError(), "Cxbx-Reloaded", MB_ICONSTOP | MB_OK);
|
||||
|
||||
delete m_Xbe; m_Xbe = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// save this exe to the list of recent exe files
|
||||
if(m_ExeFilename[0] != '\0')
|
||||
{
|
||||
bool found = false;
|
||||
|
||||
// if this filename already exists, temporarily remove it
|
||||
for(int c=0, r=0;c<m_dwRecentExe;c++, r++)
|
||||
{
|
||||
if(strcmp(m_szRecentExe[c], m_ExeFilename) == 0)
|
||||
{
|
||||
found = true;
|
||||
r++;
|
||||
}
|
||||
|
||||
if(r != c)
|
||||
{
|
||||
if(m_szRecentExe[r] == 0 || r > m_dwRecentExe - 1)
|
||||
m_szRecentExe[c] = 0;
|
||||
else
|
||||
strncpy(m_szRecentExe[c], m_szRecentExe[r], MAX_PATH-1);
|
||||
}
|
||||
}
|
||||
|
||||
if(found)
|
||||
m_dwRecentExe--;
|
||||
|
||||
// move all items down one, removing the last one if necessary
|
||||
for(int v=RECENT_EXE_SIZE-1;v>0;v--)
|
||||
{
|
||||
if(m_szRecentExe[v-1] == 0)
|
||||
m_szRecentExe[v] = 0;
|
||||
else
|
||||
{
|
||||
if(m_szRecentExe[v] == 0)
|
||||
m_szRecentExe[v] = (char*)calloc(1, MAX_PATH);
|
||||
strncpy(m_szRecentExe[v], m_szRecentExe[v-1], MAX_PATH-1);
|
||||
}
|
||||
}
|
||||
|
||||
// add new item as first index
|
||||
{
|
||||
if(m_szRecentExe[0] == 0)
|
||||
m_szRecentExe[0] = (char*)calloc(1, MAX_PATH);
|
||||
|
||||
strcpy(m_szRecentExe[0], m_ExeFilename);
|
||||
}
|
||||
|
||||
if(m_dwRecentExe < RECENT_EXE_SIZE)
|
||||
m_dwRecentExe++;
|
||||
}
|
||||
|
||||
UpdateRecentFiles();
|
||||
|
||||
XbeLoaded();
|
||||
|
||||
m_bExeChanged = true;
|
||||
}
|
||||
|
||||
// convert to exe file
|
||||
bool WndMain::ConvertToExe(const char *x_filename, bool x_bVerifyIfExists, HWND hwndParent)
|
||||
{
|
||||
char filename[MAX_PATH] = "default.exe";
|
||||
|
||||
if(x_filename == NULL)
|
||||
{
|
||||
OPENFILENAME ofn = {0};
|
||||
|
||||
SuggestFilename(m_XbeFilename, filename, ".exe");
|
||||
|
||||
ofn.lStructSize = sizeof(OPENFILENAME);
|
||||
ofn.hwndOwner = m_hwnd;
|
||||
ofn.lpstrFilter = "Windows Executables (*.exe)\0*.exe\0";
|
||||
ofn.lpstrFile = filename;
|
||||
ofn.nMaxFile = MAX_PATH;
|
||||
ofn.nFilterIndex = 1;
|
||||
ofn.lpstrFileTitle = NULL;
|
||||
ofn.nMaxFileTitle = 0;
|
||||
ofn.lpstrInitialDir = NULL;
|
||||
ofn.lpstrDefExt = "exe";
|
||||
ofn.Flags = OFN_PATHMUSTEXIST;
|
||||
|
||||
if(GetSaveFileName(&ofn) == FALSE)
|
||||
return false;
|
||||
|
||||
strcpy(filename, ofn.lpstrFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(filename, x_filename);
|
||||
}
|
||||
|
||||
// ask permission to overwrite if this file already exists
|
||||
if(x_bVerifyIfExists)
|
||||
{
|
||||
if(_access(filename, 0) != -1)
|
||||
{
|
||||
if(MessageBox(m_hwnd, "Overwrite existing file?", "Cxbx-Reloaded", MB_ICONQUESTION | MB_YESNO) != IDYES)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// convert file
|
||||
{
|
||||
EmuExe i_EmuExe(m_Xbe, m_KrnlDebug, m_KrnlDebugFilename, hwndParent);
|
||||
|
||||
i_EmuExe.Export(filename);
|
||||
|
||||
if(i_EmuExe.GetError() != 0)
|
||||
{
|
||||
MessageBox(m_hwnd, i_EmuExe.GetError(), "Cxbx-Reloaded", MB_ICONSTOP | MB_OK);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(m_ExeFilename, filename);
|
||||
|
||||
printf("WndMain: %s was converted to .exe.\n", m_Xbe->m_szAsciiTitle);
|
||||
|
||||
m_bExeChanged = false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// start emulation
|
||||
void WndMain::StartEmulation(EnumAutoConvert x_AutoConvert, HWND hwndParent)
|
||||
void WndMain::StartEmulation(HWND hwndParent)
|
||||
{
|
||||
char szBuffer[MAX_PATH];
|
||||
|
||||
|
|
|
@ -35,24 +35,12 @@
|
|||
#define WNDMAIN_H
|
||||
|
||||
#include "Wnd.h"
|
||||
#include "Common/Exe.h"
|
||||
#include "Common/Xbe.h"
|
||||
|
||||
// ******************************************************************
|
||||
// * constants
|
||||
// ******************************************************************
|
||||
#define RECENT_XBE_SIZE 10
|
||||
#define RECENT_EXE_SIZE 10
|
||||
|
||||
// ******************************************************************
|
||||
// * AutoConvert methods
|
||||
// ******************************************************************
|
||||
enum EnumAutoConvert
|
||||
{
|
||||
AUTO_CONVERT_MANUAL = 0,
|
||||
AUTO_CONVERT_XBE_PATH = 1,
|
||||
AUTO_CONVERT_WINDOWS_TEMP = 2
|
||||
};
|
||||
|
||||
// ******************************************************************
|
||||
// * class : WndMain
|
||||
|
@ -77,15 +65,9 @@ class WndMain : public Wnd
|
|||
void SaveXbeAs();
|
||||
|
||||
// ******************************************************************
|
||||
// * Exe operations
|
||||
// * start emulation
|
||||
// ******************************************************************
|
||||
void ImportExe(const char *x_filename);
|
||||
bool ConvertToExe(const char *x_filename, bool x_bVerifyIfExists, HWND hwndParent);
|
||||
|
||||
// ******************************************************************
|
||||
// * start emulation (converting to .exe if not done already)
|
||||
// ******************************************************************
|
||||
void StartEmulation(EnumAutoConvert x_bAutoConvert, HWND hwndParent);
|
||||
void StartEmulation(HWND hwndParent);
|
||||
|
||||
// ******************************************************************
|
||||
// * stop emulation (close existing child window)
|
||||
|
@ -139,46 +121,32 @@ class WndMain : public Wnd
|
|||
HBITMAP m_LogoBmp;
|
||||
|
||||
// ******************************************************************
|
||||
// * Xbe/Exe objects
|
||||
// * Xbe objects
|
||||
// ******************************************************************
|
||||
Xbe *m_Xbe;
|
||||
Exe *m_Exe;
|
||||
|
||||
// ******************************************************************
|
||||
// * changes remembered for internal purposes
|
||||
// ******************************************************************
|
||||
bool m_bXbeChanged;
|
||||
bool m_bExeChanged;
|
||||
bool m_bCanStart;
|
||||
|
||||
// ******************************************************************
|
||||
// * cached filenames
|
||||
// ******************************************************************
|
||||
char *m_XbeFilename;
|
||||
char *m_ExeFilename;
|
||||
|
||||
// ******************************************************************
|
||||
// * cached child window handle
|
||||
// ******************************************************************
|
||||
HWND m_hwndChild;
|
||||
|
||||
// ******************************************************************
|
||||
// * should emulation always auto-create the .exe?
|
||||
// ******************************************************************
|
||||
EnumAutoConvert m_AutoConvertToExe;
|
||||
|
||||
// ******************************************************************
|
||||
// * Recent Xbe files
|
||||
// ******************************************************************
|
||||
int m_dwRecentXbe;
|
||||
char *m_szRecentXbe[RECENT_XBE_SIZE];
|
||||
|
||||
// ******************************************************************
|
||||
// * Recent Exe files
|
||||
// ******************************************************************
|
||||
int m_dwRecentExe;
|
||||
char *m_szRecentExe[RECENT_EXE_SIZE];
|
||||
|
||||
// ******************************************************************
|
||||
// * is this window fully initialized?
|
||||
// ******************************************************************
|
||||
|
|
|
@ -1,277 +0,0 @@
|
|||
// ******************************************************************
|
||||
// *
|
||||
// * .,-::::: .,:: .::::::::. .,:: .:
|
||||
// * ,;;;'````' `;;;, .,;; ;;;'';;' `;;;, .,;;
|
||||
// * [[[ '[[,,[[' [[[__[[\. '[[,,[['
|
||||
// * $$$ Y$$$P $$""""Y$$ Y$$$P
|
||||
// * `88bo,__,o, oP"``"Yo, _88o,,od8P oP"``"Yo,
|
||||
// * "YUMMMMMP",m" "Mm,""YUMMMP" ,m" "Mm,
|
||||
// *
|
||||
// * Cxbx->Standard->Cxbe->Main.cpp
|
||||
// *
|
||||
// * 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
|
||||
// *
|
||||
// ******************************************************************
|
||||
#include "Exe.h"
|
||||
#include "Xbe.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
// static global(s)
|
||||
static void ShowUsage();
|
||||
static void MakeUpper(char *str);
|
||||
|
||||
// program entry point
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char szErrorMessage[266] = {0};
|
||||
char szExeFilename[266] = {0};
|
||||
char szXbeFilename[266] = {0};
|
||||
char szDumpFilename[266] = {0};
|
||||
char szXbeTitle[256] = "Untitled";
|
||||
bool bRetail = true;
|
||||
|
||||
// parse command line
|
||||
for(int v=1;v<argc;v++)
|
||||
{
|
||||
char *szOption = 0;
|
||||
char *szParam = 0;
|
||||
uint dwParamSize = 0;
|
||||
|
||||
// if this isn't an option, it must be the Exe file
|
||||
if(argv[v][0] != '-')
|
||||
{
|
||||
strncpy(szExeFilename, argv[v], 265);
|
||||
continue;
|
||||
}
|
||||
|
||||
// locate the colon and seperate option / parameters
|
||||
{
|
||||
uint dwColon = (uint)-1;
|
||||
|
||||
for(uint c=1;argv[v][c] != 0;c++)
|
||||
{
|
||||
if(argv[v][c] == ':')
|
||||
{
|
||||
dwColon = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(dwColon == (uint)-1)
|
||||
{
|
||||
strcpy(szErrorMessage, "Command line format error");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
argv[v][dwColon] = '\0';
|
||||
|
||||
szOption = &argv[v][1];
|
||||
szParam = &argv[v][dwColon + 1];
|
||||
|
||||
while(szParam[dwParamSize] != 0)
|
||||
dwParamSize++;
|
||||
}
|
||||
|
||||
// interpret the current switch
|
||||
{
|
||||
char szOptionU[266] = {0};
|
||||
char szParamU[266] = {0};
|
||||
|
||||
strncpy(szOptionU, szOption, 265);
|
||||
strncpy(szParamU, szParam, 265);
|
||||
|
||||
MakeUpper(szOptionU);
|
||||
MakeUpper(szParamU);
|
||||
|
||||
if(strcmp(szOptionU, "OUT") == 0)
|
||||
{
|
||||
strcpy(szXbeFilename, szParam);
|
||||
}
|
||||
else if(strcmp(szOptionU, "DUMPINFO") == 0)
|
||||
{
|
||||
strcpy(szDumpFilename, szParam);
|
||||
}
|
||||
else if(strcmp(szOptionU, "TITLE") == 0)
|
||||
{
|
||||
if(dwParamSize > 256)
|
||||
printf("WARNING: Title too long, using default title\n");
|
||||
else
|
||||
strcpy(szXbeTitle, szParam);
|
||||
}
|
||||
else if(strcmp(szOptionU, "MODE") == 0)
|
||||
{
|
||||
if(strcmp(szParamU, "RETAIL") == 0)
|
||||
bRetail = true;
|
||||
else if(strcmp(szParamU, "DEBUG") == 0)
|
||||
bRetail = false;
|
||||
else
|
||||
{
|
||||
strcpy(szErrorMessage, "invalid MODE");
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
char szBuffer[255];
|
||||
sprintf(szBuffer, "Unrecognized command : %s", szOption);
|
||||
strcpy(szErrorMessage, szBuffer);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// verify we recieved the required parameters
|
||||
if(szExeFilename[0] == '\0')
|
||||
{
|
||||
ShowUsage();
|
||||
return 1;
|
||||
}
|
||||
|
||||
// if we don't have an Xbe filename, generate one from szExeFilename
|
||||
if(szXbeFilename[0] == '\0')
|
||||
{
|
||||
strcpy(szXbeFilename, szExeFilename);
|
||||
|
||||
char *szFilename = &szXbeFilename[0];
|
||||
|
||||
// locate last \ or / (if there are any)
|
||||
{
|
||||
for(int c=0;szXbeFilename[c] != 0;c++)
|
||||
if(szXbeFilename[c] == '\\' || szXbeFilename[c] == '/')
|
||||
szFilename = &szXbeFilename[c+1];
|
||||
}
|
||||
|
||||
// locate and remove last . (if there are any)
|
||||
{
|
||||
char szWorkingU[266];
|
||||
|
||||
char *szWorking = szFilename;
|
||||
|
||||
strncpy(szWorkingU, szWorking, 265);
|
||||
|
||||
for(int c=0;szFilename[c] != 0;c++)
|
||||
if(szFilename[c] == '.')
|
||||
szWorking = &szFilename[c];
|
||||
|
||||
MakeUpper(szWorking);
|
||||
|
||||
if(strcmp(szWorkingU, ".exe") == 0)
|
||||
strcpy(szWorking, ".xbe");
|
||||
else
|
||||
strcat(szXbeFilename, ".xbe");
|
||||
}
|
||||
}
|
||||
|
||||
// open and convert Exe file
|
||||
{
|
||||
Exe *ExeFile = new Exe(szExeFilename);
|
||||
|
||||
if(ExeFile->GetError() != 0)
|
||||
{
|
||||
strcpy(szErrorMessage, ExeFile->GetError());
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
Xbe *XbeFile = new Xbe(ExeFile, szXbeTitle, bRetail);
|
||||
|
||||
if(XbeFile->GetError() != 0)
|
||||
{
|
||||
strcpy(szErrorMessage, XbeFile->GetError());
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if(szDumpFilename[0] != 0)
|
||||
{
|
||||
FILE *outfile = fopen(szDumpFilename, "wt");
|
||||
XbeFile->DumpInformation(outfile);
|
||||
fclose(outfile);
|
||||
|
||||
if(XbeFile->GetError() != 0)
|
||||
{
|
||||
if(XbeFile->IsFatal())
|
||||
{
|
||||
strcpy(szErrorMessage, XbeFile->GetError());
|
||||
goto cleanup;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("DUMPINFO -> Warning: %s\n", XbeFile->GetError());
|
||||
XbeFile->ClearError();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
XbeFile->Export(szXbeFilename);
|
||||
|
||||
if(XbeFile->GetError() != 0)
|
||||
{
|
||||
strcpy(szErrorMessage, XbeFile->GetError());
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
cleanup:
|
||||
|
||||
if(szErrorMessage[0] != 0)
|
||||
{
|
||||
ShowUsage();
|
||||
|
||||
printf("\n");
|
||||
printf(" * Error : %s\n", szErrorMessage);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// show program usage
|
||||
static void ShowUsage()
|
||||
{
|
||||
printf
|
||||
(
|
||||
"CXBE XBE->EXE (XBox->Win32) Relinker (CXBX Core Version " _CXBX_VERSION ")\n"
|
||||
"Copyright (C) Aaron Robinson 2002-2003. All rights reserved.\n"
|
||||
"\n"
|
||||
"Usage : cxbe [options] [exefile]\n"
|
||||
"\n"
|
||||
"Options :\n"
|
||||
"\n"
|
||||
" -OUT:filename\n"
|
||||
" -DUMPINFO:filename\n"
|
||||
" -TITLE:title\n"
|
||||
" -MODE:{debug|retail}\n"
|
||||
);
|
||||
}
|
||||
|
||||
// convert string to upper case
|
||||
static void MakeUpper(char *str)
|
||||
{
|
||||
while(*str != '\0')
|
||||
{
|
||||
if(*str >= 'a' && *str <= 'z')
|
||||
*str = *str - ('a' - 'A');
|
||||
|
||||
str++;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue