From 17d06ca519591c77cd795177be3bd259faadcf18 Mon Sep 17 00:00:00 2001 From: Jaroslav Hensl Date: Tue, 19 Mar 2024 02:13:58 +0100 Subject: [PATCH] new release --- Makefile | 15 +- README.md | 184 ++++++++---- actions.c | 448 ++++++++++++++++++++++++++--- actions.h | 30 +- changelog.txt | 20 ++ filecopy.h | 2 + resource/softgpu-se.ico | Bin 0 -> 1078 bytes resource/softgpu.rc | 4 + settings.c | 174 ++++++++++++ softgpu.c | 612 +++++++++++++--------------------------- softgpu.h | 136 +++++++++ softgpu.htm | 6 + softgpu.ini | 25 +- softgpu.md | 367 ++++++++++++++++++++++++ window.c | 511 +++++++++++++++++++++++++++++++++ windrv.c | 2 +- windrv.h | 2 +- winreg.c | 32 +++ winreg.h | 1 + winres.c | 82 ++++++ winres.h | 6 + 21 files changed, 2126 insertions(+), 533 deletions(-) create mode 100644 resource/softgpu-se.ico create mode 100644 settings.c create mode 100644 softgpu.h create mode 100644 softgpu.htm create mode 100644 softgpu.md create mode 100644 window.c create mode 100644 winres.c create mode 100644 winres.h diff --git a/Makefile b/Makefile index 2f2d3ba..c55263a 100644 --- a/Makefile +++ b/Makefile @@ -5,13 +5,17 @@ OBJ_SUFFIX = .o EXE_NAME = softgpu EXE_SUFFIX = .exe LDFLAGS=-static -LIBS=-lsetupapi -lgdi32 -luser32 -ladvapi32 -lsetupapi -lkernel32 -lshell32 -Wl,-subsystem,windows -#LIBS=-lsetupapi -lgdi32 -luser32 -ladvapi32 -lsetupapi -lkernel32 -lshell32 -Wl,-subsystem,console +LIBS=-lsetupapi -lgdi32 -luser32 -ladvapi32 -lkernel32 -lshell32 -lversion -Wl,-subsystem,windows +#LIBS=-lsetupapi -lgdi32 -luser32 -ladvapi32 -lkernel32 -lshell32 -lversion -Wl,-subsystem,console -SOFTGPU_PATCH=2023 +SOFTGPU_PATCH=2024 ifdef EXTRA_INFO -CFLAGS += -DEXTRA_INFO="\"$(EXTRA_INFO)\"" +CFLAGS += -DEXTRA_INFO="$(EXTRA_INFO)" +endif + +ifdef EXTRA_ICO +RES_FLAGS += -DEXTRA_ICO="$(EXTRA_ICO)" endif NULLOUT=$(if $(filter $(OS),Windows_NT),NUL,/dev/null) @@ -34,7 +38,10 @@ SOURCES = \ winini.c \ windrv.c \ winreg.c \ + winres.c \ setuperr.c \ + window.c \ + settings.c \ resource/softgpu.rc diff --git a/README.md b/README.md index 80df24e..a0301a2 100644 --- a/README.md +++ b/README.md @@ -2,11 +2,13 @@ ![SoftGPU animated logo](resource/softgpu.webp) -This is ready-to-use compilation of my 4 projects: +This is ready-to-use compilation of my ~4~ 6 projects: - VMDisp9x: https://github.com/JHRobotics/vmdisp9x - Mesa3D for 9x: https://github.com/JHRobotics/mesa9x - WineD3D for 9x: https://github.com/JHRobotics/wine9x - OpenGlide for 9x: https://github.com/JHRobotics/openglide9x +- VMHAL9x: https://github.com/JHRobotics/vmhal9x +- ICD enabled fork of qemu-3dfx: https://github.com/JHRobotics/qemu-3dfx ## Requirements 1) Virtual machine with one of these VGA adapter support: @@ -29,23 +31,27 @@ This is ready-to-use compilation of my 4 projects: | VMware Workstation | 16, 17 | - | ✔ | ✔ | ✔ | ⚠ | ✔ | SBPCI128 | | QEMU | 7.x, 8.0 | std | ✔ | ✔ | ✔ | ✔ | ❌ | adlib, SB16, AC97 | | QEMU | 7.x, 8.0 | vmware | ✔ | ✔ | ❌ | ❌ | ❌ | adlib, SB16, AC97 | +| QEMU | 7.x, 8.0 | std + qemu-3dfx | ✔ | ✔ | ✔ | ✔ | ✔ | adlib, SB16, AC97 | - -SoftGPU can use 3 render drivers: +SoftGPU can use 4 render drivers: - *softpipe*: software Mesa3D reference renderer - *llvmlipe*: software LLVM accelerated 3D renderer - *SVGA3D*: HW renderer for virtual GPU adapter VMWare SVGA-II (sometimes called VMSVGA, VboxSVGA or SVGA-III) +- *qemu-3dfx*: [3D passthrough for QEMU by KJ Liew](https://github.com/kjliew/qemu-3dfx), allow bypass OpenGL and GLIDE primitives to hypervisor's GPU. QEMU and fullscreen only. Not all renderers supporting all application/games, performance expectation is in 1024x768 32bit: -| Renderer | Requirements | OpenGL version | DX9 | DX9 shaders | DX8 | DX8 shaders | DX6-7 | OpenGL | Glide | Glide DOS | Expected FPS | -| :------------------ | :------------: | :------------: | :--: | :---------: | :--: | :---------: | :---: | :----: | :---: | :-------: | :----------: | -| softpipe | - | 3.3 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | 1-3 | -| llvmlipe (128 bits) | SSE | 3.3 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | 10-15 | -| llvmlipe (256 bits) | SSE, AVX | 3.3 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | 12-20 | -| SVGA3D | SVGA-II (gen9) | 2.1 | ✔ | ❌ | ✔ | ❌ | ✔ | ✔ | ✔ | ❌ | 30-60 | -| SVGA3D | SVGA-II (gen10)| 4.1 | ✔ | ✔ | ⚠ | ✔ | ❌ | ❌ | ❌ | ❌ | 35-80 | +| Renderer | Requirements | OpenGL version | DX9 | DX9 shaders | DX8 | DX8 shaders | DX6-7 | OpenGL | multiple contexts | window mode | Glide | Glide DOS | Expected FPS | +| :------------------ | :------------: | :------------: | :--: | :---------: | :--: | :---------: | :---: | :----: | :---------------: | :---------: | :---: | :-------: | :----------: | +| softpipe | - | 3.3 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | 1-3 | +| llvmlipe (128 bits) | SSE | 3.3 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | 10-15 | +| llvmlipe (256 bits) | SSE, AVX | 3.3 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | 12-20 | +| SVGA3D | SVGA-II (gen9) | 2.1 | ✔ | ❌ | ✔ | ❌ | ✔ | ✔ | ⚠ | ✔ | ✔ | ❌ | 30-60 | +| SVGA3D | SVGA-II (gen10)| 4.1 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | 35-80 | +| qemu-3dfx | [qemu-3dfx](https://github.com/kjliew/qemu-3dfx) | native | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | ❌ | ✔ * | ✔ * | native/2 * | + +Note for qemu-3dfx: performance depends on CPU emulation - you can reach about 1/2 of native GPU performance when using KVM acceleration on x86-64 host, about 1/5 when using Hyper-V, and about from 1/100 when is using accelerated emulation and about 1/1000 when using full emulation. DOS Glide and *native* Glide wrapper isn't part of SoftGPU. You have to compile it from source or you can [donate qemu-3dfx author](https://github.com/kjliew/qemu-3dfx#donation). Hypervisor translation to real HW GPU: @@ -57,32 +63,34 @@ Hypervisor translation to real HW GPU: | llvmlipe | framebuffer | all | | SVGA3D (gen 9) | DX9/OpenGL 2.1 | VirtualBox 6+7, VMware Workstation | | SVGA3D (gen 10) | DX11/Vulkan | VirtualBox 7 | +| qemu-3dfx | native OpenGL | QEMU with qemu-3dfx patch| ## Download ISO image or ZIP package can be downloaded on release page: https://github.com/JHRobotics/softgpu/releases/ ## Installation -0) Setup the Virtual Machine +General instruction for most machines: + +0) Setup the Virtual Machine (VM) 1) Copy installation files on formatted HDD and apply **patcher9x** [Optional but recommended] 2) Install the Windows 95/98/Me [Windows 98 SE is recommended] -3) Run setup with `softgpu.exe` -4) [optional] Install audio drivers (if using AC97 sound card) and USB (if you added USB controller) -5) [only if you have AC97 sound card] Reinstall DirectX again = AC97 replacing some DX files, but they are not working with newer DX versions -6) Have fun! +3) [optional] install **PATCHMEM by rloew** and increase VM memory (1024 MB is usually enough) +4) [optional] install audio drivers ([the most common drivers are below](#extra-drivers))[^1] +5) Run setup with `softgpu.exe` +6) [optional] Install additional drivers, for example USB (if you added USB controller) +7) Have fun! + +[^1]: Do this before install/update DirectX redistributable, because audio drivers usually overwrite DX files with outdated versions. ## Update If you have an older version of SoftGPU installed, you can update without any problem: insert the CD with the latest version into the VM and click install. The installer will take care of all the necessary modifications, only to increase compatibility it is necessary to do some steps manually: -**Update to version v0.4.2023.19** -- Only applies to 95/98 not Me -- Fixes occasional problem with DirectDraw detection (3DMark99) -- Find the following key in the registry: +**Update to version v0.5.2024.24** +- *VirtualBox 7.0.x*: it is possible to turn on vGPU10: ``` -HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SessionManager\KnownDLLs -``` -- And remove the value named `DDRAW` (with data `ddrawme.dll`) -- Don't do these steps in **Windows Me**, in Me is still this registry key necessary to make DDraw and DX 7 and lower to work! +VBoxManage setextradata "My Windows 98" "VBoxInternal/Devices/vga/0/Config/VMSVGA10" "1" +``` ## SoftGPU in action @@ -94,10 +102,17 @@ HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SessionManager\KnownDLLs For comparison, [video from real end-of-era PC is here](https://youtu.be/JqHw-Oh3TfY). So, some work still needs to be done :-) -## VirtualBox VM setup with HW acceleration +## Hypervisor specific setup + +Here are some brief steps for individual virtualisation software: +- VirtualBox +- VMware Workstation/Player +- QEMU + +### VirtualBox VM setup with HW acceleration 1) Create new VM selecting *Machine -> New* in menu 2) Type: Microsoft Windows, Version: Windows 98 -3) Base memory: **512 MB** (256 MB is minimum, but more 512 MB isn't recommended without additional patches!), CPU: 1 +3) Base memory: **512 MB** (this is minimum (for vGPU10), but more 512 MB isn't recommended without additional patches!), CPU: 1 4) Disk size: recommended is at least 20 GB for 98/Me (you can select less, but HDD becomes full faster). Select 2 GB if you plan install Windows 95. Tip: If you storing virtual machine on classic HDD, check *Pre-allocate Full Size*, because it leads to lower disk image fragmentation. 5) Finish wizard 6) Open VM setting @@ -108,15 +123,9 @@ For comparison, [video from real end-of-era PC is here](https://youtu.be/JqHw-Oh - Check **enable 3D Acceleration** 7) Optional adjustment - set USB controller to USB 1.1 (OHCI) for 98/Me, or turn USB off for 95 -- Audio controller set to **SoundBlaster 16** for 95 ~and 98~ or **AC 97** for 98 and Me (working drivers for Windows 98 are [below](#extra-drivers). -8) Disable VMSVGA10 **(VirtualBox >= 7.0 only!)** -- Open command line -- (on Windows) navigate to VirtualBox installation directory (default: *C:\Program Files\Oracle\VirtualBox*) -- Enter this command where *My Windows 98* is your Virtual Machine name -``` -VBoxManage setextradata "My Windows 98" "VBoxInternal/Devices/vga/0/Config/VMSVGA10" "0" -``` -9) Install system - Windows 98 SE is highly recommended (for newer CPU, you need my patch: https://github.com/JHRobotics/patcher9x) +- Audio controller set to **SoundBlaster 16** for 95 ~and 98~ or **AC 97** for 98 and Me (working drivers for Windows 98 are [below](#extra-drivers)). +8) Install system - Windows 98 SE is highly recommended (for newer CPU, you need my patch: https://github.com/JHRobotics/patcher9x) +9) Optional increase memory - especially vGPU10 driver is relative heavy about RAM usage. Apply **PATCHMEM by rloew**, after it you can increase base RAM (768 MB or 1024 MB should be enough) 10) Insert SoftGPU iso (can be downloaded in Releases) and run `softgpu.exe` 11) Click on *Install!* 12) You maybe need some reboots (after MSVCRT and DX installation) and run `softgpu.exe` again. @@ -126,7 +135,7 @@ VBoxManage setextradata "My Windows 98" "VBoxInternal/Devices/vga/0/Config/VMSVG - to 16 bits for 95, because 95 can't set colour depth on runtime (reboot is required) and lots of old applications can't start in 32 bits (all Glide for example) 15) Verify settings: - OpenGL: run `glchecker.exe` in `tools` on SoftGPU CD - - If renderer is **SVGA3D**, you have HW acceleration, congratulation! If you OpenGL version is **2.1**, you done all right. If OpenGL version is **4.1** you have GPU gen 10 active, it isn't wrong, but you may see graphical glitches in lots of games = navigate back to *8.* to turn it off. + - If renderer is **SVGA3D**, you have HW acceleration, congratulation! If you OpenGL version is **2.1** you running on vGPU9 - most application works but none vertex/pixel shaders. If OpenGL version is **3.3** you have vGPU10 active, from SoftGPU 0.5.x this is preferred variant and most application should work. - If renderer is **llvmpipe**, you have still SW acceleration, but at least accelerated by SSE (128 bits) or AVX (256 bit). GPU acceleration is disabled or you real GPU isn't sporting HW acceleration. - If renderer is **softpipe**, you have SW acceleration and running on reference (but slow) renderer, SIMD ins't accesable somehow, or you on 95, where is softpipe renderer by default, even if SIMD hack is installed (more in Mesa9x documentation: https://github.com/JHRobotics/mesa9x). - If renderer is **Generic**, then ICD OpenGL DLL is not loaded. Something is wrong with system or you installed SSE instrumented binaries on no SSE enabled/supported guest. @@ -136,10 +145,10 @@ VBoxManage setextradata "My Windows 98" "VBoxInternal/Devices/vga/0/Config/VMSVG - On Me you can still run **dxdiag**, but you can only check DX8 and DX9, because we cannot easily replace system `DDRAW.DLL`. But DX6 and DX7 games should usually run without problems - On 95 you can still run **dxdiag**, but if you run test, you only see black screens, but again, games (if supporting 95) games should usually run -### AMD Zen, 11th Generation Intel Core and newer +#### AMD Zen, 11th Generation Intel Core and newer Newer CPU have excellent performance but needs some extra tune: 1) apply [patcher9x](https://github.com/JHRobotics/patcher9x) - this is required! -2) Change TSC (Time Stamp Counter) behaviour (Warning: this options is not available when VirtualBox is using Hyper-V as execution, engine!) +2) Change TSC (Time Stamp Counter) behaviour (Warning: this options is not available when VirtualBox is using Hyper-V as execution engine!) ``` VBoxManage setextradata "My Windows 98" "VBoxInternal/TM/TSCTiedToExecution" 1 ``` @@ -148,17 +157,44 @@ VBoxManage setextradata "My Windows 98" "VBoxInternal/TM/TSCTiedToExecution" 1 VBoxManage modifyvm "My Windows 98" --cpu-profile "AMD Ryzen 7 1800X Eight-Core" ``` +### vGPU9 vs. vGPU10 + +There are 2 variant of graphical HW acceleration in VirtualBox 7: + +**vGPU9** (9 from DirectX 9) is older variant used usually to accelerate Windows Vista/7 aero and some desktop application. On host system is drawing by DirectX 9 (Windows) or OpenGL (Linux/Mac OS). Problem is very low pixel/vertex shader support, so DirectX 8 and DirectX 9 games can't use shaders. Keep on mind that DirectX in SoftGPU is emulated by Wine, so some non-shaders applications can have problems, because some behaviour is emulated by shaders. + +**vGPU10** (10 from Windows 10) is newer variant and is intended for acceleration of DirectX 12 (and DirectX 12 can emulate all older DirectX API). On host system is drawing by DirectX 12 (on Linux is translated by **dxvk** to Vulkan). Main problem is a relatively large amount of bugs ([see summary here](https://www.virtualbox.org/ticket/21515)). vGPU10 don't work well with SoftGPU 0.4.x releases, but SoftGPU 0.5.x solved most of problem and now this is preferred variant. + +Switch between vGPU9 and vGPU10: + +- Open command line +- (on Windows) navigate to VirtualBox installation directory (default: *C:\Program Files\Oracle\VirtualBox*) +- Enter this command to use **vGPU9** where *My Windows 98* is your Virtual Machine name: +``` +VBoxManage setextradata "My Windows 98" "VBoxInternal/Devices/vga/0/Config/VMSVGA10" "0" +``` +- This command is force use **vGPU10**: +``` +VBoxManage setextradata "My Windows 98" "VBoxInternal/Devices/vga/0/Config/VMSVGA10" "1" +``` +- vGPU variant is choose by VirtualBox (default) and vGPU10 is preferred if host hardware is support DX 11.1/Vulkan[^2]. +``` +VBoxManage setextradata "My Windows 98" "VBoxInternal/Devices/vga/0/Config/VMSVGA10" "" +``` + +[^2]: OK, and there some bugs, so VirtualBox is using vGPU10 event on DX10 only GPUs, so result is usually nice black screen... + -## VMware Workstation setup with HW acceleration +### VMware Workstation setup with HW acceleration SoftGPU with HW acceleration was tested only with lasted version of VMware Workstation (17.0.0 build-20800274), if you'll be successful with older version or free VMware player, please let me know. -### General information +#### General information - Use **Windows 98 SE**, newer Mesa is not currently working in 95 and Windows 98 FE (first edition) hasn't supporting WDM sound cards so you might have a problem with sound. - **Fresh install**, Windows 9x doesn't like hardware changes and if you import import VM from somewhere, strange problems may occur. - **no VMware additions**, ~because they only contain basic display driver,~ contain mouse integration driver and tray program which **is replacing display driver to VMware default display driver** [and some integration utilities](https://github.com/JHRobotics/softgpu/issues/14). If you want mouse integration driver (but is useless for gaming with mouse) alone driver is [listed below](#extra-drivers). - set as hardware compatibility **Workstation 9.x** and VM type **Windows 2000 Server**. VMware in other cases is comparing installed addition tools version and features with hypervisor version and if they don't match refuses to expose SVGA 3D commands to guest. -### Step by step guide +#### Step by step guide 1) Create new VM - from menu File->New Virtual Machine 2) In wizard choose *Custom (advanced)* click on next: - As *Hardware compatibility* select **Workstation 9.x** (important) @@ -182,9 +218,7 @@ SoftGPU with HW acceleration was tested only with lasted version of VMware Works ![](resource/docs/vmw-setup-3.png) - click on *USB Controller* and set *USB compatibility* to **USB 1.1** or remove USB controller completely - - click on *Display* and check **Accelerate 3D graphics** - -![](resource/docs/vmw-setup-4.png) + - click on *Display* but make sure, that **Accelerate 3D graphics** is turned **off** for installation = VMWare 7.x is painfully slow on 4/8-bit mode when is 3D acceleration enabled. So, turn in off for installation and turn in on after SoftGPU is installed. - (optional) click on *Printer* and click *Remove* (if you don't plan to use this feature, you'll save yourself from a pointless warning message) - click on *New CD/DVD (IDE)* and point *Use ISO image file* to your Windows 98 installation CD ISO. @@ -200,14 +234,18 @@ SoftGPU with HW acceleration was tested only with lasted version of VMware Works 7) Click on *Install!* 8) You maybe need some reboots (after MSVCRT and DX installation) and run `softgpu.exe` again. 9) After complete and final reboot system should start in 640x480 in 32 bits per pixel colors. -10) If you have still mouse trouble, open *Device Manager* (by cursor keys select *My Computer* and press `Alt`+`Enter` to open properties), then disable all *HID-compliant mouse*. Reboot VM after done! +10) If you have mouse trouble, open *Device Manager* (by cursor keys select *My Computer* and press `Alt`+`Enter` to open properties), then disable all *HID-compliant mouse*. Reboot VM after done! ![VMware HID devices disabled](resource/docs/vmw-hid.png) -11) Use `glchecker.exe` to verify settings +11) Turn off VM, open VM setting and under Display check **Accelerate 3D graphics** +![](resource/docs/vmw-setup-4.png) -## VMware Workstation Player +12) Start VM and use `glchecker.exe` to verify settings. + + +### VMware Workstation Player VMware Workstation Player hasn't GUI option to select virtual machine version. But you can set it manually by editing `*.vmx` file: 0) Turn VM off @@ -226,10 +264,21 @@ virtualHW.version = "9" -## QEMU -Hardware 3D support isn't available yet with QEMU. 2D driver now works with QEMU `-vga std` or `-vga vmware`. But main problem with QEMU is bad detection of a PCI bus. If the PCI bus is detected badly, system won't enumerate most of device - VGA adapter, sound and network card and even IDE bus. +### QEMU + +There is no native 3D acceleration support for QEMU yet, but you can apply QEMU-3dfx patches. + +Next problem with QEMU is, that Windows 98 incorrectly detected PCI bus as PnP BIOS. There is 2 solutions for it. + +#### Non-PnP BIOS + +This is best for fresh installations. First you need [SeaBIOS](https://www.seabios.org/SeaBIOS) with disabled `CONFIG_PNPBIOS`. You can compile manually from source or you can use my binary: [seabios-qemu.zip](https://files.emulace.cz/seabios-qemu.zip). Extract `bios.bin` somewhere and run QEMU with '-bios /path/to/somewhere/bios.bin'. Windows 9x installation with this BIOS should detect all hardware without problems. + + +#### PCI bus detection fix + +If you have already installed system and you don't see any PCI hardware, use these steps: -### PCI bus detection fix 1) Open Device Manager and locate *Plug and Play BIOS* (Exclamation mark should be on it) ![QEMU PCI: Plug and Play BIOS](resource/docs/qemu-pci-1.png) @@ -264,26 +313,33 @@ warning message and reboot computer. 8) After reboot (again), you have working system now and you can install SoftGPU and other drivers. -## Virtual GPU gen. 10 -VirtualBox 7.0 is supporting newer technology for rendering. It is supporting pixel/vertex/computing shaders but it is still incomplete. You can turn in by this command. +#### QEMU-3dfx + +1) [Built patched QEMU](https://github.com/kjliew/qemu-3dfx?tab=readme-ov-file#building-qemu) +2) Install Windows 98 with disabled CPU accelerator (it's a bit slow) +3) Check if you see PCI bus on Hardware manager +4) (optional) Install audio driver you're using AC-97 +5) Mount SoftGPU ISO and install SoftGPU +6) Reboot and check if video driver works +7) Now you can shutdown VM and run again with CPU accelerator enabled +8) Now navigate to SoftGPU CD to `extras\qemu3dfx` folder and you have do set the signature: + +For QEMU-3dfx need both wrapper and hypervisor same signature to works. This signature is first 7 characters from GIT revision hash. You can obtain the hash by this command in cloned qemu-3dfx repository: ``` -VBoxManage setextradata "My Windows 98" "VBoxInternal/Devices/vga/0/Config/VMSVGA10" "1" +git rev-parse HEAD ``` +Binaries in SoftGPU allows to override build signature registry keys. To check that you have same signature as QEMU run `testqmfx.exe` (in `extras\qemu3dfx`). If you see error 0x45A (= ERROR_DLL_INIT_FAILED), you have wrong signature. In this case edit `set-sign.reg` (copy it from CD to writeable location) and rewrite the value `REV_QEMU3DFX` to revision hash obtain from GIT (you need only first 7 characters, retype full hash isn't necessary). After it apply file to registry (by double click on file) and run `testqmfx.exe` to check the result - you should see rotating triangle on success and see OpenGL information from your host GPU. + +9) Copy `fxmemmap.vxd` and `qmfxgl32.dll` to `C:\WINDOWS\SYSTEM` and apply file `icd-enable.reg` (this tells to driver using `qmfxgl32.dll` when system `opengl32.dll` ask about OpenGL driver). +10) reboot (**required**) +11) run *GLchecker* or some other 3D application to verify settings. -On most configurations this is turn on by default (allows for example Windows 7-11 desktop composition aka "aero") but for legacy technologies isn't ready yet - you can probably see some serious graphical glitches if you use it with pre DirectX 9 application/games. But if you want run 3DMark03 or 2001 you'll have to turn this on. If you application or game work with this configuration, it usually runs smoother than with GPU gen. 9. ## Bugs Currently there are known these limitations: ### Vertex Shaders -Vertex shaders not working correctly with HW acceleration. You can see it, for example, with 3D Mark 2001/2003 tests. Using shaders is very rare in DirectX 8 games, but very common in DirectX 9 games (on other hand, these are usually games after Windows 9x era). As temporary solution you can turn off HW acceleration (but rendering will be much slower). Some games also has failback technology if GPU hasn't shader support (for example GTA SA). You can globally disable Vertex Shaders inserting this to registry: - -``` -REGEDIT4 - -[HKEY_LOCAL_MACHINE\Software\Wine\global] -"MaxShaderModelVS"=dword:00000000 -``` +**Update for 0.5.x versions**: Vertex Shaders works on vGPUv10 (VirtualBox 7) and for qemu-3dfx. For vGPU9 (VMware, VirtualBox 6.1) are DirectX shaders disabled, so most of applications can use shader alternative (most of DX8 games and lost of DX9). ### Windows 95 support Windows 95 support is limited - SoftGPU works, but there lots of extra bugs will appear and if you haven't any special reasons for using Windows 95 use recommended Windows 98 Second edition instead. @@ -351,8 +407,12 @@ http://files.emulace.cz/7z920.exe ``` +## Runtime configuration + +There a few registry keys to configure SoftGPU and its component, more on [softgpu.md](softgpu.md) or *softgpu.html* on SoftGPU CD. + -## Compilation from source +## Compilation from source (outdated) 1) You need MINGW and *GNU make* to build *softgpu.exe* 2) You need all development tool to compile all other component (see README.md in individual repositories) 3) Compile softgpu.exe by type `make` diff --git a/actions.c b/actions.c index 87fc2bf..4a70ce4 100644 --- a/actions.c +++ b/actions.c @@ -26,12 +26,10 @@ #include #include #include -#include "winini.h" -#include "windrv.h" -#include "actions.h" -#include "filecopy.h" -#include "winreg.h" -#include "setuperr.h" +#include + +#include "softgpu.h" + #include "nocrt.h" #define MAX(_a, _b) (((_b) > (_a)) ? (_b) : (_a)) @@ -315,11 +313,6 @@ BOOL proc_wait(HWND hwnd) return TRUE; } -extern version_t sysver; -extern version_t WINVER98SE; -extern version_t WINVER98; -extern version_t WINVERME; - void install_infobox(HWND hwnd, const char *name) { static char msg_buffer[512]; @@ -351,6 +344,40 @@ BOOL mscv_start(HWND hwnd) return install_run(iniValue("[softgpu]", "msvcrtpath"), &pi_proc, &pi_thread, TRUE); } +void delete_bad_dx_files() +{ + char syspath[MAX_PATH]; + size_t syspath_len; + + if(GetSystemDirectoryA(syspath, MAX_PATH) == 0) + { + return; + } + syspath_len = strlen(syspath); + + strcpy(syspath+syspath_len, "\\ddraw.dll"); + if(is_wrapper(syspath, FALSE)) + { + DeleteFileA(syspath); + } + + strcpy(syspath+syspath_len, "\\d3d8.dll"); + if(is_wrapper(syspath, FALSE)) + { + DeleteFileA(syspath); + } + + if(version_compare(&sysver, &WINVER98) >= 0) + { + strcpy(syspath+syspath_len, "\\d3d9.dll"); + if(is_wrapper(syspath, FALSE)) + { + removeROFlag(syspath); + DeleteFileA(syspath); + } + } +} + BOOL dx_start(HWND hwnd) { if(dx_path == NULL) @@ -359,6 +386,9 @@ BOOL dx_start(HWND hwnd) } install_infobox(hwnd, "MS DirectX"); + + delete_bad_dx_files(); + return install_run(dx_path, &pi_proc, &pi_thread, TRUE); } @@ -403,15 +433,189 @@ void setInstallSrc(const char *path) src_path = path; } +static void fix_ddraw(const char* file) +{ + const uint8_t search[] = { + 0x44, 0x44, 0x52, 0x41, 0x57, 0x31, 0x36, 0x2E, 0x44, 0x4C, 0x4C, 0x00, 0x44, 0x44, 0x52, 0x41, // ; DDRAW16.DLL.DDRA + 0x57, 0x2E, 0x44, 0x4C, 0x4C, 0x00 // ; W.DLL. + }; + const size_t replace_pos = 12; + const char defname[] = "ddraw.dll"; + const char dest[] = "ddsys.dll"; + int found = 0; + + FILE *fr = fopen(file, "rb"); + if(fr != NULL) + { + size_t fs = 0; + uint8_t *mem = NULL; + + fseek(fr, 0, SEEK_END); + fs = ftell(fr); + fseek(fr, 0, SEEK_SET); + + mem = (uint8_t*)malloc(fs); + if(mem != NULL) + { + if(fread(mem, 1, fs, fr) == fs) + { + fclose(fr); + fr = NULL; + + size_t i, j; + + for(i = 0; i < fs - sizeof(search); i++) + { + if(memcmp(mem+i, search, sizeof(search)) == 0) + { + for(j = 0; j < sizeof(defname)-1; j++) + { + mem[i+replace_pos+j] = toupper(dest[j]); + } + found++; + } + } + + if(found > 0) + { + FILE *fw = fopen(file, "wb"); + if(fw) + { + fwrite(mem, 1, fs, fw); + + fclose(fw); + } + } + } + + free(mem); + } + + if(fr != NULL) fclose(fr); + }; +} + static HANDLE filescopy_thread = 0; static int copiedfiles = 0; +void backup_sysfiles() +{ + char syspath[MAX_PATH]; + size_t syspath_len; + char inspath[MAX_PATH]; + size_t inspath_len; + + if(GetSystemDirectoryA(syspath, MAX_PATH) == 0) + { + return; + } + syspath_len = strlen(syspath); + strcpy(inspath, install_path); + inspath_len = strlen(inspath); + + /* create dirs */ + strcpy(inspath+inspath_len, "\\backup"); + mkdir_recrusive(inspath); + strcpy(inspath+inspath_len, "\\sys"); + mkdir_recrusive(inspath); + + /* ddraw.dll */ + strcpy(syspath+syspath_len, "\\ddraw.dll"); + if(!is_wrapper(syspath, TRUE)) + { + strcpy(inspath+inspath_len, "\\backup\\ddraw.dll"); + CopyFileA(syspath, inspath, FALSE); + + strcpy(inspath+inspath_len, "\\sys\\ddsys.dll"); + if(CopyFileA(syspath, inspath, FALSE)) + { + removeROFlag(inspath); + fix_ddraw(inspath); + install_settings.has_sys_ddraw = TRUE; + } + } + else + { + strcpy(syspath+syspath_len, "\\ddsys.dll"); + if(!is_wrapper(syspath, TRUE)) + { + strcpy(inspath+inspath_len, "\\sys\\ddsys.dll"); + if(CopyFileA(syspath, inspath, FALSE)) + { + removeROFlag(inspath); + fix_ddraw(inspath); + install_settings.has_sys_ddraw = TRUE; + } + } + } + + /* d3d8.dll */ + strcpy(syspath+syspath_len, "\\d3d8.dll"); + if(!is_wrapper(syspath, TRUE)) + { + strcpy(inspath+inspath_len, "\\backup\\d3d8.dll"); + CopyFileA(syspath, inspath, FALSE); + + strcpy(inspath+inspath_len, "\\sys\\msd3d8.dll"); + if(CopyFileA(syspath, inspath, FALSE)) + { + removeROFlag(inspath); + install_settings.has_sys_d3d8 = TRUE; + } + } + else + { + strcpy(syspath+syspath_len, "\\msd3d8.dll"); + if(!is_wrapper(syspath, TRUE)) + { + strcpy(inspath+inspath_len, "\\sys\\msd3d8.dll"); + if(CopyFileA(syspath, inspath, FALSE)) + { + removeROFlag(inspath); + install_settings.has_sys_d3d8 = TRUE; + } + } + } + + /* d3d9.dll */ + strcpy(syspath+syspath_len, "\\d3d9.dll"); + if(!is_wrapper(syspath, TRUE)) + { + strcpy(inspath+inspath_len, "\\backup\\d3d9.dll"); + CopyFileA(syspath, inspath, FALSE); + + strcpy(inspath+inspath_len, "\\sys\\msd3d9.dll"); + if(CopyFileA(syspath, inspath, FALSE)) + { + removeROFlag(inspath); + install_settings.has_sys_d3d9 = TRUE; + } + } + else + { + strcpy(syspath+syspath_len, "\\msd3d9.dll"); + if(!is_wrapper(syspath, TRUE)) + { + strcpy(inspath+inspath_len, "\\sys\\msd3d9.dll"); + if(CopyFileA(syspath, inspath, FALSE)) + { + removeROFlag(inspath); + install_settings.has_sys_d3d9 = TRUE; + } + } + } + + +} + DWORD WINAPI filescopy_proc(LPVOID lpParameter) { (void)lpParameter; copiedfiles = copydir(src_path, install_path); + backup_sysfiles(); + return 0; } @@ -471,24 +675,19 @@ BOOL filescopy_result(HWND hwnd) return TRUE; } -BOOL install_wine = FALSE; -BOOL install_glide = FALSE; -BOOL install_res_qxga = FALSE; -BOOL install_res_1440 = FALSE; -BOOL install_res_4k = FALSE; -BOOL install_res_5k = FALSE; +install_settings_t install_settings = {FALSE}; BOOL setLineSvga(char *buf, size_t bufs) { (void)bufs; strcpy(buf, "CopyFiles=VMSvga.Copy"); - if(install_wine) + if(install_settings.install_wine) { strcat(buf, ",Dx.Copy,DX.CopyBackup"); } - if(install_glide) + if(install_settings.install_glide) { strcat(buf, ",Voodoo.Copy"); } @@ -501,12 +700,12 @@ BOOL setLineVbox(char *buf, size_t bufs) (void)bufs; strcpy(buf, "CopyFiles=VBox.Copy"); - if(install_wine) + if(install_settings.install_wine) { strcat(buf, ",Dx.Copy,DX.CopyBackup"); } - if(install_glide) + if(install_settings.install_glide) { strcat(buf, ",Voodoo.Copy"); } @@ -519,12 +718,12 @@ BOOL setLineQemu(char *buf, size_t bufs) (void)bufs; strcpy(buf, "CopyFiles=Qemu.Copy"); - if(install_wine) + if(install_settings.install_wine) { strcat(buf, ",Dx.Copy,DX.CopyBackup"); } - if(install_glide) + if(install_settings.install_glide) { strcat(buf, ",Voodoo.Copy"); } @@ -538,22 +737,22 @@ BOOL setLineSvgaReg(char *buf, size_t bufs) strcpy(buf, "AddReg=VMSvga.AddReg,VM.AddReg"); - if(install_wine && version_compare(&sysver, &WINVERME) >= 0) + if(install_settings.install_wine && version_compare(&sysver, &WINVERME) >= 0) { /* these entries is only relevant to system, that cannot replace ddraw.dll */ strcat(buf, ",DX.addReg"); } - if(install_res_qxga) + if(install_settings.install_res_qxga) strcat(buf, ",VM.QXGA"); - if(install_res_1440) + if(install_settings.install_res_1440) strcat(buf, ",VM.WQHD"); - if(install_res_4k) + if(install_settings.install_res_4k) strcat(buf, ",VM.UHD"); - if(install_res_5k) + if(install_settings.install_res_5k) strcat(buf, ",VM.R5K"); return TRUE; @@ -564,19 +763,22 @@ BOOL setLineVboxReg(char *buf, size_t bufs) (void)bufs; strcpy(buf, "AddReg=VBox.AddReg,VM.AddReg"); - if(install_wine) + + if(install_settings.install_wine && version_compare(&sysver, &WINVERME) >= 0) + { strcat(buf, ",DX.addReg"); + } - if(install_res_qxga) + if(install_settings.install_res_qxga) strcat(buf, ",VM.QXGA"); - if(install_res_1440) + if(install_settings.install_res_1440) strcat(buf, ",VM.WQHD"); - if(install_res_4k) + if(install_settings.install_res_4k) strcat(buf, ",VM.UHD"); - if(install_res_5k) + if(install_settings.install_res_5k) strcat(buf, ",VM.R5K"); return TRUE; @@ -587,24 +789,154 @@ BOOL setLineQemuReg(char *buf, size_t bufs) (void)bufs; strcpy(buf, "AddReg=Qemu.AddReg,VM.AddReg"); - if(install_wine) + + if(install_settings.install_wine && version_compare(&sysver, &WINVERME) >= 0) + { strcat(buf, ",DX.addReg"); + } - if(install_res_qxga) + if(install_settings.install_res_qxga) strcat(buf, ",VM.QXGA"); - if(install_res_1440) + if(install_settings.install_res_1440) strcat(buf, ",VM.WQHD"); - if(install_res_4k) + if(install_settings.install_res_4k) strcat(buf, ",VM.UHD"); - if(install_res_5k) + if(install_settings.install_res_5k) strcat(buf, ",VM.R5K"); return TRUE; } +BOOL setLineMeFix(char *buf, size_t bufs) +{ + (void)bufs; + + if(version_compare(&sysver, &WINVERME) > 0 && + install_settings.install_wine) + { + size_t s_full = strlen(buf); + size_t s_prefix = sizeof(";mefix:") - 1; + size_t i; + + // memmove(buf, buf + s_prefix, s_full - s_prefix + 1); + for(i = 0; i < s_full - s_prefix + 1; i++) + { + buf[i] = buf[i + s_prefix]; + } + } + + return TRUE; +} + +BOOL setBug565(char *buf, size_t bufs) +{ + (void)bufs; + char *dst = strstr(buf, ",,"); + if(dst) + { + sprintf(dst+2, "%d", install_settings.bug_rgb565 ? 1 : 0); + return TRUE; + } + return FALSE; +} + +BOOL setBugPreferFifo(char *buf, size_t bufs) +{ + (void)bufs; + char *dst = strstr(buf, ",,"); + if(dst) + { + sprintf(dst+2, "%d", install_settings.bug_prefer_fifo ? 1 : 0); + return TRUE; + } + return FALSE; +} + +BOOL setBugDxFlags(char *buf, size_t bufs) +{ + (void)bufs; + char *dst = strstr(buf, ",,"); + if(dst) + { + sprintf(dst+2, "%d", install_settings.bug_dx_flags ? 1 : 0); + return TRUE; + } + return FALSE; +} + +BOOL setLimitGMR(char *buf, size_t bufs) +{ + (void)bufs; + char *dst = strstr(buf, ",,"); + if(dst) + { + sprintf(dst+2, "%d", install_settings.gmr_limit); + return TRUE; + } + return FALSE; +} + +BOOL setLimitVRAM(char *buf, size_t bufs) +{ + (void)bufs; + char *dst = strstr(buf, ",,"); + if(dst) + { + sprintf(dst+2, "%d", install_settings.vram_limit); + return TRUE; + } + return FALSE; +} + +BOOL setLineSyscopy(char *buf, size_t bufs) +{ + (void)bufs; + BOOL fix_line = FALSE; + + if(strstr(buf, "ddsys.dll") != NULL) + { + if(install_settings.has_sys_ddraw) + { + fix_line = TRUE; + } + } + + if(strstr(buf, "msd3d8.dll") != NULL) + { + if(install_settings.has_sys_d3d8) + { + fix_line = TRUE; + } + } + + if(strstr(buf, "msd3d9.dll") != NULL) + { + if(install_settings.has_sys_d3d9) + { + fix_line = TRUE; + } + } + + if(fix_line) + { + int line_start = sizeof(";syscopy:")-1; + int line_len = strlen(buf); + int i; + + for(i = 0; i < line_len - line_start + 1; i++) + { + buf[i] = buf[i + line_start]; + } + } + + return TRUE; +} + + + linerRule_t infFixRules[] = { {"CopyFiles=VBox.Copy,Dx.Copy,DX.CopyBackup,Voodoo.Copy", TRUE, TRUE, setLineVbox}, {"CopyFiles=VMSvga.Copy,Dx.Copy,DX.CopyBackup,Voodoo.Copy", TRUE, TRUE, setLineSvga}, @@ -612,6 +944,13 @@ linerRule_t infFixRules[] = { {"AddReg=VBox.AddReg,VM.AddReg,DX.addReg", TRUE, TRUE, setLineVboxReg}, {"AddReg=VMSvga.AddReg,VM.AddReg,DX.addReg", TRUE, TRUE, setLineSvgaReg}, {"AddReg=Qemu.AddReg,VM.AddReg,DX.addReg", TRUE, TRUE, setLineQemuReg}, + {"HKLM,Software\\VMWSVGA,RGB565bug,,0", TRUE, TRUE, setBug565}, + {"HKLM,Software\\VMWSVGA,PreferFIFO,,0", TRUE, TRUE, setBugPreferFifo}, + {"HKLM,Software\\Mesa3D\\global,SVGA_CLEAR_DX_FLAGS,,1", TRUE, TRUE, setBugDxFlags}, + {"HKLM,Software\\Mesa3D\\global,SVGA_GMR_LIMIT,,128", TRUE, TRUE, setLimitGMR}, + {"HKLM,Software\\VMWSVGA,VRAMLimit,,128", TRUE, TRUE, setLimitVRAM}, + {";mefix:", FALSE, TRUE, setLineMeFix}, + {";syscopy:", FALSE, TRUE, setLineSyscopy}, {NULL, FALSE, FALSE, NULL} }; @@ -668,6 +1007,28 @@ BOOL simd95(HWND hwnd) return TRUE; } +BOOL winenine(HWND hwnd) +{ + (void)hwnd; + + if(install_settings.dd_set_system) + registryWrite("HKLM\\Software\\DDSwitcher\\global", "system", WINREG_STR); + else + registryWrite("HKLM\\Software\\DDSwitcher\\global", "wine", WINREG_STR); + + if(install_settings.d8_set_nine) + registryWrite("HKLM\\Software\\D8Switcher\\global", "ninemore", WINREG_STR); + else + registryWrite("HKLM\\Software\\D8Switcher\\global", "wine", WINREG_STR); + + if(install_settings.d9_set_nine) + registryWrite("HKLM\\Software\\D9Switcher\\global", "nine", WINREG_STR); + else + registryWrite("HKLM\\Software\\D9Switcher\\global", "wine", WINREG_STR); + + return TRUE; +} + BOOL apply_reg_fixes(HWND hwnd) { const char *line = NULL; @@ -675,6 +1036,11 @@ BOOL apply_reg_fixes(HWND hwnd) int index = 0; (void)hwnd; + if(version_compare(&sysver, &WINVERME) < 0) + { + registryDelete("HKLM\\System\\CurrentControlSet\\Control\\SessionManager\\KnownDLLs\\DDRAW"); + } + for(; (line = iniLine("[fixes]", index)) != NULL; index++) { const char *p = strchr(line, ';'); @@ -692,6 +1058,12 @@ BOOL apply_reg_fixes(HWND hwnd) registryWrite(buf, p, WINREG_DWORD); } } + else if(strstr(p, ";DELETE") == p) + { + memcpy(buf, line, p-line); + buf[p-line] = '\0'; + registryDelete(buf); + } else { memcpy(buf, line, p-line); diff --git a/actions.h b/actions.h index 6c38d3f..b8e5bc6 100644 --- a/actions.h +++ b/actions.h @@ -68,18 +68,36 @@ BOOL filescopy_start(HWND hwnd); BOOL filescopy_wait(HWND hwnd); BOOL filescopy_result(HWND hwnd); -extern BOOL install_wine; -extern BOOL install_glide; -extern BOOL install_res_qxga; -extern BOOL install_res_1440; -extern BOOL install_res_4k; -extern BOOL install_res_5k; +typedef struct _install_settings_t +{ + BOOL install_wine; + BOOL install_glide; + BOOL install_res_qxga; + BOOL install_res_1440; + BOOL install_res_4k; + BOOL install_res_5k; + BOOL bug_rgb565; + BOOL bug_prefer_fifo; + BOOL bug_dx_flags; + BOOL dd_set_system; + BOOL d8_set_nine; + BOOL d9_set_nine; + int vram_limit; + int gmr_limit; + BOOL has_sys_ddraw; + BOOL has_sys_d3d8; + BOOL has_sys_d3d9; +} install_settings_t; + +extern install_settings_t install_settings; BOOL simd95(HWND hwnd); BOOL infFixer(HWND hwnd); BOOL apply_reg_fixes(HWND hwnd); +BOOL winenine(HWND hwnd); + void setDXpath(const char *dx); void setIEpath(const char *ie); diff --git a/changelog.txt b/changelog.txt index 2c7d6a6..85f8c57 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,23 @@ +0.5.2024.24 +! fixed the most of mouse cursor bugs +! limited RAM memory usage +! fixed some setup GUI bugs (introduced in 0.4.2023.18) +- vGPU10 finaly works +- DirectDraw HAL (2D only) +- Driver: reduced usage of 16bit RING-3 code (increase stability and speed) +- Driver: command buffers disabled for vGPU9 deviced (FIFO usage looks stable and faster) +- Wine: replaced window proc daisy chain with hooks (increase compatibility by a lot) +- Wine: report no shader support for vGPU9 devices (they didn't work anyway) +- Wine: DX 8 + D9 implementation switcher +- Wine: DLL version is set to 4.9.0.904 +- OpenGlide: fixed multi-thread rendering +- Mesa: optimized driver +- Mesa: various rendering fixes +- Mesa: Nine support (experimental) +- Mesa: 8-to-9 wrapper for Nine (experimental) +- Mesa: vGPU10 - OpenGL version 3.3 +- QEMU: QEMU-3Dfx OpenGL ICD driver + 0.4.2023.19 ! fixed GPUs without CB (VBox <= 6.1) ! fixed GMR allocation pool (introduced in 0.4.2023.13) diff --git a/filecopy.h b/filecopy.h index d46361a..ea66141 100644 --- a/filecopy.h +++ b/filecopy.h @@ -28,5 +28,7 @@ void removeROFlag(const char *path); int copydir(const char *from, const char *to); +BOOL is_dir(const char *path); +BOOL mkdir_recrusive(const char *path); #endif /* __FILECOPY_H__INCLUDED__ */ diff --git a/resource/softgpu-se.ico b/resource/softgpu-se.ico new file mode 100644 index 0000000000000000000000000000000000000000..5d8023643b8258347835bad44a04f81b7f4fe967 GIT binary patch literal 1078 zcmb_bF>-@25L}zgpivR~2d2vKi{w|(Ssm*5f@@x(r?^a+4k{~qI)Mp^Gn1JdtnT(s zI!VU??65~w9RWPyeGk0QIv$nRJK(thYWgbTjo5Ks63(4PW(!mtz!%P`;z$!A1ZoMy z^dd&F2tMMH;k%Ud$JqEB>0_gk9X(@7GB;f_3U6IrV0=&N=k@fGw>h{~#;?QyCgqZR z6s9m^I!ziz@5t{N9`Rv-C6MD{6PJZwtUSZa0pWPeIrU3?%Qx#&_Emn_d%ZvOJj?l( z3;lebdwn#nrP2DZVEi15us$%W_(YEG?l=oySKQ%-B2H|D58x~iTYNE`VgOEDaUe>f z_zwi;xf0x~;9g}7?c<7i?sG?b7U^+;iUV7laH=@c{9B)wEQd6s>60@~Cub}XTnh@6m&sier>6KTY4gTl6^sjJ?2hRHh DcupdX literal 0 HcmV?d00001 diff --git a/resource/softgpu.rc b/resource/softgpu.rc index 6512540..15ef371 100644 --- a/resource/softgpu.rc +++ b/resource/softgpu.rc @@ -31,7 +31,11 @@ #include "../softgpuver.h" //CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST softgpu.xml +#ifndef EXTRA_ICO SOFTGPU_ICON1 ICON "softgpu.ico" +#else +SOFTGPU_ICON1 ICON SOFTGPU_STR(EXTRA_ICO) +#endif 1 VERSIONINFO FILEVERSION SOFTGPU_VERSION_NUM diff --git a/settings.c b/settings.c new file mode 100644 index 0000000..c8763d7 --- /dev/null +++ b/settings.c @@ -0,0 +1,174 @@ +/****************************************************************************** + * Copyright (c) 2024 Jaroslav Hensl * + * * + * Permission is hereby granted, free of charge, to any person * + * obtaining a copy of this software and associated documentation * + * files (the "Software"), to deal in the Software without * + * restriction, including without limitation the rights to use, * + * copy, modify, merge, publish, distribute, sublicense, and/or sell * + * copies of the Software, and to permit persons to whom the * + * Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be * + * included in all copies or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * + * OTHER DEALINGS IN THE SOFTWARE. * + * * +*******************************************************************************/ +#include +#include +#include +#include +#include + +#include "softgpu.h" + +#include "nocrt.h" + +#define VRAM_DEF 128 +#define GMR_DEF 0 + +#define DEFAULT_INST_PATH "C:\\drivers\\softgpu" + +static DWORD settings_data = 0; +static DWORD settings_vram = VRAM_DEF; +static DWORD settings_gmr = GMR_DEF; + +typedef struct _settings_item_t +{ + DWORD menu; + DWORD pos; + BOOL negate; +} settings_item_t; + +const settings_item_t settings[] = +{ + {CHBX_MSCRT, 0, FALSE}, + {CHBX_DX, 1, FALSE}, + {RAD_NORMAL, 2, FALSE}, + {CHBX_WINE, 3, FALSE}, + {CHBX_GLIDE, 4, FALSE}, + {CHBX_SIMD95, 5, TRUE}, + {CHBX_FIXES, 6, FALSE}, + {BTN_ABOUT, 7, FALSE}, + {CHBX_GL95, 8, FALSE}, + {CHBX_QXGA, 9, TRUE}, + {CHBX_1440, 10, TRUE}, + {CHBX_4K, 11, TRUE}, + {CHBX_5K, 12, TRUE}, + {RAD_DD_HAL, 13, TRUE}, + {RAD_D8_NINE, 14, TRUE}, + {RAD_D9_NINE, 15, TRUE}, + {CHBX_BUG_PREFER_FIFO, 16, FALSE}, + {CHBX_BUG_RGB565, 17, FALSE}, + {CHBX_BUG_DX_FLAGS, 18, FALSE}, + {0, 0, FALSE} +}; + +void settingsReset() +{ + settings_data = 0; + settings_vram = VRAM_DEF; + settings_gmr = GMR_DEF; +} + +BOOL isSettingSet(DWORD menu) +{ + const settings_item_t *s; + for(s = &settings[0]; s->menu != 0; s++) + { + if(s->menu == menu) + { + DWORD p = ((settings_data) >> s->pos) & 0x1; + if(s->negate) + { + p = (~p) & 0x1; + } + + if(p == 0) + { + return TRUE; + } + else + { + return FALSE; + } + } + } + + return FALSE; +} + +void writeSettings(HWND hwnd) +{ + const settings_item_t *s; + + DWORD new_data = 0; + + for(s = &settings[0]; s->menu != 0; s++) + { + BOOL b = IsDlgButtonChecked(hwnd, s->menu); + if(s->negate) b = !b; + + if(!b) + { + new_data |= 1 << s->pos; + } + } + + registryWriteDWORD("HKCU\\SOFTWARE\\SoftGPU\\setup_" SOFTGPU_STR(SOFTGPU_BUILD), new_data); + + registryWriteDWORD("HKCU\\SOFTWARE\\SoftGPU\\setup_vram_" SOFTGPU_STR(SOFTGPU_BUILD), GetInputInt(hwnd, INP_VRAM_LIMIT)); + registryWriteDWORD("HKCU\\SOFTWARE\\SoftGPU\\setup_gmr_" SOFTGPU_STR(SOFTGPU_BUILD), GetInputInt(hwnd, INP_GMR_LIMIT)); + +} + +void readSettings() +{ + registryReadDWORD("HKCU\\SOFTWARE\\SoftGPU\\setup_" SOFTGPU_STR(SOFTGPU_BUILD), &settings_data); + + DWORD t = 0; + registryReadDWORD("HKCU\\SOFTWARE\\SoftGPU\\setup_vram_" SOFTGPU_STR(SOFTGPU_BUILD), &t); + if(t != 0) + t = settings_vram; + + t = 0; + registryReadDWORD("HKCU\\SOFTWARE\\SoftGPU\\setup_gmr_" SOFTGPU_STR(SOFTGPU_BUILD), &settings_gmr); + if(t != 0) + t = settings_gmr; +} + +int intSettings(int type) +{ + switch(type) + { + case SETTINGS_VRAM: + return settings_vram; + break; + case SETTINGS_GMR: + if(settings_gmr == 0) + { + MEMORYSTATUS status; + status.dwLength = sizeof(status); + GlobalMemoryStatus(&status); + + if(status.dwTotalPhys > 700 * 1024 * 1024) + settings_gmr = 256; + else + settings_gmr = 128; + } + + return settings_gmr; + break; + } + + return 0; +} diff --git a/softgpu.c b/softgpu.c index 0e34e59..f582596 100644 --- a/softgpu.c +++ b/softgpu.c @@ -29,15 +29,7 @@ #include #include -#include "winini.h" -#include "actions.h" - -#include "windrv.h" -#include "winreg.h" - -#include "actions.h" -#include "setuperr.h" -#include "softgpuver.h" +#include "softgpu.h" #include "nocrt.h" @@ -83,140 +75,116 @@ void about(HWND hwnd) MessageBoxA(hwnd, txtbuf, "About SoftGPU", MB_OK); } -#define WND_SOFTGPU_CLASS_NAME "SoftGPUCLS" -#define WND_SOFTGPU_LOAD_CLASS_NAME "SoftGPULDCLS" - -#define CHBX_MSCRT 1 -#define CHBX_DX 2 -#define INP_PATH 3 -#define BTN_BROWSE 4 -#define RAD_NORMAL 5 -#define RAD_SSE 6 -#define CHBX_WINE 7 -#define CHBX_GLIDE 8 -#define CHBX_SIMD95 9 -#define CHBX_FIXES 10 -//#define CHBX_IE 11 - -#define BTN_EXIT 11 -#define BTN_INSTALL 12 -#define CHBX_GL95 13 -#define BTN_ABOUT 14 - -#define CHBX_QXGA 15 -#define CHBX_1440 16 -#define CHBX_4K 17 -#define CHBX_5K 18 - -#define CHBX_NO_INSTALL 19 - -static float rdpiX = 1.0; -static float rdpiY = 1.0; - -typedef struct _settings_item_t +void sysinfo(HWND hwnd) { - DWORD menu; - DWORD pos; - BOOL negate; -} settings_item_t; + MessageBoxA(hwnd, sysinfomsg, "System informations", MB_OK); +} -const settings_item_t settings[] = +void runprog(const char *exe_name) { - {CHBX_MSCRT, 0, FALSE}, - {CHBX_DX, 1, FALSE}, - {RAD_NORMAL, 2, FALSE}, - {CHBX_WINE, 3, FALSE}, - {CHBX_GLIDE, 4, FALSE}, - {CHBX_SIMD95, 5, FALSE}, - {CHBX_FIXES, 6, FALSE}, - {BTN_ABOUT, 7, FALSE}, - {CHBX_GL95, 8, FALSE}, - {CHBX_QXGA, 9, TRUE}, - {CHBX_1440, 10, TRUE}, - {CHBX_4K, 11, TRUE}, - {CHBX_5K, 12, TRUE}, - {0, 0, FALSE} -}; - -DWORD settings_data = 0; + STARTUPINFO si; + PROCESS_INFORMATION pi; + char dirname_buf[MAX_PATH]; + char *dirname = NULL; + char *basename = strrchr(exe_name, '\\'); + + if(basename != NULL) + { + DWORD s2 = basename-exe_name; + DWORD s = GetCurrentDirectory(MAX_PATH, dirname_buf); + dirname_buf[s] = '\\'; + + memcpy(&dirname_buf[s+1], exe_name, s2); + dirname_buf[s+s2+1] = '\0'; + } -#define DPIX(_spx) ((int)(ceil((_spx)*rdpiX))) -#define DPIY(_spx) ((int)(ceil((_spx)*rdpiY))) + memset(&si, 0, sizeof(si)); + si.cb = sizeof(si); + memset(&pi, 0, sizeof(pi)); + + CreateProcessA(exe_name, + NULL, + NULL, + NULL, + FALSE, + 0, + NULL, + dirname, + &si, + &pi); + + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); +} -#define DEFAULT_INST_PATH "C:\\drivers\\softgpu" +#define WND_SOFTGPU_CLASS_NAME "SoftGPUCLS" +#define WND_SOFTGPU_LOAD_CLASS_NAME "SoftGPULDCLS" -#define DRAW_START_X 16 -#define DRAW_START_Y 10 -#define LINE_HEIGHT 20 -#define LINE_HL 10 -#define LINE_WIDTH 250 -#define LINE_QWIDTH 80 +float rdpiX = 1.0; +float rdpiY = 1.0; -#define LINE_WIDTH2 350 +BOOL isNT = FALSE; +version_t sysver = {0}; +version_t dxver = {0}; +BOOL hasCRT = FALSE; +BOOL hasSETUPAPI = FALSE; +uint32_t hasSSE3 = 0; +uint32_t hasSSE42 = 0; +uint32_t hasAVX = 0; +BOOL hasOpengl = FALSE; -version_t WINVER95 = {4,0,0,0}; -version_t WINVER98 = {4,10,0,0}; -version_t WINVER98SE = {4,10,2222,0}; -version_t WINVERME = {4,90,0,0}; -version_t WINVER2K = {5,0,0,0}; +BOOL reinstall_dx = FALSE; -static BOOL isNT = FALSE; -version_t sysver = {0}; -static version_t dxver = {0}; -static BOOL hasCRT = FALSE; -static BOOL hasSETUPAPI = FALSE; -static uint32_t hasSSE = 0; -static uint32_t hasAVX = 0; -static BOOL hasOpengl = FALSE; static DWORD drvPCstatus = CHECK_DRV_OK; -static char sysinfomsg[1024]; +char sysinfomsg[1024]; + -static BOOL isSettingSet(DWORD menu) +BOOL checkDXReinstall() { - const settings_item_t *s; - for(s = &settings[0]; s->menu != 0; s++) + char syspath[MAX_PATH]; + size_t syspath_len; + + if(GetSystemDirectoryA(syspath, MAX_PATH) == 0) + { + return FALSE; + } + syspath_len = strlen(syspath); + + strcat(syspath, "\\ddraw.dll"); + if(is_wrapper(syspath, FALSE)) { - if(s->menu == menu) + strcpy(syspath+syspath_len, "\\ddsys.dll"); + if(is_wrapper(syspath, TRUE)) { - DWORD p = ((settings_data) >> s->pos) & 0x1; - if(s->negate) - { - p = (~p) & 0x1; - } - - if(p == 0) - { - return TRUE; - } - else - { - return FALSE; - } + return TRUE; } } - return FALSE; -} - -static void writeSettings(HWND hwnd) -{ - const settings_item_t *s; - - DWORD new_data = 0; + strcpy(syspath+syspath_len, "\\d3d8.dll"); + if(is_wrapper(syspath, FALSE)) + { + strcpy(syspath+syspath_len, "\\msd3d8.dll"); + if(is_wrapper(syspath, TRUE)) + { + return TRUE; + } + } - for(s = &settings[0]; s->menu != 0; s++) + if(version_compare(&sysver, &WINVER98) >= 0) { - BOOL b = IsDlgButtonChecked(hwnd, s->menu); - if(s->negate) b = !b; - - if(!b) + strcpy(syspath+syspath_len, "\\d3d9.dll"); + if(is_wrapper(syspath, FALSE)) { - new_data |= 1 << s->pos; + strcpy(syspath+syspath_len, "\\msd3d9.dll"); + if(is_wrapper(syspath, TRUE)) + { + return TRUE; + } } } - registryWriteDWORD("HKCU\\SOFTWARE\\SoftGPU\\setup", new_data); + return FALSE; } void readCPUInfo() @@ -250,24 +218,29 @@ void readCPUInfo() { __asm( "pusha\n" + "movl $0, %0\n" + "movl $0, %1\n" "xorl %%eax, %%eax\n" "cpuid\n" "cmpl $1, %%eax\n" // does CPUID support eax = 1? - "jb not_supported_sse\n" + "jb end_sse\n" "movl $1, %%eax\n" "cpuid\n" "andl $0x06000000, %%edx\n" // check 25 and 26 - SSE and SSE2 "cmpl $0x06000000, %%edx\n" - "jne not_supported_sse\n" - "andl $0x00180001, %%ecx\n" // check 0, 19, 20 - SSE3 and SSE4.1 SSE4.2 - "cmpl $0x00180001, %%ecx\n" - "jne not_supported_sse\n" + "jne end_sse\n" + "mov %%ecx, %%eax\n" + "andl $0x00000001, %%eax\n" // check 0 - SSE3 + "cmpl $0x00000001, %%eax\n" + "jne end_sse\n" // SSE1, SSE2, SSE3 "movl $1, %0\n" + "andl $0x00180000, %%ecx\n" // check 19, 20 - SSE3 and SSE4.1 SSE4.2 + "cmpl $0x00180000, %%ecx\n" + "jne end_sse\n" // SSE4.1, SSE4.2 + "movl $1, %1\n" "jmp end_sse\n" - "not_supported_sse:\n" - "movl $0, %0\n" "end_sse:\n" - "popa" : "=m" (hasSSE)); + "popa" : "=m" (hasSSE3), "=m" (hasSSE42)); } else { @@ -292,7 +265,7 @@ void readCPUInfo() "not_supported_sse95:\n" "movl $0, %0\n" "end_sse95:\n" - "popa" : "=m" (hasSSE)); + "popa" : "=m" (hasSSE3)); } } @@ -325,10 +298,9 @@ void softgpu_sysinfo() readCPUInfo(); - //hasSSE2 = __builtin_cpu_supports("sse2") > 0; - //hasAVX = __builtin_cpu_supports("avx") > 0; - - sprintf(sysinfomsg, "System informations:\n" + reinstall_dx = checkDXReinstall(); + + sprintf(sysinfomsg, "System version: %d.%d.%d.%d\n" "Core type: %s\n" "DX version: %d.%d.%d.%d\n" @@ -343,15 +315,15 @@ void softgpu_sysinfo() hasCRT ? "yes" : "no", hasSETUPAPI ? "yes" : "no", hasOpengl ? "yes" : "no", - hasSSE ? "yes" : "no", + hasSSE42 ? "4.2" : (hasSSE3 ? "3" : "no"), hasAVX ? "yes" : "no" ); } -static HWND infobox = INVALID_HANDLE_VALUE; -static HWND installbtn = INVALID_HANDLE_VALUE; -static HWND pathinput = INVALID_HANDLE_VALUE; +HWND infobox = INVALID_HANDLE_VALUE; +HWND installbtn = INVALID_HANDLE_VALUE; +HWND pathinput = INVALID_HANDLE_VALUE; static BOOL need_reboot = FALSE; @@ -435,266 +407,28 @@ void softgpu_browse(HWND hwnd) } } -LRESULT CALLBACK softgpuWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +int GetInputInt(HWND hwnd, int id) { - static char dxname[250]; + HWND el = GetDlgItem(hwnd, id); + if(el) + { + char inp[64]; + if(GetWindowTextA(el, inp, 64) != 0) + { + return strtol(inp, NULL, 0); + } + } + return 0; +} + +LRESULT CALLBACK softgpuWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ switch(msg) { case WM_CREATE: { - version_t dxtarget; - DWORD sty; - - if(version_compare(&sysver, &WINVER98) >= 0) - { - version_parse(iniValue("[softgpu]", "dx9target"), &dxtarget); - strcpy(dxname, "Install DirectX 9"); - } - else - { - version_parse(iniValue("[softgpu]", "dx8target"), &dxtarget); - strcpy(dxname, "Install DirectX 8"); - } - - /*CreateWindowA("BUTTON", iename, - WS_VISIBLE | WS_CHILD | BS_AUTOCHECKBOX, - DPIX(DRAW_START_X), DPIY(DRAW_START_Y + 0*LINE_HEIGHT), DPIX(LINE_WIDTH), DPIY(LINE_HEIGHT), - hwnd, (HMENU)CHBX_IE, ((LPCREATESTRUCT)lParam)->hInstance, NULL); - if(!hasSETUPAPI) - { - CheckDlgButton(hwnd, CHBX_IE, BST_CHECKED); - }*/ - - HWND btnGL = CreateWindowA("BUTTON", "Install OpenGL 95", - WS_VISIBLE | WS_CHILD | BS_AUTOCHECKBOX, - DPIX(DRAW_START_X), DPIY(DRAW_START_Y + 0*LINE_HEIGHT), DPIX(LINE_WIDTH), DPIY(LINE_HEIGHT), - hwnd, (HMENU)CHBX_GL95, ((LPCREATESTRUCT)lParam)->hInstance, NULL); - if(version_compare(&sysver, &WINVER98) < 0) - { - if(!hasOpengl) - { - if(isSettingSet(CHBX_GL95)) - { - CheckDlgButton(hwnd, CHBX_GL95, BST_CHECKED); - } - } - } - else - { - sty = GetWindowLongA(btnGL, GWL_STYLE) | WS_DISABLED; - SetWindowLongA(btnGL, GWL_STYLE, sty); - } - - CreateWindowA("BUTTON", "Install MSVCRT", - WS_VISIBLE | WS_CHILD | BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP, - DPIX(DRAW_START_X), DPIY(DRAW_START_Y + 1*LINE_HEIGHT), DPIX(LINE_WIDTH), DPIY(LINE_HEIGHT), - hwnd, (HMENU)CHBX_MSCRT, ((LPCREATESTRUCT)lParam)->hInstance, NULL); - if(!hasCRT) - { - if(isSettingSet(CHBX_MSCRT)) - { - CheckDlgButton(hwnd, CHBX_MSCRT, BST_CHECKED); - } - } - - /* directx checkbox */ - CreateWindowA("BUTTON", dxname, - WS_VISIBLE | WS_CHILD | BS_AUTOCHECKBOX, - DPIX(DRAW_START_X), DPIY(DRAW_START_Y + 2*LINE_HEIGHT), DPIX(LINE_WIDTH), DPIY(LINE_HEIGHT), - hwnd, (HMENU)CHBX_DX, ((LPCREATESTRUCT)lParam)->hInstance, NULL); - if(version_compare(&dxver, &dxtarget) < 0) - { - if(isSettingSet(CHBX_DX)) - { - CheckDlgButton(hwnd, CHBX_DX, BST_CHECKED); - } - } - - /* SSE/non SSE instalation type */ - CreateWindowA("BUTTON", "Install classical binaries", - WS_VISIBLE | WS_CHILD | BS_AUTORADIOBUTTON | WS_GROUP, - DPIX(DRAW_START_X), DPIY(DRAW_START_Y + LINE_HL + 3*LINE_HEIGHT), DPIX(LINE_WIDTH), DPIY(LINE_HEIGHT), - hwnd, (HMENU)RAD_NORMAL, ((LPCREATESTRUCT)lParam)->hInstance, NULL); - - CreateWindowA("BUTTON", "Install SSE instrumented binaries", - WS_VISIBLE | WS_CHILD | BS_AUTORADIOBUTTON, - DPIX(DRAW_START_X), DPIY(DRAW_START_Y + LINE_HL + 4*LINE_HEIGHT), DPIX(LINE_WIDTH), DPIY(LINE_HEIGHT), - hwnd, (HMENU)RAD_SSE, ((LPCREATESTRUCT)lParam)->hInstance, NULL); - - if(version_compare(&sysver, &WINVER98) >= 0 && hasSSE) - { - CheckDlgButton(hwnd, RAD_SSE, BST_CHECKED); - } - else - { - CheckDlgButton(hwnd, RAD_NORMAL, BST_CHECKED); - } - - CreateWindowA("BUTTON", "Install DirectX wrapper (Wine9x)", - WS_VISIBLE | WS_CHILD | BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP, - DPIX(DRAW_START_X), DPIY(DRAW_START_Y + LINE_HL + 5*LINE_HEIGHT), DPIX(LINE_WIDTH), DPIY(LINE_HEIGHT), - hwnd, (HMENU)CHBX_WINE, ((LPCREATESTRUCT)lParam)->hInstance, NULL); - if(isSettingSet(CHBX_WINE)) - { - CheckDlgButton(hwnd, CHBX_WINE, BST_CHECKED); - } - - CreateWindowA("BUTTON", "Install Glide wrapper (OpenGlide9x)", - WS_VISIBLE | WS_CHILD | BS_AUTOCHECKBOX, - DPIX(DRAW_START_X), DPIY(DRAW_START_Y + LINE_HL + 6*LINE_HEIGHT), DPIX(LINE_WIDTH), DPIY(LINE_HEIGHT), - hwnd, (HMENU)CHBX_GLIDE, ((LPCREATESTRUCT)lParam)->hInstance, NULL); - if(isSettingSet(CHBX_GLIDE)) - { - CheckDlgButton(hwnd, CHBX_GLIDE, BST_CHECKED); - } - - HWND btnSIMD95 = CreateWindowA("BUTTON", "Enable SSE/AVX hack", - WS_VISIBLE | WS_CHILD | BS_AUTOCHECKBOX, - DPIX(DRAW_START_X), DPIY(DRAW_START_Y + LINE_HL + 7*LINE_HEIGHT), DPIX(LINE_WIDTH), DPIY(LINE_HEIGHT), - hwnd, (HMENU)CHBX_SIMD95, ((LPCREATESTRUCT)lParam)->hInstance, NULL); - if(version_compare(&sysver, &WINVERME) < 0) - { -#if 0 - if(!hasAVX) - { - if(isSettingSet(CHBX_SIMD95)) - { - CheckDlgButton(hwnd, CHBX_SIMD95, BST_CHECKED); - } - } -#endif - } - else - { - sty = GetWindowLongA(btnSIMD95, GWL_STYLE) | WS_DISABLED; - SetWindowLongA(btnSIMD95, GWL_STYLE, sty); - } - - CreateWindowA("BUTTON", "Apply compatibility enhacements", - WS_VISIBLE | WS_CHILD | BS_AUTOCHECKBOX, - DPIX(DRAW_START_X), DPIY(DRAW_START_Y + LINE_HL + 8*LINE_HEIGHT), DPIX(LINE_WIDTH), DPIY(LINE_HEIGHT), - hwnd, (HMENU)CHBX_FIXES, ((LPCREATESTRUCT)lParam)->hInstance, NULL); - if(isSettingSet(CHBX_FIXES)) - { - CheckDlgButton(hwnd, CHBX_FIXES, BST_CHECKED); - } - - CreateWindowA("STATIC", "Resolutions > FullHD:", - WS_VISIBLE | WS_CHILD | SS_LEFT, - DPIX(DRAW_START_X), DPIY(DRAW_START_Y + 10*LINE_HEIGHT), DPIX(LINE_QWIDTH*2), DPIY(LINE_HEIGHT), - hwnd, (HMENU)0, ((LPCREATESTRUCT)lParam)->hInstance, NULL); - - CreateWindowA("BUTTON", "QXGA", - WS_VISIBLE | WS_CHILD | BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP, - DPIX(DRAW_START_X+2*LINE_QWIDTH), DPIY(DRAW_START_Y + 10*LINE_HEIGHT), DPIX(LINE_QWIDTH), DPIY(LINE_HEIGHT), - hwnd, (HMENU)CHBX_QXGA, ((LPCREATESTRUCT)lParam)->hInstance, NULL); - if(isSettingSet(CHBX_QXGA)) - { - CheckDlgButton(hwnd, CHBX_QXGA, BST_CHECKED); - } - - CreateWindowA("BUTTON", "1440p", - WS_VISIBLE | WS_CHILD | BS_AUTOCHECKBOX, - DPIX(DRAW_START_X+3*LINE_QWIDTH), DPIY(DRAW_START_Y + 10*LINE_HEIGHT), DPIX(LINE_QWIDTH), DPIY(LINE_HEIGHT), - hwnd, (HMENU)CHBX_1440, ((LPCREATESTRUCT)lParam)->hInstance, NULL); - if(isSettingSet(CHBX_1440)) - { - CheckDlgButton(hwnd, CHBX_1440, BST_CHECKED); - } - - CreateWindowA("BUTTON", "4K", - WS_VISIBLE | WS_CHILD | BS_AUTOCHECKBOX, - DPIX(DRAW_START_X+4*LINE_QWIDTH), DPIY(DRAW_START_Y + 10*LINE_HEIGHT), DPIX(LINE_QWIDTH), DPIY(LINE_HEIGHT), - hwnd, (HMENU)CHBX_4K, ((LPCREATESTRUCT)lParam)->hInstance, NULL); - if(isSettingSet(CHBX_4K)) - { - CheckDlgButton(hwnd, CHBX_4K, BST_CHECKED); - } - - CreateWindowA("BUTTON", "5K", - WS_VISIBLE | WS_CHILD | BS_AUTOCHECKBOX, - DPIX(DRAW_START_X+5*LINE_QWIDTH), DPIY(DRAW_START_Y + 10*LINE_HEIGHT), DPIX(LINE_QWIDTH), DPIY(LINE_HEIGHT), - hwnd, (HMENU)CHBX_5K, ((LPCREATESTRUCT)lParam)->hInstance, NULL); - if(isSettingSet(CHBX_5K)) - { - CheckDlgButton(hwnd, CHBX_5K, BST_CHECKED); - } - - CreateWindowA("STATIC", "Install path:", - WS_VISIBLE | WS_CHILD | SS_LEFT | WS_GROUP, - DPIX(DRAW_START_X), DPIY(DRAW_START_Y + 12*LINE_HEIGHT), DPIX(LINE_WIDTH), DPIY(LINE_HEIGHT), - hwnd, (HMENU)0, ((LPCREATESTRUCT)lParam)->hInstance, NULL); - - pathinput = CreateWindowA("EDIT", iniValue("[softgpu]", "defpath"), - WS_VISIBLE | WS_CHILD | ES_LEFT | WS_BORDER | WS_GROUP | WS_TABSTOP, - DPIX(DRAW_START_X), DPIY(DRAW_START_Y + 13*LINE_HEIGHT), DPIX(LINE_WIDTH2), DPIY(LINE_HEIGHT), - hwnd, (HMENU)INP_PATH, ((LPCREATESTRUCT)lParam)->hInstance, NULL); - - CreateWindowA("BUTTON", "Browse", - WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON | WS_GROUP, - DPIX(DRAW_START_X+LINE_WIDTH2+10), DPIY(DRAW_START_Y + 13*LINE_HEIGHT), DPIX(80), DPIY(LINE_HEIGHT), - hwnd, (HMENU)BTN_BROWSE, ((LPCREATESTRUCT)lParam)->hInstance, NULL); - - CreateWindowA("BUTTON", "Exit", - WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON | WS_GROUP | WS_TABSTOP, - DPIX(DRAW_START_X), DPIY(DRAW_START_Y + LINE_HL + 14*LINE_HEIGHT), DPIX(80), DPIY(LINE_HEIGHT), - hwnd, (HMENU)BTN_EXIT, ((LPCREATESTRUCT)lParam)->hInstance, NULL); - - if(!isNT) - { - installbtn = CreateWindowA("BUTTON", "Install!", - WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP, - DPIX(DRAW_START_X+LINE_WIDTH2+10), DPIY(DRAW_START_Y + LINE_HL + 14*LINE_HEIGHT), DPIX(80), DPIY(LINE_HEIGHT), - hwnd, (HMENU)BTN_INSTALL, ((LPCREATESTRUCT)lParam)->hInstance, NULL); - SetFocus(installbtn); - } - else - { - CreateWindowA("BUTTON", "Install!", - WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON | WS_DISABLED, - DPIX(DRAW_START_X+LINE_WIDTH2+10), DPIY(DRAW_START_Y + LINE_HL + 14*LINE_HEIGHT), DPIX(80), DPIY(LINE_HEIGHT), - hwnd, (HMENU)0, ((LPCREATESTRUCT)lParam)->hInstance, NULL); - } - -#ifdef EXTRA_INFO - CreateWindowA("STATIC", EXTRA_INFO, - WS_VISIBLE | WS_CHILD | SS_RIGHT | WS_DISABLED, - DPIX(DRAW_START_X+LINE_WIDTH+10), DPIY(DRAW_START_Y-5 + 0*LINE_HEIGHT), DPIX(200), DPIY(LINE_HEIGHT), - hwnd, (HMENU)0, ((LPCREATESTRUCT)lParam)->hInstance, NULL); -#endif - - CreateWindowA("STATIC", sysinfomsg, - WS_VISIBLE | WS_CHILD | SS_LEFT | WS_BORDER, - DPIX(DRAW_START_X+LINE_WIDTH+10), DPIY(DRAW_START_Y + 1*LINE_HEIGHT), DPIX(200), DPIY(8*LINE_HEIGHT), - hwnd, (HMENU)0, ((LPCREATESTRUCT)lParam)->hInstance, NULL); - - CreateWindowA("BUTTON", "About", - WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON, - DPIX(DRAW_START_X+LINE_WIDTH2+10), DPIY(DRAW_START_Y + LINE_HL + 11*LINE_HEIGHT), DPIX(80), DPIY(LINE_HEIGHT), - hwnd, (HMENU)BTN_ABOUT, ((LPCREATESTRUCT)lParam)->hInstance, NULL); - - infobox = CreateWindowA("STATIC", "https://github.com/JHRobotics/softgpu", - WS_VISIBLE | WS_CHILD | SS_CENTER, - DPIX(DRAW_START_X+80+10), DPIY(DRAW_START_Y + LINE_HL +14*LINE_HEIGHT), DPIX(LINE_WIDTH2-80-10), DPIY(LINE_HEIGHT), - hwnd, (HMENU)0, ((LPCREATESTRUCT)lParam)->hInstance, NULL); - - if(version_compare(&sysver, &WINVER98) >= 0) - { - CreateWindowA("BUTTON", "Don't install driver, only copy files", - WS_VISIBLE | WS_CHILD | BS_AUTOCHECKBOX, - DPIX(DRAW_START_X+80+10), DPIY(DRAW_START_Y + 16*LINE_HEIGHT), DPIX(LINE_WIDTH2-80-10), DPIY(LINE_HEIGHT), - hwnd, (HMENU)CHBX_NO_INSTALL, ((LPCREATESTRUCT)lParam)->hInstance, NULL); - } - else - { - CreateWindowA("BUTTON", "Don't install driver, only copy files", - WS_VISIBLE | WS_CHILD | BS_AUTOCHECKBOX | WS_DISABLED, - DPIX(DRAW_START_X+80+10), DPIY(DRAW_START_Y + 16*LINE_HEIGHT), DPIX(LINE_WIDTH2-80-10), DPIY(LINE_HEIGHT), - hwnd, (HMENU)CHBX_NO_INSTALL, ((LPCREATESTRUCT)lParam)->hInstance, NULL); - CheckDlgButton(hwnd, CHBX_NO_INSTALL, BST_CHECKED); - } - + softgpu_window_create(hwnd, lParam); break; } case WM_COMMAND: @@ -762,7 +496,11 @@ LRESULT CALLBACK softgpuWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara } #endif - if(IsDlgButtonChecked(hwnd, RAD_SSE)) + if(IsDlgButtonChecked(hwnd, RAD_SSE4)) + { + setInstallSrc(iniValue("[softgpu]", "drvpath.sse4")); + } + else if(IsDlgButtonChecked(hwnd, RAD_SSE)) { setInstallSrc(iniValue("[softgpu]", "drvpath.sse")); } @@ -771,15 +509,27 @@ LRESULT CALLBACK softgpuWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara setInstallSrc(iniValue("[softgpu]", "drvpath")); } - install_wine = IsDlgButtonChecked(hwnd, CHBX_WINE); - install_glide = IsDlgButtonChecked(hwnd, CHBX_GLIDE); + install_settings.install_wine = IsDlgButtonChecked(hwnd, CHBX_WINE); + install_settings.install_glide = IsDlgButtonChecked(hwnd, CHBX_GLIDE); + + install_settings.install_res_qxga = IsDlgButtonChecked(hwnd, CHBX_QXGA); + install_settings.install_res_1440 = IsDlgButtonChecked(hwnd, CHBX_1440); + install_settings.install_res_4k = IsDlgButtonChecked(hwnd, CHBX_4K); + install_settings.install_res_5k = IsDlgButtonChecked(hwnd, CHBX_5K); - install_res_qxga = IsDlgButtonChecked(hwnd, CHBX_QXGA); - install_res_1440 = IsDlgButtonChecked(hwnd, CHBX_1440); - install_res_4k = IsDlgButtonChecked(hwnd, CHBX_4K); - install_res_5k = IsDlgButtonChecked(hwnd, CHBX_5K); + install_settings.bug_rgb565 = IsDlgButtonChecked(hwnd, CHBX_BUG_RGB565); + install_settings.bug_prefer_fifo = IsDlgButtonChecked(hwnd, CHBX_BUG_PREFER_FIFO); + install_settings.bug_dx_flags = IsDlgButtonChecked(hwnd, CHBX_BUG_DX_FLAGS); + + install_settings.dd_set_system = IsDlgButtonChecked(hwnd, RAD_DD_HAL); + install_settings.d8_set_nine = IsDlgButtonChecked(hwnd, RAD_D8_NINE); + install_settings.d9_set_nine = IsDlgButtonChecked(hwnd, RAD_D9_NINE); + + install_settings.vram_limit = GetInputInt(hwnd, INP_VRAM_LIMIT); + install_settings.gmr_limit = GetInputInt(hwnd, INP_GMR_LIMIT); action_create("Files copy", filescopy_start, filescopy_wait, filescopy_result); + //action_create("Copy system files", ); action_create("Modify inf", infFixer, NULL, NULL); if(hasSETUPAPI && version_compare(&sysver, &WINVER98) >= 0) @@ -798,6 +548,8 @@ LRESULT CALLBACK softgpuWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara action_create("Driver installation", driver_without_setupapi, NULL, NULL); } + action_create("Configure wrappers", winenine, NULL, NULL); + if(IsDlgButtonChecked(hwnd, CHBX_FIXES)) { action_create("Compat. enhacements", apply_reg_fixes, NULL, NULL); @@ -828,6 +580,39 @@ LRESULT CALLBACK softgpuWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara } } break; + case BTN_SYSINFO: + sysinfo(hwnd); + break; + case BTN_WGLTEST: + runprog("tools\\wgltest.exe"); + break; + case BTN_GLCHECKER: + runprog("tools\\glchecker.exe"); + break; + case BTN_README: + { + char url[MAX_PATH] = "file:///"; + size_t len = strlen(url); + size_t i; + + GetCurrentDirectory(MAX_PATH-len, url+len); + len = strlen(url); + for(i = 0; i < len; i++) + { + if(url[i] == '\\') + url[i] = '/'; + } + strcat(url, "/softgpu.htm"); + + softgpu_browser(url); + + break; + } + case BTN_DEFAULTS: + void settingsReset(); + softgpu_set(hwnd); + break; + } // switch(wParam) break; } @@ -859,10 +644,7 @@ LRESULT CALLBACK softgpuLoadingProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM l { case WM_CREATE: { - CreateWindowA("STATIC", "Inspecting system...\n\nPlease stand by!", - WS_VISIBLE | WS_CHILD | SS_CENTER, - DPIX(0), DPIY(80), DPIX(400), DPIY(LINE_HEIGHT*3), - hwnd, (HMENU)0, ((LPCREATESTRUCT)lParam)->hInstance, NULL); + softgpu_loading_create(hwnd, lParam); break; } case WM_DESTROY: @@ -873,12 +655,18 @@ LRESULT CALLBACK softgpuLoadingProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM l return DefWindowProc(hwnd, msg, wParam, lParam); } +#ifdef EXTRA_INFO +#define WINDOW_TITLE "SoftGPU setup - " SOFTGPU_STR(EXTRA_INFO) +#else +#define WINDOW_TITLE "SoftGPU setup" +#endif + DWORD WINAPI softgpuLoadingThread(LPVOID lpParameter) { MSG msg; (void)lpParameter; - HWND win_loading = CreateWindowA(WND_SOFTGPU_LOAD_CLASS_NAME, "SoftGPU setup", WS_TILED|WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, DPIX(400), DPIY(250), 0, 0, NULL, 0); + HWND win_loading = CreateWindowA(WND_SOFTGPU_LOAD_CLASS_NAME, WINDOW_TITLE, WS_TILED|WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, DPIX(400), DPIY(250), 0, 0, NULL, 0); while(GetMessage(&msg, NULL, 0, 0)) { @@ -939,8 +727,8 @@ int main(int argc, const char *argv[]) DWORD threadId; HANDLE win_loading_th = CreateThread(NULL, 0, softgpuLoadingThread, NULL, 0, &threadId); - - registryReadDWORD("HKCU\\SOFTWARE\\SoftGPU\\setup", &settings_data); + + readSettings(); hasSETUPAPI = loadSETUAPI(); if(hasSETUPAPI) @@ -949,7 +737,7 @@ int main(int argc, const char *argv[]) } softgpu_sysinfo(); - + if(win_loading_th != INVALID_HANDLE_VALUE) { /* destroy loading window */ @@ -973,7 +761,7 @@ int main(int argc, const char *argv[]) wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE); wc.hCursor = LoadCursor(0, IDC_ARROW); wc.hIcon = LoadIconA(hInst, MAKEINTRESOURCE(SOFTGPU_ICON1)); - wc_loading.hInstance = hInst; + wc.hInstance = hInst; RegisterClass(&wc); @@ -992,7 +780,7 @@ int main(int argc, const char *argv[]) ReleaseDC(NULL, hdc); } - HWND win = CreateWindowA(WND_SOFTGPU_CLASS_NAME, "SoftGPU setup", WS_OVERLAPPEDWINDOW|WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, DPIX(512), DPIY(390), 0, 0, NULL, 0); + HWND win = CreateWindowA(WND_SOFTGPU_CLASS_NAME, WINDOW_TITLE, SOFTGPU_WIN_STYLE|WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, DPIX(600), DPIY(420), 0, 0, NULL, 0); if(isNT) { @@ -1022,13 +810,19 @@ int main(int argc, const char *argv[]) timer_proc(win); } + if(reinstall_dx) + { + MessageBoxA(win, "Some DirectX files were modified by previous SoftGPU installation or other wrapper. It is recommended to install DirectX redistributable again!", "DX redistributable", MB_OK); + } + while(GetMessage(&msg, NULL, 0, 0)) { - if (IsDialogMessage(win, &msg)) + /*if(IsDialogMessageA(win, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); - } + }*/ + IsDialogMessageA(win, &msg); } DestroyWindow(win); diff --git a/softgpu.h b/softgpu.h new file mode 100644 index 0000000..d8bd3c3 --- /dev/null +++ b/softgpu.h @@ -0,0 +1,136 @@ +/****************************************************************************** + * Copyright (c) 2023 Jaroslav Hensl * + * * + * Permission is hereby granted, free of charge, to any person * + * obtaining a copy of this software and associated documentation * + * files (the "Software"), to deal in the Software without * + * restriction, including without limitation the rights to use, * + * copy, modify, merge, publish, distribute, sublicense, and/or sell * + * copies of the Software, and to permit persons to whom the * + * Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be * + * included in all copies or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * + * OTHER DEALINGS IN THE SOFTWARE. * + * * +*******************************************************************************/ +#ifndef __SOFTGPU_H__INCLUDED__ +#define __SOFTGPU_H__INCLUDED__ + +#include "winini.h" +#include "actions.h" + +#include "windrv.h" +#include "winreg.h" +#include "filecopy.h" +#include "winres.h" + +#include "actions.h" +#include "setuperr.h" +#include "softgpuver.h" + +#define CHBX_MSCRT 1 +#define CHBX_DX 2 +#define INP_PATH 3 +#define BTN_BROWSE 4 +#define RAD_NORMAL 5 +#define RAD_SSE 6 +#define CHBX_WINE 7 +#define CHBX_GLIDE 8 +#define CHBX_SIMD95 9 +#define CHBX_FIXES 10 +//#define CHBX_IE 11 + +#define BTN_EXIT 11 +#define BTN_INSTALL 12 +#define CHBX_GL95 13 +#define BTN_ABOUT 14 + +#define CHBX_QXGA 15 +#define CHBX_1440 16 +#define CHBX_4K 17 +#define CHBX_5K 18 + +#define CHBX_NO_INSTALL 19 +#define RAD_SSE4 20 + +#define RAD_DD_HAL 21 +#define RAD_DD_WINE 22 + +#define RAD_D8_WINE 23 +#define RAD_D8_NINE 24 + +#define RAD_D9_WINE 25 +#define RAD_D9_NINE 26 + +#define CHBX_BUG_PREFER_FIFO 27 +#define CHBX_BUG_RGB565 28 +#define CHBX_BUG_DX_FLAGS 29 + +#define INP_VRAM_LIMIT 30 +#define INP_GMR_LIMIT 31 + +#define BTN_README 32 +#define BTN_SYSINFO 33 +#define BTN_WGLTEST 34 +#define BTN_GLCHECKER 35 +#define BTN_DEFAULTS 36 + +BOOL isSettingSet(DWORD menu); +void writeSettings(HWND hwnd); +void readSettings(); +int intSettings(int type); +void settingsReset(); + +#define SETTINGS_VRAM 1 +#define SETTINGS_GMR 2 + +extern float rdpiX; +extern float rdpiY; + +extern BOOL isNT; +extern version_t sysver; +extern version_t dxver; +extern BOOL hasCRT; +extern BOOL hasSETUPAPI; +extern uint32_t hasSSE3; +extern uint32_t hasSSE42; +extern uint32_t hasAVX; +extern BOOL hasOpengl; + +#define DPIX(_spx) ((int)(ceil((_spx)*rdpiX))) +#define DPIY(_spx) ((int)(ceil((_spx)*rdpiY))) + +static const version_t WINVER95 = {4,0,0,0}; +static const version_t WINVER98 = {4,10,0,0}; +static const version_t WINVER98SE = {4,10,2222,0}; +static const version_t WINVERME = {4,90,0,0}; +static const version_t WINVER2K = {5,0,0,0}; + +void softgpu_window_create(HWND hwnd, LPARAM lParam); +void softgpu_loading_create(HWND hwnd, LPARAM lParam); + +extern char sysinfomsg[]; + +extern HWND infobox; +extern HWND installbtn; +extern HWND pathinput; + +extern BOOL reinstall_dx; + +#define SOFTGPU_WIN_STYLE (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX) + +void softgpu_browser(const char *url); +int GetInputInt(HWND hwnd, int id); +void softgpu_set(HWND hwnd); + +#endif /* __SOFTGPU_H__INCLUDED__ */ diff --git a/softgpu.htm b/softgpu.htm new file mode 100644 index 0000000..1d483a7 --- /dev/null +++ b/softgpu.htm @@ -0,0 +1,6 @@ + + + +

Hello world

+ + diff --git a/softgpu.ini b/softgpu.ini index 6a861f7..13a6bb0 100644 --- a/softgpu.ini +++ b/softgpu.ini @@ -9,7 +9,7 @@ ; - no UTF here, only OEM charset ; - names ARE cASe sensitive ; -; THIS FILE IS ONLY FOR VERSION 0.4 DON'T USE IT WITH FUTURE VERSIONS! +; THIS FILE IS ONLY FOR VERSION 0.5 DON'T USE IT WITH FUTURE VERSIONS! ; [softgpu] dx8target=4.8.0.400 @@ -19,8 +19,9 @@ dx9path=redist\dx9_2006\dxsetup.exe dx9path.fe=redist\dx9_2004\dxsetup.exe msvcrtpath=redist\vc6redist.exe defpath=C:\drivers\softgpu -drvpath=driver\win95 -drvpath.sse=driver\win98me +drvpath=driver\mmx-w95 +drvpath.sse=driver\sse3-w98 +drvpath.sse4=driver\sse4-w98 drvfile=vmdisp9x.inf simd95=simd95\simd95.com opengl95=redist\opengl95\DLL\OPENGL32.DLL @@ -31,27 +32,27 @@ glu95=redist\opengl95\DLL\GLU32.DLL ;ie98.ver=Internet Explorer 6.0 [version] -vmdisp9x=1.2023.0.24 -mesa9x=23.1.6.36 -wine9x=1.7.55.16 -openglide9x=0.1.2023.11 +vmdisp9x=1.2024.0.39 +mesa9x=23.1.9.70 +wine9x=1.7.55.23 +openglide9x=0.1.2024.14 simd95=1.0.0.0 [fixes] HKLM\Software\Mesa3D\glquake.exe\MESA_EXTENSION_MAX_YEAR;2000 HKLM\Software\Mesa3D\quake2.exe\MESA_EXTENSION_MAX_YEAR;2000 HKLM\Software\Mesa3D\quake3.exe\MESA_EXTENSION_MAX_YEAR;2004 +HKLM\Software\Mesa3D\SoF.exe\MESA_EXTENSION_MAX_YEAR;2000 HKLM\Software\DDSwitcher\hl.exe;system HKLM\Software\DDSwitcher\diablo.exe;system HKLM\Software\DDSwitcher\mdk95.exe;system HKLM\Software\DDSwitcher\isle.exe;system HKLM\Software\DDSwitcher\legoisle.exe;system HKLM\Software\DDSwitcher\mib.exe;system +HKLM\Software\DDSwitcher\Sims.exe;system +HKLM\Software\DDSwitcher\MPLAYER2.exe;system HKLM\Software\OpenGlide\Hitman.exe\NumTMU;2 HKLM\Software\OpenGlide\u9.icd\HideCursor;2 HKLM\Software\OpenGlide\u9.exe\HideCursor;2 -HKLM\Software\Mesa3D\u9.icd\DIRECT_VRAM;0 -HKLM\Software\Mesa3D\u9.exe\DIRECT_VRAM;0 -HKLM\Software\Wine\tp_win32.exe\MaxShaderModelVS;DWORD:0 -HKLM\Software\Wine\gta_sa.exe\MaxShaderModelVS;DWORD:0 - +HKLM\Software\Wine\tp_win32.exe\MaxShaderModelVS;DELETE +HKLM\Software\Wine\gta_sa.exe\MaxShaderModelVS;DELETE diff --git a/softgpu.md b/softgpu.md new file mode 100644 index 0000000..dd6b110 --- /dev/null +++ b/softgpu.md @@ -0,0 +1,367 @@ +# SoftGPU +SoftGPU is pack of driver, wrappers, and system components to make 3D acceleration work on Microsoft Windows 9x Systems (Windows 95, Windows 98, Windows Me) in a Virtual Machine. + +## Requirements + +### Hypervisor +- For maximum HW 3D feature support: + - Oracle VirtualBox 7.0 +- HW 3D acceleration without pixel shader support: + - Oracle VirtualBox 6.1 + - VMWare Workstation 16.x - 17.x + - VMWare Player 16.x - 17.x +- 3D pass-through + - QEMU 6.x - 8.x + [QEMU 3Dfx](https://github.com/kjliew/qemu-3dfx) +- SW 3D acceleration + - QEMU 6.x - 8.x + - VirtualBox 5.1, 6.0 + +### Hardware +- Intel Core2 CPU or AMD's equivalent +- VM-x/AMD-V CPU instruction support and enabled in BIOS/firmware +- 4 GB RAM +- GPU for HW acceleration: + - Oracle VirtualBox 7.0: DirectX 11.1 or Vulcan compatible + - VMWare Workstation/Player: DirectX 9.0c with Shader Model 3 and OpenGL 2.1 + - Oracle VirtualBox 6.1: DirectX 9.0c on Windows host, OpenGL 2.1 on Linux + +### Virtual Machine +- CPU acceleration +- Pentium II instruction set (when CPU is emulated) +- 1 GB free HDD space +- 512 MB RAM +- Microsoft Windows 95, 98, 98 SE or Me (Windows 98 SE is recommended) +- [patcher9x](https://github.com/JHRobotics/patcher9x/releases) +- [R. Loew's patchmem](http://files.emulace.cz/patchmem.zip) (if you want to set more RAM than 512 MB) +- OpenGL95 (included, for Windows 95 without OpenGL) +- MSVCRT (included, for Windows 95) +- DirectX Redistributable 8 or 9 (included) + +## Virtual GPU + +Historically video card in Virtual Machines were designed for only rendering framebuffer - they're simply to implement, both on hypervisor side and on BIOS/firmware in VM, drivers for OS in VM are simply too and on most cases there not needed and most modern OS can use to some basic drawing using (video) BIOS calls. This is logical, because VM are usually used as servers, and you don't want to waste resources on something that is not visible. This is important to know because (by my opinion) most problem with graphic on virtual desktop is that these technologies were developed for server use and has been only a bit fixed for desktop usage. + +Following are the most common types of virtual video adapters: + +### Bochs VBE Extensions (aka VBoxVGA or -vga std) + +On this API is based basic video adapter in VirtualBox (VBoxVGA) and on QEMU (`-vga std`). There is no 2D or 3D acceleration support in this video card. SoftGPU support VirtualBox and QEMU variant but all drawing is done by software. It is slow but is most compatible and works in all cases. Key feature for speed of SW rendering is SSE instructions (at least SSE 3) support on VM and virtual OS (>= Windows 98). + +### VMware SVGA3D (aka VBoxSVGA or VMSVGA) + +This is real (virtual) GPU and SoftGPU can use this for accelerated rendering. This GPU can occur in multiple variant. + +#### SVGA-II (aka -vga vmware) + +Simplest variant supported event in QEMU but with very limited 2D acceleration. This variant still using full software rendering with similar results as VBE. To this variant is GPU degraded if is 3D acceleration turned off in VMware or VirtualBox. + +QEMU isn't support 8 and 16 bit modes, SoftGPU can work on it, but most games won't start. Please use `-vga std` in QEMU instead. + +#### SVGA3D gen.9 (vGPU9) + +Supported by VMware and VirtualBox 6.1 and 7.0, mainly designed for accelerate DX 9 drawing (usually for Windows Vista and 7 aero). Limiting is shader model used in this GPU and isn't possible to use pixel/vertex shaders in DX8 and DX9 games. Again, isn't possible use Mesa Nine (DX9 translation to native driver) with this GPU variant. + +#### SVGA3D gen.10 (vGPU10) + +Supported only in VirtualBox 7.0. (On VMware is theoretically supported too, but I'm currently not able to turn on it for Windows 9x guest). This is designed for Windows 10 for DirectX 11/12 support - DirectX 12 can emulate all older DX variant and native DDI isn't needed (but this works only on W7 and W10/W11). + +DX8/DX9/OpenGL Shader are supported, and most DX 9 games works, OpenGL rendering in games is faster than with vGPU9. This is actually most preferred way to use with SoftGPU. Disadvantage of using vGPU10 is that all textures are stored in VM RAM so you need more RAM to attach to VM. 512 MB RAM is minimum recommended value for vGPU10 and for Windows 9x is value also maximum recommended without additional patches. + +#### SVGA-III + +Newest variant primary developed for ARM devices, currently not supported by SoftGPU. (But when this will be supported on VirtualBox or another opensource HV, I will include support of this to SoftGPU too). + + +### VirGL + +This virtual GPU for QEMU, potentially faster than SVGA3D. Not supported by SoftGPU yet. + +### Real GPU (PCI passthrough) + +This is connection of real GPU to virtual machine. Works (as I known) only on QEMU in Linux (as Host). Need extra GPU compatible with Windows 9x - I personally had relative success with PCI express variant of nvidia 6600/6600 GT. You also need specific HW (free PCI express slot, VT-d CPU support, mother board support for PCIe slot isolation and second monitor + keyboard and mouse). I also observe very massive performance loss. I recommend this only for most advanced users. SoftGPU is no needed there because you can use native GPU drivers. + +### Virtual GPU (PCI passthrough) + +Some GPUs allow to split the real GPU to multiple virtual GPUs and attach them to virtual machines. This feature isn't commonly present in gaming hardware (for example for nvidia you need quadro card), only common technology is Intel GVT-g. But there are no drivers for Windows 9x guest. I see too many problems to consider support in SoftGPU. + +### Emulated GPU + +This is domain for emulators. Software like DOSBox (DOSBox-X) and PCem allow emulate real GPU like S3 Trio or S3 ViRGE and 3D accelerator like Voodoo/Voodoo2. This allows to use unchanged legacy software and driver. SoftGPU support is not needed here. + + +## 3D passthrough + +This technique creates side channel so 3D commands do not go to virtual GPU, but they are serialized and send to host machine where are unpacked and send to real GPU. This is much simpler than create full-weight virtual GPU. Can be do it over shared memory or via network. Disadvantages are problems with transporting rendered image back to VM (for example to draw in Window or postprocess) and with multiple contexts (more different application want render own graphics same time). There are some solutions: + +### QEMU-3Dfx + +More on [QEMU-3Dfx page](https://github.com/kjliew/qemu-3dfx). SoftGPU is supporting this. See instructions on [GitHub main page](https://github.com/JHRobotics/softgpu/#qemu-3dfx-usage) how to use. + +### Chromium + +This is [very old software](https://chromium.sourceforge.net/), but it's modification was used in VirtualBox to version 5.1 to accelerate 3D rendering. Currently is abandoned and not supported by SoftGPU. + + +## Virtual Machine configuration + +General tips how to configure individual software is on [Github project main page](https://github.com/JHRobotics/softgpu/). + + +## Installation + +Mount SoftGPU CD or unpack zip package to VM HDD and run softgpu.exe, revise options (default are recommended for most users and configurations) and click on **Install** button. + +Options descriptions follow: + +### Binaries types + +SoftGPU support 2 differed CPU architectures: + +**Pentium II** is mainly for Windows 95 natively which supports only MMX instruction set (and event with SSE hack is required to minimize usage of SSE/AVX instructions to only one application) or when your virtual CPU is emulated and advanced instruction isn't available. + +**SSE 3** is for Windows 95/98 and is much faster and because I want to keep compatibility with old Intel Core2 architecture, is SSE instruction set limited to SSE3. + +**SSE 4.2** using maximum CPU extensions which Windows 98/Me supporting. Speed is slightly faster than **SSE3** but depends on CPU. There binaries aren't included in standard releases, I'm including them to edition for supporters as gift for their support. But in every case you can build them yourself by add this `CFLAGS` to `config.mk`: + +```TUNE += -march=westmere``` + + +### Wrappers + +Currently GPU driver natively support only **DirectDraw** and **OpenGL** and other API needs to translated to them. + +#### Wine D3D (Wine9x) + +Translating DirectDraw and DirectX to OpenGL. Although Wine has many bugs and graphical glitches it is still preferred way to emulate DirectX. + +#### Mesa Nine (Mesa9x) + +Translating DirectX 9 directly to driver primitives (if is based on Mesa3D library) and in theory should be faster than Wine. But require higher shader model so works only for vGPU10. Also Wine solving some quirks in Windows software so is more compatible and stable than Nine. + +#### Eight-to-Nine (Mesa9x) + +Since Nine supporting only, DX9 there is wrapper to translate DX8 to DX9. It is based on [d3d8to9](https://github.com/crosire/d3d8to9) project. All is statically linked to one DLL, so you don't need to worry about DLL ping-pong. Is is slightly faster than Wine. + + +#### OpenGlide (OpenGlide9x) + +This wrapper is translating 3Dfx Glide to OpenGL. Currently is supported only Glide2x and Glide3x. This wrapper isn't ideal but I making slowly progress. Glide for DOS is not supported and support is not planed. You can use DOS Glide with [QEMU-3Dfx](https://github.com/kjliew/qemu-3dfx), but binaries no included in SoftGPU package. + + +### VRAM and GMR + +Every Windows 9x application has this memory (RING-3) layout: +- 0x00000000 - 0x7FFFFFFF: private memory (2 GB) +- 0x80000000 - 0xBFFFFFFF: shared memory (1 GB) +- 0xC0000000 - 0xFFFFFFFF: system memory (1 GB) + +First 2 GB is private to every application but shared and system are the same for every application (RING-3) or driver (PM16 RING-3 or PM32 RING-0). And here is problem: devices memory is mapped to system. As memory we're speaking about ROM (including BIOS), RAM on devices (VRAM, disk controller cache etc., without system RAM) and I/O space (device HW registers, etc.). If we weren't counting VRAM, on most PCs are only about 300-400 MB free in system memory. This is one of problem, why GPU with 512 MB VRAM, not working on Windows 9x, VRAM just not fit here. + +In real VRAM are stored framebuffer, surfaces, textures, and buffers (on modern GPU also graphical primitives, shaders and GPU computation data and code). But on Virtual GPU is stored only framebuffer, VMHAL can use VRAM to store surfaces, but for 1920x1200 is only about 16 MB used, 32 MB for theoretical application using DirectDraw with double buffering. Limiting VRAM can be useful to save system memory space. + +But where the textures and rendering buffers stored? In something called Guest Memory Region, this is guest system RAM mapped to virtual GPU. vGPU9 stores in GMR working buffer + system memory mapped textures and GPU only mapped textures are in the host memory (in theory they can be in host VRAM only, but usually they are occupying both host RAM and VRAM). vGPU10 also stores GPU mapped textures in guest system RAM (and this RAM is mapped to real GPU, more or less effectively). So minimal application eats 64 MB memory (~32 MB runtime + 32 MB frame buffer), typical game eats about 128 MB for vGPU9 and 256 for vGPU10. Compressed textures are eating more space, then uncompressed, because you need store both compressed and unpacked variant. 16-bit frame buffer is larger than 32-bit, because all rendering operations are 32-bit and final version it's software blit to 16-bit. + +Some later game and 3DMark can eat all 512 MB of RAM. So that why is here GMR limitation, because if the driver (GMR allocation is done by RING-0 driver) eats all usable RAM, system freeze. + +SoftGPU will limit VRAM to 128 MB and GMR to 128 MB for 512 MB system and for 256 if you have 768 MB RAM and more. These limits can be adjust by this registry keys: + +``` +REGEDIT4 + + +[HKEY_LOCAL_MACHINE\Software\VMWSVGA] +"VRAMLimit"=dword:00000080 + +[HKEY_LOCAL_MACHINE\Software\Mesa3D\global] +"SVGA_GMR_LIMIT"="128" +``` + +GMR limit can be configured per application, 128 MB is usually enough, but 3Dmark03 for example need about 256 MB to work correctly. + + +## Registry configuration + +Where are example how registry configuration work, you can save there example as text file with REG extension and apply them on double click or open `regedit.exe` edit these value directly (create these key when missing). + +### Hypervisors bugs override + +``` +REGEDIT4 + + +[HKEY_LOCAL_MACHINE\Software\VMWSVGA] +; +; For 565 format were reported bad attributes +; You can disable it if you have: +; VirtualBox >= 6.1.46 +; VirtualBox >= 7.0.10 +"RGB565bug"=dword:00000001 +; +; Vmware sometime freeze when Command Buffers are used. +; This using older way to send commands to GPU. +; You turn off for VirtualBox, bud vGPU9 is slightly waster +; when using FIFO. This option have no effect to vGPU10 +"PreferFIFO"=dword:00000001 + +[HKEY_LOCAL_MACHINE\Software\Mesa3D\global] +; +; +"SVGA_CLEAR_DX_FLAGS"="1" +``` + + +### Universal driver configuration +``` +REGEDIT4 + + +[HKEY_LOCAL_MACHINE\Software\vmdisp9x] +; +; set 1 to use software OpenGL event there is some accelerated +"FORCE_SOFTWARE"=dword:00000000 +; +; set 1 when you has working QEMU-3Dfx wrapper +"FORCE_QEMU3DFX"=dword:00000000 + + +``` + +### SVGA driver configuration + +``` +REGEDIT4 + + +[HKEY_LOCAL_MACHINE\Software\VMWSVGA] +; +; Limit mapping of VRAM in MB. For Windows 9x is limit +; around 300 MB and if you attach mode, system will crash. +; But keep on might that VRAM is almost unutilized and if you +; don't need 8k resolution isn't reason why increase this value. +"VRAMLimit"=dword:00000080 +; +; set 0 to disable command buffer support, use FIFO instead. +; For debug only. +"CommandBuffers"=dword:00000001 + +``` + + +### DirectX/DirectDraw wrapper selection + +Some application won't work or not working well with Wine, for 2D application you can use native DirectDraw HAL. Media player is one of them: + +``` +REGEDIT4 + + +[HKEY_LOCAL_MACHINE\Software\DDSwitcher] +"MPLAYER2.exe"="system" + +``` + +Some 2D games have these problems to, for example The Sims: + +``` +REGEDIT4 + + +[HKEY_LOCAL_MACHINE\Software\DDSwitcher] +"sims.exe"="system" + +``` + +You can also select native DirectDraw HAL by default, and turn on wine for individual applications: + +``` +REGEDIT4 + + +[HKEY_LOCAL_MACHINE\Software\DDSwitcher] +"global"="system" +"rayman2.exe"="wine" + +``` + +For DX8 and DX9 you can switch between HEL (there isn't native DirectX HAL) - but application needs support software/emulated rendering, Wine or Nine (Mesa DirectX 9 driver). Using Nine for DX8 (when is supported) game (Mafia): + +``` +REGEDIT4 + + +[HKEY_LOCAL_MACHINE\Software\D8Switcher] +"game.exe"="ninemore" + +``` + +Nine for DX9 game (CMR 3): + +``` +REGEDIT4 + + +[HKEY_LOCAL_MACHINE\Software\D9Switcher] +"Rally_3PC.exe"="nine" + +``` + +Supported values are: *system* (pass calls to system DLL), *wine* (using Wine9x), *nine* (use nine for DX9 when is supported), *ninemore* (Nine for DX 8 and DX 9), *nineforce* (try use Nine even when looks like unsupported) or value can be name of DLL (with path or only file name) to wrapper DLL (can be used for example with SwiftShader). + +### Mesa3D + +Old OpenGL games have problem with too large extension string Quake II is on of them: + +``` +REGEDIT4 + +[HKEY_LOCAL_MACHINE\Software\Mesa3D\quake2.exe] +"MESA_EXTENSION_MAX_YEAR"="2000" +``` + +When you using software rendering and [SIMD95](https://github.com/JHRobotics/simd95) for enable AXV instruction set, it is recommended to use them only with one application Q3 for example: + +``` +REGEDIT4 + +[HKEY_LOCAL_MACHINE\Software\Mesa3D\quake2.exe] +"LP_NATIVE_VECTOR_WIDTH"="256" +``` + +Possible configuration values here are: https://docs.mesa3d.org/envvars.html + +### Wine + +Default Wine registry path also working: https://wiki.winehq.org/Useful_Registry_Keys + +But also working same registry path scheme as for Mesa, for example increase VRAM memory to 256 MB (Video RAM is emulated anyway, you can use any value when you have enough system RAM): + + +``` +REGEDIT4 + +[HKEY_LOCAL_MACHINE\Software\Wine\global] +"VideoMemorySize"="256" +``` + + +### QEMU 3DFX + +``` +REGEDIT4 + + +[HKEY_LOCAL_MACHINE\Software\vmdisp9x] +; override signature in QEMU-3dfx driver +; you can obtain current signature by command: +; git rev-parse HEAD +; (only first 7 characters needed) +; you need same signature as QEMU-3dfx which you used to +; build QEMU +; +"REV_QEMU3DFX"="3258e4a30" +; +; When you have working QEMU-3dfx this key enable +; ICD OpenGL driver +"FORCE_QEMU3DFX"=dword:00000001 + +``` \ No newline at end of file diff --git a/window.c b/window.c new file mode 100644 index 0000000..18f7e97 --- /dev/null +++ b/window.c @@ -0,0 +1,511 @@ +/****************************************************************************** + * Copyright (c) 2024 Jaroslav Hensl * + * * + * Permission is hereby granted, free of charge, to any person * + * obtaining a copy of this software and associated documentation * + * files (the "Software"), to deal in the Software without * + * restriction, including without limitation the rights to use, * + * copy, modify, merge, publish, distribute, sublicense, and/or sell * + * copies of the Software, and to permit persons to whom the * + * Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be * + * included in all copies or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * + * OTHER DEALINGS IN THE SOFTWARE. * + * * +*******************************************************************************/ +#include +#include +#include +#include +#include + +#include "softgpu.h" + +#include "nocrt.h" + +#define DRAW_START_X 16 +#define DRAW_START_Y 10 +#define LINE_HEIGHT 20 +#define LINE_HL 10 +#define LINE_QL 5 +#define LINE_WIDTH 230 +#define LINE_QWIDTH 80 +#define LINE_HWIDTH 160 + +#define LINE_WIDTH2 350 + +version_t dxtarget; + +void softgpu_set(HWND hwnd) +{ + DWORD sty; + + /* opengl 95 */ + if(version_compare(&sysver, &WINVER98) < 0) + { + if(!hasOpengl && isSettingSet(CHBX_GL95)) + { + CheckDlgButton(hwnd, CHBX_GL95, BST_CHECKED); + } + else + { + CheckDlgButton(hwnd, CHBX_GL95, BST_UNCHECKED); + } + } + else + { + HWND btnGL = GetDlgItem(hwnd, CHBX_GL95); + if(btnGL) + { + sty = GetWindowLongA(btnGL, GWL_STYLE) | WS_DISABLED; + SetWindowLongA(btnGL, GWL_STYLE, sty); + } + } + + /* CRT */ + if(!hasCRT && isSettingSet(CHBX_MSCRT)) + { + CheckDlgButton(hwnd, CHBX_MSCRT, BST_CHECKED); + } + else + { + CheckDlgButton(hwnd, CHBX_MSCRT, BST_UNCHECKED); + } + + /* DX redistrib. */ + CheckDlgButton(hwnd, CHBX_DX, BST_UNCHECKED); + if(version_compare(&dxver, &dxtarget) < 0 || reinstall_dx) + { + if(isSettingSet(CHBX_DX)) + CheckDlgButton(hwnd, CHBX_DX, BST_CHECKED); + } + + /* reset items */ + CheckDlgButton(hwnd, RAD_NORMAL, BST_UNCHECKED); + CheckDlgButton(hwnd, RAD_SSE, BST_UNCHECKED); + CheckDlgButton(hwnd, RAD_SSE4, BST_UNCHECKED); + + /* MMX/SSE3/SSE4.2 */ + const char *drv_sse4 = iniValue("[softgpu]", "drvpath.sse4"); + int selected_sse = 0; + if(drv_sse4 != NULL + && is_dir(drv_sse4) + && version_compare(&sysver, &WINVER98) >= 0 + && hasSSE42) + { + selected_sse = 4; + } + else if(version_compare(&sysver, &WINVER98) >= 0 && hasSSE3) + { + selected_sse = 3; + } + + if(drv_sse4 == NULL || !is_dir(drv_sse4)) + { + HWND radioSSE4 = GetDlgItem(hwnd, RAD_SSE4); + if(radioSSE4) + { + sty = GetWindowLongA(radioSSE4, GWL_STYLE) | WS_DISABLED; + SetWindowLongA(radioSSE4, GWL_STYLE, sty); + } + } + + switch(selected_sse) + { + case 3: + CheckDlgButton(hwnd, RAD_SSE, BST_CHECKED); + break; + case 4: + CheckDlgButton(hwnd, RAD_SSE4, BST_CHECKED); + break; + default: + CheckDlgButton(hwnd, RAD_NORMAL, BST_CHECKED); + break; + } + + /* Wine */ + if(isSettingSet(CHBX_WINE)) + CheckDlgButton(hwnd, CHBX_WINE, BST_CHECKED); + else + CheckDlgButton(hwnd, CHBX_WINE, BST_UNCHECKED); + + /* Glide */ + if(isSettingSet(CHBX_GLIDE)) + CheckDlgButton(hwnd, CHBX_GLIDE, BST_CHECKED); + else + CheckDlgButton(hwnd, CHBX_GLIDE, BST_UNCHECKED); + + /* SIMD95 */ + if(version_compare(&sysver, &WINVERME) < 0) + { + if(!hasAVX) + { + if(isSettingSet(CHBX_SIMD95)) + { + CheckDlgButton(hwnd, CHBX_SIMD95, BST_CHECKED); + } + else + { + CheckDlgButton(hwnd, CHBX_SIMD95, BST_UNCHECKED); + } + } + } + else + { + HWND btnSIMD95 = GetDlgItem(hwnd, CHBX_SIMD95); + if(btnSIMD95) + { + sty = GetWindowLongA(btnSIMD95, GWL_STYLE) | WS_DISABLED; + SetWindowLongA(btnSIMD95, GWL_STYLE, sty); + } + } + + /* fixes */ + if(isSettingSet(CHBX_FIXES)) + CheckDlgButton(hwnd, CHBX_FIXES, BST_CHECKED); + else + CheckDlgButton(hwnd, CHBX_FIXES, BST_UNCHECKED); + + /* reset */ + CheckDlgButton(hwnd, RAD_DD_HAL, BST_UNCHECKED); + CheckDlgButton(hwnd, RAD_DD_WINE, BST_UNCHECKED); + CheckDlgButton(hwnd, RAD_D8_WINE, BST_UNCHECKED); + CheckDlgButton(hwnd, RAD_D8_NINE, BST_UNCHECKED); + CheckDlgButton(hwnd, RAD_D9_NINE, BST_UNCHECKED); + CheckDlgButton(hwnd, RAD_D9_WINE, BST_UNCHECKED); + + // wine vs nine + if(isSettingSet(RAD_DD_HAL)) + CheckDlgButton(hwnd, RAD_DD_HAL, BST_CHECKED); + else + CheckDlgButton(hwnd, RAD_DD_WINE, BST_CHECKED); + + if(isSettingSet(RAD_D8_NINE)) + CheckDlgButton(hwnd, RAD_D8_NINE, BST_CHECKED); + else + CheckDlgButton(hwnd, RAD_D8_WINE, BST_CHECKED); + + if(isSettingSet(RAD_D9_NINE)) + CheckDlgButton(hwnd, RAD_D9_NINE, BST_CHECKED); + else + CheckDlgButton(hwnd, RAD_D9_WINE, BST_CHECKED); + + // BUGS + if(isSettingSet(CHBX_BUG_PREFER_FIFO)) + CheckDlgButton(hwnd, CHBX_BUG_PREFER_FIFO, BST_CHECKED); + else + CheckDlgButton(hwnd, CHBX_BUG_PREFER_FIFO, BST_UNCHECKED); + + if(isSettingSet(CHBX_BUG_RGB565)) + CheckDlgButton(hwnd, CHBX_BUG_RGB565, BST_CHECKED); + else + CheckDlgButton(hwnd, CHBX_BUG_RGB565, BST_UNCHECKED); + + if(isSettingSet(CHBX_BUG_DX_FLAGS)) + CheckDlgButton(hwnd, CHBX_BUG_DX_FLAGS, BST_CHECKED); + else + CheckDlgButton(hwnd, CHBX_BUG_DX_FLAGS, BST_UNCHECKED); + + // extra resolutions + if(isSettingSet(CHBX_QXGA)) + CheckDlgButton(hwnd, CHBX_QXGA, BST_CHECKED); + else + CheckDlgButton(hwnd, CHBX_QXGA, BST_UNCHECKED); + + if(isSettingSet(CHBX_1440)) + CheckDlgButton(hwnd, CHBX_1440, BST_CHECKED); + else + CheckDlgButton(hwnd, CHBX_1440, BST_UNCHECKED); + + if(isSettingSet(CHBX_4K)) + CheckDlgButton(hwnd, CHBX_4K, BST_CHECKED); + else + CheckDlgButton(hwnd, CHBX_4K, BST_UNCHECKED); + + if(isSettingSet(CHBX_5K)) + CheckDlgButton(hwnd, CHBX_5K, BST_CHECKED); + else + CheckDlgButton(hwnd, CHBX_5K, BST_UNCHECKED); + + if(version_compare(&sysver, &WINVER98) < 0) + { + HWND btnNoInstall = GetDlgItem(hwnd, CHBX_NO_INSTALL); + if(btnNoInstall) + { + sty = GetWindowLongA(btnNoInstall, GWL_STYLE) | WS_DISABLED; + SetWindowLongA(btnNoInstall, GWL_STYLE, sty); + } + CheckDlgButton(hwnd, CHBX_NO_INSTALL, BST_CHECKED); + } + + char tmplabel[64]; + HWND inp_vram = GetDlgItem(hwnd, INP_VRAM_LIMIT); + if(inp_vram) + { + sprintf(tmplabel, "%d", intSettings(SETTINGS_VRAM)); + SetWindowTextA(inp_vram, tmplabel); + } + + HWND inp_gmr = GetDlgItem(hwnd, INP_GMR_LIMIT); + if(inp_gmr) + { + sprintf(tmplabel, "%d", intSettings(SETTINGS_GMR)); + SetWindowTextA(inp_gmr, tmplabel); + } + + +} + +#define DRAW_MOVE(_w, _h) if(draw_direction == 0) \ + {draw_y += _h;} \ + else \ + {draw_x += _w;} + +#define CHECKBOX(id, w, h, text) CreateWindowA("BUTTON", text, WS_VISIBLE | WS_CHILD | BS_AUTOCHECKBOX, \ + DPIX(draw_x), DPIY(draw_y), DPIX(w), DPIY(h), \ + hwnd, (HMENU)id, ((LPCREATESTRUCT)lParam)->hInstance, NULL); \ + DRAW_MOVE(w, h) + +#define RADIO(id, w, h, text, flags) CreateWindowA("BUTTON", text, (WS_VISIBLE | WS_CHILD | BS_AUTORADIOBUTTON) | (flags), \ + DPIX(draw_x), DPIY(draw_y), DPIX(w), DPIY(h), \ + hwnd, (HMENU)id, ((LPCREATESTRUCT)lParam)->hInstance, NULL); \ + DRAW_MOVE(w, h) + +#define BUTTON(id, w, h, text, flags) CreateWindowA("BUTTON", text, (WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON) | (flags), \ + DPIX(draw_x), DPIY(draw_y), DPIX(w), DPIY(h), \ + hwnd, (HMENU)id, ((LPCREATESTRUCT)lParam)->hInstance, NULL); \ + DRAW_MOVE(w, h) + +#define LABEL(id, w, h, text) CreateWindowA("STATIC", text, WS_VISIBLE | WS_CHILD | SS_LEFT, \ + DPIX(draw_x), DPIY(draw_y), DPIX(w), DPIY(h), \ + hwnd, (HMENU)id, ((LPCREATESTRUCT)lParam)->hInstance, NULL); \ + DRAW_MOVE(w, h) + +#define LABEL_CENTER(id, w, h, text) CreateWindowA("STATIC", text, WS_VISIBLE | WS_CHILD | SS_CENTER, \ + DPIX(draw_x), DPIY(draw_y), DPIX(w), DPIY(h), \ + hwnd, (HMENU)id, ((LPCREATESTRUCT)lParam)->hInstance, NULL); \ + DRAW_MOVE(w, h) + +#define INPUT(id, w, h, value, flags) CreateWindowA("EDIT", value, (WS_VISIBLE | WS_CHILD | ES_LEFT | WS_BORDER | WS_GROUP) | (flags), \ + DPIX(draw_x), DPIY(draw_y), DPIX(w), DPIY(h), \ + hwnd, (HMENU)id, ((LPCREATESTRUCT)lParam)->hInstance, NULL); \ + DRAW_MOVE(w, h) + + +#define DRAW_DIRECTION_DOWN draw_direction = 0 +#define DRAW_DIRECTION_RIGHT draw_direction = 1 + +#define VSPACE draw_y += LINE_QL + +typedef UINT (WINAPI *GetDpiForWindowFunc)(HWND hwnd); + +UINT GetDpiForWindowDynamic(HWND hwnd) +{ + GetDpiForWindowFunc GetDpiForWindowProc = NULL; + HMODULE user32 = GetModuleHandleA("user32.dll"); + + if(user32) + { + GetDpiForWindowProc = (GetDpiForWindowFunc)GetProcAddress(user32, "GetDpiForWindow"); + } + + if(GetDpiForWindowProc) + { + return GetDpiForWindowProc(hwnd); + } + + return 0; +} + +void softgpu_window_create(HWND hwnd, LPARAM lParam) +{ + static char dxname[250]; + + int draw_x = 0; + int draw_y = 0; + int draw_direction = 0; + int saved_y = 0; + + + UINT dpi10 = GetDpiForWindowDynamic(hwnd); + if(dpi10 != 0) + { + rdpiX = dpi10 / 96.0f; + rdpiY = dpi10 / 96.0f; + } + + if(version_compare(&sysver, &WINVER98) >= 0) + { + version_parse(iniValue("[softgpu]", "dx9target"), &dxtarget); + strcpy(dxname, "Install DirectX 9"); + } + else + { + version_parse(iniValue("[softgpu]", "dx8target"), &dxtarget); + strcpy(dxname, "Install DirectX 8"); + } + + DRAW_DIRECTION_DOWN; + + draw_x = DRAW_START_X; + draw_y = DRAW_START_Y; + + CHECKBOX(CHBX_GL95, LINE_WIDTH, LINE_HEIGHT, "Install OpenGL 95"); + CHECKBOX(CHBX_MSCRT, LINE_WIDTH, LINE_HEIGHT, "Install MSVCRT"); + CHECKBOX(CHBX_DX, LINE_WIDTH, LINE_HEIGHT, dxname); + + VSPACE; + + RADIO(RAD_NORMAL, LINE_WIDTH, LINE_HEIGHT, "Install MMX binaries", WS_GROUP); + RADIO(RAD_SSE, LINE_WIDTH, LINE_HEIGHT, "Install SSE3 binaries", 0); + RADIO(RAD_SSE4, LINE_WIDTH, LINE_HEIGHT, "Install SSE4.2 binaries", 0); + + VSPACE; + + CHECKBOX(CHBX_WINE, LINE_WIDTH, LINE_HEIGHT, "Install DirectX wrapper"); + CHECKBOX(CHBX_GLIDE, LINE_WIDTH, LINE_HEIGHT, "Install Glide wrapper"); + CHECKBOX(CHBX_SIMD95, LINE_WIDTH, LINE_HEIGHT, "Enable SSE/AVX hack"); + CHECKBOX(CHBX_FIXES, LINE_WIDTH, LINE_HEIGHT, "Apply compatibility fixes"); + + saved_y = draw_y; + + draw_x = DRAW_START_X+LINE_WIDTH; + draw_y = DRAW_START_Y; + + RADIO(RAD_DD_HAL, LINE_WIDTH+50, LINE_HEIGHT, "Native HAL for DX <= 7 (2D only, no 3D!)", WS_GROUP); + RADIO(RAD_DD_WINE, LINE_WIDTH, LINE_HEIGHT, "Wine for DX <= 7", 0); + + VSPACE; + + RADIO(RAD_D8_WINE, LINE_WIDTH-30, LINE_HEIGHT, "Wine for DX 8", WS_GROUP); + RADIO(RAD_D8_NINE, LINE_WIDTH-20, LINE_HEIGHT, "Nine for DX 8 (experimental)", 0); + + VSPACE; + + RADIO(RAD_D9_WINE, LINE_WIDTH-30, LINE_HEIGHT, "Wine for DX 9", WS_GROUP); + RADIO(RAD_D9_NINE, LINE_WIDTH-20, LINE_HEIGHT, "Nine for DX 9 (experimental)", 0); + + VSPACE; + + DRAW_DIRECTION_RIGHT; + LABEL(0, 120, LINE_HEIGHT, "VRAM limit (MB): "); + INPUT(INP_VRAM_LIMIT, 50, LINE_HEIGHT, "", 0) + + draw_x = DRAW_START_X+LINE_WIDTH; + draw_y += LINE_HEIGHT + LINE_HL; + + LABEL(0, 120, LINE_HEIGHT, "GMR limit (MB): "); + INPUT(INP_GMR_LIMIT, 50, LINE_HEIGHT, "", 0) + + draw_x = DRAW_START_X+LINE_WIDTH*2; + draw_y = DRAW_START_Y+LINE_HEIGHT*2; + DRAW_DIRECTION_DOWN; + + // third column + BUTTON(BTN_ABOUT, LINE_QWIDTH, LINE_HEIGHT, "About", 0); + VSPACE; + BUTTON(BTN_README, LINE_QWIDTH, LINE_HEIGHT, "Readme", 0); + VSPACE; + BUTTON(BTN_SYSINFO, LINE_QWIDTH, LINE_HEIGHT, "Sys. info", 0); + VSPACE; + BUTTON(BTN_WGLTEST, LINE_QWIDTH, LINE_HEIGHT, "WGL test", 0); + VSPACE; + BUTTON(BTN_GLCHECKER, LINE_QWIDTH, LINE_HEIGHT, "GLChecker", 0); + + draw_x = DRAW_START_X; + draw_y = saved_y+LINE_HL; + + // BUGS + DRAW_DIRECTION_RIGHT; + LABEL(0, 160, LINE_HEIGHT, "HV bugs override:"); + + CHECKBOX(CHBX_BUG_DX_FLAGS, LINE_HWIDTH+40, LINE_HEIGHT, "DX flags (VBox <= 7.0.14)"); + CHECKBOX(CHBX_BUG_PREFER_FIFO, LINE_HWIDTH+20, LINE_HEIGHT, "Prefer FIFO (VMware)"); + + draw_y += LINE_HEIGHT; + draw_x = DRAW_START_X + 160; + + CHECKBOX(CHBX_BUG_RGB565, LINE_WIDTH2, LINE_HEIGHT, "RGB565 (VBox < 7.0.10, VBox < 6.1.46)"); + + draw_x = DRAW_START_X; + draw_y += LINE_HEIGHT + LINE_QL; + DRAW_DIRECTION_DOWN; + + // Resolutions + DRAW_DIRECTION_RIGHT; + LABEL(0, 160, LINE_HEIGHT, "Resolutions > FullHD:"); + CHECKBOX(CHBX_QXGA, LINE_QWIDTH, LINE_HEIGHT, "QXGA"); + CHECKBOX(CHBX_1440, LINE_QWIDTH, LINE_HEIGHT, "1440p"); + CHECKBOX(CHBX_4K, LINE_QWIDTH, LINE_HEIGHT, "4K"); + CHECKBOX(CHBX_5K, LINE_QWIDTH, LINE_HEIGHT, "5K"); + + // path and install + draw_x = DRAW_START_X; + draw_y += LINE_HEIGHT + LINE_HL; + + DRAW_DIRECTION_RIGHT; + + LABEL(0, 100, LINE_HEIGHT, "Install path:"); + //draw_x += 20; + pathinput = INPUT(INP_PATH, LINE_WIDTH*2-100-20, LINE_HEIGHT, iniValue("[softgpu]", "defpath"), WS_TABSTOP); + draw_x += 20; + BUTTON(BTN_BROWSE, LINE_QWIDTH, LINE_HEIGHT, "Browse", WS_TABSTOP); + + draw_x = DRAW_START_X; + draw_y += LINE_HEIGHT + LINE_QL; + + BUTTON(BTN_EXIT, LINE_QWIDTH, LINE_HEIGHT, "Exit", WS_TABSTOP); + draw_x += 20; + CHECKBOX(CHBX_NO_INSTALL, LINE_WIDTH*2 - 2*20-LINE_QWIDTH, LINE_HEIGHT, "Don't install driver, only copy files"); + draw_x += 20; + + if(!isNT) + { + installbtn = BUTTON(BTN_INSTALL, LINE_QWIDTH, LINE_HEIGHT*2+LINE_QL, "Install!", WS_TABSTOP); + SetFocus(installbtn); + } + else + { + BUTTON(BTN_INSTALL, LINE_QWIDTH, LINE_HEIGHT*2+LINE_QL, "Install!", WS_DISABLED); + } + + draw_x = DRAW_START_X; + draw_y += LINE_HEIGHT + LINE_QL; + + BUTTON(BTN_DEFAULTS, LINE_QWIDTH, LINE_HEIGHT, "Defaults", 0); + draw_x += 20; + + infobox = LABEL_CENTER(0, LINE_WIDTH*2 - 2*20 - LINE_QWIDTH, LINE_HEIGHT, "https://github.com/JHRobotics/softgpu"); + +#if 0 // EXTRA_INFO + CreateWindowA("STATIC", EXTRA_INFO, + WS_VISIBLE | WS_CHILD | SS_RIGHT | WS_DISABLED, + DPIX(DRAW_START_X+LINE_WIDTH+10), DPIY(DRAW_START_Y-5 + 0*LINE_HEIGHT), DPIX(200), DPIY(LINE_HEIGHT), + hwnd, (HMENU)0, ((LPCREATESTRUCT)lParam)->hInstance, NULL); +#endif + + softgpu_set(hwnd); +} + +void softgpu_loading_create(HWND hwnd, LPARAM lParam) +{ + CreateWindowA("STATIC", "Inspecting system...\n\nPlease stand by!", + WS_VISIBLE | WS_CHILD | SS_CENTER, + DPIX(0), DPIY(80), DPIX(400), DPIY(LINE_HEIGHT*3), + hwnd, (HMENU)0, ((LPCREATESTRUCT)lParam)->hInstance, NULL); +} + +void softgpu_browser(const char *url) +{ + ShellExecuteA(NULL, "open", url, NULL, NULL, SW_SHOW); +} diff --git a/windrv.c b/windrv.c index 8d5f749..d004870 100644 --- a/windrv.c +++ b/windrv.c @@ -133,7 +133,7 @@ void version_parse(const char *version_str, version_t *out) * v1 == v2 => 0 * v1 > v2 => positive */ -int version_compare(version_t *v1, version_t *v2) +int version_compare(const version_t *v1, const version_t *v2) { int r = v1->major - v2->major; if(r == 0) diff --git a/windrv.h b/windrv.h index 2702b13..2c44fef 100644 --- a/windrv.h +++ b/windrv.h @@ -13,7 +13,7 @@ typedef struct _version_t } version_t; void version_parse(const char *version_str, version_t *out); -int version_compare(version_t *v1, version_t *v2); +int version_compare(const version_t *v1, const version_t *v2); void version_win(version_t *v); BOOL version_is_nt(); DWORD checkInstallation(); diff --git a/winreg.c b/winreg.c index 5d9cf51..3dbcb9c 100644 --- a/winreg.c +++ b/winreg.c @@ -230,3 +230,35 @@ BOOL registryWriteDWORD(const char *path, DWORD dw) sprintf(buf, "%lu", dw); return registryWrite(path, buf, WINREG_DWORD); } + + +BOOL registryDelete(const char *path) +{ + HKEY rootkey; + const char *key; + const char *subkey; + BOOL rc = FALSE; + + //printf("deleting key: %s ", path); + + if(registrySplitPath(path, &rootkey, &key, &subkey)) + { + HKEY hKey; + LSTATUS lResult = -1; + + //lResult = RegCreateKeyA(rootkey, key, &hKey); + lResult = RegOpenKeyEx(rootkey, key, 0, KEY_READ | KEY_WRITE, &hKey); + if(lResult == ERROR_SUCCESS) + { + if(RegDeleteValueA(hKey, subkey) == ERROR_SUCCESS) + { + rc = TRUE; + } + } + RegCloseKey(hKey); + } + + //printf("was: %d\n", rc); + + return rc; +} \ No newline at end of file diff --git a/winreg.h b/winreg.h index 6e95872..ad9a282 100644 --- a/winreg.h +++ b/winreg.h @@ -5,6 +5,7 @@ BOOL registryRead(const char *path, char *buffer, size_t buffer_size); BOOL registryReadDWORD(const char *path, DWORD *out); BOOL registryWrite(const char *path, const char *str, int type); BOOL registryWriteDWORD(const char *path, DWORD dw); +BOOL registryDelete(const char *path); #define WINREG_DWORD 1 #define WINREG_STR 2 diff --git a/winres.c b/winres.c new file mode 100644 index 0000000..019c8e2 --- /dev/null +++ b/winres.c @@ -0,0 +1,82 @@ +#include +#include +#include +#include +#include "nocrt.h" + +#include "winres.h" + +#include "setuperr.h" + +BOOL is_wrapper(const char *dll, BOOL need_exists) +{ + DWORD cbRes = 0; + DWORD dwHandle = 0; + void *res; + char strbuf[255]; + int cnt = 0; + BOOL rc = FALSE; + + cbRes = GetFileVersionInfoSizeA(dll, &dwHandle); + if(cbRes > 0) + { + res = malloc(cbRes); + if(res != NULL) + { + if(GetFileVersionInfoA(dll, dwHandle, cbRes, res)) + { + struct LANGANDCODEPAGE { + WORD wLanguage; + WORD wCodePage; + } *lpTranslate; + UINT cbTranslate; + UINT i; + + VerQueryValueA(res, "\\VarFileInfo\\Translation", (LPVOID *)&lpTranslate, &cbTranslate); + + for(i = 0; i < (cbTranslate/sizeof(struct LANGANDCODEPAGE)); i++) + { + void *desc; + UINT descLen; + + sprintf(strbuf, "\\StringFileInfo\\%04x%04x\\ProductName", lpTranslate[i].wLanguage, lpTranslate[i].wCodePage); + if(VerQueryValue(res, strbuf, &desc, &descLen)) + { + if(descLen < sizeof(strbuf)) + { + memcpy(strbuf, desc, descLen); + strbuf[descLen] = '\0'; + //printf("ProductName (%u): %s\n", descLen, strbuf); + if(strstr(strbuf, "WINE") != NULL) + { + rc = TRUE; + } + else if(strstr(strbuf, "wine") != NULL) + { + rc = TRUE; + } + } + + cnt++; + } + } + } + + free(res); + + /* no info, this is probably wrapper... */ + if(cnt == 0) + { + rc = TRUE; + } + + } + } + else if(need_exists) + { + return TRUE; + } + + return rc; +} + diff --git a/winres.h b/winres.h new file mode 100644 index 0000000..c033555 --- /dev/null +++ b/winres.h @@ -0,0 +1,6 @@ +#ifndef __WINRES_H__INCLUDED__ +#define __WINRES_H__INCLUDED__ + +BOOL is_wrapper(const char *dll, BOOL need_exists); + +#endif /* __WINREG_H__INCLUDED__ */