From 3329a382c0e8aabe8bccb2ef4d62036fa3e807c3 Mon Sep 17 00:00:00 2001 From: Marco Cawthorne Date: Sat, 31 Aug 2024 23:31:50 -0700 Subject: [PATCH] Push more misc files --- engine.h | 248 ++++++++++++++++++++++ src/menu/Makefile | 4 + src/menu/progs.src | 10 + zpak001.pk3dir/PAK_NAME | 1 + zpak001.pk3dir/cfg/skill_manifest.cfg | 2 + zpak001.pk3dir/cvar_defaults.cfg | 161 ++++++++++++++ zpak001.pk3dir/decls/def/items.def | 44 ++++ zpak001.pk3dir/decls/def/projectiles.def | 6 + zpak001.pk3dir/decls/def/spawns.def | 26 +++ zpak001.pk3dir/default.cfg | 2 + zpak001.pk3dir/default_controls.cfg | 35 +++ zpak001.pk3dir/fonts/IBMPlexMono-Text.otf | Bin 0 -> 83916 bytes zpak001.pk3dir/fonts/IBMPlexMono-Text.txt | 92 ++++++++ zpak001.pk3dir/fonts/chat.font | 2 + zpak001.pk3dir/fonts/font16.font | 2 + zpak001.pk3dir/fonts/font20.font | 2 + zpak001.pk3dir/fonts/fontcon.font | 2 + zpak001.pk3dir/fonts/menu_header.font | 3 + zpak001.pk3dir/fonts/menu_label.font | 2 + zpak001.pk3dir/fonts/menu_label_bold.font | 2 + zpak001.pk3dir/fonts/menu_main.font | 3 + zpak001.pk3dir/fonts/ui.font | 4 + zpak001.pk3dir/glsl/vmt/lightmapped.glsl | 173 +++++++++++++++ zpak001.pk3dir/glsl/vmt/refract.glsl | 47 ++++ zpak001.pk3dir/glsl/vmt/transition.glsl | 160 ++++++++++++++ zpak001.pk3dir/glsl/vmt/unlit.glsl | 30 +++ zpak001.pk3dir/glsl/vmt/vertexlit.glsl | 140 ++++++++++++ zpak001.pk3dir/glsl/vmt/water.glsl | 183 ++++++++++++++++ 28 files changed, 1386 insertions(+) create mode 100644 engine.h create mode 100644 src/menu/Makefile create mode 100644 src/menu/progs.src create mode 100644 zpak001.pk3dir/PAK_NAME create mode 100644 zpak001.pk3dir/cfg/skill_manifest.cfg create mode 100644 zpak001.pk3dir/cvar_defaults.cfg create mode 100644 zpak001.pk3dir/decls/def/items.def create mode 100644 zpak001.pk3dir/decls/def/projectiles.def create mode 100644 zpak001.pk3dir/decls/def/spawns.def create mode 100644 zpak001.pk3dir/default_controls.cfg create mode 100644 zpak001.pk3dir/fonts/IBMPlexMono-Text.otf create mode 100644 zpak001.pk3dir/fonts/IBMPlexMono-Text.txt create mode 100644 zpak001.pk3dir/fonts/chat.font create mode 100644 zpak001.pk3dir/fonts/font16.font create mode 100644 zpak001.pk3dir/fonts/font20.font create mode 100644 zpak001.pk3dir/fonts/fontcon.font create mode 100644 zpak001.pk3dir/fonts/menu_header.font create mode 100644 zpak001.pk3dir/fonts/menu_label.font create mode 100644 zpak001.pk3dir/fonts/menu_label_bold.font create mode 100644 zpak001.pk3dir/fonts/menu_main.font create mode 100644 zpak001.pk3dir/fonts/ui.font create mode 100644 zpak001.pk3dir/glsl/vmt/lightmapped.glsl create mode 100644 zpak001.pk3dir/glsl/vmt/refract.glsl create mode 100644 zpak001.pk3dir/glsl/vmt/transition.glsl create mode 100644 zpak001.pk3dir/glsl/vmt/unlit.glsl create mode 100644 zpak001.pk3dir/glsl/vmt/vertexlit.glsl create mode 100644 zpak001.pk3dir/glsl/vmt/water.glsl diff --git a/engine.h b/engine.h new file mode 100644 index 0000000..ef2d68c --- /dev/null +++ b/engine.h @@ -0,0 +1,248 @@ +#define FULLENGINENAME "Rad-Therapy II" +#define GAME_SHORTNAME "halflife2" +#define GAME_BASEGAMES "platform","hl2" +#define GAME_PROTOCOL "FTE-RadTherapy2" +#define GAME_DEFAULTCMDS "game_hl2;fteplug_ffmpeg;fteplug_hl2;fteplug_ode;plug_load ffmpeg;plug_load hl2;plug_load ode" +#define GAME_DOWNLOADSURL "https://www.frag-net.com/pkgs/list" + +#define BRANDING_ICON "freecs.ico" +#define DISTRIBUTION "RT2" +#define DISTRIBUTIONLONG "eukara" +#define GAME_FULLNAME FULLENGINENAME +#define GAME_DEFAULTPORT 27500 +#define ENGINEWEBSITE "https://www.frag-net.com/" + +#ifndef GLQUAKE +#define GLQUAKE +#endif + +/* +#ifndef VKQUAKE +#define VKQUAKE +#endif +*/ +#undef VKQUAKE /* not yet, needs more testing */ + + /* disable quake specific hacks and overrides */ +#define QUAKETC +#define NOBUILTINMENUS +#define NOLEGACY + +/* engine behaviour */ +#define PLUGINS /* enables fteplug_ files */ +#define AVAIL_ZLIB /* we need this for pk3 and ogg vorbis */ +#define CL_MASTER /* allows for serverbrowser builtins */ +#define CSQC_DAT /* clientside qcvm */ +#define MENU_DAT /* persistent qcvm */ +#define PSET_SCRIPT /* scripts defining particles */ +#define LOADERTHREAD /* multithreading related */ +#define USEAREAGRID /* leave it on, improves performance */ +#define AVAIL_DINPUT /* input for Windows */ +#define AVAIL_FREETYPE /* for truetype font rendering */ +#define AVAIL_STBI /* avoid libpng/libjpeg dependancies */ +#define ENGINE_ROUTING /* engine-side, fast routing */ + +#ifndef LEGACY_GPU + #define RTLIGHTS +#else + #undef RTLIGHTS +#endif + +#undef D3D9QUAKE /* MICROS~1 trash */ +#undef D3D11QUAKE /* MICROS~1 trash */ +#undef D3D8QUAKE /* MICROS~1 trash */ + +/* uncompressed textures */ +#define IMAGEFMT_BMP /* sprays */ +#define IMAGEFMT_TGA + +/* compressed textures */ +#define IMAGEFMT_KTX +#define DECOMPRESS_ETC2 +#define DECOMPRESS_RGTC +#define DECOMPRESS_S3TC + +/* To be able to comm with Frag-Net.com */ +#define HAVE_PACKET +#define SUPPORT_ICE +#define HAVE_TCP +#define HAVE_GNUTLS /* linux tls/dtls support */ +#define HAVE_WINSSPI /* windows tls/dtls support */ +#define WEBCLIENT /* uri_get+any internal downloads etc */ + +#ifndef MULTITHREAD +#define MULTITHREAD +#endif + +#ifndef DEBUG +/* if 2, disables writing fteextensions.qc completely. */ +#define NOQCDESCRIPTIONS 2 +#endif + +/* various package formats */ +#define PACKAGE_PK3 +#define PACKAGE_TEXWAD +#define PACKAGE_Q1PAK + +/* level formats */ +#define Q3BSPS +#define Q1BSPS +#define TERRAIN + +/* audio */ +#define AVAIL_DSOUND +#undef AVAIL_OPENAL +#define AVAIL_OGGVORBIS +#define HAVE_OPUS +#define VOICECHAT + +/* todo: make OpenAL only */ +#define HAVE_MIXER + +/* Model formats, IQM/VVM and HLMDL for legacy maps */ +#define INTERQUAKEMODELS +#define HALFLIFEMODELS + +/* physics */ +#undef USE_INTERNAL_ODE +#undef USE_INTERNAL_BULLET +#define RAGDOLL +#define USERBE + +/* we don't need any of these */ +#undef IMAGEFMT_PCX +#undef PACKAGE_DOOMWAD +#undef DOOMWADS +#undef MAP_PROC +#undef Q2BSPS +#define RFBSPS +#define VERTEXINDEXBYTES 2 //16bit indexes work everywhere but may break some file types, 32bit indexes are optional in gles<=2 and d3d<=9 and take more memory/copying but allow for bigger batches/models. Plugins need to be compiled the same way so this is no longer set per-renderer. +#define SPRMODELS +#undef SP2MODELS +#undef DSPMODELS +#undef MD1MODELS +#undef MD2MODELS +#undef MD3MODELS +#undef MD5MODELS +#undef ZYMOTICMODELS +#undef DPMMODELS +#undef PSKMODELS +#undef MENU_NATIVECODE /* native menu replacing menuQC */ +#undef MVD_RECORDING /* server can record MVDs. */ +#undef AVAIL_WASAPI /* windows advanced sound api */ +//#undef AVAIL_DSOUND /* MICROS~1 trash */ +#undef BOTLIB_STATIC /* q3 botlib */ +#undef AVAIL_XZDEC /* .xz decompression */ +#undef HAVE_SPEEX /* .xz decompression */ +#undef AVAIL_GZDEC /* .gz decompression */ +#undef PACKAGE_DZIP /* .dzip special-case archive support */ +#undef AVAIL_PNGLIB /* .png image format support (read+screenshots) */ +#undef AVAIL_JPEGLIB /* .jpeg image format support (read+screenshots) */ +#undef AVAIL_MP3_ACM /* .mp3 support (in windows). */ +#undef IMAGEFMT_DDS +#undef IMAGEFMT_PKM +#undef IMAGEFMT_BLP +#undef NETPREPARSE /* allows for running both nq+qw on the same server (if not, protocol used must match gamecode) */ +#undef USE_SQLITE /* sql-database-as-file support */ +#undef QUAKESTATS /* defines STAT_HEALTH etc. if omitted, you'll need to provide that functionality yourself */ +#undef QUAKEHUD /* support for drawing the vanilla hud */ +#undef QWSKINS /* disabling this means no qw .pcx skins nor enemy/team skin/colour forcing */ +#undef SVRANKING /* legacy server-side ranking system */ +#define HUFFNETWORK /* crappy network compression. probably needs reseeding */ +#undef SVCHAT /* ancient lame builtin to support NPC-style chat.. */ +#undef VM_Q1 /* q1qvm implementation, to support ktx */ +#undef Q2SERVER /* q2 server+gamecode */ +#undef Q2CLIENT /* q2 client. file formats enabled separately */ +#undef Q3CLIENT /* q3 client stuff */ +#undef Q3SERVER /* q3 server stuff */ +#undef HEXEN2 /* runs hexen2 gamecode, supports hexen2 file formats */ +#undef NQPROT /* act as an nq client/server, with nq gamecode */ +#undef WEBSERVER /* sv_ftp + sv_http cvars */ +#undef RUNTIMELIGHTING /* automatic generation of .lit files */ +#undef R_XFLIP /* old silly thing */ +#undef TEXTEDITOR /* because emacs */ +#undef TCPCONNECT /* support for playing over tcp sockets, instead of just udp. compatible with qizmo */ +#undef IRCCONNECT /* lame support for routing game packets via irc server. not a good idea */ +#undef PSET_CLASSIC /* support the 'classic' particle system, for that classic quake feel */ +#undef HAVE_CDPLAYER /* Redbook CD Audio */ +#undef QTERM +#undef SIDEVIEWS +#undef MAX_SPLITS +#undef SUBSERVERS /* multi-map */ +#undef VM_LUA /* lua game-logic */ +#undef HLCLIENT /* regressed, unfinished*/ +#undef HLSERVER /* regressed, unfinished */ +#undef FTPSERVER +#undef HAVE_JUKEBO /* includes built-in jukebox */ +#define HAVE_MEDIA_DECODER /* can play cin/roq, more with plugins */ +#undef HAVE_MEDIA_ENCODER /* capture/capturedemo work */ +#undef HAVE_SPEECHTOTEXT /* Windows speech-to-text thing */ +#undef SAVEDGAMES +#undef PACKAGEMANAGER /* enable/disable/download packages and plugins */ +#undef HEADLESSQUAKE +#undef WAYLANDQUAKE +#undef SERVER_DEMO_PLAYBACK /* deprecated */ +#undef DECOMPRESS_BPTC +#undef IMAGEFMT_HDR +#undef IMAGEFMT_PBM +#undef IMAGEFMT_PSD +#undef IMAGEFMT_XCF +#undef IMAGEFMT_LMP +#undef IMAGEFMT_PNG +#undef IMAGEFMT_JPG +#undef IMAGEFMT_GIF +#undef IMAGEFMT_EXR +#undef IPLOG +#undef AVAIL_BOTLIB +#undef AVAIL_BZLIB +#undef DECOMPRESS_ASTC +#undef IMAGEFMT_ASTC +#undef HAVE_HTTPSV +#undef MODELFMT_MDX +#undef MODELFMT_OBJ +#undef MODELFMT_GLTF + +#ifdef COMPILE_OPTS +/* things to configure qclib, which annoyingly doesn't include this + * file itself */ +-DOMIT_QCC /* disable the built-in qcc */ +-DSIMPLE_QCVM /* disable qc debugging and 32bit opcodes */ +#ifndef AVAIL_ZLIB +-DNO_ZLIB /* disable zlib */ +#endif +#ifdef AVAIL_PNGLIB +-DLINK_PNG +#endif +#ifdef AVAIL_JPEGLIB +-DLINK_JPEG +#endif +#ifdef AVAIL_FREETYPE +-DLINK_FREETYPE +#endif + +/* makefile will respond to this by trying to link bullet into the + * engine itself, instead of as a plugin. */ +#ifdef USE_INTERNAL_BULLET +-DLINK_INTERNAL_BULLET +#endif + +#ifdef USE_INTERNAL_ODE +-DODE_STATIC +#endif + +/* disable static speex */ +#ifdef HAVE_SPEEX +-DNO_SPEEX +#endif + +/* disable static botlib */ +#ifndef BOTLIB_STATIC +-DNO_BOTLIB +#endif + +-DLIBVORBISFILE_STATIC + +/* optimise for size instead of speed. less cpu cache needed means that + * its sometimes faster.*/ +-Os +#endif diff --git a/src/menu/Makefile b/src/menu/Makefile new file mode 100644 index 0000000..2fe44a4 --- /dev/null +++ b/src/menu/Makefile @@ -0,0 +1,4 @@ +QCC=fteqcc + +all: + $(QCC) progs.src diff --git a/src/menu/progs.src b/src/menu/progs.src new file mode 100644 index 0000000..953b5b8 --- /dev/null +++ b/src/menu/progs.src @@ -0,0 +1,10 @@ +#pragma target fte_5768 +//#pragma flag enable assumeint +#pragma progs_dat "../../menu.dat" +#define MENU +#define GAME_DIR "base" + +#includelist +../../../src/menu-vgui/includes.src +#endlist + diff --git a/zpak001.pk3dir/PAK_NAME b/zpak001.pk3dir/PAK_NAME new file mode 100644 index 0000000..8ed6502 --- /dev/null +++ b/zpak001.pk3dir/PAK_NAME @@ -0,0 +1 @@ +package_hl2.pk3 diff --git a/zpak001.pk3dir/cfg/skill_manifest.cfg b/zpak001.pk3dir/cfg/skill_manifest.cfg new file mode 100644 index 0000000..5187a53 --- /dev/null +++ b/zpak001.pk3dir/cfg/skill_manifest.cfg @@ -0,0 +1,2 @@ +exec "skill.cfg" +exec "skill_hl2.cfg" diff --git a/zpak001.pk3dir/cvar_defaults.cfg b/zpak001.pk3dir/cvar_defaults.cfg new file mode 100644 index 0000000..3ae3823 --- /dev/null +++ b/zpak001.pk3dir/cvar_defaults.cfg @@ -0,0 +1,161 @@ +set ai_debugAlerts "0" // Show prints when AI gets alerted to a position. +set ai_debugLogic "0" // Show prints when AI makes decisions regarding thinking. +set ai_debugNav "0" // Show prints when AI makes decisions regarding navigation. +set ai_debugScripts "0" // Show prints when AI interacts with scripted sequences. +set ai_runSpeed "320" // Default run speed chosen by AI characters, in units per second. +set ai_walkSpeed "150" // Default walk speed chosen by AI characters, in units per second. +set ai_enable "1" // Disable AI behaviour when set. + +set bot_aimless "0" // Bots will not set goals for themselves when set. +set bot_backspeed "133" // Bots desired maximum backwards speed. +set bot_crouch "0" // Bots are all forced to move crouched. +set bot_developer "0" // TODO: remove? +set bot_dont_shoot "0" // Bots never actually shoot. +set bot_enable "1" // Bot support enabled when set. +set bot_fastChat "0" // Bots will chat instantly instead of 'typing'. +set bot_forwardspeed "190" // Bots desired maximum forward speed. +set bot_minClients "-1" // How many player slots are to be filled, -1 is 'untouched'. +set bot_noChat "0" // Bots will no longer communicate when set. +set bot_pause "0" // Bots logic will be paused. +set bot_prefix "" // Bot nickname prefix for newly added bots. +set bot_prone "0" // Bots are all forced to move prone. +set bot_sidespeed "152" // Bots desired maximum strafe speed. +set bot_skill "2" // Bot version of cvar "skill". +set bot_walk "0" // Bots are forced to walk slowly. + +set cg_chatEnabled "1" // Enable the display of chat messages. +set cg_damageShake "0" // Shake the display upon taking damage. +set cg_hudAspect "0" // Aspect ratio override for the HUD. 1.0 is 1:1 square, 0 is auto. +set cg_muzzleDLight "1" // Enable dlights being spawned from muzzleflashes. +set cg_muzzleDLightColor "1.0 0.45 0.0" // Color of muzzleflash dlights. +set cg_viewZSmoothingMax "16" // Camera vertical-axis smoothing max delta threshold. +set cg_viewZSmoothingMin "1" // Camera vertical-axis smoothing delta threshold. +set cg_viewZSmoothingTime "0.1" // Camera vertical-axis smoothing steps. +set cg_viewmodelFlip "0" // Flip the viewmodel. +set cg_viewmodelFov "90" // Viewmodel field of view. +set cg_viewmodelLag "0" // Viewmodel lag when camera looks around. +set cg_viewmodelOffset "0 0 0" // Viewmodel offset in relative units (forward, right, up) +set cg_viewmodelPass "1" // Renders viewmodel in separate drawpass (no lighting) +set cg_viewmodelScale "1.0" // Viewmodel scale multiplier, affects bob as well. + +set cl_backspeed "400" // Client's desired backwards speed. +set cl_decals "128" +set cl_forwardspeed "400" // Client's desired forward speed. +set cl_musicstyle "0" +set cl_sidespeed "400" // Client's desired side-step speed. + +set con_color "255 150 0" // HUD color value, R G B, 0-255 for each channel. + +set dev_cornerspeed "0" // Override speed set by path_corner entities. +set dev_loddistance "0" // Override distance at which func_lod entities disappear. +set dev_skyscale "" // Override for the sky_camera room scale. + +set dsp_soundscapes "1" // Enable the use of sound scapes. + +set g_damageScale "1" // final damage scale on objects +set g_logLevel "2" // Game console log levels. 0 = None, 1 = Errors, 2 = Warnings, 3 = Extra Messages +set g_logTimestamps "0" // When 1, will print time stamps before the log message +set g_gravity "800" // Global gravity setting. + +set in_zoomSensitivity "1.0" // Input sensitivity multiplier for when you're zoomed in. + +set logging_enabled "0" // Enable server-side logging for game specific events. + +set menu_helptext_size "11" +set menu_intro "1" +set menu_steambg "0" +set menu_updating "0" + +set motdfile "motd.txt" + +set mp_allowvote "1" +set mp_decals "128" +set mp_flashlight "1" +set mp_td_dmgToKick "300" +set mp_td_dmgToWarn "200" + +set nav_linksize "256" +set nav_radius "32" + +set phys_developer "0" // Shows debug prints regarding physics operations when set. +set phys_impactforcescale "100" +set phys_pushscale "1" + +set pm_accelerate "10" +set pm_airaccelerate "10" +set pm_airstepsize "0" +set pm_boxcenter "1" +set pm_boxwidth "32" +set pm_crouchheight "36" +set pm_crouchspeed "90" +set pm_crouchviewheight "30" +set pm_edgefriction "1" +set pm_friction "4" +set pm_gravity "800" +set pm_jumpheight "265" +set pm_maxviewpitch "89" +set pm_minviewpitch "-89" +set pm_noclipaccelerate "5" +set pm_noclipspeed "500" +set pm_normalheight "72" +set pm_normalviewheight "64" +set pm_nospeedcap "0" +set pm_proneheight "0" +set pm_pronespeed "40.5" +set pm_proneviewheight "16" +set pm_runspeed "0" +set pm_stairSmoothing "1" +set pm_stamina "24" +set pm_staminarate "0.75" +set pm_staminathreshold "4" +set pm_stepsize "18" +set pm_stopspeed "100" +set pm_thirdPerson "0" +set pm_walkspeed "270" +set pm_wateraccelerate "10" +set pm_waterjumpheight "350" + +set r_autoscale "1" // When set, will ensure the game is at 640x480 type scaling. +set r_drawdecals "1" // Shows decal entities managed by the game when set. +set r_pixelscale "0" // When set, will ensure the 3D rendered scene is restricted to 640x480 resolution in definition. +set r_renderEntityInfo "0" // Display visual information about entities in-world. +set r_showDlights "0" // Displays dynamic light representations in-world. +set r_showPhysicsInfo "0" // Displays physics entity information in-world. +set r_skipGlows "0" // Skip rendering of glowing sprites. +set r_skipLensFlares "0" // Skip rendering of lens flares. +set r_skipWorld "0" // Skip rendering of the world. + +set rm_unlit_additive "1" // Render entities with the 'additive' rendermode fullbright. +set rm_unlit_texture "1" // Render entities with the 'texture' rendermode fullbright. + +set rope_debug "0" // Shows primitive debug rendering of a rope when set. +set rope_fast "1" // Don't perform expensive calculations on the rope when set. +set rope_maxsegments "-1" // Limit rope segments. -1 means no limit. +set rope_sag "2" // Rope sagging multiplier. +set rope_swing "2" // Rope swinging multiplier. + +set s_logLevel "2" // Sound console log levels. 0 = None, 1 = Errors, 2 = Warnings, 3 = Extra Messages + +set sp_decals "128" + +set sv_friendlyFire "0" // Team-inflicted damage is possible when set. +set sv_levelexec "1" // Will search and execute `/maps/currentmap.cfg` when set. +set sv_plugins "1" // Enable the use of server-side plugins when set. + +set vehicle_developer "0" // Shows vehicle related debug prints when set. + +set vgui_color "255 170 0" // Default primary color for VGUI widgets. + +set vid_brightness "0" // Controls display brightness. +set vid_gamma "1" // Controls gamma level. +set vid_desktopgamma "0" +set vid_hardwaregamma "2" + +set violence_ablood "1" // Enable non-human (alternative) blood. +set violence_agibs "1" // Enable non-human (alternative) gibs. +set violence_hblood "1" // Enable human blood. +set violence_hgibs "1" // Enable human giblets. + +set xr_roomScale "1.0" // XR: Room scale multiplier. +set xr_testInputs "0" // XR: Enable fake inputs, to debug the VR camera and weapon inputs. +set xr_viewHeight "-48" // XR: Default view-height offset. diff --git a/zpak001.pk3dir/decls/def/items.def b/zpak001.pk3dir/decls/def/items.def new file mode 100644 index 0000000..cd105d6 --- /dev/null +++ b/zpak001.pk3dir/decls/def/items.def @@ -0,0 +1,44 @@ +entityDef item_battery +{ + "spawnclass" "NSItem" + "model" "models/items/battery.mdl" + "mins" "-16 -16 0" + "maxs" "16 16 16" + "snd_acquire" "item.battery" + "snd_respawn" "item.respawn" + "inv_armor" "skill:battery" + "requires" "item_suit" +} + +entityDef item_healthvial +{ + "spawnclass" "NSItem" + "model" "models/healthvial.mdl" + "mins" "-16 -16 0" + "maxs" "16 16 16" + "snd_acquire" "item.healthkit" + "snd_respawn" "item.respawn" + "inv_health" "skill:healthvial" +} + +entityDef item_healthkit +{ + "spawnclass" "NSItem" + "model" "models/items/healthkit.mdl" + "mins" "-16 -16 0" + "maxs" "16 16 16" + "snd_acquire" "item.healthkit" + "snd_respawn" "item.respawn" + "inv_health" "skill:healthkit" +} + +entityDef item_suit +{ + "spawnclass" "NSItem" + "model" "models/items/hevsuit.mdl" + "mins" "-16 -16 0" + "maxs" "16 16 16" + "snd_acquire" "item.suit" + "snd_respawn" "item.respawn" + "inv_carry" "1" +} diff --git a/zpak001.pk3dir/decls/def/projectiles.def b/zpak001.pk3dir/decls/def/projectiles.def new file mode 100644 index 0000000..6439fac --- /dev/null +++ b/zpak001.pk3dir/decls/def/projectiles.def @@ -0,0 +1,6 @@ +entityDef projectile_bullet_base +{ + "spawnclass" "NSProjectile" + "is_bullet" "1" + "detonate_on_world" "1" +} diff --git a/zpak001.pk3dir/decls/def/spawns.def b/zpak001.pk3dir/decls/def/spawns.def new file mode 100644 index 0000000..e0145cb --- /dev/null +++ b/zpak001.pk3dir/decls/def/spawns.def @@ -0,0 +1,26 @@ +entityDef info_player_start +{ + "spawnclass" "NSSpawnPoint" + "editor_mins" "-16 -16 -36" + "editor_maxs" "16 16 36" + "editor_description" "Singleplayer Spawn Point" + "editor_color" "1 0 0" +} + +entityDef info_player_deathmatch +{ + "spawnclass" "NSSpawnPoint" + "editor_mins" "-16 -16 -36" + "editor_maxs" "16 16 36" + "editor_description" "Deathmatch Spawn Point" + "editor_color" "1 0 0" +} + +entityDef info_player_coop +{ + "spawnclass" "NSSpawnPoint" + "editor_mins" "-16 -16 -36" + "editor_maxs" "16 16 36" + "editor_description" "Cooperative Spawn Point" + "editor_color" "1 0 0" +} diff --git a/zpak001.pk3dir/default.cfg b/zpak001.pk3dir/default.cfg index b210ac5..a0b75fc 100644 --- a/zpak001.pk3dir/default.cfg +++ b/zpak001.pk3dir/default.cfg @@ -10,3 +10,5 @@ seta "cross_color" "0 255 0" seta pm_walkspeed 190 seta pm_runspeed 320 + +seta r_imageextensions "vtf tga" diff --git a/zpak001.pk3dir/default_controls.cfg b/zpak001.pk3dir/default_controls.cfg new file mode 100644 index 0000000..ec189a2 --- /dev/null +++ b/zpak001.pk3dir/default_controls.cfg @@ -0,0 +1,35 @@ +bind "ESC" "togglemenu" +bind "w" "+forward" +bind "s" "+back" +bind "a" "+moveleft" +bind "d" "+moveright" +bind "SPACE" "+jump" +bind "CTRL" "+duck" +bind "SHIFT" "+speed" +bind "0" "slot10" +bind "1" "slot1" +bind "2" "slot2" +bind "3" "slot3" +bind "4" "slot4" +bind "5" "slot5" +bind "6" "slot6" +bind "7" "slot7" +bind "8" "slot8" +bind "9" "slot9" +bind "UPARROW" "+forward" +bind "DOWNARROW" "+back" +bind "LEFTARROW" "+left" +bind "RIGHTARROW" "+right" +bind "MOUSE1" "+attack" +bind "MOUSE2" "+attack2" +bind "MWHEELDOWN" "invnext" +bind "MWHEELUP" "invprev" +bind "r" "+reload" +bind "e" "+use" +bind "TAB" "+showscores" +bind "y" "messagemode" +bind "u" "messagemode2" +bind "t" "impulse 201" +bind "f" "impulse 100" +bind "f1" "vote yes" +bind "f2" "vote no" diff --git a/zpak001.pk3dir/fonts/IBMPlexMono-Text.otf b/zpak001.pk3dir/fonts/IBMPlexMono-Text.otf new file mode 100644 index 0000000000000000000000000000000000000000..30964569c30b54cd42bedeb2406e38b1933d9514 GIT binary patch literal 83916 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 literal 0 HcmV?d00001 diff --git a/zpak001.pk3dir/fonts/IBMPlexMono-Text.txt b/zpak001.pk3dir/fonts/IBMPlexMono-Text.txt new file mode 100644 index 0000000..f72f765 --- /dev/null +++ b/zpak001.pk3dir/fonts/IBMPlexMono-Text.txt @@ -0,0 +1,92 @@ +Copyright © 2017 IBM Corp. with Reserved Font Name "Plex" + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. \ No newline at end of file diff --git a/zpak001.pk3dir/fonts/chat.font b/zpak001.pk3dir/fonts/chat.font new file mode 100644 index 0000000..d7956f1 --- /dev/null +++ b/zpak001.pk3dir/fonts/chat.font @@ -0,0 +1,2 @@ +path fonts/IBMPlexMono-Text.otf +size 12 \ No newline at end of file diff --git a/zpak001.pk3dir/fonts/font16.font b/zpak001.pk3dir/fonts/font16.font new file mode 100644 index 0000000..34f2c50 --- /dev/null +++ b/zpak001.pk3dir/fonts/font16.font @@ -0,0 +1,2 @@ +path fonts/IBMPlexMono-Text.otf +size 16 \ No newline at end of file diff --git a/zpak001.pk3dir/fonts/font20.font b/zpak001.pk3dir/fonts/font20.font new file mode 100644 index 0000000..d8f9d39 --- /dev/null +++ b/zpak001.pk3dir/fonts/font20.font @@ -0,0 +1,2 @@ +path fonts/IBMPlexMono-Text.otf +size 20 \ No newline at end of file diff --git a/zpak001.pk3dir/fonts/fontcon.font b/zpak001.pk3dir/fonts/fontcon.font new file mode 100644 index 0000000..d7956f1 --- /dev/null +++ b/zpak001.pk3dir/fonts/fontcon.font @@ -0,0 +1,2 @@ +path fonts/IBMPlexMono-Text.otf +size 12 \ No newline at end of file diff --git a/zpak001.pk3dir/fonts/menu_header.font b/zpak001.pk3dir/fonts/menu_header.font new file mode 100644 index 0000000..3992e2a --- /dev/null +++ b/zpak001.pk3dir/fonts/menu_header.font @@ -0,0 +1,3 @@ +rendersize "21 16" +path fonts/IBMPlexMono-Text.otf +size 16 \ No newline at end of file diff --git a/zpak001.pk3dir/fonts/menu_label.font b/zpak001.pk3dir/fonts/menu_label.font new file mode 100644 index 0000000..aaebdd3 --- /dev/null +++ b/zpak001.pk3dir/fonts/menu_label.font @@ -0,0 +1,2 @@ +rendersize "10 11 12 14" +path fonts/IBMPlexMono-Text.otf \ No newline at end of file diff --git a/zpak001.pk3dir/fonts/menu_label_bold.font b/zpak001.pk3dir/fonts/menu_label_bold.font new file mode 100644 index 0000000..c8ddd86 --- /dev/null +++ b/zpak001.pk3dir/fonts/menu_label_bold.font @@ -0,0 +1,2 @@ +rendersize "14 12" +path fonts/IBMPlexMono-Text.otf \ No newline at end of file diff --git a/zpak001.pk3dir/fonts/menu_main.font b/zpak001.pk3dir/fonts/menu_main.font new file mode 100644 index 0000000..f54db34 --- /dev/null +++ b/zpak001.pk3dir/fonts/menu_main.font @@ -0,0 +1,3 @@ +rendersize "14 11 12" +path fonts/IBMPlexMono-Text.otf +size 12 \ No newline at end of file diff --git a/zpak001.pk3dir/fonts/ui.font b/zpak001.pk3dir/fonts/ui.font new file mode 100644 index 0000000..8422ed0 --- /dev/null +++ b/zpak001.pk3dir/fonts/ui.font @@ -0,0 +1,4 @@ +color "255 255 255" +alpha 255 +size 12 +path fonts/IBMPlexMono-Text.otf diff --git a/zpak001.pk3dir/glsl/vmt/lightmapped.glsl b/zpak001.pk3dir/glsl/vmt/lightmapped.glsl new file mode 100644 index 0000000..3b37c41 --- /dev/null +++ b/zpak001.pk3dir/glsl/vmt/lightmapped.glsl @@ -0,0 +1,173 @@ +!!ver 110 +!!permu FOG +!!permu BUMP +!!permu LIGHTSTYLED +!!permu REFLECTCUBEMASK +!!samps diffuse + +!!samps lightmap +!!samps =LIGHTSTYLED lightmap1 lightmap2 lightmap3 + +!!samps =BUMP normalmap + +// envmaps only +!!samps =REFLECTCUBEMASK reflectmask reflectcube + +!!permu FAKESHADOWS +!!cvardf r_glsl_pcf +!!samps =FAKESHADOWS shadowmap + +#include "sys/defs.h" + +varying vec2 tex_c; + +varying vec2 lm0; + +#ifdef LIGHTSTYLED +varying vec2 lm1, lm2, lm3; +#endif + +#ifdef FAKESHADOWS + varying vec4 vtexprojcoord; +#endif + +/* CUBEMAPS ONLY */ +#ifdef REFLECTCUBEMASK + varying vec3 eyevector; + varying mat3 invsurface; +#endif + +#ifdef VERTEX_SHADER + void lightmapped_init(void) + { + lm0 = v_lmcoord; + #ifdef LIGHTSTYLED + lm1 = v_lmcoord2; + lm2 = v_lmcoord3; + lm3 = v_lmcoord4; + #endif + } + + void main () + { + lightmapped_init(); + tex_c = v_texcoord; + gl_Position = ftetransform(); + + /* CUBEMAPS ONLY */ + #ifdef REFLECTCUBEMASK + invsurface = mat3(v_svector, v_tvector, v_normal); + + vec3 eyeminusvertex = e_eyepos - v_position.xyz; + eyevector.x = dot(eyeminusvertex, v_svector.xyz); + eyevector.y = dot(eyeminusvertex, v_tvector.xyz); + eyevector.z = dot(eyeminusvertex, v_normal.xyz); + #endif + + #ifdef FAKESHADOWS + vtexprojcoord = (l_cubematrix*vec4(v_position.xyz, 1.0)); + #endif + } +#endif + +#ifdef FRAGMENT_SHADER + #include "sys/fog.h" + +#ifdef FAKESHADOWS + #include "sys/pcf.h" +#endif + + #ifdef LIGHTSTYLED + #define LIGHTMAP0 texture2D(s_lightmap0, lm0).rgb + #define LIGHTMAP1 texture2D(s_lightmap1, lm1).rgb + #define LIGHTMAP2 texture2D(s_lightmap2, lm2).rgb + #define LIGHTMAP3 texture2D(s_lightmap3, lm3).rgb + #else + #define LIGHTMAP texture2D(s_lightmap, lm0).rgb + #endif + + vec3 lightmap_fragment() + { + vec3 lightmaps; + +#ifdef LIGHTSTYLED + lightmaps = LIGHTMAP0 * e_lmscale[0].rgb; + lightmaps += LIGHTMAP1 * e_lmscale[1].rgb; + lightmaps += LIGHTMAP2 * e_lmscale[2].rgb; + lightmaps += LIGHTMAP3 * e_lmscale[3].rgb; +#else + lightmaps = LIGHTMAP * e_lmscale.rgb; +#endif + + /* the light we're getting is always too bright */ + lightmaps *= 0.75; + + /* clamp at 1.5 */ + if (lightmaps.r > 1.5) + lightmaps.r = 1.5; + if (lightmaps.g > 1.5) + lightmaps.g = 1.5; + if (lightmaps.b > 1.5) + lightmaps.b = 1.5; + + return lightmaps; + } + + void main (void) + { + vec4 diffuse_f; + vec3 light = vec3(0.0, 0.0, 0.0); + + diffuse_f = texture2D(s_diffuse, tex_c); + +#ifdef MASKLT + if (diffuse_f.a < float(MASK)) + discard; +#endif + +#ifdef FAKESHADOWS + diffuse_f.rgb *= ShadowmapFilter(s_shadowmap, vtexprojcoord); +#endif + + /* deluxemapping isn't working on Source BSP yet */ + diffuse_f.rgb *= lightmap_fragment(); + +/* CUBEMAPS ONLY */ +#ifdef REFLECTCUBEMASK + /* We currently only use the normal/bumpmap for cubemap warping. move this block out once we do proper radiosity normalmapping */ + #ifdef BUMP + /* Source's normalmaps are in the DX format where the green channel is flipped */ + vec4 normal_f = texture2D(s_normalmap, tex_c); + normal_f.g *= -1.0; + normal_f.rgb = normalize(normal_f.rgb - 0.5); + #else + vec4 normal_f = vec4(0.0,0.0,1.0,0.0); + #endif + + #if defined(ENVFROMMASK) + /* We have a dedicated reflectmask */ + #define refl texture2D(s_reflectmask, tex_c).r + #else + /* when ENVFROMBASE is set or a normal isn't present, we're getting the reflectivity info from the diffusemap's alpha channel */ + #if defined(ENVFROMBASE) || !defined(BUMP) + #define refl 1.0 - diffuse_f.a + #else + #define refl normal_f.a * 0.5 + #endif + #endif + + vec3 cube_c = reflect(normalize(-eyevector), normal_f.rgb); + cube_c = cube_c.x * invsurface[0] + cube_c.y * invsurface[1] + cube_c.z * invsurface[2]; + cube_c = (m_model * vec4(cube_c.xyz, 0.0)).xyz; + diffuse_f.rgb += (textureCube(s_reflectcube, cube_c).rgb * vec3(refl,refl,refl)); +#endif + + light += (e_light_mul * lambert(norm, e_light_dir)) * 2.0; + light += (e_light_ambient * lambert(norm, reflect(norm, e_light_dir))) * 0.5; + light += (e_light_mul * dot(normal_f, e_light_dir)); + + diffuse_f.rgb *= light; + + gl_FragColor = fog4(diffuse_f); + } +#endif diff --git a/zpak001.pk3dir/glsl/vmt/refract.glsl b/zpak001.pk3dir/glsl/vmt/refract.glsl new file mode 100644 index 0000000..fa56149 --- /dev/null +++ b/zpak001.pk3dir/glsl/vmt/refract.glsl @@ -0,0 +1,47 @@ +!!ver 110 +!!samps diffuse +!!samps =BUMP normalmap +!!samps =REFLECTCUBEMASK reflectmask reflectcube +!!samps refraction=0 + +#include "sys/defs.h" + +varying vec2 tex_c; +varying mat3 invsurface; +varying vec4 tf_c; +varying vec3 eyeminusvertex; + +#ifdef VERTEX_SHADER + void main () + { + invsurface[0] = v_svector; + invsurface[1] = v_tvector; + invsurface[2] = v_normal; + tf_c = ftetransform(); + tex_c = v_texcoord; + gl_Position = tf_c; + } +#endif + +#ifdef FRAGMENT_SHADER + #include "sys/fog.h" + void main ( void ) + { + vec2 refl_c; + vec3 refr_f; + vec3 norm_f; + vec4 out_f = vec4( 1.0, 1.0, 1.0, 1.0 ); + + norm_f = ( texture2D( s_normalmap, tex_c).xyz); + norm_f.g *= -1.0; + norm_f = normalize( norm_f ); + + // Reflection/View coordinates + refl_c = ( 1.0 + ( tf_c.xy / tf_c.w ) ) * 0.5; + + refr_f = texture2D(s_refraction, refl_c + (norm_f.st) ).rgb; + out_f.rgb = refr_f * texture2D(s_diffuse, tex_c).rgb; + + gl_FragColor = out_f; + } +#endif diff --git a/zpak001.pk3dir/glsl/vmt/transition.glsl b/zpak001.pk3dir/glsl/vmt/transition.glsl new file mode 100644 index 0000000..100280f --- /dev/null +++ b/zpak001.pk3dir/glsl/vmt/transition.glsl @@ -0,0 +1,160 @@ +!!ver 110 +!!permu FOG +!!permu BUMP +!!permu LIGHTSTYLED +!!permu REFLECTCUBEMASK +!!permu UPPERLOWER +!!samps diffuse upper + +!!samps lightmap +!!samps =LIGHTSTYLED lightmap1 lightmap2 lightmap3 + +!!samps =BUMP normalmap + +// envmaps only +!!samps =REFLECTCUBEMASK reflectmask reflectcube + +!!permu FAKESHADOWS +!!cvardf r_glsl_pcf +!!samps =FAKESHADOWS shadowmap + +#include "sys/defs.h" + +varying vec2 tex_c; +varying vec4 vex_color; + +varying vec2 lm0; + +#ifdef LIGHTSTYLED +varying vec2 lm1, lm2, lm3; +#endif + +#ifdef FAKESHADOWS + varying vec4 vtexprojcoord; +#endif + +/* CUBEMAPS ONLY */ +#ifdef REFLECTCUBEMASK + varying vec3 eyevector; + varying mat3 invsurface; +#endif + +#ifdef VERTEX_SHADER + void lightmapped_init(void) + { + lm0 = v_lmcoord; + #ifdef LIGHTSTYLED + lm1 = v_lmcoord2; + lm2 = v_lmcoord3; + lm3 = v_lmcoord4; + #endif + } + + void main () + { + lightmapped_init(); + tex_c = v_texcoord; + gl_Position = ftetransform(); + vex_color = v_colour; + + /* CUBEMAPS ONLY */ + #ifdef REFLECTCUBEMASK + invsurface = mat3(v_svector, v_tvector, v_normal); + + vec3 eyeminusvertex = e_eyepos - v_position.xyz; + eyevector.x = dot(eyeminusvertex, v_svector.xyz); + eyevector.y = dot(eyeminusvertex, v_tvector.xyz); + eyevector.z = dot(eyeminusvertex, v_normal.xyz); + #endif + + #ifdef FAKESHADOWS + vtexprojcoord = (l_cubematrix*vec4(v_position.xyz, 1.0)); + #endif + } +#endif + +#ifdef FRAGMENT_SHADER + #include "sys/fog.h" + +#ifdef FAKESHADOWS + #include "sys/pcf.h" +#endif + + #ifdef LIGHTSTYLED + #define LIGHTMAP0 texture2D(s_lightmap0, lm0).rgb + #define LIGHTMAP1 texture2D(s_lightmap1, lm1).rgb + #define LIGHTMAP2 texture2D(s_lightmap2, lm2).rgb + #define LIGHTMAP3 texture2D(s_lightmap3, lm3).rgb + #else + #define LIGHTMAP texture2D(s_lightmap, lm0).rgb + #endif + + vec3 lightmap_fragment() + { + vec3 lightmaps; + +#ifdef LIGHTSTYLED + lightmaps = LIGHTMAP0 * e_lmscale[0].rgb; + lightmaps += LIGHTMAP1 * e_lmscale[1].rgb; + lightmaps += LIGHTMAP2 * e_lmscale[2].rgb; + lightmaps += LIGHTMAP3 * e_lmscale[3].rgb; +#else + lightmaps = LIGHTMAP * e_lmscale.rgb; +#endif + + /* the light we're getting is always too bright */ + lightmaps *= 0.75; + + /* clamp at 1.5 */ + if (lightmaps.r > 1.5) + lightmaps.r = 1.5; + if (lightmaps.g > 1.5) + lightmaps.g = 1.5; + if (lightmaps.b > 1.5) + lightmaps.b = 1.5; + + return lightmaps; + } + + void main (void) + { + vec4 diffuse_f; + diffuse_f.rgb = mix(texture2D(s_diffuse, tex_c).rgb, texture2D(s_upper, tex_c).rgb, vex_color.a); + diffuse_f.a = 1.0; + + /* deluxemapping isn't working on Source BSP yet, FIXME */ + diffuse_f.rgb *= lightmap_fragment(); + +#ifdef FAKESHADOWS + diffuse_f.rgb *= ShadowmapFilter(s_shadowmap, vtexprojcoord); +#endif + +/* CUBEMAPS ONLY */ +#ifdef REFLECTCUBEMASK + /* We currently only use the normal/bumpmap for cubemap warping. move this block out once we do proper radiosity normalmapping */ + #ifdef BUMP + /* Source's normalmaps are in the DX format where the green channel is flipped */ + vec4 normal_f = texture2D(s_normalmap, tex_c); + normal_f.g *= -1.0; + normal_f.rgb = normalize(normal_f.rgb - 0.5); + #else + vec4 normal_f = vec4(0.0,0.0,1.0,0.0); + #endif + + /* when ENVFROMBASE is set or a normal isn't present, we're getting the reflectivity info from the diffusemap's alpha channel */ + #if defined(ENVFROMBASE) || !defined(BUMP) + /* since we're sampling from the diffuse = 1.0 fully visible, 0.0 = fully reflective */ + #define refl 1.0 - diffuse_f.a + #else + #define refl normal_f.a * 0.5 + #endif + + vec3 cube_c = reflect(normalize(-eyevector), normal_f.rgb); + cube_c = cube_c.x * invsurface[0] + cube_c.y * invsurface[1] + cube_c.z * invsurface[2]; + cube_c = (m_model * vec4(cube_c.xyz, 0.0)).xyz; + diffuse_f.rgb += (textureCube(s_reflectcube, cube_c).rgb * vec3(refl,refl,refl)); +#endif + + gl_FragColor = fog4(diffuse_f); + } +#endif diff --git a/zpak001.pk3dir/glsl/vmt/unlit.glsl b/zpak001.pk3dir/glsl/vmt/unlit.glsl new file mode 100644 index 0000000..bcb7915 --- /dev/null +++ b/zpak001.pk3dir/glsl/vmt/unlit.glsl @@ -0,0 +1,30 @@ +!!ver 110 +!!permu FOG +!!samps diffuse + +#include "sys/defs.h" +#include "sys/fog.h" + +varying vec2 tex_c; + +#ifdef VERTEX_SHADER +void main () +{ + tex_c = v_texcoord; + gl_Position = ftetransform(); +} +#endif + +#ifdef FRAGMENT_SHADER +void main () +{ + vec4 diffuse_f = texture2D( s_diffuse, tex_c ); + +#ifdef MASKLT + if (diffuse_f.a < float(MASK)) + discard; +#endif + + gl_FragColor = fog4( diffuse_f ); +} +#endif diff --git a/zpak001.pk3dir/glsl/vmt/vertexlit.glsl b/zpak001.pk3dir/glsl/vmt/vertexlit.glsl new file mode 100644 index 0000000..8b53ccd --- /dev/null +++ b/zpak001.pk3dir/glsl/vmt/vertexlit.glsl @@ -0,0 +1,140 @@ +!!ver 110 +!!permu FRAMEBLEND +!!permu BUMP +!!permu FOG +!!permu SKELETAL +!!permu AMBIENTCUBE +!!samps diffuse fullbright normalmap +!!permu FAKESHADOWS +!!cvardf r_glsl_pcf +!!samps =FAKESHADOWS shadowmap + +// envmaps only +!!samps =REFLECTCUBEMASK reflectmask reflectcube + +!!cvardf r_skipDiffuse + +#include "sys/defs.h" + +varying vec2 tex_c; +varying vec3 norm; + +/* CUBEMAPS ONLY */ +#ifdef REFLECTCUBEMASK + varying vec3 eyevector; + varying mat3 invsurface; +#endif + +#ifdef FAKESHADOWS + varying vec4 vtexprojcoord; +#endif + +#ifdef VERTEX_SHADER + #include "sys/skeletal.h" + + void main (void) + { + vec3 n, s, t, w; + tex_c = v_texcoord; + gl_Position = skeletaltransform_wnst(w,n,s,t); + norm = n; + +/* CUBEMAPS ONLY */ +#ifdef REFLECTCUBEMASK + invsurface = mat3(v_svector, v_tvector, v_normal); + + vec3 eyeminusvertex = e_eyepos - v_position.xyz; + eyevector.x = dot(eyeminusvertex, v_svector.xyz); + eyevector.y = dot(eyeminusvertex, v_tvector.xyz); + eyevector.z = dot(eyeminusvertex, v_normal.xyz); +#endif + + #ifdef FAKESHADOWS + vtexprojcoord = (l_cubematrix*vec4(v_position.xyz, 1.0)); + #endif + } +#endif + + +#ifdef FRAGMENT_SHADER + #include "sys/fog.h" + #include "sys/pcf.h" + + float lambert(vec3 normal, vec3 dir) + { + return max(dot(normal, dir), 0.0); + } + + float halflambert(vec3 normal, vec3 dir) + { + return (lambert(normal, dir) * 0.5) + 0.5; + } + + void main (void) + { + vec4 diffuse_f = texture2D(s_diffuse, tex_c); + vec3 light; + +#ifdef MASKLT + if (diffuse_f.a < float(MASK)) + discard; +#endif + +/* Normal/Bumpmap Shenanigans */ +#ifdef BUMP + /* Source's normalmaps are in the DX format where the green channel is flipped */ + vec3 normal_f = texture2D(s_normalmap, tex_c).rgb; + normal_f.g *= -1.0; + normal_f = normalize(normal_f.rgb - 0.5); +#else + vec3 normal_f = vec3(0.0,0.0,1.0); +#endif + +/* CUBEMAPS ONLY */ +#ifdef REFLECTCUBEMASK + /* when ENVFROMBASE is set or a normal isn't present, we're getting the reflectivity info from the diffusemap's alpha channel */ + #if defined(ENVFROMBASE) || !defined(BUMP) + #define refl 1.0 - diffuse_f.a + #else + #define refl texture2D(s_normalmap, tex_c).a + #endif + vec3 cube_c = reflect(normalize(-eyevector), normal_f.rgb); + cube_c = cube_c.x * invsurface[0] + cube_c.y * invsurface[1] + cube_c.z * invsurface[2]; + cube_c = (m_model * vec4(cube_c.xyz, 0.0)).xyz; + diffuse_f.rgb += (textureCube(s_reflectcube, cube_c).rgb * vec3(refl,refl,refl)); +#endif + +#ifdef AMBIENTCUBE + //no specular effect here. use rtlights for that. + vec3 nn = norm*norm; //FIXME: should be worldspace normal. + light = nn.x * e_light_ambientcube[(norm.x<0.0)?1:0] + + nn.y * e_light_ambientcube[(norm.y<0.0)?3:2] + + nn.z * e_light_ambientcube[(norm.z<0.0)?5:4]; +#else + #ifdef HALFLAMBERT + light = e_light_ambient + (e_light_mul * halflambert(norm, e_light_dir)); + #else + light = e_light_ambient + (e_light_mul * lambert(norm, e_light_dir)); + #endif + + /* the light we're getting is always too bright */ + light *= 0.75; + + /* clamp at 1.5 */ + if (light.r > 1.5) + light.r = 1.5; + if (light.g > 1.5) + light.g = 1.5; + if (light.b > 1.5) + light.b = 1.5; +#endif + + diffuse_f.rgb *= light; + + #ifdef FAKESHADOWS + diffuse_f.rgb *= ShadowmapFilter(s_shadowmap, vtexprojcoord); + #endif + + gl_FragColor = fog4(diffuse_f * e_colourident) * e_lmscale; + } +#endif diff --git a/zpak001.pk3dir/glsl/vmt/water.glsl b/zpak001.pk3dir/glsl/vmt/water.glsl new file mode 100644 index 0000000..223a64e --- /dev/null +++ b/zpak001.pk3dir/glsl/vmt/water.glsl @@ -0,0 +1,183 @@ +!!cvardf r_glsl_turbscale_reflect=1 //simpler scaler +!!cvardf r_glsl_turbscale_refract=1 //simpler scaler +!!samps diffuse normalmap +!!samps refract=0 //always present +!!samps =REFLECT reflect=1 +!!samps !REFLECT reflectcube +!!permu FOG + +#include "sys/defs.h" + +//modifier: REFLECT (s_t2 is a reflection instead of diffusemap) +//modifier: STRENGTH_REFL (distortion strength - 0.1 = fairly gentle, 0.2 = big waves) +//modifier: STRENGTH_REFL (distortion strength - 0.1 = fairly gentle, 0.2 = big waves) +//modifier: FRESNEL_EXP (5=water) +//modifier: TXSCALE (wave size - 0.2) +//modifier: RIPPLEMAP (s_t3 contains a ripplemap +//modifier: TINT_REFR (some colour value) +//modifier: TINT_REFL (some colour value) +//modifier: ALPHA (mix in the normal water texture over the top) +//modifier: USEMODS (use single-texture scrolling via tcmods - note, also forces the engine to actually use tcmod etc) + +//a few notes on DP compat: +//'dpwater' makes numerous assumptions about DP internals +//by default there is a single pass that uses the pass's normal tcmods +//the fresnel has a user-supplied min+max rather than an exponent +//both parts are tinted individually +//if alpha is enabled, the regular water texture is blended over the top, again using the same crappy tcmods... + +//legacy crap +#ifndef FRESNEL +#define FRESNEL 5.0 +#endif +#ifndef TINT +#define TINT 0.7,0.8,0.7 +#endif +#ifndef STRENGTH +#define STRENGTH 0.1 +#endif +#ifndef TXSCALE +#define TXSCALE 1 +#endif + +//current values (referring to legacy defaults where needed) +#ifndef FRESNEL_EXP +#define FRESNEL_EXP 4.0 +#endif +#ifndef FRESNEL_MIN +#define FRESNEL_MIN 0.0 +#endif +#ifndef FRESNEL_RANGE +#define FRESNEL_RANGE 1.0 +#endif +#ifndef STRENGTH_REFL +#define STRENGTH_REFL STRENGTH +#endif +#ifndef STRENGTH_REFR +#define STRENGTH_REFR STRENGTH +#endif +#ifndef TXSCALE1 +#define TXSCALE1 TXSCALE +#endif +#ifndef TXSCALE2 +#define TXSCALE2 TXSCALE +#endif +#ifndef TINT_REFR +#define TINT_REFR TINT +#endif +#ifndef TINT_REFL +#define TINT_REFL 1.0,1.0,1.0 +#endif +#ifndef FOGTINT +#define FOGTINT 0.2,0.3,0.2 +#endif + +varying vec2 tc; +varying vec4 tf; +varying vec3 norm; +varying vec3 eye; +#ifdef VERTEX_SHADER +void main (void) +{ + tc = v_texcoord.st; + tf = ftetransform(); + norm = v_normal; + eye = e_eyepos - v_position.xyz; + gl_Position = ftetransform(); +} +#endif +#ifdef FRAGMENT_SHADER +#include "sys/fog.h" + + +void main (void) +{ + vec2 stc; //screen tex coords + vec2 ntc; //normalmap/diffuse tex coords + vec3 n, refr, refl; + float fres; + float depth; + stc = (1.0 + (tf.xy / tf.w)) * 0.5; + //hack the texture coords slightly so that there are less obvious gaps + stc.t -= 1.5*norm.z/1080.0; + +#if 0//def USEMODS + ntc = tc; + n = texture2D(s_normalmap, ntc).xyz - 0.5; +#else + //apply q1-style warp, just for kicks + ntc.s = tc.s + sin(tc.t+e_time)*0.125; + ntc.t = tc.t + sin(tc.s+e_time)*0.125; + + //generate the two wave patterns from the normalmap + n = (texture2D(s_normalmap, vec2(TXSCALE1)*tc + vec2(e_time*0.1, 0.0)).xyz); + n += (texture2D(s_normalmap, vec2(TXSCALE2)*tc - vec2(0, e_time*0.097)).xyz); + n -= 1.0 - 4.0/256.0; +#endif + +#ifdef RIPPLEMAP + n += texture2D(s_ripplemap, stc).rgb*3.0; +#endif + n = normalize(n); + + //the fresnel term decides how transparent the water should be + fres = pow(1.0-abs(dot(n, normalize(eye))), float(FRESNEL_EXP)) * float(FRESNEL_RANGE) + float(FRESNEL_MIN); + +#ifdef DEPTH + float far = #include "cvar/gl_maxdist"; + float near = #include "cvar/gl_mindist"; + //get depth value at the surface + float sdepth = gl_FragCoord.z; + sdepth = (2.0*near) / (far + near - sdepth * (far - near)); + sdepth = mix(near, far, sdepth); + + //get depth value at the ground beyond the surface. + float gdepth = texture2D(s_refractdepth, stc).x; + gdepth = (2.0*near) / (far + near - gdepth * (far - near)); + if (gdepth >= 0.5) + { + gdepth = sdepth; + depth = 0.0; + } + else + { + gdepth = mix(near, far, gdepth); + depth = gdepth - sdepth; + } + + //reduce the normals in shallow water (near walls, reduces the pain of linear sampling) + if (depth < 100.0) + n *= depth/100.0; +#else + depth = 1.0; +#endif + + + //refraction image (and water fog, if possible) + refr = texture2D(s_refract, stc + n.st*float(STRENGTH_REFR)*float(r_glsl_turbscale_refract)).rgb * vec3(TINT_REFR); +#ifdef DEPTH + refr = mix(refr, vec3(FOGTINT), min(depth/4096.0, 1.0)); +#endif + +#ifdef REFLECT + //reflection/diffuse + refl = texture2D(s_reflect, stc - n.st*float(STRENGTH_REFL)*float(r_glsl_turbscale_reflect)).rgb * vec3(TINT_REFL); +#else + refl = textureCube(s_reflectcube, n).rgb;// * vec3(TINT_REFL); +#endif + + //interplate by fresnel + refr = mix(refr, refl, fres); + +#ifdef ALPHA + vec4 ts = texture2D(s_diffuse, ntc); + vec4 surf = fog4blend(vec4(ts.rgb, float(ALPHA)*ts.a)); + refr = mix(refr, surf.rgb, surf.a); +#else + refr = fog3(refr); +#endif + + //done + gl_FragColor = vec4(refr, 1.0); +} +#endif