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

set NAME	{SDL Mamex}
set VERSION	1.4.1
set MAMEDIR	/usr/local/share/xmame
set ROMDIRS	$MAMEDIR/roms
set RCFILE	/root/.sdlmamexrc
set BINARIES	{sdlmame}
set DEFAULTS	{-skip_gameinfo -cheat}
 
# SDLMAMEX - M.A.M.E. front end - hacked by stevenaaus, http://tkgames.sf.net
#
# About
#
#   This version of mamex is written for sdlmame. It's tested with sdlmame-0.127
#
# Install
#
#   At the least, you'll have to find a recent sdlmame binary or source. If
#   compiling, edit the makefile, "make" , and copy some roms to $MAMEDIR/roms.
#   Edit the BINARIES line above to point to your sdlmame binary(s).  To
#   enable cheats and all the other extra stuff, find and copy data files to
#   $MAMEDIR.
#
# 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
#   "sdlmame -showusage | less" to see a full list of sdlmame options and add
#   extra options in the entry at the bottom.
#
# Notes
#
#   For me, opengl uses much less cpu.
#   I can't get scaling working... but alt-tab switches between fullscreen,
#   and you can resize windows too.
#
# Changes to 1.4.1 (??):
#
#   Nothing really ;> Disabled the "scale" scale widget, as it does nothing.
#
# Changes to 1.4 (??):
#
#   Enable multiple binaries. Fork project into mamex
#   and sdlmamex as they are too f-ing different.
#
# 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	. "$NAME $VERSION"
wm iconname	. "$NAME $VERSION"

cd  $MAMEDIR

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

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
  set mamelist [lsort [lrange [split $gamelist "\n"] 1 end]]

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

  # find available game roms.

  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 NAME nosound fullscreen opengl volume scale allGames rotate mouse 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 -nosound"
    } else {
      set options "$options -sound"
    }
    if !{$fullscreen}	{set options "$options -window -nomax"}
    # scale doesn't work, but windows are resizable ! -keepaspect doesnt work :<
    if {$opengl}	{set options "$options -video opengl"}
    if {$rotate}	{set options "$options -ror"}
    if {$mouse}		{set options "$options -mouse"}
    # if {$scale}		{set options "$options -scale $scale"}

    set options "$options -scalemode $effect"

    puts "$NAME now executing:\n\n$binary $options $game\n"
    eval "catch { 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 opengl volume scale rotate mouse 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 opengl volume scale rotate mouse 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 async yv12 yuy2 yv12x2 yuy2x2}

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 "Software Effect"
eval \
tk_optionMenu	.top.left.effect.menu effect $effect_list

### gamelist widget ###

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

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.opengl -text OpenGL -variable opengl -anchor w 
checkbutton	.top.right.rotate -text "Rotate" -variable rotate -anchor w 
checkbutton	.top.right.mouse -text "Mouse" -variable mouse -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  } -state disabled
scale 		.top.right.scale.value -label "" -from 1 -to 3 -length 100 \
		-orient horizontal -command setScale -showvalue 1 -state disabled
.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.opengl -side top -anchor w -padx 20 -pady 3
pack .top.right.nosound -side top -anchor w -padx 20 -pady 3
pack .top.right.mouse -side top -anchor w -padx 20 -pady 3
pack .top.right.rotate -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 .]
