1#!/usr/local/bin/python3.8 2# -*- coding: utf-8 -*- 3 4# Copyright (C) 2002 Martin Willemoes Hansen <mwh@sysrq.dk> 5# Copyright (C) 2019 Dawid Gan <deveee@gmail.com> 6# 7# Jump 'n Bump is free software; you can redistribute it and/or modify 8# it under the terms of the GNU General Public License as published by 9# the Free Software Foundation; either version 2 of the License, or 10# (at your option) any later version. 11# 12# Jump 'n Bump is distributed in the hope that it will be useful, 13# but WITHOUT ANY WARRANTY; without even the implied warranty of 14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15# GNU General Public License for more details. 16# 17# You should have received a copy of the GNU General Public License 18# along with this program; if not, write to the Free Software 19# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 21import sys 22import os 23import tempfile 24import shutil 25import gettext 26 27import gi 28gi.require_version('Gtk', '3.0') 29from gi.repository import Gtk, Gdk, GObject 30 31RESOURCE_DIR = '%%DATADIR%%/jumpnbump' 32BINARY_DIR = '%%BINDIR%%' 33UNPACK_BIN = '%%UNPACKBIN%%' 34 35application = "jumpnbump-menu" 36gettext.install(application) 37 38 39def populate_treeview(): 40 levels = [] 41 add_levels(levels, RESOURCE_DIR) 42 add_levels(levels, os.path.expanduser("~/.jumpnbump/levels")) 43 44 levels = sorted(levels, key=lambda level: level[0]) 45 46 COLUMN_LEVEL = 0 47 COLUMN_DIR = 1 48 store = Gtk.ListStore(GObject.TYPE_STRING, GObject.TYPE_STRING) 49 50 for level in levels: 51 iter = store.append() 52 store.set(iter, COLUMN_LEVEL, level[0], COLUMN_DIR, level[1]) 53 54 treeview.set_model(store) 55 56 renderer = Gtk.CellRendererText() 57 treeview.append_column(Gtk.TreeViewColumn( 58 _('Level'), renderer, text=COLUMN_LEVEL)) 59 60 61def add_levels(levels, dir): 62 try: 63 for file in os.listdir(dir): 64 if (file.endswith('.dat') or file.endswith('.DAT')): 65 levels.append((file, dir)) 66 except OSError as err: 67 print("%s not found (%s)." % (dir, str(err))) 68 69 70def standalone_mode(widget): 71 disable_enable_level(1) 72 disable_enable_server(0) 73 num_clients.set_sensitive(0) 74 nogore.set_sensitive(1) 75 noflies.set_sensitive(1) 76 77 78def client_mode(widget): 79 disable_enable_level(1) 80 disable_enable_server(1) 81 num_clients.set_sensitive(0) 82 nogore.set_sensitive(1) 83 noflies.set_sensitive(1) 84 85 86def server_mode(widget): 87 disable_enable_level(1) 88 disable_enable_server(0) 89 num_clients.set_sensitive(1) 90 nogore.set_sensitive(1) 91 noflies.set_sensitive(1) 92 93 94def disable_enable_server(setting): 95 server_entry.set_sensitive(setting) 96 player_num.set_sensitive(setting) 97 98 99def disable_enable_level(setting): 100 treeview.set_sensitive(setting) 101 mirror.set_sensitive(setting) 102 if (not setting): 103 mirror.set_active(setting) 104 105 106def level_changed(widget): 107 model, iter = treeview.get_selection().get_selected() 108 global choosen_level 109 choosen_level = '%s/%s' % (model.get_value(iter, 1), 110 model.get_value(iter, 0)) 111 unpackdir = None 112 try: 113 unpackdir = tempfile.mkdtemp("", "jumpnbump-menu-") 114 os.chdir(unpackdir) 115 os.spawnlp(os.P_WAIT, UNPACK_BIN, 116 'unpack', choosen_level) 117 os.spawnlp(os.P_WAIT, 'convert', 'convert', '-scale', 118 '50%', 'level.pcx', 'level_scaled.pcx') 119 os.spawnlp(os.P_WAIT, 'convert', 'convert', 120 'level_scaled.pcx', 'level.png') 121 image.set_from_file('level.png') 122 except Exception as err: 123 print(err) 124 finally: 125 if unpackdir != None: 126 shutil.rmtree(unpackdir) 127 128 image.show() 129 130 131def about(widget): 132 global about_dialog 133 if (not about_dialog.is_visible()): 134 about_dialog.show_all() 135 136 137def about_close(widget): 138 global about_dialog 139 about_dialog.hide() 140 141def about_quit(widget, event): 142 global about_dialog 143 about_dialog.hide() 144 return True 145 146 147def run(widget): 148 if (standalone.get_active()): 149 execute(*get_level() + common_options()) 150 elif (client.get_active()): 151 execute('-player', str(player_num.get_value_as_int()), 152 '-connect', server_entry.get_text(), 153 *get_level() + common_options()) 154 else: 155 execute('-server', str(num_clients.get_value_as_int()), 156 *get_level() + common_options()) 157 158 159def get_level(): 160 level = [] 161 if (mirror.get_active()): 162 level.append('-mirror') 163 else: 164 level.append('-dat') 165 level.append(choosen_level) 166 167 return level 168 169 170def common_options(): 171 options = [] 172 173 if (fullscreen.get_active()): 174 options.append('-fullscreen') 175 if (nogore.get_active()): 176 options.append('-nogore') 177 if (double_res.get_active()): 178 options.append('-scaleup') 179 if (nosound.get_active()): 180 options.append('-nosound') 181 if (noflies.get_active()): 182 options.append('-noflies') 183 if (withmusic.get_active()): 184 options.append('-musicnosound') 185 if (mirror.get_active()): 186 options.append('-mirror') 187 188 return options 189 190 191def execute(*cmd): 192 try: 193 os.spawnl(os.P_NOWAIT, BINARY_DIR + '/jumpnbump', 'jumpnbump', *cmd) 194 except Exception as err: 195 print(err) 196 197 198def main(): 199 global gladefile 200 201 global_gladefile = RESOURCE_DIR + '/jumpnbump_menu.glade' 202 local_gladefile = './jumpnbump_menu.glade' 203 204 if (os.access(global_gladefile, os.R_OK)): 205 gladefile = global_gladefile 206 del local_gladefile 207 elif (os.access(local_gladefile, os.R_OK)): 208 gladefile = local_gladefile 209 del global_gladefile 210 else: 211 print('Could not find the glade file') 212 return 0 213 214 gui = Gtk.Builder() 215 gui.add_from_file(gladefile) 216 217 global about_dialog, choosen_level, standalone, client, server, treeview, \ 218 mirror, num_clients, server_entry, player_num, fullscreen, \ 219 nogore, double_res, nosound, noflies, withmusic, image 220 221 choosen_level = '' 222 standalone = gui.get_object('standalone') 223 client = gui.get_object('client') 224 server = gui.get_object('server') 225 treeview = gui.get_object('level_treeview') 226 populate_treeview() 227 mirror = gui.get_object('mirror') 228 num_clients = gui.get_object('num_of_clients') 229 server_entry = gui.get_object('server_entry') 230 player_num = gui.get_object('player_num') 231 fullscreen = gui.get_object('fullscreen') 232 nogore = gui.get_object('nogore') 233 double_res = gui.get_object('double_res') 234 nosound = gui.get_object('nosound') 235 noflies = gui.get_object('noflies') 236 withmusic = gui.get_object('withmusic') 237 image = gui.get_object('image') 238 about_dialog = gui.get_object('about') 239 240 gui.connect_signals({'standalone_mode': standalone_mode, 241 'client_mode': client_mode, 242 'server_mode': server_mode, 243 'level_changed': level_changed, 244 'quit': lambda *args: Gtk.main_quit(), 245 'run': run, 246 'about': about, 247 'about_ok': about_close, 248 'about_quit': about_quit}) 249 250 Gtk.main() 251 252if __name__ == '__main__': 253 main() 254