From 4f52c04b3b81ef426b7ab60b7618ab0e3997fc5a Mon Sep 17 00:00:00 2001 From: BjossiAlfreds Date: Sat, 26 Oct 2024 19:56:02 +0000 Subject: [PATCH 01/19] Small fix for SDL3 API change for SetClipboardText --- src/client/input/sdl2.c | 5 ++++- src/client/input/sdl3.c | 7 ++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/client/input/sdl2.c b/src/client/input/sdl2.c index 992d1a88..ed2a28f9 100644 --- a/src/client/input/sdl2.c +++ b/src/client/input/sdl2.c @@ -2441,8 +2441,11 @@ IN_GetClipboardText(char *out, size_t n) SDL_free(s); } +/* Copy string s to the clipboard. + Returns 0 on success, 1 otherwise. +*/ int IN_SetClipboardText(const char *s) { - return SDL_SetClipboardText(s); + return SDL_SetClipboardText(s) != 0; } diff --git a/src/client/input/sdl3.c b/src/client/input/sdl3.c index 52b97535..2bee5218 100644 --- a/src/client/input/sdl3.c +++ b/src/client/input/sdl3.c @@ -2437,8 +2437,13 @@ IN_GetClipboardText(char *out, size_t n) SDL_free(s); } +/* Copy string s to the clipboard. + Returns 0 on success, 1 otherwise. +*/ int IN_SetClipboardText(const char *s) { - return SDL_SetClipboardText(s); + bool res = SDL_SetClipboardText(s); + + return !res; } From f5eb462fc1cbe0e7a8d96c80b3502add40f1cf32 Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Fri, 1 Nov 2024 08:48:54 +0200 Subject: [PATCH 02/19] filesystem: fix usage of 'void *' in pointer arithmetic Fixes: #30 --- src/client/refresh/files/models_mdr.c | 2 +- src/common/filesystem.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/client/refresh/files/models_mdr.c b/src/client/refresh/files/models_mdr.c index 00e869de..05cf3f40 100644 --- a/src/client/refresh/files/models_mdr.c +++ b/src/client/refresh/files/models_mdr.c @@ -236,7 +236,7 @@ Mod_LoadModel_MDR(const char *mod_name, const void *buffer, int modfilelen, } mdr_lod_t *inlod; - inlod = (mdr_lod_t*)(buffer + pinmodel.ofs_lods); + inlod = (mdr_lod_t*)((byte *)buffer + pinmodel.ofs_lods); meshofs = inlod->ofs_surfaces; for (i = 0; i < inlod->num_surfaces; i++) diff --git a/src/common/filesystem.c b/src/common/filesystem.c index ebe46bf5..ee555dc3 100644 --- a/src/common/filesystem.c +++ b/src/common/filesystem.c @@ -655,7 +655,7 @@ FS_DecompressFile(void *buffer, int size, const fsHandle_t *handle) return 0; } - memmove(buffer + written, comressed_buffer + read, x + 1); + memmove((byte *)buffer + written, comressed_buffer + read, x + 1); read += x + 1; written += x + 1; @@ -670,7 +670,7 @@ FS_DecompressFile(void *buffer, int size, const fsHandle_t *handle) return 0; } - memset(buffer + written, 0, x - 62); + memset((byte *)buffer + written, 0, x - 62); written += x - 62; } @@ -684,7 +684,7 @@ FS_DecompressFile(void *buffer, int size, const fsHandle_t *handle) return 0; } - memset(buffer + written, comressed_buffer[read], x - 126); + memset((byte *)buffer + written, comressed_buffer[read], x - 126); ++read; written += x - 126; @@ -699,7 +699,7 @@ FS_DecompressFile(void *buffer, int size, const fsHandle_t *handle) return 0; } - memmove(buffer + written, (buffer + written) - ( + memmove((byte *)buffer + written, ((byte *)buffer + written) - ( (int)comressed_buffer[read] + 2), x - 190); ++read; From 1f147f2fa85bd41e2b14fedf1ca2c9536e47821f Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Wed, 30 Oct 2024 01:09:17 +0200 Subject: [PATCH 03/19] game: sort spawn functions --- src/game/g_spawn.c | 85 ++++++++++++++++++++++++++++++++---- src/game/header/local.h | 2 +- src/game/savegame/savegame.c | 2 +- stuff/models/entity.dat | 2 - 4 files changed, 78 insertions(+), 13 deletions(-) diff --git a/src/game/g_spawn.c b/src/game/g_spawn.c index 012400e4..620c2e21 100644 --- a/src/game/g_spawn.c +++ b/src/game/g_spawn.c @@ -72,6 +72,7 @@ typedef struct static dynamicentity_t *dynamicentities; static int ndynamicentities; +static int nstaticentities; static void DynamicSpawnUpdate(edict_t *self, dynamicentity_t *data) @@ -220,6 +221,39 @@ Spawn_CheckCoop_MapHacks(edict_t *ent) return false; } +static const spawn_t * +StaticSpawnSearch(const char *classname) +{ + int start, end; + + start = 0; + end = nstaticentities - 1; + + while (start <= end) + { + int i, res; + + i = start + (end - start) / 2; + + res = Q_stricmp(spawns[i].name, classname); + if (res == 0) + { + return &spawns[i]; + } + else if (res < 0) + { + start = i + 1; + } + else + { + end = i - 1; + } + } + + return NULL; +} + + /* * Finds the spawn function for * the entity and calls it @@ -227,7 +261,7 @@ Spawn_CheckCoop_MapHacks(edict_t *ent) void ED_CallSpawn(edict_t *ent) { - spawn_t *s; + const spawn_t *s; gitem_t *item; int i, dyn_id; @@ -291,14 +325,12 @@ ED_CallSpawn(edict_t *ent) } /* check normal spawn functions */ - for (s = spawns; s->name; s++) + s = StaticSpawnSearch(ent->classname); + if (s) { - if (!strcmp(s->name, ent->classname)) - { - /* found it */ - s->spawn(ent); - return; - } + /* found it */ + s->spawn(ent); + return; } if (dyn_id >= 0 && dynamicentities[dyn_id].model_path[0]) @@ -1940,7 +1972,7 @@ DynamicSort(const void *p1, const void *p2) return Q_stricmp(ent1->classname, ent2->classname); } -void +static void DynamicSpawnInit(void) { char *buf_ent, *buf_ai, *raw; @@ -2226,3 +2258,38 @@ DynamicSpawnInit(void) /* sort definitions */ qsort(dynamicentities, ndynamicentities, sizeof(dynamicentity_t), DynamicSort); } + +static int +StaticSort(const void *p1, const void *p2) +{ + spawn_t *ent1, *ent2; + + ent1 = (spawn_t*)p1; + ent2 = (spawn_t*)p2; + return Q_stricmp(ent1->name, ent2->name); +} + +static void +StaticSpawnInit(void) +{ + const spawn_t *s; + + /* check count of spawn functions */ + for (s = spawns; s->name; s++) + { + } + + nstaticentities = s - spawns; + + gi.dprintf("Found %d static definitions\n", nstaticentities); + + /* sort definitions */ + qsort(spawns, nstaticentities, sizeof(spawn_t), StaticSort); +} + +void +SpawnInit(void) +{ + StaticSpawnInit(); + DynamicSpawnInit(); +} diff --git a/src/game/header/local.h b/src/game/header/local.h index 4eb4fc28..b0134bb3 100644 --- a/src/game/header/local.h +++ b/src/game/header/local.h @@ -1084,7 +1084,7 @@ void fire_doppleganger(edict_t *ent, vec3_t start, vec3_t aimdir); /* g_spawn.c */ void ED_CallSpawn(edict_t *ent); char *ED_NewString(const char *string, qboolean raw); -void DynamicSpawnInit(void); +void SpawnInit(void); edict_t *CreateFlyMonster(vec3_t origin, vec3_t angles, vec3_t mins, vec3_t maxs, char *classname); edict_t *CreateGroundMonster(vec3_t origin, vec3_t angles, vec3_t mins, diff --git a/src/game/savegame/savegame.c b/src/game/savegame/savegame.c index 8cfe4e8d..e4208c5c 100644 --- a/src/game/savegame/savegame.c +++ b/src/game/savegame/savegame.c @@ -268,7 +268,7 @@ InitGame(void) LocalizationInit(); /* initilize dynamic object spawn */ - DynamicSpawnInit(); + SpawnInit(); /* items */ InitItems(); diff --git a/stuff/models/entity.dat b/stuff/models/entity.dat index 1f2e09e1..5006ef01 100644 --- a/stuff/models/entity.dat +++ b/stuff/models/entity.dat @@ -887,12 +887,10 @@ trigger_endgame||1.0|1.0|1.0|general|0.0|0.0|0.0|0.0|0.0|0.0|shadow|0|0.0|0.0|0| trigger_farclip||1.0|1.0|1.0|general|0.0|0.0|0.0|0.0|0.0|0.0|shadow|0|0.0|0.0|0|0|0|0:0|0|0|none|Changes the console variable r_farclipdist.|0.5|0.5|0.5 trigger_fogdensity||1.0|1.0|1.0|general|0.0|0.0|0.0|0.0|0.0|0.0|shadow|0|0.0|0.0|0|0|0|0:0|0|0|none|Sets r_fog_density and fog color|.5|.5|.5 trigger_goto_buoy||1.0|1.0|1.0|general|0.0|0.0|0.0|0.0|0.0|0.0|shadow|0|0.0|0.0|0|0|0|0:0|0|0|none|Send monster to buoy|.5|.5|.5 -trigger_Gravity||1.0|1.0|1.0|general|0.0|0.0|0.0|0.0|0.0|0.0|shadow|0|0.0|0.0|0|0|0|0:0|0|0|none||.5|.5|.5 trigger_lightning||1.0|1.0|1.0|general|0.0|0.0|0.0|0.0|0.0|0.0|shadow|0|0.0|0.0|0|0|0|0:0|0|0|none|Triggers lightning bolt|0.5|0.5|0.5 trigger_mappercentage||1.0|1.0|1.0|general|0.0|0.0|0.0|0.0|0.0|0.0|shadow|0|0.0|0.0|0|0|0|0:0|0|0|none|Map percentage|0.3|0.1|0.6 trigger_mission_give||1.0|1.0|1.0|general|0.0|0.0|0.0|0.0|0.0|0.0|shadow|0|0.0|0.0|0|0|0|0:0|0|0|none|Gives mission objectives|0.5|0.5|0.5 trigger_mission_take||1.0|1.0|1.0|general|0.0|0.0|0.0|0.0|0.0|0.0|shadow|0|0.0|0.0|0|0|0|0:0|0|0|none|Removes mission objectives|0.5|0.5|0.5 -trigger_MonsterJump||1.0|1.0|1.0|general|0.0|0.0|0.0|0.0|0.0|0.0|shadow|0|0.0|0.0|0|0|0|0:0|0|0|none|Makes monsters jump|0.5|0.5|0.5 trigger_playerpushbutton||1.0|1.0|1.0|general|0.0|0.0|0.0|0.0|0.0|0.0|shadow|0|0.0|0.0|0|0|0|0:0|0|0|none|Player push button|.5|.5|.5 trigger_playerpushlever||1.0|1.0|1.0|general|0.0|0.0|0.0|0.0|0.0|0.0|shadow|0|0.0|0.0|0|0|0|0:0|0|0|none|Player Push lever|.5|.5|.5 trigger_playerusepuzzle||1.0|1.0|1.0|general|0.0|0.0|0.0|0.0|0.0|0.0|shadow|0|0.0|0.0|0|0|0|0:0|0|0|none|Player can use puzzle items within this entity|.5|.5|.5 From dce94154114e1090d1b8c10a8edbb36b591b1fe9 Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Fri, 1 Nov 2024 00:27:12 +0200 Subject: [PATCH 04/19] game: Add key_yellow_key item definition Based on: * https://github.com/id-Software/quake2-rerelease-dll/blob/main/rerelease/g_items.cpp --- src/game/g_ctf.c | 2 +- src/game/g_items.c | 78 +++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 78 insertions(+), 2 deletions(-) diff --git a/src/game/g_ctf.c b/src/game/g_ctf.c index 6eaaeeb4..3d2b44ba 100644 --- a/src/game/g_ctf.c +++ b/src/game/g_ctf.c @@ -1198,7 +1198,7 @@ CTFFlagSetup(edict_t *ent) if (tr.startsolid) { - gi.dprintf("CTFFlagSetup: %s startsolid at %s\n", ent->classname, + gi.dprintf("%s: %s startsolid at %s\n", __func__, ent->classname, vtos(ent->s.origin)); G_FreeEdict(ent); return; diff --git a/src/game/g_items.c b/src/game/g_items.c index 39a8a031..a20e5138 100644 --- a/src/game/g_items.c +++ b/src/game/g_items.c @@ -1975,7 +1975,8 @@ droptofloor(edict_t *ent) } else { - gi.dprintf("droptofloor: %s startsolid at %s\n", + gi.dprintf("%s: %s startsolid at %s\n", + __func__, ent->classname, vtos(ent->s.origin)); G_FreeEdict(ent); @@ -3761,6 +3762,81 @@ static const gitem_t gameitemlist[] = { "" }, + /* + * QUAKED key_explosive_charges (0 .5 .8) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN NO_TOUCH + * warehouse circuits, key for N64 + */ + { + "key_explosive_charges", + Pickup_Key, + NULL, + Drop_General, + NULL, + "items/pkup.wav", + "models/items/n64/charge/tris.md2", EF_ROTATE, + NULL, + "n64/i_charges", + "Explosive Charges", + 2, + 0, + NULL, + IT_STAY_COOP | IT_KEY, + 0, + NULL, + 0, + "" + }, + + /* + * QUAKED key_yellow_key (0 .5 .8) (-16 -16 -16) (16 16 16) + * normal door key - yellow, key for N64 + */ + { + "key_yellow_key", + Pickup_Key, + NULL, + Drop_General, + NULL, + "items/pkup.wav", + "models/items/n64/yellow_key/tris.md2", EF_ROTATE, + NULL, + "n64/i_yellow_key", + "Yellow Key", + 2, + 0, + NULL, + IT_STAY_COOP | IT_KEY, + 0, + NULL, + 0, + "" + }, + + /* + * QUAKED key_power_core (0 .5 .8) (-16 -16 -16) (16 16 16) + * key for N64 + */ + { + "key_power_core", + Pickup_Key, + NULL, + Drop_General, + NULL, + "items/pkup.wav", + "models/items/n64/power_core/tris.md2", EF_ROTATE, + NULL, + "k_pyramid", + "Power Core", + 2, + 0, + NULL, + IT_STAY_COOP | IT_KEY, + 0, + NULL, + 0, + "" + }, + /* * QUAKED key_pyramid (0 .5 .8) (-16 -16 -16) (16 16 16) TRIGGER_SPAWN * key for the entrance of jail3 From 1b7ceada592c7e4f56578142b1fe2b7e0ad2f208 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Sat, 2 Nov 2024 14:05:47 +0000 Subject: [PATCH 05/19] FS_Dir_f little optimisation. --- src/common/filesystem.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/common/filesystem.c b/src/common/filesystem.c index 6e15cdbc..ece3ba97 100644 --- a/src/common/filesystem.c +++ b/src/common/filesystem.c @@ -1534,6 +1534,7 @@ FS_Dir_f(void) char **dirnames; /* File list. */ char findname[1024]; /* File search path and pattern. */ char *path = NULL; /* Search path. */ + char *lastsep; char wildcard[1024] = "*.*"; /* File pattern. */ int i; /* Loop counter. */ int ndirs; /* Number of files in list. */ @@ -1555,9 +1556,10 @@ FS_Dir_f(void) { for (i = 0; i < ndirs - 1; i++) { - if (strrchr(dirnames[i], '/')) + lastsep = strrchr(dirnames[i], '/'); + if (lastsep) { - Com_Printf("%s\n", strrchr(dirnames[i], '/') + 1); + Com_Printf("%s\n", lastsep + 1); } else { From be83c229e027ef08c451824c04803fa947333ad9 Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Sat, 2 Nov 2024 17:54:27 +0200 Subject: [PATCH 06/19] game: fix position of dropped objects --- Makefile | 4 ++-- src/game/g_items.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index d26b013f..612a789e 100644 --- a/Makefile +++ b/Makefile @@ -150,7 +150,7 @@ endif # Highest supported optimizations are -O2, higher levels # will likely break this crappy code. ifdef DEBUG -CFLAGS ?= -O0 -g -Wall -pipe -DDEBUG +CFLAGS ?= -O0 -g -Wall -Wpointer-arith -pipe -DDEBUG ifdef ASAN override CFLAGS += -fsanitize=address -DUSE_SANITIZER endif @@ -158,7 +158,7 @@ ifdef UBSAN override CFLAGS += -fsanitize=undefined -DUSE_SANITIZER endif else -CFLAGS ?= -O2 -Wall -pipe -fomit-frame-pointer +CFLAGS ?= -O2 -Wall -Wpointer-arith -pipe -fomit-frame-pointer endif # Always needed are: diff --git a/src/game/g_items.c b/src/game/g_items.c index a20e5138..6ccf8f21 100644 --- a/src/game/g_items.c +++ b/src/game/g_items.c @@ -1931,6 +1931,57 @@ Use_Item(edict_t *ent, edict_t *other /* unused */, edict_t *activator /* unused /* ====================================================================== */ +static void +FixObjectPosition(edict_t *ent) +{ + int i; + + for (i = 0; i < 3; i++) + { + int j; + + for (j = 0; j < 3; j++) + { + vec3_t pos; + trace_t tr_pos; + int k; + + VectorCopy(ent->s.origin, pos); + + /* move by min */ + for (k = 0; k < i + 1; k++) + { + int v; + + v = (j + k) % 3; + pos[v] = ent->s.origin[v] - ent->mins[v]; + } + + tr_pos = gi.trace(pos, ent->mins, ent->maxs, ent->s.origin, ent, MASK_SOLID); + if (!tr_pos.startsolid) + { + VectorCopy(tr_pos.endpos, ent->s.origin); + return; + } + + /* move by max */ + for (k = 0; k < i + 1; k++) + { + int v; + + v = (j + k) % 3; + pos[v] = ent->s.origin[v] - ent->maxs[v]; + } + tr_pos = gi.trace(pos, ent->mins, ent->maxs, ent->s.origin, ent, MASK_SOLID); + if (!tr_pos.startsolid) + { + VectorCopy(tr_pos.endpos, ent->s.origin); + return; + } + } + } +} + void droptofloor(edict_t *ent) { @@ -1966,6 +2017,13 @@ droptofloor(edict_t *ent) tr = gi.trace(ent->s.origin, ent->mins, ent->maxs, dest, ent, MASK_SOLID); + if (tr.startsolid) + { + FixObjectPosition(ent); + + tr = gi.trace(ent->s.origin, ent->mins, ent->maxs, dest, ent, MASK_SOLID); + } + if (tr.startsolid) { if (strcmp(ent->classname, "foodcube") == 0) From 67b2bc80ac7df26b4150a39ca18982b273c158b5 Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Mon, 4 Nov 2024 23:31:14 +0200 Subject: [PATCH 07/19] game: add choose_cdtrack --- src/game/g_obj.c | 6 +++++ src/game/g_target.c | 9 +++++++ src/game/g_trigger.c | 30 +++++++++++++++++++++++ src/game/savegame/tables/gamefunc_decs.h | 3 ++- src/game/savegame/tables/gamefunc_list.h | 1 + src/game/savegame/tables/spawnfunc_decs.h | 1 + src/game/savegame/tables/spawnfunc_list.h | 1 + stuff/models/entity.dat | 2 +- 8 files changed, 51 insertions(+), 2 deletions(-) diff --git a/src/game/g_obj.c b/src/game/g_obj.c index 4dd27663..0549e5e5 100644 --- a/src/game/g_obj.c +++ b/src/game/g_obj.c @@ -79,6 +79,12 @@ object_big_fire_think(edict_t *self) { self->s.frame = (self->s.frame + 1) % 60; self->nextthink = level.time + FRAMETIME; + + /* add particles */ + gi.WriteByte(svc_temp_entity); + gi.WriteByte(TE_FLAME); + gi.WritePosition(self->s.origin); + gi.multicast(self->s.origin, MULTICAST_PVS); } void diff --git a/src/game/g_target.c b/src/game/g_target.c index e3b690ef..ec5effaf 100644 --- a/src/game/g_target.c +++ b/src/game/g_target.c @@ -1627,6 +1627,15 @@ SP_target_music(edict_t* self) self->use = target_music_use; } +/* + * QUAKED target_sky (1 0 0) (-8 -8 -8) (8 8 8) + * + * Change sky parameters + * - sky: Environment map name + * - skyaxis: Vector axis for rotating sky + * - skyrotate: Speed of rotation (degrees/second) + * - skyautorotate: Disable to set sky rotation manually + */ void target_sky_use(edict_t *self, edict_t *other, edict_t *activator) { diff --git a/src/game/g_trigger.c b/src/game/g_trigger.c index 6b4663e1..9fdab432 100644 --- a/src/game/g_trigger.c +++ b/src/game/g_trigger.c @@ -1124,3 +1124,33 @@ SP_trigger_monsterjump(edict_t *self) self->touch = trigger_monsterjump_touch; self->movedir[2] = st.height; } + +/* + * QUAKED choose_cdtrack (.5 .5 .5) ? + * Sets CD track + * + * style: CD Track Id + */ +void +choose_cdtrack_touch(edict_t *self, edict_t *other, cplane_t *plane /* unused */, + csurface_t *surf /* unused */) +{ + if (!self) + { + return; + } + + gi.configstring(CS_CDTRACK, va("%i", self->style)); +} + +void +SP_choose_cdtrack(edict_t *self) +{ + if (!self) + { + return; + } + + InitTrigger(self); + self->touch = choose_cdtrack_touch; +} diff --git a/src/game/savegame/tables/gamefunc_decs.h b/src/game/savegame/tables/gamefunc_decs.h index 205810c3..e6e0e7da 100644 --- a/src/game/savegame/tables/gamefunc_decs.h +++ b/src/game/savegame/tables/gamefunc_decs.h @@ -560,6 +560,7 @@ extern void chick_sight ( edict_t * self , edict_t * other ) ; extern void chick_slash ( edict_t * self ) ; extern void chick_stand ( edict_t * self ) ; extern void chick_walk ( edict_t * self ) ; +extern void choose_cdtrack_touch ( edict_t * ent , edict_t * other , cplane_t * plane , csurface_t * surf ) ; extern void cleanupHeal ( edict_t * ent, qboolean change_frame ) ; extern void cleanupHealTarget ( edict_t * ent ) ; extern void commander_body_die ( edict_t * self , edict_t * inflictor , edict_t * attacker , int damage , vec3_t point ) ; @@ -617,7 +618,7 @@ extern void drawbbox ( edict_t * self ) ; extern void drop_make_touchable ( edict_t * ent ) ; extern void drop_temp_touch ( edict_t * ent , edict_t * other , cplane_t * plane , csurface_t * surf ) ; extern void droptofloor ( edict_t * ent ) ; -extern void dynamicspawn_touch(edict_t *self, edict_t *other, cplane_t *plane /* unused */, csurface_t *surf /* unused */); +extern void dynamicspawn_touch ( edict_t * ent , edict_t * other , cplane_t * plane , csurface_t * surf ) ; extern void enfbolt_touch ( edict_t * self , edict_t * other , cplane_t * plane, csurface_t *surf); extern void enforcer_attack ( edict_t * self ) ; extern void enforcer_die ( edict_t * self , edict_t * inflictor , edict_t * attacker , int damage , vec3_t point ) ; diff --git a/src/game/savegame/tables/gamefunc_list.h b/src/game/savegame/tables/gamefunc_list.h index 12d347aa..e8ea8133 100644 --- a/src/game/savegame/tables/gamefunc_list.h +++ b/src/game/savegame/tables/gamefunc_list.h @@ -522,6 +522,7 @@ {"chick_slash", (byte *)chick_slash}, {"chick_stand", (byte *)chick_stand}, {"chick_walk", (byte *)chick_walk}, +{"choose_cdtrack_touch", (byte *)choose_cdtrack_touch}, {"cleanupHeal", (byte *)cleanupHeal}, {"cleanupHealTarget", (byte *)cleanupHealTarget}, {"commander_body_die", (byte *)commander_body_die}, diff --git a/src/game/savegame/tables/spawnfunc_decs.h b/src/game/savegame/tables/spawnfunc_decs.h index 4981a760..adef8e0e 100644 --- a/src/game/savegame/tables/spawnfunc_decs.h +++ b/src/game/savegame/tables/spawnfunc_decs.h @@ -29,6 +29,7 @@ extern void SP_CreateCoopSpots(edict_t * self); extern void SP_CreateUnnamedSpawn(edict_t * self); extern void SP_FixCoopSpots(edict_t * self); +extern void SP_choose_cdtrack(edict_t *self); extern void SP_dm_dball_ball(edict_t * self); extern void SP_dm_dball_ball_start(edict_t * self); extern void SP_dm_dball_goal(edict_t * self); diff --git a/src/game/savegame/tables/spawnfunc_list.h b/src/game/savegame/tables/spawnfunc_list.h index d1e08128..8c30c04f 100644 --- a/src/game/savegame/tables/spawnfunc_list.h +++ b/src/game/savegame/tables/spawnfunc_list.h @@ -28,6 +28,7 @@ {"ammo_magslug", SP_xatrix_item}, {"ammo_trap", SP_xatrix_item}, +{"choose_cdtrack", SP_choose_cdtrack}, {"dm_dball_ball", SP_dm_dball_ball}, {"dm_dball_ball_start", SP_dm_dball_ball_start}, {"dm_dball_goal", SP_dm_dball_goal}, diff --git a/stuff/models/entity.dat b/stuff/models/entity.dat index 5006ef01..27b833b7 100644 --- a/stuff/models/entity.dat +++ b/stuff/models/entity.dat @@ -600,7 +600,7 @@ character_siernan2|models/monsters/siernan/laying/tris.fm|1.0|1.0|1.0|general|-1 character_ssithra_scout|models/monsters/ssithra/scout_scene/tris.fm|1.0|1.0|1.0|general|-26.0|-16.0|-13.0|26.0|16.0|13.0|shadow|0|0.0|0.0|0|0|0|0:0|0|0|none|Ssithra scout|0.3|0.3|1.0 character_ssithra_victim|models/monsters/Ssithra/cinematics/tris.fm|1.0|1.0|1.0|general|-40.0|-16.0|-2.0|40.0|16.0|2.0|shadow|0|0.0|0.0|0|0|0|0:0|0|0|none|Ssithra torture victim|0.3|0.3|1.0 character_tome|models/spells/book/tris.fm|1.0|1.0|1.0|general|-4.0|-8.0|-12.0|4.0|8.0|12.0|shadow|0|0.0|0.0|0|0|0|0:0|0|0|none|Tome of Power|0.3|0.3|1.0 -choose_CDTrack||1.0|1.0|1.0|general|0.0|0.0|0.0|0.0|0.0|0.0|shadow|0|0.0|0.0|0|0|0|0:0|0|0|none|Sets CD track|.5|.5|.5 +choose_cdtrack||1.0|1.0|1.0|general|0.0|0.0|0.0|0.0|0.0|0.0|shadow|0|0.0|0.0|0|0|0|0:0|0|0|none|Sets CD track|.5|.5|.5 env_bubbler||1.0|1.0|1.0|general|-8.0|-8.0|-8.0|8.0|8.0|8.0|shadow|0|0.0|0.0|0|0|0|0:0|0|0|none|Bubbler|0.3|0.3|1.0 env_dust||1.0|1.0|1.0|general|-8.0|-8.0|-8.0|8.0|8.0|8.0|shadow|0|0.0|0.0|0|0|0|0:0|0|0|none|Dust (triggered)|0.3|0.3|1.0 env_fire||1.0|1.0|1.0|general|-8.0|-8.0|-8.0|8.0|8.0|8.0|shadow|0|0.0|0.0|0|0|0|0:0|0|0|none|Flame effect. Does not emit light|0.3|0.3|1.0 From af51dfbed4c4d5448e52bebaa408f76d1cc6105a Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Mon, 4 Nov 2024 23:56:19 +0200 Subject: [PATCH 08/19] Add mention about Q2Game.kpf for localization Fixes: #32 --- README.md | 4 +- doc/090_filelists.md | 234 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 236 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 671a08e4..6519bf2e 100644 --- a/README.md +++ b/README.md @@ -13,15 +13,15 @@ Saves format is unstabled and could change between alpha releases. State: +* Localization requires `Q2Game.kpf` file in root directory of game, * GL1/GLES3/GL3/GL4/VK: * base1: no known issues, * base2: no known issues, - * q64/outpost: broken level change, * mguhub: sometimes broken logic for surface fall in next maps. * SOFT: * base1: broken wall light and wall glitch, * base2: broken wall light and wall glitch, - * q64/outpost: broken level change, scale textures unsupported, + * q64/outpost: scale textures unsupported, * mguhub: broken wall light, sometimes broken logic for surface fall in next maps. diff --git a/doc/090_filelists.md b/doc/090_filelists.md index eae376b1..a1ed09b6 100644 --- a/doc/090_filelists.md +++ b/doc/090_filelists.md @@ -35,6 +35,8 @@ level. /ref_gl1.dll /ref_gl3.dll /ref_gles3.dll +/ref_gl4.dll +/ref_vk.dll /ref_soft.dll # The Executables: @@ -391,6 +393,238 @@ level. ``` +# Remaster + +Remaster does not requires files from original release. In game directory +should be placed only files provided with rerelease. + +``` +/baseq2/music/D_DDTBLU.ogg +/baseq2/music/track02.ogg +/baseq2/music/track03.ogg +/baseq2/music/track04.ogg +/baseq2/music/track05.ogg +/baseq2/music/track06.ogg +/baseq2/music/track07.ogg +/baseq2/music/track08.ogg +/baseq2/music/track09.ogg +/baseq2/music/track10.ogg +/baseq2/music/track11.ogg +/baseq2/music/track12.ogg +/baseq2/music/track13.ogg +/baseq2/music/track14.ogg +/baseq2/music/track15.ogg +/baseq2/music/track16.ogg +/baseq2/music/track17.ogg +/baseq2/music/track18.ogg +/baseq2/music/track19.ogg +/baseq2/music/track20.ogg +/baseq2/music/track21.ogg +/baseq2/music/track64.ogg +/baseq2/music/track65.ogg +/baseq2/music/track66.ogg +/baseq2/music/track67.ogg +/baseq2/music/track68.ogg +/baseq2/music/track69.ogg +/baseq2/music/track70.ogg +/baseq2/music/track71.ogg +/baseq2/music/track72.ogg +/baseq2/music/track73.ogg +/baseq2/music/track74.ogg +/baseq2/music/track75.ogg +/baseq2/music/track76.ogg +/baseq2/music/track77.ogg +/baseq2/music/track78.ogg +/baseq2/music/track79.ogg +/baseq2/video/ects.ogv +/baseq2/video/end_de.srt +/baseq2/video/end_es.srt +/baseq2/video/end_fr.srt +/baseq2/video/end_it.srt +/baseq2/video/end.ogv +/baseq2/video/end_ru.srt +/baseq2/video/end.srt +/baseq2/video/eou1__de.srt +/baseq2/video/eou1__es.srt +/baseq2/video/eou1__fr.srt +/baseq2/video/eou1__it.srt +/baseq2/video/eou1_.ogv +/baseq2/video/eou1__ru.srt +/baseq2/video/eou1_.srt +/baseq2/video/eou2__de.srt +/baseq2/video/eou2__es.srt +/baseq2/video/eou2__fr.srt +/baseq2/video/eou2__it.srt +/baseq2/video/eou2_.ogv +/baseq2/video/eou2__ru.srt +/baseq2/video/eou2_.srt +/baseq2/video/eou3__de.srt +/baseq2/video/eou3__es.srt +/baseq2/video/eou3__fr.srt +/baseq2/video/eou3__it.srt +/baseq2/video/eou3_.ogv +/baseq2/video/eou3__ru.srt +/baseq2/video/eou3_.srt +/baseq2/video/eou4__de.srt +/baseq2/video/eou4__es.srt +/baseq2/video/eou4__fr.srt +/baseq2/video/eou4__it.srt +/baseq2/video/eou4_.ogv +/baseq2/video/eou4__ru.srt +/baseq2/video/eou4_.srt +/baseq2/video/eou5__de.srt +/baseq2/video/eou5__es.srt +/baseq2/video/eou5__fr.srt +/baseq2/video/eou5__it.srt +/baseq2/video/eou5_.ogv +/baseq2/video/eou5__ru.srt +/baseq2/video/eou5_.srt +/baseq2/video/eou6__de.srt +/baseq2/video/eou6__es.srt +/baseq2/video/eou6__fr.srt +/baseq2/video/eou6__it.srt +/baseq2/video/eou6_.ogv +/baseq2/video/eou6__ru.srt +/baseq2/video/eou6_.srt +/baseq2/video/eou7__de.srt +/baseq2/video/eou7__es.srt +/baseq2/video/eou7__fr.srt +/baseq2/video/eou7__it.srt +/baseq2/video/eou7_.ogv +/baseq2/video/eou7__ru.srt +/baseq2/video/eou7_.srt +/baseq2/video/eou8__de.srt +/baseq2/video/eou8__es.srt +/baseq2/video/eou8__fr.srt +/baseq2/video/eou8__it.srt +/baseq2/video/eou8_.ogv +/baseq2/video/eou8__ru.srt +/baseq2/video/eou8_.srt +/baseq2/video/n64/n64l0t.ogv +/baseq2/video/n64/n64l10t.ogv +/baseq2/video/n64/n64l11t.ogv +/baseq2/video/n64/n64l12t.ogv +/baseq2/video/n64/n64l13t.ogv +/baseq2/video/n64/n64l14t.ogv +/baseq2/video/n64/n64l15t.ogv +/baseq2/video/n64/n64l16t.ogv +/baseq2/video/n64/n64l17t.ogv +/baseq2/video/n64/n64l18t.ogv +/baseq2/video/n64/n64l1t.ogv +/baseq2/video/n64/n64l2t.ogv +/baseq2/video/n64/n64l3t.ogv +/baseq2/video/n64/n64l4t.ogv +/baseq2/video/n64/n64l5t.ogv +/baseq2/video/n64/n64l6t.ogv +/baseq2/video/n64/n64l7t.ogv +/baseq2/video/n64/n64l8t.ogv +/baseq2/video/n64/n64l9t.ogv +/baseq2/video/ntro_de.srt +/baseq2/video/ntro_es.srt +/baseq2/video/ntro_fr.srt +/baseq2/video/ntro_it.srt +/baseq2/video/ntro.ogv +/baseq2/video/ntro_ru.srt +/baseq2/video/ntro.srt +/baseq2/video/rend_de.srt +/baseq2/video/rend_es.srt +/baseq2/video/rend_fr.srt +/baseq2/video/rend_it.srt +/baseq2/video/rend.ogv +/baseq2/video/rend_ru.srt +/baseq2/video/rend.srt +/baseq2/video/reu1__de.srt +/baseq2/video/reu1__es.srt +/baseq2/video/reu1__fr.srt +/baseq2/video/reu1__it.srt +/baseq2/video/reu1_.ogv +/baseq2/video/reu1__ru.srt +/baseq2/video/reu1_.srt +/baseq2/video/reu2__de.srt +/baseq2/video/reu2__es.srt +/baseq2/video/reu2__fr.srt +/baseq2/video/reu2__it.srt +/baseq2/video/reu2_.ogv +/baseq2/video/reu2__ru.srt +/baseq2/video/reu2_.srt +/baseq2/video/reu3__de.srt +/baseq2/video/reu3__es.srt +/baseq2/video/reu3__fr.srt +/baseq2/video/reu3__it.srt +/baseq2/video/reu3_.ogv +/baseq2/video/reu3__ru.srt +/baseq2/video/reu3_.srt +/baseq2/video/reu4__de.srt +/baseq2/video/reu4__es.srt +/baseq2/video/reu4__fr.srt +/baseq2/video/reu4__it.srt +/baseq2/video/reu4_.ogv +/baseq2/video/reu4__ru.srt +/baseq2/video/reu4_.srt +/baseq2/video/rintro_de.srt +/baseq2/video/rintro_es.srt +/baseq2/video/rintro_fr.srt +/baseq2/video/rintro_it.srt +/baseq2/video/rintro.ogv +/baseq2/video/rintro_ru.srt +/baseq2/video/rintro.srt +/baseq2/video/xin_de.srt +/baseq2/video/xin_es.srt +/baseq2/video/xin_fr.srt +/baseq2/video/xin_it.srt +/baseq2/video/xin.ogv +/baseq2/video/xin_ru.srt +/baseq2/video/xin.srt +/baseq2/video/xout_de.srt +/baseq2/video/xout_es.srt +/baseq2/video/xout_fr.srt +/baseq2/video/xout_it.srt +/baseq2/video/xout.ogv +/baseq2/video/xout_ru.srt +/baseq2/video/xout.srt +/baseq2/video/xu1_de.srt +/baseq2/video/xu1_es.srt +/baseq2/video/xu1_fr.srt +/baseq2/video/xu1_it.srt +/baseq2/video/xu1.ogv +/baseq2/video/xu1_ru.srt +/baseq2/video/xu1.srt +/baseq2/video/xu2_de.srt +/baseq2/video/xu2_es.srt +/baseq2/video/xu2_fr.srt +/baseq2/video/xu2_it.srt +/baseq2/video/xu2.ogv +/baseq2/video/xu2_ru.srt +/baseq2/video/xu2.srt +/baseq2/video/xu3_de.srt +/baseq2/video/xu3_es.srt +/baseq2/video/xu3_fr.srt +/baseq2/video/xu3_it.srt +/baseq2/video/xu3.ogv +/baseq2/video/xu3_ru.srt +/baseq2/video/xu3.srt +/baseq2/video/xu4_de.srt +/baseq2/video/xu4_es.srt +/baseq2/video/xu4_fr.srt +/baseq2/video/xu4_it.srt +/baseq2/video/xu4.ogv +/baseq2/video/xu4_ru.srt +/baseq2/video/xu4.srt +/baseq2/pak0.pak +/Q2Game.kpf +``` + +Additionally could be added files from [PSX](https://www.moddb.com/mods/quake-ii-psx) + +``` +/psx/pak0.pak +/psx/video/psx/boss.ogv +/psx/video/psx/command.ogv +/psx/video/psx/intro.ogv +/psx/video/psx/jail.ogv +/psx/video/psx/power.ogv +``` + ## Checksums From 03cb2be1e63e7ad582a50e1046c3c03f998d9a5d Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Tue, 5 Nov 2024 23:34:01 +0200 Subject: [PATCH 09/19] game: add 'g_language' localization cvar --- README.md | 2 +- doc/040_cvarlist.md | 4 ++++ src/game/g_main.c | 1 + src/game/g_translate.c | 4 +++- src/game/header/local.h | 1 + src/game/savegame/savegame.c | 1 + 6 files changed, 11 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6519bf2e..d2fdc3b8 100644 --- a/README.md +++ b/README.md @@ -79,7 +79,7 @@ Maps support: Note: -* Non Quake 2 maps are limmited mostly view only, and could have issues +* Non Quake 2 maps are limited mostly view only, and could have issues with tranparency or some animations flags and properties. * If you like support some other maps type, create pull request for Mod_Load2QBSP function and provide a link to demo maps. diff --git a/doc/040_cvarlist.md b/doc/040_cvarlist.md index d70c5c2e..4fb735c5 100644 --- a/doc/040_cvarlist.md +++ b/doc/040_cvarlist.md @@ -249,6 +249,10 @@ it's `+set busywait 0` (setting the `busywait` cvar) and `-portable` By default this cvar is set to `1`, and will only work if the game.dll implements this behaviour. +* **g_language**: Default language for ReRelease game, requires `Q2Game.kpf` + or other source of `localization/loc_english.txt` like file. + Defaults to `english`. + * **g_swap_speed**: Sets the speed of the "changing weapon" animation. Default is `1`. If set to `2`, it will be double the speed, `3` is the triple... up until the max of `8`, since there are at least 2 diff --git a/src/game/g_main.c b/src/game/g_main.c index 8ed7c994..d3cab5ce 100644 --- a/src/game/g_main.c +++ b/src/game/g_main.c @@ -102,6 +102,7 @@ cvar_t *aimfix; cvar_t *g_machinegun_norecoil; cvar_t *g_quick_weap; cvar_t *g_swap_speed; +cvar_t *g_language; static void G_RunFrame(void); diff --git a/src/game/g_translate.c b/src/game/g_translate.c index 37d2a8a2..f06a87ed 100644 --- a/src/game/g_translate.c +++ b/src/game/g_translate.c @@ -53,12 +53,14 @@ LocalizationInit(void) byte *raw = NULL; char *buf_local = NULL, *buf_level = NULL; int len_local, len_level, curr_pos; + char loc_name[MAX_QPATH]; localmessages = NULL; nlocalmessages = 0; + snprintf(loc_name, sizeof(loc_name) - 1, "localization/loc_%s.txt", g_language->string); /* load the localization file */ - len_local = gi.FS_LoadFile("localization/loc_english.txt", (void **)&raw); + len_local = gi.FS_LoadFile(loc_name, (void **)&raw); if (len_local > 1) { buf_local = malloc(len_local + 1); diff --git a/src/game/header/local.h b/src/game/header/local.h index b0134bb3..acdedb0f 100644 --- a/src/game/header/local.h +++ b/src/game/header/local.h @@ -679,6 +679,7 @@ extern cvar_t *aimfix; extern cvar_t *g_machinegun_norecoil; extern cvar_t *g_quick_weap; extern cvar_t *g_swap_speed; +extern cvar_t *g_language; /* this is for the count of monsters */ #define ENT_SLOTS_LEFT \ diff --git a/src/game/savegame/savegame.c b/src/game/savegame/savegame.c index e4208c5c..ab295732 100644 --- a/src/game/savegame/savegame.c +++ b/src/game/savegame/savegame.c @@ -263,6 +263,7 @@ InitGame(void) g_machinegun_norecoil = gi.cvar("g_machinegun_norecoil", "0", CVAR_ARCHIVE); g_quick_weap = gi.cvar("g_quick_weap", "1", CVAR_ARCHIVE); g_swap_speed = gi.cvar("g_swap_speed", "1", CVAR_ARCHIVE); + g_language = gi.cvar("g_language", "english", CVAR_ARCHIVE); /* initilize localization */ LocalizationInit(); From 6fd9e0ecc4d60af5d3b2676a0c1a5f99194de430 Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Thu, 7 Nov 2024 00:01:52 +0200 Subject: [PATCH 10/19] game: code style --- src/game/g_target.c | 2 +- src/game/monster/actor/actor.c | 24 ++++++++++++------------ src/game/monster/boss3/boss32.c | 4 ++-- src/game/monster/dog/dog.c | 2 +- src/game/monster/shalrath/shalrath.c | 2 +- src/game/monster/shambler/shambler.c | 4 ++-- src/game/monster/tank/tank.c | 4 ++-- src/game/monster/tarbaby/tarbaby.c | 2 +- src/game/monster/wizard/wizard.c | 2 +- src/game/player/chase.c | 2 +- src/game/player/view.c | 2 +- src/game/player/weapon.c | 4 ++-- 12 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/game/g_target.c b/src/game/g_target.c index ec5effaf..68739e23 100644 --- a/src/game/g_target.c +++ b/src/game/g_target.c @@ -672,7 +672,7 @@ SP_target_spawner(edict_t *self) if (!Q_stricmp(level.mapname, "fact2") && VectorCompare(self->s.origin, fact2spawnpoint1) ) { - VectorSet (forward, 0, 0, 1); + VectorSet(forward, 0, 0, 1); VectorMA (self->s.origin, -8, forward, self->s.origin); } diff --git a/src/game/monster/actor/actor.c b/src/game/monster/actor/actor.c index 579bd031..fef54b37 100644 --- a/src/game/monster/actor/actor.c +++ b/src/game/monster/actor/actor.c @@ -314,7 +314,7 @@ void actorMachineGun (edict_t *self) vec3_t start, target; vec3_t forward, right; - AngleVectors (self->s.angles, forward, right, NULL); + AngleVectors(self->s.angles, forward, right, NULL); G_ProjectSource (self->s.origin, monster_flash_offset[MZ2_ACTOR_MACHINEGUN_1], forward, right, start); if (self->enemy) { @@ -325,7 +325,7 @@ void actorMachineGun (edict_t *self) } else { - VectorCopy (self->enemy->absmin, target); + VectorCopy(self->enemy->absmin, target); target[2] += (self->enemy->size[2] / 2); } VectorSubtract (target, start, forward); @@ -333,7 +333,7 @@ void actorMachineGun (edict_t *self) } else { - AngleVectors (self->s.angles, forward, NULL, NULL); + AngleVectors(self->s.angles, forward, NULL, NULL); } monster_fire_bullet (self, start, forward, 3, 4, DEFAULT_BULLET_HSPREAD, DEFAULT_BULLET_VSPREAD, MZ2_ACTOR_MACHINEGUN_1); } @@ -341,12 +341,12 @@ void actorMachineGun (edict_t *self) void actor_dead (edict_t *self) { - VectorSet (self->mins, -16, -16, -24); - VectorSet (self->maxs, 16, 16, -8); + VectorSet(self->mins, -16, -16, -24); + VectorSet(self->maxs, 16, 16, -8); self->movetype = MOVETYPE_TOSS; self->svflags |= SVF_DEADMONSTER; self->nextthink = 0; - gi.linkentity (self); + gi.linkentity(self); } static mframe_t actor_frames_death1 [] = @@ -506,8 +506,8 @@ void SP_misc_actor (edict_t *self) self->movetype = MOVETYPE_STEP; self->solid = SOLID_BBOX; self->s.modelindex = gi.modelindex("players/male/tris.md2"); - VectorSet (self->mins, -16, -16, -24); - VectorSet (self->maxs, 16, 16, 32); + VectorSet(self->mins, -16, -16, -24); + VectorSet(self->maxs, 16, 16, 32); if (!self->health) self->health = 100; @@ -525,7 +525,7 @@ void SP_misc_actor (edict_t *self) self->monsterinfo.aiflags |= AI_GOOD_GUY; - gi.linkentity (self); + gi.linkentity(self); self->monsterinfo.currentmove = &actor_move_stand; self->monsterinfo.scale = MODEL_SCALE; @@ -651,8 +651,8 @@ void SP_target_actor (edict_t *self) self->solid = SOLID_TRIGGER; self->touch = target_actor_touch; - VectorSet (self->mins, -8, -8, -8); - VectorSet (self->maxs, 8, 8, 8); + VectorSet(self->mins, -8, -8, -8); + VectorSet(self->maxs, 8, 8, 8); self->svflags = SVF_NOCLIENT; if (self->spawnflags & 1) @@ -667,5 +667,5 @@ void SP_target_actor (edict_t *self) self->movedir[2] = st.height; } - gi.linkentity (self); + gi.linkentity(self); } diff --git a/src/game/monster/boss3/boss32.c b/src/game/monster/boss3/boss32.c index e62026fa..2f56d279 100644 --- a/src/game/monster/boss3/boss32.c +++ b/src/game/monster/boss3/boss32.c @@ -871,7 +871,7 @@ makron_torso_origin(edict_t *self, edict_t *torso) tr = gi.trace(self->s.origin, torso->mins, torso->maxs, v, self, MASK_SOLID); - VectorCopy (tr.endpos, torso->s.origin); + VectorCopy(tr.endpos, torso->s.origin); } void @@ -1007,7 +1007,7 @@ makron_die(edict_t *self, edict_t *inflictor /* unused */, edict_t *attacker /* /* lower bbox since the torso is gone */ self->maxs[2] = 64; - gi.linkentity (self); + gi.linkentity(self); self->monsterinfo.currentmove = &makron_move_death2; } diff --git a/src/game/monster/dog/dog.c b/src/game/monster/dog/dog.c index 5e9e559a..05e8c146 100644 --- a/src/game/monster/dog/dog.c +++ b/src/game/monster/dog/dog.c @@ -122,7 +122,7 @@ dog_leap_step(edict_t *self) { vec3_t forward; - AngleVectors (self->s.angles, forward, NULL, NULL); + AngleVectors(self->s.angles, forward, NULL, NULL); self->s.origin[2] += 1; VectorScale(forward, 300, self->velocity); self->velocity[2] = 200; diff --git a/src/game/monster/shalrath/shalrath.c b/src/game/monster/shalrath/shalrath.c index 8de7f131..2f78715e 100644 --- a/src/game/monster/shalrath/shalrath.c +++ b/src/game/monster/shalrath/shalrath.c @@ -191,7 +191,7 @@ FireShalrathPod(edict_t *self) vec3_t vec; vec3_t offset = {16, 0, 16}; - AngleVectors (self->s.angles, forward, right, NULL); + AngleVectors(self->s.angles, forward, right, NULL); G_ProjectSource(self->s.origin, offset, forward, right, start); VectorCopy(self->enemy->s.origin, vec); vec[2] += self->enemy->viewheight; diff --git a/src/game/monster/shambler/shambler.c b/src/game/monster/shambler/shambler.c index fe1bbb9b..1b75ef70 100644 --- a/src/game/monster/shambler/shambler.c +++ b/src/game/monster/shambler/shambler.c @@ -710,8 +710,8 @@ SP_monster_shambler(edict_t* self) } self->s.modelindex = gi.modelindex("models/monsters/shambler/tris.md2"); - VectorSet (self->mins, -32, -32, -24); - VectorSet (self->maxs, 32, 32, 64); + VectorSet(self->mins, -32, -32, -24); + VectorSet(self->maxs, 32, 32, 64); self->movetype = MOVETYPE_STEP; self->solid = SOLID_BBOX; diff --git a/src/game/monster/tank/tank.c b/src/game/monster/tank/tank.c index 87c491d3..fbe61d51 100644 --- a/src/game/monster/tank/tank.c +++ b/src/game/monster/tank/tank.c @@ -539,11 +539,11 @@ TankRocket(edict_t *self) if (blindfire) { - VectorCopy (self->monsterinfo.blind_fire_target, target); + VectorCopy(self->monsterinfo.blind_fire_target, target); } else { - VectorCopy (self->enemy->s.origin, target); + VectorCopy(self->enemy->s.origin, target); } if (blindfire) diff --git a/src/game/monster/tarbaby/tarbaby.c b/src/game/monster/tarbaby/tarbaby.c index f40aed5f..91715ac4 100644 --- a/src/game/monster/tarbaby/tarbaby.c +++ b/src/game/monster/tarbaby/tarbaby.c @@ -145,7 +145,7 @@ tarbaby_jump_step(edict_t *self) self->movetype = MOVETYPE_BOUNCE; self->touch = tarbaby_touch; - AngleVectors (self->s.angles, forward, NULL, NULL); + AngleVectors(self->s.angles, forward, NULL, NULL); self->s.origin[2] += 1; VectorScale(forward, 600, self->velocity); self->velocity[2] = 200 + (random() * 150); diff --git a/src/game/monster/wizard/wizard.c b/src/game/monster/wizard/wizard.c index c9921e0f..686536ab 100644 --- a/src/game/monster/wizard/wizard.c +++ b/src/game/monster/wizard/wizard.c @@ -221,7 +221,7 @@ wizard_spit(edict_t *self) vec3_t vec; vec3_t offset = {0, 0, 30}; - AngleVectors (self->s.angles, forward, right, NULL); + AngleVectors(self->s.angles, forward, right, NULL); G_ProjectSource(self->s.origin, offset, forward, right, start); VectorCopy(self->enemy->s.origin, vec); vec[2] += self->enemy->viewheight; diff --git a/src/game/player/chase.c b/src/game/player/chase.c index 31031f44..0ed75785 100644 --- a/src/game/player/chase.c +++ b/src/game/player/chase.c @@ -321,7 +321,7 @@ CheckChasecam_Viewent(edict_t *ent) ent->client->oldplayer->flags = ent->flags; /* end Lazarus */ - gi.linkentity (ent->client->oldplayer); + gi.linkentity(ent->client->oldplayer); } } diff --git a/src/game/player/view.c b/src/game/player/view.c index 92d6838f..70a8a7d3 100644 --- a/src/game/player/view.c +++ b/src/game/player/view.c @@ -432,7 +432,7 @@ SV_CalcViewOffset(edict_t *ent) } else { - VectorSet (v, 0, 0, 0); + VectorSet(v, 0, 0, 0); if (ent->client->chasecam) { ent->client->ps.pmove.origin[0] = ent->client->chasecam->s.origin[0] * 8; diff --git a/src/game/player/weapon.c b/src/game/player/weapon.c index df5101ba..4019e50a 100644 --- a/src/game/player/weapon.c +++ b/src/game/player/weapon.c @@ -210,8 +210,8 @@ PlayerNoise_Spawn(edict_t *who, int type) noise->classname = "player_noise"; noise->spawnflags = type; - VectorSet (noise->mins, -8, -8, -8); - VectorSet (noise->maxs, 8, 8, 8); + VectorSet(noise->mins, -8, -8, -8); + VectorSet(noise->maxs, 8, 8, 8); noise->owner = who; noise->svflags = SVF_NOCLIENT; From c3638d6c9a67bef1f947121a3b384ca1dcda13fa Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Sun, 10 Nov 2024 22:26:12 +0200 Subject: [PATCH 11/19] renders: skip SURF_NODRAW surfaces Cheked with remaster psx/base0 map --- src/client/refresh/gl1/gl1_surf.c | 5 +++++ src/client/refresh/gl3/gl3_surf.c | 5 +++++ src/client/refresh/gl4/gl4_surf.c | 5 +++++ src/client/refresh/soft/sw_bsp.c | 6 ++++-- src/client/refresh/soft/sw_rast.c | 6 ++++++ src/client/refresh/vk/vk_surf.c | 5 +++++ 6 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/client/refresh/gl1/gl1_surf.c b/src/client/refresh/gl1/gl1_surf.c index 97809f9d..6437b253 100644 --- a/src/client/refresh/gl1/gl1_surf.c +++ b/src/client/refresh/gl1/gl1_surf.c @@ -1090,6 +1090,11 @@ R_RecursiveWorldNode(entity_t *currententity, mnode_t *node) r_alpha_surfaces = surf; r_alpha_surfaces->texinfo->image = R_TextureAnimation(currententity, surf->texinfo); } + else if (surf->texinfo->flags & SURF_NODRAW) + { + /* Surface should be skipped */ + continue; + } else { /* the polygon is visible, so add it to the texture sorted chain */ diff --git a/src/client/refresh/gl3/gl3_surf.c b/src/client/refresh/gl3/gl3_surf.c index 71c5ab23..4e602efe 100644 --- a/src/client/refresh/gl3/gl3_surf.c +++ b/src/client/refresh/gl3/gl3_surf.c @@ -729,6 +729,11 @@ RecursiveWorldNode(entity_t *currententity, mnode_t *node) gl3_alpha_surfaces = surf; gl3_alpha_surfaces->texinfo->image = R_TextureAnimation(currententity, surf->texinfo); } + else if (surf->texinfo->flags & SURF_NODRAW) + { + /* Surface should be skipped */ + continue; + } else { // calling RenderLightmappedPoly() here probably isn't optimal, rendering everything diff --git a/src/client/refresh/gl4/gl4_surf.c b/src/client/refresh/gl4/gl4_surf.c index 7e4904ed..618c1235 100644 --- a/src/client/refresh/gl4/gl4_surf.c +++ b/src/client/refresh/gl4/gl4_surf.c @@ -726,6 +726,11 @@ RecursiveWorldNode(entity_t *currententity, mnode_t *node) gl4_alpha_surfaces = surf; gl4_alpha_surfaces->texinfo->image = R_TextureAnimation(currententity, surf->texinfo); } + else if (surf->texinfo->flags & SURF_NODRAW) + { + /* Surface should be skipped */ + continue; + } else { // calling RenderLightmappedPoly() here probably isn't optimal, rendering everything diff --git a/src/client/refresh/soft/sw_bsp.c b/src/client/refresh/soft/sw_bsp.c index 901b148e..755dfebf 100644 --- a/src/client/refresh/soft/sw_bsp.c +++ b/src/client/refresh/soft/sw_bsp.c @@ -322,7 +322,7 @@ R_DrawSolidClippedSubmodelPolygons(entity_t *currententity, const model_t *curre numsurfaces = currentmodel->nummodelsurfaces; pedges = currentmodel->edges; - for (i=0 ; iflags & SURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) || ((psurf->flags & SURF_PLANEBACK) && (dot > BACKFACE_EPSILON))) + { continue; + } // FIXME: use bounding-box-based frustum clipping info? @@ -349,7 +351,7 @@ R_DrawSolidClippedSubmodelPolygons(entity_t *currententity, const model_t *curre pbedge = &bedges[numbedges]; numbedges += psurf->numedges; - for (j=0 ; jnumedges ; j++) + for (j = 0; j < psurf->numedges; j++) { int lindex; diff --git a/src/client/refresh/soft/sw_rast.c b/src/client/refresh/soft/sw_rast.c index 8ca67bce..24eb96dd 100644 --- a/src/client/refresh/soft/sw_rast.c +++ b/src/client/refresh/soft/sw_rast.c @@ -536,6 +536,12 @@ R_RenderFace (entity_t *currententity, const model_t *currentmodel, msurface_t * return; } + if (fa->texinfo->flags & SURF_NODRAW) + { + /* Surface should be skipped */ + return; + } + // sky surfaces encountered in the world will cause the // environment box surfaces to be emited if ( fa->texinfo->flags & SURF_SKY ) diff --git a/src/client/refresh/vk/vk_surf.c b/src/client/refresh/vk/vk_surf.c index 23332d1f..af9a7825 100644 --- a/src/client/refresh/vk/vk_surf.c +++ b/src/client/refresh/vk/vk_surf.c @@ -740,6 +740,11 @@ R_RecursiveWorldNode(entity_t *currententity, mnode_t *node) surf->texturechain = r_alpha_surfaces; r_alpha_surfaces = surf; } + else if (surf->texinfo->flags & SURF_NODRAW) + { + /* Surface should be skipped */ + continue; + } else { if (!(surf->flags & SURF_DRAWTURB) && !r_showtris->value) From a09cbe20bdb78c30b217d121d8e6d767be3e5aef Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Sun, 10 Nov 2024 22:26:47 +0200 Subject: [PATCH 12/19] maps: fix daikatana context flag convert --- src/common/header/flags.h | 8 ++++---- src/common/maps.c | 1 + 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/common/header/flags.h b/src/common/header/flags.h index 6a59da90..775146fa 100644 --- a/src/common/header/flags.h +++ b/src/common/header/flags.h @@ -196,7 +196,7 @@ static const int daikatana_flags[32] = { 0, /* 16: Mirror */ 0, /* 17: Holy Grond */ SURF_ALPHATEST, /* 18: Alphachan */ - 0, /* 19: Midtexture (Used together with Clear and Nodraw.) */ + SURF_ALPHATEST, /* 19: Midtexture (Used together with Clear and Nodraw.) */ 0, /* 20: Puddle */ 0, /* 21: Water Surge */ 0, /* 22: Big Water Surge */ @@ -214,15 +214,15 @@ static const int daikatana_flags[32] = { static const int daikatana_contents_flags[32] = { CONTENTS_SOLID, /* 0: Default for all brushes */ CONTENTS_WINDOW, /* 1: Brush is a window (not really used) */ - 0, /* 2: Unused by the Dk's engine? */ + CONTENTS_AUX, /* 2: Unused by the Dk's engine? */ CONTENTS_LAVA, /* 3: The brush is lava */ CONTENTS_SLIME, /* 4: The brush is slime */ CONTENTS_WATER, /* 5: The brush is water */ CONTENTS_MIST, /* 6: The brush is non-solid */ - 0, /* 7: clear */ + CONTENTS_SOLID, /* 7: clear */ 0, /* 8: notsolid */ 0, /* 9: noshoot */ - 0, /* 10: fog */ + CONTENTS_MIST, /* 10: fog */ 0, /* 11: nitro */ 0, /* 12: Unused */ 0, /* 13: Unused */ diff --git a/src/common/maps.c b/src/common/maps.c index 125b7678..77651bfd 100644 --- a/src/common/maps.c +++ b/src/common/maps.c @@ -68,6 +68,7 @@ Mod_LoadSurfConvertFlags(int flags, maptype_t maptype) case map_kingpin: convert = kingpin_flags; break; case map_anachronox: convert = anachronox_flags; break; case map_sin: convert = sin_flags; break; + case map_quake2: convert = quake2_flags; break; default: convert = NULL; break; } From 53e93824ca6ca590622d425303f281ecf334b918 Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Sun, 17 Nov 2024 14:58:30 +0200 Subject: [PATCH 13/19] protocol: CUSTOM_PLAYER_MODEL(MAX_MODELS - 1) as player model --- src/client/cl_entities.c | 4 ++-- src/client/cl_parse.c | 8 ++++++++ src/common/header/common.h | 3 +++ src/common/header/shared.h | 1 + src/common/movemsg.c | 20 ++++++++++++++++++-- src/game/player/client.c | 6 +++--- src/game/player/view.c | 6 +++--- src/game/player/weapon.c | 6 +++--- 8 files changed, 41 insertions(+), 13 deletions(-) diff --git a/src/client/cl_entities.c b/src/client/cl_entities.c index a2a48a20..d3cb1d98 100644 --- a/src/client/cl_entities.c +++ b/src/client/cl_entities.c @@ -156,7 +156,7 @@ CL_AddPacketEntities(frame_t *frame) else { /* set skin */ - if (s1->modelindex == 255) + if (s1->modelindex == CUSTOM_PLAYER_MODEL) { /* use custom player skin */ ent.skinnum = 0; @@ -381,7 +381,7 @@ CL_AddPacketEntities(frame_t *frame) /* duplicate for linked models */ if (s1->modelindex2) { - if (s1->modelindex2 == 255) + if (s1->modelindex2 == CUSTOM_PLAYER_MODEL) { /* custom weapon */ ci = &cl.clientinfo[s1->skinnum & 0xff]; diff --git a/src/client/cl_parse.c b/src/client/cl_parse.c index ae6efabe..0554e728 100644 --- a/src/client/cl_parse.c +++ b/src/client/cl_parse.c @@ -148,11 +148,19 @@ CL_ParseDelta(entity_state_t *from, entity_state_t *to, int number, int bits) if (bits & U_MODEL) { to->modelindex = MSG_ReadByte(&net_message); + if (to->modelindex == QII97_PLAYER_MODEL) + { + to->modelindex = CUSTOM_PLAYER_MODEL; + } } if (bits & U_MODEL2) { to->modelindex2 = MSG_ReadByte(&net_message); + if (to->modelindex2 == QII97_PLAYER_MODEL) + { + to->modelindex2 = CUSTOM_PLAYER_MODEL; + } } if (bits & U_MODEL3) diff --git a/src/common/header/common.h b/src/common/header/common.h index d59c7636..7438e82d 100644 --- a/src/common/header/common.h +++ b/src/common/header/common.h @@ -190,6 +190,9 @@ void Info_Print(char *s); /* Quake 2 Customized Network Release */ #define PROTOCOL_VERSION 2024 +/* Quake 2 originaly uses 255 as player model */ +#define QII97_PLAYER_MODEL 255 + #define IS_QII97_PROTOCOL(x) ( \ ((x) == PROTOCOL_RELEASE_VERSION) || \ ((x) == PROTOCOL_DEMO_VERSION) || \ diff --git a/src/common/header/shared.h b/src/common/header/shared.h index 472bebda..4bacad16 100644 --- a/src/common/header/shared.h +++ b/src/common/header/shared.h @@ -178,6 +178,7 @@ typedef unsigned char byte; #define MAX_IMAGES 256 #define MAX_ITEMS 256 #define MAX_GENERAL (MAX_CLIENTS * 2) /* general config strings */ +#define CUSTOM_PLAYER_MODEL (MAX_MODELS - 1) /* game print flags */ #define PRINT_LOW 0 /* pickup messages */ diff --git a/src/common/movemsg.c b/src/common/movemsg.c index d425b793..d7dcbc1e 100644 --- a/src/common/movemsg.c +++ b/src/common/movemsg.c @@ -650,12 +650,28 @@ MSG_WriteDeltaEntity(entity_state_t *from, { if (bits & U_MODEL) { - MSG_WriteByte(msg, to->modelindex); + int modelindex = to->modelindex; + + /* New protocol use 16 bit for model id, and custom player model + * id is different to old one, converty back */ + if (modelindex == CUSTOM_PLAYER_MODEL) + { + modelindex = QII97_PLAYER_MODEL; + } + MSG_WriteByte(msg, modelindex); } if (bits & U_MODEL2) { - MSG_WriteByte(msg, to->modelindex2); + int modelindex = to->modelindex2; + + /* New protocol use 16 bit for model id, and custom player model + * id is different to old one, converty back */ + if (modelindex == CUSTOM_PLAYER_MODEL) + { + modelindex = QII97_PLAYER_MODEL; + } + MSG_WriteByte(msg, modelindex); } if (bits & U_MODEL3) diff --git a/src/game/player/client.c b/src/game/player/client.c index a67e1566..07caa800 100644 --- a/src/game/player/client.c +++ b/src/game/player/client.c @@ -2265,8 +2265,8 @@ PutClientInServer(edict_t *ent) /* clear entity state values */ ent->s.effects = 0; ent->s.skinnum = ent - g_edicts - 1; - ent->s.modelindex = 255; /* will use the skin specified model */ - ent->s.modelindex2 = 255; /* custom gun model */ + ent->s.modelindex = CUSTOM_PLAYER_MODEL; /* will use the skin specified model */ + ent->s.modelindex2 = CUSTOM_PLAYER_MODEL; /* custom gun model */ /* sknum is player num and weapon number weapon number will be added in changeweapon */ @@ -2840,7 +2840,7 @@ ClientThink(edict_t *ent, usercmd_t *ucmd) { client->ps.pmove.pm_type = PM_SPECTATOR; } - else if (ent->s.modelindex != 255) + else if (ent->s.modelindex != CUSTOM_PLAYER_MODEL) { client->ps.pmove.pm_type = PM_GIB; } diff --git a/src/game/player/view.c b/src/game/player/view.c index 70a8a7d3..673f26a1 100644 --- a/src/game/player/view.c +++ b/src/game/player/view.c @@ -116,7 +116,7 @@ P_DamageFeedback(edict_t *player) } /* start a pain animation if still in the player model */ - if ((client->anim_priority < ANIM_PAIN) && (player->s.modelindex == 255)) + if ((client->anim_priority < ANIM_PAIN) && (player->s.modelindex == CUSTOM_PLAYER_MODEL)) { static int i; @@ -782,7 +782,7 @@ P_FallingDamage(edict_t *ent) return; } - if (ent->s.modelindex != 255) + if (ent->s.modelindex != CUSTOM_PLAYER_MODEL) { return; /* not in the player model */ } @@ -1333,7 +1333,7 @@ G_SetClientFrame(edict_t *ent) return; } - if (ent->s.modelindex != 255) + if (ent->s.modelindex != CUSTOM_PLAYER_MODEL) { return; /* not in the player model */ } diff --git a/src/game/player/weapon.c b/src/game/player/weapon.c index 4019e50a..c77c5491 100644 --- a/src/game/player/weapon.c +++ b/src/game/player/weapon.c @@ -477,7 +477,7 @@ ChangeWeapon(edict_t *ent) ent->client->machinegun_shots = 0; /* set visible model */ - if (ent->s.modelindex == 255) + if (ent->s.modelindex == CUSTOM_PLAYER_MODEL) { if (ent->client->pers.weapon) { @@ -847,7 +847,7 @@ Weapon_Generic2(edict_t *ent, int FRAME_ACTIVATE_LAST, int FRAME_FIRE_LAST, return; } - if (ent->deadflag || (ent->s.modelindex != 255)) /* VWep animations screw up corpses */ + if (ent->deadflag || (ent->s.modelindex != CUSTOM_PLAYER_MODEL)) /* VWep animations screw up corpses */ { return; } @@ -1125,7 +1125,7 @@ weapon_grenade_fire(edict_t *ent, qboolean held) ent->client->grenade_time = level.time + 1.0; - if (ent->deadflag || (ent->s.modelindex != 255)) /* VWep animations screw up corpses */ + if (ent->deadflag || (ent->s.modelindex != CUSTOM_PLAYER_MODEL)) /* VWep animations screw up corpses */ { return; } From 4981c8b9728ffcf5ef8ae6166544d6f7657f3a14 Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Sun, 17 Nov 2024 16:54:21 +0200 Subject: [PATCH 14/19] maps: use shared function to replace backslashes --- src/client/refresh/files/models.c | 26 +++++--------------------- src/client/refresh/gl1/gl1_image.c | 16 +++++++--------- src/client/refresh/gl3/gl3_image.c | 16 +++++++--------- src/client/refresh/gl3/gl3_sdl.c | 2 +- src/client/refresh/gl4/gl4_image.c | 17 ++++++++--------- src/client/refresh/soft/sw_image.c | 18 ++++++++---------- src/client/refresh/vk/vk_image.c | 18 ++++++++---------- src/common/filesystem.c | 19 ++----------------- src/common/header/shared.h | 3 +++ src/common/maps.c | 6 ++++++ src/common/shared/shared.c | 20 +++++++++++++++++--- 11 files changed, 72 insertions(+), 89 deletions(-) diff --git a/src/client/refresh/files/models.c b/src/client/refresh/files/models.c index edcaf666..f4b9f9f9 100644 --- a/src/client/refresh/files/models.c +++ b/src/client/refresh/files/models.c @@ -658,6 +658,9 @@ Mod_LoadFixImages(const char* mod_name, dmdx_t *pheader, qboolean internal) skin = (char *)pheader + pheader->ofs_skins + i * MAX_SKINNAME; skin[MAX_SKINNAME - 1] = 0; + /* fix skin backslash */ + Q_replacebackslash(skin); + R_Printf(PRINT_DEVELOPER, "%s: %s #%d: Should load %s '%s'\n", __func__, mod_name, i, internal ? "internal": "external", skin); } @@ -2895,8 +2898,6 @@ Mod_LoadModel_MDA_Text(const char *mod_name, char *curr_buff, /* found basemodel */ else if (!strcmp(token, "basemodel")) { - char *curr; - token = COM_Parse(&curr_buff); if (!token) { @@ -2904,15 +2905,7 @@ Mod_LoadModel_MDA_Text(const char *mod_name, char *curr_buff, } strncpy(base_model, token, sizeof(base_model) - 1); - curr = base_model; - while (*curr) - { - if (*curr == '\\') - { - *curr = '/'; - } - curr++; - } + Q_replacebackslash(base_model); if (base_skin[0]) { @@ -2924,7 +2917,6 @@ Mod_LoadModel_MDA_Text(const char *mod_name, char *curr_buff, else if (!strcmp(token, "map")) { char* token_end = NULL; - char *curr; token = COM_Parse(&curr_buff); if (!token) @@ -2946,15 +2938,7 @@ Mod_LoadModel_MDA_Text(const char *mod_name, char *curr_buff, strncpy(base_skin, token, sizeof(base_skin) - 1); - curr = base_skin; - while (*curr) - { - if (*curr == '\\') - { - *curr = '/'; - } - curr++; - } + Q_replacebackslash(base_skin); if (base_model[0]) { diff --git a/src/client/refresh/gl1/gl1_image.c b/src/client/refresh/gl1/gl1_image.c index 0ffd26c2..dd94fea6 100644 --- a/src/client/refresh/gl1/gl1_image.c +++ b/src/client/refresh/gl1/gl1_image.c @@ -1139,19 +1139,20 @@ R_LoadPic(const char *name, byte *pic, int width, int realwidth, * Finds or loads the given image or null */ image_t * -R_FindImage(const char *name, imagetype_t type) +R_FindImage(const char *originname, imagetype_t type) { + char namewe[256], name[256] = {0}; + const char* ext; image_t *image; int i, len; - char *ptr; - char namewe[256]; - const char* ext; - if (!name) + if (!originname) { return NULL; } + strncpy(name, originname, sizeof(name) - 1); + ext = COM_FileExtension(name); if(!ext[0]) { @@ -1171,10 +1172,7 @@ R_FindImage(const char *name, imagetype_t type) } /* fix backslashes */ - while ((ptr = strchr(name, '\\'))) - { - *ptr = '/'; - } + Q_replacebackslash(name); /* look for it */ for (i = 0, image = gltextures; i < numgltextures; i++, image++) diff --git a/src/client/refresh/gl3/gl3_image.c b/src/client/refresh/gl3/gl3_image.c index 7484556d..99772d41 100644 --- a/src/client/refresh/gl3/gl3_image.c +++ b/src/client/refresh/gl3/gl3_image.c @@ -609,19 +609,20 @@ GL3_LoadPic(char *name, byte *pic, int width, int realwidth, * Finds or loads the given image or NULL */ gl3image_t * -GL3_FindImage(const char *name, imagetype_t type) +GL3_FindImage(const char *originname, imagetype_t type) { + char namewe[256], name[256] = {0}; gl3image_t *image; - int i, len; - char *ptr; - char namewe[256]; const char* ext; + int i, len; - if (!name) + if (!originname) { return NULL; } + strncpy(name, originname, sizeof(name) - 1); + ext = COM_FileExtension(name); if(!ext[0]) { @@ -641,10 +642,7 @@ GL3_FindImage(const char *name, imagetype_t type) } /* fix backslashes */ - while ((ptr = strchr(name, '\\'))) - { - *ptr = '/'; - } + Q_replacebackslash(name); /* look for it */ for (i = 0, image = gl3textures; i < numgl3textures; i++, image++) diff --git a/src/client/refresh/gl3/gl3_sdl.c b/src/client/refresh/gl3/gl3_sdl.c index 16354abb..a8e06567 100644 --- a/src/client/refresh/gl3/gl3_sdl.c +++ b/src/client/refresh/gl3/gl3_sdl.c @@ -463,7 +463,7 @@ int GL3_InitContext(void* win) } // Window title - set here so we can display renderer name in it. - char title[40] = {0}; + char title[64] = {0}; #ifdef YQ2_GL3_GLES3 snprintf(title, sizeof(title), "Yamagi Quake II %s - OpenGL ES 3.0", YQ2VERSION); #else diff --git a/src/client/refresh/gl4/gl4_image.c b/src/client/refresh/gl4/gl4_image.c index e6ea1ec4..7c436c07 100644 --- a/src/client/refresh/gl4/gl4_image.c +++ b/src/client/refresh/gl4/gl4_image.c @@ -610,19 +610,21 @@ GL4_LoadPic(char *name, byte *pic, int width, int realwidth, * Finds or loads the given image or NULL */ gl4image_t * -GL4_FindImage(const char *name, imagetype_t type) +GL4_FindImage(const char *originname, imagetype_t type) { + char namewe[256], name[256] = {0}; gl4image_t *image; - int i, len; - char *ptr; - char namewe[256]; const char* ext; + int i, len; - if (!name) + if (!originname) { return NULL; } + strncpy(name, originname, sizeof(name) - 1); + + ext = COM_FileExtension(name); if(!ext[0]) { @@ -642,10 +644,7 @@ GL4_FindImage(const char *name, imagetype_t type) } /* fix backslashes */ - while ((ptr = strchr(name, '\\'))) - { - *ptr = '/'; - } + Q_replacebackslash(name); /* look for it */ for (i = 0, image = gl4textures; i < numgl4textures; i++, image++) diff --git a/src/client/refresh/soft/sw_image.c b/src/client/refresh/soft/sw_image.c index c4444857..3a684acd 100644 --- a/src/client/refresh/soft/sw_image.c +++ b/src/client/refresh/soft/sw_image.c @@ -548,19 +548,20 @@ Finds or loads the given image or NULL =============== */ image_t * -R_FindImage(const char *name, imagetype_t type) +R_FindImage(const char *originname, imagetype_t type) { - image_t *image; - int i, len; - char *ptr; - char namewe[256]; + char namewe[256], name[256] = {0}; const char* ext; + image_t *image; + int i, len; - if (!name) + if (!originname) { return NULL; } + strncpy(name, originname, sizeof(name) - 1); + /* just return white image if show lightmap only */ if ((type == it_wall || type == it_skin) && r_lightmap->value) { @@ -586,10 +587,7 @@ R_FindImage(const char *name, imagetype_t type) } /* fix backslashes */ - while ((ptr = strchr(name, '\\'))) - { - *ptr = '/'; - } + Q_replacebackslash(name); // look for it for (i=0, image=r_images ; i 0; s--) diff --git a/src/common/header/shared.h b/src/common/header/shared.h index 4bacad16..2ffcfc5b 100644 --- a/src/common/header/shared.h +++ b/src/common/header/shared.h @@ -343,6 +343,9 @@ void Q_strdel(char *s, size_t i, size_t n); size_t Q_strins(char *dest, const char *src, size_t i, size_t n); qboolean Q_strisnum(const char *s); +/* fix backslashes in path */ +void Q_replacebackslash(char *curr); + /* ============================================= */ /* Unicode wrappers that also make sure it's a regular file around fopen(). */ diff --git a/src/common/maps.c b/src/common/maps.c index 77651bfd..7f8f4ee2 100644 --- a/src/common/maps.c +++ b/src/common/maps.c @@ -284,6 +284,9 @@ Mod_Load2QBSP_IBSP_TEXINFO(byte *outbuf, dheader_t *outheader, strncpy(out->texture, in->texture, Q_min(sizeof(out->texture), sizeof(in->texture))); + /* Fix backslashes */ + Q_replacebackslash(out->texture); + out++; in++; } @@ -317,6 +320,9 @@ Mod_Load2QBSP_RBSP_TEXINFO(byte *outbuf, dheader_t *outheader, strncpy(out->texture, in->texture, Q_min(sizeof(out->texture), sizeof(in->texture))); + /* Fix backslashes */ + Q_replacebackslash(out->texture); + out++; in++; } diff --git a/src/common/shared/shared.c b/src/common/shared/shared.c index b7d6142f..712f21eb 100644 --- a/src/common/shared/shared.c +++ b/src/common/shared/shared.c @@ -581,9 +581,10 @@ double sqrt(double x); vec_t VectorLength(const vec3_t v) { - return sqrtf((v[0] * v[0]) + - (v[1] * v[1]) + - (v[2] * v[2])); + return sqrtf( + (v[0] * v[0]) + + (v[1] * v[1]) + + (v[2] * v[2])); } void @@ -1084,6 +1085,19 @@ Q_strcasecmp(const char *s1, const char *s2) return Q_strncasecmp(s1, s2, 99999); } +void +Q_replacebackslash(char *curr) +{ + while (*curr) + { + if (*curr == '\\') + { + *curr = '/'; + } + curr++; + } +} + void Com_sprintf(char *dest, int size, const char *fmt, ...) { From 3f4efa05a16943280b5d03c7eac736260180da0f Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Sun, 17 Nov 2024 18:32:27 +0200 Subject: [PATCH 15/19] models: ignore MDA tag before load --- README.md | 3 +++ src/client/refresh/files/models.c | 2 +- src/client/refresh/gl1/gl1_model.c | 15 +++++++++++++-- src/client/refresh/gl3/gl3_model.c | 15 +++++++++++++-- src/client/refresh/gl4/gl4_model.c | 15 +++++++++++++-- src/client/refresh/soft/sw_model.c | 15 +++++++++++++-- src/client/refresh/vk/vk_model.c | 15 +++++++++++++-- src/game/g_spawn.c | 9 +++++++++ 8 files changed, 78 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index d2fdc3b8..fc3b86bc 100644 --- a/README.md +++ b/README.md @@ -150,6 +150,9 @@ Goals: * [x] MDR model format from Star Trek: Voyager – Elite Force, * [x] MDA entity format from Anachronox, * [ ] CTC entity format from Anachronox, +* [ ] ATD texture format from Anachronox, +* [ ] MDA model skin selection by tag, +* [ ] SDEF/MDA dynamicaly allocate list of skins, * [ ] Support material load textures/textureinfo.dat from Anachronox, * [ ] Support textures/*/*.mat load from ReRelease, * [ ] Support textures/*/*_glow.png load from ReRelease, diff --git a/src/client/refresh/files/models.c b/src/client/refresh/files/models.c index f4b9f9f9..6ed6f7d2 100644 --- a/src/client/refresh/files/models.c +++ b/src/client/refresh/files/models.c @@ -3181,7 +3181,7 @@ Mod_LoadMinMaxUpdate(const char *mod_name, vec3_t mins, vec3_t maxs, void *extra /* ================= -Mod_LoadModel +Mod_LoadModelFile ================= */ static void * diff --git a/src/client/refresh/gl1/gl1_model.c b/src/client/refresh/gl1/gl1_model.c index f7bc1a34..2f8f5d2c 100644 --- a/src/client/refresh/gl1/gl1_model.c +++ b/src/client/refresh/gl1/gl1_model.c @@ -397,9 +397,10 @@ Mod_ReadFile(const char *path, void **buffer) static model_t * Mod_ForName(const char *name, model_t *parent_model, qboolean crash) { + char filename[256] = {0}, *tag; + int i, modfilelen; model_t *mod; void *buf; - int i, modfilelen; if (!name[0]) { @@ -455,8 +456,18 @@ Mod_ForName(const char *name, model_t *parent_model, qboolean crash) strcpy(mod->name, name); + /* Anachronox has tags in model path*/ + strncpy(filename, name, sizeof(filename) - 1); + tag = strstr(filename, ".mda!"); + if (tag) + { + tag += 4; /* strlen(.mda) */ + *tag = 0; + tag ++; + } + /* load the file */ - modfilelen = ri.Mod_LoadFile(mod->name, &buf); + modfilelen = ri.Mod_LoadFile(filename, &buf); if (!buf) { diff --git a/src/client/refresh/gl3/gl3_model.c b/src/client/refresh/gl3/gl3_model.c index eb6b2560..83b1861a 100644 --- a/src/client/refresh/gl3/gl3_model.c +++ b/src/client/refresh/gl3/gl3_model.c @@ -398,9 +398,10 @@ Mod_ReadFile(const char *path, void **buffer) static gl3model_t * Mod_ForName(const char *name, gl3model_t *parent_model, qboolean crash) { + char filename[256] = {0}, *tag; + int i, modfilelen; gl3model_t *mod; void *buf; - int i, modfilelen; if (!name[0]) { @@ -456,8 +457,18 @@ Mod_ForName(const char *name, gl3model_t *parent_model, qboolean crash) strcpy(mod->name, name); + /* Anachronox has tags in model path*/ + strncpy(filename, name, sizeof(filename) - 1); + tag = strstr(filename, ".mda!"); + if (tag) + { + tag += 4; /* strlen(.mda) */ + *tag = 0; + tag ++; + } + /* load the file */ - modfilelen = ri.Mod_LoadFile(mod->name, &buf); + modfilelen = ri.Mod_LoadFile(filename, &buf); if (!buf) { diff --git a/src/client/refresh/gl4/gl4_model.c b/src/client/refresh/gl4/gl4_model.c index 5e06517a..495e5959 100644 --- a/src/client/refresh/gl4/gl4_model.c +++ b/src/client/refresh/gl4/gl4_model.c @@ -398,9 +398,10 @@ Mod_ReadFile(const char *path, void **buffer) static gl4model_t * Mod_ForName(const char *name, gl4model_t *parent_model, qboolean crash) { + char filename[256] = {0}, *tag; + int i, modfilelen; gl4model_t *mod; void *buf; - int i, modfilelen; if (!name[0]) { @@ -456,8 +457,18 @@ Mod_ForName(const char *name, gl4model_t *parent_model, qboolean crash) strcpy(mod->name, name); + /* Anachronox has tags in model path*/ + strncpy(filename, name, sizeof(filename) - 1); + tag = strstr(filename, ".mda!"); + if (tag) + { + tag += 4; /* strlen(.mda) */ + *tag = 0; + tag ++; + } + /* load the file */ - modfilelen = ri.Mod_LoadFile(mod->name, &buf); + modfilelen = ri.Mod_LoadFile(filename, &buf); if (!buf) { diff --git a/src/client/refresh/soft/sw_model.c b/src/client/refresh/soft/sw_model.c index 8ce47c82..2795a64d 100644 --- a/src/client/refresh/soft/sw_model.c +++ b/src/client/refresh/soft/sw_model.c @@ -405,9 +405,10 @@ Mod_ReadFile(const char *path, void **buffer) static model_t * Mod_ForName(const char *name, model_t *parent_model, qboolean crash) { + char filename[256] = {0}, *tag; + int i, modfilelen; model_t *mod; void *buf; - int i, modfilelen; if (!name[0]) { @@ -463,8 +464,18 @@ Mod_ForName(const char *name, model_t *parent_model, qboolean crash) strcpy(mod->name, name); + /* Anachronox has tags in model path*/ + strncpy(filename, name, sizeof(filename) - 1); + tag = strstr(filename, ".mda!"); + if (tag) + { + tag += 4; /* strlen(.mda) */ + *tag = 0; + tag ++; + } + /* load the file */ - modfilelen = ri.Mod_LoadFile(mod->name, &buf); + modfilelen = ri.Mod_LoadFile(filename, &buf); if (!buf) { diff --git a/src/client/refresh/vk/vk_model.c b/src/client/refresh/vk/vk_model.c index e3f41acd..5ab96c4c 100644 --- a/src/client/refresh/vk/vk_model.c +++ b/src/client/refresh/vk/vk_model.c @@ -372,9 +372,10 @@ Mod_ReadFile(const char *path, void **buffer) static model_t * Mod_ForName(const char *name, model_t *parent_model, qboolean crash) { + char filename[256] = {0}, *tag; + int i, modfilelen; model_t *mod; void *buf; - int i, modfilelen; if (!name[0]) { @@ -430,8 +431,18 @@ Mod_ForName(const char *name, model_t *parent_model, qboolean crash) strcpy(mod->name, name); + /* Anachronox has tags in model path*/ + strncpy(filename, name, sizeof(filename) - 1); + tag = strstr(filename, ".mda!"); + if (tag) + { + tag += 4; /* strlen(.mda) */ + *tag = 0; + tag ++; + } + /* load the file */ - modfilelen = ri.Mod_LoadFile(mod->name, &buf); + modfilelen = ri.Mod_LoadFile(filename, &buf); if (!buf) { diff --git a/src/game/g_spawn.c b/src/game/g_spawn.c index 620c2e21..8e51c1ca 100644 --- a/src/game/g_spawn.c +++ b/src/game/g_spawn.c @@ -2164,6 +2164,11 @@ DynamicSpawnInit(void) * max attenuation */ + + /* Fix path */ + Q_replacebackslash(dynamicentities[curr_pos].model_path); + + /* go to next row */ curr_pos ++; } @@ -2231,6 +2236,10 @@ DynamicSpawnInit(void) /* Additional field for cover for color from QUAKED */ line = DynamicFloatParse(line, dynamicentities[curr_pos].color, 3, '|'); + /* Fix path */ + Q_replacebackslash(dynamicentities[curr_pos].model_path); + + /* go to next row */ curr_pos ++; } curr += linesize; From f856be35128fed954d5f900cb672ca7566f8abd2 Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Mon, 18 Nov 2024 00:43:15 +0200 Subject: [PATCH 16/19] game: Add scale entity field (without real usage) --- README.md | 2 +- src/common/header/shared.h | 1 + src/game/g_misc.c | 1 + src/game/g_spawn.c | 27 ++++++++++++++++++++++----- src/game/header/local.h | 5 +++++ src/game/savegame/tables/fields.h | 4 +++- 6 files changed, 33 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index fc3b86bc..9626b6eb 100644 --- a/README.md +++ b/README.md @@ -158,7 +158,7 @@ Goals: * [ ] Support textures/*/*_glow.png load from ReRelease, * [ ] Support tactile/*/*.bnvib/.wav feedback load from ReRelease, * [ ] Fix physics with incorrect floor height in psx/base0.bsp, -* [ ] Fix strange white flying boxes in psx/base0.bsp, +* [x] Fix strange white flying boxes in psx/base0.bsp, * [x] RGB particles support instead palette based one, * [x] Get rid of VID_PaletteColor client internal api use, * [x] Broken maps groups from base2 to next, diff --git a/src/common/header/shared.h b/src/common/header/shared.h index 2ffcfc5b..a71da662 100644 --- a/src/common/header/shared.h +++ b/src/common/header/shared.h @@ -1222,6 +1222,7 @@ typedef struct entity_state_s int event; /* impulse events -- muzzle flashes, footsteps, etc */ /* events only go out for a single frame, they */ /* are automatically cleared each frame */ + vec3_t scale; } entity_state_t; /* ============================================== */ diff --git a/src/game/g_misc.c b/src/game/g_misc.c index d1f86662..7b68e195 100644 --- a/src/game/g_misc.c +++ b/src/game/g_misc.c @@ -3336,6 +3336,7 @@ SP_misc_flare(edict_t* ent) ent->s.modelindex2 = st.fade_start_dist; ent->s.modelindex3 = st.fade_end_dist; + ent->s.skinnum = st.rgba; if (ent->targetname) { diff --git a/src/game/g_spawn.c b/src/game/g_spawn.c index 8e51c1ca..da8a0e0e 100644 --- a/src/game/g_spawn.c +++ b/src/game/g_spawn.c @@ -117,11 +117,27 @@ DynamicSpawnUpdate(edict_t *self, dynamicentity_t *data) VectorCopy(data->mins, self->mins); VectorCopy(data->maxs, self->maxs); - self->monsterinfo.scale = ( - data->scale[0] + - data->scale[1] + - data->scale[2] - ) / 3; + /* has updated scale */ + if (st.scale[0] || st.scale[1] || st.scale[2]) + { + /* copy to other parts if zero */ + if (!st.scale[1]) + { + st.scale[1] = st.scale[0]; + } + + if (!st.scale[2]) + { + st.scale[2] = st.scale[0]; + } + + /* Copy to entity scale field */ + VectorCopy(st.scale, self->s.scale); + } + else + { + VectorCopy(data->scale, self->s.scale); + } } void @@ -510,6 +526,7 @@ ED_ParseField(const char *key, const char *value, edict_t *ent) *(char **)(b + f->ofs) = ED_NewString(value, false); break; case F_VECTOR: + VectorClear(vec); sscanf(value, "%f %f %f", &vec[0], &vec[1], &vec[2]); ((float *)(b + f->ofs))[0] = vec[0]; ((float *)(b + f->ofs))[1] = vec[1]; diff --git a/src/game/header/local.h b/src/game/header/local.h index acdedb0f..998ad624 100644 --- a/src/game/header/local.h +++ b/src/game/header/local.h @@ -411,10 +411,15 @@ typedef struct float minpitch; float maxpitch; + /* misc_flare */ float radius; float fade_start_dist; float fade_end_dist; char *image; + unsigned rgba; + + /* Addional fields for models */ + vec3_t scale; } spawn_temp_t; typedef struct diff --git a/src/game/savegame/tables/fields.h b/src/game/savegame/tables/fields.h index 3a5cf336..a88da009 100644 --- a/src/game/savegame/tables/fields.h +++ b/src/game/savegame/tables/fields.h @@ -58,7 +58,9 @@ {"origin", FOFS(s.origin), F_VECTOR}, {"angles", FOFS(s.angles), F_VECTOR}, {"angle", FOFS(s.angles), F_ANGLEHACK}, -{"rgba", FOFS(s.skinnum), F_RGBA}, +{"rgb", STOFS(rgba), F_RGBA, FFL_SPAWNTEMP}, +{"rgba", STOFS(rgba), F_RGBA, FFL_SPAWNTEMP}, +{"scale", STOFS(scale), F_VECTOR, FFL_SPAWNTEMP}, {"radius", STOFS(radius), F_FLOAT, FFL_SPAWNTEMP}, {"fade_start_dist", STOFS(fade_start_dist), F_FLOAT, FFL_SPAWNTEMP}, {"fade_end_dist", STOFS(fade_end_dist), F_FLOAT, FFL_SPAWNTEMP}, From ddda42244d3d9f2568b7b966a739c56986e86713 Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Mon, 18 Nov 2024 00:53:10 +0200 Subject: [PATCH 17/19] gl4: Disable too bright FRAMEBUFFER_SRGB --- src/client/refresh/gl4/gl4_main.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/client/refresh/gl4/gl4_main.c b/src/client/refresh/gl4/gl4_main.c index 8c520d3d..629e52c5 100644 --- a/src/client/refresh/gl4/gl4_main.c +++ b/src/client/refresh/gl4/gl4_main.c @@ -1590,9 +1590,6 @@ GL4_RenderView(refdef_t *fd) GL4_DrawAlphaSurfaces(); - // simple gamma correction - glEnable(GL_FRAMEBUFFER_SRGB); - // Note: R_Flash() is now GL4_Draw_Flash() and called from GL4_RenderFrame() if (r_speeds->value) From 84fde2cfe700ae19c8fe6dabbb072765dead2111 Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Mon, 18 Nov 2024 01:17:13 +0200 Subject: [PATCH 18/19] initial scale --- src/client/cl_entities.c | 2 ++ src/client/cl_parse.c | 12 ++++++++++++ src/client/refresh/files/mesh.c | 16 +++++++++++----- src/client/refresh/gl1/gl1_mesh.c | 2 +- src/client/refresh/gl3/gl3_mesh.c | 6 ++++-- src/client/refresh/gl4/gl4_mesh.c | 6 ++++-- src/client/refresh/ref_shared.h | 2 +- src/client/refresh/soft/sw_alias.c | 2 +- src/client/refresh/vk/vk_main.c | 2 +- src/client/refresh/vk/vk_mesh.c | 2 +- src/client/vid/header/ref.h | 1 + src/common/cmodels.c | 1 + src/common/header/shared.h | 1 + src/common/movemsg.c | 15 +++++++++++++++ src/game/g_misc.c | 12 ++++++++---- 15 files changed, 64 insertions(+), 18 deletions(-) diff --git a/src/client/cl_entities.c b/src/client/cl_entities.c index d3cb1d98..555ce7fb 100644 --- a/src/client/cl_entities.c +++ b/src/client/cl_entities.c @@ -198,6 +198,8 @@ CL_AddPacketEntities(frame_t *frame) ent.skin = NULL; ent.model = cl.model_draw[s1->modelindex]; } + /* store scale */ + ent.scale = s1->scale[0]; } /* only used for black hole model right now */ diff --git a/src/client/cl_parse.c b/src/client/cl_parse.c index 0554e728..57c45452 100644 --- a/src/client/cl_parse.c +++ b/src/client/cl_parse.c @@ -143,6 +143,12 @@ CL_ParseDelta(entity_state_t *from, entity_state_t *to, int number, int bits) VectorCopy(from->origin, to->old_origin); to->number = number; + if (cls.serverProtocol != PROTOCOL_VERSION) + { + /* Always set scale to 1.0f for old clients */ + to->scale[0] = 1.0f; + } + if (IS_QII97_PROTOCOL(cls.serverProtocol)) { if (bits & U_MODEL) @@ -210,6 +216,12 @@ CL_ParseDelta(entity_state_t *from, entity_state_t *to, int number, int bits) if ((bits & U_SKIN8) && (bits & U_SKIN16)) { to->skinnum = MSG_ReadLong(&net_message); + /* Additional scale with skinnum */ + if (cls.serverProtocol == PROTOCOL_VERSION) + { + to->scale[0] = MSG_ReadFloat(&net_message); + printf("received scale %f\n", to->scale[0]); + } } else if (bits & U_SKIN8) { diff --git a/src/client/refresh/files/mesh.c b/src/client/refresh/files/mesh.c index e0a7eae0..4d8b0c1f 100644 --- a/src/client/refresh/files/mesh.c +++ b/src/client/refresh/files/mesh.c @@ -95,10 +95,16 @@ void R_LerpVerts(qboolean powerUpEffect, int nverts, const dxtrivertx_t *v, const dxtrivertx_t *ov, float *lerp, const float move[3], - const float frontv[3], const float backv[3]) + const float frontv[3], const float backv[3], float scale) { int i; + /* If scale is undefined, set scale 1.0f */ + if (!scale) + { + scale = 1.0f; + } + if (powerUpEffect) { for (i = 0; i < nverts; i++, v++, ov++, lerp += 4) @@ -111,7 +117,7 @@ R_LerpVerts(qboolean powerUpEffect, int nverts, normal = v->normal[n] / 127.f; - lerp[n] = move[n] + ov->v[n] * backv[n] + v->v[n] * frontv[n] + + lerp[n] = scale * (move[n] + ov->v[n] * backv[n] + v->v[n] * frontv[n]) + normal * POWERSUIT_SCALE; } } @@ -120,9 +126,9 @@ R_LerpVerts(qboolean powerUpEffect, int nverts, { for (i = 0; i < nverts; i++, v++, ov++, lerp += 4) { - lerp[0] = move[0] + ov->v[0] * backv[0] + v->v[0] * frontv[0]; - lerp[1] = move[1] + ov->v[1] * backv[1] + v->v[1] * frontv[1]; - lerp[2] = move[2] + ov->v[2] * backv[2] + v->v[2] * frontv[2]; + lerp[0] = scale * (move[0] + ov->v[0] * backv[0] + v->v[0] * frontv[0]); + lerp[1] = scale * (move[1] + ov->v[1] * backv[1] + v->v[1] * frontv[1]); + lerp[2] = scale * (move[2] + ov->v[2] * backv[2] + v->v[2] * frontv[2]); } } } diff --git a/src/client/refresh/gl1/gl1_mesh.c b/src/client/refresh/gl1/gl1_mesh.c index f39e53a8..b3f51ace 100644 --- a/src/client/refresh/gl1/gl1_mesh.c +++ b/src/client/refresh/gl1/gl1_mesh.c @@ -174,7 +174,7 @@ R_DrawAliasFrameLerp(entity_t *currententity, dmdx_t *paliashdr, float backlerp, lerp = s_lerped[0]; R_LerpVerts(colorOnly, paliashdr->num_xyz, verts, ov, lerp, - move, frontv, backv); + move, frontv, backv, currententity->scale); num_mesh_nodes = paliashdr->num_meshes; mesh_nodes = (dmdxmesh_t *)((char*)paliashdr + paliashdr->ofs_meshes); diff --git a/src/client/refresh/gl3/gl3_mesh.c b/src/client/refresh/gl3/gl3_mesh.c index fe690a02..6d0b4744 100644 --- a/src/client/refresh/gl3/gl3_mesh.c +++ b/src/client/refresh/gl3/gl3_mesh.c @@ -289,7 +289,8 @@ DrawAliasFrameLerp(dmdx_t *paliashdr, entity_t* entity, vec3_t shadelight, lerp = s_lerped[0]; - R_LerpVerts(colorOnly, paliashdr->num_xyz, verts, ov, lerp, move, frontv, backv); + R_LerpVerts(colorOnly, paliashdr->num_xyz, verts, ov, lerp, + move, frontv, backv, entity->scale); YQ2_STATIC_ASSERT(sizeof(gl3_alias_vtx_t) == 9 * sizeof(GLfloat), "invalid gl3_alias_vtx_t size"); @@ -469,7 +470,8 @@ DrawAliasShadow(gl3_shadowinfo_t* shadowInfo) // false: don't extrude vertices for powerup - this means the powerup shell // is not seen in the shadow, only the underlying model.. - R_LerpVerts(false, paliashdr->num_xyz, verts, ov, s_lerped[0], move, frontv, backv); + R_LerpVerts(false, paliashdr->num_xyz, verts, ov, s_lerped[0], + move, frontv, backv, entity->scale); } lheight = entity->origin[2] - shadowInfo->lightspot[2]; diff --git a/src/client/refresh/gl4/gl4_mesh.c b/src/client/refresh/gl4/gl4_mesh.c index cf302431..17577251 100644 --- a/src/client/refresh/gl4/gl4_mesh.c +++ b/src/client/refresh/gl4/gl4_mesh.c @@ -289,7 +289,8 @@ DrawAliasFrameLerp(dmdx_t *paliashdr, entity_t* entity, vec3_t shadelight, lerp = s_lerped[0]; - R_LerpVerts(colorOnly, paliashdr->num_xyz, verts, ov, lerp, move, frontv, backv); + R_LerpVerts(colorOnly, paliashdr->num_xyz, verts, ov, lerp, + move, frontv, backv, entity->scale); YQ2_STATIC_ASSERT(sizeof(gl4_alias_vtx_t) == 9 * sizeof(GLfloat), "invalid gl4_alias_vtx_t size"); @@ -469,7 +470,8 @@ DrawAliasShadow(gl4_shadowinfo_t* shadowInfo) // false: don't extrude vertices for powerup - this means the powerup shell // is not seen in the shadow, only the underlying model.. - R_LerpVerts(false, paliashdr->num_xyz, verts, ov, s_lerped[0], move, frontv, backv); + R_LerpVerts(false, paliashdr->num_xyz, verts, ov, s_lerped[0], + move, frontv, backv, entity->scale); } lheight = entity->origin[2] - shadowInfo->lightspot[2]; diff --git a/src/client/refresh/ref_shared.h b/src/client/refresh/ref_shared.h index dc09728e..a5edad3a 100644 --- a/src/client/refresh/ref_shared.h +++ b/src/client/refresh/ref_shared.h @@ -382,7 +382,7 @@ extern qboolean R_CullAliasMeshModel(dmdx_t *paliashdr, cplane_t *frustum, extern void R_LerpVerts(qboolean powerUpEffect, int nverts, const dxtrivertx_t *v, const dxtrivertx_t *ov, float *lerp, const float move[3], - const float frontv[3], const float backv[3]); + const float frontv[3], const float backv[3], float scale); extern void R_ConvertNormalMDL(byte in_normal, signed char *normal); extern vec4_t *R_VertBufferRealloc(int num); extern void R_VertBufferInit(void); diff --git a/src/client/refresh/soft/sw_alias.c b/src/client/refresh/soft/sw_alias.c index 32b74797..58fd22da 100644 --- a/src/client/refresh/soft/sw_alias.c +++ b/src/client/refresh/soft/sw_alias.c @@ -457,7 +457,7 @@ R_AliasPreparePoints(const entity_t *currententity, finalvert_t *verts, const fi RF_SHELL_HALF_DAM)); R_LerpVerts(colorOnly, s_pmdl->num_xyz, r_thisframe->verts, r_lastframe->verts, - s_lerped[0], r_lerp_move, r_lerp_frontv, r_lerp_backv); + s_lerped[0], r_lerp_move, r_lerp_frontv, r_lerp_backv, currententity->scale); R_AliasTransformFinalVerts(s_pmdl->num_xyz, verts, /* destination for transformed verts */ diff --git a/src/client/refresh/vk/vk_main.c b/src/client/refresh/vk/vk_main.c index b87aee21..4c82986f 100644 --- a/src/client/refresh/vk/vk_main.c +++ b/src/client/refresh/vk/vk_main.c @@ -979,7 +979,7 @@ RE_RenderView(refdef_t *fd) R_DrawAlphaSurfaces(); - R_Flash(); + R_Flash(); /* citadel error */ if (r_speeds->value) { diff --git a/src/client/refresh/vk/vk_mesh.c b/src/client/refresh/vk/vk_mesh.c index c0817e28..de92db8d 100644 --- a/src/client/refresh/vk/vk_mesh.c +++ b/src/client/refresh/vk/vk_mesh.c @@ -359,7 +359,7 @@ Vk_DrawAliasFrameLerp(entity_t *currententity, dmdx_t *paliashdr, float backlerp } R_LerpVerts(colorOnly, paliashdr->num_xyz, verts, ov, (float*)s_lerped, - move, frontv, backv); + move, frontv, backv, currententity->scale); VkDescriptorSet descriptorSets[] = { skin->vk_texture.descriptorSet, diff --git a/src/client/vid/header/ref.h b/src/client/vid/header/ref.h index 43e0c810..22a88c6f 100644 --- a/src/client/vid/header/ref.h +++ b/src/client/vid/header/ref.h @@ -68,6 +68,7 @@ typedef struct entity_s { /* misc */ float backlerp; /* 0.0 = current, 1.0 = old */ int skinnum; /* also used as RF_BEAM's palette index */ + float scale; int lightstyle; /* for flashing entities */ float alpha; /* ignore if RF_TRANSLUCENT isn't set */ diff --git a/src/common/cmodels.c b/src/common/cmodels.c index e235d0bd..0e87dfeb 100644 --- a/src/common/cmodels.c +++ b/src/common/cmodels.c @@ -69,6 +69,7 @@ Mod_LoadVisibility(const char *name, dvis_t **vis, int *numvisibility, if (!l->filelen) { + /* n64jam_chnuckierdbeer */ Com_Printf("%s: Map %s has too small visibility lump\n", __func__, name); *vis = NULL; diff --git a/src/common/header/shared.h b/src/common/header/shared.h index a71da662..14ee4322 100644 --- a/src/common/header/shared.h +++ b/src/common/header/shared.h @@ -1222,6 +1222,7 @@ typedef struct entity_state_s int event; /* impulse events -- muzzle flashes, footsteps, etc */ /* events only go out for a single frame, they */ /* are automatically cleared each frame */ + /* New protocol fields */ vec3_t scale; } entity_state_t; diff --git a/src/common/movemsg.c b/src/common/movemsg.c index d7dcbc1e..a1ee4db8 100644 --- a/src/common/movemsg.c +++ b/src/common/movemsg.c @@ -505,6 +505,13 @@ MSG_WriteDeltaEntity(entity_state_t *from, } } + /* Scale with skins if force or different */ + if ((protocol == PROTOCOL_VERSION) && + ((to->scale != from->scale) || force)) + { + bits |= (U_SKIN8 | U_SKIN16); + } + if (to->frame != from->frame) { if (to->frame < 256) @@ -720,6 +727,14 @@ MSG_WriteDeltaEntity(entity_state_t *from, if ((bits & U_SKIN8) && (bits & U_SKIN16)) /*used for laser colors */ { MSG_WriteLong(msg, to->skinnum); + + /* Send scale */ + if (protocol == PROTOCOL_VERSION) + { + to->scale[0] = 1.5f; + MSG_WriteFloat(msg, to->scale[0]); + printf("send scale %f\n", to->scale[0]); + } } else if (bits & U_SKIN8) diff --git a/src/game/g_misc.c b/src/game/g_misc.c index 7b68e195..95abdcdf 100644 --- a/src/game/g_misc.c +++ b/src/game/g_misc.c @@ -3297,13 +3297,17 @@ misc_flare_use(edict_t *ent, edict_t *other, edict_t *activator) void SP_misc_flare(edict_t* ent) { + int i; + ent->s.modelindex = 0; ent->s.renderfx = RF_FLARE; ent->solid = SOLID_NOT; - /* - * TODO: Add scale field - * ent->s.scale = st.radius; - */ + + /* Radius saved to scale */ + for (i = 0; i < 3; i++) + { + ent->s.scale[i] = st.radius; + } if (ent->spawnflags & SPAWNFLAG_FLARE_RED) { From 129b6ea7f40e28f3a0f06be3c355d45f4eb08b10 Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Tue, 19 Nov 2024 00:02:51 +0200 Subject: [PATCH 19/19] broken scale --- src/client/cl_entities.c | 3 ++- src/client/cl_parse.c | 18 +++++++++++++++--- src/client/refresh/files/mesh.c | 25 ++++++++++++++++--------- src/client/refresh/gl1/gl1_mesh.c | 9 +++++++++ src/client/refresh/gl3/gl3_mesh.c | 9 +++++++++ src/client/refresh/gl4/gl4_mesh.c | 9 +++++++++ src/client/refresh/ref_shared.h | 2 +- src/client/refresh/soft/sw_alias.c | 17 +++++++++++++++-- src/client/refresh/vk/vk_mesh.c | 9 +++++++++ src/client/vid/header/ref.h | 2 +- src/common/movemsg.c | 12 +++++++++--- 11 files changed, 95 insertions(+), 20 deletions(-) diff --git a/src/client/cl_entities.c b/src/client/cl_entities.c index 555ce7fb..a0e41c8f 100644 --- a/src/client/cl_entities.c +++ b/src/client/cl_entities.c @@ -198,8 +198,9 @@ CL_AddPacketEntities(frame_t *frame) ent.skin = NULL; ent.model = cl.model_draw[s1->modelindex]; } + /* store scale */ - ent.scale = s1->scale[0]; + VectorCopy(s1->scale, ent.scale); } /* only used for black hole model right now */ diff --git a/src/client/cl_parse.c b/src/client/cl_parse.c index 57c45452..2990c1f3 100644 --- a/src/client/cl_parse.c +++ b/src/client/cl_parse.c @@ -145,8 +145,13 @@ CL_ParseDelta(entity_state_t *from, entity_state_t *to, int number, int bits) if (cls.serverProtocol != PROTOCOL_VERSION) { + int i; + /* Always set scale to 1.0f for old clients */ - to->scale[0] = 1.0f; + for (i = 0; i < 3; i++) + { + to->scale[i] = 1.0f; + } } if (IS_QII97_PROTOCOL(cls.serverProtocol)) @@ -219,8 +224,15 @@ CL_ParseDelta(entity_state_t *from, entity_state_t *to, int number, int bits) /* Additional scale with skinnum */ if (cls.serverProtocol == PROTOCOL_VERSION) { - to->scale[0] = MSG_ReadFloat(&net_message); - printf("received scale %f\n", to->scale[0]); + int i; + + for (i = 0; i < 3; i++) + { + to->scale[i] = MSG_ReadFloat(&net_message); + } + + printf("received scale %.2fx%.2fx%.2f\n", + to->scale[0], to->scale[1], to->scale[2]); } } else if (bits & U_SKIN8) diff --git a/src/client/refresh/files/mesh.c b/src/client/refresh/files/mesh.c index 4d8b0c1f..6089f312 100644 --- a/src/client/refresh/files/mesh.c +++ b/src/client/refresh/files/mesh.c @@ -95,18 +95,20 @@ void R_LerpVerts(qboolean powerUpEffect, int nverts, const dxtrivertx_t *v, const dxtrivertx_t *ov, float *lerp, const float move[3], - const float frontv[3], const float backv[3], float scale) + const float frontv[3], const float backv[3], const float *scale) { - int i; + vec3_t new_scale = {1.0, 1.0, 1.0}; + scale = new_scale; - /* If scale is undefined, set scale 1.0f */ - if (!scale) + if (!scale[0] || !scale[1] || !scale[2]) { - scale = 1.0f; + printf("model without scale\n"); } if (powerUpEffect) { + int i; + for (i = 0; i < nverts; i++, v++, ov++, lerp += 4) { int n; @@ -117,18 +119,23 @@ R_LerpVerts(qboolean powerUpEffect, int nverts, normal = v->normal[n] / 127.f; - lerp[n] = scale * (move[n] + ov->v[n] * backv[n] + v->v[n] * frontv[n]) + + lerp[n] = scale[n] * (move[n] + ov->v[n] * backv[n] + v->v[n] * frontv[n]) + normal * POWERSUIT_SCALE; } } } else { + int i; + for (i = 0; i < nverts; i++, v++, ov++, lerp += 4) { - lerp[0] = scale * (move[0] + ov->v[0] * backv[0] + v->v[0] * frontv[0]); - lerp[1] = scale * (move[1] + ov->v[1] * backv[1] + v->v[1] * frontv[1]); - lerp[2] = scale * (move[2] + ov->v[2] * backv[2] + v->v[2] * frontv[2]); + int n; + + for (n = 0; n < 3; n++) + { + lerp[n] = scale[n] * (move[n] + ov->v[n] * backv[n] + v->v[n] * frontv[n]); + } } } } diff --git a/src/client/refresh/gl1/gl1_mesh.c b/src/client/refresh/gl1/gl1_mesh.c index b3f51ace..c2c42088 100644 --- a/src/client/refresh/gl1/gl1_mesh.c +++ b/src/client/refresh/gl1/gl1_mesh.c @@ -338,6 +338,15 @@ R_DrawAliasModel(entity_t *currententity, const model_t *currentmodel) } } + for (i = 0; i < 3; i++) + { + /* fix scale */ + if (!currententity->scale[i]) + { + currententity->scale[i] = 1.0f; + } + } + paliashdr = (dmdx_t *)currentmodel->extradata; /* get lighting information */ diff --git a/src/client/refresh/gl3/gl3_mesh.c b/src/client/refresh/gl3/gl3_mesh.c index 6d0b4744..0ff9e889 100644 --- a/src/client/refresh/gl3/gl3_mesh.c +++ b/src/client/refresh/gl3/gl3_mesh.c @@ -548,6 +548,15 @@ GL3_DrawAliasModel(entity_t *entity) } } + for (i = 0; i < 3; i++) + { + /* fix scale */ + if (!entity->scale[i]) + { + entity->scale[i] = 1.0f; + } + } + gl3model_t* model = entity->model; paliashdr = (dmdx_t *)model->extradata; diff --git a/src/client/refresh/gl4/gl4_mesh.c b/src/client/refresh/gl4/gl4_mesh.c index 17577251..a8f789a2 100644 --- a/src/client/refresh/gl4/gl4_mesh.c +++ b/src/client/refresh/gl4/gl4_mesh.c @@ -548,6 +548,15 @@ GL4_DrawAliasModel(entity_t *entity) } } + for (i = 0; i < 3; i++) + { + /* fix scale */ + if (!entity->scale[i]) + { + entity->scale[i] = 1.0f; + } + } + gl4model_t* model = entity->model; paliashdr = (dmdx_t *)model->extradata; diff --git a/src/client/refresh/ref_shared.h b/src/client/refresh/ref_shared.h index a5edad3a..d41392f2 100644 --- a/src/client/refresh/ref_shared.h +++ b/src/client/refresh/ref_shared.h @@ -382,7 +382,7 @@ extern qboolean R_CullAliasMeshModel(dmdx_t *paliashdr, cplane_t *frustum, extern void R_LerpVerts(qboolean powerUpEffect, int nverts, const dxtrivertx_t *v, const dxtrivertx_t *ov, float *lerp, const float move[3], - const float frontv[3], const float backv[3], float scale); + const float frontv[3], const float backv[3], const float *scale); extern void R_ConvertNormalMDL(byte in_normal, signed char *normal); extern vec4_t *R_VertBufferRealloc(int num); extern void R_VertBufferInit(void); diff --git a/src/client/refresh/soft/sw_alias.c b/src/client/refresh/soft/sw_alias.c index 58fd22da..185071f5 100644 --- a/src/client/refresh/soft/sw_alias.c +++ b/src/client/refresh/soft/sw_alias.c @@ -795,17 +795,21 @@ R_AliasDrawModel void R_AliasDrawModel(entity_t *currententity, const model_t *currentmodel) { + int i; + s_pmdl = (dmdx_t *)currentmodel->extradata; if ( r_lerpmodels->value == 0 ) + { currententity->backlerp = 0; + } float oldAliasxscale = aliasxscale; float oldAliasyscale = aliasyscale; - if ( currententity->flags & RF_WEAPONMODEL ) + if (currententity->flags & RF_WEAPONMODEL) { - if ( r_lefthand->value == 2.0F ) + if (r_lefthand->value == 2.0F) { return; } @@ -821,6 +825,15 @@ R_AliasDrawModel(entity_t *currententity, const model_t *currentmodel) aliasxscale = -aliasxscale; } + for (i = 0; i < 3; i++) + { + /* fix scale */ + if (!currententity->scale[i]) + { + currententity->scale[i] = 1.0f; + } + } + /* ** we have to set our frame pointers and transformations before ** doing any real work diff --git a/src/client/refresh/vk/vk_mesh.c b/src/client/refresh/vk/vk_mesh.c index de92db8d..4ba2759c 100644 --- a/src/client/refresh/vk/vk_mesh.c +++ b/src/client/refresh/vk/vk_mesh.c @@ -527,6 +527,15 @@ R_DrawAliasModel(entity_t *currententity, const model_t *currentmodel) } } + for (i = 0; i < 3; i++) + { + /* fix scale */ + if (!currententity->scale[i]) + { + currententity->scale[i] = 1.0f; + } + } + paliashdr = (dmdx_t *)currentmodel->extradata; /* get lighting information */ diff --git a/src/client/vid/header/ref.h b/src/client/vid/header/ref.h index 22a88c6f..2b7c5e9c 100644 --- a/src/client/vid/header/ref.h +++ b/src/client/vid/header/ref.h @@ -68,7 +68,7 @@ typedef struct entity_s { /* misc */ float backlerp; /* 0.0 = current, 1.0 = old */ int skinnum; /* also used as RF_BEAM's palette index */ - float scale; + vec3_t scale; /* model scale before render */ int lightstyle; /* for flashing entities */ float alpha; /* ignore if RF_TRANSLUCENT isn't set */ diff --git a/src/common/movemsg.c b/src/common/movemsg.c index a1ee4db8..d4b25412 100644 --- a/src/common/movemsg.c +++ b/src/common/movemsg.c @@ -731,9 +731,15 @@ MSG_WriteDeltaEntity(entity_state_t *from, /* Send scale */ if (protocol == PROTOCOL_VERSION) { - to->scale[0] = 1.5f; - MSG_WriteFloat(msg, to->scale[0]); - printf("send scale %f\n", to->scale[0]); + int i; + + for (i = 0; i < 3; i++) + { + MSG_WriteFloat(msg, to->scale[i]); + } + + printf("send scale %.2fx%.2fx%.2f\n", + to->scale[0], to->scale[1], to->scale[2]); } }