ppspp android编译,安卓PSP模拟器 PPSSPP金手指
PPSSPP金手指使用
1,网上找到对应的psp游戏cmf金手指,例如S ULJM-05035
2,粘贴金手指到记事本,保存为UTF-8编码、ini后缀,文件名去掉“S ”和“-”,最终为ULJM05035.ini3,打开安卓机器上PSP文件夹,新建Cheats文件夹,复制ULJM05035.ini进去
3,启动安卓PPSSPP模拟器选“游戏设置”-“系统设置”-“开启金手指”
psp Cw 金手指解析
CheatOperation CWCheatEngine::InterpretNextCwCheat(const CheatCode &cheat, size_t &i) {
const CheatLine &line1 = cheat.lines[i++];
const uint32_t &arg = line1.part2;
// Filled as needed.
u32 addr;
int type = line1.part1 >> 28;
switch (type) {
case 0x0: // Write 8-bit data (up to 4 bytes.)
addr = GetAddress(line1.part1 & 0x0FFFFFFF);
if (arg & 0xFFFF0000)
return { CheatOp::Write, addr, 4, arg };
else if (arg & 0x0000FF00)
return { CheatOp::Write, addr, 2, arg };
else
return { CheatOp::Write, addr, 1, arg };
case 0x1: // Write 16-bit data.
addr = GetAddress(line1.part1 & 0x0FFFFFFF);
return { CheatOp::Write, addr, 2, arg };
case 0x2: // Write 32-bit data.
addr = GetAddress(line1.part1 & 0x0FFFFFFF);
return { CheatOp::Write, addr, 4, arg };
case 0x3: // Increment/decrement data.
addr = GetAddress(arg & 0x0FFFFFFF);
switch ((line1.part1 >> 20) & 0xF) {
case 1:
return { CheatOp::Add, addr, 1, line1.part1 & 0xFF };
case 2:
return { CheatOp::Subtract, addr, 1, line1.part1 & 0xFF };
case 3:
return { CheatOp::Add, addr, 2, line1.part1 & 0xFFFF };
case 4:
return { CheatOp::Subtract, addr, 2, line1.part1 & 0xFFFF };
case 5:
if (i < cheat.lines.size())
return { CheatOp::Add, addr, 4, cheat.lines[i++].part1 };
return { CheatOp::Invalid };
case 6:
if (i < cheat.lines.size())
return { CheatOp::Subtract, addr, 4, cheat.lines[i++].part1 };
return { CheatOp::Invalid };
default:
return { CheatOp::Invalid };
}
break;
case 0x4: // 32-bit multi-write patch data.
addr = GetAddress(line1.part1 & 0x0FFFFFFF);
if (i < cheat.lines.size()) {
const CheatLine &line2 = cheat.lines[i++];
CheatOperation op = { CheatOp::MultiWrite, addr, 4, line2.part1 };
op.multiWrite.count = arg >> 16;
op.multiWrite.step = (arg & 0xFFFF) * 4;
op.multiWrite.add = line2.part2;
return op;
}
return { CheatOp::Invalid };
case 0x5: // Memcpy command.
addr = GetAddress(line1.part1 & 0x0FFFFFFF);
if (i < cheat.lines.size()) {
const CheatLine &line2 = cheat.lines[i++];
CheatOperation op = { CheatOp::CopyBytesFrom, addr, 0, arg };
op.copyBytesFrom.destAddr = GetAddress(line2.part1 & 0x0FFFFFFF);
return op;
}
return { CheatOp::Invalid };
case 0x6: // Pointer commands.
addr = GetAddress(line1.part1 & 0x0FFFFFFF);
if (i < cheat.lines.size()) {
const CheatLine &line2 = cheat.lines[i++];
int count = (line2.part1 & 0xFFFF) - 1;
// Validate lines to process - make sure we stay inside cheat.lines.
if (i + count > cheat.lines.size())
return { CheatOp::Invalid };
CheatOperation op = { CheatOp::CwCheatPointerCommands, addr, 0, arg };
op.pointerCommands.offset = (int)line2.part2;
// TODO: Verify sign handling. Is this really supposed to sign extend?
op.pointerCommands.baseOffset = ((int)line2.part1 >> 20) * 4;
op.pointerCommands.count = count;
op.pointerCommands.type = (line2.part1 >> 16) & 0xF;
return op;
}
return { CheatOp::Invalid };
case 0x7: // Boolean data operations.
addr = GetAddress(line1.part1 & 0x0FFFFFFF);
switch (arg >> 16) {
case 0x0000: // 8-bit OR.
return { CheatOp::Or, addr, 1, arg & 0xFF };
case 0x0001: // 16-bit OR.
return { CheatOp::Or, addr, 2, arg & 0xFFFF };
case 0x0002: // 8-bit AND.
return { CheatOp::And, addr, 1, arg & 0xFF };
case 0x0003: // 16-bit AND.
return { CheatOp::And, addr, 2, arg & 0xFFFF };
case 0x0004: // 8-bit XOR.
return { CheatOp::Xor, addr, 1, arg & 0xFF };
case 0x0005: // 16-bit XOR.
return { CheatOp::Xor, addr, 2, arg & 0xFFFF };
}
return { CheatOp::Invalid };
case 0x8: // 8-bit or 16-bit multi-write patch data.
addr = GetAddress(line1.part1 & 0x0FFFFFFF);
if (i < cheat.lines.size()) {
const CheatLine &line2 = cheat.lines[i++];
const bool is8Bit = (line2.part1 & 0xFFFF0000) == 0;
const uint32_t val = is8Bit ? (line2.part1 & 0xFF) : (line2.part1 & 0xFFFF);
CheatOperation op = { CheatOp::MultiWrite, addr, is8Bit ? 1 : 2, val };
op.multiWrite.count = arg >> 16;
op.multiWrite.step = (arg & 0xFFFF) * (is8Bit ? 1 : 2);
op.multiWrite.add = line2.part2;
return op;
}
return { CheatOp::Invalid };
case 0xB: // Delay command.
return { CheatOp::Delay, 0, 0, arg };
case 0xC: // 32-bit equal check / code stopper.
addr = GetAddress(line1.part1 & 0x0FFFFFFF);
return { CheatOp::Assert, addr, 4, arg };
case 0xD: // Line skip tests & joker codes.
switch (arg >> 28) {
case 0x0: // 16-bit next line skip test.
case 0x2: // 8-bit next line skip test.
addr = GetAddress(line1.part1 & 0x0FFFFFFF);
{
const bool is8Bit = (arg >> 28) == 0x2;
const uint32_t val = is8Bit ? (arg & 0xFF) : (arg & 0xFFFF);
CheatOp opcode;
switch ((arg >> 20) & 0xF) {
case 0x0:
opcode = CheatOp::IfEqual;
break;
case 0x1:
opcode = CheatOp::IfNotEqual;
break;
case 0x2:
opcode = CheatOp::IfLess;
break;
case 0x3:
opcode = CheatOp::IfGreater;
break;
default:
return { CheatOp::Invalid };
}
CheatOperation op = { opcode, addr, is8Bit ? 1 : 2, val };
op.ifTypes.skip = 1;
return op;
}
case 0x1: // Joker code - button pressed.
case 0x3: // Inverse joker code - button not pressed.
{
bool pressed = (arg >> 28) == 0x1;
CheatOperation op = { pressed ? CheatOp::IfPressed : CheatOp::IfNotPressed, 0, 0, arg & 0x0FFFFFFF };
op.ifTypes.skip = (line1.part1 & 0xFF) + 1;
return op;
}
case 0x4: // Adress equal test.
case 0x5: // Address not equal test.
case 0x6: // Address less than test.
case 0x7: // Address greater than test.
addr = GetAddress(line1.part1 & 0x0FFFFFFF);
if (i < cheat.lines.size()) {
const CheatLine &line2 = cheat.lines[i++];
const int sz = 1 << (line2.part2 & 0xF);
CheatOp opcode;
switch (arg >> 28) {
case 0x4:
opcode = CheatOp::IfAddrEqual;
break;
case 0x5:
opcode = CheatOp::IfAddrNotEqual;
break;
case 0x6:
opcode = CheatOp::IfAddrLess;
break;
case 0x7:
opcode = CheatOp::IfAddrGreater;
break;
default:
return { CheatOp::Invalid };
}
CheatOperation op = { opcode, addr, sz, 0 };
op.ifAddrTypes.skip = line2.part1;
op.ifAddrTypes.compareAddr = GetAddress(arg & 0x0FFFFFFF);
return op;
}
return { CheatOp::Invalid };
default:
return { CheatOp::Invalid };
}
case 0xE: // Multiple line skip tests.
addr = GetAddress(arg & 0x0FFFFFFF);
{
const bool is8Bit = (line1.part1 >> 24) == 0xE1;
const uint32_t val = is8Bit ? (line1.part1 & 0xFF) : (line1.part1 & 0xFFFF);
CheatOp opcode;
switch (arg >> 28) {
case 0x0:
opcode = CheatOp::IfEqual;
break;
case 0x1:
opcode = CheatOp::IfNotEqual;
break;
case 0x2:
opcode = CheatOp::IfLess;
break;
case 0x3:
opcode = CheatOp::IfGreater;
break;
default:
return { CheatOp::Invalid };
}
CheatOperation op = { opcode, addr, is8Bit ? 1 : 2, val };
op.ifTypes.skip = (line1.part1 >> 16) & (is8Bit ? 0xFF : 0xFFF);
return op;
}
default:
return { CheatOp::Invalid };
}
}
void CWCheatEngine::ExecuteOp(const CheatOperation &op, const CheatCode &cheat, size_t &i) {
switch (op.op) {
case CheatOp::Invalid:
i = cheat.lines.size();
break;
case CheatOp::Noop:
break;
case CheatOp::Write:
if (Memory::IsValidAddress(op.addr)) {
InvalidateICache(op.addr, 4);
if (op.sz == 1)
Memory::Write_U8((u8)op.val, op.addr);
else if (op.sz == 2)
Memory::Write_U16((u16)op.val, op.addr);
else if (op.sz == 4)
Memory::Write_U32((u32)op.val, op.addr);
}
break;
case CheatOp::Add:
ApplyMemoryOperator(op, [](uint32_t a, uint32_t b) {
return a + b;
});
break;
case CheatOp::Subtract:
ApplyMemoryOperator(op, [](uint32_t a, uint32_t b) {
return a - b;
});
break;
case CheatOp::Or:
ApplyMemoryOperator(op, [](uint32_t a, uint32_t b) {
return a | b;
});
break;
case CheatOp::And:
ApplyMemoryOperator(op, [](uint32_t a, uint32_t b) {
return a & b;
});
break;
case CheatOp::Xor:
ApplyMemoryOperator(op, [](uint32_t a, uint32_t b) {
return a ^ b;
});
break;
case CheatOp::MultiWrite:
if (Memory::IsValidAddress(op.addr)) {
InvalidateICache(op.addr, op.multiWrite.count * op.multiWrite.step + op.sz);
uint32_t data = op.val;
uint32_t addr = op.addr;
for (uint32_t a = 0; a < op.multiWrite.count; a++) {
if (Memory::IsValidAddress(addr)) {
if (op.sz == 1)
Memory::Write_U8((u8)data, addr);
else if (op.sz == 2)
Memory::Write_U16((u16)data, addr);
else if (op.sz == 4)
Memory::Write_U32((u32)data, addr);
}
addr += op.multiWrite.step;
data += op.multiWrite.add;
}
}
break;
case CheatOp::CopyBytesFrom:
if (Memory::IsValidRange(op.addr, op.val) && Memory::IsValidRange(op.copyBytesFrom.destAddr, op.val)) {
InvalidateICache(op.addr, op.val);
InvalidateICache(op.copyBytesFrom.destAddr, op.val);
Memory::MemcpyUnchecked(op.copyBytesFrom.destAddr, op.addr, op.val);
}
break;
case CheatOp::Delay:
// TODO: Not supported.
break;
case CheatOp::Assert:
if (Memory::IsValidAddress(op.addr)) {
InvalidateICache(op.addr, 4);
if (Memory::Read_U32(op.addr) != op.val) {
i = cheat.lines.size();
}
}
break;
case CheatOp::IfEqual:
if (!TestIf(op, [](int a, int b) { return a == b; })) {
i += (size_t)op.ifTypes.skip;
}
break;
case CheatOp::IfNotEqual:
if (!TestIf(op, [](int a, int b) { return a != b; })) {
i += (size_t)op.ifTypes.skip;
}
break;
case CheatOp::IfLess:
if (!TestIf(op, [](int a, int b) { return a < b; })) {
i += (size_t)op.ifTypes.skip;
}
break;
case CheatOp::IfGreater:
if (!TestIf(op, [](int a, int b) { return a > b; })) {
i += (size_t)op.ifTypes.skip;
}
break;
case CheatOp::IfAddrEqual:
if (!TestIfAddr(op, [](int a, int b) { return a == b; })) {
i += (size_t)op.ifAddrTypes.skip;
}
break;
case CheatOp::IfAddrNotEqual:
if (!TestIfAddr(op, [](int a, int b) { return a != b; })) {
i += (size_t)op.ifAddrTypes.skip;
}
break;
case CheatOp::IfAddrLess:
if (!TestIfAddr(op, [](int a, int b) { return a < b; })) {
i += (size_t)op.ifAddrTypes.skip;
}
break;
case CheatOp::IfAddrGreater:
if (!TestIfAddr(op, [](int a, int b) { return a > b; })) {
i += (size_t)op.ifAddrTypes.skip;
}
break;
case CheatOp::IfPressed:
// Button Code
// SELECT 0x00000001
// START 0x00000008
// DPAD UP 0x00000010
// DPAD RIGHT 0x00000020
// DPAD DOWN 0x00000040
// DPAD LEFT 0x00000080
// L TRIGGER 0x00000100
// R TRIGGER 0x00000200
// TRIANGLE 0x00001000
// CIRCLE 0x00002000
// CROSS 0x00004000
// SQUARE 0x00008000
// HOME 0x00010000
// HOLD 0x00020000
// WLAN 0x00040000
// REMOTE HOLD 0x00080000
// VOLUME UP 0x00100000
// VOLUME DOWN 0x00200000
// SCREEN 0x00400000
// NOTE 0x00800000
if ((__CtrlPeekButtons() & op.val) != op.val) {
i += (size_t)op.ifTypes.skip;
}
break;
case CheatOp::IfNotPressed:
if ((__CtrlPeekButtons() & op.val) == op.val) {
i += (size_t)op.ifTypes.skip;
}
break;
case CheatOp::CwCheatPointerCommands:
{
InvalidateICache(op.addr + op.pointerCommands.baseOffset, 4);
u32 base = Memory::Read_U32(op.addr + op.pointerCommands.baseOffset);
u32 val = op.val;
int type = op.pointerCommands.type;
for (int a = 0; a < op.pointerCommands.count; ++a) {
const CheatLine &line = cheat.lines[i++];
switch (line.part1 >> 28) {
case 0x1: // type copy byte
{
InvalidateICache(op.addr, 4);
u32 srcAddr = Memory::Read_U32(op.addr) + op.pointerCommands.offset;
u32 dstAddr = Memory::Read_U32(op.addr + op.pointerCommands.baseOffset) + (line.part1 & 0x0FFFFFFF);
if (Memory::IsValidRange(dstAddr, val) && Memory::IsValidRange(srcAddr, val)) {
InvalidateICache(dstAddr, val);
InvalidateICache(srcAddr, val);
Memory::MemcpyUnchecked(dstAddr, srcAddr, val);
}
// Don't perform any further action.
type = -1;
}
break;
case 0x2:
case 0x3: // type pointer walk
{
int walkOffset = (int)line.part1 & 0x0FFFFFFF;
if ((line.part1 >> 28) == 0x3) {
walkOffset = -walkOffset;
}
InvalidateICache(base + walkOffset, 4);
base = Memory::Read_U32(base + walkOffset);
switch (line.part2 >> 28) {
case 0x2:
case 0x3: // type pointer walk
walkOffset = line.part2 & 0x0FFFFFFF;
if ((line.part2 >> 28) == 0x3) {
walkOffset = -walkOffset;
}
InvalidateICache(base + walkOffset, 4);
base = Memory::Read_U32(base + walkOffset);
break;
default:
// Unexpected value in cheat line?
break;
}
}
break;
case 0x9: // type multi address write
base += line.part1 & 0x0FFFFFFF;
val += line.part2;
break;
default:
// Unexpected value in cheat line?
break;
}
}
switch (type) {
case 0: // 8 bit write
InvalidateICache(base + op.pointerCommands.offset, 4);
Memory::Write_U8((u8)val, base + op.pointerCommands.offset);
break;
case 1: // 16-bit write
InvalidateICache(base + op.pointerCommands.offset, 4);
Memory::Write_U16((u16)val, base + op.pointerCommands.offset);
break;
case 2: // 32-bit write
InvalidateICache(base + op.pointerCommands.offset, 4);
Memory::Write_U32((u32)val, base + op.pointerCommands.offset);
break;
case 3: // 8 bit inverse write
InvalidateICache(base - op.pointerCommands.offset, 4);
Memory::Write_U8((u8)val, base - op.pointerCommands.offset);
break;
case 4: // 16-bit inverse write
InvalidateICache(base - op.pointerCommands.offset, 4);
Memory::Write_U16((u16)val, base - op.pointerCommands.offset);
break;
case 5: // 32-bit inverse write
InvalidateICache(base - op.pointerCommands.offset, 4);
Memory::Write_U32((u32)val, base - op.pointerCommands.offset);
break;
case -1: // Operation already performed, nothing to do
break;
}
}
break;
default:
assert(false);
}
}
void CWCheatEngine::Run() {
for (CheatCode cheat : cheats_) {
// InterpretNextOp and ExecuteOp move i.
for (size_t i = 0; i < cheat.lines.size(); ) {
CheatOperation op = InterpretNextOp(cheat, i);
ExecuteOp(op, cheat, i);
}
}
}
ppspp android编译,安卓PSP模拟器 PPSSPP金手指相关推荐
- android psp模拟器 怪物猎人,曾经狩猎的日子:安卓PSP模拟器评测:怪物猎人P3
原标题:曾经狩猎的日子:安卓PSP模拟器评测:怪物猎人P3 怪物猎人这款狩猎游戏大家应该很熟悉了吧,PSP掌机中的神作,今天在安卓手机上面用PPSSPP模拟器玩<怪物猎人P3>,这款游戏发 ...
- 电脑psp模拟器(ppsspp) v1.0.0 中文版
电脑psp模拟器(ppsspp) v1.0.0 中文版 软件大小:10.3MB 软件语言:简体中文 软件类别:游戏工具 软件授权:免费版 更新时间:2015-02-03 应用平台:/Win8/Win7 ...
- 安卓ps2模拟器_安卓PSP模拟器评测:合金装备 和平步行者
哈喽,大家好,好久没有玩PSP模拟器了,昨晚下载了一款PSP游戏的3A大作,这款游戏名字叫做<合金装备 和平步行者>,这款游戏发售时间是:2010年4月29日.本作是真真正正由小岛秀夫亲自 ...
- linux系统装psp,Linux上的PSP模拟器PPSSPP 1.7 发布了
索尼PSP模拟器PPSSPP 1.7几天前发布了,大量的兼容性和错误修正. 以下是如何在Ubuntu 18.04,Ubuntu 18.10,Ubuntu 16.04和Ubuntu 14.04中安装它. ...
- psp模拟器linux,PSP模拟器PPSSPP 1.7 发布,兼容性和错误修正
索尼PSP模拟器PPSSPP 1.7几天前发布了,大量的兼容性和错误修正. 以下是如何在Ubuntu 18.04,Ubuntu 18.10,Ubuntu 16.04和Ubuntu 14.04中安装它. ...
- android10 psp模拟器,ppsspp模拟器安卓版
游戏介绍: <ppsspp模拟器安卓版>是一款为安卓手机量身打造的手机psp模拟器,软件自带官方中文,并且对于psp游戏的模拟非常完善,你只需要安装软件后下载相应的游戏,即可在手机上自由爽 ...
- psp模拟器完美字库_安卓PSP模拟器评测:《无双大蛇》最强无双
<无双大蛇>是由日本KOEI TECMO开发的一款无双游戏,属于无双大乱斗游戏,2008年在PSP发布,原来是发布在PS2游戏主机上面的,游戏讲述的是<无双大蛇>以魔王·远吕智 ...
- ppspp android编译,PPSSPP Windows和Android更新版本至1.1~~
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 October 4, 2015: PPSSPP 1.1! It's been a while, but there are some major new ...
- 安卓ps2模拟器_安卓PSP模拟器评测:如龙 黑豹2 阿修罗篇
大家好,今天给大家介绍一个PSP游戏,在家太无聊了,PSV被姐姐拿去玩了,PS4又没有在身边,只能去下载PSP游戏了,不过我是用模拟器玩,这款游戏名字叫做<如龙 黑豹2 阿修罗篇>,用的是 ...
最新文章
- 2021综述:视频监控中的多目标跟踪
- leetcode 53.最大子序和
- 第二篇:阿里数据中台之OneData体系1
- mysql innodb 锁_MySQL/InnoDB锁机制
- BufferedWriter_字符缓冲输出流
- 堆排序算法---属于选择排序
- 一步一步教你使用AgileEAS.NET基础类库进行应用开发-系列目录
- saltstack系列2之zabbix-agent自动化部署
- easyBCD多系统引导软件
- LaTeX常用符号(持续更新)
- Hello World, Hello Me | 图灵人工智能书单
- 如何成为很厉害的程序员?- 读《精进》
- xz2p更新android 9,索尼 XZ2 迎来安卓 9.0 更新,但少了全面屏手势
- android 区分平板,加量不加价!台电首款基于Android 11的平板终上市
- java.lang.IncompatibleClassChangeError 常见错误
- 对于支付宝里面推荐的基金大家怎么看待呢?
- 无法共享别的计算机,本机能上网,但打印机不能共享,别的电脑也不能Ping以通本机,是什么原因?...
- 在Word中让公式在中间,公式编号右对齐
- 【程序】STM32H743ZI单片机驱动DP83848以太网PHY芯片,移植lwip 2.1.3协议栈,并加入网线热插拔检测的功能
- 全国青少年编程等级考试python一级真题2020年9月(含题库答题软件账号)
热门文章
- 浅谈Linux信号那些事
- 计算机毕业设计源代码java项目开发实例ssm+mysql实现零食商城系统(电商项目)[包运行成功]
- 数据分析(一)百度指数,代码如下:
- 学海无涯!回头是岸!
- 国内常用git仓库 中文gitlab
- python 控件失去焦点_Tk / Tkinter:检测应用程序失去焦点 - python
- 对iOS开发有用的一些自动化处理脚本
- 计算机二级python2020年考试时间_2020年计算机二级考试时间最新安排
- idea代码字体大小放大和缩小的快捷键设置
- ansible命令行常用模块