Author Topic: Creating Custom Skins  (Read 92889 times)

Offline Paul

  • Administrator
  • double
  • *****
  • Posts: 3499
  • Developer
    • View Profile
    • PaulsCode.Com
Creating Custom Skins
« on: December 18, 2011, 10:43:14 AM »
The Mupen64Plus AE front-end currently allows you to customize the virtual gamepad layouts (as well as the touchpad louyouts for Xperia Play users).  In the future, there will be a lot more that can be customized as well (keep an eye out for future announcements).  I'll list the procedures for creating your own custom layouts.

Customizing the Virtual Gamepad

The virtual game pad is set up to follow the rules laid out in a configuration file, and thus can be made to look any way you like.

Getting started

Begin by taking a look through the folder [sdcard]/Android/data/  You can get a pretty good idea for how layouts work by looking at the ones that ship with the app.  If you look in the folder for layout "Mupen64Plus-AE-Analog", you will notice several pairs of images that have similar names, one ending in .bmp and the other .png.  These are for the virtual buttons.  The .png image is the actual image that gets drawn on the screen (generally looks like a grouping of buttons), and the .bmp image is called the "color mask".  The color mask image defines where on the image, if touched, will activate the buttons.  If you compare the .bmp image with its associated .png image, you will see that if the button grouping has 4 buttons on it, then the color mask will have 4 different colors on it (one for each button).  Every color is unique to a specific button.  Pure black means that area is dead (pressing there will not activate any button).

The analog control works a little differently than the buttons.  It has two .png images.  The first image is the background image for the analog control, and the second image (ending in _2.png) is the image of the control's "stick" (a.k.a. "hat").  The hat image moves around as the user touches different areas of the analog control.

The FPS control consists of a single image (the background).  Custom fonts for the numbers can be created (I'll outline the procedure for that later)

Creating your own skin

Begin by taking a look at the pad.ini file for one of the existing skins.  You will see that there are several sections with titles in brackets.  The first section is [INFO], which provides some information about the layout, such as the version and who wrote it.  The next section is [MASK_COLOR].  These list all the N64 buttons used in that particular layout, followed by a mask number.  This list can also contain entries that look like "scancode_123".  These entries act like physical keys on the device with the specified code.  The mask number is a decimal representation of the color from those color masks you saw earlier.  To get this number, take the hexadecimal values of each color element: (red = ff, green = 63, blue = 5c).  Combine them into an RGB string: "ff635c", and convert that from hexadecimal to decimal (16737116).  When creating your own color mask images, you can either use a paint tool that gives you the RGB values and do the conversion yourself, or simply copy the color masks from one of the existing layouts which as the numbers converted for you already.  (Note about color masks:  A bug in Android returns incorrect RGB values when doing a read-pixel, so I coded it to find the "best match".  This means if two color mask values are too close to each other, they could be mixed up with each other in the game, resulting in the wrong button being pressed.  Often two colors that don't look similar to the human eye can actually have a similar converted RGB value, so be mindful of this.  If you run into this problem, choose a different color for your color mask)

The remaining sections can be called anything you like.  The header title indicates the name of the image files (without the extensions or suffixes).  So for example, information about "FPS.png" is under the section title [FPS], and information about "ANALOG.png" and "ANALOG_2.png" is under the section [ANALOG].  The section title must have the same name as the group of image files that go with that control.  For simplicity, I recommend calling your FPS image "FPS", your analog images "ANALOG", and your button-grouping images "BUTTON1", "BUTTON2", etc, but you can call them anything you like.  Under the header, there are several parameters that indicate what type of control it is and where it should be positioned on the screen.

Lets start with the FPS control.  First, the "info" parameter must equal "fps" (in small letters).  This tells the program that the information that follows is for an FPS indicator.  Next are "x" and "y".  These represent where on the screen the background image will be centered.  These are percentage values, not pixel coordinates!  The control will never get drawn beyond the edge of the screen, so percentages like 0 and 100 are perfectly valid (and recommended).  An x of 0 is the left side and 100 is the right side.  A y of 0 is the top, and 100 is the bottom.  This allows the layout to work on multiple screen dimensions.  Next are "numx" and "numy"  These represent where on the background image the numbers will be centered, and are also in percentages.  To center the numbers at the center of the background image, use numx=50 and numy=50.  Next is rate.  This indicates how often the FPS indicator will refresh itself.  This value must be 2 or greater.  The last parameter is font.  This indicates which number font to use for the numbers displayed over the background image.

Next, lets look at the analog control.  The first parameter is "info".  This should contain the word "Analog" (case-sensitive) followed by the type of analog control.  There are currently two types of analog controls.  The first is "touch".  This type only has a background image, and not a "stick" or "hat" image.  The second type is "hat".  This type has both a background image and a hat image.  Parameters "x" and "y" are the same as before.  The remaining parameters indicate radius percentages.  For example, if the background image had a width of 100 pixels, the radius of the analog control would be 50 pixels, and a percentage of 50 would be 25 pixels.  This allows the analog control to be resized without changing the way it functions.  The first parameter "min" is the radius percentage that is is the "dead zone".  Touching within this zone will not move the control.  The next parameter "max" is the radius percentage where the control becomes "full throttle".  The final parameter "buff" is the radius percentage beyond "max" that is still part of the control.  Touching within this zone will be considered full throttle.  Touching outside this zone will not register as touching the control.  The values for "max" and "buff" should add up to at least 100, and can be higher than 100 if desired (be careful not to overlap with other buttons in the layout).

Finally, lets look at the button-grouping controls.  These may contain one or more buttons.  Each button must have an associated mask color in the [MASK_COLOR] section.  It is not necessary to use the "info" parameter, but it makes it easier for someone reading the configuration file to know which buttons are in a particular grouping.  IMPORTANT: Do not put the words "Analog", "fps", "hat", or "touch" in the info line of a button grouping (this will confuse the program and have unexpected results).  Also, do not use bracket symbols (anything else should be fine to put in there, as long as it stays on a single line).  The only required parameters for button groupings are "x" and "y" which work the same as the other controls.

Once your custom gamepad is complete, give it a unique folder name under "skins/gamepads", and add that name to the file "skins/gamepads/gamepad_list.ini".  Share your custom skins with others if you come up with some good ones!

Creating Custom Fonts

This is actually quite simple.  You merely need to create images 0.png, 1.png, 2.png ... 9.png.  They can be any size, and should have transparency to make them look good.  Give your font a unique folder name under "skins/fonts", and add that name to the file "skins/fonts/font_list.ini"  Don't forget if you create a custom gamepad skin that also uses a custom font, be sure package both the gamepad and the font together before distributing them to other users.

Customizing the Touchpad (Xperia Play users only)

The touchpad layouts are identical to the gamepad skins, and the exact same procedure outlined above applies.  There are only a couple of differences.  Firstly, the analog control consists of a blank, black mask image (in .bmp format), which is used merely to determine the radius of the control (so resizing the control is as simple as resizing the mask image).  In the pad.ini file, analog controls don't use the "touch" or "hat" identifiers in their "info" line.  The button groupings only have the color mask image (in .bmp format), but the syntax in pad.ini is identical.  And finally, there is no "fps" control type.

That should be everything.  If you have any questions or something isn't clear, post a reply here!  I'll try and keep these instructions up to date as things change.
« Last Edit: January 10, 2013, 09:28:01 PM by Paul »
Device: Samsung Galaxy Nexus i515
CPU: TI OMAP4460, 1.2 GHz (dual core, ARM Cortex-A9)
GPU: PowerVR SGX540, 307 MHz
Resolution: 720 x 1280
Rom: omni-4.4.4-20141014-toro-FML KitKat 4.4.4, rooted

Device: Eee PC 1015PEM
CPU: Intel Atom N550, 1.5 GHz (dual core, x86)
GPU: Intel GMA 3150, 200 MHz (dual core)
Resolution: 1024 x 600
Rom: android-x86-4.3-20130725 Jelly Bean 4.3, rooted

Offline fzurita

  • Moderator
  • double
  • *****
  • Posts: 617
    • View Profile
Re: Creating Custom Skins
« Reply #1 on: October 18, 2020, 05:08:41 PM »
One update to this topic. Touchscreen profiles now need to be imported through  "Settings"-->"Touchscreen"-->"Import Touchscreen Graphics". From there, a valid zip file containing touchscreen graphics must be selected. I have linked a sample file. For the zip file to be considered valid, these files must be present, otherwise it will be rejected:

« Last Edit: October 18, 2020, 05:18:54 PM by fzurita »