Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Topics - littleguy

Pages: 1 [2] 3
General Discussion / Pak switching mechanics
« on: February 28, 2013, 10:31:15 PM »
In the process of streamlining the native input plugin, I've learned quite a bit.  The plugin interface is really lean, and looks well thought out.  However, there is one thing that I find odd about the core API.  Why are the mempak and rumblepak switched via the input plugin and not the front-end plugin?  All on-the-fly configuration changes (pause, reset, open ROM, frame advance, etc.) are done in the ui-console plugin via the CoreDoCommand function.  Except for the pak switching.

Instead, pak switching is done via the input plugin.  Input-sdl uses some leftover bits in the BUTTONS data structure, bits which are documented in the core (m64p_plugin.h) to be "Reserved".  So that kind of bugs me.  But what really bothers me is that such fundamentally different handling is then required for these two "buttons".  All the other buttons are momentary-on type switches, and by necessity are polled very frequently in the inner event loop.  However, when a pak "button" is pressed, a whole sequence of timers is initiated to simulate manual removal and reinsertion of a physical pak.  This just seems out of place here, and is a nuisance to implement.  And why make every input plug-in re-implement this behavior?  If this sequence of delays is important, seems like it should be implemented in the core.

So I'm sort of at a cross-roads.  I'd like to keep the input-android plugin very thin (300 lines or less), just bridging the Android/Java code with the core.  But this whole timer mechanism is a bother.  I either have to implement it in the native plugin (cluttering it up) or add a bunch of code to my Java class that just seems out of place.

I'm wondering if we even need mempak/rumblepak switching to be mappable.  Given that it's an intentionally delayed procedure, seems like it would work just fine in the in-game menu, which is where I'd much rather wire it to.  Are there any N64 games that require in-game pak switching, and is fingertip access so critical?

General Discussion / Rice source code
« on: February 26, 2013, 02:03:55 PM »
All Lioncash's and Gilles recent updates to gles2rice got me thinking about upstream again.  Is the upstream source in Richard's repository?  Or is his repository a sibling to ours, with a common ancestor to both further upstream?  I had always assumed the former, until today when I did a diff of ours and theirs and noticed how significantly different the two versions are.

Then it dawned on me that we are essentially porting Richard's version from OpenGL to GLES, and that's why large blocks of code are commented out in our version.  Is there any desire/hope/expectation that we eventually merge our rice effort back upstream?  Or would that be pointless?

Sorry for all the basic questions, I feel like I'm finally starting to (slowly) get a handle on the native code.

General Discussion / GLES2 and Android compatibility
« on: February 21, 2013, 11:01:04 PM »
I seem to recall reading awhile ago that GLES 2.0 was supported back to API 4 (1.6 Donut), which is why Mupen only requires SDK 4 in the manifest.  However, tonight I've started reading up on Android/OpenGL relationship and now I can't find that reference anywhere.  Instead, much of what I find says GLES2 support came with API 8 (2.2 Froyo).  Here's an example.  I'm guessing that refers to when GLES2 was supported via the Java API.

Then I look at the official NDK documentation and it says that GLES2 support didn't arrive until API 5.

What am I forgetting?

General Discussion / Migrating from Bugsense
« on: February 20, 2013, 08:03:06 PM »
We're good to go with Acralyzer.  The java code is already written and tested on one of my local branches.  We can start using immediately if you wish.  The web UI isn't as polished as BugSense yet, but we'd have full control of it and it's not hard at all to customize.  We could also use the command-line to access the data if we just need something quick for debugging.

Right now, the data is sent to  If you create your own couchdb I can have it all set up in a matter of minutes.  If we want to start customizing the views (which I've already started to do) you could just fork Acralyzer on github and we could all work on it together.

Edit: Something else, with acralyzer we can have the default UI and the customized UI(s) installed side-by-side on the server.  So we could have our cake and eat it too as acralyzer matures.

General Discussion / A simpler way to rename the application package
« on: February 19, 2013, 08:32:51 PM »
Was talking with some of the Acralyzer devs and one mentioned that you don't need to change the package name for every class/activity to push out alternative versions of the app on the market.  You only need to change the application package name.  I've tried manually changing the name in the manifest, but that never works.  Build failure.  There's a little more to it than that obviously.

But then I discovered this gem.  The answer was right under my nose the whole time.  So I gave it a try and lo and behold, it worked.  Everything including the native emulator code worked just fine, no change in behavior.

One of the benefits of doing it this way (besides the fool-proof simplicity) is that different application packages will generate the same stack traces because the package names remain the same across the different apps.  With the current approach, you get two different error signatures in BugSense or Acralyzer (or whatever your crash report tool):
Code: [Select]
java.lang.Exception: BENIGN CRASH TEST
Code: [Select]
java.lang.Exception: BENIGN CRASH TEST

Using the simple method in the link, both apps generate the same stack trace (which is exactly what we want):
Code: [Select]
java.lang.Exception: BENIGN CRASH TEST

General Discussion / Better integrating with upstream
« on: February 19, 2013, 10:04:16 AM »
I wonder if we can get tighter integration of issues with the upstream devs.  I know that this AE version is not "officially" supported by the Mupen64Plus team, but with all Sven's efforts to sync with upstream, and Android builds now supported directly in the upstream branch, perhaps it's time to revisit that decision between Paul and Richard.

We have numerous issues on our github issue tracker and I honestly don't know how many are due to bugs in the Mupen-AE branch and how many are general defects that the upstream devs should be aware of (if they aren't already).  It's not a blame game, I just mean that the people who are best equipped to solve certain problems should be directly in the feedback loop with users.  Maybe some upstream devs are watching the github issue board and this forum, I don't know.  Either way, perhaps it's time to make the partnership between the teams more concrete.

General Discussion / Ideas needed: Improving input mapping and listening
« on: January 22, 2013, 11:10:41 PM »
Ok, been thinking about this awhile now so I think I'll try to communicate the current input handling process for analog data and the issues we're facing.  As I've said in other posts, the current implementation is kind of brittle and it would be nice to have something a little more robust.  In one sense, the most reliable solution to the problems outlined below is to make the user go through a detailed controller setup process.  However, I expect this would annoy or confuse many users.  We could stuff more options into "advanced" menus and the like, but that may just shift where the confusion happens.  I'm still holding out hope that we can devise a more automatic solution that "just works" like it generally does on a PC or console.

So in a nutshell, here's what's going on...:
  • What you see in the "Controller diagnostics" screen are the raw, unadulterated key and motion events passed from the Android framework.  If controller signals do not show up on this screen, then it will not be a quick-fix to get that particular controller working.  The notable exception is the Xperia PLAY touchpad, which required considerable effort to integrate into Mupen (thanks Paul!).  On the other hand, if user inputs are visible here, then we should be able to map them to Mupen commands without a lot of changes to the existing code. Currently, the app just listens to KeyEvents (digital) and MotionEvents (analog) and uses the user-defined map to convert them to Mupen commands. For digital buttons, this is very easy and the signals are used in raw form.  Analog signals should be equally easy to interpret and convert, but...
  • Xbox 360 controllers have a little quirk.  Unlike most controllers, their analog triggers produce values in the range [-1,1] with a resting value of -1 (most controller triggers use [0,1] and rest at 0).  So when you go to map, you'll instantly map everything to one of the triggers, since it looks like it's fully pressed in the negative direction.  Solutions I've considered include:
        (a) Communicate to users that they may have to press their triggers half-way to remove the bias during mapping.  Obviously a bad user experience, but including it for the sake of completeness.
        (b) Offset the trigger axes (AXIS_Z and AXIS_RZ) so that their resting value is 0.  Or ignore negative values on these axes.  Problem is that most other controllers (e.g. PS3) use those axes for right stick.  So fixing it for Xbox breaks it for most others.
        (c) Hard-code the fix only for xbox controllers.  First problem is that there are so many clones on the market that it would be a real maintenance chore, and would require a user to alert and work with us to put a fix in.  Second problem is that you might not be able to reliably distinguish a clone from another controller.  Might just give you a name like "Generic gamepad" or something from the SDK.
        (d) Add a user option to select between default and Xbox controller styles, then use the solution above.  Or auto-detect but provide an override option to the user to force Xbox or standard mode.
        (e) Somehow infer the bias at run-time based on the analog signals, and let the user be blissfully unaware.  This is the approach that is currently implemented.  Unfortunately it's brittle, as I'll describe later.
  • Assuming we somehow get the bias issues fixed, we're not out of the woods yet.  Some controllers do just the opposite: they map a stick to [0,1] with a rest position of 0.5.  I've only encountered this with one controller (old Logitech Wingman Rumblepad) so maybe we can just ignore it and leave good enough alone.  Or we could try solving it by
        (a) Normalizing all analog values to [-1,1].  That is, newValue = -1 + 2 * (rawValue - minValue) / (maxValue - minValue) where the min and max values are easily obtained through the SDK.  This solves problem (3) but now introduces problem (2) to most controllers on the market.  For example a PS3 trigger with resting value 0 and range [0,1] now behaves just like the xbox controllers.  My hope was that I could come up with a reliable solution to (2) so that this normalizing trick wouldn't create new issues.
  • Assuming (2) and (3) are solvable, there are still other quirks to be solved.  For example, some controllers send out a digital signal in addition to the analog signal when the analog crosses the 0.5 threshold.  For example, the PS3 controller sends out KEYCODE_L1 whenever AXIS_LTRIGGER crosses 0.5.  If want to map left trigger to an analog signal, we must guarantee that AXIS_LTRIGGER is heard first.  The obvious solution is just to reduce the threshold on analog signals during the mapping process.  Simple solution but brittle, as I'll discuss later.  There are also more confusing cases, such as the Nyko PlayPad (and Pro) controllers, which send out AXIS_X and AXIS_HAT_X simultaneously for the left stick, but rounds the value on AXIS_HAT_X, i.e. AXIS_HAT_X = math.round(AXIS_X)
  • Some controllers combine multiple modalities in a single device.  E.g. many of the new "Android" controllers send two AXIS_X signals - one coming from a "mouse" and another coming from a "joystick" whenever you press one stick.  Another example is the OUYA controller which has both a touchpad and a left stick that deliver AXIS_X and AXIS_Y signals.  This is actually easy to test for, but I only discovered the issue (and solution) this week.

So, all told, issues 3, 4, and 5 are not too big a deal. Issue 2 has multiple possible solutions (chime in if you have other ideas) but none without flaws.  Option (2e) is currently implemented but is still brittle.  Here's the pseudocode:
Code: [Select]
on analog input (AXIS_ARRAY):

    strongest_val := 0
    AXIS_strongest := null

    foreach (AXIS in AXIS_ARRAY)
        // normalize
        AXIS_val := -1 + 2 * (AXIS_val - AXIS_min) / (AXIS_max - AXIS_min)
        // identify bias
        if (AXIS_bias not defined)
            AXIS_bias := round(AXIS_val)
        // remove bias
        AXIS_val := AXIS_val - AXIS_bias
        // record the strongest axis
        if (abs(AXIS_val) > strongest)
            strongest_val := abs(AXIS_val)
            AXIS_strongest := AXIS
    // map the strongest axis if appropriate
    if (strongest_val > threshold)
        map.put(AXIS_strongest, MUPEN_COMMAND)
Threshold can be set to a value less than 0.5 to address issue (4). In everything I've seen, the biases are always in the set {-1, 0, 1}, hence the rounding function. Though it's not strictly necessary and I've tinkered with not rounding it.

Now here's where the brittleness comes in.  It all has to do with when the bias is defined.  If the user ramps up an analog input very quickly (easy to do, especially with stiff nubs) and their cpu is already burdened, the first analog value heard might be large enough to be rounded to the wrong value.  Removing the rounding process may help but is not a panacea.  For example, true bias = 0, first value heard (and inferred bias) is 0.7 and threshold is 0.4... this axis will become unmappable regardless of whether rounding is used or not.  Other options are to allow the user to undefine the biases on command so they can be re-inferred.  Or let the user manually specify the biases.  Also, it helps to limit the bias inference only to AXES that truly might be biased.  For example, AXIS_X and AXIS_Y are always unbiased for joysticks; inferring the bias for these axes is pointless and can only introduce errors.  So the current implementation limits the bias inference process to AXIS_Z and AXIS_RZ (for Xbox); AXIS_LTRIGGER and AXIS_RTRIGGER (for PS3); AXIS_GAS and AXIS_BRAKE (for Nyko PlayPad); and AXIS_GENERIC_1 (for OUYA).  But since the inference process is not perfect right now, the bias on any of these axes may be erroneous, leading to mapping difficulties.

The next approach that I may implement soon would allow the user to define which axes are triggers and which are sticks.  This could take the form of some sort of list and radio buttons, or it could be more seamless where the user is asked to wiggle all sticks, then wiggle all triggers.  This would remove the inference (and normalization) requirements and might be the simplest and least annoying solution in the grand scheme of things.  It could also auto-detect based on ranges, so many users would never even need to use the wizard.

Whew.  Just talking through this has helped me.  If you've stuck with me through all that, congratulations.  If you can offer any ideas or concerns, I'd love to hear them.

General Discussion / Analog Controller FAQ and Compatibility List
« on: January 21, 2013, 08:16:01 AM »
Android 2.3 to 3.0

Sony-Ericcson Xperia PLAY touchpad is fully supported for analog control.

New!  PowerA's MOGA series of controllers are now fully supported all the way back to Android 2.3.  You just need to install the official MOGA Pivot app.  Root not required for full analog control!  See below for additional notes.

Android 3.1 and Above

Any controller that uses the HID protocol should be compatible if you're running Android 3.1 or higher.  If not, please see the troubleshooting section below and post a reply in this thread.  We'll get you up and running in no time.

USB-based wired controllers:
Your tablet/phone needs to support USB OTG and you will need an OTG adapter.
 - The vast majority of USB-based Windows-compatible controllers built in the last 10 years are fully supported.
 - Xbox 360 controllers (official or third-party) fully supported.
 - Wired PS3 controllers (official or third-party) fully supported.
 - Raphnet Technologies USB adapters fully supported.
 - Mayflash/Huijia USB adapters fully supported.
 - Retrolink N64 Classic USB controller support is not recommended.  We've received mixed compatibility reports.  See here and here for details.  It appears that this device is unrecognized by the Android operating system in most cases.
 - Your mileage may vary for other USB adapters for original console controllers. Testers needed!

USB-dongle-based wireless controllers:
 - Compatibility generally follows the same rules as USB-based wired controllers above.
 - Official wireless Xbox 360 controllers are fully supported except for the D-pad, which is unfixable due to Google/Microsoft's broken drivers.

Bluetooth-based wireless controllers:
 - New!  PowerA MOGA series fully supported.  See below for important notes.
 - OUYA fully supported.
 - Mad Catz C.T.R.L.R. fully supported.
 - iControlPad fully supported in gamepad mode.
 - GameStop Red Samurai series fully supported in gamepad mode.
 - Nyko PlayPad series fully supported in gamepad mode. See here if you have difficulty re-mapping the left analog stick.
 - Wireless PS3 controllers fully supported using Sixaxis Controller app in gamepad mode. That app currently requires root for analog capabilities and does not usually work with non-Sony-branded controllers. See that app for full support details.
 - Wiimote controllers supported using Wiimote Controller or similar apps, but only in digital mode (analog not currently supported).
 - This list will be extended as more users report their results.

Built-in controllers:
 - Xperia PLAY (with custom ICS+ ROM) is fully supported, although some users have had problems with the circle button when running a custom Android ROM.
 - Archos GamePad is fully supported. You do NOT need to use the Archos touch-mapping software.
 - NVIDIA Shield is fully supported.
 - JXD S7300 is fully supported but requires custom firmware (Sxelrom 3.5 or higher).  See here for installation tips (thanks snapuswip3!).

General Discussion / Cheats, lag, caching
« on: January 05, 2013, 07:43:51 PM »
Seeing more discussion in the shoutbox about cheat lags.  Somehow my cheats menu doesn't refresh when I expect it to.  E.g. reset to default user preferences, then pick a game, go to Play, and no cheats show up.  Next time I restart the app the cheats are built properly. I have a few questions:

- When to refresh the cheats menu - Currently I think this is done when the user presses the Play menu.  But I'm wondering if it might be more logical to refresh after the user changes to a different ROM.

- Caching - Is there anything we can persist between sessions that would speed it up?  I'm thinking, user changes ROMS, the menu system refreshes itself (possibly with a toast or progress bar) then persists whatever it needs to reconstruct the cheats menu.  Next time user starts the app, if they don't change ROMS, there's nothing to wait for.

I may be missing the point entirely, not sure exactly what's going on in the cheats menu and have hardly looked at that part of the code other than where it ties into  Thoughts?

General Discussion / GLSurfaceView
« on: November 30, 2012, 09:37:14 AM »
This is more of a curiosity question than anything, but does this have any relevance to Mupen64PlusAE?

General Discussion / Xperia PLAY coding questions
« on: November 16, 2012, 10:31:09 PM »
Hey Paul, been beating my head against the wall for awhile here tracking down an Xperia Play -specific bug I must have introduced into the concepts branch.  I have the NativeActivity stuff working again for the most part, and am able to load a ROM, resume from before, etc. just like the regular Activity version.  I'm getting video and audio just fine.  Problem occurs when user input arrives, eg. touchpad, touchscreen, hardware buttons... the whole NativeActivity quits and bounces me back to the menu screen, i.e. pops the activity stack.  It's all graceful, no error codes, etc.  I've been poring over every line of code in the master branch, trying to figure out what I omitted, but no success yet.  I believe I have everything sequenced correctly on creation...  Just wondering if you bumped into this already and might know what's going on.

For a little more info, I haven't touched the C++ code, and the logcat seems to indicate that the C++/Java bridging functions are registering properly in both directions.  In the concepts branch, the organization of the game activity/implementation is shown below.  GameActivity and GameActivityXperiaPlay are very thin classes, most work happens in GameLifecycleHandler and GameSurface.

General Discussion / Core thread and shutdown
« on: November 13, 2012, 10:04:13 PM »
Been having a persistent problem that I can't seem to fix from the Java side.  Here goes.  As you know, the SDL surface starts a second thread which calls NativeMethods.init() which gets the whole core running.  Everything works great.  Problem is when we go to quit the core.
 - User clicks to return to main menu
 - UI thread calls finish() on GameActivity
 - Android fires a sequence of lifecycle methods, in the process destroying the SDL surface.
 - In the SDL surfaceDestroyed callback, we call NativeMethods.quit(), and wait for core shutdown and thread join.

Ideally, Android would pop the activity stack to return us to the MainMenu.  Instead, Android pops the stack twice (which I verified with some extra dummy activities) but never crashes.  No warnings or errors in the logcat, everything just as you would expect... except for the extra popped activity.  So it's like something on the C++ side is sending an extra pop.  Have you noticed this or have any ideas what's going on?

General Discussion / SDL and other layers
« on: October 22, 2012, 04:20:03 PM »
Doh!   :P  As I was mucking about in the java code refactoring some things, I realized I broke a lot of the implicit connections with the native side, largely in the SDL part of the core.  I know I need to update the calls in C++ if I change any of the java functions that use the 'native' keyword... But it looks like the SDL library is less overt, calling java functions not marked with the 'native' syntax.  I'm pretty new to Java, and don't know much about this aspect of the language.

If I change a function name, I assume I need to update it on the C++ side.  Any way to find those calls easily?  Also, what if I don't change the name of the function, but just move it to another class (e.g.  Changes in C++ necessary?

Also, I know in some previous posts, you mentioned removing the SDL layer altogether.  Is this a far-off goal, or something that might happen soon?

General Discussion / GPL V3 and header comments
« on: October 11, 2012, 01:48:50 PM »
I have almost no knowledge of licensing, but can/should we update the gpl-license file in the source root to GPL version 3?  Right now it's version 2.

Also, do we need to be appending GPL stuff in the header of all the source files?  Some googling suggests we do.  If so, how about this?

Code: [Select]
 * Mupen64PlusAE, an N64 emulator for the Android platform
 * Copyright (C) 2012 Paul Lamb
 * This file is part of Mupen64PlusAE.
 * Mupen64PlusAE is free software: you can redistribute it and/or modify it under the terms of the
 * GNU General Public License as published by the Free Software Foundation, either version 2 of the
 * License, or (at your option) any later version.
 * Mupen64PlusAE is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details. You should have received a copy of the GNU
 * General Public License along with Mupen64PlusAE. If not, see <>.
 * Authors: TODO

General Discussion / Code formatting configuration
« on: October 11, 2012, 08:32:28 AM »
@Paul and Lioncash -

Looks like most of the java source follows a unique but consistent formatting convention.  I'd like my code contributions to be consistent.  Would you mind posting your Eclipse formatter config file?  In Eclipse, go to Window->Preferences->Java->Code Style->Formatter and press the "Export All.." button.  Thanks!

PS - It might be a good idea to include this config file with the source code, alongside the README.

Pages: 1 [2] 3