From 5b176114cd27f3b7cf4dc1a5a5ec4edcc1265bef Mon Sep 17 00:00:00 2001 From: Razish Date: Fri, 1 Mar 2024 04:21:08 +1100 Subject: [PATCH] add LEGACYFIX_WEAPONATTACKANIM + LEGACYFIX_RUNWALKANIMS - JACoders/OpenJK#1211 misc loop overrun fixes - JACoders/OpenJK#1201 render local entities as late as possible - JACoders/OpenJK#1200 remove unused localents code add macos arm64 build to CI fix linux arm64 builds fix crash when being loaded by eternaljk-based engines (missing UI export) update readme --- .github/workflows/build.yml | 14 +- README.md | 46 +++- SConstruct | 8 +- cgame/cg_draw.cpp | 2 +- cgame/cg_effects.cpp | 480 ------------------------------------ cgame/cg_local.h | 38 +-- cgame/cg_localents.cpp | 284 +++------------------ cgame/cg_lualocalentity.cpp | 12 - cgame/cg_main.cpp | 121 ++++----- cgame/cg_media.cpp | 1 - cgame/cg_media.h | 1 - cgame/cg_newDraw.cpp | 2 +- cgame/cg_players.cpp | 14 +- cgame/cg_servercmds.cpp | 6 +- cgame/cg_smartentities.cpp | 2 +- cgame/cg_view.cpp | 11 +- game/NPC_stats.cpp | 2 +- game/bg_lua.cpp | 2 +- game/bg_lua.h | 2 + game/bg_misc.cpp | 30 ++- game/bg_panimate.cpp | 5 +- game/bg_pmove.cpp | 176 +++++++------ game/bg_public.h | 5 +- game/bg_saberLoad.cpp | 2 +- game/g_admin.cpp | 4 +- game/g_bot.cpp | 1 + game/g_client.cpp | 26 +- game/g_cmds.cpp | 4 + game/g_main.cpp | 83 ++++--- game/g_smartentities.cpp | 2 +- game/g_utils.cpp | 4 +- game/g_xcvar.h | 2 + ui/ui_cvar.cpp | 47 ++-- ui/ui_main.cpp | 20 ++ ui/ui_public.h | 143 +---------- ui/ui_shared.cpp | 6 +- 36 files changed, 428 insertions(+), 1180 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6c2b730..d1d2c0d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -141,12 +141,17 @@ jobs: macos: name: macOS ${{ matrix.arch }} ${{ matrix.build_type }} - runs-on: macos-12 + runs-on: ${{ matrix.runner }} strategy: fail-fast: false matrix: - arch: [x86_64] + runner: [macos-12, macos-14] build_type: [Debug, Release] + include: + - runner: macos-12 + arch: x86_64 + - runner: macos-14 + arch: arm64 steps: - uses: actions/checkout@v3 @@ -195,6 +200,7 @@ jobs: mv ./japp-linux-x86-Release/* japp-linux-x86.tar.gz mv ./japp-linux-x86_64-Release/* japp-linux-x86_64.tar.gz mv ./japp-macos-x86_64-Release/* japp-macos-x86_64.tar.gz + mv ./japp-macos-arm64-Release/* japp-macos-arm64.tar.gz - name: Create latest build uses: marvinpinto/action-automatic-releases@latest @@ -234,6 +240,10 @@ jobs: artifact_name: japp-macos-x86_64.tar.gz zip: false + - artifact_dir: japp-macos-arm64-Release + artifact_name: japp-macos-arm64.tar.gz + zip: false + steps: - uses: actions/checkout@v3 with: diff --git a/README.md b/README.md index 764c62a..c158646 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,9 @@ # ja++ -ja++ modification for jedi academy - best used with [openjk](http://github.com/JACoders/OpenJK) -see [japp.jkhub.org](http://japp.jkhub.org) for more information +ja++ modification for jedi academy - best used with [openjk](https://github.com/JACoders/OpenJK) +see [japp.jkhub.org](https://japp.jkhub.org) for more information. + +assets can be found here: [Razish/japp-assets](https://github.com/Razish/japp-assets) [![build](https://github.com/Razish/japp/actions/workflows/build.yml/badge.svg?branch=master)](https://github.com/Razish/japp/releases/tag/latest) @@ -11,35 +13,57 @@ see [japp.jkhub.org](http://japp.jkhub.org) for more information | - | - | - | - | | x86 | ✅ | ✅ | ❓ | | x86_64 | ✅ | ✅ | ✅ | -| Arm (RPi) | ❌ | ✅ | ❌ | -| Apple Silicon | ❌ | ❌ | ✅ | +| armhf | ❌ | ✅ | ❌ | +| arm64 | ❌ | ✅ | ✅ | ## development requirements (general) - Python 3.11 - [Scons](https://github.com/SCons/scons) 4.4 +- zip or 7zip on your `PATH` (for packaging) ### windows -[TDM-GCC](https://jmeubank.github.io/tdm-gcc/) or MSVC (if you pass `tools=default` to scons) +[TDM-GCC](https://jmeubank.github.io/tdm-gcc/) or Visual Studio (if you pass `tools=default` to scons) ### linux (debian-based) -- `git scons gcc g++ libreadline-dev` -- [asdf-vm](https://asdf-vm.com/guide/getting-started.html) (optional, recommended) +install packages: `git scons gcc g++ libreadline-dev libglib2.0-dev libgtk2.0-dev libnotify-dev` + +### asdf-vm + lua setup (optional, recommended) + +install [asdf-vm](https://asdf-vm.com/guide/getting-started.html): + +```sh +git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch v0.14.0 +``` + +add the following to your shell rc (e.g. `~/.bashrc`) and restart your shell: + +```sh +. "$HOME/.asdf/asdf.sh" +``` + +```sh +asdf plugin-add python +asdf plugin-add lua https://github.com/Stratus3D/asdf-lua.git +asdf install # install required versions +luarocks install luafilesystem +luarocks install luacheck +``` ## compiling -just run `scons` or `build.sh` +just run `scons` or `build.sh` followed by `lua package.lua` -Options: +options: - `force32` 1 to build a 32-bit binary on a 64-bit machine - `debug` 1 to generate debug information, 2 to also optimise code - `no_sql` 1 to disable MySQL/SQLite support - `no_crashhandler` 1 to disable the crash handler/logger functionality -Environment Variables +environment variables: - `NO_SSE` 1 to not generate SSE2 instructions - closer to basejka. This is used for official builds - `MORE_WARNINGS` 1 to enable more compiler warnings @@ -49,7 +73,7 @@ Environment Variables - Raz0r (lead) - AstralSerpent - Ensiform -- EpicLoyd +- Exmirai - Morabis - teh diff --git a/SConstruct b/SConstruct index b24510b..e633e5b 100644 --- a/SConstruct +++ b/SConstruct @@ -107,7 +107,7 @@ if bits == 32: else: raise RuntimeError("unexpected platform: " + target_plat) elif bits == 64: - if platform.machine()[:3] == "arm": + if platform.machine()[:3] == "arm" or platform.machine()[:5] == "aarch": arch = "arm64" else: arch = "x86_64" @@ -149,9 +149,9 @@ colours["orange"] = "\033[33m" if enableColours else "" colours["green"] = "\033[92m" if enableColours else "" colours["end"] = "\033[0m" if enableColours else "" -env["SHCCCOMSTR"] = env["SHCXXCOMSTR"] = env["CCCOMSTR"] = env[ - "CXXCOMSTR" -] = f"{colours['cyan']} compiling: {colours['white']}$SOURCE{colours['end']}" +env["SHCCCOMSTR"] = env["SHCXXCOMSTR"] = env["CCCOMSTR"] = env["CXXCOMSTR"] = ( + f"{colours['cyan']} compiling: {colours['white']}$SOURCE{colours['end']}" +) env["ARCOMSTR"] = f"{colours['orange']} archiving: {colours['white']}$TARGET{colours['end']}" env["RANLIBCOMSTR"] = f"{colours['orange']} indexing: {colours['white']}$TARGET{colours['end']}" env["ASCOMSTR"] = f"{colours['orange']}assembling: {colours['white']}$TARGET{colours['end']}" diff --git a/cgame/cg_draw.cpp b/cgame/cg_draw.cpp index 12ff9a1..218cdd7 100644 --- a/cgame/cg_draw.cpp +++ b/cgame/cg_draw.cpp @@ -3294,7 +3294,7 @@ static float CG_DrawTeamOverlay(float y, qboolean right, qboolean upper) { } else { xx = x + w - TINYCHAR_WIDTH * cgs.widthRatioCoef; } - for (j = 0; j <= PW_NUM_POWERUPS; j++) { + for (j = 0; j < PW_NUM_POWERUPS; j++) { if (ci->powerups & (1 << j)) { item = BG_FindItemForPowerup((powerup_e)j); diff --git a/cgame/cg_effects.cpp b/cgame/cg_effects.cpp index 86aa67d..1c1c6d1 100644 --- a/cgame/cg_effects.cpp +++ b/cgame/cg_effects.cpp @@ -6,115 +6,6 @@ #include "cg_local.h" #include "cg_media.h" -// Bullets shot underwater -void CG_BubbleTrail(vector3 *start, vector3 *end, float spacing) { - vector3 move; - vector3 vec; - float len; - int i; - -#if 0 - if ( cg_noProjectileTrail.integer ) { - return; - } -#endif - - VectorCopy(start, &move); - VectorSubtract(end, start, &vec); - len = VectorNormalize(&vec); - - // advance a random amount first - i = rand() % (int)spacing; - VectorMA(&move, i, &vec, &move); - - VectorScale(&vec, spacing, &vec); - - for (; i < len; i += spacing) { - localEntity_t *le; - refEntity_t *re; - - le = CG_AllocLocalEntity(); - le->leFlags = LEF_PUFF_DONT_SCALE; - le->leType = LE_MOVE_SCALE_FADE; - le->startTime = cg.time; - le->endTime = cg.time + 1000 + random() * 250; - le->lifeRate = 1.0f / (le->endTime - le->startTime); - - re = &le->refEntity; - re->shaderTime = cg.time / 1000.0f; - - re->reType = RT_SPRITE; - re->rotation = 0; - re->radius = 3; - re->customShader = 0; // media.gfx.world.waterBubble; - re->shaderRGBA[0] = 0xff; - re->shaderRGBA[1] = 0xff; - re->shaderRGBA[2] = 0xff; - re->shaderRGBA[3] = 0xff; - - le->color[3] = 1.0f; - - le->pos.trType = TR_LINEAR; - le->pos.trTime = cg.time; - VectorCopy(&move, &le->pos.trBase); - le->pos.trDelta.x = crandom() * 5; - le->pos.trDelta.y = crandom() * 5; - le->pos.trDelta.z = crandom() * 5 + 6; - - VectorAdd(&move, &vec, &move); - } -} - -// Adds a smoke puff or blood trail localEntity. -localEntity_t *CG_SmokePuff(const vector3 *p, const vector3 *vel, float radius, float r, float g, float b, float a, float duration, int startTime, - int fadeInTime, uint32_t leFlags, qhandle_t hShader) { - static int seed = 0x92; - localEntity_t *le; - refEntity_t *re; - // int fadeInTime = startTime + duration / 2; - - le = CG_AllocLocalEntity(); - le->leFlags = leFlags; - le->radius = radius; - - re = &le->refEntity; - re->rotation = Q_random(&seed) * 360; - re->radius = radius; - re->shaderTime = startTime / 1000.0f; - - le->leType = LE_MOVE_SCALE_FADE; - le->startTime = startTime; - le->fadeInTime = fadeInTime; - le->endTime = startTime + duration; - if (fadeInTime > startTime) { - le->lifeRate = 1.0f / (le->endTime - le->fadeInTime); - } else { - le->lifeRate = 1.0f / (le->endTime - le->startTime); - } - le->color[0] = r; - le->color[1] = g; - le->color[2] = b; - le->color[3] = a; - - le->pos.trType = TR_LINEAR; - le->pos.trTime = startTime; - VectorCopy(vel, &le->pos.trDelta); - VectorCopy(p, &le->pos.trBase); - - VectorCopy(p, &re->origin); - re->customShader = hShader; - - re->shaderRGBA[0] = le->color[0] * 0xff; - re->shaderRGBA[1] = le->color[1] * 0xff; - re->shaderRGBA[2] = le->color[2] * 0xff; - re->shaderRGBA[3] = 0xff; - - re->reType = RT_SPRITE; - re->radius = le->radius; - - return le; -} - void CG_TestLine(vector3 *start, vector3 *end, int time, uint32_t color, int radius) { localEntity_t *le; refEntity_t *re; @@ -148,40 +39,6 @@ void CG_TestLine(vector3 *start, vector3 *end, int time, uint32_t color, int rad // re->renderfx |= RF_DEPTHHACK; } -void CG_ThrowChunk(vector3 *origin, vector3 *velocity, qhandle_t hModel, int optionalSound, int startalpha) { - localEntity_t *le; - refEntity_t *re; - - le = CG_AllocLocalEntity(); - re = &le->refEntity; - - le->leType = LE_FRAGMENT; - le->startTime = cg.time; - le->endTime = le->startTime + 5000 + random() * 3000; - - VectorCopy(origin, &re->origin); - AxisCopy(axisDefault, re->axis); - re->hModel = hModel; - - le->pos.trType = TR_GRAVITY; - le->angles.trType = TR_GRAVITY; - VectorCopy(origin, &le->pos.trBase); - VectorCopy(velocity, &le->pos.trDelta); - VectorSet(&le->angles.trBase, 20, 20, 20); - VectorCopy(velocity, &le->angles.trDelta); - le->pos.trTime = cg.time; - le->angles.trTime = cg.time; - - le->leFlags = LEF_TUMBLE; - - le->angles.trBase.yaw = 180; - - le->bounceFactor = 0.3f; - le->bounceSound = optionalSound; - - le->forceAlpha = startalpha; -} - //---------------------------- // // Breaking Glass Technology @@ -546,63 +403,6 @@ void CG_GlassShatter(int entnum, vector3 *dmgPt, vector3 *dmgDir, float dmgRadiu // otherwise something awful has happened. } -// Throws glass shards from within a given bounding box in the world -void CG_GlassShatter_Old(int entnum, vector3 *org, vector3 *mins, vector3 *maxs) { - vector3 velocity, a, shardorg, dif, difx; - float windowmass; - float shardsthrow = 0; - char chunkname[256]; - - trap->S_StartSound(org, entnum, CHAN_BODY, trap->S_RegisterSound("sound/effects/glassbreak1.wav")); - - VectorSubtract(maxs, mins, &a); - - windowmass = VectorLength(&a); // should give us some idea of how big the chunk of glass is - - while (shardsthrow < windowmass) { - velocity.x = crandom() * 150; - velocity.y = crandom() * 150; - velocity.z = 150 + crandom() * 75; - - Com_sprintf(chunkname, sizeof(chunkname), "models/chunks/glass/glchunks_%i.md3", Q_irand(1, 6)); - VectorCopy(org, &shardorg); - - dif.x = (maxs->x - mins->x) / 2; - dif.y = (maxs->y - mins->y) / 2; - dif.z = (maxs->z - mins->z) / 2; - - if (dif.x < 2) - dif.x = 2; - if (dif.y < 2) - dif.y = 2; - if (dif.z < 2) - dif.z = 2; - - difx.x = Q_irand(1, (dif.x * 0.9f) * 2); - difx.y = Q_irand(1, (dif.y * 0.9f) * 2); - difx.z = Q_irand(1, (dif.z * 0.9f) * 2); - - if (difx.x > dif.x) - shardorg.x += difx.x - (dif.x); - else - shardorg.x -= difx.x; - if (difx.y > dif.y) - shardorg.y += difx.y - (dif.y); - else - shardorg.y -= difx.y; - if (difx.z > dif.z) - shardorg.z += difx.z - (dif.z); - else - shardorg.z -= difx.z; - - // CG_TestLine(org, shardorg, 5000, 0xFF0000u, 3); - - CG_ThrowChunk(&shardorg, &velocity, trap->R_RegisterModel(chunkname), 0, 254); - - shardsthrow += 10; - } -} - #define DEBRIS_SPECIALCASE_ROCK -1 #define DEBRIS_SPECIALCASE_CHUNKS -2 #define DEBRIS_SPECIALCASE_WOOD -3 @@ -618,110 +418,6 @@ int dbModels_Wood[NUM_DEBRIS_MODELS_WOOD]; int dbModels_Chunks[NUM_DEBRIS_MODELS_CHUNKS]; int dbModels_Rocks[NUM_DEBRIS_MODELS_ROCKS]; -// Throws specified debris from within a given bounding box in the world -void CG_CreateDebris(int entnum, vector3 *org, vector3 *mins, vector3 *maxs, int debrissound, int debrismodel) { - vector3 velocity, a, shardorg, dif, difx; - float windowmass; - float shardsthrow = 0; - int omodel = debrismodel; - - if (omodel == DEBRIS_SPECIALCASE_GLASS && !dbModels_Glass[0]) { // glass no longer exists, using it for metal. - dbModels_Glass[0] = trap->R_RegisterModel("models/chunks/metal/metal1_1.md3"); - dbModels_Glass[1] = trap->R_RegisterModel("models/chunks/metal/metal1_2.md3"); - dbModels_Glass[2] = trap->R_RegisterModel("models/chunks/metal/metal1_3.md3"); - dbModels_Glass[3] = trap->R_RegisterModel("models/chunks/metal/metal1_4.md3"); - dbModels_Glass[4] = trap->R_RegisterModel("models/chunks/metal/metal2_1.md3"); - dbModels_Glass[5] = trap->R_RegisterModel("models/chunks/metal/metal2_2.md3"); - dbModels_Glass[6] = trap->R_RegisterModel("models/chunks/metal/metal2_3.md3"); - dbModels_Glass[7] = trap->R_RegisterModel("models/chunks/metal/metal2_4.md3"); - } - if (omodel == DEBRIS_SPECIALCASE_WOOD && !dbModels_Wood[0]) { - dbModels_Wood[0] = trap->R_RegisterModel("models/chunks/crate/crate1_1.md3"); - dbModels_Wood[1] = trap->R_RegisterModel("models/chunks/crate/crate1_2.md3"); - dbModels_Wood[2] = trap->R_RegisterModel("models/chunks/crate/crate1_3.md3"); - dbModels_Wood[3] = trap->R_RegisterModel("models/chunks/crate/crate1_4.md3"); - dbModels_Wood[4] = trap->R_RegisterModel("models/chunks/crate/crate2_1.md3"); - dbModels_Wood[5] = trap->R_RegisterModel("models/chunks/crate/crate2_2.md3"); - dbModels_Wood[6] = trap->R_RegisterModel("models/chunks/crate/crate2_3.md3"); - dbModels_Wood[7] = trap->R_RegisterModel("models/chunks/crate/crate2_4.md3"); - } - if (omodel == DEBRIS_SPECIALCASE_CHUNKS && !dbModels_Chunks[0]) { - dbModels_Chunks[0] = trap->R_RegisterModel("models/chunks/generic/chunks_1.md3"); - dbModels_Chunks[1] = trap->R_RegisterModel("models/chunks/generic/chunks_2.md3"); - } - if (omodel == DEBRIS_SPECIALCASE_ROCK && !dbModels_Rocks[0]) { - dbModels_Rocks[0] = trap->R_RegisterModel("models/chunks/rock/rock1_1.md3"); - dbModels_Rocks[1] = trap->R_RegisterModel("models/chunks/rock/rock1_2.md3"); - dbModels_Rocks[2] = trap->R_RegisterModel("models/chunks/rock/rock1_3.md3"); - dbModels_Rocks[3] = trap->R_RegisterModel("models/chunks/rock/rock1_4.md3"); - /* - dbModels_Rocks[4] = trap->R_RegisterModel("models/chunks/rock/rock2_1.md3"); - dbModels_Rocks[5] = trap->R_RegisterModel("models/chunks/rock/rock2_2.md3"); - dbModels_Rocks[6] = trap->R_RegisterModel("models/chunks/rock/rock2_3.md3"); - dbModels_Rocks[7] = trap->R_RegisterModel("models/chunks/rock/rock2_4.md3"); - dbModels_Rocks[8] = trap->R_RegisterModel("models/chunks/rock/rock3_1.md3"); - dbModels_Rocks[9] = trap->R_RegisterModel("models/chunks/rock/rock3_2.md3"); - dbModels_Rocks[10] = trap->R_RegisterModel("models/chunks/rock/rock3_3.md3"); - dbModels_Rocks[11] = trap->R_RegisterModel("models/chunks/rock/rock3_4.md3"); - */ - } - - VectorSubtract(maxs, mins, &a); - - windowmass = VectorLength(&a); // should give us some idea of how big the chunk of glass is - - while (shardsthrow < windowmass) { - velocity.x = crandom() * 150; - velocity.y = crandom() * 150; - velocity.z = 150 + crandom() * 75; - - if (omodel == DEBRIS_SPECIALCASE_GLASS) - debrismodel = dbModels_Glass[Q_irand(0, NUM_DEBRIS_MODELS_GLASS - 1)]; - else if (omodel == DEBRIS_SPECIALCASE_WOOD) - debrismodel = dbModels_Wood[Q_irand(0, NUM_DEBRIS_MODELS_WOOD - 1)]; - else if (omodel == DEBRIS_SPECIALCASE_CHUNKS) - debrismodel = dbModels_Chunks[Q_irand(0, NUM_DEBRIS_MODELS_CHUNKS - 1)]; - else if (omodel == DEBRIS_SPECIALCASE_ROCK) - debrismodel = dbModels_Rocks[Q_irand(0, NUM_DEBRIS_MODELS_ROCKS - 1)]; - - VectorCopy(org, &shardorg); - - dif.x = (maxs->x - mins->x) / 2; - dif.y = (maxs->y - mins->y) / 2; - dif.z = (maxs->z - mins->z) / 2; - - if (dif.x < 2) - dif.x = 2; - if (dif.y < 2) - dif.y = 2; - if (dif.z < 2) - dif.z = 2; - - difx.x = Q_irand(1, (dif.x * 0.9f) * 2); - difx.y = Q_irand(1, (dif.y * 0.9f) * 2); - difx.z = Q_irand(1, (dif.z * 0.9f) * 2); - - if (difx.x > dif.x) - shardorg.x += difx.x - (dif.x); - else - shardorg.x -= difx.x; - if (difx.y > dif.y) - shardorg.y += difx.y - (dif.y); - else - shardorg.y -= difx.y; - if (difx.z > dif.z) - shardorg.z += difx.z - (dif.z); - else - shardorg.z -= difx.z; - - // CG_TestLine(org, shardorg, 5000, 0xFF0000u, 3); - - CG_ThrowChunk(&shardorg, &velocity, debrismodel, debrissound, 0); - - shardsthrow += 10; - } -} - // Used to find the player and shake the camera if close enough // intensity ranges from 1 (minor tremble) to 16 (major quake) void CG_ExplosionEffects(vector3 *origin, float intensity, int radius, int time) { @@ -1071,179 +767,3 @@ void CG_ScorePlum(int client, vector3 *org, int score) { VectorClear(&angles); AnglesToAxis(&angles, re->axis); } - -localEntity_t *CG_MakeExplosion(vector3 *origin, vector3 *dir, qhandle_t hModel, int numFrames, qhandle_t shader, int msec, qboolean isSprite, float scale, - uint32_t flags) { - float ang = 0; - localEntity_t *ex; - int offset; - vector3 tmpVec, newOrigin; - - if (msec <= 0) { - trap->Error(ERR_DROP, "CG_MakeExplosion: msec = %i", msec); - } - - // skew the time a bit so they aren't all in sync - offset = rand() & 63; - - ex = CG_AllocLocalEntity(); - if (isSprite) { - ex->leType = LE_SPRITE_EXPLOSION; - ex->refEntity.rotation = rand() % 360; - ex->radius = scale; - VectorScale(dir, 16, &tmpVec); - VectorAdd(&tmpVec, origin, &newOrigin); - } else { - ex->leType = LE_EXPLOSION; - VectorCopy(origin, &newOrigin); - - // set axis with random rotate when necessary - if (!dir) { - AxisClear(ex->refEntity.axis); - } else { - if (!(flags & LEF_NO_RANDOM_ROTATE)) - ang = rand() % 360; - VectorCopy(dir, &ex->refEntity.axis[0]); - RotateAroundDirection(ex->refEntity.axis, ang); - } - } - - ex->startTime = cg.time - offset; - ex->endTime = ex->startTime + msec; - - // bias the time so all shader effects start correctly - ex->refEntity.shaderTime = ex->startTime / 1000.0f; - - ex->refEntity.hModel = hModel; - ex->refEntity.customShader = shader; - ex->lifeRate = (float)numFrames / msec; - ex->leFlags = flags; - - // Scale the explosion - if (scale != 1) { - ex->refEntity.nonNormalizedAxes = qtrue; - - VectorScale(&ex->refEntity.axis[0], scale, &ex->refEntity.axis[0]); - VectorScale(&ex->refEntity.axis[1], scale, &ex->refEntity.axis[1]); - VectorScale(&ex->refEntity.axis[2], scale, &ex->refEntity.axis[2]); - } - // set origin - VectorCopy(&newOrigin, &ex->refEntity.origin); - VectorCopy(&newOrigin, &ex->refEntity.oldorigin); - - ex->color[0] = ex->color[1] = ex->color[2] = 1.0f; - - return ex; -} - -/* -------------------------- -CG_SurfaceExplosion - -Adds an explosion to a surface -------------------------- -*/ - -#define NUM_SPARKS 12 -#define NUM_PUFFS 1 -#define NUM_EXPLOSIONS 4 - -void CG_SurfaceExplosion(vector3 *origin, vector3 *normal, float radius, float shake_speed, qboolean smoke) { - localEntity_t *le; - // FXTrail *particle; - vector3 direction, new_org; - vector3 velocity = {0, 0, 0}; - vector3 temp_org, temp_vel; - int i; - refdef_t *refdef = CG_GetRefdef(); - - // Smoke - // Move this out a little from the impact surface - VectorMA(origin, 4, normal, &new_org); - VectorSet(&velocity, 0.0f, 0.0f, 16.0f); - - for (i = 0; i < 4; i++) { - VectorSet(&temp_org, new_org.x + (crandom() * 16.0f), new_org.y + (crandom() * 16.0f), new_org.z + (random() * 4.0f)); - VectorSet(&temp_vel, velocity.x + (crandom() * 8.0f), velocity.y + (crandom() * 8.0f), velocity.z + (crandom() * 8.0f)); - } - - // Core of the explosion - - // Orient the explosions to face the camera - VectorSubtract(&refdef->vieworg, origin, &direction); - VectorNormalize(&direction); - - // Tag the last one with a light - le = CG_MakeExplosion(origin, &direction, media.models.explosion, 6, media.gfx.world.surfaceExplosion, 500, qfalse, radius * 0.02f + (random() * 0.3f), 0); - le->light = 150; - VectorSet(&le->lightColor, 0.9f, 0.8f, 0.5f); - - for (i = 0; i < NUM_EXPLOSIONS - 1; i++) { - VectorSet(&new_org, (origin->x + (16 + (crandom() * 8)) * crandom()), (origin->y + (16 + (crandom() * 8)) * crandom()), - (origin->z + (16 + (crandom() * 8)) * crandom())); - CG_MakeExplosion(&new_org, &direction, media.models.explosion, 6, media.gfx.world.surfaceExplosion, 300 + (rand() & 99), qfalse, - radius * 0.05f + (crandom() * 0.3f), 0); - } - - // Shake the camera - CG_ExplosionEffects(origin, shake_speed, 350, 750); - - // The level designers wanted to be able to turn the smoke spawners off. The rationale is that they - // want to blow up catwalks and such that fall down...when that happens, it shouldn't really leave a mark - // and a smoke spewer at the explosion point... - if (smoke) { - VectorMA(origin, -8, normal, &temp_org); - // Impact mark - // FIXME: Replace mark - // CG_ImpactMark( media.gfx.world.burnMarkShader, origin, normal, random()*360, 1,1,1,1, qfalse, 8, qfalse ); - } -} - -// This is the spurt of blood when a character gets hit -void CG_Bleed(vector3 *origin, int entityNum) { - localEntity_t *ex; - - ex = CG_AllocLocalEntity(); - ex->leType = LE_EXPLOSION; - - ex->startTime = cg.time; - ex->endTime = ex->startTime + 500; - - VectorCopy(origin, &ex->refEntity.origin); - ex->refEntity.reType = RT_SPRITE; - ex->refEntity.rotation = rand() % 360; - ex->refEntity.radius = 24; - - ex->refEntity.customShader = 0; // media.gfx.world.bloodExplosion; - - // don't show player's own blood in view - if (entityNum == cg.snap->ps.clientNum) { - ex->refEntity.renderfx |= RF_THIRD_PERSON; - } -} - -void CG_LaunchGib(vector3 *origin, vector3 *velocity, qhandle_t hModel) { - localEntity_t *le; - refEntity_t *re; - - le = CG_AllocLocalEntity(); - re = &le->refEntity; - - le->leType = LE_FRAGMENT; - le->startTime = cg.time; - le->endTime = le->startTime + 5000 + random() * 3000; - - VectorCopy(origin, &re->origin); - AxisCopy(axisDefault, re->axis); - re->hModel = hModel; - - le->pos.trType = TR_GRAVITY; - VectorCopy(origin, &le->pos.trBase); - VectorCopy(velocity, &le->pos.trDelta); - le->pos.trTime = cg.time; - - le->bounceFactor = 0.6f; - - le->leBounceSoundType = LEBS_BLOOD; - le->leMarkType = LEMT_BLOOD; -} diff --git a/cgame/cg_local.h b/cgame/cg_local.h index 65b92fd..b18be87 100644 --- a/cgame/cg_local.h +++ b/cgame/cg_local.h @@ -93,7 +93,6 @@ #define DRAWTIMER_COUNTDOWN (0x0002u) #define DRAWTIMER_COLOUR (0x0004u) -#define LEF_PUFF_DONT_SCALE (0x0001u) // do not scale size over time #define LEF_TUMBLE (0x0002u) // tumble over time, used for ejecting shells #define LEF_FADE_RGB (0x0004u) // explicitly fade #define LEF_NO_RANDOM_ROTATE (0x0008u) // MakeExplosion adds random rotate which could be bad in some cases @@ -323,25 +322,19 @@ typedef struct markPoly_s { } markPoly_t; enum leType_e { - LE_MARK, - LE_EXPLOSION, - LE_SPRITE_EXPLOSION, - LE_FADE_SCALE_MODEL, // currently only for Demp2 shock sphere - LE_FRAGMENT, - LE_PUFF, - LE_MOVE_SCALE_FADE, - LE_FALL_SCALE_FADE, - LE_FADE_RGB, - LE_SCALE_FADE, - LE_SCOREPLUM, - LE_OLINE, - LE_SHOWREFENTITY, - LE_LINE + LE_NONE, + LE_FADE_SCALE_MODEL, // demp2 + LE_FRAGMENT, // EV_DEBRIS + LE_PUFF, // force push, grip + LE_FADE_RGB, // strafe trail, rail trail + LE_SCOREPLUM, // score plums + LE_OLINE, // portable shield + LE_LINE, // CG_TestLine + NUM_LE_TYPES }; +extern const stringID_table_t leTypeStrings[NUM_LE_TYPES + 1]; -enum leMarkType_e { LEMT_NONE, LEMT_BURN, LEMT_BLOOD }; // fragment local entities can leave marks on walls - -enum leBounceSoundType_e { LEBS_NONE, LEBS_BLOOD, LEBS_BRASS, LEBS_METAL, LEBS_ROCK }; // fragment local entities can make sounds on impacts +enum leBounceSoundType_e { LEBS_NONE, LEBS_METAL, LEBS_ROCK }; // fragment local entities can make sounds on impacts typedef struct localEntity_s { struct localEntity_s *prev, *next; @@ -359,7 +352,6 @@ typedef struct localEntity_s { float radius; float light; vector3 lightColor; - leMarkType_e leMarkType; // mark to leave on fragment impact leBounceSoundType_e leBounceSoundType; union { @@ -507,6 +499,7 @@ typedef struct cg_s { qboolean levelShot; // taking a level menu screenshot bool haveDeferredPlayers; int deferredPlayerLoading; + bool queueLoad; qboolean loading; // don't defer players at initial startup qboolean intermissionStarted; // don't play voice rewards, because game will end shortly int latestSnapshotNum; // the number of snapshots the client system has received @@ -862,8 +855,6 @@ void CG_AdjustEyePos(const char *modelName); const char *CG_Argv(int arg); localEntity_t *CG_AllocLocalEntity(void); void CG_Beam(centity_t *cent); -void CG_Bleed(vector3 *origin, int entityNum); -void CG_BubbleTrail(vector3 *start, vector3 *end, float spacing); void CG_BuildSolidList(void); void CG_BuildSpectatorString(void); void CG_CacheG2AnimInfo(char *modelName); @@ -984,8 +975,6 @@ void CG_LoadingItem(int itemNum); void CG_LoadingClient(int clientNum); void CG_LoadMenus(const char *menuFile); void CG_LogPrintf(fileHandle_t fileHandle, const char *fmt, ...) Q_PRINT_FORMAT(2, 3); -localEntity_t *CG_MakeExplosion(vector3 *origin, vector3 *dir, qhandle_t hModel, int numframes, qhandle_t shader, int msec, qboolean isSprite, float scale, - uint32_t flags); void CG_ManualEntityRender(centity_t *cent); void CG_MissileHitPlayer(int weapon, vector3 *origin, vector3 *dir, int entityNum, qboolean alt_fire); void CG_MissileHitWall(int weapon, int clientNum, vector3 *origin, vector3 *dir, impactSound_e soundType, qboolean alt_fire, int charge); @@ -1045,12 +1034,9 @@ void CG_Shutdown(void); void CG_ShutDownG2Weapons(void); void CG_SiegeRoundOver(centity_t *ent, int won); void CG_SiegeObjectiveCompleted(centity_t *ent, int won, int objectivenum); -localEntity_t *CG_SmokePuff(const vector3 *p, const vector3 *vel, float radius, float r, float g, float b, float a, float duration, int startTime, - int fadeInTime, uint32_t leFlags, qhandle_t hShader); void CG_Spark(vector3 *origin, vector3 *dir); void CG_StartMusic(qboolean bForceStart); qhandle_t CG_StatusHandle(int task); -void CG_SurfaceExplosion(vector3 *origin, vector3 *normal, float radius, float shake_speed, qboolean smoke); vector4 *CG_TeamColor(int team); void CG_TestModel_f(void); void CG_TestGun_f(void); diff --git a/cgame/cg_localents.cpp b/cgame/cg_localents.cpp index b63180f..30b33a9 100644 --- a/cgame/cg_localents.cpp +++ b/cgame/cg_localents.cpp @@ -6,11 +6,24 @@ #include "cg_local.h" #include "cg_media.h" +#include "qcommon/q_shared.h" + +const stringID_table_t leTypeStrings[NUM_LE_TYPES + 1] = { + ENUM2STRING(LE_NONE), + ENUM2STRING(LE_FADE_SCALE_MODEL), + ENUM2STRING(LE_FRAGMENT), + ENUM2STRING(LE_PUFF), + ENUM2STRING(LE_FADE_RGB), + ENUM2STRING(LE_SCOREPLUM), + ENUM2STRING(LE_OLINE), + ENUM2STRING(LE_LINE), + {NULL, -1}, +}; #define MAX_LOCAL_ENTITIES (2048) -localEntity_t cg_localEntities[MAX_LOCAL_ENTITIES]; -localEntity_t cg_activeLocalEntities; // double linked list -localEntity_t *cg_freeLocalEntities; // single linked list +localEntity_t cg_localEntities[MAX_LOCAL_ENTITIES] = {}; +localEntity_t cg_activeLocalEntities = {}; // double linked list +localEntity_t *cg_freeLocalEntities = nullptr; // single linked list static uint32_t localEntitySpawnCount = 0u; // This is called at startup and for tournament restarts @@ -74,49 +87,6 @@ localEntity_t *CG_FindLocalEntity(uint32_t id) { // A fragment localentity interacts with the environment in some way (hitting walls), or generates more localentities // along a trail. -// Leave expanding blood puffs behind gibs -void CG_BloodTrail(localEntity_t *le) { - int t; - int t2; - int step; - vector3 newOrigin; - localEntity_t *blood; - - step = 150; - t = step * ((cg.time - cg.frametime + step) / step); - t2 = step * (cg.time / step); - - for (; t <= t2; t += step) { - BG_EvaluateTrajectory(&le->pos, t, &newOrigin); - - blood = CG_SmokePuff(&newOrigin, &vec3_origin, - 20, // radius - 1, 1, 1, 1, // color - 2000, // trailTime - t, // startTime - 0, // fadeInTime - 0, // flags - /*media.gfx.world.bloodTrail*/ 0); - // use the optimized version - blood->leType = LE_FALL_SCALE_FADE; - // drop a total of 40 units over its lifetime - blood->pos.trDelta.z = 40; - } -} - -void CG_FragmentBounceMark(localEntity_t *le, trace_t *trace) { -#if 0 - if ( le->leMarkType == LEMT_BLOOD ) - CG_ImpactMark( media.gfx.world.bloodMark, trace->endpos, trace->plane.normal, random()*360, 1,1,1,1, qtrue, radius, qfalse ); - else if ( le->leMarkType == LEMT_BURN ) - CG_ImpactMark( media.gfx.world.burnMark, trace->endpos, trace->plane.normal, random()*360, 1,1,1,1, qtrue, radius, qfalse ); -#endif - - // don't allow a fragment to make multiple marks, or they - // pile up while settling - le->leMarkType = LEMT_NONE; -} - void CG_FragmentBounceSound(localEntity_t *le, trace_t *trace) { // half the fragments will make a bounce sounds if (rand() & 1) { @@ -231,11 +201,6 @@ void CG_AddFragment(localEntity_t *le) { SE_R_AddRefEntityToScene(&le->refEntity, MAX_CLIENTS); - // add a blood trail - if (le->leBounceSoundType == LEBS_BLOOD) { - CG_BloodTrail(le); - } - return; } @@ -248,9 +213,6 @@ void CG_AddFragment(localEntity_t *le) { } if (!trace.startsolid) { - // leave a mark - CG_FragmentBounceMark(le, &trace); - // do a bouncy sound CG_FragmentBounceSound(le, &trace); @@ -311,43 +273,6 @@ static void CG_AddFadeScaleModel(localEntity_t *le) { SE_R_AddRefEntityToScene(ent, MAX_CLIENTS); } -static void CG_AddMoveScaleFade(localEntity_t *le) { - refEntity_t *re; - float c; - vector3 delta; - float len; - refdef_t *refdef = CG_GetRefdef(); - - re = &le->refEntity; - - if (le->fadeInTime > le->startTime && cg.time < le->fadeInTime) { - // fade / grow time - c = 1.0f - (float)(le->fadeInTime - cg.time) / (le->fadeInTime - le->startTime); - } else { - // fade / grow time - c = (le->endTime - cg.time) * le->lifeRate; - } - - re->shaderRGBA[3] = 0xff * c * le->color[3]; - - if (!(le->leFlags & LEF_PUFF_DONT_SCALE)) { - re->radius = le->radius * (1.0f - c) + 8; - } - - BG_EvaluateTrajectory(&le->pos, cg.time, &re->origin); - - // if the view would be "inside" the sprite, kill the sprite - // so it doesn't add too much overdraw - VectorSubtract(&re->origin, &refdef->vieworg, &delta); - len = VectorLength(&delta); - if (len < le->radius) { - CG_FreeLocalEntity(le); - return; - } - - SE_R_AddRefEntityToScene(re, MAX_CLIENTS); -} - static void CG_AddPuff(localEntity_t *le) { refEntity_t *re; float c; @@ -364,73 +289,9 @@ static void CG_AddPuff(localEntity_t *le) { re->shaderRGBA[1] = le->color[1] * c; re->shaderRGBA[2] = le->color[2] * c; - if (!(le->leFlags & LEF_PUFF_DONT_SCALE)) { - re->radius = le->radius * (1.0f - c) + 8; - } - - BG_EvaluateTrajectory(&le->pos, cg.time, &re->origin); - - // if the view would be "inside" the sprite, kill the sprite - // so it doesn't add too much overdraw - VectorSubtract(&re->origin, &refdef->vieworg, &delta); - len = VectorLength(&delta); - if (len < le->radius) { - CG_FreeLocalEntity(le); - return; - } - - SE_R_AddRefEntityToScene(re, MAX_CLIENTS); -} - -// For rocket smokes that hang in place, fade out, and are removed if the view passes through them. -// There are often many of these, so it needs to be simple. -static void CG_AddScaleFade(localEntity_t *le) { - refEntity_t *re; - float c; - vector3 delta; - float len; - refdef_t *refdef = CG_GetRefdef(); - - re = &le->refEntity; - - // fade / grow time - c = (le->endTime - cg.time) * le->lifeRate; - - re->shaderRGBA[3] = 0xff * c * le->color[3]; re->radius = le->radius * (1.0f - c) + 8; - // if the view would be "inside" the sprite, kill the sprite - // so it doesn't add too much overdraw - VectorSubtract(&re->origin, &refdef->vieworg, &delta); - len = VectorLength(&delta); - if (len < le->radius) { - CG_FreeLocalEntity(le); - return; - } - - SE_R_AddRefEntityToScene(re, MAX_CLIENTS); -} - -// This is just an optimized CG_AddMoveScaleFade for blood mists that drift down, fade out, and are emoved if the view -// passes through them. -// There are often 100+ of these, so it needs to be simple. -static void CG_AddFallScaleFade(localEntity_t *le) { - refEntity_t *re; - float c; - vector3 delta; - float len; - refdef_t *refdef = CG_GetRefdef(); - - re = &le->refEntity; - - // fade time - c = (le->endTime - cg.time) * le->lifeRate; - - re->shaderRGBA[3] = 0xff * c * le->color[3]; - - re->origin.z = le->pos.trBase.z - (1.0f - c) * le->pos.trDelta.z; - - re->radius = le->radius * (1.0f - c) + 16; + BG_EvaluateTrajectory(&le->pos, cg.time, &re->origin); // if the view would be "inside" the sprite, kill the sprite // so it doesn't add too much overdraw @@ -444,73 +305,6 @@ static void CG_AddFallScaleFade(localEntity_t *le) { SE_R_AddRefEntityToScene(re, MAX_CLIENTS); } -static void CG_AddExplosion(localEntity_t *ex) { - refEntity_t *ent; - - ent = &ex->refEntity; - - // add the entity - SE_R_AddRefEntityToScene(ent, MAX_CLIENTS); - - // add the dlight - if (ex->light) { - float light; - - light = (float)(cg.time - ex->startTime) / (ex->endTime - ex->startTime); - if (light < 0.5f) { - light = 1.0f; - } else { - light = 1.0f - (light - 0.5f) * 2; - } - light = ex->light * light; - trap->R_AddLightToScene(&ent->origin, light, ex->lightColor.r, ex->lightColor.g, ex->lightColor.b); - } -} - -static void CG_AddSpriteExplosion(localEntity_t *le) { - refEntity_t re; - float c; - - re = le->refEntity; - - c = (le->endTime - cg.time) / (float)(le->endTime - le->startTime); - if (c > 1) { - c = 1.0f; // can happen during connection problems - } - - re.shaderRGBA[0] = 0xff; - re.shaderRGBA[1] = 0xff; - re.shaderRGBA[2] = 0xff; - re.shaderRGBA[3] = 0xff * c * 0.33f; - - re.reType = RT_SPRITE; - re.radius = 42 * (1.0f - c) + 30; - - SE_R_AddRefEntityToScene(&re, MAX_CLIENTS); - - // add the dlight - if (le->light) { - float light; - - light = (float)(cg.time - le->startTime) / (le->endTime - le->startTime); - if (light < 0.5f) { - light = 1.0f; - } else { - light = 1.0f - (light - 0.5f) * 2; - } - light = le->light * light; - trap->R_AddLightToScene(&re.origin, light, le->lightColor.r, le->lightColor.g, le->lightColor.b); - } -} - -void CG_AddRefEntity(localEntity_t *le) { - if (le->endTime < cg.time) { - CG_FreeLocalEntity(le); - return; - } - SE_R_AddRefEntityToScene(&le->refEntity, MAX_CLIENTS); -} - #define NUMBER_SIZE 8 void CG_AddScorePlum(localEntity_t *le) { @@ -640,35 +434,30 @@ void CG_AddLine(localEntity_t *le) { } void CG_AddLocalEntities(void) { - localEntity_t *next; + // int numAdded[NUM_LE_TYPES] = {}; + localEntity_t *next; // walk the list backwards, so any new local entities generated (trails, marks, etc) will be present this frame for (localEntity_t *le = cg_activeLocalEntities.prev; le != &cg_activeLocalEntities; le = next) { - // grab next now, so if the local entity is freed we - // still have it + // grab next now, so if the local entity is freed we still have it next = le->prev; if (cg.time >= le->endTime) { CG_FreeLocalEntity(le); continue; } - switch (le->leType) { - case LE_MARK: - break; - case LE_SPRITE_EXPLOSION: - CG_AddSpriteExplosion(le); - break; + // numAdded[le->leType]++; - case LE_EXPLOSION: - CG_AddExplosion(le); + switch (le->leType) { + default: break; case LE_FADE_SCALE_MODEL: CG_AddFadeScaleModel(le); break; - case LE_FRAGMENT: // gibs and brass + case LE_FRAGMENT: CG_AddFragment(le); break; @@ -676,22 +465,10 @@ void CG_AddLocalEntities(void) { CG_AddPuff(le); break; - case LE_MOVE_SCALE_FADE: // water bubbles - CG_AddMoveScaleFade(le); - break; - - case LE_FADE_RGB: // teleporters, railtrails + case LE_FADE_RGB: CG_AddFadeRGB(le); break; - case LE_FALL_SCALE_FADE: // gib blood trails - CG_AddFallScaleFade(le); - break; - - case LE_SCALE_FADE: // rocket trails - CG_AddScaleFade(le); - break; - case LE_SCOREPLUM: CG_AddScorePlum(le); break; @@ -700,13 +477,14 @@ void CG_AddLocalEntities(void) { CG_AddOLine(le); break; - case LE_SHOWREFENTITY: - CG_AddRefEntity(le); - break; - - case LE_LINE: // oriented lines for FX + case LE_LINE: CG_AddLine(le); break; } } + + // for (leType_e leType = LE_NONE; leType < NUM_LE_TYPES; leType = (leType_e)(leType + 1)) { + // const char *leTypeStr = GetStringForID(leTypeStrings, leType); + // Com_Printf("CG_AddLocalEntities: %s: %i\n", leTypeStr, numAdded[leType]); + // } } diff --git a/cgame/cg_lualocalentity.cpp b/cgame/cg_lualocalentity.cpp index 3e0be53..d60b356 100644 --- a/cgame/cg_lualocalentity.cpp +++ b/cgame/cg_lualocalentity.cpp @@ -160,13 +160,6 @@ static int LocalEntity_GetLightColor(lua_State *L, localEntity_t *ent) { return 1; } -static void LocalEntity_SetMarkType(lua_State *L, localEntity_t *ent) { ent->leMarkType = (leMarkType_e)luaL_checkinteger(L, 3); } - -static int LocalEntity_GetMarkType(lua_State *L, localEntity_t *ent) { - lua_pushinteger(L, ent->leMarkType); - return 1; -} - static void LocalEntity_SetBSndType(lua_State *L, localEntity_t *ent) { ent->leBounceSoundType = (leBounceSoundType_e)luaL_checkinteger(L, 3); } static int LocalEntity_GetBSndType(lua_State *L, localEntity_t *ent) { @@ -240,11 +233,6 @@ static const le_prop_t localEntityProperties[] = { LocalEntity_Line_GetWidth, LocalEntity_Line_SetWidth, }, - { - "marktype", - LocalEntity_GetMarkType, - LocalEntity_SetMarkType, - }, { "radius", LocalEntity_GetRadius, diff --git a/cgame/cg_main.cpp b/cgame/cg_main.cpp index 5173691..7cc94ac 100644 --- a/cgame/cg_main.cpp +++ b/cgame/cg_main.cpp @@ -334,6 +334,11 @@ static void CVU_ForceColour(void) { } static void CVU_ForceModel(void) { + if (cg.loading) { + cg.haveDeferredPlayers = true; + cg.queueLoad = true; + return; + } for (int i = 0; i < cgs.maxclients; i++) { if (VALIDSTRING(CG_ConfigString(CS_PLAYERS + i))) { CG_NewClientInfo(i, qtrue); @@ -551,13 +556,6 @@ static void CVU_AccelSize(void) { } } -typedef struct cvarTable_s { - vmCvar_t *vmCvar; - const char *cvarName, *defaultString; - void (*update)(void); - uint32_t cvarFlags; -} cvarTable_t; - #define XCVAR_DECL #include "cg_xcvar.h" #undef XCVAR_DECL @@ -569,38 +567,38 @@ void CG_Set2DRatio(void) { cgs.widthRatioCoef = 1.0f; } -static cvarTable_t cvarTable[] = { +static const struct cvarTable_t { + vmCvar_t *vmCvar; + const char *cvarName, *defaultString; + void (*update)(void); + uint32_t cvarFlags; +} cvarTable[] = { #define XCVAR_LIST #include "cg_xcvar.h" #undef XCVAR_LIST }; -static int cvarTableSize = ARRAY_LEN(cvarTable); - void CG_RegisterCvars(void) { - int i; - cvarTable_t *cv; - - for (i = 0, cv = cvarTable; i < cvarTableSize; i++, cv++) { - trap->Cvar_Register(cv->vmCvar, cv->cvarName, cv->defaultString, cv->cvarFlags); - if (cv->update) - cv->update(); + for (const auto &cv : cvarTable) { + trap->Cvar_Register(cv.vmCvar, cv.cvarName, cv.defaultString, cv.cvarFlags); + } + for (const auto &cv : cvarTable) { + if (cv.update) { + cv.update(); + } } } void CG_UpdateCvars(void) { - int i; - cvarTable_t *cv; - - for (i = 0, cv = cvarTable; i < cvarTableSize; i++, cv++) { - if (cv->vmCvar) { - int modCount = cv->vmCvar->modificationCount; - trap->Cvar_Update(cv->vmCvar); - if (cv->vmCvar->modificationCount > modCount) { - if (cv->update) { - cv->update(); + for (const auto &cv : cvarTable) { + if (cv.vmCvar) { + int modCount = cv.vmCvar->modificationCount; + trap->Cvar_Update(cv.vmCvar); + if (cv.vmCvar->modificationCount > modCount) { + if (cv.update) { + cv.update(); } - JPLua::Cvar_Update(cv->cvarName); + JPLua::Cvar_Update(cv.cvarName); } } } @@ -772,7 +770,7 @@ static void CG_RegisterClients(void) { const char *CG_ConfigString(int index) { // don't read configstrings before initialisation - assert(cgs.gameState.dataCount != 0); + // assert(cgs.gameState.dataCount != 0); if (index < 0 || index >= MAX_CONFIGSTRINGS) { trap->Error(ERR_DROP, "CG_ConfigString: bad index: %i", index); @@ -800,11 +798,11 @@ char *CG_GetMenuBuffer(const char *filename) { len = trap->FS_Open(filename, &f, FS_READ); if (!f) { - trap->Print(va(S_COLOR_RED "menu file not found: %s, using default\n", filename)); + trap->Print(S_COLOR_RED "menu file not found: %s, using default\n", filename); return NULL; } if (len >= MAX_MENUFILE) { - trap->Print(va(S_COLOR_RED "menu file too large: %s is %i, max allowed is %i", filename, len, MAX_MENUFILE)); + trap->Print(S_COLOR_RED "menu file too large: %s is %i, max allowed is %i", filename, len, MAX_MENUFILE); trap->FS_Close(f); return NULL; } @@ -1697,25 +1695,32 @@ static void CG_CloseLog(fileHandle_t *f) { // Called after every level change or subsystem restart // Will perform callbacks to make the loading info screen update. void CG_Init(int serverMessageNum, int serverCommandSequence, int clientNum, qboolean demoPlayback) { - char buf[64]; - const char *s; - // clear out globals - memset(cg_entities, 0, sizeof(cg_entities)); - cgs.~cgs_t(); new (&cgs) cgs_t{}; // Using {} instead of () to work around MSVC bug cg.~cg_t(); new (&cg) cg_t{}; - + memset(cg_entities, 0, sizeof(cg_entities)); memset(cg_items, 0, sizeof(cg_items)); memset(cg_weapons, 0, sizeof(cg_weapons)); - trap->GetGameState(&cgs.gameState); - - trap->RegisterSharedMemory(cg.sharedBuffer); + cg.clientNum = clientNum; + cg.demoPlayback = demoPlayback; + cg.forceHUDActive = qtrue; + cg.forceHUDNextFlashTime = 0; + cg.forceHUDTotalFlashTime = 0; + cg.forceSelect = 0xFFFFFFFFu; + cg.itemSelect = -1; + cg.weaponSelect = WP_BRYAR_PISTOL; + cgs.processedSnapshotNum = serverMessageNum; + cgs.redflag = cgs.blueflag = FLAG_ATBASE; + cgs.serverCommandSequence = serverCommandSequence; + CG_LoadingString("Cvars"); CG_RegisterCvars(); + cg.renderingThirdPerson = cg_thirdPerson.integer; + + CG_LoadingString("Commands"); CG_InitConsoleCommands(); // logging @@ -1737,46 +1742,40 @@ void CG_Init(int serverMessageNum, int serverCommandSequence, int clientNum, qbo trap->Print("Not logging security events to disk.\n"); // load some permanent stuff + CG_LoadingString("Animation sets"); BG_InitAnimsets(); + CG_LoadingString("Vehicles"); BG_VehicleLoadParms(); CG_InitJetpackGhoul2(); CG_PmoveClientPointerUpdate(); CG_PreloadMedia(); - cg.clientNum = clientNum; - cgs.processedSnapshotNum = serverMessageNum; - cgs.serverCommandSequence = serverCommandSequence; - cg.itemSelect = -1; - cg.forceSelect = 0xFFFFFFFFu; - cg.forceHUDActive = qtrue; - cg.forceHUDTotalFlashTime = 0; - cg.forceHUDNextFlashTime = 0; - cg.renderingThirdPerson = cg_thirdPerson.integer; - cg.weaponSelect = WP_BRYAR_PISTOL; - cgs.redflag = cgs.blueflag = FLAG_ATBASE; - cg.demoPlayback = demoPlayback; - cgs.levelStartTime = atoi(CG_ConfigString(CS_LEVEL_START_TIME)); - trap->GetGlconfig(&cgs.glconfig); - cgs.screenXScale = cgs.glconfig.vidWidth / SCREEN_WIDTH; - cgs.screenYScale = cgs.glconfig.vidHeight / SCREEN_HEIGHT; + cgs.screenXScale = cgs.glconfig.vidWidth / (float)SCREEN_WIDTH; + cgs.screenYScale = cgs.glconfig.vidHeight / (float)SCREEN_HEIGHT; CG_Set2DRatio(); - s = CG_ConfigString(CS_GAME_VERSION); + // NOTE: do not read configstrings before this point + trap->GetGameState(&cgs.gameState); + + const char *s = CG_ConfigString(CS_GAME_VERSION); if (strcmp(s, GAME_VERSION)) { trap->Error(ERR_DROP, "Client/Server game mismatch: " GAME_VERSION "/%s", s); return; } + CG_LoadingString("Game state"); + trap->RegisterSharedMemory(cg.sharedBuffer); + CG_ParseServerinfo(); + cgs.levelStartTime = atoi(CG_ConfigString(CS_LEVEL_START_TIME)); + Q_strncpyz(cgs.voteString, CG_ConfigString(CS_VOTE_STRING), sizeof(cgs.voteString)); + CG_TransitionPermanent(); CG_LoadingString("Notifications"); CG_NotifyInit(); - CG_LoadingString("Server info"); - CG_ParseServerinfo(); - CG_LoadingString("String pool"); String_Init(); @@ -1850,6 +1849,7 @@ void CG_Init(int serverMessageNum, int serverCommandSequence, int clientNum, qbo CG_LoadingString(""); // post-init stuff + char buf[64]; trap->Cvar_VariableStringBuffer("rate", buf, sizeof(buf)); if (atoi(buf) == 4000) { trap->Print(S_COLOR_YELLOW "WARNING: Default /rate value detected. Suggest typing /rate 25000 for a smoother " @@ -1858,6 +1858,7 @@ void CG_Init(int serverMessageNum, int serverCommandSequence, int clientNum, qbo CG_UpdateServerHistory(); BG_FixSaberMoveData(); + BG_FixWeaponAttackAnim(); } // makes sure returned string is in localized format diff --git a/cgame/cg_media.cpp b/cgame/cg_media.cpp index fcb94e6..2effa63 100644 --- a/cgame/cg_media.cpp +++ b/cgame/cg_media.cpp @@ -516,7 +516,6 @@ static const resource_t gfx[] = { {&media.gfx.world.sightShell, "powerups/sightshell", RFL_NONE, GTB_ALL}, {&media.gfx.world.solidWhite, "gfx/effects/solidWhite_cull", RFL_NONE, GTB_ALL}, {&media.gfx.world.strafeTrail, "gfx/misc/whiteline2", RFL_NOMIP, GTB_ALL}, - {&media.gfx.world.surfaceExplosion, "surfaceExplosion", RFL_NONE, GTB_ALL}, {&media.gfx.world.wakeMark, "wake", RFL_NONE, GTB_ALL}, // { &media.gfx.world.whiteShader, NULL, RFL_NONE, GTB_ALL }, {&media.gfx.world.yellowDroppedSaber, "gfx/effects/yellow_glow", RFL_NONE, GTB_ALL}, diff --git a/cgame/cg_media.h b/cgame/cg_media.h index fbfe1bd..b557946 100644 --- a/cgame/cg_media.h +++ b/cgame/cg_media.h @@ -253,7 +253,6 @@ typedef struct cgMedia_s { qhandle_t sightShell; qhandle_t solidWhite; qhandle_t strafeTrail; - qhandle_t surfaceExplosion; qhandle_t wakeMark; qhandle_t whiteShader; qhandle_t yellowDroppedSaber; diff --git a/cgame/cg_newDraw.cpp b/cgame/cg_newDraw.cpp index 45c3a8b..e7178db 100644 --- a/cgame/cg_newDraw.cpp +++ b/cgame/cg_newDraw.cpp @@ -321,7 +321,7 @@ void CG_DrawNewTeamInfo(rectDef_t *rect, float text_x, float text_y, float scale ci = cgs.clientinfo + sortedTeamPlayers[i]; if (ci->infoValid && ci->team == cg.snap->ps.persistant[PERS_TEAM]) { xx = rect->x + 1; - for (j = 0; j <= PW_NUM_POWERUPS; j++) { + for (j = 0; j < PW_NUM_POWERUPS; j++) { if (ci->powerups & (1 << j)) { if ((item = BG_FindItemForPowerup((powerup_e)j))) { CG_DrawPic(xx, y, PIC_WIDTH, PIC_WIDTH, trap->R_RegisterShader(item->icon)); diff --git a/cgame/cg_players.cpp b/cgame/cg_players.cpp index 6249728..f882e6d 100644 --- a/cgame/cg_players.cpp +++ b/cgame/cg_players.cpp @@ -1302,8 +1302,7 @@ void CG_NewClientInfo(int clientNum, qboolean entitiesInitialized) { } } -qboolean cgQueueLoad = qfalse; -// Called at the beginning of CG_Player if cgQueueLoad is set. +// Called at the beginning of CG_Player if cg.queueLoad is set. void CG_ActualLoadDeferredPlayers(void) { int i; clientInfo_t *ci; @@ -1325,7 +1324,7 @@ void CG_ActualLoadDeferredPlayers(void) { } // Called each frame when a player is dead and the scoreboard is up so deferred players can be loaded -void CG_LoadDeferredPlayers(void) { cgQueueLoad = qtrue; } +void CG_LoadDeferredPlayers(void) { cg.queueLoad = qtrue; } #define FOOTSTEP_DISTANCE (32) static void _PlayerFootStep(const vector3 *origin, const float orientation, const float radius, centity_t *const cent, footstepType_e footStepType) { @@ -1698,7 +1697,6 @@ void CG_PlayerAnimEvents(int animFileIndex, int eventFileIndex, qboolean torso, else { // still in same anim, check for looping anim animation_t *animation; - inSameAnim = qtrue; animation = &bgAllAnims[animFileIndex].anims[anim]; animBackward = (animation->frameLerp < 0); @@ -2205,7 +2203,7 @@ void CG_Rag_Trace(trace_t *result, const vector3 *start, const vector3 *mins, co result->entityNum = result->fraction != 1.0f ? ENTITYNUM_WORLD : ENTITYNUM_NONE; } -//#define _RAG_BOLT_TESTING +// #define _RAG_BOLT_TESTING #ifdef _RAG_BOLT_TESTING void CG_TempTestFunction(centity_t *cent, vector3 *forcedAngles) { @@ -6235,7 +6233,9 @@ static void CG_VehicleEffects(centity_t *cent) { #else if (pVehNPC->m_pVehicleInfo->iTrailFX) #endif - { trap->FX_PlayEffectID(pVehNPC->m_pVehicleInfo->iTrailFX, &org, &fwd, -1, -1, qfalse); } + { + trap->FX_PlayEffectID(pVehNPC->m_pVehicleInfo->iTrailFX, &org, &fwd, -1, -1, qfalse); + } // do exhaust if ((cent->currentState.eFlags & EF_JETPACK_ACTIVE)) @@ -6426,7 +6426,7 @@ void CG_Player(centity_t *cent) { vector3 rootAngles, angles, dir, elevated, enang, seekorg; mdxaBone_t boltMatrix, lHandMatrix; clientInfo_t *ci; - refEntity_t legs, torso; + refEntity_t legs = {}, torso = {}; int clientNum, team; uint32_t renderfx; diff --git a/cgame/cg_servercmds.cpp b/cgame/cg_servercmds.cpp index a394544..69f1ba0 100644 --- a/cgame/cg_servercmds.cpp +++ b/cgame/cg_servercmds.cpp @@ -176,9 +176,6 @@ void CG_ParseServerinfo(void) { Q_strncpyz(cgs.japp.serverName, Info_ValueForKey(info, "sv_hostname"), sizeof(cgs.japp.serverName)); CPM_UpdateSettings(!!(cgs.japp.jp_cinfo & CINFO_CPMPHYSICS)); - // Fix fucked up vote strings - Q_strncpyz(cgs.voteString, CG_ConfigString(CS_VOTE_STRING), sizeof(cgs.voteString)); - // Raz: Synchronise our expected snaps/sec with the server's framerate // OpenJK servers will try to match us to the sv_fps too (sv_client.cpp -> SV_UserinfoChanged) i = atoi(Info_ValueForKey(info, "sv_fps")); @@ -753,8 +750,9 @@ static void CG_ConfigStringModified(void) { } else if (num == CS_LEGACY_FIXES) { - // LEGACYFIX_SABERMOVEDATA may have changed + // LEGACYFIX_SABERMOVEDATA etc may have changed BG_FixSaberMoveData(); + BG_FixWeaponAttackAnim(); } else if (num >= CS_LIGHT_STYLES && num < CS_LIGHT_STYLES + (MAX_LIGHT_STYLES * 3)) diff --git a/cgame/cg_smartentities.cpp b/cgame/cg_smartentities.cpp index f0a9dc8..bba0671 100644 --- a/cgame/cg_smartentities.cpp +++ b/cgame/cg_smartentities.cpp @@ -214,7 +214,7 @@ qboolean SE_RenderPlayer(int targIndex) { // Tracing non-players seems to have a bad effect, we know players are limited to 32 per frame, however other gentities // that are being added are not! It's stupid to actually add traces for it, even with a limited form i used before of 2 -// traces per object. There are to many too track and simply drawing them takes less FPS either way. +// traces per object. There are too many to track and simply drawing them takes less FPS either way. qboolean SE_RenderThisEntity(vector3 *testOrigin, int gameEntity) { // If we do not have a snapshot, we cannot calculate anything. if (!cg.snap) diff --git a/cgame/cg_view.cpp b/cgame/cg_view.cpp index 51ce6df..e5a6c5e 100644 --- a/cgame/cg_view.cpp +++ b/cgame/cg_view.cpp @@ -1768,7 +1768,6 @@ float cg_linearFogOverride = 0.0f; // designer-specified override for li void BG_VehicleTurnRateForSpeed(Vehicle_t *pVeh, float speed, float *mPitchOverride, float *mYawOverride); qboolean PM_InKnockDown(playerState_t *ps); -extern qboolean cgQueueLoad; void CG_ActualLoadDeferredPlayers(void); static int cg_siegeClassIndex = -2; @@ -2006,10 +2005,10 @@ void CG_DrawActiveFrame(int serverTime, stereoFrame_e stereoView, qboolean demoP pwSet = 1; } - if (cgQueueLoad || (cg.haveDeferredPlayers && cg_deferPlayers.integer == 2 && cg.snap && VectorLength(&cg.snap->ps.velocity) < 1.0f)) { + if (cg.queueLoad || (cg.haveDeferredPlayers && cg_deferPlayers.integer == 2 && cg.snap && VectorLength(&cg.snap->ps.velocity) < 1.0f)) { // do this before you start messing around with adding ghoul2 refents and crap CG_ActualLoadDeferredPlayers(); - cgQueueLoad = qfalse; + cg.queueLoad = qfalse; } cg.time = serverTime; @@ -2183,7 +2182,6 @@ void CG_DrawActiveFrame(int serverTime, stereoFrame_e stereoView, qboolean demoP if (!cg.hyperspace) { CG_AddPacketEntities(qfalse); // adter calcViewValues, so predicted player state is correct CG_AddMarks(); - CG_AddLocalEntities(); CG_DrawMiscEnts(); } CG_AddViewWeapon(&cg.predictedPlayerState); @@ -2204,6 +2202,11 @@ void CG_DrawActiveFrame(int serverTime, stereoFrame_e stereoView, qboolean demoP CG_AddMovementVectors(); } + if (!cg.hyperspace) { + // specifically render these later, as they may overflow the refent buffer + CG_AddLocalEntities(); + } + refdef->time = cg.time; memcpy(refdef->areamask, cg.snap->areamask, sizeof(refdef->areamask)); diff --git a/game/NPC_stats.cpp b/game/NPC_stats.cpp index 69eb24b..2817477 100644 --- a/game/NPC_stats.cpp +++ b/game/NPC_stats.cpp @@ -1855,7 +1855,7 @@ qboolean NPC_ParseParms(const char *NPCName, gentity_t *NPC) { } // FIXME: need to precache the weapon, too? (in above func) weap = GetIDForString(WPTable, value); - if (weap >= WP_NONE && weap <= WP_NUM_WEAPONS) ///*WP_BLASTER_PISTOL*/WP_SABER ) //?! + if (weap >= WP_NONE && weap < WP_NUM_WEAPONS) ///*WP_BLASTER_PISTOL*/WP_SABER ) //?! { NPC->client->ps.weapon = weap; NPC->client->ps.stats[STAT_WEAPONS] |= (1 << NPC->client->ps.weapon); diff --git a/game/bg_lua.cpp b/game/bg_lua.cpp index f4b2ac2..240e113 100644 --- a/game/bg_lua.cpp +++ b/game/bg_lua.cpp @@ -1711,7 +1711,7 @@ void Init(void) { } // set the JPLua version - semver_parse("13.6.1", &jpluaVersion); + semver_parse(JPLUA_VERSION, &jpluaVersion); // set the callback in case of an error lua_atpanic(ls.L, Error); diff --git a/game/bg_lua.h b/game/bg_lua.h index 616e9cd..5e206b7 100644 --- a/game/bg_lua.h +++ b/game/bg_lua.h @@ -25,6 +25,8 @@ #include "semver/semver.h" +#define JPLUA_VERSION "13.6.2" + namespace JPLua { struct plugin_t { diff --git a/game/bg_misc.cpp b/game/bg_misc.cpp index c7b3287..e0d0e62 100644 --- a/game/bg_misc.cpp +++ b/game/bg_misc.cpp @@ -199,7 +199,7 @@ const int WeaponReadyLegsAnim[WP_NUM_WEAPONS] = { BOTH_STAND1 // WP_TURRET, }; -const int WeaponAttackAnim[WP_NUM_WEAPONS] = { +int WeaponAttackAnim[WP_NUM_WEAPONS] = { BOTH_ATTACK1, // WP_NONE, //(shouldn't happen) BOTH_ATTACK3, // WP_STUN_BATON, @@ -216,7 +216,7 @@ const int WeaponAttackAnim[WP_NUM_WEAPONS] = { BOTH_THERMAL_THROW, // WP_THERMAL, BOTH_ATTACK3, // BOTH_ATTACK11,//WP_TRIP_MINE, BOTH_ATTACK3, // BOTH_ATTACK12,//WP_DET_PACK, - BOTH_ATTACK3, // WP_CONCUSSION, //Raz: Fixed bryar pistol animation + BOTH_ATTACK3, // WP_CONCUSSION, BOTH_ATTACK2, // WP_BRYAR_OLD, // NOT VALID (e.g. should never really be used): @@ -225,6 +225,32 @@ const int WeaponAttackAnim[WP_NUM_WEAPONS] = { BOTH_ATTACK1 // WP_TURRET, }; +void BG_FixWeaponAttackAnim(void) { +#if defined(PROJECT_GAME) + const qboolean doFix = !!g_fixWeaponAttackAnim.integer; +#elif defined(PROJECT_CGAME) + const char *cs = CG_ConfigString(CS_LEGACY_FIXES); + const uint32_t legacyFixes = strtoul(cs, NULL, 0); + const qboolean doFix = !!(legacyFixes & (1 << LEGACYFIX_WEAPONATTACKANIM)); +#elif defined(PROJECT_UI) + const qboolean doFix = qtrue; // no chance of prediction error from UI code +#endif + int *move; + + for (move = WeaponAttackAnim; move - WeaponAttackAnim < ARRAY_LEN(WeaponAttackAnim); move++) { + const weapon_e wpIndex = (weapon_e)(move - WeaponAttackAnim); + if (wpIndex == WP_CONCUSSION) { + *move = doFix ? BOTH_ATTACK3 : BOTH_ATTACK2; + } else if (wpIndex == WP_BRYAR_OLD) { + *move = doFix ? BOTH_ATTACK2 : BOTH_STAND1; + } else if (wpIndex == WP_EMPLACED_GUN) { + *move = doFix ? BOTH_STAND1 : BOTH_ATTACK1; + } else if (wpIndex == WP_TURRET) { + *move = doFix ? BOTH_ATTACK1 : BOTH_ATTACK2; // better than UB? + } + } +} + const stringID_table_t eTypes[ET_MAX] = { ENUM2STRING(ET_GENERAL), ENUM2STRING(ET_PLAYER), ENUM2STRING(ET_ITEM), ENUM2STRING(ET_MISSILE), ENUM2STRING(ET_SPECIAL), ENUM2STRING(ET_HOLOCRON), ENUM2STRING(ET_MOVER), ENUM2STRING(ET_BEAM), diff --git a/game/bg_panimate.cpp b/game/bg_panimate.cpp index 89f76c5..5e64770 100644 --- a/game/bg_panimate.cpp +++ b/game/bg_panimate.cpp @@ -2488,8 +2488,9 @@ void BG_SetAnim(playerState_t *ps, animation_t *animations, int setAnimParts, in animations = bgAllAnims[0].anims; } - // if ( !animations ) - // return; + if (!animations) { + return; + } if (animations[anim].firstFrame == 0 && animations[anim].numFrames == 0) { if (anim == BOTH_RUNBACK1 || anim == BOTH_WALKBACK1 || anim == BOTH_RUN1) { // hack for droids diff --git a/game/bg_pmove.cpp b/game/bg_pmove.cpp index ff59c79..14f0e2f 100644 --- a/game/bg_pmove.cpp +++ b/game/bg_pmove.cpp @@ -4700,6 +4700,16 @@ static uint32_t JP_GetJPFixRoll(void) { return level; } +static bool BG_AreRunWalkAnimsFixed(void) { +#if defined(PROJECT_GAME) + return !!g_fixRunWalkAnims.integer; +#elif defined(PROJECT_CGAME) + const char *cs = CG_ConfigString(CS_LEGACY_FIXES); + const uint32_t legacyFixes = strtoul(cs, NULL, 0); + return !!(legacyFixes & (1 << LEGACYFIX_RUNWALKANIMS)); +#endif +} + static void PM_Footsteps(void) { float bobmove; int old; @@ -4882,101 +4892,115 @@ static void PM_Footsteps(void) { desiredAnim = BOTH_WALK1; } } else if (pm->ps->pm_flags & PMF_BACKWARDS_RUN) { - switch (pm->ps->fd.saberAnimLevel) { - case SS_STAFF: - if (pm->ps->saberHolstered > 1) { // saber off - desiredAnim = BOTH_RUNBACK1; - } else { - // desiredAnim = BOTH_RUNBACK_STAFF; - // hmm.. stuff runback anim is pretty messed up for some reason. - desiredAnim = BOTH_RUNBACK2; - } - break; - case SS_DUAL: - if (pm->ps->saberHolstered > 1) { // sabers off - desiredAnim = BOTH_RUNBACK1; - } else { - // desiredAnim = BOTH_RUNBACK_DUAL; - // and so is the dual - desiredAnim = BOTH_RUNBACK2; - } - break; - default: - if (pm->ps->saberHolstered) { // saber off - desiredAnim = BOTH_RUNBACK1; - } else { - desiredAnim = BOTH_RUNBACK2; + if (BG_AreRunWalkAnimsFixed() && pm->ps->weapon != WP_SABER) { + desiredAnim = BOTH_RUNBACK1; + } else { + switch (pm->ps->fd.saberAnimLevel) { + case SS_STAFF: + if (pm->ps->saberHolstered > 1) { // saber off + desiredAnim = BOTH_RUNBACK1; + } else { + // desiredAnim = BOTH_RUNBACK_STAFF; + // hmm.. stuff runback anim is pretty messed up for some reason. + desiredAnim = BOTH_RUNBACK2; + } + break; + case SS_DUAL: + if (pm->ps->saberHolstered > 1) { // sabers off + desiredAnim = BOTH_RUNBACK1; + } else { + // desiredAnim = BOTH_RUNBACK_DUAL; + // and so is the dual + desiredAnim = BOTH_RUNBACK2; + } + break; + default: + if (pm->ps->saberHolstered) { // saber off + desiredAnim = BOTH_RUNBACK1; + } else { + desiredAnim = BOTH_RUNBACK2; + } + break; } - break; } } else { - switch (pm->ps->fd.saberAnimLevel) { - case SS_STAFF: - if (pm->ps->saberHolstered > 1) { // blades off - desiredAnim = BOTH_RUN1; - } else if (pm->ps->saberHolstered == 1) { // 1 blade on - desiredAnim = BOTH_RUN2; - } else { - if (pm->ps->fd.forcePowersActive & (1 << FP_SPEED)) { + if (BG_AreRunWalkAnimsFixed() && pm->ps->weapon != WP_SABER) { + desiredAnim = BOTH_RUN1; + } else { + switch (pm->ps->fd.saberAnimLevel) { + case SS_STAFF: + if (pm->ps->saberHolstered > 1) { // blades off desiredAnim = BOTH_RUN1; + } else if (pm->ps->saberHolstered == 1) { // 1 blade on + desiredAnim = BOTH_RUN2; } else { - desiredAnim = BOTH_RUN_STAFF; + if (pm->ps->fd.forcePowersActive & (1 << FP_SPEED)) { + desiredAnim = BOTH_RUN1; + } else { + desiredAnim = BOTH_RUN_STAFF; + } } + break; + case SS_DUAL: + if (pm->ps->saberHolstered > 1) { // blades off + desiredAnim = BOTH_RUN1; + } else if (pm->ps->saberHolstered == 1) { // 1 saber on + desiredAnim = BOTH_RUN2; + } else { + desiredAnim = BOTH_RUN_DUAL; + } + break; + default: + if (pm->ps->saberHolstered) { // saber off + desiredAnim = BOTH_RUN1; + } else { + desiredAnim = BOTH_RUN2; + } + break; } - break; - case SS_DUAL: - if (pm->ps->saberHolstered > 1) { // blades off - desiredAnim = BOTH_RUN1; - } else if (pm->ps->saberHolstered == 1) { // 1 saber on - desiredAnim = BOTH_RUN2; - } else { - desiredAnim = BOTH_RUN_DUAL; - } - break; - default: - if (pm->ps->saberHolstered) { // saber off - desiredAnim = BOTH_RUN1; - } else { - desiredAnim = BOTH_RUN2; - } - break; } } } else { bobmove = 0.2f; // walking bobs slow if (pm->ps->pm_flags & PMF_BACKWARDS_RUN) { - switch (pm->ps->fd.saberAnimLevel) { - case SS_STAFF: - if (pm->ps->saberHolstered > 1) { - desiredAnim = BOTH_WALKBACK1; - } else if (pm->ps->saberHolstered) { - desiredAnim = BOTH_WALKBACK2; - } else { - desiredAnim = BOTH_WALKBACK_STAFF; - } - break; - case SS_DUAL: - if (pm->ps->saberHolstered > 1) { - desiredAnim = BOTH_WALKBACK1; - } else if (pm->ps->saberHolstered) { - desiredAnim = BOTH_WALKBACK2; - } else { - desiredAnim = BOTH_WALKBACK_DUAL; - } - break; - default: - if (pm->ps->saberHolstered) { - desiredAnim = BOTH_WALKBACK1; - } else { - desiredAnim = BOTH_WALKBACK2; + if (BG_AreRunWalkAnimsFixed() && pm->ps->weapon != WP_SABER) { + desiredAnim = BOTH_WALKBACK1; + } else { + switch (pm->ps->fd.saberAnimLevel) { + case SS_STAFF: + if (pm->ps->saberHolstered > 1) { + desiredAnim = BOTH_WALKBACK1; + } else if (pm->ps->saberHolstered) { + desiredAnim = BOTH_WALKBACK2; + } else { + desiredAnim = BOTH_WALKBACK_STAFF; + } + break; + case SS_DUAL: + if (pm->ps->saberHolstered > 1) { + desiredAnim = BOTH_WALKBACK1; + } else if (pm->ps->saberHolstered) { + desiredAnim = BOTH_WALKBACK2; + } else { + desiredAnim = BOTH_WALKBACK_DUAL; + } + break; + default: + if (pm->ps->saberHolstered) { + desiredAnim = BOTH_WALKBACK1; + } else { + desiredAnim = BOTH_WALKBACK2; + } + break; } - break; } } else { if (pm->ps->weapon == WP_MELEE) { desiredAnim = BOTH_WALK1; } else if (BG_SabersOff(pm->ps)) { desiredAnim = BOTH_WALK1; + } else if (BG_AreRunWalkAnimsFixed() && pm->ps->weapon != WP_SABER) { + desiredAnim = BOTH_WALK1; } else { switch (pm->ps->fd.saberAnimLevel) { case SS_STAFF: diff --git a/game/bg_public.h b/game/bg_public.h index 5a7be16..d423e00 100644 --- a/game/bg_public.h +++ b/game/bg_public.h @@ -140,6 +140,8 @@ Ghoul2 Insert End enum legacyFixes_e { LEGACYFIX_SABERMOVEDATA = 0, + LEGACYFIX_WEAPONATTACKANIM, + LEGACYFIX_RUNWALKANIMS, /* m m ""# " m m # # mmm m m # mmm mmm mm#mm mmm m mm # @@ -1587,7 +1589,7 @@ typedef struct saberInfo_s { extern const int WeaponReadyAnim[WP_NUM_WEAPONS]; extern const int WeaponReadyLegsAnim[WP_NUM_WEAPONS]; -extern const int WeaponAttackAnim[WP_NUM_WEAPONS]; +extern int WeaponAttackAnim[WP_NUM_WEAPONS]; extern const int forcePowerDarkLight[NUM_FORCE_POWERS]; @@ -1631,6 +1633,7 @@ const gitem_t *BG_FindItemForHoldable(holdable_e hi); const gitem_t *BG_FindItemForPowerup(powerup_e pw); const gitem_t *BG_FindItemForWeapon(weapon_e wp); void BG_FixSaberMoveData(void); +void BG_FixWeaponAttackAnim(void); qboolean BG_FlippingAnim(int anim); void BG_ForcePowerDrain(playerState_t *ps, forcePowers_t forcePower, int overrideAmt); void BG_G2ATSTAngles(void *ghoul2, int time, vector3 *cent_lerpAngles); diff --git a/game/bg_saberLoad.cpp b/game/bg_saberLoad.cpp index 2650a9c..8cc7368 100644 --- a/game/bg_saberLoad.cpp +++ b/game/bg_saberLoad.cpp @@ -544,7 +544,7 @@ static void Saber_ParseSaberType(saberInfo_t *saber, const char **p) { if (COM_ParseString(p, &value)) return; saberType = GetIDForString(saberTable, value); - if (saberType >= SABER_SINGLE && saberType <= NUM_SABERS) + if (saberType >= SABER_SINGLE && saberType < NUM_SABERS) saber->type = (saberType_e)saberType; } static void Saber_ParseSaberModel(saberInfo_t *saber, const char **p) { diff --git a/game/g_admin.cpp b/game/g_admin.cpp index c90949e..f0be806 100644 --- a/game/g_admin.cpp +++ b/game/g_admin.cpp @@ -179,13 +179,13 @@ static void AM_ConsolePrint(const gentity_t *ent, const char *msg) { if (ent) { trap->SendServerCommand(ent - g_entities, va("print \"%s\"", msg)); } else { - trap->Print(msg); + trap->Print("%s", msg); } } static void PB_Callback(const char *buffer, int clientNum) { if (clientNum == -1) { - trap->Print(buffer); + trap->Print("%s", buffer); } else { trap->SendServerCommand(clientNum, va("print \"%s\"", buffer)); } diff --git a/game/g_bot.cpp b/game/g_bot.cpp index b03c410..37ccbda 100644 --- a/game/g_bot.cpp +++ b/game/g_bot.cpp @@ -3,6 +3,7 @@ // g_bot.c #include "g_local.h" +#include "g_public.h" #define BOT_BEGIN_DELAY_BASE 2000 #define BOT_BEGIN_DELAY_INCREMENT 1500 diff --git a/game/g_client.cpp b/game/g_client.cpp index b61470c..d05a863 100644 --- a/game/g_client.cpp +++ b/game/g_client.cpp @@ -1863,8 +1863,8 @@ qboolean ClientUserinfoChanged(int clientNum) { } else if (client->pers.adminData.renamedTime != 0 && client->pers.adminData.renamedTime > level.time - (japp_amrenameTime.value * 60.0f) * 1000) { float remaining = japp_amrenameTime.value * 60.0f; remaining -= (level.time - client->pers.adminData.renamedTime) / 1000.0f; - trap->SendServerCommand(clientNum, - va("print \"You are not allowed to change name for another " S_COLOR_CYAN "%.1f " S_COLOR_WHITE "seconds\n\"", (double)remaining)); + trap->SendServerCommand( + clientNum, va("print \"You are not allowed to change name for another " S_COLOR_CYAN "%.1f " S_COLOR_WHITE "seconds\n\"", (double)remaining)); } else { trap->SendServerCommand(-1, va("print \"%s" S_COLOR_WHITE " %s %s\n\"", oldname, G_GetStringEdString("MP_SVGAME", "PLRENAME"), client->pers.netname)); @@ -2178,19 +2178,17 @@ const char *ClientConnect(int clientNum, qboolean firstTime, qboolean isBot) { } // disallow multiple connections from same IP - if (!isBot && firstTime) { - if (japp_antiFakePlayer.integer) { - // check for > g_maxConnPerIP connections from same IP - int count = 0, i = 0; - for (i = 0; i < sv_maxclients.integer; i++) { - if (CompareIPString(tmpIP, level.clients[i].sess.IP)) { - count++; - } - } - if (count > japp_maxConnPerIP.integer) { - return "Too many connections from the same IP"; + if (japp_antiFakePlayer.integer && !isBot && firstTime) { + int count = 0, i = 0; + gclient_t *cl; + for (i = 0, cl = level.clients; i < sv_maxclients.integer; i++, cl++) { + if (cl->pers.connected >= CON_CONNECTING && CompareIPString(tmpIP, cl->sess.IP)) { + count++; } } + if (count >= japp_maxConnPerIP.integer) { + return "Too many connections from the same IP"; + } } if (ent->inuse) { @@ -2236,7 +2234,7 @@ const char *ClientConnect(int clientNum, qboolean firstTime, qboolean isBot) { } Q_strcat(msg, sizeof(msg), va(" final csf 0x%X\n", finalCSF)); - G_LogPrintf(level.log.console, msg); + G_LogPrintf(level.log.console, "%s", msg); } // JPLua plugins can deny connections diff --git a/game/g_cmds.cpp b/game/g_cmds.cpp index 404c5cc..231212b 100644 --- a/game/g_cmds.cpp +++ b/game/g_cmds.cpp @@ -1,5 +1,6 @@ // Copyright (C) 1999-2000 Id Software, Inc. // +#include "anims.h" #include "g_local.h" #include "bg_saga.h" #include "g_admin.h" @@ -3164,6 +3165,7 @@ static const emote_t emotes[] = { {"victory", BOTH_TAVION_SCEPTERGROUND, MAX_ANIMATIONS, EMF_NONE}, {"wait", BOTH_STAND10, BOTH_STAND10TOSTAND1, EMF_STATIC | EMF_HOLD | EMF_HOLSTER}, {"won", TORSO_HANDSIGNAL1, MAX_ANIMATIONS, EMF_NONE}, + {"worm", BOTH_WORM, MAX_ANIMATIONS, EMF_STATIC | EMF_HOLD}, }; static const size_t numEmotes = ARRAY_LEN(emotes); @@ -3277,6 +3279,7 @@ EMOTE(victory) EMOTE(surrender) EMOTE(wait) EMOTE(won) +EMOTE(worm) static void Cmd_KnockMeDown(gentity_t *ent) { G_Knockdown(ent); } @@ -3438,6 +3441,7 @@ static const command_t commands[] = { {"amvictory", Cmd_Emote_victory, GTB_ALL, CMDFLAG_NOINTERMISSION | CMDFLAG_ALIVE}, {"amwait", Cmd_Emote_wait, GTB_ALL, CMDFLAG_NOINTERMISSION | CMDFLAG_ALIVE}, {"amwon", Cmd_Emote_won, GTB_ALL, CMDFLAG_NOINTERMISSION | CMDFLAG_ALIVE}, + {"amworm", Cmd_Emote_worm, GTB_ALL, CMDFLAG_NOINTERMISSION | CMDFLAG_ALIVE}, {"callvote", Cmd_CallVote_f, GTB_ALL, CMDFLAG_NOINTERMISSION}, {"debugBMove_Back", Cmd_BotMoveBack_f, GTB_ALL, CMDFLAG_CHEAT | CMDFLAG_ALIVE}, {"debugBMove_Forward", Cmd_BotMoveForward_f, GTB_ALL, CMDFLAG_CHEAT | CMDFLAG_ALIVE}, diff --git a/game/g_main.cpp b/game/g_main.cpp index 1555a05..1a9412e 100644 --- a/game/g_main.cpp +++ b/game/g_main.cpp @@ -170,45 +170,51 @@ static void CVU_CInfo(void) { CPM_UpdateSettings(!!(jp_cinfo.bits & CINFO_CPMPHY static void CVU_Motd(void) { Q_ConvertLinefeeds(g_motd.string); } -static void CVU_FixSaberMoveData(void) { +static void UpdateLegacyFixesConfigstring(legacyFixes_e legacyFix, qboolean enabled) { char sLegacyFixes[32]; trap->GetConfigstring(CS_LEGACY_FIXES, sLegacyFixes, sizeof(sLegacyFixes)); uint32_t legacyFixes = strtoul(sLegacyFixes, NULL, 0); - if (g_fixSaberMoveData.integer) { - legacyFixes |= (1 << LEGACYFIX_SABERMOVEDATA); + if (enabled) { + legacyFixes |= (1 << legacyFix); } else { - legacyFixes &= ~(1 << LEGACYFIX_SABERMOVEDATA); + legacyFixes &= ~(1 << legacyFix); } trap->SetConfigstring(CS_LEGACY_FIXES, va("%" PRIu32, legacyFixes)); } -typedef struct cvarTable_s { - vmCvar_t *vmCvar; - const char *cvarName, *defaultString; - void (*update)(void); - uint32_t cvarFlags; - qboolean trackChange; // track this variable, and announce if changed -} cvarTable_t; +static void CVU_FixSaberMoveData(void) { + BG_FixSaberMoveData(); + UpdateLegacyFixesConfigstring(LEGACYFIX_SABERMOVEDATA, g_fixSaberMoveData.integer); +} + +static void CVU_FixRunWalkAnims(void) { UpdateLegacyFixesConfigstring(LEGACYFIX_RUNWALKANIMS, g_fixRunWalkAnims.integer); } + +static void CVU_FixWeaponAttackAnim(void) { + BG_FixWeaponAttackAnim(); + UpdateLegacyFixesConfigstring(LEGACYFIX_WEAPONATTACKANIM, g_fixWeaponAttackAnim.integer); +} #define XCVAR_DECL #include "g_xcvar.h" #undef XCVAR_DECL -static cvarTable_t gameCvarTable[] = { +static const struct cvarTable_t { + vmCvar_t *vmCvar; + const char *cvarName, *defaultString; + void (*update)(void); + uint32_t cvarFlags; + qboolean trackChange; // track this variable, and announce if changed +} cvarTable[] = { #define XCVAR_LIST #include "g_xcvar.h" #undef XCVAR_LIST }; -static int gameCvarTableSize = ARRAY_LEN(gameCvarTable); const char *G_Cvar_DefaultString(const vmCvar_t *vmCvar) { - int i = 0; - const cvarTable_t *cv = NULL; - - for (i = 0, cv = gameCvarTable; i < gameCvarTableSize; i++, cv++) { - if (cv->vmCvar == vmCvar) { - return cv->defaultString; + for (const auto &cv : cvarTable) { + if (cv.vmCvar == vmCvar) { + return cv.defaultString; } } @@ -216,17 +222,15 @@ const char *G_Cvar_DefaultString(const vmCvar_t *vmCvar) { } void G_RegisterCvars(void) { - int i = 0; - cvarTable_t *cv = NULL; - - // register all cvars - for (i = 0, cv = gameCvarTable; i < gameCvarTableSize; i++, cv++) - trap->Cvar_Register(cv->vmCvar, cv->cvarName, cv->defaultString, cv->cvarFlags); + for (const auto &cv : cvarTable) { + trap->Cvar_Register(cv.vmCvar, cv.cvarName, cv.defaultString, cv.cvarFlags); + } // now update them - for (i = 0, cv = gameCvarTable; i < gameCvarTableSize; i++, cv++) { - if (cv->update) - cv->update(); + for (const auto &cv : cvarTable) { + if (cv.update) { + cv.update(); + } } } @@ -249,22 +253,19 @@ void G_CacheGametype(void) { } void G_UpdateCvars(void) { - int i = 0; - cvarTable_t *cv = NULL; - - for (i = 0, cv = gameCvarTable; i < gameCvarTableSize; i++, cv++) { - if (cv->vmCvar) { - int modCount = cv->vmCvar->modificationCount; - trap->Cvar_Update(cv->vmCvar); - if (cv->vmCvar->modificationCount != modCount) { - if (cv->update) { - cv->update(); + for (const auto &cv : cvarTable) { + if (cv.vmCvar) { + int modCount = cv.vmCvar->modificationCount; + trap->Cvar_Update(cv.vmCvar); + if (cv.vmCvar->modificationCount != modCount) { + if (cv.update) { + cv.update(); } - JPLua::Cvar_Update(cv->cvarName); + JPLua::Cvar_Update(cv.cvarName); - if (cv->trackChange) { - trap->SendServerCommand(-1, va("print \"Server: %s changed to %s\n\"", cv->cvarName, cv->vmCvar->string)); + if (cv.trackChange) { + trap->SendServerCommand(-1, va("print \"Server: %s changed to %s\n\"", cv.cvarName, cv.vmCvar->string)); } } } diff --git a/game/g_smartentities.cpp b/game/g_smartentities.cpp index 57a72c0..3a873e4 100644 --- a/game/g_smartentities.cpp +++ b/game/g_smartentities.cpp @@ -234,7 +234,7 @@ static qboolean SE_NetworkPlayer(const gentity_t *self, const gentity_t *other) // Tracing non-players seems to have a bad effect, we know players are limited to 32 per frame, however other gentities // that are being added are not! It's stupid to actually add traces for it, even with a limited form i used before of 2 -// traces per object. There are to many too track and simply networking them takes less FPS either way +// traces per object. There are too many to track and simply networking them takes less FPS either way qboolean G_EntityOccluded(const gentity_t *self, const gentity_t *other) { // This is a non-player object, just send it (see above). if (!other->inuse || other->s.number >= level.maxclients) { diff --git a/game/g_utils.cpp b/game/g_utils.cpp index 41bfb45..39cb668 100644 --- a/game/g_utils.cpp +++ b/game/g_utils.cpp @@ -1633,7 +1633,7 @@ int G_ClientFromString(const gentity_t *ent, const char *match, uint32_t flags) if (ent) { trap->SendServerCommand(ent - g_entities, va("print \"%s\"", msg)); } else { - trap->Print(va("print %s", msg)); + trap->Print("print %s", msg); } return -1; } @@ -1644,7 +1644,7 @@ int G_ClientFromString(const gentity_t *ent, const char *match, uint32_t flags) if (ent) { trap->SendServerCommand(ent - g_entities, va("print \"Client %s does not exist\n\"", cleanedMatch)); } else { - trap->Print(va("Client %s does not exist\n", cleanedMatch)); + trap->Print("Client %s does not exist\n", cleanedMatch); } } return -1; diff --git a/game/g_xcvar.h b/game/g_xcvar.h index ba8cdd1..162b605 100644 --- a/game/g_xcvar.h +++ b/game/g_xcvar.h @@ -67,6 +67,8 @@ XCVAR_DEF(g_duelWeaponDisable, "1", NULL, CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_ XCVAR_DEF(g_ff_objectives, "0", NULL, CVAR_CHEAT | CVAR_NORESTART, qtrue) XCVAR_DEF(g_fixSaberDisarmBonus, "1", NULL, CVAR_ARCHIVE, qtrue) XCVAR_DEF(g_fixSaberMoveData, "1", CVU_FixSaberMoveData, CVAR_ARCHIVE, qtrue) +XCVAR_DEF(g_fixRunWalkAnims, "1", CVU_FixRunWalkAnims, CVAR_ARCHIVE, qtrue) +XCVAR_DEF(g_fixWeaponAttackAnim, "1", CVU_FixWeaponAttackAnim, CVAR_ARCHIVE, qtrue) XCVAR_DEF(g_forceBasedTeams, "0", NULL, CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_LATCH, qfalse) XCVAR_DEF(g_forceClientUpdateRate, "250", NULL, CVAR_NONE, qfalse) XCVAR_DEF(g_forceDodge, "1", NULL, CVAR_NONE, qtrue) diff --git a/ui/ui_cvar.cpp b/ui/ui_cvar.cpp index d8953b3..14845d7 100644 --- a/ui/ui_cvar.cpp +++ b/ui/ui_cvar.cpp @@ -10,13 +10,6 @@ static void CVU_Derpity( void ) { // Cvar table -typedef struct cvarTable_s { - vmCvar_t *vmCvar; - const char *cvarName, *defaultString; - void (*update)(void); - uint32_t cvarFlags; -} cvarTable_t; - #define XCVAR_DECL #include "ui_xcvar.h" #undef XCVAR_DECL @@ -35,17 +28,18 @@ static void CVU_Master3(void) { trap->Cmd_ExecuteText(EXEC_NOW, va("set sv_maste static void CVU_Master4(void) { trap->Cmd_ExecuteText(EXEC_NOW, va("set sv_master4 \"%s\"", ui_sv_master4.string)); } static void CVU_Master5(void) { trap->Cmd_ExecuteText(EXEC_NOW, va("set sv_master5 \"%s\"", ui_sv_master5.string)); } -static const cvarTable_t uiCvarTable[] = { +static const struct cvarTable_t { + vmCvar_t *vmCvar; + const char *cvarName, *defaultString; + void (*update)(void); + uint32_t cvarFlags; +} cvarTable[] = { #define XCVAR_LIST #include "ui_xcvar.h" #undef XCVAR_LIST }; -static const size_t uiCvarTableSize = ARRAY_LEN(uiCvarTable); void UI_RegisterCvars(void) { - size_t i = 0; - const cvarTable_t *cv = NULL; - char buf[MAX_CVAR_VALUE_STRING]; trap->Cvar_VariableStringBuffer("sv_master1", buf, sizeof(buf)); trap->Cvar_Set("ui_sv_master1", buf); @@ -58,24 +52,25 @@ void UI_RegisterCvars(void) { trap->Cvar_VariableStringBuffer("sv_master5", buf, sizeof(buf)); trap->Cvar_Set("ui_sv_master5", buf); - for (i = 0, cv = uiCvarTable; i < uiCvarTableSize; i++, cv++) { - trap->Cvar_Register(cv->vmCvar, cv->cvarName, cv->defaultString, cv->cvarFlags); - if (cv->update) - cv->update(); + for (const auto &cv : cvarTable) { + trap->Cvar_Register(cv.vmCvar, cv.cvarName, cv.defaultString, cv.cvarFlags); + } + for (const auto &cv : cvarTable) { + if (cv.update) { + cv.update(); + } } } void UI_UpdateCvars(void) { - size_t i = 0; - const cvarTable_t *cv = NULL; - - for (i = 0, cv = uiCvarTable; i < uiCvarTableSize; i++, cv++) { - if (cv->vmCvar) { - int modCount = cv->vmCvar->modificationCount; - trap->Cvar_Update(cv->vmCvar); - if (cv->vmCvar->modificationCount != modCount) { - if (cv->update) - cv->update(); + for (const auto &cv : cvarTable) { + if (cv.vmCvar) { + int modCount = cv.vmCvar->modificationCount; + trap->Cvar_Update(cv.vmCvar); + if (cv.vmCvar->modificationCount != modCount) { + if (cv.update) { + cv.update(); + } } } } diff --git a/ui/ui_main.cpp b/ui/ui_main.cpp index 623461d..241d6c3 100644 --- a/ui/ui_main.cpp +++ b/ui/ui_main.cpp @@ -8327,6 +8327,25 @@ void JP_SaveFavServers(void) { } #endif +static void UI_CvarHelp(const char *cvarName, qboolean enter, char *helpBuffer, size_t helpBufferSize) { + /* + In the digital realm, where lines of code dance and weave, + One missing export can bring a program to its knees. + A fragile balance disrupted by a single slip, + Don't crash my program, let it continue its script. + + Each function, each module, carefully crafted and linked, + A symphony of logic, with no room for a missing brink. + So delicate, so intricate, a web of commands, + Don't let it break, don't let it end. + + For in this world of bytes and bits, where errors hide, + A missing export can be a fatal divide. + So heed my plea, oh code gods above, + Don't crash my program, let it run with love. + */ +} + uiImport_t *trap = NULL; Q_CABI { @@ -8355,6 +8374,7 @@ Q_CABI { uie.ConsoleCommand = UI_ConsoleCommand; uie.DrawConnectScreen = UI_DrawConnectScreen; uie.MenuReset = Menu_Reset; + uie.CvarHelp = UI_CvarHelp; return &uie; } diff --git a/ui/ui_public.h b/ui/ui_public.h index d444a9c..e22801e 100644 --- a/ui/ui_public.h +++ b/ui/ui_public.h @@ -3,6 +3,9 @@ // Copyright (C) 1999-2000 Id Software, Inc. // +#include "qcommon/q_shared.h" +#include "cgame/tr_types.h" + #define UI_API_VERSION 3 #define UI_LEGACY_API_VERSION 7 @@ -208,274 +211,144 @@ enum uiExportLegacy_e { typedef struct uiImport_s { void (*Print)(const char *msg, ...); - void (*Error)(int level, const char *error, ...); - int (*Milliseconds)(void); - int (*RealTime)(qtime_t *qtime); - int (*MemoryRemaining)(void); - void (*Cvar_Create)(const char *var_name, const char *var_value, uint32_t flags); - void (*Cvar_InfoStringBuffer)(int bit, char *buffer, int bufsize); - void (*Cvar_Register)(vmCvar_t *cvar, const char *var_name, const char *value, uint32_t flags); - void (*Cvar_Reset)(const char *name); - void (*Cvar_Set)(const char *var_name, const char *value); - void (*Cvar_SetValue)(const char *var_name, float value); - void (*Cvar_Update)(vmCvar_t *cvar); - void (*Cvar_VariableStringBuffer)(const char *var_name, char *buffer, int bufsize); - float (*Cvar_VariableValue)(const char *var_name); - int (*Cmd_Argc)(void); - void (*Cmd_Argv)(int n, char *buffer, int bufferLength); - void (*Cmd_ExecuteText)(int exec_when, const char *text); - void (*FS_Close)(fileHandle_t f); - int (*FS_GetFileList)(const char *path, const char *extension, char *listbuf, int bufsize); - int (*FS_Open)(const char *qpath, fileHandle_t *f, fsMode_t mode); - int (*FS_Read)(void *buffer, int len, fileHandle_t f); - int (*FS_Write)(const void *buffer, int len, fileHandle_t f); - void (*GetClientState)(uiClientState_t *state); - void (*GetClipboardData)(char *buf, int bufsize); - int (*GetConfigString)(int index, char *buff, int buffsize); - void (*GetGlconfig)(glconfig_t *glconfig); - void (*UpdateScreen)(void); - void (*Key_ClearStates)(void); - void (*Key_GetBindingBuf)(int keynum, char *buf, int buflen); - qboolean (*Key_IsDown)(int keynum); - void (*Key_KeynumToStringBuf)(int keynum, char *buf, int buflen); - void (*Key_SetBinding)(int keynum, const char *binding); - int (*Key_GetCatcher)(void); - qboolean (*Key_GetOverstrikeMode)(void); - void (*Key_SetCatcher)(int catcher); - void (*Key_SetOverstrikeMode)(qboolean state); - int (*PC_AddGlobalDefine)(char *define); - int (*PC_FreeSource)(int handle); - int (*PC_LoadGlobalDefines)(const char *filename); - int (*PC_LoadSource)(const char *filename); - int (*PC_ReadToken)(int handle, pc_token_t *pc_token); - void (*PC_RemoveAllGlobalDefines)(void); - int (*PC_SourceFileAndLine)(int handle, char *filename, int *line); - void (*CIN_DrawCinematic)(int handle); - int (*CIN_PlayCinematic)(const char *arg0, int xpos, int ypos, int width, int height, uint32_t bits); - cinState_t (*CIN_RunCinematic)(int handle); - void (*CIN_SetExtents)(int handle, int x, int y, int w, int h); - cinState_t (*CIN_StopCinematic)(int handle); - int (*LAN_AddServer)(int source, const char *name, const char *addr); - void (*LAN_ClearPing)(int n); - int (*LAN_CompareServers)(int source, int sortKey, int sortDir, int s1, int s2); - void (*LAN_GetPing)(int n, char *buf, int buflen, int *pingtime); - void (*LAN_GetPingInfo)(int n, char *buf, int buflen); - int (*LAN_GetPingQueueCount)(void); - void (*LAN_GetServerAddressString)(int source, int n, char *buf, int buflen); - int (*LAN_GetServerCount)(int source); - void (*LAN_GetServerInfo)(int source, int n, char *buf, int buflen); - int (*LAN_GetServerPing)(int source, int n); - void (*LAN_LoadCachedServers)(void); - void (*LAN_MarkServerVisible)(int source, int n, qboolean visible); - void (*LAN_RemoveServer)(int source, const char *addr); - void (*LAN_ResetPings)(int n); - void (*LAN_SaveCachedServers)(void); - int (*LAN_ServerIsVisible)(int source, int n); - int (*LAN_ServerStatus)(const char *serverAddress, char *serverStatus, int maxLen); - qboolean (*LAN_UpdateVisiblePings)(int source); - void (*S_StartBackgroundTrack)(const char *intro, const char *loop, qboolean bReturnWithoutStarting); - void (*S_StartLocalSound)(sfxHandle_t sfx, int channelNum); - void (*S_StopBackgroundTrack)(void); - sfxHandle_t (*S_RegisterSound)(const char *sample); - void (*SE_GetLanguageName)(const int languageIndex, char *buffer); - int (*SE_GetNumLanguages)(void); - qboolean (*SE_GetStringTextString)(const char *text, char *buffer, int bufferLength); - qboolean (*R_Language_IsAsian)(void); - qboolean (*R_Language_UsesSpaces)(void); - unsigned int (*R_AnyLanguage_ReadCharFromString)(const char *psText, int *piAdvanceCount, qboolean *pbIsTrailingPunctuation); - void (*R_AddLightToScene)(const vector3 *org, float intensity, float r, float g, float b); - void (*R_AddPolysToScene)(qhandle_t hShader, int numVerts, const polyVert_t *verts, int num); - void (*R_AddRefEntityToScene)(const refEntity_t *re); - void (*R_ClearScene)(void); - void (*R_DrawStretchPic)(float x, float y, float w, float h, float s1, float t1, float s2, float t2, qhandle_t hShader); - int (*R_Font_StrLenPixels)(const char *text, const int iFontIndex, const float scale); - int (*R_Font_StrLenChars)(const char *text); - int (*R_Font_HeightPixels)(const int iFontIndex, const float scale); - void (*R_Font_DrawString)(int ox, int oy, const char *text, const vector4 *rgba, const int setIndex, int iCharLimit, const float scale); - int (*R_LerpTag)(orientation_t *tag, clipHandle_t mod, int startFrame, int endFrame, float frac, const char *tagName); - void (*R_ModelBounds)(clipHandle_t model, vector3 *mins, vector3 *maxs); - qhandle_t (*R_RegisterModel)(const char *name); - qhandle_t (*R_RegisterSkin)(const char *name); - qhandle_t (*R_RegisterShaderNoMip)(const char *name); - qhandle_t (*R_RegisterFont)(const char *fontName); - void (*R_RemapShader)(const char *oldShader, const char *newShader, const char *timeOffset); - void (*R_RenderScene)(const refdef_t *fd); - void (*R_SetColor)(const vector4 *rgba); - void (*R_ShaderNameFromIndex)(char *name, int index); - void (*G2_ListModelSurfaces)(void *ghlInfo); - void (*G2_ListModelBones)(void *ghlInfo, int frame); - void (*G2_SetGhoul2ModelIndexes)(void *ghoul2, qhandle_t *modelList, qhandle_t *skinList); - qboolean (*G2_HaveWeGhoul2Models)(void *ghoul2); - qboolean (*G2API_GetBoltMatrix)(void *ghoul2, const int modelIndex, const int boltIndex, mdxaBone_t *matrix, const vector3 *angles, const vector3 *position, const int frameNum, qhandle_t *modelList, vector3 *scale); - qboolean (*G2API_GetBoltMatrix_NoReconstruct)(void *ghoul2, const int modelIndex, const int boltIndex, mdxaBone_t *matrix, const vector3 *angles, const vector3 *position, const int frameNum, qhandle_t *modelList, vector3 *scale); - qboolean (*G2API_GetBoltMatrix_NoRecNoRot)(void *ghoul2, const int modelIndex, const int boltIndex, mdxaBone_t *matrix, const vector3 *angles, const vector3 *position, const int frameNum, qhandle_t *modelList, vector3 *scale); - int (*G2API_InitGhoul2Model)(void **ghoul2Ptr, const char *fileName, int modelIndex, qhandle_t customSkin, qhandle_t customShader, uint32_t modelFlags, int lodBias); - void (*G2API_CollisionDetect)(CollisionRecord_t *collRecMap, void *ghoul2, const vector3 *angles, const vector3 *position, int frameNumber, int entNum, vector3 *rayStart, vector3 *rayEnd, vector3 *scale, uint32_t traceFlags, int useLod, float fRadius); - void (*G2API_CollisionDetectCache)(CollisionRecord_t *collRecMap, void *ghoul2, const vector3 *angles, const vector3 *position, int frameNumber, int entNum, vector3 *rayStart, vector3 *rayEnd, vector3 *scale, uint32_t traceFlags, int useLod, float fRadius); - void (*G2API_CleanGhoul2Models)(void **ghoul2Ptr); - qboolean (*G2API_SetBoneAngles)(void *ghoul2, int modelIndex, const char *boneName, const vector3 *angles, const uint32_t flags, const int up, const int right, const int forward, qhandle_t *modelList, int blendTime, int currentTime); - qboolean (*G2API_SetBoneAnim)(void *ghoul2, const int modelIndex, const char *boneName, const int startFrame, const int endFrame, const uint32_t flags, const float animSpeed, const int currentTime, const float setFrame, const int blendTime); - qboolean (*G2API_GetBoneAnim)(void *ghoul2, const char *boneName, const int currentTime, float *currentFrame, int *startFrame, int *endFrame, uint32_t *flags, float *animSpeed, int *modelList, const int modelIndex); - qboolean (*G2API_GetBoneFrame)(void *ghoul2, const char *boneName, const int currentTime, float *currentFrame, int *modelList, const int modelIndex); - void (*G2API_GetGLAName)(void *ghoul2, int modelIndex, char *fillBuf); - int (*G2API_CopyGhoul2Instance)(void *g2From, void *g2To, int modelIndex); - void (*G2API_CopySpecificGhoul2Model)(void *g2From, int modelFrom, void *g2To, int modelTo); - void (*G2API_DuplicateGhoul2Instance)(void *g2From, void **g2To); - qboolean (*G2API_HasGhoul2ModelOnIndex)(void *ghlInfo, int modelIndex); - qboolean (*G2API_RemoveGhoul2Model)(void *ghlInfo, int modelIndex); - int (*G2API_AddBolt)(void *ghoul2, int modelIndex, const char *boneName); - void (*G2API_SetBoltInfo)(void *ghoul2, int modelIndex, int boltInfo); - qboolean (*G2API_SetRootSurface)(void *ghoul2, const int modelIndex, const char *surfaceName); - qboolean (*G2API_SetSurfaceOnOff)(void *ghoul2, const char *surfaceName, const uint32_t flags); - qboolean (*G2API_SetNewOrigin)(void *ghoul2, const int boltIndex); - int (*G2API_GetTime)(void); - void (*G2API_SetTime)(int time, int clock); - void (*G2API_SetRagDoll)(void *ghoul2, sharedRagDollParams_t *params); - void (*G2API_AnimateG2Models)(void *ghoul2, int time, sharedRagDollUpdateParams_t *params); - qboolean (*G2API_SetBoneIKState)(void *ghoul2, int time, const char *boneName, int ikState, sharedSetBoneIKStateParams_t *params); - qboolean (*G2API_IKMove)(void *ghoul2, int time, sharedIKMoveParams_t *params); - void (*G2API_GetSurfaceName)(void *ghoul2, int surfNumber, int modelIndex, char *fillBuf); - qboolean (*G2API_SetSkin)(void *ghoul2, int modelIndex, qhandle_t customSkin, qhandle_t renderSkin); - qboolean (*G2API_AttachG2Model)(void *ghoul2From, int modelIndexFrom, void *ghoul2To, int toBoltIndex, int toModel); - struct { float (*R_Font_StrLenPixels)(const char *text, const int iFontIndex, const float scale); void (*AddCommand)(const char *cmd_name); @@ -485,22 +358,14 @@ typedef struct uiImport_s { typedef struct uiExport_s { void (*Init)(qboolean inGameLoad); - void (*Shutdown)(void); - void (*KeyEvent)(int key, qboolean down); - void (*MouseEvent)(int dx, int dy); - void (*Refresh)(int realtime); - qboolean (*IsFullscreen)(void); - void (*SetActiveMenu)(uiMenuCommand_e menu); - qboolean (*ConsoleCommand)(int realTime); - void (*DrawConnectScreen)(qboolean overlay); - void (*MenuReset)(void); + void (*CvarHelp)(const char *cvarName, qboolean enter, char *helpBuffer, size_t helpBufferSize); } uiExport_t; diff --git a/ui/ui_shared.cpp b/ui/ui_shared.cpp index ee8089d..f5f0bd5 100644 --- a/ui/ui_shared.cpp +++ b/ui/ui_shared.cpp @@ -424,8 +424,8 @@ qboolean String_Parse(char **p, const char **out) { qboolean PC_String_Parse(int handle, const char **out) { static const char *squiggy = "}"; pc_token_t token{}; - static int counter = 0; - counter++; + // static int counter = 0; + // counter++; if (!trap->PC_ReadToken(handle, &token)) return qfalse; @@ -6712,7 +6712,7 @@ qboolean ItemParse_flag(itemDef_t *item, int handle) { } if (itemFlags[i].string == NULL) { - Com_Printf( S_COLOR_YELLOW "Unknown item style value '%s'", token.string); + Com_Printf(S_COLOR_YELLOW "Unknown item style value '%s'", token.string); } return qtrue;