mirror of
https://github.com/isledecomp/isle-portable.git
synced 2026-05-03 02:53:57 +00:00
Glide renderer
This commit is contained in:
parent
e939aa3ef7
commit
613c1e7339
121
CMakeLists.txt
121
CMakeLists.txt
@ -90,6 +90,7 @@ cmake_dependent_option(ISLE_USE_LWS "Use libwebsockets for native multiplayer" O
|
||||
cmake_dependent_option(ISLE_BUILD_CONFIG "Build CONFIG.EXE application" ON "MSVC OR ISLE_MINIWIN;NOT DOS;NOT NINTENDO_3DS;NOT NINTENDO_SWITCH;NOT WINDOWS_STORE;NOT VITA" OFF)
|
||||
cmake_dependent_option(ISLE_COMPILE_SHADERS "Compile shaders" ON "SDL_SHADERCROSS_BIN;TARGET Python3::Interpreter" OFF)
|
||||
cmake_dependent_option(CMAKE_POSITION_INDEPENDENT_CODE "Build with -fPIC" ON "NOT DOS;NOT VITA" OFF)
|
||||
cmake_dependent_option(ISLE_USE_GLIDE "Build with 3dfx Glide support (Voodoo)" OFF "DOS" OFF)
|
||||
option(ENABLE_CLANG_TIDY "Enable clang-tidy")
|
||||
option(DOWNLOAD_DEPENDENCIES "Download dependencies" ON)
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" CACHE PATH "Directory where to put executables and dll")
|
||||
@ -103,6 +104,126 @@ if(DOS)
|
||||
# (normally in libatomic, which DJGPP doesn't ship) are provided as simple
|
||||
# non-atomic stubs in 3rdparty/djgpp_atomic64.c since DOS is single-threaded.
|
||||
add_compile_options(-march=i486)
|
||||
|
||||
if(ISLE_USE_GLIDE)
|
||||
# 3dfx Glide support for Voodoo cards.
|
||||
# See: https://federicotech.wordpress.com/2024/12/19/compiling-3dfx-glide-2-and-3-in-ms-dos-with-djgpp/
|
||||
set(GLIDE_VERSION "3" CACHE STRING "Glide API version: 2 or 3")
|
||||
set_property(CACHE GLIDE_VERSION PROPERTY STRINGS 2 3)
|
||||
set(GLIDE_HW "sst1" CACHE STRING "Target Glide hardware: sst1 (Voodoo1), sst96 (Rush), cvg (Voodoo2), h3 (Banshee), h5 (Voodoo3/4/5)")
|
||||
set_property(CACHE GLIDE_HW PROPERTY STRINGS sst1 sst96 cvg h3 h5)
|
||||
|
||||
include(FetchContent)
|
||||
FetchContent_Declare(
|
||||
glide
|
||||
GIT_REPOSITORY "https://github.com/sezero/glide.git"
|
||||
GIT_TAG "glide-devel-sezero"
|
||||
)
|
||||
FetchContent_MakeAvailable(glide)
|
||||
set(GLIDE_SRC_DIR "${glide_SOURCE_DIR}")
|
||||
if(GLIDE_VERSION STREQUAL "3")
|
||||
set(GLIDE_ROOT "${GLIDE_SRC_DIR}/glide3x")
|
||||
else()
|
||||
set(GLIDE_ROOT "${GLIDE_SRC_DIR}/glide2x")
|
||||
endif()
|
||||
|
||||
# Copy swlibs into glide dir (required by the build system)
|
||||
if(NOT EXISTS "${GLIDE_ROOT}/swlibs")
|
||||
file(COPY "${GLIDE_SRC_DIR}/swlibs" DESTINATION "${GLIDE_ROOT}")
|
||||
endif()
|
||||
|
||||
# Patch fxglide.h for h3/h5 builds: the P6 fence inline asm check
|
||||
# fails when HOST_CC is x86_64 gcc (no __i386__ defined).
|
||||
foreach(_glide_hw_dir h3 h5)
|
||||
set(_fxglide "${GLIDE_ROOT}/${_glide_hw_dir}/glide/src/fxglide.h")
|
||||
if(EXISTS "${_fxglide}")
|
||||
file(READ "${_fxglide}" _fxglide_content)
|
||||
string(FIND "${_fxglide_content}" "defined(__x86_64__)" _already_patched)
|
||||
if(_already_patched EQUAL -1)
|
||||
string(REPLACE
|
||||
"defined(__GNUC__) && defined(__i386__)"
|
||||
"defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))"
|
||||
_fxglide_content "${_fxglide_content}")
|
||||
file(WRITE "${_fxglide}" "${_fxglide_content}")
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
# Determine include and lib paths based on hardware target
|
||||
set(_glide_subdir "glide")
|
||||
if(GLIDE_VERSION STREQUAL "3")
|
||||
set(_glide_subdir "glide3")
|
||||
endif()
|
||||
|
||||
if(GLIDE_HW STREQUAL "sst1" OR GLIDE_HW STREQUAL "sst96")
|
||||
set(GLIDE_INCLUDE_DIR
|
||||
"${GLIDE_ROOT}/swlibs/fxmisc"
|
||||
"${GLIDE_ROOT}/sst1/${_glide_subdir}/src"
|
||||
"${GLIDE_ROOT}/sst1/init"
|
||||
)
|
||||
set(GLIDE_LIB_DIR "${GLIDE_ROOT}/sst1/lib/${GLIDE_HW}")
|
||||
elseif(GLIDE_HW STREQUAL "cvg")
|
||||
set(GLIDE_INCLUDE_DIR
|
||||
"${GLIDE_ROOT}/swlibs/fxmisc"
|
||||
"${GLIDE_ROOT}/cvg/${_glide_subdir}/src"
|
||||
"${GLIDE_ROOT}/cvg/incsrc"
|
||||
)
|
||||
set(GLIDE_LIB_DIR "${GLIDE_ROOT}/cvg/lib")
|
||||
elseif(GLIDE_HW STREQUAL "h3")
|
||||
set(GLIDE_INCLUDE_DIR
|
||||
"${GLIDE_ROOT}/swlibs/fxmisc"
|
||||
"${GLIDE_ROOT}/h3/${_glide_subdir}/src"
|
||||
"${GLIDE_ROOT}/h3/incsrc"
|
||||
)
|
||||
set(GLIDE_LIB_DIR "${GLIDE_ROOT}/h3/lib")
|
||||
elseif(GLIDE_HW STREQUAL "h5")
|
||||
set(GLIDE_INCLUDE_DIR
|
||||
"${GLIDE_ROOT}/swlibs/fxmisc"
|
||||
"${GLIDE_ROOT}/h5/${_glide_subdir}/src"
|
||||
"${GLIDE_ROOT}/h5/incsrc"
|
||||
)
|
||||
set(GLIDE_LIB_DIR "${GLIDE_ROOT}/h5/lib")
|
||||
endif()
|
||||
|
||||
# Build Glide using its native DJGPP Makefile.
|
||||
# We pass CC and AR from the CMake toolchain so it uses the correct cross-compiler.
|
||||
if(GLIDE_VERSION STREQUAL "3")
|
||||
set(_glide_lib_name "libgld3x.a")
|
||||
set(_glide_lib_var "GLIDE_LIB=libgld3x.a")
|
||||
set(_glide_imp_var "GLIDE_IMP=libgld3i.a")
|
||||
else()
|
||||
set(_glide_lib_name "libgld2x.a")
|
||||
set(_glide_lib_var "GLIDE_LIB=libgld2x.a")
|
||||
set(_glide_imp_var "GLIDE_IMP=libgld2i.a")
|
||||
endif()
|
||||
set(GLIDE_LIB_FILE "${GLIDE_LIB_DIR}/${_glide_lib_name}")
|
||||
if(NOT EXISTS "${GLIDE_LIB_FILE}")
|
||||
message(STATUS "Building 3dfx Glide ${GLIDE_VERSION}.x for ${GLIDE_HW}...")
|
||||
execute_process(
|
||||
COMMAND make
|
||||
${_glide_lib_var}
|
||||
${_glide_imp_var}
|
||||
FX_GLIDE_HW=${GLIDE_HW}
|
||||
CC=${CMAKE_C_COMPILER}
|
||||
AR=${CMAKE_AR}
|
||||
HOST_CC=gcc
|
||||
-f Makefile.DJ
|
||||
WORKING_DIRECTORY "${GLIDE_ROOT}"
|
||||
RESULT_VARIABLE GLIDE_BUILD_RESULT
|
||||
)
|
||||
if(NOT GLIDE_BUILD_RESULT EQUAL 0)
|
||||
message(FATAL_ERROR "Failed to build Glide library. "
|
||||
"You may need to build manually: cd ${GLIDE_ROOT} && make ${_glide_lib_var} FX_GLIDE_HW=${GLIDE_HW} CC=${CMAKE_C_COMPILER} AR=${CMAKE_AR} -f Makefile.DJ")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT EXISTS "${GLIDE_LIB_FILE}")
|
||||
message(FATAL_ERROR "Glide library not found at ${GLIDE_LIB_FILE} after build.")
|
||||
endif()
|
||||
|
||||
set(GLIDE_LIBRARY "${GLIDE_LIB_FILE}")
|
||||
message(STATUS "3dfx Glide: ${GLIDE_HW} (${GLIDE_LIBRARY})")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
message(STATUS "Isle app: ${ISLE_BUILD_APP}")
|
||||
|
||||
@ -71,6 +71,15 @@ endif()
|
||||
|
||||
if(DOS)
|
||||
list(REMOVE_ITEM GRAPHICS_BACKENDS USE_SDL_GPU USE_OPENGL1 USE_OPENGLES2) #USE_SDL_GPU
|
||||
if(ISLE_USE_GLIDE)
|
||||
target_sources(miniwin PRIVATE src/d3drm/backends/glide/renderer.cpp)
|
||||
target_include_directories(miniwin PRIVATE ${GLIDE_INCLUDE_DIR})
|
||||
target_link_libraries(miniwin PRIVATE ${GLIDE_LIBRARY})
|
||||
if(GLIDE_VERSION STREQUAL "3")
|
||||
target_compile_definitions(miniwin PRIVATE GLIDE3=1)
|
||||
endif()
|
||||
list(APPEND GRAPHICS_BACKENDS USE_GLIDE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
list(APPEND GRAPHICS_BACKENDS USE_PALETTE_SW_RENDER)
|
||||
|
||||
1490
miniwin/src/d3drm/backends/glide/renderer.cpp
Normal file
1490
miniwin/src/d3drm/backends/glide/renderer.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -26,6 +26,9 @@
|
||||
#ifdef USE_GXM
|
||||
#include "d3drmrenderer_gxm.h"
|
||||
#endif
|
||||
#ifdef USE_GLIDE
|
||||
#include "d3drmrenderer_glide.h"
|
||||
#endif
|
||||
|
||||
Direct3DRMRenderer* CreateDirect3DRMRenderer(
|
||||
const IDirect3DMiniwin* d3d,
|
||||
@ -78,6 +81,11 @@ Direct3DRMRenderer* CreateDirect3DRMRenderer(
|
||||
return GXMRenderer::Create(DDSDesc.dwWidth, DDSDesc.dwHeight, d3d->GetMSAASamples());
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_GLIDE
|
||||
if (SDL_memcmp(guid, &GLIDE_GUID, sizeof(GUID)) == 0) {
|
||||
return new Direct3DRMGlideRenderer(DDSDesc.dwWidth, DDSDesc.dwHeight);
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_PALETTE_SW_RENDER
|
||||
if (SDL_memcmp(guid, &PALETTE_SW_GUID, sizeof(GUID)) == 0) {
|
||||
return new Direct3DRMPaletteSWRenderer(DDSDesc.dwWidth, DDSDesc.dwHeight);
|
||||
@ -112,6 +120,9 @@ void Direct3DRMRenderer_EnumDevices(const IDirect3DMiniwin* d3d, LPD3DENUMDEVICE
|
||||
#ifdef USE_PALETTE_SW_RENDER
|
||||
Direct3DRMPaletteSW_EnumDevice(cb, ctx);
|
||||
#endif
|
||||
#ifdef USE_GLIDE
|
||||
Direct3DRMGlide_EnumDevice(cb, ctx);
|
||||
#endif
|
||||
#ifdef USE_GXM
|
||||
GXMRenderer_EnumDevice(cb, ctx);
|
||||
#endif
|
||||
|
||||
110
miniwin/src/internal/d3drmrenderer_glide.h
Normal file
110
miniwin/src/internal/d3drmrenderer_glide.h
Normal file
@ -0,0 +1,110 @@
|
||||
#pragma once
|
||||
|
||||
#include "d3drmrenderer.h"
|
||||
#include "d3drmtexture_impl.h"
|
||||
#include "ddraw_impl.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include <glide.h>
|
||||
}
|
||||
|
||||
#ifdef GLIDE3
|
||||
// Glide 3 uses custom vertex layout - define our own struct
|
||||
struct GlideVertex {
|
||||
float x, y; // screen coords
|
||||
float ooz; // 65535/Z (for Z-buffering)
|
||||
float oow; // 1/w (for perspective correction)
|
||||
float r, g, b, a; // color (0-255)
|
||||
float sow, tow; // texture coords (s/w, t/w)
|
||||
};
|
||||
#define GR_WDEPTHVALUE_FARTHEST 0xFFFF
|
||||
#else
|
||||
typedef GrVertex GlideVertex;
|
||||
#endif
|
||||
|
||||
#include <vector>
|
||||
|
||||
// clang-format off
|
||||
DEFINE_GUID(GLIDE_GUID, 0x682656F3, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08);
|
||||
// clang-format on
|
||||
|
||||
struct GlideTextureEntry {
|
||||
IDirect3DRMTexture* texture;
|
||||
Uint32 version;
|
||||
GrTexInfo info;
|
||||
FxU32 startAddress;
|
||||
int texW; // actual power-of-2 width uploaded to Glide
|
||||
int texH; // actual power-of-2 height uploaded to Glide
|
||||
};
|
||||
|
||||
struct GlideMeshEntry {
|
||||
const MeshGroup* meshGroup;
|
||||
Uint32 version;
|
||||
bool flat;
|
||||
// Cached flattened geometry (only populated for flat-shaded meshes)
|
||||
std::vector<D3DRMVERTEX> flatVertices;
|
||||
std::vector<uint16_t> flatIndices;
|
||||
};
|
||||
|
||||
class Direct3DRMGlideRenderer : public Direct3DRMRenderer {
|
||||
public:
|
||||
Direct3DRMGlideRenderer(int width, int height);
|
||||
~Direct3DRMGlideRenderer() override;
|
||||
|
||||
void PushLights(const SceneLight* lights, size_t count) override;
|
||||
void SetProjection(const D3DRMMATRIX4D& projection, D3DVALUE front, D3DVALUE back) override;
|
||||
void SetFrustumPlanes(const Plane* frustumPlanes) override;
|
||||
Uint32 GetTextureId(IDirect3DRMTexture* texture, bool isUI = false, float scaleX = 0, float scaleY = 0) override;
|
||||
Uint32 GetMeshId(IDirect3DRMMesh* mesh, const MeshGroup* meshGroup) override;
|
||||
HRESULT BeginFrame() override;
|
||||
void EnableTransparency() override;
|
||||
void SubmitDraw(
|
||||
DWORD meshId,
|
||||
const D3DRMMATRIX4D& modelViewMatrix,
|
||||
const D3DRMMATRIX4D& worldMatrix,
|
||||
const D3DRMMATRIX4D& viewMatrix,
|
||||
const Matrix3x3& normalMatrix,
|
||||
const Appearance& appearance
|
||||
) override;
|
||||
HRESULT FinalizeFrame() override;
|
||||
void Resize(int width, int height, const ViewportTransform& viewportTransform) override;
|
||||
void Clear(float r, float g, float b) override;
|
||||
void Flip() override;
|
||||
void Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const SDL_Rect& dstRect, FColor color) override;
|
||||
void Download(SDL_Surface* target) override;
|
||||
void SetDither(bool dither) override;
|
||||
void SetPalette(SDL_Palette* palette) override;
|
||||
|
||||
private:
|
||||
std::vector<GlideTextureEntry> m_textureCache;
|
||||
std::vector<GlideMeshEntry> m_meshCache;
|
||||
std::vector<SceneLight> m_lights;
|
||||
D3DRMMATRIX4D m_projection;
|
||||
D3DVALUE m_frontClip;
|
||||
D3DVALUE m_backClip;
|
||||
Plane m_frustumPlanes[6];
|
||||
std::vector<D3DRMVERTEX> m_transformedVertices;
|
||||
std::vector<SDL_Color> m_litColors;
|
||||
bool m_transparencyEnabled;
|
||||
FxU32 m_nextTextureAddress;
|
||||
SDL_Palette* m_palette = nullptr;
|
||||
bool m_paletteUploaded = false;
|
||||
#ifdef GLIDE3
|
||||
FxU32 m_glideContext = 0;
|
||||
#endif
|
||||
};
|
||||
|
||||
inline static void Direct3DRMGlide_EnumDevice(LPD3DENUMDEVICESCALLBACK cb, void* ctx)
|
||||
{
|
||||
D3DDEVICEDESC halDesc = {};
|
||||
D3DDEVICEDESC helDesc = {};
|
||||
halDesc.dcmColorModel = D3DCOLOR_RGB;
|
||||
halDesc.dwFlags = D3DDD_DEVICEZBUFFERBITDEPTH;
|
||||
halDesc.dwDeviceZBufferBitDepth = DDBD_16;
|
||||
halDesc.dwDeviceRenderBitDepth = DDBD_16;
|
||||
halDesc.dpcTriCaps.dwTextureCaps = D3DPTEXTURECAPS_PERSPECTIVE;
|
||||
halDesc.dpcTriCaps.dwShadeCaps = D3DPSHADECAPS_ALPHAFLATBLEND;
|
||||
halDesc.dpcTriCaps.dwTextureFilterCaps = D3DPTFILTERCAPS_LINEAR;
|
||||
EnumDevice(cb, ctx, "3dfx Glide", &halDesc, &helDesc, GLIDE_GUID);
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user