mirror of
https://github.com/jmarshall23/CnC_Remastered_Collection.git
synced 2026-08-19 17:44:13 +02:00
Initial mouse code(mouse graphics driver from Chronoshift). Very buggy.
This commit is contained in:
@@ -535,6 +535,8 @@ KeyNumType GadgetClass::Input(void)
|
|||||||
// jmarshall
|
// jmarshall
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
WWSDL_ProcessEvents(key, flags);
|
WWSDL_ProcessEvents(key, flags);
|
||||||
|
|
||||||
|
Show_Mouse(); // jmarshall: thsi shouldn't be here!
|
||||||
// jmarshall end
|
// jmarshall end
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -275,6 +275,8 @@ void GScreenClass::Input(KeyNumType & key, int & x, int & y)
|
|||||||
x = Keyboard->Mouse_X();
|
x = Keyboard->Mouse_X();
|
||||||
y = Keyboard->Mouse_Y();
|
y = Keyboard->Mouse_Y();
|
||||||
|
|
||||||
|
Show_Mouse();
|
||||||
|
|
||||||
if (Buttons != NULL) {
|
if (Buttons != NULL) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
+2
-2
@@ -672,7 +672,7 @@ bool Select_Game(bool fade)
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
Set_Logic_Page(SeenBuff);
|
Set_Logic_Page(SeenBuff);
|
||||||
display = false;
|
// display = false;
|
||||||
Show_Mouse();
|
Show_Mouse();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -3387,7 +3387,7 @@ static void Init_Mouse(void)
|
|||||||
** to set one of our own.
|
** to set one of our own.
|
||||||
*/
|
*/
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
// ShowCursor(false);
|
ShowCursor(false);
|
||||||
#endif
|
#endif
|
||||||
if (MouseInstalled) {
|
if (MouseInstalled) {
|
||||||
void const * temp_mouse_shapes = MFCD::Retrieve("MOUSE.SHP");
|
void const * temp_mouse_shapes = MFCD::Retrieve("MOUSE.SHP");
|
||||||
|
|||||||
+1
-1
@@ -274,7 +274,7 @@ int WWMessageBox::Process(const char * msg, const char * b1txt, const char * b2t
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (display) {
|
if (display) {
|
||||||
display = false;
|
//display = false;
|
||||||
|
|
||||||
Hide_Mouse();
|
Hide_Mouse();
|
||||||
Dialog_Box(x, y, width, height);
|
Dialog_Box(x, y, width, height);
|
||||||
|
|||||||
@@ -449,6 +449,7 @@
|
|||||||
<ClCompile Include="Win32Lib\IRANDOM.CPP" />
|
<ClCompile Include="Win32Lib\IRANDOM.CPP" />
|
||||||
<ClCompile Include="Win32Lib\LOAD.CPP" />
|
<ClCompile Include="Win32Lib\LOAD.CPP" />
|
||||||
<ClCompile Include="Win32Lib\LOADFONT.CPP" />
|
<ClCompile Include="Win32Lib\LOADFONT.CPP" />
|
||||||
|
<ClCompile Include="WIN32LIB\MouseShape.cpp" />
|
||||||
<ClCompile Include="Win32Lib\MOUSEWW.CPP" />
|
<ClCompile Include="Win32Lib\MOUSEWW.CPP" />
|
||||||
<ClCompile Include="Win32Lib\PALETTE.CPP" />
|
<ClCompile Include="Win32Lib\PALETTE.CPP" />
|
||||||
<ClCompile Include="Win32Lib\SET_FONT.CPP" />
|
<ClCompile Include="Win32Lib\SET_FONT.CPP" />
|
||||||
@@ -739,6 +740,7 @@
|
|||||||
<ClInclude Include="Win32Lib\MODEMREG.H" />
|
<ClInclude Include="Win32Lib\MODEMREG.H" />
|
||||||
<ClInclude Include="Win32Lib\MONO.H" />
|
<ClInclude Include="Win32Lib\MONO.H" />
|
||||||
<ClInclude Include="Win32Lib\MOUSE.H" />
|
<ClInclude Include="Win32Lib\MOUSE.H" />
|
||||||
|
<ClInclude Include="WIN32LIB\MouseShape.h" />
|
||||||
<ClInclude Include="Win32Lib\PALETTE.H" />
|
<ClInclude Include="Win32Lib\PALETTE.H" />
|
||||||
<ClInclude Include="Win32Lib\PLAYCD.H" />
|
<ClInclude Include="Win32Lib\PLAYCD.H" />
|
||||||
<ClInclude Include="Win32Lib\PROFILE.H" />
|
<ClInclude Include="Win32Lib\PROFILE.H" />
|
||||||
|
|||||||
@@ -942,6 +942,9 @@
|
|||||||
<ClCompile Include="WIN32LIB\WSA.CPP">
|
<ClCompile Include="WIN32LIB\WSA.CPP">
|
||||||
<Filter>Source Files\win32lib</Filter>
|
<Filter>Source Files\win32lib</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="WIN32LIB\MouseShape.cpp">
|
||||||
|
<Filter>Source Files\win32lib</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="ABSTRACT.H">
|
<ClInclude Include="ABSTRACT.H">
|
||||||
@@ -1838,6 +1841,9 @@
|
|||||||
<ClInclude Include="..\external\libsmacker\smk_malloc.h">
|
<ClInclude Include="..\external\libsmacker\smk_malloc.h">
|
||||||
<Filter>Source Files\libsmacker</Filter>
|
<Filter>Source Files\libsmacker</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="WIN32LIB\MouseShape.h">
|
||||||
|
<Filter>Source Files\win32lib</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="COORDA.ASM">
|
<None Include="COORDA.ASM">
|
||||||
|
|||||||
@@ -527,12 +527,12 @@ int Fetch_Difficulty(void)
|
|||||||
** Main Processing Loop.
|
** Main Processing Loop.
|
||||||
*/
|
*/
|
||||||
Set_Logic_Page(SeenBuff);
|
Set_Logic_Page(SeenBuff);
|
||||||
bool redraw = true;
|
//bool redraw = true;
|
||||||
bool process = true;
|
bool process = true;
|
||||||
while (process) {
|
while (process) {
|
||||||
|
|
||||||
if (redraw) {
|
{
|
||||||
redraw = false;
|
// redraw = false;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Draw the background of the dialog.
|
** Draw the background of the dialog.
|
||||||
@@ -575,7 +575,7 @@ int Fetch_Difficulty(void)
|
|||||||
*/
|
*/
|
||||||
if (AllSurfaces.SurfacesRestored) {
|
if (AllSurfaces.SurfacesRestored) {
|
||||||
AllSurfaces.SurfacesRestored=FALSE;
|
AllSurfaces.SurfacesRestored=FALSE;
|
||||||
redraw = true;
|
//redraw = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#endif //WIN32
|
#endif //WIN32
|
||||||
|
|||||||
@@ -60,6 +60,24 @@ class WWMouseClass {
|
|||||||
void Set_Cursor_Clip(void);
|
void Set_Cursor_Clip(void);
|
||||||
void Clear_Cursor_Clip(void);
|
void Clear_Cursor_Clip(void);
|
||||||
|
|
||||||
|
// jmarshall - accessor functions to hook up mouse code from chronoshift.
|
||||||
|
int Get_Hotspot_X(void) { return MouseXHot; }
|
||||||
|
int Get_Hotspot_Y(void) { return MouseYHot; }
|
||||||
|
int Get_Cursor_Width(void) { return CursorWidth; }
|
||||||
|
int Get_Cursor_Height(void) { return CursorHeight; }
|
||||||
|
int Get_Max_Width(void) { return MaxWidth; }
|
||||||
|
int Get_Max_Height(void) { return MaxHeight; }
|
||||||
|
void Set_Hotspot_X(int hotspotX) { MouseXHot = hotspotX; }
|
||||||
|
void Set_Hotspot_Y(int hotspotY) { MouseYHot = hotspotY; }
|
||||||
|
void Set_Cursor_Width(int width) { CursorWidth = width; }
|
||||||
|
void Set_Cursor_Height(int height) { CursorHeight = height; }
|
||||||
|
void Set_Max_Width(int width) { MaxWidth = width; }
|
||||||
|
void Set_Max_Height(int height) { MaxHeight = height; }
|
||||||
|
|
||||||
|
char* Get_Image_Buff(void) { return MouseCursor; }
|
||||||
|
void* Get_Frame_Pointer() { return PrevCursor; }
|
||||||
|
void Set_Frame_Pointer(void* frame) { PrevCursor = (char *)frame; }
|
||||||
|
// jmarshall end
|
||||||
private:
|
private:
|
||||||
enum {
|
enum {
|
||||||
CONDHIDE = 1,
|
CONDHIDE = 1,
|
||||||
@@ -105,11 +123,9 @@ class WWMouseClass {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern "C" {
|
void __cdecl Mouse_Shadow_Buffer(WWMouseClass& mouse, GraphicViewPortClass& viewport, void* buffer, int x_pos, int y_pos, int hspot_x, int hspot_y, BOOL save);
|
||||||
void __cdecl Mouse_Shadow_Buffer(void *thisptr, GraphicViewPortClass *srcdst, void *buffer, int x, int y, int hotx, int hoty, int store);
|
void __cdecl Mouse_Draw(WWMouseClass& mouse, GraphicViewPortClass& viewport, int x_pos, int y_pos);
|
||||||
void __cdecl Draw_Mouse(void *thisptr, GraphicViewPortClass *srcdst, int x, int y);
|
void* __cdecl Mouse_Set_Cursor(WWMouseClass& mouse, int hspot_x, int hspot_y, void* frame);
|
||||||
void * __cdecl ASM_Set_Mouse_Cursor(void * thisptr, int hotspotx, int hotspoty, VOID *cursor);
|
|
||||||
};
|
|
||||||
|
|
||||||
void Hide_Mouse(void);
|
void Hide_Mouse(void);
|
||||||
void Show_Mouse(void);
|
void Show_Mouse(void);
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ static WWMouseClass *_Mouse=NULL;
|
|||||||
void CALLBACK Process_Mouse( UINT event_id, UINT res1 , DWORD user, DWORD res2, DWORD res3 );
|
void CALLBACK Process_Mouse( UINT event_id, UINT res1 , DWORD user, DWORD res2, DWORD res3 );
|
||||||
extern bool GameInFocus;
|
extern bool GameInFocus;
|
||||||
|
|
||||||
|
extern int mousex, mousey;
|
||||||
|
|
||||||
/***********************************************************************************************
|
/***********************************************************************************************
|
||||||
* MOUSECLASS::MOUSECLASS -- Constructor for the Mouse Class *
|
* MOUSECLASS::MOUSECLASS -- Constructor for the Mouse Class *
|
||||||
@@ -184,9 +185,6 @@ void WWMouseClass::Clear_Cursor_Clip(void)
|
|||||||
|
|
||||||
void WWMouseClass::Process_Mouse(void)
|
void WWMouseClass::Process_Mouse(void)
|
||||||
{
|
{
|
||||||
//ST - 1/3/2019 10:50AM
|
|
||||||
return;
|
|
||||||
#if (0)
|
|
||||||
POINT pt; // define a structure to hold current cursor pos
|
POINT pt; // define a structure to hold current cursor pos
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -255,19 +253,10 @@ void WWMouseClass::Process_Mouse(void)
|
|||||||
// Allow other threads to lock the screen again
|
// Allow other threads to lock the screen again
|
||||||
//
|
//
|
||||||
//Unblock_Mouse(Screen->Get_Graphic_Buffer());
|
//Unblock_Mouse(Screen->Get_Graphic_Buffer());
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void *WWMouseClass::Set_Cursor(int xhotspot, int yhotspot, void *cursor)
|
void *WWMouseClass::Set_Cursor(int xhotspot, int yhotspot, void *cursor)
|
||||||
{
|
{
|
||||||
//ST - 1/3/2019 10:50AM
|
|
||||||
xhotspot;
|
|
||||||
yhotspot;
|
|
||||||
cursor;
|
|
||||||
return cursor;
|
|
||||||
|
|
||||||
#if (0)
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// If the pointer to the cursor we got is invalid, or its the same as the
|
// If the pointer to the cursor we got is invalid, or its the same as the
|
||||||
// currently set cursor then just return.
|
// currently set cursor then just return.
|
||||||
@@ -287,7 +276,7 @@ void *WWMouseClass::Set_Cursor(int xhotspot, int yhotspot, void *cursor)
|
|||||||
// Now convert the shape to a mouse cursor with the given hotspots and
|
// Now convert the shape to a mouse cursor with the given hotspots and
|
||||||
// set it as our current mouse.
|
// set it as our current mouse.
|
||||||
//
|
//
|
||||||
void *retval = ASM_Set_Mouse_Cursor(this, xhotspot, yhotspot, cursor);
|
void *retval = Mouse_Set_Cursor(*this, xhotspot, yhotspot, cursor);
|
||||||
//
|
//
|
||||||
// Show the mouse which will force it to appear with the new shape we
|
// Show the mouse which will force it to appear with the new shape we
|
||||||
// have assigned.
|
// have assigned.
|
||||||
@@ -302,24 +291,21 @@ void *WWMouseClass::Set_Cursor(int xhotspot, int yhotspot, void *cursor)
|
|||||||
// Asm_Set_Mouse_Cursor.
|
// Asm_Set_Mouse_Cursor.
|
||||||
//
|
//
|
||||||
return(retval);
|
return(retval);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WWMouseClass::Low_Hide_Mouse()
|
void WWMouseClass::Low_Hide_Mouse()
|
||||||
{
|
{
|
||||||
//ST - 1/3/2019 10:50AM
|
|
||||||
#if (0)
|
|
||||||
if (!State) {
|
if (!State) {
|
||||||
if (MouseBuffX != -1 || MouseBuffY != -1) {
|
if (MouseBuffX != -1 || MouseBuffY != -1) {
|
||||||
if (Screen->Lock()){
|
if (Screen->Lock()){
|
||||||
Mouse_Shadow_Buffer(this, Screen, MouseBuffer, MouseBuffX, MouseBuffY, MouseXHot, MouseYHot, 0);
|
Mouse_Shadow_Buffer(*this, *Screen, MouseBuffer, MouseBuffX, MouseBuffY, MouseXHot, MouseYHot, 0);
|
||||||
Screen->Unlock();
|
Screen->Unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MouseBuffX = -1;
|
MouseBuffX = -1;
|
||||||
MouseBuffY = -1;
|
MouseBuffY = -1;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
State++;
|
State++;
|
||||||
}
|
}
|
||||||
void WWMouseClass::Hide_Mouse()
|
void WWMouseClass::Hide_Mouse()
|
||||||
@@ -332,23 +318,11 @@ void WWMouseClass::Hide_Mouse()
|
|||||||
|
|
||||||
void WWMouseClass::Low_Show_Mouse(int x, int y)
|
void WWMouseClass::Low_Show_Mouse(int x, int y)
|
||||||
{
|
{
|
||||||
//
|
|
||||||
// If the mouse is already visible then just ignore the problem.
|
|
||||||
//
|
|
||||||
if (State == 0) return;
|
|
||||||
//
|
|
||||||
// Make the mouse a little bit more visible
|
|
||||||
//
|
|
||||||
State--;
|
|
||||||
|
|
||||||
//ST - 1/3/2019 10:50AM
|
|
||||||
#if (0)
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// If the mouse is completely visible then draw it at its current
|
// If the mouse is completely visible then draw it at its current
|
||||||
// position.
|
// position.
|
||||||
//
|
//
|
||||||
if (!State) {
|
{
|
||||||
//
|
//
|
||||||
// Try to lock the screen til we sucessfully get a lock.
|
// Try to lock the screen til we sucessfully get a lock.
|
||||||
//
|
//
|
||||||
@@ -356,11 +330,11 @@ void WWMouseClass::Low_Show_Mouse(int x, int y)
|
|||||||
//
|
//
|
||||||
// Save off the area behind the mouse.
|
// Save off the area behind the mouse.
|
||||||
//
|
//
|
||||||
Mouse_Shadow_Buffer(this, Screen, MouseBuffer, x, y, MouseXHot, MouseYHot, 1);
|
Mouse_Shadow_Buffer(*this, *Screen, MouseBuffer, x, y, MouseXHot, MouseYHot, 1);
|
||||||
//
|
//
|
||||||
// Draw the mouse in its new location
|
// Draw the mouse in its new location
|
||||||
//
|
//
|
||||||
::Draw_Mouse(this, Screen, x, y);
|
Mouse_Draw(*this, *Screen, x, y);
|
||||||
//
|
//
|
||||||
// Save off the positions that we saved the buffer from
|
// Save off the positions that we saved the buffer from
|
||||||
//
|
//
|
||||||
@@ -372,17 +346,16 @@ void WWMouseClass::Low_Show_Mouse(int x, int y)
|
|||||||
Screen->Unlock();
|
Screen->Unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WWMouseClass::Show_Mouse()
|
void WWMouseClass::Show_Mouse()
|
||||||
{
|
{
|
||||||
POINT pt;
|
//POINT pt;
|
||||||
GetCursorPos(&pt);
|
//GetCursorPos(&pt);
|
||||||
|
//
|
||||||
MouseUpdate++;
|
//MouseUpdate++;
|
||||||
Low_Show_Mouse(pt.x, pt.y);
|
Low_Show_Mouse(mousex, mousey);
|
||||||
MouseUpdate--;
|
//MouseUpdate--;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WWMouseClass::Conditional_Hide_Mouse(int x1, int y1, int x2, int y2)
|
void WWMouseClass::Conditional_Hide_Mouse(int x1, int y1, int x2, int y2)
|
||||||
@@ -589,7 +562,7 @@ void WWMouseClass::Erase_Mouse(GraphicViewPortClass *scr, int forced)
|
|||||||
|
|
||||||
int WWMouseClass::Get_Mouse_State(void)
|
int WWMouseClass::Get_Mouse_State(void)
|
||||||
{
|
{
|
||||||
return(State);
|
return 0;//(State);
|
||||||
}
|
}
|
||||||
/***********************************************************************************************
|
/***********************************************************************************************
|
||||||
* WWKeyboardClass::Get_Mouse_X -- Returns the mouses current x position in pixels *
|
* WWKeyboardClass::Get_Mouse_X -- Returns the mouses current x position in pixels *
|
||||||
@@ -603,9 +576,7 @@ int WWMouseClass::Get_Mouse_State(void)
|
|||||||
*=============================================================================================*/
|
*=============================================================================================*/
|
||||||
int WWMouseClass::Get_Mouse_X(void)
|
int WWMouseClass::Get_Mouse_X(void)
|
||||||
{
|
{
|
||||||
POINT pt;
|
return mousex;
|
||||||
GetCursorPos(&pt);
|
|
||||||
return(pt.x);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -621,9 +592,7 @@ int WWMouseClass::Get_Mouse_X(void)
|
|||||||
*=============================================================================================*/
|
*=============================================================================================*/
|
||||||
int WWMouseClass::Get_Mouse_Y(void)
|
int WWMouseClass::Get_Mouse_Y(void)
|
||||||
{
|
{
|
||||||
POINT pt;
|
return mousey;
|
||||||
GetCursorPos(&pt);
|
|
||||||
return(pt.y);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************************************
|
/***********************************************************************************************
|
||||||
@@ -638,12 +607,9 @@ int WWMouseClass::Get_Mouse_Y(void)
|
|||||||
* 10/17/1995 PWG : Created. *
|
* 10/17/1995 PWG : Created. *
|
||||||
*=============================================================================================*/
|
*=============================================================================================*/
|
||||||
void WWMouseClass::Get_Mouse_XY(int &x, int &y)
|
void WWMouseClass::Get_Mouse_XY(int &x, int &y)
|
||||||
{
|
{
|
||||||
POINT pt;
|
x = mousex;
|
||||||
|
y = mousey;
|
||||||
GetCursorPos(&pt);
|
|
||||||
x = pt.x;
|
|
||||||
y = pt.y;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//#pragma off(unreferenced)
|
//#pragma off(unreferenced)
|
||||||
|
|||||||
@@ -0,0 +1,304 @@
|
|||||||
|
/**
|
||||||
|
* @file
|
||||||
|
*
|
||||||
|
* @author OmniBlade
|
||||||
|
* @author CCHyper
|
||||||
|
*
|
||||||
|
* @brief Low level sprite drawing functions for Dune2 sprite format (used for mouse in early C&C games).
|
||||||
|
*
|
||||||
|
* @copyright Chronoshift 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
|
||||||
|
* 2 of the License, or (at your option) any later version.
|
||||||
|
* A full copy of the GNU General Public License can be found in
|
||||||
|
* LICENSE
|
||||||
|
*/
|
||||||
|
#include "../FUNCTION.H"
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "mouse.h"
|
||||||
|
#include "mouseshape.h"
|
||||||
|
#include "gbuffer.h"
|
||||||
|
//#include "lcw.h"
|
||||||
|
#include <cstring>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#define MIN(a,b) (((a)<(b))?(a):(b))
|
||||||
|
#define MAX(a,b) (((a)>(b))?(a):(b))
|
||||||
|
|
||||||
|
using std::memcpy;
|
||||||
|
|
||||||
|
uint8_t g_mouseShapeBuffer[65000]; // Original code shares the global ShapeBuffer with other sprite drawing.
|
||||||
|
|
||||||
|
int Get_Shape_Uncomp_Size(void* shape)
|
||||||
|
{
|
||||||
|
return static_cast<MouseShapeFrameHeader*>(shape)->data_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Extract_Shape_Count(void* shape)
|
||||||
|
{
|
||||||
|
return static_cast<MouseShapeHeader*>(shape)->frame_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* Extract_Shape(void* shape, int frame)
|
||||||
|
{
|
||||||
|
char* data = static_cast<char*>(shape);
|
||||||
|
MouseShapeHeader* header = static_cast<MouseShapeHeader*>(shape);
|
||||||
|
|
||||||
|
if (shape && frame >= 0 && header->frame_count > frame) {
|
||||||
|
return data + (&header->offset)[frame] + 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Get_Shape_Width(void* shape)
|
||||||
|
{
|
||||||
|
// return static_cast<ShapeHeaderStruct*>(shape)->Width;
|
||||||
|
return static_cast<MouseShapeFrameHeader*>(shape)->width;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Get_Shape_Height(void* shape)
|
||||||
|
{
|
||||||
|
return static_cast<MouseShapeFrameHeader*>(shape)->height;
|
||||||
|
}
|
||||||
|
|
||||||
|
//int Restore_Shape_Height(void* shape)
|
||||||
|
//{
|
||||||
|
// int oldheight = static_cast<MouseShapeFrameHeader*>(shape)->height;
|
||||||
|
// static_cast<MouseShapeFrameHeader*>(shape)->height = static_cast<MouseShapeFrameHeader*>(shape)->original_height;
|
||||||
|
// return oldheight;
|
||||||
|
//}
|
||||||
|
|
||||||
|
int Get_Shape_Original_Height(void* shape)
|
||||||
|
{
|
||||||
|
return static_cast<MouseShapeFrameHeader*>(shape)->original_height;
|
||||||
|
}
|
||||||
|
|
||||||
|
void __cdecl Mouse_Shadow_Buffer(WWMouseClass& mouse, GraphicViewPortClass& viewport, void* buffer, int x_pos, int y_pos, int hspot_x, int hspot_y, BOOL save)
|
||||||
|
{
|
||||||
|
int xstart = x_pos - hspot_x;
|
||||||
|
int ystart = y_pos - hspot_y;
|
||||||
|
int yend = mouse.Get_Cursor_Height() + ystart - 1;
|
||||||
|
int xend = mouse.Get_Cursor_Width() + xstart - 1;
|
||||||
|
int ms_img_offset = 0;
|
||||||
|
uint8_t* mouse_img = static_cast<uint8_t*>(buffer);
|
||||||
|
|
||||||
|
//If we aren't drawing within the viewport, return
|
||||||
|
if (xstart >= viewport.Get_Width() ||
|
||||||
|
ystart >= viewport.Get_Height() ||
|
||||||
|
xend <= 0 || yend <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xstart < 0) {
|
||||||
|
ms_img_offset = -xstart;
|
||||||
|
xstart = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ystart < 0) {
|
||||||
|
mouse_img += mouse.Get_Cursor_Width() * (-ystart);
|
||||||
|
ystart = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
xend = MIN(xend, viewport.Get_Width() - 1);
|
||||||
|
yend = MIN(yend, viewport.Get_Height() - 1);
|
||||||
|
|
||||||
|
int blit_height = yend - ystart + 1;
|
||||||
|
int blit_width = xend - xstart + 1;
|
||||||
|
int src_pitch;
|
||||||
|
int dst_pitch;
|
||||||
|
uint8_t* src;
|
||||||
|
uint8_t* dst;
|
||||||
|
|
||||||
|
// Bool will control if we are copying to or from shadow buffer, set vars here
|
||||||
|
if (save) {
|
||||||
|
src_pitch = (viewport.Get_Pitch() + viewport.Get_XAdd() + viewport.Get_Width());
|
||||||
|
dst_pitch = mouse.Get_Cursor_Width();
|
||||||
|
src = (uint8_t*)(viewport.Get_Offset()) + src_pitch * ystart + xstart;
|
||||||
|
dst = mouse_img + ms_img_offset;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
src_pitch = mouse.Get_Cursor_Width();
|
||||||
|
dst_pitch = (viewport.Get_Pitch() + viewport.Get_XAdd() + viewport.Get_Width());
|
||||||
|
src = mouse_img + ms_img_offset;
|
||||||
|
dst = (uint8_t*)(viewport.Get_Offset()) + dst_pitch * ystart + xstart;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (blit_height--) {
|
||||||
|
memcpy(dst, src, blit_width);
|
||||||
|
src += src_pitch;
|
||||||
|
dst += dst_pitch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void __cdecl Mouse_Draw(WWMouseClass& mouse, GraphicViewPortClass& viewport, int x_pos, int y_pos)
|
||||||
|
{
|
||||||
|
int xstart = x_pos - mouse.Get_Hotspot_X();
|
||||||
|
int ystart = y_pos - mouse.Get_Hotspot_Y();
|
||||||
|
int yend = mouse.Get_Cursor_Height() + ystart - 1;
|
||||||
|
int xend = mouse.Get_Cursor_Width() + xstart - 1;
|
||||||
|
int ms_img_offset = 0;
|
||||||
|
uint8_t* mouse_img = (uint8_t * )mouse.Get_Image_Buff();
|
||||||
|
|
||||||
|
//If we aren't drawing within the viewport, return
|
||||||
|
if (xstart >= viewport.Get_Width() ||
|
||||||
|
ystart >= viewport.Get_Height() ||
|
||||||
|
xend <= 0 || yend <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xstart < 0) {
|
||||||
|
ms_img_offset = -xstart;
|
||||||
|
xstart = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ystart < 0) {
|
||||||
|
mouse_img += mouse.Get_Cursor_Width() * (-ystart);
|
||||||
|
ystart = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
xend = MIN(xend, viewport.Get_Width() - 1);
|
||||||
|
yend = MIN(yend, viewport.Get_Height() - 1);
|
||||||
|
|
||||||
|
int pitch = viewport.Get_Pitch() + viewport.Get_XAdd() + viewport.Get_Width();
|
||||||
|
uint8_t* dst = xstart + pitch * ystart + (uint8_t*)(viewport.Get_Offset());
|
||||||
|
uint8_t* src = ms_img_offset + mouse_img;
|
||||||
|
int blit_pitch = xend - xstart + 1;
|
||||||
|
|
||||||
|
if ((xend > xstart) && (yend > ystart)) {
|
||||||
|
int blit_height = yend - ystart + 1;
|
||||||
|
int dst_pitch = pitch - blit_pitch;
|
||||||
|
int src_pitch = mouse.Get_Cursor_Width() - blit_pitch;
|
||||||
|
|
||||||
|
while (blit_height--) {
|
||||||
|
int blit_width = blit_pitch;
|
||||||
|
while (blit_width--) {
|
||||||
|
uint8_t current = *src++;
|
||||||
|
if (current) {
|
||||||
|
*dst = current;
|
||||||
|
}
|
||||||
|
|
||||||
|
++dst;
|
||||||
|
//--blit_width;
|
||||||
|
}
|
||||||
|
|
||||||
|
src += src_pitch;
|
||||||
|
dst += dst_pitch;
|
||||||
|
//--blit_height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void* __cdecl Mouse_Set_Cursor(WWMouseClass& mouse, int hspot_x, int hspot_y, void* frame)
|
||||||
|
{
|
||||||
|
uint8_t* frame_buff;
|
||||||
|
uint8_t* data_buff;
|
||||||
|
uint8_t* decmp_buff;
|
||||||
|
uint8_t* lcw_buff;
|
||||||
|
int16_t frame_flags;
|
||||||
|
|
||||||
|
int height;
|
||||||
|
int width;
|
||||||
|
int uncompsz;
|
||||||
|
|
||||||
|
MouseShapeFrameHeader* frame_header = static_cast<MouseShapeFrameHeader*>(frame);
|
||||||
|
|
||||||
|
//Get the dimensions of our frame, mouse shp format can have variable
|
||||||
|
//dimensions for each frame.
|
||||||
|
uncompsz = Get_Shape_Uncomp_Size(frame);
|
||||||
|
width = Get_Shape_Width(frame);
|
||||||
|
height = Get_Shape_Original_Height(frame);
|
||||||
|
|
||||||
|
if (width <= mouse.Get_Max_Width() && height <= mouse.Get_Max_Height()) {
|
||||||
|
frame_buff = (uint8_t * )mouse.Get_Image_Buff();
|
||||||
|
data_buff = static_cast<uint8_t*>(frame);
|
||||||
|
frame_flags = frame_header->flags;
|
||||||
|
|
||||||
|
//Flag bit 2 is flag for no compression on frame, decompress to
|
||||||
|
//intermediate buffer if flag is clear
|
||||||
|
if (!(frame_header->flags & 2)) {
|
||||||
|
decmp_buff = g_mouseShapeBuffer;
|
||||||
|
lcw_buff = reinterpret_cast<uint8_t*>(frame_header);
|
||||||
|
frame_flags = frame_header->flags | 2;
|
||||||
|
|
||||||
|
memcpy(decmp_buff, lcw_buff, sizeof(MouseShapeFrameHeader));
|
||||||
|
decmp_buff += sizeof(MouseShapeFrameHeader);
|
||||||
|
lcw_buff += sizeof(MouseShapeFrameHeader);
|
||||||
|
|
||||||
|
//Copies a small lookup table if it exists, probably not in RA.
|
||||||
|
if (frame_flags & 1) {
|
||||||
|
memcpy(decmp_buff, lcw_buff, 16);
|
||||||
|
decmp_buff += 16;
|
||||||
|
lcw_buff += 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
LCW_Uncomp(lcw_buff, decmp_buff, uncompsz);
|
||||||
|
data_buff = g_mouseShapeBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (frame_flags & 1) {
|
||||||
|
uint8_t* data_start = data_buff + sizeof(MouseShapeFrameHeader);
|
||||||
|
uint8_t* image_start = data_buff + sizeof(MouseShapeFrameHeader) + 16;
|
||||||
|
int image_size = height * width;
|
||||||
|
//uint8_t current_byte = 0;
|
||||||
|
int run_len = 0;
|
||||||
|
|
||||||
|
while (image_size) {
|
||||||
|
uint8_t current_byte = *image_start++;
|
||||||
|
if (current_byte) {
|
||||||
|
*frame_buff++ = data_start[current_byte];
|
||||||
|
--image_size;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!image_size) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
run_len = *image_start;
|
||||||
|
image_size -= run_len;
|
||||||
|
++image_start;
|
||||||
|
|
||||||
|
while (run_len--) {
|
||||||
|
*frame_buff++ = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
uint8_t* data_start = data_buff + sizeof(MouseShapeFrameHeader);
|
||||||
|
int image_size = height * width;
|
||||||
|
int run_len = 0;
|
||||||
|
|
||||||
|
while (image_size) {
|
||||||
|
uint8_t current_byte = *data_start++;
|
||||||
|
if (current_byte) {
|
||||||
|
*frame_buff++ = current_byte;
|
||||||
|
--image_size;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!image_size) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
run_len = *data_start;
|
||||||
|
image_size -= run_len;
|
||||||
|
++data_start;
|
||||||
|
|
||||||
|
while (run_len--) {
|
||||||
|
*frame_buff++ = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mouse.Set_Hotspot_X(hspot_x);
|
||||||
|
mouse.Set_Hotspot_Y(hspot_y);
|
||||||
|
mouse.Set_Cursor_Height(height);
|
||||||
|
mouse.Set_Cursor_Width(width);
|
||||||
|
}
|
||||||
|
|
||||||
|
void* result = mouse.Get_Frame_Pointer();
|
||||||
|
mouse.Set_Frame_Pointer(frame);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
/**
|
||||||
|
* @file
|
||||||
|
*
|
||||||
|
* @author OmniBlade
|
||||||
|
* @author CCHyper
|
||||||
|
*
|
||||||
|
* @brief Low level sprite drawing functions for Dune2 sprite format (used for mouse in early C&C games).
|
||||||
|
*
|
||||||
|
* @copyright Chronoshift 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
|
||||||
|
* 2 of the License, or (at your option) any later version.
|
||||||
|
* A full copy of the GNU General Public License can be found in
|
||||||
|
* LICENSE
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef MOUSESHAPE_H
|
||||||
|
#define MOUSESHAPE_H
|
||||||
|
|
||||||
|
#pragma pack(push, 1)
|
||||||
|
// Header for each frame in the old SHP format... only used for mouse now.
|
||||||
|
struct MouseShapeFrameHeader
|
||||||
|
{
|
||||||
|
//"MAKESHAPE_NORMAL" 0
|
||||||
|
//"MAKESHAPE_COMPACT" 1
|
||||||
|
//"MAKESHAPE_NOCOMP" 2
|
||||||
|
//"MAKESHAPE_VARIABLE" 4
|
||||||
|
uint16_t flags; // flag 1 specifies that a 16 byte color table follows the header.
|
||||||
|
// flag 2 specifies that this frame doesn't have LCW compression,
|
||||||
|
// this frame would only have RLE compression.
|
||||||
|
// flag 4 specifies a custom length color table follows the header.
|
||||||
|
uint8_t height; //height after RLE compression?
|
||||||
|
uint16_t width;
|
||||||
|
uint8_t original_height; // original frame height without any compression.
|
||||||
|
uint16_t shape_size; // full frame size including this header.
|
||||||
|
uint16_t data_length; // uncompressed size, frame size minus header if flag 2 is specified.
|
||||||
|
//
|
||||||
|
// Following this is optional data, in Dune 2 this was used to specify remap indexes.
|
||||||
|
// If flag 1 is set then a uint8_t color_table[16] follows.
|
||||||
|
// if flag 4 is set then a uint8_t color_table_size and uint8_t color_table[color_table_size] follows.
|
||||||
|
};
|
||||||
|
|
||||||
|
// Header for the old SHP format... only used for mouse now. Offset values need +2 to get actual frame pos.
|
||||||
|
struct MouseShapeHeader
|
||||||
|
{
|
||||||
|
uint16_t frame_count;
|
||||||
|
uint32_t offset;
|
||||||
|
};
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
class WWMouseClass;
|
||||||
|
class GraphicViewPortClass;
|
||||||
|
|
||||||
|
int Get_Shape_Uncomp_Size(void* shape);
|
||||||
|
int Extract_Shape_Count(void* shape);
|
||||||
|
void* Extract_Shape(void* shape, int frame = 0);
|
||||||
|
int Get_Shape_Width(void* shape);
|
||||||
|
int Get_Shape_Height(void* shape);
|
||||||
|
int Restore_Shape_Height(void* shape);
|
||||||
|
int Get_Shape_Original_Height(void* shape);
|
||||||
|
|
||||||
|
void __cdecl Mouse_Shadow_Buffer(WWMouseClass& mouse, GraphicViewPortClass& viewport, void* buffer, int x_pos, int y_pos, int hspot_x, int hspot_y, BOOL save);
|
||||||
|
void __cdecl Mouse_Draw(WWMouseClass& mouse, GraphicViewPortClass& viewport, int x_pos, int y_pos);
|
||||||
|
void* __cdecl Mouse_Set_Cursor(WWMouseClass& mouse, int hspot_x, int hspot_y, void* shape);
|
||||||
|
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user