diff --git a/.gitignore b/.gitignore index b08d376..04d64b1 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ # generated and temporary files *.o *.bak +*.backup *.tmp *.gen *.exe diff --git a/Makefile b/Makefile index ed1c997..d6be10a 100644 --- a/Makefile +++ b/Makefile @@ -6,6 +6,7 @@ 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 SOFTGPU_PATCH=2023 diff --git a/README.md b/README.md index 36eeb12..9c22b44 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # SoftGPU: SW and HW accelerated driver for Windows 9x Virtual Machines -![SoftGPU animated logo](/resource/softgpu.webp) +![SoftGPU animated logo](resource/softgpu.webp) This is ready-to-use compilation of my 4 projects: - VMDisp9x: https://github.com/JHRobotics/vmdisp9x @@ -19,6 +19,18 @@ This is ready-to-use compilation of my 4 projects: - Visual C runtime (version 6 included in package) - OpenGL 95 for versions without `opengl32.dll` (included in package) +## Feature support + +| Hypervisor | Version | Adapter | VGA driver | 32 bpp | 16 bpp | 8 bpp | HW 3D | Sound drivers | +| :----------------- | :--------: | :-----: | :---------: | :----: | :----: | :----: | :-----: | :---------------- | +| Oracle VirtualBox | 6.1, 7.0 | VboxVGA | ✔ | ✔ | ✔ | ✔ | ❌ | SB16, AC97 | +| Oracle VirtualBox | 6.1, 7.0 | VboxSVGA | ✔ | ✔ | ✔ | ✔ | ✔ | SB16, AC97 | +| Oracle VirtualBox | 6.1, 7.0 | VMSVGA | ✔ | ✔ | ✔ | ✔ | ✔ | SB16, AC97 | +| VMware Workstation | 17 | - | ✔ | ✔ | ✔ | ⚠ | ✔ | SBPCI128 | +| QEMU | 7.x, 8.0 | std | ✔ | ✔ | ✔ | ✔ | ❌ | adlib, SB16, AC97 | +| QEMU | 7.x, 8.0 | vmware | ✔ | ✔ | ❌ | ❌ | ❌ | adlib, SB16, AC97 | + + ## Download ISO image or ZIP package can be downloaded on release page: https://github.com/JHRobotics/softgpu/releases/ @@ -27,8 +39,8 @@ ISO image or ZIP package can be downloaded on release page: https://github.com/J 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 soundcard) and USB (if you added USB controller) -5) [only if you have AC97 soundcard] Reinstall DirectX again = AC97 replacing some DX files, but they are not working with newer DX versions +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! ## VirtualBox VM setup with HW acceleration @@ -73,6 +85,101 @@ 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 +## WMware 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 +- 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, mouse integration driver and tray program which immediately replaces display driver with VMware one. If you want mouse integration driver (but is useless for gaming with mouse) alone driver is listed below. +- 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 +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) + +![](resource/docs/vmw-setup-1.png) + + - Select *I will install the operating system later.* + - As *Guest operating system* choice **Microsoft Windows** and as *Version* select **Windows 2000 Server** (important) + +![](resource/docs/vmw-setup-2.png) + + - Type VM name and number of processors keep on *1* + - Set the memory to 512 MB (but without additional patches not more!) + - Network choice is your own (default NAT should work all cases) and SCSI Controller keep on **BusLogic** + - set *Virtual disk type* to **IDE** (important) + - create new virtual disk and set space at last at 20 GB (but lower than 127 GB without extra patches!) + - type or keep HDD file name and at last page before finish click on *Customize Hardware* +3) Now VM needs to be a bit reconfigure: + - click on *Add...* and **Floppy drive** + +![](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) + + - (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. + - (optional) click on Floppy and point *Use floppy image file* to your boot floppy (only if you plan boot floppy) +4) Click on *Close*, *Finish* and Power on machine + - TIP: if you wish customize boot order, right click on the new VM, choose *Power* and *Power on to Firmware* - VM will boot to environment very close to common PC BIOS. + +![](resource/docs/vmw-bios.png) + +5) Install the Windows 98 - this step is really pain, VMware VM in BIOS VGA mode is hyper slow and mouse isn't usable - you have navigate through installation by keyboard (`TAB`, `Shift`+`TAB`, cursor keys, `Enter`). + - TIP: apply [patcher9x](https://github.com/JHRobotics/patcher9x). If you have Intel 11th gen. CPU or newer or AMD Ryzen (any model) or other AMD ZEN architecture CPU and newer, this is necessary. +6) After installation isn't system very usable until you'll install GPU driver! So, insert **SoftGPU iso** (can be downloaded in Releases) and run `softgpu.exe`. +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! + +![VMware HID devices disabled](resource/docs/vmw-hid.png) + +11) Use `glchecker.exe` to verify settings + +## 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. + +### 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) + +2) With this device selected click on *Properties*, select *Driver* tab and click on *Update driver* + +![QEMU PCI: Plug and Play BIOS properties](resource/docs/qemu-pci-2.png) + +3) In Wizard select second option (*Display a list of all drivers in specific location, ...*) + +![QEMU PCI: list drivers](resource/docs/qemu-pci-3.png) + +4) Select *Show all hadrware* and from models list choose **PCI bus**, click on *next*, confirm +warning message and reboot computer. + +![QEMU PCI: select PCI bus](resource/docs/qemu-pci-4.png) +![QEMU PCI: warning message](resource/docs/qemu-pci-5.png) + +5) After reboot, system will ask you for drive on every new discovered device. All you need to do, is select *Search for the best driver...* and clicking on *next*. Please don't select new or updated drivers here - you can do it later. You may need reboot computer several times. + +![QEMU PCI: new PCI device](resource/docs/qemu-pci-6.png) +![QEMU PCI: select best driver](resource/docs/qemu-pci-7.png) + +6) You will be asked for VGA driver and unknown device drivers. Still select default generic driver here! + +![QEMU PCI: standard PCI VGA](resource/docs/qemu-pci-8.png) +![QEMU PCI: unknown device](resource/docs/qemu-pci-9.png) + +7) After last reboot open *Device manager* again - as you see, you have 2 VGA cards now, so select *Standard Display Adapter (VGA)* (the working one) and click on *Remove*. + +![QEMU PCI: 2 VGA adapters](resource/docs/qemu-vga.png) + +8) After reboot (again), you have working system now and you can install SoftGPU and other drivers. + ## Bugs Currently there are known these limitations: @@ -87,11 +194,53 @@ There are many bugs in individual components, please post them to individual rep But still, please be patient. SoftGPU compatibility target is about a decade of intensive HW and SW development (from DOS direct VGA/VESA access, SW rendering through GDI, DirectDraw, OpenGL, Glide, DirectX, OpenGL again). After all, there will still applications that cannot be run anyway because there are written for very individual SW/HW combinations. +## General tips +There are some tips without direct relation to SoftGPU but they can improve the user experience with MS Windows 9x OS. + +### Fresh install +Prefer new installation over copy older installations done on different (even virtual) HW. + +### Copy Installation to HDD before run setup +If you installed Windows 9x from CD, on near every system change your will be asked to insert Install CD. You can avoid it if you prepare HDD manually, copy installation from CD and run `setup.exe` from `C:` drive. + +All utilities you need are on [patcher9x](https://github.com/JHRobotics/patcher9x) boot floppy. The short procedure follows: + +- insert *patcher9x* floppy to floppy driver and Windows Installation CD to CD driver. Boot from floppy drive +- run `fdisk` and create primary dos partition (it wizard type program, just keep pressing `1`, `Y` and finally `ESC`). +- reboot after `fdisk` finish +- format HDD, copy files, install necessary patches and run the setup using following commands: +``` +format C: +xcopy /v D:\win98\ C:\install\win98\ +patch9x C:\install\win98 -auto +C: +cd install\win98 +setup /ie /nm +``` +Explanation: The `/v` switch with `xcopy` means *verify*. The `/ie` switch with `setup` means *skip recovery floppy creation* and `/nm` means *no machine check* - this is necessary because in Patcher9x boot floppy is using FreeDOS and MS setup program cannot determine RAM size without MS memory manager. + +Now *setup* automatically runs `scandisk` and after complete it you can continue with installer GUI. You can also remove floppy and CD from drive at this point. + +### Turn on DMA +Windows by default using interrupts to access HDD and CD drive. This is especially slow in the HW accelerated virtual machines because every interrupt will stop executing visualisation engine and hand over access to hypervisor to solve it and after that it'll be need to restart visualisation engine again. Time consumed by interrupts depends on visualization technology for example in QEMU + kvm is HDD access very slow equally VirtualBox + Hyper-V and combination QEMU + Hyper-V is downright painful. Fortunately there is DMA transfer of whole memory block instead of individual bytes. Unfortunately you have to enable it manually. + +You can turn it on in Device Manager on HDD properties enable `DMA` checkbox. Do it the same for CD driver and reboot VM for applying changes. + +![setting DMA access to HDD](resource/docs/dma.png) + + +### Change logon to Windows Logon + +After install network card you are asked every time to enter the credentials - but this is not credentials to the computer but to the network (you can also skip this by press `ESC`). If you don't plan to install NT server as other VM and runs ancient network sharing, this is only annoying thing. You can turn it off in *Control panel* -> *Network* and change *Primary network logon* to **Windows Logon**. + +![Windows logon switch](resource/docs/windows-logon.png) + + ## Compilation from source 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` -4) Compile VMDisp9x and copy files `boxvmini.drv`, `vmwsmini.drv`, `vmwsmini.vxd`, `vmdisp9x.inf` and place them to `driver/win95` and `driver/win98me` folder +4) Compile VMDisp9x and copy files `boxvmini.drv`, `vmwsmini.drv`, `qemumini.drv`, `vmwsmini.vxd`, `vmdisp9x.inf` and place them to `driver/win95` and `driver/win98me` folder 5) Compile Mesa9x for Windows 95 (e.g., without SSE) and copy and rename files to following schema - `vmwsgl32.dll` => `driver/win95/vmwsgl32.dll` - `opengl32.w98me.dll` => `driver/win95/extra/opengl32.dll` diff --git a/actions.c b/actions.c index b8754ae..94cddd7 100644 --- a/actions.c +++ b/actions.c @@ -317,6 +317,7 @@ BOOL proc_wait(HWND hwnd) extern version_t sysver; extern version_t WINVER98SE; +extern version_t WINVER98; void install_infobox(HWND hwnd, const char *name) { @@ -375,9 +376,16 @@ BOOL setup_end(HWND hwnd) BOOL driver_without_setupapi(HWND hwnd) { static char mgsbuf[512]; - sprintf(mgsbuf, "Automatic instalation isn't possible, because it is unsupported on this system. You have to install driver manually!\n\nDriver files are located here: %s", install_path); - - MessageBoxA(hwnd, mgsbuf, "No automatic driver install", MB_ICONWARNING); + if(version_compare(&sysver, &WINVER98) >= 0) + { + sprintf(mgsbuf, "Driver files are located here: %s", install_path); + MessageBoxA(hwnd, mgsbuf, "No automatic driver install", MB_ICONWARNING); + } + else + { + sprintf(mgsbuf, "Automatic instalation isn't possible, because it is unsupported on this system. You have to install driver manually!\n\nDriver files are located here: %s", install_path); + MessageBoxA(hwnd, mgsbuf, "No automatic driver install", MB_ICONWARNING); + } return TRUE; } @@ -464,6 +472,10 @@ BOOL filescopy_result(HWND hwnd) 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; BOOL setLineSvga(char *buf, size_t bufs) { @@ -501,15 +513,44 @@ BOOL setLineVbox(char *buf, size_t bufs) return TRUE; } +BOOL setLineQemu(char *buf, size_t bufs) +{ + (void)bufs; + + strcpy(buf, "CopyFiles=Qemu.Copy"); + if(install_wine) + { + strcat(buf, ",Dx.Copy,DX.CopyBackup"); + } + + if(install_glide) + { + strcat(buf, ",Voodoo.Copy"); + } + + return TRUE; +} + BOOL setLineSvgaReg(char *buf, size_t bufs) { (void)bufs; strcpy(buf, "AddReg=VMSvga.AddReg,VM.AddReg"); + if(install_wine) - { strcat(buf, ",DX.addReg"); - } + + if(install_res_qxga) + strcat(buf, ",VM.QXGA"); + + if(install_res_1440) + strcat(buf, ",VM.WQHD"); + + if(install_res_4k) + strcat(buf, ",VM.UHD"); + + if(install_res_5k) + strcat(buf, ",VM.R5K"); return TRUE; } @@ -520,18 +561,53 @@ BOOL setLineVboxReg(char *buf, size_t bufs) strcpy(buf, "AddReg=VBox.AddReg,VM.AddReg"); if(install_wine) - { strcat(buf, ",DX.addReg"); - } + + if(install_res_qxga) + strcat(buf, ",VM.QXGA"); + + if(install_res_1440) + strcat(buf, ",VM.WQHD"); + + if(install_res_4k) + strcat(buf, ",VM.UHD"); + + if(install_res_5k) + strcat(buf, ",VM.R5K"); + + return TRUE; +} + +BOOL setLineQemuReg(char *buf, size_t bufs) +{ + (void)bufs; + + strcpy(buf, "AddReg=Qemu.AddReg,VM.AddReg"); + if(install_wine) + strcat(buf, ",DX.addReg"); + + if(install_res_qxga) + strcat(buf, ",VM.QXGA"); + + if(install_res_1440) + strcat(buf, ",VM.WQHD"); + + if(install_res_4k) + strcat(buf, ",VM.UHD"); + + if(install_res_5k) + strcat(buf, ",VM.R5K"); return TRUE; } linerRule_t infFixRules[] = { - {"CopyFiles=VBox.Copy,Dx.Copy,DX.CopyBackup,Voodoo.Copy", TRUE, TRUE, setLineVbox}, + {"CopyFiles=VBox.Copy,Dx.Copy,DX.CopyBackup,Voodoo.Copy", TRUE, TRUE, setLineVbox}, {"CopyFiles=VMSvga.Copy,Dx.Copy,DX.CopyBackup,Voodoo.Copy", TRUE, TRUE, setLineSvga}, - {"AddReg=VBox.AddReg,VM.AddReg,DX.addReg", TRUE, TRUE, setLineVboxReg}, - {"AddReg=VMSvga.AddReg,VM.AddReg,DX.addReg", TRUE, TRUE, setLineSvgaReg}, + {"CopyFiles=Qemu.Copy,Dx.Copy,DX.CopyBackup,Voodoo.Copy", TRUE, TRUE, setLineQemu}, + {"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}, {NULL, FALSE, FALSE, NULL} }; @@ -581,6 +657,7 @@ BOOL simd95(HWND hwnd) liner("C:\\autoexec.bak", "C:\\autoexec.bat", simd95rules); } + addLine("C:\\autoexec.bat", "REM Added by SOFTGPU = simd95.com = enable SSE/AVX\r\n"); addLine("C:\\autoexec.bat", "C:\\simd95.com\r\n"); } diff --git a/actions.h b/actions.h index cfbb396..6c38d3f 100644 --- a/actions.h +++ b/actions.h @@ -70,6 +70,10 @@ 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; BOOL simd95(HWND hwnd); BOOL infFixer(HWND hwnd); diff --git a/changelog.txt b/changelog.txt index b194ed7..3fdb177 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,13 @@ +0.4.2023.13 +! QEMU display driver works +- Mesa 21.3.8 +- VMware 3D support (see README) +- optimalizations in VMware SVGA driver +- frame buffer fixes (fewer black screens when switching color depth) +- fixed memory allocator +- SIMD95 is disabled by default +- Optional resolution above FullHD sets + 0.4.2023.11 ! R5G6B5 surface workaround - fixed black screen on (mostly) NVIDIA GPUs - large Wine (DirectX) update diff --git a/resource/docs/dma.png b/resource/docs/dma.png new file mode 100644 index 0000000..6bcb3ea Binary files /dev/null and b/resource/docs/dma.png differ diff --git a/resource/docs/qemu-pci-1.png b/resource/docs/qemu-pci-1.png new file mode 100644 index 0000000..5430ca9 Binary files /dev/null and b/resource/docs/qemu-pci-1.png differ diff --git a/resource/docs/qemu-pci-2.png b/resource/docs/qemu-pci-2.png new file mode 100644 index 0000000..ea653f2 Binary files /dev/null and b/resource/docs/qemu-pci-2.png differ diff --git a/resource/docs/qemu-pci-3.png b/resource/docs/qemu-pci-3.png new file mode 100644 index 0000000..a46cd82 Binary files /dev/null and b/resource/docs/qemu-pci-3.png differ diff --git a/resource/docs/qemu-pci-4.png b/resource/docs/qemu-pci-4.png new file mode 100644 index 0000000..9a849fb Binary files /dev/null and b/resource/docs/qemu-pci-4.png differ diff --git a/resource/docs/qemu-pci-5.png b/resource/docs/qemu-pci-5.png new file mode 100644 index 0000000..6b27238 Binary files /dev/null and b/resource/docs/qemu-pci-5.png differ diff --git a/resource/docs/qemu-pci-6.png b/resource/docs/qemu-pci-6.png new file mode 100644 index 0000000..02213bf Binary files /dev/null and b/resource/docs/qemu-pci-6.png differ diff --git a/resource/docs/qemu-pci-7.png b/resource/docs/qemu-pci-7.png new file mode 100644 index 0000000..53f0a0f Binary files /dev/null and b/resource/docs/qemu-pci-7.png differ diff --git a/resource/docs/qemu-pci-8.png b/resource/docs/qemu-pci-8.png new file mode 100644 index 0000000..bb6147b Binary files /dev/null and b/resource/docs/qemu-pci-8.png differ diff --git a/resource/docs/qemu-pci-9.png b/resource/docs/qemu-pci-9.png new file mode 100644 index 0000000..fda3281 Binary files /dev/null and b/resource/docs/qemu-pci-9.png differ diff --git a/resource/docs/qemu-vga.png b/resource/docs/qemu-vga.png new file mode 100644 index 0000000..ae981ad Binary files /dev/null and b/resource/docs/qemu-vga.png differ diff --git a/resource/docs/vmw-bios.png b/resource/docs/vmw-bios.png new file mode 100644 index 0000000..573e79c Binary files /dev/null and b/resource/docs/vmw-bios.png differ diff --git a/resource/docs/vmw-hid.png b/resource/docs/vmw-hid.png new file mode 100644 index 0000000..67126d8 Binary files /dev/null and b/resource/docs/vmw-hid.png differ diff --git a/resource/docs/vmw-setup-1.png b/resource/docs/vmw-setup-1.png new file mode 100644 index 0000000..c47a9c0 Binary files /dev/null and b/resource/docs/vmw-setup-1.png differ diff --git a/resource/docs/vmw-setup-2.png b/resource/docs/vmw-setup-2.png new file mode 100644 index 0000000..44bceb2 Binary files /dev/null and b/resource/docs/vmw-setup-2.png differ diff --git a/resource/docs/vmw-setup-3.png b/resource/docs/vmw-setup-3.png new file mode 100644 index 0000000..f35cdb5 Binary files /dev/null and b/resource/docs/vmw-setup-3.png differ diff --git a/resource/docs/vmw-setup-4.png b/resource/docs/vmw-setup-4.png new file mode 100644 index 0000000..ac20ff9 Binary files /dev/null and b/resource/docs/vmw-setup-4.png differ diff --git a/resource/docs/windows-logon.png b/resource/docs/windows-logon.png new file mode 100644 index 0000000..cd2bf27 Binary files /dev/null and b/resource/docs/windows-logon.png differ diff --git a/softgpu.c b/softgpu.c index d4b177f..087b0ca 100644 --- a/softgpu.c +++ b/softgpu.c @@ -36,7 +36,7 @@ #include "winreg.h" #include "actions.h" - +#include "setuperr.h" #include "softgpuver.h" #include "nocrt.h" @@ -66,6 +66,7 @@ void about(HWND hwnd) "Components\n" "VMDisp9x: %s\n" "Mesa9x: %s\n" + "Mesa9x (SSE): %s\n" "Wine9x: %s\n" "OpenGlide9x: %s\n" "SIMD95: %s\n\n" @@ -73,6 +74,7 @@ void about(HWND hwnd) SOFTGPU_VERSION_STR, iniValue("[version]", "vmdisp9x"), iniValue("[version]", "mesa9x"), + iniValue("[version]", "mesa9x_sse"), iniValue("[version]", "wine9x"), iniValue("[version]", "openglide9x"), iniValue("[version]", "simd95") @@ -93,12 +95,19 @@ void about(HWND hwnd) #define CHBX_GLIDE 8 #define CHBX_SIMD95 9 #define CHBX_FIXES 10 -#define CHBX_IE 11 +//#define CHBX_IE 11 + +#define BTN_EXIT 11 +#define BTN_INSTALL 12 +#define CHBX_GL95 13 +#define BTN_ABOUT 14 -#define BTN_EXIT 12 -#define BTN_INSTALL 13 -#define CHBX_GL95 14 -#define BTN_ABOUT 15 +#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; @@ -107,20 +116,25 @@ typedef struct _settings_item_t { DWORD menu; DWORD pos; + BOOL negate; } settings_item_t; const settings_item_t settings[] = { - {CHBX_MSCRT, 0}, - {CHBX_DX, 1}, - {RAD_NORMAL, 2}, - {CHBX_WINE, 3}, - {CHBX_GLIDE, 4}, - {CHBX_SIMD95, 5}, - {CHBX_FIXES, 6}, - {BTN_ABOUT, 7}, - {CHBX_GL95, 8}, - {0, 0} + {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; @@ -133,7 +147,9 @@ DWORD settings_data = 0; #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 #define LINE_WIDTH2 350 @@ -148,9 +164,10 @@ version_t sysver = {0}; static version_t dxver = {0}; static BOOL hasCRT = FALSE; static BOOL hasSETUPAPI = FALSE; -static uint32_t hasSSE2 = 0; +static uint32_t hasSSE = 0; static uint32_t hasAVX = 0; static BOOL hasOpengl = FALSE; +static DWORD drvPCstatus = CHECK_DRV_OK; static char sysinfomsg[1024]; @@ -162,6 +179,11 @@ static BOOL isSettingSet(DWORD menu) if(s->menu == menu) { DWORD p = ((settings_data) >> s->pos) & 0x1; + if(s->negate) + { + p = (~p) & 0x1; + } + if(p == 0) { return TRUE; @@ -184,7 +206,10 @@ static void writeSettings(HWND hwnd) for(s = &settings[0]; s->menu != 0; s++) { - if(!IsDlgButtonChecked(hwnd, s->menu)) + BOOL b = IsDlgButtonChecked(hwnd, s->menu); + if(s->negate) b = !b; + + if(!b) { new_data |= 1 << s->pos; } @@ -233,12 +258,15 @@ void readCPUInfo() "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" "movl $1, %0\n" "jmp end_sse\n" "not_supported_sse:\n" "movl $0, %0\n" "end_sse:\n" - "popa" : "=m" (hasSSE2)); + "popa" : "=m" (hasSSE)); } else { @@ -263,7 +291,7 @@ void readCPUInfo() "not_supported_sse95:\n" "movl $0, %0\n" "end_sse95:\n" - "popa" : "=m" (hasSSE2)); + "popa" : "=m" (hasSSE)); } } @@ -314,7 +342,7 @@ void softgpu_sysinfo() hasCRT ? "yes" : "no", hasSETUPAPI ? "yes" : "no", hasOpengl ? "yes" : "no", - hasSSE2 ? "yes" : "no", + hasSSE ? "yes" : "no", hasAVX ? "yes" : "no" ); } @@ -336,7 +364,7 @@ void softgpu_done(HWND hwnd) SetWindowText(infobox, "SUCCESS!"); - int id = MessageBox(hwnd, "Installation complete! Reboot is required. Reboot now?", "Complete!", MB_YESNO | MB_ICONQUESTION); + int id = MessageBoxA(hwnd, "Installation complete! Reboot is required. Reboot now?", "Complete!", MB_YESNO | MB_ICONQUESTION); if(id == IDYES) { need_reboot = TRUE; @@ -458,7 +486,7 @@ LRESULT CALLBACK softgpuWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara } CreateWindowA("BUTTON", "Install MSVCRT", - WS_VISIBLE | WS_CHILD | BS_AUTOCHECKBOX, + 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) @@ -484,16 +512,16 @@ LRESULT CALLBACK softgpuWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara /* SSE/non SSE instalation type */ CreateWindowA("BUTTON", "Install classical binaries", - WS_VISIBLE | WS_CHILD | BS_AUTORADIOBUTTON, - DPIX(DRAW_START_X), DPIY(DRAW_START_Y + 4*LINE_HEIGHT), DPIX(LINE_WIDTH), DPIY(LINE_HEIGHT), + 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 + 5*LINE_HEIGHT), DPIX(LINE_WIDTH), DPIY(LINE_HEIGHT), + 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) + if(version_compare(&sysver, &WINVER98) >= 0 && hasSSE) { CheckDlgButton(hwnd, RAD_SSE, BST_CHECKED); } @@ -503,8 +531,8 @@ LRESULT CALLBACK softgpuWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara } CreateWindowA("BUTTON", "Install DirectX wrapper (Wine9x)", - WS_VISIBLE | WS_CHILD | BS_AUTOCHECKBOX, - DPIX(DRAW_START_X), DPIY(DRAW_START_Y + 6*LINE_HEIGHT), DPIX(LINE_WIDTH), DPIY(LINE_HEIGHT), + 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)) { @@ -513,7 +541,7 @@ LRESULT CALLBACK softgpuWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara CreateWindowA("BUTTON", "Install Glide wrapper (OpenGlide9x)", WS_VISIBLE | WS_CHILD | BS_AUTOCHECKBOX, - DPIX(DRAW_START_X), DPIY(DRAW_START_Y + 7*LINE_HEIGHT), DPIX(LINE_WIDTH), DPIY(LINE_HEIGHT), + 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)) { @@ -522,10 +550,11 @@ LRESULT CALLBACK softgpuWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara HWND btnSIMD95 = CreateWindowA("BUTTON", "Enable SSE/AVX hack", WS_VISIBLE | WS_CHILD | BS_AUTOCHECKBOX, - DPIX(DRAW_START_X), DPIY(DRAW_START_Y + 8*LINE_HEIGHT), DPIX(LINE_WIDTH), DPIY(LINE_HEIGHT), + 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)) @@ -533,6 +562,7 @@ LRESULT CALLBACK softgpuWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara CheckDlgButton(hwnd, CHBX_SIMD95, BST_CHECKED); } } +#endif } else { @@ -542,64 +572,121 @@ LRESULT CALLBACK softgpuWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara CreateWindowA("BUTTON", "Apply compatibility enhacements", WS_VISIBLE | WS_CHILD | BS_AUTOCHECKBOX, - DPIX(DRAW_START_X), DPIY(DRAW_START_Y + 9*LINE_HEIGHT), DPIX(LINE_WIDTH), DPIY(LINE_HEIGHT), + 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", "Install path:", + CreateWindowA("STATIC", "Resolutions > FullHD:", WS_VISIBLE | WS_CHILD | SS_LEFT, - DPIX(DRAW_START_X), DPIY(DRAW_START_Y + 11*LINE_HEIGHT), DPIX(LINE_WIDTH), DPIY(LINE_HEIGHT), + 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, - DPIX(DRAW_START_X), DPIY(DRAW_START_Y + 12*LINE_HEIGHT), DPIX(LINE_WIDTH2), DPIY(LINE_HEIGHT), + 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, - DPIX(DRAW_START_X+LINE_WIDTH2+10), DPIY(DRAW_START_Y + 12*LINE_HEIGHT), DPIX(80), DPIY(LINE_HEIGHT), + 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, - DPIX(DRAW_START_X), DPIY(DRAW_START_Y + 14*LINE_HEIGHT), DPIX(80), DPIY(LINE_HEIGHT), + 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, - DPIX(DRAW_START_X+LINE_WIDTH2+10), DPIY(DRAW_START_Y + 14*LINE_HEIGHT), DPIX(80), DPIY(LINE_HEIGHT), + 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 + 14*LINE_HEIGHT), DPIX(80), DPIY(LINE_HEIGHT), + 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); } CreateWindowA("STATIC", sysinfomsg, - WS_VISIBLE | WS_CHILD | SS_LEFT | WS_BORDER , + WS_VISIBLE | WS_CHILD | SS_LEFT | WS_BORDER, DPIX(DRAW_START_X+LINE_WIDTH+10), DPIY(DRAW_START_Y + 0*LINE_HEIGHT), DPIX(200), DPIY(9*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 + 10*LINE_HEIGHT), DPIX(80), DPIY(LINE_HEIGHT), + 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 + 14*LINE_HEIGHT), DPIX(LINE_WIDTH2-80-10), DPIY(LINE_HEIGHT), + 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); + } + break; } case WM_COMMAND: @@ -679,12 +766,24 @@ LRESULT CALLBACK softgpuWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara install_wine = IsDlgButtonChecked(hwnd, CHBX_WINE); install_glide = IsDlgButtonChecked(hwnd, CHBX_GLIDE); + 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); + action_create("Files copy", filescopy_start, filescopy_wait, filescopy_result); action_create("Modify inf", infFixer, NULL, NULL); if(hasSETUPAPI && version_compare(&sysver, &WINVER98) >= 0) { - action_create("Driver installation", driver_install, NULL, NULL); + if(!IsDlgButtonChecked(hwnd, CHBX_NO_INSTALL)) + { + action_create("Driver installation", driver_install, NULL, NULL); + } + else + { + action_create("Driver installation", driver_without_setupapi, NULL, NULL); + } } else { @@ -763,6 +862,10 @@ int main(int argc, const char *argv[]) registryReadDWORD("HKCU\\SOFTWARE\\SoftGPU\\setup", &settings_data); hasSETUPAPI = loadSETUAPI(); + if(hasSETUPAPI) + { + drvPCstatus = checkInstallation(); + } softgpu_sysinfo(); @@ -796,21 +899,43 @@ 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(370), 0, 0, NULL, 0); + 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); if(isNT) { - MessageBox(win, "Your system is NT-based (eg. NT, 2k, XP, ..., 11). But this driver package is only for Windows 9x = 95, 98 and Me.\n\nIt can't work on any modern system. Sorry.", "Only for 9x", MB_ICONSTOP); + MessageBoxA(win, "Your system is NT-based (eg. NT, 2k, XP, ..., 11). But this driver package is only for Windows 9x = 95, 98 and Me.\n\nIt can't work on any modern system. Sorry.", "Only for 9x", MB_ICONSTOP); } else { + if(version_compare(&sysver, &WINVER98) >= 0) + { + if(drvPCstatus != CHECK_DRV_OK) + { + if(drvPCstatus & CHECK_DRV_NOPCI) + { + MessageBoxA(win, "No working PCI bus found! Without PCI bus installer and driver can't work!\n\nIf you're seeing this on QEMU, check REAME to solve this problem:\nhttps://github.com/JHRobotics/softgpu#qemu", "No PCI bus", MB_OK | MB_ICONHAND); + } + else if(drvPCstatus & CHECK_DRV_LEGACY_VGA) + { + MessageBoxA(win, "Found non PCI VGA adapter! This is probably result of the late PCI bus driver installation.\n\nPlease, remove this adapter first!\nMore on README in QEMU section:\nhttps://github.com/JHRobotics/softgpu#qemu", "Legacy non-PCI VGA adapter", MB_OK | MB_ICONHAND); + } + } + } + else + { + MessageBoxA(win, "In Windows 95 isn't available automatic installation. This program copy and set driver and you must manually install it from Device manager.", "Windows 95", MB_OK); + } + timer_proc(win); } while(GetMessage(&msg, NULL, 0, 0)) { - TranslateMessage(&msg); - DispatchMessage(&msg); + if (IsDialogMessage(win, &msg)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } } DestroyWindow(win); diff --git a/softgpu.ini b/softgpu.ini index 772d38c..c6a780e 100644 --- a/softgpu.ini +++ b/softgpu.ini @@ -31,10 +31,11 @@ glu95=redist\opengl95\DLL\GLU32.DLL ;ie98.ver=Internet Explorer 6.0 [version] -vmdisp9x=1.2023.0.4 -mesa9x=17.3.9.3 -wine9x=1.7.55.10 -openglide9x=0.1.2023.8 +vmdisp9x=1.2023.0.10 +mesa9x=17.3.9.17 +mesa9x_sse=21.3.8.17 +wine9x=1.7.55.12 +openglide9x=0.1.2023.9 simd95=1.0.0.0 [fixes] @@ -50,3 +51,5 @@ 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 + + diff --git a/windrv.c b/windrv.c index e17ab57..8d5f749 100644 --- a/windrv.c +++ b/windrv.c @@ -32,6 +32,7 @@ #include #include #include +#include /* CM_DEVCAP_Xxx constants */ #include "windrv.h" #include "winreg.h" @@ -68,9 +69,21 @@ static const drivers_list_t knowndrivers[]= {"VBox VGA", "PCI\\VEN_80EE&DEV_BEEF&SUBSYS_00000000&REV_00", "VBox"}, {"VBox SVGA", "PCI\\VEN_80EE&DEV_BEEF&SUBSYS_040515AD&REV_00", "VBoxSvga"}, {"VMWare SVGA", "PCI\\VEN_15AD&DEV_0405&SUBSYS_040515AD&REV_00", "VMSvga"}, + {"QEMU STD VGA","PCI\\VEN_1234&DEV_1111&", "Qemu"}, {NULL, NULL, NULL} }; +static const char *pci_ids[] = { + "*PNP0A03", /* PCI bus */ + "ACPI\\VEN_PNP&DEV_0A03", /* PCI bus (NT) */ + "*PNP0A08", /* PCI Express root bus */ + "ACPI\\VEN_PNP&DEV_0A08", /* PCI Express root bus (NT) */ + "*PNP0C00", /* PCI bus (qemu) */ + NULL +}; + +static const char non_pci_vga[] = "*PNP0900"; + typedef DWORD (WINAPI *GetVersionFunc)(void); void version_parse(const char *version_str, version_t *out) @@ -282,7 +295,8 @@ const char *getVGAadapter(HDEVINFO DeviceInfoSet, SP_DEVINFO_DATA *did_out) { for(const drivers_list_t *driver = &(knowndrivers[0]); driver->name != NULL; driver++) { - if(stricmp(driver->hwid, hwid_str) == 0) + size_t driver_hwid_len = strlen(driver->hwid); + if(strnicmp(driver->hwid, hwid_str, driver_hwid_len) == 0) { memcpy(did_out, &DeviceInfoData, sizeof(SP_DEVINFO_DATA)); return driver->section; @@ -297,6 +311,109 @@ const char *getVGAadapter(HDEVINFO DeviceInfoSet, SP_DEVINFO_DATA *did_out) return NULL; } +static DWORD checkInstallatioListLookup(HDEVINFO DeviceInfoSet) +{ + static char device_id[1024]; + int DeviceIndex = 0; + SP_DEVINFO_DATA DeviceInfoData; + int count_legacy_vga = 0; + int count_pci_bus = 0; + DWORD ret = CHECK_DRV_OK; + const char *test_id; + int i; + + if(DeviceInfoSet) + { + ZeroMemory(&DeviceInfoData, sizeof(SP_DEVINFO_DATA)); + DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); + DeviceIndex = 0; + + while(DYN(SetupDiEnumDeviceInfo)(DeviceInfoSet, DeviceIndex, &DeviceInfoData)) + { + if(DYN(SetupDiGetDeviceRegistryPropertyA)(DeviceInfoSet, &DeviceInfoData, SPDRP_HARDWAREID, NULL, (PBYTE)&(device_id[0]), sizeof(device_id), NULL)) + { + for(test_id = pci_ids[0], i = 0; test_id != NULL; test_id = pci_ids[++i]) + { + if(stricmp(device_id, test_id) == 0) + { + DWORD camps = 0; + if(DYN(SetupDiGetDeviceRegistryPropertyA)(DeviceInfoSet, &DeviceInfoData, SPDRP_CAPABILITIES, NULL, (PBYTE)&(camps), sizeof(camps), NULL)) + { + if((camps & CM_DEVCAP_HARDWAREDISABLED) == 0) + { + count_pci_bus++; + } + } + break; + } + } + + if(stricmp(device_id, non_pci_vga) == 0) + { + count_legacy_vga++; + } + } + DeviceIndex++; + } + } + + if(count_pci_bus == 0) + { + ret |= CHECK_DRV_NOPCI; + } + + if(count_legacy_vga != 0) + { + ret |= CHECK_DRV_LEGACY_VGA; + } + + return ret; +} + +DWORD checkInstallation() +{ + HDEVINFO hDevInfo; + DWORD ret = 0; + + /* Enumerate all display adapters */ + hDevInfo = DYN(SetupDiGetClassDevsA)(NULL, NULL, NULL, DIGCF_PRESENT | DIGCF_ALLCLASSES); + + if(hDevInfo == INVALID_HANDLE_VALUE) + { + REPORT("SetupDiCreateDeviceInfoList: %ld", GetLastError()); + return CHECK_DRV_FAIL; + } + + /* Read the drivers from the inf file */ + if (!DYN(SetupDiBuildDriverInfoList)(hDevInfo, NULL, SPDIT_CLASSDRIVER)) + { + REPORT("SetupDiBuildDriverInfoList: %ld", GetLastError()); + DYN(SetupDiDestroyDeviceInfoList)(hDevInfo); + return CHECK_DRV_FAIL; + } + + ret = checkInstallatioListLookup(hDevInfo); + + /* Cleanup */ + DYN(SetupDiDestroyDeviceInfoList)(hDevInfo); + + return ret; +} + +static void set32bpp() +{ + DEVMODEA mode; + memset(&mode, 0, sizeof(DEVMODEA)); + mode.dmSize = sizeof(DEVMODEA); + mode.dmSpecVersion = DM_SPECVERSION; + mode.dmBitsPerPel = 32; + mode.dmPelsWidth = 640; + mode.dmPelsHeight = 480; + mode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; + + ChangeDisplaySettingsA(&mode, CDS_UPDATEREGISTRY | CDS_NORESET); +} + BOOL installVideoDriver(const char *szDriverDir, const char *infName) { HDEVINFO hDevInfo; @@ -468,15 +585,7 @@ BOOL installVideoDriver(const char *szDriverDir, const char *infName) closeAndDestroy(hDevInfo, hInf); /* set screen color depth to some usable value */ - DWORD BitsPerPixel = 0; - if(registryReadDWORD("HKCC\\Display\\Settings\\BitsPerPixel", &BitsPerPixel)) - { - if(BitsPerPixel <= 8) - { - registryWriteDWORD("HKCC\\Display\\Settings\\BitsPerPixel", 32); - } - } - + set32bpp(); return TRUE; } diff --git a/windrv.h b/windrv.h index 1cb9d03..2702b13 100644 --- a/windrv.h +++ b/windrv.h @@ -16,8 +16,14 @@ void version_parse(const char *version_str, version_t *out); int version_compare(version_t *v1, version_t *v2); void version_win(version_t *v); BOOL version_is_nt(); +DWORD checkInstallation(); BOOL loadSETUAPI(); void freeSETUAPI(); +#define CHECK_DRV_OK 0 +#define CHECK_DRV_NOPCI 1 +#define CHECK_DRV_LEGACY_VGA 2 +#define CHECK_DRV_FAIL 4 + #endif