#!/bin/sh
# the next line restarts using tclsh \
exec wish "$0" "$@"

set VERSION	1.4.1
set MAMEDIR	/usr/local/share/xmame
set ROMDIRS	/usr/local/share/xmame/roms
set RCFILE	/root/.mamexrc
set BINARIES	{xmame.x11-0.96 xmame.x11-0.106 xmame.SDL-0.96 xmame.SDL-0.106 xmame-knoppix}
set DEFAULTS	{-nocursor -skip_gameinfo}; # hmmm skip_disclaimer is for 0.96 but not 0.106
 
# MAMEX - M.A.M.E. front end - hacked by stevenaaus, http://tkgames.sf.net
#
#   This version of mamex is written for xmame-0.96 or xmame-0.106, and it's
#   now working nice ;>. Find some roms and enjoy this awesome project.
#
# Install
#
#   At the least, you'll have to find the xmame 0-96 or 0.106 source code, edit
#   the makefile (to enable gcc options and choose either x11 or SDL), "make
#   install", and copy some roms to /usr/local/share/xmame/roms.
#   Edit the BINARIES line *above* to point to your xmame binaries (eg
#   xmame.x11, xmame.SDL). For me, SDL has nicer fullscreen modes but no XV
#   acceleration.  To enable cheats and all the other extra stuff, find and
#   copy data files to /usr/local/share/xmame or your install directory.
#
# Play
#
#   Once the game is running.  you'll have to insert coins by pressing "5",
#   then start the game by pressing "1". By default the cursor keys , control
#   and alt are used to emulate the joystick.  Some games even use the mouse.
#   The Mame option menu is controlled by "tab", and sound volume by "~" Type
#   "xmame.x11 -? | less" to see a full list of xmame options and add extra
#   options in the entry at the bottom. Xmame SDL binaries can toggle
#   fullscreen mode with "alt-pagedown"
#
# Notes
#
#   The xmame SDL builds i've tested have some quirks. They don't support Xv
#   acceleration, and ignore the "-audiodevice /dev/null" option i use for
#   muting.  To get around this, i have to use the oss sound plugin with
#   "-dsp-plugin oss" for muting.
#
# Bugs 
#
#   SDL xmame maximises all other windows somehow!
#
# Changes to 1.4.x 
#
#   (maybe) Stop the zombie processes left behind by the '&'
#
# Changes to 1.4.1 (29/09/09):
#
#   Tcl code optimisations
#   Enable multiple binaries from xmame.x11, xmame.SDL, rearranging the
#   tk_optionMenu widgets. Fork project into mamex and sdlmamex. Add
#   -skip_gameinfo default.
#
# Changes to 1.3 (31/08/08):
#
# * new mute, xvideo, title, volume and video effect widgets
# * added persistent volume and scale sliders
# * reorganised the widget hierarchy making everything resize nicely
# * added some documentation.
#
# 04/08/98: v1.1 enhanced by Takashi MATSUDA <matsu@arch.comp.kyutech.ac.jp>
#
# 05/09/97: chris Sharp <sharpc@hursley.ibm.com>
#
# Known bugs:
#    Zombie process remain when xmame finished ?
#    This is a known issue with tcl/tk when compiled with threads

wm title	. "Mamex $VERSION"
wm iconname	. "Mamex $VERSION"

cd  $MAMEDIR

set fullscreen	0
set xv		0
set volume	-16
set nosound	0
set scale	1
set rotate	0
set cheat	0
set more_options {}
set show_type	{Available Games}
set effect	none
set binary	[lindex $BINARIES 0]
set lastgame	0

# this is broken at the moment.
#		 option		xmame 		sdlmame
set OPTIONS {	{defaults	{-nocursor -fullscreen}	{}}
		{accel		{-video-mode 1}		{-video opengl}}
		{window		-nofullscreen		-window	}
}


proc setListItems {type dummy opt} {
  global allGames gamesAvailable
  upvar $type show_type

  .top.left.games.list delete 0 end
  foreach title [lsort [array names allGames]] {
    if {[string compare $show_type "All Games"] == 0 ||
        [lsearch $gamesAvailable $allGames($title)] >= 0} {
      .top.left.games.list insert end $title 
    }
  }
}

proc findSupportedGames {} {

  global ROMDIRS binary allGames gamesAvailable

  catch { exec $binary -listfull 2>/dev/null } gamelist

  # hmmm: "-sortname" option dumps core in xmame.x11-0.106,
  # - and doesn't exist in sdlmame - but would do away with lsort.

  set mamelist [lsort [lrange [split $gamelist "\n"] 2 end-3]]

  foreach i $mamelist {
      foreach {index title} $i {
        set allGames($title) "$index"
      }
  }

  set gamesAvailable {}
  foreach dir $ROMDIRS {
    foreach f [ glob -nocomplain $dir/*.zip ] {
      lappend gamesAvailable [lindex [split [file tail $f] "."] 0]
    }
  }
}

proc runMame {} {
  global BINARIES binary DEFAULTS nosound fullscreen xv volume scale allGames rotate cheat lastgame effect_list effect

  set game {}

  if [catch {set game $allGames([selection get])}] {

    bell

  } else {

    set options "$DEFAULTS -volume $volume [.bottom.extraoptions get]"
    set lastgame [.top.left.games.list curselection]

    if {$nosound}	{set options "$options -dsp-plugin oss -audiodevice /dev/null"}
    if {$fullscreen}	{set options "$options -fullscreen"}
    if {$xv}		{set options "$options -video-mode 1"}
    if {$rotate}	{set options "$options -ror"}
    if {$cheat}		{set options "$options -cheat"}
    if {$scale}		{set options "$options -scale $scale"}

    set effect_number [lsearch $effect_list $effect]
    if {$effect_number == -1} {
	puts stderr "Mamex: illegal effect_number"
    } else {
	set options "$options -effect $effect_number"
    }

    puts "Mamex now executing: $binary $options $game"
    catch {puts "process id [eval exec $binary $options $game &]"}
  }
}

proc setVolume value {
  global volume
  set volume [.top.right.volume.value get ]
}

proc setScale value {
  global scale
  set scale [.top.right.scale.value get ]
}

proc quitMamex {} {

  global RCFILE nosound fullscreen xv volume scale rotate cheat show_type binary effect lastgame

  if { ! [ catch { set rcfile [ open $RCFILE w ] } ] } {

    set more_options [.bottom.extraoptions get]
    # regsub -all {"} [.bottom.extraoptions get] {} result
    # puts $rcfile "set more_options \"$result\""

    foreach i {nosound fullscreen xv volume scale rotate cheat show_type binary effect lastgame more_options} {
      puts $rcfile "set $i \{[set $i]\}"
    }

    close $rcfile
  }
  exit 0
}

image create photo dkong -data {
[encoded data, 6954 characters]
DOIQDHhQCbWAtcLAuWlcycgxNQohDvGcdAEBADs=}

### main ###

catch { source $RCFILE }

set effect_list \
	{none {smooth scaling} {low quality filter} \
	{high quality filter} {6-tap filter} {light scanlines} \
	{rgb scanlines} {deluxe scanlines} {black scanlines}}

findSupportedGames

# create widgets

frame		.top	;# listbox and scroll bar on left, other widgets on right
frame		.bottom ;# options menu

frame 		.top.left
frame		.top.left.games

tk_optionMenu 	.top.left.showmenu show_type "Available Games" "All Games"

frame		.top.left.binary
label		.top.left.binary.label -text "Binary"
eval \
tk_optionMenu	.top.left.binary.menu binary $BINARIES

frame		.top.left.effect
label		.top.left.effect.label -text "Video Effect"
eval \
tk_optionMenu	.top.left.effect.menu effect $effect_list

### gamelist widget ###

scrollbar 	.top.left.games.scroll -command ".top.left.games.list yview" \
		-relief ridge

listbox 	.top.left.games.list -borderwidth 2 -selectmode single \
		-yscrollcommand ".top.left.games.scroll set" -relief groove

# Occasional blank line at bottom of listbox is related to widget size and font

bind		.top.left.games.list <Double-1> "runMame" 
trace variable	show_type w setListItems
setListItems	show_type {} w

# highlight the last game played

.top.left.games.list	selection set $lastgame
.top.left.games.list	yview $lastgame

frame 		.top.right -width 300
frame		.top.right.title
label		.top.right.title.dkong -image dkong
label 		.top.right.title.1 -text {M . A . M . E} -font {{luxi serif} -20 bold} -foreground red3
label 		.top.right.title.2 -text "Arcade Emulator" -font {Arial -17}
checkbutton	.top.right.nosound -text Mute -variable nosound -anchor w 
checkbutton	.top.right.fullscreen -text Fullscreen -variable fullscreen -anchor w 
checkbutton	.top.right.xv -text {Xv Video Acceleration} -variable xv -anchor w 
checkbutton	.top.right.rotate -text "Rotate" -variable rotate -anchor w 
checkbutton	.top.right.cheats -text "Cheats" -variable cheat -anchor w 

frame		.top.right.volume
label		.top.right.volume.label -text Volume
scale 		.top.right.volume.value -label "" -from -32 -to 0 -length 100 \
		-orient horizontal -command setVolume -showvalue 1
.top.right.volume.value set $volume

frame		.top.right.scale
label		.top.right.scale.label -text {Scale  }
scale 		.top.right.scale.value -label "" -from 1 -to 3 -length 100 \
		-orient horizontal -command setScale -showvalue 1
.top.right.scale.value set $scale

frame		.top.right.buttons -border 2
button		.top.right.buttons.play -text "Play!!" -command "runMame" -width 6
focus		.top.right.buttons.play
button		.top.right.buttons.exit -text "Quit" -command quitMamex -width 6
bind 	.	<Control-q> quitMamex

label		.bottom.label -text "Other Options:"
entry		.bottom.extraoptions

.bottom.extraoptions insert 0 $more_options
bind .bottom.extraoptions <Return> ".top.right.buttons.play invoke"

pack .top -fill both -expand 1

pack .top.right -side right -fill both -expand 1
pack .top.right.title -side top -pady 10
pack .top.right.title.1 -side top
pack .top.right.title.2 -side top -pady 5
pack .top.right.title.dkong -side top -pady 5

pack .top.right.fullscreen -side top -anchor w -padx 20 -pady 3
pack .top.right.xv -side top -anchor w -padx 20 -pady 3
pack .top.right.nosound -side top -anchor w -padx 20 -pady 3
pack .top.right.rotate -side top -anchor w -padx 20 -pady 3
pack .top.right.cheats -side top -anchor w -padx 20 -pady 3

pack .top.right.volume -padx 5
pack .top.right.volume.label -side left -padx 5
pack .top.right.volume.value -side right -padx 5

pack .top.right.scale -padx 5
pack .top.right.scale.label -side left -padx 5
pack .top.right.scale.value -side right -padx 5

pack [label .top.right.space2] -side top ;# spacer

# pack [label .top.right.space3] -side top ;# spacer

pack .top.right.buttons -side bottom -fill x -padx 5 -pady 5
pack .top.right.buttons.play -side left -padx 5 -pady 2
pack .top.right.buttons.exit -side right -padx 5 -pady 2

pack .top.left -side left -fill both -expand 1 -padx 5 -pady 5
pack .top.left.games -side top -fill both -expand 1 -pady 5
pack .top.left.games.list -side left -fill both -expand 1 
pack .top.left.games.scroll -side right -fill y -padx 3

pack .top.left.showmenu -side top -fill x -padx 5 -pady 2

pack .top.left.effect -side top -fill x -padx 5 -pady 5
pack .top.left.effect.label -side top -padx 3 -anchor center
pack .top.left.effect.menu -side top -fill x

pack .top.left.binary -side top -fill x -padx 5 -pady 5
pack .top.left.binary.label -side top -padx 3 -anchor center
pack .top.left.binary.menu -side top -fill x

pack .bottom -side bottom -fill x -pady 3 -anchor n
pack .bottom.label -side left -padx 2 -anchor e
pack .bottom.extraoptions -side right -fill x -expand 1 -padx 3 -anchor w -ipady 2

update

wm minsize . [winfo width .] [winfo height .]
