358 lines
19 KiB
C++
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
|
|
};
|