VERSION 2.0 - 2 January 2021
This guide will explain how to make a TV box with your ODroid XU4. The first section is the only one you need to read in order to have a fully functional TV box using Kodi. The next sections give extra configuration to set up an external USB drive, a MAME video game console and other topics.
One important feature is this new guide is that we don't use X11 or Wayland but Kodi runs directly on the Linux framebuffer using OpenGL acceleration thanks to the Mali 3d driver. Therefore the final product will be a very fast and light system. It is even possible to use it as a small home server for other purposes, even while playing videos. So all the family will be happy at the same time.
- Install Linux and Kodi on your Odroid XU4
- Install an USB external drive on your Odroid XU4
- Install MAME to play arcade games from Kodi
- Install a joystick to play with MAME
All along this guide, I will assume you have access to a Linux box and all the command lines below are for Linux, either your other Linux machine or the Odroid XU-4 we're going to install now. To install all of this, follow the steps:
-
The first step is ideally done on another Linux box. If you don't have one yet (wait,what?), better to migrate to Linux as soon as you can
Download the Ubuntu image and its MD5 sum file:
-
Check your image is valid with
md5sum
and compare the result with the content of the previously downloaded md5sum abovemd5sum ubuntu-20.04.1-5.4-minimal-odroid-xu4-20200812.img.xz
and compare the result with the content of the file
ubuntu-20.04.1-5.4-minimal-odroid-xu4-20200812.img.xz.md5sum
-
Uncompress the file first you've downloaded:
xz -d ubuntu-20.04.1-5.4-minimal-odroid-xu4-20200812.img.xz
-
Put an SD card with enough capacity in your Linux machine
-
Search for the device with
lsblk
lsblk
WARNING
Let's assume your SD card is on
/dev/sdX
. Be very careful to choose the correct device or you will risk to erase the content of another disk.WARNING
-
Write the image to the SD card
dd if=ubuntu-20.04.1-5.4-minimal-odroid-xu4-20200812.img.xz of=/dev/sdX bs=1M conv=fsync status=progress sync
-
Umount your SD card either from your desktop environment or on the command line with. This step is not required but can be necessary:
sudo umount /dev/sdX
-
Insert your SD card in your odroid XU4 and boot your machine
Check the release notes pages to find the credentials: https://wiki.odroid.com/odroid-xu4/os_images/linux/ubuntu_5.4/minimal/20200812 Usually, the login is
root
and the password isodroid
. Obviously, you want to change them immediately after logging in.At this stage you have a fully functional ODroid XU4 machine. The next steps can either be done from your XU4 by connecting a keyboard to it or you can SSH from another machine to the XU4. I recommend using the Ethernet port at first. It is much simpler to configure than a wifi. But both wifi and Ethernet will work.
-
Optional: if you want to SSH to your XU4, you must first find the IP address of your XU4:
ip addr
The IP address is after the
inet
keyboard. The result of the command above gives a list of at least two entries. Usually the first one is calledlo
and is the loopback network interface. It's a fake network interface which creates a network with one machine only. It is used if you want to test a networked program for which the client and the server applications are on the same machine. Usually, the second entry is eth0 and denotes the Ethernet port of your XU4. It's the one you want and the IP address you need is after theinet
keyword. Use this address from your other machine to connect to your XU4 -
Connect as
root
as explained above, either directly or through a SSH connection to your XU4. Alternatively you can connect with the defaultodroid
user and open a terminal. Then in the terminal dosudo bash
to login asroot
.To connect from another machine with
ssh
:ssh root@192.168.xxx.zzz
where
xxx
andzzz
are replaced by the numbers you found doingip addr
. -
Update the packages
apt update apt upgrade apt dist-upgrade
During the update, you might encounter the following situations (or not):
-
the first time you boot your machine, you may get an error regarding a lock file with dpkg (
/var/lib/dpkg/lock
), it means that one of the automated update procedure is still running which is very likely with a new install. Just let it run until the end and try the commands again. -
if you get a message about boot.ini being replaced, just say 'OK'
-
if you get a question about
/etc/apt-fast.conf
, answer Y (for Yes)
The last command (
autoremove
) is to leave the system in a clean state and use a bit less disk by removing unecessary packages. -
-
The Mali graphical driver is installed by default and works well. However, the driver provided by ARM only implement OpenGL ES and not OpenGL. We will use
gl4es
as a wrapper between OpenGL and OpenGL ES and therefore have a hardware-accelerated OpenGL on the Mali GPU in XU4:apt install git cmake xorg-dev gcc g++ build-essential git clone https://github.com/ptitSeb/gl4es.git cd gl4es
Then we compile
gl4es
:mkdir build cd build cmake .. -DODROID=1 make -j
It will compile and display its progress with a lot of messages. Toward the end, if the compilation has been successfull, you should see the following:
[100%] Built target GL
Now we backup the previous GL library and install the new one:
mv /usr/lib/arm-linux-gnueabihf/libGL.so.1.7.0 /usr/lib/arm-linux-gnueabihf/save.libGL.so.1.7.0 rm /usr/lib/arm-linux-gnueabihf/libGL.so.1 cd ../lib cp libGL.so.1 /usr/lib/arm-linux-gnueabihf/ ln -s /usr/lib/arm-linux-gnueabihf/libGL.so.1 /usr/lib/arm-linux-gnueabihf/libGL.so ldconfig
-
Install Kodi now and disable the main GUI environment:
apt install kodi-fbdev kodi-fbdev-bin kodi-fbdev-data libcec4 ffmpeg libavcodec-extra libavcodec-extra58 libavdevice58 libavfilter-extra libavformat58 libdlna0 libpostproc55 libswresample3 libswscale5
-
For security reason, kodi and its associated programs will be run by a user with limited privileges, with no password and automatic login. We will call the user
kodi
:adduser --disabled-password --gecos "" kodi
The output will be:
Adding user `kodi' ... Adding new group `kodi' (1000) ... Adding new user `kodi' (1000) with group `kodi' ... Creating home directory `/home/kodi' ... Copying files from `/etc/skel' ...
-
Assign some privileges to this user:
usermod -a -G cdrom,video,plugdev,users,dialout,dip,input,netdev,audio,pulse,pulse-access,games kodi
-
Add the Kodi service to
systemd
(better to copy and paste the following rather than typing it):cat << EOF | tee /etc/systemd/system/kodi.service [Unit] Description = Kodi Media Center After = systemd-user-sessions.service network.target sound.target mysql.service dbus.service polkit.service upower.service Wants = mysql.service pulseaudio.service [Service] User = kodi Group = kodi Type = simple #PAMName = login # you might want to try this one, did not work on all systems ExecStart = /usr/bin/kodi-standalone Restart = on-abort RestartSec = 5 [Install] WantedBy = multi-user.target EOF
-
Enable Kodi at boot time:
systemctl enable kodi systemctl set-default multi-user.target
-
Remove the blinking cursor on the Kodi screen. There is an annoying blinking cursor at the top-left corner. This will remove it:
grep -v 'exit 0' /etc/rc.local > /tmp/rc.local echo 'echo 0 > /sys/class/graphics/fbcon/cursor_blink' >> /tmp/rc.local echo 'exit 0' >> /tmp/rc.local mv /tmp/rc.local /etc/rc.local chmod ugo+x /etc/rc.local
-
Disable the
unattended upgrades
service to avoid packages being installed in the background. It caused a few problems in the past and we want a stable Kodi system for all the family:systemctl stop unattended-upgrades.service systemctl disable unattended-upgrades.service
-
Add support for audio and the PulseAudio service
systemctl --user enable pulseaudio.service
The Kodi service requires the PulseAudio service (cf. the
Wants
line above). PulseAudio comes by default in Ubuntu, so we just need to link to it. When Kodi starts, it will start the PulseAudio service just before and give Kodi a sound service on-demand. -
Clean up and remove unused services to free up memory and CPU cycles:
ModemManager is a daemon which controls mobile broadband (2G/3G/4G) devices and connections. The Odroid XU4 is connected to an ethernet (or a wifi if you have one) and does not need a modem connection.
systemctl stop ModemManager systemctl disable ModemManager
-
Set the clock to your own time zone
You can synchronize the clock to a time server on the net and always have your Odroid set to the most accurate time. Moreover, you want to set the clock to your timezone.
- First we install an NTP (Network Time Protocol) client which will connect to time server to get an accurate time
apt install chrony
- Then we search for the time zone. It will be something like
Europe/Zurich
orPacific/Auckland
. To find yours do:
timedatectl list-timezones
Search and note your own time zone. Let's say you live near the North Pole in Longyearbyen, you will find the time zone in the list given above as
Arctic/Longyearbyen
. Then tune your Odroid XU4 by doing:timedatectl set-timezone Arctic/Longyearbyen
-
You now have a fully functional Kodi system. If you want to reboot, your Odroid XU4 will directly start on Kodi. I you want to add more features, like MAME (Mame on Wikipedia), an external USB drive, a joystick, a firewall, just keep reading.
In the next sections, I'll show you how to:
- install an external USB drive and have it automounted (for Kodi or Mame for example),
- install and configure Mame and use it from Kodi
- install and configure a joystick for Mame
- remove software and services which are not necessary and use memory and CPU cycle for nothing
Everything can be done either by connecting to your ODroid XU4 with ssh
or on the screen directly (you'll need a keyboard). For the second option, after booting on the Kodi screen, you need to exit Kodi first to get back onto the terminal. After doing what needs to be done (below), just reboot your machine to check everything is fine.
-
Switch to a terminal or login with
ssh
. -
Install
usbmount
to automount USB drives:apt install usbmount debhelper build-essential fakeroot
There is a bug in the version 0.0.22 of
usbmount
as provided by the stock Ubuntu Linux when connecting 2 USB drives at the same time. The bug has been fixed withusbmount 0.0.24
which is not yet on the Ubuntu repository. You can upgrade it manually, if you like:If your second drive (or even the first) doesn't mount properly when you plug it in, you can try to upgrade
usbmount
as follows:git clone https://github.com/rbrito/usbmount.git cd usbmount dpkg-buildpackage -us -uc -b cd .. dpkg -i usbmount_0.0.24_all.deb
-
By default, usbmount will mount the external USB drive with the
sync
option.sync
means that all write access to the disk will be immediately flushed to the disk. And it can dramatically slow down all the disk operations.sed -ie 's/^MOUNTOPTIONS=.*/MOUNTOPTIONS="noexec,nodev,noatime,nodiratime"/' /etc/usbmount/usbmount.conf
I assume it is safe to use the
async
option here because you're not supposed to unplug this disk at any time. When I've done that, the write speed of my external hard drive has been multiplied by 10!
This section is long and will require external resources if you want to have all the bells and whistles of a full-featured MAME installation. From time to time, we will refer to external guides too.
-
Install MAME
sudo apt install mame mame-data mame-doc mame-extra mame-tools libsdl2-gfx-1.0-0 libsdl2-image-2.0-0 libsdl2-mixer-2.0-0 libsdl2-net-2.0-0 libsdl2-net-2.0-0 python-pil
Create a new config file with the correct paths, using OpenGL ES 2, the ALSA audio driver, tuning the speed and using all the cores:
cat << EOF | sudo tee /etc/mame/mame.ini inipath $HOME/.mame;/etc/mame rompath /home/kodi/AML-ROMs/ samplepath /home/kodi/AML-assets/samples/ ctrlrpath /home/kodi/AML-assets/ctrlr hashpath /usr/share/games/mame/hash cfg_directory $HOME/.mame/cfg nvram_directory $HOME/.mame/nvram memcard_directory $HOME/.mame/memcard input_directory $HOME/.mame/inp state_directory $HOME/.mame/sta snapshot_directory $HOME/.mame/snap diff_directory $HOME/.mame/diff comment_directory $HOME/.mame/comments video auto render opengles2 audiodriver alsa samplerate 32000 numprocessors 8 mouse 1 uimodekey INSERT autoframeskip 1 EOF sudo chmod ugo+r /etc/mame/mame.ini
Then we need to remove the
gl4es
startup message to make MAME happy. Long story short: a Kodi plugin will extract the games' databaseMAME.xml
to the standard output by runningmame
. Whenmame
starts,gl4es
is initialized and displays a nice message, like the one above. But the Kodi plugins capture the standard output which is supposed to be an XML file, except that we have this welcome message on top of it fromgl4es
. So when Kodi tries to read the XML file (in fact a Python library tries too), it fails:cat << EOF | sudo tee /usr/local/bin/mame #!/bin/sh export LIBGL_SILENTSTUB=1 export LIBGL_NOBANNER=1 /usr/games/mame "$@" EOF sudo chmod ugo+x /usr/local/bin/mame
When configuring the AML add-on in Kodi, we will use this new mame command we've just created
-
Install and configure Advanced Mame Launcher plugin from Kodi
We're going to follow the official guide of a Kodi plugin called Advanced Mame Launcher (AML) and adapt a few steps to follow our setup. Here, I assume that we have an external USB drive connected to the Odroid XU4. It will be helpful to store data for MAME.
- Assuming you're on a text terminal (see above on how to switch to a text terminal from Kodi), the first step is to create directories to store MAME data. The external USB drive is mounted to
/media/usb0
and by default to/media/usb
too. We will assume it's the case from now on.
cd /media/usb sudo mkdir mame sudo chown kodi.kodi mame sudo su - kodi cd /media/usb/mame mkdir -p AML-ROMs AML-CHDs AML-SL-ROMs AML-SL-CHDs AML-assets/samples/ cd AML-assets mkdir artpreviews artwork cabinets clearlogos covers_SL cpanels fanarts fanarts_SL flyers manuals manuals_SL marquees PCBs snaps snaps_SL titles titles_SL videosnaps videosnaps_SL cd ln -s /media/usb/mame/* . exit
- Then we need to fill in the directories with the latest data for Mame as described in https://forum.kodi.tv/showthread.php?tid=304186. We use the following script to download and install everything automatically:
sudo su - kodi cd /media/usb/mame/AML-assets # catlist.ini catver.ini genre.ini genre_OWS.ini mature.ini not_mature.ini wget http://www.progettosnaps.net/catver/ -q -O - | grep 'download?tipo=catver' | sed "s#.*href=\"\(.*\.zip\)\".*#wget -q 'http://www.progettosnaps.net\1' -O file.zip#"|sh unzip -jq file.zip '*.ini' rm file.zip # nplayers.ini wget http://nplayers.arcadebelgium.be/ -q -O - | grep -E 'nplayers[[:digit:]]{4}\.zip' | sed "s#.*href=\"\(http://nplayers.*zip\)\">.*#wget -q '\1' -O file.zip#" | sh unzip -jq file.zip nplayers.ini rm file.zip # bestgames.ini wget http://www.progettosnaps.net/bestgames/ -q -O - | grep 'download?tipo=bestgames' | sed "s#.*href=\"\(.*\.zip\)\".*#wget -q 'http://www.progettosnaps.net\1' -O file.zip#"|sh unzip -jq file.zip '*.ini' rm file.zip # series.ini wget http://www.progettosnaps.net/series/ -q -O - | grep 'download?tipo=series' | sed "s#.*href=\"\(.*\.zip\)\".*#wget -q 'http://www.progettosnaps.net\1' -O file.zip#"|sh unzip -jq file.zip '*.ini' rm file.zip # history.dat wget https://www.arcade-history.com/?page=download -q -O - | grep -o 'href="[^"]*\.zip"' | sed 's#href=\"\.\.\(.*zip\)\"#wget https://www.arcade-history.com\1 -q -O file.zip#'|sh unzip -jq file.zip history.dat # mameinfo.dat wget 'http://mameinfo.mameworld.info' --header="User-Agent: Firefox/70.0" -q -O - |grep -o 'href=\"[^"]*Mameinfo.*\.zip"'|sort|tail -1| sed 's#href=\"\(.*zip\)\"#wget --header=\"User-Agent: Firefox/70.0\" \1 -q -O file.zip#'|sh unzip -qjp file.zip *.7z > mameinfo.7z 7z e '-i!mameinfo.dat' mameinfo.7z > /dev/null rm file.zip mameinfo.7z # gameinit.dat wget http://www.progettosnaps.net/gameinit/ -q -O - | grep 'download?tipo=gameinit' | sed "s#.*href=\"\(.*\.zip\)\".*#wget -q 'http://www.progettosnaps.net\1' -O file.zip#"|sh unzip -jq file.zip english/gameinit.dat rm file.zip # command.dat wget http://www.progettosnaps.net/command/ -q -O - | grep 'download?tipo=command' | sed "s#.*href=\"\(.*\.zip\)\".*#wget -q 'http://www.progettosnaps.net\1' -O file.zip#"|sh unzip -jq file.zip Longhand/command.dat rm file.zip exit
- Assuming you're on a text terminal (see above on how to switch to a text terminal from Kodi), the first step is to create directories to store MAME data. The external USB drive is mounted to
-
Modify
mame.ini
to reflect the new directory structure:sudo sed -i 's#^rompath \+.*$#rompath /home/kodi/AML-ROMs/#' /etc/mame/mame.ini sudo sed -i 's#^samplepath \+.*$#samplepath /home/kodi/AML-assets/samples/#' /etc/mame/mame.ini
-
Add assets
-
Go back to Kodi: type 'Ctrl+D' on your terminal, then 'Atl+F7' to go back to Kodi.
-
In https://forum.kodi.tv/showthread.php?tid=304186, you can follow the paragraph called Setting up MAME assets and Software List assets to add more resources and assets. This is the way to get extra pictures, logos, etc... You can read the page here: http://forum.pleasuredome.org.uk/index.php?showtopic=30715 about the MAME Extra packages to understand all the type of resources you can find on the Net for Mame.
-
On the above mentioned page, you can find links to Mame resources on the Internet. They come in huge packages you simply have to move to
/media/usb/mame
as we created before. Let me give you some examples about those packages, which can be useful in the process:- if you find a package called
MAME 0.xxx EXTRAs
wherexxx
is a Mame version number, go into the directory you have downloaded. In this directory, you will find more directories. Move their content to the corresponding directory in/media/usb/mame/AML-assets/<some directory>
- Another similar package might be called something like
MAME 0.xxx Multimedia
. You should process it the same way - but you will find
.zip
files too. You can simply unzip them and move them to the final directory as above. Some directories don't have the same name, so keep the names we created above. In this case, transfer the content of the directory instead of the directory itself. - if you find packages with
bios-devices
in their name you don't need them if you already downloaded the very big packages withROMs
in their name. They are just subset for different situation. You can read more about all those packages on this page. These packages are made when you want a minimal version of the ROMs for example if you're running short on disk. - There are packages called Rollbacks Roms too (information here). You only need them if you have a ROM manager for Mame which can deal with multiple version. You won't need them in this tutorial.
- There are the Software List ROMs and CHDs. Obviously, their content will go into the
/media/usb/mame/AML-SL-ROMS
and/media/usb/mame/AML-SL-CHDs
directories we've created before.SL
stands forSoftware List
of course.
- if you find a package called
-
Finally, you might have messed up a bit with users' permission when downloading and moving files. So you want to make things well by assignign the
kodi
user to themame
directory:
sudo chown -R kodi.kodi /media/usb/mame
-
-
Install and configure the AML plugin. You will find it in Program Adds-on. It's called Advanced Mame Launcher.
-
in Kodi, go to Settings, Addon settings, Install from repository. In Program add-ons, look for Advanced Mame Launcher and install it. Follow the picture in the order:
-
After it's installed, right-click on the add-ons logo and go to Settings:
-
Change the paths to the executable and the data directories as shown on the picture:
-
Go back to Kodi's initial screen and look for the AML plugin, in general Add-ons, Program Add-ons, Advanced Mame Launcher.
-
Select any row, open the context menu with a right-click and select Setup plugin.
-
And run a full setup and configuration of the plugin by choosing the All in one step options in the context menu of the plugin: This step can take several minutes to an hour. You will see a lots of progress bars. If you did everything well before, it should work without error messages. The plugin is now configured and ready.
-
And Mame is ready!
Ideally, playing with MAME requires a nice joystick. Here are two examples of joystick I've built myself. It's a good exercise of woodwork, painting, designing and electronics and a fun game for the family. I've made them with planks I collected from a construction site nearby. Good for the environment to recycle things too.
-
Install the software to support and calibrate the joystick. Arcade joysticks are easy to build or can be bought on Internet. They work very well and ideal for playing with MAME's arcade games.
sudo apt install joystick jstest-gtk
-
Calibrate the joystick As most of Mame games will require a simple joystick with buttons, calibration will be very simple. You can use
jstest-gtk
but as we already install Kodi, we will do the calibration from the command line only. With click joystick, the only calibration is to associate buttons (inside the joystick for the directions and fire/select buttons), with their respective direction or function. The calibration will be available system-wide and therefore will be used by mame- if you can plug your joystick to your Linux machine, I recommend to use, in first instance, a small programm called
jstest-gtk
. It's a simple GUI and you can check what's the proper direction of your joystick. In my case, I use a DragonRise compatible joystick (the one on the picture), with 4 connectors for up, down, left and right. But there are a few problems which we will fix with the calibration. First of all, the left-right and up-down are inversed and then the up-down axis is upside down. So to make it short: up is right, down is left, right is down and left if up!!! I can see that on thejstest-gtk
interface. - another option (since Kodi 17) is to setup your joystick directly from Kodi. Read the tutorial here.
As there are many models of joystick, I won't cover all the possible configurations but please contribute and I'll add your solution to this guide.
- If you want to play with the joystick configuration and assign various command to each button or change the directions, you need to provide a configuration file. Let's call it
myjoyremap.cfg
. In my case, I use the following file, but yours might differ a lot depending on what you want to achieve and your joystick's model.
<?xml version="1.0"?> <mameconfig version="10"> <system name="default"> <input> <port type="P1_JOYSTICK_UP"> <newseq type="standard"> JOYCODE_1_XAXIS_RIGHT_SWITCH </newseq> </port> <port type="P1_JOYSTICK_DOWN"> <newseq type="standard"> JOYCODE_1_XAXIS_LEFT_SWITCH </newseq> </port> <port type="P1_JOYSTICK_LEFT"> <newseq type="standard"> JOYCODE_1_YAXIS_UP_SWITCH </newseq> </port> <port type="P1_JOYSTICK_RIGHT"> <newseq type="standard"> JOYCODE_1_YAXIS_DOWN_SWITCH </newseq> </port> <port type="P1_BUTTON1"> <newseq type="standard"> JOYCODE_1_BUTTON1 </newseq> </port> <port type="P1_BUTTON2"> <newseq type="standard"> JOYCODE_1_BUTTON3 </newseq> </port> <port type="P1_BUTTON3"> <newseq type="standard"> JOYCODE_1_BUTTON5 </newseq> </port> <port type="P1_BUTTON4"> <newseq type="standard"> JOYCODE_1_BUTTON7 </newseq> </port> <port type="P1_BUTTON5"> <newseq type="standard"> JOYCODE_1_BUTTON2 </newseq> </port> <port type="P1_BUTTON6"> <newseq type="standard"> JOYCODE_1_BUTTON4 </newseq> </port> <port type="P1_BUTTON7"> <newseq type="standard"> JOYCODE_1_BUTTON6 </newseq> </port> <port type="P1_BUTTON8"> <newseq type="standard"> NONE </newseq> </port> <port type="P1_BUTTON9"> <newseq type="standard"> NONE </newseq> </port> <port type="P1_BUTTON10"> <newseq type="standard"> NONE </newseq> </port> <port type="P1_BUTTON11"> <newseq type="standard"> NONE </newseq> </port> <port type="P1_BUTTON12"> <newseq type="standard"> NONE </newseq> </port> <port type="P1_START"> <newseq type="standard"> JOYCODE_1_BUTTON9 </newseq> </port> <port type="P1_SELECT"> <newseq type="standard"> JOYCODE_1_BUTTON10 </newseq> </port> <port type="COIN1"> <newseq type="standard"> JOYCODE_1_BUTTON8 </newseq> </port> <port type="START1"> <newseq type="standard"> KEYCODE_1 OR JOYCODE_1_BUTTON9 </newseq> </port> <port type="P1_PEDAL"> <newseq type="standard"> NONE </newseq> <newseq type="increment"> NONE </newseq> </port> <port type="P1_PEDAL2"> <newseq type="standard"> NONE </newseq> <newseq type="increment"> NONE </newseq> </port> <port type="P1_PEDAL3"> <newseq type="increment"> NONE </newseq> </port> <port type="P1_PADDLE"> <newseq type="standard"> NONE </newseq> <newseq type="increment"> NONE </newseq> <newseq type="decrement"> NONE </newseq> </port> <port type="P1_PADDLE_V"> <newseq type="standard"> NONE </newseq> <newseq type="increment"> NONE </newseq> <newseq type="decrement"> NONE </newseq> </port> <port type="P1_POSITIONAL"> <newseq type="standard"> NONE </newseq> <newseq type="increment"> NONE </newseq> <newseq type="decrement"> NONE </newseq> </port> <port type="P1_POSITIONAL_V"> <newseq type="standard"> NONE </newseq> <newseq type="increment"> NONE </newseq> <newseq type="decrement"> NONE </newseq> </port> <port type="P1_DIAL"> <newseq type="standard"> NONE </newseq> <newseq type="increment"> NONE </newseq> <newseq type="decrement"> NONE </newseq> </port> <port type="P1_DIAL_V"> <newseq type="standard"> NONE </newseq> <newseq type="increment"> NONE </newseq> <newseq type="decrement"> NONE </newseq> </port> <port type="P1_TRACKBALL_X"> <newseq type="standard"> NONE </newseq> <newseq type="increment"> NONE </newseq> <newseq type="decrement"> NONE </newseq> </port> <port type="P1_TRACKBALL_Y"> <newseq type="standard"> NONE </newseq> <newseq type="increment"> NONE </newseq> <newseq type="decrement"> NONE </newseq> </port> <port type="P1_AD_STICK_X"> <newseq type="standard"> NONE </newseq> <newseq type="increment"> NONE </newseq> <newseq type="decrement"> NONE </newseq> </port> <port type="P1_AD_STICK_Y"> <newseq type="standard"> NONE </newseq> <newseq type="increment"> NONE </newseq> <newseq type="decrement"> NONE </newseq> </port> <port type="P1_AD_STICK_Z"> <newseq type="standard"> NONE </newseq> <newseq type="increment"> NONE </newseq> <newseq type="decrement"> NONE </newseq> </port> <port type="P1_LIGHTGUN_X"> <newseq type="standard"> NONE </newseq> <newseq type="increment"> NONE </newseq> <newseq type="decrement"> NONE </newseq> </port> <port type="P1_LIGHTGUN_Y"> <newseq type="standard"> NONE </newseq> <newseq type="increment"> NONE </newseq> <newseq type="decrement"> NONE </newseq> </port> <port type="P2_JOYSTICK_UP"> <newseq type="standard"> JOYCODE_2_XAXIS_RIGHT_SWITCH </newseq> </port> <port type="P2_JOYSTICK_DOWN"> <newseq type="standard"> JOYCODE_2_XAXIS_LEFT_SWITCH </newseq> </port> <port type="P2_JOYSTICK_LEFT"> <newseq type="standard"> JOYCODE_2_YAXIS_UP_SWITCH </newseq> </port> <port type="P2_JOYSTICK_RIGHT"> <newseq type="standard"> JOYCODE_2_YAXIS_DOWN_SWITCH </newseq> </port> <port type="P2_BUTTON1"> <newseq type="standard"> JOYCODE_2_BUTTON1 </newseq> </port> <port type="P2_BUTTON2"> <newseq type="standard"> JOYCODE_2_BUTTON3 </newseq> </port> <port type="P2_BUTTON3"> <newseq type="standard"> JOYCODE_2_BUTTON5 </newseq> </port> <port type="P2_BUTTON4"> <newseq type="standard"> JOYCODE_2_BUTTON7 </newseq> </port> <port type="P2_BUTTON5"> <newseq type="standard"> JOYCODE_2_BUTTON2 </newseq> </port> <port type="P2_BUTTON6"> <newseq type="standard"> JOYCODE_2_BUTTON4 </newseq> </port> <port type="P2_BUTTON7"> <newseq type="standard"> JOYCODE_2_BUTTON6 </newseq> </port> <port type="P2_BUTTON8"> <newseq type="standard"> NONE </newseq> </port> <port type="P2_BUTTON9"> <newseq type="standard"> NONE </newseq> </port> <port type="P2_BUTTON10"> <newseq type="standard"> NONE </newseq> </port> <port type="P2_BUTTON11"> <newseq type="standard"> NONE </newseq> </port> <port type="P2_BUTTON12"> <newseq type="standard"> NONE </newseq> </port> <port type="P2_START"> <newseq type="standard"> JOYCODE_2_BUTTON9 </newseq> </port> <port type="P2_SELECT"> <newseq type="standard"> JOYCODE_2_BUTTON10 </newseq> </port> <port type="COIN2"> <newseq type="standard"> JOYCODE_2_BUTTON8 </newseq> </port> <port type="START2"> <newseq type="standard"> KEYCODE_2 OR JOYCODE_2_BUTTON9 </newseq> </port> <port type="P2_PEDAL"> <newseq type="standard"> NONE </newseq> <newseq type="increment"> NONE </newseq> </port> <port type="P2_PEDAL2"> <newseq type="standard"> NONE </newseq> <newseq type="increment"> NONE </newseq> </port> <port type="P2_PEDAL3"> <newseq type="increment"> NONE </newseq> </port> <port type="P2_PADDLE"> <newseq type="standard"> NONE </newseq> <newseq type="increment"> NONE </newseq> <newseq type="decrement"> NONE </newseq> </port> <port type="P2_PADDLE_V"> <newseq type="standard"> NONE </newseq> <newseq type="increment"> NONE </newseq> <newseq type="decrement"> NONE </newseq> </port> <port type="P2_POSITIONAL"> <newseq type="standard"> NONE </newseq> <newseq type="increment"> NONE </newseq> <newseq type="decrement"> NONE </newseq> </port> <port type="P2_POSITIONAL_V"> <newseq type="standard"> NONE </newseq> <newseq type="increment"> NONE </newseq> <newseq type="decrement"> NONE </newseq> </port> <port type="P2_DIAL"> <newseq type="standard"> NONE </newseq> <newseq type="increment"> NONE </newseq> <newseq type="decrement"> NONE </newseq> </port> <port type="P2_DIAL_V"> <newseq type="standard"> NONE </newseq> <newseq type="increment"> NONE </newseq> <newseq type="decrement"> NONE </newseq> </port> <port type="P2_TRACKBALL_X"> <newseq type="standard"> NONE </newseq> <newseq type="increment"> NONE </newseq> <newseq type="decrement"> NONE </newseq> </port> <port type="P2_TRACKBALL_Y"> <newseq type="standard"> NONE </newseq> <newseq type="increment"> NONE </newseq> <newseq type="decrement"> NONE </newseq> </port> <port type="P2_AD_STICK_X"> <newseq type="standard"> NONE </newseq> <newseq type="increment"> NONE </newseq> <newseq type="decrement"> NONE </newseq> </port> <port type="P2_AD_STICK_Y"> <newseq type="standard"> NONE </newseq> <newseq type="increment"> NONE </newseq> <newseq type="decrement"> NONE </newseq> </port> <port type="P2_AD_STICK_Z"> <newseq type="standard"> NONE </newseq> <newseq type="increment"> NONE </newseq> <newseq type="decrement"> NONE </newseq> </port> <port type="P2_LIGHTGUN_X"> <newseq type="standard"> NONE </newseq> <newseq type="increment"> NONE </newseq> <newseq type="decrement"> NONE </newseq> </port> <port type="P2_LIGHTGUN_Y"> <newseq type="standard"> NONE </newseq> <newseq type="increment"> NONE </newseq> <newseq type="decrement"> NONE </newseq> </port> </input> </system> </mameconfig>
Then you need to copy it to
/media/usb/AML-assets/ctrlr/
.Then you can edit this file to adjust it to you own joystick. My joystick (which I built myself, hence the little problem :-) ) has a 90 degrees misconfiguration. So UP is right, RIGHT is down, etc... In the XML file, you have two parts. one for the Player 1 joystick and another part for the Player 2. Each line with
type="P1_JOYSTICK_UP"
(etc...) is the direction as understood bymame
. Then, the real configuration comes after asJOYCODE_1_XAXIS_RIGHT_SWITCH
. Therefore, this line means that when my joystick sends a code forRIGHT
,mame
will interpret it asUP
. Below this, I configured the buttons 1 to 8 and theSTART
andSELECT
buttons. Then I do the same for the Player's 2 joystick.Finally, you can add it to the
mame.ini
configuration file by doingecho "ctrlr myjoyremap" | sudo tee -a /etc/mame/mame.ini
- if you can plug your joystick to your Linux machine, I recommend to use, in first instance, a small programm called
odroid-xu4-setup by David Bellot is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.
Based on a work at https://github.com/yimyom/odroid-xu4-setup.
All the images in this document are licensed under CC-BY-SA 4.0
David Bellot Sydney, Australia 2019-2021