william 发表于 2025-9-25 21:48:27

记录一些romdata调试中遇到的问题

本帖最后由 william 于 2025-9-25 23:27 编辑

本来是在做fbneo_libretro 增加对nebula格式支持的事,程序写完后,调试过程,发现一些romdata不能运行,就找原因,钻进了源代码的深渊..可能发现了一些问题,也可能不是问题,记录下来,也许对程序编写者或者romdata编写者有参考作用。
记录1:
问题现象:加载游戏时候提示 m0600.rom 文件缺失
romdata 如下:

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
System: PGM
RomName: kovqxzbwss1
Game: 三国战纪 群雄争霸无双版 孙悟空
Parent: kovshpd3dw


qxzb_v500cn.rom,0,800000,0,0


t0600.rom,0,800000,0,0


a0600.rom,0,800000,0,0
a0601.rom,0,800000,0,0
a0602.rom,0,800000,0,0
a0540.rom,0,800000,0,0
a0541.rom,0,800000,0,0
a0542.rom,0,800000,0,0
a0543.rom,0,800000,0,0


b0600.rom,0,800000,0,0
b0540.rom,0,800000,0,0
b0541.rom,0,800000,0,0


m0600.rom,0,800000,0,0


qxzb_v100_china.asic,0,8000,0,0




AsicRegionHackAddress:
Arm7SetIdleLoopAddress:


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
驱动文件定义如下:

static struct BurnRomInfo kovshpd3dwRomDesc[] = {
      { "kovshpd3dw_p0600.rom",                        0x0400000, 0xf88f4b0a, 1 | BRF_PRG | BRF_ESS }, //0 68K Code

      { "kovshpd3dw_t0600.rom",                        0x0800000, 0x1f78d522, 2 | BRF_GRA },                        //1 Tile data

      { "kovshpd3dw_a0600.rom",                        0x0800000, 0x72643288, 3 | BRF_GRA },                        //2 Sprite Color Data
      { "kovshpd3dw_a0601.rom",                        0x0800000, 0x94a0c63d, 3 | BRF_GRA },               //3
      { "kovshpd3dw_a0602.rom",                        0x0800000, 0xaf21456c, 3 | BRF_GRA },               //4
      { "kovshpd3dw_a0540.rom",                        0x0800000, 0xa3204d56, 3 | BRF_GRA },               //5
      { "kovshpd3dw_a0541.rom",                        0x0800000, 0xfac5160e, 3 | BRF_GRA },               //6

      { "kovshpd3dw_b0600.rom",                           0x0800000, 0x0646c5ef, 4 | BRF_GRA },                        //7 Sprite Masks & Color Indexes
      { "kovshpd3dw_b0540.rom",                           0x0800000, 0x8697ec72, 4 | BRF_GRA },                        //8
      { "kovshpd3dw_b0601.rom",                           0x0400000, 0xa0bb1c2f, 4 | BRF_GRA },                        //9
      
      { "kovshpd3dw_m0600.rom",                        0x0400000, 0xec3f335d, 5 | BRF_SND },                        // 10 Samples

      { "kovshpd3dw_v100_china.asic",         0x0004000, 0xd9a43086, 7 | BRF_PRG | BRF_ESS },      // 11 Internal ARM7 Rom
};

程序对rom状态的设置代码是:
程序先用crc找文件,找不到index就是-1,进入下面这个判断语句的处理中,用名字找文件。下面的代码是我对源码有一些修改(蓝色部分是我增加或者修改的),调试用的,标红的部分是设置rom文件状态值的,程序文件如果和驱动定义中大小不一样,就会被置为3(小于标准),4(大于标准),而只有设置为1(ok)和5(skip),后面才会认为是找到并且是正常的。



                                        if (index < 0)
                                        {
                                                if ((g_find_list_path.ignoreCrc && bPatchedRomsetsEnabled) ||
                                                      ((NULL != pDataRomDesc) && (-1 != pRDI->nDescCount)))// romdata mode
                                                {
                                                      uint32_t real_rom_crc;
                                                      int name_index = find_rom_by_name(rom_name, list, count, &real_rom_crc);// 使用局部变量,变量名有替换,用局部变量,避免对index的干扰,毕竟原来代码我不熟悉,我用自己更容易把握的方式调试
                                                      HandleMessage(RETRO_LOG_DEBUG, "ROMDATA Mode===> find_rom_by_name returned name_index=%d, count=%d\n", name_index, count);
                                                      //用名字找到rom文件后的处理
                                                      if (name_index >= 0)
                                                      {
                                                                unknown_crc = true;
                                                                HandleMessage(RETRO_LOG_WARN, "ROMDATA Mode===> Using ROM with unknown crc 0x%08x and name %s from archive %s\n", real_rom_crc, rom_name, g_find_list_path.path.c_str());

                                                                //以下红色部分都是我增加的代码,含义是如果是romdata模式,在通过名字找到rom文件后,要设置文件的状态,避免后面被再度检查
                                                                // ROM处理代码
                                                                if (bIsNeogeoCartGame)
                                                                        set_neogeo_bios_availability(list.szName, list.nCrc, (g_find_list_path.ignoreCrc && bPatchedRomsetsEnabled));

                                                                pRomFind.nZip = z;
                                                                pRomFind.nPos = name_index;
                                                                pRomFind.nState = STAT_OK;


                                                                if (list.nLen < ri.nLen)
                                                                        pRomFind.nState = STAT_SMALL;
                                                                else if (list.nLen > ri.nLen)
                                                                        pRomFind.nState = STAT_LARGE;
                                                                        
                                                                continue;
                                                      }
                                                }
                                        }

这个问题很明显,romdata中音频文件的定义800000超过了驱动文件的定义400000,在程序处理的复查过程中

               //复查前,增加对state的检查      
                HandleMessage(RETRO_LOG_DEBUG, " Pre-check ROM states:\n");
                for (unsigned j = 0; j < nRomCount; j++) {
                        struct BurnRomInfo ri;
                        BurnDrvGetRomInfo(&ri, j);
                        char* rom_name_check;
                        BurnDrvGetRomName(&rom_name_check, j, 0);
                        HandleMessage(RETRO_LOG_DEBUG, " ROM %d (%s): state=%d, crc=0x%08x\n", j, rom_name_check, pRomFind.nState, ri.nCrc);
                }

                     

                // Going over every rom to see if they are properly loaded before we continue ...
                bool ret = true;
                for (unsigned i = 0; i < nRomCount; i++)
                {
                        // Neither the available roms nor the unneeded ones should trigger an error here
                        // 修改复检逻辑:STAT_OK、STAT_SMALL、STAT_LARGE都认为是找到的
                        if (pRomFind.nState != STAT_OK &&
                              pRomFind.nState != STAT_SMALL &&
                              pRomFind.nState != STAT_LARGE &&
                              pRomFind.nState != STAT_SKIP)
                        {
                              struct BurnRomInfo ri;
                              memset(&ri, 0, sizeof(ri));
                              BurnDrvGetRomInfo(&ri, i);
                              if(!(ri.nType & BRF_OPT))
                              {
                                        static char prev;
                                        strcpy(prev, text_missing_files);
                                        BurnDrvGetRomName(&rom_name, i, 0);
                                        sprintf(text_missing_files, RETRO_ERROR_MESSAGES_11, prev, rom_name, ri.nCrc);
                                        log_cb(RETRO_LOG_ERROR, " ROM at index %d with name %s and CRC 0x%08x is required\n", i, rom_name, ri.nCrc);
                                        ret = false;
                              }
                        }
                }

修改代码运行程序,从前端的日志可以看到如下:

: Pre-check ROM states:

: ROM 0 (qxzb_v500cn.rom): state=1, crc=0x00000000

: ROM 1 (t0600.rom): state=1, crc=0x00000000

: ROM 2 (a0600.rom): state=1, crc=0x00000000

: ROM 3 (a0601.rom): state=1, crc=0x00000000

: ROM 4 (a0602.rom): state=1, crc=0x00000000

: ROM 5 (a0540.rom): state=1, crc=0x00000000

: ROM 6 (a0541.rom): state=1, crc=0x00000000

: ROM 7 (a0542.rom): state=1, crc=0x00000000

: ROM 8 (a0543.rom): state=1, crc=0x00000000

: ROM 9 (b0600.rom): state=1, crc=0x00000000

: ROM 10 (b0540.rom): state=1, crc=0x00000000

: ROM 11 (b0541.rom): state=1, crc=0x00000000

: ROM 12 (m0600.rom): state=4, crc=0x00000000

: ROM 13 (qxzb_v100_china.asic): state=1, crc=0x00000000

: ROM 14 (): state=5, crc=0x00000000

: ROM 15 (): state=5, crc=0x00000000

增加state的检查后,发现值是4,是大于驱动的定义,源代码是等于1(ok)或者5(skip)才算通过,4算缺失,上面是我在复查代码判断条件那里增加了对状态3,4的通过,但这个romdata不争气啊,这样改代码让他通过后,可以加载游戏,但过了启动画面后,不能正常运行,然后我又去改了驱动中这个samples类型的rom文件大小的定义,改为800000,可以加载游戏,还是不能正常运行。对于romdata制作者来说,要注意文件大小要和驱动定义的一致,否则复查这里无法通过的,会被置为3,或者4,显示这个文件缺失,不能加载游戏。
这是rom状态的定义
#define STAT_NOFIND0
#define STAT_OK      1
#define STAT_CRC   2
#define STAT_SMALL   3
#define STAT_LARGE   4
#define STAT_SKIP    5


查清这个问题根因,代价是3-4个小时....
附1.调试环境说明:自编前端程序EzMAME,加载修改代码后编译的fbneo_libretro.dll ,通过环境回调中的日志接口,观察核心的运行状态和输出,在核心的代码中调用前端的回调函数(核心已封装)来实现。如果需要前端程序的带控制台调试窗口的版本,可以单独编译提供
附2.nebula格式的romdata支持,已经基本实现,现在在做更多的测试,以消除增加代码的可能潜在问题,并提高健壮性。
附3.做这个的出发点,是尽可能的增加对各种改版文件的支持,让历史沉淀下来的东西不至于随风而散,还能发挥一些作用,增加玩家对改版游戏的体验。个人认为,支持romdata是fbneo对模拟器界的巨大贡献,让rom有了一定的发展空间,模拟游戏的生命力得到进一步的延伸。













漆黑晚星 发表于 2025-9-25 21:52:04

支持一下,如果能把支持代码提交到官方fbneo核心仓库就更好了

william 发表于 2025-9-25 22:01:59

本帖最后由 william 于 2025-9-25 22:04 编辑

漆黑晚星 发表于 2025-9-25 21:52
支持一下,如果能把支持代码提交到官方fbneo核心仓库就更好了
其实支持nebula格式的代码很简单,不是能为不能为的事,是愿意还是不愿意去做...写支持neblula的代码,也就几个小时,最多一天时间,当然调试还需要一些时间,甚至更多时间,我花的时间大部分是在调试五花八门的,各种问题的romdata数据,我得排除是我程序的原因,如果是romdata有问题,我写的代码处理不了,是正常的

爱唱歌的汤姆猫 发表于 2025-9-25 22:42:36

进来支持一下{:3_48:}

Alifu1227 发表于 2025-9-25 23:22:39

进来支持一下

maoer 发表于 2025-9-26 00:05:39

学习一下:loveliness:

am7 发表于 2025-9-26 00:17:59

哦技术大神哦

illegal_day 发表于 2025-9-26 06:52:14

学习一下,谢谢分享
页: [1]
查看完整版本: 记录一些romdata调试中遇到的问题