Lowercase all CAPS to prevent case sensitive errors in non-Windows platforms
22
src/win/86Box.manifest
Normal file
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
|
||||
<assemblyIdentity
|
||||
version="1.20.0.0"
|
||||
processorArchitecture="*"
|
||||
name="86Box.exe"
|
||||
type="win32"
|
||||
/>
|
||||
<description>Emulator for X86-based systems.</description>
|
||||
<dependency>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity
|
||||
type="win32"
|
||||
name="Microsoft.Windows.Common-Controls"
|
||||
version="6.0.0.0"
|
||||
processorArchitecture="*"
|
||||
publicKeyToken="6595b64144ccf1df"
|
||||
language="*"
|
||||
/>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
</assembly>
|
||||
958
src/win/86Box.rc
Normal file
@@ -0,0 +1,958 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Windows resource script.
|
||||
*
|
||||
* Version: @(#)86Box.rc 1.0.7 2017/08/26
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Copyright 2016,2017 Miran Grca.
|
||||
*/
|
||||
#include <inttypes.h>
|
||||
#define IN_RESOURCE_H
|
||||
#include "resource.h"
|
||||
#include "../86box.h"
|
||||
#undef IN_RESOURCE_H
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
#define APSTUDIO_HIDDEN_SYMBOLS
|
||||
#include "windows.h"
|
||||
#undef APSTUDIO_HIDDEN_SYMBOLS
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// English (U.S.) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
#pragma code_page(1252)
|
||||
#endif //_WIN32
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Menu
|
||||
//
|
||||
|
||||
MAINMENU MENU DISCARDABLE
|
||||
BEGIN
|
||||
POPUP "&Action"
|
||||
BEGIN
|
||||
MENUITEM "&Hard Reset", IDM_ACTION_HRESET
|
||||
MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD
|
||||
MENUITEM "Ctrl+Alt+&Esc", IDM_ACTION_CTRL_ALT_ESC
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "E&xit", IDM_ACTION_EXIT
|
||||
END
|
||||
POPUP "&View"
|
||||
BEGIN
|
||||
MENUITEM "&Resizeable window", IDM_VID_RESIZE
|
||||
MENUITEM "R&emember size && position", IDM_VID_REMEMBER
|
||||
MENUITEM SEPARATOR
|
||||
POPUP "Re&nderer"
|
||||
BEGIN
|
||||
MENUITEM "&DirectDraw", IDM_VID_DDRAW
|
||||
MENUITEM "Direct&3D 9", IDM_VID_D3D
|
||||
END
|
||||
MENUITEM SEPARATOR
|
||||
POPUP "&Window scale factor"
|
||||
BEGIN
|
||||
MENUITEM "&0.5x", IDM_VID_SCALE_1X
|
||||
MENUITEM "&1x", IDM_VID_SCALE_2X
|
||||
MENUITEM "1.&5x", IDM_VID_SCALE_3X
|
||||
MENUITEM "&2x", IDM_VID_SCALE_4X
|
||||
END
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "&Fullscreen\tCtrl+Alt+PageUP", IDM_VID_FULLSCREEN
|
||||
POPUP "Fullscreen &stretch mode"
|
||||
BEGIN
|
||||
MENUITEM "&Full screen stretch", IDM_VID_FS_FULL
|
||||
MENUITEM "&4:3", IDM_VID_FS_43
|
||||
MENUITEM "&Square pixels", IDM_VID_FS_SQ
|
||||
MENUITEM "&Integer scale", IDM_VID_FS_INT
|
||||
END
|
||||
POPUP "E&GA/(S)VGA settings"
|
||||
BEGIN
|
||||
MENUITEM "&Inverted VGA monitor", IDM_VID_INVERT
|
||||
MENUITEM "E&GA/(S)VGA overscan", IDM_VID_OVERSCAN
|
||||
POPUP "VGA screen &type"
|
||||
BEGIN
|
||||
MENUITEM "RGB &Color", IDM_VID_GRAY_RGB
|
||||
MENUITEM "&RGB Grayscale", IDM_VID_GRAY_MONO
|
||||
MENUITEM "&Amber monitor", IDM_VID_GRAY_AMBER
|
||||
MENUITEM "&Green monitor", IDM_VID_GRAY_GREEN
|
||||
MENUITEM "&White monitor", IDM_VID_GRAY_WHITE
|
||||
END
|
||||
POPUP "Grayscale &conversion type"
|
||||
BEGIN
|
||||
MENUITEM "BT&601 (NTSC/PAL)", IDM_VID_GRAYCT_601
|
||||
MENUITEM "BT&709 (HDTV)", IDM_VID_GRAYCT_709
|
||||
MENUITEM "&Average", IDM_VID_GRAYCT_AVE
|
||||
END
|
||||
END
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "F&orce 4:3 display ratio", IDM_VID_FORCE43
|
||||
MENUITEM "Change contrast for &monochrome display", IDM_VID_CGACON
|
||||
END
|
||||
POPUP "&Tools"
|
||||
BEGIN
|
||||
MENUITEM "&Settings...", IDM_CONFIG
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "&Load configuration...", IDM_CONFIG_LOAD
|
||||
MENUITEM "&Save configuration...", IDM_CONFIG_SAVE
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "S&tatus", IDM_STATUS
|
||||
MENUITEM "Take s&creenshot\tCtrl+F11", IDM_ACTION_SCREENSHOT
|
||||
END
|
||||
#if defined(ENABLE_LOG_TOGGLES) || defined(ENABLE_LOG_COMMANDS)
|
||||
POPUP "&Logging"
|
||||
BEGIN
|
||||
# ifdef ENABLE_BUSLOGIC_LOG
|
||||
MENUITEM "Enable BusLogic logs\tCtrl+F4", IDM_LOG_BUSLOGIC
|
||||
# endif
|
||||
# ifdef ENABLE_CDROM_LOG
|
||||
MENUITEM "Enable CD-ROM logs\tCtrl+F5", IDM_LOG_CDROM
|
||||
# endif
|
||||
# ifdef ENABLE_D86F_LOG
|
||||
MENUITEM "Enable floppy (86F) logs\tCtrl+F6", IDM_LOG_D86F
|
||||
# endif
|
||||
# ifdef ENABLE_FDC_LOG
|
||||
MENUITEM "Enable floppy controller logs\tCtrl+F7", IDM_LOG_FDC
|
||||
# endif
|
||||
# ifdef ENABLE_IDE_LOG
|
||||
MENUITEM "Enable IDE logs\tCtrl+F8", IDM_LOG_IDE
|
||||
# endif
|
||||
# ifdef ENABLE_SERIAL_LOG
|
||||
MENUITEM "Enable Serial Port logs\tCtrl+F3", IDM_LOG_SERIAL
|
||||
# endif
|
||||
#ifdef USE_NETWORK
|
||||
# ifdef ENABLE_NIC_LOG
|
||||
MENUITEM "Enable Network logs\tCtrl+F9", IDM_LOG_NIC
|
||||
# endif
|
||||
#endif
|
||||
# ifdef ENABLE_LOG_COMMANDS
|
||||
# ifdef ENABLE_LOG_TOGGLES
|
||||
MENUITEM SEPARATOR
|
||||
# endif
|
||||
# ifdef ENABLE_LOG_BREAKPOINT
|
||||
MENUITEM "&Log breakpoint\tCtrl+F10", IDM_LOG_BREAKPOINT
|
||||
# endif
|
||||
# ifdef ENABLE_VRAM_DUMP
|
||||
MENUITEM "Dump &video RAM\tCtrl+F1", IDM_DUMP_VRAM
|
||||
# endif
|
||||
# endif
|
||||
END
|
||||
#endif
|
||||
POPUP "&Help"
|
||||
BEGIN
|
||||
MENUITEM "&About 86Box...", IDM_ABOUT
|
||||
END
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Accelerator
|
||||
//
|
||||
|
||||
MAINACCEL ACCELERATORS MOVEABLE PURE
|
||||
BEGIN
|
||||
#ifdef ENABLE_VRAM_DUMP
|
||||
VK_F1, IDM_DUMP_VRAM, CONTROL, VIRTKEY
|
||||
#endif
|
||||
#ifdef ENABLE_SERIAL_LOG
|
||||
VK_F3, IDM_LOG_SERIAL, CONTROL, VIRTKEY
|
||||
#endif
|
||||
#ifdef ENABLE_BUSLOGIC_LOG
|
||||
VK_F4, IDM_LOG_BUSLOGIC, CONTROL, VIRTKEY
|
||||
#endif
|
||||
#ifdef ENABLE_CDROM_LOG
|
||||
VK_F5, IDM_LOG_CDROM, CONTROL, VIRTKEY
|
||||
#endif
|
||||
#ifdef ENABLE_D86F_LOG
|
||||
VK_F6, IDM_LOG_D86F, CONTROL, VIRTKEY
|
||||
#endif
|
||||
#ifdef ENABLE_FDC_LOG
|
||||
VK_F7, IDM_LOG_FDC, CONTROL, VIRTKEY
|
||||
#endif
|
||||
#ifdef ENABLE_IDE_LOG
|
||||
VK_F8, IDM_LOG_IDE, CONTROL, VIRTKEY
|
||||
#endif
|
||||
#ifdef ENABLE_NIC_LOG
|
||||
VK_F9, IDM_LOG_NIC, CONTROL, VIRTKEY
|
||||
#endif
|
||||
#ifdef ENABLE_LOG_BREAKPOINT
|
||||
VK_F10, IDM_LOG_BREAKPOINT, CONTROL, VIRTKEY
|
||||
#endif
|
||||
VK_PRIOR,IDM_VID_FULLSCREEN, VIRTKEY, CONTROL , ALT
|
||||
VK_F11, IDM_ACTION_SCREENSHOT, VIRTKEY, CONTROL
|
||||
VK_F12, IDM_ACTION_RESET_CAD, VIRTKEY, CONTROL
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Dialog
|
||||
//
|
||||
DLG_ABOUT DIALOG DISCARDABLE 0, 0, 209, 114
|
||||
STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "About 86Box"
|
||||
FONT 9, "Segoe UI"
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "OK",IDOK,129,94,71,12
|
||||
ICON 100,IDC_ABOUT_ICON,7,7,20,20
|
||||
LTEXT "86Box v2.00 - A fork of PCem\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, MoochMcGee, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2. See LICENSE for more information.",
|
||||
IDC_ABOUT_ICON,54,7,146,73
|
||||
CONTROL "",IDC_ABOUT_ICON,"Static",SS_BLACKFRAME | SS_SUNKEN,0,
|
||||
86,208,1
|
||||
END
|
||||
|
||||
DLG_STATUS DIALOG DISCARDABLE 0, 0, 186, 386
|
||||
STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Status"
|
||||
FONT 9, "Segoe UI"
|
||||
BEGIN
|
||||
LTEXT "1",IDT_SDEVICE,16,16,180,1000
|
||||
LTEXT "1",IDT_STEXT,16,186,180,1000
|
||||
END
|
||||
|
||||
DLG_CONFIG DIALOG DISCARDABLE 0, 0, 366, 241
|
||||
STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "86Box Settings"
|
||||
FONT 9, "Segoe UI"
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "OK",IDOK,246,220,50,14
|
||||
PUSHBUTTON "Cancel",IDCANCEL,307,220,50,14
|
||||
CONTROL "List2",IDC_SETTINGSCATLIST,"SysListView32",LVS_LIST |
|
||||
LVS_SHOWSELALWAYS | LVS_SINGLESEL | WS_BORDER | WS_TABSTOP,7,7,90,197
|
||||
CONTROL "",-1,"Static",SS_BLACKFRAME | SS_SUNKEN,1,211,363,1
|
||||
/* Leave this commented out until we get into localization. */
|
||||
#if 0
|
||||
LTEXT "Language:",IDT_1700,7,222,41,10
|
||||
COMBOBOX IDC_COMBO_LANG,48,221,108,120,CBS_DROPDOWN | WS_VSCROLL |
|
||||
WS_TABSTOP
|
||||
#endif
|
||||
END
|
||||
|
||||
DLG_CFG_MACHINE DIALOG DISCARDABLE 97, 0, 267, 132
|
||||
STYLE DS_CONTROL | WS_CHILD
|
||||
FONT 9, "Segoe UI"
|
||||
BEGIN
|
||||
COMBOBOX IDC_COMBO_MACHINE,71,7,138,120,CBS_DROPDOWNLIST |
|
||||
WS_VSCROLL | WS_TABSTOP
|
||||
LTEXT "Machine:",IDT_1701,7,8,60,10
|
||||
PUSHBUTTON "Configure",IDC_CONFIGURE_MACHINE,214,7,46,12
|
||||
COMBOBOX IDC_COMBO_CPU_TYPE,71,25,45,120,CBS_DROPDOWNLIST |
|
||||
WS_VSCROLL | WS_TABSTOP
|
||||
LTEXT "CPU type:",IDT_1702,7,26,59,10
|
||||
COMBOBOX IDC_COMBO_CPU,145,25,115,120,CBS_DROPDOWNLIST |
|
||||
WS_VSCROLL | WS_TABSTOP
|
||||
LTEXT "CPU:",IDT_1704,124,26,18,10
|
||||
COMBOBOX IDC_COMBO_WS,71,44,189,120,CBS_DROPDOWNLIST | WS_VSCROLL |
|
||||
WS_TABSTOP
|
||||
LTEXT "Wait states:",IDT_1703,7,45,60,10
|
||||
EDITTEXT IDC_MEMTEXT,70,63,45,12,ES_AUTOHSCROLL | ES_NUMBER
|
||||
CONTROL "",IDC_MEMSPIN,"msctls_updown32",UDS_SETBUDDYINT |
|
||||
UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS,113,63,
|
||||
12,12
|
||||
LTEXT "MB",IDT_1705,123,64,10,10
|
||||
LTEXT "Memory:",IDT_1706,7,64,30,10
|
||||
LTEXT "NVR Path:",IDT_1700,7,83,60,10
|
||||
EDITTEXT IDC_EDIT_NVR_PATH,71,82,138,12,ES_AUTOHSCROLL
|
||||
PUSHBUTTON "&Specify...",IDC_BUTTON_NVR_PATH,214,82,46,12
|
||||
CONTROL "Dynamic Recompiler",IDC_CHECK_DYNAREC,"Button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,7,100,94,10
|
||||
CONTROL "Enable FPU",IDC_CHECK_FPU,"Button",BS_AUTOCHECKBOX |
|
||||
WS_TABSTOP,147,100,113,10
|
||||
CONTROL "Enable time sync",IDC_CHECK_SYNC,"Button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,7,115,102,10
|
||||
END
|
||||
|
||||
DLG_CFG_VIDEO DIALOG DISCARDABLE 97, 0, 267, 63
|
||||
STYLE DS_CONTROL | WS_CHILD
|
||||
FONT 9, "Segoe UI"
|
||||
BEGIN
|
||||
LTEXT "Video:",IDT_1707,7,8,55,10
|
||||
COMBOBOX IDC_COMBO_VIDEO,71,7,140,120,CBS_DROPDOWNLIST |
|
||||
WS_VSCROLL | WS_TABSTOP
|
||||
PUSHBUTTON "Configure",IDC_CONFIGURE_VID,214,7,46,12
|
||||
COMBOBOX IDC_COMBO_VIDEO_SPEED,71,25,189,120,CBS_DROPDOWNLIST |
|
||||
WS_VSCROLL | WS_TABSTOP
|
||||
LTEXT "Video speed:",IDT_1708,7,26,58,10
|
||||
CONTROL "Voodoo Graphics",IDC_CHECK_VOODOO,"Button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,7,45,199,10
|
||||
PUSHBUTTON "Configure",IDC_BUTTON_VOODOO,214,44,46,12
|
||||
END
|
||||
|
||||
DLG_CFG_INPUT DIALOG DISCARDABLE 97, 0, 267, 65
|
||||
STYLE DS_CONTROL | WS_CHILD
|
||||
FONT 9, "Segoe UI"
|
||||
BEGIN
|
||||
LTEXT "Mouse :",IDT_1709,7,8,57,10
|
||||
COMBOBOX IDC_COMBO_MOUSE,71,7,189,120,CBS_DROPDOWNLIST | WS_VSCROLL |
|
||||
WS_TABSTOP
|
||||
LTEXT "Joystick :",IDT_1710,7,26,58,10
|
||||
COMBOBOX IDC_COMBO_JOYSTICK,71,25,189,120,CBS_DROPDOWNLIST |
|
||||
WS_VSCROLL | WS_TABSTOP
|
||||
PUSHBUTTON "Joystick 1...",IDC_JOY1,7,44,50,14
|
||||
PUSHBUTTON "Joystick 2...",IDC_JOY2,74,44,50,14
|
||||
PUSHBUTTON "Joystick 3...",IDC_JOY3,141,44,50,14
|
||||
PUSHBUTTON "Joystick 4...",IDC_JOY4,209,44,50,14
|
||||
END
|
||||
|
||||
DLG_CFG_SOUND DIALOG DISCARDABLE 97, 0, 267, 116
|
||||
STYLE DS_CONTROL | WS_CHILD
|
||||
FONT 9, "Segoe UI"
|
||||
BEGIN
|
||||
COMBOBOX IDC_COMBO_SOUND,71,7,140,120,CBS_DROPDOWNLIST | WS_VSCROLL |
|
||||
WS_TABSTOP
|
||||
LTEXT "Sound card:",IDT_1711,7,8,59,10
|
||||
PUSHBUTTON "Configure",IDC_CONFIGURE_SND,214,7,46,12
|
||||
|
||||
COMBOBOX IDC_COMBO_MIDI,71,25,140,120,CBS_DROPDOWNLIST | WS_VSCROLL |
|
||||
WS_TABSTOP
|
||||
LTEXT "MIDI Out Device:",IDT_1712,7,26,59,10
|
||||
PUSHBUTTON "Configure",IDC_CONFIGURE_MIDI,214,25,46,12
|
||||
|
||||
CONTROL "Standalone MPU-401",IDC_CHECK_MPU401,"Button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,7,45,199,10
|
||||
PUSHBUTTON "Configure",IDC_CONFIGURE_MPU401,214,44,46,12
|
||||
|
||||
CONTROL "Innovation SSI-2001",IDC_CHECK_SSI,"Button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,7,63,94,10
|
||||
CONTROL "CMS / Game Blaster",IDC_CHECK_CMS,"Button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,147,63,94,10
|
||||
|
||||
CONTROL "Gravis Ultrasound",IDC_CHECK_GUS,"Button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,7,81,94,10
|
||||
CONTROL "Use Nuked OPL",IDC_CHECK_NUKEDOPL,"Button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,147,81,94,10
|
||||
|
||||
CONTROL "Use FLOAT32 sound",IDC_CHECK_FLOAT,"Button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,7,99,94,10
|
||||
END
|
||||
|
||||
#ifdef USE_NETWORK
|
||||
DLG_CFG_NETWORK DIALOG DISCARDABLE 97, 0, 267, 63
|
||||
STYLE DS_CONTROL | WS_CHILD
|
||||
FONT 9, "Segoe UI"
|
||||
BEGIN
|
||||
LTEXT "Network type:",IDT_1713,7,8,59,10
|
||||
COMBOBOX IDC_COMBO_NET_TYPE,71,7,189,120,CBS_DROPDOWNLIST | WS_VSCROLL |
|
||||
WS_TABSTOP
|
||||
|
||||
LTEXT "PCap device:",IDT_1714,7,26,59,10
|
||||
COMBOBOX IDC_COMBO_PCAP,71,25,189,120,CBS_DROPDOWNLIST | WS_VSCROLL |
|
||||
WS_TABSTOP
|
||||
|
||||
LTEXT "Network adapter:",IDT_1715,7,44,59,10
|
||||
COMBOBOX IDC_COMBO_NET,71,43,140,120,CBS_DROPDOWNLIST | WS_VSCROLL |
|
||||
WS_TABSTOP
|
||||
PUSHBUTTON "Configure",IDC_CONFIGURE_NET,214,43,46,12
|
||||
END
|
||||
#endif
|
||||
|
||||
DLG_CFG_PERIPHERALS DIALOG DISCARDABLE 97, 0, 267, 115
|
||||
STYLE DS_CONTROL | WS_CHILD
|
||||
FONT 9, "Segoe UI"
|
||||
BEGIN
|
||||
LTEXT "SCSI Controller:",IDT_1716,7,8,59,10
|
||||
COMBOBOX IDC_COMBO_SCSI,71,7,140,120,CBS_DROPDOWNLIST |
|
||||
WS_VSCROLL | WS_TABSTOP
|
||||
PUSHBUTTON "Configure",IDC_CONFIGURE_SCSI,214,7,46,12
|
||||
|
||||
LTEXT "HD Controller:",IDT_1717,7,26,61,10
|
||||
COMBOBOX IDC_COMBO_HDC,71,25,189,120,CBS_DROPDOWNLIST |
|
||||
WS_VSCROLL | WS_TABSTOP
|
||||
|
||||
LTEXT "Tertiary IDE:",IDT_1718,7,44,61,10
|
||||
COMBOBOX IDC_COMBO_IDE_TER,71,43,189,120,CBS_DROPDOWNLIST |
|
||||
WS_VSCROLL | WS_TABSTOP
|
||||
|
||||
LTEXT "Quaternary IDE:",IDT_1719,7,62,61,10
|
||||
COMBOBOX IDC_COMBO_IDE_QUA,71,61,189,120,CBS_DROPDOWNLIST |
|
||||
WS_VSCROLL | WS_TABSTOP
|
||||
|
||||
CONTROL "Serial port 1",IDC_CHECK_SERIAL1,"Button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,7,80,94,10
|
||||
CONTROL "Serial port 2",IDC_CHECK_SERIAL2,"Button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,147,80,94,10
|
||||
|
||||
CONTROL "Parallel port",IDC_CHECK_PARALLEL,"Button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,7,98,94,10
|
||||
CONTROL "ISABugger device",IDC_CHECK_BUGGER,"Button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,147,98,94,10
|
||||
END
|
||||
|
||||
DLG_CFG_HARD_DISKS DIALOG DISCARDABLE 97, 0, 267, 154
|
||||
STYLE DS_CONTROL | WS_CHILD
|
||||
FONT 9, "Segoe UI"
|
||||
BEGIN
|
||||
CONTROL "List1",IDC_LIST_HARD_DISKS,"SysListView32",LVS_REPORT |
|
||||
LVS_SHOWSELALWAYS | LVS_SINGLESEL | WS_BORDER |
|
||||
WS_TABSTOP,7,18,253,92
|
||||
LTEXT "Hard disks:",IDT_1720,7,7,34,8
|
||||
PUSHBUTTON "&New...",IDC_BUTTON_HDD_ADD_NEW,60,137,62,10
|
||||
PUSHBUTTON "&Existing...",IDC_BUTTON_HDD_ADD,129,137,62,10
|
||||
PUSHBUTTON "&Remove",IDC_BUTTON_HDD_REMOVE,198,137,62,10
|
||||
COMBOBOX IDC_COMBO_HD_BUS,33,117,90,12,CBS_DROPDOWNLIST |
|
||||
WS_VSCROLL | WS_TABSTOP
|
||||
LTEXT "Bus:",IDT_1721,7,118,24,8
|
||||
COMBOBOX IDC_COMBO_HD_CHANNEL,170,117,90,12,CBS_DROPDOWNLIST |
|
||||
WS_VSCROLL | WS_TABSTOP
|
||||
LTEXT "Channel:",IDT_1722,131,118,38,8
|
||||
COMBOBOX IDC_COMBO_HD_ID,170,117,22,12,CBS_DROPDOWNLIST |
|
||||
WS_VSCROLL | WS_TABSTOP
|
||||
LTEXT "ID:",IDT_1723,131,118,38,8
|
||||
COMBOBOX IDC_COMBO_HD_LUN,239,117,22,12,CBS_DROPDOWNLIST |
|
||||
WS_VSCROLL | WS_TABSTOP
|
||||
LTEXT "LUN:",IDT_1724,200,118,38,8
|
||||
COMBOBOX IDC_COMBO_HD_CHANNEL_IDE,170,117,90,12,CBS_DROPDOWNLIST |
|
||||
WS_VSCROLL | WS_TABSTOP
|
||||
END
|
||||
|
||||
DLG_CFG_HARD_DISKS_ADD DIALOG DISCARDABLE 0, 0, 219, 111
|
||||
STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Add Hard Disk"
|
||||
FONT 9, "Segoe UI"
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "OK",IDOK,55,89,50,14
|
||||
PUSHBUTTON "Cancel",IDCANCEL,112,89,50,14
|
||||
EDITTEXT IDC_EDIT_HD_FILE_NAME,7,16,153,12
|
||||
PUSHBUTTON "&Specify...",IDC_CFILE,167,16,44,12
|
||||
EDITTEXT IDC_EDIT_HD_SPT,183,34,28,12
|
||||
EDITTEXT IDC_EDIT_HD_HPC,112,34,28,12
|
||||
EDITTEXT IDC_EDIT_HD_CYL,42,34,28,12
|
||||
EDITTEXT IDC_EDIT_HD_SIZE,42,52,28,12
|
||||
COMBOBOX IDC_COMBO_HD_TYPE,113,52,98,12,CBS_DROPDOWNLIST |
|
||||
WS_VSCROLL | WS_TABSTOP
|
||||
LTEXT "Sectors:",IDT_1726,154,35,27,10
|
||||
LTEXT "Heads:",IDT_1727,81,35,29,8
|
||||
LTEXT "Cylinders:",IDT_1728,7,35,32,12
|
||||
LTEXT "Size (MB):",IDT_1729,7,54,33,8
|
||||
LTEXT "Type:",IDT_1730,86,54,24,8
|
||||
LTEXT "File name:",IDT_1731,7,7,204,9
|
||||
COMBOBOX IDC_COMBO_HD_BUS,33,71,58,12,CBS_DROPDOWNLIST |
|
||||
WS_VSCROLL | WS_TABSTOP
|
||||
LTEXT "Bus:",IDT_1721,7,72,24,8
|
||||
COMBOBOX IDC_COMBO_HD_CHANNEL,134,71,77,12,CBS_DROPDOWNLIST |
|
||||
WS_VSCROLL | WS_TABSTOP
|
||||
LTEXT "Channel:",IDT_1722,99,72,34,8
|
||||
COMBOBOX IDC_COMBO_HD_ID,133,71,26,12,CBS_DROPDOWNLIST |
|
||||
WS_VSCROLL | WS_TABSTOP
|
||||
LTEXT "ID:",IDT_1723,117,72,15,8
|
||||
COMBOBOX IDC_COMBO_HD_LUN,185,71,26,12,CBS_DROPDOWNLIST |
|
||||
WS_VSCROLL | WS_TABSTOP
|
||||
LTEXT "LUN:",IDT_1724,168,72,15,8
|
||||
COMBOBOX IDC_COMBO_HD_CHANNEL_IDE,134,71,77,12,CBS_DROPDOWNLIST |
|
||||
WS_VSCROLL | WS_TABSTOP
|
||||
END
|
||||
|
||||
DLG_CFG_REMOVABLE_DEVICES DIALOG DISCARDABLE 97, 0, 267, 202
|
||||
STYLE DS_CONTROL | WS_CHILD
|
||||
FONT 9, "Segoe UI"
|
||||
BEGIN
|
||||
CONTROL "List1",IDC_LIST_FLOPPY_DRIVES,"SysListView32",
|
||||
LVS_REPORT | LVS_SHOWSELALWAYS | LVS_SINGLESEL | WS_BORDER |
|
||||
WS_TABSTOP,7,18,253,60
|
||||
LTEXT "Floppy drives:",IDT_1737,7,7,43,8
|
||||
COMBOBOX IDC_COMBO_FD_TYPE,33,85,90,12,CBS_DROPDOWNLIST |
|
||||
WS_VSCROLL | WS_TABSTOP
|
||||
LTEXT "Type:",IDT_1738,7,86,24,8
|
||||
CONTROL "Turbo timings",IDC_CHECKTURBO,"Button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,131,86,64,10
|
||||
CONTROL "Check BPB",IDC_CHECKBPB,"Button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,196,86,64,10
|
||||
CONTROL "List1",IDC_LIST_CDROM_DRIVES,"SysListView32",LVS_REPORT |
|
||||
LVS_SHOWSELALWAYS | LVS_SINGLESEL | WS_BORDER |
|
||||
WS_TABSTOP,7,116,253,60
|
||||
LTEXT "CD-ROM drives:",IDT_1739,7,106,50,8
|
||||
COMBOBOX IDC_COMBO_CD_BUS,33,183,90,12,CBS_DROPDOWNLIST |
|
||||
WS_VSCROLL | WS_TABSTOP
|
||||
LTEXT "Bus:",IDT_1740,7,184,24,8
|
||||
COMBOBOX IDC_COMBO_CD_ID,170,183,22,12,CBS_DROPDOWNLIST |
|
||||
WS_VSCROLL | WS_TABSTOP
|
||||
LTEXT "ID:",IDT_1741,131,184,38,8
|
||||
COMBOBOX IDC_COMBO_CD_LUN,239,183,22,12,CBS_DROPDOWNLIST |
|
||||
WS_VSCROLL | WS_TABSTOP
|
||||
LTEXT "LUN:",IDT_1742,200,184,38,8
|
||||
COMBOBOX IDC_COMBO_CD_CHANNEL_IDE,170,183,90,12,CBS_DROPDOWNLIST |
|
||||
WS_VSCROLL | WS_TABSTOP
|
||||
LTEXT "Channel:",IDT_1743,131,184,38,8
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 24
|
||||
//
|
||||
|
||||
1 24 MOVEABLE PURE "86Box.manifest"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Icon
|
||||
//
|
||||
|
||||
// Icon with lowest ID value placed first to ensure application icon
|
||||
// remains consistent on all systems.
|
||||
#ifdef RELEASE_BUILD
|
||||
/* Icon by Devcore - https://commons.wikimedia.org/wiki/File:Icon_PC_256x256.png */
|
||||
100 ICON DISCARDABLE "win/icons/86Box-RB.ico"
|
||||
#else
|
||||
/* Icon by Devcore - https://commons.wikimedia.org/wiki/File:Icon_PC2_256x256.png */
|
||||
100 ICON DISCARDABLE "win/icons/86Box.ico"
|
||||
#endif
|
||||
128 ICON DISCARDABLE "win/icons/floppy_525.ico"
|
||||
129 ICON DISCARDABLE "win/icons/floppy_525_active.ico"
|
||||
144 ICON DISCARDABLE "win/icons/floppy_35.ico"
|
||||
145 ICON DISCARDABLE "win/icons/floppy_35_active.ico"
|
||||
160 ICON DISCARDABLE "win/icons/cdrom.ico"
|
||||
161 ICON DISCARDABLE "win/icons/cdrom_active.ico"
|
||||
176 ICON DISCARDABLE "win/icons/removable_disk.ico"
|
||||
177 ICON DISCARDABLE "win/icons/removable_disk_active.ico"
|
||||
192 ICON DISCARDABLE "win/icons/hard_disk.ico"
|
||||
193 ICON DISCARDABLE "win/icons/hard_disk_active.ico"
|
||||
#ifdef USE_NETWORK
|
||||
208 ICON DISCARDABLE "win/icons/network.ico"
|
||||
209 ICON DISCARDABLE "win/icons/network_active.ico"
|
||||
#endif
|
||||
256 ICON DISCARDABLE "win/icons/machine.ico"
|
||||
257 ICON DISCARDABLE "win/icons/display.ico"
|
||||
258 ICON DISCARDABLE "win/icons/input_devices.ico"
|
||||
259 ICON DISCARDABLE "win/icons/sound.ico"
|
||||
#ifdef USE_NETWORK
|
||||
260 ICON DISCARDABLE "win/icons/network.ico"
|
||||
261 ICON DISCARDABLE "win/icons/other_peripherals.ico"
|
||||
262 ICON DISCARDABLE "win/icons/hard_disk.ico"
|
||||
263 ICON DISCARDABLE "win/icons/removable_devices.ico"
|
||||
#else
|
||||
260 ICON DISCARDABLE "win/icons/other_peripherals.ico"
|
||||
261 ICON DISCARDABLE "win/icons/hard_disk.ico"
|
||||
262 ICON DISCARDABLE "win/icons/removable_devices.ico"
|
||||
#endif
|
||||
384 ICON DISCARDABLE "win/icons/floppy_525_empty.ico"
|
||||
385 ICON DISCARDABLE "win/icons/floppy_525_empty_active.ico"
|
||||
400 ICON DISCARDABLE "win/icons/floppy_35_empty.ico"
|
||||
401 ICON DISCARDABLE "win/icons/floppy_35_empty_active.ico"
|
||||
416 ICON DISCARDABLE "win/icons/cdrom_empty.ico"
|
||||
417 ICON DISCARDABLE "win/icons/cdrom_empty_active.ico"
|
||||
432 ICON DISCARDABLE "win/icons/removable_disk_empty.ico"
|
||||
433 ICON DISCARDABLE "win/icons/removable_disk_empty_active.ico"
|
||||
512 ICON DISCARDABLE "win/icons/floppy_disabled.ico"
|
||||
514 ICON DISCARDABLE "win/icons/cdrom_disabled.ico"
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
|
||||
"#include ""windows.h""\r\n"
|
||||
"#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
|
||||
"#include ""resources.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DESIGNINFO
|
||||
//
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
GUIDELINES DESIGNINFO DISCARDABLE
|
||||
BEGIN
|
||||
CONFIGUREDLG_MAIN, DIALOG
|
||||
BEGIN
|
||||
RIGHTMARGIN, 365
|
||||
END
|
||||
|
||||
ABOUTDLG, DIALOG
|
||||
BEGIN
|
||||
RIGHTMARGIN, 208
|
||||
END
|
||||
|
||||
CONFIGUREDLG_MACHINE, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 260
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 105
|
||||
END
|
||||
|
||||
CONFIGUREDLG_VIDEO, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 260
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 56
|
||||
END
|
||||
|
||||
CONFIGUREDLG_INPUT, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 260
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 58
|
||||
END
|
||||
|
||||
CONFIGUREDLG_SOUND, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 260
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 109
|
||||
END
|
||||
|
||||
#ifdef USE_NETWORK
|
||||
CONFIGUREDLG_NETWORK, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 260
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 56
|
||||
END
|
||||
#endif
|
||||
|
||||
CONFIGUREDLG_PERIPHERALS, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 260
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 102
|
||||
END
|
||||
|
||||
CONFIGUREDLG_HARD_DISKS, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 260
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 137
|
||||
END
|
||||
|
||||
CONFIGUREDLG_REMOVABLE_DEVICES, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 260
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 195
|
||||
END
|
||||
END
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// String Table
|
||||
//
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
2048 "86Box"
|
||||
IDS_2049 "86Box Error"
|
||||
IDS_2050 "86Box Fatal Error"
|
||||
IDS_2051 "This will reset 86Box.\nAre you sure you want to save the settings?"
|
||||
IDS_2052 "DirectDraw Screenshot Error"
|
||||
IDS_2053 "Invalid number of sectors (valid values are between 1 and 63)"
|
||||
IDS_2054 "Invalid number of heads (valid values are between 1 and 16)"
|
||||
IDS_2055 "Invalid number of cylinders (valid values are between 1 and 266305)"
|
||||
IDS_2056 "Specify the NVR Path"
|
||||
IDS_2057 "(empty)"
|
||||
IDS_2058 "(host drive %c:)"
|
||||
IDS_2059 "Turbo"
|
||||
IDS_2060 "On"
|
||||
IDS_2061 "Off"
|
||||
IDS_2062 "86Box was unable to find any ROMs.\nAt least one ROM set is required to use 86Box."
|
||||
IDS_2063 "Configured ROM set not available.\nDefaulting to an available ROM set."
|
||||
END
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
IDS_2064 "Configured video BIOS not available.\nDefaulting to an available video BIOS."
|
||||
IDS_2065 "Machine"
|
||||
IDS_2066 "Display"
|
||||
IDS_2067 "Input devices"
|
||||
IDS_2068 "Sound"
|
||||
#ifdef USE_NETWORK
|
||||
IDS_2069 "Network"
|
||||
IDS_2070 "Other peripherals"
|
||||
IDS_2071 "Hard disks"
|
||||
IDS_2072 "Removable devices"
|
||||
#else
|
||||
IDS_2069 "Other peripherals"
|
||||
IDS_2070 "Hard disks"
|
||||
IDS_2071 "Removable devices"
|
||||
#endif
|
||||
IDS_2073 "Unable to create bitmap file: %s"
|
||||
IDS_2074 "Use CTRL+ALT+PAGE DOWN to return to windowed mode"
|
||||
IDS_2075 "CD-ROM images (*.ISO;*.CUE)\0*.ISO;*.CUE\0All files (*.*)\0*.*\0"
|
||||
IDS_2076 "Host CD/DVD Drive (%c:)"
|
||||
IDS_2077 "Click to capture mouse"
|
||||
IDS_2078 "Press F12-F8 to release mouse"
|
||||
IDS_2079 "Press F12-F8 or middle button to release mouse"
|
||||
END
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
IDS_2080 "Drive"
|
||||
IDS_2081 "Location"
|
||||
IDS_2082 "Bus"
|
||||
IDS_2083 "File"
|
||||
IDS_2084 "C"
|
||||
IDS_2085 "H"
|
||||
IDS_2086 "S"
|
||||
IDS_2087 "MB"
|
||||
IDS_2089 "Enabled"
|
||||
IDS_2090 "Mute"
|
||||
IDS_2091 "Type"
|
||||
IDS_2092 "Bus"
|
||||
IDS_2093 "DMA"
|
||||
IDS_2094 "KB"
|
||||
END
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
IDS_2096 "Slave"
|
||||
IDS_2097 "SCSI (ID %s, LUN %s)"
|
||||
IDS_2098 "Adapter Type"
|
||||
IDS_2099 "Base Address"
|
||||
IDS_2100 "IRQ"
|
||||
IDS_2101 "8-bit DMA"
|
||||
IDS_2102 "16-bit DMA"
|
||||
IDS_2103 "BIOS"
|
||||
IDS_2104 "Network Type"
|
||||
IDS_2105 "Surround Module"
|
||||
IDS_2106 "MPU-401 Base Address"
|
||||
IDS_2108 "On-board RAM"
|
||||
IDS_2109 "Memory Size"
|
||||
IDS_2110 "Display Type"
|
||||
IDS_2111 "RGB"
|
||||
END
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
IDS_2112 "Composite"
|
||||
IDS_2113 "Composite Type"
|
||||
IDS_2114 "Old"
|
||||
IDS_2115 "New"
|
||||
IDS_2116 "RGB Type"
|
||||
IDS_2117 "Color"
|
||||
IDS_2118 "Monochrome (Green)"
|
||||
IDS_2119 "Monochrome (Amber)"
|
||||
IDS_2120 "Monochrome (Gray)"
|
||||
IDS_2121 "Color (no brown)"
|
||||
IDS_2122 "Monochrome (Default)"
|
||||
IDS_2123 "Snow Emulation"
|
||||
IDS_2124 "Bilinear Filtering"
|
||||
IDS_2125 "Dithering"
|
||||
IDS_2126 "Framebuffer Memory Size"
|
||||
IDS_2127 "Texture Memory Size"
|
||||
END
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
IDS_2128 "Screen Filter"
|
||||
IDS_2129 "Render Threads"
|
||||
IDS_2130 "Recompiler"
|
||||
IDS_2131 "System Default"
|
||||
IDS_2132 "%i Wait state(s)"
|
||||
IDS_2133 "8-bit"
|
||||
IDS_2134 "Slow 16-bit"
|
||||
IDS_2135 "Fast 16-bit"
|
||||
IDS_2136 "Slow VLB/PCI"
|
||||
IDS_2137 "Mid VLB/PCI"
|
||||
IDS_2138 "Fast VLB/PCI"
|
||||
END
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
#ifdef USE_NETWORK
|
||||
IDS_2139 "PCap failed to set up because it may not be initialized"
|
||||
IDS_2140 "No PCap devices found"
|
||||
IDS_2141 "Invalid PCap device"
|
||||
#endif
|
||||
IDS_2142 "&Notify disk change"
|
||||
IDS_2143 "Type"
|
||||
IDS_2144 "Standard 2-button joystick(s)"
|
||||
IDS_2145 "Standard 4-button joystick"
|
||||
IDS_2146 "Standard 6-button joystick"
|
||||
IDS_2147 "Standard 8-button joystick"
|
||||
IDS_2148 "CH Flightstick Pro"
|
||||
IDS_2149 "Microsoft SideWinder Pad"
|
||||
IDS_2150 "Thrustmaster Flight Control System"
|
||||
IDS_2151 "Disabled"
|
||||
IDS_2152 "None"
|
||||
IDS_2153 "AT Fixed Disk Adapter"
|
||||
IDS_2154 "Internal IDE"
|
||||
IDS_2155 "IRQ %i"
|
||||
IDS_2156 "%" PRIu64
|
||||
IDS_2157 "%" PRIu64 " MB (CHS: %" PRIu64 ", %" PRIu64 ", %" PRIu64 ")"
|
||||
IDS_2158 "Floppy %i (%s): %ws"
|
||||
IDS_2159"All floppy images (*.0??;*.12;*.144;*.360;*.720;*.86F;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMD;*.IMG;*.TD0;*.VFD;*.XDF)\0*.0??;*.12;*.144;*.360;*.720;*.86F;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMD;*.IMG;*.TD0;*.VFD;*.XDF\0Advanced sector-based images (*.IMD;*.TD0)\0*.IMD;*.TD0\0Basic sector-based images (*.0??;*.12;*.144;*.360;*.720;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMG;*.VFD;*.XDF)\0*.0??;*.12;*.144;*.360;*.720;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMG;*.VFD;*.XDF\0Flux images (*.FDI)\0*.FDI\0Surface-based images (*.86F)\0*.86F\0All files (*.*)\0*.*\0"
|
||||
IDS_2160 "Configuration files (*.CFG)\0*.CFG\0All files (*.*)\0*.*\0"
|
||||
IDS_2161 "&New image..."
|
||||
IDS_2162 "Existing image..."
|
||||
IDS_2163 "Existing image (&Write-protected)..."
|
||||
IDS_2164 "E&ject"
|
||||
IDS_2165 "&Mute"
|
||||
IDS_2166 "E&mpty"
|
||||
IDS_2167 "&Reload previous image"
|
||||
IDS_2168 "&Image..."
|
||||
IDS_2169 "Image (&Write-protected)..."
|
||||
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 "[Bus] Logitech Bus Mouse"
|
||||
IDS_3074 "[Bus] Microsoft Bus Mouse (InPort)"
|
||||
IDS_3075 "[Serial] Mouse Systems Mouse"
|
||||
IDS_3076 "[Serial] Microsoft 2-button Mouse"
|
||||
IDS_3077 "[Serial] Logitech 3-button Mouse"
|
||||
IDS_3078 "[Serial] Microsoft Wheel Mouse"
|
||||
IDS_3079 "[PS/2] 2-button Mouse"
|
||||
IDS_3080 "[PS/2] Microsoft Intellimouse"
|
||||
IDS_3081 "[Proprietary] Amstrad Mouse"
|
||||
IDS_3082 "[Proprietary] Olivetti M24 Mouse"
|
||||
|
||||
IDS_4096 "Hard disk (%s)"
|
||||
IDS_4097 "%01i:%01i"
|
||||
IDS_4098 "%i"
|
||||
IDS_4099 "Disabled"
|
||||
IDS_4100 "Custom..."
|
||||
IDS_4101 "Custom (large)..."
|
||||
IDS_4102 "Add New Hard Disk"
|
||||
IDS_4103 "Add Existing Hard Disk"
|
||||
IDS_4104 "Attempting to create a HDI image larger than 4 GB"
|
||||
IDS_4105 "Attempting to create a spuriously large hard disk image"
|
||||
IDS_4106 "Hard disk images (*.HDI;*.HDX;*.IMA;*.IMG)\0*.HDI;*.HDX;*.IMA;*.IMG\0All files (*.*)\0*.*\0"
|
||||
IDS_4107 "Unable to open the file for read"
|
||||
IDS_4108 "Unable to open the file for write"
|
||||
IDS_4109 "HDI or HDX image with a sector size that is not 512 are not supported"
|
||||
IDS_4110 "USB is not yet supported"
|
||||
IDS_4111 "This image exists and will be overwritten.\nAre you sure you want to use it?"
|
||||
IDS_4112 "Please enter a valid file name"
|
||||
IDS_4113 "Remember to partition and format the new drive"
|
||||
IDS_4114 "MFM/RLL or ESDI CD-ROM drives never existed"
|
||||
IDS_4115 "Removable disk %i (SCSI): %ws"
|
||||
|
||||
IDS_4352 "MFM/RLL"
|
||||
IDS_4353 "XT IDE"
|
||||
IDS_4354 "ESDI"
|
||||
IDS_4355 "IDE (PIO-only)"
|
||||
IDS_4356 "IDE (PIO+DMA)"
|
||||
IDS_4357 "SCSI"
|
||||
IDS_4358 "SCSI (removable)"
|
||||
|
||||
IDS_4608 "MFM/RLL (%01i:%01i)"
|
||||
IDS_4609 "XT IDE (%01i:%01i)"
|
||||
IDS_4610 "ESDI (%01i:%01i)"
|
||||
IDS_4611 "IDE (PIO-only) (%01i:%01i)"
|
||||
IDS_4612 "IDE (PIO+DMA) (%01i:%01i)"
|
||||
IDS_4613 "SCSI (%02i:%02i)"
|
||||
IDS_4614 "SCSI (removable) (%02i:%02i)"
|
||||
|
||||
IDS_5120 "CD-ROM %i (%s): %s"
|
||||
|
||||
IDS_5376 "Disabled"
|
||||
IDS_5377 "<Reserved>"
|
||||
IDS_5378 "<Reserved>"
|
||||
IDS_5379 "<Reserved>"
|
||||
IDS_5380 "ATAPI (PIO-only)"
|
||||
IDS_5381 "ATAPI (PIO and DMA)"
|
||||
IDS_5382 "SCSI"
|
||||
|
||||
IDS_5632 "Disabled"
|
||||
IDS_5633 "<Reserved>"
|
||||
IDS_5634 "<Reserved>"
|
||||
IDS_5635 "<Reserved>"
|
||||
IDS_5636 "ATAPI (PIO-only) (%01i:%01i)"
|
||||
IDS_5637 "ATAPI (PIO and DMA) (%01i:%01i)"
|
||||
IDS_5638 "SCSI (%02i:%02i)"
|
||||
|
||||
IDS_6144 "English (United States)"
|
||||
END
|
||||
#define IDS_LANG_ENUS IDS_6144
|
||||
|
||||
|
||||
#ifndef _MAC
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 2,0,0,0
|
||||
PRODUCTVERSION 2,0,0,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS 0x40004L
|
||||
FILETYPE 0x1L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "Comments", "\0"
|
||||
VALUE "CompanyName", "IRC #SoftHistory\0"
|
||||
VALUE "FileDescription", "86Box - an emulator for X86-based systems\0"
|
||||
VALUE "FileVersion", "2.00\0"
|
||||
VALUE "InternalName", "86Box\0"
|
||||
VALUE "LegalCopyright", "Copyright (C)SoftHistory, Sarah Walker, 2007-2017, Released under the GNU GPL v2\0"
|
||||
VALUE "LegalTrademarks", "\0"
|
||||
VALUE "OriginalFilename", "86Box.exe\0"
|
||||
VALUE "PrivateBuild", "\0"
|
||||
VALUE "ProductName", "86Box Emulator\0"
|
||||
VALUE "ProductVersion", "2.00\0"
|
||||
VALUE "SpecialBuild", "\0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
||||
|
||||
#endif // !_MAC
|
||||
|
||||
#endif // English (U.S.) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
BIN
src/win/icons/86Box-RB.ico
Normal file
|
After Width: | Height: | Size: 385 KiB |
BIN
src/win/icons/86Box.ico
Normal file
|
After Width: | Height: | Size: 385 KiB |
BIN
src/win/icons/cdrom.ico
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
src/win/icons/cdrom_active.ico
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
src/win/icons/cdrom_disabled.ico
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
src/win/icons/cdrom_empty.ico
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
src/win/icons/cdrom_empty_active.ico
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
src/win/icons/display.ico
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
src/win/icons/floppy_35.ico
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
src/win/icons/floppy_35_active.ico
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
src/win/icons/floppy_35_empty.ico
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
src/win/icons/floppy_35_empty_active.ico
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
src/win/icons/floppy_525.ico
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
src/win/icons/floppy_525_active.ico
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
src/win/icons/floppy_525_empty.ico
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
src/win/icons/floppy_525_empty_active.ico
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
src/win/icons/floppy_disabled.ico
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
src/win/icons/hard_disk.ico
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
src/win/icons/hard_disk_active.ico
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
src/win/icons/input_devices.ico
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
src/win/icons/machine.ico
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
src/win/icons/network.ico
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
src/win/icons/network_active.ico
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
src/win/icons/other_peripherals.ico
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
src/win/icons/removable_devices.ico
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
src/win/icons/removable_disk.ico
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
src/win/icons/removable_disk_active.ico
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
src/win/icons/removable_disk_empty.ico
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
src/win/icons/removable_disk_empty_active.ico
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
src/win/icons/sound.ico
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
54
src/win/pcap_if.rc
Normal file
@@ -0,0 +1,54 @@
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
#pragma code_page(1252)
|
||||
#endif //_WIN32
|
||||
|
||||
|
||||
/*
|
||||
* Icons by Devcore
|
||||
* - https://commons.wikimedia.org/wiki/File:Icon_PC_256x256.png
|
||||
*/
|
||||
#ifdef RELEASE_BUILD
|
||||
100 ICON DISCARDABLE "win/icons/86Box-RB.ico"
|
||||
#else
|
||||
100 ICON DISCARDABLE "win/icons/86Box.ico"
|
||||
#endif
|
||||
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,0,2,0
|
||||
PRODUCTVERSION 1,0,2,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS 0x40004L
|
||||
FILETYPE 0x1L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "Comments", "\0"
|
||||
VALUE "CompanyName", "IRC #SoftHistory\0"
|
||||
VALUE "FileDescription", "PCap_IF - test tool for WinPcap\0"
|
||||
VALUE "FileVersion", "1.0.2\0"
|
||||
VALUE "InternalName", "pcap_if\0"
|
||||
VALUE "LegalCopyright", "Copyright 2017 Fred N. van Kempen\0"
|
||||
VALUE "LegalTrademarks", "\0"
|
||||
VALUE "OriginalFilename", "pcap_if.exe\0"
|
||||
VALUE "PrivateBuild", "\0"
|
||||
VALUE "ProductName", "WinPcap Test Tool\0"
|
||||
VALUE "ProductVersion", "1.0.2\0"
|
||||
VALUE "SpecialBuild", "\0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
||||
4
src/win/plat_dinput.h
Normal file
@@ -0,0 +1,4 @@
|
||||
/* Copyright holders: Sarah Walker
|
||||
see COPYING for more details
|
||||
*/
|
||||
extern LPDIRECTINPUT lpdi;
|
||||
76
src/win/plat_dir.h
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Definitions for the platform OpenDir module.
|
||||
*
|
||||
* Version: @(#)plat_dir.h 1.0.1 2017/05/17
|
||||
*
|
||||
* Author: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Copyright 2017 Fred N. van Kempen.
|
||||
*/
|
||||
#ifndef PLAT_DIR_H
|
||||
# define PLAT_DIR_H
|
||||
|
||||
|
||||
#ifdef _MAX_FNAME
|
||||
# define MAXNAMLEN _MAX_FNAME
|
||||
#else
|
||||
# define MAXNAMLEN 15
|
||||
#endif
|
||||
# define MAXDIRLEN 127
|
||||
|
||||
|
||||
struct direct {
|
||||
long d_ino;
|
||||
unsigned short d_reclen;
|
||||
unsigned short d_off;
|
||||
#ifdef UNICODE
|
||||
wchar_t d_name[MAXNAMLEN + 1];
|
||||
#else
|
||||
char d_name[MAXNAMLEN + 1];
|
||||
#endif
|
||||
};
|
||||
#define d_namlen d_reclen
|
||||
|
||||
|
||||
typedef struct {
|
||||
short flags; /* internal flags */
|
||||
short offset; /* offset of entry into dir */
|
||||
long handle; /* open handle to Win32 system */
|
||||
short sts; /* last known status code */
|
||||
char *dta; /* internal work data */
|
||||
#ifdef UNICODE
|
||||
wchar_t dir[MAXDIRLEN+1]; /* open dir */
|
||||
#else
|
||||
char dir[MAXDIRLEN+1]; /* open dir */
|
||||
#endif
|
||||
struct direct dent; /* actual directory entry */
|
||||
} DIR;
|
||||
|
||||
|
||||
/* Directory routine flags. */
|
||||
#define DIR_F_LOWER 0x0001 /* force to lowercase */
|
||||
#define DIR_F_SANE 0x0002 /* force this to sane path */
|
||||
#define DIR_F_ISROOT 0x0010 /* this is the root directory */
|
||||
|
||||
|
||||
/* Function prototypes. */
|
||||
#ifdef UNICODE
|
||||
extern DIR *opendirw(const wchar_t *);
|
||||
#else
|
||||
extern DIR *opendir(const char *);
|
||||
#endif
|
||||
extern struct direct *readdir(DIR *);
|
||||
extern long telldir(DIR *);
|
||||
extern void seekdir(DIR *, long);
|
||||
extern int closedir(DIR *);
|
||||
|
||||
#define rewinddir(dirp) seekdir(dirp, 0L)
|
||||
|
||||
|
||||
#endif /*PLAT_DIR_H*/
|
||||
30
src/win/plat_dynld.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Define the Dynamic Module Loader interface.
|
||||
*
|
||||
* Version: @(#)plat_dynld.h 1.0.1 2017/05/21
|
||||
*
|
||||
* Author: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Copyright 2017 Fred N. van Kempen
|
||||
*/
|
||||
#ifndef PLAT_DYNLD_H
|
||||
# define PLAT_DYNLD_H
|
||||
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
void *func;
|
||||
} dllimp_t;
|
||||
|
||||
|
||||
extern void *dynld_module(const char *, dllimp_t *);
|
||||
extern void dynld_close(void *);
|
||||
|
||||
|
||||
#endif /*PLAT_DYNLD_H*/
|
||||
5
src/win/plat_iodev.h
Normal file
@@ -0,0 +1,5 @@
|
||||
extern void cdrom_eject(uint8_t id);
|
||||
extern void cdrom_reload(uint8_t id);
|
||||
extern void removable_disk_unload(uint8_t id);
|
||||
extern void removable_disk_eject(uint8_t id);
|
||||
extern void removable_disk_reload(uint8_t id);
|
||||
69
src/win/plat_joystick.h
Normal file
@@ -0,0 +1,69 @@
|
||||
/* Copyright holders: Sarah Walker
|
||||
see COPYING for more details
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void joystick_init();
|
||||
void joystick_close();
|
||||
void joystick_poll();
|
||||
|
||||
typedef struct plat_joystick_t
|
||||
{
|
||||
char name[64];
|
||||
|
||||
int a[8];
|
||||
int b[32];
|
||||
int p[4];
|
||||
|
||||
struct
|
||||
{
|
||||
char name[32];
|
||||
int id;
|
||||
} axis[8];
|
||||
|
||||
struct
|
||||
{
|
||||
char name[32];
|
||||
int id;
|
||||
} button[32];
|
||||
|
||||
struct
|
||||
{
|
||||
char name[32];
|
||||
int id;
|
||||
} pov[4];
|
||||
|
||||
int nr_axes;
|
||||
int nr_buttons;
|
||||
int nr_povs;
|
||||
} plat_joystick_t;
|
||||
|
||||
#define MAX_PLAT_JOYSTICKS 8
|
||||
|
||||
extern plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS];
|
||||
extern int joysticks_present;
|
||||
|
||||
#define POV_X 0x80000000
|
||||
#define POV_Y 0x40000000
|
||||
|
||||
typedef struct joystick_t
|
||||
{
|
||||
int axis[8];
|
||||
int button[32];
|
||||
int pov[4];
|
||||
|
||||
int plat_joystick_nr;
|
||||
int axis_mapping[8];
|
||||
int button_mapping[32];
|
||||
int pov_mapping[4][2];
|
||||
} joystick_t;
|
||||
|
||||
#define MAX_JOYSTICKS 4
|
||||
extern joystick_t joystick_state[MAX_JOYSTICKS];
|
||||
|
||||
#define JOYSTICK_PRESENT(n) (joystick_state[n].plat_joystick_nr != 0)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
22
src/win/plat_keyboard.h
Normal file
@@ -0,0 +1,22 @@
|
||||
/* Copyright holders: Sarah Walker
|
||||
see COPYING for more details
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void keyboard_init();
|
||||
void keyboard_close();
|
||||
void keyboard_poll_host();
|
||||
extern int recv_key[272];
|
||||
extern int rawinputkey[272];
|
||||
|
||||
#ifndef __unix
|
||||
#define KEY_LCONTROL 0x1d
|
||||
#define KEY_RCONTROL (0x1d | 0x80)
|
||||
#define KEY_END (0x4f | 0x80)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
7
src/win/plat_midi.h
Normal file
@@ -0,0 +1,7 @@
|
||||
void plat_midi_init();
|
||||
void plat_midi_close();
|
||||
void plat_midi_play_msg(uint8_t* val);
|
||||
void plat_midi_play_sysex(uint8_t* data, unsigned int len);
|
||||
int plat_midi_write(uint8_t val);
|
||||
int plat_midi_get_num_devs();
|
||||
void plat_midi_get_dev_name(int num, char *s);
|
||||
16
src/win/plat_mouse.h
Normal file
@@ -0,0 +1,16 @@
|
||||
/* Copyright holders: Sarah Walker
|
||||
see COPYING for more details
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void mouse_init();
|
||||
void mouse_close();
|
||||
extern int mouse_buttons;
|
||||
void mouse_poll_host();
|
||||
void mouse_get_mickeys(int *x, int *y, int *z);
|
||||
extern int mousecapture;
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
52
src/win/plat_serial.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Definitions for the Bottom Half of the SERIAL card.
|
||||
*
|
||||
* Version: @(#)plat_serial.h 1.0.5 2017/06/04
|
||||
*
|
||||
* Author: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Copyright 2017 Fred N. van Kempen.
|
||||
*/
|
||||
#ifndef PLAT_SERIAL_H
|
||||
# define PLAT_SERIAL_H
|
||||
|
||||
|
||||
typedef struct {
|
||||
char name[80]; /* name of open port */
|
||||
void (*rd_done)(void *, int);
|
||||
void *rd_arg;
|
||||
#ifdef BHTTY_C
|
||||
HANDLE handle;
|
||||
OVERLAPPED rov, /* READ and WRITE events */
|
||||
wov;
|
||||
int tmo; /* current timeout value */
|
||||
DCB dcb, /* terminal settings */
|
||||
odcb;
|
||||
thread_t *tid; /* pointer to receiver thread */
|
||||
char buff[1024];
|
||||
int icnt, ihead, itail;
|
||||
#endif
|
||||
} BHTTY;
|
||||
|
||||
|
||||
extern BHTTY *bhtty_open(char *__port, int __tmo);
|
||||
extern void bhtty_close(BHTTY *);
|
||||
extern int bhtty_flush(BHTTY *);
|
||||
extern void bhtty_raw(BHTTY *, void *__arg);
|
||||
extern int bhtty_speed(BHTTY *, long __speed);
|
||||
extern int bhtty_params(BHTTY *, char __dbit, char __par, char __sbit);
|
||||
extern int bhtty_sstate(BHTTY *, void *__arg);
|
||||
extern int bhtty_gstate(BHTTY *, void *__arg);
|
||||
extern int bhtty_crtscts(BHTTY *, char __yesno);
|
||||
extern int bhtty_active(BHTTY *, int);
|
||||
extern int bhtty_write(BHTTY *, unsigned char);
|
||||
extern int bhtty_read(BHTTY *, unsigned char *, int);
|
||||
|
||||
|
||||
#endif /*PLAT_SERIAL_H*/
|
||||
24
src/win/plat_thread.h
Normal file
@@ -0,0 +1,24 @@
|
||||
/* Copyright holders: Sarah Walker
|
||||
see COPYING for more details
|
||||
*/
|
||||
#ifndef PLAT_THREAD_H
|
||||
# define PLAT_THREAD_H
|
||||
|
||||
|
||||
typedef void thread_t;
|
||||
typedef void event_t;
|
||||
|
||||
|
||||
extern thread_t *thread_create(void (*thread_rout)(void *param), void *param);
|
||||
extern void thread_kill(thread_t *handle);
|
||||
|
||||
extern event_t *thread_create_event(void);
|
||||
extern void thread_set_event(event_t *event);
|
||||
extern void thread_reset_event(event_t *_event);
|
||||
extern int thread_wait_event(event_t *event, int timeout);
|
||||
extern void thread_destroy_event(event_t *_event);
|
||||
|
||||
extern void thread_sleep(int t);
|
||||
|
||||
|
||||
#endif /*PLAT_THREAD_H*/
|
||||
2
src/win/plat_ticks.h
Normal file
@@ -0,0 +1,2 @@
|
||||
uint32_t get_ticks(void);
|
||||
void delay_ms(uint32_t count);
|
||||
34
src/win/plat_ui.h
Normal file
@@ -0,0 +1,34 @@
|
||||
#ifndef __unix
|
||||
extern void plat_msgbox_error(int i);
|
||||
extern wchar_t *plat_get_string_from_id(int i);
|
||||
|
||||
#ifndef IDS_2077
|
||||
#define IDS_2077 2077
|
||||
#endif
|
||||
|
||||
#ifndef IDS_2078
|
||||
#define IDS_2078 2078
|
||||
#endif
|
||||
|
||||
#ifndef IDS_2079
|
||||
#define IDS_2079 2079
|
||||
#endif
|
||||
|
||||
#ifndef IDS_2139
|
||||
#define IDS_2139 2139
|
||||
#endif
|
||||
|
||||
#ifndef IDS_2171
|
||||
#define IDS_2171 2171
|
||||
#endif
|
||||
|
||||
#ifndef IDS_2219
|
||||
#define IDS_2219 2219
|
||||
#endif
|
||||
#endif
|
||||
|
||||
extern void plat_msgbox_fatal(char *string);
|
||||
extern void get_executable_name(wchar_t *s, int size);
|
||||
extern void set_window_title(wchar_t *s);
|
||||
extern void startblit(void);
|
||||
extern void endblit(void);
|
||||
493
src/win/resource.h
Normal file
@@ -0,0 +1,493 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Windows resource defines.
|
||||
*
|
||||
* NOTE: FIXME: Strings 2176 and 2193 are same.
|
||||
* NOTE: FIXME: string 2095 not in use.
|
||||
*
|
||||
* Version: @(#)resource.h 1.0.5 2017/08/24
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Fred N. van Kempem, <decwiz@yahoo.com>
|
||||
* Copyright 2008-2017 Sarah Walker.
|
||||
* Copyright 2016,2017 Miran Grca.
|
||||
*/
|
||||
#ifndef WIN_RESOURCE_H
|
||||
# define WIN_RESOURCE_H
|
||||
|
||||
|
||||
/* Dialog IDs. */
|
||||
#define DLG_ABOUT 101 /* top-level dialog */
|
||||
#define DLG_STATUS 102 /* top-level dialog */
|
||||
#define DLG_CONFIG 110 /* top-level dialog */
|
||||
#define DLG_CFG_MACHINE 111 /* sub-dialog of config */
|
||||
#define DLG_CFG_VIDEO 112 /* sub-dialog of config */
|
||||
#define DLG_CFG_INPUT 113 /* sub-dialog of config */
|
||||
#define DLG_CFG_SOUND 114 /* sub-dialog of config */
|
||||
#define DLG_CFG_NETWORK 115 /* sub-dialog of config */
|
||||
#define DLG_CFG_PERIPHERALS 116 /* sub-dialog of config */
|
||||
#define DLG_CFG_HARD_DISKS 117 /* sub-dialog of config */
|
||||
#define DLG_CFG_HARD_DISKS_ADD 118 /* sub-dialog of config */
|
||||
#define DLG_CFG_REMOVABLE_DEVICES 119 /* sub-dialog of config */
|
||||
|
||||
/* Static text label IDs. */
|
||||
#define IDT_1700 1700 /* Language: */
|
||||
#define IDT_1701 1701 /* Machine: */
|
||||
#define IDT_1702 1702 /* CPU type: */
|
||||
#define IDT_1703 1703 /* Wait states: */
|
||||
#define IDT_1704 1704 /* CPU: */
|
||||
#define IDT_1705 1705 /* MB == IDC_TEXT_MB */
|
||||
#define IDT_1706 1706 /* Memory: */
|
||||
#define IDT_1707 1707 /* Video: */
|
||||
#define IDT_1708 1708 /* Video speed: */
|
||||
#define IDT_1709 1709 /* Mouse: */
|
||||
#define IDT_1710 1710 /* Joystick: */
|
||||
#define IDT_1711 1711 /* Sound card: */
|
||||
#define IDT_1712 1712 /* MIDI Out Device: */
|
||||
#define IDT_1713 1713 /* Network type: */
|
||||
#define IDT_1714 1714 /* PCap device: */
|
||||
#define IDT_1715 1715 /* Network adapter: */
|
||||
#define IDT_1716 1716 /* SCSI Controller: */
|
||||
#define IDT_1717 1717 /* HD Controller: */
|
||||
#define IDT_1718 1718 /* Tertiary IDE: */
|
||||
#define IDT_1719 1719 /* Quaternary IDE: */
|
||||
#define IDT_1720 1720 /* Hard disks: */
|
||||
#define IDT_1721 1721 /* Bus: */
|
||||
#define IDT_1722 1722 /* Channel: */
|
||||
#define IDT_1723 1723 /* ID: */
|
||||
#define IDT_1724 1724 /* LUN: */
|
||||
#define IDT_1726 1726 /* Sectors: */
|
||||
#define IDT_1727 1727 /* Heads: */
|
||||
#define IDT_1728 1728 /* Cylinders: */
|
||||
#define IDT_1729 1729 /* Size (MB): */
|
||||
#define IDT_1730 1730 /* Type: */
|
||||
#define IDT_1731 1731 /* File name: */
|
||||
#define IDT_1737 1737 /* Floppy drives: */
|
||||
#define IDT_1738 1738 /* Type: */
|
||||
#define IDT_1739 1739 /* CD-ROM drives: */
|
||||
#define IDT_1740 1740 /* Bus: */
|
||||
#define IDT_1741 1741 /* ID: */
|
||||
#define IDT_1742 1742 /* LUN: */
|
||||
#define IDT_1743 1743 /* Channel: */
|
||||
#define IDT_STEXT 1744 /* text in status window */
|
||||
#define IDT_SDEVICE 1745 /* text in status window */
|
||||
|
||||
|
||||
/*
|
||||
* To try to keep these organized, we now group the
|
||||
* constants per dialog, as this allows easy adding
|
||||
* and deleting items.
|
||||
*/
|
||||
#define IDC_SETTINGSCATLIST 1001 /* generic config */
|
||||
#define IDC_CFILE 1002 /* Select File dialog */
|
||||
#define IDC_CHECK_SYNC 1008
|
||||
/* Leave this as is until we finally get into localization in 86Box 3.00(?). */
|
||||
#if 0
|
||||
#define IDC_COMBO_LANG 1009
|
||||
#endif
|
||||
|
||||
#define IDC_COMBO_MACHINE 1010 /* machine/cpu config */
|
||||
#define IDC_CONFIGURE_MACHINE 1011
|
||||
#define IDC_COMBO_CPU_TYPE 1012
|
||||
#define IDC_COMBO_CPU 1013
|
||||
#define IDC_CHECK_FPU 1014
|
||||
#define IDC_COMBO_WS 1015
|
||||
#define IDC_CHECK_DYNAREC 1016
|
||||
#define IDC_MEMTEXT 1017
|
||||
#define IDC_MEMSPIN 1018
|
||||
#define IDC_TEXT_MB IDT_1705
|
||||
#define IDC_EDIT_NVR_PATH 1019
|
||||
#define IDC_BUTTON_NVR_PATH 1020
|
||||
|
||||
#define IDC_VIDEO 1030 /* video config */
|
||||
#define IDC_COMBO_VIDEO 1031
|
||||
#define IDC_COMBO_VIDEO_SPEED 1032
|
||||
#define IDC_CHECK_VOODOO 1033
|
||||
#define IDC_BUTTON_VOODOO 1034
|
||||
|
||||
#define IDC_INPUT 1050 /* input config */
|
||||
#define IDC_COMBO_MOUSE 1051
|
||||
#define IDC_COMBO_JOYSTICK 1052
|
||||
#define IDC_COMBO_JOY 1053
|
||||
|
||||
#define IDC_SOUND 1070 /* sound config */
|
||||
#define IDC_COMBO_SOUND 1071
|
||||
#define IDC_CHECK_SSI 1072
|
||||
#define IDC_CHECK_CMS 1073
|
||||
#define IDC_CHECK_GUS 1074
|
||||
#define IDC_CHECK_NUKEDOPL 1075
|
||||
#define IDC_COMBO_MIDI 1076
|
||||
#define IDC_CHECK_MPU401 1077
|
||||
#define IDC_CONFIGURE_MPU401 1078
|
||||
#define IDC_CHECK_FLOAT 1079
|
||||
|
||||
#define IDC_COMBO_NET_TYPE 1090 /* network config */
|
||||
#define IDC_COMBO_PCAP 1091
|
||||
#define IDC_COMBO_NET 1092
|
||||
|
||||
#define IDC_OTHER_PERIPH 1110 /* other periph config */
|
||||
#define IDC_COMBO_SCSI 1111
|
||||
#define IDC_CONFIGURE_SCSI 1112
|
||||
#define IDC_COMBO_HDC 1113
|
||||
#define IDC_COMBO_IDE_TER 1114
|
||||
#define IDC_COMBO_IDE_QUA 1115
|
||||
#define IDC_CHECK_SERIAL1 1116
|
||||
#define IDC_CHECK_SERIAL2 1117
|
||||
#define IDC_CHECK_PARALLEL 1118
|
||||
#define IDC_CHECK_BUGGER 1119
|
||||
|
||||
#define IDC_HARD_DISKS 1130 /* hard disk config */
|
||||
#define IDC_LIST_HARD_DISKS 1131
|
||||
#define IDC_BUTTON_HDD_ADD_NEW 1132
|
||||
#define IDC_BUTTON_HDD_ADD 1133
|
||||
#define IDC_BUTTON_HDD_REMOVE 1134
|
||||
#define IDC_COMBO_HD_BUS 1135
|
||||
#define IDC_COMBO_HD_CHANNEL 1136
|
||||
#define IDC_COMBO_HD_ID 1137
|
||||
#define IDC_COMBO_HD_LUN 1138
|
||||
#define IDC_COMBO_HD_CHANNEL_IDE 1139
|
||||
#define IDC_EDIT_HD_FILE_NAME 1140
|
||||
#define IDC_EDIT_HD_SPT 1141
|
||||
#define IDC_EDIT_HD_HPC 1142
|
||||
#define IDC_EDIT_HD_CYL 1143
|
||||
#define IDC_EDIT_HD_SIZE 1144
|
||||
#define IDC_COMBO_HD_TYPE 1145
|
||||
|
||||
#define IDC_REMOV_DEVICES 1150 /* removable dev config */
|
||||
#define IDC_LIST_FLOPPY_DRIVES 1151
|
||||
#define IDC_COMBO_FD_TYPE 1152
|
||||
#define IDC_CHECKTURBO 1153
|
||||
#define IDC_CHECKBPB 1154
|
||||
#define IDC_BUTTON_FDD_ADD 1155 // status bar menu
|
||||
#define IDC_BUTTON_FDD_EDIT 1156 // status bar menu
|
||||
#define IDC_BUTTON_FDD_REMOVE 1157 // status bar menu
|
||||
#define IDC_LIST_CDROM_DRIVES 1158
|
||||
#define IDC_COMBO_CD_BUS 1159
|
||||
#define IDC_COMBO_CD_ID 1160
|
||||
#define IDC_COMBO_CD_LUN 1161
|
||||
#define IDC_COMBO_CD_CHANNEL_IDE 1162
|
||||
#define IDC_BUTTON_CDROM_ADD 1163 // status bar menu
|
||||
#define IDC_BUTTON_CDROM_EDIT 1164 // status bar menu
|
||||
#define IDC_BUTTON_CDROM_REMOVE 1165 // status bar menu
|
||||
|
||||
|
||||
/* For the DeviceConfig code, re-do later. */
|
||||
#define IDC_CONFIG_BASE 1200
|
||||
#define IDC_CONFIGURE_VID 1200
|
||||
#define IDC_CONFIGURE_SND 1201
|
||||
#define IDC_CONFIGURE_VOODOO 1202
|
||||
#define IDC_CONFIGURE_MOD 1203
|
||||
#define IDC_CONFIGURE_NET_TYPE 1204
|
||||
#define IDC_CONFIGURE_BUSLOGIC 1205
|
||||
#define IDC_CONFIGURE_PCAP 1206
|
||||
#define IDC_CONFIGURE_NET 1207
|
||||
#define IDC_CONFIGURE_MIDI 1208
|
||||
#define IDC_JOY1 1210
|
||||
#define IDC_JOY2 1211
|
||||
#define IDC_JOY3 1212
|
||||
#define IDC_JOY4 1213
|
||||
#define IDC_HDTYPE 1280
|
||||
#define IDC_RENDER 1281
|
||||
#define IDC_STATUS 1282
|
||||
|
||||
|
||||
/* String IDs. */
|
||||
#define IDS_STRINGS 2048 // "86Box"
|
||||
#define IDS_2049 2049 // "86Box Error"
|
||||
#define IDS_2050 2050 // "86Box Fatal Error"
|
||||
#define IDS_2051 2051 // "This will reset 86Box.."
|
||||
#define IDS_2052 2052 // "DirectDraw Screenshot Error"
|
||||
#define IDS_2053 2053 // "Invalid number of sectors.."
|
||||
#define IDS_2054 2054 // "Invalid number of heads.."
|
||||
#define IDS_2055 2055 // "Invalid number of cylinders.."
|
||||
#define IDS_2056 2056 // "Please enter a valid file name"
|
||||
#define IDS_2057 2057 // "Unable to open the file for write"
|
||||
#define IDS_2058 2058 // "Attempting to create a HDI.."
|
||||
#define IDS_2059 2059 // "Remember to partition and.."
|
||||
#define IDS_2060 2060 // "Unable to open the file.."
|
||||
#define IDS_2061 2061 // "HDI or HDX image with a.."
|
||||
#define IDS_2062 2062 // "86Box was unable to find any.."
|
||||
#define IDS_2063 2063 // "Configured ROM set not avai.."
|
||||
#define IDS_2064 2064 // "Configured video BIOS not.."
|
||||
#define IDS_2065 2065 // "Machine"
|
||||
#define IDS_2066 2066 // "Video"
|
||||
#define IDS_2067 2067 // "Input devices"
|
||||
#define IDS_2068 2068 // "Sound"
|
||||
#define IDS_2069 2069 // "Network"
|
||||
#define IDS_2070 2070 // "Other peripherals"
|
||||
#define IDS_2071 2071 // "Hard disks"
|
||||
#define IDS_2072 2072 // "Removable devices"
|
||||
#define IDS_2073 2073 // "%i"" floppy drive: %s"
|
||||
#define IDS_2074 2074 // "Disabled CD-ROM drive"
|
||||
#define IDS_2075 2075 // "%s CD-ROM drive: %s"
|
||||
#define IDS_2076 2076 // "Host CD/DVD Drive (%c:)"
|
||||
#define IDS_2077 2077 // "Click to capture mouse"
|
||||
#define IDS_2078 2078 // "Press F12-F8 to release mouse"
|
||||
#define IDS_2079 2079 // "Press F12-F8 or middle button.."
|
||||
#define IDS_2080 2080 // "Drive"
|
||||
#define IDS_2081 2081 // "Location"
|
||||
#define IDS_2082 2082 // "Bus"
|
||||
#define IDS_2083 2083 // "File"
|
||||
#define IDS_2084 2084 // "C"
|
||||
#define IDS_2085 2085 // "H"
|
||||
#define IDS_2086 2086 // "S"
|
||||
#define IDS_2087 2087 // "MB"
|
||||
#define IDS_2088 2088 // "%i"
|
||||
#define IDS_2089 2089 // "Enabled"
|
||||
#define IDS_2090 2090 // "Mute"
|
||||
#define IDS_2091 2091 // "Type"
|
||||
#define IDS_2092 2092 // "Bus"
|
||||
#define IDS_2093 2093 // "DMA"
|
||||
#define IDS_2094 2094 // "KB"
|
||||
#define IDS_2095 2095
|
||||
#define IDS_2096 2096 // "Slave"
|
||||
#define IDS_2097 2097 // "SCSI (ID %s, LUN %s)"
|
||||
#define IDS_2098 2098 // "Adapter Type"
|
||||
#define IDS_2099 2099 // "Base Address"
|
||||
#define IDS_2100 2100 // "IRQ"
|
||||
#define IDS_2101 2101 // "8-bit DMA"
|
||||
#define IDS_2102 2102 // "16-bit DMA"
|
||||
#define IDS_2103 2103 // "BIOS"
|
||||
#define IDS_2104 2104 // "Network Type"
|
||||
#define IDS_2105 2105 // "Surround Module"
|
||||
#define IDS_2106 2106 // "MPU-401 Base Address"
|
||||
#define IDS_2107 2107 // "No PCap devices found"
|
||||
#define IDS_2108 2108 // "On-board RAM"
|
||||
#define IDS_2109 2109 // "Memory Size"
|
||||
#define IDS_2110 2110 // "Display Type"
|
||||
#define IDS_2111 2111 // "RGB"
|
||||
#define IDS_2112 2112 // "Composite"
|
||||
#define IDS_2113 2113 // "Composite Type"
|
||||
#define IDS_2114 2114 // "Old"
|
||||
#define IDS_2115 2115 // "New"
|
||||
#define IDS_2116 2116 // "RGB Type"
|
||||
#define IDS_2117 2117 // "Color"
|
||||
#define IDS_2118 2118 // "Monochrome (Green)"
|
||||
#define IDS_2119 2119 // "Monochrome (Amber)"
|
||||
#define IDS_2120 2120 // "Monochrome (Gray)"
|
||||
#define IDS_2121 2121 // "Color (no brown)"
|
||||
#define IDS_2122 2122 // "Monochrome (Default)"
|
||||
#define IDS_2123 2123 // "Snow Emulation"
|
||||
#define IDS_2124 2124 // "Bilinear Filtering"
|
||||
#define IDS_2125 2125 // "Dithering"
|
||||
#define IDS_2126 2126 // "Framebuffer Memory Size"
|
||||
#define IDS_2127 2127 // "Texture Memory Size"
|
||||
#define IDS_2128 2128 // "Screen Filter"
|
||||
#define IDS_2129 2129 // "Render Threads"
|
||||
#define IDS_2130 2130 // "Recompiler"
|
||||
#define IDS_2131 2131 // "System Default"
|
||||
#define IDS_2132 2132 // "%i Wait state(s)"
|
||||
#define IDS_2133 2133 // "8-bit"
|
||||
#define IDS_2134 2134 // "Slow 16-bit"
|
||||
#define IDS_2135 2135 // "Fast 16-bit"
|
||||
#define IDS_2136 2136 // "Slow VLB/PCI"
|
||||
#define IDS_2137 2137 // "Mid VLB/PCI"
|
||||
#define IDS_2138 2138 // "Fast VLB/PCI"
|
||||
#define IDS_2139 2139
|
||||
#define IDS_2140 2140
|
||||
#define IDS_2141 2141
|
||||
#define IDS_2142 2142
|
||||
#define IDS_2143 2143
|
||||
#define IDS_2144 2144 // "Standard 2-button joystick(s)"
|
||||
#define IDS_2145 2145 // "Standard 4-button joystick"
|
||||
#define IDS_2146 2146 // "Standard 6-button joystick"
|
||||
#define IDS_2147 2147 // "Standard 8-button joystick"
|
||||
#define IDS_2148 2148 // "CH Flightstick Pro"
|
||||
#define IDS_2149 2149 // "Microsoft SideWinder Pad"
|
||||
#define IDS_2150 2150 // "Thrustmaster Flight Control System"
|
||||
#define IDS_2151 2151 // "Disabled"
|
||||
#define IDS_2152 2152 // "None"
|
||||
#define IDS_2153 2153 // "AT Fixed Disk Adapter"
|
||||
#define IDS_2154 2154 // "Internal IDE"
|
||||
#define IDS_2155 2155 // "IRQ %i"
|
||||
#define IDS_2156 2156 // "MFM (%01i:%01i)"
|
||||
#define IDS_2157 2157 // "IDE (PIO+DMA) (%01i:%01i)"
|
||||
#define IDS_2158 2158 // "SCSI (%02i:%02i)"
|
||||
#define IDS_2159 2159 // "Invalid number of cylinders.."
|
||||
#define IDS_2160 2160 // "%" PRIu64
|
||||
#define IDS_2161 2161
|
||||
#define IDS_2162 2162
|
||||
#define IDS_2163 2163 // "Attempting to create a spuriously.."
|
||||
#define IDS_2164 2164 // "Invalid number of sectors.."
|
||||
#define IDS_2165 2165 // "MFM"
|
||||
#define IDS_2166 2166 // "XT IDE"
|
||||
#define IDS_2167 2167 // "ESDI"
|
||||
#define IDS_2168 2168 // "IDE (PIO-only)"
|
||||
#define IDS_2169 2169 // "%01i:%01i"
|
||||
#define IDS_2170 2170 // "%01i:%01i"
|
||||
#define IDS_2171 2171
|
||||
|
||||
#define IDS_3072 3072
|
||||
#define IDS_3073 3073
|
||||
#define IDS_3074 3074
|
||||
#define IDS_3075 3075
|
||||
#define IDS_3076 3076
|
||||
#define IDS_3077 3077
|
||||
#define IDS_3078 3078
|
||||
#define IDS_3079 3079
|
||||
#define IDS_3080 3080
|
||||
#define IDS_3081 3081
|
||||
#define IDS_3082 3082
|
||||
|
||||
#define IDS_4096 4096
|
||||
#define IDS_4097 4097
|
||||
#define IDS_4098 4098
|
||||
#define IDS_4099 4099
|
||||
#define IDS_4100 4100
|
||||
#define IDS_4101 4101
|
||||
#define IDS_4102 4102
|
||||
#define IDS_4103 4103
|
||||
#define IDS_4104 4104
|
||||
#define IDS_4105 4105
|
||||
#define IDS_4106 4106
|
||||
#define IDS_4107 4107
|
||||
#define IDS_4108 4108
|
||||
#define IDS_4109 4109
|
||||
#define IDS_4110 4110
|
||||
#define IDS_4111 4111
|
||||
#define IDS_4112 4112
|
||||
#define IDS_4113 4113
|
||||
#define IDS_4114 4114
|
||||
#define IDS_4115 4115
|
||||
|
||||
#define IDS_4352 4352
|
||||
#define IDS_4353 4353
|
||||
#define IDS_4354 4354
|
||||
#define IDS_4355 4355
|
||||
#define IDS_4356 4356
|
||||
#define IDS_4357 4357
|
||||
#define IDS_4358 4358
|
||||
|
||||
#define IDS_4608 4608
|
||||
#define IDS_4609 4609
|
||||
#define IDS_4610 4610
|
||||
#define IDS_4611 4611
|
||||
#define IDS_4612 4612
|
||||
#define IDS_4613 4613
|
||||
#define IDS_4614 4614
|
||||
|
||||
#define IDS_5120 5120
|
||||
|
||||
#define IDS_5376 5376
|
||||
#define IDS_5377 5377
|
||||
#define IDS_5378 5378
|
||||
#define IDS_5379 5379
|
||||
#define IDS_5380 5380
|
||||
#define IDS_5381 5381
|
||||
#define IDS_5382 5382
|
||||
|
||||
#define IDS_5632 5632
|
||||
#define IDS_5633 5633
|
||||
#define IDS_5634 5634
|
||||
#define IDS_5635 5635
|
||||
#define IDS_5636 5636
|
||||
#define IDS_5637 5637
|
||||
#define IDS_5638 5638
|
||||
|
||||
#define IDS_6144 6144
|
||||
|
||||
#define IDS_LANG_ENUS IDS_6144
|
||||
|
||||
#define STRINGS_NUM_2048 124
|
||||
#define STRINGS_NUM_3072 11
|
||||
#define STRINGS_NUM_4096 20
|
||||
#define STRINGS_NUM_4352 7
|
||||
#define STRINGS_NUM_4608 7
|
||||
#define STRINGS_NUM_5120 1
|
||||
#define STRINGS_NUM_5376 7
|
||||
#define STRINGS_NUM_5632 7
|
||||
#define STRINGS_NUM_6144 1
|
||||
|
||||
|
||||
#define IDM_ABOUT 40001
|
||||
#define IDC_ABOUT_ICON 65535
|
||||
#define IDM_ACTION_SCREENSHOT 40011
|
||||
#define IDM_ACTION_HRESET 40012
|
||||
#define IDM_ACTION_RESET_CAD 40013
|
||||
#define IDM_ACTION_EXIT 40014
|
||||
#define IDM_ACTION_CTRL_ALT_ESC 40015
|
||||
#define IDM_CONFIG 40020
|
||||
#define IDM_CONFIG_LOAD 40021
|
||||
#define IDM_CONFIG_SAVE 40022
|
||||
#define IDM_STATUS 40030
|
||||
#define IDM_VID_RESIZE 40050
|
||||
#define IDM_VID_REMEMBER 40051
|
||||
#define IDM_VID_DDRAW 40060
|
||||
#define IDM_VID_D3D 40061
|
||||
#define IDM_VID_SCALE_1X 40064
|
||||
#define IDM_VID_SCALE_2X 40065
|
||||
#define IDM_VID_SCALE_3X 40066
|
||||
#define IDM_VID_SCALE_4X 40067
|
||||
#define IDM_VID_FULLSCREEN 40070
|
||||
#define IDM_VID_FS_FULL 40071
|
||||
#define IDM_VID_FS_43 40072
|
||||
#define IDM_VID_FS_SQ 40073
|
||||
#define IDM_VID_FS_INT 40074
|
||||
#define IDM_VID_FORCE43 40075
|
||||
#define IDM_VID_OVERSCAN 40076
|
||||
#define IDM_VID_INVERT 40079
|
||||
#define IDM_VID_CGACON 40080
|
||||
#define IDM_VID_GRAYCT_601 40085
|
||||
#define IDM_VID_GRAYCT_709 40086
|
||||
#define IDM_VID_GRAYCT_AVE 40087
|
||||
#define IDM_VID_GRAY_RGB 40090
|
||||
#define IDM_VID_GRAY_MONO 40091
|
||||
#define IDM_VID_GRAY_AMBER 40092
|
||||
#define IDM_VID_GRAY_GREEN 40093
|
||||
#define IDM_VID_GRAY_WHITE 40094
|
||||
|
||||
#define IDM_LOG_BREAKPOINT 51201
|
||||
#define IDM_DUMP_VRAM 51202 // should be an Action
|
||||
|
||||
#define IDM_LOG_SERIAL 51211
|
||||
#define IDM_LOG_D86F 51212
|
||||
#define IDM_LOG_FDC 51213
|
||||
#define IDM_LOG_IDE 51214
|
||||
#define IDM_LOG_CDROM 51215
|
||||
#define IDM_LOG_NIC 51216
|
||||
#define IDM_LOG_BUSLOGIC 51217
|
||||
|
||||
/*
|
||||
* We need 7 bits for CDROM (2 bits ID and 5 bits for host drive),
|
||||
* and 5 bits for Removable Disks (5 bits for ID), so we use an
|
||||
* 8bit (256 entries) space for these devices.
|
||||
*/
|
||||
#define IDM_FLOPPY_IMAGE_NEW 0x1200
|
||||
#define IDM_FLOPPY_IMAGE_EXISTING 0x1300
|
||||
#define IDM_FLOPPY_IMAGE_EXISTING_WP 0x1400
|
||||
#define IDM_FLOPPY_DUMP_86F 0x1500
|
||||
#define IDM_FLOPPY_EJECT 0x1600
|
||||
|
||||
#define IDM_CDROM_MUTE 0x2200
|
||||
#define IDM_CDROM_EMPTY 0x2300
|
||||
#define IDM_CDROM_RELOAD 0x2400
|
||||
#define IDM_CDROM_IMAGE 0x2500
|
||||
#define IDM_CDROM_HOST_DRIVE 0x2600
|
||||
|
||||
#define IDM_RDISK_EJECT 0x3200
|
||||
#define IDM_RDISK_RELOAD 0x3300
|
||||
#define IDM_RDISK_SEND_CHANGE 0x3400
|
||||
#define IDM_RDISK_IMAGE 0x3500
|
||||
#define IDM_RDISK_IMAGE_WP 0x3600
|
||||
|
||||
|
||||
/* Next default values for new objects */
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
# ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
# define _APS_NO_MFC 1
|
||||
# define _APS_NEXT_RESOURCE_VALUE 1400
|
||||
# define _APS_NEXT_COMMAND_VALUE 55000
|
||||
# define _APS_NEXT_CONTROL_VALUE 1800
|
||||
# define _APS_NEXT_SYMED_VALUE 200
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
#endif /*WIN_RESOURCE_H*/
|
||||
2742
src/win/win.c
Normal file
117
src/win/win.h
Normal file
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* The Emulator's Windows core.
|
||||
*
|
||||
* Version: @(#)win.h 1.0.0 2017/05/30
|
||||
*
|
||||
* Author: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Copyright 2008-2017 Sarah Walker.
|
||||
* Copyright 2016-2017 Miran Grca.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This should be named 'plat.h' and then include any
|
||||
* Windows-specific header files needed, to keep them
|
||||
* out of the main code.
|
||||
*/
|
||||
/* Copyright holders: Sarah Walker
|
||||
see COPYING for more details
|
||||
*/
|
||||
#ifndef BOX_WIN_H
|
||||
# define BOX_WIN_H
|
||||
|
||||
# ifndef NO_UNICODE
|
||||
# define UNICODE
|
||||
# endif
|
||||
# define BITMAP WINDOWS_BITMAP
|
||||
/* # ifdef _WIN32_WINNT
|
||||
# undef _WIN32_WINNT
|
||||
# define _WIN32_WINNT 0x0501
|
||||
# endif */
|
||||
# include <windows.h>
|
||||
# include "resource.h"
|
||||
# undef BITMAP
|
||||
|
||||
|
||||
#define szClassName L"86BoxMainWnd"
|
||||
#define szSubClassName L"86BoxSubWnd"
|
||||
#define szStatusBarClassName L"86BoxStatusBar"
|
||||
|
||||
|
||||
#define WM_RESETD3D WM_USER
|
||||
#define WM_LEAVEFULLSCREEN WM_USER + 1
|
||||
|
||||
#define WM_SAVESETTINGS 0x8888 /* 86Box-specific message, used to tell the child dialog to save the currently specified settings. */
|
||||
|
||||
#define SB_ICON_WIDTH 24
|
||||
|
||||
|
||||
extern HINSTANCE hinstance;
|
||||
extern HWND ghwnd;
|
||||
extern HWND status_hwnd;
|
||||
extern HWND hwndStatus;
|
||||
extern int status_is_open;
|
||||
extern int mousecapture;
|
||||
|
||||
extern char openfilestring[260];
|
||||
extern WCHAR wopenfilestring[260];
|
||||
|
||||
extern int pause;
|
||||
|
||||
extern HMENU smenu;
|
||||
extern HMENU *sb_menu_handles;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern void leave_fullscreen(void);
|
||||
|
||||
extern void status_open(HWND hwnd);
|
||||
|
||||
extern void deviceconfig_open(HWND hwnd, struct device_t *device);
|
||||
extern void joystickconfig_open(HWND hwnd, int joy_nr, int type);
|
||||
|
||||
extern int getfile(HWND hwnd, char *f, char *fn);
|
||||
extern int getsfile(HWND hwnd, char *f, char *fn);
|
||||
|
||||
extern void get_executable_name(wchar_t *s, int size);
|
||||
extern void set_window_title(wchar_t *s);
|
||||
|
||||
extern void startblit(void);
|
||||
extern void endblit(void);
|
||||
|
||||
extern void win_settings_open(HWND hwnd);
|
||||
extern void win_menu_update();
|
||||
|
||||
extern void update_status_bar_panes(HWND hwnds);
|
||||
|
||||
extern int fdd_type_to_icon(int type);
|
||||
|
||||
extern void hard_disk_add_open(HWND hwnd, int is_existing);
|
||||
extern int hard_disk_was_added(void);
|
||||
|
||||
extern void get_registry_key_map(void);
|
||||
extern void process_raw_input(LPARAM lParam, int infocus);
|
||||
|
||||
extern int find_status_bar_part(int tag);
|
||||
|
||||
extern void cdrom_close(uint8_t id);
|
||||
extern void update_tip(int meaning);
|
||||
|
||||
extern BOOL DirectoryExists(LPCTSTR szPath);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /*BOX_WIN_H*/
|
||||
29
src/win/win_cgapal.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* The Windows CGA palette handler header.
|
||||
*
|
||||
* Version: @(#)win_cgapal.h 1.0.0 2017/05/30
|
||||
*
|
||||
* Author: Miran Grca, <mgrca8@gmail.com>
|
||||
* Copyright 2016-2017 Miran Grca.
|
||||
*/
|
||||
|
||||
extern PALETTE cgapal;
|
||||
extern PALETTE cgapal_mono[6];
|
||||
|
||||
extern uint32_t pal_lookup[256];
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void cgapal_rebuild();
|
||||
void destroy_bitmap(BITMAP *b);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
225
src/win/win_crashdump.c
Normal file
@@ -0,0 +1,225 @@
|
||||
/* Copyright holders: Riley
|
||||
see COPYING for more details
|
||||
|
||||
win_crashdump.c : Windows exception handler to make a crash dump just before a crash happens.
|
||||
*/
|
||||
#define _WIN32_WINNT 0x0501
|
||||
#include <windows.h>
|
||||
#include <psapi.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "../86box.h"
|
||||
#include "win_crashdump.h"
|
||||
|
||||
|
||||
#define ExceptionHandlerBufferSize (10240)
|
||||
|
||||
|
||||
static PVOID hExceptionHandler;
|
||||
static char *ExceptionHandlerBuffer;
|
||||
|
||||
|
||||
LONG CALLBACK MakeCrashDump(PEXCEPTION_POINTERS ExceptionInfo)
|
||||
{
|
||||
SYSTEMTIME SystemTime;
|
||||
HANDLE hDumpFile;
|
||||
DWORD Error;
|
||||
char *BufPtr;
|
||||
|
||||
/*
|
||||
* Win32-specific functions will be used wherever possible,
|
||||
* just in case the C stdlib-equivalents try to allocate
|
||||
* memory.
|
||||
* (The Win32-specific functions are generally just wrappers
|
||||
* over NT system calls anyway.)
|
||||
*/
|
||||
if ((ExceptionInfo->ExceptionRecord->ExceptionCode >> 28) != 0xC) {
|
||||
/*
|
||||
* ExceptionCode is not a fatal exception (high 4b of
|
||||
* ntstatus = 0xC) Not going to crash, let's not make
|
||||
* a crash dump.
|
||||
*/
|
||||
return(EXCEPTION_CONTINUE_SEARCH);
|
||||
}
|
||||
|
||||
/*
|
||||
* So, the program is about to crash. Oh no what do?
|
||||
* Let's create a crash dump file as a debugging-aid.
|
||||
*
|
||||
* First, get the path to the executable.
|
||||
*/
|
||||
GetModuleFileName(NULL,ExceptionHandlerBuffer,ExceptionHandlerBufferSize);
|
||||
if (GetLastError() != ERROR_SUCCESS) {
|
||||
/* Could not get full path, create in current directory. */
|
||||
BufPtr = ExceptionHandlerBuffer;
|
||||
} else {
|
||||
/*
|
||||
* Walk through the string backwards looking for the
|
||||
* last backslash, so as to remove the "86Box.exe"
|
||||
* filename from the string.
|
||||
*/
|
||||
BufPtr = &ExceptionHandlerBuffer[strlen(ExceptionHandlerBuffer)];
|
||||
for (; BufPtr > ExceptionHandlerBuffer; BufPtr--) {
|
||||
if (BufPtr[0] == '\\') {
|
||||
/* Found backslash, terminate the string after it. */
|
||||
BufPtr[1] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
BufPtr = &ExceptionHandlerBuffer[strlen(ExceptionHandlerBuffer)];
|
||||
}
|
||||
|
||||
/*
|
||||
* What would a good filename be?
|
||||
*
|
||||
* It should contain the current date and time so as
|
||||
* to be (hopefully!) unique.
|
||||
*/
|
||||
GetSystemTime(&SystemTime);
|
||||
sprintf(CurrentBufferPointer,
|
||||
"86box-%d%02d%02d-%02d-%02d-%02d-%03d.dmp",
|
||||
SystemTime.wYear,
|
||||
SystemTime.wMonth,
|
||||
SystemTime.wDay,
|
||||
SystemTime.wHour,
|
||||
SystemTime.wMinute,
|
||||
SystemTime.wSecond,
|
||||
SystemTime.wMilliseconds);
|
||||
|
||||
/* Now the filename is in the buffer, the file can be created. */
|
||||
hDumpFile = CreateFile(
|
||||
ExceptionHandlerBuffer, // The filename of the file to open.
|
||||
GENERIC_WRITE, // The permissions to request.
|
||||
0, // Make sure other processes can't
|
||||
// touch the crash dump at all
|
||||
// while it's open.
|
||||
NULL, // Leave the security descriptor
|
||||
// undefined, it doesn't matter.
|
||||
OPEN_ALWAYS, // Opens the file if it exists,
|
||||
// creates a new file if it doesn't.
|
||||
FILE_ATTRIBUTE_NORMAL, // File attributes / etc don't matter.
|
||||
NULL); // A template file is not being used.
|
||||
|
||||
/* Check to make sure the file was actually created. */
|
||||
if (hDumpFile == INVALID_HANDLE_VALUE) {
|
||||
/* CreateFile() failed, so just do nothing more. */
|
||||
return(EXCEPTION_CONTINUE_SEARCH);
|
||||
}
|
||||
|
||||
// Now the file is open, let's write the data we were passed out in a human-readable format.
|
||||
|
||||
// Let's get the name of the module where the exception occured.
|
||||
HMODULE hMods[1024];
|
||||
MODULEINFO modInfo;
|
||||
HMODULE ipModule = 0;
|
||||
DWORD cbNeeded;
|
||||
|
||||
// Try to get a list of all loaded modules.
|
||||
if (EnumProcessModules(GetCurrentProcess(),
|
||||
hMods, sizeof(hMods), &cbNeeded)) {
|
||||
// The list was obtained, walk through each of the modules.
|
||||
for (DWORD i = 0; i < (cbNeeded / sizeof(HMODULE)); i++) {
|
||||
// For each module, get the module information
|
||||
// (base address, size, entry point)
|
||||
GetModuleInformation(GetCurrentProcess(),
|
||||
hMods[i], &modInfo, sizeof(MODULEINFO));
|
||||
// If the exception address is located in the range of
|
||||
// where this module is loaded...
|
||||
if ( (ExceptionInfo->ExceptionRecord->ExceptionAddress >= modInfo.lpBaseOfDll) &&
|
||||
(ExceptionInfo->ExceptionRecord->ExceptionAddress < (modInfo.lpBaseOfDll + modInfo.SizeOfImage))) {
|
||||
// ...this is the module we're looking for!
|
||||
ipModule = hMods[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Start to put the crash-dump string into the buffer.
|
||||
sprintf(ExceptionHandlerBuffer,
|
||||
"86Box version %s crashed on %d-%02d-%02d %02d:%02d:%02d.%03d\r\n\r\n"
|
||||
""
|
||||
"Exception details:\r\n"
|
||||
"Exception NTSTATUS code: 0x%08x\r\n"
|
||||
"Occured at address: 0x%p",
|
||||
emulator_version,
|
||||
SystemTime.wYear, SystemTime.wMonth, SystemTime.wDay,
|
||||
SystemTime.wHour, SystemTime.wMinute, SystemTime.wSecond,
|
||||
SystemTime.wMilliseconds,
|
||||
ExceptionInfo->ExceptionRecord->ExceptionCode,
|
||||
ExceptionInfo->ExceptionRecord->ExceptionAddress);
|
||||
|
||||
// If we found the module that the exception occured in, get the full path to the module the exception occured at and include it.
|
||||
BufPtr = &ExceptionHandlerBuffer[strlen(ExceptionHandlerBuffer)];
|
||||
if (ipModule != 0) {
|
||||
sprintf(BufPtr," [");
|
||||
GetModuleFileName(ipModule, &BufPtr[2],
|
||||
ExceptionHandlerBufferSize - strlen(ExceptionHandlerBuffer));
|
||||
if (GetLastError() == ERROR_SUCCESS) {
|
||||
BufPtr = &ExceptionHandlerBuffer[strlen(ExceptionHandlerBuffer)];
|
||||
sprintf(BufPtr,"]");
|
||||
BufPtr += 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Continue to create the crash-dump string.
|
||||
sprintf(BufPtr,
|
||||
"\r\n"
|
||||
"Number of parameters: %d\r\n"
|
||||
"Exception parameters: ",
|
||||
ExceptionInfo->ExceptionRecord->NumberParameters);
|
||||
|
||||
// Add the exception parameters to the crash-dump string.
|
||||
for (int i = 0; i < ExceptionInfo->ExceptionRecord->NumberParameters; i++) {
|
||||
BufPtr = &ExceptionHandlerBuffer[strlen(ExceptionHandlerBuffer)];
|
||||
sprintf(BufPtr,"0x%p ",
|
||||
ExceptionInfo->ExceptionRecord->ExceptionInformation[i]);
|
||||
}
|
||||
BufPtr = &ExceptionHandlerBuffer[strlen(ExceptionHandlerBuffer) - 1];
|
||||
|
||||
PCONTEXT Registers = ExceptionInfo->ContextRecord;
|
||||
|
||||
#if defined(__i386__) && !defined(__x86_64)
|
||||
// This binary is being compiled for x86, include a register dump.
|
||||
sprintf(BufPtr,
|
||||
"\r\n"
|
||||
"Register dump:\r\n"
|
||||
"eax=0x%08x ebx=0x%08x ecx=0x%08x edx=0x%08x ebp=0x%08x esp=0x%08x esi=0x%08x edi=0x%08x eip=0x%08x\r\n"
|
||||
"\r\n",
|
||||
Registers->Eax, Registers->Ebx, Registers->Ecx, Registers->Edx, Registers->Ebp, Registers->Esp, Registers->Esi, Registers->Edi, Registers->Eip);
|
||||
#else
|
||||
// Register dump is supported by no other architectures right now. MinGW headers seem to lack the x64 CONTEXT structure definition.
|
||||
sprintf(BufPtr,"\r\n");
|
||||
#endif
|
||||
|
||||
// The crash-dump string has been created, write it to disk.
|
||||
WriteFile(hDumpFile, ExceptionHandlerBuffer,
|
||||
strlen(ExceptionHandlerBuffer), NULL, NULL);
|
||||
|
||||
// Finally, close the file.
|
||||
CloseHandle(hDumpFile);
|
||||
|
||||
// And return, therefore causing the crash,
|
||||
// but only after the crash dump has been created.
|
||||
return(EXCEPTION_CONTINUE_SEARCH);
|
||||
}
|
||||
|
||||
|
||||
void InitCrashDump(void)
|
||||
{
|
||||
/*
|
||||
* An exception handler should not allocate memory,
|
||||
* so allocate 10kb for it to use if it gets called,
|
||||
* an amount which should be more than enough.
|
||||
*/
|
||||
ExceptionHandlerBuffer = malloc(ExceptionHandlerBufferSize);
|
||||
|
||||
/*
|
||||
* Register the exception handler.
|
||||
* Zero first argument means this exception handler gets
|
||||
* called last, therefore, crash dump is only made, when
|
||||
* a crash is going to happen.
|
||||
*/
|
||||
hExceptionHandler = AddVectoredExceptionHandler(0, MakeCrashDump);
|
||||
}
|
||||
7
src/win/win_crashdump.h
Normal file
@@ -0,0 +1,7 @@
|
||||
/* Copyright holders: Riley
|
||||
see COPYING for more details
|
||||
|
||||
win-crashdump.c : Windows crash dump exception handler header file.
|
||||
*/
|
||||
|
||||
void InitCrashDump();
|
||||
431
src/win/win_d3d.cc
Normal file
@@ -0,0 +1,431 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Direct3D 9 rendererer and screenshots taking.
|
||||
*
|
||||
* Version: @(#)win_d3d.cc 1.0.1 2017/08/23
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Copyright 2008-2017 Sarah Walker.
|
||||
* Copyright 2016,2017 Miran Grca.
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include "../video/video.h"
|
||||
#include "win.h"
|
||||
#include "win_d3d.h"
|
||||
#include "win_cgapal.h"
|
||||
|
||||
|
||||
extern "C" void fatal(const char *format, ...);
|
||||
extern "C" void pclog(const char *format, ...);
|
||||
|
||||
extern "C" void device_force_redraw(void);
|
||||
extern "C" void video_blit_complete(void);
|
||||
|
||||
|
||||
void d3d_init_objects(void);
|
||||
void d3d_close_objects(void);
|
||||
void d3d_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h);
|
||||
void d3d_blit_memtoscreen_8(int x, int y, int w, int h);
|
||||
|
||||
static LPDIRECT3D9 d3d = NULL;
|
||||
static LPDIRECT3DDEVICE9 d3ddev = NULL;
|
||||
static LPDIRECT3DVERTEXBUFFER9 v_buffer = NULL;
|
||||
static LPDIRECT3DTEXTURE9 d3dTexture = NULL;
|
||||
static D3DPRESENT_PARAMETERS d3dpp;
|
||||
|
||||
static HWND d3d_hwnd;
|
||||
|
||||
struct CUSTOMVERTEX
|
||||
{
|
||||
FLOAT x, y, z, rhw; // from the D3DFVF_XYZRHW flag
|
||||
DWORD color;
|
||||
FLOAT tu, tv;
|
||||
};
|
||||
|
||||
static CUSTOMVERTEX d3d_verts[] =
|
||||
{
|
||||
{ 0.0f, 0.0f, 1.0f, 1.0f, 0xffffff, 0.0f, 0.0f},
|
||||
{2048.0f, 2048.0f, 1.0f, 1.0f, 0xffffff, 1.0f, 1.0f},
|
||||
{ 0.0f, 2048.0f, 1.0f, 1.0f, 0xffffff, 0.0f, 1.0f},
|
||||
|
||||
{ 0.0f, 0.0f, 1.0f, 1.0f, 0xffffff, 0.0f, 0.0f},
|
||||
{2048.0f, 0.0f, 1.0f, 1.0f, 0xffffff, 1.0f, 0.0f},
|
||||
{2048.0f, 2048.0f, 1.0f, 1.0f, 0xffffff, 1.0f, 1.0f},
|
||||
|
||||
{ 0.0f, 0.0f, 1.0f, 1.0f, 0xffffff, 0.0f, 0.0f},
|
||||
{2048.0f, 2048.0f, 1.0f, 1.0f, 0xffffff, 1.0f, 1.0f},
|
||||
{ 0.0f, 2048.0f, 1.0f, 1.0f, 0xffffff, 0.0f, 1.0f},
|
||||
|
||||
{ 0.0f, 0.0f, 1.0f, 1.0f, 0xffffff, 0.0f, 0.0f},
|
||||
{2048.0f, 0.0f, 1.0f, 1.0f, 0xffffff, 1.0f, 0.0f},
|
||||
{2048.0f, 2048.0f, 1.0f, 1.0f, 0xffffff, 1.0f, 1.0f}
|
||||
};
|
||||
|
||||
int d3d_init(HWND h)
|
||||
{
|
||||
int c;
|
||||
|
||||
for (c = 0; c < 256; c++)
|
||||
pal_lookup[c] = makecol(cgapal[c].r << 2, cgapal[c].g << 2, cgapal[c].b << 2);
|
||||
|
||||
d3d_hwnd = h;
|
||||
|
||||
d3d = Direct3DCreate9(D3D_SDK_VERSION);
|
||||
|
||||
memset(&d3dpp, 0, sizeof(d3dpp));
|
||||
|
||||
d3dpp.Flags = 0;
|
||||
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
|
||||
d3dpp.hDeviceWindow = h;
|
||||
d3dpp.BackBufferCount = 1;
|
||||
d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
|
||||
d3dpp.MultiSampleQuality = 0;
|
||||
d3dpp.EnableAutoDepthStencil = false;
|
||||
d3dpp.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
|
||||
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
|
||||
d3dpp.Windowed = true;
|
||||
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
|
||||
d3dpp.BackBufferWidth = 0;
|
||||
d3dpp.BackBufferHeight = 0;
|
||||
|
||||
if (FAILED(d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, h, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3ddev)))
|
||||
fatal("CreateDevice failed\n");
|
||||
|
||||
d3d_init_objects();
|
||||
|
||||
video_blit_memtoscreen_func = d3d_blit_memtoscreen;
|
||||
video_blit_memtoscreen_8_func = d3d_blit_memtoscreen_8;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void d3d_close_objects()
|
||||
{
|
||||
if (d3dTexture)
|
||||
{
|
||||
d3dTexture->Release();
|
||||
d3dTexture = NULL;
|
||||
}
|
||||
if (v_buffer)
|
||||
{
|
||||
v_buffer->Release();
|
||||
v_buffer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void d3d_init_objects()
|
||||
{
|
||||
D3DLOCKED_RECT dr;
|
||||
int y;
|
||||
RECT r;
|
||||
|
||||
if (FAILED(d3ddev->CreateVertexBuffer(12*sizeof(CUSTOMVERTEX),
|
||||
0,
|
||||
D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1,
|
||||
D3DPOOL_MANAGED,
|
||||
&v_buffer,
|
||||
NULL)))
|
||||
fatal("CreateVertexBuffer failed\n");
|
||||
|
||||
if (FAILED(d3ddev->CreateTexture(2048, 2048, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &d3dTexture, NULL)))
|
||||
fatal("CreateTexture failed\n");
|
||||
|
||||
r.top = r.left = 0;
|
||||
r.bottom = r.right = 2047;
|
||||
|
||||
if (FAILED(d3dTexture->LockRect(0, &dr, &r, 0)))
|
||||
fatal("LockRect failed\n");
|
||||
|
||||
for (y = 0; y < 2048; y++)
|
||||
{
|
||||
uint32_t *p = (uint32_t *)((uintptr_t)dr.pBits + (y * dr.Pitch));
|
||||
memset(p, 0, 2048 * 4);
|
||||
}
|
||||
|
||||
d3dTexture->UnlockRect(0);
|
||||
|
||||
d3ddev->SetTextureStageState(0,D3DTSS_COLOROP, D3DTOP_SELECTARG1);
|
||||
d3ddev->SetTextureStageState(0,D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
d3ddev->SetTextureStageState(0,D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||
|
||||
d3ddev->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
|
||||
d3ddev->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
|
||||
}
|
||||
|
||||
void d3d_resize(int x, int y)
|
||||
{
|
||||
d3dpp.BackBufferWidth = x;
|
||||
d3dpp.BackBufferHeight = y;
|
||||
|
||||
d3d_reset();
|
||||
}
|
||||
|
||||
void d3d_reset()
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (!d3ddev)
|
||||
return;
|
||||
memset(&d3dpp, 0, sizeof(d3dpp));
|
||||
|
||||
d3dpp.Flags = 0;
|
||||
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
|
||||
d3dpp.hDeviceWindow = d3d_hwnd;
|
||||
d3dpp.BackBufferCount = 1;
|
||||
d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
|
||||
d3dpp.MultiSampleQuality = 0;
|
||||
d3dpp.EnableAutoDepthStencil = false;
|
||||
d3dpp.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
|
||||
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
|
||||
d3dpp.Windowed = true;
|
||||
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
|
||||
d3dpp.BackBufferWidth = 0;
|
||||
d3dpp.BackBufferHeight = 0;
|
||||
|
||||
hr = d3ddev->Reset(&d3dpp);
|
||||
|
||||
if (hr == D3DERR_DEVICELOST)
|
||||
return;
|
||||
|
||||
d3ddev->SetTextureStageState(0,D3DTSS_COLOROP, D3DTOP_SELECTARG1);
|
||||
d3ddev->SetTextureStageState(0,D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
d3ddev->SetTextureStageState(0,D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||
|
||||
d3ddev->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
|
||||
d3ddev->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
|
||||
|
||||
device_force_redraw();
|
||||
}
|
||||
|
||||
void d3d_close()
|
||||
{
|
||||
if (d3dTexture)
|
||||
{
|
||||
d3dTexture->Release();
|
||||
d3dTexture = NULL;
|
||||
}
|
||||
if (v_buffer)
|
||||
{
|
||||
v_buffer->Release();
|
||||
v_buffer = NULL;
|
||||
}
|
||||
if (d3ddev)
|
||||
{
|
||||
d3ddev->Release();
|
||||
d3ddev = NULL;
|
||||
}
|
||||
if (d3d)
|
||||
{
|
||||
d3d->Release();
|
||||
d3d = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void d3d_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h)
|
||||
{
|
||||
HRESULT hr = D3D_OK;
|
||||
VOID* pVoid;
|
||||
D3DLOCKED_RECT dr;
|
||||
RECT r;
|
||||
int yy;
|
||||
|
||||
if (y1 == y2)
|
||||
{
|
||||
video_blit_complete();
|
||||
return; /*Nothing to do*/
|
||||
}
|
||||
|
||||
r.top = y1;
|
||||
r.left = 0;
|
||||
r.bottom = y2;
|
||||
r.right = 2047;
|
||||
|
||||
hr = d3dTexture->LockRect(0, &dr, &r, 0);
|
||||
if (hr == D3D_OK)
|
||||
{
|
||||
for (yy = y1; yy < y2; yy++)
|
||||
{
|
||||
if ((y + yy) >= 0 && (y + yy) < buffer32->h)
|
||||
memcpy((void *)((uintptr_t)dr.pBits + ((yy - y1) * dr.Pitch)), &(((uint32_t *)buffer32->line[yy + y])[x]), w * 4);
|
||||
}
|
||||
|
||||
video_blit_complete();
|
||||
d3dTexture->UnlockRect(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
video_blit_complete();
|
||||
return;
|
||||
}
|
||||
|
||||
d3d_verts[0].tu = d3d_verts[2].tu = d3d_verts[3].tu = 0;//0.5 / 2048.0;
|
||||
d3d_verts[0].tv = d3d_verts[3].tv = d3d_verts[4].tv = 0;//0.5 / 2048.0;
|
||||
d3d_verts[1].tu = d3d_verts[4].tu = d3d_verts[5].tu = (float)w / 2048.0;
|
||||
d3d_verts[1].tv = d3d_verts[2].tv = d3d_verts[5].tv = (float)h / 2048.0;
|
||||
d3d_verts[0].color = d3d_verts[1].color = d3d_verts[2].color =
|
||||
d3d_verts[3].color = d3d_verts[4].color = d3d_verts[5].color =
|
||||
d3d_verts[6].color = d3d_verts[7].color = d3d_verts[8].color =
|
||||
d3d_verts[9].color = d3d_verts[10].color = d3d_verts[11].color = 0xffffff;
|
||||
|
||||
GetClientRect(d3d_hwnd, &r);
|
||||
d3d_verts[0].x = d3d_verts[2].x = d3d_verts[3].x = -0.5;
|
||||
d3d_verts[0].y = d3d_verts[3].y = d3d_verts[4].y = -0.5;
|
||||
d3d_verts[1].x = d3d_verts[4].x = d3d_verts[5].x = (r.right - r.left) - 0.5;
|
||||
d3d_verts[1].y = d3d_verts[2].y = d3d_verts[5].y = (r.bottom - r.top) - 0.5;
|
||||
d3d_verts[6].x = d3d_verts[8].x = d3d_verts[9].x = (r.right - r.left) - 40.5;
|
||||
d3d_verts[6].y = d3d_verts[9].y = d3d_verts[10].y = 8.5;
|
||||
d3d_verts[7].x = d3d_verts[10].x = d3d_verts[11].x = (r.right - r.left) - 8.5;
|
||||
d3d_verts[7].y = d3d_verts[8].y = d3d_verts[11].y = 14.5;
|
||||
|
||||
if (hr == D3D_OK)
|
||||
hr = v_buffer->Lock(0, 0, (void**)&pVoid, 0); // lock the vertex buffer
|
||||
if (hr == D3D_OK)
|
||||
memcpy(pVoid, d3d_verts, sizeof(d3d_verts)); // copy the vertices to the locked buffer
|
||||
if (hr == D3D_OK)
|
||||
hr = v_buffer->Unlock(); // unlock the vertex buffer
|
||||
|
||||
if (hr == D3D_OK)
|
||||
hr = d3ddev->BeginScene();
|
||||
|
||||
if (hr == D3D_OK)
|
||||
{
|
||||
if (hr == D3D_OK)
|
||||
hr = d3ddev->SetTexture(0, d3dTexture);
|
||||
|
||||
if (hr == D3D_OK)
|
||||
hr = d3ddev->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1);
|
||||
|
||||
if (hr == D3D_OK)
|
||||
hr = d3ddev->SetStreamSource(0, v_buffer, 0, sizeof(CUSTOMVERTEX));
|
||||
|
||||
if (hr == D3D_OK)
|
||||
hr = d3ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);
|
||||
|
||||
if (hr == D3D_OK)
|
||||
hr = d3ddev->SetTexture(0, NULL);
|
||||
|
||||
if (hr == D3D_OK)
|
||||
hr = d3ddev->EndScene();
|
||||
}
|
||||
|
||||
if (hr == D3D_OK)
|
||||
hr = d3ddev->Present(NULL, NULL, d3d_hwnd, NULL);
|
||||
|
||||
if (hr == D3DERR_DEVICELOST || hr == D3DERR_INVALIDCALL)
|
||||
PostMessage(d3d_hwnd, WM_RESETD3D, 0, 0);
|
||||
}
|
||||
|
||||
void d3d_blit_memtoscreen_8(int x, int y, int w, int h)
|
||||
{
|
||||
VOID* pVoid;
|
||||
D3DLOCKED_RECT dr;
|
||||
RECT r;
|
||||
int yy, xx;
|
||||
HRESULT hr = D3D_OK;
|
||||
|
||||
if (h == 0)
|
||||
{
|
||||
video_blit_complete();
|
||||
return; /*Nothing to do*/
|
||||
}
|
||||
|
||||
r.top = 0;
|
||||
r.left = 0;
|
||||
r.bottom = h;
|
||||
r.right = 2047;
|
||||
|
||||
hr = d3dTexture->LockRect(0, &dr, &r, 0);
|
||||
if (hr == D3D_OK)
|
||||
{
|
||||
for (yy = 0; yy < h; yy++)
|
||||
{
|
||||
uint32_t *p = (uint32_t *)((uintptr_t)dr.pBits + (yy * dr.Pitch));
|
||||
if ((y + yy) >= 0 && (y + yy) < buffer->h)
|
||||
{
|
||||
for (xx = 0; xx < w; xx++)
|
||||
p[xx] = pal_lookup[buffer->line[y + yy][x + xx]];
|
||||
}
|
||||
}
|
||||
video_blit_complete();
|
||||
|
||||
d3dTexture->UnlockRect(0);
|
||||
}
|
||||
else
|
||||
video_blit_complete();
|
||||
|
||||
d3d_verts[0].tu = d3d_verts[2].tu = d3d_verts[3].tu = 0;//0.5 / 2048.0;
|
||||
d3d_verts[0].tv = d3d_verts[3].tv = d3d_verts[4].tv = 0;//0.5 / 2048.0;
|
||||
d3d_verts[1].tu = d3d_verts[4].tu = d3d_verts[5].tu = (float)w / 2048.0;
|
||||
d3d_verts[1].tv = d3d_verts[2].tv = d3d_verts[5].tv = (float)h / 2048.0;
|
||||
d3d_verts[0].color = d3d_verts[1].color = d3d_verts[2].color =
|
||||
d3d_verts[3].color = d3d_verts[4].color = d3d_verts[5].color =
|
||||
d3d_verts[6].color = d3d_verts[7].color = d3d_verts[8].color =
|
||||
d3d_verts[9].color = d3d_verts[10].color = d3d_verts[11].color = 0xffffff;
|
||||
|
||||
GetClientRect(d3d_hwnd, &r);
|
||||
d3d_verts[0].x = d3d_verts[2].x = d3d_verts[3].x = -0.5;
|
||||
d3d_verts[0].y = d3d_verts[3].y = d3d_verts[4].y = -0.5;
|
||||
d3d_verts[1].x = d3d_verts[4].x = d3d_verts[5].x = (r.right - r.left) - 0.5;
|
||||
d3d_verts[1].y = d3d_verts[2].y = d3d_verts[5].y = (r.bottom - r.top) - 0.5;
|
||||
d3d_verts[6].x = d3d_verts[8].x = d3d_verts[9].x = (r.right - r.left) - 40.5;
|
||||
d3d_verts[6].y = d3d_verts[9].y = d3d_verts[10].y = 8.5;
|
||||
d3d_verts[7].x = d3d_verts[10].x = d3d_verts[11].x = (r.right - r.left) - 8.5;
|
||||
d3d_verts[7].y = d3d_verts[8].y = d3d_verts[11].y = 14.5;
|
||||
|
||||
if (hr == D3D_OK)
|
||||
hr = v_buffer->Lock(0, 0, (void**)&pVoid, 0); // lock the vertex buffer
|
||||
if (hr == D3D_OK)
|
||||
memcpy(pVoid, d3d_verts, sizeof(d3d_verts)); // copy the vertices to the locked buffer
|
||||
if (hr == D3D_OK)
|
||||
hr = v_buffer->Unlock(); // unlock the vertex buffer
|
||||
|
||||
if (hr == D3D_OK)
|
||||
hr = d3ddev->BeginScene();
|
||||
|
||||
if (hr == D3D_OK)
|
||||
{
|
||||
if (hr == D3D_OK)
|
||||
hr = d3ddev->SetTexture(0, d3dTexture);
|
||||
|
||||
if (hr == D3D_OK)
|
||||
hr = d3ddev->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1);
|
||||
|
||||
if (hr == D3D_OK)
|
||||
hr = d3ddev->SetStreamSource(0, v_buffer, 0, sizeof(CUSTOMVERTEX));
|
||||
|
||||
if (hr == D3D_OK)
|
||||
hr = d3ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);
|
||||
|
||||
if (hr == D3D_OK)
|
||||
hr = d3ddev->SetTexture(0, NULL);
|
||||
|
||||
if (hr == D3D_OK)
|
||||
hr = d3ddev->EndScene();
|
||||
}
|
||||
|
||||
if (hr == D3D_OK)
|
||||
hr = d3ddev->Present(NULL, NULL, d3d_hwnd, NULL);
|
||||
|
||||
if (hr == D3DERR_DEVICELOST || hr == D3DERR_INVALIDCALL)
|
||||
PostMessage(d3d_hwnd, WM_RESETD3D, 0, 0);
|
||||
}
|
||||
|
||||
void d3d_take_screenshot(wchar_t *fn)
|
||||
{
|
||||
LPDIRECT3DSURFACE9 d3dSurface = NULL;
|
||||
|
||||
if (!d3dTexture) return;
|
||||
|
||||
d3ddev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &d3dSurface);
|
||||
D3DXSaveSurfaceToFile(fn, D3DXIFF_PNG, d3dSurface, NULL, NULL);
|
||||
|
||||
d3dSurface->Release();
|
||||
d3dSurface = NULL;
|
||||
}
|
||||
47
src/win/win_d3d.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Direct3D 9 rendererer and screenshots taking.
|
||||
*
|
||||
* Version: @(#)win_d3d.h 1.0.0 2017/05/30
|
||||
*
|
||||
* Author: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Copyright 2008-2017 Sarah Walker.
|
||||
* Copyright 2016-2017 Miran Grca.
|
||||
*/
|
||||
|
||||
#ifndef WIN_D3D_H
|
||||
# define WIN_D3D_H
|
||||
# define UNICODE
|
||||
# define BITMAP WINDOWS_BITMAP
|
||||
# include <d3d9.h>
|
||||
# include <d3dx9tex.h>
|
||||
# undef BITMAP
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern int d3d_init(HWND h);
|
||||
extern void d3d_close(void);
|
||||
extern void d3d_reset(void);
|
||||
extern void d3d_resize(int x, int y);
|
||||
|
||||
extern int d3d_fs_init(HWND h);
|
||||
extern void d3d_fs_close(void);
|
||||
extern void d3d_fs_reset(void);
|
||||
extern void d3d_fs_resize(int x, int y);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /*WIN_D3D_H*/
|
||||
633
src/win/win_d3d_fs.cc
Normal file
@@ -0,0 +1,633 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Direct3D 9 full screen rendererer and screenshots taking.
|
||||
*
|
||||
* Version: @(#)win_d3d_fs.cc 1.0.2 2017/08/23
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Copyright 2008-2017 Sarah Walker.
|
||||
* Copyright 2016,2017 Miran Grca.
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include "../86box.h"
|
||||
#include "../video/video.h"
|
||||
#include "win.h"
|
||||
#include "win_d3d.h"
|
||||
#include "win_cgapal.h"
|
||||
|
||||
|
||||
extern "C" void fatal(const char *format, ...);
|
||||
extern "C" void pclog(const char *format, ...);
|
||||
|
||||
extern "C" void device_force_redraw(void);
|
||||
|
||||
static void d3d_fs_init_objects(void);
|
||||
static void d3d_fs_close_objects(void);
|
||||
static void d3d_fs_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h);
|
||||
static void d3d_fs_blit_memtoscreen_8(int x, int y, int w, int h);
|
||||
|
||||
extern "C" void video_blit_complete(void);
|
||||
|
||||
|
||||
static LPDIRECT3D9 d3d = NULL;
|
||||
static LPDIRECT3DDEVICE9 d3ddev = NULL;
|
||||
static LPDIRECT3DVERTEXBUFFER9 v_buffer = NULL;
|
||||
static LPDIRECT3DTEXTURE9 d3dTexture = NULL;
|
||||
static D3DPRESENT_PARAMETERS d3dpp;
|
||||
|
||||
static HWND d3d_hwnd;
|
||||
static HWND d3d_device_window;
|
||||
|
||||
static int d3d_fs_w, d3d_fs_h;
|
||||
|
||||
struct CUSTOMVERTEX
|
||||
{
|
||||
FLOAT x, y, z, rhw; // from the D3DFVF_XYZRHW flag
|
||||
DWORD color;
|
||||
FLOAT tu, tv;
|
||||
};
|
||||
|
||||
PALETTE cgapal =
|
||||
{
|
||||
{0,0,0},{0,42,0},{42,0,0},{42,21,0},
|
||||
{0,0,0},{0,42,42},{42,0,42},{42,42,42},
|
||||
{0,0,0},{21,63,21},{63,21,21},{63,63,21},
|
||||
{0,0,0},{21,63,63},{63,21,63},{63,63,63},
|
||||
|
||||
{0,0,0},{0,0,42},{0,42,0},{0,42,42},
|
||||
{42,0,0},{42,0,42},{42,21,00},{42,42,42},
|
||||
{21,21,21},{21,21,63},{21,63,21},{21,63,63},
|
||||
{63,21,21},{63,21,63},{63,63,21},{63,63,63},
|
||||
|
||||
{0,0,0},{0,21,0},{0,0,42},{0,42,42},
|
||||
{42,0,21},{21,10,21},{42,0,42},{42,0,63},
|
||||
{21,21,21},{21,63,21},{42,21,42},{21,63,63},
|
||||
{63,0,0},{42,42,0},{63,21,42},{41,41,41},
|
||||
|
||||
{0,0,0},{0,42,42},{42,0,0},{42,42,42},
|
||||
{0,0,0},{0,42,42},{42,0,0},{42,42,42},
|
||||
{0,0,0},{0,63,63},{63,0,0},{63,63,63},
|
||||
{0,0,0},{0,63,63},{63,0,0},{63,63,63},
|
||||
};
|
||||
|
||||
PALETTE cgapal_mono[6] =
|
||||
{
|
||||
{ // 0 - green, 4-color-optimized contrast
|
||||
{0x00,0x00,0x00},{0x00,0x0d,0x03},{0x01,0x17,0x05},{0x01,0x1a,0x06},{0x02,0x28,0x09},{0x02,0x2c,0x0a},{0x03,0x39,0x0d},{0x03,0x3c,0x0e},
|
||||
{0x00,0x07,0x01},{0x01,0x13,0x04},{0x01,0x1f,0x07},{0x01,0x23,0x08},{0x02,0x31,0x0b},{0x02,0x35,0x0c},{0x05,0x3f,0x11},{0x0d,0x3f,0x17},
|
||||
},
|
||||
{ // 1 - green, 16-color-optimized contrast
|
||||
{0x00,0x00,0x00},{0x00,0x0d,0x03},{0x01,0x15,0x05},{0x01,0x17,0x05},{0x01,0x21,0x08},{0x01,0x24,0x08},{0x02,0x2e,0x0b},{0x02,0x31,0x0b},
|
||||
{0x01,0x22,0x08},{0x02,0x28,0x09},{0x02,0x30,0x0b},{0x02,0x32,0x0c},{0x03,0x39,0x0d},{0x03,0x3b,0x0e},{0x09,0x3f,0x14},{0x0d,0x3f,0x17},
|
||||
},
|
||||
{ // 2 - amber, 4-color-optimized contrast
|
||||
{0x00,0x00,0x00},{0x15,0x05,0x00},{0x20,0x0b,0x00},{0x24,0x0d,0x00},{0x33,0x18,0x00},{0x37,0x1b,0x00},{0x3f,0x26,0x01},{0x3f,0x2b,0x06},
|
||||
{0x0b,0x02,0x00},{0x1b,0x08,0x00},{0x29,0x11,0x00},{0x2e,0x14,0x00},{0x3b,0x1e,0x00},{0x3e,0x21,0x00},{0x3f,0x32,0x0a},{0x3f,0x38,0x0d},
|
||||
},
|
||||
{ // 3 - amber, 16-color-optimized contrast
|
||||
{0x00,0x00,0x00},{0x15,0x05,0x00},{0x1e,0x09,0x00},{0x21,0x0b,0x00},{0x2b,0x12,0x00},{0x2f,0x15,0x00},{0x38,0x1c,0x00},{0x3b,0x1e,0x00},
|
||||
{0x2c,0x13,0x00},{0x32,0x17,0x00},{0x3a,0x1e,0x00},{0x3c,0x1f,0x00},{0x3f,0x27,0x01},{0x3f,0x2a,0x04},{0x3f,0x36,0x0c},{0x3f,0x38,0x0d},
|
||||
},
|
||||
{ // 4 - grey, 4-color-optimized contrast
|
||||
{0x00,0x00,0x00},{0x0e,0x0f,0x10},{0x15,0x17,0x18},{0x18,0x1a,0x1b},{0x24,0x25,0x25},{0x27,0x28,0x28},{0x33,0x34,0x32},{0x37,0x38,0x35},
|
||||
{0x09,0x0a,0x0b},{0x11,0x12,0x13},{0x1c,0x1e,0x1e},{0x20,0x22,0x22},{0x2c,0x2d,0x2c},{0x2f,0x30,0x2f},{0x3c,0x3c,0x38},{0x3f,0x3f,0x3b},
|
||||
},
|
||||
{ // 5 - grey, 16-color-optimized contrast
|
||||
{0x00,0x00,0x00},{0x0e,0x0f,0x10},{0x13,0x14,0x15},{0x15,0x17,0x18},{0x1e,0x20,0x20},{0x20,0x22,0x22},{0x29,0x2a,0x2a},{0x2c,0x2d,0x2c},
|
||||
{0x1f,0x21,0x21},{0x23,0x25,0x25},{0x2b,0x2c,0x2b},{0x2d,0x2e,0x2d},{0x34,0x35,0x33},{0x37,0x37,0x34},{0x3e,0x3e,0x3a},{0x3f,0x3f,0x3b},
|
||||
}
|
||||
};
|
||||
|
||||
uint32_t pal_lookup[256];
|
||||
|
||||
static CUSTOMVERTEX d3d_verts[] =
|
||||
{
|
||||
{ 0.0f, 0.0f, 1.0f, 1.0f, 0xffffff, 0.0f, 0.0f},
|
||||
{2048.0f, 2048.0f, 1.0f, 1.0f, 0xffffff, 1.0f, 1.0f},
|
||||
{ 0.0f, 2048.0f, 1.0f, 1.0f, 0xffffff, 0.0f, 1.0f},
|
||||
|
||||
{ 0.0f, 0.0f, 1.0f, 1.0f, 0xffffff, 0.0f, 0.0f},
|
||||
{2048.0f, 0.0f, 1.0f, 1.0f, 0xffffff, 1.0f, 0.0f},
|
||||
{2048.0f, 2048.0f, 1.0f, 1.0f, 0xffffff, 1.0f, 1.0f},
|
||||
|
||||
{ 0.0f, 0.0f, 1.0f, 1.0f, 0xffffff, 0.0f, 0.0f},
|
||||
{2048.0f, 2048.0f, 1.0f, 1.0f, 0xffffff, 1.0f, 1.0f},
|
||||
{ 0.0f, 2048.0f, 1.0f, 1.0f, 0xffffff, 0.0f, 1.0f},
|
||||
|
||||
{ 0.0f, 0.0f, 1.0f, 1.0f, 0xffffff, 0.0f, 0.0f},
|
||||
{2048.0f, 0.0f, 1.0f, 1.0f, 0xffffff, 1.0f, 0.0f},
|
||||
{2048.0f, 2048.0f, 1.0f, 1.0f, 0xffffff, 1.0f, 1.0f}
|
||||
};
|
||||
|
||||
|
||||
void cgapal_rebuild(void)
|
||||
{
|
||||
int c;
|
||||
for (c = 0; c < 256; c++)
|
||||
{
|
||||
pal_lookup[c] = makecol(video_6to8[cgapal[c].r], video_6to8[cgapal[c].g], video_6to8[cgapal[c].b]);
|
||||
}
|
||||
if ((cga_palette > 1) && (cga_palette < 8))
|
||||
{
|
||||
if (vid_cga_contrast != 0)
|
||||
{
|
||||
for (c = 0; c < 16; c++)
|
||||
{
|
||||
pal_lookup[c] = makecol(video_6to8[cgapal_mono[cga_palette - 2][c].r], video_6to8[cgapal_mono[cga_palette - 2][c].g], video_6to8[cgapal_mono[cga_palette - 2][c].b]);
|
||||
pal_lookup[c + 16] = makecol(video_6to8[cgapal_mono[cga_palette - 2][c].r], video_6to8[cgapal_mono[cga_palette - 2][c].g], video_6to8[cgapal_mono[cga_palette - 2][c].b]);
|
||||
pal_lookup[c + 32] = makecol(video_6to8[cgapal_mono[cga_palette - 2][c].r], video_6to8[cgapal_mono[cga_palette - 2][c].g], video_6to8[cgapal_mono[cga_palette - 2][c].b]);
|
||||
pal_lookup[c + 48] = makecol(video_6to8[cgapal_mono[cga_palette - 2][c].r], video_6to8[cgapal_mono[cga_palette - 2][c].g], video_6to8[cgapal_mono[cga_palette - 2][c].b]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (c = 0; c < 16; c++)
|
||||
{
|
||||
pal_lookup[c] = makecol(video_6to8[cgapal_mono[cga_palette - 1][c].r], video_6to8[cgapal_mono[cga_palette - 1][c].g], video_6to8[cgapal_mono[cga_palette - 1][c].b]);
|
||||
pal_lookup[c + 16] = makecol(video_6to8[cgapal_mono[cga_palette - 1][c].r], video_6to8[cgapal_mono[cga_palette - 1][c].g], video_6to8[cgapal_mono[cga_palette - 1][c].b]);
|
||||
pal_lookup[c + 32] = makecol(video_6to8[cgapal_mono[cga_palette - 1][c].r], video_6to8[cgapal_mono[cga_palette - 1][c].g], video_6to8[cgapal_mono[cga_palette - 1][c].b]);
|
||||
pal_lookup[c + 48] = makecol(video_6to8[cgapal_mono[cga_palette - 1][c].r], video_6to8[cgapal_mono[cga_palette - 1][c].g], video_6to8[cgapal_mono[cga_palette - 1][c].b]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cga_palette == 8)
|
||||
{
|
||||
pal_lookup[0x16] = makecol(video_6to8[42], video_6to8[42], video_6to8[0]);
|
||||
}
|
||||
}
|
||||
|
||||
int d3d_fs_init(HWND h)
|
||||
{
|
||||
int c;
|
||||
WCHAR emulator_title[200];
|
||||
|
||||
d3d_fs_w = GetSystemMetrics(SM_CXSCREEN);
|
||||
d3d_fs_h = GetSystemMetrics(SM_CYSCREEN);
|
||||
|
||||
for (c = 0; c < 256; c++)
|
||||
pal_lookup[c] = makecol(cgapal[c].r << 2, cgapal[c].g << 2, cgapal[c].b << 2);
|
||||
|
||||
d3d_hwnd = h;
|
||||
|
||||
/*FIXME: should be done once, in win.c */
|
||||
_swprintf(emulator_title, L"%s v%s", EMU_NAME_W, EMU_VERSION_W);
|
||||
d3d_device_window = CreateWindowEx (
|
||||
0,
|
||||
szSubClassName,
|
||||
emulator_title,
|
||||
WS_POPUP,
|
||||
CW_USEDEFAULT,
|
||||
CW_USEDEFAULT,
|
||||
640,
|
||||
480,
|
||||
HWND_DESKTOP,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
);
|
||||
|
||||
d3d = Direct3DCreate9(D3D_SDK_VERSION);
|
||||
|
||||
memset(&d3dpp, 0, sizeof(d3dpp));
|
||||
|
||||
d3dpp.Flags = 0;
|
||||
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
|
||||
d3dpp.hDeviceWindow = d3d_device_window;
|
||||
d3dpp.BackBufferCount = 1;
|
||||
d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
|
||||
d3dpp.MultiSampleQuality = 0;
|
||||
d3dpp.EnableAutoDepthStencil = false;
|
||||
d3dpp.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
|
||||
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
|
||||
d3dpp.Windowed = false;
|
||||
d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
|
||||
d3dpp.BackBufferWidth = d3d_fs_w;
|
||||
d3dpp.BackBufferHeight = d3d_fs_h;
|
||||
|
||||
if (FAILED(d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, h, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3ddev)))
|
||||
fatal("CreateDevice failed\n");
|
||||
|
||||
d3d_fs_init_objects();
|
||||
|
||||
video_blit_memtoscreen_func = d3d_fs_blit_memtoscreen;
|
||||
video_blit_memtoscreen_8_func = d3d_fs_blit_memtoscreen_8;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void d3d_fs_close_objects()
|
||||
{
|
||||
if (d3dTexture)
|
||||
{
|
||||
d3dTexture->Release();
|
||||
d3dTexture = NULL;
|
||||
}
|
||||
if (v_buffer)
|
||||
{
|
||||
v_buffer->Release();
|
||||
v_buffer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void d3d_fs_init_objects()
|
||||
{
|
||||
D3DLOCKED_RECT dr;
|
||||
int y;
|
||||
RECT r;
|
||||
|
||||
if (FAILED(d3ddev->CreateVertexBuffer(12*sizeof(CUSTOMVERTEX),
|
||||
0,
|
||||
D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1,
|
||||
D3DPOOL_MANAGED,
|
||||
&v_buffer,
|
||||
NULL)))
|
||||
fatal("CreateVertexBuffer failed\n");
|
||||
|
||||
if (FAILED(d3ddev->CreateTexture(2048, 2048, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &d3dTexture, NULL)))
|
||||
fatal("CreateTexture failed\n");
|
||||
|
||||
r.top = r.left = 0;
|
||||
r.bottom = r.right = 2047;
|
||||
|
||||
if (FAILED(d3dTexture->LockRect(0, &dr, &r, 0)))
|
||||
fatal("LockRect failed\n");
|
||||
|
||||
for (y = 0; y < 2048; y++)
|
||||
{
|
||||
uint32_t *p = (uint32_t *)((uintptr_t)dr.pBits + (y * dr.Pitch));
|
||||
memset(p, 0, 2048 * 4);
|
||||
}
|
||||
|
||||
d3dTexture->UnlockRect(0);
|
||||
|
||||
d3ddev->SetTextureStageState(0,D3DTSS_COLOROP, D3DTOP_SELECTARG1);
|
||||
d3ddev->SetTextureStageState(0,D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
d3ddev->SetTextureStageState(0,D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||
|
||||
d3ddev->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
|
||||
d3ddev->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
|
||||
}
|
||||
|
||||
/*void d3d_resize(int x, int y)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
d3dpp.BackBufferWidth = x;
|
||||
d3dpp.BackBufferHeight = y;
|
||||
|
||||
d3d_reset();
|
||||
}*/
|
||||
|
||||
void d3d_fs_reset()
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
memset(&d3dpp, 0, sizeof(d3dpp));
|
||||
|
||||
d3dpp.Flags = 0;
|
||||
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
|
||||
d3dpp.hDeviceWindow = d3d_device_window;
|
||||
d3dpp.BackBufferCount = 1;
|
||||
d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
|
||||
d3dpp.MultiSampleQuality = 0;
|
||||
d3dpp.EnableAutoDepthStencil = false;
|
||||
d3dpp.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
|
||||
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
|
||||
d3dpp.Windowed = false;
|
||||
d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
|
||||
d3dpp.BackBufferWidth = d3d_fs_w;
|
||||
d3dpp.BackBufferHeight = d3d_fs_h;
|
||||
|
||||
hr = d3ddev->Reset(&d3dpp);
|
||||
|
||||
if (hr == D3DERR_DEVICELOST)
|
||||
return;
|
||||
|
||||
d3ddev->SetTextureStageState(0,D3DTSS_COLOROP, D3DTOP_SELECTARG1);
|
||||
d3ddev->SetTextureStageState(0,D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
d3ddev->SetTextureStageState(0,D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||
|
||||
d3ddev->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
|
||||
d3ddev->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
|
||||
|
||||
device_force_redraw();
|
||||
}
|
||||
|
||||
void d3d_fs_close()
|
||||
{
|
||||
d3d_fs_close_objects();
|
||||
if (d3ddev)
|
||||
{
|
||||
d3ddev->Release();
|
||||
d3ddev = NULL;
|
||||
}
|
||||
if (d3d)
|
||||
{
|
||||
d3d->Release();
|
||||
d3d = NULL;
|
||||
}
|
||||
DestroyWindow(d3d_device_window);
|
||||
}
|
||||
|
||||
static void d3d_fs_size(RECT window_rect, double *l, double *t, double *r, double *b, int w, int h)
|
||||
{
|
||||
int ratio_w, ratio_h;
|
||||
switch (video_fullscreen_scale)
|
||||
{
|
||||
case FULLSCR_SCALE_FULL:
|
||||
*l = -0.5;
|
||||
*t = -0.5;
|
||||
*r = (window_rect.right - window_rect.left) - 0.5;
|
||||
*b = (window_rect.bottom - window_rect.top) - 0.5;
|
||||
break;
|
||||
case FULLSCR_SCALE_43:
|
||||
*t = -0.5;
|
||||
*b = (window_rect.bottom - window_rect.top) - 0.5;
|
||||
*l = ((window_rect.right - window_rect.left) / 2) - (((window_rect.bottom - window_rect.top) * 4) / (3 * 2)) - 0.5;
|
||||
*r = ((window_rect.right - window_rect.left) / 2) + (((window_rect.bottom - window_rect.top) * 4) / (3 * 2)) - 0.5;
|
||||
if (*l < -0.5)
|
||||
{
|
||||
*l = -0.5;
|
||||
*r = (window_rect.right - window_rect.left) - 0.5;
|
||||
*t = ((window_rect.bottom - window_rect.top) / 2) - (((window_rect.right - window_rect.left) * 3) / (4 * 2)) - 0.5;
|
||||
*b = ((window_rect.bottom - window_rect.top) / 2) + (((window_rect.right - window_rect.left) * 3) / (4 * 2)) - 0.5;
|
||||
}
|
||||
break;
|
||||
case FULLSCR_SCALE_SQ:
|
||||
*t = -0.5;
|
||||
*b = (window_rect.bottom - window_rect.top) - 0.5;
|
||||
*l = ((window_rect.right - window_rect.left) / 2) - (((window_rect.bottom - window_rect.top) * w) / (h * 2)) - 0.5;
|
||||
*r = ((window_rect.right - window_rect.left) / 2) + (((window_rect.bottom - window_rect.top) * w) / (h * 2)) - 0.5;
|
||||
if (*l < -0.5)
|
||||
{
|
||||
*l = -0.5;
|
||||
*r = (window_rect.right - window_rect.left) - 0.5;
|
||||
*t = ((window_rect.bottom - window_rect.top) / 2) - (((window_rect.right - window_rect.left) * h) / (w * 2)) - 0.5;
|
||||
*b = ((window_rect.bottom - window_rect.top) / 2) + (((window_rect.right - window_rect.left) * h) / (w * 2)) - 0.5;
|
||||
}
|
||||
break;
|
||||
case FULLSCR_SCALE_INT:
|
||||
ratio_w = (window_rect.right - window_rect.left) / w;
|
||||
ratio_h = (window_rect.bottom - window_rect.top) / h;
|
||||
if (ratio_h < ratio_w)
|
||||
ratio_w = ratio_h;
|
||||
*l = ((window_rect.right - window_rect.left) / 2) - ((w * ratio_w) / 2) - 0.5;
|
||||
*r = ((window_rect.right - window_rect.left) / 2) + ((w * ratio_w) / 2) - 0.5;
|
||||
*t = ((window_rect.bottom - window_rect.top) / 2) - ((h * ratio_w) / 2) - 0.5;
|
||||
*b = ((window_rect.bottom - window_rect.top) / 2) + ((h * ratio_w) / 2) - 0.5;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void d3d_fs_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h)
|
||||
{
|
||||
HRESULT hr = D3D_OK;
|
||||
VOID* pVoid;
|
||||
D3DLOCKED_RECT dr;
|
||||
RECT window_rect;
|
||||
int yy;
|
||||
double l = 0, t = 0, r = 0, b = 0;
|
||||
|
||||
if (y1 == y2)
|
||||
{
|
||||
video_blit_complete();
|
||||
return; /*Nothing to do*/
|
||||
}
|
||||
|
||||
if (hr == D3D_OK && !(y1 == 0 && y2 == 0))
|
||||
{
|
||||
RECT lock_rect;
|
||||
|
||||
lock_rect.top = y1;
|
||||
lock_rect.left = 0;
|
||||
lock_rect.bottom = y2;
|
||||
lock_rect.right = 2047;
|
||||
|
||||
hr = d3dTexture->LockRect(0, &dr, &lock_rect, 0);
|
||||
if (hr == D3D_OK)
|
||||
{
|
||||
for (yy = y1; yy < y2; yy++)
|
||||
memcpy((void *)((uintptr_t)dr.pBits + ((yy - y1) * dr.Pitch)), &(((uint32_t *)buffer32->line[yy + y])[x]), w * 4);
|
||||
|
||||
video_blit_complete();
|
||||
d3dTexture->UnlockRect(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
video_blit_complete();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
video_blit_complete();
|
||||
|
||||
d3d_verts[0].tu = d3d_verts[2].tu = d3d_verts[3].tu = 0;
|
||||
d3d_verts[0].tv = d3d_verts[3].tv = d3d_verts[4].tv = 0;
|
||||
d3d_verts[1].tu = d3d_verts[4].tu = d3d_verts[5].tu = (float)w / 2048.0;
|
||||
d3d_verts[1].tv = d3d_verts[2].tv = d3d_verts[5].tv = (float)h / 2048.0;
|
||||
d3d_verts[0].color = d3d_verts[1].color = d3d_verts[2].color =
|
||||
d3d_verts[3].color = d3d_verts[4].color = d3d_verts[5].color =
|
||||
d3d_verts[6].color = d3d_verts[7].color = d3d_verts[8].color =
|
||||
d3d_verts[9].color = d3d_verts[10].color = d3d_verts[11].color = 0xffffff;
|
||||
|
||||
GetClientRect(d3d_device_window, &window_rect);
|
||||
d3d_fs_size(window_rect, &l, &t, &r, &b, w, h);
|
||||
|
||||
d3d_verts[0].x = l;
|
||||
d3d_verts[0].y = t;
|
||||
d3d_verts[1].x = r;
|
||||
d3d_verts[1].y = b;
|
||||
d3d_verts[2].x = l;
|
||||
d3d_verts[2].y = b;
|
||||
d3d_verts[3].x = l;
|
||||
d3d_verts[3].y = t;
|
||||
d3d_verts[4].x = r;
|
||||
d3d_verts[4].y = t;
|
||||
d3d_verts[5].x = r;
|
||||
d3d_verts[5].y = b;
|
||||
d3d_verts[6].x = d3d_verts[8].x = d3d_verts[9].x = r - 40.5;
|
||||
d3d_verts[6].y = d3d_verts[9].y = d3d_verts[10].y = t + 8.5;
|
||||
d3d_verts[7].x = d3d_verts[10].x = d3d_verts[11].x = r - 8.5;
|
||||
d3d_verts[7].y = d3d_verts[8].y = d3d_verts[11].y = t + 14.5;
|
||||
|
||||
if (hr == D3D_OK)
|
||||
hr = v_buffer->Lock(0, 0, (void**)&pVoid, 0);
|
||||
if (hr == D3D_OK)
|
||||
memcpy(pVoid, d3d_verts, sizeof(d3d_verts));
|
||||
if (hr == D3D_OK)
|
||||
hr = v_buffer->Unlock();
|
||||
|
||||
if (hr == D3D_OK)
|
||||
hr = d3ddev->BeginScene();
|
||||
|
||||
if (hr == D3D_OK)
|
||||
{
|
||||
if (hr == D3D_OK)
|
||||
d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0, 0);
|
||||
|
||||
if (hr == D3D_OK)
|
||||
hr = d3ddev->SetTexture(0, d3dTexture);
|
||||
|
||||
if (hr == D3D_OK)
|
||||
hr = d3ddev->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1);
|
||||
|
||||
if (hr == D3D_OK)
|
||||
hr = d3ddev->SetStreamSource(0, v_buffer, 0, sizeof(CUSTOMVERTEX));
|
||||
|
||||
if (hr == D3D_OK)
|
||||
hr = d3ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);
|
||||
|
||||
if (hr == D3D_OK)
|
||||
hr = d3ddev->SetTexture(0, NULL);
|
||||
|
||||
if (hr == D3D_OK)
|
||||
hr = d3ddev->EndScene();
|
||||
}
|
||||
|
||||
if (hr == D3D_OK)
|
||||
hr = d3ddev->Present(NULL, NULL, d3d_device_window, NULL);
|
||||
|
||||
if (hr == D3DERR_DEVICELOST || hr == D3DERR_INVALIDCALL)
|
||||
PostMessage(ghwnd, WM_RESETD3D, 0, 0);
|
||||
}
|
||||
|
||||
static void d3d_fs_blit_memtoscreen_8(int x, int y, int w, int h)
|
||||
{
|
||||
HRESULT hr = D3D_OK;
|
||||
VOID* pVoid;
|
||||
D3DLOCKED_RECT dr;
|
||||
RECT window_rect;
|
||||
int xx, yy;
|
||||
double l = 0, t = 0, r = 0, b = 0;
|
||||
|
||||
if (!h)
|
||||
{
|
||||
video_blit_complete();
|
||||
return; /*Nothing to do*/
|
||||
}
|
||||
|
||||
if (hr == D3D_OK)
|
||||
{
|
||||
RECT lock_rect;
|
||||
|
||||
lock_rect.top = 0;
|
||||
lock_rect.left = 0;
|
||||
lock_rect.bottom = 2047;
|
||||
lock_rect.right = 2047;
|
||||
|
||||
hr = d3dTexture->LockRect(0, &dr, &lock_rect, 0);
|
||||
if (hr == D3D_OK)
|
||||
{
|
||||
for (yy = 0; yy < h; yy++)
|
||||
{
|
||||
uint32_t *p = (uint32_t *)((uintptr_t)dr.pBits + (yy * dr.Pitch));
|
||||
if ((y + yy) >= 0 && (y + yy) < buffer->h)
|
||||
{
|
||||
for (xx = 0; xx < w; xx++)
|
||||
p[xx] = pal_lookup[buffer->line[y + yy][x + xx]];
|
||||
}
|
||||
}
|
||||
video_blit_complete();
|
||||
d3dTexture->UnlockRect(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
video_blit_complete();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
video_blit_complete();
|
||||
|
||||
d3d_verts[0].tu = d3d_verts[2].tu = d3d_verts[3].tu = 0;
|
||||
d3d_verts[0].tv = d3d_verts[3].tv = d3d_verts[4].tv = 0;
|
||||
d3d_verts[1].tu = d3d_verts[4].tu = d3d_verts[5].tu = (float)w / 2048.0;
|
||||
d3d_verts[1].tv = d3d_verts[2].tv = d3d_verts[5].tv = (float)h / 2048.0;
|
||||
d3d_verts[0].color = d3d_verts[1].color = d3d_verts[2].color =
|
||||
d3d_verts[3].color = d3d_verts[4].color = d3d_verts[5].color =
|
||||
d3d_verts[6].color = d3d_verts[7].color = d3d_verts[8].color =
|
||||
d3d_verts[9].color = d3d_verts[10].color = d3d_verts[11].color = 0xffffff;
|
||||
|
||||
GetClientRect(d3d_device_window, &window_rect);
|
||||
d3d_fs_size(window_rect, &l, &t, &r, &b, w, h);
|
||||
|
||||
d3d_verts[0].x = l;
|
||||
d3d_verts[0].y = t;
|
||||
d3d_verts[1].x = r;
|
||||
d3d_verts[1].y = b;
|
||||
d3d_verts[2].x = l;
|
||||
d3d_verts[2].y = b;
|
||||
d3d_verts[3].x = l;
|
||||
d3d_verts[3].y = t;
|
||||
d3d_verts[4].x = r;
|
||||
d3d_verts[4].y = t;
|
||||
d3d_verts[5].x = r;
|
||||
d3d_verts[5].y = b;
|
||||
d3d_verts[6].x = d3d_verts[8].x = d3d_verts[9].x = r - 40.5;
|
||||
d3d_verts[6].y = d3d_verts[9].y = d3d_verts[10].y = t + 8.5;
|
||||
d3d_verts[7].x = d3d_verts[10].x = d3d_verts[11].x = r - 8.5;
|
||||
d3d_verts[7].y = d3d_verts[8].y = d3d_verts[11].y = t + 14.5;
|
||||
|
||||
if (hr == D3D_OK)
|
||||
hr = v_buffer->Lock(0, 0, (void**)&pVoid, 0);
|
||||
if (hr == D3D_OK)
|
||||
memcpy(pVoid, d3d_verts, sizeof(d3d_verts));
|
||||
if (hr == D3D_OK)
|
||||
hr = v_buffer->Unlock();
|
||||
|
||||
if (hr == D3D_OK)
|
||||
hr = d3ddev->BeginScene();
|
||||
|
||||
if (hr == D3D_OK)
|
||||
{
|
||||
if (hr == D3D_OK)
|
||||
d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0, 0);
|
||||
|
||||
if (hr == D3D_OK)
|
||||
hr = d3ddev->SetTexture(0, d3dTexture);
|
||||
|
||||
if (hr == D3D_OK)
|
||||
hr = d3ddev->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1);
|
||||
|
||||
if (hr == D3D_OK)
|
||||
hr = d3ddev->SetStreamSource(0, v_buffer, 0, sizeof(CUSTOMVERTEX));
|
||||
|
||||
if (hr == D3D_OK)
|
||||
hr = d3ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);
|
||||
|
||||
if (hr == D3D_OK)
|
||||
hr = d3ddev->SetTexture(0, NULL);
|
||||
|
||||
if (hr == D3D_OK)
|
||||
hr = d3ddev->EndScene();
|
||||
}
|
||||
|
||||
if (hr == D3D_OK)
|
||||
hr = d3ddev->Present(NULL, NULL, d3d_device_window, NULL);
|
||||
|
||||
if (hr == D3DERR_DEVICELOST || hr == D3DERR_INVALIDCALL)
|
||||
PostMessage(ghwnd, WM_RESETD3D, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
void d3d_fs_take_screenshot(wchar_t *fn)
|
||||
{
|
||||
LPDIRECT3DSURFACE9 d3dSurface = NULL;
|
||||
|
||||
if (!d3dTexture) return;
|
||||
|
||||
d3ddev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &d3dSurface);
|
||||
D3DXSaveSurfaceToFile(fn, D3DXIFF_PNG, d3dSurface, NULL, NULL);
|
||||
|
||||
d3dSurface->Release();
|
||||
d3dSurface = NULL;
|
||||
}
|
||||
286
src/win/win_ddraw.cc
Normal file
@@ -0,0 +1,286 @@
|
||||
/* Copyright holders: Sarah Walker, Tenshi
|
||||
see COPYING for more details
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include "../video/video.h"
|
||||
#include "win_ddraw.h"
|
||||
#include "win_cgapal.h"
|
||||
|
||||
|
||||
extern "C" void fatal(const char *format, ...);
|
||||
extern "C" void pclog(const char *format, ...);
|
||||
|
||||
extern "C" void device_force_redraw(void);
|
||||
|
||||
extern "C" int ddraw_init(HWND h);
|
||||
extern "C" void ddraw_close(void);
|
||||
|
||||
extern "C" void video_blit_complete(void);
|
||||
|
||||
static void ddraw_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h);
|
||||
static void ddraw_blit_memtoscreen_8(int x, int y, int w, int h);
|
||||
|
||||
static LPDIRECTDRAW lpdd = NULL;
|
||||
static LPDIRECTDRAW7 lpdd7 = NULL;
|
||||
static LPDIRECTDRAWSURFACE7 lpdds_pri = NULL;
|
||||
static LPDIRECTDRAWSURFACE7 lpdds_back = NULL;
|
||||
static LPDIRECTDRAWSURFACE7 lpdds_back2 = NULL;
|
||||
static LPDIRECTDRAWCLIPPER lpdd_clipper = NULL;
|
||||
static DDSURFACEDESC2 ddsd;
|
||||
|
||||
static HWND ddraw_hwnd;
|
||||
|
||||
int ddraw_init(HWND h)
|
||||
{
|
||||
cgapal_rebuild();
|
||||
|
||||
if (FAILED(DirectDrawCreate(NULL, &lpdd, NULL)))
|
||||
return 0;
|
||||
|
||||
if (FAILED(lpdd->QueryInterface(IID_IDirectDraw7, (LPVOID *)&lpdd7)))
|
||||
return 0;
|
||||
|
||||
lpdd->Release();
|
||||
lpdd = NULL;
|
||||
|
||||
atexit(ddraw_close);
|
||||
|
||||
if (FAILED(lpdd7->SetCooperativeLevel(h, DDSCL_NORMAL)))
|
||||
return 0;
|
||||
|
||||
memset(&ddsd, 0, sizeof(ddsd));
|
||||
ddsd.dwSize = sizeof(ddsd);
|
||||
|
||||
ddsd.dwFlags = DDSD_CAPS;
|
||||
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
|
||||
if (FAILED(lpdd7->CreateSurface(&ddsd, &lpdds_pri, NULL)))
|
||||
return 0;
|
||||
|
||||
// memset(&ddsd, 0, sizeof(ddsd));
|
||||
// ddsd.dwSize = sizeof(ddsd);
|
||||
|
||||
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
|
||||
ddsd.dwWidth = 2048;
|
||||
ddsd.dwHeight = 2048;
|
||||
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY;
|
||||
if (FAILED(lpdd7->CreateSurface(&ddsd, &lpdds_back, NULL)))
|
||||
{
|
||||
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
|
||||
ddsd.dwWidth = 2048;
|
||||
ddsd.dwHeight = 2048;
|
||||
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
|
||||
if (FAILED(lpdd7->CreateSurface(&ddsd, &lpdds_back, NULL)))
|
||||
fatal("CreateSurface back failed\n");
|
||||
}
|
||||
|
||||
memset(&ddsd, 0, sizeof(ddsd));
|
||||
ddsd.dwSize = sizeof(ddsd);
|
||||
|
||||
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
|
||||
ddsd.dwWidth = 2048;
|
||||
ddsd.dwHeight = 2048;
|
||||
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY;
|
||||
if (FAILED(lpdd7->CreateSurface(&ddsd, &lpdds_back2, NULL)))
|
||||
{
|
||||
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
|
||||
ddsd.dwWidth = 2048;
|
||||
ddsd.dwHeight = 2048;
|
||||
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
|
||||
if (FAILED(lpdd7->CreateSurface(&ddsd, &lpdds_back2, NULL)))
|
||||
fatal("CreateSurface back failed\n");
|
||||
}
|
||||
|
||||
if (FAILED(lpdd7->CreateClipper(0, &lpdd_clipper, NULL)))
|
||||
return 0;
|
||||
if (FAILED(lpdd_clipper->SetHWnd(0, h)))
|
||||
return 0;
|
||||
if (FAILED(lpdds_pri->SetClipper(lpdd_clipper)))
|
||||
return 0;
|
||||
|
||||
pclog("DDRAW_INIT complete\n");
|
||||
ddraw_hwnd = h;
|
||||
video_blit_memtoscreen_func = ddraw_blit_memtoscreen;
|
||||
video_blit_memtoscreen_8_func = ddraw_blit_memtoscreen_8;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void ddraw_close(void)
|
||||
{
|
||||
if (lpdds_back2)
|
||||
{
|
||||
lpdds_back2->Release();
|
||||
lpdds_back2 = NULL;
|
||||
}
|
||||
if (lpdds_back)
|
||||
{
|
||||
lpdds_back->Release();
|
||||
lpdds_back = NULL;
|
||||
}
|
||||
if (lpdds_pri)
|
||||
{
|
||||
lpdds_pri->Release();
|
||||
lpdds_pri = NULL;
|
||||
}
|
||||
if (lpdd_clipper)
|
||||
{
|
||||
lpdd_clipper->Release();
|
||||
lpdd_clipper = NULL;
|
||||
}
|
||||
if (lpdd7)
|
||||
{
|
||||
lpdd7->Release();
|
||||
lpdd7 = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void ddraw_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h)
|
||||
{
|
||||
RECT r_src;
|
||||
RECT r_dest;
|
||||
int yy;
|
||||
POINT po;
|
||||
HRESULT hr;
|
||||
// pclog("Blit memtoscreen %i,%i %i %i %i,%i\n", x, y, y1, y2, w, h);
|
||||
|
||||
if (lpdds_back == NULL)
|
||||
{
|
||||
video_blit_complete();
|
||||
return; /*Nothing to do*/
|
||||
}
|
||||
|
||||
if (h <= 0)
|
||||
{
|
||||
video_blit_complete();
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&ddsd, 0, sizeof(ddsd));
|
||||
ddsd.dwSize = sizeof(ddsd);
|
||||
|
||||
hr = lpdds_back->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL);
|
||||
if (hr == DDERR_SURFACELOST)
|
||||
{
|
||||
lpdds_back->Restore();
|
||||
lpdds_back->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL);
|
||||
device_force_redraw();
|
||||
}
|
||||
if (!ddsd.lpSurface)
|
||||
{
|
||||
video_blit_complete();
|
||||
return;
|
||||
}
|
||||
for (yy = y1; yy < y2; yy++)
|
||||
{
|
||||
if ((y + yy) >= 0 && (y + yy) < buffer->h)
|
||||
memcpy((uint32_t *) &(((uint8_t *) ddsd.lpSurface)[yy * ddsd.lPitch]), &(((uint32_t *)buffer32->line[y + yy])[x]), w * 4);
|
||||
}
|
||||
video_blit_complete();
|
||||
lpdds_back->Unlock(NULL);
|
||||
|
||||
po.x = po.y = 0;
|
||||
|
||||
ClientToScreen(ddraw_hwnd, &po);
|
||||
GetClientRect(ddraw_hwnd, &r_dest);
|
||||
OffsetRect(&r_dest, po.x, po.y);
|
||||
|
||||
r_src.left = 0;
|
||||
r_src.top = 0;
|
||||
r_src.right = w;
|
||||
r_src.bottom = h;
|
||||
|
||||
hr = lpdds_back2->Blt(&r_src, lpdds_back, &r_src, DDBLT_WAIT, NULL);
|
||||
if (hr == DDERR_SURFACELOST)
|
||||
{
|
||||
lpdds_back2->Restore();
|
||||
lpdds_back2->Blt(&r_src, lpdds_back, &r_src, DDBLT_WAIT, NULL);
|
||||
}
|
||||
|
||||
lpdds_back2->Unlock(NULL);
|
||||
|
||||
// pclog("Blit from %i,%i %i,%i to %i,%i %i,%i\n", r_src.left, r_src.top, r_src.right, r_src.bottom, r_dest.left, r_dest.top, r_dest.right, r_dest.bottom);
|
||||
hr = lpdds_pri->Blt(&r_dest, lpdds_back2, &r_src, DDBLT_WAIT, NULL);
|
||||
if (hr == DDERR_SURFACELOST)
|
||||
{
|
||||
lpdds_pri->Restore();
|
||||
lpdds_pri->Blt(&r_dest, lpdds_back2, &r_src, DDBLT_WAIT, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void ddraw_blit_memtoscreen_8(int x, int y, int w, int h)
|
||||
{
|
||||
RECT r_src;
|
||||
RECT r_dest;
|
||||
int xx, yy;
|
||||
POINT po;
|
||||
uint32_t *p;
|
||||
HRESULT hr;
|
||||
|
||||
if (lpdds_back == NULL)
|
||||
{
|
||||
video_blit_complete();
|
||||
return; /*Nothing to do*/
|
||||
}
|
||||
|
||||
memset(&ddsd, 0, sizeof(ddsd));
|
||||
ddsd.dwSize = sizeof(ddsd);
|
||||
|
||||
hr = lpdds_back->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL);
|
||||
|
||||
if (hr == DDERR_SURFACELOST)
|
||||
{
|
||||
lpdds_back->Restore();
|
||||
lpdds_back->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL);
|
||||
device_force_redraw();
|
||||
}
|
||||
if (!ddsd.lpSurface)
|
||||
{
|
||||
video_blit_complete();
|
||||
return;
|
||||
}
|
||||
for (yy = 0; yy < h; yy++)
|
||||
{
|
||||
if ((y + yy) >= 0 && (y + yy) < buffer->h)
|
||||
{
|
||||
p = (uint32_t *) &(((uint8_t *) ddsd.lpSurface)[yy * ddsd.lPitch]);
|
||||
for (xx = 0; xx < w; xx++)
|
||||
{
|
||||
p[xx] = pal_lookup[buffer->line[y + yy][x + xx]];
|
||||
}
|
||||
}
|
||||
}
|
||||
p = &(((uint32_t *) ddsd.lpSurface)[4 * ddsd.lPitch]);
|
||||
lpdds_back->Unlock(NULL);
|
||||
video_blit_complete();
|
||||
|
||||
po.x = po.y = 0;
|
||||
|
||||
ClientToScreen(ddraw_hwnd, &po);
|
||||
GetClientRect(ddraw_hwnd, &r_dest);
|
||||
OffsetRect(&r_dest, po.x, po.y);
|
||||
|
||||
r_src.left = 0;
|
||||
r_src.top = 0;
|
||||
r_src.right = w;
|
||||
r_src.bottom = h;
|
||||
|
||||
hr = lpdds_back2->Blt(&r_src, lpdds_back, &r_src, DDBLT_WAIT, NULL);
|
||||
if (hr == DDERR_SURFACELOST)
|
||||
{
|
||||
lpdds_back2->Restore();
|
||||
lpdds_back2->Blt(&r_src, lpdds_back, &r_src, DDBLT_WAIT, NULL);
|
||||
}
|
||||
|
||||
hr = lpdds_pri->Blt(&r_dest, lpdds_back2, &r_src, DDBLT_WAIT, NULL);
|
||||
if (hr == DDERR_SURFACELOST)
|
||||
{
|
||||
lpdds_pri->Restore();
|
||||
hr = lpdds_pri->Blt(&r_dest, lpdds_back2, &r_src, DDBLT_WAIT, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void ddraw_take_screenshot(wchar_t *fn)
|
||||
{
|
||||
ddraw_common_take_screenshot(fn, lpdds_back2);
|
||||
}
|
||||
30
src/win/win_ddraw.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/* Copyright holders: Sarah Walker, Tenshi
|
||||
see COPYING for more details
|
||||
*/
|
||||
#ifndef WIN_DDRAW_H
|
||||
# define WIN_DDRAW_H
|
||||
# define UNICODE
|
||||
# define BITMAP WINDOWS_BITMAP
|
||||
# include <ddraw.h>
|
||||
# undef BITMAP
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern int ddraw_init(HWND h);
|
||||
extern void ddraw_close(void);
|
||||
|
||||
extern int ddraw_fs_init(HWND h);
|
||||
extern void ddraw_fs_close(void);
|
||||
|
||||
extern void ddraw_common_take_screenshot(wchar_t *fn,
|
||||
IDirectDrawSurface7 *pDDSurface);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /*WIN_DDRAW_H*/
|
||||
319
src/win/win_ddraw_fs.cc
Normal file
@@ -0,0 +1,319 @@
|
||||
/* Copyright holders: Sarah Walker, Tenshi
|
||||
see COPYING for more details
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include "../video/video.h"
|
||||
#include "win_ddraw.h"
|
||||
#include "win_cgapal.h"
|
||||
|
||||
|
||||
static LPDIRECTDRAW lpdd = NULL;
|
||||
static LPDIRECTDRAW7 lpdd7 = NULL;
|
||||
static LPDIRECTDRAWSURFACE7 lpdds_pri = NULL;
|
||||
static LPDIRECTDRAWSURFACE7 lpdds_back = NULL;
|
||||
static LPDIRECTDRAWSURFACE7 lpdds_back2 = NULL;
|
||||
static LPDIRECTDRAWCLIPPER lpdd_clipper = NULL;
|
||||
static DDSURFACEDESC2 ddsd;
|
||||
static HWND ddraw_hwnd;
|
||||
static int ddraw_w, ddraw_h;
|
||||
|
||||
|
||||
extern "C" void fatal(const char *format, ...);
|
||||
extern "C" void pclog(const char *format, ...);
|
||||
|
||||
extern "C" void device_force_redraw(void);
|
||||
|
||||
extern "C" int ddraw_fs_init(HWND h);
|
||||
extern "C" void ddraw_fs_close(void);
|
||||
|
||||
extern "C" void video_blit_complete(void);
|
||||
|
||||
static void ddraw_fs_blit_memtoscreen(int, int, int, int, int, int);
|
||||
static void ddraw_fs_blit_memtoscreen_8(int, int, int, int);
|
||||
|
||||
|
||||
int ddraw_fs_init(HWND h)
|
||||
{
|
||||
ddraw_w = GetSystemMetrics(SM_CXSCREEN);
|
||||
ddraw_h = GetSystemMetrics(SM_CYSCREEN);
|
||||
|
||||
cgapal_rebuild();
|
||||
|
||||
if (FAILED(DirectDrawCreate(NULL, &lpdd, NULL)))
|
||||
return 0;
|
||||
|
||||
if (FAILED(lpdd->QueryInterface(IID_IDirectDraw7, (LPVOID *)&lpdd7)))
|
||||
return 0;
|
||||
|
||||
lpdd->Release();
|
||||
lpdd = NULL;
|
||||
|
||||
atexit(ddraw_fs_close);
|
||||
|
||||
if (FAILED(lpdd7->SetCooperativeLevel(h, DDSCL_SETFOCUSWINDOW |
|
||||
DDSCL_CREATEDEVICEWINDOW | DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_ALLOWREBOOT)))
|
||||
return 0;
|
||||
|
||||
if (FAILED(lpdd7->SetDisplayMode(ddraw_w, ddraw_h, 32, 0 ,0)))
|
||||
return 0;
|
||||
|
||||
// memset(&ddsd, 0, sizeof(ddsd));
|
||||
// ddsd.dwSize = sizeof(ddsd);
|
||||
|
||||
ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
|
||||
ddsd.dwBackBufferCount = 1;
|
||||
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP;
|
||||
if (FAILED(lpdd7->CreateSurface(&ddsd, &lpdds_pri, NULL)))
|
||||
return 0;
|
||||
|
||||
ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
|
||||
if (FAILED(lpdds_pri->GetAttachedSurface(&ddsd.ddsCaps, &lpdds_back2)))
|
||||
return 0;
|
||||
|
||||
memset(&ddsd, 0, sizeof(ddsd));
|
||||
ddsd.dwSize = sizeof(ddsd);
|
||||
|
||||
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
|
||||
ddsd.dwWidth = 2048;
|
||||
ddsd.dwHeight = 2048;
|
||||
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY;
|
||||
if (FAILED(lpdd7->CreateSurface(&ddsd, &lpdds_back, NULL)))
|
||||
{
|
||||
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
|
||||
ddsd.dwWidth = 2048;
|
||||
ddsd.dwHeight = 2048;
|
||||
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
|
||||
if (FAILED(lpdd7->CreateSurface(&ddsd, &lpdds_back, NULL)))
|
||||
return 0;
|
||||
}
|
||||
|
||||
pclog("DDRAW_INIT complete\n");
|
||||
ddraw_hwnd = h;
|
||||
video_blit_memtoscreen_func = ddraw_fs_blit_memtoscreen;
|
||||
video_blit_memtoscreen_8_func = ddraw_fs_blit_memtoscreen_8;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void ddraw_fs_close(void)
|
||||
{
|
||||
if (lpdds_back2)
|
||||
{
|
||||
lpdds_back2->Release();
|
||||
lpdds_back2 = NULL;
|
||||
}
|
||||
if (lpdds_back)
|
||||
{
|
||||
lpdds_back->Release();
|
||||
lpdds_back = NULL;
|
||||
}
|
||||
if (lpdds_pri)
|
||||
{
|
||||
lpdds_pri->Release();
|
||||
lpdds_pri = NULL;
|
||||
}
|
||||
if (lpdd_clipper)
|
||||
{
|
||||
lpdd_clipper->Release();
|
||||
lpdd_clipper = NULL;
|
||||
}
|
||||
if (lpdd7)
|
||||
{
|
||||
lpdd7->Release();
|
||||
lpdd7 = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void ddraw_fs_size(RECT window_rect, RECT *r_dest, int w, int h)
|
||||
{
|
||||
int ratio_w, ratio_h;
|
||||
switch (video_fullscreen_scale)
|
||||
{
|
||||
case FULLSCR_SCALE_FULL:
|
||||
r_dest->left = 0;
|
||||
r_dest->top = 0;
|
||||
r_dest->right = (window_rect.right - window_rect.left) - 1;
|
||||
r_dest->bottom = (window_rect.bottom - window_rect.top) - 1;
|
||||
break;
|
||||
case FULLSCR_SCALE_43:
|
||||
r_dest->top = 0;
|
||||
r_dest->bottom = (window_rect.bottom - window_rect.top) - 1;
|
||||
r_dest->left = ((window_rect.right - window_rect.left) / 2) - (((window_rect.bottom - window_rect.top) * 4) / (3 * 2));
|
||||
r_dest->right = ((window_rect.right - window_rect.left) / 2) + (((window_rect.bottom - window_rect.top) * 4) / (3 * 2)) - 1;
|
||||
if (r_dest->left < 0)
|
||||
{
|
||||
r_dest->left = 0;
|
||||
r_dest->right = (window_rect.right - window_rect.left) - 1;
|
||||
r_dest->top = ((window_rect.bottom - window_rect.top) / 2) - (((window_rect.right - window_rect.left) * 3) / (4 * 2));
|
||||
r_dest->bottom = ((window_rect.bottom - window_rect.top) / 2) + (((window_rect.right - window_rect.left) * 3) / (4 * 2)) - 1;
|
||||
}
|
||||
break;
|
||||
case FULLSCR_SCALE_SQ:
|
||||
r_dest->top = 0;
|
||||
r_dest->bottom = (window_rect.bottom - window_rect.top) - 1;
|
||||
r_dest->left = ((window_rect.right - window_rect.left) / 2) - (((window_rect.bottom - window_rect.top) * w) / (h * 2));
|
||||
r_dest->right = ((window_rect.right - window_rect.left) / 2) + (((window_rect.bottom - window_rect.top) * w) / (h * 2)) - 1;
|
||||
if (r_dest->left < 0)
|
||||
{
|
||||
r_dest->left = 0;
|
||||
r_dest->right = (window_rect.right - window_rect.left) - 1;
|
||||
r_dest->top = ((window_rect.bottom - window_rect.top) / 2) - (((window_rect.right - window_rect.left) * h) / (w * 2));
|
||||
r_dest->bottom = ((window_rect.bottom - window_rect.top) / 2) + (((window_rect.right - window_rect.left) * h) / (w * 2)) - 1;
|
||||
}
|
||||
break;
|
||||
case FULLSCR_SCALE_INT:
|
||||
ratio_w = (window_rect.right - window_rect.left) / w;
|
||||
ratio_h = (window_rect.bottom - window_rect.top) / h;
|
||||
if (ratio_h < ratio_w)
|
||||
ratio_w = ratio_h;
|
||||
r_dest->left = ((window_rect.right - window_rect.left) / 2) - ((w * ratio_w) / 2);
|
||||
r_dest->right = ((window_rect.right - window_rect.left) / 2) + ((w * ratio_w) / 2) - 1;
|
||||
r_dest->top = ((window_rect.bottom - window_rect.top) / 2) - ((h * ratio_w) / 2);
|
||||
r_dest->bottom = ((window_rect.bottom - window_rect.top) / 2) + ((h * ratio_w) / 2) - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void ddraw_fs_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h)
|
||||
{
|
||||
RECT r_src;
|
||||
RECT r_dest;
|
||||
RECT window_rect;
|
||||
int yy;
|
||||
HRESULT hr;
|
||||
DDBLTFX ddbltfx;
|
||||
|
||||
if (lpdds_back == NULL)
|
||||
{
|
||||
video_blit_complete();
|
||||
return; /*Nothing to do*/
|
||||
}
|
||||
|
||||
memset(&ddsd, 0, sizeof(ddsd));
|
||||
ddsd.dwSize = sizeof(ddsd);
|
||||
|
||||
hr = lpdds_back->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL);
|
||||
if (hr == DDERR_SURFACELOST)
|
||||
{
|
||||
lpdds_back->Restore();
|
||||
lpdds_back->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL);
|
||||
device_force_redraw();
|
||||
}
|
||||
if (!ddsd.lpSurface)
|
||||
{
|
||||
video_blit_complete();
|
||||
return;
|
||||
}
|
||||
for (yy = y1; yy < y2; yy++)
|
||||
{
|
||||
if ((y + yy) >= 0) memcpy((unsigned char*)ddsd.lpSurface + (yy * ddsd.lPitch), &(((uint32_t *)buffer32->line[y + yy])[x]), w * 4);
|
||||
}
|
||||
video_blit_complete();
|
||||
lpdds_back->Unlock(NULL);
|
||||
|
||||
window_rect.left = 0;
|
||||
window_rect.top = 0;
|
||||
window_rect.right = ddraw_w;
|
||||
window_rect.bottom = ddraw_h;
|
||||
ddraw_fs_size(window_rect, &r_dest, w, h);
|
||||
|
||||
r_src.left = 0;
|
||||
r_src.top = 0;
|
||||
r_src.right = w;
|
||||
r_src.bottom = h;
|
||||
|
||||
ddbltfx.dwSize = sizeof(ddbltfx);
|
||||
ddbltfx.dwFillColor = 0;
|
||||
|
||||
lpdds_back2->Blt(&window_rect, NULL, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &ddbltfx);
|
||||
|
||||
hr = lpdds_back2->Blt(&r_dest, lpdds_back, &r_src, DDBLT_WAIT, NULL);
|
||||
if (hr == DDERR_SURFACELOST)
|
||||
{
|
||||
lpdds_back2->Restore();
|
||||
lpdds_back2->Blt(&r_dest, lpdds_back, &r_src, DDBLT_WAIT, NULL);
|
||||
}
|
||||
|
||||
hr = lpdds_pri->Flip(NULL, DDFLIP_NOVSYNC);
|
||||
if (hr == DDERR_SURFACELOST)
|
||||
{
|
||||
lpdds_pri->Restore();
|
||||
lpdds_pri->Flip(NULL, DDFLIP_NOVSYNC);
|
||||
}
|
||||
}
|
||||
|
||||
static void ddraw_fs_blit_memtoscreen_8(int x, int y, int w, int h)
|
||||
{
|
||||
RECT r_src;
|
||||
RECT r_dest;
|
||||
RECT window_rect;
|
||||
int xx, yy;
|
||||
HRESULT hr;
|
||||
DDBLTFX ddbltfx;
|
||||
|
||||
if (lpdds_back == NULL)
|
||||
{
|
||||
video_blit_complete();
|
||||
return; /*Nothing to do*/
|
||||
}
|
||||
|
||||
memset(&ddsd, 0, sizeof(ddsd));
|
||||
ddsd.dwSize = sizeof(ddsd);
|
||||
|
||||
hr = lpdds_back->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL);
|
||||
|
||||
if (hr == DDERR_SURFACELOST)
|
||||
{
|
||||
lpdds_back->Restore();
|
||||
lpdds_back->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL);
|
||||
device_force_redraw();
|
||||
}
|
||||
if (!ddsd.lpSurface)
|
||||
{
|
||||
video_blit_complete();
|
||||
return;
|
||||
}
|
||||
for (yy = 0; yy < h; yy++)
|
||||
{
|
||||
if ((y + yy) >= 0 && (y + yy) < buffer->h)
|
||||
{
|
||||
uint32_t *p = (uint32_t *) &(((uint8_t *) ddsd.lpSurface)[yy * ddsd.lPitch]);
|
||||
for (xx = 0; xx < w; xx++)
|
||||
{
|
||||
p[xx] = pal_lookup[buffer->line[y + yy][x + xx]];
|
||||
}
|
||||
}
|
||||
}
|
||||
video_blit_complete();
|
||||
lpdds_back->Unlock(NULL);
|
||||
|
||||
window_rect.left = 0;
|
||||
window_rect.top = 0;
|
||||
window_rect.right = ddraw_w;
|
||||
window_rect.bottom = ddraw_h;
|
||||
ddraw_fs_size(window_rect, &r_dest, w, h);
|
||||
|
||||
r_src.left = 0;
|
||||
r_src.top = 0;
|
||||
r_src.right = w;
|
||||
r_src.bottom = h;
|
||||
|
||||
ddbltfx.dwSize = sizeof(ddbltfx);
|
||||
ddbltfx.dwFillColor = 0;
|
||||
|
||||
lpdds_back2->Blt(&window_rect, NULL, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &ddbltfx);
|
||||
|
||||
hr = lpdds_back2->Blt(&r_dest, lpdds_back, &r_src, DDBLT_WAIT, NULL);
|
||||
if (hr == DDERR_SURFACELOST)
|
||||
{
|
||||
lpdds_back2->Restore();
|
||||
lpdds_back2->Blt(&r_dest, lpdds_back, &r_src, DDBLT_WAIT, NULL);
|
||||
}
|
||||
|
||||
lpdds_pri->Flip(NULL, DDFLIP_NOVSYNC);
|
||||
}
|
||||
|
||||
void ddraw_fs_take_screenshot(wchar_t *fn)
|
||||
{
|
||||
ddraw_common_take_screenshot(fn, lpdds_back2);
|
||||
}
|
||||
187
src/win/win_ddraw_screenshot.cc
Normal file
@@ -0,0 +1,187 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* DirectDraw screenshot taking code.
|
||||
*
|
||||
* Version: @(#)win_ddraw_screenshot.cc 1.0.1 2017/08/23
|
||||
*
|
||||
* Author: Miran Grca, <mgrca8@gmail.com>
|
||||
* Copyright 2016,2017 Miran Grca.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#define UNICODE
|
||||
#define BITMAP WINDOWS_BITMAP
|
||||
#include <windows.h>
|
||||
#undef BITMAP
|
||||
#include "../video/video.h"
|
||||
#include "win.h"
|
||||
#include "win_ddraw.h"
|
||||
#include "win_language.h"
|
||||
|
||||
|
||||
HBITMAP hbitmap;
|
||||
int xs, ys, ys2;
|
||||
|
||||
|
||||
extern "C" void pclog(const char *format, ...);
|
||||
|
||||
|
||||
void CopySurface(IDirectDrawSurface7 *pDDSurface)
|
||||
{
|
||||
HDC hdc, hmemdc;
|
||||
|
||||
HBITMAP hprevbitmap;
|
||||
|
||||
DDSURFACEDESC2 ddsd2;
|
||||
|
||||
pDDSurface->GetDC(&hdc);
|
||||
|
||||
hmemdc = CreateCompatibleDC(hdc);
|
||||
|
||||
ZeroMemory(&ddsd2 ,sizeof( ddsd2 )); // better to clear before using
|
||||
|
||||
ddsd2.dwSize = sizeof( ddsd2 ); //initialize with size
|
||||
|
||||
pDDSurface->GetSurfaceDesc(&ddsd2);
|
||||
|
||||
hbitmap = CreateCompatibleBitmap( hdc ,xs ,ys);
|
||||
|
||||
hprevbitmap = (HBITMAP) SelectObject( hmemdc, hbitmap );
|
||||
|
||||
BitBlt(hmemdc,0 ,0 ,xs ,ys ,hdc ,0 ,0,SRCCOPY);
|
||||
|
||||
SelectObject(hmemdc,hprevbitmap); // restore the old bitmap
|
||||
|
||||
DeleteDC(hmemdc);
|
||||
|
||||
pDDSurface->ReleaseDC(hdc);
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
|
||||
void DoubleLines(uint8_t *dst, uint8_t *src)
|
||||
{
|
||||
int i = 0;
|
||||
for (i = 0; i < ys; i++)
|
||||
{
|
||||
memcpy(dst + (i * xs * 8), src + (i * xs * 4), xs * 4);
|
||||
memcpy(dst + ((i * xs * 8) + (xs * 4)), src + (i * xs * 4), xs * 4);
|
||||
}
|
||||
}
|
||||
|
||||
static WCHAR szMessage[2048];
|
||||
|
||||
void SaveBitmap(wchar_t *szFilename,HBITMAP hBitmap)
|
||||
{
|
||||
HDC hdc=NULL;
|
||||
FILE* fp=NULL;
|
||||
LPVOID pBuf=NULL;
|
||||
LPVOID pBuf2=NULL;
|
||||
BITMAPINFO bmpInfo;
|
||||
BITMAPFILEHEADER bmpFileHeader;
|
||||
|
||||
do{
|
||||
|
||||
hdc=GetDC(NULL);
|
||||
|
||||
ZeroMemory(&bmpInfo,sizeof(BITMAPINFO));
|
||||
|
||||
bmpInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
|
||||
|
||||
GetDIBits(hdc,hBitmap,0,0,NULL,&bmpInfo,DIB_RGB_COLORS);
|
||||
|
||||
if(bmpInfo.bmiHeader.biSizeImage<=0)
|
||||
bmpInfo.bmiHeader.biSizeImage=bmpInfo.bmiHeader.biWidth*abs(bmpInfo.bmiHeader.biHeight)*(bmpInfo.bmiHeader.biBitCount+7)/8;
|
||||
|
||||
if((pBuf = malloc(bmpInfo.bmiHeader.biSizeImage))==NULL)
|
||||
{
|
||||
// pclog("ERROR: Unable to Allocate Bitmap Memory");
|
||||
break;
|
||||
}
|
||||
|
||||
if (ys2 <= 250)
|
||||
{
|
||||
pBuf2 = malloc(bmpInfo.bmiHeader.biSizeImage * 2);
|
||||
}
|
||||
|
||||
bmpInfo.bmiHeader.biCompression=BI_RGB;
|
||||
|
||||
GetDIBits(hdc,hBitmap,0,bmpInfo.bmiHeader.biHeight,pBuf, &bmpInfo, DIB_RGB_COLORS);
|
||||
|
||||
if((fp = _wfopen(szFilename,L"wb"))==NULL)
|
||||
{
|
||||
_swprintf(szMessage, win_language_get_string_from_id(IDS_2073), szFilename);
|
||||
msgbox_error_wstr(ghwnd, szMessage);
|
||||
break;
|
||||
}
|
||||
|
||||
bmpFileHeader.bfReserved1=0;
|
||||
|
||||
bmpFileHeader.bfReserved2=0;
|
||||
|
||||
if (pBuf2)
|
||||
{
|
||||
bmpInfo.bmiHeader.biSizeImage <<= 1;
|
||||
bmpInfo.bmiHeader.biHeight <<= 1;
|
||||
}
|
||||
|
||||
bmpFileHeader.bfSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+bmpInfo.bmiHeader.biSizeImage;
|
||||
|
||||
bmpFileHeader.bfType=0x4D42;
|
||||
|
||||
bmpFileHeader.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
|
||||
|
||||
fwrite(&bmpFileHeader,sizeof(BITMAPFILEHEADER),1,fp);
|
||||
|
||||
fwrite(&bmpInfo.bmiHeader,sizeof(BITMAPINFOHEADER),1,fp);
|
||||
|
||||
if (pBuf2)
|
||||
{
|
||||
DoubleLines((uint8_t *) pBuf2, (uint8_t *) pBuf);
|
||||
fwrite(pBuf2,bmpInfo.bmiHeader.biSizeImage,1,fp);
|
||||
}
|
||||
else
|
||||
{
|
||||
fwrite(pBuf,bmpInfo.bmiHeader.biSizeImage,1,fp);
|
||||
}
|
||||
|
||||
}while(false);
|
||||
|
||||
if(hdc) ReleaseDC(NULL,hdc);
|
||||
|
||||
if(pBuf2) free(pBuf2);
|
||||
|
||||
if(pBuf) free(pBuf);
|
||||
|
||||
if(fp) fclose(fp);
|
||||
}
|
||||
|
||||
void ddraw_common_take_screenshot(wchar_t *fn, IDirectDrawSurface7 *pDDSurface)
|
||||
{
|
||||
xs = xsize;
|
||||
ys = ys2 = ysize;
|
||||
/* For EGA/(S)VGA, the size is NOT adjusted for overscan. */
|
||||
if ((overscan_y > 16) && enable_overscan)
|
||||
{
|
||||
xs += overscan_x;
|
||||
ys += overscan_y;
|
||||
}
|
||||
/* For CGA, the width is adjusted for overscan, but the height is not. */
|
||||
if (overscan_y == 16)
|
||||
{
|
||||
if (ys2 <= 250)
|
||||
ys += (overscan_y >> 1);
|
||||
else
|
||||
ys += overscan_y;
|
||||
}
|
||||
CopySurface(pDDSurface);
|
||||
SaveBitmap(fn, hbitmap);
|
||||
}
|
||||
719
src/win/win_deviceconfig.c
Normal file
@@ -0,0 +1,719 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Windows device configuration dialog implementation.
|
||||
*
|
||||
* Version: @(#)win_deviceconfig.c 1.0.1 2017/06/19
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Copyright 2008-2017 Sarah Walker.
|
||||
* Copyright 2016-2017 Miran Grca.
|
||||
*/
|
||||
#include "../ibm.h"
|
||||
#include "../config.h"
|
||||
#include "../device.h"
|
||||
#include "plat_midi.h"
|
||||
#define NO_UNICODE /*FIXME: not Unicode? */
|
||||
#include "win.h"
|
||||
#include "win_language.h"
|
||||
#include <windowsx.h>
|
||||
|
||||
|
||||
static device_t *config_device;
|
||||
|
||||
|
||||
static BOOL CALLBACK deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
HWND h;
|
||||
|
||||
int val_int;
|
||||
int ret;
|
||||
int id;
|
||||
int c;
|
||||
int num;
|
||||
int changed;
|
||||
int cid;
|
||||
device_config_t *config;
|
||||
char s[80];
|
||||
wchar_t ws[512];
|
||||
|
||||
switch (message)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
id = IDC_CONFIG_BASE;
|
||||
config = config_device->config;
|
||||
|
||||
while (config->type != -1)
|
||||
{
|
||||
device_config_selection_t *selection = config->selection;
|
||||
h = GetDlgItem(hdlg, id);
|
||||
|
||||
switch (config->type)
|
||||
{
|
||||
case CONFIG_BINARY:
|
||||
val_int = config_get_int(config_device->name, config->name, config->default_int);
|
||||
|
||||
SendMessage(h, BM_SETCHECK, val_int, 0);
|
||||
|
||||
id++;
|
||||
break;
|
||||
|
||||
case CONFIG_SELECTION:
|
||||
val_int = config_get_int(config_device->name, config->name, config->default_int);
|
||||
|
||||
c = 0;
|
||||
while (selection->description[0])
|
||||
{
|
||||
SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)selection->description);
|
||||
if (val_int == selection->value)
|
||||
SendMessage(h, CB_SETCURSEL, c, 0);
|
||||
selection++;
|
||||
c++;
|
||||
}
|
||||
|
||||
id += 2;
|
||||
break;
|
||||
|
||||
case CONFIG_MIDI:
|
||||
val_int = config_get_int(config_device->name, config->name, config->default_int);
|
||||
|
||||
num = plat_midi_get_num_devs();
|
||||
for (c = 0; c < num; c++)
|
||||
{
|
||||
plat_midi_get_dev_name(c, s);
|
||||
SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)s);
|
||||
if (val_int == c)
|
||||
SendMessage(h, CB_SETCURSEL, c, 0);
|
||||
}
|
||||
|
||||
id += 2;
|
||||
break;
|
||||
|
||||
case CONFIG_SPINNER:
|
||||
val_int = config_get_int(config_device->name, config->name, config->default_int);
|
||||
|
||||
sprintf(s, "%i", val_int);
|
||||
SendMessage(h, WM_SETTEXT, 0, (LPARAM)s);
|
||||
|
||||
id += 2;
|
||||
break;
|
||||
|
||||
case CONFIG_FILE:
|
||||
{
|
||||
char* str = config_get_string(config_device->name, config->name, 0);
|
||||
if (str)
|
||||
SendMessage(h, WM_SETTEXT, 0, (LPARAM)str);
|
||||
id += 3;
|
||||
}
|
||||
break;
|
||||
|
||||
case CONFIG_HEX16:
|
||||
val_int = config_get_hex16(config_device->name, config->name, config->default_int);
|
||||
|
||||
c = 0;
|
||||
while (selection->description[0])
|
||||
{
|
||||
SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)selection->description);
|
||||
if (val_int == selection->value)
|
||||
SendMessage(h, CB_SETCURSEL, c, 0);
|
||||
selection++;
|
||||
c++;
|
||||
}
|
||||
|
||||
id += 2;
|
||||
break;
|
||||
|
||||
case CONFIG_HEX20:
|
||||
val_int = config_get_hex20(config_device->name, config->name, config->default_int);
|
||||
|
||||
c = 0;
|
||||
while (selection->description[0])
|
||||
{
|
||||
SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)selection->description);
|
||||
if (val_int == selection->value)
|
||||
SendMessage(h, CB_SETCURSEL, c, 0);
|
||||
selection++;
|
||||
c++;
|
||||
}
|
||||
|
||||
id += 2;
|
||||
break;
|
||||
}
|
||||
config++;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
|
||||
case WM_COMMAND:
|
||||
{
|
||||
cid = LOWORD(wParam);
|
||||
if (cid == IDOK)
|
||||
{
|
||||
id = IDC_CONFIG_BASE;
|
||||
config = config_device->config;
|
||||
changed = 0;
|
||||
char s[512];
|
||||
|
||||
while (config->type != -1)
|
||||
{
|
||||
device_config_selection_t *selection = config->selection;
|
||||
h = GetDlgItem(hdlg, id);
|
||||
|
||||
switch (config->type)
|
||||
{
|
||||
case CONFIG_BINARY:
|
||||
val_int = config_get_int(config_device->name, config->name, config->default_int);
|
||||
|
||||
if (val_int != SendMessage(h, BM_GETCHECK, 0, 0))
|
||||
changed = 1;
|
||||
|
||||
id++;
|
||||
break;
|
||||
|
||||
case CONFIG_SELECTION:
|
||||
val_int = config_get_int(config_device->name, config->name, config->default_int);
|
||||
|
||||
c = SendMessage(h, CB_GETCURSEL, 0, 0);
|
||||
|
||||
for (; c > 0; c--)
|
||||
selection++;
|
||||
|
||||
if (val_int != selection->value)
|
||||
changed = 1;
|
||||
|
||||
id += 2;
|
||||
break;
|
||||
|
||||
case CONFIG_MIDI:
|
||||
val_int = config_get_int(config_device->name, config->name, config->default_int);
|
||||
|
||||
c = SendMessage(h, CB_GETCURSEL, 0, 0);
|
||||
|
||||
if (val_int != c)
|
||||
changed = 1;
|
||||
|
||||
id += 2;
|
||||
break;
|
||||
|
||||
case CONFIG_FILE:
|
||||
{
|
||||
char* str = config_get_string(config_device->name, config->name, (char*)"");
|
||||
SendMessage(h, WM_GETTEXT, 511, (LPARAM)s);
|
||||
if (strcmp(str, s))
|
||||
changed = 1;
|
||||
|
||||
id += 3;
|
||||
}
|
||||
break;
|
||||
|
||||
case CONFIG_SPINNER:
|
||||
val_int = config_get_int(config_device->name, config->name, config->default_int);
|
||||
if (val_int > config->spinner.max)
|
||||
val_int = config->spinner.max;
|
||||
else if (val_int < config->spinner.min)
|
||||
val_int = config->spinner.min;
|
||||
|
||||
SendMessage(h, WM_GETTEXT, 79, (LPARAM)s);
|
||||
sscanf(s, "%i", &c);
|
||||
|
||||
if (val_int != c)
|
||||
changed = 1;
|
||||
|
||||
id += 2;
|
||||
break;
|
||||
|
||||
case CONFIG_HEX16:
|
||||
val_int = config_get_hex16(config_device->name, config->name, config->default_int);
|
||||
|
||||
c = SendMessage(h, CB_GETCURSEL, 0, 0);
|
||||
|
||||
for (; c > 0; c--)
|
||||
selection++;
|
||||
|
||||
if (val_int != selection->value)
|
||||
changed = 1;
|
||||
|
||||
id += 2;
|
||||
break;
|
||||
|
||||
case CONFIG_HEX20:
|
||||
val_int = config_get_hex20(config_device->name, config->name, config->default_int);
|
||||
|
||||
c = SendMessage(h, CB_GETCURSEL, 0, 0);
|
||||
|
||||
for (; c > 0; c--)
|
||||
selection++;
|
||||
|
||||
if (val_int != selection->value)
|
||||
changed = 1;
|
||||
|
||||
id += 2;
|
||||
break;
|
||||
}
|
||||
config++;
|
||||
}
|
||||
|
||||
if (!changed)
|
||||
{
|
||||
EndDialog(hdlg, 0);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
ret = msgbox_reset(ghwnd);
|
||||
switch(ret)
|
||||
{
|
||||
case IDNO:
|
||||
EndDialog(hdlg, 0);
|
||||
return TRUE;
|
||||
case IDCANCEL:
|
||||
return FALSE;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
id = IDC_CONFIG_BASE;
|
||||
config = config_device->config;
|
||||
|
||||
while (config->type != -1)
|
||||
{
|
||||
device_config_selection_t *selection = config->selection;
|
||||
h = GetDlgItem(hdlg, id);
|
||||
|
||||
switch (config->type)
|
||||
{
|
||||
case CONFIG_BINARY:
|
||||
config_set_int(config_device->name, config->name, SendMessage(h, BM_GETCHECK, 0, 0));
|
||||
|
||||
id++;
|
||||
break;
|
||||
|
||||
case CONFIG_SELECTION:
|
||||
c = SendMessage(h, CB_GETCURSEL, 0, 0);
|
||||
for (; c > 0; c--)
|
||||
selection++;
|
||||
config_set_int(config_device->name, config->name, selection->value);
|
||||
|
||||
id += 2;
|
||||
break;
|
||||
|
||||
case CONFIG_MIDI:
|
||||
c = SendMessage(h, CB_GETCURSEL, 0, 0);
|
||||
config_set_int(config_device->name, config->name, c);
|
||||
|
||||
id += 2;
|
||||
break;
|
||||
|
||||
case CONFIG_FILE:
|
||||
SendMessage(h, WM_GETTEXT, 511, (LPARAM)s);
|
||||
|
||||
config_set_string(config_device->name, config->name, s);
|
||||
|
||||
id += 3;
|
||||
break;
|
||||
|
||||
case CONFIG_SPINNER:
|
||||
SendMessage(h, WM_GETTEXT, 79, (LPARAM)s);
|
||||
sscanf(s, "%i", &c);
|
||||
if (c > config->spinner.max)
|
||||
c = config->spinner.max;
|
||||
else if (c < config->spinner.min)
|
||||
c = config->spinner.min;
|
||||
|
||||
config_set_int(config_device->name, config->name, c);
|
||||
|
||||
id += 2;
|
||||
break;
|
||||
|
||||
case CONFIG_HEX16:
|
||||
c = SendMessage(h, CB_GETCURSEL, 0, 0);
|
||||
for (; c > 0; c--)
|
||||
selection++;
|
||||
config_set_hex16(config_device->name, config->name, selection->value);
|
||||
|
||||
id += 2;
|
||||
break;
|
||||
|
||||
case CONFIG_HEX20:
|
||||
c = SendMessage(h, CB_GETCURSEL, 0, 0);
|
||||
for (; c > 0; c--)
|
||||
selection++;
|
||||
config_set_hex20(config_device->name, config->name, selection->value);
|
||||
|
||||
id += 2;
|
||||
break;
|
||||
}
|
||||
config++;
|
||||
}
|
||||
|
||||
saveconfig();
|
||||
|
||||
resetpchard();
|
||||
|
||||
EndDialog(hdlg, 0);
|
||||
return TRUE;
|
||||
}
|
||||
else if (cid == IDCANCEL)
|
||||
{
|
||||
EndDialog(hdlg, 0);
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
int id = IDC_CONFIG_BASE;
|
||||
device_config_t *config = config_device->config;
|
||||
|
||||
while (config->type != -1)
|
||||
{
|
||||
switch (config->type)
|
||||
{
|
||||
case CONFIG_BINARY:
|
||||
id++;
|
||||
break;
|
||||
|
||||
case CONFIG_SELECTION:
|
||||
case CONFIG_MIDI:
|
||||
case CONFIG_SPINNER:
|
||||
id += 2;
|
||||
break;
|
||||
|
||||
case CONFIG_FILE:
|
||||
{
|
||||
if (cid == id+1)
|
||||
{
|
||||
char s[512];
|
||||
s[0] = 0;
|
||||
int c, d;
|
||||
HWND h = GetDlgItem(hdlg, id);
|
||||
SendMessage(h, WM_GETTEXT, 511, (LPARAM)s);
|
||||
char file_filter[512];
|
||||
file_filter[0] = 0;
|
||||
|
||||
c = 0;
|
||||
while (config->file_filter[c].description[0])
|
||||
{
|
||||
if (c > 0)
|
||||
strcat(file_filter, "|");
|
||||
strcat(file_filter, config->file_filter[c].description);
|
||||
strcat(file_filter, " (");
|
||||
d = 0;
|
||||
while (config->file_filter[c].extensions[d][0])
|
||||
{
|
||||
if (d > 0)
|
||||
strcat(file_filter, ";");
|
||||
strcat(file_filter, "*.");
|
||||
strcat(file_filter, config->file_filter[c].extensions[d]);
|
||||
d++;
|
||||
}
|
||||
strcat(file_filter, ")|");
|
||||
d = 0;
|
||||
while (config->file_filter[c].extensions[d][0])
|
||||
{
|
||||
if (d > 0)
|
||||
strcat(file_filter, ";");
|
||||
strcat(file_filter, "*.");
|
||||
strcat(file_filter, config->file_filter[c].extensions[d]);
|
||||
d++;
|
||||
}
|
||||
c++;
|
||||
}
|
||||
strcat(file_filter, "|All files (*.*)|*.*|");
|
||||
mbstowcs(ws, file_filter, strlen(file_filter) + 1);
|
||||
d = strlen(file_filter);
|
||||
|
||||
/* replace | with \0 */
|
||||
for (c = 0; c < d; ++c)
|
||||
if (ws[c] == L'|')
|
||||
ws[c] = 0;
|
||||
|
||||
if (!file_dlg(hdlg, ws, s, 0))
|
||||
SendMessage(h, WM_SETTEXT, 0, (LPARAM)openfilestring);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
config++;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void deviceconfig_open(HWND hwnd, device_t *device)
|
||||
{
|
||||
device_config_t *config = device->config;
|
||||
uint16_t *data_block = malloc(16384);
|
||||
uint16_t *data;
|
||||
DLGTEMPLATE *dlg = (DLGTEMPLATE *)data_block;
|
||||
DLGITEMTEMPLATE *item;
|
||||
int y = 10;
|
||||
int id = IDC_CONFIG_BASE;
|
||||
|
||||
memset(data_block, 0, 4096);
|
||||
|
||||
dlg->style = DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU;
|
||||
dlg->x = 10;
|
||||
dlg->y = 10;
|
||||
dlg->cx = 220;
|
||||
dlg->cy = 70;
|
||||
|
||||
data = (uint16_t *)(dlg + 1);
|
||||
|
||||
*data++ = 0; /*no menu*/
|
||||
*data++ = 0; /*predefined dialog box class*/
|
||||
data += MultiByteToWideChar(CP_ACP, 0, "Device Configuration", -1, data, 50);
|
||||
|
||||
*data++ = 9; /*Point*/
|
||||
data += MultiByteToWideChar(CP_ACP, 0, "Segoe UI", -1, data, 50);
|
||||
|
||||
if (((unsigned long)data) & 2)
|
||||
data++;
|
||||
|
||||
while (config->type != -1)
|
||||
{
|
||||
switch (config->type)
|
||||
{
|
||||
case CONFIG_BINARY:
|
||||
item = (DLGITEMTEMPLATE *)data;
|
||||
item->x = 10;
|
||||
item->y = y;
|
||||
item->id = id++;
|
||||
|
||||
item->cx = 80;
|
||||
item->cy = 15;
|
||||
|
||||
item->style = WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX;
|
||||
|
||||
data = (uint16_t *)(item + 1);
|
||||
*data++ = 0xFFFF;
|
||||
*data++ = 0x0080; /* button class */
|
||||
|
||||
data += MultiByteToWideChar(CP_ACP, 0, config->description, -1, data, 256);
|
||||
*data++ = 0; /* no creation data */
|
||||
|
||||
y += 20;
|
||||
break;
|
||||
|
||||
case CONFIG_SELECTION:
|
||||
case CONFIG_MIDI:
|
||||
case CONFIG_HEX16:
|
||||
case CONFIG_HEX20:
|
||||
/*Combo box*/
|
||||
item = (DLGITEMTEMPLATE *)data;
|
||||
item->x = 70;
|
||||
item->y = y;
|
||||
item->id = id++;
|
||||
|
||||
item->cx = 140;
|
||||
item->cy = 150;
|
||||
|
||||
item->style = WS_CHILD | WS_VISIBLE | CBS_DROPDOWN | WS_VSCROLL;
|
||||
|
||||
data = (uint16_t *)(item + 1);
|
||||
*data++ = 0xFFFF;
|
||||
*data++ = 0x0085; /* combo box class */
|
||||
|
||||
data += MultiByteToWideChar(CP_ACP, 0, config->description, -1, data, 256);
|
||||
*data++ = 0; /* no creation data */
|
||||
|
||||
if (((unsigned long)data) & 2)
|
||||
data++;
|
||||
|
||||
/*Static text*/
|
||||
item = (DLGITEMTEMPLATE *)data;
|
||||
item->x = 10;
|
||||
item->y = y;
|
||||
item->id = id++;
|
||||
|
||||
item->cx = 60;
|
||||
item->cy = 15;
|
||||
|
||||
item->style = WS_CHILD | WS_VISIBLE;
|
||||
|
||||
data = (uint16_t *)(item + 1);
|
||||
*data++ = 0xFFFF;
|
||||
*data++ = 0x0082; /* static class */
|
||||
|
||||
data += MultiByteToWideChar(CP_ACP, 0, config->description, -1, data, 256);
|
||||
*data++ = 0; /* no creation data */
|
||||
|
||||
if (((unsigned long)data) & 2)
|
||||
data++;
|
||||
|
||||
y += 20;
|
||||
break;
|
||||
|
||||
case CONFIG_SPINNER:
|
||||
/*Spinner*/
|
||||
item = (DLGITEMTEMPLATE *)data;
|
||||
item->x = 70;
|
||||
item->y = y;
|
||||
item->id = id++;
|
||||
|
||||
item->cx = 140;
|
||||
item->cy = 14;
|
||||
|
||||
item->style = WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL | ES_NUMBER;
|
||||
item->dwExtendedStyle = WS_EX_CLIENTEDGE;
|
||||
|
||||
data = (uint16_t *)(item + 1);
|
||||
*data++ = 0xFFFF;
|
||||
*data++ = 0x0081; /* edit text class */
|
||||
|
||||
data += MultiByteToWideChar(CP_ACP, 0, "", -1, data, 256);
|
||||
*data++ = 0; /* no creation data */
|
||||
|
||||
if (((uintptr_t)data) & 2)
|
||||
data++;
|
||||
|
||||
/* TODO: add up down class */
|
||||
/*Static text*/
|
||||
item = (DLGITEMTEMPLATE *)data;
|
||||
item->x = 10;
|
||||
item->y = y;
|
||||
item->id = id++;
|
||||
|
||||
item->cx = 60;
|
||||
item->cy = 15;
|
||||
|
||||
item->style = WS_CHILD | WS_VISIBLE;
|
||||
|
||||
data = (uint16_t *)(item + 1);
|
||||
*data++ = 0xFFFF;
|
||||
*data++ = 0x0082; /* static class */
|
||||
|
||||
data += MultiByteToWideChar(CP_ACP, 0, config->description, -1, data, 256);
|
||||
*data++ = 0; /* no creation data */
|
||||
|
||||
if (((uintptr_t)data) & 2)
|
||||
data++;
|
||||
|
||||
y += 20;
|
||||
break;
|
||||
|
||||
case CONFIG_FILE:
|
||||
/*File*/
|
||||
item = (DLGITEMTEMPLATE *)data;
|
||||
item->x = 70;
|
||||
item->y = y;
|
||||
item->id = id++;
|
||||
|
||||
item->cx = 100;
|
||||
item->cy = 14;
|
||||
|
||||
item->style = WS_CHILD | WS_VISIBLE | ES_READONLY;
|
||||
item->dwExtendedStyle = WS_EX_CLIENTEDGE;
|
||||
|
||||
data = (uint16_t *)(item + 1);
|
||||
*data++ = 0xFFFF;
|
||||
*data++ = 0x0081; /* edit text class */
|
||||
|
||||
data += MultiByteToWideChar(CP_ACP, 0, "", -1, data, 256);
|
||||
*data++ = 0; /* no creation data */
|
||||
|
||||
if (((uintptr_t)data) & 2)
|
||||
data++;
|
||||
|
||||
/* Button */
|
||||
item = (DLGITEMTEMPLATE *)data;
|
||||
item->x = 175;
|
||||
item->y = y;
|
||||
item->id = id++;
|
||||
|
||||
item->cx = 35;
|
||||
item->cy = 14;
|
||||
|
||||
item->style = WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON;
|
||||
|
||||
data = (uint16_t *)(item + 1);
|
||||
*data++ = 0xFFFF;
|
||||
*data++ = 0x0080; /* button class */
|
||||
|
||||
data += MultiByteToWideChar(CP_ACP, 0, "Browse", -1, data, 256);
|
||||
*data++ = 0; /* no creation data */
|
||||
|
||||
if (((uintptr_t)data) & 2)
|
||||
data++;
|
||||
|
||||
/*Static text*/
|
||||
item = (DLGITEMTEMPLATE *)data;
|
||||
item->x = 10;
|
||||
item->y = y;
|
||||
item->id = id++;
|
||||
|
||||
item->cx = 60;
|
||||
item->cy = 15;
|
||||
|
||||
item->style = WS_CHILD | WS_VISIBLE;
|
||||
|
||||
data = (uint16_t *)(item + 1);
|
||||
*data++ = 0xFFFF;
|
||||
*data++ = 0x0082; /* static class */
|
||||
|
||||
data += MultiByteToWideChar(CP_ACP, 0, config->description, -1, data, 256);
|
||||
*data++ = 0; /* no creation data */
|
||||
|
||||
if (((uintptr_t)data) & 2)
|
||||
data++;
|
||||
|
||||
y += 20;
|
||||
break;
|
||||
}
|
||||
|
||||
if (((unsigned long)data) & 2)
|
||||
data++;
|
||||
|
||||
config++;
|
||||
}
|
||||
|
||||
dlg->cdit = (id - IDC_CONFIG_BASE) + 2;
|
||||
|
||||
item = (DLGITEMTEMPLATE *)data;
|
||||
item->x = 20;
|
||||
item->y = y;
|
||||
item->cx = 50;
|
||||
item->cy = 14;
|
||||
item->id = IDOK; /* OK button identifier */
|
||||
item->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON;
|
||||
|
||||
data = (uint16_t *)(item + 1);
|
||||
*data++ = 0xFFFF;
|
||||
*data++ = 0x0080; /* button class */
|
||||
|
||||
data += MultiByteToWideChar(CP_ACP, 0, "OK", -1, data, 50);
|
||||
*data++ = 0; /* no creation data */
|
||||
|
||||
if (((unsigned long)data) & 2)
|
||||
data++;
|
||||
|
||||
item = (DLGITEMTEMPLATE *)data;
|
||||
item->x = 80;
|
||||
item->y = y;
|
||||
item->cx = 50;
|
||||
item->cy = 14;
|
||||
item->id = IDCANCEL; /* OK button identifier */
|
||||
item->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON;
|
||||
|
||||
data = (uint16_t *)(item + 1);
|
||||
*data++ = 0xFFFF;
|
||||
*data++ = 0x0080; /* button class */
|
||||
|
||||
data += MultiByteToWideChar(CP_ACP, 0, "Cancel", -1, data, 50);
|
||||
*data++ = 0; /* no creation data */
|
||||
|
||||
dlg->cy = y + 20;
|
||||
|
||||
config_device = device;
|
||||
|
||||
DialogBoxIndirect(hinstance, dlg, hwnd, deviceconfig_dlgproc);
|
||||
|
||||
free(data_block);
|
||||
}
|
||||
64
src/win/win_dynld.c
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Try to load a support DLL.
|
||||
*
|
||||
* Version: @(#)win_dynld.c 1.0.2 2017/05/24
|
||||
*
|
||||
* Author: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Copyright 2017 Fred N. van Kempen
|
||||
*/
|
||||
#include <windows.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <pcap.h>
|
||||
#include "plat_dynld.h"
|
||||
#include "../ibm.h"
|
||||
|
||||
|
||||
void *
|
||||
dynld_module(const char *name, dllimp_t *table)
|
||||
{
|
||||
HMODULE h;
|
||||
dllimp_t *imp;
|
||||
void *func;
|
||||
/* char **foo; */
|
||||
|
||||
/* See if we can load the desired module. */
|
||||
if ((h = LoadLibrary(name)) == NULL) {
|
||||
pclog("DynLd(\"%s\"): library not found!\n", name);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/* Now load the desired function pointers. */
|
||||
for (imp=table; imp->name!=NULL; imp++) {
|
||||
func = GetProcAddress(h, imp->name);
|
||||
if (func == NULL) {
|
||||
pclog("DynLd(\"%s\"): function '%s' not found!\n",
|
||||
name, imp->name);
|
||||
CloseHandle(h);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/* To overcome typing issues.. */
|
||||
*(char **)imp->func = (char *)func;
|
||||
}
|
||||
|
||||
/* All good. */
|
||||
return((void *)h);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
dynld_close(void *handle)
|
||||
{
|
||||
if (handle != NULL)
|
||||
FreeLibrary((HMODULE)handle);
|
||||
}
|
||||
202
src/win/win_iodev.c
Normal file
@@ -0,0 +1,202 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Windows IO device menu handler.
|
||||
*
|
||||
* Version: @(#)win_iodev.c 1.0.0 2017/05/30
|
||||
*
|
||||
* Author: Miran Grca, <mgrca8@gmail.com>
|
||||
* Copyright 2016-2017 Miran Grca.
|
||||
*/
|
||||
#define UNICODE
|
||||
#define _WIN32_WINNT 0x0501
|
||||
#define BITMAP WINDOWS_BITMAP
|
||||
#include <windows.h>
|
||||
#include <windowsx.h>
|
||||
#undef BITMAP
|
||||
|
||||
#include <commctrl.h>
|
||||
#include <commdlg.h>
|
||||
#include <process.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "../ibm.h"
|
||||
#include "../device.h"
|
||||
#include "../cdrom.h"
|
||||
#include "../cdrom_image.h"
|
||||
#include "../cdrom_ioctl.h"
|
||||
#include "../cdrom_null.h"
|
||||
#include "../scsi/scsi_disk.h"
|
||||
#include "plat_iodev.h"
|
||||
#include "win.h"
|
||||
|
||||
|
||||
void cdrom_eject(uint8_t id)
|
||||
{
|
||||
int part;
|
||||
|
||||
part = find_status_bar_part(SB_CDROM | id);
|
||||
|
||||
if ((part == -1) || (sb_menu_handles == NULL))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (cdrom_drives[id].host_drive == 0)
|
||||
{
|
||||
/* Switch from empty to empty. Do nothing. */
|
||||
return;
|
||||
}
|
||||
if ((cdrom_drives[id].host_drive >= 'A') && (cdrom_drives[id].host_drive <= 'Z'))
|
||||
{
|
||||
CheckMenuItem(sb_menu_handles[part], IDM_CDROM_HOST_DRIVE | id | ((cdrom_drives[id].host_drive - 'A') << 3), MF_UNCHECKED);
|
||||
}
|
||||
if (cdrom_drives[id].host_drive == 200)
|
||||
{
|
||||
wcscpy(cdrom_image[id].prev_image_path, cdrom_image[id].image_path);
|
||||
}
|
||||
cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive;
|
||||
cdrom_drives[id].handler->exit(id);
|
||||
cdrom_close(id);
|
||||
cdrom_null_open(id, 0);
|
||||
if (cdrom_drives[id].bus_type)
|
||||
{
|
||||
/* Signal disc change to the emulated machine. */
|
||||
cdrom_insert(id);
|
||||
}
|
||||
CheckMenuItem(sb_menu_handles[part], IDM_CDROM_IMAGE | id, MF_UNCHECKED);
|
||||
cdrom_drives[id].host_drive=0;
|
||||
CheckMenuItem(sb_menu_handles[part], IDM_CDROM_EMPTY | id, MF_CHECKED);
|
||||
update_status_bar_icon_state(SB_CDROM | id, 1);
|
||||
EnableMenuItem(sb_menu_handles[part], IDM_CDROM_RELOAD | id, MF_BYCOMMAND | MF_ENABLED);
|
||||
update_tip(SB_CDROM | id);
|
||||
saveconfig();
|
||||
}
|
||||
|
||||
void cdrom_reload(uint8_t id)
|
||||
{
|
||||
int part;
|
||||
int new_cdrom_drive;
|
||||
|
||||
part = find_status_bar_part(SB_CDROM | id);
|
||||
|
||||
if ((part == -1) || (sb_menu_handles == NULL))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ((cdrom_drives[id].host_drive == cdrom_drives[id].prev_host_drive) || (cdrom_drives[id].prev_host_drive == 0) || (cdrom_drives[id].host_drive != 0))
|
||||
{
|
||||
/* Switch from empty to empty. Do nothing. */
|
||||
return;
|
||||
}
|
||||
cdrom_close(id);
|
||||
if (cdrom_drives[id].prev_host_drive == 200)
|
||||
{
|
||||
wcscpy(cdrom_image[id].image_path, cdrom_image[id].prev_image_path);
|
||||
image_open(id, cdrom_image[id].image_path);
|
||||
if (cdrom_drives[id].bus_type)
|
||||
{
|
||||
/* Signal disc change to the emulated machine. */
|
||||
cdrom_insert(id);
|
||||
}
|
||||
if (wcslen(cdrom_image[id].image_path) == 0)
|
||||
{
|
||||
CheckMenuItem(sb_menu_handles[part], IDM_CDROM_EMPTY | id, MF_CHECKED);
|
||||
cdrom_drives[id].host_drive = 0;
|
||||
CheckMenuItem(sb_menu_handles[part], IDM_CDROM_IMAGE | id, MF_UNCHECKED);
|
||||
update_status_bar_icon_state(SB_CDROM | id, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
CheckMenuItem(sb_menu_handles[part], IDM_CDROM_EMPTY | id, MF_UNCHECKED);
|
||||
cdrom_drives[id].host_drive = 200;
|
||||
CheckMenuItem(sb_menu_handles[part], IDM_CDROM_IMAGE | id, MF_CHECKED);
|
||||
update_status_bar_icon_state(SB_CDROM | id, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
new_cdrom_drive = cdrom_drives[id].prev_host_drive;
|
||||
ioctl_open(id, new_cdrom_drive);
|
||||
if (cdrom_drives[id].bus_type)
|
||||
{
|
||||
/* Signal disc change to the emulated machine. */
|
||||
cdrom_insert(id);
|
||||
}
|
||||
CheckMenuItem(sb_menu_handles[part], IDM_CDROM_EMPTY | id, MF_UNCHECKED);
|
||||
cdrom_drives[id].host_drive = new_cdrom_drive;
|
||||
CheckMenuItem(sb_menu_handles[part], IDM_CDROM_HOST_DRIVE | id | ((cdrom_drives[id].host_drive - 'A') << 3), MF_CHECKED);
|
||||
update_status_bar_icon_state(SB_CDROM | id, 0);
|
||||
}
|
||||
EnableMenuItem(sb_menu_handles[part], IDM_CDROM_RELOAD | id, MF_BYCOMMAND | MF_GRAYED);
|
||||
update_tip(SB_CDROM | id);
|
||||
saveconfig();
|
||||
}
|
||||
|
||||
void removable_disk_unload(uint8_t id)
|
||||
{
|
||||
if (wcslen(hdc[id].fn) == 0)
|
||||
{
|
||||
/* Switch from empty to empty. Do nothing. */
|
||||
return;
|
||||
}
|
||||
scsi_unloadhd(hdc[id].scsi_id, hdc[id].scsi_lun, id);
|
||||
scsi_disk_insert(id);
|
||||
}
|
||||
|
||||
void removable_disk_eject(uint8_t id)
|
||||
{
|
||||
int part = 0;
|
||||
|
||||
part = find_status_bar_part(SB_CDROM | id);
|
||||
|
||||
if ((part == -1) || (sb_menu_handles == NULL))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
removable_disk_unload(id);
|
||||
update_status_bar_icon_state(SB_RDISK | id, 1);
|
||||
EnableMenuItem(sb_menu_handles[part], IDM_RDISK_EJECT | id, MF_BYCOMMAND | MF_GRAYED);
|
||||
EnableMenuItem(sb_menu_handles[part], IDM_RDISK_RELOAD | id, MF_BYCOMMAND | MF_ENABLED);
|
||||
EnableMenuItem(sb_menu_handles[part], IDM_RDISK_SEND_CHANGE | id, MF_BYCOMMAND | MF_GRAYED);
|
||||
update_tip(SB_RDISK | id);
|
||||
saveconfig();
|
||||
}
|
||||
|
||||
void removable_disk_reload(uint8_t id)
|
||||
{
|
||||
int part = 0;
|
||||
|
||||
part = find_status_bar_part(SB_CDROM | id);
|
||||
|
||||
if ((part == -1) || (sb_menu_handles == NULL))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (wcslen(hdc[id].fn) != 0)
|
||||
{
|
||||
/* Attempting to reload while an image is already loaded. Do nothing. */
|
||||
return;
|
||||
}
|
||||
scsi_reloadhd(id);
|
||||
/* scsi_disk_insert(id); */
|
||||
update_status_bar_icon_state(SB_RDISK | id, wcslen(hdc[id].fn) ? 0 : 1);
|
||||
EnableMenuItem(sb_menu_handles[part], IDM_RDISK_EJECT | id, MF_BYCOMMAND | (wcslen(hdc[id].fn) ? MF_ENABLED : MF_GRAYED));
|
||||
EnableMenuItem(sb_menu_handles[part], IDM_RDISK_RELOAD | id, MF_BYCOMMAND | MF_GRAYED);
|
||||
EnableMenuItem(sb_menu_handles[part], IDM_RDISK_SEND_CHANGE | id, MF_BYCOMMAND | (wcslen(hdc[id].fn) ? MF_ENABLED : MF_GRAYED));
|
||||
update_tip(SB_RDISK | id);
|
||||
saveconfig();
|
||||
}
|
||||
|
||||
296
src/win/win_joystick.cc
Normal file
@@ -0,0 +1,296 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Joystick interface to host device.
|
||||
*
|
||||
* Version: @(#)win_joystick.cc 1.0.0 2017/05/30
|
||||
*
|
||||
* Author: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Copyright 2008-2017 Sarah Walker.
|
||||
* Copyright 2016-2017 Miran Grca.
|
||||
*/
|
||||
|
||||
#define DIRECTINPUT_VERSION 0x0800
|
||||
#include <dinput.h>
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
extern "C" {
|
||||
#include "../device.h"
|
||||
#include "../gameport.h"
|
||||
}
|
||||
#include "plat_joystick.h"
|
||||
#include "win.h"
|
||||
|
||||
extern "C" int video_fullscreen;
|
||||
|
||||
extern "C" void fatal(const char *format, ...);
|
||||
extern "C" void pclog(const char *format, ...);
|
||||
|
||||
extern "C" void joystick_init();
|
||||
extern "C" void joystick_close();
|
||||
extern "C" void poll_joystick();
|
||||
|
||||
plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS];
|
||||
joystick_t joystick_state[MAX_JOYSTICKS];
|
||||
|
||||
static LPDIRECTINPUT8 lpdi;
|
||||
static LPDIRECTINPUTDEVICE8 lpdi_joystick[2] = {NULL, NULL};
|
||||
|
||||
int joysticks_present = 0;
|
||||
static GUID joystick_guids[MAX_JOYSTICKS];
|
||||
|
||||
static BOOL CALLBACK joystick_enum_callback(LPCDIDEVICEINSTANCE lpddi, LPVOID data)
|
||||
{
|
||||
if (joysticks_present >= MAX_JOYSTICKS)
|
||||
return DIENUM_STOP;
|
||||
|
||||
pclog("joystick_enum_callback : found joystick %i : %s\n", joysticks_present, lpddi->tszProductName);
|
||||
|
||||
joystick_guids[joysticks_present++] = lpddi->guidInstance;
|
||||
|
||||
if (joysticks_present >= MAX_JOYSTICKS)
|
||||
return DIENUM_STOP;
|
||||
|
||||
return DIENUM_CONTINUE;
|
||||
}
|
||||
|
||||
BOOL CALLBACK DIEnumDeviceObjectsCallback(
|
||||
LPCDIDEVICEOBJECTINSTANCE lpddoi,
|
||||
LPVOID pvRef)
|
||||
{
|
||||
plat_joystick_t *state = (plat_joystick_t *)pvRef;
|
||||
|
||||
if (lpddoi->guidType == GUID_XAxis || lpddoi->guidType == GUID_YAxis || lpddoi->guidType == GUID_ZAxis ||
|
||||
lpddoi->guidType == GUID_RxAxis || lpddoi->guidType == GUID_RyAxis || lpddoi->guidType == GUID_RzAxis ||
|
||||
lpddoi->guidType == GUID_Slider)
|
||||
{
|
||||
strncpy(state->axis[state->nr_axes].name, lpddoi->tszName, sizeof(state->axis[state->nr_axes].name));
|
||||
pclog("Axis %i : %s %x %x\n", state->nr_axes, state->axis[state->nr_axes].name, lpddoi->dwOfs, lpddoi->dwType);
|
||||
if (lpddoi->guidType == GUID_XAxis)
|
||||
state->axis[state->nr_axes].id = 0;
|
||||
else if (lpddoi->guidType == GUID_YAxis)
|
||||
state->axis[state->nr_axes].id = 1;
|
||||
else if (lpddoi->guidType == GUID_ZAxis)
|
||||
state->axis[state->nr_axes].id = 2;
|
||||
else if (lpddoi->guidType == GUID_RxAxis)
|
||||
state->axis[state->nr_axes].id = 3;
|
||||
else if (lpddoi->guidType == GUID_RyAxis)
|
||||
state->axis[state->nr_axes].id = 4;
|
||||
else if (lpddoi->guidType == GUID_RzAxis)
|
||||
state->axis[state->nr_axes].id = 5;
|
||||
state->nr_axes++;
|
||||
}
|
||||
else if (lpddoi->guidType == GUID_Button)
|
||||
{
|
||||
strncpy(state->button[state->nr_buttons].name, lpddoi->tszName, sizeof(state->button[state->nr_buttons].name));
|
||||
pclog("Button %i : %s %x %x\n", state->nr_buttons, state->button[state->nr_buttons].name, lpddoi->dwOfs, lpddoi->dwType);
|
||||
state->nr_buttons++;
|
||||
}
|
||||
else if (lpddoi->guidType == GUID_POV)
|
||||
{
|
||||
strncpy(state->pov[state->nr_povs].name, lpddoi->tszName, sizeof(state->pov[state->nr_povs].name));
|
||||
pclog("POV %i : %s %x %x\n", state->nr_povs, state->pov[state->nr_povs].name, lpddoi->dwOfs, lpddoi->dwType);
|
||||
state->nr_povs++;
|
||||
}
|
||||
|
||||
return DIENUM_CONTINUE;
|
||||
}
|
||||
|
||||
void joystick_init()
|
||||
{
|
||||
int c;
|
||||
|
||||
if (joystick_type == 7) return;
|
||||
|
||||
atexit(joystick_close);
|
||||
|
||||
joysticks_present = 0;
|
||||
|
||||
if (FAILED(DirectInput8Create(hinstance, DIRECTINPUT_VERSION, IID_IDirectInput8A, (void **) &lpdi, NULL)))
|
||||
fatal("joystick_init : DirectInputCreate failed\n");
|
||||
|
||||
if (FAILED(lpdi->EnumDevices(DIDEVTYPE_JOYSTICK, joystick_enum_callback, NULL, DIEDFL_ATTACHEDONLY)))
|
||||
fatal("joystick_init : EnumDevices failed\n");
|
||||
|
||||
pclog("joystick_init: joysticks_present=%i\n", joysticks_present);
|
||||
|
||||
for (c = 0; c < joysticks_present; c++)
|
||||
{
|
||||
LPDIRECTINPUTDEVICE8 lpdi_joystick_temp = NULL;
|
||||
DIPROPRANGE joy_axis_range;
|
||||
DIDEVICEINSTANCE device_instance;
|
||||
DIDEVCAPS devcaps;
|
||||
|
||||
if (FAILED(lpdi->CreateDevice(joystick_guids[c], &lpdi_joystick_temp, NULL)))
|
||||
fatal("joystick_init : CreateDevice failed\n");
|
||||
if (FAILED(lpdi_joystick_temp->QueryInterface(IID_IDirectInputDevice8, (void **)&lpdi_joystick[c])))
|
||||
fatal("joystick_init : CreateDevice failed\n");
|
||||
lpdi_joystick_temp->Release();
|
||||
|
||||
memset(&device_instance, 0, sizeof(device_instance));
|
||||
device_instance.dwSize = sizeof(device_instance);
|
||||
if (FAILED(lpdi_joystick[c]->GetDeviceInfo(&device_instance)))
|
||||
fatal("joystick_init : GetDeviceInfo failed\n");
|
||||
pclog("Joystick %i :\n", c);
|
||||
pclog(" tszInstanceName = %s\n", device_instance.tszInstanceName);
|
||||
pclog(" tszProductName = %s\n", device_instance.tszProductName);
|
||||
strncpy(plat_joystick_state[c].name, device_instance.tszInstanceName, 64);
|
||||
|
||||
memset(&devcaps, 0, sizeof(devcaps));
|
||||
devcaps.dwSize = sizeof(devcaps);
|
||||
if (FAILED(lpdi_joystick[c]->GetCapabilities(&devcaps)))
|
||||
fatal("joystick_init : GetCapabilities failed\n");
|
||||
pclog(" Axes = %i\n", devcaps.dwAxes);
|
||||
pclog(" Buttons = %i\n", devcaps.dwButtons);
|
||||
pclog(" POVs = %i\n", devcaps.dwPOVs);
|
||||
|
||||
lpdi_joystick[c]->EnumObjects(DIEnumDeviceObjectsCallback, &plat_joystick_state[c], DIDFT_ALL);
|
||||
|
||||
if (FAILED(lpdi_joystick[c]->SetCooperativeLevel(ghwnd, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE)))
|
||||
fatal("joystick_init : SetCooperativeLevel failed\n");
|
||||
if (FAILED(lpdi_joystick[c]->SetDataFormat(&c_dfDIJoystick)))
|
||||
fatal("joystick_init : SetDataFormat failed\n");
|
||||
|
||||
joy_axis_range.lMin = -32768;
|
||||
joy_axis_range.lMax = 32767;
|
||||
joy_axis_range.diph.dwSize = sizeof(DIPROPRANGE);
|
||||
joy_axis_range.diph.dwHeaderSize = sizeof(DIPROPHEADER);
|
||||
joy_axis_range.diph.dwHow = DIPH_BYOFFSET;
|
||||
joy_axis_range.diph.dwObj = DIJOFS_X;
|
||||
lpdi_joystick[c]->SetProperty(DIPROP_RANGE, &joy_axis_range.diph);
|
||||
joy_axis_range.diph.dwObj = DIJOFS_Y;
|
||||
lpdi_joystick[c]->SetProperty(DIPROP_RANGE, &joy_axis_range.diph);
|
||||
joy_axis_range.diph.dwObj = DIJOFS_Z;
|
||||
lpdi_joystick[c]->SetProperty(DIPROP_RANGE, &joy_axis_range.diph);
|
||||
joy_axis_range.diph.dwObj = DIJOFS_RX;
|
||||
lpdi_joystick[c]->SetProperty(DIPROP_RANGE, &joy_axis_range.diph);
|
||||
joy_axis_range.diph.dwObj = DIJOFS_RY;
|
||||
lpdi_joystick[c]->SetProperty(DIPROP_RANGE, &joy_axis_range.diph);
|
||||
joy_axis_range.diph.dwObj = DIJOFS_RZ;
|
||||
lpdi_joystick[c]->SetProperty(DIPROP_RANGE, &joy_axis_range.diph);
|
||||
|
||||
if (FAILED(lpdi_joystick[c]->Acquire()))
|
||||
fatal("joystick_init : Acquire failed\n");
|
||||
}
|
||||
}
|
||||
|
||||
void joystick_close()
|
||||
{
|
||||
if (lpdi_joystick[1])
|
||||
{
|
||||
lpdi_joystick[1]->Release();
|
||||
lpdi_joystick[1] = NULL;
|
||||
}
|
||||
if (lpdi_joystick[0])
|
||||
{
|
||||
lpdi_joystick[0]->Release();
|
||||
lpdi_joystick[0] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int joystick_get_axis(int joystick_nr, int mapping)
|
||||
{
|
||||
if (mapping & POV_X)
|
||||
{
|
||||
int pov = plat_joystick_state[joystick_nr].p[mapping & 3];
|
||||
|
||||
if (LOWORD(pov) == 0xFFFF)
|
||||
return 0;
|
||||
else
|
||||
return sin((2*M_PI * (double)pov) / 36000.0) * 32767;
|
||||
}
|
||||
else if (mapping & POV_Y)
|
||||
{
|
||||
int pov = plat_joystick_state[joystick_nr].p[mapping & 3];
|
||||
|
||||
if (LOWORD(pov) == 0xFFFF)
|
||||
return 0;
|
||||
else
|
||||
return -cos((2*M_PI * (double)pov) / 36000.0) * 32767;
|
||||
}
|
||||
else
|
||||
return plat_joystick_state[joystick_nr].a[plat_joystick_state[joystick_nr].axis[mapping].id];
|
||||
}
|
||||
|
||||
void joystick_poll()
|
||||
{
|
||||
int c, d;
|
||||
|
||||
for (c = 0; c < joysticks_present; c++)
|
||||
{
|
||||
DIJOYSTATE joystate;
|
||||
int b;
|
||||
|
||||
if (FAILED(lpdi_joystick[c]->Poll()))
|
||||
{
|
||||
lpdi_joystick[c]->Acquire();
|
||||
lpdi_joystick[c]->Poll();
|
||||
}
|
||||
if (FAILED(lpdi_joystick[c]->GetDeviceState(sizeof(DIJOYSTATE), (LPVOID)&joystate)))
|
||||
{
|
||||
lpdi_joystick[c]->Acquire();
|
||||
lpdi_joystick[c]->Poll();
|
||||
lpdi_joystick[c]->GetDeviceState(sizeof(DIJOYSTATE), (LPVOID)&joystate);
|
||||
}
|
||||
|
||||
plat_joystick_state[c].a[0] = joystate.lX;
|
||||
plat_joystick_state[c].a[1] = joystate.lY;
|
||||
plat_joystick_state[c].a[2] = joystate.lZ;
|
||||
plat_joystick_state[c].a[3] = joystate.lRx;
|
||||
plat_joystick_state[c].a[4] = joystate.lRy;
|
||||
plat_joystick_state[c].a[5] = joystate.lRz;
|
||||
|
||||
for (b = 0; b < 16; b++)
|
||||
plat_joystick_state[c].b[b] = joystate.rgbButtons[b] & 0x80;
|
||||
|
||||
for (b = 0; b < 4; b++)
|
||||
plat_joystick_state[c].p[b] = joystate.rgdwPOV[b];
|
||||
// pclog("joystick %i - x=%i y=%i b[0]=%i b[1]=%i %i\n", c, joystick_state[c].x, joystick_state[c].y, joystick_state[c].b[0], joystick_state[c].b[1], joysticks_present);
|
||||
}
|
||||
|
||||
for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++)
|
||||
{
|
||||
if (joystick_state[c].plat_joystick_nr)
|
||||
{
|
||||
int joystick_nr = joystick_state[c].plat_joystick_nr - 1;
|
||||
|
||||
for (d = 0; d < joystick_get_axis_count(joystick_type); d++)
|
||||
joystick_state[c].axis[d] = joystick_get_axis(joystick_nr, joystick_state[c].axis_mapping[d]);
|
||||
for (d = 0; d < joystick_get_button_count(joystick_type); d++)
|
||||
joystick_state[c].button[d] = plat_joystick_state[joystick_nr].b[joystick_state[c].button_mapping[d]];
|
||||
|
||||
for (d = 0; d < joystick_get_pov_count(joystick_type); d++)
|
||||
{
|
||||
int x, y;
|
||||
double angle, magnitude;
|
||||
|
||||
x = joystick_get_axis(joystick_nr, joystick_state[c].pov_mapping[d][0]);
|
||||
y = joystick_get_axis(joystick_nr, joystick_state[c].pov_mapping[d][1]);
|
||||
|
||||
angle = (atan2((double)y, (double)x) * 360.0) / (2*M_PI);
|
||||
magnitude = sqrt((double)x*(double)x + (double)y*(double)y);
|
||||
|
||||
if (magnitude < 16384)
|
||||
joystick_state[c].pov[d] = -1;
|
||||
else
|
||||
joystick_state[c].pov[d] = ((int)angle + 90 + 360) % 360;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (d = 0; d < joystick_get_axis_count(joystick_type); d++)
|
||||
joystick_state[c].axis[d] = 0;
|
||||
for (d = 0; d < joystick_get_button_count(joystick_type); d++)
|
||||
joystick_state[c].button[d] = 0;
|
||||
for (d = 0; d < joystick_get_pov_count(joystick_type); d++)
|
||||
joystick_state[c].pov[d] = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
542
src/win/win_joystickconfig.c
Normal file
@@ -0,0 +1,542 @@
|
||||
/* Copyright holders: Sarah Walker
|
||||
see COPYING for more details
|
||||
*/
|
||||
#define BITMAP WINDOWS_BITMAP
|
||||
#include <windows.h>
|
||||
#include <windowsx.h>
|
||||
#undef BITMAP
|
||||
|
||||
#include "../ibm.h"
|
||||
#include "../config.h"
|
||||
#include "../device.h"
|
||||
#include "../gameport.h"
|
||||
#include "plat_joystick.h"
|
||||
#include "win.h"
|
||||
|
||||
|
||||
static int joystick_nr;
|
||||
static int joystick_config_type;
|
||||
#define AXIS_STRINGS_MAX 3
|
||||
static char *axis_strings[AXIS_STRINGS_MAX] = {"X Axis", "Y Axis", "Z Axis"};
|
||||
|
||||
|
||||
static void rebuild_axis_button_selections(HWND hdlg)
|
||||
{
|
||||
int id = IDC_CONFIG_BASE + 2;
|
||||
HWND h;
|
||||
int joystick;
|
||||
int c, d;
|
||||
|
||||
h = GetDlgItem(hdlg, IDC_CONFIG_BASE);
|
||||
joystick = SendMessage(h, CB_GETCURSEL, 0, 0);
|
||||
|
||||
for (c = 0; c < joystick_get_axis_count(joystick_config_type); c++)
|
||||
{
|
||||
int sel = c;
|
||||
|
||||
h = GetDlgItem(hdlg, id);
|
||||
SendMessage(h, CB_RESETCONTENT, 0, 0);
|
||||
|
||||
if (joystick)
|
||||
{
|
||||
for (d = 0; d < plat_joystick_state[joystick-1].nr_axes; d++)
|
||||
{
|
||||
SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)plat_joystick_state[joystick-1].axis[d].name);
|
||||
if (c < AXIS_STRINGS_MAX)
|
||||
{
|
||||
if (!stricmp(axis_strings[c], plat_joystick_state[joystick-1].axis[d].name))
|
||||
sel = d;
|
||||
}
|
||||
}
|
||||
for (d = 0; d < plat_joystick_state[joystick-1].nr_povs; d++)
|
||||
{
|
||||
char s[80];
|
||||
|
||||
sprintf(s, "%s (X axis)", plat_joystick_state[joystick-1].pov[d].name);
|
||||
SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)s);
|
||||
sprintf(s, "%s (Y axis)", plat_joystick_state[joystick-1].pov[d].name);
|
||||
SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)s);
|
||||
}
|
||||
SendMessage(h, CB_SETCURSEL, sel, 0);
|
||||
EnableWindow(h, TRUE);
|
||||
}
|
||||
else
|
||||
EnableWindow(h, FALSE);
|
||||
|
||||
id += 2;
|
||||
}
|
||||
|
||||
for (c = 0; c < joystick_get_button_count(joystick_config_type); c++)
|
||||
{
|
||||
h = GetDlgItem(hdlg, id);
|
||||
SendMessage(h, CB_RESETCONTENT, 0, 0);
|
||||
|
||||
if (joystick)
|
||||
{
|
||||
for (d = 0; d < plat_joystick_state[joystick-1].nr_buttons; d++)
|
||||
SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)plat_joystick_state[joystick-1].button[d].name);
|
||||
SendMessage(h, CB_SETCURSEL, c, 0);
|
||||
EnableWindow(h, TRUE);
|
||||
}
|
||||
else
|
||||
EnableWindow(h, FALSE);
|
||||
|
||||
id += 2;
|
||||
}
|
||||
|
||||
for (c = 0; c < joystick_get_pov_count(joystick_config_type)*2; c++)
|
||||
{
|
||||
int sel = c;
|
||||
|
||||
h = GetDlgItem(hdlg, id);
|
||||
SendMessage(h, CB_RESETCONTENT, 0, 0);
|
||||
|
||||
if (joystick)
|
||||
{
|
||||
for (d = 0; d < plat_joystick_state[joystick-1].nr_povs; d++)
|
||||
{
|
||||
char s[80];
|
||||
|
||||
sprintf(s, "%s (X axis)", plat_joystick_state[joystick-1].pov[d].name);
|
||||
SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)s);
|
||||
sprintf(s, "%s (Y axis)", plat_joystick_state[joystick-1].pov[d].name);
|
||||
SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)s);
|
||||
}
|
||||
for (d = 0; d < plat_joystick_state[joystick-1].nr_axes; d++)
|
||||
{
|
||||
SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)plat_joystick_state[joystick-1].axis[d].name);
|
||||
}
|
||||
SendMessage(h, CB_SETCURSEL, sel, 0);
|
||||
EnableWindow(h, TRUE);
|
||||
}
|
||||
else
|
||||
EnableWindow(h, FALSE);
|
||||
|
||||
id += 2;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static int get_axis(HWND hdlg, int id)
|
||||
{
|
||||
HWND h = GetDlgItem(hdlg, id);
|
||||
int axis_sel = SendMessage(h, CB_GETCURSEL, 0, 0);
|
||||
int nr_axes = plat_joystick_state[joystick_state[joystick_nr].plat_joystick_nr-1].nr_axes;
|
||||
|
||||
if (axis_sel < nr_axes)
|
||||
return axis_sel;
|
||||
|
||||
axis_sel -= nr_axes;
|
||||
if (axis_sel & 1)
|
||||
return POV_Y | (axis_sel >> 1);
|
||||
else
|
||||
return POV_X | (axis_sel >> 1);
|
||||
}
|
||||
|
||||
static int get_pov(HWND hdlg, int id)
|
||||
{
|
||||
HWND h = GetDlgItem(hdlg, id);
|
||||
int axis_sel = SendMessage(h, CB_GETCURSEL, 0, 0);
|
||||
int nr_povs = plat_joystick_state[joystick_state[joystick_nr].plat_joystick_nr-1].nr_povs*2;
|
||||
|
||||
if (axis_sel < nr_povs)
|
||||
{
|
||||
if (axis_sel & 1)
|
||||
return POV_Y | (axis_sel >> 1);
|
||||
else
|
||||
return POV_X | (axis_sel >> 1);
|
||||
}
|
||||
|
||||
return axis_sel - nr_povs;
|
||||
}
|
||||
|
||||
static BOOL CALLBACK joystickconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
HWND h;
|
||||
int c;
|
||||
int id;
|
||||
int joystick;
|
||||
int nr_axes;
|
||||
int nr_povs;
|
||||
int mapping;
|
||||
|
||||
switch (message)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
h = GetDlgItem(hdlg, IDC_CONFIG_BASE);
|
||||
id = IDC_CONFIG_BASE + 2;
|
||||
joystick = joystick_state[joystick_nr].plat_joystick_nr;
|
||||
|
||||
SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"None");
|
||||
|
||||
for (c = 0; c < joysticks_present; c++)
|
||||
SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)plat_joystick_state[c].name);
|
||||
|
||||
SendMessage(h, CB_SETCURSEL, joystick, 0);
|
||||
|
||||
rebuild_axis_button_selections(hdlg);
|
||||
|
||||
if (joystick_state[joystick_nr].plat_joystick_nr)
|
||||
{
|
||||
nr_axes = plat_joystick_state[joystick-1].nr_axes;
|
||||
nr_povs = plat_joystick_state[joystick-1].nr_povs;
|
||||
for (c = 0; c < joystick_get_axis_count(joystick_config_type); c++)
|
||||
{
|
||||
int mapping = joystick_state[joystick_nr].axis_mapping[c];
|
||||
|
||||
h = GetDlgItem(hdlg, id);
|
||||
if (mapping & POV_X)
|
||||
SendMessage(h, CB_SETCURSEL, nr_axes + (mapping & 3)*2, 0);
|
||||
else if (mapping & POV_Y)
|
||||
SendMessage(h, CB_SETCURSEL, nr_axes + (mapping & 3)*2 + 1, 0);
|
||||
else
|
||||
SendMessage(h, CB_SETCURSEL, mapping, 0);
|
||||
id += 2;
|
||||
}
|
||||
for (c = 0; c < joystick_get_button_count(joystick_config_type); c++)
|
||||
{
|
||||
h = GetDlgItem(hdlg, id);
|
||||
SendMessage(h, CB_SETCURSEL, joystick_state[joystick_nr].button_mapping[c], 0);
|
||||
id += 2;
|
||||
}
|
||||
for (c = 0; c < joystick_get_pov_count(joystick_config_type); c++)
|
||||
{
|
||||
h = GetDlgItem(hdlg, id);
|
||||
mapping = joystick_state[joystick_nr].pov_mapping[c][0];
|
||||
if (mapping & POV_X)
|
||||
SendMessage(h, CB_SETCURSEL, (mapping & 3)*2, 0);
|
||||
else if (mapping & POV_Y)
|
||||
SendMessage(h, CB_SETCURSEL, (mapping & 3)*2 + 1, 0);
|
||||
else
|
||||
SendMessage(h, CB_SETCURSEL, mapping + nr_povs*2, 0);
|
||||
id += 2;
|
||||
h = GetDlgItem(hdlg, id);
|
||||
mapping = joystick_state[joystick_nr].pov_mapping[c][1];
|
||||
if (mapping & POV_X)
|
||||
SendMessage(h, CB_SETCURSEL, (mapping & 3)*2, 0);
|
||||
else if (mapping & POV_Y)
|
||||
SendMessage(h, CB_SETCURSEL, (mapping & 3)*2 + 1, 0);
|
||||
else
|
||||
SendMessage(h, CB_SETCURSEL, mapping + nr_povs*2, 0);
|
||||
id += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
|
||||
case WM_COMMAND:
|
||||
switch (LOWORD(wParam))
|
||||
{
|
||||
case IDC_CONFIG_BASE:
|
||||
if (HIWORD(wParam) == CBN_SELCHANGE)
|
||||
rebuild_axis_button_selections(hdlg);
|
||||
break;
|
||||
|
||||
case IDOK:
|
||||
{
|
||||
id = IDC_CONFIG_BASE + 2;
|
||||
|
||||
h = GetDlgItem(hdlg, IDC_CONFIG_BASE);
|
||||
joystick_state[joystick_nr].plat_joystick_nr = SendMessage(h, CB_GETCURSEL, 0, 0);
|
||||
|
||||
if (joystick_state[joystick_nr].plat_joystick_nr)
|
||||
{
|
||||
for (c = 0; c < joystick_get_axis_count(joystick_config_type); c++)
|
||||
{
|
||||
joystick_state[joystick_nr].axis_mapping[c] = get_axis(hdlg, id);
|
||||
id += 2;
|
||||
}
|
||||
for (c = 0; c < joystick_get_button_count(joystick_config_type); c++)
|
||||
{
|
||||
h = GetDlgItem(hdlg, id);
|
||||
joystick_state[joystick_nr].button_mapping[c] = SendMessage(h, CB_GETCURSEL, 0, 0);
|
||||
id += 2;
|
||||
}
|
||||
for (c = 0; c < joystick_get_button_count(joystick_config_type); c++)
|
||||
{
|
||||
h = GetDlgItem(hdlg, id);
|
||||
joystick_state[joystick_nr].pov_mapping[c][0] = get_pov(hdlg, id);
|
||||
id += 2;
|
||||
h = GetDlgItem(hdlg, id);
|
||||
joystick_state[joystick_nr].pov_mapping[c][1] = get_pov(hdlg, id);
|
||||
id += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
case IDCANCEL:
|
||||
EndDialog(hdlg, 0);
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void joystickconfig_open(HWND hwnd, int joy_nr, int type)
|
||||
{
|
||||
uint16_t *data_block = malloc(16384);
|
||||
uint16_t *data;
|
||||
DLGTEMPLATE *dlg = (DLGTEMPLATE *)data_block;
|
||||
DLGITEMTEMPLATE *item;
|
||||
int y = 10;
|
||||
int id = IDC_CONFIG_BASE;
|
||||
int c;
|
||||
|
||||
joystick_nr = joy_nr;
|
||||
joystick_config_type = type;
|
||||
|
||||
memset(data_block, 0, 4096);
|
||||
|
||||
dlg->style = DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU;
|
||||
dlg->x = 10;
|
||||
dlg->y = 10;
|
||||
dlg->cx = 220;
|
||||
dlg->cy = 70;
|
||||
|
||||
data = (uint16_t *)(dlg + 1);
|
||||
|
||||
*data++ = 0; /*no menu*/
|
||||
*data++ = 0; /*predefined dialog box class*/
|
||||
data += MultiByteToWideChar(CP_ACP, 0, "Device Configuration", -1, data, 50);
|
||||
|
||||
*data++ = 8; /*Point*/
|
||||
data += MultiByteToWideChar(CP_ACP, 0, "MS Sans Serif", -1, data, 50);
|
||||
|
||||
if (((unsigned long)data) & 2)
|
||||
data++;
|
||||
|
||||
|
||||
/*Combo box*/
|
||||
item = (DLGITEMTEMPLATE *)data;
|
||||
item->x = 70;
|
||||
item->y = y;
|
||||
item->id = id++;
|
||||
|
||||
item->cx = 140;
|
||||
item->cy = 150;
|
||||
|
||||
item->style = WS_CHILD | WS_VISIBLE | CBS_DROPDOWN | WS_VSCROLL;
|
||||
|
||||
data = (uint16_t *)(item + 1);
|
||||
*data++ = 0xFFFF;
|
||||
*data++ = 0x0085; /* combo box class */
|
||||
|
||||
data += MultiByteToWideChar(CP_ACP, 0, "Device", -1, data, 256);
|
||||
*data++ = 0; /* no creation data */
|
||||
|
||||
if (((unsigned long)data) & 2)
|
||||
data++;
|
||||
|
||||
/*Static text*/
|
||||
item = (DLGITEMTEMPLATE *)data;
|
||||
item->x = 10;
|
||||
item->y = y;
|
||||
item->id = id++;
|
||||
|
||||
item->cx = 60;
|
||||
item->cy = 15;
|
||||
|
||||
item->style = WS_CHILD | WS_VISIBLE;
|
||||
|
||||
data = (uint16_t *)(item + 1);
|
||||
*data++ = 0xFFFF;
|
||||
*data++ = 0x0082; /* static class */
|
||||
|
||||
data += MultiByteToWideChar(CP_ACP, 0, "Device :", -1, data, 256);
|
||||
*data++ = 0; /* no creation data */
|
||||
|
||||
if (((unsigned long)data) & 2)
|
||||
data++;
|
||||
|
||||
y += 20;
|
||||
|
||||
|
||||
for (c = 0; c < joystick_get_axis_count(type); c++)
|
||||
{
|
||||
/*Combo box*/
|
||||
item = (DLGITEMTEMPLATE *)data;
|
||||
item->x = 70;
|
||||
item->y = y;
|
||||
item->id = id++;
|
||||
|
||||
item->cx = 140;
|
||||
item->cy = 150;
|
||||
|
||||
item->style = WS_CHILD | WS_VISIBLE | CBS_DROPDOWN | WS_VSCROLL;
|
||||
|
||||
data = (uint16_t *)(item + 1);
|
||||
*data++ = 0xFFFF;
|
||||
*data++ = 0x0085; /* combo box class */
|
||||
|
||||
data += MultiByteToWideChar(CP_ACP, 0, joystick_get_axis_name(type, c), -1, data, 256);
|
||||
*data++ = 0; /* no creation data */
|
||||
|
||||
if (((unsigned long)data) & 2)
|
||||
data++;
|
||||
|
||||
/*Static text*/
|
||||
item = (DLGITEMTEMPLATE *)data;
|
||||
item->x = 10;
|
||||
item->y = y;
|
||||
item->id = id++;
|
||||
|
||||
item->cx = 60;
|
||||
item->cy = 15;
|
||||
|
||||
item->style = WS_CHILD | WS_VISIBLE;
|
||||
|
||||
data = (uint16_t *)(item + 1);
|
||||
*data++ = 0xFFFF;
|
||||
*data++ = 0x0082; /* static class */
|
||||
|
||||
data += MultiByteToWideChar(CP_ACP, 0, joystick_get_axis_name(type, c), -1, data, 256);
|
||||
*data++ = 0; /* no creation data */
|
||||
|
||||
if (((unsigned long)data) & 2)
|
||||
data++;
|
||||
|
||||
y += 20;
|
||||
}
|
||||
|
||||
for (c = 0; c < joystick_get_button_count(type); c++)
|
||||
{
|
||||
/*Combo box*/
|
||||
item = (DLGITEMTEMPLATE *)data;
|
||||
item->x = 70;
|
||||
item->y = y;
|
||||
item->id = id++;
|
||||
|
||||
item->cx = 140;
|
||||
item->cy = 150;
|
||||
|
||||
item->style = WS_CHILD | WS_VISIBLE | CBS_DROPDOWN | WS_VSCROLL;
|
||||
|
||||
data = (uint16_t *)(item + 1);
|
||||
*data++ = 0xFFFF;
|
||||
*data++ = 0x0085; /* combo box class */
|
||||
|
||||
data += MultiByteToWideChar(CP_ACP, 0, joystick_get_button_name(type, c), -1, data, 256);
|
||||
*data++ = 0; /* no creation data */
|
||||
|
||||
if (((unsigned long)data) & 2)
|
||||
data++;
|
||||
|
||||
/*Static text*/
|
||||
item = (DLGITEMTEMPLATE *)data;
|
||||
item->x = 10;
|
||||
item->y = y;
|
||||
item->id = id++;
|
||||
|
||||
item->cx = 60;
|
||||
item->cy = 15;
|
||||
|
||||
item->style = WS_CHILD | WS_VISIBLE;
|
||||
|
||||
data = (uint16_t *)(item + 1);
|
||||
*data++ = 0xFFFF;
|
||||
*data++ = 0x0082; /* static class */
|
||||
|
||||
data += MultiByteToWideChar(CP_ACP, 0, joystick_get_button_name(type, c), -1, data, 256);
|
||||
*data++ = 0; /* no creation data */
|
||||
|
||||
if (((unsigned long)data) & 2)
|
||||
data++;
|
||||
|
||||
y += 20;
|
||||
}
|
||||
|
||||
for (c = 0; c < joystick_get_pov_count(type)*2; c++)
|
||||
{
|
||||
char s[80];
|
||||
|
||||
/*Combo box*/
|
||||
item = (DLGITEMTEMPLATE *)data;
|
||||
item->x = 70;
|
||||
item->y = y;
|
||||
item->id = id++;
|
||||
|
||||
item->cx = 140;
|
||||
item->cy = 150;
|
||||
|
||||
item->style = WS_CHILD | WS_VISIBLE | CBS_DROPDOWN | WS_VSCROLL;
|
||||
|
||||
data = (uint16_t *)(item + 1);
|
||||
*data++ = 0xFFFF;
|
||||
*data++ = 0x0085; /* combo box class */
|
||||
|
||||
if (c & 1)
|
||||
sprintf(s, "%s (Y axis)", joystick_get_pov_name(type, c/2));
|
||||
else
|
||||
sprintf(s, "%s (X axis)", joystick_get_pov_name(type, c/2));
|
||||
data += MultiByteToWideChar(CP_ACP, 0, s, -1, data, 256);
|
||||
*data++ = 0; /* no creation data */
|
||||
|
||||
if (((unsigned long)data) & 2)
|
||||
data++;
|
||||
|
||||
/*Static text*/
|
||||
item = (DLGITEMTEMPLATE *)data;
|
||||
item->x = 10;
|
||||
item->y = y;
|
||||
item->id = id++;
|
||||
|
||||
item->cx = 60;
|
||||
item->cy = 15;
|
||||
|
||||
item->style = WS_CHILD | WS_VISIBLE;
|
||||
|
||||
data = (uint16_t *)(item + 1);
|
||||
*data++ = 0xFFFF;
|
||||
*data++ = 0x0082; /* static class */
|
||||
|
||||
data += MultiByteToWideChar(CP_ACP, 0, s, -1, data, 256);
|
||||
*data++ = 0; /* no creation data */
|
||||
|
||||
if (((unsigned long)data) & 2)
|
||||
data++;
|
||||
|
||||
y += 20;
|
||||
}
|
||||
|
||||
dlg->cdit = (id - IDC_CONFIG_BASE) + 2;
|
||||
|
||||
item = (DLGITEMTEMPLATE *)data;
|
||||
item->x = 20;
|
||||
item->y = y;
|
||||
item->cx = 50;
|
||||
item->cy = 14;
|
||||
item->id = IDOK; /* OK button identifier */
|
||||
item->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON;
|
||||
|
||||
data = (uint16_t *)(item + 1);
|
||||
*data++ = 0xFFFF;
|
||||
*data++ = 0x0080; /* button class */
|
||||
|
||||
data += MultiByteToWideChar(CP_ACP, 0, "OK", -1, data, 50);
|
||||
*data++ = 0; /* no creation data */
|
||||
|
||||
if (((unsigned long)data) & 2)
|
||||
data++;
|
||||
|
||||
item = (DLGITEMTEMPLATE *)data;
|
||||
item->x = 80;
|
||||
item->y = y;
|
||||
item->cx = 50;
|
||||
item->cy = 14;
|
||||
item->id = IDCANCEL; /* OK button identifier */
|
||||
item->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON;
|
||||
|
||||
data = (uint16_t *)(item + 1);
|
||||
*data++ = 0xFFFF;
|
||||
*data++ = 0x0080; /* button class */
|
||||
|
||||
data += MultiByteToWideChar(CP_ACP, 0, "Cancel", -1, data, 50);
|
||||
*data++ = 0; /* no creation data */
|
||||
|
||||
dlg->cy = y + 20;
|
||||
|
||||
DialogBoxIndirect(hinstance, dlg, hwnd, joystickconfig_dlgproc);
|
||||
|
||||
free(data_block);
|
||||
}
|
||||
211
src/win/win_keyboard.c
Normal file
@@ -0,0 +1,211 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Windows raw keyboard input handler.
|
||||
*
|
||||
* Version: @(#)win_d3d.cc 1.0.0 2017/05/30
|
||||
*
|
||||
* Author: Miran Grca, <mgrca8@gmail.com>
|
||||
* Copyright 2016-2017 Miran Grca.
|
||||
*/
|
||||
|
||||
#define UNICODE
|
||||
#define _WIN32_WINNT 0x0501
|
||||
#define BITMAP WINDOWS_BITMAP
|
||||
#include <windows.h>
|
||||
#include <windowsx.h>
|
||||
#undef BITMAP
|
||||
|
||||
#include <commctrl.h>
|
||||
#include <commdlg.h>
|
||||
#include <process.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "../device.h"
|
||||
#include "plat_keyboard.h"
|
||||
|
||||
#include "win.h"
|
||||
|
||||
#ifndef MAPVK_VK_TO_VSC
|
||||
#define MAPVK_VK_TO_VSC 0
|
||||
#endif
|
||||
|
||||
static uint16_t scancode_map[65536];
|
||||
|
||||
/* This is so we can disambiguate scan codes that would otherwise conflict and get
|
||||
passed on incorrectly. */
|
||||
UINT16 convert_scan_code(UINT16 scan_code)
|
||||
{
|
||||
switch (scan_code)
|
||||
{
|
||||
case 0xE001:
|
||||
return 0xF001;
|
||||
case 0xE002:
|
||||
return 0xF002;
|
||||
case 0xE0AA:
|
||||
return 0xF003;
|
||||
case 0xE005:
|
||||
return 0xF005;
|
||||
case 0xE006:
|
||||
return 0xF006;
|
||||
case 0xE007:
|
||||
return 0xF007;
|
||||
case 0xE071:
|
||||
return 0xF008;
|
||||
case 0xE072:
|
||||
return 0xF009;
|
||||
case 0xE07F:
|
||||
return 0xF00A;
|
||||
case 0xE0E1:
|
||||
return 0xF00B;
|
||||
case 0xE0EE:
|
||||
return 0xF00C;
|
||||
case 0xE0F1:
|
||||
return 0xF00D;
|
||||
case 0xE0FE:
|
||||
return 0xF00E;
|
||||
case 0xE0EF:
|
||||
return 0xF00F;
|
||||
|
||||
default:
|
||||
return scan_code;
|
||||
}
|
||||
}
|
||||
|
||||
void get_registry_key_map()
|
||||
{
|
||||
WCHAR *keyName = L"SYSTEM\\CurrentControlSet\\Control\\Keyboard Layout";
|
||||
WCHAR *valueName = L"Scancode Map";
|
||||
unsigned char buf[32768];
|
||||
DWORD bufSize;
|
||||
HKEY hKey;
|
||||
int j;
|
||||
UINT32 *bufEx2;
|
||||
int scMapCount;
|
||||
UINT16 *bufEx;
|
||||
int scancode_unmapped;
|
||||
int scancode_mapped;
|
||||
|
||||
/* First, prepare the default scan code map list which is 1:1.
|
||||
Remappings will be inserted directly into it.
|
||||
65536 bytes so scan codes fit in easily and it's easy to find what each maps too,
|
||||
since each array element is a scan code and provides for E0, etc. ones too. */
|
||||
for (j = 0; j < 65536; j++)
|
||||
scancode_map[j] = convert_scan_code(j);
|
||||
|
||||
bufSize = 32768;
|
||||
/* Get the scan code remappings from:
|
||||
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout */
|
||||
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyName, 0, 1, &hKey) == ERROR_SUCCESS)
|
||||
{
|
||||
if(RegQueryValueEx(hKey, valueName, NULL, NULL, buf, &bufSize) == ERROR_SUCCESS)
|
||||
{
|
||||
bufEx2 = (UINT32 *) buf;
|
||||
scMapCount = bufEx2[2];
|
||||
if ((bufSize != 0) && (scMapCount != 0))
|
||||
{
|
||||
bufEx = (UINT16 *) (buf + 12);
|
||||
for (j = 0; j < scMapCount*2; j += 2)
|
||||
{
|
||||
/* Each scan code is 32-bit: 16 bits of remapped scan code,
|
||||
and 16 bits of original scan code. */
|
||||
scancode_unmapped = bufEx[j + 1];
|
||||
scancode_mapped = bufEx[j];
|
||||
|
||||
scancode_mapped = convert_scan_code(scancode_mapped);
|
||||
|
||||
/* Fixes scan code map logging. */
|
||||
scancode_map[scancode_unmapped] = scancode_mapped;
|
||||
}
|
||||
}
|
||||
}
|
||||
RegCloseKey(hKey);
|
||||
}
|
||||
}
|
||||
|
||||
void process_raw_input(LPARAM lParam, int infocus)
|
||||
{
|
||||
uint32_t ri_size = 0;
|
||||
UINT size;
|
||||
RAWINPUT *raw;
|
||||
USHORT scancode;
|
||||
|
||||
if (!infocus)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &size, sizeof(RAWINPUTHEADER));
|
||||
|
||||
raw = malloc(size);
|
||||
|
||||
if (raw == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Here we read the raw input data for the keyboard */
|
||||
ri_size = GetRawInputData((HRAWINPUT)(lParam), RID_INPUT, raw, &size, sizeof(RAWINPUTHEADER));
|
||||
|
||||
if(ri_size != size)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* If the input is keyboard, we process it */
|
||||
if (raw->header.dwType == RIM_TYPEKEYBOARD)
|
||||
{
|
||||
RAWKEYBOARD rawKB = raw->data.keyboard;
|
||||
scancode = rawKB.MakeCode;
|
||||
|
||||
/* If it's not a scan code that starts with 0xE1 */
|
||||
if (!(rawKB.Flags & RI_KEY_E1))
|
||||
{
|
||||
if (rawKB.Flags & RI_KEY_E0)
|
||||
{
|
||||
scancode |= (0xE0 << 8);
|
||||
}
|
||||
|
||||
/* Remap it according to the list from the Registry */
|
||||
scancode = scancode_map[scancode];
|
||||
|
||||
if ((scancode >> 8) == 0xF0)
|
||||
{
|
||||
scancode |= 0x100; /* Extended key code in disambiguated format */
|
||||
}
|
||||
else if ((scancode >> 8) == 0xE0)
|
||||
{
|
||||
scancode |= 0x80; /* Normal extended key code */
|
||||
}
|
||||
|
||||
/* If it's not 0 (therefore not 0xE1, 0xE2, etc),
|
||||
then pass it on to the rawinputkey array */
|
||||
if (!(scancode & 0xf00))
|
||||
{
|
||||
recv_key[scancode & 0x1ff] = !(rawKB.Flags & RI_KEY_BREAK);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (rawKB.MakeCode == 0x1D)
|
||||
{
|
||||
scancode = 0xFF;
|
||||
}
|
||||
if (!(scancode & 0xf00))
|
||||
{
|
||||
recv_key[scancode & 0x1ff] = !(rawKB.Flags & RI_KEY_BREAK);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(raw);
|
||||
}
|
||||
373
src/win/win_language.c
Normal file
@@ -0,0 +1,373 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Windows localization core.
|
||||
*
|
||||
* Version: @(#)win_language.c 1.0.1 2017/08/24
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Copyright 2008-2017 Sarah Walker.
|
||||
* Copyright 2016,2017 Miran Grca.
|
||||
*/
|
||||
#include <inttypes.h>
|
||||
#define UNICODE
|
||||
#define BITMAP WINDOWS_BITMAP
|
||||
#include <windows.h>
|
||||
#include <windowsx.h>
|
||||
#include <shlobj.h>
|
||||
#undef BITMAP
|
||||
|
||||
#include <commdlg.h>
|
||||
|
||||
#include "../ibm.h"
|
||||
#include "../device.h"
|
||||
#include "plat_ui.h"
|
||||
#include "win.h"
|
||||
#include "win_language.h"
|
||||
|
||||
|
||||
LCID dwLanguage;
|
||||
|
||||
uint32_t dwLangID, dwSubLangID;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
WCHAR lpString[512];
|
||||
} resource_string_t;
|
||||
|
||||
resource_string_t *lpResourceString2048;
|
||||
resource_string_t *lpResourceString3072;
|
||||
resource_string_t *lpResourceString4096;
|
||||
resource_string_t *lpResourceString4352;
|
||||
resource_string_t *lpResourceString4608;
|
||||
resource_string_t *lpResourceString5120;
|
||||
resource_string_t *lpResourceString5376;
|
||||
resource_string_t *lpResourceString5632;
|
||||
resource_string_t *lpResourceString6144;
|
||||
|
||||
char openfilestring[260];
|
||||
WCHAR wopenfilestring[260];
|
||||
|
||||
void win_language_set()
|
||||
{
|
||||
SetThreadLocale(dwLanguage);
|
||||
}
|
||||
|
||||
void win_language_load_common_strings()
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
lpResourceString2048 = (resource_string_t *) malloc(STRINGS_NUM_2048 * sizeof(resource_string_t));
|
||||
lpResourceString3072 = (resource_string_t *) malloc(STRINGS_NUM_3072 * sizeof(resource_string_t));
|
||||
lpResourceString4096 = (resource_string_t *) malloc(STRINGS_NUM_4096 * sizeof(resource_string_t));
|
||||
lpResourceString4352 = (resource_string_t *) malloc(STRINGS_NUM_4352 * sizeof(resource_string_t));
|
||||
lpResourceString4608 = (resource_string_t *) malloc(STRINGS_NUM_4608 * sizeof(resource_string_t));
|
||||
lpResourceString5120 = (resource_string_t *) malloc(STRINGS_NUM_5120 * sizeof(resource_string_t));
|
||||
lpResourceString5376 = (resource_string_t *) malloc(STRINGS_NUM_5376 * sizeof(resource_string_t));
|
||||
lpResourceString5632 = (resource_string_t *) malloc(STRINGS_NUM_5632 * sizeof(resource_string_t));
|
||||
lpResourceString6144 = (resource_string_t *) malloc(STRINGS_NUM_6144 * sizeof(resource_string_t));
|
||||
|
||||
for (i = 0; i < STRINGS_NUM_2048; i++)
|
||||
{
|
||||
LoadString(hinstance, 2048 + i, lpResourceString2048[i].lpString, 512);
|
||||
}
|
||||
|
||||
for (i = 0; i < STRINGS_NUM_3072; i++)
|
||||
{
|
||||
LoadString(hinstance, 3072 + i, lpResourceString3072[i].lpString, 512);
|
||||
}
|
||||
|
||||
for (i = 0; i < STRINGS_NUM_4096; i++)
|
||||
{
|
||||
LoadString(hinstance, 4096 + i, lpResourceString4096[i].lpString, 512);
|
||||
}
|
||||
|
||||
for (i = 0; i < STRINGS_NUM_4352; i++)
|
||||
{
|
||||
LoadString(hinstance, 4352 + i, lpResourceString4352[i].lpString, 512);
|
||||
}
|
||||
|
||||
for (i = 0; i < STRINGS_NUM_4608; i++)
|
||||
{
|
||||
LoadString(hinstance, 4608 + i, lpResourceString4608[i].lpString, 512);
|
||||
}
|
||||
|
||||
for (i = 0; i < STRINGS_NUM_5120; i++)
|
||||
{
|
||||
LoadString(hinstance, 5120 + i, lpResourceString5120[i].lpString, 512);
|
||||
}
|
||||
|
||||
for (i = 0; i < STRINGS_NUM_5376; i++)
|
||||
{
|
||||
LoadString(hinstance, 5376 + i, lpResourceString5376[i].lpString, 512);
|
||||
}
|
||||
|
||||
for (i = 0; i < STRINGS_NUM_5632; i++)
|
||||
{
|
||||
LoadString(hinstance, 5632 + i, lpResourceString5632[i].lpString, 512);
|
||||
}
|
||||
|
||||
for (i = 0; i < STRINGS_NUM_6144; i++)
|
||||
{
|
||||
LoadString(hinstance, 6144 + i, lpResourceString6144[i].lpString, 512);
|
||||
}
|
||||
}
|
||||
|
||||
LPTSTR win_language_get_settings_category(int i)
|
||||
{
|
||||
return lpResourceString2048[17 + i].lpString;
|
||||
}
|
||||
|
||||
void win_language_update()
|
||||
{
|
||||
win_language_set();
|
||||
win_menu_update();
|
||||
win_language_load_common_strings();
|
||||
}
|
||||
|
||||
void win_language_check()
|
||||
{
|
||||
LCID dwLanguageNew = MAKELCID(dwLangID, dwSubLangID);
|
||||
if (dwLanguageNew != dwLanguage)
|
||||
{
|
||||
dwLanguage = dwLanguageNew;
|
||||
win_language_update();
|
||||
}
|
||||
}
|
||||
|
||||
LPTSTR win_language_get_string_from_id(int i)
|
||||
{
|
||||
if ((i >= 2048) && (i <= 3071))
|
||||
{
|
||||
return lpResourceString2048[i - 2048].lpString;
|
||||
}
|
||||
else if ((i >= 3072) && (i <= 4095))
|
||||
{
|
||||
return lpResourceString3072[i - 3072].lpString;
|
||||
}
|
||||
else if ((i >= 4096) && (i <= 4351))
|
||||
{
|
||||
return lpResourceString4096[i - 4096].lpString;
|
||||
}
|
||||
else if ((i >= 4352) && (i <= 4607))
|
||||
{
|
||||
return lpResourceString4352[i - 4352].lpString;
|
||||
}
|
||||
else if ((i >= 4608) && (i <= 5119))
|
||||
{
|
||||
return lpResourceString4608[i - 4608].lpString;
|
||||
}
|
||||
else if ((i >= 5120) && (i <= 5375))
|
||||
{
|
||||
return lpResourceString5120[i - 5120].lpString;
|
||||
}
|
||||
else if ((i >= 5376) && (i <= 5631))
|
||||
{
|
||||
return lpResourceString5376[i - 5376].lpString;
|
||||
}
|
||||
else if ((i >= 5632) && (i <= 6143))
|
||||
{
|
||||
return lpResourceString5632[i - 5632].lpString;
|
||||
}
|
||||
else
|
||||
{
|
||||
return lpResourceString6144[i - 6144].lpString;
|
||||
}
|
||||
}
|
||||
|
||||
wchar_t *plat_get_string_from_id(int i)
|
||||
{
|
||||
return (wchar_t *) win_language_get_string_from_id(i);
|
||||
}
|
||||
|
||||
LPTSTR win_language_get_string_from_string(char *str)
|
||||
{
|
||||
return win_language_get_string_from_id(atoi(str));
|
||||
}
|
||||
|
||||
int msgbox_reset(HWND hwndParent)
|
||||
{
|
||||
return MessageBox(hwndParent, lpResourceString2048[3].lpString, lpResourceString2048[0].lpString, MB_YESNOCANCEL | MB_ICONQUESTION);
|
||||
}
|
||||
|
||||
int msgbox_reset_yn(HWND hwndParent)
|
||||
{
|
||||
return MessageBox(hwndParent, lpResourceString2048[3].lpString, lpResourceString2048[0].lpString, MB_YESNO | MB_ICONQUESTION);
|
||||
}
|
||||
|
||||
int msgbox_question(HWND hwndParent, int i)
|
||||
{
|
||||
return MessageBox(hwndParent, win_language_get_string_from_id(i), lpResourceString2048[0].lpString, MB_YESNO | MB_ICONQUESTION);
|
||||
}
|
||||
|
||||
void msgbox_info(HWND hwndParent, int i)
|
||||
{
|
||||
MessageBox(hwndParent, win_language_get_string_from_id(i), lpResourceString2048[0].lpString, MB_OK | MB_ICONINFORMATION);
|
||||
}
|
||||
|
||||
void msgbox_info_wstr(HWND hwndParent, WCHAR *wstr)
|
||||
{
|
||||
MessageBox(hwndParent, wstr, lpResourceString2048[0].lpString, MB_OK | MB_ICONINFORMATION);
|
||||
}
|
||||
|
||||
void msgbox_error(HWND hwndParent, int i)
|
||||
{
|
||||
MessageBox(hwndParent, win_language_get_string_from_id(i), lpResourceString2048[1].lpString, MB_OK | MB_ICONWARNING);
|
||||
}
|
||||
|
||||
void plat_msgbox_error(int i)
|
||||
{
|
||||
msgbox_error(ghwnd, i);
|
||||
}
|
||||
|
||||
void msgbox_error_wstr(HWND hwndParent, WCHAR *wstr)
|
||||
{
|
||||
MessageBox(hwndParent, wstr, lpResourceString2048[1].lpString, MB_OK | MB_ICONWARNING);
|
||||
}
|
||||
|
||||
void msgbox_critical(HWND hwndParent, int i)
|
||||
{
|
||||
MessageBox(hwndParent, win_language_get_string_from_id(i), lpResourceString2048[2].lpString, MB_OK | MB_ICONERROR);
|
||||
}
|
||||
|
||||
void msgbox_fatal(HWND hwndParent, char *string)
|
||||
{
|
||||
LPTSTR lptsTemp;
|
||||
lptsTemp = (LPTSTR) malloc(512);
|
||||
|
||||
mbstowcs(lptsTemp, string, strlen(string) + 1);
|
||||
|
||||
MessageBox(hwndParent, lptsTemp, lpResourceString2048[2].lpString, MB_OK | MB_ICONERROR);
|
||||
|
||||
free(lptsTemp);
|
||||
}
|
||||
|
||||
void plat_msgbox_fatal(char *string)
|
||||
{
|
||||
msgbox_fatal(ghwnd, string);
|
||||
}
|
||||
|
||||
int file_dlg_w(HWND hwnd, WCHAR *f, WCHAR *fn, int save)
|
||||
{
|
||||
OPENFILENAME ofn; /* common dialog box structure */
|
||||
BOOL r;
|
||||
DWORD err;
|
||||
|
||||
/* Initialize OPENFILENAME */
|
||||
ZeroMemory(&ofn, sizeof(ofn));
|
||||
ofn.lStructSize = sizeof(ofn);
|
||||
ofn.hwndOwner = hwnd;
|
||||
ofn.lpstrFile = wopenfilestring;
|
||||
/*
|
||||
Set lpstrFile[0] to '\0' so that GetOpenFileName does not
|
||||
use the contents of szFile to initialize itself.
|
||||
*/
|
||||
memcpy(ofn.lpstrFile, fn, (wcslen(fn) << 1) + 2);
|
||||
ofn.nMaxFile = 259;
|
||||
ofn.lpstrFilter = f;
|
||||
ofn.nFilterIndex = 1;
|
||||
ofn.lpstrFileTitle = NULL;
|
||||
ofn.nMaxFileTitle = 0;
|
||||
ofn.lpstrInitialDir = NULL;
|
||||
ofn.Flags = OFN_PATHMUSTEXIST;
|
||||
if (!save)
|
||||
{
|
||||
ofn.Flags |= OFN_FILEMUSTEXIST;
|
||||
}
|
||||
|
||||
/* Display the Open dialog box. */
|
||||
|
||||
if (save)
|
||||
{
|
||||
pclog("GetSaveFileName - lpstrFile = %s\n", ofn.lpstrFile);
|
||||
r = GetSaveFileName(&ofn);
|
||||
}
|
||||
else
|
||||
{
|
||||
pclog("GetOpenFileName - lpstrFile = %s\n", ofn.lpstrFile);
|
||||
r = GetOpenFileName(&ofn);
|
||||
}
|
||||
if (r)
|
||||
{
|
||||
wcstombs(openfilestring, wopenfilestring, sizeof(openfilestring));
|
||||
pclog("File dialog return true\n");
|
||||
return 0;
|
||||
}
|
||||
pclog("File dialog return false\n");
|
||||
err = CommDlgExtendedError();
|
||||
pclog("CommDlgExtendedError return %04X\n", err);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int file_dlg(HWND hwnd, WCHAR *f, char *fn, int save)
|
||||
{
|
||||
WCHAR ufn[512];
|
||||
mbstowcs(ufn, fn, strlen(fn) + 1);
|
||||
return file_dlg_w(hwnd, f, ufn, save);
|
||||
}
|
||||
|
||||
int file_dlg_mb(HWND hwnd, char *f, char *fn, int save)
|
||||
{
|
||||
WCHAR uf[512];
|
||||
WCHAR ufn[512];
|
||||
mbstowcs(uf, f, strlen(fn) + 1);
|
||||
mbstowcs(ufn, fn, strlen(fn) + 1);
|
||||
return file_dlg_w(hwnd, uf, ufn, save);
|
||||
}
|
||||
|
||||
int file_dlg_w_st(HWND hwnd, int i, WCHAR *fn, int save)
|
||||
{
|
||||
return file_dlg_w(hwnd, win_language_get_string_from_id(i), fn, save);
|
||||
}
|
||||
|
||||
int file_dlg_st(HWND hwnd, int i, char *fn, int save)
|
||||
{
|
||||
return file_dlg(hwnd, win_language_get_string_from_id(i), fn, save);
|
||||
}
|
||||
|
||||
static int CALLBACK BrowseCallbackProc(HWND hwnd,UINT uMsg, LPARAM lParam, LPARAM lpData)
|
||||
{
|
||||
if(uMsg == BFFM_INITIALIZED)
|
||||
{
|
||||
SendMessage(hwnd, BFFM_SETSELECTION, TRUE, lpData);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
WCHAR path[MAX_PATH];
|
||||
|
||||
wchar_t *BrowseFolder(wchar_t *saved_path, wchar_t *title)
|
||||
{
|
||||
BROWSEINFO bi = { 0 };
|
||||
bi.lpszTitle = title;
|
||||
bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE;
|
||||
bi.lpfn = BrowseCallbackProc;
|
||||
bi.lParam = (LPARAM) saved_path;
|
||||
|
||||
LPITEMIDLIST pidl = SHBrowseForFolder(&bi);
|
||||
|
||||
if (pidl != 0)
|
||||
{
|
||||
/* Get the name of the folder and put it in path. */
|
||||
SHGetPathFromIDList(pidl, path);
|
||||
|
||||
/* Free memory used. */
|
||||
IMalloc *imalloc = 0;
|
||||
if (SUCCEEDED(SHGetMalloc(&imalloc)))
|
||||
{
|
||||
imalloc->lpVtbl->Free(imalloc, pidl);
|
||||
imalloc->lpVtbl->Release(imalloc);
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
return L"";
|
||||
}
|
||||
54
src/win/win_language.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Windows localization core.
|
||||
*
|
||||
* Version: @(#)win_language.h 1.0.0 2017/05/30
|
||||
*
|
||||
* Author: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Copyright 2008-2017 Sarah Walker.
|
||||
* Copyright 2016-2017 Miran Grca.
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
LCID dwLanguage;
|
||||
|
||||
int msgbox_reset(HWND hwndParent);
|
||||
int msgbox_reset_yn(HWND hwndParent);
|
||||
int msgbox_question(HWND hwndParent, int i);
|
||||
void msgbox_info(HWND hwndParent, int i);
|
||||
void msgbox_info_wstr(HWND hwndParent, WCHAR *wstr);
|
||||
void msgbox_error(HWND hwndParent, int i);
|
||||
void msgbox_error_wstr(HWND hwndParent, WCHAR *wstr);
|
||||
void msgbox_fatal(HWND hwndParent, char *string);
|
||||
void msgbox_critical(HWND hwndParent, int i);
|
||||
|
||||
int file_dlg_w(HWND hwnd, WCHAR *f, WCHAR *fn, int save);
|
||||
int file_dlg(HWND hwnd, WCHAR *f, char *fn, int save);
|
||||
int file_dlg_mb(HWND hwnd, char *f, char *fn, int save);
|
||||
int file_dlg_w_st(HWND hwnd, int i, WCHAR *fn, int save);
|
||||
int file_dlg_st(HWND hwnd, int i, char *fn, int save);
|
||||
|
||||
void win_language_load_common_strings();
|
||||
LPTSTR win_language_get_settings_category(int i);
|
||||
|
||||
void win_language_update();
|
||||
void win_language_check();
|
||||
|
||||
LPTSTR win_language_get_string_from_id(int i);
|
||||
LPTSTR win_language_get_string_from_string(char *str);
|
||||
|
||||
wchar_t *BrowseFolder(wchar_t *saved_path, wchar_t *title);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
125
src/win/win_midi.c
Normal file
@@ -0,0 +1,125 @@
|
||||
#include <windows.h>
|
||||
#include <mmsystem.h>
|
||||
#include "../ibm.h"
|
||||
#include "../config.h"
|
||||
#include "../sound/midi.h"
|
||||
#include "plat_midi.h"
|
||||
|
||||
int midi_id = 0;
|
||||
static HMIDIOUT midi_out_device = NULL;
|
||||
|
||||
HANDLE m_event;
|
||||
|
||||
static uint8_t midi_rt_buf[1024];
|
||||
static uint8_t midi_cmd_buf[1024];
|
||||
static int midi_cmd_pos = 0;
|
||||
static int midi_cmd_len = 0;
|
||||
static uint8_t midi_status = 0;
|
||||
static unsigned int midi_sysex_start = 0;
|
||||
static unsigned int midi_sysex_delay = 0;
|
||||
|
||||
void plat_midi_init()
|
||||
{
|
||||
/* This is for compatibility with old configuration files. */
|
||||
midi_id = config_get_int("Sound", "midi_host_device", -1);
|
||||
if (midi_id == -1)
|
||||
{
|
||||
midi_id = config_get_int(SYSTEM_MIDI_NAME, "midi", 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
config_delete_var("Sound", "midi_host_device");
|
||||
config_set_int(SYSTEM_MIDI_NAME, "midi", midi_id);
|
||||
}
|
||||
|
||||
MMRESULT hr = MMSYSERR_NOERROR;
|
||||
|
||||
memset(midi_rt_buf, 0, sizeof(midi_rt_buf));
|
||||
memset(midi_cmd_buf, 0, sizeof(midi_cmd_buf));
|
||||
|
||||
midi_cmd_pos = midi_cmd_len = 0;
|
||||
midi_status = 0;
|
||||
|
||||
midi_sysex_start = midi_sysex_delay = 0;
|
||||
|
||||
m_event = CreateEvent(NULL, TRUE, TRUE, NULL);
|
||||
|
||||
hr = midiOutOpen(&midi_out_device, midi_id, (DWORD) m_event,
|
||||
0, CALLBACK_EVENT);
|
||||
if (hr != MMSYSERR_NOERROR) {
|
||||
printf("midiOutOpen error - %08X\n",hr);
|
||||
midi_id = 0;
|
||||
hr = midiOutOpen(&midi_out_device, midi_id, (DWORD) m_event,
|
||||
0, CALLBACK_EVENT);
|
||||
if (hr != MMSYSERR_NOERROR) {
|
||||
printf("midiOutOpen error - %08X\n",hr);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
midiOutReset(midi_out_device);
|
||||
}
|
||||
|
||||
void plat_midi_close()
|
||||
{
|
||||
if (midi_out_device != NULL)
|
||||
{
|
||||
midiOutReset(midi_out_device);
|
||||
midiOutClose(midi_out_device);
|
||||
/* midi_out_device = NULL; */
|
||||
CloseHandle(m_event);
|
||||
}
|
||||
}
|
||||
|
||||
int plat_midi_get_num_devs()
|
||||
{
|
||||
return midiOutGetNumDevs();
|
||||
}
|
||||
void plat_midi_get_dev_name(int num, char *s)
|
||||
{
|
||||
MIDIOUTCAPS caps;
|
||||
|
||||
midiOutGetDevCaps(num, &caps, sizeof(caps));
|
||||
strcpy(s, caps.szPname);
|
||||
}
|
||||
|
||||
void plat_midi_play_msg(uint8_t *msg)
|
||||
{
|
||||
midiOutShortMsg(midi_out_device, *(uint32_t *) msg);
|
||||
}
|
||||
|
||||
MIDIHDR m_hdr;
|
||||
|
||||
void plat_midi_play_sysex(uint8_t *sysex, unsigned int len)
|
||||
{
|
||||
MMRESULT result;
|
||||
|
||||
if (WaitForSingleObject(m_event, 2000) == WAIT_TIMEOUT)
|
||||
{
|
||||
pclog("Can't send MIDI message\n");
|
||||
return;
|
||||
}
|
||||
|
||||
midiOutUnprepareHeader(midi_out_device, &m_hdr, sizeof(m_hdr));
|
||||
|
||||
m_hdr.lpData = (char *) sysex;
|
||||
m_hdr.dwBufferLength = len;
|
||||
m_hdr.dwBytesRecorded = len;
|
||||
m_hdr.dwUser = 0;
|
||||
|
||||
result = midiOutPrepareHeader(midi_out_device, &m_hdr, sizeof(m_hdr));
|
||||
|
||||
if (result != MMSYSERR_NOERROR) return;
|
||||
ResetEvent(m_event);
|
||||
result = midiOutLongMsg(midi_out_device, &m_hdr, sizeof(m_hdr));
|
||||
if (result != MMSYSERR_NOERROR)
|
||||
{
|
||||
SetEvent(m_event);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int plat_midi_write(uint8_t val)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
96
src/win/win_mouse.cc
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Mouse interface to host device.
|
||||
*
|
||||
* Version: @(#)win_mouse.cc 1.0.1 2017/06/21
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Copyright 2008-2017 Sarah Walker.
|
||||
* Copyright 2016-2017 Miran Grca.
|
||||
*/
|
||||
#define DIRECTINPUT_VERSION 0x0800
|
||||
#include <dinput.h>
|
||||
#include <stdint.h>
|
||||
#include "plat_mouse.h"
|
||||
#include "win.h"
|
||||
|
||||
|
||||
extern "C" int video_fullscreen;
|
||||
|
||||
extern "C" void fatal(const char *format, ...);
|
||||
extern "C" void pclog(const char *format, ...);
|
||||
|
||||
extern "C" void mouse_init(void);
|
||||
extern "C" void mouse_close(void);
|
||||
extern "C" void mouse_poll_host(void);
|
||||
extern "C" void mouse_get_mickeys(int *x, int *y, int *z);
|
||||
|
||||
|
||||
static LPDIRECTINPUT8 lpdi;
|
||||
static LPDIRECTINPUTDEVICE8 lpdi_mouse = NULL;
|
||||
static DIMOUSESTATE mousestate;
|
||||
static int mouse_x = 0, mouse_y = 0, mouse_z = 0;
|
||||
int mouse_buttons = 0;
|
||||
|
||||
|
||||
void mouse_init(void)
|
||||
{
|
||||
atexit(mouse_close);
|
||||
|
||||
if (FAILED(DirectInput8Create(hinstance, DIRECTINPUT_VERSION, IID_IDirectInput8A, (void **) &lpdi, NULL)))
|
||||
fatal("mouse_init : DirectInputCreate failed\n");
|
||||
if (FAILED(lpdi->CreateDevice(GUID_SysMouse, &lpdi_mouse, NULL)))
|
||||
fatal("mouse_init : CreateDevice failed\n");
|
||||
if (FAILED(lpdi_mouse->SetCooperativeLevel(ghwnd, DISCL_FOREGROUND | (video_fullscreen ? DISCL_EXCLUSIVE : DISCL_NONEXCLUSIVE))))
|
||||
fatal("mouse_init : SetCooperativeLevel failed\n");
|
||||
if (FAILED(lpdi_mouse->SetDataFormat(&c_dfDIMouse)))
|
||||
fatal("mouse_init : SetDataFormat failed\n");
|
||||
}
|
||||
|
||||
|
||||
void mouse_close(void)
|
||||
{
|
||||
if (lpdi_mouse)
|
||||
{
|
||||
lpdi_mouse->Release();
|
||||
lpdi_mouse = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void mouse_poll_host(void)
|
||||
{
|
||||
if (FAILED(lpdi_mouse->GetDeviceState(sizeof(DIMOUSESTATE), (LPVOID)&mousestate)))
|
||||
{
|
||||
lpdi_mouse->Acquire();
|
||||
lpdi_mouse->GetDeviceState(sizeof(DIMOUSESTATE), (LPVOID)&mousestate);
|
||||
}
|
||||
mouse_buttons = 0;
|
||||
if (mousestate.rgbButtons[0] & 0x80)
|
||||
mouse_buttons |= 1;
|
||||
if (mousestate.rgbButtons[1] & 0x80)
|
||||
mouse_buttons |= 2;
|
||||
if (mousestate.rgbButtons[2] & 0x80)
|
||||
mouse_buttons |= 4;
|
||||
mouse_x += mousestate.lX;
|
||||
mouse_y += mousestate.lY;
|
||||
mouse_z += mousestate.lZ/120;
|
||||
if (!mousecapture && !video_fullscreen)
|
||||
mouse_x = mouse_y = mouse_buttons = 0;
|
||||
}
|
||||
|
||||
|
||||
void mouse_get_mickeys(int *x, int *y, int *z)
|
||||
{
|
||||
*x = mouse_x;
|
||||
*y = mouse_y;
|
||||
*z = mouse_z;
|
||||
mouse_x = mouse_y = mouse_z = 0;
|
||||
}
|
||||
213
src/win/win_opendir.c
Normal file
@@ -0,0 +1,213 @@
|
||||
/*
|
||||
* 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 POSIX OpenDir(3) and friends for Win32 API.
|
||||
*
|
||||
* Based on old original code @(#)dir_win32.c 1.2.0 2007/04/19
|
||||
*
|
||||
* Version: @(#)win_opendir.c 1.0.1 2017/05/17
|
||||
*
|
||||
* Author: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Copyright 1998-2007 MicroWalt Corporation
|
||||
* Copyright 2017 Fred N. van Kempen
|
||||
*/
|
||||
#define UNICODE
|
||||
#include <windows.h>
|
||||
#include <io.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "../ibm.h"
|
||||
#include "plat_dir.h"
|
||||
|
||||
|
||||
#ifdef UNICODE
|
||||
# define SUFFIX L"\\*"
|
||||
# define FINDATA struct _wfinddata_t
|
||||
# define FINDFIRST _wfindfirst
|
||||
# define FINDNEXT _wfindnext
|
||||
#else
|
||||
# define SUFFIX "\\*"
|
||||
# define FINDATA struct _finddata_t
|
||||
# define FINDFIRST _findfirst
|
||||
# define FINDNEXT _findnext
|
||||
#endif
|
||||
|
||||
|
||||
/* Open a directory. */
|
||||
DIR *
|
||||
#ifdef UNICODE
|
||||
opendirw(const wchar_t *name)
|
||||
#else
|
||||
opendir(const char *name)
|
||||
#endif
|
||||
{
|
||||
DIR *p;
|
||||
|
||||
/* Create a new control structure. */
|
||||
p = (DIR *) malloc(sizeof(DIR));
|
||||
if (p == NULL)
|
||||
return(NULL);
|
||||
memset(p, 0x00, sizeof(DIR));
|
||||
p->flags = (DIR_F_LOWER | DIR_F_SANE);
|
||||
p->offset = 0;
|
||||
p->sts = 0;
|
||||
|
||||
/* Create a work area. */
|
||||
p->dta = (char *)malloc(sizeof(FINDATA));
|
||||
if (p->dta == NULL) {
|
||||
free(p);
|
||||
return(NULL);
|
||||
}
|
||||
memset(p->dta, 0x00, sizeof(struct _finddata_t));
|
||||
|
||||
/* Add search filespec. */
|
||||
#ifdef UNICODE
|
||||
wcscpy(p->dir, name);
|
||||
wcscat(p->dir, SUFFIX);
|
||||
#else
|
||||
strcpy(p->dir, name);
|
||||
strcat(p->dir, SUFFIX);
|
||||
#endif
|
||||
|
||||
/* Special case: flag if we are in the root directory. */
|
||||
#ifdef UNICODE
|
||||
if (wcslen(p->dir) == 3)
|
||||
#else
|
||||
if (strlen(p->dir) == 3)
|
||||
#endif
|
||||
p->flags |= DIR_F_ISROOT;
|
||||
|
||||
/* Start the searching by doing a FindFirst. */
|
||||
p->handle = FINDFIRST(p->dir, (FINDATA *)p->dta);
|
||||
if (p->handle < 0L) {
|
||||
free(p->dta);
|
||||
free(p);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/* All OK. */
|
||||
return(p);
|
||||
}
|
||||
|
||||
|
||||
/* Close an open directory. */
|
||||
int
|
||||
closedir(DIR *p)
|
||||
{
|
||||
if (p == NULL)
|
||||
return(0);
|
||||
|
||||
_findclose(p->handle);
|
||||
|
||||
if (p->dta != NULL)
|
||||
free(p->dta);
|
||||
free(p);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Read the next entry from a directory.
|
||||
* Note that the DOS (FAT), Windows (FAT, FAT32) and Windows NTFS
|
||||
* file systems do not have a root directory containing the UNIX-
|
||||
* standard "." and ".." entries. Many applications do assume
|
||||
* this anyway, so we simply fake these entries.
|
||||
*/
|
||||
struct direct *
|
||||
readdir(DIR *p)
|
||||
{
|
||||
FINDATA *ffp;
|
||||
|
||||
if (p == NULL || p->sts == 1)
|
||||
return(NULL);
|
||||
|
||||
/* Format structure with current data. */
|
||||
ffp = (FINDATA *)p->dta;
|
||||
p->dent.d_ino = 1L;
|
||||
p->dent.d_off = p->offset++;
|
||||
switch(p->offset) {
|
||||
case 1: /* . */
|
||||
#ifdef UNICODE
|
||||
wcsncpy(p->dent.d_name, L".", MAXNAMLEN+1);
|
||||
#else
|
||||
strncpy(p->dent.d_name, ".", MAXNAMLEN+1);
|
||||
#endif
|
||||
p->dent.d_reclen = 1;
|
||||
break;
|
||||
|
||||
case 2: /* .. */
|
||||
#ifdef UNICODE
|
||||
wcsncpy(p->dent.d_name, L"..", MAXNAMLEN+1);
|
||||
#else
|
||||
strncpy(p->dent.d_name, "..", MAXNAMLEN+1);
|
||||
#endif
|
||||
p->dent.d_reclen = 2;
|
||||
break;
|
||||
|
||||
default: /* regular entry. */
|
||||
#ifdef UNICODE
|
||||
wcsncpy(p->dent.d_name, ffp->name, MAXNAMLEN+1);
|
||||
#else
|
||||
strncpy(p->dent.d_name, ffp->name, MAXNAMLEN+1);
|
||||
#endif
|
||||
p->dent.d_reclen = (char) wcslen(p->dent.d_name);
|
||||
}
|
||||
|
||||
/* Read next entry. */
|
||||
p->sts = 0;
|
||||
|
||||
/* Fake the "." and ".." entries here.. */
|
||||
if ((p->flags & DIR_F_ISROOT) && (p->offset <= 2))
|
||||
return(&(p->dent));
|
||||
|
||||
/* Get the next entry if we did not fake the above. */
|
||||
if (FINDNEXT(p->handle, ffp) < 0)
|
||||
p->sts = 1;
|
||||
|
||||
return(&(p->dent));
|
||||
}
|
||||
|
||||
|
||||
/* Report current position within the directory. */
|
||||
long
|
||||
telldir(DIR *p)
|
||||
{
|
||||
return(p->offset);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
seekdir(DIR *p, long newpos)
|
||||
{
|
||||
short pos;
|
||||
|
||||
/* First off, rewind to start of directory. */
|
||||
p->handle = FINDFIRST(p->dir, (FINDATA *)p->dta);
|
||||
if (p->handle < 0L) {
|
||||
p->sts = 1;
|
||||
return;
|
||||
}
|
||||
p->offset = 0;
|
||||
p->sts = 0;
|
||||
|
||||
/* If we are rewinding, that's all... */
|
||||
if (newpos == 0L) return;
|
||||
|
||||
/* Nope.. read entries until we hit the right spot. */
|
||||
pos = (short) newpos;
|
||||
while (p->offset != pos) {
|
||||
p->offset++;
|
||||
if (FINDNEXT(p->handle, (FINDATA *)p->dta) < 0) {
|
||||
p->sts = 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
571
src/win/win_serial.c
Normal file
@@ -0,0 +1,571 @@
|
||||
/*
|
||||
* 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 host serial port services for Win32.
|
||||
*
|
||||
* This code is based on a universal serial port driver for
|
||||
* Windows and UNIX systems, with support for FTDI and Prolific
|
||||
* USB ports. Support for these has been removed.
|
||||
*
|
||||
* Version: @(#)win_serial.c 1.0.3 2017/06/04
|
||||
*
|
||||
* Author: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Copyright 2017 Fred N. van Kempen.
|
||||
*/
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "plat_thread.h"
|
||||
#define BHTTY_C
|
||||
#include "plat_serial.h"
|
||||
|
||||
|
||||
extern void pclog(char *__fmt, ...);
|
||||
|
||||
|
||||
/* Handle the receiving of data from the host port. */
|
||||
static void
|
||||
bhtty_reader(void *arg)
|
||||
{
|
||||
BHTTY *pp = (BHTTY *)arg;
|
||||
unsigned char b;
|
||||
DWORD n;
|
||||
|
||||
pclog("%s: thread started\n", pp->name);
|
||||
|
||||
/* As long as the channel is open.. */
|
||||
while (pp->tid != NULL) {
|
||||
/* Post a READ on the device. */
|
||||
n = 0;
|
||||
if (ReadFile(pp->handle, &b, (DWORD)1, &n, &pp->rov) == FALSE) {
|
||||
n = GetLastError();
|
||||
if (n != ERROR_IO_PENDING) {
|
||||
/* Not good, we got an error. */
|
||||
pclog("%s: I/O error %d in read!\n", pp->name, n);
|
||||
break;
|
||||
}
|
||||
|
||||
/* The read is pending, wait for it.. */
|
||||
if (GetOverlappedResult(pp->handle, &pp->rov, &n, TRUE) == FALSE) {
|
||||
n = GetLastError();
|
||||
pclog("%s: I/O error %d in read!\n", pp->name, n);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pclog("%s: got %d bytes of data\n", pp->name, n);
|
||||
if (n == 1) {
|
||||
/* We got data, update stuff. */
|
||||
if (pp->icnt < sizeof(pp->buff)) {
|
||||
pclog("%s: queued byte %02x (%d)\n", pp->name, b, pp->icnt+1);
|
||||
pp->buff[pp->ihead++] = b;
|
||||
pp->ihead &= (sizeof(pp->buff)-1);
|
||||
pp->icnt++;
|
||||
|
||||
/* Do a callback to let them know. */
|
||||
if (pp->rd_done != NULL)
|
||||
pp->rd_done(pp->rd_arg, n);
|
||||
} else {
|
||||
pclog("%s: RX buffer overrun!\n", pp->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Error or done, clean up. */
|
||||
pp->tid = NULL;
|
||||
pclog("%s: thread stopped.\n", pp->name);
|
||||
}
|
||||
|
||||
|
||||
/* Set the state of a port. */
|
||||
int
|
||||
bhtty_sstate(BHTTY *pp, void *arg)
|
||||
{
|
||||
/* Make sure we can do this. */
|
||||
if (arg == NULL) {
|
||||
pclog("%s: invalid argument\n", pp->name);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
if (SetCommState(pp->handle, (DCB *)arg) == FALSE) {
|
||||
/* Mark an error. */
|
||||
pclog("%s: set state: %d\n", pp->name, GetLastError());
|
||||
return(-1);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/* Fetch the state of a port. */
|
||||
int
|
||||
bhtty_gstate(BHTTY *pp, void *arg)
|
||||
{
|
||||
/* Make sure we can do this. */
|
||||
if (arg == NULL) {
|
||||
pclog("%s: invalid argument\n", pp->name);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
if (GetCommState(pp->handle, (DCB *)arg) == FALSE) {
|
||||
/* Mark an error. */
|
||||
pclog("%s: get state: %d\n", pp->name, GetLastError());
|
||||
return(-1);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/* Enable or disable RTS/CTS mode (hardware handshaking.) */
|
||||
int
|
||||
bhtty_crtscts(BHTTY *pp, char yesno)
|
||||
{
|
||||
/* Get the current mode. */
|
||||
if (bhtty_gstate(pp, &pp->dcb) < 0) return(-1);
|
||||
|
||||
switch(yesno) {
|
||||
case 0: /* disable CRTSCTS */
|
||||
pp->dcb.fOutxDsrFlow = 0; /* disable DSR/DCD mode */
|
||||
pp->dcb.fDsrSensitivity = 0;
|
||||
|
||||
pp->dcb.fOutxCtsFlow = 0; /* disable RTS/CTS mode */
|
||||
|
||||
pp->dcb.fTXContinueOnXoff = 0; /* disable XON/XOFF mode */
|
||||
pp->dcb.fOutX = 0;
|
||||
pp->dcb.fInX = 0;
|
||||
break;
|
||||
|
||||
case 1: /* enable CRTSCTS */
|
||||
pp->dcb.fOutxDsrFlow = 0; /* disable DSR/DCD mode */
|
||||
pp->dcb.fDsrSensitivity = 0;
|
||||
|
||||
pp->dcb.fOutxCtsFlow = 1; /* enable RTS/CTS mode */
|
||||
|
||||
pp->dcb.fTXContinueOnXoff = 0; /* disable XON/XOFF mode */
|
||||
pp->dcb.fOutX = 0;
|
||||
pp->dcb.fInX = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
pclog("%s: invalid parameter '%d'!\n", pp->name, yesno);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/* Set new mode. */
|
||||
if (bhtty_sstate(pp, &pp->dcb) < 0) return(-1);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/* Set the port parameters. */
|
||||
int
|
||||
bhtty_params(BHTTY *pp, char dbit, char par, char sbit)
|
||||
{
|
||||
/* Get the current mode. */
|
||||
if (bhtty_gstate(pp, &pp->dcb) < 0) return(-1);
|
||||
|
||||
/* Set the desired word length. */
|
||||
switch((int)dbit) {
|
||||
case -1: /* no change */
|
||||
break;
|
||||
|
||||
case 5: /* FTDI doesnt like these */
|
||||
case 6:
|
||||
case 9:
|
||||
break;
|
||||
|
||||
case 7:
|
||||
case 8:
|
||||
pp->dcb.ByteSize = dbit;
|
||||
break;
|
||||
|
||||
default:
|
||||
pclog("%s: invalid parameter '%d'!\n", pp->name, dbit);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/* Set the type of parity encoding. */
|
||||
switch((int)par) {
|
||||
case -1: /* no change */
|
||||
case ' ':
|
||||
break;
|
||||
|
||||
case 0:
|
||||
case 'N':
|
||||
pp->dcb.fParity = FALSE;
|
||||
pp->dcb.Parity = NOPARITY;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
case 'O':
|
||||
pp->dcb.fParity = TRUE;
|
||||
pp->dcb.Parity = ODDPARITY;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
case 'E':
|
||||
pp->dcb.fParity = TRUE;
|
||||
pp->dcb.Parity = EVENPARITY;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
case 'M':
|
||||
case 4:
|
||||
case 'S':
|
||||
break;
|
||||
|
||||
default:
|
||||
pclog("%s: invalid parameter '%c'!\n", pp->name, par);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/* Set the number of stop bits. */
|
||||
switch((int)sbit) {
|
||||
case -1: /* no change */
|
||||
break;
|
||||
|
||||
case 1:
|
||||
pp->dcb.StopBits = ONESTOPBIT;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
pp->dcb.StopBits = TWOSTOPBITS;
|
||||
break;
|
||||
|
||||
default:
|
||||
pclog("%s: invalid parameter '%d'!\n", pp->name, sbit);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/* Set new mode. */
|
||||
if (bhtty_sstate(pp, &pp->dcb) < 0) return(-1);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/* Put a port in transparent ("raw") state. */
|
||||
void
|
||||
bhtty_raw(BHTTY *pp, void *arg)
|
||||
{
|
||||
DCB *dcb = (DCB *)arg;
|
||||
|
||||
/* Make sure we can do this. */
|
||||
if (arg == NULL) {
|
||||
pclog("%s: invalid parameter\n", pp->name);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Enable BINARY transparent mode. */
|
||||
dcb->fBinary = 1;
|
||||
dcb->fErrorChar = 0; /* disable Error Replacement */
|
||||
dcb->fNull = 0; /* disable NUL stripping */
|
||||
|
||||
/* Disable the DTR and RTS lines. */
|
||||
dcb->fDtrControl = DTR_CONTROL_DISABLE; /* DTR line */
|
||||
dcb->fRtsControl = RTS_CONTROL_DISABLE; /* RTS line */
|
||||
|
||||
/* Disable DSR/DCD handshaking. */
|
||||
dcb->fOutxDsrFlow = 0; /* DSR handshaking */
|
||||
dcb->fDsrSensitivity = 0; /* DSR Sensitivity */
|
||||
|
||||
/* Disable RTS/CTS handshaking. */
|
||||
dcb->fOutxCtsFlow = 0; /* CTS handshaking */
|
||||
|
||||
/* Disable XON/XOFF handshaking. */
|
||||
dcb->fTXContinueOnXoff = 0; /* continue TX after Xoff */
|
||||
dcb->fOutX = 0; /* enable output X-ON/X-OFF */
|
||||
dcb->fInX = 0; /* enable input X-ON/X-OFF */
|
||||
dcb->XonChar = 0x11; /* ASCII XON */
|
||||
dcb->XoffChar = 0x13; /* ASCII XOFF */
|
||||
dcb->XonLim = 100;
|
||||
dcb->XoffLim = 100;
|
||||
|
||||
dcb->fParity = FALSE;
|
||||
dcb->Parity = NOPARITY;
|
||||
dcb->StopBits = ONESTOPBIT;
|
||||
dcb->BaudRate = CBR_1200;
|
||||
}
|
||||
|
||||
|
||||
/* Set the port speed. */
|
||||
int
|
||||
bhtty_speed(BHTTY *pp, long speed)
|
||||
{
|
||||
/* Get the current mode and speed. */
|
||||
if (bhtty_gstate(pp, &pp->dcb) < 0) return(-1);
|
||||
|
||||
/*
|
||||
* Set speed.
|
||||
*
|
||||
* This is not entirely correct, we should use a table
|
||||
* with DCB_xxx speed values here, but we removed that
|
||||
* and just hardcode the speed value into DCB. --FvK
|
||||
*/
|
||||
pp->dcb.BaudRate = speed;
|
||||
|
||||
/* Set new speed. */
|
||||
if (bhtty_sstate(pp, &pp->dcb) < 0) return(-1);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/* Clean up and flush. */
|
||||
int
|
||||
bhtty_flush(BHTTY *pp)
|
||||
{
|
||||
DWORD dwErrs;
|
||||
COMSTAT cs;
|
||||
|
||||
/* First, clear any errors. */
|
||||
(void)ClearCommError(pp->handle, &dwErrs, &cs);
|
||||
|
||||
/* Now flush all buffers. */
|
||||
if (PurgeComm(pp->handle,
|
||||
(PURGE_RXABORT | PURGE_TXABORT | \
|
||||
PURGE_RXCLEAR | PURGE_TXCLEAR)) == FALSE) {
|
||||
pclog("%s: flush: %d\n", pp->name, GetLastError());
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/* Re-clear any errors. */
|
||||
if (ClearCommError(pp->handle, &dwErrs, &cs) == FALSE) {
|
||||
pclog("%s: clear errors: %d\n", pp->name, GetLastError());
|
||||
return(-1);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/* Close an open serial port. */
|
||||
void
|
||||
bhtty_close(BHTTY *pp)
|
||||
{
|
||||
/* If the polling thread is running, stop it. */
|
||||
(void)bhtty_active(pp, 0);
|
||||
|
||||
/* Close the event handles. */
|
||||
if (pp->rov.hEvent != INVALID_HANDLE_VALUE)
|
||||
CloseHandle(pp->rov.hEvent);
|
||||
if (pp->wov.hEvent != INVALID_HANDLE_VALUE)
|
||||
CloseHandle(pp->wov.hEvent);
|
||||
|
||||
if (pp->handle != INVALID_HANDLE_VALUE) {
|
||||
pclog("%s: closing host port\n", pp->name);
|
||||
|
||||
/* Restore the previous port state, if any. */
|
||||
(void)bhtty_sstate(pp, &pp->odcb);
|
||||
|
||||
/* Close the port. */
|
||||
CloseHandle(pp->handle);
|
||||
pp->handle = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
/* Release the control block. */
|
||||
free(pp);
|
||||
}
|
||||
|
||||
|
||||
/* Open a host serial port for I/O. */
|
||||
BHTTY *
|
||||
bhtty_open(char *port, int tmo)
|
||||
{
|
||||
char temp[84];
|
||||
COMMTIMEOUTS to;
|
||||
COMMCONFIG conf;
|
||||
BHTTY *pp;
|
||||
DWORD d;
|
||||
|
||||
/* First things first... create a control block. */
|
||||
if ((pp = (BHTTY *)malloc(sizeof(BHTTY))) == NULL) {
|
||||
pclog("%s: out of memory!\n", port);
|
||||
return(NULL);
|
||||
}
|
||||
memset(pp, 0x00, sizeof(BHTTY));
|
||||
strncpy(pp->name, port, sizeof(pp->name)-1);
|
||||
|
||||
/* Try a regular Win32 serial port. */
|
||||
sprintf(temp, "\\\\.\\%s", pp->name);
|
||||
if ((pp->handle = CreateFile(temp,
|
||||
(GENERIC_READ|GENERIC_WRITE),
|
||||
0,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
FILE_FLAG_OVERLAPPED,
|
||||
0)) == INVALID_HANDLE_VALUE) {
|
||||
pclog("%s: open port: %d\n", pp->name, GetLastError());
|
||||
free(pp);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/* Create event handles. */
|
||||
pp->rov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
pp->wov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
|
||||
/* Set up buffer size of the port. */
|
||||
if (SetupComm(pp->handle, 32768L, 32768L) == FALSE) {
|
||||
/* This fails on FTDI-based devices. */
|
||||
pclog("%s: set buffers: %d\n", pp->name, GetLastError());
|
||||
#if 0
|
||||
CloseHandle(pp->handle);
|
||||
free(pp);
|
||||
return(NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Grab default config for the driver and set it. */
|
||||
d = sizeof(COMMCONFIG);
|
||||
memset(&conf, 0x00, d);
|
||||
conf.dwSize = d;
|
||||
if (GetDefaultCommConfig(temp, &conf, &d) == TRUE) {
|
||||
/* Change config here... */
|
||||
|
||||
/* Set new configuration. */
|
||||
if (SetCommConfig(pp->handle, &conf, d) == FALSE) {
|
||||
/* This fails on FTDI-based devices. */
|
||||
pclog("%s: set configuration: %d\n", pp->name, GetLastError());
|
||||
#if 0
|
||||
CloseHandle(pp->handle);
|
||||
free(pp);
|
||||
return(NULL);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
pclog("%s: host port '%s' open\n", pp->name, temp);
|
||||
|
||||
/*
|
||||
* We now have an open port. To allow for clean exit
|
||||
* of the application, we first retrieve the port's
|
||||
* current settings, and save these for later.
|
||||
*/
|
||||
if (bhtty_gstate(pp, &pp->odcb) < 0) {
|
||||
(void)bhtty_close(pp);
|
||||
return(NULL);
|
||||
}
|
||||
memcpy(&pp->dcb, &pp->odcb, sizeof(DCB));
|
||||
|
||||
/* Force the port to BINARY mode. */
|
||||
bhtty_raw(pp, &pp->dcb);
|
||||
|
||||
/* Set new state of this port. */
|
||||
if (bhtty_sstate(pp, &pp->dcb) < 0) {
|
||||
(void)bhtty_close(pp);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/* Just to make sure.. disable RTS/CTS mode. */
|
||||
(void)bhtty_crtscts(pp, 0);
|
||||
|
||||
/* Set new timeout values. */
|
||||
if (GetCommTimeouts(pp->handle, &to) == FALSE) {
|
||||
pclog("%s: error %d while getting current TO\n",
|
||||
pp->name, GetLastError());
|
||||
(void)bhtty_close(pp);
|
||||
return(NULL);
|
||||
}
|
||||
if (tmo < 0) {
|
||||
/* No timeout, immediate return. */
|
||||
to.ReadIntervalTimeout = MAXDWORD;
|
||||
to.ReadTotalTimeoutMultiplier = 0;
|
||||
to.ReadTotalTimeoutConstant = 0;
|
||||
} else if (tmo == 0) {
|
||||
/* No timeout, wait for data. */
|
||||
memset(&to, 0x00, sizeof(to));
|
||||
} else {
|
||||
/* Timeout specified. */
|
||||
to.ReadIntervalTimeout = MAXDWORD;
|
||||
to.ReadTotalTimeoutMultiplier = MAXDWORD;
|
||||
to.ReadTotalTimeoutConstant = tmo;
|
||||
}
|
||||
if (SetCommTimeouts(pp->handle, &to) == FALSE) {
|
||||
pclog("%s: error %d while setting TO\n", pp->name, GetLastError());
|
||||
(void)bhtty_close(pp);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/* Clear all errors and flush all buffers. */
|
||||
if (bhtty_flush(pp) < 0) {
|
||||
(void)bhtty_close(pp);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
return(pp);
|
||||
}
|
||||
|
||||
|
||||
/* Activate the I/O for this port. */
|
||||
int
|
||||
bhtty_active(BHTTY *pp, int flg)
|
||||
{
|
||||
if (flg) {
|
||||
pclog("%s: starting thread..\n", pp->name);
|
||||
pp->tid = thread_create(bhtty_reader, pp);
|
||||
} else {
|
||||
if (pp->tid != NULL) {
|
||||
pclog("%s: stopping thread..\n", pp->name);
|
||||
thread_kill(pp->tid);
|
||||
pp->tid = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/* Try to write data to an open port. */
|
||||
int
|
||||
bhtty_write(BHTTY *pp, unsigned char val)
|
||||
{
|
||||
DWORD n = 0;
|
||||
|
||||
pclog("%s: writing byte %02x\n", pp->name, val);
|
||||
if (WriteFile(pp->handle, &val, 1, &n, &pp->wov) == FALSE) {
|
||||
n = GetLastError();
|
||||
if (n != ERROR_IO_PENDING) {
|
||||
/* Not good, we got an error. */
|
||||
pclog("%s: I/O error %d in write!\n", pp->name, n);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/* The write is pending, wait for it.. */
|
||||
if (GetOverlappedResult(pp->handle, &pp->wov, &n, TRUE) == FALSE) {
|
||||
n = GetLastError();
|
||||
pclog("%s: I/O error %d in write!\n", pp->name, n);
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
|
||||
return((int)n);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Try to read data from an open port.
|
||||
*
|
||||
* For now, we will use one byte per call. Eventually,
|
||||
* we should go back to loading a buffer full of data,
|
||||
* just to speed things up a bit. --FvK
|
||||
*/
|
||||
int
|
||||
bhtty_read(BHTTY *pp, unsigned char *bufp, int max)
|
||||
{
|
||||
if (pp->icnt == 0) return(0);
|
||||
|
||||
while (max-- > 0) {
|
||||
*bufp++ = pp->buff[pp->itail++];
|
||||
pclog("%s: dequeued byte %02x (%d)\n", pp->name, *(bufp-1), pp->icnt);
|
||||
pp->itail &= (sizeof(pp->buff)-1);
|
||||
if (--pp->icnt == 0) break;
|
||||
}
|
||||
|
||||
return(max);
|
||||
}
|
||||
4390
src/win/win_settings.c
Normal file
94
src/win/win_status.c
Normal file
@@ -0,0 +1,94 @@
|
||||
/* Copyright holders: Sarah Walker
|
||||
see COPYING for more details
|
||||
*/
|
||||
#define BITMAP WINDOWS_BITMAP
|
||||
#include <windows.h>
|
||||
#include <windowsx.h>
|
||||
#undef BITMAP
|
||||
|
||||
#include "../ibm.h"
|
||||
#include "../mem.h"
|
||||
#include "../cpu/x86_ops.h"
|
||||
#include "../cpu/codegen.h"
|
||||
#include "../device.h"
|
||||
#include "win.h"
|
||||
|
||||
|
||||
HWND status_hwnd;
|
||||
int status_is_open = 0;
|
||||
|
||||
|
||||
extern int sreadlnum, swritelnum, segareads, segawrites, scycles_lost;
|
||||
|
||||
extern uint64_t main_time;
|
||||
static uint64_t status_time;
|
||||
|
||||
|
||||
static BOOL CALLBACK status_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
char device_s[4096];
|
||||
switch (message)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
status_is_open = 1;
|
||||
case WM_USER:
|
||||
{
|
||||
uint64_t new_time = timer_read();
|
||||
uint64_t status_diff = new_time - status_time;
|
||||
status_time = new_time;
|
||||
sprintf(device_s,
|
||||
"CPU speed : %f MIPS\n"
|
||||
"FPU speed : %f MFLOPS\n\n"
|
||||
|
||||
"Video throughput (read) : %i bytes/sec\n"
|
||||
"Video throughput (write) : %i bytes/sec\n\n"
|
||||
"Effective clockspeed : %iHz\n\n"
|
||||
"Timer 0 frequency : %fHz\n\n"
|
||||
"CPU time : %f%% (%f%%)\n"
|
||||
|
||||
"New blocks : %i\nOld blocks : %i\nRecompiled speed : %f MIPS\nAverage size : %f\n"
|
||||
"Flushes : %i\nEvicted : %i\nReused : %i\nRemoved : %i\nReal speed : %f MIPS"
|
||||
,mips,
|
||||
flops,
|
||||
segareads,
|
||||
segawrites,
|
||||
clockrate - scycles_lost,
|
||||
pit_timer0_freq(),
|
||||
((double)main_time * 100.0) / status_diff,
|
||||
((double)main_time * 100.0) / timer_freq
|
||||
|
||||
, cpu_new_blocks_latched, cpu_recomp_blocks_latched, (double)cpu_recomp_ins_latched / 1000000.0, (double)cpu_recomp_ins_latched/cpu_recomp_blocks_latched,
|
||||
cpu_recomp_flushes_latched, cpu_recomp_evicted_latched,
|
||||
cpu_recomp_reuse_latched, cpu_recomp_removed_latched,
|
||||
|
||||
((double)cpu_recomp_ins_latched / 1000000.0) / ((double)main_time / timer_freq)
|
||||
);
|
||||
main_time = 0;
|
||||
SendDlgItemMessage(hdlg, IDT_SDEVICE, WM_SETTEXT, (WPARAM)NULL, (LPARAM)device_s);
|
||||
|
||||
device_s[0] = 0;
|
||||
device_add_status_info(device_s, 4096);
|
||||
SendDlgItemMessage(hdlg, IDT_STEXT, WM_SETTEXT, (WPARAM)NULL, (LPARAM)device_s);
|
||||
}
|
||||
return TRUE;
|
||||
|
||||
case WM_COMMAND:
|
||||
switch (LOWORD(wParam))
|
||||
{
|
||||
case IDOK:
|
||||
case IDCANCEL:
|
||||
status_is_open = 0;
|
||||
EndDialog(hdlg, 0);
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void status_open(HWND hwnd)
|
||||
{
|
||||
status_hwnd = CreateDialog(hinstance, (LPCSTR)DLG_STATUS, hwnd, status_dlgproc);
|
||||
ShowWindow(status_hwnd, SW_SHOW);
|
||||
}
|
||||
57
src/win/win_video.c
Normal file
@@ -0,0 +1,57 @@
|
||||
/* Copyright holders: Sarah Walker
|
||||
see COPYING for more details
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "../video/video.h"
|
||||
#include "win_cgapal.h"
|
||||
|
||||
|
||||
BITMAP *screen;
|
||||
|
||||
|
||||
void hline(BITMAP *b, int x1, int y, int x2, uint32_t col)
|
||||
{
|
||||
if (y < 0 || y >= buffer->h)
|
||||
return;
|
||||
|
||||
if (b == buffer)
|
||||
memset(&b->line[y][x1], col, x2 - x1);
|
||||
else
|
||||
memset(&((uint32_t *)b->line[y])[x1], col, (x2 - x1) * 4);
|
||||
}
|
||||
|
||||
void blit(BITMAP *src, BITMAP *dst, int x1, int y1, int x2, int y2, int xs, int ys)
|
||||
{
|
||||
}
|
||||
|
||||
void stretch_blit(BITMAP *src, BITMAP *dst, int x1, int y1, int xs1, int ys1, int x2, int y2, int xs2, int ys2)
|
||||
{
|
||||
}
|
||||
|
||||
void rectfill(BITMAP *b, int x1, int y1, int x2, int y2, uint32_t col)
|
||||
{
|
||||
}
|
||||
|
||||
void set_palette(PALETTE p)
|
||||
{
|
||||
}
|
||||
|
||||
void destroy_bitmap(BITMAP *b)
|
||||
{
|
||||
}
|
||||
|
||||
BITMAP *create_bitmap(int x, int y)
|
||||
{
|
||||
BITMAP *b = malloc(sizeof(BITMAP) + (y * sizeof(uint8_t *)));
|
||||
int c;
|
||||
b->dat = malloc(x * y * 4);
|
||||
for (c = 0; c < y; c++)
|
||||
{
|
||||
b->line[c] = b->dat + (c * x * 4);
|
||||
}
|
||||
b->w = x;
|
||||
b->h = y;
|
||||
return b;
|
||||
}
|
||||