В сети валяются несколько версий эмуляторов NES с открытыми исходниками.
В основном это либо едва начатые учебные проекты, либо порты написанного на C универсального эмулятора FCE.
Версия под android называется Nesoid, исходники её разбросаны по интернету
http://sourceforge.net/projects/nesoid
https://code.google.com/p/androidnes/source/browse/
https://f-droid.org/repository/browse/?fdfilter=nesoid&fdid=com.androidemu.nes
Полные исходники, с библиотекой Emudroid-Common, (без неё при сборке будет ругаться на нехватку файла utils/Log.h) и интерфейсом на Java, есть только на f-droid, там же есть и собранный из них готовый apk, так что для старта лучше выбрать их.
Библиотеки на C собирается с помощью Android Native SDK, после установки в папке с Nesoid достаточно набрать ndk-build, чтобы собрать нужные для эмулятора библиотека libnes, libemu и libnativehelper.
Для сборки самого эмулятора необходим Android SDK, с доустановленным через SDK Manager Android API 10 (под него по умолчанию собирается эмулятор).
Сами Build tools лучше использовать версии > 19.0, потому что на 19.0 компилятор падает с Buffer overflow exception.
После установки всех необходимых sdk осталось установить систему сборки Ant, и для него указать в файле (PATH_TO_EMULATOR_SOURCES)/local.properties пути к sdk и ndk, например: sdk.dir=C:/android-sdk ndk.dir=C:/android-ndk-r9d
Далее можно собрать эмулятор с помощью команды ant debug и установить на подключенное по usb устройство с android: ant installd
После этого при открытии рома эмулятор будет падать из-за ошибки в сигнатуре метода, поэтому в файле common\emumedia.cpp стоит поправить строчку 116: - env->CallStaticIntMethod(jPeerClass, midSetSurfaceRegion, x, y, w, h); + env->CallStaticVoidMethod(jPeerClass, midSetSurfaceRegion, x, y, w, h); После этого эмулятор будет работать нормально.
Что можно добавить в эмулятор полезного? Практически любую фичу из реализованных в современной версии fceux.
Например, можно вернуть поддерживаемую в FCE опцию автоматической загрузки ips-патчей и проигрывание повторений игры. Если открыть файл romname.nes.ips или romname.nes.fcm, то эмулятор использует его, чтобы открыть игру romname.nes и загрузить данный файл - функция FCEUI_LoadGamе.
Всё, что нужно для активации данной фишки -добавить в GUI эмулятора отображение файлов нужных типов.
Они описаны в файле (EMU_PATH)/res/values/arrays.xml:
Встроить lua быстро не выйдет, но можно добавить свой обработчик в главный цикл эмуляции процессора X6502.
Для этого сначала отредактировать файл (EMU_PATH)/neslib/Android.mk: #LOCAL_CFLAGS += -DASM_6502 #убрать директиву, которая включает код реализации главного цикла на ассемблере.
LOCAL_SRC_FILES +=x6502.c #добавить код реализации главного цикла процессора на C.
Дальше можно просто добавить в функцию X6502_Run_c вызов своего кода:
… CallInjected();
//вызов функции обработки каждый такт процессора.
_PC++; switch(b1) {
…
Затем надо реализовать обработчик для конкретной игры и сделать распознавание конкретных игр по хэшу при открытии.
Можно для теста найти места переключения уровней в Super Mario Bros. Lua-скрипт для win версии FCEUltra:
function logLevel()
local logStr = string.format(“Level %01X-%01X\n”, memory.readbyte(0x75F)+1, memory.readbyte(0x75C)+1)
rint(logStr)
end
memory.registerexec(0xB8A5, logLevel) — переключение обычных сцен
memory.registerexec(0x845A, logLevel) — конец мира 8.
Если подключить к эмулятору Google Play Services (про это нужна отдельная статья), то можно играть в Марио и получать ачивменты за пройденные уровни ^_^.
Ссылка на приложение в маркете: https://play.google.com/store/apps/details?id=com.androidemu.nesachiev