Files
source/Utils/Slider.cpp
BeatAroundTheBuscherandGitHub ed00830202 Fixes Upper/Lower Casing for include paths (#487)
* Fixing upper/lower case for includes

types.h, zconf.h and zlib.h were renamed so that global includes like Types.h
are not used.
2025-08-16 22:01:12 -03:00

772 lines
19 KiB
C++

#include "types.h"
#include "WordWrap.h"
#include "Render Dirty.h"
#include "Utilities.h"
#include "WCheck.h"
#include "Slider.h"
#include "sysutil.h"
#include "line.h"
///////////////////////////////////////////////////
//
// Defines
//
///////////////////////////////////////////////////
#define DEFUALT_SLIDER_SIZE 7
#define STEEL_SLIDER_WIDTH 42
#define STEEL_SLIDER_HEIGHT 25
typedef struct TAG_SLIDER
{
UINT32 uiSliderID;
UINT8 ubStyle;
UINT16 usPosX;
UINT16 usPosY;
UINT16 usWidth;
UINT16 usHeight;
UINT16 usNumberOfIncrements;
SLIDER_CHANGE_CALLBACK SliderChangeCallback;
UINT16 usCurrentIncrement;
UINT16 usBackGroundColor;
MOUSE_REGION ScrollAreaMouseRegion;
UINT32 uiSliderBoxImage;
UINT16 usCurrentSliderBoxPosition;
SGPRect LastRect;
UINT32 uiFlags;
UINT8 ubSliderWidth;
UINT8 ubSliderHeight;
struct TAG_SLIDER *pNext;
struct TAG_SLIDER *pPrev;
} SLIDER;
//ddd
///////////////////////////////////////////////////
//
// Global Variables
//
///////////////////////////////////////////////////
SLIDER *pSliderHead = NULL;
UINT32 guiCurrentSliderID=1;
BOOLEAN gfSliderInited=FALSE;
BOOLEAN gfCurrentSliderIsAnchored=FALSE; //if true, the current selected slider mouse button is down
SLIDER *gpCurrentSlider=NULL;
UINT32 guiSliderBoxImage=0;
//ggg
//Mouse regions for the currently selected save game
void SelectedSliderButtonCallBack(MOUSE_REGION * pRegion, INT32 iReason );
void SelectedSliderMovementCallBack(MOUSE_REGION * pRegion, INT32 reason );
///////////////////////////////////////////////////
//
// Function Prototypes
//
///////////////////////////////////////////////////
void OptDisplayLine( UINT16 usStartX, UINT16 usStartY, UINT16 EndX, UINT16 EndY, INT16 iColor );
void RenderSelectedSliderBar( SLIDER *pSlider );
void CalculateNewSliderBoxPosition( SLIDER *pSlider );
SLIDER *GetSliderFromID( UINT32 uiSliderID );
void RenderSliderBox( SLIDER *pSlider );
void CalculateNewSliderIncrement( UINT32 uiSliderID, UINT16 usPosX );
//ppp
///////////////////////////////////////////////////
//
// Functions
//
///////////////////////////////////////////////////
BOOLEAN InitSlider()
{
VOBJECT_DESC VObjectDesc;
// load Slider Box Graphic graphic and add it
VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE;
FilenameForBPP("INTERFACE\\SliderBox.sti", VObjectDesc.ImageFile);
CHECKF(AddVideoObject(&VObjectDesc, &guiSliderBoxImage ));
gfSliderInited = TRUE;
return( TRUE );
}
void ShutDownSlider()
{
SLIDER *pRemove = NULL;
SLIDER *pTemp = NULL;
AssertMsg( gfSliderInited, "Trying to ShutDown the Slider System when it was never inited");
//Do a cehck to see if there are still active nodes
pTemp = pSliderHead;
while( pTemp )
{
pRemove = pTemp;
pTemp = pTemp->pNext;
RemoveSliderBar( pRemove->uiSliderID );
//Report an error
}
//if so report an errror
gfSliderInited = 0;
DeleteVideoObjectFromIndex( guiSliderBoxImage );
}
INT32 AddSlider( UINT8 ubStyle, UINT16 usCursor, UINT16 usPosX, UINT16 usPosY, UINT16 usWidth, UINT16 usNumberOfIncrements, INT8 sPriority, SLIDER_CHANGE_CALLBACK SliderChangeCallback, UINT32 uiFlags )
{
SLIDER *pTemp = NULL;
SLIDER *pNewSlider = NULL;
AssertMsg( gfSliderInited, "Trying to Add a Slider Bar when the Slider System was never inited");
//checks
if( ubStyle >= NUM_SLIDER_STYLES )
return( -1 );
pNewSlider = (SLIDER *) MemAlloc( sizeof( SLIDER ) );
if( pNewSlider == NULL )
{
return( -1 );
}
memset( pNewSlider, 0, sizeof( SLIDER ) );
//Assign the settings to the current slider
pNewSlider->ubStyle = ubStyle;
pNewSlider->usPosX = usPosX;
pNewSlider->usPosY = usPosY;
// pNewSlider->usWidth = usWidth;
pNewSlider->usNumberOfIncrements = usNumberOfIncrements;
pNewSlider->SliderChangeCallback = SliderChangeCallback;
pNewSlider->usCurrentIncrement = 0;
pNewSlider->usBackGroundColor = Get16BPPColor( FROMRGB( 255, 255, 255 ) );
pNewSlider->uiFlags = uiFlags;
//Get a new Identifier for the slider
//Temp just increment for now
pNewSlider->uiSliderID = guiCurrentSliderID;
//increment counter
guiCurrentSliderID++;
//
// Create the mouse regions for each increment in the slider
//
//add the region
usPosX = pNewSlider->usPosX;
usPosY = pNewSlider->usPosY;
//Add the last one, the width will be whatever is left over
switch( ubStyle )
{
case SLIDER_VERTICAL_STEEL:
pNewSlider->uiFlags |= SLIDER_VERTICAL;
pNewSlider->usWidth = STEEL_SLIDER_WIDTH;
pNewSlider->usHeight = usWidth;
pNewSlider->ubSliderWidth = STEEL_SLIDER_WIDTH;
pNewSlider->ubSliderHeight = STEEL_SLIDER_HEIGHT;
MSYS_DefineRegion( &pNewSlider->ScrollAreaMouseRegion, (UINT16)(usPosX-pNewSlider->usWidth/2), usPosY, (UINT16)(usPosX+pNewSlider->usWidth/2), (UINT16)(pNewSlider->usPosY+pNewSlider->usHeight), sPriority,
usCursor, SelectedSliderMovementCallBack, SelectedSliderButtonCallBack );
MSYS_SetRegionUserData( &pNewSlider->ScrollAreaMouseRegion, 1, pNewSlider->uiSliderID );
break;
case SLIDER_DEFAULT_STYLE:
default:
pNewSlider->uiFlags |= SLIDER_HORIZONTAL;
pNewSlider->usWidth = usWidth;
pNewSlider->usHeight = DEFUALT_SLIDER_SIZE;
MSYS_DefineRegion( &pNewSlider->ScrollAreaMouseRegion, usPosX, (UINT16)(usPosY-DEFUALT_SLIDER_SIZE), (UINT16)(pNewSlider->usPosX+pNewSlider->usWidth), (UINT16)(usPosY+DEFUALT_SLIDER_SIZE), sPriority,
usCursor, SelectedSliderMovementCallBack, SelectedSliderButtonCallBack );
MSYS_SetRegionUserData( &pNewSlider->ScrollAreaMouseRegion, 1, pNewSlider->uiSliderID );
break;
}
//
// Load the graphic image for the slider box
//
//add the slider into the list
pTemp = pSliderHead;
//if its the first time in
if( pSliderHead == NULL )
{
pSliderHead = pNewSlider;
pNewSlider->pNext = NULL;
}
else
{
while( pTemp->pNext != NULL )
{
pTemp = pTemp->pNext;
}
pTemp->pNext = pNewSlider;
pNewSlider->pPrev = pTemp;
pNewSlider->pNext = NULL;
}
CalculateNewSliderBoxPosition( pNewSlider );
return( pNewSlider->uiSliderID );
}
void RenderAllSliderBars()
{
SLIDER *pTemp = NULL;
// set the currently selectd slider bar
if( gfLeftButtonState && gpCurrentSlider != NULL )
{
UINT16 usPosY = 0;
if( gusMouseYPos < gpCurrentSlider->usPosY )
usPosY = 0;
else
usPosY = gusMouseYPos - gpCurrentSlider->usPosY;
//if the mouse
CalculateNewSliderIncrement( gpCurrentSlider->uiSliderID, usPosY );
}
else
{
gpCurrentSlider = NULL;
}
pTemp = pSliderHead;
while( pTemp )
{
RenderSelectedSliderBar( pTemp );
pTemp = pTemp->pNext;
}
}
void RenderSelectedSliderBar( SLIDER *pSlider )
{
if( pSlider->uiFlags & SLIDER_VERTICAL )
{
}
else
{
//display the background ( the bar )
OptDisplayLine( (UINT16)(pSlider->usPosX+1), (UINT16)(pSlider->usPosY-1), (UINT16)(pSlider->usPosX + pSlider->usWidth-1), (UINT16)(pSlider->usPosY-1), pSlider->usBackGroundColor );
OptDisplayLine( pSlider->usPosX, pSlider->usPosY, (UINT16)(pSlider->usPosX + pSlider->usWidth), pSlider->usPosY, pSlider->usBackGroundColor );
OptDisplayLine( (UINT16)(pSlider->usPosX+1), (UINT16)(pSlider->usPosY+1), (UINT16)(pSlider->usPosX + pSlider->usWidth-1), (UINT16)(pSlider->usPosY+1), pSlider->usBackGroundColor );
//invalidate the area
InvalidateRegion( pSlider->usPosX, pSlider->usPosY-2, pSlider->usPosX+pSlider->usWidth+1, pSlider->usPosY+2 );
}
RenderSliderBox( pSlider );
}
void RenderSliderBox( SLIDER *pSlider )
{
HVOBJECT hPixHandle;
SGPRect SrcRect;
SGPRect DestRect;
if( pSlider->uiFlags & SLIDER_VERTICAL )
{
//fill out the settings for the current dest and source rects
SrcRect.iLeft = 0;
SrcRect.iTop = 0;
SrcRect.iRight = pSlider->ubSliderWidth;
SrcRect.iBottom = pSlider->ubSliderHeight;
DestRect.iLeft = pSlider->usPosX - pSlider->ubSliderWidth / 2;
DestRect.iTop = pSlider->usCurrentSliderBoxPosition - pSlider->ubSliderHeight/2;
DestRect.iRight = DestRect.iLeft + pSlider->ubSliderWidth;
DestRect.iBottom = DestRect.iTop + pSlider->ubSliderHeight;
//If it is not the first time to render the slider
if( !( pSlider->LastRect.iLeft == 0 && pSlider->LastRect.iRight == 0 ) )
{
//Restore the old rect
BlitBufferToBuffer(guiSAVEBUFFER, guiRENDERBUFFER, (UINT16)pSlider->LastRect.iLeft, (UINT16)pSlider->LastRect.iTop, pSlider->ubSliderWidth, pSlider->ubSliderHeight );
//invalidate the old area
InvalidateRegion( pSlider->LastRect.iLeft, pSlider->LastRect.iTop, pSlider->LastRect.iRight, pSlider->LastRect.iBottom );
}
//Blit the new rect
BlitBufferToBuffer( guiRENDERBUFFER, guiSAVEBUFFER, (UINT16)DestRect.iLeft, (UINT16)DestRect.iTop, pSlider->ubSliderWidth, pSlider->ubSliderHeight );
}
else
{
//fill out the settings for the current dest and source rects
SrcRect.iLeft = 0;
SrcRect.iTop = 0;
SrcRect.iRight = pSlider->ubSliderWidth;
SrcRect.iBottom = pSlider->ubSliderHeight;
DestRect.iLeft = pSlider->usCurrentSliderBoxPosition;
DestRect.iTop = pSlider->usPosY-DEFUALT_SLIDER_SIZE;
DestRect.iRight = DestRect.iLeft + pSlider->ubSliderWidth;
DestRect.iBottom = DestRect.iTop + pSlider->ubSliderHeight;
//If it is not the first time to render the slider
if( !( pSlider->LastRect.iLeft == 0 && pSlider->LastRect.iRight == 0 ) )
{
//Restore the old rect
BlitBufferToBuffer(guiSAVEBUFFER, guiRENDERBUFFER, (UINT16)pSlider->LastRect.iLeft, (UINT16)pSlider->LastRect.iTop, 8, 15 );
}
//save the new rect
BlitBufferToBuffer(guiRENDERBUFFER, guiSAVEBUFFER, (UINT16)DestRect.iLeft, (UINT16)DestRect.iTop, 8, 15 );
}
//Save the new rect location
pSlider->LastRect = DestRect;
if( pSlider->uiFlags & SLIDER_VERTICAL )
{
//display the slider box
GetVideoObject(&hPixHandle, guiSliderBoxImage );
BltVideoObject(FRAME_BUFFER, hPixHandle, 0, pSlider->LastRect.iLeft, pSlider->LastRect.iTop, VO_BLT_SRCTRANSPARENCY,NULL);
//invalidate the area
InvalidateRegion( pSlider->LastRect.iLeft, pSlider->LastRect.iTop, pSlider->LastRect.iRight, pSlider->LastRect.iBottom );
}
else
{
//display the slider box
GetVideoObject(&hPixHandle, guiSliderBoxImage );
BltVideoObject(FRAME_BUFFER, hPixHandle, 0, pSlider->usCurrentSliderBoxPosition, pSlider->usPosY-DEFUALT_SLIDER_SIZE, VO_BLT_SRCTRANSPARENCY,NULL);
//invalidate the area
InvalidateRegion( pSlider->usCurrentSliderBoxPosition, pSlider->usPosY-DEFUALT_SLIDER_SIZE, pSlider->usCurrentSliderBoxPosition+9, pSlider->usPosY+DEFUALT_SLIDER_SIZE );
}
}
void RemoveSliderBar( UINT32 uiSliderID )
{
SLIDER *pTemp = NULL;
SLIDER *pNodeToRemove = NULL;
// UINT32 cnt;
pTemp = pSliderHead;
//Get the required slider
while( pTemp && pTemp->uiSliderID != uiSliderID )
{
pTemp = pTemp->pNext;
}
//if we could not find the required slider
if( pTemp == NULL )
{
//return an error
return;
}
pNodeToRemove = pTemp;
if( pTemp == pSliderHead )
pSliderHead = pSliderHead->pNext;
//Detach the node.
if( pTemp->pNext )
pTemp->pNext->pPrev = pTemp->pPrev;
if( pTemp->pPrev )
pTemp->pPrev->pNext = pTemp->pNext;
MSYS_RemoveRegion( &pNodeToRemove->ScrollAreaMouseRegion );
//if its the last node
if( pNodeToRemove == pSliderHead )
pSliderHead = NULL;
//Remove the slider node
MemFree( pNodeToRemove );
pNodeToRemove = NULL;
}
void SelectedSliderMovementCallBack(MOUSE_REGION * pRegion, INT32 reason )
{
UINT32 uiSelectedSlider;
SLIDER *pSlider=NULL;
//if we already have an anchored slider bar
if( gpCurrentSlider != NULL )
return;
if( reason & MSYS_CALLBACK_REASON_LOST_MOUSE )
{
pRegion->uiFlags &= (~BUTTON_CLICKED_ON );
if( gfLeftButtonState )
{
uiSelectedSlider = MSYS_GetRegionUserData( pRegion, 1 );
pSlider = GetSliderFromID( uiSelectedSlider );
if( pSlider == NULL )
return;
// set the currently selectd slider bar
if( gfLeftButtonState )
{
gpCurrentSlider = pSlider;
}
if( pSlider->uiFlags & SLIDER_VERTICAL )
{
CalculateNewSliderIncrement( uiSelectedSlider, pRegion->RelativeYPos );
}
else
{
CalculateNewSliderIncrement( uiSelectedSlider, pRegion->RelativeXPos );
}
}
}
else if( reason & MSYS_CALLBACK_REASON_GAIN_MOUSE )
{
pRegion->uiFlags |= BUTTON_CLICKED_ON ;
if( gfLeftButtonState )
{
uiSelectedSlider = MSYS_GetRegionUserData( pRegion, 1 );
pSlider = GetSliderFromID( uiSelectedSlider );
if( pSlider == NULL )
return;
// set the currently selectd slider bar
// gpCurrentSlider = pSlider;
if( pSlider->uiFlags & SLIDER_VERTICAL )
{
CalculateNewSliderIncrement( uiSelectedSlider, pRegion->RelativeYPos );
}
else
{
CalculateNewSliderIncrement( uiSelectedSlider, pRegion->RelativeXPos );
}
}
}
else if( reason & MSYS_CALLBACK_REASON_MOVE )
{
pRegion->uiFlags |= BUTTON_CLICKED_ON ;
if( gfLeftButtonState )
{
uiSelectedSlider = MSYS_GetRegionUserData( pRegion, 1 );
pSlider = GetSliderFromID( uiSelectedSlider );
if( pSlider == NULL )
return;
// set the currently selectd slider bar
// gpCurrentSlider = pSlider;
if( pSlider->uiFlags & SLIDER_VERTICAL )
{
CalculateNewSliderIncrement( uiSelectedSlider, pRegion->RelativeYPos );
}
else
{
CalculateNewSliderIncrement( uiSelectedSlider, pRegion->RelativeXPos );
}
}
}
}
void SelectedSliderButtonCallBack(MOUSE_REGION * pRegion, INT32 iReason )
{
UINT32 uiSelectedSlider;
SLIDER *pSlider=NULL;
//if we already have an anchored slider bar
if( gpCurrentSlider != NULL )
return;
if (iReason & MSYS_CALLBACK_REASON_INIT)
{
}
else if (iReason & MSYS_CALLBACK_REASON_LBUTTON_DWN)
{
uiSelectedSlider = MSYS_GetRegionUserData( pRegion, 1 );
pSlider = GetSliderFromID( uiSelectedSlider );
if( pSlider == NULL )
return;
/* // set the currently selectd slider bar
if( gfLeftButtonState )
{
gpCurrentSlider = pSlider;
}
*/
if( pSlider->uiFlags & SLIDER_VERTICAL )
{
CalculateNewSliderIncrement( uiSelectedSlider, pRegion->RelativeYPos );
}
else
{
CalculateNewSliderIncrement( uiSelectedSlider, pRegion->RelativeXPos );
}
}
else if (iReason & MSYS_CALLBACK_REASON_LBUTTON_REPEAT )
{
uiSelectedSlider = MSYS_GetRegionUserData( pRegion, 1 );
pSlider = GetSliderFromID( uiSelectedSlider );
if( pSlider == NULL )
return;
// set the currently selectd slider bar
/* if( gfLeftButtonState )
{
gpCurrentSlider = pSlider;
}
*/
if( pSlider->uiFlags & SLIDER_VERTICAL )
{
CalculateNewSliderIncrement( uiSelectedSlider, pRegion->RelativeYPos );
}
else
{
CalculateNewSliderIncrement( uiSelectedSlider, pRegion->RelativeXPos );
}
}
else if (iReason & MSYS_CALLBACK_REASON_LBUTTON_UP)
{
}
}
void CalculateNewSliderIncrement( UINT32 uiSliderID, UINT16 usPos )
{
FLOAT dNewIncrement=0.0;
SLIDER *pSlider;
UINT16 usOldIncrement;
BOOLEAN fLastSpot=FALSE;
BOOLEAN fFirstSpot=FALSE;
pSlider = GetSliderFromID( uiSliderID );
if( pSlider == NULL )
return;
usOldIncrement = pSlider->usCurrentIncrement;
if( pSlider->uiFlags & SLIDER_VERTICAL )
{
if( usPos >= (UINT16)(pSlider->usHeight * 0.99f ) )
fLastSpot = TRUE;
if( usPos <= (UINT16)(pSlider->usHeight * 0.01f ) )
fFirstSpot = TRUE;
//pSlider->usNumberOfIncrements
if( fFirstSpot )
dNewIncrement = 0;
else if( fLastSpot )
dNewIncrement = pSlider->usNumberOfIncrements;
else
dNewIncrement = ( usPos / (FLOAT)pSlider->usHeight ) * pSlider->usNumberOfIncrements;
}
else
{
dNewIncrement = ( usPos / (FLOAT)pSlider->usWidth ) * pSlider->usNumberOfIncrements;
}
pSlider->usCurrentIncrement = (UINT16)( dNewIncrement + .5 );
CalculateNewSliderBoxPosition( pSlider );
//if the the new value is different
if( usOldIncrement != pSlider->usCurrentIncrement )
{
if( pSlider->uiFlags & SLIDER_VERTICAL )
{
//Call the call back for the slider
(*(pSlider->SliderChangeCallback) )( pSlider->usNumberOfIncrements - pSlider->usCurrentIncrement );
}
else
{
//Call the call back for the slider
(*(pSlider->SliderChangeCallback) )( pSlider->usCurrentIncrement );
}
}
}
void OptDisplayLine( UINT16 usStartX, UINT16 usStartY, UINT16 EndX, UINT16 EndY, INT16 iColor )
{
UINT32 uiDestPitchBYTES;
UINT8 *pDestBuf;
pDestBuf = LockVideoSurface( FRAME_BUFFER, &uiDestPitchBYTES );
SetClippingRegionAndImageWidth( uiDestPitchBYTES, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
// draw the line
LineDraw(FALSE, usStartX, usStartY, EndX, EndY, iColor, pDestBuf);
// unlock frame buffer
UnLockVideoSurface( FRAME_BUFFER );
}
void CalculateNewSliderBoxPosition( SLIDER *pSlider )
{
UINT16 usMaxPos;
if( pSlider->uiFlags & SLIDER_VERTICAL )
{
//if the box is in the last position
if( pSlider->usCurrentIncrement >= ( pSlider->usNumberOfIncrements ) )
{
pSlider->usCurrentSliderBoxPosition = pSlider->usPosY + pSlider->usHeight;// - pSlider->ubSliderHeight / 2; // - minus box width
}
//else if the box is in the first position
else if( pSlider->usCurrentIncrement == 0 )
{
pSlider->usCurrentSliderBoxPosition = pSlider->usPosY;// - pSlider->ubSliderHeight / 2;
}
else
{
pSlider->usCurrentSliderBoxPosition = pSlider->usPosY + (UINT16)( ( pSlider->usHeight / (FLOAT)pSlider->usNumberOfIncrements ) * pSlider->usCurrentIncrement );
}
usMaxPos = pSlider->usPosY + pSlider->usHeight;// - pSlider->ubSliderHeight//2 + 1;
//if the box is past the edge, move it back
if( pSlider->usCurrentSliderBoxPosition > usMaxPos )
pSlider->usCurrentSliderBoxPosition = usMaxPos;
}
else
{
//if the box is in the last position
if( pSlider->usCurrentIncrement == ( pSlider->usNumberOfIncrements ) )
{
pSlider->usCurrentSliderBoxPosition = pSlider->usPosX + pSlider->usWidth - 8 + 1; // - minus box width
}
else
{
pSlider->usCurrentSliderBoxPosition = pSlider->usPosX + (UINT16)( ( pSlider->usWidth / (FLOAT)pSlider->usNumberOfIncrements ) * pSlider->usCurrentIncrement );
}
usMaxPos = pSlider->usPosX + pSlider->usWidth - 8+1;
//if the box is past the edge, move it back
if( pSlider->usCurrentSliderBoxPosition > usMaxPos )
pSlider->usCurrentSliderBoxPosition = usMaxPos;
}
}
SLIDER *GetSliderFromID( UINT32 uiSliderID )
{
SLIDER *pTemp = NULL;
pTemp = pSliderHead;
//Get the required slider
while( pTemp && pTemp->uiSliderID != uiSliderID )
{
pTemp = pTemp->pNext;
}
// if we couldnt find the right slider
if( pTemp == NULL )
return( NULL );
return( pTemp );
}
void SetSliderValue( UINT32 uiSliderID, UINT32 uiNewValue )
{
SLIDER *pSlider = NULL;
pSlider = GetSliderFromID( uiSliderID );
if( pSlider == NULL )
return;
if( uiNewValue >= pSlider->usNumberOfIncrements )
return;
if( pSlider->uiFlags & SLIDER_VERTICAL )
pSlider->usCurrentIncrement = pSlider->usNumberOfIncrements - (UINT16)uiNewValue;
else
pSlider->usCurrentIncrement = (UINT16)uiNewValue;
CalculateNewSliderBoxPosition( pSlider );
}