diff --git a/src/Makefile.mingw b/src/Makefile.mingw index e85fb7d06..12f302989 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -8,7 +8,7 @@ # # Modified Makefile for Win32 (MinGW32) environment. # -# Version: @(#)Makefile.mingw 1.0.52 2017/10/05 +# Version: @(#)Makefile.mingw 1.0.53 2017/10/06 # # Authors: Miran Grca, # Fred N. van Kempen, @@ -347,12 +347,12 @@ VIDOBJ := video.o \ vid_tandy.o vid_tandysl.o WINOBJ := win.o \ - win_ddraw.o win_ddraw_fs.o win_ddraw_screenshot.o \ - win_d3d.o win_d3d_fs.o \ + win_ddraw.o win_ddraw_fs.o win_d3d.o win_d3d_fs.o \ win_language.o win_status.o $(OPENDIR) win_dynld.o \ win_video.o $(WSERIAL) win_keyboard.o win_mouse.o \ - win_joystick.o win_midi.o win_thread.o \ - win_settings.o win_deviceconfig.o win_joystickconfig.o + win_joystick.o win_midi.o win_cdrom.o win_thread.o \ + win_about.o win_stbar.o win_settings.o \ + win_deviceconfig.o win_joystickconfig.o OBJ := $(MAINOBJ) $(CPUOBJ) $(MCHOBJ) $(DEVOBJ) \ $(FDDOBJ) $(CDROMOBJ) $(HDDOBJ) \ diff --git a/src/scsi/scsi.h b/src/scsi/scsi.h index e61c0545d..ff8863753 100644 --- a/src/scsi/scsi.h +++ b/src/scsi/scsi.h @@ -281,7 +281,9 @@ extern int scsi_card_current; extern int scsi_card_available(int card); extern char *scsi_card_getname(int card); +#ifdef EMU_DEVICE_H extern device_t *scsi_card_getdevice(int card); +#endif extern int scsi_card_has_config(int card); extern char *scsi_card_get_internal_name(int card); extern int scsi_card_get_from_internal_name(char *s); diff --git a/src/win/plat_iodev.h b/src/win/plat_iodev.h index 650973483..c9f1ba874 100644 --- a/src/win/plat_iodev.h +++ b/src/win/plat_iodev.h @@ -1,3 +1,9 @@ +extern uint8_t host_cdrom_drive_available[26]; +extern uint8_t host_cdrom_drive_available_num; + + +extern void cdrom_init_host_drives(void); +extern void cdrom_close(uint8_t id); extern void cdrom_eject(uint8_t id); extern void cdrom_reload(uint8_t id); extern void removable_disk_unload(uint8_t id); diff --git a/src/win/win.c b/src/win/win.c index 586e0e910..493f1f9dc 100644 --- a/src/win/win.c +++ b/src/win/win.c @@ -8,13 +8,15 @@ * * The Emulator's Windows core. * - * Version: @(#)win.c 1.0.15 2017/10/05 + * Version: @(#)win.c 1.0.16 2017/10/06 * * Authors: Sarah Walker, * Miran Grca, * Fred N. van Kempen, + * * Copyright 2008-2017 Sarah Walker. * Copyright 2016,2017 Miran Grca. + * Copyright 2017 Fred N. van Kempen. */ #define UNICODE #define BITMAP WINDOWS_BITMAP @@ -33,25 +35,18 @@ #include #include "../86box.h" #include "../config.h" -#include "../cpu/cpu.h" #include "../ibm.h" #include "../mem.h" #include "../rom.h" #include "../device.h" #include "../nvr.h" #include "../mouse.h" -#include "../machine/machine.h" #include "../cdrom/cdrom.h" #include "../cdrom/cdrom_ioctl.h" #include "../cdrom/cdrom_image.h" #include "../cdrom/cdrom_null.h" -#include "../disk/hdd.h" -#include "../disk/hdc.h" -#include "../disk/hdc_ide.h" #include "../floppy/floppy.h" -#include "../floppy/fdd.h" #include "../scsi/scsi.h" -#include "../scsi/scsi_disk.h" #include "../network/network.h" #include "../video/video.h" #include "../video/vid_ega.h" @@ -87,18 +82,20 @@ HMENU menuMain; HANDLE ghMutex; HANDLE slirpMutex; HINSTANCE hinstance; +HICON hIcon[512]; RECT oldclip; int pause = 0; int scale = 0; uint64_t timer_freq; -int winsizex=640, winsizey=480; -int efwinsizey=480; +int winsizex = 640, + winsizey = 480; +int efwinsizey = 480; int gfx_present[GFX_MAX]; -int infocus=1; -int drawits=0; -int quited=0; -int mousecapture=0; +int infocus = 1; +int drawits = 0; +int quited = 0; +int mousecapture = 0; uint64_t main_time; @@ -107,7 +104,6 @@ static HHOOK hKeyboardHook; static int hook_enabled = 0; static HANDLE thMain; -static HICON hIcon[512]; static HWND hwndRender; /* machine render window */ static wchar_t wTitle[512]; static int save_window_pos = 0; @@ -117,8 +113,6 @@ static int unscaled_size_x = 0; static int unscaled_size_y = 0; static uint64_t start_time; static uint64_t end_time; -static uint8_t host_cdrom_drive_available[26]; -static uint8_t host_cdrom_drive_available_num = 0; static wchar_t **argv; static int argc; static wchar_t *argbuf; @@ -138,7 +132,7 @@ static struct { }; -static HICON +HICON LoadIconEx(PCTSTR pszIconName) { return((HICON)LoadImage(hinstance, pszIconName, IMAGE_ICON, @@ -146,1116 +140,6 @@ LoadIconEx(PCTSTR pszIconName) } -static HICON -LoadIconBig(PCTSTR pszIconName) -{ - return((HICON)LoadImage(hinstance, pszIconName, IMAGE_ICON, 64, 64, 0)); -} - - -/**************************************************************** - * Status Bar Handling * - ****************************************************************/ - -static HWND hwndSBAR; /* status bar window */ -static LONG_PTR OriginalStatusBarProcedure; -static HMENU *sb_menu_handles; -static HMENU menuSBAR; -static WCHAR **sbTips; -static int *iStatusWidths; -static int *sb_icon_flags; -static int *sb_part_meanings; -static int *sb_part_icons; -static int sb_parts = 0; -static int sb_ready = 0; - - -/* Also used by win_settings.c */ -int -fdd_type_to_icon(int type) -{ - int ret = 512; - - switch(type) { - case 0: - break; - - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: - ret = 128; - break; - - case 7: - case 8: - case 9: - case 10: - case 11: - case 12: - case 13: - ret = 144; - break; - - default: - break; - } - - return(ret); -} - - -/* FIXME: should be hdd_count() in hdd.c */ -static int -hdd_count(int bus) -{ - int c = 0; - int i; - - for (i=0; i= 'A') && - (cdrom_drives[id].host_drive <= 'Z')) { - cdrom_drives[id].host_drive = 0; - } - - goto check_menu_items; - } else { - if ((cdrom_drives[id].host_drive >= 'A') && - (cdrom_drives[id].host_drive <= 'Z')) { - if (!host_cdrom_drive_available[cdrom_drives[id].host_drive - 'A']) { - cdrom_drives[id].host_drive = 0; - } - } - } - - AppendMenu(m, MF_SEPARATOR, 0, 0); - - for (i=0; i<26; i++) { - _swprintf(s, L"Host CD/DVD Drive (%c:)", i+'A'); - if (host_cdrom_drive_available[i]) - AppendMenu(m, MF_STRING, IDM_CDROM_HOST_DRIVE | (i<<3)|id, s); - } - -check_menu_items: - if (! cdrom_drives[id].sound_on) - CheckMenuItem(m, IDM_CDROM_MUTE | id, MF_CHECKED); - - if (cdrom_drives[id].host_drive == 200) - CheckMenuItem(m, IDM_CDROM_IMAGE | id, MF_CHECKED); - else - if ((cdrom_drives[id].host_drive >= 'A') && (cdrom_drives[id].host_drive <= 'Z')) { - CheckMenuItem(m, IDM_CDROM_HOST_DRIVE | id | - ((cdrom_drives[id].host_drive - 'A') << 3), MF_CHECKED); - } else { - cdrom_drives[id].host_drive = 0; - CheckMenuItem(m, IDM_CDROM_EMPTY | id, MF_CHECKED); - } -} - - -static void -StatusBarCreateRemovableDiskSubmenu(HMENU m, int id) -{ - AppendMenu(m, MF_STRING, IDM_RDISK_EJECT | id, - win_language_get_string_from_id(IDS_2166)); - AppendMenu(m, MF_STRING, IDM_RDISK_RELOAD | id, - win_language_get_string_from_id(IDS_2167)); - AppendMenu(m, MF_SEPARATOR, 0, 0); - AppendMenu(m, MF_STRING, IDM_RDISK_SEND_CHANGE | id, - win_language_get_string_from_id(IDS_2142)); - AppendMenu(m, MF_SEPARATOR, 0, 0); - AppendMenu(m, MF_STRING, IDM_RDISK_IMAGE | id, - win_language_get_string_from_id(IDS_2168)); - AppendMenu(m, MF_STRING, IDM_RDISK_IMAGE_WP | id, - win_language_get_string_from_id(IDS_2169)); -} - - -/* API */ -int -StatusBarFindPart(int tag) -{ - int found = -1; - int i; - - if (!sb_ready || (sb_parts == 0) || (sb_part_meanings == NULL)) { - return -1; - } - - for (i=0; i= SB_TEXT) || !sb_ready || (sb_parts == 0) || (sb_icon_flags == NULL) || (sb_part_icons == NULL)) { - return; - } - - temp_flags |= active; - - found = StatusBarFindPart(tag); - 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(hwndSBAR, SB_SETICON, found, - (LPARAM)hIcon[sb_part_icons[found]]); - } - } -} - - -/* API: This is for the drive state indicator. */ -void -StatusBarUpdateIconState(int tag, int state) -{ - int found = -1; - - if (((tag & 0xf0) >= SB_HDD) || !sb_ready || (sb_parts == 0) || (sb_icon_flags == NULL) || (sb_part_icons == NULL)) { - return; - } - - found = StatusBarFindPart(tag); - 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(hwndSBAR, SB_SETICON, found, - (LPARAM)hIcon[sb_part_icons[found]]); - } -} - - -static void -StatusBarCreateFloppyTip(int part) -{ - WCHAR wtext[512]; - WCHAR tempTip[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(floppyfns[drive]) == 0) { - _swprintf(tempTip, win_language_get_string_from_id(IDS_2158), - drive+1, wtext, win_language_get_string_from_id(IDS_2057)); - } else { - _swprintf(tempTip, win_language_get_string_from_id(IDS_2158), - drive+1, wtext, floppyfns[drive]); - } - - if (sbTips[part] != NULL) - free(sbTips[part]); - sbTips[part] = (WCHAR *) malloc((wcslen(tempTip) << 1) + 2); - wcscpy(sbTips[part], tempTip); -} - - -static void -StatusBarCreateCdromTip(int part) -{ - WCHAR wtext[512]; - WCHAR tempTip[512]; - WCHAR *szText; - int id; - int drive = sb_part_meanings[part] & 0xf; - int bus = cdrom_drives[drive].bus_type; - - id = IDS_4352 + (bus - 1); - szText = (WCHAR *)win_language_get_string_from_id(id); - - if (cdrom_drives[drive].host_drive == 200) { - if (wcslen(cdrom_image[drive].image_path) == 0) { - _swprintf(tempTip, win_language_get_string_from_id(IDS_5120), drive + 1, szText, win_language_get_string_from_id(IDS_2057)); - } else { - _swprintf(tempTip, win_language_get_string_from_id(IDS_5120), drive + 1, szText, cdrom_image[drive].image_path); - } - } else if ((cdrom_drives[drive].host_drive >= 'A') && (cdrom_drives[drive].host_drive <= 'Z')) { - _swprintf(wtext, win_language_get_string_from_id(IDS_2058), cdrom_drives[drive].host_drive & ~0x20); - _swprintf(tempTip, win_language_get_string_from_id(IDS_5120), drive + 1, szText, wtext); - } else { - _swprintf(tempTip, win_language_get_string_from_id(IDS_5120), drive + 1, szText, win_language_get_string_from_id(IDS_2057)); - } - - if (sbTips[part] != NULL) - free(sbTips[part]); - sbTips[part] = (WCHAR *) malloc((wcslen(tempTip) << 1) + 2); - wcscpy(sbTips[part], tempTip); -} - - -static void -StatusBarCreateRemovableDiskTip(int part) -{ - WCHAR tempTip[512]; - int drive = sb_part_meanings[part] & 0x1f; - - if (wcslen(hdd[drive].fn) == 0) { - _swprintf(tempTip, win_language_get_string_from_id(IDS_4115), drive, win_language_get_string_from_id(IDS_2057)); - } else { - _swprintf(tempTip, win_language_get_string_from_id(IDS_4115), drive, hdd[drive].fn); - } - - if (sbTips[part] != NULL) - free(sbTips[part]); - sbTips[part] = (WCHAR *) malloc((wcslen(tempTip) << 1) + 2); - wcscpy(sbTips[part], tempTip); -} - - -static void -StatusBarCreateDiskTip(int part) -{ - WCHAR tempTip[512]; - WCHAR *szText; - int id; - int bus = sb_part_meanings[part] & 0xf; - - id = IDS_4352 + (bus - 1); - szText = (WCHAR *)win_language_get_string_from_id(id); - - _swprintf(tempTip, win_language_get_string_from_id(IDS_4096), szText); - if (sbTips[part] != NULL) - free(sbTips[part]); - sbTips[part] = (WCHAR *) malloc((wcslen(tempTip) << 1) + 2); - wcscpy(sbTips[part], tempTip); -} - - -static void -StatusBarCreateNetworkTip(int part) -{ - WCHAR tempTip[512]; - - _swprintf(tempTip, win_language_get_string_from_id(IDS_2069)); - - if (sbTips[part] != NULL) - free(sbTips[part]); - sbTips[part] = (WCHAR *) malloc((wcslen(tempTip) << 1) + 2); - wcscpy(sbTips[part], tempTip); -} - - -/* API */ -void -StatusBarUpdateTip(int meaning) -{ - int part = -1; - int i; - - if (!sb_ready || (sb_parts == 0) || (sb_part_meanings == NULL)) return; - - for (i=0; i 0) { - for (i = 0; i < sb_parts; i++) - SendMessage(hwndSBAR, SB_SETICON, i, (LPARAM)NULL); - SendMessage(hwndSBAR, SB_SETPARTS, (WPARAM)0, (LPARAM)NULL); - - if (iStatusWidths) { - free(iStatusWidths); - iStatusWidths = NULL; - } - if (sb_part_meanings) { - free(sb_part_meanings); - sb_part_meanings = NULL; - } - if (sb_part_icons) { - free(sb_part_icons); - sb_part_icons = NULL; - } - if (sb_icon_flags) { - free(sb_icon_flags); - sb_icon_flags = NULL; - } - StatusBarDestroyMenus(); - StatusBarDestroyTips(); - } - sb_parts = 0; - - for (i=0; i= 'A') && (cdrom_drives[id].host_drive <= 'Z')) { - sb_icon_flags[i] = 0; - } else { - sb_icon_flags[i] = 256; - } - sb_part_icons[i] = 160 | sb_icon_flags[i]; - sb_menu_handles[i] = StatusBarCreatePopupMenu(i); - StatusBarCreateCdromSubmenu(sb_menu_handles[i], sb_part_meanings[i] & 0xf); - EnableMenuItem(sb_menu_handles[i], IDM_CDROM_RELOAD | (sb_part_meanings[i] & 0xf), MF_BYCOMMAND | MF_GRAYED); - StatusBarCreateCdromTip(i); - break; - - case SB_RDISK: /* Removable hard disk */ - sb_icon_flags[i] = (wcslen(hdd[sb_part_meanings[i] & 0x1f].fn) == 0) ? 256 : 0; - sb_part_icons[i] = 176 + sb_icon_flags[i]; - sb_menu_handles[i] = StatusBarCreatePopupMenu(i); - StatusBarCreateRemovableDiskSubmenu(sb_menu_handles[i], sb_part_meanings[i] & 0x1f); - EnableMenuItem(sb_menu_handles[i], IDM_RDISK_EJECT | (sb_part_meanings[i] & 0x1f), MF_BYCOMMAND | ((sb_icon_flags[i] & 256) ? MF_GRAYED : MF_ENABLED)); - EnableMenuItem(sb_menu_handles[i], IDM_RDISK_RELOAD | (sb_part_meanings[i] & 0x1f), MF_BYCOMMAND | MF_GRAYED); - EnableMenuItem(sb_menu_handles[i], IDM_RDISK_SEND_CHANGE | (sb_part_meanings[i] & 0x1f), MF_BYCOMMAND | ((sb_icon_flags[i] & 256) ? MF_GRAYED : MF_ENABLED)); - StatusBarCreateRemovableDiskTip(i); - break; - - case SB_HDD: /* Hard disk */ - sb_part_icons[i] = 192; - StatusBarCreateDiskTip(i); - break; - - case SB_NETWORK: /* Network */ - sb_part_icons[i] = 208; - StatusBarCreateNetworkTip(i); - break; - - case SB_TEXT: /* Status text */ - SendMessage(hwndSBAR, SB_SETTEXT, i | SBT_NOBORDERS, (LPARAM) L""); - sb_part_icons[i] = -1; - break; - } - - if (sb_part_icons[i] != -1) { - SendMessage(hwndSBAR, SB_SETTEXT, i | SBT_NOBORDERS, (LPARAM)""); - SendMessage(hwndSBAR, SB_SETICON, i, (LPARAM)hIcon[sb_part_icons[i]]); - SendMessage(hwndSBAR, SB_SETTIPTEXT, i, (LPARAM)sbTips[i]); - } else { - SendMessage(hwndSBAR, SB_SETICON, i, (LPARAM)NULL); - } - } - - sb_ready = 1; -} - - -static VOID APIENTRY -StatusBarPopupMenu(HWND hwnd, POINT pt, int id) -{ - 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); - TrackPopupMenu(sb_menu_handles[id], - TPM_LEFTALIGN | TPM_BOTTOMALIGN | TPM_LEFTBUTTON, - pt.x, pt.y, 0, hwndSBAR, NULL); -} - - -/* Handle messages for the Status Bar window. */ -static LRESULT CALLBACK -StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - WCHAR temp_image_path[1024]; - RECT rc; - POINT pt; - int new_cdrom_drive; - int ret = 0; - int item_id = 0; - int item_params = 0; - int id = 0; - int part = 0; - int letter = 0; - - switch (message) { - case WM_COMMAND: - item_id = LOWORD(wParam) & 0xff00; /* low 8 bits */ - item_params = LOWORD(wParam) & 0x00ff; /* high 8 bits */ - - switch (item_id) { - case IDM_FLOPPY_IMAGE_EXISTING: - case IDM_FLOPPY_IMAGE_EXISTING_WP: - id = item_params & 0x0003; - part = StatusBarFindPart(SB_FLOPPY | id); - if ((part == -1) || (sb_menu_handles == NULL)) - break; - - ret = file_dlg_w_st(hwnd, IDS_2159, floppyfns[id], 0); - if (! ret) { - floppy_close(id); - ui_writeprot[id] = (item_id == IDM_FLOPPY_IMAGE_EXISTING_WP) ? 1 : 0; - floppy_load(id, wopenfilestring); - StatusBarUpdateIconState(SB_FLOPPY | id, wcslen(floppyfns[id]) ? 0 : 1); - EnableMenuItem(sb_menu_handles[part], IDM_FLOPPY_EJECT | id, MF_BYCOMMAND | (wcslen(floppyfns[id]) ? MF_ENABLED : MF_GRAYED)); - StatusBarUpdateTip(SB_FLOPPY | id); - config_save(); - } - break; - - case IDM_FLOPPY_EJECT: - id = item_params & 0x0003; - part = StatusBarFindPart(SB_FLOPPY | id); - if ((part == -1) || (sb_menu_handles == NULL)) - break; - - floppy_close(id); - StatusBarUpdateIconState(SB_FLOPPY | id, 1); - EnableMenuItem(sb_menu_handles[part], IDM_FLOPPY_EJECT | id, MF_BYCOMMAND | MF_GRAYED); - StatusBarUpdateTip(SB_FLOPPY | id); - config_save(); - break; - - case IDM_CDROM_MUTE: - id = item_params & 0x0007; - part = StatusBarFindPart(SB_CDROM | id); - if ((part == -1) || (sb_menu_handles == NULL)) - break; - - cdrom_drives[id].sound_on ^= 1; - CheckMenuItem(sb_menu_handles[part], IDM_CDROM_MUTE | id, cdrom_drives[id].sound_on ? MF_UNCHECKED : MF_CHECKED); - config_save(); - sound_cd_thread_reset(); - break; - - case IDM_CDROM_EMPTY: - id = item_params & 0x0007; - cdrom_eject(id); - break; - - case IDM_CDROM_RELOAD: - id = item_params & 0x0007; - cdrom_reload(id); - break; - - case IDM_CDROM_IMAGE: - id = item_params & 0x0007; - part = StatusBarFindPart(SB_CDROM | id); - if ((part == -1) || (sb_menu_handles == NULL)) - break; - - if (!file_dlg_w_st(hwnd, IDS_2075, cdrom_image[id].image_path, 0)) { - cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; - wcscpy(temp_image_path, wopenfilestring); - if ((wcscmp(cdrom_image[id].image_path, temp_image_path) == 0) && (cdrom_drives[id].host_drive == 200)) { - /* Switching from image to the same image. Do nothing. */ - break; - } - wcscpy(cdrom_image[id].prev_image_path, cdrom_image[id].image_path); - cdrom_drives[id].handler->exit(id); - cdrom_close(id); - image_open(id, temp_image_path); - /* Signal media change to the emulated machine. */ - cdrom_insert(id); - CheckMenuItem(sb_menu_handles[part], IDM_CDROM_EMPTY | id, MF_UNCHECKED); - if ((cdrom_drives[id].host_drive >= 'A') && (cdrom_drives[id].host_drive <= 'Z')) { - CheckMenuItem(sb_menu_handles[part], IDM_CDROM_HOST_DRIVE | id | ((cdrom_drives[id].host_drive - 'A') << 3), MF_UNCHECKED); - } - cdrom_drives[id].host_drive = (wcslen(cdrom_image[id].image_path) == 0) ? 0 : 200; - if (cdrom_drives[id].host_drive == 200) { - CheckMenuItem(sb_menu_handles[part], IDM_CDROM_IMAGE | id, MF_CHECKED); - StatusBarUpdateIconState(SB_CDROM | id, 0); - } else { - CheckMenuItem(sb_menu_handles[part], IDM_CDROM_IMAGE | id, MF_UNCHECKED); - CheckMenuItem(sb_menu_handles[part], IDM_CDROM_EMPTY | id, MF_UNCHECKED); - StatusBarUpdateIconState(SB_CDROM | id, 1); - } - EnableMenuItem(sb_menu_handles[part], IDM_CDROM_RELOAD | id, MF_BYCOMMAND | MF_GRAYED); - StatusBarUpdateTip(SB_CDROM | id); - config_save(); - } - break; - - case IDM_CDROM_HOST_DRIVE: - id = item_params & 0x0007; - letter = ((item_params >> 3) & 0x001f) + 'A'; - part = StatusBarFindPart(SB_CDROM | id); - if ((part == -1) || (sb_menu_handles == NULL)) - { - break; - } - - new_cdrom_drive = letter; - if (cdrom_drives[id].host_drive == new_cdrom_drive) - { - /* Switching to the same drive. Do nothing. */ - break; - } - cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; - cdrom_drives[id].handler->exit(id); - cdrom_close(id); - ioctl_open(id, new_cdrom_drive); - /* Signal media change to the emulated machine. */ - cdrom_insert(id); - CheckMenuItem(sb_menu_handles[part], IDM_CDROM_EMPTY | id, MF_UNCHECKED); - if ((cdrom_drives[id].host_drive >= 'A') && (cdrom_drives[id].host_drive <= 'Z')) - { - CheckMenuItem(sb_menu_handles[part], IDM_CDROM_HOST_DRIVE | id | ((cdrom_drives[id].host_drive - 'A') << 3), MF_UNCHECKED); - } - CheckMenuItem(sb_menu_handles[part], IDM_CDROM_IMAGE | id, MF_UNCHECKED); - cdrom_drives[id].host_drive = new_cdrom_drive; - CheckMenuItem(sb_menu_handles[part], IDM_CDROM_HOST_DRIVE | id | ((cdrom_drives[id].host_drive - 'A') << 3), MF_CHECKED); - EnableMenuItem(sb_menu_handles[part], IDM_CDROM_RELOAD | id, MF_BYCOMMAND | MF_GRAYED); - StatusBarUpdateIconState(SB_CDROM | id, 0); - StatusBarUpdateTip(SB_CDROM | id); - config_save(); - break; - - case IDM_RDISK_EJECT: - id = item_params & 0x001f; - removable_disk_eject(id); - break; - - case IDM_RDISK_RELOAD: - id = item_params & 0x001f; - removable_disk_reload(id); - break; - - case IDM_RDISK_SEND_CHANGE: - id = item_params & 0x001f; - scsi_disk_insert(id); - break; - - case IDM_RDISK_IMAGE: - case IDM_RDISK_IMAGE_WP: - id = item_params & 0x001f; - ret = file_dlg_w_st(hwnd, IDS_4106, hdd[id].fn, id); - if (!ret) { - removable_disk_unload(id); - memset(hdd[id].fn, 0, sizeof(hdd[id].fn)); - wcscpy(hdd[id].fn, wopenfilestring); - hdd[id].wp = (item_id == IDM_RDISK_IMAGE_WP) ? 1 : 0; - scsi_loadhd(hdd[id].scsi_id, hdd[id].scsi_lun, id); - scsi_disk_insert(id); - if (wcslen(hdd[id].fn) > 0) { - StatusBarUpdateIconState(SB_RDISK | id, 0); - EnableMenuItem(sb_menu_handles[part], IDM_RDISK_EJECT | id, MF_BYCOMMAND | MF_ENABLED); - EnableMenuItem(sb_menu_handles[part], IDM_RDISK_RELOAD | id, MF_BYCOMMAND | MF_GRAYED); - EnableMenuItem(sb_menu_handles[part], IDM_RDISK_SEND_CHANGE | id, MF_BYCOMMAND | MF_ENABLED); - } - else { - StatusBarUpdateIconState(SB_RDISK | id, 1); - EnableMenuItem(sb_menu_handles[part], IDM_RDISK_EJECT | id, MF_BYCOMMAND | MF_GRAYED); - EnableMenuItem(sb_menu_handles[part], IDM_RDISK_RELOAD | id, MF_BYCOMMAND | MF_GRAYED); - EnableMenuItem(sb_menu_handles[part], IDM_RDISK_SEND_CHANGE | id, MF_BYCOMMAND | MF_GRAYED); - } - StatusBarUpdateTip(SB_RDISK | id); - config_save(); - } - break; - - default: - 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)) - StatusBarPopupMenu(hwnd, pt, (pt.x / SB_ICON_WIDTH)); - break; - - default: - return(CallWindowProc((WNDPROC)OriginalStatusBarProcedure, - hwnd, message, wParam, lParam)); - } - - return(0); -} - - -/* Create and set up the Status Bar window. */ -static void -StatusBarCreate(HWND hwndParent, int idStatus, HINSTANCE hInst) -{ - RECT rectDialog; - int dw, dh, i; - - for (i = 128; i < 130; i++) - hIcon[i] = LoadIconEx((PCTSTR) i); - for (i = 144; i < 146; i++) - hIcon[i] = LoadIconEx((PCTSTR) i); - for (i = 160; i < 162; i++) - hIcon[i] = LoadIconEx((PCTSTR) i); - for (i = 176; i < 178; i++) - hIcon[i] = LoadIconEx((PCTSTR) i); - for (i = 192; i < 194; i++) - hIcon[i] = LoadIconEx((PCTSTR) i); - for (i = 208; i < 210; i++) - hIcon[i] = LoadIconEx((PCTSTR) i); - for (i = 384; i < 386; i++) - hIcon[i] = LoadIconEx((PCTSTR) i); - for (i = 400; i < 402; i++) - hIcon[i] = LoadIconEx((PCTSTR) i); - for (i = 416; i < 418; i++) - hIcon[i] = LoadIconEx((PCTSTR) i); - for (i = 432; i < 434; i++) - hIcon[i] = LoadIconEx((PCTSTR) i); - - GetWindowRect(hwndParent, &rectDialog); - dw = rectDialog.right - rectDialog.left; - dh = rectDialog.bottom - rectDialog.top; - - /* Load the Common Controls DLL if needed. */ - InitCommonControls(); - - /* Create the window, and make sure it's using the STATUS class. */ - hwndSBAR = CreateWindowEx(0, - STATUSCLASSNAME, - (LPCTSTR)NULL, - SBARS_SIZEGRIP|WS_CHILD|WS_VISIBLE|SBT_TOOLTIPS, - 0, dh-17, dw, 17, - hwndParent, - (HMENU)idStatus, hInst, NULL); - - /* Replace the original procedure with ours. */ - OriginalStatusBarProcedure = GetWindowLongPtr(hwndSBAR, GWLP_WNDPROC); - SetWindowLongPtr(hwndSBAR, GWL_WNDPROC, (LONG_PTR)&StatusBarProcedure); - - SendMessage(hwndSBAR, SB_SETMINHEIGHT, (WPARAM)17, (LPARAM)0); - - /* Align the window with the parent (main) window. */ - GetWindowRect(hwndSBAR, &rectDialog); - SetWindowPos(hwndSBAR, - HWND_TOPMOST, - rectDialog.left, rectDialog.top, - rectDialog.right-rectDialog.left, - rectDialog.bottom-rectDialog.top, - SWP_SHOWWINDOW); - - /* Load the dummu menu for this window. */ - menuSBAR = LoadMenu(hInst, SB_MENU_NAME); - - /* Initialize the status bar and populate the icons and menus. */ - sb_parts = 0; - StatusBarUpdatePanes(); -} - - -/* API */ -void -StatusBarSetTextW(wchar_t *wstr) -{ - int part = -1; - int i; - - if (!sb_ready || (sb_parts == 0) || (sb_part_meanings == NULL)) return; - - for (i=0; i= 'A') && - (cdrom_drives[id].host_drive <= 'Z')) { - CheckMenuItem(sb_menu_handles[part], IDM_CDROM_HOST_DRIVE | id | ((cdrom_drives[id].host_drive - 'A') << 3), MF_UNCHECKED); - } - if (cdrom_drives[id].host_drive == 200) { - wcscpy(cdrom_image[id].prev_image_path, cdrom_image[id].image_path); - } - cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; - cdrom_drives[id].handler->exit(id); - cdrom_close(id); - cdrom_null_open(id, 0); - if (cdrom_drives[id].bus_type) { - /* Signal disc change to the emulated machine. */ - cdrom_insert(id); - } - CheckMenuItem(sb_menu_handles[part], IDM_CDROM_IMAGE | id, MF_UNCHECKED); - cdrom_drives[id].host_drive=0; - CheckMenuItem(sb_menu_handles[part], IDM_CDROM_EMPTY | id, MF_CHECKED); - StatusBarUpdateIconState(SB_CDROM | id, 1); - EnableMenuItem(sb_menu_handles[part], IDM_CDROM_RELOAD | id, MF_BYCOMMAND | MF_ENABLED); - StatusBarUpdateTip(SB_CDROM | id); - - config_save(); -} - - -void -cdrom_reload(uint8_t id) -{ - int new_cdrom_drive; - int part; - - part = StatusBarFindPart(SB_CDROM | id); - if ((part == -1) || (sb_menu_handles == NULL)) return; - - if ((cdrom_drives[id].host_drive == cdrom_drives[id].prev_host_drive) || (cdrom_drives[id].prev_host_drive == 0) || (cdrom_drives[id].host_drive != 0)) { - /* Switch from empty to empty. Do nothing. */ - return; - } - - cdrom_close(id); - if (cdrom_drives[id].prev_host_drive == 200) { - wcscpy(cdrom_image[id].image_path, cdrom_image[id].prev_image_path); - image_open(id, cdrom_image[id].image_path); - if (cdrom_drives[id].bus_type) { - /* Signal disc change to the emulated machine. */ - cdrom_insert(id); - } - if (wcslen(cdrom_image[id].image_path) == 0) { - CheckMenuItem(sb_menu_handles[part], IDM_CDROM_EMPTY | id, MF_CHECKED); - cdrom_drives[id].host_drive = 0; - CheckMenuItem(sb_menu_handles[part], IDM_CDROM_IMAGE | id, MF_UNCHECKED); - StatusBarUpdateIconState(SB_CDROM | id, 1); - } else { - CheckMenuItem(sb_menu_handles[part], IDM_CDROM_EMPTY | id, MF_UNCHECKED); - cdrom_drives[id].host_drive = 200; - CheckMenuItem(sb_menu_handles[part], IDM_CDROM_IMAGE | id, MF_CHECKED); - StatusBarUpdateIconState(SB_CDROM | id, 0); - } - } else { - new_cdrom_drive = cdrom_drives[id].prev_host_drive; - ioctl_open(id, new_cdrom_drive); - if (cdrom_drives[id].bus_type) { - /* Signal disc change to the emulated machine. */ - cdrom_insert(id); - } - CheckMenuItem(sb_menu_handles[part], IDM_CDROM_EMPTY | id, MF_UNCHECKED); - cdrom_drives[id].host_drive = new_cdrom_drive; - CheckMenuItem(sb_menu_handles[part], IDM_CDROM_HOST_DRIVE | id | ((cdrom_drives[id].host_drive - 'A') << 3), MF_CHECKED); - StatusBarUpdateIconState(SB_CDROM | id, 0); - } - - EnableMenuItem(sb_menu_handles[part], IDM_CDROM_RELOAD | id, MF_BYCOMMAND | MF_GRAYED); - StatusBarUpdateTip(SB_CDROM | id); - - config_save(); -} - - -void -removable_disk_unload(uint8_t id) -{ - if (wcslen(hdd[id].fn) == 0) { - /* Switch from empty to empty. Do nothing. */ - return; - } - - scsi_unloadhd(hdd[id].scsi_id, hdd[id].scsi_lun, id); - scsi_disk_insert(id); -} - - -void -removable_disk_eject(uint8_t id) -{ - int part = 0; - - part = StatusBarFindPart(SB_CDROM | id); - if ((part == -1) || (sb_menu_handles == NULL)) return; - - removable_disk_unload(id); - StatusBarUpdateIconState(SB_RDISK | id, 1); - EnableMenuItem(sb_menu_handles[part], IDM_RDISK_EJECT | id, MF_BYCOMMAND | MF_GRAYED); - EnableMenuItem(sb_menu_handles[part], IDM_RDISK_RELOAD | id, MF_BYCOMMAND | MF_ENABLED); - EnableMenuItem(sb_menu_handles[part], IDM_RDISK_SEND_CHANGE | id, MF_BYCOMMAND | MF_GRAYED); - - StatusBarUpdateTip(SB_RDISK | id); - - config_save(); -} - - -void -removable_disk_reload(uint8_t id) -{ - int part = 0; - - part = StatusBarFindPart(SB_CDROM | id); - if ((part == -1) || (sb_menu_handles == NULL)) return; - - if (wcslen(hdd[id].fn) != 0) { - /* Attempting to reload while an image is already loaded. Do nothing. */ - return; - } - - scsi_reloadhd(id); -#if 0 - scsi_disk_insert(id); -#endif - - StatusBarUpdateIconState(SB_RDISK | id, wcslen(hdd[id].fn) ? 0 : 1); - - EnableMenuItem(sb_menu_handles[part], IDM_RDISK_EJECT | id, MF_BYCOMMAND | (wcslen(hdd[id].fn) ? MF_ENABLED : MF_GRAYED)); - EnableMenuItem(sb_menu_handles[part], IDM_RDISK_RELOAD | id, MF_BYCOMMAND | MF_GRAYED); - EnableMenuItem(sb_menu_handles[part], IDM_RDISK_SEND_CHANGE | id, MF_BYCOMMAND | (wcslen(hdd[id].fn) ? MF_ENABLED : MF_GRAYED)); - - StatusBarUpdateTip(SB_RDISK | id); - - config_save(); -} diff --git a/src/win/win.h b/src/win/win.h index 99bae1d35..49cd08439 100644 --- a/src/win/win.h +++ b/src/win/win.h @@ -12,7 +12,7 @@ * Windows-specific header files needed, to keep them * out of the main code. * - * Version: @(#)win.h 1.0.2 2017/10/05 + * Version: @(#)win.h 1.0.3 2017/10/06 * * Authors: Sarah Walker, * Miran Grca, @@ -54,6 +54,7 @@ extern HINSTANCE hinstance; extern HWND hwndMain; +extern HICON hIcon[512]; extern int status_is_open; extern int mousecapture; @@ -84,7 +85,6 @@ extern void startblit(void); extern void endblit(void); extern void win_settings_open(HWND hwnd); -extern void win_menu_update(); extern void hard_disk_add_open(HWND hwnd, int is_existing); extern int hard_disk_was_added(void); @@ -95,13 +95,17 @@ extern void process_raw_input(LPARAM lParam, int infocus); extern void cdrom_init_host_drives(void); extern void cdrom_close(uint8_t id); +extern HICON LoadIconEx(PCTSTR pszIconName); + extern BOOL DirectoryExists(LPCTSTR szPath); +/* About dialog definitions. */ +extern void AboutDialogCreate(HWND hwnd); + /* Status Window definitions. */ extern HWND hwndStatus; extern void StatusWindowCreate(HWND hwnd); - /* Status Bar definitions. */ #define SB_ICON_WIDTH 24 #define SB_FLOPPY 0x00 @@ -111,12 +115,16 @@ extern void StatusWindowCreate(HWND hwnd); #define SB_NETWORK 0x50 #define SB_TEXT 0x60 +extern HWND hwndSBAR; +extern void StatusBarCreate(HWND hwndParent, int idStatus, HINSTANCE hInst); extern int fdd_type_to_icon(int type); extern int StatusBarFindPart(int tag); extern void StatusBarUpdatePanes(void); extern void StatusBarUpdateTip(int meaning); extern void StatusBarUpdateIcon(int tag, int val); extern void StatusBarUpdateIconState(int tag, int active); +extern void StatusBarCheckMenuItem(int tag, int id, int chk); +extern void StatusBarEnableMenuItem(int tag, int id, int val); extern void StatusBarSetTextW(wchar_t *wstr); extern void StatusBarSetText(char *str); diff --git a/src/win/win_about.c b/src/win/win_about.c new file mode 100644 index 000000000..2982d67dd --- /dev/null +++ b/src/win/win_about.c @@ -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. + * + * Handle the About dialog. + * + * Version: @(#)win_about.c 1.0.1 2017/10/06 + * + * Authors: Sarah Walker, + * Miran Grca, + * Fred N. van Kempen, + * + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016,2017 Miran Grca. + * Copyright 2017 Fred N. van Kempen. + */ +#define UNICODE +#define BITMAP WINDOWS_BITMAP +#include +#include +#undef BITMAP +#include +#include +#include +#include +#include +#include "../86box.h" +#include "../ibm.h" +#include "win.h" +#include "win_language.h" + + +#ifndef MAPVK_VK_TO_VSC +#define MAPVK_VK_TO_VSC 0 +#endif + + +static BOOL CALLBACK +AboutDialogProcedure(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)LoadImage(hinstance,(PCTSTR)100,IMAGE_ICON,64,64,0)); + break; + + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDOK: + EndDialog(hdlg, 0); + pause = 0; + return TRUE; + + default: + break; + } + break; + } + + return(FALSE); +} + + +void +AboutDialogCreate(HWND hwnd) +{ + DialogBox(hinstance, (LPCTSTR)DLG_ABOUT, hwnd, AboutDialogProcedure); +} diff --git a/src/win/win_cdrom.c b/src/win/win_cdrom.c new file mode 100644 index 000000000..d38517c39 --- /dev/null +++ b/src/win/win_cdrom.c @@ -0,0 +1,224 @@ +/* + * 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. + * + * Handle the platform-side of CDROM drives. + * + * Version: @(#)win_cdrom.c 1.0.1 2017/10/06 + * + * Authors: Sarah Walker, + * Miran Grca, + * Fred N. van Kempen, + * + * Copyright 2016,2017 Miran Grca. + * Copyright 2017 Fred N. van Kempen. + */ +#define UNICODE +#define BITMAP WINDOWS_BITMAP +#include +#include +#undef BITMAP +#include +#include +#include +#include +#include +#include "../config.h" +#include "../cdrom/cdrom.h" +#include "../cdrom/cdrom_ioctl.h" +#include "../cdrom/cdrom_image.h" +#include "../cdrom/cdrom_null.h" +#include "../disk/hdd.h" +#include "../scsi/scsi.h" +#include "../scsi/scsi_disk.h" +#include "plat_ui.h" +#include "win.h" +#include "win_language.h" + + +uint8_t host_cdrom_drive_available[26]; +uint8_t host_cdrom_drive_available_num = 0; + + +void +cdrom_init_host_drives(void) +{ + WCHAR s[64]; + int i = 0; + + host_cdrom_drive_available_num = 0; + for (i='A'; i<='Z'; i++) { + _swprintf(s, L"%c:\\", i); + + if (GetDriveType(s)==DRIVE_CDROM) { + host_cdrom_drive_available[i - 'A'] = 1; + + host_cdrom_drive_available_num++; + } else { + host_cdrom_drive_available[i - 'A'] = 0; + } + } +} + + +void +cdrom_close(uint8_t id) +{ + switch (cdrom_drives[id].host_drive) { + case 0: + null_close(id); + break; + + case 200: + image_close(id); + break; + + default: + ioctl_close(id); + break; + } +} + + +void +cdrom_eject(uint8_t id) +{ + if (cdrom_drives[id].host_drive == 0) { + /* Switch from empty to empty. Do nothing. */ + return; + } + + if ((cdrom_drives[id].host_drive >= 'A') && + (cdrom_drives[id].host_drive <= 'Z')) { + StatusBarCheckMenuItem(SB_CDROM|id, + IDM_CDROM_HOST_DRIVE | id | ((cdrom_drives[id].host_drive - 'A') << 3), MF_UNCHECKED); + } + + if (cdrom_drives[id].host_drive == 200) { + wcscpy(cdrom_image[id].prev_image_path, cdrom_image[id].image_path); + } + cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; + cdrom_drives[id].handler->exit(id); + cdrom_close(id); + cdrom_null_open(id, 0); + if (cdrom_drives[id].bus_type) { + /* Signal disc change to the emulated machine. */ + cdrom_insert(id); + } + + StatusBarCheckMenuItem(SB_CDROM|id, IDM_CDROM_IMAGE | id, MF_UNCHECKED); + cdrom_drives[id].host_drive=0; + StatusBarCheckMenuItem(SB_CDROM|id, IDM_CDROM_EMPTY | id, MF_CHECKED); + StatusBarUpdateIconState(SB_CDROM|id, 1); + StatusBarEnableMenuItem(SB_CDROM|id, IDM_CDROM_RELOAD | id, MF_BYCOMMAND | MF_ENABLED); + StatusBarUpdateTip(SB_CDROM|id); + + config_save(); +} + + +void +cdrom_reload(uint8_t id) +{ + 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) { + wcscpy(cdrom_image[id].image_path, cdrom_image[id].prev_image_path); + image_open(id, cdrom_image[id].image_path); + if (cdrom_drives[id].bus_type) { + /* Signal disc change to the emulated machine. */ + cdrom_insert(id); + } + if (wcslen(cdrom_image[id].image_path) == 0) { + StatusBarCheckMenuItem(SB_CDROM|id, IDM_CDROM_EMPTY | id, MF_CHECKED); + cdrom_drives[id].host_drive = 0; + StatusBarCheckMenuItem(SB_CDROM|id, IDM_CDROM_IMAGE | id, MF_UNCHECKED); + StatusBarUpdateIconState(SB_CDROM|id, 1); + } else { + StatusBarCheckMenuItem(SB_CDROM|id, IDM_CDROM_EMPTY | id, MF_UNCHECKED); + cdrom_drives[id].host_drive = 200; + StatusBarCheckMenuItem(SB_CDROM|id, IDM_CDROM_IMAGE | id, MF_CHECKED); + StatusBarUpdateIconState(SB_CDROM|id, 0); + } + } else { + new_cdrom_drive = cdrom_drives[id].prev_host_drive; + ioctl_open(id, new_cdrom_drive); + if (cdrom_drives[id].bus_type) { + /* Signal disc change to the emulated machine. */ + cdrom_insert(id); + } + StatusBarCheckMenuItem(SB_CDROM|id, IDM_CDROM_EMPTY | id, MF_UNCHECKED); + cdrom_drives[id].host_drive = new_cdrom_drive; + StatusBarCheckMenuItem(SB_CDROM|id, IDM_CDROM_HOST_DRIVE | id | ((cdrom_drives[id].host_drive - 'A') << 3), MF_CHECKED); + StatusBarUpdateIconState(SB_CDROM|id, 0); + } + + StatusBarEnableMenuItem(SB_CDROM|id, IDM_CDROM_RELOAD | id, MF_BYCOMMAND | MF_GRAYED); + StatusBarUpdateTip(SB_CDROM|id); + + config_save(); +} + + +void +removable_disk_unload(uint8_t id) +{ + if (wcslen(hdd[id].fn) == 0) { + /* Switch from empty to empty. Do nothing. */ + return; + } + + scsi_unloadhd(hdd[id].scsi_id, hdd[id].scsi_lun, id); + scsi_disk_insert(id); +} + + +void +removable_disk_eject(uint8_t id) +{ + removable_disk_unload(id); + StatusBarUpdateIconState(SB_RDISK|id, 1); + StatusBarEnableMenuItem(SB_RDISK|id, IDM_RDISK_EJECT | id, MF_BYCOMMAND | MF_GRAYED); + StatusBarEnableMenuItem(SB_RDISK|id, IDM_RDISK_RELOAD | id, MF_BYCOMMAND | MF_ENABLED); + StatusBarEnableMenuItem(SB_RDISK|id, IDM_RDISK_SEND_CHANGE | id, MF_BYCOMMAND | MF_GRAYED); + + StatusBarUpdateTip(SB_RDISK|id); + + config_save(); +} + + +void +removable_disk_reload(uint8_t id) +{ + if (wcslen(hdd[id].fn) != 0) { + /* Attempting to reload while an image is already loaded. Do nothing. */ + return; + } + + scsi_reloadhd(id); +#if 0 + scsi_disk_insert(id); +#endif + + StatusBarUpdateIconState(SB_RDISK|id, wcslen(hdd[id].fn) ? 0 : 1); + + StatusBarEnableMenuItem(SB_RDISK|id, IDM_RDISK_EJECT | id, MF_BYCOMMAND | (wcslen(hdd[id].fn) ? MF_ENABLED : MF_GRAYED)); + StatusBarEnableMenuItem(SB_RDISK|id, IDM_RDISK_RELOAD | id, MF_BYCOMMAND | MF_GRAYED); + StatusBarEnableMenuItem(SB_RDISK|id, IDM_RDISK_SEND_CHANGE | id, MF_BYCOMMAND | (wcslen(hdd[id].fn) ? MF_ENABLED : MF_GRAYED)); + + StatusBarUpdateTip(SB_RDISK|id); + + config_save(); +} diff --git a/src/win/win_d3d.h b/src/win/win_d3d.h index 11128d486..7829d08a7 100644 --- a/src/win/win_d3d.h +++ b/src/win/win_d3d.h @@ -33,6 +33,7 @@ extern int d3d_init(HWND h); extern void d3d_close(void); extern void d3d_reset(void); extern void d3d_resize(int x, int y); +extern void d3d_take_screenshot(wchar_t *fn); extern int d3d_fs_init(HWND h); extern void d3d_fs_close(void); diff --git a/src/win/win_ddraw.cc b/src/win/win_ddraw.cc index fc6dec759..747d305b5 100644 --- a/src/win/win_ddraw.cc +++ b/src/win/win_ddraw.cc @@ -3,9 +3,15 @@ */ #include #include +#define UNICODE +#define BITMAP WINDOWS_BITMAP +#include +#undef BITMAP #include "../video/video.h" #include "win_ddraw.h" #include "win_cgapal.h" +#include "win.h" +#include "win_language.h" extern "C" void fatal(const char *format, ...); @@ -18,8 +24,6 @@ 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; @@ -28,261 +32,373 @@ static LPDIRECTDRAWSURFACE7 lpdds_back = NULL; static LPDIRECTDRAWSURFACE7 lpdds_back2 = NULL; static LPDIRECTDRAWCLIPPER lpdd_clipper = NULL; static DDSURFACEDESC2 ddsd; - static HWND ddraw_hwnd; +static HBITMAP hbitmap; +static int xs, ys, ys2; -int ddraw_init(HWND h) -{ -#if NO_THIS_CRASHES_NOW - cgapal_rebuild(); -#endif - if (FAILED(DirectDrawCreate(NULL, &lpdd, NULL))) - return 0; - - if (FAILED(lpdd->QueryInterface(IID_IDirectDraw7, (LPVOID *)&lpdd7))) - return 0; +static void +CopySurface(IDirectDrawSurface7 *pDDSurface) +{ + HDC hdc, hmemdc; + HBITMAP hprevbitmap; + DDSURFACEDESC2 ddsd2; - lpdd->Release(); - lpdd = NULL; - - atexit(ddraw_close); - - if (FAILED(lpdd7->SetCooperativeLevel(h, DDSCL_NORMAL))) - return 0; - - memset(&ddsd, 0, sizeof(ddsd)); - ddsd.dwSize = sizeof(ddsd); - - ddsd.dwFlags = DDSD_CAPS; - ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; - if (FAILED(lpdd7->CreateSurface(&ddsd, &lpdds_pri, NULL))) - return 0; - - // memset(&ddsd, 0, sizeof(ddsd)); - // ddsd.dwSize = sizeof(ddsd); - - ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; - ddsd.dwWidth = 2048; - ddsd.dwHeight = 2048; - ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY; - if (FAILED(lpdd7->CreateSurface(&ddsd, &lpdds_back, NULL))) - { - ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; - ddsd.dwWidth = 2048; - ddsd.dwHeight = 2048; - ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; - if (FAILED(lpdd7->CreateSurface(&ddsd, &lpdds_back, NULL))) - fatal("CreateSurface back failed\n"); - } - - memset(&ddsd, 0, sizeof(ddsd)); - ddsd.dwSize = sizeof(ddsd); - - ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; - ddsd.dwWidth = 2048; - ddsd.dwHeight = 2048; - ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY; - if (FAILED(lpdd7->CreateSurface(&ddsd, &lpdds_back2, NULL))) - { - ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; - ddsd.dwWidth = 2048; - ddsd.dwHeight = 2048; - ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; - if (FAILED(lpdd7->CreateSurface(&ddsd, &lpdds_back2, NULL))) - fatal("CreateSurface back failed\n"); - } - - if (FAILED(lpdd7->CreateClipper(0, &lpdd_clipper, NULL))) - return 0; - if (FAILED(lpdd_clipper->SetHWnd(0, h))) - return 0; - if (FAILED(lpdds_pri->SetClipper(lpdd_clipper))) - return 0; - - pclog("DDRAW_INIT complete\n"); - ddraw_hwnd = h; - video_blit_memtoscreen_func = ddraw_blit_memtoscreen; - video_blit_memtoscreen_8_func = ddraw_blit_memtoscreen_8; - - return 1; + 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); } -void ddraw_close(void) + +static void +DoubleLines(uint8_t *dst, uint8_t *src) { - 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; - } + 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 void ddraw_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) + +static void +SaveBitmap(wchar_t *szFilename, HBITMAP hBitmap) { - RECT r_src; - RECT r_dest; - int yy; - POINT po; - HRESULT hr; -// pclog("Blit memtoscreen %i,%i %i %i %i,%i\n", x, y, y1, y2, w, h); + static WCHAR szMessage[512]; + BITMAPFILEHEADER bmpFileHeader; + BITMAPINFO bmpInfo; + HDC hdc; + FILE *fp = NULL; + LPVOID pBuf = NULL; + LPVOID pBuf2 = NULL; - if (lpdds_back == NULL) - { - video_blit_complete(); - return; /*Nothing to do*/ - } + do { + hdc = GetDC(NULL); - if (h <= 0) - { - video_blit_complete(); - return; + 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; } - memset(&ddsd, 0, sizeof(ddsd)); - ddsd.dwSize = sizeof(ddsd); + if (ys2 <= 250) + pBuf2 = malloc(bmpInfo.bmiHeader.biSizeImage * 2); - 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); + bmpInfo.bmiHeader.biCompression = BI_RGB; - 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; + GetDIBits(hdc, hBitmap, 0, bmpInfo.bmiHeader.biHeight, pBuf, &bmpInfo, DIB_RGB_COLORS); - 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 ((fp = _wfopen(szFilename, L"wb")) == NULL) { + _swprintf(szMessage, + win_language_get_string_from_id(IDS_2088), szFilename); + msgbox_error_wstr(hwndMain, szMessage); + break; + } - 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); - } + 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); + + (void)fwrite(&bmpFileHeader,sizeof(BITMAPFILEHEADER),1,fp); + (void)fwrite(&bmpInfo.bmiHeader,sizeof(BITMAPINFOHEADER),1,fp); + if (pBuf2) { + DoubleLines((uint8_t *) pBuf2, (uint8_t *) pBuf); + (void)fwrite(pBuf2,bmpInfo.bmiHeader.biSizeImage,1,fp); + } else { + (void)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); } -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) +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) { - video_blit_complete(); - return; /*Nothing to do*/ - } - - memset(&ddsd, 0, sizeof(ddsd)); - ddsd.dwSize = sizeof(ddsd); - - hr = lpdds_back->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); - - if (hr == DDERR_SURFACELOST) - { - lpdds_back->Restore(); - lpdds_back->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); - device_force_redraw(); - } - if (!ddsd.lpSurface) - { - video_blit_complete(); - return; - } - for (yy = 0; yy < h; yy++) - { - if ((y + yy) >= 0 && (y + yy) < buffer->h) - { - p = (uint32_t *) &(((uint8_t *) ddsd.lpSurface)[yy * ddsd.lPitch]); - for (xx = 0; xx < w; xx++) - { - p[xx] = pal_lookup[buffer->line[y + yy][x + xx]]; - } - } - } - p = &(((uint32_t *) ddsd.lpSurface)[4 * ddsd.lPitch]); - lpdds_back->Unlock(NULL); - video_blit_complete(); - - po.x = po.y = 0; - - ClientToScreen(ddraw_hwnd, &po); - GetClientRect(ddraw_hwnd, &r_dest); - OffsetRect(&r_dest, po.x, po.y); - - r_src.left = 0; - r_src.top = 0; - r_src.right = w; - r_src.bottom = h; - - hr = lpdds_back2->Blt(&r_src, lpdds_back, &r_src, DDBLT_WAIT, NULL); - if (hr == DDERR_SURFACELOST) - { - lpdds_back2->Restore(); - lpdds_back2->Blt(&r_src, lpdds_back, &r_src, DDBLT_WAIT, NULL); - } - - hr = lpdds_pri->Blt(&r_dest, lpdds_back2, &r_src, DDBLT_WAIT, NULL); - if (hr == DDERR_SURFACELOST) - { - lpdds_pri->Restore(); - hr = lpdds_pri->Blt(&r_dest, lpdds_back2, &r_src, DDBLT_WAIT, NULL); - } + 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); } -void ddraw_take_screenshot(wchar_t *fn) + +static void +ddraw_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) { - ddraw_common_take_screenshot(fn, lpdds_back2); + RECT r_src; + RECT r_dest; + int yy; + POINT po; + HRESULT hr; + +// pclog("Blit memtoscreen %i,%i %i %i %i,%i\n", x, y, y1, y2, w, h); + + if (lpdds_back == NULL) { + video_blit_complete(); + return; /*Nothing to do*/ + } + + if (h <= 0) { + video_blit_complete(); + return; + } + + memset(&ddsd, 0, sizeof(ddsd)); + ddsd.dwSize = sizeof(ddsd); + + hr = lpdds_back->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); + if (hr == DDERR_SURFACELOST) { + lpdds_back->Restore(); + lpdds_back->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); + device_force_redraw(); + } + if (!ddsd.lpSurface) { + video_blit_complete(); + return; + } + + for (yy = y1; yy < y2; yy++) { + if ((y + yy) >= 0 && (y + yy) < buffer->h) + memcpy((uint32_t *) &(((uint8_t *) ddsd.lpSurface)[yy * ddsd.lPitch]), &(((uint32_t *)buffer32->line[y + yy])[x]), w * 4); + } + video_blit_complete(); + lpdds_back->Unlock(NULL); + + po.x = po.y = 0; + + ClientToScreen(ddraw_hwnd, &po); + GetClientRect(ddraw_hwnd, &r_dest); + OffsetRect(&r_dest, po.x, po.y); + + r_src.left = 0; + r_src.top = 0; + r_src.right = w; + r_src.bottom = h; + + hr = lpdds_back2->Blt(&r_src, lpdds_back, &r_src, DDBLT_WAIT, NULL); + if (hr == DDERR_SURFACELOST) { + lpdds_back2->Restore(); + lpdds_back2->Blt(&r_src, lpdds_back, &r_src, DDBLT_WAIT, NULL); + } + + lpdds_back2->Unlock(NULL); + +// pclog("Blit from %i,%i %i,%i to %i,%i %i,%i\n", r_src.left, r_src.top, r_src.right, r_src.bottom, r_dest.left, r_dest.top, r_dest.right, r_dest.bottom); + hr = lpdds_pri->Blt(&r_dest, lpdds_back2, &r_src, DDBLT_WAIT, NULL); + if (hr == DDERR_SURFACELOST) { + lpdds_pri->Restore(); + lpdds_pri->Blt(&r_dest, lpdds_back2, &r_src, DDBLT_WAIT, NULL); + } +} + + +static void +ddraw_blit_memtoscreen_8(int x, int y, int w, int h) +{ + RECT r_src; + RECT r_dest; + int xx, yy; + POINT po; + uint32_t *p; + HRESULT hr; + + if (lpdds_back == NULL) { + video_blit_complete(); + return; /*Nothing to do*/ + } + + memset(&ddsd, 0, sizeof(ddsd)); + ddsd.dwSize = sizeof(ddsd); + + hr = lpdds_back->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); + if (hr == DDERR_SURFACELOST) { + lpdds_back->Restore(); + lpdds_back->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); + device_force_redraw(); + } + if (!ddsd.lpSurface) { + video_blit_complete(); + return; + } + + for (yy = 0; yy < h; yy++) { + if ((y + yy) >= 0 && (y + yy) < buffer->h) { + p = (uint32_t *) &(((uint8_t *) ddsd.lpSurface)[yy * ddsd.lPitch]); + for (xx = 0; xx < w; xx++) + p[xx] = pal_lookup[buffer->line[y + yy][x + xx]]; + } + } + p = &(((uint32_t *) ddsd.lpSurface)[4 * ddsd.lPitch]); + lpdds_back->Unlock(NULL); + video_blit_complete(); + + po.x = po.y = 0; + ClientToScreen(ddraw_hwnd, &po); + GetClientRect(ddraw_hwnd, &r_dest); + OffsetRect(&r_dest, po.x, po.y); + + r_src.left = 0; + r_src.top = 0; + r_src.right = w; + r_src.bottom = h; + + hr = lpdds_back2->Blt(&r_src, lpdds_back, &r_src, DDBLT_WAIT, NULL); + if (hr == DDERR_SURFACELOST) { + lpdds_back2->Restore(); + lpdds_back2->Blt(&r_src, lpdds_back, &r_src, DDBLT_WAIT, NULL); + } + + hr = lpdds_pri->Blt(&r_dest, lpdds_back2, &r_src, DDBLT_WAIT, NULL); + if (hr == DDERR_SURFACELOST) { + lpdds_pri->Restore(); + hr = lpdds_pri->Blt(&r_dest, lpdds_back2, &r_src, DDBLT_WAIT, NULL); + } +} + + +int +ddraw_init(HWND h) +{ +#if NO_THIS_CRASHES_NOW + cgapal_rebuild(); +#endif + + if (FAILED(DirectDrawCreate(NULL, &lpdd, NULL))) return(0); + + if (FAILED(lpdd->QueryInterface(IID_IDirectDraw7, (LPVOID *)&lpdd7))) + return(0); + + lpdd->Release(); + lpdd = NULL; + + atexit(ddraw_close); + + if (FAILED(lpdd7->SetCooperativeLevel(h, DDSCL_NORMAL))) return(0); + + memset(&ddsd, 0, sizeof(ddsd)); + ddsd.dwSize = sizeof(ddsd); + + ddsd.dwFlags = DDSD_CAPS; + ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; + if (FAILED(lpdd7->CreateSurface(&ddsd, &lpdds_pri, NULL))) return(0); + + // memset(&ddsd, 0, sizeof(ddsd)); + // ddsd.dwSize = sizeof(ddsd); + ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; + ddsd.dwWidth = 2048; + ddsd.dwHeight = 2048; + ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY; + if (FAILED(lpdd7->CreateSurface(&ddsd, &lpdds_back, NULL))) { + ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; + ddsd.dwWidth = 2048; + ddsd.dwHeight = 2048; + ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; + if (FAILED(lpdd7->CreateSurface(&ddsd, &lpdds_back, NULL))) + fatal("CreateSurface back failed\n"); + } + + memset(&ddsd, 0, sizeof(ddsd)); + ddsd.dwSize = sizeof(ddsd); + + ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; + ddsd.dwWidth = 2048; + ddsd.dwHeight = 2048; + ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY; + if (FAILED(lpdd7->CreateSurface(&ddsd, &lpdds_back2, NULL))) { + ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; + ddsd.dwWidth = 2048; + ddsd.dwHeight = 2048; + ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; + if (FAILED(lpdd7->CreateSurface(&ddsd, &lpdds_back2, NULL))) + fatal("CreateSurface back failed\n"); + } + + if (FAILED(lpdd7->CreateClipper(0, &lpdd_clipper, NULL))) return(0); + + if (FAILED(lpdd_clipper->SetHWnd(0, h))) return(0); + + if (FAILED(lpdds_pri->SetClipper(lpdd_clipper))) return(0); + + 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; + } +} + + +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 index 5090aa0cc..93041ff88 100644 --- a/src/win/win_ddraw.h +++ b/src/win/win_ddraw.h @@ -15,13 +15,11 @@ extern "C" { extern int ddraw_init(HWND h); extern void ddraw_close(void); +extern void ddraw_take_screenshot(wchar_t *fn); extern int ddraw_fs_init(HWND h); extern void ddraw_fs_close(void); -extern void ddraw_common_take_screenshot(wchar_t *fn, - IDirectDrawSurface7 *pDDSurface); - #ifdef __cplusplus } #endif diff --git a/src/win/win_ddraw_fs.cc b/src/win/win_ddraw_fs.cc index abb390093..9687e21b5 100644 --- a/src/win/win_ddraw_fs.cc +++ b/src/win/win_ddraw_fs.cc @@ -26,8 +26,11 @@ extern "C" void device_force_redraw(void); extern "C" int ddraw_fs_init(HWND h); extern "C" void ddraw_fs_close(void); +extern void ddraw_common_take_screenshot(wchar_t *fn, IDirectDrawSurface7 *pDDSurface); + extern "C" void video_blit_complete(void); + static void ddraw_fs_blit_memtoscreen(int, int, int, int, int, int); static void ddraw_fs_blit_memtoscreen_8(int, int, int, int); diff --git a/src/win/win_ddraw_screenshot.cc b/src/win/win_ddraw_screenshot.cc deleted file mode 100644 index 9b2e5fe15..000000000 --- a/src/win/win_ddraw_screenshot.cc +++ /dev/null @@ -1,187 +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. - * - * DirectDraw screenshot taking code. - * - * Version: @(#)win_ddraw_screenshot.cc 1.0.1 2017/08/23 - * - * Author: Miran Grca, - * Copyright 2016,2017 Miran Grca. - */ - -#include -#include -#define UNICODE -#define BITMAP WINDOWS_BITMAP -#include -#undef BITMAP -#include "../video/video.h" -#include "win.h" -#include "win_ddraw.h" -#include "win_language.h" - - -HBITMAP hbitmap; -int xs, ys, ys2; - - -extern "C" void pclog(const char *format, ...); - - -void CopySurface(IDirectDrawSurface7 *pDDSurface) -{ - HDC hdc, hmemdc; - - HBITMAP hprevbitmap; - - DDSURFACEDESC2 ddsd2; - - pDDSurface->GetDC(&hdc); - - hmemdc = CreateCompatibleDC(hdc); - - ZeroMemory(&ddsd2 ,sizeof( ddsd2 )); // better to clear before using - - ddsd2.dwSize = sizeof( ddsd2 ); //initialize with size - - pDDSurface->GetSurfaceDesc(&ddsd2); - - hbitmap = CreateCompatibleBitmap( hdc ,xs ,ys); - - hprevbitmap = (HBITMAP) SelectObject( hmemdc, hbitmap ); - - BitBlt(hmemdc,0 ,0 ,xs ,ys ,hdc ,0 ,0,SRCCOPY); - - SelectObject(hmemdc,hprevbitmap); // restore the old bitmap - - DeleteDC(hmemdc); - - pDDSurface->ReleaseDC(hdc); - - return ; -} - - -void DoubleLines(uint8_t *dst, uint8_t *src) -{ - int i = 0; - for (i = 0; i < ys; i++) - { - memcpy(dst + (i * xs * 8), src + (i * xs * 4), xs * 4); - memcpy(dst + ((i * xs * 8) + (xs * 4)), src + (i * xs * 4), xs * 4); - } -} - -static WCHAR szMessage[2048]; - -void SaveBitmap(wchar_t *szFilename,HBITMAP hBitmap) -{ - HDC hdc=NULL; - FILE* fp=NULL; - LPVOID pBuf=NULL; - LPVOID pBuf2=NULL; - BITMAPINFO bmpInfo; - BITMAPFILEHEADER bmpFileHeader; - - do{ - - hdc=GetDC(NULL); - - ZeroMemory(&bmpInfo,sizeof(BITMAPINFO)); - - bmpInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER); - - GetDIBits(hdc,hBitmap,0,0,NULL,&bmpInfo,DIB_RGB_COLORS); - - if(bmpInfo.bmiHeader.biSizeImage<=0) - bmpInfo.bmiHeader.biSizeImage=bmpInfo.bmiHeader.biWidth*abs(bmpInfo.bmiHeader.biHeight)*(bmpInfo.bmiHeader.biBitCount+7)/8; - - if((pBuf = malloc(bmpInfo.bmiHeader.biSizeImage))==NULL) - { - // pclog("ERROR: Unable to Allocate Bitmap Memory"); - break; - } - - if (ys2 <= 250) - { - pBuf2 = malloc(bmpInfo.bmiHeader.biSizeImage * 2); - } - - bmpInfo.bmiHeader.biCompression=BI_RGB; - - GetDIBits(hdc,hBitmap,0,bmpInfo.bmiHeader.biHeight,pBuf, &bmpInfo, DIB_RGB_COLORS); - - if((fp = _wfopen(szFilename,L"wb"))==NULL) - { - _swprintf(szMessage, win_language_get_string_from_id(IDS_2088), szFilename); - msgbox_error_wstr(hwndMain, 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_stbar.c b/src/win/win_stbar.c new file mode 100644 index 000000000..00e449259 --- /dev/null +++ b/src/win/win_stbar.c @@ -0,0 +1,1137 @@ +/* + * 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. + * + * Implement the application's Status Bar. + * + * Version: @(#)win_stbar.c 1.0.2 2017/10/06 + * + * Authors: Miran Grca, + * Fred N. van Kempen, + * + * Copyright 2016,2017 Miran Grca. + * Copyright 2017 Fred N. van Kempen. + */ +#define UNICODE +#define BITMAP WINDOWS_BITMAP +#include +#include +#include +#include +#undef BITMAP +#include +#include +#include +#include +#include +#include "../config.h" +#include "../ibm.h" +#include "../cpu/cpu.h" +#include "../device.h" +#include "../machine/machine.h" +#include "../cdrom/cdrom.h" +#include "../cdrom/cdrom_ioctl.h" +#include "../cdrom/cdrom_image.h" +#include "../cdrom/cdrom_null.h" +#include "../disk/hdd.h" +#include "../disk/hdc.h" +#include "../floppy/floppy.h" +#include "../floppy/fdd.h" +#include "../scsi/scsi.h" +#include "../scsi/scsi_disk.h" +#include "../network/network.h" +#include "../video/video.h" +#include "../sound/sound.h" +#include "plat_iodev.h" +#include "plat_ui.h" +#include "win.h" +#include "win_language.h" + + +HWND hwndSBAR; + + +static LONG_PTR OriginalStatusBarProcedure; +static HMENU *sb_menu_handles; +static HMENU menuSBAR; +static WCHAR **sbTips; +static int *iStatusWidths; +static int *sb_icon_flags; +static int *sb_part_meanings; +static int *sb_part_icons; +static int sb_parts = 0; +static int sb_ready = 0; + + +/* Also used by win_settings.c */ +int +fdd_type_to_icon(int type) +{ + int ret = 512; + + switch(type) { + case 0: + break; + + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + ret = 128; + break; + + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + ret = 144; + break; + + default: + break; + } + + return(ret); +} + + +/* FIXME: should be hdd_count() in hdd.c */ +static int +hdd_count(int bus) +{ + int c = 0; + int i; + + for (i=0; i= 'A') && + (cdrom_drives[id].host_drive <= 'Z')) { + cdrom_drives[id].host_drive = 0; + } + + goto check_menu_items; + } else { + if ((cdrom_drives[id].host_drive >= 'A') && + (cdrom_drives[id].host_drive <= 'Z')) { + if (!host_cdrom_drive_available[cdrom_drives[id].host_drive - 'A']) { + cdrom_drives[id].host_drive = 0; + } + } + } + + AppendMenu(m, MF_SEPARATOR, 0, 0); + + for (i=0; i<26; i++) { + _swprintf(s, L"Host CD/DVD Drive (%c:)", i+'A'); + if (host_cdrom_drive_available[i]) + AppendMenu(m, MF_STRING, IDM_CDROM_HOST_DRIVE | (i<<3)|id, s); + } + +check_menu_items: + if (! cdrom_drives[id].sound_on) + CheckMenuItem(m, IDM_CDROM_MUTE | id, MF_CHECKED); + + if (cdrom_drives[id].host_drive == 200) + CheckMenuItem(m, IDM_CDROM_IMAGE | id, MF_CHECKED); + else + if ((cdrom_drives[id].host_drive >= 'A') && (cdrom_drives[id].host_drive <= 'Z')) { + CheckMenuItem(m, IDM_CDROM_HOST_DRIVE | id | + ((cdrom_drives[id].host_drive - 'A') << 3), MF_CHECKED); + } else { + cdrom_drives[id].host_drive = 0; + CheckMenuItem(m, IDM_CDROM_EMPTY | id, MF_CHECKED); + } +} + + +static void +StatusBarCreateRemovableDiskSubmenu(HMENU m, int id) +{ + AppendMenu(m, MF_STRING, IDM_RDISK_EJECT | id, + win_language_get_string_from_id(IDS_2166)); + AppendMenu(m, MF_STRING, IDM_RDISK_RELOAD | id, + win_language_get_string_from_id(IDS_2167)); + AppendMenu(m, MF_SEPARATOR, 0, 0); + AppendMenu(m, MF_STRING, IDM_RDISK_SEND_CHANGE | id, + win_language_get_string_from_id(IDS_2142)); + AppendMenu(m, MF_SEPARATOR, 0, 0); + AppendMenu(m, MF_STRING, IDM_RDISK_IMAGE | id, + win_language_get_string_from_id(IDS_2168)); + AppendMenu(m, MF_STRING, IDM_RDISK_IMAGE_WP | id, + win_language_get_string_from_id(IDS_2169)); +} + + +/* API */ +int +StatusBarFindPart(int tag) +{ + int found = -1; + int i; + + if (!sb_ready || (sb_parts == 0) || (sb_part_meanings == NULL)) { + return -1; + } + + for (i=0; i= SB_TEXT) || !sb_ready || (sb_parts == 0) || (sb_icon_flags == NULL) || (sb_part_icons == NULL)) { + return; + } + + temp_flags |= active; + + found = StatusBarFindPart(tag); + 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(hwndSBAR, SB_SETICON, found, + (LPARAM)hIcon[sb_part_icons[found]]); + } + } +} + + +/* API: This is for the drive state indicator. */ +void +StatusBarUpdateIconState(int tag, int state) +{ + int found = -1; + + if (((tag & 0xf0) >= SB_HDD) || !sb_ready || (sb_parts == 0) || (sb_icon_flags == NULL) || (sb_part_icons == NULL)) { + return; + } + + found = StatusBarFindPart(tag); + 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(hwndSBAR, SB_SETICON, found, + (LPARAM)hIcon[sb_part_icons[found]]); + } +} + + +static void +StatusBarCreateFloppyTip(int part) +{ + WCHAR wtext[512]; + WCHAR tempTip[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(floppyfns[drive]) == 0) { + _swprintf(tempTip, win_language_get_string_from_id(IDS_2158), + drive+1, wtext, win_language_get_string_from_id(IDS_2057)); + } else { + _swprintf(tempTip, win_language_get_string_from_id(IDS_2158), + drive+1, wtext, floppyfns[drive]); + } + + if (sbTips[part] != NULL) + free(sbTips[part]); + sbTips[part] = (WCHAR *) malloc((wcslen(tempTip) << 1) + 2); + wcscpy(sbTips[part], tempTip); +} + + +static void +StatusBarCreateCdromTip(int part) +{ + WCHAR wtext[512]; + WCHAR tempTip[512]; + WCHAR *szText; + int id; + int drive = sb_part_meanings[part] & 0xf; + int bus = cdrom_drives[drive].bus_type; + + id = IDS_4352 + (bus - 1); + szText = (WCHAR *)win_language_get_string_from_id(id); + + if (cdrom_drives[drive].host_drive == 200) { + if (wcslen(cdrom_image[drive].image_path) == 0) { + _swprintf(tempTip, win_language_get_string_from_id(IDS_5120), drive + 1, szText, win_language_get_string_from_id(IDS_2057)); + } else { + _swprintf(tempTip, win_language_get_string_from_id(IDS_5120), drive + 1, szText, cdrom_image[drive].image_path); + } + } else if ((cdrom_drives[drive].host_drive >= 'A') && (cdrom_drives[drive].host_drive <= 'Z')) { + _swprintf(wtext, win_language_get_string_from_id(IDS_2058), cdrom_drives[drive].host_drive & ~0x20); + _swprintf(tempTip, win_language_get_string_from_id(IDS_5120), drive + 1, szText, wtext); + } else { + _swprintf(tempTip, win_language_get_string_from_id(IDS_5120), drive + 1, szText, win_language_get_string_from_id(IDS_2057)); + } + + if (sbTips[part] != NULL) + free(sbTips[part]); + sbTips[part] = (WCHAR *) malloc((wcslen(tempTip) << 1) + 2); + wcscpy(sbTips[part], tempTip); +} + + +static void +StatusBarCreateRemovableDiskTip(int part) +{ + WCHAR tempTip[512]; + int drive = sb_part_meanings[part] & 0x1f; + + if (wcslen(hdd[drive].fn) == 0) { + _swprintf(tempTip, win_language_get_string_from_id(IDS_4115), drive, win_language_get_string_from_id(IDS_2057)); + } else { + _swprintf(tempTip, win_language_get_string_from_id(IDS_4115), drive, hdd[drive].fn); + } + + if (sbTips[part] != NULL) + free(sbTips[part]); + sbTips[part] = (WCHAR *) malloc((wcslen(tempTip) << 1) + 2); + wcscpy(sbTips[part], tempTip); +} + + +static void +StatusBarCreateDiskTip(int part) +{ + WCHAR tempTip[512]; + WCHAR *szText; + int id; + int bus = sb_part_meanings[part] & 0xf; + + id = IDS_4352 + (bus - 1); + szText = (WCHAR *)win_language_get_string_from_id(id); + + _swprintf(tempTip, win_language_get_string_from_id(IDS_4096), szText); + if (sbTips[part] != NULL) + free(sbTips[part]); + sbTips[part] = (WCHAR *) malloc((wcslen(tempTip) << 1) + 2); + wcscpy(sbTips[part], tempTip); +} + + +static void +StatusBarCreateNetworkTip(int part) +{ + WCHAR tempTip[512]; + + _swprintf(tempTip, win_language_get_string_from_id(IDS_2069)); + + if (sbTips[part] != NULL) + free(sbTips[part]); + sbTips[part] = (WCHAR *) malloc((wcslen(tempTip) << 1) + 2); + wcscpy(sbTips[part], tempTip); +} + + +/* API */ +void +StatusBarUpdateTip(int meaning) +{ + int part = -1; + int i; + + if (!sb_ready || (sb_parts == 0) || (sb_part_meanings == NULL)) return; + + for (i=0; i 0) { + for (i = 0; i < sb_parts; i++) + SendMessage(hwndSBAR, SB_SETICON, i, (LPARAM)NULL); + SendMessage(hwndSBAR, SB_SETPARTS, (WPARAM)0, (LPARAM)NULL); + + if (iStatusWidths) { + free(iStatusWidths); + iStatusWidths = NULL; + } + if (sb_part_meanings) { + free(sb_part_meanings); + sb_part_meanings = NULL; + } + if (sb_part_icons) { + free(sb_part_icons); + sb_part_icons = NULL; + } + if (sb_icon_flags) { + free(sb_icon_flags); + sb_icon_flags = NULL; + } + StatusBarDestroyMenus(); + StatusBarDestroyTips(); + } + sb_parts = 0; + + for (i=0; i= 'A') && (cdrom_drives[id].host_drive <= 'Z')) { + sb_icon_flags[i] = 0; + } else { + sb_icon_flags[i] = 256; + } + sb_part_icons[i] = 160 | sb_icon_flags[i]; + sb_menu_handles[i] = StatusBarCreatePopupMenu(i); + StatusBarCreateCdromSubmenu(sb_menu_handles[i], sb_part_meanings[i] & 0xf); + EnableMenuItem(sb_menu_handles[i], IDM_CDROM_RELOAD | (sb_part_meanings[i] & 0xf), MF_BYCOMMAND | MF_GRAYED); + StatusBarCreateCdromTip(i); + break; + + case SB_RDISK: /* Removable hard disk */ + sb_icon_flags[i] = (wcslen(hdd[sb_part_meanings[i] & 0x1f].fn) == 0) ? 256 : 0; + sb_part_icons[i] = 176 + sb_icon_flags[i]; + sb_menu_handles[i] = StatusBarCreatePopupMenu(i); + StatusBarCreateRemovableDiskSubmenu(sb_menu_handles[i], sb_part_meanings[i] & 0x1f); + EnableMenuItem(sb_menu_handles[i], IDM_RDISK_EJECT | (sb_part_meanings[i] & 0x1f), MF_BYCOMMAND | ((sb_icon_flags[i] & 256) ? MF_GRAYED : MF_ENABLED)); + EnableMenuItem(sb_menu_handles[i], IDM_RDISK_RELOAD | (sb_part_meanings[i] & 0x1f), MF_BYCOMMAND | MF_GRAYED); + EnableMenuItem(sb_menu_handles[i], IDM_RDISK_SEND_CHANGE | (sb_part_meanings[i] & 0x1f), MF_BYCOMMAND | ((sb_icon_flags[i] & 256) ? MF_GRAYED : MF_ENABLED)); + StatusBarCreateRemovableDiskTip(i); + break; + + case SB_HDD: /* Hard disk */ + sb_part_icons[i] = 192; + StatusBarCreateDiskTip(i); + break; + + case SB_NETWORK: /* Network */ + sb_part_icons[i] = 208; + StatusBarCreateNetworkTip(i); + break; + + case SB_TEXT: /* Status text */ + SendMessage(hwndSBAR, SB_SETTEXT, i | SBT_NOBORDERS, (LPARAM) L""); + sb_part_icons[i] = -1; + break; + } + + if (sb_part_icons[i] != -1) { + SendMessage(hwndSBAR, SB_SETTEXT, i | SBT_NOBORDERS, (LPARAM)""); + SendMessage(hwndSBAR, SB_SETICON, i, (LPARAM)hIcon[sb_part_icons[i]]); + SendMessage(hwndSBAR, SB_SETTIPTEXT, i, (LPARAM)sbTips[i]); + } else { + SendMessage(hwndSBAR, SB_SETICON, i, (LPARAM)NULL); + } + } + + sb_ready = 1; +} + + +static VOID APIENTRY +StatusBarPopupMenu(HWND hwnd, POINT pt, int id) +{ + 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); + TrackPopupMenu(sb_menu_handles[id], + TPM_LEFTALIGN | TPM_BOTTOMALIGN | TPM_LEFTBUTTON, + pt.x, pt.y, 0, hwndSBAR, NULL); +} + + +/* Handle messages for the Status Bar window. */ +static LRESULT CALLBACK +StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + WCHAR temp_image_path[1024]; + RECT rc; + POINT pt; + int new_cdrom_drive; + int ret = 0; + int item_id = 0; + int item_params = 0; + int id = 0; + int part = 0; + int letter = 0; + + switch (message) { + case WM_COMMAND: + item_id = LOWORD(wParam) & 0xff00; /* low 8 bits */ + item_params = LOWORD(wParam) & 0x00ff; /* high 8 bits */ + + switch (item_id) { + case IDM_FLOPPY_IMAGE_EXISTING: + case IDM_FLOPPY_IMAGE_EXISTING_WP: + id = item_params & 0x0003; + part = StatusBarFindPart(SB_FLOPPY | id); + if ((part == -1) || (sb_menu_handles == NULL)) + break; + + ret = file_dlg_w_st(hwnd, IDS_2159, floppyfns[id], 0); + if (! ret) { + floppy_close(id); + ui_writeprot[id] = (item_id == IDM_FLOPPY_IMAGE_EXISTING_WP) ? 1 : 0; + floppy_load(id, wopenfilestring); + StatusBarUpdateIconState(SB_FLOPPY | id, wcslen(floppyfns[id]) ? 0 : 1); + EnableMenuItem(sb_menu_handles[part], IDM_FLOPPY_EJECT | id, MF_BYCOMMAND | (wcslen(floppyfns[id]) ? MF_ENABLED : MF_GRAYED)); + StatusBarUpdateTip(SB_FLOPPY | id); + config_save(); + } + break; + + case IDM_FLOPPY_EJECT: + id = item_params & 0x0003; + part = StatusBarFindPart(SB_FLOPPY | id); + if ((part == -1) || (sb_menu_handles == NULL)) + break; + + floppy_close(id); + StatusBarUpdateIconState(SB_FLOPPY | id, 1); + EnableMenuItem(sb_menu_handles[part], IDM_FLOPPY_EJECT | id, MF_BYCOMMAND | MF_GRAYED); + StatusBarUpdateTip(SB_FLOPPY | id); + config_save(); + break; + + case IDM_CDROM_MUTE: + id = item_params & 0x0007; + part = StatusBarFindPart(SB_CDROM | id); + if ((part == -1) || (sb_menu_handles == NULL)) + break; + + cdrom_drives[id].sound_on ^= 1; + CheckMenuItem(sb_menu_handles[part], IDM_CDROM_MUTE | id, cdrom_drives[id].sound_on ? MF_UNCHECKED : MF_CHECKED); + config_save(); + sound_cd_thread_reset(); + break; + + case IDM_CDROM_EMPTY: + id = item_params & 0x0007; + cdrom_eject(id); + break; + + case IDM_CDROM_RELOAD: + id = item_params & 0x0007; + cdrom_reload(id); + break; + + case IDM_CDROM_IMAGE: + id = item_params & 0x0007; + part = StatusBarFindPart(SB_CDROM | id); + if ((part == -1) || (sb_menu_handles == NULL)) + break; + + if (!file_dlg_w_st(hwnd, IDS_2075, cdrom_image[id].image_path, 0)) { + cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; + wcscpy(temp_image_path, wopenfilestring); + if ((wcscmp(cdrom_image[id].image_path, temp_image_path) == 0) && (cdrom_drives[id].host_drive == 200)) { + /* Switching from image to the same image. Do nothing. */ + break; + } + wcscpy(cdrom_image[id].prev_image_path, cdrom_image[id].image_path); + cdrom_drives[id].handler->exit(id); + cdrom_close(id); + image_open(id, temp_image_path); + /* Signal media change to the emulated machine. */ + cdrom_insert(id); + CheckMenuItem(sb_menu_handles[part], IDM_CDROM_EMPTY | id, MF_UNCHECKED); + if ((cdrom_drives[id].host_drive >= 'A') && (cdrom_drives[id].host_drive <= 'Z')) { + CheckMenuItem(sb_menu_handles[part], IDM_CDROM_HOST_DRIVE | id | ((cdrom_drives[id].host_drive - 'A') << 3), MF_UNCHECKED); + } + cdrom_drives[id].host_drive = (wcslen(cdrom_image[id].image_path) == 0) ? 0 : 200; + if (cdrom_drives[id].host_drive == 200) { + CheckMenuItem(sb_menu_handles[part], IDM_CDROM_IMAGE | id, MF_CHECKED); + StatusBarUpdateIconState(SB_CDROM | id, 0); + } else { + CheckMenuItem(sb_menu_handles[part], IDM_CDROM_IMAGE | id, MF_UNCHECKED); + CheckMenuItem(sb_menu_handles[part], IDM_CDROM_EMPTY | id, MF_UNCHECKED); + StatusBarUpdateIconState(SB_CDROM | id, 1); + } + EnableMenuItem(sb_menu_handles[part], IDM_CDROM_RELOAD | id, MF_BYCOMMAND | MF_GRAYED); + StatusBarUpdateTip(SB_CDROM | id); + config_save(); + } + break; + + case IDM_CDROM_HOST_DRIVE: + id = item_params & 0x0007; + letter = ((item_params >> 3) & 0x001f) + 'A'; + part = StatusBarFindPart(SB_CDROM | id); + if ((part == -1) || (sb_menu_handles == NULL)) + { + break; + } + + new_cdrom_drive = letter; + if (cdrom_drives[id].host_drive == new_cdrom_drive) + { + /* Switching to the same drive. Do nothing. */ + break; + } + cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; + cdrom_drives[id].handler->exit(id); + cdrom_close(id); + ioctl_open(id, new_cdrom_drive); + /* Signal media change to the emulated machine. */ + cdrom_insert(id); + CheckMenuItem(sb_menu_handles[part], IDM_CDROM_EMPTY | id, MF_UNCHECKED); + if ((cdrom_drives[id].host_drive >= 'A') && (cdrom_drives[id].host_drive <= 'Z')) + { + CheckMenuItem(sb_menu_handles[part], IDM_CDROM_HOST_DRIVE | id | ((cdrom_drives[id].host_drive - 'A') << 3), MF_UNCHECKED); + } + CheckMenuItem(sb_menu_handles[part], IDM_CDROM_IMAGE | id, MF_UNCHECKED); + cdrom_drives[id].host_drive = new_cdrom_drive; + CheckMenuItem(sb_menu_handles[part], IDM_CDROM_HOST_DRIVE | id | ((cdrom_drives[id].host_drive - 'A') << 3), MF_CHECKED); + EnableMenuItem(sb_menu_handles[part], IDM_CDROM_RELOAD | id, MF_BYCOMMAND | MF_GRAYED); + StatusBarUpdateIconState(SB_CDROM | id, 0); + StatusBarUpdateTip(SB_CDROM | id); + config_save(); + break; + + case IDM_RDISK_EJECT: + id = item_params & 0x001f; + removable_disk_eject(id); + break; + + case IDM_RDISK_RELOAD: + id = item_params & 0x001f; + removable_disk_reload(id); + break; + + case IDM_RDISK_SEND_CHANGE: + id = item_params & 0x001f; + scsi_disk_insert(id); + break; + + case IDM_RDISK_IMAGE: + case IDM_RDISK_IMAGE_WP: + id = item_params & 0x001f; + ret = file_dlg_w_st(hwnd, IDS_4106, hdd[id].fn, id); + if (!ret) { + removable_disk_unload(id); + memset(hdd[id].fn, 0, sizeof(hdd[id].fn)); + wcscpy(hdd[id].fn, wopenfilestring); + hdd[id].wp = (item_id == IDM_RDISK_IMAGE_WP) ? 1 : 0; + scsi_loadhd(hdd[id].scsi_id, hdd[id].scsi_lun, id); + scsi_disk_insert(id); + if (wcslen(hdd[id].fn) > 0) { + StatusBarUpdateIconState(SB_RDISK | id, 0); + EnableMenuItem(sb_menu_handles[part], IDM_RDISK_EJECT | id, MF_BYCOMMAND | MF_ENABLED); + EnableMenuItem(sb_menu_handles[part], IDM_RDISK_RELOAD | id, MF_BYCOMMAND | MF_GRAYED); + EnableMenuItem(sb_menu_handles[part], IDM_RDISK_SEND_CHANGE | id, MF_BYCOMMAND | MF_ENABLED); + } + else { + StatusBarUpdateIconState(SB_RDISK | id, 1); + EnableMenuItem(sb_menu_handles[part], IDM_RDISK_EJECT | id, MF_BYCOMMAND | MF_GRAYED); + EnableMenuItem(sb_menu_handles[part], IDM_RDISK_RELOAD | id, MF_BYCOMMAND | MF_GRAYED); + EnableMenuItem(sb_menu_handles[part], IDM_RDISK_SEND_CHANGE | id, MF_BYCOMMAND | MF_GRAYED); + } + StatusBarUpdateTip(SB_RDISK | id); + config_save(); + } + break; + + default: + 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)) + StatusBarPopupMenu(hwnd, pt, (pt.x / SB_ICON_WIDTH)); + break; + + default: + return(CallWindowProc((WNDPROC)OriginalStatusBarProcedure, + hwnd, message, wParam, lParam)); + } + + return(0); +} + + +/* API: Create and set up the Status Bar window. */ +void +StatusBarCreate(HWND hwndParent, int idStatus, HINSTANCE hInst) +{ + RECT rectDialog; + int dw, dh, i; + + /* Load our icons into the cache for faster access. */ + for (i = 128; i < 130; i++) + hIcon[i] = LoadIconEx((PCTSTR) i); + for (i = 144; i < 146; i++) + hIcon[i] = LoadIconEx((PCTSTR) i); + for (i = 160; i < 162; i++) + hIcon[i] = LoadIconEx((PCTSTR) i); + for (i = 176; i < 178; i++) + hIcon[i] = LoadIconEx((PCTSTR) i); + for (i = 192; i < 194; i++) + hIcon[i] = LoadIconEx((PCTSTR) i); + for (i = 208; i < 210; i++) + hIcon[i] = LoadIconEx((PCTSTR) i); + for (i = 384; i < 386; i++) + hIcon[i] = LoadIconEx((PCTSTR) i); + for (i = 400; i < 402; i++) + hIcon[i] = LoadIconEx((PCTSTR) i); + for (i = 416; i < 418; i++) + hIcon[i] = LoadIconEx((PCTSTR) i); + for (i = 432; i < 434; i++) + hIcon[i] = LoadIconEx((PCTSTR) i); + + GetWindowRect(hwndParent, &rectDialog); + dw = rectDialog.right - rectDialog.left; + dh = rectDialog.bottom - rectDialog.top; + + /* Load the Common Controls DLL if needed. */ + InitCommonControls(); + + /* Create the window, and make sure it's using the STATUS class. */ + hwndSBAR = CreateWindowEx(0, + STATUSCLASSNAME, + (LPCTSTR)NULL, + SBARS_SIZEGRIP|WS_CHILD|WS_VISIBLE|SBT_TOOLTIPS, + 0, dh-17, dw, 17, + hwndParent, + (HMENU)idStatus, hInst, NULL); + + /* Replace the original procedure with ours. */ + OriginalStatusBarProcedure = GetWindowLongPtr(hwndSBAR, GWLP_WNDPROC); + SetWindowLongPtr(hwndSBAR, GWL_WNDPROC, (LONG_PTR)&StatusBarProcedure); + + SendMessage(hwndSBAR, SB_SETMINHEIGHT, (WPARAM)17, (LPARAM)0); + + /* Align the window with the parent (main) window. */ + GetWindowRect(hwndSBAR, &rectDialog); + SetWindowPos(hwndSBAR, + HWND_TOPMOST, + rectDialog.left, rectDialog.top, + rectDialog.right-rectDialog.left, + rectDialog.bottom-rectDialog.top, + SWP_SHOWWINDOW); + + /* Load the dummu menu for this window. */ + menuSBAR = LoadMenu(hInst, SB_MENU_NAME); + + /* Initialize the status bar and populate the icons and menus. */ + sb_parts = 0; + StatusBarUpdatePanes(); +} + + +/* API */ +void +StatusBarCheckMenuItem(int tag, int id, int chk) +{ + int part; + + part = StatusBarFindPart(tag); + if ((part == -1) || (sb_menu_handles == NULL)) + return; + + CheckMenuItem(sb_menu_handles[part], id, chk); +} + + +/* API */ +void +StatusBarEnableMenuItem(int tag, int id, int flg) +{ + int part; + + part = StatusBarFindPart(tag); + if ((part == -1) || (sb_menu_handles == NULL)) + return; + + EnableMenuItem(sb_menu_handles[part], id, flg); +} + + +/* API */ +void +StatusBarSetTextW(wchar_t *wstr) +{ + int part = -1; + int i; + + if (!sb_ready || (sb_parts == 0) || (sb_part_meanings == NULL)) return; + + for (i=0; i