revision 1034:7044e01148f0
summary |
tree |
shortlog |
changelog |
graph |
changeset |
raw | bz2 | zip | gz changeset | 1034:7044e01148f0 |
parent | 1033:b77b081441b5 |
child | 1035:e3093fd7d1da |
author | nkeynes |
date | Wed Jun 24 02:41:12 2009 +0000 (14 years ago) |
Add initial VMU support
1.1 --- a/po/POTFILES.in Wed Jun 24 02:27:34 2009 +00001.2 +++ b/po/POTFILES.in Wed Jun 24 02:41:12 2009 +00001.3 @@ -108,6 +108,7 @@1.4 src/maple/maple.c1.5 src/maple/maple.h1.6 src/maple/mouse.c1.7 +src/maple/vmu.c1.8 src/mem.c1.9 src/mem.h1.10 src/mmio.h1.11 @@ -170,6 +171,10 @@1.12 src/tools/insparse.c1.13 src/util.c1.14 src/version.c1.15 +src/vmu/vmulist.c1.16 +src/vmu/vmulist.h1.17 +src/vmu/vmuvol.c1.18 +src/vmu/vmuvol.h1.19 src/watch.c1.20 src/x86dasm/ansidecl.h1.21 src/x86dasm/bfd.h
2.1 --- a/po/de.po Wed Jun 24 02:27:34 2009 +00002.2 +++ b/po/de.po Wed Jun 24 02:41:12 2009 +00002.3 @@ -7,7 +7,7 @@2.4 msgstr ""2.5 "Project-Id-Version: lxdream 0.8.3\n"2.6 "Report-Msgid-Bugs-To: \n"2.7 -"POT-Creation-Date: 2009-06-12 19:52+1000\n"2.8 +"POT-Creation-Date: 2009-06-24 12:36+1000\n"2.9 "PO-Revision-Date: 2007-11-10 18:53+0100\n"2.10 "Last-Translator: Thomas Kowaliczek (LinuxDonald) LinuxDonald@LinuxDonald.de\n"2.11 "Language-Team: DE <trans-de@lxdream.org>\n"2.12 @@ -15,25 +15,30 @@2.13 "Content-Type: text/plain; charset=utf-8\n"2.14 "Content-Transfer-Encoding: 8bit\n"2.16 -#: src/cocoaui/cocoa_ctrl.m:342 src/gtkui/gtk_ctrl.c:2942.17 -#, c-format2.18 -msgid "Slot %d."2.19 +#: src/cocoaui/cocoa_ctrl.m:324 src/gtkui/gtk_ctrl.c:4862.20 +#, fuzzy, c-format2.21 +msgid "Port %c."2.22 msgstr "Slot %d."2.24 -#: src/cocoaui/cocoaui.m:4042.25 +#: src/cocoaui/cocoa_ctrl.m:326 src/gtkui/gtk_ctrl.c:5152.26 +#, c-format2.27 +msgid "VMU %d."2.28 +msgstr ""2.29 +2.30 +#: src/cocoaui/cocoaui.m:4122.31 #, c-format2.32 msgid "Running (%2.4f%%)"2.33 msgstr ""2.35 -#: src/cocoaui/cocoa_win.m:192 src/gtkui/gtk_win.c:3562.36 +#: src/cocoaui/cocoa_win.m:193 src/gtkui/gtk_win.c:3562.37 msgid "(Press <ctrl><alt> to release grab)"2.38 msgstr ""2.40 -#: src/cocoaui/cocoa_win.m:204 src/gtkui/gtk_win.c:3662.41 +#: src/cocoaui/cocoa_win.m:205 src/gtkui/gtk_win.c:3662.42 msgid "Running"2.43 msgstr ""2.45 -#: src/cocoaui/cocoa_win.m:207 src/gtkui/gtk_win.c:3662.46 +#: src/cocoaui/cocoa_win.m:208 src/gtkui/gtk_win.c:3662.47 msgid "Stopped"2.48 msgstr ""2.50 @@ -56,32 +61,36 @@2.51 msgid "Save-state path"2.52 msgstr "Speicherstand pfad"2.54 -#: src/config.c:45 src/gtkui/gtk_path.c:292.55 +#: src/config.c:452.56 +msgid "VMU path"2.57 +msgstr ""2.58 +2.59 +#: src/config.c:46 src/gtkui/gtk_path.c:292.60 msgid "Bootstrap IP.BIN"2.61 msgstr "Bootstrap IP.BIN"2.63 -#: src/config.c:512.64 +#: src/config.c:532.65 msgid "Serial device"2.66 msgstr ""2.68 -#: src/dreamcast.c:1922.69 +#: src/dreamcast.c:1932.70 msgid ""2.71 "No program is loaded, and no BIOS is configured (required to boot a CD "2.72 "image). To continue, either load a binary program, or set the path to your "2.73 "BIOS file in the Path Preferences"2.74 msgstr ""2.76 -#: src/dreamcast.c:3242.77 +#: src/dreamcast.c:3282.78 #, c-format2.79 msgid "File is not a %s save state"2.80 msgstr ""2.82 -#: src/dreamcast.c:3292.83 +#: src/dreamcast.c:3332.84 #, c-format2.85 msgid "Unsupported %s save state version"2.86 msgstr ""2.88 -#: src/dreamcast.c:3342.89 +#: src/dreamcast.c:3382.90 #, c-format2.91 msgid "%s save state is corrupted (bad module count)"2.92 msgstr ""2.93 @@ -134,7 +143,7 @@2.94 msgid "OS X Cocoa GUI-based OpenGL driver"2.95 msgstr ""2.97 -#: src/gdlist.c:206 src/gdlist.c:2292.98 +#: src/gdlist.c:187 src/gdlist.c:2102.99 msgid "Empty"2.100 msgstr "Leer"2.102 @@ -142,48 +151,65 @@2.103 msgid "All files"2.104 msgstr "Alle Dateien"2.106 -#: src/gtkui/gtkcb.c:1392.107 +#: src/gtkui/gtkcb.c:1622.108 msgid "Load state..."2.109 msgstr "Speicherpunkt laden..."2.111 -#: src/gtkui/gtkcb.c:144 src/gtkui/gtkcb.c:1752.112 +#: src/gtkui/gtkcb.c:167 src/gtkui/gtkcb.c:1982.113 msgid "lxDream Save State (*.dst)"2.114 msgstr "lxDream Speicherpunt (*.dst)"2.116 -#: src/gtkui/gtkcb.c:237 src/gtkui/gtk_dump.c:692.117 +#: src/gtkui/gtkcb.c:260 src/gtkui/gtk_dump.c:692.118 msgid "Memory dump"2.119 msgstr "Speicher dump"2.121 -#: src/gtkui/gtkcb.c:2502.122 +#: src/gtkui/gtkcb.c:2732.123 msgid "Save next scene..."2.124 msgstr "Nächste Szene speichern"2.126 -#: src/gtkui/gtkcb.c:2502.127 +#: src/gtkui/gtkcb.c:2732.128 msgid "lxdream scene file (*.dsc)"2.129 msgstr "lxdream szene Datei (*.dsc)"2.131 -#: src/gtkui/gtkcb.c:2652.132 +#: src/gtkui/gtkcb.c:2882.133 msgid "No address selected, so can't run to it"2.134 msgstr "Keine Adresse ausgewählt, also kann es nicht laufen"2.136 -#: src/gtkui/gtk_ctrl.c:72 src/gtkui/gtk_ctrl.c:101 src/gtkui/gtk_hotkeys.c:502.137 +#: src/gtkui/gtk_ctrl.c:80 src/gtkui/gtk_ctrl.c:109 src/gtkui/gtk_hotkeys.c:502.138 #: src/gtkui/gtk_hotkeys.c:792.139 msgid "<press key>"2.140 msgstr "<Taste drücken>"2.142 -#: src/gtkui/gtk_ctrl.c:2012.143 +#: src/gtkui/gtk_ctrl.c:2092.144 msgid "Controller Configuration"2.145 msgstr "Kontroller Konfiguration"2.147 -#: src/gtkui/gtk_ctrl.c:2202.148 +#: src/gtkui/gtk_ctrl.c:2282.149 msgid "No configuration page available for device type"2.150 msgstr "Keine Konfigurationseite für dieses Gerät"2.152 -#: src/gtkui/gtk_ctrl.c:2972.153 +#: src/gtkui/gtk_ctrl.c:2522.154 +msgid "Load VMU"2.155 +msgstr ""2.156 +2.157 +#: src/gtkui/gtk_ctrl.c:2662.158 +msgid "Create VMU"2.159 +msgstr ""2.160 +2.161 +#: src/gtkui/gtk_ctrl.c:329 src/gtkui/gtk_ctrl.c:3472.162 msgid "<empty>"2.163 msgstr "<leer>"2.165 -#: src/gtkui/gtk_ctrl.c:3252.166 +#: src/gtkui/gtk_ctrl.c:3562.167 +#, fuzzy2.168 +msgid "Load VMU..."2.169 +msgstr "Speicherpunkt laden..."2.170 +2.171 +#: src/gtkui/gtk_ctrl.c:3572.172 +msgid "Create VMU..."2.173 +msgstr ""2.174 +2.175 +#: src/gtkui/gtk_ctrl.c:5512.176 msgid "Controller Settings"2.177 msgstr "Kontroller einstellungen"2.179 @@ -571,139 +597,139 @@2.180 msgid "Select quick save state 9"2.181 msgstr ""2.183 -#: src/main.c:852.184 +#: src/main.c:862.185 msgid "Run the AICA SPU only, with the supplied program"2.186 msgstr ""2.188 -#: src/main.c:862.189 +#: src/main.c:872.190 msgid "Use the specified audio driver (? to list)"2.191 msgstr ""2.193 -#: src/main.c:872.194 +#: src/main.c:882.195 msgid "Load configuration from CONFFILE"2.196 msgstr ""2.198 -#: src/main.c:882.199 +#: src/main.c:892.200 msgid "Start in debugger mode"2.201 msgstr ""2.203 -#: src/main.c:892.204 +#: src/main.c:902.205 msgid "Start in fullscreen mode"2.206 msgstr ""2.208 -#: src/main.c:902.209 +#: src/main.c:912.210 msgid "Start GDB remote server on PORT for SH4"2.211 msgstr ""2.213 -#: src/main.c:912.214 +#: src/main.c:922.215 msgid "Start GDB remote server on PORT for ARM"2.216 msgstr ""2.218 -#: src/main.c:922.219 +#: src/main.c:932.220 msgid "Display this usage information"2.221 msgstr ""2.223 -#: src/main.c:932.224 +#: src/main.c:942.225 msgid "Run in headless (no video) mode"2.226 msgstr ""2.228 -#: src/main.c:942.229 +#: src/main.c:952.230 msgid "Set the output log level"2.231 msgstr ""2.233 -#: src/main.c:952.234 +#: src/main.c:962.235 msgid "Set the SH4 multiplier (1.0 = fullspeed)"2.236 msgstr ""2.238 -#: src/main.c:962.239 +#: src/main.c:972.240 msgid "Don't start running immediately"2.241 msgstr ""2.243 -#: src/main.c:972.244 +#: src/main.c:982.245 msgid "Start running immediately on startup"2.246 msgstr ""2.248 -#: src/main.c:982.249 +#: src/main.c:992.250 msgid "Run for the specified number of seconds"2.251 msgstr ""2.253 -#: src/main.c:992.254 +#: src/main.c:1002.255 msgid "Output trace information for the named regions"2.256 msgstr ""2.258 -#: src/main.c:1002.259 +#: src/main.c:1012.260 msgid "Allow unsafe dcload syscalls"2.261 msgstr ""2.263 -#: src/main.c:1012.264 +#: src/main.c:1022.265 msgid "Print the lxdream version string"2.266 msgstr ""2.268 -#: src/main.c:1022.269 +#: src/main.c:1032.270 msgid "Use the specified video driver (? to list)"2.271 msgstr ""2.273 -#: src/main.c:1032.274 +#: src/main.c:1042.275 msgid "Disable the SH4 translator"2.276 msgstr ""2.278 -#: src/maple/controller.c:105 src/maple/lightgun.c:852.279 +#: src/maple/controller.c:106 src/maple/lightgun.c:862.280 msgid "Dpad left"2.281 msgstr ""2.283 -#: src/maple/controller.c:106 src/maple/lightgun.c:862.284 +#: src/maple/controller.c:107 src/maple/lightgun.c:872.285 msgid "Dpad right"2.286 msgstr ""2.288 -#: src/maple/controller.c:107 src/maple/lightgun.c:872.289 +#: src/maple/controller.c:108 src/maple/lightgun.c:882.290 msgid "Dpad up"2.291 msgstr ""2.293 -#: src/maple/controller.c:108 src/maple/lightgun.c:882.294 +#: src/maple/controller.c:109 src/maple/lightgun.c:892.295 msgid "Dpad down"2.296 msgstr ""2.298 -#: src/maple/controller.c:1092.299 +#: src/maple/controller.c:1102.300 msgid "Analog left"2.301 msgstr ""2.303 -#: src/maple/controller.c:1102.304 +#: src/maple/controller.c:1112.305 msgid "Analog right"2.306 msgstr ""2.308 -#: src/maple/controller.c:1112.309 +#: src/maple/controller.c:1122.310 msgid "Analog up"2.311 msgstr ""2.313 -#: src/maple/controller.c:1122.314 +#: src/maple/controller.c:1132.315 msgid "Analog down"2.316 msgstr ""2.318 -#: src/maple/controller.c:1132.319 +#: src/maple/controller.c:1142.320 msgid "Button X"2.321 msgstr ""2.323 -#: src/maple/controller.c:1142.324 +#: src/maple/controller.c:1152.325 msgid "Button Y"2.326 msgstr ""2.328 -#: src/maple/controller.c:115 src/maple/lightgun.c:892.329 +#: src/maple/controller.c:116 src/maple/lightgun.c:902.330 msgid "Button A"2.331 msgstr ""2.333 -#: src/maple/controller.c:116 src/maple/lightgun.c:902.334 +#: src/maple/controller.c:117 src/maple/lightgun.c:912.335 msgid "Button B"2.336 msgstr ""2.338 -#: src/maple/controller.c:1172.339 +#: src/maple/controller.c:1182.340 msgid "Trigger left"2.341 msgstr ""2.343 -#: src/maple/controller.c:1182.344 +#: src/maple/controller.c:1192.345 msgid "Trigger right"2.346 msgstr ""2.348 -#: src/maple/controller.c:119 src/maple/lightgun.c:912.349 +#: src/maple/controller.c:120 src/maple/lightgun.c:922.350 msgid "Start button"2.351 msgstr ""
3.1 --- a/po/es.po Wed Jun 24 02:27:34 2009 +00003.2 +++ b/po/es.po Wed Jun 24 02:41:12 2009 +00003.3 @@ -7,7 +7,7 @@3.4 msgstr ""3.5 "Project-Id-Version: lxdream 0.8.3\n"3.6 "Report-Msgid-Bugs-To: \n"3.7 -"POT-Creation-Date: 2009-06-12 19:52+1000\n"3.8 +"POT-Creation-Date: 2009-06-24 12:36+1000\n"3.9 "PO-Revision-Date: 2007-12-18 17:29+0430\n"3.10 "Last-Translator:Jesus Segnini (the0ne) segnini75@hotmail.com\n"3.11 "Language-Team: ES <trans-es@lxdream.org>\n"3.12 @@ -15,25 +15,30 @@3.13 "Content-Type: text/plain; charset=utf-8\n"3.14 "Content-Transfer-Encoding: 8bit\n"3.16 -#: src/cocoaui/cocoa_ctrl.m:342 src/gtkui/gtk_ctrl.c:2943.17 -#, c-format3.18 -msgid "Slot %d."3.19 +#: src/cocoaui/cocoa_ctrl.m:324 src/gtkui/gtk_ctrl.c:4863.20 +#, fuzzy, c-format3.21 +msgid "Port %c."3.22 msgstr "Casilla %d"3.24 -#: src/cocoaui/cocoaui.m:4043.25 +#: src/cocoaui/cocoa_ctrl.m:326 src/gtkui/gtk_ctrl.c:5153.26 +#, c-format3.27 +msgid "VMU %d."3.28 +msgstr ""3.29 +3.30 +#: src/cocoaui/cocoaui.m:4123.31 #, c-format3.32 msgid "Running (%2.4f%%)"3.33 msgstr ""3.35 -#: src/cocoaui/cocoa_win.m:192 src/gtkui/gtk_win.c:3563.36 +#: src/cocoaui/cocoa_win.m:193 src/gtkui/gtk_win.c:3563.37 msgid "(Press <ctrl><alt> to release grab)"3.38 msgstr ""3.40 -#: src/cocoaui/cocoa_win.m:204 src/gtkui/gtk_win.c:3663.41 +#: src/cocoaui/cocoa_win.m:205 src/gtkui/gtk_win.c:3663.42 msgid "Running"3.43 msgstr ""3.45 -#: src/cocoaui/cocoa_win.m:207 src/gtkui/gtk_win.c:3663.46 +#: src/cocoaui/cocoa_win.m:208 src/gtkui/gtk_win.c:3663.47 msgid "Stopped"3.48 msgstr ""3.50 @@ -56,32 +61,36 @@3.51 msgid "Save-state path"3.52 msgstr "Guardar ruta de estado"3.54 -#: src/config.c:45 src/gtkui/gtk_path.c:293.55 +#: src/config.c:453.56 +msgid "VMU path"3.57 +msgstr ""3.58 +3.59 +#: src/config.c:46 src/gtkui/gtk_path.c:293.60 msgid "Bootstrap IP.BIN"3.61 msgstr "Bootstrap IP.BIN"3.63 -#: src/config.c:513.64 +#: src/config.c:533.65 msgid "Serial device"3.66 msgstr ""3.68 -#: src/dreamcast.c:1923.69 +#: src/dreamcast.c:1933.70 msgid ""3.71 "No program is loaded, and no BIOS is configured (required to boot a CD "3.72 "image). To continue, either load a binary program, or set the path to your "3.73 "BIOS file in the Path Preferences"3.74 msgstr ""3.76 -#: src/dreamcast.c:3243.77 +#: src/dreamcast.c:3283.78 #, c-format3.79 msgid "File is not a %s save state"3.80 msgstr ""3.82 -#: src/dreamcast.c:3293.83 +#: src/dreamcast.c:3333.84 #, c-format3.85 msgid "Unsupported %s save state version"3.86 msgstr ""3.88 -#: src/dreamcast.c:3343.89 +#: src/dreamcast.c:3383.90 #, c-format3.91 msgid "%s save state is corrupted (bad module count)"3.92 msgstr ""3.93 @@ -134,7 +143,7 @@3.94 msgid "OS X Cocoa GUI-based OpenGL driver"3.95 msgstr ""3.97 -#: src/gdlist.c:206 src/gdlist.c:2293.98 +#: src/gdlist.c:187 src/gdlist.c:2103.99 msgid "Empty"3.100 msgstr ""3.102 @@ -142,49 +151,66 @@3.103 msgid "All files"3.104 msgstr "Todos los archivos"3.106 -#: src/gtkui/gtkcb.c:1393.107 +#: src/gtkui/gtkcb.c:1623.108 msgid "Load state..."3.109 msgstr "Cargar estado..."3.111 -#: src/gtkui/gtkcb.c:144 src/gtkui/gtkcb.c:1753.112 +#: src/gtkui/gtkcb.c:167 src/gtkui/gtkcb.c:1983.113 msgid "lxDream Save State (*.dst)"3.114 msgstr "Estado guardado LxDream (*.dst)"3.116 -#: src/gtkui/gtkcb.c:237 src/gtkui/gtk_dump.c:693.117 +#: src/gtkui/gtkcb.c:260 src/gtkui/gtk_dump.c:693.118 msgid "Memory dump"3.119 msgstr "Volcado de memoria"3.121 -#: src/gtkui/gtkcb.c:2503.122 +#: src/gtkui/gtkcb.c:2733.123 msgid "Save next scene..."3.124 msgstr "Guardar proxima escena"3.126 -#: src/gtkui/gtkcb.c:2503.127 +#: src/gtkui/gtkcb.c:2733.128 msgid "lxdream scene file (*.dsc)"3.129 msgstr "Archivo de escena de lxdream (*.dsc)"3.131 -#: src/gtkui/gtkcb.c:2653.132 +#: src/gtkui/gtkcb.c:2883.133 msgid "No address selected, so can't run to it"3.134 msgstr "No ha seleccionado una direccion, no puede ir alla entonces"3.136 -#: src/gtkui/gtk_ctrl.c:72 src/gtkui/gtk_ctrl.c:101 src/gtkui/gtk_hotkeys.c:503.137 +#: src/gtkui/gtk_ctrl.c:80 src/gtkui/gtk_ctrl.c:109 src/gtkui/gtk_hotkeys.c:503.138 #: src/gtkui/gtk_hotkeys.c:793.139 msgid "<press key>"3.140 msgstr "<presione una tecla>"3.142 -#: src/gtkui/gtk_ctrl.c:2013.143 +#: src/gtkui/gtk_ctrl.c:2093.144 msgid "Controller Configuration"3.145 msgstr "Configuracion del mando"3.147 -#: src/gtkui/gtk_ctrl.c:2203.148 +#: src/gtkui/gtk_ctrl.c:2283.149 msgid "No configuration page available for device type"3.150 msgstr ""3.151 "No hay pagina de configuracion disponible para este tipo de dispositivo"3.153 -#: src/gtkui/gtk_ctrl.c:2973.154 +#: src/gtkui/gtk_ctrl.c:2523.155 +msgid "Load VMU"3.156 +msgstr ""3.157 +3.158 +#: src/gtkui/gtk_ctrl.c:2663.159 +msgid "Create VMU"3.160 +msgstr ""3.161 +3.162 +#: src/gtkui/gtk_ctrl.c:329 src/gtkui/gtk_ctrl.c:3473.163 msgid "<empty>"3.164 msgstr "<vacio>"3.166 -#: src/gtkui/gtk_ctrl.c:3253.167 +#: src/gtkui/gtk_ctrl.c:3563.168 +#, fuzzy3.169 +msgid "Load VMU..."3.170 +msgstr "Cargar estado..."3.171 +3.172 +#: src/gtkui/gtk_ctrl.c:3573.173 +msgid "Create VMU..."3.174 +msgstr ""3.175 +3.176 +#: src/gtkui/gtk_ctrl.c:5513.177 msgid "Controller Settings"3.178 msgstr "Configuracion del mando"3.180 @@ -572,139 +598,139 @@3.181 msgid "Select quick save state 9"3.182 msgstr ""3.184 -#: src/main.c:853.185 +#: src/main.c:863.186 msgid "Run the AICA SPU only, with the supplied program"3.187 msgstr ""3.189 -#: src/main.c:863.190 +#: src/main.c:873.191 msgid "Use the specified audio driver (? to list)"3.192 msgstr ""3.194 -#: src/main.c:873.195 +#: src/main.c:883.196 msgid "Load configuration from CONFFILE"3.197 msgstr ""3.199 -#: src/main.c:883.200 +#: src/main.c:893.201 msgid "Start in debugger mode"3.202 msgstr ""3.204 -#: src/main.c:893.205 +#: src/main.c:903.206 msgid "Start in fullscreen mode"3.207 msgstr ""3.209 -#: src/main.c:903.210 +#: src/main.c:913.211 msgid "Start GDB remote server on PORT for SH4"3.212 msgstr ""3.214 -#: src/main.c:913.215 +#: src/main.c:923.216 msgid "Start GDB remote server on PORT for ARM"3.217 msgstr ""3.219 -#: src/main.c:923.220 +#: src/main.c:933.221 msgid "Display this usage information"3.222 msgstr ""3.224 -#: src/main.c:933.225 +#: src/main.c:943.226 msgid "Run in headless (no video) mode"3.227 msgstr ""3.229 -#: src/main.c:943.230 +#: src/main.c:953.231 msgid "Set the output log level"3.232 msgstr ""3.234 -#: src/main.c:953.235 +#: src/main.c:963.236 msgid "Set the SH4 multiplier (1.0 = fullspeed)"3.237 msgstr ""3.239 -#: src/main.c:963.240 +#: src/main.c:973.241 msgid "Don't start running immediately"3.242 msgstr ""3.244 -#: src/main.c:973.245 +#: src/main.c:983.246 msgid "Start running immediately on startup"3.247 msgstr ""3.249 -#: src/main.c:983.250 +#: src/main.c:993.251 msgid "Run for the specified number of seconds"3.252 msgstr ""3.254 -#: src/main.c:993.255 +#: src/main.c:1003.256 msgid "Output trace information for the named regions"3.257 msgstr ""3.259 -#: src/main.c:1003.260 +#: src/main.c:1013.261 msgid "Allow unsafe dcload syscalls"3.262 msgstr ""3.264 -#: src/main.c:1013.265 +#: src/main.c:1023.266 msgid "Print the lxdream version string"3.267 msgstr ""3.269 -#: src/main.c:1023.270 +#: src/main.c:1033.271 msgid "Use the specified video driver (? to list)"3.272 msgstr ""3.274 -#: src/main.c:1033.275 +#: src/main.c:1043.276 msgid "Disable the SH4 translator"3.277 msgstr ""3.279 -#: src/maple/controller.c:105 src/maple/lightgun.c:853.280 +#: src/maple/controller.c:106 src/maple/lightgun.c:863.281 msgid "Dpad left"3.282 msgstr ""3.284 -#: src/maple/controller.c:106 src/maple/lightgun.c:863.285 +#: src/maple/controller.c:107 src/maple/lightgun.c:873.286 msgid "Dpad right"3.287 msgstr ""3.289 -#: src/maple/controller.c:107 src/maple/lightgun.c:873.290 +#: src/maple/controller.c:108 src/maple/lightgun.c:883.291 msgid "Dpad up"3.292 msgstr ""3.294 -#: src/maple/controller.c:108 src/maple/lightgun.c:883.295 +#: src/maple/controller.c:109 src/maple/lightgun.c:893.296 msgid "Dpad down"3.297 msgstr ""3.299 -#: src/maple/controller.c:1093.300 +#: src/maple/controller.c:1103.301 msgid "Analog left"3.302 msgstr ""3.304 -#: src/maple/controller.c:1103.305 +#: src/maple/controller.c:1113.306 msgid "Analog right"3.307 msgstr ""3.309 -#: src/maple/controller.c:1113.310 +#: src/maple/controller.c:1123.311 msgid "Analog up"3.312 msgstr ""3.314 -#: src/maple/controller.c:1123.315 +#: src/maple/controller.c:1133.316 msgid "Analog down"3.317 msgstr ""3.319 -#: src/maple/controller.c:1133.320 +#: src/maple/controller.c:1143.321 msgid "Button X"3.322 msgstr ""3.324 -#: src/maple/controller.c:1143.325 +#: src/maple/controller.c:1153.326 msgid "Button Y"3.327 msgstr ""3.329 -#: src/maple/controller.c:115 src/maple/lightgun.c:893.330 +#: src/maple/controller.c:116 src/maple/lightgun.c:903.331 msgid "Button A"3.332 msgstr ""3.334 -#: src/maple/controller.c:116 src/maple/lightgun.c:903.335 +#: src/maple/controller.c:117 src/maple/lightgun.c:913.336 msgid "Button B"3.337 msgstr ""3.339 -#: src/maple/controller.c:1173.340 +#: src/maple/controller.c:1183.341 msgid "Trigger left"3.342 msgstr ""3.344 -#: src/maple/controller.c:1183.345 +#: src/maple/controller.c:1193.346 msgid "Trigger right"3.347 msgstr ""3.349 -#: src/maple/controller.c:119 src/maple/lightgun.c:913.350 +#: src/maple/controller.c:120 src/maple/lightgun.c:923.351 msgid "Start button"3.352 msgstr ""
4.1 --- a/po/it.po Wed Jun 24 02:27:34 2009 +00004.2 +++ b/po/it.po Wed Jun 24 02:41:12 2009 +00004.3 @@ -7,7 +7,7 @@4.4 msgstr ""4.5 "Project-Id-Version: lxdream 0.8.3\n"4.6 "Report-Msgid-Bugs-To: \n"4.7 -"POT-Creation-Date: 2009-06-12 19:52+1000\n"4.8 +"POT-Creation-Date: 2009-06-24 12:36+1000\n"4.9 "PO-Revision-Date: 2008-04-10 00:00+0000\n"4.10 "Last-Translator: Ghost22 <ghost22@infinito.it>\n"4.11 "Language-Team: Italiano <LL@li.org>\n"4.12 @@ -15,25 +15,30 @@4.13 "Content-Type: text/plain; charset=utf-8\n"4.14 "Content-Transfer-Encoding: 8bit\n"4.16 -#: src/cocoaui/cocoa_ctrl.m:342 src/gtkui/gtk_ctrl.c:2944.17 -#, c-format4.18 -msgid "Slot %d."4.19 +#: src/cocoaui/cocoa_ctrl.m:324 src/gtkui/gtk_ctrl.c:4864.20 +#, fuzzy, c-format4.21 +msgid "Port %c."4.22 msgstr "Slot %d."4.24 -#: src/cocoaui/cocoaui.m:4044.25 +#: src/cocoaui/cocoa_ctrl.m:326 src/gtkui/gtk_ctrl.c:5154.26 +#, c-format4.27 +msgid "VMU %d."4.28 +msgstr ""4.29 +4.30 +#: src/cocoaui/cocoaui.m:4124.31 #, c-format4.32 msgid "Running (%2.4f%%)"4.33 msgstr ""4.35 -#: src/cocoaui/cocoa_win.m:192 src/gtkui/gtk_win.c:3564.36 +#: src/cocoaui/cocoa_win.m:193 src/gtkui/gtk_win.c:3564.37 msgid "(Press <ctrl><alt> to release grab)"4.38 msgstr ""4.40 -#: src/cocoaui/cocoa_win.m:204 src/gtkui/gtk_win.c:3664.41 +#: src/cocoaui/cocoa_win.m:205 src/gtkui/gtk_win.c:3664.42 msgid "Running"4.43 msgstr ""4.45 -#: src/cocoaui/cocoa_win.m:207 src/gtkui/gtk_win.c:3664.46 +#: src/cocoaui/cocoa_win.m:208 src/gtkui/gtk_win.c:3664.47 msgid "Stopped"4.48 msgstr ""4.50 @@ -56,32 +61,36 @@4.51 msgid "Save-state path"4.52 msgstr "Percorso del salvataggio dello stato"4.54 -#: src/config.c:45 src/gtkui/gtk_path.c:294.55 +#: src/config.c:454.56 +msgid "VMU path"4.57 +msgstr ""4.58 +4.59 +#: src/config.c:46 src/gtkui/gtk_path.c:294.60 msgid "Bootstrap IP.BIN"4.61 msgstr "Bootstrap IP.BIN"4.63 -#: src/config.c:514.64 +#: src/config.c:534.65 msgid "Serial device"4.66 msgstr ""4.68 -#: src/dreamcast.c:1924.69 +#: src/dreamcast.c:1934.70 msgid ""4.71 "No program is loaded, and no BIOS is configured (required to boot a CD "4.72 "image). To continue, either load a binary program, or set the path to your "4.73 "BIOS file in the Path Preferences"4.74 msgstr ""4.76 -#: src/dreamcast.c:3244.77 +#: src/dreamcast.c:3284.78 #, c-format4.79 msgid "File is not a %s save state"4.80 msgstr ""4.82 -#: src/dreamcast.c:3294.83 +#: src/dreamcast.c:3334.84 #, c-format4.85 msgid "Unsupported %s save state version"4.86 msgstr ""4.88 -#: src/dreamcast.c:3344.89 +#: src/dreamcast.c:3384.90 #, c-format4.91 msgid "%s save state is corrupted (bad module count)"4.92 msgstr ""4.93 @@ -134,7 +143,7 @@4.94 msgid "OS X Cocoa GUI-based OpenGL driver"4.95 msgstr ""4.97 -#: src/gdlist.c:206 src/gdlist.c:2294.98 +#: src/gdlist.c:187 src/gdlist.c:2104.99 msgid "Empty"4.100 msgstr "Vuoto"4.102 @@ -142,48 +151,65 @@4.103 msgid "All files"4.104 msgstr "Tutti i files"4.106 -#: src/gtkui/gtkcb.c:1394.107 +#: src/gtkui/gtkcb.c:1624.108 msgid "Load state..."4.109 msgstr "Carica stato..."4.111 -#: src/gtkui/gtkcb.c:144 src/gtkui/gtkcb.c:1754.112 +#: src/gtkui/gtkcb.c:167 src/gtkui/gtkcb.c:1984.113 msgid "lxDream Save State (*.dst)"4.114 msgstr "Salvataggio stato LxDream (*.dst)"4.116 -#: src/gtkui/gtkcb.c:237 src/gtkui/gtk_dump.c:694.117 +#: src/gtkui/gtkcb.c:260 src/gtkui/gtk_dump.c:694.118 msgid "Memory dump"4.119 msgstr "Memoria"4.121 -#: src/gtkui/gtkcb.c:2504.122 +#: src/gtkui/gtkcb.c:2734.123 msgid "Save next scene..."4.124 msgstr "Salva prossima scena..."4.126 -#: src/gtkui/gtkcb.c:2504.127 +#: src/gtkui/gtkcb.c:2734.128 msgid "lxdream scene file (*.dsc)"4.129 msgstr "file scena lxdream (*.dsc)"4.131 -#: src/gtkui/gtkcb.c:2654.132 +#: src/gtkui/gtkcb.c:2884.133 msgid "No address selected, so can't run to it"4.134 msgstr "Nessun indirizzo selezionato, quindi non posso andarci"4.136 -#: src/gtkui/gtk_ctrl.c:72 src/gtkui/gtk_ctrl.c:101 src/gtkui/gtk_hotkeys.c:504.137 +#: src/gtkui/gtk_ctrl.c:80 src/gtkui/gtk_ctrl.c:109 src/gtkui/gtk_hotkeys.c:504.138 #: src/gtkui/gtk_hotkeys.c:794.139 msgid "<press key>"4.140 msgstr "<premi un tasto>"4.142 -#: src/gtkui/gtk_ctrl.c:2014.143 +#: src/gtkui/gtk_ctrl.c:2094.144 msgid "Controller Configuration"4.145 msgstr "Configura il controller"4.147 -#: src/gtkui/gtk_ctrl.c:2204.148 +#: src/gtkui/gtk_ctrl.c:2284.149 msgid "No configuration page available for device type"4.150 msgstr "Nessuna configurazione è attivabile per questo tipo di periferica"4.152 -#: src/gtkui/gtk_ctrl.c:2974.153 +#: src/gtkui/gtk_ctrl.c:2524.154 +msgid "Load VMU"4.155 +msgstr ""4.156 +4.157 +#: src/gtkui/gtk_ctrl.c:2664.158 +msgid "Create VMU"4.159 +msgstr ""4.160 +4.161 +#: src/gtkui/gtk_ctrl.c:329 src/gtkui/gtk_ctrl.c:3474.162 msgid "<empty>"4.163 msgstr "<vuoto>"4.165 -#: src/gtkui/gtk_ctrl.c:3254.166 +#: src/gtkui/gtk_ctrl.c:3564.167 +#, fuzzy4.168 +msgid "Load VMU..."4.169 +msgstr "Carica stato..."4.170 +4.171 +#: src/gtkui/gtk_ctrl.c:3574.172 +msgid "Create VMU..."4.173 +msgstr ""4.174 +4.175 +#: src/gtkui/gtk_ctrl.c:5514.176 msgid "Controller Settings"4.177 msgstr "Opzioni del controller"4.179 @@ -571,139 +597,139 @@4.180 msgid "Select quick save state 9"4.181 msgstr ""4.183 -#: src/main.c:854.184 +#: src/main.c:864.185 msgid "Run the AICA SPU only, with the supplied program"4.186 msgstr ""4.188 -#: src/main.c:864.189 +#: src/main.c:874.190 msgid "Use the specified audio driver (? to list)"4.191 msgstr ""4.193 -#: src/main.c:874.194 +#: src/main.c:884.195 msgid "Load configuration from CONFFILE"4.196 msgstr ""4.198 -#: src/main.c:884.199 +#: src/main.c:894.200 msgid "Start in debugger mode"4.201 msgstr ""4.203 -#: src/main.c:894.204 +#: src/main.c:904.205 msgid "Start in fullscreen mode"4.206 msgstr ""4.208 -#: src/main.c:904.209 +#: src/main.c:914.210 msgid "Start GDB remote server on PORT for SH4"4.211 msgstr ""4.213 -#: src/main.c:914.214 +#: src/main.c:924.215 msgid "Start GDB remote server on PORT for ARM"4.216 msgstr ""4.218 -#: src/main.c:924.219 +#: src/main.c:934.220 msgid "Display this usage information"4.221 msgstr ""4.223 -#: src/main.c:934.224 +#: src/main.c:944.225 msgid "Run in headless (no video) mode"4.226 msgstr ""4.228 -#: src/main.c:944.229 +#: src/main.c:954.230 msgid "Set the output log level"4.231 msgstr ""4.233 -#: src/main.c:954.234 +#: src/main.c:964.235 msgid "Set the SH4 multiplier (1.0 = fullspeed)"4.236 msgstr ""4.238 -#: src/main.c:964.239 +#: src/main.c:974.240 msgid "Don't start running immediately"4.241 msgstr ""4.243 -#: src/main.c:974.244 +#: src/main.c:984.245 msgid "Start running immediately on startup"4.246 msgstr ""4.248 -#: src/main.c:984.249 +#: src/main.c:994.250 msgid "Run for the specified number of seconds"4.251 msgstr ""4.253 -#: src/main.c:994.254 +#: src/main.c:1004.255 msgid "Output trace information for the named regions"4.256 msgstr ""4.258 -#: src/main.c:1004.259 +#: src/main.c:1014.260 msgid "Allow unsafe dcload syscalls"4.261 msgstr ""4.263 -#: src/main.c:1014.264 +#: src/main.c:1024.265 msgid "Print the lxdream version string"4.266 msgstr ""4.268 -#: src/main.c:1024.269 +#: src/main.c:1034.270 msgid "Use the specified video driver (? to list)"4.271 msgstr ""4.273 -#: src/main.c:1034.274 +#: src/main.c:1044.275 msgid "Disable the SH4 translator"4.276 msgstr ""4.278 -#: src/maple/controller.c:105 src/maple/lightgun.c:854.279 +#: src/maple/controller.c:106 src/maple/lightgun.c:864.280 msgid "Dpad left"4.281 msgstr ""4.283 -#: src/maple/controller.c:106 src/maple/lightgun.c:864.284 +#: src/maple/controller.c:107 src/maple/lightgun.c:874.285 msgid "Dpad right"4.286 msgstr ""4.288 -#: src/maple/controller.c:107 src/maple/lightgun.c:874.289 +#: src/maple/controller.c:108 src/maple/lightgun.c:884.290 msgid "Dpad up"4.291 msgstr ""4.293 -#: src/maple/controller.c:108 src/maple/lightgun.c:884.294 +#: src/maple/controller.c:109 src/maple/lightgun.c:894.295 msgid "Dpad down"4.296 msgstr ""4.298 -#: src/maple/controller.c:1094.299 +#: src/maple/controller.c:1104.300 msgid "Analog left"4.301 msgstr ""4.303 -#: src/maple/controller.c:1104.304 +#: src/maple/controller.c:1114.305 msgid "Analog right"4.306 msgstr ""4.308 -#: src/maple/controller.c:1114.309 +#: src/maple/controller.c:1124.310 msgid "Analog up"4.311 msgstr ""4.313 -#: src/maple/controller.c:1124.314 +#: src/maple/controller.c:1134.315 msgid "Analog down"4.316 msgstr ""4.318 -#: src/maple/controller.c:1134.319 +#: src/maple/controller.c:1144.320 msgid "Button X"4.321 msgstr ""4.323 -#: src/maple/controller.c:1144.324 +#: src/maple/controller.c:1154.325 msgid "Button Y"4.326 msgstr ""4.328 -#: src/maple/controller.c:115 src/maple/lightgun.c:894.329 +#: src/maple/controller.c:116 src/maple/lightgun.c:904.330 msgid "Button A"4.331 msgstr ""4.333 -#: src/maple/controller.c:116 src/maple/lightgun.c:904.334 +#: src/maple/controller.c:117 src/maple/lightgun.c:914.335 msgid "Button B"4.336 msgstr ""4.338 -#: src/maple/controller.c:1174.339 +#: src/maple/controller.c:1184.340 msgid "Trigger left"4.341 msgstr ""4.343 -#: src/maple/controller.c:1184.344 +#: src/maple/controller.c:1194.345 msgid "Trigger right"4.346 msgstr ""4.348 -#: src/maple/controller.c:119 src/maple/lightgun.c:914.349 +#: src/maple/controller.c:120 src/maple/lightgun.c:924.350 msgid "Start button"4.351 msgstr ""
5.1 --- a/po/lxdream.pot Wed Jun 24 02:27:34 2009 +00005.2 +++ b/po/lxdream.pot Wed Jun 24 02:41:12 2009 +00005.3 @@ -8,7 +8,7 @@5.4 msgstr ""5.5 "Project-Id-Version: PACKAGE VERSION\n"5.6 "Report-Msgid-Bugs-To: \n"5.7 -"POT-Creation-Date: 2009-06-12 19:52+1000\n"5.8 +"POT-Creation-Date: 2009-06-24 12:36+1000\n"5.9 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"5.10 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"5.11 "Language-Team: LANGUAGE <LL@li.org>\n"5.12 @@ -16,25 +16,30 @@5.13 "Content-Type: text/plain; charset=CHARSET\n"5.14 "Content-Transfer-Encoding: 8bit\n"5.16 -#: src/cocoaui/cocoa_ctrl.m:342 src/gtkui/gtk_ctrl.c:2945.17 +#: src/cocoaui/cocoa_ctrl.m:324 src/gtkui/gtk_ctrl.c:4865.18 #, c-format5.19 -msgid "Slot %d."5.20 +msgid "Port %c."5.21 msgstr ""5.23 -#: src/cocoaui/cocoaui.m:4045.24 +#: src/cocoaui/cocoa_ctrl.m:326 src/gtkui/gtk_ctrl.c:5155.25 +#, c-format5.26 +msgid "VMU %d."5.27 +msgstr ""5.28 +5.29 +#: src/cocoaui/cocoaui.m:4125.30 #, c-format5.31 msgid "Running (%2.4f%%)"5.32 msgstr ""5.34 -#: src/cocoaui/cocoa_win.m:192 src/gtkui/gtk_win.c:3565.35 +#: src/cocoaui/cocoa_win.m:193 src/gtkui/gtk_win.c:3565.36 msgid "(Press <ctrl><alt> to release grab)"5.37 msgstr ""5.39 -#: src/cocoaui/cocoa_win.m:204 src/gtkui/gtk_win.c:3665.40 +#: src/cocoaui/cocoa_win.m:205 src/gtkui/gtk_win.c:3665.41 msgid "Running"5.42 msgstr ""5.44 -#: src/cocoaui/cocoa_win.m:207 src/gtkui/gtk_win.c:3665.45 +#: src/cocoaui/cocoa_win.m:208 src/gtkui/gtk_win.c:3665.46 msgid "Stopped"5.47 msgstr ""5.49 @@ -54,32 +59,36 @@5.50 msgid "Save-state path"5.51 msgstr ""5.53 -#: src/config.c:45 src/gtkui/gtk_path.c:295.54 +#: src/config.c:455.55 +msgid "VMU path"5.56 +msgstr ""5.57 +5.58 +#: src/config.c:46 src/gtkui/gtk_path.c:295.59 msgid "Bootstrap IP.BIN"5.60 msgstr ""5.62 -#: src/config.c:515.63 +#: src/config.c:535.64 msgid "Serial device"5.65 msgstr ""5.67 -#: src/dreamcast.c:1925.68 +#: src/dreamcast.c:1935.69 msgid ""5.70 "No program is loaded, and no BIOS is configured (required to boot a CD "5.71 "image). To continue, either load a binary program, or set the path to your "5.72 "BIOS file in the Path Preferences"5.73 msgstr ""5.75 -#: src/dreamcast.c:3245.76 +#: src/dreamcast.c:3285.77 #, c-format5.78 msgid "File is not a %s save state"5.79 msgstr ""5.81 -#: src/dreamcast.c:3295.82 +#: src/dreamcast.c:3335.83 #, c-format5.84 msgid "Unsupported %s save state version"5.85 msgstr ""5.87 -#: src/dreamcast.c:3345.88 +#: src/dreamcast.c:3385.89 #, c-format5.90 msgid "%s save state is corrupted (bad module count)"5.91 msgstr ""5.92 @@ -132,7 +141,7 @@5.93 msgid "OS X Cocoa GUI-based OpenGL driver"5.94 msgstr ""5.96 -#: src/gdlist.c:206 src/gdlist.c:2295.97 +#: src/gdlist.c:187 src/gdlist.c:2105.98 msgid "Empty"5.99 msgstr ""5.101 @@ -140,48 +149,64 @@5.102 msgid "All files"5.103 msgstr ""5.105 -#: src/gtkui/gtkcb.c:1395.106 +#: src/gtkui/gtkcb.c:1625.107 msgid "Load state..."5.108 msgstr ""5.110 -#: src/gtkui/gtkcb.c:144 src/gtkui/gtkcb.c:1755.111 +#: src/gtkui/gtkcb.c:167 src/gtkui/gtkcb.c:1985.112 msgid "lxDream Save State (*.dst)"5.113 msgstr ""5.115 -#: src/gtkui/gtkcb.c:237 src/gtkui/gtk_dump.c:695.116 +#: src/gtkui/gtkcb.c:260 src/gtkui/gtk_dump.c:695.117 msgid "Memory dump"5.118 msgstr ""5.120 -#: src/gtkui/gtkcb.c:2505.121 +#: src/gtkui/gtkcb.c:2735.122 msgid "Save next scene..."5.123 msgstr ""5.125 -#: src/gtkui/gtkcb.c:2505.126 +#: src/gtkui/gtkcb.c:2735.127 msgid "lxdream scene file (*.dsc)"5.128 msgstr ""5.130 -#: src/gtkui/gtkcb.c:2655.131 +#: src/gtkui/gtkcb.c:2885.132 msgid "No address selected, so can't run to it"5.133 msgstr ""5.135 -#: src/gtkui/gtk_ctrl.c:72 src/gtkui/gtk_ctrl.c:101 src/gtkui/gtk_hotkeys.c:505.136 +#: src/gtkui/gtk_ctrl.c:80 src/gtkui/gtk_ctrl.c:109 src/gtkui/gtk_hotkeys.c:505.137 #: src/gtkui/gtk_hotkeys.c:795.138 msgid "<press key>"5.139 msgstr ""5.141 -#: src/gtkui/gtk_ctrl.c:2015.142 +#: src/gtkui/gtk_ctrl.c:2095.143 msgid "Controller Configuration"5.144 msgstr ""5.146 -#: src/gtkui/gtk_ctrl.c:2205.147 +#: src/gtkui/gtk_ctrl.c:2285.148 msgid "No configuration page available for device type"5.149 msgstr ""5.151 -#: src/gtkui/gtk_ctrl.c:2975.152 +#: src/gtkui/gtk_ctrl.c:2525.153 +msgid "Load VMU"5.154 +msgstr ""5.155 +5.156 +#: src/gtkui/gtk_ctrl.c:2665.157 +msgid "Create VMU"5.158 +msgstr ""5.159 +5.160 +#: src/gtkui/gtk_ctrl.c:329 src/gtkui/gtk_ctrl.c:3475.161 msgid "<empty>"5.162 msgstr ""5.164 -#: src/gtkui/gtk_ctrl.c:3255.165 +#: src/gtkui/gtk_ctrl.c:3565.166 +msgid "Load VMU..."5.167 +msgstr ""5.168 +5.169 +#: src/gtkui/gtk_ctrl.c:3575.170 +msgid "Create VMU..."5.171 +msgstr ""5.172 +5.173 +#: src/gtkui/gtk_ctrl.c:5515.174 msgid "Controller Settings"5.175 msgstr ""5.177 @@ -561,139 +586,139 @@5.178 msgid "Select quick save state 9"5.179 msgstr ""5.181 -#: src/main.c:855.182 +#: src/main.c:865.183 msgid "Run the AICA SPU only, with the supplied program"5.184 msgstr ""5.186 -#: src/main.c:865.187 +#: src/main.c:875.188 msgid "Use the specified audio driver (? to list)"5.189 msgstr ""5.191 -#: src/main.c:875.192 +#: src/main.c:885.193 msgid "Load configuration from CONFFILE"5.194 msgstr ""5.196 -#: src/main.c:885.197 +#: src/main.c:895.198 msgid "Start in debugger mode"5.199 msgstr ""5.201 -#: src/main.c:895.202 +#: src/main.c:905.203 msgid "Start in fullscreen mode"5.204 msgstr ""5.206 -#: src/main.c:905.207 +#: src/main.c:915.208 msgid "Start GDB remote server on PORT for SH4"5.209 msgstr ""5.211 -#: src/main.c:915.212 +#: src/main.c:925.213 msgid "Start GDB remote server on PORT for ARM"5.214 msgstr ""5.216 -#: src/main.c:925.217 +#: src/main.c:935.218 msgid "Display this usage information"5.219 msgstr ""5.221 -#: src/main.c:935.222 +#: src/main.c:945.223 msgid "Run in headless (no video) mode"5.224 msgstr ""5.226 -#: src/main.c:945.227 +#: src/main.c:955.228 msgid "Set the output log level"5.229 msgstr ""5.231 -#: src/main.c:955.232 +#: src/main.c:965.233 msgid "Set the SH4 multiplier (1.0 = fullspeed)"5.234 msgstr ""5.236 -#: src/main.c:965.237 +#: src/main.c:975.238 msgid "Don't start running immediately"5.239 msgstr ""5.241 -#: src/main.c:975.242 +#: src/main.c:985.243 msgid "Start running immediately on startup"5.244 msgstr ""5.246 -#: src/main.c:985.247 +#: src/main.c:995.248 msgid "Run for the specified number of seconds"5.249 msgstr ""5.251 -#: src/main.c:995.252 +#: src/main.c:1005.253 msgid "Output trace information for the named regions"5.254 msgstr ""5.256 -#: src/main.c:1005.257 +#: src/main.c:1015.258 msgid "Allow unsafe dcload syscalls"5.259 msgstr ""5.261 -#: src/main.c:1015.262 +#: src/main.c:1025.263 msgid "Print the lxdream version string"5.264 msgstr ""5.266 -#: src/main.c:1025.267 +#: src/main.c:1035.268 msgid "Use the specified video driver (? to list)"5.269 msgstr ""5.271 -#: src/main.c:1035.272 +#: src/main.c:1045.273 msgid "Disable the SH4 translator"5.274 msgstr ""5.276 -#: src/maple/controller.c:105 src/maple/lightgun.c:855.277 +#: src/maple/controller.c:106 src/maple/lightgun.c:865.278 msgid "Dpad left"5.279 msgstr ""5.281 -#: src/maple/controller.c:106 src/maple/lightgun.c:865.282 +#: src/maple/controller.c:107 src/maple/lightgun.c:875.283 msgid "Dpad right"5.284 msgstr ""5.286 -#: src/maple/controller.c:107 src/maple/lightgun.c:875.287 +#: src/maple/controller.c:108 src/maple/lightgun.c:885.288 msgid "Dpad up"5.289 msgstr ""5.291 -#: src/maple/controller.c:108 src/maple/lightgun.c:885.292 +#: src/maple/controller.c:109 src/maple/lightgun.c:895.293 msgid "Dpad down"5.294 msgstr ""5.296 -#: src/maple/controller.c:1095.297 +#: src/maple/controller.c:1105.298 msgid "Analog left"5.299 msgstr ""5.301 -#: src/maple/controller.c:1105.302 +#: src/maple/controller.c:1115.303 msgid "Analog right"5.304 msgstr ""5.306 -#: src/maple/controller.c:1115.307 +#: src/maple/controller.c:1125.308 msgid "Analog up"5.309 msgstr ""5.311 -#: src/maple/controller.c:1125.312 +#: src/maple/controller.c:1135.313 msgid "Analog down"5.314 msgstr ""5.316 -#: src/maple/controller.c:1135.317 +#: src/maple/controller.c:1145.318 msgid "Button X"5.319 msgstr ""5.321 -#: src/maple/controller.c:1145.322 +#: src/maple/controller.c:1155.323 msgid "Button Y"5.324 msgstr ""5.326 -#: src/maple/controller.c:115 src/maple/lightgun.c:895.327 +#: src/maple/controller.c:116 src/maple/lightgun.c:905.328 msgid "Button A"5.329 msgstr ""5.331 -#: src/maple/controller.c:116 src/maple/lightgun.c:905.332 +#: src/maple/controller.c:117 src/maple/lightgun.c:915.333 msgid "Button B"5.334 msgstr ""5.336 -#: src/maple/controller.c:1175.337 +#: src/maple/controller.c:1185.338 msgid "Trigger left"5.339 msgstr ""5.341 -#: src/maple/controller.c:1185.342 +#: src/maple/controller.c:1195.343 msgid "Trigger right"5.344 msgstr ""5.346 -#: src/maple/controller.c:119 src/maple/lightgun.c:915.347 +#: src/maple/controller.c:120 src/maple/lightgun.c:925.348 msgid "Start button"5.349 msgstr ""
6.1 --- a/po/pt_BR.po Wed Jun 24 02:27:34 2009 +00006.2 +++ b/po/pt_BR.po Wed Jun 24 02:41:12 2009 +00006.3 @@ -7,7 +7,7 @@6.4 msgstr ""6.5 "Project-Id-Version: lxdream 0.8.3\n"6.6 "Report-Msgid-Bugs-To: \n"6.7 -"POT-Creation-Date: 2009-06-12 19:52+1000\n"6.8 +"POT-Creation-Date: 2009-06-24 12:36+1000\n"6.9 "PO-Revision-Date: 2009-04-03 11:05-0300\n"6.10 "Last-Translator: Gabriel Tillmann <gtillmann@gmail.com>\n"6.11 "Language-Team: PT <trans-pt@lxdream.org>\n"6.12 @@ -15,25 +15,30 @@6.13 "Content-Type: text/plain; charset=utf-8\n"6.14 "Content-Transfer-Encoding: 8bit\n"6.16 -#: src/cocoaui/cocoa_ctrl.m:342 src/gtkui/gtk_ctrl.c:2946.17 -#, c-format6.18 -msgid "Slot %d."6.19 +#: src/cocoaui/cocoa_ctrl.m:324 src/gtkui/gtk_ctrl.c:4866.20 +#, fuzzy, c-format6.21 +msgid "Port %c."6.22 msgstr "Slot %d."6.24 -#: src/cocoaui/cocoaui.m:4046.25 +#: src/cocoaui/cocoa_ctrl.m:326 src/gtkui/gtk_ctrl.c:5156.26 +#, c-format6.27 +msgid "VMU %d."6.28 +msgstr ""6.29 +6.30 +#: src/cocoaui/cocoaui.m:4126.31 #, c-format6.32 msgid "Running (%2.4f%%)"6.33 msgstr "Rodando (%2.4f%%)"6.35 -#: src/cocoaui/cocoa_win.m:192 src/gtkui/gtk_win.c:3566.36 +#: src/cocoaui/cocoa_win.m:193 src/gtkui/gtk_win.c:3566.37 msgid "(Press <ctrl><alt> to release grab)"6.38 msgstr "(Pressione <Ctrl><alt> para desprender)"6.40 -#: src/cocoaui/cocoa_win.m:204 src/gtkui/gtk_win.c:3666.41 +#: src/cocoaui/cocoa_win.m:205 src/gtkui/gtk_win.c:3666.42 msgid "Running"6.43 msgstr "Rodando"6.45 -#: src/cocoaui/cocoa_win.m:207 src/gtkui/gtk_win.c:3666.46 +#: src/cocoaui/cocoa_win.m:208 src/gtkui/gtk_win.c:3666.47 msgid "Stopped"6.48 msgstr "Parado"6.50 @@ -53,32 +58,36 @@6.51 msgid "Save-state path"6.52 msgstr "Diretório de Estados Salvos"6.54 -#: src/config.c:45 src/gtkui/gtk_path.c:296.55 +#: src/config.c:456.56 +msgid "VMU path"6.57 +msgstr ""6.58 +6.59 +#: src/config.c:46 src/gtkui/gtk_path.c:296.60 msgid "Bootstrap IP.BIN"6.61 msgstr "Bootstrap IP.BIN"6.63 -#: src/config.c:516.64 +#: src/config.c:536.65 msgid "Serial device"6.66 msgstr "Dispositivo Serial"6.68 -#: src/dreamcast.c:1926.69 +#: src/dreamcast.c:1936.70 msgid ""6.71 "No program is loaded, and no BIOS is configured (required to boot a CD "6.72 "image). To continue, either load a binary program, or set the path to your "6.73 "BIOS file in the Path Preferences"6.74 msgstr ""6.76 -#: src/dreamcast.c:3246.77 +#: src/dreamcast.c:3286.78 #, c-format6.79 msgid "File is not a %s save state"6.80 msgstr ""6.82 -#: src/dreamcast.c:3296.83 +#: src/dreamcast.c:3336.84 #, c-format6.85 msgid "Unsupported %s save state version"6.86 msgstr ""6.88 -#: src/dreamcast.c:3346.89 +#: src/dreamcast.c:3386.90 #, c-format6.91 msgid "%s save state is corrupted (bad module count)"6.92 msgstr ""6.93 @@ -131,7 +140,7 @@6.94 msgid "OS X Cocoa GUI-based OpenGL driver"6.95 msgstr "Driver GUI OS X Cocoa baseado em OpenGL "6.97 -#: src/gdlist.c:206 src/gdlist.c:2296.98 +#: src/gdlist.c:187 src/gdlist.c:2106.99 msgid "Empty"6.100 msgstr "Vazio"6.102 @@ -139,48 +148,65 @@6.103 msgid "All files"6.104 msgstr "Todos os Arquivos"6.106 -#: src/gtkui/gtkcb.c:1396.107 +#: src/gtkui/gtkcb.c:1626.108 msgid "Load state..."6.109 msgstr "Carregar stado..."6.111 -#: src/gtkui/gtkcb.c:144 src/gtkui/gtkcb.c:1756.112 +#: src/gtkui/gtkcb.c:167 src/gtkui/gtkcb.c:1986.113 msgid "lxDream Save State (*.dst)"6.114 msgstr "lxDream Save State (*.dst)"6.116 -#: src/gtkui/gtkcb.c:237 src/gtkui/gtk_dump.c:696.117 +#: src/gtkui/gtkcb.c:260 src/gtkui/gtk_dump.c:696.118 msgid "Memory dump"6.119 msgstr "Dump de memória"6.121 -#: src/gtkui/gtkcb.c:2506.122 +#: src/gtkui/gtkcb.c:2736.123 msgid "Save next scene..."6.124 msgstr "Salvar próxima cena"6.126 -#: src/gtkui/gtkcb.c:2506.127 +#: src/gtkui/gtkcb.c:2736.128 msgid "lxdream scene file (*.dsc)"6.129 msgstr "lxdream scene file (*.dsc)"6.131 -#: src/gtkui/gtkcb.c:2656.132 +#: src/gtkui/gtkcb.c:2886.133 msgid "No address selected, so can't run to it"6.134 msgstr "Sem endereço selecionado, então impossível correr a ele"6.136 -#: src/gtkui/gtk_ctrl.c:72 src/gtkui/gtk_ctrl.c:101 src/gtkui/gtk_hotkeys.c:506.137 +#: src/gtkui/gtk_ctrl.c:80 src/gtkui/gtk_ctrl.c:109 src/gtkui/gtk_hotkeys.c:506.138 #: src/gtkui/gtk_hotkeys.c:796.139 msgid "<press key>"6.140 msgstr "<Precione tecla>"6.142 -#: src/gtkui/gtk_ctrl.c:2016.143 +#: src/gtkui/gtk_ctrl.c:2096.144 msgid "Controller Configuration"6.145 msgstr "Configuração de controle"6.147 -#: src/gtkui/gtk_ctrl.c:2206.148 +#: src/gtkui/gtk_ctrl.c:2286.149 msgid "No configuration page available for device type"6.150 msgstr "Não há página de configuração disponível para este tipo de dispositivo"6.152 -#: src/gtkui/gtk_ctrl.c:2976.153 +#: src/gtkui/gtk_ctrl.c:2526.154 +msgid "Load VMU"6.155 +msgstr ""6.156 +6.157 +#: src/gtkui/gtk_ctrl.c:2666.158 +msgid "Create VMU"6.159 +msgstr ""6.160 +6.161 +#: src/gtkui/gtk_ctrl.c:329 src/gtkui/gtk_ctrl.c:3476.162 msgid "<empty>"6.163 msgstr "<Vazio>"6.165 -#: src/gtkui/gtk_ctrl.c:3256.166 +#: src/gtkui/gtk_ctrl.c:3566.167 +#, fuzzy6.168 +msgid "Load VMU..."6.169 +msgstr "Carregar stado..."6.170 +6.171 +#: src/gtkui/gtk_ctrl.c:3576.172 +msgid "Create VMU..."6.173 +msgstr ""6.174 +6.175 +#: src/gtkui/gtk_ctrl.c:5516.176 msgid "Controller Settings"6.177 msgstr "Configurações de Controle"6.179 @@ -564,140 +590,140 @@6.180 msgid "Select quick save state 9"6.181 msgstr ""6.183 -#: src/main.c:856.184 +#: src/main.c:866.185 msgid "Run the AICA SPU only, with the supplied program"6.186 msgstr "Correr Apenas o Spu AICA, com o programa dado"6.188 -#: src/main.c:866.189 +#: src/main.c:876.190 msgid "Use the specified audio driver (? to list)"6.191 msgstr "Usar Driver de audio específico (? para listar)"6.193 -#: src/main.c:876.194 +#: src/main.c:886.195 msgid "Load configuration from CONFFILE"6.196 msgstr "Carregar configurações de uma CONFFILE"6.198 -#: src/main.c:886.199 +#: src/main.c:896.200 msgid "Start in debugger mode"6.201 msgstr "Iniciar no modo debbugador"6.203 -#: src/main.c:896.204 +#: src/main.c:906.205 #, fuzzy6.206 msgid "Start in fullscreen mode"6.207 msgstr "Iniciar no modo debbugador"6.209 -#: src/main.c:906.210 +#: src/main.c:916.211 msgid "Start GDB remote server on PORT for SH4"6.212 msgstr ""6.214 -#: src/main.c:916.215 +#: src/main.c:926.216 msgid "Start GDB remote server on PORT for ARM"6.217 msgstr ""6.219 -#: src/main.c:926.220 +#: src/main.c:936.221 msgid "Display this usage information"6.222 msgstr "Mostrar informações de uso"6.224 -#: src/main.c:936.225 +#: src/main.c:946.226 msgid "Run in headless (no video) mode"6.227 msgstr "Rodar no Modo (sem vídeo) sem cabeça"6.229 -#: src/main.c:946.230 +#: src/main.c:956.231 msgid "Set the output log level"6.232 msgstr "Definir o nível de saída do Log"6.234 -#: src/main.c:956.235 +#: src/main.c:966.236 msgid "Set the SH4 multiplier (1.0 = fullspeed)"6.237 msgstr "Definir Multiplicador do SH4 (1.0 = Velocidade total)"6.239 -#: src/main.c:966.240 +#: src/main.c:976.241 msgid "Don't start running immediately"6.242 msgstr "Não Correr Imediatamente"6.244 -#: src/main.c:976.245 +#: src/main.c:986.246 msgid "Start running immediately on startup"6.247 msgstr "Correr Imediatamente "6.249 -#: src/main.c:986.250 +#: src/main.c:996.251 msgid "Run for the specified number of seconds"6.252 msgstr "Correr por um número específico de segundos"6.254 -#: src/main.c:996.255 +#: src/main.c:1006.256 msgid "Output trace information for the named regions"6.257 msgstr "Traçar informação de saída para regiões nomeadas"6.259 -#: src/main.c:1006.260 +#: src/main.c:1016.261 msgid "Allow unsafe dcload syscalls"6.262 msgstr "Permitir chamadas de sistema não seguras do dcload"6.264 -#: src/main.c:1016.265 +#: src/main.c:1026.266 msgid "Print the lxdream version string"6.267 msgstr "Mostrar a String de versão do lxdream"6.269 -#: src/main.c:1026.270 +#: src/main.c:1036.271 msgid "Use the specified video driver (? to list)"6.272 msgstr "Usar driver de vídeo específico (? para listar)"6.274 -#: src/main.c:1036.275 +#: src/main.c:1046.276 msgid "Disable the SH4 translator"6.277 msgstr "Desabilitar o tradutor de SH4"6.279 -#: src/maple/controller.c:105 src/maple/lightgun.c:856.280 +#: src/maple/controller.c:106 src/maple/lightgun.c:866.281 msgid "Dpad left"6.282 msgstr "Dpad Esquerda"6.284 -#: src/maple/controller.c:106 src/maple/lightgun.c:866.285 +#: src/maple/controller.c:107 src/maple/lightgun.c:876.286 msgid "Dpad right"6.287 msgstr "Dpad Direita"6.289 -#: src/maple/controller.c:107 src/maple/lightgun.c:876.290 +#: src/maple/controller.c:108 src/maple/lightgun.c:886.291 msgid "Dpad up"6.292 msgstr "Dpad Cima"6.294 -#: src/maple/controller.c:108 src/maple/lightgun.c:886.295 +#: src/maple/controller.c:109 src/maple/lightgun.c:896.296 msgid "Dpad down"6.297 msgstr "Dpad Baixo"6.299 -#: src/maple/controller.c:1096.300 +#: src/maple/controller.c:1106.301 msgid "Analog left"6.302 msgstr "Analógico Esquerda"6.304 -#: src/maple/controller.c:1106.305 +#: src/maple/controller.c:1116.306 msgid "Analog right"6.307 msgstr "Analógico Direita"6.309 -#: src/maple/controller.c:1116.310 +#: src/maple/controller.c:1126.311 msgid "Analog up"6.312 msgstr "Analógico Cima"6.314 -#: src/maple/controller.c:1126.315 +#: src/maple/controller.c:1136.316 msgid "Analog down"6.317 msgstr "Analógico Baixo"6.319 -#: src/maple/controller.c:1136.320 +#: src/maple/controller.c:1146.321 msgid "Button X"6.322 msgstr "Botão X"6.324 -#: src/maple/controller.c:1146.325 +#: src/maple/controller.c:1156.326 msgid "Button Y"6.327 msgstr "Botão Y"6.329 -#: src/maple/controller.c:115 src/maple/lightgun.c:896.330 +#: src/maple/controller.c:116 src/maple/lightgun.c:906.331 msgid "Button A"6.332 msgstr "Botão A"6.334 -#: src/maple/controller.c:116 src/maple/lightgun.c:906.335 +#: src/maple/controller.c:117 src/maple/lightgun.c:916.336 msgid "Button B"6.337 msgstr "Botão B"6.339 -#: src/maple/controller.c:1176.340 +#: src/maple/controller.c:1186.341 msgid "Trigger left"6.342 msgstr "Gatilho Esquerda"6.344 -#: src/maple/controller.c:1186.345 +#: src/maple/controller.c:1196.346 msgid "Trigger right"6.347 msgstr "Gatilho Direita"6.349 -#: src/maple/controller.c:119 src/maple/lightgun.c:916.350 +#: src/maple/controller.c:120 src/maple/lightgun.c:926.351 msgid "Start button"6.352 msgstr "Botão Start"
7.1 --- a/src/Makefile.am Wed Jun 24 02:27:34 2009 +00007.2 +++ b/src/Makefile.am Wed Jun 24 02:41:12 2009 +00007.3 @@ -63,8 +63,9 @@7.4 pvr2/gl_sl.c pvr2/gl_slsrc.c pvr2/glutil.c pvr2/glutil.h pvr2/glrender.c \7.5 pvr2/vertex.glsl pvr2/fragment.glsl \7.6 maple/maple.c maple/maple.h \7.7 - maple/controller.c maple/kbd.c maple/mouse.c maple/lightgun.c \7.8 + maple/controller.c maple/kbd.c maple/mouse.c maple/lightgun.c maple/vmu.c \7.9 loader.c loader.h elf.h bootstrap.c bootstrap.h util.c gdlist.c gdlist.h \7.10 + vmu/vmuvol.c vmu/vmuvol.h vmu/vmulist.c vmu/vmulist.h \7.11 display.c display.h dckeysyms.h \7.12 drivers/audio_null.c drivers/video_null.c drivers/cd_mmc.c \7.13 drivers/video_gl.c drivers/video_gl.h drivers/gl_fbo.c \
8.1 --- a/src/Makefile.in Wed Jun 24 02:27:34 2009 +00008.2 +++ b/src/Makefile.in Wed Jun 24 02:41:12 2009 +00008.3 @@ -161,8 +161,9 @@8.4 pvr2/glutil.h pvr2/glrender.c pvr2/vertex.glsl \8.5 pvr2/fragment.glsl maple/maple.c maple/maple.h \8.6 maple/controller.c maple/kbd.c maple/mouse.c maple/lightgun.c \8.7 - loader.c loader.h elf.h bootstrap.c bootstrap.h util.c \8.8 - gdlist.c gdlist.h display.c display.h dckeysyms.h \8.9 + maple/vmu.c loader.c loader.h elf.h bootstrap.c bootstrap.h \8.10 + util.c gdlist.c gdlist.h vmu/vmuvol.c vmu/vmuvol.h \8.11 + vmu/vmulist.c vmu/vmulist.h display.c display.h dckeysyms.h \8.12 drivers/audio_null.c drivers/video_null.c drivers/cd_mmc.c \8.13 drivers/video_gl.c drivers/video_gl.h drivers/gl_fbo.c \8.14 sh4/sh4.def sh4/sh4core.in sh4/sh4x86.in sh4/sh4dasm.in \8.15 @@ -259,18 +260,20 @@8.16 lxdream-glutil.$(OBJEXT) lxdream-glrender.$(OBJEXT) \8.17 lxdream-maple.$(OBJEXT) lxdream-controller.$(OBJEXT) \8.18 lxdream-kbd.$(OBJEXT) lxdream-mouse.$(OBJEXT) \8.19 - lxdream-lightgun.$(OBJEXT) lxdream-loader.$(OBJEXT) \8.20 - lxdream-bootstrap.$(OBJEXT) lxdream-util.$(OBJEXT) \8.21 - lxdream-gdlist.$(OBJEXT) lxdream-display.$(OBJEXT) \8.22 - lxdream-audio_null.$(OBJEXT) lxdream-video_null.$(OBJEXT) \8.23 - lxdream-cd_mmc.$(OBJEXT) lxdream-video_gl.$(OBJEXT) \8.24 - lxdream-gl_fbo.$(OBJEXT) lxdream-hotkeys.$(OBJEXT) \8.25 - $(am__objects_1) $(am__objects_2) $(am__objects_3) \8.26 - $(am__objects_4) $(am__objects_5) $(am__objects_6) \8.27 - $(am__objects_7) $(am__objects_8) $(am__objects_9) \8.28 - $(am__objects_10) $(am__objects_11) $(am__objects_12) \8.29 - $(am__objects_13) $(am__objects_14) $(am__objects_15) \8.30 - $(am__objects_16) $(am__objects_17) $(am__objects_18)8.31 + lxdream-lightgun.$(OBJEXT) lxdream-vmu.$(OBJEXT) \8.32 + lxdream-loader.$(OBJEXT) lxdream-bootstrap.$(OBJEXT) \8.33 + lxdream-util.$(OBJEXT) lxdream-gdlist.$(OBJEXT) \8.34 + lxdream-vmuvol.$(OBJEXT) lxdream-vmulist.$(OBJEXT) \8.35 + lxdream-display.$(OBJEXT) lxdream-audio_null.$(OBJEXT) \8.36 + lxdream-video_null.$(OBJEXT) lxdream-cd_mmc.$(OBJEXT) \8.37 + lxdream-video_gl.$(OBJEXT) lxdream-gl_fbo.$(OBJEXT) \8.38 + lxdream-hotkeys.$(OBJEXT) $(am__objects_1) $(am__objects_2) \8.39 + $(am__objects_3) $(am__objects_4) $(am__objects_5) \8.40 + $(am__objects_6) $(am__objects_7) $(am__objects_8) \8.41 + $(am__objects_9) $(am__objects_10) $(am__objects_11) \8.42 + $(am__objects_12) $(am__objects_13) $(am__objects_14) \8.43 + $(am__objects_15) $(am__objects_16) $(am__objects_17) \8.44 + $(am__objects_18)8.45 lxdream_OBJECTS = $(am_lxdream_OBJECTS)8.46 lxdream_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \8.47 $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \8.48 @@ -558,9 +561,10 @@8.49 pvr2/gl_sl.c pvr2/gl_slsrc.c pvr2/glutil.c pvr2/glutil.h \8.50 pvr2/glrender.c pvr2/vertex.glsl pvr2/fragment.glsl \8.51 maple/maple.c maple/maple.h maple/controller.c maple/kbd.c \8.52 - maple/mouse.c maple/lightgun.c loader.c loader.h elf.h \8.53 - bootstrap.c bootstrap.h util.c gdlist.c gdlist.h display.c \8.54 - display.h dckeysyms.h drivers/audio_null.c \8.55 + maple/mouse.c maple/lightgun.c maple/vmu.c loader.c loader.h \8.56 + elf.h bootstrap.c bootstrap.h util.c gdlist.c gdlist.h \8.57 + vmu/vmuvol.c vmu/vmuvol.h vmu/vmulist.c vmu/vmulist.h \8.58 + display.c display.h dckeysyms.h drivers/audio_null.c \8.59 drivers/video_null.c drivers/cd_mmc.c drivers/video_gl.c \8.60 drivers/video_gl.h drivers/gl_fbo.c sh4/sh4.def sh4/sh4core.in \8.61 sh4/sh4x86.in sh4/sh4dasm.in sh4/sh4stat.in hotkeys.c \8.62 @@ -841,6 +845,9 @@8.63 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxdream-video_nsgl.Po@am__quote@8.64 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxdream-video_null.Po@am__quote@8.65 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxdream-video_osx.Po@am__quote@8.66 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxdream-vmu.Po@am__quote@8.67 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxdream-vmulist.Po@am__quote@8.68 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxdream-vmuvol.Po@am__quote@8.69 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxdream-watch.Po@am__quote@8.70 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxdream-x86dasm.Po@am__quote@8.71 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lxdream-xltcache.Po@am__quote@8.72 @@ -1726,6 +1733,20 @@8.73 @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@8.74 @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lxdream_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lxdream-lightgun.obj `if test -f 'maple/lightgun.c'; then $(CYGPATH_W) 'maple/lightgun.c'; else $(CYGPATH_W) '$(srcdir)/maple/lightgun.c'; fi`8.76 +lxdream-vmu.o: maple/vmu.c8.77 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lxdream_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lxdream-vmu.o -MD -MP -MF "$(DEPDIR)/lxdream-vmu.Tpo" -c -o lxdream-vmu.o `test -f 'maple/vmu.c' || echo '$(srcdir)/'`maple/vmu.c; \8.78 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/lxdream-vmu.Tpo" "$(DEPDIR)/lxdream-vmu.Po"; else rm -f "$(DEPDIR)/lxdream-vmu.Tpo"; exit 1; fi8.79 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='maple/vmu.c' object='lxdream-vmu.o' libtool=no @AMDEPBACKSLASH@8.80 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@8.81 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lxdream_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lxdream-vmu.o `test -f 'maple/vmu.c' || echo '$(srcdir)/'`maple/vmu.c8.82 +8.83 +lxdream-vmu.obj: maple/vmu.c8.84 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lxdream_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lxdream-vmu.obj -MD -MP -MF "$(DEPDIR)/lxdream-vmu.Tpo" -c -o lxdream-vmu.obj `if test -f 'maple/vmu.c'; then $(CYGPATH_W) 'maple/vmu.c'; else $(CYGPATH_W) '$(srcdir)/maple/vmu.c'; fi`; \8.85 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/lxdream-vmu.Tpo" "$(DEPDIR)/lxdream-vmu.Po"; else rm -f "$(DEPDIR)/lxdream-vmu.Tpo"; exit 1; fi8.86 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='maple/vmu.c' object='lxdream-vmu.obj' libtool=no @AMDEPBACKSLASH@8.87 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@8.88 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lxdream_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lxdream-vmu.obj `if test -f 'maple/vmu.c'; then $(CYGPATH_W) 'maple/vmu.c'; else $(CYGPATH_W) '$(srcdir)/maple/vmu.c'; fi`8.89 +8.90 lxdream-loader.o: loader.c8.91 @am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lxdream_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lxdream-loader.o -MD -MP -MF "$(DEPDIR)/lxdream-loader.Tpo" -c -o lxdream-loader.o `test -f 'loader.c' || echo '$(srcdir)/'`loader.c; \8.92 @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/lxdream-loader.Tpo" "$(DEPDIR)/lxdream-loader.Po"; else rm -f "$(DEPDIR)/lxdream-loader.Tpo"; exit 1; fi8.93 @@ -1782,6 +1803,34 @@8.94 @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@8.95 @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lxdream_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lxdream-gdlist.obj `if test -f 'gdlist.c'; then $(CYGPATH_W) 'gdlist.c'; else $(CYGPATH_W) '$(srcdir)/gdlist.c'; fi`8.97 +lxdream-vmuvol.o: vmu/vmuvol.c8.98 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lxdream_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lxdream-vmuvol.o -MD -MP -MF "$(DEPDIR)/lxdream-vmuvol.Tpo" -c -o lxdream-vmuvol.o `test -f 'vmu/vmuvol.c' || echo '$(srcdir)/'`vmu/vmuvol.c; \8.99 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/lxdream-vmuvol.Tpo" "$(DEPDIR)/lxdream-vmuvol.Po"; else rm -f "$(DEPDIR)/lxdream-vmuvol.Tpo"; exit 1; fi8.100 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vmu/vmuvol.c' object='lxdream-vmuvol.o' libtool=no @AMDEPBACKSLASH@8.101 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@8.102 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lxdream_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lxdream-vmuvol.o `test -f 'vmu/vmuvol.c' || echo '$(srcdir)/'`vmu/vmuvol.c8.103 +8.104 +lxdream-vmuvol.obj: vmu/vmuvol.c8.105 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lxdream_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lxdream-vmuvol.obj -MD -MP -MF "$(DEPDIR)/lxdream-vmuvol.Tpo" -c -o lxdream-vmuvol.obj `if test -f 'vmu/vmuvol.c'; then $(CYGPATH_W) 'vmu/vmuvol.c'; else $(CYGPATH_W) '$(srcdir)/vmu/vmuvol.c'; fi`; \8.106 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/lxdream-vmuvol.Tpo" "$(DEPDIR)/lxdream-vmuvol.Po"; else rm -f "$(DEPDIR)/lxdream-vmuvol.Tpo"; exit 1; fi8.107 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vmu/vmuvol.c' object='lxdream-vmuvol.obj' libtool=no @AMDEPBACKSLASH@8.108 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@8.109 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lxdream_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lxdream-vmuvol.obj `if test -f 'vmu/vmuvol.c'; then $(CYGPATH_W) 'vmu/vmuvol.c'; else $(CYGPATH_W) '$(srcdir)/vmu/vmuvol.c'; fi`8.110 +8.111 +lxdream-vmulist.o: vmu/vmulist.c8.112 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lxdream_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lxdream-vmulist.o -MD -MP -MF "$(DEPDIR)/lxdream-vmulist.Tpo" -c -o lxdream-vmulist.o `test -f 'vmu/vmulist.c' || echo '$(srcdir)/'`vmu/vmulist.c; \8.113 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/lxdream-vmulist.Tpo" "$(DEPDIR)/lxdream-vmulist.Po"; else rm -f "$(DEPDIR)/lxdream-vmulist.Tpo"; exit 1; fi8.114 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vmu/vmulist.c' object='lxdream-vmulist.o' libtool=no @AMDEPBACKSLASH@8.115 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@8.116 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lxdream_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lxdream-vmulist.o `test -f 'vmu/vmulist.c' || echo '$(srcdir)/'`vmu/vmulist.c8.117 +8.118 +lxdream-vmulist.obj: vmu/vmulist.c8.119 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lxdream_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lxdream-vmulist.obj -MD -MP -MF "$(DEPDIR)/lxdream-vmulist.Tpo" -c -o lxdream-vmulist.obj `if test -f 'vmu/vmulist.c'; then $(CYGPATH_W) 'vmu/vmulist.c'; else $(CYGPATH_W) '$(srcdir)/vmu/vmulist.c'; fi`; \8.120 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/lxdream-vmulist.Tpo" "$(DEPDIR)/lxdream-vmulist.Po"; else rm -f "$(DEPDIR)/lxdream-vmulist.Tpo"; exit 1; fi8.121 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vmu/vmulist.c' object='lxdream-vmulist.obj' libtool=no @AMDEPBACKSLASH@8.122 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@8.123 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lxdream_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lxdream-vmulist.obj `if test -f 'vmu/vmulist.c'; then $(CYGPATH_W) 'vmu/vmulist.c'; else $(CYGPATH_W) '$(srcdir)/vmu/vmulist.c'; fi`8.124 +8.125 lxdream-display.o: display.c8.126 @am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lxdream_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lxdream-display.o -MD -MP -MF "$(DEPDIR)/lxdream-display.Tpo" -c -o lxdream-display.o `test -f 'display.c' || echo '$(srcdir)/'`display.c; \8.127 @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/lxdream-display.Tpo" "$(DEPDIR)/lxdream-display.Po"; else rm -f "$(DEPDIR)/lxdream-display.Tpo"; exit 1; fi
9.1 --- a/src/cocoaui/cocoa_ctrl.m Wed Jun 24 02:27:34 2009 +00009.2 +++ b/src/cocoaui/cocoa_ctrl.m Wed Jun 24 02:41:12 2009 +00009.3 @@ -20,14 +20,20 @@9.4 #include "config.h"9.5 #include "display.h"9.6 #include "maple/maple.h"9.7 +#include "vmu/vmulist.h"9.9 #include <glib/gstrfuncs.h>9.11 -#define MAX_DEVICES 49.12 +#define FIRST_SECONDARY_DEVICE MAPLE_PORTS9.13 +9.14 +#define FIRST_VMU_TAG 0x10009.15 +#define LOAD_VMU_TAG -19.16 +#define CREATE_VMU_TAG -29.18 #define KEYBINDING_SIZE 1109.20 static void cocoa_config_keysym_hook(void *data, const gchar *keysym);9.21 +static gboolean cocoa_config_vmulist_hook(vmulist_change_type_t type, int idx, void *data);9.23 @interface KeyBindingEditor (Private)9.24 - (void)updateKeysym: (const gchar *)sym;9.25 @@ -188,7 +194,7 @@9.26 @interface ControllerKeyBindingView : NSView9.27 {9.28 maple_device_t device;9.29 - KeyBindingField *field[MAX_KEY_BINDINGS][2];9.30 + NSTextField *field[MAX_KEY_BINDINGS][2];9.31 }9.32 - (id)initWithFrame: (NSRect)frameRect;9.33 - (void)setDevice: (maple_device_t)device;9.34 @@ -214,21 +220,25 @@9.35 }9.36 - (void)controlTextDidChange: (NSNotification *)notify9.37 {9.38 + const gchar *p = NULL;9.39 int binding = [[notify object] tag];9.40 NSString *val1 = [field[binding][0] stringValue];9.41 - NSString *val2 = [field[binding][1] stringValue];9.42 - char buf[ [val1 length] + [val2 length] + 2 ];9.43 - const gchar *p = NULL;9.44 -9.45 - if( [val1 length] == 0 ) {9.46 - if( [val2 length] != 0 ) {9.47 - p = [val2 UTF8String];9.48 - }9.49 - } else if( [val2 length] == 0 ) {9.50 + if( field[binding][1] == NULL ) {9.51 p = [val1 UTF8String];9.52 } else {9.53 - sprintf( buf, "%s,%s", [val1 UTF8String], [val2 UTF8String] );9.54 - p = buf;9.55 + NSString *val2 = [field[binding][1] stringValue];9.56 + char buf[ [val1 length] + [val2 length] + 2 ];9.57 +9.58 + if( [val1 length] == 0 ) {9.59 + if( [val2 length] != 0 ) {9.60 + p = [val2 UTF8String];9.61 + }9.62 + } else if( [val2 length] == 0 ) {9.63 + p = [val1 UTF8String];9.64 + } else {9.65 + sprintf( buf, "%s,%s", [val1 UTF8String], [val2 UTF8String] );9.66 + p = buf;9.67 + }9.68 }9.69 maple_set_device_config_value( device, binding, p );9.70 lxdream_save_config();9.71 @@ -237,7 +247,7 @@9.72 {9.73 device = newDevice;9.74 [self removeSubviews];9.75 - if( device != NULL ) {9.76 + if( device != NULL && !MAPLE_IS_VMU(device) ) {9.77 lxdream_config_entry_t config = maple_get_device_config(device);9.78 if( config != NULL ) {9.79 int count, i, y, x;9.80 @@ -249,35 +259,51 @@9.81 [self scrollRectToVisible: NSMakeRect(0,0,1,1)];9.82 y = TEXT_GAP;9.83 for( i=0; config[i].key != NULL; i++ ) {9.84 + /* Add label */9.85 NSRect frame = NSMakeRect(x, y + 2, 85, LABEL_HEIGHT);9.86 NSTextField *label = cocoa_gui_add_label(self, NS_(config[i].label), frame);9.87 [label setAlignment: NSRightTextAlignment];9.88 +9.89 + switch(config[i].type) {9.90 + case CONFIG_TYPE_KEY:9.91 + frame = NSMakeRect( x + 85 + TEXT_GAP, y, KEYBINDING_SIZE, TEXT_HEIGHT);9.92 + field[i][0] = [[KeyBindingField alloc] initWithFrame: frame];9.93 + [field[i][0] setAutoresizingMask: (NSViewMinYMargin|NSViewMaxXMargin)];9.94 + [field[i][0] setTag: i];9.95 + [field[i][0] setDelegate: self];9.96 + [self addSubview: field[i][0]];9.98 - frame = NSMakeRect( x + 85 + TEXT_GAP, y, KEYBINDING_SIZE, TEXT_HEIGHT);9.99 - field[i][0] = [[KeyBindingField alloc] initWithFrame: frame];9.100 - [field[i][0] setAutoresizingMask: (NSViewMinYMargin|NSViewMaxXMargin)];9.101 - [field[i][0] setTag: i];9.102 - [field[i][0] setDelegate: self];9.103 - [self addSubview: field[i][0]];9.104 -9.105 - frame = NSMakeRect( x + 85 + KEYBINDING_SIZE + (TEXT_GAP*2), y, KEYBINDING_SIZE, TEXT_HEIGHT);9.106 - field[i][1] = [[KeyBindingField alloc] initWithFrame: frame];9.107 - [field[i][1] setAutoresizingMask: (NSViewMinYMargin|NSViewMaxXMargin)];9.108 - [field[i][1] setTag: i];9.109 - [field[i][1] setDelegate: self];9.110 - [self addSubview: field[i][1]];9.111 + frame = NSMakeRect( x + 85 + KEYBINDING_SIZE + (TEXT_GAP*2), y, KEYBINDING_SIZE, TEXT_HEIGHT);9.112 + field[i][1] = [[KeyBindingField alloc] initWithFrame: frame];9.113 + [field[i][1] setAutoresizingMask: (NSViewMinYMargin|NSViewMaxXMargin)];9.114 + [field[i][1] setTag: i];9.115 + [field[i][1] setDelegate: self];9.116 + [self addSubview: field[i][1]];9.118 - if( config[i].value != NULL ) {9.119 - gchar **parts = g_strsplit(config[i].value,",",3);9.120 - if( parts[0] != NULL ) {9.121 - [field[i][0] setStringValue: [NSString stringWithCString: parts[0]]];9.122 - if( parts[1] != NULL ) {9.123 - [field[i][1] setStringValue: [NSString stringWithCString: parts[1]]];9.124 + if( config[i].value != NULL ) {9.125 + gchar **parts = g_strsplit(config[i].value,",",3);9.126 + if( parts[0] != NULL ) {9.127 + [field[i][0] setStringValue: [NSString stringWithCString: parts[0]]];9.128 + if( parts[1] != NULL ) {9.129 + [field[i][1] setStringValue: [NSString stringWithCString: parts[1]]];9.130 + }9.131 }9.132 + g_strfreev(parts);9.133 }9.134 - g_strfreev(parts);9.135 - }9.136 -9.137 + break;9.138 + case CONFIG_TYPE_FILE:9.139 + case CONFIG_TYPE_PATH:9.140 + frame = NSMakeRect( x + 85 + TEXT_GAP, y, KEYBINDING_SIZE*2+TEXT_GAP, TEXT_HEIGHT);9.141 + field[i][0] = [[NSTextField alloc] initWithFrame: frame];9.142 + [field[i][0] setAutoresizingMask: (NSViewMinYMargin|NSViewMaxXMargin)];9.143 + [field[i][0] setTag: i];9.144 + [field[i][0] setDelegate: self];9.145 + [self addSubview: field[i][0]];9.146 + if( config[i].value != NULL ) {9.147 + [field[i][0] setStringValue: [NSString stringWithCString: config[i].value]];9.148 + }9.149 + field[i][1] = NULL;9.150 + }9.151 y += (TEXT_HEIGHT + TEXT_GAP);9.152 }9.153 } else {9.154 @@ -290,16 +316,176 @@9.155 @end9.157 /*************************** Top-level controller pane ***********************/9.158 +static NSButton *addRadioButton( int port, int sub, int x, int y, id parent )9.159 +{9.160 + char buf[16];9.161 +9.162 + if( sub == 0 ) {9.163 + snprintf( buf, sizeof(buf), _("Port %c."), 'A'+port );9.164 + } else {9.165 + snprintf( buf, sizeof(buf), _("VMU %d."), sub );9.166 + }9.167 +9.168 + NSButton *radio = [[NSButton alloc] initWithFrame: NSMakeRect( x, y, 60, TEXT_HEIGHT )];9.169 + [radio setTitle: [NSString stringWithUTF8String: buf]];9.170 + [radio setTag: MAPLE_DEVID(port,sub) ];9.171 + [radio setButtonType: NSRadioButton];9.172 + [radio setAlignment: NSRightTextAlignment];9.173 + [radio setTarget: parent];9.174 + [radio setAction: @selector(radioChanged:)];9.175 + [radio setAutoresizingMask: (NSViewMinYMargin|NSViewMaxXMargin)];9.176 + [parent addSubview: radio];9.177 + return radio;9.178 +}9.179 +9.180 +static void setDevicePopupSelection( NSPopUpButton *popup, maple_device_t device )9.181 +{9.182 + if( device == NULL ) {9.183 + [popup selectItemAtIndex: 0];9.184 + } else if( MAPLE_IS_VMU(device) ) {9.185 + int idx = vmulist_get_index_by_filename( MAPLE_VMU_NAME(device) );9.186 + if( idx == -1 ) {9.187 + [popup selectItemAtIndex: 0];9.188 + } else {9.189 + [popup selectItemWithTag: FIRST_VMU_TAG + idx];9.190 + }9.191 + } else {9.192 + const struct maple_device_class **devices = maple_get_device_classes();9.193 + int i;9.194 + for( i=0; devices[i] != NULL; i++ ) {9.195 + if( devices[i] == device->device_class ) {9.196 + [popup selectItemWithTag: i+1];9.197 + return;9.198 + }9.199 + }9.200 + // Should never get here, but if so...9.201 + [popup selectItemAtIndex: 0];9.202 + }9.203 +}9.204 +9.205 +static void buildDevicePopupMenu( NSPopUpButton *popup, maple_device_t device, BOOL primary )9.206 +{9.207 + int j;9.208 + const struct maple_device_class **devices = maple_get_device_classes();9.209 +9.210 + [popup removeAllItems];9.211 + [popup addItemWithTitle: NS_("<empty>")];9.212 + [[popup itemAtIndex: 0] setTag: 0];9.213 + for( j=0; devices[j] != NULL; j++ ) {9.214 + int isPrimaryDevice = devices[j]->flags & MAPLE_TYPE_PRIMARY;9.215 + if( primary ? isPrimaryDevice : (!isPrimaryDevice && !MAPLE_IS_VMU_CLASS(devices[j])) ) {9.216 + [popup addItemWithTitle: [NSString stringWithUTF8String: devices[j]->name]];9.217 + if( device != NULL && device->device_class == devices[j] ) {9.218 + [popup selectItemAtIndex: ([popup numberOfItems]-1)];9.219 + }9.220 + [[popup itemAtIndex: ([popup numberOfItems]-1)] setTag: (j+1)];9.221 + }9.222 + }9.223 +9.224 + if( !primary ) {9.225 + BOOL vmu_selected = NO;9.226 + const char *vmu_name;9.227 + if( device != NULL && MAPLE_IS_VMU(device) ) {9.228 + vmu_selected = YES;9.229 + vmu_name = MAPLE_VMU_NAME(device);9.230 + }9.231 + if( [popup numberOfItems] > 0 ) {9.232 + [[popup menu] addItem: [NSMenuItem separatorItem]];9.233 + }9.234 +9.235 + unsigned int vmu_count = vmulist_get_size();9.236 + for( j=0; j<vmu_count; j++ ) {9.237 + const char *name = vmulist_get_name(j);9.238 + [popup addItemWithTitle: [NSString stringWithUTF8String: name]];9.239 + if( vmu_selected && strcmp(vmu_name, vmulist_get_filename(j)) == 0 ) {9.240 + [popup selectItemAtIndex: ([popup numberOfItems]-1)];9.241 + }9.242 + [[popup itemAtIndex: ([popup numberOfItems]-1)] setTag: FIRST_VMU_TAG + j];9.243 + }9.244 +9.245 + [popup addItemWithTitle: NS_("Load VMU...")];9.246 + [[popup itemAtIndex: ([popup numberOfItems]-1)] setTag: LOAD_VMU_TAG];9.247 + [popup addItemWithTitle: NS_("Create VMU...")];9.248 + [[popup itemAtIndex: ([popup numberOfItems]-1)] setTag: CREATE_VMU_TAG];9.249 + }9.250 +9.251 +}9.252 +9.253 +static NSPopUpButton *addDevicePopup( int port, int sub, int x, int y, maple_device_t device, BOOL primary, id parent )9.254 +{9.255 + NSPopUpButton *popup = [[NSPopUpButton alloc] initWithFrame: NSMakeRect(x,y,150,TEXT_HEIGHT)9.256 + pullsDown: NO];9.257 + [popup setAutoresizingMask: (NSViewMinYMargin|NSViewMaxXMargin)];9.258 + buildDevicePopupMenu(popup,device,primary);9.259 +9.260 + [popup setTarget: parent];9.261 + [popup setAction: @selector(deviceChanged:)];9.262 + [popup setTag: MAPLE_DEVID(port,sub) ];9.263 + [parent addSubview: popup];9.264 + return popup;9.265 +}9.266 +9.267 +@interface VMULoadValidator : NSObject9.268 +{9.269 +}9.270 +- (BOOL)panel:(id) sender isValidFilename: (NSString *)filename;9.271 +@end9.272 +9.273 +@implementation VMULoadValidator9.274 +- (BOOL)panel:(id) sender isValidFilename: (NSString *)filename9.275 +{9.276 + const char *c_fn = [filename UTF8String];9.277 + vmu_volume_t vol = vmu_volume_load( c_fn );9.278 + if( vol != NULL ) {9.279 + vmulist_add_vmu(c_fn, vol);9.280 + return YES;9.281 + } else {9.282 + ERROR( "Unable to load VMU file (not a valid VMU)" );9.283 + return NO;9.284 + }9.285 +}9.286 +9.287 +@end9.288 +9.289 +@interface VMUCreateValidator : NSObject9.290 +{9.291 +}9.292 +- (BOOL)panel:(id) sender isValidFilename: (NSString *)filename;9.293 +@end9.294 +9.295 +@implementation VMUCreateValidator9.296 +- (BOOL)panel:(id) sender isValidFilename: (NSString *)filename9.297 +{9.298 + const char *vmu_filename = [filename UTF8String];9.299 + int idx = vmulist_create_vmu(vmu_filename, FALSE);9.300 + if( idx == -1 ) {9.301 + ERROR( "Unable to create file: %s\n", strerror(errno) );9.302 + return NO;9.303 + } else {9.304 + return YES;9.305 + }9.306 +}9.307 +@end9.308 +9.310 @interface LxdreamPrefsControllerPane: LxdreamPrefsPane9.311 {9.312 - struct maple_device *save_controller[4];9.313 - NSButton *radio[4];9.314 + struct maple_device *save_controller[MAPLE_MAX_DEVICES];9.315 + NSButton *radio[MAPLE_MAX_DEVICES];9.316 + NSPopUpButton *popup[MAPLE_MAX_DEVICES];9.317 ControllerKeyBindingView *key_bindings;9.318 }9.319 + (LxdreamPrefsControllerPane *)new;9.320 +- (void)vmulistChanged: (id)sender;9.321 @end9.323 +static gboolean cocoa_config_vmulist_hook(vmulist_change_type_t type, int idx, void *data)9.324 +{9.325 + LxdreamPrefsControllerPane *pane = (LxdreamPrefsControllerPane *)data;9.326 + [pane vmulistChanged: nil];9.327 + return TRUE;9.328 +}9.329 +9.330 @implementation LxdreamPrefsControllerPane9.331 + (LxdreamPrefsControllerPane *)new9.332 {9.333 @@ -310,11 +496,11 @@9.334 if( [super initWithFrame: frameRect title: NS_("Controllers")] == nil ) {9.335 return nil;9.336 } else {9.337 - const struct maple_device_class **devices = maple_get_device_classes();9.338 - char buf[16];9.339 int i,j;9.340 int y = [self contentHeight] - TEXT_HEIGHT - TEXT_GAP;9.342 + memset( radio, 0, sizeof(radio) );9.343 + memset( save_controller, 0, sizeof(save_controller) );9.344 NSBox *rule = [[NSBox alloc] initWithFrame:9.345 NSMakeRect(210+(TEXT_GAP*3), 1, 1, [self contentHeight] + TEXT_GAP - 2)];9.346 [rule setAutoresizingMask: (NSViewMaxXMargin|NSViewHeightSizable)];9.347 @@ -334,96 +520,158 @@9.348 [self addSubview: scrollView];9.349 [key_bindings setDevice: maple_get_device(0,0)];9.351 - for( i=0; i<MAX_DEVICES; i++ ) {9.352 - int x = TEXT_GAP;9.353 - save_controller[i] = NULL;9.354 + for( i=0; i<MAPLE_PORTS; i++ ) {9.355 maple_device_t device = maple_get_device(i,0);9.357 - snprintf( buf, sizeof(buf), _("Slot %d."), i );9.358 - radio[i] = [[NSButton alloc] initWithFrame: NSMakeRect( x, y, 60, TEXT_HEIGHT )];9.359 - [radio[i] setTitle: [NSString stringWithUTF8String: buf]];9.360 - [radio[i] setTag: i];9.361 - [radio[i] setButtonType: NSRadioButton];9.362 - [radio[i] setAlignment: NSRightTextAlignment];9.363 - [radio[i] setTarget: self];9.364 - [radio[i] setAction: @selector(radioChanged:)];9.365 - [radio[i] setAutoresizingMask: (NSViewMinYMargin|NSViewMaxXMargin)];9.366 - [self addSubview: radio[i]];9.367 - x += 60 + TEXT_GAP;9.368 -9.369 - NSPopUpButton *popup = [[NSPopUpButton alloc] initWithFrame: NSMakeRect(x,y,150,TEXT_HEIGHT)9.370 - pullsDown: NO];9.371 - [popup addItemWithTitle: NS_("<empty>")];9.372 - [popup setAutoresizingMask: (NSViewMinYMargin|NSViewMaxXMargin)];9.373 - [[popup itemAtIndex: 0] setTag: 0];9.374 - for( j=0; devices[j] != NULL; j++ ) {9.375 - [popup addItemWithTitle: [NSString stringWithUTF8String: devices[j]->name]];9.376 - if( device != NULL && device->device_class == devices[j] ) {9.377 - [popup selectItemAtIndex: (j+1)];9.378 + radio[i] = addRadioButton(i,0,TEXT_GAP,y,self);9.379 + popup[i] = addDevicePopup(i,0,60 + (TEXT_GAP*2),y,device, YES,self);9.380 + y -= (TEXT_HEIGHT+TEXT_GAP);9.381 +9.382 + int j,max = device == NULL ? 0 : MAPLE_SLOTS(device->device_class);9.383 + for( j=1; j<=MAPLE_USER_SLOTS; j++ ) {9.384 + radio[MAPLE_DEVID(i,j)] = addRadioButton(i, j, TEXT_GAP*2, y, self);9.385 + popup[MAPLE_DEVID(i,j)] = addDevicePopup(i, j, 60 + TEXT_GAP*2, y, maple_get_device(i,j), NO, self);9.386 + y -= (TEXT_HEIGHT+TEXT_GAP);9.387 + if( j > max ) {9.388 + [radio[MAPLE_DEVID(i,j)] setEnabled: NO];9.389 + [popup[MAPLE_DEVID(i,j)] setEnabled: NO];9.390 }9.391 - [[popup itemAtIndex: (j+1)] setTag: (j+1)];9.392 }9.393 - [popup setTarget: self];9.394 - [popup setAction: @selector(deviceChanged:)];9.395 - [popup setTag: i];9.396 - [self addSubview: popup];9.397 - y -= (TEXT_HEIGHT+TEXT_GAP);9.398 }9.400 [radio[0] setState: NSOnState];9.401 +9.402 + register_vmulist_change_hook(cocoa_config_vmulist_hook, self);9.403 return self;9.404 }9.405 }9.406 +- (void)dealloc9.407 +{9.408 + unregister_vmulist_change_hook(cocoa_config_vmulist_hook,self);9.409 + [super dealloc];9.410 +}9.411 +- (void)vmulistChanged: (id)sender9.412 +{9.413 + int i;9.414 + for( i=FIRST_SECONDARY_DEVICE; i<MAPLE_MAX_DEVICES; i++ ) {9.415 + if( popup[i] != NULL ) {9.416 + buildDevicePopupMenu(popup[i], maple_get_device(MAPLE_DEVID_PORT(i), MAPLE_DEVID_SLOT(i)), NO );9.417 + }9.418 + }9.419 +}9.420 - (void)radioChanged: (id)sender9.421 {9.422 - int slot = [sender tag];9.423 + int tag = [sender tag];9.424 int i;9.425 - for( i=0; i<MAX_DEVICES; i++ ) {9.426 - if( i != slot ) {9.427 + for( i=0; i<MAPLE_MAX_DEVICES; i++ ) {9.428 + if( i != tag && radio[i] != NULL ) {9.429 [radio[i] setState: NSOffState];9.430 }9.431 }9.432 - [key_bindings setDevice: maple_get_device(slot,0)];9.433 + [key_bindings setDevice: maple_get_device(MAPLE_DEVID_PORT(tag),MAPLE_DEVID_SLOT(tag))];9.434 }9.435 - (void)deviceChanged: (id)sender9.436 {9.437 - int slot = [sender tag];9.438 - int new_device_idx = [sender indexOfSelectedItem] - 1, i;9.439 + int tag = [sender tag];9.440 + int port = MAPLE_DEVID_PORT(tag);9.441 + int slot = MAPLE_DEVID_SLOT(tag);9.442 + int new_device_idx = [[sender selectedItem] tag], i;9.443 maple_device_class_t new_device_class = NULL;9.444 + const gchar *vmu_filename = NULL;9.446 - for( i=0; i<MAX_DEVICES; i++ ) {9.447 - if( i == slot ) {9.448 - [radio[i] setState: NSOnState];9.449 - } else {9.450 - [radio[i] setState: NSOffState];9.451 + for( i=0; i<MAPLE_MAX_DEVICES; i++ ) {9.452 + if( radio[i] != NULL ) {9.453 + if( i == tag ) {9.454 + [radio[i] setState: NSOnState];9.455 + } else {9.456 + [radio[i] setState: NSOffState];9.457 + }9.458 }9.459 }9.461 - maple_device_t current = maple_get_device(slot,0);9.462 + maple_device_t current = maple_get_device(port,slot);9.463 maple_device_t new_device = NULL;9.464 - if( new_device_idx != -1 ) {9.465 - new_device_class = maple_get_device_classes()[new_device_idx];9.466 + if( new_device_idx == LOAD_VMU_TAG ) {9.467 + NSArray *array = [NSArray arrayWithObjects: @"vmu", nil];9.468 + NSOpenPanel *panel = [NSOpenPanel openPanel];9.469 + VMULoadValidator *valid = [[VMULoadValidator alloc] autorelease];9.470 + [panel setDelegate: valid];9.471 + NSInteger result = [panel runModalForDirectory: [NSString stringWithUTF8String: lxdream_get_config_value(CONFIG_VMU_PATH)]9.472 + file: nil types: array];9.473 + if( result == NSOKButton ) {9.474 + vmu_filename = [[panel filename] UTF8String];9.475 + int idx = vmulist_get_index_by_filename(vmu_filename);9.476 + [sender selectItemWithTag: (FIRST_VMU_TAG+idx)];9.477 + new_device_class = &vmu_class;9.478 + } else {9.479 + /* Cancelled - restore previous value */9.480 + setDevicePopupSelection( sender, current );9.481 + return;9.482 + }9.483 + } else if( new_device_idx == CREATE_VMU_TAG ) {9.484 + NSSavePanel *panel = [NSSavePanel savePanel];9.485 + [panel setTitle: NS_("Create VMU")];9.486 + [panel setCanCreateDirectories: YES];9.487 + [panel setRequiredFileType: @"vmu"];9.488 + VMUCreateValidator *valid = [[VMUCreateValidator alloc] autorelease];9.489 + [panel setDelegate: valid];9.490 + NSInteger result = [panel runModalForDirectory: [NSString stringWithUTF8String: lxdream_get_config_value(CONFIG_VMU_PATH)]9.491 + file: nil];9.492 + if( result == NSFileHandlingPanelOKButton ) {9.493 + /* Validator has already created the file by now */9.494 + vmu_filename = [[panel filename] UTF8String];9.495 + int idx = vmulist_get_index_by_filename(vmu_filename);9.496 + [sender selectItemWithTag: (FIRST_VMU_TAG+idx)];9.497 + new_device_class = &vmu_class;9.498 + } else {9.499 + setDevicePopupSelection( sender, current );9.500 + return;9.501 + }9.502 + } else if( new_device_idx >= FIRST_VMU_TAG ) {9.503 + vmu_filename = vmulist_get_filename( new_device_idx - FIRST_VMU_TAG );9.504 + new_device_class = &vmu_class;9.505 + } else if( new_device_idx > 0) {9.506 + new_device_class = maple_get_device_classes()[new_device_idx-1];9.507 }9.508 - if( current == NULL ? new_device_class == NULL : current->device_class == new_device_class ) {9.509 +9.510 + if( current == NULL ? new_device_class == NULL :9.511 + (current->device_class == new_device_class &&9.512 + (!MAPLE_IS_VMU(current) || MAPLE_VMU_HAS_NAME(current, vmu_filename))) ) {9.513 // No change9.514 [key_bindings setDevice: current];9.515 return;9.516 }9.517 if( current != NULL && current->device_class == &controller_class ) {9.518 - save_controller[slot] = current->clone(current);9.519 + save_controller[tag] = current->clone(current);9.520 }9.521 if( new_device_class == NULL ) {9.522 - maple_detach_device(slot,0);9.523 + maple_detach_device(port,slot);9.524 } else {9.525 - if( new_device_class == &controller_class && save_controller[slot] != NULL ) {9.526 - new_device = save_controller[slot];9.527 - save_controller[slot] = NULL;9.528 + if( new_device_class == &controller_class && save_controller[tag] != NULL ) {9.529 + new_device = save_controller[tag];9.530 + save_controller[tag] = NULL;9.531 } else {9.532 new_device = maple_new_device( new_device_class->name );9.533 }9.534 - maple_attach_device(new_device,slot,0);9.535 + if( MAPLE_IS_VMU(new_device) ) {9.536 + MAPLE_SET_VMU_NAME(new_device,vmu_filename);9.537 + }9.538 + maple_attach_device(new_device,port,slot);9.539 }9.540 - [key_bindings setDevice: maple_get_device(slot,0)];9.541 + [key_bindings setDevice: maple_get_device(port,slot)];9.542 +9.543 + if( slot == 0 ) { /* Change primary */9.544 + int max = new_device_class == NULL ? 0 : MAPLE_SLOTS(new_device_class);9.545 + for( i=1; i<=MAPLE_USER_SLOTS; i++ ) {9.546 + if( i <= max ) {9.547 + [radio[MAPLE_DEVID(port,i)] setEnabled: YES];9.548 + [popup[MAPLE_DEVID(port,i)] setEnabled: YES];9.549 + } else {9.550 + [radio[MAPLE_DEVID(port,i)] setEnabled: NO];9.551 + [popup[MAPLE_DEVID(port,i)] setEnabled: NO];9.552 + }9.553 + }9.554 + }9.555 lxdream_save_config();9.556 }9.557 @end
10.1 --- a/src/cocoaui/cocoa_prefs.m Wed Jun 24 02:27:34 2009 +000010.2 +++ b/src/cocoaui/cocoa_prefs.m Wed Jun 24 02:41:12 2009 +000010.3 @@ -184,7 +184,7 @@10.4 void cocoa_gui_show_preferences()10.5 {10.6 if( prefs_panel == NULL ) {10.7 - prefs_panel = [[LxdreamPrefsPanel alloc] initWithContentRect: NSMakeRect(0,0,640,400)];10.8 + prefs_panel = [[LxdreamPrefsPanel alloc] initWithContentRect: NSMakeRect(0,0,640,540)];10.9 }10.10 [prefs_panel makeKeyAndOrderFront: prefs_panel];10.11 }10.12 \ No newline at end of file
11.1 --- a/src/config.c Wed Jun 24 02:27:34 2009 +000011.2 +++ b/src/config.c Wed Jun 24 02:41:12 2009 +000011.3 @@ -42,9 +42,11 @@11.4 { "flash", N_("Flash ROM"), CONFIG_TYPE_FILE, "dcflash.rom" },11.5 { "default path", N_("Default disc path"), CONFIG_TYPE_PATH, "." },11.6 { "save path", N_("Save-state path"), CONFIG_TYPE_PATH, "save" },11.7 + { "vmu path", N_("VMU path"), CONFIG_TYPE_PATH, "vmu" },11.8 { "bootstrap", N_("Bootstrap IP.BIN"), CONFIG_TYPE_FILE, "IP.BIN" },11.9 { "gdrom", NULL, CONFIG_TYPE_FILE, NULL },11.10 - { "recent", NULL, CONFIG_TYPE_FILE, NULL },11.11 + { "recent", NULL, CONFIG_TYPE_FILELIST, NULL },11.12 + { "vmu", NULL, CONFIG_TYPE_FILELIST, NULL },11.13 { NULL, CONFIG_TYPE_NONE }};11.15 static struct lxdream_config_entry serial_config[] =11.16 @@ -139,6 +141,42 @@11.17 return global_config[key].value;11.18 }11.20 +GList *lxdream_get_global_config_list_value( int key )11.21 +{11.22 + GList *result = NULL;11.23 + const gchar *str = lxdream_get_config_value( key );11.24 + if( str != NULL ) {11.25 + gchar **strv = g_strsplit(str, ":",0);11.26 + int i;11.27 + for( i=0; strv[i] != NULL; i++ ) {11.28 + result = g_list_append( result, g_strdup(strv[i]) );11.29 + }11.30 + g_strfreev(strv);11.31 + }11.32 + return result;11.33 +}11.34 +11.35 +void lxdream_set_global_config_list_value( int key, const GList *list )11.36 +{11.37 + if( list == NULL ) {11.38 + lxdream_set_global_config_value( key, NULL );11.39 + } else {11.40 + GList *ptr;11.41 + int size = 0;11.42 +11.43 + for( ptr = list; ptr != NULL; ptr = g_list_next(ptr) ) {11.44 + size += strlen( (gchar *)ptr->data ) + 1;11.45 + }11.46 + char buf[size];11.47 + strcpy( buf, (gchar *)list->data );11.48 + for( ptr = g_list_next(list); ptr != NULL; ptr = g_list_next(ptr) ) {11.49 + strcat( buf, ":" );11.50 + strcat( buf, (gchar *)ptr->data );11.51 + }11.52 + lxdream_set_global_config_value( key, buf );11.53 + }11.54 +}11.55 +11.56 void lxdream_set_config_value( lxdream_config_entry_t param, const gchar *value )11.57 {11.58 if( param->value != value ) {
12.1 --- a/src/config.h Wed Jun 24 02:27:34 2009 +000012.2 +++ b/src/config.h Wed Jun 24 02:41:12 2009 +000012.3 @@ -20,6 +20,7 @@12.4 #define lxdream_config_H 112.6 #include <glib/gtypes.h>12.7 +#include <glib/glist.h>12.8 #include "gettext.h"12.10 #ifdef __cplusplus12.11 @@ -30,6 +31,7 @@12.12 #define CONFIG_TYPE_FILE 112.13 #define CONFIG_TYPE_PATH 212.14 #define CONFIG_TYPE_KEY 312.15 +#define CONFIG_TYPE_FILELIST 412.17 #define DEFAULT_CONFIG_FILENAME "lxdreamrc"12.19 @@ -50,10 +52,12 @@12.20 #define CONFIG_FLASH_PATH 112.21 #define CONFIG_DEFAULT_PATH 212.22 #define CONFIG_SAVE_PATH 312.23 -#define CONFIG_BOOTSTRAP 412.24 -#define CONFIG_GDROM 512.25 -#define CONFIG_RECENT 612.26 -#define CONFIG_KEY_MAX CONFIG_RECENT12.27 +#define CONFIG_VMU_PATH 412.28 +#define CONFIG_BOOTSTRAP 512.29 +#define CONFIG_GDROM 612.30 +#define CONFIG_RECENT 712.31 +#define CONFIG_VMU 812.32 +#define CONFIG_KEY_MAX CONFIG_VMU12.34 extern struct lxdream_config_group lxdream_config_root[];12.36 @@ -67,6 +71,16 @@12.37 void lxdream_copy_config_list( lxdream_config_entry_t dest, lxdream_config_entry_t src );12.39 /**12.40 + * Construct a list of strings for the given config key - The caller is12.41 + * responsible for freeing the list and its values.12.42 + */12.43 +GList *lxdream_get_global_config_list_value( int key );12.44 +12.45 +/**12.46 + * Set a config key based on a list of strings.12.47 + */12.48 +void lxdream_set_global_config_list_value( int key, const GList *list );12.49 +/**12.50 * Search the standard locations for the configuration file:12.51 * $HOME/.lxdreamrc12.52 * $CWD/lxdreamrc
13.1 --- a/src/dreamcast.c Wed Jun 24 02:27:34 2009 +000013.2 +++ b/src/dreamcast.c Wed Jun 24 02:41:12 2009 +000013.3 @@ -32,6 +32,7 @@13.4 #include "pvr2/pvr2.h"13.5 #include "sh4/sh4.h"13.6 #include "sh4/sh4core.h"13.7 +#include "vmu/vmulist.h"13.9 /**13.10 * Current state of the DC virtual machine13.11 @@ -242,6 +243,8 @@13.12 if( modules[i]->stop != NULL )13.13 modules[i]->stop();13.14 }13.15 +13.16 + vmulist_save_all();13.17 dreamcast_state = STATE_STOPPED;13.19 if( dreamcast_exit_on_stop ) {13.20 @@ -264,6 +267,7 @@13.21 if( dreamcast_state == STATE_RUNNING )13.22 dreamcast_state = STATE_STOPPING;13.23 dreamcast_save_flash();13.24 + vmulist_save_all();13.25 #ifdef ENABLE_SH4STATS13.26 sh4_stats_print(stdout);13.27 #endif
14.1 --- a/src/gdlist.c Wed Jun 24 02:27:34 2009 +000014.2 +++ b/src/gdlist.c Wed Jun 24 02:41:12 2009 +000014.3 @@ -65,18 +65,7 @@14.4 */14.5 void gdrom_list_update_config()14.6 {14.7 - GList *ptr;14.8 - int size = 0;14.9 - for( ptr = gdrom_recent_list; ptr != NULL; ptr = g_list_next(ptr) ) {14.10 - size += strlen( (gchar *)ptr->data ) + 1;14.11 - }14.12 - char buf[size];14.13 - strcpy( buf, (gchar *)gdrom_recent_list->data );14.14 - for( ptr = g_list_next(gdrom_recent_list); ptr != NULL; ptr = g_list_next(ptr) ) {14.15 - strcat( buf, ":" );14.16 - strcat( buf, (gchar *)ptr->data );14.17 - }14.18 - lxdream_set_global_config_value( CONFIG_RECENT, buf );14.19 + lxdream_set_global_config_list_value( CONFIG_RECENT, gdrom_recent_list );14.20 }14.23 @@ -146,17 +135,9 @@14.25 void gdrom_list_init()14.26 {14.27 - const gchar *recent = lxdream_get_config_value( CONFIG_RECENT );14.28 + gdrom_recent_list = lxdream_get_global_config_list_value( CONFIG_RECENT );14.29 register_gdrom_disc_change_hook( gdrom_list_disc_changed, NULL );14.30 gdrom_device_list = cdrom_get_native_devices();14.31 - if( recent != NULL ) {14.32 - gchar **list = g_strsplit(recent, ":", MAX_RECENT_ITEMS);14.33 - int i;14.34 - for( i=0; list[i] != NULL; i++ ) {14.35 - gdrom_recent_list = g_list_append( gdrom_recent_list, g_strdup(list[i]) );14.36 - }14.37 - g_strfreev(list);14.38 - }14.39 gdrom_device_count = g_list_length(gdrom_device_list);14.40 gdrom_recent_count = g_list_length(gdrom_recent_list);
15.1 --- a/src/gtkui/gtk_ctrl.c Wed Jun 24 02:27:34 2009 +000015.2 +++ b/src/gtkui/gtk_ctrl.c Wed Jun 24 02:41:12 2009 +000015.3 @@ -19,6 +19,7 @@15.5 #include <assert.h>15.6 #include <string.h>15.7 +#include <errno.h>15.8 #include <gtk/gtk.h>15.9 #include <gdk/gdkkeysyms.h>15.11 @@ -26,10 +27,15 @@15.12 #include "display.h"15.13 #include "gtkui/gtkui.h"15.14 #include "maple/maple.h"15.15 +#include "vmu/vmulist.h"15.17 #define MAX_DEVICES 415.19 +#define LOAD_VMU_TAG ((void *)-1)15.20 +#define CREATE_VMU_TAG ((void *)-2)15.21 +15.22 static void controller_device_configure(maple_device_t device);15.23 +static void maple_set_device_selection( GtkWidget *combo, maple_device_t device );15.25 struct maple_config_class {15.26 const char *name;15.27 @@ -41,14 +47,16 @@15.28 maple_device_t new_device;15.29 GtkWidget *button;15.30 GtkWidget *combo;15.31 + gboolean primarySlot;15.32 } *maple_slot_data_t;15.34 +15.35 static struct maple_config_class maple_device_config[] = {15.36 { "Sega Controller", controller_device_configure },15.37 { "Sega Lightgun", controller_device_configure },15.38 { NULL, NULL } };15.40 -static struct maple_slot_data maple_data[MAX_DEVICES];15.41 +static struct maple_slot_data maple_data[MAPLE_MAX_DEVICES];15.43 static void config_keysym_hook( void *data, const gchar *keysym )15.44 {15.45 @@ -201,7 +209,7 @@15.46 gtk_gui_run_property_dialog( _("Controller Configuration"), table, controller_config_done );15.47 }15.49 -gboolean maple_properties_activated( GtkButton *button, gpointer user_data )15.50 +static gboolean maple_properties_activated( GtkButton *button, gpointer user_data )15.51 {15.52 maple_slot_data_t data = (maple_slot_data_t)user_data;15.53 if( data->new_device != NULL ) {15.54 @@ -223,26 +231,76 @@15.55 return TRUE;15.56 }15.58 -gboolean maple_device_changed( GtkComboBox *combo, gpointer user_data )15.59 +static gboolean maple_device_changed( GtkComboBox *combo, gpointer user_data )15.60 {15.61 maple_slot_data_t data = (maple_slot_data_t)user_data;15.62 - int active = gtk_combo_box_get_active(combo);15.63 + int active = gtk_combo_box_get_active(combo), i;15.64 gboolean has_config = FALSE;15.65 + gboolean set_selection = FALSE;15.66 + int has_slots = 0;15.67 if( active != 0 ) {15.68 - gchar *devname = gtk_combo_box_get_active_text(combo);15.69 - const maple_device_class_t devclz = maple_get_device_class(devname);15.70 - assert(devclz != NULL);15.71 + GtkTreeIter iter;15.72 + maple_device_class_t devclz;15.73 + const gchar *vmu_filename;15.74 +15.75 + GtkTreeModel *model = gtk_combo_box_get_model(combo);15.76 + gtk_combo_box_get_active_iter(combo, &iter);15.77 + gtk_tree_model_get(model, &iter, 1, &devclz, 2, &vmu_filename, -1 );15.78 +15.79 + if( devclz == LOAD_VMU_TAG ) {15.80 + devclz = NULL;15.81 + vmu_filename = open_file_dialog( _("Load VMU"), "*.vmu", "VMU Files",15.82 + lxdream_get_config_value(CONFIG_VMU_PATH) );15.83 + if( vmu_filename != NULL ) {15.84 + vmu_volume_t vol = vmu_volume_load( vmu_filename );15.85 + if( vol != NULL ) {15.86 + devclz = &vmu_class;15.87 + vmulist_add_vmu(vmu_filename, vol);15.88 + set_selection = TRUE;15.89 + } else {15.90 + ERROR( "Unable to load VMU file (not a valid VMU)" );15.91 + }15.92 + }15.93 + } else if( devclz == CREATE_VMU_TAG ) {15.94 + devclz = NULL;15.95 + vmu_filename = save_file_dialog( _("Create VMU"), "*.vmu", "VMU Files",15.96 + lxdream_get_config_value(CONFIG_VMU_PATH) );15.97 + if( vmu_filename != NULL ) {15.98 + devclz = &vmu_class;15.99 + set_selection = TRUE;15.100 + int idx = vmulist_create_vmu( vmu_filename, FALSE );15.101 + if( idx == -1 ) {15.102 + ERROR( "Unable to save VMU file: %s", strerror(errno) );15.103 + }15.104 + }15.105 + } else if( vmu_filename != NULL ) {15.106 + devclz = &vmu_class;15.107 + }15.108 +15.109 + if( devclz == NULL ) {15.110 + maple_set_device_selection(data->combo, data->new_device);15.111 + return TRUE;15.112 + }15.113 +15.114 if( data->new_device != NULL ) {15.115 if( data->new_device->device_class != devclz ) {15.116 if( data->new_device != data->old_device ) {15.117 data->new_device->destroy(data->new_device);15.118 }15.119 - data->new_device = maple_new_device(devname);15.120 + data->new_device = devclz->new_device();15.121 }15.122 } else {15.123 - data->new_device = maple_new_device(devname);15.124 + data->new_device = devclz->new_device();15.125 }15.126 has_config = data->new_device != NULL && data->new_device->get_config != NULL;15.127 + has_slots = data->new_device == NULL ? 0 : MAPLE_SLOTS(devclz);15.128 + if( MAPLE_IS_VMU(data->new_device) ) {15.129 + MAPLE_SET_VMU_NAME(data->new_device,vmu_filename);15.130 + }15.131 +15.132 + if( set_selection ) {15.133 + maple_set_device_selection(data->combo, data->new_device);15.134 + }15.135 } else {15.136 if( data->new_device != NULL && data->new_device != data->old_device ) {15.137 data->new_device->destroy(data->new_device);15.138 @@ -250,27 +308,146 @@15.139 data->new_device = NULL;15.140 }15.141 gtk_widget_set_sensitive(data->button, has_config);15.142 +15.143 + if( data->primarySlot ) {15.144 + for( i=0; i<MAPLE_USER_SLOTS; i++ ) {15.145 + /* This is a little morally dubious... */15.146 + maple_slot_data_t subdata = data + MAPLE_DEVID(0,(i+1));15.147 + gtk_widget_set_sensitive(subdata->combo, i < has_slots );15.148 + gtk_widget_set_sensitive(subdata->button, i < has_slots && subdata->new_device != NULL && subdata->new_device->get_config != NULL );15.149 + }15.150 + }15.151 return TRUE;15.152 }15.154 -void maple_dialog_done( GtkWidget *panel, gboolean isOK )15.155 +static void maple_build_device_model( GtkListStore *dev_model )15.156 {15.157 + const struct maple_device_class **devices = maple_get_device_classes();15.158 + int i;15.159 +15.160 + gtk_list_store_clear(dev_model);15.161 + gtk_list_store_insert_with_values( dev_model, NULL, 0, 0, _("<empty>"), 1, NULL, 2, NULL, -1 );15.162 + for( i=0; devices[i] != NULL; i++ ) {15.163 + if( devices[i]->flags & MAPLE_TYPE_PRIMARY ) {15.164 + gtk_list_store_insert_with_values( dev_model, NULL, i+1, 0, devices[i]->name, 1, devices[i], 2, NULL, -1 );15.165 + }15.166 + }15.167 +15.168 +}15.169 +15.170 +/**15.171 + * (Re)build the subdevice combo-box model.15.172 + */15.173 +static void maple_build_subdevice_model( GtkListStore *subdev_model )15.174 +{15.175 + int i, j;15.176 + const struct maple_device_class **devices = maple_get_device_classes();15.177 +15.178 + gtk_list_store_clear(subdev_model);15.179 + gtk_list_store_insert_with_values( subdev_model, NULL, 0, 0, _("<empty>"), 1, NULL, 2, NULL, -1 );15.180 + for( i=0; devices[i] != NULL; i++ ) {15.181 + if( !(devices[i]->flags & MAPLE_TYPE_PRIMARY) && !MAPLE_IS_VMU_CLASS(devices[i]) ) {15.182 + gtk_list_store_insert_with_values( subdev_model, NULL, i+1, 0, devices[i]->name, 1, devices[i], 2, NULL, -1 );15.183 + }15.184 + }15.185 + for( j=0; j < vmulist_get_size(); j++ ) {15.186 + gtk_list_store_insert_with_values( subdev_model, NULL, i+j+1, 0, vmulist_get_name(j), 1, NULL, 2, vmulist_get_filename(j), -1 );15.187 + }15.188 + gtk_list_store_insert_with_values( subdev_model, NULL, i+j+1, 0, _("Load VMU..."), 1, LOAD_VMU_TAG, 2, NULL, -1 );15.189 + gtk_list_store_insert_with_values( subdev_model, NULL, i+j+2, 0, _("Create VMU..."), 1, CREATE_VMU_TAG, 2, NULL, -1 );15.190 +}15.191 +15.192 +static gboolean maple_vmulist_changed( vmulist_change_type_t type, int idx, void *data )15.193 +{15.194 + GtkListStore *list = (GtkListStore *)data;15.195 + GtkTreeIter iter;15.196 + int i,j;15.197 +15.198 + /* Search for the row and update accordingly. There's probably better ways15.199 + * to do this15.200 + */15.201 +15.202 + gboolean valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(list), &iter);15.203 + while( valid ) {15.204 + gchar *vmu_filename;15.205 + gtk_tree_model_get(GTK_TREE_MODEL(list), &iter, 2, &vmu_filename, -1 );15.206 + if( vmu_filename != NULL )15.207 + break;15.208 + valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(list), &iter);15.209 + }15.210 + if( valid ) {15.211 + for( i=0; i<idx && valid; i++ ) {15.212 + valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(list), &iter);15.213 + }15.214 + }15.215 + if( valid ) {15.216 + if( type == VMU_ADDED ) {15.217 + GtkTreeIter newiter;15.218 + gtk_list_store_insert_before(list, &newiter, &iter);15.219 + gtk_list_store_set(list, &newiter, 0, vmulist_get_name(idx), 1, NULL, 2, vmulist_get_filename(idx), -1 );15.220 + } else if( type == VMU_REMOVED ) {15.221 + gtk_list_store_remove(list, &iter );15.222 + }15.223 + }15.224 + return TRUE;15.225 +}15.226 +15.227 +/**15.228 + * Set the device popup selection based on the device (works for both primary15.229 + * and secondary devices)15.230 + */15.231 +static void maple_set_device_selection( GtkWidget *combo, maple_device_t device )15.232 +{15.233 + GtkTreeModel *model = gtk_combo_box_get_model(GTK_COMBO_BOX(combo));15.234 + GtkTreeIter iter;15.235 +15.236 + if( device == NULL ) {15.237 + gtk_combo_box_set_active( GTK_COMBO_BOX(combo), 0 );15.238 + return;15.239 + }15.240 +15.241 + gboolean valid = gtk_tree_model_get_iter_first(model, &iter);15.242 + while( valid ) {15.243 + const struct maple_device_class *clz;15.244 + const gchar *vmu_filename;15.245 +15.246 + gtk_tree_model_get(model, &iter, 1, &clz, 2, &vmu_filename, -1 );15.247 +15.248 + if( device->device_class == clz ) {15.249 + gtk_combo_box_set_active_iter( GTK_COMBO_BOX(combo), &iter );15.250 + return;15.251 + } else if( vmu_filename != NULL && MAPLE_IS_VMU(device) &&15.252 + MAPLE_VMU_HAS_NAME(device, vmu_filename) ) {15.253 + gtk_combo_box_set_active_iter( GTK_COMBO_BOX(combo), &iter );15.254 + return;15.255 + }15.256 +15.257 + valid = gtk_tree_model_iter_next(model, &iter);15.258 + }15.259 + gtk_combo_box_set_active(GTK_COMBO_BOX(combo), 0);15.260 +}15.261 +15.262 +static void maple_dialog_done( GtkWidget *panel, gboolean isOK )15.263 +{15.264 + void *p = g_object_get_data( G_OBJECT(panel), "subdev_model" );15.265 + unregister_vmulist_change_hook( maple_vmulist_changed, p );15.266 +15.267 if( isOK ) {15.268 int i;15.269 - for( i=0; i<MAX_DEVICES; i++ ) {15.270 + for( i=0; i<MAPLE_MAX_DEVICES; i++ ) {15.271 if( maple_data[i].new_device != maple_data[i].old_device ) {15.272 if( maple_data[i].old_device != NULL ) {15.273 - maple_detach_device(i,0);15.274 + maple_detach_device(MAPLE_DEVID_PORT(i),MAPLE_DEVID_SLOT(i));15.275 }15.276 if( maple_data[i].new_device != NULL ) {15.277 - maple_attach_device(maple_data[i].new_device, i, 0 );15.278 + maple_attach_device(maple_data[i].new_device, MAPLE_DEVID_PORT(i), MAPLE_DEVID_SLOT(i) );15.279 }15.280 }15.281 }15.282 lxdream_save_config();15.283 } else {15.284 int i;15.285 - for( i=0; i<MAX_DEVICES; i++ ) {15.286 + for( i=0; i<MAPLE_MAX_DEVICES; i++ ) {15.287 if( maple_data[i].new_device != NULL &&15.288 maple_data[i].new_device != maple_data[i].old_device ) {15.289 maple_data[i].new_device->destroy(maple_data[i].new_device);15.290 @@ -280,42 +457,91 @@15.292 }15.294 -GtkWidget *maple_panel_new()15.295 +static GtkWidget *maple_panel_new()15.296 {15.297 - GtkWidget *table = gtk_table_new(4, 3, TRUE);15.298 - int i,j;15.299 + GtkWidget *table = gtk_table_new( MAPLE_PORTS * (MAPLE_USER_SLOTS+1), 3, TRUE);15.300 + int i,j,k;15.301 const struct maple_device_class **devices = maple_get_device_classes();15.303 - for( i=0; i< MAX_DEVICES; i++ ) {15.304 + gtk_table_set_row_spacings(GTK_TABLE(table), 3);15.305 + gtk_table_set_col_spacings(GTK_TABLE(table), 5);15.306 +15.307 + /* Device models */15.308 + GtkListStore *dev_model = gtk_list_store_new(3, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_STRING);15.309 + maple_build_device_model(dev_model);15.310 +15.311 + GtkListStore *subdev_model = gtk_list_store_new(3, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_STRING);15.312 + maple_build_subdevice_model(subdev_model);15.313 + g_object_set_data( G_OBJECT(table), "subdev_model", subdev_model );15.314 + register_vmulist_change_hook( maple_vmulist_changed, subdev_model );15.315 +15.316 + int y =0;15.317 + for( i=0; i< MAPLE_PORTS; i++ ) {15.318 char buf[16];15.319 GtkWidget *combo, *button;15.320 - int active = 0;15.321 + int active = 0, length = 1;15.322 maple_device_t device = maple_get_device(i,0);15.323 - snprintf( buf, sizeof(buf), _("Slot %d."), i );15.324 - gtk_table_attach_defaults( GTK_TABLE(table), gtk_label_new(buf), 0, 1, i, i+1 );15.325 - combo = gtk_combo_box_new_text();15.326 - gtk_combo_box_append_text( GTK_COMBO_BOX(combo), _("<empty>") );15.327 - for( j=0; devices[j] != NULL; j++ ) {15.328 - gtk_combo_box_append_text(GTK_COMBO_BOX(combo), devices[j]->name);15.329 - if( device != NULL && device->device_class == devices[j] ) {15.330 - active = j+1;15.331 - }15.332 - }15.333 - gtk_combo_box_set_active(GTK_COMBO_BOX(combo), active);15.334 - gtk_table_attach_defaults( GTK_TABLE(table), combo, 1, 2, i, i+1 );15.335 + int has_slots = device == NULL ? 0 : MAPLE_SLOTS(device->device_class);15.336 +15.337 + snprintf( buf, sizeof(buf), _("Port %c."), 'A'+i );15.338 + gtk_table_attach_defaults( GTK_TABLE(table), gtk_label_new(buf), 0, 1, y, y+1 );15.339 +15.340 + combo = gtk_combo_box_new_with_model(GTK_TREE_MODEL(dev_model));15.341 + GtkCellRenderer *rend = gtk_cell_renderer_text_new();15.342 + gtk_cell_layout_pack_start( GTK_CELL_LAYOUT(combo), rend, TRUE);15.343 + gtk_cell_layout_add_attribute( GTK_CELL_LAYOUT(combo), rend, "text", 0 );15.344 + maple_set_device_selection(combo,device);15.345 + gtk_table_attach_defaults( GTK_TABLE(table), combo, 1, 2, y, y+1 );15.346 +15.347 button = gtk_button_new_from_stock( GTK_STOCK_PROPERTIES );15.348 gtk_widget_set_sensitive(button, active != 0 && device->get_config != NULL);15.349 - gtk_table_attach_defaults( GTK_TABLE(table), button, 2, 3, i, i+1 );15.350 + gtk_table_attach_defaults( GTK_TABLE(table), button, 2, 3, y, y+1 );15.352 - maple_data[i].old_device = device;15.353 - maple_data[i].new_device = device;15.354 - maple_data[i].combo = combo;15.355 - maple_data[i].button = button;15.356 + maple_data[MAPLE_DEVID(i,0)].old_device = device;15.357 + maple_data[MAPLE_DEVID(i,0)].new_device = device;15.358 + maple_data[MAPLE_DEVID(i,0)].combo = combo;15.359 + maple_data[MAPLE_DEVID(i,0)].button = button;15.360 + maple_data[MAPLE_DEVID(i,0)].primarySlot = TRUE;15.361 g_signal_connect( button, "clicked",15.362 - G_CALLBACK( maple_properties_activated ), &maple_data[i] );15.363 + G_CALLBACK( maple_properties_activated ), &maple_data[MAPLE_DEVID(i,0)] );15.364 g_signal_connect( combo, "changed",15.365 - G_CALLBACK( maple_device_changed ), &maple_data[i] );15.366 -15.367 + G_CALLBACK( maple_device_changed ), &maple_data[MAPLE_DEVID(i,0)] );15.368 + y++;15.369 +15.370 + for( k=0; k< MAPLE_USER_SLOTS; k++ ) {15.371 + char tmp[32] = " ";15.372 + device = maple_get_device(i,k+1);15.373 + active = 0;15.374 + snprintf( tmp+8, sizeof(tmp)-8, _("VMU %d."), (k+1) );15.375 + gtk_table_attach_defaults( GTK_TABLE(table), gtk_label_new(tmp), 0, 1, y, y+1 );15.376 + combo = gtk_combo_box_new_with_model(GTK_TREE_MODEL(subdev_model));15.377 + GtkCellRenderer *rend = gtk_cell_renderer_text_new();15.378 + gtk_cell_layout_pack_start( GTK_CELL_LAYOUT(combo), rend, TRUE);15.379 + gtk_cell_layout_add_attribute( GTK_CELL_LAYOUT(combo), rend, "text", 0 );15.380 + maple_set_device_selection(combo, device);15.381 +15.382 + gtk_table_attach_defaults( GTK_TABLE(table), combo, 1, 2, y, y+1 );15.383 + button = gtk_button_new_from_stock( GTK_STOCK_PROPERTIES );15.384 + gtk_table_attach_defaults( GTK_TABLE(table), button, 2, 3, y, y+1 );15.385 + if( k >= has_slots ) {15.386 + gtk_widget_set_sensitive(combo, FALSE);15.387 + gtk_widget_set_sensitive(button, FALSE);15.388 + } else {15.389 + gtk_widget_set_sensitive(button, device != NULL && device->get_config != NULL && !MAPLE_IS_VMU(device));15.390 + }15.391 +15.392 + maple_data[MAPLE_DEVID(i,k+1)].old_device = device;15.393 + maple_data[MAPLE_DEVID(i,k+1)].new_device = device;15.394 + maple_data[MAPLE_DEVID(i,k+1)].combo = combo;15.395 + maple_data[MAPLE_DEVID(i,k+1)].button = button;15.396 + maple_data[MAPLE_DEVID(i,k+1)].primarySlot = FALSE;15.397 + g_signal_connect( button, "clicked",15.398 + G_CALLBACK( maple_properties_activated ), &maple_data[MAPLE_DEVID(i,k+1)] );15.399 + g_signal_connect( combo, "changed",15.400 + G_CALLBACK( maple_device_changed ), &maple_data[MAPLE_DEVID(i,k+1)] );15.401 + y++;15.402 + }15.403 + gtk_table_set_row_spacing( GTK_TABLE(table), y-1, 10 );15.404 }15.405 return table;15.406 }
16.1 --- a/src/gtkui/gtk_gd.c Wed Jun 24 02:27:34 2009 +000016.2 +++ b/src/gtkui/gtk_gd.c Wed Jun 24 02:41:12 2009 +000016.3 @@ -31,7 +31,7 @@16.4 {16.5 if( !gdrom_menu_adjusting ) {16.6 const gchar *dir = lxdream_get_config_value(CONFIG_DEFAULT_PATH);16.7 - open_file_dialog( _("Open..."), gdrom_mount_image, NULL, NULL, dir );16.8 + open_file_dialog_cb( _("Open..."), gdrom_mount_image, NULL, NULL, dir );16.9 }16.10 }
17.1 --- a/src/gtkui/gtkcb.c Wed Jun 24 02:27:34 2009 +000017.2 +++ b/src/gtkui/gtkcb.c Wed Jun 24 02:41:12 2009 +000017.3 @@ -39,10 +39,11 @@17.4 }17.5 }17.7 -void open_file_dialog( const char *title, file_callback_t action, const char *pattern, const char *patname,17.8 - const gchar *initial_dir )17.9 +gchar *open_file_dialog( const char *title, const char *pattern, const char *patname,17.10 + const gchar *initial_dir )17.11 {17.12 GtkWidget *file;17.13 + gchar *filename = NULL;17.14 gchar *initial_path = get_absolute_path(initial_dir);17.15 file = gtk_file_chooser_dialog_new( title, NULL,17.16 GTK_FILE_CHOOSER_ACTION_OPEN,17.17 @@ -55,17 +56,19 @@17.18 gtk_dialog_set_default_response( GTK_DIALOG(file), GTK_RESPONSE_ACCEPT );17.19 int result = gtk_dialog_run( GTK_DIALOG(file) );17.20 if( result == GTK_RESPONSE_ACCEPT ) {17.21 - gchar *filename = gtk_file_chooser_get_filename( GTK_FILE_CHOOSER(file) );17.22 - action( filename );17.23 + filename = gtk_file_chooser_get_filename( GTK_FILE_CHOOSER(file) );17.24 }17.25 gtk_widget_destroy(file);17.26 g_free(initial_path);17.27 +17.28 + return filename;17.29 }17.31 -void save_file_dialog( const char *title, file_callback_t action, const char *pattern, const char *patname,17.32 +gchar *save_file_dialog( const char *title, const char *pattern, const char *patname,17.33 const gchar *initial_dir )17.34 {17.35 GtkWidget *file;17.36 + gchar *filename;17.37 gchar *initial_path = get_absolute_path(initial_dir);17.38 file = gtk_file_chooser_dialog_new( title, NULL,17.39 GTK_FILE_CHOOSER_ACTION_SAVE,17.40 @@ -78,17 +81,37 @@17.41 gtk_dialog_set_default_response( GTK_DIALOG(file), GTK_RESPONSE_ACCEPT );17.42 int result = gtk_dialog_run( GTK_DIALOG(file) );17.43 if( result == GTK_RESPONSE_ACCEPT ) {17.44 - gchar *filename = gtk_file_chooser_get_filename( GTK_FILE_CHOOSER(file) );17.45 - action( filename );17.46 + filename = gtk_file_chooser_get_filename( GTK_FILE_CHOOSER(file) );17.47 }17.48 gtk_widget_destroy(file);17.49 g_free(initial_path);17.50 + return filename;17.51 +}17.52 +17.53 +void open_file_dialog_cb( const char *title, file_callback_t action, const char *pattern, const char *patname,17.54 + const gchar *initial_dir )17.55 +{17.56 + gchar *filename = open_file_dialog( title, pattern, patname, initial_dir );17.57 + if( filename != NULL ) {17.58 + action( filename );17.59 + g_free(filename);17.60 + }17.61 +}17.62 +17.63 +void save_file_dialog_cb( const char *title, file_callback_t action, const char *pattern, const char *patname,17.64 + const gchar *initial_dir )17.65 +{17.66 + gchar *filename = save_file_dialog( title, pattern, patname, initial_dir );17.67 + if( filename != NULL ) {17.68 + action(filename);17.69 + g_free(filename);17.70 + }17.71 }17.73 void mount_action_callback( GtkAction *action, gpointer user_data)17.74 {17.75 const gchar *dir = lxdream_get_config_value(CONFIG_DEFAULT_PATH);17.76 - open_file_dialog( "Open...", gdrom_mount_image, NULL, NULL, dir );17.77 + open_file_dialog_cb( "Open...", gdrom_mount_image, NULL, NULL, dir );17.78 }17.79 void reset_action_callback( GtkAction *action, gpointer user_data)17.80 {17.81 @@ -108,7 +131,7 @@17.82 void load_binary_action_callback( GtkAction *action, gpointer user_data)17.83 {17.84 const gchar *dir = lxdream_get_config_value(CONFIG_DEFAULT_PATH);17.85 - open_file_dialog( "Open Binary...", file_load_magic, NULL, NULL, dir );17.86 + open_file_dialog_cb( "Open Binary...", file_load_magic, NULL, NULL, dir );17.87 }17.89 void load_state_preview_callback( GtkFileChooser *chooser, gpointer user_data )17.90 @@ -172,7 +195,7 @@17.91 void save_state_action_callback( GtkAction *action, gpointer user_data)17.92 {17.93 const gchar *dir = lxdream_get_config_value(CONFIG_SAVE_PATH);17.94 - save_file_dialog( "Save state...", dreamcast_save_state, "*.dst", _("lxDream Save State (*.dst)"), dir );17.95 + save_file_dialog_cb( "Save state...", dreamcast_save_state, "*.dst", _("lxDream Save State (*.dst)"), dir );17.96 }17.97 void about_action_callback( GtkAction *action, gpointer user_data)17.98 {17.99 @@ -247,7 +270,7 @@17.100 void save_scene_action_callback( GtkAction *action, gpointer user_data)17.101 {17.102 const gchar *dir = lxdream_get_config_value(CONFIG_SAVE_PATH);17.103 - save_file_dialog( _("Save next scene..."), pvr2_save_next_scene, "*.dsc", _("lxdream scene file (*.dsc)"), dir );17.104 + save_file_dialog_cb( _("Save next scene..."), pvr2_save_next_scene, "*.dsc", _("lxdream scene file (*.dsc)"), dir );17.105 }17.107 int debug_window_get_selected_row( debug_window_t data );
18.1 --- a/src/gtkui/gtkui.h Wed Jun 24 02:27:34 2009 +000018.2 +++ b/src/gtkui/gtkui.h Wed Jun 24 02:41:12 2009 +000018.3 @@ -88,8 +88,14 @@18.6 typedef gboolean (*file_callback_t)( const gchar *filename );18.7 -void open_file_dialog( const char *title, file_callback_t action, const char *pattern, const char *patname,18.8 +gchar *open_file_dialog( const char *title, const char *pattern, const char *patname,18.9 const gchar *initial_dir );18.10 +gchar *save_file_dialog( const char *title, const char *pattern, const char *patname,18.11 + const gchar *initial_dir );18.12 +void open_file_dialog_cb( const char *title, file_callback_t action, const char *pattern, const char *patname,18.13 + const gchar *initial_dir );18.14 +void save_file_dialog_cb( const char *title, file_callback_t action, const char *pattern, const char *patname,18.15 + const gchar *initial_dir );18.16 /**18.17 * Extract the keyval of the key event if no modifier keys were pressed -18.18 * in other words get the keyval of the key by itself. The other way around
19.1 --- a/src/hook.h Wed Jun 24 02:27:34 2009 +000019.2 +++ b/src/hook.h Wed Jun 24 02:41:12 2009 +000019.3 @@ -22,7 +22,7 @@19.4 #include <assert.h>19.6 /**19.7 - * Hook functions are generally useful, so we'd let to limit the overhead (and19.8 + * Hook functions are generally useful, so we'd like to limit the overhead (and19.9 * opportunity for stupid bugs) by minimizing the amount of code involved. Glib19.10 * has GHook (and of course signals), but they don't actually simplify anything19.11 * at this level.19.12 @@ -46,6 +46,7 @@19.14 #define FOREACH_HOOK( h, name ) struct name##_hook_struct *h; for( h = name##_hook_list; h != NULL; h = h->next )19.16 +#define CALL_HOOKS0( name ) FOREACH_HOOK(h,name) { h->fn(h->user_data); }19.17 #define CALL_HOOKS( name, args... ) FOREACH_HOOK(h, name) { h->fn(args, h->user_data); }19.19 #define DEFINE_HOOK( name, fn_type ) \
20.1 --- a/src/main.c Wed Jun 24 02:27:34 2009 +000020.2 +++ b/src/main.c Wed Jun 24 02:41:12 2009 +000020.3 @@ -35,6 +35,7 @@20.4 #include "maple/maple.h"20.5 #include "sh4/sh4.h"20.6 #include "aica/armdasm.h"20.7 +#include "vmu/vmulist.h"20.8 #include "hotkeys.h"20.9 #include "plugin.h"20.11 @@ -216,6 +217,7 @@20.12 }20.14 gdrom_list_init();20.15 + vmulist_init();20.17 if( aica_program == NULL ) {20.18 dreamcast_init();
21.1 --- a/src/maple/controller.c Wed Jun 24 02:27:34 2009 +000021.2 +++ b/src/maple/controller.c Wed Jun 24 02:41:12 2009 +000021.3 @@ -93,14 +93,15 @@21.4 struct lxdream_config_entry config[CONTROLLER_CONFIG_ENTRIES+1];21.5 } *controller_device_t;21.7 -struct maple_device_class controller_class = { "Sega Controller", controller_new };21.8 +struct maple_device_class controller_class = { "Sega Controller",21.9 + MAPLE_TYPE_PRIMARY|MAPLE_GRAB_DONTCARE|MAPLE_SLOTS_2, controller_new };21.11 static struct controller_device base_controller = {21.12 - { MAPLE_DEVICE_TAG, &controller_class, MAPLE_GRAB_DONTCARE,21.13 + { MAPLE_DEVICE_TAG, &controller_class,21.14 CONTROLLER_IDENT, CONTROLLER_VERSION,21.15 controller_get_config, controller_set_config_value,21.16 controller_attach, controller_detach, controller_destroy,21.17 - controller_clone, NULL, NULL, controller_get_cond, NULL, NULL, NULL, NULL, NULL },21.18 + controller_clone, NULL, NULL, controller_get_cond, NULL, NULL, NULL, NULL, NULL, NULL },21.19 {0x0000FFFF, 0x80808080},21.20 {{ "dpad left", N_("Dpad left"), CONFIG_TYPE_KEY },21.21 { "dpad right", N_("Dpad right"), CONFIG_TYPE_KEY },
22.1 --- a/src/maple/kbd.c Wed Jun 24 02:27:34 2009 +000022.2 +++ b/src/maple/kbd.c Wed Jun 24 02:41:12 2009 +000022.3 @@ -52,13 +52,14 @@22.4 uint8_t condition[8];22.5 } *keyboard_device_t;22.7 -struct maple_device_class keyboard_class = { "Sega Keyboard", keyboard_new };22.8 +struct maple_device_class keyboard_class = { "Sega Keyboard", MAPLE_GRAB_DONTCARE|MAPLE_TYPE_PRIMARY, keyboard_new };22.10 static struct keyboard_device base_keyboard = {22.11 - { MAPLE_DEVICE_TAG, &keyboard_class, MAPLE_GRAB_DONTCARE,22.12 + { MAPLE_DEVICE_TAG, &keyboard_class,22.13 KEYBOARD_IDENT, KEYBOARD_VERSION,22.14 NULL, NULL, keyboard_attach, keyboard_detach, maple_default_destroy,22.15 - keyboard_clone, NULL, NULL, keyboard_get_cond, NULL, NULL, NULL },22.16 + keyboard_clone, NULL, NULL, keyboard_get_cond, NULL, NULL, NULL,22.17 + NULL, NULL, NULL},22.18 {0,0,0,0,0,0,0,0},22.19 };
23.1 --- a/src/maple/lightgun.c Wed Jun 24 02:27:34 2009 +000023.2 +++ b/src/maple/lightgun.c Wed Jun 24 02:41:12 2009 +000023.3 @@ -72,14 +72,15 @@23.4 struct lxdream_config_entry config[LIGHTGUN_CONFIG_ENTRIES+1];23.5 } *lightgun_device_t;23.7 -struct maple_device_class lightgun_class = { "Sega Lightgun", lightgun_new };23.8 +struct maple_device_class lightgun_class = { "Sega Lightgun",23.9 + MAPLE_TYPE_PRIMARY|MAPLE_GRAB_NO|MAPLE_SLOTS_2, lightgun_new };23.11 static struct lightgun_device base_lightgun = {23.12 - { MAPLE_DEVICE_TAG, &lightgun_class, MAPLE_GRAB_NO,23.13 + { MAPLE_DEVICE_TAG, &lightgun_class,23.14 LIGHTGUN_IDENT, LIGHTGUN_VERSION,23.15 lightgun_get_config, lightgun_set_config_value,23.16 lightgun_attach, lightgun_detach, lightgun_destroy,23.17 - lightgun_clone, NULL, NULL, lightgun_get_cond, NULL, NULL, NULL,23.18 + lightgun_clone, NULL, NULL, lightgun_get_cond, NULL, NULL, NULL, NULL,23.19 lightgun_start_gun, lightgun_stop_gun},23.20 {0x0000FFFF, 0x80808080}, 0, -1, -1,23.21 {{ "dpad left", N_("Dpad left"), CONFIG_TYPE_KEY },
24.1 --- a/src/maple/maple.c Wed Jun 24 02:27:34 2009 +000024.2 +++ b/src/maple/maple.c Wed Jun 24 02:41:12 2009 +000024.3 @@ -30,7 +30,7 @@24.4 NULL, NULL, NULL };24.6 struct maple_device_class *maple_device_classes[] = {24.7 - &controller_class, &keyboard_class, &lightgun_class, &mouse_class, NULL };24.8 + &controller_class, &keyboard_class, &lightgun_class, &mouse_class, &vmu_class, NULL };24.10 void maple_init( void )24.11 {24.12 @@ -175,13 +175,26 @@24.13 /* no device attached */24.14 *((uint32_t *)return_buf) = -1;24.15 } else {24.16 - int status, func, block;24.17 + int status, func;24.18 + unsigned int pt, phase, block;24.19 out_length = 0;24.20 switch( cmd ) {24.21 case MAPLE_CMD_INFO:24.22 status = MAPLE_RESP_INFO;24.23 memcpy( return_buf+4, dev->ident, 112 );24.24 out_length = 0x1C;24.25 + if( periph == 0 ) {24.26 + /* Identify command on the primary device also sets the24.27 + * bits in the address in the response according to the24.28 + * sub-peripherals present.24.29 + */24.30 + recv_addr &= 0xE0;24.31 + for( i=0; i<5; i++ ) {24.32 + if( maple_devices[port][i+1] != NULL ) {24.33 + recv_addr |= (1<<i);24.34 + }24.35 + }24.36 + }24.37 break;24.38 case MAPLE_CMD_EXT_INFO:24.39 status = MAPLE_RESP_EXT_INFO;24.40 @@ -217,16 +230,29 @@24.41 status = MAPLE_ERR_CMD_UNKNOWN;24.42 else status = dev->set_condition(dev, func,24.43 buf+16,24.44 - length);24.45 + length-1);24.46 if( status == 0 )24.47 status = MAPLE_RESP_ACK;24.48 break;24.49 + case MAPLE_CMD_MEM_INFO:24.50 + func = GETWORD(12);24.51 + pt = GETWORD(16);24.52 + if( dev->get_memory_info == NULL )24.53 + status = MAPLE_ERR_CMD_UNKNOWN;24.54 + else status = dev->get_memory_info(dev,func, pt, return_buf+8, &out_length);24.55 + if( status == 0 ) {24.56 + status = MAPLE_RESP_DATA;24.57 + PUTWORD(4,func);24.58 + }24.59 + break;24.60 case MAPLE_CMD_READ_BLOCK:24.61 func = GETWORD(12);24.62 - block = GETWORD(16);24.63 + pt = GETBYTE(16);24.64 + phase = GETBYTE(17);24.65 + block = (GETBYTE(18)<<8) | GETBYTE(19);24.66 if( dev->read_block == NULL )24.67 status = MAPLE_ERR_CMD_UNKNOWN;24.68 - else status = dev->read_block(dev, func, block,24.69 + else status = dev->read_block(dev, func, pt, block, phase,24.70 return_buf+12,24.71 &out_length );24.72 if( status == 0 ) {24.73 @@ -237,16 +263,26 @@24.74 break;24.75 case MAPLE_CMD_WRITE_BLOCK:24.76 func = GETWORD(12);24.77 - block = GETWORD(16);24.78 + pt = GETBYTE(16);24.79 + phase = GETBYTE(17);24.80 + block = (GETBYTE(18)<<8) | GETBYTE(19);24.81 if( dev->write_block == NULL )24.82 status = MAPLE_ERR_CMD_UNKNOWN;24.83 else {24.84 - status = dev->write_block(dev, func, block,24.85 - buf+20, length);24.86 + status = dev->write_block(dev, func, pt, block, phase,24.87 + buf+20, length-2);24.88 if( status == 0 )24.89 status = MAPLE_RESP_ACK;24.90 }24.91 break;24.92 + case MAPLE_CMD_SYNC_BLOCK:24.93 + func = GETWORD(12);24.94 + pt = GETBYTE(16);24.95 + phase = GETBYTE(17);24.96 + block = (GETBYTE(18)<<8) | GETBYTE(19);24.97 + /* TODO: something? */24.98 + status = MAPLE_RESP_ACK;24.99 + break;24.100 default:24.101 status = MAPLE_ERR_CMD_UNKNOWN;24.102 }24.103 @@ -352,8 +388,8 @@24.104 for( j=0; j<6; j++ ) {24.105 if( maple_devices[i][j] != NULL ) {24.106 maple_device_t dev = maple_devices[i][j];24.107 - if( dev->grab_mode > mode ) {24.108 - mode = dev->grab_mode;24.109 + if( (dev->device_class->flags&MAPLE_GRAB_MASK) > mode ) {24.110 + mode = dev->device_class->flags & MAPLE_GRAB_MASK;24.111 }24.112 }24.113 }
25.1 --- a/src/maple/maple.h Wed Jun 24 02:27:34 2009 +000025.2 +++ b/src/maple/maple.h Wed Jun 24 02:41:12 2009 +000025.3 @@ -26,6 +26,18 @@25.4 #include <stdint.h>25.5 #include "config.h"25.7 +#define MAPLE_PORTS 425.8 +#define MAPLE_MAX_DEVICES 24 /* 1 Primary + 5 secondary per port */25.9 +#define MAPLE_USER_SLOTS 2 /* Number of slots to show in configuration */25.10 +25.11 +/* Map devices to a single id from 0..MAPLE_MAX_DEVICES, to simplify25.12 + * configuration. Port is 0..3 (A..D) representing the primary ports, and25.13 + * slot is 0 for the primary, or 1..5 for for one the secondary slots.25.14 + */25.15 +#define MAPLE_DEVID(port,slot) ( (port)|((slot)<<2) )25.16 +#define MAPLE_DEVID_PORT(id) ((id)&0x03)25.17 +#define MAPLE_DEVID_SLOT(id) ((id)>>2)25.18 +25.19 #define MAPLE_CMD_INFO 1 /* Request device information */25.20 #define MAPLE_CMD_EXT_INFO 2 /* Request extended information */25.21 #define MAPLE_CMD_RESET 3 /* Reset device */25.22 @@ -34,6 +46,7 @@25.23 #define MAPLE_CMD_MEM_INFO 10 /* Get memory information */25.24 #define MAPLE_CMD_READ_BLOCK 11 /* Block read */25.25 #define MAPLE_CMD_WRITE_BLOCK 12 /* Block write */25.26 +#define MAPLE_CMD_SYNC_BLOCK 13 /* Block sync */25.27 #define MAPLE_CMD_SET_COND 14 /* Set condition */25.28 #define MAPLE_RESP_INFO 5 /* Device information response */25.29 #define MAPLE_RESP_EXT_INFO 6 /* Extended device information response */25.30 @@ -56,18 +69,36 @@25.31 #define MAPLE_FUNC_PURU_PURU 0x0001000025.32 #define MAPLE_FUNC_MOUSE 0x0002000025.34 -#define MAPLE_GRAB_DONTCARE 025.35 -#define MAPLE_GRAB_YES 125.36 -#define MAPLE_GRAB_NO 225.37 +/* Internal flags, mainly for UI consumption */25.38 +#define MAPLE_GRAB_DONTCARE 0x0025.39 +#define MAPLE_GRAB_YES 0x0125.40 +#define MAPLE_GRAB_NO 0x0225.41 +#define MAPLE_GRAB_MASK 0x0325.42 +#define MAPLE_TYPE_PRIMARY 0x08 /* attaches directly to maple port */25.43 +#define MAPLE_SLOTS_MASK 0xF0 /* number of slots on device (primaries only) */25.44 +#define MAPLE_SLOTS_1 0x1025.45 +#define MAPLE_SLOTS_2 0x2025.46 +#define MAPLE_SLOTS(x) ((((x)->flags)&MAPLE_SLOTS_MASK)>>4)25.48 #define MAPLE_DEVICE_TAG 0x4D41504C25.49 #define MAPLE_DEVICE(x) ((maple_device_t)x)25.51 +/* Some convenience methods for VMU handling */25.52 +#define MAPLE_IS_VMU(dev) ((dev)->device_class == &vmu_class)25.53 +#define MAPLE_IS_VMU_CLASS(clz) ((clz) == &vmu_class)25.54 +#define MAPLE_VMU_NAME(dev) (((dev)->get_config(dev))[0].value)25.55 +#define MAPLE_SET_VMU_NAME(dev,name) ((dev)->set_config_value((dev),0,(name)))25.56 +#define MAPLE_VMU_HAS_NAME(d1,name) (MAPLE_VMU_NAME(d1) == NULL ? name == NULL : \25.57 + name != NULL && strcmp(MAPLE_VMU_NAME(d1),name) == 0)25.58 +#define MAPLE_IS_SAME_VMU(d1,d2) (MAPLE_VMU_NAME(d1) == NULL ? MAPLE_VMU_NAME(d2) == NULL : \25.59 + MAPLE_VMU_NAME(d2) != NULL && strcmp(MAPLE_VMU_NAME(d1),MAPLE_VMU_NAME(d2)) == 0)25.60 +25.61 typedef const struct maple_device_class *maple_device_class_t;25.62 typedef struct maple_device *maple_device_t;25.64 struct maple_device_class {25.65 const char *name;25.66 + int flags;25.67 maple_device_t (*new_device)();25.68 };25.70 @@ -77,7 +108,6 @@25.71 struct maple_device {25.72 uint32_t _tag;25.73 maple_device_class_t device_class;25.74 - int grab_mode;25.75 unsigned char ident[112];25.76 unsigned char version[80];25.77 lxdream_config_entry_t (*get_config)(struct maple_device *dev);25.78 @@ -92,10 +122,12 @@25.79 int function, unsigned char *outbuf, unsigned int *buflen);25.80 int (*set_condition)(struct maple_device *dev,25.81 int function, unsigned char *inbuf, unsigned int buflen);25.82 - int (*read_block)(struct maple_device *dev,25.83 - int function, uint32_t block, unsigned char *outbuf, unsigned int *buflen);25.84 - int (*write_block)(struct maple_device *dev,25.85 - int function, uint32_t block, unsigned char *inbuf, unsigned int buflen);25.86 + int (*get_memory_info)(struct maple_device *dev, int function, unsigned int partition,25.87 + unsigned char *outbuf, unsigned int *buflen);25.88 + int (*read_block)(struct maple_device *dev, int function, unsigned int partition,25.89 + uint32_t block, unsigned int phase, unsigned char *outbuf, unsigned int *buflen);25.90 + int (*write_block)(struct maple_device *dev, int function, unsigned int partition,25.91 + uint32_t block, unsigned int phase, unsigned char *inbuf, unsigned int buflen);25.92 void (*start_gun)(struct maple_device *dev);25.93 void (*stop_gun)(struct maple_device *dev);25.94 };25.95 @@ -104,6 +136,7 @@25.96 extern struct maple_device_class keyboard_class;25.97 extern struct maple_device_class lightgun_class;25.98 extern struct maple_device_class mouse_class;25.99 +extern struct maple_device_class vmu_class;25.101 maple_device_t maple_new_device( const gchar *name );25.102 maple_device_t maple_get_device( unsigned int port, unsigned int periph );
26.1 --- a/src/maple/mouse.c Wed Jun 24 02:27:34 2009 +000026.2 +++ b/src/maple/mouse.c Wed Jun 24 02:41:12 2009 +000026.3 @@ -55,13 +55,13 @@26.4 int32_t axis[8];26.5 } *mouse_device_t;26.7 -struct maple_device_class mouse_class = { "Sega Mouse", mouse_new };26.8 +struct maple_device_class mouse_class = { "Sega Mouse", MAPLE_GRAB_YES|MAPLE_TYPE_PRIMARY, mouse_new };26.10 static struct mouse_device base_mouse = {26.11 - { MAPLE_DEVICE_TAG, &mouse_class, MAPLE_GRAB_YES,26.12 + { MAPLE_DEVICE_TAG, &mouse_class,26.13 MOUSE_IDENT, MOUSE_VERSION,26.14 NULL, NULL, mouse_attach, mouse_detach, maple_default_destroy,26.15 - mouse_clone, NULL, NULL, mouse_get_cond, NULL, NULL, NULL, NULL, NULL },26.16 + mouse_clone, NULL, NULL, mouse_get_cond, NULL, NULL, NULL, NULL, NULL, NULL },26.17 0, {0,0,0,0,0,0,0,0},26.18 };
27.1 --- /dev/null Thu Jan 01 00:00:00 1970 +000027.2 +++ b/src/maple/vmu.c Wed Jun 24 02:41:12 2009 +000027.3 @@ -0,0 +1,241 @@27.4 +/**27.5 + * $Id: vmu.c 858 2008-09-02 03:34:00Z nkeynes $27.6 + *27.7 + * Implementation of the SEGA VMU device27.8 + * Part No. HKT-700027.9 + *27.10 + * The standard VMU implements 3 functions - Clock, LCD, and memory card,27.11 + * in addition to having it's own little CPU, buttons, etc. The CPU isn't27.12 + * implemented just yet.27.13 + *27.14 + * Copyright (c) 2009 Nathan Keynes.27.15 + *27.16 + * This program is free software; you can redistribute it and/or modify27.17 + * it under the terms of the GNU General Public License as published by27.18 + * the Free Software Foundation; either version 2 of the License, or27.19 + * (at your option) any later version.27.20 + *27.21 + * This program is distributed in the hope that it will be useful,27.22 + * but WITHOUT ANY WARRANTY; without even the implied warranty of27.23 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the27.24 + * GNU General Public License for more details.27.25 + */27.26 +27.27 +#include <assert.h>27.28 +#include <stdlib.h>27.29 +#include <stdio.h>27.30 +#include <string.h>27.31 +#include <errno.h>27.32 +#include <sys/mman.h>27.33 +#include <fcntl.h>27.34 +#include "display.h"27.35 +#include "maple/maple.h"27.36 +#include "vmu/vmuvol.h"27.37 +#include "vmu/vmulist.h"27.38 +27.39 +#define VMU_LCD_SIZE (48*4)27.40 +#define VMU_BLOCK_COUNT 25627.41 +#define VMU_BLOCK_SIZE 51227.42 +#define VMU_PHASE_SIZE 12827.43 +#define VMU_CONFIG_ENTRIES 127.44 +27.45 +#define VMU_IDENT { 0x00, 0x00, 0x00, 0x0E, 0x7E, 0x7E, 0x3F, 0x40, 0x00, 0x05, 0x10, 0x00, \27.46 + 0x00, 0x0F, 0x41, 0x00, 0xFF, 0x00, 0x56, 0x69, 0x73, 0x75, 0x61, 0x6C, 0x20, 0x4D, 0x65, 0x6D, \27.47 + 0x6F, 0x72, 0x79, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, \27.48 + 0x20, 0x20, 0x20, 0x20, 0x50, 0x72, 0x6F, 0x64, 0x75, 0x63, 0x65, 0x64, 0x20, 0x42, 0x79, 0x20, \27.49 + 0x6F, 0x72, 0x20, 0x55, 0x6E, 0x64, 0x65, 0x72, 0x20, 0x4C, 0x69, 0x63, 0x65, 0x6E, 0x73, 0x65, \27.50 + 0x20, 0x46, 0x72, 0x6F, 0x6D, 0x20, 0x53, 0x45, 0x47, 0x41, 0x20, 0x45, 0x4E, 0x54, 0x45, 0x52, \27.51 + 0x50, 0x52, 0x49, 0x53, 0x45, 0x53, 0x2C, 0x4C, 0x54, 0x44, 0x2E, 0x20, 0x20, 0x20, 0x20, 0x20, \27.52 + 0x7C, 0x00, 0x82, 0x00 }27.53 +#define VMU_VERSION { 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x20, 0x31, 0x2E, 0x30, 0x30, \27.54 + 0x35, 0x2C, 0x31, 0x39, 0x39, 0x39, 0x2F, 0x30, 0x34, 0x2F, 0x31, 0x35, 0x2C, 0x33, 0x31, 0x35, \27.55 + 0x2D, 0x36, 0x32, 0x30, 0x38, 0x2D, 0x30, 0x33, 0x2C, 0x53, 0x45, 0x47, 0x41, 0x20, 0x56, 0x69, \27.56 + 0x73, 0x75, 0x61, 0x6C, 0x20, 0x4D, 0x65, 0x6D, 0x6F, 0x72, 0x79, 0x20, 0x53, 0x79, 0x73, 0x74, \27.57 + 0x65, 0x6D, 0x20, 0x42, 0x49, 0x4F, 0x53, 0x20, 0x50, 0x72, 0x6F, 0x64, 0x75, 0x63, 0x65, 0x64, \27.58 + 0x20, 0x62, 0x79, 0x20 }27.59 +27.60 +static void vmu_destroy( maple_device_t dev );27.61 +static maple_device_t vmu_clone( maple_device_t dev );27.62 +static maple_device_t vmu_new();27.63 +static lxdream_config_entry_t vmu_get_config( maple_device_t dev );27.64 +static void vmu_set_config_value( maple_device_t dev, unsigned int key, const gchar *value );27.65 +static int vmu_get_condition( maple_device_t dev, int function, unsigned char *outbuf,27.66 + unsigned int *outlen );27.67 +static int vmu_get_meminfo( maple_device_t dev, int function, unsigned int pt,27.68 + unsigned char *outbuf, unsigned int *outlen );27.69 +static void vmu_attach(struct maple_device *dev);27.70 +static void vmu_detach(struct maple_device *dev);27.71 +static int vmu_read_block(struct maple_device *dev, int function, unsigned int pt,27.72 + uint32_t block, unsigned int phase,27.73 + unsigned char *outbuf, unsigned int *buflen);27.74 +static int vmu_write_block(struct maple_device *dev, int function, unsigned int pt,27.75 + uint32_t block, unsigned int phase,27.76 + unsigned char *inbuf, unsigned int buflen);27.77 +27.78 +typedef struct vmu_device {27.79 + struct maple_device dev;27.80 + vmu_volume_t vol;27.81 + char lcd_bitmap[VMU_LCD_SIZE]; /* 48x32 bitmap */27.82 + struct lxdream_config_entry config[VMU_CONFIG_ENTRIES+1];27.83 +} *vmu_device_t;27.84 +27.85 +struct maple_device_class vmu_class = { "Sega VMU", MAPLE_GRAB_DONTCARE, vmu_new };27.86 +27.87 +static struct vmu_device base_vmu = {27.88 + { MAPLE_DEVICE_TAG, &vmu_class,27.89 + VMU_IDENT, VMU_VERSION,27.90 + vmu_get_config, vmu_set_config_value,27.91 + vmu_attach, vmu_detach, vmu_destroy,27.92 + vmu_clone, NULL, NULL, vmu_get_condition, NULL,27.93 + vmu_get_meminfo, vmu_read_block, vmu_write_block, NULL, NULL },27.94 + NULL, {0},27.95 + {{ "volume", N_("Volume"), CONFIG_TYPE_FILE },27.96 + { NULL, CONFIG_TYPE_NONE }} };27.97 +27.98 +static maple_device_t vmu_new( )27.99 +{27.100 + vmu_device_t dev = malloc( sizeof(struct vmu_device) );27.101 + memcpy( dev, &base_vmu, sizeof(base_vmu) );27.102 + return MAPLE_DEVICE(dev);27.103 +}27.104 +27.105 +static maple_device_t vmu_clone( maple_device_t srcdevice )27.106 +{27.107 + vmu_device_t src = (vmu_device_t)srcdevice;27.108 + vmu_device_t dev = (vmu_device_t)vmu_new();27.109 + lxdream_copy_config_list( dev->config, src->config );27.110 + return MAPLE_DEVICE(dev);27.111 +}27.112 +27.113 +static lxdream_config_entry_t vmu_get_config( maple_device_t mdev )27.114 +{27.115 + vmu_device_t dev = (vmu_device_t)mdev;27.116 + return dev->config;27.117 +}27.118 +27.119 +static void vmu_set_config_value( maple_device_t dev, unsigned int key, const gchar *value )27.120 +{27.121 + vmu_device_t vmu = (vmu_device_t)dev;27.122 + assert( key < VMU_CONFIG_ENTRIES );27.123 +27.124 + if( value == vmu->config[key].value ||27.125 + value != NULL && vmu->config[key].value != NULL && strcmp(vmu->config[key].value, value) == 0 ) {27.126 + return; /* Unchanged */27.127 + }27.128 +27.129 + if( vmu->vol != NULL ) {27.130 + vmulist_detach_vmu(vmu->vol);27.131 + }27.132 + lxdream_set_config_value( &vmu->config[key], value );27.133 + vmu->vol = vmulist_get_vmu_by_filename( value );27.134 + if( vmu->vol != NULL ) {27.135 + vmulist_attach_vmu(vmu->vol, "MAPLE");27.136 + }27.137 +}27.138 +27.139 +void vmu_attach(struct maple_device *dev)27.140 +{27.141 + vmu_device_t vmu = (vmu_device_t)dev;27.142 + if( vmu->config[0].value != NULL ) {27.143 + vmu->vol = vmulist_get_vmu_by_filename(vmu->config[0].value);27.144 + if( vmu->vol != NULL ) {27.145 + vmulist_attach_vmu(vmu->vol, "MAPLE");27.146 + }27.147 + }27.148 +}27.149 +27.150 +static void vmu_detach(struct maple_device *dev)27.151 +{27.152 + vmu_device_t vmu = (vmu_device_t)dev;27.153 + if( vmu->vol != NULL ) {27.154 + vmulist_detach_vmu(vmu->vol);27.155 + vmu->vol = NULL;27.156 + }27.157 +}27.158 +27.159 +static void vmu_destroy( maple_device_t dev )27.160 +{27.161 + vmu_device_t vmu = (vmu_device_t)dev;27.162 + free( dev );27.163 +}27.164 +27.165 +static int vmu_get_condition(struct maple_device *dev, int function,27.166 + unsigned char *outbuf, unsigned int *buflen)27.167 +{27.168 +}27.169 +static int vmu_set_condition(struct maple_device *dev, int function,27.170 + unsigned char *inbuf, unsigned int buflen)27.171 +{27.172 + return MAPLE_ERR_NO_RESPONSE; /* CHECKME */27.173 +}27.174 +27.175 +static int vmu_get_meminfo(struct maple_device *dev, int function, unsigned int pt,27.176 + unsigned char *outbuf, unsigned int *buflen)27.177 +{27.178 + struct vmu_device *vmu = (struct vmu_device *)dev;27.179 + switch(function) {27.180 + case MAPLE_FUNC_MEMORY:27.181 + if( vmu->vol != NULL ) {27.182 + const struct vmu_volume_metadata *md = vmu_volume_get_metadata( vmu->vol, pt );27.183 + memcpy( outbuf, md, sizeof(struct vmu_volume_metadata) );27.184 + *buflen = sizeof(struct vmu_volume_metadata);27.185 + return 0;27.186 + } // Else fallthrough27.187 + case MAPLE_FUNC_LCD:27.188 + case MAPLE_FUNC_CLOCK:27.189 + return MAPLE_ERR_NO_RESPONSE;27.190 + default:27.191 + return MAPLE_ERR_FUNC_UNSUP;27.192 + }27.193 +27.194 +}27.195 +static int vmu_read_block(struct maple_device *dev, int function, unsigned int pt,27.196 + uint32_t block, unsigned int phase,27.197 + unsigned char *outbuf, unsigned int *buflen)27.198 +{27.199 + struct vmu_device *vmu = (struct vmu_device *)dev;27.200 + switch( function ) {27.201 + case MAPLE_FUNC_LCD:27.202 + if( pt == 0 && block == 0 ) {27.203 + *buflen = VMU_LCD_SIZE/4;27.204 + memcpy( outbuf, vmu->lcd_bitmap, VMU_LCD_SIZE/4 );27.205 + }27.206 + return 0;27.207 + break;27.208 + case MAPLE_FUNC_MEMORY:27.209 + if( vmu->vol != NULL ) {27.210 + vmu_volume_read_block( vmu->vol, pt, block, outbuf );27.211 + return 0;27.212 + }27.213 + // Else fallthrough for now27.214 + case MAPLE_FUNC_CLOCK:27.215 + return MAPLE_ERR_NO_RESPONSE; /* CHECKME */27.216 + default:27.217 + return MAPLE_ERR_FUNC_UNSUP;27.218 + }27.219 +}27.220 +27.221 +static int vmu_write_block(struct maple_device *dev, int function, unsigned int pt,27.222 + uint32_t block, unsigned int phase,27.223 + unsigned char *inbuf, unsigned int buflen)27.224 +{27.225 + struct vmu_device *vmu = (struct vmu_device *)dev;27.226 + switch( function ) {27.227 + case MAPLE_FUNC_LCD:27.228 + if( pt == 0 && block == 0 && buflen == (VMU_LCD_SIZE/4) ) {27.229 + memcpy( vmu->lcd_bitmap, inbuf, VMU_LCD_SIZE );27.230 + }27.231 + return 0;27.232 + break;27.233 + case MAPLE_FUNC_MEMORY:27.234 + if( vmu->vol != NULL && buflen == (VMU_PHASE_SIZE/4) ) {27.235 + vmu_volume_write_phase( vmu->vol, pt, block, phase, inbuf );27.236 + return 0;27.237 + }27.238 + // Else fallthrough for now27.239 + case MAPLE_FUNC_CLOCK:27.240 + return MAPLE_ERR_NO_RESPONSE; /* CHECKME */27.241 + default:27.242 + return MAPLE_ERR_FUNC_UNSUP;27.243 + }27.244 +}
28.1 --- /dev/null Thu Jan 01 00:00:00 1970 +000028.2 +++ b/src/vmu/vmulist.c Wed Jun 24 02:41:12 2009 +000028.3 @@ -0,0 +1,314 @@28.4 +/**28.5 + * $Id: vmulist.c 869 2008-09-08 07:56:33Z nkeynes $28.6 + *28.7 + * VMU management - maintains a list of all known VMUs28.8 + *28.9 + * Copyright (c) 2009 Nathan Keynes.28.10 + *28.11 + * This program is free software; you can redistribute it and/or modify28.12 + * it under the terms of the GNU General Public License as published by28.13 + * the Free Software Foundation; either version 2 of the License, or28.14 + * (at your option) any later version.28.15 + *28.16 + * This program is distributed in the hope that it will be useful,28.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of28.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the28.19 + * GNU General Public License for more details.28.20 + */28.21 +28.22 +#include <string.h>28.23 +#include <stdlib.h>28.24 +#include <glib/glist.h>28.25 +#include <glib/gstrfuncs.h>28.26 +#include "vmulist.h"28.27 +#include "config.h"28.28 +28.29 +DEFINE_HOOK(vmulist_change_hook, vmulist_change_hook_t);28.30 +28.31 +typedef struct vmulist_entry {28.32 + const gchar *filename;28.33 + vmu_volume_t vol;28.34 + int attach_count;28.35 +} *vmulist_entry_t;28.36 +28.37 +/**28.38 + * Doubly-linked list of vmulist_entry_t maintained in sorted order by display name.28.39 + * Could be augmented with a hashtable if it gets too long28.40 + */28.41 +static GList *vmu_list;28.42 +28.43 +#define ENTRY(it) ((vmulist_entry_t)(it)->data)28.44 +#define VOLUME(it) (ENTRY(it)->vol)28.45 +#define DISPLAY_NAME(it) vmulist_display_name(ENTRY(it))28.46 +28.47 +static const char *vmulist_display_name(vmulist_entry_t ent)28.48 +{28.49 + if( ent->filename == NULL ) {28.50 + return NULL;28.51 + }28.52 + const char *s = strrchr(ent->filename, '/' );28.53 + if( s == NULL || *(s+1) == '\0' ) {28.54 + return ent->filename;28.55 + } else {28.56 + return s+1;28.57 + }28.58 +}28.59 +28.60 +static void vmulist_update_config( void )28.61 +{28.62 + GList *temp = NULL, *it;28.63 +28.64 + for( it = vmu_list; it != NULL; it = g_list_next(it) ) {28.65 + vmulist_entry_t entry = ENTRY(it);28.66 + temp = g_list_append( temp, (char *)entry->filename );28.67 + }28.68 + lxdream_set_global_config_list_value( CONFIG_VMU, temp );28.69 + g_list_free( temp );28.70 +}28.71 +28.72 +static vmulist_entry_t vmulist_get_entry_by_name( const gchar *name )28.73 +{28.74 + GList *it;28.75 + for( it = vmu_list; it != NULL; it = g_list_next(it) ) {28.76 + const gchar *vmu_name = DISPLAY_NAME(it);28.77 + if( name == NULL ? vmu_name == NULL : vmu_name != NULL && strcmp( vmu_name, name ) == 0 ) {28.78 + return ENTRY(it);28.79 + }28.80 + }28.81 + return NULL; // not found28.82 +}28.83 +28.84 +static vmulist_entry_t vmulist_get_entry_by_filename( const gchar *name )28.85 +{28.86 + GList *it;28.87 + for( it = vmu_list; it != NULL; it = g_list_next(it) ) {28.88 + const gchar *vmu_name = ENTRY(it)->filename;28.89 + if( name == NULL ? vmu_name == NULL : vmu_name != NULL && strcmp( vmu_name, name ) == 0 ) {28.90 + return ENTRY(it);28.91 + }28.92 + }28.93 + return NULL; // not found28.94 +}28.95 +28.96 +static vmulist_entry_t vmulist_get_entry_by_volume( vmu_volume_t vol )28.97 +{28.98 + GList *it;28.99 + for( it = vmu_list; it != NULL; it = g_list_next(it) ) {28.100 + if( VOLUME(it) == vol ) {28.101 + return ENTRY(it);28.102 + }28.103 + }28.104 + return NULL; // not found28.105 +}28.106 +28.107 +static vmulist_entry_t vmulist_get_entry_by_index( unsigned int index )28.108 +{28.109 + return (vmulist_entry_t)g_list_nth_data(vmu_list,index);28.110 +}28.111 +28.112 +static gint vmulist_display_name_compare( gconstpointer a, gconstpointer b )28.113 +{28.114 + const char *aname = vmulist_display_name((vmulist_entry_t)a);28.115 + const char *bname = vmulist_display_name((vmulist_entry_t)b);28.116 + if( aname == bname )28.117 + return 0;28.118 + if( aname == NULL )28.119 + return -1;28.120 + if( bname == NULL )28.121 + return 1;28.122 + return strcmp(aname,bname);28.123 +}28.124 +28.125 +/**28.126 + * Add a new entry into the list, maintaining the sorted order.28.127 + * If the filename is already in the list, it is updated instead.28.128 + */28.129 +static vmulist_entry_t vmulist_add_entry( const gchar *filename, vmu_volume_t vol )28.130 +{28.131 + vmulist_entry_t entry = vmulist_get_entry_by_filename(filename);28.132 + if( entry == NULL ) {28.133 + entry = g_malloc( sizeof(struct vmulist_entry) );28.134 + entry->filename = g_strdup(filename);28.135 + entry->vol = vol;28.136 + vmu_list = g_list_insert_sorted(vmu_list, entry, vmulist_display_name_compare );28.137 + } else {28.138 + if( entry->vol != vol && entry->vol != NULL )28.139 + vmu_volume_destroy( entry->vol );28.140 + entry->vol = vol;28.141 + /* NOTE: at the moment this can't require a resort, but if we allow28.142 + * user-editable display names it will28.143 + */28.144 + }28.145 + entry->attach_count = 0;28.146 +28.147 + vmulist_update_config();28.148 + CALL_HOOKS( vmulist_change_hook, VMU_ADDED, g_list_index(vmu_list,entry) );28.149 + return entry;28.150 +}28.151 +28.152 +static void vmulist_remove_entry( vmulist_entry_t entry )28.153 +{28.154 + int idx = g_list_index(vmu_list, entry);28.155 + vmu_list = g_list_remove( vmu_list, entry );28.156 + g_free( (char *)entry->filename );28.157 + g_free( entry );28.158 + vmulist_update_config();28.159 + CALL_HOOKS( vmulist_change_hook, VMU_REMOVED, idx );28.160 +}28.161 +28.162 +static unsigned int vmulist_get_index( vmulist_entry_t entry )28.163 +{28.164 + return g_list_index( vmu_list, entry );28.165 +}28.166 +28.167 +int vmulist_add_vmu( const gchar *filename, vmu_volume_t vol )28.168 +{28.169 + vmulist_entry_t entry = vmulist_add_entry( filename, vol );28.170 + return vmulist_get_index(entry);28.171 +}28.172 +28.173 +void vmulist_remove_vmu( vmu_volume_t vol )28.174 +{28.175 + vmulist_entry_t entry = vmulist_get_entry_by_volume(vol);28.176 + if( entry != NULL ) {28.177 + vmulist_remove_entry(entry);28.178 + }28.179 +}28.180 +28.181 +const char *vmulist_get_name( unsigned int idx )28.182 +{28.183 + vmulist_entry_t entry = vmulist_get_entry_by_index(idx);28.184 + if( entry != NULL ) {28.185 + return vmulist_display_name(entry);28.186 + }28.187 + return NULL;28.188 +}28.189 +28.190 +const char *vmulist_get_filename( unsigned int idx )28.191 +{28.192 + vmulist_entry_t entry = vmulist_get_entry_by_index(idx);28.193 + if( entry != NULL ) {28.194 + return entry->filename;28.195 + }28.196 + return NULL;28.197 +}28.198 +28.199 +const char *vmulist_get_volume_name( vmu_volume_t vol )28.200 +{28.201 + vmulist_entry_t entry = vmulist_get_entry_by_volume(vol);28.202 + if( entry != NULL ) {28.203 + return entry->filename;28.204 + }28.205 + return NULL;28.206 +}28.207 +28.208 +vmu_volume_t vmulist_get_vmu( unsigned int idx )28.209 +{28.210 + vmulist_entry_t entry = vmulist_get_entry_by_index(idx);28.211 + if( entry != NULL ) {28.212 + if( entry->vol == NULL ) {28.213 + entry->vol = vmu_volume_load(entry->filename);28.214 + }28.215 + return entry->vol;28.216 + }28.217 + return NULL;28.218 +}28.219 +28.220 +vmu_volume_t vmulist_get_vmu_by_name( const gchar *name )28.221 +{28.222 + vmulist_entry_t entry = vmulist_get_entry_by_name(name);28.223 + if( entry != NULL ) {28.224 + if( entry->vol == NULL ) {28.225 + entry->vol = vmu_volume_load(entry->filename);28.226 + }28.227 + return entry->vol;28.228 + }28.229 + return NULL;28.230 +}28.231 +28.232 +vmu_volume_t vmulist_get_vmu_by_filename( const gchar *name )28.233 +{28.234 + vmulist_entry_t entry = vmulist_get_entry_by_filename(name);28.235 + if( entry != NULL ) {28.236 + if( entry->vol == NULL ) {28.237 + entry->vol = vmu_volume_load(entry->filename);28.238 + }28.239 + return entry->vol;28.240 + } else {28.241 + vmu_volume_t vol = vmu_volume_load( name );28.242 + vmulist_add_entry( name, vol );28.243 + return vol;28.244 + }28.245 +}28.246 +28.247 +int vmulist_get_index_by_filename( const gchar *name )28.248 +{28.249 + vmulist_entry_t entry = vmulist_get_entry_by_filename(name);28.250 + if( entry != NULL ) {28.251 + return g_list_index( vmu_list, entry );28.252 + }28.253 + return -1;28.254 +}28.255 +28.256 +28.257 +int vmulist_create_vmu( const gchar *filename, gboolean create_only )28.258 +{28.259 + vmu_volume_t vol = vmu_volume_new_default(filename);28.260 +28.261 + if( vmu_volume_save( filename, vol, create_only ) ) {28.262 + return vmulist_add_vmu( filename, vol );28.263 + } else {28.264 + vmu_volume_destroy(vol);28.265 + }28.266 + return -1;28.267 +}28.268 +28.269 +gboolean vmulist_attach_vmu( vmu_volume_t vol, const gchar *where )28.270 +{28.271 + vmulist_entry_t entry = vmulist_get_entry_by_volume(vol);28.272 + if( entry == NULL ) {28.273 + return FALSE;28.274 + }28.275 + entry->attach_count++;28.276 + return TRUE;28.277 +}28.278 +28.279 +void vmulist_detach_vmu( vmu_volume_t vol )28.280 +{28.281 + vmulist_entry_t entry = vmulist_get_entry_by_volume(vol);28.282 + if( entry != NULL && entry->attach_count > 0 ) {28.283 + entry->attach_count--;28.284 + }28.285 +}28.286 +28.287 +unsigned int vmulist_get_size(void)28.288 +{28.289 + return g_list_length(vmu_list);28.290 +}28.291 +28.292 +void vmulist_init( void )28.293 +{28.294 + GList *filenames = lxdream_get_global_config_list_value( CONFIG_VMU );28.295 + GList *ptr;28.296 + for( ptr = filenames; ptr != NULL; ptr = g_list_next(ptr) ) {28.297 + vmulist_add_entry( (gchar *)ptr->data, NULL );28.298 + g_free( ptr->data );28.299 + }28.300 + g_list_free( filenames );28.301 +}28.302 +28.303 +void vmulist_save_all( void )28.304 +{28.305 + GList *it;28.306 + for( it = vmu_list; it != NULL; it = g_list_next(it) ) {28.307 + vmulist_entry_t entry = ENTRY(it);28.308 + if( entry->vol != NULL && vmu_volume_is_dirty(entry->vol) ) {28.309 + vmu_volume_save(entry->filename, entry->vol, FALSE);28.310 + }28.311 + }28.312 +}28.313 +28.314 +void vmulist_shutdown( void )28.315 +{28.316 + vmulist_save_all();28.317 +}
29.1 --- /dev/null Thu Jan 01 00:00:00 1970 +000029.2 +++ b/src/vmu/vmulist.h Wed Jun 24 02:41:12 2009 +000029.3 @@ -0,0 +1,95 @@29.4 +/**29.5 + * $Id: vmulist.h 869 2008-09-08 07:56:33Z nkeynes $29.6 + *29.7 + * VMU management - maintains a list of all known VMUs29.8 + *29.9 + * Copyright (c) 2009 Nathan Keynes.29.10 + *29.11 + * This program is free software; you can redistribute it and/or modify29.12 + * it under the terms of the GNU General Public License as published by29.13 + * the Free Software Foundation; either version 2 of the License, or29.14 + * (at your option) any later version.29.15 + *29.16 + * This program is distributed in the hope that it will be useful,29.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of29.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the29.19 + * GNU General Public License for more details.29.20 + */29.21 +29.22 +29.23 +#ifndef lxdream_vmulist_H29.24 +#define lxdream_vmulist_H 129.25 +29.26 +#ifdef __cplusplus29.27 +extern "C" {29.28 +#endif29.29 +29.30 +#include "hook.h"29.31 +#include "vmu/vmuvol.h"29.32 +29.33 +typedef enum { VMU_ADDED, VMU_MODIFIED, VMU_REMOVED } vmulist_change_type_t;29.34 +29.35 +/* Hook for notification of list change events */29.36 +typedef gboolean (*vmulist_change_hook_t)(vmulist_change_type_t change, int rowidx, void *user_data);29.37 +DECLARE_HOOK(vmulist_change_hook, vmulist_change_hook_t);29.38 +29.39 +vmu_volume_t vmulist_get_vmu(unsigned int index);29.40 +29.41 +/** Retrieve a known vmu by name */29.42 +vmu_volume_t vmulist_get_vmu_by_name(const gchar *name);29.43 +29.44 +/** Retrieve a vmu by filename. The filename/vmu will be added to the list if it's29.45 + * not already in it.29.46 + */29.47 +vmu_volume_t vmulist_get_vmu_by_filename(const gchar *name);29.48 +29.49 +const char *vmulist_get_name(unsigned int index);29.50 +29.51 +const char *vmulist_get_filename(unsigned int index);29.52 +29.53 +const char *vmulist_get_volume_name( vmu_volume_t vol );29.54 +29.55 +29.56 +29.57 +/** Mark a VMU as being attached.29.58 + * @return FALSE if the VMU was already attached, otherwise TRUE29.59 + */29.60 +gboolean vmulist_attach_vmu( vmu_volume_t vol, const gchar *where );29.61 +29.62 +/** Mark a VMU as detached. */29.63 +void vmulist_detach_vmu( vmu_volume_t vol );29.64 +29.65 +/**29.66 + * Create a new VMU at the given filename, and add it to the list29.67 + * @param filename to save the new VMU as29.68 + * @param create_only if TRUE, the file must not already exist. If FALSE,29.69 + * the create will overwrite any existing file at that filename.29.70 + * @return index of the VMU in the list, or -1 if the call failed.29.71 + **/29.72 +int vmulist_create_vmu(const gchar *filename, gboolean create_only);29.73 +29.74 +/** Add a VMU volume to the list. Returns the index of the added volume */29.75 +int vmulist_add_vmu(const gchar *filename, vmu_volume_t vol);29.76 +29.77 +int vmulist_get_index_by_filename( const gchar *name );29.78 +29.79 +/** Remove a VMU volume from the list */29.80 +void vmulist_remove_vmu(vmu_volume_t vol);29.81 +29.82 +/** Initialize the list */29.83 +void vmulist_init(void);29.84 +29.85 +/** Save all VMUs in the list (actually only ones which have been written to29.86 + * some point)29.87 + **/29.88 +void vmulist_save_all(void);29.89 +29.90 +void vmulist_shutdown(void);29.91 +29.92 +unsigned int vmulist_get_size(void);29.93 +29.94 +#ifdef __cplusplus29.95 +}29.96 +#endif29.97 +29.98 +#endif /* !lxdream_vmulist_H */
30.1 --- /dev/null Thu Jan 01 00:00:00 1970 +000030.2 +++ b/src/vmu/vmuvol.c Wed Jun 24 02:41:12 2009 +000030.3 @@ -0,0 +1,375 @@30.4 +/**30.5 + * $Id: vmuvol.h 869 2008-09-08 07:56:33Z nkeynes $30.6 + *30.7 + * VMU volume (ie block device) support30.8 + *30.9 + * Copyright (c) 2009 Nathan Keynes.30.10 + *30.11 + * This program is free software; you can redistribute it and/or modify30.12 + * it under the terms of the GNU General Public License as published by30.13 + * the Free Software Foundation; either version 2 of the License, or30.14 + * (at your option) any later version.30.15 + *30.16 + * This program is distributed in the hope that it will be useful,30.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of30.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the30.19 + * GNU General Public License for more details.30.20 + */30.21 +30.22 +#include <glib/gmem.h>30.23 +#include <glib/gstrfuncs.h>30.24 +#include <string.h>30.25 +#include <stdio.h>30.26 +#include <fcntl.h>30.27 +#include <errno.h>30.28 +30.29 +#include "vmu/vmuvol.h"30.30 +#include "dream.h"30.31 +30.32 +#define VMU_MAX_PARTITIONS 25630.33 +#define VMU_MAX_BLOCKS 65536 /* Actually slightly less than this, but it'll do */30.34 +30.35 +typedef struct vmu_partition {30.36 + struct vmu_volume_metadata metadata;30.37 + uint32_t block_count;30.38 + char *blocks;30.39 +} *vmu_partition_t;30.40 +30.41 +struct vmu_volume {30.42 + const gchar *display_name;30.43 + vmu_partnum_t part_count;30.44 + gboolean dirty;30.45 + struct vmu_partition part[0];30.46 +};30.47 +30.48 +/* On-VMU structures, courtesy of Marcus Comstedt */30.49 +struct vmu_superblock {30.50 + char magic[16];30.51 + uint8_t colour_flag;30.52 + uint8_t bgra[4];30.53 + uint8_t pad1[27];30.54 + char timestamp[8];30.55 + char pad2[8];30.56 + char unknown[6];30.57 + uint16_t fat_block;30.58 + uint16_t fat_size;30.59 + uint16_t dir_block;30.60 + uint16_t dir_size;30.61 + uint16_t icon_shape;30.62 + uint16_t user_size;30.63 + /* remainder unknown */30.64 +};30.65 +30.66 +struct vmu_direntry {30.67 + uint8_t filetype;30.68 + uint8_t copy_flag;30.69 + uint16_t blkno;30.70 + char filename[12];30.71 + char timestamp[8];30.72 + uint16_t blksize; /* Size in blocks*/30.73 + uint16_t hdroff; /* Header offset in blocks */30.74 + char pad[4];30.75 +};30.76 +30.77 +#define MD(vmu,ptno) ((vmu)->part[ptno].metadata)30.78 +30.79 +#define VMU_BLOCK(vmu,ptno,blkno) (&(vmu)->part[ptno].blocks[(blkno)*VMU_BLOCK_SIZE])30.80 +30.81 +#define VMU_FAT_ENTRY(vmu,pt,ent) ((uint16_t *)VMU_BLOCK(vmu, pt, (MD(vmu,pt).fat_block - ((ent)>>8))))[(ent)&0xFF]30.82 +30.83 +#define FAT_EMPTY 0xFFFC30.84 +#define FAT_EOF 0xFFFA30.85 +30.86 +static const struct vmu_volume_metadata default_metadata = { 255, 255, 254, 1, 253, 13, 0, 200, 31, 0, 128 };30.87 +30.88 +vmu_volume_t vmu_volume_new_default( const gchar *display_name )30.89 +{30.90 + vmu_volume_t vol = g_malloc0( sizeof(struct vmu_volume) + sizeof(struct vmu_partition) );30.91 + vol->part_count = 1;30.92 + vol->dirty = FALSE;30.93 + memcpy( &vol->part[0].metadata, &default_metadata, sizeof(struct vmu_volume_metadata) );30.94 + vol->part[0].block_count = VMU_DEFAULT_VOL_BLOCKS;30.95 + vol->part[0].blocks = g_malloc0( VMU_DEFAULT_VOL_BLOCKS * VMU_BLOCK_SIZE );30.96 + vol->display_name = display_name == NULL ? NULL : g_strdup(display_name);30.97 + vmu_volume_format( vol, 0, TRUE );30.98 + return vol;30.99 +}30.100 +30.101 +void vmu_volume_destroy( vmu_volume_t vol )30.102 +{30.103 + int i;30.104 + if( vol == NULL )30.105 + return;30.106 +30.107 + for( i=0; i<vol->part_count; i++ ) {30.108 + g_free( vol->part[i].blocks );30.109 + vol->part[i].blocks = NULL;30.110 + }30.111 + if( vol->display_name ) {30.112 + g_free( (char *)vol->display_name );30.113 + vol->display_name = NULL;30.114 + }30.115 + g_free(vol);30.116 +}30.117 +30.118 +void vmu_volume_format( vmu_volume_t vol, vmu_partnum_t pt, gboolean quick )30.119 +{30.120 + if( pt >= vol->part_count ) {30.121 + return;30.122 + }30.123 +30.124 + if( !quick ) {30.125 + /* Wipe it completely first */30.126 + memset( vol->part[pt].blocks, 0, (vol->part[pt].block_count) * VMU_BLOCK_SIZE );30.127 + }30.128 +30.129 + struct vmu_volume_metadata *meta = &vol->part[pt].metadata;30.130 + unsigned int fatblkno = meta->fat_block;30.131 + unsigned int dirblkno = meta->dir_block;30.132 +30.133 + /* Write superblock */30.134 + struct vmu_superblock *super = (struct vmu_superblock *)VMU_BLOCK(vol,pt, meta->super_block);30.135 + memset( super->magic, 0x55, 16 );30.136 + memset( &super->colour_flag, 0, 240 ); /* Blank the rest for now */30.137 + super->fat_block = meta->fat_block;30.138 + super->fat_size = meta->fat_size;30.139 + super->dir_block = meta->dir_block;30.140 + super->user_size = meta->user_size;30.141 +30.142 + /* Write file allocation tables */30.143 + int i,j;30.144 + for( j=0; j<meta->fat_size; j++ ) {30.145 + uint16_t *fat = (uint16_t *)VMU_BLOCK(vol,pt,fatblkno-j);30.146 + for( i=0; i<256; i++ ) {30.147 + fat[i] = FAT_EMPTY;30.148 + }30.149 + }30.150 +30.151 + /* Fill in the system allocations in the FAT */30.152 + for( i=0; i<meta->fat_size-1; i++ ) {30.153 + VMU_FAT_ENTRY(vol,pt,fatblkno-i) = fatblkno-i-1;30.154 + }30.155 + VMU_FAT_ENTRY(vol,pt,fatblkno - i) = FAT_EOF;30.156 + for( i=0; i<meta->dir_size-1; i++ ) {30.157 + VMU_FAT_ENTRY(vol,pt,dirblkno-i) = dirblkno-i-1;30.158 + }30.159 + VMU_FAT_ENTRY(vol,pt,dirblkno-i) = FAT_EOF;30.160 +30.161 + /* If quick-format, blank the directory. Otherwise it's already been done */30.162 + if( quick ) {30.163 + memset( VMU_BLOCK(vol,pt,dirblkno-meta->dir_size+1),30.164 + 0, meta->dir_size * VMU_BLOCK_SIZE );30.165 + }30.166 +}30.167 +30.168 +/*************************** File load/save ********************************/30.169 +30.170 +/**30.171 + * Current file has 1 META chunk for all volume metadata, followed by a30.172 + * DATA chunk for each partition's block data. The META chunk is required to30.173 + * occur before any DATA blocks.30.174 + * Unknown chunks are skipped to allow for forwards compatibility if/when30.175 + * we add the VMU runtime side of things30.176 + */30.177 +30.178 +struct vmu_file_header {30.179 + char magic[16];30.180 + uint32_t version;30.181 + uint32_t head_len;30.182 + uint32_t part_count;30.183 + uint32_t display_name_len;30.184 + char display_name[0];30.185 +};30.186 +30.187 +struct vmu_chunk_header {30.188 + char name[4];30.189 + uint32_t length;30.190 +};30.191 +30.192 +30.193 +30.194 +gboolean vmu_volume_save( const gchar *filename, vmu_volume_t vol, gboolean create_only )30.195 +{30.196 + struct vmu_file_header head;30.197 + struct vmu_chunk_header chunk;30.198 + int i;30.199 +30.200 + FILE *f = fopen( filename, (create_only ? "wx" : "w") ); /* Portable? */30.201 + if( f == NULL ) {30.202 + return FALSE;30.203 + }30.204 +30.205 + /* File header */30.206 + memcpy( head.magic, VMU_FILE_MAGIC, 16 );30.207 + head.version = VMU_FILE_VERSION;30.208 + head.part_count = vol->part_count;30.209 + head.display_name_len = vol->display_name == NULL ? 0 : (strlen(vol->display_name)+1);30.210 + head.head_len = sizeof(head) + head.display_name_len;30.211 + fwrite( &head, sizeof(head), 1, f );30.212 + if( vol->display_name != NULL ) {30.213 + fwrite( vol->display_name, head.display_name_len, 1, f );30.214 + }30.215 +30.216 + /* METAdata chunk */30.217 + memcpy( chunk.name, "META", 4 );30.218 + chunk.length = sizeof(struct vmu_volume_metadata) * vol->part_count;30.219 + fwrite( &chunk, sizeof(chunk), 1, f );30.220 + for( i=0; i < vol->part_count; i++ ) {30.221 + fwrite( &vol->part[i].metadata, sizeof(struct vmu_volume_metadata), 1, f );30.222 + }30.223 +30.224 + /* partition DATA chunks */30.225 + for( i=0; i< vol->part_count; i++ ) {30.226 + memcpy( chunk.name, "DATA", 4 );30.227 + chunk.length = 0;30.228 + fwrite( &chunk, sizeof(chunk), 1, f );30.229 + long posn = ftell(f);30.230 + fwrite( &vol->part[i].block_count, sizeof(vol->part[i].block_count), 1, f );30.231 + fwrite_gzip( vol->part[i].blocks, vol->part[i].block_count, VMU_BLOCK_SIZE, f );30.232 + long end = ftell(f);30.233 + fseek( f, posn - sizeof(chunk.length), SEEK_SET );30.234 + chunk.length = end-posn;30.235 + fwrite( &chunk.length, sizeof(chunk.length), 1, f );30.236 + fseek( f, end, SEEK_SET );30.237 + }30.238 + fclose(f);30.239 + vol->dirty = FALSE;30.240 + return TRUE;30.241 +}30.242 +30.243 +vmu_volume_t vmu_volume_load( const gchar *filename )30.244 +{30.245 + struct vmu_file_header head;30.246 + struct vmu_chunk_header chunk;30.247 + vmu_volume_t vol;30.248 + int i;30.249 +30.250 + FILE *f = fopen( filename, "ro" );30.251 + if( f == NULL ) {30.252 + ERROR( "Unable to open VMU file '%s': %s", filename, strerror(errno) );30.253 + return FALSE;30.254 + }30.255 +30.256 + if( fread( &head, sizeof(head), 1, f ) != 1 ||30.257 + memcmp(head.magic, VMU_FILE_MAGIC, 16) != 0 ||30.258 + head.part_count > VMU_MAX_PARTITIONS ||30.259 + head.head_len < (sizeof(head) + head.display_name_len) ) {30.260 + fclose(f);30.261 + ERROR( "Unable to load VMU '%s': bad file header", filename );30.262 + return NULL;30.263 + }30.264 +30.265 + vol = (vmu_volume_t)g_malloc0( sizeof(struct vmu_volume) + sizeof(struct vmu_partition)*head.part_count );30.266 + vol->part_count = head.part_count;30.267 + vol->dirty = FALSE;30.268 + if( head.display_name_len != 0 ) {30.269 + vol->display_name = g_malloc( head.display_name_len );30.270 + fread( (char *)vol->display_name, head.display_name_len, 1, f );30.271 + }30.272 + fseek( f, head.head_len, SEEK_SET );30.273 +30.274 + gboolean have_meta = FALSE;30.275 + int next_part = 0;30.276 + while( !feof(f) && fread( &chunk, sizeof(chunk), 1, f ) == 1 ) {30.277 + if( memcmp( &chunk.name, "META", 4 ) == 0 ) {30.278 + if( have_meta || chunk.length != head.part_count * sizeof(struct vmu_volume_metadata) ) {30.279 + vmu_volume_destroy(vol);30.280 + fclose(f);30.281 + ERROR( "Unable to load VMU '%s': bad metadata size (expected %d but was %d)", filename,30.282 + head.part_count * sizeof(struct vmu_volume_metadata), chunk.length );30.283 + return NULL;30.284 + }30.285 + for( i=0; i<head.part_count; i++ ) {30.286 + fread( &vol->part[i].metadata, sizeof(struct vmu_volume_metadata), 1, f );30.287 + }30.288 + have_meta = TRUE;30.289 + } else if( memcmp( &chunk.name, "DATA", 4 ) == 0 ) {30.290 + uint32_t block_count;30.291 + fread( &block_count, sizeof(block_count), 1, f );30.292 + if( next_part >= vol->part_count || block_count >= VMU_MAX_BLOCKS ) {30.293 + // Too many partitions / blocks30.294 + vmu_volume_destroy(vol);30.295 + fclose(f);30.296 + ERROR( "Unable to load VMU '%s': too large (%d/%d)", filename, next_part, block_count );30.297 + return NULL;30.298 + }30.299 + vol->part[next_part].block_count = block_count;30.300 + vol->part[next_part].blocks = g_malloc(block_count*VMU_BLOCK_SIZE);30.301 + fread_gzip(vol->part[next_part].blocks, VMU_BLOCK_SIZE, block_count, f );30.302 + next_part++;30.303 + } else {30.304 + // else skip unknown block30.305 + fseek( f, SEEK_CUR, chunk.length );30.306 + WARN( "Unexpected VMU data chunk: '%4.4s'", chunk.name );30.307 + }30.308 + }30.309 +30.310 + fclose(f);30.311 +30.312 + if( !have_meta || next_part != vol->part_count ) {30.313 + vmu_volume_destroy( vol );30.314 + return NULL;30.315 + }30.316 +30.317 + return vol;30.318 +}30.319 +30.320 +/*************************** Accessing data ********************************/30.321 +const char *vmu_volume_get_display_name( vmu_volume_t vol )30.322 +{30.323 + return vol->display_name;30.324 +}30.325 +30.326 +void vmu_volume_set_display_name( vmu_volume_t vol, const gchar *name )30.327 +{30.328 + if( vol->display_name != NULL ) {30.329 + g_free( (char *)vol->display_name );30.330 + }30.331 + if( name == NULL ) {30.332 + vol->display_name = NULL;30.333 + } else {30.334 + vol->display_name = g_strdup(name);30.335 + }30.336 +}30.337 +30.338 +gboolean vmu_volume_is_dirty( vmu_volume_t vol )30.339 +{30.340 + return vol->dirty;30.341 +}30.342 +30.343 +gboolean vmu_volume_read_block( vmu_volume_t vol, vmu_partnum_t pt, unsigned int block, unsigned char *out )30.344 +{30.345 + if( pt >= vol->part_count || block >= vol->part[pt].block_count ) {30.346 + return FALSE;30.347 + }30.348 +30.349 + memcpy( out, VMU_BLOCK(vol,pt,block), VMU_BLOCK_SIZE );30.350 + return TRUE;30.351 +}30.352 +30.353 +gboolean vmu_volume_write_block( vmu_volume_t vol, vmu_partnum_t pt, unsigned int block, unsigned char *in )30.354 +{30.355 + if( pt >= vol->part_count || block >= vol->part[pt].block_count ) {30.356 + return FALSE;30.357 + }30.358 + memcpy( VMU_BLOCK(vol,pt,block), in, VMU_BLOCK_SIZE );30.359 + vol->dirty = TRUE;30.360 +}30.361 +30.362 +gboolean vmu_volume_write_phase( vmu_volume_t vol, vmu_partnum_t pt, unsigned int block, unsigned int phase, unsigned char *in )30.363 +{30.364 + if( pt >= vol->part_count || block >= vol->part[pt].block_count || phase >= 4 ) {30.365 + return FALSE;30.366 + }30.367 + memcpy( VMU_BLOCK(vol,pt,block) + (phase*128), in, VMU_BLOCK_SIZE/4 );30.368 + vol->dirty = TRUE;30.369 +}30.370 +30.371 +const struct vmu_volume_metadata *vmu_volume_get_metadata( vmu_volume_t vol, vmu_partnum_t partition )30.372 +{30.373 + if( partition >= vol->part_count ) {30.374 + return NULL;30.375 + } else {30.376 + return &vol->part[partition].metadata;30.377 + }30.378 +}
31.1 --- /dev/null Thu Jan 01 00:00:00 1970 +000031.2 +++ b/src/vmu/vmuvol.h Wed Jun 24 02:41:12 2009 +000031.3 @@ -0,0 +1,116 @@31.4 +/**31.5 + * $Id: vmuvol.h 869 2008-09-08 07:56:33Z nkeynes $31.6 + *31.7 + * VMU volume (ie block device) declarations31.8 + *31.9 + * Copyright (c) 2009 Nathan Keynes.31.10 + *31.11 + * This program is free software; you can redistribute it and/or modify31.12 + * it under the terms of the GNU General Public License as published by31.13 + * the Free Software Foundation; either version 2 of the License, or31.14 + * (at your option) any later version.31.15 + *31.16 + * This program is distributed in the hope that it will be useful,31.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of31.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the31.19 + * GNU General Public License for more details.31.20 + */31.21 +31.22 +#ifndef lxdream_vmuvol_H31.23 +#define lxdream_vmuvol_H 131.24 +31.25 +#ifdef __cplusplus31.26 +extern "C" {31.27 +#endif31.28 +31.29 +#include "lxdream.h"31.30 +31.31 +typedef struct vmu_volume *vmu_volume_t;31.32 +typedef unsigned int vmu_partnum_t;31.33 +31.34 +#define VMU_FILE_MAGIC "%!Dreamcast$VMU\0"31.35 +#define VMU_FILE_VERSION 0x0001000031.36 +31.37 +/** VMU block size is 512 bytes */31.38 +#define VMU_BLOCK_SIZE 51231.39 +31.40 +/** Default VMU volume is 256 blocks */31.41 +#define VMU_DEFAULT_VOL_BLOCKS 25631.42 +31.43 +/** Default VMU has 200 user blocks */31.44 +#define VMU_DEFAULT_VOL_USERBLOCKS 20031.45 +31.46 +/** Default superblock is at block 255 */31.47 +#define VMU_DEFAULT_VOL_SUPERBLOCK 25531.48 +31.49 +/** Default file allocation table is at block 254 */31.50 +#define VMU_DEFAULT_VOL_FATBLOCK 25431.51 +31.52 +/** Default root directory block starts at block 253 */31.53 +#define VMU_DEFAULT_VOL_ROOTDIR 25331.54 +31.55 +/**31.56 + * VMU metadata structure. Note that this is structured to match the maple31.57 + * memory info result packet.31.58 + */31.59 +struct vmu_volume_metadata {31.60 + uint32_t last_block;31.61 + uint16_t super_block;31.62 + uint16_t fat_block;31.63 + uint16_t fat_size;31.64 + uint16_t dir_block;31.65 + uint16_t dir_size;31.66 + uint16_t user_block; /* ?? */31.67 + uint16_t user_size;31.68 + uint16_t unknown[3]; /* 0x001F, 0x0000, 0x0080 */31.69 +};31.70 +31.71 +/**31.72 + * Construct a new VMU volume with a single partition of the default size31.73 + * (128Kb). The partitions is formatted using the default filesystem31.74 + * organization.31.75 + */31.76 +vmu_volume_t vmu_volume_new_default( const gchar *display_name );31.77 +31.78 +void vmu_volume_destroy( vmu_volume_t vol );31.79 +31.80 +void vmu_volume_set_display_name( vmu_volume_t vol, const gchar *display_name );31.81 +31.82 +const gchar *vmu_volume_get_display_name( vmu_volume_t vol );31.83 +31.84 +gboolean vmu_volume_is_dirty( vmu_volume_t vol );31.85 +31.86 +/**31.87 + * Format a VMU partition according to the standard layout31.88 + */31.89 +void vmu_volume_format( vmu_volume_t vol, vmu_partnum_t partition, gboolean quick );31.90 +31.91 +31.92 +31.93 +/**31.94 + * Load a VMU volume from a file.31.95 + */31.96 +vmu_volume_t vmu_volume_load( const gchar *filename );31.97 +31.98 +/**31.99 + * Save a VMU volume to a file.31.100 + */31.101 +gboolean vmu_volume_save( const gchar *filename, vmu_volume_t vol, gboolean create_only );31.102 +31.103 +gboolean vmu_volume_read_block( vmu_volume_t vol, vmu_partnum_t partition, unsigned int block, unsigned char *out );31.104 +gboolean vmu_volume_write_block( vmu_volume_t vol, vmu_partnum_t partition, unsigned int block, unsigned char *in );31.105 +gboolean vmu_volume_write_phase( vmu_volume_t vol, vmu_partnum_t partition, unsigned int block,31.106 + unsigned int phase, unsigned char *in );31.107 +31.108 +/**31.109 + * Retrieve the metadata for the given volume. The metadata is owned by the31.110 + * volume and should not be modified or freed.31.111 + */31.112 +const struct vmu_volume_metadata *vmu_volume_get_metadata( vmu_volume_t vol, vmu_partnum_t partition );31.113 +31.114 +31.115 +#ifdef __cplusplus31.116 +}31.117 +#endif31.118 +31.119 +#endif /* !lxdream_vmuvol_H */
.