美文网首页工作生活
ActionReplay,CodeBreaker,GameSha

ActionReplay,CodeBreaker,GameSha

作者: LiuJP | 来源:发表于2019-07-01 10:53 被阅读0次

项目说明:和多插件项目结构类似

打包说明build.sh

debug {
//写死,测试使用
target0:com.iplay.gba
}
release{
}

intputGBA:gba插件项目的基础库包括:金手指

intputNDS:nds插件项目的基础库包括:金手指

ndsNDKLibrary:nds的native库,写好之后会打包成so,然后关闭掉

gbaNDKLibrary:nds的native库,写好之后会打包成so,然后关闭掉

frankpi-orange:插件ui界面

controller:悬浮摇杆按钮模块 单独写项目 EmuController

引用顺序 app->dep/xxx->inputGBA || inputNDS->frankpi-orange

操作内容:deps+properties

properties:看例子,

hash:表示rom的md5
Emulator=com.iplay.gba
Emulator0=90048

dep:包含各个插件的项目内容

assets/cheats.xml 配置文件说明:

重点:<!-- --->中内容

<?xml version='1.0' encoding='UTF-8' ?>
<cheats>

    <!--nativeId是个位 1-8 是菜单栏的标志使用  1功能互斥、6是物品、7是nds金手指、8是火焰纹章预留   使用 2,3,4,5,-->
    <cheat cheatCode="" cheatName="拓展模式" commodityId="" isSwitch="0" menuId="0" nativeId="2" />

    <!--nativeId是两位数 9-299 是功能位 -->

    <cheat cheatCode="02037274:0000" cheatName="不遇敌" commodityId="17" isSwitch="1" menuId="2"
        nativeId="17" />

    <!--nativeId 300-400  400-500  500-600  grideView 物品列表的-->
    <cheat cheatCode="" cheatName="全收集" commodityId="" isSwitch="0" menuId="0" nativeId="3" />

    <cheat cheatCode="" cheatName="全道具" commodityId="500" isSwitch="0" menuId="3" nativeId="500" />
    
</cheats>

<cheat />含义:

    isSwitch="0" :按钮
    1:开关
    2:移速二倍,四倍 关
    3:快捷键按钮(一般都不用)
    4:快捷键开关(一般都不用)
    5:拓展标签,二级标签
    6:-+1
    menuId:对应菜单cheat的nativeId
    nativeId:唯一,不可重复,当isSwitch="0" 且menuId="0“,是一级菜单,nativeId就是菜单id
    commodityId:唯一,不可重复,1级菜单的时候不用,二级菜单用的话,二级菜单子功能都不需要用。
    u = "1" 直接解锁
    isSupportSave = "1" 功能记忆保存

<cheat logic />含义:

configManager.xxxxx.xxxx.xxx.xx
configManager.getHashMapCodes().get(a1):获取金手指
configManager.cheatManager.parseCheatCode();
configManager.nativeProcessCheat(a1, a2, a3);

金手指EmuCheat EC 说明:

[速度]
ON=44E2C,60,EA
说明:0200442C 60;0200442D EA

[钱]
ON=44770,9F,86,1
说明:02044770 9F;02044771 86;02044772 01

vba GBA模拟器常用

02044770:9F

GameShark1 来自gameboid

2XXXXXXX YYYYYYYY  把 4 byte 数据 YYYYYYYY 写入到位址 XXXXXXX 上。
1XXXXXXX 0000YYYY  把 2 byte 数据 YYYY   写入到位址 XXXXXXX 上。
0XXXXXXX 000000YY  把 1 byte 数据 YY    写入到位址 XXXXXXX 上。
case 0x3:
      {
        u32 num_addresses = address & 0xFFFF;
        u32 address1, address2;
        u32 i2;

        for(i2 = 0; i2 < num_addresses; i2++)
        {
          address1 = code_ptr[0];
          address2 = code_ptr[1];
          code_ptr += 2;
          i++;

          write_memory32(address1, value);
          if(address2 != 0)
            write_memory32(address2, value);
        }
        break;
      }

Gameshark 来自GBA-Emulator-android

    AF7B768C7 DB18B104或者AF7B768C7DB18B104  是加密过的gs码
    解密算法      
    void cheatsDecryptGSACode(u32& address, u32& value, bool v3) 
    {
      u32 rollingseed = 0xC6EF3720;
      u32 seeds_v1[] =  { 0x09F4FBBD, 0x9681884A, 0x352027E9, 0xF3DEE5A7 }; 
      u32 seeds_v3[] = { 0x7AA9648F, 0x7FAE6994, 0xC0EFAAD5, 0x42712C57 };
      u32 *seeds = v3 ? seeds_v3 : seeds_v1;
      
      int bitsleft = 32;
      while (bitsleft > 0) {
        value -= ((((address << 4) + seeds[2]) ^ (address + rollingseed)) ^
                  ((address >> 5) + seeds[3]));
        address -= ((((value << 4) + seeds[0]) ^ (value + rollingseed)) ^
                    ((value >> 5) + seeds[1]));
        rollingseed -= 0x9E3779B9;
        bitsleft--;
      }
    }
    /**
     * Gameshark code types:
     *
     * NNNNNNNN 001DC0DE - ID code for the game (game 4 character name) from ROM
     * DEADFACE XXXXXXXX - changes decryption seeds
     * 0AAAAAAA 000000YY - 8-bit constant write
     * 1AAAAAAA 0000YYYY - 16-bit constant write
     * 2AAAAAAA YYYYYYYY - 32-bit constant write
     * 3AAAAAAA YYYYYYYY - ??
     * 6AAAAAAA 0000YYYY - 16-bit ROM Patch (address >> 1)
     * 6AAAAAAA 1000YYYY - 16-bit ROM Patch ? (address >> 1)
     * 6AAAAAAA 2000YYYY - 16-bit ROM Patch ? (address >> 1)
     * 8A1AAAAA 000000YY - 8-bit button write
     * 8A2AAAAA 0000YYYY - 16-bit button write
     * 8A3AAAAA YYYYYYYY - 32-bit button write
     * 80F00000 0000YYYY - button slow motion
     * DAAAAAAA 0000YYYY - if address contains 16-bit value enable next code
     * FAAAAAAA 0000YYYY - Master code function
     */

CodeBreaker:8200510a0001 来自GBA-Emulator-android

    /** 
     * CodeBreaker codes types:
     *
     * 0000AAAA 000Y - Game CRC (Y are flags: 8 - CRC, 2 - DI)
     * 1AAAAAAA YYYY - Master Code function (store address at ((YYYY << 0x16)
     *                 + 0x08000100))
     * 2AAAAAAA YYYY - 16-bit or
     * 3AAAAAAA YYYY - 8-bit constant write
     * 4AAAAAAA YYYY - Slide code
     * XXXXCCCC IIII   (C is count and I is address increment, X is value incr.)
     * 5AAAAAAA CCCC - Super code (Write bytes to address, CCCC is count)
     * BBBBBBBB BBBB 
     * 6AAAAAAA YYYY - 16-bit and
     * 7AAAAAAA YYYY - if address contains 16-bit value enable next code
     * 8AAAAAAA YYYY - 16-bit constant write
     * 9AAAAAAA YYYY - change decryption (when first code only?)
     * AAAAAAAA YYYY - if address does not contain 16-bit value enable next code
     * BAAAAAAA YYYY - if 16-bit < YYYY
     * CAAAAAAA YYYY - if 16-bit > YYYY
     * D0000020 YYYY - if button keys equal value enable next code
     * EAAAAAAA YYYY - increase value stored in address
     */

Action Replay 金手指R4 nds主用来自github OpenEmu/DeSmuME-Core 版本1.54

D6000000 0XXXXXXX YYYYYYYY  把 4 byte 数据 YYYYYYYY 写入到位址 XXXXXXX 上。
D7000000 1XXXXXXX 0000YYYY  把 2 byte 数据 YYYY   写入到位址 XXXXXXX 上。
D8000000 2XXXXXXX 000000YY  把 1 byte 数据 YY    写入到位址 XXXXXXX 上。


DA000000 021121AE //控制血量
D7000000 021121AC 
D2000000 00000000

021121AC:021121AE的值

D2000000 00000000 
是结束符

94000130 FFFB0000 
按住select键

D5000000 00000099   value
C0000000 0000004E   size
D8000000 02107206   addr
D2000000 00000000

for(int i=0x02107206; i<=i+0x4E; i++){
    i:00000099 BYTE
}

C0000000 00000003   size
020BB028 270F270F   addr:value
120BB02C 0000270F   addr:value
DC000000 00000148   offset
D2000000 00000000

for(int i=0x020BB028; i<=i+0x3*0x148; i=i+0x148){
    i:270F270F  INT
    i+4:0000270F SHORT
}
void CHEATS::ARparser(CHEATS_LIST& list)
{
    u8  type = 0;
    u8  subtype = 0;
    u32 hi = 0;
    u32 lo = 0;
    u32 addr = 0;
    u32 val = 0;
    // AR temporary vars & flags
    u32 offset = 0;
    u32 datareg = 0;
    u32 loopcount = 0;
    u32 counter = 0;
    u32 if_flag = 0;
    s32 loopbackline = 0;
    u32 loop_flag = 0;
    
    for (int i=0; i < list.num; i++)
    {
        type = list.code[i][0] >> 28;
        subtype = (list.code[i][0] >> 24) & 0x0F;

        hi = list.code[i][0] & 0x0FFFFFFF;
        lo = list.code[i][1];

        if (if_flag > 0) 
        {
            if ((type == 0x0E)) i += ((lo + 7) / 8);
            if ( (type == 0x0D) && (subtype == 0)) if_flag--;   // ENDIF
            if ( (type == 0x0D) && (subtype == 2))              // NEXT & Flush
            {
                if (loop_flag)
                    i = (loopbackline-1);
                else
                {
                    offset = 0;
                    datareg = 0;
                    loopcount = 0;
                    counter = 0;
                    if_flag = 0;
                    loop_flag = 0;
                }
            }
            continue;
        }

        switch (type)
        {
            case 0x00:
            {
                if (hi==0)
                {
                    //manual hook
                }
                else
                if ((hi==0x0000AA99) && (lo==0))    // 0000AA99 00000000   parameter bytes 9..10 for above code (padded with 00s)
                {
                    //parameter bytes 9..10 for above code (padded with 00s)
                }
                else    // 0XXXXXXX YYYYYYYY   word[XXXXXXX+offset] = YYYYYYYY
                {
                    addr = hi + offset;
                    _MMU_write32<ARMCPU_ARM9,MMU_AT_DEBUG>(addr, lo);
                }
            }
            break;

            case 0x01:  // 1XXXXXXX 0000YYYY   half[XXXXXXX+offset] = YYYY
                addr = hi + offset;
                _MMU_write16<ARMCPU_ARM9,MMU_AT_DEBUG>(addr, lo);
            break;

            case 0x02:  // 2XXXXXXX 000000YY   byte[XXXXXXX+offset] = YY
                addr = hi + offset;
                _MMU_write08<ARMCPU_ARM9,MMU_AT_DEBUG>(addr, lo);
            break;

            case 0x03:  // 3XXXXXXX YYYYYYYY   IF YYYYYYYY > word[XXXXXXX]   ;unsigned
                if (hi == 0) hi = offset;   // V1.54+
                val = _MMU_read32<ARMCPU_ARM9,MMU_AT_DEBUG>(hi);
                if ( lo > val )
                {
                    if (if_flag > 0) if_flag--;
                }
                else
                {
                    if_flag++;
                }
            break;

            case 0x04:  // 4XXXXXXX YYYYYYYY   IF YYYYYYYY < word[XXXXXXX]   ;unsigned
                if ((hi == 0x04332211) && (lo == 88776655)) //44332211 88776655   parameter bytes 1..8 for above code  (example)
                {
                    break;
                }
                if (hi == 0) hi = offset;   // V1.54+
                val = _MMU_read32<ARMCPU_ARM9,MMU_AT_DEBUG>(hi);
                if ( lo < val )
                {
                    if (if_flag > 0) if_flag--;
                }
                else
                {
                    if_flag++;
                }
            break;

            case 0x05:  // 5XXXXXXX YYYYYYYY   IF YYYYYYYY = word[XXXXXXX]
                if (hi == 0) hi = offset;   // V1.54+
                val = _MMU_read32<ARMCPU_ARM9,MMU_AT_DEBUG>(hi);
                if ( lo == val )
                {
                    if (if_flag > 0) if_flag--;
                }
                else
                {
                    if_flag++;
                }
            break;

            case 0x06:  // 6XXXXXXX YYYYYYYY   IF YYYYYYYY <> word[XXXXXXX]
                if (hi == 0) hi = offset;   // V1.54+
                val = _MMU_read32<ARMCPU_ARM9,MMU_AT_DEBUG>(hi);
                if ( lo != val )
                {
                    if (if_flag > 0) if_flag--;
                }
                else
                {
                    if_flag++;
                }
            break;

            case 0x07:  // 7XXXXXXX ZZZZYYYY   IF YYYY > ((not ZZZZ) AND half[XXXXXXX])
                if (hi == 0) hi = offset;   // V1.54+
                val = _MMU_read16<ARMCPU_ARM9,MMU_AT_DEBUG>(hi);
                if ( (lo & 0xFFFF) > ( (~(lo >> 16)) & val) )
                {
                    if (if_flag > 0) if_flag--;
                }
                else
                {
                    if_flag++;
                }
            break;

            case 0x08:  // 8XXXXXXX ZZZZYYYY   IF YYYY < ((not ZZZZ) AND half[XXXXXXX])
                if (hi == 0) hi = offset;   // V1.54+
                val = _MMU_read16<ARMCPU_ARM9,MMU_AT_DEBUG>(hi);
                if ( (lo & 0xFFFF) < ( (~(lo >> 16)) & val) )
                {
                    if (if_flag > 0) if_flag--;
                }
                else
                {
                    if_flag++;
                }
            break;

            case 0x09:  // 9XXXXXXX ZZZZYYYY   IF YYYY = ((not ZZZZ) AND half[XXXXXXX])
                if (hi == 0) hi = offset;   // V1.54+
                val = _MMU_read16<ARMCPU_ARM9,MMU_AT_DEBUG>(hi);
                if ( (lo & 0xFFFF) == ( (~(lo >> 16)) & val) )
                {
                    if (if_flag > 0) if_flag--;
                }
                else
                {
                    if_flag++;
                }
            break;

            case 0x0A:  // AXXXXXXX ZZZZYYYY   IF YYYY <> ((not ZZZZ) AND half[XXXXXXX])
                if (hi == 0) hi = offset;   // V1.54+
                val = _MMU_read16<ARMCPU_ARM9,MMU_AT_DEBUG>(hi);
                if ( (lo & 0xFFFF) != ( (~(lo >> 16)) & val) )
                {
                    if (if_flag > 0) if_flag--;
                }
                else
                {
                    if_flag++;
                }
            break;

            case 0x0B:  // BXXXXXXX 00000000   offset = word[XXXXXXX+offset]
                addr = hi + offset;
                offset = _MMU_read32<ARMCPU_ARM9,MMU_AT_DEBUG>(addr);;
            break;

            case 0x0C:
                switch (subtype)
                {
                    case 0x0:   // C0000000 YYYYYYYY   FOR loopcount=0 to YYYYYYYY  ;execute Y+1 times
                        if (loopcount < (lo+1))
                            loop_flag = 1;
                        else
                            loop_flag = 0;
                        loopcount++;
                        loopbackline = i;
                    break;

                    case 0x4:   // C4000000 00000000   offset = address of the C4000000 code ; V1.54
                        printf("AR: untested code C4\n");
                    break;

                    case 0x5:   // C5000000 XXXXYYYY   counter=counter+1, IF (counter AND YYYY) = XXXX ; V1.54
                        counter++;
                        if ( (counter & (lo & 0xFFFF)) == ((lo >> 8) & 0xFFFF) )
                        {
                            if (if_flag > 0) if_flag--;
                        }
                        else
                        {
                            if_flag++;
                        }
                    break;

                    case 0x6:   // C6000000 XXXXXXXX   [XXXXXXXX]=offset ; V1.54
                        _MMU_write32<ARMCPU_ARM9,MMU_AT_DEBUG>(lo, offset);
                    break;
                }
            break;

            case 0x0D:
            {
                switch (subtype)
                {
                    case 0x0:   // D0000000 00000000   ENDIF
                    break;

                    case 0x1:   // D1000000 00000000   NEXT loopcount
                        if (loop_flag)
                            i = (loopbackline-1);
                    break;

                    case 0x2:   // D2000000 00000000   NEXT loopcount, and then FLUSH everything
                        if (loop_flag)
                            i = (loopbackline-1);
                        else
                        {
                            offset = 0;
                            datareg = 0;
                            loopcount = 0;
                            counter = 0;
                            if_flag = 0;
                            loop_flag = 0;
                        }
                    break;

                    case 0x3:   // D3000000 XXXXXXXX   offset = XXXXXXXX
                        offset = lo;
                    break;

                    case 0x4:   // D4000000 XXXXXXXX   datareg = datareg + XXXXXXXX
                        datareg += lo;
                    break;

                    case 0x5:   // D5000000 XXXXXXXX   datareg = XXXXXXXX
                        datareg = lo;
                    break;

                    case 0x6:   // D6000000 XXXXXXXX   word[XXXXXXXX+offset]=datareg, offset=offset+4
                        addr = lo + offset;
                        _MMU_write32<ARMCPU_ARM9,MMU_AT_DEBUG>(addr, datareg);
                        offset += 4;
                    break;

                    case 0x7:   // D7000000 XXXXXXXX   half[XXXXXXXX+offset]=datareg, offset=offset+2
                        addr = lo + offset;
                        _MMU_write16<ARMCPU_ARM9,MMU_AT_DEBUG>(addr, datareg);
                        offset += 2;
                    break;

                    case 0x8:   // D8000000 XXXXXXXX   byte[XXXXXXXX+offset]=datareg, offset=offset+1
                        addr = lo + offset;
                        _MMU_write08<ARMCPU_ARM9,MMU_AT_DEBUG>(addr, datareg);
                        offset += 1;
                    break;

                    case 0x9:   // D9000000 XXXXXXXX   datareg = word[XXXXXXXX+offset]
                        addr = lo + offset;
                        datareg = _MMU_read32<ARMCPU_ARM9,MMU_AT_DEBUG>(addr);
                    break;

                    case 0xA:   // DA000000 XXXXXXXX   datareg = half[XXXXXXXX+offset]
                        addr = lo + offset;
                        datareg = _MMU_read16<ARMCPU_ARM9,MMU_AT_DEBUG>(addr);
                    break;

                    case 0xB:   // DB000000 XXXXXXXX   datareg = byte[XXXXXXXX+offset] ;bugged on pre-v1.54
                        addr = lo + offset;
                        datareg = _MMU_read08<ARMCPU_ARM9,MMU_AT_DEBUG>(addr);
                    break;

                    case 0xC:   // DC000000 XXXXXXXX   offset = offset + XXXXXXXX
                        offset += lo;
                    break;
                }
            }
            break;

            case 0xE:       // EXXXXXXX YYYYYYYY   Copy YYYYYYYY parameter bytes to [XXXXXXXX+offset...]
            {
                u8  *tmp_code = (u8*)(list.code[i+1]);
                u32 addr = hi+offset;
                u32 maxByteReadLocation = ((2 * 4) * (MAX_XX_CODE - i - 1)) - 1; // 2 = 2 array dimensions, 4 = 4 bytes per array element
                
                if (lo <= maxByteReadLocation)
                {
                    for (u32 t = 0; t < lo; t++)
                    {
                        u8  tmp = tmp_code[t];
                        _MMU_write08<ARMCPU_ARM9,MMU_AT_DEBUG>(addr, tmp);
                        addr++;
                    }
                }
                
                i += ((lo + 7) / 8);
            }
            break;

            case 0xF:       // FXXXXXXX YYYYYYYY   Copy YYYYYYYY bytes from [offset..] to [XXXXXXX...]
                for (u32 t = 0; t < lo; t++)
                {
                    u8 tmp = _MMU_read08<ARMCPU_ARM9,MMU_AT_DEBUG>(offset+t);
                    _MMU_write08<ARMCPU_ARM9,MMU_AT_DEBUG>(hi+t, tmp);
                }
            break;
            default: PROGINFO("AR: ERROR unknown command 0x%2X at %08X:%08X\n", type, hi, lo); break;
        }
    }
}

相关文章

网友评论

    本文标题:ActionReplay,CodeBreaker,GameSha

    本文链接:https://www.haomeiwen.com/subject/uzowcctx.html