Photo mode (#1)

This commit is contained in:
Lauri Räsänen 2024-10-05 20:26:50 +03:00
parent e760b9f988
commit 9cf713fba2
12 changed files with 668 additions and 287 deletions

View file

@ -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

View file

@ -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 );

View file

@ -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();

View file

@ -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<int>(cam_thirdperson || (0 != g_iUser1 && (g_iUser2 == gEngfuncs.GetLocalPlayer()->index)));
// Return true for photo mode so engine draws gordon
return static_cast<int>(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<int>(cam_photomode || (0 != g_iUser1 && (g_iUser2 == gEngfuncs.GetLocalPlayer()->index)));
}
void DLLEXPORT CL_CameraPhotoModeOffset(float* ofs)
{
VectorCopy(cam_pm_ofs, ofs);
}

View file

@ -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);
}

View file

@ -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)

View file

@ -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)

View file

@ -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)

183
photomode/config.cfg Normal file
View file

@ -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

59
photomode/gfx/shell/kb_act.lst Executable file
View file

@ -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"

54
photomode/gfx/shell/kb_def.lst Executable file
View file

@ -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"

9
photomode/liblist.gam Normal file
View file

@ -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"