Sunday, November 17, 2013

Mame arcade cabinet

The Cabinet

When I started this project, I decided the cabinet should be made last. If  I couldn't get the sticks and buttons, or get the actual software running, then all I would end up with would be an empty case at the end. Getting the bits to fit would be easier.

In planning my cabinet, I considered a couple of different designs: stand up, cocktail cabinet, and barcade. I decided on barcade because it was small and portable, and I could put it on a stand to make it a standup if i wished (though realistically, it's too small). I would have loved to have made a cocktail cabinet, but I wasn't sure I could get the glass for the top.

 I also considered a couple of materials. I do woodwork, so I thought of wooden panels, or using plywood or MDF. We've got some spare MDF , so I used that.

Here is a picture of the cardboard version I made to make sure all of the bits would fit, and also that I could make the parts fit on the MDF I have.



I used these approximately these plans to make my cabinet pattern. However I didn't put the curve in.
http://www.koenigs.dk/mame/eng/stepweecade3.htm

Here are some other plans for barcades.

http://bartoparcade.katorlegaz.com/

A cocktail cabinet  plan (Japanese style):
http://dannygalaga.com/mame.htm

http://members.iinet.net.au/~things/ihs/cocktail/index.html

http://web.archive.org/web/20050311053639/http://www.oblate-spheriods.demon.co.uk/mame.htm


Saturday, November 16, 2013

Roms and screenshots

Of Roms and Screenshots

I downloaded my Roms from a  torrent site. It had large number of ROMs from different systems (dreamcast, megadrive/genesis, master system, playstation  etc). However many of the the MAME ROMs didn't work with the version of MAME I had in Puppy linux, nor with the MAME version from Debian.

However, downloading the most up to date ROMs for MAME would be onerous, especially given the low datacap I have. There are 28 thousand games in the current release for MAME. This means 29 gig of ROMs, and about the same in CHD files. CHD files are extra information for the ROM files, eg graphics and music. Sorting through that number of ROMs to get only the few that I really wanted would be crazy, so I'd need to get them another way.


So what I've done instead is pick through the ROMs which work and then re-download the ones from my wishlist. I was considering getting Space Ace and Dragon's Lair, old school laser disc games, but I haven't added them yet. I have the rom files, but not the video files. It could be fun creating a video disc game of my own ( there are editors out there, I don't think it would be hard) but I lack the time and inclination at the moment. Daphne is the emulator for those games.

For my other roms, there are other emulators which I could have used, especially the for the NES, which has quite a variety, but as I said before, these are the ones which worked with all of my roms. 
I only picked 2d systems with a limited number of buttons, since I have four fire buttons and  two other buttons. Unfortunately this excluded the Super NES. I did have a spare 3d card, but since I was testing the setup on a different system (by adding the hard drive to my current computer and rebooting into the harddrive) I decided I couldn't really test it effectively. I've got the setup down now, so if I really wanted to add some more emulators (and buttons) I could.

So I have:

Gens - for Megadrive/Sega Genesis
Fceaux - NES
osmose - Sega Master System
mame - arcade
Gngeo - Neogeo

As stated above, many of the ROMs I had downloaded for MAME didn't work. I had a wishlist of games to get, and so I tried downloading them from a couple of ROM sites.
 The best one I found was http://www.mamest.com/ You can search by game name, ROM name, or the names of files within the zip file. Thats really handy if you have a ROM which isn't going, and you need to download another file to fix it.
Verifying ROMs

MAME and some of the other emulators allow you to verify your ROMs. You run the command against the ROM directory and it will spit out a list of ROMs which will run, and ones which wont. It even gives you the names of the missing files. However, it *doesn't* tell you which ROM file which contains those files though. So, if you have a game called "safety dance" based on "stair dancer", it'll tell you need the file stairdancer.bin, but not that its in the "stair dancer" parent zip file. Thats where the website comes in. It makes fixing games really much easy.

Snaps: aka screenshots or previews

I got my screenshots for the previews from a variety of web sources. I needed to rename some of the files to match the rom names, otherwise advmenu doesn't pick them up.  Here is the (very ugly) script I used to rename the misnamed files.

I downloaded my sega megadrive screenshots from here, and  the NES ones too I think? It looks quite comprehensive for many systems.
 https://www.dropbox.com/sh/8xuhgxahhk6pfk4/umSNUhRGC0

I got my NeoGeo  screenshots by leeching this site (mostly because I wasn't sure the above site had them)
 http://www.neogeosoft.com/?section=artwork&filter=mvs

I leeched this site for the Sega Master System, though many of the files needed to be renamed.
 http://www.vgmuseum.com/

For MAME I used  Hitf12:
http://www.mameworld.info/hitf12/



An ugly script to rename Rom files

This is a bash script to rename snaps (screenshots/previews)  to the corresponding ROM file. it easier than tediously doing it manually.

Be warned! It may be buggy. I basically got it to the state where it would read the snaps and the ROMs. You can go back/forward in the ROM list, and skip back/forward by 10 in the snaps list. It displays one ROM and 10 snaps, you choose from the list which one to rename by typing a number from 1 to 10.

I'd strongly suggest running this against a copy of your snaps directory, and only copying it over once you verify the images are correct.





#!/bin/bash
#rename the file, then increment the lists?

#Neo Geo
Filename_Array=(/Roms/NeoGeo/roms/*)
RenamingThese_Array=(/Roms/NeoGeo/snaps/*)

##variables
#counters
Filename_Start=0
Rename_Start=0

skip_amount=10
array_end=$[${#RenamingThese_Array[@]} -$skip_amount]

function rename_files(){
echo
echo ----Original Rom File ----
echo ${Filename_Array[Filename_Start]}
echo

IFS="^"
a=$Rename_Start
b=$[Rename_Start+1]
c=$[Rename_Start+2]

d=$[Rename_Start+3]
e=$[Rename_Start+4]
f=$[Rename_Start+5]

g=$[Rename_Start+6]
h=$[Rename_Start+7]
i=$[Rename_Start+8]

j=$[Rename_Start+9]

names=(
${RenamingThese_Array[a]}
${RenamingThese_Array[b]}
${RenamingThese_Array[c]}

${RenamingThese_Array[d]}
${RenamingThese_Array[e]}
${RenamingThese_Array[f]}

${RenamingThese_Array[g]}
${RenamingThese_Array[h]}
${RenamingThese_Array[i]}

${RenamingThese_Array[j]}
next5 back5 previous_rom skip_5_roms)
echo ----Rename File ----
echo Press any other key to skip renaming the image file

PS3="Choose an image file (1-$skip_amount) to rename:"

select varname in ${names[*]}; do
   if [[ -n "$varname" ]]; then
       # chop off the filename from $varname, and from ${Filename_Array[0]}
       echo ${Filename_Array[Filename_Start]}
       echo $varname

       if [[ $varname = "next5" ]]; then
        Rename_Start=$[$Rename_Start+$skip_amount]
        if [[ $Rename_Start -gt $array_end ]]; then
      echo $array_end
      echo $Rename_Start
          echo "Reached the end of the list of images"
      Rename_Start=$array_end
    fi
    break
       fi

       if [[ $varname = "back5" ]]; then
    Rename_Start=$[$Rename_Start-$skip_amount]
    if [[ $Rename_Start -lt 0 ]]; then
      echo "Reached the start of the list of images"
      Rename_Start=0
     fi
    break
       fi
   
       if [[ $varname = "previous_rom" ]]; then
    Filename_Start=$[$Filename_Start-1]
    if [[ $Filename_Start -lt 0 ]]; then
      echo "Reached the start of the list of images"
      Filename_Start=0
     fi
    break
       fi

       if [[ $varname = "skip_5_roms" ]]; then
    Filename_Start=$[$Filename_Start+1]
    break
       fi      

       # get only the file name of the file
       FILENAME_AND_EXTN=$(echo ${Filename_Array[Filename_Start]} | rev | cut -d"/" -f1 | rev)
       FILENAME=$( echo $FILENAME_AND_EXTN | cut -d"." -f1)

       VARNAME_AND_EXTN=$(echo $varname | rev | cut -d"/" -f1 | rev)
       EXTENSION=$( echo $varname | cut -d"." -f2)
    #EXTENSION=jpg

       # get the path of the destination directory
       ONLY_PATH=$(echo $varname | rev | cut -d"/" -f2- | rev)
       echo mv "$varname" "$ONLY_PATH/$FILENAME.$EXTENSION"
       mv "$varname" "$ONLY_PATH/$FILENAME.$EXTENSION"
       #increment files to process
       Filename_Start=$[$Filename_Start+1]
       #Rename_Start=$[$Rename_Start+1]             
       # start over   
       #function rename
       break
   else
       echo 'skipped renaming file'
       echo $Rename_Start
       Filename_Start=$[$Filename_Start+1]
       break
   fi
done

#echo $Filename_Start

rename_files
}

rename_files

Friday, November 15, 2013

Arcade controls for my homebrew arcade machine


Sticks and buttons

I got my stick and buttons off an online auction site (www.trademe.co.nz). They are all genuine arcade parts. I bought one Sanwa 8 way joystick, and four Streetfighter style buttons (which are concave, rather than convex). I prefer those buttons, as most arcade machines I played on had that style of button. I also bought two player 1/player 2 buttons with the intention of having a seperate (home made) coin mech for credits.








I only bought 4 buttons because I don't like fighting games, which usually require 6. There is a web page (I can't find it again) which shows stats for the number of buttons used, by far 3 or 4 buttons was the most common. I also bought only one stick, for a couple of reasons. Mostly, it was quite expensive, and I wasn't sure how successful my hack would be. Given the issues I've since had with the keyboard hack, I think if I was doing a multi-player cabinet I would get some actual joysticks. Keyboards don't seem to be designed for too many key inputs at once.

The keyboard that I used had a limited number of buttons which could be pressed at once, due to the way the key matrix is set up. I'd say that most keyboards are like that.

However, if I can modify my control panel so the buttons are removable, then I would happily set up something which would hot-swap a button/joystick panel for twinstick shooters.

Wiring a keyboard as a joystick + buttons:

I pulled apart an old ps2 keyboard. You could equally pull apart (or use) a USB joystick. I thought about buying one of -these- USB joysticks and putting it part, but ultimately decided to go with a keybaord.

Inside, there is a board which allows each key press to be interpreted as a letter.


I took 3 goes before I finally wired my keyboard correctly! I got instructions for wiring the keyboard from this instructible and soldered  it up. However, I skipped step 4 (which requires using a multimeter to get the keycodes) and hooked the keyboard up to my computer. Using a bit of wire, I simulated pressing a key by shorting the contacts for each key, and mapped out each key on a piece of paper, in a grid.



I found out the keys pressed by running testkeys from the mame-tools package. This is better than just pressing keys on the console or a text editor, as it will display non-printing characters, such as shift (and even say if its left or right shift). The reason I took so many tries to do the joystick was because some of the keys would block other keys from being pressed. Eg (use example from the keycode matrix)

This page explains how keyboard matricies work. Effectively, I had hooked up my keyboard so the key A1 and A3 could be pressed at once: A1 was
"joystick left" and Button 2 was A3. The keyboard didn't know both keys were being pressed at once, and would only send the first input. So I couldn't move when I had a button held down. So I needed to pull out all of my connections and start over.

I started out with hooks made from paperclips, but ended up soldering it in the end, as I thought it might be more robust. If I ever redo it, I'll try drilling wiring holes in the circuit board, and solder the wires through, instead of soldering it directly on. I'll also use some kind of quick release system or something so I don't waste so much heat shrink tubing. Too many of the contacts either came off when I was resoldering, or  got  pulled off by the weight of the harness (or my impatience).






I did make quick release end bits for the switch ends of the wires, so I could rewire the switches if I needed to. They worked really well, though I used a lot of heatshrink tubing to make them neat and tidy.

I'm not sure what I would do for twinsticks, but I could have it so the second stick uses the same keys as the four buttons, and have the buttons/extra stick each on their own removable baseplate.

Or I could make another cabinet, for twinstick shooters :P



Tuesday, November 5, 2013

Emulator choice and sample Advancemenu configuration file


Emulators

My emulator choices were constrained by a couple of things. Firstly, I had downloaded a heap of ROMs (from a disk put out in 1998!) so they needed to work with them. Secondly, there aren't that many emulators for Linux (especially for NeoGeo!). 

I was considering getting Space Ace and Dragon's Lair, old school laser disc games, but I haven't added them yet. I have the ROM files, but not the video files. It could be fun creating a video disc game of my own ( there are editors out there, I don't think it would be hard) but i lack the time and inclination at the moment.-Daphne is the emulator for those games. Here is how to get it to work with Advancemenu

For my other ROMs, there are other emulators which I could have used, especially for the NES, which has quite a variety, but as I said before, these are the ones which worked with my roms. 

So I have: 
Gens for Sega Megadrive (aka Genesis)
Osmose for Sega Master System
MAME for arcade machines
fceux for NES games
Gngeo for Neo Geo games

Frontends
I'm using this in a cabinet, with a heap of roms and emulators all mixed together, so I need a frontend to launch the different games, and keep everything organised. I've opted for Advancemenu, though there are loads of other frontends (a couple of lists are here and here) which are up to the task. Advancemenu can display the games how I want (a list on the left, screenshot on the right), and works with all of the emulators I want to use. Effectively, you could use advancemenu as a launcher for just about anything - movies, music, whatever - not just games.

Configuration files

Advancemenu (download my config here, includes comments)

My Advance menuconfig has the following features:
*Multiple emulators, with one emulator per screen.
*Custom keys mapped to page through ROM lists (one emulator per page).
*A 'utility' section, for shutdowns, restarts and verifying mame roms.
*Preview screenshots of games.
*8bit tunes as background music for the menu.

The music directory and mame roms directories are on a usb stick, which gets loaded when the operating system starts up.  I used ls-by-uuid to get the uuid of the usb stick, and added the following line to my /etc/fstab to load it where I wanted each time:

 UUID=dac3b911-d2e7-462d-b0cf-d19aa4d1fa48 /Roms/MAME/ fat32  auto  0       0
Utility directory
This has 3 scripts, one to shutdown the computer, one to restart the computer, and one to verify the mame roms. To do the shutdown and restarts, I had to add the user running Advancemenu to /etc/shutdown.allow.

Some configuration tips
You can add BIOS files to emulators, so they can run more games, for example adding the Naomi BIOS to MAME allows you to play Naomi based games. I put them in a seperate BIOS folder, and add that to the ROM search path in the emulator config file. That way the emulator can read the file, but Advancemenu doesn't add the BIOS files to its menu.  
All of the emulators I've used allow for multiple paths to the files.

Sample config file for AdvanceMenu, with comments

So it seems I can't upload text files to blogger (who knew!) so I've just dumped my Advmenu config as a blog post.



#updated by Zenoscope
config restore_at_exit
device_alsa_device default
device_alsa_mixer channel
device_color_bgr15 yes
device_color_bgr16 yes
device_color_bgr24 yes
device_color_bgr32 yes
device_color_bgr8 yes
device_color_palette8 yes
device_color_yuy2 yes
device_joystick none
device_keyboard auto
device_mouse none
device_raw_firstkeyhack no
device_raw_mousedev[0] auto
device_raw_mousedev[1] auto
device_raw_mousedev[2] auto
device_raw_mousedev[3] auto
device_raw_mousetype[0] pnp
device_raw_mousetype[1] pnp
device_raw_mousetype[2] pnp
device_raw_mousetype[3] pnp
device_sdl_samples 512
#updated by Zenoscope
#otherwise conflicts with what the emulators are using
device_sound oss
device_video auto
device_video_cursor auto
device_video_doublescan yes
device_video_fastchange no
device_video_interlace yes
#updated bu Zenoscope - fullscreen Advmenu
#device_video_output fullscreen
device_video_output auto
device_video_overlaysize 1024
device_video_singlescan yes
difficulty none
display_brightness 1
display_gamma 1
display_orientation
display_restoreatexit yes
display_restoreatgame yes
#updated by Zenoscope
display_size 800

#The emulators AdvanceMAME, AdvanceMESS, MAME, xmame, DMAME, DMESS and DRAINE
# are directly supported. All other emulators require "generic"
#updated by Zenoscope
# Xmame Arcade emulator

emulator "xmame" generic "/usr/local/bin/xmame.x11"
emulator_roms "xmame" "/Roms/MAME/"
emulator_roms_filter "xmame" "*.zip"
emulator_altss "xmame" "/Roms/MAME/snaps"

#Gens Megadrive/Genesis emulator
emulator "megadrive" generic "/usr/local/bin/gens"                      
emulator_roms "megadrive" "/Roms/SegaMegaDrive/roms/"                                       
emulator_roms_filter "megadrive" "*.zip"                                      
emulator_altss "megadrive" "/Roms/SegaMegaDrive/snaps"

#Mastersystem emulator
emulator "SegaMS" generic "/usr/bin/osmose"
emulator_roms "SegaMS" "/Roms/SegaMS/roms/"
emulator_roms_filter "SegaMS" "*.zip"
emulator_altss "SegaMS" "/Roms/SegaMS/snaps"

#NES emulator
emulator "NES" generic "/usr/bin/fceu -opengl 0"
emulator_roms "NES" "/Roms/NES/roms/"
emulator_roms_filter "NES" "*.zip"
emulator_altss "NES" "/Roms/NES/snaps"

#SNES
emulator "SNES" generic "/usr/bin/znes"
emulator_roms "SNES" "/Roms/SNES/roms/"
emulator_roms_filter "SNES" "*.zip"
emulator_altss "gens" "/Roms/SNES/snaps"

#NeoGeo
emulator "NeoGeo" generic "/usr/bin/neocd"
emulator_roms "NeoGeo" "/Roms/NeoGeo/roms/"
emulator_roms_filter "NeoGeo" "*.zip"
emulator_altss "NeoGeo" "/Roms/NeoGeo/snaps"

#Daphne a laserdisk game emulator, needs the video files to go as well.
#emulator "daphne" generic "/usr/local/bin/*****"
#emulator_roms "daphne" "/Roms/Daphne/roms/"
#emulator_roms_filter "daphne" "*.zip"
#emulator_altss "daphne" "/Roms/Daphne/snaps"

#These ones need OpenGL to go.

#N64 emulator
# needs open GL drivers                                                                 
#emulator "N64" generic "/usr/local/mupen64plus-1.5/mupen64plus"                                  
#emulator_roms "N64" "/Roms/N64/roms/"                                         
#emulator_roms_filter "N64" "*.zip"                                            
#emulator_altss "N64" "/Roms/N64/snaps"

#Dreamcast
#emulator "dreamcast" generic "/usr/bin/lxdream"
#emulator_roms "dreamcast" "/Roms/dreamcast/roms/"
#emulator_roms_filter "dreamcast" "*.zip"
#emulator_altss "dreamcast" "/Roms/dreamcast/snaps"

#Sega Saturn
#emulator "saturn" generic "/usr/local/bin/saturn"
#emulator_roms "saturn" "/Roms/saturn/roms/"
#emulator_roms_filter "saturn" "*.zip"
#emulator_altss "saturn" "/Roms/saturn/snaps"

#psx
#emulator "psx" generic "/usr/local/bin/gens"
#emulator_roms "psx" "/Roms/psx/roms/"
#emulator_roms_filter "psx" "*.zip"
#emulator_altss "psx" "/Roms/psx/snaps"

#menu organisation stuff
#mode list
#preview snap

event_alpha yes
event_assign up up or 8_pad
event_assign down down or 2_pad
event_assign left left or 4_pad
event_assign right right or 6_pad
event_assign enter enter or enter_pad
event_assign esc esc
event_assign space space
event_assign home home
event_assign end end
event_assign pgup pgup
event_assign pgdn pgdn
event_assign del del
event_assign ins insert
event_assign shutdown lcontrol esc
event_assign mode tab
event_assign help f1
event_assign group f2
event_assign type f3
event_assign exclude f4
event_assign sort f5
event_assign setgroup f9
event_assign settype f10
event_assign runclone f12
event_assign command f8
event_assign menu backquote or backslash
event_assign emulator f6
event_assign rotate 0_pad
event_assign lock scrlock
event_assign preview space
event_assign mute period_pad
event_mode fast
event_repeat 500 50
#group "Very Good"
#group "Good"
#group "Bad"
#group ""
icon_space 43
idle_screensaver 60 10
idle_screensaver_preview snap
idle_start 0 0
include
input_hotkey yes
lock no
menu_base 0
menu_rel 0
merge differential
misc_exit normal
misc_quiet no
#updated by Zenoscope
mode_skip full, full_mixed, text, list_mixed, tile_small, tile_normal, tile_big, tile_enormous, tile_giant, tile_icon, tile_marquee
mouse_delta 100
#preview_default none
#preview_default_cabinet none
#preview_default_flyer none
#preview_default_icon none
#preview_default_marquee none
#preview_default_snap none
#preview_default_title none
#preview_expand 1.15
sort parent
sound_background_begin none
sound_background_end none
sound_background_loop default
sound_background_loop_dir "/Roms/SystemFiles/Music"
sound_background_start none
sound_background_stop none
sound_buffer 1
sound_foreground_begin none
sound_foreground_end none
sound_foreground_key default
sound_foreground_start default
sound_foreground_stop default
sound_latency 0.1
sound_samplerate 44100
sound_volume -3
#ui_background none
#updated by Zenoscope
ui_background /Roms/SystemFiles/Menu_Graphics/background.png
#updated by Zenoscope
ui_bottombar no
ui_clip single
ui_color help 000000 ffffff
ui_color help_tag 247ef0 ffffff
ui_color submenu_bar 247ef0 ffffff
ui_color submenu_item 000000 ffffff
ui_color submenu_item_select 000000 afffff
ui_color submenu_hidden 808080 ffffff
ui_color submenu_hidden_select 808080 afffff
ui_color menu_item 000000 ffffff
ui_color menu_hidden 808080 ffffff
ui_color menu_tag 247ef0 ffffff
ui_color menu_item_select 000000 afffff
ui_color menu_hidden_select 808080 afffff
ui_color menu_tag_select 247ef0 afffff
ui_color bar 000000 ffffff
ui_color bar_tag 247ef0 ffffff
ui_color bar_hidden 808080 ffffff
ui_color grid 247ef0 ffffff
ui_color backdrop 000000 808080
ui_color icon ffffff ffffff
ui_color cursor 808080 ffffff
ui_command_error Error running the command
ui_command_menu Command...
ui_command "shut down" "/usr/bin/shutdown"
ui_console no
#updated by Zenoscope
#ui_exit none
ui_exit normal
#updated by Zenoscope
ui_font "/Roms/SystemFiles/Fonts/freaky-fonts_liquid-kidz/lqdkdz_nospace.ttf"
ui_fontsize auto
ui_game snap
ui_gamemsg "Loading"
ui_help none
ui_menukey yes
#updated by Zenoscope (all skip configs)
ui_skipbottom 20
ui_skipleft 20
ui_skipright 20
ui_skiptop 90
ui_startup none
ui_topbar no
ui_translucency 0.6
group_include ""
group_include "Good"
type_include ""
type_include "Application"
type_include "Arcade"
type_include "Bet 'em Up"
type_include "Breakout"
type_include "Computer"
type_include "Console"
type_include "Fight"
type_include "Filler"
type_include "Flipper"
type_include "Gun"
type_include "Puzzle"
type_include "RPG"
type_include "Racing"
type_include "Shot 'em Up"
type_include "Sport"

emulator_include "xmame"
xmame/mode tile_normal
xmame/preview snap
xmame/sort parent

emulator_include "megadrive"
megadrive/mode tile_normal
megadrive/preview snap
megadrive/sort parent

emulator_include "SegaMS"
SegaMS/mode tile_normal
SegaMS/preview snap
SegaMS/sort parent

emulator_include "SNES"
SNES/mode tile_normal
SNES/preview snaps
SNES/sort parent

emulator_include "NES"
NES/mode tile_normal
NES/preview snaps
NES/sort parent

emulator_include "neogeo"
neogeo/mode tile_normal
neogeo/preview snaps
neogeo/sort parent

#emulator_include "psx"
#psx/mode tile_normal
#psx/preview snaps
#emulator_include "dreamcast"
#psx/mode tile_normal
#psx/preview snaps
#emulator_include "daphne"
#psx/mode tile_normal
#psx/preview snaps
#emulator_include "N64"
#psx/mode tile_normal
#psx/preview snaps

#menu organisation stuff

group_include ""
type_include ""
xmame/group_include "Good"
xmame/type_include ""
emulator_include "MAME"
group ""
group "Good"
type ""


group ""
group "Good"
type ""
type "Application"
type "Arcade"
type "Bet 'em Up"
type "Breakout"
type "Computer"
type "Console"
type "Fight"
type "Filler"
type "Flipper"
type "Gun"
type "Puzzle"
type "Racing"
type "RPG"
type "Shot 'em Up"
type "Sport"