Re-worked mouse code to be devices (to allow for configuration.)
Re-worked the system pathnames (pc.c), renamed cfg_path to usr_path. Other small things here and there. Logitech bus mouse re-worked, should be OK now.
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Main include file for the application.
|
||||
*
|
||||
* Version: @(#)86box.h 1.0.13 2017/11/19
|
||||
* Version: @(#)86box.h 1.0.15 2017/12/03
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
@@ -33,7 +33,7 @@
|
||||
#define EMU_VERSION_W L"2.00"
|
||||
|
||||
/* Filename and pathname info. */
|
||||
#define CONFIG_FILE_W L"86box.cfg"
|
||||
#define CONFIG_FILE L"86box.cfg"
|
||||
#define NVR_PATH L"nvr"
|
||||
#define SCREENSHOT_PATH L"screenshots"
|
||||
|
||||
@@ -113,7 +113,8 @@ extern int nic_do_log;
|
||||
#endif
|
||||
|
||||
extern wchar_t exe_path[1024]; /* path (dir) of executable */
|
||||
extern wchar_t cfg_path[1024]; /* path (dir) of user data */
|
||||
extern wchar_t usr_path[1024]; /* path (dir) of user data */
|
||||
extern wchar_t cfg_path[1024]; /* full path of config file */
|
||||
extern FILE *stdlog; /* file to log output to */
|
||||
extern int scrnsz_x, /* current screen size, X */
|
||||
scrnsz_y; /* current screen size, Y */
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
# settings, so we can avoid changing the main one for all of
|
||||
# our local setups.
|
||||
#
|
||||
# Version: @(#)Makefile.local 1.0.7 2017/11/12
|
||||
# Version: @(#)Makefile.local 1.0.8 2017/11/28
|
||||
#
|
||||
# Author: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
#
|
||||
@@ -20,12 +20,8 @@
|
||||
#########################################################################
|
||||
|
||||
|
||||
DEBUG := y
|
||||
OPTIM := n
|
||||
COPTIM := -O1
|
||||
|
||||
# Name of the executable.
|
||||
PROG := yourexe
|
||||
#PROG := yourexe
|
||||
|
||||
|
||||
# Various compile-time options.
|
||||
|
||||
27
src/config.c
27
src/config.c
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Configuration file handler.
|
||||
*
|
||||
* Version: @(#)config.c 1.0.32 2017/11/25
|
||||
* Version: @(#)config.c 1.0.33 2017/12/03
|
||||
*
|
||||
* Authors: Sarah Walker,
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -101,9 +101,6 @@ typedef struct {
|
||||
}
|
||||
|
||||
|
||||
wchar_t config_file_default[256];
|
||||
|
||||
|
||||
static list_t config_head;
|
||||
|
||||
|
||||
@@ -900,13 +897,13 @@ load_hard_disks(void)
|
||||
* files. We should remove this before
|
||||
* finalizing this release! --FvK
|
||||
*/
|
||||
if (! wcsnicmp(wp, cfg_path, wcslen(cfg_path))) {
|
||||
if (! wcsnicmp(wp, usr_path, wcslen(usr_path))) {
|
||||
/*
|
||||
* Yep, its absolute and prefixed
|
||||
* with the CFG path. Just strip
|
||||
* that off for now...
|
||||
*/
|
||||
wcsncpy(hdd[c].fn, &wp[wcslen(cfg_path)], sizeof_w(hdd[c].fn));
|
||||
wcsncpy(hdd[c].fn, &wp[wcslen(usr_path)], sizeof_w(hdd[c].fn));
|
||||
} else
|
||||
#endif
|
||||
wcsncpy(hdd[c].fn, wp, sizeof_w(hdd[c].fn));
|
||||
@@ -967,13 +964,13 @@ load_removable_devices(void)
|
||||
* files. We should remove this before
|
||||
* finalizing this release! --FvK
|
||||
*/
|
||||
if (! wcsnicmp(wp, cfg_path, wcslen(cfg_path))) {
|
||||
if (! wcsnicmp(wp, usr_path, wcslen(usr_path))) {
|
||||
/*
|
||||
* Yep, its absolute and prefixed
|
||||
* with the EXE path. Just strip
|
||||
* that off for now...
|
||||
*/
|
||||
wcsncpy(floppyfns[c], &wp[wcslen(cfg_path)], sizeof_w(floppyfns[c]));
|
||||
wcsncpy(floppyfns[c], &wp[wcslen(usr_path)], sizeof_w(floppyfns[c]));
|
||||
} else
|
||||
#endif
|
||||
wcsncpy(floppyfns[c], wp, sizeof_w(floppyfns[c]));
|
||||
@@ -1071,13 +1068,13 @@ load_removable_devices(void)
|
||||
* files. We should remove this before
|
||||
* finalizing this release! --FvK
|
||||
*/
|
||||
if (! wcsnicmp(wp, cfg_path, wcslen(cfg_path))) {
|
||||
if (! wcsnicmp(wp, usr_path, wcslen(usr_path))) {
|
||||
/*
|
||||
* Yep, its absolute and prefixed
|
||||
* with the EXE path. Just strip
|
||||
* that off for now...
|
||||
*/
|
||||
wcsncpy(cdrom_image[c].image_path, &wp[wcslen(cfg_path)], sizeof_w(cdrom_image[c].image_path));
|
||||
wcsncpy(cdrom_image[c].image_path, &wp[wcslen(usr_path)], sizeof_w(cdrom_image[c].image_path));
|
||||
} else
|
||||
#endif
|
||||
wcsncpy(cdrom_image[c].image_path, wp, sizeof_w(cdrom_image[c].image_path));
|
||||
@@ -1116,13 +1113,11 @@ load_removable_devices(void)
|
||||
|
||||
/* Load the specified or a default configuration file. */
|
||||
void
|
||||
config_load(wchar_t *fn)
|
||||
config_load(void)
|
||||
{
|
||||
if (fn == NULL)
|
||||
fn = config_file_default;
|
||||
pclog("Loading config file '%ls'..\n", fn);
|
||||
pclog("Loading config file '%ls'..\n", cfg_path);
|
||||
|
||||
if (! config_read(fn)) {
|
||||
if (! config_read(cfg_path)) {
|
||||
cpu = 0;
|
||||
#ifdef USE_LANGUAGE
|
||||
plat_langid = 0x0409;
|
||||
@@ -1701,7 +1696,7 @@ config_save(void)
|
||||
save_hard_disks(); /* Hard disks */
|
||||
save_removable_devices(); /* Removable devices */
|
||||
|
||||
config_write(config_file_default);
|
||||
config_write(cfg_path);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Configuration file handler header.
|
||||
*
|
||||
* Version: @(#)config.h 1.0.5 2017/10/18
|
||||
* Version: @(#)config.h 1.0.6 2017/12/03
|
||||
*
|
||||
* Authors: Sarah Walker,
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -23,14 +23,11 @@
|
||||
# define EMU_CONFIG_H
|
||||
|
||||
|
||||
extern wchar_t config_file_default[256];
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern void config_load(wchar_t *fn);
|
||||
extern void config_load(void);
|
||||
extern void config_save(void);
|
||||
extern void config_write(wchar_t *fn);
|
||||
extern void config_dump(void);
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
* 2 clocks - fetch opcode 1 2 clocks - execute
|
||||
* 2 clocks - fetch opcode 2 etc
|
||||
*
|
||||
* Version: @(#)808x.c 1.0.9 2017/11/24
|
||||
* Version: @(#)808x.c 1.0.10 2017/12/03
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -518,7 +518,7 @@ void dumpregs(int force)
|
||||
#ifndef RELEASE_BUILD
|
||||
indump = 1;
|
||||
output=0;
|
||||
(void)plat_chdir(cfg_path);
|
||||
(void)plat_chdir(usr_path);
|
||||
nopageerrors=1;
|
||||
f=fopen("ram.dmp","wb");
|
||||
fwrite(ram,mem_size*1024,1,f);
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* CPU type handler.
|
||||
*
|
||||
* Version: @(#)cpu.c 1.0.7 2017/11/04
|
||||
* Version: @(#)cpu.c 1.0.8 2017/11/27
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* leilei,
|
||||
@@ -1244,6 +1244,21 @@ void cpu_set()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
cpu_current_pc(char *bufp)
|
||||
{
|
||||
static char buff[10];
|
||||
|
||||
if (bufp == NULL)
|
||||
bufp = buff;
|
||||
|
||||
sprintf(bufp, "%04X:%04X", CS, cpu_state.pc);
|
||||
|
||||
return(bufp);
|
||||
}
|
||||
|
||||
|
||||
void cpu_CPUID()
|
||||
{
|
||||
switch (machines[machine].cpu[cpu_manufacturer].cpus[cpu].cpu_type)
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* CPU type handler.
|
||||
*
|
||||
* Version: @(#)cpu.h 1.0.3 2017/11/04
|
||||
* Version: @(#)cpu.h 1.0.4 2017/11/27
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* leilei,
|
||||
@@ -151,7 +151,7 @@ typedef struct {
|
||||
int checked; /*Non-zero if selector is known to be valid*/
|
||||
} x86seg;
|
||||
|
||||
typedef union MMX_REG {
|
||||
typedef union {
|
||||
uint64_t q;
|
||||
int64_t sq;
|
||||
uint32_t l[2];
|
||||
@@ -405,6 +405,8 @@ extern uint8_t cyrix_read(uint16_t addr, void *priv);
|
||||
extern void loadseg(uint16_t seg, x86seg *s);
|
||||
extern void loadcs(uint16_t seg);
|
||||
|
||||
extern char *cpu_current_pc(char *bufp);
|
||||
|
||||
extern void cpu_update_waitstates(void);
|
||||
extern void cpu_set(void);
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
* Implementation of the generic device interface to handle
|
||||
* all devices attached to the emulator.
|
||||
*
|
||||
* Version: @(#)device.h 1.0.5 2017/11/03
|
||||
* Version: @(#)device.h 1.0.7 2017/11/25
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -28,7 +28,7 @@
|
||||
#define CONFIG_BINARY 2
|
||||
#define CONFIG_SELECTION 3
|
||||
#define CONFIG_MIDI 4
|
||||
#define CONFIG_FILE 5
|
||||
#define CONFIG_FNAME 5
|
||||
#define CONFIG_SPINNER 6
|
||||
#define CONFIG_HEX16 7
|
||||
#define CONFIG_HEX20 8
|
||||
@@ -84,7 +84,7 @@ typedef struct _device_ {
|
||||
void *(*init)(struct _device_ *);
|
||||
void (*close)(void *p);
|
||||
void (*reset)(void *p);
|
||||
int (*available)(void);
|
||||
int (*available)(/*void*/);
|
||||
void (*speed_changed)(void *p);
|
||||
void (*force_redraw)(void *p);
|
||||
void (*add_status_info)(char *s, int max_len, void *p);
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
*
|
||||
* NOTE: FIXME: Strings 2176 and 2193 are same.
|
||||
*
|
||||
* Version: @(#)language.h 1.0.3 2017/11/18
|
||||
* Version: @(#)language.h 1.0.4 2017/11/25
|
||||
*
|
||||
* Author: Fred N. van Kempem, <decwiz@yahoo.com>
|
||||
*
|
||||
@@ -146,19 +146,6 @@
|
||||
#define IDS_2170 2170 // "Check BPB"
|
||||
#define IDS_2171 2171 // "Unable to initialize Flui.."
|
||||
|
||||
#define IDS_3072 3072 // "None"
|
||||
#define IDS_3073 3073 // "Internal"
|
||||
#define IDS_3074 3074 // "[Bus] Logitech Bus Mouse"
|
||||
#define IDS_3075 3075 // "[Bus] Microsoft Bus Mous.."
|
||||
#define IDS_3076 3076 // "[Serial] Mouse Systems Mouse"
|
||||
#define IDS_3077 3077 // "[Serial] Microsoft 2-button Mouse"
|
||||
#define IDS_3078 3078 // "[Serial] Logitech 3-button Mouse"
|
||||
#define IDS_3079 3079 // "[Serial] Microsoft Wheel Mouse"
|
||||
#define IDS_3080 3080 // "[PS/2] 2-button Mouse"
|
||||
#define IDS_3081 3081 // "[PS/2] Microsoft Intellimouse"
|
||||
#define IDS_3082 3082 // "[Proprietary] Amstrad Mouse"
|
||||
#define IDS_3083 3083 // "[Proprietary] Olivetti M24.."
|
||||
|
||||
#define IDS_4096 4096 // "Hard disk (%s)"
|
||||
#define IDS_4097 4097 // "%01i:%01i"
|
||||
#define IDS_4098 4098 // "%i"
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
* in alpha mode, but in highres ("ECD350") mode, it displays
|
||||
* some semi-random junk. Video-memory pointer maybe?
|
||||
*
|
||||
* Version: @(#)m_amstrad.c 1.0.3 2017/11/08
|
||||
* Version: @(#)m_amstrad.c 1.0.4 2017/11/24
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -894,7 +894,7 @@ ms_read(uint16_t addr, void *priv)
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
static int
|
||||
ms_poll(int x, int y, int z, int b, void *priv)
|
||||
{
|
||||
amstrad_t *ams = (amstrad_t *)priv;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Emulation of the Olivetti M24.
|
||||
*
|
||||
* Version: @(#)m_olivetti_m24.c 1.0.5 2017/11/24
|
||||
* Version: @(#)m_olivetti_m24.c 1.0.6 2017/11/24
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -674,7 +674,7 @@ kbd_read(uint16_t port, void *priv)
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
static int
|
||||
ms_poll(int x, int y, int z, int b, void *priv)
|
||||
{
|
||||
olim24_t *m24 = (olim24_t *)priv;
|
||||
|
||||
153
src/mouse.c
153
src/mouse.c
@@ -8,25 +8,30 @@
|
||||
*
|
||||
* Common driver module for MOUSE devices.
|
||||
*
|
||||
* Version: @(#)mouse.c 1.0.15 2017/11/03
|
||||
* TODO: Add the Genius bus- and serial mouse.
|
||||
* Remove the '3-button' flag from mouse types.
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* TheCollector1995,
|
||||
* Version: @(#)mouse.c 1.0.17 2017/12/03
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
*
|
||||
* Copyright 2008-2017 Sarah Walker.
|
||||
* Copyright 2016,2017 Miran Grca.
|
||||
* Copyright 2017 Fred N. van Kempen.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include "machine/machine.h"
|
||||
#include "86box.h"
|
||||
#include "device.h"
|
||||
#include "mouse.h"
|
||||
#include "plat_mouse.h"
|
||||
|
||||
|
||||
typedef struct {
|
||||
const char *internal_name;
|
||||
device_t *device;
|
||||
} mouse_t;
|
||||
|
||||
|
||||
int mouse_type = 0;
|
||||
@@ -36,91 +41,121 @@ int mouse_x,
|
||||
mouse_buttons;
|
||||
|
||||
|
||||
static mouse_t mouse_none = {
|
||||
"Disabled", "none",
|
||||
MOUSE_TYPE_NONE,
|
||||
NULL, NULL, NULL
|
||||
};
|
||||
|
||||
static mouse_t mouse_internal = {
|
||||
"Internal", "internal",
|
||||
MOUSE_TYPE_INTERNAL,
|
||||
NULL, NULL, NULL
|
||||
};
|
||||
|
||||
|
||||
static mouse_t *mouse_list[] = {
|
||||
&mouse_none,
|
||||
&mouse_internal,
|
||||
&mouse_bus_logitech, /* 2 Logitech Bus Mouse 2-button */
|
||||
&mouse_bus_msinport, /* 3 Microsoft InPort Mouse */
|
||||
&mouse_serial_msystems, /* 4 Mouse Systems Serial Mouse */
|
||||
&mouse_serial_microsoft, /* 5 Microsoft Serial Mouse */
|
||||
&mouse_serial_logitech, /* 6 Logitech 3-button Serial Mouse */
|
||||
&mouse_serial_mswheel, /* 7 Microsoft Serial Wheel Mouse */
|
||||
&mouse_ps2_2button, /* 8 PS/2 Mouse 2-button */
|
||||
&mouse_ps2_intellimouse, /* 9 PS/2 Intellimouse 3-button */
|
||||
#if 0
|
||||
&mouse_bus_genius, /* 10 Genius Bus Mouse */
|
||||
#endif
|
||||
static device_t mouse_none_device = {
|
||||
"None",
|
||||
0, MOUSE_TYPE_NONE,
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
static mouse_t *mouse_curr;
|
||||
static device_t mouse_internal_device = {
|
||||
"Internal Mouse",
|
||||
0, MOUSE_TYPE_INTERNAL,
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
static mouse_t mouse_devices[] = {
|
||||
{ "none", &mouse_none_device },
|
||||
{ "internal", &mouse_internal_device },
|
||||
{ "logibus", &mouse_logibus_device },
|
||||
{ "msbus", &mouse_msinport_device },
|
||||
#if 0
|
||||
{ "genibus", &mouse_genibus_device },
|
||||
#endif
|
||||
{ "mssystems", &mouse_mssystems_device },
|
||||
{ "msserial", &mouse_msserial_device },
|
||||
{ "lserial", &mouse_lserial_device },
|
||||
{ "mswheel", &mouse_mswheel_device },
|
||||
{ "ps2", &mouse_ps2_device },
|
||||
{ "intellimouse", &mouse_ps2ms_device },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
|
||||
static device_t *mouse_curr;
|
||||
static void *mouse_priv;
|
||||
|
||||
|
||||
/* Initialize the mouse module. */
|
||||
void
|
||||
mouse_emu_init(void)
|
||||
mouse_init(void)
|
||||
{
|
||||
/* Initialize local data. */
|
||||
mouse_x = mouse_y = mouse_z = 0;
|
||||
mouse_buttons = 0x00;
|
||||
|
||||
mouse_curr = mouse_list[mouse_type];
|
||||
|
||||
if (mouse_curr == NULL || mouse_curr->init == NULL) return;
|
||||
|
||||
mouse_priv = mouse_curr->init(mouse_curr);
|
||||
mouse_type = MOUSE_TYPE_NONE;
|
||||
mouse_curr = NULL;
|
||||
mouse_priv = NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
mouse_emu_close(void)
|
||||
mouse_close(void)
|
||||
{
|
||||
if (mouse_curr == NULL || mouse_curr->close == NULL) return;
|
||||
if (mouse_curr == NULL) return;
|
||||
|
||||
mouse_curr->close(mouse_priv);
|
||||
if (mouse_curr->close != NULL)
|
||||
mouse_curr->close(mouse_priv);
|
||||
|
||||
mouse_curr = NULL;
|
||||
mouse_priv = NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
mouse_reset(void)
|
||||
{
|
||||
pclog("MOUSE: reset(type=%d)\n", mouse_type);
|
||||
|
||||
/* Close previous mouse, if open. */
|
||||
mouse_close();
|
||||
|
||||
/* Clear local data. */
|
||||
mouse_x = mouse_y = mouse_z = 0;
|
||||
mouse_buttons = 0x00;
|
||||
|
||||
/* If no mouse configured, we're done. */
|
||||
if (mouse_type == 0) return;
|
||||
|
||||
mouse_curr = mouse_devices[mouse_type].device;
|
||||
|
||||
if (mouse_curr != NULL)
|
||||
mouse_priv = device_add(mouse_curr);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
mouse_process(void)
|
||||
{
|
||||
static int poll_delay = 2;
|
||||
|
||||
if (mouse_curr == NULL) return;
|
||||
|
||||
if (--poll_delay) return;
|
||||
|
||||
mouse_poll_host();
|
||||
mouse_poll();
|
||||
|
||||
if (mouse_curr->poll != NULL)
|
||||
mouse_curr->poll(mouse_x,mouse_y,mouse_z,mouse_buttons, mouse_priv);
|
||||
if (mouse_curr->available != NULL) {
|
||||
mouse_curr->available(mouse_x,mouse_y,mouse_z,mouse_buttons, mouse_priv);
|
||||
|
||||
/* Reset mouse deltas. */
|
||||
mouse_x = mouse_y = mouse_z = 0;
|
||||
/* Reset mouse deltas. */
|
||||
mouse_x = mouse_y = mouse_z = 0;
|
||||
}
|
||||
|
||||
poll_delay = 2;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
mouse_setpoll(uint8_t (*func)(int,int,int,int,void *), void *arg)
|
||||
mouse_setpoll(int (*func)(int,int,int,int,void *), void *arg)
|
||||
{
|
||||
if (mouse_type != MOUSE_TYPE_INTERNAL) return;
|
||||
|
||||
mouse_curr->poll = func;
|
||||
mouse_curr->available = func;
|
||||
mouse_priv = arg;
|
||||
}
|
||||
|
||||
@@ -128,17 +163,14 @@ mouse_setpoll(uint8_t (*func)(int,int,int,int,void *), void *arg)
|
||||
char *
|
||||
mouse_get_name(int mouse)
|
||||
{
|
||||
if (!mouse_list[mouse])
|
||||
return(NULL);
|
||||
|
||||
return((char *)mouse_list[mouse]->name);
|
||||
return((char *)mouse_devices[mouse].device->name);
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
mouse_get_internal_name(int mouse)
|
||||
{
|
||||
return((char *)mouse_list[mouse]->internal_name);
|
||||
return((char *)mouse_devices[mouse].internal_name);
|
||||
}
|
||||
|
||||
|
||||
@@ -147,9 +179,10 @@ mouse_get_from_internal_name(char *s)
|
||||
{
|
||||
int c = 0;
|
||||
|
||||
while (mouse_list[c] != NULL) {
|
||||
if (!strcmp((char *)mouse_list[c]->internal_name, s))
|
||||
while (mouse_devices[c].internal_name != NULL) {
|
||||
if (! strcmp((char *)mouse_devices[c].internal_name, s)) {
|
||||
return(c);
|
||||
}
|
||||
c++;
|
||||
}
|
||||
|
||||
@@ -160,7 +193,7 @@ mouse_get_from_internal_name(char *s)
|
||||
int
|
||||
mouse_get_type(int mouse)
|
||||
{
|
||||
return(mouse_list[mouse]->type);
|
||||
return(mouse_devices[mouse].device->local);
|
||||
}
|
||||
|
||||
|
||||
@@ -168,5 +201,5 @@ mouse_get_type(int mouse)
|
||||
int
|
||||
mouse_get_ndev(void)
|
||||
{
|
||||
return(sizeof(mouse_list)/sizeof(mouse_t *) - 1);
|
||||
return((sizeof(mouse_devices)/sizeof(mouse_t)) - 1);
|
||||
}
|
||||
|
||||
71
src/mouse.h
71
src/mouse.h
@@ -8,69 +8,66 @@
|
||||
*
|
||||
* Definitions for the mouse driver.
|
||||
*
|
||||
* Version: @(#)mouse.h 1.0.8 2017/11/03
|
||||
* Version: @(#)mouse.h 1.0.10 2017/12/03
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
*
|
||||
* Copyright 2008-2017 Sarah Walker.
|
||||
* Copyright 2016,2017 Miran Grca.
|
||||
* Copyright 2017 Fred N. van Kempen.
|
||||
*/
|
||||
#ifndef EMU_MOUSE_H
|
||||
# define EMU_MOUSE_H
|
||||
|
||||
|
||||
#define SERMOUSE_PORT 1 /* attach to Serial1 */
|
||||
|
||||
#define MOUSE_TYPE_NONE 0 /* no mouse configured */
|
||||
#define MOUSE_TYPE_INTERNAL 1 /* machine has internal mouse */
|
||||
#define MOUSE_TYPE_LOGIBUS 2 /* Logitech/ATI Bus Mouse */
|
||||
#define MOUSE_TYPE_INPORT 3 /* Microsoft InPort Mouse */
|
||||
#define MOUSE_TYPE_MSYSTEMS 4 /* Mouse Systems mouse */
|
||||
#define MOUSE_TYPE_MICROSOFT 5 /* Microsoft Serial Mouse */
|
||||
#define MOUSE_TYPE_LOGITECH 6 /* Logitech Serial Mouse */
|
||||
#define MOUSE_TYPE_MSWHEEL 7 /* Serial Wheel Mouse */
|
||||
#define MOUSE_TYPE_PS2 8 /* IBM PS/2 series Bus Mouse */
|
||||
#define MOUSE_TYPE_PS2_MS 9 /* Microsoft Intellimouse PS/2 */
|
||||
#if 0
|
||||
# define MOUSE_TYPE_GENIUS 10 /* Genius Bus Mouse */
|
||||
# define MOUSE_TYPE_GENIBUS 4 /* Genius Bus Mouse */
|
||||
#endif
|
||||
#define MOUSE_TYPE_MSYSTEMS 5 /* Mouse Systems mouse */
|
||||
#define MOUSE_TYPE_MICROSOFT 6 /* Microsoft Serial Mouse */
|
||||
#define MOUSE_TYPE_LOGITECH 7 /* Logitech Serial Mouse */
|
||||
#define MOUSE_TYPE_MSWHEEL 8 /* Serial Wheel Mouse */
|
||||
#define MOUSE_TYPE_PS2 9 /* IBM PS/2 series Bus Mouse */
|
||||
#define MOUSE_TYPE_PS2_MS 10 /* Microsoft Intellimouse PS/2 */
|
||||
|
||||
#define MOUSE_TYPE_MASK 0x0f
|
||||
#define MOUSE_TYPE_3BUTTON (1<<7) /* device has 3+ buttons */
|
||||
|
||||
|
||||
typedef struct _mouse_ {
|
||||
const char *name;
|
||||
const char *internal_name;
|
||||
int type;
|
||||
void *(*init)(struct _mouse_ *);
|
||||
void (*close)(void *p);
|
||||
uint8_t (*poll)(int x, int y, int z, int b, void *p);
|
||||
} mouse_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern int mouse_type;
|
||||
extern int mouse_x, mouse_y, mouse_z;
|
||||
extern int mouse_buttons;
|
||||
|
||||
|
||||
extern mouse_t mouse_bus_logitech;
|
||||
extern mouse_t mouse_bus_msinport;
|
||||
extern mouse_t mouse_serial_msystems;
|
||||
extern mouse_t mouse_serial_microsoft;
|
||||
extern mouse_t mouse_serial_logitech;
|
||||
extern mouse_t mouse_serial_mswheel;
|
||||
extern mouse_t mouse_ps2_2button;
|
||||
extern mouse_t mouse_ps2_intellimouse;
|
||||
#ifdef EMU_DEVICE_H
|
||||
extern device_t mouse_logibus_device;
|
||||
extern device_t mouse_msinport_device;
|
||||
#if 0
|
||||
extern device_t mouse_genibus_device;
|
||||
#endif
|
||||
extern device_t mouse_mssystems_device;
|
||||
extern device_t mouse_msserial_device;
|
||||
extern device_t mouse_lserial_device;
|
||||
extern device_t mouse_mswheel_device;
|
||||
extern device_t mouse_ps2_device;
|
||||
extern device_t mouse_ps2ms_device;
|
||||
|
||||
extern void *mouse_ps2_init(device_t *);
|
||||
#endif
|
||||
|
||||
extern void *mouse_ps2_init(void *);
|
||||
|
||||
extern void mouse_emu_init(void);
|
||||
extern void mouse_emu_close(void);
|
||||
extern void mouse_setpoll(uint8_t (*f)(int,int,int,int,void *), void *);
|
||||
extern void mouse_init(void);
|
||||
extern void mouse_reset(void);
|
||||
extern void mouse_process(void);
|
||||
extern void mouse_poll(void);
|
||||
extern void mouse_setpoll(int (*f)(int,int,int,int,void *), void *);
|
||||
|
||||
extern char *mouse_get_name(int mouse);
|
||||
extern char *mouse_get_internal_name(int mouse);
|
||||
@@ -78,5 +75,9 @@ extern int mouse_get_from_internal_name(char *s);
|
||||
extern int mouse_get_type(int mouse);
|
||||
extern int mouse_get_ndev(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /*EMU_MOUSE_H*/
|
||||
|
||||
732
src/mouse_bus.c
732
src/mouse_bus.c
@@ -30,20 +30,26 @@
|
||||
* reading of the DIP switches? Oh-well.
|
||||
*
|
||||
* NOTES: Verified with:
|
||||
* AMI WinBIOS 486 (OK, IRQ5 only)
|
||||
* Microsoft Mouse V2.00 (DOS V6.22)
|
||||
* Microsoft Mouse V9.1 (DOS V6.22)
|
||||
* AMI WinBIOS 486 (5A, no IRQ detect, OK, IRQ5 only)
|
||||
* Microsoft Mouse.com V2.00 (DOS V6.22, 5A, OK)
|
||||
* Microsoft Mouse.exe V9.1 (DOS V6.22, A5, OK)
|
||||
* Logitech LMouse.com V6.02 (DOS V6.22)
|
||||
* Logitech LMouse.com V6.43 (DOS V6.22)
|
||||
* Microsoft WfW V3.11 on DOS V6.22
|
||||
* GEOS V1.0: does not seem to work
|
||||
* GEOS V2.0: does not seem to work
|
||||
* GEOS V1.0 (OK, IRQ5 only)
|
||||
* GEOS V2.0 (OK, IRQ5 only)
|
||||
* Microsoft Windows 95 OSR2
|
||||
* Microsoft Windows 98 SE
|
||||
* Microsoft Windows NT 3.1
|
||||
* Microsoft Windows NT 3.51
|
||||
*
|
||||
* Based on an early driver for MINIX 1.5.
|
||||
* Based on the 86Box PS/2 mouse driver as a framework.
|
||||
*
|
||||
* Version: @(#)mouse_bus.c 1.0.23 2017/11/22
|
||||
* TODO: Re-integrate the InPort part. Currently,
|
||||
* only the Logitech part is considered to
|
||||
* be OK.
|
||||
*
|
||||
* Version: @(#)mouse_bus.c 1.0.24 2017/12/03
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
*
|
||||
@@ -59,111 +65,320 @@
|
||||
#include "io.h"
|
||||
#include "pic.h"
|
||||
#include "timer.h"
|
||||
#include "device.h"
|
||||
#include "mouse.h"
|
||||
|
||||
|
||||
#define BUSMOUSE_PORT 0x023c /* default */
|
||||
#define BUSMOUSE_IRQ 5 /* default (DOS,NT31) */
|
||||
#define BUSMOUSE_DEBUG 0
|
||||
|
||||
|
||||
#define ENABLE_3BTN 1 /* enable 3-button mode */
|
||||
#define MOUSE_PORT 0x023c /* default */
|
||||
#define MOUSE_IRQ 5 /* default (DOS,NT31) */
|
||||
#define MOUSE_DEBUG 2
|
||||
|
||||
|
||||
/* Our mouse device. */
|
||||
typedef struct mouse_bus {
|
||||
typedef struct mouse {
|
||||
const char *name; /* name of this device */
|
||||
int8_t type; /* type of this device */
|
||||
uint8_t flags; /* device flags */
|
||||
int8_t irq; /* IRQ channel to use */
|
||||
uint8_t flags; /* device flags */
|
||||
|
||||
uint8_t r_magic; /* MAGIC register */
|
||||
uint8_t r_ctrl; /* CONTROL register (WR) */
|
||||
uint8_t r_intr; /* INTSTAT register (RO) */
|
||||
uint8_t r_conf; /* CONFIG register */
|
||||
uint8_t r_magic, /* MAGIC register */
|
||||
r_ctrl, /* CONTROL register (WR) */
|
||||
r_conf, /* CONFIG register */
|
||||
r_cmd; /* (MS) current command */
|
||||
|
||||
uint8_t but;
|
||||
int16_t x, y; /* current mouse status */
|
||||
uint8_t seq; /* general counter */
|
||||
|
||||
uint8_t but, /* current mouse status */
|
||||
but_last;
|
||||
int8_t x, y;
|
||||
int8_t x_delay,
|
||||
y_delay;
|
||||
|
||||
int64_t timer; /* mouse event timer */
|
||||
|
||||
uint8_t (*read)(struct mouse_bus *, uint16_t);
|
||||
void (*write)(struct mouse_bus *, uint16_t, uint8_t);
|
||||
} mouse_bus_t;
|
||||
#define MOUSE_ENABLED 0x80 /* device is enabled for use */
|
||||
#define MOUSE_SCALED 0x40 /* enable delta scaling */
|
||||
#define MOUSE_FROZEN 0x01 /* do not update counters */
|
||||
uint8_t (*read)(struct mouse *, uint16_t);
|
||||
void (*write)(struct mouse *, uint16_t, uint8_t);
|
||||
} mouse_t;
|
||||
#define FLAG_INPORT 0x80 /* device is MS InPort */
|
||||
#define FLAG_3BTN 0x20 /* enable 3-button mode */
|
||||
#define FLAG_SCALED 0x10 /* enable delta scaling */
|
||||
#define FLAG_INTR 0x04 /* dev can send interrupts */
|
||||
#define FLAG_FROZEN 0x02 /* do not update counters */
|
||||
#define FLAG_ENABLED 0x01 /* dev is enabled for use */
|
||||
|
||||
|
||||
/* Definitions for Logitech. */
|
||||
#define MOUSE_DATA 0 /* DATA register */
|
||||
#define MOUSE_MAGIC 1 /* signature magic register */
|
||||
# define MAGIC_BYTE1 0xa5 /* most drivers use this */
|
||||
# define MAGIC_BYTE2 0x5a /* some drivers use this */
|
||||
#define MOUSE_CTRL 2 /* CTRL register */
|
||||
# define CTRL_FREEZE 0x80 /* do not sample when set */
|
||||
# define CTRL_RD_Y_HI 0x60 /* plus FREEZE */
|
||||
# define CTRL_RD_Y_LO 0x40 /* plus FREEZE */
|
||||
# define CTRL_RD_X_HI 0x20 /* plus FREEZE */
|
||||
# define CTRL_RD_X_LO 0x00 /* plus FREEZE */
|
||||
# define CTRL_RD_MASK 0x60
|
||||
# define CTRL_IDIS 0x10
|
||||
# define CTRL_IENB 0x00
|
||||
#define MOUSE_CONFIG 3 /* CONFIG register */
|
||||
#define LTMOUSE_DATA 0 /* DATA register */
|
||||
#define LTMOUSE_MAGIC 1 /* signature magic register */
|
||||
# define LTMAGIC_BYTE1 0xa5 /* most drivers use this */
|
||||
# define LTMAGIC_BYTE2 0x5a /* some drivers use this */
|
||||
#define LTMOUSE_CTRL 2 /* CTRL register */
|
||||
# define LTCTRL_FREEZE 0x80 /* do not sample when set */
|
||||
# define LTCTRL_RD_Y_HI 0x60
|
||||
# define LTCTRL_RD_Y_LO 0x40
|
||||
# define LTCTRL_RD_X_HI 0x20
|
||||
# define LTCTRL_RD_X_LO 0x00
|
||||
# define LTCTRL_RD_MASK 0x60
|
||||
# define LTCTRL_IDIS 0x10
|
||||
# define LTCTRL_IENB 0x00
|
||||
#define LTMOUSE_CONFIG 3 /* CONFIG register */
|
||||
|
||||
/* Definitions for Microsoft. */
|
||||
#define MSMOUSE_CTRL 0 /* CTRL register */
|
||||
# define MSCTRL_RESET 0x80 /* reset controller */
|
||||
# define MSCTRL_FREEZE 0x20 /* HOLD- freeze data */
|
||||
# define MSCTRL_IENB 0x01
|
||||
# define MSCTRL_COMMAND 0x07
|
||||
# define MSCTRL_RD_Y 0x02
|
||||
# define MSCTRL_RD_X 0x01
|
||||
# define MSCTRL_RD_BUT 0x00
|
||||
#define MSMOUSE_DATA 1 /* DATA register */
|
||||
# define MSDATA_BASE 0x10
|
||||
# define MSDATA_IRQ 0x01
|
||||
#define MSMOUSE_MAGIC 2 /* MAGIC register */
|
||||
# define MAGIC_MSBYTE1 0xde /* indicates MS InPort */
|
||||
# define MAGIC_MSBYTE2 0x12
|
||||
#define MSMOUSE_CONFIG 3 /* CONFIG register */
|
||||
|
||||
|
||||
/* Handle a WRITE to a LOGITECH register. */
|
||||
/* Reset the controller state. */
|
||||
static void
|
||||
lt_write(mouse_bus_t *ms, uint16_t port, uint8_t val)
|
||||
ms_reset(mouse_t *dev)
|
||||
{
|
||||
dev->flags &= 0xf0;
|
||||
|
||||
dev->seq = 0;
|
||||
|
||||
dev->x = dev->y = 0;
|
||||
dev->but = 0x00;
|
||||
|
||||
dev->flags |= FLAG_INTR;
|
||||
}
|
||||
|
||||
|
||||
/* Handle a WRITE to an InPort register. */
|
||||
static void
|
||||
ms_write(mouse_t *dev, uint16_t port, uint8_t val)
|
||||
{
|
||||
switch (port) {
|
||||
case MSMOUSE_CTRL:
|
||||
switch (val) {
|
||||
case MSCTRL_RESET:
|
||||
dev->r_ctrl = 0x00;
|
||||
dev->r_cmd = 0x00;
|
||||
break;
|
||||
|
||||
case MSCTRL_COMMAND:
|
||||
case MSCTRL_RD_BUT:
|
||||
case MSCTRL_RD_X:
|
||||
case MSCTRL_RD_Y:
|
||||
dev->r_cmd = val;
|
||||
break;
|
||||
|
||||
case 0x87:
|
||||
dev->r_ctrl = 0x00;
|
||||
dev->r_cmd = MSCTRL_COMMAND;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case MSMOUSE_DATA:
|
||||
picintc(1 << dev->irq);
|
||||
if (val == MSDATA_IRQ) {
|
||||
picint(1<<dev->irq);
|
||||
} else switch (dev->r_cmd) {
|
||||
case MSCTRL_COMMAND:
|
||||
dev->r_ctrl = val;
|
||||
if (val & MSCTRL_IENB)
|
||||
dev->flags |= FLAG_INTR;
|
||||
else
|
||||
dev->flags &= ~FLAG_INTR;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case MSMOUSE_MAGIC:
|
||||
break;
|
||||
|
||||
case MSMOUSE_CONFIG:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Handle a READ from an InPort register. */
|
||||
static uint8_t
|
||||
ms_read(mouse_t *dev, uint16_t port)
|
||||
{
|
||||
uint8_t ret = 0x00;
|
||||
|
||||
switch (port) {
|
||||
case MSMOUSE_CTRL:
|
||||
ret = dev->r_ctrl;
|
||||
break;
|
||||
|
||||
case MSMOUSE_DATA:
|
||||
switch (dev->r_cmd) {
|
||||
case MSCTRL_RD_BUT:
|
||||
ret = dev->but;
|
||||
ret |= 0x40;
|
||||
break;
|
||||
|
||||
case MSCTRL_RD_X:
|
||||
ret = dev->x;
|
||||
break;
|
||||
|
||||
case MSCTRL_RD_Y:
|
||||
ret = dev->y;
|
||||
break;
|
||||
|
||||
case MSCTRL_COMMAND:
|
||||
ret = dev->r_ctrl;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case MSMOUSE_MAGIC:
|
||||
if (dev->seq & 0x01)
|
||||
ret = MAGIC_MSBYTE2;
|
||||
else
|
||||
ret = MAGIC_MSBYTE1;
|
||||
dev->seq++;
|
||||
break;
|
||||
|
||||
case MSMOUSE_CONFIG:
|
||||
/* Not really present in real hardware. */
|
||||
break;
|
||||
}
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
||||
/* Called at 30hz */
|
||||
static void
|
||||
bm_timer(void *priv)
|
||||
{
|
||||
mouse_t *dev = (mouse_t *)priv;
|
||||
|
||||
dev->timer += ((1000000.0 / 30.0) * TIMER_USEC);
|
||||
|
||||
#if 0
|
||||
/* The controller updates the data on every interrupt
|
||||
We just don't copy it to the current_X if the 'hold' bit is set */
|
||||
if (dev->is_inport) {
|
||||
if ((dev->but & (1<<2)) ||
|
||||
((dev->but_last & (1<<2)) && !(dev->but & (1<<2))))
|
||||
dev->but |= (1<<5);
|
||||
if ((dev->but & (1<<1)) ||
|
||||
((dev->but_last & (1<<1)) && !(dev->but & (1<<1))))
|
||||
dev->but |= (1<<4);
|
||||
if ((dev->but & (1<<0)) ||
|
||||
((dev->but_last & (1<<0)) && !(dev->buttons & (1<<0))))
|
||||
dev->but |= (1<<3);
|
||||
dev->but_last = dev>but;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (dev->flags & FLAG_INTR)
|
||||
picint(1 << dev->irq);
|
||||
}
|
||||
|
||||
|
||||
/* Initialize the Microsoft Bus Mouse interface. */
|
||||
static void
|
||||
ms_init(mouse_t *dev)
|
||||
{
|
||||
/* Initialize registers. */
|
||||
dev->r_ctrl = 0x00;
|
||||
dev->r_conf = 0x00;
|
||||
|
||||
dev->flags |= FLAG_INPORT;
|
||||
|
||||
/* Initialize I/O handlers. */
|
||||
dev->read = ms_read;
|
||||
dev->write = ms_write;
|
||||
|
||||
timer_add(bm_timer, &dev->timer, TIMER_ALWAYS_ENABLED, dev);
|
||||
}
|
||||
|
||||
|
||||
/* Reset the controller state. */
|
||||
static void
|
||||
lt_reset(mouse_t *dev)
|
||||
{
|
||||
dev->flags &= 0xf0;
|
||||
|
||||
dev->r_magic = 0x00;
|
||||
dev->r_ctrl = (LTCTRL_IENB);
|
||||
dev->r_conf = 0x00;
|
||||
|
||||
dev->seq = 0;
|
||||
|
||||
dev->x = dev->y = 0;
|
||||
dev->but = 0x00;
|
||||
|
||||
dev->flags |= FLAG_INTR;
|
||||
}
|
||||
|
||||
|
||||
/* Handle a WRITE to a Logitech register. */
|
||||
static void
|
||||
lt_write(mouse_t *dev, uint16_t port, uint8_t val)
|
||||
{
|
||||
uint8_t b;
|
||||
|
||||
#if BUSMOUSE_DEBUG
|
||||
pclog("BUSMOUSE: lt_write(%d,%02x)\n", port, val);
|
||||
#endif
|
||||
|
||||
switch (port) {
|
||||
case MOUSE_DATA: /* [00] data register */
|
||||
case LTMOUSE_DATA: /* [00] data register */
|
||||
break;
|
||||
|
||||
case MOUSE_MAGIC: /* [01] magic data register */
|
||||
case LTMOUSE_MAGIC: /* [01] magic data register */
|
||||
switch(val) {
|
||||
case MAGIC_BYTE1:
|
||||
case MAGIC_BYTE2:
|
||||
ms->r_ctrl = (CTRL_IENB);
|
||||
ms->r_magic = val;
|
||||
ms->r_intr = 0x00;
|
||||
case LTMAGIC_BYTE1:
|
||||
case LTMAGIC_BYTE2:
|
||||
lt_reset(dev);
|
||||
dev->r_magic = val;
|
||||
dev->flags |= FLAG_ENABLED;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case MOUSE_CTRL: /* [02] control register */
|
||||
b = (ms->r_ctrl ^ val);
|
||||
if (b & CTRL_FREEZE) {
|
||||
if (val & CTRL_FREEZE) {
|
||||
case LTMOUSE_CTRL: /* [02] control register */
|
||||
b = (dev->r_ctrl ^ val);
|
||||
if (b & LTCTRL_FREEZE) {
|
||||
if (val & LTCTRL_FREEZE) {
|
||||
/* Hold the sampling while we do something. */
|
||||
ms->flags |= MOUSE_FROZEN;
|
||||
dev->flags |= FLAG_FROZEN;
|
||||
} else {
|
||||
/* Reset current state. */
|
||||
ms->x = ms->y = 0;
|
||||
if (ms->but)
|
||||
/* One more POLL for button-release. */
|
||||
ms->but = 0x80;
|
||||
ms->flags &= ~MOUSE_FROZEN;
|
||||
dev->flags &= ~FLAG_FROZEN;
|
||||
dev->x = dev->y = 0;
|
||||
if (dev->but)
|
||||
dev->but |= 0x80;
|
||||
dev->seq = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (b & CTRL_IDIS) {
|
||||
if (b & LTCTRL_IDIS) {
|
||||
/* Disable or enable interrupts. */
|
||||
/* (we don't do anything for that here..) */
|
||||
if (val & LTCTRL_IDIS)
|
||||
dev->flags &= ~FLAG_INTR;
|
||||
else
|
||||
dev->flags |= FLAG_INTR;
|
||||
}
|
||||
|
||||
/* Save new register value. */
|
||||
ms->r_ctrl = val;
|
||||
dev->r_ctrl = val;
|
||||
|
||||
/* Clear any pending interrupts. */
|
||||
picintc(1 << dev->irq);
|
||||
break;
|
||||
|
||||
case MOUSE_CONFIG: /* [03] config register */
|
||||
ms->r_conf = val;
|
||||
case LTMOUSE_CONFIG: /* [03] config register */
|
||||
dev->r_conf = val;
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -172,140 +387,104 @@ lt_write(mouse_bus_t *ms, uint16_t port, uint8_t val)
|
||||
}
|
||||
|
||||
|
||||
/* Handle a READ from a LOGITECH register. */
|
||||
/* Handle a READ from a Logitech register. */
|
||||
static uint8_t
|
||||
lt_read(mouse_bus_t *ms, uint16_t port)
|
||||
lt_read(mouse_t *dev, uint16_t port)
|
||||
{
|
||||
uint8_t r = 0xff;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
/* The GEOS drivers actually check this. */
|
||||
if (! (dev->flags & FLAG_ENABLED)) return(ret);
|
||||
|
||||
switch (port) {
|
||||
case MOUSE_DATA: /* [00] data register */
|
||||
if (! (ms->r_ctrl & CTRL_FREEZE)) {
|
||||
r = 0x00;
|
||||
} else switch(ms->r_ctrl & CTRL_RD_MASK) {
|
||||
case CTRL_RD_X_LO: /* X, low bits */
|
||||
/*
|
||||
* Some drivers expect the buttons to
|
||||
* be in this byte. Others want it in
|
||||
* the Y-LO byte. --FvK
|
||||
*/
|
||||
r = 0x07;
|
||||
if (ms->but & 0x01) /*LEFT*/
|
||||
r &= ~0x04;
|
||||
if (ms->but & 0x02) /*RIGHT*/
|
||||
r &= ~0x01;
|
||||
#if ENABLE_3BTN
|
||||
if (ms->but & 0x04) /*MIDDLE*/
|
||||
r &= ~0x02;
|
||||
#endif
|
||||
r <<= 5;
|
||||
r |= (ms->x & 0x0f);
|
||||
case LTMOUSE_DATA: /* [00] data register */
|
||||
/*
|
||||
* Regardless of which subcommand used, the first
|
||||
* one has to return the state of the buttons.
|
||||
*/
|
||||
if (! dev->seq) {
|
||||
ret = 0x07;
|
||||
if (dev->but & 0x01) /*LEFT*/
|
||||
ret &= ~0x04;
|
||||
if (dev->but & 0x02) /*RIGHT*/
|
||||
ret &= ~0x01;
|
||||
if (dev->flags & FLAG_3BTN)
|
||||
if (dev->but & 0x04) /*MIDDLE*/
|
||||
ret &= ~0x02;
|
||||
ret <<= 5;
|
||||
} else {
|
||||
dev->seq++;
|
||||
|
||||
ret = 0x00;
|
||||
}
|
||||
|
||||
switch(dev->r_ctrl & LTCTRL_RD_MASK) {
|
||||
case LTCTRL_RD_X_LO: /* X, low bits */
|
||||
ret |= (dev->x & 0x0f);
|
||||
break;
|
||||
|
||||
case CTRL_RD_X_HI: /* X, high bits */
|
||||
r = (ms->x >> 4) & 0x0f;
|
||||
case LTCTRL_RD_X_HI: /* X, high bits */
|
||||
ret |= (dev->x >> 4) & 0x0f;
|
||||
break;
|
||||
|
||||
case CTRL_RD_Y_LO: /* Y, low bits */
|
||||
r = (ms->y & 0x0f);
|
||||
case LTCTRL_RD_Y_LO: /* Y, low bits */
|
||||
ret |= (dev->y & 0x0f);
|
||||
break;
|
||||
|
||||
case CTRL_RD_Y_HI: /* Y, high bits */
|
||||
/*
|
||||
* Some drivers expect the buttons to
|
||||
* be in this byte. Others want it in
|
||||
* the X-LO byte. --FvK
|
||||
*/
|
||||
r = 0x07;
|
||||
if (ms->but & 0x01) /*LEFT*/
|
||||
r &= ~0x04;
|
||||
if (ms->but & 0x02) /*RIGHT*/
|
||||
r &= ~0x01;
|
||||
#if ENABLE_3BTN
|
||||
if (ms->but & 0x04) /*MIDDLE*/
|
||||
r &= ~0x02;
|
||||
#endif
|
||||
r <<= 5;
|
||||
r |= (ms->y >> 4) & 0x0f;
|
||||
case LTCTRL_RD_Y_HI: /* Y, high bits */
|
||||
ret |= (dev->y >> 4) & 0x0f;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case MOUSE_MAGIC: /* [01] magic data register */
|
||||
case LTMOUSE_MAGIC: /* [01] magic data register */
|
||||
/*
|
||||
* Drivers write a magic byte to this register, usually
|
||||
* this is either 5A (AMI WinBIOS, MS Mouse 2.0-9.1) or
|
||||
* A5 (Windows drivers, UNIX/Linux/Minix.)
|
||||
*
|
||||
* It is unclear why there are two values, but the most
|
||||
* likely explanation is to distinguish two variants of
|
||||
* the hardware - one locked to a certain IRQ, and one
|
||||
* that has the DIP switch to set the IRQ value.
|
||||
* this is either 5A (AMI WinBIOS, MS Mouse 2.0) or
|
||||
* A5 (MS Mouse 9.1, Windows drivers, UNIX/Linux/Minix.)
|
||||
*/
|
||||
r = ms->r_magic;
|
||||
ret = dev->r_magic;
|
||||
break;
|
||||
|
||||
case MOUSE_CTRL: /* [02] control register */
|
||||
r = 0x0f;
|
||||
switch(ms->irq) {
|
||||
case 2:
|
||||
r &= ~0x08;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
r &= ~0x04;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
r &= ~0x02;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
r &= ~0x01;
|
||||
break;
|
||||
}
|
||||
if (ms->r_intr++ < 250) {
|
||||
/* Still settling, return invalid data. */
|
||||
r = (ms->r_ctrl & 0x10) ? r : 0x0f;
|
||||
case LTMOUSE_CTRL: /* [02] control register */
|
||||
if (dev->r_ctrl & LTCTRL_IDIS) {
|
||||
/* IDIS, no interrupts, return all-off. */
|
||||
ret = 0x0f;
|
||||
} else if (dev->seq++ == 0) {
|
||||
/* !IDIS, return DIP switch setting. */
|
||||
ret = 0x0f;
|
||||
switch(dev->irq) {
|
||||
case 2:
|
||||
ret &= ~0x08;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
ret &= ~0x04;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
ret &= ~0x02;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
ret &= ~0x01;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
ms->r_intr = 0;
|
||||
/* Return all-off (invalid data.) */
|
||||
ret = 0x0f;
|
||||
}
|
||||
break;
|
||||
|
||||
case MOUSE_CONFIG: /* [03] config register */
|
||||
r = ms->r_conf;
|
||||
case LTMOUSE_CONFIG: /* [03] config register */
|
||||
ret = dev->r_conf;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
#if BUSMOUSE_DEBUG > 1
|
||||
pclog("BUSMOUSE: lt_read(%d): %02x\n", port, r);
|
||||
#endif
|
||||
|
||||
return(r);
|
||||
}
|
||||
|
||||
|
||||
/* Initialize the Logitech Bus Mouse interface. */
|
||||
static void
|
||||
lt_init(mouse_bus_t *ms)
|
||||
{
|
||||
pclog("BUSMOUSE: %s, I/O=%04x, IRQ=%d\n",
|
||||
ms->name, BUSMOUSE_PORT, ms->irq);
|
||||
|
||||
/* Initialize registers. */
|
||||
ms->r_magic = 0x00;
|
||||
ms->r_conf = 0x00;
|
||||
ms->r_ctrl= 0x00;
|
||||
|
||||
/* Initialize I/O handlers. */
|
||||
ms->read = lt_read;
|
||||
ms->write = lt_write;
|
||||
|
||||
/* All done. */
|
||||
ms->flags = 0x00;
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
||||
@@ -313,9 +492,13 @@ lt_init(mouse_bus_t *ms)
|
||||
static void
|
||||
bm_write(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
mouse_bus_t *ms = (mouse_bus_t *)priv;
|
||||
mouse_t *dev = (mouse_t *)priv;
|
||||
|
||||
ms->write(ms, port-BUSMOUSE_PORT, val);
|
||||
#if MOUSE_DEBUG
|
||||
pclog("%s: write(%d,%02x)\n", dev->name, port-MOUSE_PORT, val);
|
||||
#endif
|
||||
|
||||
dev->write(dev, port-MOUSE_PORT, val);
|
||||
}
|
||||
|
||||
|
||||
@@ -323,57 +506,68 @@ bm_write(uint16_t port, uint8_t val, void *priv)
|
||||
static uint8_t
|
||||
bm_read(uint16_t port, void *priv)
|
||||
{
|
||||
mouse_bus_t *ms = (mouse_bus_t *)priv;
|
||||
uint8_t r;
|
||||
mouse_t *dev = (mouse_t *)priv;
|
||||
uint8_t ret;
|
||||
|
||||
r = ms->read(ms, port-BUSMOUSE_PORT);
|
||||
ret = dev->read(dev, port-MOUSE_PORT);
|
||||
|
||||
return(r);
|
||||
#if MOUSE_DEBUG > 1
|
||||
pclog("%s: read(%d): %02x\n", dev->name, port-MOUSE_PORT, ret);
|
||||
#endif
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
||||
/* The emulator calls us with an update on the host mouse device. */
|
||||
static uint8_t
|
||||
static int
|
||||
bm_poll(int x, int y, int z, int b, void *priv)
|
||||
{
|
||||
mouse_bus_t *ms = (mouse_bus_t *)priv;
|
||||
mouse_t *dev = (mouse_t *)priv;
|
||||
|
||||
/* Return early if nothing to do. */
|
||||
if (!x && !y && !z && (ms->but == b)) return(1);
|
||||
if (!x && !y && !z && (dev->but == b)) return(1);
|
||||
|
||||
/* If we are not interested, return. */
|
||||
if (!(ms->flags & MOUSE_ENABLED) || (ms->flags & MOUSE_FROZEN)) return(0);
|
||||
/* If we are not enabled, return. */
|
||||
if (! (dev->flags & FLAG_ENABLED)) return(0);
|
||||
|
||||
#if 0
|
||||
pclog("BUSMOUSE: poll(%d,%d,%d, %02x)\n", x, y, z, b);
|
||||
pclog("%s: poll(%d,%d,%d,%02x) %d\n",
|
||||
dev->name, x, y, z, b, !!(dev->flags & FLAG_FROZEN));
|
||||
#endif
|
||||
|
||||
if (ms->flags & MOUSE_SCALED) {
|
||||
/* Scale down the motion. */
|
||||
if ((x < -1) || (x > 1)) x >>= 1;
|
||||
if ((y < -1) || (y > 1)) y >>= 1;
|
||||
/* If we are frozen, do not update the state. */
|
||||
if (! (dev->flags & FLAG_FROZEN)) {
|
||||
if (dev->flags & FLAG_SCALED) {
|
||||
/* Scale down the motion. */
|
||||
if ((x < -1) || (x > 1)) x >>= 1;
|
||||
if ((y < -1) || (y > 1)) y >>= 1;
|
||||
}
|
||||
|
||||
/* Add the delta to our state. */
|
||||
x += dev->x;
|
||||
if (x > 127)
|
||||
x = 127;
|
||||
if (x < -128)
|
||||
x = -128;
|
||||
dev->x = (int8_t)x;
|
||||
|
||||
y += dev->y;
|
||||
if (y > 127)
|
||||
y = 127;
|
||||
if (y < -1287)
|
||||
y = -1287;
|
||||
dev->y = (int8_t)y;
|
||||
|
||||
dev->x_delay += x;
|
||||
dev->y_delay += y;
|
||||
|
||||
dev->but = b;
|
||||
}
|
||||
|
||||
/* Add the delta to our state. */
|
||||
x += ms->x;
|
||||
if (x > 1023)
|
||||
x = 1023;
|
||||
if (x < -1024)
|
||||
x = -1024;
|
||||
ms->x = (int16_t)x;
|
||||
|
||||
y += ms->y;
|
||||
if (y > 1023)
|
||||
y = 1023;
|
||||
if (y < -1024)
|
||||
y = -1024;
|
||||
ms->y = (int16_t)y;
|
||||
|
||||
ms->but = b;
|
||||
|
||||
/* All set, generate an interrupt. */
|
||||
if (! (ms->r_ctrl & CTRL_IDIS))
|
||||
picint(1 << ms->irq);
|
||||
/* Either way, generate an interrupt. */
|
||||
if ((dev->flags & FLAG_INTR) && !(dev->flags & FLAG_INPORT))
|
||||
picint(1 << dev->irq);
|
||||
|
||||
return(0);
|
||||
}
|
||||
@@ -383,56 +577,60 @@ bm_poll(int x, int y, int z, int b, void *priv)
|
||||
static void
|
||||
bm_close(void *priv)
|
||||
{
|
||||
mouse_bus_t *ms = (mouse_bus_t *)priv;
|
||||
mouse_t *dev = (mouse_t *)priv;
|
||||
|
||||
/* Release our I/O range. */
|
||||
io_removehandler(BUSMOUSE_PORT, 4,
|
||||
bm_read, NULL, NULL, bm_write, NULL, NULL, ms);
|
||||
io_removehandler(MOUSE_PORT, 4,
|
||||
bm_read, NULL, NULL, bm_write, NULL, NULL, dev);
|
||||
|
||||
free(ms);
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
/* Initialize the device for use by the user. */
|
||||
static void *
|
||||
bm_init(mouse_t *info)
|
||||
bm_init(device_t *info)
|
||||
{
|
||||
mouse_bus_t *ms;
|
||||
|
||||
ms = (mouse_bus_t *)malloc(sizeof(mouse_bus_t));
|
||||
memset(ms, 0x00, sizeof(mouse_bus_t));
|
||||
ms->name = info->name;
|
||||
ms->type = info->type;
|
||||
mouse_t *dev;
|
||||
|
||||
dev = (mouse_t *)malloc(sizeof(mouse_t));
|
||||
memset(dev, 0x00, sizeof(mouse_t));
|
||||
dev->name = info->name;
|
||||
dev->type = info->local;
|
||||
#if NOTYET
|
||||
ms->irq = device_get_config_int("irq");
|
||||
dev->irq = device_get_config_int("irq");
|
||||
#else
|
||||
ms->irq = config_get_int((char *)info->name, "irq", 0);
|
||||
dev->irq = config_get_int((char *)info->name, "irq", 0);
|
||||
#endif
|
||||
if (ms->irq == 0)
|
||||
ms->irq = BUSMOUSE_IRQ;
|
||||
if (dev->irq == 0)
|
||||
dev->irq = MOUSE_IRQ;
|
||||
|
||||
switch(ms->type) {
|
||||
pclog("%s: I/O=%04x, IRQ=%d\n", dev->name, MOUSE_PORT, dev->irq);
|
||||
|
||||
switch(dev->type) {
|
||||
case MOUSE_TYPE_LOGIBUS:
|
||||
lt_init(ms);
|
||||
/* Initialize registers. */
|
||||
lt_reset(dev);
|
||||
|
||||
/* Initialize I/O handlers. */
|
||||
dev->read = lt_read;
|
||||
dev->write = lt_write;
|
||||
break;
|
||||
|
||||
case MOUSE_TYPE_INPORT:
|
||||
// ms_init(ms);
|
||||
ms_init(dev);
|
||||
break;
|
||||
}
|
||||
ms->flags |= MOUSE_ENABLED;
|
||||
|
||||
/* Request an I/O range. */
|
||||
io_sethandler(BUSMOUSE_PORT, 4,
|
||||
bm_read, NULL, NULL, bm_write, NULL, NULL, ms);
|
||||
io_sethandler(MOUSE_PORT, 4,
|
||||
bm_read, NULL, NULL, bm_write, NULL, NULL, dev);
|
||||
|
||||
/* Return our private data to the I/O layer. */
|
||||
return(ms);
|
||||
return(dev);
|
||||
}
|
||||
|
||||
|
||||
#if NOTYET
|
||||
static device_config_t bm_config[] = {
|
||||
{
|
||||
"irq", "IRQ", CONFIG_SELECTION, "", 2, {
|
||||
@@ -451,32 +649,72 @@ static device_config_t bm_config[] = {
|
||||
{
|
||||
""
|
||||
}
|
||||
},
|
||||
{
|
||||
"", "", -1
|
||||
}
|
||||
},
|
||||
{
|
||||
"", "", -1
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
mouse_t mouse_bus_logitech = {
|
||||
device_t mouse_logibus_device = {
|
||||
"Logitech Bus Mouse",
|
||||
"logibus",
|
||||
DEVICE_ISA,
|
||||
MOUSE_TYPE_LOGIBUS,
|
||||
bm_init,
|
||||
bm_close,
|
||||
bm_poll
|
||||
bm_init, bm_close, NULL,
|
||||
bm_poll, NULL, NULL, NULL,
|
||||
bm_config
|
||||
};
|
||||
|
||||
mouse_t mouse_bus_msinport = {
|
||||
device_t mouse_msinport_device = {
|
||||
"Microsoft Bus Mouse (InPort)",
|
||||
"msbus",
|
||||
DEVICE_ISA,
|
||||
MOUSE_TYPE_INPORT,
|
||||
bm_init,
|
||||
bm_close,
|
||||
bm_poll
|
||||
bm_init, bm_close, NULL,
|
||||
bm_poll, NULL, NULL, NULL,
|
||||
bm_config
|
||||
};
|
||||
|
||||
|
||||
#if 0
|
||||
@@@@@@
|
||||
void busmouse_update_mouse_data(void *priv)
|
||||
{
|
||||
mouse_bus_t *busmouse = (mouse_bus_t *)priv;
|
||||
|
||||
int delta_x, delta_y;
|
||||
int hold;
|
||||
|
||||
if (busmouse->x_delay > 127) {
|
||||
delta_x = 127;
|
||||
busmouse->x_delay -= 127;
|
||||
} else if (busmouse->x_delay < -128) {
|
||||
delta_x = -128;
|
||||
busmouse->x_delay += 128;
|
||||
} else {
|
||||
delta_x = busmouse->x_delay;
|
||||
busmouse->x_delay = 0;
|
||||
}
|
||||
if (busmouse->y_delay > 127) {
|
||||
delta_y = 127;
|
||||
busmouse->y_delay -= 127;
|
||||
} else if (busmouse->y_delay < -128) {
|
||||
delta_y = -128;
|
||||
busmouse->y_delay += 128;
|
||||
} else {
|
||||
delta_y = busmouse->y_delay;
|
||||
busmouse->y_delay = 0;
|
||||
}
|
||||
|
||||
if (busmouse->is_inport) {
|
||||
hold = (busmouse->control_val & INP_HOLD_COUNTER) > 0;
|
||||
} else {
|
||||
hold = (busmouse->control_val & HOLD_COUNTER) > 0;
|
||||
}
|
||||
if (!hold) {
|
||||
busmouse->x = (uint8_t) delta_x;
|
||||
busmouse->y = (uint8_t) delta_y;
|
||||
busmouse->but = busmouse->mouse_buttons;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
332
src/mouse_ps2.c
332
src/mouse_ps2.c
@@ -1,61 +1,79 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of PS/2 series Mouse devices.
|
||||
*
|
||||
* Version: @(#)mouse_ps2.c 1.0.2 2017/12/03
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
#include "86box.h"
|
||||
#include "config.h"
|
||||
#include "device.h"
|
||||
#include "keyboard.h"
|
||||
#include "mouse.h"
|
||||
#include "plat_mouse.h"
|
||||
|
||||
|
||||
#define MOUSE_ENABLE 0x20
|
||||
#define MOUSE_SCALE 0x10
|
||||
|
||||
|
||||
enum {
|
||||
MOUSE_STREAM,
|
||||
MOUSE_REMOTE,
|
||||
MOUSE_ECHO
|
||||
MODE_STREAM,
|
||||
MODE_REMOTE,
|
||||
MODE_ECHO
|
||||
};
|
||||
|
||||
|
||||
typedef struct {
|
||||
int mode;
|
||||
const char *name; /* name of this device */
|
||||
int8_t type; /* type of this device */
|
||||
|
||||
uint8_t flags;
|
||||
uint8_t resolution;
|
||||
uint8_t sample_rate;
|
||||
int mode;
|
||||
|
||||
uint8_t command;
|
||||
uint8_t flags;
|
||||
uint8_t resolution;
|
||||
uint8_t sample_rate;
|
||||
|
||||
int cd;
|
||||
uint8_t command;
|
||||
|
||||
int x, y, z, b;
|
||||
int x, y, z, b;
|
||||
|
||||
int is_intellimouse;
|
||||
int intellimouse_mode;
|
||||
|
||||
uint8_t last_data[6];
|
||||
} mouse_ps2_t;
|
||||
uint8_t last_data[6];
|
||||
} mouse_t;
|
||||
#define FLAG_INTELLI 0x80 /* device is IntelliMouse */
|
||||
#define FLAG_INTMODE 0x40 /* using Intellimouse mode */
|
||||
#define FLAG_SCALED 0x20 /* enable delta scaling */
|
||||
#define FLAG_ENABLED 0x10 /* dev is enabled for use */
|
||||
#define FLAG_CTRLDAT 0x08 /* ctrl or data mode */
|
||||
|
||||
|
||||
int mouse_scan = 0;
|
||||
|
||||
|
||||
static void
|
||||
mouse_ps2_write(uint8_t val, void *priv)
|
||||
ps2_write(uint8_t val, void *priv)
|
||||
{
|
||||
mouse_ps2_t *ms = (mouse_ps2_t *)priv;
|
||||
|
||||
if (ms->cd) {
|
||||
ms->cd = 0;
|
||||
switch (ms->command) {
|
||||
case 0xe8: /*Set mouse resolution*/
|
||||
ms->resolution = val;
|
||||
mouse_t *dev = (mouse_t *)priv;
|
||||
uint8_t temp;
|
||||
|
||||
if (dev->flags & FLAG_CTRLDAT) {
|
||||
dev->flags &= ~FLAG_CTRLDAT;
|
||||
|
||||
switch (dev->command) {
|
||||
case 0xe8: /* set mouse resolution */
|
||||
dev->resolution = val;
|
||||
keyboard_at_adddata_mouse(0xfa);
|
||||
break;
|
||||
|
||||
case 0xf3: /*Set sample rate*/
|
||||
ms->sample_rate = val;
|
||||
|
||||
case 0xf3: /* set sample rate */
|
||||
dev->sample_rate = val;
|
||||
keyboard_at_adddata_mouse(0xfa);
|
||||
break;
|
||||
|
||||
@@ -63,66 +81,64 @@ mouse_ps2_write(uint8_t val, void *priv)
|
||||
keyboard_at_adddata_mouse(0xfc);
|
||||
}
|
||||
} else {
|
||||
uint8_t temp;
|
||||
dev->command = val;
|
||||
|
||||
ms->command = val;
|
||||
switch (ms->command) {
|
||||
case 0xe6: /*Set scaling to 1:1*/
|
||||
ms->flags &= ~MOUSE_SCALE;
|
||||
switch (dev->command) {
|
||||
case 0xe6: /* set scaling to 1:1 */
|
||||
dev->flags &= ~FLAG_SCALED;
|
||||
keyboard_at_adddata_mouse(0xfa);
|
||||
break;
|
||||
|
||||
case 0xe7: /*Set scaling to 2:1*/
|
||||
ms->flags |= MOUSE_SCALE;
|
||||
case 0xe7: /* set scaling to 2:1 */
|
||||
dev->flags |= FLAG_SCALED;
|
||||
keyboard_at_adddata_mouse(0xfa);
|
||||
break;
|
||||
|
||||
case 0xe8: /*Set mouse resolution*/
|
||||
ms->cd = 1;
|
||||
case 0xe8: /* set mouse resolution */
|
||||
dev->flags |= FLAG_CTRLDAT;
|
||||
keyboard_at_adddata_mouse(0xfa);
|
||||
break;
|
||||
|
||||
case 0xe9: /*Status request*/
|
||||
case 0xe9: /* status request */
|
||||
keyboard_at_adddata_mouse(0xfa);
|
||||
temp = ms->flags;
|
||||
if (mouse_buttons & 1)
|
||||
temp |= 1;
|
||||
if (mouse_buttons & 2)
|
||||
temp |= 2;
|
||||
if (mouse_buttons & 4)
|
||||
temp |= 3;
|
||||
temp = (dev->flags & 0x3f);
|
||||
if (mouse_buttons & 0x01)
|
||||
temp |= 0x01;
|
||||
if (mouse_buttons & 0x02)
|
||||
temp |= 0x02;
|
||||
if (mouse_buttons & 0x04)
|
||||
temp |= 0x03;
|
||||
keyboard_at_adddata_mouse(temp);
|
||||
keyboard_at_adddata_mouse(ms->resolution);
|
||||
keyboard_at_adddata_mouse(ms->sample_rate);
|
||||
keyboard_at_adddata_mouse(dev->resolution);
|
||||
keyboard_at_adddata_mouse(dev->sample_rate);
|
||||
break;
|
||||
|
||||
case 0xf2: /*Read ID*/
|
||||
case 0xf2: /* read ID */
|
||||
keyboard_at_adddata_mouse(0xfa);
|
||||
if (ms->intellimouse_mode)
|
||||
if (dev->flags & FLAG_INTMODE)
|
||||
keyboard_at_adddata_mouse(0x03);
|
||||
else
|
||||
else
|
||||
keyboard_at_adddata_mouse(0x00);
|
||||
break;
|
||||
|
||||
case 0xf3: /*Set command mode*/
|
||||
ms->cd = 1;
|
||||
case 0xf3: /* set command mode */
|
||||
dev->flags |= FLAG_CTRLDAT;
|
||||
keyboard_at_adddata_mouse(0xfa);
|
||||
break;
|
||||
|
||||
case 0xf4: /*Enable*/
|
||||
ms->flags |= MOUSE_ENABLE;
|
||||
case 0xf4: /* enable */
|
||||
dev->flags |= FLAG_ENABLED;
|
||||
keyboard_at_adddata_mouse(0xfa);
|
||||
break;
|
||||
|
||||
case 0xf5: /*Disable*/
|
||||
ms->flags &= ~MOUSE_ENABLE;
|
||||
case 0xf5: /* disable */
|
||||
dev->flags &= ~FLAG_ENABLED;
|
||||
keyboard_at_adddata_mouse(0xfa);
|
||||
break;
|
||||
|
||||
case 0xff: /*Reset*/
|
||||
ms->mode = MOUSE_STREAM;
|
||||
ms->flags = 0;
|
||||
ms->intellimouse_mode = 0;
|
||||
case 0xff: /* reset */
|
||||
dev->mode = MODE_STREAM;
|
||||
dev->flags &= 0x80;
|
||||
keyboard_at_adddata_mouse(0xfa);
|
||||
keyboard_at_adddata_mouse(0xaa);
|
||||
keyboard_at_adddata_mouse(0x00);
|
||||
@@ -133,120 +149,150 @@ mouse_ps2_write(uint8_t val, void *priv)
|
||||
}
|
||||
}
|
||||
|
||||
if (ms->is_intellimouse) {
|
||||
int c;
|
||||
if (dev->flags & FLAG_INTELLI) {
|
||||
for (temp=0; temp<5; temp++)
|
||||
dev->last_data[temp] = dev->last_data[temp+1];
|
||||
dev->last_data[5] = val;
|
||||
|
||||
for (c = 0; c < 5; c++)
|
||||
ms->last_data[c] = ms->last_data[c+1];
|
||||
ms->last_data[5] = val;
|
||||
|
||||
if (ms->last_data[0] == 0xf3 && ms->last_data[1] == 0xc8 &&
|
||||
ms->last_data[2] == 0xf3 && ms->last_data[3] == 0x64 &&
|
||||
ms->last_data[4] == 0xf3 && ms->last_data[5] == 0x50)
|
||||
ms->intellimouse_mode = 1;
|
||||
if (dev->last_data[0] == 0xf3 && dev->last_data[1] == 0xc8 &&
|
||||
dev->last_data[2] == 0xf3 && dev->last_data[3] == 0x64 &&
|
||||
dev->last_data[4] == 0xf3 && dev->last_data[5] == 0x50)
|
||||
dev->flags |= FLAG_INTMODE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
mouse_ps2_poll(int x, int y, int z, int b, void *priv)
|
||||
static int
|
||||
ps2_poll(int x, int y, int z, int b, void *priv)
|
||||
{
|
||||
mouse_ps2_t *ms = (mouse_ps2_t *)priv;
|
||||
uint8_t packet[3] = {0x08, 0, 0};
|
||||
mouse_t *dev = (mouse_t *)priv;
|
||||
uint8_t buff[3];
|
||||
|
||||
if (!x && !y && !z && b == ms->b) return(0xff);
|
||||
if (!x && !y && !z && b == dev->b) return(0xff);
|
||||
|
||||
if (! (dev->flags & FLAG_ENABLED)) return(0xff);
|
||||
|
||||
if (! mouse_scan) return(0xff);
|
||||
|
||||
ms->x += x;
|
||||
ms->y -= y;
|
||||
ms->z -= z;
|
||||
if (ms->mode == MOUSE_STREAM && (ms->flags & MOUSE_ENABLE) &&
|
||||
((mouse_queue_end - mouse_queue_start) & 0xf) < 13) {
|
||||
ms->b = b;
|
||||
// pclog("Send packet : %i %i\n", ps2_x, ps2_y);
|
||||
if (ms->x > 255)
|
||||
ms->x = 255;
|
||||
if (ms->x < -256)
|
||||
ms->x = -256;
|
||||
if (ms->y > 255)
|
||||
ms->y = 255;
|
||||
if (ms->y < -256)
|
||||
ms->y = -256;
|
||||
if (ms->z < -8)
|
||||
ms->z = -8;
|
||||
if (ms->z > 7)
|
||||
ms->z = 7;
|
||||
if (ms->x < 0)
|
||||
packet[0] |= 0x10;
|
||||
if (ms->y < 0)
|
||||
packet[0] |= 0x20;
|
||||
if (mouse_buttons & 1)
|
||||
packet[0] |= 1;
|
||||
if (mouse_buttons & 2)
|
||||
packet[0] |= 2;
|
||||
if ((mouse_buttons & 4) &&
|
||||
(mouse_get_type(mouse_type) & MOUSE_TYPE_3BUTTON)) packet[0] |= 4;
|
||||
packet[1] = ms->x & 0xff;
|
||||
packet[2] = ms->y & 0xff;
|
||||
dev->x += x;
|
||||
dev->y -= y;
|
||||
dev->z -= z;
|
||||
if ((dev->mode == MODE_STREAM) &&
|
||||
((mouse_queue_end-mouse_queue_start) & 0x0f) < 13) {
|
||||
dev->b = b;
|
||||
|
||||
keyboard_at_adddata_mouse(packet[0]);
|
||||
keyboard_at_adddata_mouse(packet[1]);
|
||||
keyboard_at_adddata_mouse(packet[2]);
|
||||
if (ms->intellimouse_mode)
|
||||
keyboard_at_adddata_mouse(ms->z);
|
||||
if (dev->x > 255) dev->x = 255;
|
||||
if (dev->x < -256) dev->x = -256;
|
||||
if (dev->y > 255) dev->y = 255;
|
||||
if (dev->y < -256) dev->y = -256;
|
||||
if (dev->z < -8) dev->z = -8;
|
||||
if (dev->z > 7) dev->z = 7;
|
||||
|
||||
ms->x = ms->y = ms->z = 0;
|
||||
memset(buff, 0x00, sizeof(buff));
|
||||
buff[0] = 0x08;
|
||||
if (dev->x < 0)
|
||||
buff[0] |= 0x10;
|
||||
if (dev->y < 0)
|
||||
buff[0] |= 0x20;
|
||||
if (mouse_buttons & 0x01)
|
||||
buff[0] |= 0x01;
|
||||
if (mouse_buttons & 0x02)
|
||||
buff[0] |= 0x02;
|
||||
if (dev->flags & FLAG_INTELLI) {
|
||||
if (mouse_buttons & 0x04)
|
||||
buff[0] |= 0x04;
|
||||
}
|
||||
buff[1] = (dev->x & 0xff);
|
||||
buff[2] = (dev->y & 0xff);
|
||||
|
||||
keyboard_at_adddata_mouse(buff[0]);
|
||||
keyboard_at_adddata_mouse(buff[1]);
|
||||
keyboard_at_adddata_mouse(buff[2]);
|
||||
if (dev->flags & FLAG_INTELLI)
|
||||
keyboard_at_adddata_mouse(dev->z);
|
||||
|
||||
dev->x = dev->y = dev->z = 0;
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/* We also get called from the various machines. */
|
||||
/*
|
||||
* Initialize the device for use by the user.
|
||||
*
|
||||
* We also get called from the various machines.
|
||||
*/
|
||||
void *
|
||||
mouse_ps2_init(void *arg)
|
||||
mouse_ps2_init(device_t *info)
|
||||
{
|
||||
mouse_ps2_t *ms = (mouse_ps2_t *)malloc(sizeof(mouse_ps2_t));
|
||||
mouse_t *info = (mouse_t *)arg;
|
||||
mouse_t *dev;
|
||||
|
||||
memset(ms, 0x00, sizeof(mouse_ps2_t));
|
||||
dev = (mouse_t *)malloc(sizeof(mouse_t));
|
||||
memset(dev, 0x00, sizeof(mouse_t));
|
||||
dev->name = info->name;
|
||||
dev->type = info->local;
|
||||
|
||||
ms->cd = 0;
|
||||
ms->flags = 0;
|
||||
ms->mode = MOUSE_STREAM;
|
||||
if ((info != NULL) && (info->type & MOUSE_TYPE_3BUTTON))
|
||||
ms->is_intellimouse = 1;
|
||||
dev->mode = MODE_STREAM;
|
||||
if (dev->type & MOUSE_TYPE_3BUTTON)
|
||||
dev->flags |= FLAG_INTELLI;
|
||||
|
||||
keyboard_at_set_mouse(mouse_ps2_write, ms);
|
||||
/* Hook into the general AT Keyboard driver. */
|
||||
keyboard_at_set_mouse(ps2_write, dev);
|
||||
|
||||
return(ms);
|
||||
pclog("%s: buttons=%d\n", dev->name, (dev->flags & FLAG_INTELLI)? 3 : 2);
|
||||
|
||||
/* Return our private data to the I/O layer. */
|
||||
return(dev);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
mouse_ps2_close(void *priv)
|
||||
static void
|
||||
ps2_close(void *priv)
|
||||
{
|
||||
mouse_ps2_t *ms = (mouse_ps2_t *)priv;
|
||||
mouse_t *dev = (mouse_t *)priv;
|
||||
|
||||
free(ms);
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
mouse_t mouse_ps2_2button = {
|
||||
"Standard 2-button mouse (PS/2)",
|
||||
"ps2",
|
||||
static device_config_t ps2_config[] = {
|
||||
{
|
||||
"buttons", "Buttons", CONFIG_SELECTION, "", 2, {
|
||||
{
|
||||
"Two", 2
|
||||
},
|
||||
{
|
||||
"Three", 3
|
||||
},
|
||||
{
|
||||
"Wheel", 4
|
||||
},
|
||||
{
|
||||
""
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"", "", -1
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
device_t mouse_ps2_device = {
|
||||
"Standard 2-button PS/2 Mouse",
|
||||
0,
|
||||
MOUSE_TYPE_PS2,
|
||||
(void *(*)(mouse_t *))mouse_ps2_init,
|
||||
mouse_ps2_close,
|
||||
mouse_ps2_poll
|
||||
mouse_ps2_init, ps2_close, NULL,
|
||||
ps2_poll, NULL, NULL, NULL,
|
||||
ps2_config
|
||||
};
|
||||
|
||||
mouse_t mouse_ps2_intellimouse = {
|
||||
"Microsoft Intellimouse (PS/2)",
|
||||
"intellimouse",
|
||||
device_t mouse_ps2ms_device = {
|
||||
"Microsoft 3-button PS/2 Mouse",
|
||||
0,
|
||||
MOUSE_TYPE_PS2 | MOUSE_TYPE_3BUTTON,
|
||||
(void *(*)(mouse_t *))mouse_ps2_init,
|
||||
mouse_ps2_close,
|
||||
mouse_ps2_poll
|
||||
mouse_ps2_init, ps2_close, NULL,
|
||||
ps2_poll, NULL, NULL, NULL,
|
||||
ps2_config
|
||||
};
|
||||
|
||||
@@ -8,9 +8,9 @@
|
||||
*
|
||||
* Implementation of Serial Mouse devices.
|
||||
*
|
||||
* Based on the 86Box Serial Mouse driver as a framework.
|
||||
* TODO: Add the Genius Serial Mouse.
|
||||
*
|
||||
* Version: @(#)mouse_serial.c 1.0.13 2017/11/13
|
||||
* Version: @(#)mouse_serial.c 1.0.14 2017/12/03
|
||||
*
|
||||
* Author: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
*/
|
||||
@@ -19,31 +19,46 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
#include "86box.h"
|
||||
#include "config.h"
|
||||
#include "device.h"
|
||||
#include "timer.h"
|
||||
#include "serial.h"
|
||||
#include "mouse.h"
|
||||
|
||||
|
||||
typedef struct mouse_serial_t {
|
||||
char *name;
|
||||
int8_t port,
|
||||
type;
|
||||
#define SERMOUSE_PORT 0 /* attach to Serial0 */
|
||||
|
||||
|
||||
typedef struct {
|
||||
const char *name; /* name of this device */
|
||||
int8_t type, /* type of this device */
|
||||
port;
|
||||
uint8_t flags; /* device flags */
|
||||
|
||||
int pos;
|
||||
int64_t delay;
|
||||
int oldb;
|
||||
|
||||
SERIAL *serial;
|
||||
} mouse_serial_t;
|
||||
} mouse_t;
|
||||
#define FLAG_INPORT 0x80 /* device is MS InPort */
|
||||
#define FLAG_3BTN 0x20 /* enable 3-button mode */
|
||||
#define FLAG_SCALED 0x10 /* enable delta scaling */
|
||||
#define FLAG_INTR 0x04 /* dev can send interrupts */
|
||||
#define FLAG_FROZEN 0x02 /* do not update counters */
|
||||
#define FLAG_ENABLED 0x01 /* dev is enabled for use */
|
||||
|
||||
|
||||
/* Callback from serial driver: RTS was toggled. */
|
||||
static void
|
||||
sermouse_callback(struct SERIAL *serial, void *priv)
|
||||
{
|
||||
mouse_serial_t *ms = (mouse_serial_t *)priv;
|
||||
mouse_t *dev = (mouse_t *)priv;
|
||||
|
||||
/* Start a timer to wake us up in a little while. */
|
||||
ms->pos = -1;
|
||||
ms->delay = 5000LL * (1LL << TIMER_SHIFT);
|
||||
dev->pos = -1;
|
||||
dev->delay = 5000LL * (1LL << TIMER_SHIFT);
|
||||
}
|
||||
|
||||
|
||||
@@ -51,63 +66,69 @@ sermouse_callback(struct SERIAL *serial, void *priv)
|
||||
static void
|
||||
sermouse_timer(void *priv)
|
||||
{
|
||||
mouse_serial_t *ms = (mouse_serial_t *)priv;
|
||||
mouse_t *dev = (mouse_t *)priv;
|
||||
|
||||
ms->delay = 0LL;
|
||||
dev->delay = 0LL;
|
||||
|
||||
if (ms->pos != -1) return;
|
||||
if (dev->pos != -1) return;
|
||||
|
||||
ms->pos = 0;
|
||||
switch(ms->type & MOUSE_TYPE_MASK) {
|
||||
dev->pos = 0;
|
||||
switch(dev->type & MOUSE_TYPE_MASK) {
|
||||
case MOUSE_TYPE_MSYSTEMS:
|
||||
/* Identifies Mouse Systems serial mouse. */
|
||||
serial_write_fifo(ms->serial, 'H');
|
||||
serial_write_fifo(dev->serial, 'H');
|
||||
break;
|
||||
|
||||
case MOUSE_TYPE_MICROSOFT:
|
||||
default:
|
||||
/* Identifies a two-button Microsoft Serial mouse. */
|
||||
serial_write_fifo(ms->serial, 'M');
|
||||
serial_write_fifo(dev->serial, 'M');
|
||||
break;
|
||||
|
||||
case MOUSE_TYPE_LOGITECH:
|
||||
/* Identifies a two-button Logitech Serial mouse. */
|
||||
serial_write_fifo(ms->serial, 'M');
|
||||
serial_write_fifo(ms->serial, '3');
|
||||
serial_write_fifo(dev->serial, 'M');
|
||||
serial_write_fifo(dev->serial, '3');
|
||||
break;
|
||||
|
||||
case MOUSE_TYPE_MSWHEEL:
|
||||
/* Identifies multi-button Microsoft Wheel Mouse. */
|
||||
serial_write_fifo(ms->serial, 'M');
|
||||
serial_write_fifo(ms->serial, 'Z');
|
||||
serial_write_fifo(dev->serial, 'M');
|
||||
serial_write_fifo(dev->serial, 'Z');
|
||||
break;
|
||||
|
||||
default:
|
||||
pclog("%s: unsupported mouse type %d?\n", dev->type);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
static int
|
||||
sermouse_poll(int x, int y, int z, int b, void *priv)
|
||||
{
|
||||
mouse_serial_t *ms = (mouse_serial_t *)priv;
|
||||
mouse_t *dev = (mouse_t *)priv;
|
||||
uint8_t buff[16];
|
||||
int len;
|
||||
|
||||
if (!x && !y && b == ms->oldb) return(1);
|
||||
if (!x && !y && b == dev->oldb) return(1);
|
||||
|
||||
ms->oldb = b;
|
||||
#if 0
|
||||
pclog("%s: poll(%d,%d,%d,%02x)\n", dev->name, x, y, z, b);
|
||||
#endif
|
||||
|
||||
if (x>127) x = 127;
|
||||
if (y>127) y = 127;
|
||||
if (x<-128) x = -128;
|
||||
if (y<-128) y = -128;
|
||||
dev->oldb = b;
|
||||
|
||||
if (x > 127) x = 127;
|
||||
if (y > 127) y = 127;
|
||||
if (x <- 128) x = -128;
|
||||
if (y <- 128) y = -128;
|
||||
|
||||
len = 0;
|
||||
switch(ms->type & MOUSE_TYPE_MASK) {
|
||||
switch(dev->type & MOUSE_TYPE_MASK) {
|
||||
case MOUSE_TYPE_MSYSTEMS:
|
||||
buff[0] = 0x80;
|
||||
buff[0] |= (b&0x01) ? 0x00 : 0x04; /* left button */
|
||||
buff[0] |= (b&0x02) ? 0x00 : 0x01; /* middle button */
|
||||
buff[0] |= (b&0x04) ? 0x00 : 0x02; /* right button */
|
||||
buff[0] |= (b & 0x01) ? 0x00 : 0x04; /* left button */
|
||||
buff[0] |= (b & 0x02) ? 0x00 : 0x01; /* middle button */
|
||||
buff[0] |= (b & 0x04) ? 0x00 : 0x02; /* right button */
|
||||
buff[1] = x;
|
||||
buff[2] = -y;
|
||||
buff[3] = x; /* same as byte 1 */
|
||||
@@ -117,10 +138,10 @@ sermouse_poll(int x, int y, int z, int b, void *priv)
|
||||
|
||||
case MOUSE_TYPE_MICROSOFT:
|
||||
buff[0] = 0x40;
|
||||
buff[0] |= (((y>>6)&0x03)<<2);
|
||||
buff[0] |= ((x>>6)&0x03);
|
||||
if (b&0x01) buff[0] |= 0x20;
|
||||
if (b&0x02) buff[0] |= 0x10;
|
||||
buff[0] |= (((y >> 6) & 0x03) << 2);
|
||||
buff[0] |= ((x >> 6) & 0x03);
|
||||
if (b & 0x01) buff[0] |= 0x20;
|
||||
if (b & 0x02) buff[0] |= 0x10;
|
||||
buff[1] = x & 0x3F;
|
||||
buff[2] = y & 0x3F;
|
||||
len = 3;
|
||||
@@ -128,14 +149,14 @@ sermouse_poll(int x, int y, int z, int b, void *priv)
|
||||
|
||||
case MOUSE_TYPE_LOGITECH:
|
||||
buff[0] = 0x40;
|
||||
buff[0] |= (((y>>6)&0x03)<<2);
|
||||
buff[0] |= ((x>>6)&0x03);
|
||||
if (b&0x01) buff[0] |= 0x20;
|
||||
if (b&0x02) buff[0] |= 0x10;
|
||||
buff[0] |= (((y >> 6) & 0x03) << 2);
|
||||
buff[0] |= ((x >> 6) & 0x03);
|
||||
if (b & 0x01) buff[0] |= 0x20;
|
||||
if (b & 0x02) buff[0] |= 0x10;
|
||||
buff[1] = x & 0x3F;
|
||||
buff[2] = y & 0x3F;
|
||||
len = 3;
|
||||
if (b&0x04) {
|
||||
if (b & 0x04) {
|
||||
buff[3] = 0x20;
|
||||
len++;
|
||||
}
|
||||
@@ -143,28 +164,28 @@ sermouse_poll(int x, int y, int z, int b, void *priv)
|
||||
|
||||
case MOUSE_TYPE_MSWHEEL:
|
||||
buff[0] = 0x40;
|
||||
buff[0] |= (((y>>6)&0x03)<<2);
|
||||
buff[0] |= ((x>>6)&0x03);
|
||||
if (b&0x01) buff[0] |= 0x20;
|
||||
if (b&0x02) buff[0] |= 0x10;
|
||||
buff[0] |= (((y >> 6) & 0x03) << 2);
|
||||
buff[0] |= ((x >> 6) & 0x03);
|
||||
if (b & 0x01) buff[0] |= 0x20;
|
||||
if (b & 0x02) buff[0] |= 0x10;
|
||||
buff[1] = x & 0x3F;
|
||||
buff[2] = y & 0x3F;
|
||||
buff[3] = z & 0x0F;
|
||||
if (b&0x04)
|
||||
if (b & 0x04)
|
||||
buff[3] |= 0x10;
|
||||
len = 4;
|
||||
|
||||
}
|
||||
|
||||
#if 0
|
||||
pclog("Mouse_Serial(%d): [", ms->type);
|
||||
pclog("%s: [", dev->name);
|
||||
for (b=0; b<len; b++) pclog(" %02X", buff[b]);
|
||||
pclog(" ] (%d)\n", len);
|
||||
#endif
|
||||
|
||||
/* Send the packet to the bottom-half of the attached port. */
|
||||
for (b=0; b<len; b++)
|
||||
serial_write_fifo(ms->serial, buff[b]);
|
||||
serial_write_fifo(dev->serial, buff[b]);
|
||||
|
||||
return(0);
|
||||
}
|
||||
@@ -173,70 +194,118 @@ sermouse_poll(int x, int y, int z, int b, void *priv)
|
||||
static void
|
||||
sermouse_close(void *priv)
|
||||
{
|
||||
mouse_serial_t *ms = (mouse_serial_t *)priv;
|
||||
mouse_t *dev = (mouse_t *)priv;
|
||||
|
||||
/* Detach serial port from the mouse. */
|
||||
serial1.rcr_callback = NULL;
|
||||
dev->serial->rcr_callback = NULL;
|
||||
dev->serial->rcr_callback_p = NULL;
|
||||
|
||||
free(ms);
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
/* Initialize the device for use by the user. */
|
||||
static void *
|
||||
sermouse_init(mouse_t *info)
|
||||
sermouse_init(device_t *info)
|
||||
{
|
||||
mouse_serial_t *ms = (mouse_serial_t *)malloc(sizeof(mouse_serial_t));
|
||||
memset(ms, 0x00, sizeof(mouse_serial_t));
|
||||
ms->name = (char *)info->name;
|
||||
ms->port = SERMOUSE_PORT;
|
||||
ms->type = info->type;
|
||||
mouse_t *dev;
|
||||
|
||||
dev = (mouse_t *)malloc(sizeof(mouse_t));
|
||||
memset(dev, 0x00, sizeof(mouse_t));
|
||||
dev->name = info->name;
|
||||
dev->type = info->local;
|
||||
|
||||
#if NOTYET
|
||||
dev->port = device_get_config_int("port");
|
||||
#else
|
||||
dev->port = config_get_int((char *)info->name, "port", SERMOUSE_PORT);
|
||||
#endif
|
||||
|
||||
/* Attach a serial port to the mouse. */
|
||||
ms->serial = &serial1;
|
||||
ms->serial->rcr_callback = sermouse_callback;
|
||||
ms->serial->rcr_callback_p = ms;
|
||||
if (dev->port == 0)
|
||||
dev->serial = &serial1;
|
||||
else
|
||||
dev->serial = &serial2;
|
||||
dev->serial->rcr_callback = sermouse_callback;
|
||||
dev->serial->rcr_callback_p = dev;
|
||||
|
||||
timer_add(sermouse_timer, &ms->delay, &ms->delay, ms);
|
||||
pclog("%s: port=COM%d\n", dev->name, dev->port+1);
|
||||
|
||||
return(ms);
|
||||
timer_add(sermouse_timer, &dev->delay, &dev->delay, dev);
|
||||
|
||||
/* Return our private data to the I/O layer. */
|
||||
return(dev);
|
||||
}
|
||||
|
||||
|
||||
mouse_t mouse_serial_msystems = {
|
||||
"Mouse Systems Mouse (serial)",
|
||||
"mssystems",
|
||||
static device_config_t sermouse_config[] = {
|
||||
{
|
||||
"buttons", "Buttons", CONFIG_SELECTION, "", 2, {
|
||||
{
|
||||
"Two", 2
|
||||
},
|
||||
{
|
||||
"Three", 3
|
||||
},
|
||||
{
|
||||
"Wheel", 4
|
||||
},
|
||||
{
|
||||
""
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"port", "Serial Port", CONFIG_SELECTION, "", 0, {
|
||||
{
|
||||
"COM1", 0
|
||||
},
|
||||
{
|
||||
"COM2", 1
|
||||
},
|
||||
{
|
||||
""
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"", "", -1
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
device_t mouse_mssystems_device = {
|
||||
"Mouse Systems Serial Mouse",
|
||||
0,
|
||||
MOUSE_TYPE_MSYSTEMS | MOUSE_TYPE_3BUTTON,
|
||||
sermouse_init,
|
||||
sermouse_close,
|
||||
sermouse_poll
|
||||
sermouse_init, sermouse_close, NULL,
|
||||
sermouse_poll, NULL, NULL, NULL,
|
||||
sermouse_config
|
||||
};
|
||||
|
||||
|
||||
mouse_t mouse_serial_microsoft = {
|
||||
"Microsoft 2-button mouse (serial)",
|
||||
"msserial",
|
||||
device_t mouse_msserial_device = {
|
||||
"Microsoft 2-button Serial Mouse",
|
||||
0,
|
||||
MOUSE_TYPE_MICROSOFT,
|
||||
sermouse_init,
|
||||
sermouse_close,
|
||||
sermouse_poll
|
||||
sermouse_init, sermouse_close, NULL,
|
||||
sermouse_poll, NULL, NULL, NULL,
|
||||
sermouse_config
|
||||
};
|
||||
|
||||
|
||||
mouse_t mouse_serial_logitech = {
|
||||
"Logitech 3-button mouse (serial)",
|
||||
"lserial",
|
||||
device_t mouse_lserial_device = {
|
||||
"Logitech 3-button Serial Mouse",
|
||||
0,
|
||||
MOUSE_TYPE_LOGITECH | MOUSE_TYPE_3BUTTON,
|
||||
sermouse_init,
|
||||
sermouse_close,
|
||||
sermouse_poll
|
||||
sermouse_init, sermouse_close, NULL,
|
||||
sermouse_poll, NULL, NULL, NULL,
|
||||
sermouse_config
|
||||
};
|
||||
|
||||
|
||||
mouse_t mouse_serial_mswheel = {
|
||||
"Microsoft wheel mouse (serial)",
|
||||
"mswheel",
|
||||
device_t mouse_mswheel_device = {
|
||||
"Microsoft Serial Wheel Mouse",
|
||||
0,
|
||||
MOUSE_TYPE_MSWHEEL | MOUSE_TYPE_3BUTTON,
|
||||
sermouse_init,
|
||||
sermouse_close,
|
||||
sermouse_poll
|
||||
sermouse_init, sermouse_close, NULL,
|
||||
sermouse_poll, NULL, NULL, NULL,
|
||||
sermouse_config
|
||||
};
|
||||
|
||||
@@ -186,7 +186,7 @@
|
||||
* (DS12887A) which implemented a "century" register to be
|
||||
* compatible with Y2K.
|
||||
*
|
||||
* Version: @(#)nvr.c 1.0.13 2017/11/19
|
||||
* Version: @(#)nvr.c 1.0.14 2017/12/03
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Mahod,
|
||||
@@ -751,7 +751,7 @@ nvr_path(wchar_t *str)
|
||||
|
||||
/* Get the full prefix in place. */
|
||||
memset(temp, 0x00, sizeof(temp));
|
||||
wcscpy(temp, cfg_path);
|
||||
wcscpy(temp, usr_path);
|
||||
wcscat(temp, NVR_PATH);
|
||||
|
||||
/* Create the directory if needed. */
|
||||
|
||||
410
src/pc.c
410
src/pc.c
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Main emulator module where most things are controlled.
|
||||
*
|
||||
* Version: @(#)pc.c 1.0.45 2017/11/23
|
||||
* Version: @(#)pc.c 1.0.47 2017/12/03
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -40,24 +40,24 @@
|
||||
#include "pit.h"
|
||||
#include "random.h"
|
||||
#include "timer.h"
|
||||
#include "mouse.h"
|
||||
#include "device.h"
|
||||
#include "nvr.h"
|
||||
#include "machine/machine.h"
|
||||
#include "game/gameport.h"
|
||||
#include "keyboard.h"
|
||||
#include "bugger.h"
|
||||
#include "lpt.h"
|
||||
#include "serial.h"
|
||||
#include "bugger.h"
|
||||
#include "keyboard.h"
|
||||
#include "mouse.h"
|
||||
#include "game/gameport.h"
|
||||
#include "floppy/floppy.h"
|
||||
#include "floppy/fdc.h"
|
||||
#include "disk/hdd.h"
|
||||
#include "disk/hdc.h"
|
||||
#include "disk/hdc_ide.h"
|
||||
#include "cdrom/cdrom.h"
|
||||
#include "cdrom/cdrom.h"
|
||||
#include "cdrom/cdrom_image.h"
|
||||
#include "cdrom/cdrom_null.h"
|
||||
#include "disk/hdd.h"
|
||||
#include "disk/hdc.h"
|
||||
#include "disk/hdc_ide.h"
|
||||
#include "floppy/floppy.h"
|
||||
#include "floppy/fdc.h"
|
||||
#include "scsi/scsi.h"
|
||||
#include "network/network.h"
|
||||
#include "sound/sound.h"
|
||||
@@ -75,7 +75,6 @@
|
||||
#include "plat.h"
|
||||
#include "plat_joystick.h"
|
||||
#include "plat_midi.h"
|
||||
#include "plat_mouse.h"
|
||||
|
||||
|
||||
/* Commandline options. */
|
||||
@@ -149,7 +148,8 @@ int clockrate;
|
||||
int gfx_present[GFX_MAX]; /* should not be here */
|
||||
|
||||
wchar_t exe_path[1024]; /* path (dir) of executable */
|
||||
wchar_t cfg_path[1024]; /* path (dir) of user data */
|
||||
wchar_t usr_path[1024]; /* path (dir) of user data */
|
||||
wchar_t cfg_path[1024]; /* full path of config file */
|
||||
FILE *stdlog = NULL; /* file to log output to */
|
||||
int scrnsz_x = SCREEN_RES_X, /* current screen size, X */
|
||||
scrnsz_y = SCREEN_RES_Y; /* current screen size, Y */
|
||||
@@ -164,14 +164,23 @@ static int unscaled_size_x = SCREEN_RES_X, /* current unscaled size X */
|
||||
efscrnsz_y = SCREEN_RES_Y;
|
||||
|
||||
|
||||
/* Log something to the logfile or stdout. */
|
||||
/*
|
||||
* Log something to the logfile or stdout.
|
||||
*
|
||||
* To avoid excessively-large logfiles because some
|
||||
* module repeatedly logs, we keep track of what is
|
||||
* being logged, and catch repeating entries.
|
||||
*/
|
||||
void
|
||||
pclog(const char *format, ...)
|
||||
pclog(const char *fmt, ...)
|
||||
{
|
||||
#ifndef RELEASE_BUILD
|
||||
static char buff[1024];
|
||||
static int seen = 0;
|
||||
char temp[1024];
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, format);
|
||||
va_start(ap, fmt);
|
||||
|
||||
if (stdlog == NULL) {
|
||||
if (log_path[0] != L'\0') {
|
||||
@@ -183,7 +192,18 @@ pclog(const char *format, ...)
|
||||
}
|
||||
}
|
||||
|
||||
vfprintf(stdlog, format, ap);
|
||||
vsprintf(temp, fmt, ap);
|
||||
if (! strcmp(buff, temp)) {
|
||||
seen++;
|
||||
} else {
|
||||
if (seen) {
|
||||
fprintf(stdlog, "*** %d repeats ***\n", seen);
|
||||
seen = 0;
|
||||
}
|
||||
strcpy(buff, temp);
|
||||
fprintf(stdlog, temp, ap);
|
||||
}
|
||||
|
||||
va_end(ap);
|
||||
fflush(stdlog);
|
||||
#endif
|
||||
@@ -192,13 +212,13 @@ pclog(const char *format, ...)
|
||||
|
||||
/* Log a fatal error, and display a UI message before exiting. */
|
||||
void
|
||||
fatal(const char *format, ...)
|
||||
fatal(const char *fmt, ...)
|
||||
{
|
||||
char temp[1024];
|
||||
va_list ap;
|
||||
char *sp;
|
||||
|
||||
va_start(ap, format);
|
||||
va_start(ap, fmt);
|
||||
|
||||
if (stdlog == NULL) {
|
||||
if (log_path[0] != L'\0') {
|
||||
@@ -210,7 +230,7 @@ fatal(const char *format, ...)
|
||||
}
|
||||
}
|
||||
|
||||
vsprintf(temp, format, ap);
|
||||
vsprintf(temp, fmt, ap);
|
||||
fprintf(stdlog, "%s", temp);
|
||||
fflush(stdlog);
|
||||
va_end(ap);
|
||||
@@ -227,130 +247,12 @@ fatal(const char *format, ...)
|
||||
|
||||
ui_msgbox(MBX_ERROR|MBX_FATAL|MBX_ANSI, temp);
|
||||
|
||||
fflush(stdout);
|
||||
fflush(stdlog);
|
||||
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
set_screen_size(int x, int y)
|
||||
{
|
||||
int owsx = scrnsz_x;
|
||||
int owsy = scrnsz_y;
|
||||
int temp_overscan_x = overscan_x;
|
||||
int temp_overscan_y = overscan_y;
|
||||
double dx, dy, dtx, dty;
|
||||
|
||||
/* Make sure we keep usable values. */
|
||||
#if 0
|
||||
pclog("SetScreenSize(%d, %d) resize=%d\n", x, y, vid_resize);
|
||||
#endif
|
||||
if (x < 320) x = 320;
|
||||
if (y < 200) y = 200;
|
||||
if (x > 2048) x = 2048;
|
||||
if (y > 2048) y = 2048;
|
||||
|
||||
/* Save the new values as "real" (unscaled) resolution. */
|
||||
unscaled_size_x = x;
|
||||
efscrnsz_y = y;
|
||||
|
||||
if (suppress_overscan)
|
||||
temp_overscan_x = temp_overscan_y = 0;
|
||||
|
||||
if (force_43) {
|
||||
dx = (double)x;
|
||||
dtx = (double)temp_overscan_x;
|
||||
|
||||
dy = (double)y;
|
||||
dty = (double)temp_overscan_y;
|
||||
|
||||
/* Account for possible overscan. */
|
||||
if (!(VGA) && (temp_overscan_y == 16)) {
|
||||
/* CGA */
|
||||
dy = (((dx - dtx) / 4.0) * 3.0) + dty;
|
||||
} else if (!(VGA) && (temp_overscan_y < 16)) {
|
||||
/* MDA/Hercules */
|
||||
dy = (x / 4.0) * 3.0;
|
||||
} else {
|
||||
if (enable_overscan) {
|
||||
/* EGA/(S)VGA with overscan */
|
||||
dy = (((dx - dtx) / 4.0) * 3.0) + dty;
|
||||
} else {
|
||||
/* EGA/(S)VGA without overscan */
|
||||
dy = (x / 4.0) * 3.0;
|
||||
}
|
||||
}
|
||||
unscaled_size_y = (int)dy;
|
||||
} else {
|
||||
unscaled_size_y = efscrnsz_y;
|
||||
}
|
||||
|
||||
switch(scale) {
|
||||
case 0: /* 50% */
|
||||
scrnsz_x = (unscaled_size_x>>1);
|
||||
scrnsz_y = (unscaled_size_y>>1);
|
||||
break;
|
||||
|
||||
case 1: /* 100% */
|
||||
scrnsz_x = unscaled_size_x;
|
||||
scrnsz_y = unscaled_size_y;
|
||||
break;
|
||||
|
||||
case 2: /* 150% */
|
||||
scrnsz_x = ((unscaled_size_x*3)>>1);
|
||||
scrnsz_y = ((unscaled_size_y*3)>>1);
|
||||
break;
|
||||
|
||||
case 3: /* 200% */
|
||||
scrnsz_x = (unscaled_size_x<<1);
|
||||
scrnsz_y = (unscaled_size_y<<1);
|
||||
break;
|
||||
}
|
||||
|
||||
/* If the resolution has changed, let the main thread handle it. */
|
||||
if ((owsx != scrnsz_x) || (owsy != scrnsz_y))
|
||||
doresize = 1;
|
||||
else
|
||||
doresize = 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
set_screen_size_natural(void)
|
||||
{
|
||||
set_screen_size(unscaled_size_x, unscaled_size_y);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
get_actual_size_x(void)
|
||||
{
|
||||
return(unscaled_size_x);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
get_actual_size_y(void)
|
||||
{
|
||||
return(efscrnsz_y);
|
||||
}
|
||||
|
||||
|
||||
void cfg_path_slash(void)
|
||||
{
|
||||
/* Make sure cfg_path has a trailing backslash. */
|
||||
if ((cfg_path[wcslen(cfg_path)-1] != L'\\') &&
|
||||
(cfg_path[wcslen(cfg_path)-1] != L'/')) {
|
||||
#ifdef _WIN32
|
||||
wcscat(cfg_path, L"\\");
|
||||
#else
|
||||
wcscat(cfg_path, L"/");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Perform initial startup of the PC.
|
||||
*
|
||||
@@ -361,14 +263,12 @@ void cfg_path_slash(void)
|
||||
int
|
||||
pc_init(int argc, wchar_t *argv[])
|
||||
{
|
||||
wchar_t path[2048];
|
||||
wchar_t *cfg = NULL, *p;
|
||||
char temp[128];
|
||||
struct tm *info;
|
||||
time_t now;
|
||||
int c;
|
||||
int cfgp = 0;
|
||||
wchar_t cmdl_cfg_path[2048];
|
||||
wchar_t emu_cwd[2048];
|
||||
|
||||
/* Grab the executable's full path. */
|
||||
plat_get_exe_name(exe_path, sizeof(exe_path)-1);
|
||||
@@ -377,12 +277,14 @@ pc_init(int argc, wchar_t *argv[])
|
||||
|
||||
/*
|
||||
* Get the current working directory.
|
||||
*
|
||||
* This is normally the directory from where the
|
||||
* program was run. If we have been started via
|
||||
* a shortcut (desktop icon), however, the CWD
|
||||
* could have been set to something else.
|
||||
*/
|
||||
plat_getcwd(emu_cwd, sizeof(emu_cwd)-1);
|
||||
plat_getcwd(usr_path, sizeof_w(usr_path)-1);
|
||||
memset(path, 0x00, sizeof(path));
|
||||
|
||||
for (c=1; c<argc; c++) {
|
||||
if (argv[c][0] != L'-') break;
|
||||
@@ -427,8 +329,7 @@ usage:
|
||||
!wcscasecmp(argv[c], L"-P")) {
|
||||
if ((c+1) == argc) goto usage;
|
||||
|
||||
wcscpy(cmdl_cfg_path, argv[++c]);
|
||||
cfgp = 1;
|
||||
wcscpy(path, argv[++c]);
|
||||
#ifdef USE_WX
|
||||
} else if (!wcscasecmp(argv[c], L"--fps") ||
|
||||
!wcscasecmp(argv[c], L"-R")) {
|
||||
@@ -452,43 +353,73 @@ usage:
|
||||
cfg = argv[c++];
|
||||
if (c != argc) goto usage;
|
||||
|
||||
if (!cfgp) {
|
||||
wcscpy(cfg_path, emu_cwd);
|
||||
} else {
|
||||
if ((cmdl_cfg_path[0] != L'\\') && (cmdl_cfg_path[0] != L'/') && (cmdl_cfg_path[1] != L':')) {
|
||||
wcscpy(cfg_path, emu_cwd);
|
||||
cfg_path_slash();
|
||||
wcscat(cfg_path, cmdl_cfg_path);
|
||||
/*
|
||||
* If the user provided a path for files, use that
|
||||
* instead of the current working directory. We do
|
||||
* make sure that if that was a relative path, we
|
||||
* make it absolute.
|
||||
*/
|
||||
if (path[0] != L'\0') {
|
||||
if (! plat_path_abs(path)) {
|
||||
/*
|
||||
* This looks like a relative path.
|
||||
*
|
||||
* Add it to the current working directory
|
||||
* to convert it (back) to an absolute path.
|
||||
*/
|
||||
plat_path_slash(usr_path);
|
||||
wcscat(usr_path, path);
|
||||
} else {
|
||||
wcscpy(cfg_path, cmdl_cfg_path);
|
||||
/*
|
||||
* The user-provided path seems like an
|
||||
* absolute path, so just use that.
|
||||
*/
|
||||
wcscpy(usr_path, path);
|
||||
}
|
||||
}
|
||||
|
||||
cfg_path_slash();
|
||||
/* Make sure we have a trailing backslash. */
|
||||
plat_path_slash(usr_path);
|
||||
|
||||
if (cfg != NULL) {
|
||||
/* Grab the name of the configuration file. */
|
||||
if (cfg == NULL)
|
||||
cfg = CONFIG_FILE;
|
||||
|
||||
/*
|
||||
* If the configuration file name has (part of)
|
||||
* a pathname, consider that to be part of the
|
||||
* actual working directory.
|
||||
*
|
||||
* This can happen when people load a config
|
||||
* file using the UI, for example.
|
||||
*/
|
||||
p = plat_get_filename(cfg);
|
||||
if (cfg != p) {
|
||||
/*
|
||||
* The user specified a configuration file.
|
||||
*
|
||||
* If this is an absolute path, keep it, as
|
||||
* they probably have a reason to do that.
|
||||
* Otherwise, assume the pathname given is
|
||||
* relative to whatever the cfg_path is.
|
||||
* OK, the configuration file name has a
|
||||
* path component. Separate the two, and
|
||||
* add the path component to the cfg path.
|
||||
*/
|
||||
#ifdef _WIN32
|
||||
if ((cfg[1] == L':') || /* drive letter present */
|
||||
(cfg[0] == L'\\')) /* backslash, root dir */
|
||||
#else
|
||||
if (cfg[0] == L'/') /* slash, root dir */
|
||||
#endif
|
||||
wcscpy(config_file_default, cfg);
|
||||
*(p-1) = L'\0';
|
||||
|
||||
/*
|
||||
* If this is an absolute path, keep it, as
|
||||
* there is probably have a reason to do so.
|
||||
* Otherwise, assume the pathname given is
|
||||
* relative to whatever the usr_path is.
|
||||
*/
|
||||
if (plat_path_abs(cfg))
|
||||
wcscpy(usr_path, cfg);
|
||||
else
|
||||
plat_append_filename(config_file_default, cfg_path, cfg, 511);
|
||||
cfg = NULL;
|
||||
} else {
|
||||
plat_append_filename(config_file_default, cfg_path, CONFIG_FILE_W, 511);
|
||||
wcscat(usr_path, cfg);
|
||||
|
||||
/* Make sure we have a trailing backslash. */
|
||||
plat_path_slash(usr_path);
|
||||
}
|
||||
|
||||
/* At this point, we can safely create the full path name. */
|
||||
plat_append_filename(cfg_path, usr_path, p);
|
||||
|
||||
/*
|
||||
* This is where we start outputting to the log file,
|
||||
* if there is one. Create a little info header first.
|
||||
@@ -499,8 +430,8 @@ usage:
|
||||
pclog("#\n# %ls v%ls logfile, created %s\n#\n",
|
||||
EMU_NAME_W, EMU_VERSION_W, temp);
|
||||
pclog("# Emulator path: %ls\n", exe_path);
|
||||
pclog("# Userfiles path: %ls\n", cfg_path);
|
||||
pclog("# Configuration file: %ls\n#\n\n", config_file_default);
|
||||
pclog("# Userfiles path: %ls\n", usr_path);
|
||||
pclog("# Configuration file: %ls\n#\n\n", cfg_path);
|
||||
|
||||
/*
|
||||
* We are about to read the configuration file, which MAY
|
||||
@@ -510,10 +441,11 @@ usage:
|
||||
*/
|
||||
hdd_init();
|
||||
network_init();
|
||||
mouse_init();
|
||||
cdrom_global_init();
|
||||
|
||||
/* Load the configuration file. */
|
||||
config_load(cfg);
|
||||
config_load();
|
||||
|
||||
/* All good! */
|
||||
return(1);
|
||||
@@ -551,12 +483,13 @@ pc_speed_changed(void)
|
||||
|
||||
|
||||
/* Re-load system configuration and restart. */
|
||||
/* FIXME: this has to be reviewed! */
|
||||
void
|
||||
pc_reload(wchar_t *fn)
|
||||
{
|
||||
int i;
|
||||
|
||||
config_write(config_file_default);
|
||||
config_write(cfg_path);
|
||||
|
||||
for (i=0; i<FDD_NUM; i++)
|
||||
floppy_close(i);
|
||||
@@ -572,7 +505,9 @@ pc_reload(wchar_t *fn)
|
||||
|
||||
pc_reset_hard_close();
|
||||
|
||||
config_load(fn);
|
||||
// FIXME: set up new config file path 'fn'... --FvK
|
||||
|
||||
config_load();
|
||||
|
||||
for (i=0; i<CDROM_NUM; i++) {
|
||||
if (cdrom_drives[i].bus_type)
|
||||
@@ -644,7 +579,7 @@ again:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Make sure we have a usable video card. */
|
||||
for (c=0; c<GFX_MAX; c++)
|
||||
gfx_present[c] = video_card_available(video_old_to_new(c));
|
||||
@@ -675,11 +610,10 @@ again2:
|
||||
codegen_init();
|
||||
#endif
|
||||
|
||||
keyboard_init();
|
||||
mouse_init();
|
||||
#ifdef WALTJE_SERIAL
|
||||
serial_init();
|
||||
#endif
|
||||
keyboard_init();
|
||||
joystick_init();
|
||||
video_init();
|
||||
|
||||
@@ -776,7 +710,7 @@ pc_reset_hard_close(void)
|
||||
device_close_all();
|
||||
|
||||
midi_close();
|
||||
mouse_emu_close();
|
||||
|
||||
closeal();
|
||||
}
|
||||
|
||||
@@ -819,11 +753,6 @@ pc_reset_hard_init(void)
|
||||
serial_init();
|
||||
#endif
|
||||
|
||||
/* This has to be after the serial initialization so that
|
||||
serial_init() doesn't break the serial mouse by resetting
|
||||
the RCR callback to NULL. */
|
||||
mouse_emu_init();
|
||||
|
||||
/* Initialize the actual machine and its basic modules. */
|
||||
machine_init();
|
||||
|
||||
@@ -846,6 +775,13 @@ pc_reset_hard_init(void)
|
||||
shadowbios = 0;
|
||||
keyboard_at_reset();
|
||||
|
||||
/*
|
||||
* This has to be after the serial initialization so that
|
||||
* serial_init() doesn't break the serial mouse by resetting
|
||||
* the RCR callback to NULL.
|
||||
*/
|
||||
mouse_reset();
|
||||
|
||||
/* Reset the video card. */
|
||||
video_reset(gfxcard);
|
||||
|
||||
@@ -1169,3 +1105,107 @@ pc_onesec(void)
|
||||
|
||||
title_update = 1;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
set_screen_size(int x, int y)
|
||||
{
|
||||
int owsx = scrnsz_x;
|
||||
int owsy = scrnsz_y;
|
||||
int temp_overscan_x = overscan_x;
|
||||
int temp_overscan_y = overscan_y;
|
||||
double dx, dy, dtx, dty;
|
||||
|
||||
/* Make sure we keep usable values. */
|
||||
#if 0
|
||||
pclog("SetScreenSize(%d, %d) resize=%d\n", x, y, vid_resize);
|
||||
#endif
|
||||
if (x < 320) x = 320;
|
||||
if (y < 200) y = 200;
|
||||
if (x > 2048) x = 2048;
|
||||
if (y > 2048) y = 2048;
|
||||
|
||||
/* Save the new values as "real" (unscaled) resolution. */
|
||||
unscaled_size_x = x;
|
||||
efscrnsz_y = y;
|
||||
|
||||
if (suppress_overscan)
|
||||
temp_overscan_x = temp_overscan_y = 0;
|
||||
|
||||
if (force_43) {
|
||||
dx = (double)x;
|
||||
dtx = (double)temp_overscan_x;
|
||||
|
||||
dy = (double)y;
|
||||
dty = (double)temp_overscan_y;
|
||||
|
||||
/* Account for possible overscan. */
|
||||
if (!(VGA) && (temp_overscan_y == 16)) {
|
||||
/* CGA */
|
||||
dy = (((dx - dtx) / 4.0) * 3.0) + dty;
|
||||
} else if (!(VGA) && (temp_overscan_y < 16)) {
|
||||
/* MDA/Hercules */
|
||||
dy = (x / 4.0) * 3.0;
|
||||
} else {
|
||||
if (enable_overscan) {
|
||||
/* EGA/(S)VGA with overscan */
|
||||
dy = (((dx - dtx) / 4.0) * 3.0) + dty;
|
||||
} else {
|
||||
/* EGA/(S)VGA without overscan */
|
||||
dy = (x / 4.0) * 3.0;
|
||||
}
|
||||
}
|
||||
unscaled_size_y = (int)dy;
|
||||
} else {
|
||||
unscaled_size_y = efscrnsz_y;
|
||||
}
|
||||
|
||||
switch(scale) {
|
||||
case 0: /* 50% */
|
||||
scrnsz_x = (unscaled_size_x>>1);
|
||||
scrnsz_y = (unscaled_size_y>>1);
|
||||
break;
|
||||
|
||||
case 1: /* 100% */
|
||||
scrnsz_x = unscaled_size_x;
|
||||
scrnsz_y = unscaled_size_y;
|
||||
break;
|
||||
|
||||
case 2: /* 150% */
|
||||
scrnsz_x = ((unscaled_size_x*3)>>1);
|
||||
scrnsz_y = ((unscaled_size_y*3)>>1);
|
||||
break;
|
||||
|
||||
case 3: /* 200% */
|
||||
scrnsz_x = (unscaled_size_x<<1);
|
||||
scrnsz_y = (unscaled_size_y<<1);
|
||||
break;
|
||||
}
|
||||
|
||||
/* If the resolution has changed, let the main thread handle it. */
|
||||
if ((owsx != scrnsz_x) || (owsy != scrnsz_y))
|
||||
doresize = 1;
|
||||
else
|
||||
doresize = 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
set_screen_size_natural(void)
|
||||
{
|
||||
set_screen_size(unscaled_size_x, unscaled_size_y);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
get_actual_size_x(void)
|
||||
{
|
||||
return(unscaled_size_x);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
get_actual_size_y(void)
|
||||
{
|
||||
return(efscrnsz_y);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Define the various platform support functions.
|
||||
*
|
||||
* Version: @(#)plat.h 1.0.21 2017/11/18
|
||||
* Version: @(#)plat.h 1.0.22 2017/12/03
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
@@ -71,8 +71,10 @@ extern int plat_chdir(wchar_t *path);
|
||||
extern void plat_get_exe_name(wchar_t *s, int size);
|
||||
extern wchar_t *plat_get_filename(wchar_t *s);
|
||||
extern wchar_t *plat_get_extension(wchar_t *s);
|
||||
extern void plat_append_filename(wchar_t *dest, wchar_t *s1, wchar_t *s2, int size);
|
||||
extern void plat_append_filename(wchar_t *dest, wchar_t *s1, wchar_t *s2);
|
||||
extern void plat_put_backslash(wchar_t *s);
|
||||
extern void plat_path_slash(wchar_t *path);
|
||||
extern int plat_path_abs(wchar_t *path);
|
||||
extern int plat_dir_check(wchar_t *path);
|
||||
extern int plat_dir_create(wchar_t *path);
|
||||
extern uint64_t plat_timer_read(void);
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
/* Copyright holders: Sarah Walker
|
||||
see COPYING for more details
|
||||
*/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern void mouse_init(void);
|
||||
extern void mouse_close(void);
|
||||
extern void mouse_process(void);
|
||||
extern void mouse_poll_host(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -375,7 +375,7 @@ static device_config_t fluidsynth_config[] =
|
||||
{
|
||||
.name = "sound_font",
|
||||
.description = "Sound Font",
|
||||
.type = CONFIG_FILE,
|
||||
.type = CONFIG_FNAME,
|
||||
.default_string = "",
|
||||
.file_filter =
|
||||
{
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Definitions for the video controller module.
|
||||
*
|
||||
* Version: @(#)video.h 1.0.4 2017/11/18
|
||||
* Version: @(#)video.h 1.0.5 2017/11/25
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Application resource script for Windows.
|
||||
*
|
||||
* Version: @(#)86Box.rc 1.0.20 2017/11/18
|
||||
* Version: @(#)86Box.rc 1.0.21 2017/11/25
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
@@ -849,19 +849,6 @@ BEGIN
|
||||
IDS_2170 "Check BPB"
|
||||
IDS_2171 "Unable to initialize FluidSynth, make sure you have the following libraries\nin your 86Box folder:\n\nlibfluidsynth.dll\nlibglib-2.0-0.dll\nlibiconv-2.dll\nlibintl-8.dll\nlibpcre-1.dll"
|
||||
|
||||
IDS_3072 "None"
|
||||
IDS_3073 "Internal"
|
||||
IDS_3074 "[Bus] Logitech Bus Mouse"
|
||||
IDS_3075 "[Bus] Microsoft Bus Mouse (InPort)"
|
||||
IDS_3076 "[Serial] Mouse Systems Mouse"
|
||||
IDS_3077 "[Serial] Microsoft 2-button Mouse"
|
||||
IDS_3078 "[Serial] Logitech 3-button Mouse"
|
||||
IDS_3079 "[Serial] Microsoft Wheel Mouse"
|
||||
IDS_3080 "[PS/2] 2-button Mouse"
|
||||
IDS_3081 "[PS/2] Microsoft Intellimouse"
|
||||
IDS_3082 "[Proprietary] Amstrad Mouse"
|
||||
IDS_3083 "[Proprietary] Olivetti M24 Mouse"
|
||||
|
||||
IDS_4096 "Hard disk (%s)"
|
||||
IDS_4097 "%01i:%01i"
|
||||
IDS_4098 "%i"
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#
|
||||
# Makefile for Win32 (MinGW32) environment.
|
||||
#
|
||||
# Version: @(#)Makefile.mingw 1.0.82 2017/11/27
|
||||
# Version: @(#)Makefile.mingw 1.0.81 2017/11/25
|
||||
#
|
||||
# Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
# Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
@@ -446,7 +446,7 @@ VIDOBJ := video.o \
|
||||
PLATOBJ := win.o \
|
||||
win_crashdump.o win_dynld.o win_thread.o $(WSERIAL) \
|
||||
win_cdrom.o win_cdrom_ioctl.o win_keyboard.o \
|
||||
win_mouse.o win_joystick.o win_midi.o win_video.o
|
||||
win_mouse.o win_joystick.o win_midi.o
|
||||
|
||||
OBJ := $(MAINOBJ) $(CPUOBJ) $(MCHOBJ) $(DEVOBJ) \
|
||||
$(FDDOBJ) $(CDROMOBJ) $(HDDOBJ) \
|
||||
|
||||
364
src/win/win.c
364
src/win/win.c
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Platform main support module for Windows.
|
||||
*
|
||||
* Version: @(#)win.c 1.0.37 2017/11/20
|
||||
* Version: @(#)win.c 1.0.40 2017/12/03
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -20,20 +20,34 @@
|
||||
*/
|
||||
#define UNICODE
|
||||
#include <windows.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <time.h>
|
||||
#include <wchar.h>
|
||||
#include "../86box.h"
|
||||
#include "../config.h"
|
||||
#include "../device.h"
|
||||
#include "../mouse.h"
|
||||
#include "../video/video.h"
|
||||
#define GLOBAL
|
||||
#include "../plat.h"
|
||||
#include "../plat_mouse.h"
|
||||
#include "../plat_midi.h"
|
||||
#include "../ui.h"
|
||||
#ifdef USE_VNC
|
||||
# include "../vnc.h"
|
||||
#endif
|
||||
#ifdef USE_RDP
|
||||
# include "../rdp.h"
|
||||
#endif
|
||||
#ifdef USE_WX
|
||||
# include "../wx/wx_ui.h"
|
||||
#else
|
||||
# include "win_ddraw.h"
|
||||
# include "win_d3d.h"
|
||||
#endif
|
||||
#include "win.h"
|
||||
|
||||
|
||||
@@ -52,7 +66,6 @@ DWORD dwSubLangID;
|
||||
/* Local data. */
|
||||
static HANDLE thMain;
|
||||
static rc_str_t *lpRCstr2048,
|
||||
*lpRCstr3072,
|
||||
*lpRCstr4096,
|
||||
*lpRCstr4352,
|
||||
*lpRCstr4608,
|
||||
@@ -62,13 +75,61 @@ static rc_str_t *lpRCstr2048,
|
||||
*lpRCstr6144;
|
||||
|
||||
|
||||
static struct {
|
||||
char *name;
|
||||
int local;
|
||||
int (*init)(void *);
|
||||
void (*close)(void);
|
||||
void (*resize)(int x, int y);
|
||||
int (*pause)(void);
|
||||
} vid_apis[2][4] = {
|
||||
{
|
||||
#ifdef USE_WX
|
||||
{ "WxWidgets", 1, wx_init, wx_close, NULL, wx_pause },
|
||||
{ "WxWidgets", 1, wx_init, wx_close, NULL, wx_pause },
|
||||
#else
|
||||
{ "DDraw", 1, (int(*)(void*))ddraw_init, ddraw_close, NULL, ddraw_pause },
|
||||
{ "D3D", 1, (int(*)(void*))d3d_init, d3d_close, d3d_resize, d3d_pause },
|
||||
#endif
|
||||
#ifdef USE_VNC
|
||||
{ "VNC", 0, vnc_init, vnc_close, vnc_resize, vnc_pause },
|
||||
#else
|
||||
{ NULL, 0, NULL, NULL, NULL, NULL },
|
||||
#endif
|
||||
#ifdef USE_RDP
|
||||
{ "RDP", 0, rdp_init, rdp_close, rdp_resize, rdp_pause }
|
||||
#else
|
||||
{ NULL, 0, NULL, NULL, NULL, NULL }
|
||||
#endif
|
||||
},
|
||||
{
|
||||
#ifdef USE_WX
|
||||
{ "WxWidgets", 1, wx_init, wx_close, NULL, wx_pause },
|
||||
{ "WxWidgets", 1, wx_init, wx_close, NULL, wx_pause },
|
||||
#else
|
||||
{ "DDraw", 1, (int(*)(void*))ddraw_init_fs, ddraw_close, NULL, ddraw_pause },
|
||||
{ "D3D", 1, (int(*)(void*))d3d_init_fs, d3d_close, NULL, d3d_pause },
|
||||
#endif
|
||||
#ifdef USE_VNC
|
||||
{ "VNC", 0, vnc_init, vnc_close, vnc_resize, vnc_pause },
|
||||
#else
|
||||
{ NULL, 0, NULL, NULL, NULL, NULL },
|
||||
#endif
|
||||
#ifdef USE_RDP
|
||||
{ "RDP", 0, rdp_init, rdp_close, rdp_resize, rdp_pause }
|
||||
#else
|
||||
{ NULL, 0, NULL, NULL, NULL, NULL }
|
||||
#endif
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
static void
|
||||
LoadCommonStrings(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
lpRCstr2048 = (rc_str_t *)malloc(STR_NUM_2048*sizeof(rc_str_t));
|
||||
lpRCstr3072 = (rc_str_t *)malloc(STR_NUM_3072*sizeof(rc_str_t));
|
||||
lpRCstr4096 = (rc_str_t *)malloc(STR_NUM_4096*sizeof(rc_str_t));
|
||||
lpRCstr4352 = (rc_str_t *)malloc(STR_NUM_4352*sizeof(rc_str_t));
|
||||
lpRCstr4608 = (rc_str_t *)malloc(STR_NUM_4608*sizeof(rc_str_t));
|
||||
@@ -80,9 +141,6 @@ LoadCommonStrings(void)
|
||||
for (i=0; i<STR_NUM_2048; i++)
|
||||
LoadString(hinstance, 2048+i, lpRCstr2048[i].str, 512);
|
||||
|
||||
for (i=0; i<STR_NUM_3072; i++)
|
||||
LoadString(hinstance, 3072+i, lpRCstr3072[i].str, 512);
|
||||
|
||||
for (i=0; i<STR_NUM_4096; i++)
|
||||
LoadString(hinstance, 4096+i, lpRCstr4096[i].str, 512);
|
||||
|
||||
@@ -136,8 +194,6 @@ plat_get_string(int i)
|
||||
|
||||
if ((i >= 2048) && (i <= 3071)) {
|
||||
str = lpRCstr2048[i-2048].str;
|
||||
} else if ((i >= 3072) && (i <= 4095)) {
|
||||
str = lpRCstr3072[i-3072].str;
|
||||
} else if ((i >= 4096) && (i <= 4351)) {
|
||||
str = lpRCstr4096[i-4096].str;
|
||||
} else if ((i >= 4352) && (i <= 4607)) {
|
||||
@@ -272,9 +328,7 @@ ProcessCommandLine(wchar_t ***argw)
|
||||
}
|
||||
|
||||
|
||||
/* @@@
|
||||
* For the Windows platform, this is the start of the application.
|
||||
*/
|
||||
/* For the Windows platform, this is the start of the application. */
|
||||
int WINAPI
|
||||
WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpszArg, int nCmdShow)
|
||||
{
|
||||
@@ -308,14 +362,9 @@ WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpszArg, int nCmdShow)
|
||||
return(1);
|
||||
}
|
||||
|
||||
/* Cleanup: we no longer need the commandline arguments. */
|
||||
/* Cleanup: we may no longer need the console. */
|
||||
if (! force_debug)
|
||||
CreateConsole(0);
|
||||
#if 0
|
||||
//QUICKFIX, DO NOT CHANGE --FvK
|
||||
free(argw[0]);
|
||||
free(argw);
|
||||
#endif
|
||||
|
||||
/* Handle our GUI. */
|
||||
i = ui_init(nCmdShow);
|
||||
@@ -344,11 +393,6 @@ do_start(void)
|
||||
timer_freq = qpc.QuadPart;
|
||||
pclog("Main timer precision: %llu\n", timer_freq);
|
||||
|
||||
#if 0
|
||||
/* We should have an application-wide at_exit catcher. */
|
||||
atexit(plat_mouse_capture);
|
||||
#endif
|
||||
|
||||
/* Start the emulator, really. */
|
||||
thMain = thread_create(pc_thread, &quited);
|
||||
SetThreadPriority(thMain, THREAD_PRIORITY_HIGHEST);
|
||||
@@ -406,6 +450,28 @@ plat_remove(wchar_t *path)
|
||||
}
|
||||
|
||||
|
||||
/* Make sure a path ends with a trailing (back)slash. */
|
||||
void
|
||||
plat_path_slash(wchar_t *path)
|
||||
{
|
||||
if ((path[wcslen(path)-1] != L'\\') &&
|
||||
(path[wcslen(path)-1] != L'/')) {
|
||||
wcscat(path, L"\\");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Check if the given path is absolute or not. */
|
||||
int
|
||||
plat_path_abs(wchar_t *path)
|
||||
{
|
||||
if ((path[1] == L':') || (path[0] == L'\\'))
|
||||
return(1);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
wchar_t *
|
||||
plat_get_filename(wchar_t *s)
|
||||
{
|
||||
@@ -440,7 +506,7 @@ plat_get_extension(wchar_t *s)
|
||||
|
||||
|
||||
void
|
||||
plat_append_filename(wchar_t *dest, wchar_t *s1, wchar_t *s2, int size)
|
||||
plat_append_filename(wchar_t *dest, wchar_t *s1, wchar_t *s2)
|
||||
{
|
||||
wcscat(dest, s1);
|
||||
wcscat(dest, s2);
|
||||
@@ -497,3 +563,251 @@ plat_delay_ms(uint32_t count)
|
||||
{
|
||||
Sleep(count);
|
||||
}
|
||||
|
||||
|
||||
/* Return the VIDAPI number for the given name. */
|
||||
int
|
||||
plat_vidapi(char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!strcasecmp(name, "default") || !strcasecmp(name, "system")) return(1);
|
||||
|
||||
for (i=0; i<4; i++) {
|
||||
if (vid_apis[0][i].name &&
|
||||
!strcasecmp(vid_apis[0][i].name, name)) return(i);
|
||||
}
|
||||
|
||||
/* Default value. */
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
/* Return the VIDAPI name for the given number. */
|
||||
char *
|
||||
plat_vidapi_name(int api)
|
||||
{
|
||||
char *name = "default";
|
||||
|
||||
switch(api) {
|
||||
#if USE_WX
|
||||
case 0:
|
||||
break;
|
||||
|
||||
case 1:
|
||||
name = "wxwidgets";
|
||||
break;
|
||||
#else
|
||||
case 0:
|
||||
name = "ddraw";
|
||||
break;
|
||||
|
||||
case 1:
|
||||
#if 0
|
||||
/* Direct3D is default. */
|
||||
name = "d3d";
|
||||
#endif
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef USE_VNC
|
||||
case 2:
|
||||
name = "vnc";
|
||||
break;
|
||||
|
||||
#endif
|
||||
#ifdef USE_RDP
|
||||
case 3:
|
||||
name = "rdp";
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
return(name);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
plat_setvid(int api)
|
||||
{
|
||||
int i;
|
||||
|
||||
pclog("Initializing VIDAPI: api=%d\n", api);
|
||||
startblit();
|
||||
video_wait_for_blit();
|
||||
|
||||
/* Close the (old) API. */
|
||||
vid_apis[0][vid_api].close();
|
||||
//#ifdef USE_WX
|
||||
// ui_check_menu_item(IDM_View_WX+vid_api, 0);
|
||||
//#endif
|
||||
vid_api = api;
|
||||
|
||||
#ifndef USE_WX
|
||||
if (vid_apis[0][vid_api].local)
|
||||
ShowWindow(hwndRender, SW_SHOW);
|
||||
else
|
||||
ShowWindow(hwndRender, SW_HIDE);
|
||||
#endif
|
||||
|
||||
/* Initialize the (new) API. */
|
||||
#ifdef USE_WX
|
||||
// ui_check_menu_item(IDM_View_WX+vid_api, 1);
|
||||
i = vid_apis[0][vid_api].init(NULL);
|
||||
#else
|
||||
i = vid_apis[0][vid_api].init((void *)hwndRender);
|
||||
#endif
|
||||
endblit();
|
||||
if (! i) return(0);
|
||||
|
||||
device_force_redraw();
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
/* Tell the renderers about a new screen resolution. */
|
||||
void
|
||||
plat_vidsize(int x, int y)
|
||||
{
|
||||
if (! vid_apis[video_fullscreen][vid_api].resize) return;
|
||||
|
||||
startblit();
|
||||
video_wait_for_blit();
|
||||
vid_apis[video_fullscreen][vid_api].resize(x, y);
|
||||
endblit();
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
get_vidpause(void)
|
||||
{
|
||||
return(vid_apis[video_fullscreen][vid_api].pause());
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
plat_setfullscreen(int on)
|
||||
{
|
||||
static int flag = 0;
|
||||
HWND *hw;
|
||||
|
||||
/* Want off and already off? */
|
||||
if (!on && !video_fullscreen) return;
|
||||
|
||||
/* Want on and already on? */
|
||||
if (on && video_fullscreen) return;
|
||||
|
||||
if (!on && !flag) {
|
||||
/* We want to leave FS mode. */
|
||||
flag = 1;
|
||||
|
||||
#ifdef USE_WX
|
||||
goto doit;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
if (video_fullscreen_first) {
|
||||
video_fullscreen_first = 0;
|
||||
ui_msgbox(MBX_INFO, (wchar_t *)IDS_2074);
|
||||
}
|
||||
|
||||
/* OK, claim the video. */
|
||||
#ifdef USE_WX
|
||||
doit:
|
||||
#endif
|
||||
startblit();
|
||||
video_wait_for_blit();
|
||||
|
||||
win_mouse_close();
|
||||
|
||||
/* Close the current mode, and open the new one. */
|
||||
vid_apis[video_fullscreen][vid_api].close();
|
||||
video_fullscreen = on;
|
||||
hw = (video_fullscreen) ? &hwndMain : &hwndRender;
|
||||
vid_apis[video_fullscreen][vid_api].init((void *) *hw);
|
||||
flag = 0;
|
||||
|
||||
#ifdef USE_WX
|
||||
wx_set_fullscreen(on);
|
||||
#endif
|
||||
|
||||
win_mouse_init();
|
||||
|
||||
leave_fullscreen_flag = 0;
|
||||
|
||||
/* Release video and make it redraw the screen. */
|
||||
endblit();
|
||||
device_force_redraw();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
take_screenshot(void)
|
||||
{
|
||||
wchar_t path[1024], fn[128];
|
||||
struct tm *info;
|
||||
time_t now;
|
||||
|
||||
pclog("Screenshot: video API is: %i\n", vid_api);
|
||||
if ((vid_api < 0) || (vid_api > 1)) return;
|
||||
|
||||
memset(fn, 0, sizeof(fn));
|
||||
memset(path, 0, sizeof(path));
|
||||
|
||||
(void)time(&now);
|
||||
info = localtime(&now);
|
||||
|
||||
plat_append_filename(path, usr_path, SCREENSHOT_PATH);
|
||||
|
||||
if (! plat_dir_check(path))
|
||||
plat_dir_create(path);
|
||||
|
||||
wcscat(path, L"\\");
|
||||
|
||||
switch(vid_api) {
|
||||
#ifdef USE_WX
|
||||
case 0:
|
||||
case 1:
|
||||
wcsftime(fn, 128, L"%Y%m%d_%H%M%S.png", info);
|
||||
wcscat(path, fn);
|
||||
wx_screenshot(path);
|
||||
break;
|
||||
#else
|
||||
case 0: /* ddraw */
|
||||
wcsftime(fn, 128, L"%Y%m%d_%H%M%S.bmp", info);
|
||||
wcscat(path, fn);
|
||||
ddraw_take_screenshot(path);
|
||||
break;
|
||||
|
||||
case 1: /* d3d9 */
|
||||
wcsftime(fn, 128, L"%Y%m%d_%H%M%S.png", info);
|
||||
wcscat(path, fn);
|
||||
d3d_take_screenshot(path);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef USE_VNC
|
||||
case 2: /* vnc */
|
||||
wcsftime(fn, 128, L"%Y%m%d_%H%M%S.png", info);
|
||||
wcscat(path, fn);
|
||||
vnc_take_screenshot(path);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void /* plat_ */
|
||||
startblit(void)
|
||||
{
|
||||
WaitForSingleObject(ghMutex, INFINITE);
|
||||
}
|
||||
|
||||
|
||||
void /* plat_ */
|
||||
endblit(void)
|
||||
{
|
||||
ReleaseMutex(ghMutex);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Platform support defintions for Win32.
|
||||
*
|
||||
* Version: @(#)win.h 1.0.10 2017/11/20
|
||||
* Version: @(#)win.h 1.0.11 2017/11/24
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -82,6 +82,9 @@ extern int get_vidpause(void);
|
||||
extern void keyboard_getkeymap(void);
|
||||
extern void keyboard_handle(LPARAM lParam, int infocus);
|
||||
|
||||
extern void win_mouse_init(void);
|
||||
extern void win_mouse_close(void);
|
||||
|
||||
extern int fdd_type_to_icon(int type);
|
||||
|
||||
#ifdef EMU_DEVICE_H
|
||||
|
||||
@@ -68,7 +68,7 @@ cdrom_ioctl_log(const char *format, ...)
|
||||
va_start(ap, format);
|
||||
vfprintf(stdlog, format, ap);
|
||||
va_end(ap);
|
||||
fflush(stdstdlog);
|
||||
fflush(stdlog);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Rendering module for Microsoft Direct3D 9.
|
||||
*
|
||||
* Version: @(#)win_d3d.cc 1.0.6 2017/11/12
|
||||
* Version: @(#)win_d3d.cpp 1.0.6 2017/11/25
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -11,7 +11,7 @@
|
||||
* NOTES: This code should be re-merged into a single init() with a
|
||||
* 'fullscreen' argument, indicating FS mode is requested.
|
||||
*
|
||||
* Version: @(#)win_ddraw.cc 1.0.2 2017/11/12
|
||||
* Version: @(#)win_ddraw.cpp 1.0.2 2017/11/25
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Windows device configuration dialog implementation.
|
||||
*
|
||||
* Version: @(#)win_devconf.c 1.0.9 2017/11/18
|
||||
* Version: @(#)win_devconf.c 1.0.10 2017/11/25
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -117,7 +117,7 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
id += 2;
|
||||
break;
|
||||
|
||||
case CONFIG_FILE:
|
||||
case CONFIG_FNAME:
|
||||
{
|
||||
wchar_t* str = config_get_wstring(config_device->name, config->name, 0);
|
||||
if (str)
|
||||
@@ -218,7 +218,7 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
id += 2;
|
||||
break;
|
||||
|
||||
case CONFIG_FILE:
|
||||
case CONFIG_FNAME:
|
||||
{
|
||||
char* str = config_get_string(config_device->name, config->name, (char*)"");
|
||||
SendMessage(h, WM_GETTEXT, 511, (LPARAM)s);
|
||||
@@ -318,7 +318,7 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
id += 2;
|
||||
break;
|
||||
|
||||
case CONFIG_FILE:
|
||||
case CONFIG_FNAME:
|
||||
SendMessage(h, WM_GETTEXT, 511, (LPARAM)ws);
|
||||
config_set_wstring(config_device->name, config->name, ws);
|
||||
|
||||
@@ -387,7 +387,7 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
id += 2;
|
||||
break;
|
||||
|
||||
case CONFIG_FILE:
|
||||
case CONFIG_FNAME:
|
||||
{
|
||||
if (cid == id+1)
|
||||
{
|
||||
@@ -605,7 +605,7 @@ uint8_t deviceconfig_open(HWND hwnd, device_t *device)
|
||||
y += 20;
|
||||
break;
|
||||
|
||||
case CONFIG_FILE:
|
||||
case CONFIG_FNAME:
|
||||
/*File*/
|
||||
item = (DLGITEMTEMPLATE *)data;
|
||||
item->x = 70;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Joystick interface to host device.
|
||||
*
|
||||
* Version: @(#)win_joystick.cc 1.0.6 2017/11/18
|
||||
* Version: @(#)win_joystick.cpp 1.0.6 2017/11/25
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Mouse interface to host device.
|
||||
*
|
||||
* Version: @(#)win_mouse.cc 1.0.5 2017/10/22
|
||||
* Version: @(#)win_mouse.cpp 1.0.6 2017/11/25
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -23,7 +23,6 @@
|
||||
#include "../86Box.h"
|
||||
#include "../mouse.h"
|
||||
#include "../plat.h"
|
||||
#include "../plat_mouse.h"
|
||||
#include "win.h"
|
||||
|
||||
|
||||
@@ -36,32 +35,32 @@ static DIMOUSESTATE mousestate;
|
||||
|
||||
|
||||
void
|
||||
mouse_init(void)
|
||||
win_mouse_init(void)
|
||||
{
|
||||
atexit(mouse_close);
|
||||
|
||||
atexit(win_mouse_close);
|
||||
|
||||
mouse_capture = 0;
|
||||
|
||||
if (FAILED(DirectInput8Create(hinstance, DIRECTINPUT_VERSION,
|
||||
IID_IDirectInput8A, (void **) &lpdi, NULL)))
|
||||
fatal("mouse_init : DirectInputCreate failed\n");
|
||||
fatal("plat_mouse_init: DirectInputCreate failed\n");
|
||||
|
||||
if (FAILED(lpdi->CreateDevice(GUID_SysMouse, &lpdi_mouse, NULL)))
|
||||
fatal("mouse_init : CreateDevice failed\n");
|
||||
fatal("plat_mouse_init: CreateDevice failed\n");
|
||||
|
||||
if (FAILED(lpdi_mouse->SetCooperativeLevel(hwndMain,
|
||||
DISCL_FOREGROUND | (video_fullscreen ? DISCL_EXCLUSIVE : DISCL_NONEXCLUSIVE))))
|
||||
fatal("mouse_init : SetCooperativeLevel failed\n");
|
||||
fatal("plat_mouse_init: SetCooperativeLevel failed\n");
|
||||
|
||||
if (FAILED(lpdi_mouse->SetDataFormat(&c_dfDIMouse)))
|
||||
fatal("mouse_init : SetDataFormat failed\n");
|
||||
fatal("plat_mouse_init: SetDataFormat failed\n");
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
mouse_close(void)
|
||||
win_mouse_close(void)
|
||||
{
|
||||
if (lpdi_mouse) {
|
||||
if (lpdi_mouse != NULL) {
|
||||
lpdi_mouse->Release();
|
||||
lpdi_mouse = NULL;
|
||||
}
|
||||
@@ -69,7 +68,7 @@ mouse_close(void)
|
||||
|
||||
|
||||
void
|
||||
mouse_poll_host(void)
|
||||
mouse_poll(void)
|
||||
{
|
||||
static int buttons = 0;
|
||||
static int x = 0, y = 0, z = 0;
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Windows 86Box Settings dialog handler.
|
||||
*
|
||||
* Version: @(#)win_settings.c 1.0.24 2017/11/08
|
||||
* Version: @(#)win_settings.c 1.0.25 2017/11/24
|
||||
*
|
||||
* Author: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
@@ -927,11 +927,11 @@ static int mouse_valid(int type, int machine)
|
||||
|
||||
static BOOL CALLBACK win_settings_input_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
wchar_t str[128];
|
||||
HWND h;
|
||||
int c = 0;
|
||||
int d = 0;
|
||||
int type;
|
||||
int str_id = 0;
|
||||
|
||||
switch (message)
|
||||
{
|
||||
@@ -946,9 +946,8 @@ static BOOL CALLBACK win_settings_input_proc(HWND hdlg, UINT message, WPARAM wPa
|
||||
|
||||
if (mouse_valid(type, temp_machine))
|
||||
{
|
||||
str_id = IDS_3072 + c;
|
||||
|
||||
SendMessage(h, CB_ADDSTRING, 0, (LPARAM)plat_get_string(str_id));
|
||||
mbstowcs(str, mouse_get_name(c), sizeof_w(str));
|
||||
SendMessage(h, CB_ADDSTRING, 0, (LPARAM)str);
|
||||
|
||||
settings_list_to_mouse[d] = c;
|
||||
d++;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* user Interface module for WinAPI on Windows.
|
||||
*
|
||||
* Version: @(#)win_ui.c 1.0.5 2017/11/28
|
||||
* Version: @(#)win_ui.c 1.0.6 2017/11/28
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -30,12 +30,11 @@
|
||||
#include "../86box.h"
|
||||
#include "../config.h"
|
||||
#include "../device.h"
|
||||
#include "../mouse.h"
|
||||
#include "../keyboard.h"
|
||||
#include "../mouse.h"
|
||||
#include "../video/video.h"
|
||||
#include "../video/vid_ega.h" // for update_overscan
|
||||
#include "../plat.h"
|
||||
#include "../plat_mouse.h"
|
||||
#include "../plat_midi.h"
|
||||
#include "../ui.h"
|
||||
#include "win.h"
|
||||
@@ -651,6 +650,11 @@ ui_init(int nCmdShow)
|
||||
HACCEL haccel; /* handle to accelerator table */
|
||||
int bRet;
|
||||
|
||||
#if 0
|
||||
/* We should have an application-wide at_exit catcher. */
|
||||
atexit(plat_mouse_capture);
|
||||
#endif
|
||||
|
||||
/* Create our main window's class and register it. */
|
||||
wincl.hInstance = hinstance;
|
||||
wincl.lpszClassName = CLASS_NAME;
|
||||
@@ -735,6 +739,9 @@ ui_init(int nCmdShow)
|
||||
}
|
||||
keyboard_getkeymap();
|
||||
|
||||
/* Initialize the mouse module. */
|
||||
win_mouse_init();
|
||||
|
||||
/* Create the status bar window. */
|
||||
StatusBarCreate(hwndMain, IDC_STATUS, hinstance);
|
||||
|
||||
@@ -824,11 +831,13 @@ ui_init(int nCmdShow)
|
||||
if (mouse_capture)
|
||||
plat_mouse_capture(0);
|
||||
|
||||
/* Close down the emulator. */
|
||||
do_stop();
|
||||
|
||||
UnregisterClass(SUB_CLASS_NAME, hinstance);
|
||||
UnregisterClass(CLASS_NAME, hinstance);
|
||||
|
||||
/* Close down the emulator. */
|
||||
do_stop();
|
||||
win_mouse_close();
|
||||
|
||||
return(messages.wParam);
|
||||
}
|
||||
|
||||
@@ -1,394 +0,0 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Video API platform support for Windows.
|
||||
*
|
||||
* Version: @(#)win_video.c 1.0.8 2017/11/18
|
||||
*
|
||||
* Author: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
*
|
||||
* Copyright 2017 Fred N. van Kempen.
|
||||
*/
|
||||
#define UNICODE
|
||||
#include <windows.h>
|
||||
#include <windowsx.h>
|
||||
#include <commctrl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <wchar.h>
|
||||
#include "../86box.h"
|
||||
#include "../config.h"
|
||||
#include "../device.h"
|
||||
#include "../mouse.h"
|
||||
#include "../video/video.h"
|
||||
#include "../plat.h"
|
||||
#include "../plat_mouse.h"
|
||||
#include "../ui.h"
|
||||
#ifdef USE_VNC
|
||||
# include "../vnc.h"
|
||||
#endif
|
||||
#ifdef USE_RDP
|
||||
# include "../rdp.h"
|
||||
#endif
|
||||
#ifdef USE_WX
|
||||
# include "../wx/wx_ui.h"
|
||||
#else
|
||||
# include "win_ddraw.h"
|
||||
# include "win_d3d.h"
|
||||
#endif
|
||||
#include "win.h"
|
||||
|
||||
|
||||
static struct {
|
||||
char *name;
|
||||
int local;
|
||||
int (*init)(void *);
|
||||
void (*close)(void);
|
||||
void (*resize)(int x, int y);
|
||||
int (*pause)(void);
|
||||
} vid_apis[2][4] = {
|
||||
{
|
||||
#ifdef USE_WX
|
||||
{ "WxWidgets", 1, wx_init, wx_close, NULL, wx_pause },
|
||||
{ "WxWidgets", 1, wx_init, wx_close, NULL, wx_pause },
|
||||
#else
|
||||
{ "DDraw", 1, (int(*)(void*))ddraw_init, ddraw_close, NULL, ddraw_pause },
|
||||
{ "D3D", 1, (int(*)(void*))d3d_init, d3d_close, d3d_resize, d3d_pause },
|
||||
#endif
|
||||
#ifdef USE_VNC
|
||||
{ "VNC", 0, vnc_init, vnc_close, vnc_resize, vnc_pause },
|
||||
#else
|
||||
{ NULL, 0, NULL, NULL, NULL, NULL },
|
||||
#endif
|
||||
#ifdef USE_RDP
|
||||
{ "RDP", 0, rdp_init, rdp_close, rdp_resize, rdp_pause }
|
||||
#else
|
||||
{ NULL, 0, NULL, NULL, NULL, NULL }
|
||||
#endif
|
||||
},
|
||||
{
|
||||
#ifdef USE_WX
|
||||
{ "WxWidgets", 1, wx_init, wx_close, NULL, wx_pause },
|
||||
{ "WxWidgets", 1, wx_init, wx_close, NULL, wx_pause },
|
||||
#else
|
||||
{ "DDraw", 1, (int(*)(void*))ddraw_init_fs, ddraw_close, NULL, ddraw_pause },
|
||||
{ "D3D", 1, (int(*)(void*))d3d_init_fs, d3d_close, NULL, d3d_pause },
|
||||
#endif
|
||||
#ifdef USE_VNC
|
||||
{ "VNC", 0, vnc_init, vnc_close, vnc_resize, vnc_pause },
|
||||
#else
|
||||
{ NULL, 0, NULL, NULL, NULL, NULL },
|
||||
#endif
|
||||
#ifdef USE_RDP
|
||||
{ "RDP", 0, rdp_init, rdp_close, rdp_resize, rdp_pause }
|
||||
#else
|
||||
{ NULL, 0, NULL, NULL, NULL, NULL }
|
||||
#endif
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
/* Return the VIDAPI number for the given name. */
|
||||
int
|
||||
plat_vidapi(char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!strcasecmp(name, "default") || !strcasecmp(name, "system")) return(1);
|
||||
|
||||
for (i=0; i<4; i++) {
|
||||
if (vid_apis[0][i].name &&
|
||||
!strcasecmp(vid_apis[0][i].name, name)) return(i);
|
||||
}
|
||||
|
||||
/* Default value. */
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
/* Return the VIDAPI name for the given number. */
|
||||
char *
|
||||
plat_vidapi_name(int api)
|
||||
{
|
||||
char *name = "default";
|
||||
|
||||
switch(api) {
|
||||
#if USE_WX
|
||||
case 0:
|
||||
break;
|
||||
|
||||
case 1:
|
||||
name = "wxwidgets";
|
||||
break;
|
||||
#else
|
||||
case 0:
|
||||
name = "ddraw";
|
||||
break;
|
||||
|
||||
case 1:
|
||||
#if 0
|
||||
/* Direct3D is default. */
|
||||
name = "d3d";
|
||||
#endif
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef USE_VNC
|
||||
case 2:
|
||||
name = "vnc";
|
||||
break;
|
||||
|
||||
#endif
|
||||
#ifdef USE_RDP
|
||||
case 3:
|
||||
name = "rdp";
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
return(name);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
plat_setvid(int api)
|
||||
{
|
||||
int i;
|
||||
|
||||
pclog("Initializing VIDAPI: api=%d\n", api);
|
||||
startblit();
|
||||
video_wait_for_blit();
|
||||
|
||||
/* Close the (old) API. */
|
||||
vid_apis[0][vid_api].close();
|
||||
//#ifdef USE_WX
|
||||
// ui_check_menu_item(IDM_View_WX+vid_api, 0);
|
||||
//#endif
|
||||
vid_api = api;
|
||||
|
||||
#ifndef USE_WX
|
||||
if (vid_apis[0][vid_api].local)
|
||||
ShowWindow(hwndRender, SW_SHOW);
|
||||
else
|
||||
ShowWindow(hwndRender, SW_HIDE);
|
||||
#endif
|
||||
|
||||
/* Initialize the (new) API. */
|
||||
#ifdef USE_WX
|
||||
// ui_check_menu_item(IDM_View_WX+vid_api, 1);
|
||||
i = vid_apis[0][vid_api].init(NULL);
|
||||
#else
|
||||
i = vid_apis[0][vid_api].init((void *)hwndRender);
|
||||
#endif
|
||||
endblit();
|
||||
if (! i) return(0);
|
||||
|
||||
device_force_redraw();
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
/* Tell the renderers about a new screen resolution. */
|
||||
void
|
||||
plat_vidsize(int x, int y)
|
||||
{
|
||||
if (! vid_apis[video_fullscreen][vid_api].resize) return;
|
||||
|
||||
startblit();
|
||||
video_wait_for_blit();
|
||||
vid_apis[video_fullscreen][vid_api].resize(x, y);
|
||||
endblit();
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
get_vidpause(void)
|
||||
{
|
||||
return(vid_apis[video_fullscreen][vid_api].pause());
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
plat_setfullscreen(int on)
|
||||
{
|
||||
static int flag = 0;
|
||||
HWND *hw;
|
||||
|
||||
/* Want off and already off? */
|
||||
if (!on && !video_fullscreen) return;
|
||||
|
||||
/* Want on and already on? */
|
||||
if (on && video_fullscreen) return;
|
||||
|
||||
if (!on && !flag) {
|
||||
/* We want to leave FS mode. */
|
||||
flag = 1;
|
||||
|
||||
#ifdef USE_WX
|
||||
goto doit;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
if (video_fullscreen_first) {
|
||||
video_fullscreen_first = 0;
|
||||
ui_msgbox(MBX_INFO, (wchar_t *)IDS_2074);
|
||||
}
|
||||
|
||||
/* OK, claim the video. */
|
||||
#ifdef USE_WX
|
||||
doit:
|
||||
#endif
|
||||
startblit();
|
||||
video_wait_for_blit();
|
||||
|
||||
mouse_close();
|
||||
|
||||
/* Close the current mode, and open the new one. */
|
||||
vid_apis[video_fullscreen][vid_api].close();
|
||||
video_fullscreen = on;
|
||||
hw = (video_fullscreen) ? &hwndMain : &hwndRender;
|
||||
vid_apis[video_fullscreen][vid_api].init((void *) *hw);
|
||||
flag = 0;
|
||||
|
||||
#ifdef USE_WX
|
||||
wx_set_fullscreen(on);
|
||||
#endif
|
||||
|
||||
mouse_init();
|
||||
leave_fullscreen_flag = 0;
|
||||
|
||||
/* Release video and make it redraw the screen. */
|
||||
endblit();
|
||||
device_force_redraw();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
take_screenshot(void)
|
||||
{
|
||||
wchar_t path[1024], fn[128];
|
||||
struct tm *info;
|
||||
time_t now;
|
||||
|
||||
pclog("Screenshot: video API is: %i\n", vid_api);
|
||||
if ((vid_api < 0) || (vid_api > 1)) return;
|
||||
|
||||
memset(fn, 0, sizeof(fn));
|
||||
memset(path, 0, sizeof(path));
|
||||
|
||||
(void)time(&now);
|
||||
info = localtime(&now);
|
||||
|
||||
plat_append_filename(path, cfg_path, SCREENSHOT_PATH, sizeof(path)-2);
|
||||
|
||||
if (! plat_dir_check(path))
|
||||
plat_dir_create(path);
|
||||
|
||||
wcscat(path, L"\\");
|
||||
|
||||
switch(vid_api) {
|
||||
#ifdef USE_WX
|
||||
case 0:
|
||||
case 1:
|
||||
wcsftime(fn, 128, L"%Y%m%d_%H%M%S.png", info);
|
||||
wcscat(path, fn);
|
||||
wx_screenshot(path);
|
||||
break;
|
||||
#else
|
||||
case 0: /* ddraw */
|
||||
wcsftime(fn, 128, L"%Y%m%d_%H%M%S.bmp", info);
|
||||
wcscat(path, fn);
|
||||
ddraw_take_screenshot(path);
|
||||
break;
|
||||
|
||||
case 1: /* d3d9 */
|
||||
wcsftime(fn, 128, L"%Y%m%d_%H%M%S.png", info);
|
||||
wcscat(path, fn);
|
||||
d3d_take_screenshot(path);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef USE_VNC
|
||||
case 2: /* vnc */
|
||||
wcsftime(fn, 128, L"%Y%m%d_%H%M%S.png", info);
|
||||
wcscat(path, fn);
|
||||
vnc_take_screenshot(path);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void /* plat_ */
|
||||
startblit(void)
|
||||
{
|
||||
WaitForSingleObject(ghMutex, INFINITE);
|
||||
}
|
||||
|
||||
|
||||
void /* plat_ */
|
||||
endblit(void)
|
||||
{
|
||||
ReleaseMutex(ghMutex);
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
/* Tell the UI and/or renderers about a new screen resolution. */
|
||||
void
|
||||
plat_resize(int x, int y)
|
||||
{
|
||||
pclog("PLAT: VID[%d,%d] resizing to %dx%d\n", video_fullscreen, vid_api, x, y);
|
||||
|
||||
/* Do not accept these sizes. */
|
||||
if (x==0 || x<320 || y==0 || y<200) return;
|
||||
|
||||
/* First, see if we should resize the UI window. */
|
||||
if (! vid_resize)
|
||||
#ifdef USE_WX
|
||||
wx_resize(x, y);
|
||||
#else
|
||||
ui_resize(x, y);
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
/* Now, tell the renderer about the new screen size we want. */
|
||||
if (vid_apis[video_fullscreen][vid_api].resize) {
|
||||
startblit();
|
||||
vid_apis[video_fullscreen][vid_api].resize(x, y);
|
||||
endblit();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
plat_mouse_capture(int on)
|
||||
{
|
||||
if (on && !mouse_capture) {
|
||||
/* Enable the in-app mouse. */
|
||||
#ifdef USE_WX
|
||||
wx_capture_mouse(1);
|
||||
#endif
|
||||
|
||||
mouse_capture = 1;
|
||||
} else if (!on && mouse_capture) {
|
||||
/* Disable the in-app mouse. */
|
||||
#ifdef USE_WX
|
||||
wx_capture_mouse(0);
|
||||
#endif
|
||||
|
||||
mouse_capture = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user