Merge branch 'master' of github.com:hrydgard/ppsspp

Conflicts:
	Core/HLE/sceKernelInterrupt.cpp
	native
This commit is contained in:
Henrik Rydgård 2012-11-19 11:35:53 +01:00
commit ec2cb15c38
27 changed files with 429 additions and 318 deletions

1
.gitignore vendored
View file

@ -33,3 +33,4 @@ android/ui_atlas.zim
__testoutput.txt
__testerror.txt
ppge_atlas.zim.png
local.properties

View file

@ -10,7 +10,7 @@ class FixedSizeUnorderedSet
public:
bool insert(T item)
{
if (count_ < maxCount - 1)
if (count_ < (int)maxCount - 1)
{
data_[count_++] = item;
return true;
@ -41,7 +41,7 @@ public:
size_t size()
{
return count_;
return (size_t)count_;
}
T &operator[](size_t index) {

View file

@ -149,14 +149,14 @@ u32 sceAudioOutputPanned(u32 chan, u32 leftVol, u32 rightVol, u32 samplePtr)
int sceAudioGetChannelRestLen(u32 chan)
{
int sz = (int)chans[chan].sampleQueue.size() / 2;
DEBUG_LOG(HLE,"UNTESTED %i = sceAudioGetChannelRestLen(%i)", PARAM(0));
DEBUG_LOG(HLE,"UNTESTED %i = sceAudioGetChannelRestLen(%i)", sz, chan);
return sz;
}
int sceAudioGetChannelRestLength(u32 chan)
{
int sz = (int)chans[chan].sampleQueue.size() / 2;
DEBUG_LOG(HLE,"UNTESTED %i = sceAudioGetChannelRestLen(%i)", PARAM(0));
DEBUG_LOG(HLE,"UNTESTED %i = sceAudioGetChannelRestLen(%i)", sz, chan);
return sz;
}

View file

@ -71,15 +71,17 @@ u32 sceGeListEnQueue(u32 listAddress, u32 stallAddress, u32 callbackId, u32 optP
else
state = SCE_GE_LIST_COMPLETED;
DEBUG_LOG(HLE,"List enqueued.");
DEBUG_LOG(HLE,"List %i enqueued.", listID);
//return display list ID
return listID;
}
u32 sceGeListEnQueueHead(u32 listAddress, u32 stallAddress, u32 callbackId, u32 optParamAddr)
{
if (!stallAddress)
stallAddress = listAddress;
DEBUG_LOG(HLE,"sceGeListEnQueueHead(addr=%08x, stall=%08x, cbid=%08x, param=%08x)",
listAddress,stallAddress,callbackId,optParamAddr);
//if (!stallAddress)
// stallAddress = listAddress;
u32 listID = gpu->EnqueueList(listAddress,stallAddress);
// HACKY
if (listID)
@ -87,9 +89,7 @@ u32 sceGeListEnQueueHead(u32 listAddress, u32 stallAddress, u32 callbackId, u32
else
state = SCE_GE_LIST_COMPLETED;
DEBUG_LOG(HLE,"%i=sceGeListEnQueueHead(addr=%08x, stall=%08x, cbid=%08x, param=%08x)",
listID, listAddress,stallAddress,callbackId,optParamAddr);
DEBUG_LOG(HLE,"List enqueued.");
DEBUG_LOG(HLE,"List %i enqueued.", listID);
//return display list ID
return listID;
}

View file

@ -199,10 +199,12 @@ public:
{
return subIntrHandlers.find(subIntrNum) != subIntrHandlers.end();
}
SubIntrHandler &get(int subIntrNum)
SubIntrHandler *get(int subIntrNum)
{
if (has(subIntrNum))
return subIntrHandlers[subIntrNum];
return &subIntrHandlers[subIntrNum];
else
return 0;
// what to do, what to do...
}
@ -365,7 +367,7 @@ u32 sceKernelEnableSubIntr(u32 intrNumber, u32 subIntrNumber)
if (!intrHandlers[intrNumber].has(subIntrNumber))
return -1;
intrHandlers[intrNumber].get(subIntrNumber).enabled = true;
intrHandlers[intrNumber].get(subIntrNumber)->enabled = true;
return 0;
}
@ -378,7 +380,7 @@ u32 sceKernelDisableSubIntr(u32 intrNumber, u32 subIntrNumber)
if (!intrHandlers[intrNumber].has(subIntrNumber))
return -1;
intrHandlers[intrNumber].get(subIntrNumber).enabled = false;
intrHandlers[intrNumber].get(subIntrNumber)->enabled = false;
return 0;
}

View file

@ -1170,7 +1170,7 @@ void sceKernelWakeupThread()
}
}
else {
ERROR_LOG(HLE,"sceKernelWakeupThread(%i) - bad thread id");
ERROR_LOG(HLE,"sceKernelWakeupThread(%i) - bad thread id", uid);
RETURN(error);
}
}
@ -1189,7 +1189,7 @@ void sceKernelCancelWakeupThread()
RETURN(wCount);
}
else {
ERROR_LOG(HLE,"sceKernelCancelWakeupThread(%i) - bad thread id");
ERROR_LOG(HLE,"sceKernelCancelWakeupThread(%i) - bad thread id", uid);
RETURN(error);
}
}

View file

@ -135,17 +135,17 @@ int scePowerUnregisterCallback(int slotId)
int sceKernelPowerLock(int lockType)
{
DEBUG_LOG(HLE,"UNIMPL 0=sceKernelPowerLock(%i)", lockType);
DEBUG_LOG(HLE,"0=sceKernelPowerLock(%i)", lockType);
return 0;
}
int sceKernelPowerUnlock(int lockType)
{
DEBUG_LOG(HLE,"UNIMPL 0=sceKernelPowerUnlock(%i)");
DEBUG_LOG(HLE,"0=sceKernelPowerUnlock(%i)", lockType);
return 0;
}
int sceKernelPowerTick(int flag)
{
DEBUG_LOG(HLE,"UNIMPL 0=sceKernelPowerTick()");
DEBUG_LOG(HLE,"UNIMPL 0=sceKernelPowerTick(%i)", flag);
return 0;
}
@ -161,13 +161,13 @@ int sceKernelVolatileMemTryLock(int type, int paddr, int psize)
}
else
{
ERROR_LOG(HLE, "sceKernelVolatileMemTryLock - already locked!");
//RETURN(ERROR_POWER_VMEM_IN_USE); // does this line still need to be here??
ERROR_LOG(HLE, "sceKernelVolatileMemTryLock(%i, %08x, %i) - already locked!", type, paddr, psize);
return ERROR_POWER_VMEM_IN_USE;
}
// Volatile RAM is always at 0x08400000 and is of size 0x00400000.
// It's always available in the emu.
// TODO: Should really reserve this properly!
Memory::Write_U32(0x08400000, paddr);
Memory::Write_U32(0x00400000, psize);
@ -176,10 +176,9 @@ int sceKernelVolatileMemTryLock(int type, int paddr, int psize)
int sceKernelVolatileMemUnlock(int type)
{
INFO_LOG(HLE,"sceKernelVolatileMemUnlock()");
INFO_LOG(HLE,"sceKernelVolatileMemUnlock(%i)", type);
// TODO: sanity check
volatileMemLocked = false;
return 0;
}

View file

@ -82,30 +82,28 @@ enum SceUtilitySavedataType
#define SCE_UTILITY_STATUS_SHUTDOWN 4
/** title, savedataTitle, detail: parts of the unencrypted SFO
data, it contains what the VSH and standard load screen shows */
typedef struct PspUtilitySavedataSFOParam
// title, savedataTitle, detail: parts of the unencrypted SFO
// data, it contains what the VSH and standard load screen shows
struct PspUtilitySavedataSFOParam
{
char title[0x80];
char savedataTitle[0x80];
char detail[0x400];
unsigned char parentalLevel;
unsigned char unknown[3];
} PspUtilitySavedataSFOParam;
};
typedef struct PspUtilitySavedataFileData {
struct PspUtilitySavedataFileData {
void *buf;
SceSize bufSize;
SceSize size; /* ??? - why are there two sizes? */
SceSize bufSize; // Size of the buffer pointed to by buf
SceSize size; // Actual file size to write / was read
int unknown;
} PspUtilitySavedataFileData;
};
/** Structure to hold the parameters for the ::sceUtilitySavedataInitStart function.
*/
typedef struct SceUtilitySavedataParam
// Structure to hold the parameters for the sceUtilitySavedataInitStart function.
struct SceUtilitySavedataParam
{
/** Size of the structure */
SceSize size;
SceSize size; // Size of the structure
int language;
@ -115,12 +113,10 @@ typedef struct SceUtilitySavedataParam
int result;
int unknown2[4];
/** mode: 0 to load, 1 to save */
int mode;
int mode; // 0 to load, 1 to save
int bind;
/** unknown13 use 0x10 */
int overwriteMode;
int overwriteMode; // use 0x10 ?
/** gameName: name used from the game for saves, equal for all saves */
char gameName[16];
@ -133,7 +129,7 @@ typedef struct SceUtilitySavedataParam
void *dataBuf;
/** size of allocated space to dataBuf */
SceSize dataBufSize;
SceSize dataSize;
SceSize dataSize; // Size of the actual save data
PspUtilitySavedataSFOParam sfoParam;
@ -143,17 +139,20 @@ typedef struct SceUtilitySavedataParam
PspUtilitySavedataFileData snd0FileData;
unsigned char unknown17[4];
} SceUtilitySavedataParam;
};
static u32 utilityDialogState = SCE_UTILITY_STATUS_SHUTDOWN;
u32 messageDialogAddr;
void __UtilityInit()
{
messageDialogAddr = 0;
utilityDialogState = SCE_UTILITY_STATUS_SHUTDOWN;
// Creates a directory for save on the sdcard or MemStick directory
}
@ -292,12 +291,15 @@ struct pspMessageDialog
u32 buttonPressed; // 0=?, 1=Yes, 2=No, 3=Back
};
u32 messageDialogAddr;
void sceUtilityMsgDialogInitStart()
{
u32 structAddr = PARAM(0);
DEBUG_LOG(HLE,"FAKE sceUtilityMsgDialogInitStart(%i)", structAddr);
DEBUG_LOG(HLE,"sceUtilityMsgDialogInitStart(%i)", structAddr);
if (!Memory::IsValidAddress(structAddr))
{
RETURN(-1);
return;
}
messageDialogAddr = structAddr;
pspMessageDialog messageDialog;
Memory::ReadStruct(messageDialogAddr, &messageDialog);
@ -321,7 +323,8 @@ void sceUtilityMsgDialogShutdownStart()
void sceUtilityMsgDialogUpdate()
{
DEBUG_LOG(HLE,"sceUtilityMsgDialogUpdate(%i)", PARAM(0));
int animSpeed = PARAM(0);
DEBUG_LOG(HLE,"sceUtilityMsgDialogUpdate(%i)", animSpeed);
switch (utilityDialogState) {
case SCE_UTILITY_STATUS_FINISHED:
@ -334,6 +337,12 @@ void sceUtilityMsgDialogUpdate()
RETURN(0);
return;
}
if (!Memory::IsValidAddress(messageDialogAddr)) {
ERROR_LOG(HLE, "sceUtilityMsgDialogUpdate: Bad messagedialogaddr %08x", messageDialogAddr);
RETURN(-1);
return;
}
pspMessageDialog messageDialog;
Memory::ReadStruct(messageDialogAddr, &messageDialog);
@ -354,7 +363,7 @@ void sceUtilityMsgDialogUpdate()
static u32 lastButtons = 0;
u32 buttons = __CtrlPeekButtons();
if (messageDialog.options & 0x10) //yesnobutton
if (messageDialog.options & 0x10) // yesnobutton
{
PPGeDrawImage(I_CROSS, 80, 220, 0, 0xFFFFFFFF);
PPGeDrawText("Yes", 140, 220, PPGE_ALIGN_HCENTER, 1.0f, 0xFFFFFFFF);

View file

@ -365,7 +365,7 @@ void JitBlockCache::DestroyBlock(int block_num, bool invalidate)
#ifdef JIT_UNLIMITED_ICACHE
Memory::Write_Opcode_JIT(b.originalAddress, b.originalFirstOpcode?b.originalFirstOpcode:JIT_ICACHE_INVALID_WORD);
#else
if (Memory::ReadUnchecked_U32(b.originalAddress) == block_num)
if ((int)Memory::ReadUnchecked_U32(b.originalAddress) == block_num)
Memory::WriteUnchecked_U32(b.originalFirstOpcode, b.originalAddress);
#endif

View file

@ -282,7 +282,7 @@ void GPRRegCache::BindToRegister(int i, bool doLoad, bool makeDirty)
{
if (i != j && regs[j].location.IsSimpleReg() && regs[j].location.GetSimpleReg() == xr)
{
PanicAlert("");
PanicAlert("bad");
}
}
regs[i].away = true;
@ -318,7 +318,8 @@ void GPRRegCache::StoreFromRegister(int i)
doStore = true;
}
Location newLoc = GetDefaultLocation(i);
//if (doStore)
if (doStore)
;
// emit->MOV(32, newLoc, regs[i].location);
regs[i].location = newLoc;
regs[i].away = false;

View file

@ -77,7 +77,6 @@ void MIPSState::Reset()
SetWriteMask(b);
pc = 0;
prevPC = 0;
hi = 0;
lo = 0;
fpcond = 0;
@ -157,7 +156,6 @@ void MIPSState::RunLoopUntil(u64 globalTicks)
break;
}
#endif
prevPC = pc;
if (inDelaySlot)
{
MIPSInterpret(op);
@ -172,6 +170,7 @@ void MIPSState::RunLoopUntil(u64 globalTicks)
MIPSInterpret(op);
}
/*
if (!Memory::IsValidAddress(pc))
{
pc = pc;
@ -179,9 +178,12 @@ void MIPSState::RunLoopUntil(u64 globalTicks)
if (r[MIPS_REG_RA] != 0 && !Memory::IsValidAddress(r[MIPS_REG_RA]))
{
// pc = pc;
}
}*/
if (inDelaySlot)
{
CoreTiming::downcount -= 1;
goto again;
}
}
CoreTiming::downcount -= 1;
@ -190,11 +192,9 @@ void MIPSState::RunLoopUntil(u64 globalTicks)
DEBUG_LOG(CPU, "Hit the max ticks, bailing : %llu, %llu", globalTicks, CoreTiming::GetTicks());
break;
}
}
CoreTiming::Advance();
// if (exceptions) checkExceptions();
if (CoreTiming::GetTicks() > globalTicks)
{
DEBUG_LOG(CPU, "Hit the max ticks, bailing : %llu, %llu", globalTicks, CoreTiming::GetTicks());

View file

@ -112,7 +112,6 @@ public:
u32 pc;
u32 nextPC;
u32 prevPC;
u32 hi;
u32 lo;

View file

@ -431,6 +431,7 @@ namespace MIPSDis
break;
default:
// invalid
name = "???";
break;
}
int vd = _VD;

View file

@ -311,7 +311,7 @@ namespace MIPSInt
switch (op >> 26)
{
case 48: // ll
R(rt) = Memory::Read_U32(addr);
R(rt) = Memory::Read_U32(addr);
currentMIPS->llBit = 1;
break;
case 56: // sc
@ -580,7 +580,7 @@ namespace MIPSInt
{
s32 a = (s32)R(rs);
s32 b = (s32)R(rt);
if (a == 0x80000000 && b == -1) {
if (a == (s32)0x80000000 && b == -1) {
LO = 0x80000000;
} else if (b != 0) {
LO = (u32)(a / b);
@ -768,10 +768,10 @@ namespace MIPSInt
case 36:
switch (currentMIPS->fcr31 & 3)
{
case 0: FsI(fd) = roundf(F(fs)); break; // RINT_0 // TODO: rintf or roundf?
case 0: FsI(fd) = (int)roundf(F(fs)); break; // RINT_0 // TODO: rintf or roundf?
case 1: FsI(fd) = (int)F(fs); break; // CAST_1
case 2: FsI(fd) = ceilf(F(fs)); break; // CEIL_2
case 3: FsI(fd) = floorf(F(fs)); break; // FLOOR_3
case 2: FsI(fd) = (int)ceilf(F(fs)); break; // CEIL_2
case 3: FsI(fd) = (int)floorf(F(fs)); break; // FLOOR_3
}
break; //cvt.w.s
default:
@ -815,6 +815,7 @@ namespace MIPSInt
default:
_dbg_assert_msg_(CPU,0,"Trying to interpret FPUComp instruction that can't be interpreted");
cond = false;
break;
}
currentMIPS->fpcond = cond;

View file

@ -170,78 +170,78 @@ namespace MIPSInt
switch (op >> 26)
{
case 53: //lvl.q/lvr.q
if (addr & 0x3)
{
_dbg_assert_msg_(CPU, 0, "Misaligned lvX.q");
}
if ((op&2) == 0)
{
// It's an LVL
float d[4];
ReadVector(d, V_Quad, vt);
int offset = (addr >> 2) & 3;
for (int i = 0; i < offset + 1; i++)
{
d[3 - i] = Memory::Read_Float(addr - i * 4);
}
WriteVector(d, V_Quad, vt);
}
else
{
// It's an LVR
float d[4];
ReadVector(d, V_Quad, vt);
int offset = (addr >> 2) & 3;
for (int i = 0; i < (3 - offset) + 1; i++)
{
d[i] = Memory::Read_Float(addr + 4 * i);
}
WriteVector(d, V_Quad, vt);
}
break;
if (addr & 0x3)
{
_dbg_assert_msg_(CPU, 0, "Misaligned lvX.q");
}
if ((op&2) == 0)
{
// It's an LVL
float d[4];
ReadVector(d, V_Quad, vt);
int offset = (addr >> 2) & 3;
for (int i = 0; i < offset + 1; i++)
{
d[3 - i] = Memory::Read_Float(addr - i * 4);
}
WriteVector(d, V_Quad, vt);
}
else
{
// It's an LVR
float d[4];
ReadVector(d, V_Quad, vt);
int offset = (addr >> 2) & 3;
for (int i = 0; i < (3 - offset) + 1; i++)
{
d[i] = Memory::Read_Float(addr + 4 * i);
}
WriteVector(d, V_Quad, vt);
}
break;
case 54: //lv.q
if (addr & 0xF)
{
_dbg_assert_msg_(CPU, 0, "Misaligned lv.q");
}
if (addr & 0xF)
{
_dbg_assert_msg_(CPU, 0, "Misaligned lv.q");
}
WriteVector((const float*)Memory::GetPointer(addr), V_Quad, vt);
break;
case 61: // svl.q/svr.q
if (addr & 0x3)
{
_dbg_assert_msg_(CPU, 0, "Misaligned svX.q");
}
if ((op&2) == 0)
{
// It's an SVL
float d[4];
ReadVector(d, V_Quad, vt);
int offset = (addr >> 2) & 3;
for (int i = 0; i < offset + 1; i++)
{
Memory::Write_Float(d[3 - i], addr - i * 4);
}
}
else
{
// It's an SVR
float d[4];
ReadVector(d, V_Quad, vt);
int offset = (addr >> 2) & 3;
for (int i = 0; i < (3 - offset) + 1; i++)
{
Memory::Write_Float(d[i], addr + 4 * i);
}
}
break;
if (addr & 0x3)
{
_dbg_assert_msg_(CPU, 0, "Misaligned svX.q");
}
if ((op&2) == 0)
{
// It's an SVL
float d[4];
ReadVector(d, V_Quad, vt);
int offset = (addr >> 2) & 3;
for (int i = 0; i < offset + 1; i++)
{
Memory::Write_Float(d[3 - i], addr - i * 4);
}
}
else
{
// It's an SVR
float d[4];
ReadVector(d, V_Quad, vt);
int offset = (addr >> 2) & 3;
for (int i = 0; i < (3 - offset) + 1; i++)
{
Memory::Write_Float(d[i], addr + 4 * i);
}
}
break;
case 62: //sv.q
if (addr & 0xF)
{
_dbg_assert_msg_(CPU, 0, "Misaligned sv.q");
}
if (addr & 0xF)
{
_dbg_assert_msg_(CPU, 0, "Misaligned sv.q");
}
ReadVector((float*)Memory::GetPointer(addr), V_Quad, vt);
break;
@ -401,33 +401,33 @@ namespace MIPSInt
EatPrefixes();
}
void Int_Vmscl(u32 op)
{
float s[16];
float t[16];
float d[16];
void Int_Vmscl(u32 op)
{
float d[16];
float s[16];
float t[1];
int vd = _VD;
int vs = _VS;
int vt = _VT;
MatrixSize sz = GetMtxSize(op);
int n = GetMatrixSide(sz);
int vd = _VD;
int vs = _VS;
int vt = _VT;
MatrixSize sz = GetMtxSize(op);
int n = GetMatrixSide(sz);
ReadMatrix(s, sz, vs);
ReadMatrix(t, sz, vt);
ReadMatrix(s, sz, vs);
ReadVector(t, V_Single, vt);
for (int a = 0; a < n; a++)
{
for (int b = 0; b < n; b++)
{
d[a*4 + b] = s[a*4 + b] * t[0];
}
}
for (int a = 0; a < n; a++)
{
for (int b = 0; b < n; b++)
{
d[a*4 + b] = s[a*4 + b] * t[0];
}
}
WriteMatrix(d, sz, vd);
PC += 4;
EatPrefixes();
}
WriteMatrix(d, sz, vd);
PC += 4;
EatPrefixes();
}
void Int_Vmmov(u32 op)
{
@ -436,7 +436,7 @@ namespace MIPSInt
int vs = _VS;
MatrixSize sz = GetMtxSize(op);
ReadMatrix(s, sz, vs);
WriteMatrix(s,sz,vd);
WriteMatrix(s, sz, vd);
PC += 4;
EatPrefixes();
}
@ -470,7 +470,7 @@ namespace MIPSInt
case 19: d[i] = cosf((float)M_PI_2 * s[i]); break; //vcos
case 20: d[i] = powf(2.0f, s[i]); break;
case 21: d[i] = logf(s[i])/log(2.0f); break;
case 22: d[i] = sqrtf(s[i]); break; //vsqrt
case 22: d[i] = sqrtf(s[i]); break; //vsqrt
case 23: d[i] = asinf(s[i] * (float)M_2_PI); break; //vasin
// case 24: vnrcp
// case 26: vnsin
@ -703,7 +703,7 @@ namespace MIPSInt
void Int_Vi2x(u32 op)
{
int s[4];
u32 d[2] = {0};
u32 d[2] = {0};
int vd = _VD;
int vs = _VS;
VectorSize sz = GetVecSize(op);
@ -726,18 +726,18 @@ namespace MIPSInt
break;
case 1: //vi2c
{
for (int i = 0; i < 4; i++)
{
int v = s[i];
v >>= 24;
d[0] |= ((u32)v & 0xFF) << (i * 8);
}
oz = V_Single;
}
break;
{
for (int i = 0; i < 4; i++)
{
int v = s[i];
v >>= 24;
d[0] |= ((u32)v & 0xFF) << (i * 8);
}
oz = V_Single;
}
break;
case 2: //vi2us
case 2: //vi2us
{
for (int i = 0; i < GetNumVectorElements(sz) / 2; i++) {
int low = s[i * 2];
@ -775,54 +775,54 @@ namespace MIPSInt
EatPrefixes();
}
void Int_ColorConv(u32 op)
{
int vd = _VD;
int vs = _VS;
u32 s[4];
VectorSize sz = V_Quad;
ReadVector((float *)s, sz, vs);
u16 colors[4];
for (int i = 0; i < 4; i++)
{
u32 in = s[i];
u16 col = 0;
switch ((op >> 16) & 3)
{
case 1: // 4444
{
int a = ((in >> 24) & 0xFF) >> 4;
int b = ((in >> 16) & 0xFF) >> 4;
int g = ((in >> 8) & 0xFF) >> 4;
int r = ((in) & 0xFF) >> 4;
col = (a << 12) | (b << 8) | (g << 4 ) | (r);
break;
}
case 2: // 5551
{
int a = ((in >> 24) & 0xFF) >> 7;
int b = ((in >> 16) & 0xFF) >> 3;
int g = ((in >> 8) & 0xFF) >> 3;
int r = ((in) & 0xFF) >> 3;
col = (a << 15) | (b << 10) | (g << 5) | (r);
break;
}
case 3: // 565
{
int b = ((in >> 16) & 0xFF) >> 3;
int g = ((in >> 8) & 0xFF) >> 2;
int r = ((in) & 0xFF) >> 3;
col = (b << 11) | (g << 5) | (r);
break;
}
}
colors[i] = col;
}
u32 ov[2] = {(u32)colors[0] | (colors[1] << 16), (u32)colors[2] | (colors[3] << 16)};
WriteVector((const float *)ov, V_Pair, vd);
PC += 4;
EatPrefixes();
}
void Int_ColorConv(u32 op)
{
int vd = _VD;
int vs = _VS;
u32 s[4];
VectorSize sz = V_Quad;
ReadVector((float *)s, sz, vs);
u16 colors[4];
for (int i = 0; i < 4; i++)
{
u32 in = s[i];
u16 col = 0;
switch ((op >> 16) & 3)
{
case 1: // 4444
{
int a = ((in >> 24) & 0xFF) >> 4;
int b = ((in >> 16) & 0xFF) >> 4;
int g = ((in >> 8) & 0xFF) >> 4;
int r = ((in) & 0xFF) >> 4;
col = (a << 12) | (b << 8) | (g << 4 ) | (r);
break;
}
case 2: // 5551
{
int a = ((in >> 24) & 0xFF) >> 7;
int b = ((in >> 16) & 0xFF) >> 3;
int g = ((in >> 8) & 0xFF) >> 3;
int r = ((in) & 0xFF) >> 3;
col = (a << 15) | (b << 10) | (g << 5) | (r);
break;
}
case 3: // 565
{
int b = ((in >> 16) & 0xFF) >> 3;
int g = ((in >> 8) & 0xFF) >> 2;
int r = ((in) & 0xFF) >> 3;
col = (b << 11) | (g << 5) | (r);
break;
}
}
colors[i] = col;
}
u32 ov[2] = {(u32)colors[0] | (colors[1] << 16), (u32)colors[2] | (colors[3] << 16)};
WriteVector((const float *)ov, V_Pair, vd);
PC += 4;
EatPrefixes();
}
void Int_VDot(u32 op)
{
@ -927,27 +927,27 @@ namespace MIPSInt
EatPrefixes();
}
void Int_Vavg(u32 op)
{
float s[4];
float d;
int vd = _VD;
int vs = _VS;
VectorSize sz = GetVecSize(op);
ReadVector(s, sz, vs);
ApplySwizzleS(s, sz);
float sum = 0.0f;
int n = GetNumVectorElements(sz);
for (int i = 0; i < n; i++)
{
sum += s[i];
}
d = sum / n;
ApplyPrefixD(&d, V_Single);
V(vd) = d;
PC += 4;
EatPrefixes();
}
void Int_Vavg(u32 op)
{
float s[4];
float d;
int vd = _VD;
int vs = _VS;
VectorSize sz = GetVecSize(op);
ReadVector(s, sz, vs);
ApplySwizzleS(s, sz);
float sum = 0.0f;
int n = GetNumVectorElements(sz);
for (int i = 0; i < n; i++)
{
sum += s[i];
}
d = sum / n;
ApplyPrefixD(&d, V_Single);
V(vd) = d;
PC += 4;
EatPrefixes();
}
void Int_VScl(u32 op)
{
@ -971,36 +971,36 @@ namespace MIPSInt
EatPrefixes();
}
void Int_Vrnds(u32 op)
{
int vd = _VD;
int seed = VI(vd);
currentMIPS->rng.Init(seed);
}
void Int_VrndX(u32 op)
{
float d[4];
int vd = _VD;
VectorSize sz = GetVecSize(op);
int n = GetNumVectorElements(sz);
for (int i = 0; i < n; i++)
{
switch ((op >> 16) & 0x1f)
{
case 1: d[i] = (float)currentMIPS->rng.R32(); break; // vrndi - TODO: copy bits instead?
case 2: d[i] = 1.0f + ((float)currentMIPS->rng.R32() / 0xFFFFFFFF); break; // vrndf1 TODO: make more accurate
case 3: d[i] = 2.0f + 2 * ((float)currentMIPS->rng.R32() / 0xFFFFFFFF); break; // vrndf2 TODO: make more accurate
case 4: d[i] = 0.0f; // Should not get here
}
}
ApplyPrefixD(d, sz);
WriteVector(d, sz, vd);
PC += 4;
EatPrefixes();
}
void Int_Vrnds(u32 op)
{
int vd = _VD;
int seed = VI(vd);
currentMIPS->rng.Init(seed);
}
// Generates one line of a rotation matrix around one of the three axes
void Int_VrndX(u32 op)
{
float d[4];
int vd = _VD;
VectorSize sz = GetVecSize(op);
int n = GetNumVectorElements(sz);
for (int i = 0; i < n; i++)
{
switch ((op >> 16) & 0x1f)
{
case 1: d[i] = (float)currentMIPS->rng.R32(); break; // vrndi - TODO: copy bits instead?
case 2: d[i] = 1.0f + ((float)currentMIPS->rng.R32() / 0xFFFFFFFF); break; // vrndf1 TODO: make more accurate
case 3: d[i] = 2.0f + 2 * ((float)currentMIPS->rng.R32() / 0xFFFFFFFF); break; // vrndf2 TODO: make more accurate
case 4: d[i] = 0.0f; // Should not get here
}
}
ApplyPrefixD(d, sz);
WriteVector(d, sz, vd);
PC += 4;
EatPrefixes();
}
// Generates one line of a rotation matrix around one of the three axes
void Int_Vrot(u32 op)
{
int vd = _VD;
@ -1010,9 +1010,9 @@ namespace MIPSInt
float angle = V(vs) * M_PI_2;
bool negSin = (imm & 0x10) ? true : false;
float sine = sinf(angle);
float cosine = cosf(angle);
float cosine = cosf(angle);
if (negSin)
sine = -sine;
sine = -sine;
float d[4] = {0};
if (((imm >> 2) & 3) == (imm & 3))
{
@ -1035,23 +1035,23 @@ namespace MIPSInt
VectorSize sz = GetVecSize(op);
MatrixSize msz = GetMtxSize(op);
int n = GetNumVectorElements(sz);
int n = GetNumVectorElements(sz);
bool homogenous = false;
if (n == ins)
{
n++;
sz = (VectorSize)((int)(sz) + 1);
msz = (MatrixSize)((int)(msz) + 1);
homogenous = true;
}
bool homogenous = false;
if (n == ins)
{
n++;
sz = (VectorSize)((int)(sz) + 1);
msz = (MatrixSize)((int)(msz) + 1);
homogenous = true;
}
float s[16];
ReadMatrix(s, msz, vs);
float t[4];
ReadVector(t, sz, vt);
float d[4];
if (homogenous)
{
for (int i = 0; i < n; i++)
@ -1082,7 +1082,7 @@ namespace MIPSInt
PC += 4;
EatPrefixes();
}
void Int_SV(u32 op)
{
s32 imm = (signed short)(op&0xFFFC);
@ -1093,7 +1093,7 @@ namespace MIPSInt
switch (op >> 26)
{
case 50: //lv.s
VI(vt) = Memory::Read_U32(addr);
VI(vt) = Memory::Read_U32(addr);
break;
case 58: //sv.s
Memory::Write_U32(VI(vt), addr);
@ -1208,6 +1208,7 @@ namespace MIPSInt
for (int i = 0; i < n; i++)
{
int c;
// These set c to 0 or 1, nothing else.
switch (cond)
{
case VC_EQ: c = s[i] == t[i]; break;
@ -1232,8 +1233,9 @@ namespace MIPSInt
affected_bits |= 1 << i;
}
// Use masking to only change the affected bits
currentMIPS->vfpuCtrl[VFPU_CTRL_CC] = (currentMIPS->vfpuCtrl[VFPU_CTRL_CC] & ~affected_bits) |
(cc | (or_val << 4) | (and_val << 5)) & affected_bits;
currentMIPS->vfpuCtrl[VFPU_CTRL_CC] =
(currentMIPS->vfpuCtrl[VFPU_CTRL_CC] & ~affected_bits) |
((cc | (or_val << 4) | (and_val << 5)) & affected_bits);
PC += 4;
EatPrefixes();
}
@ -1348,13 +1350,6 @@ namespace MIPSInt
default: goto bad;
}
break;
/*
case 27: //VFPU3
switch ((op >> 23)&7)
{
case 0: d[i] = s[i] * t[i]; break; //vmul
}
break;*/
default:
bad:
_dbg_assert_msg_(CPU,0,"Trying to interpret instruction that can't be interpreted");

View file

@ -225,8 +225,8 @@ const MIPSInstruction tableSpecial[64] = /// 000000 ...... ...... .......... xxx
{-2},
INSTR("slt", &Jit::Comp_RType3, Dis_RType3, Int_RType3,IN_RS|IN_RT|OUT_RD),
INSTR("sltu", &Jit::Comp_RType3, Dis_RType3, Int_RType3,IN_RS|IN_RT|OUT_RD),
INSTR("max", &Jit::Comp_Generic, Dis_RType3, Int_RType3,IN_RS|IN_RT|OUT_RD),
INSTR("min", &Jit::Comp_Generic, Dis_RType3, Int_RType3,IN_RS|IN_RT|OUT_RD),
INSTR("max", &Jit::Comp_RType3, Dis_RType3, Int_RType3,IN_RS|IN_RT|OUT_RD),
INSTR("min", &Jit::Comp_RType3, Dis_RType3, Int_RType3,IN_RS|IN_RT|OUT_RD),
INSTR("msub", &Jit::Comp_Generic, Dis_MulDivType, Int_MulDivType, IN_RS|IN_RT|OUT_OTHER),
INSTR("msubu", &Jit::Comp_Generic, Dis_MulDivType, Int_MulDivType, IN_RS|IN_RT|OUT_OTHER),

View file

@ -161,17 +161,17 @@ namespace MIPSComp
case 33: //R(rd) = R(rs) + R(rt); break; //addu
CompTriArith(op, &XEmitter::ADD);
break;
case 134: //R(rd) = R(rs) - R(rt); break; //sub
case 135:
case 34: //R(rd) = R(rs) - R(rt); break; //sub
case 35:
CompTriArith(op, &XEmitter::SUB);
break;
case 136: //R(rd) = R(rs) & R(rt); break; //and
case 36: //R(rd) = R(rs) & R(rt); break; //and
CompTriArith(op, &XEmitter::AND);
break;
case 137: //R(rd) = R(rs) | R(rt); break; //or
case 37: //R(rd) = R(rs) | R(rt); break; //or
CompTriArith(op, &XEmitter::OR);
break;
case 138: //R(rd) = R(rs) ^ R(rt); break; //xor
case 38: //R(rd) = R(rs) ^ R(rt); break; //xor
CompTriArith(op, &XEmitter::XOR);
break;

View file

@ -82,7 +82,7 @@ inline void ReadFromHardware(T &var, const u32 address)
}
else
{
WARN_LOG(MEMMAP, "ReadFromHardware: Invalid address %08x PC %08x PPC %08x LR %08x", address, currentMIPS->pc, currentMIPS->prevPC, currentMIPS->r[MIPS_REG_RA]);
WARN_LOG(MEMMAP, "ReadFromHardware: Invalid address %08x PC %08x LR %08x", address, currentMIPS->pc, currentMIPS->r[MIPS_REG_RA]);
if (!g_Config.bIgnoreBadMemAccess) {
// TODO: Not sure what the best way to crash is...
exit(0);

View file

@ -497,8 +497,8 @@ void PSPSetTexture()
if (!texaddr) return;
u8 level = 0;
int format = gstate.texformat & 0xF;
int clutformat = gstate.clutformat & 3;
u32 format = gstate.texformat & 0xF;
u32 clutformat = gstate.clutformat & 3;
DEBUG_LOG(G3D,"Texture at %08x",texaddr);
u8 *texptr = Memory::GetPointer(texaddr);
@ -513,26 +513,23 @@ void PSPSetTexture()
bool match = true;
//TODO: Check more texture parameters, compute real texture hash
if(dim != entry.dim || entry.hash != *(u32*)texptr || entry.format != format)
if (dim != entry.dim || entry.hash != *(u32*)texptr || entry.format != format)
match = false;
//TODO: Check more clut parameters, compute clut hash
if(match && (format >= GE_TFMT_CLUT4 && format <= GE_TFMT_CLUT32) &&
(entry.clutformat != clutformat ||
entry.clutaddr != GetClutAddr(clutformat == GE_CMODE_32BIT_ABGR8888 ? 4 : 2) ||
entry.cluthash != Memory::Read_U32(entry.clutaddr)))
if (match && (format >= GE_TFMT_CLUT4 && format <= GE_TFMT_CLUT32) &&
(entry.clutformat != clutformat ||
entry.clutaddr != GetClutAddr(clutformat == GE_CMODE_32BIT_ABGR8888 ? 4 : 2) ||
entry.cluthash != Memory::Read_U32(entry.clutaddr)))
match = false;
if (match)
{
if (match) {
//got one!
glBindTexture(GL_TEXTURE_2D, entry.texture);
UpdateSamplingParams();
DEBUG_LOG(G3D,"Texture at %08x Found in Cache, applying", texaddr);
return; //Done!
}
else
{
} else {
NOTICE_LOG(G3D,"Texture different or overwritten, reloading at %08x", texaddr);
//Damnit, got overwritten.
@ -785,7 +782,7 @@ void PSPSetTexture()
} else {
write = (u8 *)finalBuf;
}
for (int y = 0; y < h; y++) {
for (u32 y = 0; y < h; y++) {
memmove(write, read, outRowBytes);
read += inRowBytes;
write += outRowBytes;

View file

@ -234,14 +234,12 @@ struct GPUgstate
float tgenMatrix[12];
float boneMatrix[8*12];
};
// Real data in the context ends here
// The rest is cached simplified/converted data for fast access.
// Does not need to be saved when saving/restoring context.
struct GPUStateCache
{
// Real data in the context ends here
// The rest is cached simplified/converted data for fast access.
// What we have here still fits into 512 words, but just barely so we should
// in the future just recompute the below on an sceGeRestoreContext().
u32 vertexAddr;
u32 indexAddr;

View file

@ -1 +1 @@
NDK_MODULE_PATH=..:../native/ext $NDK/ndk-build -j 3
NDK_MODULE_PATH=..:../native/ext $NDK/ndk-build -j3 TARGET_PLATFORM=android-9 $*

92
android/build.xml Normal file
View file

@ -0,0 +1,92 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="PPSSPP" default="help">
<!-- The local.properties file is created and updated by the 'android' tool.
It contains the path to the SDK. It should *NOT* be checked into
Version Control Systems. -->
<property file="local.properties" />
<!-- The ant.properties file can be created by you. It is only edited by the
'android' tool to add properties to it.
This is the place to change some Ant specific build properties.
Here are some properties you may want to change/update:
source.dir
The name of the source directory. Default is 'src'.
out.dir
The name of the output directory. Default is 'bin'.
For other overridable properties, look at the beginning of the rules
files in the SDK, at tools/ant/build.xml
Properties related to the SDK location or the project target should
be updated using the 'android' tool with the 'update' action.
This file is an integral part of the build system for your
application and should be checked into Version Control Systems.
-->
<property file="ant.properties" />
<!-- if sdk.dir was not set from one of the property file, then
get it from the ANDROID_HOME env var.
This must be done before we load project.properties since
the proguard config can use sdk.dir -->
<property environment="env" />
<condition property="sdk.dir" value="${env.ANDROID_HOME}">
<isset property="env.ANDROID_HOME" />
</condition>
<!-- The project.properties file is created and updated by the 'android'
tool, as well as ADT.
This contains project specific properties such as project target, and library
dependencies. Lower level build properties are stored in ant.properties
(or in .classpath for Eclipse projects).
This file is an integral part of the build system for your
application and should be checked into Version Control Systems. -->
<loadproperties srcFile="project.properties" />
<!-- quick check on sdk.dir -->
<fail
message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through the ANDROID_HOME environment variable."
unless="sdk.dir"
/>
<!--
Import per project custom build rules if present at the root of the project.
This is the place to put custom intermediary targets such as:
-pre-build
-pre-compile
-post-compile (This is typically used for code obfuscation.
Compiled code location: ${out.classes.absolute.dir}
If this is not done in place, override ${out.dex.input.absolute.dir})
-post-package
-post-build
-pre-clean
-->
<import file="custom_rules.xml" optional="true" />
<!-- Import the actual build file.
To customize existing targets, there are two options:
- Customize only one target:
- copy/paste the target into this file, *before* the
<import> task.
- customize it to your needs.
- Customize the whole content of build.xml
- copy/paste the content of the rules files (minus the top node)
into this file, replacing the <import> task.
- customize to your needs.
***********************
****** IMPORTANT ******
***********************
In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
in order to avoid having your file be overridden by tools such as "android update project"
-->
<!-- version-tag: 1 -->
<import file="${sdk.dir}/tools/ant/build.xml" />
</project>

16
android/custom_rules.xml Normal file
View file

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="PPSSPP" default="help">
<property name="ndkbuildopt" value=""/>
<target name="-pre-build">
<exec executable="${ndk.dir}/ndk-build" failonerror="true">
<arg line="-j4 ${ndkbuildopt}"/>
<env key="NDK_MODULE_PATH" path="..:../native/ext"/>
</exec>
</target>
<target name="clean" depends="android_rules.clean">
<exec executable="${ndk.dir}/ndk-build" failonerror="true">
<arg value="clean"/>
<env key="NDK_MODULE_PATH" path="..:../native/ext"/>
</exec>
</target>
</project>

View file

@ -24,8 +24,8 @@ LOCAL_MODULE := ppsspp_jni
NATIVE := ../../native
SRC := ../..
LOCAL_CFLAGS := -DUSE_PROFILER -DGL_GLEXT_PROTOTYPES -O2 -fsigned-char -Wall -Wno-multichar -Wno-psabi -std=gnu++0x -Wno-unused-variable -fno-strict-aliasing -ffast-math
LOCAL_CPPFLAGS :=
LOCAL_CFLAGS := -DUSE_PROFILER -DGL_GLEXT_PROTOTYPES -O2 -fsigned-char -Wall -Wno-multichar -Wno-psabi -Wno-unused-variable -fno-strict-aliasing -ffast-math
LOCAL_CPPFLAGS := -std=gnu++0x
LOCAL_C_INCLUDES := \
$(LOCAL_PATH)/../../Common \
$(LOCAL_PATH)/../.. \
@ -68,7 +68,7 @@ LOCAL_SRC_FILES := \
$(SRC)/Common/ThunkARM.cpp \
$(SRC)/Common/Misc.cpp \
$(SRC)/GPU/Math3D.cpp \
$(SRC)/GPU/GpuState.cpp \
$(SRC)/GPU/GPUState.cpp \
$(SRC)/GPU/GLES/Framebuffer.cpp \
$(SRC)/GPU/GLES/DisplayListInterpreter.cpp \
$(SRC)/GPU/GLES/TextureCache.cpp \
@ -89,7 +89,7 @@ LOCAL_SRC_FILES := \
$(SRC)/Core/Loaders.cpp \
$(SRC)/Core/PSPLoaders.cpp \
$(SRC)/Core/MemMap.cpp \
$(SRC)/Core/MemmapFunctions.cpp \
$(SRC)/Core/MemMapFunctions.cpp \
$(SRC)/Core/System.cpp \
$(SRC)/Core/PSPMixer.cpp \
$(SRC)/Core/Debugger/Breakpoints.cpp \

View file

@ -11,5 +11,5 @@
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
# Project target.
target=android-8
target=android-10
android.library.reference.1=../native/android

2
native

@ -1 +1 @@
Subproject commit 2703289d456bf22e80eafbce0aa0307389a51dc6
Subproject commit 8e673a20f70bb636a5cc4ba17cbbe6613869b461