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.
This commit is contained in:
parent
3c8a675d01
commit
2207f704dd
18 changed files with 1061 additions and 123 deletions
|
|
@ -19,7 +19,7 @@ OBJ = 386.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl.o \
|
||||||
vid_s3_virge.o vid_sdac_ramdac.o vid_stg_ramdac.o vid_svga.o vid_svga_render.o \
|
vid_s3_virge.o vid_sdac_ramdac.o vid_stg_ramdac.o vid_svga.o vid_svga_render.o \
|
||||||
vid_tandy.o vid_tgui9440.o vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o vid_vga.o \
|
vid_tandy.o vid_tgui9440.o vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o vid_vga.o \
|
||||||
vid_voodoo.o video.o wd76c10.o win.o win-config.o win-d3d.o win-d3d-fs.o win-ddraw.o \
|
vid_voodoo.o video.o wd76c10.o win.o win-config.o win-d3d.o win-d3d-fs.o win-ddraw.o \
|
||||||
win-ddraw-fs.o win-hdconf.o win-joystick.o win-keyboard.o win-midi.o win-mouse.o \
|
win-ddraw-fs.o win-deviceconfig.o win-hdconf.o win-joystick.o win-keyboard.o win-midi.o win-mouse.o \
|
||||||
win-status.o win-video.o x86seg.o x87.o xtide.o pc.res
|
win-status.o win-video.o x86seg.o x87.o xtide.o pc.res
|
||||||
FMOBJ = dbopl.o
|
FMOBJ = dbopl.o
|
||||||
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
|
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
|
||||||
|
|
|
||||||
421
src/config.c
421
src/config.c
|
|
@ -1,9 +1,194 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
static char config_file[256];
|
static char config_file[256];
|
||||||
|
|
||||||
|
typedef struct list_t
|
||||||
|
{
|
||||||
|
struct list_t *next;
|
||||||
|
} list_t;
|
||||||
|
|
||||||
|
static list_t config_head;
|
||||||
|
|
||||||
|
typedef struct section_t
|
||||||
|
{
|
||||||
|
struct list_t list;
|
||||||
|
|
||||||
|
char name[256];
|
||||||
|
|
||||||
|
struct list_t entry_head;
|
||||||
|
} section_t;
|
||||||
|
|
||||||
|
typedef struct entry_t
|
||||||
|
{
|
||||||
|
struct list_t list;
|
||||||
|
|
||||||
|
char name[256];
|
||||||
|
char data[256];
|
||||||
|
} entry_t;
|
||||||
|
|
||||||
|
#define list_add(new, head) \
|
||||||
|
{ \
|
||||||
|
struct list_t *next = head; \
|
||||||
|
\
|
||||||
|
while (next->next) \
|
||||||
|
next = next->next; \
|
||||||
|
\
|
||||||
|
(next)->next = new; \
|
||||||
|
(new)->next = NULL; \
|
||||||
|
}
|
||||||
|
|
||||||
|
void config_dump()
|
||||||
|
{
|
||||||
|
section_t *current_section;
|
||||||
|
|
||||||
|
pclog("Config data :\n");
|
||||||
|
|
||||||
|
current_section = (section_t *)config_head.next;
|
||||||
|
|
||||||
|
while (current_section)
|
||||||
|
{
|
||||||
|
entry_t *current_entry;
|
||||||
|
|
||||||
|
pclog("[%s]\n", current_section->name);
|
||||||
|
|
||||||
|
current_entry = (entry_t *)current_section->entry_head.next;
|
||||||
|
|
||||||
|
while (current_entry)
|
||||||
|
{
|
||||||
|
pclog("%s = %s\n", current_entry->name, current_entry->data);
|
||||||
|
|
||||||
|
current_entry = (entry_t *)current_entry->list.next;
|
||||||
|
}
|
||||||
|
|
||||||
|
current_section = (section_t *)current_section->list.next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void config_free()
|
||||||
|
{
|
||||||
|
section_t *current_section;
|
||||||
|
current_section = (section_t *)config_head.next;
|
||||||
|
|
||||||
|
while (current_section)
|
||||||
|
{
|
||||||
|
section_t *next_section = (section_t *)current_section->list.next;
|
||||||
|
entry_t *current_entry;
|
||||||
|
|
||||||
|
current_entry = (entry_t *)current_section->entry_head.next;
|
||||||
|
|
||||||
|
while (current_entry)
|
||||||
|
{
|
||||||
|
entry_t *next_entry = (entry_t *)current_entry->list.next;
|
||||||
|
|
||||||
|
free(current_entry);
|
||||||
|
current_entry = next_entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(current_section);
|
||||||
|
current_section = next_section;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void config_load()
|
||||||
|
{
|
||||||
|
FILE *f = fopen(config_file, "rt");
|
||||||
|
section_t *current_section;
|
||||||
|
|
||||||
|
memset(&config_head, 0, sizeof(list_t));
|
||||||
|
|
||||||
|
current_section = malloc(sizeof(section_t));
|
||||||
|
memset(current_section, 0, sizeof(section_t));
|
||||||
|
list_add(¤t_section->list, &config_head);
|
||||||
|
|
||||||
|
if (!f)
|
||||||
|
return;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
int c;
|
||||||
|
char buffer[256];
|
||||||
|
|
||||||
|
fgets(buffer, 255, f);
|
||||||
|
if (feof(f)) break;
|
||||||
|
|
||||||
|
c = 0;
|
||||||
|
|
||||||
|
while (buffer[c] == ' ' && buffer[c])
|
||||||
|
c++;
|
||||||
|
|
||||||
|
if (!buffer[c]) continue;
|
||||||
|
|
||||||
|
if (buffer[c] == '#') /*Comment*/
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (buffer[c] == '[') /*Section*/
|
||||||
|
{
|
||||||
|
section_t *new_section;
|
||||||
|
char name[256];
|
||||||
|
int d = 0;
|
||||||
|
|
||||||
|
c++;
|
||||||
|
while (buffer[c] != ']' && buffer[c])
|
||||||
|
name[d++] = buffer[c++];
|
||||||
|
|
||||||
|
if (buffer[c] != ']')
|
||||||
|
continue;
|
||||||
|
name[d] = 0;
|
||||||
|
|
||||||
|
new_section = malloc(sizeof(section_t));
|
||||||
|
memset(new_section, 0, sizeof(section_t));
|
||||||
|
strncpy(new_section->name, name, 256);
|
||||||
|
list_add(&new_section->list, &config_head);
|
||||||
|
|
||||||
|
current_section = new_section;
|
||||||
|
|
||||||
|
// pclog("New section : %s %p\n", name, (void *)current_section);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
entry_t *new_entry;
|
||||||
|
char name[256];
|
||||||
|
int d = 0, data_pos;
|
||||||
|
|
||||||
|
while (buffer[c] != '=' && buffer[c] != ' ' && buffer[c])
|
||||||
|
name[d++] = buffer[c++];
|
||||||
|
|
||||||
|
if (!buffer[c]) continue;
|
||||||
|
name[d] = 0;
|
||||||
|
|
||||||
|
while ((buffer[c] == '=' || buffer[c] == ' ') && buffer[c])
|
||||||
|
c++;
|
||||||
|
|
||||||
|
if (!buffer[c]) continue;
|
||||||
|
|
||||||
|
data_pos = c;
|
||||||
|
while (buffer[c])
|
||||||
|
{
|
||||||
|
if (buffer[c] == '\n')
|
||||||
|
buffer[c] = 0;
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
|
||||||
|
new_entry = malloc(sizeof(entry_t));
|
||||||
|
memset(new_entry, 0, sizeof(entry_t));
|
||||||
|
strncpy(new_entry->name, name, 256);
|
||||||
|
strncpy(new_entry->data, &buffer[data_pos], 256);
|
||||||
|
list_add(&new_entry->list, ¤t_section->entry_head);
|
||||||
|
|
||||||
|
// pclog("New data under section [%s] : %s = %s\n", current_section->name, new_entry->name, new_entry->data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
config_dump();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void set_config_file(char *s)
|
void set_config_file(char *s)
|
||||||
{
|
{
|
||||||
strcpy(config_file, s);
|
strcpy(config_file, s);
|
||||||
|
|
@ -15,132 +200,139 @@ void config_new()
|
||||||
fclose(f);
|
fclose(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
int get_config_int(char *head, char *name, int def)
|
static section_t *find_section(char *name)
|
||||||
{
|
{
|
||||||
char buffer[256];
|
section_t *current_section;
|
||||||
char name2[256];
|
char blank[] = "";
|
||||||
FILE *f = fopen(config_file, "rt");
|
|
||||||
int c, d;
|
|
||||||
int res = def;
|
|
||||||
|
|
||||||
if (!f)
|
current_section = (section_t *)config_head.next;
|
||||||
return def;
|
if (!name)
|
||||||
|
name = blank;
|
||||||
|
|
||||||
// pclog("Searching for %s\n", name);
|
while (current_section)
|
||||||
|
|
||||||
while (1)
|
|
||||||
{
|
{
|
||||||
fgets(buffer, 255, f);
|
if (!strncmp(current_section->name, name, 256))
|
||||||
if (feof(f)) break;
|
return current_section;
|
||||||
|
|
||||||
c = d = 0;
|
current_section = (section_t *)current_section->list.next;
|
||||||
|
|
||||||
while (buffer[c] == ' ' && buffer[c])
|
|
||||||
c++;
|
|
||||||
|
|
||||||
if (!buffer[c]) continue;
|
|
||||||
|
|
||||||
while (buffer[c] != '=' && buffer[c] != ' ' && buffer[c])
|
|
||||||
name2[d++] = buffer[c++];
|
|
||||||
|
|
||||||
if (!buffer[c]) continue;
|
|
||||||
name2[d] = 0;
|
|
||||||
|
|
||||||
// pclog("Comparing %s and %s\n", name, name2);
|
|
||||||
if (strcmp(name, name2)) continue;
|
|
||||||
// pclog("Found!\n");
|
|
||||||
|
|
||||||
while ((buffer[c] == '=' || buffer[c] == ' ') && buffer[c])
|
|
||||||
c++;
|
|
||||||
|
|
||||||
if (!buffer[c]) continue;
|
|
||||||
|
|
||||||
sscanf(&buffer[c], "%i", &res);
|
|
||||||
// pclog("Reading value - %i\n", res);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
return NULL;
|
||||||
fclose(f);
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char config_return_string[256];
|
static entry_t *find_entry(section_t *section, char *name)
|
||||||
|
{
|
||||||
|
entry_t *current_entry;
|
||||||
|
|
||||||
|
current_entry = (entry_t *)section->entry_head.next;
|
||||||
|
|
||||||
|
while (current_entry)
|
||||||
|
{
|
||||||
|
if (!strncmp(current_entry->name, name, 256))
|
||||||
|
return current_entry;
|
||||||
|
|
||||||
|
current_entry = (entry_t *)current_entry->list.next;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static section_t *create_section(char *name)
|
||||||
|
{
|
||||||
|
section_t *new_section = malloc(sizeof(section_t));
|
||||||
|
|
||||||
|
memset(new_section, 0, sizeof(section_t));
|
||||||
|
strncpy(new_section->name, name, 256);
|
||||||
|
list_add(&new_section->list, &config_head);
|
||||||
|
|
||||||
|
return new_section;
|
||||||
|
}
|
||||||
|
|
||||||
|
static entry_t *create_entry(section_t *section, char *name)
|
||||||
|
{
|
||||||
|
entry_t *new_entry = malloc(sizeof(entry_t));
|
||||||
|
memset(new_entry, 0, sizeof(entry_t));
|
||||||
|
strncpy(new_entry->name, name, 256);
|
||||||
|
list_add(&new_entry->list, §ion->entry_head);
|
||||||
|
|
||||||
|
return new_entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
int get_config_int(char *head, char *name, int def)
|
||||||
|
{
|
||||||
|
section_t *section;
|
||||||
|
entry_t *entry;
|
||||||
|
int value;
|
||||||
|
|
||||||
|
section = find_section(head);
|
||||||
|
|
||||||
|
if (!section)
|
||||||
|
return def;
|
||||||
|
|
||||||
|
entry = find_entry(section, name);
|
||||||
|
|
||||||
|
if (!entry)
|
||||||
|
return def;
|
||||||
|
|
||||||
|
sscanf(entry->data, "%i", &value);
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
char *get_config_string(char *head, char *name, char *def)
|
char *get_config_string(char *head, char *name, char *def)
|
||||||
{
|
{
|
||||||
char buffer[256];
|
section_t *section;
|
||||||
char name2[256];
|
entry_t *entry;
|
||||||
FILE *f = fopen(config_file, "rt");
|
int value;
|
||||||
int c, d;
|
|
||||||
|
|
||||||
strcpy(config_return_string, def);
|
section = find_section(head);
|
||||||
|
|
||||||
if (!f)
|
if (!section)
|
||||||
return config_return_string;
|
return def;
|
||||||
|
|
||||||
// pclog("Searching for %s\n", name);
|
entry = find_entry(section, name);
|
||||||
|
|
||||||
while (1)
|
if (!entry)
|
||||||
{
|
return def;
|
||||||
fgets(buffer, 255, f);
|
|
||||||
if (feof(f)) break;
|
|
||||||
|
|
||||||
c = d = 0;
|
return entry->data;
|
||||||
|
|
||||||
while (buffer[c] == ' ' && buffer[c])
|
|
||||||
c++;
|
|
||||||
|
|
||||||
if (!buffer[c]) continue;
|
|
||||||
|
|
||||||
while (buffer[c] != '=' && buffer[c] != ' ' && buffer[c])
|
|
||||||
name2[d++] = buffer[c++];
|
|
||||||
|
|
||||||
if (!buffer[c]) continue;
|
|
||||||
name2[d] = 0;
|
|
||||||
|
|
||||||
// pclog("Comparing %s and %s\n", name, name2);
|
|
||||||
if (strcmp(name, name2)) continue;
|
|
||||||
// pclog("Found!\n");
|
|
||||||
|
|
||||||
while ((buffer[c] == '=' || buffer[c] == ' ') && buffer[c])
|
|
||||||
c++;
|
|
||||||
|
|
||||||
if (!buffer[c]) continue;
|
|
||||||
|
|
||||||
strcpy(config_return_string, &buffer[c]);
|
|
||||||
|
|
||||||
c = strlen(config_return_string) - 1;
|
|
||||||
// pclog("string len %i\n", c);
|
|
||||||
while (config_return_string[c] <= 32 && config_return_string[c])
|
|
||||||
config_return_string[c--] = 0;
|
|
||||||
|
|
||||||
// pclog("Reading value - %s\n", config_return_string);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(f);
|
|
||||||
return config_return_string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_config_int(char *head, char *name, int val)
|
void set_config_int(char *head, char *name, int val)
|
||||||
{
|
{
|
||||||
FILE *f = fopen(config_file, "at");
|
section_t *section;
|
||||||
// if (!f) pclog("set_config_int - !f\n");
|
entry_t *entry;
|
||||||
fprintf(f, "%s = %i\n", name, val);
|
|
||||||
// pclog("Write %s = %i\n", name, val);
|
section = find_section(head);
|
||||||
fclose(f);
|
|
||||||
// pclog("fclose\n");
|
if (!section)
|
||||||
|
section = create_section(head);
|
||||||
|
|
||||||
|
entry = find_entry(section, name);
|
||||||
|
|
||||||
|
if (!entry)
|
||||||
|
entry = create_entry(section, name);
|
||||||
|
|
||||||
|
sprintf(entry->data, "%i", val);
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_config_string(char *head, char *name, char *val)
|
void set_config_string(char *head, char *name, char *val)
|
||||||
{
|
{
|
||||||
FILE *f = fopen(config_file, "at");
|
section_t *section;
|
||||||
// if (!f) pclog("set_config_string - !f\n");
|
entry_t *entry;
|
||||||
fprintf(f, "%s = %s\n", name, val);
|
|
||||||
// pclog("Write %s = %s\n", name, val);
|
section = find_section(head);
|
||||||
fclose(f);
|
|
||||||
|
if (!section)
|
||||||
|
section = create_section(head);
|
||||||
|
|
||||||
|
entry = find_entry(section, name);
|
||||||
|
|
||||||
|
if (!entry)
|
||||||
|
entry = create_entry(section, name);
|
||||||
|
|
||||||
|
strncpy(entry->data, val, 256);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
char *get_filename(char *s)
|
char *get_filename(char *s)
|
||||||
{
|
{
|
||||||
int c = strlen(s) - 1;
|
int c = strlen(s) - 1;
|
||||||
|
|
@ -164,3 +356,32 @@ void put_backslash(char *s)
|
||||||
if (s[c] != '/' && s[c] != '\\')
|
if (s[c] != '/' && s[c] != '\\')
|
||||||
s[c] = '/';
|
s[c] = '/';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void config_save()
|
||||||
|
{
|
||||||
|
FILE *f = fopen(config_file, "wt");
|
||||||
|
section_t *current_section;
|
||||||
|
|
||||||
|
current_section = (section_t *)config_head.next;
|
||||||
|
|
||||||
|
while (current_section)
|
||||||
|
{
|
||||||
|
entry_t *current_entry;
|
||||||
|
|
||||||
|
if (current_section->name[0])
|
||||||
|
fprintf(f, "\n[%s]\n", current_section->name);
|
||||||
|
|
||||||
|
current_entry = (entry_t *)current_section->entry_head.next;
|
||||||
|
|
||||||
|
while (current_entry)
|
||||||
|
{
|
||||||
|
fprintf(f, "%s = %s\n", current_entry->name, current_entry->data);
|
||||||
|
|
||||||
|
current_entry = (entry_t *)current_entry->list.next;
|
||||||
|
}
|
||||||
|
|
||||||
|
current_section = (section_t *)current_section->list.next;
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,3 +7,8 @@ void set_config_string(char *head, char *name, char *val);
|
||||||
char *get_filename(char *s);
|
char *get_filename(char *s);
|
||||||
void append_filename(char *dest, char *s1, char *s2, int size);
|
void append_filename(char *dest, char *s1, char *s2, int size);
|
||||||
void put_backslash(char *s);
|
void put_backslash(char *s);
|
||||||
|
|
||||||
|
void config_load();
|
||||||
|
void config_save();
|
||||||
|
void config_dump();
|
||||||
|
void config_free();
|
||||||
|
|
|
||||||
33
src/device.c
33
src/device.c
|
|
@ -1,9 +1,12 @@
|
||||||
#include "ibm.h"
|
#include "ibm.h"
|
||||||
|
#include "config.h"
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
|
|
||||||
static void *device_priv[256];
|
static void *device_priv[256];
|
||||||
static device_t *devices[256];
|
static device_t *devices[256];
|
||||||
|
|
||||||
|
static device_t *current_device;
|
||||||
|
|
||||||
void device_init()
|
void device_init()
|
||||||
{
|
{
|
||||||
memset(devices, 0, sizeof(devices));
|
memset(devices, 0, sizeof(devices));
|
||||||
|
|
@ -20,6 +23,8 @@ void device_add(device_t *d)
|
||||||
if (c >= 256)
|
if (c >= 256)
|
||||||
fatal("device_add : too many devices\n");
|
fatal("device_add : too many devices\n");
|
||||||
|
|
||||||
|
current_device = d;
|
||||||
|
|
||||||
priv = d->init();
|
priv = d->init();
|
||||||
if (priv == NULL)
|
if (priv == NULL)
|
||||||
fatal("device_add : device init failed\n");
|
fatal("device_add : device init failed\n");
|
||||||
|
|
@ -105,3 +110,31 @@ char *device_add_status_info(char *s, int max_len)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int device_get_config_int(char *s)
|
||||||
|
{
|
||||||
|
device_config_t *config = current_device->config;
|
||||||
|
|
||||||
|
while (config->type != -1)
|
||||||
|
{
|
||||||
|
if (!strcmp(s, config->name))
|
||||||
|
return get_config_int(current_device->name, s, config->default_int);
|
||||||
|
|
||||||
|
config++;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *device_get_config_string(char *s)
|
||||||
|
{
|
||||||
|
device_config_t *config = current_device->config;
|
||||||
|
|
||||||
|
while (config->type != -1)
|
||||||
|
{
|
||||||
|
if (!strcmp(s, config->name))
|
||||||
|
return get_config_string(current_device->name, s, config->default_string);
|
||||||
|
|
||||||
|
config++;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
|
||||||
25
src/device.h
25
src/device.h
|
|
@ -1,3 +1,24 @@
|
||||||
|
#define CONFIG_STRING 0
|
||||||
|
#define CONFIG_INT 1
|
||||||
|
#define CONFIG_BINARY 2
|
||||||
|
#define CONFIG_SELECTION 3
|
||||||
|
|
||||||
|
typedef struct device_config_selection_t
|
||||||
|
{
|
||||||
|
char description[256];
|
||||||
|
int value;
|
||||||
|
} device_config_selection_t;
|
||||||
|
|
||||||
|
typedef struct device_config_t
|
||||||
|
{
|
||||||
|
char name[256];
|
||||||
|
char description[256];
|
||||||
|
int type;
|
||||||
|
char default_string[256];
|
||||||
|
int default_int;
|
||||||
|
device_config_selection_t selection[16];
|
||||||
|
} device_config_t;
|
||||||
|
|
||||||
typedef struct device_t
|
typedef struct device_t
|
||||||
{
|
{
|
||||||
char name[50];
|
char name[50];
|
||||||
|
|
@ -8,6 +29,7 @@ typedef struct device_t
|
||||||
void (*speed_changed)(void *p);
|
void (*speed_changed)(void *p);
|
||||||
void (*force_redraw)(void *p);
|
void (*force_redraw)(void *p);
|
||||||
int (*add_status_info)(char *s, int max_len, void *p);
|
int (*add_status_info)(char *s, int max_len, void *p);
|
||||||
|
device_config_t *config;
|
||||||
} device_t;
|
} device_t;
|
||||||
|
|
||||||
void device_init();
|
void device_init();
|
||||||
|
|
@ -18,6 +40,9 @@ void device_speed_changed();
|
||||||
void device_force_redraw();
|
void device_force_redraw();
|
||||||
char *device_add_status_info(char *s, int max_len);
|
char *device_add_status_info(char *s, int max_len);
|
||||||
|
|
||||||
|
int device_get_config_int(char *name);
|
||||||
|
char *device_get_config_string(char *name);
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
DEVICE_NOT_WORKING = 1 /*Device does not currently work correctly and will be disabled in a release build*/
|
DEVICE_NOT_WORKING = 1 /*Device does not currently work correctly and will be disabled in a release build*/
|
||||||
|
|
|
||||||
6
src/pc.c
6
src/pc.c
|
|
@ -426,6 +426,9 @@ void loadconfig()
|
||||||
char *p;
|
char *p;
|
||||||
append_filename(s, pcempath, "pcem.cfg", 511);
|
append_filename(s, pcempath, "pcem.cfg", 511);
|
||||||
set_config_file(s);
|
set_config_file(s);
|
||||||
|
|
||||||
|
config_load();
|
||||||
|
|
||||||
GAMEBLASTER = get_config_int(NULL, "gameblaster", 0);
|
GAMEBLASTER = get_config_int(NULL, "gameblaster", 0);
|
||||||
GUS = get_config_int(NULL, "gus", 0);
|
GUS = get_config_int(NULL, "gus", 0);
|
||||||
SSI2001 = get_config_int(NULL, "ssi2001", 0);
|
SSI2001 = get_config_int(NULL, "ssi2001", 0);
|
||||||
|
|
@ -480,7 +483,6 @@ void loadconfig()
|
||||||
|
|
||||||
void saveconfig()
|
void saveconfig()
|
||||||
{
|
{
|
||||||
config_new();
|
|
||||||
set_config_int(NULL, "gameblaster", GAMEBLASTER);
|
set_config_int(NULL, "gameblaster", GAMEBLASTER);
|
||||||
set_config_int(NULL, "gus", GUS);
|
set_config_int(NULL, "gus", GUS);
|
||||||
set_config_int(NULL, "ssi2001", SSI2001);
|
set_config_int(NULL, "ssi2001", SSI2001);
|
||||||
|
|
@ -515,4 +517,6 @@ void saveconfig()
|
||||||
set_config_int(NULL, "hdd_heads", hdc[1].hpc);
|
set_config_int(NULL, "hdd_heads", hdc[1].hpc);
|
||||||
set_config_int(NULL, "hdd_cylinders", hdc[1].tracks);
|
set_config_int(NULL, "hdd_cylinders", hdc[1].tracks);
|
||||||
set_config_string(NULL, "hdd_fn", ide_fn[1]);
|
set_config_string(NULL, "hdd_fn", ide_fn[1]);
|
||||||
|
|
||||||
|
config_save();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ BEGIN
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
|
|
||||||
ConfigureDlg DIALOGEX 0, 0, 232, 256
|
ConfigureDlg DIALOGEX 0, 0, 232+40, 256
|
||||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||||
CAPTION "Configure PCem"
|
CAPTION "Configure PCem"
|
||||||
FONT 8, "MS Sans Serif"
|
FONT 8, "MS Sans Serif"
|
||||||
|
|
@ -56,11 +56,13 @@ BEGIN
|
||||||
PUSHBUTTON "Cancel",IDCANCEL,128,232,50,14, WS_TABSTOP
|
PUSHBUTTON "Cancel",IDCANCEL,128,232,50,14, WS_TABSTOP
|
||||||
COMBOBOX IDC_COMBO1,62,16,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
|
COMBOBOX IDC_COMBO1,62,16,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
|
||||||
COMBOBOX IDC_COMBOVID,62,36,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
|
COMBOBOX IDC_COMBOVID,62,36,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
|
||||||
|
PUSHBUTTON "Configure", IDC_CONFIGUREVID, 224, 36, 40, 14, WS_TABSTOP
|
||||||
COMBOBOX IDC_COMBOCPUM,62,56,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
|
COMBOBOX IDC_COMBOCPUM,62,56,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
|
||||||
COMBOBOX IDC_COMBO3,62,76,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
|
COMBOBOX IDC_COMBO3,62,76,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
|
||||||
COMBOBOX IDC_COMBOCHC,62,96,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
|
COMBOBOX IDC_COMBOCHC,62,96,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
|
||||||
COMBOBOX IDC_COMBOSPD,62,116,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
|
COMBOBOX IDC_COMBOSPD,62,116,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
|
||||||
COMBOBOX IDC_COMBOSND,62,136,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
|
COMBOBOX IDC_COMBOSND,62,136,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
|
||||||
|
PUSHBUTTON "Configure", IDC_CONFIGURESND, 224, 136, 40, 14, WS_TABSTOP
|
||||||
EDITTEXT IDC_MEMTEXT, 62, 152, 36, 14, ES_AUTOHSCROLL | ES_NUMBER
|
EDITTEXT IDC_MEMTEXT, 62, 152, 36, 14, ES_AUTOHSCROLL | ES_NUMBER
|
||||||
CONTROL "", IDC_MEMSPIN, UPDOWN_CLASS, UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS | UDS_SETBUDDYINT, 98, 152, 12, 14
|
CONTROL "", IDC_MEMSPIN, UPDOWN_CLASS, UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS | UDS_SETBUDDYINT, 98, 152, 12, 14
|
||||||
LTEXT "MB", IDC_STATIC, 98, 152, 40, 10
|
LTEXT "MB", IDC_STATIC, 98, 152, 40, 10
|
||||||
|
|
|
||||||
12
src/pic.c
12
src/pic.c
|
|
@ -244,6 +244,8 @@ int pic_current[16];
|
||||||
|
|
||||||
void picint(uint16_t num)
|
void picint(uint16_t num)
|
||||||
{
|
{
|
||||||
|
if (AT && num == (1 << 2))
|
||||||
|
num = 1 << 9;
|
||||||
// pclog("picint : %04X\n", num);
|
// pclog("picint : %04X\n", num);
|
||||||
// if (num == 0x10) pclog("PICINT 10\n");
|
// if (num == 0x10) pclog("PICINT 10\n");
|
||||||
if (num>0xFF)
|
if (num>0xFF)
|
||||||
|
|
@ -264,6 +266,11 @@ void picintlevel(uint16_t num)
|
||||||
{
|
{
|
||||||
int c = 0;
|
int c = 0;
|
||||||
while (!(num & (1 << c))) c++;
|
while (!(num & (1 << c))) c++;
|
||||||
|
if (AT && c == 2)
|
||||||
|
{
|
||||||
|
c = 9;
|
||||||
|
num = 1 << 9;
|
||||||
|
}
|
||||||
// pclog("INTLEVEL %04X %i\n", num, c);
|
// pclog("INTLEVEL %04X %i\n", num, c);
|
||||||
if (!pic_current[c])
|
if (!pic_current[c])
|
||||||
{
|
{
|
||||||
|
|
@ -283,6 +290,11 @@ void picintc(uint16_t num)
|
||||||
{
|
{
|
||||||
int c = 0;
|
int c = 0;
|
||||||
while (!(num & (1 << c))) c++;
|
while (!(num & (1 << c))) c++;
|
||||||
|
if (AT && c == 2)
|
||||||
|
{
|
||||||
|
c = 9;
|
||||||
|
num = 1 << 9;
|
||||||
|
}
|
||||||
// pclog("INTC %04X %i\n", num, c);
|
// pclog("INTC %04X %i\n", num, c);
|
||||||
pic_current[c]=0;
|
pic_current[c]=0;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -77,5 +77,10 @@
|
||||||
#define IDC_EDIT_C_FN 1220
|
#define IDC_EDIT_C_FN 1220
|
||||||
#define IDC_EDIT_D_FN 1221
|
#define IDC_EDIT_D_FN 1221
|
||||||
|
|
||||||
|
#define IDC_CONFIGUREVID 1200
|
||||||
|
#define IDC_CONFIGURESND 1201
|
||||||
|
|
||||||
|
#define IDC_CONFIG_BASE 1200
|
||||||
|
|
||||||
#define WM_RESETD3D WM_USER
|
#define WM_RESETD3D WM_USER
|
||||||
#define WM_LEAVEFULLSCREEN WM_USER + 1
|
#define WM_LEAVEFULLSCREEN WM_USER + 1
|
||||||
|
|
|
||||||
10
src/sound.c
10
src/sound.c
|
|
@ -56,6 +56,16 @@ char *sound_card_getname(int card)
|
||||||
return sound_cards[card].name;
|
return sound_cards[card].name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
device_t *sound_card_getdevice(int card)
|
||||||
|
{
|
||||||
|
return sound_cards[card].device;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sound_card_has_config(int card)
|
||||||
|
{
|
||||||
|
return sound_cards[card].device->config ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
void sound_card_init()
|
void sound_card_init()
|
||||||
{
|
{
|
||||||
if (sound_cards[sound_card_current].device)
|
if (sound_cards[sound_card_current].device)
|
||||||
|
|
|
||||||
|
|
@ -7,4 +7,6 @@ extern int sound_card_current;
|
||||||
|
|
||||||
int sound_card_available(int card);
|
int sound_card_available(int card);
|
||||||
char *sound_card_getname(int card);
|
char *sound_card_getname(int card);
|
||||||
|
struct device_t *sound_card_getdevice(int card);
|
||||||
|
int sound_card_has_config(int card);
|
||||||
void sound_card_init();
|
void sound_card_init();
|
||||||
|
|
|
||||||
212
src/sound_sb.c
212
src/sound_sb.c
|
|
@ -256,13 +256,16 @@ void sb_mixer_init(sb_mixer_t *mixer)
|
||||||
void *sb_1_init()
|
void *sb_1_init()
|
||||||
{
|
{
|
||||||
sb_t *sb = malloc(sizeof(sb_t));
|
sb_t *sb = malloc(sizeof(sb_t));
|
||||||
|
uint16_t addr = device_get_config_int("addr");
|
||||||
memset(sb, 0, sizeof(sb_t));
|
memset(sb, 0, sizeof(sb_t));
|
||||||
|
|
||||||
opl2_init(&sb->opl);
|
opl2_init(&sb->opl);
|
||||||
sb_dsp_init(&sb->dsp, SB1);
|
sb_dsp_init(&sb->dsp, SB1);
|
||||||
sb_dsp_setaddr(&sb->dsp, 0x0220);
|
sb_dsp_setaddr(&sb->dsp, addr);
|
||||||
|
sb_dsp_setirq(&sb->dsp, device_get_config_int("irq"));
|
||||||
|
sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma"));
|
||||||
sb_mixer_init(&sb->mixer);
|
sb_mixer_init(&sb->mixer);
|
||||||
io_sethandler(0x0228, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl);
|
io_sethandler(addr+8, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl);
|
||||||
io_sethandler(0x0388, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl);
|
io_sethandler(0x0388, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl);
|
||||||
sound_add_handler(sb_opl2_poll, sb_get_buffer, sb);
|
sound_add_handler(sb_opl2_poll, sb_get_buffer, sb);
|
||||||
return sb;
|
return sb;
|
||||||
|
|
@ -270,13 +273,16 @@ void *sb_1_init()
|
||||||
void *sb_15_init()
|
void *sb_15_init()
|
||||||
{
|
{
|
||||||
sb_t *sb = malloc(sizeof(sb_t));
|
sb_t *sb = malloc(sizeof(sb_t));
|
||||||
|
uint16_t addr = device_get_config_int("addr");
|
||||||
memset(sb, 0, sizeof(sb_t));
|
memset(sb, 0, sizeof(sb_t));
|
||||||
|
|
||||||
opl2_init(&sb->opl);
|
opl2_init(&sb->opl);
|
||||||
sb_dsp_init(&sb->dsp, SB15);
|
sb_dsp_init(&sb->dsp, SB15);
|
||||||
sb_dsp_setaddr(&sb->dsp, 0x0220);
|
sb_dsp_setaddr(&sb->dsp, addr);
|
||||||
|
sb_dsp_setirq(&sb->dsp, device_get_config_int("irq"));
|
||||||
|
sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma"));
|
||||||
sb_mixer_init(&sb->mixer);
|
sb_mixer_init(&sb->mixer);
|
||||||
io_sethandler(0x0228, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl);
|
io_sethandler(addr+8, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl);
|
||||||
io_sethandler(0x0388, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl);
|
io_sethandler(0x0388, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl);
|
||||||
sound_add_handler(sb_opl2_poll, sb_get_buffer, sb);
|
sound_add_handler(sb_opl2_poll, sb_get_buffer, sb);
|
||||||
return sb;
|
return sb;
|
||||||
|
|
@ -284,13 +290,16 @@ void *sb_15_init()
|
||||||
void *sb_2_init()
|
void *sb_2_init()
|
||||||
{
|
{
|
||||||
sb_t *sb = malloc(sizeof(sb_t));
|
sb_t *sb = malloc(sizeof(sb_t));
|
||||||
|
uint16_t addr = device_get_config_int("addr");
|
||||||
memset(sb, 0, sizeof(sb_t));
|
memset(sb, 0, sizeof(sb_t));
|
||||||
|
|
||||||
opl2_init(&sb->opl);
|
opl2_init(&sb->opl);
|
||||||
sb_dsp_init(&sb->dsp, SB2);
|
sb_dsp_init(&sb->dsp, SB2);
|
||||||
sb_dsp_setaddr(&sb->dsp, 0x0220);
|
sb_dsp_setaddr(&sb->dsp, addr);
|
||||||
|
sb_dsp_setirq(&sb->dsp, device_get_config_int("irq"));
|
||||||
|
sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma"));
|
||||||
sb_mixer_init(&sb->mixer);
|
sb_mixer_init(&sb->mixer);
|
||||||
io_sethandler(0x0228, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl);
|
io_sethandler(addr+8, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl);
|
||||||
io_sethandler(0x0388, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl);
|
io_sethandler(0x0388, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl);
|
||||||
sound_add_handler(sb_opl2_poll, sb_get_buffer, sb);
|
sound_add_handler(sb_opl2_poll, sb_get_buffer, sb);
|
||||||
return sb;
|
return sb;
|
||||||
|
|
@ -299,17 +308,20 @@ void *sb_2_init()
|
||||||
void *sb_pro_v1_init()
|
void *sb_pro_v1_init()
|
||||||
{
|
{
|
||||||
sb_t *sb = malloc(sizeof(sb_t));
|
sb_t *sb = malloc(sizeof(sb_t));
|
||||||
|
uint16_t addr = device_get_config_int("addr");
|
||||||
memset(sb, 0, sizeof(sb_t));
|
memset(sb, 0, sizeof(sb_t));
|
||||||
|
|
||||||
opl2_init(&sb->opl);
|
opl2_init(&sb->opl);
|
||||||
sb_dsp_init(&sb->dsp, SBPRO);
|
sb_dsp_init(&sb->dsp, SBPRO);
|
||||||
sb_dsp_setaddr(&sb->dsp, 0x0220);
|
sb_dsp_setaddr(&sb->dsp, addr);
|
||||||
|
sb_dsp_setirq(&sb->dsp, device_get_config_int("irq"));
|
||||||
|
sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma"));
|
||||||
sb_mixer_init(&sb->mixer);
|
sb_mixer_init(&sb->mixer);
|
||||||
io_sethandler(0x0220, 0x0002, opl2_l_read, NULL, NULL, opl2_l_write, NULL, NULL, &sb->opl);
|
io_sethandler(addr+0, 0x0002, opl2_l_read, NULL, NULL, opl2_l_write, NULL, NULL, &sb->opl);
|
||||||
io_sethandler(0x0222, 0x0002, opl2_r_read, NULL, NULL, opl2_r_write, NULL, NULL, &sb->opl);
|
io_sethandler(addr+2, 0x0002, opl2_r_read, NULL, NULL, opl2_r_write, NULL, NULL, &sb->opl);
|
||||||
io_sethandler(0x0228, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl);
|
io_sethandler(addr+8, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl);
|
||||||
io_sethandler(0x0388, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl);
|
io_sethandler(0x0388, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl);
|
||||||
io_sethandler(0x0224, 0x0002, sb_pro_mixer_read, NULL, NULL, sb_pro_mixer_write, NULL, NULL, sb);
|
io_sethandler(addr+4, 0x0002, sb_pro_mixer_read, NULL, NULL, sb_pro_mixer_write, NULL, NULL, sb);
|
||||||
sound_add_handler(sb_opl2_poll, sb_get_buffer, sb);
|
sound_add_handler(sb_opl2_poll, sb_get_buffer, sb);
|
||||||
|
|
||||||
sb->mixer.regs[0x22] = 0xff;
|
sb->mixer.regs[0x22] = 0xff;
|
||||||
|
|
@ -323,16 +335,19 @@ void *sb_pro_v1_init()
|
||||||
void *sb_pro_v2_init()
|
void *sb_pro_v2_init()
|
||||||
{
|
{
|
||||||
sb_t *sb = malloc(sizeof(sb_t));
|
sb_t *sb = malloc(sizeof(sb_t));
|
||||||
|
uint16_t addr = device_get_config_int("addr");
|
||||||
memset(sb, 0, sizeof(sb_t));
|
memset(sb, 0, sizeof(sb_t));
|
||||||
|
|
||||||
opl3_init(&sb->opl);
|
opl3_init(&sb->opl);
|
||||||
sb_dsp_init(&sb->dsp, SBPRO2);
|
sb_dsp_init(&sb->dsp, SBPRO2);
|
||||||
sb_dsp_setaddr(&sb->dsp, 0x0220);
|
sb_dsp_setaddr(&sb->dsp, addr);
|
||||||
|
sb_dsp_setirq(&sb->dsp, device_get_config_int("irq"));
|
||||||
|
sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma"));
|
||||||
sb_mixer_init(&sb->mixer);
|
sb_mixer_init(&sb->mixer);
|
||||||
io_sethandler(0x0220, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl);
|
io_sethandler(addr+0, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl);
|
||||||
io_sethandler(0x0228, 0x0002, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl);
|
io_sethandler(addr+8, 0x0002, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl);
|
||||||
io_sethandler(0x0388, 0x0002, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl);
|
io_sethandler(0x0388, 0x0002, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl);
|
||||||
io_sethandler(0x0224, 0x0002, sb_pro_mixer_read, NULL, NULL, sb_pro_mixer_write, NULL, NULL, sb);
|
io_sethandler(addr+4, 0x0002, sb_pro_mixer_read, NULL, NULL, sb_pro_mixer_write, NULL, NULL, sb);
|
||||||
sound_add_handler(sb_opl3_poll, sb_get_buffer, sb);
|
sound_add_handler(sb_opl3_poll, sb_get_buffer, sb);
|
||||||
|
|
||||||
sb->mixer.regs[0x22] = 0xff;
|
sb->mixer.regs[0x22] = 0xff;
|
||||||
|
|
@ -436,6 +451,158 @@ int sb_add_status_info(char *s, int max_len, void *p)
|
||||||
sb_dsp_add_status_info(s, max_len, &sb->dsp);
|
sb_dsp_add_status_info(s, max_len, &sb->dsp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static device_config_t sb_config[] =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
.name = "addr",
|
||||||
|
.description = "Address",
|
||||||
|
.type = CONFIG_BINARY,
|
||||||
|
.type = CONFIG_SELECTION,
|
||||||
|
.selection =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
.description = "0x220",
|
||||||
|
.value = 0x220
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.description = "0x240",
|
||||||
|
.value = 0x240
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.description = ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
.default_int = 0x220
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "irq",
|
||||||
|
.description = "IRQ",
|
||||||
|
.type = CONFIG_SELECTION,
|
||||||
|
.selection =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
.description = "IRQ 2",
|
||||||
|
.value = 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.description = "IRQ 3",
|
||||||
|
.value = 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.description = "IRQ 5",
|
||||||
|
.value = 5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.description = "IRQ 7",
|
||||||
|
.value = 7
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.description = ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
.default_int = 7
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "dma",
|
||||||
|
.description = "DMA",
|
||||||
|
.type = CONFIG_SELECTION,
|
||||||
|
.selection =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
.description = "DMA 1",
|
||||||
|
.value = 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.description = "DMA 3",
|
||||||
|
.value = 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.description = ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
.default_int = 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.type = -1
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static device_config_t sb_pro_config[] =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
.name = "addr",
|
||||||
|
.description = "Address",
|
||||||
|
.type = CONFIG_BINARY,
|
||||||
|
.type = CONFIG_SELECTION,
|
||||||
|
.selection =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
.description = "0x220",
|
||||||
|
.value = 0x220
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.description = "0x240",
|
||||||
|
.value = 0x240
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.description = ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
.default_int = 0x220
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "irq",
|
||||||
|
.description = "IRQ",
|
||||||
|
.type = CONFIG_SELECTION,
|
||||||
|
.selection =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
.description = "IRQ 2",
|
||||||
|
.value = 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.description = "IRQ 5",
|
||||||
|
.value = 5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.description = "IRQ 7",
|
||||||
|
.value = 7
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.description = "IRQ 10",
|
||||||
|
.value = 10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.description = ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
.default_int = 7
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "dma",
|
||||||
|
.description = "DMA",
|
||||||
|
.type = CONFIG_SELECTION,
|
||||||
|
.selection =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
.description = "DMA 1",
|
||||||
|
.value = 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.description = "DMA 3",
|
||||||
|
.value = 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.description = ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
.default_int = 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.type = -1
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
device_t sb_1_device =
|
device_t sb_1_device =
|
||||||
{
|
{
|
||||||
"Sound Blaster v1.0",
|
"Sound Blaster v1.0",
|
||||||
|
|
@ -445,7 +612,8 @@ device_t sb_1_device =
|
||||||
NULL,
|
NULL,
|
||||||
sb_speed_changed,
|
sb_speed_changed,
|
||||||
NULL,
|
NULL,
|
||||||
sb_add_status_info
|
sb_add_status_info,
|
||||||
|
sb_config
|
||||||
};
|
};
|
||||||
device_t sb_15_device =
|
device_t sb_15_device =
|
||||||
{
|
{
|
||||||
|
|
@ -456,7 +624,8 @@ device_t sb_15_device =
|
||||||
NULL,
|
NULL,
|
||||||
sb_speed_changed,
|
sb_speed_changed,
|
||||||
NULL,
|
NULL,
|
||||||
sb_add_status_info
|
sb_add_status_info,
|
||||||
|
sb_config
|
||||||
};
|
};
|
||||||
device_t sb_2_device =
|
device_t sb_2_device =
|
||||||
{
|
{
|
||||||
|
|
@ -467,7 +636,8 @@ device_t sb_2_device =
|
||||||
NULL,
|
NULL,
|
||||||
sb_speed_changed,
|
sb_speed_changed,
|
||||||
NULL,
|
NULL,
|
||||||
sb_add_status_info
|
sb_add_status_info,
|
||||||
|
sb_config
|
||||||
};
|
};
|
||||||
device_t sb_pro_v1_device =
|
device_t sb_pro_v1_device =
|
||||||
{
|
{
|
||||||
|
|
@ -478,7 +648,8 @@ device_t sb_pro_v1_device =
|
||||||
NULL,
|
NULL,
|
||||||
sb_speed_changed,
|
sb_speed_changed,
|
||||||
NULL,
|
NULL,
|
||||||
sb_add_status_info
|
sb_add_status_info,
|
||||||
|
sb_pro_config
|
||||||
};
|
};
|
||||||
device_t sb_pro_v2_device =
|
device_t sb_pro_v2_device =
|
||||||
{
|
{
|
||||||
|
|
@ -489,7 +660,8 @@ device_t sb_pro_v2_device =
|
||||||
NULL,
|
NULL,
|
||||||
sb_speed_changed,
|
sb_speed_changed,
|
||||||
NULL,
|
NULL,
|
||||||
sb_add_status_info
|
sb_add_status_info,
|
||||||
|
sb_pro_config
|
||||||
};
|
};
|
||||||
device_t sb_16_device =
|
device_t sb_16_device =
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,9 @@ typedef struct virge_t
|
||||||
|
|
||||||
int is_375;
|
int is_375;
|
||||||
|
|
||||||
|
int bilinear_enabled;
|
||||||
|
int memory_size;
|
||||||
|
|
||||||
int pixel_count, tri_count;
|
int pixel_count, tri_count;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
|
|
@ -2486,7 +2489,7 @@ static void s3_virge_triangle(virge_t *virge)
|
||||||
// pclog("use tex_sample_mipmap\n");
|
// pclog("use tex_sample_mipmap\n");
|
||||||
break;
|
break;
|
||||||
case 2: case 3:
|
case 2: case 3:
|
||||||
tex_sample = tex_sample_mipmap_filter;
|
tex_sample = virge->bilinear_enabled ? tex_sample_mipmap_filter : tex_sample_mipmap;
|
||||||
// pclog("use tex_sample_mipmap_filter\n");
|
// pclog("use tex_sample_mipmap_filter\n");
|
||||||
break;
|
break;
|
||||||
case 4: case 5:
|
case 4: case 5:
|
||||||
|
|
@ -2494,7 +2497,7 @@ static void s3_virge_triangle(virge_t *virge)
|
||||||
// pclog("use tex_sample_normal\n");
|
// pclog("use tex_sample_normal\n");
|
||||||
break;
|
break;
|
||||||
case 6: case 7:
|
case 6: case 7:
|
||||||
tex_sample = tex_sample_normal_filter;
|
tex_sample = virge->bilinear_enabled ? tex_sample_normal_filter : tex_sample_normal;
|
||||||
// pclog("use tex_sample_normal_filter\n");
|
// pclog("use tex_sample_normal_filter\n");
|
||||||
break;
|
break;
|
||||||
case (0 | 8): case (1 | 8):
|
case (0 | 8): case (1 | 8):
|
||||||
|
|
@ -2506,9 +2509,9 @@ static void s3_virge_triangle(virge_t *virge)
|
||||||
break;
|
break;
|
||||||
case (2 | 8): case (3 | 8):
|
case (2 | 8): case (3 | 8):
|
||||||
if (virge->is_375)
|
if (virge->is_375)
|
||||||
tex_sample = tex_sample_persp_mipmap_filter_375;
|
tex_sample = virge->bilinear_enabled ? tex_sample_persp_mipmap_filter_375 : tex_sample_persp_mipmap_375;
|
||||||
else
|
else
|
||||||
tex_sample = tex_sample_persp_mipmap_filter;
|
tex_sample = virge->bilinear_enabled ? tex_sample_persp_mipmap_filter : tex_sample_persp_mipmap;
|
||||||
// pclog("use tex_sample_persp_mipmap_filter\n");
|
// pclog("use tex_sample_persp_mipmap_filter\n");
|
||||||
break;
|
break;
|
||||||
case (4 | 8): case (5 | 8):
|
case (4 | 8): case (5 | 8):
|
||||||
|
|
@ -2520,9 +2523,9 @@ static void s3_virge_triangle(virge_t *virge)
|
||||||
break;
|
break;
|
||||||
case (6 | 8): case (7 | 8):
|
case (6 | 8): case (7 | 8):
|
||||||
if (virge->is_375)
|
if (virge->is_375)
|
||||||
tex_sample = tex_sample_persp_normal_filter_375;
|
tex_sample = virge->bilinear_enabled ? tex_sample_persp_normal_filter_375 : tex_sample_persp_normal_375;
|
||||||
else
|
else
|
||||||
tex_sample = tex_sample_persp_normal_filter;
|
tex_sample = virge->bilinear_enabled ? tex_sample_persp_normal_filter : tex_sample_persp_normal;
|
||||||
// pclog("use tex_sample_persp_normal_filter\n");
|
// pclog("use tex_sample_persp_normal_filter\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -2975,7 +2978,11 @@ static void *s3_virge_init()
|
||||||
virge_t *virge = malloc(sizeof(virge_t));
|
virge_t *virge = malloc(sizeof(virge_t));
|
||||||
memset(virge, 0, sizeof(virge_t));
|
memset(virge, 0, sizeof(virge_t));
|
||||||
|
|
||||||
svga_init(&virge->svga, virge, 1 << 22, /*4mb*/
|
virge->bilinear_enabled = device_get_config_int("bilinear");
|
||||||
|
virge->memory_size = device_get_config_int("memory");
|
||||||
|
pclog("bilinear_enabled=%i memory_size=%i\n", virge->bilinear_enabled, virge->memory_size);
|
||||||
|
|
||||||
|
svga_init(&virge->svga, virge, virge->memory_size << 20,
|
||||||
s3_virge_recalctimings,
|
s3_virge_recalctimings,
|
||||||
s3_virge_in, s3_virge_out,
|
s3_virge_in, s3_virge_out,
|
||||||
s3_virge_hwcursor_draw,
|
s3_virge_hwcursor_draw,
|
||||||
|
|
@ -3029,7 +3036,17 @@ static void *s3_virge_init()
|
||||||
virge->virge_rev = 0;
|
virge->virge_rev = 0;
|
||||||
virge->virge_id = 0xe1;
|
virge->virge_id = 0xe1;
|
||||||
|
|
||||||
virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4);
|
switch (virge->memory_size)
|
||||||
|
{
|
||||||
|
case 2:
|
||||||
|
virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4) | (4 << 5);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
default:
|
||||||
|
virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4) | (0 << 5);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
virge->svga.crtc[0x37] = 1;// | (7 << 5);
|
virge->svga.crtc[0x37] = 1;// | (7 << 5);
|
||||||
virge->svga.crtc[0x53] = 1 << 3;
|
virge->svga.crtc[0x53] = 1 << 3;
|
||||||
virge->svga.crtc[0x59] = 0x70;
|
virge->svga.crtc[0x59] = 0x70;
|
||||||
|
|
@ -3046,7 +3063,11 @@ static void *s3_virge_375_init()
|
||||||
virge_t *virge = malloc(sizeof(virge_t));
|
virge_t *virge = malloc(sizeof(virge_t));
|
||||||
memset(virge, 0, sizeof(virge_t));
|
memset(virge, 0, sizeof(virge_t));
|
||||||
|
|
||||||
svga_init(&virge->svga, virge, 1 << 22, /*4mb*/
|
virge->bilinear_enabled = device_get_config_int("bilinear");
|
||||||
|
virge->memory_size = device_get_config_int("memory");
|
||||||
|
pclog("bilinear_enabled=%i memory_size=%i\n", virge->bilinear_enabled, virge->memory_size);
|
||||||
|
|
||||||
|
svga_init(&virge->svga, virge, virge->memory_size << 20,
|
||||||
s3_virge_recalctimings,
|
s3_virge_recalctimings,
|
||||||
s3_virge_in, s3_virge_out,
|
s3_virge_in, s3_virge_out,
|
||||||
s3_virge_hwcursor_draw,
|
s3_virge_hwcursor_draw,
|
||||||
|
|
@ -3100,7 +3121,17 @@ static void *s3_virge_375_init()
|
||||||
virge->virge_rev = 0;
|
virge->virge_rev = 0;
|
||||||
virge->virge_id = 0xe1;
|
virge->virge_id = 0xe1;
|
||||||
|
|
||||||
virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4);
|
switch (virge->memory_size)
|
||||||
|
{
|
||||||
|
case 2:
|
||||||
|
virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4) | (4 << 5);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
default:
|
||||||
|
virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4) | (0 << 5);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4);
|
||||||
virge->svga.crtc[0x37] = 1;// | (7 << 5);
|
virge->svga.crtc[0x37] = 1;// | (7 << 5);
|
||||||
virge->svga.crtc[0x53] = 1 << 3;
|
virge->svga.crtc[0x53] = 1 << 3;
|
||||||
virge->svga.crtc[0x59] = 0x70;
|
virge->svga.crtc[0x59] = 0x70;
|
||||||
|
|
@ -3174,6 +3205,39 @@ static int s3_virge_add_status_info(char *s, int max_len, void *p)
|
||||||
return max_len - cur_len;
|
return max_len - cur_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static device_config_t s3_virge_config[] =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
.name = "bilinear",
|
||||||
|
.description = "Bilinear filtering",
|
||||||
|
.type = CONFIG_BINARY,
|
||||||
|
.default_int = 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "memory",
|
||||||
|
.description = "Memory size",
|
||||||
|
.type = CONFIG_SELECTION,
|
||||||
|
.selection =
|
||||||
|
{
|
||||||
|
{
|
||||||
|
.description = "2 MB",
|
||||||
|
.value = 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.description = "4 MB",
|
||||||
|
.value = 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.description = ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
.default_int = 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.type = -1
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
device_t s3_virge_device =
|
device_t s3_virge_device =
|
||||||
{
|
{
|
||||||
"Diamond Stealth 3D 2000 (S3 ViRGE)",
|
"Diamond Stealth 3D 2000 (S3 ViRGE)",
|
||||||
|
|
@ -3183,7 +3247,8 @@ device_t s3_virge_device =
|
||||||
s3_virge_available,
|
s3_virge_available,
|
||||||
s3_virge_speed_changed,
|
s3_virge_speed_changed,
|
||||||
s3_virge_force_redraw,
|
s3_virge_force_redraw,
|
||||||
s3_virge_add_status_info
|
s3_virge_add_status_info,
|
||||||
|
s3_virge_config
|
||||||
};
|
};
|
||||||
|
|
||||||
device_t s3_virge_375_device =
|
device_t s3_virge_375_device =
|
||||||
|
|
@ -3195,5 +3260,6 @@ device_t s3_virge_375_device =
|
||||||
s3_virge_375_available,
|
s3_virge_375_available,
|
||||||
s3_virge_speed_changed,
|
s3_virge_speed_changed,
|
||||||
s3_virge_force_redraw,
|
s3_virge_force_redraw,
|
||||||
s3_virge_add_status_info
|
s3_virge_add_status_info,
|
||||||
|
s3_virge_config
|
||||||
};
|
};
|
||||||
|
|
|
||||||
10
src/video.c
10
src/video.c
|
|
@ -78,6 +78,16 @@ char *video_card_getname(int card)
|
||||||
return video_cards[card].name;
|
return video_cards[card].name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
device_t *video_card_getdevice(int card)
|
||||||
|
{
|
||||||
|
return video_cards[card].device;
|
||||||
|
}
|
||||||
|
|
||||||
|
int video_card_has_config(int card)
|
||||||
|
{
|
||||||
|
return video_cards[card].device->config ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
int video_card_getid(char *s)
|
int video_card_getid(char *s)
|
||||||
{
|
{
|
||||||
int c = 0;
|
int c = 0;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
int video_card_available(int card);
|
int video_card_available(int card);
|
||||||
char *video_card_getname(int card);
|
char *video_card_getname(int card);
|
||||||
|
struct device_t *video_card_getdevice(int card);
|
||||||
|
int video_card_has_config(int card);
|
||||||
int video_card_getid(char *s);
|
int video_card_getid(char *s);
|
||||||
int video_old_to_new(int card);
|
int video_old_to_new(int card);
|
||||||
int video_new_to_old(int card);
|
int video_new_to_old(int card);
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
#include "ibm.h"
|
#include "ibm.h"
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
|
#include "device.h"
|
||||||
#include "model.h"
|
#include "model.h"
|
||||||
#include "resources.h"
|
#include "resources.h"
|
||||||
#include "sound.h"
|
#include "sound.h"
|
||||||
|
|
@ -154,6 +155,18 @@ static BOOL CALLBACK config_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR
|
||||||
SendMessage(h, UDM_SETRANGE, 0, (1 << 16) | 256);
|
SendMessage(h, UDM_SETRANGE, 0, (1 << 16) | 256);
|
||||||
SendMessage(h, UDM_SETPOS, 0, mem_size);
|
SendMessage(h, UDM_SETPOS, 0, mem_size);
|
||||||
|
|
||||||
|
h = GetDlgItem(hdlg, IDC_CONFIGUREVID);
|
||||||
|
if (video_card_has_config(video_old_to_new(gfxcard)))
|
||||||
|
EnableWindow(h, TRUE);
|
||||||
|
else
|
||||||
|
EnableWindow(h, FALSE);
|
||||||
|
|
||||||
|
h = GetDlgItem(hdlg, IDC_CONFIGURESND);
|
||||||
|
if (sound_card_has_config(sound_card_current))
|
||||||
|
EnableWindow(h, TRUE);
|
||||||
|
else
|
||||||
|
EnableWindow(h, FALSE);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
case WM_COMMAND:
|
case WM_COMMAND:
|
||||||
|
|
@ -322,6 +335,43 @@ static BOOL CALLBACK config_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR
|
||||||
SendMessage(h, CB_SETCURSEL, temp_cpu, 0);
|
SendMessage(h, CB_SETCURSEL, temp_cpu, 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case IDC_CONFIGUREVID:
|
||||||
|
h = GetDlgItem(hdlg, IDC_COMBOVID);
|
||||||
|
SendMessage(h, CB_GETLBTEXT, SendMessage(h, CB_GETCURSEL, 0, 0), (LPARAM)temp_str);
|
||||||
|
|
||||||
|
deviceconfig_open(hdlg, (void *)video_card_getdevice(video_card_getid(temp_str)));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IDC_COMBOVID:
|
||||||
|
h = GetDlgItem(hdlg, IDC_COMBOVID);
|
||||||
|
SendMessage(h, CB_GETLBTEXT, SendMessage(h, CB_GETCURSEL, 0, 0), (LPARAM)temp_str);
|
||||||
|
gfx = video_card_getid(temp_str);
|
||||||
|
|
||||||
|
h = GetDlgItem(hdlg, IDC_CONFIGUREVID);
|
||||||
|
if (video_card_has_config(gfx))
|
||||||
|
EnableWindow(h, TRUE);
|
||||||
|
else
|
||||||
|
EnableWindow(h, FALSE);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IDC_CONFIGURESND:
|
||||||
|
h = GetDlgItem(hdlg, IDC_COMBOSND);
|
||||||
|
temp_sound_card_current = settings_list_to_sound[SendMessage(h, CB_GETCURSEL, 0, 0)];
|
||||||
|
|
||||||
|
deviceconfig_open(hdlg, (void *)sound_card_getdevice(temp_sound_card_current));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IDC_COMBOSND:
|
||||||
|
h = GetDlgItem(hdlg, IDC_COMBOSND);
|
||||||
|
temp_sound_card_current = settings_list_to_sound[SendMessage(h, CB_GETCURSEL, 0, 0)];
|
||||||
|
|
||||||
|
h = GetDlgItem(hdlg, IDC_CONFIGURESND);
|
||||||
|
if (sound_card_has_config(temp_sound_card_current))
|
||||||
|
EnableWindow(h, TRUE);
|
||||||
|
else
|
||||||
|
EnableWindow(h, FALSE);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
317
src/win-deviceconfig.c
Normal file
317
src/win-deviceconfig.c
Normal file
|
|
@ -0,0 +1,317 @@
|
||||||
|
#define BITMAP WINDOWS_BITMAP
|
||||||
|
#include <windows.h>
|
||||||
|
#include <windowsx.h>
|
||||||
|
#undef BITMAP
|
||||||
|
|
||||||
|
#include "ibm.h"
|
||||||
|
#include "config.h"
|
||||||
|
#include "device.h"
|
||||||
|
#include "resources.h"
|
||||||
|
#include "win.h"
|
||||||
|
|
||||||
|
static device_t *config_device;
|
||||||
|
|
||||||
|
static BOOL CALLBACK deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
|
||||||
|
{
|
||||||
|
switch (message)
|
||||||
|
{
|
||||||
|
case WM_INITDIALOG:
|
||||||
|
{
|
||||||
|
int id = IDC_CONFIG_BASE;
|
||||||
|
device_config_t *config = config_device->config;
|
||||||
|
int c;
|
||||||
|
|
||||||
|
while (config->type != -1)
|
||||||
|
{
|
||||||
|
device_config_selection_t *selection = config->selection;
|
||||||
|
HWND h = GetDlgItem(hdlg, id);
|
||||||
|
int val_int;
|
||||||
|
char *val_string;
|
||||||
|
|
||||||
|
switch (config->type)
|
||||||
|
{
|
||||||
|
case CONFIG_BINARY:
|
||||||
|
val_int = get_config_int(config_device->name, config->name, config->default_int);
|
||||||
|
|
||||||
|
SendMessage(h, BM_SETCHECK, val_int, 0);
|
||||||
|
|
||||||
|
id++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CONFIG_SELECTION:
|
||||||
|
val_int = get_config_int(config_device->name, config->name, config->default_int);
|
||||||
|
|
||||||
|
c = 0;
|
||||||
|
while (selection->description[0])
|
||||||
|
{
|
||||||
|
SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)selection->description);
|
||||||
|
if (val_int == selection->value)
|
||||||
|
SendMessage(h, CB_SETCURSEL, c, 0);
|
||||||
|
selection++;
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
|
||||||
|
id += 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
config++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
case WM_COMMAND:
|
||||||
|
switch (LOWORD(wParam))
|
||||||
|
{
|
||||||
|
case IDOK:
|
||||||
|
{
|
||||||
|
int id = IDC_CONFIG_BASE;
|
||||||
|
device_config_t *config = config_device->config;
|
||||||
|
int c;
|
||||||
|
int changed = 0;
|
||||||
|
|
||||||
|
while (config->type != -1)
|
||||||
|
{
|
||||||
|
device_config_selection_t *selection = config->selection;
|
||||||
|
HWND h = GetDlgItem(hdlg, id);
|
||||||
|
int val_int;
|
||||||
|
char *val_string;
|
||||||
|
|
||||||
|
switch (config->type)
|
||||||
|
{
|
||||||
|
case CONFIG_BINARY:
|
||||||
|
val_int = get_config_int(config_device->name, config->name, config->default_int);
|
||||||
|
|
||||||
|
if (val_int != SendMessage(h, BM_GETCHECK, 0, 0))
|
||||||
|
changed = 1;
|
||||||
|
|
||||||
|
id++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CONFIG_SELECTION:
|
||||||
|
val_int = get_config_int(config_device->name, config->name, config->default_int);
|
||||||
|
|
||||||
|
c = SendMessage(h, CB_GETCURSEL, 0, 0);
|
||||||
|
|
||||||
|
for (; c > 0; c--)
|
||||||
|
selection++;
|
||||||
|
|
||||||
|
if (val_int != selection->value)
|
||||||
|
changed = 1;
|
||||||
|
|
||||||
|
id += 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
config++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!changed)
|
||||||
|
{
|
||||||
|
EndDialog(hdlg, 0);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MessageBox(NULL, "This will reset PCem!\nOkay to continue?", "PCem", MB_OKCANCEL) != IDOK)
|
||||||
|
{
|
||||||
|
EndDialog(hdlg, 0);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
id = IDC_CONFIG_BASE;
|
||||||
|
config = config_device->config;
|
||||||
|
|
||||||
|
while (config->type != -1)
|
||||||
|
{
|
||||||
|
device_config_selection_t *selection = config->selection;
|
||||||
|
HWND h = GetDlgItem(hdlg, id);
|
||||||
|
int val_int;
|
||||||
|
char *val_string;
|
||||||
|
|
||||||
|
switch (config->type)
|
||||||
|
{
|
||||||
|
case CONFIG_BINARY:
|
||||||
|
set_config_int(config_device->name, config->name, SendMessage(h, BM_GETCHECK, 0, 0));
|
||||||
|
|
||||||
|
id++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CONFIG_SELECTION:
|
||||||
|
c = SendMessage(h, CB_GETCURSEL, 0, 0);
|
||||||
|
for (; c > 0; c--)
|
||||||
|
selection++;
|
||||||
|
set_config_int(config_device->name, config->name, selection->value);
|
||||||
|
|
||||||
|
id += 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
config++;
|
||||||
|
}
|
||||||
|
|
||||||
|
saveconfig();
|
||||||
|
|
||||||
|
resetpchard();
|
||||||
|
|
||||||
|
EndDialog(hdlg, 0);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
case IDCANCEL:
|
||||||
|
EndDialog(hdlg, 0);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void deviceconfig_open(HWND hwnd, device_t *device)
|
||||||
|
{
|
||||||
|
device_config_t *config = device->config;
|
||||||
|
uint16_t *data = malloc(16384);
|
||||||
|
DLGTEMPLATE *dlg = (DLGTEMPLATE *)data;
|
||||||
|
DLGITEMTEMPLATE *item;
|
||||||
|
int y = 10;
|
||||||
|
int id = IDC_CONFIG_BASE;
|
||||||
|
|
||||||
|
memset(data, 0, 4096);
|
||||||
|
|
||||||
|
dlg->style = DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU;
|
||||||
|
dlg->x = 10;
|
||||||
|
dlg->y = 10;
|
||||||
|
dlg->cx = 150;
|
||||||
|
dlg->cy = 70;
|
||||||
|
|
||||||
|
data = (uint16_t *)(dlg + 1);
|
||||||
|
|
||||||
|
*data++ = 0; /*no menu*/
|
||||||
|
*data++ = 0; /*predefined dialog box class*/
|
||||||
|
data += MultiByteToWideChar(CP_ACP, 0, "Device Configuration", -1, data, 50);
|
||||||
|
|
||||||
|
*data++ = 8; /*Point*/
|
||||||
|
data += MultiByteToWideChar(CP_ACP, 0, "MS Sans Serif", -1, data, 50);
|
||||||
|
|
||||||
|
if (((unsigned long)data) & 2)
|
||||||
|
data++;
|
||||||
|
|
||||||
|
while (config->type != -1)
|
||||||
|
{
|
||||||
|
switch (config->type)
|
||||||
|
{
|
||||||
|
case CONFIG_BINARY:
|
||||||
|
item = (DLGITEMTEMPLATE *)data;
|
||||||
|
item->x = 10;
|
||||||
|
item->y = y;
|
||||||
|
item->id = id++;
|
||||||
|
|
||||||
|
item->cx = 80;
|
||||||
|
item->cy = 15;
|
||||||
|
|
||||||
|
item->style = WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX;
|
||||||
|
|
||||||
|
data = (uint16_t *)(item + 1);
|
||||||
|
*data++ = 0xFFFF;
|
||||||
|
*data++ = 0x0080; // button class
|
||||||
|
|
||||||
|
data += MultiByteToWideChar(CP_ACP, 0, config->description, -1, data, 256);
|
||||||
|
*data++ = 0; // no creation data
|
||||||
|
|
||||||
|
y += 20;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CONFIG_SELECTION:
|
||||||
|
/*Combo box*/
|
||||||
|
item = (DLGITEMTEMPLATE *)data;
|
||||||
|
item->x = 70;
|
||||||
|
item->y = y;
|
||||||
|
item->id = id++;
|
||||||
|
|
||||||
|
item->cx = 70;
|
||||||
|
item->cy = 150;
|
||||||
|
|
||||||
|
item->style = WS_CHILD | WS_VISIBLE | CBS_DROPDOWN | WS_VSCROLL;
|
||||||
|
|
||||||
|
data = (uint16_t *)(item + 1);
|
||||||
|
*data++ = 0xFFFF;
|
||||||
|
*data++ = 0x0085; // combo box class
|
||||||
|
|
||||||
|
data += MultiByteToWideChar(CP_ACP, 0, config->description, -1, data, 256);
|
||||||
|
*data++ = 0; // no creation data
|
||||||
|
|
||||||
|
if (((unsigned long)data) & 2)
|
||||||
|
data++;
|
||||||
|
|
||||||
|
/*Static text*/
|
||||||
|
item = (DLGITEMTEMPLATE *)data;
|
||||||
|
item->x = 10;
|
||||||
|
item->y = y;
|
||||||
|
item->id = id++;
|
||||||
|
|
||||||
|
item->cx = 60;
|
||||||
|
item->cy = 15;
|
||||||
|
|
||||||
|
item->style = WS_CHILD | WS_VISIBLE;
|
||||||
|
|
||||||
|
data = (uint16_t *)(item + 1);
|
||||||
|
*data++ = 0xFFFF;
|
||||||
|
*data++ = 0x0082; // static class
|
||||||
|
|
||||||
|
data += MultiByteToWideChar(CP_ACP, 0, config->description, -1, data, 256);
|
||||||
|
*data++ = 0; // no creation data
|
||||||
|
|
||||||
|
if (((unsigned long)data) & 2)
|
||||||
|
data++;
|
||||||
|
|
||||||
|
y += 20;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (((unsigned long)data) & 2)
|
||||||
|
data++;
|
||||||
|
|
||||||
|
config++;
|
||||||
|
}
|
||||||
|
|
||||||
|
dlg->cdit = (id - IDC_CONFIG_BASE) + 2;
|
||||||
|
|
||||||
|
// DEFPUSHBUTTON "OK",IDOK,64,232,50,14, WS_TABSTOP
|
||||||
|
// PUSHBUTTON "Cancel",IDCANCEL,128,232,50,14, WS_TABSTOP
|
||||||
|
|
||||||
|
item = (DLGITEMTEMPLATE *)data;
|
||||||
|
item->x = 20;
|
||||||
|
item->y = y;
|
||||||
|
item->cx = 50;
|
||||||
|
item->cy = 14;
|
||||||
|
item->id = IDOK; // OK button identifier
|
||||||
|
item->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON;
|
||||||
|
|
||||||
|
data = (uint16_t *)(item + 1);
|
||||||
|
*data++ = 0xFFFF;
|
||||||
|
*data++ = 0x0080; // button class
|
||||||
|
|
||||||
|
data += MultiByteToWideChar(CP_ACP, 0, "OK", -1, data, 50);
|
||||||
|
*data++ = 0; // no creation data
|
||||||
|
|
||||||
|
if (((unsigned long)data) & 2)
|
||||||
|
data++;
|
||||||
|
|
||||||
|
item = (DLGITEMTEMPLATE *)data;
|
||||||
|
item->x = 80;
|
||||||
|
item->y = y;
|
||||||
|
item->cx = 50;
|
||||||
|
item->cy = 14;
|
||||||
|
item->id = IDCANCEL; // OK button identifier
|
||||||
|
item->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON;
|
||||||
|
|
||||||
|
data = (uint16_t *)(item + 1);
|
||||||
|
*data++ = 0xFFFF;
|
||||||
|
*data++ = 0x0080; // button class
|
||||||
|
|
||||||
|
data += MultiByteToWideChar(CP_ACP, 0, "Cancel", -1, data, 50);
|
||||||
|
*data++ = 0; // no creation data
|
||||||
|
|
||||||
|
dlg->cy = y + 20;
|
||||||
|
|
||||||
|
config_device = device;
|
||||||
|
|
||||||
|
DialogBoxIndirect(hinstance, dlg, hwnd, deviceconfig_dlgproc);
|
||||||
|
|
||||||
|
free(data);
|
||||||
|
}
|
||||||
|
|
@ -24,6 +24,8 @@ void hdconf_open(HWND hwnd);
|
||||||
|
|
||||||
void config_open(HWND hwnd);
|
void config_open(HWND hwnd);
|
||||||
|
|
||||||
|
void deviceconfig_open(HWND hwnd, struct device_t *device);
|
||||||
|
|
||||||
extern char openfilestring[260];
|
extern char openfilestring[260];
|
||||||
|
|
||||||
int getfile(HWND hwnd, char *f, char *fn);
|
int getfile(HWND hwnd, char *f, char *fn);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue