Hello,

I want to share my experience on adding support for Neo Geo games to
Freevo 1.9 in case anybody is interested.
I've found that the procedure a bit complicated, but the results are
worth it.  The quality of the games is impressive.

Here is what has to be done:

1. Install gngeo 0.7 from http://gngeo.berlios.de/
If you want an assembler optimized build you should first install
nasm, and then configure gngeo with:
--enable-i386asm --enable-star --enable-raze

2. Download the BIOS rom files for neogeo.  This is the hard part,
because there are so many versions, and not all of them work with all
games.  The one I'm using allows me to run most games, but I'm still
missing KoF, and other interesting games.  I found the BIOS rom files
in a torrent website, its called neogeo.zip, and its a 2.1Mb file.
If anybody can point me to where to find valid bios rom files for KoF
I would appreciate it.

3. Configure gngeo for your freevo user.  You can copy a sample
configuration file from the gngeo tarball, but you have to configure
two important options:
"rompath" should point to where you store your games rom files.  Game
rom files must be kept inside their zip archives.
"biospath" should point to where you store your bios rom files (this
is missing in the sample configuration).  I keep my bios rom files in
a separated directory from games, uncompressed.

You might want to enable fullscreen and configure the joysticks as well.

I'm using these gamepads:
http://www.tomshardware.com/news/super-nes-nintendo-controller-usb,9809.html

The website says they cost 2700 yen, but I only paid 1000 yen for each.
With these gamepads I used this button configuration:

p1joy     3,1,0,2,7,6,0,1,1,1
p2joy     3,1,0,2,7,6,0,1,1,1


4. Configure Freevo for gngeo.  You have to add a new item to the
GAMES_ITEMS configuration option.
It should be possible to just use the GENERIC type, but I implemented
a new type called NEOGEO.
I'm attaching a patch to this message that enables you to use the
NEOGEO type as well.
I'm no python programmer, so my patch is very simple: I just copied
the classes used for MAME and changed a few things to make them work
with gngeo.
I would be very happy if this is integrated into the official Freevo
distribution.

To apply the patch just save the attachment to /tmp and then run:
patch -p 2 -d /usr/lib/python/site-packages/freevo/games -i
/tmp/freevo-neogeo.patch

Then configure freevo like this:

In /etc/freevo/local_conf.py:

GAMES_ITEMS = [
     ('Super Nintendo', '/data/roms/snes', ('SNES',
'/var/lib/freevo/bin/zsnes', '-m', '', None )),
     ('Neo Geo','/data/roms/neogeo', ('NEOGEO',
'/var/lib/freevo/bin/gngeo', '-f', '', [ 'zip' ])),
]

In /usr/share/freevo/freevo_config.py:
GAMES_NEOGEO_CACHE = '%s/romlist-%s.pickled' % (FREEVO_CACHEDIR, os.getuid())

Note: you can make this second change in /etc/freevo/local_conf.py
instead of /usr/share/freevo/freevo_config.py, because files in /usr
will be overwritten when you upgrade Freevo.

That's all.

I would be glad to get any comments or suggestions.  I'm willing to
post this information to the Wiki if anybody considers it useful, but
first I would like to know if the developers are willing to include my
trivial patch in the official distribution.

Alan
diff -r -N -u freevo/games.orig/__init__.py freevo/games/__init__.py
--- freevo/games.orig/__init__.py	2010-08-27 10:04:53.901408997 +0900
+++ freevo/games/__init__.py	2010-08-27 10:09:02.838050612 +0900
@@ -35,9 +35,11 @@
 
 import menu
 import mame_cache
+import neogeo_cache
 import plugin
 
 from mameitem import MameItem
+from neogeoitem import NeogeoItem
 from snesitem import SnesItem, snesromExtensions
 from genesisitem import GenesisItem, genesisromExtensions
 from genericitem import GenericItem
@@ -91,6 +93,14 @@
                     files.remove(rm_file)
                 for ml in mame_list:
                     items += [ MameItem(ml[0], ml[1], ml[2], cmd, args, imgpath, parent, ml[3]) ]
+            elif gtype == 'NEOGEO':
+                neogeo_files = util.find_matches(files, [ 'zip' ] )
+                # This will only add real neogeo roms to the cache.
+                (rm_files, neogeo_list) = neogeo_cache.getNeogeoItemInfoList(neogeo_files, cmd)
+                for rm_file in rm_files:
+                    files.remove(rm_file)
+                for ml in neogeo_list:
+                    items += [ NeogeoItem(ml[0], ml[1], ml[2], cmd, args, imgpath, parent, ml[3]) ]
             elif gtype == 'SNES':
                 for file in util.find_matches(files, snesromExtensions + [ 'zip' ]):
                     items += [ SnesItem(file, cmd, args, imgpath, parent) ]
diff -r -N -u freevo/games.orig/neogeo_cache.py freevo/games/neogeo_cache.py
--- freevo/games.orig/neogeo_cache.py	1970-01-01 09:00:00.000000000 +0900
+++ freevo/games/neogeo_cache.py	2010-08-27 18:39:03.944990456 +0900
@@ -0,0 +1,214 @@
+# -*- coding: iso-8859-1 -*-
+# -----------------------------------------------------------------------
+# neogeo_cache.py - Module for caching NEOGEO rom information for Freevo.
+# -----------------------------------------------------------------------
+# $Id: $
+#
+# Notes: This contains some rominfo code from videogame.py.
+# Todo:
+#
+# -----------------------------------------------------------------------
+# Freevo - A Home Theater PC framework
+# Copyright (C) 2002 Krister Lagerstrom, et al.
+# Please see the file freevo/Docs/CREDITS for a complete list of authors.
+#
+# This program 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.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MER-
+# CHANTABILITY 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 this program; if not, write to the Free Software Foundation, Inc.,
+# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# -----------------------------------------------------------------------
+
+
+import sys
+import random
+import time, os, string
+
+# Classes to keep track of our roms
+import neogeo_types
+
+# Configuration file.
+import config
+
+# Various utilities
+import util
+
+# RegExp
+import re
+
+from gui.PopupBox import PopupBox
+
+TRUE = 1
+FALSE = 0
+
+
+#
+# Lets get a NeogeoRomList if one is available from disk.  If not
+# then we shall return an empty one.
+#
+def getNeogeoRomList():
+    file_ver = None
+    neogeoRomList = None
+
+    if os.path.isfile(config.GAMES_NEOGEO_CACHE):
+        neogeoRomList = util.read_pickle(config.GAMES_NEOGEO_CACHE)
+
+        try:
+            file_ver = neogeoRomList.TYPES_VERSION
+        except AttributeError:
+            print 'The cache does not have a version and must be recreated.'
+
+        if file_ver != neogeo_types.TYPES_VERSION:
+            print (('NeogeoRomList version number %s is stale (new is %s), must ' +
+                    'be reloaded') % (file_ver, neogeo_types.TYPES_VERSION))
+        else:
+            _debug_('Got NeogeoRomList (version %s).' % file_ver)
+
+    if neogeoRomList == None:
+        neogeoRomList = neogeo_types.NeogeoRomList()
+
+    print "NeogeoRomList has %s items." % len(neogeoRomList.getNeogeoRoms())
+    return neogeoRomList
+
+
+#
+# function to save the cache to disk
+#
+def saveNeogeoRomList(neogeoRomList):
+
+    if not neogeoRomList or neogeoRomList == None:
+        neogeoRomList = neogeo_types.NeogeoRomList()
+
+    util.save_pickle(neogeoRomList, config.GAMES_NEOGEO_CACHE)
+
+
+#
+# We should keep neogeoRomList up to date.
+# This function takes in a list of files and makes sure
+# the cache has any relevant information.
+#
+def neogeoRomListFromListinfo(neogeo_cmd):
+    # This method of running xneogeo --listinfo and parsing the output was
+    # borrowed from pyrecade - http://pyrecade.sf.net.
+
+    try:
+        listinfo = os.popen(neogeo_cmd + ' --listgame', 'r')
+    except:
+        print 'Unable to get neogeo listinfo.'
+        return FALSE
+
+    newRom = neogeo_types.NeogeoRom()
+    cache = {}
+
+    for line in listinfo.readlines():
+        if re.compile("^([^\s:]*)\s*:\s*(.*)").match(line):
+            newRom = neogeo_types.NeogeoRom()
+            [newRom.name, newRom.description] = re.compile("^([^\s:]*)\s*:\s*(.*)").match(line).group(1, 2)
+            cache[newRom.name] = newRom
+
+    listinfo.close()
+
+    neogeoRomList = neogeo_types.NeogeoRomList()
+    neogeoRomList.setNeogeoRoms(cache)
+    return neogeoRomList
+
+def roms_equal( lhs, rhs ) :
+    return ( (lhs.name == rhs.name) and
+             (lhs.description == rhs.description) and
+             (lhs.year == rhs.year) and
+             (lhs.manufacturer == rhs.manufacturer) and
+             (lhs.cloneof == rhs.cloneof) and
+             (lhs.romof == rhs.romof) )
+
+def roms_compare( lhs, rhs ) :
+    if not roms_equal( lhs, rhs ) :
+        print "%s not equal to %s" % ( lhs.name, rhs.name )
+        if ( lhs.name != rhs.name ) :
+            print( "Names: '%s' vs '%s'" % (lhs.name, rhs.name) )
+        if ( lhs.manufacturer != rhs.manufacturer ) :
+            print( "Manufacturers: '%s' vs '%s'" % (lhs.manufacturer, rhs.manufacturer) )
+        if ( lhs.description != rhs.description ) :
+            print( "Descriptions: '%s' vs '%s'" % (lhs.description, rhs.description) )
+        if ( lhs.year != rhs.year ) :
+            print( "Years: '%s' vs '%s'" % (lhs.year, rhs.year) )
+        if ( lhs.cloneof != rhs.cloneof ) :
+            print( "Cloneofs: '%s' vs '%s'" % (lhs.cloneof, rhs.cloneof) )
+        if ( lhs.romof != rhs.romof ) :
+            print( "Romofs: '%s' vs '%s'" % (lhs.romof, rhs.romof) )
+
+def romsets_compare( lhs, rhs ) :
+    lkeys = lhs.neogeoRoms.keys()
+    rkeys = rhs.neogeoRoms.keys()
+    lkeys_not_in_rkeys = [ x for x in lkeys if x not in rkeys ]
+    rkeys_not_in_lkeys = [ x for x in rkeys if x not in lkeys ]
+    print "lhs keys not in rhs keys: %s" % lkeys_not_in_rkeys
+    print "rhs keys not in lhs keys: %s" % rkeys_not_in_lkeys
+    for key in lkeys :
+        if key in rkeys :
+            roms_compare( lhs.neogeoRoms[ key ], rhs.neogeoRoms[ key ] )
+
+def updateNeogeoRomList( neogeo_cmd ) :
+    _debug_("updating romlist by running " + neogeo_cmd)
+    neogeoRomList = neogeoRomListFromListinfo( neogeo_cmd )
+    saveNeogeoRomList(neogeoRomList)
+    return TRUE
+
+
+#
+# This will return a list of things relevant to NeogeoItem based on
+# which neogeo files we have cached.  It ignores files we don't.
+# Returns: title, filename, and image file for each neogeo_file.
+#
+def getNeogeoItemInfoList(neogeo_files, neogeo_cmd):
+    items = []
+    rm_files = []
+
+    print "Call NEOGEO command : %s" % neogeo_cmd
+    # Only build the cache if it doesn't exis.
+    if not os.path.isfile(config.GAMES_NEOGEO_CACHE):
+        waitmsg = PopupBox(text=_('Generating NEOGEO cache, please wait.'))
+        waitmsg.show()
+        neogeo_ok = updateNeogeoRomList(neogeo_cmd)
+        waitmsg.destroy()
+
+        if not neogeo_ok:
+            return (neogeo_files, [])
+
+    neogeoRomList = getNeogeoRomList()
+    roms = neogeoRomList.getNeogeoRoms()
+
+    for romfile in neogeo_files:
+        key = os.path.splitext(os.path.basename(romfile))[0]
+        if roms.has_key(key):
+            rom = roms[key]
+            info = { 'manufacturer': rom.manufacturer,
+                     'name': rom.name,
+                     'description': rom.description,
+                     'year': rom.year,
+                     'cloneof': rom.cloneof,
+                     'romof': rom.romof }
+            items += [(rom.description, romfile, None, info)]
+            rm_files.append(romfile)
+
+    return (rm_files, items)
+
+
+def getNeogeoItemInfo(neogeo_file):
+    if not os.path.isfile(config.GAMES_NEOGEO_CACHE):
+        return
+    neogeoRomList = getNeogeoRomList()
+    roms = neogeoRomList.getNeogeoRoms()
+    key = os.path.splitext(os.path.basename(neogeo_file))[0]
+    if roms.has_key(key):
+        return roms[key]
+    else:
+        return
diff -r -N -u freevo/games.orig/neogeo_types.py freevo/games/neogeo_types.py
--- freevo/games.orig/neogeo_types.py	1970-01-01 09:00:00.000000000 +0900
+++ freevo/games/neogeo_types.py	2010-08-27 15:26:38.419478550 +0900
@@ -0,0 +1,122 @@
+# -*- coding: iso-8859-1 -*-
+# -----------------------------------------------------------------------
+# neogeo_types.py - Some classes to keep track of information from NEOGEO
+#                 roms.  The cache makes use of this.
+# -----------------------------------------------------------------------
+# $Id: $
+#
+# Notes:
+# Todo:
+#
+# -----------------------------------------------------------------------
+# Freevo - A Home Theater PC framework
+# Copyright (C) 2002 Krister Lagerstrom, et al.
+# Please see the file freevo/Docs/CREDITS for a complete list of authors.
+#
+# This program 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.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MER-
+# CHANTABILITY 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 this program; if not, write to the Free Software Foundation, Inc.,
+# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# -----------------------------------------------------------------------
+
+
+import sys
+import time, os, string
+import config
+
+# The file format version number. It must be updated when incompatible
+# changes are made to the file format.
+TYPES_VERSION = 2
+
+TRUE = 1
+FALSE = 0
+
+
+class NeogeoRom:
+
+    def __init__(self):
+        self.filename = ''
+        self.title = ''
+        self.name = ''
+        self.description = ''
+        self.year = ''
+        self.manufacturer = ''
+        self.cloneof = ''
+        self.romof = ''
+
+
+    def getFilename(self):
+        return self.filename
+
+    def setFilename(self, f):
+        self.filename = f
+
+    def getDirname(self):
+        return self.dirname
+
+    def setDirname(self, d):
+        self.dirname = d
+
+    def getTitle(self):
+        return self.title
+
+    def setTitle(self, t):
+        self.title = t
+
+    def getImageFile(self):
+        return self.imageFile
+
+    def setImageFile(self, i):
+        self.imageFile = i
+
+    def getPartial(self):
+        return self.partial
+
+    def setPartial(self, p):
+        self.partial = p
+
+    def getMatched(self):
+        return self.matched
+
+    def setMatched(self, m):
+        self.matched = m
+
+    def getTrashme(self):
+        return self.trashme
+
+    def setTrashme(self, t):
+        self.trashme = t
+
+
+class NeogeoRomList:
+    # We are using a dictionary that will be keyed on the
+    # absolute filename of the actual rom.
+    neogeoRoms = {}
+
+    def __init__(self):
+        self.TYPES_VERSION = TYPES_VERSION
+
+    def addNeogeoRom(self, rom):
+        if not self.neogeoRoms.has_key(rom.getFilename()):
+            self.neogeoRoms[rom.getFilename()] = rom
+        else:
+            print "We already know about %s." % rom.getFilename()
+
+    def getNeogeoRoms(self):
+        return self.neogeoRoms
+
+    def setNeogeoRoms(self, mr):
+        self.neogeoRoms = mr
+
+    def Sort(self):
+        self.neogeoRoms.Sort()
diff -r -N -u freevo/games.orig/neogeoitem.py freevo/games/neogeoitem.py
--- freevo/games.orig/neogeoitem.py	1970-01-01 09:00:00.000000000 +0900
+++ freevo/games/neogeoitem.py	2010-08-27 15:28:00.996970939 +0900
@@ -0,0 +1,136 @@
+# -*- coding: iso-8859-1 -*-
+# -----------------------------------------------------------------------
+# neogeoitem.py - Item for neogeo objects
+# -----------------------------------------------------------------------
+# $Id: $
+#
+# Notes:
+# Todo:
+#
+# -----------------------------------------------------------------------
+# Freevo - A Home Theater PC framework
+# Copyright (C) 2002 Krister Lagerstrom, et al.
+# Please see the file freevo/Docs/CREDITS for a complete list of authors.
+#
+# This program 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.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MER-
+# CHANTABILITY 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 this program; if not, write to the Free Software Foundation, Inc.,
+# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# -----------------------------------------------------------------------
+
+
+import os
+import re
+
+import config
+import util
+import game
+import rc
+
+TRUE  = 1
+FALSE = 0
+
+import menu
+import event as em
+import time
+import copy
+import neogeo_cache
+
+from item import Item
+
+
+class NeogeoItem(Item):
+    def __init__(self, title, file, image=None, cmd=None, args=None, imgpath=None, parent=None, info=None):
+        Item.__init__(self, parent)
+        self.type  = 'neogeo'            # fix value
+        self.set_url(file, info=True)
+        self.image = image
+        self.name  = title
+        self.parent = parent
+
+        # find image for this file
+        if image == None:
+            shot = imgpath + '/' + \
+                os.path.splitext(os.path.basename(file))[0] + ".png"
+            if os.path.isfile(shot):
+                self.image = shot
+            elif os.path.isfile(os.path.splitext(file)[0] + ".png"):
+                self.image = os.path.splitext(file)[0] + ".png"
+
+        command = ['--prio=%s' % config.GAMES_NICE, cmd]
+        command.extend(args.split())
+
+        # Some files needs special arguments to neogeo, they can be
+        # put in a <file>.neogeo options file. The <file>
+        # includes the suffix (.zip, etc)!
+        # The arguments in the options file are added at the end of the
+        # regular neogeo arguments.
+        if os.path.isfile(file + '.neogeo'):
+            addargs = open(filename + '.neogeo').read().strip()
+            command.extend(addargs.split())
+            _debug_('Read additional options = "%s"' % addargs)
+
+        command.append(file)
+
+        self.command = command
+
+        self.game_player = game.get_singleton()
+        if info:
+            self.info = { 'description' : '%s - %s - %s' % (info['description'],info['manufacturer'],info['year']) }
+        else:
+            self.info = { 'description' : 'No ROM information' }
+
+
+    def sort(self, mode=None):
+        """
+        Returns the string how to sort this item
+        """
+        return self.name
+
+    # ------------------------------------------------------------------------
+    # actions:
+
+
+    def actions(self):
+        return [ ( self.play, 'Play' ) ]
+
+
+    def play(self, arg=None, menuw=None):
+        _debug_('%s.play(arg=%r, menuw=%r)' % (self.__module__, arg, menuw))
+        self.parent.current_item = self
+
+        if not self.menuw:
+            self.menuw = menuw
+
+        if self.menuw.visible:
+            self.menuw.hide()
+
+        _debug_("Playing:  %s" % self.filename)
+
+        self.game_player.play(self, menuw)
+
+
+    def stop(self, menuw=None):
+        self.game_player.stop()
+
+
+    def eventhandler(self, event, menuw=None):
+
+        if event == em.STOP:
+            self.stop()
+            rc.app(None)
+            if not menuw == None:
+                menuw.refresh(reload=1)
+
+        # give the event to the next eventhandler in the list
+        return Item.eventhandler(self, event, menuw)
------------------------------------------------------------------------------
Sell apps to millions through the Intel(R) Atom(Tm) Developer Program
Be part of this innovative community and reach millions of netbook users 
worldwide. Take advantage of special opportunities to increase revenue and 
speed time-to-market. Join now, and jumpstart your future.
http://p.sf.net/sfu/intel-atom-d2d
_______________________________________________
Freevo-users mailing list
Freevo-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/freevo-users

Reply via email to