TUTORIAL 28 - Progressive zooming (à la UT)
by Kilderean
This tutorial will show you how to modify the zooming functions
so that a progressive zoom can be achieved similar to the zooming
in Unreal Tournament.
This is a pretty simple tutorial, so newbies shouldn't have any
problem with the copy-pasting involved. :)
1. Adding some new variables and making some small changes
Open up cg_local.h and at around line ~29 you should see these lines:
#define ITEM_SCALEUP_TIME 1000
#define ZOOM_TIME 150
#define ITEM_BLOB_TIME 200
Make the following changes:
#define ITEM_SCALEUP_TIME 1000
#define ZOOM_TIME 500
#define ZOOM_TIME_OUT 200
#define ITEM_BLOB_TIME 200
What we did is make the zoom in time a little bit longer, 500 milliseconds (half a second),
so that the player can set the zoom more easily. We also added a new define
for the time it takes to come out of zoom, since coming out of zoom needs to be done
faster than zooming in we set it to 200 milliseconds (1/5 of a second).
Next go around line ~421 inside struct cg_t, and find these lines of code:
// zoom key
qboolean zoomed;
int zoomTime;
float zoomSensitivity;
Make the following changes:
// zoom key
qboolean zoomed;
int zoomTime;
float zoomSensitivity;
qboolean zooming;
int setZoomFov;
We will need the zooming boolean to determine if the player is currently zooming in and
the setZoomFov integer to remember the zoom FOV the player sets when he releases his zoom key.
2. Finding and modifying the zoom control functions
First open up cg_view.c and find the 2 zooming functions around line ~423.
You should see the 2 functions called by the +zoom and -zoom button
and they should look like this:
void CG_ZoomDown_f( void ) {
if ( cg.zoomed ) {
return;
}
cg.zoomed = qtrue;
cg.zoomTime = cg.time;
}
void CG_ZoomUp_f( void ) {
if ( !cg.zoomed ) {
return;
}
cg.zoomed = qfalse;
cg.zoomTime = cg.time;
}
Now these functions are pretty straightforward, when you hold down the zoom
button (CG_ZoomDown is called) if you are currently zooming the
function returns, if not it sets the zoomed boolean to true and
sets a timer for the zooming animation. If you release the zooming
button (CG_ZoomUP is called) the function checks if we were zooming,
if not it returns and does nothing, if yes it sets the zoomed boolean
to false and sets a timer for the out of zoom animation.
What we will do is replace these 2 functions entirely so that when we press the
zoom button it starts zooming in but when we release it it stops
and waits for another hit on the zoom button to come out of zoom.
Replace the 2 zoom functions with these:
void CG_ZoomDown_f( void ) {
if ( cg.zoomed && !cg.zooming ) {
cg.zoomed = qfalse;
cg.zoomTime = cg.time;
}
else{
if(cg.zoomed)
return;
cg.zoomed = qtrue;
cg.zooming = qtrue;
cg.zoomTime = cg.time;
}
}
void CG_ZoomUp_f( void ) {
if(cg.zoomed){
cg.zoomTime=0;
cg.zooming=qfalse;
}
}
Lets check out what we just did:
First when someone presses the zoom button we check if
we are currently zoomed in and if we aren't zooming in anymore. If this is the case then
the player was zoomed in on something and he pressed the zoom button to zoom out. We then
set zoomed to false and set the timer for the zooming out animation. If the first condition
is not met, (e.g.:we are not currently zoomed in or we are but we are still zooming in) then
we check we actually aren't zoomed, if we are we return, if not we set the zoom in variables.
Lastly when the player releases the zoom button the only thing we check for is if we are zoomed
on something, if we are we stop the zoom where we are and let it stay there.
3. Modifying the zooming function
Now that we made all the small changes lets modify the function that actually does the zooming. Still
in cg_view.c, go to line ~485 in the CG_CalcFov() function and find the following bit of code:
if ( cg.zoomed ) {
f = ( cg.time - cg.zoomTime ) / (float)ZOOM_TIME;
if ( f > 1.0 ) {
fov_x = zoomFov;
} else {
fov_x = fov_x + f * ( zoomFov - fov_x );
}
} else {
f = ( cg.time - cg.zoomTime ) / (float)ZOOM_TIME;
if ( f > 1.0 ) {
fov_x = fov_x;
} else {
fov_x = zoomFov + f * ( fov_x - zoomFov );
}
}
And replace it with this segment of code:
if ( cg.zoomed ) {
if (cg.zoomTime != 0)
f = ( cg.time - cg.zoomTime ) / (float)ZOOM_TIME;
else
f=-1;
if ( f > 1.0 ) {
fov_x = zoomFov;
cg.setZoomFov = fov_x;
} else {
if(f!=-1){
fov_x = fov_x + f * ( zoomFov - fov_x );
cg.setZoomFov = fov_x;
}
else
fov_x = cg.setZoomFov;
}
} else {
f = ( cg.time - cg.zoomTime ) / (float)ZOOM_TIME_OUT;
if ( f > 1.0 ) {
fov_x = fov_x;
} else {
fov_x = cg.setZoomFov + f * ( fov_x - cg.setZoomFov );
}
}
First what we do here is we check if we are still zooming or if we have stopped zooming in (zoomTime==0).
If we are still zooming in we run the function as it normally would be run. When we stop zooming in we
set the setZoomFov variable to the current fov we have achieved so that when we zoom out we can start
at this fov.
4. Other cool things
You can now adjust the maximum amount of zoom by modifying the cg_zoomFov variable
from the console. If you make it a small value then zoom in and out
moves to useful intermediate positions very quickly.
There are other cool things you can do with the zoom. For instance you can change the crosshair in cg_draw.c and
you can also draw an index to indicate the current magnification of the zoom.
Those things *might* be covered in a future tutorial by me :) so check back on C3A often!
Et voilà! Have fun!
|