최근 이 문제를 깊이, AI 친구들과 함께 고민하였다.
증상은 ES-DE를 프론트엔드로 쓰고 있을 때 Retroarch로 구동하는 게임은 문제가 없지만, 외부의 에뮬레이터를 사용해야 하는 경우에는 제대로 작동하지 않고 에뮬레이터의 메인 화면 등으로 연결되는 문제이다. 내 경우에는 Duckstation(PS1), PPSSPP(PSP), Redream(Dreamcast), NetherSX2(PS2)가 말썽이었다.
핵심은 ES-DE가 ROM의 주소(위치)를 개별 에뮬레이터에 넘겨 줄 때, 어떤 형식으로 넘겨줄 것인가의 문제이다. 크게 보면 ES-DE는 3가지 변수를 사용할 수 있다.
1) ROMSAF
일괄 디폴트로 잡혀 있는 변수다. content://com.android.externalstorage.documents/… 와 같은 형태로 주소를 넘겨준다.
2) ROMPROVIDER
ES-DE가 생성하는 변수로 content://org.es_de.frontend.files/…의 형태이다.
3) ROMRAW
/storage/xxxx-xxxx/Games/ps2/xxx.iso와 같이 파일 문자열을 그대로 보낸다.
문제는 에뮬레이터에 따라서 1)로 해결되는 경우, 2)만 먹히는 경우, 3)만 먹히는 경우가 제각각이라는 것이다. 즉, 1)로 주소 전달이 실패하는 경우 2)나 3)으로 시도해봐야 한다는 것이다. 그러면 이 변수는 어디서 어떻게 바꿔줄 수 있는가? es_systems.xml에서 규정해야 한다. 이 파일은 바꾸고 싶은 부분만 발췌한 후 파일로 만든 다음에 ES-DE/custom_systems(처음 ES-DE 구동할 때에 어디에 폴더를 만들 것인지 설정했을 것이다. 바로 그 폴더이다…) 폴더에 저장하면 된다. 가령 기본 설정에 어떻게 반영되는지를 찾아보면 플레이스테이션 2의 경우는 다음과 같은 내용이다.
<system> <name>ps2</name> <fullname>Sony PlayStation 2</fullname> <path>%ROMPATH%/ps2</path> <extension>.bin .BIN .chd .CHD .ciso .CISO .cso .CSO .dump .DUMP .elf .ELF .gz .GZ .m3u .M3U .mdf .MDF .img .IMG .iso .ISO .isz .ISZ .ngr .NRG</extension> <command label="AetherSX2 (Standalone)">%EMULATOR_AETHERSX2% %ACTIVITY_CLEAR_TASK% %ACTIVITY_CLEAR_TOP% %ACTION%=android.intent.action.MAIN %EXTRA_bootPath%=%ROMSAF%</command> <command label="Play! (Standalone)">%EMULATOR_PLAY!% %ACTION%=android.intent.action.VIEW %DATA%=%ROMSAF%</command> <platform>ps2</platform> <theme>ps2</theme> </system>
이대로 실행하면 NetherSX2는 파일 이름이 필요하다든지 못 찾겠다고 하면서 아무런 일도 하지 않는다. %EXTRA_bootPath%=%ROMSAF% 부분에서 ‘content://com.android.externalstorage.documents/… ‘을 해석해 ROM 파일 위치를 추출하는 게 아니라, 그냥 문자열 그대로를 파일 이름으로 받아서 ROM 위치를 못 찾는 것이다. 따라서 해당 변수를 ROMRAW로 바꿔 파일명 그대로를 전달해야 한다. 이를 적용하면 es_system.xml은 이렇게 만들어야 할 것이다.
<systemList>
<system>
<name>ps2</name>
<fullname>Sony PlayStation 2</fullname>
<path>%ROMPATH%/ps2</path>
<extension>.bin .BIN .chd .CHD .ciso .CISO .cso .CSO .dump .DUMP .elf .ELF .gz .GZ .m3u .M3U .mdf .MDF .img .IMG .iso .ISO .isz .ISZ .ngr .NRG</extension>
<command label="NetherSX2(AetherSX2) (Standalone)">%EMULATOR_AETHERSX2% %ACTIVITY_CLEAR_TASK% %ACTIVITY_CLEAR_TOP% %ACTION%=android.intent.action.MAIN %EXTRA_bootPath%=%ROMRAW%</command>
<command label="Play! (Standalone)">%EMULATOR_PLAY!% %ACTION%=android.intent.action.VIEW %DATA%=%ROMSAF%</command>
<platform>ps2</platform>
<theme>ps2</theme>
</system>
</systemList>
나머지도 마찬가지 원리에 따라서 진행하면 된다.
PPSSPP는 ROMPROVIDER, Redream도 ROMPROVIDER, DuckStation은 ROMRAW 변수가 먹혔다. 이를 다 적용하려면 아래와 같은 내용으로 es_system.xml 파일을 작성하면 된다.
<systemList> <system> <name>ps2</name> <fullname>Sony PlayStation 2</fullname> <path>%ROMPATH%/ps2</path> <extension>.bin .BIN .chd .CHD .ciso .CISO .cso .CSO .dump .DUMP .elf .ELF .gz .GZ .m3u .M3U .mdf .MDF .img .IMG .iso .ISO .isz .ISZ .ngr .NRG</extension> <command label="NetherSX2(AetherSX2) (Standalone)">%EMULATOR_AETHERSX2% %ACTIVITY_CLEAR_TASK% %ACTIVITY_CLEAR_TOP% %ACTION%=android.intent.action.MAIN %EXTRA_bootPath%=%ROMRAW%</command> <command label="Play! (Standalone)">%EMULATOR_PLAY!% %ACTION%=android.intent.action.VIEW %DATA%=%ROMSAF%</command> <platform>ps2</platform> <theme>ps2</theme> </system> <system> <name>psx</name> <fullname>Sony PlayStation</fullname> <path>%ROMPATH%/psx</path> <extension>.bin .BIN .cbn .CBN .ccd .CCD .chd .CHD .cue .CUE .ecm .ECM .exe .EXE .img .IMG .iso .ISO .m3u .M3U .mdf .MDF .mds .MDS .minipsf .MINIPSF .pbp .PBP .psexe .PSEXE .psf .PSF .toc .TOC .z .Z .znx .ZNX .7z .7Z .zip .ZIP</extension> <command label="Beetle PSX">%EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mednafen_psx_libretro_android.so %EXTRA_ROM%=%ROM%</command> <command label="Beetle PSX HW">%EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=mednafen_psx_hw_libretro_android.so %EXTRA_ROM%=%ROM%</command> <command label="PCSX ReARMed">%EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=pcsx_rearmed_libretro_android.so %EXTRA_ROM%=%ROM%</command> <command label="SwanStation">%EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=swanstation_libretro_android.so %EXTRA_ROM%=%ROM%</command> <command label="DuckStation (Standalone)">%EMULATOR_DUCKSTATION% %ACTIVITY_CLEAR_TASK% %ACTIVITY_CLEAR_TOP% %EXTRABOOL_resumeState%=false %EXTRA_bootPath%=%ROMRAW%</command> <command label="ePSXe (Standalone)">%EMULATOR_EPSXE% %ACTION%=android.intent.action.MAIN %EXTRA_com.epsxe.ePSXe.isoName%=%ROMSAF%</command> <command label="FPseNG (Standalone)">%EMULATOR_FPSE-NG% %ACTION%=android.intent.action.VIEW %DATA%=%ROMPROVIDER%</command> <command label="FPse (Standalone)">%EMULATOR_FPSE% %ACTION%=android.intent.action.VIEW %DATA%=%ROMPROVIDER%</command> <platform>psx</platform> <theme>psx</theme> </system> <system> <name>psp</name> <fullname>Sony PlayStation Portable</fullname> <path>%ROMPATH%/psp</path> <extension>.chd .CHD .cso .CSO .elf .ELF .iso .ISO .pbp .PBP .prx .PRX .7z .7Z .zip .ZIP</extension> <command label="PPSSPP">%EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=ppsspp_libretro_android.so %EXTRA_ROM%=%ROM%</command> <command label="PPSSPP (Standalone)">%EMULATOR_PPSSPP% %ACTION%=android.intent.action.VIEW %CATEGORY%=android.intent.category.DEFAULT %DATA%=%ROMPROVIDER%</command> <platform>psp</platform> <theme>psp</theme> </system> <system> <name>dreamcast</name> <fullname>Sega Dreamcast</fullname> <path>%ROMPATH%/dreamcast</path> <extension>.cdi .CDI .chd .CHD .cue .CUE .dat .DAT .elf .ELF .gdi .GDI .iso .ISO .lst .LST .m3u .M3U .7z .7Z .zip .ZIP</extension> <command label="Flycast">%EMULATOR_RETROARCH% %EXTRA_CONFIGFILE%=/storage/emulated/0/Android/data/%ANDROIDPACKAGE%/files/retroarch.cfg %EXTRA_LIBRETRO%=flycast_libretro_android.so %EXTRA_ROM%=%ROM%</command> <command label="Flycast (Standalone)">%EMULATOR_FLYCAST% %ACTION%=android.intent.action.VIEW %DATA%=%ROM%</command> <command label="Redream (Standalone)">%EMULATOR_REDREAM% %ACTION%=android.intent.action.VIEW %DATA%=%ROMPROVIDER%</command> <platform>dreamcast</platform> <theme>dreamcast</theme> </system> </systemList>
위의 파일은 오타가 있을 수 있으니 신중하게 고려하시기 바라고, 아무튼 이렇게 작성한 파일을 아까 파일이 있어야 할 경로로 넣으면 대체로 될 것이다. 다른 에뮬레이터의 경우, 뭐가 되고 뭐가 안 되는지는 맨땅에 헤딩하기로 찾아야 한다.

Comments are closed, but trackbacks and pingbacks are open.