Added support to load dsp images from xbe sections

This commit is contained in:
ergo720 2021-06-10 19:39:42 +02:00
parent c7bf62ce62
commit d847580881
4 changed files with 56 additions and 55 deletions

View File

@ -698,19 +698,6 @@ uint8_t *Xbe::GetLogoBitmap(uint32_t x_dwSize)
return 0;
}
void *Xbe::FindSection(char *zsSectionName)
{
for (uint32_t v = 0; v < m_Header.dwSections; v++) {
if (strcmp(m_szSectionName[v], zsSectionName) == 0) {
if (m_SectionHeader[v].dwVirtualAddr > 0 && m_SectionHeader[v].dwVirtualSize > 0) {
return m_bzSection[v];
}
}
}
return nullptr;
}
void* Xbe::FindSection(xbox::PXBEIMAGE_SECTION section)
{
for (uint32_t v = 0; v < m_Header.dwSections; v++) {
@ -827,3 +814,6 @@ XbeType Xbe::GetXbeType()
// Otherwise, the XBE is a Retail build :
return XbeType::xtRetail;
}
template auto Xbe::FindSection<true>(const char *zsSectionName);
template auto Xbe::FindSection<false>(const char *zsSectionName);

View File

@ -55,7 +55,8 @@ class Xbe : public Error
~Xbe();
// find an section by name
void *FindSection(char *zsSectionName);
template<bool want_pxbe_ret>
auto FindSection(const char *zsSectionName);
// Find a section by its definition
void* FindSection(xbox::PXBEIMAGE_SECTION section);
@ -356,6 +357,37 @@ class Xbe : public Error
*m_xprImage;
};
template<bool want_pxbe_ret>
auto Xbe::FindSection(const char *zsSectionName)
{
if constexpr (want_pxbe_ret) { // returns a ptr to xbe section of xbe loaded in placeholder memory
xbox::PXBEIMAGE_SECTION sectionHeaders = (xbox::PXBEIMAGE_SECTION)m_Header.dwSectionHeadersAddr;
for (uint32_t v = 0; v < m_Header.dwSections; v++) {
if (strcmp(sectionHeaders[v].SectionName, zsSectionName) == 0) {
if (m_SectionHeader[v].dwVirtualAddr > 0 && m_SectionHeader[v].dwVirtualSize > 0) {
return &sectionHeaders[v];
}
}
}
return static_cast<xbox::PXBEIMAGE_SECTION>(nullptr);
}
else { // returns a ptr to xbe section of xbe loaded by this class
for (uint32_t v = 0; v < m_Header.dwSections; v++) {
if (strcmp(m_szSectionName[v], zsSectionName) == 0) {
if (m_SectionHeader[v].dwVirtualAddr > 0 && m_SectionHeader[v].dwVirtualSize > 0) {
return static_cast<void *>(m_bzSection[v]);
}
}
}
return static_cast<void *>(nullptr);
}
}
extern template auto Xbe::FindSection<true>(const char *zsSectionName);
extern template auto Xbe::FindSection<false>(const char *zsSectionName);
// debug/retail XOR keys
const uint32_t XOR_EP_DEBUG = 0x94859D4B; // Entry Point (Debug)
const uint32_t XOR_EP_RETAIL = 0xA8FC57AB; // Entry Point (Retail)

View File

@ -115,54 +115,28 @@ xbox::hresult_xt WINAPI xbox::EMUPATCH(XAudioDownloadEffectsImage)
LOG_FUNC_ARG(ppImageDesc)
LOG_FUNC_END;
LOG_INCOMPLETE();
xbox::hresult_xt result = S_OK;
xbox::hresult_xt result = E_FAIL;
if (ppImageDesc) { //only process image section/file which the guest code asks for ImageDesc.
PBYTE pvImageBuffer;
dword_xt dwImageSize;
if (dwFlags & 1) { // dwFlags == XAUDIO_DOWNLOADFX_XBESECTION, The DSP effects image is located in a section of the XBE.
/*
//future code for loading imgae from XBE section. these codes are reversd from PGR2.
PXBEIMAGE_SECTION pImageSectionHandle=XGetSectionHandle(pszImageName); //get section handle by section name, not implemented yet.
// perhaps use pImageSectionHandle = CxbxKrnl_Xbe->FindSection(pszImageName); will be easier.
if (XeLoadSection(pImageSectionHandle) > 0) { //load section handle and get the loaded address.
//note this sction must be freed after the internal image bacup and ImageDesc was created.
//EmuKnrlXe.cpp implements XeLoadSection(). could reference that code.
pvImageBuffer = pImageSectionHandle->VirtualAddress;
if (dwFlags & 1) { // load from xbe section. Test case: Halo 2
PXBEIMAGE_SECTION pSection = CxbxKrnl_Xbe->FindSection<true>(pszImageName);
if (pSection != nullptr) {
if (XeLoadSection(pSection) == xbox::status_success) {
result = xbox::EMUPATCH(CDirectSound_DownloadEffectsImage)(zeroptr, pSection->VirtualAddress, pSection->VirtualSize, pImageLoc, ppImageDesc);
XeUnloadSection(pSection);
}
}
dwImageSize=pImageSectionHandle->VirtualSize; //get section size by section handle.
result = xbox::EMUPATCH(CDirectSound_DownloadEffectsImage)(pThis_tmp, pvImageBuffer,dwImageSize,pImageLoc,ppImageDesc);
if(pImageSectionHandle<>0 && pImageSectionHandle!=-1)
XeUnloadSection(pImageSectionHandle);
*/
LOG_TEST_CASE("Loading dsp images from xbe sections is currently not yet supported");
result = S_OK;//this line should be removed once the section loading code was implemented.
}
else { // load from file
LPDIRECTSOUND8 pThis_tmp = zeroptr;
HANDLE hFile;
// using xbox::NtCreateFile() directly instead of Host CreateFile();
OBJECT_ATTRIBUTES obj;
ANSI_STRING file_name;
IO_STATUS_BLOCK io_status_block;
RtlInitAnsiString(&file_name, pszImageName);
XB_InitializeObjectAttributes(&obj, &file_name, obj_case_insensitive, ObDosDevicesDirectory());
ntstatus_xt NtStatusCreateFile;
//LARGE_INTEGER tmp_LargeInt;
//tmp_LargeInt.QuadPart= dwImageSize;
NtStatusCreateFile = NtCreateFile(
HANDLE hFile;
ntstatus_xt NtStatusCreateFile = NtCreateFile(
&hFile,
FILE_GENERIC_READ, // FILE_READ_DATA, GENERIC_READ, DesiredAccess,
&obj,
@ -194,6 +168,8 @@ xbox::hresult_xt WINAPI xbox::EMUPATCH(XAudioDownloadEffectsImage)
&FileStdInfo, // FileInformation
sizeof(FILE_STANDARD_INFORMATION),
FileStandardInformation); // FileInformationClass; Enumation of the file information class.
dword_xt dwImageSize;
if (NtStatusQueryInfoFile >= 0) {
dwImageSize = FileStdInfo.EndOfFile.u.LowPart;
}
@ -203,7 +179,7 @@ xbox::hresult_xt WINAPI xbox::EMUPATCH(XAudioDownloadEffectsImage)
}
if (dwImageSize > 0) { //proceed the process only if the file size > 0
pvImageBuffer = new BYTE[dwImageSize]; //allocate buffer to read in to image file.
PBYTE pvImageBuffer = new BYTE[dwImageSize]; //allocate buffer to read in to image file.
//use NtReadFile() to replace host CreatFile();
ntstatus_xt NtStatusReadFile = NtReadFile(
@ -238,7 +214,7 @@ xbox::hresult_xt WINAPI xbox::EMUPATCH(XAudioDownloadEffectsImage)
}
if (dwBytesRead == dwImageSize) { // only process the image if the whole image was read successfully.
result = xbox::EMUPATCH(CDirectSound_DownloadEffectsImage)(pThis_tmp, pvImageBuffer,dwImageSize,pImageLoc,ppImageDesc);
result = xbox::EMUPATCH(CDirectSound_DownloadEffectsImage)(zeroptr, pvImageBuffer,dwImageSize,pImageLoc,ppImageDesc);
}
else {
EmuLog(LOG_LEVEL::WARNING, "%s: Image file NtReadFile read in lenth not enough", __func__);
@ -255,6 +231,9 @@ xbox::hresult_xt WINAPI xbox::EMUPATCH(XAudioDownloadEffectsImage)
}
}
}
else {
result = S_OK;
}
return result;
}

View File

@ -1489,9 +1489,9 @@ typedef struct {
void WndMain::LoadGameLogo()
{
// Export Game Logo bitmap (XTIMAG or XSIMAG)
uint8_t *pSection = (uint8_t *)m_Xbe->FindSection("$$XTIMAGE"); // Check for XTIMAGE
uint8_t *pSection = (uint8_t *)m_Xbe->FindSection<false>("$$XTIMAGE"); // Check for XTIMAGE
if (!pSection) {
pSection = (uint8_t *)m_Xbe->FindSection("$$XSIMAGE"); // if XTIMAGE isn't present, check for XSIMAGE (smaller)
pSection = (uint8_t *)m_Xbe->FindSection<false>("$$XSIMAGE"); // if XTIMAGE isn't present, check for XSIMAGE (smaller)
if (!pSection) {
return;
}