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_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 \
|
||||
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
|
||||
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
|
||||
|
|
|
|||
429
src/config.c
429
src/config.c
|
|
@ -1,9 +1,194 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "config.h"
|
||||
|
||||
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)
|
||||
{
|
||||
strcpy(config_file, s);
|
||||
|
|
@ -15,132 +200,139 @@ void config_new()
|
|||
fclose(f);
|
||||
}
|
||||
|
||||
int get_config_int(char *head, char *name, int def)
|
||||
static section_t *find_section(char *name)
|
||||
{
|
||||
char buffer[256];
|
||||
char name2[256];
|
||||
FILE *f = fopen(config_file, "rt");
|
||||
int c, d;
|
||||
int res = def;
|
||||
section_t *current_section;
|
||||
char blank[] = "";
|
||||
|
||||
if (!f)
|
||||
return def;
|
||||
|
||||
// pclog("Searching for %s\n", name);
|
||||
|
||||
while (1)
|
||||
{
|
||||
fgets(buffer, 255, f);
|
||||
if (feof(f)) break;
|
||||
|
||||
c = d = 0;
|
||||
|
||||
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");
|
||||
current_section = (section_t *)config_head.next;
|
||||
if (!name)
|
||||
name = blank;
|
||||
|
||||
while ((buffer[c] == '=' || buffer[c] == ' ') && buffer[c])
|
||||
c++;
|
||||
|
||||
if (!buffer[c]) continue;
|
||||
while (current_section)
|
||||
{
|
||||
if (!strncmp(current_section->name, name, 256))
|
||||
return current_section;
|
||||
|
||||
sscanf(&buffer[c], "%i", &res);
|
||||
// pclog("Reading value - %i\n", res);
|
||||
break;
|
||||
current_section = (section_t *)current_section->list.next;
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
return res;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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 buffer[256];
|
||||
char name2[256];
|
||||
FILE *f = fopen(config_file, "rt");
|
||||
int c, d;
|
||||
|
||||
strcpy(config_return_string, def);
|
||||
|
||||
if (!f)
|
||||
return config_return_string;
|
||||
|
||||
// pclog("Searching for %s\n", name);
|
||||
|
||||
while (1)
|
||||
{
|
||||
fgets(buffer, 255, f);
|
||||
if (feof(f)) break;
|
||||
|
||||
c = d = 0;
|
||||
|
||||
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");
|
||||
section_t *section;
|
||||
entry_t *entry;
|
||||
int value;
|
||||
|
||||
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;
|
||||
}
|
||||
section = find_section(head);
|
||||
|
||||
fclose(f);
|
||||
return config_return_string;
|
||||
if (!section)
|
||||
return def;
|
||||
|
||||
entry = find_entry(section, name);
|
||||
|
||||
if (!entry)
|
||||
return def;
|
||||
|
||||
return entry->data;
|
||||
}
|
||||
|
||||
void set_config_int(char *head, char *name, int val)
|
||||
{
|
||||
FILE *f = fopen(config_file, "at");
|
||||
// if (!f) pclog("set_config_int - !f\n");
|
||||
fprintf(f, "%s = %i\n", name, val);
|
||||
// pclog("Write %s = %i\n", name, val);
|
||||
fclose(f);
|
||||
// pclog("fclose\n");
|
||||
section_t *section;
|
||||
entry_t *entry;
|
||||
|
||||
section = find_section(head);
|
||||
|
||||
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)
|
||||
{
|
||||
FILE *f = fopen(config_file, "at");
|
||||
// if (!f) pclog("set_config_string - !f\n");
|
||||
fprintf(f, "%s = %s\n", name, val);
|
||||
// pclog("Write %s = %s\n", name, val);
|
||||
fclose(f);
|
||||
section_t *section;
|
||||
entry_t *entry;
|
||||
|
||||
section = find_section(head);
|
||||
|
||||
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)
|
||||
{
|
||||
int c = strlen(s) - 1;
|
||||
|
|
@ -164,3 +356,32 @@ void put_backslash(char *s)
|
|||
if (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);
|
||||
void append_filename(char *dest, char *s1, char *s2, int size);
|
||||
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 "config.h"
|
||||
#include "device.h"
|
||||
|
||||
static void *device_priv[256];
|
||||
static device_t *devices[256];
|
||||
|
||||
static device_t *current_device;
|
||||
|
||||
void device_init()
|
||||
{
|
||||
memset(devices, 0, sizeof(devices));
|
||||
|
|
@ -20,6 +23,8 @@ void device_add(device_t *d)
|
|||
if (c >= 256)
|
||||
fatal("device_add : too many devices\n");
|
||||
|
||||
current_device = d;
|
||||
|
||||
priv = d->init();
|
||||
if (priv == NULL)
|
||||
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
|
||||
{
|
||||
char name[50];
|
||||
|
|
@ -8,6 +29,7 @@ typedef struct device_t
|
|||
void (*speed_changed)(void *p);
|
||||
void (*force_redraw)(void *p);
|
||||
int (*add_status_info)(char *s, int max_len, void *p);
|
||||
device_config_t *config;
|
||||
} device_t;
|
||||
|
||||
void device_init();
|
||||
|
|
@ -18,6 +40,9 @@ void device_speed_changed();
|
|||
void device_force_redraw();
|
||||
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
|
||||
{
|
||||
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;
|
||||
append_filename(s, pcempath, "pcem.cfg", 511);
|
||||
set_config_file(s);
|
||||
|
||||
config_load();
|
||||
|
||||
GAMEBLASTER = get_config_int(NULL, "gameblaster", 0);
|
||||
GUS = get_config_int(NULL, "gus", 0);
|
||||
SSI2001 = get_config_int(NULL, "ssi2001", 0);
|
||||
|
|
@ -480,7 +483,6 @@ void loadconfig()
|
|||
|
||||
void saveconfig()
|
||||
{
|
||||
config_new();
|
||||
set_config_int(NULL, "gameblaster", GAMEBLASTER);
|
||||
set_config_int(NULL, "gus", GUS);
|
||||
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_cylinders", hdc[1].tracks);
|
||||
set_config_string(NULL, "hdd_fn", ide_fn[1]);
|
||||
|
||||
config_save();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ BEGIN
|
|||
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
|
||||
CAPTION "Configure PCem"
|
||||
FONT 8, "MS Sans Serif"
|
||||
|
|
@ -56,11 +56,13 @@ BEGIN
|
|||
PUSHBUTTON "Cancel",IDCANCEL,128,232,50,14, 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
|
||||
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_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_COMBOSPD,62,116,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
|
||||
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
|
||||
|
|
|
|||
12
src/pic.c
12
src/pic.c
|
|
@ -244,6 +244,8 @@ int pic_current[16];
|
|||
|
||||
void picint(uint16_t num)
|
||||
{
|
||||
if (AT && num == (1 << 2))
|
||||
num = 1 << 9;
|
||||
// pclog("picint : %04X\n", num);
|
||||
// if (num == 0x10) pclog("PICINT 10\n");
|
||||
if (num>0xFF)
|
||||
|
|
@ -264,6 +266,11 @@ void picintlevel(uint16_t num)
|
|||
{
|
||||
int c = 0;
|
||||
while (!(num & (1 << c))) c++;
|
||||
if (AT && c == 2)
|
||||
{
|
||||
c = 9;
|
||||
num = 1 << 9;
|
||||
}
|
||||
// pclog("INTLEVEL %04X %i\n", num, c);
|
||||
if (!pic_current[c])
|
||||
{
|
||||
|
|
@ -283,6 +290,11 @@ void picintc(uint16_t num)
|
|||
{
|
||||
int c = 0;
|
||||
while (!(num & (1 << c))) c++;
|
||||
if (AT && c == 2)
|
||||
{
|
||||
c = 9;
|
||||
num = 1 << 9;
|
||||
}
|
||||
// pclog("INTC %04X %i\n", num, c);
|
||||
pic_current[c]=0;
|
||||
|
||||
|
|
|
|||
|
|
@ -77,5 +77,10 @@
|
|||
#define IDC_EDIT_C_FN 1220
|
||||
#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_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;
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
if (sound_cards[sound_card_current].device)
|
||||
|
|
|
|||
|
|
@ -7,4 +7,6 @@ extern int sound_card_current;
|
|||
|
||||
int sound_card_available(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();
|
||||
|
|
|
|||
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()
|
||||
{
|
||||
sb_t *sb = malloc(sizeof(sb_t));
|
||||
uint16_t addr = device_get_config_int("addr");
|
||||
memset(sb, 0, sizeof(sb_t));
|
||||
|
||||
opl2_init(&sb->opl);
|
||||
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);
|
||||
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);
|
||||
sound_add_handler(sb_opl2_poll, sb_get_buffer, sb);
|
||||
return sb;
|
||||
|
|
@ -270,13 +273,16 @@ void *sb_1_init()
|
|||
void *sb_15_init()
|
||||
{
|
||||
sb_t *sb = malloc(sizeof(sb_t));
|
||||
uint16_t addr = device_get_config_int("addr");
|
||||
memset(sb, 0, sizeof(sb_t));
|
||||
|
||||
opl2_init(&sb->opl);
|
||||
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);
|
||||
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);
|
||||
sound_add_handler(sb_opl2_poll, sb_get_buffer, sb);
|
||||
return sb;
|
||||
|
|
@ -284,13 +290,16 @@ void *sb_15_init()
|
|||
void *sb_2_init()
|
||||
{
|
||||
sb_t *sb = malloc(sizeof(sb_t));
|
||||
uint16_t addr = device_get_config_int("addr");
|
||||
memset(sb, 0, sizeof(sb_t));
|
||||
|
||||
opl2_init(&sb->opl);
|
||||
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);
|
||||
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);
|
||||
sound_add_handler(sb_opl2_poll, sb_get_buffer, sb);
|
||||
return sb;
|
||||
|
|
@ -299,17 +308,20 @@ void *sb_2_init()
|
|||
void *sb_pro_v1_init()
|
||||
{
|
||||
sb_t *sb = malloc(sizeof(sb_t));
|
||||
uint16_t addr = device_get_config_int("addr");
|
||||
memset(sb, 0, sizeof(sb_t));
|
||||
|
||||
opl2_init(&sb->opl);
|
||||
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);
|
||||
io_sethandler(0x0220, 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(0x0228, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl);
|
||||
io_sethandler(addr+0, 0x0002, opl2_l_read, NULL, NULL, opl2_l_write, NULL, NULL, &sb->opl);
|
||||
io_sethandler(addr+2, 0x0002, opl2_r_read, NULL, NULL, opl2_r_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(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);
|
||||
|
||||
sb->mixer.regs[0x22] = 0xff;
|
||||
|
|
@ -323,16 +335,19 @@ void *sb_pro_v1_init()
|
|||
void *sb_pro_v2_init()
|
||||
{
|
||||
sb_t *sb = malloc(sizeof(sb_t));
|
||||
uint16_t addr = device_get_config_int("addr");
|
||||
memset(sb, 0, sizeof(sb_t));
|
||||
|
||||
opl3_init(&sb->opl);
|
||||
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);
|
||||
io_sethandler(0x0220, 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+0, 0x0004, 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(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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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 =
|
||||
{
|
||||
"Sound Blaster v1.0",
|
||||
|
|
@ -445,7 +612,8 @@ device_t sb_1_device =
|
|||
NULL,
|
||||
sb_speed_changed,
|
||||
NULL,
|
||||
sb_add_status_info
|
||||
sb_add_status_info,
|
||||
sb_config
|
||||
};
|
||||
device_t sb_15_device =
|
||||
{
|
||||
|
|
@ -456,7 +624,8 @@ device_t sb_15_device =
|
|||
NULL,
|
||||
sb_speed_changed,
|
||||
NULL,
|
||||
sb_add_status_info
|
||||
sb_add_status_info,
|
||||
sb_config
|
||||
};
|
||||
device_t sb_2_device =
|
||||
{
|
||||
|
|
@ -467,7 +636,8 @@ device_t sb_2_device =
|
|||
NULL,
|
||||
sb_speed_changed,
|
||||
NULL,
|
||||
sb_add_status_info
|
||||
sb_add_status_info,
|
||||
sb_config
|
||||
};
|
||||
device_t sb_pro_v1_device =
|
||||
{
|
||||
|
|
@ -478,7 +648,8 @@ device_t sb_pro_v1_device =
|
|||
NULL,
|
||||
sb_speed_changed,
|
||||
NULL,
|
||||
sb_add_status_info
|
||||
sb_add_status_info,
|
||||
sb_pro_config
|
||||
};
|
||||
device_t sb_pro_v2_device =
|
||||
{
|
||||
|
|
@ -489,7 +660,8 @@ device_t sb_pro_v2_device =
|
|||
NULL,
|
||||
sb_speed_changed,
|
||||
NULL,
|
||||
sb_add_status_info
|
||||
sb_add_status_info,
|
||||
sb_pro_config
|
||||
};
|
||||
device_t sb_16_device =
|
||||
{
|
||||
|
|
|
|||
|
|
@ -38,6 +38,9 @@ typedef struct virge_t
|
|||
|
||||
int is_375;
|
||||
|
||||
int bilinear_enabled;
|
||||
int memory_size;
|
||||
|
||||
int pixel_count, tri_count;
|
||||
|
||||
struct
|
||||
|
|
@ -2486,7 +2489,7 @@ static void s3_virge_triangle(virge_t *virge)
|
|||
// pclog("use tex_sample_mipmap\n");
|
||||
break;
|
||||
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");
|
||||
break;
|
||||
case 4: case 5:
|
||||
|
|
@ -2494,7 +2497,7 @@ static void s3_virge_triangle(virge_t *virge)
|
|||
// pclog("use tex_sample_normal\n");
|
||||
break;
|
||||
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");
|
||||
break;
|
||||
case (0 | 8): case (1 | 8):
|
||||
|
|
@ -2506,9 +2509,9 @@ static void s3_virge_triangle(virge_t *virge)
|
|||
break;
|
||||
case (2 | 8): case (3 | 8):
|
||||
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
|
||||
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");
|
||||
break;
|
||||
case (4 | 8): case (5 | 8):
|
||||
|
|
@ -2520,9 +2523,9 @@ static void s3_virge_triangle(virge_t *virge)
|
|||
break;
|
||||
case (6 | 8): case (7 | 8):
|
||||
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
|
||||
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");
|
||||
break;
|
||||
}
|
||||
|
|
@ -2974,8 +2977,12 @@ static void *s3_virge_init()
|
|||
{
|
||||
virge_t *virge = malloc(sizeof(virge_t));
|
||||
memset(virge, 0, sizeof(virge_t));
|
||||
|
||||
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, 1 << 22, /*4mb*/
|
||||
svga_init(&virge->svga, virge, virge->memory_size << 20,
|
||||
s3_virge_recalctimings,
|
||||
s3_virge_in, s3_virge_out,
|
||||
s3_virge_hwcursor_draw,
|
||||
|
|
@ -3029,7 +3036,17 @@ static void *s3_virge_init()
|
|||
virge->virge_rev = 0;
|
||||
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[0x53] = 1 << 3;
|
||||
virge->svga.crtc[0x59] = 0x70;
|
||||
|
|
@ -3046,7 +3063,11 @@ static void *s3_virge_375_init()
|
|||
virge_t *virge = malloc(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_in, s3_virge_out,
|
||||
s3_virge_hwcursor_draw,
|
||||
|
|
@ -3100,7 +3121,17 @@ static void *s3_virge_375_init()
|
|||
virge->virge_rev = 0;
|
||||
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[0x53] = 1 << 3;
|
||||
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;
|
||||
}
|
||||
|
||||
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 =
|
||||
{
|
||||
"Diamond Stealth 3D 2000 (S3 ViRGE)",
|
||||
|
|
@ -3183,7 +3247,8 @@ device_t s3_virge_device =
|
|||
s3_virge_available,
|
||||
s3_virge_speed_changed,
|
||||
s3_virge_force_redraw,
|
||||
s3_virge_add_status_info
|
||||
s3_virge_add_status_info,
|
||||
s3_virge_config
|
||||
};
|
||||
|
||||
device_t s3_virge_375_device =
|
||||
|
|
@ -3195,5 +3260,6 @@ device_t s3_virge_375_device =
|
|||
s3_virge_375_available,
|
||||
s3_virge_speed_changed,
|
||||
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;
|
||||
}
|
||||
|
||||
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 c = 0;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
int video_card_available(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_old_to_new(int card);
|
||||
int video_new_to_old(int card);
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include "ibm.h"
|
||||
#include "cpu.h"
|
||||
#include "device.h"
|
||||
#include "model.h"
|
||||
#include "resources.h"
|
||||
#include "sound.h"
|
||||
|
|
@ -153,7 +154,19 @@ static BOOL CALLBACK config_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR
|
|||
SendMessage(h, UDM_SETBUDDY, (WPARAM)GetDlgItem(hdlg, IDC_MEMTEXT), 0);
|
||||
SendMessage(h, UDM_SETRANGE, 0, (1 << 16) | 256);
|
||||
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;
|
||||
|
||||
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);
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
|
|
|||
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 deviceconfig_open(HWND hwnd, struct device_t *device);
|
||||
|
||||
extern char openfilestring[260];
|
||||
|
||||
int getfile(HWND hwnd, char *f, char *fn);
|
||||
|
|
|
|||
Loading…
Reference in a new issue