Friday, July 15, 2016

RetroArch on a Raspberry Pi

Untitled Document.md

I just put the finishing touches on my Raspberry Pi 2 emulation machine running RetroArch. I was not a huge fan of RetroPie due to the reliance on Emulation Station - more moving parts meant that there were more things that could potentially break. I just wanted something that would run raw RetroArch, no frills.

This tutorial is mostly recreated from memory and was done with a Raspberry Pi 2 running Raspbian Jessie and RetroArch 1.3.4. If there is a mistake or a broken link, PLEASE message me and I will fix it.

Step 1: Install Raspbian

I used Raspbian Jessie Lite from this page. Write the image to your SD card using something like Win32 Disk Imager, or if you’re using OSX/Linux follow a tutorial on how to write the image using dd.

Step 2: Get Comfortable

First things first, you’re going to need to get Wi-Fi set up. Follow this tutorial. After that, make sure your system is totally up to date:

sudo aptitude update
sudo aptitude upgrade

Unless you live in Great Britain, you will probably not be happy with some of the defaults. Use this to fix your keyboard:

sudo dpkg-reconfigure keyboard-configuration

Use this to fix your locale (choose en_US.UTF-8 if you live in the US):

sudo dpkg-reconfigure locales

Use this to fix your timezone:

sudo dpkg-reconfigure tzdata

It’s probably a good idea to reboot at this point.

3. Compile RetroArch

Unlike some other tutorials, I believe in keeping things simple, explaining what flags I’m enabling and why, and not going overboard on bells and whistles or disabling things. So let’s get started:

sudo aptitude install libasound2-dev libudev-dev

Okay, time out - what are we installing and why?

  • libasound2-dev is ALSA. This library ensures that RetroArch will have sound - kind of important.
  • libudev-dev is udev. This library is necessary to ensure compatibility with a wider range of input devices. Without this, my DualShock 3 could be detected, but didn’t actually work.

Now that we have libraries, grab the source for the latest stable version of RetroArch:

wget 'https://github.com/libretro/RetroArch/archive/v1.3.4.tar.gz'
tar zxvf RetroArch-1.3.4.tar.gz
cd RetroArch-1.3.4

Now to configure it:

./configure --enable-alsa --enable-udev --enable-floathard --enable-neon --enable-dispmanx

Okay, time out again - why are we passing these parameters to configure?

  • --enable-alsa ensures that we’re compiling with ALSA support. If the library isn’t installed, the configure script will die screaming instead of disabling the feature.
  • --enable-udev ensures that we’re compiling with udev support.
  • --enable-floathard ensures that RetroArch uses the Pi’s built-in hardware Floating Point Unit. Without this, there is the possibility that floating point calculations might be emulated in software, which is much slower.
  • --enable-neon ensures that RetroArch can use the Pi’s SIMD CPU instructions (called NEON) for extra speed. Some cores take advantage of this.
  • --enable-dispmanx ensures RetroArch can use the Pi’s Dispmanx support for rendering graphics. Dispmanx is a low-level 2D graphics API unique to the Raspberry Pi’s video core which you can use as an efficient alternative to OpenGL. The downside is that it is not as featureful as OpenGL (for one, the OSD text at the bottom of the screen won’t render), and comes with ugly bilnear filtering enabled by default, though this can be turned off. So we compile with support for both GL and Dispmanx, and you can decide for yourself which one you prefer.

And that’s it. Disabling 20 different options is pointless - all you’re really saving is binary size. If the configure script completes without errors, you can then:

make -j4
sudo make install

4. Configure RetroArch

Now that RetroArch is installed, run it:

retroarch

You will be presented with the GUI front-end. You can use the arrow keys to navigate the UI, x to select an option, z to back out, and esc to quit RetroArch completely. We still have a little ways to go, however, until we’re completely up and running.

Quit out of RetroArch and edit the ~/.config/retroarch/retroarch.cfg file with your editor of choice - nano is good if you don’t have a preference. Look for the line that mentions core_updater_buildbot_url and set it to http://buildbot.libretro.com/nightly/linux/armhf/latest/.

Next, unless you are incredibly lucky your controller probably is not working. Navigate to Online Updater, then Update Autoconfig Profiles and wait for the OSD text to stop flashing. Quit and restart RetroArch to see if your controller was found. If your controller still isn’t configured, you might need to go to Settings, then Input, then Input User 1 Binds. It should be self-explanatory from here.

Now, let’s test our updated settings. From the main menu, navigate to Online Updater, then Core Updater, and select 2048. Once it’s installed, from the main menu, select Load Core then 2048. Finally, select Start Core. If everything went smoothly, you should be able to play a simple game of 2048 to prove that everything is set up correctly. To exit the game, press escape or use the button on your controller that you bound to said functionality.

At this point, you are now ready to follow other RetroArch tutorials that concern importing and playing your games.

5. Other Stuff

If you remember from earlier, we compiled RetroArch with Dispmanx support. To give it a spin and see if you prefer it to the default GL implementation, first ensure that you are using the default rgui menu driver - if you haven’t changed your menu driver, you’re fine. Next, at the Main Menu select Settings, Driver, then Video Driver and select dispmanx. You must then quit and relaunch RetroArch. If you ever want to go back, go to the same place and select gl instead.

RetroArch gives you many different choices for cores. Sometimes it’s a little confusing trying to figure out which core is the best. Here is my suggestions based both on personal experience and other people giving me advice:

  • NES: FCEUmm.
  • Genesis: Genesis Plus GX. If you get slowdown, try PicoDrive.
  • 32X: PicoDrive.
  • SNES: Snes9x. If you get slowdown, try Snes9x-Next. ~

Friday, September 24, 2010

Ubuntu, Linode and Locales

How annoying. The default locale on a default Ubuntu 10.4 on Linode is...well I'm not sure that it's even set to anything. So how do you fix this and ensure that you get full UTF-8 goodness? Well...I'm still not entirely sure, but I think I'm on to something. I'm sure I'm doing it completely wrong, but after spending upwards of an hour trying to figure out how to fix this I just don't really care anymore as long as it works.

The magic incantation appears to be update-locale LANG=en_US.UTF-8. Doing this and rebooting your computer you will be greeted with...something that's still not UTF-8, as for some reason it still decides that it wants to default to ISO-8859. However, if you start screen, you will find out that your screen session is UTF-8 enabled and everything works peachy.

Yeah. Pretty dumb, especially when there appear to have been perfectly fine and easy ways to configure the locale in previous versions of ubuntu. Unfortunately, localeconf no longer exists as a package and dpkg-reconfigure locales doesn't actually give you any interactive prompts. The only clue I have to go on is that /var/lib/locales/supported.d/local appears to list both ISO-8859 and UTF-8 versions of en_US. I don't want to delete ISO-8859, since I'm pretty sure it's needed for some legacy applications that don't support UTF-8, but I don't have a clue how to make UTF-8 the default when logging in.

EDIT: In debian I can't get any further but the reconfigure command is aptitude install locales and then dpkg-reconfigure locales.

EDIT #2: Another Ubuntu VPS that I have tried recently doesn't even give you the any locales out of the box. aptitude install language-pack-en should give you what you need.

Doom server management 101

After having spent a considerable amount of time running servers of my own, I have happened upon a process for putting Doom servers up that I would like to share with any who care to listen. This allows me to get servers up and running rather quickly, without having to fiddle around with a directory full of shell scripts or whatever else most server owners use. I will give everything to you on a silver platter at the end of this post, but I think it's important to comprehend the fundamentals behind my organization first, otherwise it will make no sense to you.

1. Split your configuration up


How many times have you wanted to start a generic Deathmatch server, or a generic TDM server, or a generic CTF server, and simply copied the config file from another server? Now, assume that a new version of your port of choice comes out and suddenly, there is a neat new flag or feature that you want to enable on every single server. Or lets say that after some experimentation your players demand a change to a gametype (for example, changing the fraglimit on your TDM servers). You could go back through every single one of your config files and add those configuration pieces to every single file, hoping you don't skip one. Or you could harness the power of exec.

exec is a simple command that executes another config file, and is usually used at the end of a server startup string. However, it's just as usable inside of a configuration file. To wit:

doom2-coop.cfg


// Execute base Team Deathmatch params
exec "/opt/skulltag/cfg/coop.cfg"
sv_hostname "[MS] My Servers || Doom 2 Cooperative"

Just keep all your TDM configuration inside of tdm.cfg, and you're golden.

2. Abuse the "working directory"


Now you're probably wondering. "That's awesome. However, what if I move my configuration files? Then they'll all break again!" Yep, absolute paths will do that do you. However, before you embark on using relative paths, you need to know something that will catch you off guard. If you specify a path in a config file and it references something other than an absolute path (i.e. one with a C:\ or / at the beginning), it will attempt to use a path relative to the location that the program was started. This is not necessarily the same thing as the directory the server binary is located in either, as you can run programs from any directory. For example:

$ cd /opt/skulltag
$ ./bin/98c/skulltag-server +exec "cfg/doom2-coop.cfg"


This will load /opt/skulltag/cfg/coop.cfg, not /opt/skulltag/bin/98c/cfg/coop.cfg, all because you started it from /opt/skulltag.

Neat-o, right? However, this doesn't just work for configuration files. It works for anything that uses a path. Observe:

$ cd /opt/skulltag
$ ./bin/98c/skulltag-server -iwad "wad/doom2.wad" +sv_banfile "list/banlist.txt" +exec "cfg/doom2-coop.cfg"


Now you're cooking with gas. Your server binaries are separated from your wad files, which are separated from your banlists, which are separated from your config files.

Putting it all together


Here is a sample skeleton config file that I use for my own servers. I put this in /opt/skulltag/cfg/skeleton.cfg and whenever I need a new server I simply copy the config file and then +exec it from the command line.

cfg/skeleton.cfg


// SKULLTAG SERVER CONFIGURATION FILE
// by AlexMax

// INCLUDE FILES
// Do not remove any of these commands.
exec "cfg/include/reset.cfg"
exec "cfg/include/global.cfg"
exec "cfg/include/alias.cfg"

// GAMEPLAY INCLUDES
// Uncomment one of the following commands to select which flavor of doom
// gameplay you wish to use.
//exec "cfg/include/os.cfg" // Oldschool settings (-deathmatch)
//exec "cfg/include/os-altdeath.cfg" // Oldschool settings (-altdeath)
//exec "cfg/include/ns.cfg" // Newschool settings
//exec "cfg/include/st.cfg" // Skulltag settings

// GAMETYPE INCLUDES
// Uncomment one of the following commands to determine which gametype you
// wish to play.
//exec "cfg/include/duel.cfg"
//exec "cfg/include/dm.cfg"

// ADDITIONAL SETTINGS
// If there is a setting that is either not covered by the above includes or
// is a setting you wish to overide, you should place such settings here.
// Please read the Skulltag Wiki for a full list of possible server settings.

// MAP ROTATION
clearmaplist

// Shuffle Maplist. If set, maps will be picked randomly from the available
// added maps.
sv_randommaprotation false

// Add any maps that you would like to be included in the map rotation
// to the section below.
// -- START MAPLIST --
addmap map01
addmap map02

addmap map03
addmap map04

addmap map05
// -- END MAPLIST --

// Set the map that you want to be loaded when the server starts here.
map map01

cfg/include/reset.cfg


// RESET CONFIGURATION FILE
// by AlexMax

// There should never be a reason to edit this file. This merely sets up sane
// defaults so your configuration doesn't keep any residual cvars from other
// servers.

crashlogs 2
crashlog_dir "crashlogs/"
duellimit 0
fraglimit 0
pointlimit 0
timelimit 0
winlimit 0

sv_adminlistfile "list/adminlist.txt"
sv_banexemptionfile "list/whitelist.txt"
sv_banfile "list/banlist.txt"
sv_banfilereparsetime 60
sv_broadcast false
sv_colorstripmethod 1
sv_defaultdmflags false
sv_disallowbots true
sv_enforcemasterbanlist true
sv_enforcebans true
sv_forcepassword false
sv_forcejoinpassword false
sv_joinpassword ""
sv_logfile_append true
sv_logfilenametimestamp false
sv_logfiletimestamp true
sv_logfiletimestamp_usedate true
sv_maprotation true
sv_markchatlines true
sv_minvoters 1
sv_password ""
sv_pure true
sv_timestamp true
sv_timestampformat 0
sv_updatemaster true

cfg/include/global.cfg


// GLOBAL CONFIGURATION FILE
// by AlexMax

// Put your configuration changes that you want to see across all servers
// in this file. You should keep this file hidden, for obvious reasons.

// Server title. This is used anytime you forget to set the hostname from
// the command line or another config file. I suggest using your server name,
// followed by "Skulltag Server" or something equally vague.
set sv_hostname "My Skulltag Server Farm || Skulltag Server"

// Host e-mail. If you want your users to be able to contact you via e-mail,
// put it here. Anybody who queries the server in a server browser can see
// this e-mail, so make sure it is an e-mail address that you don't mind
// being public-facing and unobfuscated.
sv_hostemail "user@example.com"

// Message of the day. This message will display to your users when they join
// your servers. Line breaks can be used here by using \n.
sv_motd "Welcome to Skulltag!\n\nHave fun!"

// RCON password. This is used to obtain access to the Skulltag server
// console while you're playing on the server as a client or through an
// RCON utility.
sv_rconpassword "changeme"

// Server website. If your server has any custom WAD files and you wish for
// them to be downloaded by server browsers such as Odalauncher, IDE or
// Doomseeker when connecting to your server, put the URL where the files can
// be located here.
sv_website "http://www.example.com/"


Take a good look at these config files so you can tell where files belong and what other config files you need to populate yourself, such as cfg/include/os.cfg and cfg/include/duel.cfg.

Finally, you need to start the server. I don't actually use shell scripts, but here's a sample one that ought to work, just substitute in your server parameters, and put it in the "root" directory of your skulltag installation.

Sample shell script


#/bin/sh
cd /opt/skulltag
./bin/98c/skulltag-server -iwad wads/doom2.wad -file wad/WADNAME.WAD -useip YOURIP -port PORT +sv_hostname "YOUR SERVER NAME" +exec cfg/CONFIG.CFG +logfile log/LOGFILE.LOG

Friday, September 17, 2010

A few thoughts on policing multiplayer communities

The other day, I had someone privately confide in me that they were overwhelmed by the amount of hacker witch hunts that were going on in their multiplayer community. I won't name who brought the concern up, or the name of the community, but an interesting question follows: how do you keep hackers out of a free multiplayer game while at the same time not making it too difficult for legitimate players, especially those who play casually and do not participate in the community proper, to play the game.

Before we continue, as someone who primarily plays Doom, I will list the three major multiplayer ports and their policing policies:
  • Odamex: Bans are purely done on an IP basis. Server owners can ban an IP or a whole range of them, and can store them in a banlist kept locally on the server.

  • Skulltag: Has the same local banlist as Odamex. In addition, there is a banlist handed out by the Skulltag master server that servers are required to use. Also, the source of the port is closed to prevent cheating.

  • ZDaemon: Has the same local and global banlist as Skulltag. In addition, you are required to create an account in order to play on a public server. Account creation is automated. In addition, access to the official forums is tightly controlled, your forum account must be verified manually by an administrator.

I am of the opinion that some of these policing systems are defective. Some of them are more defective than others, but they are all either deficient or defective in some way, and I'll list the primary reason why:

Using IP addresses to ban hackers will never be a comprehensive solution

If someone really wants to play on your servers, they will find a way. If you disable their account, they will create another one. If you ban them by IP, they will proxy around it. If you figure out a way to ban all open proxies, they will find less common ones. If you require some form of real life identification, they will steal it.

However, IP bans are not entirely useless. Many firewalls and intrusion detection systems use IP bans to deal with potential attackers, by blocking IP's after X failed attempts, or by whitelisting IP ranges where users are unlikely to come from. There is also the fact that banning an IP from a server is often enough to keep less ambitious undesired players out, perhaps those who are guilty of merely annoying the patrons of the server

So IP bans do have a use. However, these controls should be made available on a server-by-server basis, as the notion of there being one "blessed" central body that is capable of professionally and timely handling accusations of hacking for an entire free game is laughable at best.

The prospect of being able to keep an accused hacker or a supremely annoying user off of all servers is an appealing one, but the usage of the IP ban far too often promotes ban ranges that cover entire /24's or /16's, often banning entire countries or continents in the vain hopes that the problem will go away. Realistically, all it means is that a hacker now needs to find a proxy outside the range, and any legitimate players inside that range are out of luck unless they take the extraordinary step of pleading to the administrators in charge to let their IP range through. Most users will not take this step and instead play something else, since getting a "master ban" on their IP means that they can not play on literally any server on the server list.

There is also the question of community drama. Skulltag and ZDaemon have one "blessed" master banlist. If servers refuse to use the master banlist, they are not allowed to be listed on the master server list. In the past, there have been several incidents where IP ranges of players have been banned by the "blessed" administration for reasons other than hacking, and yet the server administrators are powerless to whitelist these IP ranges if they decide that they would rather "risk it" or otherwise disagree with the global bans. Arguments for preserving the "purity" of listed servers is a pretty laughable when you take into consideration that even with such a master banlist, there are rampant rumors of players hacking anyway. Far more popular games such as Battlefield Bad Company 2 and Team Fortress 2 both allow the server administrator to disable their "master banlists", and many free games don't even have a master banlist at all, such as Warsow and Urban Terror.

To sum things up: Globally-enforced IP banlists don't prevent hackers from using your servers, and can victimize perfectly innocent players, either knowingly (through community drama) or not (random player who is caught in the master banlist).

A note on user accounts.

Although I am clearly not a fan of using IP banlists for global policing of multiplayer game communities, this does not mean that I am also not a fan of user account systems. In fact, I love the idea of them. First, accounts give you player verification; it's much harder to pretend that you are a specific player when you don't have their credentials. They also give you persistence; an older, established account is much less likely to be someone who is on your server to ruin other players experience. It also opens up the doors to other neat features, such as the possibility of using your account as Remote Console credentials, or Modern Warfare-style experience points (which could be used by modifications).

One common mistake I've seen from time to time is where account systems are based on a username. I personally prefer something along the lines of Steam or Quakenet's Q, which does not guarantee you a nickname, as it also doesn't force you into a nickname either and allows it to change it later. And honestly, for a free game, I think that it would be a better idea if logins were optional, so players could play anonymously.

This is the area, in my opinion, where Odamex could use some improvement. Some form of optional user authentication would allow telling the legit players from the fakes a lot easier.

An additional note: I have been asked how these views extend to attacks against a game master server itself, for example a malicious server host that spams the master server with 255 servers running bot matches that advertise hacks in the hostname. I would consider that an attack against the master server itself. Those attacks ought to be blockable at the master server level by using an X server per IP limit, or filtering out heartbeats from malicious servers at the firewall level. But you don't need a forcibly distributed master banlist for that.

Sunday, June 14, 2009

Microsoft C/C++ Runtimes and 64-bit Vista

If your favorite program refuses to work in Windows Vista 64-bit due to an error about MSVCR??.DLL or MSVCP??.DLL being missing, then this post will be of interest to you. For some reason, Microsoft does not distribute these files with Windows Vista 64-bit, even though there are many legacy programs that depend on them. Googling these files leads to many confused message board posts and confusing and conflicting solutions that don't even work most of the time.

Here is the real solution to your missing DLL problems:
  1. Download the file(s) that the program is complaining about from DLL-files:
    You will need both the MSVCR??.DLL and MSVCP??.DLL files for a particular version. If you only download and install the one it complains about, it will ask you for the other one next.
  2. When you download a file from DLL-files it will come in a .ZIP archive. Extract the contents of the archives to your desktop. You can delete the text files, all you need are the .DLL files (Windows calls them "Application Extensions" if you have file extensions disabled).
  3. Open up Explorer and browse to the C:\Windows\SysWOW64 directory.
  4. Move the .DLL files you just extracted into this directory. Vista will give you a UAC prompt or two, just hit Continue when it prompts you.
That's it, your program should work. It would be nice if there was an official Microsoft-sanctioned redistributable for these files, but oh well.

I'm pretty sure I've run into this issue with other versions of Windows, but I don't care enough at the moment to throughly test what works and what doesn't. If you have WORKING advice for any other editions of Windows such as 32-bit Vista or perhaps even Windows XP, leave a comment.

Thursday, May 28, 2009

First Post!

This is my blog. There are many other blogs around the internet but this one is mine.

It is also probably unlike most other blogs that you are used to. I am not so foolish as to think that some random Joe Stranger on the internet particularly cares who I am or what I did last Friday, but I do think that a general place where I can publicly dump ideas and articles would be handy.

In fact, I think I will be writing my first "real" post very shortly. Stay tuned!