Next Generation Emulation banner

Status
Not open for further replies.
1 - 20 of 125 Posts

·
Registered
Joined
·
58 Posts
Discussion Starter #1
Having been out of the emulation scene for a few years, I recently decided to play some of my old N64 ROMs. I went with Mupen64Plus 1.99.3 for the emulator, and I was so impressed with the program that I had to dig around in the source code. I really like the modular nature of this library - it is perfectly structured to facilitate porting to new systems.

I've decided to take a crack at porting it to Android, using the NDK (so I can use native c/c++ directly rather than having to translate the entire project into Java). I realize that current devices are probably not at a level to run N64 emulation smoothly yet, but by the time I finish the port, who knows?

I'll be using pelya's Android SDL port, which doesn't require the target device to be rooted (allowing for easy distribution through the Android Market and avoiding any licensing/warranty concerns that can come with rooting). My initial challenge is translating the Makefiles used by the Mupen64Plus source into NDK-speak (I'm rather new to the whole Makefile concept, so it will be a bit of an initial learning curve). I'll post my progress on this project here. Comments and suggestions are welcome. Also, if anyone else is already working on an Android port of Mupen64Plus, I'd be happy to collaborate.
 

·
Registered
Joined
·
58 Posts
Discussion Starter #2
I thought I would post a progress update, in case anyone is interested. I've got the basic project set up, utilizing Pelya's SDL port and the n64oid source code (based on Mupen64Plus 1.99.1). Current logcat output is very encouraging:

Code:
12-04 14:14:27.830: INFO/System.out(2130): libSDL: setting envvar LANGUAGE to 'en_US'
12-04 14:14:27.830: INFO/System.out(2130): libSDL: accelerometer start required: false
12-04 14:14:27.830: INFO/libSDL(2130): Calling SDL_main("mupen64plus --corelib /data/data/paulscode.android.mupen64plus/lib/libcore.so --rsp /data/data/paulscode.android.mupen64plus/lib/librsp-hle.so --audio /data/data/paulscode.android.mupen64plus/lib/libaudio-sdl.so roms/mario.n64")
12-04 14:14:27.830: INFO/libSDL(2130): param 0 = "mupen64plus"
12-04 14:14:27.830: INFO/libSDL(2130): param 1 = "--corelib"
12-04 14:14:27.830: INFO/libSDL(2130): param 2 = "/data/data/paulscode.android.mupen64plus/lib/libcore.so"
12-04 14:14:27.830: INFO/libSDL(2130): param 3 = "--rsp"
12-04 14:14:27.830: INFO/libSDL(2130): param 4 = "/data/data/paulscode.android.mupen64plus/lib/librsp-hle.so"
12-04 14:14:27.830: INFO/libSDL(2130): param 5 = "--audio"
12-04 14:14:27.830: INFO/libSDL(2130): param 6 = "/data/data/paulscode.android.mupen64plus/lib/libaudio-sdl.so"
12-04 14:14:27.830: INFO/libSDL(2130): param 7 = "roms/mario.n64"
12-04 14:14:27.830: VERBOSE/front-end(2130):  __  __                         __   _  _   ____  _             
12-04 14:14:27.830: VERBOSE/front-end(2130): |  \/  |_   _ _ __   ___ _ __  / /_ | || | |  _ \| |_   _ ___ 
12-04 14:14:27.830: VERBOSE/front-end(2130): | |\/| | | | | '_ \ / _ \ '_ \| '_ \| || |_| |_) | | | | / __|  
12-04 14:14:27.830: VERBOSE/front-end(2130): | |  | | |_| | |_) |  __/ | | | (_) |__   _|  __/| | |_| \__ \  
12-04 14:14:27.830: VERBOSE/front-end(2130): |_|  |_|\__,_| .__/ \___|_| |_|\___/   |_| |_|   |_|\__,_|___/  
12-04 14:14:27.830: VERBOSE/front-end(2130):              |_|         http://code.google.com/p/mupen64plus/  
12-04 14:14:27.830: VERBOSE/front-end(2130): Mupen64Plus Console User-Interface Version 1.99.1
12-04 14:14:27.830: VERBOSE/front-end(2130): Parsing arg 1: --corelib
12-04 14:14:27.830: VERBOSE/front-end(2130): Parsing arg 3: --rsp
12-04 14:14:27.830: VERBOSE/front-end(2130): Parsing arg 4: /data/data/paulscode.android.mupen64plus/lib/librsp-hle.so
12-04 14:14:27.830: VERBOSE/front-end(2130): Parsing arg 5: --audio
12-04 14:14:27.830: VERBOSE/front-end(2130): Parsing arg 6: /data/data/paulscode.android.mupen64plus/lib/libaudio-sdl.so
12-04 14:14:27.830: VERBOSE/front-end(2130): Parsing arg 7: roms/mario.n64
12-04 14:14:27.861: VERBOSE/front-end(2130): Core Warning: Couldn't open configuration file '/mnt/sdcard/app-data/paulscode.android.mupen64plus/./mupen64plus.cfg'.  Using defaults.
12-04 14:14:29.416: VERBOSE/front-end(2130): Core: Goodname: Super Mario 64 (U) [!]
12-04 14:14:29.416: VERBOSE/front-end(2130): Core: Name: SUPER MARIO 64
12-04 14:14:29.416: VERBOSE/front-end(2130): Core: MD5: 20B854B239203BAF6C961B850A4A51A2
12-04 14:14:29.416: VERBOSE/front-end(2130): Core: CRC: 635a2bff 8b022326
12-04 14:14:29.416: VERBOSE/front-end(2130): Core: Imagetype: .v64 (byteswapped)
12-04 14:14:29.416: VERBOSE/front-end(2130): Core: Rom size: 8388608 bytes (or 8 Mb or 64 Megabits)
12-04 14:14:29.416: VERBOSE/front-end(2130): Core: Version: 1444
12-04 14:14:29.416: VERBOSE/front-end(2130): Core: Manufacturer: Nintendo
12-04 14:14:29.416: VERBOSE/front-end(2130): Core: Country: USA
12-04 14:14:29.432: VERBOSE/front-end(2130): Core Warning: No video plugin attached.  There will be no video output.
12-04 14:14:29.432: VERBOSE/front-end(2130): Core Warning: No input plugin attached.  You won't be able to control the game.
12-04 14:14:29.713: VERBOSE/front-end(2130): Audio: Initializing SDL audio subsystem...
12-04 14:14:29.713: INFO/libSDL(2130): ANDROIDAUD_OpenAudio(): app requested audio bytespersample 2 freq 44100 channels 2 samples 4096
12-04 14:14:29.760: INFO/libSDL(2130): ANDROIDAUD_OpenAudio(): app opened audio bytespersample 2 freq 44100 channels 2 bufsize 16384
12-04 14:14:30.119: VERBOSE/front-end(2130): Core: Starting R4300 emulator: Cached Interpreter
12-04 14:14:31.314: INFO/libSDL(2130): ANDROIDAUD_OpenAudio(): app requested audio bytespersample 2 freq 44100 channels 2 samples 4096
12-04 14:14:31.322: INFO/libSDL(2130): ANDROIDAUD_OpenAudio(): app opened audio bytespersample 2 freq 44100 channels 2 bufsize 16384
Going with Pelya's SDL port has really paid off -- mupen64plus' sdl audio plugin successfully connects to the audio device, meaning I've advanced beyond n64oid's original capability (if anyone wants to continue n64oid development using Pelya's SDL, let me know and I can help you set up the project).

Now that I have the makefiles and globals set up the way I want them, I'm ready to trash n64oid. My next step will be to port the current Mupen64Plus 1.99.4 sources and Ari64's ARM dynarec.
 

·
Registered
Joined
·
58 Posts
Discussion Starter #3
So, I have some good news, some bad news, and some really bad news.

The good news is I finished upgrading the sources to version 1.99.4 and adding in the ARM dynarec (just the c code, and it is yet untested).

The bad news is that the NDK will not compile assembly. The compiler throws a stack of "bad instruction" errors. After some research into the issue, it seems that I need a program called the "Keil RealView Microcontroller Development Kit". Apparently, one must compile the assembly in this program into a library that the NDK can link with.

The really bad news is this program costs around $2,500. If I were a rich man, no problem, but unfortunately I am not. I'm looking into the possibility of any other program that can perform the same function for less cash (preferably free). Another option would be to find someone who owns the software and can compile the assembly for me (I'll be asking around on various forums).

In the mean time, unfortunately, this project is at a standstill.
 

·
Registered
Joined
·
58 Posts
Discussion Starter #4
I've determined that the NDK can compile this file. I've only gotten it to work from the command line, but at least that means the separate shared library is an option (and won't cost me anything). I'm sure there has got to be a way for this to compile in the project as well (output from the builder shows that it is using the same executable I used from the command line). I really think I just need to get the compiler options right in my Android.mk file. I'll keep tinkering around with this.

For reference, here are the commands for building it into a shared library from the terminal:
Code:
/home/paul/bin/android-ndk-r4b/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/arm-eabi-gcc -fpic -c linkage_arm.s -o linkage_arm.o

/home/paul/bin/android-ndk-r4b/build/prebuilt/linux-x86/arm-eabi-4.4.0/bin/arm-eabi-gcc -shared -Wl,-soname,liblinkage_arm.so.1 -nostdlib -o liblinkage_arm.so linkage_arm.o
 

·
Registered
Joined
·
58 Posts
Discussion Starter #5
Wow, so I found the problem. For some reason the builder decides to give the output from the first command an extension of ".s" instead of ".o". This then confuses the builder when it executes the second command (apparently it sees that ".s" extension and expects a text file with assembly commands, which is why it spits out a hundred "bad instruction" errors).

What a stupid bug! Although it is so simple, I honestly have no clue how to get around it short of compiling from the command line -- I have no clue how to debug the Eclipse plug-in so it names the output (name).o instead of (name).s. I'll probably have to build the entire core from the command line, and just plug the resulting library into my project, rather than having it built inside the project along with the other libraries. The other way would be to compile linkage_arm.s separately, but this would require a different memory mapping than it is using now, and I'd really rather not tinker with Ari64's complicated assembly code..
 

·
Registered
Joined
·
58 Posts
Discussion Starter #6
I figured out an acceptable workaround. I've created two mirror projects, one with the new dynarec as part of the core, the other with the cached interpreter. I run the builder for the first project and wait for the errors. Then I select copy the last build command onto the clipboard, and pull up a terminal. I rename that output file to linkage_arm.o, paste the command, change the word linkage_arm.s to linkage_arm.o, and run it. This creates the good core library. Then I load up the second project and build it completely. I swap out the old core library with the good one, and can then deploy the .apk to the phone or emulator. This method is a pain in the butt, but at least I am back on track.

I now have some debugging to do, because the program crashes when it tries to start the dynamic recompiler, but right now I am just thrilled that I finally got the thing out of Eclipse onto the phone.
 

·
Pilgrim
Joined
·
9,687 Posts
This is very interesting.

Your thread might have gotten more recognition if it was posted on the Web development/programming section I guess.

Anyways nice work and very good luck on your project.
 

·
Registered
Joined
·
58 Posts
Discussion Starter #8
I found a better workaround for that compiler bug. It seems that if I rename the file linkage_arm.S, gcc can still compile it, and the plug-in will call the output linkage_arm.o like it is supposed to, instead of linkage_arm.s like it was before.

Also, it turns out that I will have to make some changes to Ari64's code, because it assumes the program to be statically linked (which isn't possible with an .apk). The changes are fairly minor, though, so it shouldn't be too much trouble to get working. I basically added 16MB to the .bss section rather than mapping memory directly. Due to a limitation of the ARM architecture, I have to make sure everything in linkage_arm.s, fpu.c, tlb.c, cop0.c, BASE_ADDR through BASE_ADDR+16777216, and the .text section are within 32MB of each other. Looking at the current memory mapping, it looks like I have met these requirements.

The ap is still crashing, but at least now I can debug it a bit more easily without having to worry about that compiler bug anymore.
 

·
Registered
Joined
·
58 Posts
Discussion Starter #9
I thought I would post a progress update. I have hit a brick wall on the dynamic recompiler. I'm starting to believe that I'm looking in the wrong place for the source of the problem. Part of it may be the fact that I am trying to port the dynarec from Ari64's Pandora port of Mupen64Plus (which is based on version 1.5) to the current version 1.99.4. I've noticed that every other port of Mupen64Plus to ARM devices are all based on version 1.5 (Ari64's Pandora port, zodttd's n64iphone port, Cpasjuste's droid64 port, and several other completed or in development ports). The only project based on 1.99.x that I know of is scottgl's n64oid port, and he stopped development before adding the dynamic recompiler.

All this leads me to believe that I am not the only one who is having problems getting the ARM dynarec to work on more recent versions of Mupen64Plus. For that reason, I think I will change my strategy here. I'll port version 1.5 plus the dynarec to Android first (to solve any dynarec/Android issues first). If zodttd gets his project out before then, I'll start with his code (which I'm guessing is also based on version 1.5) Once I get the dynarec working on Android, I can then focus on trying to port the project to version 1.99.4. I think breaking the problem up into two parts should help me isolate trouble spots.

For those who have been asking when I'll be ready to release a beta version, this is just another example of why placing a time-line on this type of project is really impossible. A couple days ago I felt I was nearly finished with the dynamic recompiler, and now I'm basically starting from scratch again. Zodttd will almost certainly release his project first, unless he also runs into a problem. But I think ultimately, my port will be superior to his. There have been a number of optimizations and bug fixes for Mupen64Plus since version 1.5. Additionally, the new Mupen64Plus API will allow the user to download and link with core and video plug-ins that I've specifically optimized for their phone models' hardware. This is something which can't be done for with the statically linked version 1.5. Zodttd would have to either release multiple versions of his emulator on the market, or release a non-optimized version in order to support a wider variety of phone models.
 

·
Registered
Joined
·
58 Posts
Discussion Starter #10
Woohoo! I have the dynamic recompiler working on my phone! Project is based on Mupen64Plus 1.5, and it is a total hack-job. I compiled it as a basic executable with statically linked libraries, pushed to the phone into /tmp directory, and run via the "terminal emulator", but the dynarec runs smoothly and the process does not crash.

My next step is to port this to a JNI project which can be deployed as an .apk package.
 

·
Least Likely to Succeed
Joined
·
236 Posts
Wow, I had no idea this was going on. I never would have thought Assembly code could be compiled to run on ARM processors, since it's a Microsoft creation.

This is fantastic. My Motorola Devour would die trying to emulate something like Banjo-Tooie, but hell, I'll do it for the sheer novelty of it. Anytime you can package an APK I'll try it out, whether it's on the market or not. I'm rooted, if it matters.

One potentially major problem: what are you gonna do for controls? I can use my keyboard, but about 75% of Android devices don't have a physical keyboard.

EDIT: I hope it will be compatible with Android 1.6, I'm stuck on it for ten more months.
 

·
Registered
Joined
·
160 Posts
Wow, I had no idea this was going on. I never would have thought Assembly code could be compiled to run on ARM processors, since it's a Microsoft creation.

This is fantastic. My Motorola Devour would die trying to emulate something like Banjo-Tooie, but hell, I'll do it for the sheer novelty of it. Anytime you can package an APK I'll try it out, whether it's on the market or not. I'm rooted, if it matters.

One potentially major problem: what are you gonna do for controls? I can use my keyboard, but about 75% of Android devices don't have a physical keyboard.

EDIT: I hope it will be compatible with Android 1.6, I'm stuck on it for ten more months.
Controls are the biggest problem once the actual emu is running, but most devices do have Bluetooth - meaning a PS3 or Wii controller will be able to sync to the devices with a little work. My phone is an Xperia Play so I don't have that problem but it's what I've seen suggested for a lot of emulators on other phones.

IS Paul still working on this? It's been a little while since we've heard out of him but he does seem to take a few weeks or months of non-updating.
 

·
Pilgrim
Joined
·
9,687 Posts
Wow, I had no idea this was going on. I never would have thought Assembly code could be compiled to run on ARM processors, since it's a Microsoft creation.

This is fantastic. My Motorola Devour would die trying to emulate something like Banjo-Tooie, but hell, I'll do it for the sheer novelty of it. Anytime you can package an APK I'll try it out, whether it's on the market or not. I'm rooted, if it matters.

One potentially major problem: what are you gonna do for controls? I can use my keyboard, but about 75% of Android devices don't have a physical keyboard.

EDIT: I hope it will be compatible with Android 1.6, I'm stuck on it for ten more months.
Strange you're rooted but stuck on 1.6.:p
 

·
Least Likely to Succeed
Joined
·
236 Posts
Strange you're rooted but stuck on 1.6.:p
This particular phone isn't difficult to root. But it's part of Motorola's not-so-recent nazi-esque campaign to lock their bootloaders. The Droid X and Droid 2 have the same problem as far as I know.
 

·
Registered
Joined
·
58 Posts
Discussion Starter #17 (Edited)
The available GLES video plug-ins weren't quite plug-and-play, so I've decided to leave video out for now. The glide64 plug-in wouldn't compile, and the gles2n64 plug-in shuts down stating that a functionality is missing. I'll work on debugging these as well as the audio plug-in next. In the mean time, here are links to the test APKs. Note that test C is the only one that works on my phone; tests A and B may work on other devices, but are mainly for gathering debug information to help me with development:

--Links Removed--

NOTE: All of these first three tests require a device with ARM7a and minimum Android version 2.2. Sorry to the folks with older devices. I'll be posting more compatible tests hopefully later this week. Also note that there is no video plug-in and the audio plug-in is broken, so "working" means the app doesn't crash.

NOTE 2: These apps do not have a "shutdown" functionality built into them yet, so if they work on your device, you'll have to either force close the app or reboot your device to shut the dynarec down. Please be sure to do this after running each test.

The test aps will automatically download the Mupen64Plus configs and data files, as well as a rom the first time you run one of them. If your device doesn't have an internet connection, or if you have a data limit, you can manually install this data BEFORE running any of the tests. Simply unzip the following file and place all the contents onto your device's SD card under
/app-data/paulscode.android.mupen64plus/
App Data ZIP (not necessary if your device has internet access)

Testers, please note that you must uninstall each test app before installing another one. Debug files will be generated on your device's SD card under app-data/paulscode.android.mupen64plus/DEBUG_test*.txt. Please also provide logcat output in addition to the DEBUG_test*.txt files. You can use the free app "aLogcat" from the Android Market to get the logcat output. Just run aLogcat, press the menu button and choose "Clear". Then run one of the test APKs above, return to aLogcat, and choose "Save" from the menu. Be sure to clear the logcat output between tests. You can email me the logcat output and debug files to [email protected]. Be sure to include your device model, Android version, and whether or not your device is rooted in the email. Also describe any odd behavior you might have experienced when running the test.

And here is the sourcode for the above test apps. I haven't had time to streamline the project yet, so I apologize for all the extra garbage included.

--Links Removed--
 

·
Registered
Joined
·
58 Posts
Discussion Starter #18 (Edited)
Here is the next test app, which utilizes the latest version of Ari64's dynarec:

--Link Removed--

And the sourcecode:

--Link Removed--

As with the earlier tests, this one requires a device with ARM7a and minimum Android version 2.2. There will be one more upcoming test in this series, which will be compiled for ARM5 and minimum Android version 1.6. I haven't decided if I'll work on it next, or if I'll debug the audio and video plug-ins first.
 

·
Registered
Joined
·
58 Posts
Discussion Starter #19 (Edited)
Hello all, here is the last test app in my core test series. This one is compiled for ARM5 and should be compatible back to Android 1.6. This is the same core as in Test D, plus a couple changes in the jni/core/Android.mk file:
Code:
LOCAL_CFLAGS += -DARMv5_ONLY
#LOCAL_CFLAGS += -mfpu=vfp -mfloat-abi=softfp
And in the jni/Settings.mk file:
Code:
APP_ABI := armeabi
TARGET_CPU_ABI	:= armeabi
#APP_ABI			:= armeabi-v7a
#TARGET_CPU_ABI	:= armeabi-v7a
--Link Removed--

As with the previous tests, I'm measuring "success" as the app enters into a black screen and does not crash. Be sure to either restart your device after running the test, or force-close the app, or it will continue running in the background slowing down your device.

I haven't posted the full project source for this one yet, because I fully expect I'll need to fix a few initial bugs in the Java code, XML manifest, or project settings. It runs fine on my phone, but I don't have an older device myself, and my netbook is too slow to emulate an AVD to test it on (an emulator running within an emulator - now theres a fun thought). I'm mainly interested in getting ahold of some logcat outputs from older devices which do not have SDCards. This should help me identify where any problems are located.
 

·
Registered
Joined
·
1 Posts
Paul, thanks for your reply.

By the way, do you know where I can get the latest source code of Air64's dynarec? The old link seemed broken.
 
1 - 20 of 125 Posts
Status
Not open for further replies.
Top