diff --git a/Core/Dialog/PSPDialog.h b/Core/Dialog/PSPDialog.h index d06fe8f9fd..c249750093 100644 --- a/Core/Dialog/PSPDialog.h +++ b/Core/Dialog/PSPDialog.h @@ -30,19 +30,18 @@ const int SCE_ERROR_UTILITY_INVALID_STATUS = 0x80110001; const int SCE_ERROR_UTILITY_INVALID_PARAM_SIZE = 0x80110004; const int SCE_ERROR_UTILITY_WRONG_TYPE = 0x80110005; -typedef struct +struct pspUtilityDialogCommon { - unsigned int size; /** Size of the structure */ - int language; /** Language */ - int buttonSwap; /** Set to 1 for X/O button swap */ - int graphicsThread; /** Graphics thread priority */ - int accessThread; /** Access/fileio thread priority (SceJobThread) */ - int fontThread; /** Font thread priority (ScePafThread) */ - int soundThread; /** Sound thread priority */ - int result; /** Result */ - int reserved[4]; /** Set to 0 */ - -} pspUtilityDialogCommon; + u32_le size; /** Size of the structure */ + s32_le language; /** Language */ + s32_le buttonSwap; /** Set to 1 for X/O button swap */ + s32_le graphicsThread; /** Graphics thread priority */ + s32_le accessThread; /** Access/fileio thread priority (SceJobThread) */ + s32_le fontThread; /** Font thread priority (ScePafThread) */ + s32_le soundThread; /** Sound thread priority */ + s32_le result; /** Result */ + s32_le reserved[4]; /** Set to 0 */ +}; class PSPDialog diff --git a/Core/Dialog/PSPMsgDialog.h b/Core/Dialog/PSPMsgDialog.h index f002d488eb..17c30cf3c8 100644 --- a/Core/Dialog/PSPMsgDialog.h +++ b/Core/Dialog/PSPMsgDialog.h @@ -39,15 +39,15 @@ struct pspMessageDialog { pspUtilityDialogCommon common; - int result; - int type; - unsigned int errorNum; + s32_le result; + s32_le type; + u32_le errorNum; char string[512]; // End of request V1 (Size 572) - unsigned int options; - unsigned int buttonPressed; + u32_le options; + u32_le buttonPressed; // End of request V2 (Size 580) - int unknown[32]; + s32_le unknown[32]; // End of request V3 (Size 708) }; diff --git a/Core/Dialog/PSPOskDialog.cpp b/Core/Dialog/PSPOskDialog.cpp index 954a119e05..82aef20580 100755 --- a/Core/Dialog/PSPOskDialog.cpp +++ b/Core/Dialog/PSPOskDialog.cpp @@ -126,7 +126,7 @@ PSPOskDialog::PSPOskDialog() : PSPDialog() { PSPOskDialog::~PSPOskDialog() { } -void PSPOskDialog::ConvertUCS2ToUTF8(std::string& _string, const PSPPointer em_address) +void PSPOskDialog::ConvertUCS2ToUTF8(std::string& _string, const PSPPointer em_address) { if (!em_address.IsValid()) { @@ -839,7 +839,7 @@ int PSPOskDialog::Update() status = SCE_UTILITY_STATUS_SHUTDOWN; } - u16 *outText = oskParams->fields[0].outtext; + u16_le *outText = oskParams->fields[0].outtext; for (u32 i = 0, end = oskParams->fields[0].outtextlength; i < end; ++i) { u16 value = 0; diff --git a/Core/Dialog/PSPOskDialog.h b/Core/Dialog/PSPOskDialog.h index 8dce1fc6a2..29d428dd20 100644 --- a/Core/Dialog/PSPOskDialog.h +++ b/Core/Dialog/PSPOskDialog.h @@ -17,9 +17,9 @@ #pragma once -#include "PSPDialog.h" -#include "../Core/MemMap.h" - +#include "Core/Dialog/PSPDialog.h" +#include "Core/MemMap.h" +#include "Common/CommonTypes.h" /** @@ -91,37 +91,45 @@ enum SceUtilityOskInputType PSP_UTILITY_OSK_INPUTTYPE_URL = 0x00080000 }; +#if COMMON_LITTLE_ENDIAN +typedef SceUtilityOskState SceUtilityOskState_le; +typedef SceUtilityOskInputLanguage SceUtilityOskInputLanguage_le; +typedef SceUtilityOskResult SceUtilityOskResult_le; +#else +#error FIX ME +#endif + /** * OSK Field data */ struct SceUtilityOskData { /** Unknown. Pass 0. */ - int unk_00; + s32_le unk_00; /** Unknown. Pass 0. */ - int unk_04; + s32_le unk_04; /** One of ::SceUtilityOskInputLanguage */ - int language; + SceUtilityOskInputLanguage_le language; /** Unknown. Pass 0. */ - int unk_12; + s32_le unk_12; /** One or more of ::SceUtilityOskInputType (types that are selectable by pressing SELECT) */ - int inputtype; + s32_le inputtype; /** Number of lines */ - int lines; + s32_le lines; /** Unknown. Pass 0. */ - int unk_24; + s32_le unk_24; /** Description text */ - PSPPointer desc; + PSPPointer desc; /** Initial text */ - PSPPointer intext; + PSPPointer intext; // Length, in unsigned shorts, including the terminator. - u32 outtextlength; + u32_le outtextlength; /** Pointer to the output text */ - PSPPointer outtext; + PSPPointer outtext; /** Result. One of ::SceUtilityOskResult */ - int result; + SceUtilityOskResult_le result; // Number of characters to allow, not including terminator (if less than outtextlength - 1.) - u32 outtextlimit; + u32_le outtextlimit; }; // Parameters to sceUtilityOskInitStart @@ -129,12 +137,12 @@ struct SceUtilityOskParams { pspUtilityDialogCommon base; // Number of fields. - int fieldCount; + s32_le fieldCount; // Pointer to an array of fields (see SceUtilityOskData.) PSPPointer fields; - SceUtilityOskState state; + SceUtilityOskState_le state; // Maybe just padding? - int unk_60; + s32_le unk_60; }; @@ -165,7 +173,7 @@ public: virtual pspUtilityDialogCommon *GetCommonParam(); private: - void ConvertUCS2ToUTF8(std::string& _string, const PSPPointer em_address); + void ConvertUCS2ToUTF8(std::string& _string, const PSPPointer em_address); void ConvertUCS2ToUTF8(std::string& _string, const wchar_t *input); void RenderKeyboard(); diff --git a/Core/Dialog/PSPSaveDialog.cpp b/Core/Dialog/PSPSaveDialog.cpp index 8a1819e2fb..613e7080e9 100755 --- a/Core/Dialog/PSPSaveDialog.cpp +++ b/Core/Dialog/PSPSaveDialog.cpp @@ -56,7 +56,7 @@ int PSPSaveDialog::Init(int paramAddr) u32 retval = param.SetPspParam(&request); INFO_LOG(HLE,"sceUtilitySavedataInitStart(%08x)", paramAddr); - INFO_LOG(HLE,"Mode: %i", param.GetPspParam()->mode); + INFO_LOG(HLE,"Mode: %i", (SceUtilitySavedataType)param.GetPspParam()->mode); yesnoChoice = 1; switch (param.GetPspParam()->focus) @@ -164,7 +164,7 @@ int PSPSaveDialog::Init(int paramAddr) break; default: { - ERROR_LOG_REPORT(HLE, "Load/Save function %d not coded. Title: %s Save: %s File: %s", param.GetPspParam()->mode, param.GetGameName(param.GetPspParam()).c_str(), param.GetGameName(param.GetPspParam()).c_str(), param.GetFileName(param.GetPspParam()).c_str()); + ERROR_LOG_REPORT(HLE, "Load/Save function %d not coded. Title: %s Save: %s File: %s", (SceUtilitySavedataType)param.GetPspParam()->mode, param.GetGameName(param.GetPspParam()).c_str(), param.GetGameName(param.GetPspParam()).c_str(), param.GetFileName(param.GetPspParam()).c_str()); param.GetPspParam()->common.result = 0; status = SCE_UTILITY_STATUS_INITIALIZE; display = DS_NONE; diff --git a/Core/Dialog/SavedataParam.h b/Core/Dialog/SavedataParam.h index 9611edf816..2a7431499d 100644 --- a/Core/Dialog/SavedataParam.h +++ b/Core/Dialog/SavedataParam.h @@ -21,6 +21,8 @@ #include "Core/HLE/sceRtc.h" #include "Core/System.h" #include "Core/Dialog/PSPDialog.h" +#include "Common/CommonTypes.h" + #undef st_ctime #undef st_atime #undef st_mtime @@ -65,6 +67,13 @@ enum SceUtilitySavedataFocus SCE_UTILITY_SAVEDATA_FOCUS_LASTEMPTY = 8, // last empty (what if no empty?) }; +#if COMMON_LITTLE_ENDIAN +typedef SceUtilitySavedataType SceUtilitySavedataType_le; +typedef SceUtilitySavedataFocus SceUtilitySavedataFocus_le; +#else +#error FIX ME +#endif + typedef char SceUtilitySavedataSaveName[20]; // title, savedataTitle, detail: parts of the unencrypted SFO @@ -80,34 +89,34 @@ struct PspUtilitySavedataSFOParam struct PspUtilitySavedataFileData { PSPPointer buf; - SceSize bufSize; // Size of the buffer pointed to by buf - SceSize size; // Actual file size to write / was read - int unknown; + SceSize_le bufSize; // Size of the buffer pointed to by buf + SceSize_le size; // Actual file size to write / was read + s32_le unknown; }; struct PspUtilitySavedataSizeEntry { - u64 size; + u64_le size; char name[16]; }; struct PspUtilitySavedataSizeInfo { - int numSecureEntries; - int numNormalEntries; + s32_le numSecureEntries; + s32_le numNormalEntries; PSPPointer secureEntries; PSPPointer normalEntries; - int sectorSize; - int freeSectors; - int freeKB; + s32_le sectorSize; + s32_le freeSectors; + s32_le freeKB; char freeString[8]; - int neededKB; + s32_le neededKB; char neededString[8]; - int overwriteKB; + s32_le overwriteKB; char overwriteString[8]; }; struct SceUtilitySavedataIdListEntry { - int st_mode; + s32_le st_mode; ScePspDateTime st_ctime; ScePspDateTime st_atime; ScePspDateTime st_mtime; @@ -116,15 +125,15 @@ struct SceUtilitySavedataIdListEntry struct SceUtilitySavedataIdListInfo { - int maxCount; - int resultCount; + s32_le maxCount; + s32_le resultCount; PSPPointer entries; }; struct SceUtilitySavedataFileListEntry { - int st_mode; - u64 st_size; + s32_le st_mode; + u64_le st_size; ScePspDateTime st_ctime; ScePspDateTime st_atime; ScePspDateTime st_mtime; @@ -133,12 +142,12 @@ struct SceUtilitySavedataFileListEntry struct SceUtilitySavedataFileListInfo { - u32 maxSecureEntries; - u32 maxNormalEntries; - u32 maxSystemEntries; - u32 resultNumSecureEntries; - u32 resultNumNormalEntries; - u32 resultNumSystemEntries; + u32_le maxSecureEntries; + u32_le maxNormalEntries; + u32_le maxSystemEntries; + u32_le resultNumSecureEntries; + u32_le resultNumNormalEntries; + u32_le resultNumSystemEntries; PSPPointer secureEntries; PSPPointer normalEntries; PSPPointer systemEntries; @@ -146,18 +155,18 @@ struct SceUtilitySavedataFileListInfo struct SceUtilitySavedataMsFreeInfo { - int clusterSize; - int freeClusters; - int freeSpaceKB; + s32_le clusterSize; + s32_le freeClusters; + s32_le freeSpaceKB; char freeSpaceStr[8]; }; struct SceUtilitySavedataUsedDataInfo { - int usedClusters; - int usedSpaceKB; + s32_le usedClusters; + s32_le usedSpaceKB; char usedSpaceStr[8]; - int usedSpace32KB; + s32_le usedSpace32KB; char usedSpace32Str[8]; }; @@ -174,10 +183,10 @@ struct SceUtilitySavedataParam { pspUtilityDialogCommon common; - int mode; // 0 to load, 1 to save - int bind; + SceUtilitySavedataType_le mode; // 0 to load, 1 to save + s32_le bind; - int overwriteMode; // use 0x10 ? + s32_le overwriteMode; // use 0x10 ? /** gameName: name used from the game for saves, equal for all saves */ char gameName[13]; @@ -192,8 +201,8 @@ struct SceUtilitySavedataParam /** pointer to a buffer that will contain data file unencrypted data */ PSPPointer dataBuf; /** size of allocated space to dataBuf */ - SceSize dataBufSize; - SceSize dataSize; // Size of the actual save data + SceSize_le dataBufSize; + SceSize_le dataSize; // Size of the actual save data PspUtilitySavedataSFOParam sfoParam; @@ -203,8 +212,8 @@ struct SceUtilitySavedataParam PspUtilitySavedataFileData snd0FileData; PSPPointer newData; - int focus; - int abortStatus; + SceUtilitySavedataFocus_le focus; + s32_le abortStatus; // Function SCE_UTILITY_SAVEDATA_TYPE_SIZES PSPPointer msFree; @@ -213,8 +222,8 @@ struct SceUtilitySavedataParam u8 key[16]; - int secureVersion; - int multiStatus; + s32_le secureVersion; + s32_le multiStatus; // Function 11 LIST PSPPointer idList; diff --git a/Core/FileSystems/BlockDevices.cpp b/Core/FileSystems/BlockDevices.cpp index c1db97ea94..21c3dafa7b 100644 --- a/Core/FileSystems/BlockDevices.cpp +++ b/Core/FileSystems/BlockDevices.cpp @@ -70,23 +70,23 @@ bool FileBlockDevice::ReadBlock(int blockNumber, u8 *outPtr) // compressed ISO(9660) header format typedef struct ciso_header { - unsigned char magic[4]; // +00 : 'C','I','S','O' - u32 header_size; // +04 : header size (==0x18) - u64 total_bytes; // +08 : number of original data size - u32 block_size; // +10 : number of compressed block size - unsigned char ver; // +14 : version 01 - unsigned char align; // +15 : align of index value - unsigned char rsv_06[2]; // +16 : reserved + unsigned char magic[4]; // +00 : 'C','I','S','O' + u32_le header_size; // +04 : header size (==0x18) + u64_le total_bytes; // +08 : number of original data size + u32_le block_size; // +10 : number of compressed block size + unsigned char ver; // +14 : version 01 + unsigned char align; // +15 : align of index value + unsigned char rsv_06[2]; // +16 : reserved #if 0 // INDEX BLOCK - unsigned int index[0]; // +18 : block[0] index - unsigned int index[1]; // +1C : block[1] index + unsigned int index[0]; // +18 : block[0] index + unsigned int index[1]; // +1C : block[1] index : : - unsigned int index[last]; // +?? : block[last] - unsigned int index[last+1]; // +?? : end of last data point + unsigned int index[last]; // +?? : block[last] + unsigned int index[last+1]; // +?? : end of last data point // DATA BLOCK - unsigned char data[]; // +?? : compressed or plain sector data + unsigned char data[]; // +?? : compressed or plain sector data #endif } CISO_H; @@ -128,9 +128,18 @@ CISOFileBlockDevice::CISOFileBlockDevice(FILE *file) u32 indexSize = numBlocks + 1; +#if COMMON_LITTLE_ENDIAN index = new u32[indexSize]; - if(fread(index, sizeof(u32), indexSize, f) != indexSize) + if (fread(index, sizeof(u32), indexSize, f) != indexSize) memset(index, 0, indexSize * sizeof(u32)); +#else + index = new u32[indexSize]; + u32_le *indexTemp = new u32_le[indexSize]; + if (fread(indexTemp, sizeof(u32), indexSize, f) != indexSize) + memset(indexTemp, 0, indexSize * sizeof(u32_le)); + for (u32 i = 0; i < indexSize; i++) + index[i] = indexTemp[i]; +#endif } CISOFileBlockDevice::~CISOFileBlockDevice() diff --git a/Core/FileSystems/ISOFileSystem.cpp b/Core/FileSystems/ISOFileSystem.cpp index c5236596db..5f6e06470c 100644 --- a/Core/FileSystems/ISOFileSystem.cpp +++ b/Core/FileSystems/ISOFileSystem.cpp @@ -81,6 +81,34 @@ struct DirectoryEntry u16 volSeqNumberBE; u8 identifierLength; //identifier comes right after u8 firstIdChar; + +#if COMMON_LITTLE_ENDIAN + u32 firstDataSector() const + { + return firstDataSectorLE; + } + u32 dataLength() const + { + return dataLengthLE; + } + u32 volSeqNumber() const + { + return volSeqNumberLE; + } +#else + u32 firstDataSector() const + { + return firstDataSectorBE; + } + u32 dataLength() const + { + return dataLengthBE; + } + u32 volSeqNumber() const + { + return volSeqNumberBE; + } +#endif }; struct DirectorySector { @@ -175,8 +203,8 @@ ISOFileSystem::ISOFileSystem(IHandleAllocator *_hAlloc, BlockDevice *_blockDevic treeroot->flags = 0; treeroot->parent = NULL; - u32 rootSector = desc.root.firstDataSectorLE; - u32 rootSize = desc.root.dataLengthLE; + u32 rootSector = desc.root.firstDataSector(); + u32 rootSize = desc.root.dataLength(); ReadDirectory(rootSector, rootSize, treeroot, 0); } @@ -232,8 +260,8 @@ void ISOFileSystem::ReadDirectory(u32 startsector, u32 dirsize, TreeEntry *root, relative = false; } - e->size = dir.dataLengthLE; - e->startingPosition = dir.firstDataSectorLE * 2048; + e->size = dir.dataLength(); + e->startingPosition = dir.firstDataSector() * 2048; e->isDirectory = !isFile; e->flags = dir.flags; e->parent = root; @@ -243,7 +271,7 @@ void ISOFileSystem::ReadDirectory(u32 startsector, u32 dirsize, TreeEntry *root, if (e->isDirectory && !relative) { - if (dir.firstDataSectorLE == startsector) + if (dir.firstDataSector() == startsector) { ERROR_LOG(FILESYS, "WARNING: Appear to have a recursive file system, breaking recursion"); } @@ -254,7 +282,7 @@ void ISOFileSystem::ReadDirectory(u32 startsector, u32 dirsize, TreeEntry *root, doRecurse = level < restrictTree.size() && restrictTree[level] == e->name; if (doRecurse) - ReadDirectory(dir.firstDataSectorLE, dir.dataLengthLE, e, level + 1); + ReadDirectory(dir.firstDataSector(), dir.dataLength(), e, level + 1); else continue; } diff --git a/Core/HLE/sceCtrl.cpp b/Core/HLE/sceCtrl.cpp index c9e2142cce..99073cb919 100644 --- a/Core/HLE/sceCtrl.cpp +++ b/Core/HLE/sceCtrl.cpp @@ -47,19 +47,19 @@ enum // Returned control data struct _ctrl_data { - u32 frame; - u32 buttons; + u32_le frame; + u32_le buttons; // The PSP has only one stick, but has space for more info. // The second stick is populated for HD remasters and possibly in the PSP emulator on PS3/Vita. - u8 analog[2][2]; - u8 unused[4]; + u8 analog[2][2]; + u8 unused[4]; }; struct CtrlLatch { - u32 btnMake; - u32 btnBreak; - u32 btnPress; - u32 btnRelease; + u32_le btnMake; + u32_le btnBreak; + u32_le btnPress; + u32_le btnRelease; }; diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index 268c42dc78..4766923377 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -121,19 +121,19 @@ enum { #endif struct SceIoStat { - SceMode st_mode; - unsigned int st_attr; - SceOff st_size; + SceMode_le st_mode; + u32_le st_attr; + SceOff_le st_size; ScePspDateTime st_ctime; ScePspDateTime st_atime; ScePspDateTime st_mtime; - unsigned int st_private[6]; + u32_le st_private[6]; }; struct SceIoDirEnt { SceIoStat d_stat; char d_name[256]; - u32 d_private; + u32_le d_private; }; #ifndef __SYMBIAN32__ struct dirent { @@ -892,11 +892,11 @@ u32 sceIoSync(const char *devicename, int flag) { } struct DeviceSize { - u32 maxClusters; - u32 freeClusters; - u32 maxSectors; - u32 sectorSize; - u32 sectorCount; + u32_le maxClusters; + u32_le freeClusters; + u32_le maxSectors; + u32_le sectorSize; + u32_le sectorCount; }; u32 sceIoDevctl(const char *name, int cmd, u32 argAddr, int argLen, u32 outPtr, int outLen) { diff --git a/Core/HLE/sceMpeg.h b/Core/HLE/sceMpeg.h index a55e2bcc38..ba19ab2531 100644 --- a/Core/HLE/sceMpeg.h +++ b/Core/HLE/sceMpeg.h @@ -78,17 +78,17 @@ struct SceMpegAu { // As native in PSP ram struct SceMpegRingBuffer { // PSP info - int packets; - int packetsRead; - int packetsWritten; - int packetsFree; // pspsdk: unk2, noxa: iUnk0 - int packetSize; // 2048 - int data; // address, ring buffer - u32 callback_addr; // see sceMpegRingbufferPut - int callback_args; - int dataUpperBound; - int semaID; // unused? - u32 mpeg; // pointer to mpeg struct, fixed up in sceMpegCreate + s32_le packets; + s32_le packetsRead; + s32_le packetsWritten; + s32_le packetsFree; // pspsdk: unk2, noxa: iUnk0 + s32_le packetSize; // 2048 + s32_le data; // address, ring buffer + u32_le callback_addr; // see sceMpegRingbufferPut + s32_le callback_args; + s32_le dataUpperBound; + s32_le semaID; // unused? + u32_le mpeg; // pointer to mpeg struct, fixed up in sceMpegCreate }; void __MpegInit(); diff --git a/Core/HLE/sceNet.cpp b/Core/HLE/sceNet.cpp index 110c2ab89e..517933fa2e 100644 --- a/Core/HLE/sceNet.cpp +++ b/Core/HLE/sceNet.cpp @@ -72,21 +72,21 @@ enum { // These might come in handy in the future, if PPSSPP ever supports wifi/ad-hoc.. struct SceNetAdhocctlParams { - int channel; //which ad-hoc channel to connect to + s32_le channel; //which ad-hoc channel to connect to char name[8]; //connection name u8 bssid[6]; //BSSID of the connection? char nickname[128]; //PSP's nickname? }; struct ProductStruct { - int unknown; // Unknown, set to 0 + s32_le unknown; // Unknown, set to 0 char product[9]; // Game ID (Example: ULUS10000) }; struct SceNetMallocStat { - int pool; // Pointer to the pool? - int maximum; // Maximum size of the pool? - int free; // How much memory is free + s32_le pool; // Pointer to the pool? + s32_le maximum; // Maximum size of the pool? + s32_le free; // How much memory is free }; static struct SceNetMallocStat netMallocStat; diff --git a/Core/HLE/scePsmf.cpp b/Core/HLE/scePsmf.cpp index 2ff6bc51db..42df1871c0 100644 --- a/Core/HLE/scePsmf.cpp +++ b/Core/HLE/scePsmf.cpp @@ -67,24 +67,25 @@ enum PsmfPlayerStatus { }; struct PsmfData { - u32 version; - u32 headerSize; - u32 headerOffset; - u32 streamSize; - u32 streamOffset; - u32 streamNum; - u32 unk1; - u32 unk2; + u32_le version; + u32_le headerSize; + u32_le headerOffset; + u32_le streamSize; + u32_le streamOffset; + u32_le streamNum; + u32_le unk1; + u32_le unk2; }; struct PsmfPlayerData { - int videoCodec; - int videoStreamNum; - int audioCodec; - int audioStreamNum; - int playMode; - int playSpeed; - long psmfPlayerLastTimestamp; + s32_le videoCodec; + s32_le videoStreamNum; + s32_le audioCodec; + s32_le audioStreamNum; + s32_le playMode; + s32_le playSpeed; + // TODO: Was "long", which is 32, but should this be 64? Not even used? + s32_le psmfPlayerLastTimestamp; }; struct PsmfEntry { diff --git a/Core/HLE/sceUmd.cpp b/Core/HLE/sceUmd.cpp index 1d4bfb35d5..b13d1095fd 100644 --- a/Core/HLE/sceUmd.cpp +++ b/Core/HLE/sceUmd.cpp @@ -47,8 +47,8 @@ static int umdStatChangeEvent = -1; static std::vector umdWaitingThreads; struct PspUmdInfo { - u32 size; - u32 type; + u32_le size; + u32_le type; }; void __UmdStatTimeout(u64 userdata, int cyclesLate); @@ -146,13 +146,12 @@ u32 sceUmdGetDiscInfo(u32 infoAddr) DEBUG_LOG(HLE, "sceUmdGetDiscInfo(%08x)", infoAddr); if (Memory::IsValidAddress(infoAddr)) { - PspUmdInfo info; - Memory::ReadStruct(infoAddr, &info); - if (info.size != 8) + PSPPointer info; + info = infoAddr; + if (info->size != 8) return PSP_ERROR_UMD_INVALID_PARAM; - info.type = PSP_UMD_TYPE_GAME; - Memory::WriteStruct(infoAddr, &info); + info->type = PSP_UMD_TYPE_GAME; return 0; } else return PSP_ERROR_UMD_INVALID_PARAM; diff --git a/Core/Loaders.cpp b/Core/Loaders.cpp index 464100026a..074e00bda5 100644 --- a/Core/Loaders.cpp +++ b/Core/Loaders.cpp @@ -74,7 +74,7 @@ EmuFileType Identify_File(std::string &filename) } - u32 id; + u32_le id; size_t readSize = fread(&id, 4, 1, f); if (readSize != 1) { diff --git a/Core/MIPS/ARM/ArmCompFPU.cpp b/Core/MIPS/ARM/ArmCompFPU.cpp index 9af3490644..d57ec09000 100644 --- a/Core/MIPS/ARM/ArmCompFPU.cpp +++ b/Core/MIPS/ARM/ArmCompFPU.cpp @@ -91,6 +91,7 @@ void Jit::Comp_FPULS(u32 op) switch(op >> 26) { case 49: //FI(ft) = Memory::Read_U32(addr); break; //lwc1 + fpr.SpillLock(ft); fpr.MapReg(ft, MAP_NOINIT | MAP_DIRTY); if (gpr.IsImm(rs)) { u32 addr = (offset + gpr.GetImm(rs)) & 0x3FFFFFFF; @@ -124,6 +125,7 @@ void Jit::Comp_FPULS(u32 op) SetCC(CC_AL); } #endif + fpr.ReleaseSpillLock(ft); break; case 57: //Memory::Write_U32(FI(ft), addr); break; //swc1 diff --git a/Core/MIPS/ARM/ArmCompVFPU.cpp b/Core/MIPS/ARM/ArmCompVFPU.cpp index e64b33bab5..c355ef0d33 100644 --- a/Core/MIPS/ARM/ArmCompVFPU.cpp +++ b/Core/MIPS/ARM/ArmCompVFPU.cpp @@ -772,11 +772,77 @@ namespace MIPSComp } void Jit::Comp_VScl(u32 op) { - DISABLE; + DISABLE; // see todo below + + CONDITIONAL_DISABLE; + + if (js.HasUnknownPrefix()) + DISABLE; + + VectorSize sz = GetVecSize(op); + int n = GetNumVectorElements(sz); + + u8 sregs[4], dregs[4], scale; + GetVectorRegsPrefixS(sregs, sz, _VS); + // TODO: Prefixes seem strange... + GetVectorRegsPrefixT(&scale, V_Single, _VT); + GetVectorRegsPrefixD(dregs, sz, _VD); + + // Move to XMM0 early, so we don't have to worry about overlap with scale. + fpr.SpillLockV(scale); + fpr.MapRegV(scale); + + // TODO: need temp registers because of prefixD + for (int i = 0; i < n; ++i) + { + fpr.MapDirtyInV(dregs[i], sregs[i]); + VMUL(fpr.V(dregs[i]), fpr.V(sregs[i]), fpr.V(scale)); + } + ApplyPrefixD(dregs, sz); + + fpr.ReleaseSpillLocks(); } void Jit::Comp_Vmmul(u32 op) { - DISABLE; + CONDITIONAL_DISABLE; + + // TODO: This probably ignores prefixes? + if (js.MayHavePrefix()) { + DISABLE; + } + + MatrixSize sz = GetMtxSize(op); + int n = GetMatrixSide(sz); + + u8 sregs[16], tregs[16], dregs[16]; + GetMatrixRegs(sregs, sz, _VS); + GetMatrixRegs(tregs, sz, _VT); + GetMatrixRegs(dregs, sz, _VD); + + // Rough overlap check. + bool overlap = false; + if (GetMtx(_VS) == GetMtx(_VD) || GetMtx(_VT) == GetMtx(_VD)) { + // Potential overlap (guaranteed for 3x3 or more). + overlap = true; + } + + if (overlap) { + DISABLE; + } else { + for (int a = 0; a < n; a++) { + for (int b = 0; b < n; b++) { + fpr.MapInInV(sregs[b * 4], tregs[a * 4]); + VMUL(S0, fpr.V(sregs[b * 4]), fpr.V(tregs[a * 4])); + for (int c = 1; c < n; c++) { + fpr.MapInInV(sregs[b * 4 + c], tregs[a * 4 + c]); + VMLA(S0, fpr.V(sregs[b * 4 + c]), fpr.V(tregs[a * 4 + c])); + } + fpr.MapRegV(dregs[a * 4 + b], MAP_DIRTY | MAP_NOINIT); + VMOV(fpr.V(dregs[a * 4 + b]), S0); + } + } + fpr.ReleaseSpillLocks(); + } } void Jit::Comp_Vmscl(u32 op) { @@ -816,7 +882,32 @@ namespace MIPSComp } void Jit::Comp_Vcst(u32 op) { - DISABLE; + CONDITIONAL_DISABLE; + + if (js.HasUnknownPrefix()) + DISABLE; + + // TODO: support prefixes properly + if (js.MayHavePrefix()) + DISABLE; + + int conNum = (op >> 16) & 0x1f; + int vd = _VD; + + VectorSize sz = GetVecSize(op); + int n = GetNumVectorElements(sz); + + u8 dregs[4]; + GetVectorRegsPrefixD(dregs, sz, _VD); + fpr.MapRegsV(dregs, sz, MAP_NOINIT | MAP_DIRTY); + + MOVI2R(R0, (u32)(void *)&cst_constants[conNum]); + VLDR(S0, R0, 0); + for (int i = 0; i < n; ++i) + VMOV(fpr.V(dregs[i]), S0); + + ApplyPrefixD(dregs, sz); + fpr.ReleaseSpillLocks(); } void Jit::Comp_Vhoriz(u32 op) { diff --git a/Core/MIPS/ARM/ArmRegCache.cpp b/Core/MIPS/ARM/ArmRegCache.cpp index 00795433f9..773b2a56e3 100644 --- a/Core/MIPS/ARM/ArmRegCache.cpp +++ b/Core/MIPS/ARM/ArmRegCache.cpp @@ -290,6 +290,10 @@ void ArmRegCache::ReleaseSpillLocks() { } } +void ArmRegCache::ReleaseSpillLock(MIPSReg reg) { + mr[reg].spillLock = false; +} + ARMReg ArmRegCache::R(int mipsReg) { if (mr[mipsReg].loc == ML_ARMREG) { return (ARMReg)mr[mipsReg].reg; diff --git a/Core/MIPS/ARM/ArmRegCache.h b/Core/MIPS/ARM/ArmRegCache.h index 1138df726a..d1cec8af3d 100644 --- a/Core/MIPS/ARM/ArmRegCache.h +++ b/Core/MIPS/ARM/ArmRegCache.h @@ -84,6 +84,7 @@ public: // Protect the arm register containing a MIPS register from spilling, to ensure that // it's being kept allocated. void SpillLock(MIPSReg reg, MIPSReg reg2 = -1, MIPSReg reg3 = -1, MIPSReg reg4 = -1); + void ReleaseSpillLock(MIPSReg reg); void ReleaseSpillLocks(); void SetImm(MIPSReg reg, u32 immVal); diff --git a/Core/MIPS/ARM/ArmRegCacheFPU.cpp b/Core/MIPS/ARM/ArmRegCacheFPU.cpp index 62021bef76..883f2095de 100644 --- a/Core/MIPS/ARM/ArmRegCacheFPU.cpp +++ b/Core/MIPS/ARM/ArmRegCacheFPU.cpp @@ -15,6 +15,7 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. +#include "base/logging.h" #include "Common/ArmEmitter.h" #include "Common/CPUDetect.h" #include "Core/MIPS/ARM/ArmRegCacheFPU.h" @@ -182,6 +183,25 @@ void ArmRegCacheFPU::MapRegsV(const u8 *v, VectorSize sz, int flags) { } } +void ArmRegCacheFPU::MapInInV(int vs, int vt) { + SpillLockV(vs); + SpillLockV(vt); + MapRegV(vs); + MapRegV(vt); + ReleaseSpillLockV(vs); + ReleaseSpillLockV(vt); +} + +void ArmRegCacheFPU::MapDirtyInV(int vd, int vs, bool avoidLoad) { + bool overlap = avoidLoad && (vd == vs); + SpillLockV(vd); + SpillLockV(vs); + MapRegV(vd, MAP_DIRTY | (overlap ? 0 : MAP_NOINIT)); + MapRegV(vs); + ReleaseSpillLockV(vd); + ReleaseSpillLockV(vs); +} + void ArmRegCacheFPU::FlushArmReg(ARMReg r) { int reg = r - S0; if (ar[reg].mipsReg == -1) { diff --git a/Core/MIPS/ARM/ArmRegCacheFPU.h b/Core/MIPS/ARM/ArmRegCacheFPU.h index c22cbecf9e..4d858e6b06 100644 --- a/Core/MIPS/ARM/ArmRegCacheFPU.h +++ b/Core/MIPS/ARM/ArmRegCacheFPU.h @@ -79,6 +79,8 @@ public: // Returns an ARM register containing the requested MIPS register. ARMReg MapReg(MIPSReg reg, int mapFlags = 0); void MapInIn(MIPSReg rd, MIPSReg rs); + void MapInInV(int rt, int rs); + void MapDirtyInV(int rd, int rs, bool avoidLoad = true); void MapDirty(MIPSReg rd); void MapDirtyIn(MIPSReg rd, MIPSReg rs, bool avoidLoad = true); void MapDirtyInIn(MIPSReg rd, MIPSReg rs, MIPSReg rt, bool avoidLoad = true); diff --git a/Core/MIPS/MIPSVFPUUtils.h b/Core/MIPS/MIPSVFPUUtils.h index 22212defd5..d44d2fdf20 100644 --- a/Core/MIPS/MIPSVFPUUtils.h +++ b/Core/MIPS/MIPSVFPUUtils.h @@ -60,6 +60,11 @@ void ReadVector(float *rd, VectorSize N, int reg); void GetVectorRegs(u8 regs[4], VectorSize N, int vectorReg); void GetMatrixRegs(u8 regs[16], MatrixSize N, int matrixReg); +// Returns a number from 0-7, good for checking overlap for 4x4 matrices. +inline int GetMtx(int matrixReg) { + return (matrixReg >> 2) & 7; +} + VectorSize GetVecSize(u32 op); MatrixSize GetMtxSize(u32 op); VectorSize GetHalfVectorSize(VectorSize sz); diff --git a/Core/MIPS/x86/CompVFPU.cpp b/Core/MIPS/x86/CompVFPU.cpp index bb77a2962c..d661e09557 100644 --- a/Core/MIPS/x86/CompVFPU.cpp +++ b/Core/MIPS/x86/CompVFPU.cpp @@ -935,36 +935,52 @@ void Jit::Comp_Vmmul(u32 op) { GetMatrixRegs(tregs, sz, _VT); GetMatrixRegs(dregs, sz, _VD); - // TODO: test overlap, fix non-optimal. - u8 tempregs[16]; - for (int a = 0; a < n; a++) - { - for (int b = 0; b < n; b++) - { - XORPS(XMM0, R(XMM0)); - for (int c = 0; c < n; c++) - { - MOVSS(XMM1, fpr.V(sregs[b * 4 + c])); - MULSS(XMM1, fpr.V(tregs[a * 4 + c])); - ADDSS(XMM0, R(XMM1)); - } - u8 temp = (u8) fpr.GetTempV(); - fpr.MapRegV(temp, MAP_NOINIT | MAP_DIRTY); - MOVSS(fpr.VX(temp), R(XMM0)); - fpr.StoreFromRegisterV(temp); - tempregs[a * 4 + b] = temp; - } - } - for (int a = 0; a < n; a++) - { - for (int b = 0; b < n; b++) - { - u8 temp = tempregs[a * 4 + b]; - fpr.MapRegV(temp, 0); - MOVSS(fpr.V(dregs[a * 4 + b]), fpr.VX(temp)); - } + // Rough overlap check. + bool overlap = false; + if (GetMtx(_VS) == GetMtx(_VD) || GetMtx(_VT) == GetMtx(_VD)) { + // Potential overlap (guaranteed for 3x3 or more). + overlap = true; } + if (overlap) { + u8 tempregs[16]; + for (int a = 0; a < n; a++) { + for (int b = 0; b < n; b++) { + MOVSS(XMM0, fpr.V(sregs[b * 4])); + MULSS(XMM0, fpr.V(tregs[a * 4])); + for (int c = 1; c < n; c++) { + MOVSS(XMM1, fpr.V(sregs[b * 4 + c])); + MULSS(XMM1, fpr.V(tregs[a * 4 + c])); + ADDSS(XMM0, R(XMM1)); + } + u8 temp = (u8) fpr.GetTempV(); + fpr.MapRegV(temp, MAP_NOINIT | MAP_DIRTY); + MOVSS(fpr.VX(temp), R(XMM0)); + fpr.StoreFromRegisterV(temp); + tempregs[a * 4 + b] = temp; + } + } + for (int a = 0; a < n; a++) { + for (int b = 0; b < n; b++) { + u8 temp = tempregs[a * 4 + b]; + fpr.MapRegV(temp, 0); + MOVSS(fpr.V(dregs[a * 4 + b]), fpr.VX(temp)); + } + } + } else { + for (int a = 0; a < n; a++) { + for (int b = 0; b < n; b++) { + MOVSS(XMM0, fpr.V(sregs[b * 4])); + MULSS(XMM0, fpr.V(tregs[a * 4])); + for (int c = 1; c < n; c++) { + MOVSS(XMM1, fpr.V(sregs[b * 4 + c])); + MULSS(XMM1, fpr.V(tregs[a * 4 + c])); + ADDSS(XMM0, R(XMM1)); + } + MOVSS(fpr.V(dregs[a * 4 + b]), XMM0); + } + } + } fpr.ReleaseSpillLocks(); } diff --git a/Core/Util/PPGeDraw.cpp b/Core/Util/PPGeDraw.cpp index dc3262788b..401cbd9af8 100644 --- a/Core/Util/PPGeDraw.cpp +++ b/Core/Util/PPGeDraw.cpp @@ -35,9 +35,9 @@ static int atlasWidth; static int atlasHeight; struct PPGeVertex { - u16 u, v; - u32 color; - float x, y, z; + u16_le u, v; + u32_le color; + float_le x, y, z; }; static u32 savedContextPtr; @@ -52,8 +52,8 @@ static u32 dataPtr; static u32 dataWritePtr; static u32 dataSize = 0x10000; // should be enough for a frame of gui... -static u32 palettePtr; -static u32 paletteSize = 2 * 16; +static PSPPointer palette; +static u32 paletteSize = sizeof(u16) * 16; // Vertex collector static u32 vertexStart; @@ -160,10 +160,9 @@ void __PPGeInit() dataPtr = __PPGeDoAlloc(dataSize, false, "PPGe Vertex Data"); savedContextPtr = __PPGeDoAlloc(savedContextSize, false, "PPGe Saved Context"); atlasPtr = __PPGeDoAlloc(atlasSize, false, "PPGe Atlas Texture"); - palettePtr = __PPGeDoAlloc(paletteSize, false, "PPGe Texture Palette"); + palette = __PPGeDoAlloc(paletteSize, false, "PPGe Texture Palette"); // Generate 16-greyscale palette. All PPGe graphics are greyscale so we can use a tiny paletted texture. - u16 *palette = (u16 *)Memory::GetPointer(palettePtr); for (int i = 0; i < 16; i++) { int val = i; palette[i] = (val << 12) | 0xFFF; @@ -193,7 +192,7 @@ void __PPGeDoState(PointerWrap &p) p.Do(atlasPtr); p.Do(atlasWidth); p.Do(atlasHeight); - p.Do(palettePtr); + p.Do(palette); p.Do(savedContextPtr); p.Do(savedContextSize); @@ -225,8 +224,8 @@ void __PPGeShutdown() kernelMemory.Free(dlPtr); if (savedContextPtr) kernelMemory.Free(savedContextPtr); - if (palettePtr) - kernelMemory.Free(palettePtr); + if (palette) + kernelMemory.Free(palette.ptr); atlasPtr = 0; dataPtr = 0; @@ -728,8 +727,8 @@ void PPGeSetDefaultTexture() WriteCmd(GE_CMD_TEXTUREMAPENABLE, 1); int wp2 = GetPow2(atlasWidth); int hp2 = GetPow2(atlasHeight); - WriteCmd(GE_CMD_CLUTADDR, palettePtr & 0xFFFFF0); - WriteCmd(GE_CMD_CLUTADDRUPPER, (palettePtr & 0xFF000000) >> 8); + WriteCmd(GE_CMD_CLUTADDR, palette.ptr & 0xFFFFF0); + WriteCmd(GE_CMD_CLUTADDRUPPER, (palette.ptr & 0xFF000000) >> 8); WriteCmd(GE_CMD_CLUTFORMAT, 0x00FF02); WriteCmd(GE_CMD_LOADCLUT, 2); WriteCmd(GE_CMD_TEXSIZE0, wp2 | (hp2 << 8));