mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-11-14 18:19:36 +01:00
Merge branch 'master' of https://github.com/hrydgard/ppsspp into Assembler
This commit is contained in:
commit
961905cce8
24 files changed
+391
-198
No files matched your search
+11
-12
@@ -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
|
||||
|
||||
@@ -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)
|
||||
};
|
||||
|
||||
|
||||
@@ -126,7 +126,7 @@ PSPOskDialog::PSPOskDialog() : PSPDialog() {
|
||||
PSPOskDialog::~PSPOskDialog() {
|
||||
}
|
||||
|
||||
void PSPOskDialog::ConvertUCS2ToUTF8(std::string& _string, const PSPPointer<u16> em_address)
|
||||
void PSPOskDialog::ConvertUCS2ToUTF8(std::string& _string, const PSPPointer<u16_le> 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;
|
||||
|
||||
+28
-20
@@ -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<u16> desc;
|
||||
PSPPointer<u16_le> desc;
|
||||
/** Initial text */
|
||||
PSPPointer<u16> intext;
|
||||
PSPPointer<u16_le> intext;
|
||||
// Length, in unsigned shorts, including the terminator.
|
||||
u32 outtextlength;
|
||||
u32_le outtextlength;
|
||||
/** Pointer to the output text */
|
||||
PSPPointer<u16> outtext;
|
||||
PSPPointer<u16_le> 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<SceUtilityOskData> 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<u16> em_address);
|
||||
void ConvertUCS2ToUTF8(std::string& _string, const PSPPointer<u16_le> em_address);
|
||||
void ConvertUCS2ToUTF8(std::string& _string, const wchar_t *input);
|
||||
void RenderKeyboard();
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
+46
-37
@@ -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<u8> 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<PspUtilitySavedataSizeEntry> secureEntries;
|
||||
PSPPointer<PspUtilitySavedataSizeEntry> 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<SceUtilitySavedataIdListEntry> 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<SceUtilitySavedataFileListEntry> secureEntries;
|
||||
PSPPointer<SceUtilitySavedataFileListEntry> normalEntries;
|
||||
PSPPointer<SceUtilitySavedataFileListEntry> 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<u8> 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<PspUtilitySavedataFileData> newData;
|
||||
int focus;
|
||||
int abortStatus;
|
||||
SceUtilitySavedataFocus_le focus;
|
||||
s32_le abortStatus;
|
||||
|
||||
// Function SCE_UTILITY_SAVEDATA_TYPE_SIZES
|
||||
PSPPointer<SceUtilitySavedataMsFreeInfo> msFree;
|
||||
@@ -213,8 +222,8 @@ struct SceUtilitySavedataParam
|
||||
|
||||
u8 key[16];
|
||||
|
||||
int secureVersion;
|
||||
int multiStatus;
|
||||
s32_le secureVersion;
|
||||
s32_le multiStatus;
|
||||
|
||||
// Function 11 LIST
|
||||
PSPPointer<SceUtilitySavedataIdListInfo> idList;
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
+10
-10
@@ -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) {
|
||||
|
||||
+11
-11
@@ -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();
|
||||
|
||||
+5
-5
@@ -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;
|
||||
|
||||
+16
-15
@@ -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 {
|
||||
|
||||
+6
-7
@@ -47,8 +47,8 @@ static int umdStatChangeEvent = -1;
|
||||
static std::vector<UmdWaitingThread> 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<PspUmdInfo> 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;
|
||||
|
||||
+1
-1
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
+44
-28
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
+11
-12
@@ -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<u16_le> 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));
|
||||
|
||||
Reference in new issue
Block a user