Search
lxdream.org :: lxdream :: r1034:7044e01148f0
lxdream 0.9.1
released Jun 29
Download Now
changeset1034:7044e01148f0
parent1033:b77b081441b5
child1035:e3093fd7d1da
authornkeynes
dateWed Jun 24 02:41:12 2009 +0000 (10 years ago)
Add initial VMU support
po/POTFILES.in
po/de.po
po/es.po
po/it.po
po/lxdream.pot
po/pt_BR.po
src/Makefile.am
src/Makefile.in
src/cocoaui/cocoa_ctrl.m
src/cocoaui/cocoa_prefs.m
src/config.c
src/config.h
src/dreamcast.c
src/gdlist.c
src/gtkui/gtk_ctrl.c
src/gtkui/gtk_gd.c
src/gtkui/gtkcb.c
src/gtkui/gtkui.h
src/hook.h
src/main.c
src/maple/controller.c
src/maple/kbd.c
src/maple/lightgun.c
src/maple/maple.c
src/maple/maple.h
src/maple/mouse.c
src/maple/vmu.c
src/vmu/vmulist.c
src/vmu/vmulist.h
src/vmu/vmuvol.c
src/vmu/vmuvol.h
1.1 --- a/po/POTFILES.in Wed Jun 24 02:27:34 2009 +0000
1.2 +++ b/po/POTFILES.in Wed Jun 24 02:41:12 2009 +0000
1.3 @@ -108,6 +108,7 @@
1.4 src/maple/maple.c
1.5 src/maple/maple.h
1.6 src/maple/mouse.c
1.7 +src/maple/vmu.c
1.8 src/mem.c
1.9 src/mem.h
1.10 src/mmio.h
1.11 @@ -170,6 +171,10 @@
1.12 src/tools/insparse.c
1.13 src/util.c
1.14 src/version.c
1.15 +src/vmu/vmulist.c
1.16 +src/vmu/vmulist.h
1.17 +src/vmu/vmuvol.c
1.18 +src/vmu/vmuvol.h
1.19 src/watch.c
1.20 src/x86dasm/ansidecl.h
1.21 src/x86dasm/bfd.h
2.1 --- a/po/de.po Wed Jun 24 02:27:34 2009 +0000
2.2 +++ b/po/de.po Wed Jun 24 02:41:12 2009 +0000
2.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.15
2.16 -#: src/cocoaui/cocoa_ctrl.m:342 src/gtkui/gtk_ctrl.c:294
2.17 -#, c-format
2.18 -msgid "Slot %d."
2.19 +#: src/cocoaui/cocoa_ctrl.m:324 src/gtkui/gtk_ctrl.c:486
2.20 +#, fuzzy, c-format
2.21 +msgid "Port %c."
2.22 msgstr "Slot %d."
2.23
2.24 -#: src/cocoaui/cocoaui.m:404
2.25 +#: src/cocoaui/cocoa_ctrl.m:326 src/gtkui/gtk_ctrl.c:515
2.26 +#, c-format
2.27 +msgid "VMU %d."
2.28 +msgstr ""
2.29 +
2.30 +#: src/cocoaui/cocoaui.m:412
2.31 #, c-format
2.32 msgid "Running (%2.4f%%)"
2.33 msgstr ""
2.34
2.35 -#: src/cocoaui/cocoa_win.m:192 src/gtkui/gtk_win.c:356
2.36 +#: src/cocoaui/cocoa_win.m:193 src/gtkui/gtk_win.c:356
2.37 msgid "(Press <ctrl><alt> to release grab)"
2.38 msgstr ""
2.39
2.40 -#: src/cocoaui/cocoa_win.m:204 src/gtkui/gtk_win.c:366
2.41 +#: src/cocoaui/cocoa_win.m:205 src/gtkui/gtk_win.c:366
2.42 msgid "Running"
2.43 msgstr ""
2.44
2.45 -#: src/cocoaui/cocoa_win.m:207 src/gtkui/gtk_win.c:366
2.46 +#: src/cocoaui/cocoa_win.m:208 src/gtkui/gtk_win.c:366
2.47 msgid "Stopped"
2.48 msgstr ""
2.49
2.50 @@ -56,32 +61,36 @@
2.51 msgid "Save-state path"
2.52 msgstr "Speicherstand pfad"
2.53
2.54 -#: src/config.c:45 src/gtkui/gtk_path.c:29
2.55 +#: src/config.c:45
2.56 +msgid "VMU path"
2.57 +msgstr ""
2.58 +
2.59 +#: src/config.c:46 src/gtkui/gtk_path.c:29
2.60 msgid "Bootstrap IP.BIN"
2.61 msgstr "Bootstrap IP.BIN"
2.62
2.63 -#: src/config.c:51
2.64 +#: src/config.c:53
2.65 msgid "Serial device"
2.66 msgstr ""
2.67
2.68 -#: src/dreamcast.c:192
2.69 +#: src/dreamcast.c:193
2.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.75
2.76 -#: src/dreamcast.c:324
2.77 +#: src/dreamcast.c:328
2.78 #, c-format
2.79 msgid "File is not a %s save state"
2.80 msgstr ""
2.81
2.82 -#: src/dreamcast.c:329
2.83 +#: src/dreamcast.c:333
2.84 #, c-format
2.85 msgid "Unsupported %s save state version"
2.86 msgstr ""
2.87
2.88 -#: src/dreamcast.c:334
2.89 +#: src/dreamcast.c:338
2.90 #, c-format
2.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.96
2.97 -#: src/gdlist.c:206 src/gdlist.c:229
2.98 +#: src/gdlist.c:187 src/gdlist.c:210
2.99 msgid "Empty"
2.100 msgstr "Leer"
2.101
2.102 @@ -142,48 +151,65 @@
2.103 msgid "All files"
2.104 msgstr "Alle Dateien"
2.105
2.106 -#: src/gtkui/gtkcb.c:139
2.107 +#: src/gtkui/gtkcb.c:162
2.108 msgid "Load state..."
2.109 msgstr "Speicherpunkt laden..."
2.110
2.111 -#: src/gtkui/gtkcb.c:144 src/gtkui/gtkcb.c:175
2.112 +#: src/gtkui/gtkcb.c:167 src/gtkui/gtkcb.c:198
2.113 msgid "lxDream Save State (*.dst)"
2.114 msgstr "lxDream Speicherpunt (*.dst)"
2.115
2.116 -#: src/gtkui/gtkcb.c:237 src/gtkui/gtk_dump.c:69
2.117 +#: src/gtkui/gtkcb.c:260 src/gtkui/gtk_dump.c:69
2.118 msgid "Memory dump"
2.119 msgstr "Speicher dump"
2.120
2.121 -#: src/gtkui/gtkcb.c:250
2.122 +#: src/gtkui/gtkcb.c:273
2.123 msgid "Save next scene..."
2.124 msgstr "Nächste Szene speichern"
2.125
2.126 -#: src/gtkui/gtkcb.c:250
2.127 +#: src/gtkui/gtkcb.c:273
2.128 msgid "lxdream scene file (*.dsc)"
2.129 msgstr "lxdream szene Datei (*.dsc)"
2.130
2.131 -#: src/gtkui/gtkcb.c:265
2.132 +#: src/gtkui/gtkcb.c:288
2.133 msgid "No address selected, so can't run to it"
2.134 msgstr "Keine Adresse ausgewählt, also kann es nicht laufen"
2.135
2.136 -#: src/gtkui/gtk_ctrl.c:72 src/gtkui/gtk_ctrl.c:101 src/gtkui/gtk_hotkeys.c:50
2.137 +#: src/gtkui/gtk_ctrl.c:80 src/gtkui/gtk_ctrl.c:109 src/gtkui/gtk_hotkeys.c:50
2.138 #: src/gtkui/gtk_hotkeys.c:79
2.139 msgid "<press key>"
2.140 msgstr "<Taste drücken>"
2.141
2.142 -#: src/gtkui/gtk_ctrl.c:201
2.143 +#: src/gtkui/gtk_ctrl.c:209
2.144 msgid "Controller Configuration"
2.145 msgstr "Kontroller Konfiguration"
2.146
2.147 -#: src/gtkui/gtk_ctrl.c:220
2.148 +#: src/gtkui/gtk_ctrl.c:228
2.149 msgid "No configuration page available for device type"
2.150 msgstr "Keine Konfigurationseite für dieses Gerät"
2.151
2.152 -#: src/gtkui/gtk_ctrl.c:297
2.153 +#: src/gtkui/gtk_ctrl.c:252
2.154 +msgid "Load VMU"
2.155 +msgstr ""
2.156 +
2.157 +#: src/gtkui/gtk_ctrl.c:266
2.158 +msgid "Create VMU"
2.159 +msgstr ""
2.160 +
2.161 +#: src/gtkui/gtk_ctrl.c:329 src/gtkui/gtk_ctrl.c:347
2.162 msgid "<empty>"
2.163 msgstr "<leer>"
2.164
2.165 -#: src/gtkui/gtk_ctrl.c:325
2.166 +#: src/gtkui/gtk_ctrl.c:356
2.167 +#, fuzzy
2.168 +msgid "Load VMU..."
2.169 +msgstr "Speicherpunkt laden..."
2.170 +
2.171 +#: src/gtkui/gtk_ctrl.c:357
2.172 +msgid "Create VMU..."
2.173 +msgstr ""
2.174 +
2.175 +#: src/gtkui/gtk_ctrl.c:551
2.176 msgid "Controller Settings"
2.177 msgstr "Kontroller einstellungen"
2.178
2.179 @@ -571,139 +597,139 @@
2.180 msgid "Select quick save state 9"
2.181 msgstr ""
2.182
2.183 -#: src/main.c:85
2.184 +#: src/main.c:86
2.185 msgid "Run the AICA SPU only, with the supplied program"
2.186 msgstr ""
2.187
2.188 -#: src/main.c:86
2.189 +#: src/main.c:87
2.190 msgid "Use the specified audio driver (? to list)"
2.191 msgstr ""
2.192
2.193 -#: src/main.c:87
2.194 +#: src/main.c:88
2.195 msgid "Load configuration from CONFFILE"
2.196 msgstr ""
2.197
2.198 -#: src/main.c:88
2.199 +#: src/main.c:89
2.200 msgid "Start in debugger mode"
2.201 msgstr ""
2.202
2.203 -#: src/main.c:89
2.204 +#: src/main.c:90
2.205 msgid "Start in fullscreen mode"
2.206 msgstr ""
2.207
2.208 -#: src/main.c:90
2.209 +#: src/main.c:91
2.210 msgid "Start GDB remote server on PORT for SH4"
2.211 msgstr ""
2.212
2.213 -#: src/main.c:91
2.214 +#: src/main.c:92
2.215 msgid "Start GDB remote server on PORT for ARM"
2.216 msgstr ""
2.217
2.218 -#: src/main.c:92
2.219 +#: src/main.c:93
2.220 msgid "Display this usage information"
2.221 msgstr ""
2.222
2.223 -#: src/main.c:93
2.224 +#: src/main.c:94
2.225 msgid "Run in headless (no video) mode"
2.226 msgstr ""
2.227
2.228 -#: src/main.c:94
2.229 +#: src/main.c:95
2.230 msgid "Set the output log level"
2.231 msgstr ""
2.232
2.233 -#: src/main.c:95
2.234 +#: src/main.c:96
2.235 msgid "Set the SH4 multiplier (1.0 = fullspeed)"
2.236 msgstr ""
2.237
2.238 -#: src/main.c:96
2.239 +#: src/main.c:97
2.240 msgid "Don't start running immediately"
2.241 msgstr ""
2.242
2.243 -#: src/main.c:97
2.244 +#: src/main.c:98
2.245 msgid "Start running immediately on startup"
2.246 msgstr ""
2.247
2.248 -#: src/main.c:98
2.249 +#: src/main.c:99
2.250 msgid "Run for the specified number of seconds"
2.251 msgstr ""
2.252
2.253 -#: src/main.c:99
2.254 +#: src/main.c:100
2.255 msgid "Output trace information for the named regions"
2.256 msgstr ""
2.257
2.258 -#: src/main.c:100
2.259 +#: src/main.c:101
2.260 msgid "Allow unsafe dcload syscalls"
2.261 msgstr ""
2.262
2.263 -#: src/main.c:101
2.264 +#: src/main.c:102
2.265 msgid "Print the lxdream version string"
2.266 msgstr ""
2.267
2.268 -#: src/main.c:102
2.269 +#: src/main.c:103
2.270 msgid "Use the specified video driver (? to list)"
2.271 msgstr ""
2.272
2.273 -#: src/main.c:103
2.274 +#: src/main.c:104
2.275 msgid "Disable the SH4 translator"
2.276 msgstr ""
2.277
2.278 -#: src/maple/controller.c:105 src/maple/lightgun.c:85
2.279 +#: src/maple/controller.c:106 src/maple/lightgun.c:86
2.280 msgid "Dpad left"
2.281 msgstr ""
2.282
2.283 -#: src/maple/controller.c:106 src/maple/lightgun.c:86
2.284 +#: src/maple/controller.c:107 src/maple/lightgun.c:87
2.285 msgid "Dpad right"
2.286 msgstr ""
2.287
2.288 -#: src/maple/controller.c:107 src/maple/lightgun.c:87
2.289 +#: src/maple/controller.c:108 src/maple/lightgun.c:88
2.290 msgid "Dpad up"
2.291 msgstr ""
2.292
2.293 -#: src/maple/controller.c:108 src/maple/lightgun.c:88
2.294 +#: src/maple/controller.c:109 src/maple/lightgun.c:89
2.295 msgid "Dpad down"
2.296 msgstr ""
2.297
2.298 -#: src/maple/controller.c:109
2.299 +#: src/maple/controller.c:110
2.300 msgid "Analog left"
2.301 msgstr ""
2.302
2.303 -#: src/maple/controller.c:110
2.304 +#: src/maple/controller.c:111
2.305 msgid "Analog right"
2.306 msgstr ""
2.307
2.308 -#: src/maple/controller.c:111
2.309 +#: src/maple/controller.c:112
2.310 msgid "Analog up"
2.311 msgstr ""
2.312
2.313 -#: src/maple/controller.c:112
2.314 +#: src/maple/controller.c:113
2.315 msgid "Analog down"
2.316 msgstr ""
2.317
2.318 -#: src/maple/controller.c:113
2.319 +#: src/maple/controller.c:114
2.320 msgid "Button X"
2.321 msgstr ""
2.322
2.323 -#: src/maple/controller.c:114
2.324 +#: src/maple/controller.c:115
2.325 msgid "Button Y"
2.326 msgstr ""
2.327
2.328 -#: src/maple/controller.c:115 src/maple/lightgun.c:89
2.329 +#: src/maple/controller.c:116 src/maple/lightgun.c:90
2.330 msgid "Button A"
2.331 msgstr ""
2.332
2.333 -#: src/maple/controller.c:116 src/maple/lightgun.c:90
2.334 +#: src/maple/controller.c:117 src/maple/lightgun.c:91
2.335 msgid "Button B"
2.336 msgstr ""
2.337
2.338 -#: src/maple/controller.c:117
2.339 +#: src/maple/controller.c:118
2.340 msgid "Trigger left"
2.341 msgstr ""
2.342
2.343 -#: src/maple/controller.c:118
2.344 +#: src/maple/controller.c:119
2.345 msgid "Trigger right"
2.346 msgstr ""
2.347
2.348 -#: src/maple/controller.c:119 src/maple/lightgun.c:91
2.349 +#: src/maple/controller.c:120 src/maple/lightgun.c:92
2.350 msgid "Start button"
2.351 msgstr ""
2.352
3.1 --- a/po/es.po Wed Jun 24 02:27:34 2009 +0000
3.2 +++ b/po/es.po Wed Jun 24 02:41:12 2009 +0000
3.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.15
3.16 -#: src/cocoaui/cocoa_ctrl.m:342 src/gtkui/gtk_ctrl.c:294
3.17 -#, c-format
3.18 -msgid "Slot %d."
3.19 +#: src/cocoaui/cocoa_ctrl.m:324 src/gtkui/gtk_ctrl.c:486
3.20 +#, fuzzy, c-format
3.21 +msgid "Port %c."
3.22 msgstr "Casilla %d"
3.23
3.24 -#: src/cocoaui/cocoaui.m:404
3.25 +#: src/cocoaui/cocoa_ctrl.m:326 src/gtkui/gtk_ctrl.c:515
3.26 +#, c-format
3.27 +msgid "VMU %d."
3.28 +msgstr ""
3.29 +
3.30 +#: src/cocoaui/cocoaui.m:412
3.31 #, c-format
3.32 msgid "Running (%2.4f%%)"
3.33 msgstr ""
3.34
3.35 -#: src/cocoaui/cocoa_win.m:192 src/gtkui/gtk_win.c:356
3.36 +#: src/cocoaui/cocoa_win.m:193 src/gtkui/gtk_win.c:356
3.37 msgid "(Press <ctrl><alt> to release grab)"
3.38 msgstr ""
3.39
3.40 -#: src/cocoaui/cocoa_win.m:204 src/gtkui/gtk_win.c:366
3.41 +#: src/cocoaui/cocoa_win.m:205 src/gtkui/gtk_win.c:366
3.42 msgid "Running"
3.43 msgstr ""
3.44
3.45 -#: src/cocoaui/cocoa_win.m:207 src/gtkui/gtk_win.c:366
3.46 +#: src/cocoaui/cocoa_win.m:208 src/gtkui/gtk_win.c:366
3.47 msgid "Stopped"
3.48 msgstr ""
3.49
3.50 @@ -56,32 +61,36 @@
3.51 msgid "Save-state path"
3.52 msgstr "Guardar ruta de estado"
3.53
3.54 -#: src/config.c:45 src/gtkui/gtk_path.c:29
3.55 +#: src/config.c:45
3.56 +msgid "VMU path"
3.57 +msgstr ""
3.58 +
3.59 +#: src/config.c:46 src/gtkui/gtk_path.c:29
3.60 msgid "Bootstrap IP.BIN"
3.61 msgstr "Bootstrap IP.BIN"
3.62
3.63 -#: src/config.c:51
3.64 +#: src/config.c:53
3.65 msgid "Serial device"
3.66 msgstr ""
3.67
3.68 -#: src/dreamcast.c:192
3.69 +#: src/dreamcast.c:193
3.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.75
3.76 -#: src/dreamcast.c:324
3.77 +#: src/dreamcast.c:328
3.78 #, c-format
3.79 msgid "File is not a %s save state"
3.80 msgstr ""
3.81
3.82 -#: src/dreamcast.c:329
3.83 +#: src/dreamcast.c:333
3.84 #, c-format
3.85 msgid "Unsupported %s save state version"
3.86 msgstr ""
3.87
3.88 -#: src/dreamcast.c:334
3.89 +#: src/dreamcast.c:338
3.90 #, c-format
3.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.96
3.97 -#: src/gdlist.c:206 src/gdlist.c:229
3.98 +#: src/gdlist.c:187 src/gdlist.c:210
3.99 msgid "Empty"
3.100 msgstr ""
3.101
3.102 @@ -142,49 +151,66 @@
3.103 msgid "All files"
3.104 msgstr "Todos los archivos"
3.105
3.106 -#: src/gtkui/gtkcb.c:139
3.107 +#: src/gtkui/gtkcb.c:162
3.108 msgid "Load state..."
3.109 msgstr "Cargar estado..."
3.110
3.111 -#: src/gtkui/gtkcb.c:144 src/gtkui/gtkcb.c:175
3.112 +#: src/gtkui/gtkcb.c:167 src/gtkui/gtkcb.c:198
3.113 msgid "lxDream Save State (*.dst)"
3.114 msgstr "Estado guardado LxDream (*.dst)"
3.115
3.116 -#: src/gtkui/gtkcb.c:237 src/gtkui/gtk_dump.c:69
3.117 +#: src/gtkui/gtkcb.c:260 src/gtkui/gtk_dump.c:69
3.118 msgid "Memory dump"
3.119 msgstr "Volcado de memoria"
3.120
3.121 -#: src/gtkui/gtkcb.c:250
3.122 +#: src/gtkui/gtkcb.c:273
3.123 msgid "Save next scene..."
3.124 msgstr "Guardar proxima escena"
3.125
3.126 -#: src/gtkui/gtkcb.c:250
3.127 +#: src/gtkui/gtkcb.c:273
3.128 msgid "lxdream scene file (*.dsc)"
3.129 msgstr "Archivo de escena de lxdream (*.dsc)"
3.130
3.131 -#: src/gtkui/gtkcb.c:265
3.132 +#: src/gtkui/gtkcb.c:288
3.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.135
3.136 -#: src/gtkui/gtk_ctrl.c:72 src/gtkui/gtk_ctrl.c:101 src/gtkui/gtk_hotkeys.c:50
3.137 +#: src/gtkui/gtk_ctrl.c:80 src/gtkui/gtk_ctrl.c:109 src/gtkui/gtk_hotkeys.c:50
3.138 #: src/gtkui/gtk_hotkeys.c:79
3.139 msgid "<press key>"
3.140 msgstr "<presione una tecla>"
3.141
3.142 -#: src/gtkui/gtk_ctrl.c:201
3.143 +#: src/gtkui/gtk_ctrl.c:209
3.144 msgid "Controller Configuration"
3.145 msgstr "Configuracion del mando"
3.146
3.147 -#: src/gtkui/gtk_ctrl.c:220
3.148 +#: src/gtkui/gtk_ctrl.c:228
3.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.152
3.153 -#: src/gtkui/gtk_ctrl.c:297
3.154 +#: src/gtkui/gtk_ctrl.c:252
3.155 +msgid "Load VMU"
3.156 +msgstr ""
3.157 +
3.158 +#: src/gtkui/gtk_ctrl.c:266
3.159 +msgid "Create VMU"
3.160 +msgstr ""
3.161 +
3.162 +#: src/gtkui/gtk_ctrl.c:329 src/gtkui/gtk_ctrl.c:347
3.163 msgid "<empty>"
3.164 msgstr "<vacio>"
3.165
3.166 -#: src/gtkui/gtk_ctrl.c:325
3.167 +#: src/gtkui/gtk_ctrl.c:356
3.168 +#, fuzzy
3.169 +msgid "Load VMU..."
3.170 +msgstr "Cargar estado..."
3.171 +
3.172 +#: src/gtkui/gtk_ctrl.c:357
3.173 +msgid "Create VMU..."
3.174 +msgstr ""
3.175 +
3.176 +#: src/gtkui/gtk_ctrl.c:551
3.177 msgid "Controller Settings"
3.178 msgstr "Configuracion del mando"
3.179
3.180 @@ -572,139 +598,139 @@
3.181 msgid "Select quick save state 9"
3.182 msgstr ""
3.183
3.184 -#: src/main.c:85
3.185 +#: src/main.c:86
3.186 msgid "Run the AICA SPU only, with the supplied program"
3.187 msgstr ""
3.188
3.189 -#: src/main.c:86
3.190 +#: src/main.c:87
3.191 msgid "Use the specified audio driver (? to list)"
3.192 msgstr ""
3.193
3.194 -#: src/main.c:87
3.195 +#: src/main.c:88
3.196 msgid "Load configuration from CONFFILE"
3.197 msgstr ""
3.198
3.199 -#: src/main.c:88
3.200 +#: src/main.c:89
3.201 msgid "Start in debugger mode"
3.202 msgstr ""
3.203
3.204 -#: src/main.c:89
3.205 +#: src/main.c:90
3.206 msgid "Start in fullscreen mode"
3.207 msgstr ""
3.208
3.209 -#: src/main.c:90
3.210 +#: src/main.c:91
3.211 msgid "Start GDB remote server on PORT for SH4"
3.212 msgstr ""
3.213
3.214 -#: src/main.c:91
3.215 +#: src/main.c:92
3.216 msgid "Start GDB remote server on PORT for ARM"
3.217 msgstr ""
3.218
3.219 -#: src/main.c:92
3.220 +#: src/main.c:93
3.221 msgid "Display this usage information"
3.222 msgstr ""
3.223
3.224 -#: src/main.c:93
3.225 +#: src/main.c:94
3.226 msgid "Run in headless (no video) mode"
3.227 msgstr ""
3.228
3.229 -#: src/main.c:94
3.230 +#: src/main.c:95
3.231 msgid "Set the output log level"
3.232 msgstr ""
3.233
3.234 -#: src/main.c:95
3.235 +#: src/main.c:96
3.236 msgid "Set the SH4 multiplier (1.0 = fullspeed)"
3.237 msgstr ""
3.238
3.239 -#: src/main.c:96
3.240 +#: src/main.c:97
3.241 msgid "Don't start running immediately"
3.242 msgstr ""
3.243
3.244 -#: src/main.c:97
3.245 +#: src/main.c:98
3.246 msgid "Start running immediately on startup"
3.247 msgstr ""
3.248
3.249 -#: src/main.c:98
3.250 +#: src/main.c:99
3.251 msgid "Run for the specified number of seconds"
3.252 msgstr ""
3.253
3.254 -#: src/main.c:99
3.255 +#: src/main.c:100
3.256 msgid "Output trace information for the named regions"
3.257 msgstr ""
3.258
3.259 -#: src/main.c:100
3.260 +#: src/main.c:101
3.261 msgid "Allow unsafe dcload syscalls"
3.262 msgstr ""
3.263
3.264 -#: src/main.c:101
3.265 +#: src/main.c:102
3.266 msgid "Print the lxdream version string"
3.267 msgstr ""
3.268
3.269 -#: src/main.c:102
3.270 +#: src/main.c:103
3.271 msgid "Use the specified video driver (? to list)"
3.272 msgstr ""
3.273
3.274 -#: src/main.c:103
3.275 +#: src/main.c:104
3.276 msgid "Disable the SH4 translator"
3.277 msgstr ""
3.278
3.279 -#: src/maple/controller.c:105 src/maple/lightgun.c:85
3.280 +#: src/maple/controller.c:106 src/maple/lightgun.c:86
3.281 msgid "Dpad left"
3.282 msgstr ""
3.283
3.284 -#: src/maple/controller.c:106 src/maple/lightgun.c:86
3.285 +#: src/maple/controller.c:107 src/maple/lightgun.c:87
3.286 msgid "Dpad right"
3.287 msgstr ""
3.288
3.289 -#: src/maple/controller.c:107 src/maple/lightgun.c:87
3.290 +#: src/maple/controller.c:108 src/maple/lightgun.c:88
3.291 msgid "Dpad up"
3.292 msgstr ""
3.293
3.294 -#: src/maple/controller.c:108 src/maple/lightgun.c:88
3.295 +#: src/maple/controller.c:109 src/maple/lightgun.c:89
3.296 msgid "Dpad down"
3.297 msgstr ""
3.298
3.299 -#: src/maple/controller.c:109
3.300 +#: src/maple/controller.c:110
3.301 msgid "Analog left"
3.302 msgstr ""
3.303
3.304 -#: src/maple/controller.c:110
3.305 +#: src/maple/controller.c:111
3.306 msgid "Analog right"
3.307 msgstr ""
3.308
3.309 -#: src/maple/controller.c:111
3.310 +#: src/maple/controller.c:112
3.311 msgid "Analog up"
3.312 msgstr ""
3.313
3.314 -#: src/maple/controller.c:112
3.315 +#: src/maple/controller.c:113
3.316 msgid "Analog down"
3.317 msgstr ""
3.318
3.319 -#: src/maple/controller.c:113
3.320 +#: src/maple/controller.c:114
3.321 msgid "Button X"
3.322 msgstr ""
3.323
3.324 -#: src/maple/controller.c:114
3.325 +#: src/maple/controller.c:115
3.326 msgid "Button Y"
3.327 msgstr ""
3.328
3.329 -#: src/maple/controller.c:115 src/maple/lightgun.c:89
3.330 +#: src/maple/controller.c:116 src/maple/lightgun.c:90
3.331 msgid "Button A"
3.332 msgstr ""
3.333
3.334 -#: src/maple/controller.c:116 src/maple/lightgun.c:90
3.335 +#: src/maple/controller.c:117 src/maple/lightgun.c:91
3.336 msgid "Button B"
3.337 msgstr ""
3.338
3.339 -#: src/maple/controller.c:117
3.340 +#: src/maple/controller.c:118
3.341 msgid "Trigger left"
3.342 msgstr ""
3.343
3.344 -#: src/maple/controller.c:118
3.345 +#: src/maple/controller.c:119
3.346 msgid "Trigger right"
3.347 msgstr ""
3.348
3.349 -#: src/maple/controller.c:119 src/maple/lightgun.c:91
3.350 +#: src/maple/controller.c:120 src/maple/lightgun.c:92
3.351 msgid "Start button"
3.352 msgstr ""
3.353
4.1 --- a/po/it.po Wed Jun 24 02:27:34 2009 +0000
4.2 +++ b/po/it.po Wed Jun 24 02:41:12 2009 +0000
4.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.15
4.16 -#: src/cocoaui/cocoa_ctrl.m:342 src/gtkui/gtk_ctrl.c:294
4.17 -#, c-format
4.18 -msgid "Slot %d."
4.19 +#: src/cocoaui/cocoa_ctrl.m:324 src/gtkui/gtk_ctrl.c:486
4.20 +#, fuzzy, c-format
4.21 +msgid "Port %c."
4.22 msgstr "Slot %d."
4.23
4.24 -#: src/cocoaui/cocoaui.m:404
4.25 +#: src/cocoaui/cocoa_ctrl.m:326 src/gtkui/gtk_ctrl.c:515
4.26 +#, c-format
4.27 +msgid "VMU %d."
4.28 +msgstr ""
4.29 +
4.30 +#: src/cocoaui/cocoaui.m:412
4.31 #, c-format
4.32 msgid "Running (%2.4f%%)"
4.33 msgstr ""
4.34
4.35 -#: src/cocoaui/cocoa_win.m:192 src/gtkui/gtk_win.c:356
4.36 +#: src/cocoaui/cocoa_win.m:193 src/gtkui/gtk_win.c:356
4.37 msgid "(Press <ctrl><alt> to release grab)"
4.38 msgstr ""
4.39
4.40 -#: src/cocoaui/cocoa_win.m:204 src/gtkui/gtk_win.c:366
4.41 +#: src/cocoaui/cocoa_win.m:205 src/gtkui/gtk_win.c:366
4.42 msgid "Running"
4.43 msgstr ""
4.44
4.45 -#: src/cocoaui/cocoa_win.m:207 src/gtkui/gtk_win.c:366
4.46 +#: src/cocoaui/cocoa_win.m:208 src/gtkui/gtk_win.c:366
4.47 msgid "Stopped"
4.48 msgstr ""
4.49
4.50 @@ -56,32 +61,36 @@
4.51 msgid "Save-state path"
4.52 msgstr "Percorso del salvataggio dello stato"
4.53
4.54 -#: src/config.c:45 src/gtkui/gtk_path.c:29
4.55 +#: src/config.c:45
4.56 +msgid "VMU path"
4.57 +msgstr ""
4.58 +
4.59 +#: src/config.c:46 src/gtkui/gtk_path.c:29
4.60 msgid "Bootstrap IP.BIN"
4.61 msgstr "Bootstrap IP.BIN"
4.62
4.63 -#: src/config.c:51
4.64 +#: src/config.c:53
4.65 msgid "Serial device"
4.66 msgstr ""
4.67
4.68 -#: src/dreamcast.c:192
4.69 +#: src/dreamcast.c:193
4.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.75
4.76 -#: src/dreamcast.c:324
4.77 +#: src/dreamcast.c:328
4.78 #, c-format
4.79 msgid "File is not a %s save state"
4.80 msgstr ""
4.81
4.82 -#: src/dreamcast.c:329
4.83 +#: src/dreamcast.c:333
4.84 #, c-format
4.85 msgid "Unsupported %s save state version"
4.86 msgstr ""
4.87
4.88 -#: src/dreamcast.c:334
4.89 +#: src/dreamcast.c:338
4.90 #, c-format
4.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.96
4.97 -#: src/gdlist.c:206 src/gdlist.c:229
4.98 +#: src/gdlist.c:187 src/gdlist.c:210
4.99 msgid "Empty"
4.100 msgstr "Vuoto"
4.101
4.102 @@ -142,48 +151,65 @@
4.103 msgid "All files"
4.104 msgstr "Tutti i files"
4.105
4.106 -#: src/gtkui/gtkcb.c:139
4.107 +#: src/gtkui/gtkcb.c:162
4.108 msgid "Load state..."
4.109 msgstr "Carica stato..."
4.110
4.111 -#: src/gtkui/gtkcb.c:144 src/gtkui/gtkcb.c:175
4.112 +#: src/gtkui/gtkcb.c:167 src/gtkui/gtkcb.c:198
4.113 msgid "lxDream Save State (*.dst)"
4.114 msgstr "Salvataggio stato LxDream (*.dst)"
4.115
4.116 -#: src/gtkui/gtkcb.c:237 src/gtkui/gtk_dump.c:69
4.117 +#: src/gtkui/gtkcb.c:260 src/gtkui/gtk_dump.c:69
4.118 msgid "Memory dump"
4.119 msgstr "Memoria"
4.120
4.121 -#: src/gtkui/gtkcb.c:250
4.122 +#: src/gtkui/gtkcb.c:273
4.123 msgid "Save next scene..."
4.124 msgstr "Salva prossima scena..."
4.125
4.126 -#: src/gtkui/gtkcb.c:250
4.127 +#: src/gtkui/gtkcb.c:273
4.128 msgid "lxdream scene file (*.dsc)"
4.129 msgstr "file scena lxdream (*.dsc)"
4.130
4.131 -#: src/gtkui/gtkcb.c:265
4.132 +#: src/gtkui/gtkcb.c:288
4.133 msgid "No address selected, so can't run to it"
4.134 msgstr "Nessun indirizzo selezionato, quindi non posso andarci"
4.135
4.136 -#: src/gtkui/gtk_ctrl.c:72 src/gtkui/gtk_ctrl.c:101 src/gtkui/gtk_hotkeys.c:50
4.137 +#: src/gtkui/gtk_ctrl.c:80 src/gtkui/gtk_ctrl.c:109 src/gtkui/gtk_hotkeys.c:50
4.138 #: src/gtkui/gtk_hotkeys.c:79
4.139 msgid "<press key>"
4.140 msgstr "<premi un tasto>"
4.141
4.142 -#: src/gtkui/gtk_ctrl.c:201
4.143 +#: src/gtkui/gtk_ctrl.c:209
4.144 msgid "Controller Configuration"
4.145 msgstr "Configura il controller"
4.146
4.147 -#: src/gtkui/gtk_ctrl.c:220
4.148 +#: src/gtkui/gtk_ctrl.c:228
4.149 msgid "No configuration page available for device type"
4.150 msgstr "Nessuna configurazione è attivabile per questo tipo di periferica"
4.151
4.152 -#: src/gtkui/gtk_ctrl.c:297
4.153 +#: src/gtkui/gtk_ctrl.c:252
4.154 +msgid "Load VMU"
4.155 +msgstr ""
4.156 +
4.157 +#: src/gtkui/gtk_ctrl.c:266
4.158 +msgid "Create VMU"
4.159 +msgstr ""
4.160 +
4.161 +#: src/gtkui/gtk_ctrl.c:329 src/gtkui/gtk_ctrl.c:347
4.162 msgid "<empty>"
4.163 msgstr "<vuoto>"
4.164
4.165 -#: src/gtkui/gtk_ctrl.c:325
4.166 +#: src/gtkui/gtk_ctrl.c:356
4.167 +#, fuzzy
4.168 +msgid "Load VMU..."
4.169 +msgstr "Carica stato..."
4.170 +
4.171 +#: src/gtkui/gtk_ctrl.c:357
4.172 +msgid "Create VMU..."
4.173 +msgstr ""
4.174 +
4.175 +#: src/gtkui/gtk_ctrl.c:551
4.176 msgid "Controller Settings"
4.177 msgstr "Opzioni del controller"
4.178
4.179 @@ -571,139 +597,139 @@
4.180 msgid "Select quick save state 9"
4.181 msgstr ""
4.182
4.183 -#: src/main.c:85
4.184 +#: src/main.c:86
4.185 msgid "Run the AICA SPU only, with the supplied program"
4.186 msgstr ""
4.187
4.188 -#: src/main.c:86
4.189 +#: src/main.c:87
4.190 msgid "Use the specified audio driver (? to list)"
4.191 msgstr ""
4.192
4.193 -#: src/main.c:87
4.194 +#: src/main.c:88
4.195 msgid "Load configuration from CONFFILE"
4.196 msgstr ""
4.197
4.198 -#: src/main.c:88
4.199 +#: src/main.c:89
4.200 msgid "Start in debugger mode"
4.201 msgstr ""
4.202
4.203 -#: src/main.c:89
4.204 +#: src/main.c:90
4.205 msgid "Start in fullscreen mode"
4.206 msgstr ""
4.207
4.208 -#: src/main.c:90
4.209 +#: src/main.c:91
4.210 msgid "Start GDB remote server on PORT for SH4"
4.211 msgstr ""
4.212
4.213 -#: src/main.c:91
4.214 +#: src/main.c:92
4.215 msgid "Start GDB remote server on PORT for ARM"
4.216 msgstr ""
4.217
4.218 -#: src/main.c:92
4.219 +#: src/main.c:93
4.220 msgid "Display this usage information"
4.221 msgstr ""
4.222
4.223 -#: src/main.c:93
4.224 +#: src/main.c:94
4.225 msgid "Run in headless (no video) mode"
4.226 msgstr ""
4.227
4.228 -#: src/main.c:94
4.229 +#: src/main.c:95
4.230 msgid "Set the output log level"
4.231 msgstr ""
4.232
4.233 -#: src/main.c:95
4.234 +#: src/main.c:96
4.235 msgid "Set the SH4 multiplier (1.0 = fullspeed)"
4.236 msgstr ""
4.237
4.238 -#: src/main.c:96
4.239 +#: src/main.c:97
4.240 msgid "Don't start running immediately"
4.241 msgstr ""
4.242
4.243 -#: src/main.c:97
4.244 +#: src/main.c:98
4.245 msgid "Start running immediately on startup"
4.246 msgstr ""
4.247
4.248 -#: src/main.c:98
4.249 +#: src/main.c:99
4.250 msgid "Run for the specified number of seconds"
4.251 msgstr ""
4.252
4.253 -#: src/main.c:99
4.254 +#: src/main.c:100
4.255 msgid "Output trace information for the named regions"
4.256 msgstr ""
4.257
4.258 -#: src/main.c:100
4.259 +#: src/main.c:101
4.260 msgid "Allow unsafe dcload syscalls"
4.261 msgstr ""
4.262
4.263 -#: src/main.c:101
4.264 +#: src/main.c:102
4.265 msgid "Print the lxdream version string"
4.266 msgstr ""
4.267
4.268 -#: src/main.c:102
4.269 +#: src/main.c:103
4.270 msgid "Use the specified video driver (? to list)"
4.271 msgstr ""
4.272
4.273 -#: src/main.c:103
4.274 +#: src/main.c:104
4.275 msgid "Disable the SH4 translator"
4.276 msgstr ""
4.277
4.278 -#: src/maple/controller.c:105 src/maple/lightgun.c:85
4.279 +#: src/maple/controller.c:106 src/maple/lightgun.c:86
4.280 msgid "Dpad left"
4.281 msgstr ""
4.282
4.283 -#: src/maple/controller.c:106 src/maple/lightgun.c:86
4.284 +#: src/maple/controller.c:107 src/maple/lightgun.c:87
4.285 msgid "Dpad right"
4.286 msgstr ""
4.287
4.288 -#: src/maple/controller.c:107 src/maple/lightgun.c:87
4.289 +#: src/maple/controller.c:108 src/maple/lightgun.c:88
4.290 msgid "Dpad up"
4.291 msgstr ""
4.292
4.293 -#: src/maple/controller.c:108 src/maple/lightgun.c:88
4.294 +#: src/maple/controller.c:109 src/maple/lightgun.c:89
4.295 msgid "Dpad down"
4.296 msgstr ""
4.297
4.298 -#: src/maple/controller.c:109
4.299 +#: src/maple/controller.c:110
4.300 msgid "Analog left"
4.301 msgstr ""
4.302
4.303 -#: src/maple/controller.c:110
4.304 +#: src/maple/controller.c:111
4.305 msgid "Analog right"
4.306 msgstr ""
4.307
4.308 -#: src/maple/controller.c:111
4.309 +#: src/maple/controller.c:112
4.310 msgid "Analog up"
4.311 msgstr ""
4.312
4.313 -#: src/maple/controller.c:112
4.314 +#: src/maple/controller.c:113
4.315 msgid "Analog down"
4.316 msgstr ""
4.317
4.318 -#: src/maple/controller.c:113
4.319 +#: src/maple/controller.c:114
4.320 msgid "Button X"
4.321 msgstr ""
4.322
4.323 -#: src/maple/controller.c:114
4.324 +#: src/maple/controller.c:115
4.325 msgid "Button Y"
4.326 msgstr ""
4.327
4.328 -#: src/maple/controller.c:115 src/maple/lightgun.c:89
4.329 +#: src/maple/controller.c:116 src/maple/lightgun.c:90
4.330 msgid "Button A"
4.331 msgstr ""
4.332
4.333 -#: src/maple/controller.c:116 src/maple/lightgun.c:90
4.334 +#: src/maple/controller.c:117 src/maple/lightgun.c:91
4.335 msgid "Button B"
4.336 msgstr ""
4.337
4.338 -#: src/maple/controller.c:117
4.339 +#: src/maple/controller.c:118
4.340 msgid "Trigger left"
4.341 msgstr ""
4.342
4.343 -#: src/maple/controller.c:118
4.344 +#: src/maple/controller.c:119
4.345 msgid "Trigger right"
4.346 msgstr ""
4.347
4.348 -#: src/maple/controller.c:119 src/maple/lightgun.c:91
4.349 +#: src/maple/controller.c:120 src/maple/lightgun.c:92
4.350 msgid "Start button"
4.351 msgstr ""
4.352
5.1 --- a/po/lxdream.pot Wed Jun 24 02:27:34 2009 +0000
5.2 +++ b/po/lxdream.pot Wed Jun 24 02:41:12 2009 +0000
5.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.15
5.16 -#: src/cocoaui/cocoa_ctrl.m:342 src/gtkui/gtk_ctrl.c:294
5.17 +#: src/cocoaui/cocoa_ctrl.m:324 src/gtkui/gtk_ctrl.c:486
5.18 #, c-format
5.19 -msgid "Slot %d."
5.20 +msgid "Port %c."
5.21 msgstr ""
5.22
5.23 -#: src/cocoaui/cocoaui.m:404
5.24 +#: src/cocoaui/cocoa_ctrl.m:326 src/gtkui/gtk_ctrl.c:515
5.25 +#, c-format
5.26 +msgid "VMU %d."
5.27 +msgstr ""
5.28 +
5.29 +#: src/cocoaui/cocoaui.m:412
5.30 #, c-format
5.31 msgid "Running (%2.4f%%)"
5.32 msgstr ""
5.33
5.34 -#: src/cocoaui/cocoa_win.m:192 src/gtkui/gtk_win.c:356
5.35 +#: src/cocoaui/cocoa_win.m:193 src/gtkui/gtk_win.c:356
5.36 msgid "(Press <ctrl><alt> to release grab)"
5.37 msgstr ""
5.38
5.39 -#: src/cocoaui/cocoa_win.m:204 src/gtkui/gtk_win.c:366
5.40 +#: src/cocoaui/cocoa_win.m:205 src/gtkui/gtk_win.c:366
5.41 msgid "Running"
5.42 msgstr ""
5.43
5.44 -#: src/cocoaui/cocoa_win.m:207 src/gtkui/gtk_win.c:366
5.45 +#: src/cocoaui/cocoa_win.m:208 src/gtkui/gtk_win.c:366
5.46 msgid "Stopped"
5.47 msgstr ""
5.48
5.49 @@ -54,32 +59,36 @@
5.50 msgid "Save-state path"
5.51 msgstr ""
5.52
5.53 -#: src/config.c:45 src/gtkui/gtk_path.c:29
5.54 +#: src/config.c:45
5.55 +msgid "VMU path"
5.56 +msgstr ""
5.57 +
5.58 +#: src/config.c:46 src/gtkui/gtk_path.c:29
5.59 msgid "Bootstrap IP.BIN"
5.60 msgstr ""
5.61
5.62 -#: src/config.c:51
5.63 +#: src/config.c:53
5.64 msgid "Serial device"
5.65 msgstr ""
5.66
5.67 -#: src/dreamcast.c:192
5.68 +#: src/dreamcast.c:193
5.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.74
5.75 -#: src/dreamcast.c:324
5.76 +#: src/dreamcast.c:328
5.77 #, c-format
5.78 msgid "File is not a %s save state"
5.79 msgstr ""
5.80
5.81 -#: src/dreamcast.c:329
5.82 +#: src/dreamcast.c:333
5.83 #, c-format
5.84 msgid "Unsupported %s save state version"
5.85 msgstr ""
5.86
5.87 -#: src/dreamcast.c:334
5.88 +#: src/dreamcast.c:338
5.89 #, c-format
5.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.95
5.96 -#: src/gdlist.c:206 src/gdlist.c:229
5.97 +#: src/gdlist.c:187 src/gdlist.c:210
5.98 msgid "Empty"
5.99 msgstr ""
5.100
5.101 @@ -140,48 +149,64 @@
5.102 msgid "All files"
5.103 msgstr ""
5.104
5.105 -#: src/gtkui/gtkcb.c:139
5.106 +#: src/gtkui/gtkcb.c:162
5.107 msgid "Load state..."
5.108 msgstr ""
5.109
5.110 -#: src/gtkui/gtkcb.c:144 src/gtkui/gtkcb.c:175
5.111 +#: src/gtkui/gtkcb.c:167 src/gtkui/gtkcb.c:198
5.112 msgid "lxDream Save State (*.dst)"
5.113 msgstr ""
5.114
5.115 -#: src/gtkui/gtkcb.c:237 src/gtkui/gtk_dump.c:69
5.116 +#: src/gtkui/gtkcb.c:260 src/gtkui/gtk_dump.c:69
5.117 msgid "Memory dump"
5.118 msgstr ""
5.119
5.120 -#: src/gtkui/gtkcb.c:250
5.121 +#: src/gtkui/gtkcb.c:273
5.122 msgid "Save next scene..."
5.123 msgstr ""
5.124
5.125 -#: src/gtkui/gtkcb.c:250
5.126 +#: src/gtkui/gtkcb.c:273
5.127 msgid "lxdream scene file (*.dsc)"
5.128 msgstr ""
5.129
5.130 -#: src/gtkui/gtkcb.c:265
5.131 +#: src/gtkui/gtkcb.c:288
5.132 msgid "No address selected, so can't run to it"
5.133 msgstr ""
5.134
5.135 -#: src/gtkui/gtk_ctrl.c:72 src/gtkui/gtk_ctrl.c:101 src/gtkui/gtk_hotkeys.c:50
5.136 +#: src/gtkui/gtk_ctrl.c:80 src/gtkui/gtk_ctrl.c:109 src/gtkui/gtk_hotkeys.c:50
5.137 #: src/gtkui/gtk_hotkeys.c:79
5.138 msgid "<press key>"
5.139 msgstr ""
5.140
5.141 -#: src/gtkui/gtk_ctrl.c:201
5.142 +#: src/gtkui/gtk_ctrl.c:209
5.143 msgid "Controller Configuration"
5.144 msgstr ""
5.145
5.146 -#: src/gtkui/gtk_ctrl.c:220
5.147 +#: src/gtkui/gtk_ctrl.c:228
5.148 msgid "No configuration page available for device type"
5.149 msgstr ""
5.150
5.151 -#: src/gtkui/gtk_ctrl.c:297
5.152 +#: src/gtkui/gtk_ctrl.c:252
5.153 +msgid "Load VMU"
5.154 +msgstr ""
5.155 +
5.156 +#: src/gtkui/gtk_ctrl.c:266
5.157 +msgid "Create VMU"
5.158 +msgstr ""
5.159 +
5.160 +#: src/gtkui/gtk_ctrl.c:329 src/gtkui/gtk_ctrl.c:347
5.161 msgid "<empty>"
5.162 msgstr ""
5.163
5.164 -#: src/gtkui/gtk_ctrl.c:325
5.165 +#: src/gtkui/gtk_ctrl.c:356
5.166 +msgid "Load VMU..."
5.167 +msgstr ""
5.168 +
5.169 +#: src/gtkui/gtk_ctrl.c:357
5.170 +msgid "Create VMU..."
5.171 +msgstr ""
5.172 +
5.173 +#: src/gtkui/gtk_ctrl.c:551
5.174 msgid "Controller Settings"
5.175 msgstr ""
5.176
5.177 @@ -561,139 +586,139 @@
5.178 msgid "Select quick save state 9"
5.179 msgstr ""
5.180
5.181 -#: src/main.c:85
5.182 +#: src/main.c:86
5.183 msgid "Run the AICA SPU only, with the supplied program"
5.184 msgstr ""
5.185
5.186 -#: src/main.c:86
5.187 +#: src/main.c:87
5.188 msgid "Use the specified audio driver (? to list)"
5.189 msgstr ""
5.190
5.191 -#: src/main.c:87
5.192 +#: src/main.c:88
5.193 msgid "Load configuration from CONFFILE"
5.194 msgstr ""
5.195
5.196 -#: src/main.c:88
5.197 +#: src/main.c:89
5.198 msgid "Start in debugger mode"
5.199 msgstr ""
5.200
5.201 -#: src/main.c:89
5.202 +#: src/main.c:90
5.203 msgid "Start in fullscreen mode"
5.204 msgstr ""
5.205
5.206 -#: src/main.c:90
5.207 +#: src/main.c:91
5.208 msgid "Start GDB remote server on PORT for SH4"
5.209 msgstr ""
5.210
5.211 -#: src/main.c:91
5.212 +#: src/main.c:92
5.213 msgid "Start GDB remote server on PORT for ARM"
5.214 msgstr ""
5.215
5.216 -#: src/main.c:92
5.217 +#: src/main.c:93
5.218 msgid "Display this usage information"
5.219 msgstr ""
5.220
5.221 -#: src/main.c:93
5.222 +#: src/main.c:94
5.223 msgid "Run in headless (no video) mode"
5.224 msgstr ""
5.225
5.226 -#: src/main.c:94
5.227 +#: src/main.c:95
5.228 msgid "Set the output log level"
5.229 msgstr ""
5.230
5.231 -#: src/main.c:95
5.232 +#: src/main.c:96
5.233 msgid "Set the SH4 multiplier (1.0 = fullspeed)"
5.234 msgstr ""
5.235
5.236 -#: src/main.c:96
5.237 +#: src/main.c:97
5.238 msgid "Don't start running immediately"
5.239 msgstr ""
5.240
5.241 -#: src/main.c:97
5.242 +#: src/main.c:98
5.243 msgid "Start running immediately on startup"
5.244 msgstr ""
5.245
5.246 -#: src/main.c:98
5.247 +#: src/main.c:99
5.248 msgid "Run for the specified number of seconds"
5.249 msgstr ""
5.250
5.251 -#: src/main.c:99
5.252 +#: src/main.c:100
5.253 msgid "Output trace information for the named regions"
5.254 msgstr ""
5.255
5.256 -#: src/main.c:100
5.257 +#: src/main.c:101
5.258 msgid "Allow unsafe dcload syscalls"
5.259 msgstr ""
5.260
5.261 -#: src/main.c:101
5.262 +#: src/main.c:102
5.263 msgid "Print the lxdream version string"
5.264 msgstr ""
5.265
5.266 -#: src/main.c:102
5.267 +#: src/main.c:103
5.268 msgid "Use the specified video driver (? to list)"
5.269 msgstr ""
5.270
5.271 -#: src/main.c:103
5.272 +#: src/main.c:104
5.273 msgid "Disable the SH4 translator"
5.274 msgstr ""
5.275
5.276 -#: src/maple/controller.c:105 src/maple/lightgun.c:85
5.277 +#: src/maple/controller.c:106 src/maple/lightgun.c:86
5.278 msgid "Dpad left"
5.279 msgstr ""
5.280
5.281 -#: src/maple/controller.c:106 src/maple/lightgun.c:86
5.282 +#: src/maple/controller.c:107 src/maple/lightgun.c:87
5.283 msgid "Dpad right"
5.284 msgstr ""
5.285
5.286 -#: src/maple/controller.c:107 src/maple/lightgun.c:87
5.287 +#: src/maple/controller.c:108 src/maple/lightgun.c:88
5.288 msgid "Dpad up"
5.289 msgstr ""
5.290
5.291 -#: src/maple/controller.c:108 src/maple/lightgun.c:88
5.292 +#: src/maple/controller.c:109 src/maple/lightgun.c:89
5.293 msgid "Dpad down"
5.294 msgstr ""
5.295
5.296 -#: src/maple/controller.c:109
5.297 +#: src/maple/controller.c:110
5.298 msgid "Analog left"
5.299 msgstr ""
5.300
5.301 -#: src/maple/controller.c:110
5.302 +#: src/maple/controller.c:111
5.303 msgid "Analog right"
5.304 msgstr ""
5.305
5.306 -#: src/maple/controller.c:111
5.307 +#: src/maple/controller.c:112
5.308 msgid "Analog up"
5.309 msgstr ""
5.310
5.311 -#: src/maple/controller.c:112
5.312 +#: src/maple/controller.c:113
5.313 msgid "Analog down"
5.314 msgstr ""
5.315
5.316 -#: src/maple/controller.c:113
5.317 +#: src/maple/controller.c:114
5.318 msgid "Button X"
5.319 msgstr ""
5.320
5.321 -#: src/maple/controller.c:114
5.322 +#: src/maple/controller.c:115
5.323 msgid "Button Y"
5.324 msgstr ""
5.325
5.326 -#: src/maple/controller.c:115 src/maple/lightgun.c:89
5.327 +#: src/maple/controller.c:116 src/maple/lightgun.c:90
5.328 msgid "Button A"
5.329 msgstr ""
5.330
5.331 -#: src/maple/controller.c:116 src/maple/lightgun.c:90
5.332 +#: src/maple/controller.c:117 src/maple/lightgun.c:91
5.333 msgid "Button B"
5.334 msgstr ""
5.335
5.336 -#: src/maple/controller.c:117
5.337 +#: src/maple/controller.c:118
5.338 msgid "Trigger left"
5.339 msgstr ""
5.340
5.341 -#: src/maple/controller.c:118
5.342 +#: src/maple/controller.c:119
5.343 msgid "Trigger right"
5.344 msgstr ""
5.345
5.346 -#: src/maple/controller.c:119 src/maple/lightgun.c:91
5.347 +#: src/maple/controller.c:120 src/maple/lightgun.c:92
5.348 msgid "Start button"
5.349 msgstr ""
5.350
6.1 --- a/po/pt_BR.po Wed Jun 24 02:27:34 2009 +0000
6.2 +++ b/po/pt_BR.po Wed Jun 24 02:41:12 2009 +0000
6.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.15
6.16 -#: src/cocoaui/cocoa_ctrl.m:342 src/gtkui/gtk_ctrl.c:294
6.17 -#, c-format
6.18 -msgid "Slot %d."
6.19 +#: src/cocoaui/cocoa_ctrl.m:324 src/gtkui/gtk_ctrl.c:486
6.20 +#, fuzzy, c-format
6.21 +msgid "Port %c."
6.22 msgstr "Slot %d."
6.23
6.24 -#: src/cocoaui/cocoaui.m:404
6.25 +#: src/cocoaui/cocoa_ctrl.m:326 src/gtkui/gtk_ctrl.c:515
6.26 +#, c-format
6.27 +msgid "VMU %d."
6.28 +msgstr ""
6.29 +
6.30 +#: src/cocoaui/cocoaui.m:412
6.31 #, c-format
6.32 msgid "Running (%2.4f%%)"
6.33 msgstr "Rodando (%2.4f%%)"
6.34
6.35 -#: src/cocoaui/cocoa_win.m:192 src/gtkui/gtk_win.c:356
6.36 +#: src/cocoaui/cocoa_win.m:193 src/gtkui/gtk_win.c:356
6.37 msgid "(Press <ctrl><alt> to release grab)"
6.38 msgstr "(Pressione <Ctrl><alt> para desprender)"
6.39
6.40 -#: src/cocoaui/cocoa_win.m:204 src/gtkui/gtk_win.c:366
6.41 +#: src/cocoaui/cocoa_win.m:205 src/gtkui/gtk_win.c:366
6.42 msgid "Running"
6.43 msgstr "Rodando"
6.44
6.45 -#: src/cocoaui/cocoa_win.m:207 src/gtkui/gtk_win.c:366
6.46 +#: src/cocoaui/cocoa_win.m:208 src/gtkui/gtk_win.c:366
6.47 msgid "Stopped"
6.48 msgstr "Parado"
6.49
6.50 @@ -53,32 +58,36 @@
6.51 msgid "Save-state path"
6.52 msgstr "Diretório de Estados Salvos"
6.53
6.54 -#: src/config.c:45 src/gtkui/gtk_path.c:29
6.55 +#: src/config.c:45
6.56 +msgid "VMU path"
6.57 +msgstr ""
6.58 +
6.59 +#: src/config.c:46 src/gtkui/gtk_path.c:29
6.60 msgid "Bootstrap IP.BIN"
6.61 msgstr "Bootstrap IP.BIN"
6.62
6.63 -#: src/config.c:51
6.64 +#: src/config.c:53
6.65 msgid "Serial device"
6.66 msgstr "Dispositivo Serial"
6.67
6.68 -#: src/dreamcast.c:192
6.69 +#: src/dreamcast.c:193
6.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.75
6.76 -#: src/dreamcast.c:324
6.77 +#: src/dreamcast.c:328
6.78 #, c-format
6.79 msgid "File is not a %s save state"
6.80 msgstr ""
6.81
6.82 -#: src/dreamcast.c:329
6.83 +#: src/dreamcast.c:333
6.84 #, c-format
6.85 msgid "Unsupported %s save state version"
6.86 msgstr ""
6.87
6.88 -#: src/dreamcast.c:334
6.89 +#: src/dreamcast.c:338
6.90 #, c-format
6.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.96
6.97 -#: src/gdlist.c:206 src/gdlist.c:229
6.98 +#: src/gdlist.c:187 src/gdlist.c:210
6.99 msgid "Empty"
6.100 msgstr "Vazio"
6.101
6.102 @@ -139,48 +148,65 @@
6.103 msgid "All files"
6.104 msgstr "Todos os Arquivos"
6.105
6.106 -#: src/gtkui/gtkcb.c:139
6.107 +#: src/gtkui/gtkcb.c:162
6.108 msgid "Load state..."
6.109 msgstr "Carregar stado..."
6.110
6.111 -#: src/gtkui/gtkcb.c:144 src/gtkui/gtkcb.c:175
6.112 +#: src/gtkui/gtkcb.c:167 src/gtkui/gtkcb.c:198
6.113 msgid "lxDream Save State (*.dst)"
6.114 msgstr "lxDream Save State (*.dst)"
6.115
6.116 -#: src/gtkui/gtkcb.c:237 src/gtkui/gtk_dump.c:69
6.117 +#: src/gtkui/gtkcb.c:260 src/gtkui/gtk_dump.c:69
6.118 msgid "Memory dump"
6.119 msgstr "Dump de memória"
6.120
6.121 -#: src/gtkui/gtkcb.c:250
6.122 +#: src/gtkui/gtkcb.c:273
6.123 msgid "Save next scene..."
6.124 msgstr "Salvar próxima cena"
6.125
6.126 -#: src/gtkui/gtkcb.c:250
6.127 +#: src/gtkui/gtkcb.c:273
6.128 msgid "lxdream scene file (*.dsc)"
6.129 msgstr "lxdream scene file (*.dsc)"
6.130
6.131 -#: src/gtkui/gtkcb.c:265
6.132 +#: src/gtkui/gtkcb.c:288
6.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.135
6.136 -#: src/gtkui/gtk_ctrl.c:72 src/gtkui/gtk_ctrl.c:101 src/gtkui/gtk_hotkeys.c:50
6.137 +#: src/gtkui/gtk_ctrl.c:80 src/gtkui/gtk_ctrl.c:109 src/gtkui/gtk_hotkeys.c:50
6.138 #: src/gtkui/gtk_hotkeys.c:79
6.139 msgid "<press key>"
6.140 msgstr "<Precione tecla>"
6.141
6.142 -#: src/gtkui/gtk_ctrl.c:201
6.143 +#: src/gtkui/gtk_ctrl.c:209
6.144 msgid "Controller Configuration"
6.145 msgstr "Configuração de controle"
6.146
6.147 -#: src/gtkui/gtk_ctrl.c:220
6.148 +#: src/gtkui/gtk_ctrl.c:228
6.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.151
6.152 -#: src/gtkui/gtk_ctrl.c:297
6.153 +#: src/gtkui/gtk_ctrl.c:252
6.154 +msgid "Load VMU"
6.155 +msgstr ""
6.156 +
6.157 +#: src/gtkui/gtk_ctrl.c:266
6.158 +msgid "Create VMU"
6.159 +msgstr ""
6.160 +
6.161 +#: src/gtkui/gtk_ctrl.c:329 src/gtkui/gtk_ctrl.c:347
6.162 msgid "<empty>"
6.163 msgstr "<Vazio>"
6.164
6.165 -#: src/gtkui/gtk_ctrl.c:325
6.166 +#: src/gtkui/gtk_ctrl.c:356
6.167 +#, fuzzy
6.168 +msgid "Load VMU..."
6.169 +msgstr "Carregar stado..."
6.170 +
6.171 +#: src/gtkui/gtk_ctrl.c:357
6.172 +msgid "Create VMU..."
6.173 +msgstr ""
6.174 +
6.175 +#: src/gtkui/gtk_ctrl.c:551
6.176 msgid "Controller Settings"
6.177 msgstr "Configurações de Controle"
6.178
6.179 @@ -564,140 +590,140 @@
6.180 msgid "Select quick save state 9"
6.181 msgstr ""
6.182
6.183 -#: src/main.c:85
6.184 +#: src/main.c:86
6.185 msgid "Run the AICA SPU only, with the supplied program"
6.186 msgstr "Correr Apenas o Spu AICA, com o programa dado"
6.187
6.188 -#: src/main.c:86
6.189 +#: src/main.c:87
6.190 msgid "Use the specified audio driver (? to list)"
6.191 msgstr "Usar Driver de audio específico (? para listar)"
6.192
6.193 -#: src/main.c:87
6.194 +#: src/main.c:88
6.195 msgid "Load configuration from CONFFILE"
6.196 msgstr "Carregar configurações de uma CONFFILE"
6.197
6.198 -#: src/main.c:88
6.199 +#: src/main.c:89
6.200 msgid "Start in debugger mode"
6.201 msgstr "Iniciar no modo debbugador"
6.202
6.203 -#: src/main.c:89
6.204 +#: src/main.c:90
6.205 #, fuzzy
6.206 msgid "Start in fullscreen mode"
6.207 msgstr "Iniciar no modo debbugador"
6.208
6.209 -#: src/main.c:90
6.210 +#: src/main.c:91
6.211 msgid "Start GDB remote server on PORT for SH4"
6.212 msgstr ""
6.213
6.214 -#: src/main.c:91
6.215 +#: src/main.c:92
6.216 msgid "Start GDB remote server on PORT for ARM"
6.217 msgstr ""
6.218
6.219 -#: src/main.c:92
6.220 +#: src/main.c:93
6.221 msgid "Display this usage information"
6.222 msgstr "Mostrar informações de uso"
6.223
6.224 -#: src/main.c:93
6.225 +#: src/main.c:94
6.226 msgid "Run in headless (no video) mode"
6.227 msgstr "Rodar no Modo (sem vídeo) sem cabeça"
6.228
6.229 -#: src/main.c:94
6.230 +#: src/main.c:95
6.231 msgid "Set the output log level"
6.232 msgstr "Definir o nível de saída do Log"
6.233
6.234 -#: src/main.c:95
6.235 +#: src/main.c:96
6.236 msgid "Set the SH4 multiplier (1.0 = fullspeed)"
6.237 msgstr "Definir Multiplicador do SH4 (1.0 = Velocidade total)"
6.238
6.239 -#: src/main.c:96
6.240 +#: src/main.c:97
6.241 msgid "Don't start running immediately"
6.242 msgstr "Não Correr Imediatamente"
6.243
6.244 -#: src/main.c:97
6.245 +#: src/main.c:98
6.246 msgid "Start running immediately on startup"
6.247 msgstr "Correr Imediatamente "
6.248
6.249 -#: src/main.c:98
6.250 +#: src/main.c:99
6.251 msgid "Run for the specified number of seconds"
6.252 msgstr "Correr por um número específico de segundos"
6.253
6.254 -#: src/main.c:99
6.255 +#: src/main.c:100
6.256 msgid "Output trace information for the named regions"
6.257 msgstr "Traçar informação de saída para regiões nomeadas"
6.258
6.259 -#: src/main.c:100
6.260 +#: src/main.c:101
6.261 msgid "Allow unsafe dcload syscalls"
6.262 msgstr "Permitir chamadas de sistema não seguras do dcload"
6.263
6.264 -#: src/main.c:101
6.265 +#: src/main.c:102
6.266 msgid "Print the lxdream version string"
6.267 msgstr "Mostrar a String de versão do lxdream"
6.268
6.269 -#: src/main.c:102
6.270 +#: src/main.c:103
6.271 msgid "Use the specified video driver (? to list)"
6.272 msgstr "Usar driver de vídeo específico (? para listar)"
6.273
6.274 -#: src/main.c:103
6.275 +#: src/main.c:104
6.276 msgid "Disable the SH4 translator"
6.277 msgstr "Desabilitar o tradutor de SH4"
6.278
6.279 -#: src/maple/controller.c:105 src/maple/lightgun.c:85
6.280 +#: src/maple/controller.c:106 src/maple/lightgun.c:86
6.281 msgid "Dpad left"
6.282 msgstr "Dpad Esquerda"
6.283
6.284 -#: src/maple/controller.c:106 src/maple/lightgun.c:86
6.285 +#: src/maple/controller.c:107 src/maple/lightgun.c:87
6.286 msgid "Dpad right"
6.287 msgstr "Dpad Direita"
6.288
6.289 -#: src/maple/controller.c:107 src/maple/lightgun.c:87
6.290 +#: src/maple/controller.c:108 src/maple/lightgun.c:88
6.291 msgid "Dpad up"
6.292 msgstr "Dpad Cima"
6.293
6.294 -#: src/maple/controller.c:108 src/maple/lightgun.c:88
6.295 +#: src/maple/controller.c:109 src/maple/lightgun.c:89
6.296 msgid "Dpad down"
6.297 msgstr "Dpad Baixo"
6.298
6.299 -#: src/maple/controller.c:109
6.300 +#: src/maple/controller.c:110
6.301 msgid "Analog left"
6.302 msgstr "Analógico Esquerda"
6.303
6.304 -#: src/maple/controller.c:110
6.305 +#: src/maple/controller.c:111
6.306 msgid "Analog right"
6.307 msgstr "Analógico Direita"
6.308
6.309 -#: src/maple/controller.c:111
6.310 +#: src/maple/controller.c:112
6.311 msgid "Analog up"
6.312 msgstr "Analógico Cima"
6.313
6.314 -#: src/maple/controller.c:112
6.315 +#: src/maple/controller.c:113
6.316 msgid "Analog down"
6.317 msgstr "Analógico Baixo"
6.318
6.319 -#: src/maple/controller.c:113
6.320 +#: src/maple/controller.c:114
6.321 msgid "Button X"
6.322 msgstr "Botão X"
6.323
6.324 -#: src/maple/controller.c:114
6.325 +#: src/maple/controller.c:115
6.326 msgid "Button Y"
6.327 msgstr "Botão Y"
6.328
6.329 -#: src/maple/controller.c:115 src/maple/lightgun.c:89
6.330 +#: src/maple/controller.c:116 src/maple/lightgun.c:90
6.331 msgid "Button A"
6.332 msgstr "Botão A"
6.333
6.334 -#: src/maple/controller.c:116 src/maple/lightgun.c:90
6.335 +#: src/maple/controller.c:117 src/maple/lightgun.c:91
6.336 msgid "Button B"
6.337 msgstr "Botão B"
6.338
6.339 -#: src/maple/controller.c:117
6.340 +#: src/maple/controller.c:118
6.341 msgid "Trigger left"
6.342 msgstr "Gatilho Esquerda"
6.343
6.344 -#: src/maple/controller.c:118
6.345 +#: src/maple/controller.c:119
6.346 msgid "Trigger right"
6.347 msgstr "Gatilho Direita"
6.348
6.349 -#: src/maple/controller.c:119 src/maple/lightgun.c:91
6.350 +#: src/maple/controller.c:120 src/maple/lightgun.c:92
6.351 msgid "Start button"
6.352 msgstr "Botão Start"
6.353
7.1 --- a/src/Makefile.am Wed Jun 24 02:27:34 2009 +0000
7.2 +++ b/src/Makefile.am Wed Jun 24 02:41:12 2009 +0000
7.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 +0000
8.2 +++ b/src/Makefile.in Wed Jun 24 02:41:12 2009 +0000
8.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.75
8.76 +lxdream-vmu.o: maple/vmu.c
8.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; fi
8.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.c
8.82 +
8.83 +lxdream-vmu.obj: maple/vmu.c
8.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; fi
8.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.c
8.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; fi
8.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.96
8.97 +lxdream-vmuvol.o: vmu/vmuvol.c
8.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; fi
8.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.c
8.103 +
8.104 +lxdream-vmuvol.obj: vmu/vmuvol.c
8.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; fi
8.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.c
8.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; fi
8.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.c
8.117 +
8.118 +lxdream-vmulist.obj: vmu/vmulist.c
8.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; fi
8.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.c
8.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 +0000
9.2 +++ b/src/cocoaui/cocoa_ctrl.m Wed Jun 24 02:41:12 2009 +0000
9.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.8
9.9 #include <glib/gstrfuncs.h>
9.10
9.11 -#define MAX_DEVICES 4
9.12 +#define FIRST_SECONDARY_DEVICE MAPLE_PORTS
9.13 +
9.14 +#define FIRST_VMU_TAG 0x1000
9.15 +#define LOAD_VMU_TAG -1
9.16 +#define CREATE_VMU_TAG -2
9.17
9.18 #define KEYBINDING_SIZE 110
9.19
9.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.22
9.23 @interface KeyBindingEditor (Private)
9.24 - (void)updateKeysym: (const gchar *)sym;
9.25 @@ -188,7 +194,7 @@
9.26 @interface ControllerKeyBindingView : NSView
9.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 *)notify
9.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.97
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.117
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 @end
9.156
9.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 : NSObject
9.268 +{
9.269 +}
9.270 +- (BOOL)panel:(id) sender isValidFilename: (NSString *)filename;
9.271 +@end
9.272 +
9.273 +@implementation VMULoadValidator
9.274 +- (BOOL)panel:(id) sender isValidFilename: (NSString *)filename
9.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 +@end
9.288 +
9.289 +@interface VMUCreateValidator : NSObject
9.290 +{
9.291 +}
9.292 +- (BOOL)panel:(id) sender isValidFilename: (NSString *)filename;
9.293 +@end
9.294 +
9.295 +@implementation VMUCreateValidator
9.296 +- (BOOL)panel:(id) sender isValidFilename: (NSString *)filename
9.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 +@end
9.308 +
9.309
9.310 @interface LxdreamPrefsControllerPane: LxdreamPrefsPane
9.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 @end
9.322
9.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 LxdreamPrefsControllerPane
9.331 + (LxdreamPrefsControllerPane *)new
9.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.341
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.350
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.356
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.399
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)dealloc
9.407 +{
9.408 + unregister_vmulist_change_hook(cocoa_config_vmulist_hook,self);
9.409 + [super dealloc];
9.410 +}
9.411 +- (void)vmulistChanged: (id)sender
9.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)sender
9.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)sender
9.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.445
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.460
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 change
9.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 +0000
10.2 +++ b/src/cocoaui/cocoa_prefs.m Wed Jun 24 02:41:12 2009 +0000
10.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 +0000
11.2 +++ b/src/config.c Wed Jun 24 02:41:12 2009 +0000
11.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.14
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.19
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 +0000
12.2 +++ b/src/config.h Wed Jun 24 02:41:12 2009 +0000
12.3 @@ -20,6 +20,7 @@
12.4 #define lxdream_config_H 1
12.5
12.6 #include <glib/gtypes.h>
12.7 +#include <glib/glist.h>
12.8 #include "gettext.h"
12.9
12.10 #ifdef __cplusplus
12.11 @@ -30,6 +31,7 @@
12.12 #define CONFIG_TYPE_FILE 1
12.13 #define CONFIG_TYPE_PATH 2
12.14 #define CONFIG_TYPE_KEY 3
12.15 +#define CONFIG_TYPE_FILELIST 4
12.16
12.17 #define DEFAULT_CONFIG_FILENAME "lxdreamrc"
12.18
12.19 @@ -50,10 +52,12 @@
12.20 #define CONFIG_FLASH_PATH 1
12.21 #define CONFIG_DEFAULT_PATH 2
12.22 #define CONFIG_SAVE_PATH 3
12.23 -#define CONFIG_BOOTSTRAP 4
12.24 -#define CONFIG_GDROM 5
12.25 -#define CONFIG_RECENT 6
12.26 -#define CONFIG_KEY_MAX CONFIG_RECENT
12.27 +#define CONFIG_VMU_PATH 4
12.28 +#define CONFIG_BOOTSTRAP 5
12.29 +#define CONFIG_GDROM 6
12.30 +#define CONFIG_RECENT 7
12.31 +#define CONFIG_VMU 8
12.32 +#define CONFIG_KEY_MAX CONFIG_VMU
12.33
12.34 extern struct lxdream_config_group lxdream_config_root[];
12.35
12.36 @@ -67,6 +71,16 @@
12.37 void lxdream_copy_config_list( lxdream_config_entry_t dest, lxdream_config_entry_t src );
12.38
12.39 /**
12.40 + * Construct a list of strings for the given config key - The caller is
12.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/.lxdreamrc
12.52 * $CWD/lxdreamrc
13.1 --- a/src/dreamcast.c Wed Jun 24 02:27:34 2009 +0000
13.2 +++ b/src/dreamcast.c Wed Jun 24 02:41:12 2009 +0000
13.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.8
13.9 /**
13.10 * Current state of the DC virtual machine
13.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.18
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_SH4STATS
13.26 sh4_stats_print(stdout);
13.27 #endif
14.1 --- a/src/gdlist.c Wed Jun 24 02:27:34 2009 +0000
14.2 +++ b/src/gdlist.c Wed Jun 24 02:41:12 2009 +0000
14.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.21
14.22
14.23 @@ -146,17 +135,9 @@
14.24
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);
14.41
15.1 --- a/src/gtkui/gtk_ctrl.c Wed Jun 24 02:27:34 2009 +0000
15.2 +++ b/src/gtkui/gtk_ctrl.c Wed Jun 24 02:41:12 2009 +0000
15.3 @@ -19,6 +19,7 @@
15.4
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.10
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.16
15.17 #define MAX_DEVICES 4
15.18
15.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.24
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.33
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.39
15.40 -static struct maple_slot_data maple_data[MAX_DEVICES];
15.41 +static struct maple_slot_data maple_data[MAPLE_MAX_DEVICES];
15.42
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.48
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.57
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.153
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 ways
15.199 + * to do this
15.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 primary
15.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.291
15.292 }
15.293
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.302
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.351
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 +0000
16.2 +++ b/src/gtkui/gtk_gd.c Wed Jun 24 02:41:12 2009 +0000
16.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 }
16.11
17.1 --- a/src/gtkui/gtkcb.c Wed Jun 24 02:27:34 2009 +0000
17.2 +++ b/src/gtkui/gtkcb.c Wed Jun 24 02:41:12 2009 +0000
17.3 @@ -39,10 +39,11 @@
17.4 }
17.5 }
17.6
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.30
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.72
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.88
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.106
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 +0000
18.2 +++ b/src/gtkui/gtkui.h Wed Jun 24 02:41:12 2009 +0000
18.3 @@ -88,8 +88,14 @@
18.4
18.5
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 +0000
19.2 +++ b/src/hook.h Wed Jun 24 02:41:12 2009 +0000
19.3 @@ -22,7 +22,7 @@
19.4 #include <assert.h>
19.5
19.6 /**
19.7 - * Hook functions are generally useful, so we'd let to limit the overhead (and
19.8 + * Hook functions are generally useful, so we'd like to limit the overhead (and
19.9 * opportunity for stupid bugs) by minimizing the amount of code involved. Glib
19.10 * has GHook (and of course signals), but they don't actually simplify anything
19.11 * at this level.
19.12 @@ -46,6 +46,7 @@
19.13
19.14 #define FOREACH_HOOK( h, name ) struct name##_hook_struct *h; for( h = name##_hook_list; h != NULL; h = h->next )
19.15
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.18
19.19 #define DEFINE_HOOK( name, fn_type ) \
20.1 --- a/src/main.c Wed Jun 24 02:27:34 2009 +0000
20.2 +++ b/src/main.c Wed Jun 24 02:41:12 2009 +0000
20.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.10
20.11 @@ -216,6 +217,7 @@
20.12 }
20.13
20.14 gdrom_list_init();
20.15 + vmulist_init();
20.16
20.17 if( aica_program == NULL ) {
20.18 dreamcast_init();
21.1 --- a/src/maple/controller.c Wed Jun 24 02:27:34 2009 +0000
21.2 +++ b/src/maple/controller.c Wed Jun 24 02:41:12 2009 +0000
21.3 @@ -93,14 +93,15 @@
21.4 struct lxdream_config_entry config[CONTROLLER_CONFIG_ENTRIES+1];
21.5 } *controller_device_t;
21.6
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.10
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 +0000
22.2 +++ b/src/maple/kbd.c Wed Jun 24 02:41:12 2009 +0000
22.3 @@ -52,13 +52,14 @@
22.4 uint8_t condition[8];
22.5 } *keyboard_device_t;
22.6
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.9
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 };
22.20
23.1 --- a/src/maple/lightgun.c Wed Jun 24 02:27:34 2009 +0000
23.2 +++ b/src/maple/lightgun.c Wed Jun 24 02:41:12 2009 +0000
23.3 @@ -72,14 +72,15 @@
23.4 struct lxdream_config_entry config[LIGHTGUN_CONFIG_ENTRIES+1];
23.5 } *lightgun_device_t;
23.6
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.10
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 +0000
24.2 +++ b/src/maple/maple.c Wed Jun 24 02:41:12 2009 +0000
24.3 @@ -30,7 +30,7 @@
24.4 NULL, NULL, NULL };
24.5
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.9
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 the
24.27 + * bits in the address in the response according to the
24.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 +0000
25.2 +++ b/src/maple/maple.h Wed Jun 24 02:41:12 2009 +0000
25.3 @@ -26,6 +26,18 @@
25.4 #include <stdint.h>
25.5 #include "config.h"
25.6
25.7 +#define MAPLE_PORTS 4
25.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 simplify
25.12 + * configuration. Port is 0..3 (A..D) representing the primary ports, and
25.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 0x00010000
25.32 #define MAPLE_FUNC_MOUSE 0x00020000
25.33
25.34 -#define MAPLE_GRAB_DONTCARE 0
25.35 -#define MAPLE_GRAB_YES 1
25.36 -#define MAPLE_GRAB_NO 2
25.37 +/* Internal flags, mainly for UI consumption */
25.38 +#define MAPLE_GRAB_DONTCARE 0x00
25.39 +#define MAPLE_GRAB_YES 0x01
25.40 +#define MAPLE_GRAB_NO 0x02
25.41 +#define MAPLE_GRAB_MASK 0x03
25.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 0x10
25.45 +#define MAPLE_SLOTS_2 0x20
25.46 +#define MAPLE_SLOTS(x) ((((x)->flags)&MAPLE_SLOTS_MASK)>>4)
25.47
25.48 #define MAPLE_DEVICE_TAG 0x4D41504C
25.49 #define MAPLE_DEVICE(x) ((maple_device_t)x)
25.50
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.63
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.69
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.100
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 +0000
26.2 +++ b/src/maple/mouse.c Wed Jun 24 02:41:12 2009 +0000
26.3 @@ -55,13 +55,13 @@
26.4 int32_t axis[8];
26.5 } *mouse_device_t;
26.6
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.9
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 };
26.19
27.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
27.2 +++ b/src/maple/vmu.c Wed Jun 24 02:41:12 2009 +0000
27.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 device
27.8 + * Part No. HKT-7000
27.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't
27.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 modify
27.17 + * it under the terms of the GNU General Public License as published by
27.18 + * the Free Software Foundation; either version 2 of the License, or
27.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 of
27.23 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27.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 256
27.41 +#define VMU_BLOCK_SIZE 512
27.42 +#define VMU_PHASE_SIZE 128
27.43 +#define VMU_CONFIG_ENTRIES 1
27.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 fallthrough
27.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 now
27.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 now
27.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 +0000
28.2 +++ b/src/vmu/vmulist.c Wed Jun 24 02:41:12 2009 +0000
28.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 VMUs
28.8 + *
28.9 + * Copyright (c) 2009 Nathan Keynes.
28.10 + *
28.11 + * This program is free software; you can redistribute it and/or modify
28.12 + * it under the terms of the GNU General Public License as published by
28.13 + * the Free Software Foundation; either version 2 of the License, or
28.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 of
28.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28.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 long
28.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 found
28.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 found
28.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 found
28.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 allow
28.142 + * user-editable display names it will
28.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 +0000
29.2 +++ b/src/vmu/vmulist.h Wed Jun 24 02:41:12 2009 +0000
29.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 VMUs
29.8 + *
29.9 + * Copyright (c) 2009 Nathan Keynes.
29.10 + *
29.11 + * This program is free software; you can redistribute it and/or modify
29.12 + * it under the terms of the GNU General Public License as published by
29.13 + * the Free Software Foundation; either version 2 of the License, or
29.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 of
29.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29.19 + * GNU General Public License for more details.
29.20 + */
29.21 +
29.22 +
29.23 +#ifndef lxdream_vmulist_H
29.24 +#define lxdream_vmulist_H 1
29.25 +
29.26 +#ifdef __cplusplus
29.27 +extern "C" {
29.28 +#endif
29.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's
29.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 TRUE
29.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 list
29.67 + * @param filename to save the new VMU as
29.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 to
29.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 __cplusplus
29.95 +}
29.96 +#endif
29.97 +
29.98 +#endif /* !lxdream_vmulist_H */
30.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
30.2 +++ b/src/vmu/vmuvol.c Wed Jun 24 02:41:12 2009 +0000
30.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) support
30.8 + *
30.9 + * Copyright (c) 2009 Nathan Keynes.
30.10 + *
30.11 + * This program is free software; you can redistribute it and/or modify
30.12 + * it under the terms of the GNU General Public License as published by
30.13 + * the Free Software Foundation; either version 2 of the License, or
30.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 of
30.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30.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 256
30.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 0xFFFC
30.84 +#define FAT_EOF 0xFFFA
30.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 a
30.172 + * DATA chunk for each partition's block data. The META chunk is required to
30.173 + * occur before any DATA blocks.
30.174 + * Unknown chunks are skipped to allow for forwards compatibility if/when
30.175 + * we add the VMU runtime side of things
30.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 / blocks
30.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 block
30.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 +0000
31.2 +++ b/src/vmu/vmuvol.h Wed Jun 24 02:41:12 2009 +0000
31.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) declarations
31.8 + *
31.9 + * Copyright (c) 2009 Nathan Keynes.
31.10 + *
31.11 + * This program is free software; you can redistribute it and/or modify
31.12 + * it under the terms of the GNU General Public License as published by
31.13 + * the Free Software Foundation; either version 2 of the License, or
31.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 of
31.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31.19 + * GNU General Public License for more details.
31.20 + */
31.21 +
31.22 +#ifndef lxdream_vmuvol_H
31.23 +#define lxdream_vmuvol_H 1
31.24 +
31.25 +#ifdef __cplusplus
31.26 +extern "C" {
31.27 +#endif
31.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 0x00010000
31.36 +
31.37 +/** VMU block size is 512 bytes */
31.38 +#define VMU_BLOCK_SIZE 512
31.39 +
31.40 +/** Default VMU volume is 256 blocks */
31.41 +#define VMU_DEFAULT_VOL_BLOCKS 256
31.42 +
31.43 +/** Default VMU has 200 user blocks */
31.44 +#define VMU_DEFAULT_VOL_USERBLOCKS 200
31.45 +
31.46 +/** Default superblock is at block 255 */
31.47 +#define VMU_DEFAULT_VOL_SUPERBLOCK 255
31.48 +
31.49 +/** Default file allocation table is at block 254 */
31.50 +#define VMU_DEFAULT_VOL_FATBLOCK 254
31.51 +
31.52 +/** Default root directory block starts at block 253 */
31.53 +#define VMU_DEFAULT_VOL_ROOTDIR 253
31.54 +
31.55 +/**
31.56 + * VMU metadata structure. Note that this is structured to match the maple
31.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 size
31.73 + * (128Kb). The partitions is formatted using the default filesystem
31.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 layout
31.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 the
31.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 __cplusplus
31.116 +}
31.117 +#endif
31.118 +
31.119 +#endif /* !lxdream_vmuvol_H */
.