PCem
changeset 113:f749363ad763
Added per-device configuration.
Reworked configuration parser a bit.
Added configuration for S3 ViRGE and 8-bit Sound Blasters.
IRQ 2 routed to IRQ 9 on AT machines.
| author | TomW |
|---|---|
| date | Mon Jun 30 21:31:28 2014 +0100 |
| parents | c5989dbbc2ce |
| children | 9834054948fc |
| files | src/Makefile.mingw src/config.c src/config.h src/device.c src/device.h src/pc.c src/pc.rc src/pic.c src/resources.h src/sound.c src/sound.h src/sound_sb.c src/vid_s3_virge.c src/video.c src/video.h src/win-config.c src/win-deviceconfig.c src/win.h |
| diffstat | 18 files changed, 1077 insertions(+), 139 deletions(-) [+] |
line diff
1.1 --- a/src/Makefile.mingw Tue Jun 24 21:15:42 2014 +0100 1.2 +++ b/src/Makefile.mingw Mon Jun 30 21:31:28 2014 +0100 1.3 @@ -19,7 +19,7 @@ 1.4 vid_s3_virge.o vid_sdac_ramdac.o vid_stg_ramdac.o vid_svga.o vid_svga_render.o \ 1.5 vid_tandy.o vid_tgui9440.o vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o vid_vga.o \ 1.6 vid_voodoo.o video.o wd76c10.o win.o win-config.o win-d3d.o win-d3d-fs.o win-ddraw.o \ 1.7 - win-ddraw-fs.o win-hdconf.o win-joystick.o win-keyboard.o win-midi.o win-mouse.o \ 1.8 + win-ddraw-fs.o win-deviceconfig.o win-hdconf.o win-joystick.o win-keyboard.o win-midi.o win-mouse.o \ 1.9 win-status.o win-video.o x86seg.o x87.o xtide.o pc.res 1.10 FMOBJ = dbopl.o 1.11 SIDOBJ = convolve.o envelope.o extfilt.o filter.o pot.o sid.o voice.o wave6581__ST.o wave6581_P_T.o wave6581_PS_.o wave6581_PST.o wave8580__ST.o wave8580_P_T.o wave8580_PS_.o wave8580_PST.o wave.o
2.1 --- a/src/config.c Tue Jun 24 21:15:42 2014 +0100 2.2 +++ b/src/config.c Mon Jun 30 21:31:28 2014 +0100 2.3 @@ -1,9 +1,194 @@ 2.4 #include <stdio.h> 2.5 #include <string.h> 2.6 +#include <stdlib.h> 2.7 #include "config.h" 2.8 2.9 static char config_file[256]; 2.10 2.11 +typedef struct list_t 2.12 +{ 2.13 + struct list_t *next; 2.14 +} list_t; 2.15 + 2.16 +static list_t config_head; 2.17 + 2.18 +typedef struct section_t 2.19 +{ 2.20 + struct list_t list; 2.21 + 2.22 + char name[256]; 2.23 + 2.24 + struct list_t entry_head; 2.25 +} section_t; 2.26 + 2.27 +typedef struct entry_t 2.28 +{ 2.29 + struct list_t list; 2.30 + 2.31 + char name[256]; 2.32 + char data[256]; 2.33 +} entry_t; 2.34 + 2.35 +#define list_add(new, head) \ 2.36 + { \ 2.37 + struct list_t *next = head; \ 2.38 + \ 2.39 + while (next->next) \ 2.40 + next = next->next; \ 2.41 + \ 2.42 + (next)->next = new; \ 2.43 + (new)->next = NULL; \ 2.44 + } 2.45 + 2.46 +void config_dump() 2.47 +{ 2.48 + section_t *current_section; 2.49 + 2.50 + pclog("Config data :\n"); 2.51 + 2.52 + current_section = (section_t *)config_head.next; 2.53 + 2.54 + while (current_section) 2.55 + { 2.56 + entry_t *current_entry; 2.57 + 2.58 + pclog("[%s]\n", current_section->name); 2.59 + 2.60 + current_entry = (entry_t *)current_section->entry_head.next; 2.61 + 2.62 + while (current_entry) 2.63 + { 2.64 + pclog("%s = %s\n", current_entry->name, current_entry->data); 2.65 + 2.66 + current_entry = (entry_t *)current_entry->list.next; 2.67 + } 2.68 + 2.69 + current_section = (section_t *)current_section->list.next; 2.70 + } 2.71 +} 2.72 + 2.73 +void config_free() 2.74 +{ 2.75 + section_t *current_section; 2.76 + current_section = (section_t *)config_head.next; 2.77 + 2.78 + while (current_section) 2.79 + { 2.80 + section_t *next_section = (section_t *)current_section->list.next; 2.81 + entry_t *current_entry; 2.82 + 2.83 + current_entry = (entry_t *)current_section->entry_head.next; 2.84 + 2.85 + while (current_entry) 2.86 + { 2.87 + entry_t *next_entry = (entry_t *)current_entry->list.next; 2.88 + 2.89 + free(current_entry); 2.90 + current_entry = next_entry; 2.91 + } 2.92 + 2.93 + free(current_section); 2.94 + current_section = next_section; 2.95 + } 2.96 +} 2.97 + 2.98 +void config_load() 2.99 +{ 2.100 + FILE *f = fopen(config_file, "rt"); 2.101 + section_t *current_section; 2.102 + 2.103 + memset(&config_head, 0, sizeof(list_t)); 2.104 + 2.105 + current_section = malloc(sizeof(section_t)); 2.106 + memset(current_section, 0, sizeof(section_t)); 2.107 + list_add(¤t_section->list, &config_head); 2.108 + 2.109 + if (!f) 2.110 + return; 2.111 + 2.112 + while (1) 2.113 + { 2.114 + int c; 2.115 + char buffer[256]; 2.116 + 2.117 + fgets(buffer, 255, f); 2.118 + if (feof(f)) break; 2.119 + 2.120 + c = 0; 2.121 + 2.122 + while (buffer[c] == ' ' && buffer[c]) 2.123 + c++; 2.124 + 2.125 + if (!buffer[c]) continue; 2.126 + 2.127 + if (buffer[c] == '#') /*Comment*/ 2.128 + continue; 2.129 + 2.130 + if (buffer[c] == '[') /*Section*/ 2.131 + { 2.132 + section_t *new_section; 2.133 + char name[256]; 2.134 + int d = 0; 2.135 + 2.136 + c++; 2.137 + while (buffer[c] != ']' && buffer[c]) 2.138 + name[d++] = buffer[c++]; 2.139 + 2.140 + if (buffer[c] != ']') 2.141 + continue; 2.142 + name[d] = 0; 2.143 + 2.144 + new_section = malloc(sizeof(section_t)); 2.145 + memset(new_section, 0, sizeof(section_t)); 2.146 + strncpy(new_section->name, name, 256); 2.147 + list_add(&new_section->list, &config_head); 2.148 + 2.149 + current_section = new_section; 2.150 + 2.151 +// pclog("New section : %s %p\n", name, (void *)current_section); 2.152 + } 2.153 + else 2.154 + { 2.155 + entry_t *new_entry; 2.156 + char name[256]; 2.157 + int d = 0, data_pos; 2.158 + 2.159 + while (buffer[c] != '=' && buffer[c] != ' ' && buffer[c]) 2.160 + name[d++] = buffer[c++]; 2.161 + 2.162 + if (!buffer[c]) continue; 2.163 + name[d] = 0; 2.164 + 2.165 + while ((buffer[c] == '=' || buffer[c] == ' ') && buffer[c]) 2.166 + c++; 2.167 + 2.168 + if (!buffer[c]) continue; 2.169 + 2.170 + data_pos = c; 2.171 + while (buffer[c]) 2.172 + { 2.173 + if (buffer[c] == '\n') 2.174 + buffer[c] = 0; 2.175 + c++; 2.176 + } 2.177 + 2.178 + new_entry = malloc(sizeof(entry_t)); 2.179 + memset(new_entry, 0, sizeof(entry_t)); 2.180 + strncpy(new_entry->name, name, 256); 2.181 + strncpy(new_entry->data, &buffer[data_pos], 256); 2.182 + list_add(&new_entry->list, ¤t_section->entry_head); 2.183 + 2.184 +// pclog("New data under section [%s] : %s = %s\n", current_section->name, new_entry->name, new_entry->data); 2.185 + } 2.186 + } 2.187 + 2.188 + fclose(f); 2.189 + 2.190 + config_dump(); 2.191 +} 2.192 + 2.193 + 2.194 + 2.195 void set_config_file(char *s) 2.196 { 2.197 strcpy(config_file, s); 2.198 @@ -15,132 +200,139 @@ 2.199 fclose(f); 2.200 } 2.201 2.202 +static section_t *find_section(char *name) 2.203 +{ 2.204 + section_t *current_section; 2.205 + char blank[] = ""; 2.206 + 2.207 + current_section = (section_t *)config_head.next; 2.208 + if (!name) 2.209 + name = blank; 2.210 + 2.211 + while (current_section) 2.212 + { 2.213 + if (!strncmp(current_section->name, name, 256)) 2.214 + return current_section; 2.215 + 2.216 + current_section = (section_t *)current_section->list.next; 2.217 + } 2.218 + return NULL; 2.219 +} 2.220 + 2.221 +static entry_t *find_entry(section_t *section, char *name) 2.222 +{ 2.223 + entry_t *current_entry; 2.224 + 2.225 + current_entry = (entry_t *)section->entry_head.next; 2.226 + 2.227 + while (current_entry) 2.228 + { 2.229 + if (!strncmp(current_entry->name, name, 256)) 2.230 + return current_entry; 2.231 + 2.232 + current_entry = (entry_t *)current_entry->list.next; 2.233 + } 2.234 + return NULL; 2.235 +} 2.236 + 2.237 +static section_t *create_section(char *name) 2.238 +{ 2.239 + section_t *new_section = malloc(sizeof(section_t)); 2.240 + 2.241 + memset(new_section, 0, sizeof(section_t)); 2.242 + strncpy(new_section->name, name, 256); 2.243 + list_add(&new_section->list, &config_head); 2.244 + 2.245 + return new_section; 2.246 +} 2.247 + 2.248 +static entry_t *create_entry(section_t *section, char *name) 2.249 +{ 2.250 + entry_t *new_entry = malloc(sizeof(entry_t)); 2.251 + memset(new_entry, 0, sizeof(entry_t)); 2.252 + strncpy(new_entry->name, name, 256); 2.253 + list_add(&new_entry->list, §ion->entry_head); 2.254 + 2.255 + return new_entry; 2.256 +} 2.257 + 2.258 int get_config_int(char *head, char *name, int def) 2.259 { 2.260 - char buffer[256]; 2.261 - char name2[256]; 2.262 - FILE *f = fopen(config_file, "rt"); 2.263 - int c, d; 2.264 - int res = def; 2.265 + section_t *section; 2.266 + entry_t *entry; 2.267 + int value; 2.268 + 2.269 + section = find_section(head); 2.270 2.271 - if (!f) 2.272 - return def; 2.273 - 2.274 -// pclog("Searching for %s\n", name); 2.275 + if (!section) 2.276 + return def; 2.277 + 2.278 + entry = find_entry(section, name); 2.279 + 2.280 + if (!entry) 2.281 + return def; 2.282 2.283 - while (1) 2.284 - { 2.285 - fgets(buffer, 255, f); 2.286 - if (feof(f)) break; 2.287 - 2.288 - c = d = 0; 2.289 - 2.290 - while (buffer[c] == ' ' && buffer[c]) 2.291 - c++; 2.292 - 2.293 - if (!buffer[c]) continue; 2.294 - 2.295 - while (buffer[c] != '=' && buffer[c] != ' ' && buffer[c]) 2.296 - name2[d++] = buffer[c++]; 2.297 - 2.298 - if (!buffer[c]) continue; 2.299 - name2[d] = 0; 2.300 - 2.301 -// pclog("Comparing %s and %s\n", name, name2); 2.302 - if (strcmp(name, name2)) continue; 2.303 -// pclog("Found!\n"); 2.304 - 2.305 - while ((buffer[c] == '=' || buffer[c] == ' ') && buffer[c]) 2.306 - c++; 2.307 - 2.308 - if (!buffer[c]) continue; 2.309 - 2.310 - sscanf(&buffer[c], "%i", &res); 2.311 -// pclog("Reading value - %i\n", res); 2.312 - break; 2.313 - } 2.314 + sscanf(entry->data, "%i", &value); 2.315 2.316 - fclose(f); 2.317 - return res; 2.318 + return value; 2.319 } 2.320 2.321 -char config_return_string[256]; 2.322 - 2.323 char *get_config_string(char *head, char *name, char *def) 2.324 { 2.325 - char buffer[256]; 2.326 - char name2[256]; 2.327 - FILE *f = fopen(config_file, "rt"); 2.328 - int c, d; 2.329 + section_t *section; 2.330 + entry_t *entry; 2.331 + int value; 2.332 + 2.333 + section = find_section(head); 2.334 2.335 - strcpy(config_return_string, def); 2.336 - 2.337 - if (!f) 2.338 - return config_return_string; 2.339 - 2.340 -// pclog("Searching for %s\n", name); 2.341 - 2.342 - while (1) 2.343 - { 2.344 - fgets(buffer, 255, f); 2.345 - if (feof(f)) break; 2.346 + if (!section) 2.347 + return def; 2.348 2.349 - c = d = 0; 2.350 - 2.351 - while (buffer[c] == ' ' && buffer[c]) 2.352 - c++; 2.353 - 2.354 - if (!buffer[c]) continue; 2.355 - 2.356 - while (buffer[c] != '=' && buffer[c] != ' ' && buffer[c]) 2.357 - name2[d++] = buffer[c++]; 2.358 - 2.359 - if (!buffer[c]) continue; 2.360 - name2[d] = 0; 2.361 - 2.362 -// pclog("Comparing %s and %s\n", name, name2); 2.363 - if (strcmp(name, name2)) continue; 2.364 -// pclog("Found!\n"); 2.365 + entry = find_entry(section, name); 2.366 2.367 - while ((buffer[c] == '=' || buffer[c] == ' ') && buffer[c]) 2.368 - c++; 2.369 - 2.370 - if (!buffer[c]) continue; 2.371 - 2.372 - strcpy(config_return_string, &buffer[c]); 2.373 - 2.374 - c = strlen(config_return_string) - 1; 2.375 -// pclog("string len %i\n", c); 2.376 - while (config_return_string[c] <= 32 && config_return_string[c]) 2.377 - config_return_string[c--] = 0; 2.378 - 2.379 -// pclog("Reading value - %s\n", config_return_string); 2.380 - break; 2.381 - } 2.382 - 2.383 - fclose(f); 2.384 - return config_return_string; 2.385 + if (!entry) 2.386 + return def; 2.387 + 2.388 + return entry->data; 2.389 } 2.390 2.391 void set_config_int(char *head, char *name, int val) 2.392 { 2.393 - FILE *f = fopen(config_file, "at"); 2.394 -// if (!f) pclog("set_config_int - !f\n"); 2.395 - fprintf(f, "%s = %i\n", name, val); 2.396 -// pclog("Write %s = %i\n", name, val); 2.397 - fclose(f); 2.398 -// pclog("fclose\n"); 2.399 + section_t *section; 2.400 + entry_t *entry; 2.401 + 2.402 + section = find_section(head); 2.403 + 2.404 + if (!section) 2.405 + section = create_section(head); 2.406 + 2.407 + entry = find_entry(section, name); 2.408 + 2.409 + if (!entry) 2.410 + entry = create_entry(section, name); 2.411 + 2.412 + sprintf(entry->data, "%i", val); 2.413 } 2.414 2.415 void set_config_string(char *head, char *name, char *val) 2.416 { 2.417 - FILE *f = fopen(config_file, "at"); 2.418 -// if (!f) pclog("set_config_string - !f\n"); 2.419 - fprintf(f, "%s = %s\n", name, val); 2.420 -// pclog("Write %s = %s\n", name, val); 2.421 - fclose(f); 2.422 + section_t *section; 2.423 + entry_t *entry; 2.424 + 2.425 + section = find_section(head); 2.426 + 2.427 + if (!section) 2.428 + section = create_section(head); 2.429 + 2.430 + entry = find_entry(section, name); 2.431 + 2.432 + if (!entry) 2.433 + entry = create_entry(section, name); 2.434 + 2.435 + strncpy(entry->data, val, 256); 2.436 } 2.437 2.438 + 2.439 char *get_filename(char *s) 2.440 { 2.441 int c = strlen(s) - 1; 2.442 @@ -164,3 +356,32 @@ 2.443 if (s[c] != '/' && s[c] != '\\') 2.444 s[c] = '/'; 2.445 } 2.446 + 2.447 +void config_save() 2.448 +{ 2.449 + FILE *f = fopen(config_file, "wt"); 2.450 + section_t *current_section; 2.451 + 2.452 + current_section = (section_t *)config_head.next; 2.453 + 2.454 + while (current_section) 2.455 + { 2.456 + entry_t *current_entry; 2.457 + 2.458 + if (current_section->name[0]) 2.459 + fprintf(f, "\n[%s]\n", current_section->name); 2.460 + 2.461 + current_entry = (entry_t *)current_section->entry_head.next; 2.462 + 2.463 + while (current_entry) 2.464 + { 2.465 + fprintf(f, "%s = %s\n", current_entry->name, current_entry->data); 2.466 + 2.467 + current_entry = (entry_t *)current_entry->list.next; 2.468 + } 2.469 + 2.470 + current_section = (section_t *)current_section->list.next; 2.471 + } 2.472 + 2.473 + fclose(f); 2.474 +}
3.1 --- a/src/config.h Tue Jun 24 21:15:42 2014 +0100 3.2 +++ b/src/config.h Mon Jun 30 21:31:28 2014 +0100 3.3 @@ -7,3 +7,8 @@ 3.4 char *get_filename(char *s); 3.5 void append_filename(char *dest, char *s1, char *s2, int size); 3.6 void put_backslash(char *s); 3.7 + 3.8 +void config_load(); 3.9 +void config_save(); 3.10 +void config_dump(); 3.11 +void config_free();
4.1 --- a/src/device.c Tue Jun 24 21:15:42 2014 +0100 4.2 +++ b/src/device.c Mon Jun 30 21:31:28 2014 +0100 4.3 @@ -1,9 +1,12 @@ 4.4 #include "ibm.h" 4.5 +#include "config.h" 4.6 #include "device.h" 4.7 4.8 static void *device_priv[256]; 4.9 static device_t *devices[256]; 4.10 4.11 +static device_t *current_device; 4.12 + 4.13 void device_init() 4.14 { 4.15 memset(devices, 0, sizeof(devices)); 4.16 @@ -20,6 +23,8 @@ 4.17 if (c >= 256) 4.18 fatal("device_add : too many devices\n"); 4.19 4.20 + current_device = d; 4.21 + 4.22 priv = d->init(); 4.23 if (priv == NULL) 4.24 fatal("device_add : device init failed\n"); 4.25 @@ -105,3 +110,31 @@ 4.26 } 4.27 } 4.28 } 4.29 + 4.30 +int device_get_config_int(char *s) 4.31 +{ 4.32 + device_config_t *config = current_device->config; 4.33 + 4.34 + while (config->type != -1) 4.35 + { 4.36 + if (!strcmp(s, config->name)) 4.37 + return get_config_int(current_device->name, s, config->default_int); 4.38 + 4.39 + config++; 4.40 + } 4.41 + return 0; 4.42 +} 4.43 + 4.44 +char *device_get_config_string(char *s) 4.45 +{ 4.46 + device_config_t *config = current_device->config; 4.47 + 4.48 + while (config->type != -1) 4.49 + { 4.50 + if (!strcmp(s, config->name)) 4.51 + return get_config_string(current_device->name, s, config->default_string); 4.52 + 4.53 + config++; 4.54 + } 4.55 + return NULL; 4.56 +}
5.1 --- a/src/device.h Tue Jun 24 21:15:42 2014 +0100 5.2 +++ b/src/device.h Mon Jun 30 21:31:28 2014 +0100 5.3 @@ -1,3 +1,24 @@ 5.4 +#define CONFIG_STRING 0 5.5 +#define CONFIG_INT 1 5.6 +#define CONFIG_BINARY 2 5.7 +#define CONFIG_SELECTION 3 5.8 + 5.9 +typedef struct device_config_selection_t 5.10 +{ 5.11 + char description[256]; 5.12 + int value; 5.13 +} device_config_selection_t; 5.14 + 5.15 +typedef struct device_config_t 5.16 +{ 5.17 + char name[256]; 5.18 + char description[256]; 5.19 + int type; 5.20 + char default_string[256]; 5.21 + int default_int; 5.22 + device_config_selection_t selection[16]; 5.23 +} device_config_t; 5.24 + 5.25 typedef struct device_t 5.26 { 5.27 char name[50]; 5.28 @@ -8,6 +29,7 @@ 5.29 void (*speed_changed)(void *p); 5.30 void (*force_redraw)(void *p); 5.31 int (*add_status_info)(char *s, int max_len, void *p); 5.32 + device_config_t *config; 5.33 } device_t; 5.34 5.35 void device_init(); 5.36 @@ -18,6 +40,9 @@ 5.37 void device_force_redraw(); 5.38 char *device_add_status_info(char *s, int max_len); 5.39 5.40 +int device_get_config_int(char *name); 5.41 +char *device_get_config_string(char *name); 5.42 + 5.43 enum 5.44 { 5.45 DEVICE_NOT_WORKING = 1 /*Device does not currently work correctly and will be disabled in a release build*/
6.1 --- a/src/pc.c Tue Jun 24 21:15:42 2014 +0100 6.2 +++ b/src/pc.c Mon Jun 30 21:31:28 2014 +0100 6.3 @@ -426,6 +426,9 @@ 6.4 char *p; 6.5 append_filename(s, pcempath, "pcem.cfg", 511); 6.6 set_config_file(s); 6.7 + 6.8 + config_load(); 6.9 + 6.10 GAMEBLASTER = get_config_int(NULL, "gameblaster", 0); 6.11 GUS = get_config_int(NULL, "gus", 0); 6.12 SSI2001 = get_config_int(NULL, "ssi2001", 0); 6.13 @@ -480,7 +483,6 @@ 6.14 6.15 void saveconfig() 6.16 { 6.17 - config_new(); 6.18 set_config_int(NULL, "gameblaster", GAMEBLASTER); 6.19 set_config_int(NULL, "gus", GUS); 6.20 set_config_int(NULL, "ssi2001", SSI2001); 6.21 @@ -515,4 +517,6 @@ 6.22 set_config_int(NULL, "hdd_heads", hdc[1].hpc); 6.23 set_config_int(NULL, "hdd_cylinders", hdc[1].tracks); 6.24 set_config_string(NULL, "hdd_fn", ide_fn[1]); 6.25 + 6.26 + config_save(); 6.27 }
7.1 --- a/src/pc.rc Tue Jun 24 21:15:42 2014 +0100 7.2 +++ b/src/pc.rc Mon Jun 30 21:31:28 2014 +0100 7.3 @@ -47,7 +47,7 @@ 7.4 END 7.5 END 7.6 7.7 -ConfigureDlg DIALOGEX 0, 0, 232, 256 7.8 +ConfigureDlg DIALOGEX 0, 0, 232+40, 256 7.9 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU 7.10 CAPTION "Configure PCem" 7.11 FONT 8, "MS Sans Serif" 7.12 @@ -56,11 +56,13 @@ 7.13 PUSHBUTTON "Cancel",IDCANCEL,128,232,50,14, WS_TABSTOP 7.14 COMBOBOX IDC_COMBO1,62,16,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP 7.15 COMBOBOX IDC_COMBOVID,62,36,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP 7.16 + PUSHBUTTON "Configure", IDC_CONFIGUREVID, 224, 36, 40, 14, WS_TABSTOP 7.17 COMBOBOX IDC_COMBOCPUM,62,56,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP 7.18 COMBOBOX IDC_COMBO3,62,76,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP 7.19 COMBOBOX IDC_COMBOCHC,62,96,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP 7.20 COMBOBOX IDC_COMBOSPD,62,116,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP 7.21 COMBOBOX IDC_COMBOSND,62,136,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP 7.22 + PUSHBUTTON "Configure", IDC_CONFIGURESND, 224, 136, 40, 14, WS_TABSTOP 7.23 EDITTEXT IDC_MEMTEXT, 62, 152, 36, 14, ES_AUTOHSCROLL | ES_NUMBER 7.24 CONTROL "", IDC_MEMSPIN, UPDOWN_CLASS, UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS | UDS_SETBUDDYINT, 98, 152, 12, 14 7.25 LTEXT "MB", IDC_STATIC, 98, 152, 40, 10
8.1 --- a/src/pic.c Tue Jun 24 21:15:42 2014 +0100 8.2 +++ b/src/pic.c Mon Jun 30 21:31:28 2014 +0100 8.3 @@ -244,6 +244,8 @@ 8.4 8.5 void picint(uint16_t num) 8.6 { 8.7 + if (AT && num == (1 << 2)) 8.8 + num = 1 << 9; 8.9 // pclog("picint : %04X\n", num); 8.10 // if (num == 0x10) pclog("PICINT 10\n"); 8.11 if (num>0xFF) 8.12 @@ -264,6 +266,11 @@ 8.13 { 8.14 int c = 0; 8.15 while (!(num & (1 << c))) c++; 8.16 + if (AT && c == 2) 8.17 + { 8.18 + c = 9; 8.19 + num = 1 << 9; 8.20 + } 8.21 // pclog("INTLEVEL %04X %i\n", num, c); 8.22 if (!pic_current[c]) 8.23 { 8.24 @@ -283,6 +290,11 @@ 8.25 { 8.26 int c = 0; 8.27 while (!(num & (1 << c))) c++; 8.28 + if (AT && c == 2) 8.29 + { 8.30 + c = 9; 8.31 + num = 1 << 9; 8.32 + } 8.33 // pclog("INTC %04X %i\n", num, c); 8.34 pic_current[c]=0; 8.35
9.1 --- a/src/resources.h Tue Jun 24 21:15:42 2014 +0100 9.2 +++ b/src/resources.h Mon Jun 30 21:31:28 2014 +0100 9.3 @@ -77,5 +77,10 @@ 9.4 #define IDC_EDIT_C_FN 1220 9.5 #define IDC_EDIT_D_FN 1221 9.6 9.7 +#define IDC_CONFIGUREVID 1200 9.8 +#define IDC_CONFIGURESND 1201 9.9 + 9.10 +#define IDC_CONFIG_BASE 1200 9.11 + 9.12 #define WM_RESETD3D WM_USER 9.13 #define WM_LEAVEFULLSCREEN WM_USER + 1
10.1 --- a/src/sound.c Tue Jun 24 21:15:42 2014 +0100 10.2 +++ b/src/sound.c Mon Jun 30 21:31:28 2014 +0100 10.3 @@ -56,6 +56,16 @@ 10.4 return sound_cards[card].name; 10.5 } 10.6 10.7 +device_t *sound_card_getdevice(int card) 10.8 +{ 10.9 + return sound_cards[card].device; 10.10 +} 10.11 + 10.12 +int sound_card_has_config(int card) 10.13 +{ 10.14 + return sound_cards[card].device->config ? 1 : 0; 10.15 +} 10.16 + 10.17 void sound_card_init() 10.18 { 10.19 if (sound_cards[sound_card_current].device)
11.1 --- a/src/sound.h Tue Jun 24 21:15:42 2014 +0100 11.2 +++ b/src/sound.h Mon Jun 30 21:31:28 2014 +0100 11.3 @@ -7,4 +7,6 @@ 11.4 11.5 int sound_card_available(int card); 11.6 char *sound_card_getname(int card); 11.7 +struct device_t *sound_card_getdevice(int card); 11.8 +int sound_card_has_config(int card); 11.9 void sound_card_init();
12.1 --- a/src/sound_sb.c Tue Jun 24 21:15:42 2014 +0100 12.2 +++ b/src/sound_sb.c Mon Jun 30 21:31:28 2014 +0100 12.3 @@ -256,13 +256,16 @@ 12.4 void *sb_1_init() 12.5 { 12.6 sb_t *sb = malloc(sizeof(sb_t)); 12.7 + uint16_t addr = device_get_config_int("addr"); 12.8 memset(sb, 0, sizeof(sb_t)); 12.9 12.10 opl2_init(&sb->opl); 12.11 sb_dsp_init(&sb->dsp, SB1); 12.12 - sb_dsp_setaddr(&sb->dsp, 0x0220); 12.13 + sb_dsp_setaddr(&sb->dsp, addr); 12.14 + sb_dsp_setirq(&sb->dsp, device_get_config_int("irq")); 12.15 + sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma")); 12.16 sb_mixer_init(&sb->mixer); 12.17 - io_sethandler(0x0228, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl); 12.18 + io_sethandler(addr+8, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl); 12.19 io_sethandler(0x0388, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl); 12.20 sound_add_handler(sb_opl2_poll, sb_get_buffer, sb); 12.21 return sb; 12.22 @@ -270,13 +273,16 @@ 12.23 void *sb_15_init() 12.24 { 12.25 sb_t *sb = malloc(sizeof(sb_t)); 12.26 + uint16_t addr = device_get_config_int("addr"); 12.27 memset(sb, 0, sizeof(sb_t)); 12.28 12.29 opl2_init(&sb->opl); 12.30 sb_dsp_init(&sb->dsp, SB15); 12.31 - sb_dsp_setaddr(&sb->dsp, 0x0220); 12.32 + sb_dsp_setaddr(&sb->dsp, addr); 12.33 + sb_dsp_setirq(&sb->dsp, device_get_config_int("irq")); 12.34 + sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma")); 12.35 sb_mixer_init(&sb->mixer); 12.36 - io_sethandler(0x0228, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl); 12.37 + io_sethandler(addr+8, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl); 12.38 io_sethandler(0x0388, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl); 12.39 sound_add_handler(sb_opl2_poll, sb_get_buffer, sb); 12.40 return sb; 12.41 @@ -284,13 +290,16 @@ 12.42 void *sb_2_init() 12.43 { 12.44 sb_t *sb = malloc(sizeof(sb_t)); 12.45 + uint16_t addr = device_get_config_int("addr"); 12.46 memset(sb, 0, sizeof(sb_t)); 12.47 12.48 opl2_init(&sb->opl); 12.49 sb_dsp_init(&sb->dsp, SB2); 12.50 - sb_dsp_setaddr(&sb->dsp, 0x0220); 12.51 + sb_dsp_setaddr(&sb->dsp, addr); 12.52 + sb_dsp_setirq(&sb->dsp, device_get_config_int("irq")); 12.53 + sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma")); 12.54 sb_mixer_init(&sb->mixer); 12.55 - io_sethandler(0x0228, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl); 12.56 + io_sethandler(addr+8, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl); 12.57 io_sethandler(0x0388, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl); 12.58 sound_add_handler(sb_opl2_poll, sb_get_buffer, sb); 12.59 return sb; 12.60 @@ -299,17 +308,20 @@ 12.61 void *sb_pro_v1_init() 12.62 { 12.63 sb_t *sb = malloc(sizeof(sb_t)); 12.64 + uint16_t addr = device_get_config_int("addr"); 12.65 memset(sb, 0, sizeof(sb_t)); 12.66 12.67 opl2_init(&sb->opl); 12.68 sb_dsp_init(&sb->dsp, SBPRO); 12.69 - sb_dsp_setaddr(&sb->dsp, 0x0220); 12.70 + sb_dsp_setaddr(&sb->dsp, addr); 12.71 + sb_dsp_setirq(&sb->dsp, device_get_config_int("irq")); 12.72 + sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma")); 12.73 sb_mixer_init(&sb->mixer); 12.74 - io_sethandler(0x0220, 0x0002, opl2_l_read, NULL, NULL, opl2_l_write, NULL, NULL, &sb->opl); 12.75 - io_sethandler(0x0222, 0x0002, opl2_r_read, NULL, NULL, opl2_r_write, NULL, NULL, &sb->opl); 12.76 - io_sethandler(0x0228, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl); 12.77 + io_sethandler(addr+0, 0x0002, opl2_l_read, NULL, NULL, opl2_l_write, NULL, NULL, &sb->opl); 12.78 + io_sethandler(addr+2, 0x0002, opl2_r_read, NULL, NULL, opl2_r_write, NULL, NULL, &sb->opl); 12.79 + io_sethandler(addr+8, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl); 12.80 io_sethandler(0x0388, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl); 12.81 - io_sethandler(0x0224, 0x0002, sb_pro_mixer_read, NULL, NULL, sb_pro_mixer_write, NULL, NULL, sb); 12.82 + io_sethandler(addr+4, 0x0002, sb_pro_mixer_read, NULL, NULL, sb_pro_mixer_write, NULL, NULL, sb); 12.83 sound_add_handler(sb_opl2_poll, sb_get_buffer, sb); 12.84 12.85 sb->mixer.regs[0x22] = 0xff; 12.86 @@ -323,16 +335,19 @@ 12.87 void *sb_pro_v2_init() 12.88 { 12.89 sb_t *sb = malloc(sizeof(sb_t)); 12.90 + uint16_t addr = device_get_config_int("addr"); 12.91 memset(sb, 0, sizeof(sb_t)); 12.92 12.93 opl3_init(&sb->opl); 12.94 sb_dsp_init(&sb->dsp, SBPRO2); 12.95 - sb_dsp_setaddr(&sb->dsp, 0x0220); 12.96 + sb_dsp_setaddr(&sb->dsp, addr); 12.97 + sb_dsp_setirq(&sb->dsp, device_get_config_int("irq")); 12.98 + sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma")); 12.99 sb_mixer_init(&sb->mixer); 12.100 - io_sethandler(0x0220, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); 12.101 - io_sethandler(0x0228, 0x0002, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); 12.102 + io_sethandler(addr+0, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); 12.103 + io_sethandler(addr+8, 0x0002, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); 12.104 io_sethandler(0x0388, 0x0002, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); 12.105 - io_sethandler(0x0224, 0x0002, sb_pro_mixer_read, NULL, NULL, sb_pro_mixer_write, NULL, NULL, sb); 12.106 + io_sethandler(addr+4, 0x0002, sb_pro_mixer_read, NULL, NULL, sb_pro_mixer_write, NULL, NULL, sb); 12.107 sound_add_handler(sb_opl3_poll, sb_get_buffer, sb); 12.108 12.109 sb->mixer.regs[0x22] = 0xff; 12.110 @@ -436,6 +451,158 @@ 12.111 sb_dsp_add_status_info(s, max_len, &sb->dsp); 12.112 } 12.113 12.114 +static device_config_t sb_config[] = 12.115 +{ 12.116 + { 12.117 + .name = "addr", 12.118 + .description = "Address", 12.119 + .type = CONFIG_BINARY, 12.120 + .type = CONFIG_SELECTION, 12.121 + .selection = 12.122 + { 12.123 + { 12.124 + .description = "0x220", 12.125 + .value = 0x220 12.126 + }, 12.127 + { 12.128 + .description = "0x240", 12.129 + .value = 0x240 12.130 + }, 12.131 + { 12.132 + .description = "" 12.133 + } 12.134 + }, 12.135 + .default_int = 0x220 12.136 + }, 12.137 + { 12.138 + .name = "irq", 12.139 + .description = "IRQ", 12.140 + .type = CONFIG_SELECTION, 12.141 + .selection = 12.142 + { 12.143 + { 12.144 + .description = "IRQ 2", 12.145 + .value = 2 12.146 + }, 12.147 + { 12.148 + .description = "IRQ 3", 12.149 + .value = 3 12.150 + }, 12.151 + { 12.152 + .description = "IRQ 5", 12.153 + .value = 5 12.154 + }, 12.155 + { 12.156 + .description = "IRQ 7", 12.157 + .value = 7 12.158 + }, 12.159 + { 12.160 + .description = "" 12.161 + } 12.162 + }, 12.163 + .default_int = 7 12.164 + }, 12.165 + { 12.166 + .name = "dma", 12.167 + .description = "DMA", 12.168 + .type = CONFIG_SELECTION, 12.169 + .selection = 12.170 + { 12.171 + { 12.172 + .description = "DMA 1", 12.173 + .value = 1 12.174 + }, 12.175 + { 12.176 + .description = "DMA 3", 12.177 + .value = 3 12.178 + }, 12.179 + { 12.180 + .description = "" 12.181 + } 12.182 + }, 12.183 + .default_int = 1 12.184 + }, 12.185 + { 12.186 + .type = -1 12.187 + } 12.188 +}; 12.189 + 12.190 +static device_config_t sb_pro_config[] = 12.191 +{ 12.192 + { 12.193 + .name = "addr", 12.194 + .description = "Address", 12.195 + .type = CONFIG_BINARY, 12.196 + .type = CONFIG_SELECTION, 12.197 + .selection = 12.198 + { 12.199 + { 12.200 + .description = "0x220", 12.201 + .value = 0x220 12.202 + }, 12.203 + { 12.204 + .description = "0x240", 12.205 + .value = 0x240 12.206 + }, 12.207 + { 12.208 + .description = "" 12.209 + } 12.210 + }, 12.211 + .default_int = 0x220 12.212 + }, 12.213 + { 12.214 + .name = "irq", 12.215 + .description = "IRQ", 12.216 + .type = CONFIG_SELECTION, 12.217 + .selection = 12.218 + { 12.219 + { 12.220 + .description = "IRQ 2", 12.221 + .value = 2 12.222 + }, 12.223 + { 12.224 + .description = "IRQ 5", 12.225 + .value = 5 12.226 + }, 12.227 + { 12.228 + .description = "IRQ 7", 12.229 + .value = 7 12.230 + }, 12.231 + { 12.232 + .description = "IRQ 10", 12.233 + .value = 10 12.234 + }, 12.235 + { 12.236 + .description = "" 12.237 + } 12.238 + }, 12.239 + .default_int = 7 12.240 + }, 12.241 + { 12.242 + .name = "dma", 12.243 + .description = "DMA", 12.244 + .type = CONFIG_SELECTION, 12.245 + .selection = 12.246 + { 12.247 + { 12.248 + .description = "DMA 1", 12.249 + .value = 1 12.250 + }, 12.251 + { 12.252 + .description = "DMA 3", 12.253 + .value = 3 12.254 + }, 12.255 + { 12.256 + .description = "" 12.257 + } 12.258 + }, 12.259 + .default_int = 1 12.260 + }, 12.261 + { 12.262 + .type = -1 12.263 + } 12.264 +}; 12.265 + 12.266 device_t sb_1_device = 12.267 { 12.268 "Sound Blaster v1.0", 12.269 @@ -445,7 +612,8 @@ 12.270 NULL, 12.271 sb_speed_changed, 12.272 NULL, 12.273 - sb_add_status_info 12.274 + sb_add_status_info, 12.275 + sb_config 12.276 }; 12.277 device_t sb_15_device = 12.278 { 12.279 @@ -456,7 +624,8 @@ 12.280 NULL, 12.281 sb_speed_changed, 12.282 NULL, 12.283 - sb_add_status_info 12.284 + sb_add_status_info, 12.285 + sb_config 12.286 }; 12.287 device_t sb_2_device = 12.288 { 12.289 @@ -467,7 +636,8 @@ 12.290 NULL, 12.291 sb_speed_changed, 12.292 NULL, 12.293 - sb_add_status_info 12.294 + sb_add_status_info, 12.295 + sb_config 12.296 }; 12.297 device_t sb_pro_v1_device = 12.298 { 12.299 @@ -478,7 +648,8 @@ 12.300 NULL, 12.301 sb_speed_changed, 12.302 NULL, 12.303 - sb_add_status_info 12.304 + sb_add_status_info, 12.305 + sb_pro_config 12.306 }; 12.307 device_t sb_pro_v2_device = 12.308 { 12.309 @@ -489,7 +660,8 @@ 12.310 NULL, 12.311 sb_speed_changed, 12.312 NULL, 12.313 - sb_add_status_info 12.314 + sb_add_status_info, 12.315 + sb_pro_config 12.316 }; 12.317 device_t sb_16_device = 12.318 {
13.1 --- a/src/vid_s3_virge.c Tue Jun 24 21:15:42 2014 +0100 13.2 +++ b/src/vid_s3_virge.c Mon Jun 30 21:31:28 2014 +0100 13.3 @@ -38,6 +38,9 @@ 13.4 13.5 int is_375; 13.6 13.7 + int bilinear_enabled; 13.8 + int memory_size; 13.9 + 13.10 int pixel_count, tri_count; 13.11 13.12 struct 13.13 @@ -2486,7 +2489,7 @@ 13.14 // pclog("use tex_sample_mipmap\n"); 13.15 break; 13.16 case 2: case 3: 13.17 - tex_sample = tex_sample_mipmap_filter; 13.18 + tex_sample = virge->bilinear_enabled ? tex_sample_mipmap_filter : tex_sample_mipmap; 13.19 // pclog("use tex_sample_mipmap_filter\n"); 13.20 break; 13.21 case 4: case 5: 13.22 @@ -2494,7 +2497,7 @@ 13.23 // pclog("use tex_sample_normal\n"); 13.24 break; 13.25 case 6: case 7: 13.26 - tex_sample = tex_sample_normal_filter; 13.27 + tex_sample = virge->bilinear_enabled ? tex_sample_normal_filter : tex_sample_normal; 13.28 // pclog("use tex_sample_normal_filter\n"); 13.29 break; 13.30 case (0 | 8): case (1 | 8): 13.31 @@ -2506,9 +2509,9 @@ 13.32 break; 13.33 case (2 | 8): case (3 | 8): 13.34 if (virge->is_375) 13.35 - tex_sample = tex_sample_persp_mipmap_filter_375; 13.36 + tex_sample = virge->bilinear_enabled ? tex_sample_persp_mipmap_filter_375 : tex_sample_persp_mipmap_375; 13.37 else 13.38 - tex_sample = tex_sample_persp_mipmap_filter; 13.39 + tex_sample = virge->bilinear_enabled ? tex_sample_persp_mipmap_filter : tex_sample_persp_mipmap; 13.40 // pclog("use tex_sample_persp_mipmap_filter\n"); 13.41 break; 13.42 case (4 | 8): case (5 | 8): 13.43 @@ -2520,9 +2523,9 @@ 13.44 break; 13.45 case (6 | 8): case (7 | 8): 13.46 if (virge->is_375) 13.47 - tex_sample = tex_sample_persp_normal_filter_375; 13.48 + tex_sample = virge->bilinear_enabled ? tex_sample_persp_normal_filter_375 : tex_sample_persp_normal_375; 13.49 else 13.50 - tex_sample = tex_sample_persp_normal_filter; 13.51 + tex_sample = virge->bilinear_enabled ? tex_sample_persp_normal_filter : tex_sample_persp_normal; 13.52 // pclog("use tex_sample_persp_normal_filter\n"); 13.53 break; 13.54 } 13.55 @@ -2974,8 +2977,12 @@ 13.56 { 13.57 virge_t *virge = malloc(sizeof(virge_t)); 13.58 memset(virge, 0, sizeof(virge_t)); 13.59 + 13.60 + virge->bilinear_enabled = device_get_config_int("bilinear"); 13.61 + virge->memory_size = device_get_config_int("memory"); 13.62 + pclog("bilinear_enabled=%i memory_size=%i\n", virge->bilinear_enabled, virge->memory_size); 13.63 13.64 - svga_init(&virge->svga, virge, 1 << 22, /*4mb*/ 13.65 + svga_init(&virge->svga, virge, virge->memory_size << 20, 13.66 s3_virge_recalctimings, 13.67 s3_virge_in, s3_virge_out, 13.68 s3_virge_hwcursor_draw, 13.69 @@ -3029,7 +3036,17 @@ 13.70 virge->virge_rev = 0; 13.71 virge->virge_id = 0xe1; 13.72 13.73 - virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4); 13.74 + switch (virge->memory_size) 13.75 + { 13.76 + case 2: 13.77 + virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4) | (4 << 5); 13.78 + break; 13.79 + case 4: 13.80 + default: 13.81 + virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4) | (0 << 5); 13.82 + break; 13.83 + } 13.84 + 13.85 virge->svga.crtc[0x37] = 1;// | (7 << 5); 13.86 virge->svga.crtc[0x53] = 1 << 3; 13.87 virge->svga.crtc[0x59] = 0x70; 13.88 @@ -3046,7 +3063,11 @@ 13.89 virge_t *virge = malloc(sizeof(virge_t)); 13.90 memset(virge, 0, sizeof(virge_t)); 13.91 13.92 - svga_init(&virge->svga, virge, 1 << 22, /*4mb*/ 13.93 + virge->bilinear_enabled = device_get_config_int("bilinear"); 13.94 + virge->memory_size = device_get_config_int("memory"); 13.95 + pclog("bilinear_enabled=%i memory_size=%i\n", virge->bilinear_enabled, virge->memory_size); 13.96 + 13.97 + svga_init(&virge->svga, virge, virge->memory_size << 20, 13.98 s3_virge_recalctimings, 13.99 s3_virge_in, s3_virge_out, 13.100 s3_virge_hwcursor_draw, 13.101 @@ -3100,7 +3121,17 @@ 13.102 virge->virge_rev = 0; 13.103 virge->virge_id = 0xe1; 13.104 13.105 - virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4); 13.106 + switch (virge->memory_size) 13.107 + { 13.108 + case 2: 13.109 + virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4) | (4 << 5); 13.110 + break; 13.111 + case 4: 13.112 + default: 13.113 + virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4) | (0 << 5); 13.114 + break; 13.115 + } 13.116 +// virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4); 13.117 virge->svga.crtc[0x37] = 1;// | (7 << 5); 13.118 virge->svga.crtc[0x53] = 1 << 3; 13.119 virge->svga.crtc[0x59] = 0x70; 13.120 @@ -3174,6 +3205,39 @@ 13.121 return max_len - cur_len; 13.122 } 13.123 13.124 +static device_config_t s3_virge_config[] = 13.125 +{ 13.126 + { 13.127 + .name = "bilinear", 13.128 + .description = "Bilinear filtering", 13.129 + .type = CONFIG_BINARY, 13.130 + .default_int = 1 13.131 + }, 13.132 + { 13.133 + .name = "memory", 13.134 + .description = "Memory size", 13.135 + .type = CONFIG_SELECTION, 13.136 + .selection = 13.137 + { 13.138 + { 13.139 + .description = "2 MB", 13.140 + .value = 2 13.141 + }, 13.142 + { 13.143 + .description = "4 MB", 13.144 + .value = 4 13.145 + }, 13.146 + { 13.147 + .description = "" 13.148 + } 13.149 + }, 13.150 + .default_int = 4 13.151 + }, 13.152 + { 13.153 + .type = -1 13.154 + } 13.155 +}; 13.156 + 13.157 device_t s3_virge_device = 13.158 { 13.159 "Diamond Stealth 3D 2000 (S3 ViRGE)", 13.160 @@ -3183,7 +3247,8 @@ 13.161 s3_virge_available, 13.162 s3_virge_speed_changed, 13.163 s3_virge_force_redraw, 13.164 - s3_virge_add_status_info 13.165 + s3_virge_add_status_info, 13.166 + s3_virge_config 13.167 }; 13.168 13.169 device_t s3_virge_375_device = 13.170 @@ -3195,5 +3260,6 @@ 13.171 s3_virge_375_available, 13.172 s3_virge_speed_changed, 13.173 s3_virge_force_redraw, 13.174 - s3_virge_add_status_info 13.175 + s3_virge_add_status_info, 13.176 + s3_virge_config 13.177 };
14.1 --- a/src/video.c Tue Jun 24 21:15:42 2014 +0100 14.2 +++ b/src/video.c Mon Jun 30 21:31:28 2014 +0100 14.3 @@ -78,6 +78,16 @@ 14.4 return video_cards[card].name; 14.5 } 14.6 14.7 +device_t *video_card_getdevice(int card) 14.8 +{ 14.9 + return video_cards[card].device; 14.10 +} 14.11 + 14.12 +int video_card_has_config(int card) 14.13 +{ 14.14 + return video_cards[card].device->config ? 1 : 0; 14.15 +} 14.16 + 14.17 int video_card_getid(char *s) 14.18 { 14.19 int c = 0;
15.1 --- a/src/video.h Tue Jun 24 21:15:42 2014 +0100 15.2 +++ b/src/video.h Mon Jun 30 21:31:28 2014 +0100 15.3 @@ -1,5 +1,7 @@ 15.4 int video_card_available(int card); 15.5 char *video_card_getname(int card); 15.6 +struct device_t *video_card_getdevice(int card); 15.7 +int video_card_has_config(int card); 15.8 int video_card_getid(char *s); 15.9 int video_old_to_new(int card); 15.10 int video_new_to_old(int card);
16.1 --- a/src/win-config.c Tue Jun 24 21:15:42 2014 +0100 16.2 +++ b/src/win-config.c Mon Jun 30 21:31:28 2014 +0100 16.3 @@ -7,6 +7,7 @@ 16.4 16.5 #include "ibm.h" 16.6 #include "cpu.h" 16.7 +#include "device.h" 16.8 #include "model.h" 16.9 #include "resources.h" 16.10 #include "sound.h" 16.11 @@ -153,7 +154,19 @@ 16.12 SendMessage(h, UDM_SETBUDDY, (WPARAM)GetDlgItem(hdlg, IDC_MEMTEXT), 0); 16.13 SendMessage(h, UDM_SETRANGE, 0, (1 << 16) | 256); 16.14 SendMessage(h, UDM_SETPOS, 0, mem_size); 16.15 + 16.16 + h = GetDlgItem(hdlg, IDC_CONFIGUREVID); 16.17 + if (video_card_has_config(video_old_to_new(gfxcard))) 16.18 + EnableWindow(h, TRUE); 16.19 + else 16.20 + EnableWindow(h, FALSE); 16.21 16.22 + h = GetDlgItem(hdlg, IDC_CONFIGURESND); 16.23 + if (sound_card_has_config(sound_card_current)) 16.24 + EnableWindow(h, TRUE); 16.25 + else 16.26 + EnableWindow(h, FALSE); 16.27 + 16.28 return TRUE; 16.29 16.30 case WM_COMMAND: 16.31 @@ -322,6 +335,43 @@ 16.32 SendMessage(h, CB_SETCURSEL, temp_cpu, 0); 16.33 } 16.34 break; 16.35 + 16.36 + case IDC_CONFIGUREVID: 16.37 + h = GetDlgItem(hdlg, IDC_COMBOVID); 16.38 + SendMessage(h, CB_GETLBTEXT, SendMessage(h, CB_GETCURSEL, 0, 0), (LPARAM)temp_str); 16.39 + 16.40 + deviceconfig_open(hdlg, (void *)video_card_getdevice(video_card_getid(temp_str))); 16.41 + break; 16.42 + 16.43 + case IDC_COMBOVID: 16.44 + h = GetDlgItem(hdlg, IDC_COMBOVID); 16.45 + SendMessage(h, CB_GETLBTEXT, SendMessage(h, CB_GETCURSEL, 0, 0), (LPARAM)temp_str); 16.46 + gfx = video_card_getid(temp_str); 16.47 + 16.48 + h = GetDlgItem(hdlg, IDC_CONFIGUREVID); 16.49 + if (video_card_has_config(gfx)) 16.50 + EnableWindow(h, TRUE); 16.51 + else 16.52 + EnableWindow(h, FALSE); 16.53 + break; 16.54 + 16.55 + case IDC_CONFIGURESND: 16.56 + h = GetDlgItem(hdlg, IDC_COMBOSND); 16.57 + temp_sound_card_current = settings_list_to_sound[SendMessage(h, CB_GETCURSEL, 0, 0)]; 16.58 + 16.59 + deviceconfig_open(hdlg, (void *)sound_card_getdevice(temp_sound_card_current)); 16.60 + break; 16.61 + 16.62 + case IDC_COMBOSND: 16.63 + h = GetDlgItem(hdlg, IDC_COMBOSND); 16.64 + temp_sound_card_current = settings_list_to_sound[SendMessage(h, CB_GETCURSEL, 0, 0)]; 16.65 + 16.66 + h = GetDlgItem(hdlg, IDC_CONFIGURESND); 16.67 + if (sound_card_has_config(temp_sound_card_current)) 16.68 + EnableWindow(h, TRUE); 16.69 + else 16.70 + EnableWindow(h, FALSE); 16.71 + break; 16.72 } 16.73 break; 16.74 }
17.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 17.2 +++ b/src/win-deviceconfig.c Mon Jun 30 21:31:28 2014 +0100 17.3 @@ -0,0 +1,317 @@ 17.4 +#define BITMAP WINDOWS_BITMAP 17.5 +#include <windows.h> 17.6 +#include <windowsx.h> 17.7 +#undef BITMAP 17.8 + 17.9 +#include "ibm.h" 17.10 +#include "config.h" 17.11 +#include "device.h" 17.12 +#include "resources.h" 17.13 +#include "win.h" 17.14 + 17.15 +static device_t *config_device; 17.16 + 17.17 +static BOOL CALLBACK deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) 17.18 +{ 17.19 + switch (message) 17.20 + { 17.21 + case WM_INITDIALOG: 17.22 + { 17.23 + int id = IDC_CONFIG_BASE; 17.24 + device_config_t *config = config_device->config; 17.25 + int c; 17.26 + 17.27 + while (config->type != -1) 17.28 + { 17.29 + device_config_selection_t *selection = config->selection; 17.30 + HWND h = GetDlgItem(hdlg, id); 17.31 + int val_int; 17.32 + char *val_string; 17.33 + 17.34 + switch (config->type) 17.35 + { 17.36 + case CONFIG_BINARY: 17.37 + val_int = get_config_int(config_device->name, config->name, config->default_int); 17.38 + 17.39 + SendMessage(h, BM_SETCHECK, val_int, 0); 17.40 + 17.41 + id++; 17.42 + break; 17.43 + 17.44 + case CONFIG_SELECTION: 17.45 + val_int = get_config_int(config_device->name, config->name, config->default_int); 17.46 + 17.47 + c = 0; 17.48 + while (selection->description[0]) 17.49 + { 17.50 + SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)selection->description); 17.51 + if (val_int == selection->value) 17.52 + SendMessage(h, CB_SETCURSEL, c, 0); 17.53 + selection++; 17.54 + c++; 17.55 + } 17.56 + 17.57 + id += 2; 17.58 + break; 17.59 + } 17.60 + config++; 17.61 + } 17.62 + } 17.63 + return TRUE; 17.64 + 17.65 + case WM_COMMAND: 17.66 + switch (LOWORD(wParam)) 17.67 + { 17.68 + case IDOK: 17.69 + { 17.70 + int id = IDC_CONFIG_BASE; 17.71 + device_config_t *config = config_device->config; 17.72 + int c; 17.73 + int changed = 0; 17.74 + 17.75 + while (config->type != -1) 17.76 + { 17.77 + device_config_selection_t *selection = config->selection; 17.78 + HWND h = GetDlgItem(hdlg, id); 17.79 + int val_int; 17.80 + char *val_string; 17.81 + 17.82 + switch (config->type) 17.83 + { 17.84 + case CONFIG_BINARY: 17.85 + val_int = get_config_int(config_device->name, config->name, config->default_int); 17.86 + 17.87 + if (val_int != SendMessage(h, BM_GETCHECK, 0, 0)) 17.88 + changed = 1; 17.89 + 17.90 + id++; 17.91 + break; 17.92 + 17.93 + case CONFIG_SELECTION: 17.94 + val_int = get_config_int(config_device->name, config->name, config->default_int); 17.95 + 17.96 + c = SendMessage(h, CB_GETCURSEL, 0, 0); 17.97 + 17.98 + for (; c > 0; c--) 17.99 + selection++; 17.100 + 17.101 + if (val_int != selection->value) 17.102 + changed = 1; 17.103 + 17.104 + id += 2; 17.105 + break; 17.106 + } 17.107 + config++; 17.108 + } 17.109 + 17.110 + if (!changed) 17.111 + { 17.112 + EndDialog(hdlg, 0); 17.113 + return TRUE; 17.114 + } 17.115 + 17.116 + if (MessageBox(NULL, "This will reset PCem!\nOkay to continue?", "PCem", MB_OKCANCEL) != IDOK) 17.117 + { 17.118 + EndDialog(hdlg, 0); 17.119 + return TRUE; 17.120 + } 17.121 + 17.122 + id = IDC_CONFIG_BASE; 17.123 + config = config_device->config; 17.124 + 17.125 + while (config->type != -1) 17.126 + { 17.127 + device_config_selection_t *selection = config->selection; 17.128 + HWND h = GetDlgItem(hdlg, id); 17.129 + int val_int; 17.130 + char *val_string; 17.131 + 17.132 + switch (config->type) 17.133 + { 17.134 + case CONFIG_BINARY: 17.135 + set_config_int(config_device->name, config->name, SendMessage(h, BM_GETCHECK, 0, 0)); 17.136 + 17.137 + id++; 17.138 + break; 17.139 + 17.140 + case CONFIG_SELECTION: 17.141 + c = SendMessage(h, CB_GETCURSEL, 0, 0); 17.142 + for (; c > 0; c--) 17.143 + selection++; 17.144 + set_config_int(config_device->name, config->name, selection->value); 17.145 + 17.146 + id += 2; 17.147 + break; 17.148 + } 17.149 + config++; 17.150 + } 17.151 + 17.152 + saveconfig(); 17.153 + 17.154 + resetpchard(); 17.155 + 17.156 + EndDialog(hdlg, 0); 17.157 + return TRUE; 17.158 + } 17.159 + case IDCANCEL: 17.160 + EndDialog(hdlg, 0); 17.161 + return TRUE; 17.162 + } 17.163 + break; 17.164 + } 17.165 + return FALSE; 17.166 +} 17.167 + 17.168 +void deviceconfig_open(HWND hwnd, device_t *device) 17.169 +{ 17.170 + device_config_t *config = device->config; 17.171 + uint16_t *data = malloc(16384); 17.172 + DLGTEMPLATE *dlg = (DLGTEMPLATE *)data; 17.173 + DLGITEMTEMPLATE *item; 17.174 + int y = 10; 17.175 + int id = IDC_CONFIG_BASE; 17.176 + 17.177 + memset(data, 0, 4096); 17.178 + 17.179 + dlg->style = DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU; 17.180 + dlg->x = 10; 17.181 + dlg->y = 10; 17.182 + dlg->cx = 150; 17.183 + dlg->cy = 70; 17.184 + 17.185 + data = (uint16_t *)(dlg + 1); 17.186 + 17.187 + *data++ = 0; /*no menu*/ 17.188 + *data++ = 0; /*predefined dialog box class*/ 17.189 + data += MultiByteToWideChar(CP_ACP, 0, "Device Configuration", -1, data, 50); 17.190 + 17.191 + *data++ = 8; /*Point*/ 17.192 + data += MultiByteToWideChar(CP_ACP, 0, "MS Sans Serif", -1, data, 50); 17.193 + 17.194 + if (((unsigned long)data) & 2) 17.195 + data++; 17.196 + 17.197 + while (config->type != -1) 17.198 + { 17.199 + switch (config->type) 17.200 + { 17.201 + case CONFIG_BINARY: 17.202 + item = (DLGITEMTEMPLATE *)data; 17.203 + item->x = 10; 17.204 + item->y = y; 17.205 + item->id = id++; 17.206 + 17.207 + item->cx = 80; 17.208 + item->cy = 15; 17.209 + 17.210 + item->style = WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX; 17.211 + 17.212 + data = (uint16_t *)(item + 1); 17.213 + *data++ = 0xFFFF; 17.214 + *data++ = 0x0080; // button class 17.215 + 17.216 + data += MultiByteToWideChar(CP_ACP, 0, config->description, -1, data, 256); 17.217 + *data++ = 0; // no creation data 17.218 + 17.219 + y += 20; 17.220 + break; 17.221 + 17.222 + case CONFIG_SELECTION: 17.223 + /*Combo box*/ 17.224 + item = (DLGITEMTEMPLATE *)data; 17.225 + item->x = 70; 17.226 + item->y = y; 17.227 + item->id = id++; 17.228 + 17.229 + item->cx = 70; 17.230 + item->cy = 150; 17.231 + 17.232 + item->style = WS_CHILD | WS_VISIBLE | CBS_DROPDOWN | WS_VSCROLL; 17.233 + 17.234 + data = (uint16_t *)(item + 1); 17.235 + *data++ = 0xFFFF; 17.236 + *data++ = 0x0085; // combo box class 17.237 + 17.238 + data += MultiByteToWideChar(CP_ACP, 0, config->description, -1, data, 256); 17.239 + *data++ = 0; // no creation data 17.240 + 17.241 + if (((unsigned long)data) & 2) 17.242 + data++; 17.243 + 17.244 + /*Static text*/ 17.245 + item = (DLGITEMTEMPLATE *)data; 17.246 + item->x = 10; 17.247 + item->y = y; 17.248 + item->id = id++; 17.249 + 17.250 + item->cx = 60; 17.251 + item->cy = 15; 17.252 + 17.253 + item->style = WS_CHILD | WS_VISIBLE; 17.254 + 17.255 + data = (uint16_t *)(item + 1); 17.256 + *data++ = 0xFFFF; 17.257 + *data++ = 0x0082; // static class 17.258 + 17.259 + data += MultiByteToWideChar(CP_ACP, 0, config->description, -1, data, 256); 17.260 + *data++ = 0; // no creation data 17.261 + 17.262 + if (((unsigned long)data) & 2) 17.263 + data++; 17.264 + 17.265 + y += 20; 17.266 + break; 17.267 + } 17.268 + 17.269 + if (((unsigned long)data) & 2) 17.270 + data++; 17.271 + 17.272 + config++; 17.273 + } 17.274 + 17.275 + dlg->cdit = (id - IDC_CONFIG_BASE) + 2; 17.276 + 17.277 +// DEFPUSHBUTTON "OK",IDOK,64,232,50,14, WS_TABSTOP 17.278 +// PUSHBUTTON "Cancel",IDCANCEL,128,232,50,14, WS_TABSTOP 17.279 + 17.280 + item = (DLGITEMTEMPLATE *)data; 17.281 + item->x = 20; 17.282 + item->y = y; 17.283 + item->cx = 50; 17.284 + item->cy = 14; 17.285 + item->id = IDOK; // OK button identifier 17.286 + item->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON; 17.287 + 17.288 + data = (uint16_t *)(item + 1); 17.289 + *data++ = 0xFFFF; 17.290 + *data++ = 0x0080; // button class 17.291 + 17.292 + data += MultiByteToWideChar(CP_ACP, 0, "OK", -1, data, 50); 17.293 + *data++ = 0; // no creation data 17.294 + 17.295 + if (((unsigned long)data) & 2) 17.296 + data++; 17.297 + 17.298 + item = (DLGITEMTEMPLATE *)data; 17.299 + item->x = 80; 17.300 + item->y = y; 17.301 + item->cx = 50; 17.302 + item->cy = 14; 17.303 + item->id = IDCANCEL; // OK button identifier 17.304 + item->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON; 17.305 + 17.306 + data = (uint16_t *)(item + 1); 17.307 + *data++ = 0xFFFF; 17.308 + *data++ = 0x0080; // button class 17.309 + 17.310 + data += MultiByteToWideChar(CP_ACP, 0, "Cancel", -1, data, 50); 17.311 + *data++ = 0; // no creation data 17.312 + 17.313 + dlg->cy = y + 20; 17.314 + 17.315 + config_device = device; 17.316 + 17.317 + DialogBoxIndirect(hinstance, dlg, hwnd, deviceconfig_dlgproc); 17.318 + 17.319 + free(data); 17.320 +}
18.1 --- a/src/win.h Tue Jun 24 21:15:42 2014 +0100 18.2 +++ b/src/win.h Mon Jun 30 21:31:28 2014 +0100 18.3 @@ -24,6 +24,8 @@ 18.4 18.5 void config_open(HWND hwnd); 18.6 18.7 +void deviceconfig_open(HWND hwnd, struct device_t *device); 18.8 + 18.9 extern char openfilestring[260]; 18.10 18.11 int getfile(HWND hwnd, char *f, char *fn);
