├── src ├── engine │ ├── client │ │ ├── ui │ │ │ ├── ui_centermsg.c │ │ │ ├── gui.h │ │ │ └── ui_local.h │ │ ├── fx │ │ │ ├── effects.h │ │ │ └── fx_main.c │ │ ├── vid.h │ │ ├── input.h │ │ ├── screen.h │ │ ├── cgame │ │ │ ├── cg_events.c │ │ │ ├── cg_local.h │ │ │ ├── client_game.h │ │ │ ├── cg_tempents.c │ │ │ ├── progdefs_client.h │ │ │ ├── cg_weapon.c │ │ │ ├── cg_lightstyles.c │ │ │ └── cg_dlights.c │ │ ├── sound.h │ │ ├── console.h │ │ ├── cl_cinematic.c │ │ ├── keys.h │ │ └── cl_graph.c │ ├── md4.c │ ├── pragma.ico │ ├── resource.h │ ├── usercmd.h │ ├── sizebuf.h │ ├── filesystem.h │ ├── script │ │ ├── progdefs_ui.h │ │ └── qc_opcodes.h │ ├── sizebuf.c │ ├── pragma.rc │ ├── message.h │ ├── network.h │ ├── cmodel.h │ ├── net_chan.h │ ├── usercmd.c │ ├── winquake.rc │ ├── model_cache.h │ ├── pragma_config.h │ └── cvar.h ├── renderer_dll │ ├── renderer.def │ ├── win_glw.h │ ├── TODO.md │ ├── win_qgl.h │ ├── warpsin.h │ ├── pragma_renderer.filters │ └── r_shadow.c ├── common │ ├── cmd_public.h │ ├── pragma_files.h │ ├── fileformats │ │ ├── pak.h │ │ ├── pmodel.h │ │ ├── md3.h │ │ └── smdl.h │ ├── crc.h │ ├── pragma_windows.h │ ├── cvar_public.h │ └── crc.c ├── tools │ ├── prtool │ │ ├── prtool.vcxproj.filters │ │ ├── smd.h │ │ ├── prtool.h │ │ └── prtool.filters │ └── tools_shared.h ├── .gitattributes └── pragma.sln ├── stuff ├── fteqcc_win64.zip ├── pragma-lq-dev-textures.zip └── pragma-netradiant-gamepack.zip ├── progs_src ├── svgame │ ├── svgame.dat │ ├── weapons │ │ ├── weapon_ar.qc │ │ └── weapon_blaster.qc │ ├── ents │ │ ├── func_group.qc │ │ ├── info.qc │ │ ├── target_tent.qc │ │ ├── func_rotating.qc │ │ ├── func_areaportal.qc │ │ ├── target_changelevel.qc │ │ ├── target_explosion.qc │ │ ├── devents.qc │ │ ├── spawnpoints.qc │ │ ├── spawnflags.qc │ │ ├── prop_model.qc │ │ ├── worldspawn.qc │ │ ├── func_object.qc │ │ ├── monsters.qc │ │ ├── func_wall.qc │ │ ├── light.qc │ │ └── target_speaker.qc │ ├── progs.src │ ├── pers.qc │ ├── fteqc_ext.qc │ ├── hud.qc │ ├── effects.qc │ ├── fields.qc │ └── clcmds.qc ├── ui │ ├── ui_main.qc │ ├── progs.src │ └── fteqc_ext.qc ├── cgame │ ├── cg_load.qc │ ├── progs.src │ ├── cg_main.qc │ ├── cg_svcmd.qc │ ├── cg_crosshair.qc │ ├── cg_debug.qc │ ├── fteqc_ext.qc │ └── cg_hud.qc ├── compile_svgame.bat ├── compile_cgame.bat ├── compile_allprogs.bat ├── inc │ ├── pragma_funcs_clgame.qc │ ├── pragma_funcs_shared.qc │ ├── pragma_structs_client.qc │ ├── fteqc_ext.qc │ └── shared.qc └── bg │ └── bg_weapons.qc ├── readme.txt ├── .github └── workflows │ ├── msbuild-release-x86.yml │ ├── msbuild-release-x64.yml │ ├── msbuild-debug-x86.yml │ └── msbuild-debug-x64.yml └── .gitattributes /src/engine/client/ui/ui_centermsg.c: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/renderer_dll/renderer.def: -------------------------------------------------------------------------------- 1 | EXPORTS 2 | GetRefAPI 3 | -------------------------------------------------------------------------------- /src/engine/md4.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BraXi/pragma/HEAD/src/engine/md4.c -------------------------------------------------------------------------------- /src/engine/pragma.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BraXi/pragma/HEAD/src/engine/pragma.ico -------------------------------------------------------------------------------- /stuff/fteqcc_win64.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BraXi/pragma/HEAD/stuff/fteqcc_win64.zip -------------------------------------------------------------------------------- /progs_src/svgame/svgame.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BraXi/pragma/HEAD/progs_src/svgame/svgame.dat -------------------------------------------------------------------------------- /stuff/pragma-lq-dev-textures.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BraXi/pragma/HEAD/stuff/pragma-lq-dev-textures.zip -------------------------------------------------------------------------------- /stuff/pragma-netradiant-gamepack.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BraXi/pragma/HEAD/stuff/pragma-netradiant-gamepack.zip -------------------------------------------------------------------------------- /progs_src/ui/ui_main.qc: -------------------------------------------------------------------------------- 1 | /* 2 | pragma engine 3 | Copyright (C) 2023 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | */ 8 | 9 | 10 | void() UI_Main = 11 | { 12 | }; -------------------------------------------------------------------------------- /progs_src/svgame/weapons/weapon_ar.qc: -------------------------------------------------------------------------------- 1 | /* 2 | pragma engine 3 | Copyright (C) 2023 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | */ 8 | // weapon_blaster.qc 9 | 10 | -------------------------------------------------------------------------------- /src/engine/client/fx/effects.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | // 7 | // fx_main.c 8 | // 9 | 10 | void FX_ClearParticles(); 11 | int CL_FindEffect(char* name); 12 | 13 | void CL_InitEffects(); 14 | void CL_ShutdownEffects(); -------------------------------------------------------------------------------- /progs_src/cgame/cg_load.qc: -------------------------------------------------------------------------------- 1 | /* 2 | pragma engine 3 | Copyright (C) 2023 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | */ 8 | 9 | 10 | void() load_assets = 11 | { 12 | }; 13 | -------------------------------------------------------------------------------- /progs_src/compile_svgame.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | echo *************************** 4 | echo pragma - server game qc 5 | echo *************************** 6 | 7 | fteqcc64 -src ./svgame 8 | move svgame.dat ../build/main/progs/ 9 | 10 | pause -------------------------------------------------------------------------------- /progs_src/compile_cgame.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | echo *************************** 4 | echo pragma - client game qc 5 | echo *************************** 6 | 7 | fteqcc64 -src ./progs_src/cgame 8 | move cgame.dat ./build/main/progs/ 9 | 10 | pause -------------------------------------------------------------------------------- /progs_src/ui/progs.src: -------------------------------------------------------------------------------- 1 | ui.dat 2 | 3 | #define UI 1 4 | 5 | // qc extensions 6 | #include "fteqc_ext.qc" 7 | 8 | // 9 | // includes 10 | // 11 | ../inc/pragma_structs_ui.qc 12 | ../inc/pragma_funcs_shared.qc 13 | ../inc/pragma_funcs_ui.qc 14 | ../inc/pragma_defs.qc 15 | 16 | // 17 | // user interface 18 | // 19 | ui_main.qc -------------------------------------------------------------------------------- /progs_src/svgame/ents/func_group.qc: -------------------------------------------------------------------------------- 1 | /* 2 | P R A G M A 3 | Copyright (C) 2023 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | */ 8 | 9 | 10 | /*QUAKED func_group (0 0 0) ? 11 | Used to group brushes together just for editor convenience. 12 | removed in game 13 | */ 14 | float() SP_func_group = 15 | { 16 | return false; // remove entity straight away 17 | }; -------------------------------------------------------------------------------- /src/engine/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Developer Studio generated include file. 3 | // Used by q2.rc 4 | // 5 | #define IDI_ICON1 101 6 | 7 | // Next default values for new objects 8 | // 9 | #ifdef APSTUDIO_INVOKED 10 | #ifndef APSTUDIO_READONLY_SYMBOLS 11 | #define _APS_NEXT_RESOURCE_VALUE 103 12 | #define _APS_NEXT_COMMAND_VALUE 40001 13 | #define _APS_NEXT_CONTROL_VALUE 1000 14 | #define _APS_NEXT_SYMED_VALUE 101 15 | #endif 16 | #endif 17 | -------------------------------------------------------------------------------- /progs_src/cgame/progs.src: -------------------------------------------------------------------------------- 1 | cgame.dat 2 | 3 | #define CLGAME 1 4 | 5 | // qc extensions 6 | #include "fteqc_ext.qc" 7 | 8 | // 9 | // includes 10 | // 11 | ../inc/pragma_structs_client.qc 12 | ../inc/pragma_funcs_shared.qc 13 | ../inc/pragma_funcs_clgame.qc 14 | ../inc/pragma_defs.qc 15 | 16 | // shared by client and server 17 | ../inc/shared.qc 18 | ../bg/bg_pmove.qc 19 | ../bg/bg_weapons.qc 20 | 21 | // 22 | // client game 23 | // 24 | cg_crosshair.qc 25 | cg_debug.qc 26 | cg_hud.qc 27 | cg_load.qc 28 | cg_main.qc 29 | cg_svcmd.qc -------------------------------------------------------------------------------- /progs_src/svgame/ents/info.qc: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | info_null 4 | info_notnull 5 | 6 | */ 7 | 8 | /*QUAKED info_null (0 0.5 0) (-4 -4 -4) (4 4 4) 9 | Used as a positional target for spotlights, etc. 10 | removed in game 11 | */ 12 | 13 | /*QUAKED info_notnull (0 0.5 0) (-4 -4 -4) (4 4 4) 14 | Used as a positional target for triggers, lights, etc. 15 | */ 16 | 17 | float() SP_info_null = 18 | { 19 | return false; // discard it, it's only used by BSP tools 20 | }; 21 | 22 | float() SP_info_notnull = 23 | { 24 | return true; 25 | }; 26 | 27 | -------------------------------------------------------------------------------- /readme.txt: -------------------------------------------------------------------------------- 1 | ======== 2 | pragma 3 | ======== 4 | 5 | https://github.com/BraXi/pragma 6 | 7 | Pragma is an highly modified and upgraded IdTech2 engine derived from Quake 2 and is designed for stand-alone projects. 8 | It does replace native C gamecode with QuakeC VM and adds support for client-side QC, and more. 9 | Engine does not require Quake2 game data to launch, you can grab minimal package from repo. 10 | For more informations visit GitHub page. 11 | 12 | Engine source code (https://github.com/BraXi/pragma/src) is GPL-2.0 licensed 13 | 14 | - BraXi -------------------------------------------------------------------------------- /progs_src/cgame/cg_main.qc: -------------------------------------------------------------------------------- 1 | /* 2 | pragma engine 3 | Copyright (C) 2023 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | */ 8 | 9 | void() cmd_test = 10 | { 11 | print("This is the first CG registered command!\n"); 12 | }; 13 | 14 | void() CG_Main = 15 | { 16 | BG_InitWeapons(); 17 | CG_InitCrosshair(); 18 | 19 | addcommand("cgtest", cmd_test); 20 | }; 21 | 22 | void() CG_Frame = 23 | { 24 | cg_nocrosshair = cvar("cg_nocrosshair"); 25 | }; 26 | 27 | void() CG_DrawGUI = 28 | { 29 | CG_DrawHUD(); 30 | CG_DrawCrosshair(); 31 | }; -------------------------------------------------------------------------------- /progs_src/compile_allprogs.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | echo *************************** 4 | echo pragma - ui qc 5 | echo *************************** 6 | 7 | fteqcc64 -src ./ui 8 | move svgame.dat ../build/main/progs/ 9 | 10 | 11 | 12 | echo *************************** 13 | echo pragma - client game qc 14 | echo *************************** 15 | 16 | fteqcc64 -src ./cgame 17 | move cgame.dat ../build/main/progs/ 18 | 19 | echo *************************** 20 | echo pragma - server game qc 21 | echo *************************** 22 | 23 | fteqcc64 -src ./svgame 24 | move svgame.dat ../build/main/progs/ 25 | 26 | pause -------------------------------------------------------------------------------- /src/common/cmd_public.h: -------------------------------------------------------------------------------- 1 | /* 2 | pragma 3 | Copyright (C) 2023-2024 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | 8 | See the attached GNU General Public License v2 for more details. 9 | */ 10 | 11 | #pragma once 12 | 13 | /* 14 | ============================================================== 15 | 16 | cmd_public.h 17 | 18 | Public interface shared with all pragma modules. 19 | 20 | ============================================================== 21 | */ 22 | 23 | 24 | 25 | #ifndef _PRAGMA_CMD_PUBLIC_H_ 26 | #define _PRAGMA_CMD_PUBLIC_H_ 27 | 28 | 29 | 30 | #endif /*_PRAGMA_CMD_PUBLIC_H_*/ -------------------------------------------------------------------------------- /src/engine/client/vid.h: -------------------------------------------------------------------------------- 1 | /* 2 | pragma 3 | Copyright (C) 2023-2024 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | 8 | See the attached GNU General Public License v2 for more details. 9 | */ 10 | 11 | // vid.h -- video driver defs 12 | 13 | typedef struct vrect_s 14 | { 15 | int x,y,width,height; 16 | } vrect_t; 17 | 18 | typedef struct 19 | { 20 | int width; 21 | int height; 22 | } viddef_t; 23 | 24 | extern viddef_t viddef; // global video state 25 | 26 | // Video module initialisation etc 27 | void VID_Init (void); 28 | void VID_Shutdown (void); 29 | void VID_CheckChanges (void); 30 | -------------------------------------------------------------------------------- /src/common/pragma_files.h: -------------------------------------------------------------------------------- 1 | /* 2 | pragma 3 | Copyright (C) 2023-2024 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | 8 | See the attached GNU General Public License v2 for more details. 9 | */ 10 | 11 | // 12 | // pragma_files.h: pragma file formats 13 | // This file must be identical in the pragma and utils directories 14 | // 15 | 16 | #pragma once 17 | 18 | #ifndef _PRAGMA_FILES_H_ 19 | #define _PRAGMA_FILES_H_ 20 | 21 | #include "fileformats/bsp.h" 22 | #include "fileformats/pak.h" 23 | #include "fileformats/smdl.h" 24 | #include "fileformats/md3.h" 25 | #include "fileformats/pmodel.h" 26 | 27 | #endif /*_PRAGMA_FILES_H_*/ 28 | -------------------------------------------------------------------------------- /progs_src/cgame/cg_svcmd.qc: -------------------------------------------------------------------------------- 1 | /* 2 | pragma engine 3 | Copyright (C) 2023 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | */ 8 | 9 | // cg_svcmd.qc 10 | 11 | /* 12 | ================= 13 | CG_ServerCommand 14 | 15 | handles 'SVC_CGCMD [command (byte)] [...]' command from server 16 | 17 | Use MSG_Read functions here... 18 | ================= 19 | */ 20 | void(float inCommand) CG_ServerCommand = 21 | { 22 | switch(inCommand) 23 | { 24 | case 1: 25 | localsound("misc/beep.wav", 1.0); 26 | print(MSG_ReadString()); // print our message 27 | break; 28 | default: 29 | print("received unknown CG command from server: ", ftos(inCommand), "\n"); 30 | break; 31 | } 32 | }; -------------------------------------------------------------------------------- /src/engine/usercmd.h: -------------------------------------------------------------------------------- 1 | /* 2 | pragma 3 | Copyright (C) 2023-2024 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | 8 | See the attached GNU General Public License v2 for more details. 9 | */ 10 | 11 | /* 12 | ============================================================== 13 | 14 | User Commands 15 | 16 | ============================================================== 17 | */ 18 | 19 | #pragma once 20 | 21 | #ifndef _PRAGMA_USERCMD_H_ 22 | #define _PRAGMA_USERCMD_H_ 23 | 24 | 25 | void MSG_WriteDeltaUsercmd(sizebuf_t* buf, usercmd_t* from, usercmd_t* cmd); 26 | void MSG_ReadDeltaUsercmd(sizebuf_t* msg_read, usercmd_t* from, usercmd_t* move); 27 | 28 | 29 | #endif /*_PRAGMA_USERCMD_H_*/ -------------------------------------------------------------------------------- /src/engine/client/input.h: -------------------------------------------------------------------------------- 1 | /* 2 | pragma 3 | Copyright (C) 2023-2024 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | 8 | See the attached GNU General Public License v2 for more details. 9 | */ 10 | 11 | // input.h -- external (non-keyboard) input devices 12 | 13 | #ifndef _PRAGMA_INPUT_H_ 14 | #define _PRAGMA_INPUT_H_ 15 | 16 | void IN_Init (void); 17 | 18 | void IN_Shutdown (void); 19 | 20 | void IN_Commands (void); 21 | // oportunity for devices to stick commands on the script buffer 22 | 23 | void IN_Frame (void); 24 | 25 | void IN_Move (usercmd_t *cmd); 26 | // add additional movement on top of the keyboard move cmd 27 | 28 | void IN_Activate (qboolean active); 29 | 30 | #endif /*_PRAGMA_INPUT_H_*/ 31 | -------------------------------------------------------------------------------- /progs_src/svgame/ents/target_tent.qc: -------------------------------------------------------------------------------- 1 | /* 2 | P R A G M A 3 | Copyright (C) 2023 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | */ 8 | 9 | 10 | /*QUAKED target_temp_entity (1 0 0) (-8 -8 -8) (8 8 8) 11 | Fire an origin based temp entity event to the clients. 12 | 13 | "style" type byte (TE_ enum) 14 | */ 15 | 16 | void(entity user) target_temp_use = 17 | { 18 | MSG_WriteByte(SVC_TEMP_ENTITY); 19 | MSG_WriteByte(self.style); 20 | MSG_WritePos(self.origin); 21 | MSG_Multicast(self.origin, MULTICAST_PVS); 22 | }; 23 | 24 | float() SP_target_temp_entity = 25 | { 26 | if( !self.style ) 27 | return false; 28 | 29 | if( !strlen(self.targetname) ) 30 | return false; 31 | 32 | self.use = target_temp_use; 33 | return true; 34 | }; -------------------------------------------------------------------------------- /src/renderer_dll/win_glw.h: -------------------------------------------------------------------------------- 1 | /* 2 | pragma 3 | Copyright (C) 2023-2024 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | 8 | See the attached GNU General Public License v2 for more details. 9 | */ 10 | #ifndef _WIN32 11 | # error You should not be including this file on this platform 12 | #endif 13 | 14 | #ifndef __GLW_WIN_H__ 15 | #define __GLW_WIN_H__ 16 | 17 | typedef struct 18 | { 19 | HINSTANCE hInstance; 20 | void *wndproc; 21 | 22 | HDC hDC; // handle to device context 23 | HWND hWnd; // handle to window 24 | HGLRC hGLRC; // handle to GL rendering context 25 | 26 | HINSTANCE hinstOpenGL; // HINSTANCE for the OpenGL library 27 | 28 | qboolean minidriver; 29 | qboolean allowdisplaydepthchange; 30 | 31 | FILE *log_fp; 32 | } glwstate_t; 33 | 34 | extern glwstate_t glw_state; 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /progs_src/svgame/ents/func_rotating.qc: -------------------------------------------------------------------------------- 1 | /* 2 | P R A G M A 3 | Copyright (C) 2023 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | */ 8 | 9 | /*QUAKED func_rotating (0 .5 .8) ? X X X X X 10 | rotating brush model 11 | */ 12 | 13 | void() func_rotating_think = 14 | { 15 | self.avelocity = '0 45 0'; 16 | self.think = func_rotating_think; 17 | self.nextthink = g_time + 1; 18 | }; 19 | 20 | 21 | float() SP_func_rotating = 22 | { 23 | setmodel(self, self.model); //setmodel sets bbox sizes for brushmodel 24 | self.takedamage = DAMAGE_NO; 25 | 26 | if( self.avelocity == vec3_origin ) 27 | self.avelocity = '0 45 0'; 28 | 29 | self.solid = SOLID_BSP; 30 | self.movetype = MOVETYPE_PUSH; 31 | self.clipmask = MASK_MONSTERSOLID; 32 | linkentity(self); 33 | 34 | self.think = func_rotating_think; 35 | self.nextthink = g_time + 1; 36 | 37 | return true; 38 | } -------------------------------------------------------------------------------- /progs_src/cgame/cg_crosshair.qc: -------------------------------------------------------------------------------- 1 | /* 2 | pragma engine 3 | Copyright (C) 2023 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | */ 8 | 9 | 10 | string gfx_crosshair; 11 | float cg_nocrosshair; 12 | vector crosshair_size; 13 | 14 | void() CG_InitCrosshair = 15 | { 16 | gfx_crosshair = "hud/crosshair_1"; 17 | crosshair_size = '28 36 0'; 18 | }; 19 | 20 | 21 | void() CG_DrawCrosshair = 22 | { 23 | float alpha; 24 | if(cg_nocrosshair) 25 | return; 26 | 27 | if(getstat(STAT_HEALTH) <= 0) 28 | return; //dont draw when dead or spectating 29 | 30 | // snipet to scale crosshair 31 | // crosshair_size = '28 36 0'; 32 | // crosshair_size = crosshair_size * cvar("cs"); 33 | // float alpha = 2.0 - cvar("cs"); 34 | 35 | if(getstat(STAT_AMMO) <= 0) 36 | alpha = 0.1; 37 | else 38 | alpha = 0.6; 39 | 40 | drawimage(400-(crosshair_size_x/2), 300-(crosshair_size_y/2), crosshair_size_x, crosshair_size_y, '1 1 1', alpha, gfx_crosshair); 41 | }; 42 | 43 | -------------------------------------------------------------------------------- /src/common/fileformats/pak.h: -------------------------------------------------------------------------------- 1 | /* 2 | pragma 3 | Copyright (C) 2023-2024 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | 8 | See the attached GNU General Public License v2 for more details. 9 | */ 10 | 11 | /* 12 | ======================================================================== 13 | 14 | The .pak files are just a linear collapse of a directory tree 15 | 16 | ======================================================================== 17 | */ 18 | 19 | #ifndef _PRAGMA_PAK_H_ 20 | #define _PRAGMA_PAK_H_ 21 | 22 | #define IDPAKHEADER (('K'<<24)+('C'<<16)+('A'<<8)+'P') 23 | 24 | #define MAX_FILENAME_IN_PACK 56 25 | #define MAX_FILES_IN_PACK 4096 26 | 27 | typedef struct 28 | { 29 | char name[MAX_FILENAME_IN_PACK]; 30 | int32_t filepos, filelen; 31 | } dpackfile_t; 32 | 33 | typedef struct 34 | { 35 | int32_t ident; // == IDPAKHEADER 36 | int32_t dirofs; 37 | int32_t dirlen; 38 | } dpackheader_t; 39 | 40 | 41 | 42 | 43 | #endif /*_PRAGMA_PAK_H_*/ -------------------------------------------------------------------------------- /src/common/crc.h: -------------------------------------------------------------------------------- 1 | /* 2 | pragma 3 | Copyright (C) 2023-2024 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | 8 | See the attached GNU General Public License v2 for more details. 9 | */ 10 | 11 | #pragma once 12 | 13 | /* 14 | ============================================================== 15 | 16 | CRC 17 | 18 | This is a 16 bit, non-reflected CRC using the polynomial 0x1021 19 | and the initial and final xor values shown below.. 20 | . 21 | In other words, the CCITT standard CRC used by XMODEM. 22 | 23 | ============================================================== 24 | */ 25 | 26 | 27 | 28 | #ifndef _PRAGMA_CRC_H_ 29 | #define _PRAGMA_CRC_H_ 30 | 31 | void CRC_Init(unsigned short* crcvalue); 32 | void CRC_ProcessByte(unsigned short* crcvalue, byte data); 33 | unsigned short CRC_Value(unsigned short crcvalue); 34 | unsigned short CRC_Block(byte* start, int count); 35 | unsigned short CRC_ChecksumFile(const char* name, qboolean fatal); 36 | 37 | #endif /*_PRAGMA_CRC_H_*/ -------------------------------------------------------------------------------- /progs_src/svgame/ents/func_areaportal.qc: -------------------------------------------------------------------------------- 1 | /* 2 | P R A G M A 3 | Copyright (C) 2023 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | */ 8 | 9 | /*QUAKED func_areaportal (0 0 0) ? 10 | 11 | This is a non-visible object that divides the world into 12 | areas that are seperated when this portal is not activated. 13 | Usually enclosed in the middle of a door. 14 | */ 15 | 16 | #define OPEN_ALL_AREAPORTALS 1 // testing 17 | 18 | void(entity activator) func_areaportal_use = 19 | { 20 | self.count ^= 1; // toggle state 21 | 22 | if( cvar("developer_script") > 0 ) 23 | dprint("portalstate: ", ftos(self.style)," = ", ftos(self.count), ";\n"); 24 | 25 | SetAreaPortalState(self.style, self.count); 26 | }; 27 | 28 | float() SP_func_areaportal = 29 | { 30 | // testing 31 | #ifdef OPEN_ALL_AREAPORTALS 32 | SetAreaPortalState(self.style, 1); 33 | return true; 34 | #else 35 | self.use = func_areaportal_use; 36 | self.count = 0; // always start closed 37 | return true; 38 | #endif 39 | }; -------------------------------------------------------------------------------- /src/tools/prtool/prtool.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | Common 16 | 17 | 18 | Common 19 | 20 | 21 | 22 | 23 | 24 | {9662834a-e518-4ac8-90a1-9ea22bb6a422} 25 | 26 | 27 | -------------------------------------------------------------------------------- /src/common/pragma_windows.h: -------------------------------------------------------------------------------- 1 | /* 2 | pragma 3 | Copyright (C) 2023-2024 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | 8 | See the attached GNU General Public License v2 for more details. 9 | */ 10 | 11 | // pragma_windows.h: Win32-specific pragmaheader file 12 | // 13 | // NOTE: this file is not included in DEDICATED_ONLY binary ! 14 | 15 | #ifndef _PRAGMA_WINDOWS_H_ 16 | #define _PRAGMA_WINDOWS_H_ 17 | 18 | #pragma once 19 | 20 | #pragma warning( disable : 4229 ) // mgraph gets this 21 | 22 | #include 23 | #include 24 | 25 | #define WINDOW_STYLE (WS_OVERLAPPED|WS_BORDER|WS_CAPTION|WS_VISIBLE) 26 | 27 | extern HINSTANCE global_hInstance; 28 | 29 | extern LPDIRECTSOUND pDS; 30 | extern LPDIRECTSOUNDBUFFER pDSBuf; 31 | 32 | extern DWORD gSndBufSize; 33 | 34 | extern HWND cl_hwnd; 35 | extern qboolean ActiveApp, Minimized; 36 | 37 | void IN_Activate (qboolean active); 38 | void IN_MouseEvent (int mstate); 39 | 40 | extern int window_center_x, window_center_y; 41 | extern RECT window_rect; 42 | 43 | #endif /*_PRAGMA_WINDOWS_H_*/ -------------------------------------------------------------------------------- /src/engine/sizebuf.h: -------------------------------------------------------------------------------- 1 | /* 2 | pragma 3 | Copyright (C) 2023-2024 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | 8 | See the attached GNU General Public License v2 for more details. 9 | */ 10 | 11 | /* 12 | ============================================================== 13 | 14 | SIZEBUF 15 | 16 | 17 | ============================================================== 18 | */ 19 | 20 | #pragma once 21 | 22 | #ifndef _PRAGMA_SIZEBUF_H_ 23 | #define _PRAGMA_SIZEBUF_H_ 24 | 25 | typedef struct sizebuf_s 26 | { 27 | qboolean allowoverflow; // if false, do a Com_Error 28 | qboolean overflowed; // set to true if the buffer size failed 29 | byte* data; 30 | int maxsize; 31 | int cursize; 32 | int readcount; 33 | } sizebuf_t; 34 | 35 | void SZ_Init(sizebuf_t* buf, byte* data, const int length); 36 | void SZ_Clear(sizebuf_t* buf); 37 | void* SZ_GetSpace(sizebuf_t* buf, const int length); 38 | void SZ_Write(sizebuf_t* buf, void* data, const int length); 39 | void SZ_Print(sizebuf_t* buf, char* data); // strcats onto the sizebuf 40 | 41 | #endif /*_PRAGMA_SIZEBUF_H_*/ 42 | -------------------------------------------------------------------------------- /src/engine/client/screen.h: -------------------------------------------------------------------------------- 1 | /* 2 | pragma 3 | Copyright (C) 2023-2024 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | 8 | See the attached GNU General Public License v2 for more details. 9 | */ 10 | 11 | // screen.h 12 | 13 | void SCR_Init (void); 14 | 15 | void SCR_UpdateScreen (void); 16 | 17 | void SCR_SizeUp (void); 18 | void SCR_SizeDown (void); 19 | void SCR_CenterPrint (char *str); 20 | void SCR_BeginLoadingPlaque (void); 21 | void SCR_EndLoadingPlaque (void); 22 | 23 | void CL_DebugGraph (float value, vec3_t color); 24 | 25 | void SCR_RunConsole (void); 26 | 27 | extern float scr_con_current; 28 | extern float scr_conlines; // lines of console to display 29 | 30 | extern int sb_lines; 31 | 32 | extern cvar_t *scr_viewsize; 33 | 34 | extern vrect_t scr_vrect; // position of render window 35 | 36 | 37 | void SCR_AddDirtyPoint (int x, int y); 38 | void SCR_DirtyScreen (void); 39 | 40 | // 41 | // scr_cin.c 42 | // 43 | void SCR_PlayCinematic (char *name); 44 | qboolean SCR_DrawCinematic (void); 45 | void SCR_RunCinematic (void); 46 | void SCR_StopCinematic (void); 47 | void SCR_FinishCinematic (void); 48 | 49 | -------------------------------------------------------------------------------- /src/engine/client/cgame/cg_events.c: -------------------------------------------------------------------------------- 1 | /* 2 | pragma 3 | Copyright (C) 2023-2024 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | 8 | See the attached GNU General Public License v2 for more details. 9 | */ 10 | 11 | #include "../client.h" 12 | #include "cg_local.h" 13 | 14 | /* 15 | ============== 16 | CG_EntityEvent 17 | 18 | An entity has just been parsed that has an event value 19 | ============== 20 | */ 21 | 22 | void CG_EntityEvent(entity_state_t* ent) 23 | { 24 | switch (ent->event) 25 | { 26 | case EV_FOOTSTEP: 27 | S_StartSound (NULL, ent->number, CHAN_BODY, cgMedia.sfx_footsteps[rand()&3], 1, ATTN_NORM, 0); // TODO: footstep sounds based on surface type (wood, metal, grass, etc) 28 | break; 29 | case EV_FALLSHORT: 30 | S_StartSound(NULL, ent->number, CHAN_AUTO, S_RegisterSound("player/land1.wav"), 1, ATTN_NORM, 0); 31 | break; 32 | case EV_FALL: 33 | S_StartSound(NULL, ent->number, CHAN_AUTO, S_RegisterSound("player/fall.wav"), 1, ATTN_NORM, 0); 34 | break; 35 | case EV_FALLFAR: 36 | S_StartSound(NULL, ent->number, CHAN_AUTO, S_RegisterSound("player/fall_far.wav"), 1, ATTN_NORM, 0); 37 | break; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/engine/client/ui/gui.h: -------------------------------------------------------------------------------- 1 | /* 2 | pragma 3 | Copyright (C) 2023-2024 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | 8 | See the attached GNU General Public License v2 for more details. 9 | */ 10 | 11 | #pragma once 12 | 13 | /* 14 | pragma 15 | Copyright (C) 2023-2024 BraXi. 16 | 17 | Quake 2 Engine 'Id Tech 2' 18 | Copyright (C) 1997-2001 Id Software, Inc. 19 | 20 | See the attached GNU General Public License v2 for more details. 21 | */ 22 | 23 | // 24 | // ui_main.c 25 | // 26 | 27 | qboolean UI_IsGuiOpen(char* name); 28 | void UI_OpenGui(char* name); 29 | void UI_CloseGui(char* name); 30 | void UI_CloseAllGuis(); 31 | int UI_NumOpenedGuis(); 32 | 33 | void UI_Main(); 34 | 35 | void UI_Init(); 36 | void UI_Shutdown(); 37 | 38 | void UI_KeyInputHandler(int key); 39 | void UI_Draw(); 40 | 41 | 42 | #define MAX_SERVERS 32 43 | typedef struct server_entry_s 44 | { 45 | qboolean good; 46 | 47 | char address[32]; 48 | 49 | char name[32]; 50 | char mod[16]; 51 | char map[16]; 52 | 53 | int numcl, maxcl; 54 | 55 | int ping; 56 | }server_entry_t; 57 | 58 | extern server_entry_t ui_servers[MAX_SERVERS]; 59 | extern int ui_numServers; -------------------------------------------------------------------------------- /src/engine/client/sound.h: -------------------------------------------------------------------------------- 1 | /* 2 | pragma 3 | Copyright (C) 2023-2024 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | 8 | See the attached GNU General Public License v2 for more details. 9 | */ 10 | 11 | struct sfx_s; 12 | 13 | void S_Init (void); 14 | void S_Shutdown (void); 15 | 16 | // if origin is NULL, the sound will be dynamically sourced from the entity 17 | void S_StartSound (vec3_t origin, int entnum, int entchannel, struct sfx_s *sfx, float fvol, float attenuation, float timeofs); 18 | void S_StopEntitySounds(int entnum); 19 | void S_StartLocalSound (const char *s); 20 | 21 | void S_RawSamples (int samples, int rate, int width, int channels, byte *data); 22 | 23 | void S_StopAllSounds(void); 24 | void S_Update (vec3_t origin, vec3_t v_forward, vec3_t v_right, vec3_t v_up); 25 | 26 | void S_Activate (qboolean active); 27 | 28 | void S_BeginRegistration (void); 29 | struct sfx_s *S_RegisterSound (const char *sample); 30 | void S_EndRegistration (void); 31 | 32 | struct sfx_s *S_FindName (const char *name, qboolean create); 33 | 34 | // the sound code makes callbacks to the client for entitiy position 35 | // information, so entities can be dynamically re-spatialized 36 | void CL_GetEntitySoundOrigin (int ent, vec3_t org); 37 | -------------------------------------------------------------------------------- /progs_src/inc/pragma_funcs_clgame.qc: -------------------------------------------------------------------------------- 1 | // this file was generated by pragma engine version 0.22 (build: Dec 29 2023 21:02:08) 2 | // DO NOT EDIT 3 | // number of builtins: 24 4 | 5 | float(string fn) precache_model = #41; 6 | float(string fn) precache_sound = #42; 7 | float(string fn) precache_image = #43; 8 | float(vector v) pointcontents = #44; 9 | void(vector s, vector bmins, vector bmaxs, vector e, float ie, int cm) trace = #45; 10 | string(int idx) getconfigstring = #46; 11 | float(float idx) getstat = #47; 12 | int() MSG_ReadChar = #48; 13 | int() MSG_ReadByte = #49; 14 | int() MSG_ReadShort = #50; 15 | int() MSG_ReadLong = #51; 16 | float() MSG_ReadFloat = #52; 17 | float() MSG_ReadCoord = #53; 18 | vector() MSG_ReadPos = #54; 19 | float() MSG_ReadAngle = #55; 20 | float() MSG_ReadAngle16 = #56; 21 | vector() MSG_ReadDir = #57; 22 | string() MSG_ReadString = #58; 23 | void(vector xya, float fs, vector c, float a, string s1, ...) drawstring = #59; 24 | void(float x, float y, float w, float h, vector c, float a, string img) drawimage = #60; 25 | void(float x, float y, float w, float h, vector c, float a) drawfill = #61; 26 | void(string s, float v) localsound = #62; 27 | void(vector v, float en, string snd, float ch, float vol, float att, float tofs) playsound = #63; 28 | void(string cn, void() f) addcommand = #64; 29 | -------------------------------------------------------------------------------- /src/engine/filesystem.h: -------------------------------------------------------------------------------- 1 | /* 2 | pragma 3 | Copyright (C) 2023-2024 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | 8 | See the attached GNU General Public License v2 for more details. 9 | */ 10 | 11 | 12 | /* 13 | ============================================================== 14 | FILESYSTEM 15 | ============================================================== 16 | */ 17 | 18 | #pragma once 19 | 20 | #ifndef _PRAGMA_FILESYSTEM_H_ 21 | #define _PRAGMA_FILESYSTEM_H_ 22 | 23 | void FS_InitFilesystem(void); 24 | void FS_SetGamedir(const char* dir); 25 | char *FS_Gamedir(void); 26 | char *FS_NextPath(const char* prevpath); 27 | void FS_ExecAutoexec(void); 28 | 29 | int FS_FOpenFile(const char* filename, FILE** file); 30 | void FS_FCloseFile(FILE* f); // note: this can't be called from another DLL, due to MS libc issues 31 | 32 | 33 | int FS_LoadFile(const char* path, void** buffer); 34 | // a null buffer will just return the file length without loading 35 | // a -1 length is not present 36 | 37 | void FS_Read(void* buffer, int len, FILE* f); 38 | // properly handles partial reads 39 | 40 | void FS_FreeFile(void* buffer); 41 | 42 | int FS_LoadTextFile(const char* filename, char** buffer); 43 | 44 | void FS_CreatePath(const char* path); 45 | 46 | #endif /*_PRAGMA_FILESYSTEM_H_*/ 47 | -------------------------------------------------------------------------------- /src/tools/prtool/smd.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _SMD_H_ 3 | 4 | typedef enum { SMD_MODEL, SMD_ANIMATION } smdtype_t; // What was loaded from file and what we expect to load 5 | 6 | typedef struct smd_bone_s 7 | { 8 | int index; 9 | int parent; // parent bone index index, -1 == root bone 10 | char name[MAX_QPATH]; 11 | } smd_bone_t; 12 | 13 | typedef struct smd_vert_s 14 | { 15 | vec3_t xyz; 16 | vec3_t normal; 17 | vec2_t uv; 18 | int bone; 19 | } smd_vert_t; 20 | 21 | typedef struct smd_bonetransform_s 22 | { 23 | int bone; 24 | vec3_t position; 25 | vec3_t rotation; 26 | } smd_bonetransform_t; 27 | 28 | typedef struct smd_surface_s 29 | { 30 | int firstvert; 31 | int numverts; // firstvert + numverts = triangles 32 | char texture[MAX_QPATH]; 33 | } smd_surface_t; 34 | 35 | typedef struct smddata_s 36 | { 37 | char name[MAX_QPATH]; 38 | smdtype_t type; 39 | 40 | // data loaded or derived from .smd file 41 | int numbones; 42 | int numframes; 43 | int numverts; 44 | int numsurfaces; 45 | 46 | vec3_t mins, maxs; 47 | int radius; 48 | 49 | smd_bone_t* vBones[SMDL_MAX_BONES]; //SMD_NODES 50 | smd_bonetransform_t* vBoneTransforms[SMDL_MAX_BONES * SMDL_MAX_FRAMES]; //SMD_SKELETON 51 | smd_vert_t* vVerts[SMDL_MAX_VERTS]; //SMD_TRIANGLES 52 | smd_surface_t* vSurfaces[SMDL_MAX_SURFACES]; // built for each texture 53 | } smddata_t; 54 | 55 | #endif // ! _SMD_H_ 56 | -------------------------------------------------------------------------------- /progs_src/svgame/ents/target_changelevel.qc: -------------------------------------------------------------------------------- 1 | /* 2 | P R A G M A 3 | Copyright (C) 2023 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | */ 8 | 9 | 10 | /*QUAKED target_changelevel (1 0 0) (-8 -8 -8) (8 8 8) SAVE_PERS 11 | Changes level to "message" when fired (maps/.bsp) 12 | 13 | SAVE_PERS save inventory and global variables across levels 14 | "message" map name 15 | */ 16 | 17 | void(entity who) target_changelevel_use = 18 | { 19 | float savepers; 20 | 21 | if(g_intermissionTime > 0) 22 | return; //activated 23 | // commented out for testing TODO: uncomment later 24 | // if(cvar_deathmatch) 25 | // return; //not in multiplayer 26 | if( !isplayer(who) ) 27 | return; 28 | if( who.health <= 0 ) 29 | return; // dead player in single/coop 30 | 31 | if( self.spawnflags & 1 ) 32 | savepers = true; 33 | else 34 | savepers = false; 35 | 36 | g_intermissionTime = g_time; 37 | changemap(self.message, savepers); 38 | }; 39 | 40 | float() SP_target_changelevel = 41 | { 42 | if(!strlen(self.message)) 43 | { 44 | print("target_changelevel with no map ('message' key) at ", vtos(self.origin), "\n"); 45 | return false; 46 | } 47 | 48 | self.use = target_changelevel_use; 49 | // self.svflags = SVF_NOCLIENT; 50 | self.loopsound = precache_sound("world/quake.wav"); 51 | linkentity(self); 52 | return true; 53 | }; 54 | -------------------------------------------------------------------------------- /progs_src/svgame/ents/target_explosion.qc: -------------------------------------------------------------------------------- 1 | /* 2 | P R A G M A 3 | Copyright (C) 2023 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | */ 8 | 9 | /*QUAKED target_explosion (1 0 0) (-8 -8 -8) (8 8 8) ONCE 10 | Spawns an explosion temporary entity when used 11 | 12 | ONCE entity will be deleted after first explosion 13 | 14 | "delay" wait this long before going off 15 | "dmg" how much radius damage should be done, defaults to 0 16 | "radius" entities in this distance will be damaged 17 | */ 18 | 19 | void() target_explosion_explode = 20 | { 21 | float save; 22 | 23 | FX_Explosion( self.origin, "medium" ); 24 | 25 | if( self.dmg > 0 && self.radius > 0 ) 26 | RadiusDamage(self, self.activator, self.dmg, world, self.radius, DMG_EXPLOSIVE); 27 | 28 | save = self.delay; 29 | self.delay = 0; 30 | SUB_UseTargets (self, self.activator); 31 | self.delay = save; 32 | 33 | if(self.spawnflags & 1) 34 | remove(self); 35 | }; 36 | 37 | void(entity who) use_target_explosion = 38 | { 39 | self.activator = who; 40 | 41 | if (!self.delay) 42 | { 43 | target_explosion_explode(); 44 | return; 45 | } 46 | 47 | self.think = target_explosion_explode; 48 | self.nextthink = g_time + self.delay; 49 | }; 50 | 51 | float() SP_target_explosion = 52 | { 53 | self.use = use_target_explosion; 54 | self.svflags = SVF_NOCLIENT; 55 | return true; 56 | }; -------------------------------------------------------------------------------- /src/tools/prtool/prtool.h: -------------------------------------------------------------------------------- 1 | /* 2 | prtool, part of pragma 3 | Copyright (C) 2024 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | 8 | See the attached GNU General Public License v2 for more details. 9 | */ 10 | 11 | #pragma once 12 | #ifndef _CONVERTER_H_ 13 | #define _CONVERTER_H_ 14 | 15 | #include "../tools_shared.h" 16 | #include 17 | 18 | #define PRTOOL_VERSION "0.1" 19 | 20 | #define DEFAULT_GAME_DIR "main" 21 | #define DEFAULT_DEV_DIR "devraw" 22 | 23 | #define PAKLIST_DIR "pak_src" 24 | 25 | extern char g_gamedir[MAXPATH]; 26 | extern char g_devdir[MAXPATH]; 27 | extern char g_controlFileName[MAXPATH]; 28 | extern bool g_verbose; 29 | 30 | 31 | typedef void (*xcommand_t) (); 32 | typedef struct 33 | { 34 | const char* name; 35 | xcommand_t pFunc; 36 | int numargs; 37 | } command_t; 38 | 39 | // 40 | // models.c 41 | // 42 | 43 | typedef enum { MOD_BAD = 0, MOD_BRUSH, MOD_MD3, MOD_SKEL } modtype_t; 44 | 45 | typedef struct model_s 46 | { 47 | char name[MAX_QPATH]; 48 | modtype_t type; 49 | 50 | int numTextures; 51 | char textureNames[32][MAX_QPATH]; 52 | 53 | void *pData; 54 | size_t dataSize; 55 | } model_t; 56 | 57 | extern model_t* LoadModel(const char* modelname, const char* filename); 58 | 59 | #include "../../common/pragma_files.h" 60 | 61 | 62 | // 63 | // smd.cpp 64 | // 65 | 66 | #include "smd.h" 67 | 68 | #endif /*_CONVERTER_H_*/ -------------------------------------------------------------------------------- /progs_src/svgame/progs.src: -------------------------------------------------------------------------------- 1 | svgame.dat 2 | 3 | #define SVGAME 1 4 | 5 | // qc extensions 6 | #include "fteqc_ext.qc" 7 | 8 | // 9 | // includes 10 | // 11 | ../inc/pragma_structs_server.qc 12 | ../inc/pragma_funcs_shared.qc 13 | ../inc/pragma_funcs_svgame.qc 14 | ../inc/pragma_defs.qc 15 | 16 | ../inc/shared.qc // shared by client and server 17 | 18 | ../bg/bg_pmove.qc 19 | ../bg/bg_weapons.qc 20 | 21 | // 22 | // server game 23 | // 24 | fields.qc // additional entity fields used by scripts 25 | 26 | subs.qc 27 | // server logic 28 | effects.qc 29 | callbacks.qc // entry points 30 | 31 | clcmds.qc // client console commands 32 | client.qc // client code 33 | damage.qc 34 | main.qc 35 | pers.qc // save/load of persistant data across level changes 36 | hud.qc 37 | 38 | // 39 | // entities 40 | // 41 | ents/spawnflags.qc //entity spawnflags 42 | ents/func_areaportal.qc 43 | ents/func_group.qc 44 | ents/func_object.qc 45 | ents/func_rotating.qc 46 | ents/func_wall.qc 47 | 48 | ents/light.qc // also creates lightstyles 49 | ents/info.qc 50 | 51 | ents/prop_barrel.qc 52 | ents/prop_model.qc 53 | 54 | ents/spawnpoints.qc 55 | 56 | ents/target_changelevel.qc 57 | ents/target_explosion.qc 58 | ents/target_speaker.qc 59 | ents/target_tent.qc 60 | 61 | ents/triggers.qc 62 | ents/worldspawn.qc 63 | ents/monsters.qc 64 | 65 | // 66 | // weapons and their logic 67 | // 68 | weapons/weaponlogic.qc 69 | weapons/weapon_ar.qc 70 | -------------------------------------------------------------------------------- /src/engine/script/progdefs_ui.h: -------------------------------------------------------------------------------- 1 | /* 2 | pragma 3 | Copyright (C) 2023-2024 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | 8 | See the attached GNU General Public License v2 for more details. 9 | */ 10 | 11 | #ifndef _PRAGMA_PROGDEFS_GUI_H_ 12 | #define _PRAGMA_PROGDEFS_GUI_H_ 13 | 14 | #pragma once 15 | 16 | #ifndef scr_func_t 17 | typedef int32_t scr_func_t; 18 | typedef int32_t scr_int_t; 19 | // typedef vec3_t scr_vec_t; 20 | typedef int32_t scr_entity_t; 21 | typedef int32_t scr_string_t; 22 | #endif 23 | 24 | typedef struct ui_globalvars_s 25 | { 26 | int32_t pad[28]; 27 | 28 | float frametime; 29 | int32_t time; 30 | float realtime; 31 | 32 | int32_t vid_width; 33 | int32_t vid_height; 34 | int32_t scr_width; 35 | int32_t scr_height; 36 | 37 | float clientState; //cs_* 38 | float serverState; //ss_* 39 | 40 | float numServers; 41 | 42 | scr_entity_t self; 43 | scr_string_t currentGuiName; 44 | 45 | scr_func_t main; 46 | scr_func_t frame; 47 | scr_func_t Callback_GenericItemDraw; 48 | scr_func_t Callback_ParseItemKeyVal; 49 | scr_func_t Callback_InitItemDef; 50 | } ui_globalvars_t; 51 | 52 | 53 | typedef struct ui_itemvars_s 54 | { 55 | scr_string_t name; 56 | scr_func_t drawfunc; 57 | 58 | // also "rect" 59 | float x, y, w, h; 60 | 61 | // also "rgba" 62 | vec3_t color; 63 | float alpha; 64 | } ui_itemvars_t; 65 | 66 | #endif /*_PRAGMA_PROGDEFS_GUI_H_*/ -------------------------------------------------------------------------------- /src/engine/client/console.h: -------------------------------------------------------------------------------- 1 | /* 2 | pragma 3 | Copyright (C) 2023-2024 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | 8 | See the attached GNU General Public License v2 for more details. 9 | */ 10 | 11 | // cl_console.h 12 | 13 | #ifndef _PRAGMA_CL_CONSOLE_H_ 14 | #define _PRAGMA_CL_CONSOLE_H_ 15 | 16 | #pragma once 17 | 18 | #define NUM_CON_TIMES 8 19 | #define CON_TEXTSIZE 32768 20 | 21 | typedef struct 22 | { 23 | qboolean initialized; 24 | 25 | char text[CON_TEXTSIZE]; 26 | int current; // line where next message will be printed 27 | int x; // offset in current line for next print 28 | int display; // bottom of console displays this line 29 | 30 | int ormask; // high bit mask for colored characters 31 | 32 | int linewidth; // characters across screen 33 | int totallines; // total lines in console scrollback 34 | 35 | float cursorspeed; 36 | 37 | int vislines; 38 | 39 | float times[NUM_CON_TIMES]; // cls.realtime time the line was generated 40 | // for transparent notify lines 41 | } console_t; 42 | 43 | extern console_t con; 44 | 45 | void Con_CheckResize (void); 46 | void Con_Init (void); 47 | void Con_DrawConsole (float frac); 48 | void Con_Print (char *txt); 49 | //void Con_CenteredPrint (char *text); 50 | void Con_Clear_f (void); 51 | void Con_DrawNotify (void); 52 | void Con_ClearNotify (void); 53 | void Con_ToggleConsole_f (void); 54 | 55 | #endif /*_PRAGMA_CL_CONSOLE_H_*/ 56 | -------------------------------------------------------------------------------- /src/tools/prtool/prtool.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | 10 | 11 | Pliki źródłowe 12 | 13 | 14 | Pliki źródłowe 15 | 16 | 17 | Pliki źródłowe 18 | 19 | 20 | Pliki źródłowe 21 | 22 | 23 | Pliki źródłowe 24 | 25 | 26 | Pliki źródłowe 27 | 28 | 29 | Pliki źródłowe 30 | 31 | 32 | 33 | 34 | Pliki źródłowe 35 | 36 | 37 | Pliki źródłowe 38 | 39 | 40 | -------------------------------------------------------------------------------- /src/common/cvar_public.h: -------------------------------------------------------------------------------- 1 | /* 2 | pragma 3 | Copyright (C) 2023-2024 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | 8 | See the attached GNU General Public License v2 for more details. 9 | */ 10 | 11 | /* 12 | ============================================================== 13 | 14 | cvar_public.h - console variables 15 | 16 | Public interface shared with all pragma modules. 17 | 18 | Nothing outside the Cvar_*() functions should modify cvar_s! 19 | 20 | ============================================================== 21 | */ 22 | 23 | #pragma once 24 | 25 | #ifndef _PRAGMA_CVAR_PUBLIC_H_ 26 | #define _PRAGMA_CVAR_PUBLIC_H_ 27 | 28 | // cvar flags 29 | 30 | #define CVAR_ARCHIVE 1 // set to cause it to be saved to vars.rc 31 | #define CVAR_USERINFO 2 // added to userinfo when changed 32 | #define CVAR_SERVERINFO 4 // added to serverinfo when changed 33 | #define CVAR_NOSET 8 // don't allow change from console at all, but can be set from the command line 34 | #define CVAR_LATCH 16 // save changes until server restart 35 | #define CVAR_CHEAT 32 // set only when cheats are enabled, unused yet 36 | 37 | 38 | typedef struct cvar_s 39 | { 40 | char* name; 41 | char* description; // can be NULL 42 | char* string; 43 | char* latched_string; // for CVAR_LATCH vars 44 | int flags; 45 | qboolean modified; // set each time the cvar is changed 46 | float value; 47 | struct cvar_s* next; 48 | } cvar_t; 49 | 50 | #endif /*_PRAGMA_CVAR_PUBLIC_H_*/ -------------------------------------------------------------------------------- /progs_src/svgame/pers.qc: -------------------------------------------------------------------------------- 1 | /* 2 | pragma engine 3 | Copyright (C) 2023 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | */ 8 | // pers.qc - persistant info across level changes 9 | 10 | /* 11 | MAX_PERS_FIELDS = 64 // for each client and globals 12 | 13 | //client fields 14 | void saveclientfield(entity player, float index, float val) 15 | float loadclientfield(entity player, float index) 16 | 17 | // the better 'serverflags' 18 | void saveglobal(float index, float val) 19 | float loadglobal(float index) 20 | 21 | 22 | float changemap(string nextmap, float saveGlobals, float saveClients) // returns 0 if no map found so we can try unstuck server 23 | */ 24 | 25 | const float PERS_HEALTH = 0; 26 | const float PERS_MAX_HEALTH = 1; 27 | 28 | void(entity player) SaveClientPersData = 29 | { 30 | if(isplayer(player) == 0) 31 | return; 32 | 33 | // give some health if dead or near death 34 | if(player.health < 10) 35 | player.health = 25; 36 | 37 | // cap max health 38 | if(player.max_health > 100) 39 | player.max_health = 100; 40 | 41 | saveclientfield(player, PERS_HEALTH, player.health); 42 | saveclientfield(player, PERS_MAX_HEALTH, player.max_health); 43 | }; 44 | 45 | 46 | void() RestoreClientPers = 47 | { 48 | if( loadclientfield(self, PERS_HEALTH) ) 49 | { 50 | // no health means we probably connected for the first time 51 | return; 52 | } 53 | 54 | self.health = loadclientfield(self, PERS_HEALTH); 55 | self.max_health = loadclientfield(self, PERS_MAX_HEALTH); 56 | }; -------------------------------------------------------------------------------- /progs_src/svgame/ents/devents.qc: -------------------------------------------------------------------------------- 1 | /*QUAKED test_solid (.5 .5 1) (-15 -15 -15) (15 15 15) 2 | 30x30x30 solid box, DEVELOPER_SCRIPT must be enabled 3 | */ 4 | float() SP_test_solid = 5 | { 6 | // test_solid is the classname 7 | // self is the new spawned entity 8 | local float mdl; 9 | if(!developer_script) 10 | return FALSE; 11 | if((mdl = ModelIndex("dev/box_30x30x30")) == 0) 12 | return FALSE; //no model found, delete ent 13 | 14 | SetModelIndex( self, mdl ); 15 | SetSize( self, '-15 -15 -15', '15 15 15' ); 16 | SetSolid( self, SOLID_BBOX ); 17 | 18 | self.movetype = MOVETYPE_NONE; 19 | 20 | return TRUE; 21 | }; 22 | 23 | // ---------------------------------------------------------------------- 24 | 25 | void() viewthing_think = 26 | { 27 | // self.animFrame = (self.animFrame + 1) % 7; 28 | self.nextthink = time + frameTime; 29 | }; 30 | 31 | /*QUAKED viewthing (0 .5 .8) (-8 -8 -8) (8 8 8) 32 | Place one in a level to serve as an animation and model viewer. DEVELOPER_SCRIPT must be enabled 33 | */ 34 | float() SP_viewthing = 35 | { 36 | local float mdl; 37 | 38 | if(!developer_script) 39 | return FALSE; 40 | if((mdl = ModelIndex("objects/banner/tris")) == 0) 41 | return FALSE; // G_FreeEdict(self) 42 | 43 | self.movetype = MOVETYPE_NONE; 44 | self.solid = SOLID_BBOX; 45 | self.renderfx = RF_FRAMELERP; 46 | 47 | SetSize( self, '-16 -16 -24', '16 16 32' ); 48 | SetModelIndex( self, mdl ); 49 | 50 | self.nextthink = time + 0.5; 51 | self.think = viewthing_think; 52 | 53 | dprint( "viewthing spawned\n" ); 54 | return TRUE; //spawned succesfuly 55 | }; -------------------------------------------------------------------------------- /progs_src/inc/pragma_funcs_shared.qc: -------------------------------------------------------------------------------- 1 | // this file was generated by pragma engine version 0.22 (build: Dec 29 2023 21:02:08) 2 | // DO NOT EDIT 3 | // number of builtins: 40 4 | 5 | void(string s, ...) print = #1; 6 | void(string s, ...) dprint = #2; 7 | void() resetrunaway = #3; 8 | void() traceon = #4; 9 | void() traceoff = #5; 10 | void() crash = #6; 11 | void() printstack = #7; 12 | void(string str) localcmd = #8; 13 | float() argc = #9; 14 | string(float idx) argv = #10; 15 | float(string str) cvar = #11; 16 | string(string str) cvarstring = #12; 17 | void(string str, string val, ...) cvarset = #13; 18 | void(string str, string val) cvarforceset = #14; 19 | float(string s) strlen = #15; 20 | string(string s, float idx) strat = #16; 21 | float(string s1, string s2) issubstr = #17; 22 | string(float f) ftos = #18; 23 | float(string s) stof = #19; 24 | string(vector v1) vtos = #20; 25 | void(float ts, string s, ...) logprint = #21; 26 | float(string fn) crcfile = #22; 27 | float(float val) fabs = #23; 28 | float(float val) rint = #24; 29 | float(float val) floor = #25; 30 | float(float val) ceil = #26; 31 | float(float val) sin = #27; 32 | float(float val) cos = #28; 33 | float(float val) sqrt = #29; 34 | vector(vector in) normalize = #30; 35 | float(vector in) vectorlength = #31; 36 | float(vector in) vectoyaw = #32; 37 | vector(vector in) vectoangles = #33; 38 | float() random = #34; 39 | float(float n) randomint = #35; 40 | void(vector v1) anglevectors = #36; 41 | vector(vector v1, vector v2) crossproduct = #37; 42 | float(vector v1, vector v2) dotproduct = #38; 43 | float(float a) anglemod = #39; 44 | float(float a2, float a1, float frac) lerpangle = #40; 45 | -------------------------------------------------------------------------------- /progs_src/svgame/ents/spawnpoints.qc: -------------------------------------------------------------------------------- 1 | // spawnpoints.qc 2 | 3 | /*QUAKED info_player_start (1 0 0) (-16 -16 -24) (16 16 32) 4 | The normal starting point for a level. 5 | */ 6 | 7 | /*QUAKED info_player_intermission (1 0 1) (-16 -16 -24) (16 16 32) 8 | The deathmatch intermission point will be at one of these 9 | Use 'angles' instead of 'angle', so you can set pitch or roll as well as yaw. 'pitch yaw roll' 10 | */ 11 | 12 | /*QUAKED info_player_coop (1 0 1) (-16 -16 -24) (16 16 32) 13 | potential spawning position for coop games 14 | */ 15 | 16 | /*QUAKED info_player_deathmatch (1 0 1) (-16 -16 -24) (16 16 32) 17 | potential spawning position for deathmatch games 18 | */ 19 | 20 | 21 | float() SP_info_player_start = 22 | { 23 | return true; 24 | }; 25 | 26 | 27 | float() SP_info_player_intermission = 28 | { 29 | return true; 30 | }; 31 | 32 | float() SP_info_player_coop = 33 | { 34 | return cvar("coop"); 35 | 36 | }; 37 | 38 | 39 | float() SP_info_player_deathmatch = 40 | { 41 | return cvar("deathmatch"); 42 | }; 43 | 44 | // ===================================================== 45 | 46 | /* 47 | =========== 48 | SelectSpawnPoint 49 | 50 | Chooses a player start, deathmatch start, coop start, etc 51 | ============ 52 | */ 53 | 54 | entity(string spawnpointname) SelectSpawnPoint = 55 | { 56 | entity ent; 57 | 58 | ent = world; 59 | for( ent = nextent(world); ent != world; ent = nextent(ent) ) 60 | { 61 | float num = getentnum(ent); 62 | if( ent.classname == spawnpointname ) 63 | { 64 | break; 65 | } 66 | } 67 | 68 | if( ent == world ) 69 | { 70 | print( spawnpointname, " not found :c\n"); 71 | } 72 | 73 | return ent; 74 | } -------------------------------------------------------------------------------- /src/engine/sizebuf.c: -------------------------------------------------------------------------------- 1 | /* 2 | pragma 3 | Copyright (C) 2023-2024 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | 8 | See the attached GNU General Public License v2 for more details. 9 | */ 10 | 11 | #include "pragma.h" 12 | 13 | void SZ_Init(sizebuf_t* buf, byte* data, const int length) 14 | { 15 | memset(buf, 0, sizeof(*buf)); 16 | buf->data = data; 17 | buf->maxsize = length; 18 | } 19 | 20 | void SZ_Clear(sizebuf_t* buf) 21 | { 22 | buf->cursize = 0; 23 | buf->overflowed = false; 24 | } 25 | 26 | void* SZ_GetSpace(sizebuf_t* buf, const int length) 27 | { 28 | void* data; 29 | 30 | if (buf->cursize + length > buf->maxsize) 31 | { 32 | if (!buf->allowoverflow) 33 | Com_Error(ERR_FATAL, "SZ_GetSpace: overflow without allowoverflow set"); 34 | 35 | if (length > buf->maxsize) 36 | Com_Error(ERR_FATAL, "SZ_GetSpace: %i is > full buffer size", length); 37 | 38 | Com_Printf("SZ_GetSpace: overflow\n"); 39 | SZ_Clear(buf); 40 | buf->overflowed = true; 41 | } 42 | 43 | data = buf->data + buf->cursize; 44 | buf->cursize += length; 45 | 46 | return data; 47 | } 48 | 49 | void SZ_Write(sizebuf_t* buf, void* data, const int length) 50 | { 51 | memcpy(SZ_GetSpace(buf, length), data, length); 52 | } 53 | 54 | void SZ_Print(sizebuf_t* buf, char* data) 55 | { 56 | int len; 57 | 58 | len = (int)strlen(data) + 1; 59 | 60 | if (buf->cursize) 61 | { 62 | if (buf->data[buf->cursize - 1]) 63 | memcpy((byte*)SZ_GetSpace(buf, len), data, len); // no trailing 0 64 | else 65 | memcpy((byte*)SZ_GetSpace(buf, len - 1) - 1, data, len); // write over trailing 0 66 | } 67 | else 68 | memcpy((byte*)SZ_GetSpace(buf, len), data, len); 69 | } 70 | -------------------------------------------------------------------------------- /progs_src/inc/pragma_structs_client.qc: -------------------------------------------------------------------------------- 1 | // DO. NOT. EDIT. 2 | // structures shared with engine 3 | // this must be the first file to compile into client progs! 4 | // add anything at the *end* of the file, it will help you maintaining parity with current server version 5 | 6 | 7 | // ======================================================== 8 | // begin of engine defs 9 | // ======================================================== 10 | 11 | // 12 | // client game globals 13 | // 14 | float frametime; 15 | int time; 16 | float realtime; 17 | 18 | int vid_width; 19 | int vid_height; 20 | 21 | float localplayernum; 22 | 23 | vector v_forward, v_up, v_right; 24 | 25 | float trace_allsolid, trace_startsolid, trace_fraction, trace_plane_dist; 26 | vector trace_endpos, trace_plane_normal; 27 | float trace_entnum; 28 | int trace_contents; 29 | string trace_surface_name; 30 | float trace_surface_flags; 31 | float trace_surface_value; 32 | entity trace_ent; 33 | 34 | float pm_state_pm_type; // byte 35 | vector pm_state_origin; // floats 36 | vector pm_state_velocity; // floats 37 | float pm_state_gravity; // short 38 | vector pm_state_mins; // char [-127,127 range] 39 | vector pm_state_maxs; // char [-127,127 range] 40 | float pm_state_pm_flags; // byte [0-255] 41 | float pm_state_pm_time; // byte [0-255] 42 | vector pm_state_delta_angles; // shorts, use ANGLE2SHORT/SHORT2ANGLE 43 | 44 | vector cam_viewangles; 45 | vector cam_viewoffset; 46 | 47 | void() CG_Main; 48 | void() CG_Frame; 49 | void() CG_DrawGUI; 50 | void(vector cmdMove, vector cmdAngles, float cmdButtons, float cmdMsec) CG_PlayerMove; 51 | void(float inCommand) CG_ServerCommand; 52 | 53 | void end_sys_globals; 54 | 55 | .string str; 56 | .float var1; 57 | .entity ent; 58 | void end_sys_fields; -------------------------------------------------------------------------------- /progs_src/cgame/cg_debug.qc: -------------------------------------------------------------------------------- 1 | /* 2 | pragma engine 3 | Copyright (C) 2023 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | */ 8 | 9 | float debuggui = 1; 10 | 11 | void() debuggui_pmove; 12 | 13 | void() CG_DebugGUI = 14 | { 15 | if(!debuggui) 16 | return; 17 | 18 | if(cvarstring("pmdebug_0") != "none") 19 | { 20 | debuggui_pmove(); 21 | } 22 | }; 23 | 24 | 25 | void() debuggui_pmove = 26 | { 27 | float fsize; 28 | vector xy_align; 29 | string cvarname; 30 | 31 | xy_align = '10 400 0'; 32 | drawfill(xy_align_x-5, xy_align_y-3, 350, 100, '0 0 0', 0.5); 33 | 34 | fsize = 1.2; 35 | drawstring(xy_align, fsize, '0.5 1 0.5', 1, "pmove debug"); 36 | 37 | xy_align_y += 24; 38 | 39 | fsize = 0.9; 40 | 41 | cvarname = "pmdebug_0"; 42 | if(cvarstring(cvarname) != "none") 43 | { 44 | drawstring(xy_align, fsize, '1 1 1', 1, cvarstring(cvarname)); 45 | xy_align_y += 12; 46 | } 47 | 48 | cvarname = "pmdebug_1"; 49 | if(cvarstring(cvarname) != "none") 50 | { 51 | drawstring(xy_align, fsize, '1 1 1', 1, cvarstring(cvarname)); 52 | xy_align_y += 12; 53 | } 54 | 55 | cvarname = "pmdebug_2"; 56 | if(cvarstring(cvarname) != "none") 57 | { 58 | drawstring(xy_align, fsize, '1 1 1', 1, cvarstring(cvarname)); 59 | xy_align_y += 12; 60 | } 61 | 62 | cvarname = "pmdebug_3"; 63 | if(cvarstring(cvarname) != "none") 64 | { 65 | drawstring(xy_align, fsize, '1 1 1', 1, cvarstring(cvarname)); 66 | xy_align_y += 12; 67 | } 68 | 69 | cvarname = "pmdebug_4"; 70 | if(cvarstring(cvarname) != "none") 71 | { 72 | drawstring(xy_align, fsize, '1 1 1', 1, cvarstring(cvarname)); 73 | xy_align_y += 12; 74 | } 75 | 76 | cvarname = "pmdebug_5"; 77 | if(cvarstring(cvarname) != "none") 78 | { 79 | drawstring(xy_align, fsize, '1 1 1', 1, cvarstring(cvarname)); 80 | xy_align_y += 12; 81 | } 82 | }; -------------------------------------------------------------------------------- /progs_src/svgame/ents/spawnflags.qc: -------------------------------------------------------------------------------- 1 | /* 2 | P R A G M A 3 | Copyright (C) 2023 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | */ 8 | 9 | 10 | // 11 | // spawnflags 12 | // 13 | 14 | float SPAWNFLAG_NOT_EASY = 256; 15 | float SPAWNFLAG_NOT_MEDIUM = 512; 16 | float SPAWNFLAG_NOT_HARD = 1024; 17 | float SPAWNFLAG_NOT_DEATHMATCH = 2048; 18 | float SPAWNFLAG_NOT_COOP = 4096; 19 | float SPAWNFLAG_NOT_SINGLEPLAYER = 8192; 20 | 21 | 22 | //func_wall & func_object 23 | float FUNC_SPAWNFLAG_TRIGGER_SPAWN = 1; 24 | float FUNC_SPAWNFLAG_TOGGLE = 2; 25 | float FUNC_SPAWNFLAG_START_ON = 4; 26 | float FUNC_SPAWNFLAG_ANIMATED = 8; 27 | float FUNC_SPAWNFLAG_ANIMATED_FAST = 16; 28 | 29 | // light 30 | float SPAWNFLAG_LIGHTSTART_OFF = 1; 31 | 32 | // misc_model 33 | float SPAWNFLAG_M_MODEL_START_HIDDEN = 1; 34 | 35 | // target_speaker 36 | float SF_SPEAKER_LOOPED_ON = 1; 37 | float SF_SPEAKER_LOOPED_OFF = 2; 38 | float SF_SPEAKER_RELIABLE = 4; 39 | 40 | 41 | /* 42 | ============ 43 | CheckSpawnFlags 44 | 45 | used to discard entities from various gametypes and skill levels, etc. 46 | ============ 47 | */ 48 | float() CheckSpawnFlags = 49 | { 50 | if((cvar_deathmatch > 0) && (self.spawnflags & SPAWNFLAG_NOT_DEATHMATCH)) 51 | return false; // not in deathmatch 52 | 53 | if( (cvar_coop > 0) && (self.spawnflags & SPAWNFLAG_NOT_COOP) ) 54 | return false; // not in coop 55 | 56 | if( cvar_coop == 0 && cvar_deathmatch == 0 && (self.spawnflags & SPAWNFLAG_NOT_SINGLEPLAYER) ) 57 | return false; // not in singleplayer 58 | 59 | if( cvar_skill == 0 && (self.spawnflags & SPAWNFLAG_NOT_EASY) ) 60 | return false; // not on EASY 61 | if( cvar_skill == 1 && (self.spawnflags & SPAWNFLAG_NOT_MEDIUM) ) 62 | return false; // not on MEDIUM 63 | if( cvar_skill == 2 && (self.spawnflags & SPAWNFLAG_NOT_HARD) ) 64 | return false; // not on HARD 65 | 66 | return true; 67 | }; -------------------------------------------------------------------------------- /progs_src/svgame/ents/prop_model.qc: -------------------------------------------------------------------------------- 1 | /* 2 | P R A G M A 3 | Copyright (C) 2023 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | */ 8 | 9 | /*QUAKED prop_model (0.5 0.5 0) (-16 -16 -16) (16 16 6) START_HIDDEN 10 | model for decorations 11 | 12 | START_HIDDEN - must be triggered to show 13 | 14 | "model" model or sprite to render 15 | "animFrame" animation frame (default 0) 16 | "solid" set to 1 to make it collidable (default 0) 17 | "mins" bbox mins for collision (default '-16 -16 0') 18 | "maxs" bbox maxs for collision (default '16 16 32') 19 | */ 20 | 21 | void(entity activ) prop_model_use = 22 | { 23 | if (self.spawnflags & SPAWNFLAG_M_MODEL_START_HIDDEN) 24 | { 25 | self.svflags = 0; 26 | self.spawnflags &= ~SPAWNFLAG_M_MODEL_START_HIDDEN; 27 | } 28 | else 29 | { 30 | self.svflags = SVF_NOCLIENT; 31 | self.spawnflags |= SPAWNFLAG_M_MODEL_START_HIDDEN; 32 | } 33 | }; 34 | 35 | 36 | float() SP_prop_model = 37 | { 38 | if( !strlen(self.model) ) 39 | { 40 | dprint("prop_model with no model at ", vtos(self.origin), ", removed\n"); 41 | return false; 42 | } 43 | 44 | if (self.spawnflags & SPAWNFLAG_M_MODEL_START_HIDDEN) 45 | { 46 | if( !strlen(self.targetname) ) 47 | { 48 | dprint("prop_model with START_HIDDEN flag at ", vtos(self.origin), " has no targetname, removed\n"); 49 | return false; 50 | } 51 | self.svflags = SVF_NOCLIENT; 52 | } 53 | 54 | precache_model(self.model); 55 | setmodel(self, self.model); 56 | 57 | if( self.animFrame < 0 ) 58 | self.animFrame = 0; 59 | 60 | if( self.solid ) 61 | { 62 | self.solid = SOLID_BBOX; 63 | if( self.mins == vec3_origin || self.maxs == vec3_origin ) 64 | { 65 | self.mins = '-16 -16 0'; 66 | self.maxs = '16 16 32'; 67 | } 68 | setsize(self, self.mins, self.maxs); 69 | } 70 | 71 | self.movetype = MOVETYPE_NONE; 72 | self.use = prop_model_use; 73 | linkentity(self); 74 | return true; 75 | }; -------------------------------------------------------------------------------- /src/engine/pragma.rc: -------------------------------------------------------------------------------- 1 | //Microsoft Developer Studio generated resource script. 2 | // 3 | #include "resource.h" 4 | 5 | #define APSTUDIO_READONLY_SYMBOLS 6 | ///////////////////////////////////////////////////////////////////////////// 7 | // 8 | // Generated from the TEXTINCLUDE 2 resource. 9 | // 10 | #include "windows.h" 11 | 12 | ///////////////////////////////////////////////////////////////////////////// 13 | #undef APSTUDIO_READONLY_SYMBOLS 14 | 15 | ///////////////////////////////////////////////////////////////////////////// 16 | // English (U.S.) resources 17 | 18 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) 19 | #ifdef _WIN32 20 | LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US 21 | #pragma code_page(1252) 22 | #endif //_WIN32 23 | 24 | #ifdef APSTUDIO_INVOKED 25 | ///////////////////////////////////////////////////////////////////////////// 26 | // 27 | // TEXTINCLUDE 28 | // 29 | 30 | 1 TEXTINCLUDE DISCARDABLE 31 | BEGIN 32 | "resource.h\0" 33 | END 34 | 35 | 2 TEXTINCLUDE DISCARDABLE 36 | BEGIN 37 | "#include ""afxres.h""\r\n" 38 | "\0" 39 | END 40 | 41 | 3 TEXTINCLUDE DISCARDABLE 42 | BEGIN 43 | "\r\n" 44 | "\0" 45 | END 46 | 47 | #endif // APSTUDIO_INVOKED 48 | 49 | 50 | ///////////////////////////////////////////////////////////////////////////// 51 | // 52 | // Icon 53 | // 54 | 55 | // Icon with lowest ID value placed first to ensure application icon 56 | // remains consistent on all systems. 57 | IDI_ICON1 ICON DISCARDABLE "pragma.ico" 58 | #endif // English (U.S.) resources 59 | ///////////////////////////////////////////////////////////////////////////// 60 | 61 | 62 | 63 | #ifndef APSTUDIO_INVOKED 64 | ///////////////////////////////////////////////////////////////////////////// 65 | // 66 | // Generated from the TEXTINCLUDE 3 resource. 67 | // 68 | 69 | 70 | ///////////////////////////////////////////////////////////////////////////// 71 | #endif // not APSTUDIO_INVOKED 72 | 73 | -------------------------------------------------------------------------------- /src/engine/client/ui/ui_local.h: -------------------------------------------------------------------------------- 1 | /* 2 | pragma 3 | Copyright (C) 2023-2024 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | 8 | See the attached GNU General Public License v2 for more details. 9 | */ 10 | 11 | #pragma once 12 | 13 | #define GUI_LIST_IDENT "PRAGMA_PRELOAD_GUIS" 14 | 15 | #define GUI_IDENT "PRAGMA_GUI" 16 | #define GUI_VERSION 1 17 | 18 | #define MAX_GUIS 64 19 | #define MAX_ITEMS_PER_GUI 256 20 | #define MAX_GUI_ITEMS 4096 21 | 22 | 23 | 24 | typedef struct ui_item_s 25 | { 26 | qboolean inuse; 27 | int gui; // index to ui.guis 28 | 29 | ui_itemvars_t v; //qc 30 | } ui_item_t; 31 | 32 | typedef struct GuiDef_s 33 | { 34 | char name[MAX_QPATH]; 35 | 36 | qboolean active; 37 | int openTime; // cl.realtime, qsorted 38 | 39 | ui_item_t *items[MAX_ITEMS_PER_GUI]; 40 | ui_item_t *items_default[MAX_ITEMS_PER_GUI]; 41 | 42 | int numItems; 43 | 44 | // qc 45 | scr_func_t Callback_Active; 46 | scr_func_t Callback_OnOpen; 47 | scr_func_t Callback_OnClose; 48 | scr_func_t Callback_OnKey; 49 | } GuiDef_t; 50 | 51 | typedef struct uistate_s 52 | { 53 | GuiDef_t *guis[MAX_GUIS]; 54 | int numGuis; 55 | 56 | int itemDef_size; 57 | int itemDefs_limit; 58 | int itemDefs_current; 59 | 60 | ui_globalvars_t *script_globals; 61 | ui_item_t *itemDefs; 62 | } uistate_t; 63 | 64 | 65 | extern GuiDef_t* current_gui; 66 | extern ui_item_t* current_item; 67 | 68 | extern uistate_t ui; 69 | 70 | // 71 | // ui_main.c 72 | // 73 | extern GuiDef_t* UI_FindGui(char* name); 74 | extern ui_item_t* UI_CreateItemDef(GuiDef_t* menu); 75 | 76 | // 77 | // ui_load.c 78 | // 79 | extern qboolean UI_LoadGui(char* guiname); 80 | extern void UI_LoadGuisFromFile(char* name); 81 | 82 | // 83 | // ui_actions.c 84 | // 85 | void UI_AddAction(const char* cmd_name, xcommand_t function, scr_func_t progfunc); 86 | void UI_RemoveActions(); 87 | void UI_ExecuteAction(const char* actionstring); 88 | void UI_InitActions(); -------------------------------------------------------------------------------- /progs_src/ui/fteqc_ext.qc: -------------------------------------------------------------------------------- 1 | #pragma opcode enable STORE_I 2 | #pragma opcode enable STORE_IF 3 | #pragma opcode enable STORE_FI 4 | 5 | #pragma opcode enable ADD_I 6 | #pragma opcode enable ADD_FI 7 | #pragma opcode enable ADD_IF 8 | 9 | #pragma opcode enable SUB_I 10 | #pragma opcode enable SUB_FI 11 | #pragma opcode enable SUB_IF 12 | 13 | #pragma opcode enable C_ITOF //CONV_ITOF 14 | #pragma opcode enable C_FTOI //CONV_FTOI 15 | #pragma opcode enable LOADF_I //LOAD_I 16 | #pragma opcode enable STOREP_I 17 | #pragma opcode enable STOREP_IF 18 | #pragma opcode enable STOREP_FI 19 | 20 | #pragma opcode enable BITAND_I 21 | #pragma opcode enable BITOR_I 22 | 23 | #pragma opcode enable MUL_I 24 | #pragma opcode enable DIV_I 25 | #pragma opcode enable EQ_I 26 | #pragma opcode enable NE_I 27 | 28 | #pragma opcode enable NOT_I 29 | 30 | #pragma opcode enable BITXOR_I 31 | #pragma opcode enable RSHIFT_I 32 | #pragma opcode enable LSHIFT_I 33 | #pragma opcode enable LE_I 34 | #pragma opcode enable GE_I 35 | #pragma opcode enable LT_I 36 | #pragma opcode enable GT_I 37 | 38 | #pragma opcode enable LE_IF 39 | #pragma opcode enable GE_IF 40 | #pragma opcode enable LT_IF 41 | #pragma opcode enable GT_IF 42 | 43 | #pragma opcode enable LE_FI 44 | #pragma opcode enable GE_FI 45 | #pragma opcode enable LT_FI 46 | #pragma opcode enable GT_FI 47 | 48 | #pragma opcode enable EQ_IF 49 | #pragma opcode enable EQ_FI 50 | 51 | #pragma opcode enable MUL_IF 52 | #pragma opcode enable MUL_FI 53 | #pragma opcode enable MUL_VI 54 | #pragma opcode enable MUL_IV 55 | #pragma opcode enable DIV_IF 56 | #pragma opcode enable DIV_FI 57 | #pragma opcode enable BITAND_IF 58 | #pragma opcode enable BITOR_IF 59 | #pragma opcode enable BITAND_FI 60 | #pragma opcode enable BITOR_FI 61 | #pragma opcode enable AND_I 62 | #pragma opcode enable OR_I 63 | #pragma opcode enable AND_IF 64 | #pragma opcode enable OR_IF 65 | #pragma opcode enable AND_FI 66 | #pragma opcode enable OR_FI 67 | #pragma opcode enable NE_IF 68 | #pragma opcode enable NE_FI -------------------------------------------------------------------------------- /progs_src/cgame/fteqc_ext.qc: -------------------------------------------------------------------------------- 1 | #pragma opcode enable STORE_I 2 | #pragma opcode enable STORE_IF 3 | #pragma opcode enable STORE_FI 4 | 5 | #pragma opcode enable ADD_I 6 | #pragma opcode enable ADD_FI 7 | #pragma opcode enable ADD_IF 8 | 9 | #pragma opcode enable SUB_I 10 | #pragma opcode enable SUB_FI 11 | #pragma opcode enable SUB_IF 12 | 13 | #pragma opcode enable C_ITOF //CONV_ITOF 14 | #pragma opcode enable C_FTOI //CONV_FTOI 15 | #pragma opcode enable LOADF_I //LOAD_I 16 | #pragma opcode enable STOREP_I 17 | #pragma opcode enable STOREP_IF 18 | #pragma opcode enable STOREP_FI 19 | 20 | #pragma opcode enable BITAND_I 21 | #pragma opcode enable BITOR_I 22 | 23 | #pragma opcode enable MUL_I 24 | #pragma opcode enable DIV_I 25 | #pragma opcode enable EQ_I 26 | #pragma opcode enable NE_I 27 | 28 | #pragma opcode enable NOT_I 29 | 30 | #pragma opcode enable BITXOR_I 31 | #pragma opcode enable RSHIFT_I 32 | #pragma opcode enable LSHIFT_I 33 | #pragma opcode enable LE_I 34 | #pragma opcode enable GE_I 35 | #pragma opcode enable LT_I 36 | #pragma opcode enable GT_I 37 | 38 | #pragma opcode enable LE_IF 39 | #pragma opcode enable GE_IF 40 | #pragma opcode enable LT_IF 41 | #pragma opcode enable GT_IF 42 | 43 | #pragma opcode enable LE_FI 44 | #pragma opcode enable GE_FI 45 | #pragma opcode enable LT_FI 46 | #pragma opcode enable GT_FI 47 | 48 | #pragma opcode enable EQ_IF 49 | #pragma opcode enable EQ_FI 50 | 51 | #pragma opcode enable MUL_IF 52 | #pragma opcode enable MUL_FI 53 | #pragma opcode enable MUL_VI 54 | #pragma opcode enable MUL_IV 55 | #pragma opcode enable DIV_IF 56 | #pragma opcode enable DIV_FI 57 | #pragma opcode enable BITAND_IF 58 | #pragma opcode enable BITOR_IF 59 | #pragma opcode enable BITAND_FI 60 | #pragma opcode enable BITOR_FI 61 | #pragma opcode enable AND_I 62 | #pragma opcode enable OR_I 63 | #pragma opcode enable AND_IF 64 | #pragma opcode enable OR_IF 65 | #pragma opcode enable AND_FI 66 | #pragma opcode enable OR_FI 67 | #pragma opcode enable NE_IF 68 | #pragma opcode enable NE_FI -------------------------------------------------------------------------------- /progs_src/svgame/fteqc_ext.qc: -------------------------------------------------------------------------------- 1 | #pragma opcode enable STORE_I 2 | #pragma opcode enable STORE_IF 3 | #pragma opcode enable STORE_FI 4 | 5 | #pragma opcode enable ADD_I 6 | #pragma opcode enable ADD_FI 7 | #pragma opcode enable ADD_IF 8 | 9 | #pragma opcode enable SUB_I 10 | #pragma opcode enable SUB_FI 11 | #pragma opcode enable SUB_IF 12 | 13 | #pragma opcode enable C_ITOF //CONV_ITOF 14 | #pragma opcode enable C_FTOI //CONV_FTOI 15 | #pragma opcode enable LOADF_I //LOAD_I 16 | #pragma opcode enable STOREP_I 17 | #pragma opcode enable STOREP_IF 18 | #pragma opcode enable STOREP_FI 19 | 20 | #pragma opcode enable BITAND_I 21 | #pragma opcode enable BITOR_I 22 | 23 | #pragma opcode enable MUL_I 24 | #pragma opcode enable DIV_I 25 | #pragma opcode enable EQ_I 26 | #pragma opcode enable NE_I 27 | 28 | #pragma opcode enable NOT_I 29 | 30 | #pragma opcode enable BITXOR_I 31 | #pragma opcode enable RSHIFT_I 32 | #pragma opcode enable LSHIFT_I 33 | #pragma opcode enable LE_I 34 | #pragma opcode enable GE_I 35 | #pragma opcode enable LT_I 36 | #pragma opcode enable GT_I 37 | 38 | #pragma opcode enable LE_IF 39 | #pragma opcode enable GE_IF 40 | #pragma opcode enable LT_IF 41 | #pragma opcode enable GT_IF 42 | 43 | #pragma opcode enable LE_FI 44 | #pragma opcode enable GE_FI 45 | #pragma opcode enable LT_FI 46 | #pragma opcode enable GT_FI 47 | 48 | #pragma opcode enable EQ_IF 49 | #pragma opcode enable EQ_FI 50 | 51 | #pragma opcode enable MUL_IF 52 | #pragma opcode enable MUL_FI 53 | #pragma opcode enable MUL_VI 54 | #pragma opcode enable MUL_IV 55 | #pragma opcode enable DIV_IF 56 | #pragma opcode enable DIV_FI 57 | #pragma opcode enable BITAND_IF 58 | #pragma opcode enable BITOR_IF 59 | #pragma opcode enable BITAND_FI 60 | #pragma opcode enable BITOR_FI 61 | #pragma opcode enable AND_I 62 | #pragma opcode enable OR_I 63 | #pragma opcode enable AND_IF 64 | #pragma opcode enable OR_IF 65 | #pragma opcode enable AND_FI 66 | #pragma opcode enable OR_FI 67 | #pragma opcode enable NE_IF 68 | #pragma opcode enable NE_FI -------------------------------------------------------------------------------- /progs_src/inc/fteqc_ext.qc: -------------------------------------------------------------------------------- 1 | /* 2 | P R A G M A 3 | Copyright (C) 2023 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | */ 8 | 9 | #pragma opcode enable STORE_I 10 | #pragma opcode enable STORE_IF 11 | #pragma opcode enable STORE_FI 12 | #pragma opcode enable ADD_I 13 | #pragma opcode enable ADD_FI 14 | #pragma opcode enable ADD_IF 15 | #pragma opcode enable SUB_I 16 | #pragma opcode enable SUB_FI 17 | #pragma opcode enable SUB_IF 18 | #pragma opcode enable C_ITOF // CONV_ITOF 19 | #pragma opcode enable C_FTOI // CONV_FTOI 20 | #pragma opcode enable LOADF_I // LOAD_I 21 | #pragma opcode enable STOREP_I 22 | #pragma opcode enable STOREP_IF 23 | #pragma opcode enable STOREP_FI 24 | #pragma opcode enable BITAND_I 25 | #pragma opcode enable BITOR_I 26 | #pragma opcode enable MUL_I 27 | #pragma opcode enable DIV_I 28 | #pragma opcode enable EQ_I 29 | #pragma opcode enable NE_I 30 | #pragma opcode enable NOT_I 31 | #pragma opcode enable BITXOR_I 32 | #pragma opcode enable RSHIFT_I 33 | #pragma opcode enable LSHIFT_I 34 | #pragma opcode enable LE_I 35 | #pragma opcode enable GE_I 36 | #pragma opcode enable LT_I 37 | #pragma opcode enable GT_I 38 | #pragma opcode enable LE_IF 39 | #pragma opcode enable GE_IF 40 | #pragma opcode enable LT_IF 41 | #pragma opcode enable GT_IF 42 | #pragma opcode enable LE_FI 43 | #pragma opcode enable GE_FI 44 | #pragma opcode enable LT_FI 45 | #pragma opcode enable GT_FI 46 | #pragma opcode enable EQ_IF 47 | #pragma opcode enable EQ_FI 48 | #pragma opcode enable MUL_IF 49 | #pragma opcode enable MUL_FI 50 | #pragma opcode enable MUL_VI 51 | #pragma opcode enable MUL_IV 52 | #pragma opcode enable DIV_IF 53 | #pragma opcode enable DIV_FI 54 | #pragma opcode enable BITAND_IF 55 | #pragma opcode enable BITOR_IF 56 | #pragma opcode enable BITAND_FI 57 | #pragma opcode enable BITOR_FI 58 | #pragma opcode enable AND_I 59 | #pragma opcode enable OR_I 60 | #pragma opcode enable AND_IF 61 | #pragma opcode enable OR_IF 62 | #pragma opcode enable AND_FI 63 | #pragma opcode enable OR_FI 64 | #pragma opcode enable NE_IF 65 | #pragma opcode enable NE_FI -------------------------------------------------------------------------------- /src/engine/message.h: -------------------------------------------------------------------------------- 1 | /* 2 | pragma 3 | Copyright (C) 2023-2024 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | 8 | See the attached GNU General Public License v2 for more details. 9 | */ 10 | 11 | /* 12 | ============================================================== 13 | 14 | MESSAGE IO FUNCTIONS 15 | 16 | Handles byte ordering and avoids alignment errors. 17 | 18 | ============================================================== 19 | */ 20 | 21 | #pragma once 22 | 23 | #ifndef _PRAGMA_MESSAGE_H_ 24 | #define _PRAGMA_MESSAGE_H_ 25 | 26 | // TODO: move MSG_WriteDeltaEntity out of here? 27 | 28 | void MSG_WriteDeltaEntity(entity_state_t* from, entity_state_t* to, sizebuf_t* msg, qboolean force, qboolean newentity); 29 | 30 | void MSG_WriteChar(sizebuf_t* sb, int c); 31 | void MSG_WriteByte(sizebuf_t* sb, int c); 32 | void MSG_WriteShort(sizebuf_t* sb, int c); 33 | void MSG_WriteLong(sizebuf_t* sb, int c); 34 | void MSG_WriteFloat(sizebuf_t* sb, float f); 35 | void MSG_WriteString(sizebuf_t* sb, const char* s); 36 | void MSG_WriteCoord(sizebuf_t* sb, float f); 37 | void MSG_WritePos(sizebuf_t* sb, vec3_t pos); 38 | void MSG_WriteAngle(sizebuf_t* sb, float f); 39 | void MSG_WriteAngle16(sizebuf_t* sb, float f); 40 | void MSG_WriteDir(sizebuf_t* sb, vec3_t vector); 41 | 42 | void MSG_BeginReading(sizebuf_t* sb); 43 | 44 | int MSG_ReadChar(sizebuf_t* sb); 45 | int MSG_ReadByte(sizebuf_t* sb); 46 | int MSG_ReadShort(sizebuf_t* sb); 47 | int MSG_ReadLong(sizebuf_t* sb); 48 | float MSG_ReadFloat(sizebuf_t* sb); 49 | char *MSG_ReadString(sizebuf_t* sb); 50 | char *MSG_ReadStringLine(sizebuf_t* sb); 51 | float MSG_ReadCoord(sizebuf_t* sb); 52 | void MSG_ReadPos(sizebuf_t* sb, vec3_t pos); 53 | float MSG_ReadAngle(sizebuf_t* sb); 54 | float MSG_ReadAngle16(sizebuf_t* sb); 55 | void MSG_ReadDir(sizebuf_t* sb, vec3_t vector); 56 | void MSG_ReadData(sizebuf_t* sb, void* buffer, int size); 57 | 58 | int MSG_PackSolid32(const vec3_t mins, const vec3_t maxs); 59 | void MSG_UnpackSolid32(int packedsolid, vec3_t mins, vec3_t maxs); 60 | 61 | 62 | #endif /*_PRAGMA_MESSAGE_H_*/ 63 | -------------------------------------------------------------------------------- /.github/workflows/msbuild-release-x86.yml: -------------------------------------------------------------------------------- 1 | # This workflow uses actions that are not certified by GitHub. 2 | # They are provided by a third-party and are governed by 3 | # separate terms of service, privacy policy, and support 4 | # documentation. 5 | 6 | name: Release 32bit 7 | 8 | on: 9 | push: 10 | branches: [ "main" ] 11 | pull_request: 12 | branches: [ "main" ] 13 | workflow_dispatch: 14 | branches: [ "main" ] 15 | 16 | env: 17 | # Path to the solution file relative to the root of the project. 18 | SOLUTION_FILE_PATH: ./src/pragma.sln 19 | 20 | # Configuration type to build. 21 | # You can convert this to a build matrix if you need coverage of multiple configuration types. 22 | # https://docs.github.com/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix 23 | BUILD_CONFIGURATION: Release 24 | BUILD_PLATFORM: x86 25 | 26 | permissions: 27 | contents: read 28 | 29 | jobs: 30 | build: 31 | runs-on: windows-latest 32 | 33 | steps: 34 | - uses: actions/checkout@v3 35 | 36 | - name: Add MSBuild to PATH 37 | uses: microsoft/setup-msbuild@v1.0.2 38 | 39 | - name: Restore NuGet packages 40 | working-directory: ${{env.GITHUB_WORKSPACE}} 41 | run: nuget restore ${{env.SOLUTION_FILE_PATH}} 42 | 43 | - name: Build 44 | working-directory: ${{env.GITHUB_WORKSPACE}} 45 | # Add additional options to the MSBuild command line here (like platform or verbosity level). 46 | # See https://docs.microsoft.com/visualstudio/msbuild/msbuild-command-line-reference 47 | run: msbuild /m /p:Configuration=${{env.BUILD_CONFIGURATION}} /p:Platform=${{env.BUILD_PLATFORM}} ${{env.SOLUTION_FILE_PATH}} 48 | 49 | - name: Generate MSBuild archives 50 | uses: actions/upload-artifact@v3 51 | with: 52 | name: pragma-release-win-${{env.BUILD_PLATFORM}} 53 | path: | 54 | build/pragma.exe 55 | build/pragma_server.exe 56 | build/pragma_renderer_gl2_x86.dll 57 | build/prtool.exe 58 | build/prtool.qc 59 | build/main/dummy.txt 60 | readme.txt 61 | -------------------------------------------------------------------------------- /src/engine/network.h: -------------------------------------------------------------------------------- 1 | /* 2 | pragma 3 | Copyright (C) 2023-2024 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | 8 | See the attached GNU General Public License v2 for more details. 9 | */ 10 | 11 | /* 12 | ============================================================== 13 | 14 | NETWORK 15 | 16 | Pragma's interface to the networking layer. 17 | 18 | ============================================================== 19 | */ 20 | 21 | #pragma once 22 | 23 | #ifndef _PRAGMA_NETWORK_H_ 24 | #define _PRAGMA_NETWORK_H_ 25 | 26 | // minimum rate in bytes per second, was absurdly low 100 in Q2 27 | #define NET_RATE_MIN 5000 28 | 29 | // maximum rate in bytes per second 30 | #define NET_RATE_MAX 25000 31 | 32 | // default rate in bytes per second, was 5000 in Q2 33 | #define NET_RATE_DEFAULT 15000 34 | 35 | 36 | // ditto. 37 | #define PORT_ANY -1 38 | 39 | // master server port 40 | #define PORT_MASTER 27900 41 | 42 | // default port for clients 43 | #define PORT_CLIENT 27901 44 | 45 | // default port for game servers 46 | #define PORT_SERVER 27910 47 | 48 | // max length of a message 49 | #define MAX_MSGLEN 1400 50 | 51 | // size of header in each packet two ints and a short 52 | //#define PACKET_HEADER 10 // braxi: commented out, unused 53 | 54 | typedef enum { NA_LOOPBACK, NA_BROADCAST, NA_IP } netadrtype_t; 55 | 56 | typedef enum { NS_CLIENT, NS_SERVER } netsrc_t; 57 | 58 | typedef struct 59 | { 60 | netadrtype_t type; 61 | byte ip[4]; 62 | unsigned short port; 63 | } netadr_t; 64 | 65 | void NET_Init(void); 66 | void NET_Shutdown(void); 67 | 68 | void NET_Config(qboolean multiplayer); 69 | 70 | qboolean NET_GetPacket(netsrc_t sock, netadr_t* net_from, sizebuf_t* net_message); 71 | void NET_SendPacket(netsrc_t sock, int length, void* data, netadr_t to); 72 | 73 | qboolean NET_CompareAdr(netadr_t a, netadr_t b); 74 | qboolean NET_CompareBaseAdr(netadr_t a, netadr_t b); 75 | qboolean NET_IsLocalAddress(netadr_t adr); 76 | char *NET_AdrToString(netadr_t a); 77 | qboolean NET_StringToAdr(char* s, netadr_t* a); 78 | void NET_Sleep(int msec); 79 | 80 | 81 | #endif /*_PRAGMA_NETWORK_H_*/ 82 | -------------------------------------------------------------------------------- /.github/workflows/msbuild-release-x64.yml: -------------------------------------------------------------------------------- 1 | # This workflow uses actions that are not certified by GitHub. 2 | # They are provided by a third-party and are governed by 3 | # separate terms of service, privacy policy, and support 4 | # documentation. 5 | 6 | name: Release 64bit 7 | 8 | on: 9 | push: 10 | branches: [ "main" ] 11 | pull_request: 12 | branches: [ "main" ] 13 | workflow_dispatch: 14 | branches: [ "main" ] 15 | 16 | env: 17 | # Path to the solution file relative to the root of the project. 18 | SOLUTION_FILE_PATH: ./src/pragma.sln 19 | 20 | # Configuration type to build. 21 | # You can convert this to a build matrix if you need coverage of multiple configuration types. 22 | # https://docs.github.com/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix 23 | BUILD_CONFIGURATION: Release 24 | BUILD_PLATFORM: x64 25 | 26 | permissions: 27 | contents: read 28 | 29 | jobs: 30 | build: 31 | runs-on: windows-latest 32 | 33 | steps: 34 | - uses: actions/checkout@v3 35 | 36 | - name: Add MSBuild to PATH 37 | uses: microsoft/setup-msbuild@v1.0.2 38 | 39 | - name: Restore NuGet packages 40 | working-directory: ${{env.GITHUB_WORKSPACE}} 41 | run: nuget restore ${{env.SOLUTION_FILE_PATH}} 42 | 43 | - name: Build 44 | working-directory: ${{env.GITHUB_WORKSPACE}} 45 | # Add additional options to the MSBuild command line here (like platform or verbosity level). 46 | # See https://docs.microsoft.com/visualstudio/msbuild/msbuild-command-line-reference 47 | run: msbuild /m /p:Configuration=${{env.BUILD_CONFIGURATION}} /p:Platform=${{env.BUILD_PLATFORM}} ${{env.SOLUTION_FILE_PATH}} 48 | 49 | - name: Generate MSBuild archives 50 | uses: actions/upload-artifact@v3 51 | with: 52 | name: pragma-release-win-${{env.BUILD_PLATFORM}} 53 | path: | 54 | build/pragma_x64.exe 55 | build/pragma_server_x64.exe 56 | build/pragma_renderer_gl2_x64.dll 57 | build/prtool.exe 58 | build/prtool.qc 59 | build/main/dummy.txt 60 | readme.txt 61 | -------------------------------------------------------------------------------- /src/engine/client/cgame/cg_local.h: -------------------------------------------------------------------------------- 1 | /* 2 | pragma 3 | Copyright (C) 2023-2024 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | 8 | See the attached GNU General Public License v2 for more details. 9 | */ 10 | 11 | #pragma once 12 | 13 | typedef struct 14 | { 15 | int length; 16 | float value[3]; 17 | float map[MAX_QPATH]; 18 | } CLightStyle_t; 19 | 20 | typedef struct 21 | { 22 | dLightType_t type; 23 | int key; // so entities can reuse same entry 24 | vec3_t color; 25 | vec3_t origin; 26 | float radius; 27 | float die; // stop lighting after this time 28 | float decay; // drop this each second 29 | float minlight; // don't add when contributing less 30 | 31 | vec3_t dir; 32 | float cutoff; 33 | } cdlight_t; 34 | 35 | typedef struct localEntity_s 36 | { 37 | struct localEntity_s* prev, * next; 38 | 39 | // float lifeRate; // 1.0 / (endTime - startTime) 40 | 41 | vec3_t origin; 42 | vec3_t angles; 43 | 44 | rentity_t refEntity; 45 | 46 | } localEntity_t; 47 | 48 | 49 | // 50 | // cg_dlights.c 51 | // 52 | void CG_ClearDynamicLights(); 53 | cdlight_t* CG_AllocDynamicLight(int key); 54 | void CL_NewDynamicPointLight(int key, float x, float y, float z, float radius, float time); 55 | void CL_NewDynamicSpotLight(int key, float x, float y, float z, vec3_t dir, float radius, float cutoff, float time); 56 | 57 | // 58 | // cg_lightstyles.c 59 | // 60 | void CG_ClearLightStyles(); 61 | 62 | 63 | // 64 | // cg_particles.c 65 | // 66 | void CG_ClearParticles(); 67 | cparticle_t* CG_ParticleFromPool(); 68 | qboolean CG_AreThereFreeParticles(); 69 | void CG_GenericParticleEffect(vec3_t org, vec3_t dir, vec3_t color, int count, int dirspread, float alphavel, float gravity); 70 | void CG_ParseParticleEffectCommand(); 71 | 72 | 73 | // 74 | // cg_physics.c 75 | // 76 | trace_t CG_Trace(vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int contentsMask, int ignoreEntNum); 77 | int CG_PointContents(vec3_t point); 78 | 79 | 80 | // 81 | // cg_localents.c 82 | // 83 | //void CG_InitLocalEntities(); 84 | //void CG_FreeEntity(localEntity_t* le); 85 | //localEntity_t* CG_AllocLocalEntity(); -------------------------------------------------------------------------------- /progs_src/svgame/ents/worldspawn.qc: -------------------------------------------------------------------------------- 1 | 2 | void() HUD_Init; 3 | 4 | /*QUAKED worldspawn (0 0 0) ? 5 | 6 | Only used for the world. 7 | "sky" environment map name (env/_*.tga) 8 | "skyaxis" axis of sky rotation 9 | "skyrotate" speed of rotation in degrees/second 10 | "gravity" 800 is default gravity 11 | "message" text to print at user logon 12 | */ 13 | float() SP_worldspawn = 14 | { 15 | // never change these three lines or weird shit will happen 16 | self.movetype = MOVETYPE_PUSH; 17 | self.solid = SOLID_BSP; 18 | self.modelindex = 1; // world model MUST always be index 1 19 | 20 | 21 | // make some data visible to the server 22 | 23 | // --- LEVEL NAME --- 24 | if(strlen(self.message) == 0) 25 | { 26 | self.message = "unknown map"; 27 | print("WARNING: worldspawn with no 'message' set\n"); 28 | } 29 | configstring(CS_NAME, self.message); 30 | 31 | // --- SKYBOX --- 32 | if( self.skyrotate != 0 && self.skyaxis == vec3_origin ) 33 | { 34 | // cannot rotate sky when skyaxis is 0,0,0 35 | self.skyrotate = 0; 36 | print("WARNING: sky rotation disabled, wrong worldspawn skyaxis vector\n"); 37 | } 38 | if(strlen(self.sky) == 0) 39 | { 40 | // use default sky 41 | self.sky = "black"; 42 | print("WARNING: map with no worldspawn sky set, using sky 'none'\n"); 43 | } 44 | 45 | if( self.skycolor == vec3_origin ) 46 | self.skycolor = '1 1 1'; 47 | 48 | configstring(CS_SKY, self.sky); 49 | configstring(CS_SKYROTATE, ftos(self.skyrotate) ); 50 | configstring(CS_SKYAXIS, vtos(self.skyaxis) ); 51 | configstring(CS_SKYCOLOR, vtos(self.skycolor) ); 52 | 53 | // --- make max clients visible --- 54 | float maxc; 55 | maxc = cvar("sv_maxclients"); 56 | configstring(CS_MAXCLIENTS, ftos(maxc)); //FIXME 57 | 58 | // --- GRAVITY --- 59 | if(!self.gravity) 60 | self.gravity = 800; 61 | cvarforceset("sv_gravity", ftos(self.gravity)); // force set 62 | 63 | // precache sounds that are used in C physics code 64 | precache_sound("world/land.wav"); 65 | precache_sound("misc/h2ohit1.wav"); 66 | 67 | // initialize g_weapons array 68 | BG_InitWeapons(); 69 | 70 | // initialize hud 71 | HUD_Init(); 72 | 73 | // create lightstyles 74 | InitLightStyles(); 75 | 76 | return true; 77 | }; 78 | -------------------------------------------------------------------------------- /src/engine/cmodel.h: -------------------------------------------------------------------------------- 1 | /* 2 | pragma 3 | Copyright (C) 2023-2024 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | 8 | See the attached GNU General Public License v2 for more details. 9 | */ 10 | 11 | 12 | /* 13 | ============================================================== 14 | COLLISION MODEL 15 | ============================================================== 16 | */ 17 | 18 | #pragma once 19 | 20 | #ifndef _PRAGMA_CMODEL_H_ 21 | #define _PRAGMA_CMODEL_H_ 22 | 23 | void CM_FreeMap(); 24 | cmodel_t* CM_LoadMap(char* name, qboolean clientload, unsigned* checksum); 25 | cmodel_t* CM_InlineModelNum(int index); 26 | cmodel_t* CM_InlineModel(const char* name); // *1, *2, etc 27 | 28 | int CM_NumClusters(); 29 | int CM_NumInlineModels(); 30 | char* CM_EntityString(); 31 | 32 | // creates a clipping hull for an arbitrary box 33 | int CM_HeadnodeForBox(vec3_t mins, vec3_t maxs); 34 | 35 | 36 | // returns an ORed contents mask 37 | int CM_PointContents(vec3_t p, int headnode); 38 | int CM_TransformedPointContents(vec3_t p, int headnode, vec3_t origin, vec3_t angles); 39 | 40 | trace_t CM_BoxTrace(vec3_t start, vec3_t end, 41 | vec3_t mins, vec3_t maxs, 42 | int headnode, int brushmask); 43 | 44 | trace_t CM_TransformedBoxTrace(vec3_t start, vec3_t end, 45 | vec3_t mins, vec3_t maxs, 46 | int headnode, int brushmask, 47 | vec3_t origin, vec3_t angles); 48 | 49 | byte* CM_ClusterPVS(int cluster); 50 | byte* CM_ClusterPHS(int cluster); 51 | 52 | int CM_PointLeafnum(vec3_t p); 53 | 54 | // call with topnode set to the headnode, returns with topnode 55 | // set to the first node that splits the box 56 | int CM_BoxLeafnums(vec3_t mins, vec3_t maxs, int* list, int listsize, int* topnode); 57 | 58 | int CM_LeafContents(int leafnum); 59 | int CM_LeafCluster(int leafnum); 60 | int CM_LeafArea(int leafnum); 61 | 62 | void CM_SetAreaPortalState(int portalnum, qboolean open); 63 | qboolean CM_AreasConnected(int area1, int area2); 64 | 65 | int CM_WriteAreaBits(byte* buffer, int area); 66 | qboolean CM_HeadnodeVisible(int headnode, byte* visbits); 67 | 68 | void CM_WritePortalState(FILE* f); 69 | void CM_ReadPortalState(FILE* f); 70 | 71 | #endif /*_PRAGMA_CMODEL_H_*/ 72 | -------------------------------------------------------------------------------- /.github/workflows/msbuild-debug-x86.yml: -------------------------------------------------------------------------------- 1 | # This workflow uses actions that are not certified by GitHub. 2 | # They are provided by a third-party and are governed by 3 | # separate terms of service, privacy policy, and support 4 | # documentation. 5 | 6 | name: Debug 32bit 7 | 8 | on: 9 | push: 10 | branches: [ "main" ] 11 | pull_request: 12 | branches: [ "main" ] 13 | workflow_dispatch: 14 | branches: [ "main" ] 15 | 16 | env: 17 | # Path to the solution file relative to the root of the project. 18 | SOLUTION_FILE_PATH: ./src/pragma.sln 19 | 20 | # Configuration type to build. 21 | # You can convert this to a build matrix if you need coverage of multiple configuration types. 22 | # https://docs.github.com/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix 23 | BUILD_CONFIGURATION: Debug 24 | BUILD_PLATFORM: x86 25 | 26 | permissions: 27 | contents: read 28 | 29 | jobs: 30 | build: 31 | runs-on: windows-latest 32 | 33 | steps: 34 | - uses: actions/checkout@v3 35 | 36 | - name: Add MSBuild to PATH 37 | uses: microsoft/setup-msbuild@v1.0.2 38 | 39 | - name: Restore NuGet packages 40 | working-directory: ${{env.GITHUB_WORKSPACE}} 41 | run: nuget restore ${{env.SOLUTION_FILE_PATH}} 42 | 43 | - name: Build 44 | working-directory: ${{env.GITHUB_WORKSPACE}} 45 | # Add additional options to the MSBuild command line here (like platform or verbosity level). 46 | # See https://docs.microsoft.com/visualstudio/msbuild/msbuild-command-line-reference 47 | run: msbuild /m /p:Configuration=${{env.BUILD_CONFIGURATION}} /p:Platform=${{env.BUILD_PLATFORM}} ${{env.SOLUTION_FILE_PATH}} 48 | 49 | - name: Generate MSBuild archives 50 | uses: actions/upload-artifact@v3 51 | with: 52 | name: pragma-debug-win-${{env.BUILD_PLATFORM}} 53 | path: | 54 | build/pragma.exe 55 | build/pragma.pdb 56 | build/pragma_server.exe 57 | build/pragma_server.pdb 58 | build/pragma_renderer_gl2_x86.dll 59 | build/pragma_renderer_gl2_x86.pdb 60 | build/prtool.exe 61 | build/prtool.pdb 62 | build/prtool.qc 63 | build/main/dummy.txt 64 | readme.txt 65 | -------------------------------------------------------------------------------- /.github/workflows/msbuild-debug-x64.yml: -------------------------------------------------------------------------------- 1 | # This workflow uses actions that are not certified by GitHub. 2 | # They are provided by a third-party and are governed by 3 | # separate terms of service, privacy policy, and support 4 | # documentation. 5 | 6 | name: Debug 64bit 7 | 8 | on: 9 | push: 10 | branches: [ "main" ] 11 | pull_request: 12 | branches: [ "main" ] 13 | workflow_dispatch: 14 | branches: [ "main" ] 15 | 16 | env: 17 | # Path to the solution file relative to the root of the project. 18 | SOLUTION_FILE_PATH: ./src/pragma.sln 19 | 20 | # Configuration type to build. 21 | # You can convert this to a build matrix if you need coverage of multiple configuration types. 22 | # https://docs.github.com/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix 23 | BUILD_CONFIGURATION: Debug 24 | BUILD_PLATFORM: x64 25 | 26 | permissions: 27 | contents: read 28 | 29 | jobs: 30 | build: 31 | runs-on: windows-latest 32 | 33 | steps: 34 | - uses: actions/checkout@v3 35 | 36 | - name: Add MSBuild to PATH 37 | uses: microsoft/setup-msbuild@v1.0.2 38 | 39 | - name: Restore NuGet packages 40 | working-directory: ${{env.GITHUB_WORKSPACE}} 41 | run: nuget restore ${{env.SOLUTION_FILE_PATH}} 42 | 43 | - name: Build 44 | working-directory: ${{env.GITHUB_WORKSPACE}} 45 | # Add additional options to the MSBuild command line here (like platform or verbosity level). 46 | # See https://docs.microsoft.com/visualstudio/msbuild/msbuild-command-line-reference 47 | run: msbuild /m /p:Configuration=${{env.BUILD_CONFIGURATION}} /p:Platform=${{env.BUILD_PLATFORM}} ${{env.SOLUTION_FILE_PATH}} 48 | 49 | - name: Generate MSBuild archives 50 | uses: actions/upload-artifact@v3 51 | with: 52 | name: pragma-debug-win-${{env.BUILD_PLATFORM}} 53 | path: | 54 | build/pragma_x64.exe 55 | build/pragma_x64.pdb 56 | build/pragma_server_x64.exe 57 | build/pragma_server_x64.pdb 58 | build/pragma_renderer_gl2_x64.dll 59 | build/pragma_renderer_gl2_x64.pdb 60 | build/prtool.exe 61 | build/prtool.pdb 62 | build/prtool.qc 63 | build/main/dummy.txt 64 | readme.txt 65 | -------------------------------------------------------------------------------- /src/engine/net_chan.h: -------------------------------------------------------------------------------- 1 | /* 2 | pragma 3 | Copyright (C) 2023-2024 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | 8 | See the attached GNU General Public License v2 for more details. 9 | */ 10 | 11 | /* 12 | ============================================================== 13 | 14 | NETWORK 15 | 16 | Pragma's interface to the networking layer. 17 | 18 | ============================================================== 19 | */ 20 | 21 | #pragma once 22 | 23 | #ifndef _PRAGMA_NET_CHAN_H_ 24 | #define _PRAGMA_NET_CHAN_H_ 25 | 26 | typedef struct 27 | { 28 | qboolean fatal_error; 29 | 30 | netsrc_t sock; 31 | 32 | int dropped; // between last packet and previous 33 | 34 | int last_received; // for timeouts 35 | int last_sent; // for retransmits 36 | 37 | netadr_t remote_address; 38 | int qport; // qport value to write when transmitting 39 | 40 | // sequencing variables 41 | int incoming_sequence; 42 | int incoming_acknowledged; 43 | int incoming_reliable_acknowledged; // single bit 44 | 45 | int incoming_reliable_sequence; // single bit, maintained local 46 | 47 | int outgoing_sequence; 48 | int reliable_sequence; // single bit 49 | int last_reliable_sequence; // sequence number of last send 50 | 51 | // reliable staging and holding areas 52 | sizebuf_t message; // writing buffer to send to server 53 | byte message_buf[MAX_MSGLEN - 16]; // leave space for header 54 | 55 | // message is copied to this buffer when it is first transfered 56 | int reliable_length; 57 | byte reliable_buf[MAX_MSGLEN - 16]; // unacked reliable message 58 | } netchan_t; 59 | 60 | 61 | extern netadr_t net_from; 62 | extern sizebuf_t net_message; 63 | extern byte net_message_buffer[MAX_MSGLEN]; 64 | 65 | void Netchan_Init(void); 66 | void Netchan_Setup(netsrc_t sock, netchan_t* chan, netadr_t adr, int qport); 67 | 68 | qboolean Netchan_NeedReliable(netchan_t* chan); 69 | void Netchan_Transmit(netchan_t* chan, int length, byte* data); 70 | void Netchan_OutOfBand(int net_socket, netadr_t adr, int length, byte* data); 71 | void Netchan_OutOfBandPrint(int net_socket, netadr_t adr, char* format, ...); 72 | qboolean Netchan_Process(netchan_t* chan, sizebuf_t* msg); 73 | 74 | qboolean Netchan_CanReliable(netchan_t* chan); 75 | 76 | #endif /*_PRAGMA_NET_CHAN_H_*/ 77 | -------------------------------------------------------------------------------- /progs_src/svgame/ents/func_object.qc: -------------------------------------------------------------------------------- 1 | /* 2 | P R A G M A 3 | Copyright (C) 2023 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | */ 8 | 9 | /*QUAKED func_object (0 .5 .8) ? TRIGGER_SPAWN X X ANIMATED ANIMATED_FAST 10 | This is solid brush model that will fall if it's support is removed. 11 | 12 | "dmg" - damage to apply on crushed entities (default 100) 13 | */ 14 | 15 | void(float planeDist, vector planeNormal, float surfaceFlags) func_object_touch = 16 | { 17 | // only squash thing we fall on top of 18 | if (planeNormal == vec3_origin) 19 | return; 20 | 21 | if (planeNormal_z < 1.0) 22 | return; 23 | 24 | if (other.takedamage == DAMAGE_NO) 25 | return; 26 | 27 | DoDamage(self.activator, self, other, self.dmg, 0, DMG_CRUSH); 28 | }; 29 | 30 | void() func_object_release = 31 | { 32 | self.movetype = MOVETYPE_TOSS; 33 | self.touch = func_object_touch; 34 | }; 35 | 36 | void(entity user) func_object_use = 37 | { 38 | self.solid = SOLID_BSP; 39 | self.svflags &= ~SVF_NOCLIENT; 40 | self.use = null_use; 41 | KillBox(); 42 | func_object_release(); 43 | }; 44 | 45 | float() SP_func_object = 46 | { 47 | if(!strlen(self.model)) 48 | { 49 | dprint("func_object with no brushmodel removed\n"); 50 | return false; 51 | } 52 | 53 | setmodel(self, self.model); 54 | 55 | self.mins = self.mins + '1 1 1'; 56 | self.maxs = self.maxs - '1 1 1'; 57 | 58 | if( !self.dmg ) 59 | self.dmg = 100; 60 | 61 | if( self.spawnflags == 0 ) 62 | { 63 | self.solid = SOLID_BSP; 64 | self.movetype = MOVETYPE_PUSH; 65 | self.think = func_object_release; 66 | self.nextthink = g_time + (g_frameTime * 2); 67 | } 68 | else 69 | { 70 | self.solid = SOLID_NOT; 71 | self.movetype = MOVETYPE_PUSH; 72 | self.use = func_object_use; 73 | self.svflags |= SVF_NOCLIENT; 74 | } 75 | 76 | //a case where we want object to be solid from start, but fall when triggered 77 | if( self.think == func_object_release && strlen(self.targetname) > 0 ) 78 | { 79 | self.think = SUB_Null; // so the object doesn't fall on its own 80 | self.use = func_object_use; 81 | } 82 | 83 | if(self.spawnflags & FUNC_SPAWNFLAG_ANIMATED) 84 | self.effects |= EF_ANIM_ALL; 85 | if(self.spawnflags & FUNC_SPAWNFLAG_ANIMATED_FAST) 86 | self.effects |= EF_ANIM_ALLFAST; 87 | 88 | self.clipmask = MASK_MONSTERSOLID; 89 | 90 | linkentity(self); 91 | return true; 92 | } 93 | -------------------------------------------------------------------------------- /src/engine/client/cgame/client_game.h: -------------------------------------------------------------------------------- 1 | /* 2 | pragma 3 | Copyright (C) 2023-2024 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | 8 | See the attached GNU General Public License v2 for more details. 9 | */ 10 | 11 | #pragma once 12 | 13 | #define MAX_CLIENT_ENTITIES 2048 14 | // 15 | // all loaded media by cgame 16 | // 17 | typedef struct 18 | { 19 | struct sfx_s* sfx_ricochet[3]; 20 | struct sfx_s* sfx_footsteps[3]; 21 | struct sfx_s* sfx_splash[3]; 22 | struct sfx_s* sfx_explosion[3]; 23 | 24 | struct model_s* mod_v_muzzleflash; 25 | struct model_s* mod_w_flashlight; 26 | struct model_s* mod_v_flashlight; 27 | struct model_s* mod_w_muzzleflash; 28 | 29 | struct model_s* impact_small; 30 | } cgMedia_t; 31 | 32 | typedef struct 33 | { 34 | unsigned int time; 35 | 36 | // 37 | // qcvm 38 | // 39 | qboolean qcvm_active; 40 | cl_globalvars_t *script_globals; // qcvm globals 41 | 42 | struct clentity_t *localEntities; // local (not broadcasted) entities allocated by qcvm 43 | int maxLocalEntities; // number of progs allocated entities 44 | int localEntitySize; // retrieved from progs 45 | int numActiveLocalEnts; // increases towards MAX_CLENTITIES 46 | } cg_t; 47 | 48 | extern cg_t cg; 49 | 50 | extern cgMedia_t cgMedia; 51 | 52 | // 53 | // cg_main.c 54 | // 55 | void CG_ClearState(); 56 | void CL_ShutdownClientGame(); 57 | void CG_InitClientGame(); 58 | void CG_BeginGame(); 59 | void CG_AddEntities(); 60 | 61 | void CG_Frame(); 62 | void CG_DrawGUI(); 63 | 64 | qboolean CG_CanDrawCall(); 65 | void CG_ParseCommandFromServer(); 66 | 67 | #define AF_NOLERP 1 68 | #define AF_LOOPING 2 69 | 70 | typedef struct 71 | { 72 | int soundindex; 73 | int effects; 74 | } anim_event_t; 75 | 76 | typedef struct 77 | { 78 | char name[MAX_QPATH]; 79 | 80 | int startframe; 81 | int numframes; 82 | int rate; 83 | 84 | int flags; 85 | 86 | int numevents; 87 | anim_event_t *events; // [numevents] 88 | } anim_t; 89 | 90 | typedef struct 91 | { 92 | unsigned int starttime; //sv.time when animation started 93 | 94 | int startframe; 95 | int numframes; 96 | int rate; 97 | 98 | int flags; 99 | } animstate_t; 100 | 101 | 102 | //extern cdlight_t cl_dlights[MAX_DLIGHTS]; 103 | 104 | typedef unsigned short cs_index; 105 | -------------------------------------------------------------------------------- /progs_src/svgame/ents/monsters.qc: -------------------------------------------------------------------------------- 1 | /* 2 | P R A G M A 3 | Copyright (C) 2023 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | */ 8 | // ai/monsters_temp.qc -- this is a placehorder to spawn q2 monsters as props 9 | 10 | //.void(entity ent, entity attacker, float damage, float method) pain; 11 | //.void(entity ent, entity attacker, float damage, float method) die; 12 | 13 | 14 | float(string mdlname) CreateTestDummy = 15 | { 16 | if( !precache_model(mdlname) ) 17 | return false; 18 | 19 | setmodel(self, mdlname); 20 | linkentity(self); 21 | return true; 22 | }; 23 | 24 | float() SP_monster_berserk = { return CreateTestDummy("models/monsters/berserk/tris.md2"); }; 25 | float() SP_monster_gladiator = { return CreateTestDummy("models/monsters/gladiatr/tris.md2"); }; 26 | float() SP_monster_gunner = { return CreateTestDummy("models/monsters/gunner/tris.md2"); }; 27 | float() SP_monster_infantry = { return CreateTestDummy("models/monsters/infantry/tris.md2"); }; 28 | float() SP_monster_soldier_light = { return CreateTestDummy("models/monsters/soldier/tris.md2"); }; 29 | float() SP_monster_soldier = { return CreateTestDummy("models/monsters/soldier/tris.md2"); }; 30 | float() SP_monster_soldier_ss = { return CreateTestDummy("models/monsters/soldier/tris.md2"); }; 31 | float() SP_monster_tank = { return CreateTestDummy("models/monsters/tank/tris.md2"); }; 32 | float() SP_monster_medic = { return CreateTestDummy("models/monsters/medic/tris.md2"); }; 33 | float() SP_monster_flipper = { return CreateTestDummy("models/monsters/flipper/tris.md2"); }; 34 | float() SP_monster_chick = { return CreateTestDummy("models/monsters/bitch/tris.md2"); }; 35 | float() SP_monster_parasite = { return CreateTestDummy("models/monsters/parasite/tris.md2"); }; 36 | float() SP_monster_flyer = { return CreateTestDummy("models/monsters/flyer/tris.md2"); }; 37 | float() SP_monster_brain = { return CreateTestDummy("models/monsters/brain/tris.md2"); }; 38 | float() SP_monster_floater = { return CreateTestDummy("models/monsters/float/tris.md2"); }; 39 | float() SP_monster_hover = { return CreateTestDummy("models/monsters/hover/tris.md2"); }; 40 | float() SP_monster_mutant = { return CreateTestDummy("models/monsters/mutant/tris.md2"); }; 41 | float() SP_monster_supertank = { return CreateTestDummy("models/monsters/boss1/tris.md2"); }; 42 | float() SP_monster_boss2 = { return CreateTestDummy("models/monsters/boss2/tris.md2"); }; 43 | float() SP_monster_jorg = { return CreateTestDummy("models/monsters/boss3/jorg/tris.md2"); }; 44 | -------------------------------------------------------------------------------- /progs_src/inc/shared.qc: -------------------------------------------------------------------------------- 1 | // globals shared by both client and server 2 | // you can add new globals here 3 | 4 | float FRAMETIME = 0.1; 5 | float FALSE = 0; 6 | float TRUE = 1; 7 | float false = FALSE; 8 | float true = TRUE; 9 | 10 | string string_null = ""; 11 | vector vec_null = '0 0 0'; 12 | vector vec3_origin = vec_null; //temporary, ugly 13 | 14 | // ------------------------------------------------------ 15 | // BG - defines shared by cgame and svgame 16 | // ------------------------------------------------------ 17 | 18 | // .waterlevel levels 19 | enum 20 | { 21 | TEAM_NONE = 0, 22 | TEAM_SURVIVORS, 23 | TEAM_MONSTERS, 24 | TEAM_SPECTATOR 25 | }; 26 | 27 | // .waterlevel levels 28 | enum 29 | { 30 | WL_NOTINWATER = 0, // not in water 31 | WL_TOUCHING, // touching water 32 | WL_HALFWAY, // half in water 33 | WL_UNDERWATER // head under water 34 | }; 35 | 36 | // 37 | // stats are used to display HUD 38 | // 39 | // player_state->stats[] indexes 40 | enum 41 | { 42 | /* these MUST match in C code */ 43 | STAT_HEALTH, 44 | STAT_SCORE, 45 | /* add custom stats below */ 46 | STAT_WEAPON, 47 | STAT_AMMO_RESERVE, 48 | STAT_MONSTERS_KILLED 49 | }; 50 | 51 | 52 | // damage methods 53 | enum 54 | { 55 | DMG_UNKNOWN, 56 | DMG_SLIME, 57 | DMG_LAVA, 58 | DMG_FALLING, 59 | DMG_CRUSH, 60 | DMG_DROWNING, 61 | DMG_EXPLOSIVE, 62 | DMG_BULLET, 63 | DMG_ENERGY 64 | }; 65 | 66 | // weapons list 67 | enum 68 | { 69 | WEAPON_NONE = 0, 70 | WEAPON_AR, 71 | WEAPON_PISTOL, 72 | NUM_WEAPONS 73 | }; 74 | 75 | // weapon definitions 76 | typedef struct 77 | { 78 | string displayName; 79 | 80 | float damage; 81 | float dmgmethod; 82 | 83 | float range; //trace dist 84 | float spread; 85 | 86 | float clipAmmo; 87 | float maxAmmo; 88 | 89 | float fireTime; 90 | float reloadTime; 91 | float reloadEmptyTime; 92 | 93 | float vkick; 94 | 95 | string viewModel; 96 | string worldModel; 97 | 98 | float muzzleflash; //effect+fire sound 99 | 100 | string sfx_raise; 101 | string sfx_reload; 102 | string sfx_reload_empty; 103 | 104 | // [firstframe, lastframe, speed] 105 | vector anim_idle; 106 | vector anim_fire; 107 | vector anim_drop; 108 | vector anim_raise; 109 | vector anim_reload; 110 | vector anim_reload_empty; 111 | } WeaponDef; 112 | 113 | void() BG_InitWeapons; 114 | string(float wpn) GetWeaponNameForNum; 115 | float(float wpn) GetWeaponMaxClipAmmo; 116 | float(float wpn) GetWeaponMaxAmmo; 117 | float(float wpn) IsWeaponClipOnly; -------------------------------------------------------------------------------- /progs_src/svgame/ents/func_wall.qc: -------------------------------------------------------------------------------- 1 | /* 2 | P R A G M A 3 | Copyright (C) 2023 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | */ 8 | 9 | /*QUAKED func_wall (0 .5 .8) ? TRIGGER_SPAWN TOGGLE START_ON ANIMATED ANIMATED_FAST 10 | This is just a solid wall if not inhibited 11 | 12 | TRIGGER_SPAWN the wall will not be present until triggered 13 | it will then blink in to existance; it will 14 | kill anything that was in it's way 15 | 16 | TOGGLE only valid for TRIGGER_SPAWN walls 17 | this allows the wall to be turned on and off 18 | 19 | START_ON only valid for TRIGGER_SPAWN walls 20 | the wall will initially be present 21 | */ 22 | 23 | //func_wall & func_object 24 | float FUNC_SPAWNFLAG_TRIGGER_SPAWN = 1; 25 | float FUNC_SPAWNFLAG_TOGGLE = 2; 26 | float FUNC_SPAWNFLAG_START_ON = 4; 27 | float FUNC_SPAWNFLAG_ANIMATED = 8; 28 | float FUNC_SPAWNFLAG_ANIMATED_FAST = 16; 29 | 30 | void(entity acti) func_wall_use = 31 | { 32 | if (self.solid == SOLID_NOT) 33 | { 34 | self.solid = SOLID_BSP; 35 | self.svflags &= ~SVF_NOCLIENT; 36 | KillBox(); 37 | } 38 | else 39 | { 40 | self.solid = SOLID_NOT; 41 | self.svflags |= SVF_NOCLIENT; 42 | } 43 | linkentity(self); 44 | 45 | if (!(self.spawnflags & FUNC_SPAWNFLAG_TOGGLE)) 46 | self.use = null_use; 47 | }; 48 | 49 | float() SP_func_wall = 50 | { 51 | self.movetype = MOVETYPE_PUSH; 52 | setmodel(self, self.model); 53 | 54 | if (self.spawnflags & FUNC_SPAWNFLAG_ANIMATED) 55 | self.effects |= EF_ANIM_ALL; 56 | if (self.spawnflags & FUNC_SPAWNFLAG_ANIMATED_FAST) 57 | self.effects |= EF_ANIM_ALLFAST; 58 | 59 | // just a wall 60 | if ((self.spawnflags & 7) == 0) 61 | { 62 | self.solid = SOLID_BSP; 63 | linkentity(self); 64 | return true; 65 | } 66 | 67 | // it must be TRIGGER_SPAWN 68 | if (!(self.spawnflags & FUNC_SPAWNFLAG_TRIGGER_SPAWN)) 69 | { 70 | dprint("func_wall at ", vtos(self.origin), " missing TRIGGER_SPAWN\n"); 71 | self.spawnflags |= FUNC_SPAWNFLAG_TRIGGER_SPAWN; 72 | } 73 | 74 | // yell if the spawnflags are odd 75 | if (self.spawnflags & FUNC_SPAWNFLAG_START_ON) 76 | { 77 | if (!(self.spawnflags & FUNC_SPAWNFLAG_TOGGLE)) 78 | { 79 | dprint("func_wall START_ON without TOGGLE\n"); 80 | self.spawnflags |= FUNC_SPAWNFLAG_TOGGLE; 81 | } 82 | } 83 | 84 | self.use = func_wall_use; 85 | if (self.spawnflags & FUNC_SPAWNFLAG_START_ON) 86 | { 87 | self.solid = SOLID_BSP; 88 | } 89 | else 90 | { 91 | self.solid = SOLID_NOT; 92 | self.svflags |= SVF_NOCLIENT; 93 | } 94 | linkentity(self); 95 | return true; 96 | } 97 | -------------------------------------------------------------------------------- /src/engine/usercmd.c: -------------------------------------------------------------------------------- 1 | /* 2 | pragma 3 | Copyright (C) 2023-2024 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | 8 | See the attached GNU General Public License v2 for more details. 9 | */ 10 | 11 | #include "pragma.h" 12 | 13 | void MSG_WriteDeltaUsercmd(sizebuf_t* buf, usercmd_t* from, usercmd_t* cmd) 14 | { 15 | int bits; 16 | 17 | // 18 | // send the movement message 19 | // 20 | bits = 0; 21 | if (cmd->angles[0] != from->angles[0]) 22 | bits |= CM_ANGLE1; 23 | if (cmd->angles[1] != from->angles[1]) 24 | bits |= CM_ANGLE2; 25 | if (cmd->angles[2] != from->angles[2]) 26 | bits |= CM_ANGLE3; 27 | if (cmd->forwardmove != from->forwardmove) 28 | bits |= CM_FORWARD; 29 | if (cmd->sidemove != from->sidemove) 30 | bits |= CM_SIDE; 31 | if (cmd->upmove != from->upmove) 32 | bits |= CM_UP; 33 | if (cmd->buttons != from->buttons) 34 | bits |= CM_BUTTONS; 35 | if (cmd->impulse != from->impulse) 36 | bits |= CM_IMPULSE; 37 | 38 | MSG_WriteByte(buf, bits); 39 | 40 | if (bits & CM_ANGLE1) 41 | MSG_WriteShort(buf, cmd->angles[0]); 42 | if (bits & CM_ANGLE2) 43 | MSG_WriteShort(buf, cmd->angles[1]); 44 | if (bits & CM_ANGLE3) 45 | MSG_WriteShort(buf, cmd->angles[2]); 46 | 47 | if (bits & CM_FORWARD) 48 | MSG_WriteShort(buf, cmd->forwardmove); 49 | if (bits & CM_SIDE) 50 | MSG_WriteShort(buf, cmd->sidemove); 51 | if (bits & CM_UP) 52 | MSG_WriteShort(buf, cmd->upmove); 53 | 54 | if (bits & CM_BUTTONS) 55 | MSG_WriteByte(buf, cmd->buttons); 56 | if (bits & CM_IMPULSE) 57 | MSG_WriteByte(buf, cmd->impulse); 58 | 59 | MSG_WriteByte(buf, cmd->msec); 60 | } 61 | 62 | void MSG_ReadDeltaUsercmd(sizebuf_t* msg_read, usercmd_t* from, usercmd_t* move) 63 | { 64 | int bits; 65 | 66 | memcpy(move, from, sizeof(*move)); 67 | 68 | bits = MSG_ReadByte(msg_read); 69 | 70 | // read current angles 71 | if (bits & CM_ANGLE1) 72 | move->angles[0] = MSG_ReadShort(msg_read); 73 | if (bits & CM_ANGLE2) 74 | move->angles[1] = MSG_ReadShort(msg_read); 75 | if (bits & CM_ANGLE3) 76 | move->angles[2] = MSG_ReadShort(msg_read); 77 | 78 | // read movement 79 | if (bits & CM_FORWARD) 80 | move->forwardmove = MSG_ReadShort(msg_read); 81 | if (bits & CM_SIDE) 82 | move->sidemove = MSG_ReadShort(msg_read); 83 | if (bits & CM_UP) 84 | move->upmove = MSG_ReadShort(msg_read); 85 | 86 | // read buttons 87 | if (bits & CM_BUTTONS) 88 | move->buttons = MSG_ReadByte(msg_read); 89 | 90 | if (bits & CM_IMPULSE) 91 | move->impulse = MSG_ReadByte(msg_read); 92 | 93 | // read time to run command 94 | move->msec = MSG_ReadByte(msg_read); 95 | } -------------------------------------------------------------------------------- /src/engine/client/cgame/cg_tempents.c: -------------------------------------------------------------------------------- 1 | /* 2 | pragma 3 | Copyright (C) 2023-2024 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | 8 | See the attached GNU General Public License v2 for more details. 9 | */ 10 | 11 | #include "../client.h" 12 | #include "cg_local.h" 13 | 14 | #if 0 15 | // cg_localents.c -- every frame, generate renderer commands for locally 16 | // processed entities, like gibs, physics objects, shells, etc. 17 | 18 | #define MAX_LOCAL_ENTITIES 1024 19 | localEntity_t cg_localEntities[MAX_LOCAL_ENTITIES]; 20 | localEntity_t cg_activeLocalEntities; // double linked list 21 | localEntity_t *cg_freeLocalEntities; // single linked list 22 | 23 | /* 24 | =================== 25 | CG_InitLocalEntities 26 | 27 | This is called every time cgame is initialized 28 | =================== 29 | */ 30 | void CG_InitLocalEntities() 31 | { 32 | int i; 33 | 34 | memset(cg_localEntities, 0, sizeof(cg_localEntities)); 35 | 36 | cg_activeLocalEntities.next = &cg_activeLocalEntities; 37 | cg_activeLocalEntities.prev = &cg_activeLocalEntities; 38 | cg_freeLocalEntities = cg_localEntities; 39 | 40 | for (i = 0; i < MAX_LOCAL_ENTITIES - 1; i++) 41 | { 42 | cg_localEntities[i].next = &cg_localEntities[i + 1]; 43 | } 44 | } 45 | 46 | 47 | /* 48 | ================== 49 | CG_FreeLocalEntity 50 | ================== 51 | */ 52 | void CG_FreeLocalEntity(localEntity_t* le) 53 | { 54 | if (!le || !le->prev) 55 | { 56 | Com_Error(ERR_DROP, "CG_FreeLocalEntity: not active\n"); 57 | return; 58 | } 59 | 60 | // remove from the doubly linked active list 61 | le->prev->next = le->next; 62 | le->next->prev = le->prev; 63 | 64 | // the free list is only singly linked 65 | le->next = cg_freeLocalEntities; 66 | cg_freeLocalEntities = le; 67 | } 68 | 69 | /* 70 | =================== 71 | CG_AllocLocalEntity 72 | 73 | Will allways succeed, even if it requires freeing an old active entity 74 | =================== 75 | */ 76 | localEntity_t* CG_AllocLocalEntity() 77 | { 78 | localEntity_t* le; 79 | 80 | if (!cg_freeLocalEntities) 81 | { 82 | // no free entities, so free the one at the end of the chain, remove the oldest active entity 83 | CG_FreeLocalEntity(cg_activeLocalEntities.prev); 84 | } 85 | 86 | le = cg_freeLocalEntities; 87 | cg_freeLocalEntities = cg_freeLocalEntities->next; 88 | 89 | memset(le, 0, sizeof(*le)); 90 | 91 | // link into the active list 92 | le->next = cg_activeLocalEntities.next; 93 | le->prev = &cg_activeLocalEntities; 94 | cg_activeLocalEntities.next->prev = le; 95 | cg_activeLocalEntities.next = le; 96 | return le; 97 | } 98 | #endif -------------------------------------------------------------------------------- /src/engine/winquake.rc: -------------------------------------------------------------------------------- 1 | //Microsoft Developer Studio generated resource script. 2 | // 3 | #include "resource.h" 4 | 5 | #define APSTUDIO_READONLY_SYMBOLS 6 | ///////////////////////////////////////////////////////////////////////////// 7 | // 8 | // Generated from the TEXTINCLUDE 2 resource. 9 | // 10 | #include "afxres.h" 11 | 12 | ///////////////////////////////////////////////////////////////////////////// 13 | #undef APSTUDIO_READONLY_SYMBOLS 14 | 15 | ///////////////////////////////////////////////////////////////////////////// 16 | // English (U.S.) resources 17 | 18 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) 19 | #ifdef _WIN32 20 | LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US 21 | #pragma code_page(1252) 22 | #endif //_WIN32 23 | 24 | #ifdef APSTUDIO_INVOKED 25 | ///////////////////////////////////////////////////////////////////////////// 26 | // 27 | // TEXTINCLUDE 28 | // 29 | 30 | 1 TEXTINCLUDE DISCARDABLE 31 | BEGIN 32 | "resource.h\0" 33 | END 34 | 35 | 2 TEXTINCLUDE DISCARDABLE 36 | BEGIN 37 | "#include ""afxres.h""\r\n" 38 | "\0" 39 | END 40 | 41 | 3 TEXTINCLUDE DISCARDABLE 42 | BEGIN 43 | "\r\n" 44 | "\0" 45 | END 46 | 47 | #endif // APSTUDIO_INVOKED 48 | 49 | 50 | ///////////////////////////////////////////////////////////////////////////// 51 | // 52 | // Icon 53 | // 54 | 55 | // Icon with lowest ID value placed first to ensure application icon 56 | // remains consistent on all systems. 57 | IDI_ICON1 ICON DISCARDABLE "pragma.ico" 58 | 59 | ///////////////////////////////////////////////////////////////////////////// 60 | // 61 | // Dialog 62 | // 63 | 64 | IDD_DIALOG1 DIALOGEX 0, 0, 62, 21 65 | STYLE DS_MODALFRAME | DS_SETFOREGROUND | DS_3DLOOK | DS_CENTER | WS_POPUP | 66 | WS_VISIBLE 67 | EXSTYLE WS_EX_TOOLWINDOW | WS_EX_CLIENTEDGE 68 | FONT 16, "Times New Roman", 0, 0, 0x1 69 | BEGIN 70 | CTEXT "Starting Pragma...",IDC_STATIC,4,6,54,8 71 | END 72 | 73 | 74 | ///////////////////////////////////////////////////////////////////////////// 75 | // 76 | // String Table 77 | // 78 | 79 | STRINGTABLE DISCARDABLE 80 | BEGIN 81 | IDS_STRING1 "Pragma" 82 | END 83 | 84 | #endif // English (U.S.) resources 85 | ///////////////////////////////////////////////////////////////////////////// 86 | 87 | 88 | 89 | #ifndef APSTUDIO_INVOKED 90 | ///////////////////////////////////////////////////////////////////////////// 91 | // 92 | // Generated from the TEXTINCLUDE 3 resource. 93 | // 94 | 95 | 96 | ///////////////////////////////////////////////////////////////////////////// 97 | #endif // not APSTUDIO_INVOKED 98 | 99 | -------------------------------------------------------------------------------- /src/renderer_dll/TODO.md: -------------------------------------------------------------------------------- 1 | # RENDERER 2 | An attempt to bring renderer to OpenGL 2.1, while making it many times faster than GL1.4 renderer 3 | 4 | 5 | ## TODO: 6 | - anistropic texture filtering 7 | - entities should be lit by lightgrid instead of lightmap pixel underneath them (which is awful for objects in air) -- add support for `LIGHTGRID_OCTREE` BSPX 8 | - convert remaining code that does immediate rendering (glBegin/glEnd) to vertex buffers 9 | - exponential fog + make it cull objects that are completly occluded 10 | - MD5 models and skeletal animations (maybe?) 11 | - add `r_picmip` back 12 | - particles can be optionaly lit 13 | - sky rendering code is awful 14 | - add beams back 15 | - local entities rendering and culling based on PVS ? 16 | 17 | ## PARTIALY DONE: 18 | - move viewblend to shader (problem: it looks worse) 19 | - alphatest is gone in newer opengl, removed `glAlphaTest`, a few remaining calls left to enable/disable `GL_ALPHA_TEST` 20 | 21 | ## DONE: 22 | - flashlights 23 | - render brushmodels and entirity of world with vertexbuffers 24 | - add per pixel lighting 25 | - move lightstyles to GPU 26 | - upload all lightmaps to GPU and not waste cpu clocks for updates (aitest.bsp ~120fps with old code vs ~370fps now on my machine) 27 | - render `GL_POLYGON` as `GL_TRIANGLE_STRIP` 28 | - all UI rendering is now done with vertexbuffers (bringing up console no longer tanks FPS) 29 | - support `QBISM` extended BSP format allowing for greatly more advanced maps 30 | - world loading code is aware of `BSPX` lumps 31 | - decoupled lightmap coords from texture coords (`DECOUPLED_LM` lump) - this also allows for much higher (or lower) quality lightmaps 32 | - configurable `LMSHIFT` (was needed for `DECOUPLED_LM`) 33 | - support GLSL shaders 34 | - implement framebuffer objects and render all the world to texture for post processing 35 | - get rid of `GL_QUAD` primitives 36 | - make `r_gamma` not require restarts 37 | - cull MD3 models based on distance and frustum 38 | - post processing effects such as film grain, saturation, contrast, intensity, grayscale, blur, etc.. 39 | - render MD3 models with vbos 40 | - animate MD3 models entirely on GPU -- this has improved pefrormance from 3-6fps to >200fps on my machine (bench1.bsp, 362 animated models, ~5mil vert transforms) 41 | - use opengl to generate mipmaps, thus allow for better textures 42 | - remove calls to `glColor`, use uniforms instead 43 | - particles can be of any size 44 | - setup projection without immediate calls 45 | - get rid of IM translation/rotation -- calculate matrices and pass them to shaders 46 | - multitexture support 47 | - use GLSL shaders for diferent gemoetries 48 | - dynamic lights 49 | -------------------------------------------------------------------------------- /progs_src/svgame/ents/light.qc: -------------------------------------------------------------------------------- 1 | /* 2 | P R A G M A 3 | Copyright (C) 2023 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | */ 8 | 9 | /*QUAKED light (0 1 0) (-8 -8 -8) (8 8 8) START_OFF 10 | Non-displayed light. 11 | Default light value is 300. 12 | Default style is 0. 13 | If targeted, will toggle between on and off. 14 | Default _cone value is 10 (used to set size of light for spotlights) 15 | */ 16 | 17 | void(entity activ) light_use = 18 | { 19 | if (self.spawnflags & SPAWNFLAG_LIGHTSTART_OFF) 20 | { 21 | lightstyle(self.style, "m"); 22 | self.spawnflags &= ~SPAWNFLAG_LIGHTSTART_OFF; 23 | } 24 | else 25 | { 26 | lightstyle(self.style, "a"); 27 | self.spawnflags |= SPAWNFLAG_LIGHTSTART_OFF; 28 | } 29 | }; 30 | 31 | 32 | float() SP_light = 33 | { 34 | if(IsStringEmpty(self.targetname)) 35 | return false; 36 | 37 | if (self.style >= 32) 38 | { 39 | self.use = light_use; 40 | if (self.spawnflags & SPAWNFLAG_LIGHTSTART_OFF) 41 | lightstyle(self.style, "a"); 42 | else 43 | lightstyle(self.style, "m"); 44 | } 45 | return true; 46 | }; 47 | 48 | // ======nn=============================================== 49 | 50 | /* 51 | ============ 52 | Initlightstyles 53 | 54 | Setup light animation tables. 'a' is total darkness, 'z' is doublebright. 55 | ============ 56 | */ 57 | void() InitLightStyles = 58 | { 59 | 60 | // 0 normal 61 | lightstyle(0, "m"); 62 | 63 | // 1 FLICKER (first variety) 64 | lightstyle(1, "mmnmmommommnonmmonqnmmo"); 65 | 66 | // 2 SLOW STRONG PULSE 67 | lightstyle(2, "abcdefghijklmnopqrstuvwxyzyxwvutsrqponmlkjihgfedcba"); 68 | 69 | // 3 CANDLE (first variety) 70 | lightstyle(3, "mmmmmaaaaammmmmaaaaaabcdefgabcdefg"); 71 | 72 | // 4 FAST STROBE 73 | lightstyle(4, "mamamamamama"); 74 | 75 | // 5 GENTLE PULSE 1 76 | lightstyle(5,"jklmnopqrstuvwxyzyxwvutsrqponmlkj"); 77 | 78 | // 6 FLICKER (second variety) 79 | lightstyle(6, "nmonqnmomnmomomno"); 80 | 81 | // 7 CANDLE (second variety) 82 | lightstyle(7, "mmmaaaabcdefgmmmmaaaammmaamm"); 83 | 84 | // 8 CANDLE (third variety) 85 | lightstyle(8, "mmmaaammmaaammmabcdefaaaammmmabcdefmmmaaaa"); 86 | 87 | // 9 SLOW STROBE (fourth variety) 88 | lightstyle(9, "aaaaaaaazzzzzzzz"); 89 | 90 | // 10 FLUORESCENT FLICKER 91 | lightstyle(10, "mmamammmmammamamaaamammma"); 92 | 93 | // 11 SLOW PULSE NOT FADE TO BLACK 94 | lightstyle(11, "abcdefghijklmnopqrrqponmlkjihgfedcba"); 95 | 96 | // styles 32-62 are assigned by the light program for switchable lights 97 | 98 | // 63 testing 99 | lightstyle(63, "a"); 100 | }; -------------------------------------------------------------------------------- /src/renderer_dll/win_qgl.h: -------------------------------------------------------------------------------- 1 | /* 2 | pragma 3 | Copyright (C) 2023-2024 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | 8 | See the attached GNU General Public License v2 for more details. 9 | */ 10 | // win_qgl.h 11 | 12 | #ifndef __QGL_H__ 13 | #define __QGL_H__ 14 | 15 | #ifdef _WIN32 16 | # include 17 | #endif 18 | 19 | //#include 20 | 21 | qboolean QGL_Init( const char *dllname ); 22 | void QGL_Shutdown( void ); 23 | 24 | #ifndef APIENTRY 25 | # define APIENTRY 26 | #endif 27 | 28 | #ifdef _WIN32 29 | 30 | extern int ( WINAPI * qwglChoosePixelFormat )(HDC, CONST PIXELFORMATDESCRIPTOR *); 31 | extern int ( WINAPI * qwglDescribePixelFormat) (HDC, int, UINT, LPPIXELFORMATDESCRIPTOR); 32 | extern int ( WINAPI * qwglGetPixelFormat)(HDC); 33 | extern BOOL ( WINAPI * qwglSetPixelFormat)(HDC, int, CONST PIXELFORMATDESCRIPTOR *); 34 | extern BOOL ( WINAPI * qwglSwapBuffers)(HDC); 35 | 36 | extern BOOL ( WINAPI * qwglCopyContext)(HGLRC, HGLRC, UINT); 37 | extern HGLRC ( WINAPI * qwglCreateContext)(HDC); 38 | extern HGLRC ( WINAPI * qwglCreateLayerContext)(HDC, int); 39 | extern BOOL ( WINAPI * qwglDeleteContext)(HGLRC); 40 | extern HGLRC ( WINAPI * qwglGetCurrentContext)(VOID); 41 | extern HDC ( WINAPI * qwglGetCurrentDC)(VOID); 42 | extern PROC ( WINAPI * qwglGetProcAddress)(LPCSTR); 43 | extern BOOL ( WINAPI * qwglMakeCurrent)(HDC, HGLRC); 44 | extern BOOL ( WINAPI * qwglShareLists)(HGLRC, HGLRC); 45 | extern BOOL ( WINAPI * qwglUseFontBitmaps)(HDC, DWORD, DWORD, DWORD); 46 | 47 | extern BOOL ( WINAPI * qwglUseFontOutlines)(HDC, DWORD, DWORD, DWORD, FLOAT, 48 | FLOAT, int, LPGLYPHMETRICSFLOAT); 49 | 50 | extern BOOL ( WINAPI * qwglDescribeLayerPlane)(HDC, int, int, UINT, 51 | LPLAYERPLANEDESCRIPTOR); 52 | extern int ( WINAPI * qwglSetLayerPaletteEntries)(HDC, int, int, int, 53 | CONST COLORREF *); 54 | extern int ( WINAPI * qwglGetLayerPaletteEntries)(HDC, int, int, int, 55 | COLORREF *); 56 | extern BOOL ( WINAPI * qwglRealizeLayerPalette)(HDC, int, BOOL); 57 | extern BOOL ( WINAPI * qwglSwapLayerBuffers)(HDC, UINT); 58 | 59 | extern BOOL ( WINAPI * qwglSwapIntervalEXT)( int interval ); 60 | 61 | extern BOOL ( WINAPI * qwglGetDeviceGammaRampEXT ) ( unsigned char *pRed, unsigned char *pGreen, unsigned char *pBlue ); 62 | extern BOOL ( WINAPI * qwglSetDeviceGammaRampEXT ) ( const unsigned char *pRed, const unsigned char *pGreen, const unsigned char *pBlue ); 63 | 64 | #endif 65 | 66 | 67 | #endif 68 | -------------------------------------------------------------------------------- /src/engine/model_cache.h: -------------------------------------------------------------------------------- 1 | /* 2 | pragma 3 | Copyright (C) 2023-2024 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | 8 | See the attached GNU General Public License v2 for more details. 9 | */ 10 | 11 | #pragma once 12 | 13 | #ifndef _MODEL_CACHE_H_ 14 | #define _MODEL_CACHE_H_ 15 | 16 | // CACHE_CLIENT will load additional data for renderer 17 | // CACHE_SERVER will only load the bare minimum 18 | // CACHE_NONE means we no longer need the model 19 | typedef enum { CACHE_NONE, CACHE_SERVER, CACHE_CLIENT} cacheuser_t; 20 | 21 | typedef struct cached_model_s // !!! IF THIS IS CHANGED RENDERER MUST BE RECOMPILED !!! 22 | { 23 | char name[MAX_QPATH]; 24 | 25 | modtype_t type; 26 | cacheuser_t users[2]; // client & server 27 | 28 | int numFrames; 29 | int numParts; 30 | int numBones; 31 | 32 | vec3_t mins, maxs; 33 | 34 | cmodel_t* brush; 35 | pmodel_header_t* skel; 36 | md3Header_t* alias; 37 | 38 | // inversed skeleton matrix is created for bind pose 39 | mat4_t* pInverseSkeleton; 40 | 41 | // shared with everyone, accessible via: brush, skel or alias ptrs 42 | void* pData; 43 | int dataSize; 44 | 45 | // pRenderData is private to renderer 46 | void* pRenderData; 47 | int renderDataSize; 48 | } cached_model_t; 49 | 50 | 51 | const int Mod_NumCachedModels(); 52 | 53 | qboolean Mod_HasRenderData(cached_model_t* pModel); 54 | 55 | cached_model_t* Mod_Register(const cacheuser_t user, const char* name, const qboolean bMustLoad); 56 | //void Mod_Free(cached_model_t* pModel); 57 | void Mod_FreeUnused(const cacheuser_t user); 58 | void Mod_FreeAll(); 59 | 60 | mat4_t* Mod_GetInverseSkeletonMatrix(const cached_model_t* pModel); 61 | 62 | pmodel_bone_t* Mod_GetBonesPtr(const cached_model_t* pModel); 63 | panim_bonetrans_t* Mod_GetSkeletonPtr(const cached_model_t* pModel); 64 | pmodel_vertex_t* Mod_GetVertexesPtr(const cached_model_t* pModel); 65 | void* Mod_GetSurfacesPtr(const cached_model_t* pModel); 66 | void* Mod_GetPartsPtr(const cached_model_t* pModel); 67 | 68 | modtype_t Mod_GetType(const cached_model_t* pModel); 69 | int Mod_NumVerts(const cached_model_t* pModel); 70 | int Mod_NumFrames(const cached_model_t* pModel); 71 | int Mod_NumParts(const cached_model_t* pModel); 72 | int Mod_NumBones(const cached_model_t* pModel); 73 | 74 | int Mod_PartIndexForName(const cached_model_t* pModel, const char* partName); 75 | int Mod_BoneIndexForName(const cached_model_t* pModel, const char* boneName); 76 | 77 | // float Mod_GetCullRadius(const cached_model_t* pModel); 78 | //vec3_t Mod_GetCullMins(const cached_model_t* pModel); 79 | //vec3_t Mod_GetCullMaxs(const cached_model_t* pModel); 80 | 81 | #endif /*_MODEL_CACHE_H_*/ 82 | -------------------------------------------------------------------------------- /src/engine/client/cgame/progdefs_client.h: -------------------------------------------------------------------------------- 1 | /* 2 | pragma 3 | Copyright (C) 2023-2024 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | 8 | See the attached GNU General Public License v2 for more details. 9 | */ 10 | 11 | #ifndef _PRAGMA_PROGDEFS_CLIENT_H_ 12 | #define _PRAGMA_PROGDEFS_CLIENT_H_ 13 | 14 | #pragma once 15 | 16 | #ifndef scr_func_t 17 | typedef int32_t scr_func_t; 18 | // typedef vec3_t scr_vec_t; 19 | typedef int32_t scr_entity_t; 20 | typedef int32_t scr_string_t; 21 | #endif 22 | 23 | // prog globals 24 | typedef struct cl_globalvars_s 25 | { 26 | int32_t pad[28]; 27 | 28 | float frametime; // seconds since last frame 29 | int32_t time; // this is the time value that the clientis rendering at. always <= realtime between oldframe and frame 30 | int32_t realtime; // always increasing, no clamping 31 | 32 | int32_t vid_width; 33 | int32_t vid_height; 34 | 35 | float localplayernum; // packetentity number of local player 36 | 37 | scr_entity_t self; 38 | scr_entity_t other; 39 | 40 | vec3_t v_forward, v_up, v_right; 41 | 42 | float trace_allsolid, trace_startsolid, trace_fraction, trace_plane_dist; 43 | vec3_t trace_endpos, trace_plane_normal; 44 | float trace_entnum; 45 | int32_t trace_contents; 46 | scr_string_t trace_surface_name; 47 | float trace_surface_flags; 48 | float trace_surface_value; 49 | scr_entity_t trace_ent; 50 | 51 | float pm_state_pm_type; // byte pmtype_t 52 | vec3_t pm_state_origin; // floats 53 | vec3_t pm_state_velocity; // floats 54 | float pm_state_gravity; // short 55 | vec3_t pm_state_mins; // char [-127,127 range] 56 | vec3_t pm_state_maxs; // char [-127,127 range] 57 | float pm_state_pm_flags; // byte [0-255] 58 | float pm_state_pm_time; // byte [0-255] 59 | vec3_t pm_state_delta_angles; // shorts, use ANGLE2SHORT/SHORT2ANGLE 60 | 61 | vec3_t cam_viewangles; // current camera angles 62 | vec3_t cam_viewoffset; // current camera position 63 | 64 | scr_func_t CG_Main; 65 | scr_func_t CG_Frame; 66 | scr_func_t CG_DrawGUI; 67 | scr_func_t CG_PlayerMove; // CG_PlayerMove(vector cmdMove, vector cmdAngles, float cmdMsec) 68 | scr_func_t CG_ParseCommandFromServer; // CG_ParseCommandFromServer(float cmd) // cmd is byte 0-255 limited 69 | } cl_globalvars_t; 70 | 71 | 72 | typedef struct cl_entvars_s 73 | { 74 | scr_string_t classname; 75 | 76 | scr_string_t model; 77 | int32_t modelindex; 78 | 79 | vec3_t mins; 80 | vec3_t maxs; 81 | 82 | vec3_t origin; 83 | vec3_t angles; 84 | 85 | float scale; 86 | vec3_t color; 87 | 88 | float fullbright; 89 | } cl_entvars_t; 90 | 91 | #endif /*_PRAGMA_PROGDEFS_CLIENT_H_*/ -------------------------------------------------------------------------------- /src/engine/script/qc_opcodes.h: -------------------------------------------------------------------------------- 1 | /* 2 | pragma 3 | Copyright (C) 2023-2024 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | 8 | See the attached GNU General Public License v2 for more details. 9 | */ 10 | 11 | /* Quake 1 QC vanilla opcodes */ 12 | OP_DONE, 13 | OP_MUL_F, 14 | OP_MUL_V, 15 | OP_MUL_FV, 16 | OP_MUL_VF, 17 | OP_DIV_F, 18 | OP_ADD_F, 19 | OP_ADD_V, 20 | OP_SUB_F, 21 | OP_SUB_V, 22 | 23 | OP_EQ_F, 24 | OP_EQ_V, 25 | OP_EQ_S, 26 | OP_EQ_E, 27 | OP_EQ_FNC, 28 | 29 | OP_NE_F, 30 | OP_NE_V, 31 | OP_NE_S, 32 | OP_NE_E, 33 | OP_NE_FNC, 34 | 35 | OP_LE, 36 | OP_GE, 37 | OP_LT, 38 | OP_GT, 39 | 40 | OP_LOAD_F, 41 | OP_LOAD_V, 42 | OP_LOAD_S, 43 | OP_LOAD_ENT, 44 | OP_LOAD_FLD, 45 | OP_LOAD_FNC, 46 | 47 | OP_ADDRESS, 48 | 49 | OP_STORE_F, 50 | OP_STORE_V, 51 | OP_STORE_S, 52 | OP_STORE_ENT, 53 | OP_STORE_FLD, 54 | OP_STORE_FNC, 55 | 56 | OP_STOREP_F, 57 | OP_STOREP_V, 58 | OP_STOREP_S, 59 | OP_STOREP_ENT, 60 | OP_STOREP_FLD, 61 | OP_STOREP_FNC, 62 | 63 | OP_RETURN, 64 | 65 | OP_NOT_F, 66 | OP_NOT_V, 67 | OP_NOT_S, 68 | OP_NOT_ENT, 69 | OP_NOT_FNC, 70 | 71 | OP_IF, 72 | OP_IFNOT, 73 | 74 | OP_CALL0, 75 | OP_CALL1, 76 | OP_CALL2, 77 | OP_CALL3, 78 | OP_CALL4, 79 | OP_CALL5, 80 | OP_CALL6, 81 | OP_CALL7, 82 | OP_CALL8, 83 | 84 | OP_STATE, 85 | 86 | OP_GOTO, 87 | OP_AND, 88 | OP_OR, 89 | 90 | OP_BITAND, 91 | OP_BITOR, 92 | 93 | /* ---- opcodes 66 to 112 are unsupported ---- */ 94 | 95 | /*FTE's INT all of it*/ 96 | OP_STORE_I = 113, 97 | OP_STORE_IF, 98 | OP_STORE_FI, 99 | 100 | OP_ADD_I, 101 | OP_ADD_FI, 102 | OP_ADD_IF, 103 | 104 | OP_SUB_I, 105 | OP_SUB_FI, 106 | OP_SUB_IF, 107 | 108 | OP_CONV_ITOF, 109 | OP_CONV_FTOI, 110 | OP_LOADP_ITOF, // unsupported 111 | OP_LOADP_FTOI, // unsupported 112 | OP_LOAD_I, 113 | OP_STOREP_I, 114 | OP_STOREP_IF, 115 | OP_STOREP_FI, 116 | 117 | OP_BITAND_I, 118 | OP_BITOR_I, 119 | 120 | OP_MUL_I, 121 | OP_DIV_I, 122 | OP_EQ_I, 123 | OP_NE_I, 124 | 125 | OP_NOT_I = 138, 126 | 127 | OP_BITXOR_I = 140, 128 | OP_RSHIFT_I, 129 | OP_LSHIFT_I, 130 | 131 | OP_LOADA_I = 151, // unsupported 132 | OP_LOADP_I = 160, // unsupported 133 | 134 | OP_LE_I, 135 | OP_GE_I, 136 | OP_LT_I, 137 | OP_GT_I, 138 | 139 | OP_LE_IF, 140 | OP_GE_IF, 141 | OP_LT_IF, 142 | OP_GT_IF, 143 | 144 | OP_LE_FI, 145 | OP_GE_FI, 146 | OP_LT_FI, 147 | OP_GT_FI, 148 | 149 | OP_EQ_IF, 150 | OP_EQ_FI, 151 | 152 | OP_MUL_IF = 179, 153 | OP_MUL_FI, 154 | OP_MUL_VI, 155 | OP_MUL_IV, 156 | OP_DIV_IF, 157 | OP_DIV_FI, 158 | OP_BITAND_IF, 159 | OP_BITOR_IF, 160 | OP_BITAND_FI, 161 | OP_BITOR_FI, 162 | OP_AND_I, 163 | OP_OR_I, 164 | OP_AND_IF, 165 | OP_OR_IF, 166 | OP_AND_FI, 167 | OP_OR_FI, 168 | OP_NE_IF, 169 | OP_NE_FI -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /src/engine/client/cgame/cg_weapon.c: -------------------------------------------------------------------------------- 1 | /* 2 | pragma 3 | Copyright (C) 2023-2024 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | 8 | See the attached GNU General Public License v2 for more details. 9 | */ 10 | 11 | #include "../client.h" 12 | #include "cg_local.h" 13 | 14 | void CG_AddViewMuzzleFlash(rentity_t* refent, player_state_t* ps); 15 | void CG_AddViewFlashLight(rentity_t* refent, player_state_t* ps); 16 | 17 | /* 18 | ============== 19 | CG_AddViewWeapon 20 | ============== 21 | */ 22 | void CG_AddViewWeapon(player_state_t* ps, player_state_t* ops) 23 | { 24 | rentity_t viewmodel; 25 | int i; 26 | 27 | // allow the gun to be completely removed but don't cull flashlight 28 | if (!cl_drawviewmodel->value) 29 | { 30 | CG_AddViewFlashLight(NULL, ps); 31 | return; 32 | } 33 | 34 | memset(&viewmodel, 0, sizeof(viewmodel)); 35 | 36 | if (gun_model && CL_CheatsAllowed()) 37 | viewmodel.model = gun_model; // development tool 38 | else 39 | viewmodel.model = CL_GetDrawModel(ps->viewmodel[0]); 40 | 41 | if (!viewmodel.model) 42 | return; 43 | 44 | // set up position 45 | for (i = 0; i < 3; i++) 46 | { 47 | viewmodel.origin[i] = cl.refdef.view.origin[i] + ops->viewmodel_offset[i] 48 | + cl.lerpfrac * (ps->viewmodel_offset[i] - ops->viewmodel_offset[i]); 49 | viewmodel.angles[i] = cl.refdef.view.angles[i] + LerpAngle(ops->viewmodel_angles[i], 50 | ps->viewmodel_angles[i], cl.lerpfrac); 51 | } 52 | 53 | if (gun_frame && CL_CheatsAllowed()) 54 | { 55 | // development tool 56 | viewmodel.frame = gun_frame; 57 | viewmodel.oldframe = gun_frame; 58 | viewmodel.backlerp = 1.0 - cl.lerpfrac; 59 | } 60 | else 61 | { 62 | viewmodel.frame = ps->viewmodel_frame; 63 | 64 | // just changed weapons, don't lerp from oldframe and remove muzzleflash if present 65 | if (ps->viewmodel[0] != ops->viewmodel[0]) 66 | { 67 | cl.muzzleflash_time = 0; 68 | viewmodel.oldframe = viewmodel.frame; 69 | viewmodel.backlerp = 1; 70 | } 71 | else 72 | { 73 | viewmodel.oldframe = ops->viewmodel_frame; 74 | viewmodel.backlerp = 1.0 - cl.lerpfrac; 75 | } 76 | } 77 | 78 | viewmodel.animbacklerp = viewmodel.backlerp; 79 | VectorCopy(viewmodel.origin, viewmodel.oldorigin); 80 | viewmodel.renderfx = RF_MINLIGHT | RF_DEPTHHACK | RF_VIEW_MODEL; 81 | 82 | V_AddEntity(&viewmodel); 83 | 84 | AnglesToAxis(viewmodel.angles, viewmodel.axis); // this is necessary to attach other entities to the model 85 | 86 | CG_AddViewMuzzleFlash(&viewmodel, ps); 87 | CG_AddViewFlashLight(&viewmodel, ps); 88 | 89 | // second viewmodel is arms so just copy all params to it 90 | if (ps->viewmodel[1]) 91 | { 92 | viewmodel.model = CL_GetDrawModel(ps->viewmodel[1]); 93 | V_AddEntity(&viewmodel); 94 | } 95 | } -------------------------------------------------------------------------------- /src/.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /src/renderer_dll/warpsin.h: -------------------------------------------------------------------------------- 1 | /* 2 | pragma 3 | Copyright (C) 2023-2024 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | 8 | See the attached GNU General Public License v2 for more details. 9 | */ 10 | 0, 0.19633, 0.392541, 0.588517, 0.784137, 0.979285, 1.17384, 1.3677, 11 | 1.56072, 1.75281, 1.94384, 2.1337, 2.32228, 2.50945, 2.69512, 2.87916, 12 | 3.06147, 3.24193, 3.42044, 3.59689, 3.77117, 3.94319, 4.11282, 4.27998, 13 | 4.44456, 4.60647, 4.76559, 4.92185, 5.07515, 5.22538, 5.37247, 5.51632, 14 | 5.65685, 5.79398, 5.92761, 6.05767, 6.18408, 6.30677, 6.42566, 6.54068, 15 | 6.65176, 6.75883, 6.86183, 6.9607, 7.05537, 7.14579, 7.23191, 7.31368, 16 | 7.39104, 7.46394, 7.53235, 7.59623, 7.65552, 7.71021, 7.76025, 7.80562, 17 | 7.84628, 7.88222, 7.91341, 7.93984, 7.96148, 7.97832, 7.99036, 7.99759, 18 | 8, 7.99759, 7.99036, 7.97832, 7.96148, 7.93984, 7.91341, 7.88222, 19 | 7.84628, 7.80562, 7.76025, 7.71021, 7.65552, 7.59623, 7.53235, 7.46394, 20 | 7.39104, 7.31368, 7.23191, 7.14579, 7.05537, 6.9607, 6.86183, 6.75883, 21 | 6.65176, 6.54068, 6.42566, 6.30677, 6.18408, 6.05767, 5.92761, 5.79398, 22 | 5.65685, 5.51632, 5.37247, 5.22538, 5.07515, 4.92185, 4.76559, 4.60647, 23 | 4.44456, 4.27998, 4.11282, 3.94319, 3.77117, 3.59689, 3.42044, 3.24193, 24 | 3.06147, 2.87916, 2.69512, 2.50945, 2.32228, 2.1337, 1.94384, 1.75281, 25 | 1.56072, 1.3677, 1.17384, 0.979285, 0.784137, 0.588517, 0.392541, 0.19633, 26 | 9.79717e-16, -0.19633, -0.392541, -0.588517, -0.784137, -0.979285, -1.17384, -1.3677, 27 | -1.56072, -1.75281, -1.94384, -2.1337, -2.32228, -2.50945, -2.69512, -2.87916, 28 | -3.06147, -3.24193, -3.42044, -3.59689, -3.77117, -3.94319, -4.11282, -4.27998, 29 | -4.44456, -4.60647, -4.76559, -4.92185, -5.07515, -5.22538, -5.37247, -5.51632, 30 | -5.65685, -5.79398, -5.92761, -6.05767, -6.18408, -6.30677, -6.42566, -6.54068, 31 | -6.65176, -6.75883, -6.86183, -6.9607, -7.05537, -7.14579, -7.23191, -7.31368, 32 | -7.39104, -7.46394, -7.53235, -7.59623, -7.65552, -7.71021, -7.76025, -7.80562, 33 | -7.84628, -7.88222, -7.91341, -7.93984, -7.96148, -7.97832, -7.99036, -7.99759, 34 | -8, -7.99759, -7.99036, -7.97832, -7.96148, -7.93984, -7.91341, -7.88222, 35 | -7.84628, -7.80562, -7.76025, -7.71021, -7.65552, -7.59623, -7.53235, -7.46394, 36 | -7.39104, -7.31368, -7.23191, -7.14579, -7.05537, -6.9607, -6.86183, -6.75883, 37 | -6.65176, -6.54068, -6.42566, -6.30677, -6.18408, -6.05767, -5.92761, -5.79398, 38 | -5.65685, -5.51632, -5.37247, -5.22538, -5.07515, -4.92185, -4.76559, -4.60647, 39 | -4.44456, -4.27998, -4.11282, -3.94319, -3.77117, -3.59689, -3.42044, -3.24193, 40 | -3.06147, -2.87916, -2.69512, -2.50945, -2.32228, -2.1337, -1.94384, -1.75281, 41 | -1.56072, -1.3677, -1.17384, -0.979285, -0.784137, -0.588517, -0.392541, -0.19633, 42 | -------------------------------------------------------------------------------- /progs_src/svgame/hud.qc: -------------------------------------------------------------------------------- 1 | /* 2 | pragma engine 3 | Copyright (C) 2023 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | */ 8 | // hud.q2c 9 | 10 | //float hud_pic_health; 11 | //float hud_pic_armor; 12 | 13 | /* 14 | "xl " - X pos [0+x] from left to right 15 | "xr " - X pos from right [width-val] 16 | "xv " - X middle [width/2+val] 17 | "yt " - Y pos [0+val] from top to bottom 18 | "yb " - Y pos from right [height-val] 19 | 20 | "yv " - Y pos middle [height/2+x] 21 | 22 | "if ... endif" - if X > 0 ..ops.. endif 23 | 24 | "pic " - draw image (does render it at pic's size) 25 | "img " - draw image strecthed to W/H 26 | 27 | "str " - print string 28 | "cstr " - print config string 29 | */ 30 | 31 | 32 | string hud_layoutstring_empty = ""; 33 | string hud_layoutstring_mp = ""; 34 | 35 | string hud_layoutstring_sp = 36 | "yb -35 " 37 | 38 | // health 39 | "if 1 " //STAT_HEALTH_VALUE 40 | "xl 10 " 41 | "pic 5 " 42 | "xl 40 " 43 | "hnum " 44 | "endif " 45 | ; 46 | 47 | void() HUD_SetStats = 48 | { 49 | // update hud 50 | 51 | setstat(self, STAT_HEALTH, self.health); 52 | // setstat(self, STAT_ARMOR, self.armor); 53 | 54 | // weapon 55 | setstat(self, STAT_WEAPON, self.weapon); 56 | setstat(self, STAT_AMMO, self.clipammo); 57 | setstat(self, STAT_AMMO_RESERVE, self.reserveammo); 58 | }; 59 | 60 | 61 | 62 | void() HUD_SetInitialStats = 63 | { 64 | // UNUSED 65 | // setstat(self, STAT_HEALTH_IMAGE, hud_pic_health); 66 | // setstat(self, STAT_ARMOR_IMAGE, hud_pic_armor); 67 | }; 68 | 69 | /* 70 | ============== 71 | HUD_SetLayout 72 | 73 | Set hud layout string for everyone or for a single player 74 | ============== 75 | */ 76 | void(entity who, string hudprogram) HUD_SetLayout = 77 | { 78 | if(isplayer(who)) 79 | { 80 | MSG_WriteByte(SVC_LAYOUT); 81 | MSG_WriteString(hudprogram); 82 | MSG_Unicast(who, true); // send reliable message 83 | } 84 | else 85 | { 86 | // send to everyone 87 | configstring(CS_HUD, hudprogram); 88 | } 89 | }; 90 | 91 | 92 | /* 93 | ============== 94 | HUD_Init 95 | 96 | Precache hud images and set default HUD program 97 | ============== 98 | */ 99 | void() HUD_Init = 100 | { 101 | // precache default images 102 | // hud_pic_health = precache_image("i_health"); 103 | // hud_pic_armor = precache_image("i_powershield"); 104 | 105 | // hud_layoutstring_mp = hud_layoutstring_sp; 106 | 107 | // set default HUD based on gametype 108 | if(cvar("deathmatch")) 109 | HUD_SetLayout( world, hud_layoutstring_mp ); 110 | else 111 | HUD_SetLayout( world, hud_layoutstring_empty ); 112 | }; -------------------------------------------------------------------------------- /src/engine/client/cgame/cg_lightstyles.c: -------------------------------------------------------------------------------- 1 | /* 2 | pragma 3 | Copyright (C) 2023-2024 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | 8 | See the attached GNU General Public License v2 for more details. 9 | */ 10 | 11 | #include "../client.h" 12 | #include "cg_local.h" 13 | 14 | /* 15 | ============================================================== 16 | 17 | LIGHT STYLE MANAGEMENT 18 | 19 | ============================================================== 20 | */ 21 | 22 | static CLightStyle_t cg_lightstyles[MAX_LIGHTSTYLES]; 23 | static int lastofs; 24 | 25 | /* 26 | ================ 27 | CG_ClearLightStyles 28 | ================ 29 | */ 30 | void CG_ClearLightStyles() 31 | { 32 | memset(cg_lightstyles, 0, sizeof(cg_lightstyles)); 33 | lastofs = -1; 34 | } 35 | 36 | /* 37 | ================ 38 | CG_RunLightStyles 39 | 40 | Advance light animation 41 | ================ 42 | */ 43 | void CG_RunLightStyles(void) 44 | { 45 | int ofs; 46 | int i; 47 | CLightStyle_t* ls; 48 | 49 | ofs = cl.time / 100; 50 | if (ofs == lastofs) 51 | return; 52 | lastofs = ofs; 53 | 54 | for (i = 0, ls = cg_lightstyles; i < MAX_LIGHTSTYLES; i++, ls++) 55 | { 56 | if (!ls->length) 57 | { 58 | ls->value[0] = ls->value[1] = ls->value[2] = 1.0; 59 | continue; 60 | } 61 | if (ls->length == 1) 62 | ls->value[0] = ls->value[1] = ls->value[2] = ls->map[0]; 63 | else 64 | ls->value[0] = ls->value[1] = ls->value[2] = ls->map[ofs % ls->length]; 65 | } 66 | } 67 | 68 | /* 69 | ================ 70 | CG_LightStyleFromConfigString 71 | 72 | sets lightstyle from configstring 73 | ================ 74 | */ 75 | void CG_LightStyleFromConfigString(int index) 76 | { 77 | char *config; 78 | size_t len; 79 | int k; 80 | 81 | if (index < 0) 82 | { 83 | Com_Error(ERR_DROP, "%s: index %i < 0", __FUNCTION__, index); 84 | return; //msvc 85 | } 86 | 87 | if (index >= MAX_LIGHTSTYLES) 88 | { 89 | Com_Error(ERR_DROP, "%s: index %i >= MAX_LIGHTSTYLES", __FUNCTION__, index); 90 | return; //msvc 91 | } 92 | 93 | config = cl.configstrings[index + CS_LIGHTS]; 94 | 95 | len = (int)strlen(config); 96 | if (len >= MAX_QPATH) 97 | Com_Error(ERR_DROP, "%s: style %i is too long", __FUNCTION__, index); 98 | 99 | cg_lightstyles[index].length = len; 100 | 101 | for (k = 0; k < len; k++) 102 | cg_lightstyles[index].map[k] = (float)(config[k] - 'a') / (float)('m' - 'a'); 103 | } 104 | 105 | /* 106 | ================ 107 | CG_AddLightStyles 108 | ================ 109 | */ 110 | void CG_AddLightStyles(void) 111 | { 112 | int i; 113 | CLightStyle_t* ls; 114 | 115 | for (i = 0, ls = cg_lightstyles; i < MAX_LIGHTSTYLES; i++, ls++) 116 | V_AddLightStyle(i, ls->value[0], ls->value[1], ls->value[2]); 117 | } 118 | 119 | 120 | -------------------------------------------------------------------------------- /src/tools/tools_shared.h: -------------------------------------------------------------------------------- 1 | /* 2 | prtool, part of pragma 3 | Copyright (C) 2024 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | 8 | See the attached GNU General Public License v2 for more details. 9 | */ 10 | 11 | #pragma once 12 | 13 | #ifdef _WIN32 14 | #define _CRT_SECURE_NO_DEPRECATE 15 | #define _WINDOWS_LEAN_AND_MEAN 16 | #endif 17 | 18 | typedef unsigned char byte; 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | //#include 27 | //#include 28 | 29 | #ifdef _WIN32 30 | #include 31 | //extern HANDLE hConsole; 32 | #define CON_COL_WHITE "" 33 | #define CON_COL_GREEN "" 34 | #define CON_COL_RED "" 35 | #define CON_COL_YELLOW "" 36 | #else 37 | #define CON_COL_WHITE "\x1B[37m" 38 | #define CON_COL_GREEN "\x1B[32m" 39 | #define CON_COL_RED "\x1B[31m" 40 | #define CON_COL_YELLOW "\x1B[33m" 41 | #endif 42 | 43 | #ifndef M_PI 44 | #define M_PI 3.14159265358979323846 45 | #endif 46 | 47 | #define MAX_QPATH 64 // maximum path length in quake filesystem (for includes from qcommon mostly) 48 | #define MAXPRINTMSG 4096 // maximum length of a print 49 | #define MAXLINELEN 512 // maximum length of a single line 50 | #define MAXPATH 512 // maximum path length in prtool 51 | 52 | #include "../common/mathlib.h" 53 | 54 | extern void* Com_SafeMalloc(const size_t size, const char* sWhere); 55 | 56 | extern void Com_Exit(const int code); 57 | 58 | extern int GetNumWarnings(); 59 | 60 | extern void Com_HappyPrintf(const char* text, ...); 61 | extern void Com_Printf(const char* text, ...); 62 | extern void Com_Warning(const char* text, ...); 63 | extern void Com_Error2(const char* text, ...); 64 | extern void Com_Error(const char* text, ...); 65 | 66 | extern FILE* Com_OpenReadFile(const char* filename, const int crash); 67 | extern FILE* Com_OpenWriteFile(const char* filename, const int crash); 68 | extern void Com_SafeRead(FILE* f, void* buffer, const unsigned int count); 69 | extern void Com_SafeWrite(FILE* f, void* buffer, const unsigned int count); 70 | extern long Com_FileLength(FILE* f); 71 | extern int Com_LoadFile(const char* filename, void** buffer, int crash); 72 | extern int Com_FileExists(const char* filename, ...); 73 | 74 | extern int Com_NumArgs(); 75 | extern char* Com_GetArg(int arg); 76 | extern char* Com_Args(); 77 | extern char* Com_Parse(char* data); 78 | extern void Com_Tokenize(char* text); 79 | 80 | extern int Com_EndianLong(int val); 81 | extern short Com_EndianShort(short val); 82 | extern float Com_EndianFloat(float val); 83 | 84 | extern int Com_stricmp(const char* s1, const char* s2); 85 | 86 | 87 | extern void ClearBounds(vec3_t mins, vec3_t maxs); 88 | extern void AddPointToBounds(vec3_t v, vec3_t mins, vec3_t maxs); 89 | extern float RadiusFromBounds(vec3_t mins, vec3_t maxs);; -------------------------------------------------------------------------------- /progs_src/cgame/cg_hud.qc: -------------------------------------------------------------------------------- 1 | /* 2 | pragma engine 3 | Copyright (C) 2023 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | */ 8 | 9 | //drawfill(float x, float y, float w, float h, vector color, float alpha) 10 | //drawstring(vector xy_align, float fontsize, vector color, float alpha, string text, ...) 11 | // todo add VA() builtin to save on loc :v 12 | 13 | /* 14 | XALIGN_LEFT = 0, 15 | XALIGN_RIGHT = 1, 16 | XALIGN_CENTER = 2 17 | */ 18 | 19 | void() HUD_BossBar = 20 | { 21 | vector xy_align; 22 | float width = 296 * cvar("bosshp"); 23 | 24 | if(!width) 25 | return; 26 | 27 | drawfill(250, 100, 300, 18, '0 0 0', 0.7); 28 | drawfill(252, 103, width, 12, '1 0 0', 0.5); 29 | 30 | xy_align = '400 104 2'; 31 | drawstring(xy_align, 1.0, '1 1 0', 1, cvarstring("bossname")); 32 | }; 33 | 34 | 35 | void() HUD_DrawHealth = 36 | { 37 | vector xy_align; 38 | float health = getstat(STAT_HEALTH); 39 | 40 | xy_align = '5 570 0'; 41 | drawstring(xy_align, 1.2, '1 1 1', 1, ftos(health), " HP"); 42 | }; 43 | 44 | void() HUD_DrawCurrentWeaponStats = 45 | { 46 | vector xy_align; 47 | float weapon; 48 | 49 | weapon = getstat(STAT_WEAPON); 50 | if(weapon <= 0) 51 | return; 52 | 53 | // ammo 54 | float clip = getstat(STAT_AMMO); 55 | float reserve = getstat(STAT_AMMO_RESERVE); 56 | 57 | // out of ammo warning 58 | if( !clip && !reserve ) 59 | { 60 | xy_align = '400 450 2'; 61 | drawstring(xy_align, 1.1, '1 0 0', 1, "[OUT OF AMMO]"); 62 | } 63 | // else if( !clip && reserve ) 64 | // { 65 | // xy_align = '400 450 2'; 66 | // drawstring(xy_align, 1, '1 0 0', 0.7, "[ RELOAD ]"); 67 | // } 68 | 69 | 70 | // weapon name 71 | xy_align = '795 560 1'; 72 | drawstring(xy_align, 0.8, '1 1 1', 1, GetWeaponNameForNum(weapon)); 73 | 74 | // ammo in magazine 75 | xy_align = '755 570 1'; 76 | if(clip > (GetWeaponMaxClipAmmo(weapon)/3)) 77 | drawstring(xy_align, 1.2, '1 1 1', 1, ftos(clip)); 78 | else //draw red to indicate low ammo 79 | drawstring(xy_align, 1.2, '1 0 0', 1, ftos(clip)); 80 | 81 | if(IsWeaponClipOnly(weapon) == 0) 82 | { 83 | xy_align = '795 570 1'; 84 | drawstring(xy_align, 1.2, '1 1 1', 1, ftos(reserve)); 85 | } 86 | }; 87 | 88 | 89 | void() HUD_DeadScreen = 90 | { 91 | vector xy_align; 92 | 93 | drawfill(200, 285, 400, 28, '0 0 0', 0.5); 94 | 95 | xy_align = '400 290 2'; 96 | drawstring(xy_align, 2, '1 0.2 0.2', 1, "You are dead"); 97 | 98 | xy_align = '400 330 2'; 99 | drawstring(xy_align, 0.8, '1 1 1', 1, "press SPACE to respawn"); 100 | }; 101 | 102 | 103 | // 104 | // draw minimalistic hud 105 | // 106 | void() CG_DrawHUD = 107 | { 108 | // there should be a spectator hud too 109 | 110 | if( getstat(STAT_HEALTH) <= 0 ) 111 | { 112 | HUD_DeadScreen(); 113 | return; 114 | } 115 | 116 | HUD_DrawHealth(); 117 | HUD_DrawCurrentWeaponStats(); 118 | 119 | HUD_BossBar(); 120 | 121 | CG_DebugGUI(); 122 | }; 123 | -------------------------------------------------------------------------------- /progs_src/svgame/effects.qc: -------------------------------------------------------------------------------- 1 | /* 2 | pragma engine 3 | Copyright (C) 2023 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | */ 8 | // effects.qc 9 | 10 | 11 | float TE_FLASHLIGHT = 36; 12 | void(entity src, vector pos) FX_FlashLight = 13 | { 14 | // short short pos pos 15 | MSG_WriteByte(SVC_TEMP_ENTITY); 16 | MSG_WriteByte(TE_FLASHLIGHT); 17 | MSG_WritePos(pos); 18 | MSG_WriteShort( getentnum(src) ); 19 | MSG_Multicast(pos, MULTICAST_PVS); 20 | }; 21 | 22 | void(vector pos) FX_Flame = 23 | { 24 | // short short pos pos 25 | MSG_WriteByte(SVC_TEMP_ENTITY); 26 | MSG_WriteByte(TE_FLAME); 27 | MSG_WritePos(pos); 28 | MSG_Multicast(pos, MULTICAST_PVS); 29 | }; 30 | 31 | void(vector start, vector end) FX_DebugLine = 32 | { 33 | // short short pos pos 34 | MSG_WriteByte(SVC_TEMP_ENTITY); 35 | MSG_WriteByte(TE_DEBUGTRAIL); 36 | MSG_WritePos(start); 37 | MSG_WritePos(end); 38 | MSG_Multicast(start, MULTICAST_ALL); 39 | }; 40 | 41 | void(entity src, entity dst, vector start, vector end) FX_Lighting = 42 | { 43 | // short short pos pos 44 | MSG_WriteByte(SVC_TEMP_ENTITY); 45 | MSG_WriteByte(TE_LIGHTNING); 46 | MSG_WriteShort( getentnum(src) ); 47 | MSG_WriteShort( getentnum(dst) ); 48 | MSG_WritePos(start); 49 | MSG_WritePos(end); 50 | MSG_Multicast(start, MULTICAST_ALL); 51 | }; 52 | 53 | 54 | void(vector pos, vector start, vector end) FX_RailTrail = 55 | { 56 | MSG_WriteByte(SVC_TEMP_ENTITY); 57 | MSG_WriteByte(TE_RAILTRAIL); 58 | MSG_WritePos(start); 59 | MSG_WritePos(end); 60 | MSG_Multicast(pos, MULTICAST_PHS); 61 | }; 62 | 63 | void(vector pos, string fx) FX_Explosion = 64 | { 65 | float fxnum; 66 | if( fx == "small" ) 67 | fxnum = TE_EXPLOSION2; 68 | else if( fx == "medium" ) 69 | fxnum = TE_EXPLOSION1; 70 | 71 | MSG_WriteByte(SVC_TEMP_ENTITY); 72 | MSG_WriteByte(fxnum); 73 | MSG_WritePos(pos); 74 | MSG_Multicast(pos, MULTICAST_PHS /*MULTICAST_PVS*/); 75 | }; 76 | 77 | /* 78 | ============== 79 | FX_BulletImpact 80 | ============== 81 | */ 82 | void(vector pos, vector normal, string fx) FX_BulletImpact = 83 | { 84 | float fxnum; 85 | 86 | if( fx == "blood" ) 87 | fxnum = TE_BLOOD; 88 | else if( fx == "blood_green" ) 89 | fxnum = TE_GREENBLOOD; 90 | else if( fx == "sparks" ) 91 | fxnum = TE_SPARKS; 92 | else /*if( fx == "generic" )*/ 93 | fxnum = TE_GUNSHOT; 94 | 95 | MSG_WriteByte(SVC_TEMP_ENTITY); 96 | MSG_WriteByte(fxnum); 97 | MSG_WritePos(pos); 98 | MSG_WriteDir(normal); 99 | MSG_Multicast(pos, MULTICAST_PVS); 100 | }; 101 | 102 | 103 | /* 104 | ============== 105 | FX_Muzzleflash 106 | Player weapon fire sound and casts a muzzle flash 107 | ============== 108 | */ 109 | void(entity ent, float fx) FX_Muzzleflash = 110 | { 111 | //svc_muzzleflash [entnum] [muzzleflashfx] 112 | 113 | MSG_WriteByte(SVC_MUZZLEFLASH); 114 | MSG_WriteShort( getentnum(ent) ); 115 | MSG_WriteByte(fx); 116 | MSG_Multicast (ent.origin + '0 0 4', MULTICAST_PVS); 117 | }; -------------------------------------------------------------------------------- /progs_src/svgame/ents/target_speaker.qc: -------------------------------------------------------------------------------- 1 | /* 2 | P R A G M A 3 | Copyright (C) 2023 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | */ 8 | 9 | 10 | /*QUAKED target_speaker (1 0 0) (-8 -8 -8) (8 8 8) LOOPED_ON LOOPED_OFF RELIABLE 11 | Normal sounds play each time the target is used. The reliable flag can be set for crucial sounds 12 | Looped sounds are allways ATTN_STATIC / vol 1, and the use function toggles it on/off. 13 | Multiple identical looping sounds will just increase volume without any speed cost. 14 | 15 | LOOPED_ON speaker will play looping sound 16 | LOOPED_OFF speaker needs to be triggered to play a looping sound 17 | RELIABLE its guaranteed everyone on server will have this sound delivered 18 | 19 | "message" wav file to play 20 | 21 | "volume" 0.0 to 1.0 (default 1) 22 | "attenuation": default 0 (normal) 23 | 0 normal 24 | 1 static 25 | 2 diminish very rapidly with distance 26 | 3 full volume the entire level 27 | */ 28 | void(entity user) target_speaker_use = 29 | { 30 | float chan; 31 | 32 | if (self.spawnflags & SF_SPEAKER_LOOPED_ON || self.spawnflags & SF_SPEAKER_LOOPED_OFF) 33 | { 34 | // looping sound toggles 35 | if (self.loopsound) 36 | self.loopsound = 0; 37 | else 38 | self.loopsound = self.noise_index; 39 | } 40 | else 41 | { 42 | // normal sound 43 | if (self.spawnflags & SF_SPEAKER_RELIABLE) 44 | chan = CHAN_VOICE|CHAN_RELIABLE; 45 | else 46 | chan = CHAN_VOICE; 47 | 48 | // use a positioned_sound, because this entity won't normally be 49 | // sent to any clients because it is invisible 50 | playsound(self.origin, self, chan, self.message, self.volume, self.attenuation, 0); 51 | } 52 | }; 53 | 54 | float() SP_target_speaker = 55 | { 56 | if(!strlen(self.message)) 57 | { 58 | print("target_speaker with no sound ('message' key) set at ", vtos(self.origin), "\n"); 59 | return false; 60 | } 61 | 62 | // remap attenuation to engine defs 63 | if (self.attenuation == 0) 64 | self.attenuation = ATTN_NORM; 65 | else if (self.attenuation == 1) 66 | self.attenuation = ATTN_IDLE; 67 | else if (self.attenuation == 2) 68 | self.attenuation = ATTN_STATIC; 69 | else if (self.attenuation == 3) 70 | self.attenuation = ATTN_NONE; 71 | else 72 | { 73 | print("target_speaker at ", vtos(self.origin), " has attenuation set to unknown value ", ftos(self.attenuation), "\n"); 74 | return false; 75 | } 76 | 77 | self.noise_index = precache_sound(self.message); 78 | if(!self.noise_index) 79 | { 80 | print("target_speaker at ", vtos(self.origin), " has unknown sound ", self.message, "\n"); 81 | return false; 82 | } 83 | // self.message = ""; 84 | 85 | if (!self.volume) 86 | self.volume = 1.0; 87 | 88 | // check for prestarted looping sound 89 | if (self.spawnflags & SF_SPEAKER_LOOPED_ON) 90 | self.loopsound = self.noise_index; 91 | 92 | self.use = target_speaker_use; 93 | 94 | // must link the entity so we get areas and clusters so 95 | // the server can determine who to send updates to 96 | linkentity(self); 97 | return true; 98 | }; -------------------------------------------------------------------------------- /src/engine/pragma_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | pragma 3 | Copyright (C) 2023-2024 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | 8 | See the attached GNU General Public License v2 for more details. 9 | */ 10 | 11 | // 12 | // MAIN CONFIGURATION FILE FOR ENGINE 13 | // 14 | 15 | #ifndef PRAGMA_CONFIG_INCLUDED 16 | #define PRAGMA_CONFIG_INCLUDED 1 17 | 18 | #pragma once 19 | 20 | // what renderer DLL to use by default 21 | #define DEFAULT_RENDERER "gl2" 22 | 23 | // main engine directory to load assets from (the default 'game' directory) 24 | #define BASEDIRNAME "main" 25 | 26 | // define this to dissalow any data but the pak0.pak matching checksum below 27 | //#define NO_ADDONS 28 | 29 | // if a packfile directory differs from this, it is assumed to be hacked 30 | #define PAK0_CHECKSUM 0x40e614e0 31 | 32 | // Enable fix for "stupid quake bug" 33 | #define FIX_SQB 1 34 | 35 | // Include new GUI system 36 | #define NEW_GUI 1 37 | 38 | 39 | // See protocol.h for MORE! 40 | 41 | // protocol can use shorts when modelindex or soundindex exceed byte 42 | 43 | #define MAX_CLIENTS 12 // maximum number of client slots 44 | #define MAX_GENTITIES 2048 // number of game entities 45 | #define MAX_LIGHTSTYLES 256 // number of light styles 46 | 47 | #define MAX_ITEMS 256 // general config strings 48 | #define MAX_GENERAL (MAX_CLIENTS*2) // general config strings 49 | 50 | 51 | #define MAX_MODELS 512 // number of models (excluding inline models), always short 52 | #define MAX_SOUNDS 512 53 | #define MAX_IMAGES 256 54 | 55 | #if (MAX_SOUNDS > 256) 56 | #define PROTO_SHORT_INDEXES 1 57 | #endif 58 | 59 | 60 | 61 | 62 | // experimental -- variable server fps 63 | #define SERVER_FPS 10 // quake 2 64 | //#define SERVER_FPS 20 // default 65 | //#define SERVER_FPS 40 66 | 67 | #if SERVER_FPS == 10 68 | #define SV_FRAMETIME 0.1 69 | #define SV_FRAMETIME_MSEC 100 70 | #elif SERVER_FPS == 20 71 | #define SV_FRAMETIME 0.05 72 | #define SV_FRAMETIME_MSEC 50 73 | #elif SERVER_FPS == 40 74 | #define SV_FRAMETIME 0.025 75 | #define SV_FRAMETIME_MSEC 25 76 | #else 77 | #pragma error "Wrong SERVER_FPS" 78 | #endif 79 | 80 | // version string 81 | #define PRAGMA_VERSION "0.34" 82 | #define PRAGMA_TIMESTAMP (__DATE__ " " __TIME__) 83 | 84 | // version history: 85 | // 0.34 - 24.09.2024 -- inline models separated from external models 86 | // 0.33 - 22.09.2024 -- lots of fixes from over time 87 | // 0.32 - 08.09.2024 -- source tree cleanup 88 | // 0.31 - 03.09.2024 -- prtool and pragma's own model/anim formats 89 | // 0.30 - xx.xx.2024 -- skeletal models 90 | // 0.29 - xx.xx.2024 -- lighting overhaul 91 | // 0.28 - 22.03.2024 -- BSPX, QBISM, DECOUPLEDLM, LMSHIFT 92 | // 0.27 - 02.03.2024 -- experimental renderer 93 | // 0.26 - 21.02.2024 94 | // 0.25 - 18.01.2024 -- linux dedicated server 95 | // 0.24 - 17.01.2024 -- win32 dedicated server 96 | // 0.23 - 04.01.2024 97 | 98 | //#define DEDICATED_ONLY 1 99 | 100 | #endif /*PRAGMA_CONFIG_INCLUDED*/ 101 | -------------------------------------------------------------------------------- /src/engine/cvar.h: -------------------------------------------------------------------------------- 1 | /* 2 | pragma 3 | Copyright (C) 2023-2024 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | 8 | See the attached GNU General Public License v2 for more details. 9 | */ 10 | 11 | #pragma once 12 | 13 | /* 14 | ============================================================== 15 | CONSOLE VARIABLES 16 | 17 | cvar_t variables are used to hold scalar or string variables that can be changed or displayed at the console or prog code as well as accessed directly 18 | in C code. 19 | 20 | The user can access cvars from the console in three ways: 21 | r_draworder prints the current value 22 | r_draworder 0 sets the current value to 0 23 | set r_draworder 0 as above, but creates the cvar if not present 24 | Cvars are restricted from having the same names as commands to keep this 25 | interface from being ambiguous. 26 | ============================================================== 27 | */ 28 | 29 | #ifndef _PRAGMA_CVAR_H_ 30 | #define _PRAGMA_CVAR_H_ 31 | 32 | extern cvar_t* cvar_vars; 33 | 34 | cvar_t* Cvar_Get(const char* var_name, const char* value, int flags, const char* description); 35 | // creates the variable if it doesn't exist, or returns the existing one 36 | // if it exists, the value will not be changed, but flags will be ORed in 37 | // that allows variables to be unarchived without needing bitflags 38 | 39 | cvar_t* Cvar_Set(const char* var_name, const char* value); 40 | // will create the variable if it doesn't exist 41 | 42 | cvar_t* Cvar_ForceSet(const char* var_name, const char* value); 43 | // will set the variable even if NOSET or LATCH 44 | 45 | cvar_t* Cvar_FullSet(const char* var_name, const char* value, int flags, const char* desc); 46 | 47 | void Cvar_SetValue(const char* var_name, float value); 48 | // expands value to a string and calls Cvar_Set 49 | 50 | float Cvar_VariableValue(const char* var_name); 51 | // returns 0 if not defined or non numeric 52 | 53 | char* Cvar_VariableString(const char* var_name); 54 | // returns an empty string if not defined 55 | 56 | char* Cvar_CompleteVariable(const char* partial); 57 | // attempts to match a partial variable name for command line completion 58 | // returns NULL if nothing fits 59 | 60 | void Cvar_GetLatchedVars(void); 61 | // any CVAR_LATCHED variables that have been set will now take effect 62 | 63 | qboolean Cvar_Command(void); 64 | // called by Cmd_ExecuteString when Cmd_Argv(0) doesn't match a known 65 | // command. Returns true if the command was a variable reference that 66 | // was handled. (print or change) 67 | 68 | void Cvar_WriteVariables(const char* path); 69 | // appends lines containing "set variable value" for all variables 70 | // with the archive flag set to true. 71 | 72 | void Cvar_Init(void); 73 | 74 | char* Cvar_Userinfo(void); 75 | // returns an info string containing all the CVAR_USERINFO cvars 76 | 77 | char* Cvar_Serverinfo(void); 78 | // returns an info string containing all the CVAR_SERVERINFO cvars 79 | 80 | extern qboolean userinfo_modified; 81 | // this is set each time a CVAR_USERINFO variable is changed 82 | // so that the client knows to send it to the server 83 | #endif 84 | -------------------------------------------------------------------------------- /src/common/crc.c: -------------------------------------------------------------------------------- 1 | /* 2 | pragma 3 | Copyright (C) 2023-2024 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | 8 | See the attached GNU General Public License v2 for more details. 9 | */ 10 | 11 | // see crc.h 12 | 13 | #include "../engine/pragma.h" 14 | 15 | 16 | #define CRC_INIT_VALUE 0xffff 17 | #define CRC_XOR_VALUE 0x0000 18 | 19 | static unsigned short crctable[256] = 20 | { 21 | 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 22 | 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, 23 | 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, 24 | 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, 25 | 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, 26 | 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, 27 | 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, 28 | 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, 29 | 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, 30 | 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, 31 | 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, 32 | 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, 33 | 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, 34 | 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, 35 | 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, 36 | 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, 37 | 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, 38 | 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, 39 | 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, 40 | 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, 41 | 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, 42 | 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 43 | 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, 44 | 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, 45 | 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, 46 | 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, 47 | 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, 48 | 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, 49 | 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, 50 | 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, 51 | 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, 52 | 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0 53 | }; 54 | 55 | void CRC_Init(unsigned short *crcvalue) 56 | { 57 | *crcvalue = CRC_INIT_VALUE; 58 | } 59 | 60 | void CRC_ProcessByte(unsigned short *crcvalue, byte data) 61 | { 62 | *crcvalue = (*crcvalue << 8) ^ crctable[(*crcvalue >> 8) ^ data]; 63 | } 64 | 65 | unsigned short CRC_Value(unsigned short crcvalue) 66 | { 67 | return crcvalue ^ CRC_XOR_VALUE; 68 | } 69 | 70 | unsigned short CRC_Block (byte *start, int count) 71 | { 72 | unsigned short crc; 73 | 74 | CRC_Init (&crc); 75 | while (count--) 76 | crc = (crc << 8) ^ crctable[(crc >> 8) ^ *start++]; 77 | 78 | return crc; 79 | } 80 | 81 | -------------------------------------------------------------------------------- /src/engine/client/fx/fx_main.c: -------------------------------------------------------------------------------- 1 | /* 2 | pragma 3 | Copyright (C) 2023-2024 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | 8 | See the attached GNU General Public License v2 for more details. 9 | */ 10 | 11 | #include "../client.h" 12 | #include "fx_local.h" 13 | 14 | fxsysstate_t fxSys; 15 | 16 | static cvar_t* fx_show; 17 | 18 | 19 | int FX_GetNumLoadedEffects() // FIXME 20 | { 21 | return fxSys.numLoadedEffects; 22 | } 23 | 24 | int FX_GetNumTags() // FIXME 25 | { 26 | return 1; 27 | } 28 | 29 | 30 | // void CL_NewDynamicPointLight(int key, float x, float y, float z, float radius, float time) 31 | 32 | /* 33 | ================= 34 | CL_FindEffect 35 | ================= 36 | */ 37 | int CL_FindEffect(char* name) 38 | { 39 | for (int i = 0; i < FX_GetNumLoadedEffects(); i++) 40 | { 41 | if (!fxSys.fxDefs[i] || !fxSys.fxDefs[i]->name[0]) 42 | continue; 43 | 44 | if (!Q_stricmp(name, fxSys.fxDefs[i]->name)) 45 | return i; 46 | } 47 | return -1; 48 | } 49 | 50 | 51 | static void Cmd_LoadFX_f(void) 52 | { 53 | char* name = Cmd_Argv(1); 54 | if (Cmd_Argc() != 2) 55 | { 56 | Com_Printf("loadfx : load effect (fx/.fx)\n"); 57 | return; 58 | } 59 | 60 | FX_LoadFromFile(Cmd_Argv(1)); 61 | } 62 | 63 | static void Cmd_PlayFX_f(void) 64 | { 65 | char* name = Cmd_Argv(1); 66 | if (Cmd_Argc() != 2) 67 | { 68 | Com_Printf("playfx x y z: play effect at xyz\n"); 69 | return; 70 | } 71 | } 72 | 73 | /* 74 | ================= 75 | FX_ClearParticles 76 | ================= 77 | */ 78 | void FX_ClearParticles() 79 | { 80 | int i; 81 | 82 | memset(fxSys.particles, 0, sizeof(fxSys.particles)); 83 | fxSys.free_particles = &fxSys.particles[0]; 84 | fxSys.active_particles = NULL; 85 | 86 | for (i = 0; i < FX_MAX_PARTICLES; i++) 87 | { 88 | fxSys.particles[i].next = &fxSys.particles[i + 1]; 89 | } 90 | 91 | fxSys.particles[FX_MAX_PARTICLES - 1].next = NULL; 92 | } 93 | 94 | 95 | 96 | 97 | 98 | static void FX_FreeEffects() 99 | { 100 | Z_FreeTags(TAG_FX); 101 | memset(&fxSys.fxDefs, 0, sizeof(fxSys.fxDefs)); 102 | fxSys.numLoadedEffects = 0; 103 | 104 | for (int i = 0; i < FX_MAX_ACTIVE_EFFECTS; i++) 105 | { 106 | 107 | } 108 | } 109 | 110 | /* 111 | ================= 112 | CL_InitEffects 113 | ================= 114 | */ 115 | void CL_InitEffects() 116 | { 117 | fx_show = Cvar_Get("fx_show", "1", CVAR_CHEAT, NULL); 118 | 119 | FX_ClearParticles(); 120 | 121 | if (fxSys.numLoadedEffects > 0) 122 | { 123 | Z_FreeTags(TAG_FX); 124 | } 125 | 126 | memset(&fxSys, 0, sizeof(fxSys)); 127 | 128 | Com_Printf("... max particles : %i\n", FX_MAX_PARTICLES); 129 | Com_Printf("... max fx runners : %i\n", FX_MAX_ACTIVE_EFFECTS); 130 | Com_Printf("... max effects : %i\n", FX_MAX_EFFECTS); 131 | 132 | Cmd_AddCommand("loadfx", Cmd_LoadFX_f); 133 | Cmd_AddCommand("playfx", Cmd_PlayFX_f); 134 | 135 | Com_Printf("Initialized FX system.\n"); 136 | } 137 | 138 | 139 | /* 140 | ================= 141 | CL_ShutdownEffects 142 | ================= 143 | */ 144 | void CL_ShutdownEffects() 145 | { 146 | FX_FreeEffects(); 147 | 148 | Cmd_RemoveCommand("loadfx"); 149 | Cmd_RemoveCommand("playfx"); 150 | 151 | } 152 | -------------------------------------------------------------------------------- /src/renderer_dll/pragma_renderer.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | include 6 | 7 | 8 | include 9 | 10 | 11 | include 12 | 13 | 14 | include 15 | 16 | 17 | include 18 | 19 | 20 | common 21 | 22 | 23 | common 24 | 25 | 26 | common 27 | 28 | 29 | common 30 | 31 | 32 | include 33 | 34 | 35 | common 36 | 37 | 38 | common 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | sys 55 | 56 | 57 | common 58 | 59 | 60 | sys 61 | 62 | 63 | sys 64 | 65 | 66 | common 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | sys 76 | 77 | 78 | 79 | 80 | 81 | 82 | {166774dd-64fd-4cbb-8c3a-9935c23f52c6} 83 | 84 | 85 | {6af85753-47d0-4090-8ec1-277bc0852ee2} 86 | 87 | 88 | {e472f71e-8143-4259-8f93-02322578c7ab} 89 | 90 | 91 | -------------------------------------------------------------------------------- /progs_src/svgame/weapons/weapon_blaster.qc: -------------------------------------------------------------------------------- 1 | /* 2 | pragma engine 3 | Copyright (C) 2023 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | */ 8 | // weapon_blaster.qc 9 | 10 | /* 11 | ================= 12 | blaster_effect 13 | ================= 14 | */ 15 | void(vec3 norm) blaster_effect = 16 | { 17 | MSG_WriteByte(svc_temp_entity); 18 | MSG_WriteByte(TE_BLASTER); 19 | MSG_WritePos(self.origin); 20 | MSG_WriteDir(norm); 21 | MSG_Multicast(self.origin, MULTICAST_PVS); 22 | }; 23 | 24 | /* 25 | ================= 26 | fire_blaster 27 | 28 | Fires a single blaster bolt. Used by the blaster and hyper blaster. 29 | ================= 30 | */ 31 | void blaster_touch (cplane_t *plane, csurface_t *surf) 32 | { 33 | if(other == self.owner) 34 | return; 35 | 36 | if(surf_flags & SURF_SKY)) 37 | { 38 | remove(self); 39 | return; 40 | } 41 | 42 | if(other.takedamage) 43 | { 44 | DoDamage(other, self, self.owner, self.velocity, self.origin, plane_normal, self.dmg, 1, DMG_BULLET); 45 | } 46 | else 47 | { 48 | blaster_effect(plane_normal); 49 | } 50 | 51 | remove(self); 52 | } 53 | 54 | 55 | void Blaster_Fire (edict_t *ent, vec3_t g_offset, int damage, qboolean hyper, int effect) 56 | { 57 | vec3_t forward, right; 58 | vec3_t start; 59 | vec3_t offset; 60 | 61 | if (is_quad) 62 | damage *= 4; 63 | AngleVectors (ent.client.v_angle, forward, right, NULL); 64 | VectorSet(offset, 24, 8, ent.viewheight-8); 65 | VectorAdd (offset, g_offset, offset); 66 | P_ProjectSource (ent.client, ent.s.origin, offset, forward, right, start); 67 | 68 | VectorScale (forward, -2, ent.client.kick_origin); 69 | ent.client.kick_angles[0] = -1; 70 | 71 | fire_blaster (ent, start, forward, damage, 1000, effect, hyper); 72 | 73 | // send muzzle flash 74 | gi.WriteByte (svc_muzzleflash); 75 | gi.WriteShort (ent-g_edicts); 76 | if (hyper) 77 | gi.WriteByte (MZ_HYPERBLASTER); 78 | else 79 | gi.WriteByte (MZ_BLASTER); 80 | gi.multicast (ent.s.origin, MULTICAST_PVS); 81 | 82 | PlayerNoise(ent, start, PNOISE_WEAPON); 83 | } 84 | 85 | 86 | void fire_blaster (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed, int effect, qboolean hyper) 87 | { 88 | edict_t *bolt; 89 | trace_t tr; 90 | 91 | VectorNormalize (dir); 92 | 93 | bolt = spawn(); 94 | bolt.svflags = SVF_DEADMONSTER; 95 | VectorCopy (start, bolt.s.origin); 96 | VectorCopy (start, bolt.s.old_origin); 97 | vectoangles (dir, bolt.s.angles); 98 | VectorScale (dir, speed, bolt.velocity); 99 | bolt.movetype = MOVETYPE_FLYMISSILE; 100 | bolt.clipmask = MASK_SHOT; 101 | bolt.solid = SOLID_BBOX; 102 | 103 | bolt.effects |= effect; 104 | VectorClear (bolt.mins); 105 | VectorClear (bolt.maxs); 106 | 107 | bolt.modelindex = precache_model("models/objects/laser/tris.md2"); 108 | bolt.sound = precache_sound("misc/lasfly.wav"); 109 | bolt.owner = self; 110 | bolt.touch = blaster_touch; 111 | bolt.nextthink = g_time + 2; 112 | bolt.think = SUB_RemoveMe; 113 | bolt.dmg = 10; 114 | bolt.classname = "bolt"; 115 | 116 | gi.linkentity (bolt); 117 | 118 | 119 | 120 | tr = traceline(self.origin, NULL, NULL, bolt.s.origin, bolt, MASK_SHOT); 121 | if (tr.fraction < 1.0) 122 | { 123 | VectorMA (bolt.s.origin, -10, dir, bolt.s.origin); 124 | bolt.touch (bolt, tr.ent, NULL, NULL); 125 | } 126 | } -------------------------------------------------------------------------------- /src/common/fileformats/pmodel.h: -------------------------------------------------------------------------------- 1 | /* 2 | pragma 3 | Copyright (C) 2023-2024 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | 8 | See the attached GNU General Public License v2 for more details. 9 | */ 10 | 11 | #ifndef _mod_pragma_h_ 12 | #define _mod_pragma_h_ 13 | 14 | /* 15 | MODEL 16 | ----- 17 | 18 | [pmodel_header_s] 19 | [pmodel_bone_s] * numBones 20 | [pmodel_bonetrans_t] * numBones 21 | [pmodel_vertex_s] * numVertexes 22 | [pmodel_surf_s] * numSurfaces 23 | [pmodel_part_s] * numParts 24 | */ 25 | 26 | /* 27 | ANIMATION 28 | --------- 29 | 30 | [panim_header_s] 31 | [panim_bone_s] * numBones 32 | [panim_bonetrans_s] * numBones * numFrames 33 | [panim_event_s] * numFrames 34 | */ 35 | 36 | #define PMODEL_IDENT (('D'<<24)+('M'<<16)+('R'<<8)+'P') // little-endian "PRMD" 37 | #define PMODEL_VERSION 4 38 | 39 | #define PANIM_IDENT (('N'<<24)+('A'<<16)+('R'<<8)+'P') // little-endian "PRAN" 40 | #define PANIM_VERSION 2 41 | 42 | // common 43 | #define PMOD_MAX_SURFNAME 64 // MAX_QPATH 44 | #define PMOD_MAX_MATNAME 64 // MAX_QPATH 45 | #define PMOD_MAX_BONENAME 32 46 | #define PMOD_MAX_HITPARTNAME 32 47 | #define PMOD_MAX_EVENTSTRING 64 // MAX_QPATH 48 | 49 | 50 | typedef struct pmodel_bone_s 51 | { 52 | int32_t number; 53 | int32_t parentIndex; 54 | char name[PMOD_MAX_BONENAME]; 55 | 56 | // hitboxes 57 | char partname[PMOD_MAX_HITPARTNAME]; // head, arm_upper, torso_lower, hand_left etc.. 58 | vec3_t mins, maxs; 59 | } pmodel_bone_t; 60 | 61 | typedef struct pmodel_vertex_s 62 | { 63 | vec3_t xyz; 64 | vec3_t normal; 65 | vec2_t uv; 66 | int32_t boneId; 67 | //short boneId; 68 | } pmodel_vertex_t; 69 | 70 | typedef struct pmodel_surface_s 71 | { 72 | char material[PMOD_MAX_MATNAME]; 73 | uint32_t firstVert; 74 | uint32_t numVerts; 75 | 76 | // reserved for engine use 77 | int32_t materialIndex; 78 | int32_t flags; 79 | } pmodel_surface_t; 80 | 81 | typedef struct pmodel_part_s 82 | { 83 | char name[PMOD_MAX_SURFNAME]; 84 | uint32_t firstSurf; 85 | uint32_t numSurfs; 86 | int32_t flags; // reserved for engine use 87 | } pmodel_part_t; 88 | 89 | typedef struct pmodel_header_s 90 | { 91 | int32_t ident; 92 | int32_t version; 93 | 94 | uint32_t flags; 95 | 96 | uint32_t numBones; 97 | uint32_t numVertexes; 98 | uint32_t numSurfaces; 99 | uint32_t numParts; 100 | 101 | vec3_t mins, maxs; 102 | float radius; 103 | 104 | // used by engine 105 | uint32_t ofs_bones; 106 | uint32_t ofs_skeleton; 107 | uint32_t ofs_vertexes; 108 | uint32_t ofs_surfaces; 109 | uint32_t ofs_parts; 110 | uint32_t ofs_end; 111 | } pmodel_header_t; 112 | 113 | typedef struct panim_bone_s 114 | { 115 | int32_t number; 116 | int32_t parentIndex; 117 | char name[PMOD_MAX_BONENAME]; 118 | } panim_bone_t; 119 | 120 | typedef struct panim_bonetrans_s 121 | { 122 | int32_t bone; 123 | vec3_t origin; 124 | vec3_t rotation; 125 | quat_t quat; // for engine use 126 | } panim_bonetrans_t; 127 | 128 | typedef struct panim_event_s 129 | { 130 | char str[PMOD_MAX_EVENTSTRING]; 131 | } panim_event_t; 132 | 133 | typedef struct panim_header_s 134 | { 135 | int32_t ident; 136 | int32_t version; 137 | 138 | uint32_t flags; 139 | uint32_t rate; 140 | 141 | uint32_t numBones; 142 | uint32_t numFrames; 143 | } panim_header_t; 144 | 145 | #endif /*_mod_pragma_h_*/ -------------------------------------------------------------------------------- /src/common/fileformats/md3.h: -------------------------------------------------------------------------------- 1 | /* 2 | pragma 3 | Copyright (C) 2023-2024 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | 8 | See the attached GNU General Public License v2 for more details. 9 | */ 10 | 11 | #ifndef _mod_md3_h_ 12 | #define _mod_md3_h_ 13 | 14 | /* 15 | ======================================================================== 16 | 17 | .MD3 triangle model file format 18 | 19 | MOD_ALIAS is MD3 20 | 21 | ======================================================================== 22 | */ 23 | 24 | /* 25 | ** md3Surface_t 26 | ** 27 | ** CHUNK SIZE 28 | ** header sizeof( md3Surface_t ) 29 | ** shaders sizeof( md3Shader_t ) * numShaders 30 | ** triangles[0] sizeof( md3Triangle_t ) * numTriangles 31 | ** st sizeof( md3St_t ) * numVerts 32 | ** XyzNormals sizeof( md3XyzNormal_t ) * numVerts * numFrames 33 | */ 34 | 35 | #define MD3_IDENT (('3'<<24)+('P'<<16)+('D'<<8)+'I') 36 | #define MD3_VERSION 15 37 | 38 | // limits 39 | #define MD3_MAX_TRIANGLES 8192 // per surface 40 | #define MD3_MAX_VERTS 4096 // per surface 41 | #define MD3_MAX_SHADERS 256 // per model 42 | #define MD3_MAX_FRAMES 1024 // per model 43 | #define MD3_MAX_SURFACES 8 // per model 44 | #define MD3_MAX_TAGS 16 // per frame 45 | #define MD3_MAX_NAME 64 // max tag and skin names len, this was MAX_QPATH 46 | 47 | #define MD3_XYZ_SCALE (1.0/64) // vertex scales 48 | 49 | typedef struct md3Frame_s 50 | { 51 | vec3_t bounds[2]; 52 | vec3_t localOrigin; 53 | float radius; 54 | char name[16]; 55 | } md3Frame_t; 56 | 57 | typedef struct md3Tag_s 58 | { 59 | char name[MD3_MAX_NAME]; // tag name 60 | vec3_t origin; 61 | vec3_t axis[3]; 62 | } md3Tag_t; 63 | 64 | 65 | typedef struct 66 | { 67 | int32_t ident; 68 | 69 | char name[MD3_MAX_NAME]; // polyset name 70 | 71 | int32_t flags; 72 | 73 | int32_t numFrames; // all surfaces in a model should have the same 74 | int32_t numShaders; // all surfaces in a model should have the same 75 | int32_t numVerts; 76 | int32_t numTriangles; 77 | 78 | int32_t ofsTriangles; 79 | 80 | int32_t ofsShaders; // offset from start of md3Surface_t 81 | int32_t ofsSt; // texture coords are common for all frames 82 | int32_t ofsXyzNormals; // numVerts * numFrames 83 | 84 | int32_t ofsEnd; // next surface follows 85 | } md3Surface_t; 86 | 87 | typedef struct 88 | { 89 | char name[MAX_QPATH]; 90 | int32_t shaderIndex; // for in-game use 91 | } md3Shader_t; 92 | 93 | typedef struct 94 | { 95 | int32_t indexes[3]; 96 | } md3Triangle_t; 97 | 98 | typedef struct 99 | { 100 | float st[2]; 101 | } md3St_t; 102 | 103 | typedef struct 104 | { 105 | int16_t xyz[3]; 106 | int16_t normal; 107 | } md3XyzNormal_t; 108 | 109 | typedef struct 110 | { 111 | int32_t ident; // == MD3_IDENT 112 | int32_t version; // == MD3_VERSION 113 | 114 | char name[MAX_QPATH]; // model name 115 | 116 | int32_t flags; 117 | 118 | int32_t numFrames; 119 | int32_t numTags; 120 | int32_t numSurfaces; 121 | 122 | int32_t numSkins; 123 | 124 | int32_t ofsFrames; // offset for first frame 125 | int32_t ofsTags; // numFrames * numTags 126 | int32_t ofsSurfaces; // first surface, others follow 127 | 128 | int32_t ofsEnd; // end of file 129 | } md3Header_t; 130 | 131 | #endif /*_mod_md3_h_*/ -------------------------------------------------------------------------------- /progs_src/svgame/fields.qc: -------------------------------------------------------------------------------- 1 | /* 2 | pragma engine 3 | Copyright (C) 2023 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | */ 8 | 9 | float developer, developer_script; // cvars for debugging 10 | 11 | // TODO move these 12 | .float noise_index; 13 | .float groundEntityNum; 14 | .float mass; 15 | 16 | 17 | // 18 | // ONLY FOR CLIENTS! 19 | // 20 | .float oldbuttons; 21 | .float buttons; 22 | .float latched_buttons; 23 | 24 | .vector playerAnim; // current player anim 25 | .float playerAnimTree; 26 | .float playerAnimFrame; // current animation frame 27 | .float animPriority; 28 | 29 | .float clipammo; 30 | .float reserveammo; 31 | .float weapon_animrate; 32 | 33 | .float nextFireTime; 34 | .float weaponState; 35 | .float weaponThinkFrame; 36 | 37 | 38 | // 39 | // 'worldspawn' entity 40 | // 41 | .string sky; // skybox textures to use 42 | .vector skyaxis; // vector axis for rotating sky 43 | .vector skycolor; // rgb 44 | .float skyrotate; // speed of rotation in degrees/second 45 | 46 | // 47 | // weapons 48 | // 49 | 50 | .float weapon; // current weapon index to g_weapons array 51 | //.float wpn_spreadScale; // increases with every shot 52 | 53 | // 54 | // damage and pain handling 55 | // 56 | .float deadflag; // DEAD_NO, DEAD_DYING, DEAD_YES 57 | .float takedamage; // does entity take damage? DAMAGE_NO, DAMAGE_YES, DAMAGE_AIM 58 | .float max_health; // health should be never higher than this 59 | .float armor; // number of armor points for protection 60 | 61 | 62 | .void(entity attacker, float damage, float method) pain; 63 | .void(entity attacker, float damage, float method) die; 64 | 65 | 66 | 67 | // 'target_speaker' 68 | .float volume; 69 | .float attenuation; 70 | .float noise_index; 71 | 72 | // 'trigger_hurt': deal dmg damage points 73 | .float dmg; 74 | 75 | // 'func_barrel': damage radius 76 | .float radius; 77 | 78 | // 'light' entity: index to lightstyle 79 | // 'func_areaportal': toggle between states 80 | .float style; 81 | 82 | // 'trigger_counter': when this reaches 0 fire all of its targets 83 | // 'func_spawner': spawn this number of entities 84 | .float count; 85 | 86 | // 87 | // 'light' entity 88 | // 89 | .vector color; // light color 90 | .float light; // light radius 91 | 92 | // 93 | // used by SUB_UseTargets solely 94 | // 95 | .entity activator; // entity that's going to usetargets after a delay 96 | .string target; // enities with targetname of this will be used 97 | .string targetname; // 'target' name used for targets and killtargets 98 | .string killtarget; // entities with targetname matching this killtarget will be removed 99 | 100 | 101 | // function to call when entity is being used (triggered) 102 | // self = entity being used, other = activator 103 | .void(entity a) use; 104 | 105 | 106 | // SUB_UseTargets: targets will be fired after this time 107 | // 'func_spawner': wait this time before spawning next entity 108 | .float delay; 109 | 110 | 111 | //SUB_UseTargets: play this sound to the activator when firing targets 112 | .string snd; 113 | 114 | //'trigger_counter': play this sound when counting 115 | .string snd2; 116 | 117 | 118 | // SUB_UseTargets: message to print to user/activator 119 | // 'worldspawn': name of the level 120 | // 'func_spawner': spawn entities with this classname 121 | .string message; -------------------------------------------------------------------------------- /src/engine/client/cl_cinematic.c: -------------------------------------------------------------------------------- 1 | /* 2 | pragma 3 | Copyright (C) 2023-2024 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | 8 | See the attached GNU General Public License v2 for more details. 9 | */ 10 | 11 | #include "client.h" 12 | 13 | 14 | typedef struct 15 | { 16 | int width; 17 | int height; 18 | byte *pic; 19 | } cinematics_t; 20 | 21 | cinematics_t cin; 22 | 23 | 24 | //============================================================= 25 | 26 | /* 27 | ================== 28 | SCR_StopCinematic 29 | ================== 30 | */ 31 | void SCR_StopCinematic (void) 32 | { 33 | cl.cinematictime = 0; // done 34 | } 35 | 36 | /* 37 | ==================== 38 | SCR_FinishCinematic 39 | 40 | Called when either the cinematic completes, or it is aborted 41 | ==================== 42 | */ 43 | void SCR_FinishCinematic (void) 44 | { 45 | // tell the server to advance to the next map / cinematic 46 | MSG_WriteByte (&cls.netchan.message, clc_stringcmd); 47 | SZ_Print (&cls.netchan.message, va("nextserver %i\n", cl.servercount)); 48 | } 49 | 50 | /* 51 | ================== 52 | SCR_ReadNextFrame 53 | ================== 54 | */ 55 | byte *SCR_ReadNextFrame (void) 56 | { 57 | cl.cinematicframe++; 58 | return NULL; 59 | } 60 | 61 | 62 | /* 63 | ================== 64 | SCR_RunCinematic 65 | ================== 66 | */ 67 | void SCR_RunCinematic() 68 | { 69 | unsigned int frame; 70 | cl.cinematictime = 0; //bonk. 71 | 72 | if (cl.cinematictime <= 0) 73 | { 74 | SCR_StopCinematic (); 75 | return; 76 | } 77 | 78 | if (cl.cinematicframe == -1) 79 | return; // static image 80 | 81 | if (cls.key_dest != key_game) 82 | { // pause if menu or console is up 83 | cl.cinematictime = cls.realtime - cl.cinematicframe*1000/14; 84 | return; 85 | } 86 | 87 | frame = (cls.realtime - cl.cinematictime) * 14 / 1000; 88 | if (frame <= cl.cinematicframe) 89 | return; 90 | 91 | if (frame > cl.cinematicframe+1) 92 | { 93 | Com_Printf ("Dropped frame: %i > %i\n", frame, cl.cinematicframe+1); 94 | cl.cinematictime = cls.realtime - cl.cinematicframe*1000/14; 95 | } 96 | } 97 | 98 | /* 99 | ================== 100 | SCR_DrawCinematic 101 | 102 | Returns true if a cinematic is active, meaning the view rendering should be skipped 103 | ================== 104 | */ 105 | qboolean SCR_DrawCinematic (void) 106 | { 107 | if (cl.cinematictime <= 0) 108 | { 109 | return false; 110 | } 111 | 112 | if (cls.key_dest == key_menu) 113 | { // blank screen and pause if menu is up 114 | return true; 115 | } 116 | 117 | if (!cin.pic) 118 | return true; 119 | 120 | // re.DrawStretchRaw(0, 0, viddef.width, viddef.height, cin.width, cin.height, cin.pic); 121 | return true; 122 | } 123 | 124 | /* 125 | ================== 126 | SCR_PlayCinematic 127 | ================== 128 | */ 129 | void SCR_PlayCinematic (char *arg) 130 | { 131 | char name[MAX_OSPATH], *dot; 132 | 133 | cl.cinematicframe = 0; 134 | 135 | dot = strstr (arg, "."); 136 | 137 | if (dot && !strcmp (dot, ".tga")) 138 | { 139 | Com_sprintf (name, sizeof(name), "gfx/cin/%s", arg); 140 | cl.cinematicframe = -1; 141 | cl.cinematictime = 1; 142 | SCR_EndLoadingPlaque (); 143 | cls.state = CS_ACTIVE; 144 | 145 | if (!cin.pic) 146 | { 147 | Com_Printf ("%s not found.\n", name); 148 | cl.cinematictime = 0; 149 | } 150 | return; 151 | } 152 | 153 | } 154 | -------------------------------------------------------------------------------- /src/engine/client/cgame/cg_dlights.c: -------------------------------------------------------------------------------- 1 | /* 2 | pragma 3 | Copyright (C) 2023-2024 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | 8 | See the attached GNU General Public License v2 for more details. 9 | */ 10 | 11 | #include "../client.h" 12 | 13 | #include "cg_local.h" 14 | /* 15 | ============================================================== 16 | 17 | DYNAMIC LIGHT MANAGEMENT 18 | 19 | ============================================================== 20 | */ 21 | 22 | static cdlight_t cl_dlights[MAX_DLIGHTS]; 23 | 24 | /* 25 | ================ 26 | CG_ClearDynamicLights 27 | ================ 28 | */ 29 | void CG_ClearDynamicLights(void) 30 | { 31 | memset(cl_dlights, 0, sizeof(cl_dlights)); 32 | } 33 | 34 | 35 | /* 36 | =============== 37 | CG_AllocDynamicLight 38 | =============== 39 | */ 40 | cdlight_t* CG_AllocDynamicLight(int key) 41 | { 42 | int i; 43 | cdlight_t* dl; 44 | 45 | // first look for an exact key match 46 | if (key) 47 | { 48 | dl = cl_dlights; 49 | for (i = 0; i < MAX_DLIGHTS; i++, dl++) 50 | { 51 | if (dl->key == key) 52 | { 53 | memset(dl, 0, sizeof(*dl)); 54 | dl->key = key; 55 | return dl; 56 | } 57 | } 58 | } 59 | 60 | // then look for anything else 61 | dl = cl_dlights; 62 | for (i = 0; i < MAX_DLIGHTS; i++, dl++) 63 | { 64 | if (dl->die < cl.time) 65 | { 66 | memset(dl, 0, sizeof(*dl)); 67 | dl->key = key; 68 | return dl; 69 | } 70 | } 71 | 72 | dl = &cl_dlights[0]; 73 | memset(dl, 0, sizeof(*dl)); 74 | dl->key = key; 75 | return dl; 76 | } 77 | 78 | /* 79 | =============== 80 | CL_NewDynamicPointLight 81 | =============== 82 | */ 83 | void CL_NewDynamicPointLight(int key, float x, float y, float z, float radius, float time) 84 | { 85 | cdlight_t* dl; 86 | 87 | dl = CG_AllocDynamicLight(key); 88 | dl->type = DL_POINTLIGHT; 89 | 90 | VectorSet(dl->origin, x, y, z); 91 | dl->radius = radius; 92 | dl->die = cl.time + time; 93 | } 94 | 95 | /* 96 | =============== 97 | CL_NewDynamicSpotLight 98 | 99 | dir must be normalized 100 | =============== 101 | */ 102 | void CL_NewDynamicSpotLight(int key, float x, float y, float z, vec3_t dir, float radius, float cutoff, float time) 103 | { 104 | cdlight_t* dl; 105 | 106 | dl = CG_AllocDynamicLight(key); 107 | dl->type = DL_SPOTLIGHT; 108 | 109 | VectorSet(dl->origin, x, y, z); 110 | dl->radius = radius; 111 | dl->die = cl.time + time; 112 | 113 | VectorCopy(dir, dl->dir); 114 | dl->cutoff = cutoff; 115 | } 116 | 117 | /* 118 | =============== 119 | CG_RunDynamicLights 120 | =============== 121 | */ 122 | void CG_RunDynamicLights(void) 123 | { 124 | int i; 125 | cdlight_t* dl; 126 | 127 | dl = cl_dlights; 128 | for (i = 0; i < MAX_DLIGHTS; i++, dl++) 129 | { 130 | if (!dl->radius) 131 | continue; 132 | 133 | if (dl->die < cl.time) 134 | { 135 | dl->radius = 0; 136 | return; 137 | } 138 | dl->radius -= cls.frametime * dl->decay; 139 | if (dl->radius < 0) 140 | dl->radius = 0; 141 | } 142 | } 143 | 144 | 145 | /* 146 | =============== 147 | CG_AddDynamicLights 148 | =============== 149 | */ 150 | void CG_AddDynamicLights(void) 151 | { 152 | int i; 153 | cdlight_t* dl; 154 | 155 | dl = cl_dlights; 156 | for (i = 0; i < MAX_DLIGHTS; i++, dl++) 157 | { 158 | if (!dl->radius) 159 | continue; 160 | V_AddPointLight(dl->origin, dl->radius, dl->color[0], dl->color[1], dl->color[2]); 161 | } 162 | } -------------------------------------------------------------------------------- /src/engine/client/keys.h: -------------------------------------------------------------------------------- 1 | /* 2 | pragma 3 | Copyright (C) 2023-2024 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | 8 | See the attached GNU General Public License v2 for more details. 9 | */ 10 | 11 | // 12 | // these are the key numbers that should be passed to Key_Event 13 | // 14 | #define K_TAB 9 15 | #define K_ENTER 13 16 | #define K_ESCAPE 27 17 | #define K_SPACE 32 18 | 19 | // normal keys should be passed as lowercased ascii 20 | 21 | #define K_BACKSPACE 127 22 | #define K_UPARROW 128 23 | #define K_DOWNARROW 129 24 | #define K_LEFTARROW 130 25 | #define K_RIGHTARROW 131 26 | 27 | #define K_ALT 132 28 | #define K_CTRL 133 29 | #define K_SHIFT 134 30 | #define K_F1 135 31 | #define K_F2 136 32 | #define K_F3 137 33 | #define K_F4 138 34 | #define K_F5 139 35 | #define K_F6 140 36 | #define K_F7 141 37 | #define K_F8 142 38 | #define K_F9 143 39 | #define K_F10 144 40 | #define K_F11 145 41 | #define K_F12 146 42 | #define K_INS 147 43 | #define K_DEL 148 44 | #define K_PGDN 149 45 | #define K_PGUP 150 46 | #define K_HOME 151 47 | #define K_END 152 48 | 49 | #define K_KP_HOME 160 50 | #define K_KP_UPARROW 161 51 | #define K_KP_PGUP 162 52 | #define K_KP_LEFTARROW 163 53 | #define K_KP_5 164 54 | #define K_KP_RIGHTARROW 165 55 | #define K_KP_END 166 56 | #define K_KP_DOWNARROW 167 57 | #define K_KP_PGDN 168 58 | #define K_KP_ENTER 169 59 | #define K_KP_INS 170 60 | #define K_KP_DEL 171 61 | #define K_KP_SLASH 172 62 | #define K_KP_MINUS 173 63 | #define K_KP_PLUS 174 64 | 65 | #define K_PAUSE 255 66 | 67 | // 68 | // mouse buttons generate virtual keys 69 | // 70 | #define K_MOUSE1 200 71 | #define K_MOUSE2 201 72 | #define K_MOUSE3 202 73 | 74 | // 75 | // joystick buttons 76 | // 77 | #define K_JOY1 203 78 | #define K_JOY2 204 79 | #define K_JOY3 205 80 | #define K_JOY4 206 81 | 82 | // 83 | // aux keys are for multi-buttoned joysticks to generate so they can use 84 | // the normal binding process 85 | // 86 | #define K_AUX1 207 87 | #define K_AUX2 208 88 | #define K_AUX3 209 89 | #define K_AUX4 210 90 | #define K_AUX5 211 91 | #define K_AUX6 212 92 | #define K_AUX7 213 93 | #define K_AUX8 214 94 | #define K_AUX9 215 95 | #define K_AUX10 216 96 | #define K_AUX11 217 97 | #define K_AUX12 218 98 | #define K_AUX13 219 99 | #define K_AUX14 220 100 | #define K_AUX15 221 101 | #define K_AUX16 222 102 | #define K_AUX17 223 103 | #define K_AUX18 224 104 | #define K_AUX19 225 105 | #define K_AUX20 226 106 | #define K_AUX21 227 107 | #define K_AUX22 228 108 | #define K_AUX23 229 109 | #define K_AUX24 230 110 | #define K_AUX25 231 111 | #define K_AUX26 232 112 | #define K_AUX27 233 113 | #define K_AUX28 234 114 | #define K_AUX29 235 115 | #define K_AUX30 236 116 | #define K_AUX31 237 117 | #define K_AUX32 238 118 | 119 | #define K_MWHEELDOWN 239 120 | #define K_MWHEELUP 240 121 | 122 | extern char *keybindings[256]; 123 | extern int key_repeats[256]; 124 | 125 | extern int anykeydown; 126 | extern char chat_buffer[]; 127 | extern int chat_bufferlen; 128 | extern qboolean chat_team; 129 | 130 | void Key_Event (int key, qboolean down, unsigned time); 131 | void Key_Init (void); 132 | void Key_WriteBindings (FILE *f); 133 | void Key_SetBinding (int keynum, char *binding); 134 | void Key_ClearStates (void); 135 | int Key_GetKey (void); 136 | 137 | -------------------------------------------------------------------------------- /src/renderer_dll/r_shadow.c: -------------------------------------------------------------------------------- 1 | /* 2 | pragma 3 | Copyright (C) 2023-2024 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | 8 | See the attached GNU General Public License v2 for more details. 9 | */ 10 | 11 | #include "r_local.h" 12 | 13 | vec3_t shadow_origin, shadow_angles; 14 | 15 | void R_SetupProjection(unsigned int width, unsigned int height, float fov_y, float znear, float zfar, vec3_t origin, vec3_t angles); 16 | 17 | static unsigned int shadowMapSize[2] = { 0,0 }; 18 | 19 | static GLuint r_shadow_fbo = 0; 20 | GLuint r_texture_shadow_id = 0; 21 | 22 | void R_DestroyShadowMapFBO() 23 | { 24 | if (r_shadow_fbo != 0) 25 | { 26 | glDeleteFramebuffers(1, &r_shadow_fbo); 27 | r_shadow_fbo = 0; 28 | } 29 | 30 | if (r_texture_shadow_id != 0) 31 | { 32 | glDeleteTextures(1, &r_texture_shadow_id); 33 | r_texture_shadow_id = 0; 34 | } 35 | } 36 | 37 | qboolean R_InitShadowMap(unsigned int width, unsigned int height) 38 | { 39 | if (shadowMapSize[0] != width || shadowMapSize[1] != height) 40 | { 41 | // force a rebuild when screen dimensions change 42 | R_DestroyShadowMapFBO(); 43 | } 44 | else if (r_shadow_fbo) 45 | { 46 | return true; 47 | } 48 | 49 | shadowMapSize[0] = width; 50 | shadowMapSize[1] = height; 51 | 52 | glGenFramebuffers(1, &r_shadow_fbo); 53 | 54 | glGenTextures(1, &r_texture_shadow_id); 55 | glBindTexture(GL_TEXTURE_2D, r_texture_shadow_id); 56 | glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, shadowMapSize[0], shadowMapSize[1], 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL); 57 | glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 58 | glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 59 | glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); 60 | glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); 61 | 62 | glBindFramebuffer(GL_DRAW_FRAMEBUFFER, r_shadow_fbo); 63 | glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, r_texture_shadow_id, 0); 64 | 65 | glDrawBuffer(GL_NONE); 66 | 67 | GLenum Status = glCheckFramebufferStatus(GL_FRAMEBUFFER); 68 | if (Status != GL_FRAMEBUFFER_COMPLETE) 69 | { 70 | ri.Error(ERR_FATAL, "Shadow FBO error (0x%x)\n", Status); 71 | return false; 72 | } 73 | 74 | #ifdef _DEBUG 75 | ri.Printf(PRINT_LOW, "r_texture_shadow_id = %i\n", r_texture_shadow_id); 76 | #endif 77 | 78 | return true; 79 | } 80 | 81 | void R_BeginShadowMapPass() 82 | { 83 | R_SetupProjection(shadowMapSize[0], shadowMapSize[1], 30.0f, 1.0f, 2048.0f, r_newrefdef.view.origin, r_newrefdef.view.flashlight_angles); 84 | R_UpdateCommonProgUniforms(false); 85 | 86 | R_MultiTextureBind(TMU_DIFFUSE, r_texture_white->texnum); 87 | R_MultiTextureBind(TMU_LIGHTMAP, r_texture_white->texnum); 88 | //R_MultiTextureBind(TMU_SHADOWMAP, r_texture_shadow_id); 89 | 90 | glBindFramebuffer(GL_DRAW_FRAMEBUFFER, r_shadow_fbo); 91 | glViewport(0, 0, shadowMapSize[0], shadowMapSize[1]); 92 | glClear(GL_DEPTH_BUFFER_BIT); 93 | 94 | gl_state.bShadowMapPass = true; // this also locks texture changes 95 | } 96 | 97 | void R_EndShadowMapPass() 98 | { 99 | glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); 100 | gl_state.bShadowMapPass = false; 101 | } 102 | 103 | 104 | void BindForReading() 105 | { 106 | R_MultiTextureBind(TMU_SHADOWMAP, r_texture_shadow_id); 107 | } -------------------------------------------------------------------------------- /src/common/fileformats/smdl.h: -------------------------------------------------------------------------------- 1 | /* 2 | pragma 3 | Copyright (C) 2023-2024 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | 8 | See the attached GNU General Public License v2 for more details. 9 | */ 10 | 11 | #ifndef _mod_skel_h_ 12 | #define _mod_skel_h_ 13 | 14 | 15 | // IF THIS IS CHANGED RENDERER MUST BE RECOMPILED 16 | 17 | /* 18 | ======================================================================== 19 | 20 | triangle model and skeletal animation format -- .smd 21 | 22 | structs also match optimized binary file 23 | 24 | [smdl_header] 25 | [smdl_bone * smdl_header.numbones] 26 | [smdl_seq * smdl_header.numbones * smdl_header.numframes] 27 | [smdl_group * smdl_header.numgroups] 28 | [smdl_vert * smdl_header.numverts] 29 | 30 | ======================================================================== 31 | */ 32 | 33 | #define SANIM_IDENT (('Q'<<24)+('E'<<16)+('S'<<8)+'B') // little-endian "BSEQ" 34 | #define SANIM_VERSION 1 35 | 36 | #define SANIM_FPS 10 // default 37 | 38 | #define SMDL_IDENT (('D'<<24)+('O'<<16)+('M'<<8)+'B') // little-endian "BMOD" 39 | #define SMDL_VERSION 1 40 | 41 | #define SMDL_MAX_BONES 128 // all the limits can be easily changed 42 | #define SMDL_MAX_FRAMES 512 // a single animation can have, a model will have only one 43 | 44 | #define SMDL_MAX_SURFACES 8 // also max textures if each surface has diferent 45 | #define SMDL_MAX_TRIS 32768 // for entire model 46 | #define SMDL_MAX_VERTS (SMDL_MAX_TRIS*3) 47 | 48 | typedef struct smdl_vert_s 49 | { 50 | float xyz[3]; 51 | float normal[3]; 52 | float uv[2]; 53 | int bone; // bone index -- smdl_bone_t[bone] 54 | } smdl_vert_t; 55 | 56 | typedef struct smdl_group_s 57 | { 58 | char name[32]; 59 | char texture[MAX_QPATH]; 60 | int firstvert; // smdl_vert_t[firstvert] 61 | int numverts; // smdl_vert_t[firstvert+numverts] always enough to form triangles 62 | unsigned int texnum; // *for engine use* 63 | unsigned int flags; // *for engine use* 64 | } smdl_surf_t; 65 | 66 | // animation frame == smdl_seq_t * header.numbones 67 | typedef struct smdl_seq_s 68 | { 69 | int bone; 70 | float pos[3]; 71 | float rot[3]; 72 | quat_t q; 73 | } smdl_seq_t; 74 | 75 | typedef struct smdl_bone_s 76 | { 77 | char name[MAX_QPATH]; 78 | int index; 79 | int parent; // parent bone index, -1 == root bone 80 | } smdl_bone_t; 81 | 82 | typedef struct smdl_header_s 83 | { 84 | int ident; // SMDL_IDENT 85 | int version; // SMDL_VERSION 86 | 87 | int numbones; // ??each lod must have the same?? 88 | int numframes; // a model will only have one, reference pose 89 | int numverts; 90 | int numsurfaces; 91 | 92 | int playrate; // frames per second 93 | 94 | float mins[3]; // local bounds 95 | float maxs[3]; 96 | int boundingradius; // radius from bounds 97 | } smdl_header_t; 98 | 99 | typedef enum // NOTE: DO NOT CHANGE ORDER 100 | { 101 | SMDL_BAD, 102 | SMDL_ANIMATION, 103 | SMDL_MODEL, 104 | SMDL_MODEL_NO_TRIS // because server doesn't need tris 105 | } SMDL_Type; 106 | 107 | typedef struct smdl_data_s 108 | { 109 | SMDL_Type type; 110 | 111 | smdl_header_t hdr; 112 | 113 | smdl_bone_t* bones[SMDL_MAX_BONES]; 114 | smdl_seq_t* seqences[SMDL_MAX_FRAMES]; 115 | 116 | // a model will have inverted bind pose matrix 117 | mat4_t invBindPoseMat[SMDL_MAX_BONES]; 118 | 119 | // animations don't have these 120 | smdl_surf_t* surfaces[SMDL_MAX_SURFACES]; 121 | smdl_vert_t* verts; 122 | 123 | } smdl_data_t; 124 | 125 | typedef struct smdl_anim_s 126 | { 127 | char name[MAX_QPATH]; 128 | smdl_data_t data; 129 | 130 | int extradatasize; 131 | void *extradata; 132 | } smdl_anim_t; 133 | 134 | #endif /*_mod_skel_h_*/ -------------------------------------------------------------------------------- /progs_src/svgame/clcmds.qc: -------------------------------------------------------------------------------- 1 | /* 2 | pragma engine 3 | Copyright (C) 2023 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | */ 8 | // clcmds.qc - client commands 9 | 10 | void(float cheat) ClientCmd_Cheat; 11 | 12 | entity testmodel; 13 | void() testmodel_rotate = 14 | { 15 | // self.avelocity = '0 90 0'; 16 | 17 | self.animFrame ++; 18 | if( self.animFrame > 125 ) 19 | self.animFrame = 62; 20 | self.nextthink = g_time + TIME_100_MS; 21 | self.think = testmodel_rotate; 22 | 23 | }; 24 | void() ClientCmd_TestModel = 25 | { 26 | if(!testmodel) 27 | { 28 | testmodel = spawn(); 29 | setmodel(testmodel, "models/mutant.md3"); 30 | testmodel.think = testmodel_rotate; 31 | testmodel.nextthink = g_time + TIME_100_MS; 32 | self.animFrame = 62; 33 | } 34 | setorigin(testmodel, self.origin + '0 0 0' ); 35 | 36 | testmodel.renderFlags = RF_FULLBRIGHT | RF_COLOR | RF_SCALE; //| RF_TRANSLUCENT; 37 | testmodel.renderColor = '0 1 0'; 38 | testmodel.renderScale = 3; 39 | testmodel.renderAlpha = 0.8; 40 | testmodel.angles = self.angles - '0 180 0'; 41 | testmodel.angles_x = testmodel.angles_z = 0; 42 | testmodel.origin_z = testmodel.origin_z + (24 * (testmodel.renderScale-1)); 43 | }; 44 | 45 | void(entity ent, int newweapon) SetWeapon; 46 | void() ClientCmd_SetWeapon = 47 | { 48 | float newweapon = stof(argv(1)); 49 | SetWeapon(self, newweapon); 50 | 51 | }; 52 | 53 | float() ParseClientCommand = 54 | { 55 | local string cmd; 56 | 57 | cmd = argv(0); 58 | 59 | if(g_intermissionTime) 60 | return 0; 61 | 62 | if( cmd == "respawn" ) 63 | { 64 | if( self.health <= 0 ) 65 | { 66 | SpawnPlayer(); 67 | sprint(self, PRINT_HIGH, "respawned\n"); 68 | } 69 | } 70 | 71 | if( cmd == "mdl" ) /* cheat */ 72 | { 73 | ClientCmd_TestModel(); 74 | } 75 | else if( cmd == "weapon" ) /* cheat */ 76 | { 77 | ClientCmd_SetWeapon(); 78 | } 79 | 80 | if( cmd == "god" ) /* cheat */ 81 | { 82 | ClientCmd_Cheat(0); 83 | } 84 | else if( cmd == "noclip" ) /* cheat */ 85 | { 86 | ClientCmd_Cheat(1); 87 | } 88 | else if( cmd == "notarget" ) /* cheat */ 89 | { 90 | ClientCmd_Cheat(2); 91 | } 92 | else if( cmd == "give" ) /* cheat */ 93 | { 94 | ClientCmd_Cheat(3); 95 | } 96 | else 97 | { 98 | return 0; 99 | } 100 | 101 | return 1; 102 | }; 103 | 104 | // ========================================================== 105 | // client commands 106 | // ========================================================== 107 | 108 | void(float cheat) ClientCmd_Cheat = 109 | { 110 | local string msg; 111 | 112 | if(cvar("sv_cheats") < 1) 113 | { 114 | sprint(self, PRINT_HIGH, "Cheats not enabled.\n"); 115 | return; 116 | } 117 | 118 | msg = "unknown cheat command\n"; 119 | 120 | if( cheat == 0 ) 121 | { 122 | //GOD MODE 123 | self.flags ^= FL_GODMODE; 124 | if(!(self.flags & FL_GODMODE)) 125 | msg = "godmode OFF\n"; 126 | else 127 | msg = "godmode ON\n"; 128 | } 129 | else if( cheat == 1 ) 130 | { 131 | // NOCLIP 132 | if(self.movetype == MOVETYPE_NOCLIP) 133 | { 134 | self.movetype = MOVETYPE_WALK; 135 | msg = "noclip OFF\n"; 136 | } 137 | else 138 | { 139 | self.movetype = MOVETYPE_NOCLIP; 140 | msg = "noclip ON\n"; 141 | } 142 | } 143 | else if( cheat == 2 ) 144 | { 145 | // NOTARGET 146 | self.flags ^= FL_NOTARGET; 147 | if(!(self.flags & FL_NOTARGET)) 148 | msg = "notarget OFF\n"; 149 | else 150 | msg = "notarget ON\n"; 151 | } 152 | else if( cheat == 3 ) 153 | { 154 | // GIVE 155 | //error("implement 'give' cheat\n" ); 156 | } 157 | sprint( self, PRINT_HIGH, msg ); 158 | // self.cheatsUsed = self.cheatsUsed + 1; // mark cheater :) 159 | }; 160 | -------------------------------------------------------------------------------- /progs_src/bg/bg_weapons.qc: -------------------------------------------------------------------------------- 1 | /* 2 | pragma engine 3 | Copyright (C) 2023 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | */ 8 | 9 | WeaponDef g_weapons[NUM_WEAPONS]; 10 | 11 | void() BG_InitWeapons = 12 | { 13 | float i; 14 | 15 | // 16 | // --- noweapon --- 17 | // 18 | g_weapons[WEAPON_NONE].displayName = "none"; 19 | 20 | 21 | // 22 | // AUTOMATIC RIFLE 23 | // 24 | g_weapons[WEAPON_AR].displayName = "AK-47"; 25 | 26 | g_weapons[WEAPON_AR].damage = 15; 27 | g_weapons[WEAPON_AR].dmgmethod = DMG_BULLET; 28 | 29 | g_weapons[WEAPON_AR].range = 2048; 30 | g_weapons[WEAPON_AR].spread = 38; 31 | 32 | g_weapons[WEAPON_AR].clipAmmo = 30; 33 | g_weapons[WEAPON_AR].maxAmmo = 120; 34 | 35 | g_weapons[WEAPON_AR].fireTime = 0.19; 36 | g_weapons[WEAPON_AR].reloadTime = 1.79; 37 | 38 | g_weapons[WEAPON_AR].vkick = 3; 39 | 40 | g_weapons[WEAPON_AR].viewModel = "models/v_ak47.md3"; 41 | g_weapons[WEAPON_AR].worldModel = ""; 42 | 43 | g_weapons[WEAPON_AR].muzzleflash = FX_MUZZLEFLASH_RIFLE; 44 | g_weapons[WEAPON_AR].sfx_reload = "weapons/ak47/reload.wav"; 45 | 46 | g_weapons[WEAPON_AR].anim_idle = '0 0 1'; 47 | g_weapons[WEAPON_AR].anim_fire = '2 8 2'; 48 | g_weapons[WEAPON_AR].anim_drop = '0 0 1'; 49 | g_weapons[WEAPON_AR].anim_raise = '15 67 2'; 50 | g_weapons[WEAPON_AR].anim_reload = '15 67 2'; 51 | 52 | 53 | // 54 | // PISTOL 55 | // 56 | g_weapons[WEAPON_PISTOL].displayName = "Desert Eagle"; 57 | 58 | g_weapons[WEAPON_PISTOL].damage = 25; 59 | g_weapons[WEAPON_PISTOL].dmgmethod = DMG_BULLET; 60 | 61 | g_weapons[WEAPON_PISTOL].range = 1024; 62 | g_weapons[WEAPON_PISTOL].spread = 56; 63 | 64 | g_weapons[WEAPON_PISTOL].clipAmmo = 8; 65 | g_weapons[WEAPON_PISTOL].maxAmmo = 32; 66 | 67 | g_weapons[WEAPON_PISTOL].fireTime = 0.39; 68 | g_weapons[WEAPON_PISTOL].reloadTime = 2.09; 69 | 70 | g_weapons[WEAPON_PISTOL].vkick = 2; 71 | 72 | g_weapons[WEAPON_PISTOL].viewModel = "models/v_deagle.md3"; 73 | g_weapons[WEAPON_PISTOL].worldModel = ""; 74 | 75 | g_weapons[WEAPON_PISTOL].muzzleflash = FX_MUZZLEFLASH_PISTOL; 76 | g_weapons[WEAPON_PISTOL].sfx_reload = "weapons/deagle/reload.wav"; 77 | 78 | g_weapons[WEAPON_PISTOL].anim_idle = '0 0 1'; 79 | g_weapons[WEAPON_PISTOL].anim_fire = '1 21 3'; 80 | g_weapons[WEAPON_PISTOL].anim_drop = '0 0 1'; 81 | g_weapons[WEAPON_PISTOL].anim_raise = '0 0 1'; 82 | g_weapons[WEAPON_PISTOL].anim_reload = '22 103 3'; 83 | 84 | 85 | #ifdef SVGAME 86 | // only server precaches 87 | for( i = 1; i < NUM_WEAPONS; i++ ) 88 | { 89 | print("W_InitWeapons: ", ftos(i), " ", g_weapons[i].displayName, "\n"); 90 | 91 | if(strlen(g_weapons[i].viewModel) > 1) 92 | precache_model(g_weapons[i].viewModel); 93 | 94 | if(strlen(g_weapons[i].worldModel) > 1) 95 | precache_model(g_weapons[i].worldModel); 96 | 97 | if(strlen(g_weapons[i].sfx_reload) > 1) 98 | precache_sound(g_weapons[i].sfx_reload); 99 | } 100 | print("W_InitWeapons: ", ftos(NUM_WEAPONS), " weapons total\n"); 101 | #endif 102 | }; 103 | 104 | 105 | string(float wpn) GetWeaponNameForNum = 106 | { 107 | if(wpn < 0 || wpn >= NUM_WEAPONS) 108 | return "undefined"; 109 | return g_weapons[wpn].displayName; 110 | }; 111 | 112 | float(float wpn) GetWeaponMaxClipAmmo = 113 | { 114 | if(wpn < 0 || wpn >= NUM_WEAPONS) 115 | return 0; 116 | return g_weapons[wpn].clipAmmo; 117 | }; 118 | 119 | float(float wpn) GetWeaponMaxAmmo = 120 | { 121 | if(wpn < 0 || wpn >= NUM_WEAPONS) 122 | return 0; 123 | return g_weapons[wpn].maxAmmo; 124 | }; 125 | 126 | float(float wpn) IsWeaponClipOnly = 127 | { 128 | if(wpn < 0 || wpn >= NUM_WEAPONS) 129 | return true; 130 | 131 | if(g_weapons[wpn].maxAmmo > 0) 132 | return false; 133 | 134 | return false; 135 | }; -------------------------------------------------------------------------------- /src/pragma.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.33801.447 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pragma_engine", "engine\pragma_engine.vcxproj", "{A8E87A57-9F0A-4C40-82CF-531407B7843E}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pragma_renderer", "renderer_dll\pragma_renderer.vcxproj", "{5629A810-5D8D-410C-B8A2-E4A0CDE15AF4}" 9 | EndProject 10 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pragma_tool", "tools\prtool\prtool.vcxproj", "{E2651D63-6F27-40A1-9035-A6E1AB90722F}" 11 | EndProject 12 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pragma_dedsv", "engine\pragma_dedsv.vcxproj", "{0CA27754-F257-489E-B808-16610454DE81}" 13 | EndProject 14 | Global 15 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 16 | Debug|x64 = Debug|x64 17 | Debug|x86 = Debug|x86 18 | Release|x64 = Release|x64 19 | Release|x86 = Release|x86 20 | EndGlobalSection 21 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 22 | {A8E87A57-9F0A-4C40-82CF-531407B7843E}.Debug|x64.ActiveCfg = Debug|x64 23 | {A8E87A57-9F0A-4C40-82CF-531407B7843E}.Debug|x64.Build.0 = Debug|x64 24 | {A8E87A57-9F0A-4C40-82CF-531407B7843E}.Debug|x86.ActiveCfg = Debug|Win32 25 | {A8E87A57-9F0A-4C40-82CF-531407B7843E}.Debug|x86.Build.0 = Debug|Win32 26 | {A8E87A57-9F0A-4C40-82CF-531407B7843E}.Release|x64.ActiveCfg = Release|x64 27 | {A8E87A57-9F0A-4C40-82CF-531407B7843E}.Release|x64.Build.0 = Release|x64 28 | {A8E87A57-9F0A-4C40-82CF-531407B7843E}.Release|x86.ActiveCfg = Release|Win32 29 | {A8E87A57-9F0A-4C40-82CF-531407B7843E}.Release|x86.Build.0 = Release|Win32 30 | {5629A810-5D8D-410C-B8A2-E4A0CDE15AF4}.Debug|x64.ActiveCfg = Debug|x64 31 | {5629A810-5D8D-410C-B8A2-E4A0CDE15AF4}.Debug|x64.Build.0 = Debug|x64 32 | {5629A810-5D8D-410C-B8A2-E4A0CDE15AF4}.Debug|x86.ActiveCfg = Debug|Win32 33 | {5629A810-5D8D-410C-B8A2-E4A0CDE15AF4}.Debug|x86.Build.0 = Debug|Win32 34 | {5629A810-5D8D-410C-B8A2-E4A0CDE15AF4}.Release|x64.ActiveCfg = Release|x64 35 | {5629A810-5D8D-410C-B8A2-E4A0CDE15AF4}.Release|x64.Build.0 = Release|x64 36 | {5629A810-5D8D-410C-B8A2-E4A0CDE15AF4}.Release|x86.ActiveCfg = Release|Win32 37 | {5629A810-5D8D-410C-B8A2-E4A0CDE15AF4}.Release|x86.Build.0 = Release|Win32 38 | {E2651D63-6F27-40A1-9035-A6E1AB90722F}.Debug|x64.ActiveCfg = Debug|x64 39 | {E2651D63-6F27-40A1-9035-A6E1AB90722F}.Debug|x64.Build.0 = Debug|x64 40 | {E2651D63-6F27-40A1-9035-A6E1AB90722F}.Debug|x86.ActiveCfg = Debug|Win32 41 | {E2651D63-6F27-40A1-9035-A6E1AB90722F}.Debug|x86.Build.0 = Debug|Win32 42 | {E2651D63-6F27-40A1-9035-A6E1AB90722F}.Release|x64.ActiveCfg = Release|x64 43 | {E2651D63-6F27-40A1-9035-A6E1AB90722F}.Release|x64.Build.0 = Release|x64 44 | {E2651D63-6F27-40A1-9035-A6E1AB90722F}.Release|x86.ActiveCfg = Release|Win32 45 | {E2651D63-6F27-40A1-9035-A6E1AB90722F}.Release|x86.Build.0 = Release|Win32 46 | {0CA27754-F257-489E-B808-16610454DE81}.Debug|x64.ActiveCfg = Debug|x64 47 | {0CA27754-F257-489E-B808-16610454DE81}.Debug|x64.Build.0 = Debug|x64 48 | {0CA27754-F257-489E-B808-16610454DE81}.Debug|x86.ActiveCfg = Debug|Win32 49 | {0CA27754-F257-489E-B808-16610454DE81}.Debug|x86.Build.0 = Debug|Win32 50 | {0CA27754-F257-489E-B808-16610454DE81}.Release|x64.ActiveCfg = Release|x64 51 | {0CA27754-F257-489E-B808-16610454DE81}.Release|x64.Build.0 = Release|x64 52 | {0CA27754-F257-489E-B808-16610454DE81}.Release|x86.ActiveCfg = Release|Win32 53 | {0CA27754-F257-489E-B808-16610454DE81}.Release|x86.Build.0 = Release|Win32 54 | EndGlobalSection 55 | GlobalSection(SolutionProperties) = preSolution 56 | HideSolutionNode = FALSE 57 | EndGlobalSection 58 | GlobalSection(ExtensibilityGlobals) = postSolution 59 | SolutionGuid = {7B081066-A83E-4A67-AF15-6065B90E9D4D} 60 | EndGlobalSection 61 | EndGlobal 62 | -------------------------------------------------------------------------------- /src/engine/client/cl_graph.c: -------------------------------------------------------------------------------- 1 | /* 2 | pragma 3 | Copyright (C) 2023-2024 BraXi. 4 | 5 | Quake 2 Engine 'Id Tech 2' 6 | Copyright (C) 1997-2001 Id Software, Inc. 7 | 8 | See the attached GNU General Public License v2 for more details. 9 | */ 10 | 11 | #include "client.h" 12 | 13 | /* 14 | =============================================================================== 15 | 16 | BAR GRAPHS 17 | 18 | =============================================================================== 19 | */ 20 | 21 | cvar_t* scr_netgraph; 22 | cvar_t* scr_timegraph; 23 | cvar_t* scr_debuggraph; 24 | cvar_t* scr_graphheight; 25 | cvar_t* scr_graphscale; 26 | cvar_t* scr_graphshift; 27 | 28 | typedef struct 29 | { 30 | float value; 31 | vec3_t color; 32 | } graphsamp_t; 33 | 34 | static int current; 35 | static graphsamp_t values[1024]; 36 | 37 | /* 38 | ============== 39 | CL_DebugGraph 40 | ============== 41 | */ 42 | void CL_DebugGraph(float value, vec3_t color) 43 | { 44 | values[current & 1023].value = value; 45 | VectorCopy(color, values[current & 1023].color); 46 | current++; 47 | } 48 | 49 | /* 50 | ============== 51 | CL_AddNetGraph 52 | 53 | A new packet was just parsed 54 | ============== 55 | */ 56 | void CL_AddNetGraph() 57 | { 58 | int i; 59 | int in; 60 | int ping; 61 | 62 | static vec3_t c1 = { 0.654902, 0.231373, 0.168627 }; 63 | static vec3_t c2 = { 1.000000, 0.749020, 0.058824 }; 64 | 65 | // if using the debuggraph for something else, don't 66 | // add the net lines 67 | if (scr_debuggraph->value || scr_timegraph->value) 68 | return; 69 | 70 | for (i = 0; i < cls.netchan.dropped; i++) 71 | CL_DebugGraph(30, c1); 72 | 73 | for (i = 0; i < cl.surpressCount; i++) 74 | CL_DebugGraph(30, c2); 75 | 76 | // see what the latency was on this packet 77 | in = cls.netchan.incoming_acknowledged & (CMD_BACKUP - 1); 78 | ping = cls.realtime - cl.cmd_time[in]; 79 | ping /= 30; 80 | if (ping > 30) 81 | ping = 30; 82 | 83 | static vec3_t c = { 0.000000, 1.000000, 0.000000 }; 84 | CL_DebugGraph(ping, c); 85 | } 86 | 87 | 88 | /* 89 | ============== 90 | CL_DrawDebugGraph 91 | ============== 92 | */ 93 | void CL_DrawDebugGraph() 94 | { 95 | int a, x, y, w, i, h; 96 | float v; 97 | 98 | // 99 | // draw the graph 100 | // 101 | w = scr_vrect.width; 102 | 103 | x = scr_vrect.x; 104 | y = scr_vrect.y + scr_vrect.height; 105 | 106 | re.SetColor(0.482353, 0.482353, 0.482353, 1); 107 | re.DrawFill(x, y - scr_graphheight->value, w, scr_graphheight->value); 108 | 109 | for (a = 0; a < w; a++) 110 | { 111 | i = (current - 1 - a + 1024) & 1023; 112 | v = values[i].value; 113 | 114 | v = v * scr_graphscale->value + scr_graphshift->value; 115 | 116 | if (v < 0) 117 | v += scr_graphheight->value * (1 + (int)(-v / scr_graphheight->value)); 118 | h = (int)v % (int)scr_graphheight->value; 119 | 120 | re.SetColor(values[i].color[0], values[i].color[1], values[i].color[2], 1); 121 | re.DrawFill(x + w - 1 - a, y - h, 1, h); 122 | } 123 | re.SetColor(1, 1, 1, 1); 124 | 125 | } 126 | 127 | /* 128 | ============== 129 | CL_DrawGraphOnScreen 130 | ============== 131 | */ 132 | void CL_DrawGraphOnScreen() 133 | { 134 | static vec3_t col_black = { 0,0,0 }; 135 | if (scr_timegraph->value) 136 | CL_DebugGraph(cls.frametime * 300, col_black); 137 | 138 | if (scr_debuggraph->value || scr_timegraph->value || scr_netgraph->value) 139 | CL_DrawDebugGraph(); 140 | } 141 | 142 | /* 143 | ============== 144 | CL_InitGraph 145 | ============== 146 | */ 147 | void CL_InitGraph() 148 | { 149 | scr_netgraph = Cvar_Get("netgraph", "0", 0, NULL); 150 | scr_timegraph = Cvar_Get("timegraph", "0", 0, NULL); 151 | scr_debuggraph = Cvar_Get("debuggraph", "0", 0, NULL); 152 | scr_graphheight = Cvar_Get("graphheight", "32", 0, NULL); 153 | scr_graphscale = Cvar_Get("graphscale", "1", 0, NULL); 154 | scr_graphshift = Cvar_Get("graphshift", "0", 0, NULL); 155 | } --------------------------------------------------------------------------------