From 3bb15e1fe7a225be775604cfb43b8d84a6fd5a6d Mon Sep 17 00:00:00 2001 From: waltje Date: Sat, 28 Jul 2018 20:52:51 -0400 Subject: [PATCH] Added several small upstream patches for CPU module. Added the D2D rendering module from 86Box, and updated it. Fixed the Slovenian translation. Added Norwegian (Bokmal) translation. Several small fixes here and there. --- src/cpu/cpu_table.c | 36 +-- src/cpu/x86_ops_mov.h | 7 +- src/devices/system/pci_dummy.c | 4 +- src/pc.c | 4 +- src/ui/lang/Extra-NO.txt | 85 +++++++ src/ui/lang/VARCem-NO.str | 403 +++++++++++++++++++++++++++++ src/ui/lang/VARCem-SL.str | 10 +- src/ui/lang/VARCem.lang | 3 +- src/version.h | 4 +- src/win/mingw/Makefile.MinGW | 29 ++- src/win/msvc/Makefile.VC | 31 ++- src/win/win.c | 8 +- src/win/win.h | 2 +- src/win/win_d2d.cpp | 450 +++++++++++++++++++++++++++++++++ src/win/win_d2d.h | 62 +++++ 15 files changed, 1094 insertions(+), 44 deletions(-) create mode 100644 src/ui/lang/Extra-NO.txt create mode 100644 src/ui/lang/VARCem-NO.str create mode 100644 src/win/win_d2d.cpp create mode 100644 src/win/win_d2d.h diff --git a/src/cpu/cpu_table.c b/src/cpu/cpu_table.c index bf1c7a1..6d390e2 100644 --- a/src/cpu/cpu_table.c +++ b/src/cpu/cpu_table.c @@ -8,36 +8,13 @@ * * Define all known processor types. * - * Available cpuspeeds: - * - * 0 = 16 MHz - * 1 = 20 MHz - * 2 = 25 MHz - * 3 = 33 MHz - * 4 = 40 MHz - * 5 = 50 MHz - * 6 = 66 MHz - * 7 = 75 MHz - * 8 = 80 MHz - * 9 = 90 MHz - * 10 = 100 MHz - * 11 = 120 MHz - * 12 = 133 MHz - * 13 = 150 MHz - * 14 = 160 MHz - * 15 = 166 MHz - * 16 = 180 MHz - * 17 = 200 MHz - * - * Version: @(#)cpu_table.c 1.0.2 2018/05/06 + * Version: @(#)cpu_table.c 1.0.3 2018/07/28 * * Authors: Sarah Walker, - * leilei, * Miran Grca, * Fred N. van Kempen, * * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 leilei. * Copyright 2016-2018 Miran Grca. * Copyright 2017,2018 Fred N. van Kempen. * @@ -231,14 +208,25 @@ CPU cpus_i486[] = { {"i486SX/20", CPU_i486SX, 1, 20000000, 1, 20000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 4,4,3,3, 3}, {"i486SX/25", CPU_i486SX, 2, 25000000, 1, 25000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 4,4,3,3, 3}, {"i486SX/33", CPU_i486SX, 3, 33333333, 1, 33333333, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4}, +#if 0 {"i486SX2/50", CPU_i486SX, 5, 50000000, 2, 25000000, 0x45b, 0, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 6}, {"i486SX2/66 (Q0569)", CPU_i486SX, 6, 66666666, 2, 33333333, 0x45b, 0, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 8}, +#else + {"i486SX2/50", CPU_i486SX, 5, 50000000, 2, 25000000, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 6}, + {"i486SX2/66 (Q0569)", CPU_i486SX, 6, 66666666, 2, 33333333, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 8}, +#endif {"i486DX/25", CPU_i486DX, 2, 25000000, 1, 25000000, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 4,4,3,3, 3}, {"i486DX/33", CPU_i486DX, 3, 33333333, 1, 33333333, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4}, {"i486DX/50", CPU_i486DX, 5, 50000000, 1, 25000000, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 8,8,4,4, 6}, +#if 0 {"i486DX2/40", CPU_i486DX, 4, 40000000, 2, 20000000, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 6}, {"i486DX2/50", CPU_i486DX, 5, 50000000, 2, 25000000, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 6}, {"i486DX2/66", CPU_i486DX, 6, 66666666, 2, 33333333, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 8}, +#else + {"i486DX2/40", CPU_i486DX, 4, 40000000, 2, 20000000, 0x430, 0x430, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 6}, + {"i486DX2/50", CPU_i486DX, 5, 50000000, 2, 25000000, 0x430, 0x430, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 6}, + {"i486DX2/66", CPU_i486DX, 6, 66666666, 2, 33333333, 0x430, 0x430, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 8}, +#endif {"iDX4/75", CPU_iDX4, 7, 75000000, 3, 25000000, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC, 12,12,9,9, 9}, /*CPUID available on DX4, >= 75 MHz*/ {"iDX4/100", CPU_iDX4, 10, 100000000, 3, 33333333, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 12}, /*Is on some real Intel DX2s, limit here is pretty arbitary*/ {"Pentium OverDrive/63", CPU_PENTIUM, 6, 62500000, 3, 25000000, 0x1531, 0x1531, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,7,7, 15/2}, diff --git a/src/cpu/x86_ops_mov.h b/src/cpu/x86_ops_mov.h index d497007..0bbba81 100644 --- a/src/cpu/x86_ops_mov.h +++ b/src/cpu/x86_ops_mov.h @@ -8,7 +8,7 @@ * * Miscellaneous x86 CPU Instructions. * - * Version: @(#)x86_ops_mov.h 1.0.2 2018/05/09 + * Version: @(#)x86_ops_mov.h 1.0.3 2018/07/28 * * Authors: Sarah Walker, * Miran Grca, @@ -232,6 +232,7 @@ static int opMOV_b_imm_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); ILLEGAL_ON((rmdat & 0x38) != 0); temp = getbyte(); if (cpu_state.abrt) return 1; + CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); seteab(temp); CLOCK_CYCLES(timing_rr); PREFETCH_RUN(timing_rr, 3, rmdat, 0,0,(cpu_mod == 3) ? 1:0,0, 1); @@ -244,6 +245,7 @@ static int opMOV_w_imm_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); ILLEGAL_ON((rmdat & 0x38) != 0); temp = getword(); if (cpu_state.abrt) return 1; + CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1); seteaw(temp); CLOCK_CYCLES(timing_rr); PREFETCH_RUN(timing_rr, 4, rmdat, 0,0,(cpu_mod == 3) ? 1:0,0, 0); @@ -255,6 +257,7 @@ static int opMOV_w_imm_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); ILLEGAL_ON((rmdat & 0x38) != 0); temp = getword(); if (cpu_state.abrt) return 1; + CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1); seteaw(temp); CLOCK_CYCLES(timing_rr); PREFETCH_RUN(timing_rr, 4, rmdat, 0,0,(cpu_mod == 3) ? 1:0,0, 1); @@ -266,6 +269,7 @@ static int opMOV_l_imm_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); ILLEGAL_ON((rmdat & 0x38) != 0); temp = getlong(); if (cpu_state.abrt) return 1; + CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); seteal(temp); CLOCK_CYCLES(timing_rr); PREFETCH_RUN(timing_rr, 6, rmdat, 0,0,0,(cpu_mod == 3) ? 1:0, 0); @@ -277,6 +281,7 @@ static int opMOV_l_imm_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); ILLEGAL_ON((rmdat & 0x38) != 0); temp = getlong(); if (cpu_state.abrt) return 1; + CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); seteal(temp); CLOCK_CYCLES(timing_rr); PREFETCH_RUN(timing_rr, 6, rmdat, 0,0,0,(cpu_mod == 3) ? 1:0, 1); diff --git a/src/devices/system/pci_dummy.c b/src/devices/system/pci_dummy.c index 0f57d05..bedc9a0 100644 --- a/src/devices/system/pci_dummy.c +++ b/src/devices/system/pci_dummy.c @@ -8,7 +8,7 @@ * * Example implementation of a PCI device. * - * Version: @(#)pci_dummy.c 1.0.3 2018/05/06 + * Version: @(#)pci_dummy.c 1.0.4 2018/07/26 * * Author: Miran Grca, * @@ -36,7 +36,7 @@ #include #include #include -#include "../../emu.h +#include "../../emu.h" #include "../../io.h" #include "pci.h" #include "pci_dummy.h" diff --git a/src/pc.c b/src/pc.c index 2e59ae2..a356ce4 100644 --- a/src/pc.c +++ b/src/pc.c @@ -8,7 +8,7 @@ * * Main emulator module where most things are controlled. * - * Version: @(#)pc.c 1.0.48 2018/06/26 + * Version: @(#)pc.c 1.0.49 2018/07/28 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -301,7 +301,7 @@ pclog_dump(int num) while (i < num) { if (sp == NULL) { sp = buff; - sprintf(sp, "%08lx:", cpu_state.pc + i); + sprintf(sp, "%08lx:", (unsigned long)cpu_state.pc + i); sp += strlen(sp); } diff --git a/src/ui/lang/Extra-NO.txt b/src/ui/lang/Extra-NO.txt new file mode 100644 index 0000000..508cf32 --- /dev/null +++ b/src/ui/lang/Extra-NO.txt @@ -0,0 +1,85 @@ +**** Additional strings for the Installer itself **** +**** (keep the > lines, add translation after : **** + + +> Select the setup language: +: Velg installasjonsspråk: + +> Desktop (as in "Desktop icons") +: Skrivebord + + +> Executing file removal operations +: Sletter filer + +> Preparing files for removal +: Forbereder sletting av filer + +> Restoring removed files +: Gjenoppretter slettede filer + +> Extracting files from archive +: Pakker ut filer fra arkiv + +> Executing file removal +: Sletter filer + +> Preparing file +: Forbereder fil + +> Restoring file +: Gjenoppretter fil + +> This package can only be run from a bootstrapper. +: Denne pakken kan kun kjøres fra en boostrapper. + + +> Several commandline tools +: Flere kommandolinjeverktøy + +> A set of example configurations to get you started. +: Et sett med eksempelkonfigurasjoner å starte med + +> Generic Turbo-XT Clone. +: Generisk Turbo-XT-klone. + +> The original IBM-PC model. +: Den originale IBM-PC-modellen. + +> The new model of the IBM-PC +: Den nye modellen av IBM-PC. + +> Segoe UI Fonts for Windows XP +: Segoe typesnitt for brukergrensesnitt i Windows XP + + +> Additional Languages support files. +: Ytterligere filer for språkstøtte. + +> Your virtual machines. +: Dine virtuelle maskiner. + +> Runtime files for the FluidSynth MIDI synthesizer +: Kjøretidsbiblioteker for FluidSynths MIDI-synthesizer + +> Various runtime files needed by the application. +: Diverse kjøretidsfiler brukt av applikasjonen. + +> ROM BIOS image files of emulated machines and devices. +: ROM BIOS-avtrykksfiler for emulerte maskiner og enheter. + +> Runtime files needed for the SDL2 renderer. +: Kjøretidsfiler brukt av SDL2-rendereren. + +> The VARCem Application +: VARCem-applikasjonen + +> License Agreement +: Lisensavtale + +> Installer for the [ProductName] application. +: Installer for [ProductName]-applikasjonen. + +> The VARCem Team +: VARCem-teamet + diff --git a/src/ui/lang/VARCem-NO.str b/src/ui/lang/VARCem-NO.str new file mode 100644 index 0000000..9e52d88 --- /dev/null +++ b/src/ui/lang/VARCem-NO.str @@ -0,0 +1,403 @@ +/* + * VARCem Virtual ARchaeological Computer EMulator. + * An emulator of (mostly) x86-based PC systems and devices, + * using the ISA,EISA,VLB,MCA and PCI system buses, roughly + * spanning the era between 1981 and 1995. + * + * This file is part of the VARCem Project. + * + * String definitions for "English (United States) language. + * + * TRANSLATION: The application uses English as its primary language, and + * this file is the "Master" for all translations. Please use + * it as the line-by-line base for the translated version, and + * update fields as needed. + * + * Version: @(#)VARCem-EN.str 1.0.1 2018/07/11 + * + * Author: Fred N. van Kempen, + * Tore Sinding Bekkedal, " +#define STR_3581 "" +#define STR_3582 "ATAPI (kun PIO)" +#define STR_3583 "ATAPI (PIO+DMA)" +#define STR_3584 "SCSI" +#define STR_3585 "USB" + +/* UI dialog: status bar (3900.) */ +#define STR_3900 "(tom)" +#define STR_3901 "(vertsdisk %c:)" +#define STR_3902 " [Skrivebeskyttet]" +#define STR_3903 "&Nytt avtrykk.." +#define STR_3904 "&Last inn avtrykk.." +#define STR_3905 "Oppdate&re avtrykk" +#define STR_3906 "Løs &ut" + +#define STR_3910 "Diskett %i (%s): %ls" +#define STR_3911 "Alle avtrykk\0*.0??;*.1??;*.360;*.720;*.86f;*.bin;*.cq?;*.dsk;*.flp;*.hdm;*.im?;*.json;*.td0;*.*fd?;*.xdf\0Avanserte sektoravtrykk\0*.imd;*.json;*.td0\0Enkle sektoravtrykk\0*.0??;*.1??;*.360;*.720;*.bin;*.cq?;*.dsk;*.flp;*.hdm;*.im?;*.xdf;*.*fd?\0Flux-avtrykk\0*.fdi\0Overflateavtrykk\0*.86f\0Alle filer\0*.*\0" +#define STR_3912 "Alle avtrykk\0*.86f;*.dsk;*.flp;*.im?;*.*fd?\0Enkle sektoravtrykk\0*.dsk;*.flp;*.im?;*.img;*.*fd?\0Overflateavtrykk\0*.86f\0" +#define STR_3913 "Overflateavtrykk\0*.86f\0" +#define STR_3914 "(&x) Eksporter til 86F..." + +#define STR_3920 "CD-ROM %i (%s): %s" +#define STR_3921 "Vertens CD/DVD-enhet (%c:)" +#define STR_3922 "CD-ROM-avtrykk\0*.iso;*.cue\0Alle filer (*.*)\0*.*\0" +#define STR_3923 "&Mute" + +#define STR_3930 "Platelager (%s)" + +#define STR_3940 "Flyttbar disk %i: %ls" +#define STR_3941 "(&N) Varsle diskbytte" + +#define STR_3950 "ZIP %i (%03i): %ls" +#define STR_3951 "ZIP-avtrykk\0*.im?;*.zdi\0Alle filer\0*.*\0" +#define STR_3952 "ZIP-avtrykk\0*.im?;*.zdi\0" +#define STR_3960 "Nettverk" +#define STR_3970 "Lyd" + + +/* Menu: Action (4000.) */ +#define STR_ACTION "H&andlinger" +#define STR_4001 "&Hard omstart" +#define STR_4002 "&Kontroll+Alt+Del" +#define STR_4003 "Send Kontroll+Alt+&Esc" +#define STR_4004 "Send Kontroll+Alt+&Break" +#define STR_4005 "&Pause" +#define STR_4006 "(&x) Avslutt" + +/* Menu: View (4010.) */ +#define STR_VIEW "&Vis" +#define STR_4011 "Skale&rbart vindu" +#define STR_4012 "Lagr&e størrelse && posisjon" +#define STR_4013 "&Fullskjerm\tKontroll+Alt+PageUP" +#define STR_4014 "Høyre Kontroll g&ir venstre Alt" +#define STR_4015 "Oppdater stat&uslinjeikoner" + +/* Menu: View > Renderer */ +#define STR_4020 "Re&nderer" + +/* Menu: View > Window Scale Factor */ +#define STR_4030 "(&w) Vinduskala" +#define STR_4031 "&0.5x" +#define STR_4032 "&1x" +#define STR_4033 "1.&5x" +#define STR_4034 "&2x" + +/* Menu: View > Fullscreen Stretch Mode */ +#define STR_4040 "Fullskjerm &strukket modus" +#define STR_4041 "&Fullskjerm strukket" +#define STR_4042 "&4:3" +#define STR_4043 "Kvadrati&ske piksler" +#define STR_4044 "Heltallskaler&ing" +#define STR_4045 "Faktis&k størrelse" + +/* Menu: Display (4050.) */ +#define STR_DISPLAY "(&d) Skjerm" +#define STR_4051 "&Omvendt video" +#define STR_4052 "Bruk &overskanning" +#define STR_4053 "Tving 4:3 bildeforh&old" +#define STR_4054 "(&c) Endre kontrast for monokrom skjerm" + +/* Menu: Display > Display Type */ +#define STR_DISPTYPE "Skjerm&type" +#define STR_4061 "(&c) RGB fargeskjerm" +#define STR_4062 "&GrÃ¥skalaskjerm" +#define STR_4063 "R&avfarget skjerm" +#define STR_4064 "&Grønn skjerm" +#define STR_4065 "(&w) Hvit skjerm" + +/* Menu: Display > Grayscale Conversion Type */ +#define STR_GRAYSCALE "&GrÃ¥skala konverteringsmetode" +#define STR_4071 "BT&601 (NTSC/PAL)" +#define STR_4072 "BT&709 (HDTV)" +#define STR_4073 "f&argesnitt" + +/* Menu: Tools (4080.) */ +#define STR_TOOLS "Verk&tøy" +#define STR_4081 "Inn&stillinger" +#define STR_4082 "SprÃ¥kva&lg" +#define STR_4083 "L&ogging" +#define STR_4084 "(&c) Last inn konfigurasjon" +#define STR_4085 "L&agre konfigurasjon" +#define STR_4086 "Stat&us" +#define STR_4087 "&Ta skjermbilde\tKontroll+Hjem" + +/* Menu: Help (4090.) */ +#define STR_HELP "&Hjelp" +#define STR_4091 "Om V&ARCem" + + +/* End of file. */ diff --git a/src/ui/lang/VARCem-SL.str b/src/ui/lang/VARCem-SL.str index 512e793..df3a9ed 100644 --- a/src/ui/lang/VARCem-SL.str +++ b/src/ui/lang/VARCem-SL.str @@ -1,4 +1,4 @@ -/* +/* * VARCem Virtual ARchaeological Computer EMulator. * An emulator of (mostly) x86-based PC systems and devices, * using the ISA,EISA,VLB,MCA and PCI system buses, roughly @@ -13,7 +13,7 @@ * it as the line-by-line base for the translated version, and * update fields as needed. * - * Version: @(#)VARCem-SL.str 1.0.3 2018/06/02 + * Version: @(#)VARCem-SL.str 1.0.4 2018/06/27 * * Authors: David Simunic, * Fred N. van Kempen, @@ -53,7 +53,7 @@ */ /* Do not translate! */ -#define TAG_VERSION 1,0,3 +#define TAG_VERSION 1,0,4 #define TAG_AUTHOR "David Simunic" #define TAG_EMAIL "simunic.david@outlook.com" @@ -293,7 +293,7 @@ #define STR_3579 "Histrost" #define STR_3580 "" #define STR_3581 "" -#define STR_3582 "ATAPI (samo only)" +#define STR_3582 "ATAPI (samo PIO)" #define STR_3583 "ATAPI (PIO+DMA)" #define STR_3584 "SCSI" #define STR_3585 "USB" @@ -389,7 +389,7 @@ /* Menu: Tools (4080.) */ #define STR_TOOLS "&Orodja" #define STR_4081 "&Nastavitve" -#define STR_4082 "&Jazyk" +#define STR_4082 "&Jezik" #define STR_4083 "&Beleženje" #define STR_4084 "N&aloži konfiguracijo" #define STR_4085 "&Shrani konfiguracijo" diff --git a/src/ui/lang/VARCem.lang b/src/ui/lang/VARCem.lang index a2efe3e..f63d80c 100644 --- a/src/ui/lang/VARCem.lang +++ b/src/ui/lang/VARCem.lang @@ -8,7 +8,7 @@ # # Supported Languages database. # -# Version: @(#)VARCem.lang 1.0.2 2018/06/19 +# Version: @(#)VARCem.lang 1.0.3 2018/07/11 # # Author: Fred N. van Kempen, # @@ -56,6 +56,7 @@ JP,0411,LANG_JAPANESE,SUBLANG_JAPANESE_JAPAN KR,0412,LANG_KOREAN,SUBLANG_KOREAN KZ,043f,LANG_KAZAK,SUBLANG_KAZAK_KAZAKHSTAN LT,0427,LANG_LITHUANIAN,SUBLANG_LITHUANIAN_LITHUANIA +NO,0414,LANG_NORWEGIAN,SUBLANG_NORWEGIAN_BOKMAL RU,0419,LANG_RUSSIAN,SUBLANG_RUSSIAN_RUSSIA SL,0424,LANG_SLOVENIAN,SUBLANG_SLOVENIAN_SLOVENIA UA,0422,LANG_UKRAINIAN,SUBLANG_UKRAINIAN_UKRAINE diff --git a/src/version.h b/src/version.h index 9bbf278..e55a72c 100644 --- a/src/version.h +++ b/src/version.h @@ -8,7 +8,7 @@ * * Define application version and build info. * - * Version: @(#)version.h 1.0.16 2018/06/25 + * Version: @(#)version.h 1.0.17 2018/07/28 * * Author: Fred N. van Kempen, * @@ -55,7 +55,7 @@ #define EMU_VER_MAJOR 0 #define EMU_VER_MINOR 1 #define EMU_VER_REV 6 -#define EMU_VER_PATCH 1 +#define EMU_VER_PATCH 2 /* Standard C preprocessor macros. */ diff --git a/src/win/mingw/Makefile.MinGW b/src/win/mingw/Makefile.MinGW index 1316e0a..c887246 100644 --- a/src/win/mingw/Makefile.MinGW +++ b/src/win/mingw/Makefile.MinGW @@ -8,7 +8,7 @@ # # Makefile for Windows systems using the MinGW32 environment. # -# Version: @(#)Makefile.mingw 1.0.49 2018/06/16 +# Version: @(#)Makefile.mingw 1.0.50 2018/07/28 # # Author: Fred N. van Kempen, # @@ -92,6 +92,9 @@ endif ifndef SDL SDL := n endif +ifndef D2D + D2D := n +endif ifndef VNC VNC := n endif @@ -404,6 +407,28 @@ ifneq ($(SDL), n) SDLOBJ := win_sdl.o endif +# N=no, Y=yes,linked, D=yes,dynamic, S=yes,static +ifneq ($(D2D), n) + ifeq ($(D2D), d) + OPTS += -DUSE_D2D=2 + else + OPTS += -DUSE_D2D=1 + endif + RFLAGS += -DUSE_D2D + ifneq ($(D2D_PATH), ) + OPTS += -I$(D2D_PATH)/include/mingw -I$(D2D_PATH)/include + ifeq ($(X64), y) + LOPTS += -L$(D2D_PATH)/lib/mingw/x64 + else + LOPTS += -L$(D2D_PATH)/lib/mingw/x86 + endif + endif + ifeq ($(D2D), y) + LIBS += -ld2d1 + endif + D2DOBJ := win_d2d.o +endif + # N=no, Y=yes,linked, D=yes,dynamic, S=yes,static ifneq ($(VNC), n) OPTS += -DUSE_VNC @@ -468,7 +493,7 @@ ifneq ($(WX), n) UIOBJ := wx_main.o wx_ui.o wx_stbar.o wx_render.o else UIOBJ := win_ui.o \ - win_ddraw.o win_d3d.o $(SDLOBJ) \ + win_ddraw.o win_d3d.o $(SDLOBJ) $(D2DOBJ) \ win_dialog.o win_about.o win_status.o \ win_settings.o win_devconf.o win_snd_gain.o \ win_new_image.o diff --git a/src/win/msvc/Makefile.VC b/src/win/msvc/Makefile.VC index f9a4516..abca1a2 100644 --- a/src/win/msvc/Makefile.VC +++ b/src/win/msvc/Makefile.VC @@ -8,7 +8,7 @@ # # Makefile for Windows using Visual Studio 2015. # -# Version: @(#)Makefile.VC 1.0.36 2018/06/19 +# Version: @(#)Makefile.VC 1.0.37 2018/07/28 # # Author: Fred N. van Kempen, # @@ -93,6 +93,9 @@ endif ifndef SDL SDL := n endif +ifndef D2D + D2D := n +endif ifndef VNC VNC := n endif @@ -378,6 +381,28 @@ ifneq ($(SDL), n) SDLOBJ := win_sdl.obj endif +# N=no, Y=yes,linked, D=yes,dynamic, S=yes,static +ifneq ($(D2D), n) + ifeq ($(D2D), d) + OPTS += -DUSE_D2D=2 + else + OPTS += -DUSE_D2D=1 + endif + RFLAGS += -DUSE_D2D + ifneq ($(D2D_PATH), ) + OPTS += -I$(D2D_PATH)/include/msvc -I$(D2D_PATH)/include + ifeq ($(X64), y) + LOPTS += -LIBPATH:$(D2D_PATH)\lib\msvc\x64 + else + LOPTS += -LIBPATH:$(D2D_PATH)\lib\msvc\x86 + endif + endif + ifeq ($(D2D), y) + LIBS += d2d1.lib + endif + D2DOBJ := win_d2d.obj +endif + # N=no, Y=yes,linked, D=yes,dynamic, S=yes,static ifneq ($(VNC), n) OPTS += -DUSE_VNC @@ -442,7 +467,7 @@ ifneq ($(WX), n) UIOBJ := wx_main.obj wx_ui.obj wx_stbar.obj wx_render.obj else UIOBJ := win_ui.obj \ - win_ddraw.obj win_d3d.obj $(SDLOBJ) \ + win_ddraw.obj win_d3d.obj $(SDLOBJ) $(D2DOBJ) \ win_dialog.obj win_about.obj win_status.obj \ win_settings.obj win_devconf.obj win_snd_gain.obj \ win_new_image.obj @@ -711,7 +736,7 @@ win/Mklang.cmd: win/msvc/Makefile.VC @echo @IF NOT "%%LANG%%"=="none" @$(MAKE) -fwin/msvc/Makefile.VC "RFLAGS=$(RFLAGS) $(EXTRAS)" LANG=%%LANG%% VARCem-%%1.dll >>win\Mklang.cmd -lang: win/Mklang.cmd +langs: win/Mklang.cmd ifdef LANG @echo Generating localization $(LANG) .. else diff --git a/src/win/win.c b/src/win/win.c index 41b346c..95e5d83 100644 --- a/src/win/win.c +++ b/src/win/win.c @@ -8,7 +8,7 @@ * * Platform main support module for Windows. * - * Version: @(#)win.c 1.0.16 2018/05/20 + * Version: @(#)win.c 1.0.17 2018/07/28 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -58,6 +58,9 @@ #ifdef USE_SDL # include "win_sdl.h" #endif +#ifdef USE_D2D +# include "win_d2d.h" +#endif #ifdef USE_VNC # include "../vnc.h" #endif @@ -89,6 +92,9 @@ const vidapi_t *plat_vidapis[] = { &ddraw_vidapi, &d3d_vidapi, #endif +#ifdef USE_D2D + &d2d_vidapi, +#endif #ifdef USE_SDL &sdl_vidapi, diff --git a/src/win/win.h b/src/win/win.h index ef63e64..e72b78e 100644 --- a/src/win/win.h +++ b/src/win/win.h @@ -8,7 +8,7 @@ * * Platform support defintions for Win32. * - * Version: @(#)win.h 1.0.17 2018/05/28 + * Version: @(#)win.h 1.0.18 2018/07/28 * * Authors: Fred N. van Kempen, * Miran Grca, diff --git a/src/win/win_d2d.cpp b/src/win/win_d2d.cpp new file mode 100644 index 0000000..247b656 --- /dev/null +++ b/src/win/win_d2d.cpp @@ -0,0 +1,450 @@ +/* + * VARCem Virtual ARchaeological Computer EMulator. + * An emulator of (mostly) x86-based PC systems and devices, + * using the ISA,EISA,VLB,MCA and PCI system buses, roughly + * spanning the era between 1981 and 1995. + * + * This file is part of the VARCem Project. + * + * Rendering module for Microsoft Direct2D. + * + * Version: @(#)win_d2d.cpp 1.0.1 2018/07/28 + * + * Authors: Fred N. van Kempen, + * David Hrdlicka, + * + * Copyright 2018 Fred N. van Kempen. + * Copyright 2018 David Hrdlicka. + * + * 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. + */ +#define UNICODE +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#include +#include +#include +#define PNG_DEBUG 0 +#include +#include "../emu.h" +#include "../version.h" +#include "../device.h" +#include "../plat.h" +#ifdef _MSC_VER +# pragma warning(disable: 4200) +#endif +#include "../devices/video/video.h" +#include "win.h" +#include "win_d2d.h" + + +#ifdef USE_D2D + +# if USE_D2D == 2 +# define PATH_D2D_DLL "d2d1.dll" +# define DLLFUNC(x) D2D1_ ## x + + +/* Pointers to the real functions. */ +static bool (*D2D1_CreateFactory)( + D2D1_FACTORY_TYPE factoryType, + REFIID riid, + CONST D2D1_FACTORY_OPTIONS *pFactoryOptions, + void **ppIFactory); + +static const dllimp_t d2d_imports[] = { + { "D2D1CreateFactory", &D2D1_CreateFactory }, + { NULL, NULL } +}; + +static void *d2d_handle = NULL; +# else +# define DLLFUNC(x) D2D1 ## x +# endif +#endif + + +static HWND d2d_hwnd, old_hwndMain; +static ID2D1Factory *d2d_factory; +static ID2D1HwndRenderTarget *d2d_hwndRT; +static ID2D1BitmapRenderTarget *d2d_btmpRT; +static ID2D1Bitmap *d2d_bitmap; +static int d2d_width, d2d_height, + d2d_screen_width, d2d_screen_height, + d2d_fs; + + +static void +d2d_stretch(float *w, float *h, float *x, float *y) +{ + double dw, dh, dx, dy, temp, temp2, ratio_w, ratio_h, gsr, hsr; + + switch (vid_fullscreen_scale) { + case FULLSCR_SCALE_FULL: + *w = (float)d2d_screen_width; + *h = (float)d2d_screen_height; + *x = 0; + *y = 0; + break; + + case FULLSCR_SCALE_43: + dw = (double)d2d_screen_width; + dh = (double)d2d_screen_height; + temp = (dh / 3.0) * 4.0; + dx = (dw - temp) / 2.0; + dw = temp; + *w = (float)dw; + *h = (float)dh; + *x = (float)dx; + *y = 0; + break; + + case FULLSCR_SCALE_SQ: + dw = (double)d2d_screen_width; + dh = (double)d2d_screen_height; + temp = ((double) *w); + temp2 = ((double) *h); + dx = (dw / 2.0) - ((dh * temp) / (temp2 * 2.0)); + dy = 0.0; + if (dx < 0.0) { + dx = 0.0; + dy = (dw / 2.0) - ((dh * temp2) / (temp * 2.0)); + } + dw -= (dx * 2.0); + dh -= (dy * 2.0); + *w = (float)dw; + *h = (float)dh; + *x = (float)dx; + *y = (float)dy; + break; + + case FULLSCR_SCALE_INT: + dw = (double)d2d_screen_width; + dh = (double)d2d_screen_height; + temp = ((double) *w); + temp2 = ((double) *h); + ratio_w = dw / ((double) *w); + ratio_h = dh / ((double) *h); + if (ratio_h < ratio_w) + ratio_w = ratio_h; + dx = (dw / 2.0) - ((temp * ratio_w) / 2.0); + dy = (dh / 2.0) - ((temp2 * ratio_h) / 2.0); + dw -= (dx * 2.0); + dh -= (dy * 2.0); + *w = (float)dw; + *h = (float)dh; + *x = (float)dx; + *y = (float)dy; + break; + + case FULLSCR_SCALE_KEEPRATIO: + dw = (double)d2d_screen_width; + dh = (double)d2d_screen_height; + hsr = dw / dh; + gsr = ((double) *w) / ((double) *h); + if (gsr <= hsr) { + temp = dh * gsr; + dx = (dw - temp) / 2.0; + dw = temp; + *w = (float)dw; + *h = (float)dh; + *x = (float)dx; + *y = 0; + } else { + temp = dw / gsr; + dy = (dh - temp) / 2.0; + dh = temp; + *w = (float)dw; + *h = (float)dh; + *x = 0; + *y = (float)dy; + } + break; + } +} + + +static void +d2d_blit(int x, int y, int y1, int y2, int w, int h) +{ + ID2D1Bitmap *fs_bitmap; + ID2D1RenderTarget *RT; + D2D1_RECT_U rectU; + HRESULT hr = S_OK; + void *srcdata; + int yy; + float fs_x, fs_y; + float fs_w = (float)w; + float fs_h = (float)h; + +#if 0 + pclog("D2D: blit(x=%d, y=%d, y1=%d, y2=%d, w=%d, h=%d)\n", x,y, y1,y2, w,h); +#endif + + // TODO: Detect double scanned mode and resize render target + // appropriately for more clear picture + if (w != d2d_width || h != d2d_height) { + if (d2d_fs) { + if (d2d_btmpRT) { + d2d_btmpRT->Release(); + d2d_btmpRT = NULL; + } + hr = d2d_hwndRT->CreateCompatibleRenderTarget( + D2D1::SizeF((float)w, (float)h), + &d2d_btmpRT); + if (SUCCEEDED(hr)) { + d2d_width = w; + d2d_height = h; + } + } else { + hr = d2d_hwndRT->Resize(D2D1::SizeU(w, h)); + if (SUCCEEDED(hr)) { + d2d_width = w; + d2d_height = h; + } + } + } + + if ((y1 == y2) || (buffer32 == NULL)) { + video_blit_complete(); + return; + } + + // TODO: Copy data directly from buffer32 to d2d_bitmap + srcdata = malloc(h * w * 4); + for (yy = y1; yy < y2; yy++) { + if ((y + yy) >= 0 && (y + yy) < buffer32->h) { +#if 0 + if (vid_grayscale || invert_display) + video_transform_copy( + (uint32_t *) &(((uint8_t *)srcdata)[yy * w * 4]), + &(((uint32_t *)buffer32->line[y + yy])[x]), + w); + else +#endif + memcpy( + (uint32_t *) &(((uint8_t *)srcdata)[yy * w * 4]), + &(((uint32_t *)buffer32->line[y + yy])[x]), + w * 4); + } + } + + video_blit_complete(); + + rectU = D2D1::RectU(0, 0, w, h); + hr = d2d_bitmap->CopyFromMemory(&rectU, srcdata, w * 4); + // In fullscreen mode we first draw offscreen to an intermediate + // BitmapRenderTarget, which then gets rendered to the actual + // HwndRenderTarget in order to implement different scaling modes + // In windowed mode we draw directly to the HwndRenderTarget + if (SUCCEEDED(hr)) { + RT = d2d_fs ? (ID2D1RenderTarget *) d2d_btmpRT : (ID2D1RenderTarget *) d2d_hwndRT; + RT->BeginDraw(); + RT->DrawBitmap(d2d_bitmap, + D2D1::RectF(0, (float)y1, (float)w, (float)y2), + 1.0f, + D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR, + D2D1::RectF(0, (float)y1, (float)w, (float)y2)); + hr = RT->EndDraw(); + } + + if (d2d_fs) { + if (SUCCEEDED(hr)) + hr = d2d_btmpRT->GetBitmap(&fs_bitmap); + if (SUCCEEDED(hr)) { + d2d_stretch(&fs_w, &fs_h, &fs_x, &fs_y); + d2d_hwndRT->BeginDraw(); + d2d_hwndRT->Clear(D2D1::ColorF(D2D1::ColorF::Black)); + d2d_hwndRT->DrawBitmap(fs_bitmap, + D2D1::RectF(fs_x, fs_y, fs_x + fs_w, fs_y + fs_h), + 1.0f, + D2D1_BITMAP_INTERPOLATION_MODE_LINEAR, + D2D1::RectF(0, 0, (float)w, (float)h)); + hr = d2d_hwndRT->EndDraw(); + } + } + + if (FAILED(hr)) + pclog("D2D: blit: error 0x%08lx\n", hr); + + /* Clean up. */ + free(srcdata); +} + + +static void +d2d_close(void) +{ + pclog("D2D: close()\n"); + + video_setblit(NULL); + + if (d2d_bitmap) { + d2d_bitmap->Release(); + d2d_bitmap = NULL; + } + if (d2d_btmpRT) { + d2d_btmpRT->Release(); + d2d_btmpRT = NULL; + } + + if (d2d_hwndRT) { + d2d_hwndRT->Release(); + d2d_hwndRT = NULL; + } + if (d2d_factory) { + d2d_factory->Release(); + d2d_factory = NULL; + } + if (d2d_hwnd) { + hwndMain = old_hwndMain; + plat_set_input(hwndMain); + DestroyWindow(d2d_hwnd); + d2d_hwnd = NULL; + old_hwndMain = NULL; + } + +#if defined(USE_D2D) && USE_D2D == 2 + /* Quit and unload the DLL if possible. */ + if (d2d_handle != NULL) { + dynld_close(d2d_handle); + d2d_handle = NULL; + } +#endif +} + + +static int +d2d_init(int fs) +{ + WCHAR title[200]; + D2D1_HWND_RENDER_TARGET_PROPERTIES props; + HRESULT hr = S_OK; + + pclog("D2D: init(fs=%d)\n", fs); + + cgapal_rebuild(); + +#if defined(USE_D2D) && USE_D2D == 2 + /* Try loading the DLL. */ + d2d_handle = dynld_module(PATH_D2D_DLL, d2d_imports); + if (d2d_handle == NULL) { + pclog("D2D: unable to load '%s', D2D not available.\n", PATH_D2D_DLL); + return(0); + } +#endif + + /* Get and log the version of the DLL we are using. */ + if (fs) { + /* + * Direct2D seems to lack any proper fullscreen mode, + * therefore we just create a full screen window and + * pass its handle to a HwndRenderTarget. + */ + d2d_screen_width = GetSystemMetrics(SM_CXSCREEN); + d2d_screen_height = GetSystemMetrics(SM_CYSCREEN); + + mbstowcs(title, emu_version, sizeof_w(title)); + d2d_hwnd = CreateWindow(FS_CLASS_NAME, + title, + WS_POPUP, + 0, 0, d2d_screen_width, d2d_screen_height, + HWND_DESKTOP, + NULL, + hInstance, + NULL); + + old_hwndMain = hwndMain; + hwndMain = d2d_hwnd; + + plat_set_input(d2d_hwnd); + SetFocus(d2d_hwnd); + SetWindowPos(d2d_hwnd, HWND_TOPMOST, + 0,0, d2d_screen_width,d2d_screen_height, SWP_SHOWWINDOW); + } + + if (SUCCEEDED(hr)) + hr = DLLFUNC(CreateFactory)(D2D1_FACTORY_TYPE_MULTI_THREADED, + __uuidof(ID2D1Factory), + NULL, + reinterpret_cast (&d2d_factory)); + + if (fs) { + props = D2D1::HwndRenderTargetProperties(d2d_hwnd, + D2D1::SizeU(d2d_screen_width, d2d_screen_height)); + } else { + // HwndRenderTarget will get resized appropriately by d2d_blit, + // so it's fine to let D2D imply size of 0x0 for now + props = D2D1::HwndRenderTargetProperties(hwndRender); + } + + if (SUCCEEDED(hr)) + hr = d2d_factory->CreateHwndRenderTarget(D2D1::RenderTargetProperties(), + props, + &d2d_hwndRT); + if (SUCCEEDED(hr)) { + // Create a bitmap for storing intermediate data + hr = d2d_hwndRT->CreateBitmap(D2D1::SizeU(2048, 2048), + D2D1::BitmapProperties(D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE)), + &d2d_bitmap); + } + + if (FAILED(hr)) { + pclog("D2D: init: error 0x%08lx\n", hr); + d2d_close(); + return(0); + } + + d2d_fs = fs; + d2d_width = 0; + d2d_height = 0; + + /* Make sure we get a clean exit. */ + atexit(d2d_close); + + /* Register our renderer! */ + video_setblit(d2d_blit); + + return(1); +} + + +static void +d2d_screenshot(const wchar_t *fn) +{ + // Saving a screenshot of a Direct2D render target is harder than + // one would think. Keeping this stubbed for the moment + // -ryu + pclog("D2D: screenshot(%ls)\n", fn); +} + + +const vidapi_t d2d_vidapi = { + "D2D", + 1, + d2d_init, + d2d_close, + NULL, + NULL, + NULL, + d2d_screenshot, + NULL +}; diff --git a/src/win/win_d2d.h b/src/win/win_d2d.h new file mode 100644 index 0000000..13aef4d --- /dev/null +++ b/src/win/win_d2d.h @@ -0,0 +1,62 @@ +/* + * VARCem Virtual ARchaeological Computer EMulator. + * An emulator of (mostly) x86-based PC systems and devices, + * using the ISA,EISA,VLB,MCA and PCI system buses, roughly + * spanning the era between 1981 and 1995. + * + * This file is part of the VARCem Project. + * + * Definitions for the Direct2D rendering module. + * + * Version: @(#)win_d2d.h 1.0.1 2018/07/28 + * + * Author: Fred N. van Kempen, + * + * Copyright 2018 Fred N. van Kempen. + * + * Redistribution and use in source and binary forms, with + * or without modification, are permitted provided that the + * following conditions are met: + * + * 1. Redistributions of source code must retain the entire + * above notice, this list of conditions and the following + * disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names + * of its contributors may be used to endorse or promote + * products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef WIN_D2D_H +# define WIN_D2D_H + + +#ifdef __cplusplus +extern "C" { +#endif + +extern const vidapi_t d2d_vidapi; + +#ifdef __cplusplus +} +#endif + + +#endif /*WIN_D2D_H*/