Skip to content

Commit

Permalink
Implements and hooks MouseTypeClass, including loading of MOUSE.INI.
Browse files Browse the repository at this point in the history
  • Loading branch information
CCHyper committed Mar 29, 2023
1 parent 9310876 commit 3897f26
Show file tree
Hide file tree
Showing 8 changed files with 860 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/extensions/extension_hooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@

#include "displayext_hooks.h"
#include "sidebarext_hooks.h"
#include "mouseext_hooks.h"

#include "initext_hooks.h"
#include "mainloopext_hooks.h"
Expand Down Expand Up @@ -243,6 +244,7 @@ void Extension_Hooks()

DisplayClassExtension_Hooks();
SidebarClassExtension_Hooks();
MouseClassExtension_Hooks();

/**
* Various modules and functions.
Expand Down
245 changes: 245 additions & 0 deletions src/extensions/mouse/mouseext_hooks.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,245 @@
/*******************************************************************************
/* O P E N S O U R C E -- V I N I F E R A **
/*******************************************************************************
*
* @project Vinifera
*
* @file MOUSEEXT_HOOKS.CPP
*
* @author CCHyper
*
* @brief Contains the hooks for the extended MouseClass.
*
* @license Vinifera 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.
*
* Vinifera is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program.
* If not, see <http://www.gnu.org/licenses/>.
*
******************************************************************************/
#include "mouseext_hooks.h"
#include "mouse.h"
#include "mousetype.h"
#include "vinifera_globals.h"
#include "wwmouse.h"
#include "debughandler.h"
#include "asserthandler.h"

#include "hooker.h"
#include "hooker_macros.h"


/**
* A fake class for implementing new member functions which allow
* access to the "this" pointer of the intended class.
*
* @note: This must not contain a constructor or destructor!
* @note: All functions must be prefixed with "_" to prevent accidental virtualization.
*/
class MouseClassExt final : public MouseClass
{
public:
void _AI(KeyNumType &input, Point2D &xy);
bool _Override_Mouse_Shape(MouseType mouse, bool wsmall = false);
void _Mouse_Small(bool wsmall = true);
int _Get_Mouse_Current_Frame(MouseType mouse, bool wsmall = false) const;
Point2D _Get_Mouse_Hotspot(MouseType mouse) const;
int _Get_Mouse_Start_Frame(MouseType mouse) const;
int _Get_Mouse_Frame_Count(MouseType mouse) const;
};


/**
* Controls the sizing of the mouse.
*
* @author: 09/21/1995 JLB - Red Alert source code.
* CCHyper - Adjustments for Tiberian Sun.
* CCHyper - Change use of MouseControl to MouseTypes.
*/
void MouseClassExt::_Mouse_Small(bool wsmall)
{
//MouseStruct const * control = &MouseControl[CurrentMouseShape];
MouseTypeClass const * control = MouseTypeClass::As_Pointer(CurrentMouseShape);

if (IsSmall == wsmall) {
return;
}

IsSmall = wsmall;

int frame = Get_Mouse_Current_Frame(CurrentMouseShape, wsmall);
Point2D hotspot = Get_Mouse_Hotspot(CurrentMouseShape);

WWMouse->Set_Cursor(&hotspot, MouseShapes, frame);
}


/**
* Alters the shape of the mouse.
*
* @author: 03/10/1994 JLB - Red Alert source code.
* CCHyper - Adjustments for Tiberian Sun.
* CCHyper - Change use of MouseControl to MouseTypes.
*/
bool MouseClassExt::_Override_Mouse_Shape(MouseType mouse, bool wsmall)
{
ASSERT((unsigned)mouse < MOUSE_COUNT);

//MouseStruct const * control = &MouseControl[mouse];
MouseTypeClass const * control = MouseTypeClass::As_Pointer(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) {
wsmall = false;
}

/**
* If the mouse shape is going to change, then inform the mouse driver of the
* change.
*/
if (!startup || (MouseShapes && ((mouse != CurrentMouseShape) || (wsmall != IsSmall)))) {
startup = true;

Timer = control->FrameRate;
Frame = 0;

baseshp = Get_Mouse_Current_Frame(mouse, wsmall);
Point2D hotspot = Get_Mouse_Hotspot(mouse);
WWMouse->Set_Cursor(&hotspot, MouseShapes, baseshp);
CurrentMouseShape = mouse;
IsSmall = wsmall;
return true;
}
return false;
}


/**
* Process player input as it relates to the mouse.
*
* @author: 12/24/1994 JLB - Red Alert source code.
* CCHyper - Adjustments for Tiberian Sun.
* CCHyper - Change use of MouseControl to MouseTypes.
*/
void MouseClassExt::_AI(KeyNumType &input, Point2D &xy)
{
//MouseStruct const * control = &MouseControl[CurrentMouseShape];
MouseTypeClass const * control = MouseTypeClass::As_Pointer(CurrentMouseShape);

if (control->FrameRate && Timer == 0) {

Frame++;
Frame %= control->FrameCount;
Timer = control->FrameRate;
int baseframe = Get_Mouse_Current_Frame(CurrentMouseShape, IsSmall);
Point2D hotspot = Get_Mouse_Hotspot(CurrentMouseShape);
WWMouse->Set_Cursor(&hotspot, MouseShapes, baseframe);
}

ScrollClass::AI(input, xy);
}


/**
* x
*
* @author: CCHyper - Reimplemented from Tiberian Sun.
* CCHyper - Change use of MouseControl to MouseTypes.
*/
int MouseClassExt::_Get_Mouse_Current_Frame(MouseType mouse, bool wsmall) const
{
//MouseStruct const * control = &MouseControl[mouse];
MouseTypeClass const * control = MouseTypeClass::As_Pointer(mouse);

if (wsmall) {
if (control->SmallFrame != -1) {
return control->SmallFrame + Frame;
}
}

return control->StartFrame + Frame;
}


/**
* x
*
* @author: CCHyper - Reimplemented from Tiberian Sun.
* CCHyper - Change use of MouseControl to MouseTypes.
*/
Point2D MouseClassExt::_Get_Mouse_Hotspot(MouseType mouse) const
{
Point2D hotspot(0,0);

//MouseStruct const * control = &MouseControl[mouse];
MouseTypeClass const * control = MouseTypeClass::As_Pointer(mouse);

int hotspot_x = control->Hotspot.X;
if (hotspot_x == MOUSE_HOTSPOT_CENTER) {
hotspot.X = MouseShapes->Get_Width() / 2;
}
if (hotspot_x == MOUSE_HOTSPOT_MAX) {
hotspot.X = MouseShapes->Get_Width();
}

int hotspot_y = control->Hotspot.Y;
if (hotspot_y == MOUSE_HOTSPOT_CENTER) {
hotspot.Y = MouseShapes->Get_Height() / 2;
}
if (hotspot_y == MOUSE_HOTSPOT_MAX) {
hotspot.Y = MouseShapes->Get_Height();
}

return hotspot;
}


/**
* Returns the starting frame of the mouse.
*
* @author: CCHyper - Reimplemented from Tiberian Sun.
* CCHyper - Change use of MouseControl to MouseTypes.
*/
int MouseClassExt::_Get_Mouse_Start_Frame(MouseType mouse) const
{
//return MouseControl[mouse].StartFrame;
return MouseTypeClass::As_Pointer(mouse)->StartFrame;
}


/**
* Returns the frame count of the mouse.
*
* @author: CCHyper - Reimplemented from Tiberian Sun.
* CCHyper - Change use of MouseControl to MouseTypes.
*/
int MouseClassExt::_Get_Mouse_Frame_Count(MouseType mouse) const
{
//return MouseControl[mouse].FrameCount;
return MouseTypeClass::As_Pointer(mouse)->FrameCount;
}


void MouseClassExtension_Hooks()
{
Patch_Jump(0x00562200, &MouseClassExt::_Mouse_Small);
Patch_Jump(0x005622D0, &MouseClassExt::_Get_Mouse_Current_Frame);
Patch_Jump(0x00562310, &MouseClassExt::_Get_Mouse_Hotspot);
Patch_Jump(0x00562390, &MouseClassExt::_Override_Mouse_Shape);
Patch_Jump(0x005624D0, &MouseClassExt::_AI);
Patch_Jump(0x00563220, &MouseClassExt::_Get_Mouse_Start_Frame);
Patch_Jump(0x00563240, &MouseClassExt::_Get_Mouse_Frame_Count);
}
31 changes: 31 additions & 0 deletions src/extensions/mouse/mouseext_hooks.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*******************************************************************************
/* O P E N S O U R C E -- V I N I F E R A **
/*******************************************************************************
*
* @project Vinifera
*
* @file MOUSEEXT_HOOKS.H
*
* @author CCHyper
*
* @brief Contains the hooks for the extended MouseClass.
*
* @license Vinifera 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.
*
* Vinifera is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program.
* If not, see <http://www.gnu.org/licenses/>.
*
******************************************************************************/
#pragma once


void MouseClassExtension_Hooks();
Loading

0 comments on commit 3897f26

Please sign in to comment.