Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
#include "GameLogic/GameLogic.h"
#include "GameLogic/TerrainLogic.h"

#include "Common/File.h"
#include "Common/file.h"
#include "VideoDevice/FFmpeg/FFmpegFile.h"

extern "C" {
Expand Down
75 changes: 75 additions & 0 deletions GeneralsMD/Code/CompatLib/Source/d3dx8_compat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,81 @@ D3DXLoadSurfaceFromSurface(
}

#ifndef __APPLE__
// GeneralsX @bugfix Antigravity 26/06/2026 Linux: GLI lacks support for A4R4G4B4/R5G6B5 formats.
// We use manual box filter downsampling for these formats to fix black infantry rendering.
if (descDest.Width == descSrc.Width / 2 && descDest.Height == descSrc.Height / 2)
{
if (descSrc.Format == D3DFMT_A4R4G4B4)
{
// Box filter for A4R4G4B4: average 2x2 blocks
const uint16_t *src = (const uint16_t *)srcRect.pBits;
uint16_t *dst = (uint16_t *)destRect.pBits;
uint32_t srcPitch16 = srcRect.Pitch / 2;
uint32_t dstPitch16 = destRect.Pitch / 2;

for (uint32_t y = 0; y < descDest.Height; y++)
{
for (uint32_t x = 0; x < descDest.Width; x++)
{
uint32_t sx = x * 2;
uint32_t sy = y * 2;
uint16_t p00 = src[sy * srcPitch16 + sx];
uint16_t p10 = src[sy * srcPitch16 + sx + 1];
uint16_t p01 = src[(sy + 1) * srcPitch16 + sx];
uint16_t p11 = src[(sy + 1) * srcPitch16 + sx + 1];

// Extract and average each channel (A4 R4 G4 B4)
uint32_t a = (((p00 >> 12) & 0x0F) + ((p10 >> 12) & 0x0F) +
((p01 >> 12) & 0x0F) + ((p11 >> 12) & 0x0F) + 2) >> 2;
uint32_t r = (((p00 >> 8) & 0x0F) + ((p10 >> 8) & 0x0F) +
((p01 >> 8) & 0x0F) + ((p11 >> 8) & 0x0F) + 2) >> 2;
uint32_t g = (((p00 >> 4) & 0x0F) + ((p10 >> 4) & 0x0F) +
((p01 >> 4) & 0x0F) + ((p11 >> 4) & 0x0F) + 2) >> 2;
uint32_t b = ((p00 & 0x0F) + (p10 & 0x0F) +
(p01 & 0x0F) + (p11 & 0x0F) + 2) >> 2;

dst[y * dstPitch16 + x] = (uint16_t)((a << 12) | (r << 8) | (g << 4) | b);
}
}
pDestSurface->UnlockRect();
pSrcSurface->UnlockRect();
return D3D_OK;
}
else if (descSrc.Format == D3DFMT_R5G6B5)
{
// Box filter for R5G6B5: average 2x2 blocks
const uint16_t *src = (const uint16_t *)srcRect.pBits;
uint16_t *dst = (uint16_t *)destRect.pBits;
uint32_t srcPitch16 = srcRect.Pitch / 2;
uint32_t dstPitch16 = destRect.Pitch / 2;

for (uint32_t y = 0; y < descDest.Height; y++)
{
for (uint32_t x = 0; x < descDest.Width; x++)
{
uint32_t sx = x * 2;
uint32_t sy = y * 2;
uint16_t p00 = src[sy * srcPitch16 + sx];
uint16_t p10 = src[sy * srcPitch16 + sx + 1];
uint16_t p01 = src[(sy + 1) * srcPitch16 + sx];
uint16_t p11 = src[(sy + 1) * srcPitch16 + sx + 1];

// Extract and average each channel (R5 G6 B5)
uint32_t r = (((p00 >> 11) & 0x1F) + ((p11 >> 11) & 0x1F) +
((p01 >> 11) & 0x1F) + ((p10 >> 11) & 0x1F) + 2) >> 2;
uint32_t g = (((p00 >> 5) & 0x3F) + ((p11 >> 5) & 0x3F) +
((p01 >> 5) & 0x3F) + ((p10 >> 5) & 0x3F) + 2) >> 2;
uint32_t b = ((p00 & 0x1F) + (p11 & 0x1F) +
(p01 & 0x1F) + (p10 & 0x1F) + 2) >> 2;

dst[y * dstPitch16 + x] = (uint16_t)((r << 11) | (g << 5) | b);
}
}
pDestSurface->UnlockRect();
pSrcSurface->UnlockRect();
return D3D_OK;
}
}
// Pick a compatible format
gli::format imageFormat = gli::format::FORMAT_RGBA8_UNORM_PACK8;

Expand Down
3 changes: 3 additions & 0 deletions docs/DEV_BLOG/2026-06-DIARY.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Development Diary - June 2026

## 2026-06-26: Support D3DFMT_A4R4G4B4 and D3DFMT_R5G6B5 Downsampling on Linux

- **DirectX 8 Downsampling Parity on Linux**: Backported the manual box filter downsampling logic for `D3DFMT_A4R4G4B4` and `D3DFMT_R5G6B5` from macOS to Linux in [d3dx8_compat.cpp](file:///home/felipe/Projects/GeneralsX/GeneralsMD/Code/CompatLib/Source/d3dx8_compat.cpp). Previously, the Linux port relied on the GLI library to generate mipmaps, which lacked support for these specific formats, causing `D3DXLoadSurfaceFromSurface` to fail. This failure resulted in team/house recolored textures on infantry rendering as solid black silhouettes at lower mipmap levels. Bypassing GLI for these formats and applying the manual box filter restores rendering parity with macOS and original Windows targets.
## 2026-06-21: Use Git Clone with Fallback for Assets in Replay Tests

- **GitLab & GitHub Resilient Assets Fetch**: Replaced `actions/checkout` with a direct `git clone` and `git lfs pull` sequence in [replay-tests.yml](file:///Users/felipebraz/PhpstormProjects/pessoal/GeneralsX/.github/workflows/replay-tests.yml) to retrieve large game asset archives. Implemented try/catch logic in the shell script: it attempts to clone the assets from GitLab first (benefiting from GitLab's larger LFS transfer limits), and falls back to GitHub if the GitLab clone or LFS pull fails. This maintains maximum build reliability while bypassing GitHub's LFS restrictions where possible.
Expand Down
4 changes: 2 additions & 2 deletions docs/HOWTO/INSTALLATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@

GeneralsX has been developed and tested primarily on the following environments:

- Ubuntu 24.04 LTS (x86_64)
- Ubuntu 26.04 LTS (x86_64)
- macOS 26 "Tahoe" on Apple Silicon (M1 / ARM64)

Other Linux distributions or macOS versions may work, but you may need to install additional dependencies manually. On some systems, certain libraries might need to be built from source.
Expand All @@ -81,7 +81,7 @@ Current development and test matrix:

| Platform | Architecture | Status |
|--------------------|------------------------|---------|
| Ubuntu 24.04 LTS | x86_64 | Working |
| Ubuntu 26.04 LTS | x86_64 | Working |
| macOS 26 "Tahoe" | ARM64 (Apple Silicon) | Working |

Support for other platforms and configurations is possible but not yet officially tested.
Expand Down
8 changes: 4 additions & 4 deletions docs/WORKDIR/phases/PHASE04_POLISH_HARDENING.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ Stabilize, optimize, and prepare for community release.
- Invalid command-line arguments

- [ ] **Compatibility tests** (multiple environments):
- Ubuntu 22.04, 24.04 (LTS targets)
- Ubuntu 22.04, 26.04 (LTS targets)
- Fedora 40+ (latest kernel/drivers)
- Arch Linux (rolling release, bleeding edge)
- Steam Deck (Proton comparison: native vs. Wine)
Expand Down Expand Up @@ -231,7 +231,7 @@ Stabilize, optimize, and prepare for community release.

**Target Distros**:
- [ ] Ubuntu 22.04 LTS (stable, large user base)
- [ ] Ubuntu 24.04 LTS (latest LTS)
- [ ] Ubuntu 26.04 LTS (latest LTS)
- [ ] Fedora 40+ (cutting edge, latest Mesa)
- [ ] Arch Linux (rolling release, community favorite)
- [ ] Debian 12 (stable, server-oriented but some gamers)
Expand All @@ -241,7 +241,7 @@ Stabilize, optimize, and prepare for community release.
| Distro | Vulkan Driver | GPU | Status | Notes |
|--------|---------------|-----|--------|-------|
| Ubuntu 22.04 | Mesa RADV | AMD RX 6800 | ❓ | Test here |
| Ubuntu 24.04 | Mesa RADV | AMD RX 6800 | ❓ | Test here |
| Ubuntu 26.04 | Mesa RADV | AMD RX 6800 | ❓ | Test here |
| Fedora 40 | Mesa RADV | AMD RX 7900 | ❓ | Test here |
| Arch | Mesa RADV | AMD RX 580 | ❓ | Test here |
| Ubuntu 22.04 | NVIDIA 550 | RTX 3080 | ❓ | Test here |
Expand Down Expand Up @@ -381,7 +381,7 @@ Phase 4 is **COMPLETE** when:
- [ ] No memory leaks (Valgrind clean)
- [ ] Case-insensitive filesystem working (no "file not found" errors)
- [ ] Passes 2-hour stress test (no crashes, minimal performance drop)
- [ ] Works on Ubuntu 22.04, 24.04, Fedora 40, Arch (verified)
- [ ] Works on Ubuntu 22.04, 26.04, Fedora 40, Arch (verified)
- [ ] AppImage or Flatpak release available
- [ ] Documentation complete (`INSTALL_LINUX.md`, `TROUBLESHOOTING_LINUX.md`)
- [ ] Community beta tested (>10 testers, feedback incorporated)
Expand Down
2 changes: 1 addition & 1 deletion resources/dockerbuild/Dockerfile.linux
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# Base image for building GeneralsX/GeneralsXZH Linux binaries
# Platform: linux/amd64 (x86_64)

FROM ubuntu:24.04
FROM ubuntu:26.04

LABEL maintainer="GeneralsX Project"
LABEL description="Linux native build environment for GeneralsX (GCC/Clang + CMake + vcpkg)"
Expand Down
2 changes: 1 addition & 1 deletion scripts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ Scripts support customization:

```bash
# Custom Docker image base
export DOCKER_IMAGE="ubuntu:24.04"
export DOCKER_IMAGE="ubuntu:26.04"
./scripts/build/linux/docker-build-linux-zh.sh

# Flatpak PoC: inject newer libxcb/X11 libs from an external directory
Expand Down
2 changes: 1 addition & 1 deletion scripts/README_DOCKER_SCRIPTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ Scripts support environment variables:

```bash
# Custom Docker image
export DOCKER_IMAGE="ubuntu:24.04"
export DOCKER_IMAGE="ubuntu:26.04"
./scripts/docker-build-linux-zh.sh

# Custom log directory
Expand Down
5 changes: 2 additions & 3 deletions scripts/build/linux/bundle-linux-zh.sh
Original file line number Diff line number Diff line change
Expand Up @@ -175,10 +175,9 @@ if [[ -f "${SCRIPT_DIR}/libsage_patch.so" && "${SAGE_PATCH_DISABLED:-0}" != "1"
else
export LD_PRELOAD="${SCRIPT_DIR}/libsage_patch.so"
fi
export DXVK_HUD="${DXVK_HUD:-fps}"
else
export DXVK_HUD="${DXVK_HUD:-0}"
fi
# DXVK HUD is disabled by default because Generals has a native FPS counter.
export DXVK_HUD="${DXVK_HUD:-0}"

# Auto-detect base Generals install path
if [[ -z "${CNC_GENERALS_INSTALLPATH:-}" && -d "${SCRIPT_DIR}/../Generals" ]]; then
Expand Down
5 changes: 2 additions & 3 deletions scripts/build/linux/bundle-linux.sh
Original file line number Diff line number Diff line change
Expand Up @@ -174,10 +174,9 @@ if [[ -f "${SCRIPT_DIR}/libsage_patch.so" && "${SAGE_PATCH_DISABLED:-0}" != "1"
else
export LD_PRELOAD="${SCRIPT_DIR}/libsage_patch.so"
fi
export DXVK_HUD="${DXVK_HUD:-fps}"
else
export DXVK_HUD="${DXVK_HUD:-0}"
fi
# DXVK HUD is disabled by default because Generals has a native FPS counter.
export DXVK_HUD="${DXVK_HUD:-0}"

# Auto-detect base Generals install path
if [[ -z "${CNC_GENERALS_INSTALLPATH:-}" && -d "${SCRIPT_DIR}/../Generals" ]]; then
Expand Down
11 changes: 3 additions & 8 deletions scripts/build/linux/deploy-linux-zh.sh
Original file line number Diff line number Diff line change
Expand Up @@ -190,14 +190,9 @@ export LD_LIBRARY_PATH="${SCRIPT_DIR}:${LD_LIBRARY_PATH:-}"
# Set DXVK environment
export DXVK_WSI_DRIVER="SDL3"
export DXVK_LOG_LEVEL="${DXVK_LOG_LEVEL:-info}"
# DXVK HUD: SagePatch builds default to "fps" so casual users see frame rate
# without extra config. Set DXVK_HUD=0 explicitly to disable, or anything else
# (e.g. fps,memory,version) to customize. See DXVK docs for full list.
if [[ -f "${SCRIPT_DIR}/libsage_patch.so" && "${SAGE_PATCH_DISABLED:-0}" != "1" ]]; then
export DXVK_HUD="${DXVK_HUD:-fps}"
else
export DXVK_HUD="${DXVK_HUD:-0}"
fi
# DXVK HUD is disabled by default because Generals has a native FPS counter.
# Set DXVK_HUD=fps,memory,version or similar to customize. See DXVK docs for full list.
export DXVK_HUD="${DXVK_HUD:-0}"

# SagePatch (optional QoL features). Loaded via LD_PRELOAD so it can interpose
# SDL3 functions for hot-keys (F11 screenshot, Scroll Lock cursor lock,
Expand Down
2 changes: 1 addition & 1 deletion scripts/build/linux/run-linux-zh.sh
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export LD_LIBRARY_PATH="${GAME_DIR}:${LD_LIBRARY_PATH:-}"
# Set DXVK environment
export DXVK_WSI_DRIVER="SDL3"
export DXVK_LOG_LEVEL="${DXVK_LOG_LEVEL:-info}" # Override with 'debug' if needed
export DXVK_HUD="${DXVK_HUD:-devinfo,fps}" # Show GPU info + FPS overlay; override with DXVK_HUD=0 to disable
export DXVK_HUD="${DXVK_HUD:-0}" # Disabled by default; Generals has native FPS counter

# GeneralsX @bugfix BenderAI 06/03/2026 - Exclude LLVMpipe Vulkan ICD (LLVM 20.x crash workaround)
# libvulkan_lvp.so (LLVMpipe) crashes during static initialization with LLVM 20.x.
Expand Down
2 changes: 1 addition & 1 deletion scripts/build/linux/run-linux.sh
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export LD_LIBRARY_PATH="${GAME_DIR}:${LD_LIBRARY_PATH:-}"
# Set DXVK environment
export DXVK_WSI_DRIVER="SDL3"
export DXVK_LOG_LEVEL="${DXVK_LOG_LEVEL:-info}" # Override with 'debug' if needed
export DXVK_HUD="${DXVK_HUD:-devinfo,fps}" # Show GPU info + FPS overlay; override with DXVK_HUD=0 to disable
export DXVK_HUD="${DXVK_HUD:-0}" # Disabled by default; Generals has native FPS counter

# GeneralsX @bugfix BenderAI 06/03/2026 - Exclude LLVMpipe Vulkan ICD (LLVM 20.x crash workaround)
# libvulkan_lvp.so (LLVMpipe) crashes during static initialization with LLVM 20.x.
Expand Down
Loading