CnC_Remastered_Collection/TIBERIANDAWN/MOUSE.CPP
PG-SteveT 03416d24e1 Initial Source Code commit
Initial commit of original Tiberian Dawn and Red Alert source code converted to build as DLLs, and compatible with the release version of Command & Conquer Remastered.
2020-05-27 12:16:20 -07:00

358 lines
19 KiB
C++

//
// Copyright 2020 Electronic Arts Inc.
//
// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free
// software: you can redistribute it and/or modify it under the terms of
// the GNU General Public License as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed
// in the hope that it will be useful, but with permitted additional restrictions
// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
// distributed with this program. You should have received a copy of the
// GNU General Public License along with permitted additional restrictions
// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
/* $Header: F:\projects\c&c\vcs\code\mouse.cpv 2.18 16 Oct 1995 16:49:56 JOE_BOSTIC $ */
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Command & Conquer *
* *
* File Name : MOUSE.CPP *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : 12/15/94 *
* *
* Last Update : June 30, 1995 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* MouseClass::AI -- Process player input as it relates to the mouse *
* MouseClass::Override_Mouse_Shape -- Alters the shape of the mouse. *
* MouseClass::Init_Clear -- Sets the mouse system to a known state *
* MouseClass::MouseClass -- Default constructor for the mouse handler class. *
* MouseClass::One_Time -- Performs the one time initialization of the mouse system. *
* MouseClass::Set_Default_Mouse -- Sets the mouse to match the shape specified. *
* MouseClass::Revert_Mouse_Shape -- Reverts the mouse shape to the non overridden shape. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "function.h"
/*
** This points to the loaded mouse shapes.
*/
void const * MouseClass::MouseShapes;
/*
** This is the timer that controls the mouse animation. It is always at a fixed
** rate so it uses the constant system timer.
*/
CountDownTimerClass MouseClass::Timer;
/*
** This contains the value of the Virtual Function Table Pointer
*/
void * MouseClass::VTable;
/***********************************************************************************************
* MouseClass::Set_Default_Mouse -- Sets the mouse to match the shape specified. *
* *
* This routine is used to inform the display system as to which mouse shape is desired. *
* *
* INPUT: mouse -- The mouse shape number to set the mouse to. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 09/19/1994 JLB : Created. *
*=============================================================================================*/
void MouseClass::Set_Default_Mouse(MouseType mouse, bool size)
{
NormalMouseShape = mouse;
Override_Mouse_Shape(mouse, size);
}
/***********************************************************************************************
* MouseClass::Revert_Mouse_Shape -- Reverts the mouse shape to the non overridden shape. *
* *
* Use this routine to cancel the effects of Override_Mouse_Shape(). It will revert the *
* mouse back to the original shape. *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 03/27/1995 JLB : Created. *
*=============================================================================================*/
void MouseClass::Revert_Mouse_Shape(void)
{
Override_Mouse_Shape(NormalMouseShape, false);
}
void MouseClass::Mouse_Small(bool wwsmall)
{
MouseStruct const * control = &MouseControl[CurrentMouseShape];
if (IsSmall == wwsmall) {
return;
}
IsSmall = wwsmall;
if (wwsmall) {
if (control->SmallFrame != -1) {
Set_Mouse_Cursor(control->X, control->Y, Extract_Shape(MouseShapes, control->SmallFrame + Frame/4));
} else {
Set_Mouse_Cursor(MouseControl[MOUSE_NORMAL].X, MouseControl[MOUSE_NORMAL].Y, Extract_Shape(MouseShapes, MOUSE_NORMAL));
}
} else {
Set_Mouse_Cursor(control->X, control->Y, Extract_Shape(MouseShapes, control->StartFrame + Frame/4));
}
}
/***********************************************************************************************
* MouseClass::Override_Mouse_Shape -- Alters the shape of the mouse. *
* *
* This routine is used to alter the shape of the mouse as needed. *
* Typical mouse shape change occurs when scrolling the map or *
* selecting targets. *
* *
* INPUT: mouse -- The mouse shape number to use. *
* *
* OUTPUT: bool; Was the mouse shape changed? *
* *
* WARNINGS: This is not intended to be used as a means to hide the *
* mouse. Nor will it work correctly if the mouse shape *
* file hasn't been loaded. *
* *
* HISTORY: *
* 03/10/1994 JLB : Created. *
* 06/03/1994 JLB : Made into member function. *
* 12/24/1994 JLB : Added small control parameter. *
*=============================================================================================*/
bool MouseClass::Override_Mouse_Shape(MouseType mouse, bool wwsmall)
{
MouseStruct const * control = &MouseControl[mouse];
static bool startup = false;
int baseshp;
/*
** Only certain mouse shapes have a small counterpart. If the requested mouse
** shape is not one of these, then force the small size override flag to false.
*/
if (control->SmallFrame == -1) {
wwsmall = false;
}
/*
** If the mouse shape is going to change, then inform the mouse driver of the
** change.
*/
if (!startup || (MouseShapes && ((mouse != CurrentMouseShape) || (wwsmall != IsSmall)))) {
startup = true;
Timer.Set(control->FrameRate);
Frame = 0;
#ifdef OBSOLETE
Control.Set_Stage(0);
int rate = Options.Normalize_Delay(control->FrameRate);
Control.Set_Rate(MAX(rate, 1));
#endif
baseshp = (wwsmall) ? control->SmallFrame : control->StartFrame;
Set_Mouse_Cursor(control->X, control->Y, Extract_Shape(MouseShapes, baseshp + Frame/4));
CurrentMouseShape = mouse;
IsSmall = wwsmall;
return(true);
}
return(false);
}
/***********************************************************************************************
* MouseClass::AI -- Process player input as it relates to the mouse *
* *
* This routine will is to be called once per game tick and is passed the player keyboard *
* or mouse input code. It processes this code and updates the mouse shape as appropriate. *
* *
* INPUT: input -- The player input code as returned from Keyboard::Get(). *
* *
* x,y -- The mouse coordinate values to use. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 12/24/1994 JLB : Created. *
* 12/31/1994 JLB : Uses mouse coordinate parameters. *
* 03/27/1995 JLB : New animation control. *
* 05/28/1995 JLB : Moderates animation so is more steady regardless of speed. *
* 06/30/1995 JLB : Uses constant timer system. *
*=============================================================================================*/
void MouseClass::AI(KeyNumType &input, int x, int y)
{
// bool doit = false;
void *mouse_shape_ptr;
MouseStruct const * control = &MouseControl[CurrentMouseShape];
if (control->FrameRate && Timer.Time() == 0) {
Frame++;
Frame %= control->FrameCount;
Timer.Set(control->FrameRate);
#ifdef OBSOLETE
Control.Set_Stage(Control.Fetch_Stage() % control->FrameCount);
#endif
if (!IsSmall || control->SmallFrame != -1) {
int baseframe = (IsSmall) ? control->SmallFrame : control->StartFrame;
mouse_shape_ptr = Extract_Shape(MouseShapes, baseframe + Frame);
if (mouse_shape_ptr){
Set_Mouse_Cursor(control->X, control->Y, mouse_shape_ptr);
}
}
}
ScrollClass::AI(input, x, y);
}
/***********************************************************************************************
* MouseClass::MouseClass -- Default constructor for the mouse handler class. *
* *
* This is the default constructor for the mouse handling class. It merely sets up the *
* mouse system to its default state. *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 12/24/1994 JLB : Created. *
*=============================================================================================*/
MouseClass::MouseClass(void)
{
CurrentMouseShape = MOUSE_NORMAL;
NormalMouseShape = MOUSE_NORMAL;
Timer.Start();
}
/***********************************************************************************************
* MouseClass::One_Time -- Performs the one time initialization of the mouse system. *
* *
* Use this routine to load the mouse data file and perform any other necessary one time *
* preparations for the game. *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: Only call this routine ONCE. *
* *
* HISTORY: *
* 12/24/1994 JLB : Created. *
*=============================================================================================*/
void MouseClass::One_Time(void)
{
ScrollClass::One_Time();
/*
** Override the mouse shape file with the one in the current directory, but only if there
** is an override file available.
*/
RawFileClass file("MOUSE.SHP");
if (file.Is_Available()) {
MouseShapes = Load_Alloc_Data(file);
} else {
MouseShapes = MixFileClass::Retrieve("MOUSE.SHP");
}
VTable = ((void **)(((char *)this) + sizeof(VectorClass<CellClass>) - 4))[0];
}
/***********************************************************************************************
* MouseClass::Init_Clear -- Sets the mouse system to a known state *
* *
* This routine will reset the mouse handling system. Typically, this routine is called *
* when preparing for the beginning of a new scenario. *
* *
* INPUT: theater -- The theater that the scenario will take place. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 12/24/1994 JLB : Created. *
*=============================================================================================*/
void MouseClass::Init_Clear(void)
{
ScrollClass::Init_Clear();
IsSmall = false;
NormalMouseShape = MOUSE_NORMAL;
}
/*
** This array of structures is used to control the mouse animation
** sequences.
*/
MouseClass::MouseStruct MouseClass::MouseControl[MOUSE_COUNT] = {
{0, 1, 0, 86, 0, 0}, // MOUSE_NORMAL
{1, 1, 0, -1, 15, 0}, // MOUSE_N
{2, 1, 0, -1, 29, 0}, // MOUSE_NE
{3, 1, 0, -1, 29, 12}, // MOUSE_E
{4, 1, 0, -1, 29, 23}, // MOUSE_SE
{5, 1, 0, -1, 15, 23}, // MOUSE_S
{6, 1, 0, -1, 0, 23}, // MOUSE_SW
{7, 1, 0, -1, 0, 13}, // MOUSE_W
{8, 1, 0, -1, 0, 0}, // MOUSE_NW
{130, 1, 0, -1, 15, 0}, // MOUSE_NO_N
{131, 1, 0, -1, 29, 0}, // MOUSE_NO_NE
{132, 1, 0, -1, 29, 12}, // MOUSE_NO_E
{133, 1, 0, -1, 29, 23}, // MOUSE_NO_SE
{134, 1, 0, -1, 15, 23}, // MOUSE_NO_S
{135, 1, 0, -1, 0, 23}, // MOUSE_NO_SW
{136, 1, 0, -1, 0, 13}, // MOUSE_NO_W
{137, 1, 0, -1, 0, 0}, // MOUSE_NO_NW
{11, 1, 0, 27, 15, 12}, // MOUSE_NO_MOVE
{10, 1, 0, 26, 15, 12}, // MOUSE_CAN_MOVE
{119, 3, 4, 148, 15, 12}, // MOUSE_ENTER
{53, 9, 4, -1, 15, 12}, // MOUSE_DEPLOY
{12, 6, 4, -1, 15, 12}, // MOUSE_CAN_SELECT
{18, 8, 4, 140, 15, 12}, // MOUSE_CAN_ATTACK
{62, 24, 2, -1, 15, 12}, // MOUSE_SELL_BACK
{154, 24, 2, -1, 15, 12}, // MOUSE_SELL_UNIT
{29, 24, 2, -1, 15, 12}, // MOUSE_REPAIR
{126, 1, 0, -1, 15, 12}, // MOUSE_NO_REPAIR
{125, 1, 0, -1, 15, 12}, // MOUSE_NO_SELL_BACK
{87, 1, 0, 151, 0, 0}, // MOUSE_RADAR_CURSOR
{103, 16, 2, -1, 15, 12}, // MOUSE_ION_CANNON
{96, 7, 4, -1, 15, 12}, // MOUSE_NUCLEAR_BOMB
{88, 8, 2, -1, 15, 12}, // MOUSE_AIR_STRIKE
{122, 3, 4, 127, 15, 12}, // MOUSE_DEMOLITIONS
{153, 1, 0, 152, 15, 12}, // MOUSE_AREA_GUARD
};