Merge pull request #50 from x1nixmzeng/remove-exe-support

Removed all EXE support
This commit is contained in:
Luke Usher 2016-12-22 05:10:25 +00:00 committed by GitHub
commit ece663f6fe
12 changed files with 22 additions and 2008 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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