From 09ca09775c4d03b0223b298c272cd985cac60df4 Mon Sep 17 00:00:00 2001 From: waltje Date: Thu, 18 May 2017 01:57:16 -0400 Subject: [PATCH 1/2] Cleanup of the configuration code, and source tree layout. --- src/86Box.manifest | 22 - src/86Box.rc | 941 -------- src/Makefile.mingw | 32 +- src/SOUND/snd_mpu401.c | 2 +- src/SOUND/snd_sb_dsp.c | 2 +- src/VIDEO/vid_cga.c | 2 +- src/VIDEO/vid_hercules.c | 2 +- src/VIDEO/vid_mda.c | 2 +- src/VIDEO/video.c | 2 +- src/cdrom-dosbox.cpp | 565 ----- src/cdrom-dosbox.h | 173 -- src/cdrom-image.cc | 1045 -------- src/cdrom-image.h | 28 - src/cdrom-ioctl-linux.c | 725 ------ src/cdrom-ioctl.c | 1099 --------- src/cdrom-ioctl.h | 17 - src/cdrom-null.c | 130 - src/cdrom-null.h | 14 - src/config.c | 515 ++-- src/config.h | 50 +- src/gameport.c | 2 +- src/joystick_ch_flightstick_pro.c | 3 +- src/joystick_standard.c | 3 +- src/joystick_sw_pad.c | 3 +- src/joystick_tm_fcs.c | 3 +- src/keyboard.c | 2 +- src/mouse_bus.c | 4 +- src/mouse_ps2.c | 3 +- src/net_ne2000.c | 64 +- src/net_ne2000.h | 9 +- src/net_pcap.c | 40 +- src/net_slirp.c | 27 +- src/network.c | 48 +- src/network.h | 20 +- src/pc.c | 22 +- src/pcap_if.rc | 52 - src/plat-dinput.h | 4 - src/plat-dir.h | 76 - src/plat-joystick.h | 69 - src/plat-keyboard.h | 22 - src/plat-midi.h | 10 - src/plat-mouse.h | 16 - src/plat-serial.h | 49 - src/ppi.c | 5 +- src/resource.h | 432 ---- src/serial.c | 4 +- src/win-cgapal.h | 13 - src/win-crashdump.c | 185 -- src/win-crashdump.h | 7 - src/win-d3d-fs.cc | 587 ----- src/win-d3d-fs.h | 13 - src/win-d3d.cc | 397 ---- src/win-d3d.h | 13 - src/win-ddraw-fs.cc | 338 --- src/win-ddraw-fs.h | 11 - src/win-ddraw-screenshot.cc | 178 -- src/win-ddraw-screenshot.h | 4 - src/win-ddraw.cc | 318 --- src/win-ddraw.h | 12 - src/win-deviceconfig.c | 317 --- src/win-joystick.cc | 281 --- src/win-joystickconfig.c | 541 ----- src/win-language.c | 197 -- src/win-language.h | 33 - src/win-midi.c | 279 --- src/win-mouse.cc | 75 - src/win-opendir.c | 213 -- src/win-serial.c | 606 ----- src/win-settings.c | 3674 ----------------------------- src/win-status.c | 95 - src/win-video.c | 57 - src/win.c | 2427 ------------------- src/win.h | 51 - 73 files changed, 472 insertions(+), 16810 deletions(-) delete mode 100644 src/86Box.manifest delete mode 100644 src/86Box.rc delete mode 100644 src/cdrom-dosbox.cpp delete mode 100644 src/cdrom-dosbox.h delete mode 100644 src/cdrom-image.cc delete mode 100644 src/cdrom-image.h delete mode 100644 src/cdrom-ioctl-linux.c delete mode 100644 src/cdrom-ioctl.c delete mode 100644 src/cdrom-ioctl.h delete mode 100644 src/cdrom-null.c delete mode 100644 src/cdrom-null.h delete mode 100644 src/pcap_if.rc delete mode 100644 src/plat-dinput.h delete mode 100644 src/plat-dir.h delete mode 100644 src/plat-joystick.h delete mode 100644 src/plat-keyboard.h delete mode 100644 src/plat-midi.h delete mode 100644 src/plat-mouse.h delete mode 100644 src/plat-serial.h delete mode 100644 src/resource.h delete mode 100644 src/win-cgapal.h delete mode 100644 src/win-crashdump.c delete mode 100644 src/win-crashdump.h delete mode 100644 src/win-d3d-fs.cc delete mode 100644 src/win-d3d-fs.h delete mode 100644 src/win-d3d.cc delete mode 100644 src/win-d3d.h delete mode 100644 src/win-ddraw-fs.cc delete mode 100644 src/win-ddraw-fs.h delete mode 100644 src/win-ddraw-screenshot.cc delete mode 100644 src/win-ddraw-screenshot.h delete mode 100644 src/win-ddraw.cc delete mode 100644 src/win-ddraw.h delete mode 100644 src/win-deviceconfig.c delete mode 100644 src/win-joystick.cc delete mode 100644 src/win-joystickconfig.c delete mode 100644 src/win-language.c delete mode 100644 src/win-language.h delete mode 100644 src/win-midi.c delete mode 100644 src/win-mouse.cc delete mode 100644 src/win-opendir.c delete mode 100644 src/win-serial.c delete mode 100644 src/win-settings.c delete mode 100644 src/win-status.c delete mode 100644 src/win-video.c delete mode 100644 src/win.c delete mode 100644 src/win.h diff --git a/src/86Box.manifest b/src/86Box.manifest deleted file mode 100644 index be8c16756..000000000 --- a/src/86Box.manifest +++ /dev/null @@ -1,22 +0,0 @@ - - - -Emulator for X86-based systems. - - - - - - diff --git a/src/86Box.rc b/src/86Box.rc deleted file mode 100644 index fb5d56296..000000000 --- a/src/86Box.rc +++ /dev/null @@ -1,941 +0,0 @@ -#include - -//Microsoft Developer Studio generated resource script. -// -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#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 -// - -STATUSBARMENU MENU DISCARDABLE -BEGIN - POPUP "FDD 1" - BEGIN - MENUITEM "&Change...", IDM_DISC_1 - MENUITEM "Change FDD 1 (&Write-protected)...", IDM_DISC_1_WP - MENUITEM "&Eject FDD 1", IDM_EJECT_1 - END - POPUP "FDD 2" - BEGIN - MENUITEM "&Change...", IDM_DISC_2 - MENUITEM "Change FDD 2 (&Write-protected)...", IDM_DISC_2_WP - MENUITEM "&Eject FDD 2", IDM_EJECT_2 - END - POPUP "FDD 3" - BEGIN - MENUITEM "&Change...", IDM_DISC_3 - MENUITEM "Change FDD 3 (&Write-protected)...", IDM_DISC_3_WP - MENUITEM "&Eject FDD 3", IDM_EJECT_3 - END - POPUP "FDD 4" - BEGIN - MENUITEM "&Change...", IDM_DISC_4 - MENUITEM "Change FDD 4 (&Write-protected)...", IDM_DISC_4_WP - MENUITEM "&Eject FDD 4", IDM_EJECT_4 - END - POPUP "CD-ROM 1" - BEGIN - MENUITEM "&Mute", IDM_CDROM_1_MUTE - MENUITEM SEPARATOR - MENUITEM "E&mpty", IDM_CDROM_1_EMPTY - MENUITEM "&Reload previous disc", IDM_CDROM_1_RELOAD - MENUITEM SEPARATOR - MENUITEM "&Image...", IDM_CDROM_1_IMAGE - END - POPUP "CD-ROM 2" - BEGIN - MENUITEM "&Mute", IDM_CDROM_2_MUTE - MENUITEM SEPARATOR - MENUITEM "E&mpty", IDM_CDROM_2_EMPTY - MENUITEM "&Reload previous disc", IDM_CDROM_2_RELOAD - MENUITEM SEPARATOR - MENUITEM "&Image...", IDM_CDROM_2_IMAGE - END - POPUP "CD-ROM 3" - BEGIN - MENUITEM "&Mute", IDM_CDROM_3_MUTE - MENUITEM SEPARATOR - MENUITEM "E&mpty", IDM_CDROM_3_EMPTY - MENUITEM "&Reload previous disc", IDM_CDROM_3_RELOAD - MENUITEM SEPARATOR - MENUITEM "&Image...", IDM_CDROM_3_IMAGE - END - POPUP "CD-ROM 4" - BEGIN - MENUITEM "&Mute", IDM_CDROM_4_MUTE - MENUITEM SEPARATOR - MENUITEM "E&mpty", IDM_CDROM_4_EMPTY - MENUITEM "&Reload previous disc", IDM_CDROM_4_RELOAD - MENUITEM SEPARATOR - MENUITEM "&Image...", IDM_CDROM_4_IMAGE - END -END - -MAINMENU MENU DISCARDABLE -BEGIN - POPUP "&Action" - BEGIN - MENUITEM "&Hard Reset", IDM_FILE_HRESET - MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_FILE_RESET_CAD - MENUITEM SEPARATOR - MENUITEM "E&xit", IDM_FILE_EXIT - END - POPUP "&Tools" - BEGIN - MENUITEM "&Settings...", IDM_CONFIG - MENUITEM SEPARATOR - MENUITEM "&Load configuration...", IDM_CONFIG_LOAD - MENUITEM "&Save configuration...", IDM_CONFIG_SAVE - MENUITEM SEPARATOR - POPUP "&Video" - BEGIN - MENUITEM "&Resizeable window", IDM_VID_RESIZE - MENUITEM "R&emember size && position", IDM_VID_REMEMBER - MENUITEM SEPARATOR - MENUITEM "&DirectDraw", IDM_VID_DDRAW - MENUITEM "Direct&3D 9", IDM_VID_D3D - 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", 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 - MENUITEM "&Inverted VGA monitor", IDM_VID_INVERT - MENUITEM SEPARATOR - MENUITEM "F&orce 4:3 display ratio", IDM_VID_FORCE43 - MENUITEM "E&GA/(S)VGA overscan", IDM_VID_OVERSCAN - MENUITEM SEPARATOR - MENUITEM "Take s&creenshot\tCtrl+F11", IDM_VID_SCREENSHOT - END - MENUITEM "S&tatus", IDM_STATUS -#ifdef ENABLE_LOG_TOGGLES -#if defined ENABLE_BUSLOGIC_LOG || defined ENABLE_CDROM_LOG || defined ENABLE_D86F_LOG || defined ENABLE_FDC_LOG || defined ENABLE_IDE_LOG || defined ENABLE_NE2000_LOG - MENUITEM SEPARATOR -#endif -#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_NE2000_LOG - MENUITEM "Enable NE2000 logs\tCtrl+F9", IDM_LOG_NE2000 -#endif -#endif -#ifdef ENABLE_LOG_BREAKPOINT - MENUITEM SEPARATOR - MENUITEM "&Log breakpoint\tCtrl+F10", IDM_LOG_BREAKPOINT -#ifdef ENABLE_VRAM_DUMP - MENUITEM "Dump &video RAM\tCtrl+F1", IDM_DUMP_VRAM -#endif -#else -#ifdef ENABLE_VRAM_DUMP - MENUITEM SEPARATOR - MENUITEM "Dump &video RAM\tCtrl+F1", IDM_DUMP_VRAM -#endif -#endif - END - 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_LOG_TOGGLES -#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_NE2000_LOG - VK_F9, IDM_LOG_NE2000, CONTROL, VIRTKEY -#endif -#endif -#ifdef ENABLE_LOG_BREAKPOINT - VK_F10, IDM_LOG_BREAKPOINT, CONTROL, VIRTKEY -#endif - VK_F11, IDM_VID_SCREENSHOT, VIRTKEY, CONTROL - VK_F12, IDM_FILE_RESET_CAD, VIRTKEY, CONTROL -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -CONFIGUREDLG_MAIN 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 | WS_BORDER | WS_TABSTOP,7,7,90,197 - CONTROL "",-1,"Static",SS_BLACKFRAME | SS_SUNKEN,1,211,363,1 - LTEXT "Language:",2047,7,222,41,10 - COMBOBOX IDC_COMBO_LANG,48,221,108,120,CBS_DROPDOWN | WS_VSCROLL | - WS_TABSTOP -END - -CONFIGUREDLG_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:",IDC_STATIC,154,35,27,10 - LTEXT "Heads:",1793,81,35,29,8 - LTEXT "Cylinders:",1794,7,35,32,12 - LTEXT "Size (MB):",1795,7,54,33,8 - LTEXT "Type:",1797,86,54,24,8 - LTEXT "File name:",-1,7,7,204,9 - COMBOBOX IDC_COMBO_HD_BUS,33,71,58,12,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "Bus:",1798,7,72,24,8 - COMBOBOX IDC_COMBO_HD_CHANNEL,134,71,77,12,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "Channel:",1799,99,72,34,8 - COMBOBOX IDC_COMBO_HD_ID,133,71,26,12,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "ID:",1800,117,72,15,8 - COMBOBOX IDC_COMBO_HD_LUN,185,71,26,12,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "LUN:",1801,168,72,15,8 - COMBOBOX IDC_COMBO_HD_CHANNEL_IDE,134,71,77,12,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "Channel:",1802,99,72,34,8 -END - -STATUSDLG 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",IDC_STEXT_DEVICE,16,16,180,1000 - LTEXT "1",IDC_STEXT1,16,186,180,1000 -END - -ABOUTDLG 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 v1.20 - A fork of PCem\n\nAuthors: Sarah Walker, Tohka, 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 - -CONFIGUREDLG_MACHINE DIALOG DISCARDABLE 97, 0, 267, 112 -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:",1794,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:",1796,7,26,59,10 - COMBOBOX IDC_COMBO_WS,71,44,189,120,CBS_DROPDOWNLIST | WS_VSCROLL | - WS_TABSTOP - LTEXT "Wait states:",1798,7,45,60,10 - COMBOBOX IDC_COMBO_CPU,145,25,115,120,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "CPU:",1797,124,26,18,10 - CONTROL "Dynamic Recompiler",IDC_CHECK_DYNAREC,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,7,80,94,10 - CONTROL "Enable FPU",IDC_CHECK_FPU,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,147,80,113,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",IDC_TEXT_MB,123,64,10,10 - LTEXT "Memory:",1802,7,64,30,10 - CONTROL "Enable time sync",IDC_CHECK_SYNC,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,7,95,102,10 -END - -CONFIGUREDLG_VIDEO DIALOG DISCARDABLE 97, 0, 267, 63 -STYLE DS_CONTROL | WS_CHILD -FONT 9, "Segoe UI" -BEGIN - COMBOBOX IDC_COMBO_VIDEO,71,7,140,120,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "Video:",1795,7,8,55,10 - COMBOBOX IDC_COMBO_VIDEO_SPEED,71,25,189,120,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "Video speed:",1800,7,26,58,10 - CONTROL "Voodoo Graphics",IDC_CHECK_VOODOO,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,7,45,199,10 - PUSHBUTTON "Configure",IDC_CONFIGURE_VOODOO,214,44,46,12 - PUSHBUTTON "Configure",IDC_CONFIGUREVID,214,7,46,12 -END - -CONFIGUREDLG_INPUT DIALOG DISCARDABLE 97, 0, 267, 65 -STYLE DS_CONTROL | WS_CHILD -FONT 9, "Segoe UI" -BEGIN - LTEXT "Mouse :",IDC_STATIC,7,8,57,10 - COMBOBOX IDC_COMBO_MOUSE,71,7,189,120,CBS_DROPDOWN | WS_VSCROLL | - WS_TABSTOP - LTEXT "Joystick :",1793,7,26,58,10 - COMBOBOX IDC_COMBO_JOYSTICK,71,25,189,120,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - DEFPUSHBUTTON "Joystick 1...",IDC_JOY1,7,44,50,14 - PUSHBUTTON "Joystick 2...",IDC_JOY2,74,44,50,14 - DEFPUSHBUTTON "Joystick 3...",IDC_JOY3,141,44,50,14 - PUSHBUTTON "Joystick 4...",IDC_JOY4,209,44,50,14 -END - -CONFIGUREDLG_SOUND DIALOG DISCARDABLE 97, 0, 267, 78 -STYLE DS_CONTROL | WS_CHILD -FONT 9, "Segoe UI" -BEGIN - COMBOBOX IDC_COMBOSND,71,7,140,120,CBS_DROPDOWNLIST | WS_VSCROLL | - WS_TABSTOP - LTEXT "Sound card:",1800,7,8,59,10 - PUSHBUTTON "Configure",IDC_CONFIGURESND,214,7,46,12 - COMBOBOX IDC_COMBO_MIDI,71,25,189,120,CBS_DROPDOWNLIST | WS_VSCROLL | - WS_TABSTOP - LTEXT "MIDI Out Device:",1801,7,26,59,10 - CONTROL "CMS / Game Blaster",IDC_CHECKCMS,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,87,43,80,10 - CONTROL "Innovation SSI-2001",IDC_CHECKSSI,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,7,43,80,10 - CONTROL "Gravis Ultrasound",IDC_CHECKGUS,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,174,43,80,10 - CONTROL "Use Nuked OPL",IDC_CHECKNUKEDOPL,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,7,61,80,10 -END - -CONFIGUREDLG_NETWORK DIALOG DISCARDABLE 97, 0, 267, 63 -STYLE DS_CONTROL | WS_CHILD -FONT 9, "Segoe UI" -BEGIN - LTEXT "Network type:",1800,7,8,59,10 - COMBOBOX IDC_COMBONETTYPE,71,7,189,120,CBS_DROPDOWNLIST | WS_VSCROLL | - WS_TABSTOP - - LTEXT "PCap device:",1801,7,26,59,10 - COMBOBOX IDC_COMBOPCAP,71,25,189,120,CBS_DROPDOWNLIST | WS_VSCROLL | - WS_TABSTOP - - LTEXT "Network adapter:",1802,7,44,59,10 - COMBOBOX IDC_COMBONET,71,43,140,120,CBS_DROPDOWNLIST | WS_VSCROLL | - WS_TABSTOP - PUSHBUTTON "Configure",IDC_CONFIGURENET,214,43,46,12 -END - -CONFIGUREDLG_PERIPHERALS DIALOG DISCARDABLE 97, 0, 267, 115 -STYLE DS_CONTROL | WS_CHILD -FONT 9, "Segoe UI" -BEGIN - LTEXT "SCSI Controller:",1804,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:",1799,7,26,61,10 - COMBOBOX IDC_COMBO_HDC,71,25,189,120,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - - LTEXT "Tertiary IDE:",1802,7,44,61,10 - COMBOBOX IDC_COMBO_IDE_TER,71,43,189,120,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - - LTEXT "Quaternary IDE:",1803,7,62,61,10 - COMBOBOX IDC_COMBO_IDE_QUA,71,61,189,120,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - - CONTROL "Serial port 1",IDC_CHECKSERIAL1,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,7,80,94,10 - CONTROL "Serial port 2",IDC_CHECKSERIAL2,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,147,80,94,10 - - CONTROL "Parallel port",IDC_CHECKPARALLEL,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,7,98,94,10 - CONTROL "ISABugger device",IDC_CHECKBUGGER,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,147,98,94,10 -END - -CONFIGUREDLG_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 | WS_BORDER | WS_TABSTOP,7,18,253,92 - LTEXT "Hard disks:",-1,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:",1798,7,118,24,8 - COMBOBOX IDC_COMBO_HD_CHANNEL,170,117,90,12,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "Channel:",1799,131,118,38,8 - COMBOBOX IDC_COMBO_HD_ID,170,117,22,12,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "ID:",1800,131,118,38,8 - COMBOBOX IDC_COMBO_HD_LUN,239,117,22,12,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "LUN:",1801,200,118,38,8 - COMBOBOX IDC_COMBO_HD_CHANNEL_IDE,170,117,90,12,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "Channel:",1802,131,118,38,8 -END - -CONFIGUREDLG_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 | WS_BORDER | WS_TABSTOP, - 7,18,253,60 - LTEXT "Floppy drives:",-1,7,7,43,8 - CONTROL "List1",IDC_LIST_CDROM_DRIVES,"SysListView32",LVS_REPORT | - LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP,7,116,253,60 - LTEXT "CD-ROM drives:",-1,7,106,50,8 - COMBOBOX IDC_COMBO_FD_TYPE,33,85,90,12,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "Type:",1803,7,86,24,8 - COMBOBOX IDC_COMBO_CD_BUS,33,183,90,12,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "Bus:",1798,7,184,24,8 - COMBOBOX IDC_COMBO_CD_ID,170,183,22,12,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "ID:",1800,131,184,38,8 - COMBOBOX IDC_COMBO_CD_LUN,239,183,22,12,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "LUN:",1801,200,184,38,8 - COMBOBOX IDC_COMBO_CD_CHANNEL_IDE,170,183,90,12,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "Channel:",1802,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 "ICONS/86Box-RB.ico" -#else -/* Icon by Devcore - https://commons.wikimedia.org/wiki/File:Icon_PC2_256x256.png */ -100 ICON DISCARDABLE "ICONS/86Box.ico" -#endif -128 ICON DISCARDABLE "ICONS/floppy_525_1dd.ico" -129 ICON DISCARDABLE "ICONS/floppy_525_1dd_active.ico" -130 ICON DISCARDABLE "ICONS/floppy_525_2dd.ico" -131 ICON DISCARDABLE "ICONS/floppy_525_2dd_active.ico" -132 ICON DISCARDABLE "ICONS/floppy_525_2qd.ico" -133 ICON DISCARDABLE "ICONS/floppy_525_2qd_active.ico" -134 ICON DISCARDABLE "ICONS/floppy_525_2hd.ico" -135 ICON DISCARDABLE "ICONS/floppy_525_2hd_active.ico" -144 ICON DISCARDABLE "ICONS/floppy_35_1dd.ico" -145 ICON DISCARDABLE "ICONS/floppy_35_1dd_active.ico" -146 ICON DISCARDABLE "ICONS/floppy_35_2dd.ico" -147 ICON DISCARDABLE "ICONS/floppy_35_2dd_active.ico" -150 ICON DISCARDABLE "ICONS/floppy_35_2hd.ico" -151 ICON DISCARDABLE "ICONS/floppy_35_2hd_active.ico" -152 ICON DISCARDABLE "ICONS/floppy_35_2ed.ico" -153 ICON DISCARDABLE "ICONS/floppy_35_2ed_active.ico" -160 ICON DISCARDABLE "ICONS/cdrom_atapi.ico" -161 ICON DISCARDABLE "ICONS/cdrom_atapi_active.ico" -162 ICON DISCARDABLE "ICONS/cdrom_atapi_dma.ico" -163 ICON DISCARDABLE "ICONS/cdrom_atapi_dma_active.ico" -164 ICON DISCARDABLE "ICONS/cdrom_scsi.ico" -165 ICON DISCARDABLE "ICONS/cdrom_scsi_active.ico" -176 ICON DISCARDABLE "ICONS/hard_disk_mfm.ico" -177 ICON DISCARDABLE "ICONS/hard_disk_mfm_active.ico" -178 ICON DISCARDABLE "ICONS/hard_disk.ico" -179 ICON DISCARDABLE "ICONS/hard_disk_active.ico" -180 ICON DISCARDABLE "ICONS/hard_disk_ide.ico" -181 ICON DISCARDABLE "ICONS/hard_disk_ide_active.ico" -182 ICON DISCARDABLE "ICONS/hard_disk_scsi.ico" -183 ICON DISCARDABLE "ICONS/hard_disk_scsi_active.ico" -256 ICON DISCARDABLE "ICONS/machine.ico" -257 ICON DISCARDABLE "ICONS/video.ico" -258 ICON DISCARDABLE "ICONS/input_devices.ico" -259 ICON DISCARDABLE "ICONS/sound.ico" -260 ICON DISCARDABLE "ICONS/network.ico" -261 ICON DISCARDABLE "ICONS/other_peripherals.ico" -262 ICON DISCARDABLE "ICONS/hard_disk.ico" -263 ICON DISCARDABLE "ICONS/removable_devices.ico" -384 ICON DISCARDABLE "ICONS/floppy_525_1dd_empty.ico" -385 ICON DISCARDABLE "ICONS/floppy_525_1dd_empty_active.ico" -386 ICON DISCARDABLE "ICONS/floppy_525_2dd_empty.ico" -387 ICON DISCARDABLE "ICONS/floppy_525_2dd_empty_active.ico" -388 ICON DISCARDABLE "ICONS/floppy_525_2qd_empty.ico" -389 ICON DISCARDABLE "ICONS/floppy_525_2qd_empty_active.ico" -390 ICON DISCARDABLE "ICONS/floppy_525_2hd_empty.ico" -391 ICON DISCARDABLE "ICONS/floppy_525_2hd_empty_active.ico" -400 ICON DISCARDABLE "ICONS/floppy_35_1dd_empty.ico" -401 ICON DISCARDABLE "ICONS/floppy_35_1dd_empty_active.ico" -402 ICON DISCARDABLE "ICONS/floppy_35_2dd_empty.ico" -403 ICON DISCARDABLE "ICONS/floppy_35_2dd_empty_active.ico" -406 ICON DISCARDABLE "ICONS/floppy_35_2hd_empty.ico" -407 ICON DISCARDABLE "ICONS/floppy_35_2hd_empty_active.ico" -408 ICON DISCARDABLE "ICONS/floppy_35_2ed_empty.ico" -409 ICON DISCARDABLE "ICONS/floppy_35_2ed_empty_active.ico" -416 ICON DISCARDABLE "ICONS/cdrom_atapi_empty.ico" -417 ICON DISCARDABLE "ICONS/cdrom_atapi_empty_active.ico" -418 ICON DISCARDABLE "ICONS/cdrom_atapi_dma_empty.ico" -419 ICON DISCARDABLE "ICONS/cdrom_atapi_dma_empty_active.ico" -420 ICON DISCARDABLE "ICONS/cdrom_scsi_empty.ico" -421 ICON DISCARDABLE "ICONS/cdrom_scsi_empty_active.ico" -512 ICON DISCARDABLE "ICONS/floppy_disabled.ico" -514 ICON DISCARDABLE "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, 71 - END - - CONFIGUREDLG_NETWORK, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 260 - TOPMARGIN, 7 - BOTTOMMARGIN, 56 - END - - 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_STRING2049 "86Box Error" - IDS_STRING2050 "86Box Fatal Error" - IDS_STRING2051 "This will reset 86Box.\nAre you sure you want to save the settings?" - IDS_STRING2052 "DirectDraw Screenshot Error" - IDS_STRING2053 "Invalid number of sectors (valid values are between 1 and 63)" - IDS_STRING2054 "Invalid number of heads (valid values are between 1 and 16)" - IDS_STRING2055 "Invalid number of cylinders (valid values are between 1 and 266305)" - IDS_STRING2056 "Please enter a valid file name" - IDS_STRING2057 "Unable to open the file for write" - IDS_STRING2058 "Attempting to create a HDI image larger than 4 GB" - IDS_STRING2059 "Remember to partition and format the new drive" - IDS_STRING2060 "Unable to open the file for read" - IDS_STRING2061 "HDI or HDX image with a sector size that is not 512 are not supported" - IDS_STRING2062 "86Box was unable to find any ROMs.\nAt least one ROM set is required to use 86Box." - IDS_STRING2063 "Configured ROM set not available.\nDefaulting to an available ROM set." -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_STRING2064 "Configured video BIOS not available.\nDefaulting to an available video BIOS." - IDS_STRING2065 "Machine" - IDS_STRING2066 "Video" - IDS_STRING2067 "Input devices" - IDS_STRING2068 "Sound" - IDS_STRING2069 "Network" - IDS_STRING2070 "Other peripherals" - IDS_STRING2071 "Hard disks" - IDS_STRING2072 "Removable devices" - IDS_STRING2073 "%i"" floppy drive: %s" - IDS_STRING2074 "Disabled CD-ROM drive" - IDS_STRING2075 "%s CD-ROM drive: %s" - IDS_STRING2076 "Host CD/DVD Drive (%c:)" - IDS_STRING2077 "Click to capture mouse" - IDS_STRING2078 "Press F12-F8 to release mouse" - IDS_STRING2079 "Press F12-F8 or middle button to release mouse" -END - -STRINGTABLE DISCARDABLE -BEGIN - 2080 "Drive" - 2081 "Location" - 2082 "Bus" - 2083 "File" - 2084 "C" - 2085 "H" - 2086 "S" - 2087 "MB" - 2088 "%i" - 2089 "Enabled" - 2090 "Mute" - 2091 "Type" - 2092 "Bus" - 2093 "DMA" - 2094 "KB" - 2095 "MFM, RLL, or ESDI CD-ROM drives never existed" -END - -STRINGTABLE DISCARDABLE -BEGIN - 2096 "Slave" - 2097 "SCSI (ID %s, LUN %s)" - 2098 "Adapter Type" - 2099 "Base Address" - 2100 "IRQ" - 2101 "8-bit DMA" - 2102 "16-bit DMA" - 2103 "BIOS" - 2104 "Network Type" - 2105 "Surround Module" - 2106 "MPU-401 Base Address" - 2107 "No PCap devices found" - 2108 "On-board RAM" - 2109 "Memory Size" - 2110 "Display Type" - 2111 "RGB" -END - -STRINGTABLE DISCARDABLE -BEGIN - 2112 "Composite" - 2113 "Composite Type" - 2114 "Old" - 2115 "New" - 2116 "RGB Type" - 2117 "Color" - 2118 "Monochrome (Green)" - 2119 "Monochrome (Amber)" - 2120 "Monochrome (Gray)" - 2121 "Color (no brown)" - 2122 "Monochrome (Default)" - 2123 "Snow Emulation" - 2124 "Bilinear Filtering" - 2125 "Dithering" - 2126 "Framebuffer Memory Size" - 2127 "Texture Memory Size" -END - -STRINGTABLE DISCARDABLE -BEGIN - 2128 "Screen Filter" - 2129 "Render Threads" - 2130 "Recompiler" - 2131 "System Default" - 2132 "%i Wait state(s)" - 2133 "8-bit" - 2134 "Slow 16-bit" - 2135 "Fast 16-bit" - 2136 "Slow VLB/PCI" - 2137 "Mid VLB/PCI" - 2138 "Fast VLB/PCI" - 2139 "Microsoft 2-button mouse (serial)" - 2140 "Mouse Systems mouse (serial)" - 2141 "2-button mouse (PS/2)" - 2142 "Microsoft Intellimouse (PS/2)" - 2143 "Bus mouse" -END - -STRINGTABLE DISCARDABLE -BEGIN - 2144 "Standard 2-button joystick(s)" - 2145 "Standard 4-button joystick" - 2146 "Standard 6-button joystick" - 2147 "Standard 8-button joystick" - 2148 "CH Flightstick Pro" - 2149 "Microsoft SideWinder Pad" - 2150 "Thrustmaster Flight Control System" - 2151 "Disabled" - 2152 "None" - 2153 "AT Fixed Disk Adapter" - 2154 "Internal IDE" - 2155 "IRQ %i" - 2156 "MFM (%01i:%01i)" - 2157 "IDE (PIO+DMA) (%01i:%01i)" - 2158 "SCSI (%02i:%02i)" - 2159 "Invalid number of cylinders (valid values are between 1 and 1023)" - 2160 "%" PRIu64 - 2161 "Genius Bus mouse" - 2162 "Amstrad mouse" - 2163 "Attempting to create a spuriously large hard disk image" - 2164 "Invalid number of sectors (valid values are between 1 and 99)" - 2165 "MFM" - 2166 "IDE (PIO-only)" - 2167 "IDE (PIO and DMA)" - 2168 "SCSI" - 2169 "%01i:%01i" - 2170 "Custom..." - 2171 "%" PRIu64 " MB (CHS: %" PRIu64 ", %" PRIu64 ", %" PRIu64 ")" - 2172 "Hard disk images (*.HDI;*.HDX;*.IMA;*.IMG)\0*.HDI;*.HDX;*.IMA;*.IMG\0All files (*.*)\0*.*\0" - 2173 "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" - 2174 "Configuration files (*.CFG)\0*.CFG\0All files (*.*)\0*.*\0" - 2175 "CD-ROM image (*.ISO;*.CUE)\0*.ISO;*.CUE\0All files (*.*)\0*.*\0" - 2176 "Use CTRL + ALT + PAGE DOWN to return to windowed mode" - 2177 "Olivetti M24 mouse" - 2178 "This image exists and will be overwritten.\nAre you sure you want to use it?" - 2179 "Floppy %i (%s): %ws" - 2180 "CD-ROM %i: %ws" - 2181 "MFM hard disk" - 2182 "IDE hard disk (PIO-only)" - 2183 "IDE hard disk (PIO and DMA)" - 2184 "SCSI hard disk" - 2185 "(empty)" - 2186 "(host drive %c:)" - 2187 "Custom (large)..." - 2188 "Type" - 2189 "ATAPI (PIO-only)" - 2190 "ATAPI (PIO and DMA)" - 2191 "ATAPI (PIO-only) (%01i:%01i)" - 2192 "ATAPI (PIO and DMA) (%01i:%01i)" - 2193 "Use CTRL + ALT + PAGE DOWN to return to windowed mode" - 2194 "Unable to create bitmap file: %s" - 2195 "IDE (PIO-only) (%01i:%01i)" - 2196 "Add New Hard Disk" - 2197 "Add Existing Hard Disk" - 2198 "Removable disk %i: %s" - 2199 "USB is not yet supported" - 2200 "Invalid PCap device" - 2201 "English (United States)" -END - - -#ifndef _MAC -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,20,0,0 - PRODUCTVERSION 1,20,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", "1.20\0" - VALUE "InternalName", "pc_new\0" - VALUE "LegalCopyright", "Copyright © 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", "1.20\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 - diff --git a/src/Makefile.mingw b/src/Makefile.mingw index ff573e673..d2cbc03e3 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -8,7 +8,7 @@ # # Modified Makefile for Win32 MinGW 32-bit environment. # -# Version: @(#)Makefile.mingw 1.0.12 2017/05/12 +# Version: @(#)Makefile.mingw 1.0.13 2017/05/17 # # Authors: Kotori, # Fred N. van Kempen, @@ -33,16 +33,20 @@ DEBUG = n OPTIM = n X64 = n +# Where is the WinPcap DLL ? +PCAPDLL = C:\\Windows\\System32\\wpcap.dll + ######################################################################### # Nothing should need changing from here on.. # ######################################################################### -VPATH = . cpu sound sound/resid-fp video lzf slirp +VPATH = . cpu sound sound/resid-fp video lzf slirp win +PLAT = win/ CPP = g++.exe CC = gcc.exe WINDRES = windres.exe -OPTS = -DWIN32 $(EXTRAS) $(STUFF) +OPTS = -DWIN32 -I$(PLAT) $(EXTRAS) $(STUFF) ifeq ($(DEBUG), y) ifeq ($(VRAMDUMP), y) DFLAGS = -march=i686 -ggdb -DDEBUG -DENABLE_VRAM_DUMP @@ -129,7 +133,7 @@ DEVOBJ = bugger.o lpt.o serial.o \ disc_86f.o disc_fdi.o disc_imd.o disc_img.o \ disc_random.o disc_td0.o \ cdrom.o \ - cdrom-dosbox.o cdrom-image.o cdrom-ioctl.o cdrom-null.o + cdrom_dosbox.o cdrom_image.o cdrom_ioctl.o cdrom_null.o USBOBJ = usb.o NETOBJ = network.o \ net_pcap.o net_slirp.o \ @@ -173,12 +177,12 @@ VIDOBJ = video.o \ vid_pc1512.o vid_pc1640.o vid_pc200.o \ vid_tandy.o vid_tandysl.o WINOBJ = win.o \ - win-d3d.o win-d3d-fs.o \ - win-ddraw.o win-ddraw-fs.o win-ddraw-screenshot.o \ - win-language.o win-status.o win-opendir.o \ - win-video.o win-serial.o win-mouse.o \ - win-joystick.o win-midi.o \ - win-settings.o win-deviceconfig.o win-joystickconfig.o \ + win_d3d.o win_d3d-fs.o \ + win_ddraw.o win_ddraw-fs.o win_ddraw-screenshot.o \ + win_language.o win_status.o win_opendir.o \ + win_video.o win_serial.o win_mouse.o \ + win_joystick.o win_midi.o \ + win_settings.o win_deviceconfig.o win_joystickconfig.o \ 86Box.res OBJ = $(MAINOBJ) $(CPUOBJ) $(SYSOBJ) $(DEVOBJ) $(USBOBJ) \ $(NETOBJ) $(SCSIOBJ) $(SNDOBJ) $(VIDOBJ) $(WINOBJ) @@ -235,11 +239,15 @@ clean: 86Box.res: 86Box.rc @echo Processing $< - @$(WINDRES) $(RFLAGS) -i 86Box.rc -o 86Box.res + @$(WINDRES) $(RFLAGS) -i win/86Box.rc -o 86Box.res + +libwpcapdelay.a: $(PCAPDLL) + @dlltool --export-all-symbols --output-def wpcap.def $(PCAPDLL) + @dlltool --def wpcap.def --output-delaylib libwpcapdelay.a pcap_if.res: pcap_if.rc @echo Processing $< - @$(WINDRES) $(RFLAGS) -i pcap_if.rc -o pcap_if.res + @$(WINDRES) $(RFLAGS) -i win/pcap_if.rc -o pcap_if.res # End of Makefile.mingw. diff --git a/src/SOUND/snd_mpu401.c b/src/SOUND/snd_mpu401.c index eace343f3..474d717b9 100644 --- a/src/SOUND/snd_mpu401.c +++ b/src/SOUND/snd_mpu401.c @@ -2,7 +2,7 @@ #include "../io.h" #include "../pic.h" #include "../timer.h" -#include "../plat-midi.h" +#include "../win/plat_midi.h" /*YUCK*/ #include "snd_mpu401.h" #include diff --git a/src/SOUND/snd_sb_dsp.c b/src/SOUND/snd_sb_dsp.c index 92f7cacd0..8c6f4a036 100644 --- a/src/SOUND/snd_sb_dsp.c +++ b/src/SOUND/snd_sb_dsp.c @@ -9,7 +9,7 @@ #include "../io.h" #include "../pic.h" #include "../dma.h" -#include "../plat-midi.h" +#include "../win/plat_midi.h" /*YUCK*/ #include "../timer.h" #include "sound.h" #include "snd_mpu401.h" diff --git a/src/VIDEO/vid_cga.c b/src/VIDEO/vid_cga.c index 41553f671..afae65439 100644 --- a/src/VIDEO/vid_cga.c +++ b/src/VIDEO/vid_cga.c @@ -13,7 +13,7 @@ #include "vid_cga.h" #include "vid_cga_comp.h" #ifndef __unix -#include "../win-cgapal.h" +# include "../win/win_cgapal.h" /*YUCK*/ #endif diff --git a/src/VIDEO/vid_hercules.c b/src/VIDEO/vid_hercules.c index a7c5ab73a..bbb8b57b6 100644 --- a/src/VIDEO/vid_hercules.c +++ b/src/VIDEO/vid_hercules.c @@ -11,7 +11,7 @@ #include "video.h" #include "vid_hercules.h" #ifndef __unix -#include "../win-cgapal.h" +# include "../win/win_cgapal.h" /*YUCK*/ #endif diff --git a/src/VIDEO/vid_mda.c b/src/VIDEO/vid_mda.c index 7180a4921..d9e254b3a 100644 --- a/src/VIDEO/vid_mda.c +++ b/src/VIDEO/vid_mda.c @@ -11,7 +11,7 @@ #include "video.h" #include "vid_mda.h" #ifndef __unix -#include "../win-cgapal.h" +# include "../win/win_cgapal.h" /*YUCK*/ #endif diff --git a/src/VIDEO/video.c b/src/VIDEO/video.c index c7c1a31b8..f3deed5bc 100644 --- a/src/VIDEO/video.c +++ b/src/VIDEO/video.c @@ -17,7 +17,7 @@ #include "video.h" #include "vid_svga.h" #ifndef __unix -#include "../win-cgapal.h" +# include "../win/win_cgapal.h" /*YUCK*/ #endif diff --git a/src/cdrom-dosbox.cpp b/src/cdrom-dosbox.cpp deleted file mode 100644 index 6f966cf1b..000000000 --- a/src/cdrom-dosbox.cpp +++ /dev/null @@ -1,565 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/* Modified for use with PCem by bit */ - -#include -#include -#include -#include -#include -#include -#include //GCC 2.95 -#include -#include -#include -#include "cdrom-dosbox.h" - -#if !defined(WIN32) -#include -#else -#include -#endif - -using namespace std; - -#define MAX_LINE_LENGTH 512 -#define MAX_FILENAME_LENGTH 256 -#define CROSS_LEN 512 - -#define safe_strncpy(a,b,n) do { strncpy((a),(b),(n)-1); (a)[(n)-1] = 0; } while (0) - -CDROM_Interface_Image::BinaryFile::BinaryFile(const char *filename, bool &error) -{ - file = new ifstream(filename, ios::in | ios::binary); - error = (file == NULL) || (file->fail()); -} - -CDROM_Interface_Image::BinaryFile::~BinaryFile() -{ - delete file; -} - -bool CDROM_Interface_Image::BinaryFile::read(Bit8u *buffer, int seek, int count) -{ - file->seekg(seek, ios::beg); - file->read((char*)buffer, count); - return !(file->fail()); -} - -int CDROM_Interface_Image::BinaryFile::getLength() -{ - file->seekg(0, ios::end); - int length = (int)file->tellg(); - if (file->fail()) return -1; - return length; -} - -CDROM_Interface_Image::CDROM_Interface_Image() -{ -} - -CDROM_Interface_Image::~CDROM_Interface_Image() -{ - ClearTracks(); -} - -void CDROM_Interface_Image::InitNewMedia() -{ -} - -bool CDROM_Interface_Image::SetDevice(char* path, int forceCD) -{ - if (LoadCueSheet(path)) return true; - if (LoadIsoFile(path)) return true; - - // print error message on dosbox console - //printf("Could not load image file: %s\n", path); - return false; -} - -bool CDROM_Interface_Image::GetUPC(unsigned char& attr, char* upc) -{ - attr = 0; - strcpy(upc, this->mcn.c_str()); - return true; -} - -bool CDROM_Interface_Image::GetAudioTracks(int& stTrack, int& end, TMSF& leadOut) -{ - stTrack = 1; - end = (int)(tracks.size() - 1); - FRAMES_TO_MSF(tracks[tracks.size() - 1].start + 150, &leadOut.min, &leadOut.sec, &leadOut.fr); - return true; -} - -bool CDROM_Interface_Image::GetAudioTrackInfo(int track, int& track_number, TMSF& start, unsigned char& attr) -{ - if (track < 1 || track > (int)tracks.size()) return false; - FRAMES_TO_MSF(tracks[track - 1].start + 150, &start.min, &start.sec, &start.fr); - track_number = tracks[track - 1].track_number; - attr = tracks[track - 1].attr; - return true; -} - -bool CDROM_Interface_Image::GetAudioSub(int sector, unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos) -{ - int cur_track = GetTrack(sector); - if (cur_track < 1) return false; - track = (unsigned char)cur_track; - attr = tracks[track - 1].attr; - index = 1; - FRAMES_TO_MSF(sector + 150, &absPos.min, &absPos.sec, &absPos.fr); - FRAMES_TO_MSF(sector - tracks[track - 1].start + 150, &relPos.min, &relPos.sec, &relPos.fr); - return true; -} - -bool CDROM_Interface_Image::GetMediaTrayStatus(bool& mediaPresent, bool& mediaChanged, bool& trayOpen) -{ - mediaPresent = true; - mediaChanged = false; - trayOpen = false; - return true; -} - -bool CDROM_Interface_Image::ReadSectors(PhysPt buffer, bool raw, unsigned long sector, unsigned long num) -{ - int sectorSize = raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE; - Bitu buflen = num * sectorSize; - Bit8u* buf = new Bit8u[buflen]; - - bool success = true; //Gobliiins reads 0 sectors - for(unsigned long i = 0; i < num; i++) { - success = ReadSector(&buf[i * sectorSize], raw, sector + i); - if (!success) break; - } - - memcpy((void*)buffer, buf, buflen); - delete[] buf; - - return success; -} - -bool CDROM_Interface_Image::LoadUnloadMedia(bool unload) -{ - return true; -} - -int CDROM_Interface_Image::GetTrack(int sector) -{ - vector::iterator i = tracks.begin(); - vector::iterator end = tracks.end() - 1; - - while(i != end) { - Track &curr = *i; - Track &next = *(i + 1); - if (curr.start <= sector && sector < next.start) return curr.number; - i++; - } - return -1; -} - -bool CDROM_Interface_Image::ReadSector(Bit8u *buffer, bool raw, unsigned long sector) -{ - int track = GetTrack(sector) - 1; - if (track < 0) return false; - - int seek = tracks[track].skip + (sector - tracks[track].start) * tracks[track].sectorSize; - int length = (raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE); - if (tracks[track].sectorSize != RAW_SECTOR_SIZE && raw) return false; - if (tracks[track].sectorSize == RAW_SECTOR_SIZE && !tracks[track].mode2 && !raw) seek += 16; - if (tracks[track].mode2 && !raw) seek += 24; - - return tracks[track].file->read(buffer, seek, length); -} - -bool CDROM_Interface_Image::IsMode2(unsigned long sector) -{ - int track = GetTrack(sector) - 1; - if (track < 0) return false; - - if (tracks[track].mode2) - { - return true; - } - else - { - return false; - } -} - -bool CDROM_Interface_Image::LoadIsoFile(char* filename) -{ - int shift = 0; - int totalPregap = 0; - - tracks.clear(); - - // data track - Track track = {0, 0, 0, 0, 0, 0, false, NULL}; - bool error; - track.file = new BinaryFile(filename, error); - if (error) { - delete track.file; - return false; - } - track.number = 1; - track.track_number = 1;//IMPORTANT: This is needed. - track.attr = DATA_TRACK;//data - - // try to detect iso type - if (CanReadPVD(track.file, COOKED_SECTOR_SIZE, false)) { - track.sectorSize = COOKED_SECTOR_SIZE; - track.mode2 = false; - } else if (CanReadPVD(track.file, RAW_SECTOR_SIZE, false)) { - track.sectorSize = RAW_SECTOR_SIZE; - track.mode2 = false; - } else if (CanReadPVD(track.file, 2336, true)) { - track.sectorSize = 2336; - track.mode2 = true; - } else if (CanReadPVD(track.file, RAW_SECTOR_SIZE, true)) { - track.sectorSize = RAW_SECTOR_SIZE; - track.mode2 = true; - } else return false; - - track.length = track.file->getLength() / track.sectorSize; - tracks.push_back(track); - - // leadout track - track.number = 2; - track.track_number = 0xAA; - track.attr = 0x16; /* Was 0x00 but I believe 0x16 is appropriate. */ - track.start = track.length; - track.length = 0; - track.file = NULL; - tracks.push_back(track); - - return true; -} - -bool CDROM_Interface_Image::CanReadPVD(TrackFile *file, int sectorSize, bool mode2) -{ - Bit8u pvd[COOKED_SECTOR_SIZE]; - int seek = 16 * sectorSize; // first vd is located at sector 16 - if (sectorSize == RAW_SECTOR_SIZE && !mode2) seek += 16; - if (mode2) seek += 24; - file->read(pvd, seek, COOKED_SECTOR_SIZE); - // pvd[0] = descriptor type, pvd[1..5] = standard identifier, pvd[6] = iso version (+8 for High Sierra) - return ((pvd[0] == 1 && !strncmp((char*)(&pvd[1]), "CD001", 5) && pvd[6] == 1) || - (pvd[8] == 1 && !strncmp((char*)(&pvd[9]), "CDROM", 5) && pvd[14] == 1)); -} - -#if defined(WIN32) -static string dirname(char * file) { - char * sep = strrchr(file, '\\'); - if (sep == NULL) - sep = strrchr(file, '/'); - if (sep == NULL) - return ""; - else { - int len = (int)(sep - file); - char tmp[MAX_FILENAME_LENGTH]; - safe_strncpy(tmp, file, len+1); - return tmp; - } -} -#endif - -bool CDROM_Interface_Image::LoadCueSheet(char *cuefile) -{ - Track track = {0, 0, 0, 0, 0, 0, false, NULL}; - tracks.clear(); - int shift = 0; - int currPregap = 0; - int totalPregap = 0; - int prestart = 0; - bool success; - bool canAddTrack = false; - char tmp[MAX_FILENAME_LENGTH]; // dirname can change its argument - safe_strncpy(tmp, cuefile, MAX_FILENAME_LENGTH); - string pathname(dirname(tmp)); - ifstream in; - in.open(cuefile, ios::in); - if (in.fail()) return false; - - while(!in.eof()) { - // get next line - char buf[MAX_LINE_LENGTH]; - in.getline(buf, MAX_LINE_LENGTH); - if (in.fail() && !in.eof()) return false; // probably a binary file - istringstream line(buf); - - string command; - GetCueKeyword(command, line); - - if (command == "TRACK") { - if (canAddTrack) success = AddTrack(track, shift, prestart, totalPregap, currPregap); - else success = true; - - track.start = 0; - track.skip = 0; - currPregap = 0; - prestart = 0; - - line >> track.number; - track.track_number = track.number; - string type; - GetCueKeyword(type, line); - - if (type == "AUDIO") { - track.sectorSize = RAW_SECTOR_SIZE; - track.attr = AUDIO_TRACK; - track.mode2 = false; - } else if (type == "MODE1/2048") { - track.sectorSize = COOKED_SECTOR_SIZE; - track.attr = DATA_TRACK; - track.mode2 = false; - } else if (type == "MODE1/2352") { - track.sectorSize = RAW_SECTOR_SIZE; - track.attr = DATA_TRACK; - track.mode2 = false; - } else if (type == "MODE2/2336") { - track.sectorSize = 2336; - track.attr = DATA_TRACK; - track.mode2 = true; - } else if (type == "MODE2/2352") { - track.sectorSize = RAW_SECTOR_SIZE; - track.attr = DATA_TRACK; - track.mode2 = true; - } else success = false; - - canAddTrack = true; - } - else if (command == "INDEX") { - int index; - line >> index; - int frame; - success = GetCueFrame(frame, line); - - if (index == 1) track.start = frame; - else if (index == 0) prestart = frame; - // ignore other indices - } - else if (command == "FILE") { - if (canAddTrack) success = AddTrack(track, shift, prestart, totalPregap, currPregap); - else success = true; - canAddTrack = false; - - string filename; - GetCueString(filename, line); - GetRealFileName(filename, pathname); - string type; - GetCueKeyword(type, line); - - track.file = NULL; - bool error = true; - if (type == "BINARY") { - track.file = new BinaryFile(filename.c_str(), error); - } - if (error) { - delete track.file; - success = false; - } - } - else if (command == "PREGAP") success = GetCueFrame(currPregap, line); - else if (command == "CATALOG") success = GetCueString(mcn, line); - // ignored commands - else if (command == "CDTEXTFILE" || command == "FLAGS" || command == "ISRC" - || command == "PERFORMER" || command == "POSTGAP" || command == "REM" - || command == "SONGWRITER" || command == "TITLE" || command == "") success = true; - // failure - else success = false; - - if (!success) return false; - } - // add last track - if (!AddTrack(track, shift, prestart, totalPregap, currPregap)) return false; - - // add leadout track - track.number++; - track.track_number = 0xAA; - // track.attr = 0;//sync with load iso - track.attr = 0x16; /* Was 0x00 but I believe 0x16 is appropriate. */ - track.start = 0; - track.length = 0; - track.file = NULL; - if(!AddTrack(track, shift, 0, totalPregap, 0)) return false; - - return true; -} - -bool CDROM_Interface_Image::AddTrack(Track &curr, int &shift, int prestart, int &totalPregap, int currPregap) -{ - // frames between index 0(prestart) and 1(curr.start) must be skipped - int skip; - if (prestart > 0) { - if (prestart > curr.start) return false; - skip = curr.start - prestart; - } else skip = 0; - - // first track (track number must be 1) - if (tracks.empty()) { - if (curr.number != 1) return false; - curr.skip = skip * curr.sectorSize; - curr.start += currPregap; - totalPregap = currPregap; - tracks.push_back(curr); - return true; - } - - Track &prev = *(tracks.end() - 1); - - // current track consumes data from the same file as the previous - if (prev.file == curr.file) { - curr.start += shift; - prev.length = curr.start + totalPregap - prev.start - skip; - curr.skip += prev.skip + prev.length * prev.sectorSize + skip * curr.sectorSize; - totalPregap += currPregap; - curr.start += totalPregap; - // current track uses a different file as the previous track - } else { - int tmp = prev.file->getLength() - prev.skip; - prev.length = tmp / prev.sectorSize; - if (tmp % prev.sectorSize != 0) prev.length++; // padding - - curr.start += prev.start + prev.length + currPregap; - curr.skip = skip * curr.sectorSize; - shift += prev.start + prev.length; - totalPregap = currPregap; - } - - // error checks - if (curr.number <= 1) return false; - if (prev.number + 1 != curr.number) return false; - if (curr.start < prev.start + prev.length) return false; - if (curr.length < 0) return false; - - tracks.push_back(curr); - return true; -} - -bool CDROM_Interface_Image::HasDataTrack(void) -{ - //Data track has attribute 0x14 - for(track_it it = tracks.begin(); it != tracks.end(); it++) { - if ((*it).attr == DATA_TRACK) return true; - } - return false; -} - -bool CDROM_Interface_Image::HasAudioTracks(void) -{ - for(track_it it = tracks.begin(); it != tracks.end(); it++) { - if ((*it).attr == AUDIO_TRACK) return true; - } - return false; -} - - -bool CDROM_Interface_Image::GetRealFileName(string &filename, string &pathname) -{ - // check if file exists - struct stat test; - if (stat(filename.c_str(), &test) == 0) return true; - - // check if file with path relative to cue file exists - string tmpstr(pathname + "/" + filename); - if (stat(tmpstr.c_str(), &test) == 0) { - filename = tmpstr; - return true; - } -#if defined (WIN32) || defined(OS2) - //Nothing -#else - //Consider the possibility that the filename has a windows directory seperator (inside the CUE file) - //which is common for some commercial rereleases of DOS games using DOSBox - - string copy = filename; - size_t l = copy.size(); - for (size_t i = 0; i < l;i++) { - if(copy[i] == '\\') copy[i] = '/'; - } - - if (stat(copy.c_str(), &test) == 0) { - filename = copy; - return true; - } - - tmpstr = pathname + "/" + copy; - if (stat(tmpstr.c_str(), &test) == 0) { - filename = tmpstr; - return true; - } - -#endif - return false; -} - -bool CDROM_Interface_Image::GetCueKeyword(string &keyword, istream &in) -{ - in >> keyword; - for(Bitu i = 0; i < keyword.size(); i++) keyword[i] = toupper(keyword[i]); - - return true; -} - -bool CDROM_Interface_Image::GetCueFrame(int &frames, istream &in) -{ - string msf; - in >> msf; - int min, sec, fr; - bool success = sscanf(msf.c_str(), "%d:%d:%d", &min, &sec, &fr) == 3; - frames = MSF_TO_FRAMES(min, sec, fr); - - return success; -} - -bool CDROM_Interface_Image::GetCueString(string &str, istream &in) -{ - int pos = (int)in.tellg(); - in >> str; - if (str[0] == '\"') { - if (str[str.size() - 1] == '\"') { - str.assign(str, 1, str.size() - 2); - } else { - in.seekg(pos, ios::beg); - char buffer[MAX_FILENAME_LENGTH]; - in.getline(buffer, MAX_FILENAME_LENGTH, '\"'); // skip - in.getline(buffer, MAX_FILENAME_LENGTH, '\"'); - str = buffer; - } - } - return true; -} - -void CDROM_Interface_Image::ClearTracks() -{ - vector::iterator i = tracks.begin(); - vector::iterator end = tracks.end(); - - TrackFile* last = NULL; - while(i != end) { - Track &curr = *i; - if (curr.file != last) { - delete curr.file; - last = curr.file; - } - i++; - } - tracks.clear(); -} diff --git a/src/cdrom-dosbox.h b/src/cdrom-dosbox.h deleted file mode 100644 index 39ed79bed..000000000 --- a/src/cdrom-dosbox.h +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/* Modified for use with PCem by bit */ - -#ifndef __CDROM_INTERFACE__ -#define __CDROM_INTERFACE__ - -#include -#include -#include -#include -#include -#include -//#include "dosbox.h" -//#include "mem.h" -//#include "mixer.h" -//#include "SDL.h" -//#include "SDL_thread.h" - -#include -typedef signed int Bits; -typedef unsigned int Bitu; -typedef int8_t Bit8s; -typedef uint8_t Bit8u; -typedef int16_t Bit16s; -typedef uint16_t Bit16u; -typedef int32_t Bit32s; -typedef uint32_t Bit32u; - -typedef size_t PhysPt; - -#define RAW_SECTOR_SIZE 2352 -#define COOKED_SECTOR_SIZE 2048 - -#define DATA_TRACK 0x14 -#define AUDIO_TRACK 0x10 - -#define CD_FPS 75 -#define FRAMES_TO_MSF(f, M,S,F) { \ - int value = f; \ - *(F) = value%CD_FPS; \ - value /= CD_FPS; \ - *(S) = value%60; \ - value /= 60; \ - *(M) = value; \ -} -#define MSF_TO_FRAMES(M, S, F) ((M)*60*CD_FPS+(S)*CD_FPS+(F)) - - -typedef struct SMSF { - unsigned char min; - unsigned char sec; - unsigned char fr; -} TMSF; - -typedef struct SCtrl { - Bit8u out[4]; // output channel - Bit8u vol[4]; // channel volume -} TCtrl; - -extern int CDROM_GetMountType(char* path, int force); - -class CDROM_Interface -{ -public: -// CDROM_Interface (void); - virtual ~CDROM_Interface (void) {}; - - virtual bool SetDevice (char* path, int forceCD) = 0; - - virtual bool GetUPC (unsigned char& attr, char* upc) = 0; - - virtual bool GetAudioTracks (int& stTrack, int& end, TMSF& leadOut) = 0; - virtual bool GetAudioTrackInfo (int track, int& number, TMSF& start, unsigned char& attr) = 0; - virtual bool GetAudioSub (int sector, unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos) = 0; - virtual bool GetMediaTrayStatus (bool& mediaPresent, bool& mediaChanged, bool& trayOpen) = 0; - - virtual bool ReadSectors (PhysPt buffer, bool raw, unsigned long sector, unsigned long num) = 0; - - virtual bool LoadUnloadMedia (bool unload) = 0; - - virtual void InitNewMedia (void) {}; -}; - -class CDROM_Interface_Image : public CDROM_Interface -{ -private: - class TrackFile { - public: - virtual bool read(Bit8u *buffer, int seek, int count) = 0; - virtual int getLength() = 0; - virtual ~TrackFile() { }; - }; - - class BinaryFile : public TrackFile { - public: - BinaryFile(const char *filename, bool &error); - ~BinaryFile(); - bool read(Bit8u *buffer, int seek, int count); - int getLength(); - private: - BinaryFile(); - std::ifstream *file; - }; - - struct Track { - int number; - int track_number; - int attr; - int start; - int length; - int skip; - int sectorSize; - bool mode2; - TrackFile *file; - }; - -public: - CDROM_Interface_Image (); - virtual ~CDROM_Interface_Image (void); - void InitNewMedia (void); - bool SetDevice (char* path, int forceCD); - bool GetUPC (unsigned char& attr, char* upc); - bool GetAudioTracks (int& stTrack, int& end, TMSF& leadOut); - bool GetAudioTrackInfo (int track, int& number, TMSF& start, unsigned char& attr); - bool GetAudioSub (int sector, unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos); - bool GetMediaTrayStatus (bool& mediaPresent, bool& mediaChanged, bool& trayOpen); - bool ReadSectors (PhysPt buffer, bool raw, unsigned long sector, unsigned long num); - bool LoadUnloadMedia (bool unload); - bool ReadSector (Bit8u *buffer, bool raw, unsigned long sector); - bool IsMode2 (unsigned long sector); - bool HasDataTrack (void); - bool HasAudioTracks (void); - - int GetTrack (int sector); - -private: - // player -static void CDAudioCallBack(Bitu len); - - void ClearTracks(); - bool LoadIsoFile(char *filename); - bool CanReadPVD(TrackFile *file, int sectorSize, bool mode2); - // cue sheet processing - bool LoadCueSheet(char *cuefile); - bool GetRealFileName(std::string& filename, std::string& pathname); - bool GetCueKeyword(std::string &keyword, std::istream &in); - bool GetCueFrame(int &frames, std::istream &in); - bool GetCueString(std::string &str, std::istream &in); - bool AddTrack(Track &curr, int &shift, int prestart, int &totalPregap, int currPregap); - - std::vector tracks; -typedef std::vector::iterator track_it; - std::string mcn; -}; - -#endif /* __CDROM_INTERFACE__ */ diff --git a/src/cdrom-image.cc b/src/cdrom-image.cc deleted file mode 100644 index 5ec185d65..000000000 --- a/src/cdrom-image.cc +++ /dev/null @@ -1,1045 +0,0 @@ -/* Copyright holders: RichardG867, Tenshi, bit - see COPYING for more details -*/ -/*CD-ROM image support*/ - -#include - -#include "config.h" -#include "cdrom-dosbox.h" -#include "cdrom.h" -#include "cdrom-image.h" -#include "cdrom-null.h" - -#define __USE_LARGEFILE64 -#define _LARGEFILE_SOURCE -#define _LARGEFILE64_SOURCE - -#include - -#define CD_STATUS_EMPTY 0 -#define CD_STATUS_DATA_ONLY 1 -#define CD_STATUS_PLAYING 2 -#define CD_STATUS_PAUSED 3 -#define CD_STATUS_STOPPED 4 - -/* The addresses sent from the guest are absolute, ie. a LBA of 0 corresponds to a MSF of 00:00:00. Otherwise, the counter displayed by the guest is wrong: - there is a seeming 2 seconds in which audio plays but counter does not move, while a data track before audio jumps to 2 seconds before the actual start - of the audio while audio still plays. With an absolute conversion, the counter is fine. */ -#define MSFtoLBA(m,s,f) ((((m*60)+s)*75)+f) - -extern CDROM image_cdrom; - -enum -{ - CD_STOPPED = 0, - CD_PLAYING, - CD_PAUSED -}; - -int cdrom_image_do_log = 0; - -CDROM_Interface_Image* cdimg[CDROM_NUM] = { NULL, NULL, NULL, NULL }; - -void cdrom_image_log(const char *format, ...) -{ -#ifdef ENABLE_CDROM_IMAGE_LOG - if (cdrom_image_do_log) - { - va_list ap; - va_start(ap, format); - vprintf(format, ap); - va_end(ap); - fflush(stdout); - } -#endif -} - -void image_close(uint8_t id); - -void image_audio_callback(uint8_t id, int16_t *output, int len) -{ - if ((cdrom_image[id].cd_state != CD_PLAYING) || (cdrom_image[id].image_is_iso)) - { - memset(output, 0, len * 2); - return; - } - while (cdrom_image[id].cd_buflen < len) - { - if (cdrom[id].seek_pos < cdrom_image[id].cd_end) - { - if (!cdimg[id]->ReadSector((unsigned char*)&cdrom_image[id].cd_buffer[cdrom_image[id].cd_buflen], true, cdrom[id].seek_pos - 150)) - { - memset(&cdrom_image[id].cd_buffer[cdrom_image[id].cd_buflen], 0, (BUF_SIZE - cdrom_image[id].cd_buflen) * 2); - cdrom_image[id].cd_state = CD_STOPPED; - cdrom_image[id].cd_buflen = len; - } - else - { - cdrom[id].seek_pos++; - cdrom_image[id].cd_buflen += (RAW_SECTOR_SIZE / 2); - } - } - else - { - memset(&cdrom_image[id].cd_buffer[cdrom_image[id].cd_buflen], 0, (BUF_SIZE - cdrom_image[id].cd_buflen) * 2); - cdrom_image[id].cd_state = CD_STOPPED; - cdrom_image[id].cd_buflen = len; - } - } - memcpy(output, cdrom_image[id].cd_buffer, len * 2); - memmove(cdrom_image[id].cd_buffer, &cdrom_image[id].cd_buffer[len], (BUF_SIZE - len) * 2); - cdrom_image[id].cd_buflen -= len; -} - -void image_audio_stop(uint8_t id) -{ - cdrom_image[id].cd_state = CD_STOPPED; -} - -static void image_playaudio(uint8_t id, uint32_t pos, uint32_t len, int ismsf) -{ - if (!cdimg[id]) return; - int number; - unsigned char attr; - TMSF tmsf; - int m = 0, s = 0, f = 0; - uint32_t start_msf = 0, end_msf = 0; - cdimg[id]->GetAudioTrackInfo(cdimg[id]->GetTrack(pos), number, tmsf, attr); - if (attr == DATA_TRACK) - { - cdrom_image_log("Can't play data track\n"); - cdrom[id].seek_pos = 0; - cdrom_image[id].cd_state = CD_STOPPED; - return; - } - cdrom_image_log("Play audio - %08X %08X %i\n", pos, len, ismsf); - if (ismsf == 2) - { - cdimg[id]->GetAudioTrackInfo(pos, number, tmsf, attr); - pos = MSFtoLBA(tmsf.min, tmsf.sec, tmsf.fr); - cdimg[id]->GetAudioTrackInfo(len, number, tmsf, attr); - len = MSFtoLBA(tmsf.min, tmsf.sec, tmsf.fr); - } - else if (ismsf == 1) - { - m = (pos >> 16) & 0xff; - s = (pos >> 8) & 0xff; - f = pos & 0xff; - - if (pos == 0xffffff) - { - cdrom_image_log("Playing from current position (MSF)\n"); - pos = cdrom[id].seek_pos; - } - else - { - pos = MSFtoLBA(m, s, f); - } - - m = (len >> 16) & 0xff; - s = (len >> 8) & 0xff; - f = len & 0xff; - len = MSFtoLBA(m, s, f); - - cdrom_image_log("MSF - pos = %08X len = %08X\n", pos, len); - } - else if (ismsf == 0) - { - if (pos == 0xffffffff) - { - cdrom_image_log("Playing from current position\n"); - pos = cdrom[id].seek_pos; - } - len += pos; - } - cdrom[id].seek_pos = pos; - cdrom_image[id].cd_end = len; - cdrom_image[id].cd_state = CD_PLAYING; - if (cdrom[id].seek_pos < 150) - cdrom[id].seek_pos = 150; - cdrom_image[id].cd_buflen = 0; -} - -static void image_pause(uint8_t id) -{ - if (!cdimg[id] || cdrom_image[id].image_is_iso) return; - if (cdrom_image[id].cd_state == CD_PLAYING) - cdrom_image[id].cd_state = CD_PAUSED; -} - -static void image_resume(uint8_t id) -{ - if (!cdimg[id] || cdrom_image[id].image_is_iso) return; - if (cdrom_image[id].cd_state == CD_PAUSED) - cdrom_image[id].cd_state = CD_PLAYING; -} - -static void image_stop(uint8_t id) -{ - if (!cdimg[id] || cdrom_image[id].image_is_iso) return; - cdrom_image[id].cd_state = CD_STOPPED; -} - -static void image_seek(uint8_t id, uint32_t pos) -{ - if (!cdimg[id] || cdrom_image[id].image_is_iso) return; - cdrom_image[id].cd_pos = pos; - cdrom_image[id].cd_state = CD_STOPPED; -} - -static int image_ready(uint8_t id) -{ - if (!cdimg[id]) - return 0; - - if (wcslen(cdrom_image[id].image_path) == 0) - return 0; - - if (cdrom_drives[id].prev_host_drive != cdrom_drives[id].host_drive) - { - return 1; - } - - if (cdrom_image[id].image_changed) - { - cdrom_image[id].image_changed = 0; - return 1; - } - - return 1; -} - -static int image_get_last_block(uint8_t id, uint8_t starttrack, int msf, int maxlen, int single) -{ - int c; - uint32_t lb=0; - - if (!cdimg[id]) return 0; - - int first_track; - int last_track; - int number; - unsigned char attr; - TMSF tmsf; - cdimg[id]->GetAudioTracks(first_track, last_track, tmsf); - - for (c = 0; c <= last_track; c++) - { - uint32_t address; - cdimg[id]->GetAudioTrackInfo(c+1, number, tmsf, attr); - address = MSFtoLBA(tmsf.min, tmsf.sec, tmsf.fr) - 150; /* Do the - 150 here as well. */ - if (address > lb) - lb = address; - } - return lb; -} - -static int image_medium_changed(uint8_t id) -{ - if (!cdimg[id]) - return 0; - - if (wcslen(cdrom_image[id].image_path) == 0) - { - return 0; - } - - if (cdrom_drives[id].prev_host_drive != cdrom_drives[id].host_drive) - { - cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; - return 1; - } - - if (cdrom_image[id].image_changed) - { - cdrom_image[id].image_changed = 0; - return 1; - } - - return 0; -} - -static uint8_t image_getcurrentsubchannel(uint8_t id, uint8_t *b, int msf) -{ - if (!cdimg[id]) return 0; - uint8_t ret; - int pos=0; - - uint32_t cdpos = cdrom[id].seek_pos; - if (cdpos >= 150) cdpos -= 150; - TMSF relPos, absPos; - unsigned char attr, track, index; - cdimg[id]->GetAudioSub(cdpos, attr, track, index, relPos, absPos); - - if (cdrom_image[id].image_is_iso) - { - ret = 0x15; - } - else - { - if (cdrom_image[id].cd_state == CD_PLAYING) - ret = 0x11; - else if (cdrom_image[id].cd_state == CD_PAUSED) - ret = 0x12; - else - ret = 0x13; - } - - b[pos++] = attr; - b[pos++] = track; - b[pos++] = index; - - if (msf) - { - uint32_t dat = MSFtoLBA(absPos.min, absPos.sec, absPos.fr); - b[pos + 3] = (uint8_t)(dat % 75); dat /= 75; - b[pos + 2] = (uint8_t)(dat % 60); dat /= 60; - b[pos + 1] = (uint8_t)dat; - b[pos] = 0; - pos += 4; - dat = MSFtoLBA(relPos.min, relPos.sec, relPos.fr); - b[pos + 3] = (uint8_t)(dat % 75); dat /= 75; - b[pos + 2] = (uint8_t)(dat % 60); dat /= 60; - b[pos + 1] = (uint8_t)dat; - b[pos] = 0; - pos += 4; - } - else - { - uint32_t dat = MSFtoLBA(absPos.min, absPos.sec, absPos.fr); - b[pos++] = (dat >> 24) & 0xff; - b[pos++] = (dat >> 16) & 0xff; - b[pos++] = (dat >> 8) & 0xff; - b[pos++] = dat & 0xff; - dat = MSFtoLBA(relPos.min, relPos.sec, relPos.fr); - b[pos++] = (dat >> 24) & 0xff; - b[pos++] = (dat >> 16) & 0xff; - b[pos++] = (dat >> 8) & 0xff; - b[pos++] = dat & 0xff; - } - - return ret; -} - -static void image_eject(uint8_t id) -{ - return; -} - -static void image_load(uint8_t id) -{ - return; -} - -static int image_is_track_audio(uint8_t id, uint32_t pos, int ismsf) -{ - int m, s, f; - unsigned char attr; - TMSF tmsf; - int number; - - if (!cdimg[id] || cdrom_image[id].image_is_iso) return 0; - - if (ismsf) - { - m = (pos >> 16) & 0xff; - s = (pos >> 8) & 0xff; - f = pos & 0xff; - pos = MSFtoLBA(m, s, f); - } - else - { - pos += 150; - } - - cdimg[id]->GetAudioTrackInfo(cdimg[id]->GetTrack(pos), number, tmsf, attr); - - return attr == AUDIO_TRACK; -} - -typedef struct __attribute__((__packed__)) -{ - uint8_t user_data[2048]; - uint8_t ecc[288]; -} m1_data_t; - -typedef struct __attribute__((__packed__)) -{ - uint8_t sub_header[8]; - uint8_t user_data[2328]; -} m2_data_t; - -typedef union __attribute__((__packed__)) -{ - m1_data_t m1_data; - m2_data_t m2_data; - uint8_t raw_data[2336]; -} sector_data_t; - -typedef struct __attribute__((__packed__)) -{ - uint8_t sync[12]; - uint8_t header[4]; - sector_data_t data; -} sector_raw_data_t; - -typedef union __attribute__((__packed__)) -{ - sector_raw_data_t sector_data; - uint8_t raw_data[2352]; -} sector_t; - -typedef struct __attribute__((__packed__)) -{ - sector_t sector; - uint8_t c2[296]; - uint8_t subchannel_raw[96]; - uint8_t subchannel_q[16]; - uint8_t subchannel_rw[96]; -} cdrom_sector_t; - -typedef union __attribute__((__packed__)) -{ - cdrom_sector_t cdrom_sector; - uint8_t buffer[2856]; -} sector_buffer_t; - -sector_buffer_t cdrom_sector_buffer; - -int cdrom_sector_size; -uint8_t raw_buffer[2352]; -uint8_t extra_buffer[296]; - -static int image_readsector_raw(uint8_t id, uint8_t *buffer, int sector, int ismsf, int cdrom_sector_type, int cdrom_sector_flags, int *len) -{ - uint8_t *b; - uint8_t *temp_b; - int real_pos; - int audio; - int mode2; - - if (!cdimg[id]) - { - return 0; - } - - if (!cdrom_drives[id].host_drive) - { - return 0; - } - - b = temp_b = buffer; - - *len = 0; - - if (ismsf) - { - real_pos = cdrom_lba_to_msf_accurate(sector); - } - else - { - real_pos = sector; - } - - if (cdrom_image[id].image_is_iso) - { - audio = 0; - mode2 = 0; - } - else - { - audio = image_is_track_audio(id, real_pos, 1); - mode2 = cdimg[id]->IsMode2(real_pos) ? 1 : 0; - } - - memset(raw_buffer, 0, 2352); - memset(extra_buffer, 0, 296); - - if (!(cdrom_sector_flags & 0xf0)) /* 0x00 and 0x08 are illegal modes */ - { - cdrom_image_log("CD-ROM %i: [Mode 1] 0x00 and 0x08 are illegal modes\n", id); - return 0; - } - - if ((cdrom_sector_type == 3) || (cdrom_sector_type > 4)) - { - if (cdrom_sector_type == 3) - { - cdrom_image_log("CD-ROM %i: Attempting to read a Yellowbook Mode 2 data sector from an image\n", id); - } - if (cdrom_sector_type > 4) - { - cdrom_image_log("CD-ROM %i: Attempting to read a XA Mode 2 Form 2 data sector from an image\n", id); - } - return 0; - } - else if (cdrom_sector_type == 1) - { - if (!audio || cdrom_image[id].image_is_iso) - { - cdrom_image_log("CD-ROM %i: [Audio] Attempting to read an audio sector from a data image\n", id); - return 0; - } - -read_audio: - cdimg[id]->ReadSector(raw_buffer, true, real_pos); - memcpy(temp_b, raw_buffer, 2352); - } - else if (cdrom_sector_type == 2) - { - if (audio || mode2) - { - cdrom_image_log("CD-ROM %i: [Mode 1] Attempting to read a non-Mode 1 sector from an audio track\n", id); - return 0; - } - -read_mode1: - if ((cdrom_sector_flags & 0x06) == 0x06) - { - cdrom_image_log("CD-ROM %i: [Mode 1] Invalid error flags\n", id); - return 0; - } - - if (((cdrom_sector_flags & 0x700) == 0x300) || ((cdrom_sector_flags & 0x700) > 0x400)) - { - cdrom_image_log("CD-ROM %i: [Mode 1] Invalid subchannel data flags (%02X)\n", id, cdrom_sector_flags & 0x700); - return 0; - } - - if ((cdrom_sector_flags & 0x18) == 0x08) /* EDC/ECC without user data is an illegal mode */ - { - cdrom_image_log("CD-ROM %i: [Mode 1] EDC/ECC without user data is an illegal mode\n", id); - return 0; - } - - if (cdrom_image[id].image_is_iso) - { - cdimg[id]->ReadSector(raw_buffer + 16, false, real_pos); - - uint8_t *bb = raw_buffer; - - /* sync bytes */ - bb[0] = 0; - memset(bb + 1, 0xff, 10); - bb[11] = 0; - bb += 12; - - bb[0] = (real_pos >> 16) & 0xff; - bb[1] = (real_pos >> 8) & 0xff; - bb[2] = real_pos & 0xff; - - bb[3] = 1; /* mode 1 data */ - bb += 4; - bb += 2048; - memset(bb, 0, 288); - } - else - { - cdimg[id]->ReadSector(raw_buffer, true, real_pos); - } - - cdrom_sector_size = 0; - - if (cdrom_sector_flags & 0x80) /* Sync */ - { - cdrom_image_log("CD-ROM %i: [Mode 1] Sync\n", id); - memcpy(temp_b, raw_buffer, 12); - cdrom_sector_size += 12; - temp_b += 12; - } - - if (cdrom_sector_flags & 0x20) /* Header */ - { - cdrom_image_log("CD-ROM %i: [Mode 1] Header\n", id); - memcpy(temp_b, raw_buffer + 12, 4); - cdrom_sector_size += 4; - temp_b += 4; - } - - /* Mode 1 sector, expected type is 1 type. */ - if (cdrom_sector_flags & 0x40) /* Sub-header */ - { - if (!(cdrom_sector_flags & 0x10)) /* No user data */ - { - cdrom_image_log("CD-ROM %i: [Mode 1] Sub-header\n", id); - memcpy(temp_b, raw_buffer + 16, 8); - cdrom_sector_size += 8; - temp_b += 8; - } - } - - if (cdrom_sector_flags & 0x10) /* User data */ - { - cdrom_image_log("CD-ROM %i: [Mode 1] User data\n", id); - memcpy(temp_b, raw_buffer + 16, 2048); - cdrom_sector_size += 2048; - temp_b += 2048; - } - - if (cdrom_sector_flags & 0x08) /* EDC/ECC */ - { - cdrom_image_log("CD-ROM %i: [Mode 1] EDC/ECC\n", id); - memcpy(temp_b, raw_buffer + 2064, 288); - cdrom_sector_size += 288; - temp_b += 288; - } - } - else if (cdrom_sector_type == 4) - { - if (audio || !mode2 || cdrom_image[id].image_is_iso) - { - cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] Attempting to read a non-XA Mode 2 Form 1 sector from an audio track\n", id); - return 0; - } - -read_mode2: - if (!(cdrom_sector_flags & 0xf0)) /* 0x00 and 0x08 are illegal modes */ - { - cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] 0x00 and 0x08 are illegal modes\n", id); - return 0; - } - - if (((cdrom_sector_flags & 0xf0) == 0xb0) || ((cdrom_sector_flags & 0xf0) == 0xd0)) /* 0xBx and 0xDx are illegal modes */ - { - cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] 0xBx and 0xDx are illegal modes\n", id); - return 0; - } - - if ((cdrom_sector_flags & 0x06) == 0x06) - { - cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] Invalid error flags\n", id); - return 0; - } - - if (((cdrom_sector_flags & 0x700) == 0x300) || ((cdrom_sector_flags & 0x700) > 0x400)) - { - cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] Invalid subchannel data flags (%02X)\n", id, cdrom_sector_flags & 0x700); - return 0; - } - - if ((cdrom_sector_flags & 0x18) == 0x08) /* EDC/ECC without user data is an illegal mode */ - { - cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] EDC/ECC without user data is an illegal mode\n", id); - return 0; - } - - cdimg[id]->ReadSector(cdrom_sector_buffer.buffer, true, real_pos); - - cdrom_sector_size = 0; - - if (cdrom_sector_flags & 0x80) /* Sync */ - { - cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] Sync\n", id); - memcpy(temp_b, raw_buffer, 12); - cdrom_sector_size += 12; - temp_b += 12; - } - - if (cdrom_sector_flags & 0x20) /* Header */ - { - cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] Header\n", id); - memcpy(temp_b, raw_buffer + 12, 4); - cdrom_sector_size += 4; - temp_b += 4; - } - - /* Mode 1 sector, expected type is 1 type. */ - if (cdrom_sector_flags & 0x40) /* Sub-header */ - { - cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] Sub-header\n", id); - memcpy(temp_b, raw_buffer + 16, 8); - cdrom_sector_size += 8; - temp_b += 8; - } - - if (cdrom_sector_flags & 0x10) /* User data */ - { - cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] User data\n", id); - memcpy(temp_b, raw_buffer + 24, 2048); - cdrom_sector_size += 2048; - temp_b += 2048; - } - - if (cdrom_sector_flags & 0x08) /* EDC/ECC */ - { - cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] EDC/ECC\n", id); - memcpy(temp_b, raw_buffer + 2072, 280); - cdrom_sector_size += 280; - temp_b += 280; - } - } - else - { - if (mode2) - { - goto read_mode2; - } - else - { - if (audio) - { - goto read_audio; - } - else - { - goto read_mode1; - } - } - } - - if ((cdrom_sector_flags & 0x06) == 0x02) - { - /* Add error flags. */ - cdrom_image_log("CD-ROM %i: Error flags\n", id); - memcpy(b + cdrom_sector_size, extra_buffer, 294); - cdrom_sector_size += 294; - } - else if ((cdrom_sector_flags & 0x06) == 0x04) - { - /* Add error flags. */ - cdrom_image_log("CD-ROM %i: Full error flags\n", id); - memcpy(b + cdrom_sector_size, extra_buffer, 296); - cdrom_sector_size += 296; - } - - if ((cdrom_sector_flags & 0x700) == 0x100) - { - cdrom_image_log("CD-ROM %i: Raw subchannel data\n", id); - memcpy(b + cdrom_sector_size, extra_buffer, 96); - cdrom_sector_size += 96; - } - else if ((cdrom_sector_flags & 0x700) == 0x200) - { - cdrom_image_log("CD-ROM %i: Q subchannel data\n", id); - memcpy(b + cdrom_sector_size, extra_buffer, 16); - cdrom_sector_size += 16; - } - else if ((cdrom_sector_flags & 0x700) == 0x400) - { - cdrom_image_log("CD-ROM %i: R/W subchannel data\n", id); - memcpy(b + cdrom_sector_size, extra_buffer, 96); - cdrom_sector_size += 96; - } - - *len = cdrom_sector_size; - - return 1; -} - - -static void lba_to_msf(uint8_t *buf, int lba) -{ - lba += 150; - buf[0] = (lba / 75) / 60; - buf[1] = (lba / 75) % 60; - buf[2] = lba % 75; -} - -static uint32_t image_size(uint8_t id) -{ - return cdrom_image[id].cdrom_capacity; -} - -static int image_readtoc(uint8_t id, unsigned char *b, unsigned char starttrack, int msf, int maxlen, int single) -{ - if (!cdimg[id]) return 0; - int len=4; - int c,d; - uint32_t temp; - - int first_track; - int last_track; - int number; - unsigned char attr; - TMSF tmsf; - cdimg[id]->GetAudioTracks(first_track, last_track, tmsf); - - b[2] = first_track; - b[3] = last_track; - - d = 0; - for (c = 0; c <= last_track; c++) - { - cdimg[id]->GetAudioTrackInfo(c+1, number, tmsf, attr); - if (number >= starttrack) - { - d=c; - break; - } - } - cdimg[id]->GetAudioTrackInfo(c+1, number, tmsf, attr); - b[2] = number; - - for (c = d; c <= last_track; c++) - { - if ((len + 8) > maxlen) - break; - cdimg[id]->GetAudioTrackInfo(c+1, number, tmsf, attr); - -// pclog("Len %i max %i Track %02X - %02X %02X %02i:%02i:%02i %08X\n",len,maxlen,toc[c].cdte_track,toc[c].cdte_adr,toc[c].cdte_ctrl,toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame,MSFtoLBA(toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame)); - b[len++] = 0; /* reserved */ - b[len++] = attr; - b[len++] = number; /* track number */ - b[len++] = 0; /* reserved */ - - if (msf) - { - b[len++] = 0; - b[len++] = tmsf.min; - b[len++] = tmsf.sec; - b[len++] = tmsf.fr; - } - else - { - temp = MSFtoLBA(tmsf.min, tmsf.sec, tmsf.fr) - 150; - b[len++] = temp >> 24; - b[len++] = temp >> 16; - b[len++] = temp >> 8; - b[len++] = temp; - } - if (single) - break; - } - b[0] = (uint8_t)(((len-2) >> 8) & 0xff); - b[1] = (uint8_t)((len-2) & 0xff); - /* - pclog("Table of Contents:\n"); - pclog("First track - %02X\n", first_track); - pclog("Last track - %02X\n", last_track); - for (c = 0; c <= last_track; c++) - { - cdimg[id]->GetAudioTrackInfo(c+1, number, tmsf, attr); - pclog("Track %02X - number %02X control %02X adr %02X address %02X %02X %02X %02X\n", c, number, attr, 0, 0, tmsf.min, tmsf.sec, tmsf.fr); - } - for (c = 0;c <= last_track; c++) { - cdimg[id]->GetAudioTrackInfo(c+1, number, tmsf, attr); - pclog("Track %02X - number %02X control %02X adr %02X address %06X\n", c, number, attr, 0, MSF_TO_FRAMES(tmsf.min, tmsf.sec, tmsf.fr)); - } - */ - return len; -} - -static int image_readtoc_session(uint8_t id, unsigned char *b, int msf, int maxlen) -{ - int len = 4; - - int number; - TMSF tmsf; - unsigned char attr; - - if (!cdimg[id]) return 0; - - cdimg[id]->GetAudioTrackInfo(1, number, tmsf, attr); - - if (number == 0) - { - number = 1; - } - - b[2] = 1; - b[3] = 1; - b[len++] = 0; /* reserved */ - b[len++] = attr; - b[len++] = number; /* track number */ - b[len++] = 0; /* reserved */ - if (msf) - { - b[len++] = 0; - b[len++] = tmsf.min; - b[len++] = tmsf.sec; - b[len++] = tmsf.fr; - } - else - { - uint32_t temp = MSFtoLBA(tmsf.min, tmsf.sec, tmsf.fr) - 150; /* Do the - 150. */ - b[len++] = temp >> 24; - b[len++] = temp >> 16; - b[len++] = temp >> 8; - b[len++] = temp; - } - - if (maxlen < len) - { - return maxlen; - } - - return len; -} - -static int image_readtoc_raw(uint8_t id, unsigned char *b, int msf, int maxlen) -{ - int track; - int len = 4; - - int first_track; - int last_track; - int number; - unsigned char attr; - TMSF tmsf; - int lb; - - if (!cdimg[id]) return 0; - - cdimg[id]->GetAudioTracks(first_track, last_track, tmsf); - - b[2] = first_track; - b[3] = last_track; - - for (track = first_track; track <= last_track; track++) - { - if ((len + 11) > maxlen) - { - cdrom_image_log("image_readtocraw: This iteration would fill the buffer beyond the bounds, aborting...\n"); - return len; - } - - cdimg[id]->GetAudioTrackInfo(track, number, tmsf, attr); - - b[len++] = track; - b[len++]= attr; - b[len++]=0; - b[len++]=0; - b[len++]=0; - b[len++]=0; - b[len++]=0; - b[len++]=0; - b[len++] = tmsf.min; - b[len++] = tmsf.sec; - b[len++] = tmsf.fr; - } - return len; -} - -static int image_status(uint8_t id) -{ - if (!cdimg[id]) return CD_STATUS_EMPTY; - if (cdrom_image[id].image_is_iso) return CD_STATUS_DATA_ONLY; - if (cdimg[id]->HasAudioTracks()) - { - switch(cdrom_image[id].cd_state) - { - case CD_PLAYING: - return CD_STATUS_PLAYING; - case CD_PAUSED: - return CD_STATUS_PAUSED; - case CD_STOPPED: - default: - return CD_STATUS_STOPPED; - } - } - return CD_STATUS_DATA_ONLY; -} - -void image_reset(uint8_t id) -{ -} - -void image_close(uint8_t id) -{ - cdrom_image[id].cd_state = CD_STOPPED; - if (cdimg[id]) - { - delete cdimg[id]; - cdimg[id] = NULL; - } - memset(cdrom_image[id].image_path, 0, 2048); -} - -static char afn[1024]; - -int image_open(uint8_t id, wchar_t *fn) -{ - if (wcscmp(fn, cdrom_image[id].image_path) != 0) - { - cdrom_image[id].image_changed = 1; - } - - /* Make sure image_changed stays when changing from an image to another image. */ - if (!cdrom_image[id].image_inited && (cdrom_drives[id].host_drive != 200)) cdrom_image[id].image_changed = 0; - - if (!cdrom_image[id].image_inited || cdrom_image[id].image_changed) - { - _swprintf(cdrom_image[id].image_path, L"%ws", fn); - } - - if (!wcsicmp(get_extension_w(fn), L"ISO")) - { - cdrom_image[id].image_is_iso = 1; - } - else - { - cdrom_image[id].image_is_iso = 0; - } - - cdimg[id] = new CDROM_Interface_Image(); - wcstombs(afn, fn, (wcslen(fn) << 1) + 2); - if (!cdimg[id]->SetDevice(afn, false)) - { - image_close(id); - cdrom_set_null_handler(id); - return 1; - } - cdrom_image[id].cd_state = CD_STOPPED; - cdrom[id].seek_pos = 0; - cdrom_image[id].cd_buflen = 0; - cdrom_image[id].cdrom_capacity = image_get_last_block(id, 0, 0, 4096, 0) + 1; - cdrom_drives[id].handler = &image_cdrom; - - if (!cdrom_image[id].image_inited || cdrom_image[id].image_changed) - { - if (!cdrom_image[id].image_inited) - cdrom_image[id].image_inited = 1; - } - - update_status_bar_icon_state(0x10 | id, 0); - return 0; -} - -static void image_exit(uint8_t id) -{ - cdrom_image[id].image_inited = 0; -} - -/* TODO: Check for what data type a mixed CD is. */ -static int image_media_type_id(uint8_t id) -{ - if (!cdrom_image[id].image_is_iso) - { - return 3; /* Mixed mode CD. */ - } - - if (image_size(id) <= 405000) - { - return 1; /* Data CD. */ - } - else - { - return 65; /* DVD. */ - } -} - -CDROM image_cdrom = -{ - image_ready, - image_medium_changed, - image_media_type_id, - image_audio_callback, - image_audio_stop, - image_readtoc, - image_readtoc_session, - image_readtoc_raw, - image_getcurrentsubchannel, - NULL, - image_readsector_raw, - image_playaudio, - image_load, - image_eject, - image_pause, - image_resume, - image_size, - image_status, - image_is_track_audio, - image_stop, - image_exit -}; diff --git a/src/cdrom-image.h b/src/cdrom-image.h deleted file mode 100644 index 4ea4cb78f..000000000 --- a/src/cdrom-image.h +++ /dev/null @@ -1,28 +0,0 @@ -/* Copyright holders: RichardG867, Tenshi - see COPYING for more details -*/ -#ifndef CDROM_IMAGE_H -#define CDROM_IMAGE_H - -/* this header file lists the functions provided by - various platform specific cdrom-ioctl files */ - -#ifdef __cplusplus -extern "C" { -#endif - -extern int image_open(uint8_t id, wchar_t *fn); -extern void image_reset(uint8_t id); - -extern void image_close(uint8_t id); - -void update_status_bar_icon_state(int tag, int state); -extern void cdrom_set_null_handler(uint8_t id); - -void pclog(const char *format, ...); - -#ifdef __cplusplus -} -#endif - -#endif /* ! CDROM_IMAGE_H */ diff --git a/src/cdrom-ioctl-linux.c b/src/cdrom-ioctl-linux.c deleted file mode 100644 index 5b993b612..000000000 --- a/src/cdrom-ioctl-linux.c +++ /dev/null @@ -1,725 +0,0 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ -/*Linux CD-ROM support via IOCTL*/ - -#include -#include -#include -#include -#include "ibm.h" -#include "ide.h" -#include "cdrom-ioctl.h" - -static ATAPI ioctl_atapi; - -static uint32_t last_block = 0; -static uint32_t cdrom_capacity = 0; -static int ioctl_inited = 0; -static char ioctl_path[8]; -static int tocvalid = 0; -static struct cdrom_tocentry toc[100]; -static int first_track, last_track; - -int old_cdrom_drive; - -#define MSFtoLBA(m,s,f) (((((m*60)+s)*75)+f)-150) - -enum -{ - CD_STOPPED = 0, - CD_PLAYING, - CD_PAUSED -}; - -static int ioctl_cd_state = CD_STOPPED; -static uint32_t ioctl_cd_pos = 0, ioctl_cd_end = 0; -#define BUF_SIZE 32768 -static int16_t cd_buffer[BUF_SIZE]; -static int cd_buflen = 0; -void ioctl_audio_callback(int16_t *output, int len) -{ - int fd; - struct cdrom_read_audio read_audio; - -// pclog("Audio callback %08X %08X %i %i %i %04X %i\n", ioctl_cd_pos, ioctl_cd_end, ioctl_cd_state, cd_buflen, len, cd_buffer[4], GetTickCount()); - if (ioctl_cd_state != CD_PLAYING) - { - memset(output, 0, len * 2); - return; - } - fd = open("/dev/cdrom", O_RDONLY|O_NONBLOCK); - - if (fd <= 0) - { - memset(output, 0, len * 2); - return; - } - - while (cd_buflen < len) - { - if (ioctl_cd_pos < ioctl_cd_end) - { - read_audio.addr.lba = ioctl_cd_pos - 150; - read_audio.addr_format = CDROM_LBA; - read_audio.nframes = 1; - read_audio.buf = (__u8 *)&cd_buffer[cd_buflen]; - - if (ioctl(fd, CDROMREADAUDIO, &read_audio) < 0) - { -// pclog("DeviceIoControl returned false\n"); - memset(&cd_buffer[cd_buflen], 0, (BUF_SIZE - cd_buflen) * 2); - ioctl_cd_state = CD_STOPPED; - cd_buflen = len; - } - else - { -// pclog("DeviceIoControl returned true\n"); - ioctl_cd_pos++; - cd_buflen += (2352 / 2); - } - } - else - { - memset(&cd_buffer[cd_buflen], 0, (BUF_SIZE - cd_buflen) * 2); - ioctl_cd_state = CD_STOPPED; - cd_buflen = len; - } - } - close(fd); - memcpy(output, cd_buffer, len * 2); -// for (c = 0; c < BUF_SIZE - len; c++) -// cd_buffer[c] = cd_buffer[c + cd_buflen]; - memcpy(&cd_buffer[0], &cd_buffer[len], (BUF_SIZE - len) * 2); - cd_buflen -= len; -// pclog("Done %i\n", GetTickCount()); -} - -void ioctl_audio_stop() -{ - ioctl_cd_state = CD_STOPPED; -} - -static int get_track_nr(uint32_t pos) -{ - int c; - int track = 0; - - if (!tocvalid) - return 0; - - for (c = first_track; c < last_track; c++) - { - uint32_t track_address = toc[c].cdte_addr.msf.frame + - (toc[c].cdte_addr.msf.second * 75) + - (toc[c].cdte_addr.msf.minute * 75 * 60); -//pclog("get_track_nr: track=%i pos=%x track_address=%x\n", c, pos, track_address); - if (track_address <= pos) - track = c; - } - return track; -} - -static int is_track_audio(uint32_t pos) -{ - int c; - int control = 0; - - if (!tocvalid) - return 0; - - for (c = first_track; c < last_track; c++) - { - uint32_t track_address = toc[c].cdte_addr.msf.frame + - (toc[c].cdte_addr.msf.second * 75) + - (toc[c].cdte_addr.msf.minute * 75 * 60); -//pclog("get_track_nr: track=%i pos=%x track_address=%x\n", c, pos, track_address); - if (track_address <= pos) - control = toc[c].cdte_ctrl; - } - return (control & 4) ? 0 : 1; -} - -static int ioctl_is_track_audio(uint32_t pos, int ismsf) -{ - if (ismsf) - { - int m = (pos >> 16) & 0xff; - int s = (pos >> 8) & 0xff; - int f = pos & 0xff; - pos = MSFtoLBA(m, s, f); - } - return is_track_audio(pos); -} - -static void ioctl_playaudio(uint32_t pos, uint32_t len, int ismsf) -{ -// pclog("Play audio - %08X %08X %i\n", pos, len, ismsf); - if (ismsf) - { - pos = (pos & 0xff) + (((pos >> 8) & 0xff) * 75) + (((pos >> 16) & 0xff) * 75 * 60); - len = (len & 0xff) + (((len >> 8) & 0xff) * 75) + (((len >> 16) & 0xff) * 75 * 60); -// pclog("MSF - pos = %08X len = %08X\n", pos, len); - } - else - len += pos; - ioctl_cd_pos = pos;// + 150; - ioctl_cd_end = pos+len;// + 150; - ioctl_cd_state = CD_PLAYING; - if (ioctl_cd_pos < 150) - ioctl_cd_pos = 150; -// pclog("Audio start %08X %08X %i %i %i\n", ioctl_cd_pos, ioctl_cd_end, ioctl_cd_state, 0, len); -} - -static void ioctl_pause(void) -{ - if (ioctl_cd_state == CD_PLAYING) - ioctl_cd_state = CD_PAUSED; -} - -static void ioctl_resume(void) -{ - if (ioctl_cd_state == CD_PAUSED) - ioctl_cd_state = CD_PLAYING; -} - -static void ioctl_stop(void) -{ - ioctl_cd_state = CD_STOPPED; -} - -static void ioctl_seek(uint32_t pos) -{ -// pclog("Seek %08X\n", pos); - ioctl_cd_pos = pos; - ioctl_cd_state = CD_STOPPED; -} - -static int read_toc(int fd, struct cdrom_tocentry *btoc) -{ - struct cdrom_tochdr toc_hdr; - int track, err; -//pclog("read_toc\n"); - err = ioctl(fd, CDROMREADTOCHDR, &toc_hdr); - if (err == -1) - { - pclog("read_toc: CDROMREADTOCHDR failed\n"); - return 0; - } - - first_track = toc_hdr.cdth_trk0; - last_track = toc_hdr.cdth_trk1; -//pclog("read_toc: first_track=%i last_track=%i\n", first_track, last_track); - memset(btoc, 0, sizeof(cdrom_tocentry)); - - for (track = toc_hdr.cdth_trk0; track <= toc_hdr.cdth_trk1; track++) - { - btoc[track].cdte_track = track; - btoc[track].cdte_format = CDROM_MSF; - err = ioctl(fd, CDROMREADTOCENTRY, &btoc[track]); - if (err == -1) - { -// pclog("read_toc: CDROMREADTOCENTRY failed on track %i\n", track); - return 0; - } -// pclog("read_toc: Track %02X - number %02X control %02X adr %02X address %02X %02X %02X %02X\n", track, toc[track].cdte_track, toc[track].cdte_ctrl, toc[track].cdte_adr, 0, toc[track].cdte_addr.msf.minute, toc[track].cdte_addr.msf.second, toc[track].cdte_addr.msf.frame); - } - return 1; -} - -static int ioctl_ready(void) -{ - long size; - int temp; - struct cdrom_tochdr toc_hdr; - struct cdrom_tocentry toc_entry; - int err; - int fd = open("/dev/cdrom", O_RDONLY|O_NONBLOCK); - - if (fd <= 0) - return 0; - - err = ioctl(fd, CDROMREADTOCHDR, &toc_hdr); - if (err == -1) - { - close(fd); - return 0; - } -// pclog("CDROMREADTOCHDR: start track=%i end track=%i\n", toc_hdr.cdth_trk0, toc_hdr.cdth_trk1); - toc_entry.cdte_track = toc_hdr.cdth_trk1; - toc_entry.cdte_format = CDROM_MSF; - err = ioctl(fd, CDROMREADTOCENTRY, &toc_entry); - if (err == -1) - { - close(fd); - return 0; - } -// pclog("CDROMREADTOCENTRY: addr=%02i:%02i:%02i\n", toc_entry.cdte_addr.msf.minute, toc_entry.cdte_addr.msf.second, toc_entry.cdte_addr.msf.frame); - if ((toc_entry.cdte_addr.msf.minute != toc[toc_hdr.cdth_trk1].cdte_addr.msf.minute) || - (toc_entry.cdte_addr.msf.second != toc[toc_hdr.cdth_trk1].cdte_addr.msf.second) || - (toc_entry.cdte_addr.msf.frame != toc[toc_hdr.cdth_trk1].cdte_addr.msf.frame ) || - !tocvalid) - { - int track; - ioctl_cd_state = CD_STOPPED; - - tocvalid = read_toc(fd, toc); - close(fd); - return 1; - } - close(fd); - return 1; -} - -static int ioctl_get_last_block(unsigned char starttrack, int msf, int maxlen, int single) -{ - int c; - int lb = 0; - int tv = 0; - struct cdrom_tocentry lbtoc[100]; - int fd = open("/dev/cdrom", O_RDONLY|O_NONBLOCK); - - if (fd <= 0) - return 0; - - ioctl_cd_state = CD_STOPPED; - - tv = read_toc(fd, lbtoc); - - close(fd); - - if (!tv) - return 0; - - last_block = 0; - for (c = 0; c <= last_track; c++) - { - uint32_t address; - address = MSFtoLBA(toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame); - if (address > last_block) - lb = address; - } - return lb; -} - -static int ioctl_medium_changed(void) -{ - long size; - int temp; - struct cdrom_tochdr toc_hdr; - struct cdrom_tocentry toc_entry; - int err; - int fd = open("/dev/cdrom", O_RDONLY|O_NONBLOCK); - - if (fd <= 0) - return 0; - - err = ioctl(fd, CDROMREADTOCHDR, &toc_hdr); - if (err == -1) - { - close(fd); - return 0; - } - toc_entry.cdte_track = toc_hdr.cdth_trk1; - toc_entry.cdte_format = CDROM_MSF; - err = ioctl(fd, CDROMREADTOCENTRY, &toc_entry); - if (err == -1) - { - close(fd); - return 0; - } -// pclog("CDROMREADTOCENTRY: addr=%02i:%02i:%02i\n", toc_entry.cdte_addr.msf.minute, toc_entry.cdte_addr.msf.second, toc_entry.cdte_addr.msf.frame); - if ((toc_entry.cdte_addr.msf.minute != toc[toc_hdr.cdth_trk1].cdte_addr.msf.minute) || - (toc_entry.cdte_addr.msf.second != toc[toc_hdr.cdth_trk1].cdte_addr.msf.second) || - (toc_entry.cdte_addr.msf.frame != toc[toc_hdr.cdth_trk1].cdte_addr.msf.frame )) - { - cdrom_capacity = ioctl_get_last_block(0, 0, 4096, 0); - return 1; - } - return 0; -} - -static uint8_t ioctl_getcurrentsubchannel(uint8_t *b, int msf) -{ - struct cdrom_subchnl sub; - uint32_t cdpos = ioctl_cd_pos; - int track = get_track_nr(cdpos); - uint32_t track_address = toc[track].cdte_addr.msf.frame + - (toc[track].cdte_addr.msf.second * 75) + - (toc[track].cdte_addr.msf.minute * 75 * 60); - long size; - int pos=0; - int err; - uint8_t ret; -//pclog("ioctl_getsubchannel: cdpos=%x track_address=%x track=%i\n", cdpos, track_address, track); - if (ioctl_cd_state == CD_PLAYING) - ret = 0x11; - else if (ioctl_cd_state == CD_PAUSED) - ret = 0x12; - else - ret = 0x13; - - b[pos++] = (toc[track].cdte_adr << 4) | toc[track].cdte_ctrl; - b[pos++] = track; - b[pos++] = 0; - - if (msf) - { - uint32_t dat = cdpos; - b[pos + 3] = (uint8_t)(dat % 75); dat /= 75; - b[pos + 2] = (uint8_t)(dat % 60); dat /= 60; - b[pos + 1] = (uint8_t)dat; - b[pos] = 0; - pos += 4; - dat = cdpos - track_address; - b[pos + 3] = (uint8_t)(dat % 75); dat /= 75; - b[pos + 2] = (uint8_t)(dat % 60); dat /= 60; - b[pos + 1] = (uint8_t)dat; - b[pos] = 0; - pos += 4; - } - else - { - b[pos++] = (cdpos >> 24) & 0xff; - b[pos++] = (cdpos >> 16) & 0xff; - b[pos++] = (cdpos >> 8) & 0xff; - b[pos++] = cdpos & 0xff; - cdpos -= track_address; - b[pos++] = (cdpos >> 24) & 0xff; - b[pos++] = (cdpos >> 16) & 0xff; - b[pos++] = (cdpos >> 8) & 0xff; - b[pos++] = cdpos & 0xff; - } - - return ret; -} - -static void ioctl_eject(void) -{ - int fd = open("/dev/cdrom", O_RDONLY|O_NONBLOCK); - - if (fd <= 0) - return; - - ioctl(fd, CDROMEJECT); - - close(fd); -} - -static void ioctl_load(void) -{ - int fd = open("/dev/cdrom", O_RDONLY|O_NONBLOCK); - - if (fd <= 0) - return; - - ioctl(fd, CDROMEJECT); - - close(fd); - - cdrom_capacity = ioctl_get_last_block(0, 0, 4096, 0); -} - -union -{ - struct cdrom_msf *msf; - char b[CD_FRAMESIZE_RAW]; -} raw_read_params; - -static int lba_to_msf(int lba) -{ - return (((lba / 75) / 60) << 16) + (((lba / 75) % 60) << 8) + (lba % 75); -} - -static int ioctl_sector_data_type(int sector, int ismsf) -{ - return 2; /* Always Mode 1 */ -} - -static void ioctl_readsector_raw(uint8_t *b, int sector) -{ - int err; - int imsf = lba_to_msf(sector); - int cdrom = open("/dev/cdrom", O_RDONLY|O_NONBLOCK); - - if (cdrom <= 0) - return; - - raw_read_params.msf = malloc(sizeof(struct cdrom_msf)); - raw_read_params.msf->cdmsf_frame0 = imsf & 0xff; - raw_read_params.msf->cdmsf_sec0 = (imsf >> 8) & 0xff; - raw_read_params.msf->cdmsf_min0 = (imsf >> 16) & 0xff; - - /* This will read the actual raw sectors from the disc. */ - err = ioctl(cdrom, CDROMREADRAW, (void *) &raw_read_params); - if (err == -1) - { - pclog("read_toc: CDROMREADTOCHDR failed\n"); - return; - } - - memcpy(b, raw_read_params.b, 2352); - - close(cdrom); - - free(raw_read_params.msf); -} - -static int ioctl_readtoc(unsigned char *b, unsigned char starttrack, int msf, int maxlen, int single) -{ - int len=4; - long size; - int c,d; - uint32_t temp; - int fd = open("/dev/cdrom", O_RDONLY|O_NONBLOCK); - - if (fd <= 0) - return 0; - - ioctl_cd_state = CD_STOPPED; - - tocvalid = read_toc(fd, toc); - - close(fd); - - if (!tocvalid) - return 4; - -// pclog("Read TOC done! %i\n",single); - b[2] = first_track; - b[3] = last_track; - d = 0; -//pclog("Read TOC starttrack=%i\n", starttrack); - for (c = 1; c <= last_track; c++) - { - if (toc[c].cdte_track >= starttrack) - { - d = c; - break; - } - } - b[2] = toc[c].cdte_track; - last_block = 0; - for (c = d; c <= last_track; c++) - { - uint32_t address; - if ((len + 8) > maxlen) - break; -// pclog("Len %i max %i Track %02X - %02X %02X %02i:%02i:%02i %08X\n",len,maxlen,toc[c].cdte_track,toc[c].cdte_adr,toc[c].cdte_ctrl,toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame,MSFtoLBA(toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame)); - b[len++] = 0; /*Reserved*/ - b[len++] = (toc[c].cdte_adr << 4) | toc[c].cdte_ctrl; - b[len++] = toc[c].cdte_track; - b[len++] = 0; /*Reserved*/ - address = MSFtoLBA(toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame); - if (address > last_block) - last_block = address; - - if (msf) - { - b[len++] = 0; - b[len++] = toc[c].cdte_addr.msf.minute; - b[len++] = toc[c].cdte_addr.msf.second; - b[len++] = toc[c].cdte_addr.msf.frame; - } - else - { - temp = MSFtoLBA(toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame); - b[len++] = temp >> 24; - b[len++] = temp >> 16; - b[len++] = temp >> 8; - b[len++] = temp; - } - if (single) - break; - } - b[0] = (uint8_t)(((len-2) >> 8) & 0xff); - b[1] = (uint8_t)((len-2) & 0xff); -/* pclog("Table of Contents (%i bytes) : \n", size); - pclog("First track - %02X\n", first_track); - pclog("Last track - %02X\n", last_track); - for (c = 0; c <= last_track; c++) - pclog("Track %02X - number %02X control %02X adr %02X address %02X %02X %02X %02X\n", c, toc[c].cdte_track, toc[c].cdte_ctrl, toc[c].cdte_adr, 0, toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame); - for (c = 0;c <= last_track; c++) - pclog("Track %02X - number %02X control %02X adr %02X address %06X\n", c, toc[c].cdte_track, toc[c].cdte_ctrl, toc[c].cdte_adr, MSFtoLBA(toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame));*/ - return len; -} - -static int ioctl_readtoc_session(unsigned char *b, int msf, int maxlen) -{ - struct cdrom_multisession session; - int len = 4; - int err; - int fd = open("/dev/cdrom", O_RDONLY|O_NONBLOCK); - - if (fd <= 0) - return 0; - - session.addr_format = CDROM_MSF; - err = ioctl(fd, CDROMMULTISESSION, &session); - - if (err == -1) - { - close(fd); - return 0; - } - - b[2] = 0; - b[3] = 0; - b[len++] = 0; /*Reserved*/ - b[len++] = (toc[0].cdte_adr << 4) | toc[0].cdte_ctrl; - b[len++] = toc[0].cdte_track; - b[len++] = 0; /*Reserved*/ - if (msf) - { - b[len++] = 0; - b[len++] = session.addr.msf.minute; - b[len++] = session.addr.msf.second; - b[len++] = session.addr.msf.frame; - } - else - { - uint32_t temp = MSFtoLBA(session.addr.msf.minute, session.addr.msf.second, session.addr.msf.frame); - b[len++] = temp >> 24; - b[len++] = temp >> 16; - b[len++] = temp >> 8; - b[len++] = temp; - } - - return len; -} - -static int ioctl_readtoc_raw(unsigned char *b, int maxlen) -{ - struct cdrom_tochdr toc_hdr; - struct cdrom_tocentry toc2[100]; - int track, err; - int len = 4; - int fd = open("/dev/cdrom", O_RDONLY|O_NONBLOCK); -//pclog("read_toc\n"); - if (fd <= 0) - return 0; - - err = ioctl(fd, CDROMREADTOCHDR, &toc_hdr); - if (err == -1) - { - pclog("read_toc: CDROMREADTOCHDR failed\n"); - return 0; - } - - b[2] = toc_hdr.cdth_trk0; - b[3] = toc_hdr.cdth_trk1; - - //pclog("read_toc: first_track=%i last_track=%i\n", first_track, last_track); - memset(toc, 0, sizeof(toc)); - - for (track = toc_hdr.cdth_trk0; track <= toc_hdr.cdth_trk1; track++) - { - if ((len + 11) > maxlen) - { - pclog("ioctl_readtocraw: This iteration would fill the buffer beyond the bounds, aborting...\n"); - close(fd); - return len; - } - - toc2[track].cdte_track = track; - toc2[track].cdte_format = CDROM_MSF; - err = ioctl(fd, CDROMREADTOCENTRY, &toc2[track]); - if (err == -1) - { -// pclog("read_toc: CDROMREADTOCENTRY failed on track %i\n", track); - close(fd); - return 0; - } -// pclog("read_toc: Track %02X - number %02X control %02X adr %02X address %02X %02X %02X %02X\n", track, toc[track].cdte_track, toc[track].cdte_ctrl, toc[track].cdte_adr, 0, toc[track].cdte_addr.msf.minute, toc[track].cdte_addr.msf.second, toc[track].cdte_addr.msf.frame); - - b[len++] = toc2[track].cdte_track; - b[len++]= (toc2[track].cdte_adr << 4) | toc[track].cdte_ctrl; - b[len++]=0; - b[len++]=0; - b[len++]=0; - b[len++]=0; - b[len++]=0; - b[len++]=0; - b[len++] = toc2[track].cdte_addr.msf.minute; - b[len++] = toc2[track].cdte_addr.msf.second; - b[len++] = toc2[track].cdte_addr.msf.frame; - } - close(fd); - return len; -} - -static uint32_t ioctl_size() -{ - return cdrom_capacity; -} - -static int ioctl_status() -{ - if (!(ioctl_ready) && (cdrom_drive <= 0)) return CD_STATUS_EMPTY; - - switch(ioctl_cd_state) - { - case CD_PLAYING: - return CD_STATUS_PLAYING; - case CD_PAUSED: - return CD_STATUS_PAUSED; - case CD_STOPPED: - return CD_STATUS_STOPPED; - } -} -void ioctl_reset() -{ - int fd = open("/dev/cdrom", O_RDONLY|O_NONBLOCK); -//pclog("ioctl_reset: fd=%i\n", fd); - tocvalid = 0; - - if (fd <= 0) - return; - - tocvalid = read_toc(fd, toc); - - close(fd); -} - -int ioctl_open(char d) -{ - atapi=&ioctl_atapi; - return 0; -} - -void ioctl_close(void) -{ -} - -static void ioctl_exit(void) -{ - ioctl_stop(); - ioctl_inited = 0; - tocvalid=0; -} - -static ATAPI ioctl_atapi= -{ - ioctl_ready, - ioctl_medium_changed, - ioctl_readtoc, - ioctl_readtoc_session, - ioctl_readtoc_raw, - ioctl_getcurrentsubchannel, - NULL, - NULL, - NULL, - ioctl_sector_data_type, - ioctl_readsector_raw, - ioctl_playaudio, - ioctl_seek, - ioctl_load, - ioctl_eject, - ioctl_pause, - ioctl_resume, - ioctl_size, - ioctl_status, - ioctl_is_track_audio, - ioctl_stop, - ioctl_exit -}; diff --git a/src/cdrom-ioctl.c b/src/cdrom-ioctl.c deleted file mode 100644 index 98c7cc538..000000000 --- a/src/cdrom-ioctl.c +++ /dev/null @@ -1,1099 +0,0 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ -/*Win32 CD-ROM support via IOCTL*/ - -#define WINVER 0x0600 -#include -#include -#include "ntddcdrm.h" -#include "ntddscsi.h" -#include "ibm.h" -#include "cdrom.h" -#include "cdrom-ioctl.h" -#include "scsi.h" - -#define MSFtoLBA(m,s,f) ((((m*60)+s)*75)+f) - -static CDROM ioctl_cdrom; - -typedef struct -{ - HANDLE hIOCTL; - CDROM_TOC toc; -} cdrom_ioctl_windows_t; - -cdrom_ioctl_windows_t cdrom_ioctl_windows[CDROM_NUM]; - -enum -{ - CD_STOPPED = 0, - CD_PLAYING, - CD_PAUSED -}; - -int cdrom_ioctl_do_log = 0; - -void cdrom_ioctl_log(const char *format, ...) -{ -#ifdef ENABLE_CDROM_LOG - if (cdrom_ioctl_do_log) - { - va_list ap; - va_start(ap, format); - vprintf(format, ap); - va_end(ap); - fflush(stdout); - } -#endif -} - -void ioctl_audio_callback(uint8_t id, int16_t *output, int len) -{ - RAW_READ_INFO in; - DWORD count; - - if (cdrom_ioctl[id].cd_state != CD_PLAYING) - { - memset(output, 0, len * 2); - return; - } - while (cdrom_ioctl[id].cd_buflen < len) - { - if (cdrom[id].seek_pos < cdrom_ioctl[id].cd_end) - { - in.DiskOffset.LowPart = (cdrom[id].seek_pos - 150) * 2048; - in.DiskOffset.HighPart = 0; - in.SectorCount = 1; - in.TrackMode = CDDA; - ioctl_open(id, 0); - if (!DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_RAW_READ, &in, sizeof(in), &(cdrom_ioctl[id].cd_buffer[cdrom_ioctl[id].cd_buflen]), 2352, &count, NULL)) - { - memset(&(cdrom_ioctl[id].cd_buffer[cdrom_ioctl[id].cd_buflen]), 0, (BUF_SIZE - cdrom_ioctl[id].cd_buflen) * 2); - cdrom_ioctl[id].cd_state = CD_STOPPED; - cdrom_ioctl[id].cd_buflen = len; - } - else - { - cdrom[id].seek_pos++; - cdrom_ioctl[id].cd_buflen += (2352 / 2); - } - ioctl_close(id); - } - else - { - memset(&(cdrom_ioctl[id].cd_buffer[cdrom_ioctl[id].cd_buflen]), 0, (BUF_SIZE - cdrom_ioctl[id].cd_buflen) * 2); - cdrom_ioctl[id].cd_state = CD_STOPPED; - cdrom_ioctl[id].cd_buflen = len; - } - } - memcpy(output, cdrom_ioctl[id].cd_buffer, len * 2); - memcpy(&cdrom_ioctl[id].cd_buffer[0], &(cdrom_ioctl[id].cd_buffer[len]), (BUF_SIZE - len) * 2); - cdrom_ioctl[id].cd_buflen -= len; -} - -void ioctl_audio_stop(uint8_t id) -{ - cdrom_ioctl[id].cd_state = CD_STOPPED; -} - -static int get_track_nr(uint8_t id, uint32_t pos) -{ - int c; - int track = 0; - - if (!cdrom_ioctl[id].tocvalid) - { - return 0; - } - - if (cdrom_ioctl[id].last_track_pos == pos) - { - return cdrom_ioctl[id].last_track_nr; - } - - for (c = cdrom_ioctl_windows[id].toc.FirstTrack; c < cdrom_ioctl_windows[id].toc.LastTrack; c++) - { - uint32_t track_address = cdrom_ioctl_windows[id].toc.TrackData[c].Address[3] + - (cdrom_ioctl_windows[id].toc.TrackData[c].Address[2] * 75) + - (cdrom_ioctl_windows[id].toc.TrackData[c].Address[1] * 75 * 60); - - if (track_address <= pos) - { - track = c; - } - } - cdrom_ioctl[id].last_track_pos = pos; - cdrom_ioctl[id].last_track_nr = track; - - return track; -} - -static uint32_t get_track_msf(uint8_t id, uint32_t track_no) -{ - int c; - - if (!cdrom_ioctl[id].tocvalid) - { - return 0; - } - - for (c = cdrom_ioctl_windows[id].toc.FirstTrack; c < cdrom_ioctl_windows[id].toc.LastTrack; c++) - { - if (c == track_no) - { - return cdrom_ioctl_windows[id].toc.TrackData[c].Address[3] + (cdrom_ioctl_windows[id].toc.TrackData[c].Address[2] << 8) + (cdrom_ioctl_windows[id].toc.TrackData[c].Address[1] << 16); - } - } - return 0xffffffff; -} - -static void ioctl_playaudio(uint8_t id, uint32_t pos, uint32_t len, int ismsf) -{ - int m = 0, s = 0, f = 0; - uint32_t start_msf = 0, end_msf = 0; - if (!cdrom_drives[id].host_drive) - { - return; - } - if (ismsf == 2) - { - start_msf = get_track_msf(id, pos); - end_msf = get_track_msf(id, len); - if (start_msf == 0xffffffff) - { - return; - } - if (end_msf == 0xffffffff) - { - return; - } - m = (start_msf >> 16) & 0xff; - s = (start_msf >> 8) & 0xff; - f = start_msf & 0xff; - pos = MSFtoLBA(m, s, f); - m = (end_msf >> 16) & 0xff; - s = (end_msf >> 8) & 0xff; - f = end_msf & 0xff; - len = MSFtoLBA(m, s, f); - } - else if (ismsf == 1) - { - m = (pos >> 16) & 0xff; - s = (pos >> 8) & 0xff; - f = pos & 0xff; - - if (pos == 0xffffff) - { - cdrom_ioctl_log("Playing from current position (MSF)\n"); - pos = cdrom[id].seek_pos; - } - else - { - pos = MSFtoLBA(m, s, f); - } - - m = (len >> 16) & 0xff; - s = (len >> 8) & 0xff; - f = len & 0xff; - len = MSFtoLBA(m, s, f); - } - else if (ismsf == 0) - { - if (pos == 0xffffffff) - { - cdrom_ioctl_log("Playing from current position\n"); - pos = cdrom[id].seek_pos; - } - len += pos; - } - cdrom[id].seek_pos = pos; - cdrom_ioctl[id].cd_end = len; - if (cdrom[id].seek_pos < 150) - { - /* Adjust because the host expects a minimum adjusted LBA of 0 which is equivalent to an absolute LBA of 150. */ - cdrom[id].seek_pos = 150; - } - cdrom_ioctl[id].cd_state = CD_PLAYING; -} - -static void ioctl_pause(uint8_t id) -{ - if (!cdrom_drives[id].host_drive) - { - return; - } - if (cdrom_ioctl[id].cd_state == CD_PLAYING) - { - cdrom_ioctl[id].cd_state = CD_PAUSED; - } -} - -static void ioctl_resume(uint8_t id) -{ - if (!cdrom_drives[id].host_drive) - { - return; - } - if (cdrom_ioctl[id].cd_state == CD_PAUSED) - { - cdrom_ioctl[id].cd_state = CD_PLAYING; - } -} - -static void ioctl_stop(uint8_t id) -{ - if (!cdrom_drives[id].host_drive) - { - return; - } - cdrom_ioctl[id].cd_state = CD_STOPPED; -} - -static int ioctl_ready(uint8_t id) -{ - unsigned long size; - int temp; - CDROM_TOC ltoc; - if (!cdrom_drives[id].host_drive) - { - return 0; - } - ioctl_open(id, 0); - temp = DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, <oc, sizeof(ltoc), &size, NULL); - ioctl_close(id); - if (!temp) - { - return 0; - } - if ((ltoc.TrackData[ltoc.LastTrack].Address[1] != cdrom_ioctl_windows[id].toc.TrackData[cdrom_ioctl_windows[id].toc.LastTrack].Address[1]) || - (ltoc.TrackData[ltoc.LastTrack].Address[2] != cdrom_ioctl_windows[id].toc.TrackData[cdrom_ioctl_windows[id].toc.LastTrack].Address[2]) || - (ltoc.TrackData[ltoc.LastTrack].Address[3] != cdrom_ioctl_windows[id].toc.TrackData[cdrom_ioctl_windows[id].toc.LastTrack].Address[3]) || - !cdrom_ioctl[id].tocvalid || (cdrom_drives[id].host_drive != cdrom_drives[id].prev_host_drive)) - { - cdrom_ioctl[id].cd_state = CD_STOPPED; - if (cdrom_drives[id].host_drive != cdrom_drives[id].prev_host_drive) - { - cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; - } - return 1; - } - return 1; -} - -static int ioctl_get_last_block(uint8_t id, unsigned char starttrack, int msf, int maxlen, int single) -{ - unsigned long size; - int c, d = 0; - CDROM_TOC lbtoc; - int lb = 0; - if (!cdrom_drives[id].host_drive) - { - return 0; - } - cdrom_ioctl[id].cd_state = CD_STOPPED; - ioctl_open(id, 0); - DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, &lbtoc, sizeof(lbtoc), &size, NULL); - ioctl_close(id); - cdrom_ioctl[id].tocvalid=1; - for (c=d; c <= lbtoc.LastTrack; c++) - { - uint32_t address; - address = MSFtoLBA(cdrom_ioctl_windows[id].toc.TrackData[c].Address[1], cdrom_ioctl_windows[id].toc.TrackData[c].Address[2], cdrom_ioctl_windows[id].toc.TrackData[c].Address[3]); - if (address > lb) - { - lb = address; - } - } - return lb; -} - -static int ioctl_medium_changed(uint8_t id) -{ - unsigned long size; - int temp; - CDROM_TOC ltoc; - if (!cdrom_drives[id].host_drive) - { - return 0; /* This will be handled by the not ready handler instead. */ - } - ioctl_open(id, 0); - temp = DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, <oc,sizeof(ltoc), &size, NULL); - ioctl_close(id); - if (!temp) - { - return 0; /* Drive empty, a not ready handler matter, not disc change. */ - } - if (!cdrom_ioctl[id].tocvalid || (cdrom_drives[id].host_drive != cdrom_drives[id].prev_host_drive)) - { - cdrom_ioctl[id].cd_state = CD_STOPPED; - cdrom_ioctl_windows[id].toc = ltoc; - cdrom_ioctl[id].tocvalid = 1; - if (cdrom_drives[id].host_drive != cdrom_drives[id].prev_host_drive) - { - cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; - } - cdrom_ioctl[id].cdrom_capacity = ioctl_get_last_block(id, 0, 0, 4096, 0); - return 1; - } - else - { - if ((ltoc.TrackData[ltoc.LastTrack].Address[1] != cdrom_ioctl_windows[id].toc.TrackData[cdrom_ioctl_windows[id].toc.LastTrack].Address[1]) || - (ltoc.TrackData[ltoc.LastTrack].Address[2] != cdrom_ioctl_windows[id].toc.TrackData[cdrom_ioctl_windows[id].toc.LastTrack].Address[2]) || - (ltoc.TrackData[ltoc.LastTrack].Address[3] != cdrom_ioctl_windows[id].toc.TrackData[cdrom_ioctl_windows[id].toc.LastTrack].Address[3])) - { - cdrom_ioctl[id].cd_state = CD_STOPPED; - cdrom_ioctl_log("Setting TOC...\n"); - cdrom_ioctl_windows[id].toc = ltoc; - cdrom_ioctl[id].cdrom_capacity = ioctl_get_last_block(id, 0, 0, 4096, 0); - return 1; /* TOC mismatches. */ - } - } - return 0; /* None of the above, return 0. */ -} - -static uint8_t ioctl_getcurrentsubchannel(uint8_t id, uint8_t *b, int msf) -{ - CDROM_SUB_Q_DATA_FORMAT insub; - SUB_Q_CHANNEL_DATA sub; - unsigned long size; - int pos = 0, track; - uint32_t cdpos, track_address, dat; - - if (!cdrom_drives[id].host_drive) return 0; - - cdpos = cdrom[id].seek_pos; - - if (cdrom_ioctl[id].last_subchannel_pos == cdpos) - { - memcpy(&insub, cdrom_ioctl[id].sub_q_data_format, sizeof(insub)); - memcpy(&sub, cdrom_ioctl[id].sub_q_channel_data, sizeof(sub)); - } - else - { - insub.Format = IOCTL_CDROM_CURRENT_POSITION; - ioctl_open(id, 0); - DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_CDROM_READ_Q_CHANNEL,&insub,sizeof(insub),&sub,sizeof(sub),&size,NULL); - ioctl_close(id); - memset(cdrom_ioctl[id].sub_q_data_format, 0, 16); - memcpy(cdrom_ioctl[id].sub_q_data_format, &insub, sizeof(insub)); - memset(cdrom_ioctl[id].sub_q_channel_data, 0, 256); - memcpy(cdrom_ioctl[id].sub_q_channel_data, &sub, sizeof(sub)); - cdrom_ioctl[id].last_subchannel_pos = cdpos; - } - - if (cdrom_ioctl[id].cd_state == CD_PLAYING || cdrom_ioctl[id].cd_state == CD_PAUSED) - { - track = get_track_nr(id, cdpos); - track_address = cdrom_ioctl_windows[id].toc.TrackData[track].Address[3] + (cdrom_ioctl_windows[id].toc.TrackData[track].Address[2] * 75) + (cdrom_ioctl_windows[id].toc.TrackData[track].Address[1] * 75 * 60); - - cdrom_ioctl_log("cdpos = %i, track = %i, track_address = %i\n", cdpos, track, track_address); - - b[pos++] = sub.CurrentPosition.Control; - b[pos++] = track + 1; - b[pos++] = sub.CurrentPosition.IndexNumber; - - if (msf) - { - dat = cdpos; - b[pos + 3] = (uint8_t)(dat % 75); dat /= 75; - b[pos + 2] = (uint8_t)(dat % 60); dat /= 60; - b[pos + 1] = (uint8_t)dat; - b[pos] = 0; - pos += 4; - dat = cdpos - track_address; - b[pos + 3] = (uint8_t)(dat % 75); dat /= 75; - b[pos + 2] = (uint8_t)(dat % 60); dat /= 60; - b[pos + 1] = (uint8_t)dat; - b[pos] = 0; - pos += 4; - } - else - { - b[pos++] = (cdpos >> 24) & 0xff; - b[pos++] = (cdpos >> 16) & 0xff; - b[pos++] = (cdpos >> 8) & 0xff; - b[pos++] = cdpos & 0xff; - cdpos -= track_address; - b[pos++] = (cdpos >> 24) & 0xff; - b[pos++] = (cdpos >> 16) & 0xff; - b[pos++] = (cdpos >> 8) & 0xff; - b[pos++] = cdpos & 0xff; - } - - if (cdrom_ioctl[id].cd_state == CD_PLAYING) return 0x11; - return 0x12; - } - - b[pos++]=sub.CurrentPosition.Control; - b[pos++]=sub.CurrentPosition.TrackNumber; - b[pos++]=sub.CurrentPosition.IndexNumber; - - cdrom_ioctl_log("cdpos = %i, track_address = %i\n", MSFtoLBA(sub.CurrentPosition.AbsoluteAddress[1], sub.CurrentPosition.AbsoluteAddress[2], sub.CurrentPosition.AbsoluteAddress[3]), MSFtoLBA(sub.CurrentPosition.TrackRelativeAddress[1], sub.CurrentPosition.TrackRelativeAddress[2], sub.CurrentPosition.TrackRelativeAddress[3])); - - if (msf) - { - int c; - for (c = 0; c < 4; c++) - { - b[pos++] = sub.CurrentPosition.AbsoluteAddress[c]; - } - for (c = 0; c < 4; c++) - { - b[pos++] = sub.CurrentPosition.TrackRelativeAddress[c]; - } - } - else - { - uint32_t temp = MSFtoLBA(sub.CurrentPosition.AbsoluteAddress[1], sub.CurrentPosition.AbsoluteAddress[2], sub.CurrentPosition.AbsoluteAddress[3]); - b[pos++] = temp >> 24; - b[pos++] = temp >> 16; - b[pos++] = temp >> 8; - b[pos++] = temp; - temp = MSFtoLBA(sub.CurrentPosition.TrackRelativeAddress[1], sub.CurrentPosition.TrackRelativeAddress[2], sub.CurrentPosition.TrackRelativeAddress[3]); - b[pos++] = temp >> 24; - b[pos++] = temp >> 16; - b[pos++] = temp >> 8; - b[pos++] = temp; - } - - return 0x13; -} - -static void ioctl_eject(uint8_t id) -{ - unsigned long size; - if (!cdrom_drives[id].host_drive) - { - return; - } - cdrom_ioctl[id].cd_state = CD_STOPPED; - ioctl_open(id, 0); - DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_STORAGE_EJECT_MEDIA,NULL,0,NULL,0,&size,NULL); - ioctl_close(id); -} - -static void ioctl_load(uint8_t id) -{ - unsigned long size; - if (!cdrom_drives[id].host_drive) - { - return; - } - cdrom_ioctl[id].cd_state = CD_STOPPED; - ioctl_open(id, 0); - DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_STORAGE_LOAD_MEDIA,NULL,0,NULL,0,&size,NULL); - ioctl_close(id); - cdrom_ioctl[id].cdrom_capacity = ioctl_get_last_block(id, 0, 0, 4096, 0); -} - -static int is_track_audio(uint8_t id, uint32_t pos) -{ - int c; - int control = 0; - - uint32_t track_address = 0; - - if (!cdrom_ioctl[id].tocvalid) - { - return 0; - } - - for (c = 0; c <= cdrom_ioctl_windows[id].toc.LastTrack; c++) - { - track_address = MSFtoLBA(cdrom_ioctl_windows[id].toc.TrackData[c].Address[1],cdrom_ioctl_windows[id].toc.TrackData[c].Address[2],cdrom_ioctl_windows[id].toc.TrackData[c].Address[3]); - - if (track_address <= pos) - { - control = cdrom_ioctl_windows[id].toc.TrackData[c].Control; - } - } - - if ((control & 0xd) <= 1) - { - return 1; - } - else - { - return 0; - } -} - -static int ioctl_is_track_audio(uint8_t id, uint32_t pos, int ismsf) -{ - int m = 0, s = 0, f = 0; - - if (ismsf) - { - m = (pos >> 16) & 0xff; - s = (pos >> 8) & 0xff; - f = pos & 0xff; - pos = MSFtoLBA(m, s, f); - } - else - { - pos += 150; - } - return is_track_audio(id, pos); -} - -/* 00, 08, 10, 18, 20, 28, 30, 38 */ -int flags_to_size[5][32] = { { 0, 0, 2352, 2352, 2352, 2352, 2352, 2352, /* 00-38 (CD-DA) */ - 2352, 2352, 2352, 2352, 2352, 2352, 2352, 2352, /* 40-78 */ - 2352, 2352, 2352, 2352, 2352, 2352, 2352, 2352, /* 80-B8 */ - 2352, 2352, 2352, 2352, 2352, 2352, 2352, 2352 }, /* C0-F8 */ - { 0, 0, 2048, 2336, 4, -296, 2052, 2344, /* 00-38 (Mode 1) */ - 8, -296, 2048, 2048, 12, -296, 2052, 2052, /* 40-78 */ - -296, -296, -296, -296, 16, -296, 2064, 2344, /* 80-B8 */ - -296, -296, 2048, 2048, 24, -296, 2064, 2352 }, /* C0-F8 */ - { 0, 0, 2336, 2336, 4, -296, 2340, 2340, /* 00-38 (Mode 2 non-XA) */ - 8, -296, 2336, 2336, 12, -296, 2340, 2340, /* 40-78 */ - -296, -296, -296, -296, 16, -296, 2352, 2340, /* 80-B8 */ - -296, -296, 2336, 2336, 24, -296, 2352, 2352 }, /* C0-F8 */ - { 0, 0, 2048, 2336, 4, -296, -296, -296, /* 00-38 (Mode 2 Form 1) */ - 8, -296, 2056, 2344, 12, -296, 2060, 2340, /* 40-78 */ - -296, -296, -296, -296, 16, -296, -296, -296, /* 80-B8 */ - -296, -296, -296, -296, 24, -296, 2072, 2352 }, /* C0-F8 */ - { 0, 0, 2328, 2328, 4, -296, -296, -296, /* 00-38 (Mode 2 Form 2) */ - 8, -296, 2336, 2336, 12, -296, 2340, 2340, /* 40-78 */ - -296, -296, -296, -296, 16, -296, -296, -296, /* 80-B8 */ - -296, -296, -296, -296, 24, -296, 2352, 2352 } /* C0-F8 */ - }; - -static int ioctl_get_sector_data_type(uint8_t id, uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3, int ismsf); - -static void cdrom_illegal_mode(uint8_t id) -{ - cdrom_sense_key = SENSE_ILLEGAL_REQUEST; - cdrom_asc = ASC_ILLEGAL_MODE_FOR_THIS_TRACK; - cdrom_ascq = 0; -} - -struct sptd_with_sense -{ - SCSI_PASS_THROUGH s; - ULONG Filler; - UCHAR sense[32]; - UCHAR data[65536]; -} sptd; - -static int ioctl_get_block_length(uint8_t id, const UCHAR *cdb, int number_of_blocks, int no_length_check) -{ - int sector_type = 0; - int temp_len = 0; - - if (no_length_check) - { - switch (cdb[0]) - { - case 0x25: - /* READ CAPACITY */ - return 8; - case 0x42: /* READ SUBCHANNEL */ - case 0x43: /* READ TOC */ - case 0x51: /* READ DISC INFORMATION */ - case 0x52: /* READ TRACK INFORMATION */ - case 0x5A: /* MODE SENSE (10) */ - return ((uint16_t) cdb[8]) + (((uint16_t) cdb[7]) << 8); - default: - return 65534; - } - } - - switch (cdb[0]) - { - case 0x25: - /* READ CAPACITY */ - return 8; - case 0x42: /* READ SUBCHANNEL */ - case 0x43: /* READ TOC */ - case 0x51: /* READ DISC INFORMATION */ - case 0x52: /* READ TRACK INFORMATION */ - case 0x5A: /* MODE SENSE (10) */ - return ((uint16_t) cdb[8]) + (((uint16_t) cdb[7]) << 8); - case 0x08: - case 0x28: - case 0xa8: - /* READ (6), READ (10), READ (12) */ - return 2048 * number_of_blocks; - break; - case 0xb9: - sector_type = (cdb[1] >> 2) & 7; - if (sector_type == 0) - { - sector_type = ioctl_get_sector_data_type(id, 0, cdb[3], cdb[4], cdb[5], 1); - if (sector_type == 0) - { - cdrom_illegal_mode(id); - return -1; - } - } - goto common_handler; - case 0xbe: - /* READ CD MSF, READ CD */ - sector_type = (cdb[1] >> 2) & 7; - if (sector_type == 0) - { - sector_type = ioctl_get_sector_data_type(id, cdb[2], cdb[3], cdb[4], cdb[5], 0); - if (sector_type == 0) - { - cdrom_illegal_mode(id); - return -1; - } - } -common_handler: - temp_len = flags_to_size[sector_type - 1][cdb[9] >> 3]; - if ((cdb[9] & 6) == 2) - { - temp_len += 294; - } - else if ((cdb[9] & 6) == 4) - { - temp_len += 296; - } - if ((cdb[10] & 7) == 1) - { - temp_len += 96; - } - else if ((cdb[10] & 7) == 2) - { - temp_len += 16; - } - else if ((cdb[10] & 7) == 4) - { - temp_len += 96; - } - if (temp_len <= 0) - { - cdrom_illegal_mode(id); - return -1; - } - return temp_len * cdrom[id].requested_blocks; - break; - default: - /* Other commands */ - return 65534; - break; - } - -} - -static int SCSICommand(uint8_t id, const UCHAR *cdb, UCHAR *buf, uint32_t *len, int no_length_check) -{ - DWORD ioctl_bytes; - int ioctl_rv = 0; - - SCSISense.SenseKey = 0; - SCSISense.Asc = 0; - SCSISense.Ascq = 0; - - *len = 0; - memset(&sptd, 0, sizeof(sptd)); - sptd.s.Length = sizeof(SCSI_PASS_THROUGH); - sptd.s.CdbLength = 12; - sptd.s.DataIn = SCSI_IOCTL_DATA_IN; - sptd.s.TimeOutValue = 80 * 60; - sptd.s.DataTransferLength = ioctl_get_block_length(id, cdb, cdrom_ioctl[id].actual_requested_blocks, no_length_check); - sptd.s.SenseInfoOffset = (uintptr_t)&sptd.sense - (uintptr_t)&sptd; - sptd.s.SenseInfoLength = 32; - sptd.s.DataBufferOffset = (uintptr_t)&sptd.data - (uintptr_t)&sptd; - - memcpy(sptd.s.Cdb, cdb, 12); - ioctl_rv = DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_SCSI_PASS_THROUGH, &sptd, sizeof(sptd), &sptd, sizeof(sptd), &ioctl_bytes, NULL); - - if (sptd.s.SenseInfoLength) - { - cdrom_sense_key = sptd.sense[2]; - cdrom_asc = sptd.sense[12]; - cdrom_ascq = sptd.sense[13]; - } - - cdrom_ioctl_log("Transferred length: %i (command: %02X)\n", sptd.s.DataTransferLength, cdb[0]); - cdrom_ioctl_log("Sense length: %i (%02X %02X %02X %02X %02X)\n", sptd.s.SenseInfoLength, sptd.sense[0], sptd.sense[1], sptd.sense[2], sptd.sense[12], sptd.sense[13]); - cdrom_ioctl_log("IOCTL bytes: %i; SCSI status: %i, status: %i, LastError: %08X\n", ioctl_bytes, sptd.s.ScsiStatus, ioctl_rv, GetLastError()); - cdrom_ioctl_log("DATA: %02X %02X %02X %02X %02X %02X\n", sptd.data[0], sptd.data[1], sptd.data[2], sptd.data[3], sptd.data[4], sptd.data[5]); - cdrom_ioctl_log(" %02X %02X %02X %02X %02X %02X\n", sptd.data[6], sptd.data[7], sptd.data[8], sptd.data[9], sptd.data[10], sptd.data[11]); - cdrom_ioctl_log(" %02X %02X %02X %02X %02X %02X\n", sptd.data[12], sptd.data[13], sptd.data[14], sptd.data[15], sptd.data[16], sptd.data[17]); - cdrom_ioctl_log("SENSE: %02X %02X %02X %02X %02X %02X\n", sptd.sense[0], sptd.sense[1], sptd.sense[2], sptd.sense[3], sptd.sense[4], sptd.sense[5]); - cdrom_ioctl_log(" %02X %02X %02X %02X %02X %02X\n", sptd.sense[6], sptd.sense[7], sptd.sense[8], sptd.sense[9], sptd.sense[10], sptd.sense[11]); - cdrom_ioctl_log(" %02X %02X %02X %02X %02X %02X\n", sptd.sense[12], sptd.sense[13], sptd.sense[14], sptd.sense[15], sptd.sense[16], sptd.sense[17]); - *len = sptd.s.DataTransferLength; - if (sptd.s.DataTransferLength != 0) - { - memcpy(buf, sptd.data, sptd.s.DataTransferLength); - } - - return ioctl_rv; -} - -static void ioctl_read_capacity(uint8_t id, uint8_t *b) -{ - uint32_t len = 0; - - const UCHAR cdb[] = { 0x25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - UCHAR buf[16]; - - if (!cdrom_ioctl[id].capacity_read) - { - ioctl_open(id, 0); - - SCSICommand(id, cdb, buf, &len, 1); - - memcpy(cdrom_ioctl[id].rcbuf, buf, len); - cdrom_ioctl[id].capacity_read = 1; - } - else - { - memcpy(b, cdrom_ioctl[id].rcbuf, 16); - } - - ioctl_close(id); -} - -static int ioctl_media_type_id(uint8_t id) -{ - uint8_t old_sense[3] = { 0, 0, 0 }; - - UCHAR msbuf[28]; - uint32_t len = 0; - int sense = 0; - - const UCHAR cdb[] = { 0x5A, 0x00, 0x2A, 0, 0, 0, 0, 0, 28, 0, 0, 0 }; - - old_sense[0] = cdrom_sense_key; - old_sense[1] = cdrom_asc; - old_sense[2] = cdrom_asc; - - ioctl_open(id, 0); - - SCSICommand(id, cdb, msbuf, &len, 1); - - ioctl_close(id); - - sense = cdrom_sense_key; - cdrom_sense_key = old_sense[0]; - cdrom_asc = old_sense[1]; - cdrom_asc = old_sense[2]; - - if (sense == 0) - { - return msbuf[2]; - } - else - { - return 3; - } -} - -static uint32_t msf_to_lba32(int lba) -{ - int m = (lba >> 16) & 0xff; - int s = (lba >> 8) & 0xff; - int f = lba & 0xff; - return (m * 60 * 75) + (s * 75) + f; -} - -static int ioctl_get_type(uint8_t id, UCHAR *cdb, UCHAR *buf) -{ - int i = 0; - int ioctl_rv = 0; - - uint32_t len = 0; - - for (i = 2; i <= 5; i++) - { - cdb[1] = i << 2; - ioctl_rv = SCSICommand(id, cdb, buf, &len, 1); /* Bypass length check so we don't risk calling this again and getting stuck in an endless up. */ - if (ioctl_rv) - { - return i; - } - } - return 0; -} - -static int ioctl_sector_data_type(uint8_t id, int sector, int ismsf) -{ - int ioctl_rv = 0; - UCHAR cdb_lba[] = { 0xBE, 0, 0, 0, 0, 0, 0, 0, 1, 0x10, 0, 0 }; - UCHAR cdb_msf[] = { 0xB9, 0, 0, 0, 0, 0, 0, 0, 0, 0x10, 0, 0 }; - UCHAR buf[2352]; - - cdb_lba[2] = (sector >> 24); - cdb_lba[3] = ((sector >> 16) & 0xff); - cdb_lba[4] = ((sector >> 8) & 0xff); - cdb_lba[5] = (sector & 0xff); - - cdb_msf[3] = cdb_msf[6] = ((sector >> 16) & 0xff); - cdb_msf[4] = cdb_msf[7] = ((sector >> 8) & 0xff); - cdb_msf[5] = cdb_msf[8] = (sector & 0xff); - - ioctl_open(id, 0); - - if (ioctl_is_track_audio(id, sector, ismsf)) - { - return 1; - } - - if (ismsf) - { - ioctl_rv = ioctl_get_type(id, cdb_msf, buf); - } - else - { - ioctl_rv = ioctl_get_type(id, cdb_lba, buf); - } - - if (ioctl_rv) - { - ioctl_close(id); - return ioctl_rv; - } - - if (ismsf) - { - sector = msf_to_lba32(sector); - if (sector < 150) - { - ioctl_close(id); - return 0; - } - sector -= 150; - ioctl_rv = ioctl_get_type(id, (UCHAR *) cdb_lba, buf); - } - - ioctl_close(id); - return ioctl_rv; -} - -static int ioctl_get_sector_data_type(uint8_t id, uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3, int ismsf) -{ - int sector = b3; - sector |= ((uint32_t) b2) << 8; - sector |= ((uint32_t) b1) << 16; - sector |= ((uint32_t) b0) << 24; - return ioctl_sector_data_type(id, sector, ismsf); -} - -static void ioctl_validate_toc(uint8_t id) -{ - unsigned long size; - if (!cdrom_drives[id].host_drive) - { - return; - } - cdrom_ioctl[id].cd_state = CD_STOPPED; - ioctl_open(id, 0); - cdrom_ioctl_log("Validating TOC...\n"); - DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_CDROM_READ_TOC, NULL,0,&cdrom_ioctl_windows[id].toc,sizeof(cdrom_ioctl_windows[id].toc),&size,NULL); - ioctl_close(id); - cdrom_ioctl[id].tocvalid=1; -} - -UCHAR buf[262144]; - -static int ioctl_pass_through(uint8_t id, uint8_t *in_cdb, uint8_t *b, uint32_t *len) -{ - const UCHAR cdb[12]; - - int ret = 0; - - int block_length = 0; - - int temp_block_length = 0; - int temp_pos = 0; - - int blocks_at_once = 0; - int buffer_pos = 0; - - int transferred_blocks = 0; - - uint32_t temp_len = 0; - int chunk = 0; - - if (in_cdb[0] == 0x43) - { - /* This is a read TOC, so we have to validate the TOC to make the rest of the emulator happy. */ - ioctl_validate_toc(id); - } - - ioctl_open(id, 0); - - memcpy((void *) cdb, in_cdb, 12); - - temp_block_length = ioctl_get_block_length(id, cdb, cdrom[id].requested_blocks, 0); - *len = 0; - if (temp_block_length != -1) - { - if (temp_block_length > 65534) - { - block_length = temp_block_length / cdrom[id].requested_blocks; - blocks_at_once = 32768 / block_length; - cdrom_ioctl_log("CD-ROM %i: ioctl_pass_through(): Expected transfer length %i is bigger than 65534, splitting the transfer into chunks of %i blocks...\n", id, temp_block_length, blocks_at_once); - - buffer_pos = 0; - temp_pos = cdrom[id].sector_pos; - transferred_blocks = 0; - temp_len = 0; - -split_block_read_iterate: - chunk = (cdrom[id].requested_blocks - transferred_blocks); - if (chunk < blocks_at_once) - { - cdrom_ioctl_log("CD-ROM %i: ioctl_pass_through(): The remaining chunk (%i blocks) is less than a complete split block\n", id, chunk); - cdrom_ioctl[id].actual_requested_blocks = chunk; - } - else - { - cdrom_ioctl_log("CD-ROM %i: ioctl_pass_through(): The remaining chunk (%i blocks) is more or equal than a complete split block\n", id, chunk); - cdrom_ioctl[id].actual_requested_blocks = blocks_at_once; - } - cdrom_ioctl_log("CD-ROM %i: ioctl_pass_through(): Transferring %i blocks...\n", id, cdrom_ioctl[id].actual_requested_blocks); - cdrom_update_cdb((uint8_t *) cdb, temp_pos, cdrom_ioctl[id].actual_requested_blocks); - ret = SCSICommand(id, cdb, buf + buffer_pos, &temp_len, 0); - *len += temp_len; - transferred_blocks += cdrom_ioctl[id].actual_requested_blocks; - if (ret && (transferred_blocks < cdrom[id].requested_blocks)) - { - /* Return value was successful and there are still more blocks left to transfer. */ - temp_pos += cdrom_ioctl[id].actual_requested_blocks; - buffer_pos += (cdrom_ioctl[id].actual_requested_blocks * block_length); - goto split_block_read_iterate; - } - cdrom_ioctl_log("CD-ROM %i: ioctl_pass_through(): Split transfer done\n", id); - } - else - { - cdrom_ioctl_log("CD-ROM %i: ioctl_pass_through(): Expected transfer length %i is smaller than 65534, transferring all at once...\n", id, temp_block_length); - cdrom_ioctl[id].actual_requested_blocks = cdrom[id].requested_blocks; - ret = SCSICommand(id, cdb, buf, len, 0); - cdrom_ioctl_log("CD-ROM %i: ioctl_pass_through(): Single transfer done\n", id); - } - memcpy(b, buf, *len); - } - else - { - cdrom_ioctl_log("CD-ROM %i: ioctl_pass_through(): Expected transfer length %i is -1, this indicates an illegal mode\n", id, temp_block_length); - } - - cdrom_ioctl_log("IOCTL DATA: %02X %02X %02X %02X %02X %02X %02X %02X\n", b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]); - - ioctl_close(id); - - cdrom_ioctl_log("IOCTL Returned value: %i\n", ret); - - return ret; -} - -static uint32_t ioctl_size(uint8_t id) -{ - uint8_t capacity_buffer[8]; - uint32_t capacity = 0; - ioctl_read_capacity(id, capacity_buffer); - capacity = ((uint32_t) capacity_buffer[0]) << 24; - capacity |= ((uint32_t) capacity_buffer[1]) << 16; - capacity |= ((uint32_t) capacity_buffer[2]) << 8; - capacity |= (uint32_t) capacity_buffer[3]; - return capacity + 1; -} - -static int ioctl_status(uint8_t id) -{ - if (!(ioctl_ready(id)) && (cdrom_drives[id].host_drive <= 0)) - { - return CD_STATUS_EMPTY; - } - - switch(cdrom_ioctl[id].cd_state) - { - case CD_PLAYING: - return CD_STATUS_PLAYING; - case CD_PAUSED: - return CD_STATUS_PAUSED; - case CD_STOPPED: - return CD_STATUS_STOPPED; - default: - return CD_STATUS_EMPTY; - } -} - -void ioctl_reset(uint8_t id) -{ - CDROM_TOC ltoc; - unsigned long size; - - if (!cdrom_drives[id].host_drive) - { - cdrom_ioctl[id].tocvalid = 0; - return; - } - - ioctl_open(id, 0); - DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, <oc, sizeof(ltoc), &size, NULL); - ioctl_close(id); - - cdrom_ioctl_windows[id].toc = ltoc; - cdrom_ioctl[id].tocvalid = 1; -} - -int ioctl_open(uint8_t id, char d) -{ - if (!cdrom_ioctl[id].ioctl_inited) - { - sprintf(cdrom_ioctl[id].ioctl_path,"\\\\.\\%c:",d); - cdrom_ioctl[id].tocvalid=0; - } - cdrom_ioctl_windows[id].hIOCTL = CreateFile(cdrom_ioctl[id].ioctl_path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); - cdrom_drives[id].handler = &ioctl_cdrom; - if (!cdrom_ioctl[id].ioctl_inited) - { - cdrom_ioctl[id].ioctl_inited=1; - cdrom_ioctl[id].capacity_read=0; /* With this two lines, we read the READ CAPACITY command output from the host drive into our cache buffer. */ - ioctl_read_capacity(id, NULL); - CloseHandle(cdrom_ioctl_windows[id].hIOCTL); - cdrom_ioctl_windows[id].hIOCTL = NULL; - update_status_bar_icon_state(0x10 | id, 0); - } - return 0; -} - -void ioctl_close(uint8_t id) -{ - if (cdrom_ioctl_windows[id].hIOCTL) - { - CloseHandle(cdrom_ioctl_windows[id].hIOCTL); - cdrom_ioctl_windows[id].hIOCTL = NULL; - } -} - -static void ioctl_exit(uint8_t id) -{ - ioctl_stop(id); - cdrom_ioctl[id].ioctl_inited=0; - cdrom_ioctl[id].tocvalid=0; -} - -static CDROM ioctl_cdrom= -{ - ioctl_ready, - ioctl_medium_changed, - ioctl_media_type_id, - ioctl_audio_callback, - ioctl_audio_stop, - NULL, - NULL, - NULL, - ioctl_getcurrentsubchannel, - ioctl_pass_through, - NULL, - ioctl_playaudio, - ioctl_load, - ioctl_eject, - ioctl_pause, - ioctl_resume, - ioctl_size, - ioctl_status, - ioctl_is_track_audio, - ioctl_stop, - ioctl_exit -}; diff --git a/src/cdrom-ioctl.h b/src/cdrom-ioctl.h deleted file mode 100644 index e39f12ddf..000000000 --- a/src/cdrom-ioctl.h +++ /dev/null @@ -1,17 +0,0 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ -#ifndef CDROM_IOCTL_H -#define CDROM_IOCTL_H - -/* this header file lists the functions provided by - various platform specific cdrom-ioctl files */ - -extern uint32_t cdrom_capacity; - -extern int ioctl_open(uint8_t id, char d); -extern void ioctl_reset(uint8_t id); - -extern void ioctl_close(uint8_t id); - -#endif /* ! CDROM_IOCTL_H */ diff --git a/src/cdrom-null.c b/src/cdrom-null.c deleted file mode 100644 index f7d117077..000000000 --- a/src/cdrom-null.c +++ /dev/null @@ -1,130 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -#include "ibm.h" -#include "cdrom.h" -#include "cdrom-ioctl.h" - -static CDROM null_cdrom; - -static int null_ready(uint8_t id) -{ - return 0; -} - -/* Always return 0, the contents of a null CD-ROM drive never change. */ -static int null_medium_changed(uint8_t id) -{ - return 0; -} - -static uint8_t null_getcurrentsubchannel(uint8_t id, uint8_t *b, int msf) -{ - return 0x13; -} - -static void null_eject(uint8_t id) -{ -} - -static void null_load(uint8_t id) -{ -} - -static int null_readsector_raw(uint8_t id, uint8_t *buffer, int sector, int ismsf, int cdrom_sector_type, int cdrom_sector_flags, int *len) -{ - *len = 0; - return 0; -} - -static int null_readtoc(uint8_t id, unsigned char *b, unsigned char starttrack, int msf, int maxlen, int single) -{ - return 0; -} - -static int null_readtoc_session(uint8_t id, unsigned char *b, int msf, int maxlen) -{ - return 0; -} - -static int null_readtoc_raw(uint8_t id, unsigned char *b, int msf, int maxlen) -{ - return 0; -} - -static uint32_t null_size(uint8_t id) -{ - return 0; -} - -static int null_status(uint8_t id) -{ - return CD_STATUS_EMPTY; -} - -void cdrom_null_reset(uint8_t id) -{ -} - -void cdrom_set_null_handler(uint8_t id); - -int cdrom_null_open(uint8_t id, char d) -{ - cdrom_set_null_handler(id); - return 0; -} - -void null_close(uint8_t id) -{ -} - -static void null_exit(uint8_t id) -{ -} - -static int null_is_track_audio(uint8_t id, uint32_t pos, int ismsf) -{ - return 0; -} - -static int null_pass_through(uint8_t id, uint8_t *in_cdb, uint8_t *b, uint32_t *len) -{ - return 0; -} - -static int null_media_type_id(uint8_t id) -{ - return 0x70; -} - -void cdrom_set_null_handler(uint8_t id) -{ - cdrom_drives[id].handler = &null_cdrom; - cdrom_drives[id].host_drive = 0; - update_status_bar_icon_state(0x10 | id, 1); -} - -static CDROM null_cdrom = -{ - null_ready, - null_medium_changed, - null_media_type_id, - NULL, - NULL, - null_readtoc, - null_readtoc_session, - null_readtoc_raw, - null_getcurrentsubchannel, - null_pass_through, - null_readsector_raw, - NULL, - null_load, - null_eject, - NULL, - NULL, - null_size, - null_status, - null_is_track_audio, - NULL, - null_exit -}; diff --git a/src/cdrom-null.h b/src/cdrom-null.h deleted file mode 100644 index 7217760ca..000000000 --- a/src/cdrom-null.h +++ /dev/null @@ -1,14 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -#ifndef CDROM_NULL_H -#define CDROM_NULL_H - -/* this header file lists the functions provided by - various platform specific cdrom-ioctl files */ - -int cdrom_null_open(uint8_t id, char d); -void cdrom_null_reset(uint8_t id); -void null_close(uint8_t id); - -#endif /* ! CDROM_NULL_H */ diff --git a/src/config.c b/src/config.c index 8796c7061..a24772e19 100644 --- a/src/config.c +++ b/src/config.c @@ -23,9 +23,9 @@ #include "mouse.h" #include "network.h" #include "nvr.h" -#include "plat-joystick.h" -#include "plat-midi.h" #include "scsi.h" +#include "plat_joystick.h" +#include "plat_midi.h" #include "sound/snd_dbopl.h" #include "sound/snd_opl.h" #include "sound/sound.h" @@ -37,7 +37,7 @@ #include #undef BITMAP #include "win.h" -#include "win-language.h" +#include "win_language.h" #endif @@ -82,6 +82,7 @@ typedef struct entry_t (new)->next = NULL; \ } + void config_dump(void) { section_t *current_section; @@ -109,7 +110,8 @@ void config_dump(void) } } -void config_free(void) + +static void config_free(void) { section_t *current_section; current_section = (section_t *)config_head.next; @@ -134,6 +136,7 @@ void config_free(void) } } + static wchar_t cfgbuffer[1024]; static char sname[256]; static char ename[256]; @@ -231,13 +234,13 @@ void config_load(wchar_t *fn) } - void config_new(void) { FILE *f = _wfopen(config_file, L"wt, ccs=UNICODE"); fclose(f); } + static section_t *find_section(char *name) { section_t *current_section; @@ -257,6 +260,7 @@ static section_t *find_section(char *name) return NULL; } + static entry_t *find_entry(section_t *section, char *name) { entry_t *current_entry; @@ -273,6 +277,7 @@ static entry_t *find_entry(section_t *section, char *name) return NULL; } + static section_t *create_section(char *name) { section_t *new_section = malloc(sizeof(section_t)); @@ -284,6 +289,7 @@ static section_t *create_section(char *name) return new_section; } + static entry_t *create_entry(section_t *section, char *name) { entry_t *new_entry = malloc(sizeof(entry_t)); @@ -293,7 +299,8 @@ static entry_t *create_entry(section_t *section, char *name) return new_entry; } - + + int config_get_int(char *head, char *name, int def) { section_t *section; @@ -315,6 +322,7 @@ int config_get_int(char *head, char *name, int def) return value; } + int config_get_hex16(char *head, char *name, int def) { section_t *section; @@ -336,6 +344,7 @@ int config_get_hex16(char *head, char *name, int def) return value; } + char *config_get_string(char *head, char *name, char *def) { section_t *section; @@ -354,6 +363,7 @@ char *config_get_string(char *head, char *name, char *def) return entry->data; } + wchar_t *config_get_wstring(char *head, char *name, wchar_t *def) { section_t *section; @@ -372,6 +382,7 @@ wchar_t *config_get_wstring(char *head, char *name, wchar_t *def) return entry->wdata; } + void config_set_int(char *head, char *name, int val) { section_t *section; @@ -391,6 +402,7 @@ void config_set_int(char *head, char *name, int val) mbstowcs(entry->wdata, entry->data, 512); } + void config_set_hex16(char *head, char *name, int val) { section_t *section; @@ -410,6 +422,7 @@ void config_set_hex16(char *head, char *name, int val) mbstowcs(entry->wdata, entry->data, 512); } + void config_set_string(char *head, char *name, char *val) { section_t *section; @@ -429,6 +442,7 @@ void config_set_string(char *head, char *name, char *val) mbstowcs(entry->wdata, entry->data, 256); } + void config_set_wstring(char *head, char *name, wchar_t *val) { section_t *section; @@ -460,6 +474,7 @@ char *get_filename(char *s) return s; } + wchar_t *get_filename_w(wchar_t *s) { int c = wcslen(s) - 1; @@ -472,16 +487,19 @@ wchar_t *get_filename_w(wchar_t *s) return s; } + void append_filename(char *dest, char *s1, char *s2, int size) { sprintf(dest, "%s%s", s1, s2); } + void append_filename_w(wchar_t *dest, wchar_t *s1, wchar_t *s2, int size) { _swprintf(dest, L"%s%s", s1, s2); } + void put_backslash(char *s) { int c = strlen(s) - 1; @@ -489,6 +507,7 @@ void put_backslash(char *s) s[c] = '/'; } + void put_backslash_w(wchar_t *s) { int c = wcslen(s) - 1; @@ -496,6 +515,7 @@ void put_backslash_w(wchar_t *s) s[c] = L'/'; } + char *get_extension(char *s) { int c = strlen(s) - 1; @@ -512,6 +532,7 @@ char *get_extension(char *s) return &s[c+1]; } + wchar_t *get_extension_w(wchar_t *s) { int c = wcslen(s) - 1; @@ -528,8 +549,10 @@ wchar_t *get_extension_w(wchar_t *s) return &s[c+1]; } + static wchar_t wname[512]; + void config_save(wchar_t *fn) { FILE *f = _wfopen(fn, L"wt, ccs=UNICODE"); @@ -581,19 +604,21 @@ void config_save(wchar_t *fn) fclose(f); } -static char temps[512]; -void loadconfig_general(void) + +/* General */ +static void loadconfig_general(void) { + char *cat = "General"; + char temps[512]; wchar_t *wp; char *p; - /* General */ - vid_resize = !!config_get_int("General", "vid_resize", 0); + vid_resize = !!config_get_int(cat, "vid_resize", 0); - p = (char *)config_get_string("General", "vid_renderer", "d3d9"); - memset(temps, 0, 512); - if (p) + memset(temps, '\0', sizeof(temps)); + p = config_get_string(cat, "vid_renderer", "d3d9"); + if (p != NULL) { strcpy(temps, p); } @@ -606,27 +631,22 @@ void loadconfig_general(void) vid_api = 1; } - video_fullscreen_scale = config_get_int("General", "video_fullscreen_scale", 0); - video_fullscreen_first = config_get_int("General", "video_fullscreen_first", 1); + video_fullscreen_scale = config_get_int(cat, "video_fullscreen_scale", 0); + video_fullscreen_first = config_get_int(cat, "video_fullscreen_first", 1); - force_43 = !!config_get_int("General", "force_43", 0); - scale = !!config_get_int("General", "scale", 1); - enable_overscan = !!config_get_int("General", "enable_overscan", 0); + force_43 = !!config_get_int(cat, "force_43", 0); + scale = !!config_get_int(cat, "scale", 1); + enable_overscan = !!config_get_int(cat, "enable_overscan", 0); - p = config_get_string("General", "window_coordinates", "0, 0, 0, 0"); - if (p) - { - sscanf(p, "%i, %i, %i, %i", &window_w, &window_h, &window_x, &window_y); - } - else - { - sscanf("0, 0, 0, 0", "%i, %i, %i, %i", &window_w, &window_h, &window_x, &window_y); - } - window_remember = config_get_int("General", "window_remember", 0); + p = config_get_string(cat, "window_coordinates", NULL); + if (p == NULL) + p = "0, 0, 0, 0"; + sscanf(p, "%i, %i, %i, %i", &window_w, &window_h, &window_x, &window_y); + window_remember = config_get_int(cat, "window_remember", 0); - memset(nvr_path, 0, 2048); - wp = (wchar_t *)config_get_wstring("General", "nvr_path", L""); - if (wp) { + memset(nvr_path, 0x00, sizeof(nvr_path)); + wp = config_get_wstring(cat, "nvr_path", L""); + if (wp != NULL) { if (wcslen(wp) && (wcslen(wp) <= 992)) wcscpy(nvr_path, wp); else { @@ -649,31 +669,31 @@ void loadconfig_general(void) #ifndef __unix /* Currently, 86Box is English (US) only, but in the future (version 1.30 at the earliest) other languages will be added, therefore it is better to future-proof the code. */ - dwLanguage = config_get_hex16("General", "language", 0x0409); + dwLanguage = config_get_hex16(cat, "language", 0x0409); #endif } + +/* Machine */ static void loadconfig_machine(void) { + char *cat = "Machine"; char *p; - /* Machine */ - p = (char *)config_get_string("Machine", "model", ""); - if (p) + p = config_get_string(cat, "model", NULL); + if (p != NULL) model = model_get_model_from_internal_name(p); else model = 0; - if (model >= model_count()) model = model_count() - 1; romset = model_getromset(); - cpu_manufacturer = config_get_int("Machine", "cpu_manufacturer", 0); - cpu = config_get_int("Machine", "cpu", 0); + cpu_manufacturer = config_get_int(cat, "cpu_manufacturer", 0); + cpu = config_get_int(cat, "cpu", 0); + cpu_waitstates = config_get_int(cat, "cpu_waitstates", 0); - cpu_waitstates = config_get_int("Machine", "cpu_waitstates", 0); - - mem_size = config_get_int("Machine", "mem_size", 4096); + mem_size = config_get_int(cat, "mem_size", 4096); if (mem_size < ((models[model].flags & MODEL_AT) ? models[model].min_ram*1024 : models[model].min_ram)) mem_size = ((models[model].flags & MODEL_AT) ? models[model].min_ram*1024 : models[model].min_ram); if (mem_size > 1048576) @@ -681,66 +701,69 @@ static void loadconfig_machine(void) mem_size = 1048576; } - cpu_use_dynarec = !!config_get_int("Machine", "cpu_use_dynarec", 0); + cpu_use_dynarec = !!config_get_int(cat, "cpu_use_dynarec", 0); - enable_external_fpu = !!config_get_int("Machine", "cpu_enable_fpu", 0); + enable_external_fpu = !!config_get_int(cat, "cpu_enable_fpu", 0); - enable_sync = !!config_get_int("Machine", "enable_sync", 1); + enable_sync = !!config_get_int(cat, "enable_sync", 1); } + +/* Video */ static void loadconfig_video(void) { + char *cat = "Video"; char *p; - /* Video */ - p = (char *)config_get_string("Video", "gfxcard", ""); - if (p) + p = config_get_string(cat, "gfxcard", NULL); + if (p != NULL) gfxcard = video_get_video_from_internal_name(p); else gfxcard = 0; - video_speed = config_get_int("Video", "video_speed", 3); + video_speed = config_get_int(cat, "video_speed", 3); - voodoo_enabled = !!config_get_int("Video", "voodoo", 0); + voodoo_enabled = !!config_get_int(cat, "voodoo", 0); } -static char s[512]; +/* Input devices */ static void loadconfig_input_devices(void) { + char *cat = "Input devices"; + char temps[512]; int c, d; char *p; - /* Input devices */ - p = (char *)config_get_string("Input devices", "mouse_type", ""); - if (p) + p = config_get_string(cat, "mouse_type", NULL); + if (p != NULL) mouse_type = mouse_get_from_internal_name(p); else mouse_type = 0; - joystick_type = config_get_int("Input devices", "joystick_type", 0); + joystick_type = config_get_int(cat, "joystick_type", 0); for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) { - sprintf(s, "joystick_%i_nr", c); - joystick_state[c].plat_joystick_nr = config_get_int("Input devices", s, 0); + sprintf(temps, "joystick_%i_nr", c); + joystick_state[c].plat_joystick_nr = config_get_int(cat, temps, 0); if (joystick_state[c].plat_joystick_nr) { for (d = 0; d < joystick_get_axis_count(joystick_type); d++) { - sprintf(s, "joystick_%i_axis_%i", c, d); - joystick_state[c].axis_mapping[d] = config_get_int("Input devices", s, d); + sprintf(temps, "joystick_%i_axis_%i", c, d); + joystick_state[c].axis_mapping[d] = config_get_int(cat, temps, d); } for (d = 0; d < joystick_get_button_count(joystick_type); d++) { - sprintf(s, "joystick_%i_button_%i", c, d); - joystick_state[c].button_mapping[d] = config_get_int("Input devices", s, d); + sprintf(temps, "joystick_%i_button_%i", c, d); + joystick_state[c].button_mapping[d] = config_get_int(cat, temps, d); } for (d = 0; d < joystick_get_pov_count(joystick_type); d++) { - sprintf(s, "joystick_%i_pov_%i", c, d); - p = (char *)config_get_string("Input devices", s, "0, 0"); + sprintf(temps, "joystick_%i_pov_%i", c, d); + p = config_get_string(cat, temps, "0, 0"); joystick_state[c].pov_mapping[d][0] = joystick_state[c].pov_mapping[d][1] = 0; sscanf(p, "%i, %i", &joystick_state[c].pov_mapping[d][0], &joystick_state[c].pov_mapping[d][1]); } @@ -748,37 +771,41 @@ static void loadconfig_input_devices(void) } } + +/* Sound */ static void loadconfig_sound(void) { + char *cat = "Sound"; char *p; - /* Sound */ - p = (char *)config_get_string("Sound", "sndcard", ""); - if (p) + p = config_get_string(cat, "sndcard", NULL); + if (p != NULL) sound_card_current = sound_card_get_from_internal_name(p); else sound_card_current = 0; - midi_id = config_get_int("Sound", "midi_host_device", 0); + midi_id = config_get_int(cat, "midi_host_device", 0); - SSI2001 = !!config_get_int("Sound", "ssi2001", 0); - GAMEBLASTER = !!config_get_int("Sound", "gameblaster", 0); - GUS = !!config_get_int("Sound", "gus", 0); - opl3_type = !!config_get_int("Sound", "opl3_type", 1); + SSI2001 = !!config_get_int(cat, "ssi2001", 0); + GAMEBLASTER = !!config_get_int(cat, "gameblaster", 0); + GUS = !!config_get_int(cat, "gus", 0); + opl3_type = !!config_get_int(cat, "opl3_type", 1); } + +/* Network */ static void loadconfig_network(void) { + char *cat = "Network"; char *p; - /* Network */ - network_type = config_get_int("Network", "net_type", -1); - memset(pcap_dev, 0, 512); - p = (char *)config_get_string("Network", "net_pcap_device", "none"); - if (p) - if ((network_dev_to_id(p) == -1) || (netdev_num == 1)) + network_type = config_get_int(cat, "net_type", NET_TYPE_NONE); + memset(network_pcap, '\0', sizeof(network_pcap)); + p = config_get_string(cat, "net_pcap_device", "none"); + if (p != NULL) + if ((network_dev_to_id(p) == -1) || (network_ndev == 1)) { - if ((netdev_num == 1) && strcmp(pcap_dev, "none")) + if ((network_ndev == 1) && strcmp(network_pcap, "none")) { msgbox_error(ghwnd, 2107); } @@ -787,59 +814,59 @@ static void loadconfig_network(void) msgbox_error(ghwnd, 2200); } - strcpy(pcap_dev, "none"); + strcpy(network_pcap, "none"); } else { - strcpy(pcap_dev, p); + strcpy(network_pcap, p); } else - strcpy(pcap_dev, "none"); - p = (char *)config_get_string("Network", "net_card", NULL); - network_card = (p) ? network_card_get_from_internal_name(p) : 0; + strcpy(network_pcap, "none"); + p = config_get_string(cat, "net_card", NULL); + if (p != NULL) + network_card = network_card_get_from_internal_name(p); + else + network_card = 0; } + +/* Other peripherals */ static void loadconfig_other_peripherals(void) { - int c; + char *cat = "Other peripherals"; + char temps[512]; char *p; + int c; - /* Other peripherals */ - p = (char *)config_get_string("Other peripherals", "scsicard", ""); - if (p) + p = config_get_string(cat, "scsicard", NULL); + if (p != NULL) scsi_card_current = scsi_card_get_from_internal_name(p); else scsi_card_current = 0; - memset(hdd_controller_name, 0, 16); - p = (char *)config_get_string("Other peripherals", "hdd_controller", ""); - if (p) + memset(hdd_controller_name, '\0', sizeof(hdd_controller_name)); + p = config_get_string(cat, "hdd_controller", NULL); + if (p != NULL) strcpy(hdd_controller_name, p); else strcpy(hdd_controller_name, "none"); - memset(temps, 0, 512); + memset(temps, '\0', sizeof(temps)); for (c = 2; c < 4; c++) { sprintf(temps, "ide_%02i", c + 1); - p = config_get_string("Other peripherals", temps, "0, 00"); - if (p) - { - sscanf(p, "%i, %02i", &ide_enable[c], &ide_irq[c]); - } - else - { - sscanf(p, "0, 00", &ide_enable[c], &ide_irq[c]); - } + p = config_get_string(cat, temps, NULL); + if (p == NULL) + p = "0, 00"; + sscanf(p, "%i, %02i", &ide_enable[c], &ide_irq[c]); } - serial_enabled[0] = !!config_get_int("Other peripherals", "serial1_enabled", 1); - serial_enabled[1] = !!config_get_int("Other peripherals", "serial2_enabled", 1); - lpt_enabled = !!config_get_int("Other peripherals", "lpt_enabled", 1); - bugger_enabled = !!config_get_int("Other peripherals", "bugger_enabled", 0); + serial_enabled[0] = !!config_get_int(cat, "serial1_enabled", 1); + serial_enabled[1] = !!config_get_int(cat, "serial2_enabled", 1); + lpt_enabled = !!config_get_int(cat, "lpt_enabled", 1); + bugger_enabled = !!config_get_int(cat, "bugger_enabled", 0); } -static char temps2[512]; static int config_string_to_bus(char *str, int cdrom) { @@ -917,26 +944,26 @@ no_mfm_cdrom: return 0; } + +/* Hard disks */ static void loadconfig_hard_disks(void) { + char *cat = "Hard disks"; + char temps[512]; + char temps2[512]; + char s[512]; int c; char *p; wchar_t *wp; - /* Hard disks */ - memset(temps, 0, 512); + memset(temps, '\0', sizeof(temps)); for (c = 0; c < HDC_NUM; c++) { sprintf(temps, "hdd_%02i_parameters", c + 1); - p = (char *)config_get_string("Hard disks", temps, "0, 0, 0, none"); - if (p) - { - sscanf(p, "%" PRIu64 ", %" PRIu64", %" PRIu64 ", %s", &hdc[c].spt, &hdc[c].hpc, &hdc[c].tracks, s); - } - else - { - sscanf("0, 0, 0, none", "%" PRIu64 ", %" PRIu64", %" PRIu64 ", %s", &hdc[c].spt, &hdc[c].hpc, &hdc[c].tracks, s); - } + p = config_get_string(cat, temps, NULL); + if (p == NULL) + p = "0, 0, 0, none"; + sscanf(p, "%" PRIu64 ", %" PRIu64", %" PRIu64 ", %s", &hdc[c].spt, &hdc[c].hpc, &hdc[c].tracks, s); hdc[c].bus = config_string_to_bus(s, 0); @@ -954,14 +981,14 @@ static void loadconfig_hard_disks(void) } sprintf(temps, "hdd_%02i_mfm_channel", c + 1); - hdc[c].mfm_channel = config_get_int("Hard disks", temps, 0); + hdc[c].mfm_channel = config_get_int(cat, temps, 0); if (hdc[c].mfm_channel > 1) { hdc[c].mfm_channel = 1; } sprintf(temps, "hdd_%02i_ide_channel", c + 1); - hdc[c].ide_channel = config_get_int("Hard disks", temps, 0); + hdc[c].ide_channel = config_get_int(cat, temps, 0); if (hdc[c].ide_channel > 7) { hdc[c].ide_channel = 7; @@ -969,13 +996,14 @@ static void loadconfig_hard_disks(void) sprintf(temps, "hdd_%02i_scsi_location", c + 1); sprintf(temps2, "%02u:%02u", c, 0); - p = (char *)config_get_string("Hard disks", temps, temps2); - if (p) + p = config_get_string(cat, temps, temps2); + if (p != NULL) { sscanf(p, "%02u:%02u", &hdc[c].scsi_id, &hdc[c].scsi_lun); } else { + /* FIXME: Can never happen, 'temps' above is non-NULL. */ sscanf(temps2, "%02u:%02u", &hdc[c].scsi_id, &hdc[c].scsi_lun); } @@ -990,7 +1018,8 @@ static void loadconfig_hard_disks(void) memset(hdd_fn[c], 0, 1024); sprintf(temps, "hdd_%02i_fn", c + 1); - wp = (wchar_t *)config_get_wstring("Hard disks", temps, L""); + wp = config_get_wstring(cat, temps, L""); + /*FIXME: wcslen(wp) instead of 512? */ if (wp) memcpy(hdd_fn[c], wp, 512); else { memcpy(hdd_fn[c], L"", 2); @@ -999,20 +1028,25 @@ static void loadconfig_hard_disks(void) } } + +/* Removable devices */ static void loadconfig_removable_devices(void) { + char *cat = "Removable devices"; + char temps[512]; + char temps2[512]; + char s[512]; int c; char *p; wchar_t *wp; - /* Removable devices */ for (c = 0; c < FDD_NUM; c++) { sprintf(temps, "fdd_%02i_type", c + 1); - p = (char *)config_get_string("Removable devices", temps, (c < 2) ? "525_2dd" : "none"); + p = config_get_string(cat, temps, (c < 2) ? "525_2dd" : "none"); if (p) fdd_set_type(c, fdd_get_from_internal_name(p)); - else + else /*FIXME: never happens, "none" is non-NULL */ fdd_set_type(c, (c < 2) ? 2 : 0); if (fdd_get_type(c) > 13) { @@ -1020,7 +1054,8 @@ static void loadconfig_removable_devices(void) } sprintf(temps, "fdd_%02i_fn", c + 1); - wp = (wchar_t *)config_get_wstring("Removable devices", temps, L""); + wp = config_get_wstring(cat, temps, L""); + /*FIXME: see above, wcslen(wp) ? */ if (wp) memcpy(discfns[c], wp, 512); else { memcpy(discfns[c], L"", 2); @@ -1028,19 +1063,19 @@ static void loadconfig_removable_devices(void) } printf("Floppy: %ws\n", discfns[c]); sprintf(temps, "fdd_%02i_writeprot", c + 1); - ui_writeprot[c] = !!config_get_int("Removable devices", temps, 0); + ui_writeprot[c] = !!config_get_int(cat, temps, 0); } memset(temps, 0, 512); for (c = 0; c < CDROM_NUM; c++) { sprintf(temps, "cdrom_%02i_host_drive", c + 1); - cdrom_drives[c].host_drive = config_get_int("Removable devices", temps, 0); + cdrom_drives[c].host_drive = config_get_int(cat, temps, 0); cdrom_drives[c].prev_host_drive = cdrom_drives[c].host_drive; sprintf(temps, "cdrom_%02i_parameters", c + 1); - p = (char *)config_get_string("Removable devices", temps, "0, none"); - if (p) + p = config_get_string(cat, temps, NULL); + if (p != NULL) { sscanf(p, "%u, %s", &cdrom_drives[c].sound_on, s); } @@ -1052,7 +1087,7 @@ static void loadconfig_removable_devices(void) cdrom_drives[c].bus_type = config_string_to_bus(s, 1); sprintf(temps, "cdrom_%02i_ide_channel", c + 1); - cdrom_drives[c].ide_channel = config_get_int("Removable devices", temps, c + 2); + cdrom_drives[c].ide_channel = config_get_int(cat, temps, c + 2); if (cdrom_drives[c].ide_channel > 7) { cdrom_drives[c].ide_channel = 7; @@ -1060,12 +1095,12 @@ static void loadconfig_removable_devices(void) sprintf(temps, "cdrom_%02i_scsi_location", c + 1); sprintf(temps2, "%02u:%02u", c + 2, 0); - p = (char *)config_get_string("Removable devices", temps, temps2); - if (p) + p = config_get_string(cat, temps, temps2); + if (p != NULL) { sscanf(p, "%02u:%02u", &cdrom_drives[c].scsi_device_id, &cdrom_drives[c].scsi_device_lun); } - else + else /*FIXME: never happens, 'temps2' is non-NULL */ { sscanf(temps2, "%02u:%02u", &cdrom_drives[c].scsi_device_id, &cdrom_drives[c].scsi_device_lun); } @@ -1081,8 +1116,9 @@ static void loadconfig_removable_devices(void) } sprintf(temps, "cdrom_%02i_image_path", c + 1); - wp = (wchar_t *)config_get_wstring("Removable devices", temps, L""); - if (wp) memcpy(cdrom_image[c].image_path, wp, 512); + wp = config_get_wstring(cat, temps, L""); + /*FIXME see above, wcslen(wp) */ + if (wp != NULL) memcpy(cdrom_image[c].image_path, wp, 512); else { memcpy(cdrom_image[c].image_path, L"", 2); cdrom_image[c].image_path[0] = L'\0'; @@ -1090,12 +1126,12 @@ static void loadconfig_removable_devices(void) } } + void loadconfig(wchar_t *fn) { - if (!fn) - config_load(config_file_default); - else - config_load(fn); + if (fn == NULL) + fn = config_file_default; + config_load(fn); /* General */ loadconfig_general(); @@ -1126,10 +1162,10 @@ void loadconfig(wchar_t *fn) } -wchar_t temp_nvr_path[1024]; wchar_t *nvr_concat(wchar_t *to_concat) { + static wchar_t temp_nvr_path[1024]; char *p; wchar_t *wp; @@ -1144,146 +1180,171 @@ wchar_t *nvr_concat(wchar_t *to_concat) return temp_nvr_path; } -void saveconfig_general(void) + +static void saveconfig_general(void) { - config_set_int("General", "vid_resize", vid_resize); + char *cat = "General"; + char temps[512]; + + config_set_int(cat, "vid_resize", vid_resize); switch(vid_api) { case 0: - config_set_string("General", "vid_renderer", "ddraw"); + config_set_string(cat, "vid_renderer", "ddraw"); break; case 1: default: - config_set_string("General", "vid_renderer", "d3d9"); + config_set_string(cat, "vid_renderer", "d3d9"); break; } - config_set_int("General", "video_fullscreen_scale", video_fullscreen_scale); - config_set_int("General", "video_fullscreen_first", video_fullscreen_first); + config_set_int(cat, "video_fullscreen_scale", video_fullscreen_scale); + config_set_int(cat, "video_fullscreen_first", video_fullscreen_first); - config_set_int("General", "force_43", force_43); - config_set_int("General", "scale", scale); - config_set_int("General", "enable_overscan", enable_overscan); + config_set_int(cat, "force_43", force_43); + config_set_int(cat, "scale", scale); + config_set_int(cat, "enable_overscan", enable_overscan); sprintf(temps, "%i, %i, %i, %i", window_w, window_h, window_x, window_y); - config_set_string("General", "window_coordinates", temps); - config_set_int("General", "window_remember", window_remember); + config_set_string(cat, "window_coordinates", temps); + config_set_int(cat, "window_remember", window_remember); - config_set_wstring("General", "nvr_path", nvr_path); + config_set_wstring(cat, "nvr_path", nvr_path); #ifndef __unix - config_set_hex16("General", "language", dwLanguage); + config_set_hex16(cat, "language", dwLanguage); #endif } -void saveconfig_machine(void) -{ - /* Machine */ - config_set_string("Machine", "model", model_get_internal_name()); - config_set_int("Machine", "cpu_manufacturer", cpu_manufacturer); - config_set_int("Machine", "cpu", cpu); - config_set_int("Machine", "cpu_waitstates", cpu_waitstates); - config_set_int("Machine", "mem_size", mem_size); - config_set_int("Machine", "cpu_use_dynarec", cpu_use_dynarec); - config_set_int("Machine", "cpu_enable_fpu", enable_external_fpu); - config_set_int("Machine", "enable_sync", enable_sync); +/* Machine */ +static void saveconfig_machine(void) +{ + char *cat = "Machine"; + + config_set_string(cat, "model", model_get_internal_name()); + config_set_int(cat, "cpu_manufacturer", cpu_manufacturer); + config_set_int(cat, "cpu", cpu); + config_set_int(cat, "cpu_waitstates", cpu_waitstates); + + config_set_int(cat, "mem_size", mem_size); + config_set_int(cat, "cpu_use_dynarec", cpu_use_dynarec); + config_set_int(cat, "cpu_enable_fpu", enable_external_fpu); + config_set_int(cat, "enable_sync", enable_sync); } -void saveconfig_video(void) + +/* Video */ +static void saveconfig_video(void) { - /* Video */ - config_set_string("Video", "gfxcard", video_get_internal_name(video_old_to_new(gfxcard))); - config_set_int("Video", "video_speed", video_speed); - config_set_int("Video", "voodoo", voodoo_enabled); + char *cat = "Video"; + + config_set_string(cat, "gfxcard", video_get_internal_name(video_old_to_new(gfxcard))); + config_set_int(cat, "video_speed", video_speed); + config_set_int(cat, "voodoo", voodoo_enabled); } -void saveconfig_input_devices(void) + +/* Input devices */ +static void saveconfig_input_devices(void) { + char *cat = "Input devices"; + char temps[512]; + char s[512]; int c, d; - /* Input devices */ - config_set_string("Input devices", "mouse_type", mouse_get_internal_name(mouse_type)); + config_set_string(cat, "mouse_type", mouse_get_internal_name(mouse_type)); - config_set_int("Input devices", "joystick_type", joystick_type); + config_set_int(cat, "joystick_type", joystick_type); for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) { sprintf(s, "joystick_%i_nr", c); - config_set_int("Input devices", s, joystick_state[c].plat_joystick_nr); + config_set_int(cat, s, joystick_state[c].plat_joystick_nr); if (joystick_state[c].plat_joystick_nr) { for (d = 0; d < joystick_get_axis_count(joystick_type); d++) { sprintf(s, "joystick_%i_axis_%i", c, d); - config_set_int("Input devices", s, joystick_state[c].axis_mapping[d]); + config_set_int(cat, s, joystick_state[c].axis_mapping[d]); } for (d = 0; d < joystick_get_button_count(joystick_type); d++) { sprintf(s, "joystick_%i_button_%i", c, d); - config_set_int("Input devices", s, joystick_state[c].button_mapping[d]); + config_set_int(cat, s, joystick_state[c].button_mapping[d]); } for (d = 0; d < joystick_get_pov_count(joystick_type); d++) { sprintf(s, "joystick_%i_pov_%i", c, d); sprintf(temps, "%i, %i", joystick_state[c].pov_mapping[d][0], joystick_state[c].pov_mapping[d][1]); - config_set_string("Input devices", s, temps); + config_set_string(cat, s, temps); } } } } -void saveconfig_sound(void) + +/* Sound */ +static void saveconfig_sound(void) { - /* Sound */ - config_set_string("Sound", "sndcard", sound_card_get_internal_name(sound_card_current)); + char *cat = "Sound"; - config_set_int("Sound", "midi_host_device", midi_id); + config_set_string(cat, "sndcard", sound_card_get_internal_name(sound_card_current)); - config_set_int("Sound", "gameblaster", GAMEBLASTER); - config_set_int("Sound", "gus", GUS); - config_set_int("Sound", "ssi2001", SSI2001); - config_set_int("Sound", "opl3_type", opl3_type); + config_set_int(cat, "midi_host_device", midi_id); + + config_set_int(cat, "gameblaster", GAMEBLASTER); + config_set_int(cat, "gus", GUS); + config_set_int(cat, "ssi2001", SSI2001); + config_set_int(cat, "opl3_type", opl3_type); } -void saveconfig_network(void) + +/* Network */ +static void saveconfig_network(void) { - /* Network */ - if (pcap_dev != NULL) + char *cat = "Network"; + + if (network_pcap[0] != '\0') { - config_set_string("Network", "net_pcap_device", pcap_dev); + config_set_string(cat, "net_pcap_device", network_pcap); } else { - config_set_string("Network", "net_pcap_device", "none"); + config_set_string(cat, "net_pcap_device", "none"); } - config_set_int("Network", "net_type", network_type); - config_set_string("Network", "net_card", network_card_get_internal_name(network_card)); + config_set_int(cat, "net_type", network_type); + config_set_string(cat, "net_card", network_card_get_internal_name(network_card)); } -void saveconfig_other_peripherals(void) + +/* Other peripherals */ +static void saveconfig_other_peripherals(void) { + char *cat = "Other peripherals"; + char temps[512]; + char temps2[512]; int c, d; - /* Other peripherals */ - config_set_string("Other peripherals", "scsicard", scsi_card_get_internal_name(scsi_card_current)); + config_set_string(cat, "scsicard", scsi_card_get_internal_name(scsi_card_current)); - config_set_string("Other peripherals", "hdd_controller", hdd_controller_name); + config_set_string(cat, "hdd_controller", hdd_controller_name); - memset(temps, 0, 512); + memset(temps, '\0', sizeof(temps)); for (c = 2; c < 4; c++) { sprintf(temps, "ide_%02i", c + 1); sprintf(temps2, "%i, %02i", !!ide_enable[c], ide_irq[c]); - config_set_string("Other peripherals", temps, temps2); + config_set_string(cat, temps, temps2); } - config_set_int("Other peripherals", "serial1_enabled", serial_enabled[0]); - config_set_int("Other peripherals", "serial2_enabled", serial_enabled[1]); - config_set_int("Other peripherals", "lpt_enabled", lpt_enabled); - config_set_int("Other peripherals", "bugger_enabled", bugger_enabled); + config_set_int(cat, "serial1_enabled", serial_enabled[0]); + config_set_int(cat, "serial2_enabled", serial_enabled[1]); + config_set_int(cat, "lpt_enabled", lpt_enabled); + config_set_int(cat, "bugger_enabled", bugger_enabled); } + static char *config_bus_to_string(int bus) { switch (bus) @@ -1307,74 +1368,84 @@ static char *config_bus_to_string(int bus) } } -void saveconfig_hard_disks(void) + +/* Hard disks */ +static void saveconfig_hard_disks(void) { + char *cat = "Hard disks"; + char temps[512]; + char temps2[512]; + char s[512]; int c, d; char *p; - /* Hard disks */ - memset(temps, 0, 512); + memset(temps, '\0', sizeof(temps)); for (c = 0; c < HDC_NUM; c++) { sprintf(temps, "hdd_%02i_parameters", c + 1); - memset(s, 0, 512); + memset(s, '\0', sizeof(s)); p = config_bus_to_string(hdc[c].bus); sprintf(temps2, "%" PRIu64 ", %" PRIu64", %" PRIu64 ", %s", hdc[c].spt, hdc[c].hpc, hdc[c].tracks, p); - config_set_string("Hard disks", temps, temps2); + config_set_string(cat, temps, temps2); sprintf(temps, "hdd_%02i_mfm_channel", c + 1); - config_set_int("Hard disks", temps, hdc[c].mfm_channel); + config_set_int(cat, temps, hdc[c].mfm_channel); sprintf(temps, "hdd_%02i_ide_channel", c + 1); - config_set_int("Hard disks", temps, hdc[c].ide_channel); + config_set_int(cat, temps, hdc[c].ide_channel); sprintf(temps, "hdd_%02i_scsi_location", c + 1); sprintf(temps2, "%02u:%02u", hdc[c].scsi_id, hdc[c].scsi_lun); - config_set_string("Hard disks", temps, temps2); + config_set_string(cat, temps, temps2); sprintf(temps, "hdd_%02i_fn", c + 1); - config_set_wstring("Hard disks", temps, hdd_fn[c]); + config_set_wstring(cat, temps, hdd_fn[c]); } } -void saveconfig_removable_devices(void) + +/* Removable devices */ +static void saveconfig_removable_devices(void) { + char *cat = "Removable devices"; + char temps[512]; + char temps2[512]; int c, d; - /* Removable devices */ - memset(temps, 0, 512); + memset(temps, '\0', sizeof(temps)); for (c = 0; c < FDD_NUM; c++) { sprintf(temps, "fdd_%02i_type", c + 1); - config_set_string("Removable devices", temps, fdd_get_internal_name(fdd_get_type(c))); + config_set_string(cat, temps, fdd_get_internal_name(fdd_get_type(c))); sprintf(temps, "fdd_%02i_fn", c + 1); - config_set_wstring("Removable devices", temps, discfns[c]); + config_set_wstring(cat, temps, discfns[c]); sprintf(temps, "fdd_%02i_writeprot", c + 1); - config_set_int("Removable devices", temps, ui_writeprot[c]); + config_set_int(cat, temps, ui_writeprot[c]); } - memset(temps, 0, 512); + memset(temps, '\0', sizeof(temps)); for (c = 0; c < CDROM_NUM; c++) { sprintf(temps, "cdrom_%02i_host_drive", c + 1); - config_set_int("Removable devices", temps, cdrom_drives[c].host_drive); + config_set_int(cat, temps, cdrom_drives[c].host_drive); sprintf(temps, "cdrom_%02i_parameters", c + 1); sprintf(temps2, "%u, %s", cdrom_drives[c].sound_on, config_bus_to_string(cdrom_drives[c].bus_type)); - config_set_string("Removable devices", temps, temps2); + config_set_string(cat, temps, temps2); sprintf(temps, "cdrom_%02i_ide_channel", c + 1); - config_set_int("Removable devices", temps, cdrom_drives[c].ide_channel); + config_set_int(cat, temps, cdrom_drives[c].ide_channel); sprintf(temps, "cdrom_%02i_scsi_location", c + 1); sprintf(temps2, "%02u:%02u", cdrom_drives[c].scsi_device_id, cdrom_drives[c].scsi_device_lun); - config_set_string("Removable devices", temps, temps2); + config_set_string(cat, temps, temps2); sprintf(temps, "cdrom_%02i_image_path", c + 1); - config_set_wstring("Removable devices", temps, cdrom_image[c].image_path); + config_set_wstring(cat, temps, cdrom_image[c].image_path); } } + void saveconfig(void) { int c, d; diff --git a/src/config.h b/src/config.h index 766257f37..fb33cd98d 100644 --- a/src/config.h +++ b/src/config.h @@ -1,37 +1,39 @@ /* Copyright holders: Sarah Walker see COPYING for more details */ -int config_get_int(char *head, char *name, int def); -char *config_get_string(char *head, char *name, char *def); -wchar_t *config_get_wstring(char *head, char *name, wchar_t *def); -void config_set_int(char *head, char *name, int val); -void config_set_string(char *head, char *name, char *val); -void config_set_wstring(char *head, char *name, wchar_t *val); -char *get_filename(char *s); -wchar_t *get_filename_w(wchar_t *s); -void append_filename(char *dest, char *s1, char *s2, int size); -void append_filename_w(wchar_t *dest, wchar_t *s1, wchar_t *s2, int size); -void put_backslash(char *s); -void put_backslash_w(wchar_t *s); -char *get_extension(char *s); + +extern wchar_t config_file_default[256]; + #ifdef __cplusplus extern "C" { #endif -wchar_t *get_extension_w(wchar_t *s); +extern int config_get_int(char *head, char *name, int def); +extern char *config_get_string(char *head, char *name, char *def); +extern wchar_t *config_get_wstring(char *head, char *name, wchar_t *def); +extern void config_set_int(char *head, char *name, int val); +extern void config_set_string(char *head, char *name, char *val); +extern void config_set_wstring(char *head, char *name, wchar_t *val); + +extern char *get_filename(char *s); +extern wchar_t *get_filename_w(wchar_t *s); +extern void append_filename(char *dest, char *s1, char *s2, int size); +extern void append_filename_w(wchar_t *dest, wchar_t *s1, wchar_t *s2, int size); +extern void put_backslash(char *s); +extern void put_backslash_w(wchar_t *s); +extern char *get_extension(char *s); + +extern wchar_t *get_extension_w(wchar_t *s); + +extern void config_load(wchar_t *fn); +extern void config_save(wchar_t *fn); +extern void config_dump(void); + +extern void loadconfig(wchar_t *fn); +extern void saveconfig(void); #ifdef __cplusplus } #endif - -void config_load(wchar_t *fn); -void config_save(wchar_t *fn); -void config_dump(void); -void config_free(void); - -extern wchar_t config_file_default[256]; - -void loadconfig(wchar_t *fn); -void saveconfig(void); diff --git a/src/gameport.c b/src/gameport.c index b75e9f6ce..a80d962b7 100644 --- a/src/gameport.c +++ b/src/gameport.c @@ -8,12 +8,12 @@ #include "device.h" #include "io.h" #include "timer.h" -#include "plat-joystick.h" #include "gameport.h" #include "joystick_ch_flightstick_pro.h" #include "joystick_standard.h" #include "joystick_sw_pad.h" #include "joystick_tm_fcs.h" +#include "plat_joystick.h" int joystick_type; diff --git a/src/joystick_ch_flightstick_pro.c b/src/joystick_ch_flightstick_pro.c index 9f0e97250..9697c1c6a 100644 --- a/src/joystick_ch_flightstick_pro.c +++ b/src/joystick_ch_flightstick_pro.c @@ -4,7 +4,8 @@ #include "timer.h" #include "gameport.h" #include "joystick_standard.h" -#include "plat-joystick.h" +#include "plat_joystick.h" + static void *ch_flightstick_pro_init() { diff --git a/src/joystick_standard.c b/src/joystick_standard.c index 7c8098ba7..c73260cac 100644 --- a/src/joystick_standard.c +++ b/src/joystick_standard.c @@ -4,7 +4,8 @@ #include "timer.h" #include "gameport.h" #include "joystick_standard.h" -#include "plat-joystick.h" +#include "plat_joystick.h" + static void *joystick_standard_init() { diff --git a/src/joystick_sw_pad.c b/src/joystick_sw_pad.c index 5fce2447a..d256c290f 100644 --- a/src/joystick_sw_pad.c +++ b/src/joystick_sw_pad.c @@ -26,7 +26,8 @@ #include "timer.h" #include "gameport.h" #include "joystick_sw_pad.h" -#include "plat-joystick.h" +#include "plat_joystick.h" + typedef struct { diff --git a/src/joystick_tm_fcs.c b/src/joystick_tm_fcs.c index a60e0ca5d..1380c052d 100644 --- a/src/joystick_tm_fcs.c +++ b/src/joystick_tm_fcs.c @@ -4,7 +4,8 @@ #include "timer.h" #include "gameport.h" #include "joystick_standard.h" -#include "plat-joystick.h" +#include "plat_joystick.h" + static void *tm_fcs_init() { diff --git a/src/keyboard.c b/src/keyboard.c index 22924f504..75ec25887 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -2,7 +2,7 @@ see COPYING for more details */ #include "ibm.h" -#include "plat-keyboard.h" +#include "plat_keyboard.h" #include "keyboard.h" int keybsendcallback = 0; diff --git a/src/mouse_bus.c b/src/mouse_bus.c index ca2c4f80a..5d5d5e97e 100644 --- a/src/mouse_bus.c +++ b/src/mouse_bus.c @@ -32,7 +32,7 @@ * Based on an early driver for MINIX 1.5. * Based on the 86Box PS/2 mouse driver as a framework. * - * Version: @(#)mouse_bus.c 1.0.4 2017/05/06 + * Version: @(#)mouse_bus.c 1.0.4 2017/05/17 * * Author: Fred N. van Kempen, * Copyright 1989-2017 Fred N. van Kempen. @@ -44,7 +44,7 @@ #include "pic.h" #include "mouse.h" #include "mouse_bus.h" -#include "plat-mouse.h" +#include "plat_mouse.h" #define ENABLE_3BTN 1 /* enable 3-button mode */ diff --git a/src/mouse_ps2.c b/src/mouse_ps2.c index fa9eda980..d5627eda8 100644 --- a/src/mouse_ps2.c +++ b/src/mouse_ps2.c @@ -3,7 +3,8 @@ #include "keyboard_at.h" #include "mouse.h" #include "mouse_ps2.h" -#include "plat-mouse.h" +#include "plat_mouse.h" + int mouse_scan = 0; diff --git a/src/net_ne2000.c b/src/net_ne2000.c index 0a4a66781..51fdd7b4e 100644 --- a/src/net_ne2000.c +++ b/src/net_ne2000.c @@ -11,7 +11,7 @@ * NOTE: Its still a mess, but we're getting there. The file will * also implement an NE1000 for 8-bit ISA systems. * - * Version: @(#)net_ne2000.c 1.0.3 2017/05/12 + * Version: @(#)net_ne2000.c 1.0.4 2017/05/17 * * Authors: Fred N. van Kempen, * Peter Grehan, grehan@iprg.nokia.com> @@ -49,9 +49,6 @@ typedef union { } bar_t; -/* This stuff should go into the struct. --FvK */ -static uint8_t maclocal[6] = {0xac, 0xde, 0x48, 0x88, 0xbb, 0xaa}; -static uint8_t maclocal_pci[6] = {0xac, 0xde, 0x48, 0x88, 0xbb, 0xaa}; #if ENABLE_NE2000_LOG static int nic_do_log = ENABLE_NE2000_LOG; #else @@ -216,6 +213,7 @@ typedef struct { int disable_netbios; int tx_timer_index; int tx_timer_active; + uint8_t maclocal[6]; /* configured MAC (local) address */ uint8_t pci_regs[256]; uint8_t eeprom[128]; /* for RTL8029AS */ rom_t bios_rom; @@ -1767,14 +1765,15 @@ nic_rom_init(nic_t *dev, wchar_t *s) } -uint32_t -ne2000_get_maclocal(void) +/* Return the 'local' part of our configured MAC address. */ +static uint32_t +nic_get_maclocal(nic_t *dev) { uint32_t temp; - temp = (((int) maclocal[3]) << 16); - temp |= (((int) maclocal[4]) << 8); - temp |= ((int) maclocal[5]); + temp = (((int) dev->maclocal[3]) << 16); + temp |= (((int) dev->maclocal[4]) << 8); + temp |= ((int) dev->maclocal[5]); return(temp); } @@ -1784,23 +1783,17 @@ static void * nic_init(int board) { uint32_t mac; - uint8_t *ptr; nic_t *dev; dev = malloc(sizeof(nic_t)); memset(dev, 0x00, sizeof(nic_t)); dev->board = board; dev->is_rtl8029as = (PCI && (board == NE2K_RTL8029AS)) ? 1 : 0; - if (board == NE2K_RTL8029AS) - { + if (board == NE2K_RTL8029AS) { strcpy(dev->name, "RTL8029AS"); - } - else if (board == NE2K_NE1000) - { + } else if (board == NE2K_NE1000) { strcpy(dev->name, "NE1000"); - } - else - { + } else { strcpy(dev->name, "NE2000"); } @@ -1812,32 +1805,35 @@ nic_init(int board) dev->base_address = device_get_config_int("addr"); } + /* See if we have a local MAC address configured. */ mac = device_get_config_int_ex("mac", -1); /* Set up our MAC address. */ if (dev->is_rtl8029as) { - maclocal[0] = 0x00; /* 00:20:18 (RTL 8029AS PCI vendor prefix). */ - maclocal[1] = 0x20; - maclocal[2] = 0x18; + dev->maclocal[0] = 0x00; /* 00:20:18 (RTL 8029AS PCI vendor prefix). */ + dev->maclocal[1] = 0x20; + dev->maclocal[2] = 0x18; } else { - maclocal[0] = 0x00; /* 00:00:D8 (NE2000 ISA vendor prefix). */ - maclocal[1] = 0x00; - maclocal[2] = 0xD8; + dev->maclocal[0] = 0x00; /* 00:00:D8 (NE2000 ISA vendor prefix). */ + dev->maclocal[1] = 0x00; + dev->maclocal[2] = 0xD8; } - ptr = maclocal; -pclog(1, "MAClocal: mac=%08lx\n", mac); if (mac & 0xff000000) { /* Generating new MAC. */ - ptr[3] = disc_random_generate(); - ptr[4] = disc_random_generate(); - ptr[5] = disc_random_generate() | 1; - device_set_config_int("mac", ne2000_get_maclocal()); + dev->maclocal[3] = disc_random_generate(); + dev->maclocal[4] = disc_random_generate(); + dev->maclocal[5] = disc_random_generate() | 1; + device_set_config_int("mac", nic_get_maclocal(dev)); } else { - ptr[3] = (mac>>16) & 0xff; - ptr[4] = (mac>>8) & 0xff; - ptr[5] = (mac & 0xff) | 1; + dev->maclocal[3] = (mac>>16) & 0xff; + dev->maclocal[4] = (mac>>8) & 0xff; +#if 1 + dev->maclocal[5] = (mac & 0xfe); +#else + dev->maclocal[5] = (mac & 0xff) | 1; +#endif } - memcpy(dev->physaddr, ptr, 6); + memcpy(dev->physaddr, dev->maclocal, sizeof(dev->maclocal)); pclog(1,"%s: I/O=%04x, IRQ=%d, MAC=%02x:%02x:%02x:%02x:%02x:%02x BIOS=%d\n", dev->name, dev->base_address, dev->base_irq, diff --git a/src/net_ne2000.h b/src/net_ne2000.h index 4ff2fd0f6..44dcc3311 100644 --- a/src/net_ne2000.h +++ b/src/net_ne2000.h @@ -8,7 +8,7 @@ * * Definitions for the NE2000 ethernet controller. * - * Version: @(#)net_ne2000.h 1.0.2 2017/05/11 + * Version: @(#)net_ne2000.h 1.0.3 2017/05/17 * * Author: Fred N. van Kempen, */ @@ -26,11 +26,4 @@ extern device_t ne2000_device; extern device_t rtl8029as_device; -extern void ne2000_generate_maclocal(uint32_t mac); -extern uint32_t ne2000_get_maclocal(void); - -extern void ne2000_generate_maclocal_pci(uint32_t mac); -extern uint32_t ne2000_get_maclocal_pci(void); - - #endif /*NET_NE2000_H*/ diff --git a/src/net_pcap.c b/src/net_pcap.c index 459e04c71..5eb57bb4c 100644 --- a/src/net_pcap.c +++ b/src/net_pcap.c @@ -8,7 +8,7 @@ * * Handle WinPcap library processing. * - * Version: @(#)net_pcap.c 1.0.1 2017/05/11 + * Version: @(#)net_pcap.c 1.0.2 2017/05/17 * * Author: Fred N. van Kempen, */ @@ -29,9 +29,6 @@ static thread_t *poll_tid; static NETRXCB poll_rx; /* network RX function to call */ static void *poll_arg; /* network RX function arg */ - int netdev_num; - netdev_t netdev_list[512]; - #ifdef WALTJE int pcap_do_log = 1; @@ -108,8 +105,6 @@ poll_thread(void *arg) } -char pcap_dev[512]; - /* Initialize WinPcap for us. */ int network_pcap_setup(uint8_t *mac, NETRXCB func, void *arg) @@ -135,11 +130,12 @@ network_pcap_setup(uint8_t *mac, NETRXCB func, void *arg) pclog("Initializing WinPcap, version %s\n", temp); /* Get the value of our capture interface. */ - if (pcap_dev == NULL) { + dev = network_pcap; + if ((dev[0] == '\0') || !strcmp(dev, "none")) { pclog(" No network device configured!\n"); return(-1); } - pclog(" Network interface: '%s'\n", pcap_dev); + pclog(" Network interface: '%s'\n", dev); pcap = pcap_open_live(dev, /* interface name */ 1518, /* maximum packet size */ @@ -227,16 +223,15 @@ network_devlist(netdev_t *list) pcap_if_t *devlist, *dev; int i = 0; - /* Note by Kotori: Add the first (and guaranteed to be always present) device - "None". */ + /* Create a first entry that's always there - needed by UI. */ strcpy(list->device, "none"); strcpy(list->description, "None"); - list++; - i++; + list++; i++; /* Retrieve the device list from the local machine */ if (pcap_findalldevs(&devlist, errbuf) == -1) { - pclog("NETWORK: error in pcap_findalldevs_ex: %s\n", errbuf); - return(i); /* Note by Kotori: The list will always have at least one entry - "None". */ + pclog("NETWORK: error in pcap_findalldevs: %s\n", errbuf); + return(i); } for (dev=devlist; dev!=NULL; dev=dev->next) { @@ -245,8 +240,7 @@ network_devlist(netdev_t *list) strcpy(list->description, dev->description); else memset(list->description, '\0', sizeof(list->description)); - list++; - i++; + list++; i++; } /* Release the memory. */ @@ -254,19 +248,3 @@ network_devlist(netdev_t *list) return(i); } - -int network_dev_to_id(char *dev) -{ - int i = 0; - - for (i = 0; i < netdev_num; i++) - { - if (!strcmp(netdev_list[i].device, dev)) - { - return i; - } - } - - /* If the device does not match the list, consider it as if it was set to "none". */ - return 0; -} \ No newline at end of file diff --git a/src/net_slirp.c b/src/net_slirp.c index 43574eccf..ca1d42869 100644 --- a/src/net_slirp.c +++ b/src/net_slirp.c @@ -8,7 +8,7 @@ * * Handle SLiRP library processing. * - * Version: @(#)net_slirp.c 1.0.1 2017/05/11 + * Version: @(#)net_slirp.c 1.0.2 2017/05/17 * * Author: Fred N. van Kempen, */ @@ -29,7 +29,6 @@ static queueADT slirpq; /* SLiRP library handle */ static thread_t *poll_tid; static NETRXCB poll_rx; /* network RX function to call */ static void *poll_arg; /* network RX function arg */ -static int fizz; /* Instead of calling this and crashing some times @@ -38,27 +37,29 @@ static int fizz; static void slirp_tic(void) { - int ret2,nfds; + int ret2, nfds; struct timeval tv; fd_set rfds, wfds, xfds; int tmo; - nfds=-1; + /* Let SLiRP create a list of all open sockets. */ + nfds = -1; FD_ZERO(&rfds); FD_ZERO(&wfds); FD_ZERO(&xfds); tmo = slirp_select_fill(&nfds, &rfds, &wfds, &xfds); /* this can crash */ - if (tmo < 0) { + if (tmo < 0) tmo = 500; - } tv.tv_sec = 0; - tv.tv_usec = tmo; /* basilisk default 10000 */ + tv.tv_usec = tmo; + /* Now wait for something to happen, or at most 'tmo' usec. */ ret2 = select(nfds+1, &rfds, &wfds, &xfds, &tv); - if (ret2 >= 0) { + + /* If something happened, let SLiRP handle it. */ + if (ret2 >= 0) slirp_select_poll(&rfds, &wfds, &xfds); - } } @@ -77,10 +78,8 @@ poll_thread(void *arg) pclog("SLiRP: poll event is %08lx\n", evt); while (slirpq != NULL) { - if (++fizz > 1200) { - fizz = 0; - slirp_tic(); - } + /* See if there is any work. */ + slirp_tic(); /* Wait for the next packet to arrive. */ if (QueuePeek(slirpq) == 0) { @@ -124,8 +123,6 @@ network_slirp_setup(uint8_t *mac, NETRXCB func, void *arg) slirpq = QueueCreate(); pclog(" Packet queue is at %08lx\n", &slirpq); - fizz = 0; - /* Save the callback info. */ poll_rx = func; poll_arg = arg; diff --git a/src/network.c b/src/network.c index 7d1d6e98f..63a8c0f9d 100644 --- a/src/network.c +++ b/src/network.c @@ -12,7 +12,7 @@ * it should be malloc'ed and then linked to the NETCARD def. * Will be done later. * - * Version: @(#)network.c 1.0.3 2017/05/12 + * Version: @(#)network.c 1.0.4 2017/05/17 * * Authors: Kotori, * Fred N. van Kempen, @@ -41,8 +41,12 @@ static netcard_t net_cards[] = { }; -int network_card; -int network_type; +/* Global variables. */ +int network_card; +int network_type; +int network_ndev; +netdev_t network_devs[32]; +char network_pcap[512]; /* @@ -55,8 +59,11 @@ int network_type; void network_init(void) { + network_type = NET_TYPE_NONE; network_card = 0; - network_type = -1; + + /* Initialize list of PCap devices. */ + network_ndev = network_devlist(network_devs); } @@ -80,11 +87,11 @@ network_attach(void *dev, uint8_t *mac, NETRXCB rx) /* Start the platform module. */ switch(network_type) { - case 0: + case NET_TYPE_PCAP: ret = network_pcap_setup(mac, rx, dev); break; - case 1: + case NET_TYPE_SLIRP: ret = network_slirp_setup(mac, rx, dev); break; } @@ -98,11 +105,11 @@ void network_close(void) { switch(network_type) { - case 0: + case NET_TYPE_PCAP: network_pcap_close(); break; - case 1: + case NET_TYPE_SLIRP: network_slirp_close(); break; } @@ -127,10 +134,11 @@ network_reset(void) network_close(); /* If no active card, we're done. */ - if (!network_card || (network_type<0)) return; + if ((network_type==NET_TYPE_NONE) || (network_card==0)) return; pclog("NETWORK: set up for %s, card=%s\n", - (network_type==1)?"SLiRP":"WinPcap", net_cards[network_card].name); + (network_type==NET_TYPE_SLIRP)?"SLiRP":"WinPcap", + net_cards[network_card].name); pclog("NETWORK: reset (card=%d)\n", network_card); /* Add the (new?) card to the I/O system. */ @@ -147,11 +155,11 @@ void network_tx(uint8_t *bufp, int len) { switch(network_type) { - case 0: + case NET_TYPE_PCAP: network_pcap_in(bufp, len); break; - case 1: + case NET_TYPE_SLIRP: network_slirp_in(bufp, len); break; } @@ -217,3 +225,19 @@ network_card_get_from_internal_name(char *s) return(-1); } + + +int +network_dev_to_id(char *dev) +{ + int i = 0; + + for (i=0; i * Fred N. van Kempen, @@ -18,6 +18,12 @@ # include +/* Network provider types. */ +#define NET_TYPE_NONE 0 /* networking disabled */ +#define NET_TYPE_PCAP 1 /* use the (Win)Pcap API */ +#define NET_TYPE_SLIRP 2 /* use the SLiRP port forwarder */ + +/* Supported network cards. */ #define NE1000 1 #define NE2000 2 #define RTL8029AS 3 @@ -44,11 +50,9 @@ typedef struct { /* Global variables. */ extern int network_card; extern int network_type; - -extern char pcap_dev[512]; - -extern int netdev_num; -extern netdev_t netdev_list[512]; +extern int network_ndev; +extern netdev_t network_devs[32]; +extern char network_pcap[512]; /* Function prototypes. */ @@ -68,13 +72,13 @@ extern void network_slirp_close(void); extern void network_slirp_in(uint8_t *, int); extern int network_devlist(netdev_t *); +extern int network_dev_to_id(char *); extern int network_card_available(int); extern char *network_card_getname(int); extern int network_card_has_config(int); extern char *network_card_get_internal_name(int); extern int network_card_get_from_internal_name(char *); -extern struct device_t *network_card_getdevice(int); +extern device_t *network_card_getdevice(int); - int network_dev_to_id(char *dev); #endif /*NETWORK_H*/ diff --git a/src/pc.c b/src/pc.c index 9fced90fb..7e05e9260 100644 --- a/src/pc.c +++ b/src/pc.c @@ -18,8 +18,6 @@ #include "device.h" #include "ali1429.h" -#include "cdrom.h" -#include "cdrom-ioctl.h" #include "disc.h" #include "disc_86f.h" #include "disc_fdi.h" @@ -31,20 +29,21 @@ #include "fdc.h" #include "fdd.h" #include "gameport.h" -#include "plat-joystick.h" -#include "plat-midi.h" +#include "plat_joystick.h" +#include "plat_midi.h" #include "hdd.h" #include "ide.h" #include "cdrom.h" -#include "cdrom-image.h" -#include "cdrom-null.h" +#include "cdrom_ioctl.h" +#include "cdrom_image.h" +#include "cdrom_null.h" #include "scsi.h" #include "keyboard.h" -#include "plat-keyboard.h" +#include "plat_keyboard.h" #include "keyboard_at.h" #include "model.h" #include "mouse.h" -#include "plat-mouse.h" +#include "plat_mouse.h" #include "network.h" #include "serial.h" #include "sound/sound.h" @@ -60,7 +59,7 @@ #include "amstrad.h" #ifdef WALTJE # define UNICODE -# include "plat-dir.h" +# include "plat_dir.h" #endif #ifndef __unix @@ -69,7 +68,7 @@ #include #undef BITMAP #include "win.h" -#include "win-language.h" +#include "win_language.h" #endif @@ -288,9 +287,6 @@ void initpc(int argc, wchar_t *argv[]) *p=L'\0'; pclog("path = %ws\n", pcempath); - /* Initialize list of PCap devices. */ - netdev_num = network_devlist(netdev_list); - for (c = 1; c < argc; c++) { if (!_wcsicmp(argv[c], L"--help")) diff --git a/src/pcap_if.rc b/src/pcap_if.rc deleted file mode 100644 index 57d78e657..000000000 --- a/src/pcap_if.rc +++ /dev/null @@ -1,52 +0,0 @@ -#ifdef _WIN32 -#include -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -#pragma code_page(1252) -#endif //_WIN32 - - -#ifdef RELEASE_BUILD -/* Icon by Devcore - https://commons.wikimedia.org/wiki/File:Icon_PC_256x256.png */ -100 ICON DISCARDABLE "ICONS/86Box-RB.ico" -#else -/* Icon by Devcore - https://commons.wikimedia.org/wiki/File:Icon_PC2_256x256.png */ -100 ICON DISCARDABLE "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 diff --git a/src/plat-dinput.h b/src/plat-dinput.h deleted file mode 100644 index b5d7eca06..000000000 --- a/src/plat-dinput.h +++ /dev/null @@ -1,4 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -extern LPDIRECTINPUT lpdi; diff --git a/src/plat-dir.h b/src/plat-dir.h deleted file mode 100644 index f9fbf2a9d..000000000 --- a/src/plat-dir.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Definitions for the platform OpenDir module. - * - * Version: @(#)plat-dir.h 1.0.1 2017/05/12 - * - * Author: Fred N. van Kempen, - * 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*/ diff --git a/src/plat-joystick.h b/src/plat-joystick.h deleted file mode 100644 index aecb3537c..000000000 --- a/src/plat-joystick.h +++ /dev/null @@ -1,69 +0,0 @@ -/* 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 \ No newline at end of file diff --git a/src/plat-keyboard.h b/src/plat-keyboard.h deleted file mode 100644 index f062c5951..000000000 --- a/src/plat-keyboard.h +++ /dev/null @@ -1,22 +0,0 @@ -/* 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 - diff --git a/src/plat-midi.h b/src/plat-midi.h deleted file mode 100644 index 87ed57306..000000000 --- a/src/plat-midi.h +++ /dev/null @@ -1,10 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -void midi_init(); -void midi_close(); -void midi_write(uint8_t val); -int midi_get_num_devs(); -void midi_get_dev_name(int num, char *s); - -extern int midi_id; diff --git a/src/plat-mouse.h b/src/plat-mouse.h deleted file mode 100644 index ff248f301..000000000 --- a/src/plat-mouse.h +++ /dev/null @@ -1,16 +0,0 @@ -/* 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 diff --git a/src/plat-serial.h b/src/plat-serial.h deleted file mode 100644 index e11737a89..000000000 --- a/src/plat-serial.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Definitions for the Bottom Half of the SERIAL card. - * - * Version: @(#)plat-serial.h 1.0.3 2017/05/06 - * - * Author: Fred N. van Kempen, - * Copyright 2017 Fred N. van Kempen. - */ -#ifndef PLAT_SERIAL_H -# define PLAT_SERIAL_H - - -typedef struct { - char name[79]; /* 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; -#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_write(BHTTY *, unsigned char); -extern int bhtty_read(BHTTY *, unsigned char *, int); - - -#endif /*PLAT_SERIAL_H*/ diff --git a/src/ppi.c b/src/ppi.c index 0eb9f3a0f..e5d5a27ec 100644 --- a/src/ppi.c +++ b/src/ppi.c @@ -10,9 +10,8 @@ #include "ibm.h" #include "pit.h" - -#include "plat-keyboard.h" -#include "plat-mouse.h" +#include "plat_keyboard.h" +#include "plat_mouse.h" void ppi_reset() { diff --git a/src/resource.h b/src/resource.h deleted file mode 100644 index 5364bf674..000000000 --- a/src/resource.h +++ /dev/null @@ -1,432 +0,0 @@ -/* Copyright holders: Tenshi - see COPYING for more details -*/ -/* {{NO_DEPENDENCIES}} - Microsoft Developer Studio generated include file. - Used by 86Box.rc -*/ -#define IDHDCONFIG 3 -#define IDCDCONFIG 4 -#define CONFIGUREDLG_MACHINE 101 -#define CONFIGUREDLG_VIDEO 102 -#define CONFIGUREDLG_INPUT 103 -#define CONFIGUREDLG_SOUND 104 -#define CONFIGUREDLG_NETWORK 105 -#define CONFIGUREDLG_PERIPHERALS 106 -#define CONFIGUREDLG_HARD_DISKS 107 -#define CONFIGUREDLG_REMOVABLE_DEVICES 108 -#define ABOUTDLG 109 -#define CONFIGUREDLG_HARD_DISKS_ADD 110 -#define CONFIGUREDLG_MAIN 117 -#define IDC_SETTINGSCATLIST 1004 -#define IDC_LIST_HARD_DISKS 1005 -#define IDC_COMBO_MACHINE 1006 -#define IDC_COMBO_CPU_TYPE 1007 -#define IDC_COMBO_CPU 1008 -#define IDC_COMBO_WS 1009 -#define IDC_CHECK_DYNAREC 1010 -#define IDC_CHECK_FPU 1011 -#define IDC_COMBO_SCSI 1012 -#define IDC_CONFIGURE_SCSI 1013 -#define IDC_COMBO_VIDEO 1014 -#define IDC_COMBO_VIDEO_SPEED 1015 -#define IDC_CHECK_VOODOO 1016 -#define IDC_CHECKCMS 1016 -#define IDC_CONFIGURE_VOODOO 1017 -#define IDC_CHECKNUKEDOPL 1018 -#define IDC_COMBO_JOYSTICK 1018 -#define IDC_CHECK_SYNC 1019 -#define IDC_LIST_FLOPPY_DRIVES 1020 -#define IDC_LIST_CDROM_DRIVES 1021 -#define IDC_CONFIGURE_MACHINE 1022 -#define IDC_COMBO_LANG 1023 -#define IDC_BUTTON_FDD_ADD 1024 -#define IDC_BUTTON_FDD_EDIT 1025 -#define IDC_BUTTON_FDD_REMOVE 1026 -#define IDC_BUTTON_CDROM_ADD 1027 -#define IDC_BUTTON_HDD_ADD_NEW 1027 -#define IDC_BUTTON_CDROM_EDIT 1028 -#define IDC_BUTTON_HDD_ADD 1028 -#define IDC_BUTTON_CDROM_REMOVE 1029 -#define IDC_BUTTON_HDD_REMOVE 1029 -#define IDC_HDIMAGE_NEW 1035 -#define IDC_HD_BUS 1036 -#define IDC_HDIMAGE_EXISTING 1037 -#define IDC_COMBO_HD_BUS 1038 -#define IDC_EDIT_HD_FILE_NAME 1039 -#define IDC_EDIT_HD_CYL 1040 -#define IDC_EDIT_HD_HPC 1041 -#define IDC_EDIT_HD_SPT 1042 -#define IDC_EDIT_HD_SIZE 1043 -#define IDC_COMBO_HD_TYPE 1044 -#define IDC_COMBO_HD_LOCATION 1045 -#define IDC_CHECKGUS 1046 -#define IDC_COMBO_HD_CHANNEL 1047 -#define IDC_COMBO_HD_CHANNEL_IDE 1048 -#define IDC_COMBO_HD_ID 1050 -#define IDC_COMBO_HD_LUN 1051 -#define IDC_CHECKBUGGER 1052 -#define IDC_CHECKSERIAL1 1053 -#define IDC_CHECKPARALLEL 1054 -#define IDC_CHECKSERIAL2 1055 -#define IDC_COMBO_HDC 1068 -#define IDC_COMBO_MOUSE 1069 -#define IDC_COMBO_IDE_TER 1069 -#define IDC_COMBO_IDE_QUA 1070 -#define IDC_COMBO_FD_TYPE 1071 -#define IDC_COMBO_CD_BUS 1072 -#define IDC_COMBO_CD_CHANNEL_IDE 1073 -#define IDC_COMBO_CD_ID 1074 -#define IDC_COMBO_CD_LUN 1075 -#define IDC_COMBO_MIDI 1076 -#define IDC_CHECK_CDROM_1_AUDIO_ENABLED 1584 -#define IDC_CHECK_CDROM_2_AUDIO_ENABLED 1585 -#define IDC_CHECK_CDROM_3_AUDIO_ENABLED 1586 -#define IDC_CHECK_CDROM_4_AUDIO_ENABLED 1587 -#define IDS_STRING2049 2049 -#define IDS_STRING2050 2050 -#define IDS_STRING2051 2051 -#define IDS_STRING2052 2052 -#define IDS_STRING2053 2053 -#define IDS_STRING2054 2054 -#define IDS_STRING2055 2055 -#define IDS_STRING2056 2056 -#define IDS_STRING2057 2057 -#define IDS_STRING2058 2058 -#define IDS_STRING2059 2059 -#define IDS_STRING2060 2060 -#define IDS_STRING2061 2061 -#define IDS_STRING2062 2062 -#define IDS_STRING2063 2063 -#define IDS_STRING2064 2064 -#define IDS_STRING2065 2065 -#define IDS_STRING2066 2066 -#define IDS_STRING2067 2067 -#define IDS_STRING2068 2068 -#define IDS_STRING2069 2069 -#define IDS_STRING2070 2070 -#define IDS_STRING2071 2071 -#define IDS_STRING2072 2072 -#define IDS_STRING2073 2073 -#define IDS_STRING2074 2074 -#define IDS_STRING2075 2075 -#define IDS_STRING2076 2076 -#define IDS_STRING2077 2077 -#define IDS_STRING2078 2078 -#define IDS_STRING2079 2079 -#define IDM_ABOUT 40001 -#define IDC_ABOUT_ICON 65535 - -#define IDM_DISC_1 40000 -#define IDM_DISC_2 40001 -#define IDM_DISC_3 40002 -#define IDM_DISC_4 40003 -#define IDM_DISC_1_WP 40004 -#define IDM_DISC_2_WP 40005 -#define IDM_DISC_3_WP 40006 -#define IDM_DISC_4_WP 40007 -#define IDM_EJECT_1 40008 -#define IDM_EJECT_2 40009 -#define IDM_EJECT_3 40010 -#define IDM_EJECT_4 40011 - -#define IDM_FILE_RESET 40015 -#define IDM_FILE_HRESET 40016 -#define IDM_FILE_EXIT 40017 -#define IDM_FILE_RESET_CAD 40018 -#define IDM_HDCONF 40019 -#define IDM_CONFIG 40020 -#define IDM_CONFIG_LOAD 40021 -#define IDM_CONFIG_SAVE 40022 -#define IDM_USE_NUKEDOPL 40023 -#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_FLASH 40077 -#define IDM_VID_SCREENSHOT 40078 -#define IDM_VID_INVERT 40079 - -#define IDM_CDROM_1_MUTE 40128 -#define IDM_CDROM_1_IMAGE 40144 -#define IDM_CDROM_1_RELOAD 40160 -#define IDM_CDROM_1_EMPTY 40176 -#define IDM_CDROM_1_REAL 40192 -#define IDM_CDROM_2_MUTE 40129 -#define IDM_CDROM_2_IMAGE 40145 -#define IDM_CDROM_2_RELOAD 40161 -#define IDM_CDROM_2_EMPTY 40177 -#define IDM_CDROM_2_REAL 40193 -#define IDM_CDROM_3_MUTE 40130 -#define IDM_CDROM_3_IMAGE 40146 -#define IDM_CDROM_3_RELOAD 40162 -#define IDM_CDROM_3_EMPTY 40178 -#define IDM_CDROM_3_REAL 40194 -#define IDM_CDROM_4_MUTE 40131 -#define IDM_CDROM_4_IMAGE 40147 -#define IDM_CDROM_4_RELOAD 40163 -#define IDM_CDROM_4_EMPTY 40179 -#define IDM_CDROM_4_REAL 40195 - -#define IDM_IDE_TER_ENABLED 44000 -#define IDM_IDE_TER_IRQ9 44009 -#define IDM_IDE_TER_IRQ10 44010 -#define IDM_IDE_TER_IRQ11 44011 -#define IDM_IDE_TER_IRQ12 44012 -#define IDM_IDE_TER_IRQ14 44014 -#define IDM_IDE_TER_IRQ15 44015 -#define IDM_IDE_QUA_ENABLED 44020 -#define IDM_IDE_QUA_IRQ9 44029 -#define IDM_IDE_QUA_IRQ10 44030 -#define IDM_IDE_QUA_IRQ11 44031 -#define IDM_IDE_QUA_IRQ12 44032 -#define IDM_IDE_QUA_IRQ14 44033 -#define IDM_IDE_QUA_IRQ15 44035 - -#ifdef ENABLE_LOG_TOGGLES -# ifdef ENABLE_BUSLOGIC_LOG -# define IDM_LOG_BUSLOGIC 51200 -# endif -# ifdef ENABLE_CDROM_LOG -# define IDM_LOG_CDROM 51201 -# endif -# ifdef ENABLE_D86F_LOG -# define IDM_LOG_D86F 51202 -# endif -# ifdef ENABLE_FDC_LOG -# define IDM_LOG_FDC 51203 -# endif -# ifdef ENABLE_IDE_LOG -# define IDM_LOG_IDE 51204 -# endif -# ifdef ENABLE_NE2000_LOG -# define IDM_LOG_NE2000 51205 -# endif -#endif -#ifdef ENABLE_LOG_BREAKPOINT -# define IDM_LOG_BREAKPOINT 51206 -#endif -#ifdef ENABLE_VRAM_DUMP -# define IDM_DUMP_VRAM 51207 -#endif - -#define IDC_COMBO1 1000 -#define IDC_COMBOVID 1001 -#define IDC_COMBO3 1002 -#define IDC_COMBO4 1003 -#define IDC_COMBO5 1004 -#define IDC_COMBO386 1005 -#define IDC_COMBO486 1006 -#define IDC_COMBOSND 1007 -#define IDC_COMBONETTYPE 1008 -#define IDC_COMBOPCAP 1009 -#define IDC_COMBONET 1010 -#define IDC_COMBOCPUM 1060 -#define IDC_COMBOSPD 1061 -#define IDC_COMBODR1 1062 -#define IDC_COMBODR2 1063 -#define IDC_COMBODR3 1064 -#define IDC_COMBODR4 1065 -#define IDC_COMBOJOY 1066 -#define IDC_COMBOWS 1067 -#define IDC_COMBOMOUSE 1068 -#define IDC_COMBOHDD 1069 -#define IDC_CHECK1 1010 -#define IDC_CHECK2 1011 -#define IDC_CHECK3 1012 -#define IDC_CHECKSSI 1014 -#define IDC_CHECKVOODOO 1015 -#define IDC_CHECKDYNAREC 1016 -#define IDC_CHECKBUSLOGIC 1017 -#define IDC_CHECKSYNC 1024 -#define IDC_CHECKXTIDE 1025 -#define IDC_CHECKFPU 1026 -#define IDC_EDIT1 1030 -#define IDC_EDIT2 1031 -#define IDC_EDIT3 1032 -#define IDC_EDIT4 1033 -#define IDC_EDIT5 1034 -#define IDC_EDIT6 1035 -#define IDC_COMBOHDT 1036 - -#define IDC_EJECTC 1040 -#define IDC_EDITC 1050 -#define IDC_CFILE 1060 -#define IDC_CNEW 1070 -#define IDC_EDIT_C_SPT 1200 -#define IDC_EDIT_C_HPC 1210 -#define IDC_EDIT_C_CYL 1220 -#define IDC_EDIT_C_FN 1230 -#define IDC_TEXT_C_SIZE 1240 - -#define IDC_EJECTD 1041 -#define IDC_EDITD 1051 -#define IDC_DFILE 1061 -#define IDC_DNEW 1071 -#define IDC_EDIT_D_SPT 1201 -#define IDC_EDIT_D_HPC 1211 -#define IDC_EDIT_D_CYL 1221 -#define IDC_EDIT_D_FN 1231 -#define IDC_TEXT_D_SIZE 1241 - -#define IDC_EJECTE 1042 -#define IDC_EDITE 1052 -#define IDC_EFILE 1062 -#define IDC_ENEW 1072 -#define IDC_EDIT_E_SPT 1202 -#define IDC_EDIT_E_HPC 1212 -#define IDC_EDIT_E_CYL 1222 -#define IDC_EDIT_E_FN 1232 -#define IDC_TEXT_E_SIZE 1242 - -#define IDC_EJECTF 1043 -#define IDC_EDITF 1053 -#define IDC_FFILE 1063 -#define IDC_FNEW 1073 -#define IDC_EDIT_F_SPT 1203 -#define IDC_EDIT_F_HPC 1213 -#define IDC_EDIT_F_CYL 1223 -#define IDC_EDIT_F_FN 1233 -#define IDC_TEXT_F_SIZE 1243 - -#define IDC_EJECTG 1044 -#define IDC_EDITG 1054 -#define IDC_GFILE 1064 -#define IDC_GNEW 1074 -#define IDC_EDIT_G_SPT 1204 -#define IDC_EDIT_G_HPC 1214 -#define IDC_EDIT_G_CYL 1224 -#define IDC_EDIT_G_FN 1234 -#define IDC_TEXT_G_SIZE 1244 - -#define IDC_EJECTH 1045 -#define IDC_EDITH 1055 -#define IDC_HFILE 1065 -#define IDC_HNEW 1075 -#define IDC_EDIT_H_SPT 1205 -#define IDC_EDIT_H_HPC 1215 -#define IDC_EDIT_H_CYL 1225 -#define IDC_EDIT_H_FN 1235 -#define IDC_TEXT_H_SIZE 1245 - -#define IDC_EJECTI 1046 -#define IDC_EDITI 1056 -#define IDC_IFILE 1066 -#define IDC_INEW 1076 -#define IDC_EDIT_I_SPT 1206 -#define IDC_EDIT_I_HPC 1216 -#define IDC_EDIT_I_CYL 1226 -#define IDC_EDIT_I_FN 1236 -#define IDC_TEXT_I_SIZE 1246 - -#define IDC_EJECTJ 1047 -#define IDC_EDITJ 1057 -#define IDC_JFILE 1067 -#define IDC_JNEW 1077 -#define IDC_EDIT_J_SPT 1207 -#define IDC_EDIT_J_HPC 1217 -#define IDC_EDIT_J_CYL 1227 -#define IDC_EDIT_J_FN 1237 -#define IDC_TEXT_J_SIZE 1247 - -#define IDC_HDTYPE 1280 - -#define IDC_RENDER 1281 -#define IDC_STATUS 1282 - -#define IDC_MEMSPIN 1100 -#define IDC_MEMTEXT 1101 -#define IDC_STEXT1 1102 -#define IDC_STEXT2 1103 -#define IDC_STEXT3 1104 -#define IDC_STEXT4 1105 -#define IDC_STEXT5 1106 -#define IDC_STEXT6 1107 -#define IDC_STEXT7 1108 -#define IDC_STEXT8 1109 -#define IDC_STEXT_DEVICE 1110 -#define IDC_TEXT_MB 1111 -#define IDC_TEXT1 1115 -#define IDC_TEXT2 1116 - -#define IDC_CONFIGUREVID 1200 -#define IDC_CONFIGURESND 1201 -#define IDC_CONFIGUREVOODOO 1202 -#define IDC_CONFIGUREMOD 1203 -#define IDC_CONFIGURENETTYPE 1204 -#define IDC_CONFIGUREBUSLOGIC 1205 -#define IDC_CONFIGUREPCAP 1206 -#define IDC_CONFIGURENET 1207 -#define IDC_JOY1 1210 -#define IDC_JOY2 1211 -#define IDC_JOY3 1212 -#define IDC_JOY4 1213 - -#define IDC_CONFIG_BASE 1200 - -#define WM_RESETD3D WM_USER -#define WM_LEAVEFULLSCREEN WM_USER + 1 - -#define C_BASE 6 -#define D_BASE 44 -#define E_BASE 82 -#define F_BASE 120 -#define G_BASE 158 -#define H_BASE 196 -#define I_BASE 234 -#define J_BASE 272 -#define CMD_BASE 314 -#define DLG_HEIGHT 346 - -#define IDC_CHECK_CDROM_1_ENABLED 1536 -#define IDC_COMBO_CDROM_1_BUS 1544 -#define IDC_COMBO_CDROM_1_CHANNEL 1552 -#define IDC_CHECK_CDROM_1_DMA_ENABLED 1560 -#define IDC_COMBO_CDROM_1_SCSI_ID 1568 -#define IDC_COMBO_CDROM_1_SCSI_LUN 1576 - -#define IDC_CHECK_CDROM_2_ENABLED 1537 -#define IDC_COMBO_CDROM_2_BUS 1545 -#define IDC_COMBO_CDROM_2_CHANNEL 1553 -#define IDC_CHECK_CDROM_2_DMA_ENABLED 1561 -#define IDC_COMBO_CDROM_2_SCSI_ID 1569 -#define IDC_COMBO_CDROM_2_SCSI_LUN 1577 - -#define IDC_CHECK_CDROM_3_ENABLED 1538 -#define IDC_COMBO_CDROM_3_BUS 1546 -#define IDC_COMBO_CDROM_3_CHANNEL 1554 -#define IDC_CHECK_CDROM_3_DMA_ENABLED 1562 -#define IDC_COMBO_CDROM_3_SCSI_ID 1570 -#define IDC_COMBO_CDROM_3_SCSI_LUN 1578 - -#define IDC_CHECK_CDROM_4_ENABLED 1539 -#define IDC_COMBO_CDROM_4_BUS 1547 -#define IDC_COMBO_CDROM_4_CHANNEL 1555 -#define IDC_CHECK_CDROM_4_DMA_ENABLED 1563 -#define IDC_COMBO_CDROM_4_SCSI_ID 1571 -#define IDC_COMBO_CDROM_4_SCSI_LUN 1579 - -#define IDC_STATIC 1792 - -/* Next default values for new objects */ -#ifdef APSTUDIO_INVOKED -# ifndef APSTUDIO_READONLY_SYMBOLS -# define _APS_NO_MFC 1 -# define _APS_NEXT_RESOURCE_VALUE 111 -# define _APS_NEXT_COMMAND_VALUE 40002 -# define _APS_NEXT_CONTROL_VALUE 1055 -# define _APS_NEXT_SYMED_VALUE 101 -# endif -#endif diff --git a/src/serial.c b/src/serial.c index a2b896321..ae376960a 100644 --- a/src/serial.c +++ b/src/serial.c @@ -33,7 +33,7 @@ * * Based on the 86Box serial port driver as a framework. * - * Version: @(#)serial.c 1.0.5 2017/05/07 + * Version: @(#)serial.c 1.0.5 2017/05/17 * * Author: Fred N. van Kempen, * Copyright 2017 Fred N. van Kempen. @@ -43,7 +43,7 @@ #include "pic.h" #include "timer.h" #include "serial.h" -#include "plat-serial.h" +#include "plat_serial.h" enum { diff --git a/src/win-cgapal.h b/src/win-cgapal.h deleted file mode 100644 index d6ac7ffd8..000000000 --- a/src/win-cgapal.h +++ /dev/null @@ -1,13 +0,0 @@ -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 diff --git a/src/win-crashdump.c b/src/win-crashdump.c deleted file mode 100644 index b640c61ae..000000000 --- a/src/win-crashdump.c +++ /dev/null @@ -1,185 +0,0 @@ -/* 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 -#include -#include -#include -#include -#include "86box.h" -#include "win-crashdump.h" - -PVOID hExceptionHandler; -char* ExceptionHandlerBuffer; -#define ExceptionHandlerBufferSize (10240) - - -LONG CALLBACK MakeCrashDump(PEXCEPTION_POINTERS ExceptionInfo) { - // 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) { - // The exception code is not a fatal exception (highest 4 bits 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 86Box.exe. - char* CurrentBufferPointer; - GetModuleFileName(NULL,ExceptionHandlerBuffer,ExceptionHandlerBufferSize); - if (GetLastError() != ERROR_SUCCESS) { - // Could not get the full path of 86Box.exe. Just create the file in the current directory. - CurrentBufferPointer = ExceptionHandlerBuffer; - } else { - // Walk through the string backwards looking for the last backslash, so as to remove the "86Box.exe" filename from the string. - CurrentBufferPointer = &ExceptionHandlerBuffer[strlen(ExceptionHandlerBuffer)]; - for (; CurrentBufferPointer > ExceptionHandlerBuffer; CurrentBufferPointer--) { - if (CurrentBufferPointer[0] == '\\') { - // Found the backslash, null terminate the string after it. - CurrentBufferPointer[1] = 0; - break; - } - } - - CurrentBufferPointer = &ExceptionHandlerBuffer[strlen(ExceptionHandlerBuffer)]; - } - - // What would a good filename be? It should contain the current date and time so as to be (hopefully!) unique. - SYSTEMTIME SystemTime; - 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); - - DWORD Error; - - // Now the filename is in the buffer, the file can be created. - HANDLE 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. - CurrentBufferPointer = &ExceptionHandlerBuffer[strlen(ExceptionHandlerBuffer)]; - if (ipModule != 0) { - sprintf(CurrentBufferPointer," ["); - GetModuleFileName(ipModule,&CurrentBufferPointer[2],ExceptionHandlerBufferSize - strlen(ExceptionHandlerBuffer)); - if (GetLastError() == ERROR_SUCCESS) { - CurrentBufferPointer = &ExceptionHandlerBuffer[strlen(ExceptionHandlerBuffer)]; - sprintf(CurrentBufferPointer,"]"); - CurrentBufferPointer += 1; - } - } - - // Continue to create the crash-dump string. - sprintf(CurrentBufferPointer, - "\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++) { - CurrentBufferPointer = &ExceptionHandlerBuffer[strlen(ExceptionHandlerBuffer)]; - sprintf(CurrentBufferPointer,"0x%p ",ExceptionInfo->ExceptionRecord->ExceptionInformation[i]); - } - - CurrentBufferPointer = &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(CurrentBufferPointer, - "\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(CurrentBufferPointer,"\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() { - // 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); -} \ No newline at end of file diff --git a/src/win-crashdump.h b/src/win-crashdump.h deleted file mode 100644 index 8048cd7af..000000000 --- a/src/win-crashdump.h +++ /dev/null @@ -1,7 +0,0 @@ -/* Copyright holders: Riley - see COPYING for more details - - win-crashdump.c : Windows crash dump exception handler header file. -*/ - -void InitCrashDump(); \ No newline at end of file diff --git a/src/win-d3d-fs.cc b/src/win-d3d-fs.cc deleted file mode 100644 index dff2e0d6f..000000000 --- a/src/win-d3d-fs.cc +++ /dev/null @@ -1,587 +0,0 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ -#include -#include -#define UNICODE -#define BITMAP WINDOWS_BITMAP -#include -#undef BITMAP -#include -#include "86box.h" -#include "video/video.h" -#include "win-d3d-fs.h" -#include "win.h" -#include "win-cgapal.h" -#include "resource.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 - 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},{0x0b,0x0c,0x0a},{0x12,0x14,0x10},{0x15,0x17,0x13},{0x21,0x24,0x1e},{0x23,0x26,0x21},{0x30,0x31,0x2e},{0x34,0x35,0x33}, - {0x07,0x08,0x07},{0x0e,0x0f,0x0d},{0x19,0x1b,0x16},{0x1c,0x1f,0x1a},{0x28,0x2b,0x26},{0x2b,0x2d,0x2a},{0x37,0x38,0x37},{0x3d,0x3d,0x3c}, - }, - { // 5 - grey, 16-color-optimized contrast - {0x00,0x00,0x00},{0x0b,0x0c,0x0a},{0x0f,0x11,0x0e},{0x12,0x14,0x10},{0x1b,0x1d,0x18},{0x1c,0x1f,0x1a},{0x25,0x28,0x23},{0x28,0x2b,0x26}, - {0x1c,0x1e,0x19},{0x20,0x23,0x1d},{0x27,0x2a,0x25},{0x29,0x2c,0x27},{0x31,0x32,0x30},{0x33,0x34,0x32},{0x3a,0x3b,0x3a},{0x3d,0x3d,0x3c}, - }, -}; - -uint32_t pal_lookup[256]; - -static CUSTOMVERTEX d3d_verts[] = -{ - { 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f}, - {2048.0f, 2048.0f, 1.0f, 1.0f, 1.0f, 1.0f}, - { 0.0f, 2048.0f, 1.0f, 1.0f, 0.0f, 1.0f}, - - { 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f}, - {2048.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f}, - {2048.0f, 2048.0f, 1.0f, 1.0f, 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)) - { - 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) -{ - HRESULT hr; - WCHAR emulator_title[200]; - - d3d_fs_w = GetSystemMetrics(SM_CXSCREEN); - d3d_fs_h = GetSystemMetrics(SM_CYSCREEN); - - cgapal_rebuild(); - - d3d_hwnd = h; - - _swprintf(emulator_title, L"86Box v%s", emulator_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); - if (d3d == NULL) - { - return 0; - } - - 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 = d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, h, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3ddev); - if (FAILED(hr)) - { - return 0; - } - - 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(void) -{ - if (d3dTexture) - { - d3dTexture->Release(); - d3dTexture = NULL; - } - if (v_buffer) - { - v_buffer->Release(); - v_buffer = NULL; - } -} - -static void d3d_fs_init_objects(void) -{ - D3DLOCKED_RECT dr; - RECT r; - - d3ddev->CreateVertexBuffer(6*sizeof(CUSTOMVERTEX), - 0, - D3DFVF_XYZRHW | D3DFVF_TEX1, - D3DPOOL_MANAGED, - &v_buffer, - NULL); - - d3ddev->CreateTexture(2048, 2048, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &d3dTexture, NULL); - - // r.top = r.left = 0; - r.bottom = 2047; - 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 *)(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(void) -{ - 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(void) -{ - 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; - } - 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, t, r, b; - - if ((y1 == y2) || (d3dTexture == NULL)) - { - 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; - - if (FAILED(d3dTexture->LockRect(0, &dr, &lock_rect, 0))) - fatal("LockRect failed\n"); - - for (yy = y1; yy < y2; yy++) - memcpy((uint32_t *) &(((uint8_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(); - - 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; - - 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; - - 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_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; - uint32_t *p; - int xx, yy; - double l, t, r, b; - - if (!h || (d3dTexture == NULL)) - { - 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; - - if (FAILED(d3dTexture->LockRect(0, &dr, &lock_rect, 0))) - fatal("LockRect failed\n"); - - for (yy = 0; yy < h; yy++) - { - p = (uint32_t *) &(((uint8_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; - 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; - - 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; - - 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_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; -} diff --git a/src/win-d3d-fs.h b/src/win-d3d-fs.h deleted file mode 100644 index 41ca32e21..000000000 --- a/src/win-d3d-fs.h +++ /dev/null @@ -1,13 +0,0 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ -#ifdef __cplusplus -extern "C" { -#endif - int d3d_fs_init(HWND h); - void d3d_fs_close(); - void d3d_fs_reset(); - void d3d_fs_resize(int x, int y); -#ifdef __cplusplus -} -#endif diff --git a/src/win-d3d.cc b/src/win-d3d.cc deleted file mode 100644 index abfce0bfb..000000000 --- a/src/win-d3d.cc +++ /dev/null @@ -1,397 +0,0 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ -#include -#define UNICODE -#define BITMAP WINDOWS_BITMAP -#include -#undef BITMAP -#include -#include "resource.h" -#include "win-d3d.h" -#include "video/video.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 - FLOAT tu, tv; -}; - -static CUSTOMVERTEX d3d_verts[] = -{ - { 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f}, - {2048.0f, 2048.0f, 1.0f, 1.0f, 1.0f, 1.0f}, - { 0.0f, 2048.0f, 1.0f, 1.0f, 0.0f, 1.0f}, - - { 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f}, - {2048.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f}, - {2048.0f, 2048.0f, 1.0f, 1.0f, 1.0f, 1.0f}, -}; - -int d3d_init(HWND h) -{ - HRESULT hr; - - cgapal_rebuild(); - - d3d_hwnd = h; - - d3d = Direct3DCreate9(D3D_SDK_VERSION); - if (d3d == NULL) - { - return 0; - } - - 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; - - hr = d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, h, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3ddev); - if (FAILED(hr)) - { - return 0; - } - - 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(void) -{ - if (d3dTexture) - { - d3dTexture->Release(); - d3dTexture = NULL; - } - if (v_buffer) - { - v_buffer->Release(); - v_buffer = NULL; - } -} - -void d3d_init_objects(void) -{ - D3DLOCKED_RECT dr; - RECT r; - - d3ddev->CreateVertexBuffer(6*sizeof(CUSTOMVERTEX), - 0, - D3DFVF_XYZRHW | D3DFVF_TEX1, - D3DPOOL_MANAGED, - &v_buffer, - NULL); - - d3ddev->CreateTexture(2048, 2048, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &d3dTexture, NULL); - - // 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 *)(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(void) -{ - HRESULT hr; - - 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(void) -{ - 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 ((w <= 0) || (w > 2048) || (h <= 0) || (h > 2048) || (y1 == y2) || (y1 < 0) || (y1 > 2048) || (y2 < 0) || (y2 > 2048) || (d3dTexture == NULL)) - { - video_blit_complete(); - return; /*Nothing to do*/ - } - - r.top = y1; - r.left = 0; - r.bottom = y2; - r.right = 2047; - - if (hr == D3D_OK) - { - if (FAILED(d3dTexture->LockRect(0, &dr, &r, 0))) - fatal("LockRect failed\n"); - - for (yy = y1; yy < y2; yy++) - memcpy((uint32_t *) &(((uint8_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(); - - 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; - - 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; - - 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_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; - uint32_t *p; - int yy, xx; - HRESULT hr = D3D_OK; - - if ((w <= 0) || (w > 2048) || (h <= 0) || (h > 2048) || (d3dTexture == NULL)) - { - video_blit_complete(); - return; /*Nothing to do*/ - } - - r.top = 0; - r.left = 0; - r.bottom = h; - r.right = 2047; - - if (hr == D3D_OK) - { - if (FAILED(d3dTexture->LockRect(0, &dr, &r, 0))) - fatal("LockRect failed\n"); - - for (yy = 0; yy < h; yy++) - { - p = (uint32_t *) &((((uint8_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; - - 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; - - 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_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; -} diff --git a/src/win-d3d.h b/src/win-d3d.h deleted file mode 100644 index 7210d454b..000000000 --- a/src/win-d3d.h +++ /dev/null @@ -1,13 +0,0 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ -#ifdef __cplusplus -extern "C" { -#endif - int d3d_init(HWND h); - void d3d_close(); - void d3d_reset(); - void d3d_resize(int x, int y); -#ifdef __cplusplus -} -#endif diff --git a/src/win-ddraw-fs.cc b/src/win-ddraw-fs.cc deleted file mode 100644 index 9fc355c63..000000000 --- a/src/win-ddraw-fs.cc +++ /dev/null @@ -1,338 +0,0 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ -#include -#define UNICODE -#define BITMAP WINDOWS_BITMAP -#include -#undef BITMAP -#include "win-ddraw-fs.h" -#include "win-ddraw-screenshot.h" -#include "video/video.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_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 x, int y, int y1, int y2, int w, int h); -static void ddraw_fs_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; -static int ddraw_w, ddraw_h; - -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))) - 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); - } - - if (readflash && enable_flash) - { - RECT r; - r.left = window_rect.right - 40; - r.right = window_rect.right - 8; - r.top = 8; - r.bottom = 14; - ddbltfx.dwFillColor = 0xffffff; - lpdds_back2->Blt(&r, NULL, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &ddbltfx); - } - - 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); - } - - if (readflash && enable_flash) - { - RECT r; - r.left = window_rect.right - 40; - r.right = window_rect.right - 8; - r.top = 8; - r.bottom = 14; - ddbltfx.dwFillColor = 0xffffff; - lpdds_back2->Blt(&r, NULL, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &ddbltfx); - } - - lpdds_pri->Flip(NULL, DDFLIP_NOVSYNC); -} - -void ddraw_fs_take_screenshot(wchar_t *fn) -{ - ddraw_common_take_screenshot(fn, lpdds_back2); -} diff --git a/src/win-ddraw-fs.h b/src/win-ddraw-fs.h deleted file mode 100644 index 048c9c160..000000000 --- a/src/win-ddraw-fs.h +++ /dev/null @@ -1,11 +0,0 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ -#ifdef __cplusplus -extern "C" { -#endif - int ddraw_fs_init(HWND h); - void ddraw_fs_close(); -#ifdef __cplusplus -} -#endif diff --git a/src/win-ddraw-screenshot.cc b/src/win-ddraw-screenshot.cc deleted file mode 100644 index e8a891fe9..000000000 --- a/src/win-ddraw-screenshot.cc +++ /dev/null @@ -1,178 +0,0 @@ -/* Copyright holders: Tenshi - see COPYING for more details -*/ -#include -#include -#define UNICODE -#define BITMAP WINDOWS_BITMAP -#include -#undef BITMAP -#include "win.h" -#include "win-ddraw-screenshot.h" -#include "win-language.h" -#include "video/video.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 ddraw_init(HWND h); -extern "C" void ddraw_close(void); - -HBITMAP hbitmap; - -int xs, ys, ys2; - -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(2194), 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); -} diff --git a/src/win-ddraw-screenshot.h b/src/win-ddraw-screenshot.h deleted file mode 100644 index 4739174a1..000000000 --- a/src/win-ddraw-screenshot.h +++ /dev/null @@ -1,4 +0,0 @@ -/* Copyright holders: Tenshi - see COPYING for more details -*/ -void ddraw_common_take_screenshot(wchar_t *fn, IDirectDrawSurface7 *pDDSurface); diff --git a/src/win-ddraw.cc b/src/win-ddraw.cc deleted file mode 100644 index 509124205..000000000 --- a/src/win-ddraw.cc +++ /dev/null @@ -1,318 +0,0 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ -#include -#include -#define UNICODE -#define BITMAP WINDOWS_BITMAP -#include -#undef BITMAP -#include "win-ddraw.h" -#include "win-ddraw-screenshot.h" -#include "video/video.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))) - 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_back2, NULL))) - return 0; - - 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 xx, yy; - POINT po; - uint32_t *p; - 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*/ - } - - 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); - } - - if (readflash) - { - readflash = 0; -#ifdef LEGACY_READ_FLASH - if (enable_flash) - { - hr = lpdds_back2->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); - if (hr == DDERR_SURFACELOST) - { - lpdds_back2->Restore(); - lpdds_back2->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); - device_force_redraw(); - } - if (!ddsd.lpSurface) return; - for (yy = 8; yy < 14; yy++) - { - p = &(((uint32_t *) ddsd.lpSurface)[yy * ddsd.lPitch]); - for (xx = (w - 40); xx < (w - 8); xx++) - p[xx] = 0xffffffff; - } - } -#endif - } - 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); - } - - if (readflash) - { - readflash = 0; - if (enable_flash) - { - hr = lpdds_back2->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); - if (hr == DDERR_SURFACELOST) - { - lpdds_back2->Restore(); - lpdds_back2->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); - device_force_redraw(); - } - if (!ddsd.lpSurface) return; - for (yy = 8; yy < 14; yy++) - { - p = (uint32_t *) &(((uint8_t *) ddsd.lpSurface)[yy * ddsd.lPitch]); - for (xx = (w - 40); xx < (w - 8); xx++) - p[xx] = 0xffffffff; - } - lpdds_back2->Unlock(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); -} diff --git a/src/win-ddraw.h b/src/win-ddraw.h deleted file mode 100644 index a4044899d..000000000 --- a/src/win-ddraw.h +++ /dev/null @@ -1,12 +0,0 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ -#ifdef __cplusplus -extern "C" { -#endif - int ddraw_init(HWND h); - void ddraw_close(); -#ifdef __cplusplus -} -#endif - diff --git a/src/win-deviceconfig.c b/src/win-deviceconfig.c deleted file mode 100644 index 196845359..000000000 --- a/src/win-deviceconfig.c +++ /dev/null @@ -1,317 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -#define BITMAP WINDOWS_BITMAP -#include -#include -#undef BITMAP - -#include "ibm.h" -#include "config.h" -#include "device.h" -#include "resource.h" -#include "win.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 num; - char s[80]; - - switch (message) - { - case WM_INITDIALOG: - { - int id = IDC_CONFIG_BASE; - device_config_t *config = config_device->config; - int c; - - while (config->type != -1) - { - device_config_selection_t *selection = config->selection; - 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; - } - config++; - } - } - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) - { - case IDOK: - { - int id = IDC_CONFIG_BASE; - device_config_t *config = config_device->config; - int c; - int changed = 0; - - while (config->type != -1) - { - device_config_selection_t *selection = config->selection; - 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; - } - config++; - } - - if (!changed) - { - EndDialog(hdlg, 0); - return TRUE; - } - - if (MessageBox(NULL, "This will reset 86Box!\nOkay to continue?", "86Box", MB_OKCANCEL) != IDOK) - { - EndDialog(hdlg, 0); - return TRUE; - } - - id = IDC_CONFIG_BASE; - config = config_device->config; - - while (config->type != -1) - { - device_config_selection_t *selection = config->selection; - 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; - } - config++; - } - - saveconfig(); - - resetpchard(); - - EndDialog(hdlg, 0); - return TRUE; - } - case IDCANCEL: - EndDialog(hdlg, 0); - return TRUE; - } - break; - } - return FALSE; -} - -void deviceconfig_open(HWND hwnd, device_t *device) -{ - device_config_t *config = device->config; - uint16_t *data_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++ = 8; /*Point*/ - data += MultiByteToWideChar(CP_ACP, 0, "MS Sans Serif", -1, data, 50); - - if (((unsigned long)data) & 2) - data++; - - while (config->type != -1) - { - switch (config->type) - { - case CONFIG_BINARY: - item = (DLGITEMTEMPLATE *)data; - item->x = 10; - item->y = y; - item->id = id++; - - item->cx = 80; - item->cy = 15; - - item->style = WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX; - - data = (uint16_t *)(item + 1); - *data++ = 0xFFFF; - *data++ = 0x0080; /* button class */ - - data += MultiByteToWideChar(CP_ACP, 0, config->description, -1, data, 256); - *data++ = 0; /* no creation data */ - - y += 20; - break; - - case CONFIG_SELECTION: - /*Combo box*/ - item = (DLGITEMTEMPLATE *)data; - item->x = 70; - item->y = y; - item->id = id++; - - item->cx = 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; - } - - 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); -} diff --git a/src/win-joystick.cc b/src/win-joystick.cc deleted file mode 100644 index 13cc3c1ff..000000000 --- a/src/win-joystick.cc +++ /dev/null @@ -1,281 +0,0 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ -#define DIRECTINPUT_VERSION 0x0800 -#include -#include -#include -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; - } - } -} - diff --git a/src/win-joystickconfig.c b/src/win-joystickconfig.c deleted file mode 100644 index 1432379ff..000000000 --- a/src/win-joystickconfig.c +++ /dev/null @@ -1,541 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -#define BITMAP WINDOWS_BITMAP -#include -#include -#undef BITMAP - -#include "ibm.h" -#include "config.h" -#include "device.h" -#include "gameport.h" -#include "plat-joystick.h" -#include "resource.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); -} diff --git a/src/win-language.c b/src/win-language.c deleted file mode 100644 index c2525db48..000000000 --- a/src/win-language.c +++ /dev/null @@ -1,197 +0,0 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ -#include -#define UNICODE -#define BITMAP WINDOWS_BITMAP -#include -#include -#undef BITMAP - -#include - -#include "ibm.h" -#include "device.h" -#include "ide.h" -#include "resource.h" -#include "win.h" -#include "win-language.h" - -LCID dwLanguage; - -uint32_t dwLangID, dwSubLangID; - -#define STRINGS_NUM 154 - -WCHAR lpResourceString[STRINGS_NUM][512]; - -char openfilestring[260]; -WCHAR wopenfilestring[260]; - -void win_language_set() -{ - SetThreadLocale(dwLanguage); -} - -void win_language_load_common_strings() -{ - int i = 0; - - for (i = 0; i < STRINGS_NUM; i++) - { - LoadString(hinstance, 2048 + i, lpResourceString[i], 512); - } -} - -LPTSTR win_language_get_settings_category(int i) -{ - return lpResourceString[17 + i]; -} - -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) -{ - return lpResourceString[i - 2048]; -} - -LPTSTR win_language_get_string_from_string(char *str) -{ - return lpResourceString[atoi(str) - 2048]; -} - -int msgbox_reset(HWND hwndParent) -{ - return MessageBox(hwndParent, lpResourceString[3], lpResourceString[0], MB_YESNOCANCEL | MB_ICONQUESTION); -} - -int msgbox_reset_yn(HWND hwndParent) -{ - return MessageBox(hwndParent, lpResourceString[3], lpResourceString[0], MB_YESNO | MB_ICONQUESTION); -} - -int msgbox_question(HWND hwndParent, int i) -{ - return MessageBox(hwndParent, win_language_get_string_from_id(i), lpResourceString[0], MB_YESNO | MB_ICONQUESTION); -} - -void msgbox_info(HWND hwndParent, int i) -{ - MessageBox(hwndParent, win_language_get_string_from_id(i), lpResourceString[0], MB_OK | MB_ICONINFORMATION); -} - -void msgbox_info_wstr(HWND hwndParent, WCHAR *wstr) -{ - MessageBox(hwndParent, wstr, lpResourceString[0], MB_OK | MB_ICONINFORMATION); -} - -void msgbox_error(HWND hwndParent, int i) -{ - MessageBox(hwndParent, win_language_get_string_from_id(i), lpResourceString[1], MB_OK | MB_ICONWARNING); -} - -void msgbox_error_wstr(HWND hwndParent, WCHAR *wstr) -{ - MessageBox(hwndParent, wstr, lpResourceString[1], MB_OK | MB_ICONWARNING); -} - -void msgbox_critical(HWND hwndParent, int i) -{ - MessageBox(hwndParent, win_language_get_string_from_id(i), lpResourceString[2], 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, lpResourceString[2], MB_OK | MB_ICONERROR); - - free(lptsTemp); -} - -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, 520); - 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_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); -} diff --git a/src/win-language.h b/src/win-language.h deleted file mode 100644 index 5c4237249..000000000 --- a/src/win-language.h +++ /dev/null @@ -1,33 +0,0 @@ -#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_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); - -#ifdef __cplusplus -} -#endif diff --git a/src/win-midi.c b/src/win-midi.c deleted file mode 100644 index a11c7bfea..000000000 --- a/src/win-midi.c +++ /dev/null @@ -1,279 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -#include -#include -#include "ibm.h" -#include "config.h" -#include "plat-midi.h" - -int midi_id; -static HMIDIOUT midi_out_device = NULL; - -HANDLE m_event; - -void midi_close(); - -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; - -uint8_t MIDI_evt_len[256] = { - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x00 - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x10 - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x20 - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x30 - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x40 - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x50 - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x60 - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x70 - - 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0x80 - 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0x90 - 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0xa0 - 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0xb0 - - 2,2,2,2, 2,2,2,2, 2,2,2,2, 2,2,2,2, // 0xc0 - 2,2,2,2, 2,2,2,2, 2,2,2,2, 2,2,2,2, // 0xd0 - - 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0xe0 - - 0,2,3,2, 0,0,1,0, 1,0,1,1, 1,0,1,0 // 0xf0 -}; - -void midi_init() -{ - MMRESULT hr = MMSYSERR_NOERROR; - - memset(midi_rt_buf, 0, 1024); - memset(midi_cmd_buf, 0, 1024); - - midi_cmd_pos = midi_cmd_len = 0; - midi_status = 0; - - midi_sysex_start = midi_sysex_delay = 0; - - midi_id = config_get_int(NULL, "midi", 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 midi_close() -{ - if (midi_out_device != NULL) - { - midiOutReset(midi_out_device); - midiOutClose(midi_out_device); - midi_out_device = NULL; - CloseHandle(m_event); - } -} - -int midi_get_num_devs() -{ - return midiOutGetNumDevs(); -} -void midi_get_dev_name(int num, char *s) -{ - MIDIOUTCAPS caps; - - midiOutGetDevCaps(num, &caps, sizeof(caps)); - strcpy(s, caps.szPname); -} - -static int midi_pos, midi_len; -static uint32_t midi_command; -static int midi_lengths[8] = {3, 3, 3, 3, 2, 2, 3, 1}; -static int midi_insysex; -static char midi_sysex_data[1024+2]; - -static void midi_send_sysex() -{ - MIDIHDR hdr; - - hdr.lpData = midi_sysex_data; - hdr.dwBufferLength = midi_pos; - hdr.dwFlags = 0; - - midiOutPrepareHeader(midi_out_device, &hdr, sizeof(MIDIHDR)); - midiOutLongMsg(midi_out_device, &hdr, sizeof(MIDIHDR)); - - midi_insysex = 0; -} - -void PlayMsg(uint8_t *msg) -{ - midiOutShortMsg(midi_out_device, *(uint32_t *) msg); -} - -MIDIHDR m_hdr; - -void PlaySysex(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; - } -} - -#define SYSEX_SIZE 1024 -#define RAWBUF 1024 - -void midi_write(uint8_t val) -{ - uint32_t passed_ticks; - - if (midi_sysex_start) - { - passed_ticks = GetTickCount() - midi_sysex_start; - if (passed_ticks < midi_sysex_delay) - { - Sleep(midi_sysex_delay - passed_ticks); - } - } - - /* Test for a realtime MIDI message */ - if (val >= 0xf8) - { - midi_rt_buf[0] = val; - PlayMsg(midi_rt_buf); - return; - } - - /* Test for a active sysex transfer */ - - if (midi_status == 0xf0) - { - if (!(val & 0x80)) - { - if (midi_pos < (SYSEX_SIZE-1)) midi_sysex_data[midi_pos++] = val; - return; - } - else - { - midi_sysex_data[midi_pos++] = 0xf7; - - if ((midi_sysex_start) && (midi_pos >= 4) && (midi_pos <= 9) && (midi_sysex_data[1] == 0x411) && (midi_sysex_data[3] == 0x16)) - { - /* pclog("MIDI: Skipping invalid MT-32 SysEx MIDI message\n"); */ - } - else - { - PlaySysex(midi_sysex_data, midi_pos); - if (midi_sysex_start) - { - if (midi_sysex_data[5] == 0x7f) - { - midi_sysex_delay = 290; /* All parameters reset */ - } - else if ((midi_sysex_data[5] == 0x10) && (midi_sysex_data[6] == 0x00) && (midi_sysex_data[7] == 0x04)) - { - midi_sysex_delay = 145; /* Viking Child */ - } - else if ((midi_sysex_data[5] == 0x10) && (midi_sysex_data[6] == 0x00) && (midi_sysex_data[7] == 0x01)) - { - midi_sysex_delay = 30; /* Dark Sun 1 */ - } - else - midi_sysex_delay = (unsigned int) (((float) (midi_pos) * 1.25f) * 1000.0f / 3125.0f) + 2; - - midi_sysex_start = GetTickCount(); - } - } - } - } - - - if (val & 0x80) - { - midi_status = val; - midi_cmd_pos = 0; - midi_cmd_len = MIDI_evt_len[val]; - if (midi_status == 0xf0) - { - midi_sysex_data[0] = 0xf0; - midi_pos = 1; - } - } - - if (midi_cmd_len) - { - midi_cmd_buf[midi_cmd_pos++] = val; - if (midi_cmd_pos >= midi_cmd_len) - { - PlayMsg(midi_cmd_buf); - midi_cmd_pos = 1; - } - } -} - -void midi_reset() -{ - uint8_t buf[64], used; - - /* Flush buffers */ - midiOutReset(midi_out_device); - - /* GM1 reset */ - buf[0] = 0xf0; - buf[1] = 0x7e; - buf[2] = 0x7f; - buf[3] = 0x09; - buf[4] = 0x01; - buf[5] = 0xf7; - PlaySysex((uint8_t *) buf, 6); - - /* GS1 reset */ - buf[0] = 0xf0; - buf[1] = 0x41; - buf[2] = 0x10; - buf[3] = 0x42; - buf[4] = 0x12; - buf[5] = 0x40; - buf[6] = 0x00; - buf[7] = 0x7f; - buf[8] = 0x00; - buf[9] = 0x41; - buf[10] = 0xf7; - PlaySysex((uint8_t *) buf, 11); -} diff --git a/src/win-mouse.cc b/src/win-mouse.cc deleted file mode 100644 index 0eacdee78..000000000 --- a/src/win-mouse.cc +++ /dev/null @@ -1,75 +0,0 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ -#define DIRECTINPUT_VERSION 0x0800 -#include -#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(); -extern "C" void mouse_close(); -extern "C" void mouse_poll_host(); -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() -{ - 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() -{ - if (lpdi_mouse) - { - lpdi_mouse->Release(); - lpdi_mouse = NULL; - } -} - -void mouse_poll_host() -{ - 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; -} diff --git a/src/win-opendir.c b/src/win-opendir.c deleted file mode 100644 index 847265582..000000000 --- a/src/win-opendir.c +++ /dev/null @@ -1,213 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * 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/12 - * - * Author: Fred N. van Kempen, - * Copyright 1998-2007 MicroWalt Corporation - * Copyright 2017 Fred N. van Kempen - */ -#define UNICODE -#include -#include -#include -#include -#include -#include -#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; - } - } -} diff --git a/src/win-serial.c b/src/win-serial.c deleted file mode 100644 index fb92b8bea..000000000 --- a/src/win-serial.c +++ /dev/null @@ -1,606 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * 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.2 2017/05/05 - * - * Author: Fred N. van Kempen, - * Copyright 2017 Fred N. van Kempen. - */ -#define _WIN32_WINNT 0x0501 -#include -#include -#include -#define BHTTY_C -#include "plat-serial.h" - - -extern void pclog(char *__fmt, ...); - - -/* Set the state of a port. */ -int -bhtty_sstate(BHTTY *pp, void *arg) -{ - int i = 0; - - /* Make sure we can do this. */ - if (pp == NULL || arg == NULL) { - pclog("invalid argument\n"); - 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) -{ - int i = 0; - - /* Make sure we can do this. */ - if (pp == NULL || arg == NULL) { - pclog("BHTTY: invalid argument\n"); - 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) -{ - /* Make sure we can do this. */ - if (pp == NULL) { - pclog("invalid handle\n"); - return(-1); - } - - /* 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) -{ - /* Make sure we can do this. */ - if (pp == NULL) { - pclog("invalid handle\n"); - return(-1); - } - - /* 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 (pp == NULL || arg == NULL) { - pclog("invalid parameter\n"); - 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) -{ - int i; - - /* Make sure we can do this. */ - if (pp == NULL) { - pclog("invalid handle\n"); - return(-1); - } - - /* 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; - int i = 0; - - /* Make sure we can do this. */ - if (pp == NULL) { - pclog("invalid handle\n"); - return(-1); - } - - /* 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) -{ - /* Make sure we can do this. */ - if (pp == NULL) { - pclog("BHTTY: invalid handle\n"); - return; - } - - if (pp->handle != INVALID_HANDLE_VALUE) { - /* 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 buff[64]; - COMMTIMEOUTS to; -#if 0 - COMMCONFIG conf; - DWORD d; -#endif - BHTTY *pp; - int i = 0; - - /* Make sure we can do this. */ - if (port == NULL) { - pclog("invalid argument!\n"); - return(NULL); - } - - /* 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(buff, "\\\\.\\%s", pp->name); - pp->handle = CreateFile(buff, - (GENERIC_READ|GENERIC_WRITE), - 0, NULL, OPEN_EXISTING, - FILE_FLAG_OVERLAPPED, - 0); - if (pp->handle == INVALID_HANDLE_VALUE) { - pclog("%s: open port: %d\n", pp->name, GetLastError()); - free(pp); - return(NULL); - } - -#if 0 - /* 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()); -// CloseHandle(pp->handle); -// free(pp); -// return(NULL); - } - - /* Grab default config for the driver and set it. */ - d = sizeof(COMMCONFIG); - memset(&conf, 0x00, d); - conf.dwSize = d; - if (GetDefaultCommConfig(pp->name, &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()); -// CloseHandle(pp->handle); -// free(pp); -// return(NULL); - } - } -#endif - - /* - * 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); -} - - -/* A pending WRITE has finished, handle it. */ -static VOID CALLBACK -bhtty_write_comp(DWORD err, DWORD num, OVERLAPPED *priv) -{ - BHTTY *pp = (BHTTY *)priv->hEvent; - -//pclog("%s: write complete, status %d, num %d\n", pp->name, err, num); -#if 0 - if ( - if (GetOverlappedResult(p->handle, - &p->rov, &mst, TRUE) == FALSE) { - r = GetLastError(); - if (r != ERROR_OPERATION_ABORTED) - /* OK, we're being shut down. */ - sprintf(serial_errmsg, - "%s: I/O read error!", p->name); - return(-1); - } -#endif -} - - -/* Try to write data to an open port. */ -int -bhtty_write(BHTTY *pp, unsigned char val) -{ - DWORD n; - - /* Make sure we can do this. */ - if (pp == NULL) { - pclog("invalid parameter\n"); - return(-1); - } -//pclog("BHwrite(%08lx, %02x, '%c')\n", pp->handle, val, val); - - /* Save the control pointer for later use. */ - pp->wov.hEvent = (HANDLE)pp; - - if (WriteFileEx(pp->handle, - &val, 1, - &pp->wov, - bhtty_write_comp) == FALSE) { - n = GetLastError(); - pclog("%s: I/O error %d in write!\n", pp->name, n); - return(-1); - } - - /* Its pending, so handled in the completion routine. */ - SleepEx(1, TRUE); - - return(0); -} - - -/* - * A pending READ has finished, handle it. - */ -static VOID CALLBACK -bhtty_read_comp(DWORD err, DWORD num, OVERLAPPED *priv) -{ - BHTTY *pp = (BHTTY *)priv->hEvent; - DWORD r; -//pclog("%s: read complete, status %d, num %d\n", pp->name, err, num); - - if (GetOverlappedResult(pp->handle, &pp->rov, &r, TRUE) == FALSE) { - r = GetLastError(); - if (r != ERROR_OPERATION_ABORTED) - /* OK, we're being shut down. */ - pclog("%s: I/O read error!", pp->name); - return; - } -//pclog("%s: read done, num=%d (%d)\n", pp->name, num, r); - - /* Do a callback to let them know. */ - if (pp->rd_done != NULL) - pp->rd_done(pp->rd_arg, num); -} - - -/* - * 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 - * - * Also, not that we do not wait here. We just POST a - * read operation, and the completion routine will do - * the clean-up and notify the caller. - */ -int -bhtty_read(BHTTY *pp, unsigned char *bufp, int max) -{ - DWORD r; - - /* Just one byte. */ - max = 1; - - /* Make sure we can do this. */ - if (pp == NULL) { - pclog("invalid parameter\n"); - return(-1); - } - - /* Save the control pointer for later use. */ - pp->rov.hEvent = (HANDLE)pp; -//pclog("%s: read(%08lx, %d)\n", pp->name, pp->handle, max); - - /* Post a READ on the device. */ - if (ReadFileEx(pp->handle, - bufp, (DWORD)max, - &pp->rov, - bhtty_read_comp) == FALSE) { - r = GetLastError(); - if (r != ERROR_IO_PENDING) { - /* OK, we're being shut down. */ - if (r != ERROR_INVALID_HANDLE) - pclog("%s: I/O read error!\n", pp->name); - return(-1); - } - } - - /* Make ourself alertable. */ - SleepEx(1, TRUE); - - /* OK, it's pending, so we are good for now. */ - return(0); -} diff --git a/src/win-settings.c b/src/win-settings.c deleted file mode 100644 index 308477b70..000000000 --- a/src/win-settings.c +++ /dev/null @@ -1,3674 +0,0 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ -#define UNICODE -#define BITMAP WINDOWS_BITMAP -#include -#include -#undef BITMAP - -#include -#include -#include "ibm.h" -#include "mem.h" -#include "cpu/cpu.h" -#include "nvr.h" -#include "model.h" -#include "device.h" -#include "cdrom.h" -#include "disc.h" -#include "fdd.h" -#include "hdd.h" -#include "ide.h" -#include "scsi.h" -#include "scsi_buslogic.h" -#include "network.h" -#include "plat-midi.h" -#include "sound/sound.h" -#include "sound/snd_dbopl.h" -#include "video/video.h" -#include "video/vid_voodoo.h" -#include "gameport.h" -#include "mouse.h" -#include "win.h" -#include "win-language.h" -#include "resource.h" - - -#define WM_SAVESETTINGS 0x8888 /* 86Box-specific message, used to tell the child dialog to save the currently specified settings. */ - - -/* Machine category */ -int temp_model, temp_cpu_m, temp_cpu, temp_wait_states, temp_mem_size, temp_dynarec, temp_fpu, temp_sync; - -/* Video category */ -int temp_gfxcard, temp_video_speed, temp_voodoo; - -/* Input devices category */ -int temp_mouse, temp_joystick; - -/* Sound category */ -int temp_sound_card, temp_midi_id, temp_SSI2001, temp_GAMEBLASTER, temp_GUS, temp_opl3_type; - -/* Network category */ -int temp_net_type, temp_net_card; -char temp_pcap_dev[520]; - -/* Peripherals category */ -int temp_scsi_card, hdc_ignore, temp_ide_ter, temp_ide_ter_irq, temp_ide_qua, temp_ide_qua_irq; -int temp_serial[2], temp_lpt, temp_bugger; - -char temp_hdc_name[16]; - -/* Hard disks category */ -hard_disk_t temp_hdc[HDC_NUM]; -wchar_t temp_hdd_fn[HDC_NUM][512]; - -/* Removable devices category */ -int temp_fdd_types[FDD_NUM]; -cdrom_drive_t temp_cdrom_drives[CDROM_NUM]; - -static HWND hwndParentDialog, hwndChildDialog; - -int hdd_controller_current; - -int displayed_category = 0; - -extern int is486; -static int romstolist[ROM_MAX], listtomodel[ROM_MAX], romstomodel[ROM_MAX], modeltolist[ROM_MAX]; -static int settings_sound_to_list[20], settings_list_to_sound[20]; -static int settings_mouse_to_list[20], settings_list_to_mouse[20]; -static int settings_scsi_to_list[20], settings_list_to_scsi[20]; -static int settings_network_to_list[20], settings_list_to_network[20]; -static char *hdd_names[16]; - -/* This does the initial read of global variables into the temporary ones. */ -static void win_settings_init() -{ - int i = 0; - - /* Machine category */ - temp_model = model; - temp_cpu_m = cpu_manufacturer; - temp_cpu = cpu; - temp_mem_size = mem_size; - temp_dynarec = cpu_use_dynarec; - temp_fpu = enable_external_fpu; - temp_sync = enable_sync; - - /* Video category */ - temp_gfxcard = gfxcard; - temp_video_speed = video_speed; - temp_voodoo = voodoo_enabled; - - /* Input devices category */ - temp_mouse = mouse_type; - temp_joystick = joystick_type; - - /* Sound category */ - temp_sound_card = sound_card_current; - temp_midi_id = midi_id; - temp_SSI2001 = SSI2001; - temp_GAMEBLASTER = GAMEBLASTER; - temp_GUS = GUS; - temp_opl3_type = opl3_type; - - /* Network category */ - temp_net_type = network_type; - memset(temp_pcap_dev, 0, 520); - strcpy(temp_pcap_dev, pcap_dev); - temp_net_card = network_card; - - /* Peripherals category */ - temp_scsi_card = scsi_card_current; - strncpy(temp_hdc_name, hdd_controller_name, sizeof(temp_hdc_name) - 1); - temp_ide_ter = ide_enable[2]; - temp_ide_ter_irq = ide_irq[2]; - temp_ide_qua = ide_enable[3]; - temp_ide_qua_irq = ide_irq[3]; - temp_serial[0] = serial_enabled[0]; - temp_serial[1] = serial_enabled[1]; - temp_lpt = lpt_enabled; - temp_bugger = bugger_enabled; - - /* Hard disks category */ - memcpy(temp_hdc, hdc, HDC_NUM * sizeof(hard_disk_t)); - for (i = 0; i < HDC_NUM; i++) - { - memcpy(temp_hdd_fn[i], hdd_fn[i], 1024); - } - - /* Removable devices category */ - for (i = 0; i < FDD_NUM; i++) - { - temp_fdd_types[i] = fdd_get_type(i); - } - memcpy(temp_cdrom_drives, cdrom_drives, CDROM_NUM * sizeof(cdrom_drive_t)); -} - -/* This returns 1 if any variable has changed, 0 if not. */ -static int win_settings_changed() -{ - int i = 0; - int j = 0; - - /* Machine category */ - i = i || (model != temp_model); - i = i || (cpu_manufacturer != temp_cpu_m); - i = i || (cpu != temp_cpu); - i = i || (mem_size != temp_mem_size); - i = i || (temp_dynarec != cpu_use_dynarec); - i = i || (temp_fpu != enable_external_fpu); - i = i || (temp_sync != enable_sync); - - /* Video category */ - i = i || (gfxcard != temp_gfxcard); - i = i || (video_speed != temp_video_speed); - i = i || (voodoo_enabled != temp_voodoo); - - /* Input devices category */ - i = i || (mouse_type != temp_mouse); - i = i || (joystick_type != temp_joystick); - - /* Sound category */ - i = i || (sound_card_current != temp_sound_card); - i = i || (midi_id != temp_midi_id); - i = i || (SSI2001 != temp_SSI2001); - i = i || (GAMEBLASTER != temp_GAMEBLASTER); - i = i || (GUS != temp_GUS); - i = i || (opl3_type != temp_opl3_type); - - /* Network category */ - i = i || (network_type != temp_net_type); - i = i || strcmp(temp_pcap_dev, pcap_dev); - i = i || (network_card != temp_net_card); - - /* Peripherals category */ - i = i || (scsi_card_current != temp_scsi_card); - i = i || strncmp(temp_hdc_name, hdd_controller_name, sizeof(temp_hdc_name) - 1); - i = i || (temp_ide_ter != ide_enable[2]); - i = i || (temp_ide_ter_irq != ide_irq[2]); - i = i || (temp_ide_qua != ide_enable[3]); - i = i || (temp_ide_qua_irq != ide_irq[3]); - i = i || (temp_serial[0] != serial_enabled[0]); - i = i || (temp_serial[1] != serial_enabled[1]); - i = i || (temp_lpt != lpt_enabled); - i = i || (temp_bugger != bugger_enabled); - - /* Hard disks category */ - i = i || memcmp(hdc, temp_hdc, HDC_NUM * sizeof(hard_disk_t)); - for (j = 0; j < HDC_NUM; j++) - { - i = i || memcmp(hdd_fn[j], temp_hdd_fn[j], 1024); - } - - /* Removable devices category */ - for (j = 0; j < FDD_NUM; j++) - { - i = i || (temp_fdd_types[j] != fdd_get_type(j)); - } - i = i || memcmp(cdrom_drives, temp_cdrom_drives, CDROM_NUM * sizeof(cdrom_drive_t)); - - return i; -} - -static int settings_msgbox_reset() -{ - int i = 0; - int changed = 0; - - changed = win_settings_changed(); - - if (changed) - { - i = msgbox_reset(hwndParentDialog); - - if (i == IDNO) - { - return 1; - } - else if (i == IDCANCEL) - { - return 0; - } - else - { - return 2; - } - } - else -{ - return 1; - } -} - -/* This saves the settings back to the global variables. */ -static void win_settings_save() -{ - int i = 0; - - /* Machine category */ - model = temp_model; - romset = model_getromset(); - cpu_manufacturer = temp_cpu_m; - cpu = temp_cpu; - mem_size = temp_mem_size; - cpu_use_dynarec = temp_dynarec; - enable_external_fpu = temp_fpu; - enable_sync = temp_sync; - - /* Video category */ - gfxcard = temp_gfxcard; - video_speed = temp_video_speed; - voodoo_enabled = temp_voodoo; - - /* Input devices category */ - mouse_type = temp_mouse; - joystick_type = temp_joystick; - - /* Sound category */ - sound_card_current = temp_sound_card; - midi_id = temp_midi_id; - SSI2001 = temp_SSI2001; - GAMEBLASTER = temp_GAMEBLASTER; - GUS = temp_GUS; - opl3_type = temp_opl3_type; - - /* Network category */ - network_type = temp_net_type; - memset(pcap_dev, 0, 512); - strcpy(pcap_dev, temp_pcap_dev); - network_card = temp_net_card; - - /* Peripherals category */ - scsi_card_current = temp_scsi_card; - strncpy(hdd_controller_name, temp_hdc_name, sizeof(temp_hdc_name) - 1); - ide_enable[2] = temp_ide_ter; - ide_irq[2] = temp_ide_ter_irq; - ide_enable[3] = temp_ide_qua; - ide_irq[3] = temp_ide_qua_irq; - serial_enabled[0] = temp_serial[0]; - serial_enabled[1] = temp_serial[1]; - lpt_enabled = temp_lpt; - bugger_enabled = temp_bugger; - - /* Hard disks category */ - memcpy(hdc, temp_hdc, HDC_NUM * sizeof(hard_disk_t)); - for (i = 0; i < HDC_NUM; i++) - { - memcpy(hdd_fn[i], temp_hdd_fn[i], 1024); - } - - /* Removable devices category */ - for (i = 0; i < FDD_NUM; i++) - { - fdd_set_type(i, temp_fdd_types[i]); - } - memcpy(cdrom_drives, temp_cdrom_drives, CDROM_NUM * sizeof(cdrom_drive_t)); - - mem_resize(); - loadbios(); - - resetpchard(); - - cpu_set(); - - cpu_update_waitstates(); - - saveconfig(); - - speedchanged(); - - if (joystick_type != 7) gameport_update_joystick_type(); - - update_status_bar_panes(hwndStatus); -} - -static void win_settings_machine_recalc_cpu(HWND hdlg) -{ - HWND h; - int temp_romset = 0; - int cpu_flags; - int cpu_type; - - temp_romset = model_getromset_ex(temp_model); - - h = GetDlgItem(hdlg, IDC_COMBO_WS); - cpu_type = models[romstomodel[temp_romset]].cpu[temp_cpu_m].cpus[temp_cpu].cpu_type; - if ((cpu_type >= CPU_286) && (cpu_type <= CPU_386DX)) - { - EnableWindow(h, TRUE); - } - else - { - EnableWindow(h, FALSE); - } - - h=GetDlgItem(hdlg, IDC_CHECK_DYNAREC); - cpu_flags = models[romstomodel[temp_romset]].cpu[temp_cpu_m].cpus[temp_cpu].cpu_flags; - if (!(cpu_flags & CPU_SUPPORTS_DYNAREC) && (cpu_flags & CPU_REQUIRES_DYNAREC)) - { - fatal("Attempting to select a CPU that requires the recompiler and does not support it at the same time\n"); - } - if (!(cpu_flags & CPU_SUPPORTS_DYNAREC) || (cpu_flags & CPU_REQUIRES_DYNAREC)) - { - if (!(cpu_flags & CPU_SUPPORTS_DYNAREC)) - { - temp_dynarec = 0; - } - if (cpu_flags & CPU_REQUIRES_DYNAREC) - { - temp_dynarec = 1; - } - SendMessage(h, BM_SETCHECK, temp_dynarec, 0); - EnableWindow(h, FALSE); - } - else - { - EnableWindow(h, TRUE); - } - - h = GetDlgItem(hdlg, IDC_CHECK_FPU); - cpu_type = models[romstomodel[temp_romset]].cpu[temp_cpu_m].cpus[temp_cpu].cpu_type; - if ((cpu_type < CPU_i486DX) && (cpu_type >= CPU_286)) - { - EnableWindow(h, TRUE); - } - else if (cpu_type < CPU_286) - { - temp_fpu = 0; - EnableWindow(h, FALSE); - } - else - { - temp_fpu = 1; - EnableWindow(h, FALSE); - } - SendMessage(h, BM_SETCHECK, temp_fpu, 0); -} - -static void win_settings_machine_recalc_cpu_m(HWND hdlg) -{ - HWND h; - int c = 0; - int temp_romset = 0; - LPTSTR lptsTemp; - char *stransi; - - temp_romset = model_getromset_ex(temp_model); - lptsTemp = (LPTSTR) malloc(512); - - h = GetDlgItem(hdlg, IDC_COMBO_CPU); - SendMessage(h, CB_RESETCONTENT, 0, 0); - c = 0; - while (models[romstomodel[temp_romset]].cpu[temp_cpu_m].cpus[c].cpu_type != -1) - { - stransi = models[romstomodel[temp_romset]].cpu[temp_cpu_m].cpus[c].name; - mbstowcs(lptsTemp, stransi, strlen(stransi) + 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)lptsTemp); - c++; - } - EnableWindow(h, TRUE); - SendMessage(h, CB_SETCURSEL, temp_cpu, 0); - - win_settings_machine_recalc_cpu(hdlg); - - free(lptsTemp); -} - -static void win_settings_machine_recalc_model(HWND hdlg) -{ - HWND h; - int c = 0; - int temp_romset = 0; - LPTSTR lptsTemp; - char *stransi; - UDACCEL accel; - - temp_romset = model_getromset_ex(temp_model); - lptsTemp = (LPTSTR) malloc(512); - - h = GetDlgItem(hdlg, IDC_CONFIGURE_MACHINE); - if (model_getdevice(temp_model)) - { - EnableWindow(h, TRUE); - } - else - { - EnableWindow(h, FALSE); - } - - h = GetDlgItem(hdlg, IDC_COMBO_CPU_TYPE); - SendMessage(h, CB_RESETCONTENT, 0, 0); - c = 0; - while (models[romstomodel[temp_romset]].cpu[c].cpus != NULL && c < 4) - { - stransi = models[romstomodel[temp_romset]].cpu[c].name; - mbstowcs(lptsTemp, stransi, strlen(stransi) + 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)lptsTemp); - c++; - } - EnableWindow(h, TRUE); - SendMessage(h, CB_SETCURSEL, temp_cpu_m, 0); - if (c == 1) - { - EnableWindow(h, FALSE); - } - else - { - EnableWindow(h, TRUE); - } - - win_settings_machine_recalc_cpu_m(hdlg); - - h = GetDlgItem(hdlg, IDC_MEMSPIN); - SendMessage(h, UDM_SETRANGE, 0, (models[romstomodel[temp_romset]].min_ram << 16) | models[romstomodel[temp_romset]].max_ram); - accel.nSec = 0; - accel.nInc = models[romstomodel[temp_romset]].ram_granularity; - SendMessage(h, UDM_SETACCEL, 1, (LPARAM)&accel); - if (!(models[romstomodel[temp_romset]].flags & MODEL_AT)) - { - SendMessage(h, UDM_SETPOS, 0, temp_mem_size); - h = GetDlgItem(hdlg, IDC_TEXT_MB); - SendMessage(h, WM_SETTEXT, 0, (LPARAM) win_language_get_string_from_id(2094)); - } - else - { - SendMessage(h, UDM_SETPOS, 0, temp_mem_size / 1024); - h = GetDlgItem(hdlg, IDC_TEXT_MB); - SendMessage(h, WM_SETTEXT, 0, (LPARAM) win_language_get_string_from_id(2087)); - } - - free(lptsTemp); -} - -static BOOL CALLBACK win_settings_machine_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - HWND h; - int c = 0; - int d = 0; - LPTSTR lptsTemp; - char *stransi; - - switch (message) - { - case WM_INITDIALOG: - lptsTemp = (LPTSTR) malloc(512); - - h = GetDlgItem(hdlg, IDC_COMBO_MACHINE); - for (c = 0; c < ROM_MAX; c++) - { - romstolist[c] = 0; - } - c = d = 0; - while (models[c].id != -1) - { - if (romspresent[models[c].id]) - { - stransi = models[c].name; - mbstowcs(lptsTemp, stransi, strlen(stransi) + 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - modeltolist[c] = d; - listtomodel[d] = c; - romstolist[models[c].id] = d; - romstomodel[models[c].id] = c; - d++; - } - c++; - } - SendMessage(h, CB_SETCURSEL, modeltolist[temp_model], 0); - - h = GetDlgItem(hdlg, IDC_COMBO_WS); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2131)); - - for (c = 0; c < 8; c++) - { - wsprintf(lptsTemp, win_language_get_string_from_id(2132), c); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } - - SendMessage(h, CB_SETCURSEL, cpu_waitstates, 0); - - h=GetDlgItem(hdlg, IDC_CHECK_DYNAREC); - SendMessage(h, BM_SETCHECK, temp_dynarec, 0); - - h = GetDlgItem(hdlg, IDC_MEMSPIN); - SendMessage(h, UDM_SETBUDDY, (WPARAM)GetDlgItem(hdlg, IDC_MEMTEXT), 0); - - h=GetDlgItem(hdlg, IDC_CHECK_SYNC); - SendMessage(h, BM_SETCHECK, temp_sync, 0); - - win_settings_machine_recalc_model(hdlg); - - free(lptsTemp); - - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) - { - case IDC_COMBO_MACHINE: - if (HIWORD(wParam) == CBN_SELCHANGE) - { - h = GetDlgItem(hdlg, IDC_COMBO_MACHINE); - temp_model = listtomodel[SendMessage(h,CB_GETCURSEL,0,0)]; - - win_settings_machine_recalc_model(hdlg); - } - break; - case IDC_COMBO_CPU_TYPE: - if (HIWORD(wParam) == CBN_SELCHANGE) - { - h = GetDlgItem(hdlg, IDC_COMBO_CPU_TYPE); - temp_cpu_m = SendMessage(h, CB_GETCURSEL, 0, 0); - - temp_cpu = 0; - win_settings_machine_recalc_cpu_m(hdlg); - } - break; - case IDC_COMBO_CPU: - if (HIWORD(wParam) == CBN_SELCHANGE) - { - h = GetDlgItem(hdlg, IDC_COMBO_CPU); - temp_cpu = SendMessage(h, CB_GETCURSEL, 0, 0); - - win_settings_machine_recalc_cpu(hdlg); - } - break; - case IDC_CONFIGURE_MACHINE: - h = GetDlgItem(hdlg, IDC_COMBO_MACHINE); - temp_model = listtomodel[SendMessage(h, CB_GETCURSEL, 0, 0)]; - - deviceconfig_open(hdlg, (void *)model_getdevice(temp_model)); - break; - } - - return FALSE; - - case WM_SAVESETTINGS: - lptsTemp = (LPTSTR) malloc(512); - stransi = (char *) malloc(512); - - h=GetDlgItem(hdlg, IDC_CHECK_DYNAREC); - temp_dynarec = SendMessage(h, BM_GETCHECK, 0, 0); - - h=GetDlgItem(hdlg, IDC_CHECK_SYNC); - temp_sync = SendMessage(h, BM_GETCHECK, 0, 0); - - h=GetDlgItem(hdlg, IDC_CHECK_FPU); - temp_fpu = SendMessage(h, BM_GETCHECK, 0, 0); - - h = GetDlgItem(hdlg, IDC_COMBO_WS); - temp_wait_states = SendMessage(h, CB_GETCURSEL, 0, 0); - - h = GetDlgItem(hdlg, IDC_MEMTEXT); - SendMessage(h, WM_GETTEXT, 255, (LPARAM) lptsTemp); - wcstombs(stransi, lptsTemp, (wcslen(lptsTemp) * 2) + 2); - sscanf(stransi, "%i", &temp_mem_size); - temp_mem_size &= ~(models[temp_model].ram_granularity - 1); - if (temp_mem_size < models[temp_model].min_ram) - { - temp_mem_size = models[temp_model].min_ram; - } - else if (temp_mem_size > models[temp_model].max_ram) - { - temp_mem_size = models[temp_model].max_ram; - } - if (models[temp_model].flags & MODEL_AT) - { - temp_mem_size *= 1024; - } - - free(stransi); - free(lptsTemp); - - default: - return FALSE; - } - - return FALSE; -} - -static void recalc_vid_list(HWND hdlg) -{ - HWND h = GetDlgItem(hdlg, IDC_COMBO_VIDEO); - int c = 0, d = 0; - int found_card = 0; - WCHAR szText[512]; - - SendMessage(h, CB_RESETCONTENT, 0, 0); - SendMessage(h, CB_SETCURSEL, 0, 0); - - while (1) - { - char *s = video_card_getname(c); - - if (!s[0]) - break; - - if (video_card_available(c) && gfx_present[video_new_to_old(c)] && - ((models[temp_model].flags & MODEL_PCI) || !(video_card_getdevice(c)->flags & DEVICE_PCI))) - { - mbstowcs(szText, s, strlen(s) + 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) szText); - if (video_new_to_old(c) == gfxcard) - { - - SendMessage(h, CB_SETCURSEL, d, 0); - found_card = 1; - } - - d++; - } - - c++; - } - if (!found_card) - SendMessage(h, CB_SETCURSEL, 0, 0); - EnableWindow(h, models[temp_model].fixed_gfxcard ? FALSE : TRUE); - - h = GetDlgItem(hdlg, IDC_CHECK_VOODOO); - EnableWindow(h, (models[model].flags & MODEL_PCI) ? TRUE : FALSE); - - h = GetDlgItem(hdlg, IDC_CONFIGURE_VOODOO); - EnableWindow(h, ((models[model].flags & MODEL_PCI) && temp_voodoo) ? TRUE : FALSE); -} - -static BOOL CALLBACK win_settings_video_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - HWND h; - int c = 0; - int d = 0; - LPTSTR lptsTemp; - char *stransi; - char *s; - int gfx = 0; - - switch (message) - { - case WM_INITDIALOG: - lptsTemp = (LPTSTR) malloc(512); - stransi = (char *) malloc(512); - - recalc_vid_list(hdlg); - - h = GetDlgItem(hdlg, IDC_COMBO_VIDEO_SPEED); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2133)); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2134)); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2135)); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2136)); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2137)); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2138)); - SendMessage(h, CB_SETCURSEL, temp_video_speed, 0); - - h=GetDlgItem(hdlg, IDC_CHECK_VOODOO); - SendMessage(h, BM_SETCHECK, temp_voodoo, 0); - - h = GetDlgItem(hdlg, IDC_COMBO_VIDEO); - SendMessage(h, CB_GETLBTEXT, SendMessage(h, CB_GETCURSEL, 0, 0), (LPARAM) lptsTemp); - wcstombs(stransi, lptsTemp, (wcslen(lptsTemp) * 2) + 2); - gfx = video_card_getid(stransi); - - h = GetDlgItem(hdlg, IDC_CONFIGUREVID); - if (video_card_has_config(gfx)) - { - EnableWindow(h, TRUE); - } - else - { - EnableWindow(h, FALSE); - } - - free(stransi); - free(lptsTemp); - - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) - { - case IDC_COMBO_VIDEO: - lptsTemp = (LPTSTR) malloc(512); - stransi = (char *) malloc(512); - - h = GetDlgItem(hdlg, IDC_COMBO_VIDEO); - SendMessage(h, CB_GETLBTEXT, SendMessage(h, CB_GETCURSEL, 0, 0), (LPARAM) lptsTemp); - wcstombs(stransi, lptsTemp, (wcslen(lptsTemp) * 2) + 2); - gfx = video_card_getid(stransi); - temp_gfxcard = video_new_to_old(gfx); - - h = GetDlgItem(hdlg, IDC_CONFIGUREVID); - if (video_card_has_config(gfx)) - { - EnableWindow(h, TRUE); - } - else - { - EnableWindow(h, FALSE); - } - - free(stransi); - free(lptsTemp); - break; - - case IDC_CHECK_VOODOO: - h = GetDlgItem(hdlg, IDC_CHECK_VOODOO); - temp_voodoo = SendMessage(h, BM_GETCHECK, 0, 0); - - h = GetDlgItem(hdlg, IDC_CONFIGURE_VOODOO); - EnableWindow(h, temp_voodoo ? TRUE : FALSE); - break; - - case IDC_CONFIGURE_VOODOO: - deviceconfig_open(hdlg, (void *)&voodoo_device); - break; - - case IDC_CONFIGUREVID: - lptsTemp = (LPTSTR) malloc(512); - stransi = (char *) malloc(512); - - h = GetDlgItem(hdlg, IDC_COMBO_VIDEO); - SendMessage(h, CB_GETLBTEXT, SendMessage(h, CB_GETCURSEL, 0, 0), (LPARAM) lptsTemp); - wcstombs(stransi, lptsTemp, (wcslen(lptsTemp) * 2) + 2); - deviceconfig_open(hdlg, (void *)video_card_getdevice(video_card_getid(stransi))); - - free(stransi); - free(lptsTemp); - break; - } - return FALSE; - - case WM_SAVESETTINGS: - lptsTemp = (LPTSTR) malloc(512); - stransi = (char *) malloc(512); - - h = GetDlgItem(hdlg, IDC_COMBO_VIDEO); - SendMessage(h, CB_GETLBTEXT, SendMessage(h, CB_GETCURSEL, 0, 0), (LPARAM) lptsTemp); - wcstombs(stransi, lptsTemp, (wcslen(lptsTemp) * 2) + 2); - temp_gfxcard = video_new_to_old(video_card_getid(stransi)); - - h = GetDlgItem(hdlg, IDC_COMBO_VIDEO_SPEED); - temp_video_speed = SendMessage(h, CB_GETCURSEL, 0, 0); - - h = GetDlgItem(hdlg, IDC_CHECK_VOODOO); - temp_voodoo = SendMessage(h, BM_GETCHECK, 0, 0); - - free(stransi); - free(lptsTemp); - - default: - return FALSE; - } - return FALSE; -} - - -static int mouse_valid(int type, int model) -{ - type &= MOUSE_TYPE_MASK; - - if ((type == MOUSE_TYPE_PS2) && - !(models[model].flags & MODEL_PS2)) return(0); - - if ((type == MOUSE_TYPE_AMSTRAD) && - !(models[model].flags & MODEL_AMSTRAD)) return(0); - - if ((type == MOUSE_TYPE_OLIM24) && - !(models[model].flags & MODEL_OLIM24)) return(0); - - return(1); -} - - -static BOOL CALLBACK win_settings_input_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - HWND h; - int c = 0; - int d = 0; - int type; - int str_id = 0; - - switch (message) - { - case WM_INITDIALOG: - h = GetDlgItem(hdlg, IDC_COMBO_MOUSE); - c = d = 0; - for (c = 0; c < mouse_get_ndev(); c++) - { - type = mouse_get_type(c); - - settings_mouse_to_list[c] = d; - - if (mouse_valid(type, temp_model)) - { - switch(c) - { - case 0: /* MS Serial */ - default: - str_id = 2139; - break; - case 1: /* PS2 2b */ - str_id = 2141; - break; - case 2: /* PS2 intelli 3b */ - str_id = 2142; - break; - case 3: /* MS/logi bus 2b */ - str_id = 2143; - break; - case 4: /* Amstrad */ - str_id = 2162; - break; - case 5: /* Olivetti M24 */ - str_id = 2177; - break; - case 6: /* MouseSystems */ - str_id = 2140; - break; - case 7: /* Genius Bus */ - str_id = 2161; - break; - } - - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(str_id)); - - settings_list_to_mouse[d] = c; - d++; - } - } - - SendMessage(h, CB_SETCURSEL, settings_mouse_to_list[temp_mouse], 0); - - h = GetDlgItem(hdlg, IDC_COMBO_JOYSTICK); - c = 0; - while (joystick_get_name(c)) - { - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2144 + c)); - c++; - } - EnableWindow(h, TRUE); - SendMessage(h, CB_SETCURSEL, temp_joystick, 0); - - h = GetDlgItem(hdlg, IDC_JOY1); - EnableWindow(h, (joystick_get_max_joysticks(temp_joystick) >= 1) ? TRUE : FALSE); - h = GetDlgItem(hdlg, IDC_JOY2); - EnableWindow(h, (joystick_get_max_joysticks(temp_joystick) >= 2) ? TRUE : FALSE); - h = GetDlgItem(hdlg, IDC_JOY3); - EnableWindow(h, (joystick_get_max_joysticks(temp_joystick) >= 3) ? TRUE : FALSE); - h = GetDlgItem(hdlg, IDC_JOY4); - EnableWindow(h, (joystick_get_max_joysticks(temp_joystick) >= 4) ? TRUE : FALSE); - - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) - { - case IDC_COMBO_JOYSTICK: - if (HIWORD(wParam) == CBN_SELCHANGE) - { - h = GetDlgItem(hdlg, IDC_COMBO_JOYSTICK); - temp_joystick = SendMessage(h, CB_GETCURSEL, 0, 0); - - h = GetDlgItem(hdlg, IDC_JOY1); - EnableWindow(h, (joystick_get_max_joysticks(temp_joystick) >= 1) ? TRUE : FALSE); - h = GetDlgItem(hdlg, IDC_JOY2); - EnableWindow(h, (joystick_get_max_joysticks(temp_joystick) >= 2) ? TRUE : FALSE); - h = GetDlgItem(hdlg, IDC_JOY3); - EnableWindow(h, (joystick_get_max_joysticks(temp_joystick) >= 3) ? TRUE : FALSE); - h = GetDlgItem(hdlg, IDC_JOY4); - EnableWindow(h, (joystick_get_max_joysticks(temp_joystick) >= 4) ? TRUE : FALSE); - } - break; - - case IDC_JOY1: - h = GetDlgItem(hdlg, IDC_COMBOJOY); - temp_joystick = SendMessage(h, CB_GETCURSEL, 0, 0); - joystickconfig_open(hdlg, 0, temp_joystick); - break; - - case IDC_JOY2: - h = GetDlgItem(hdlg, IDC_COMBOJOY); - temp_joystick = SendMessage(h, CB_GETCURSEL, 0, 0); - joystickconfig_open(hdlg, 1, temp_joystick); - break; - - case IDC_JOY3: - h = GetDlgItem(hdlg, IDC_COMBOJOY); - temp_joystick = SendMessage(h, CB_GETCURSEL, 0, 0); - joystickconfig_open(hdlg, 2, temp_joystick); - break; - - case IDC_JOY4: - h = GetDlgItem(hdlg, IDC_COMBOJOY); - temp_joystick = SendMessage(h, CB_GETCURSEL, 0, 0); - joystickconfig_open(hdlg, 3, temp_joystick); - break; - } - return FALSE; - - case WM_SAVESETTINGS: - h = GetDlgItem(hdlg, IDC_COMBO_MOUSE); - temp_mouse = settings_list_to_mouse[SendMessage(h, CB_GETCURSEL, 0, 0)]; - - h = GetDlgItem(hdlg, IDC_COMBO_JOYSTICK); - temp_joystick = SendMessage(h, CB_GETCURSEL, 0, 0); - - default: - return FALSE; - } - return FALSE; -} - -static void recalc_hdd_list(HWND hdlg, int model, int use_selected_hdd) -{ - HWND h; - - char *s; - int valid = 0; - char old_name[16]; - int c, d; - - LPTSTR lptsTemp; - - lptsTemp = (LPTSTR) malloc(512); - - h = GetDlgItem(hdlg, IDC_COMBO_HDC); - - if (models[model].flags & MODEL_HAS_IDE) - { - hdc_ignore = 1; - - SendMessage(h, CB_RESETCONTENT, 0, 0); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2154)); - EnableWindow(h, FALSE); - SendMessage(h, CB_SETCURSEL, 0, 0); - } - else - { - hdc_ignore = 0; - - valid = 0; - - if (use_selected_hdd) - { - c = SendMessage(h, CB_GETCURSEL, 0, 0); - - if (c != -1 && hdd_names[c]) - { - strncpy(old_name, hdd_names[c], sizeof(old_name) - 1); - } - else - { - strcpy(old_name, "none"); - } - } - else - { - strncpy(old_name, temp_hdc_name, sizeof(old_name) - 1); - } - - SendMessage(h, CB_RESETCONTENT, 0, 0); - c = d = 0; - while (1) - { - s = hdd_controller_get_name(c); - if (s[0] == 0) - { - break; - } - if ((hdd_controller_get_flags(c) & DEVICE_AT) && !(models[model].flags & MODEL_AT)) - { - c++; - continue; - } - if ((hdd_controller_get_flags(c) & DEVICE_PS2) && !(models[model].flags & MODEL_PS2_HDD)) - { - c++; - continue; - } - if ((hdd_controller_get_flags(c) & DEVICE_MCA) && !(models[model].flags & MODEL_MCA)) - { - c++; - continue; - } - if (!hdd_controller_available(c)) - { - c++; - continue; - } - if (c < 2) - { - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2152 + c)); - } - else - { - mbstowcs(lptsTemp, s, strlen(s) + 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } - hdd_names[d] = hdd_controller_get_internal_name(c); - if (!strcmp(old_name, hdd_names[d])) - { - SendMessage(h, CB_SETCURSEL, d, 0); - valid = 1; - } - c++; - d++; - } - - if (!valid) - { - SendMessage(h, CB_SETCURSEL, 0, 0); - } - - EnableWindow(h, TRUE); - } - - free(lptsTemp); -} - -int valid_ide_irqs[11] = { 2, 3, 4, 5, 7, 9, 10, 11, 12, 14, 15 }; - -int find_irq_in_array(int irq, int def) -{ - int i = 0; - - for (i = 0; i < 11; i++) - { - if (valid_ide_irqs[i] == irq) - { - return i + 1; - } - } - - return 7 + def; -} - -static char midi_dev_name_buf[512]; - -static BOOL CALLBACK win_settings_sound_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - HWND h; - int c = 0; - int d = 0; - LPTSTR lptsTemp; - device_t *sound_dev; - int num = 0; - - switch (message) - { - case WM_INITDIALOG: - lptsTemp = (LPTSTR) malloc(512); - - h = GetDlgItem(hdlg, IDC_COMBOSND); - c = d = 0; - while (1) - { - char *s = sound_card_getname(c); - - if (!s[0]) - { - break; - } - - settings_sound_to_list[c] = d; - - if (sound_card_available(c)) - { - sound_dev = sound_card_getdevice(c); - - if (!sound_dev || (sound_dev->flags & DEVICE_MCA) == (models[temp_model].flags & MODEL_MCA)) - { - if (c == 0) - { - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2152)); - } - else - { - mbstowcs(lptsTemp, s, strlen(s) + 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } - settings_list_to_sound[d] = c; - d++; - } - } - - c++; - } - SendMessage(h, CB_SETCURSEL, settings_sound_to_list[temp_sound_card], 0); - - h = GetDlgItem(hdlg, IDC_CONFIGURESND); - if (sound_card_has_config(temp_sound_card)) - { - EnableWindow(h, TRUE); - } - else - { - EnableWindow(h, FALSE); - } - - h = GetDlgItem(hdlg, IDC_COMBO_MIDI); - num = midi_get_num_devs(); - for (c = 0; c < num; c++) - { - memset(midi_dev_name_buf, 0, 512); - midi_get_dev_name(c, midi_dev_name_buf); - mbstowcs(lptsTemp, midi_dev_name_buf, strlen(midi_dev_name_buf) + 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - if (c == temp_midi_id) - SendMessage(h, CB_SETCURSEL, c, 0); - } - - h=GetDlgItem(hdlg, IDC_CHECKCMS); - SendMessage(h, BM_SETCHECK, temp_GAMEBLASTER, 0); - - h=GetDlgItem(hdlg, IDC_CHECKGUS); - SendMessage(h, BM_SETCHECK, temp_GUS, 0); - - h=GetDlgItem(hdlg, IDC_CHECKSSI); - SendMessage(h, BM_SETCHECK, temp_SSI2001, 0); - - h=GetDlgItem(hdlg, IDC_CHECKNUKEDOPL); - SendMessage(h, BM_SETCHECK, temp_opl3_type, 0); - - free(lptsTemp); - - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) - { - case IDC_CONFIGURESND: - h = GetDlgItem(hdlg, IDC_COMBOSND); - temp_sound_card = settings_list_to_sound[SendMessage(h, CB_GETCURSEL, 0, 0)]; - - deviceconfig_open(hdlg, (void *)sound_card_getdevice(temp_sound_card)); - break; - - case IDC_COMBOSND: - h = GetDlgItem(hdlg, IDC_COMBOSND); - temp_sound_card = settings_list_to_sound[SendMessage(h, CB_GETCURSEL, 0, 0)]; - - h = GetDlgItem(hdlg, IDC_CONFIGURESND); - if (sound_card_has_config(temp_sound_card)) - { - EnableWindow(h, TRUE); - } - else - { - EnableWindow(h, FALSE); - } - break; - } - return FALSE; - - case WM_SAVESETTINGS: - h = GetDlgItem(hdlg, IDC_COMBOSND); - temp_sound_card = settings_list_to_sound[SendMessage(h, CB_GETCURSEL, 0, 0)]; - - h = GetDlgItem(hdlg, IDC_COMBO_MIDI); - temp_midi_id = SendMessage(h, CB_GETCURSEL, 0, 0); - - h = GetDlgItem(hdlg, IDC_CHECKCMS); - temp_GAMEBLASTER = SendMessage(h, BM_GETCHECK, 0, 0); - - h = GetDlgItem(hdlg, IDC_CHECKGUS); - temp_GUS = SendMessage(h, BM_GETCHECK, 0, 0); - - h = GetDlgItem(hdlg, IDC_CHECKSSI); - temp_SSI2001 = SendMessage(h, BM_GETCHECK, 0, 0); - - h = GetDlgItem(hdlg, IDC_CHECKNUKEDOPL); - temp_opl3_type = SendMessage(h, BM_GETCHECK, 0, 0); - - default: - return FALSE; - } - return FALSE; -} - -static BOOL CALLBACK win_settings_peripherals_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - HWND h; - int c = 0; - int d = 0; - LPTSTR lptsTemp; - device_t *scsi_dev; - - switch (message) - { - case WM_INITDIALOG: - lptsTemp = (LPTSTR) malloc(512); - - /*SCSI config*/ - h = GetDlgItem(hdlg, IDC_COMBO_SCSI); - c = d = 0; - while (1) - { - char *s = scsi_card_getname(c); - - if (!s[0]) - { - break; - } - - settings_scsi_to_list[c] = d; - - if (scsi_card_available(c)) - { - scsi_dev = scsi_card_getdevice(c); - - if (!scsi_dev || (scsi_dev->flags & DEVICE_MCA) == (models[temp_model].flags & MODEL_MCA)) - { - if (c == 0) - { - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2152)); - } - else - { - mbstowcs(lptsTemp, s, strlen(s) + 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } - settings_list_to_scsi[d] = c; - d++; - } - } - - c++; - } - SendMessage(h, CB_SETCURSEL, settings_scsi_to_list[temp_scsi_card], 0); - - h = GetDlgItem(hdlg, IDC_CONFIGURE_SCSI); - if (scsi_card_has_config(temp_scsi_card)) - { - EnableWindow(h, TRUE); - } - else - { - EnableWindow(h, FALSE); - } - - recalc_hdd_list(hdlg, temp_model, 0); - - h=GetDlgItem(hdlg, IDC_COMBO_IDE_TER); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2151)); - - for (c = 0; c < 11; c++) - { - wsprintf(lptsTemp, win_language_get_string_from_id(2155), valid_ide_irqs[c]); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } - - if (temp_ide_ter) - { - SendMessage(h, CB_SETCURSEL, find_irq_in_array(temp_ide_ter_irq, 0), 0); - } - else - { - SendMessage(h, CB_SETCURSEL, 0, 0); - } - - h=GetDlgItem(hdlg, IDC_COMBO_IDE_QUA); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2151)); - - for (c = 0; c < 11; c++) - { - wsprintf(lptsTemp, win_language_get_string_from_id(2155), valid_ide_irqs[c]); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } - - if (temp_ide_qua) - { - SendMessage(h, CB_SETCURSEL, find_irq_in_array(temp_ide_qua_irq, 1), 0); - } - else - { - SendMessage(h, CB_SETCURSEL, 0, 0); - } - - h=GetDlgItem(hdlg, IDC_CHECKSERIAL1); - SendMessage(h, BM_SETCHECK, temp_serial[0], 0); - - h=GetDlgItem(hdlg, IDC_CHECKSERIAL2); - SendMessage(h, BM_SETCHECK, temp_serial[1], 0); - - h=GetDlgItem(hdlg, IDC_CHECKPARALLEL); - SendMessage(h, BM_SETCHECK, temp_lpt, 0); - - h=GetDlgItem(hdlg, IDC_CHECKBUGGER); - SendMessage(h, BM_SETCHECK, temp_bugger, 0); - - free(lptsTemp); - - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) - { - case IDC_CONFIGURE_SCSI: - h = GetDlgItem(hdlg, IDC_COMBO_SCSI); - temp_scsi_card = settings_list_to_scsi[SendMessage(h, CB_GETCURSEL, 0, 0)]; - - deviceconfig_open(hdlg, (void *)scsi_card_getdevice(temp_scsi_card)); - break; - - case IDC_COMBO_SCSI: - h = GetDlgItem(hdlg, IDC_COMBO_SCSI); - temp_scsi_card = settings_list_to_scsi[SendMessage(h, CB_GETCURSEL, 0, 0)]; - - h = GetDlgItem(hdlg, IDC_CONFIGURE_SCSI); - if (scsi_card_has_config(temp_scsi_card)) - { - EnableWindow(h, TRUE); - } - else - { - EnableWindow(h, FALSE); - } - break; - } - return FALSE; - - case WM_SAVESETTINGS: - if (hdc_ignore == 0) - { - h = GetDlgItem(hdlg, IDC_COMBO_HDC); - c = SendMessage(h, CB_GETCURSEL, 0, 0); - if (hdd_names[c]) - { - strncpy(temp_hdc_name, hdd_names[c], sizeof(temp_hdc_name) - 1); - } - else - { - strcpy(temp_hdc_name, "none"); - } - } - else - { - strcpy(temp_hdc_name, "none"); - } - - h = GetDlgItem(hdlg, IDC_COMBO_SCSI); - temp_scsi_card = settings_list_to_scsi[SendMessage(h, CB_GETCURSEL, 0, 0)]; - - h = GetDlgItem(hdlg, IDC_COMBO_IDE_TER); - temp_ide_ter = SendMessage(h, CB_GETCURSEL, 0, 0); - if (temp_ide_ter > 1) - { - temp_ide_ter_irq = valid_ide_irqs[temp_ide_ter - 1]; - temp_ide_ter = 1; - } - - h = GetDlgItem(hdlg, IDC_COMBO_IDE_QUA); - temp_ide_qua = SendMessage(h, CB_GETCURSEL, 0, 0); - if (temp_ide_qua > 1) - { - temp_ide_qua_irq = valid_ide_irqs[temp_ide_qua - 1]; - temp_ide_qua = 1; - } - - h = GetDlgItem(hdlg, IDC_CHECKSERIAL1); - temp_serial[0] = SendMessage(h, BM_GETCHECK, 0, 0); - - h = GetDlgItem(hdlg, IDC_CHECKSERIAL2); - temp_serial[1] = SendMessage(h, BM_GETCHECK, 0, 0); - - h = GetDlgItem(hdlg, IDC_CHECKPARALLEL); - temp_lpt = SendMessage(h, BM_GETCHECK, 0, 0); - - h = GetDlgItem(hdlg, IDC_CHECKBUGGER); - temp_bugger = SendMessage(h, BM_GETCHECK, 0, 0); - - default: - return FALSE; - } - return FALSE; -} - -int net_ignore_message = 0; - -static void network_recalc_combos(HWND hdlg) -{ - HWND h; - - net_ignore_message = 1; - - h = GetDlgItem(hdlg, IDC_COMBOPCAP); - if (temp_net_type == 1) - { - EnableWindow(h, TRUE); - } - else - { - EnableWindow(h, FALSE); - } - - h = GetDlgItem(hdlg, IDC_COMBONET); - if (temp_net_type == 0) - { - EnableWindow(h, TRUE); - } - else if ((temp_net_type == 1) && (network_dev_to_id(temp_pcap_dev) > 0)) - { - EnableWindow(h, TRUE); - } - else - { - EnableWindow(h, FALSE); - } - - h = GetDlgItem(hdlg, IDC_CONFIGURENET); - if (network_card_has_config(temp_net_card) && (temp_net_type == 0)) - { - EnableWindow(h, TRUE); - } - else if (network_card_has_config(temp_net_card) && (temp_net_type == 1) && (network_dev_to_id(temp_pcap_dev) > 0)) - { - EnableWindow(h, TRUE); - } - else - { - EnableWindow(h, FALSE); - } - - net_ignore_message = 0; -} - -static BOOL CALLBACK win_settings_network_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - HWND h; - int c = 0; - int d = 0; - LPTSTR lptsTemp; - device_t *scsi_dev; - - switch (message) - { - case WM_INITDIALOG: - lptsTemp = (LPTSTR) malloc(512); - - h = GetDlgItem(hdlg, IDC_COMBONETTYPE); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) L"None"); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) L"PCap"); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) L"SLiRP"); - SendMessage(h, CB_SETCURSEL, temp_net_type + 1, 0); - - h = GetDlgItem(hdlg, IDC_COMBOPCAP); - if (temp_net_type == 0) - { - EnableWindow(h, TRUE); - } - else - { - EnableWindow(h, FALSE); - } - - h = GetDlgItem(hdlg, IDC_COMBOPCAP); - for (c = 0; c < netdev_num; c++) - { - mbstowcs(lptsTemp, netdev_list[c].description, strlen(netdev_list[c].description) + 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } - SendMessage(h, CB_SETCURSEL, network_dev_to_id(temp_pcap_dev), 0); - - /*NIC config*/ - h = GetDlgItem(hdlg, IDC_COMBONET); - c = d = 0; - while (1) - { - char *s = network_card_getname(c); - - if (!s[0]) - { - break; - } - - settings_network_to_list[c] = d; - - if (network_card_available(c)) - { - if (c == 0) - { - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2152)); - } - else - { - mbstowcs(lptsTemp, s, strlen(s) + 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } - settings_list_to_network[d] = c; - d++; - } - - c++; - } - SendMessage(h, CB_SETCURSEL, settings_network_to_list[temp_net_card], 0); - - network_recalc_combos(hdlg); - - free(lptsTemp); - - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) - { - case IDC_COMBONETTYPE: - if (net_ignore_message) - { - return FALSE; - } - - h = GetDlgItem(hdlg, IDC_COMBONETTYPE); - temp_net_type = SendMessage(h, CB_GETCURSEL, 0, 0) - 1; - - network_recalc_combos(hdlg); - break; - - case IDC_COMBOPCAP: - if (net_ignore_message) - { - return FALSE; - } - - h = GetDlgItem(hdlg, IDC_COMBOPCAP); - memset(temp_pcap_dev, 0, 520); - strcpy(temp_pcap_dev, netdev_list[SendMessage(h, CB_GETCURSEL, 0, 0)].device); - - network_recalc_combos(hdlg); - break; - - case IDC_COMBONET: - if (net_ignore_message) - { - return FALSE; - } - - h = GetDlgItem(hdlg, IDC_COMBONET); - temp_net_card = settings_list_to_network[SendMessage(h, CB_GETCURSEL, 0, 0)]; - - network_recalc_combos(hdlg); - break; - - case IDC_CONFIGURENET: - if (net_ignore_message) - { - return FALSE; - } - - h = GetDlgItem(hdlg, IDC_COMBONET); - temp_net_card = settings_list_to_network[SendMessage(h, CB_GETCURSEL, 0, 0)]; - - deviceconfig_open(hdlg, (void *)network_card_getdevice(temp_net_card)); - break; - } - return FALSE; - - case WM_SAVESETTINGS: - h = GetDlgItem(hdlg, IDC_COMBONETTYPE); - temp_net_type = SendMessage(h, CB_GETCURSEL, 0, 0) - 1; - - h = GetDlgItem(hdlg, IDC_COMBOPCAP); - memset(temp_pcap_dev, 0, 520); - strcpy(temp_pcap_dev, netdev_list[SendMessage(h, CB_GETCURSEL, 0, 0)].device); - - h = GetDlgItem(hdlg, IDC_COMBONET); - temp_net_card = settings_list_to_network[SendMessage(h, CB_GETCURSEL, 0, 0)]; - - default: - return FALSE; - } - - return FALSE; -} - -static BOOL win_settings_hard_disks_image_list_init(HWND hwndList) -{ - HICON hiconItem; - HIMAGELIST hSmall; - - int i = 0; - - hSmall = ImageList_Create(GetSystemMetrics(SM_CXSMICON), - GetSystemMetrics(SM_CYSMICON), - ILC_MASK | ILC_COLOR32, 1, 1); - - for (i = 0; i < 8; i += 2) - { - hiconItem = LoadIcon(hinstance, (LPCWSTR) (176 + i)); - ImageList_AddIcon(hSmall, hiconItem); - DestroyIcon(hiconItem); - } - - ListView_SetImageList(hwndList, hSmall, LVSIL_SMALL); - - return TRUE; -} - -int next_free_id = 0; - -wchar_t ifn[HDC_NUM][512]; - -static void normalize_hd_list() -{ - hard_disk_t ihdc[HDC_NUM]; - int i, j; - - j = 0; - memset(ihdc, 0, HDC_NUM * sizeof(hard_disk_t)); - for (i = 0; i < HDC_NUM; i++) - { - memset(ifn[i], 0, 1024); - } - for (i = 0; i < HDC_NUM; i++) - { - if (temp_hdc[i].bus > 0) - { - memcpy(&(ihdc[j]), &(temp_hdc[i]), sizeof(hard_disk_t)); - memcpy(ifn[j], temp_hdd_fn[i], 1024); - j++; - } - } - - memcpy(temp_hdc, ihdc, HDC_NUM * sizeof(hard_disk_t)); - for (i = 0; i < HDC_NUM; i++) - { - memcpy(temp_hdd_fn[i], ifn[i], 1024); - } -} - -int hdc_id_to_listview_index[HDC_NUM]; -int hd_listview_items; - -hard_disk_t new_hdc; -int hdlv_current_sel; - -static int get_selected_hard_disk(HWND hdlg) -{ - int hard_disk = -1; - int i, j = 0; - HWND h; - - for (i = 0; i < 6; i++) - { - h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); - j = ListView_GetItemState(h, i, LVIS_SELECTED); - if (j) - { - hard_disk = i; - } - } - - return hard_disk; -} - -static void add_locations(HWND hdlg) -{ - LPTSTR lptsTemp; - HWND h; - int i = 0; - - lptsTemp = (LPTSTR) malloc(512); - - h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); - for (i = 0; i < 4; i++) - { - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2165 + i)); - } - - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); - for (i = 0; i < 8; i++) - { - wsprintf(lptsTemp, win_language_get_string_from_id(2169), i >> 1, i & 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } - - h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); - for (i = 0; i < 16; i++) - { - wsprintf(lptsTemp, win_language_get_string_from_id(2088), i); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } - - h = GetDlgItem(hdlg, IDC_COMBO_HD_LUN); - for (i = 0; i < 8; i++) - { - wsprintf(lptsTemp, win_language_get_string_from_id(2088), i); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } - - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); - for (i = 0; i < 8; i++) - { - wsprintf(lptsTemp, win_language_get_string_from_id(2169), i >> 1, i & 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } - - free(lptsTemp); -} - -static void recalc_location_controls(HWND hdlg, int is_add_dlg) -{ - int i = 0; - HWND h; - - int bus = 0; - - for (i = 1799; i < 1803; i++) - { - h = GetDlgItem(hdlg, i); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - } - - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - - h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - - h = GetDlgItem(hdlg, IDC_COMBO_HD_LUN); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - - if ((hd_listview_items > 0) || is_add_dlg) - { - h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); - bus = SendMessage(h, CB_GETCURSEL, 0, 0); - - switch(bus) - { - case 0: /* MFM/RLL */ - h = GetDlgItem(hdlg, 1799); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdc.mfm_channel : temp_hdc[hdlv_current_sel].mfm_channel, 0); - break; - case 1: /* IDE (PIO-only) */ - case 2: /* IDE (PIO and DMA) */ - h = GetDlgItem(hdlg, 1802); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdc.ide_channel : temp_hdc[hdlv_current_sel].ide_channel, 0); - break; - case 3: /* SCSI */ - h = GetDlgItem(hdlg, 1800); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - h = GetDlgItem(hdlg, 1801); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - - h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdc.scsi_id : temp_hdc[hdlv_current_sel].scsi_id, 0); - - h = GetDlgItem(hdlg, IDC_COMBO_HD_LUN); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdc.scsi_lun : temp_hdc[hdlv_current_sel].scsi_lun, 0); - break; - } - } - - if ((hd_listview_items == 0) && !is_add_dlg) - { - h = GetDlgItem(hdlg, 1798); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - - h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); - EnableWindow(h, FALSE); ShowWindow(h, SW_HIDE); - } - else - { - h = GetDlgItem(hdlg, 1798); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - - h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - } -} - -static void recalc_next_free_id(HWND hdlg) -{ - HWND h; - int i; - - int c_mfm = 0; - int c_ide_pio = 0; - int c_ide_dma = 0; - int c_scsi = 0; - int enable_add = 0; - - next_free_id = -1; - - for (i = 0; i < HDC_NUM; i++) - { - if (temp_hdc[i].bus == 1) - { - c_mfm++; - } - else if (temp_hdc[i].bus == 2) - { - c_ide_pio++; - } - else if (temp_hdc[i].bus == 3) - { - c_ide_dma++; - } - else if (temp_hdc[i].bus == 4) - { - c_scsi++; - } - } - - for (i = 0; i < HDC_NUM; i++) - { - if (temp_hdc[i].bus == 0) - { - next_free_id = i; - break; - } - } - - /* pclog("Next free ID: %i\n", next_free_id); */ - - enable_add = enable_add || (next_free_id >= 0); - /* pclog("Enable add: %i\n", enable_add); */ - enable_add = enable_add && ((c_mfm < MFM_NUM) || (c_ide_pio < IDE_NUM) || (c_ide_dma < IDE_NUM) || (c_scsi < SCSI_NUM)); - /* pclog("Enable add: %i\n", enable_add); */ - - h = GetDlgItem(hdlg, IDC_BUTTON_HDD_ADD_NEW); - - if (enable_add) - { - EnableWindow(h, TRUE); - } - else - { - EnableWindow(h, FALSE); - } - - h = GetDlgItem(hdlg, IDC_BUTTON_HDD_ADD); - - if (enable_add) - { - EnableWindow(h, TRUE); - } - else - { - EnableWindow(h, FALSE); - } - - h = GetDlgItem(hdlg, IDC_BUTTON_HDD_REMOVE); - - if ((c_mfm == 0) && (c_ide_pio == 0) && (c_ide_dma == 0) && (c_scsi == 0)) - { - EnableWindow(h, FALSE); - } - else - { - EnableWindow(h, TRUE); - } -} - -static void win_settings_hard_disks_update_item(HWND hwndList, int i, int column) -{ - LVITEM lvI; - WCHAR szText[256]; - - lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; - lvI.stateMask = lvI.iSubItem = lvI.state = 0; - - lvI.iSubItem = column; - lvI.iItem = i; - - if (column == 0) - { - switch(temp_hdc[i].bus) - { - case 1: - wsprintf(szText, win_language_get_string_from_id(2156), temp_hdc[i].mfm_channel >> 1, temp_hdc[i].mfm_channel & 1); - break; - case 2: - wsprintf(szText, win_language_get_string_from_id(2195), temp_hdc[i].ide_channel >> 1, temp_hdc[i].ide_channel & 1); - break; - case 3: - wsprintf(szText, win_language_get_string_from_id(2157), temp_hdc[i].ide_channel >> 1, temp_hdc[i].ide_channel & 1); - break; - case 4: - wsprintf(szText, win_language_get_string_from_id(2158), temp_hdc[i].scsi_id, temp_hdc[i].scsi_lun); - break; - } - lvI.pszText = szText; - lvI.iImage = temp_hdc[i].bus - 1; - } - else if (column == 1) - { - lvI.pszText = temp_hdd_fn[i]; - lvI.iImage = 0; - } - else if (column == 2) - { - wsprintf(szText, win_language_get_string_from_id(2088), temp_hdc[i].tracks); - lvI.pszText = szText; - lvI.iImage = 0; - } - else if (column == 3) - { - wsprintf(szText, win_language_get_string_from_id(2088), temp_hdc[i].hpc); - lvI.pszText = szText; - lvI.iImage = 0; - } - else if (column == 4) - { - wsprintf(szText, win_language_get_string_from_id(2088), temp_hdc[i].spt); - lvI.pszText = szText; - lvI.iImage = 0; - } - else if (column == 5) - { - wsprintf(szText, win_language_get_string_from_id(2088), (temp_hdc[i].tracks * temp_hdc[i].hpc * temp_hdc[i].spt) >> 11); - lvI.pszText = szText; - lvI.iImage = 0; - } - - if (ListView_SetItem(hwndList, &lvI) == -1) - { - return; - } -} - -static BOOL win_settings_hard_disks_recalc_list(HWND hwndList) -{ - LVITEM lvI; - int i = 0; - int j = 0; - WCHAR szText[256]; - - hd_listview_items = 0; - hdlv_current_sel = -1; - - ListView_DeleteAllItems(hwndList); - - lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; - lvI.stateMask = lvI.iSubItem = lvI.state = 0; - - for (i = 0; i < HDC_NUM; i++) - { - if (temp_hdc[i].bus > 0) - { - hdc_id_to_listview_index[i] = j; - lvI.iSubItem = 0; - switch(temp_hdc[i].bus) - { - case 1: - wsprintf(szText, win_language_get_string_from_id(2156), temp_hdc[i].mfm_channel >> 1, temp_hdc[i].mfm_channel & 1); - break; - case 2: - wsprintf(szText, win_language_get_string_from_id(2195), temp_hdc[i].ide_channel >> 1, temp_hdc[i].ide_channel & 1); - break; - case 3: - wsprintf(szText, win_language_get_string_from_id(2157), temp_hdc[i].ide_channel >> 1, temp_hdc[i].ide_channel & 1); - break; - case 4: - wsprintf(szText, win_language_get_string_from_id(2158), temp_hdc[i].scsi_id, temp_hdc[i].scsi_lun); - break; - } - lvI.pszText = szText; - lvI.iItem = j; - lvI.iImage = temp_hdc[i].bus - 1; - - if (ListView_InsertItem(hwndList, &lvI) == -1) - { - return FALSE; - } - - lvI.iSubItem = 1; - lvI.pszText = temp_hdd_fn[i]; - lvI.iItem = j; - lvI.iImage = 0; - - if (ListView_SetItem(hwndList, &lvI) == -1) - { - return FALSE; - } - - lvI.iSubItem = 2; - wsprintf(szText, win_language_get_string_from_id(2088), temp_hdc[i].tracks); - lvI.pszText = szText; - lvI.iItem = j; - lvI.iImage = 0; - - if (ListView_SetItem(hwndList, &lvI) == -1) - { - return FALSE; - } - - lvI.iSubItem = 3; - wsprintf(szText, win_language_get_string_from_id(2088), temp_hdc[i].hpc); - lvI.pszText = szText; - lvI.iItem = j; - lvI.iImage = 0; - - if (ListView_SetItem(hwndList, &lvI) == -1) - { - return FALSE; - } - - lvI.iSubItem = 4; - wsprintf(szText, win_language_get_string_from_id(2088), temp_hdc[i].spt); - lvI.pszText = szText; - lvI.iItem = j; - lvI.iImage = 0; - - if (ListView_SetItem(hwndList, &lvI) == -1) - { - return FALSE; - } - - lvI.iSubItem = 5; - wsprintf(szText, win_language_get_string_from_id(2088), (temp_hdc[i].tracks * temp_hdc[i].hpc * temp_hdc[i].spt) >> 11); - lvI.pszText = szText; - lvI.iItem = j; - lvI.iImage = 0; - - if (ListView_SetItem(hwndList, &lvI) == -1) - { - return FALSE; - } - - j++; - } - else - { - hdc_id_to_listview_index[i] = -1; - } - } - - hd_listview_items = j; - - return TRUE; -} - -/* Icon, Bus, File, C, H, S, Size */ -#define C_COLUMNS_HARD_DISKS 6 - -static BOOL win_settings_hard_disks_init_columns(HWND hwndList) -{ - LVCOLUMN lvc; - int iCol; - - lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; - - for (iCol = 0; iCol < C_COLUMNS_HARD_DISKS; iCol++) - { - lvc.iSubItem = iCol; - lvc.pszText = win_language_get_string_from_id(2082 + iCol); - - switch(iCol) - { - - case 0: /* Bus */ - lvc.cx = 135; - lvc.fmt = LVCFMT_LEFT; - break; - case 2: /* Cylinders */ - lvc.cx = 41; - lvc.fmt = LVCFMT_RIGHT; - break; - case 3: /* Heads */ - case 4: /* Sectors */ - lvc.cx = 25; - lvc.fmt = LVCFMT_RIGHT; - break; - case 1: /* File */ - lvc.cx = 150; - lvc.fmt = LVCFMT_LEFT; - break; - case 5: /* Size (MB) 8 */ - lvc.cx = 41; - lvc.fmt = LVCFMT_RIGHT; - break; - } - - if (ListView_InsertColumn(hwndList, iCol, &lvc) == -1) - { - return FALSE; - } - } - - return TRUE; -} - -static void get_edit_box_contents(HWND hdlg, int id, uint64_t *val) -{ - HWND h; - WCHAR szText[256]; - char stransi[256]; - - h = GetDlgItem(hdlg, id); - SendMessage(h, WM_GETTEXT, 255, (LPARAM) szText); - wcstombs(stransi, szText, (wcslen(szText) * 2) + 2); - sscanf(stransi, "%" PRIu64, val); -} - -static void get_combo_box_selection(HWND hdlg, int id, uint64_t *val) -{ - HWND h; - - h = GetDlgItem(hdlg, id); - *val = SendMessage(h, CB_GETCURSEL, 0, 0); -} - -static void set_edit_box_contents(HWND hdlg, int id, uint64_t val) -{ - HWND h; - WCHAR szText[256]; - - h = GetDlgItem(hdlg, id); - wsprintf(szText, win_language_get_string_from_id(2160), val); - SendMessage(h, WM_SETTEXT, (WPARAM) wcslen(szText), (LPARAM) szText); -} - -int hard_disk_added = 0; -int max_spt = 63; - -int no_update = 0; - -int existing = 0; -uint64_t selection = 127; - -uint64_t spt, hpc, tracks, size; -wchar_t hd_file_name[512]; - -static int hdconf_initialize_hdt_combo(HWND hdlg) -{ - HWND h; - int i = 0; - uint64_t temp_size = 0; - uint64_t size_mb = 0; - WCHAR szText[256]; - - selection = 127; - - h = GetDlgItem(hdlg, IDC_COMBO_HD_TYPE); - for (i = 0; i < 127; i++) - { - temp_size = hdt[i][0] * hdt[i][1] * hdt[i][2]; - size_mb = temp_size >> 11; - wsprintf(szText, win_language_get_string_from_id(2171), size_mb, hdt[i][0], hdt[i][1], hdt[i][2]); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) szText); - if ((tracks == hdt[i][0]) && (hpc == hdt[i][1]) && (spt == hdt[i][2])) - { - selection = i; - } - } - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2170)); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2187)); - SendMessage(h, CB_SETCURSEL, selection, 0); - return selection; -} - -static void recalc_selection(HWND hdlg) -{ - HWND h; - int i = 0; - - selection = 127; - h = GetDlgItem(hdlg, IDC_COMBO_HD_TYPE); - for (i = 0; i < 127; i++) - { - if ((tracks == hdt[i][0]) && (hpc == hdt[i][1]) && (spt == hdt[i][2])) - { - selection = i; - } - } - if ((selection == 127) && (hpc == 16) && (spt == 63)) - { - selection = 128; - } - SendMessage(h, CB_SETCURSEL, selection, 0); -} - -static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - HWND h; - int64_t i = 0; - int bus; - uint64_t temp; - WCHAR szText[256]; - FILE *f; - uint32_t sector_size = 512; - uint32_t zero = 0; - uint32_t base = 0x1000; - uint64_t signature = 0xD778A82044445459ll; - char buf[512]; - - switch (message) - { - case WM_INITDIALOG: - memset(hd_file_name, 0, 512); - - SetWindowText(hdlg, win_language_get_string_from_id(existing ? 2197 : 2196)); - - no_update = 1; - spt = existing ? 0 : 17; - set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt); - hpc = existing ? 0 : 15; - set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, hpc); - tracks = existing ? 0 : 1023; - set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, tracks); - size = (tracks * hpc * spt) << 9; - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, size >> 20); - hdconf_initialize_hdt_combo(hdlg); - if (existing) - { - h = GetDlgItem(hdlg, IDC_EDIT_HD_SPT); - EnableWindow(h, FALSE); - h = GetDlgItem(hdlg, IDC_EDIT_HD_HPC); - EnableWindow(h, FALSE); - h = GetDlgItem(hdlg, IDC_EDIT_HD_CYL); - EnableWindow(h, FALSE); - h = GetDlgItem(hdlg, IDC_EDIT_HD_SIZE); - EnableWindow(h, FALSE); - h = GetDlgItem(hdlg, IDC_COMBO_HD_TYPE); - EnableWindow(h, FALSE); - } - add_locations(hdlg); - h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); - SendMessage(h, CB_SETCURSEL, 1, 0); - recalc_location_controls(hdlg, 1); - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); - SendMessage(h, CB_SETCURSEL, 0, 0); - h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); - SendMessage(h, CB_SETCURSEL, 0, 0); - h = GetDlgItem(hdlg, IDC_COMBO_HD_LUN); - SendMessage(h, CB_SETCURSEL, 0, 0); - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); - SendMessage(h, CB_SETCURSEL, 0, 0); - h = GetDlgItem(hdlg, IDC_EDIT_HD_FILE_NAME); - EnableWindow(h, FALSE); - no_update = 0; - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) - { - case IDOK: - if (wcslen(hd_file_name) == 0) - { - msgbox_error(hwndParentDialog, 2056); - return TRUE; - } - - get_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, &(temp_hdc[next_free_id].spt)); - get_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, &(temp_hdc[next_free_id].hpc)); - get_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, &(temp_hdc[next_free_id].tracks)); - h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); - temp_hdc[next_free_id].bus = SendMessage(h, CB_GETCURSEL, 0, 0) + 1; - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); - temp_hdc[next_free_id].mfm_channel = SendMessage(h, CB_GETCURSEL, 0, 0); - h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); - temp_hdc[next_free_id].scsi_id = SendMessage(h, CB_GETCURSEL, 0, 0); - h = GetDlgItem(hdlg, IDC_COMBO_HD_LUN); - temp_hdc[next_free_id].scsi_lun = SendMessage(h, CB_GETCURSEL, 0, 0); - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); - temp_hdc[next_free_id].ide_channel = SendMessage(h, CB_GETCURSEL, 0, 0); - memset(temp_hdd_fn[next_free_id], 0, 1024); - memcpy(temp_hdd_fn[next_free_id], hd_file_name, (wcslen(hd_file_name) << 1) + 2); - - sector_size = 512; - - if (!existing && (wcslen(hd_file_name) > 0)) - { - f = _wfopen(hd_file_name, L"wb"); - - if (image_is_hdi(hd_file_name)) - { - if (size >= 0x100000000ll) - { - fclose(f); - msgbox_error(hwndParentDialog, 2058); - return TRUE; - } - - fwrite(&zero, 1, 4, f); /* 00000000: Zero/unknown */ - fwrite(&zero, 1, 4, f); /* 00000004: Zero/unknown */ - fwrite(&base, 1, 4, f); /* 00000008: Offset at which data starts */ - fwrite(&size, 1, 4, f); /* 0000000C: Full size of the data (32-bit) */ - fwrite(§or_size, 1, 4, f); /* 00000010: Sector size in bytes */ - fwrite(&spt, 1, 4, f); /* 00000014: Sectors per cylinder */ - fwrite(&hpc, 1, 4, f); /* 00000018: Heads per cylinder */ - fwrite(&tracks, 1, 4, f); /* 0000001C: Cylinders */ - - for (i = 0; i < 0x3f8; i++) - { - fwrite(&zero, 1, 4, f); - } - } - else if (image_is_hdx(hd_file_name, 0)) - { - if (size > 0xffffffffffffffffll) - { - fclose(f); - msgbox_error(hwndParentDialog, 2163); - return TRUE; - } - - fwrite(&signature, 1, 8, f); /* 00000000: Signature */ - fwrite(&size, 1, 8, f); /* 00000008: Full size of the data (64-bit) */ - fwrite(§or_size, 1, 4, f); /* 00000010: Sector size in bytes */ - fwrite(&spt, 1, 4, f); /* 00000014: Sectors per cylinder */ - fwrite(&hpc, 1, 4, f); /* 00000018: Heads per cylinder */ - fwrite(&tracks, 1, 4, f); /* 0000001C: Cylinders */ - fwrite(&zero, 1, 4, f); /* 00000020: [Translation] Sectors per cylinder */ - fwrite(&zero, 1, 4, f); /* 00000004: [Translation] Heads per cylinder */ - } - - memset(buf, 0, 512); - size >>= 9; - for (i = 0; i < size; i++) - { - fwrite(buf, 512, 1, f); - } - - fclose(f); - msgbox_info(hwndParentDialog, 2059); - } - - hard_disk_added = 1; - EndDialog(hdlg, 0); - return TRUE; - - case IDCANCEL: - hard_disk_added = 0; - EndDialog(hdlg, 0); - return TRUE; - - case IDC_CFILE: - if (!file_dlg_w(hdlg, win_language_get_string_from_id(2172), L"", !existing)) - { - if (!existing) - { - f = _wfopen(wopenfilestring, L"rb"); - if (f != NULL) - { - fclose(f); - if (msgbox_question(ghwnd, 2178) != IDYES) - { - return FALSE; - } - } - } - - f = _wfopen(wopenfilestring, existing ? L"rb" : L"wb"); - if (f == NULL) - { - msgbox_error(hwndParentDialog, existing ? 2060 : 2057); - return TRUE; - } - if (existing) - { - if (image_is_hdi(wopenfilestring) || image_is_hdx(wopenfilestring, 1)) - { - fseeko64(f, 0x10, SEEK_SET); - fread(§or_size, 1, 4, f); - if (sector_size != 512) - { - msgbox_error(hwndParentDialog, 2061); - fclose(f); - return TRUE; - } - spt = hpc = tracks = 0; - fread(&spt, 1, 4, f); - fread(&hpc, 1, 4, f); - fread(&tracks, 1, 4, f); - } - else - { - fseeko64(f, 0, SEEK_END); - size = ftello64(f); - fclose(f); - if (((size % 17) == 0) && (size <= 133693440)) - { - spt = 17; - if (size <= 26738688) - { - hpc = 4; - } - else if (size <= 53477376) - { - hpc = 6; - } - else if (size <= 71303168) - { - hpc = 8; - } - else - { - hpc = 15; - } - } - else - { - spt = 63; - hpc = 16; - } - - tracks = ((size >> 9) / hpc) / spt; - } - - no_update = 1; - - set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt); - set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, hpc); - set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, tracks); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, size >> 20); - recalc_selection(hdlg); - - h = GetDlgItem(hdlg, IDC_EDIT_HD_SPT); - EnableWindow(h, TRUE); - h = GetDlgItem(hdlg, IDC_EDIT_HD_HPC); - EnableWindow(h, TRUE); - h = GetDlgItem(hdlg, IDC_EDIT_HD_CYL); - EnableWindow(h, TRUE); - h = GetDlgItem(hdlg, IDC_EDIT_HD_SIZE); - EnableWindow(h, TRUE); - h = GetDlgItem(hdlg, IDC_COMBO_HD_TYPE); - EnableWindow(h, TRUE); - - no_update = 0; - } - else - { - fclose(f); - } - } - - h = GetDlgItem(hdlg, IDC_EDIT_HD_FILE_NAME); - SendMessage(h, WM_SETTEXT, 0, (LPARAM) wopenfilestring); - memcpy(hd_file_name, wopenfilestring, (wcslen(wopenfilestring) << 1) + 2); - - return TRUE; - - case IDC_EDIT_HD_CYL: - if (no_update) - { - return FALSE; - } - - no_update = 1; - get_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, &temp); - if (temp != tracks) - { - tracks = temp; - size = (tracks * hpc * spt) << 9; - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, size >> 20); - recalc_selection(hdlg); - } - no_update = 0; - break; - - case IDC_EDIT_HD_HPC: - if (no_update) - { - return FALSE; - } - - no_update = 1; - get_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, &temp); - if (temp != hpc) - { - hpc = temp; - size = (tracks * hpc * spt) << 9; - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, size >> 20); - recalc_selection(hdlg); - } - no_update = 0; - break; - - case IDC_EDIT_HD_SPT: - if (no_update) - { - return FALSE; - } - - no_update = 1; - get_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, &temp); - if (temp != spt) - { - spt = temp; - size = (tracks * hpc * spt) << 9; - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, size >> 20); - recalc_selection(hdlg); - } - no_update = 0; - break; - - case IDC_EDIT_HD_SIZE: - if (no_update) - { - return FALSE; - } - - no_update = 1; - get_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, &temp); - if (temp != (size >> 20)) - { - size = temp << 20; - tracks = ((size >> 9) / hpc) / spt; - set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, tracks); - recalc_selection(hdlg); - } - no_update = 0; - break; - - case IDC_COMBO_HD_TYPE: - if (no_update) - { - return FALSE; - } - - no_update = 1; - get_combo_box_selection(hdlg, IDC_COMBO_HD_TYPE, &temp); - if ((temp != selection) && (temp != 127) && (temp != 128)) - { - selection = temp; - tracks = hdt[selection][0]; - hpc = hdt[selection][1]; - spt = hdt[selection][2]; - size = (tracks * hpc * spt) << 9; - set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, tracks); - set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, hpc); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, size >> 20); - } - else if ((temp != selection) && (temp == 127)) - { - selection = temp; - } - else if ((temp != selection) && (temp == 128)) - { - selection = temp; - hpc = 16; - spt = 63; - size = (tracks * hpc * spt) << 9; - set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, hpc); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, size >> 20); - } - no_update = 0; - break; - - case IDC_COMBO_HD_BUS: - if (no_update) - { - return FALSE; - } - - no_update = 1; - recalc_location_controls(hdlg, 1); - h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); - bus = SendMessage(h, CB_GETCURSEL, 0, 0); - get_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, &spt); - max_spt = (bus == 2) ? 99 : 63; - if (spt > max_spt) - { - spt = max_spt; - size = (tracks * hpc * spt) << 9; - set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, 17); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (size >> 20)); - recalc_selection(hdlg); - } - no_update = 0; - break; - } - - return FALSE; - } - - return FALSE; -} - -void hard_disk_add_open(HWND hwnd, int is_existing) -{ - BOOL ret; - - existing = !!is_existing; - hard_disk_added = 0; - ret = DialogBox(hinstance, (LPCWSTR) CONFIGUREDLG_HARD_DISKS_ADD, hwnd, win_settings_hard_disks_add_proc); -} - -int ignore_change = 0; - -static BOOL CALLBACK win_settings_hard_disks_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - HWND h; - int old_sel = 0; - - switch (message) - { - case WM_INITDIALOG: - ignore_change = 1; - - normalize_hd_list(); /* Normalize the hard disks so that non-disabled hard disks start from index 0, and so they are contiguous. - This will cause an emulator reset prompt on the first opening of this category with a messy hard disk list - (which can only happen by manually editing the configuration file). */ - h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); - win_settings_hard_disks_init_columns(h); - win_settings_hard_disks_image_list_init(h); - win_settings_hard_disks_recalc_list(h); - recalc_next_free_id(hdlg); - add_locations(hdlg); - if (hd_listview_items > 0) - { - ListView_SetItemState(h, 0, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); - hdlv_current_sel = 0; - h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); - SendMessage(h, CB_SETCURSEL, temp_hdc[0].bus - 1, 0); - } - else - { - hdlv_current_sel = -1; - } - recalc_location_controls(hdlg, 0); - - ignore_change = 0; - return TRUE; - - case WM_NOTIFY: - if ((hd_listview_items == 0) || ignore_change) - { - return FALSE; - } - - if ((((LPNMHDR)lParam)->code == LVN_ITEMCHANGED) && (((LPNMHDR)lParam)->idFrom == IDC_LIST_HARD_DISKS)) - { - old_sel = hdlv_current_sel; - hdlv_current_sel = get_selected_hard_disk(hdlg); - if (hdlv_current_sel == old_sel) - { - return FALSE; - } - else if (hdlv_current_sel == -1) - { - ignore_change = 1; - hdlv_current_sel = old_sel; - ListView_SetItemState(h, hdlv_current_sel, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); - ignore_change = 0; - return FALSE; - } - ignore_change = 1; - h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); - SendMessage(h, CB_SETCURSEL, temp_hdc[hdlv_current_sel].bus - 1, 0); - recalc_location_controls(hdlg, 0); - ignore_change = 0; - } - break; - - case WM_COMMAND: - switch (LOWORD(wParam)) - { - case IDC_COMBO_HD_BUS: - if (ignore_change) - { - return FALSE; - } - - ignore_change = 1; - recalc_location_controls(hdlg, 0); - h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); - temp_hdc[hdlv_current_sel].bus = SendMessage(h, CB_GETCURSEL, 0, 0) + 1; - h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); - win_settings_hard_disks_update_item(h, hdlv_current_sel, 0); - ignore_change = 0; - return FALSE; - - case IDC_COMBO_HD_CHANNEL: - if (ignore_change) - { - return FALSE; - } - - ignore_change = 1; - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); - temp_hdc[hdlv_current_sel].mfm_channel = SendMessage(h, CB_GETCURSEL, 0, 0); - h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); - win_settings_hard_disks_update_item(h, hdlv_current_sel, 0); - ignore_change = 0; - return FALSE; - - case IDC_COMBO_HD_CHANNEL_IDE: - if (ignore_change) - { - return FALSE; - } - - ignore_change = 1; - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); - temp_hdc[hdlv_current_sel].ide_channel = SendMessage(h, CB_GETCURSEL, 0, 0); - h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); - win_settings_hard_disks_update_item(h, hdlv_current_sel, 0); - ignore_change = 0; - return FALSE; - - case IDC_COMBO_HD_ID: - if (ignore_change) - { - return FALSE; - } - - ignore_change = 1; - h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); - temp_hdc[hdlv_current_sel].scsi_id = SendMessage(h, CB_GETCURSEL, 0, 0); - h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); - win_settings_hard_disks_update_item(h, hdlv_current_sel, 0); - ignore_change = 0; - return FALSE; - - case IDC_COMBO_HD_LUN: - if (ignore_change) - { - return FALSE; - } - - ignore_change = 1; - h = GetDlgItem(hdlg, IDC_COMBO_HD_LUN); - temp_hdc[hdlv_current_sel].scsi_lun = SendMessage(h, CB_GETCURSEL, 0, 0); - h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); - win_settings_hard_disks_update_item(h, hdlv_current_sel, 0); - ignore_change = 0; - return FALSE; - - case IDC_BUTTON_HDD_ADD: - hard_disk_add_open(hdlg, 1); - if (hard_disk_added) - { - ignore_change = 1; - h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); - win_settings_hard_disks_recalc_list(h); - recalc_next_free_id(hdlg); - ignore_change = 0; - } - return FALSE; - - case IDC_BUTTON_HDD_ADD_NEW: - hard_disk_add_open(hdlg, 0); - if (hard_disk_added) - { - ignore_change = 1; - h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); - win_settings_hard_disks_recalc_list(h); - recalc_next_free_id(hdlg); - ignore_change = 0; - } - return FALSE; - - case IDC_BUTTON_HDD_REMOVE: - memcpy(temp_hdd_fn[hdlv_current_sel], L"", 4); - temp_hdc[hdlv_current_sel].bus = 0; /* Only set the bus to zero, the list normalize code below will take care of turning this entire entry to a complete zero. */ - normalize_hd_list(); /* Normalize the hard disks so that non-disabled hard disks start from index 0, and so they are contiguous. */ - ignore_change = 1; - h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); - win_settings_hard_disks_recalc_list(h); - recalc_next_free_id(hdlg); - if (hd_listview_items > 0) - { - ListView_SetItemState(h, 0, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); - hdlv_current_sel = 0; - h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); - SendMessage(h, CB_SETCURSEL, temp_hdc[0].bus - 1, 0); - } - else - { - hdlv_current_sel = -1; - } - recalc_location_controls(hdlg, 0); - ignore_change = 0; - return FALSE; - } - - default: - return FALSE; - } - - return FALSE; -} - -int fdlv_current_sel; -int cdlv_current_sel; - -static int combo_id_to_string_id(int combo_id) -{ - switch (combo_id) - { - case 0: /* Disabled */ - default: - return 2151; - break; - case 2: /* Atapi (PIO-only) */ - return 2189; - break; - case 3: /* Atapi (PIA and DMA) */ - return 2190; - break; - case 4: /* SCSI */ - return 2168; - break; - } -} - -static int combo_id_to_format_string_id(int combo_id) -{ - switch (combo_id) - { - case 0: /* Disabled */ - default: - return 2151; - break; - case 2: /* Atapi (PIO-only) */ - return 2191; - break; - case 3: /* Atapi (PIA and DMA) */ - return 2192; - break; - case 4: /* SCSI */ - return 2158; - break; - } -} - -static BOOL win_settings_floppy_drives_image_list_init(HWND hwndList) -{ - HICON hiconItem; - HIMAGELIST hSmall; - - int i = 0; - - hSmall = ImageList_Create(GetSystemMetrics(SM_CXSMICON), - GetSystemMetrics(SM_CYSMICON), - ILC_MASK | ILC_COLOR32, 1, 1); - - for (i = 0; i < 14; i++) - { - hiconItem = LoadIcon(hinstance, (LPCWSTR) fdd_type_to_icon(i)); - ImageList_AddIcon(hSmall, hiconItem); - DestroyIcon(hiconItem); - } - - ListView_SetImageList(hwndList, hSmall, LVSIL_SMALL); - - return TRUE; -} - -static BOOL win_settings_cdrom_drives_image_list_init(HWND hwndList) -{ - HICON hiconItem; - HIMAGELIST hSmall; - - int i = 0; - int j = 0; - - hSmall = ImageList_Create(GetSystemMetrics(SM_CXSMICON), - GetSystemMetrics(SM_CYSMICON), - ILC_MASK | ILC_COLOR32, 1, 1); - - hiconItem = LoadIcon(hinstance, (LPCWSTR) 514); - ImageList_AddIcon(hSmall, hiconItem); - DestroyIcon(hiconItem); - - hiconItem = LoadIcon(hinstance, (LPCWSTR) 160); - ImageList_AddIcon(hSmall, hiconItem); - DestroyIcon(hiconItem); - - hiconItem = LoadIcon(hinstance, (LPCWSTR) 162); - ImageList_AddIcon(hSmall, hiconItem); - DestroyIcon(hiconItem); - - hiconItem = LoadIcon(hinstance, (LPCWSTR) 164); - ImageList_AddIcon(hSmall, hiconItem); - DestroyIcon(hiconItem); - - ListView_SetImageList(hwndList, hSmall, LVSIL_SMALL); - - return TRUE; -} - -static BOOL win_settings_floppy_drives_recalc_list(HWND hwndList) -{ - LVITEM lvI; - int i = 0; - char s[256]; - WCHAR szText[256]; - - lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; - lvI.stateMask = lvI.iSubItem = lvI.state = 0; - - for (i = 0; i < 4; i++) - { - if (temp_fdd_types[i] > 0) - { - strcpy(s, fdd_getname(temp_fdd_types[i])); - mbstowcs(szText, s, strlen(s) + 1); - lvI.pszText = szText; - } - else - { - lvI.pszText = win_language_get_string_from_id(2151); - } - lvI.iItem = i; - lvI.iImage = temp_fdd_types[i]; - - if (ListView_InsertItem(hwndList, &lvI) == -1) - return FALSE; - } - - return TRUE; -} - -static BOOL win_settings_cdrom_drives_recalc_list(HWND hwndList) -{ - LVITEM lvI; - int i = 0; - char s[256]; - WCHAR szText[256]; - int bid = 0; - int fsid = 0; - - lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; - lvI.stateMask = lvI.iSubItem = lvI.state = 0; - - for (i = 0; i < 4; i++) - { - fsid = combo_id_to_format_string_id(temp_cdrom_drives[i].bus_type); - - switch (temp_cdrom_drives[i].bus_type) - { - case 0: - default: - lvI.pszText = win_language_get_string_from_id(fsid); - break; - case 2: - case 3: - wsprintf(szText, win_language_get_string_from_id(fsid), temp_cdrom_drives[i].ide_channel >> 1, temp_cdrom_drives[i].ide_channel & 1); - lvI.pszText = szText; - break; - case 4: - wsprintf(szText, win_language_get_string_from_id(fsid), temp_cdrom_drives[i].scsi_device_id, temp_cdrom_drives[i].scsi_device_lun); - lvI.pszText = szText; - break; - } - - lvI.iItem = i; - - if (temp_cdrom_drives[i].bus_type) - { - lvI.iImage = temp_cdrom_drives[i].bus_type - 1; - } - else - { - lvI.iImage = 0; - } - - if (ListView_InsertItem(hwndList, &lvI) == -1) - return FALSE; - } - - return TRUE; -} - -static BOOL win_settings_floppy_drives_init_columns(HWND hwndList) -{ - LVCOLUMN lvc; - - lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; - - lvc.iSubItem = 0; - lvc.pszText = win_language_get_string_from_id(2188); - - lvc.cx = 392; - lvc.fmt = LVCFMT_LEFT; - - if (ListView_InsertColumn(hwndList, 0, &lvc) == -1) - { - return FALSE; - } - - return TRUE; -} - -static BOOL win_settings_cdrom_drives_init_columns(HWND hwndList) -{ - LVCOLUMN lvc; - - lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; - - lvc.iSubItem = 0; - lvc.pszText = win_language_get_string_from_id(2082); - - lvc.cx = 392; - lvc.fmt = LVCFMT_LEFT; - - if (ListView_InsertColumn(hwndList, 0, &lvc) == -1) - { - return FALSE; - } - - return TRUE; -} - -static int get_selected_floppy_drive(HWND hdlg) -{ - int floppy_drive = -1; - int i, j = 0; - HWND h; - - for (i = 0; i < 6; i++) - { - h = GetDlgItem(hdlg, IDC_LIST_FLOPPY_DRIVES); - j = ListView_GetItemState(h, i, LVIS_SELECTED); - if (j) - { - floppy_drive = i; - } - } - - return floppy_drive; -} - -static int get_selected_cdrom_drive(HWND hdlg) -{ - int cd_drive = -1; - int i, j = 0; - HWND h; - - for (i = 0; i < 6; i++) - { - h = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); - j = ListView_GetItemState(h, i, LVIS_SELECTED); - if (j) - { - cd_drive = i; - } - } - - return cd_drive; -} - -static void win_settings_floppy_drives_update_item(HWND hwndList, int i) -{ - LVITEM lvI; - char s[256]; - WCHAR szText[256]; - - lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; - lvI.stateMask = lvI.iSubItem = lvI.state = 0; - - lvI.iSubItem = 0; - lvI.iItem = i; - - if (temp_fdd_types[i] > 0) - { - strcpy(s, fdd_getname(temp_fdd_types[i])); - mbstowcs(szText, s, strlen(s) + 1); - lvI.pszText = szText; - } - else - { - lvI.pszText = win_language_get_string_from_id(2151); - } - lvI.iImage = temp_fdd_types[i]; - - if (ListView_SetItem(hwndList, &lvI) == -1) - { - return; - } -} - -static void win_settings_cdrom_drives_update_item(HWND hwndList, int i) -{ - LVITEM lvI; - char s[256]; - WCHAR szText[256]; - int bid; - int fsid; - - lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; - lvI.stateMask = lvI.iSubItem = lvI.state = 0; - - lvI.iSubItem = 0; - lvI.iItem = i; - - fsid = combo_id_to_format_string_id(temp_cdrom_drives[i].bus_type); - - switch (temp_cdrom_drives[i].bus_type) - { - case 0: - default: - lvI.pszText = win_language_get_string_from_id(fsid); - break; - case 2: - case 3: - wsprintf(szText, win_language_get_string_from_id(fsid), temp_cdrom_drives[i].ide_channel >> 1, temp_cdrom_drives[i].ide_channel & 1); - lvI.pszText = szText; - break; - case 4: - wsprintf(szText, win_language_get_string_from_id(fsid), temp_cdrom_drives[i].scsi_device_id, temp_cdrom_drives[i].scsi_device_lun); - lvI.pszText = szText; - break; - } - - if (temp_cdrom_drives[i].bus_type) - { - lvI.iImage = temp_cdrom_drives[i].bus_type - 1; - } - else - { - lvI.iImage = 0; - } - - if (ListView_SetItem(hwndList, &lvI) == -1) - { - return; - } -} - -static void cdrom_add_locations(HWND hdlg) -{ - LPTSTR lptsTemp; - HWND h; - int i = 0; - - lptsTemp = (LPTSTR) malloc(512); - - h = GetDlgItem(hdlg, IDC_COMBO_CD_BUS); - for (i = 1; i < 5; i++) - { - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(combo_id_to_string_id(i))); - } - - h = GetDlgItem(hdlg, IDC_COMBO_CD_ID); - for (i = 0; i < 16; i++) - { - wsprintf(lptsTemp, win_language_get_string_from_id(2088), i); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } - - h = GetDlgItem(hdlg, IDC_COMBO_CD_LUN); - for (i = 0; i < 8; i++) - { - wsprintf(lptsTemp, win_language_get_string_from_id(2088), i); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } - - h = GetDlgItem(hdlg, IDC_COMBO_CD_CHANNEL_IDE); - for (i = 0; i < 8; i++) - { - wsprintf(lptsTemp, win_language_get_string_from_id(2169), i >> 1, i & 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } - - free(lptsTemp); -} -static void cdrom_recalc_location_controls(HWND hdlg) -{ - int i = 0; - HWND h; - - int bus = temp_cdrom_drives[cdlv_current_sel].bus_type; - - for (i = 1800; i < 1803; i++) - { - h = GetDlgItem(hdlg, i); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - } - - h = GetDlgItem(hdlg, IDC_COMBO_CD_ID); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - - h = GetDlgItem(hdlg, IDC_COMBO_CD_LUN); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - - h = GetDlgItem(hdlg, IDC_COMBO_CD_CHANNEL_IDE); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - - switch(bus) - { - case 2: /* ATAPI (PIO-only) */ - case 3: /* ATAPI (PIO and DMA) */ - h = GetDlgItem(hdlg, 1802); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - - h = GetDlgItem(hdlg, IDC_COMBO_CD_CHANNEL_IDE); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - SendMessage(h, CB_SETCURSEL, temp_cdrom_drives[cdlv_current_sel].ide_channel, 0); - break; - case 4: /* SCSI */ - h = GetDlgItem(hdlg, 1800); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - h = GetDlgItem(hdlg, 1801); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - - h = GetDlgItem(hdlg, IDC_COMBO_CD_ID); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - SendMessage(h, CB_SETCURSEL, temp_cdrom_drives[cdlv_current_sel].scsi_device_id, 0); - - h = GetDlgItem(hdlg, IDC_COMBO_CD_LUN); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - SendMessage(h, CB_SETCURSEL, temp_cdrom_drives[cdlv_current_sel].scsi_device_lun, 0); - break; - } -} - - -int rd_ignore_change = 0; - -static BOOL CALLBACK win_settings_removable_devices_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - HWND h; - int i = 0; - int old_sel = 0; - int cid = 0; - WCHAR szText[256]; - - switch (message) - { - case WM_INITDIALOG: - rd_ignore_change = 1; - - fdlv_current_sel = 0; - h = GetDlgItem(hdlg, IDC_LIST_FLOPPY_DRIVES); - win_settings_floppy_drives_init_columns(h); - win_settings_floppy_drives_image_list_init(h); - win_settings_floppy_drives_recalc_list(h); - ListView_SetItemState(h, 0, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); - h = GetDlgItem(hdlg, IDC_COMBO_FD_TYPE); - for (i = 0; i < 14; i++) - { - if (i == 0) - { - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2151)); - } - else - { - mbstowcs(szText, fdd_getname(i), strlen(fdd_getname(i)) + 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) szText); - } - } - SendMessage(h, CB_SETCURSEL, temp_fdd_types[fdlv_current_sel], 0); - - cdlv_current_sel = 0; - h = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); - win_settings_cdrom_drives_init_columns(h); - win_settings_cdrom_drives_image_list_init(h); - win_settings_cdrom_drives_recalc_list(h); - ListView_SetItemState(h, 0, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); - cdrom_add_locations(hdlg); - h = GetDlgItem(hdlg, IDC_COMBO_CD_BUS); - if (temp_cdrom_drives[cdlv_current_sel].bus_type > 1) - { - SendMessage(h, CB_SETCURSEL, temp_cdrom_drives[cdlv_current_sel].bus_type, 0); - } - else - { - SendMessage(h, CB_SETCURSEL, 0, 0); - } - cdrom_recalc_location_controls(hdlg); - - rd_ignore_change = 0; - return TRUE; - - case WM_NOTIFY: - if (rd_ignore_change) - { - return FALSE; - } - - if ((((LPNMHDR)lParam)->code == LVN_ITEMCHANGED) && (((LPNMHDR)lParam)->idFrom == IDC_LIST_FLOPPY_DRIVES)) - { - old_sel = fdlv_current_sel; - fdlv_current_sel = get_selected_floppy_drive(hdlg); - if (fdlv_current_sel == old_sel) - { - return FALSE; - } - else if (fdlv_current_sel == -1) - { - rd_ignore_change = 1; - fdlv_current_sel = old_sel; - ListView_SetItemState(h, fdlv_current_sel, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); - rd_ignore_change = 0; - return FALSE; - } - rd_ignore_change = 1; - h = GetDlgItem(hdlg, IDC_COMBO_FD_TYPE); - SendMessage(h, CB_SETCURSEL, temp_fdd_types[fdlv_current_sel], 0); - rd_ignore_change = 0; - } - else if ((((LPNMHDR)lParam)->code == LVN_ITEMCHANGED) && (((LPNMHDR)lParam)->idFrom == IDC_LIST_CDROM_DRIVES)) - { - old_sel = cdlv_current_sel; - cdlv_current_sel = get_selected_cdrom_drive(hdlg); - if (cdlv_current_sel == old_sel) - { - return FALSE; - } - else if (cdlv_current_sel == -1) - { - rd_ignore_change = 1; - cdlv_current_sel = old_sel; - ListView_SetItemState(h, cdlv_current_sel, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); - rd_ignore_change = 0; - return FALSE; - } - rd_ignore_change = 1; - h = GetDlgItem(hdlg, IDC_COMBO_CD_BUS); - if (temp_cdrom_drives[cdlv_current_sel].bus_type > 1) - { - SendMessage(h, CB_SETCURSEL, temp_cdrom_drives[cdlv_current_sel].bus_type, 0); - } - else - { - SendMessage(h, CB_SETCURSEL, 0, 0); - } - cdrom_recalc_location_controls(hdlg); - rd_ignore_change = 0; - } - break; - - case WM_COMMAND: - switch (LOWORD(wParam)) - { - case IDC_COMBO_FD_TYPE: - if (rd_ignore_change) - { - return FALSE; - } - - rd_ignore_change = 1; - h = GetDlgItem(hdlg, IDC_COMBO_FD_TYPE); - temp_fdd_types[fdlv_current_sel] = SendMessage(h, CB_GETCURSEL, 0, 0); - h = GetDlgItem(hdlg, IDC_LIST_FLOPPY_DRIVES); - win_settings_floppy_drives_update_item(h, fdlv_current_sel); - rd_ignore_change = 0; - return FALSE; - - case IDC_COMBO_CD_BUS: - if (rd_ignore_change) - { - return FALSE; - } - - rd_ignore_change = 1; - h = GetDlgItem(hdlg, IDC_COMBO_CD_BUS); - temp_cdrom_drives[cdlv_current_sel].bus_type = SendMessage(h, CB_GETCURSEL, 0, 0) + 1; - if (temp_cdrom_drives[cdlv_current_sel].bus_type == 1) - { - temp_cdrom_drives[cdlv_current_sel].bus_type = 0; - } - cdrom_recalc_location_controls(hdlg); - h = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); - win_settings_cdrom_drives_update_item(h, cdlv_current_sel); - rd_ignore_change = 0; - return FALSE; - - case IDC_COMBO_CD_ID: - if (rd_ignore_change) - { - return FALSE; - } - - rd_ignore_change = 1; - h = GetDlgItem(hdlg, IDC_COMBO_CD_ID); - temp_cdrom_drives[cdlv_current_sel].scsi_device_id = SendMessage(h, CB_GETCURSEL, 0, 0); - h = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); - win_settings_cdrom_drives_update_item(h, cdlv_current_sel); - rd_ignore_change = 0; - return FALSE; - - case IDC_COMBO_CD_LUN: - if (rd_ignore_change) - { - return FALSE; - } - - rd_ignore_change = 1; - h = GetDlgItem(hdlg, IDC_COMBO_CD_LUN); - temp_cdrom_drives[cdlv_current_sel].scsi_device_lun = SendMessage(h, CB_GETCURSEL, 0, 0); - h = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); - win_settings_cdrom_drives_update_item(h, cdlv_current_sel); - rd_ignore_change = 0; - return FALSE; - - case IDC_COMBO_CD_CHANNEL_IDE: - if (rd_ignore_change) - { - return FALSE; - } - - rd_ignore_change = 1; - h = GetDlgItem(hdlg, IDC_COMBO_CD_CHANNEL_IDE); - temp_cdrom_drives[cdlv_current_sel].ide_channel = SendMessage(h, CB_GETCURSEL, 0, 0); - h = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); - win_settings_cdrom_drives_update_item(h, cdlv_current_sel); - rd_ignore_change = 0; - return FALSE; - } - - default: - return FALSE; - } - - return FALSE; -} - -void win_settings_show_child(HWND hwndParent, DWORD child_id) -{ - if (child_id == displayed_category) - { - return; - } - else - { - displayed_category = child_id; - } - - SendMessage(hwndChildDialog, WM_SAVESETTINGS, 0, 0); - - DestroyWindow(hwndChildDialog); - - switch(child_id) - { - case 0: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) CONFIGUREDLG_MACHINE, hwndParent, win_settings_machine_proc); - break; - case 1: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) CONFIGUREDLG_VIDEO, hwndParent, win_settings_video_proc); - break; - case 2: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) CONFIGUREDLG_INPUT, hwndParent, win_settings_input_proc); - break; - case 3: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) CONFIGUREDLG_SOUND, hwndParent, win_settings_sound_proc); - break; - case 4: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) CONFIGUREDLG_NETWORK, hwndParent, win_settings_network_proc); - break; - case 5: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) CONFIGUREDLG_PERIPHERALS, hwndParent, win_settings_peripherals_proc); - break; - case 6: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) CONFIGUREDLG_HARD_DISKS, hwndParent, win_settings_hard_disks_proc); - break; - case 7: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) CONFIGUREDLG_REMOVABLE_DEVICES, hwndParent, win_settings_removable_devices_proc); - break; - default: - fatal("Invalid child dialog ID\n"); - return; - } - - ShowWindow(hwndChildDialog, SW_SHOWNORMAL); -} - -static BOOL win_settings_main_image_list_init(HWND hwndList) -{ - HICON hiconItem; - HIMAGELIST hSmall; - - int i = 0; - - hSmall = ImageList_Create(GetSystemMetrics(SM_CXSMICON), - GetSystemMetrics(SM_CYSMICON), - ILC_MASK | ILC_COLOR32, 1, 1); - - for (i = 0; i < 8; i++) - { - hiconItem = LoadIcon(hinstance, (LPCWSTR) (256 + i)); - ImageList_AddIcon(hSmall, hiconItem); - DestroyIcon(hiconItem); - } - - ListView_SetImageList(hwndList, hSmall, LVSIL_SMALL); - - return TRUE; -} - -static BOOL win_settings_main_insert_categories(HWND hwndList) -{ - LVITEM lvI; - int i = 0; - - lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; - lvI.stateMask = lvI.iSubItem = lvI.state = 0; - - for (i = 0; i < 8; i++) - { - lvI.pszText = win_language_get_settings_category(i); - lvI.iItem = i; - lvI.iImage = i; - - if (ListView_InsertItem(hwndList, &lvI) == -1) - return FALSE; - } - - return TRUE; -} - -static BOOL CALLBACK win_settings_main_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - HWND h; - int category; - int i = 0; - int j = 0; - - hwndParentDialog = hdlg; - - switch (message) - { - case WM_INITDIALOG: - pause = 1; - win_settings_init(); - displayed_category = -1; - h = GetDlgItem(hdlg, IDC_SETTINGSCATLIST); - win_settings_main_image_list_init(h); - win_settings_main_insert_categories(h); - ListView_SetItemState(h, 0, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); - h = GetDlgItem(hdlg, IDC_COMBO_LANG); /* This is currently disabled, I am going to add localization options in the future. */ - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - h = GetDlgItem(hdlg, 2047); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - return TRUE; - case WM_NOTIFY: - if ((((LPNMHDR)lParam)->code == LVN_ITEMCHANGED) && (((LPNMHDR)lParam)->idFrom == IDC_SETTINGSCATLIST)) - { - category = -1; - for (i = 0; i < 8; i++) - { - h = GetDlgItem(hdlg, IDC_SETTINGSCATLIST); - j = ListView_GetItemState(h, i, LVIS_SELECTED); - if (j) - { - category = i; - /* pclog("Category %i selected\n", i); */ - } - } - if (category != -1) - { - /* pclog("Showing child: %i\n", category); */ - win_settings_show_child(hdlg, category); - } - } - break; - case WM_COMMAND: - switch (LOWORD(wParam)) - { - case IDOK: - /* pclog("Saving settings...\n"); */ - SendMessage(hwndChildDialog, WM_SAVESETTINGS, 0, 0); - i = settings_msgbox_reset(); - if (i > 0) - { - if (i == 2) - { - win_settings_save(); - } - - /* pclog("Destroying window...\n"); */ - DestroyWindow(hwndChildDialog); - EndDialog(hdlg, 0); - pause = 0; - return TRUE; - } - else - { - return FALSE; - } - case IDCANCEL: - DestroyWindow(hwndChildDialog); - EndDialog(hdlg, 0); - pause=0; - return TRUE; - } - break; - default: - return FALSE; - } - - return FALSE; -} - -void win_settings_open(HWND hwnd) -{ - DialogBox(hinstance, (LPCWSTR) CONFIGUREDLG_MAIN, hwnd, win_settings_main_proc); -} diff --git a/src/win-status.c b/src/win-status.c deleted file mode 100644 index a39d38700..000000000 --- a/src/win-status.c +++ /dev/null @@ -1,95 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -#define BITMAP WINDOWS_BITMAP -#include -#include -#undef BITMAP - -#include "ibm.h" -#include "mem.h" -#include "cpu/x86_ops.h" -#include "cpu/codegen.h" -#include "device.h" -#include "resource.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, IDC_STEXT_DEVICE, WM_SETTEXT, (WPARAM)NULL, (LPARAM)device_s); - - device_s[0] = 0; - device_add_status_info(device_s, 4096); - SendDlgItemMessage(hdlg, IDC_STEXT1, 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, TEXT("StatusDlg"), hwnd, status_dlgproc); - ShowWindow(status_hwnd, SW_SHOW); -} diff --git a/src/win-video.c b/src/win-video.c deleted file mode 100644 index 15aec3785..000000000 --- a/src/win-video.c +++ /dev/null @@ -1,57 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -#include -#include -#include -#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; -} diff --git a/src/win.c b/src/win.c deleted file mode 100644 index f5e5a96eb..000000000 --- a/src/win.c +++ /dev/null @@ -1,2427 +0,0 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ -#define UNICODE -#define _WIN32_WINNT 0x0501 -#define BITMAP WINDOWS_BITMAP -#include -#include -#undef BITMAP - -#include -#include -#include -#include -#include -#include -#include -#include -#include "86box.h" -#include "device.h" -#include "disc.h" -#include "fdd.h" -#include "hdd.h" -#include "ibm.h" -#include "cpu/cpu.h" -#include "mem.h" -#include "rom.h" -#include "nvr.h" -#include "thread.h" -#include "config.h" -#include "model.h" -#include "ide.h" -#include "cdrom.h" -#include "cdrom-null.h" -#include "cdrom-ioctl.h" -#include "cdrom-image.h" -#include "video/video.h" -#include "video/vid_ega.h" -#include "plat-keyboard.h" -#include "plat-mouse.h" -#include "plat-midi.h" -#include "mouse.h" -#include "sound/sound.h" -#include "sound/snd_dbopl.h" - -#include "win.h" -#include "win-ddraw.h" -#include "win-ddraw-fs.h" -#include "win-d3d.h" -#include "win-d3d-fs.h" -#include "win-language.h" -#include "resource.h" - - -#ifndef MAPVK_VK_TO_VSC -#define MAPVK_VK_TO_VSC 0 -#endif - -static int save_window_pos = 0; -uint64_t timer_freq; - -int rawinputkey[272]; - -static RAWINPUTDEVICE device; -static uint16_t scancode_map[65536]; - -static struct -{ - int (*init)(HWND h); - void (*close)(); - void (*resize)(int x, int y); -} vid_apis[2][2] = -{ - { - ddraw_init, ddraw_close, NULL, - d3d_init, d3d_close, d3d_resize - }, - { - ddraw_fs_init, ddraw_fs_close, NULL, - d3d_fs_init, d3d_fs_close, NULL - }, -}; - -#define TIMER_1SEC 1 - -int winsizex=640,winsizey=480; -int efwinsizey=480; -int gfx_present[GFX_MAX]; - -HANDLE ghMutex; - -HANDLE mainthreadh; - -int infocus=1; - -int drawits=0; - -int romspresent[ROM_MAX]; -int quited=0; - -RECT oldclip; -int mousecapture=0; - -/* Declare Windows procedure */ -LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); -LRESULT CALLBACK subWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); - -LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); - -LONG OriginalStatusBarProcedure; - -HWND ghwnd; - -HINSTANCE hinstance; - -HMENU menu; - -extern int updatestatus; - -int pause=0; - -static int win_doresize = 0; - -static int leave_fullscreen_flag = 0; - -static int unscaled_size_x = 0; -static int unscaled_size_y = 0; - -int scale = 0; - -HWND hwndRender, hwndStatus; - -void updatewindowsize(int x, int y) -{ - int owsx = winsizex; - int owsy = winsizey; - - int temp_overscan_x = overscan_x; - int temp_overscan_y = overscan_y; - - if (vid_resize) return; - - if (x < 160) x = 160; - if (y < 100) y = 100; - - if (x > 2048) x = 2048; - if (y > 2048) y = 2048; - - if (suppress_overscan) - { - temp_overscan_x = temp_overscan_y = 0; - } - - unscaled_size_x=x; efwinsizey=y; - - if (force_43) - { - /* Account for possible overscan. */ - if (temp_overscan_y == 16) - { - /* CGA */ - unscaled_size_y = ((int) (((double) (x - temp_overscan_x) / 4.0) * 3.0)) + temp_overscan_y; - } - else if (temp_overscan_y < 16) - { - /* MDA/Hercules */ - unscaled_size_y = ((int) (((double) (x) / 4.0) * 3.0)); - } - else - { - if (enable_overscan) - { - /* EGA/(S)VGA with overscan */ - unscaled_size_y = ((int) (((double) (x - temp_overscan_x) / 4.0) * 3.0)) + temp_overscan_y; - } - else - { - /* EGA/(S)VGA without overscan */ - unscaled_size_y = ((int) (((double) (x) / 4.0) * 3.0)); - } - } - } - else - { - unscaled_size_y = efwinsizey; - } - - switch(scale) - { - case 0: - winsizex = unscaled_size_x >> 1; - winsizey = unscaled_size_y >> 1; - break; - case 1: - winsizex = unscaled_size_x; - winsizey = unscaled_size_y; - break; - case 2: - winsizex = (unscaled_size_x * 3) >> 1; - winsizey = (unscaled_size_y * 3) >> 1; - break; - case 3: - winsizex = unscaled_size_x << 1; - winsizey = unscaled_size_y << 1; - break; - } - - if ((owsx != winsizex) || (owsy != winsizey)) - { - win_doresize = 1; - } - else - { - win_doresize = 0; - } -} - -void uws_natural() -{ - updatewindowsize(unscaled_size_x, efwinsizey); -} - -void releasemouse() -{ - if (mousecapture) - { - ClipCursor(&oldclip); - ShowCursor(TRUE); - mousecapture = 0; - } -} - -void startblit() -{ - WaitForSingleObject(ghMutex, INFINITE); -} - -void endblit() -{ - ReleaseMutex(ghMutex); -} - -void leave_fullscreen() -{ - leave_fullscreen_flag = 1; -} - -uint64_t main_time; - -uint64_t start_time; -uint64_t end_time; - -void mainthread(LPVOID param) -{ - int frames = 0; - DWORD old_time, new_time; - - RECT r; - int sb_borders[3]; - - drawits=0; - old_time = GetTickCount(); - while (!quited) - { - if (updatestatus) - { - updatestatus = 0; - if (status_is_open) - SendMessage(status_hwnd, WM_USER, 0, 0); - } - new_time = GetTickCount(); - drawits += new_time - old_time; - old_time = new_time; - if (drawits > 0 && !pause) - { - start_time = timer_read(); - drawits-=10; if (drawits>50) drawits=0; - runpc(); - frames++; - if (frames >= 200 && nvr_dosave) - { - frames = 0; - nvr_dosave = 0; - savenvr(); - } - end_time = timer_read(); - main_time += end_time - start_time; - } - else - Sleep(1); - - if (!video_fullscreen && win_doresize && (winsizex > 0) && (winsizey > 0)) - { - video_wait_for_blit(); - SendMessage(hwndStatus, SB_GETBORDERS, 0, (LPARAM) sb_borders); - GetWindowRect(ghwnd, &r); - MoveWindow(hwndRender, 0, 0, - winsizex, - winsizey, - TRUE); - GetWindowRect(hwndRender, &r); - MoveWindow(hwndStatus, 0, r.bottom + GetSystemMetrics(SM_CYEDGE), - winsizex, - 17, - TRUE); - GetWindowRect(ghwnd, &r); - - MoveWindow(ghwnd, r.left, r.top, - winsizex + (GetSystemMetrics(vid_resize ? SM_CXSIZEFRAME : SM_CXFIXEDFRAME) * 2), - winsizey + (GetSystemMetrics(SM_CYEDGE) * 2) + (GetSystemMetrics(vid_resize ? SM_CYSIZEFRAME : SM_CYFIXEDFRAME) * 2) + GetSystemMetrics(SM_CYMENUSIZE) + GetSystemMetrics(SM_CYCAPTION) + 17 + sb_borders[1] + 1, - TRUE); - - win_doresize = 0; - } - - if (leave_fullscreen_flag) - { - leave_fullscreen_flag = 0; - SendMessage(ghwnd, WM_LEAVEFULLSCREEN, 0, 0); - } - if (video_fullscreen && infocus) - { - SetCursorPos(9999, 9999); - } - } -} - -void *thread_create(void (*thread_rout)(void *param), void *param) -{ - return (void *)_beginthread(thread_rout, 0, param); -} - -void thread_kill(void *handle) -{ - TerminateThread(handle, 0); -} - -void thread_sleep(int t) -{ - Sleep(t); -} - -typedef struct win_event_t -{ - HANDLE handle; -} win_event_t; - -event_t *thread_create_event() -{ - win_event_t *event = malloc(sizeof(win_event_t)); - - event->handle = CreateEvent(NULL, FALSE, FALSE, NULL); - - return (event_t *)event; -} - -void thread_set_event(event_t *_event) -{ - win_event_t *event = (win_event_t *)_event; - - SetEvent(event->handle); -} - -void thread_reset_event(event_t *_event) -{ - win_event_t *event = (win_event_t *)_event; - - ResetEvent(event->handle); -} - -int thread_wait_event(event_t *_event, int timeout) -{ - win_event_t *event = (win_event_t *)_event; - - if (timeout == -1) - timeout = INFINITE; - - if (WaitForSingleObject(event->handle, timeout)) - return 1; - return 0; -} - -void thread_destroy_event(event_t *_event) -{ - win_event_t *event = (win_event_t *)_event; - - CloseHandle(event->handle); - - free(event); -} - -HMENU smenu; - -static void initmenu(void) -{ - int i, c; - HMENU m; - WCHAR s[64]; - - for (i = 0; i < CDROM_NUM; i++) - { - m=GetSubMenu(smenu, i + 4); /*CD-ROM*/ - - /* Loop through each Windows drive letter and test to see if - it's a CDROM */ - for (c='A';c<='Z';c++) - { - _swprintf(s,L"%c:\\",c); - if (GetDriveType(s)==DRIVE_CDROM) - { - _swprintf(s, win_language_get_string_from_id(2076), c); - AppendMenu(m,MF_STRING,IDM_CDROM_1_REAL+(c << 2)+i,s); - } - } - } -} - -void get_executable_name(WCHAR *s, int size) -{ - GetModuleFileName(hinstance, s, size); -} - -void set_window_title(WCHAR *s) -{ - if (video_fullscreen) - return; - SetWindowText(ghwnd, s); -} - -uint64_t timer_read() -{ - LARGE_INTEGER qpc_time; - QueryPerformanceCounter(&qpc_time); - return qpc_time.QuadPart; -} - -/* 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; - - /* 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) - { - UINT32 *bufEx2 = (UINT32 *) buf; - int scMapCount = bufEx2[2]; - if ((bufSize != 0) && (scMapCount != 0)) - { - UINT16 *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. */ - int scancode_unmapped = bufEx[j + 1]; - int scancode_mapped = bufEx[j]; - - scancode_mapped = convert_scan_code(scancode_mapped); - - /* Fixes scan code map logging. */ - scancode_map[scancode_unmapped] = scancode_mapped; - } - } - } - RegCloseKey(hKey); - } -} - -static wchar_t **argv; -static int argc; -static wchar_t *argbuf; - -static void process_command_line() -{ - WCHAR *cmdline; - int argc_max; - int i, q; - - cmdline = GetCommandLine(); - i = wcslen(cmdline) + 1; - argbuf = malloc(i * 2); - memcpy(argbuf, cmdline, i * 2); - - argc = 0; - argc_max = 64; - argv = malloc(sizeof(wchar_t *) * argc_max); - if (!argv) - { - free(argbuf); - return; - } - - i = 0; - - /* parse commandline into argc/argv format */ - while (argbuf[i]) - { - while (argbuf[i] == L' ') - i++; - - if (argbuf[i]) - { - if ((argbuf[i] == L'\'') || (argbuf[i] == L'"')) - { - q = argbuf[i++]; - if (!argbuf[i]) - break; - } - else - q = 0; - - argv[argc++] = &argbuf[i]; - - if (argc >= argc_max) - { - argc_max += 64; - argv = realloc(argv, sizeof(wchar_t *) * argc_max); - if (!argv) - { - free(argbuf); - return; - } - } - - while ((argbuf[i]) && ((q) ? (argbuf[i] != q) : (argbuf[i] != L' '))) - i++; - - if (argbuf[i]) - { - argbuf[i] = 0; - i++; - } - } - } - - argv[argc] = NULL; -} - -int valid_models[2] = { 0, 1 }; -int valid_bases[6] = { 0x130, 0x134, 0x230, 0x234, 0x330, 0x334 }; -int valid_irqs[6] = { 9, 10, 11, 12, 14, 15 }; -int valid_dma_channels[3] = { 5, 6, 7 }; -int valid_ide_channels[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; -int valid_scsi_ids[15] = { 0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15 }; -int valid_scsi_luns[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; - -int find_in_array(int *array, int val, int len, int menu_base) -{ - int i = 0; - int temp = 0; - for (i = 0; i < len; i++) - { - CheckMenuItem(menu, menu_base + array[i], MF_UNCHECKED); - if (array[i] == val) - { - temp = 1; - } - } - return temp; -} - -HANDLE hinstAcc; - -HICON LoadIconEx(PCTSTR pszIconName) -{ - return (HICON) LoadImage(hinstance, pszIconName, IMAGE_ICON, 16, 16, LR_SHARED); -} - -HICON LoadIconBig(PCTSTR pszIconName) -{ - return (HICON) LoadImage(hinstance, pszIconName, IMAGE_ICON, 64, 64, 0); -} - -int fdd_type_to_icon(int type) -{ - switch(type) - { - default: - case 0: - return 512; - case 1: - return 128; - case 2: - return 130; - case 3: - return 132; - case 4: - case 5: - case 6: - return 134; - case 7: - return 144; - case 8: - return 146; - case 9: - case 10: - case 11: - case 12: - return 150; - case 13: - return 152; - } -} - -int sb_parts = 10; - -int sb_part_meanings[12]; -int sb_part_icons[12]; - -int sb_icon_width = 24; - -int count_hard_disks(int bus) -{ - int i = 0; - - int c = 0; - - for (i = 0; i < HDC_NUM; i++) - { - if (hdc[i].bus == bus) - { - c++; - } - } - - return c; -} - -HICON hIcon[512]; - -int iStatusWidths[] = { 18, 36, 54, 72, 90, 108, 126, 144, 168, 192, 210, -1 }; - -#define SBI_FLAG_ACTIVE 1 -#define SBI_FLAG_EMPTY 256 - -int sb_icon_flags[512]; - -/* This is for the disk activity indicator. */ -void update_status_bar_icon(int tag, int active) -{ - int i = 0; - int found = -1; - int temp_flags = 0; - - if ((tag & 0xf0) >= 0x30) - { - return; - } - - temp_flags |= active; - - for (i = 0; i < 12; i++) - { - if (sb_part_meanings[i] == tag) - { - found = i; - break; - } - } - - if (found != -1) - { - if (temp_flags != (sb_icon_flags[found] & 1)) - { - sb_icon_flags[found] &= ~1; - sb_icon_flags[found] |= active; - - sb_part_icons[found] &= ~257; - sb_part_icons[found] |= sb_icon_flags[found]; - - SendMessage(hwndStatus, SB_SETICON, found, (LPARAM) hIcon[sb_part_icons[found]]); - } - } -} - -/* This is for the drive state indicator. */ -void update_status_bar_icon_state(int tag, int state) -{ - int i = 0; - int found = -1; - - if ((tag & 0xf0) >= 0x20) - { - return; - } - - for (i = 0; i < 12; i++) - { - if (sb_part_meanings[i] == tag) - { - found = i; - break; - } - } - - if (found != -1) - { - sb_icon_flags[found] &= ~256; - sb_icon_flags[found] |= state ? 256 : 0; - - sb_part_icons[found] &= ~257; - sb_part_icons[found] |= sb_icon_flags[found]; - - SendMessage(hwndStatus, SB_SETICON, found, (LPARAM) hIcon[sb_part_icons[found]]); - } -} - -WCHAR sbTips[24][512]; - -void create_floppy_tip(int part) -{ - WCHAR *szText; - WCHAR wtext[512]; - - int drive = sb_part_meanings[part] & 0xf; - - mbstowcs(wtext, fdd_getname(fdd_get_type(drive)), strlen(fdd_getname(fdd_get_type(drive))) + 1); - if (wcslen(discfns[drive]) == 0) - { - _swprintf(sbTips[part], win_language_get_string_from_id(2179), drive + 1, wtext, win_language_get_string_from_id(2185)); - } - else - { - _swprintf(sbTips[part], win_language_get_string_from_id(2179), drive + 1, wtext, discfns[drive]); - } -} - -void create_cdrom_tip(int part) -{ - WCHAR *szText; - char ansi_text[3][512]; - WCHAR wtext[512]; - - int drive = sb_part_meanings[part] & 0xf; - - if (cdrom_drives[drive].host_drive == 200) - { - if (wcslen(cdrom_image[drive].image_path) == 0) - { - _swprintf(sbTips[part], win_language_get_string_from_id(2180), drive + 1, win_language_get_string_from_id(2185)); - } - else - { - _swprintf(sbTips[part], win_language_get_string_from_id(2180), drive + 1, cdrom_image[drive].image_path); - } - } - else if (cdrom_drives[drive].host_drive < 0x41) - { - _swprintf(sbTips[part], win_language_get_string_from_id(2180), drive + 1, win_language_get_string_from_id(2185)); - } - else - { - _swprintf(wtext, win_language_get_string_from_id(2186), cdrom_drives[drive].host_drive & ~0x20); - _swprintf(sbTips[part], win_language_get_string_from_id(2180), drive + 1, wtext); - } -} - -void create_hd_tip(int part) -{ - WCHAR *szText; - - int bus = sb_part_meanings[part] & 0xf; - szText = (WCHAR *) win_language_get_string_from_id(2181 + bus); - memcpy(sbTips[part], szText, (wcslen(szText) << 1) + 2); -} - -void update_tip(int meaning) -{ - int i = 0; - int part = -1; - - for (i = 0; i < sb_parts; i++) - { - if (sb_part_meanings[i] == meaning) - { - part = i; - } - } - - if (part != -1) - { - switch(meaning & 0x30) - { - case 0x00: - create_floppy_tip(part); - break; - case 0x10: - create_cdrom_tip(part); - break; - case 0x20: - create_hd_tip(part); - break; - default: - break; - } - - SendMessage(hwndStatus, SB_SETTIPTEXT, part, (LPARAM) sbTips[part]); - } -} - -static int get_floppy_state(int id) -{ - return (wcslen(discfns[id]) == 0) ? 1 : 0; -} - -static int get_cd_state(int id) -{ - if (cdrom_drives[id].host_drive < 0x41) - { - return 1; - } - else - { - if (cdrom_drives[id].host_drive == 0x200) - { - return (wcslen(cdrom_image[id].image_path) == 0) ? 1 : 0; - } - else - { - return 0; - } - } -} - -void status_settextw(wchar_t *wstr) -{ - int i = 0; - int part = -1; - - for (i = 0; i < sb_parts; i++) - { - if (sb_part_meanings[i] == 0x30) - { - part = i; - } - } - - if (part != -1) - { - SendMessage(hwndStatus, SB_SETTEXT, part | SBT_NOBORDERS, (LPARAM) wstr); - } -} - -static wchar_t cwstr[512]; - -void status_settext(char *str) -{ - memset(cwstr, 0, 1024); - mbstowcs(cwstr, str, strlen(str) + 1); - status_settextw(cwstr); -} - -void update_status_bar_panes(HWND hwnds) -{ - int i, j, id; - int edge = 0; - - int c_rll = 0; - int c_mfm = 0; - int c_ide_pio = 0; - int c_ide_dma = 0; - int c_scsi = 0; - - c_mfm = count_hard_disks(1); - c_ide_pio = count_hard_disks(2); - c_ide_dma = count_hard_disks(3); - c_scsi = count_hard_disks(4); - - for (i = 0; i < sb_parts; i++) - { - SendMessage(hwnds, SB_SETICON, i, (LPARAM) NULL); - } - - sb_parts = 0; - memset(iStatusWidths, 0, 48); - memset(sb_part_meanings, 0, 48); - for (i = 0; i < 4; i++) - { - if (fdd_get_type(i) != 0) - { - /* pclog("update_status_bar_panes(): Found floppy drive %c:, type %i\n", 65 + i, fdd_get_type(i)); */ - edge += sb_icon_width; - iStatusWidths[sb_parts] = edge; - sb_part_meanings[sb_parts] = 0x00 | i; - sb_parts++; - } - } - for (i = 0; i < 4; i++) - { - if (cdrom_drives[i].bus_type != 0) - { - edge += sb_icon_width; - iStatusWidths[sb_parts] = edge; - sb_part_meanings[sb_parts] = 0x10 | i; - sb_parts++; - } - } - if (c_mfm && !(models[model].flags & MODEL_HAS_IDE) && !!memcmp(hdd_controller_name, "none", 4) && !!memcmp(hdd_controller_name, "xtide", 5)) - { - edge += sb_icon_width; - iStatusWidths[sb_parts] = edge; - sb_part_meanings[sb_parts] = 0x20; - sb_parts++; - } - if (c_ide_pio && ((models[model].flags & MODEL_HAS_IDE) || !memcmp(hdd_controller_name, "xtide", 5))) - { - edge += sb_icon_width; - iStatusWidths[sb_parts] = edge; - sb_part_meanings[sb_parts] = 0x21; - sb_parts++; - } - if (c_ide_dma && ((models[model].flags & MODEL_HAS_IDE) || !memcmp(hdd_controller_name, "xtide", 5))) - { - edge += sb_icon_width; - iStatusWidths[sb_parts] = edge; - sb_part_meanings[sb_parts] = 0x22; - sb_parts++; - } - if (c_scsi) - { - edge += sb_icon_width; - iStatusWidths[sb_parts] = edge; - sb_part_meanings[sb_parts] = 0x23; - sb_parts++; - } - if (sb_parts) - { - iStatusWidths[sb_parts - 1] += (24 - sb_icon_width); - } - iStatusWidths[sb_parts] = -1; - sb_part_meanings[sb_parts] = 0x30; - sb_parts++; - - SendMessage(hwnds, SB_SETPARTS, (WPARAM) sb_parts, (LPARAM) iStatusWidths); - - for (i = 0; i < sb_parts; i++) - { - switch (sb_part_meanings[i] & 0x30) - { - case 0x00: - /* Floppy */ - sb_icon_flags[i] = (wcslen(discfns[sb_part_meanings[i] & 0xf]) == 0) ? 256 : 0; - sb_part_icons[i] = fdd_type_to_icon(fdd_get_type(sb_part_meanings[i] & 0xf)) | sb_icon_flags[i]; - create_floppy_tip(i); - break; - case 0x10: - /* CD-ROM */ - id = sb_part_meanings[i] & 0xf; - if (cdrom_drives[id].host_drive < 0x41) - { - sb_icon_flags[i] = 256; - } - else - { - if (cdrom_drives[id].host_drive == 0x200) - { - sb_icon_flags[i] = (wcslen(cdrom_image[id].image_path) == 0) ? 256 : 0; - } - else - { - sb_icon_flags[i] = 0; - } - } - if (cdrom_drives[id].bus_type == 4) - { - j = 164; - } - else if (cdrom_drives[id].bus_type == 3) - { - j = 162; - } - else - { - j = 160; - } - sb_part_icons[i] = j | sb_icon_flags[i]; - create_cdrom_tip(i); - break; - case 0x20: - /* Hard disk */ - sb_part_icons[i] = 176 + ((sb_part_meanings[i] & 0xf) << 1); - create_hd_tip(i); - break; - case 0x30: - /* Status text */ - SendMessage(hwnds, SB_SETTEXT, i | SBT_NOBORDERS, (LPARAM) L"Welcome to Unicode 86Box! :p"); - sb_part_icons[i] = -1; - break; - } - if (sb_part_icons[i] != -1) - { - SendMessage(hwnds, SB_SETTEXT, i | SBT_NOBORDERS, (LPARAM) ""); - SendMessage(hwnds, SB_SETICON, i, (LPARAM) hIcon[sb_part_icons[i]]); - SendMessage(hwnds, SB_SETTIPTEXT, i, (LPARAM) sbTips[i]); - /* pclog("Status bar part found: %02X (%i)\n", sb_part_meanings[i], sb_part_icons[i]); */ - } - else - { - SendMessage(hwnds, SB_SETICON, i, (LPARAM) NULL); - } - } -} - -HWND EmulatorStatusBar(HWND hwndParent, int idStatus, HINSTANCE hinst) -{ - HWND hwndStatus; - int i; - RECT rectDialog; - int dw, dh; - - for (i = 128; i < 136; i++) - { - hIcon[i] = LoadIconEx((PCTSTR) i); - } - - for (i = 144; i < 148; i++) - { - hIcon[i] = LoadIconEx((PCTSTR) i); - } - - for (i = 150; i < 154; i++) - { - hIcon[i] = LoadIconEx((PCTSTR) i); - } - - for (i = 160; i < 166; i++) - { - hIcon[i] = LoadIconEx((PCTSTR) i); - } - - for (i = 176; i < 184; i++) - { - hIcon[i] = LoadIconEx((PCTSTR) i); - } - - for (i = 384; i < 392; i++) - { - hIcon[i] = LoadIconEx((PCTSTR) i); - } - - for (i = 400; i < 404; i++) - { - hIcon[i] = LoadIconEx((PCTSTR) i); - } - - for (i = 406; i < 410; i++) - { - hIcon[i] = LoadIconEx((PCTSTR) i); - } - - for (i = 416; i < 422; i++) - { - hIcon[i] = LoadIconEx((PCTSTR) i); - } - - GetWindowRect(hwndParent, &rectDialog); - dw = rectDialog.right - rectDialog.left; - dh = rectDialog.bottom - rectDialog.top; - - InitCommonControls(); - - hwndStatus = CreateWindowEx( - 0, - STATUSCLASSNAME, - (PCTSTR) NULL, - SBARS_SIZEGRIP | WS_CHILD | WS_VISIBLE | SBT_TOOLTIPS, - 0, dh - 17, dw, 17, - hwndParent, - (HMENU) idStatus, - hinst, - NULL); - - GetWindowRect(hwndStatus, &rectDialog); - - SetWindowPos( - hwndStatus, - HWND_TOPMOST, - rectDialog.left, - rectDialog.top, - rectDialog.right - rectDialog.left, - rectDialog.bottom - rectDialog.top, - SWP_SHOWWINDOW); - - SendMessage(hwndStatus, SB_SETMINHEIGHT, (WPARAM) 17, (LPARAM) 0); - - update_status_bar_panes(hwndStatus); - - return hwndStatus; -} - -void win_menu_update() -{ -#if 0 - menu = LoadMenu(hThisInstance, TEXT("MainMenu")); - - smenu = LoadMenu(hThisInstance, TEXT("StatusBarMenu")); - initmenu(); - - SetMenu(ghwnd, menu); - - win_title_update = 1; -#endif -} - -int recv_key[272]; - -int WINAPI WinMain (HINSTANCE hThisInstance, - HINSTANCE hPrevInstance, - LPSTR lpszArgument, - int nFunsterStil) - -{ - HWND hwnd; /* This is the handle for our window */ - MSG messages; /* Here messages to the application are saved */ - WNDCLASSEX wincl; /* Data structure for the windowclass */ - int c, d, e, bRet; - WCHAR emulator_title[200]; - LARGE_INTEGER qpc_freq; - HACCEL haccel; /* Handle to accelerator table */ - - memset(recv_key, 0, sizeof(recv_key)); - - process_command_line(); - - win_language_load_common_strings(); - - hinstance=hThisInstance; - /* The Window structure */ - wincl.hInstance = hThisInstance; - wincl.lpszClassName = szClassName; - wincl.lpfnWndProc = WindowProcedure; /* This function is called by windows */ - wincl.style = CS_DBLCLKS; /* Catch double-clicks */ - wincl.cbSize = sizeof (WNDCLASSEX); - - /* Use default icon and mouse-pointer */ - wincl.hIcon = LoadIcon(hinstance, (LPCTSTR) 100); - wincl.hIconSm = LoadIcon(hinstance, (LPCTSTR) 100); - wincl.hCursor = NULL; - wincl.lpszMenuName = NULL; /* No menu */ - wincl.cbClsExtra = 0; /* No extra bytes after the window class */ - wincl.cbWndExtra = 0; /* structure or the window instance */ - /* Use Windows's default color as the background of the window */ - wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND; - - /* Register the window class, and if it fails quit the program */ - if (!RegisterClassEx(&wincl)) - return 0; - - wincl.lpszClassName = szSubClassName; - wincl.lpfnWndProc = subWindowProcedure; /* This function is called by windows */ - - if (!RegisterClassEx(&wincl)) - return 0; - - menu = LoadMenu(hThisInstance, TEXT("MainMenu")); - - _swprintf(emulator_title, L"86Box v%s", emulator_version_w); - - /* The class is registered, let's create the program*/ - hwnd = CreateWindowEx ( - 0, /* Extended possibilites for variation */ - szClassName, /* Classname */ - emulator_title, /* Title Text */ - (WS_OVERLAPPEDWINDOW & ~WS_SIZEBOX)/* | DS_3DLOOK*/, /* default window */ - CW_USEDEFAULT, /* Windows decides the position */ - CW_USEDEFAULT, /* where the window ends up on the screen */ - 640+(GetSystemMetrics(SM_CXFIXEDFRAME)*2), /* The programs width */ - 480+(GetSystemMetrics(SM_CYFIXEDFRAME)*2)+GetSystemMetrics(SM_CYMENUSIZE)+GetSystemMetrics(SM_CYCAPTION)+1, /* and height in pixels */ - HWND_DESKTOP, /* The window is a child-window to desktop */ - menu, /* Menu */ - hThisInstance, /* Program Instance handler */ - NULL /* No Window Creation data */ - ); - - /* Make the window visible on the screen */ - ShowWindow (hwnd, nFunsterStil); - - /* Load the accelerator table */ - haccel = LoadAccelerators(hinstAcc, L"MainAccel"); - if (haccel == NULL) - fatal("haccel is null\n"); - - memset(rawinputkey, 0, sizeof(rawinputkey)); - device.usUsagePage = 0x01; - device.usUsage = 0x06; - device.dwFlags = RIDEV_NOHOTKEYS; - device.hwndTarget = hwnd; - - if (RegisterRawInputDevices(&device, 1, sizeof(device))) - pclog("Raw input registered!\n"); - else - pclog("Raw input registration failed!\n"); - - get_registry_key_map(); - - ghwnd=hwnd; - - initpc(argc, argv); - - hwndRender = CreateWindow(L"STATIC", NULL, WS_VISIBLE | WS_CHILD | SS_BITMAP, 0, 0, 1, 1, ghwnd, NULL, hinstance, NULL); - - hwndStatus = EmulatorStatusBar(hwnd, IDC_STATUS, hThisInstance); - - OriginalStatusBarProcedure = GetWindowLong(hwndStatus, GWL_WNDPROC); - SetWindowLong(hwndStatus, GWL_WNDPROC, (LONG) &StatusBarProcedure); - - smenu = LoadMenu(hThisInstance, TEXT("StatusBarMenu")); - initmenu(); - - if (vid_apis[0][vid_api].init(hwndRender) == 0) - { - if (vid_apis[0][vid_api ^ 1].init(hwndRender) == 0) - { - fatal("Both DirectDraw and Direct3D renderers failed to initialize\n"); - } - else - { - vid_api ^= 1; - } - } - - if (vid_resize) SetWindowLong(hwnd, GWL_STYLE, WS_OVERLAPPEDWINDOW|WS_VISIBLE); - else SetWindowLong(hwnd, GWL_STYLE, (WS_OVERLAPPEDWINDOW&~WS_SIZEBOX&~WS_THICKFRAME&~WS_MAXIMIZEBOX)|WS_VISIBLE); - - SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_MINIMIZEBOX); - - /* Note by Kiririn: I've redone this since the CD-ROM can be disabled but still have something inside it. */ - for (e = 0; e < CDROM_NUM; e++) - { - if (!cdrom_drives[e].sound_on) - { - CheckMenuItem(smenu, IDM_CDROM_1_MUTE + e, MF_CHECKED); - } - - if (cdrom_drives[e].host_drive == 200) - { - CheckMenuItem(smenu, IDM_CDROM_1_IMAGE + e, MF_CHECKED); - } - else if (cdrom_drives[e].host_drive >= 65) - { - CheckMenuItem(smenu, IDM_CDROM_1_REAL + e + (cdrom_drives[e].host_drive << 2), MF_CHECKED); - } - else - { - CheckMenuItem(smenu, IDM_CDROM_1_EMPTY + e, MF_CHECKED); - } - } - -#ifdef ENABLE_LOG_TOGGLES -#ifdef ENABLE_BUSLOGIC_LOG - CheckMenuItem(menu, IDM_LOG_BUSLOGIC, buslogic_do_log ? MF_CHECKED : MF_UNCHECKED); -#endif -#ifdef ENABLE_CDROM_LOG - CheckMenuItem(menu, IDM_LOG_CDROM, cdrom_do_log ? MF_CHECKED : MF_UNCHECKED); -#endif -#ifdef ENABLE_D86F_LOG - CheckMenuItem(menu, IDM_LOG_D86F, d86f_do_log ? MF_CHECKED : MF_UNCHECKED); -#endif -#ifdef ENABLE_FDC_LOG - CheckMenuItem(menu, IDM_LOG_FDC, fdc_do_log ? MF_CHECKED : MF_UNCHECKED); -#endif -#ifdef ENABLE_IDE_LOG - CheckMenuItem(menu, IDM_LOG_IDE, ide_do_log ? MF_CHECKED : MF_UNCHECKED); -#endif -#ifdef ENABLE_NE2000_LOG - CheckMenuItem(menu, IDM_LOG_NE2000, ne2000_do_log ? MF_CHECKED : MF_UNCHECKED); -#endif -#endif - - CheckMenuItem(menu, IDM_VID_FORCE43, force_43 ? MF_CHECKED : MF_UNCHECKED); - CheckMenuItem(menu, IDM_VID_OVERSCAN, enable_overscan ? MF_CHECKED : MF_UNCHECKED); - CheckMenuItem(menu, IDM_VID_INVERT, invert_display ? MF_CHECKED : MF_UNCHECKED); - - if (vid_resize) CheckMenuItem(menu, IDM_VID_RESIZE, MF_CHECKED); - CheckMenuItem(menu, IDM_VID_DDRAW + vid_api, MF_CHECKED); - CheckMenuItem(menu, IDM_VID_FS_FULL + video_fullscreen_scale, MF_CHECKED); - CheckMenuItem(menu, IDM_VID_REMEMBER, window_remember ? MF_CHECKED : MF_UNCHECKED); - CheckMenuItem(menu, IDM_VID_SCALE_1X + scale, MF_CHECKED); - - d=romset; - for (c=0;c= 0; c--) - { - if (gfx_present[c]) - { - gfxcard = c; - saveconfig(); - resetpchard(); - break; - } - } - } - - loadbios(); - resetpchard(); - - timeBeginPeriod(1); - - atexit(releasemouse); - - ghMutex = CreateMutex(NULL, FALSE, NULL); - mainthreadh=(HANDLE)_beginthread(mainthread,0,NULL); - SetThreadPriority(mainthreadh, THREAD_PRIORITY_HIGHEST); - - - updatewindowsize(640, 480); - - QueryPerformanceFrequency(&qpc_freq); - timer_freq = qpc_freq.QuadPart; - - if (start_in_fullscreen) - { - startblit(); - mouse_close(); - vid_apis[0][vid_api].close(); - video_fullscreen = 1; - vid_apis[1][vid_api].init(hwndRender); - mouse_init(); - leave_fullscreen_flag = 0; - endblit(); - device_force_redraw(); - } - if (window_remember) - { - MoveWindow(hwnd, window_x, window_y, - window_w, - window_h, - TRUE); - } - else - { - MoveWindow(hwndRender, 0, 0, - winsizex, - winsizey, - TRUE); - MoveWindow(hwndStatus, 0, winsizey + 6, - winsizex, - 17, - TRUE); - } - - /* Run the message loop. It will run until GetMessage() returns 0 */ - while (!quited) - { - while (((bRet = GetMessage(&messages,NULL,0,0)) != 0) && !quited) - { - if (bRet == -1) - { - fatal("bRet is -1\n"); - } - - if (messages.message==WM_QUIT) quited=1; - if (!TranslateAccelerator(hwnd, haccel, &messages)) - { - TranslateMessage(&messages); - DispatchMessage(&messages); - } - - if (recv_key[0x58] && recv_key[0x42] && mousecapture) - { - ClipCursor(&oldclip); - ShowCursor(TRUE); - mousecapture=0; - } - - if ((recv_key[0x1D] || recv_key[0x9D]) && - (recv_key[0x38] || recv_key[0xB8]) && - (recv_key[0x51] || recv_key[0xD1]) && - video_fullscreen) - { - leave_fullscreen(); - } - } - - quited=1; - } - - startblit(); - Sleep(200); - TerminateThread(mainthreadh,0); - savenvr(); - saveconfig(); - closepc(); - - vid_apis[video_fullscreen][vid_api].close(); - - timeEndPeriod(1); - if (mousecapture) - { - ClipCursor(&oldclip); - ShowCursor(TRUE); - } - - UnregisterClass(szSubClassName, hinstance); - UnregisterClass(szClassName, hinstance); - - return messages.wParam; -} - -HHOOK hKeyboardHook; -int hook_enabled = 0; - -LRESULT CALLBACK LowLevelKeyboardProc( int nCode, WPARAM wParam, LPARAM lParam ) -{ - BOOL bControlKeyDown; - KBDLLHOOKSTRUCT* p; - - if (nCode < 0 || nCode != HC_ACTION) - return CallNextHookEx( hKeyboardHook, nCode, wParam, lParam); - - p = (KBDLLHOOKSTRUCT*)lParam; - - if (p->vkCode == VK_TAB && p->flags & LLKHF_ALTDOWN) return 1; /* disable alt-tab */ - if (p->vkCode == VK_SPACE && p->flags & LLKHF_ALTDOWN) return 1; /* disable alt-tab */ - if((p->vkCode == VK_LWIN) || (p->vkCode == VK_RWIN)) return 1; /* disable windows keys */ - if (p->vkCode == VK_ESCAPE && p->flags & LLKHF_ALTDOWN) return 1; /* disable alt-escape */ - bControlKeyDown = GetAsyncKeyState (VK_CONTROL) >> ((sizeof(SHORT) * 8) - 1); /* checks ctrl key pressed */ - if (p->vkCode == VK_ESCAPE && bControlKeyDown) return 1; /* disable ctrl-escape */ - - return CallNextHookEx( hKeyboardHook, nCode, wParam, lParam ); -} - -void cdrom_close(uint8_t id) -{ - switch (cdrom_drives[id].host_drive) - { - case 0: - null_close(id); - break; - default: - ioctl_close(id); - break; - case 200: - image_close(id); - break; - } -} - -int ide_ter_set_irq(HMENU hmenu, int irq, int id) -{ - if (ide_irq[2] == irq) - { - return 0; - } - if (msgbox_reset_yn(ghwnd) != IDYES) - { - return 0; - } - pause = 1; - Sleep(100); - ide_irq[2] = irq; - CheckMenuItem(hmenu, IDM_IDE_TER_IRQ9, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_IDE_TER_IRQ10, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_IDE_TER_IRQ11, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_IDE_TER_IRQ12, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_IDE_TER_IRQ14, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_IDE_TER_IRQ15, MF_UNCHECKED); - CheckMenuItem(hmenu, id, MF_CHECKED); - saveconfig(); - resetpchard(); - pause = 0; - return 1; -} - -int ide_qua_set_irq(HMENU hmenu, int irq, int id) -{ - if (ide_irq[3] == irq) - { - return 0; - } - if (msgbox_reset_yn(ghwnd) != IDYES) - { - return 0; - } - pause = 1; - Sleep(100); - ide_irq[3] = irq; - CheckMenuItem(hmenu, IDM_IDE_QUA_IRQ9, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_IDE_QUA_IRQ10, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_IDE_QUA_IRQ11, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_IDE_QUA_IRQ12, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_IDE_QUA_IRQ14, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_IDE_QUA_IRQ15, MF_UNCHECKED); - CheckMenuItem(hmenu, id, MF_CHECKED); - saveconfig(); - resetpchard(); - pause = 0; - return 1; -} - -void video_toggle_option(HMENU hmenu, int *val, int id) -{ - *val ^= 1; - CheckMenuItem(hmenu, id, *val ? MF_CHECKED : MF_UNCHECKED); - saveconfig(); -} - -void win_cdrom_eject(uint8_t id) -{ - HMENU hmenu; - hmenu = GetSubMenu(smenu, id + 4); - if (cdrom_drives[id].host_drive == 0) - { - /* Switch from empty to empty. Do nothing. */ - return; - } - 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(hmenu, IDM_CDROM_1_IMAGE + id, MF_UNCHECKED); - if ((cdrom_drives[id].host_drive >= 65) && (cdrom_drives[id].host_drive <= 90)) - { - CheckMenuItem(hmenu, IDM_CDROM_1_REAL + id + (cdrom_drive << 2), MF_UNCHECKED); - } - cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; - cdrom_drives[id].host_drive=0; - CheckMenuItem(hmenu, IDM_CDROM_1_EMPTY + id, MF_CHECKED); - update_status_bar_icon_state(0x10 | id, get_cd_state(id)); - update_tip(0x10 | id); - saveconfig(); -} - -void win_cdrom_reload(uint8_t id) -{ - HMENU hmenu; - hmenu = GetSubMenu(smenu, id + 4); - int new_cdrom_drive; - 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) - { - image_open(id, cdrom_image[id].image_path); - if (cdrom_drives[id].bus_type) - { - /* Signal disc change to the emulated machine. */ - cdrom_insert(id); - } - CheckMenuItem(hmenu, IDM_CDROM_1_EMPTY + id, MF_UNCHECKED); - cdrom_drives[id].host_drive = 200; - CheckMenuItem(hmenu, IDM_CDROM_1_IMAGE + id, MF_CHECKED); - } - 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(hmenu, IDM_CDROM_1_EMPTY + id, MF_UNCHECKED); - cdrom_drive = new_cdrom_drive; - CheckMenuItem(hmenu, IDM_CDROM_1_REAL + id + (cdrom_drives[id].host_drive << 2), MF_CHECKED); - } - update_status_bar_icon_state(0x10 | id, get_cd_state(id)); - update_tip(0x10 | id); - saveconfig(); -} - -static BOOL CALLBACK about_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - HWND h; - - switch (message) - { - case WM_INITDIALOG: - pause = 1; - h = GetDlgItem(hdlg, IDC_ABOUT_ICON); - SendMessage(h, STM_SETIMAGE, (WPARAM) IMAGE_ICON, (LPARAM) LoadIconBig((PCTSTR) 100)); - break; - - case WM_COMMAND: - switch (LOWORD(wParam)) - { - case IDOK: - EndDialog(hdlg, 0); - pause = 0; - return TRUE; - default: - break; - } - break; - } - - return FALSE; -} - -void about_open(HWND hwnd) -{ - DialogBox(hinstance, (LPCTSTR) ABOUTDLG, hwnd, about_dlgproc); -} - -LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - HMENU hmenu; - RECT rect; - uint32_t ri_size = 0; - int edgex, edgey; - int sb_borders[3]; - - switch (message) - { - case WM_CREATE: - SetTimer(hwnd, TIMER_1SEC, 1000, NULL); - hKeyboardHook = SetWindowsHookEx( WH_KEYBOARD_LL, LowLevelKeyboardProc, GetModuleHandle(NULL), 0 ); - hook_enabled = 1; - break; - - case WM_COMMAND: - hmenu=GetMenu(hwnd); - switch (LOWORD(wParam)) - { - case IDM_FILE_HRESET: - pause=1; - Sleep(100); - savenvr(); - saveconfig(); - resetpchard(); - pause=0; - break; - case IDM_FILE_RESET_CAD: - pause=1; - Sleep(100); - savenvr(); - saveconfig(); - resetpc_cad(); - pause=0; - break; - case IDM_FILE_EXIT: - PostQuitMessage (0); /* send a WM_QUIT to the message queue */ - break; - case IDM_CONFIG: - win_settings_open(hwnd); - break; - case IDM_ABOUT: - about_open(hwnd); - break; - case IDM_STATUS: - status_open(hwnd); - break; - - case IDM_VID_RESIZE: - vid_resize=!vid_resize; - CheckMenuItem(hmenu, IDM_VID_RESIZE, (vid_resize)?MF_CHECKED:MF_UNCHECKED); - if (vid_resize) SetWindowLong(hwnd, GWL_STYLE, WS_OVERLAPPEDWINDOW|WS_VISIBLE); - else SetWindowLong(hwnd, GWL_STYLE, (WS_OVERLAPPEDWINDOW&~WS_SIZEBOX&~WS_THICKFRAME&~WS_MAXIMIZEBOX)|WS_VISIBLE); - SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_MINIMIZEBOX); - GetWindowRect(hwnd,&rect); - SetWindowPos(hwnd, 0, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER | SWP_FRAMECHANGED); - GetWindowRect(hwndStatus,&rect); - SetWindowPos(hwndStatus, 0, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER | SWP_FRAMECHANGED); - if (vid_resize) - { - CheckMenuItem(hmenu, IDM_VID_SCALE_1X + scale, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_VID_SCALE_2X, MF_CHECKED); - scale = 1; - } - EnableMenuItem(hmenu, IDM_VID_SCALE_1X, vid_resize ? MF_GRAYED : MF_ENABLED); - EnableMenuItem(hmenu, IDM_VID_SCALE_2X, vid_resize ? MF_GRAYED : MF_ENABLED); - EnableMenuItem(hmenu, IDM_VID_SCALE_3X, vid_resize ? MF_GRAYED : MF_ENABLED); - EnableMenuItem(hmenu, IDM_VID_SCALE_4X, vid_resize ? MF_GRAYED : MF_ENABLED); - win_doresize = 1; - saveconfig(); - break; - case IDM_VID_REMEMBER: - window_remember = !window_remember; - CheckMenuItem(hmenu, IDM_VID_REMEMBER, window_remember ? MF_CHECKED : MF_UNCHECKED); - GetWindowRect(hwnd, &rect); - if (window_remember) - { - window_x = rect.left; - window_y = rect.top; - window_w = rect.right - rect.left; - window_h = rect.bottom - rect.top; - } - saveconfig(); - break; - - case IDM_VID_DDRAW: case IDM_VID_D3D: - startblit(); - video_wait_for_blit(); - CheckMenuItem(hmenu, IDM_VID_DDRAW + vid_api, MF_UNCHECKED); - vid_apis[0][vid_api].close(); - vid_api = LOWORD(wParam) - IDM_VID_DDRAW; - CheckMenuItem(hmenu, IDM_VID_DDRAW + vid_api, MF_CHECKED); - vid_apis[0][vid_api].init(hwndRender); - endblit(); - saveconfig(); - device_force_redraw(); - break; - - case IDM_VID_FULLSCREEN: - - if(video_fullscreen!=1){ - - if (video_fullscreen_first) - { - video_fullscreen_first = 0; - msgbox_info(ghwnd, 2193); - } - startblit(); - video_wait_for_blit(); - mouse_close(); - vid_apis[0][vid_api].close(); - video_fullscreen = 1; - vid_apis[1][vid_api].init(ghwnd); - mouse_init(); - leave_fullscreen_flag = 0; - endblit(); - device_force_redraw(); - } - break; - - case IDM_VID_FS_FULL: - case IDM_VID_FS_43: - case IDM_VID_FS_SQ: - case IDM_VID_FS_INT: - CheckMenuItem(hmenu, IDM_VID_FS_FULL + video_fullscreen_scale, MF_UNCHECKED); - video_fullscreen_scale = LOWORD(wParam) - IDM_VID_FS_FULL; - CheckMenuItem(hmenu, IDM_VID_FS_FULL + video_fullscreen_scale, MF_CHECKED); - saveconfig(); - break; - - case IDM_VID_SCALE_1X: - case IDM_VID_SCALE_2X: - case IDM_VID_SCALE_3X: - case IDM_VID_SCALE_4X: - CheckMenuItem(hmenu, IDM_VID_SCALE_1X + scale, MF_UNCHECKED); - scale = LOWORD(wParam) - IDM_VID_SCALE_1X; - CheckMenuItem(hmenu, IDM_VID_SCALE_1X + scale, MF_CHECKED); - saveconfig(); - break; - - case IDM_VID_FORCE43: - video_toggle_option(hmenu, &force_43, IDM_VID_FORCE43); - break; - - case IDM_VID_INVERT: - video_toggle_option(hmenu, &invert_display, IDM_VID_INVERT); - break; - - case IDM_VID_OVERSCAN: - video_toggle_option(hmenu, &enable_overscan, IDM_VID_OVERSCAN); - update_overscan = 1; - break; - - case IDM_VID_FLASH: - video_toggle_option(hmenu, &enable_flash, IDM_VID_FLASH); - break; - - case IDM_VID_SCREENSHOT: - take_screenshot(); - break; - -#ifdef ENABLE_LOG_TOGGLES -#ifdef ENABLE_BUSLOGIC_LOG - case IDM_LOG_BUSLOGIC: - buslogic_do_log ^= 1; - CheckMenuItem(hmenu, IDM_LOG_BUSLOGIC, buslogic_do_log ? MF_CHECKED : MF_UNCHECKED); - break; -#endif - -#ifdef ENABLE_CDROM_LOG - case IDM_LOG_CDROM: - cdrom_do_log ^= 1; - CheckMenuItem(hmenu, IDM_LOG_CDROM, cdrom_do_log ? MF_CHECKED : MF_UNCHECKED); - break; -#endif - -#ifdef ENABLE_D86F_LOG - case IDM_LOG_D86F: - d86f_do_log ^= 1; - CheckMenuItem(hmenu, IDM_LOG_D86F, d86f_do_log ? MF_CHECKED : MF_UNCHECKED); - break; -#endif - -#ifdef ENABLE_FDC_LOG - case IDM_LOG_FDC: - fdc_do_log ^= 1; - CheckMenuItem(hmenu, IDM_LOG_FDC, fdc_do_log ? MF_CHECKED : MF_UNCHECKED); - break; -#endif - -#ifdef ENABLE_IDE_LOG - case IDM_LOG_IDE: - ide_do_log ^= 1; - CheckMenuItem(hmenu, IDM_LOG_IDE, ide_do_log ? MF_CHECKED : MF_UNCHECKED); - break; -#endif - -#ifdef ENABLE_NE2000_LOG - case IDM_LOG_NE2000: - ne2000_do_log ^= 1; - CheckMenuItem(hmenu, IDM_LOG_NE2000, ne2000_do_log ? MF_CHECKED : MF_UNCHECKED); - break; -#endif -#endif - -#ifdef ENABLE_LOG_BREAKPOINT - case IDM_LOG_BREAKPOINT: - pclog("---- LOG BREAKPOINT ----\n"); - break; -#endif - -#ifdef ENABLE_VRAM_DUMP - case IDM_DUMP_VRAM: - svga_dump_vram(); - break; -#endif - - case IDM_CONFIG_LOAD: - pause = 1; - if (!file_dlg_st(hwnd, 2174, "", 0)) - { - if (msgbox_reset_yn(ghwnd) == IDYES) - { - config_save(config_file_default); - loadconfig(wopenfilestring); - pclog_w(L"NVR path: %s\n", nvr_path); - mem_resize(); - loadbios(); - resetpchard(); - } - } - pause = 0; - break; - - case IDM_CONFIG_SAVE: - pause = 1; - if (!file_dlg_st(hwnd, 2174, "", 1)) - config_save(wopenfilestring); - pause = 0; - break; - } - return 0; - - case WM_INPUT: - { - UINT size; - RAWINPUT *raw; - - if (!infocus) - break; - - GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &size, sizeof(RAWINPUTHEADER)); - - raw = malloc(size); - - if (raw == NULL) - { - return 0; - } - - /* 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 0; - } - - /* If the input is keyboard, we process it */ - if (raw->header.dwType == RIM_TYPEKEYBOARD) - { - const RAWKEYBOARD rawKB = raw->data.keyboard; - USHORT 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)) - { - rawinputkey[scancode & 0x1ff] = !(rawKB.Flags & RI_KEY_BREAK); - recv_key[scancode & 0x1ff] = rawinputkey[scancode & 0x1ff]; - } - } - else - { - if (rawKB.MakeCode == 0x1D) - scancode = 0xFF; - if (!(scancode & 0xf00)) - { - rawinputkey[scancode & 0x1ff] = !(rawKB.Flags & RI_KEY_BREAK); - recv_key[scancode & 0x1ff] = rawinputkey[scancode & 0x1ff]; - } - } - } - free(raw); - - } - break; - - case WM_SETFOCUS: - infocus=1; - if (!hook_enabled) - { - hKeyboardHook = SetWindowsHookEx( WH_KEYBOARD_LL, LowLevelKeyboardProc, GetModuleHandle(NULL), 0 ); - hook_enabled = 1; - } - break; - - case WM_KILLFOCUS: - infocus=0; - if (mousecapture) - { - ClipCursor(&oldclip); - ShowCursor(TRUE); - mousecapture=0; - } - memset(rawinputkey, 0, sizeof(rawinputkey)); - if (video_fullscreen) - leave_fullscreen_flag = 1; - if (hook_enabled) - { - UnhookWindowsHookEx(hKeyboardHook); - hook_enabled = 0; - } - break; - - case WM_LBUTTONUP: - if (!mousecapture && !video_fullscreen) - { - RECT pcclip; - - GetClipCursor(&oldclip); - GetWindowRect(hwnd, &pcclip); - pcclip.left += GetSystemMetrics(SM_CXFIXEDFRAME) + 10; - pcclip.right -= GetSystemMetrics(SM_CXFIXEDFRAME) + 10; - pcclip.top += GetSystemMetrics(SM_CXFIXEDFRAME) + GetSystemMetrics(SM_CYMENUSIZE) + GetSystemMetrics(SM_CYCAPTION) + 10; - pcclip.bottom -= GetSystemMetrics(SM_CXFIXEDFRAME) + 10; - ClipCursor(&pcclip); - mousecapture = 1; - while (1) - { - if (ShowCursor(FALSE) < 0) break; - } - } - break; - - case WM_MBUTTONUP: - if (!(mouse_get_type(mouse_type) & MOUSE_TYPE_3BUTTON)) - releasemouse(); - break; - - case WM_ENTERMENULOOP: - break; - - case WM_SIZE: - winsizex = (lParam & 0xFFFF); - winsizey = (lParam >> 16) - (17 + 6); - - MoveWindow(hwndRender, 0, 0, - winsizex, - winsizey, - TRUE); - - if (vid_apis[video_fullscreen][vid_api].resize) - { - startblit(); - video_wait_for_blit(); - vid_apis[video_fullscreen][vid_api].resize(winsizex, winsizey); - endblit(); - } - - MoveWindow(hwndStatus, 0, winsizey + 6, - winsizex, - 17, - TRUE); - - if (mousecapture) - { - RECT pcclip; - - GetWindowRect(hwnd, &pcclip); - pcclip.left += GetSystemMetrics(SM_CXFIXEDFRAME) + 10; - pcclip.right -= GetSystemMetrics(SM_CXFIXEDFRAME) + 10; - pcclip.top += GetSystemMetrics(SM_CXFIXEDFRAME) + GetSystemMetrics(SM_CYMENUSIZE) + GetSystemMetrics(SM_CYCAPTION) + 10; - pcclip.bottom -= GetSystemMetrics(SM_CXFIXEDFRAME) + 10; - ClipCursor(&pcclip); - } - if (window_remember) - { - GetWindowRect(hwnd, &rect); - window_x = rect.left; - window_y = rect.top; - window_w = rect.right - rect.left; - window_h = rect.bottom - rect.top; - save_window_pos = 1; - } - break; - - case WM_MOVE: - if (window_remember) - { - GetWindowRect(hwnd, &rect); - window_x = rect.left; - window_y = rect.top; - window_w = rect.right - rect.left; - window_h = rect.bottom - rect.top; - save_window_pos = 1; - } - break; - - case WM_TIMER: - if (wParam == TIMER_1SEC) - onesec(); - break; - - case WM_RESETD3D: - startblit(); - if (video_fullscreen) - d3d_fs_reset(); - else - d3d_reset(); - endblit(); - break; - - case WM_LEAVEFULLSCREEN: - startblit(); - mouse_close(); - vid_apis[1][vid_api].close(); - video_fullscreen = 0; - vid_apis[0][vid_api].init(ghwnd); - mouse_init(); - endblit(); - device_force_redraw(); - break; - - case WM_KEYDOWN: - case WM_SYSKEYDOWN: - case WM_KEYUP: - case WM_SYSKEYUP: - return 0; - - case WM_DESTROY: - UnhookWindowsHookEx( hKeyboardHook ); - KillTimer(hwnd, TIMER_1SEC); - PostQuitMessage (0); /* send a WM_QUIT to the message queue */ - break; - - case WM_SYSCOMMAND: - /* Disable ALT key *ALWAYS*, I don't think there's any use for reaching the menu that way. */ - if (wParam == SC_KEYMENU && HIWORD(lParam) <= 0) - return 0; /*disable ALT key for menu*/ - - default: - return DefWindowProc (hwnd, message, wParam, lParam); - } - return 0; -} - -LRESULT CALLBACK subWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - switch (message) - { - default: - return DefWindowProc(hwnd, message, wParam, lParam); - } - return 0; -} - -VOID APIENTRY HandlePopupMenu(HWND hwnd, POINT pt, int id) -{ - HMENU pmenu; - int menu_id = -1; - if (id >= (sb_parts - 1)) - { - return; - } - pt.x = id * sb_icon_width; /* Justify to the left. */ - pt.y = 0; /* Justify to the top. */ - ClientToScreen(hwnd, (LPPOINT) &pt); - if ((sb_part_meanings[id] & 0x30) == 0x00) - { - menu_id = sb_part_meanings[id] & 0xf; - } - else if ((sb_part_meanings[id] & 0x30) == 0x10) - { - menu_id = (sb_part_meanings[id] & 0xf) + 4; - } - if (menu_id != -1) - { - pmenu = GetSubMenu(smenu, menu_id); - TrackPopupMenu(pmenu, TPM_LEFTALIGN | TPM_BOTTOMALIGN | TPM_LEFTBUTTON, pt.x, pt.y, 0, hwndStatus, NULL); - } -} - -LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - RECT rc; - POINT pt; - - WCHAR temp_image_path[1024]; - int new_cdrom_drive; - int cdrom_id = 0; - int menu_sub_param = 0; - int menu_super_param = 0; - int ret = 0; - - HMENU hmenu; - - switch (message) - { - case WM_COMMAND: - switch (LOWORD(wParam)) - { - case IDM_DISC_1: - case IDM_DISC_1_WP: - ret = file_dlg_w_st(hwnd, 2173, discfns[0], 0); - if (!ret) - { - disc_close(0); - ui_writeprot[0] = (LOWORD(wParam) == IDM_DISC_1_WP) ? 1 : 0; - disc_load(0, wopenfilestring); - update_status_bar_icon_state(0x00, 0); - update_tip(0x00); - saveconfig(); - } - break; - case IDM_DISC_2: - case IDM_DISC_2_WP: - ret = file_dlg_w_st(hwnd, 2173, discfns[1], 0); - if (!ret) - { - disc_close(1); - ui_writeprot[1] = (LOWORD(wParam) == IDM_DISC_2_WP) ? 1 : 0; - disc_load(1, wopenfilestring); - update_status_bar_icon_state(0x01, 0); - update_tip(0x01); - saveconfig(); - } - break; - case IDM_DISC_3: - case IDM_DISC_3_WP: - ret = file_dlg_w_st(hwnd, 2173, discfns[2], 0); - if (!ret) - { - disc_close(2); - ui_writeprot[2] = (LOWORD(wParam) == IDM_DISC_3_WP) ? 1 : 0; - disc_load(2, wopenfilestring); - update_status_bar_icon_state(0x02, 0); - update_tip(0x02); - saveconfig(); - } - break; - case IDM_DISC_4: - case IDM_DISC_4_WP: - ret = file_dlg_w_st(hwnd, 2173, discfns[3], 0); - if (!ret) - { - disc_close(3); - ui_writeprot[3] = (LOWORD(wParam) == IDM_DISC_4_WP) ? 1 : 0; - disc_load(3, wopenfilestring); - update_status_bar_icon_state(0x03, 0); - update_tip(0x03); - saveconfig(); - } - break; - case IDM_EJECT_1: - disc_close(0); - update_status_bar_icon_state(0x00, 1); - update_tip(0x00); - saveconfig(); - break; - case IDM_EJECT_2: - disc_close(1); - update_status_bar_icon_state(0x01, 1); - update_tip(0x01); - saveconfig(); - break; - case IDM_EJECT_3: - disc_close(2); - update_status_bar_icon_state(0x02, 1); - update_tip(0x02); - saveconfig(); - break; - case IDM_EJECT_4: - disc_close(3); - update_status_bar_icon_state(0x03, 1); - update_tip(0x03); - saveconfig(); - break; - - case IDM_CDROM_1_MUTE: - case IDM_CDROM_2_MUTE: - case IDM_CDROM_3_MUTE: - case IDM_CDROM_4_MUTE: - cdrom_id = LOWORD(wParam) & 3; - hmenu = GetSubMenu(smenu, cdrom_id + 4); - Sleep(100); - cdrom_drives[cdrom_id].sound_on ^= 1; - CheckMenuItem(hmenu, IDM_CDROM_1_MUTE + (cdrom_id * 1000), cdrom_drives[cdrom_id].sound_on ? MF_UNCHECKED : MF_CHECKED); - saveconfig(); - sound_cd_thread_reset(); - break; - - case IDM_CDROM_1_EMPTY: - case IDM_CDROM_2_EMPTY: - case IDM_CDROM_3_EMPTY: - case IDM_CDROM_4_EMPTY: - cdrom_id = LOWORD(wParam) & 3; - hmenu = GetSubMenu(smenu, cdrom_id + 4); - win_cdrom_eject(cdrom_id); - break; - - case IDM_CDROM_1_RELOAD: - case IDM_CDROM_2_RELOAD: - case IDM_CDROM_3_RELOAD: - case IDM_CDROM_4_RELOAD: - cdrom_id = LOWORD(wParam) & 3; - hmenu = GetSubMenu(smenu, cdrom_id + 4); - win_cdrom_reload(cdrom_id); - break; - - case IDM_CDROM_1_IMAGE: - case IDM_CDROM_2_IMAGE: - case IDM_CDROM_3_IMAGE: - case IDM_CDROM_4_IMAGE: - cdrom_id = LOWORD(wParam) & 3; - hmenu = GetSubMenu(smenu, cdrom_id + 4); - if (!file_dlg_w_st(hwnd, 2175, cdrom_image[cdrom_id].image_path, 0)) - { - cdrom_drives[cdrom_id].prev_host_drive = cdrom_drives[cdrom_id].host_drive; - wcscpy(temp_image_path, wopenfilestring); - if ((wcscmp(cdrom_image[cdrom_id].image_path, temp_image_path) == 0) && (cdrom_drives[cdrom_id].host_drive == 200)) - { - /* Switching from image to the same image. Do nothing. */ - break; - } - cdrom_drives[cdrom_id].handler->exit(cdrom_id); - cdrom_close(cdrom_id); - image_open(cdrom_id, temp_image_path); - if (cdrom_drives[cdrom_id].bus_type) - { - /* Signal disc change to the emulated machine. */ - cdrom_insert(cdrom_id); - } - CheckMenuItem(hmenu, IDM_CDROM_1_EMPTY + cdrom_id, MF_UNCHECKED); - if ((cdrom_drives[cdrom_id].host_drive != 0) && (cdrom_drives[cdrom_id].host_drive != 200)) - { - CheckMenuItem(hmenu, IDM_CDROM_1_REAL + cdrom_id + (cdrom_drives[cdrom_id].host_drive << 2), MF_UNCHECKED); - } - cdrom_drives[cdrom_id].host_drive = 200; - CheckMenuItem(hmenu, IDM_CDROM_1_IMAGE + cdrom_id, MF_CHECKED); - update_tip(0x10 | cdrom_id); - saveconfig(); - } - break; - - default: - cdrom_id = LOWORD(wParam) & 3; - hmenu = GetSubMenu(smenu, cdrom_id + 4); - menu_sub_param = ((LOWORD(wParam) - IDM_CDROM_1_REAL) - cdrom_id) >> 2; - /* pclog("[%04X] Guest drive %c [%i]: -> Host drive %c [%i]:\n", LOWORD(wParam), 0x4b + cdrom_id, cdrom_id, menu_sub_param, menu_sub_param); */ - if (((LOWORD(wParam) & ~3) >= (IDM_CDROM_1_REAL + ('A' << 2))) && ((LOWORD(wParam) & ~3) <= (IDM_CDROM_1_REAL + ('Z' << 2)))) - { - new_cdrom_drive = menu_sub_param; - if (cdrom_drives[cdrom_id].host_drive == new_cdrom_drive) - { - /* Switching to the same drive. Do nothing. */ - break; - } - cdrom_drives[cdrom_id].prev_host_drive = cdrom_drives[cdrom_id].host_drive; - cdrom_drives[cdrom_id].handler->exit(cdrom_id); - cdrom_close(cdrom_id); - ioctl_open(cdrom_id, new_cdrom_drive); - if (cdrom_drives[cdrom_id].bus_type) - { - /* Signal disc change to the emulated machine. */ - cdrom_insert(cdrom_id); - } - CheckMenuItem(hmenu, IDM_CDROM_1_EMPTY + cdrom_id, MF_UNCHECKED); - if ((cdrom_drives[cdrom_id].host_drive != 0) && (cdrom_drives[cdrom_id].host_drive != 200)) - { - CheckMenuItem(hmenu, IDM_CDROM_1_REAL + cdrom_id + (cdrom_drives[cdrom_id].host_drive << 2), MF_UNCHECKED); - } - CheckMenuItem(hmenu, IDM_CDROM_1_IMAGE + cdrom_id, MF_UNCHECKED); - cdrom_drives[cdrom_id].host_drive = new_cdrom_drive; - CheckMenuItem(hmenu, IDM_CDROM_1_REAL + cdrom_id + (cdrom_drives[cdrom_id].host_drive << 2), MF_CHECKED); - update_tip(0x10 | cdrom_id); - saveconfig(); - } - break; - } - return 0; - - case WM_LBUTTONDOWN: - case WM_RBUTTONDOWN: - GetClientRect(hwnd, (LPRECT)& rc); - pt.x = GET_X_LPARAM(lParam); - pt.y = GET_Y_LPARAM(lParam); - if (PtInRect((LPRECT) &rc, pt)) - { - HandlePopupMenu(hwnd, pt, (pt.x / sb_icon_width)); - } - break; - - default: - return CallWindowProc((WNDPROC) OriginalStatusBarProcedure, hwnd, message, wParam, lParam); - } - return 0; -} diff --git a/src/win.h b/src/win.h deleted file mode 100644 index 0e09db88f..000000000 --- a/src/win.h +++ /dev/null @@ -1,51 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -extern HINSTANCE hinstance; -extern HWND ghwnd; -extern int mousecapture; - -#ifdef __cplusplus -extern "C" { -#endif - -#define szClassName L"86BoxMainWnd" -#define szSubClassName L"86BoxSubWnd" -#define szStatusBarClassName L"86BoxStatusBar" - -void leave_fullscreen(); - -#ifdef __cplusplus -} -#endif - - -void status_open(HWND hwnd); -extern HWND status_hwnd; -extern int status_is_open; - -void deviceconfig_open(HWND hwnd, struct device_t *device); -void joystickconfig_open(HWND hwnd, int joy_nr, int type); - -extern char openfilestring[260]; -extern WCHAR wopenfilestring[260]; - -int getfile(HWND hwnd, char *f, char *fn); -int getsfile(HWND hwnd, char *f, char *fn); - -void get_executable_name(WCHAR *s, int size); -void set_window_title(WCHAR *s); - -void startblit(); -void endblit(); - -extern int pause; - -void win_settings_open(HWND hwnd); -void win_menu_update(); - -void update_status_bar_panes(HWND hwnds); - -int fdd_type_to_icon(int type); - -extern HWND hwndStatus; From a4a69f71eb774ab07adc790202c45a02f71ea886 Mon Sep 17 00:00:00 2001 From: waltje Date: Thu, 18 May 2017 14:03:43 -0400 Subject: [PATCH 2/2] The, uhh, missing stufff......... --- src/86box.cfg | Bin 0 -> 7452 bytes src/CPU/codegen_x86-64.c | 6 +- src/Makefile.mingw | 4 +- src/WIN/86Box.manifest | 22 + src/WIN/86Box.rc | 941 ++++++++ src/WIN/pcap_if.rc | 52 + src/WIN/plat_dinput.h | 4 + src/WIN/plat_dir.h | 76 + src/WIN/plat_joystick.h | 69 + src/WIN/plat_keyboard.h | 22 + src/WIN/plat_midi.h | 10 + src/WIN/plat_mouse.h | 16 + src/WIN/plat_serial.h | 49 + src/WIN/resource.h | 432 ++++ src/WIN/win.c | 2427 ++++++++++++++++++++ src/WIN/win.h | 51 + src/WIN/win_cgapal.h | 13 + src/WIN/win_crashdump.c | 185 ++ src/WIN/win_crashdump.h | 7 + src/WIN/win_d3d-fs.cc | 587 +++++ src/WIN/win_d3d-fs.h | 13 + src/WIN/win_d3d.cc | 398 ++++ src/WIN/win_d3d.h | 13 + src/WIN/win_ddraw-fs.cc | 338 +++ src/WIN/win_ddraw-fs.h | 11 + src/WIN/win_ddraw-screenshot.cc | 178 ++ src/WIN/win_ddraw-screenshot.h | 4 + src/WIN/win_ddraw.cc | 318 +++ src/WIN/win_ddraw.h | 12 + src/WIN/win_deviceconfig.c | 317 +++ src/WIN/win_joystick.cc | 281 +++ src/WIN/win_joystickconfig.c | 541 +++++ src/WIN/win_language.c | 197 ++ src/WIN/win_language.h | 33 + src/WIN/win_midi.c | 279 +++ src/WIN/win_mouse.cc | 75 + src/WIN/win_opendir.c | 213 ++ src/WIN/win_serial.c | 606 +++++ src/WIN/win_settings.c | 3694 +++++++++++++++++++++++++++++++ src/WIN/win_status.c | 95 + src/WIN/win_video.c | 57 + src/cdrom_dosbox.cpp | 565 +++++ src/cdrom_dosbox.h | 173 ++ src/cdrom_image.cc | 1045 +++++++++ src/cdrom_image.h | 28 + src/cdrom_ioctl.c | 1099 +++++++++ src/cdrom_ioctl.h | 17 + src/cdrom_ioctl_linux.c | 725 ++++++ src/cdrom_null.c | 130 ++ src/cdrom_null.h | 14 + 50 files changed, 16436 insertions(+), 6 deletions(-) create mode 100644 src/86box.cfg create mode 100644 src/WIN/86Box.manifest create mode 100644 src/WIN/86Box.rc create mode 100644 src/WIN/pcap_if.rc create mode 100644 src/WIN/plat_dinput.h create mode 100644 src/WIN/plat_dir.h create mode 100644 src/WIN/plat_joystick.h create mode 100644 src/WIN/plat_keyboard.h create mode 100644 src/WIN/plat_midi.h create mode 100644 src/WIN/plat_mouse.h create mode 100644 src/WIN/plat_serial.h create mode 100644 src/WIN/resource.h create mode 100644 src/WIN/win.c create mode 100644 src/WIN/win.h create mode 100644 src/WIN/win_cgapal.h create mode 100644 src/WIN/win_crashdump.c create mode 100644 src/WIN/win_crashdump.h create mode 100644 src/WIN/win_d3d-fs.cc create mode 100644 src/WIN/win_d3d-fs.h create mode 100644 src/WIN/win_d3d.cc create mode 100644 src/WIN/win_d3d.h create mode 100644 src/WIN/win_ddraw-fs.cc create mode 100644 src/WIN/win_ddraw-fs.h create mode 100644 src/WIN/win_ddraw-screenshot.cc create mode 100644 src/WIN/win_ddraw-screenshot.h create mode 100644 src/WIN/win_ddraw.cc create mode 100644 src/WIN/win_ddraw.h create mode 100644 src/WIN/win_deviceconfig.c create mode 100644 src/WIN/win_joystick.cc create mode 100644 src/WIN/win_joystickconfig.c create mode 100644 src/WIN/win_language.c create mode 100644 src/WIN/win_language.h create mode 100644 src/WIN/win_midi.c create mode 100644 src/WIN/win_mouse.cc create mode 100644 src/WIN/win_opendir.c create mode 100644 src/WIN/win_serial.c create mode 100644 src/WIN/win_settings.c create mode 100644 src/WIN/win_status.c create mode 100644 src/WIN/win_video.c create mode 100644 src/cdrom_dosbox.cpp create mode 100644 src/cdrom_dosbox.h create mode 100644 src/cdrom_image.cc create mode 100644 src/cdrom_image.h create mode 100644 src/cdrom_ioctl.c create mode 100644 src/cdrom_ioctl.h create mode 100644 src/cdrom_ioctl_linux.c create mode 100644 src/cdrom_null.c create mode 100644 src/cdrom_null.h diff --git a/src/86box.cfg b/src/86box.cfg new file mode 100644 index 0000000000000000000000000000000000000000..ad83f0d3556b0b9f3477aa51f21bf2a4a3740c75 GIT binary patch literal 7452 zcmb`M+iu%N6h-H`K>wj1P@tkLJ9dG-6e!w0v?6F2U=C}zSh;i zh2Q8JdqA_b|J?eRl`Y7P^4KZL2jzBf_od(8+_&zXd*gm^f9U(QuCLvd`(Al`)b-vo ze^=Um{6ya;jYrDPDnzum?iY1s&nfoLT6Q9NO zsUG;MV#XC;cphPH@%Y~Rt2|lHm}Y+}C-m8tdfiEbkBUOfnJZBBi!sz0$0I&L*tduZniiOl0o9FBy?JS<>4ReW&sb8CLj|X4P1; zKBnqxMZ8yBR!wR}bv~4Ls8Ur|RwDQ|`@5IAtk$eZ8+qO7mv#1}WSG14>{!~JR!3W> zOz+e9=t6Ga zm70}SbdIgAJoo58)^DCCRdx{aW5wKUr<*fYp;9svYAig}dUb4j9Yp z*7pIkmReW24)k1LHq>J+o>1`^_2Ajkk3C*;*n`hu55Ap!kz|i;6MI&O{_OFR!ybGN zd+_b-he`I>HnAURtUr6ay!ybG)`->!dY@66$YOFtdyyUP4pTiz}JNr?RJ+@8k zuQb-5JzjFygU?|PzMcJLl0CLf>|bfDKYP67um_*R9(+6dt0a4Do7i7#tUr6ay z!ybG)`&UW!*fz1h(O7@>c*$W8K8HQ{cJ|jv_SmM`7up;2XK!A*vp0Nq_J(g~f0JNu zwoU9m$6l}SJH{OLM9pCjzKuOR>w7)Rt%*H5p}w78=zS}v^9`TFzRO+@o+U`6Y5`kyyUP4 zpTiz}JNwjLuW;Blv1cdLpFLi3*n`hu55Ap!YOh!5?DIK$J6n09H*iibAM}Q6C%fr0 zvqgDwVy6M|Y0jl)8|n@{2EQ>nRy`hj)O$6jnse#TX-suSZExr&EbCVHsP$DY_S7{h z>qQ(jJli<=tgkEaSl4*W?k@4bHL1$j`FK;+39UJav3iE5kJN*c{p!Sode$x4W=p73 z-TGYD5B=Fp-KMSc2ho~ew_l2{o$T9OKmDzs&XE4e(*%o`Yl8JTP3+V==7deVCgGEy zZl9wGJ)Wlt7BANX>vNin5`BVAyC&iDA=boVcJCABTAn6Yyj&Bk&uMa*&;*-yO~R)} Ktck@ur^)}H>w5zL literal 0 HcmV?d00001 diff --git a/src/CPU/codegen_x86-64.c b/src/CPU/codegen_x86-64.c index 7673a08e4..e591adc95 100644 --- a/src/CPU/codegen_x86-64.c +++ b/src/CPU/codegen_x86-64.c @@ -1,16 +1,14 @@ #ifdef __amd64__ #include -#include "ibm.h" +#include "../ibm.h" +#include "../mem.h" #include "cpu.h" #include "x86.h" #include "x86_flags.h" #include "x86_ops.h" #include "x87.h" -#include "mem.h" - #include "386_common.h" - #include "codegen.h" #include "codegen_ops.h" #include "codegen_ops_x86-64.h" diff --git a/src/Makefile.mingw b/src/Makefile.mingw index d2cbc03e3..39caf693b 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -29,7 +29,7 @@ STUFF = EXTRAS = # Do we want a debugging build? -DEBUG = n +DEBUG = y OPTIM = n X64 = n @@ -200,7 +200,7 @@ LIBS = -mwindows -lcomctl32 -lwinmm -lopenal.dll -lopenal -lddraw \ # Build rules. %.o: %.c @echo $< - @$(CC) $(CFLAGS) -c $< + $(CC) $(CFLAGS) -c $< %.o: %.cc @echo $< diff --git a/src/WIN/86Box.manifest b/src/WIN/86Box.manifest new file mode 100644 index 000000000..be8c16756 --- /dev/null +++ b/src/WIN/86Box.manifest @@ -0,0 +1,22 @@ + + + +Emulator for X86-based systems. + + + + + + diff --git a/src/WIN/86Box.rc b/src/WIN/86Box.rc new file mode 100644 index 000000000..fb5d56296 --- /dev/null +++ b/src/WIN/86Box.rc @@ -0,0 +1,941 @@ +#include + +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#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 +// + +STATUSBARMENU MENU DISCARDABLE +BEGIN + POPUP "FDD 1" + BEGIN + MENUITEM "&Change...", IDM_DISC_1 + MENUITEM "Change FDD 1 (&Write-protected)...", IDM_DISC_1_WP + MENUITEM "&Eject FDD 1", IDM_EJECT_1 + END + POPUP "FDD 2" + BEGIN + MENUITEM "&Change...", IDM_DISC_2 + MENUITEM "Change FDD 2 (&Write-protected)...", IDM_DISC_2_WP + MENUITEM "&Eject FDD 2", IDM_EJECT_2 + END + POPUP "FDD 3" + BEGIN + MENUITEM "&Change...", IDM_DISC_3 + MENUITEM "Change FDD 3 (&Write-protected)...", IDM_DISC_3_WP + MENUITEM "&Eject FDD 3", IDM_EJECT_3 + END + POPUP "FDD 4" + BEGIN + MENUITEM "&Change...", IDM_DISC_4 + MENUITEM "Change FDD 4 (&Write-protected)...", IDM_DISC_4_WP + MENUITEM "&Eject FDD 4", IDM_EJECT_4 + END + POPUP "CD-ROM 1" + BEGIN + MENUITEM "&Mute", IDM_CDROM_1_MUTE + MENUITEM SEPARATOR + MENUITEM "E&mpty", IDM_CDROM_1_EMPTY + MENUITEM "&Reload previous disc", IDM_CDROM_1_RELOAD + MENUITEM SEPARATOR + MENUITEM "&Image...", IDM_CDROM_1_IMAGE + END + POPUP "CD-ROM 2" + BEGIN + MENUITEM "&Mute", IDM_CDROM_2_MUTE + MENUITEM SEPARATOR + MENUITEM "E&mpty", IDM_CDROM_2_EMPTY + MENUITEM "&Reload previous disc", IDM_CDROM_2_RELOAD + MENUITEM SEPARATOR + MENUITEM "&Image...", IDM_CDROM_2_IMAGE + END + POPUP "CD-ROM 3" + BEGIN + MENUITEM "&Mute", IDM_CDROM_3_MUTE + MENUITEM SEPARATOR + MENUITEM "E&mpty", IDM_CDROM_3_EMPTY + MENUITEM "&Reload previous disc", IDM_CDROM_3_RELOAD + MENUITEM SEPARATOR + MENUITEM "&Image...", IDM_CDROM_3_IMAGE + END + POPUP "CD-ROM 4" + BEGIN + MENUITEM "&Mute", IDM_CDROM_4_MUTE + MENUITEM SEPARATOR + MENUITEM "E&mpty", IDM_CDROM_4_EMPTY + MENUITEM "&Reload previous disc", IDM_CDROM_4_RELOAD + MENUITEM SEPARATOR + MENUITEM "&Image...", IDM_CDROM_4_IMAGE + END +END + +MAINMENU MENU DISCARDABLE +BEGIN + POPUP "&Action" + BEGIN + MENUITEM "&Hard Reset", IDM_FILE_HRESET + MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_FILE_RESET_CAD + MENUITEM SEPARATOR + MENUITEM "E&xit", IDM_FILE_EXIT + END + POPUP "&Tools" + BEGIN + MENUITEM "&Settings...", IDM_CONFIG + MENUITEM SEPARATOR + MENUITEM "&Load configuration...", IDM_CONFIG_LOAD + MENUITEM "&Save configuration...", IDM_CONFIG_SAVE + MENUITEM SEPARATOR + POPUP "&Video" + BEGIN + MENUITEM "&Resizeable window", IDM_VID_RESIZE + MENUITEM "R&emember size && position", IDM_VID_REMEMBER + MENUITEM SEPARATOR + MENUITEM "&DirectDraw", IDM_VID_DDRAW + MENUITEM "Direct&3D 9", IDM_VID_D3D + 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", 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 + MENUITEM "&Inverted VGA monitor", IDM_VID_INVERT + MENUITEM SEPARATOR + MENUITEM "F&orce 4:3 display ratio", IDM_VID_FORCE43 + MENUITEM "E&GA/(S)VGA overscan", IDM_VID_OVERSCAN + MENUITEM SEPARATOR + MENUITEM "Take s&creenshot\tCtrl+F11", IDM_VID_SCREENSHOT + END + MENUITEM "S&tatus", IDM_STATUS +#ifdef ENABLE_LOG_TOGGLES +#if defined ENABLE_BUSLOGIC_LOG || defined ENABLE_CDROM_LOG || defined ENABLE_D86F_LOG || defined ENABLE_FDC_LOG || defined ENABLE_IDE_LOG || defined ENABLE_NE2000_LOG + MENUITEM SEPARATOR +#endif +#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_NE2000_LOG + MENUITEM "Enable NE2000 logs\tCtrl+F9", IDM_LOG_NE2000 +#endif +#endif +#ifdef ENABLE_LOG_BREAKPOINT + MENUITEM SEPARATOR + MENUITEM "&Log breakpoint\tCtrl+F10", IDM_LOG_BREAKPOINT +#ifdef ENABLE_VRAM_DUMP + MENUITEM "Dump &video RAM\tCtrl+F1", IDM_DUMP_VRAM +#endif +#else +#ifdef ENABLE_VRAM_DUMP + MENUITEM SEPARATOR + MENUITEM "Dump &video RAM\tCtrl+F1", IDM_DUMP_VRAM +#endif +#endif + END + 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_LOG_TOGGLES +#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_NE2000_LOG + VK_F9, IDM_LOG_NE2000, CONTROL, VIRTKEY +#endif +#endif +#ifdef ENABLE_LOG_BREAKPOINT + VK_F10, IDM_LOG_BREAKPOINT, CONTROL, VIRTKEY +#endif + VK_F11, IDM_VID_SCREENSHOT, VIRTKEY, CONTROL + VK_F12, IDM_FILE_RESET_CAD, VIRTKEY, CONTROL +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +CONFIGUREDLG_MAIN 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 | WS_BORDER | WS_TABSTOP,7,7,90,197 + CONTROL "",-1,"Static",SS_BLACKFRAME | SS_SUNKEN,1,211,363,1 + LTEXT "Language:",2047,7,222,41,10 + COMBOBOX IDC_COMBO_LANG,48,221,108,120,CBS_DROPDOWN | WS_VSCROLL | + WS_TABSTOP +END + +CONFIGUREDLG_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:",IDC_STATIC,154,35,27,10 + LTEXT "Heads:",1793,81,35,29,8 + LTEXT "Cylinders:",1794,7,35,32,12 + LTEXT "Size (MB):",1795,7,54,33,8 + LTEXT "Type:",1797,86,54,24,8 + LTEXT "File name:",-1,7,7,204,9 + COMBOBOX IDC_COMBO_HD_BUS,33,71,58,12,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "Bus:",1798,7,72,24,8 + COMBOBOX IDC_COMBO_HD_CHANNEL,134,71,77,12,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "Channel:",1799,99,72,34,8 + COMBOBOX IDC_COMBO_HD_ID,133,71,26,12,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "ID:",1800,117,72,15,8 + COMBOBOX IDC_COMBO_HD_LUN,185,71,26,12,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "LUN:",1801,168,72,15,8 + COMBOBOX IDC_COMBO_HD_CHANNEL_IDE,134,71,77,12,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "Channel:",1802,99,72,34,8 +END + +STATUSDLG 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",IDC_STEXT_DEVICE,16,16,180,1000 + LTEXT "1",IDC_STEXT1,16,186,180,1000 +END + +ABOUTDLG 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 v1.20 - A fork of PCem\n\nAuthors: Sarah Walker, Tohka, 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 + +CONFIGUREDLG_MACHINE DIALOG DISCARDABLE 97, 0, 267, 112 +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:",1794,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:",1796,7,26,59,10 + COMBOBOX IDC_COMBO_WS,71,44,189,120,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP + LTEXT "Wait states:",1798,7,45,60,10 + COMBOBOX IDC_COMBO_CPU,145,25,115,120,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "CPU:",1797,124,26,18,10 + CONTROL "Dynamic Recompiler",IDC_CHECK_DYNAREC,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,7,80,94,10 + CONTROL "Enable FPU",IDC_CHECK_FPU,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,147,80,113,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",IDC_TEXT_MB,123,64,10,10 + LTEXT "Memory:",1802,7,64,30,10 + CONTROL "Enable time sync",IDC_CHECK_SYNC,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,7,95,102,10 +END + +CONFIGUREDLG_VIDEO DIALOG DISCARDABLE 97, 0, 267, 63 +STYLE DS_CONTROL | WS_CHILD +FONT 9, "Segoe UI" +BEGIN + COMBOBOX IDC_COMBO_VIDEO,71,7,140,120,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "Video:",1795,7,8,55,10 + COMBOBOX IDC_COMBO_VIDEO_SPEED,71,25,189,120,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "Video speed:",1800,7,26,58,10 + CONTROL "Voodoo Graphics",IDC_CHECK_VOODOO,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,7,45,199,10 + PUSHBUTTON "Configure",IDC_CONFIGURE_VOODOO,214,44,46,12 + PUSHBUTTON "Configure",IDC_CONFIGUREVID,214,7,46,12 +END + +CONFIGUREDLG_INPUT DIALOG DISCARDABLE 97, 0, 267, 65 +STYLE DS_CONTROL | WS_CHILD +FONT 9, "Segoe UI" +BEGIN + LTEXT "Mouse :",IDC_STATIC,7,8,57,10 + COMBOBOX IDC_COMBO_MOUSE,71,7,189,120,CBS_DROPDOWN | WS_VSCROLL | + WS_TABSTOP + LTEXT "Joystick :",1793,7,26,58,10 + COMBOBOX IDC_COMBO_JOYSTICK,71,25,189,120,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + DEFPUSHBUTTON "Joystick 1...",IDC_JOY1,7,44,50,14 + PUSHBUTTON "Joystick 2...",IDC_JOY2,74,44,50,14 + DEFPUSHBUTTON "Joystick 3...",IDC_JOY3,141,44,50,14 + PUSHBUTTON "Joystick 4...",IDC_JOY4,209,44,50,14 +END + +CONFIGUREDLG_SOUND DIALOG DISCARDABLE 97, 0, 267, 78 +STYLE DS_CONTROL | WS_CHILD +FONT 9, "Segoe UI" +BEGIN + COMBOBOX IDC_COMBOSND,71,7,140,120,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP + LTEXT "Sound card:",1800,7,8,59,10 + PUSHBUTTON "Configure",IDC_CONFIGURESND,214,7,46,12 + COMBOBOX IDC_COMBO_MIDI,71,25,189,120,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP + LTEXT "MIDI Out Device:",1801,7,26,59,10 + CONTROL "CMS / Game Blaster",IDC_CHECKCMS,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,87,43,80,10 + CONTROL "Innovation SSI-2001",IDC_CHECKSSI,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,7,43,80,10 + CONTROL "Gravis Ultrasound",IDC_CHECKGUS,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,174,43,80,10 + CONTROL "Use Nuked OPL",IDC_CHECKNUKEDOPL,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,7,61,80,10 +END + +CONFIGUREDLG_NETWORK DIALOG DISCARDABLE 97, 0, 267, 63 +STYLE DS_CONTROL | WS_CHILD +FONT 9, "Segoe UI" +BEGIN + LTEXT "Network type:",1800,7,8,59,10 + COMBOBOX IDC_COMBONETTYPE,71,7,189,120,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP + + LTEXT "PCap device:",1801,7,26,59,10 + COMBOBOX IDC_COMBOPCAP,71,25,189,120,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP + + LTEXT "Network adapter:",1802,7,44,59,10 + COMBOBOX IDC_COMBONET,71,43,140,120,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP + PUSHBUTTON "Configure",IDC_CONFIGURENET,214,43,46,12 +END + +CONFIGUREDLG_PERIPHERALS DIALOG DISCARDABLE 97, 0, 267, 115 +STYLE DS_CONTROL | WS_CHILD +FONT 9, "Segoe UI" +BEGIN + LTEXT "SCSI Controller:",1804,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:",1799,7,26,61,10 + COMBOBOX IDC_COMBO_HDC,71,25,189,120,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + + LTEXT "Tertiary IDE:",1802,7,44,61,10 + COMBOBOX IDC_COMBO_IDE_TER,71,43,189,120,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + + LTEXT "Quaternary IDE:",1803,7,62,61,10 + COMBOBOX IDC_COMBO_IDE_QUA,71,61,189,120,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + + CONTROL "Serial port 1",IDC_CHECKSERIAL1,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,7,80,94,10 + CONTROL "Serial port 2",IDC_CHECKSERIAL2,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,147,80,94,10 + + CONTROL "Parallel port",IDC_CHECKPARALLEL,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,7,98,94,10 + CONTROL "ISABugger device",IDC_CHECKBUGGER,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,147,98,94,10 +END + +CONFIGUREDLG_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 | WS_BORDER | WS_TABSTOP,7,18,253,92 + LTEXT "Hard disks:",-1,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:",1798,7,118,24,8 + COMBOBOX IDC_COMBO_HD_CHANNEL,170,117,90,12,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "Channel:",1799,131,118,38,8 + COMBOBOX IDC_COMBO_HD_ID,170,117,22,12,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "ID:",1800,131,118,38,8 + COMBOBOX IDC_COMBO_HD_LUN,239,117,22,12,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "LUN:",1801,200,118,38,8 + COMBOBOX IDC_COMBO_HD_CHANNEL_IDE,170,117,90,12,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "Channel:",1802,131,118,38,8 +END + +CONFIGUREDLG_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 | WS_BORDER | WS_TABSTOP, + 7,18,253,60 + LTEXT "Floppy drives:",-1,7,7,43,8 + CONTROL "List1",IDC_LIST_CDROM_DRIVES,"SysListView32",LVS_REPORT | + LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP,7,116,253,60 + LTEXT "CD-ROM drives:",-1,7,106,50,8 + COMBOBOX IDC_COMBO_FD_TYPE,33,85,90,12,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "Type:",1803,7,86,24,8 + COMBOBOX IDC_COMBO_CD_BUS,33,183,90,12,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "Bus:",1798,7,184,24,8 + COMBOBOX IDC_COMBO_CD_ID,170,183,22,12,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "ID:",1800,131,184,38,8 + COMBOBOX IDC_COMBO_CD_LUN,239,183,22,12,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "LUN:",1801,200,184,38,8 + COMBOBOX IDC_COMBO_CD_CHANNEL_IDE,170,183,90,12,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "Channel:",1802,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 "ICONS/86Box-RB.ico" +#else +/* Icon by Devcore - https://commons.wikimedia.org/wiki/File:Icon_PC2_256x256.png */ +100 ICON DISCARDABLE "ICONS/86Box.ico" +#endif +128 ICON DISCARDABLE "ICONS/floppy_525_1dd.ico" +129 ICON DISCARDABLE "ICONS/floppy_525_1dd_active.ico" +130 ICON DISCARDABLE "ICONS/floppy_525_2dd.ico" +131 ICON DISCARDABLE "ICONS/floppy_525_2dd_active.ico" +132 ICON DISCARDABLE "ICONS/floppy_525_2qd.ico" +133 ICON DISCARDABLE "ICONS/floppy_525_2qd_active.ico" +134 ICON DISCARDABLE "ICONS/floppy_525_2hd.ico" +135 ICON DISCARDABLE "ICONS/floppy_525_2hd_active.ico" +144 ICON DISCARDABLE "ICONS/floppy_35_1dd.ico" +145 ICON DISCARDABLE "ICONS/floppy_35_1dd_active.ico" +146 ICON DISCARDABLE "ICONS/floppy_35_2dd.ico" +147 ICON DISCARDABLE "ICONS/floppy_35_2dd_active.ico" +150 ICON DISCARDABLE "ICONS/floppy_35_2hd.ico" +151 ICON DISCARDABLE "ICONS/floppy_35_2hd_active.ico" +152 ICON DISCARDABLE "ICONS/floppy_35_2ed.ico" +153 ICON DISCARDABLE "ICONS/floppy_35_2ed_active.ico" +160 ICON DISCARDABLE "ICONS/cdrom_atapi.ico" +161 ICON DISCARDABLE "ICONS/cdrom_atapi_active.ico" +162 ICON DISCARDABLE "ICONS/cdrom_atapi_dma.ico" +163 ICON DISCARDABLE "ICONS/cdrom_atapi_dma_active.ico" +164 ICON DISCARDABLE "ICONS/cdrom_scsi.ico" +165 ICON DISCARDABLE "ICONS/cdrom_scsi_active.ico" +176 ICON DISCARDABLE "ICONS/hard_disk_mfm.ico" +177 ICON DISCARDABLE "ICONS/hard_disk_mfm_active.ico" +178 ICON DISCARDABLE "ICONS/hard_disk.ico" +179 ICON DISCARDABLE "ICONS/hard_disk_active.ico" +180 ICON DISCARDABLE "ICONS/hard_disk_ide.ico" +181 ICON DISCARDABLE "ICONS/hard_disk_ide_active.ico" +182 ICON DISCARDABLE "ICONS/hard_disk_scsi.ico" +183 ICON DISCARDABLE "ICONS/hard_disk_scsi_active.ico" +256 ICON DISCARDABLE "ICONS/machine.ico" +257 ICON DISCARDABLE "ICONS/video.ico" +258 ICON DISCARDABLE "ICONS/input_devices.ico" +259 ICON DISCARDABLE "ICONS/sound.ico" +260 ICON DISCARDABLE "ICONS/network.ico" +261 ICON DISCARDABLE "ICONS/other_peripherals.ico" +262 ICON DISCARDABLE "ICONS/hard_disk.ico" +263 ICON DISCARDABLE "ICONS/removable_devices.ico" +384 ICON DISCARDABLE "ICONS/floppy_525_1dd_empty.ico" +385 ICON DISCARDABLE "ICONS/floppy_525_1dd_empty_active.ico" +386 ICON DISCARDABLE "ICONS/floppy_525_2dd_empty.ico" +387 ICON DISCARDABLE "ICONS/floppy_525_2dd_empty_active.ico" +388 ICON DISCARDABLE "ICONS/floppy_525_2qd_empty.ico" +389 ICON DISCARDABLE "ICONS/floppy_525_2qd_empty_active.ico" +390 ICON DISCARDABLE "ICONS/floppy_525_2hd_empty.ico" +391 ICON DISCARDABLE "ICONS/floppy_525_2hd_empty_active.ico" +400 ICON DISCARDABLE "ICONS/floppy_35_1dd_empty.ico" +401 ICON DISCARDABLE "ICONS/floppy_35_1dd_empty_active.ico" +402 ICON DISCARDABLE "ICONS/floppy_35_2dd_empty.ico" +403 ICON DISCARDABLE "ICONS/floppy_35_2dd_empty_active.ico" +406 ICON DISCARDABLE "ICONS/floppy_35_2hd_empty.ico" +407 ICON DISCARDABLE "ICONS/floppy_35_2hd_empty_active.ico" +408 ICON DISCARDABLE "ICONS/floppy_35_2ed_empty.ico" +409 ICON DISCARDABLE "ICONS/floppy_35_2ed_empty_active.ico" +416 ICON DISCARDABLE "ICONS/cdrom_atapi_empty.ico" +417 ICON DISCARDABLE "ICONS/cdrom_atapi_empty_active.ico" +418 ICON DISCARDABLE "ICONS/cdrom_atapi_dma_empty.ico" +419 ICON DISCARDABLE "ICONS/cdrom_atapi_dma_empty_active.ico" +420 ICON DISCARDABLE "ICONS/cdrom_scsi_empty.ico" +421 ICON DISCARDABLE "ICONS/cdrom_scsi_empty_active.ico" +512 ICON DISCARDABLE "ICONS/floppy_disabled.ico" +514 ICON DISCARDABLE "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, 71 + END + + CONFIGUREDLG_NETWORK, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 260 + TOPMARGIN, 7 + BOTTOMMARGIN, 56 + END + + 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_STRING2049 "86Box Error" + IDS_STRING2050 "86Box Fatal Error" + IDS_STRING2051 "This will reset 86Box.\nAre you sure you want to save the settings?" + IDS_STRING2052 "DirectDraw Screenshot Error" + IDS_STRING2053 "Invalid number of sectors (valid values are between 1 and 63)" + IDS_STRING2054 "Invalid number of heads (valid values are between 1 and 16)" + IDS_STRING2055 "Invalid number of cylinders (valid values are between 1 and 266305)" + IDS_STRING2056 "Please enter a valid file name" + IDS_STRING2057 "Unable to open the file for write" + IDS_STRING2058 "Attempting to create a HDI image larger than 4 GB" + IDS_STRING2059 "Remember to partition and format the new drive" + IDS_STRING2060 "Unable to open the file for read" + IDS_STRING2061 "HDI or HDX image with a sector size that is not 512 are not supported" + IDS_STRING2062 "86Box was unable to find any ROMs.\nAt least one ROM set is required to use 86Box." + IDS_STRING2063 "Configured ROM set not available.\nDefaulting to an available ROM set." +END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_STRING2064 "Configured video BIOS not available.\nDefaulting to an available video BIOS." + IDS_STRING2065 "Machine" + IDS_STRING2066 "Video" + IDS_STRING2067 "Input devices" + IDS_STRING2068 "Sound" + IDS_STRING2069 "Network" + IDS_STRING2070 "Other peripherals" + IDS_STRING2071 "Hard disks" + IDS_STRING2072 "Removable devices" + IDS_STRING2073 "%i"" floppy drive: %s" + IDS_STRING2074 "Disabled CD-ROM drive" + IDS_STRING2075 "%s CD-ROM drive: %s" + IDS_STRING2076 "Host CD/DVD Drive (%c:)" + IDS_STRING2077 "Click to capture mouse" + IDS_STRING2078 "Press F12-F8 to release mouse" + IDS_STRING2079 "Press F12-F8 or middle button to release mouse" +END + +STRINGTABLE DISCARDABLE +BEGIN + 2080 "Drive" + 2081 "Location" + 2082 "Bus" + 2083 "File" + 2084 "C" + 2085 "H" + 2086 "S" + 2087 "MB" + 2088 "%i" + 2089 "Enabled" + 2090 "Mute" + 2091 "Type" + 2092 "Bus" + 2093 "DMA" + 2094 "KB" + 2095 "MFM, RLL, or ESDI CD-ROM drives never existed" +END + +STRINGTABLE DISCARDABLE +BEGIN + 2096 "Slave" + 2097 "SCSI (ID %s, LUN %s)" + 2098 "Adapter Type" + 2099 "Base Address" + 2100 "IRQ" + 2101 "8-bit DMA" + 2102 "16-bit DMA" + 2103 "BIOS" + 2104 "Network Type" + 2105 "Surround Module" + 2106 "MPU-401 Base Address" + 2107 "No PCap devices found" + 2108 "On-board RAM" + 2109 "Memory Size" + 2110 "Display Type" + 2111 "RGB" +END + +STRINGTABLE DISCARDABLE +BEGIN + 2112 "Composite" + 2113 "Composite Type" + 2114 "Old" + 2115 "New" + 2116 "RGB Type" + 2117 "Color" + 2118 "Monochrome (Green)" + 2119 "Monochrome (Amber)" + 2120 "Monochrome (Gray)" + 2121 "Color (no brown)" + 2122 "Monochrome (Default)" + 2123 "Snow Emulation" + 2124 "Bilinear Filtering" + 2125 "Dithering" + 2126 "Framebuffer Memory Size" + 2127 "Texture Memory Size" +END + +STRINGTABLE DISCARDABLE +BEGIN + 2128 "Screen Filter" + 2129 "Render Threads" + 2130 "Recompiler" + 2131 "System Default" + 2132 "%i Wait state(s)" + 2133 "8-bit" + 2134 "Slow 16-bit" + 2135 "Fast 16-bit" + 2136 "Slow VLB/PCI" + 2137 "Mid VLB/PCI" + 2138 "Fast VLB/PCI" + 2139 "Microsoft 2-button mouse (serial)" + 2140 "Mouse Systems mouse (serial)" + 2141 "2-button mouse (PS/2)" + 2142 "Microsoft Intellimouse (PS/2)" + 2143 "Bus mouse" +END + +STRINGTABLE DISCARDABLE +BEGIN + 2144 "Standard 2-button joystick(s)" + 2145 "Standard 4-button joystick" + 2146 "Standard 6-button joystick" + 2147 "Standard 8-button joystick" + 2148 "CH Flightstick Pro" + 2149 "Microsoft SideWinder Pad" + 2150 "Thrustmaster Flight Control System" + 2151 "Disabled" + 2152 "None" + 2153 "AT Fixed Disk Adapter" + 2154 "Internal IDE" + 2155 "IRQ %i" + 2156 "MFM (%01i:%01i)" + 2157 "IDE (PIO+DMA) (%01i:%01i)" + 2158 "SCSI (%02i:%02i)" + 2159 "Invalid number of cylinders (valid values are between 1 and 1023)" + 2160 "%" PRIu64 + 2161 "Genius Bus mouse" + 2162 "Amstrad mouse" + 2163 "Attempting to create a spuriously large hard disk image" + 2164 "Invalid number of sectors (valid values are between 1 and 99)" + 2165 "MFM" + 2166 "IDE (PIO-only)" + 2167 "IDE (PIO and DMA)" + 2168 "SCSI" + 2169 "%01i:%01i" + 2170 "Custom..." + 2171 "%" PRIu64 " MB (CHS: %" PRIu64 ", %" PRIu64 ", %" PRIu64 ")" + 2172 "Hard disk images (*.HDI;*.HDX;*.IMA;*.IMG)\0*.HDI;*.HDX;*.IMA;*.IMG\0All files (*.*)\0*.*\0" + 2173 "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" + 2174 "Configuration files (*.CFG)\0*.CFG\0All files (*.*)\0*.*\0" + 2175 "CD-ROM image (*.ISO;*.CUE)\0*.ISO;*.CUE\0All files (*.*)\0*.*\0" + 2176 "Use CTRL + ALT + PAGE DOWN to return to windowed mode" + 2177 "Olivetti M24 mouse" + 2178 "This image exists and will be overwritten.\nAre you sure you want to use it?" + 2179 "Floppy %i (%s): %ws" + 2180 "CD-ROM %i: %ws" + 2181 "MFM hard disk" + 2182 "IDE hard disk (PIO-only)" + 2183 "IDE hard disk (PIO and DMA)" + 2184 "SCSI hard disk" + 2185 "(empty)" + 2186 "(host drive %c:)" + 2187 "Custom (large)..." + 2188 "Type" + 2189 "ATAPI (PIO-only)" + 2190 "ATAPI (PIO and DMA)" + 2191 "ATAPI (PIO-only) (%01i:%01i)" + 2192 "ATAPI (PIO and DMA) (%01i:%01i)" + 2193 "Use CTRL + ALT + PAGE DOWN to return to windowed mode" + 2194 "Unable to create bitmap file: %s" + 2195 "IDE (PIO-only) (%01i:%01i)" + 2196 "Add New Hard Disk" + 2197 "Add Existing Hard Disk" + 2198 "Removable disk %i: %s" + 2199 "USB is not yet supported" + 2200 "Invalid PCap device" + 2201 "English (United States)" +END + + +#ifndef _MAC +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,20,0,0 + PRODUCTVERSION 1,20,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", "1.20\0" + VALUE "InternalName", "pc_new\0" + VALUE "LegalCopyright", "Copyright © 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", "1.20\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 + diff --git a/src/WIN/pcap_if.rc b/src/WIN/pcap_if.rc new file mode 100644 index 000000000..57d78e657 --- /dev/null +++ b/src/WIN/pcap_if.rc @@ -0,0 +1,52 @@ +#ifdef _WIN32 +#include +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + + +#ifdef RELEASE_BUILD +/* Icon by Devcore - https://commons.wikimedia.org/wiki/File:Icon_PC_256x256.png */ +100 ICON DISCARDABLE "ICONS/86Box-RB.ico" +#else +/* Icon by Devcore - https://commons.wikimedia.org/wiki/File:Icon_PC2_256x256.png */ +100 ICON DISCARDABLE "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 diff --git a/src/WIN/plat_dinput.h b/src/WIN/plat_dinput.h new file mode 100644 index 000000000..b5d7eca06 --- /dev/null +++ b/src/WIN/plat_dinput.h @@ -0,0 +1,4 @@ +/* Copyright holders: Sarah Walker + see COPYING for more details +*/ +extern LPDIRECTINPUT lpdi; diff --git a/src/WIN/plat_dir.h b/src/WIN/plat_dir.h new file mode 100644 index 000000000..6eb372aa0 --- /dev/null +++ b/src/WIN/plat_dir.h @@ -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, + * 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*/ diff --git a/src/WIN/plat_joystick.h b/src/WIN/plat_joystick.h new file mode 100644 index 000000000..aecb3537c --- /dev/null +++ b/src/WIN/plat_joystick.h @@ -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 \ No newline at end of file diff --git a/src/WIN/plat_keyboard.h b/src/WIN/plat_keyboard.h new file mode 100644 index 000000000..f062c5951 --- /dev/null +++ b/src/WIN/plat_keyboard.h @@ -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 + diff --git a/src/WIN/plat_midi.h b/src/WIN/plat_midi.h new file mode 100644 index 000000000..87ed57306 --- /dev/null +++ b/src/WIN/plat_midi.h @@ -0,0 +1,10 @@ +/* Copyright holders: Sarah Walker + see COPYING for more details +*/ +void midi_init(); +void midi_close(); +void midi_write(uint8_t val); +int midi_get_num_devs(); +void midi_get_dev_name(int num, char *s); + +extern int midi_id; diff --git a/src/WIN/plat_mouse.h b/src/WIN/plat_mouse.h new file mode 100644 index 000000000..ff248f301 --- /dev/null +++ b/src/WIN/plat_mouse.h @@ -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 diff --git a/src/WIN/plat_serial.h b/src/WIN/plat_serial.h new file mode 100644 index 000000000..cf87192c0 --- /dev/null +++ b/src/WIN/plat_serial.h @@ -0,0 +1,49 @@ +/* + * 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.3 2017/05/17 + * + * Author: Fred N. van Kempen, + * Copyright 2017 Fred N. van Kempen. + */ +#ifndef PLAT_SERIAL_H +# define PLAT_SERIAL_H + + +typedef struct { + char name[79]; /* 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; +#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_write(BHTTY *, unsigned char); +extern int bhtty_read(BHTTY *, unsigned char *, int); + + +#endif /*PLAT_SERIAL_H*/ diff --git a/src/WIN/resource.h b/src/WIN/resource.h new file mode 100644 index 000000000..5364bf674 --- /dev/null +++ b/src/WIN/resource.h @@ -0,0 +1,432 @@ +/* Copyright holders: Tenshi + see COPYING for more details +*/ +/* {{NO_DEPENDENCIES}} + Microsoft Developer Studio generated include file. + Used by 86Box.rc +*/ +#define IDHDCONFIG 3 +#define IDCDCONFIG 4 +#define CONFIGUREDLG_MACHINE 101 +#define CONFIGUREDLG_VIDEO 102 +#define CONFIGUREDLG_INPUT 103 +#define CONFIGUREDLG_SOUND 104 +#define CONFIGUREDLG_NETWORK 105 +#define CONFIGUREDLG_PERIPHERALS 106 +#define CONFIGUREDLG_HARD_DISKS 107 +#define CONFIGUREDLG_REMOVABLE_DEVICES 108 +#define ABOUTDLG 109 +#define CONFIGUREDLG_HARD_DISKS_ADD 110 +#define CONFIGUREDLG_MAIN 117 +#define IDC_SETTINGSCATLIST 1004 +#define IDC_LIST_HARD_DISKS 1005 +#define IDC_COMBO_MACHINE 1006 +#define IDC_COMBO_CPU_TYPE 1007 +#define IDC_COMBO_CPU 1008 +#define IDC_COMBO_WS 1009 +#define IDC_CHECK_DYNAREC 1010 +#define IDC_CHECK_FPU 1011 +#define IDC_COMBO_SCSI 1012 +#define IDC_CONFIGURE_SCSI 1013 +#define IDC_COMBO_VIDEO 1014 +#define IDC_COMBO_VIDEO_SPEED 1015 +#define IDC_CHECK_VOODOO 1016 +#define IDC_CHECKCMS 1016 +#define IDC_CONFIGURE_VOODOO 1017 +#define IDC_CHECKNUKEDOPL 1018 +#define IDC_COMBO_JOYSTICK 1018 +#define IDC_CHECK_SYNC 1019 +#define IDC_LIST_FLOPPY_DRIVES 1020 +#define IDC_LIST_CDROM_DRIVES 1021 +#define IDC_CONFIGURE_MACHINE 1022 +#define IDC_COMBO_LANG 1023 +#define IDC_BUTTON_FDD_ADD 1024 +#define IDC_BUTTON_FDD_EDIT 1025 +#define IDC_BUTTON_FDD_REMOVE 1026 +#define IDC_BUTTON_CDROM_ADD 1027 +#define IDC_BUTTON_HDD_ADD_NEW 1027 +#define IDC_BUTTON_CDROM_EDIT 1028 +#define IDC_BUTTON_HDD_ADD 1028 +#define IDC_BUTTON_CDROM_REMOVE 1029 +#define IDC_BUTTON_HDD_REMOVE 1029 +#define IDC_HDIMAGE_NEW 1035 +#define IDC_HD_BUS 1036 +#define IDC_HDIMAGE_EXISTING 1037 +#define IDC_COMBO_HD_BUS 1038 +#define IDC_EDIT_HD_FILE_NAME 1039 +#define IDC_EDIT_HD_CYL 1040 +#define IDC_EDIT_HD_HPC 1041 +#define IDC_EDIT_HD_SPT 1042 +#define IDC_EDIT_HD_SIZE 1043 +#define IDC_COMBO_HD_TYPE 1044 +#define IDC_COMBO_HD_LOCATION 1045 +#define IDC_CHECKGUS 1046 +#define IDC_COMBO_HD_CHANNEL 1047 +#define IDC_COMBO_HD_CHANNEL_IDE 1048 +#define IDC_COMBO_HD_ID 1050 +#define IDC_COMBO_HD_LUN 1051 +#define IDC_CHECKBUGGER 1052 +#define IDC_CHECKSERIAL1 1053 +#define IDC_CHECKPARALLEL 1054 +#define IDC_CHECKSERIAL2 1055 +#define IDC_COMBO_HDC 1068 +#define IDC_COMBO_MOUSE 1069 +#define IDC_COMBO_IDE_TER 1069 +#define IDC_COMBO_IDE_QUA 1070 +#define IDC_COMBO_FD_TYPE 1071 +#define IDC_COMBO_CD_BUS 1072 +#define IDC_COMBO_CD_CHANNEL_IDE 1073 +#define IDC_COMBO_CD_ID 1074 +#define IDC_COMBO_CD_LUN 1075 +#define IDC_COMBO_MIDI 1076 +#define IDC_CHECK_CDROM_1_AUDIO_ENABLED 1584 +#define IDC_CHECK_CDROM_2_AUDIO_ENABLED 1585 +#define IDC_CHECK_CDROM_3_AUDIO_ENABLED 1586 +#define IDC_CHECK_CDROM_4_AUDIO_ENABLED 1587 +#define IDS_STRING2049 2049 +#define IDS_STRING2050 2050 +#define IDS_STRING2051 2051 +#define IDS_STRING2052 2052 +#define IDS_STRING2053 2053 +#define IDS_STRING2054 2054 +#define IDS_STRING2055 2055 +#define IDS_STRING2056 2056 +#define IDS_STRING2057 2057 +#define IDS_STRING2058 2058 +#define IDS_STRING2059 2059 +#define IDS_STRING2060 2060 +#define IDS_STRING2061 2061 +#define IDS_STRING2062 2062 +#define IDS_STRING2063 2063 +#define IDS_STRING2064 2064 +#define IDS_STRING2065 2065 +#define IDS_STRING2066 2066 +#define IDS_STRING2067 2067 +#define IDS_STRING2068 2068 +#define IDS_STRING2069 2069 +#define IDS_STRING2070 2070 +#define IDS_STRING2071 2071 +#define IDS_STRING2072 2072 +#define IDS_STRING2073 2073 +#define IDS_STRING2074 2074 +#define IDS_STRING2075 2075 +#define IDS_STRING2076 2076 +#define IDS_STRING2077 2077 +#define IDS_STRING2078 2078 +#define IDS_STRING2079 2079 +#define IDM_ABOUT 40001 +#define IDC_ABOUT_ICON 65535 + +#define IDM_DISC_1 40000 +#define IDM_DISC_2 40001 +#define IDM_DISC_3 40002 +#define IDM_DISC_4 40003 +#define IDM_DISC_1_WP 40004 +#define IDM_DISC_2_WP 40005 +#define IDM_DISC_3_WP 40006 +#define IDM_DISC_4_WP 40007 +#define IDM_EJECT_1 40008 +#define IDM_EJECT_2 40009 +#define IDM_EJECT_3 40010 +#define IDM_EJECT_4 40011 + +#define IDM_FILE_RESET 40015 +#define IDM_FILE_HRESET 40016 +#define IDM_FILE_EXIT 40017 +#define IDM_FILE_RESET_CAD 40018 +#define IDM_HDCONF 40019 +#define IDM_CONFIG 40020 +#define IDM_CONFIG_LOAD 40021 +#define IDM_CONFIG_SAVE 40022 +#define IDM_USE_NUKEDOPL 40023 +#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_FLASH 40077 +#define IDM_VID_SCREENSHOT 40078 +#define IDM_VID_INVERT 40079 + +#define IDM_CDROM_1_MUTE 40128 +#define IDM_CDROM_1_IMAGE 40144 +#define IDM_CDROM_1_RELOAD 40160 +#define IDM_CDROM_1_EMPTY 40176 +#define IDM_CDROM_1_REAL 40192 +#define IDM_CDROM_2_MUTE 40129 +#define IDM_CDROM_2_IMAGE 40145 +#define IDM_CDROM_2_RELOAD 40161 +#define IDM_CDROM_2_EMPTY 40177 +#define IDM_CDROM_2_REAL 40193 +#define IDM_CDROM_3_MUTE 40130 +#define IDM_CDROM_3_IMAGE 40146 +#define IDM_CDROM_3_RELOAD 40162 +#define IDM_CDROM_3_EMPTY 40178 +#define IDM_CDROM_3_REAL 40194 +#define IDM_CDROM_4_MUTE 40131 +#define IDM_CDROM_4_IMAGE 40147 +#define IDM_CDROM_4_RELOAD 40163 +#define IDM_CDROM_4_EMPTY 40179 +#define IDM_CDROM_4_REAL 40195 + +#define IDM_IDE_TER_ENABLED 44000 +#define IDM_IDE_TER_IRQ9 44009 +#define IDM_IDE_TER_IRQ10 44010 +#define IDM_IDE_TER_IRQ11 44011 +#define IDM_IDE_TER_IRQ12 44012 +#define IDM_IDE_TER_IRQ14 44014 +#define IDM_IDE_TER_IRQ15 44015 +#define IDM_IDE_QUA_ENABLED 44020 +#define IDM_IDE_QUA_IRQ9 44029 +#define IDM_IDE_QUA_IRQ10 44030 +#define IDM_IDE_QUA_IRQ11 44031 +#define IDM_IDE_QUA_IRQ12 44032 +#define IDM_IDE_QUA_IRQ14 44033 +#define IDM_IDE_QUA_IRQ15 44035 + +#ifdef ENABLE_LOG_TOGGLES +# ifdef ENABLE_BUSLOGIC_LOG +# define IDM_LOG_BUSLOGIC 51200 +# endif +# ifdef ENABLE_CDROM_LOG +# define IDM_LOG_CDROM 51201 +# endif +# ifdef ENABLE_D86F_LOG +# define IDM_LOG_D86F 51202 +# endif +# ifdef ENABLE_FDC_LOG +# define IDM_LOG_FDC 51203 +# endif +# ifdef ENABLE_IDE_LOG +# define IDM_LOG_IDE 51204 +# endif +# ifdef ENABLE_NE2000_LOG +# define IDM_LOG_NE2000 51205 +# endif +#endif +#ifdef ENABLE_LOG_BREAKPOINT +# define IDM_LOG_BREAKPOINT 51206 +#endif +#ifdef ENABLE_VRAM_DUMP +# define IDM_DUMP_VRAM 51207 +#endif + +#define IDC_COMBO1 1000 +#define IDC_COMBOVID 1001 +#define IDC_COMBO3 1002 +#define IDC_COMBO4 1003 +#define IDC_COMBO5 1004 +#define IDC_COMBO386 1005 +#define IDC_COMBO486 1006 +#define IDC_COMBOSND 1007 +#define IDC_COMBONETTYPE 1008 +#define IDC_COMBOPCAP 1009 +#define IDC_COMBONET 1010 +#define IDC_COMBOCPUM 1060 +#define IDC_COMBOSPD 1061 +#define IDC_COMBODR1 1062 +#define IDC_COMBODR2 1063 +#define IDC_COMBODR3 1064 +#define IDC_COMBODR4 1065 +#define IDC_COMBOJOY 1066 +#define IDC_COMBOWS 1067 +#define IDC_COMBOMOUSE 1068 +#define IDC_COMBOHDD 1069 +#define IDC_CHECK1 1010 +#define IDC_CHECK2 1011 +#define IDC_CHECK3 1012 +#define IDC_CHECKSSI 1014 +#define IDC_CHECKVOODOO 1015 +#define IDC_CHECKDYNAREC 1016 +#define IDC_CHECKBUSLOGIC 1017 +#define IDC_CHECKSYNC 1024 +#define IDC_CHECKXTIDE 1025 +#define IDC_CHECKFPU 1026 +#define IDC_EDIT1 1030 +#define IDC_EDIT2 1031 +#define IDC_EDIT3 1032 +#define IDC_EDIT4 1033 +#define IDC_EDIT5 1034 +#define IDC_EDIT6 1035 +#define IDC_COMBOHDT 1036 + +#define IDC_EJECTC 1040 +#define IDC_EDITC 1050 +#define IDC_CFILE 1060 +#define IDC_CNEW 1070 +#define IDC_EDIT_C_SPT 1200 +#define IDC_EDIT_C_HPC 1210 +#define IDC_EDIT_C_CYL 1220 +#define IDC_EDIT_C_FN 1230 +#define IDC_TEXT_C_SIZE 1240 + +#define IDC_EJECTD 1041 +#define IDC_EDITD 1051 +#define IDC_DFILE 1061 +#define IDC_DNEW 1071 +#define IDC_EDIT_D_SPT 1201 +#define IDC_EDIT_D_HPC 1211 +#define IDC_EDIT_D_CYL 1221 +#define IDC_EDIT_D_FN 1231 +#define IDC_TEXT_D_SIZE 1241 + +#define IDC_EJECTE 1042 +#define IDC_EDITE 1052 +#define IDC_EFILE 1062 +#define IDC_ENEW 1072 +#define IDC_EDIT_E_SPT 1202 +#define IDC_EDIT_E_HPC 1212 +#define IDC_EDIT_E_CYL 1222 +#define IDC_EDIT_E_FN 1232 +#define IDC_TEXT_E_SIZE 1242 + +#define IDC_EJECTF 1043 +#define IDC_EDITF 1053 +#define IDC_FFILE 1063 +#define IDC_FNEW 1073 +#define IDC_EDIT_F_SPT 1203 +#define IDC_EDIT_F_HPC 1213 +#define IDC_EDIT_F_CYL 1223 +#define IDC_EDIT_F_FN 1233 +#define IDC_TEXT_F_SIZE 1243 + +#define IDC_EJECTG 1044 +#define IDC_EDITG 1054 +#define IDC_GFILE 1064 +#define IDC_GNEW 1074 +#define IDC_EDIT_G_SPT 1204 +#define IDC_EDIT_G_HPC 1214 +#define IDC_EDIT_G_CYL 1224 +#define IDC_EDIT_G_FN 1234 +#define IDC_TEXT_G_SIZE 1244 + +#define IDC_EJECTH 1045 +#define IDC_EDITH 1055 +#define IDC_HFILE 1065 +#define IDC_HNEW 1075 +#define IDC_EDIT_H_SPT 1205 +#define IDC_EDIT_H_HPC 1215 +#define IDC_EDIT_H_CYL 1225 +#define IDC_EDIT_H_FN 1235 +#define IDC_TEXT_H_SIZE 1245 + +#define IDC_EJECTI 1046 +#define IDC_EDITI 1056 +#define IDC_IFILE 1066 +#define IDC_INEW 1076 +#define IDC_EDIT_I_SPT 1206 +#define IDC_EDIT_I_HPC 1216 +#define IDC_EDIT_I_CYL 1226 +#define IDC_EDIT_I_FN 1236 +#define IDC_TEXT_I_SIZE 1246 + +#define IDC_EJECTJ 1047 +#define IDC_EDITJ 1057 +#define IDC_JFILE 1067 +#define IDC_JNEW 1077 +#define IDC_EDIT_J_SPT 1207 +#define IDC_EDIT_J_HPC 1217 +#define IDC_EDIT_J_CYL 1227 +#define IDC_EDIT_J_FN 1237 +#define IDC_TEXT_J_SIZE 1247 + +#define IDC_HDTYPE 1280 + +#define IDC_RENDER 1281 +#define IDC_STATUS 1282 + +#define IDC_MEMSPIN 1100 +#define IDC_MEMTEXT 1101 +#define IDC_STEXT1 1102 +#define IDC_STEXT2 1103 +#define IDC_STEXT3 1104 +#define IDC_STEXT4 1105 +#define IDC_STEXT5 1106 +#define IDC_STEXT6 1107 +#define IDC_STEXT7 1108 +#define IDC_STEXT8 1109 +#define IDC_STEXT_DEVICE 1110 +#define IDC_TEXT_MB 1111 +#define IDC_TEXT1 1115 +#define IDC_TEXT2 1116 + +#define IDC_CONFIGUREVID 1200 +#define IDC_CONFIGURESND 1201 +#define IDC_CONFIGUREVOODOO 1202 +#define IDC_CONFIGUREMOD 1203 +#define IDC_CONFIGURENETTYPE 1204 +#define IDC_CONFIGUREBUSLOGIC 1205 +#define IDC_CONFIGUREPCAP 1206 +#define IDC_CONFIGURENET 1207 +#define IDC_JOY1 1210 +#define IDC_JOY2 1211 +#define IDC_JOY3 1212 +#define IDC_JOY4 1213 + +#define IDC_CONFIG_BASE 1200 + +#define WM_RESETD3D WM_USER +#define WM_LEAVEFULLSCREEN WM_USER + 1 + +#define C_BASE 6 +#define D_BASE 44 +#define E_BASE 82 +#define F_BASE 120 +#define G_BASE 158 +#define H_BASE 196 +#define I_BASE 234 +#define J_BASE 272 +#define CMD_BASE 314 +#define DLG_HEIGHT 346 + +#define IDC_CHECK_CDROM_1_ENABLED 1536 +#define IDC_COMBO_CDROM_1_BUS 1544 +#define IDC_COMBO_CDROM_1_CHANNEL 1552 +#define IDC_CHECK_CDROM_1_DMA_ENABLED 1560 +#define IDC_COMBO_CDROM_1_SCSI_ID 1568 +#define IDC_COMBO_CDROM_1_SCSI_LUN 1576 + +#define IDC_CHECK_CDROM_2_ENABLED 1537 +#define IDC_COMBO_CDROM_2_BUS 1545 +#define IDC_COMBO_CDROM_2_CHANNEL 1553 +#define IDC_CHECK_CDROM_2_DMA_ENABLED 1561 +#define IDC_COMBO_CDROM_2_SCSI_ID 1569 +#define IDC_COMBO_CDROM_2_SCSI_LUN 1577 + +#define IDC_CHECK_CDROM_3_ENABLED 1538 +#define IDC_COMBO_CDROM_3_BUS 1546 +#define IDC_COMBO_CDROM_3_CHANNEL 1554 +#define IDC_CHECK_CDROM_3_DMA_ENABLED 1562 +#define IDC_COMBO_CDROM_3_SCSI_ID 1570 +#define IDC_COMBO_CDROM_3_SCSI_LUN 1578 + +#define IDC_CHECK_CDROM_4_ENABLED 1539 +#define IDC_COMBO_CDROM_4_BUS 1547 +#define IDC_COMBO_CDROM_4_CHANNEL 1555 +#define IDC_CHECK_CDROM_4_DMA_ENABLED 1563 +#define IDC_COMBO_CDROM_4_SCSI_ID 1571 +#define IDC_COMBO_CDROM_4_SCSI_LUN 1579 + +#define IDC_STATIC 1792 + +/* Next default values for new objects */ +#ifdef APSTUDIO_INVOKED +# ifndef APSTUDIO_READONLY_SYMBOLS +# define _APS_NO_MFC 1 +# define _APS_NEXT_RESOURCE_VALUE 111 +# define _APS_NEXT_COMMAND_VALUE 40002 +# define _APS_NEXT_CONTROL_VALUE 1055 +# define _APS_NEXT_SYMED_VALUE 101 +# endif +#endif diff --git a/src/WIN/win.c b/src/WIN/win.c new file mode 100644 index 000000000..a56660e20 --- /dev/null +++ b/src/WIN/win.c @@ -0,0 +1,2427 @@ +/* Copyright holders: Sarah Walker, Tenshi + see COPYING for more details +*/ +#define UNICODE +#define _WIN32_WINNT 0x0501 +#define BITMAP WINDOWS_BITMAP +#include +#include +#undef BITMAP + +#include +#include +#include +#include +#include +#include +#include +#include +#include "../86box.h" +#include "../device.h" +#include "../disc.h" +#include "../fdd.h" +#include "../hdd.h" +#include "../ibm.h" +#include "../cpu/cpu.h" +#include "../mem.h" +#include "../rom.h" +#include "../nvr.h" +#include "../thread.h" +#include "../config.h" +#include "../model.h" +#include "../ide.h" +#include "../cdrom.h" +#include "../cdrom_null.h" +#include "../cdrom_ioctl.h" +#include "../cdrom_image.h" +#include "../video/video.h" +#include "../video/vid_ega.h" +#include "../mouse.h" +#include "../sound/sound.h" +#include "../sound/snd_dbopl.h" +#include "plat_keyboard.h" +#include "plat_mouse.h" +#include "plat_midi.h" + +#include "win.h" +#include "win_ddraw.h" +#include "win_ddraw-fs.h" +#include "win_d3d.h" +#include "win_d3d-fs.h" +#include "win_language.h" +#include "resource.h" + + +#ifndef MAPVK_VK_TO_VSC +#define MAPVK_VK_TO_VSC 0 +#endif + +static int save_window_pos = 0; +uint64_t timer_freq; + +int rawinputkey[272]; + +static RAWINPUTDEVICE device; +static uint16_t scancode_map[65536]; + +static struct +{ + int (*init)(HWND h); + void (*close)(); + void (*resize)(int x, int y); +} vid_apis[2][2] = +{ + { + ddraw_init, ddraw_close, NULL, + d3d_init, d3d_close, d3d_resize + }, + { + ddraw_fs_init, ddraw_fs_close, NULL, + d3d_fs_init, d3d_fs_close, NULL + }, +}; + +#define TIMER_1SEC 1 + +int winsizex=640,winsizey=480; +int efwinsizey=480; +int gfx_present[GFX_MAX]; + +HANDLE ghMutex; + +HANDLE mainthreadh; + +int infocus=1; + +int drawits=0; + +int romspresent[ROM_MAX]; +int quited=0; + +RECT oldclip; +int mousecapture=0; + +/* Declare Windows procedure */ +LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); +LRESULT CALLBACK subWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); + +LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); + +LONG OriginalStatusBarProcedure; + +HWND ghwnd; + +HINSTANCE hinstance; + +HMENU menu; + +extern int updatestatus; + +int pause=0; + +static int win_doresize = 0; + +static int leave_fullscreen_flag = 0; + +static int unscaled_size_x = 0; +static int unscaled_size_y = 0; + +int scale = 0; + +HWND hwndRender, hwndStatus; + +void updatewindowsize(int x, int y) +{ + int owsx = winsizex; + int owsy = winsizey; + + int temp_overscan_x = overscan_x; + int temp_overscan_y = overscan_y; + + if (vid_resize) return; + + if (x < 160) x = 160; + if (y < 100) y = 100; + + if (x > 2048) x = 2048; + if (y > 2048) y = 2048; + + if (suppress_overscan) + { + temp_overscan_x = temp_overscan_y = 0; + } + + unscaled_size_x=x; efwinsizey=y; + + if (force_43) + { + /* Account for possible overscan. */ + if (temp_overscan_y == 16) + { + /* CGA */ + unscaled_size_y = ((int) (((double) (x - temp_overscan_x) / 4.0) * 3.0)) + temp_overscan_y; + } + else if (temp_overscan_y < 16) + { + /* MDA/Hercules */ + unscaled_size_y = ((int) (((double) (x) / 4.0) * 3.0)); + } + else + { + if (enable_overscan) + { + /* EGA/(S)VGA with overscan */ + unscaled_size_y = ((int) (((double) (x - temp_overscan_x) / 4.0) * 3.0)) + temp_overscan_y; + } + else + { + /* EGA/(S)VGA without overscan */ + unscaled_size_y = ((int) (((double) (x) / 4.0) * 3.0)); + } + } + } + else + { + unscaled_size_y = efwinsizey; + } + + switch(scale) + { + case 0: + winsizex = unscaled_size_x >> 1; + winsizey = unscaled_size_y >> 1; + break; + case 1: + winsizex = unscaled_size_x; + winsizey = unscaled_size_y; + break; + case 2: + winsizex = (unscaled_size_x * 3) >> 1; + winsizey = (unscaled_size_y * 3) >> 1; + break; + case 3: + winsizex = unscaled_size_x << 1; + winsizey = unscaled_size_y << 1; + break; + } + + if ((owsx != winsizex) || (owsy != winsizey)) + { + win_doresize = 1; + } + else + { + win_doresize = 0; + } +} + +void uws_natural() +{ + updatewindowsize(unscaled_size_x, efwinsizey); +} + +void releasemouse() +{ + if (mousecapture) + { + ClipCursor(&oldclip); + ShowCursor(TRUE); + mousecapture = 0; + } +} + +void startblit() +{ + WaitForSingleObject(ghMutex, INFINITE); +} + +void endblit() +{ + ReleaseMutex(ghMutex); +} + +void leave_fullscreen() +{ + leave_fullscreen_flag = 1; +} + +uint64_t main_time; + +uint64_t start_time; +uint64_t end_time; + +void mainthread(LPVOID param) +{ + int frames = 0; + DWORD old_time, new_time; + + RECT r; + int sb_borders[3]; + + drawits=0; + old_time = GetTickCount(); + while (!quited) + { + if (updatestatus) + { + updatestatus = 0; + if (status_is_open) + SendMessage(status_hwnd, WM_USER, 0, 0); + } + new_time = GetTickCount(); + drawits += new_time - old_time; + old_time = new_time; + if (drawits > 0 && !pause) + { + start_time = timer_read(); + drawits-=10; if (drawits>50) drawits=0; + runpc(); + frames++; + if (frames >= 200 && nvr_dosave) + { + frames = 0; + nvr_dosave = 0; + savenvr(); + } + end_time = timer_read(); + main_time += end_time - start_time; + } + else + Sleep(1); + + if (!video_fullscreen && win_doresize && (winsizex > 0) && (winsizey > 0)) + { + video_wait_for_blit(); + SendMessage(hwndStatus, SB_GETBORDERS, 0, (LPARAM) sb_borders); + GetWindowRect(ghwnd, &r); + MoveWindow(hwndRender, 0, 0, + winsizex, + winsizey, + TRUE); + GetWindowRect(hwndRender, &r); + MoveWindow(hwndStatus, 0, r.bottom + GetSystemMetrics(SM_CYEDGE), + winsizex, + 17, + TRUE); + GetWindowRect(ghwnd, &r); + + MoveWindow(ghwnd, r.left, r.top, + winsizex + (GetSystemMetrics(vid_resize ? SM_CXSIZEFRAME : SM_CXFIXEDFRAME) * 2), + winsizey + (GetSystemMetrics(SM_CYEDGE) * 2) + (GetSystemMetrics(vid_resize ? SM_CYSIZEFRAME : SM_CYFIXEDFRAME) * 2) + GetSystemMetrics(SM_CYMENUSIZE) + GetSystemMetrics(SM_CYCAPTION) + 17 + sb_borders[1] + 1, + TRUE); + + win_doresize = 0; + } + + if (leave_fullscreen_flag) + { + leave_fullscreen_flag = 0; + SendMessage(ghwnd, WM_LEAVEFULLSCREEN, 0, 0); + } + if (video_fullscreen && infocus) + { + SetCursorPos(9999, 9999); + } + } +} + +void *thread_create(void (*thread_rout)(void *param), void *param) +{ + return (void *)_beginthread(thread_rout, 0, param); +} + +void thread_kill(void *handle) +{ + TerminateThread(handle, 0); +} + +void thread_sleep(int t) +{ + Sleep(t); +} + +typedef struct win_event_t +{ + HANDLE handle; +} win_event_t; + +event_t *thread_create_event() +{ + win_event_t *event = malloc(sizeof(win_event_t)); + + event->handle = CreateEvent(NULL, FALSE, FALSE, NULL); + + return (event_t *)event; +} + +void thread_set_event(event_t *_event) +{ + win_event_t *event = (win_event_t *)_event; + + SetEvent(event->handle); +} + +void thread_reset_event(event_t *_event) +{ + win_event_t *event = (win_event_t *)_event; + + ResetEvent(event->handle); +} + +int thread_wait_event(event_t *_event, int timeout) +{ + win_event_t *event = (win_event_t *)_event; + + if (timeout == -1) + timeout = INFINITE; + + if (WaitForSingleObject(event->handle, timeout)) + return 1; + return 0; +} + +void thread_destroy_event(event_t *_event) +{ + win_event_t *event = (win_event_t *)_event; + + CloseHandle(event->handle); + + free(event); +} + +HMENU smenu; + +static void initmenu(void) +{ + int i, c; + HMENU m; + WCHAR s[64]; + + for (i = 0; i < CDROM_NUM; i++) + { + m=GetSubMenu(smenu, i + 4); /*CD-ROM*/ + + /* Loop through each Windows drive letter and test to see if + it's a CDROM */ + for (c='A';c<='Z';c++) + { + _swprintf(s,L"%c:\\",c); + if (GetDriveType(s)==DRIVE_CDROM) + { + _swprintf(s, win_language_get_string_from_id(2076), c); + AppendMenu(m,MF_STRING,IDM_CDROM_1_REAL+(c << 2)+i,s); + } + } + } +} + +void get_executable_name(WCHAR *s, int size) +{ + GetModuleFileName(hinstance, s, size); +} + +void set_window_title(WCHAR *s) +{ + if (video_fullscreen) + return; + SetWindowText(ghwnd, s); +} + +uint64_t timer_read() +{ + LARGE_INTEGER qpc_time; + QueryPerformanceCounter(&qpc_time); + return qpc_time.QuadPart; +} + +/* 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; + + /* 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) + { + UINT32 *bufEx2 = (UINT32 *) buf; + int scMapCount = bufEx2[2]; + if ((bufSize != 0) && (scMapCount != 0)) + { + UINT16 *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. */ + int scancode_unmapped = bufEx[j + 1]; + int scancode_mapped = bufEx[j]; + + scancode_mapped = convert_scan_code(scancode_mapped); + + /* Fixes scan code map logging. */ + scancode_map[scancode_unmapped] = scancode_mapped; + } + } + } + RegCloseKey(hKey); + } +} + +static wchar_t **argv; +static int argc; +static wchar_t *argbuf; + +static void process_command_line() +{ + WCHAR *cmdline; + int argc_max; + int i, q; + + cmdline = GetCommandLine(); + i = wcslen(cmdline) + 1; + argbuf = malloc(i * 2); + memcpy(argbuf, cmdline, i * 2); + + argc = 0; + argc_max = 64; + argv = malloc(sizeof(wchar_t *) * argc_max); + if (!argv) + { + free(argbuf); + return; + } + + i = 0; + + /* parse commandline into argc/argv format */ + while (argbuf[i]) + { + while (argbuf[i] == L' ') + i++; + + if (argbuf[i]) + { + if ((argbuf[i] == L'\'') || (argbuf[i] == L'"')) + { + q = argbuf[i++]; + if (!argbuf[i]) + break; + } + else + q = 0; + + argv[argc++] = &argbuf[i]; + + if (argc >= argc_max) + { + argc_max += 64; + argv = realloc(argv, sizeof(wchar_t *) * argc_max); + if (!argv) + { + free(argbuf); + return; + } + } + + while ((argbuf[i]) && ((q) ? (argbuf[i] != q) : (argbuf[i] != L' '))) + i++; + + if (argbuf[i]) + { + argbuf[i] = 0; + i++; + } + } + } + + argv[argc] = NULL; +} + +int valid_models[2] = { 0, 1 }; +int valid_bases[6] = { 0x130, 0x134, 0x230, 0x234, 0x330, 0x334 }; +int valid_irqs[6] = { 9, 10, 11, 12, 14, 15 }; +int valid_dma_channels[3] = { 5, 6, 7 }; +int valid_ide_channels[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; +int valid_scsi_ids[15] = { 0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15 }; +int valid_scsi_luns[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; + +int find_in_array(int *array, int val, int len, int menu_base) +{ + int i = 0; + int temp = 0; + for (i = 0; i < len; i++) + { + CheckMenuItem(menu, menu_base + array[i], MF_UNCHECKED); + if (array[i] == val) + { + temp = 1; + } + } + return temp; +} + +HANDLE hinstAcc; + +HICON LoadIconEx(PCTSTR pszIconName) +{ + return (HICON) LoadImage(hinstance, pszIconName, IMAGE_ICON, 16, 16, LR_SHARED); +} + +HICON LoadIconBig(PCTSTR pszIconName) +{ + return (HICON) LoadImage(hinstance, pszIconName, IMAGE_ICON, 64, 64, 0); +} + +int fdd_type_to_icon(int type) +{ + switch(type) + { + default: + case 0: + return 512; + case 1: + return 128; + case 2: + return 130; + case 3: + return 132; + case 4: + case 5: + case 6: + return 134; + case 7: + return 144; + case 8: + return 146; + case 9: + case 10: + case 11: + case 12: + return 150; + case 13: + return 152; + } +} + +int sb_parts = 10; + +int sb_part_meanings[12]; +int sb_part_icons[12]; + +int sb_icon_width = 24; + +int count_hard_disks(int bus) +{ + int i = 0; + + int c = 0; + + for (i = 0; i < HDC_NUM; i++) + { + if (hdc[i].bus == bus) + { + c++; + } + } + + return c; +} + +HICON hIcon[512]; + +int iStatusWidths[] = { 18, 36, 54, 72, 90, 108, 126, 144, 168, 192, 210, -1 }; + +#define SBI_FLAG_ACTIVE 1 +#define SBI_FLAG_EMPTY 256 + +int sb_icon_flags[512]; + +/* This is for the disk activity indicator. */ +void update_status_bar_icon(int tag, int active) +{ + int i = 0; + int found = -1; + int temp_flags = 0; + + if ((tag & 0xf0) >= 0x30) + { + return; + } + + temp_flags |= active; + + for (i = 0; i < 12; i++) + { + if (sb_part_meanings[i] == tag) + { + found = i; + break; + } + } + + if (found != -1) + { + if (temp_flags != (sb_icon_flags[found] & 1)) + { + sb_icon_flags[found] &= ~1; + sb_icon_flags[found] |= active; + + sb_part_icons[found] &= ~257; + sb_part_icons[found] |= sb_icon_flags[found]; + + SendMessage(hwndStatus, SB_SETICON, found, (LPARAM) hIcon[sb_part_icons[found]]); + } + } +} + +/* This is for the drive state indicator. */ +void update_status_bar_icon_state(int tag, int state) +{ + int i = 0; + int found = -1; + + if ((tag & 0xf0) >= 0x20) + { + return; + } + + for (i = 0; i < 12; i++) + { + if (sb_part_meanings[i] == tag) + { + found = i; + break; + } + } + + if (found != -1) + { + sb_icon_flags[found] &= ~256; + sb_icon_flags[found] |= state ? 256 : 0; + + sb_part_icons[found] &= ~257; + sb_part_icons[found] |= sb_icon_flags[found]; + + SendMessage(hwndStatus, SB_SETICON, found, (LPARAM) hIcon[sb_part_icons[found]]); + } +} + +WCHAR sbTips[24][512]; + +void create_floppy_tip(int part) +{ + WCHAR *szText; + WCHAR wtext[512]; + + int drive = sb_part_meanings[part] & 0xf; + + mbstowcs(wtext, fdd_getname(fdd_get_type(drive)), strlen(fdd_getname(fdd_get_type(drive))) + 1); + if (wcslen(discfns[drive]) == 0) + { + _swprintf(sbTips[part], win_language_get_string_from_id(2179), drive + 1, wtext, win_language_get_string_from_id(2185)); + } + else + { + _swprintf(sbTips[part], win_language_get_string_from_id(2179), drive + 1, wtext, discfns[drive]); + } +} + +void create_cdrom_tip(int part) +{ + WCHAR *szText; + char ansi_text[3][512]; + WCHAR wtext[512]; + + int drive = sb_part_meanings[part] & 0xf; + + if (cdrom_drives[drive].host_drive == 200) + { + if (wcslen(cdrom_image[drive].image_path) == 0) + { + _swprintf(sbTips[part], win_language_get_string_from_id(2180), drive + 1, win_language_get_string_from_id(2185)); + } + else + { + _swprintf(sbTips[part], win_language_get_string_from_id(2180), drive + 1, cdrom_image[drive].image_path); + } + } + else if (cdrom_drives[drive].host_drive < 0x41) + { + _swprintf(sbTips[part], win_language_get_string_from_id(2180), drive + 1, win_language_get_string_from_id(2185)); + } + else + { + _swprintf(wtext, win_language_get_string_from_id(2186), cdrom_drives[drive].host_drive & ~0x20); + _swprintf(sbTips[part], win_language_get_string_from_id(2180), drive + 1, wtext); + } +} + +void create_hd_tip(int part) +{ + WCHAR *szText; + + int bus = sb_part_meanings[part] & 0xf; + szText = (WCHAR *) win_language_get_string_from_id(2181 + bus); + memcpy(sbTips[part], szText, (wcslen(szText) << 1) + 2); +} + +void update_tip(int meaning) +{ + int i = 0; + int part = -1; + + for (i = 0; i < sb_parts; i++) + { + if (sb_part_meanings[i] == meaning) + { + part = i; + } + } + + if (part != -1) + { + switch(meaning & 0x30) + { + case 0x00: + create_floppy_tip(part); + break; + case 0x10: + create_cdrom_tip(part); + break; + case 0x20: + create_hd_tip(part); + break; + default: + break; + } + + SendMessage(hwndStatus, SB_SETTIPTEXT, part, (LPARAM) sbTips[part]); + } +} + +static int get_floppy_state(int id) +{ + return (wcslen(discfns[id]) == 0) ? 1 : 0; +} + +static int get_cd_state(int id) +{ + if (cdrom_drives[id].host_drive < 0x41) + { + return 1; + } + else + { + if (cdrom_drives[id].host_drive == 0x200) + { + return (wcslen(cdrom_image[id].image_path) == 0) ? 1 : 0; + } + else + { + return 0; + } + } +} + +void status_settextw(wchar_t *wstr) +{ + int i = 0; + int part = -1; + + for (i = 0; i < sb_parts; i++) + { + if (sb_part_meanings[i] == 0x30) + { + part = i; + } + } + + if (part != -1) + { + SendMessage(hwndStatus, SB_SETTEXT, part | SBT_NOBORDERS, (LPARAM) wstr); + } +} + +static wchar_t cwstr[512]; + +void status_settext(char *str) +{ + memset(cwstr, 0, 1024); + mbstowcs(cwstr, str, strlen(str) + 1); + status_settextw(cwstr); +} + +void update_status_bar_panes(HWND hwnds) +{ + int i, j, id; + int edge = 0; + + int c_rll = 0; + int c_mfm = 0; + int c_ide_pio = 0; + int c_ide_dma = 0; + int c_scsi = 0; + + c_mfm = count_hard_disks(1); + c_ide_pio = count_hard_disks(2); + c_ide_dma = count_hard_disks(3); + c_scsi = count_hard_disks(4); + + for (i = 0; i < sb_parts; i++) + { + SendMessage(hwnds, SB_SETICON, i, (LPARAM) NULL); + } + + sb_parts = 0; + memset(iStatusWidths, 0, 48); + memset(sb_part_meanings, 0, 48); + for (i = 0; i < 4; i++) + { + if (fdd_get_type(i) != 0) + { + /* pclog("update_status_bar_panes(): Found floppy drive %c:, type %i\n", 65 + i, fdd_get_type(i)); */ + edge += sb_icon_width; + iStatusWidths[sb_parts] = edge; + sb_part_meanings[sb_parts] = 0x00 | i; + sb_parts++; + } + } + for (i = 0; i < 4; i++) + { + if (cdrom_drives[i].bus_type != 0) + { + edge += sb_icon_width; + iStatusWidths[sb_parts] = edge; + sb_part_meanings[sb_parts] = 0x10 | i; + sb_parts++; + } + } + if (c_mfm && !(models[model].flags & MODEL_HAS_IDE) && !!memcmp(hdd_controller_name, "none", 4) && !!memcmp(hdd_controller_name, "xtide", 5)) + { + edge += sb_icon_width; + iStatusWidths[sb_parts] = edge; + sb_part_meanings[sb_parts] = 0x20; + sb_parts++; + } + if (c_ide_pio && ((models[model].flags & MODEL_HAS_IDE) || !memcmp(hdd_controller_name, "xtide", 5))) + { + edge += sb_icon_width; + iStatusWidths[sb_parts] = edge; + sb_part_meanings[sb_parts] = 0x21; + sb_parts++; + } + if (c_ide_dma && ((models[model].flags & MODEL_HAS_IDE) || !memcmp(hdd_controller_name, "xtide", 5))) + { + edge += sb_icon_width; + iStatusWidths[sb_parts] = edge; + sb_part_meanings[sb_parts] = 0x22; + sb_parts++; + } + if (c_scsi) + { + edge += sb_icon_width; + iStatusWidths[sb_parts] = edge; + sb_part_meanings[sb_parts] = 0x23; + sb_parts++; + } + if (sb_parts) + { + iStatusWidths[sb_parts - 1] += (24 - sb_icon_width); + } + iStatusWidths[sb_parts] = -1; + sb_part_meanings[sb_parts] = 0x30; + sb_parts++; + + SendMessage(hwnds, SB_SETPARTS, (WPARAM) sb_parts, (LPARAM) iStatusWidths); + + for (i = 0; i < sb_parts; i++) + { + switch (sb_part_meanings[i] & 0x30) + { + case 0x00: + /* Floppy */ + sb_icon_flags[i] = (wcslen(discfns[sb_part_meanings[i] & 0xf]) == 0) ? 256 : 0; + sb_part_icons[i] = fdd_type_to_icon(fdd_get_type(sb_part_meanings[i] & 0xf)) | sb_icon_flags[i]; + create_floppy_tip(i); + break; + case 0x10: + /* CD-ROM */ + id = sb_part_meanings[i] & 0xf; + if (cdrom_drives[id].host_drive < 0x41) + { + sb_icon_flags[i] = 256; + } + else + { + if (cdrom_drives[id].host_drive == 0x200) + { + sb_icon_flags[i] = (wcslen(cdrom_image[id].image_path) == 0) ? 256 : 0; + } + else + { + sb_icon_flags[i] = 0; + } + } + if (cdrom_drives[id].bus_type == 4) + { + j = 164; + } + else if (cdrom_drives[id].bus_type == 3) + { + j = 162; + } + else + { + j = 160; + } + sb_part_icons[i] = j | sb_icon_flags[i]; + create_cdrom_tip(i); + break; + case 0x20: + /* Hard disk */ + sb_part_icons[i] = 176 + ((sb_part_meanings[i] & 0xf) << 1); + create_hd_tip(i); + break; + case 0x30: + /* Status text */ + SendMessage(hwnds, SB_SETTEXT, i | SBT_NOBORDERS, (LPARAM) L"Welcome to Unicode 86Box! :p"); + sb_part_icons[i] = -1; + break; + } + if (sb_part_icons[i] != -1) + { + SendMessage(hwnds, SB_SETTEXT, i | SBT_NOBORDERS, (LPARAM) ""); + SendMessage(hwnds, SB_SETICON, i, (LPARAM) hIcon[sb_part_icons[i]]); + SendMessage(hwnds, SB_SETTIPTEXT, i, (LPARAM) sbTips[i]); + /* pclog("Status bar part found: %02X (%i)\n", sb_part_meanings[i], sb_part_icons[i]); */ + } + else + { + SendMessage(hwnds, SB_SETICON, i, (LPARAM) NULL); + } + } +} + +HWND EmulatorStatusBar(HWND hwndParent, int idStatus, HINSTANCE hinst) +{ + HWND hwndStatus; + int i; + RECT rectDialog; + int dw, dh; + + for (i = 128; i < 136; i++) + { + hIcon[i] = LoadIconEx((PCTSTR) i); + } + + for (i = 144; i < 148; i++) + { + hIcon[i] = LoadIconEx((PCTSTR) i); + } + + for (i = 150; i < 154; i++) + { + hIcon[i] = LoadIconEx((PCTSTR) i); + } + + for (i = 160; i < 166; i++) + { + hIcon[i] = LoadIconEx((PCTSTR) i); + } + + for (i = 176; i < 184; i++) + { + hIcon[i] = LoadIconEx((PCTSTR) i); + } + + for (i = 384; i < 392; i++) + { + hIcon[i] = LoadIconEx((PCTSTR) i); + } + + for (i = 400; i < 404; i++) + { + hIcon[i] = LoadIconEx((PCTSTR) i); + } + + for (i = 406; i < 410; i++) + { + hIcon[i] = LoadIconEx((PCTSTR) i); + } + + for (i = 416; i < 422; i++) + { + hIcon[i] = LoadIconEx((PCTSTR) i); + } + + GetWindowRect(hwndParent, &rectDialog); + dw = rectDialog.right - rectDialog.left; + dh = rectDialog.bottom - rectDialog.top; + + InitCommonControls(); + + hwndStatus = CreateWindowEx( + 0, + STATUSCLASSNAME, + (PCTSTR) NULL, + SBARS_SIZEGRIP | WS_CHILD | WS_VISIBLE | SBT_TOOLTIPS, + 0, dh - 17, dw, 17, + hwndParent, + (HMENU) idStatus, + hinst, + NULL); + + GetWindowRect(hwndStatus, &rectDialog); + + SetWindowPos( + hwndStatus, + HWND_TOPMOST, + rectDialog.left, + rectDialog.top, + rectDialog.right - rectDialog.left, + rectDialog.bottom - rectDialog.top, + SWP_SHOWWINDOW); + + SendMessage(hwndStatus, SB_SETMINHEIGHT, (WPARAM) 17, (LPARAM) 0); + + update_status_bar_panes(hwndStatus); + + return hwndStatus; +} + +void win_menu_update() +{ +#if 0 + menu = LoadMenu(hThisInstance, TEXT("MainMenu")); + + smenu = LoadMenu(hThisInstance, TEXT("StatusBarMenu")); + initmenu(); + + SetMenu(ghwnd, menu); + + win_title_update = 1; +#endif +} + +int recv_key[272]; + +int WINAPI WinMain (HINSTANCE hThisInstance, + HINSTANCE hPrevInstance, + LPSTR lpszArgument, + int nFunsterStil) + +{ + HWND hwnd; /* This is the handle for our window */ + MSG messages; /* Here messages to the application are saved */ + WNDCLASSEX wincl; /* Data structure for the windowclass */ + int c, d, e, bRet; + WCHAR emulator_title[200]; + LARGE_INTEGER qpc_freq; + HACCEL haccel; /* Handle to accelerator table */ + + memset(recv_key, 0, sizeof(recv_key)); + + process_command_line(); + + win_language_load_common_strings(); + + hinstance=hThisInstance; + /* The Window structure */ + wincl.hInstance = hThisInstance; + wincl.lpszClassName = szClassName; + wincl.lpfnWndProc = WindowProcedure; /* This function is called by windows */ + wincl.style = CS_DBLCLKS; /* Catch double-clicks */ + wincl.cbSize = sizeof (WNDCLASSEX); + + /* Use default icon and mouse-pointer */ + wincl.hIcon = LoadIcon(hinstance, (LPCTSTR) 100); + wincl.hIconSm = LoadIcon(hinstance, (LPCTSTR) 100); + wincl.hCursor = NULL; + wincl.lpszMenuName = NULL; /* No menu */ + wincl.cbClsExtra = 0; /* No extra bytes after the window class */ + wincl.cbWndExtra = 0; /* structure or the window instance */ + /* Use Windows's default color as the background of the window */ + wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND; + + /* Register the window class, and if it fails quit the program */ + if (!RegisterClassEx(&wincl)) + return 0; + + wincl.lpszClassName = szSubClassName; + wincl.lpfnWndProc = subWindowProcedure; /* This function is called by windows */ + + if (!RegisterClassEx(&wincl)) + return 0; + + menu = LoadMenu(hThisInstance, TEXT("MainMenu")); + + _swprintf(emulator_title, L"86Box v%s", emulator_version_w); + + /* The class is registered, let's create the program*/ + hwnd = CreateWindowEx ( + 0, /* Extended possibilites for variation */ + szClassName, /* Classname */ + emulator_title, /* Title Text */ + (WS_OVERLAPPEDWINDOW & ~WS_SIZEBOX)/* | DS_3DLOOK*/, /* default window */ + CW_USEDEFAULT, /* Windows decides the position */ + CW_USEDEFAULT, /* where the window ends up on the screen */ + 640+(GetSystemMetrics(SM_CXFIXEDFRAME)*2), /* The programs width */ + 480+(GetSystemMetrics(SM_CYFIXEDFRAME)*2)+GetSystemMetrics(SM_CYMENUSIZE)+GetSystemMetrics(SM_CYCAPTION)+1, /* and height in pixels */ + HWND_DESKTOP, /* The window is a child-window to desktop */ + menu, /* Menu */ + hThisInstance, /* Program Instance handler */ + NULL /* No Window Creation data */ + ); + + /* Make the window visible on the screen */ + ShowWindow (hwnd, nFunsterStil); + + /* Load the accelerator table */ + haccel = LoadAccelerators(hinstAcc, L"MainAccel"); + if (haccel == NULL) + fatal("haccel is null\n"); + + memset(rawinputkey, 0, sizeof(rawinputkey)); + device.usUsagePage = 0x01; + device.usUsage = 0x06; + device.dwFlags = RIDEV_NOHOTKEYS; + device.hwndTarget = hwnd; + + if (RegisterRawInputDevices(&device, 1, sizeof(device))) + pclog("Raw input registered!\n"); + else + pclog("Raw input registration failed!\n"); + + get_registry_key_map(); + + ghwnd=hwnd; + + initpc(argc, argv); + + hwndRender = CreateWindow(L"STATIC", NULL, WS_VISIBLE | WS_CHILD | SS_BITMAP, 0, 0, 1, 1, ghwnd, NULL, hinstance, NULL); + + hwndStatus = EmulatorStatusBar(hwnd, IDC_STATUS, hThisInstance); + + OriginalStatusBarProcedure = GetWindowLong(hwndStatus, GWL_WNDPROC); + SetWindowLong(hwndStatus, GWL_WNDPROC, (LONG) &StatusBarProcedure); + + smenu = LoadMenu(hThisInstance, TEXT("StatusBarMenu")); + initmenu(); + + if (vid_apis[0][vid_api].init(hwndRender) == 0) + { + if (vid_apis[0][vid_api ^ 1].init(hwndRender) == 0) + { + fatal("Both DirectDraw and Direct3D renderers failed to initialize\n"); + } + else + { + vid_api ^= 1; + } + } + + if (vid_resize) SetWindowLong(hwnd, GWL_STYLE, WS_OVERLAPPEDWINDOW|WS_VISIBLE); + else SetWindowLong(hwnd, GWL_STYLE, (WS_OVERLAPPEDWINDOW&~WS_SIZEBOX&~WS_THICKFRAME&~WS_MAXIMIZEBOX)|WS_VISIBLE); + + SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_MINIMIZEBOX); + + /* Note by Kiririn: I've redone this since the CD-ROM can be disabled but still have something inside it. */ + for (e = 0; e < CDROM_NUM; e++) + { + if (!cdrom_drives[e].sound_on) + { + CheckMenuItem(smenu, IDM_CDROM_1_MUTE + e, MF_CHECKED); + } + + if (cdrom_drives[e].host_drive == 200) + { + CheckMenuItem(smenu, IDM_CDROM_1_IMAGE + e, MF_CHECKED); + } + else if (cdrom_drives[e].host_drive >= 65) + { + CheckMenuItem(smenu, IDM_CDROM_1_REAL + e + (cdrom_drives[e].host_drive << 2), MF_CHECKED); + } + else + { + CheckMenuItem(smenu, IDM_CDROM_1_EMPTY + e, MF_CHECKED); + } + } + +#ifdef ENABLE_LOG_TOGGLES +#ifdef ENABLE_BUSLOGIC_LOG + CheckMenuItem(menu, IDM_LOG_BUSLOGIC, buslogic_do_log ? MF_CHECKED : MF_UNCHECKED); +#endif +#ifdef ENABLE_CDROM_LOG + CheckMenuItem(menu, IDM_LOG_CDROM, cdrom_do_log ? MF_CHECKED : MF_UNCHECKED); +#endif +#ifdef ENABLE_D86F_LOG + CheckMenuItem(menu, IDM_LOG_D86F, d86f_do_log ? MF_CHECKED : MF_UNCHECKED); +#endif +#ifdef ENABLE_FDC_LOG + CheckMenuItem(menu, IDM_LOG_FDC, fdc_do_log ? MF_CHECKED : MF_UNCHECKED); +#endif +#ifdef ENABLE_IDE_LOG + CheckMenuItem(menu, IDM_LOG_IDE, ide_do_log ? MF_CHECKED : MF_UNCHECKED); +#endif +#ifdef ENABLE_NE2000_LOG + CheckMenuItem(menu, IDM_LOG_NE2000, ne2000_do_log ? MF_CHECKED : MF_UNCHECKED); +#endif +#endif + + CheckMenuItem(menu, IDM_VID_FORCE43, force_43 ? MF_CHECKED : MF_UNCHECKED); + CheckMenuItem(menu, IDM_VID_OVERSCAN, enable_overscan ? MF_CHECKED : MF_UNCHECKED); + CheckMenuItem(menu, IDM_VID_INVERT, invert_display ? MF_CHECKED : MF_UNCHECKED); + + if (vid_resize) CheckMenuItem(menu, IDM_VID_RESIZE, MF_CHECKED); + CheckMenuItem(menu, IDM_VID_DDRAW + vid_api, MF_CHECKED); + CheckMenuItem(menu, IDM_VID_FS_FULL + video_fullscreen_scale, MF_CHECKED); + CheckMenuItem(menu, IDM_VID_REMEMBER, window_remember ? MF_CHECKED : MF_UNCHECKED); + CheckMenuItem(menu, IDM_VID_SCALE_1X + scale, MF_CHECKED); + + d=romset; + for (c=0;c= 0; c--) + { + if (gfx_present[c]) + { + gfxcard = c; + saveconfig(); + resetpchard(); + break; + } + } + } + + loadbios(); + resetpchard(); + + timeBeginPeriod(1); + + atexit(releasemouse); + + ghMutex = CreateMutex(NULL, FALSE, NULL); + mainthreadh=(HANDLE)_beginthread(mainthread,0,NULL); + SetThreadPriority(mainthreadh, THREAD_PRIORITY_HIGHEST); + + + updatewindowsize(640, 480); + + QueryPerformanceFrequency(&qpc_freq); + timer_freq = qpc_freq.QuadPart; + + if (start_in_fullscreen) + { + startblit(); + mouse_close(); + vid_apis[0][vid_api].close(); + video_fullscreen = 1; + vid_apis[1][vid_api].init(hwndRender); + mouse_init(); + leave_fullscreen_flag = 0; + endblit(); + device_force_redraw(); + } + if (window_remember) + { + MoveWindow(hwnd, window_x, window_y, + window_w, + window_h, + TRUE); + } + else + { + MoveWindow(hwndRender, 0, 0, + winsizex, + winsizey, + TRUE); + MoveWindow(hwndStatus, 0, winsizey + 6, + winsizex, + 17, + TRUE); + } + + /* Run the message loop. It will run until GetMessage() returns 0 */ + while (!quited) + { + while (((bRet = GetMessage(&messages,NULL,0,0)) != 0) && !quited) + { + if (bRet == -1) + { + fatal("bRet is -1\n"); + } + + if (messages.message==WM_QUIT) quited=1; + if (!TranslateAccelerator(hwnd, haccel, &messages)) + { + TranslateMessage(&messages); + DispatchMessage(&messages); + } + + if (recv_key[0x58] && recv_key[0x42] && mousecapture) + { + ClipCursor(&oldclip); + ShowCursor(TRUE); + mousecapture=0; + } + + if ((recv_key[0x1D] || recv_key[0x9D]) && + (recv_key[0x38] || recv_key[0xB8]) && + (recv_key[0x51] || recv_key[0xD1]) && + video_fullscreen) + { + leave_fullscreen(); + } + } + + quited=1; + } + + startblit(); + Sleep(200); + TerminateThread(mainthreadh,0); + savenvr(); + saveconfig(); + closepc(); + + vid_apis[video_fullscreen][vid_api].close(); + + timeEndPeriod(1); + if (mousecapture) + { + ClipCursor(&oldclip); + ShowCursor(TRUE); + } + + UnregisterClass(szSubClassName, hinstance); + UnregisterClass(szClassName, hinstance); + + return messages.wParam; +} + +HHOOK hKeyboardHook; +int hook_enabled = 0; + +LRESULT CALLBACK LowLevelKeyboardProc( int nCode, WPARAM wParam, LPARAM lParam ) +{ + BOOL bControlKeyDown; + KBDLLHOOKSTRUCT* p; + + if (nCode < 0 || nCode != HC_ACTION) + return CallNextHookEx( hKeyboardHook, nCode, wParam, lParam); + + p = (KBDLLHOOKSTRUCT*)lParam; + + if (p->vkCode == VK_TAB && p->flags & LLKHF_ALTDOWN) return 1; /* disable alt-tab */ + if (p->vkCode == VK_SPACE && p->flags & LLKHF_ALTDOWN) return 1; /* disable alt-tab */ + if((p->vkCode == VK_LWIN) || (p->vkCode == VK_RWIN)) return 1; /* disable windows keys */ + if (p->vkCode == VK_ESCAPE && p->flags & LLKHF_ALTDOWN) return 1; /* disable alt-escape */ + bControlKeyDown = GetAsyncKeyState (VK_CONTROL) >> ((sizeof(SHORT) * 8) - 1); /* checks ctrl key pressed */ + if (p->vkCode == VK_ESCAPE && bControlKeyDown) return 1; /* disable ctrl-escape */ + + return CallNextHookEx( hKeyboardHook, nCode, wParam, lParam ); +} + +void cdrom_close(uint8_t id) +{ + switch (cdrom_drives[id].host_drive) + { + case 0: + null_close(id); + break; + default: + ioctl_close(id); + break; + case 200: + image_close(id); + break; + } +} + +int ide_ter_set_irq(HMENU hmenu, int irq, int id) +{ + if (ide_irq[2] == irq) + { + return 0; + } + if (msgbox_reset_yn(ghwnd) != IDYES) + { + return 0; + } + pause = 1; + Sleep(100); + ide_irq[2] = irq; + CheckMenuItem(hmenu, IDM_IDE_TER_IRQ9, MF_UNCHECKED); + CheckMenuItem(hmenu, IDM_IDE_TER_IRQ10, MF_UNCHECKED); + CheckMenuItem(hmenu, IDM_IDE_TER_IRQ11, MF_UNCHECKED); + CheckMenuItem(hmenu, IDM_IDE_TER_IRQ12, MF_UNCHECKED); + CheckMenuItem(hmenu, IDM_IDE_TER_IRQ14, MF_UNCHECKED); + CheckMenuItem(hmenu, IDM_IDE_TER_IRQ15, MF_UNCHECKED); + CheckMenuItem(hmenu, id, MF_CHECKED); + saveconfig(); + resetpchard(); + pause = 0; + return 1; +} + +int ide_qua_set_irq(HMENU hmenu, int irq, int id) +{ + if (ide_irq[3] == irq) + { + return 0; + } + if (msgbox_reset_yn(ghwnd) != IDYES) + { + return 0; + } + pause = 1; + Sleep(100); + ide_irq[3] = irq; + CheckMenuItem(hmenu, IDM_IDE_QUA_IRQ9, MF_UNCHECKED); + CheckMenuItem(hmenu, IDM_IDE_QUA_IRQ10, MF_UNCHECKED); + CheckMenuItem(hmenu, IDM_IDE_QUA_IRQ11, MF_UNCHECKED); + CheckMenuItem(hmenu, IDM_IDE_QUA_IRQ12, MF_UNCHECKED); + CheckMenuItem(hmenu, IDM_IDE_QUA_IRQ14, MF_UNCHECKED); + CheckMenuItem(hmenu, IDM_IDE_QUA_IRQ15, MF_UNCHECKED); + CheckMenuItem(hmenu, id, MF_CHECKED); + saveconfig(); + resetpchard(); + pause = 0; + return 1; +} + +void video_toggle_option(HMENU hmenu, int *val, int id) +{ + *val ^= 1; + CheckMenuItem(hmenu, id, *val ? MF_CHECKED : MF_UNCHECKED); + saveconfig(); +} + +void win_cdrom_eject(uint8_t id) +{ + HMENU hmenu; + hmenu = GetSubMenu(smenu, id + 4); + if (cdrom_drives[id].host_drive == 0) + { + /* Switch from empty to empty. Do nothing. */ + return; + } + 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(hmenu, IDM_CDROM_1_IMAGE + id, MF_UNCHECKED); + if ((cdrom_drives[id].host_drive >= 65) && (cdrom_drives[id].host_drive <= 90)) + { + CheckMenuItem(hmenu, IDM_CDROM_1_REAL + id + (cdrom_drive << 2), MF_UNCHECKED); + } + cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; + cdrom_drives[id].host_drive=0; + CheckMenuItem(hmenu, IDM_CDROM_1_EMPTY + id, MF_CHECKED); + update_status_bar_icon_state(0x10 | id, get_cd_state(id)); + update_tip(0x10 | id); + saveconfig(); +} + +void win_cdrom_reload(uint8_t id) +{ + HMENU hmenu; + hmenu = GetSubMenu(smenu, id + 4); + int new_cdrom_drive; + 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) + { + image_open(id, cdrom_image[id].image_path); + if (cdrom_drives[id].bus_type) + { + /* Signal disc change to the emulated machine. */ + cdrom_insert(id); + } + CheckMenuItem(hmenu, IDM_CDROM_1_EMPTY + id, MF_UNCHECKED); + cdrom_drives[id].host_drive = 200; + CheckMenuItem(hmenu, IDM_CDROM_1_IMAGE + id, MF_CHECKED); + } + 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(hmenu, IDM_CDROM_1_EMPTY + id, MF_UNCHECKED); + cdrom_drive = new_cdrom_drive; + CheckMenuItem(hmenu, IDM_CDROM_1_REAL + id + (cdrom_drives[id].host_drive << 2), MF_CHECKED); + } + update_status_bar_icon_state(0x10 | id, get_cd_state(id)); + update_tip(0x10 | id); + saveconfig(); +} + +static BOOL CALLBACK about_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + HWND h; + + switch (message) + { + case WM_INITDIALOG: + pause = 1; + h = GetDlgItem(hdlg, IDC_ABOUT_ICON); + SendMessage(h, STM_SETIMAGE, (WPARAM) IMAGE_ICON, (LPARAM) LoadIconBig((PCTSTR) 100)); + break; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDOK: + EndDialog(hdlg, 0); + pause = 0; + return TRUE; + default: + break; + } + break; + } + + return FALSE; +} + +void about_open(HWND hwnd) +{ + DialogBox(hinstance, (LPCTSTR) ABOUTDLG, hwnd, about_dlgproc); +} + +LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + HMENU hmenu; + RECT rect; + uint32_t ri_size = 0; + int edgex, edgey; + int sb_borders[3]; + + switch (message) + { + case WM_CREATE: + SetTimer(hwnd, TIMER_1SEC, 1000, NULL); + hKeyboardHook = SetWindowsHookEx( WH_KEYBOARD_LL, LowLevelKeyboardProc, GetModuleHandle(NULL), 0 ); + hook_enabled = 1; + break; + + case WM_COMMAND: + hmenu=GetMenu(hwnd); + switch (LOWORD(wParam)) + { + case IDM_FILE_HRESET: + pause=1; + Sleep(100); + savenvr(); + saveconfig(); + resetpchard(); + pause=0; + break; + case IDM_FILE_RESET_CAD: + pause=1; + Sleep(100); + savenvr(); + saveconfig(); + resetpc_cad(); + pause=0; + break; + case IDM_FILE_EXIT: + PostQuitMessage (0); /* send a WM_QUIT to the message queue */ + break; + case IDM_CONFIG: + win_settings_open(hwnd); + break; + case IDM_ABOUT: + about_open(hwnd); + break; + case IDM_STATUS: + status_open(hwnd); + break; + + case IDM_VID_RESIZE: + vid_resize=!vid_resize; + CheckMenuItem(hmenu, IDM_VID_RESIZE, (vid_resize)?MF_CHECKED:MF_UNCHECKED); + if (vid_resize) SetWindowLong(hwnd, GWL_STYLE, WS_OVERLAPPEDWINDOW|WS_VISIBLE); + else SetWindowLong(hwnd, GWL_STYLE, (WS_OVERLAPPEDWINDOW&~WS_SIZEBOX&~WS_THICKFRAME&~WS_MAXIMIZEBOX)|WS_VISIBLE); + SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_MINIMIZEBOX); + GetWindowRect(hwnd,&rect); + SetWindowPos(hwnd, 0, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER | SWP_FRAMECHANGED); + GetWindowRect(hwndStatus,&rect); + SetWindowPos(hwndStatus, 0, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER | SWP_FRAMECHANGED); + if (vid_resize) + { + CheckMenuItem(hmenu, IDM_VID_SCALE_1X + scale, MF_UNCHECKED); + CheckMenuItem(hmenu, IDM_VID_SCALE_2X, MF_CHECKED); + scale = 1; + } + EnableMenuItem(hmenu, IDM_VID_SCALE_1X, vid_resize ? MF_GRAYED : MF_ENABLED); + EnableMenuItem(hmenu, IDM_VID_SCALE_2X, vid_resize ? MF_GRAYED : MF_ENABLED); + EnableMenuItem(hmenu, IDM_VID_SCALE_3X, vid_resize ? MF_GRAYED : MF_ENABLED); + EnableMenuItem(hmenu, IDM_VID_SCALE_4X, vid_resize ? MF_GRAYED : MF_ENABLED); + win_doresize = 1; + saveconfig(); + break; + case IDM_VID_REMEMBER: + window_remember = !window_remember; + CheckMenuItem(hmenu, IDM_VID_REMEMBER, window_remember ? MF_CHECKED : MF_UNCHECKED); + GetWindowRect(hwnd, &rect); + if (window_remember) + { + window_x = rect.left; + window_y = rect.top; + window_w = rect.right - rect.left; + window_h = rect.bottom - rect.top; + } + saveconfig(); + break; + + case IDM_VID_DDRAW: case IDM_VID_D3D: + startblit(); + video_wait_for_blit(); + CheckMenuItem(hmenu, IDM_VID_DDRAW + vid_api, MF_UNCHECKED); + vid_apis[0][vid_api].close(); + vid_api = LOWORD(wParam) - IDM_VID_DDRAW; + CheckMenuItem(hmenu, IDM_VID_DDRAW + vid_api, MF_CHECKED); + vid_apis[0][vid_api].init(hwndRender); + endblit(); + saveconfig(); + device_force_redraw(); + break; + + case IDM_VID_FULLSCREEN: + + if(video_fullscreen!=1){ + + if (video_fullscreen_first) + { + video_fullscreen_first = 0; + msgbox_info(ghwnd, 2193); + } + startblit(); + video_wait_for_blit(); + mouse_close(); + vid_apis[0][vid_api].close(); + video_fullscreen = 1; + vid_apis[1][vid_api].init(ghwnd); + mouse_init(); + leave_fullscreen_flag = 0; + endblit(); + device_force_redraw(); + } + break; + + case IDM_VID_FS_FULL: + case IDM_VID_FS_43: + case IDM_VID_FS_SQ: + case IDM_VID_FS_INT: + CheckMenuItem(hmenu, IDM_VID_FS_FULL + video_fullscreen_scale, MF_UNCHECKED); + video_fullscreen_scale = LOWORD(wParam) - IDM_VID_FS_FULL; + CheckMenuItem(hmenu, IDM_VID_FS_FULL + video_fullscreen_scale, MF_CHECKED); + saveconfig(); + break; + + case IDM_VID_SCALE_1X: + case IDM_VID_SCALE_2X: + case IDM_VID_SCALE_3X: + case IDM_VID_SCALE_4X: + CheckMenuItem(hmenu, IDM_VID_SCALE_1X + scale, MF_UNCHECKED); + scale = LOWORD(wParam) - IDM_VID_SCALE_1X; + CheckMenuItem(hmenu, IDM_VID_SCALE_1X + scale, MF_CHECKED); + saveconfig(); + break; + + case IDM_VID_FORCE43: + video_toggle_option(hmenu, &force_43, IDM_VID_FORCE43); + break; + + case IDM_VID_INVERT: + video_toggle_option(hmenu, &invert_display, IDM_VID_INVERT); + break; + + case IDM_VID_OVERSCAN: + video_toggle_option(hmenu, &enable_overscan, IDM_VID_OVERSCAN); + update_overscan = 1; + break; + + case IDM_VID_FLASH: + video_toggle_option(hmenu, &enable_flash, IDM_VID_FLASH); + break; + + case IDM_VID_SCREENSHOT: + take_screenshot(); + break; + +#ifdef ENABLE_LOG_TOGGLES +#ifdef ENABLE_BUSLOGIC_LOG + case IDM_LOG_BUSLOGIC: + buslogic_do_log ^= 1; + CheckMenuItem(hmenu, IDM_LOG_BUSLOGIC, buslogic_do_log ? MF_CHECKED : MF_UNCHECKED); + break; +#endif + +#ifdef ENABLE_CDROM_LOG + case IDM_LOG_CDROM: + cdrom_do_log ^= 1; + CheckMenuItem(hmenu, IDM_LOG_CDROM, cdrom_do_log ? MF_CHECKED : MF_UNCHECKED); + break; +#endif + +#ifdef ENABLE_D86F_LOG + case IDM_LOG_D86F: + d86f_do_log ^= 1; + CheckMenuItem(hmenu, IDM_LOG_D86F, d86f_do_log ? MF_CHECKED : MF_UNCHECKED); + break; +#endif + +#ifdef ENABLE_FDC_LOG + case IDM_LOG_FDC: + fdc_do_log ^= 1; + CheckMenuItem(hmenu, IDM_LOG_FDC, fdc_do_log ? MF_CHECKED : MF_UNCHECKED); + break; +#endif + +#ifdef ENABLE_IDE_LOG + case IDM_LOG_IDE: + ide_do_log ^= 1; + CheckMenuItem(hmenu, IDM_LOG_IDE, ide_do_log ? MF_CHECKED : MF_UNCHECKED); + break; +#endif + +#ifdef ENABLE_NE2000_LOG + case IDM_LOG_NE2000: + ne2000_do_log ^= 1; + CheckMenuItem(hmenu, IDM_LOG_NE2000, ne2000_do_log ? MF_CHECKED : MF_UNCHECKED); + break; +#endif +#endif + +#ifdef ENABLE_LOG_BREAKPOINT + case IDM_LOG_BREAKPOINT: + pclog("---- LOG BREAKPOINT ----\n"); + break; +#endif + +#ifdef ENABLE_VRAM_DUMP + case IDM_DUMP_VRAM: + svga_dump_vram(); + break; +#endif + + case IDM_CONFIG_LOAD: + pause = 1; + if (!file_dlg_st(hwnd, 2174, "", 0)) + { + if (msgbox_reset_yn(ghwnd) == IDYES) + { + config_save(config_file_default); + loadconfig(wopenfilestring); + pclog_w(L"NVR path: %s\n", nvr_path); + mem_resize(); + loadbios(); + resetpchard(); + } + } + pause = 0; + break; + + case IDM_CONFIG_SAVE: + pause = 1; + if (!file_dlg_st(hwnd, 2174, "", 1)) + config_save(wopenfilestring); + pause = 0; + break; + } + return 0; + + case WM_INPUT: + { + UINT size; + RAWINPUT *raw; + + if (!infocus) + break; + + GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &size, sizeof(RAWINPUTHEADER)); + + raw = malloc(size); + + if (raw == NULL) + { + return 0; + } + + /* 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 0; + } + + /* If the input is keyboard, we process it */ + if (raw->header.dwType == RIM_TYPEKEYBOARD) + { + const RAWKEYBOARD rawKB = raw->data.keyboard; + USHORT 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)) + { + rawinputkey[scancode & 0x1ff] = !(rawKB.Flags & RI_KEY_BREAK); + recv_key[scancode & 0x1ff] = rawinputkey[scancode & 0x1ff]; + } + } + else + { + if (rawKB.MakeCode == 0x1D) + scancode = 0xFF; + if (!(scancode & 0xf00)) + { + rawinputkey[scancode & 0x1ff] = !(rawKB.Flags & RI_KEY_BREAK); + recv_key[scancode & 0x1ff] = rawinputkey[scancode & 0x1ff]; + } + } + } + free(raw); + + } + break; + + case WM_SETFOCUS: + infocus=1; + if (!hook_enabled) + { + hKeyboardHook = SetWindowsHookEx( WH_KEYBOARD_LL, LowLevelKeyboardProc, GetModuleHandle(NULL), 0 ); + hook_enabled = 1; + } + break; + + case WM_KILLFOCUS: + infocus=0; + if (mousecapture) + { + ClipCursor(&oldclip); + ShowCursor(TRUE); + mousecapture=0; + } + memset(rawinputkey, 0, sizeof(rawinputkey)); + if (video_fullscreen) + leave_fullscreen_flag = 1; + if (hook_enabled) + { + UnhookWindowsHookEx(hKeyboardHook); + hook_enabled = 0; + } + break; + + case WM_LBUTTONUP: + if (!mousecapture && !video_fullscreen) + { + RECT pcclip; + + GetClipCursor(&oldclip); + GetWindowRect(hwnd, &pcclip); + pcclip.left += GetSystemMetrics(SM_CXFIXEDFRAME) + 10; + pcclip.right -= GetSystemMetrics(SM_CXFIXEDFRAME) + 10; + pcclip.top += GetSystemMetrics(SM_CXFIXEDFRAME) + GetSystemMetrics(SM_CYMENUSIZE) + GetSystemMetrics(SM_CYCAPTION) + 10; + pcclip.bottom -= GetSystemMetrics(SM_CXFIXEDFRAME) + 10; + ClipCursor(&pcclip); + mousecapture = 1; + while (1) + { + if (ShowCursor(FALSE) < 0) break; + } + } + break; + + case WM_MBUTTONUP: + if (!(mouse_get_type(mouse_type) & MOUSE_TYPE_3BUTTON)) + releasemouse(); + break; + + case WM_ENTERMENULOOP: + break; + + case WM_SIZE: + winsizex = (lParam & 0xFFFF); + winsizey = (lParam >> 16) - (17 + 6); + + MoveWindow(hwndRender, 0, 0, + winsizex, + winsizey, + TRUE); + + if (vid_apis[video_fullscreen][vid_api].resize) + { + startblit(); + video_wait_for_blit(); + vid_apis[video_fullscreen][vid_api].resize(winsizex, winsizey); + endblit(); + } + + MoveWindow(hwndStatus, 0, winsizey + 6, + winsizex, + 17, + TRUE); + + if (mousecapture) + { + RECT pcclip; + + GetWindowRect(hwnd, &pcclip); + pcclip.left += GetSystemMetrics(SM_CXFIXEDFRAME) + 10; + pcclip.right -= GetSystemMetrics(SM_CXFIXEDFRAME) + 10; + pcclip.top += GetSystemMetrics(SM_CXFIXEDFRAME) + GetSystemMetrics(SM_CYMENUSIZE) + GetSystemMetrics(SM_CYCAPTION) + 10; + pcclip.bottom -= GetSystemMetrics(SM_CXFIXEDFRAME) + 10; + ClipCursor(&pcclip); + } + if (window_remember) + { + GetWindowRect(hwnd, &rect); + window_x = rect.left; + window_y = rect.top; + window_w = rect.right - rect.left; + window_h = rect.bottom - rect.top; + save_window_pos = 1; + } + break; + + case WM_MOVE: + if (window_remember) + { + GetWindowRect(hwnd, &rect); + window_x = rect.left; + window_y = rect.top; + window_w = rect.right - rect.left; + window_h = rect.bottom - rect.top; + save_window_pos = 1; + } + break; + + case WM_TIMER: + if (wParam == TIMER_1SEC) + onesec(); + break; + + case WM_RESETD3D: + startblit(); + if (video_fullscreen) + d3d_fs_reset(); + else + d3d_reset(); + endblit(); + break; + + case WM_LEAVEFULLSCREEN: + startblit(); + mouse_close(); + vid_apis[1][vid_api].close(); + video_fullscreen = 0; + vid_apis[0][vid_api].init(ghwnd); + mouse_init(); + endblit(); + device_force_redraw(); + break; + + case WM_KEYDOWN: + case WM_SYSKEYDOWN: + case WM_KEYUP: + case WM_SYSKEYUP: + return 0; + + case WM_DESTROY: + UnhookWindowsHookEx( hKeyboardHook ); + KillTimer(hwnd, TIMER_1SEC); + PostQuitMessage (0); /* send a WM_QUIT to the message queue */ + break; + + case WM_SYSCOMMAND: + /* Disable ALT key *ALWAYS*, I don't think there's any use for reaching the menu that way. */ + if (wParam == SC_KEYMENU && HIWORD(lParam) <= 0) + return 0; /*disable ALT key for menu*/ + + default: + return DefWindowProc (hwnd, message, wParam, lParam); + } + return 0; +} + +LRESULT CALLBACK subWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + default: + return DefWindowProc(hwnd, message, wParam, lParam); + } + return 0; +} + +VOID APIENTRY HandlePopupMenu(HWND hwnd, POINT pt, int id) +{ + HMENU pmenu; + int menu_id = -1; + if (id >= (sb_parts - 1)) + { + return; + } + pt.x = id * sb_icon_width; /* Justify to the left. */ + pt.y = 0; /* Justify to the top. */ + ClientToScreen(hwnd, (LPPOINT) &pt); + if ((sb_part_meanings[id] & 0x30) == 0x00) + { + menu_id = sb_part_meanings[id] & 0xf; + } + else if ((sb_part_meanings[id] & 0x30) == 0x10) + { + menu_id = (sb_part_meanings[id] & 0xf) + 4; + } + if (menu_id != -1) + { + pmenu = GetSubMenu(smenu, menu_id); + TrackPopupMenu(pmenu, TPM_LEFTALIGN | TPM_BOTTOMALIGN | TPM_LEFTBUTTON, pt.x, pt.y, 0, hwndStatus, NULL); + } +} + +LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + RECT rc; + POINT pt; + + WCHAR temp_image_path[1024]; + int new_cdrom_drive; + int cdrom_id = 0; + int menu_sub_param = 0; + int menu_super_param = 0; + int ret = 0; + + HMENU hmenu; + + switch (message) + { + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDM_DISC_1: + case IDM_DISC_1_WP: + ret = file_dlg_w_st(hwnd, 2173, discfns[0], 0); + if (!ret) + { + disc_close(0); + ui_writeprot[0] = (LOWORD(wParam) == IDM_DISC_1_WP) ? 1 : 0; + disc_load(0, wopenfilestring); + update_status_bar_icon_state(0x00, 0); + update_tip(0x00); + saveconfig(); + } + break; + case IDM_DISC_2: + case IDM_DISC_2_WP: + ret = file_dlg_w_st(hwnd, 2173, discfns[1], 0); + if (!ret) + { + disc_close(1); + ui_writeprot[1] = (LOWORD(wParam) == IDM_DISC_2_WP) ? 1 : 0; + disc_load(1, wopenfilestring); + update_status_bar_icon_state(0x01, 0); + update_tip(0x01); + saveconfig(); + } + break; + case IDM_DISC_3: + case IDM_DISC_3_WP: + ret = file_dlg_w_st(hwnd, 2173, discfns[2], 0); + if (!ret) + { + disc_close(2); + ui_writeprot[2] = (LOWORD(wParam) == IDM_DISC_3_WP) ? 1 : 0; + disc_load(2, wopenfilestring); + update_status_bar_icon_state(0x02, 0); + update_tip(0x02); + saveconfig(); + } + break; + case IDM_DISC_4: + case IDM_DISC_4_WP: + ret = file_dlg_w_st(hwnd, 2173, discfns[3], 0); + if (!ret) + { + disc_close(3); + ui_writeprot[3] = (LOWORD(wParam) == IDM_DISC_4_WP) ? 1 : 0; + disc_load(3, wopenfilestring); + update_status_bar_icon_state(0x03, 0); + update_tip(0x03); + saveconfig(); + } + break; + case IDM_EJECT_1: + disc_close(0); + update_status_bar_icon_state(0x00, 1); + update_tip(0x00); + saveconfig(); + break; + case IDM_EJECT_2: + disc_close(1); + update_status_bar_icon_state(0x01, 1); + update_tip(0x01); + saveconfig(); + break; + case IDM_EJECT_3: + disc_close(2); + update_status_bar_icon_state(0x02, 1); + update_tip(0x02); + saveconfig(); + break; + case IDM_EJECT_4: + disc_close(3); + update_status_bar_icon_state(0x03, 1); + update_tip(0x03); + saveconfig(); + break; + + case IDM_CDROM_1_MUTE: + case IDM_CDROM_2_MUTE: + case IDM_CDROM_3_MUTE: + case IDM_CDROM_4_MUTE: + cdrom_id = LOWORD(wParam) & 3; + hmenu = GetSubMenu(smenu, cdrom_id + 4); + Sleep(100); + cdrom_drives[cdrom_id].sound_on ^= 1; + CheckMenuItem(hmenu, IDM_CDROM_1_MUTE + (cdrom_id * 1000), cdrom_drives[cdrom_id].sound_on ? MF_UNCHECKED : MF_CHECKED); + saveconfig(); + sound_cd_thread_reset(); + break; + + case IDM_CDROM_1_EMPTY: + case IDM_CDROM_2_EMPTY: + case IDM_CDROM_3_EMPTY: + case IDM_CDROM_4_EMPTY: + cdrom_id = LOWORD(wParam) & 3; + hmenu = GetSubMenu(smenu, cdrom_id + 4); + win_cdrom_eject(cdrom_id); + break; + + case IDM_CDROM_1_RELOAD: + case IDM_CDROM_2_RELOAD: + case IDM_CDROM_3_RELOAD: + case IDM_CDROM_4_RELOAD: + cdrom_id = LOWORD(wParam) & 3; + hmenu = GetSubMenu(smenu, cdrom_id + 4); + win_cdrom_reload(cdrom_id); + break; + + case IDM_CDROM_1_IMAGE: + case IDM_CDROM_2_IMAGE: + case IDM_CDROM_3_IMAGE: + case IDM_CDROM_4_IMAGE: + cdrom_id = LOWORD(wParam) & 3; + hmenu = GetSubMenu(smenu, cdrom_id + 4); + if (!file_dlg_w_st(hwnd, 2175, cdrom_image[cdrom_id].image_path, 0)) + { + cdrom_drives[cdrom_id].prev_host_drive = cdrom_drives[cdrom_id].host_drive; + wcscpy(temp_image_path, wopenfilestring); + if ((wcscmp(cdrom_image[cdrom_id].image_path, temp_image_path) == 0) && (cdrom_drives[cdrom_id].host_drive == 200)) + { + /* Switching from image to the same image. Do nothing. */ + break; + } + cdrom_drives[cdrom_id].handler->exit(cdrom_id); + cdrom_close(cdrom_id); + image_open(cdrom_id, temp_image_path); + if (cdrom_drives[cdrom_id].bus_type) + { + /* Signal disc change to the emulated machine. */ + cdrom_insert(cdrom_id); + } + CheckMenuItem(hmenu, IDM_CDROM_1_EMPTY + cdrom_id, MF_UNCHECKED); + if ((cdrom_drives[cdrom_id].host_drive != 0) && (cdrom_drives[cdrom_id].host_drive != 200)) + { + CheckMenuItem(hmenu, IDM_CDROM_1_REAL + cdrom_id + (cdrom_drives[cdrom_id].host_drive << 2), MF_UNCHECKED); + } + cdrom_drives[cdrom_id].host_drive = 200; + CheckMenuItem(hmenu, IDM_CDROM_1_IMAGE + cdrom_id, MF_CHECKED); + update_tip(0x10 | cdrom_id); + saveconfig(); + } + break; + + default: + cdrom_id = LOWORD(wParam) & 3; + hmenu = GetSubMenu(smenu, cdrom_id + 4); + menu_sub_param = ((LOWORD(wParam) - IDM_CDROM_1_REAL) - cdrom_id) >> 2; + /* pclog("[%04X] Guest drive %c [%i]: -> Host drive %c [%i]:\n", LOWORD(wParam), 0x4b + cdrom_id, cdrom_id, menu_sub_param, menu_sub_param); */ + if (((LOWORD(wParam) & ~3) >= (IDM_CDROM_1_REAL + ('A' << 2))) && ((LOWORD(wParam) & ~3) <= (IDM_CDROM_1_REAL + ('Z' << 2)))) + { + new_cdrom_drive = menu_sub_param; + if (cdrom_drives[cdrom_id].host_drive == new_cdrom_drive) + { + /* Switching to the same drive. Do nothing. */ + break; + } + cdrom_drives[cdrom_id].prev_host_drive = cdrom_drives[cdrom_id].host_drive; + cdrom_drives[cdrom_id].handler->exit(cdrom_id); + cdrom_close(cdrom_id); + ioctl_open(cdrom_id, new_cdrom_drive); + if (cdrom_drives[cdrom_id].bus_type) + { + /* Signal disc change to the emulated machine. */ + cdrom_insert(cdrom_id); + } + CheckMenuItem(hmenu, IDM_CDROM_1_EMPTY + cdrom_id, MF_UNCHECKED); + if ((cdrom_drives[cdrom_id].host_drive != 0) && (cdrom_drives[cdrom_id].host_drive != 200)) + { + CheckMenuItem(hmenu, IDM_CDROM_1_REAL + cdrom_id + (cdrom_drives[cdrom_id].host_drive << 2), MF_UNCHECKED); + } + CheckMenuItem(hmenu, IDM_CDROM_1_IMAGE + cdrom_id, MF_UNCHECKED); + cdrom_drives[cdrom_id].host_drive = new_cdrom_drive; + CheckMenuItem(hmenu, IDM_CDROM_1_REAL + cdrom_id + (cdrom_drives[cdrom_id].host_drive << 2), MF_CHECKED); + update_tip(0x10 | cdrom_id); + saveconfig(); + } + break; + } + return 0; + + case WM_LBUTTONDOWN: + case WM_RBUTTONDOWN: + GetClientRect(hwnd, (LPRECT)& rc); + pt.x = GET_X_LPARAM(lParam); + pt.y = GET_Y_LPARAM(lParam); + if (PtInRect((LPRECT) &rc, pt)) + { + HandlePopupMenu(hwnd, pt, (pt.x / sb_icon_width)); + } + break; + + default: + return CallWindowProc((WNDPROC) OriginalStatusBarProcedure, hwnd, message, wParam, lParam); + } + return 0; +} diff --git a/src/WIN/win.h b/src/WIN/win.h new file mode 100644 index 000000000..0e09db88f --- /dev/null +++ b/src/WIN/win.h @@ -0,0 +1,51 @@ +/* Copyright holders: Sarah Walker + see COPYING for more details +*/ +extern HINSTANCE hinstance; +extern HWND ghwnd; +extern int mousecapture; + +#ifdef __cplusplus +extern "C" { +#endif + +#define szClassName L"86BoxMainWnd" +#define szSubClassName L"86BoxSubWnd" +#define szStatusBarClassName L"86BoxStatusBar" + +void leave_fullscreen(); + +#ifdef __cplusplus +} +#endif + + +void status_open(HWND hwnd); +extern HWND status_hwnd; +extern int status_is_open; + +void deviceconfig_open(HWND hwnd, struct device_t *device); +void joystickconfig_open(HWND hwnd, int joy_nr, int type); + +extern char openfilestring[260]; +extern WCHAR wopenfilestring[260]; + +int getfile(HWND hwnd, char *f, char *fn); +int getsfile(HWND hwnd, char *f, char *fn); + +void get_executable_name(WCHAR *s, int size); +void set_window_title(WCHAR *s); + +void startblit(); +void endblit(); + +extern int pause; + +void win_settings_open(HWND hwnd); +void win_menu_update(); + +void update_status_bar_panes(HWND hwnds); + +int fdd_type_to_icon(int type); + +extern HWND hwndStatus; diff --git a/src/WIN/win_cgapal.h b/src/WIN/win_cgapal.h new file mode 100644 index 000000000..d6ac7ffd8 --- /dev/null +++ b/src/WIN/win_cgapal.h @@ -0,0 +1,13 @@ +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 diff --git a/src/WIN/win_crashdump.c b/src/WIN/win_crashdump.c new file mode 100644 index 000000000..3fee061b3 --- /dev/null +++ b/src/WIN/win_crashdump.c @@ -0,0 +1,185 @@ +/* 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 +#include +#include +#include +#include +#include "../86box.h" +#include "win_crashdump.h" + +PVOID hExceptionHandler; +char* ExceptionHandlerBuffer; +#define ExceptionHandlerBufferSize (10240) + + +LONG CALLBACK MakeCrashDump(PEXCEPTION_POINTERS ExceptionInfo) { + // 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) { + // The exception code is not a fatal exception (highest 4 bits 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 86Box.exe. + char* CurrentBufferPointer; + GetModuleFileName(NULL,ExceptionHandlerBuffer,ExceptionHandlerBufferSize); + if (GetLastError() != ERROR_SUCCESS) { + // Could not get the full path of 86Box.exe. Just create the file in the current directory. + CurrentBufferPointer = ExceptionHandlerBuffer; + } else { + // Walk through the string backwards looking for the last backslash, so as to remove the "86Box.exe" filename from the string. + CurrentBufferPointer = &ExceptionHandlerBuffer[strlen(ExceptionHandlerBuffer)]; + for (; CurrentBufferPointer > ExceptionHandlerBuffer; CurrentBufferPointer--) { + if (CurrentBufferPointer[0] == '\\') { + // Found the backslash, null terminate the string after it. + CurrentBufferPointer[1] = 0; + break; + } + } + + CurrentBufferPointer = &ExceptionHandlerBuffer[strlen(ExceptionHandlerBuffer)]; + } + + // What would a good filename be? It should contain the current date and time so as to be (hopefully!) unique. + SYSTEMTIME SystemTime; + 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); + + DWORD Error; + + // Now the filename is in the buffer, the file can be created. + HANDLE 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. + CurrentBufferPointer = &ExceptionHandlerBuffer[strlen(ExceptionHandlerBuffer)]; + if (ipModule != 0) { + sprintf(CurrentBufferPointer," ["); + GetModuleFileName(ipModule,&CurrentBufferPointer[2],ExceptionHandlerBufferSize - strlen(ExceptionHandlerBuffer)); + if (GetLastError() == ERROR_SUCCESS) { + CurrentBufferPointer = &ExceptionHandlerBuffer[strlen(ExceptionHandlerBuffer)]; + sprintf(CurrentBufferPointer,"]"); + CurrentBufferPointer += 1; + } + } + + // Continue to create the crash-dump string. + sprintf(CurrentBufferPointer, + "\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++) { + CurrentBufferPointer = &ExceptionHandlerBuffer[strlen(ExceptionHandlerBuffer)]; + sprintf(CurrentBufferPointer,"0x%p ",ExceptionInfo->ExceptionRecord->ExceptionInformation[i]); + } + + CurrentBufferPointer = &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(CurrentBufferPointer, + "\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(CurrentBufferPointer,"\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() { + // 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); +} diff --git a/src/WIN/win_crashdump.h b/src/WIN/win_crashdump.h new file mode 100644 index 000000000..8048cd7af --- /dev/null +++ b/src/WIN/win_crashdump.h @@ -0,0 +1,7 @@ +/* Copyright holders: Riley + see COPYING for more details + + win-crashdump.c : Windows crash dump exception handler header file. +*/ + +void InitCrashDump(); \ No newline at end of file diff --git a/src/WIN/win_d3d-fs.cc b/src/WIN/win_d3d-fs.cc new file mode 100644 index 000000000..4e6a367cb --- /dev/null +++ b/src/WIN/win_d3d-fs.cc @@ -0,0 +1,587 @@ +/* Copyright holders: Sarah Walker, Tenshi + see COPYING for more details +*/ +#include +#include +#define UNICODE +#define BITMAP WINDOWS_BITMAP +#include +#undef BITMAP +#include +#include "../86box.h" +#include "../video/video.h" +#include "win.h" +#include "win_d3d-fs.h" +#include "win_cgapal.h" +#include "resource.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 + 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},{0x0b,0x0c,0x0a},{0x12,0x14,0x10},{0x15,0x17,0x13},{0x21,0x24,0x1e},{0x23,0x26,0x21},{0x30,0x31,0x2e},{0x34,0x35,0x33}, + {0x07,0x08,0x07},{0x0e,0x0f,0x0d},{0x19,0x1b,0x16},{0x1c,0x1f,0x1a},{0x28,0x2b,0x26},{0x2b,0x2d,0x2a},{0x37,0x38,0x37},{0x3d,0x3d,0x3c}, + }, + { // 5 - grey, 16-color-optimized contrast + {0x00,0x00,0x00},{0x0b,0x0c,0x0a},{0x0f,0x11,0x0e},{0x12,0x14,0x10},{0x1b,0x1d,0x18},{0x1c,0x1f,0x1a},{0x25,0x28,0x23},{0x28,0x2b,0x26}, + {0x1c,0x1e,0x19},{0x20,0x23,0x1d},{0x27,0x2a,0x25},{0x29,0x2c,0x27},{0x31,0x32,0x30},{0x33,0x34,0x32},{0x3a,0x3b,0x3a},{0x3d,0x3d,0x3c}, + }, +}; + +uint32_t pal_lookup[256]; + +static CUSTOMVERTEX d3d_verts[] = +{ + { 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f}, + {2048.0f, 2048.0f, 1.0f, 1.0f, 1.0f, 1.0f}, + { 0.0f, 2048.0f, 1.0f, 1.0f, 0.0f, 1.0f}, + + { 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f}, + {2048.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f}, + {2048.0f, 2048.0f, 1.0f, 1.0f, 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)) + { + 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) +{ + HRESULT hr; + WCHAR emulator_title[200]; + + d3d_fs_w = GetSystemMetrics(SM_CXSCREEN); + d3d_fs_h = GetSystemMetrics(SM_CYSCREEN); + + cgapal_rebuild(); + + d3d_hwnd = h; + + _swprintf(emulator_title, L"86Box v%s", emulator_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); + if (d3d == NULL) + { + return 0; + } + + 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 = d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, h, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3ddev); + if (FAILED(hr)) + { + return 0; + } + + 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(void) +{ + if (d3dTexture) + { + d3dTexture->Release(); + d3dTexture = NULL; + } + if (v_buffer) + { + v_buffer->Release(); + v_buffer = NULL; + } +} + +static void d3d_fs_init_objects(void) +{ + D3DLOCKED_RECT dr; + RECT r; + + d3ddev->CreateVertexBuffer(6*sizeof(CUSTOMVERTEX), + 0, + D3DFVF_XYZRHW | D3DFVF_TEX1, + D3DPOOL_MANAGED, + &v_buffer, + NULL); + + d3ddev->CreateTexture(2048, 2048, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &d3dTexture, NULL); + + // r.top = r.left = 0; + r.bottom = 2047; + 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 *)(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(void) +{ + 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(void) +{ + 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; + } + 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, t, r, b; + + if ((y1 == y2) || (d3dTexture == NULL)) + { + 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; + + if (FAILED(d3dTexture->LockRect(0, &dr, &lock_rect, 0))) + fatal("LockRect failed\n"); + + for (yy = y1; yy < y2; yy++) + memcpy((uint32_t *) &(((uint8_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(); + + 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; + + 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; + + 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_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; + uint32_t *p; + int xx, yy; + double l, t, r, b; + + if (!h || (d3dTexture == NULL)) + { + 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; + + if (FAILED(d3dTexture->LockRect(0, &dr, &lock_rect, 0))) + fatal("LockRect failed\n"); + + for (yy = 0; yy < h; yy++) + { + p = (uint32_t *) &(((uint8_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; + 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; + + 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; + + 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_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; +} diff --git a/src/WIN/win_d3d-fs.h b/src/WIN/win_d3d-fs.h new file mode 100644 index 000000000..41ca32e21 --- /dev/null +++ b/src/WIN/win_d3d-fs.h @@ -0,0 +1,13 @@ +/* Copyright holders: Sarah Walker, Tenshi + see COPYING for more details +*/ +#ifdef __cplusplus +extern "C" { +#endif + int d3d_fs_init(HWND h); + void d3d_fs_close(); + void d3d_fs_reset(); + void d3d_fs_resize(int x, int y); +#ifdef __cplusplus +} +#endif diff --git a/src/WIN/win_d3d.cc b/src/WIN/win_d3d.cc new file mode 100644 index 000000000..258bcd4f8 --- /dev/null +++ b/src/WIN/win_d3d.cc @@ -0,0 +1,398 @@ +/* Copyright holders: Sarah Walker, Tenshi + see COPYING for more details +*/ +#include +#define UNICODE +#define BITMAP WINDOWS_BITMAP +#include +#undef BITMAP +#include +#include "win.h" +#include "win_d3d.h" +#include "../video/video.h" +#include "win_cgapal.h" +#include "resource.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 + FLOAT tu, tv; +}; + +static CUSTOMVERTEX d3d_verts[] = +{ + { 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f}, + {2048.0f, 2048.0f, 1.0f, 1.0f, 1.0f, 1.0f}, + { 0.0f, 2048.0f, 1.0f, 1.0f, 0.0f, 1.0f}, + + { 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f}, + {2048.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f}, + {2048.0f, 2048.0f, 1.0f, 1.0f, 1.0f, 1.0f}, +}; + +int d3d_init(HWND h) +{ + HRESULT hr; + + cgapal_rebuild(); + + d3d_hwnd = h; + + d3d = Direct3DCreate9(D3D_SDK_VERSION); + if (d3d == NULL) + { + return 0; + } + + 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; + + hr = d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, h, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3ddev); + if (FAILED(hr)) + { + return 0; + } + + 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(void) +{ + if (d3dTexture) + { + d3dTexture->Release(); + d3dTexture = NULL; + } + if (v_buffer) + { + v_buffer->Release(); + v_buffer = NULL; + } +} + +void d3d_init_objects(void) +{ + D3DLOCKED_RECT dr; + RECT r; + + d3ddev->CreateVertexBuffer(6*sizeof(CUSTOMVERTEX), + 0, + D3DFVF_XYZRHW | D3DFVF_TEX1, + D3DPOOL_MANAGED, + &v_buffer, + NULL); + + d3ddev->CreateTexture(2048, 2048, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &d3dTexture, NULL); + + // 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 *)(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(void) +{ + HRESULT hr; + + 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(void) +{ + 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 ((w <= 0) || (w > 2048) || (h <= 0) || (h > 2048) || (y1 == y2) || (y1 < 0) || (y1 > 2048) || (y2 < 0) || (y2 > 2048) || (d3dTexture == NULL)) + { + video_blit_complete(); + return; /*Nothing to do*/ + } + + r.top = y1; + r.left = 0; + r.bottom = y2; + r.right = 2047; + + if (hr == D3D_OK) + { + if (FAILED(d3dTexture->LockRect(0, &dr, &r, 0))) + fatal("LockRect failed\n"); + + for (yy = y1; yy < y2; yy++) + memcpy((uint32_t *) &(((uint8_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(); + + 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; + + 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; + + 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_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; + uint32_t *p; + int yy, xx; + HRESULT hr = D3D_OK; + + if ((w <= 0) || (w > 2048) || (h <= 0) || (h > 2048) || (d3dTexture == NULL)) + { + video_blit_complete(); + return; /*Nothing to do*/ + } + + r.top = 0; + r.left = 0; + r.bottom = h; + r.right = 2047; + + if (hr == D3D_OK) + { + if (FAILED(d3dTexture->LockRect(0, &dr, &r, 0))) + fatal("LockRect failed\n"); + + for (yy = 0; yy < h; yy++) + { + p = (uint32_t *) &((((uint8_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; + + 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; + + 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_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; +} diff --git a/src/WIN/win_d3d.h b/src/WIN/win_d3d.h new file mode 100644 index 000000000..7210d454b --- /dev/null +++ b/src/WIN/win_d3d.h @@ -0,0 +1,13 @@ +/* Copyright holders: Sarah Walker, Tenshi + see COPYING for more details +*/ +#ifdef __cplusplus +extern "C" { +#endif + int d3d_init(HWND h); + void d3d_close(); + void d3d_reset(); + void d3d_resize(int x, int y); +#ifdef __cplusplus +} +#endif diff --git a/src/WIN/win_ddraw-fs.cc b/src/WIN/win_ddraw-fs.cc new file mode 100644 index 000000000..42fd984ed --- /dev/null +++ b/src/WIN/win_ddraw-fs.cc @@ -0,0 +1,338 @@ +/* Copyright holders: Sarah Walker, Tenshi + see COPYING for more details +*/ +#include +#define UNICODE +#define BITMAP WINDOWS_BITMAP +#include +#undef BITMAP +#include "../video/video.h" +#include "win_ddraw-fs.h" +#include "win_ddraw-screenshot.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_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 x, int y, int y1, int y2, int w, int h); +static void ddraw_fs_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; +static int ddraw_w, ddraw_h; + +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))) + 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); + } + + if (readflash && enable_flash) + { + RECT r; + r.left = window_rect.right - 40; + r.right = window_rect.right - 8; + r.top = 8; + r.bottom = 14; + ddbltfx.dwFillColor = 0xffffff; + lpdds_back2->Blt(&r, NULL, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &ddbltfx); + } + + 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); + } + + if (readflash && enable_flash) + { + RECT r; + r.left = window_rect.right - 40; + r.right = window_rect.right - 8; + r.top = 8; + r.bottom = 14; + ddbltfx.dwFillColor = 0xffffff; + lpdds_back2->Blt(&r, NULL, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &ddbltfx); + } + + lpdds_pri->Flip(NULL, DDFLIP_NOVSYNC); +} + +void ddraw_fs_take_screenshot(wchar_t *fn) +{ + ddraw_common_take_screenshot(fn, lpdds_back2); +} diff --git a/src/WIN/win_ddraw-fs.h b/src/WIN/win_ddraw-fs.h new file mode 100644 index 000000000..048c9c160 --- /dev/null +++ b/src/WIN/win_ddraw-fs.h @@ -0,0 +1,11 @@ +/* Copyright holders: Sarah Walker, Tenshi + see COPYING for more details +*/ +#ifdef __cplusplus +extern "C" { +#endif + int ddraw_fs_init(HWND h); + void ddraw_fs_close(); +#ifdef __cplusplus +} +#endif diff --git a/src/WIN/win_ddraw-screenshot.cc b/src/WIN/win_ddraw-screenshot.cc new file mode 100644 index 000000000..bb3cb6660 --- /dev/null +++ b/src/WIN/win_ddraw-screenshot.cc @@ -0,0 +1,178 @@ +/* Copyright holders: Tenshi + see COPYING for more details +*/ +#include +#include +#define UNICODE +#define BITMAP WINDOWS_BITMAP +#include +#undef BITMAP +#include "../video/video.h" +#include "win.h" +#include "win_ddraw-screenshot.h" +#include "win_language.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 ddraw_init(HWND h); +extern "C" void ddraw_close(void); + +HBITMAP hbitmap; + +int xs, ys, ys2; + +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(2194), 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); +} diff --git a/src/WIN/win_ddraw-screenshot.h b/src/WIN/win_ddraw-screenshot.h new file mode 100644 index 000000000..4739174a1 --- /dev/null +++ b/src/WIN/win_ddraw-screenshot.h @@ -0,0 +1,4 @@ +/* Copyright holders: Tenshi + see COPYING for more details +*/ +void ddraw_common_take_screenshot(wchar_t *fn, IDirectDrawSurface7 *pDDSurface); diff --git a/src/WIN/win_ddraw.cc b/src/WIN/win_ddraw.cc new file mode 100644 index 000000000..af329eb29 --- /dev/null +++ b/src/WIN/win_ddraw.cc @@ -0,0 +1,318 @@ +/* Copyright holders: Sarah Walker, Tenshi + see COPYING for more details +*/ +#include +#include +#define UNICODE +#define BITMAP WINDOWS_BITMAP +#include +#undef BITMAP +#include "../video/video.h" +#include "win_ddraw.h" +#include "win_ddraw-screenshot.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))) + 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_back2, NULL))) + return 0; + + 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 xx, yy; + POINT po; + uint32_t *p; + 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*/ + } + + 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); + } + + if (readflash) + { + readflash = 0; +#ifdef LEGACY_READ_FLASH + if (enable_flash) + { + hr = lpdds_back2->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); + if (hr == DDERR_SURFACELOST) + { + lpdds_back2->Restore(); + lpdds_back2->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); + device_force_redraw(); + } + if (!ddsd.lpSurface) return; + for (yy = 8; yy < 14; yy++) + { + p = &(((uint32_t *) ddsd.lpSurface)[yy * ddsd.lPitch]); + for (xx = (w - 40); xx < (w - 8); xx++) + p[xx] = 0xffffffff; + } + } +#endif + } + 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); + } + + if (readflash) + { + readflash = 0; + if (enable_flash) + { + hr = lpdds_back2->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); + if (hr == DDERR_SURFACELOST) + { + lpdds_back2->Restore(); + lpdds_back2->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); + device_force_redraw(); + } + if (!ddsd.lpSurface) return; + for (yy = 8; yy < 14; yy++) + { + p = (uint32_t *) &(((uint8_t *) ddsd.lpSurface)[yy * ddsd.lPitch]); + for (xx = (w - 40); xx < (w - 8); xx++) + p[xx] = 0xffffffff; + } + lpdds_back2->Unlock(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); +} diff --git a/src/WIN/win_ddraw.h b/src/WIN/win_ddraw.h new file mode 100644 index 000000000..a4044899d --- /dev/null +++ b/src/WIN/win_ddraw.h @@ -0,0 +1,12 @@ +/* Copyright holders: Sarah Walker, Tenshi + see COPYING for more details +*/ +#ifdef __cplusplus +extern "C" { +#endif + int ddraw_init(HWND h); + void ddraw_close(); +#ifdef __cplusplus +} +#endif + diff --git a/src/WIN/win_deviceconfig.c b/src/WIN/win_deviceconfig.c new file mode 100644 index 000000000..457a38f75 --- /dev/null +++ b/src/WIN/win_deviceconfig.c @@ -0,0 +1,317 @@ +/* Copyright holders: Sarah Walker + see COPYING for more details +*/ +#define BITMAP WINDOWS_BITMAP +#include +#include +#undef BITMAP + +#include "../ibm.h" +#include "../config.h" +#include "../device.h" +#include "resource.h" +#include "win.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 num; + char s[80]; + + switch (message) + { + case WM_INITDIALOG: + { + int id = IDC_CONFIG_BASE; + device_config_t *config = config_device->config; + int c; + + while (config->type != -1) + { + device_config_selection_t *selection = config->selection; + 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; + } + config++; + } + } + return TRUE; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDOK: + { + int id = IDC_CONFIG_BASE; + device_config_t *config = config_device->config; + int c; + int changed = 0; + + while (config->type != -1) + { + device_config_selection_t *selection = config->selection; + 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; + } + config++; + } + + if (!changed) + { + EndDialog(hdlg, 0); + return TRUE; + } + + if (MessageBox(NULL, "This will reset 86Box!\nOkay to continue?", "86Box", MB_OKCANCEL) != IDOK) + { + EndDialog(hdlg, 0); + return TRUE; + } + + id = IDC_CONFIG_BASE; + config = config_device->config; + + while (config->type != -1) + { + device_config_selection_t *selection = config->selection; + 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; + } + config++; + } + + saveconfig(); + + resetpchard(); + + EndDialog(hdlg, 0); + return TRUE; + } + case IDCANCEL: + EndDialog(hdlg, 0); + return TRUE; + } + break; + } + return FALSE; +} + +void deviceconfig_open(HWND hwnd, device_t *device) +{ + device_config_t *config = device->config; + uint16_t *data_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++ = 8; /*Point*/ + data += MultiByteToWideChar(CP_ACP, 0, "MS Sans Serif", -1, data, 50); + + if (((unsigned long)data) & 2) + data++; + + while (config->type != -1) + { + switch (config->type) + { + case CONFIG_BINARY: + item = (DLGITEMTEMPLATE *)data; + item->x = 10; + item->y = y; + item->id = id++; + + item->cx = 80; + item->cy = 15; + + item->style = WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX; + + data = (uint16_t *)(item + 1); + *data++ = 0xFFFF; + *data++ = 0x0080; /* button class */ + + data += MultiByteToWideChar(CP_ACP, 0, config->description, -1, data, 256); + *data++ = 0; /* no creation data */ + + y += 20; + break; + + case CONFIG_SELECTION: + /*Combo box*/ + item = (DLGITEMTEMPLATE *)data; + item->x = 70; + item->y = y; + item->id = id++; + + item->cx = 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; + } + + 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); +} diff --git a/src/WIN/win_joystick.cc b/src/WIN/win_joystick.cc new file mode 100644 index 000000000..63d970eaa --- /dev/null +++ b/src/WIN/win_joystick.cc @@ -0,0 +1,281 @@ +/* Copyright holders: Sarah Walker, Tenshi + see COPYING for more details +*/ +#define DIRECTINPUT_VERSION 0x0800 +#include +#include +#include +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; + } + } +} + diff --git a/src/WIN/win_joystickconfig.c b/src/WIN/win_joystickconfig.c new file mode 100644 index 000000000..8962366d6 --- /dev/null +++ b/src/WIN/win_joystickconfig.c @@ -0,0 +1,541 @@ +/* Copyright holders: Sarah Walker + see COPYING for more details +*/ +#define BITMAP WINDOWS_BITMAP +#include +#include +#undef BITMAP + +#include "../ibm.h" +#include "../config.h" +#include "../device.h" +#include "../gameport.h" +#include "plat_joystick.h" +#include "resource.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); +} diff --git a/src/WIN/win_language.c b/src/WIN/win_language.c new file mode 100644 index 000000000..e87964d37 --- /dev/null +++ b/src/WIN/win_language.c @@ -0,0 +1,197 @@ +/* Copyright holders: Sarah Walker, Tenshi + see COPYING for more details +*/ +#include +#define UNICODE +#define BITMAP WINDOWS_BITMAP +#include +#include +#undef BITMAP + +#include + +#include "../ibm.h" +#include "../device.h" +#include "../ide.h" +#include "resource.h" +#include "win.h" +#include "win_language.h" + +LCID dwLanguage; + +uint32_t dwLangID, dwSubLangID; + +#define STRINGS_NUM 154 + +WCHAR lpResourceString[STRINGS_NUM][512]; + +char openfilestring[260]; +WCHAR wopenfilestring[260]; + +void win_language_set() +{ + SetThreadLocale(dwLanguage); +} + +void win_language_load_common_strings() +{ + int i = 0; + + for (i = 0; i < STRINGS_NUM; i++) + { + LoadString(hinstance, 2048 + i, lpResourceString[i], 512); + } +} + +LPTSTR win_language_get_settings_category(int i) +{ + return lpResourceString[17 + i]; +} + +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) +{ + return lpResourceString[i - 2048]; +} + +LPTSTR win_language_get_string_from_string(char *str) +{ + return lpResourceString[atoi(str) - 2048]; +} + +int msgbox_reset(HWND hwndParent) +{ + return MessageBox(hwndParent, lpResourceString[3], lpResourceString[0], MB_YESNOCANCEL | MB_ICONQUESTION); +} + +int msgbox_reset_yn(HWND hwndParent) +{ + return MessageBox(hwndParent, lpResourceString[3], lpResourceString[0], MB_YESNO | MB_ICONQUESTION); +} + +int msgbox_question(HWND hwndParent, int i) +{ + return MessageBox(hwndParent, win_language_get_string_from_id(i), lpResourceString[0], MB_YESNO | MB_ICONQUESTION); +} + +void msgbox_info(HWND hwndParent, int i) +{ + MessageBox(hwndParent, win_language_get_string_from_id(i), lpResourceString[0], MB_OK | MB_ICONINFORMATION); +} + +void msgbox_info_wstr(HWND hwndParent, WCHAR *wstr) +{ + MessageBox(hwndParent, wstr, lpResourceString[0], MB_OK | MB_ICONINFORMATION); +} + +void msgbox_error(HWND hwndParent, int i) +{ + MessageBox(hwndParent, win_language_get_string_from_id(i), lpResourceString[1], MB_OK | MB_ICONWARNING); +} + +void msgbox_error_wstr(HWND hwndParent, WCHAR *wstr) +{ + MessageBox(hwndParent, wstr, lpResourceString[1], MB_OK | MB_ICONWARNING); +} + +void msgbox_critical(HWND hwndParent, int i) +{ + MessageBox(hwndParent, win_language_get_string_from_id(i), lpResourceString[2], 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, lpResourceString[2], MB_OK | MB_ICONERROR); + + free(lptsTemp); +} + +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, 520); + 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_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); +} diff --git a/src/WIN/win_language.h b/src/WIN/win_language.h new file mode 100644 index 000000000..5c4237249 --- /dev/null +++ b/src/WIN/win_language.h @@ -0,0 +1,33 @@ +#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_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); + +#ifdef __cplusplus +} +#endif diff --git a/src/WIN/win_midi.c b/src/WIN/win_midi.c new file mode 100644 index 000000000..2fdf58bec --- /dev/null +++ b/src/WIN/win_midi.c @@ -0,0 +1,279 @@ +/* Copyright holders: Sarah Walker + see COPYING for more details +*/ +#include +#include +#include "../ibm.h" +#include "../config.h" +#include "plat_midi.h" + +int midi_id; +static HMIDIOUT midi_out_device = NULL; + +HANDLE m_event; + +void midi_close(); + +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; + +uint8_t MIDI_evt_len[256] = { + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x00 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x10 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x20 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x30 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x40 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x50 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x60 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x70 + + 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0x80 + 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0x90 + 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0xa0 + 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0xb0 + + 2,2,2,2, 2,2,2,2, 2,2,2,2, 2,2,2,2, // 0xc0 + 2,2,2,2, 2,2,2,2, 2,2,2,2, 2,2,2,2, // 0xd0 + + 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0xe0 + + 0,2,3,2, 0,0,1,0, 1,0,1,1, 1,0,1,0 // 0xf0 +}; + +void midi_init() +{ + MMRESULT hr = MMSYSERR_NOERROR; + + memset(midi_rt_buf, 0, 1024); + memset(midi_cmd_buf, 0, 1024); + + midi_cmd_pos = midi_cmd_len = 0; + midi_status = 0; + + midi_sysex_start = midi_sysex_delay = 0; + + midi_id = config_get_int(NULL, "midi", 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 midi_close() +{ + if (midi_out_device != NULL) + { + midiOutReset(midi_out_device); + midiOutClose(midi_out_device); + midi_out_device = NULL; + CloseHandle(m_event); + } +} + +int midi_get_num_devs() +{ + return midiOutGetNumDevs(); +} +void midi_get_dev_name(int num, char *s) +{ + MIDIOUTCAPS caps; + + midiOutGetDevCaps(num, &caps, sizeof(caps)); + strcpy(s, caps.szPname); +} + +static int midi_pos, midi_len; +static uint32_t midi_command; +static int midi_lengths[8] = {3, 3, 3, 3, 2, 2, 3, 1}; +static int midi_insysex; +static char midi_sysex_data[1024+2]; + +static void midi_send_sysex() +{ + MIDIHDR hdr; + + hdr.lpData = midi_sysex_data; + hdr.dwBufferLength = midi_pos; + hdr.dwFlags = 0; + + midiOutPrepareHeader(midi_out_device, &hdr, sizeof(MIDIHDR)); + midiOutLongMsg(midi_out_device, &hdr, sizeof(MIDIHDR)); + + midi_insysex = 0; +} + +void PlayMsg(uint8_t *msg) +{ + midiOutShortMsg(midi_out_device, *(uint32_t *) msg); +} + +MIDIHDR m_hdr; + +void PlaySysex(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; + } +} + +#define SYSEX_SIZE 1024 +#define RAWBUF 1024 + +void midi_write(uint8_t val) +{ + uint32_t passed_ticks; + + if (midi_sysex_start) + { + passed_ticks = GetTickCount() - midi_sysex_start; + if (passed_ticks < midi_sysex_delay) + { + Sleep(midi_sysex_delay - passed_ticks); + } + } + + /* Test for a realtime MIDI message */ + if (val >= 0xf8) + { + midi_rt_buf[0] = val; + PlayMsg(midi_rt_buf); + return; + } + + /* Test for a active sysex transfer */ + + if (midi_status == 0xf0) + { + if (!(val & 0x80)) + { + if (midi_pos < (SYSEX_SIZE-1)) midi_sysex_data[midi_pos++] = val; + return; + } + else + { + midi_sysex_data[midi_pos++] = 0xf7; + + if ((midi_sysex_start) && (midi_pos >= 4) && (midi_pos <= 9) && (midi_sysex_data[1] == 0x411) && (midi_sysex_data[3] == 0x16)) + { + /* pclog("MIDI: Skipping invalid MT-32 SysEx MIDI message\n"); */ + } + else + { + PlaySysex(midi_sysex_data, midi_pos); + if (midi_sysex_start) + { + if (midi_sysex_data[5] == 0x7f) + { + midi_sysex_delay = 290; /* All parameters reset */ + } + else if ((midi_sysex_data[5] == 0x10) && (midi_sysex_data[6] == 0x00) && (midi_sysex_data[7] == 0x04)) + { + midi_sysex_delay = 145; /* Viking Child */ + } + else if ((midi_sysex_data[5] == 0x10) && (midi_sysex_data[6] == 0x00) && (midi_sysex_data[7] == 0x01)) + { + midi_sysex_delay = 30; /* Dark Sun 1 */ + } + else + midi_sysex_delay = (unsigned int) (((float) (midi_pos) * 1.25f) * 1000.0f / 3125.0f) + 2; + + midi_sysex_start = GetTickCount(); + } + } + } + } + + + if (val & 0x80) + { + midi_status = val; + midi_cmd_pos = 0; + midi_cmd_len = MIDI_evt_len[val]; + if (midi_status == 0xf0) + { + midi_sysex_data[0] = 0xf0; + midi_pos = 1; + } + } + + if (midi_cmd_len) + { + midi_cmd_buf[midi_cmd_pos++] = val; + if (midi_cmd_pos >= midi_cmd_len) + { + PlayMsg(midi_cmd_buf); + midi_cmd_pos = 1; + } + } +} + +void midi_reset() +{ + uint8_t buf[64], used; + + /* Flush buffers */ + midiOutReset(midi_out_device); + + /* GM1 reset */ + buf[0] = 0xf0; + buf[1] = 0x7e; + buf[2] = 0x7f; + buf[3] = 0x09; + buf[4] = 0x01; + buf[5] = 0xf7; + PlaySysex((uint8_t *) buf, 6); + + /* GS1 reset */ + buf[0] = 0xf0; + buf[1] = 0x41; + buf[2] = 0x10; + buf[3] = 0x42; + buf[4] = 0x12; + buf[5] = 0x40; + buf[6] = 0x00; + buf[7] = 0x7f; + buf[8] = 0x00; + buf[9] = 0x41; + buf[10] = 0xf7; + PlaySysex((uint8_t *) buf, 11); +} diff --git a/src/WIN/win_mouse.cc b/src/WIN/win_mouse.cc new file mode 100644 index 000000000..f64b714a0 --- /dev/null +++ b/src/WIN/win_mouse.cc @@ -0,0 +1,75 @@ +/* Copyright holders: Sarah Walker, Tenshi + see COPYING for more details +*/ +#define DIRECTINPUT_VERSION 0x0800 +#include +#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(); +extern "C" void mouse_close(); +extern "C" void mouse_poll_host(); +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() +{ + 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() +{ + if (lpdi_mouse) + { + lpdi_mouse->Release(); + lpdi_mouse = NULL; + } +} + +void mouse_poll_host() +{ + 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; +} diff --git a/src/WIN/win_opendir.c b/src/WIN/win_opendir.c new file mode 100644 index 000000000..00347a365 --- /dev/null +++ b/src/WIN/win_opendir.c @@ -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, + * Copyright 1998-2007 MicroWalt Corporation + * Copyright 2017 Fred N. van Kempen + */ +#define UNICODE +#include +#include +#include +#include +#include +#include +#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; + } + } +} diff --git a/src/WIN/win_serial.c b/src/WIN/win_serial.c new file mode 100644 index 000000000..cfe8f0b43 --- /dev/null +++ b/src/WIN/win_serial.c @@ -0,0 +1,606 @@ +/* + * 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.2 2017/05/17 + * + * Author: Fred N. van Kempen, + * Copyright 2017 Fred N. van Kempen. + */ +#define _WIN32_WINNT 0x0501 +#include +#include +#include +#define BHTTY_C +#include "plat_serial.h" + + +extern void pclog(char *__fmt, ...); + + +/* Set the state of a port. */ +int +bhtty_sstate(BHTTY *pp, void *arg) +{ + int i = 0; + + /* Make sure we can do this. */ + if (pp == NULL || arg == NULL) { + pclog("invalid argument\n"); + 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) +{ + int i = 0; + + /* Make sure we can do this. */ + if (pp == NULL || arg == NULL) { + pclog("BHTTY: invalid argument\n"); + 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) +{ + /* Make sure we can do this. */ + if (pp == NULL) { + pclog("invalid handle\n"); + return(-1); + } + + /* 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) +{ + /* Make sure we can do this. */ + if (pp == NULL) { + pclog("invalid handle\n"); + return(-1); + } + + /* 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 (pp == NULL || arg == NULL) { + pclog("invalid parameter\n"); + 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) +{ + int i; + + /* Make sure we can do this. */ + if (pp == NULL) { + pclog("invalid handle\n"); + return(-1); + } + + /* 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; + int i = 0; + + /* Make sure we can do this. */ + if (pp == NULL) { + pclog("invalid handle\n"); + return(-1); + } + + /* 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) +{ + /* Make sure we can do this. */ + if (pp == NULL) { + pclog("BHTTY: invalid handle\n"); + return; + } + + if (pp->handle != INVALID_HANDLE_VALUE) { + /* 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 buff[64]; + COMMTIMEOUTS to; +#if 0 + COMMCONFIG conf; + DWORD d; +#endif + BHTTY *pp; + int i = 0; + + /* Make sure we can do this. */ + if (port == NULL) { + pclog("invalid argument!\n"); + return(NULL); + } + + /* 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(buff, "\\\\.\\%s", pp->name); + pp->handle = CreateFile(buff, + (GENERIC_READ|GENERIC_WRITE), + 0, NULL, OPEN_EXISTING, + FILE_FLAG_OVERLAPPED, + 0); + if (pp->handle == INVALID_HANDLE_VALUE) { + pclog("%s: open port: %d\n", pp->name, GetLastError()); + free(pp); + return(NULL); + } + +#if 0 + /* 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()); +// CloseHandle(pp->handle); +// free(pp); +// return(NULL); + } + + /* Grab default config for the driver and set it. */ + d = sizeof(COMMCONFIG); + memset(&conf, 0x00, d); + conf.dwSize = d; + if (GetDefaultCommConfig(pp->name, &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()); +// CloseHandle(pp->handle); +// free(pp); +// return(NULL); + } + } +#endif + + /* + * 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); +} + + +/* A pending WRITE has finished, handle it. */ +static VOID CALLBACK +bhtty_write_comp(DWORD err, DWORD num, OVERLAPPED *priv) +{ + BHTTY *pp = (BHTTY *)priv->hEvent; + +//pclog("%s: write complete, status %d, num %d\n", pp->name, err, num); +#if 0 + if ( + if (GetOverlappedResult(p->handle, + &p->rov, &mst, TRUE) == FALSE) { + r = GetLastError(); + if (r != ERROR_OPERATION_ABORTED) + /* OK, we're being shut down. */ + sprintf(serial_errmsg, + "%s: I/O read error!", p->name); + return(-1); + } +#endif +} + + +/* Try to write data to an open port. */ +int +bhtty_write(BHTTY *pp, unsigned char val) +{ + DWORD n; + + /* Make sure we can do this. */ + if (pp == NULL) { + pclog("invalid parameter\n"); + return(-1); + } +//pclog("BHwrite(%08lx, %02x, '%c')\n", pp->handle, val, val); + + /* Save the control pointer for later use. */ + pp->wov.hEvent = (HANDLE)pp; + + if (WriteFileEx(pp->handle, + &val, 1, + &pp->wov, + bhtty_write_comp) == FALSE) { + n = GetLastError(); + pclog("%s: I/O error %d in write!\n", pp->name, n); + return(-1); + } + + /* Its pending, so handled in the completion routine. */ + SleepEx(1, TRUE); + + return(0); +} + + +/* + * A pending READ has finished, handle it. + */ +static VOID CALLBACK +bhtty_read_comp(DWORD err, DWORD num, OVERLAPPED *priv) +{ + BHTTY *pp = (BHTTY *)priv->hEvent; + DWORD r; +//pclog("%s: read complete, status %d, num %d\n", pp->name, err, num); + + if (GetOverlappedResult(pp->handle, &pp->rov, &r, TRUE) == FALSE) { + r = GetLastError(); + if (r != ERROR_OPERATION_ABORTED) + /* OK, we're being shut down. */ + pclog("%s: I/O read error!", pp->name); + return; + } +//pclog("%s: read done, num=%d (%d)\n", pp->name, num, r); + + /* Do a callback to let them know. */ + if (pp->rd_done != NULL) + pp->rd_done(pp->rd_arg, num); +} + + +/* + * 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 + * + * Also, not that we do not wait here. We just POST a + * read operation, and the completion routine will do + * the clean-up and notify the caller. + */ +int +bhtty_read(BHTTY *pp, unsigned char *bufp, int max) +{ + DWORD r; + + /* Just one byte. */ + max = 1; + + /* Make sure we can do this. */ + if (pp == NULL) { + pclog("invalid parameter\n"); + return(-1); + } + + /* Save the control pointer for later use. */ + pp->rov.hEvent = (HANDLE)pp; +//pclog("%s: read(%08lx, %d)\n", pp->name, pp->handle, max); + + /* Post a READ on the device. */ + if (ReadFileEx(pp->handle, + bufp, (DWORD)max, + &pp->rov, + bhtty_read_comp) == FALSE) { + r = GetLastError(); + if (r != ERROR_IO_PENDING) { + /* OK, we're being shut down. */ + if (r != ERROR_INVALID_HANDLE) + pclog("%s: I/O read error!\n", pp->name); + return(-1); + } + } + + /* Make ourself alertable. */ + SleepEx(1, TRUE); + + /* OK, it's pending, so we are good for now. */ + return(0); +} diff --git a/src/WIN/win_settings.c b/src/WIN/win_settings.c new file mode 100644 index 000000000..6916bca28 --- /dev/null +++ b/src/WIN/win_settings.c @@ -0,0 +1,3694 @@ +/* Copyright holders: Sarah Walker, Tenshi + see COPYING for more details +*/ +#define UNICODE +#define BITMAP WINDOWS_BITMAP +#include +#include +#undef BITMAP + +#include +#include +#include "../ibm.h" +#include "../mem.h" +#include "../cpu/cpu.h" +#include "../nvr.h" +#include "../model.h" +#include "../device.h" +#include "../cdrom.h" +#include "../disc.h" +#include "../fdd.h" +#include "../hdd.h" +#include "../ide.h" +#include "../scsi.h" +#include "../scsi_buslogic.h" +#include "../network.h" +#include "../sound/sound.h" +#include "../sound/snd_dbopl.h" +#include "../video/video.h" +#include "../video/vid_voodoo.h" +#include "../gameport.h" +#include "../mouse.h" +#include "plat_midi.h" +#include "win.h" +#include "win_language.h" +#include "resource.h" + + +#define WM_SAVESETTINGS 0x8888 /* 86Box-specific message, used to tell the child dialog to save the currently specified settings. */ + + +/* Machine category */ +int temp_model, temp_cpu_m, temp_cpu, temp_wait_states, temp_mem_size, temp_dynarec, temp_fpu, temp_sync; + +/* Video category */ +int temp_gfxcard, temp_video_speed, temp_voodoo; + +/* Input devices category */ +int temp_mouse, temp_joystick; + +/* Sound category */ +int temp_sound_card, temp_midi_id, temp_SSI2001, temp_GAMEBLASTER, temp_GUS, temp_opl3_type; + +/* Network category */ +int temp_net_type, temp_net_card; +char temp_pcap_dev[520]; + +/* Peripherals category */ +int temp_scsi_card, hdc_ignore, temp_ide_ter, temp_ide_ter_irq, temp_ide_qua, temp_ide_qua_irq; +int temp_serial[2], temp_lpt, temp_bugger; + +char temp_hdc_name[16]; + +/* Hard disks category */ +hard_disk_t temp_hdc[HDC_NUM]; +wchar_t temp_hdd_fn[HDC_NUM][512]; + +/* Removable devices category */ +int temp_fdd_types[FDD_NUM]; +cdrom_drive_t temp_cdrom_drives[CDROM_NUM]; + +static HWND hwndParentDialog, hwndChildDialog; + +int hdd_controller_current; + +int displayed_category = 0; + +extern int is486; +static int romstolist[ROM_MAX], listtomodel[ROM_MAX], romstomodel[ROM_MAX], modeltolist[ROM_MAX]; +static int settings_sound_to_list[20], settings_list_to_sound[20]; +static int settings_mouse_to_list[20], settings_list_to_mouse[20]; +static int settings_scsi_to_list[20], settings_list_to_scsi[20]; +static int settings_network_to_list[20], settings_list_to_network[20]; +static char *hdd_names[16]; + + +/* This does the initial read of global variables into the temporary ones. */ +static void win_settings_init(void) +{ + int i = 0; + + /* Machine category */ + temp_model = model; + temp_cpu_m = cpu_manufacturer; + temp_cpu = cpu; + temp_mem_size = mem_size; + temp_dynarec = cpu_use_dynarec; + temp_fpu = enable_external_fpu; + temp_sync = enable_sync; + + /* Video category */ + temp_gfxcard = gfxcard; + temp_video_speed = video_speed; + temp_voodoo = voodoo_enabled; + + /* Input devices category */ + temp_mouse = mouse_type; + temp_joystick = joystick_type; + + /* Sound category */ + temp_sound_card = sound_card_current; + temp_midi_id = midi_id; + temp_SSI2001 = SSI2001; + temp_GAMEBLASTER = GAMEBLASTER; + temp_GUS = GUS; + temp_opl3_type = opl3_type; + + /* Network category */ + temp_net_type = network_type; + memset(temp_pcap_dev, '\0', sizeof(temp_pcap_dev)); + strcpy(temp_pcap_dev, network_pcap); + temp_net_card = network_card; + + /* Peripherals category */ + temp_scsi_card = scsi_card_current; + strncpy(temp_hdc_name, hdd_controller_name, sizeof(temp_hdc_name) - 1); + temp_ide_ter = ide_enable[2]; + temp_ide_ter_irq = ide_irq[2]; + temp_ide_qua = ide_enable[3]; + temp_ide_qua_irq = ide_irq[3]; + temp_serial[0] = serial_enabled[0]; + temp_serial[1] = serial_enabled[1]; + temp_lpt = lpt_enabled; + temp_bugger = bugger_enabled; + + /* Hard disks category */ + memcpy(temp_hdc, hdc, HDC_NUM * sizeof(hard_disk_t)); + for (i = 0; i < HDC_NUM; i++) + { + memcpy(temp_hdd_fn[i], hdd_fn[i], 1024); + } + + /* Removable devices category */ + for (i = 0; i < FDD_NUM; i++) + { + temp_fdd_types[i] = fdd_get_type(i); + } + memcpy(temp_cdrom_drives, cdrom_drives, CDROM_NUM * sizeof(cdrom_drive_t)); +} + + +/* This returns 1 if any variable has changed, 0 if not. */ +static int win_settings_changed(void) +{ + int i = 0; + int j = 0; + + /* Machine category */ + i = i || (model != temp_model); + i = i || (cpu_manufacturer != temp_cpu_m); + i = i || (cpu != temp_cpu); + i = i || (mem_size != temp_mem_size); + i = i || (temp_dynarec != cpu_use_dynarec); + i = i || (temp_fpu != enable_external_fpu); + i = i || (temp_sync != enable_sync); + + /* Video category */ + i = i || (gfxcard != temp_gfxcard); + i = i || (video_speed != temp_video_speed); + i = i || (voodoo_enabled != temp_voodoo); + + /* Input devices category */ + i = i || (mouse_type != temp_mouse); + i = i || (joystick_type != temp_joystick); + + /* Sound category */ + i = i || (sound_card_current != temp_sound_card); + i = i || (midi_id != temp_midi_id); + i = i || (SSI2001 != temp_SSI2001); + i = i || (GAMEBLASTER != temp_GAMEBLASTER); + i = i || (GUS != temp_GUS); + i = i || (opl3_type != temp_opl3_type); + + /* Network category */ + i = i || (network_type != temp_net_type); + i = i || strcmp(temp_pcap_dev, network_pcap); + i = i || (network_card != temp_net_card); + + /* Peripherals category */ + i = i || (scsi_card_current != temp_scsi_card); + i = i || strncmp(temp_hdc_name, hdd_controller_name, sizeof(temp_hdc_name) - 1); + i = i || (temp_ide_ter != ide_enable[2]); + i = i || (temp_ide_ter_irq != ide_irq[2]); + i = i || (temp_ide_qua != ide_enable[3]); + i = i || (temp_ide_qua_irq != ide_irq[3]); + i = i || (temp_serial[0] != serial_enabled[0]); + i = i || (temp_serial[1] != serial_enabled[1]); + i = i || (temp_lpt != lpt_enabled); + i = i || (temp_bugger != bugger_enabled); + + /* Hard disks category */ + i = i || memcmp(hdc, temp_hdc, HDC_NUM * sizeof(hard_disk_t)); + for (j = 0; j < HDC_NUM; j++) + { + i = i || memcmp(hdd_fn[j], temp_hdd_fn[j], 1024); + } + + /* Removable devices category */ + for (j = 0; j < FDD_NUM; j++) + { + i = i || (temp_fdd_types[j] != fdd_get_type(j)); + } + i = i || memcmp(cdrom_drives, temp_cdrom_drives, CDROM_NUM * sizeof(cdrom_drive_t)); + + return i; +} + + +static int settings_msgbox_reset(void) +{ + int i = 0; + int changed = 0; + + changed = win_settings_changed(); + + if (changed) + { + i = msgbox_reset(hwndParentDialog); + + if (i == IDNO) + { + return 1; + } + else if (i == IDCANCEL) + { + return 0; + } + else + { + return 2; + } + } + else +{ + return 1; + } +} + + +/* This saves the settings back to the global variables. */ +static void win_settings_save(void) +{ + int i = 0; + + /* Machine category */ + model = temp_model; + romset = model_getromset(); + cpu_manufacturer = temp_cpu_m; + cpu = temp_cpu; + mem_size = temp_mem_size; + cpu_use_dynarec = temp_dynarec; + enable_external_fpu = temp_fpu; + enable_sync = temp_sync; + + /* Video category */ + gfxcard = temp_gfxcard; + video_speed = temp_video_speed; + voodoo_enabled = temp_voodoo; + + /* Input devices category */ + mouse_type = temp_mouse; + joystick_type = temp_joystick; + + /* Sound category */ + sound_card_current = temp_sound_card; + midi_id = temp_midi_id; + SSI2001 = temp_SSI2001; + GAMEBLASTER = temp_GAMEBLASTER; + GUS = temp_GUS; + opl3_type = temp_opl3_type; + + /* Network category */ + network_type = temp_net_type; + memset(network_pcap, '\0', sizeof(network_pcap)); + strcpy(network_pcap, temp_pcap_dev); + network_card = temp_net_card; + + /* Peripherals category */ + scsi_card_current = temp_scsi_card; + strncpy(hdd_controller_name, temp_hdc_name, sizeof(temp_hdc_name) - 1); + ide_enable[2] = temp_ide_ter; + ide_irq[2] = temp_ide_ter_irq; + ide_enable[3] = temp_ide_qua; + ide_irq[3] = temp_ide_qua_irq; + serial_enabled[0] = temp_serial[0]; + serial_enabled[1] = temp_serial[1]; + lpt_enabled = temp_lpt; + bugger_enabled = temp_bugger; + + /* Hard disks category */ + memcpy(hdc, temp_hdc, HDC_NUM * sizeof(hard_disk_t)); + for (i = 0; i < HDC_NUM; i++) + { + memcpy(hdd_fn[i], temp_hdd_fn[i], 1024); + } + + /* Removable devices category */ + for (i = 0; i < FDD_NUM; i++) + { + fdd_set_type(i, temp_fdd_types[i]); + } + memcpy(cdrom_drives, temp_cdrom_drives, CDROM_NUM * sizeof(cdrom_drive_t)); + + mem_resize(); + loadbios(); + + resetpchard(); + + cpu_set(); + + cpu_update_waitstates(); + + saveconfig(); + + speedchanged(); + + if (joystick_type != 7) gameport_update_joystick_type(); + + update_status_bar_panes(hwndStatus); +} + + +static void win_settings_machine_recalc_cpu(HWND hdlg) +{ + HWND h; + int temp_romset = 0; + int cpu_flags; + int cpu_type; + + temp_romset = model_getromset_ex(temp_model); + + h = GetDlgItem(hdlg, IDC_COMBO_WS); + cpu_type = models[romstomodel[temp_romset]].cpu[temp_cpu_m].cpus[temp_cpu].cpu_type; + if ((cpu_type >= CPU_286) && (cpu_type <= CPU_386DX)) + { + EnableWindow(h, TRUE); + } + else + { + EnableWindow(h, FALSE); + } + + h=GetDlgItem(hdlg, IDC_CHECK_DYNAREC); + cpu_flags = models[romstomodel[temp_romset]].cpu[temp_cpu_m].cpus[temp_cpu].cpu_flags; + if (!(cpu_flags & CPU_SUPPORTS_DYNAREC) && (cpu_flags & CPU_REQUIRES_DYNAREC)) + { + fatal("Attempting to select a CPU that requires the recompiler and does not support it at the same time\n"); + } + if (!(cpu_flags & CPU_SUPPORTS_DYNAREC) || (cpu_flags & CPU_REQUIRES_DYNAREC)) + { + if (!(cpu_flags & CPU_SUPPORTS_DYNAREC)) + { + temp_dynarec = 0; + } + if (cpu_flags & CPU_REQUIRES_DYNAREC) + { + temp_dynarec = 1; + } + SendMessage(h, BM_SETCHECK, temp_dynarec, 0); + EnableWindow(h, FALSE); + } + else + { + EnableWindow(h, TRUE); + } + + h = GetDlgItem(hdlg, IDC_CHECK_FPU); + cpu_type = models[romstomodel[temp_romset]].cpu[temp_cpu_m].cpus[temp_cpu].cpu_type; + if ((cpu_type < CPU_i486DX) && (cpu_type >= CPU_286)) + { + EnableWindow(h, TRUE); + } + else if (cpu_type < CPU_286) + { + temp_fpu = 0; + EnableWindow(h, FALSE); + } + else + { + temp_fpu = 1; + EnableWindow(h, FALSE); + } + SendMessage(h, BM_SETCHECK, temp_fpu, 0); +} + + +static void win_settings_machine_recalc_cpu_m(HWND hdlg) +{ + HWND h; + int c = 0; + int temp_romset = 0; + LPTSTR lptsTemp; + char *stransi; + + temp_romset = model_getromset_ex(temp_model); + lptsTemp = (LPTSTR) malloc(512); + + h = GetDlgItem(hdlg, IDC_COMBO_CPU); + SendMessage(h, CB_RESETCONTENT, 0, 0); + c = 0; + while (models[romstomodel[temp_romset]].cpu[temp_cpu_m].cpus[c].cpu_type != -1) + { + stransi = models[romstomodel[temp_romset]].cpu[temp_cpu_m].cpus[c].name; + mbstowcs(lptsTemp, stransi, strlen(stransi) + 1); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)lptsTemp); + c++; + } + EnableWindow(h, TRUE); + SendMessage(h, CB_SETCURSEL, temp_cpu, 0); + + win_settings_machine_recalc_cpu(hdlg); + + free(lptsTemp); +} + + +static void win_settings_machine_recalc_model(HWND hdlg) +{ + HWND h; + int c = 0; + int temp_romset = 0; + LPTSTR lptsTemp; + char *stransi; + UDACCEL accel; + + temp_romset = model_getromset_ex(temp_model); + lptsTemp = (LPTSTR) malloc(512); + + h = GetDlgItem(hdlg, IDC_CONFIGURE_MACHINE); + if (model_getdevice(temp_model)) + { + EnableWindow(h, TRUE); + } + else + { + EnableWindow(h, FALSE); + } + + h = GetDlgItem(hdlg, IDC_COMBO_CPU_TYPE); + SendMessage(h, CB_RESETCONTENT, 0, 0); + c = 0; + while (models[romstomodel[temp_romset]].cpu[c].cpus != NULL && c < 4) + { + stransi = models[romstomodel[temp_romset]].cpu[c].name; + mbstowcs(lptsTemp, stransi, strlen(stransi) + 1); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)lptsTemp); + c++; + } + EnableWindow(h, TRUE); + SendMessage(h, CB_SETCURSEL, temp_cpu_m, 0); + if (c == 1) + { + EnableWindow(h, FALSE); + } + else + { + EnableWindow(h, TRUE); + } + + win_settings_machine_recalc_cpu_m(hdlg); + + h = GetDlgItem(hdlg, IDC_MEMSPIN); + SendMessage(h, UDM_SETRANGE, 0, (models[romstomodel[temp_romset]].min_ram << 16) | models[romstomodel[temp_romset]].max_ram); + accel.nSec = 0; + accel.nInc = models[romstomodel[temp_romset]].ram_granularity; + SendMessage(h, UDM_SETACCEL, 1, (LPARAM)&accel); + if (!(models[romstomodel[temp_romset]].flags & MODEL_AT)) + { + SendMessage(h, UDM_SETPOS, 0, temp_mem_size); + h = GetDlgItem(hdlg, IDC_TEXT_MB); + SendMessage(h, WM_SETTEXT, 0, (LPARAM) win_language_get_string_from_id(2094)); + } + else + { + SendMessage(h, UDM_SETPOS, 0, temp_mem_size / 1024); + h = GetDlgItem(hdlg, IDC_TEXT_MB); + SendMessage(h, WM_SETTEXT, 0, (LPARAM) win_language_get_string_from_id(2087)); + } + + free(lptsTemp); +} + + +static BOOL CALLBACK win_settings_machine_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + HWND h; + int c = 0; + int d = 0; + LPTSTR lptsTemp; + char *stransi; + + switch (message) + { + case WM_INITDIALOG: + lptsTemp = (LPTSTR) malloc(512); + + h = GetDlgItem(hdlg, IDC_COMBO_MACHINE); + for (c = 0; c < ROM_MAX; c++) + { + romstolist[c] = 0; + } + c = d = 0; + while (models[c].id != -1) + { + if (romspresent[models[c].id]) + { + stransi = models[c].name; + mbstowcs(lptsTemp, stransi, strlen(stransi) + 1); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + modeltolist[c] = d; + listtomodel[d] = c; + romstolist[models[c].id] = d; + romstomodel[models[c].id] = c; + d++; + } + c++; + } + SendMessage(h, CB_SETCURSEL, modeltolist[temp_model], 0); + + h = GetDlgItem(hdlg, IDC_COMBO_WS); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2131)); + + for (c = 0; c < 8; c++) + { + wsprintf(lptsTemp, win_language_get_string_from_id(2132), c); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + } + + SendMessage(h, CB_SETCURSEL, cpu_waitstates, 0); + + h=GetDlgItem(hdlg, IDC_CHECK_DYNAREC); + SendMessage(h, BM_SETCHECK, temp_dynarec, 0); + + h = GetDlgItem(hdlg, IDC_MEMSPIN); + SendMessage(h, UDM_SETBUDDY, (WPARAM)GetDlgItem(hdlg, IDC_MEMTEXT), 0); + + h=GetDlgItem(hdlg, IDC_CHECK_SYNC); + SendMessage(h, BM_SETCHECK, temp_sync, 0); + + win_settings_machine_recalc_model(hdlg); + + free(lptsTemp); + + return TRUE; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDC_COMBO_MACHINE: + if (HIWORD(wParam) == CBN_SELCHANGE) + { + h = GetDlgItem(hdlg, IDC_COMBO_MACHINE); + temp_model = listtomodel[SendMessage(h,CB_GETCURSEL,0,0)]; + + win_settings_machine_recalc_model(hdlg); + } + break; + case IDC_COMBO_CPU_TYPE: + if (HIWORD(wParam) == CBN_SELCHANGE) + { + h = GetDlgItem(hdlg, IDC_COMBO_CPU_TYPE); + temp_cpu_m = SendMessage(h, CB_GETCURSEL, 0, 0); + + temp_cpu = 0; + win_settings_machine_recalc_cpu_m(hdlg); + } + break; + case IDC_COMBO_CPU: + if (HIWORD(wParam) == CBN_SELCHANGE) + { + h = GetDlgItem(hdlg, IDC_COMBO_CPU); + temp_cpu = SendMessage(h, CB_GETCURSEL, 0, 0); + + win_settings_machine_recalc_cpu(hdlg); + } + break; + case IDC_CONFIGURE_MACHINE: + h = GetDlgItem(hdlg, IDC_COMBO_MACHINE); + temp_model = listtomodel[SendMessage(h, CB_GETCURSEL, 0, 0)]; + + deviceconfig_open(hdlg, (void *)model_getdevice(temp_model)); + break; + } + + return FALSE; + + case WM_SAVESETTINGS: + lptsTemp = (LPTSTR) malloc(512); + stransi = (char *) malloc(512); + + h=GetDlgItem(hdlg, IDC_CHECK_DYNAREC); + temp_dynarec = SendMessage(h, BM_GETCHECK, 0, 0); + + h=GetDlgItem(hdlg, IDC_CHECK_SYNC); + temp_sync = SendMessage(h, BM_GETCHECK, 0, 0); + + h=GetDlgItem(hdlg, IDC_CHECK_FPU); + temp_fpu = SendMessage(h, BM_GETCHECK, 0, 0); + + h = GetDlgItem(hdlg, IDC_COMBO_WS); + temp_wait_states = SendMessage(h, CB_GETCURSEL, 0, 0); + + h = GetDlgItem(hdlg, IDC_MEMTEXT); + SendMessage(h, WM_GETTEXT, 255, (LPARAM) lptsTemp); + wcstombs(stransi, lptsTemp, (wcslen(lptsTemp) * 2) + 2); + sscanf(stransi, "%i", &temp_mem_size); + temp_mem_size &= ~(models[temp_model].ram_granularity - 1); + if (temp_mem_size < models[temp_model].min_ram) + { + temp_mem_size = models[temp_model].min_ram; + } + else if (temp_mem_size > models[temp_model].max_ram) + { + temp_mem_size = models[temp_model].max_ram; + } + if (models[temp_model].flags & MODEL_AT) + { + temp_mem_size *= 1024; + } + + free(stransi); + free(lptsTemp); + + default: + return FALSE; + } + + return FALSE; +} + + +static void recalc_vid_list(HWND hdlg) +{ + HWND h = GetDlgItem(hdlg, IDC_COMBO_VIDEO); + int c = 0, d = 0; + int found_card = 0; + WCHAR szText[512]; + + SendMessage(h, CB_RESETCONTENT, 0, 0); + SendMessage(h, CB_SETCURSEL, 0, 0); + + while (1) + { + char *s = video_card_getname(c); + + if (!s[0]) + break; + + if (video_card_available(c) && gfx_present[video_new_to_old(c)] && + ((models[temp_model].flags & MODEL_PCI) || !(video_card_getdevice(c)->flags & DEVICE_PCI))) + { + mbstowcs(szText, s, strlen(s) + 1); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) szText); + if (video_new_to_old(c) == gfxcard) + { + + SendMessage(h, CB_SETCURSEL, d, 0); + found_card = 1; + } + + d++; + } + + c++; + } + if (!found_card) + SendMessage(h, CB_SETCURSEL, 0, 0); + EnableWindow(h, models[temp_model].fixed_gfxcard ? FALSE : TRUE); + + h = GetDlgItem(hdlg, IDC_CHECK_VOODOO); + EnableWindow(h, (models[model].flags & MODEL_PCI) ? TRUE : FALSE); + + h = GetDlgItem(hdlg, IDC_CONFIGURE_VOODOO); + EnableWindow(h, ((models[model].flags & MODEL_PCI) && temp_voodoo) ? TRUE : FALSE); +} + + +static BOOL CALLBACK win_settings_video_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + HWND h; + int c = 0; + int d = 0; + LPTSTR lptsTemp; + char *stransi; + char *s; + int gfx = 0; + + switch (message) + { + case WM_INITDIALOG: + lptsTemp = (LPTSTR) malloc(512); + stransi = (char *) malloc(512); + + recalc_vid_list(hdlg); + + h = GetDlgItem(hdlg, IDC_COMBO_VIDEO_SPEED); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2133)); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2134)); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2135)); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2136)); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2137)); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2138)); + SendMessage(h, CB_SETCURSEL, temp_video_speed, 0); + + h=GetDlgItem(hdlg, IDC_CHECK_VOODOO); + SendMessage(h, BM_SETCHECK, temp_voodoo, 0); + + h = GetDlgItem(hdlg, IDC_COMBO_VIDEO); + SendMessage(h, CB_GETLBTEXT, SendMessage(h, CB_GETCURSEL, 0, 0), (LPARAM) lptsTemp); + wcstombs(stransi, lptsTemp, (wcslen(lptsTemp) * 2) + 2); + gfx = video_card_getid(stransi); + + h = GetDlgItem(hdlg, IDC_CONFIGUREVID); + if (video_card_has_config(gfx)) + { + EnableWindow(h, TRUE); + } + else + { + EnableWindow(h, FALSE); + } + + free(stransi); + free(lptsTemp); + + return TRUE; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDC_COMBO_VIDEO: + lptsTemp = (LPTSTR) malloc(512); + stransi = (char *) malloc(512); + + h = GetDlgItem(hdlg, IDC_COMBO_VIDEO); + SendMessage(h, CB_GETLBTEXT, SendMessage(h, CB_GETCURSEL, 0, 0), (LPARAM) lptsTemp); + wcstombs(stransi, lptsTemp, (wcslen(lptsTemp) * 2) + 2); + gfx = video_card_getid(stransi); + temp_gfxcard = video_new_to_old(gfx); + + h = GetDlgItem(hdlg, IDC_CONFIGUREVID); + if (video_card_has_config(gfx)) + { + EnableWindow(h, TRUE); + } + else + { + EnableWindow(h, FALSE); + } + + free(stransi); + free(lptsTemp); + break; + + case IDC_CHECK_VOODOO: + h = GetDlgItem(hdlg, IDC_CHECK_VOODOO); + temp_voodoo = SendMessage(h, BM_GETCHECK, 0, 0); + + h = GetDlgItem(hdlg, IDC_CONFIGURE_VOODOO); + EnableWindow(h, temp_voodoo ? TRUE : FALSE); + break; + + case IDC_CONFIGURE_VOODOO: + deviceconfig_open(hdlg, (void *)&voodoo_device); + break; + + case IDC_CONFIGUREVID: + lptsTemp = (LPTSTR) malloc(512); + stransi = (char *) malloc(512); + + h = GetDlgItem(hdlg, IDC_COMBO_VIDEO); + SendMessage(h, CB_GETLBTEXT, SendMessage(h, CB_GETCURSEL, 0, 0), (LPARAM) lptsTemp); + wcstombs(stransi, lptsTemp, (wcslen(lptsTemp) * 2) + 2); + deviceconfig_open(hdlg, (void *)video_card_getdevice(video_card_getid(stransi))); + + free(stransi); + free(lptsTemp); + break; + } + return FALSE; + + case WM_SAVESETTINGS: + lptsTemp = (LPTSTR) malloc(512); + stransi = (char *) malloc(512); + + h = GetDlgItem(hdlg, IDC_COMBO_VIDEO); + SendMessage(h, CB_GETLBTEXT, SendMessage(h, CB_GETCURSEL, 0, 0), (LPARAM) lptsTemp); + wcstombs(stransi, lptsTemp, (wcslen(lptsTemp) * 2) + 2); + temp_gfxcard = video_new_to_old(video_card_getid(stransi)); + + h = GetDlgItem(hdlg, IDC_COMBO_VIDEO_SPEED); + temp_video_speed = SendMessage(h, CB_GETCURSEL, 0, 0); + + h = GetDlgItem(hdlg, IDC_CHECK_VOODOO); + temp_voodoo = SendMessage(h, BM_GETCHECK, 0, 0); + + free(stransi); + free(lptsTemp); + + default: + return FALSE; + } + return FALSE; +} + + +static int mouse_valid(int type, int model) +{ + type &= MOUSE_TYPE_MASK; + + if ((type == MOUSE_TYPE_PS2) && + !(models[model].flags & MODEL_PS2)) return(0); + + if ((type == MOUSE_TYPE_AMSTRAD) && + !(models[model].flags & MODEL_AMSTRAD)) return(0); + + if ((type == MOUSE_TYPE_OLIM24) && + !(models[model].flags & MODEL_OLIM24)) return(0); + + return(1); +} + + +static BOOL CALLBACK win_settings_input_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + HWND h; + int c = 0; + int d = 0; + int type; + int str_id = 0; + + switch (message) + { + case WM_INITDIALOG: + h = GetDlgItem(hdlg, IDC_COMBO_MOUSE); + c = d = 0; + for (c = 0; c < mouse_get_ndev(); c++) + { + type = mouse_get_type(c); + + settings_mouse_to_list[c] = d; + + if (mouse_valid(type, temp_model)) + { + switch(c) + { + case 0: /* MS Serial */ + default: + str_id = 2139; + break; + case 1: /* PS2 2b */ + str_id = 2141; + break; + case 2: /* PS2 intelli 3b */ + str_id = 2142; + break; + case 3: /* MS/logi bus 2b */ + str_id = 2143; + break; + case 4: /* Amstrad */ + str_id = 2162; + break; + case 5: /* Olivetti M24 */ + str_id = 2177; + break; + case 6: /* MouseSystems */ + str_id = 2140; + break; + case 7: /* Genius Bus */ + str_id = 2161; + break; + } + + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(str_id)); + + settings_list_to_mouse[d] = c; + d++; + } + } + + SendMessage(h, CB_SETCURSEL, settings_mouse_to_list[temp_mouse], 0); + + h = GetDlgItem(hdlg, IDC_COMBO_JOYSTICK); + c = 0; + while (joystick_get_name(c)) + { + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2144 + c)); + c++; + } + EnableWindow(h, TRUE); + SendMessage(h, CB_SETCURSEL, temp_joystick, 0); + + h = GetDlgItem(hdlg, IDC_JOY1); + EnableWindow(h, (joystick_get_max_joysticks(temp_joystick) >= 1) ? TRUE : FALSE); + h = GetDlgItem(hdlg, IDC_JOY2); + EnableWindow(h, (joystick_get_max_joysticks(temp_joystick) >= 2) ? TRUE : FALSE); + h = GetDlgItem(hdlg, IDC_JOY3); + EnableWindow(h, (joystick_get_max_joysticks(temp_joystick) >= 3) ? TRUE : FALSE); + h = GetDlgItem(hdlg, IDC_JOY4); + EnableWindow(h, (joystick_get_max_joysticks(temp_joystick) >= 4) ? TRUE : FALSE); + + return TRUE; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDC_COMBO_JOYSTICK: + if (HIWORD(wParam) == CBN_SELCHANGE) + { + h = GetDlgItem(hdlg, IDC_COMBO_JOYSTICK); + temp_joystick = SendMessage(h, CB_GETCURSEL, 0, 0); + + h = GetDlgItem(hdlg, IDC_JOY1); + EnableWindow(h, (joystick_get_max_joysticks(temp_joystick) >= 1) ? TRUE : FALSE); + h = GetDlgItem(hdlg, IDC_JOY2); + EnableWindow(h, (joystick_get_max_joysticks(temp_joystick) >= 2) ? TRUE : FALSE); + h = GetDlgItem(hdlg, IDC_JOY3); + EnableWindow(h, (joystick_get_max_joysticks(temp_joystick) >= 3) ? TRUE : FALSE); + h = GetDlgItem(hdlg, IDC_JOY4); + EnableWindow(h, (joystick_get_max_joysticks(temp_joystick) >= 4) ? TRUE : FALSE); + } + break; + + case IDC_JOY1: + h = GetDlgItem(hdlg, IDC_COMBOJOY); + temp_joystick = SendMessage(h, CB_GETCURSEL, 0, 0); + joystickconfig_open(hdlg, 0, temp_joystick); + break; + + case IDC_JOY2: + h = GetDlgItem(hdlg, IDC_COMBOJOY); + temp_joystick = SendMessage(h, CB_GETCURSEL, 0, 0); + joystickconfig_open(hdlg, 1, temp_joystick); + break; + + case IDC_JOY3: + h = GetDlgItem(hdlg, IDC_COMBOJOY); + temp_joystick = SendMessage(h, CB_GETCURSEL, 0, 0); + joystickconfig_open(hdlg, 2, temp_joystick); + break; + + case IDC_JOY4: + h = GetDlgItem(hdlg, IDC_COMBOJOY); + temp_joystick = SendMessage(h, CB_GETCURSEL, 0, 0); + joystickconfig_open(hdlg, 3, temp_joystick); + break; + } + return FALSE; + + case WM_SAVESETTINGS: + h = GetDlgItem(hdlg, IDC_COMBO_MOUSE); + temp_mouse = settings_list_to_mouse[SendMessage(h, CB_GETCURSEL, 0, 0)]; + + h = GetDlgItem(hdlg, IDC_COMBO_JOYSTICK); + temp_joystick = SendMessage(h, CB_GETCURSEL, 0, 0); + + default: + return FALSE; + } + return FALSE; +} + + +static void recalc_hdd_list(HWND hdlg, int model, int use_selected_hdd) +{ + HWND h; + + char *s; + int valid = 0; + char old_name[16]; + int c, d; + + LPTSTR lptsTemp; + + lptsTemp = (LPTSTR) malloc(512); + + h = GetDlgItem(hdlg, IDC_COMBO_HDC); + + if (models[model].flags & MODEL_HAS_IDE) + { + hdc_ignore = 1; + + SendMessage(h, CB_RESETCONTENT, 0, 0); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2154)); + EnableWindow(h, FALSE); + SendMessage(h, CB_SETCURSEL, 0, 0); + } + else + { + hdc_ignore = 0; + + valid = 0; + + if (use_selected_hdd) + { + c = SendMessage(h, CB_GETCURSEL, 0, 0); + + if (c != -1 && hdd_names[c]) + { + strncpy(old_name, hdd_names[c], sizeof(old_name) - 1); + } + else + { + strcpy(old_name, "none"); + } + } + else + { + strncpy(old_name, temp_hdc_name, sizeof(old_name) - 1); + } + + SendMessage(h, CB_RESETCONTENT, 0, 0); + c = d = 0; + while (1) + { + s = hdd_controller_get_name(c); + if (s[0] == 0) + { + break; + } + if ((hdd_controller_get_flags(c) & DEVICE_AT) && !(models[model].flags & MODEL_AT)) + { + c++; + continue; + } + if ((hdd_controller_get_flags(c) & DEVICE_PS2) && !(models[model].flags & MODEL_PS2_HDD)) + { + c++; + continue; + } + if ((hdd_controller_get_flags(c) & DEVICE_MCA) && !(models[model].flags & MODEL_MCA)) + { + c++; + continue; + } + if (!hdd_controller_available(c)) + { + c++; + continue; + } + if (c < 2) + { + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2152 + c)); + } + else + { + mbstowcs(lptsTemp, s, strlen(s) + 1); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + } + hdd_names[d] = hdd_controller_get_internal_name(c); + if (!strcmp(old_name, hdd_names[d])) + { + SendMessage(h, CB_SETCURSEL, d, 0); + valid = 1; + } + c++; + d++; + } + + if (!valid) + { + SendMessage(h, CB_SETCURSEL, 0, 0); + } + + EnableWindow(h, TRUE); + } + + free(lptsTemp); +} + + +int valid_ide_irqs[11] = { 2, 3, 4, 5, 7, 9, 10, 11, 12, 14, 15 }; + + +int find_irq_in_array(int irq, int def) +{ + int i = 0; + + for (i = 0; i < 11; i++) + { + if (valid_ide_irqs[i] == irq) + { + return i + 1; + } + } + + return 7 + def; +} + + +static char midi_dev_name_buf[512]; + +static BOOL CALLBACK win_settings_sound_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + HWND h; + int c = 0; + int d = 0; + LPTSTR lptsTemp; + device_t *sound_dev; + int num = 0; + + switch (message) + { + case WM_INITDIALOG: + lptsTemp = (LPTSTR) malloc(512); + + h = GetDlgItem(hdlg, IDC_COMBOSND); + c = d = 0; + while (1) + { + char *s = sound_card_getname(c); + + if (!s[0]) + { + break; + } + + settings_sound_to_list[c] = d; + + if (sound_card_available(c)) + { + sound_dev = sound_card_getdevice(c); + + if (!sound_dev || (sound_dev->flags & DEVICE_MCA) == (models[temp_model].flags & MODEL_MCA)) + { + if (c == 0) + { + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2152)); + } + else + { + mbstowcs(lptsTemp, s, strlen(s) + 1); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + } + settings_list_to_sound[d] = c; + d++; + } + } + + c++; + } + SendMessage(h, CB_SETCURSEL, settings_sound_to_list[temp_sound_card], 0); + + h = GetDlgItem(hdlg, IDC_CONFIGURESND); + if (sound_card_has_config(temp_sound_card)) + { + EnableWindow(h, TRUE); + } + else + { + EnableWindow(h, FALSE); + } + + h = GetDlgItem(hdlg, IDC_COMBO_MIDI); + num = midi_get_num_devs(); + for (c = 0; c < num; c++) + { + memset(midi_dev_name_buf, 0, 512); + midi_get_dev_name(c, midi_dev_name_buf); + mbstowcs(lptsTemp, midi_dev_name_buf, strlen(midi_dev_name_buf) + 1); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + if (c == temp_midi_id) + SendMessage(h, CB_SETCURSEL, c, 0); + } + + h=GetDlgItem(hdlg, IDC_CHECKCMS); + SendMessage(h, BM_SETCHECK, temp_GAMEBLASTER, 0); + + h=GetDlgItem(hdlg, IDC_CHECKGUS); + SendMessage(h, BM_SETCHECK, temp_GUS, 0); + + h=GetDlgItem(hdlg, IDC_CHECKSSI); + SendMessage(h, BM_SETCHECK, temp_SSI2001, 0); + + h=GetDlgItem(hdlg, IDC_CHECKNUKEDOPL); + SendMessage(h, BM_SETCHECK, temp_opl3_type, 0); + + free(lptsTemp); + + return TRUE; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDC_CONFIGURESND: + h = GetDlgItem(hdlg, IDC_COMBOSND); + temp_sound_card = settings_list_to_sound[SendMessage(h, CB_GETCURSEL, 0, 0)]; + + deviceconfig_open(hdlg, (void *)sound_card_getdevice(temp_sound_card)); + break; + + case IDC_COMBOSND: + h = GetDlgItem(hdlg, IDC_COMBOSND); + temp_sound_card = settings_list_to_sound[SendMessage(h, CB_GETCURSEL, 0, 0)]; + + h = GetDlgItem(hdlg, IDC_CONFIGURESND); + if (sound_card_has_config(temp_sound_card)) + { + EnableWindow(h, TRUE); + } + else + { + EnableWindow(h, FALSE); + } + break; + } + return FALSE; + + case WM_SAVESETTINGS: + h = GetDlgItem(hdlg, IDC_COMBOSND); + temp_sound_card = settings_list_to_sound[SendMessage(h, CB_GETCURSEL, 0, 0)]; + + h = GetDlgItem(hdlg, IDC_COMBO_MIDI); + temp_midi_id = SendMessage(h, CB_GETCURSEL, 0, 0); + + h = GetDlgItem(hdlg, IDC_CHECKCMS); + temp_GAMEBLASTER = SendMessage(h, BM_GETCHECK, 0, 0); + + h = GetDlgItem(hdlg, IDC_CHECKGUS); + temp_GUS = SendMessage(h, BM_GETCHECK, 0, 0); + + h = GetDlgItem(hdlg, IDC_CHECKSSI); + temp_SSI2001 = SendMessage(h, BM_GETCHECK, 0, 0); + + h = GetDlgItem(hdlg, IDC_CHECKNUKEDOPL); + temp_opl3_type = SendMessage(h, BM_GETCHECK, 0, 0); + + default: + return FALSE; + } + return FALSE; +} + + +static BOOL CALLBACK win_settings_peripherals_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + HWND h; + int c = 0; + int d = 0; + LPTSTR lptsTemp; + device_t *scsi_dev; + + switch (message) + { + case WM_INITDIALOG: + lptsTemp = (LPTSTR) malloc(512); + + /*SCSI config*/ + h = GetDlgItem(hdlg, IDC_COMBO_SCSI); + c = d = 0; + while (1) + { + char *s = scsi_card_getname(c); + + if (!s[0]) + { + break; + } + + settings_scsi_to_list[c] = d; + + if (scsi_card_available(c)) + { + scsi_dev = scsi_card_getdevice(c); + + if (!scsi_dev || (scsi_dev->flags & DEVICE_MCA) == (models[temp_model].flags & MODEL_MCA)) + { + if (c == 0) + { + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2152)); + } + else + { + mbstowcs(lptsTemp, s, strlen(s) + 1); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + } + settings_list_to_scsi[d] = c; + d++; + } + } + + c++; + } + SendMessage(h, CB_SETCURSEL, settings_scsi_to_list[temp_scsi_card], 0); + + h = GetDlgItem(hdlg, IDC_CONFIGURE_SCSI); + if (scsi_card_has_config(temp_scsi_card)) + { + EnableWindow(h, TRUE); + } + else + { + EnableWindow(h, FALSE); + } + + recalc_hdd_list(hdlg, temp_model, 0); + + h=GetDlgItem(hdlg, IDC_COMBO_IDE_TER); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2151)); + + for (c = 0; c < 11; c++) + { + wsprintf(lptsTemp, win_language_get_string_from_id(2155), valid_ide_irqs[c]); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + } + + if (temp_ide_ter) + { + SendMessage(h, CB_SETCURSEL, find_irq_in_array(temp_ide_ter_irq, 0), 0); + } + else + { + SendMessage(h, CB_SETCURSEL, 0, 0); + } + + h=GetDlgItem(hdlg, IDC_COMBO_IDE_QUA); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2151)); + + for (c = 0; c < 11; c++) + { + wsprintf(lptsTemp, win_language_get_string_from_id(2155), valid_ide_irqs[c]); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + } + + if (temp_ide_qua) + { + SendMessage(h, CB_SETCURSEL, find_irq_in_array(temp_ide_qua_irq, 1), 0); + } + else + { + SendMessage(h, CB_SETCURSEL, 0, 0); + } + + h=GetDlgItem(hdlg, IDC_CHECKSERIAL1); + SendMessage(h, BM_SETCHECK, temp_serial[0], 0); + + h=GetDlgItem(hdlg, IDC_CHECKSERIAL2); + SendMessage(h, BM_SETCHECK, temp_serial[1], 0); + + h=GetDlgItem(hdlg, IDC_CHECKPARALLEL); + SendMessage(h, BM_SETCHECK, temp_lpt, 0); + + h=GetDlgItem(hdlg, IDC_CHECKBUGGER); + SendMessage(h, BM_SETCHECK, temp_bugger, 0); + + free(lptsTemp); + + return TRUE; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDC_CONFIGURE_SCSI: + h = GetDlgItem(hdlg, IDC_COMBO_SCSI); + temp_scsi_card = settings_list_to_scsi[SendMessage(h, CB_GETCURSEL, 0, 0)]; + + deviceconfig_open(hdlg, (void *)scsi_card_getdevice(temp_scsi_card)); + break; + + case IDC_COMBO_SCSI: + h = GetDlgItem(hdlg, IDC_COMBO_SCSI); + temp_scsi_card = settings_list_to_scsi[SendMessage(h, CB_GETCURSEL, 0, 0)]; + + h = GetDlgItem(hdlg, IDC_CONFIGURE_SCSI); + if (scsi_card_has_config(temp_scsi_card)) + { + EnableWindow(h, TRUE); + } + else + { + EnableWindow(h, FALSE); + } + break; + } + return FALSE; + + case WM_SAVESETTINGS: + if (hdc_ignore == 0) + { + h = GetDlgItem(hdlg, IDC_COMBO_HDC); + c = SendMessage(h, CB_GETCURSEL, 0, 0); + if (hdd_names[c]) + { + strncpy(temp_hdc_name, hdd_names[c], sizeof(temp_hdc_name) - 1); + } + else + { + strcpy(temp_hdc_name, "none"); + } + } + else + { + strcpy(temp_hdc_name, "none"); + } + + h = GetDlgItem(hdlg, IDC_COMBO_SCSI); + temp_scsi_card = settings_list_to_scsi[SendMessage(h, CB_GETCURSEL, 0, 0)]; + + h = GetDlgItem(hdlg, IDC_COMBO_IDE_TER); + temp_ide_ter = SendMessage(h, CB_GETCURSEL, 0, 0); + if (temp_ide_ter > 1) + { + temp_ide_ter_irq = valid_ide_irqs[temp_ide_ter - 1]; + temp_ide_ter = 1; + } + + h = GetDlgItem(hdlg, IDC_COMBO_IDE_QUA); + temp_ide_qua = SendMessage(h, CB_GETCURSEL, 0, 0); + if (temp_ide_qua > 1) + { + temp_ide_qua_irq = valid_ide_irqs[temp_ide_qua - 1]; + temp_ide_qua = 1; + } + + h = GetDlgItem(hdlg, IDC_CHECKSERIAL1); + temp_serial[0] = SendMessage(h, BM_GETCHECK, 0, 0); + + h = GetDlgItem(hdlg, IDC_CHECKSERIAL2); + temp_serial[1] = SendMessage(h, BM_GETCHECK, 0, 0); + + h = GetDlgItem(hdlg, IDC_CHECKPARALLEL); + temp_lpt = SendMessage(h, BM_GETCHECK, 0, 0); + + h = GetDlgItem(hdlg, IDC_CHECKBUGGER); + temp_bugger = SendMessage(h, BM_GETCHECK, 0, 0); + + default: + return FALSE; + } + return FALSE; +} + + +int net_ignore_message = 0; + +static void network_recalc_combos(HWND hdlg) +{ + HWND h; + + net_ignore_message = 1; + + h = GetDlgItem(hdlg, IDC_COMBOPCAP); + if (temp_net_type == NET_TYPE_PCAP) + { + EnableWindow(h, TRUE); + } + else + { + EnableWindow(h, FALSE); + } + + h = GetDlgItem(hdlg, IDC_COMBONET); + if (temp_net_type == NET_TYPE_SLIRP) + { + EnableWindow(h, TRUE); + } + else if ((temp_net_type == NET_TYPE_PCAP) && + (network_dev_to_id(temp_pcap_dev) > 0)) + { + EnableWindow(h, TRUE); + } + else + { + EnableWindow(h, FALSE); + } + + h = GetDlgItem(hdlg, IDC_CONFIGURENET); + if (network_card_has_config(temp_net_card) && + (temp_net_type == NET_TYPE_SLIRP)) + { + EnableWindow(h, TRUE); + } + else if (network_card_has_config(temp_net_card) && + (temp_net_type == NET_TYPE_PCAP) && + (network_dev_to_id(temp_pcap_dev) > 0)) + { + EnableWindow(h, TRUE); + } + else + { + EnableWindow(h, FALSE); + } + + net_ignore_message = 0; +} + +static BOOL CALLBACK win_settings_network_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + HWND h; + int c = 0; + int d = 0; + LPTSTR lptsTemp; + device_t *scsi_dev; + + switch (message) + { + case WM_INITDIALOG: + lptsTemp = (LPTSTR) malloc(512); + + h = GetDlgItem(hdlg, IDC_COMBONETTYPE); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) L"None"); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) L"PCap"); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) L"SLiRP"); + SendMessage(h, CB_SETCURSEL, temp_net_type, 0); + + h = GetDlgItem(hdlg, IDC_COMBOPCAP); + if (temp_net_type == NET_TYPE_PCAP) + { + EnableWindow(h, TRUE); + } + else + { + EnableWindow(h, FALSE); + } + + h = GetDlgItem(hdlg, IDC_COMBOPCAP); + for (c = 0; c < network_ndev; c++) + { + mbstowcs(lptsTemp, network_devs[c].description, strlen(network_devs[c].description) + 1); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + } + SendMessage(h, CB_SETCURSEL, network_dev_to_id(temp_pcap_dev), 0); + + /*NIC config*/ + h = GetDlgItem(hdlg, IDC_COMBONET); + c = d = 0; + while (1) + { + char *s = network_card_getname(c); + + if (s[0] == '\0') + { + break; + } + + settings_network_to_list[c] = d; + + if (network_card_available(c)) + { + if (c == 0) + { + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2152)); + } + else + { + mbstowcs(lptsTemp, s, strlen(s) + 1); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + } + settings_list_to_network[d] = c; + d++; + } + + c++; + } + SendMessage(h, CB_SETCURSEL, settings_network_to_list[temp_net_card], 0); + + network_recalc_combos(hdlg); + + free(lptsTemp); + + return TRUE; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDC_COMBONETTYPE: + if (net_ignore_message) + { + return FALSE; + } + + h = GetDlgItem(hdlg, IDC_COMBONETTYPE); + temp_net_type = SendMessage(h, CB_GETCURSEL, 0, 0); + + network_recalc_combos(hdlg); + break; + + case IDC_COMBOPCAP: + if (net_ignore_message) + { + return FALSE; + } + + h = GetDlgItem(hdlg, IDC_COMBOPCAP); + memset(temp_pcap_dev, '\0', sizeof(temp_pcap_dev)); + strcpy(temp_pcap_dev, network_devs[SendMessage(h, CB_GETCURSEL, 0, 0)].device); + + network_recalc_combos(hdlg); + break; + + case IDC_COMBONET: + if (net_ignore_message) + { + return FALSE; + } + + h = GetDlgItem(hdlg, IDC_COMBONET); + temp_net_card = settings_list_to_network[SendMessage(h, CB_GETCURSEL, 0, 0)]; + + network_recalc_combos(hdlg); + break; + + case IDC_CONFIGURENET: + if (net_ignore_message) + { + return FALSE; + } + + h = GetDlgItem(hdlg, IDC_COMBONET); + temp_net_card = settings_list_to_network[SendMessage(h, CB_GETCURSEL, 0, 0)]; + + deviceconfig_open(hdlg, (void *)network_card_getdevice(temp_net_card)); + break; + } + return FALSE; + + case WM_SAVESETTINGS: + h = GetDlgItem(hdlg, IDC_COMBONETTYPE); + temp_net_type = SendMessage(h, CB_GETCURSEL, 0, 0); + + h = GetDlgItem(hdlg, IDC_COMBOPCAP); + memset(temp_pcap_dev, '\0', sizeof(temp_pcap_dev)); + strcpy(temp_pcap_dev, network_devs[SendMessage(h, CB_GETCURSEL, 0, 0)].device); + + h = GetDlgItem(hdlg, IDC_COMBONET); + temp_net_card = settings_list_to_network[SendMessage(h, CB_GETCURSEL, 0, 0)]; + + default: + return FALSE; + } + + return FALSE; +} + +static BOOL win_settings_hard_disks_image_list_init(HWND hwndList) +{ + HICON hiconItem; + HIMAGELIST hSmall; + + int i = 0; + + hSmall = ImageList_Create(GetSystemMetrics(SM_CXSMICON), + GetSystemMetrics(SM_CYSMICON), + ILC_MASK | ILC_COLOR32, 1, 1); + + for (i = 0; i < 8; i += 2) + { + hiconItem = LoadIcon(hinstance, (LPCWSTR) (176 + i)); + ImageList_AddIcon(hSmall, hiconItem); + DestroyIcon(hiconItem); + } + + ListView_SetImageList(hwndList, hSmall, LVSIL_SMALL); + + return TRUE; +} + +int next_free_id = 0; + +wchar_t ifn[HDC_NUM][512]; + +static void normalize_hd_list() +{ + hard_disk_t ihdc[HDC_NUM]; + int i, j; + + j = 0; + memset(ihdc, 0, HDC_NUM * sizeof(hard_disk_t)); + for (i = 0; i < HDC_NUM; i++) + { + memset(ifn[i], 0, 1024); + } + for (i = 0; i < HDC_NUM; i++) + { + if (temp_hdc[i].bus > 0) + { + memcpy(&(ihdc[j]), &(temp_hdc[i]), sizeof(hard_disk_t)); + memcpy(ifn[j], temp_hdd_fn[i], 1024); + j++; + } + } + + memcpy(temp_hdc, ihdc, HDC_NUM * sizeof(hard_disk_t)); + for (i = 0; i < HDC_NUM; i++) + { + memcpy(temp_hdd_fn[i], ifn[i], 1024); + } +} + +int hdc_id_to_listview_index[HDC_NUM]; +int hd_listview_items; + +hard_disk_t new_hdc; +int hdlv_current_sel; + +static int get_selected_hard_disk(HWND hdlg) +{ + int hard_disk = -1; + int i, j = 0; + HWND h; + + for (i = 0; i < 6; i++) + { + h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); + j = ListView_GetItemState(h, i, LVIS_SELECTED); + if (j) + { + hard_disk = i; + } + } + + return hard_disk; +} + +static void add_locations(HWND hdlg) +{ + LPTSTR lptsTemp; + HWND h; + int i = 0; + + lptsTemp = (LPTSTR) malloc(512); + + h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); + for (i = 0; i < 4; i++) + { + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2165 + i)); + } + + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); + for (i = 0; i < 8; i++) + { + wsprintf(lptsTemp, win_language_get_string_from_id(2169), i >> 1, i & 1); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + } + + h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); + for (i = 0; i < 16; i++) + { + wsprintf(lptsTemp, win_language_get_string_from_id(2088), i); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + } + + h = GetDlgItem(hdlg, IDC_COMBO_HD_LUN); + for (i = 0; i < 8; i++) + { + wsprintf(lptsTemp, win_language_get_string_from_id(2088), i); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + } + + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); + for (i = 0; i < 8; i++) + { + wsprintf(lptsTemp, win_language_get_string_from_id(2169), i >> 1, i & 1); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + } + + free(lptsTemp); +} + +static void recalc_location_controls(HWND hdlg, int is_add_dlg) +{ + int i = 0; + HWND h; + + int bus = 0; + + for (i = 1799; i < 1803; i++) + { + h = GetDlgItem(hdlg, i); + EnableWindow(h, FALSE); + ShowWindow(h, SW_HIDE); + } + + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); + EnableWindow(h, FALSE); + ShowWindow(h, SW_HIDE); + + h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); + EnableWindow(h, FALSE); + ShowWindow(h, SW_HIDE); + + h = GetDlgItem(hdlg, IDC_COMBO_HD_LUN); + EnableWindow(h, FALSE); + ShowWindow(h, SW_HIDE); + + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); + EnableWindow(h, FALSE); + ShowWindow(h, SW_HIDE); + + if ((hd_listview_items > 0) || is_add_dlg) + { + h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); + bus = SendMessage(h, CB_GETCURSEL, 0, 0); + + switch(bus) + { + case 0: /* MFM/RLL */ + h = GetDlgItem(hdlg, 1799); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdc.mfm_channel : temp_hdc[hdlv_current_sel].mfm_channel, 0); + break; + case 1: /* IDE (PIO-only) */ + case 2: /* IDE (PIO and DMA) */ + h = GetDlgItem(hdlg, 1802); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdc.ide_channel : temp_hdc[hdlv_current_sel].ide_channel, 0); + break; + case 3: /* SCSI */ + h = GetDlgItem(hdlg, 1800); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + h = GetDlgItem(hdlg, 1801); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + + h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdc.scsi_id : temp_hdc[hdlv_current_sel].scsi_id, 0); + + h = GetDlgItem(hdlg, IDC_COMBO_HD_LUN); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdc.scsi_lun : temp_hdc[hdlv_current_sel].scsi_lun, 0); + break; + } + } + + if ((hd_listview_items == 0) && !is_add_dlg) + { + h = GetDlgItem(hdlg, 1798); + EnableWindow(h, FALSE); + ShowWindow(h, SW_HIDE); + + h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); + EnableWindow(h, FALSE); ShowWindow(h, SW_HIDE); + } + else + { + h = GetDlgItem(hdlg, 1798); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + + h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + } +} + +static void recalc_next_free_id(HWND hdlg) +{ + HWND h; + int i; + + int c_mfm = 0; + int c_ide_pio = 0; + int c_ide_dma = 0; + int c_scsi = 0; + int enable_add = 0; + + next_free_id = -1; + + for (i = 0; i < HDC_NUM; i++) + { + if (temp_hdc[i].bus == 1) + { + c_mfm++; + } + else if (temp_hdc[i].bus == 2) + { + c_ide_pio++; + } + else if (temp_hdc[i].bus == 3) + { + c_ide_dma++; + } + else if (temp_hdc[i].bus == 4) + { + c_scsi++; + } + } + + for (i = 0; i < HDC_NUM; i++) + { + if (temp_hdc[i].bus == 0) + { + next_free_id = i; + break; + } + } + + /* pclog("Next free ID: %i\n", next_free_id); */ + + enable_add = enable_add || (next_free_id >= 0); + /* pclog("Enable add: %i\n", enable_add); */ + enable_add = enable_add && ((c_mfm < MFM_NUM) || (c_ide_pio < IDE_NUM) || (c_ide_dma < IDE_NUM) || (c_scsi < SCSI_NUM)); + /* pclog("Enable add: %i\n", enable_add); */ + + h = GetDlgItem(hdlg, IDC_BUTTON_HDD_ADD_NEW); + + if (enable_add) + { + EnableWindow(h, TRUE); + } + else + { + EnableWindow(h, FALSE); + } + + h = GetDlgItem(hdlg, IDC_BUTTON_HDD_ADD); + + if (enable_add) + { + EnableWindow(h, TRUE); + } + else + { + EnableWindow(h, FALSE); + } + + h = GetDlgItem(hdlg, IDC_BUTTON_HDD_REMOVE); + + if ((c_mfm == 0) && (c_ide_pio == 0) && (c_ide_dma == 0) && (c_scsi == 0)) + { + EnableWindow(h, FALSE); + } + else + { + EnableWindow(h, TRUE); + } +} + +static void win_settings_hard_disks_update_item(HWND hwndList, int i, int column) +{ + LVITEM lvI; + WCHAR szText[256]; + + lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; + lvI.stateMask = lvI.iSubItem = lvI.state = 0; + + lvI.iSubItem = column; + lvI.iItem = i; + + if (column == 0) + { + switch(temp_hdc[i].bus) + { + case 1: + wsprintf(szText, win_language_get_string_from_id(2156), temp_hdc[i].mfm_channel >> 1, temp_hdc[i].mfm_channel & 1); + break; + case 2: + wsprintf(szText, win_language_get_string_from_id(2195), temp_hdc[i].ide_channel >> 1, temp_hdc[i].ide_channel & 1); + break; + case 3: + wsprintf(szText, win_language_get_string_from_id(2157), temp_hdc[i].ide_channel >> 1, temp_hdc[i].ide_channel & 1); + break; + case 4: + wsprintf(szText, win_language_get_string_from_id(2158), temp_hdc[i].scsi_id, temp_hdc[i].scsi_lun); + break; + } + lvI.pszText = szText; + lvI.iImage = temp_hdc[i].bus - 1; + } + else if (column == 1) + { + lvI.pszText = temp_hdd_fn[i]; + lvI.iImage = 0; + } + else if (column == 2) + { + wsprintf(szText, win_language_get_string_from_id(2088), temp_hdc[i].tracks); + lvI.pszText = szText; + lvI.iImage = 0; + } + else if (column == 3) + { + wsprintf(szText, win_language_get_string_from_id(2088), temp_hdc[i].hpc); + lvI.pszText = szText; + lvI.iImage = 0; + } + else if (column == 4) + { + wsprintf(szText, win_language_get_string_from_id(2088), temp_hdc[i].spt); + lvI.pszText = szText; + lvI.iImage = 0; + } + else if (column == 5) + { + wsprintf(szText, win_language_get_string_from_id(2088), (temp_hdc[i].tracks * temp_hdc[i].hpc * temp_hdc[i].spt) >> 11); + lvI.pszText = szText; + lvI.iImage = 0; + } + + if (ListView_SetItem(hwndList, &lvI) == -1) + { + return; + } +} + +static BOOL win_settings_hard_disks_recalc_list(HWND hwndList) +{ + LVITEM lvI; + int i = 0; + int j = 0; + WCHAR szText[256]; + + hd_listview_items = 0; + hdlv_current_sel = -1; + + ListView_DeleteAllItems(hwndList); + + lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; + lvI.stateMask = lvI.iSubItem = lvI.state = 0; + + for (i = 0; i < HDC_NUM; i++) + { + if (temp_hdc[i].bus > 0) + { + hdc_id_to_listview_index[i] = j; + lvI.iSubItem = 0; + switch(temp_hdc[i].bus) + { + case 1: + wsprintf(szText, win_language_get_string_from_id(2156), temp_hdc[i].mfm_channel >> 1, temp_hdc[i].mfm_channel & 1); + break; + case 2: + wsprintf(szText, win_language_get_string_from_id(2195), temp_hdc[i].ide_channel >> 1, temp_hdc[i].ide_channel & 1); + break; + case 3: + wsprintf(szText, win_language_get_string_from_id(2157), temp_hdc[i].ide_channel >> 1, temp_hdc[i].ide_channel & 1); + break; + case 4: + wsprintf(szText, win_language_get_string_from_id(2158), temp_hdc[i].scsi_id, temp_hdc[i].scsi_lun); + break; + } + lvI.pszText = szText; + lvI.iItem = j; + lvI.iImage = temp_hdc[i].bus - 1; + + if (ListView_InsertItem(hwndList, &lvI) == -1) + { + return FALSE; + } + + lvI.iSubItem = 1; + lvI.pszText = temp_hdd_fn[i]; + lvI.iItem = j; + lvI.iImage = 0; + + if (ListView_SetItem(hwndList, &lvI) == -1) + { + return FALSE; + } + + lvI.iSubItem = 2; + wsprintf(szText, win_language_get_string_from_id(2088), temp_hdc[i].tracks); + lvI.pszText = szText; + lvI.iItem = j; + lvI.iImage = 0; + + if (ListView_SetItem(hwndList, &lvI) == -1) + { + return FALSE; + } + + lvI.iSubItem = 3; + wsprintf(szText, win_language_get_string_from_id(2088), temp_hdc[i].hpc); + lvI.pszText = szText; + lvI.iItem = j; + lvI.iImage = 0; + + if (ListView_SetItem(hwndList, &lvI) == -1) + { + return FALSE; + } + + lvI.iSubItem = 4; + wsprintf(szText, win_language_get_string_from_id(2088), temp_hdc[i].spt); + lvI.pszText = szText; + lvI.iItem = j; + lvI.iImage = 0; + + if (ListView_SetItem(hwndList, &lvI) == -1) + { + return FALSE; + } + + lvI.iSubItem = 5; + wsprintf(szText, win_language_get_string_from_id(2088), (temp_hdc[i].tracks * temp_hdc[i].hpc * temp_hdc[i].spt) >> 11); + lvI.pszText = szText; + lvI.iItem = j; + lvI.iImage = 0; + + if (ListView_SetItem(hwndList, &lvI) == -1) + { + return FALSE; + } + + j++; + } + else + { + hdc_id_to_listview_index[i] = -1; + } + } + + hd_listview_items = j; + + return TRUE; +} + +/* Icon, Bus, File, C, H, S, Size */ +#define C_COLUMNS_HARD_DISKS 6 + +static BOOL win_settings_hard_disks_init_columns(HWND hwndList) +{ + LVCOLUMN lvc; + int iCol; + + lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; + + for (iCol = 0; iCol < C_COLUMNS_HARD_DISKS; iCol++) + { + lvc.iSubItem = iCol; + lvc.pszText = win_language_get_string_from_id(2082 + iCol); + + switch(iCol) + { + + case 0: /* Bus */ + lvc.cx = 135; + lvc.fmt = LVCFMT_LEFT; + break; + case 2: /* Cylinders */ + lvc.cx = 41; + lvc.fmt = LVCFMT_RIGHT; + break; + case 3: /* Heads */ + case 4: /* Sectors */ + lvc.cx = 25; + lvc.fmt = LVCFMT_RIGHT; + break; + case 1: /* File */ + lvc.cx = 150; + lvc.fmt = LVCFMT_LEFT; + break; + case 5: /* Size (MB) 8 */ + lvc.cx = 41; + lvc.fmt = LVCFMT_RIGHT; + break; + } + + if (ListView_InsertColumn(hwndList, iCol, &lvc) == -1) + { + return FALSE; + } + } + + return TRUE; +} + +static void get_edit_box_contents(HWND hdlg, int id, uint64_t *val) +{ + HWND h; + WCHAR szText[256]; + char stransi[256]; + + h = GetDlgItem(hdlg, id); + SendMessage(h, WM_GETTEXT, 255, (LPARAM) szText); + wcstombs(stransi, szText, (wcslen(szText) * 2) + 2); + sscanf(stransi, "%" PRIu64, val); +} + +static void get_combo_box_selection(HWND hdlg, int id, uint64_t *val) +{ + HWND h; + + h = GetDlgItem(hdlg, id); + *val = SendMessage(h, CB_GETCURSEL, 0, 0); +} + +static void set_edit_box_contents(HWND hdlg, int id, uint64_t val) +{ + HWND h; + WCHAR szText[256]; + + h = GetDlgItem(hdlg, id); + wsprintf(szText, win_language_get_string_from_id(2160), val); + SendMessage(h, WM_SETTEXT, (WPARAM) wcslen(szText), (LPARAM) szText); +} + +int hard_disk_added = 0; +int max_spt = 63; + +int no_update = 0; + +int existing = 0; +uint64_t selection = 127; + +uint64_t spt, hpc, tracks, size; +wchar_t hd_file_name[512]; + +static int hdconf_initialize_hdt_combo(HWND hdlg) +{ + HWND h; + int i = 0; + uint64_t temp_size = 0; + uint64_t size_mb = 0; + WCHAR szText[256]; + + selection = 127; + + h = GetDlgItem(hdlg, IDC_COMBO_HD_TYPE); + for (i = 0; i < 127; i++) + { + temp_size = hdt[i][0] * hdt[i][1] * hdt[i][2]; + size_mb = temp_size >> 11; + wsprintf(szText, win_language_get_string_from_id(2171), size_mb, hdt[i][0], hdt[i][1], hdt[i][2]); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) szText); + if ((tracks == hdt[i][0]) && (hpc == hdt[i][1]) && (spt == hdt[i][2])) + { + selection = i; + } + } + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2170)); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2187)); + SendMessage(h, CB_SETCURSEL, selection, 0); + return selection; +} + +static void recalc_selection(HWND hdlg) +{ + HWND h; + int i = 0; + + selection = 127; + h = GetDlgItem(hdlg, IDC_COMBO_HD_TYPE); + for (i = 0; i < 127; i++) + { + if ((tracks == hdt[i][0]) && (hpc == hdt[i][1]) && (spt == hdt[i][2])) + { + selection = i; + } + } + if ((selection == 127) && (hpc == 16) && (spt == 63)) + { + selection = 128; + } + SendMessage(h, CB_SETCURSEL, selection, 0); +} + +static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + HWND h; + int64_t i = 0; + int bus; + uint64_t temp; + WCHAR szText[256]; + FILE *f; + uint32_t sector_size = 512; + uint32_t zero = 0; + uint32_t base = 0x1000; + uint64_t signature = 0xD778A82044445459ll; + char buf[512]; + + switch (message) + { + case WM_INITDIALOG: + memset(hd_file_name, 0, 512); + + SetWindowText(hdlg, win_language_get_string_from_id(existing ? 2197 : 2196)); + + no_update = 1; + spt = existing ? 0 : 17; + set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt); + hpc = existing ? 0 : 15; + set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, hpc); + tracks = existing ? 0 : 1023; + set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, tracks); + size = (tracks * hpc * spt) << 9; + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, size >> 20); + hdconf_initialize_hdt_combo(hdlg); + if (existing) + { + h = GetDlgItem(hdlg, IDC_EDIT_HD_SPT); + EnableWindow(h, FALSE); + h = GetDlgItem(hdlg, IDC_EDIT_HD_HPC); + EnableWindow(h, FALSE); + h = GetDlgItem(hdlg, IDC_EDIT_HD_CYL); + EnableWindow(h, FALSE); + h = GetDlgItem(hdlg, IDC_EDIT_HD_SIZE); + EnableWindow(h, FALSE); + h = GetDlgItem(hdlg, IDC_COMBO_HD_TYPE); + EnableWindow(h, FALSE); + } + add_locations(hdlg); + h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); + SendMessage(h, CB_SETCURSEL, 1, 0); + recalc_location_controls(hdlg, 1); + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); + SendMessage(h, CB_SETCURSEL, 0, 0); + h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); + SendMessage(h, CB_SETCURSEL, 0, 0); + h = GetDlgItem(hdlg, IDC_COMBO_HD_LUN); + SendMessage(h, CB_SETCURSEL, 0, 0); + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); + SendMessage(h, CB_SETCURSEL, 0, 0); + h = GetDlgItem(hdlg, IDC_EDIT_HD_FILE_NAME); + EnableWindow(h, FALSE); + no_update = 0; + return TRUE; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDOK: + if (wcslen(hd_file_name) == 0) + { + msgbox_error(hwndParentDialog, 2056); + return TRUE; + } + + get_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, &(temp_hdc[next_free_id].spt)); + get_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, &(temp_hdc[next_free_id].hpc)); + get_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, &(temp_hdc[next_free_id].tracks)); + h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); + temp_hdc[next_free_id].bus = SendMessage(h, CB_GETCURSEL, 0, 0) + 1; + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); + temp_hdc[next_free_id].mfm_channel = SendMessage(h, CB_GETCURSEL, 0, 0); + h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); + temp_hdc[next_free_id].scsi_id = SendMessage(h, CB_GETCURSEL, 0, 0); + h = GetDlgItem(hdlg, IDC_COMBO_HD_LUN); + temp_hdc[next_free_id].scsi_lun = SendMessage(h, CB_GETCURSEL, 0, 0); + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); + temp_hdc[next_free_id].ide_channel = SendMessage(h, CB_GETCURSEL, 0, 0); + memset(temp_hdd_fn[next_free_id], 0, 1024); + memcpy(temp_hdd_fn[next_free_id], hd_file_name, (wcslen(hd_file_name) << 1) + 2); + + sector_size = 512; + + if (!existing && (wcslen(hd_file_name) > 0)) + { + f = _wfopen(hd_file_name, L"wb"); + + if (image_is_hdi(hd_file_name)) + { + if (size >= 0x100000000ll) + { + fclose(f); + msgbox_error(hwndParentDialog, 2058); + return TRUE; + } + + fwrite(&zero, 1, 4, f); /* 00000000: Zero/unknown */ + fwrite(&zero, 1, 4, f); /* 00000004: Zero/unknown */ + fwrite(&base, 1, 4, f); /* 00000008: Offset at which data starts */ + fwrite(&size, 1, 4, f); /* 0000000C: Full size of the data (32-bit) */ + fwrite(§or_size, 1, 4, f); /* 00000010: Sector size in bytes */ + fwrite(&spt, 1, 4, f); /* 00000014: Sectors per cylinder */ + fwrite(&hpc, 1, 4, f); /* 00000018: Heads per cylinder */ + fwrite(&tracks, 1, 4, f); /* 0000001C: Cylinders */ + + for (i = 0; i < 0x3f8; i++) + { + fwrite(&zero, 1, 4, f); + } + } + else if (image_is_hdx(hd_file_name, 0)) + { + if (size > 0xffffffffffffffffll) + { + fclose(f); + msgbox_error(hwndParentDialog, 2163); + return TRUE; + } + + fwrite(&signature, 1, 8, f); /* 00000000: Signature */ + fwrite(&size, 1, 8, f); /* 00000008: Full size of the data (64-bit) */ + fwrite(§or_size, 1, 4, f); /* 00000010: Sector size in bytes */ + fwrite(&spt, 1, 4, f); /* 00000014: Sectors per cylinder */ + fwrite(&hpc, 1, 4, f); /* 00000018: Heads per cylinder */ + fwrite(&tracks, 1, 4, f); /* 0000001C: Cylinders */ + fwrite(&zero, 1, 4, f); /* 00000020: [Translation] Sectors per cylinder */ + fwrite(&zero, 1, 4, f); /* 00000004: [Translation] Heads per cylinder */ + } + + memset(buf, 0, 512); + size >>= 9; + for (i = 0; i < size; i++) + { + fwrite(buf, 512, 1, f); + } + + fclose(f); + msgbox_info(hwndParentDialog, 2059); + } + + hard_disk_added = 1; + EndDialog(hdlg, 0); + return TRUE; + + case IDCANCEL: + hard_disk_added = 0; + EndDialog(hdlg, 0); + return TRUE; + + case IDC_CFILE: + if (!file_dlg_w(hdlg, win_language_get_string_from_id(2172), L"", !existing)) + { + if (!existing) + { + f = _wfopen(wopenfilestring, L"rb"); + if (f != NULL) + { + fclose(f); + if (msgbox_question(ghwnd, 2178) != IDYES) + { + return FALSE; + } + } + } + + f = _wfopen(wopenfilestring, existing ? L"rb" : L"wb"); + if (f == NULL) + { + msgbox_error(hwndParentDialog, existing ? 2060 : 2057); + return TRUE; + } + if (existing) + { + if (image_is_hdi(wopenfilestring) || image_is_hdx(wopenfilestring, 1)) + { + fseeko64(f, 0x10, SEEK_SET); + fread(§or_size, 1, 4, f); + if (sector_size != 512) + { + msgbox_error(hwndParentDialog, 2061); + fclose(f); + return TRUE; + } + spt = hpc = tracks = 0; + fread(&spt, 1, 4, f); + fread(&hpc, 1, 4, f); + fread(&tracks, 1, 4, f); + } + else + { + fseeko64(f, 0, SEEK_END); + size = ftello64(f); + fclose(f); + if (((size % 17) == 0) && (size <= 133693440)) + { + spt = 17; + if (size <= 26738688) + { + hpc = 4; + } + else if (size <= 53477376) + { + hpc = 6; + } + else if (size <= 71303168) + { + hpc = 8; + } + else + { + hpc = 15; + } + } + else + { + spt = 63; + hpc = 16; + } + + tracks = ((size >> 9) / hpc) / spt; + } + + no_update = 1; + + set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt); + set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, hpc); + set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, tracks); + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, size >> 20); + recalc_selection(hdlg); + + h = GetDlgItem(hdlg, IDC_EDIT_HD_SPT); + EnableWindow(h, TRUE); + h = GetDlgItem(hdlg, IDC_EDIT_HD_HPC); + EnableWindow(h, TRUE); + h = GetDlgItem(hdlg, IDC_EDIT_HD_CYL); + EnableWindow(h, TRUE); + h = GetDlgItem(hdlg, IDC_EDIT_HD_SIZE); + EnableWindow(h, TRUE); + h = GetDlgItem(hdlg, IDC_COMBO_HD_TYPE); + EnableWindow(h, TRUE); + + no_update = 0; + } + else + { + fclose(f); + } + } + + h = GetDlgItem(hdlg, IDC_EDIT_HD_FILE_NAME); + SendMessage(h, WM_SETTEXT, 0, (LPARAM) wopenfilestring); + memcpy(hd_file_name, wopenfilestring, (wcslen(wopenfilestring) << 1) + 2); + + return TRUE; + + case IDC_EDIT_HD_CYL: + if (no_update) + { + return FALSE; + } + + no_update = 1; + get_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, &temp); + if (temp != tracks) + { + tracks = temp; + size = (tracks * hpc * spt) << 9; + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, size >> 20); + recalc_selection(hdlg); + } + no_update = 0; + break; + + case IDC_EDIT_HD_HPC: + if (no_update) + { + return FALSE; + } + + no_update = 1; + get_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, &temp); + if (temp != hpc) + { + hpc = temp; + size = (tracks * hpc * spt) << 9; + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, size >> 20); + recalc_selection(hdlg); + } + no_update = 0; + break; + + case IDC_EDIT_HD_SPT: + if (no_update) + { + return FALSE; + } + + no_update = 1; + get_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, &temp); + if (temp != spt) + { + spt = temp; + size = (tracks * hpc * spt) << 9; + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, size >> 20); + recalc_selection(hdlg); + } + no_update = 0; + break; + + case IDC_EDIT_HD_SIZE: + if (no_update) + { + return FALSE; + } + + no_update = 1; + get_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, &temp); + if (temp != (size >> 20)) + { + size = temp << 20; + tracks = ((size >> 9) / hpc) / spt; + set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, tracks); + recalc_selection(hdlg); + } + no_update = 0; + break; + + case IDC_COMBO_HD_TYPE: + if (no_update) + { + return FALSE; + } + + no_update = 1; + get_combo_box_selection(hdlg, IDC_COMBO_HD_TYPE, &temp); + if ((temp != selection) && (temp != 127) && (temp != 128)) + { + selection = temp; + tracks = hdt[selection][0]; + hpc = hdt[selection][1]; + spt = hdt[selection][2]; + size = (tracks * hpc * spt) << 9; + set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, tracks); + set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, hpc); + set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt); + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, size >> 20); + } + else if ((temp != selection) && (temp == 127)) + { + selection = temp; + } + else if ((temp != selection) && (temp == 128)) + { + selection = temp; + hpc = 16; + spt = 63; + size = (tracks * hpc * spt) << 9; + set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, hpc); + set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt); + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, size >> 20); + } + no_update = 0; + break; + + case IDC_COMBO_HD_BUS: + if (no_update) + { + return FALSE; + } + + no_update = 1; + recalc_location_controls(hdlg, 1); + h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); + bus = SendMessage(h, CB_GETCURSEL, 0, 0); + get_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, &spt); + max_spt = (bus == 2) ? 99 : 63; + if (spt > max_spt) + { + spt = max_spt; + size = (tracks * hpc * spt) << 9; + set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, 17); + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (size >> 20)); + recalc_selection(hdlg); + } + no_update = 0; + break; + } + + return FALSE; + } + + return FALSE; +} + +void hard_disk_add_open(HWND hwnd, int is_existing) +{ + BOOL ret; + + existing = !!is_existing; + hard_disk_added = 0; + ret = DialogBox(hinstance, (LPCWSTR) CONFIGUREDLG_HARD_DISKS_ADD, hwnd, win_settings_hard_disks_add_proc); +} + +int ignore_change = 0; + +static BOOL CALLBACK win_settings_hard_disks_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + HWND h; + int old_sel = 0; + + switch (message) + { + case WM_INITDIALOG: + ignore_change = 1; + + normalize_hd_list(); /* Normalize the hard disks so that non-disabled hard disks start from index 0, and so they are contiguous. + This will cause an emulator reset prompt on the first opening of this category with a messy hard disk list + (which can only happen by manually editing the configuration file). */ + h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); + win_settings_hard_disks_init_columns(h); + win_settings_hard_disks_image_list_init(h); + win_settings_hard_disks_recalc_list(h); + recalc_next_free_id(hdlg); + add_locations(hdlg); + if (hd_listview_items > 0) + { + ListView_SetItemState(h, 0, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); + hdlv_current_sel = 0; + h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); + SendMessage(h, CB_SETCURSEL, temp_hdc[0].bus - 1, 0); + } + else + { + hdlv_current_sel = -1; + } + recalc_location_controls(hdlg, 0); + + ignore_change = 0; + return TRUE; + + case WM_NOTIFY: + if ((hd_listview_items == 0) || ignore_change) + { + return FALSE; + } + + if ((((LPNMHDR)lParam)->code == LVN_ITEMCHANGED) && (((LPNMHDR)lParam)->idFrom == IDC_LIST_HARD_DISKS)) + { + old_sel = hdlv_current_sel; + hdlv_current_sel = get_selected_hard_disk(hdlg); + if (hdlv_current_sel == old_sel) + { + return FALSE; + } + else if (hdlv_current_sel == -1) + { + ignore_change = 1; + hdlv_current_sel = old_sel; + ListView_SetItemState(h, hdlv_current_sel, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); + ignore_change = 0; + return FALSE; + } + ignore_change = 1; + h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); + SendMessage(h, CB_SETCURSEL, temp_hdc[hdlv_current_sel].bus - 1, 0); + recalc_location_controls(hdlg, 0); + ignore_change = 0; + } + break; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDC_COMBO_HD_BUS: + if (ignore_change) + { + return FALSE; + } + + ignore_change = 1; + recalc_location_controls(hdlg, 0); + h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); + temp_hdc[hdlv_current_sel].bus = SendMessage(h, CB_GETCURSEL, 0, 0) + 1; + h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); + win_settings_hard_disks_update_item(h, hdlv_current_sel, 0); + ignore_change = 0; + return FALSE; + + case IDC_COMBO_HD_CHANNEL: + if (ignore_change) + { + return FALSE; + } + + ignore_change = 1; + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); + temp_hdc[hdlv_current_sel].mfm_channel = SendMessage(h, CB_GETCURSEL, 0, 0); + h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); + win_settings_hard_disks_update_item(h, hdlv_current_sel, 0); + ignore_change = 0; + return FALSE; + + case IDC_COMBO_HD_CHANNEL_IDE: + if (ignore_change) + { + return FALSE; + } + + ignore_change = 1; + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); + temp_hdc[hdlv_current_sel].ide_channel = SendMessage(h, CB_GETCURSEL, 0, 0); + h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); + win_settings_hard_disks_update_item(h, hdlv_current_sel, 0); + ignore_change = 0; + return FALSE; + + case IDC_COMBO_HD_ID: + if (ignore_change) + { + return FALSE; + } + + ignore_change = 1; + h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); + temp_hdc[hdlv_current_sel].scsi_id = SendMessage(h, CB_GETCURSEL, 0, 0); + h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); + win_settings_hard_disks_update_item(h, hdlv_current_sel, 0); + ignore_change = 0; + return FALSE; + + case IDC_COMBO_HD_LUN: + if (ignore_change) + { + return FALSE; + } + + ignore_change = 1; + h = GetDlgItem(hdlg, IDC_COMBO_HD_LUN); + temp_hdc[hdlv_current_sel].scsi_lun = SendMessage(h, CB_GETCURSEL, 0, 0); + h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); + win_settings_hard_disks_update_item(h, hdlv_current_sel, 0); + ignore_change = 0; + return FALSE; + + case IDC_BUTTON_HDD_ADD: + hard_disk_add_open(hdlg, 1); + if (hard_disk_added) + { + ignore_change = 1; + h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); + win_settings_hard_disks_recalc_list(h); + recalc_next_free_id(hdlg); + ignore_change = 0; + } + return FALSE; + + case IDC_BUTTON_HDD_ADD_NEW: + hard_disk_add_open(hdlg, 0); + if (hard_disk_added) + { + ignore_change = 1; + h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); + win_settings_hard_disks_recalc_list(h); + recalc_next_free_id(hdlg); + ignore_change = 0; + } + return FALSE; + + case IDC_BUTTON_HDD_REMOVE: + memcpy(temp_hdd_fn[hdlv_current_sel], L"", 4); + temp_hdc[hdlv_current_sel].bus = 0; /* Only set the bus to zero, the list normalize code below will take care of turning this entire entry to a complete zero. */ + normalize_hd_list(); /* Normalize the hard disks so that non-disabled hard disks start from index 0, and so they are contiguous. */ + ignore_change = 1; + h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); + win_settings_hard_disks_recalc_list(h); + recalc_next_free_id(hdlg); + if (hd_listview_items > 0) + { + ListView_SetItemState(h, 0, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); + hdlv_current_sel = 0; + h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); + SendMessage(h, CB_SETCURSEL, temp_hdc[0].bus - 1, 0); + } + else + { + hdlv_current_sel = -1; + } + recalc_location_controls(hdlg, 0); + ignore_change = 0; + return FALSE; + } + + default: + return FALSE; + } + + return FALSE; +} + +int fdlv_current_sel; +int cdlv_current_sel; + +static int combo_id_to_string_id(int combo_id) +{ + switch (combo_id) + { + case 0: /* Disabled */ + default: + return 2151; + break; + case 2: /* Atapi (PIO-only) */ + return 2189; + break; + case 3: /* Atapi (PIA and DMA) */ + return 2190; + break; + case 4: /* SCSI */ + return 2168; + break; + } +} + +static int combo_id_to_format_string_id(int combo_id) +{ + switch (combo_id) + { + case 0: /* Disabled */ + default: + return 2151; + break; + case 2: /* Atapi (PIO-only) */ + return 2191; + break; + case 3: /* Atapi (PIA and DMA) */ + return 2192; + break; + case 4: /* SCSI */ + return 2158; + break; + } +} + +static BOOL win_settings_floppy_drives_image_list_init(HWND hwndList) +{ + HICON hiconItem; + HIMAGELIST hSmall; + + int i = 0; + + hSmall = ImageList_Create(GetSystemMetrics(SM_CXSMICON), + GetSystemMetrics(SM_CYSMICON), + ILC_MASK | ILC_COLOR32, 1, 1); + + for (i = 0; i < 14; i++) + { + hiconItem = LoadIcon(hinstance, (LPCWSTR) fdd_type_to_icon(i)); + ImageList_AddIcon(hSmall, hiconItem); + DestroyIcon(hiconItem); + } + + ListView_SetImageList(hwndList, hSmall, LVSIL_SMALL); + + return TRUE; +} + +static BOOL win_settings_cdrom_drives_image_list_init(HWND hwndList) +{ + HICON hiconItem; + HIMAGELIST hSmall; + + int i = 0; + int j = 0; + + hSmall = ImageList_Create(GetSystemMetrics(SM_CXSMICON), + GetSystemMetrics(SM_CYSMICON), + ILC_MASK | ILC_COLOR32, 1, 1); + + hiconItem = LoadIcon(hinstance, (LPCWSTR) 514); + ImageList_AddIcon(hSmall, hiconItem); + DestroyIcon(hiconItem); + + hiconItem = LoadIcon(hinstance, (LPCWSTR) 160); + ImageList_AddIcon(hSmall, hiconItem); + DestroyIcon(hiconItem); + + hiconItem = LoadIcon(hinstance, (LPCWSTR) 162); + ImageList_AddIcon(hSmall, hiconItem); + DestroyIcon(hiconItem); + + hiconItem = LoadIcon(hinstance, (LPCWSTR) 164); + ImageList_AddIcon(hSmall, hiconItem); + DestroyIcon(hiconItem); + + ListView_SetImageList(hwndList, hSmall, LVSIL_SMALL); + + return TRUE; +} + +static BOOL win_settings_floppy_drives_recalc_list(HWND hwndList) +{ + LVITEM lvI; + int i = 0; + char s[256]; + WCHAR szText[256]; + + lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; + lvI.stateMask = lvI.iSubItem = lvI.state = 0; + + for (i = 0; i < 4; i++) + { + if (temp_fdd_types[i] > 0) + { + strcpy(s, fdd_getname(temp_fdd_types[i])); + mbstowcs(szText, s, strlen(s) + 1); + lvI.pszText = szText; + } + else + { + lvI.pszText = win_language_get_string_from_id(2151); + } + lvI.iItem = i; + lvI.iImage = temp_fdd_types[i]; + + if (ListView_InsertItem(hwndList, &lvI) == -1) + return FALSE; + } + + return TRUE; +} + +static BOOL win_settings_cdrom_drives_recalc_list(HWND hwndList) +{ + LVITEM lvI; + int i = 0; + char s[256]; + WCHAR szText[256]; + int bid = 0; + int fsid = 0; + + lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; + lvI.stateMask = lvI.iSubItem = lvI.state = 0; + + for (i = 0; i < 4; i++) + { + fsid = combo_id_to_format_string_id(temp_cdrom_drives[i].bus_type); + + switch (temp_cdrom_drives[i].bus_type) + { + case 0: + default: + lvI.pszText = win_language_get_string_from_id(fsid); + break; + case 2: + case 3: + wsprintf(szText, win_language_get_string_from_id(fsid), temp_cdrom_drives[i].ide_channel >> 1, temp_cdrom_drives[i].ide_channel & 1); + lvI.pszText = szText; + break; + case 4: + wsprintf(szText, win_language_get_string_from_id(fsid), temp_cdrom_drives[i].scsi_device_id, temp_cdrom_drives[i].scsi_device_lun); + lvI.pszText = szText; + break; + } + + lvI.iItem = i; + + if (temp_cdrom_drives[i].bus_type) + { + lvI.iImage = temp_cdrom_drives[i].bus_type - 1; + } + else + { + lvI.iImage = 0; + } + + if (ListView_InsertItem(hwndList, &lvI) == -1) + return FALSE; + } + + return TRUE; +} + +static BOOL win_settings_floppy_drives_init_columns(HWND hwndList) +{ + LVCOLUMN lvc; + + lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; + + lvc.iSubItem = 0; + lvc.pszText = win_language_get_string_from_id(2188); + + lvc.cx = 392; + lvc.fmt = LVCFMT_LEFT; + + if (ListView_InsertColumn(hwndList, 0, &lvc) == -1) + { + return FALSE; + } + + return TRUE; +} + +static BOOL win_settings_cdrom_drives_init_columns(HWND hwndList) +{ + LVCOLUMN lvc; + + lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; + + lvc.iSubItem = 0; + lvc.pszText = win_language_get_string_from_id(2082); + + lvc.cx = 392; + lvc.fmt = LVCFMT_LEFT; + + if (ListView_InsertColumn(hwndList, 0, &lvc) == -1) + { + return FALSE; + } + + return TRUE; +} + +static int get_selected_floppy_drive(HWND hdlg) +{ + int floppy_drive = -1; + int i, j = 0; + HWND h; + + for (i = 0; i < 6; i++) + { + h = GetDlgItem(hdlg, IDC_LIST_FLOPPY_DRIVES); + j = ListView_GetItemState(h, i, LVIS_SELECTED); + if (j) + { + floppy_drive = i; + } + } + + return floppy_drive; +} + +static int get_selected_cdrom_drive(HWND hdlg) +{ + int cd_drive = -1; + int i, j = 0; + HWND h; + + for (i = 0; i < 6; i++) + { + h = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); + j = ListView_GetItemState(h, i, LVIS_SELECTED); + if (j) + { + cd_drive = i; + } + } + + return cd_drive; +} + +static void win_settings_floppy_drives_update_item(HWND hwndList, int i) +{ + LVITEM lvI; + char s[256]; + WCHAR szText[256]; + + lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; + lvI.stateMask = lvI.iSubItem = lvI.state = 0; + + lvI.iSubItem = 0; + lvI.iItem = i; + + if (temp_fdd_types[i] > 0) + { + strcpy(s, fdd_getname(temp_fdd_types[i])); + mbstowcs(szText, s, strlen(s) + 1); + lvI.pszText = szText; + } + else + { + lvI.pszText = win_language_get_string_from_id(2151); + } + lvI.iImage = temp_fdd_types[i]; + + if (ListView_SetItem(hwndList, &lvI) == -1) + { + return; + } +} + +static void win_settings_cdrom_drives_update_item(HWND hwndList, int i) +{ + LVITEM lvI; + char s[256]; + WCHAR szText[256]; + int bid; + int fsid; + + lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; + lvI.stateMask = lvI.iSubItem = lvI.state = 0; + + lvI.iSubItem = 0; + lvI.iItem = i; + + fsid = combo_id_to_format_string_id(temp_cdrom_drives[i].bus_type); + + switch (temp_cdrom_drives[i].bus_type) + { + case 0: + default: + lvI.pszText = win_language_get_string_from_id(fsid); + break; + case 2: + case 3: + wsprintf(szText, win_language_get_string_from_id(fsid), temp_cdrom_drives[i].ide_channel >> 1, temp_cdrom_drives[i].ide_channel & 1); + lvI.pszText = szText; + break; + case 4: + wsprintf(szText, win_language_get_string_from_id(fsid), temp_cdrom_drives[i].scsi_device_id, temp_cdrom_drives[i].scsi_device_lun); + lvI.pszText = szText; + break; + } + + if (temp_cdrom_drives[i].bus_type) + { + lvI.iImage = temp_cdrom_drives[i].bus_type - 1; + } + else + { + lvI.iImage = 0; + } + + if (ListView_SetItem(hwndList, &lvI) == -1) + { + return; + } +} + +static void cdrom_add_locations(HWND hdlg) +{ + LPTSTR lptsTemp; + HWND h; + int i = 0; + + lptsTemp = (LPTSTR) malloc(512); + + h = GetDlgItem(hdlg, IDC_COMBO_CD_BUS); + for (i = 1; i < 5; i++) + { + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(combo_id_to_string_id(i))); + } + + h = GetDlgItem(hdlg, IDC_COMBO_CD_ID); + for (i = 0; i < 16; i++) + { + wsprintf(lptsTemp, win_language_get_string_from_id(2088), i); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + } + + h = GetDlgItem(hdlg, IDC_COMBO_CD_LUN); + for (i = 0; i < 8; i++) + { + wsprintf(lptsTemp, win_language_get_string_from_id(2088), i); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + } + + h = GetDlgItem(hdlg, IDC_COMBO_CD_CHANNEL_IDE); + for (i = 0; i < 8; i++) + { + wsprintf(lptsTemp, win_language_get_string_from_id(2169), i >> 1, i & 1); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + } + + free(lptsTemp); +} +static void cdrom_recalc_location_controls(HWND hdlg) +{ + int i = 0; + HWND h; + + int bus = temp_cdrom_drives[cdlv_current_sel].bus_type; + + for (i = 1800; i < 1803; i++) + { + h = GetDlgItem(hdlg, i); + EnableWindow(h, FALSE); + ShowWindow(h, SW_HIDE); + } + + h = GetDlgItem(hdlg, IDC_COMBO_CD_ID); + EnableWindow(h, FALSE); + ShowWindow(h, SW_HIDE); + + h = GetDlgItem(hdlg, IDC_COMBO_CD_LUN); + EnableWindow(h, FALSE); + ShowWindow(h, SW_HIDE); + + h = GetDlgItem(hdlg, IDC_COMBO_CD_CHANNEL_IDE); + EnableWindow(h, FALSE); + ShowWindow(h, SW_HIDE); + + switch(bus) + { + case 2: /* ATAPI (PIO-only) */ + case 3: /* ATAPI (PIO and DMA) */ + h = GetDlgItem(hdlg, 1802); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + + h = GetDlgItem(hdlg, IDC_COMBO_CD_CHANNEL_IDE); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + SendMessage(h, CB_SETCURSEL, temp_cdrom_drives[cdlv_current_sel].ide_channel, 0); + break; + case 4: /* SCSI */ + h = GetDlgItem(hdlg, 1800); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + h = GetDlgItem(hdlg, 1801); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + + h = GetDlgItem(hdlg, IDC_COMBO_CD_ID); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + SendMessage(h, CB_SETCURSEL, temp_cdrom_drives[cdlv_current_sel].scsi_device_id, 0); + + h = GetDlgItem(hdlg, IDC_COMBO_CD_LUN); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + SendMessage(h, CB_SETCURSEL, temp_cdrom_drives[cdlv_current_sel].scsi_device_lun, 0); + break; + } +} + + +int rd_ignore_change = 0; + +static BOOL CALLBACK win_settings_removable_devices_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + HWND h; + int i = 0; + int old_sel = 0; + int cid = 0; + WCHAR szText[256]; + + switch (message) + { + case WM_INITDIALOG: + rd_ignore_change = 1; + + fdlv_current_sel = 0; + h = GetDlgItem(hdlg, IDC_LIST_FLOPPY_DRIVES); + win_settings_floppy_drives_init_columns(h); + win_settings_floppy_drives_image_list_init(h); + win_settings_floppy_drives_recalc_list(h); + ListView_SetItemState(h, 0, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); + h = GetDlgItem(hdlg, IDC_COMBO_FD_TYPE); + for (i = 0; i < 14; i++) + { + if (i == 0) + { + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2151)); + } + else + { + mbstowcs(szText, fdd_getname(i), strlen(fdd_getname(i)) + 1); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) szText); + } + } + SendMessage(h, CB_SETCURSEL, temp_fdd_types[fdlv_current_sel], 0); + + cdlv_current_sel = 0; + h = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); + win_settings_cdrom_drives_init_columns(h); + win_settings_cdrom_drives_image_list_init(h); + win_settings_cdrom_drives_recalc_list(h); + ListView_SetItemState(h, 0, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); + cdrom_add_locations(hdlg); + h = GetDlgItem(hdlg, IDC_COMBO_CD_BUS); + if (temp_cdrom_drives[cdlv_current_sel].bus_type > 1) + { + SendMessage(h, CB_SETCURSEL, temp_cdrom_drives[cdlv_current_sel].bus_type, 0); + } + else + { + SendMessage(h, CB_SETCURSEL, 0, 0); + } + cdrom_recalc_location_controls(hdlg); + + rd_ignore_change = 0; + return TRUE; + + case WM_NOTIFY: + if (rd_ignore_change) + { + return FALSE; + } + + if ((((LPNMHDR)lParam)->code == LVN_ITEMCHANGED) && (((LPNMHDR)lParam)->idFrom == IDC_LIST_FLOPPY_DRIVES)) + { + old_sel = fdlv_current_sel; + fdlv_current_sel = get_selected_floppy_drive(hdlg); + if (fdlv_current_sel == old_sel) + { + return FALSE; + } + else if (fdlv_current_sel == -1) + { + rd_ignore_change = 1; + fdlv_current_sel = old_sel; + ListView_SetItemState(h, fdlv_current_sel, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); + rd_ignore_change = 0; + return FALSE; + } + rd_ignore_change = 1; + h = GetDlgItem(hdlg, IDC_COMBO_FD_TYPE); + SendMessage(h, CB_SETCURSEL, temp_fdd_types[fdlv_current_sel], 0); + rd_ignore_change = 0; + } + else if ((((LPNMHDR)lParam)->code == LVN_ITEMCHANGED) && (((LPNMHDR)lParam)->idFrom == IDC_LIST_CDROM_DRIVES)) + { + old_sel = cdlv_current_sel; + cdlv_current_sel = get_selected_cdrom_drive(hdlg); + if (cdlv_current_sel == old_sel) + { + return FALSE; + } + else if (cdlv_current_sel == -1) + { + rd_ignore_change = 1; + cdlv_current_sel = old_sel; + ListView_SetItemState(h, cdlv_current_sel, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); + rd_ignore_change = 0; + return FALSE; + } + rd_ignore_change = 1; + h = GetDlgItem(hdlg, IDC_COMBO_CD_BUS); + if (temp_cdrom_drives[cdlv_current_sel].bus_type > 1) + { + SendMessage(h, CB_SETCURSEL, temp_cdrom_drives[cdlv_current_sel].bus_type, 0); + } + else + { + SendMessage(h, CB_SETCURSEL, 0, 0); + } + cdrom_recalc_location_controls(hdlg); + rd_ignore_change = 0; + } + break; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDC_COMBO_FD_TYPE: + if (rd_ignore_change) + { + return FALSE; + } + + rd_ignore_change = 1; + h = GetDlgItem(hdlg, IDC_COMBO_FD_TYPE); + temp_fdd_types[fdlv_current_sel] = SendMessage(h, CB_GETCURSEL, 0, 0); + h = GetDlgItem(hdlg, IDC_LIST_FLOPPY_DRIVES); + win_settings_floppy_drives_update_item(h, fdlv_current_sel); + rd_ignore_change = 0; + return FALSE; + + case IDC_COMBO_CD_BUS: + if (rd_ignore_change) + { + return FALSE; + } + + rd_ignore_change = 1; + h = GetDlgItem(hdlg, IDC_COMBO_CD_BUS); + temp_cdrom_drives[cdlv_current_sel].bus_type = SendMessage(h, CB_GETCURSEL, 0, 0) + 1; + if (temp_cdrom_drives[cdlv_current_sel].bus_type == 1) + { + temp_cdrom_drives[cdlv_current_sel].bus_type = 0; + } + cdrom_recalc_location_controls(hdlg); + h = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); + win_settings_cdrom_drives_update_item(h, cdlv_current_sel); + rd_ignore_change = 0; + return FALSE; + + case IDC_COMBO_CD_ID: + if (rd_ignore_change) + { + return FALSE; + } + + rd_ignore_change = 1; + h = GetDlgItem(hdlg, IDC_COMBO_CD_ID); + temp_cdrom_drives[cdlv_current_sel].scsi_device_id = SendMessage(h, CB_GETCURSEL, 0, 0); + h = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); + win_settings_cdrom_drives_update_item(h, cdlv_current_sel); + rd_ignore_change = 0; + return FALSE; + + case IDC_COMBO_CD_LUN: + if (rd_ignore_change) + { + return FALSE; + } + + rd_ignore_change = 1; + h = GetDlgItem(hdlg, IDC_COMBO_CD_LUN); + temp_cdrom_drives[cdlv_current_sel].scsi_device_lun = SendMessage(h, CB_GETCURSEL, 0, 0); + h = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); + win_settings_cdrom_drives_update_item(h, cdlv_current_sel); + rd_ignore_change = 0; + return FALSE; + + case IDC_COMBO_CD_CHANNEL_IDE: + if (rd_ignore_change) + { + return FALSE; + } + + rd_ignore_change = 1; + h = GetDlgItem(hdlg, IDC_COMBO_CD_CHANNEL_IDE); + temp_cdrom_drives[cdlv_current_sel].ide_channel = SendMessage(h, CB_GETCURSEL, 0, 0); + h = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); + win_settings_cdrom_drives_update_item(h, cdlv_current_sel); + rd_ignore_change = 0; + return FALSE; + } + + default: + return FALSE; + } + + return FALSE; +} + +void win_settings_show_child(HWND hwndParent, DWORD child_id) +{ + if (child_id == displayed_category) + { + return; + } + else + { + displayed_category = child_id; + } + + SendMessage(hwndChildDialog, WM_SAVESETTINGS, 0, 0); + + DestroyWindow(hwndChildDialog); + + switch(child_id) + { + case 0: + hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) CONFIGUREDLG_MACHINE, hwndParent, win_settings_machine_proc); + break; + case 1: + hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) CONFIGUREDLG_VIDEO, hwndParent, win_settings_video_proc); + break; + case 2: + hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) CONFIGUREDLG_INPUT, hwndParent, win_settings_input_proc); + break; + case 3: + hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) CONFIGUREDLG_SOUND, hwndParent, win_settings_sound_proc); + break; + case 4: + hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) CONFIGUREDLG_NETWORK, hwndParent, win_settings_network_proc); + break; + case 5: + hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) CONFIGUREDLG_PERIPHERALS, hwndParent, win_settings_peripherals_proc); + break; + case 6: + hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) CONFIGUREDLG_HARD_DISKS, hwndParent, win_settings_hard_disks_proc); + break; + case 7: + hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) CONFIGUREDLG_REMOVABLE_DEVICES, hwndParent, win_settings_removable_devices_proc); + break; + default: + fatal("Invalid child dialog ID\n"); + return; + } + + ShowWindow(hwndChildDialog, SW_SHOWNORMAL); +} + +static BOOL win_settings_main_image_list_init(HWND hwndList) +{ + HICON hiconItem; + HIMAGELIST hSmall; + + int i = 0; + + hSmall = ImageList_Create(GetSystemMetrics(SM_CXSMICON), + GetSystemMetrics(SM_CYSMICON), + ILC_MASK | ILC_COLOR32, 1, 1); + + for (i = 0; i < 8; i++) + { + hiconItem = LoadIcon(hinstance, (LPCWSTR) (256 + i)); + ImageList_AddIcon(hSmall, hiconItem); + DestroyIcon(hiconItem); + } + + ListView_SetImageList(hwndList, hSmall, LVSIL_SMALL); + + return TRUE; +} + +static BOOL win_settings_main_insert_categories(HWND hwndList) +{ + LVITEM lvI; + int i = 0; + + lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; + lvI.stateMask = lvI.iSubItem = lvI.state = 0; + + for (i = 0; i < 8; i++) + { + lvI.pszText = win_language_get_settings_category(i); + lvI.iItem = i; + lvI.iImage = i; + + if (ListView_InsertItem(hwndList, &lvI) == -1) + return FALSE; + } + + return TRUE; +} + +static BOOL CALLBACK win_settings_main_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + HWND h; + int category; + int i = 0; + int j = 0; + + hwndParentDialog = hdlg; + + switch (message) + { + case WM_INITDIALOG: + pause = 1; + win_settings_init(); + displayed_category = -1; + h = GetDlgItem(hdlg, IDC_SETTINGSCATLIST); + win_settings_main_image_list_init(h); + win_settings_main_insert_categories(h); + ListView_SetItemState(h, 0, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); + h = GetDlgItem(hdlg, IDC_COMBO_LANG); /* This is currently disabled, I am going to add localization options in the future. */ + EnableWindow(h, FALSE); + ShowWindow(h, SW_HIDE); + h = GetDlgItem(hdlg, 2047); + EnableWindow(h, FALSE); + ShowWindow(h, SW_HIDE); + return TRUE; + case WM_NOTIFY: + if ((((LPNMHDR)lParam)->code == LVN_ITEMCHANGED) && (((LPNMHDR)lParam)->idFrom == IDC_SETTINGSCATLIST)) + { + category = -1; + for (i = 0; i < 8; i++) + { + h = GetDlgItem(hdlg, IDC_SETTINGSCATLIST); + j = ListView_GetItemState(h, i, LVIS_SELECTED); + if (j) + { + category = i; + /* pclog("Category %i selected\n", i); */ + } + } + if (category != -1) + { + /* pclog("Showing child: %i\n", category); */ + win_settings_show_child(hdlg, category); + } + } + break; + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDOK: + /* pclog("Saving settings...\n"); */ + SendMessage(hwndChildDialog, WM_SAVESETTINGS, 0, 0); + i = settings_msgbox_reset(); + if (i > 0) + { + if (i == 2) + { + win_settings_save(); + } + + /* pclog("Destroying window...\n"); */ + DestroyWindow(hwndChildDialog); + EndDialog(hdlg, 0); + pause = 0; + return TRUE; + } + else + { + return FALSE; + } + case IDCANCEL: + DestroyWindow(hwndChildDialog); + EndDialog(hdlg, 0); + pause=0; + return TRUE; + } + break; + default: + return FALSE; + } + + return FALSE; +} + +void win_settings_open(HWND hwnd) +{ + DialogBox(hinstance, (LPCWSTR) CONFIGUREDLG_MAIN, hwnd, win_settings_main_proc); +} diff --git a/src/WIN/win_status.c b/src/WIN/win_status.c new file mode 100644 index 000000000..59a7a5947 --- /dev/null +++ b/src/WIN/win_status.c @@ -0,0 +1,95 @@ +/* Copyright holders: Sarah Walker + see COPYING for more details +*/ +#define BITMAP WINDOWS_BITMAP +#include +#include +#undef BITMAP + +#include "../ibm.h" +#include "../mem.h" +#include "../cpu/x86_ops.h" +#include "../cpu/codegen.h" +#include "../device.h" +#include "resource.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, IDC_STEXT_DEVICE, WM_SETTEXT, (WPARAM)NULL, (LPARAM)device_s); + + device_s[0] = 0; + device_add_status_info(device_s, 4096); + SendDlgItemMessage(hdlg, IDC_STEXT1, 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, TEXT("StatusDlg"), hwnd, status_dlgproc); + ShowWindow(status_hwnd, SW_SHOW); +} diff --git a/src/WIN/win_video.c b/src/WIN/win_video.c new file mode 100644 index 000000000..3a50f7b9f --- /dev/null +++ b/src/WIN/win_video.c @@ -0,0 +1,57 @@ +/* Copyright holders: Sarah Walker + see COPYING for more details +*/ +#include +#include +#include +#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; +} diff --git a/src/cdrom_dosbox.cpp b/src/cdrom_dosbox.cpp new file mode 100644 index 000000000..e076fb9b1 --- /dev/null +++ b/src/cdrom_dosbox.cpp @@ -0,0 +1,565 @@ +/* + * Copyright (C) 2002-2015 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* Modified for use with PCem by bit */ + +#include +#include +#include +#include +#include +#include +#include //GCC 2.95 +#include +#include +#include +#include "cdrom_dosbox.h" + +#if !defined(WIN32) +#include +#else +#include +#endif + +using namespace std; + +#define MAX_LINE_LENGTH 512 +#define MAX_FILENAME_LENGTH 256 +#define CROSS_LEN 512 + +#define safe_strncpy(a,b,n) do { strncpy((a),(b),(n)-1); (a)[(n)-1] = 0; } while (0) + +CDROM_Interface_Image::BinaryFile::BinaryFile(const char *filename, bool &error) +{ + file = new ifstream(filename, ios::in | ios::binary); + error = (file == NULL) || (file->fail()); +} + +CDROM_Interface_Image::BinaryFile::~BinaryFile() +{ + delete file; +} + +bool CDROM_Interface_Image::BinaryFile::read(Bit8u *buffer, int seek, int count) +{ + file->seekg(seek, ios::beg); + file->read((char*)buffer, count); + return !(file->fail()); +} + +int CDROM_Interface_Image::BinaryFile::getLength() +{ + file->seekg(0, ios::end); + int length = (int)file->tellg(); + if (file->fail()) return -1; + return length; +} + +CDROM_Interface_Image::CDROM_Interface_Image() +{ +} + +CDROM_Interface_Image::~CDROM_Interface_Image() +{ + ClearTracks(); +} + +void CDROM_Interface_Image::InitNewMedia() +{ +} + +bool CDROM_Interface_Image::SetDevice(char* path, int forceCD) +{ + if (LoadCueSheet(path)) return true; + if (LoadIsoFile(path)) return true; + + // print error message on dosbox console + //printf("Could not load image file: %s\n", path); + return false; +} + +bool CDROM_Interface_Image::GetUPC(unsigned char& attr, char* upc) +{ + attr = 0; + strcpy(upc, this->mcn.c_str()); + return true; +} + +bool CDROM_Interface_Image::GetAudioTracks(int& stTrack, int& end, TMSF& leadOut) +{ + stTrack = 1; + end = (int)(tracks.size() - 1); + FRAMES_TO_MSF(tracks[tracks.size() - 1].start + 150, &leadOut.min, &leadOut.sec, &leadOut.fr); + return true; +} + +bool CDROM_Interface_Image::GetAudioTrackInfo(int track, int& track_number, TMSF& start, unsigned char& attr) +{ + if (track < 1 || track > (int)tracks.size()) return false; + FRAMES_TO_MSF(tracks[track - 1].start + 150, &start.min, &start.sec, &start.fr); + track_number = tracks[track - 1].track_number; + attr = tracks[track - 1].attr; + return true; +} + +bool CDROM_Interface_Image::GetAudioSub(int sector, unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos) +{ + int cur_track = GetTrack(sector); + if (cur_track < 1) return false; + track = (unsigned char)cur_track; + attr = tracks[track - 1].attr; + index = 1; + FRAMES_TO_MSF(sector + 150, &absPos.min, &absPos.sec, &absPos.fr); + FRAMES_TO_MSF(sector - tracks[track - 1].start + 150, &relPos.min, &relPos.sec, &relPos.fr); + return true; +} + +bool CDROM_Interface_Image::GetMediaTrayStatus(bool& mediaPresent, bool& mediaChanged, bool& trayOpen) +{ + mediaPresent = true; + mediaChanged = false; + trayOpen = false; + return true; +} + +bool CDROM_Interface_Image::ReadSectors(PhysPt buffer, bool raw, unsigned long sector, unsigned long num) +{ + int sectorSize = raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE; + Bitu buflen = num * sectorSize; + Bit8u* buf = new Bit8u[buflen]; + + bool success = true; //Gobliiins reads 0 sectors + for(unsigned long i = 0; i < num; i++) { + success = ReadSector(&buf[i * sectorSize], raw, sector + i); + if (!success) break; + } + + memcpy((void*)buffer, buf, buflen); + delete[] buf; + + return success; +} + +bool CDROM_Interface_Image::LoadUnloadMedia(bool unload) +{ + return true; +} + +int CDROM_Interface_Image::GetTrack(int sector) +{ + vector::iterator i = tracks.begin(); + vector::iterator end = tracks.end() - 1; + + while(i != end) { + Track &curr = *i; + Track &next = *(i + 1); + if (curr.start <= sector && sector < next.start) return curr.number; + i++; + } + return -1; +} + +bool CDROM_Interface_Image::ReadSector(Bit8u *buffer, bool raw, unsigned long sector) +{ + int track = GetTrack(sector) - 1; + if (track < 0) return false; + + int seek = tracks[track].skip + (sector - tracks[track].start) * tracks[track].sectorSize; + int length = (raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE); + if (tracks[track].sectorSize != RAW_SECTOR_SIZE && raw) return false; + if (tracks[track].sectorSize == RAW_SECTOR_SIZE && !tracks[track].mode2 && !raw) seek += 16; + if (tracks[track].mode2 && !raw) seek += 24; + + return tracks[track].file->read(buffer, seek, length); +} + +bool CDROM_Interface_Image::IsMode2(unsigned long sector) +{ + int track = GetTrack(sector) - 1; + if (track < 0) return false; + + if (tracks[track].mode2) + { + return true; + } + else + { + return false; + } +} + +bool CDROM_Interface_Image::LoadIsoFile(char* filename) +{ + int shift = 0; + int totalPregap = 0; + + tracks.clear(); + + // data track + Track track = {0, 0, 0, 0, 0, 0, false, NULL}; + bool error; + track.file = new BinaryFile(filename, error); + if (error) { + delete track.file; + return false; + } + track.number = 1; + track.track_number = 1;//IMPORTANT: This is needed. + track.attr = DATA_TRACK;//data + + // try to detect iso type + if (CanReadPVD(track.file, COOKED_SECTOR_SIZE, false)) { + track.sectorSize = COOKED_SECTOR_SIZE; + track.mode2 = false; + } else if (CanReadPVD(track.file, RAW_SECTOR_SIZE, false)) { + track.sectorSize = RAW_SECTOR_SIZE; + track.mode2 = false; + } else if (CanReadPVD(track.file, 2336, true)) { + track.sectorSize = 2336; + track.mode2 = true; + } else if (CanReadPVD(track.file, RAW_SECTOR_SIZE, true)) { + track.sectorSize = RAW_SECTOR_SIZE; + track.mode2 = true; + } else return false; + + track.length = track.file->getLength() / track.sectorSize; + tracks.push_back(track); + + // leadout track + track.number = 2; + track.track_number = 0xAA; + track.attr = 0x16; /* Was 0x00 but I believe 0x16 is appropriate. */ + track.start = track.length; + track.length = 0; + track.file = NULL; + tracks.push_back(track); + + return true; +} + +bool CDROM_Interface_Image::CanReadPVD(TrackFile *file, int sectorSize, bool mode2) +{ + Bit8u pvd[COOKED_SECTOR_SIZE]; + int seek = 16 * sectorSize; // first vd is located at sector 16 + if (sectorSize == RAW_SECTOR_SIZE && !mode2) seek += 16; + if (mode2) seek += 24; + file->read(pvd, seek, COOKED_SECTOR_SIZE); + // pvd[0] = descriptor type, pvd[1..5] = standard identifier, pvd[6] = iso version (+8 for High Sierra) + return ((pvd[0] == 1 && !strncmp((char*)(&pvd[1]), "CD001", 5) && pvd[6] == 1) || + (pvd[8] == 1 && !strncmp((char*)(&pvd[9]), "CDROM", 5) && pvd[14] == 1)); +} + +#if defined(WIN32) +static string dirname(char * file) { + char * sep = strrchr(file, '\\'); + if (sep == NULL) + sep = strrchr(file, '/'); + if (sep == NULL) + return ""; + else { + int len = (int)(sep - file); + char tmp[MAX_FILENAME_LENGTH]; + safe_strncpy(tmp, file, len+1); + return tmp; + } +} +#endif + +bool CDROM_Interface_Image::LoadCueSheet(char *cuefile) +{ + Track track = {0, 0, 0, 0, 0, 0, false, NULL}; + tracks.clear(); + int shift = 0; + int currPregap = 0; + int totalPregap = 0; + int prestart = 0; + bool success; + bool canAddTrack = false; + char tmp[MAX_FILENAME_LENGTH]; // dirname can change its argument + safe_strncpy(tmp, cuefile, MAX_FILENAME_LENGTH); + string pathname(dirname(tmp)); + ifstream in; + in.open(cuefile, ios::in); + if (in.fail()) return false; + + while(!in.eof()) { + // get next line + char buf[MAX_LINE_LENGTH]; + in.getline(buf, MAX_LINE_LENGTH); + if (in.fail() && !in.eof()) return false; // probably a binary file + istringstream line(buf); + + string command; + GetCueKeyword(command, line); + + if (command == "TRACK") { + if (canAddTrack) success = AddTrack(track, shift, prestart, totalPregap, currPregap); + else success = true; + + track.start = 0; + track.skip = 0; + currPregap = 0; + prestart = 0; + + line >> track.number; + track.track_number = track.number; + string type; + GetCueKeyword(type, line); + + if (type == "AUDIO") { + track.sectorSize = RAW_SECTOR_SIZE; + track.attr = AUDIO_TRACK; + track.mode2 = false; + } else if (type == "MODE1/2048") { + track.sectorSize = COOKED_SECTOR_SIZE; + track.attr = DATA_TRACK; + track.mode2 = false; + } else if (type == "MODE1/2352") { + track.sectorSize = RAW_SECTOR_SIZE; + track.attr = DATA_TRACK; + track.mode2 = false; + } else if (type == "MODE2/2336") { + track.sectorSize = 2336; + track.attr = DATA_TRACK; + track.mode2 = true; + } else if (type == "MODE2/2352") { + track.sectorSize = RAW_SECTOR_SIZE; + track.attr = DATA_TRACK; + track.mode2 = true; + } else success = false; + + canAddTrack = true; + } + else if (command == "INDEX") { + int index; + line >> index; + int frame; + success = GetCueFrame(frame, line); + + if (index == 1) track.start = frame; + else if (index == 0) prestart = frame; + // ignore other indices + } + else if (command == "FILE") { + if (canAddTrack) success = AddTrack(track, shift, prestart, totalPregap, currPregap); + else success = true; + canAddTrack = false; + + string filename; + GetCueString(filename, line); + GetRealFileName(filename, pathname); + string type; + GetCueKeyword(type, line); + + track.file = NULL; + bool error = true; + if (type == "BINARY") { + track.file = new BinaryFile(filename.c_str(), error); + } + if (error) { + delete track.file; + success = false; + } + } + else if (command == "PREGAP") success = GetCueFrame(currPregap, line); + else if (command == "CATALOG") success = GetCueString(mcn, line); + // ignored commands + else if (command == "CDTEXTFILE" || command == "FLAGS" || command == "ISRC" + || command == "PERFORMER" || command == "POSTGAP" || command == "REM" + || command == "SONGWRITER" || command == "TITLE" || command == "") success = true; + // failure + else success = false; + + if (!success) return false; + } + // add last track + if (!AddTrack(track, shift, prestart, totalPregap, currPregap)) return false; + + // add leadout track + track.number++; + track.track_number = 0xAA; + // track.attr = 0;//sync with load iso + track.attr = 0x16; /* Was 0x00 but I believe 0x16 is appropriate. */ + track.start = 0; + track.length = 0; + track.file = NULL; + if(!AddTrack(track, shift, 0, totalPregap, 0)) return false; + + return true; +} + +bool CDROM_Interface_Image::AddTrack(Track &curr, int &shift, int prestart, int &totalPregap, int currPregap) +{ + // frames between index 0(prestart) and 1(curr.start) must be skipped + int skip; + if (prestart > 0) { + if (prestart > curr.start) return false; + skip = curr.start - prestart; + } else skip = 0; + + // first track (track number must be 1) + if (tracks.empty()) { + if (curr.number != 1) return false; + curr.skip = skip * curr.sectorSize; + curr.start += currPregap; + totalPregap = currPregap; + tracks.push_back(curr); + return true; + } + + Track &prev = *(tracks.end() - 1); + + // current track consumes data from the same file as the previous + if (prev.file == curr.file) { + curr.start += shift; + prev.length = curr.start + totalPregap - prev.start - skip; + curr.skip += prev.skip + prev.length * prev.sectorSize + skip * curr.sectorSize; + totalPregap += currPregap; + curr.start += totalPregap; + // current track uses a different file as the previous track + } else { + int tmp = prev.file->getLength() - prev.skip; + prev.length = tmp / prev.sectorSize; + if (tmp % prev.sectorSize != 0) prev.length++; // padding + + curr.start += prev.start + prev.length + currPregap; + curr.skip = skip * curr.sectorSize; + shift += prev.start + prev.length; + totalPregap = currPregap; + } + + // error checks + if (curr.number <= 1) return false; + if (prev.number + 1 != curr.number) return false; + if (curr.start < prev.start + prev.length) return false; + if (curr.length < 0) return false; + + tracks.push_back(curr); + return true; +} + +bool CDROM_Interface_Image::HasDataTrack(void) +{ + //Data track has attribute 0x14 + for(track_it it = tracks.begin(); it != tracks.end(); it++) { + if ((*it).attr == DATA_TRACK) return true; + } + return false; +} + +bool CDROM_Interface_Image::HasAudioTracks(void) +{ + for(track_it it = tracks.begin(); it != tracks.end(); it++) { + if ((*it).attr == AUDIO_TRACK) return true; + } + return false; +} + + +bool CDROM_Interface_Image::GetRealFileName(string &filename, string &pathname) +{ + // check if file exists + struct stat test; + if (stat(filename.c_str(), &test) == 0) return true; + + // check if file with path relative to cue file exists + string tmpstr(pathname + "/" + filename); + if (stat(tmpstr.c_str(), &test) == 0) { + filename = tmpstr; + return true; + } +#if defined (WIN32) || defined(OS2) + //Nothing +#else + //Consider the possibility that the filename has a windows directory seperator (inside the CUE file) + //which is common for some commercial rereleases of DOS games using DOSBox + + string copy = filename; + size_t l = copy.size(); + for (size_t i = 0; i < l;i++) { + if(copy[i] == '\\') copy[i] = '/'; + } + + if (stat(copy.c_str(), &test) == 0) { + filename = copy; + return true; + } + + tmpstr = pathname + "/" + copy; + if (stat(tmpstr.c_str(), &test) == 0) { + filename = tmpstr; + return true; + } + +#endif + return false; +} + +bool CDROM_Interface_Image::GetCueKeyword(string &keyword, istream &in) +{ + in >> keyword; + for(Bitu i = 0; i < keyword.size(); i++) keyword[i] = toupper(keyword[i]); + + return true; +} + +bool CDROM_Interface_Image::GetCueFrame(int &frames, istream &in) +{ + string msf; + in >> msf; + int min, sec, fr; + bool success = sscanf(msf.c_str(), "%d:%d:%d", &min, &sec, &fr) == 3; + frames = MSF_TO_FRAMES(min, sec, fr); + + return success; +} + +bool CDROM_Interface_Image::GetCueString(string &str, istream &in) +{ + int pos = (int)in.tellg(); + in >> str; + if (str[0] == '\"') { + if (str[str.size() - 1] == '\"') { + str.assign(str, 1, str.size() - 2); + } else { + in.seekg(pos, ios::beg); + char buffer[MAX_FILENAME_LENGTH]; + in.getline(buffer, MAX_FILENAME_LENGTH, '\"'); // skip + in.getline(buffer, MAX_FILENAME_LENGTH, '\"'); + str = buffer; + } + } + return true; +} + +void CDROM_Interface_Image::ClearTracks() +{ + vector::iterator i = tracks.begin(); + vector::iterator end = tracks.end(); + + TrackFile* last = NULL; + while(i != end) { + Track &curr = *i; + if (curr.file != last) { + delete curr.file; + last = curr.file; + } + i++; + } + tracks.clear(); +} diff --git a/src/cdrom_dosbox.h b/src/cdrom_dosbox.h new file mode 100644 index 000000000..39ed79bed --- /dev/null +++ b/src/cdrom_dosbox.h @@ -0,0 +1,173 @@ +/* + * Copyright (C) 2002-2015 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* Modified for use with PCem by bit */ + +#ifndef __CDROM_INTERFACE__ +#define __CDROM_INTERFACE__ + +#include +#include +#include +#include +#include +#include +//#include "dosbox.h" +//#include "mem.h" +//#include "mixer.h" +//#include "SDL.h" +//#include "SDL_thread.h" + +#include +typedef signed int Bits; +typedef unsigned int Bitu; +typedef int8_t Bit8s; +typedef uint8_t Bit8u; +typedef int16_t Bit16s; +typedef uint16_t Bit16u; +typedef int32_t Bit32s; +typedef uint32_t Bit32u; + +typedef size_t PhysPt; + +#define RAW_SECTOR_SIZE 2352 +#define COOKED_SECTOR_SIZE 2048 + +#define DATA_TRACK 0x14 +#define AUDIO_TRACK 0x10 + +#define CD_FPS 75 +#define FRAMES_TO_MSF(f, M,S,F) { \ + int value = f; \ + *(F) = value%CD_FPS; \ + value /= CD_FPS; \ + *(S) = value%60; \ + value /= 60; \ + *(M) = value; \ +} +#define MSF_TO_FRAMES(M, S, F) ((M)*60*CD_FPS+(S)*CD_FPS+(F)) + + +typedef struct SMSF { + unsigned char min; + unsigned char sec; + unsigned char fr; +} TMSF; + +typedef struct SCtrl { + Bit8u out[4]; // output channel + Bit8u vol[4]; // channel volume +} TCtrl; + +extern int CDROM_GetMountType(char* path, int force); + +class CDROM_Interface +{ +public: +// CDROM_Interface (void); + virtual ~CDROM_Interface (void) {}; + + virtual bool SetDevice (char* path, int forceCD) = 0; + + virtual bool GetUPC (unsigned char& attr, char* upc) = 0; + + virtual bool GetAudioTracks (int& stTrack, int& end, TMSF& leadOut) = 0; + virtual bool GetAudioTrackInfo (int track, int& number, TMSF& start, unsigned char& attr) = 0; + virtual bool GetAudioSub (int sector, unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos) = 0; + virtual bool GetMediaTrayStatus (bool& mediaPresent, bool& mediaChanged, bool& trayOpen) = 0; + + virtual bool ReadSectors (PhysPt buffer, bool raw, unsigned long sector, unsigned long num) = 0; + + virtual bool LoadUnloadMedia (bool unload) = 0; + + virtual void InitNewMedia (void) {}; +}; + +class CDROM_Interface_Image : public CDROM_Interface +{ +private: + class TrackFile { + public: + virtual bool read(Bit8u *buffer, int seek, int count) = 0; + virtual int getLength() = 0; + virtual ~TrackFile() { }; + }; + + class BinaryFile : public TrackFile { + public: + BinaryFile(const char *filename, bool &error); + ~BinaryFile(); + bool read(Bit8u *buffer, int seek, int count); + int getLength(); + private: + BinaryFile(); + std::ifstream *file; + }; + + struct Track { + int number; + int track_number; + int attr; + int start; + int length; + int skip; + int sectorSize; + bool mode2; + TrackFile *file; + }; + +public: + CDROM_Interface_Image (); + virtual ~CDROM_Interface_Image (void); + void InitNewMedia (void); + bool SetDevice (char* path, int forceCD); + bool GetUPC (unsigned char& attr, char* upc); + bool GetAudioTracks (int& stTrack, int& end, TMSF& leadOut); + bool GetAudioTrackInfo (int track, int& number, TMSF& start, unsigned char& attr); + bool GetAudioSub (int sector, unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos); + bool GetMediaTrayStatus (bool& mediaPresent, bool& mediaChanged, bool& trayOpen); + bool ReadSectors (PhysPt buffer, bool raw, unsigned long sector, unsigned long num); + bool LoadUnloadMedia (bool unload); + bool ReadSector (Bit8u *buffer, bool raw, unsigned long sector); + bool IsMode2 (unsigned long sector); + bool HasDataTrack (void); + bool HasAudioTracks (void); + + int GetTrack (int sector); + +private: + // player +static void CDAudioCallBack(Bitu len); + + void ClearTracks(); + bool LoadIsoFile(char *filename); + bool CanReadPVD(TrackFile *file, int sectorSize, bool mode2); + // cue sheet processing + bool LoadCueSheet(char *cuefile); + bool GetRealFileName(std::string& filename, std::string& pathname); + bool GetCueKeyword(std::string &keyword, std::istream &in); + bool GetCueFrame(int &frames, std::istream &in); + bool GetCueString(std::string &str, std::istream &in); + bool AddTrack(Track &curr, int &shift, int prestart, int &totalPregap, int currPregap); + + std::vector tracks; +typedef std::vector::iterator track_it; + std::string mcn; +}; + +#endif /* __CDROM_INTERFACE__ */ diff --git a/src/cdrom_image.cc b/src/cdrom_image.cc new file mode 100644 index 000000000..831255db8 --- /dev/null +++ b/src/cdrom_image.cc @@ -0,0 +1,1045 @@ +/* Copyright holders: RichardG867, Tenshi, bit + see COPYING for more details +*/ +/*CD-ROM image support*/ + +#include + +#include "config.h" +#include "cdrom_dosbox.h" +#include "cdrom.h" +#include "cdrom_image.h" +#include "cdrom_null.h" + +#define __USE_LARGEFILE64 +#define _LARGEFILE_SOURCE +#define _LARGEFILE64_SOURCE + +#include + +#define CD_STATUS_EMPTY 0 +#define CD_STATUS_DATA_ONLY 1 +#define CD_STATUS_PLAYING 2 +#define CD_STATUS_PAUSED 3 +#define CD_STATUS_STOPPED 4 + +/* The addresses sent from the guest are absolute, ie. a LBA of 0 corresponds to a MSF of 00:00:00. Otherwise, the counter displayed by the guest is wrong: + there is a seeming 2 seconds in which audio plays but counter does not move, while a data track before audio jumps to 2 seconds before the actual start + of the audio while audio still plays. With an absolute conversion, the counter is fine. */ +#define MSFtoLBA(m,s,f) ((((m*60)+s)*75)+f) + +extern CDROM image_cdrom; + +enum +{ + CD_STOPPED = 0, + CD_PLAYING, + CD_PAUSED +}; + +int cdrom_image_do_log = 0; + +CDROM_Interface_Image* cdimg[CDROM_NUM] = { NULL, NULL, NULL, NULL }; + +void cdrom_image_log(const char *format, ...) +{ +#ifdef ENABLE_CDROM_IMAGE_LOG + if (cdrom_image_do_log) + { + va_list ap; + va_start(ap, format); + vprintf(format, ap); + va_end(ap); + fflush(stdout); + } +#endif +} + +void image_close(uint8_t id); + +void image_audio_callback(uint8_t id, int16_t *output, int len) +{ + if ((cdrom_image[id].cd_state != CD_PLAYING) || (cdrom_image[id].image_is_iso)) + { + memset(output, 0, len * 2); + return; + } + while (cdrom_image[id].cd_buflen < len) + { + if (cdrom[id].seek_pos < cdrom_image[id].cd_end) + { + if (!cdimg[id]->ReadSector((unsigned char*)&cdrom_image[id].cd_buffer[cdrom_image[id].cd_buflen], true, cdrom[id].seek_pos - 150)) + { + memset(&cdrom_image[id].cd_buffer[cdrom_image[id].cd_buflen], 0, (BUF_SIZE - cdrom_image[id].cd_buflen) * 2); + cdrom_image[id].cd_state = CD_STOPPED; + cdrom_image[id].cd_buflen = len; + } + else + { + cdrom[id].seek_pos++; + cdrom_image[id].cd_buflen += (RAW_SECTOR_SIZE / 2); + } + } + else + { + memset(&cdrom_image[id].cd_buffer[cdrom_image[id].cd_buflen], 0, (BUF_SIZE - cdrom_image[id].cd_buflen) * 2); + cdrom_image[id].cd_state = CD_STOPPED; + cdrom_image[id].cd_buflen = len; + } + } + memcpy(output, cdrom_image[id].cd_buffer, len * 2); + memmove(cdrom_image[id].cd_buffer, &cdrom_image[id].cd_buffer[len], (BUF_SIZE - len) * 2); + cdrom_image[id].cd_buflen -= len; +} + +void image_audio_stop(uint8_t id) +{ + cdrom_image[id].cd_state = CD_STOPPED; +} + +static void image_playaudio(uint8_t id, uint32_t pos, uint32_t len, int ismsf) +{ + if (!cdimg[id]) return; + int number; + unsigned char attr; + TMSF tmsf; + int m = 0, s = 0, f = 0; + uint32_t start_msf = 0, end_msf = 0; + cdimg[id]->GetAudioTrackInfo(cdimg[id]->GetTrack(pos), number, tmsf, attr); + if (attr == DATA_TRACK) + { + cdrom_image_log("Can't play data track\n"); + cdrom[id].seek_pos = 0; + cdrom_image[id].cd_state = CD_STOPPED; + return; + } + cdrom_image_log("Play audio - %08X %08X %i\n", pos, len, ismsf); + if (ismsf == 2) + { + cdimg[id]->GetAudioTrackInfo(pos, number, tmsf, attr); + pos = MSFtoLBA(tmsf.min, tmsf.sec, tmsf.fr); + cdimg[id]->GetAudioTrackInfo(len, number, tmsf, attr); + len = MSFtoLBA(tmsf.min, tmsf.sec, tmsf.fr); + } + else if (ismsf == 1) + { + m = (pos >> 16) & 0xff; + s = (pos >> 8) & 0xff; + f = pos & 0xff; + + if (pos == 0xffffff) + { + cdrom_image_log("Playing from current position (MSF)\n"); + pos = cdrom[id].seek_pos; + } + else + { + pos = MSFtoLBA(m, s, f); + } + + m = (len >> 16) & 0xff; + s = (len >> 8) & 0xff; + f = len & 0xff; + len = MSFtoLBA(m, s, f); + + cdrom_image_log("MSF - pos = %08X len = %08X\n", pos, len); + } + else if (ismsf == 0) + { + if (pos == 0xffffffff) + { + cdrom_image_log("Playing from current position\n"); + pos = cdrom[id].seek_pos; + } + len += pos; + } + cdrom[id].seek_pos = pos; + cdrom_image[id].cd_end = len; + cdrom_image[id].cd_state = CD_PLAYING; + if (cdrom[id].seek_pos < 150) + cdrom[id].seek_pos = 150; + cdrom_image[id].cd_buflen = 0; +} + +static void image_pause(uint8_t id) +{ + if (!cdimg[id] || cdrom_image[id].image_is_iso) return; + if (cdrom_image[id].cd_state == CD_PLAYING) + cdrom_image[id].cd_state = CD_PAUSED; +} + +static void image_resume(uint8_t id) +{ + if (!cdimg[id] || cdrom_image[id].image_is_iso) return; + if (cdrom_image[id].cd_state == CD_PAUSED) + cdrom_image[id].cd_state = CD_PLAYING; +} + +static void image_stop(uint8_t id) +{ + if (!cdimg[id] || cdrom_image[id].image_is_iso) return; + cdrom_image[id].cd_state = CD_STOPPED; +} + +static void image_seek(uint8_t id, uint32_t pos) +{ + if (!cdimg[id] || cdrom_image[id].image_is_iso) return; + cdrom_image[id].cd_pos = pos; + cdrom_image[id].cd_state = CD_STOPPED; +} + +static int image_ready(uint8_t id) +{ + if (!cdimg[id]) + return 0; + + if (wcslen(cdrom_image[id].image_path) == 0) + return 0; + + if (cdrom_drives[id].prev_host_drive != cdrom_drives[id].host_drive) + { + return 1; + } + + if (cdrom_image[id].image_changed) + { + cdrom_image[id].image_changed = 0; + return 1; + } + + return 1; +} + +static int image_get_last_block(uint8_t id, uint8_t starttrack, int msf, int maxlen, int single) +{ + int c; + uint32_t lb=0; + + if (!cdimg[id]) return 0; + + int first_track; + int last_track; + int number; + unsigned char attr; + TMSF tmsf; + cdimg[id]->GetAudioTracks(first_track, last_track, tmsf); + + for (c = 0; c <= last_track; c++) + { + uint32_t address; + cdimg[id]->GetAudioTrackInfo(c+1, number, tmsf, attr); + address = MSFtoLBA(tmsf.min, tmsf.sec, tmsf.fr) - 150; /* Do the - 150 here as well. */ + if (address > lb) + lb = address; + } + return lb; +} + +static int image_medium_changed(uint8_t id) +{ + if (!cdimg[id]) + return 0; + + if (wcslen(cdrom_image[id].image_path) == 0) + { + return 0; + } + + if (cdrom_drives[id].prev_host_drive != cdrom_drives[id].host_drive) + { + cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; + return 1; + } + + if (cdrom_image[id].image_changed) + { + cdrom_image[id].image_changed = 0; + return 1; + } + + return 0; +} + +static uint8_t image_getcurrentsubchannel(uint8_t id, uint8_t *b, int msf) +{ + if (!cdimg[id]) return 0; + uint8_t ret; + int pos=0; + + uint32_t cdpos = cdrom[id].seek_pos; + if (cdpos >= 150) cdpos -= 150; + TMSF relPos, absPos; + unsigned char attr, track, index; + cdimg[id]->GetAudioSub(cdpos, attr, track, index, relPos, absPos); + + if (cdrom_image[id].image_is_iso) + { + ret = 0x15; + } + else + { + if (cdrom_image[id].cd_state == CD_PLAYING) + ret = 0x11; + else if (cdrom_image[id].cd_state == CD_PAUSED) + ret = 0x12; + else + ret = 0x13; + } + + b[pos++] = attr; + b[pos++] = track; + b[pos++] = index; + + if (msf) + { + uint32_t dat = MSFtoLBA(absPos.min, absPos.sec, absPos.fr); + b[pos + 3] = (uint8_t)(dat % 75); dat /= 75; + b[pos + 2] = (uint8_t)(dat % 60); dat /= 60; + b[pos + 1] = (uint8_t)dat; + b[pos] = 0; + pos += 4; + dat = MSFtoLBA(relPos.min, relPos.sec, relPos.fr); + b[pos + 3] = (uint8_t)(dat % 75); dat /= 75; + b[pos + 2] = (uint8_t)(dat % 60); dat /= 60; + b[pos + 1] = (uint8_t)dat; + b[pos] = 0; + pos += 4; + } + else + { + uint32_t dat = MSFtoLBA(absPos.min, absPos.sec, absPos.fr); + b[pos++] = (dat >> 24) & 0xff; + b[pos++] = (dat >> 16) & 0xff; + b[pos++] = (dat >> 8) & 0xff; + b[pos++] = dat & 0xff; + dat = MSFtoLBA(relPos.min, relPos.sec, relPos.fr); + b[pos++] = (dat >> 24) & 0xff; + b[pos++] = (dat >> 16) & 0xff; + b[pos++] = (dat >> 8) & 0xff; + b[pos++] = dat & 0xff; + } + + return ret; +} + +static void image_eject(uint8_t id) +{ + return; +} + +static void image_load(uint8_t id) +{ + return; +} + +static int image_is_track_audio(uint8_t id, uint32_t pos, int ismsf) +{ + int m, s, f; + unsigned char attr; + TMSF tmsf; + int number; + + if (!cdimg[id] || cdrom_image[id].image_is_iso) return 0; + + if (ismsf) + { + m = (pos >> 16) & 0xff; + s = (pos >> 8) & 0xff; + f = pos & 0xff; + pos = MSFtoLBA(m, s, f); + } + else + { + pos += 150; + } + + cdimg[id]->GetAudioTrackInfo(cdimg[id]->GetTrack(pos), number, tmsf, attr); + + return attr == AUDIO_TRACK; +} + +typedef struct __attribute__((__packed__)) +{ + uint8_t user_data[2048]; + uint8_t ecc[288]; +} m1_data_t; + +typedef struct __attribute__((__packed__)) +{ + uint8_t sub_header[8]; + uint8_t user_data[2328]; +} m2_data_t; + +typedef union __attribute__((__packed__)) +{ + m1_data_t m1_data; + m2_data_t m2_data; + uint8_t raw_data[2336]; +} sector_data_t; + +typedef struct __attribute__((__packed__)) +{ + uint8_t sync[12]; + uint8_t header[4]; + sector_data_t data; +} sector_raw_data_t; + +typedef union __attribute__((__packed__)) +{ + sector_raw_data_t sector_data; + uint8_t raw_data[2352]; +} sector_t; + +typedef struct __attribute__((__packed__)) +{ + sector_t sector; + uint8_t c2[296]; + uint8_t subchannel_raw[96]; + uint8_t subchannel_q[16]; + uint8_t subchannel_rw[96]; +} cdrom_sector_t; + +typedef union __attribute__((__packed__)) +{ + cdrom_sector_t cdrom_sector; + uint8_t buffer[2856]; +} sector_buffer_t; + +sector_buffer_t cdrom_sector_buffer; + +int cdrom_sector_size; +uint8_t raw_buffer[2352]; +uint8_t extra_buffer[296]; + +static int image_readsector_raw(uint8_t id, uint8_t *buffer, int sector, int ismsf, int cdrom_sector_type, int cdrom_sector_flags, int *len) +{ + uint8_t *b; + uint8_t *temp_b; + int real_pos; + int audio; + int mode2; + + if (!cdimg[id]) + { + return 0; + } + + if (!cdrom_drives[id].host_drive) + { + return 0; + } + + b = temp_b = buffer; + + *len = 0; + + if (ismsf) + { + real_pos = cdrom_lba_to_msf_accurate(sector); + } + else + { + real_pos = sector; + } + + if (cdrom_image[id].image_is_iso) + { + audio = 0; + mode2 = 0; + } + else + { + audio = image_is_track_audio(id, real_pos, 1); + mode2 = cdimg[id]->IsMode2(real_pos) ? 1 : 0; + } + + memset(raw_buffer, 0, 2352); + memset(extra_buffer, 0, 296); + + if (!(cdrom_sector_flags & 0xf0)) /* 0x00 and 0x08 are illegal modes */ + { + cdrom_image_log("CD-ROM %i: [Mode 1] 0x00 and 0x08 are illegal modes\n", id); + return 0; + } + + if ((cdrom_sector_type == 3) || (cdrom_sector_type > 4)) + { + if (cdrom_sector_type == 3) + { + cdrom_image_log("CD-ROM %i: Attempting to read a Yellowbook Mode 2 data sector from an image\n", id); + } + if (cdrom_sector_type > 4) + { + cdrom_image_log("CD-ROM %i: Attempting to read a XA Mode 2 Form 2 data sector from an image\n", id); + } + return 0; + } + else if (cdrom_sector_type == 1) + { + if (!audio || cdrom_image[id].image_is_iso) + { + cdrom_image_log("CD-ROM %i: [Audio] Attempting to read an audio sector from a data image\n", id); + return 0; + } + +read_audio: + cdimg[id]->ReadSector(raw_buffer, true, real_pos); + memcpy(temp_b, raw_buffer, 2352); + } + else if (cdrom_sector_type == 2) + { + if (audio || mode2) + { + cdrom_image_log("CD-ROM %i: [Mode 1] Attempting to read a non-Mode 1 sector from an audio track\n", id); + return 0; + } + +read_mode1: + if ((cdrom_sector_flags & 0x06) == 0x06) + { + cdrom_image_log("CD-ROM %i: [Mode 1] Invalid error flags\n", id); + return 0; + } + + if (((cdrom_sector_flags & 0x700) == 0x300) || ((cdrom_sector_flags & 0x700) > 0x400)) + { + cdrom_image_log("CD-ROM %i: [Mode 1] Invalid subchannel data flags (%02X)\n", id, cdrom_sector_flags & 0x700); + return 0; + } + + if ((cdrom_sector_flags & 0x18) == 0x08) /* EDC/ECC without user data is an illegal mode */ + { + cdrom_image_log("CD-ROM %i: [Mode 1] EDC/ECC without user data is an illegal mode\n", id); + return 0; + } + + if (cdrom_image[id].image_is_iso) + { + cdimg[id]->ReadSector(raw_buffer + 16, false, real_pos); + + uint8_t *bb = raw_buffer; + + /* sync bytes */ + bb[0] = 0; + memset(bb + 1, 0xff, 10); + bb[11] = 0; + bb += 12; + + bb[0] = (real_pos >> 16) & 0xff; + bb[1] = (real_pos >> 8) & 0xff; + bb[2] = real_pos & 0xff; + + bb[3] = 1; /* mode 1 data */ + bb += 4; + bb += 2048; + memset(bb, 0, 288); + } + else + { + cdimg[id]->ReadSector(raw_buffer, true, real_pos); + } + + cdrom_sector_size = 0; + + if (cdrom_sector_flags & 0x80) /* Sync */ + { + cdrom_image_log("CD-ROM %i: [Mode 1] Sync\n", id); + memcpy(temp_b, raw_buffer, 12); + cdrom_sector_size += 12; + temp_b += 12; + } + + if (cdrom_sector_flags & 0x20) /* Header */ + { + cdrom_image_log("CD-ROM %i: [Mode 1] Header\n", id); + memcpy(temp_b, raw_buffer + 12, 4); + cdrom_sector_size += 4; + temp_b += 4; + } + + /* Mode 1 sector, expected type is 1 type. */ + if (cdrom_sector_flags & 0x40) /* Sub-header */ + { + if (!(cdrom_sector_flags & 0x10)) /* No user data */ + { + cdrom_image_log("CD-ROM %i: [Mode 1] Sub-header\n", id); + memcpy(temp_b, raw_buffer + 16, 8); + cdrom_sector_size += 8; + temp_b += 8; + } + } + + if (cdrom_sector_flags & 0x10) /* User data */ + { + cdrom_image_log("CD-ROM %i: [Mode 1] User data\n", id); + memcpy(temp_b, raw_buffer + 16, 2048); + cdrom_sector_size += 2048; + temp_b += 2048; + } + + if (cdrom_sector_flags & 0x08) /* EDC/ECC */ + { + cdrom_image_log("CD-ROM %i: [Mode 1] EDC/ECC\n", id); + memcpy(temp_b, raw_buffer + 2064, 288); + cdrom_sector_size += 288; + temp_b += 288; + } + } + else if (cdrom_sector_type == 4) + { + if (audio || !mode2 || cdrom_image[id].image_is_iso) + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] Attempting to read a non-XA Mode 2 Form 1 sector from an audio track\n", id); + return 0; + } + +read_mode2: + if (!(cdrom_sector_flags & 0xf0)) /* 0x00 and 0x08 are illegal modes */ + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] 0x00 and 0x08 are illegal modes\n", id); + return 0; + } + + if (((cdrom_sector_flags & 0xf0) == 0xb0) || ((cdrom_sector_flags & 0xf0) == 0xd0)) /* 0xBx and 0xDx are illegal modes */ + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] 0xBx and 0xDx are illegal modes\n", id); + return 0; + } + + if ((cdrom_sector_flags & 0x06) == 0x06) + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] Invalid error flags\n", id); + return 0; + } + + if (((cdrom_sector_flags & 0x700) == 0x300) || ((cdrom_sector_flags & 0x700) > 0x400)) + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] Invalid subchannel data flags (%02X)\n", id, cdrom_sector_flags & 0x700); + return 0; + } + + if ((cdrom_sector_flags & 0x18) == 0x08) /* EDC/ECC without user data is an illegal mode */ + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] EDC/ECC without user data is an illegal mode\n", id); + return 0; + } + + cdimg[id]->ReadSector(cdrom_sector_buffer.buffer, true, real_pos); + + cdrom_sector_size = 0; + + if (cdrom_sector_flags & 0x80) /* Sync */ + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] Sync\n", id); + memcpy(temp_b, raw_buffer, 12); + cdrom_sector_size += 12; + temp_b += 12; + } + + if (cdrom_sector_flags & 0x20) /* Header */ + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] Header\n", id); + memcpy(temp_b, raw_buffer + 12, 4); + cdrom_sector_size += 4; + temp_b += 4; + } + + /* Mode 1 sector, expected type is 1 type. */ + if (cdrom_sector_flags & 0x40) /* Sub-header */ + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] Sub-header\n", id); + memcpy(temp_b, raw_buffer + 16, 8); + cdrom_sector_size += 8; + temp_b += 8; + } + + if (cdrom_sector_flags & 0x10) /* User data */ + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] User data\n", id); + memcpy(temp_b, raw_buffer + 24, 2048); + cdrom_sector_size += 2048; + temp_b += 2048; + } + + if (cdrom_sector_flags & 0x08) /* EDC/ECC */ + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] EDC/ECC\n", id); + memcpy(temp_b, raw_buffer + 2072, 280); + cdrom_sector_size += 280; + temp_b += 280; + } + } + else + { + if (mode2) + { + goto read_mode2; + } + else + { + if (audio) + { + goto read_audio; + } + else + { + goto read_mode1; + } + } + } + + if ((cdrom_sector_flags & 0x06) == 0x02) + { + /* Add error flags. */ + cdrom_image_log("CD-ROM %i: Error flags\n", id); + memcpy(b + cdrom_sector_size, extra_buffer, 294); + cdrom_sector_size += 294; + } + else if ((cdrom_sector_flags & 0x06) == 0x04) + { + /* Add error flags. */ + cdrom_image_log("CD-ROM %i: Full error flags\n", id); + memcpy(b + cdrom_sector_size, extra_buffer, 296); + cdrom_sector_size += 296; + } + + if ((cdrom_sector_flags & 0x700) == 0x100) + { + cdrom_image_log("CD-ROM %i: Raw subchannel data\n", id); + memcpy(b + cdrom_sector_size, extra_buffer, 96); + cdrom_sector_size += 96; + } + else if ((cdrom_sector_flags & 0x700) == 0x200) + { + cdrom_image_log("CD-ROM %i: Q subchannel data\n", id); + memcpy(b + cdrom_sector_size, extra_buffer, 16); + cdrom_sector_size += 16; + } + else if ((cdrom_sector_flags & 0x700) == 0x400) + { + cdrom_image_log("CD-ROM %i: R/W subchannel data\n", id); + memcpy(b + cdrom_sector_size, extra_buffer, 96); + cdrom_sector_size += 96; + } + + *len = cdrom_sector_size; + + return 1; +} + + +static void lba_to_msf(uint8_t *buf, int lba) +{ + lba += 150; + buf[0] = (lba / 75) / 60; + buf[1] = (lba / 75) % 60; + buf[2] = lba % 75; +} + +static uint32_t image_size(uint8_t id) +{ + return cdrom_image[id].cdrom_capacity; +} + +static int image_readtoc(uint8_t id, unsigned char *b, unsigned char starttrack, int msf, int maxlen, int single) +{ + if (!cdimg[id]) return 0; + int len=4; + int c,d; + uint32_t temp; + + int first_track; + int last_track; + int number; + unsigned char attr; + TMSF tmsf; + cdimg[id]->GetAudioTracks(first_track, last_track, tmsf); + + b[2] = first_track; + b[3] = last_track; + + d = 0; + for (c = 0; c <= last_track; c++) + { + cdimg[id]->GetAudioTrackInfo(c+1, number, tmsf, attr); + if (number >= starttrack) + { + d=c; + break; + } + } + cdimg[id]->GetAudioTrackInfo(c+1, number, tmsf, attr); + b[2] = number; + + for (c = d; c <= last_track; c++) + { + if ((len + 8) > maxlen) + break; + cdimg[id]->GetAudioTrackInfo(c+1, number, tmsf, attr); + +// pclog("Len %i max %i Track %02X - %02X %02X %02i:%02i:%02i %08X\n",len,maxlen,toc[c].cdte_track,toc[c].cdte_adr,toc[c].cdte_ctrl,toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame,MSFtoLBA(toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame)); + b[len++] = 0; /* reserved */ + b[len++] = attr; + b[len++] = number; /* track number */ + b[len++] = 0; /* reserved */ + + if (msf) + { + b[len++] = 0; + b[len++] = tmsf.min; + b[len++] = tmsf.sec; + b[len++] = tmsf.fr; + } + else + { + temp = MSFtoLBA(tmsf.min, tmsf.sec, tmsf.fr) - 150; + b[len++] = temp >> 24; + b[len++] = temp >> 16; + b[len++] = temp >> 8; + b[len++] = temp; + } + if (single) + break; + } + b[0] = (uint8_t)(((len-2) >> 8) & 0xff); + b[1] = (uint8_t)((len-2) & 0xff); + /* + pclog("Table of Contents:\n"); + pclog("First track - %02X\n", first_track); + pclog("Last track - %02X\n", last_track); + for (c = 0; c <= last_track; c++) + { + cdimg[id]->GetAudioTrackInfo(c+1, number, tmsf, attr); + pclog("Track %02X - number %02X control %02X adr %02X address %02X %02X %02X %02X\n", c, number, attr, 0, 0, tmsf.min, tmsf.sec, tmsf.fr); + } + for (c = 0;c <= last_track; c++) { + cdimg[id]->GetAudioTrackInfo(c+1, number, tmsf, attr); + pclog("Track %02X - number %02X control %02X adr %02X address %06X\n", c, number, attr, 0, MSF_TO_FRAMES(tmsf.min, tmsf.sec, tmsf.fr)); + } + */ + return len; +} + +static int image_readtoc_session(uint8_t id, unsigned char *b, int msf, int maxlen) +{ + int len = 4; + + int number; + TMSF tmsf; + unsigned char attr; + + if (!cdimg[id]) return 0; + + cdimg[id]->GetAudioTrackInfo(1, number, tmsf, attr); + + if (number == 0) + { + number = 1; + } + + b[2] = 1; + b[3] = 1; + b[len++] = 0; /* reserved */ + b[len++] = attr; + b[len++] = number; /* track number */ + b[len++] = 0; /* reserved */ + if (msf) + { + b[len++] = 0; + b[len++] = tmsf.min; + b[len++] = tmsf.sec; + b[len++] = tmsf.fr; + } + else + { + uint32_t temp = MSFtoLBA(tmsf.min, tmsf.sec, tmsf.fr) - 150; /* Do the - 150. */ + b[len++] = temp >> 24; + b[len++] = temp >> 16; + b[len++] = temp >> 8; + b[len++] = temp; + } + + if (maxlen < len) + { + return maxlen; + } + + return len; +} + +static int image_readtoc_raw(uint8_t id, unsigned char *b, int msf, int maxlen) +{ + int track; + int len = 4; + + int first_track; + int last_track; + int number; + unsigned char attr; + TMSF tmsf; + int lb; + + if (!cdimg[id]) return 0; + + cdimg[id]->GetAudioTracks(first_track, last_track, tmsf); + + b[2] = first_track; + b[3] = last_track; + + for (track = first_track; track <= last_track; track++) + { + if ((len + 11) > maxlen) + { + cdrom_image_log("image_readtocraw: This iteration would fill the buffer beyond the bounds, aborting...\n"); + return len; + } + + cdimg[id]->GetAudioTrackInfo(track, number, tmsf, attr); + + b[len++] = track; + b[len++]= attr; + b[len++]=0; + b[len++]=0; + b[len++]=0; + b[len++]=0; + b[len++]=0; + b[len++]=0; + b[len++] = tmsf.min; + b[len++] = tmsf.sec; + b[len++] = tmsf.fr; + } + return len; +} + +static int image_status(uint8_t id) +{ + if (!cdimg[id]) return CD_STATUS_EMPTY; + if (cdrom_image[id].image_is_iso) return CD_STATUS_DATA_ONLY; + if (cdimg[id]->HasAudioTracks()) + { + switch(cdrom_image[id].cd_state) + { + case CD_PLAYING: + return CD_STATUS_PLAYING; + case CD_PAUSED: + return CD_STATUS_PAUSED; + case CD_STOPPED: + default: + return CD_STATUS_STOPPED; + } + } + return CD_STATUS_DATA_ONLY; +} + +void image_reset(uint8_t id) +{ +} + +void image_close(uint8_t id) +{ + cdrom_image[id].cd_state = CD_STOPPED; + if (cdimg[id]) + { + delete cdimg[id]; + cdimg[id] = NULL; + } + memset(cdrom_image[id].image_path, 0, 2048); +} + +static char afn[1024]; + +int image_open(uint8_t id, wchar_t *fn) +{ + if (wcscmp(fn, cdrom_image[id].image_path) != 0) + { + cdrom_image[id].image_changed = 1; + } + + /* Make sure image_changed stays when changing from an image to another image. */ + if (!cdrom_image[id].image_inited && (cdrom_drives[id].host_drive != 200)) cdrom_image[id].image_changed = 0; + + if (!cdrom_image[id].image_inited || cdrom_image[id].image_changed) + { + _swprintf(cdrom_image[id].image_path, L"%ws", fn); + } + + if (!wcsicmp(get_extension_w(fn), L"ISO")) + { + cdrom_image[id].image_is_iso = 1; + } + else + { + cdrom_image[id].image_is_iso = 0; + } + + cdimg[id] = new CDROM_Interface_Image(); + wcstombs(afn, fn, (wcslen(fn) << 1) + 2); + if (!cdimg[id]->SetDevice(afn, false)) + { + image_close(id); + cdrom_set_null_handler(id); + return 1; + } + cdrom_image[id].cd_state = CD_STOPPED; + cdrom[id].seek_pos = 0; + cdrom_image[id].cd_buflen = 0; + cdrom_image[id].cdrom_capacity = image_get_last_block(id, 0, 0, 4096, 0) + 1; + cdrom_drives[id].handler = &image_cdrom; + + if (!cdrom_image[id].image_inited || cdrom_image[id].image_changed) + { + if (!cdrom_image[id].image_inited) + cdrom_image[id].image_inited = 1; + } + + update_status_bar_icon_state(0x10 | id, 0); + return 0; +} + +static void image_exit(uint8_t id) +{ + cdrom_image[id].image_inited = 0; +} + +/* TODO: Check for what data type a mixed CD is. */ +static int image_media_type_id(uint8_t id) +{ + if (!cdrom_image[id].image_is_iso) + { + return 3; /* Mixed mode CD. */ + } + + if (image_size(id) <= 405000) + { + return 1; /* Data CD. */ + } + else + { + return 65; /* DVD. */ + } +} + +CDROM image_cdrom = +{ + image_ready, + image_medium_changed, + image_media_type_id, + image_audio_callback, + image_audio_stop, + image_readtoc, + image_readtoc_session, + image_readtoc_raw, + image_getcurrentsubchannel, + NULL, + image_readsector_raw, + image_playaudio, + image_load, + image_eject, + image_pause, + image_resume, + image_size, + image_status, + image_is_track_audio, + image_stop, + image_exit +}; diff --git a/src/cdrom_image.h b/src/cdrom_image.h new file mode 100644 index 000000000..4ea4cb78f --- /dev/null +++ b/src/cdrom_image.h @@ -0,0 +1,28 @@ +/* Copyright holders: RichardG867, Tenshi + see COPYING for more details +*/ +#ifndef CDROM_IMAGE_H +#define CDROM_IMAGE_H + +/* this header file lists the functions provided by + various platform specific cdrom-ioctl files */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int image_open(uint8_t id, wchar_t *fn); +extern void image_reset(uint8_t id); + +extern void image_close(uint8_t id); + +void update_status_bar_icon_state(int tag, int state); +extern void cdrom_set_null_handler(uint8_t id); + +void pclog(const char *format, ...); + +#ifdef __cplusplus +} +#endif + +#endif /* ! CDROM_IMAGE_H */ diff --git a/src/cdrom_ioctl.c b/src/cdrom_ioctl.c new file mode 100644 index 000000000..8d8e28612 --- /dev/null +++ b/src/cdrom_ioctl.c @@ -0,0 +1,1099 @@ +/* Copyright holders: Sarah Walker, Tenshi + see COPYING for more details +*/ +/*Win32 CD-ROM support via IOCTL*/ + +#define WINVER 0x0600 +#include +#include +#include "ntddcdrm.h" +#include "ntddscsi.h" +#include "ibm.h" +#include "cdrom.h" +#include "cdrom_ioctl.h" +#include "scsi.h" + +#define MSFtoLBA(m,s,f) ((((m*60)+s)*75)+f) + +static CDROM ioctl_cdrom; + +typedef struct +{ + HANDLE hIOCTL; + CDROM_TOC toc; +} cdrom_ioctl_windows_t; + +cdrom_ioctl_windows_t cdrom_ioctl_windows[CDROM_NUM]; + +enum +{ + CD_STOPPED = 0, + CD_PLAYING, + CD_PAUSED +}; + +int cdrom_ioctl_do_log = 0; + +void cdrom_ioctl_log(const char *format, ...) +{ +#ifdef ENABLE_CDROM_LOG + if (cdrom_ioctl_do_log) + { + va_list ap; + va_start(ap, format); + vprintf(format, ap); + va_end(ap); + fflush(stdout); + } +#endif +} + +void ioctl_audio_callback(uint8_t id, int16_t *output, int len) +{ + RAW_READ_INFO in; + DWORD count; + + if (cdrom_ioctl[id].cd_state != CD_PLAYING) + { + memset(output, 0, len * 2); + return; + } + while (cdrom_ioctl[id].cd_buflen < len) + { + if (cdrom[id].seek_pos < cdrom_ioctl[id].cd_end) + { + in.DiskOffset.LowPart = (cdrom[id].seek_pos - 150) * 2048; + in.DiskOffset.HighPart = 0; + in.SectorCount = 1; + in.TrackMode = CDDA; + ioctl_open(id, 0); + if (!DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_RAW_READ, &in, sizeof(in), &(cdrom_ioctl[id].cd_buffer[cdrom_ioctl[id].cd_buflen]), 2352, &count, NULL)) + { + memset(&(cdrom_ioctl[id].cd_buffer[cdrom_ioctl[id].cd_buflen]), 0, (BUF_SIZE - cdrom_ioctl[id].cd_buflen) * 2); + cdrom_ioctl[id].cd_state = CD_STOPPED; + cdrom_ioctl[id].cd_buflen = len; + } + else + { + cdrom[id].seek_pos++; + cdrom_ioctl[id].cd_buflen += (2352 / 2); + } + ioctl_close(id); + } + else + { + memset(&(cdrom_ioctl[id].cd_buffer[cdrom_ioctl[id].cd_buflen]), 0, (BUF_SIZE - cdrom_ioctl[id].cd_buflen) * 2); + cdrom_ioctl[id].cd_state = CD_STOPPED; + cdrom_ioctl[id].cd_buflen = len; + } + } + memcpy(output, cdrom_ioctl[id].cd_buffer, len * 2); + memcpy(&cdrom_ioctl[id].cd_buffer[0], &(cdrom_ioctl[id].cd_buffer[len]), (BUF_SIZE - len) * 2); + cdrom_ioctl[id].cd_buflen -= len; +} + +void ioctl_audio_stop(uint8_t id) +{ + cdrom_ioctl[id].cd_state = CD_STOPPED; +} + +static int get_track_nr(uint8_t id, uint32_t pos) +{ + int c; + int track = 0; + + if (!cdrom_ioctl[id].tocvalid) + { + return 0; + } + + if (cdrom_ioctl[id].last_track_pos == pos) + { + return cdrom_ioctl[id].last_track_nr; + } + + for (c = cdrom_ioctl_windows[id].toc.FirstTrack; c < cdrom_ioctl_windows[id].toc.LastTrack; c++) + { + uint32_t track_address = cdrom_ioctl_windows[id].toc.TrackData[c].Address[3] + + (cdrom_ioctl_windows[id].toc.TrackData[c].Address[2] * 75) + + (cdrom_ioctl_windows[id].toc.TrackData[c].Address[1] * 75 * 60); + + if (track_address <= pos) + { + track = c; + } + } + cdrom_ioctl[id].last_track_pos = pos; + cdrom_ioctl[id].last_track_nr = track; + + return track; +} + +static uint32_t get_track_msf(uint8_t id, uint32_t track_no) +{ + int c; + + if (!cdrom_ioctl[id].tocvalid) + { + return 0; + } + + for (c = cdrom_ioctl_windows[id].toc.FirstTrack; c < cdrom_ioctl_windows[id].toc.LastTrack; c++) + { + if (c == track_no) + { + return cdrom_ioctl_windows[id].toc.TrackData[c].Address[3] + (cdrom_ioctl_windows[id].toc.TrackData[c].Address[2] << 8) + (cdrom_ioctl_windows[id].toc.TrackData[c].Address[1] << 16); + } + } + return 0xffffffff; +} + +static void ioctl_playaudio(uint8_t id, uint32_t pos, uint32_t len, int ismsf) +{ + int m = 0, s = 0, f = 0; + uint32_t start_msf = 0, end_msf = 0; + if (!cdrom_drives[id].host_drive) + { + return; + } + if (ismsf == 2) + { + start_msf = get_track_msf(id, pos); + end_msf = get_track_msf(id, len); + if (start_msf == 0xffffffff) + { + return; + } + if (end_msf == 0xffffffff) + { + return; + } + m = (start_msf >> 16) & 0xff; + s = (start_msf >> 8) & 0xff; + f = start_msf & 0xff; + pos = MSFtoLBA(m, s, f); + m = (end_msf >> 16) & 0xff; + s = (end_msf >> 8) & 0xff; + f = end_msf & 0xff; + len = MSFtoLBA(m, s, f); + } + else if (ismsf == 1) + { + m = (pos >> 16) & 0xff; + s = (pos >> 8) & 0xff; + f = pos & 0xff; + + if (pos == 0xffffff) + { + cdrom_ioctl_log("Playing from current position (MSF)\n"); + pos = cdrom[id].seek_pos; + } + else + { + pos = MSFtoLBA(m, s, f); + } + + m = (len >> 16) & 0xff; + s = (len >> 8) & 0xff; + f = len & 0xff; + len = MSFtoLBA(m, s, f); + } + else if (ismsf == 0) + { + if (pos == 0xffffffff) + { + cdrom_ioctl_log("Playing from current position\n"); + pos = cdrom[id].seek_pos; + } + len += pos; + } + cdrom[id].seek_pos = pos; + cdrom_ioctl[id].cd_end = len; + if (cdrom[id].seek_pos < 150) + { + /* Adjust because the host expects a minimum adjusted LBA of 0 which is equivalent to an absolute LBA of 150. */ + cdrom[id].seek_pos = 150; + } + cdrom_ioctl[id].cd_state = CD_PLAYING; +} + +static void ioctl_pause(uint8_t id) +{ + if (!cdrom_drives[id].host_drive) + { + return; + } + if (cdrom_ioctl[id].cd_state == CD_PLAYING) + { + cdrom_ioctl[id].cd_state = CD_PAUSED; + } +} + +static void ioctl_resume(uint8_t id) +{ + if (!cdrom_drives[id].host_drive) + { + return; + } + if (cdrom_ioctl[id].cd_state == CD_PAUSED) + { + cdrom_ioctl[id].cd_state = CD_PLAYING; + } +} + +static void ioctl_stop(uint8_t id) +{ + if (!cdrom_drives[id].host_drive) + { + return; + } + cdrom_ioctl[id].cd_state = CD_STOPPED; +} + +static int ioctl_ready(uint8_t id) +{ + unsigned long size; + int temp; + CDROM_TOC ltoc; + if (!cdrom_drives[id].host_drive) + { + return 0; + } + ioctl_open(id, 0); + temp = DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, <oc, sizeof(ltoc), &size, NULL); + ioctl_close(id); + if (!temp) + { + return 0; + } + if ((ltoc.TrackData[ltoc.LastTrack].Address[1] != cdrom_ioctl_windows[id].toc.TrackData[cdrom_ioctl_windows[id].toc.LastTrack].Address[1]) || + (ltoc.TrackData[ltoc.LastTrack].Address[2] != cdrom_ioctl_windows[id].toc.TrackData[cdrom_ioctl_windows[id].toc.LastTrack].Address[2]) || + (ltoc.TrackData[ltoc.LastTrack].Address[3] != cdrom_ioctl_windows[id].toc.TrackData[cdrom_ioctl_windows[id].toc.LastTrack].Address[3]) || + !cdrom_ioctl[id].tocvalid || (cdrom_drives[id].host_drive != cdrom_drives[id].prev_host_drive)) + { + cdrom_ioctl[id].cd_state = CD_STOPPED; + if (cdrom_drives[id].host_drive != cdrom_drives[id].prev_host_drive) + { + cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; + } + return 1; + } + return 1; +} + +static int ioctl_get_last_block(uint8_t id, unsigned char starttrack, int msf, int maxlen, int single) +{ + unsigned long size; + int c, d = 0; + CDROM_TOC lbtoc; + int lb = 0; + if (!cdrom_drives[id].host_drive) + { + return 0; + } + cdrom_ioctl[id].cd_state = CD_STOPPED; + ioctl_open(id, 0); + DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, &lbtoc, sizeof(lbtoc), &size, NULL); + ioctl_close(id); + cdrom_ioctl[id].tocvalid=1; + for (c=d; c <= lbtoc.LastTrack; c++) + { + uint32_t address; + address = MSFtoLBA(cdrom_ioctl_windows[id].toc.TrackData[c].Address[1], cdrom_ioctl_windows[id].toc.TrackData[c].Address[2], cdrom_ioctl_windows[id].toc.TrackData[c].Address[3]); + if (address > lb) + { + lb = address; + } + } + return lb; +} + +static int ioctl_medium_changed(uint8_t id) +{ + unsigned long size; + int temp; + CDROM_TOC ltoc; + if (!cdrom_drives[id].host_drive) + { + return 0; /* This will be handled by the not ready handler instead. */ + } + ioctl_open(id, 0); + temp = DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, <oc,sizeof(ltoc), &size, NULL); + ioctl_close(id); + if (!temp) + { + return 0; /* Drive empty, a not ready handler matter, not disc change. */ + } + if (!cdrom_ioctl[id].tocvalid || (cdrom_drives[id].host_drive != cdrom_drives[id].prev_host_drive)) + { + cdrom_ioctl[id].cd_state = CD_STOPPED; + cdrom_ioctl_windows[id].toc = ltoc; + cdrom_ioctl[id].tocvalid = 1; + if (cdrom_drives[id].host_drive != cdrom_drives[id].prev_host_drive) + { + cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; + } + cdrom_ioctl[id].cdrom_capacity = ioctl_get_last_block(id, 0, 0, 4096, 0); + return 1; + } + else + { + if ((ltoc.TrackData[ltoc.LastTrack].Address[1] != cdrom_ioctl_windows[id].toc.TrackData[cdrom_ioctl_windows[id].toc.LastTrack].Address[1]) || + (ltoc.TrackData[ltoc.LastTrack].Address[2] != cdrom_ioctl_windows[id].toc.TrackData[cdrom_ioctl_windows[id].toc.LastTrack].Address[2]) || + (ltoc.TrackData[ltoc.LastTrack].Address[3] != cdrom_ioctl_windows[id].toc.TrackData[cdrom_ioctl_windows[id].toc.LastTrack].Address[3])) + { + cdrom_ioctl[id].cd_state = CD_STOPPED; + cdrom_ioctl_log("Setting TOC...\n"); + cdrom_ioctl_windows[id].toc = ltoc; + cdrom_ioctl[id].cdrom_capacity = ioctl_get_last_block(id, 0, 0, 4096, 0); + return 1; /* TOC mismatches. */ + } + } + return 0; /* None of the above, return 0. */ +} + +static uint8_t ioctl_getcurrentsubchannel(uint8_t id, uint8_t *b, int msf) +{ + CDROM_SUB_Q_DATA_FORMAT insub; + SUB_Q_CHANNEL_DATA sub; + unsigned long size; + int pos = 0, track; + uint32_t cdpos, track_address, dat; + + if (!cdrom_drives[id].host_drive) return 0; + + cdpos = cdrom[id].seek_pos; + + if (cdrom_ioctl[id].last_subchannel_pos == cdpos) + { + memcpy(&insub, cdrom_ioctl[id].sub_q_data_format, sizeof(insub)); + memcpy(&sub, cdrom_ioctl[id].sub_q_channel_data, sizeof(sub)); + } + else + { + insub.Format = IOCTL_CDROM_CURRENT_POSITION; + ioctl_open(id, 0); + DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_CDROM_READ_Q_CHANNEL,&insub,sizeof(insub),&sub,sizeof(sub),&size,NULL); + ioctl_close(id); + memset(cdrom_ioctl[id].sub_q_data_format, 0, 16); + memcpy(cdrom_ioctl[id].sub_q_data_format, &insub, sizeof(insub)); + memset(cdrom_ioctl[id].sub_q_channel_data, 0, 256); + memcpy(cdrom_ioctl[id].sub_q_channel_data, &sub, sizeof(sub)); + cdrom_ioctl[id].last_subchannel_pos = cdpos; + } + + if (cdrom_ioctl[id].cd_state == CD_PLAYING || cdrom_ioctl[id].cd_state == CD_PAUSED) + { + track = get_track_nr(id, cdpos); + track_address = cdrom_ioctl_windows[id].toc.TrackData[track].Address[3] + (cdrom_ioctl_windows[id].toc.TrackData[track].Address[2] * 75) + (cdrom_ioctl_windows[id].toc.TrackData[track].Address[1] * 75 * 60); + + cdrom_ioctl_log("cdpos = %i, track = %i, track_address = %i\n", cdpos, track, track_address); + + b[pos++] = sub.CurrentPosition.Control; + b[pos++] = track + 1; + b[pos++] = sub.CurrentPosition.IndexNumber; + + if (msf) + { + dat = cdpos; + b[pos + 3] = (uint8_t)(dat % 75); dat /= 75; + b[pos + 2] = (uint8_t)(dat % 60); dat /= 60; + b[pos + 1] = (uint8_t)dat; + b[pos] = 0; + pos += 4; + dat = cdpos - track_address; + b[pos + 3] = (uint8_t)(dat % 75); dat /= 75; + b[pos + 2] = (uint8_t)(dat % 60); dat /= 60; + b[pos + 1] = (uint8_t)dat; + b[pos] = 0; + pos += 4; + } + else + { + b[pos++] = (cdpos >> 24) & 0xff; + b[pos++] = (cdpos >> 16) & 0xff; + b[pos++] = (cdpos >> 8) & 0xff; + b[pos++] = cdpos & 0xff; + cdpos -= track_address; + b[pos++] = (cdpos >> 24) & 0xff; + b[pos++] = (cdpos >> 16) & 0xff; + b[pos++] = (cdpos >> 8) & 0xff; + b[pos++] = cdpos & 0xff; + } + + if (cdrom_ioctl[id].cd_state == CD_PLAYING) return 0x11; + return 0x12; + } + + b[pos++]=sub.CurrentPosition.Control; + b[pos++]=sub.CurrentPosition.TrackNumber; + b[pos++]=sub.CurrentPosition.IndexNumber; + + cdrom_ioctl_log("cdpos = %i, track_address = %i\n", MSFtoLBA(sub.CurrentPosition.AbsoluteAddress[1], sub.CurrentPosition.AbsoluteAddress[2], sub.CurrentPosition.AbsoluteAddress[3]), MSFtoLBA(sub.CurrentPosition.TrackRelativeAddress[1], sub.CurrentPosition.TrackRelativeAddress[2], sub.CurrentPosition.TrackRelativeAddress[3])); + + if (msf) + { + int c; + for (c = 0; c < 4; c++) + { + b[pos++] = sub.CurrentPosition.AbsoluteAddress[c]; + } + for (c = 0; c < 4; c++) + { + b[pos++] = sub.CurrentPosition.TrackRelativeAddress[c]; + } + } + else + { + uint32_t temp = MSFtoLBA(sub.CurrentPosition.AbsoluteAddress[1], sub.CurrentPosition.AbsoluteAddress[2], sub.CurrentPosition.AbsoluteAddress[3]); + b[pos++] = temp >> 24; + b[pos++] = temp >> 16; + b[pos++] = temp >> 8; + b[pos++] = temp; + temp = MSFtoLBA(sub.CurrentPosition.TrackRelativeAddress[1], sub.CurrentPosition.TrackRelativeAddress[2], sub.CurrentPosition.TrackRelativeAddress[3]); + b[pos++] = temp >> 24; + b[pos++] = temp >> 16; + b[pos++] = temp >> 8; + b[pos++] = temp; + } + + return 0x13; +} + +static void ioctl_eject(uint8_t id) +{ + unsigned long size; + if (!cdrom_drives[id].host_drive) + { + return; + } + cdrom_ioctl[id].cd_state = CD_STOPPED; + ioctl_open(id, 0); + DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_STORAGE_EJECT_MEDIA,NULL,0,NULL,0,&size,NULL); + ioctl_close(id); +} + +static void ioctl_load(uint8_t id) +{ + unsigned long size; + if (!cdrom_drives[id].host_drive) + { + return; + } + cdrom_ioctl[id].cd_state = CD_STOPPED; + ioctl_open(id, 0); + DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_STORAGE_LOAD_MEDIA,NULL,0,NULL,0,&size,NULL); + ioctl_close(id); + cdrom_ioctl[id].cdrom_capacity = ioctl_get_last_block(id, 0, 0, 4096, 0); +} + +static int is_track_audio(uint8_t id, uint32_t pos) +{ + int c; + int control = 0; + + uint32_t track_address = 0; + + if (!cdrom_ioctl[id].tocvalid) + { + return 0; + } + + for (c = 0; c <= cdrom_ioctl_windows[id].toc.LastTrack; c++) + { + track_address = MSFtoLBA(cdrom_ioctl_windows[id].toc.TrackData[c].Address[1],cdrom_ioctl_windows[id].toc.TrackData[c].Address[2],cdrom_ioctl_windows[id].toc.TrackData[c].Address[3]); + + if (track_address <= pos) + { + control = cdrom_ioctl_windows[id].toc.TrackData[c].Control; + } + } + + if ((control & 0xd) <= 1) + { + return 1; + } + else + { + return 0; + } +} + +static int ioctl_is_track_audio(uint8_t id, uint32_t pos, int ismsf) +{ + int m = 0, s = 0, f = 0; + + if (ismsf) + { + m = (pos >> 16) & 0xff; + s = (pos >> 8) & 0xff; + f = pos & 0xff; + pos = MSFtoLBA(m, s, f); + } + else + { + pos += 150; + } + return is_track_audio(id, pos); +} + +/* 00, 08, 10, 18, 20, 28, 30, 38 */ +int flags_to_size[5][32] = { { 0, 0, 2352, 2352, 2352, 2352, 2352, 2352, /* 00-38 (CD-DA) */ + 2352, 2352, 2352, 2352, 2352, 2352, 2352, 2352, /* 40-78 */ + 2352, 2352, 2352, 2352, 2352, 2352, 2352, 2352, /* 80-B8 */ + 2352, 2352, 2352, 2352, 2352, 2352, 2352, 2352 }, /* C0-F8 */ + { 0, 0, 2048, 2336, 4, -296, 2052, 2344, /* 00-38 (Mode 1) */ + 8, -296, 2048, 2048, 12, -296, 2052, 2052, /* 40-78 */ + -296, -296, -296, -296, 16, -296, 2064, 2344, /* 80-B8 */ + -296, -296, 2048, 2048, 24, -296, 2064, 2352 }, /* C0-F8 */ + { 0, 0, 2336, 2336, 4, -296, 2340, 2340, /* 00-38 (Mode 2 non-XA) */ + 8, -296, 2336, 2336, 12, -296, 2340, 2340, /* 40-78 */ + -296, -296, -296, -296, 16, -296, 2352, 2340, /* 80-B8 */ + -296, -296, 2336, 2336, 24, -296, 2352, 2352 }, /* C0-F8 */ + { 0, 0, 2048, 2336, 4, -296, -296, -296, /* 00-38 (Mode 2 Form 1) */ + 8, -296, 2056, 2344, 12, -296, 2060, 2340, /* 40-78 */ + -296, -296, -296, -296, 16, -296, -296, -296, /* 80-B8 */ + -296, -296, -296, -296, 24, -296, 2072, 2352 }, /* C0-F8 */ + { 0, 0, 2328, 2328, 4, -296, -296, -296, /* 00-38 (Mode 2 Form 2) */ + 8, -296, 2336, 2336, 12, -296, 2340, 2340, /* 40-78 */ + -296, -296, -296, -296, 16, -296, -296, -296, /* 80-B8 */ + -296, -296, -296, -296, 24, -296, 2352, 2352 } /* C0-F8 */ + }; + +static int ioctl_get_sector_data_type(uint8_t id, uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3, int ismsf); + +static void cdrom_illegal_mode(uint8_t id) +{ + cdrom_sense_key = SENSE_ILLEGAL_REQUEST; + cdrom_asc = ASC_ILLEGAL_MODE_FOR_THIS_TRACK; + cdrom_ascq = 0; +} + +struct sptd_with_sense +{ + SCSI_PASS_THROUGH s; + ULONG Filler; + UCHAR sense[32]; + UCHAR data[65536]; +} sptd; + +static int ioctl_get_block_length(uint8_t id, const UCHAR *cdb, int number_of_blocks, int no_length_check) +{ + int sector_type = 0; + int temp_len = 0; + + if (no_length_check) + { + switch (cdb[0]) + { + case 0x25: + /* READ CAPACITY */ + return 8; + case 0x42: /* READ SUBCHANNEL */ + case 0x43: /* READ TOC */ + case 0x51: /* READ DISC INFORMATION */ + case 0x52: /* READ TRACK INFORMATION */ + case 0x5A: /* MODE SENSE (10) */ + return ((uint16_t) cdb[8]) + (((uint16_t) cdb[7]) << 8); + default: + return 65534; + } + } + + switch (cdb[0]) + { + case 0x25: + /* READ CAPACITY */ + return 8; + case 0x42: /* READ SUBCHANNEL */ + case 0x43: /* READ TOC */ + case 0x51: /* READ DISC INFORMATION */ + case 0x52: /* READ TRACK INFORMATION */ + case 0x5A: /* MODE SENSE (10) */ + return ((uint16_t) cdb[8]) + (((uint16_t) cdb[7]) << 8); + case 0x08: + case 0x28: + case 0xa8: + /* READ (6), READ (10), READ (12) */ + return 2048 * number_of_blocks; + break; + case 0xb9: + sector_type = (cdb[1] >> 2) & 7; + if (sector_type == 0) + { + sector_type = ioctl_get_sector_data_type(id, 0, cdb[3], cdb[4], cdb[5], 1); + if (sector_type == 0) + { + cdrom_illegal_mode(id); + return -1; + } + } + goto common_handler; + case 0xbe: + /* READ CD MSF, READ CD */ + sector_type = (cdb[1] >> 2) & 7; + if (sector_type == 0) + { + sector_type = ioctl_get_sector_data_type(id, cdb[2], cdb[3], cdb[4], cdb[5], 0); + if (sector_type == 0) + { + cdrom_illegal_mode(id); + return -1; + } + } +common_handler: + temp_len = flags_to_size[sector_type - 1][cdb[9] >> 3]; + if ((cdb[9] & 6) == 2) + { + temp_len += 294; + } + else if ((cdb[9] & 6) == 4) + { + temp_len += 296; + } + if ((cdb[10] & 7) == 1) + { + temp_len += 96; + } + else if ((cdb[10] & 7) == 2) + { + temp_len += 16; + } + else if ((cdb[10] & 7) == 4) + { + temp_len += 96; + } + if (temp_len <= 0) + { + cdrom_illegal_mode(id); + return -1; + } + return temp_len * cdrom[id].requested_blocks; + break; + default: + /* Other commands */ + return 65534; + break; + } + +} + +static int SCSICommand(uint8_t id, const UCHAR *cdb, UCHAR *buf, uint32_t *len, int no_length_check) +{ + DWORD ioctl_bytes; + int ioctl_rv = 0; + + SCSISense.SenseKey = 0; + SCSISense.Asc = 0; + SCSISense.Ascq = 0; + + *len = 0; + memset(&sptd, 0, sizeof(sptd)); + sptd.s.Length = sizeof(SCSI_PASS_THROUGH); + sptd.s.CdbLength = 12; + sptd.s.DataIn = SCSI_IOCTL_DATA_IN; + sptd.s.TimeOutValue = 80 * 60; + sptd.s.DataTransferLength = ioctl_get_block_length(id, cdb, cdrom_ioctl[id].actual_requested_blocks, no_length_check); + sptd.s.SenseInfoOffset = (uintptr_t)&sptd.sense - (uintptr_t)&sptd; + sptd.s.SenseInfoLength = 32; + sptd.s.DataBufferOffset = (uintptr_t)&sptd.data - (uintptr_t)&sptd; + + memcpy(sptd.s.Cdb, cdb, 12); + ioctl_rv = DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_SCSI_PASS_THROUGH, &sptd, sizeof(sptd), &sptd, sizeof(sptd), &ioctl_bytes, NULL); + + if (sptd.s.SenseInfoLength) + { + cdrom_sense_key = sptd.sense[2]; + cdrom_asc = sptd.sense[12]; + cdrom_ascq = sptd.sense[13]; + } + + cdrom_ioctl_log("Transferred length: %i (command: %02X)\n", sptd.s.DataTransferLength, cdb[0]); + cdrom_ioctl_log("Sense length: %i (%02X %02X %02X %02X %02X)\n", sptd.s.SenseInfoLength, sptd.sense[0], sptd.sense[1], sptd.sense[2], sptd.sense[12], sptd.sense[13]); + cdrom_ioctl_log("IOCTL bytes: %i; SCSI status: %i, status: %i, LastError: %08X\n", ioctl_bytes, sptd.s.ScsiStatus, ioctl_rv, GetLastError()); + cdrom_ioctl_log("DATA: %02X %02X %02X %02X %02X %02X\n", sptd.data[0], sptd.data[1], sptd.data[2], sptd.data[3], sptd.data[4], sptd.data[5]); + cdrom_ioctl_log(" %02X %02X %02X %02X %02X %02X\n", sptd.data[6], sptd.data[7], sptd.data[8], sptd.data[9], sptd.data[10], sptd.data[11]); + cdrom_ioctl_log(" %02X %02X %02X %02X %02X %02X\n", sptd.data[12], sptd.data[13], sptd.data[14], sptd.data[15], sptd.data[16], sptd.data[17]); + cdrom_ioctl_log("SENSE: %02X %02X %02X %02X %02X %02X\n", sptd.sense[0], sptd.sense[1], sptd.sense[2], sptd.sense[3], sptd.sense[4], sptd.sense[5]); + cdrom_ioctl_log(" %02X %02X %02X %02X %02X %02X\n", sptd.sense[6], sptd.sense[7], sptd.sense[8], sptd.sense[9], sptd.sense[10], sptd.sense[11]); + cdrom_ioctl_log(" %02X %02X %02X %02X %02X %02X\n", sptd.sense[12], sptd.sense[13], sptd.sense[14], sptd.sense[15], sptd.sense[16], sptd.sense[17]); + *len = sptd.s.DataTransferLength; + if (sptd.s.DataTransferLength != 0) + { + memcpy(buf, sptd.data, sptd.s.DataTransferLength); + } + + return ioctl_rv; +} + +static void ioctl_read_capacity(uint8_t id, uint8_t *b) +{ + uint32_t len = 0; + + const UCHAR cdb[] = { 0x25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + UCHAR buf[16]; + + if (!cdrom_ioctl[id].capacity_read) + { + ioctl_open(id, 0); + + SCSICommand(id, cdb, buf, &len, 1); + + memcpy(cdrom_ioctl[id].rcbuf, buf, len); + cdrom_ioctl[id].capacity_read = 1; + } + else + { + memcpy(b, cdrom_ioctl[id].rcbuf, 16); + } + + ioctl_close(id); +} + +static int ioctl_media_type_id(uint8_t id) +{ + uint8_t old_sense[3] = { 0, 0, 0 }; + + UCHAR msbuf[28]; + uint32_t len = 0; + int sense = 0; + + const UCHAR cdb[] = { 0x5A, 0x00, 0x2A, 0, 0, 0, 0, 0, 28, 0, 0, 0 }; + + old_sense[0] = cdrom_sense_key; + old_sense[1] = cdrom_asc; + old_sense[2] = cdrom_asc; + + ioctl_open(id, 0); + + SCSICommand(id, cdb, msbuf, &len, 1); + + ioctl_close(id); + + sense = cdrom_sense_key; + cdrom_sense_key = old_sense[0]; + cdrom_asc = old_sense[1]; + cdrom_asc = old_sense[2]; + + if (sense == 0) + { + return msbuf[2]; + } + else + { + return 3; + } +} + +static uint32_t msf_to_lba32(int lba) +{ + int m = (lba >> 16) & 0xff; + int s = (lba >> 8) & 0xff; + int f = lba & 0xff; + return (m * 60 * 75) + (s * 75) + f; +} + +static int ioctl_get_type(uint8_t id, UCHAR *cdb, UCHAR *buf) +{ + int i = 0; + int ioctl_rv = 0; + + uint32_t len = 0; + + for (i = 2; i <= 5; i++) + { + cdb[1] = i << 2; + ioctl_rv = SCSICommand(id, cdb, buf, &len, 1); /* Bypass length check so we don't risk calling this again and getting stuck in an endless up. */ + if (ioctl_rv) + { + return i; + } + } + return 0; +} + +static int ioctl_sector_data_type(uint8_t id, int sector, int ismsf) +{ + int ioctl_rv = 0; + UCHAR cdb_lba[] = { 0xBE, 0, 0, 0, 0, 0, 0, 0, 1, 0x10, 0, 0 }; + UCHAR cdb_msf[] = { 0xB9, 0, 0, 0, 0, 0, 0, 0, 0, 0x10, 0, 0 }; + UCHAR buf[2352]; + + cdb_lba[2] = (sector >> 24); + cdb_lba[3] = ((sector >> 16) & 0xff); + cdb_lba[4] = ((sector >> 8) & 0xff); + cdb_lba[5] = (sector & 0xff); + + cdb_msf[3] = cdb_msf[6] = ((sector >> 16) & 0xff); + cdb_msf[4] = cdb_msf[7] = ((sector >> 8) & 0xff); + cdb_msf[5] = cdb_msf[8] = (sector & 0xff); + + ioctl_open(id, 0); + + if (ioctl_is_track_audio(id, sector, ismsf)) + { + return 1; + } + + if (ismsf) + { + ioctl_rv = ioctl_get_type(id, cdb_msf, buf); + } + else + { + ioctl_rv = ioctl_get_type(id, cdb_lba, buf); + } + + if (ioctl_rv) + { + ioctl_close(id); + return ioctl_rv; + } + + if (ismsf) + { + sector = msf_to_lba32(sector); + if (sector < 150) + { + ioctl_close(id); + return 0; + } + sector -= 150; + ioctl_rv = ioctl_get_type(id, (UCHAR *) cdb_lba, buf); + } + + ioctl_close(id); + return ioctl_rv; +} + +static int ioctl_get_sector_data_type(uint8_t id, uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3, int ismsf) +{ + int sector = b3; + sector |= ((uint32_t) b2) << 8; + sector |= ((uint32_t) b1) << 16; + sector |= ((uint32_t) b0) << 24; + return ioctl_sector_data_type(id, sector, ismsf); +} + +static void ioctl_validate_toc(uint8_t id) +{ + unsigned long size; + if (!cdrom_drives[id].host_drive) + { + return; + } + cdrom_ioctl[id].cd_state = CD_STOPPED; + ioctl_open(id, 0); + cdrom_ioctl_log("Validating TOC...\n"); + DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_CDROM_READ_TOC, NULL,0,&cdrom_ioctl_windows[id].toc,sizeof(cdrom_ioctl_windows[id].toc),&size,NULL); + ioctl_close(id); + cdrom_ioctl[id].tocvalid=1; +} + +UCHAR buf[262144]; + +static int ioctl_pass_through(uint8_t id, uint8_t *in_cdb, uint8_t *b, uint32_t *len) +{ + const UCHAR cdb[12]; + + int ret = 0; + + int block_length = 0; + + int temp_block_length = 0; + int temp_pos = 0; + + int blocks_at_once = 0; + int buffer_pos = 0; + + int transferred_blocks = 0; + + uint32_t temp_len = 0; + int chunk = 0; + + if (in_cdb[0] == 0x43) + { + /* This is a read TOC, so we have to validate the TOC to make the rest of the emulator happy. */ + ioctl_validate_toc(id); + } + + ioctl_open(id, 0); + + memcpy((void *) cdb, in_cdb, 12); + + temp_block_length = ioctl_get_block_length(id, cdb, cdrom[id].requested_blocks, 0); + *len = 0; + if (temp_block_length != -1) + { + if (temp_block_length > 65534) + { + block_length = temp_block_length / cdrom[id].requested_blocks; + blocks_at_once = 32768 / block_length; + cdrom_ioctl_log("CD-ROM %i: ioctl_pass_through(): Expected transfer length %i is bigger than 65534, splitting the transfer into chunks of %i blocks...\n", id, temp_block_length, blocks_at_once); + + buffer_pos = 0; + temp_pos = cdrom[id].sector_pos; + transferred_blocks = 0; + temp_len = 0; + +split_block_read_iterate: + chunk = (cdrom[id].requested_blocks - transferred_blocks); + if (chunk < blocks_at_once) + { + cdrom_ioctl_log("CD-ROM %i: ioctl_pass_through(): The remaining chunk (%i blocks) is less than a complete split block\n", id, chunk); + cdrom_ioctl[id].actual_requested_blocks = chunk; + } + else + { + cdrom_ioctl_log("CD-ROM %i: ioctl_pass_through(): The remaining chunk (%i blocks) is more or equal than a complete split block\n", id, chunk); + cdrom_ioctl[id].actual_requested_blocks = blocks_at_once; + } + cdrom_ioctl_log("CD-ROM %i: ioctl_pass_through(): Transferring %i blocks...\n", id, cdrom_ioctl[id].actual_requested_blocks); + cdrom_update_cdb((uint8_t *) cdb, temp_pos, cdrom_ioctl[id].actual_requested_blocks); + ret = SCSICommand(id, cdb, buf + buffer_pos, &temp_len, 0); + *len += temp_len; + transferred_blocks += cdrom_ioctl[id].actual_requested_blocks; + if (ret && (transferred_blocks < cdrom[id].requested_blocks)) + { + /* Return value was successful and there are still more blocks left to transfer. */ + temp_pos += cdrom_ioctl[id].actual_requested_blocks; + buffer_pos += (cdrom_ioctl[id].actual_requested_blocks * block_length); + goto split_block_read_iterate; + } + cdrom_ioctl_log("CD-ROM %i: ioctl_pass_through(): Split transfer done\n", id); + } + else + { + cdrom_ioctl_log("CD-ROM %i: ioctl_pass_through(): Expected transfer length %i is smaller than 65534, transferring all at once...\n", id, temp_block_length); + cdrom_ioctl[id].actual_requested_blocks = cdrom[id].requested_blocks; + ret = SCSICommand(id, cdb, buf, len, 0); + cdrom_ioctl_log("CD-ROM %i: ioctl_pass_through(): Single transfer done\n", id); + } + memcpy(b, buf, *len); + } + else + { + cdrom_ioctl_log("CD-ROM %i: ioctl_pass_through(): Expected transfer length %i is -1, this indicates an illegal mode\n", id, temp_block_length); + } + + cdrom_ioctl_log("IOCTL DATA: %02X %02X %02X %02X %02X %02X %02X %02X\n", b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]); + + ioctl_close(id); + + cdrom_ioctl_log("IOCTL Returned value: %i\n", ret); + + return ret; +} + +static uint32_t ioctl_size(uint8_t id) +{ + uint8_t capacity_buffer[8]; + uint32_t capacity = 0; + ioctl_read_capacity(id, capacity_buffer); + capacity = ((uint32_t) capacity_buffer[0]) << 24; + capacity |= ((uint32_t) capacity_buffer[1]) << 16; + capacity |= ((uint32_t) capacity_buffer[2]) << 8; + capacity |= (uint32_t) capacity_buffer[3]; + return capacity + 1; +} + +static int ioctl_status(uint8_t id) +{ + if (!(ioctl_ready(id)) && (cdrom_drives[id].host_drive <= 0)) + { + return CD_STATUS_EMPTY; + } + + switch(cdrom_ioctl[id].cd_state) + { + case CD_PLAYING: + return CD_STATUS_PLAYING; + case CD_PAUSED: + return CD_STATUS_PAUSED; + case CD_STOPPED: + return CD_STATUS_STOPPED; + default: + return CD_STATUS_EMPTY; + } +} + +void ioctl_reset(uint8_t id) +{ + CDROM_TOC ltoc; + unsigned long size; + + if (!cdrom_drives[id].host_drive) + { + cdrom_ioctl[id].tocvalid = 0; + return; + } + + ioctl_open(id, 0); + DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, <oc, sizeof(ltoc), &size, NULL); + ioctl_close(id); + + cdrom_ioctl_windows[id].toc = ltoc; + cdrom_ioctl[id].tocvalid = 1; +} + +int ioctl_open(uint8_t id, char d) +{ + if (!cdrom_ioctl[id].ioctl_inited) + { + sprintf(cdrom_ioctl[id].ioctl_path,"\\\\.\\%c:",d); + cdrom_ioctl[id].tocvalid=0; + } + cdrom_ioctl_windows[id].hIOCTL = CreateFile(cdrom_ioctl[id].ioctl_path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); + cdrom_drives[id].handler = &ioctl_cdrom; + if (!cdrom_ioctl[id].ioctl_inited) + { + cdrom_ioctl[id].ioctl_inited=1; + cdrom_ioctl[id].capacity_read=0; /* With this two lines, we read the READ CAPACITY command output from the host drive into our cache buffer. */ + ioctl_read_capacity(id, NULL); + CloseHandle(cdrom_ioctl_windows[id].hIOCTL); + cdrom_ioctl_windows[id].hIOCTL = NULL; + update_status_bar_icon_state(0x10 | id, 0); + } + return 0; +} + +void ioctl_close(uint8_t id) +{ + if (cdrom_ioctl_windows[id].hIOCTL) + { + CloseHandle(cdrom_ioctl_windows[id].hIOCTL); + cdrom_ioctl_windows[id].hIOCTL = NULL; + } +} + +static void ioctl_exit(uint8_t id) +{ + ioctl_stop(id); + cdrom_ioctl[id].ioctl_inited=0; + cdrom_ioctl[id].tocvalid=0; +} + +static CDROM ioctl_cdrom= +{ + ioctl_ready, + ioctl_medium_changed, + ioctl_media_type_id, + ioctl_audio_callback, + ioctl_audio_stop, + NULL, + NULL, + NULL, + ioctl_getcurrentsubchannel, + ioctl_pass_through, + NULL, + ioctl_playaudio, + ioctl_load, + ioctl_eject, + ioctl_pause, + ioctl_resume, + ioctl_size, + ioctl_status, + ioctl_is_track_audio, + ioctl_stop, + ioctl_exit +}; diff --git a/src/cdrom_ioctl.h b/src/cdrom_ioctl.h new file mode 100644 index 000000000..e39f12ddf --- /dev/null +++ b/src/cdrom_ioctl.h @@ -0,0 +1,17 @@ +/* Copyright holders: Sarah Walker, Tenshi + see COPYING for more details +*/ +#ifndef CDROM_IOCTL_H +#define CDROM_IOCTL_H + +/* this header file lists the functions provided by + various platform specific cdrom-ioctl files */ + +extern uint32_t cdrom_capacity; + +extern int ioctl_open(uint8_t id, char d); +extern void ioctl_reset(uint8_t id); + +extern void ioctl_close(uint8_t id); + +#endif /* ! CDROM_IOCTL_H */ diff --git a/src/cdrom_ioctl_linux.c b/src/cdrom_ioctl_linux.c new file mode 100644 index 000000000..bf1f73994 --- /dev/null +++ b/src/cdrom_ioctl_linux.c @@ -0,0 +1,725 @@ +/* Copyright holders: Sarah Walker, Tenshi + see COPYING for more details +*/ +/*Linux CD-ROM support via IOCTL*/ + +#include +#include +#include +#include +#include "ibm.h" +#include "ide.h" +#include "cdrom_ioctl.h" + +static ATAPI ioctl_atapi; + +static uint32_t last_block = 0; +static uint32_t cdrom_capacity = 0; +static int ioctl_inited = 0; +static char ioctl_path[8]; +static int tocvalid = 0; +static struct cdrom_tocentry toc[100]; +static int first_track, last_track; + +int old_cdrom_drive; + +#define MSFtoLBA(m,s,f) (((((m*60)+s)*75)+f)-150) + +enum +{ + CD_STOPPED = 0, + CD_PLAYING, + CD_PAUSED +}; + +static int ioctl_cd_state = CD_STOPPED; +static uint32_t ioctl_cd_pos = 0, ioctl_cd_end = 0; +#define BUF_SIZE 32768 +static int16_t cd_buffer[BUF_SIZE]; +static int cd_buflen = 0; +void ioctl_audio_callback(int16_t *output, int len) +{ + int fd; + struct cdrom_read_audio read_audio; + +// pclog("Audio callback %08X %08X %i %i %i %04X %i\n", ioctl_cd_pos, ioctl_cd_end, ioctl_cd_state, cd_buflen, len, cd_buffer[4], GetTickCount()); + if (ioctl_cd_state != CD_PLAYING) + { + memset(output, 0, len * 2); + return; + } + fd = open("/dev/cdrom", O_RDONLY|O_NONBLOCK); + + if (fd <= 0) + { + memset(output, 0, len * 2); + return; + } + + while (cd_buflen < len) + { + if (ioctl_cd_pos < ioctl_cd_end) + { + read_audio.addr.lba = ioctl_cd_pos - 150; + read_audio.addr_format = CDROM_LBA; + read_audio.nframes = 1; + read_audio.buf = (__u8 *)&cd_buffer[cd_buflen]; + + if (ioctl(fd, CDROMREADAUDIO, &read_audio) < 0) + { +// pclog("DeviceIoControl returned false\n"); + memset(&cd_buffer[cd_buflen], 0, (BUF_SIZE - cd_buflen) * 2); + ioctl_cd_state = CD_STOPPED; + cd_buflen = len; + } + else + { +// pclog("DeviceIoControl returned true\n"); + ioctl_cd_pos++; + cd_buflen += (2352 / 2); + } + } + else + { + memset(&cd_buffer[cd_buflen], 0, (BUF_SIZE - cd_buflen) * 2); + ioctl_cd_state = CD_STOPPED; + cd_buflen = len; + } + } + close(fd); + memcpy(output, cd_buffer, len * 2); +// for (c = 0; c < BUF_SIZE - len; c++) +// cd_buffer[c] = cd_buffer[c + cd_buflen]; + memcpy(&cd_buffer[0], &cd_buffer[len], (BUF_SIZE - len) * 2); + cd_buflen -= len; +// pclog("Done %i\n", GetTickCount()); +} + +void ioctl_audio_stop() +{ + ioctl_cd_state = CD_STOPPED; +} + +static int get_track_nr(uint32_t pos) +{ + int c; + int track = 0; + + if (!tocvalid) + return 0; + + for (c = first_track; c < last_track; c++) + { + uint32_t track_address = toc[c].cdte_addr.msf.frame + + (toc[c].cdte_addr.msf.second * 75) + + (toc[c].cdte_addr.msf.minute * 75 * 60); +//pclog("get_track_nr: track=%i pos=%x track_address=%x\n", c, pos, track_address); + if (track_address <= pos) + track = c; + } + return track; +} + +static int is_track_audio(uint32_t pos) +{ + int c; + int control = 0; + + if (!tocvalid) + return 0; + + for (c = first_track; c < last_track; c++) + { + uint32_t track_address = toc[c].cdte_addr.msf.frame + + (toc[c].cdte_addr.msf.second * 75) + + (toc[c].cdte_addr.msf.minute * 75 * 60); +//pclog("get_track_nr: track=%i pos=%x track_address=%x\n", c, pos, track_address); + if (track_address <= pos) + control = toc[c].cdte_ctrl; + } + return (control & 4) ? 0 : 1; +} + +static int ioctl_is_track_audio(uint32_t pos, int ismsf) +{ + if (ismsf) + { + int m = (pos >> 16) & 0xff; + int s = (pos >> 8) & 0xff; + int f = pos & 0xff; + pos = MSFtoLBA(m, s, f); + } + return is_track_audio(pos); +} + +static void ioctl_playaudio(uint32_t pos, uint32_t len, int ismsf) +{ +// pclog("Play audio - %08X %08X %i\n", pos, len, ismsf); + if (ismsf) + { + pos = (pos & 0xff) + (((pos >> 8) & 0xff) * 75) + (((pos >> 16) & 0xff) * 75 * 60); + len = (len & 0xff) + (((len >> 8) & 0xff) * 75) + (((len >> 16) & 0xff) * 75 * 60); +// pclog("MSF - pos = %08X len = %08X\n", pos, len); + } + else + len += pos; + ioctl_cd_pos = pos;// + 150; + ioctl_cd_end = pos+len;// + 150; + ioctl_cd_state = CD_PLAYING; + if (ioctl_cd_pos < 150) + ioctl_cd_pos = 150; +// pclog("Audio start %08X %08X %i %i %i\n", ioctl_cd_pos, ioctl_cd_end, ioctl_cd_state, 0, len); +} + +static void ioctl_pause(void) +{ + if (ioctl_cd_state == CD_PLAYING) + ioctl_cd_state = CD_PAUSED; +} + +static void ioctl_resume(void) +{ + if (ioctl_cd_state == CD_PAUSED) + ioctl_cd_state = CD_PLAYING; +} + +static void ioctl_stop(void) +{ + ioctl_cd_state = CD_STOPPED; +} + +static void ioctl_seek(uint32_t pos) +{ +// pclog("Seek %08X\n", pos); + ioctl_cd_pos = pos; + ioctl_cd_state = CD_STOPPED; +} + +static int read_toc(int fd, struct cdrom_tocentry *btoc) +{ + struct cdrom_tochdr toc_hdr; + int track, err; +//pclog("read_toc\n"); + err = ioctl(fd, CDROMREADTOCHDR, &toc_hdr); + if (err == -1) + { + pclog("read_toc: CDROMREADTOCHDR failed\n"); + return 0; + } + + first_track = toc_hdr.cdth_trk0; + last_track = toc_hdr.cdth_trk1; +//pclog("read_toc: first_track=%i last_track=%i\n", first_track, last_track); + memset(btoc, 0, sizeof(cdrom_tocentry)); + + for (track = toc_hdr.cdth_trk0; track <= toc_hdr.cdth_trk1; track++) + { + btoc[track].cdte_track = track; + btoc[track].cdte_format = CDROM_MSF; + err = ioctl(fd, CDROMREADTOCENTRY, &btoc[track]); + if (err == -1) + { +// pclog("read_toc: CDROMREADTOCENTRY failed on track %i\n", track); + return 0; + } +// pclog("read_toc: Track %02X - number %02X control %02X adr %02X address %02X %02X %02X %02X\n", track, toc[track].cdte_track, toc[track].cdte_ctrl, toc[track].cdte_adr, 0, toc[track].cdte_addr.msf.minute, toc[track].cdte_addr.msf.second, toc[track].cdte_addr.msf.frame); + } + return 1; +} + +static int ioctl_ready(void) +{ + long size; + int temp; + struct cdrom_tochdr toc_hdr; + struct cdrom_tocentry toc_entry; + int err; + int fd = open("/dev/cdrom", O_RDONLY|O_NONBLOCK); + + if (fd <= 0) + return 0; + + err = ioctl(fd, CDROMREADTOCHDR, &toc_hdr); + if (err == -1) + { + close(fd); + return 0; + } +// pclog("CDROMREADTOCHDR: start track=%i end track=%i\n", toc_hdr.cdth_trk0, toc_hdr.cdth_trk1); + toc_entry.cdte_track = toc_hdr.cdth_trk1; + toc_entry.cdte_format = CDROM_MSF; + err = ioctl(fd, CDROMREADTOCENTRY, &toc_entry); + if (err == -1) + { + close(fd); + return 0; + } +// pclog("CDROMREADTOCENTRY: addr=%02i:%02i:%02i\n", toc_entry.cdte_addr.msf.minute, toc_entry.cdte_addr.msf.second, toc_entry.cdte_addr.msf.frame); + if ((toc_entry.cdte_addr.msf.minute != toc[toc_hdr.cdth_trk1].cdte_addr.msf.minute) || + (toc_entry.cdte_addr.msf.second != toc[toc_hdr.cdth_trk1].cdte_addr.msf.second) || + (toc_entry.cdte_addr.msf.frame != toc[toc_hdr.cdth_trk1].cdte_addr.msf.frame ) || + !tocvalid) + { + int track; + ioctl_cd_state = CD_STOPPED; + + tocvalid = read_toc(fd, toc); + close(fd); + return 1; + } + close(fd); + return 1; +} + +static int ioctl_get_last_block(unsigned char starttrack, int msf, int maxlen, int single) +{ + int c; + int lb = 0; + int tv = 0; + struct cdrom_tocentry lbtoc[100]; + int fd = open("/dev/cdrom", O_RDONLY|O_NONBLOCK); + + if (fd <= 0) + return 0; + + ioctl_cd_state = CD_STOPPED; + + tv = read_toc(fd, lbtoc); + + close(fd); + + if (!tv) + return 0; + + last_block = 0; + for (c = 0; c <= last_track; c++) + { + uint32_t address; + address = MSFtoLBA(toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame); + if (address > last_block) + lb = address; + } + return lb; +} + +static int ioctl_medium_changed(void) +{ + long size; + int temp; + struct cdrom_tochdr toc_hdr; + struct cdrom_tocentry toc_entry; + int err; + int fd = open("/dev/cdrom", O_RDONLY|O_NONBLOCK); + + if (fd <= 0) + return 0; + + err = ioctl(fd, CDROMREADTOCHDR, &toc_hdr); + if (err == -1) + { + close(fd); + return 0; + } + toc_entry.cdte_track = toc_hdr.cdth_trk1; + toc_entry.cdte_format = CDROM_MSF; + err = ioctl(fd, CDROMREADTOCENTRY, &toc_entry); + if (err == -1) + { + close(fd); + return 0; + } +// pclog("CDROMREADTOCENTRY: addr=%02i:%02i:%02i\n", toc_entry.cdte_addr.msf.minute, toc_entry.cdte_addr.msf.second, toc_entry.cdte_addr.msf.frame); + if ((toc_entry.cdte_addr.msf.minute != toc[toc_hdr.cdth_trk1].cdte_addr.msf.minute) || + (toc_entry.cdte_addr.msf.second != toc[toc_hdr.cdth_trk1].cdte_addr.msf.second) || + (toc_entry.cdte_addr.msf.frame != toc[toc_hdr.cdth_trk1].cdte_addr.msf.frame )) + { + cdrom_capacity = ioctl_get_last_block(0, 0, 4096, 0); + return 1; + } + return 0; +} + +static uint8_t ioctl_getcurrentsubchannel(uint8_t *b, int msf) +{ + struct cdrom_subchnl sub; + uint32_t cdpos = ioctl_cd_pos; + int track = get_track_nr(cdpos); + uint32_t track_address = toc[track].cdte_addr.msf.frame + + (toc[track].cdte_addr.msf.second * 75) + + (toc[track].cdte_addr.msf.minute * 75 * 60); + long size; + int pos=0; + int err; + uint8_t ret; +//pclog("ioctl_getsubchannel: cdpos=%x track_address=%x track=%i\n", cdpos, track_address, track); + if (ioctl_cd_state == CD_PLAYING) + ret = 0x11; + else if (ioctl_cd_state == CD_PAUSED) + ret = 0x12; + else + ret = 0x13; + + b[pos++] = (toc[track].cdte_adr << 4) | toc[track].cdte_ctrl; + b[pos++] = track; + b[pos++] = 0; + + if (msf) + { + uint32_t dat = cdpos; + b[pos + 3] = (uint8_t)(dat % 75); dat /= 75; + b[pos + 2] = (uint8_t)(dat % 60); dat /= 60; + b[pos + 1] = (uint8_t)dat; + b[pos] = 0; + pos += 4; + dat = cdpos - track_address; + b[pos + 3] = (uint8_t)(dat % 75); dat /= 75; + b[pos + 2] = (uint8_t)(dat % 60); dat /= 60; + b[pos + 1] = (uint8_t)dat; + b[pos] = 0; + pos += 4; + } + else + { + b[pos++] = (cdpos >> 24) & 0xff; + b[pos++] = (cdpos >> 16) & 0xff; + b[pos++] = (cdpos >> 8) & 0xff; + b[pos++] = cdpos & 0xff; + cdpos -= track_address; + b[pos++] = (cdpos >> 24) & 0xff; + b[pos++] = (cdpos >> 16) & 0xff; + b[pos++] = (cdpos >> 8) & 0xff; + b[pos++] = cdpos & 0xff; + } + + return ret; +} + +static void ioctl_eject(void) +{ + int fd = open("/dev/cdrom", O_RDONLY|O_NONBLOCK); + + if (fd <= 0) + return; + + ioctl(fd, CDROMEJECT); + + close(fd); +} + +static void ioctl_load(void) +{ + int fd = open("/dev/cdrom", O_RDONLY|O_NONBLOCK); + + if (fd <= 0) + return; + + ioctl(fd, CDROMEJECT); + + close(fd); + + cdrom_capacity = ioctl_get_last_block(0, 0, 4096, 0); +} + +union +{ + struct cdrom_msf *msf; + char b[CD_FRAMESIZE_RAW]; +} raw_read_params; + +static int lba_to_msf(int lba) +{ + return (((lba / 75) / 60) << 16) + (((lba / 75) % 60) << 8) + (lba % 75); +} + +static int ioctl_sector_data_type(int sector, int ismsf) +{ + return 2; /* Always Mode 1 */ +} + +static void ioctl_readsector_raw(uint8_t *b, int sector) +{ + int err; + int imsf = lba_to_msf(sector); + int cdrom = open("/dev/cdrom", O_RDONLY|O_NONBLOCK); + + if (cdrom <= 0) + return; + + raw_read_params.msf = malloc(sizeof(struct cdrom_msf)); + raw_read_params.msf->cdmsf_frame0 = imsf & 0xff; + raw_read_params.msf->cdmsf_sec0 = (imsf >> 8) & 0xff; + raw_read_params.msf->cdmsf_min0 = (imsf >> 16) & 0xff; + + /* This will read the actual raw sectors from the disc. */ + err = ioctl(cdrom, CDROMREADRAW, (void *) &raw_read_params); + if (err == -1) + { + pclog("read_toc: CDROMREADTOCHDR failed\n"); + return; + } + + memcpy(b, raw_read_params.b, 2352); + + close(cdrom); + + free(raw_read_params.msf); +} + +static int ioctl_readtoc(unsigned char *b, unsigned char starttrack, int msf, int maxlen, int single) +{ + int len=4; + long size; + int c,d; + uint32_t temp; + int fd = open("/dev/cdrom", O_RDONLY|O_NONBLOCK); + + if (fd <= 0) + return 0; + + ioctl_cd_state = CD_STOPPED; + + tocvalid = read_toc(fd, toc); + + close(fd); + + if (!tocvalid) + return 4; + +// pclog("Read TOC done! %i\n",single); + b[2] = first_track; + b[3] = last_track; + d = 0; +//pclog("Read TOC starttrack=%i\n", starttrack); + for (c = 1; c <= last_track; c++) + { + if (toc[c].cdte_track >= starttrack) + { + d = c; + break; + } + } + b[2] = toc[c].cdte_track; + last_block = 0; + for (c = d; c <= last_track; c++) + { + uint32_t address; + if ((len + 8) > maxlen) + break; +// pclog("Len %i max %i Track %02X - %02X %02X %02i:%02i:%02i %08X\n",len,maxlen,toc[c].cdte_track,toc[c].cdte_adr,toc[c].cdte_ctrl,toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame,MSFtoLBA(toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame)); + b[len++] = 0; /*Reserved*/ + b[len++] = (toc[c].cdte_adr << 4) | toc[c].cdte_ctrl; + b[len++] = toc[c].cdte_track; + b[len++] = 0; /*Reserved*/ + address = MSFtoLBA(toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame); + if (address > last_block) + last_block = address; + + if (msf) + { + b[len++] = 0; + b[len++] = toc[c].cdte_addr.msf.minute; + b[len++] = toc[c].cdte_addr.msf.second; + b[len++] = toc[c].cdte_addr.msf.frame; + } + else + { + temp = MSFtoLBA(toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame); + b[len++] = temp >> 24; + b[len++] = temp >> 16; + b[len++] = temp >> 8; + b[len++] = temp; + } + if (single) + break; + } + b[0] = (uint8_t)(((len-2) >> 8) & 0xff); + b[1] = (uint8_t)((len-2) & 0xff); +/* pclog("Table of Contents (%i bytes) : \n", size); + pclog("First track - %02X\n", first_track); + pclog("Last track - %02X\n", last_track); + for (c = 0; c <= last_track; c++) + pclog("Track %02X - number %02X control %02X adr %02X address %02X %02X %02X %02X\n", c, toc[c].cdte_track, toc[c].cdte_ctrl, toc[c].cdte_adr, 0, toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame); + for (c = 0;c <= last_track; c++) + pclog("Track %02X - number %02X control %02X adr %02X address %06X\n", c, toc[c].cdte_track, toc[c].cdte_ctrl, toc[c].cdte_adr, MSFtoLBA(toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame));*/ + return len; +} + +static int ioctl_readtoc_session(unsigned char *b, int msf, int maxlen) +{ + struct cdrom_multisession session; + int len = 4; + int err; + int fd = open("/dev/cdrom", O_RDONLY|O_NONBLOCK); + + if (fd <= 0) + return 0; + + session.addr_format = CDROM_MSF; + err = ioctl(fd, CDROMMULTISESSION, &session); + + if (err == -1) + { + close(fd); + return 0; + } + + b[2] = 0; + b[3] = 0; + b[len++] = 0; /*Reserved*/ + b[len++] = (toc[0].cdte_adr << 4) | toc[0].cdte_ctrl; + b[len++] = toc[0].cdte_track; + b[len++] = 0; /*Reserved*/ + if (msf) + { + b[len++] = 0; + b[len++] = session.addr.msf.minute; + b[len++] = session.addr.msf.second; + b[len++] = session.addr.msf.frame; + } + else + { + uint32_t temp = MSFtoLBA(session.addr.msf.minute, session.addr.msf.second, session.addr.msf.frame); + b[len++] = temp >> 24; + b[len++] = temp >> 16; + b[len++] = temp >> 8; + b[len++] = temp; + } + + return len; +} + +static int ioctl_readtoc_raw(unsigned char *b, int maxlen) +{ + struct cdrom_tochdr toc_hdr; + struct cdrom_tocentry toc2[100]; + int track, err; + int len = 4; + int fd = open("/dev/cdrom", O_RDONLY|O_NONBLOCK); +//pclog("read_toc\n"); + if (fd <= 0) + return 0; + + err = ioctl(fd, CDROMREADTOCHDR, &toc_hdr); + if (err == -1) + { + pclog("read_toc: CDROMREADTOCHDR failed\n"); + return 0; + } + + b[2] = toc_hdr.cdth_trk0; + b[3] = toc_hdr.cdth_trk1; + + //pclog("read_toc: first_track=%i last_track=%i\n", first_track, last_track); + memset(toc, 0, sizeof(toc)); + + for (track = toc_hdr.cdth_trk0; track <= toc_hdr.cdth_trk1; track++) + { + if ((len + 11) > maxlen) + { + pclog("ioctl_readtocraw: This iteration would fill the buffer beyond the bounds, aborting...\n"); + close(fd); + return len; + } + + toc2[track].cdte_track = track; + toc2[track].cdte_format = CDROM_MSF; + err = ioctl(fd, CDROMREADTOCENTRY, &toc2[track]); + if (err == -1) + { +// pclog("read_toc: CDROMREADTOCENTRY failed on track %i\n", track); + close(fd); + return 0; + } +// pclog("read_toc: Track %02X - number %02X control %02X adr %02X address %02X %02X %02X %02X\n", track, toc[track].cdte_track, toc[track].cdte_ctrl, toc[track].cdte_adr, 0, toc[track].cdte_addr.msf.minute, toc[track].cdte_addr.msf.second, toc[track].cdte_addr.msf.frame); + + b[len++] = toc2[track].cdte_track; + b[len++]= (toc2[track].cdte_adr << 4) | toc[track].cdte_ctrl; + b[len++]=0; + b[len++]=0; + b[len++]=0; + b[len++]=0; + b[len++]=0; + b[len++]=0; + b[len++] = toc2[track].cdte_addr.msf.minute; + b[len++] = toc2[track].cdte_addr.msf.second; + b[len++] = toc2[track].cdte_addr.msf.frame; + } + close(fd); + return len; +} + +static uint32_t ioctl_size() +{ + return cdrom_capacity; +} + +static int ioctl_status() +{ + if (!(ioctl_ready) && (cdrom_drive <= 0)) return CD_STATUS_EMPTY; + + switch(ioctl_cd_state) + { + case CD_PLAYING: + return CD_STATUS_PLAYING; + case CD_PAUSED: + return CD_STATUS_PAUSED; + case CD_STOPPED: + return CD_STATUS_STOPPED; + } +} +void ioctl_reset() +{ + int fd = open("/dev/cdrom", O_RDONLY|O_NONBLOCK); +//pclog("ioctl_reset: fd=%i\n", fd); + tocvalid = 0; + + if (fd <= 0) + return; + + tocvalid = read_toc(fd, toc); + + close(fd); +} + +int ioctl_open(char d) +{ + atapi=&ioctl_atapi; + return 0; +} + +void ioctl_close(void) +{ +} + +static void ioctl_exit(void) +{ + ioctl_stop(); + ioctl_inited = 0; + tocvalid=0; +} + +static ATAPI ioctl_atapi= +{ + ioctl_ready, + ioctl_medium_changed, + ioctl_readtoc, + ioctl_readtoc_session, + ioctl_readtoc_raw, + ioctl_getcurrentsubchannel, + NULL, + NULL, + NULL, + ioctl_sector_data_type, + ioctl_readsector_raw, + ioctl_playaudio, + ioctl_seek, + ioctl_load, + ioctl_eject, + ioctl_pause, + ioctl_resume, + ioctl_size, + ioctl_status, + ioctl_is_track_audio, + ioctl_stop, + ioctl_exit +}; diff --git a/src/cdrom_null.c b/src/cdrom_null.c new file mode 100644 index 000000000..5d86b7992 --- /dev/null +++ b/src/cdrom_null.c @@ -0,0 +1,130 @@ +/* Copyright holders: Sarah Walker + see COPYING for more details +*/ +#include "ibm.h" +#include "cdrom.h" +#include "cdrom_ioctl.h" + +static CDROM null_cdrom; + +static int null_ready(uint8_t id) +{ + return 0; +} + +/* Always return 0, the contents of a null CD-ROM drive never change. */ +static int null_medium_changed(uint8_t id) +{ + return 0; +} + +static uint8_t null_getcurrentsubchannel(uint8_t id, uint8_t *b, int msf) +{ + return 0x13; +} + +static void null_eject(uint8_t id) +{ +} + +static void null_load(uint8_t id) +{ +} + +static int null_readsector_raw(uint8_t id, uint8_t *buffer, int sector, int ismsf, int cdrom_sector_type, int cdrom_sector_flags, int *len) +{ + *len = 0; + return 0; +} + +static int null_readtoc(uint8_t id, unsigned char *b, unsigned char starttrack, int msf, int maxlen, int single) +{ + return 0; +} + +static int null_readtoc_session(uint8_t id, unsigned char *b, int msf, int maxlen) +{ + return 0; +} + +static int null_readtoc_raw(uint8_t id, unsigned char *b, int msf, int maxlen) +{ + return 0; +} + +static uint32_t null_size(uint8_t id) +{ + return 0; +} + +static int null_status(uint8_t id) +{ + return CD_STATUS_EMPTY; +} + +void cdrom_null_reset(uint8_t id) +{ +} + +void cdrom_set_null_handler(uint8_t id); + +int cdrom_null_open(uint8_t id, char d) +{ + cdrom_set_null_handler(id); + return 0; +} + +void null_close(uint8_t id) +{ +} + +static void null_exit(uint8_t id) +{ +} + +static int null_is_track_audio(uint8_t id, uint32_t pos, int ismsf) +{ + return 0; +} + +static int null_pass_through(uint8_t id, uint8_t *in_cdb, uint8_t *b, uint32_t *len) +{ + return 0; +} + +static int null_media_type_id(uint8_t id) +{ + return 0x70; +} + +void cdrom_set_null_handler(uint8_t id) +{ + cdrom_drives[id].handler = &null_cdrom; + cdrom_drives[id].host_drive = 0; + update_status_bar_icon_state(0x10 | id, 1); +} + +static CDROM null_cdrom = +{ + null_ready, + null_medium_changed, + null_media_type_id, + NULL, + NULL, + null_readtoc, + null_readtoc_session, + null_readtoc_raw, + null_getcurrentsubchannel, + null_pass_through, + null_readsector_raw, + NULL, + null_load, + null_eject, + NULL, + NULL, + null_size, + null_status, + null_is_track_audio, + NULL, + null_exit +}; diff --git a/src/cdrom_null.h b/src/cdrom_null.h new file mode 100644 index 000000000..7217760ca --- /dev/null +++ b/src/cdrom_null.h @@ -0,0 +1,14 @@ +/* Copyright holders: Sarah Walker + see COPYING for more details +*/ +#ifndef CDROM_NULL_H +#define CDROM_NULL_H + +/* this header file lists the functions provided by + various platform specific cdrom-ioctl files */ + +int cdrom_null_open(uint8_t id, char d); +void cdrom_null_reset(uint8_t id); +void null_close(uint8_t id); + +#endif /* ! CDROM_NULL_H */