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*/