From 9cf713fba231add18dfb2abe155c129f5e0e7f6e Mon Sep 17 00:00:00 2001 From: nullprop Date: Sat, 5 Oct 2024 20:26:50 +0300 Subject: [PATCH] Photo mode (#1) --- .github/workflows/ci-cd.yml | 49 ++- cl_dll/Exports.h | 2 + cl_dll/camera.h | 5 +- cl_dll/in_camera.cpp | 546 ++++++++++++++++++--------------- cl_dll/view.cpp | 34 +- linux/Makefile | 2 + linux/Makefile.hl_cdll | 6 +- linux/Makefile.hldll | 6 +- photomode/config.cfg | 183 +++++++++++ photomode/gfx/shell/kb_act.lst | 59 ++++ photomode/gfx/shell/kb_def.lst | 54 ++++ photomode/liblist.gam | 9 + 12 files changed, 668 insertions(+), 287 deletions(-) create mode 100644 photomode/config.cfg create mode 100755 photomode/gfx/shell/kb_act.lst create mode 100755 photomode/gfx/shell/kb_def.lst create mode 100644 photomode/liblist.gam diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index 77170c6..13c8431 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -22,17 +22,25 @@ jobs: run: | cd linux make COMPILER=${{ matrix.compiler }} CFG=release -j2 - + + - name: Package + run: | + cp -r linux/release/cl_dlls photomode/cl_dlls + cp -r linux/release/dlls photomode/dlls + zip -r photomode-linux.zip photomode + - name: Deploy uses: actions/upload-artifact@v4 with: - name: Linux-x86-${{ matrix.compiler }} - path: | - linux/release/client.so - linux/release/client.so.dbg - linux/release/hl.so - linux/release/hl.so.dbg - + name: Linux-x86-${{ matrix.compiler }}-${{ github.sha }} + path: photomode + + - name: Release + uses: softprops/action-gh-release@v2 + if: github.ref == 'refs/heads/master' + with: + files: photomode-linux.zip + win32: name: Win32 runs-on: windows-latest @@ -48,13 +56,24 @@ jobs: - name: Build run: msbuild projects/vs2019/projects.sln -t:rebuild -property:Configuration=Release -maxcpucount:2 + - name: Package + run: | + mkdir photomode\cl_dlls + mkdir photomode\dlls + copy projects\vs2019\Release\hl_cdll\client.dll photomode\cl_dlls\client.dll + copy projects\vs2019\Release\hl_cdll\client.pdb photomode\cl_dlls\client.pdb + copy projects\vs2019\Release\hldll\hl.dll photomode\dlls\hl.dll + copy projects\vs2019\Release\hldll\hl.pdb photomode\dlls\hl.pdb + Compress-Archive photomode photomode-windows.zip + - name: Deploy uses: actions/upload-artifact@v4 with: - name: Win32 - path: | - projects/vs2019/Release/hl_cdll/client.dll - projects/vs2019/Release/hl_cdll/client.pdb - projects/vs2019/Release/hldll/hl.dll - projects/vs2019/Release/hldll/hl.pdb - + name: Win32-${{ github.sha }} + path: photomode + + - name: Release + uses: softprops/action-gh-release@v2 + if: github.ref == 'refs/heads/master' + with: + files: photomode-windows.zip diff --git a/cl_dll/Exports.h b/cl_dll/Exports.h index 7cefae7..3daee63 100644 --- a/cl_dll/Exports.h +++ b/cl_dll/Exports.h @@ -41,6 +41,8 @@ extern "C" void DLLEXPORT CAM_Think( void ); int DLLEXPORT CL_IsThirdPerson( void ); void DLLEXPORT CL_CameraOffset( float *ofs ); + int DLLEXPORT CL_IsPhotoMode( void ); + void DLLEXPORT CL_CameraPhotoModeOffset( float *ofs ); // From input struct kbutton_s DLLEXPORT *KB_Find( const char *name ); diff --git a/cl_dll/camera.h b/cl_dll/camera.h index 40367b1..ca84e57 100644 --- a/cl_dll/camera.h +++ b/cl_dll/camera.h @@ -10,10 +10,13 @@ #pragma once -// pitch, yaw, dist +// pitch, yaw, dist/roll extern Vector cam_ofs; +// photomode pos +extern Vector cam_pm_ofs; // Using third person camera extern bool cam_thirdperson; +extern bool cam_photomode; void CAM_Init(); void CAM_ClearStates(); diff --git a/cl_dll/in_camera.cpp b/cl_dll/in_camera.cpp index 4d378ea..2695de3 100644 --- a/cl_dll/in_camera.cpp +++ b/cl_dll/in_camera.cpp @@ -27,19 +27,15 @@ extern cl_enginefunc_t gEngfuncs; #define CAM_DIST_DELTA 1.0 #define CAM_ANGLE_DELTA 2.5 #define CAM_ANGLE_SPEED 2.5 +#define CAM_PM_MOVE_SPEED 1.0 #define CAM_MIN_DIST 30.0 -#define CAM_ANGLE_MOVE .5 -#define MAX_ANGLE_DIFF 10.0 -#define PITCH_MAX 90.0 -#define PITCH_MIN 0 -#define YAW_MAX 135.0 -#define YAW_MIN -135.0 enum ECAM_Command { CAM_COMMAND_NONE = 0, CAM_COMMAND_TOTHIRDPERSON = 1, - CAM_COMMAND_TOFIRSTPERSON = 2 + CAM_COMMAND_TOFIRSTPERSON = 2, + CAM_COMMAND_TOPHOTOMODE = 3 }; //-------------------------------------------------- Global Variables @@ -48,6 +44,7 @@ cvar_t* cam_command; cvar_t* cam_snapto; cvar_t* cam_idealyaw; cvar_t* cam_idealpitch; +cvar_t* cam_idealroll; cvar_t* cam_idealdist; cvar_t* cam_contain; @@ -55,41 +52,49 @@ cvar_t* c_maxpitch; cvar_t* c_minpitch; cvar_t* c_maxyaw; cvar_t* c_minyaw; +cvar_t* c_maxroll; +cvar_t* c_minroll; cvar_t* c_maxdistance; cvar_t* c_mindistance; -// pitch, yaw, dist -Vector cam_ofs; +int prev_hud_draw; +int prev_crosshair; +int prev_showpause; +// pitch, yaw, dist/roll +Vector cam_ofs; +// photomode pos +Vector cam_pm_ofs; // In third person bool cam_thirdperson; +bool cam_photomode; bool cam_mousemove; //true if we are moving the cam with the mouse, False if not bool iMouseInUse = false; bool cam_distancemove; -extern int mouse_x, mouse_y; //used to determine what the current x and y values are -int cam_old_mouse_x, cam_old_mouse_y; //holds the last ticks mouse movement Point cam_mouse; //-------------------------------------------------- Local Variables static kbutton_t cam_pitchup, cam_pitchdown, cam_yawleft, cam_yawright; static kbutton_t cam_in, cam_out, cam_move; +static kbutton_t cam_pm_forward; +static kbutton_t cam_pm_back; +static kbutton_t cam_pm_left; +static kbutton_t cam_pm_right; +static kbutton_t cam_pm_up; +static kbutton_t cam_pm_down; //-------------------------------------------------- Prototypes void CAM_ToThirdPerson(); void CAM_ToFirstPerson(); +void CAM_ToPhotoMode(); void CAM_StartDistance(); void CAM_EndDistance(); -void SDL_GetCursorPos(Point* p) -{ - gEngfuncs.GetMousePosition(&p->x, &p->y); - // SDL_GetMouseState( &p->x, &p->y ); -} - -void SDL_SetCursorPos(const int x, const int y) +void SDL_GetMouseMovement(Point* p) { + SDL_GetRelativeMouseState(&p->x, &p->y); } //-------------------------------------------------- Local Functions @@ -154,15 +159,12 @@ void DLLEXPORT CAM_Think() // RecClCamThink(); Vector origin; - Vector ext, pnt, camForward, camRight, camUp; + Vector ext, pnt, camForward, camRight, camUp, camMove; moveclip_t clip; float dist; Vector camAngles; - float flSensitivity; -#ifdef LATER - int i; -#endif Vector viewangles; + float flSensitivity = 0.022f * CVAR_GET_FLOAT("sensitivity"); switch ((int)cam_command->value) { @@ -174,239 +176,174 @@ void DLLEXPORT CAM_Think() CAM_ToFirstPerson(); break; + case CAM_COMMAND_TOPHOTOMODE: + CAM_ToPhotoMode(); + break; + case CAM_COMMAND_NONE: default: break; } - if (!cam_thirdperson) + if (!cam_thirdperson && !cam_photomode) return; -#ifdef LATER - if (cam_contain->value) - { - gEngfuncs.GetClientOrigin(origin); - ext[0] = ext[1] = ext[2] = 0.0; - } -#endif + camAngles[PITCH] = cam_idealpitch->value; + camAngles[YAW] = cam_idealyaw->value; + camAngles[ROLL] = cam_idealroll->value; + dist = cam_idealdist->value; - camAngles[PITCH] = cam_idealpitch->value; - camAngles[YAW] = cam_idealyaw->value; - dist = cam_idealdist->value; - // - //movement of the camera with the mouse - // - if (cam_mousemove) - { - //get windows cursor position - SDL_GetCursorPos(&cam_mouse); - //check for X delta values and adjust accordingly - //eventually adjust YAW based on amount of movement - //don't do any movement of the cam using YAW/PITCH if we are zooming in/out the camera - if (!cam_distancemove) - { + SDL_GetMouseMovement(&cam_mouse); - //keep the camera within certain limits around the player (ie avoid certain bad viewing angles) - if (cam_mouse.x > gEngfuncs.GetWindowCenterX()) - { - //if ((camAngles[YAW]>=225.0)||(camAngles[YAW]<135.0)) - if (camAngles[YAW] < c_maxyaw->value) - { - camAngles[YAW] += (CAM_ANGLE_MOVE) * ((cam_mouse.x - gEngfuncs.GetWindowCenterX()) / 2); - } - if (camAngles[YAW] > c_maxyaw->value) - { + if (cam_thirdperson) + { + // + //movement of the camera with the mouse + // + if (cam_mousemove) + { + //check for X delta values and adjust accordingly + //eventually adjust YAW based on amount of movement + //don't do any movement of the cam using YAW/PITCH if we are zooming in/out the camera + if (!cam_distancemove) + { + //keep the camera within certain limits around the player (ie avoid certain bad viewing angles) + if (cam_mouse.x != 0) + { + camAngles[YAW] -= flSensitivity * cam_mouse.x; + if (camAngles[YAW] > c_maxyaw->value) + { + camAngles[YAW] = c_maxyaw->value; + } + if (camAngles[YAW] < c_minyaw->value) + { + camAngles[YAW] = c_minyaw->value; + } + } - camAngles[YAW] = c_maxyaw->value; - } - } - else if (cam_mouse.x < gEngfuncs.GetWindowCenterX()) - { - //if ((camAngles[YAW]<=135.0)||(camAngles[YAW]>225.0)) - if (camAngles[YAW] > c_minyaw->value) - { - camAngles[YAW] -= (CAM_ANGLE_MOVE) * ((gEngfuncs.GetWindowCenterX() - cam_mouse.x) / 2); - } - if (camAngles[YAW] < c_minyaw->value) - { - camAngles[YAW] = c_minyaw->value; - } - } + //check for y delta values and adjust accordingly + //eventually adjust PITCH based on amount of movement + //also make sure camera is within bounds + if (cam_mouse.y != 0) + { + camAngles[PITCH] += flSensitivity * cam_mouse.y; + if (camAngles[PITCH] > c_maxpitch->value) + { + camAngles[PITCH] = c_maxpitch->value; + } + if (camAngles[PITCH] < c_minpitch->value) + { + camAngles[PITCH] = c_minpitch->value; + } + } + } + } - //check for y delta values and adjust accordingly - //eventually adjust PITCH based on amount of movement - //also make sure camera is within bounds - if (cam_mouse.y > gEngfuncs.GetWindowCenterY()) - { - if (camAngles[PITCH] < c_maxpitch->value) - { - camAngles[PITCH] += (CAM_ANGLE_MOVE) * ((cam_mouse.y - gEngfuncs.GetWindowCenterY()) / 2); - } - if (camAngles[PITCH] > c_maxpitch->value) - { - camAngles[PITCH] = c_maxpitch->value; - } - } - else if (cam_mouse.y < gEngfuncs.GetWindowCenterY()) - { - if (camAngles[PITCH] > c_minpitch->value) - { - camAngles[PITCH] -= (CAM_ANGLE_MOVE) * ((gEngfuncs.GetWindowCenterY() - cam_mouse.y) / 2); - } - if (camAngles[PITCH] < c_minpitch->value) - { - camAngles[PITCH] = c_minpitch->value; - } - } + //Nathan code here + if (0 != CL_KeyState(&cam_pitchup)) + camAngles[PITCH] += CAM_ANGLE_DELTA; + else if (0 != CL_KeyState(&cam_pitchdown)) + camAngles[PITCH] -= CAM_ANGLE_DELTA; - //set old mouse coordinates to current mouse coordinates - //since we are done with the mouse + if (0 != CL_KeyState(&cam_yawleft)) + camAngles[YAW] -= CAM_ANGLE_DELTA; + else if (0 != CL_KeyState(&cam_yawright)) + camAngles[YAW] += CAM_ANGLE_DELTA; - if ((flSensitivity = gHUD.GetSensitivity()) != 0) - { - cam_old_mouse_x = cam_mouse.x * flSensitivity; - cam_old_mouse_y = cam_mouse.y * flSensitivity; - } - else - { - cam_old_mouse_x = cam_mouse.x; - cam_old_mouse_y = cam_mouse.y; - } - SDL_SetCursorPos(gEngfuncs.GetWindowCenterX(), gEngfuncs.GetWindowCenterY()); - } - } + if (0 != CL_KeyState(&cam_in)) + { + dist -= CAM_DIST_DELTA; + if (dist < CAM_MIN_DIST) + { + // If we go back into first person, reset the angle + camAngles[PITCH] = 0; + camAngles[YAW] = 0; + dist = CAM_MIN_DIST; + } + } + else if (0 != CL_KeyState(&cam_out)) + dist += CAM_DIST_DELTA; - //Nathan code here - if (0 != CL_KeyState(&cam_pitchup)) - camAngles[PITCH] += CAM_ANGLE_DELTA; - else if (0 != CL_KeyState(&cam_pitchdown)) - camAngles[PITCH] -= CAM_ANGLE_DELTA; + if (cam_distancemove) + { + if (cam_mouse.y != 0) + { + dist += CAM_DIST_DELTA * flSensitivity * cam_mouse.y; + if (dist > c_maxdistance->value) + { + dist = c_maxdistance->value; + } + if (dist < c_mindistance->value) + { + dist = c_mindistance->value; + } + } + } + } - if (0 != CL_KeyState(&cam_yawleft)) - camAngles[YAW] -= CAM_ANGLE_DELTA; - else if (0 != CL_KeyState(&cam_yawright)) - camAngles[YAW] += CAM_ANGLE_DELTA; + if (cam_photomode) + { + cam_ofs[YAW] -= flSensitivity * cam_mouse.x; + cam_ofs[PITCH] += flSensitivity * cam_mouse.y; + cam_ofs[ROLL] = 0; - if (0 != CL_KeyState(&cam_in)) - { - dist -= CAM_DIST_DELTA; - if (dist < CAM_MIN_DIST) - { - // If we go back into first person, reset the angle - camAngles[PITCH] = 0; - camAngles[YAW] = 0; - dist = CAM_MIN_DIST; - } - } - else if (0 != CL_KeyState(&cam_out)) - dist += CAM_DIST_DELTA; + AngleVectors(cam_ofs, camForward, camRight, NULL); - if (cam_distancemove) - { - if (cam_mouse.y > gEngfuncs.GetWindowCenterY()) - { - if (dist < c_maxdistance->value) - { - dist += CAM_DIST_DELTA * ((cam_mouse.y - gEngfuncs.GetWindowCenterY()) / 2); - } - if (dist > c_maxdistance->value) - { - dist = c_maxdistance->value; - } - } - else if (cam_mouse.y < gEngfuncs.GetWindowCenterY()) - { - if (dist > c_mindistance->value) - { - dist -= (CAM_DIST_DELTA) * ((gEngfuncs.GetWindowCenterY() - cam_mouse.y) / 2); - } - if (dist < c_mindistance->value) - { - dist = c_mindistance->value; - } - } - //set old mouse coordinates to current mouse coordinates - //since we are done with the mouse - cam_old_mouse_x = cam_mouse.x * gHUD.GetSensitivity(); - cam_old_mouse_y = cam_mouse.y * gHUD.GetSensitivity(); - SDL_SetCursorPos(gEngfuncs.GetWindowCenterX(), gEngfuncs.GetWindowCenterY()); - } -#ifdef LATER - if (cam_contain->value) - { - // check new ideal - VectorCopy(origin, pnt); - AngleVectors(camAngles, camForward, camRight, camUp); - for (i = 0; i < 3; i++) - pnt[i] += -dist * camForward[i]; + camMove[0] = CL_KeyState(&cam_pm_forward); + camMove[0] -= CL_KeyState(&cam_pm_back); + camMove[1] = CL_KeyState(&cam_pm_right); + camMove[1] -= CL_KeyState(&cam_pm_left); + camMove[2] = CL_KeyState(&cam_pm_up); + camMove[2] -= CL_KeyState(&cam_pm_down); - // check line from r_refdef.vieworg to pnt - memset(&clip, 0, sizeof(moveclip_t)); - clip.trace = SV_ClipMoveToEntity(sv.edicts, r_refdef.vieworg, ext, ext, pnt); - if (clip.trace.fraction == 1.0) - { - // update ideal - cam_idealpitch->value = camAngles[PITCH]; - cam_idealyaw->value = camAngles[YAW]; - cam_idealdist->value = dist; - } - } - else -#endif - { - // update ideal - cam_idealpitch->value = camAngles[PITCH]; - cam_idealyaw->value = camAngles[YAW]; - cam_idealdist->value = dist; - } + for (int i = 0; i < 3; i++) + { + cam_pm_ofs[i] += camMove[0] * camForward[i] * CAM_PM_MOVE_SPEED; + cam_pm_ofs[i] += camMove[1] * camRight[i] * CAM_PM_MOVE_SPEED; + } + cam_pm_ofs[2] += camMove[2] * CAM_PM_MOVE_SPEED; + } - // Move towards ideal - VectorCopy(cam_ofs, camAngles); + if (cam_thirdperson) + { + // update ideal + cam_idealpitch->value = camAngles[PITCH]; + cam_idealyaw->value = camAngles[YAW]; + cam_idealroll->value = camAngles[ROLL]; + cam_idealdist->value = dist; - gEngfuncs.GetViewAngles((float*)viewangles); + // Move towards ideal + VectorCopy(cam_ofs, camAngles); - if (0 != cam_snapto->value) - { - camAngles[YAW] = cam_idealyaw->value + viewangles[YAW]; - camAngles[PITCH] = cam_idealpitch->value + viewangles[PITCH]; - camAngles[2] = cam_idealdist->value; - } - else - { - if (camAngles[YAW] - viewangles[YAW] != cam_idealyaw->value) - camAngles[YAW] = MoveToward(camAngles[YAW], cam_idealyaw->value + viewangles[YAW], CAM_ANGLE_SPEED); + gEngfuncs.GetViewAngles((float*)viewangles); - if (camAngles[PITCH] - viewangles[PITCH] != cam_idealpitch->value) - camAngles[PITCH] = MoveToward(camAngles[PITCH], cam_idealpitch->value + viewangles[PITCH], CAM_ANGLE_SPEED); + if (0 != cam_snapto->value) + { + camAngles[YAW] = cam_idealyaw->value + viewangles[YAW]; + camAngles[PITCH] = cam_idealpitch->value + viewangles[PITCH]; + camAngles[ROLL] = cam_idealdist->value; + } + else + { + if (camAngles[YAW] - viewangles[YAW] != cam_idealyaw->value) + camAngles[YAW] = MoveToward(camAngles[YAW], cam_idealyaw->value + viewangles[YAW], CAM_ANGLE_SPEED); - if (fabs(camAngles[2] - cam_idealdist->value) < 2.0) - camAngles[2] = cam_idealdist->value; - else - camAngles[2] += (cam_idealdist->value - camAngles[2]) / 4.0; - } -#ifdef LATER - if (cam_contain->value) - { - // Test new position - dist = camAngles[ROLL]; - camAngles[ROLL] = 0; + if (camAngles[PITCH] - viewangles[PITCH] != cam_idealpitch->value) + camAngles[PITCH] = MoveToward(camAngles[PITCH], cam_idealpitch->value + viewangles[PITCH], CAM_ANGLE_SPEED); - VectorCopy(origin, pnt); - AngleVectors(camAngles, camForward, camRight, camUp); - for (i = 0; i < 3; i++) - pnt[i] += -dist * camForward[i]; - - // check line from r_refdef.vieworg to pnt - memset(&clip, 0, sizeof(moveclip_t)); - ext[0] = ext[1] = ext[2] = 0.0; - clip.trace = SV_ClipMoveToEntity(sv.edicts, r_refdef.vieworg, ext, ext, pnt); - if (clip.trace.fraction != 1.0) - return; - } -#endif - cam_ofs[0] = camAngles[0]; - cam_ofs[1] = camAngles[1]; - cam_ofs[2] = dist; + if (fabs(camAngles[ROLL] - cam_idealdist->value) < 2.0) + { + camAngles[ROLL] = cam_idealdist->value; + } + else + { + camAngles[ROLL] += (cam_idealdist->value - camAngles[2]) / 4.0; + } + } + cam_ofs[0] = camAngles[0]; + cam_ofs[1] = camAngles[1]; + cam_ofs[2] = dist; + } } extern void KeyDown(kbutton_t* b); // HACK @@ -424,6 +361,31 @@ void CAM_InDown() { KeyDown(&cam_in); } void CAM_InUp() { KeyUp(&cam_in); } void CAM_OutDown() { KeyDown(&cam_out); } void CAM_OutUp() { KeyUp(&cam_out); } +void CAM_PM_ForwardDown() { KeyDown(&cam_pm_forward); } +void CAM_PM_ForwardUp() { KeyUp(&cam_pm_forward); } +void CAM_PM_BackDown() { KeyDown(&cam_pm_back); } +void CAM_PM_BackUp() { KeyUp(&cam_pm_back); } +void CAM_PM_LeftDown() { KeyDown(&cam_pm_left); } +void CAM_PM_LeftUp() { KeyUp(&cam_pm_left); } +void CAM_PM_RightDown() { KeyDown(&cam_pm_right); } +void CAM_PM_RightUp() { KeyUp(&cam_pm_right); } +void CAM_PM_UpDown() { KeyDown(&cam_pm_up); } +void CAM_PM_UpUp() { KeyUp(&cam_pm_up); } +void CAM_PM_DownDown() { KeyDown(&cam_pm_down); } +void CAM_PM_DownUp() { KeyUp(&cam_pm_down); } + +void CAM_ExitPhotoMode() +{ + if (cam_photomode) + { + cam_photomode = false; + iMouseInUse = cam_mousemove; + gEngfuncs.Cvar_SetValue("hud_draw", prev_hud_draw); + gEngfuncs.Cvar_SetValue("crosshair", prev_crosshair); + gEngfuncs.Cvar_SetValue("showpause", prev_showpause); + gEngfuncs.pfnClientCmd("pause"); + } +} void CAM_ToThirdPerson() { @@ -441,11 +403,12 @@ void CAM_ToThirdPerson() if (!cam_thirdperson) { + CAM_ExitPhotoMode(); cam_thirdperson = true; cam_ofs[YAW] = viewangles[YAW]; cam_ofs[PITCH] = viewangles[PITCH]; - cam_ofs[2] = CAM_MIN_DIST; + cam_ofs[ROLL] = CAM_MIN_DIST; } gEngfuncs.Cvar_SetValue("cam_command", 0); @@ -454,10 +417,56 @@ void CAM_ToThirdPerson() void CAM_ToFirstPerson() { cam_thirdperson = false; - + CAM_ExitPhotoMode(); gEngfuncs.Cvar_SetValue("cam_command", 0); } +void CAM_ToPhotoMode() +{ + Vector viewangles; + +#if !defined(_DEBUG) + if (gEngfuncs.GetMaxClients() > 1) + { + // no photo mode in multiplayer. + return; + } +#endif + + gEngfuncs.GetViewAngles((float*)viewangles); + + if (!cam_photomode) + { + cam_thirdperson = false; + cam_photomode = true; + iMouseInUse = true; + cam_mousemove = false; + cam_distancemove = false; + + cam_ofs[YAW] = viewangles[YAW]; + cam_ofs[PITCH] = viewangles[PITCH]; + cam_ofs[ROLL] = viewangles[ROLL]; + + cam_pm_ofs[0] = 0; + cam_pm_ofs[1] = 0; + cam_pm_ofs[2] = 0; + + prev_hud_draw = (int)CVAR_GET_FLOAT("hud_draw"); + prev_crosshair = (int)CVAR_GET_FLOAT("crosshair"); + prev_showpause = (int)CVAR_GET_FLOAT("showpause"); + gEngfuncs.Cvar_SetValue("hud_draw", 0); + gEngfuncs.Cvar_SetValue("crosshair", 0); + gEngfuncs.Cvar_SetValue("showpause", 0); + gEngfuncs.pfnClientCmd("pause"); + } + else + { + CAM_ExitPhotoMode(); + } + + gEngfuncs.Cvar_SetValue("cam_command", 0); +} + void CAM_ToggleSnapto() { cam_snapto->value = 0 != cam_snapto->value ? 0 : 1; @@ -479,23 +488,39 @@ void CAM_Init() gEngfuncs.pfnAddCommand("-camout", CAM_OutUp); gEngfuncs.pfnAddCommand("thirdperson", CAM_ToThirdPerson); gEngfuncs.pfnAddCommand("firstperson", CAM_ToFirstPerson); + gEngfuncs.pfnAddCommand("photomode", CAM_ToPhotoMode); gEngfuncs.pfnAddCommand("+cammousemove", CAM_StartMouseMove); gEngfuncs.pfnAddCommand("-cammousemove", CAM_EndMouseMove); gEngfuncs.pfnAddCommand("+camdistance", CAM_StartDistance); gEngfuncs.pfnAddCommand("-camdistance", CAM_EndDistance); gEngfuncs.pfnAddCommand("snapto", CAM_ToggleSnapto); + gEngfuncs.pfnAddCommand("+cam_pm_forward", CAM_PM_ForwardDown); + gEngfuncs.pfnAddCommand("-cam_pm_forward", CAM_PM_ForwardUp); + gEngfuncs.pfnAddCommand("+cam_pm_back", CAM_PM_BackDown); + gEngfuncs.pfnAddCommand("-cam_pm_back", CAM_PM_BackUp); + gEngfuncs.pfnAddCommand("+cam_pm_left", CAM_PM_LeftDown); + gEngfuncs.pfnAddCommand("-cam_pm_left", CAM_PM_LeftUp); + gEngfuncs.pfnAddCommand("+cam_pm_right", CAM_PM_RightDown); + gEngfuncs.pfnAddCommand("-cam_pm_right", CAM_PM_RightUp); + gEngfuncs.pfnAddCommand("+cam_pm_up", CAM_PM_UpDown); + gEngfuncs.pfnAddCommand("-cam_pm_up", CAM_PM_UpUp); + gEngfuncs.pfnAddCommand("+cam_pm_down", CAM_PM_DownDown); + gEngfuncs.pfnAddCommand("-cam_pm_down", CAM_PM_DownUp); cam_command = gEngfuncs.pfnRegisterVariable("cam_command", "0", 0); // tells camera to go to thirdperson cam_snapto = gEngfuncs.pfnRegisterVariable("cam_snapto", "0", 0); // snap to thirdperson view cam_idealyaw = gEngfuncs.pfnRegisterVariable("cam_idealyaw", "90", 0); // thirdperson yaw cam_idealpitch = gEngfuncs.pfnRegisterVariable("cam_idealpitch", "0", 0); // thirperson pitch + cam_idealroll = gEngfuncs.pfnRegisterVariable("cam_idealroll", "0", 0); // photomode roll cam_idealdist = gEngfuncs.pfnRegisterVariable("cam_idealdist", "64", 0); // thirdperson distance cam_contain = gEngfuncs.pfnRegisterVariable("cam_contain", "0", 0); // contain camera to world c_maxpitch = gEngfuncs.pfnRegisterVariable("c_maxpitch", "90.0", 0); - c_minpitch = gEngfuncs.pfnRegisterVariable("c_minpitch", "0.0", 0); - c_maxyaw = gEngfuncs.pfnRegisterVariable("c_maxyaw", "135.0", 0); - c_minyaw = gEngfuncs.pfnRegisterVariable("c_minyaw", "-135.0", 0); + c_minpitch = gEngfuncs.pfnRegisterVariable("c_minpitch", "-90.0", 0); + c_maxyaw = gEngfuncs.pfnRegisterVariable("c_maxyaw", "180.0", 0); + c_minyaw = gEngfuncs.pfnRegisterVariable("c_minyaw", "-180.0", 0); + c_maxroll = gEngfuncs.pfnRegisterVariable("c_maxroll", "180.0", 0); + c_minroll = gEngfuncs.pfnRegisterVariable("c_minroll", "-180.0", 0); c_maxdistance = gEngfuncs.pfnRegisterVariable("c_maxdistance", "200.0", 0); c_mindistance = gEngfuncs.pfnRegisterVariable("c_mindistance", "30.0", 0); } @@ -513,7 +538,15 @@ void CAM_ClearStates() cam_in.state = 0; cam_out.state = 0; + cam_pm_forward.state = 0; + cam_pm_back.state = 0; + cam_pm_right.state = 0; + cam_pm_left.state = 0; + cam_pm_up.state = 0; + cam_pm_down.state = 0; + cam_thirdperson = false; + cam_photomode = false; cam_command->value = 0; cam_mousemove = false; @@ -524,15 +557,22 @@ void CAM_ClearStates() cam_ofs[1] = 0.0; cam_ofs[2] = CAM_MIN_DIST; + cam_pm_ofs[0] = 0.0; + cam_pm_ofs[1] = 0.0; + cam_pm_ofs[2] = 0.0; + cam_idealpitch->value = viewangles[PITCH]; cam_idealyaw->value = viewangles[YAW]; + cam_idealroll->value = viewangles[ROLL]; cam_idealdist->value = CAM_MIN_DIST; + + prev_hud_draw = (int)CVAR_GET_FLOAT("hud_draw"); + prev_crosshair = (int)CVAR_GET_FLOAT("crosshair"); + prev_showpause = (int)CVAR_GET_FLOAT("showpause"); } void CAM_StartMouseMove() { - float flSensitivity; - //only move the cam with mouse if we are in third person. if (cam_thirdperson) { @@ -542,18 +582,6 @@ void CAM_StartMouseMove() { cam_mousemove = true; iMouseInUse = true; - SDL_GetCursorPos(&cam_mouse); - - if ((flSensitivity = gHUD.GetSensitivity()) != 0) - { - cam_old_mouse_x = cam_mouse.x * flSensitivity; - cam_old_mouse_y = cam_mouse.y * flSensitivity; - } - else - { - cam_old_mouse_x = cam_mouse.x; - cam_old_mouse_y = cam_mouse.y; - } } } //we are not in 3rd person view..therefore do not allow camera movement @@ -589,9 +617,6 @@ void CAM_StartDistance() cam_distancemove = true; cam_mousemove = true; iMouseInUse = true; - SDL_GetCursorPos(&cam_mouse); - cam_old_mouse_x = cam_mouse.x * gHUD.GetSensitivity(); - cam_old_mouse_y = cam_mouse.y * gHUD.GetSensitivity(); } } //we are not in 3rd person view..therefore do not allow camera movement @@ -616,7 +641,8 @@ int DLLEXPORT CL_IsThirdPerson() { // RecClCL_IsThirdPerson(); - return static_cast(cam_thirdperson || (0 != g_iUser1 && (g_iUser2 == gEngfuncs.GetLocalPlayer()->index))); + // Return true for photo mode so engine draws gordon + return static_cast(cam_thirdperson || cam_photomode || (0 != g_iUser1 && (g_iUser2 == gEngfuncs.GetLocalPlayer()->index))); } void DLLEXPORT CL_CameraOffset(float* ofs) @@ -625,3 +651,13 @@ void DLLEXPORT CL_CameraOffset(float* ofs) VectorCopy(cam_ofs, ofs); } + +int DLLEXPORT CL_IsPhotoMode() +{ + return static_cast(cam_photomode || (0 != g_iUser1 && (g_iUser2 == gEngfuncs.GetLocalPlayer()->index))); +} + +void DLLEXPORT CL_CameraPhotoModeOffset(float* ofs) +{ + VectorCopy(cam_pm_ofs, ofs); +} diff --git a/cl_dll/view.cpp b/cl_dll/view.cpp index 2dd7c4f..3b3ea80 100644 --- a/cl_dll/view.cpp +++ b/cl_dll/view.cpp @@ -21,6 +21,7 @@ #include "Exports.h" int CL_IsThirdPerson(); +int CL_IsPhotoMode(); void CL_CameraOffset(float* ofs); void DLLEXPORT V_CalcRefdef(struct ref_params_s* pparams); @@ -613,24 +614,33 @@ void V_CalcNormalRefdef(struct ref_params_s* pparams) } } - // Treating cam_ofs[2] as the distance if (0 != CL_IsThirdPerson()) { Vector ofs; - ofs[0] = ofs[1] = ofs[2] = 0.0; - CL_CameraOffset((float*)&ofs); + VectorCopy(ofs, camAngles); - VectorCopy(ofs, camAngles); - camAngles[ROLL] = 0; + if (CL_IsPhotoMode() != 0) + { + CL_CameraPhotoModeOffset((float*)&ofs); + for (i = 0; i < 3; i++) + { + pparams->vieworg[i] += ofs[i]; + } + } + else + { + // Treating cam_ofs[ROLL] as the distance + camAngles[ROLL] = 0; - AngleVectors(camAngles, camForward, camRight, camUp); + AngleVectors(camAngles, camForward, camRight, camUp); - for (i = 0; i < 3; i++) - { - pparams->vieworg[i] += -ofs[2] * camForward[i]; - } + for (i = 0; i < 3; i++) + { + pparams->vieworg[i] += -ofs[ROLL] * camForward[i]; + } + } } // Give gun our viewangles @@ -792,7 +802,7 @@ void V_CalcNormalRefdef(struct ref_params_s* pparams) v_client_aimangles = pparams->cl_viewangles; v_lastAngles = pparams->viewangles; // v_cl_angles = pparams->cl_viewangles; // keep old user mouse angles ! - if (0 != CL_IsThirdPerson()) + if (CL_IsThirdPerson() != 0 || CL_IsPhotoMode() != 0) { VectorCopy(camAngles, pparams->viewangles); } @@ -1640,7 +1650,7 @@ void DLLEXPORT V_CalcRefdef(struct ref_params_s* pparams) { V_CalcSpectatorRefdef(pparams); } - else if (0 == pparams->paused) + else if (0 == pparams->paused || CL_IsPhotoMode()) { V_CalcNormalRefdef(pparams); } diff --git a/linux/Makefile b/linux/Makefile index fefa963..894e657 100644 --- a/linux/Makefile +++ b/linux/Makefile @@ -80,6 +80,8 @@ TARGETS+= \ build_dir: -mkdir -p $(BUILD_DIR); + -mkdir -p $(BUILD_DIR)/cl_dlls; + -mkdir -p $(BUILD_DIR)/dlls; cd $(BUILD_DIR) targets: $(TARGETS) diff --git a/linux/Makefile.hl_cdll b/linux/Makefile.hl_cdll index 134ef8d..b0342ad 100644 --- a/linux/Makefile.hl_cdll +++ b/linux/Makefile.hl_cdll @@ -3,6 +3,8 @@ # # +CDLL_BUILD_DIR=$(BUILD_DIR)/cl_dlls + HL_SRC_DIR=$(SOURCE_DIR)/cl_dll HL_PARTICLEMAN_DIR=$(SOURCE_DIR)/cl_dll/particleman HL_SERVER_SRC_DIR=$(SOURCE_DIR)/dlls @@ -128,8 +130,8 @@ PM_SHARED_OBJS = \ all: client.$(SHLIBEXT) client.$(SHLIBEXT): $(HL1_OBJS) $(PUBLIC_OBJS) $(COMMON_OBJS) $(GAME_SHARED_OBJS) $(DLL_OBJS) $(PM_SHARED_OBJS) $(HL1_PARTICLEMAN_OBJS) - $(CPLUS) -o $(BUILD_DIR)/$@ $(HL1_OBJS) $(PUBLIC_OBJS) $(COMMON_OBJS) $(GAME_SHARED_OBJS) $(DLL_OBJS) $(PM_SHARED_OBJS) $(HL1_PARTICLEMAN_OBJS) $(LDFLAGS) $(CPP_LIB) - ./gendbg.sh $(BUILD_DIR)/client.$(SHLIBEXT) + $(CPLUS) -o $(CDLL_BUILD_DIR)/$@ $(HL1_OBJS) $(PUBLIC_OBJS) $(COMMON_OBJS) $(GAME_SHARED_OBJS) $(DLL_OBJS) $(PM_SHARED_OBJS) $(HL1_PARTICLEMAN_OBJS) $(LDFLAGS) $(CPP_LIB) + ./gendbg.sh $(CDLL_BUILD_DIR)/client.$(SHLIBEXT) $(HL1_OBJ_DIR): mkdir -p $(HL1_OBJ_DIR) diff --git a/linux/Makefile.hldll b/linux/Makefile.hldll index c55de4d..0c09d42 100644 --- a/linux/Makefile.hldll +++ b/linux/Makefile.hldll @@ -4,6 +4,8 @@ # Feb 2001 by Leon Hartwig (hartwig@valvesoftware.com) # +DLL_BUILD_DIR=$(BUILD_DIR)/dlls + HLDLL_SRC_DIR=$(SOURCE_DIR)/dlls HLDLL_OBJ_DIR=$(BUILD_OBJ_DIR)/hldll @@ -150,8 +152,8 @@ dirs: -mkdir -p $(COMMON_OBJ_DIR) hl.$(SHLIBEXT): $(HLDLL_OBJS) $(PM_OBJS) $(GAME_SHARED_OBJS) $(PUBLIC_OBJS) $(COMMON_OBJS) - $(CPLUS) $(LDFLAGS) $(SHLIBLDFLAGS) -o $(BUILD_DIR)/$@ $(HLDLL_OBJS) $(PM_OBJS) $(GAME_SHARED_OBJS) $(PUBLIC_OBJS) $(COMMON_OBJS) $(CPP_LIB) - ./gendbg.sh $(BUILD_DIR)/hl.$(SHLIBEXT) + $(CPLUS) $(LDFLAGS) $(SHLIBLDFLAGS) -o $(DLL_BUILD_DIR)/$@ $(HLDLL_OBJS) $(PM_OBJS) $(GAME_SHARED_OBJS) $(PUBLIC_OBJS) $(COMMON_OBJS) $(CPP_LIB) + ./gendbg.sh $(DLL_BUILD_DIR)/hl.$(SHLIBEXT) $(HLDLL_OBJ_DIR)/%.o : $(HLDLL_SRC_DIR)/%.cpp $(DO_CC) diff --git a/photomode/config.cfg b/photomode/config.cfg new file mode 100644 index 0000000..e5d43e8 --- /dev/null +++ b/photomode/config.cfg @@ -0,0 +1,183 @@ +// This file is overwritten whenever you change your user settings in the game. +// Add custom configurations to the file "userconfig.cfg". + +unbindall +bind "TAB" "photomode" +bind "ENTER" "+attack" +bind "ESCAPE" "cancelselect" +bind "SPACE" "+jump" +bind "'" "+moveup" +bind "+" "sizeup" +bind "," "+moveleft" +bind "-" "sizedown" +bind "." "+moveright" +bind "/" "+movedown" +bind "1" "slot1" +bind "2" "slot2" +bind "3" "slot3" +bind "4" "slot4" +bind "5" "slot5" +bind ";" "+mlook" +bind "=" "sizeup" +bind "[" "invprev" +bind "]" "invnext" +bind "`" "toggleconsole" +bind "a" "+moveleft" +bind "c" "+movedown" +bind "d" "+moveright" +bind "e" "+use" +bind "f" "impulse 100" +bind "k" "+voicerecord" +bind "l" "+cam_pm_down" +bind "n" "pause" +bind "o" "+cam_pm_up" +bind "p" "photomode" +bind "q" "lastinv" +bind "r" "+reload" +bind "s" "+back" +bind "t" "impulse 201" +bind "u" "messagemode2" +bind "v" "+moveup" +bind "w" "+forward" +bind "y" "messagemode" +bind "~" "toggleconsole" +bind "UPARROW" "+cam_pm_forward" +bind "DOWNARROW" "+cam_pm_back" +bind "LEFTARROW" "+cam_pm_left" +bind "RIGHTARROW" "+cam_pm_right" +bind "ALT" "+strafe" +bind "CTRL" "+duck" +bind "SHIFT" "+speed" +bind "F5" "snapshot" +bind "F6" "save quick" +bind "F7" "load quick" +bind "F10" "quit" +bind "INS" "+klook" +bind "PGDN" "+cam_pm_down" +bind "PGUP" "+cam_pm_up" +bind "END" "force_centerview" +bind "MWHEELDOWN" "+jump" +bind "MWHEELUP" "+jump" +bind "MOUSE1" "+attack" +bind "MOUSE2" "+attack2" +bind "PAUSE" "pause" +_snd_mixahead "0.1" +ati_npatch "1.0" +bgmvolume "1.000000" +bottomcolor "6" +brightness "1.000000" +cl_allowdownload "1" +cl_allowupload "1" +cl_autowepswitch "1" +cl_backspeed "400" +cl_bob "0.01" +cl_bobtilt "0" +cl_cmdbackup "2" +cl_cmdrate "60" +cl_dlmax "512" +cl_download_ingame "1" +cl_filterstuffcmd "0" +cl_forwardspeed "400" +cl_himodels "0" +cl_idealpitchscale "0.8" +cl_lc "1" +cl_logocolor "#Valve_Orange" +cl_logofile "lambda" +cl_lw "1" +cl_mousegrab "1" +cl_rollangle "2.0" +cl_rollspeed "200" +cl_showfps "0" +cl_smoothtime "0.1" +cl_timeout "60" +cl_updaterate "60" +cl_vsmoothing "0.05" +con_color "255 180 30" +con_mono "0" +console "1.000000" +crosshair "1" +default_fov "90" +ex_interp "0.1" +fps_max "100.0" +fps_override "0" +gamma "2.500000" +gl_ansio "16" +gl_dither "1" +gl_flipmatrix "0" +gl_fog "1" +gl_keeptjunctions "1" +gl_lightholes "1" +gl_lowlatency "0" +gl_lowlatency_debugoutput "0" +gl_lowlatency_maxslop_ms "5" +gl_lowlatency_minslop_ms "2" +gl_max_size "512" +gl_monolights "0" +gl_overbright "0" +gl_picmip "0" +gl_polyoffset "0.1" +gl_round_down "3" +gl_spriteblend "1" +gl_texturemode "GL_LINEAR_MIPMAP_LINEAR" +gl_use_shaders "1" +gl_vsync "1" +gl_wateramp "0" +gl_widescreen_yfov "1" +graphheight "64.0" +hisound "1" +hpk_maxsize "4" +hud_capturemouse "1" +hud_centerid "0" +hud_classautokill "1" +hud_deathnotice_time "6" +hud_draw "1" +hud_fastswitch "0" +hud_takesshots "0" +joystick "1" +lookspring "0.000000" +lookstrafe "0.000000" +m_customaccel "0" +m_customaccel_exponent "1" +m_customaccel_max "0" +m_customaccel_scale "0.04" +m_filter "0" +m_forward "1" +m_pitch "0.022000" +m_rawinput "0" +m_side "0.8" +m_yaw "0.022" +model "gordon" +MP3FadeTime "2.0" +MP3Volume "0.410000" +mp_decals "300" +name "return of the beast coast" +net_graph "0" +net_graphpos "1" +net_scale "5" +r_detailtextures "0" +r_prefertexturefiltering "1" +rate "30000" +room_off "0" +sensitivity "3.000000" +skin "" +sp_decals "4096" +suitvolume "0.250000" +sv_aim "1" +sv_voiceenable "1" +team "" +topcolor "30" +viewsize "120.000000" +violence_ablood "1" +violence_agibs "1" +violence_hblood "1" +violence_hgibs "1" +voice_enable "1" +voice_forcemicrecord "1" +voice_modenable "1" +voice_scale "1" +volume "0.15" +zoom_sensitivity_ratio "1.2" ++mlook ++jlook +exec controller.cfg +exec userconfig.cfg diff --git a/photomode/gfx/shell/kb_act.lst b/photomode/gfx/shell/kb_act.lst new file mode 100755 index 0000000..0abaa6e --- /dev/null +++ b/photomode/gfx/shell/kb_act.lst @@ -0,0 +1,59 @@ +"blank" "==========================" +"blank" "#Valve_Movement_Title" +"blank" "==========================" +"+forward" "#Valve_Move_Forward" +"+back" "#Valve_Move_Back" +"+left" "#Valve_Turn_Left" +"+right" "#Valve_Turn_Right" +"+moveleft" "#Valve_Move_Left" +"+moveright" "#Valve_Move_Right" +"+jump" "#Valve_Jump" +"+duck" "#Valve_Duck" +"+moveup" "#Valve_Swim_Up" +"+movedown" "#Valve_Swim_Down" +"+lookup" "#Valve_Look_Up" +"+lookdown" "#Valve_Look_Down" +"force_centerview" "#Valve_Look_Straight_Ahead" +"+strafe" "#Valve_Strafe_Modifier" +"+mlook" "#Valve_Mouse_Look_Modifier" +"+klook" "#Valve_Keyboard_Look_Modifier" +"+use" "#Valve_Use_Items" +"+cam_pm_forward" "Photo Mode Forward" +"+cam_pm_back" "Photo Mode Back" +"+cam_pm_left" "Photo Mode Left" +"+cam_pm_right" "Photo Mode Right" +"+cam_pm_up" "Photo Mode Up" +"+cam_pm_down" "Photo Mode Down" +"blank" "==========================" +"blank" "#Valve_Communication_Title" +"blank" "==========================" +"+voicerecord" "#Valve_Use_Voice_Communication" +"messagemode" "#Valve_Chat_Message" +"messagemode2" "#Valve_Team_Message" +"blank" "==========================" +"blank" "#Valve_Combat_Title" +"blank" "==========================" +"+attack" "#Valve_Primary_Attack" +"+attack2" "#Valve_Secondary_Attack" +"+reload" "#Valve_Reload_Weapon" +"+speed" "#Valve_Walk" +"impulse 100" "#Valve_Flashlight" +"impulse 201" "#Valve_Spray_Logo" +"slot1" "#Valve_Weapon_Category_1" +"slot2" "#Valve_Weapon_Category_2" +"slot3" "#Valve_Weapon_Category_3" +"slot4" "#Valve_Weapon_Category_4" +"slot5" "#Valve_Weapon_Category_5" +"invprev" "#Valve_Previous_Weapon" +"invnext" "#Valve_Next_Weapon" +"lastinv" "#Valve_Last_Weapon_Used" +"blank" "==========================" +"blank" "#Valve_Miscellaneous_Title" +"blank" "==========================" +"+showscores" "#Valve_Display_Scores" +"snapshot" "#Valve_Take_Screen_Shot" +"save quick" "#Valve_Quick_Save" +"load quick" "#Valve_Quick_Load" +"pause" "#Valve_Pause_Game" +"quit" "#Valve_Quit_Game" +"photomode" "Photo Mode" diff --git a/photomode/gfx/shell/kb_def.lst b/photomode/gfx/shell/kb_def.lst new file mode 100755 index 0000000..fd1ac12 --- /dev/null +++ b/photomode/gfx/shell/kb_def.lst @@ -0,0 +1,54 @@ +"k" "+voicerecord" +"w" "+forward" +"UPARROW" "+cam_pm_forward" +"s" "+back" +"DOWNARROW" "+cam_pm_back" +"LEFTARROW" "+cam_pm_left" +"RIGHTARROW" "+cam_pm_right" +"a" "+moveleft" +"," "+moveleft" +"d" "+moveright" +"." "+moveright" +"SPACE" "+jump" +"CTRL" "+duck" +"TAB" "photomode" +"e" "+use" +"v" "+moveup" +"'" "+moveup" +"c" "+movedown" +"/" "+movedown" +"PGUP" "+cam_pm_up" +"PGDN" "+cam_pm_down" +"END" "force_centerview" +"ALT" "+strafe" +"INS" "+klook" +";" "+mlook" +"r" "+reload" +"SHIFT" "+speed" +"MOUSE1" "+attack" +"ENTER" "+attack" +"MOUSE2" "+attack2" +"\\" "+attack2" +"f" "impulse 100" +"1" "slot1" +"2" "slot2" +"3" "slot3" +"4" "slot4" +"5" "slot5" +"MWHEELUP" "invprev" +"[" "invprev" +"MWHEELDOWN" "invnext" +"]" "invnext" +"q" "lastinv" +"F5" "snapshot" +"F6" "save quick" +"F7" "load quick" +"F10" "quit" +"PAUSE" "pause" +"ESCAPE" "escape" +"~" "toggleconsole" +"`" "toggleconsole" +"t" "impulse 201" +"y" "messagemode" +"u" "messagemode2" +"p" "photomode" diff --git a/photomode/liblist.gam b/photomode/liblist.gam new file mode 100644 index 0000000..c51526f --- /dev/null +++ b/photomode/liblist.gam @@ -0,0 +1,9 @@ +game "Photo Mode" +startmap "c0a0" +trainmap "t0a0" +gamedll "dlls/hl.dll" +gamedll_linux "dlls/hl.so" +secure "1" +type "singleplayer_only" +animated_title "1" +hd_background "1"