Author Topic: proc-GenericLauncher -- frontend for launching PinMAME and pyprocgame  (Read 7239 times)

tomlogic

  • Wizard
  • *****
  • Posts: 113
    • View Profile
    • PinMAME for P-ROC/Linux
There hasn't been recent activity on the previous thread discussing the collaborative effort known as proc-GenericLauncher, so I've decided to start a new thread to discuss some recent work I've done on the launcher, and to hopefully provide a home for discussion of this specific launcher code, instead of App Launchers in general.

First off, credit to where it's due.  Based on comments in the code when I started working on it, this software is the work of many hands including: Michael Ocean (mocean), Mark Sunnucks (Snux), Jim (myPinballs), and Koen (DutchPinball).  Since I don't have a lot of Python experience, it helped greatly to have their work as a starting point.

From the updated README file:
Quote
This is a Python-based front-end game launcher for a P-ROC enabled pinball machine.  Using it shouldn't require any modifications to GameLauncher.py, just the creation of a Loader.yaml file based on one of the provided examples.


I've just pushed some changes out to my fork of Michael's repo.  Those changes include the following:

  • Use of a title screen with the name of the machine, and instructions to use the flippers to select a game.  This allows for 4 lines of information on each possible selection.
  • Support for multiple configurations (e.g., 3-ball, 5-ball, tournament mode) for each PinMAME ROM.  I accomplish this by swapping in alternate NVRAM files (*.nv) when launching PinMAME.
  • Display of the current Grand Champion for each PinMAME game/configuration.  It's necessary to dig through a hex dump of an NVRAM file to find the proper offsets for the initials and score stored in binary-coded decimal (BCD).  This location is unique for each ROM version.
  • Only enable flippers for System-11 games, which rely on the EOS switches to detect flipper button presses.
  • Flash the start button lamp (if present).

I wanted to use a larger font for the game name on the title screen, but whenever I called dmd.TextLayer() with one of the larger fonts, it wouldn't show up.  Maybe someone with pyprocgame experience can help me fix that.

If you'd like help figuring out GC settings for a given ROM, let me know.  If you can send me a .nv file along with the initials and GC score it should contain, I can get back to you with the offsets to use.  For reference, here's what the scores look like in dm_lx4.nv (where Grand Champion is TBC with a score of 4,185,195,510):

Code: [Select]
Checksum 36 bytes is good (0xF663): HS1 to HS4
1c61: 54 42 43 00 32 82 19 79  50 54 42 43 00 25 81 32   TBC.2..y PTBC.%.2
1c71: 75 60 54 42 43 00 25 79  73 61 90 54 42 43 00 23   u`TBC.%y sa.TBC.#
1c81: 13 48 15 60 f6 63                                  .H.`.c
Checksum 9 bytes is good (0xFDE2): GC
1c87: 54 42 43 00 41 85 19 55  10 fd e2                  TBC.A..U ...

I'd appreciate hearing back from anyone who gets this to work under Windows (so I can update the README), along with feedback from others who try it out.  I'm also open to exploring ways to load the GC for Python-based games (like the name of the YAML and the necessary key to extract the score?).
« Last Edit: August 17, 2014, 03:55:48 PM by tomlogic »

Snux

  • Wizard
  • *****
  • Posts: 779
  • Mark Sunnucks
    • View Profile
Re: proc-GenericLauncher -- frontend for launching PinMAME and pyprocgame
« Reply #1 on: August 18, 2014, 03:10:17 AM »
As for the font issue, a number of the ones that come with pyprocgame were only put together to be used for the score displays, meaning they only contain numbers.  If you try to display text you'll just get blank.

There are some out here on the wiki which you could use/try :

http://pinballcontrollers.com/wiki/Fonts

Nice work though.  If nobody else gets to it, I'll 'window-ise' it whenever I finally get my F14 playfield and get a real machine working again...
F14 Tomcat - Second Sortie

MOcean

  • P3 Developers
  • *
  • Posts: 822
  • Michael Ocean
    • View Profile
Re: proc-GenericLauncher -- frontend for launching PinMAME and pyprocgame
« Reply #2 on: August 18, 2014, 09:32:09 AM »
This is awesome as always; thanks!

I'll try this on windows next week when I'm back on campus. We moved to windows for pinmame at Mark's urging since it has some tweaks we needed; there were quite a lot of changes I made to my Linux pinmame to make T2 work happily (pre-fliptronics issues and disabling the cannon in the t2.c simulator file), and I don't recall what that last issue was, but it was resolved when I switched to Mark's windows build, which (as you know) was a more recent version of pinmame too.

I'm eager to try going back to Linux too, now that you have a more recent version of pinmame working. I experienced an average uptime of about 36-48 hours on the old Linux version before it needed a reset; on windows we've had up times of several months before needing to exit to run student code, reboot the machine for other reasons, etc.

Anyway, thanks again for taking the auto-launcher torch. It's an important piece of the puzzle that often gets overlooked.  As I recall the command line options are different between the Linux version and the windows version (different flag for the same option) hopefully they are the same now that the versions are the same.

Anyway, I'll report back when I've tried it, assuming someone doesn't beat me to it :)

tomlogic

  • Wizard
  • *****
  • Posts: 113
    • View Profile
    • PinMAME for P-ROC/Linux
Re: proc-GenericLauncher -- frontend for launching PinMAME and pyprocgame
« Reply #3 on: August 18, 2014, 07:36:51 PM »
Michael,

In the version of the launcher I'm using, I actually use a shell script (runpinmame) to start PinMAME, instead of trying to get all of the command-line options set up properly in the launcher itself.

I'm quite pleased with how well the implementation went for using different NVRAM files on the machine.  It's allowing me to have casual games with friends (3-ball, EBs enabled), let novices stand a better chance of getting to Demolition Time (5-ball, EBs enabled) and to practice for tournaments (3-ball, no EBs).  Being able to show the GC score in the launcher is just icing on the cake.

The biggest missing piece for me now is that I don't have Demolition Man on Steroids!  I got to play it at Cal Extreme, and look forward to playing it again at Pinball Expo (along with meeting as many other P-ROC developers as I can).

-Tom

PS, here's a video demonstrating the menu on my Demolition Man:

<a href="http:////www.youtube.com/v/QikI8OQ_Nfk" target="_blank" class="new_win">http:////www.youtube.com/v/QikI8OQ_Nfk</a>

tomlogic

  • Wizard
  • *****
  • Posts: 113
    • View Profile
    • PinMAME for P-ROC/Linux
Re: proc-GenericLauncher -- frontend for launching PinMAME and pyprocgame
« Reply #4 on: October 28, 2014, 02:47:32 AM »
I'm finally getting around to integrating a Python-based game (DMoS, yeah!) into the launcher on my machine, but it looks like proc-GenericLauncher has a sqlite3 database locked that DMoS is trying to use.

Code: [Select]
Traceback (most recent call last):
  File "starter_dm.py", line 36, in <module>
    font_tiny7 = dmd.Font(fonts_path+"04B-03-7px.dmd")
  File "/usr/local/lib/python2.7/dist-packages/pyprocgame-1.0.1-py2.7.egg/procgame/dmd/font.py", line 40, in __init__
    self.load(filename)
  File "/usr/local/lib/python2.7/dist-packages/pyprocgame-1.0.1-py2.7.egg/procgame/dmd/font.py", line 50, in load
    self.__anim.load(filename)
  File "/usr/local/lib/python2.7/dist-packages/pyprocgame-1.0.1-py2.7.egg/procgame/dmd/animation.py", line 162, in load
    animation_cache = AnimationCacheManager.shared_manager()
  File "/usr/local/lib/python2.7/dist-packages/pyprocgame-1.0.1-py2.7.egg/procgame/dmd/animation.py", line 43, in shared_manager
    shared_cache_manager = AnimationCacheManager(path)
  File "/usr/local/lib/python2.7/dist-packages/pyprocgame-1.0.1-py2.7.egg/procgame/dmd/animation.py", line 29, in __init__
    self.load()
  File "/usr/local/lib/python2.7/dist-packages/pyprocgame-1.0.1-py2.7.egg/procgame/dmd/animation.py", line 57, in load
    self.conn.execute(CREATE_VERSION_TABLE)
sqlite3.OperationalError: database is locked

Any thoughts on how to workaround that?  Also, how can I go about adding a method to the Python-based game to exit when both flipper buttons and the start button are held down?

MOcean

  • P3 Developers
  • *
  • Posts: 822
  • Michael Ocean
    • View Profile
Re: proc-GenericLauncher -- frontend for launching PinMAME and pyprocgame
« Reply #5 on: October 28, 2014, 07:48:33 AM »
The SQLite database is used by the built-in animation caching. If you disable animation caching then it won't use the database. For a quick fix disable the allow_cache in the pyprocgame/dmd.py Animation.load() method.

I use a different caching mechanism so I have that commented out in mine.

Rosh

  • P3 Developers
  • *
  • Posts: 667
  • Josh Kugler
    • View Profile
Re: proc-GenericLauncher -- frontend for launching PinMAME and pyprocgame
« Reply #6 on: October 28, 2014, 10:08:44 AM »
Quote
Also, how can I go about adding a method to the Python-based game to exit when both flipper buttons and the start button are held down?


sys.exit() will do what you want . . .

https://docs.python.org/2/library/sys.html

in some mode in your mode queue you need to look for that switch combination and then issue that exit. So, for example on a press of the start button check if both flippers are currently closed, and if they are, then issue the exit command.

tomlogic

  • Wizard
  • *****
  • Posts: 113
    • View Profile
    • PinMAME for P-ROC/Linux
Re: proc-GenericLauncher -- frontend for launching PinMAME and pyprocgame
« Reply #7 on: October 30, 2014, 01:46:09 PM »
OK, so here's what I added to the top of two separate sw_startButton_active functions so it would return to the menu:

Code: [Select]
def sw_startButton_active(self, sw):
if self.game.switches.flipperLwL.is_closed() and self.game.switches.flipperLwR.is_closed():
self.game.end_run_loop()
return

I'm working in someone else's code and I'm not yet familiar with how stacked modes and mode priority works.  I would expect that I could have a single mode, active at all times as the top priority that just contains the sw_startButton_active function and prevents the event from getting to the other modes.

As for the database locking, I modified Font.load() so it wouldn't use the cache and therefore my launcher wouldn't invoke the cache from just using fonts.  I just modified this line:

Code: [Select]
self.__anim.load(filename, allow_cache=False)

I suppose adding an allow_cache parameter to Font.load(), possibly defaulting to False, is the proper course of action here.  Even better would be a method call I could make at the start of a program using pyprocgame (in this case, the launcher) to instruct it not to use animation caching.
« Last Edit: November 08, 2014, 01:53:46 PM by tomlogic »

Rosh

  • P3 Developers
  • *
  • Posts: 667
  • Josh Kugler
    • View Profile
Re: proc-GenericLauncher -- frontend for launching PinMAME and pyprocgame
« Reply #8 on: October 30, 2014, 02:14:45 PM »
I'm assuming end_run_loop is some method you have created to exit out.

In theory the switch events would continue down the mode queue, since you are not doing return game.SwitchStop to prevent that, but since you are ending the run loop before you do the return it would not matter.




tomlogic

  • Wizard
  • *****
  • Posts: 113
    • View Profile
    • PinMAME for P-ROC/Linux
Re: proc-GenericLauncher -- frontend for launching PinMAME and pyprocgame
« Reply #9 on: October 30, 2014, 02:24:33 PM »
Actually, end_run_loop is a method of the GameController class:

Code: [Select]
def end_run_loop(self):
"""Called by the programmer when he wants the run_loop to end"""
self.done = True

It looks like the proper method to do a clean shutdown of the game.  It doesn't end right away, but will cause the GameController to return from run_loop on the next pass.

tomlogic

  • Wizard
  • *****
  • Posts: 113
    • View Profile
    • PinMAME for P-ROC/Linux
Re: proc-GenericLauncher -- frontend for launching PinMAME and pyprocgame
« Reply #10 on: November 08, 2014, 01:57:50 PM »
Here's what I finally ended up with.  I don't know about mode priorities yet, so I guess it's possible for another mode to block the start button message from getting to this mode.

Code: [Select]
class ExitGameMode(game.Mode):
""" Simple mode to exit the game if the user holds both flipper buttons and start
(and the game has that feature enabled)."""
def __init__(self, game):
super(ExitGameMode, self).__init__(game, 1)

def sw_startButton_active(self, sw):
if self.game.user_settings['Machine']['Exit on flippers + start']:
if self.game.switches.flipperLwL.is_closed() and self.game.switches.flipperLwR.is_closed():
self.game.end_run_loop()
return procgame.game.SwitchStop
return procgame.game.SwitchContinue

In my Game class, I just load that mode before any others:
Code: [Select]
self.modes.add(ExitGameMode(self))
And I added the following section to settings_template.yaml:

Code: [Select]
  'Exit on flippers + start':
    # enable if starting game from proc-GenericLauncher or another menu
    options: [no,yes]
    default: no

Frank Gigliotti

  • Wizard
  • *****
  • Posts: 174
  • Wrath of Olympus Dev Team
    • View Profile
Re: proc-GenericLauncher -- frontend for launching PinMAME and pyprocgame
« Reply #11 on: November 25, 2014, 10:08:24 AM »
I just wanted to thank everyone for the loader code. I was able to use about 30 lines of code from it and added another 100 or so to pythonize it so I could add it as one of my methods on our game. I didn't need the loop or any of the p-roc stuff, but the use of the loader yaml for choices was a really good idea.

So for others that perhaps would like to add a menu to their custom game and won't be using pinmame, this is possible with the loader.


Snux

  • Wizard
  • *****
  • Posts: 779
  • Mark Sunnucks
    • View Profile
Re: proc-GenericLauncher -- frontend for launching PinMAME and pyprocgame
« Reply #12 on: February 02, 2015, 03:13:31 PM »
Wow, nice work Tom.   I know you credited a bunch of other folks, but this really isn't recognisable from the earlier versions.

With the correct paths etc in the loader.yaml file, this launcher works just fine under Windows for both pinmame and python.  For the pinmame section, I used the extra_args to get the additional options in and it works a treat.

I only found one bug.  My machine being a Sys11 is one of those that needs the flippers enabling when the launcher runs.  By default there was nothing to switch it on.  I just changed the enable=False to enable=True in the reset() and that fixed it.  Everything else worked fine.  I lifted the ExitGame mode too which you put into the python code, adding the setting to the game template and that works well too.

Seriously impressed.  One question - how did you find the spot in the nvram file containing the score?  In the Sys11 files it'll be different.

Anyway for reference here is my loader.yaml file.  I've got some more ROM versions to put in, and I'll also add some game definitions so it'll copy the NVRAM files around.

Code: [Select]
# Configuration file for the generic GameLaucncher for P-ROC

# Customize this file to your own needs --note that if your game
# is pre-fliptronic (i.e., as a flipper relay) then you need to
# specify a flipperEnable coil in your machine_config_file so
# the launcher can enable your flippers for game selection. 
#
# The launcher uses switches:
#     - flipperLwR
#     - flipperLwL
#     - startButton
#   to navigate the game list.
#
# most options should be obvious.
# Note that games that run via Python require a gamefile and gamepath
# whereas pinmame ROMs (Williams/FreeWPC) should have a ROM specified
# ROMs should be placed in the pinmame path.
#####################################################################

# Path to YAML file describing the machine.  Used by GameLauncher to
# identify the flipperLwR, flipperLwL and startButton switches, and the
# startButton lamp (if it exists).
machine_config_file: 'C:\P-ROC\games\F14SecondSortie\config\f14.yaml'

# Title and instructions to display when launcher starts
title: 'F-14 TOMCAT'
instructions_line_1: 'Choose game with flippers'
instructions_line_2: 'then press START to select.'

# Configuration for PinMAME-based games
pinmame:
    path: 'c:\pinmame'
    cmd: '.\pinmamep.exe'
   
    # Location of NVRAM files used to store high scores and settings
    # for a given PinMAME ROM.  Also used to support multiple game
    # configurations by having multiple .nv files.  Note that it should
    # end with a path separator ('/' on Linux, '\' on Windows).
    nvram: 'c:\pinmame\nvram\'

    # Extra arguments to pass to pinmame
    extra_args: -alpha_on_dmd -skip_disclaimer -skip_gameinfo

# Configuration for Python-based games
python:
    cmdpath: 'c:\python26\python'

# A list of games to run on this cabinet.  Typically includes one or more
# PinMAME ROMs for the original "stock" firmware, along with Python-based
# games built with pyprocgame.
games:
    -
      # Description for first two lines of DMD page for this Python-based game.
      line1: 'Second Sortie'
      line2: '(work in progress)'
     
      # Game directory and Python file to launch for this custom game
      gamepath: 'C:\P-ROC\games\F14SecondSortie\'
      gamefile: 'f14.py'
     
      # Details of where the Grand Champion score is stored in a YAML file
      # used by the game.  Use dot notation to specify the location of initials
      # and score.
      # Used to display the current GC on line 4 of the DMD page for a game
      # choice.
      gc:
        yaml: 'config/game_data.yaml'
        initials: 'ClassicHighScoreData.0.inits'
        score: 'ClassicHighScoreData.0.score'
     
    -
      # Description for first two lines of DMD page for this game choice.
      # GameLauncher shows the configuration description (see below) as line
      # three, and the current Grand Champion score for that configuration.
      line1: 'F14'
      line2: '(WMS, production P5 ROM)'
     
      # ROM version to use for this game choice
      ROM: 'f14_p5'
« Last Edit: February 02, 2015, 03:24:52 PM by Snux »
F14 Tomcat - Second Sortie

tomlogic

  • Wizard
  • *****
  • Posts: 113
    • View Profile
    • PinMAME for P-ROC/Linux
Re: proc-GenericLauncher -- frontend for launching PinMAME and pyprocgame
« Reply #13 on: February 02, 2015, 03:50:28 PM »
Wow, nice work Tom.   I know you credited a bunch of other folks, but this really isn't recognisable from the earlier versions.

With the correct paths etc in the loader.yaml file, this launcher works just fine under Windows for both pinmame and python.  For the pinmame section, I used the extra_args to get the additional options in and it works a treat.

I only found one bug.  My machine being a Sys11 is one of those that needs the flippers enabling when the launcher runs.  By default there was nothing to switch it on.  I just changed the enable=False to enable=True in the reset() and that fixed it.  Everything else worked fine.  I lifted the ExitGame mode too which you put into the python code, adding the setting to the game template and that works well too.

So you're saying I should update the launcher to set 'enable=True' if the machine type is 'sys11'?

Quote
Seriously impressed.  One question - how did you find the spot in the nvram file containing the score?  In the Sys11 files it'll be different.

OK, for each ROM version high scores will appear in a different location.  I used a hex dump tool to search the files for the high scores.  I recommend writing down the GC score and initials.  Then look through the text area of the hex dump for the initials, and you should see the scores to either side of it in the hex dump as BCD (binary coded decimal).  Make note of the offsets and place them in the configuration file.

See my post from August 17th with an example of how the scores looked on one of my games.

-Tom

Snux

  • Wizard
  • *****
  • Posts: 779
  • Mark Sunnucks
    • View Profile
Re: proc-GenericLauncher -- frontend for launching PinMAME and pyprocgame
« Reply #14 on: February 03, 2015, 01:29:30 AM »

So you're saying I should update the launcher to set 'enable=True' if the machine type is 'sys11'?


Actually there isn't a sys11 machine type, with the interface board it appears to the P-ROC as a WPC machine, so there was no real benefit in adding a new type.  I took a closer look at the launcher code.  What it's missing is a call to get the flippers working first time in.  After a game has been run and quit and the launcher wakes up again, it looks like the call to restart_proc would enable the flippers as required.  It's just missing that initial enable.
F14 Tomcat - Second Sortie