Made the renderer modular and loadable

This removes coupling between the renderer and UI/client functions. An option USE_RENDERER_DLOPEN was added to specify whether a renderer module should be compiled and loaded, instead of integrating the renderer into the executable directly. This opens the door for a new renderer
This commit is contained in:
smallmodel 2024-12-06 00:09:07 +01:00
parent 35f40e949b
commit 28bdd1b2b3
No known key found for this signature in database
GPG key ID: 9F2D623CEDF08512
31 changed files with 645 additions and 217 deletions

View file

@ -14,6 +14,7 @@ endif()
option(USE_INTERNAL_JPEG "If set, use bundled libjpeg." ${USE_INTERNAL_LIBS})
option(USE_INTERNAL_MAD "If set, use bundled libmad." ${USE_INTERNAL_LIBS})
option(USE_INTERNAL_ZLIB "If set, use bundled zlib." ${USE_INTERNAL_LIBS})
option(USE_RENDERER_DLOPEN "Whether to compile the renderer as separate pluggable modules" OFF)
option(TARGET_LOCAL_SYSTEM "Indicate that the project will be compiled and installed for the local system" OFF)
if(TARGET_GAME_TYPE)

View file

@ -29,14 +29,19 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "../qcommon/localization.h"
#include "../qcommon/bg_compat.h"
#include "../sys/sys_local.h"
#ifdef USE_RENDERER_DLL
#include "../sys/sys_loadlib.h"
#endif
extern "C" {
#include "../sys/sys_loadlib.h"
}
#include "../gamespy/gcdkey/gcdkeyc.h"
#include <climits>
#ifdef USE_RENDERER_DLOPEN
cvar_t* cl_renderer;
#endif
cvar_t *cl_nodelta;
cvar_t *cl_debugMove;
@ -130,19 +135,14 @@ clientGameExport_t *cge;
// Structure containing functions exported from refresh DLL
refexport_t re;
#ifdef USE_RENDERER_DLOPEN
static void *rendererLib = NULL;
#endif
qboolean camera_reset;
qboolean camera_active;
vec3_t camera_offset;
#ifdef USE_RENDERER_DLL
// su44: for plugable renderer system
refexport_t* (*DGetRefAPI)(int apiVersion, refimport_t * rimp) = NULL;
static cvar_t *cl_renderer = NULL;
static void *rendererLib = NULL;
#endif // USE_RENDERER_DLL
ping_t cl_pinglist[MAX_PINGREQUESTS];
typedef struct serverStatus_s
@ -802,9 +802,10 @@ void CL_ShutdownAll(qboolean shutdownRef) {
TIKI_FreeAll();
// shutdown the renderer
if ( re.Shutdown ) {
re.Shutdown( qfalse ); // don't destroy window or context
}
if(shutdownRef)
CL_ShutdownRef();
else if(re.Shutdown)
re.Shutdown(qfalse); // don't destroy window or context
cls.uiStarted = qfalse;
cls.cgameStarted = qfalse;
@ -1580,19 +1581,24 @@ void CL_Vid_Restart_f( void ) {
S_BeginRegistration();
// shutdown the UI
//CL_ShutdownUI();
// shutdown the renderer and clear the renderer interface
CL_ShutdownRef();
CL_ShutdownRef();
cls.rendererRegistered = qfalse;
// shutdown the CGame
CL_ShutdownCGame();
// initialize the renderer interface
CL_InitRef();
// initialize the UI
//CL_InitializeUI();
// initialize the ui library
UI_ResolutionChange();
// clear aliases
Alias_Clear();
cls.rendererRegistered = qfalse;
// unpause so the cgame definately gets a snapshot and renders a frame
Com_Unpause();
@ -2809,15 +2815,15 @@ CL_ShutdownRef
============
*/
void CL_ShutdownRef( void ) {
if ( !re.Shutdown ) {
return;
if ( re.Shutdown ) {
re.Shutdown( qtrue );
}
re.Shutdown( qtrue );
Com_Memset( &re, 0, sizeof( re ) );
#ifdef USE_RENDERER_DLL
// su44: remember to unload renderer library
if(rendererLib) {
Sys_UnloadLibrary(rendererLib);
#ifdef USE_RENDERER_DLOPEN
if ( rendererLib ) {
Sys_UnloadLibrary( rendererLib );
rendererLib = NULL;
}
#endif
@ -2994,22 +3000,105 @@ void CL_CG_EndTiki( dtiki_t *tiki ) {
}
}
/*
============
CL_CG_EndTiki
============
*/
extern "C"
int CL_ScaledMilliseconds(void) {
return Sys_Milliseconds()*com_timescale->value;
}
/*
============
CL_RefFS_WriteFile
============
*/
void CL_RefFS_WriteFile(const char* qpath, const void* buffer, int size) {
FS_WriteFile(qpath, buffer, size);
}
/*
============
CL_RefFS_ListFiles
============
*/
char** CL_RefFS_ListFiles(const char* name, const char* extension, int* numfilesfound) {
return FS_ListFiles(name, extension, qtrue, numfilesfound);
}
/*
============
CL_RefCIN_UploadCinematic
============
*/
void CL_RefCIN_UploadCinematic(int handle) {
}
/*
============
CL_RefTIKI_GetNumChannels
============
*/
int CL_RefTIKI_GetNumChannels(dtiki_t* tiki) {
return tiki->m_boneList.NumChannels();
}
/*
============
CL_RefTIKI_GetLocalChannel
============
*/
int CL_RefTIKI_GetLocalChannel(dtiki_t* tiki, int channel) {
return tiki->m_boneList.LocalChannel(channel);
}
/*
============
CL_RefTIKI_GetLocalFromGlobal
============
*/
int CL_RefTIKI_GetLocalFromGlobal(dtiki_t* tiki, int channel) {
return tiki->m_boneList.GetLocalFromGlobal(channel);
}
/*
============
CL_RefSKEL_GetMorphWeightFrame
============
*/
int CL_RefSKEL_GetMorphWeightFrame(void* skeletor, int index, float time, int* data) {
return ((skeletor_c*)skeletor)->GetMorphWeightFrame(index, time, data);
}
/*
============
CL_RefSKEL_GetBoneParent
============
*/
int CL_RefSKEL_GetBoneParent(void* skeletor, int boneIndex) {
return ((skeletor_c*)skeletor)->GetBoneParent(boneIndex);
}
/*
============
CL_GetRefSequence
============
*/
int CL_GetRefSequence(void) {
return cls.refSequence;
}
/*
============
CL_IsRendererRegistered
============
*/
qboolean CL_IsRendererRegistered(void) {
return cls.rendererRegistered;
}
/*
============
CL_InitRef
@ -3018,12 +3107,40 @@ CL_InitRef
void CL_InitRef( void ) {
refimport_t ri;
refexport_t *ret;
#ifdef USE_RENDERER_DLL
char dllName[256];
#ifdef USE_RENDERER_DLOPEN
GetRefAPI_t GetRefAPI;
char dllName[MAX_OSPATH];
#endif
Com_Printf( "----- Initializing Renderer ----\n" );
#ifdef USE_RENDERER_DLOPEN
cl_renderer = Cvar_Get("cl_renderer", "opengl1", CVAR_ARCHIVE | CVAR_LATCH);
Com_sprintf(dllName, sizeof(dllName), "renderer_%s" ARCH_SUFFIX DLL_SUFFIX DLL_EXT, cl_renderer->string);
if(!(rendererLib = Sys_LoadDll(dllName, qfalse)) && strcmp(cl_renderer->string, cl_renderer->resetString))
{
Com_Printf("failed:\n\"%s\"\n", Sys_LibraryError());
Cvar_ForceReset("cl_renderer");
Com_sprintf(dllName, sizeof(dllName), "renderer_opengl1" ARCH_SUFFIX DLL_SUFFIX DLL_EXT);
rendererLib = Sys_LoadDll(dllName, qfalse);
}
if(!rendererLib)
{
Com_Printf("failed:\n\"%s\"\n", Sys_LibraryError());
Com_Error(ERR_FATAL, "Failed to load renderer");
}
GetRefAPI = (GetRefAPI_t)Sys_LoadFunction(rendererLib, "GetRefAPI");
if(!GetRefAPI)
{
Com_Error(ERR_FATAL, "Can't load symbol GetRefAPI: '%s'", Sys_LibraryError());
}
#endif
ri.Cmd_AddCommand = Cmd_AddCommand;
ri.Cmd_RemoveCommand = Cmd_RemoveCommand;
ri.Cmd_Argc = Cmd_Argc;
@ -3047,8 +3164,10 @@ void CL_InitRef( void ) {
ri.CM_DrawDebugSurface = CM_DrawDebugSurface;
ri.FS_OpenFile = FS_FOpenFileRead;
ri.FS_OpenFileWrite = FS_FOpenFileWrite;
ri.FS_CloseFile = FS_FCloseFile;
ri.FS_Read = FS_Read;
ri.FS_Write = FS_Write;
ri.FS_Seek = FS_Seek;
ri.FS_ReadFile = FS_ReadFile;
ri.FS_ReadFileEx = FS_ReadFileEx;
@ -3058,6 +3177,7 @@ void CL_InitRef( void ) {
ri.FS_ListFiles = CL_RefFS_ListFiles;
ri.FS_FileIsInPAK = FS_FileIsInPAK;
ri.FS_FileExists = FS_FileExists;
ri.FS_CanonicalFilename = FS_CanonicalFilename;
ri.Cvar_Get = Cvar_Get;
ri.Cvar_Set = Cvar_Set;
ri.Cvar_SetDefault = Cvar_SetDefault;
@ -3108,40 +3228,30 @@ void CL_InitRef( void ) {
ri.Sys_GLimpInit = Sys_GLimpInit;
ri.Sys_LowPhysicalMemory = Sys_LowPhysicalMemory;
#ifdef USE_RENDERER_DLL
// su44: load renderer dll
cl_renderer = Cvar_Get("cl_renderer", "glom", CVAR_ARCHIVE);
Q_snprintf(dllName, sizeof(dllName), "renderer_%s" ARCH_STRING DLL_EXT, cl_renderer->string);
Com_Printf("Loading \"%s\"...", dllName);
if((rendererLib = Sys_LoadLibrary(dllName)) == 0) {
#ifdef _WIN32
Com_Error(ERR_FATAL, "failed:\n\"%s\"\n", Sys_LibraryError());
#else
char fn[1024];
//
// Added in OPM
//
ri.UI_LoadResource = UI_LoadResource;
ri.CM_PointLeafnum = CM_PointLeafnum;
ri.CM_LeafCluster = CM_LeafCluster;
Q_strncpyz(fn, Sys_Cwd(), sizeof(fn));
strncat(fn, "/", sizeof(fn) - strlen(fn) - 1);
strncat(fn, dllName, sizeof(fn) - strlen(fn) - 1);
ri.TIKI_CalcLodConsts = TIKI_CalcLodConsts;
ri.TIKI_CalculateBounds = TIKI_CalculateBounds;
ri.TIKI_FindTiki = TIKI_FindTiki;
ri.TIKI_RegisterTikiFlags = TIKI_RegisterTikiFlags;
ri.TIKI_GetSkeletor = TIKI_GetSkeletor;
ri.TIKI_GetSkel = TIKI_GetSkel;
ri.TIKI_GetSkelAnimFrame = TIKI_GetSkelAnimFrame;
ri.TIKI_GlobalRadius = TIKI_GlobalRadius;
ri.TIKI_FindSkelByHeader = TIKI_FindSkelByHeader;
ri.TIKI_GetNumChannels = CL_RefTIKI_GetNumChannels;
ri.TIKI_GetLocalChannel = CL_RefTIKI_GetLocalChannel;
ri.TIKI_GetLocalFromGlobal = CL_RefTIKI_GetLocalFromGlobal;
Com_Printf("Loading \"%s\"...", fn);
if((rendererLib = Sys_LoadLibrary(fn)) == 0)
{
Com_Error(ERR_FATAL, "failed:\n\"%s\"", Sys_LibraryError());
}
#endif /* _WIN32 */
}
ri.SKEL_GetBoneParent = CL_RefSKEL_GetBoneParent;
ri.SKEL_GetMorphWeightFrame = CL_RefSKEL_GetMorphWeightFrame;
Com_Printf("done\n");
DGetRefAPI = Sys_LoadFunction(rendererLib, "GetRefAPI");
if(!DGetRefAPI)
{
Com_Error(ERR_FATAL, "Can't load symbol GetRefAPI: '%s'", Sys_LibraryError());
}
ret = DGetRefAPI( REF_API_VERSION, &ri );
#else
ret = GetRefAPI( REF_API_VERSION, &ri );
#endif
#if defined __USEA3D && defined __A3D_GEOM
hA3Dg_ExportRenderGeom (ret);
@ -3157,6 +3267,8 @@ void CL_InitRef( void ) {
// unpause so the cgame definately gets a snapshot and renders a frame
Cvar_Set( "cl_paused", "0" );
cls.refSequence++;
}

View file

@ -3766,6 +3766,9 @@ void CL_FillUIImports(void)
uii.GetConfigstring = CL_ConfigString;
uii.UI_CloseDMConsole = UI_CloseDMConsole;
uii.GetRefSequence = CL_GetRefSequence;
uii.IsRendererRegistered = CL_IsRendererRegistered;
}
/*

View file

@ -389,6 +389,8 @@ typedef struct {
qhandle_t whiteShader;
qhandle_t consoleShader;
fontInfo_t consoleFont;
int refSequence;
} clientStatic_t;
extern clientStatic_t cls;
@ -557,6 +559,9 @@ void UI_LoadResource( const char *name );
qboolean CL_CheckPaused(void);
int CL_GetRefSequence(void);
qboolean CL_IsRendererRegistered(void);
//
// cl_input
//

View file

@ -9,7 +9,7 @@ endif()
include("./q_version.cmake")
# Shared source files for modules
set(SOURCES_SHARED
set(SOURCES_SHARED_UBER
"${CMAKE_SOURCE_DIR}/code/qcommon/class.cpp"
"${CMAKE_SOURCE_DIR}/code/qcommon/con_set.cpp"
"${CMAKE_SOURCE_DIR}/code/qcommon/con_timer.cpp"
@ -18,26 +18,35 @@ set(SOURCES_SHARED
"${CMAKE_SOURCE_DIR}/code/qcommon/lz77.cpp"
"${CMAKE_SOURCE_DIR}/code/qcommon/mem_blockalloc.cpp"
"${CMAKE_SOURCE_DIR}/code/qcommon/mem_tempalloc.cpp"
"${CMAKE_SOURCE_DIR}/code/qcommon/puff.c"
"${CMAKE_SOURCE_DIR}/code/qcommon/q_math.c"
"${CMAKE_SOURCE_DIR}/code/qcommon/q_shared.c"
"${CMAKE_SOURCE_DIR}/code/qcommon/script.cpp"
"${CMAKE_SOURCE_DIR}/code/qcommon/str.cpp"
"${CMAKE_SOURCE_DIR}/code/script/scriptexception.cpp"
"${CMAKE_SOURCE_DIR}/code/script/scriptvariable.cpp"
)
add_library(qcommon INTERFACE)
target_sources(qcommon INTERFACE ${SOURCES_SHARED})
add_library(qcommon_uber INTERFACE)
target_sources(qcommon_uber INTERFACE ${SOURCES_SHARED_UBER})
target_compile_features(qcommon_uber INTERFACE cxx_nullptr)
target_include_directories(qcommon_uber INTERFACE "../qcommon" "../script")
if(DEBUG_MEM_BLOCK)
target_compile_definitions(qcommon INTERFACE _DEBUG_MEMBLOCK=1)
target_compile_definitions(qcommon_uber INTERFACE _DEBUG_MEMBLOCK=1)
endif()
target_include_directories(qcommon INTERFACE "../qcommon" "../script")
target_compile_features(qcommon INTERFACE cxx_nullptr)
target_compile_features(qcommon INTERFACE c_variadic_macros)
target_link_libraries(qcommon INTERFACE qcommon_version)
set(SOURCES_SHARED
"${CMAKE_SOURCE_DIR}/code/qcommon/puff.c"
"${CMAKE_SOURCE_DIR}/code/qcommon/q_math.c"
"${CMAKE_SOURCE_DIR}/code/qcommon/q_shared.c"
)
add_library(qcommon_shared INTERFACE)
target_sources(qcommon_shared INTERFACE ${SOURCES_SHARED})
target_compile_features(qcommon_shared INTERFACE c_variadic_macros)
target_include_directories(qcommon_shared INTERFACE "../qcommon")
target_link_libraries(qcommon_shared INTERFACE qcommon_version)
add_library(qcommon INTERFACE)
target_link_libraries(qcommon INTERFACE qcommon_shared qcommon_uber)
# Source files for standalone executable
set(SOURCES_COMMON

View file

@ -4012,7 +4012,9 @@ void FS_Restart( int checksumFeed ) {
// try to start up normally
FS_Startup(com_basegame->string);
#ifndef STANDALONE
FS_CheckPak0( );
#endif
// if we can't find default.cfg, assume that the paths are
// busted and error out now, rather than getting an unreadable

View file

@ -25,7 +25,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "q_shared.h"
#include "qcommon.h"
#ifdef STANDALONE
#ifndef DEDICATED
# include "../client/client.h"
#endif
@ -354,7 +354,7 @@ void Z_Meminfo_f( void )
Com_Printf( "\n%.2f Kbytes in %zu blocks in all memory pools\n", ( float )totalBytes / 1024.0f, totalBlocks );
Com_Printf( "\n%.2f megabytes in 'new' system memory\n", 1.024f );
#ifdef STANDALONE
#ifndef DEDICATED
if (re.CountTextureMemory) {
Com_Printf( "\n%.2f megabytes in texture memory\n", ( float )re.CountTextureMemory() / 1024.0f );
Com_Printf( "\n%.1f megabytes in total allocations\n", ( float )re.CountTextureMemory() + totalBytes - 1 / 1024.0f );

View file

@ -20,6 +20,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#include "../../tiki/tiki_shared.h"
#define MAX_ENTITIES 1023 // can't be increased without changing drawsurf bit packing
#define MAX_POINTS 32
#define MAX_SPRITES 2048

View file

@ -266,10 +266,13 @@ typedef struct {
void (*Cvar_SetDefault)(cvar_t* var, const char* varValue);
long (*FS_OpenFile)(const char* qpath, fileHandle_t *file, qboolean uniqueFILE, qboolean quiet);
fileHandle_t (*FS_OpenFileWrite)(const char* filename);
size_t (*FS_Read)(void* buffer, size_t len, fileHandle_t fileHandle);
size_t (*FS_Write)(const void* buffer, size_t len, fileHandle_t h);
void (*FS_CloseFile)(fileHandle_t fileHandle);
int (*FS_Seek)(fileHandle_t fileHandle, long offset, int origin);
long (*FS_ReadFileEx)(const char* qpath, void** buffer, qboolean quiet);
void (*FS_CanonicalFilename)(char* filename);
void (*CM_BoxTrace)(trace_t* results, const vec3_t start, const vec3_t end, const vec3_t mins, const vec3_t maxs, int model, int brushMask, int cylinder);
int (*CM_TerrainSquareType)(int terrainPatch, int i, int j);
@ -287,13 +290,42 @@ typedef struct {
debugstring_t** DebugStrings;
int* numDebugStrings;
orientation_t (*TIKI_OrientationInternal)(dtiki_t* tiki, int entNum, int tagNum, float scale);
qboolean (*TIKI_IsOnGroundInternal)(dtiki_t* tiki, int entNum, int tagNum, float thresHold);
void (*TIKI_SetPoseInternal)(void* skeletor, const frameInfo_t* frameInfo, const int* boneTag, const vec4_t *boneQuat, float actionWeight);
void* (*TIKI_Alloc)(size_t size);
float (*GetRadiusInternal)(dtiki_t* tiki, int entNum, float scale);
float (*GetCentroidRadiusInternal)(dtiki_t* tiki, int entNum, float scale, vec3_t centroid);
void (*GetFrameInternal)(dtiki_t* tiki, int entNum, skelAnimFrame_t* newFrame);
orientation_t (*TIKI_OrientationInternal)(dtiki_t *tiki, int entNum, int tagNum, float scale);
qboolean (*TIKI_IsOnGroundInternal)(dtiki_t *tiki, int entNum, int tagNum, float thresHold);
void (*TIKI_SetPoseInternal)(
void *skeletor, const frameInfo_t *frameInfo, const int *boneTag, const vec4_t *boneQuat, float actionWeight
);
void *(*TIKI_Alloc)(size_t size);
float (*GetRadiusInternal)(dtiki_t *tiki, int entNum, float scale);
float (*GetCentroidRadiusInternal)(dtiki_t *tiki, int entNum, float scale, vec3_t centroid);
void (*GetFrameInternal)(dtiki_t *tiki, int entNum, skelAnimFrame_t *newFrame);
void (*UI_LoadResource)(const char *name);
int (*CM_PointLeafnum)(const vec3_t p);
int (*CM_LeafCluster)(int leafnum);
//
// TIKI imports
//
void (*TIKI_CalcLodConsts)(lodControl_t *LOD);
void (*TIKI_CalculateBounds)(dtiki_t *pmdl, float scale, vec3_t mins, vec3_t maxs);
dtiki_t *(*TIKI_FindTiki)(const char *path);
dtiki_t *(*TIKI_RegisterTikiFlags)(const char *path, qboolean use);
void *(*TIKI_GetSkeletor)(dtiki_t *tiki, int entnum);
skelHeaderGame_t *(*TIKI_GetSkel)(int index);
void (*TIKI_GetSkelAnimFrame)(dtiki_t *tiki, skelBoneCache_t *bones, float *radius, vec3_t *mins, vec3_t *maxes);
float (*TIKI_GlobalRadius)(dtiki_t *pmdl);
skelcache_t *(*TIKI_FindSkelByHeader)(skelHeaderGame_t *skelmodel);
int (*TIKI_GetNumChannels)(dtiki_t *tiki);
int (*TIKI_GetLocalChannel)(dtiki_t *tiki, int channel);
int (*TIKI_GetLocalFromGlobal)(dtiki_t *tiki, int channel);
//
// Skeletor imports
//
int (*SKEL_GetMorphWeightFrame)(void *skeletor, int index, float time, int *data);
int (*SKEL_GetBoneParent)(void *skeletor, int boneIndex);
} refimport_t;

View file

@ -5,17 +5,26 @@ project(omohrenderer)
file(GLOB_RECURSE SOURCES_RENDERER "./*.c" "./*.cpp" "../renderercommon/tr_*.c")
list(REMOVE_ITEM SOURCES_RENDERER "./tr_subs.c")
add_library(omohrenderer STATIC ${SOURCES_RENDERER})
set(SOURCES_RENDERER ${SOURCES_RENDERER}
"../tiki/tiki_mesh.cpp"
)
if (${USE_RENDERER_DLOPEN})
add_library(omohrenderer SHARED ${SOURCES_RENDERER})
else()
add_library(omohrenderer STATIC ${SOURCES_RENDERER})
endif()
target_include_directories(omohrenderer PUBLIC "../sdl" "../renderercommon")
target_compile_features(omohrenderer PUBLIC cxx_nullptr)
target_compile_features(omohrenderer PUBLIC c_variadic_macros)
target_compile_definitions(omohrenderer PRIVATE USE_INTERNAL_JPEG=1)
target_link_libraries(omohrenderer PRIVATE qcommon)
target_link_libraries(omohrenderer PRIVATE qcommon_shared)
target_link_libraries(omohrenderer PRIVATE omohsdl_gl)
get_target_property(target_type omohrenderer TYPE)
if (target_type STREQUAL "SHARED_LIBRARY")
target_sources(omohrenderer PRIVATE "./tr_subs.c")
target_compile_definitions(omohrenderer PUBLIC USE_RENDERER_DLOPEN=1)
endif ()
if(USE_INTERNAL_JPEG)
@ -28,3 +37,15 @@ else()
target_include_directories(omohrenderer PUBLIC ${JPEG_INCLUDE_DIRS})
target_link_libraries(omohrenderer PRIVATE ${JPEG_LIBRARIES})
endif()
set_target_properties(omohrenderer PROPERTIES PREFIX "")
set_target_properties(omohrenderer PROPERTIES OUTPUT_NAME "renderer_opengl1${TARGET_BIN_SUFFIX}")
if (target_type STREQUAL "SHARED_LIBRARY")
INSTALL(TARGETS omohrenderer DESTINATION ${CMAKE_INSTALL_LIBDIR}/${LIB_INSTALL_SUBDIR})
if(MSVC)
INSTALL(FILES $<TARGET_PDB_FILE:omohrenderer> DESTINATION ${CMAKE_INSTALL_LIBDIR}/${LIB_INSTALL_SUBDIR} OPTIONAL)
endif()
endif ()

View file

@ -2189,13 +2189,13 @@ int R_LoadLump(fileHandle_t handle, lump_t* lump, gamelump_t* glump, int size)
glump->length = lump->filelen;
if (lump->filelen) {
glump->buffer = Hunk_AllocateTempMemory(lump->filelen);
glump->buffer = ri.Hunk_AllocateTempMemory(lump->filelen);
if (FS_Seek(handle, lump->fileofs, FS_SEEK_SET) < 0) {
if (ri.FS_Seek(handle, lump->fileofs, FS_SEEK_SET) < 0) {
Com_Error(ERR_DROP, "R_LoadLump: Error seeking to lump.");
}
FS_Read(glump->buffer, lump->filelen, handle);
ri.FS_Read(glump->buffer, lump->filelen, handle);
if (size) {
return lump->filelen / size;
@ -2216,13 +2216,13 @@ void R_FreeLump(gamelump_t* lump)
{
if (lump->buffer)
{
Hunk_FreeTempMemory(lump->buffer);
ri.Hunk_FreeTempMemory(lump->buffer);
lump->buffer = NULL;
lump->length = 0;
}
}
#define _R( id ) UI_LoadResource( "*" #id )
#define _R( id ) ri.UI_LoadResource( "*" #id )
/*
=================
@ -2424,17 +2424,17 @@ void RE_LoadWorldMap( const char *name ) {
ri.FS_CloseFile(h);
UI_LoadResource("*111");
ri.UI_LoadResource("*111");
R_Sphere_InitLights();
UI_LoadResource("*112");
ri.UI_LoadResource("*112");
R_InitTerrain();
UI_LoadResource("*113");
ri.UI_LoadResource("*113");
R_InitStaticModels();
UI_LoadResource("*114");
ri.UI_LoadResource("*114");
R_LevelMarksLoad(name);
UI_LoadResource("*115");
ri.UI_LoadResource("*115");
R_VisDebugLoad(name);
UI_LoadResource("*116");
ri.UI_LoadResource("*116");
}
/*

View file

@ -38,7 +38,7 @@ R_PerformanceCounters
=====================
*/
void R_PerformanceCounters( void ) {
if (fps->integer) {
if (r_fps->integer) {
ri.SetPerformanceCounters(
backEnd.pc.c_totalIndexes / 3,
backEnd.pc.c_vertexes,

View file

@ -34,6 +34,29 @@ static float s_fontHeightScale = 1.0;
static float s_fontGeneralScale = 1.0;
static float s_fontZ = 0.0;
void R_ShutdownFont() {
int i;
fontheader_t *header;
fontheader_sgl_t *header_sgl;
for (i = 0; i < s_numLoadedFonts; i++)
{
header = &s_loadedFonts[i];
if (header->charTable) {
ri.Free(header->charTable);
header->charTable = NULL;
}
memset(header, 0, sizeof(*header));
}
for (i = 0; i < s_numLoadedFonts; i++)
{
header_sgl = &s_loadedFonts_sgl[i];
memset(header_sgl, 0, sizeof(*header_sgl));
}
}
void R_SetFontHeightScale(float scale)
{
s_fontHeightScale = scale;
@ -331,7 +354,7 @@ fontheader_t* R_LoadFont(const char* name) {
else if (!Q_stricmp(token, "Chars"))
{
header->charTableLength = atoi(COM_Parse(&ref));
header->charTable = (fontchartable_t*)Z_Malloc(header->charTableLength * sizeof(fontchartable_t));
header->charTable = (fontchartable_t*)ri.Malloc(header->charTableLength * sizeof(fontchartable_t));
if (!header->charTable)
{
ri.Printf(PRINT_WARNING, "LoadFont: Couldn't alloc mem %s\n", name);
@ -363,7 +386,7 @@ fontheader_t* R_LoadFont(const char* name) {
break;
}
pRitFontNames[i] = (char*)Z_Malloc(strlen(token) + 1);
pRitFontNames[i] = (char*)ri.Malloc(strlen(token) + 1);
if (!pRitFontNames[i])
{
ri.Printf(PRINT_WARNING, "LoadFont: Couldn't alloc mem %s\n", name);
@ -468,13 +491,13 @@ fontheader_t* R_LoadFont(const char* name) {
// Free all allocated strings
for (i = 0; i < header->numPages; i++) {
Z_Free(pRitFontNames[i]);
ri.Free(pRitFontNames[i]);
}
if (error)
{
if (header->charTable) {
Z_Free(header->charTable);
ri.Free(header->charTable);
}
header->numPages = 0;

View file

@ -2373,7 +2373,7 @@ void SaveJPG(char * filename, int quality, int image_width, int image_height, un
jpeg_finish_compress(&cinfo);
/* After finish_compress, we can close the output file. */
ri.FS_WriteFile( filename, out, hackSize );
ri.ri.FS_WriteFile( filename, out, hackSize );
ri.Hunk_FreeTempMemory(out);
@ -2461,10 +2461,10 @@ static void R_LoadImage(const char* name, byte** pic, int* width, int* height, q
}
}
if (scr_initialized)
if (tr.registered)
{
Com_sprintf(tempName, sizeof(tempName), "n%s", name);
UI_LoadResource(tempName);
ri.UI_LoadResource(tempName);
}
}
@ -2943,32 +2943,32 @@ void R_DumpTextureMemory() {
char* Label1, * Label2;
fileHandle_t stat_file;
stat_file = FS_SV_FOpenFileWrite("textureuse.csv");
stat_file = ri.FS_OpenFileWrite("textureuse.csv");
Label1 = "Texture Name,";
FS_Write(Label1, strlen(Label1), stat_file);
ri.FS_Write(Label1, strlen(Label1), stat_file);
Label2 = "Size (kb),";
FS_Write(Label2, strlen(Label2), stat_file);
ri.FS_Write(Label2, strlen(Label2), stat_file);
Label1 = "Num Uses,";
FS_Write(Label1, strlen(Label1), stat_file);
ri.FS_Write(Label1, strlen(Label1), stat_file);
Label2 = "Miplevels\n";
FS_Write(Label2, strlen(Label2), stat_file);
ri.FS_Write(Label2, strlen(Label2), stat_file);
for (i = 0; i < tr.numImages; i++) {
image_t* image = &tr.images[i];
FS_Write(image->imgName, strlen(image->imgName), stat_file);
FS_Write(", ", 2, stat_file);
ri.FS_Write(image->imgName, strlen(image->imgName), stat_file);
ri.FS_Write(", ", 2, stat_file);
// Write the number of bytes (in KiB)
Q_snprintf(str_buffer, sizeof(str_buffer), "%d", image->bytesUsed >> 10);
FS_Write(str_buffer, strlen(str_buffer), stat_file);
FS_Write(", ", 2, stat_file);
ri.FS_Write(str_buffer, strlen(str_buffer), stat_file);
ri.FS_Write(", ", 2, stat_file);
// Write the sequence
Q_snprintf(str_buffer, sizeof(str_buffer), "%d", image->r_sequence);
FS_Write(str_buffer, strlen(str_buffer), stat_file);
FS_Write(", ", 2, stat_file);
ri.FS_Write(str_buffer, strlen(str_buffer), stat_file);
ri.FS_Write(", ", 2, stat_file);
}
}

View file

@ -270,6 +270,9 @@ cvar_t* r_anaglyphMode;
cvar_t* r_aviMotionJpegQuality;
cvar_t* r_screenshotJpegQuality;
cvar_t* r_developer;
cvar_t* r_fps;
static char infostring[8192];
static void AssertCvarRange( cvar_t *cv, float minVal, float maxVal, qboolean shouldBeIntegral )
@ -1564,14 +1567,14 @@ void R_Register( void )
r_static_shadermultiplier1 = ri.Cvar_Get("r_static_shadermultiplier1", "1", CVAR_SYSTEMINFO);
r_static_shadermultiplier2 = ri.Cvar_Get("r_static_shadermultiplier2", "1", CVAR_SYSTEMINFO);
r_static_shadermultiplier3 = ri.Cvar_Get("r_static_shadermultiplier3", "1", CVAR_SYSTEMINFO);
r_precacheimages = (cvar_t*)Cvar_Get("r_precacheimages", "0", 0);
r_precacheimages = ri.Cvar_Get("r_precacheimages", "0", 0);
ter_minMarkRadius = ri.Cvar_Get("ter_minMarkRadius", "8", CVAR_ARCHIVE);
ter_fastMarks = ri.Cvar_Get("ter_fastMarks", "1", CVAR_ARCHIVE);
r_alpha_foliage1 = ri.Cvar_Get("r_alpha_foliage1", "0.75", CVAR_CHEAT);
r_alpha_foliage2 = ri.Cvar_Get("r_alpha_foliage2", "0.75", CVAR_CHEAT);
r_blendtrees = ri.Cvar_Get("r_blendtrees", "0", CVAR_LATCH);
r_blendbushes = ri.Cvar_Get("r_blendbushes", "0", CVAR_LATCH);
fps = ri.Cvar_Get("fps", "0", 0);
r_fps = ri.Cvar_Get("fps", "0", 0);
r_loadjpg = ri.Cvar_Get("r_loadjpg", "1", CVAR_LATCH);
r_loadftx = ri.Cvar_Get("r_loadftx", "0", CVAR_LATCH);
@ -1599,6 +1602,7 @@ void R_Register( void )
// Added in OPM
//
r_developer = ri.Cvar_Get("developer", "", 0);
r_showSkeleton = ri.Cvar_Get("r_showSkeleton", "0", CVAR_CHEAT);
r_aviMotionJpegQuality = ri.Cvar_Get("r_aviMotionJpegQuality", "90", CVAR_ARCHIVE);
r_screenshotJpegQuality = ri.Cvar_Get("r_screenshotJpegQuality", "90", CVAR_ARCHIVE);
@ -1770,18 +1774,20 @@ void RE_Shutdown( qboolean destroyWindow ) {
Com_Memset( &glState, 0, sizeof( glState ) );
}
R_ShutdownFont();
tr.registered = qfalse;
}
extern qboolean scr_initialized;
//extern qboolean scr_initialized;
/*
** RE_BeginRegistration
*/
void RE_BeginRegistration(glconfig_t* glconfigOut) {
UI_LoadResource("*123");
scr_initialized = 0;
ri.UI_LoadResource("*123");
//scr_initialized = 0;
R_IssuePendingRenderCommands();
@ -1807,8 +1813,8 @@ void RE_BeginRegistration(glconfig_t* glconfigOut) {
tr.registered = qtrue;
scr_initialized = 1;
UI_LoadResource("*124");
//scr_initialized = 1;
ri.UI_LoadResource("*124");
}
/*
@ -1823,11 +1829,11 @@ void RE_EndRegistration( void ) {
if (r_precacheimages->integer) {
int start, end;
start = Sys_Milliseconds();
start = ri.Milliseconds();
RB_ShowImages(qtrue);
end = Sys_Milliseconds();
end = ri.Milliseconds();
Com_Printf("RB_ShowImages: %5.2f seconds\n", (float)((end - start) / 1000.f));
}
@ -1851,7 +1857,12 @@ GetRefAPI
@@@@@@@@@@@@@@@@@@@@@
*/
#ifdef USE_RENDERER_DLOPEN
Q_EXPORT refexport_t* QDECL GetRefAPI ( int apiVersion, refimport_t *rimp ) {
#else
refexport_t *GetRefAPI ( int apiVersion, refimport_t *rimp ) {
#endif
static refexport_t re;
ri = *rimp;

View file

@ -1644,6 +1644,8 @@ extern cvar_t* r_loadjpg;
extern cvar_t* r_loadftx;
extern cvar_t* r_showSkeleton;
extern cvar_t* r_developer;
extern cvar_t* r_fps;
//====================================================================
@ -2091,6 +2093,7 @@ FONT
=============================================================
*/
void R_ShutdownFont();
fontheader_t* R_LoadFont(const char* name);
void R_LoadFontShader(fontheader_sgl_t* font);
void R_DrawString(fontheader_t* font, const char* text, float x, float y, int maxlen, const float *pvVirtualScreen);

View file

@ -160,7 +160,7 @@ void DCLC_Save(void)
char map_time[32];
int littleValue;
hFile = FS_FOpenFileWrite(lm.szDCLFilename);
hFile = ri.FS_OpenFileWrite(lm.szDCLFilename);
if (!hFile) {
ri.Printf(PRINT_ALL, "R_SaveDCLFile: couldn't write to %s\n", lm.szDCLFilename);
}
@ -182,20 +182,20 @@ void DCLC_Save(void)
header.iNumDecals = LittleLong(iNumDecals);
header.iNumFragments = LittleLong(iNumFragments);
FS_Write(&header, sizeof(header), hFile);
ri.FS_Write(&header, sizeof(header), hFile);
//
// Write the map time
//
memset(map_time, 0, sizeof(map_time));
Q_strncpyz(map_time, ri.CM_MapTime(), sizeof(map_time));
FS_Write(map_time, sizeof(map_time), hFile);
ri.FS_Write(map_time, sizeof(map_time), hFile);
if (!iNumDecals) {
//
// Nothing to write
//
FS_FCloseFile(hFile);
ri.FS_CloseFile(hFile);
return;
}
@ -221,7 +221,7 @@ void DCLC_Save(void)
saveMark.bDoLighting = LittleLong(pMark->bDoLighting);
FS_Write(&saveMark, sizeof(saveMark), hFile);
ri.FS_Write(&saveMark, sizeof(saveMark), hFile);
}
for (pMark = lm.activeMarkDefs.pNextMark; pMark != &lm.activeMarkDefs; pMark = pMark->pNextMark) {
@ -232,8 +232,8 @@ void DCLC_Save(void)
savePoly.iIndex = LittleLong(pPoly->surf.iIndex);
savePoly.iNumVerts = LittleLong(pPoly->surf.numVerts);
FS_Write(&savePoly, sizeof(savePoly), hFile);
FS_Write(pPoly->verts, sizeof(pPoly->verts[0]) * savePoly.iNumVerts, hFile);
ri.FS_Write(&savePoly, sizeof(savePoly), hFile);
ri.FS_Write(pPoly->verts, sizeof(pPoly->verts[0]) * savePoly.iNumVerts, hFile);
}
}
@ -245,16 +245,16 @@ void DCLC_Save(void)
// No fragment to save
//
littleValue = 0;
FS_Write(&littleValue, sizeof(littleValue), hFile);
ri.FS_Write(&littleValue, sizeof(littleValue), hFile);
continue;
}
littleValue = LittleLong(pBmodel->iNumMarkFragment);
FS_Write(&littleValue, sizeof(int), hFile);
ri.FS_Write(&littleValue, sizeof(int), hFile);
for (j = 0; j < pBmodel->iNumMarkFragment; i++) {
littleValue = ((lmPoly_t *)pBmodel->pFirstMarkFragment[j])->viewCount;
FS_Write(&littleValue, sizeof(int), hFile);
ri.FS_Write(&littleValue, sizeof(int), hFile);
}
}
@ -266,20 +266,20 @@ void DCLC_Save(void)
// No fragment to save
//
littleValue = 0;
FS_Write(&littleValue, sizeof(littleValue), hFile);
ri.FS_Write(&littleValue, sizeof(littleValue), hFile);
continue;
}
littleValue = LittleLong(pLeaf->iNumMarkFragment);
FS_Write(&littleValue, sizeof(int), hFile);
ri.FS_Write(&littleValue, sizeof(int), hFile);
for (j = 0; j < pLeaf->iNumMarkFragment; j++) {
littleValue = ((lmPoly_t *)pLeaf->pFirstMarkFragment[j])->viewCount;
FS_Write(&littleValue, sizeof(int), hFile);
ri.FS_Write(&littleValue, sizeof(int), hFile);
}
}
FS_FCloseFile(hFile);
ri.FS_CloseFile(hFile);
}
/*
@ -1361,23 +1361,23 @@ void DCLC_GetInfo(void)
}
if (lm.pCurrentMark->fRotation == -1) {
Cvar_Set("dcl_shader", lm.pCurrentMark->markShader->name);
Cvar_SetValue("dcl_radius", lm.pCurrentMark->fRadius);
Cvar_SetValue("dcl_widthscale", lm.pCurrentMark->fWidthScale);
ri.Cvar_Set("dcl_shader", lm.pCurrentMark->markShader->name);
ri.Cvar_SetValue("dcl_radius", lm.pCurrentMark->fRadius);
ri.Cvar_SetValue("dcl_widthscale", lm.pCurrentMark->fWidthScale);
} else {
Cvar_Set("dcl_shader", lm.pCurrentMark->markShader->name);
Cvar_SetValue("dcl_radius", lm.pCurrentMark->fRadius);
Cvar_SetValue("dcl_heightscale", lm.pCurrentMark->fHeightScale);
Cvar_SetValue("dcl_heightscale", lm.pCurrentMark->fHeightScale);
Cvar_SetValue("dcl_widthscale", lm.pCurrentMark->fWidthScale);
Cvar_SetValue("dcl_rotation", lm.pCurrentMark->fRotation);
Cvar_SetValue("dcl_r", lm.pCurrentMark->color[0]);
Cvar_SetValue("dcl_g", lm.pCurrentMark->color[1]);
Cvar_SetValue("dcl_b", lm.pCurrentMark->color[2]);
ri.Cvar_Set("dcl_shader", lm.pCurrentMark->markShader->name);
ri.Cvar_SetValue("dcl_radius", lm.pCurrentMark->fRadius);
ri.Cvar_SetValue("dcl_heightscale", lm.pCurrentMark->fHeightScale);
ri.Cvar_SetValue("dcl_heightscale", lm.pCurrentMark->fHeightScale);
ri.Cvar_SetValue("dcl_widthscale", lm.pCurrentMark->fWidthScale);
ri.Cvar_SetValue("dcl_rotation", lm.pCurrentMark->fRotation);
ri.Cvar_SetValue("dcl_r", lm.pCurrentMark->color[0]);
ri.Cvar_SetValue("dcl_g", lm.pCurrentMark->color[1]);
ri.Cvar_SetValue("dcl_b", lm.pCurrentMark->color[2]);
}
Cvar_SetValue("dcl_alpha", lm.pCurrentMark->color[3]);
Cvar_SetValue("dcl_dolighting", lm.pCurrentMark->bDoLighting);
ri.Cvar_SetValue("dcl_alpha", lm.pCurrentMark->color[3]);
ri.Cvar_SetValue("dcl_dolighting", lm.pCurrentMark->bDoLighting);
lm.bAutoApplySettings = qtrue;
}
@ -1494,7 +1494,7 @@ DCLC_RandomRoll
*/
void DCLC_RandomRoll(void)
{
Cvar_SetValue("dcl_rotation", random() * 360.0);
ri.Cvar_SetValue("dcl_rotation", random() * 360.0);
}
/*
@ -1735,14 +1735,14 @@ void R_UpdateLevelMarksSystem()
if (shader != tr.defaultShader && lm.pCurrentMark->markShader != shader) {
lm.pCurrentMark->markShader = shader;
// Set the decal radius
Cvar_SetValue("dcl_radius", 16.0);
ri.Cvar_SetValue("dcl_radius", 16.0);
dcl_radius->modified = qfalse;
// Set the decal scale
Cvar_SetValue(
ri.Cvar_SetValue(
"dcl_heightscale", shader->unfoggedStages[0]->bundle[0].image[0]->height / 16.0 * 0.5
);
Cvar_SetValue("dcl_widthscale", shader->unfoggedStages[0]->bundle[0].image[0]->width / 16.0 * 0.5);
ri.Cvar_SetValue("dcl_widthscale", shader->unfoggedStages[0]->bundle[0].image[0]->width / 16.0 * 0.5);
bDoUpdate = qtrue;
}

View file

@ -229,7 +229,7 @@ static qhandle_t R_RegisterModelInternal( const char *name, qboolean bBeginTiki,
}
else if( !stricmp( ptr, "tik" ) )
{
mod->d.tiki = TIKI_RegisterTikiFlags( name, use );
mod->d.tiki = ri.TIKI_RegisterTikiFlags( name, use );
Q_strncpyz( mod->name, name, sizeof( mod->name ) );
if( mod->d.tiki )
@ -373,7 +373,7 @@ float R_ModelRadius( qhandle_t handle ) {
}
break;
case MOD_TIKI:
return TIKI_GlobalRadius( model->d.tiki );
return ri.TIKI_GlobalRadius( model->d.tiki );
case MOD_SPRITE:
maxRadius = model->d.sprite->width * model->d.sprite->scale * 0.5;
w = model->d.sprite->height * model->d.sprite->scale * 0.5;
@ -411,7 +411,7 @@ void R_ModelBounds( qhandle_t handle, vec3_t mins, vec3_t maxs ) {
VectorCopy( model->d.bmodel->bounds[ 1 ], maxs );
break;
case MOD_TIKI:
TIKI_CalculateBounds( model->d.tiki, 1.0, mins, maxs );
ri.TIKI_CalculateBounds( model->d.tiki, 1.0, mins, maxs );
break;
case MOD_SPRITE:
mins[ 0 ] = -model->d.sprite->width * model->d.sprite->scale * 0.5;
@ -424,6 +424,8 @@ void R_ModelBounds( qhandle_t handle, vec3_t mins, vec3_t maxs ) {
}
}
#if 0
// Replaced by TIKI_FindSkelByHeader
/*
====================
GetModelPath
@ -455,6 +457,7 @@ const char *GetModelPath( skelHeaderGame_t *skelmodel ) {
return NULL;
}
#endif
/*
====================
@ -508,6 +511,22 @@ int GetLodCutoff( skelHeaderGame_t *skelmodel, float lod_val, int renderfx ) {
}
}
/*
===============
R_SaveLODFile
===============
*/
static void R_SaveLODFile(const char *path, lodControl_t *LOD)
{
fileHandle_t file = ri.FS_OpenFileWrite(path);
if (!file) {
ri.Printf(PRINT_WARNING, "SaveLODFile: Failed to open file %s\n", path);
return;
}
ri.FS_Write(LOD, sizeof(lodControl_t), file);
}
/*
====================
GetToolLodCutoff
@ -532,32 +551,32 @@ int GetToolLodCutoff( skelHeaderGame_t *skelmodel, float lod_val ) {
if( lod_save->integer == 1 )
{
Cvar_Set( "lod_save", "0" );
Q_strncpyz( lodPath, GetModelPath( skelmodel ), sizeof( lodPath ) );
ri.Cvar_Set( "lod_save", "0" );
Q_strncpyz( lodPath, ri.TIKI_FindSkelByHeader( skelmodel )->path, sizeof( lodPath ) );
ext = strstr( lodPath, "skd" );
strcpy( ext, "lod" );
SaveLODFile( lodPath, LOD );
R_SaveLODFile( lodPath, LOD );
}
if( lod_mesh->modified )
{
lod_mesh->modified = qfalse;
Cvar_Set( "lod_minLOD", va( "%f", LOD->minMetric ) );
Cvar_Set( "lod_maxLOD", va( "%f", LOD->maxMetric ) );
Cvar_Set( "lod_LOD_slider", va( "%f", 0.5 ) );
Cvar_Set( "lod_curve_0_slider", va( "%f", LOD->curve[ 0 ].val / totalRange ) );
Cvar_Set( "lod_curve_1_slider", va( "%f", LOD->curve[ 1 ].val / totalRange ) );
Cvar_Set( "lod_curve_2_slider", va( "%f", LOD->curve[ 2 ].val / totalRange ) );
Cvar_Set( "lod_curve_3_slider", va( "%f", LOD->curve[ 3 ].val / totalRange ) );
Cvar_Set( "lod_curve_4_slider", va( "%f", LOD->curve[ 4 ].val / totalRange ) );
ri.Cvar_Set( "lod_minLOD", va( "%f", LOD->minMetric ) );
ri.Cvar_Set( "lod_maxLOD", va( "%f", LOD->maxMetric ) );
ri.Cvar_Set( "lod_LOD_slider", va( "%f", 0.5 ) );
ri.Cvar_Set( "lod_curve_0_slider", va( "%f", LOD->curve[ 0 ].val / totalRange ) );
ri.Cvar_Set( "lod_curve_1_slider", va( "%f", LOD->curve[ 1 ].val / totalRange ) );
ri.Cvar_Set( "lod_curve_2_slider", va( "%f", LOD->curve[ 2 ].val / totalRange ) );
ri.Cvar_Set( "lod_curve_3_slider", va( "%f", LOD->curve[ 3 ].val / totalRange ) );
ri.Cvar_Set( "lod_curve_4_slider", va( "%f", LOD->curve[ 4 ].val / totalRange ) );
}
Cvar_Set( "lod_curve_0_val", va( "%f", lod_curve_0_slider->value * totalRange ) );
Cvar_Set( "lod_curve_1_val", va( "%f", lod_curve_1_slider->value * totalRange ) );
Cvar_Set( "lod_curve_2_val", va( "%f", lod_curve_2_slider->value * totalRange ) );
Cvar_Set( "lod_curve_3_val", va( "%f", lod_curve_3_slider->value * totalRange ) );
Cvar_Set( "lod_curve_4_val", va( "%f", lod_curve_4_slider->value * totalRange ) );
ri.Cvar_Set( "lod_curve_0_val", va( "%f", lod_curve_0_slider->value * totalRange ) );
ri.Cvar_Set( "lod_curve_1_val", va( "%f", lod_curve_1_slider->value * totalRange ) );
ri.Cvar_Set( "lod_curve_2_val", va( "%f", lod_curve_2_slider->value * totalRange ) );
ri.Cvar_Set( "lod_curve_3_val", va( "%f", lod_curve_3_slider->value * totalRange ) );
ri.Cvar_Set( "lod_curve_4_val", va( "%f", lod_curve_4_slider->value * totalRange ) );
LOD->minMetric = lod_minLOD->value;
LOD->maxMetric = lod_maxLOD->value;
@ -567,7 +586,7 @@ int GetToolLodCutoff( skelHeaderGame_t *skelmodel, float lod_val ) {
LOD->curve[ 3 ].val = lod_curve_3_val->value;
LOD->curve[ 4 ].val = lod_curve_4_val->value;
TIKI_CalcLodConsts( LOD );
ri.TIKI_CalcLodConsts( LOD );
return GetLodCutoff( skelmodel, lod_val, 0 );
}
@ -604,7 +623,7 @@ void RB_DrawSkeletor(trRefEntity_t* ent) {
skeletor_c *skeletor;
tiki = R_Model_GetHandle( ent->e.hModel );
skeletor = ( skeletor_c * )TIKI_GetSkeletor( tiki, ENTITYNUM_NONE );
skeletor = ( skeletor_c * )ri.TIKI_GetSkeletor( tiki, ENTITYNUM_NONE );
if( r_showSkeleton->integer == 1 ) {
//vec3_t vForward, vRight, vUp;
@ -615,11 +634,10 @@ void RB_DrawSkeletor(trRefEntity_t* ent) {
qglLineWidth( 3 );
qglBegin( GL_LINES );
for( i = 0; i < tiki->m_boneList.NumChannels(); i++ ) { // draw a skeleton
for( i = 0; i < ri.TIKI_GetNumChannels(tiki); i++ ) { // draw a skeleton
ori = R_GetTagPositionAndOrientation( &ent->e, i );
iParentBone = skeletor->GetBoneParent( i );
iParentBone = ri.SKEL_GetBoneParent(skeletor, i);
if( iParentBone != -1 ) {
parent_or = R_GetTagPositionAndOrientation( &ent->e, iParentBone );
@ -665,8 +683,8 @@ void RB_DrawSkeletor(trRefEntity_t* ent) {
qglLineWidth( 3 );
qglBegin( GL_LINES );
for( i = 0; i < tiki->m_boneList.NumChannels(); i++ ) {
iParentBone = skeletor->GetBoneParent( i );
for( i = 0; i < ri.TIKI_GetNumChannels(tiki); i++ ) {
iParentBone = ri.SKEL_GetBoneParent(skeletor, i);
if( iParentBone > 0 ) {
ori = R_GetTagPositionAndOrientation( &ent->e, i );
@ -680,7 +698,7 @@ void RB_DrawSkeletor(trRefEntity_t* ent) {
qglEnd();
qglBegin( GL_LINES );
for( i = 0; i < tiki->m_boneList.NumChannels(); i++ ) {
for( i = 0; i < ri.TIKI_GetNumChannels(tiki); i++ ) {
vec3_t up, down, front;
ori = R_GetTagPositionAndOrientation( &ent->e, i );
@ -754,7 +772,7 @@ void R_AddSkelSurfaces( trRefEntity_t *ent ) {
outbones = &TIKI_Skel_Bones[ TIKI_Skel_Bones_Index ];
num_tags = tiki->m_boneList.NumChannels();
num_tags = ri.TIKI_GetNumChannels(tiki);
if( num_tags + TIKI_Skel_Bones_Index > MAX_SKELBONES )
{
@ -815,7 +833,7 @@ void R_AddSkelSurfaces( trRefEntity_t *ent ) {
}
}
newFrame = ( skelAnimFrame_t * )ri.Hunk_AllocateTempMemory( sizeof( skelAnimFrame_t ) + tiki->m_boneList.NumChannels() * sizeof( SkelMat4 ) );
newFrame = ( skelAnimFrame_t * )ri.Hunk_AllocateTempMemory( sizeof( skelAnimFrame_t ) + ri.TIKI_GetNumChannels(tiki) * sizeof( SkelMat4 ) );
R_GetFrame( &ent->e, newFrame );
if (lod_tool->integer || iRadiusCull != CULL_CLIP || R_CullSkelModel(tiki, &ent->e, newFrame, tiki_scale, tiki_localorigin) != CULL_OUT)
@ -852,12 +870,12 @@ void R_AddSkelSurfaces( trRefEntity_t *ent ) {
//
// get the skeletor
//
skeletor = ( skeletor_c * )TIKI_GetSkeletor( tiki, ent->e.entityNumber );
skeletor = ( skeletor_c * )ri.TIKI_GetSkeletor( tiki, ent->e.entityNumber );
//
// add morphs
//
added = skeletor->GetMorphWeightFrame( ent->e.frameInfo[ 0 ].index, ent->e.frameInfo[ 0 ].time, &skeletorMorphCache[ skeletorMorphCacheIndex ] );
added = ri.SKEL_GetMorphWeightFrame( skeletor, ent->e.frameInfo[ 0 ].index, ent->e.frameInfo[ 0 ].time, &skeletorMorphCache[ skeletorMorphCacheIndex ] );
ent->e.morphstart = skeletorMorphCacheIndex;
if( added )
@ -874,7 +892,7 @@ void R_AddSkelSurfaces( trRefEntity_t *ent ) {
bsurf = &ent->e.surfaces[ 0 ];
for( mesh = 0; mesh < tiki->numMeshes; mesh++ )
{
skelHeaderGame_t *skelmodel = TIKI_GetSkel( tiki->mesh[ mesh ] );
skelHeaderGame_t *skelmodel = ri.TIKI_GetSkel( tiki->mesh[ mesh ] );
if( !skelmodel )
{
@ -1064,7 +1082,7 @@ void RB_SkelMesh( skelSurfaceGame_t *sf ) {
bFound = qfalse;
for( mesh = 0; mesh < tiki->numMeshes; mesh++ )
{
skelmodel = TIKI_GetSkel( tiki->mesh[ mesh ] );
skelmodel = ri.TIKI_GetSkel( tiki->mesh[ mesh ] );
psurface = skelmodel->pSurfaces;
// find the surface
@ -1246,14 +1264,14 @@ void RB_SkelMesh( skelSurfaceGame_t *sf ) {
channelNum = skelmodel->pBones[weight->boneIndex].channel;
}
boneNum = tiki->m_boneList.LocalChannel(channelNum);
boneNum = ri.TIKI_GetLocalChannel(tiki, channelNum);
bone = &bones[boneNum];
SkelVertGetNormal(newVerts, bone, normal);
for (weightNum = 0; weightNum < newVerts->numWeights; weightNum++) {
channelNum = skelmodel->pBones[weight->boneIndex].channel;
boneNum = tiki->m_boneList.LocalChannel(channelNum);
boneNum = ri.TIKI_GetLocalChannel(tiki, channelNum);
bone = &bones[boneNum];
if (!weightNum) {
@ -1352,14 +1370,14 @@ void RB_SkelMesh( skelSurfaceGame_t *sf ) {
weight = (skelWeight_t*)((byte*)newVerts + sizeof(skeletorVertex_t) + sizeof(skeletorMorph_t) * newVerts->numMorphs);
channelNum = skelmodel->pBones[weight->boneIndex].channel;
boneNum = tiki->m_boneList.LocalChannel(channelNum);
boneNum = ri.TIKI_GetLocalChannel(tiki, channelNum);
bone = &bones[boneNum];
SkelVertGetNormal(newVerts, bone, normal);
for (weightNum = 0; weightNum < newVerts->numWeights; weightNum++) {
channelNum = skelmodel->pBones[weight->boneIndex].channel;
boneNum = tiki->m_boneList.LocalChannel(channelNum);
boneNum = ri.TIKI_GetLocalChannel(tiki, channelNum);
bone = &bones[boneNum];
SkelWeightGetXyz(weight, bone, out);
@ -1501,7 +1519,7 @@ void RB_StaticMesh(staticSurface_t *staticSurf)
assert(surf->pStaticXyz);
meshNum = staticSurf->meshNum;
skelmodel = TIKI_GetSkel(tiki->mesh[meshNum]);
skelmodel = ri.TIKI_GetSkel(tiki->mesh[meshNum]);
//
// Process LOD
@ -1673,7 +1691,7 @@ void R_PrintInfoWorldtris( void ) {
totalNumTris += numTris;
tiki = backEnd.refdef.entities[i].e.tiki;
skelmodel = TIKI_GetSkel(tiki->mesh[0]);
skelmodel = ri.TIKI_GetSkel(tiki->mesh[0]);
Com_Printf("ent: %i, tris: %i, %s, version: %i\n", i, numTris, tiki->a->name, skelmodel->version);
}
@ -1690,7 +1708,7 @@ void R_PrintInfoWorldtris( void ) {
totalNumTris += numTris;
tiki = backEnd.refdef.staticModels[i].tiki;
skelmodel = TIKI_GetSkel(tiki->mesh[0]);
skelmodel = ri.TIKI_GetSkel(tiki->mesh[0]);
Com_Printf("sm: %i, tris: %i, %s, version: %i\n", i, numTris, tiki->a->name, skelmodel->version);
}
@ -1719,7 +1737,7 @@ void R_UpdatePoseInternal( refEntity_t *model ) {
tr.skel_index[ model->entityNumber ] = tr.frame_skel_index;
}
ri.TIKI_SetPoseInternal( TIKI_GetSkeletor( model->tiki, model->entityNumber ), model->frameInfo, model->bone_tag, model->bone_quat, model->actionWeight );
ri.TIKI_SetPoseInternal( ri.TIKI_GetSkeletor( model->tiki, model->entityNumber ), model->frameInfo, model->bone_tag, model->bone_quat, model->actionWeight );
}
/*
@ -1732,7 +1750,7 @@ void RE_ForceUpdatePose( refEntity_t *model ) {
tr.skel_index[ model->entityNumber ] = tr.frame_skel_index;
}
ri.TIKI_SetPoseInternal( TIKI_GetSkeletor( model->tiki, model->entityNumber ), model->frameInfo, model->bone_tag, model->bone_quat, model->actionWeight );
ri.TIKI_SetPoseInternal( ri.TIKI_GetSkeletor( model->tiki, model->entityNumber ), model->frameInfo, model->bone_tag, model->bone_quat, model->actionWeight );
}
/*
@ -1940,7 +1958,7 @@ void R_CountTikiLodTris(dtiki_t* tiki, float lodpercentage, int* render_tris, in
for (int i = 0; i < tiki->numMeshes; i++)
{
skelHeaderGame_t *skelmodel = TIKI_GetSkel(tiki->mesh[i]);
skelHeaderGame_t *skelmodel = ri.TIKI_GetSkel(tiki->mesh[i]);
skelSurfaceGame_t *surface = skelmodel->pSurfaces;
for (int j = 0; j < skelmodel->numSurfaces; j++)

View file

@ -1860,10 +1860,10 @@ void RB_EndSurface( void ) {
//
// draw debugging stuff
//
if (r_showtris->integer && developer->integer) {
if (r_showtris->integer && r_developer->integer) {
DrawTris(input, r_showtris->integer);
}
if (r_shownormals->integer && developer->integer) {
if (r_shownormals->integer && r_developer->integer) {
DrawNormals(input);
}
}

View file

@ -86,16 +86,16 @@ void R_InitStaticModels(void)
Com_sprintf(szTemp, sizeof(szTemp), "models/%s", pSM->model);
}
FS_CanonicalFilename(szTemp);
exists = TIKI_FindTiki(szTemp) != NULL;
pSM->tiki = TIKI_RegisterTiki(szTemp);
ri.FS_CanonicalFilename(szTemp);
exists = ri.TIKI_FindTiki(szTemp) != NULL;
pSM->tiki = ri.TIKI_RegisterTikiFlags(szTemp, qfalse);
if (!pSM->tiki) {
ri.Printf(PRINT_WARNING, "^~^~^: Warning: Cannot Load Static Model %s\n", szTemp);
continue;
}
pSM->radius = TIKI_GlobalRadius(pSM->tiki);
pSM->radius = ri.TIKI_GlobalRadius(pSM->tiki);
//
// register shaders
@ -121,7 +121,7 @@ void R_InitStaticModels(void)
}
// prepare the skeleton frame for the static model
TIKI_GetSkelAnimFrame(pSM->tiki, bones, &radius, &mins, &maxs);
ri.TIKI_GetSkelAnimFrame(pSM->tiki, bones, &radius, &mins, &maxs);
pSM->cull_radius = radius * pSM->tiki->load_scale * pSM->scale;
// Suggestion:
@ -129,7 +129,7 @@ void R_InitStaticModels(void)
if (!exists) {
for (j = 0; j < pSM->tiki->numMeshes; j++) {
skelHeaderGame_t *skelmodel = TIKI_GetSkel(pSM->tiki->mesh[j]);
skelHeaderGame_t *skelmodel = ri.TIKI_GetSkel(pSM->tiki->mesh[j]);
skelSurfaceGame_t *surf;
if (!skelmodel) {
@ -168,8 +168,7 @@ void R_InitStaticModels(void)
+ vert->numMorphs * sizeof(skeletorMorph_t));
if (j > 0) {
channel =
pSM->tiki->m_boneList.GetLocalFromGlobal(skelmodel->pBones[weight->boneIndex].channel);
channel = ri.TIKI_GetLocalChannel(pSM->tiki, skelmodel->pBones[weight->boneIndex].channel);
} else {
channel = weight->boneIndex;
}
@ -365,7 +364,7 @@ void R_AddStaticModelSurfaces(void)
//
dsurf = tiki->surfaces;
for (int mesh = 0; mesh < tiki->numMeshes; mesh++) {
skelHeaderGame_t *skelmodel = TIKI_GetSkel(tiki->mesh[mesh]);
skelHeaderGame_t *skelmodel = ri.TIKI_GetSkel(tiki->mesh[mesh]);
skelSurfaceGame_t *surface;
staticSurface_t *s_surface;
shader_t *shader;
@ -572,7 +571,7 @@ void R_PrintInfoStaticModels()
Com_Printf("Total static models rendered: %d\n", iRenderCount);
for (i = 0; i < count; i++) {
skelHeaderGame_t *skelmodel = TIKI_GetSkel(tikis[i]->mesh[0]);
skelHeaderGame_t *skelmodel = ri.TIKI_GetSkel(tikis[i]->mesh[0]);
Com_Printf(
"model: %s, version: %d, count: %d,\n culling min %.1f %.1f %.1f, max %.1f %.1f %.1f, radius %.1f\n",

View file

@ -0,0 +1,60 @@
/*
===========================================================================
Copyright (C) 2010 James Canete (use.less01@gmail.com)
This file is part of Quake III Arena source code.
Quake III Arena source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
Quake III Arena source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Quake III Arena source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
// tr_subs.c - common function replacements for modular renderer
#include "tr_local.h"
void QDECL Com_Printf( const char *msg, ... )
{
va_list argptr;
char text[1024];
va_start(argptr, msg);
Q_vsnprintf(text, sizeof(text), msg, argptr);
va_end(argptr);
ri.Printf(PRINT_ALL, "%s", text);
}
void QDECL Com_DPrintf( const char *msg, ... )
{
va_list argptr;
char text[1024];
va_start(argptr, msg);
Q_vsnprintf(text, sizeof(text), msg, argptr);
va_end(argptr);
ri.Printf(PRINT_DEVELOPER, "%s", text);
}
void QDECL Com_Error( int level, const char *error, ... )
{
va_list argptr;
char text[1024];
va_start(argptr, error);
Q_vsnprintf(text, sizeof(text), error, argptr);
va_end(argptr);
ri.Error(level, "%s", text);
}

View file

@ -684,9 +684,9 @@ static void R_PreTessellateTerrain()
R_IssuePendingRenderCommands();
if (ter_maxtris->integer < 4 * numTerrainPatches) {
Cvar_SetValue("ter_maxtris", 4 * numTerrainPatches);
ri.Cvar_SetValue("ter_maxtris", 4 * numTerrainPatches);
} else if (ter_maxtris->integer > 65535) {
Cvar_SetValue("ter_maxtris", 65535);
ri.Cvar_SetValue("ter_maxtris", 65535);
}
Com_DPrintf("Using ter_maxtris = %d\n", ter_maxtris->integer);
@ -1602,7 +1602,7 @@ void R_TerrainCrater_f(void)
{
vec3_t dir;
if (!Cvar_VariableIntegerValue("cheats")) {
if (!ri.Cvar_VariableIntegerValue("cheats")) {
//
// Added in OPM
// This command may be used for debugging purposes.
@ -1634,7 +1634,7 @@ void R_InitTerrain()
ter_maxtris = ri.Cvar_Get("ter_maxtris", "24576", CVAR_TERRAIN_LATCH);
ter_count = ri.Cvar_Get("ter_count", "0", 0);
Cmd_AddCommand("ter_restart", R_TerrainRestart_f);
ri.Cmd_AddCommand("ter_restart", R_TerrainRestart_f);
R_PreTessellateTerrain();
for (i = 0; i < TERRAIN_TABLE_SIZE; i++) {

View file

@ -335,8 +335,8 @@ void R_VisDebug()
LoadPortals(buffer);
}
leafnum = CM_PointLeafnum(tr.refdef.vieworg);
cluster = CM_LeafCluster(leafnum);
leafnum = ri.CM_PointLeafnum(tr.refdef.vieworg);
cluster = ri.CM_LeafCluster(leafnum);
if (cluster < 0) {
return;
}

View file

@ -774,7 +774,7 @@ qboolean R_inPVS( const vec3_t p1, const vec3_t p2 ) {
byte *vis;
leaf = R_PointInLeaf( p1 );
vis = CM_ClusterPVS( leaf->cluster );
vis = ri.CM_ClusterPVS( leaf->cluster );
leaf = R_PointInLeaf( p2 );
if ( !(vis[leaf->cluster>>3] & (1<<(leaf->cluster&7))) ) {

View file

@ -2,11 +2,11 @@ cmake_minimum_required(VERSION 3.12)
project(omohsdl)
file(GLOB SOURCES_SDL_CLIENT
set(SOURCES_SDL_CLIENT
"./sdl_input.c"
)
file(GLOB SOURCES_SDL_GL
set(SOURCES_SDL_GL
"./sdl_gamma.c"
"./sdl_glimp.c"
)

View file

@ -2,14 +2,27 @@ cmake_minimum_required(VERSION 3.12)
project(omohtiki)
file(GLOB_RECURSE SOURCES_TIKI "./*.c" "./*.cpp")
set(SOURCES_TIKI
"./tiki_anim.cpp"
"./tiki_cache.cpp"
"./tiki_commands.cpp"
"./tiki_files.cpp"
"./tiki_frame.cpp"
"./tiki_imports.cpp"
"./tiki_parse.cpp"
"./tiki_skel.cpp"
"./tiki_surface.cpp"
"./tiki_tag.cpp"
"./tiki_utility.cpp"
)
set(COMMON_TIKI_SRCS
set(SOURCES_TIKI_COMMON
"../qcommon/tiki_main.cpp"
"../qcommon/tiki_script.cpp"
)
add_library(omohtiki STATIC ${SOURCES_TIKI} ${COMMON_TIKI_SRCS})
add_library(omohtiki STATIC ${SOURCES_TIKI} ${SOURCES_TIKI_COMMON})
target_compile_features(omohtiki PRIVATE cxx_nullptr)
target_compile_features(omohtiki PRIVATE c_variadic_macros)
target_link_libraries(omohtiki PUBLIC qcommon)

View file

@ -1051,6 +1051,42 @@ skelcache_t *TIKI_FindSkel(const char *path)
return NULL;
}
/*
===============
TIKI_FindSkelByHeader
Added in OPM
Return the skelcache associated with the specified skelmodel
===============
*/
skelcache_t *TIKI_FindSkelByHeader(skelHeaderGame_t *skelmodel)
{
int i;
int num;
skelcache_t *cache;
num = cache_numskel;
for (i = 0; i < TIKI_MAX_SKELCACHE; i++) {
cache = &skelcache[i];
if (!cache->skel) {
continue;
}
if (cache->skel == skelmodel) {
return cache;
}
if (num == 0) {
break;
}
num--;
}
return NULL;
}
/*
===============
TIKI_FindFreeSkel

View file

@ -37,6 +37,7 @@ extern "C" {
void TIKI_FreeSkel(int index);
void TIKI_FreeSkelCache(skelcache_t *cache);
skelcache_t *TIKI_FindSkel(const char *path);
skelcache_t *TIKI_FindSkelByHeader(skelHeaderGame_t *skelmodel);
skelcache_t *TIKI_FindFreeSkel(void);
int TIKI_RegisterSkel(const char *path, dtiki_t *tiki);

View file

@ -126,6 +126,12 @@ typedef struct uiimport_s {
const char *( *GetConfigstring )( int index );
void ( *UI_CloseDMConsole )( void );
void ( *GetClipboardData )( char *buf, int buflen );
//
// Added in OPM
//
int (*GetRefSequence)(void);
qboolean (*IsRendererRegistered)(void);
} uiimport_t;
#if 1

View file

@ -83,11 +83,23 @@ const unsigned char DBCS_Tokin_Korean[] = {
int UIFont::CodeSearch(unsigned short uch)
{
CheckRefreshFont();
if (!m_font) {
return -1;
}
return UI_FontCodeSearch(m_font, uch);
}
bool UIFont::DBCSIsLeadByte(unsigned short uch)
{
CheckRefreshFont();
if (!m_font) {
return false;
}
return UI_FontDBCSIsLeadByte(m_font, uch);
}
@ -97,6 +109,12 @@ bool UIFont::DBCSIsMaekin(unsigned short uch)
const unsigned char *p;
unsigned char ch;
CheckRefreshFont();
if (!m_font) {
return false;
}
if (uch < 0x100) {
return false;
}
@ -135,6 +153,12 @@ bool UIFont::DBCSIsAtokin(unsigned short uch)
const unsigned char *p;
unsigned char ch;
CheckRefreshFont();
if (!m_font) {
return false;
}
if (uch < 0x100) {
return false;
}
@ -249,6 +273,9 @@ UIFont::UIFont()
color = UBlack;
setColor(color);
refHandle = uii.GetRefSequence();
name = "verdana-14";
}
UIFont::UIFont(const char *fn)
@ -272,10 +299,19 @@ void UIFont::setFont(const char *fontname)
if (!m_font) {
uii.Sys_Error(ERR_DROP, "Couldn't load font %s\n", fontname);
}
refHandle = uii.GetRefSequence();
name = fontname;
}
void UIFont::Print(float x, float y, const char *text, size_t maxlen, const float *virtualScreen)
{
CheckRefreshFont();
if (!m_font) {
return;
}
uii.Rend_SetColor(color);
uii.Rend_DrawString(m_font, text, x, y, maxlen, virtualScreen);
}
@ -489,11 +525,23 @@ void UIFont::PrintOutlinedJustified(
int UIFont::getMaxWidthIndex(const char *text, int maxlen)
{
CheckRefreshFont();
if (!m_font) {
return 0;
}
return UI_FontStringMaxWidth(m_font, text, maxlen);
}
int UIFont::getWidth(const char *text, int maxlen)
{
CheckRefreshFont();
if (!m_font) {
return 0;
}
return UI_FontStringWidth(m_font, text, maxlen);
}
@ -503,8 +551,10 @@ int UIFont::getCharWidth(unsigned short ch)
int indirected;
float widthMul = 1.0f; // Added in OPM for easier readability
CheckRefreshFont();
if (!m_font) {
return 0;
return 4;
}
if (ch == '\t') {
@ -537,6 +587,8 @@ int UIFont::getHeight(const char *text, int maxlen, const float* virtualScale)
float height;
int i;
CheckRefreshFont();
if (!m_font) {
return 0;
}
@ -558,6 +610,8 @@ int UIFont::getHeight(const char *text, int maxlen, const float* virtualScale)
int UIFont::getHeight(const float* virtualScale)
{
CheckRefreshFont();
if (virtualScale) {
if (m_font) {
return (m_font->sgl[0]->height * virtualScale[0]);
@ -731,3 +785,11 @@ int UI_FontStringWidth(fontheader_t *pFont, const char *pszString, int iMaxLen)
return maxwidths * 256.0;
}
void UIFont::CheckRefreshFont() {
if (refHandle != uii.GetRefSequence()) {
setFont(name);
} else if (!uii.IsRendererRegistered()) {
m_font = NULL;
}
}

View file

@ -43,6 +43,12 @@ protected:
UColor color;
fontheader_t *m_font;
//
// Added in OPM
//
str name;
int refHandle;
public:
UIFont();
UIFont(const char *fn);
@ -67,6 +73,9 @@ public:
bool DBCSIsMaekin(unsigned short uch);
bool DBCSIsAtokin(unsigned short uch);
int DBCSGetWordBlockCount(const char* text, int maxlen);
private:
void CheckRefreshFont();
};
int UI_FontStringWidth(fontheader_t *pFont, const char *pszString, int iMaxLen);