Skip to content

Commit

Permalink
Implement progress bar and static text gadgets (#1003)
Browse files Browse the repository at this point in the history
  • Loading branch information
jonwil authored Oct 5, 2023
1 parent ad47de4 commit 5b0b6d5
Show file tree
Hide file tree
Showing 6 changed files with 386 additions and 19 deletions.
6 changes: 3 additions & 3 deletions src/game/client/displaystring.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ class DisplayString : public MemoryPoolObject
virtual GameFont *Get_Font() { return m_font; }
virtual void Set_Word_Wrap(int length) = 0;
virtual void Set_Word_Wrap_Centered(bool on) = 0;
virtual void Draw(int x, int y, int w, int h) = 0;
virtual void Draw(int x, int y, int w, int h, int unk1, int unk2) = 0;
virtual void Draw(int x, int y, int color, int border_color) = 0;
virtual void Draw(int x, int y, int color, int border_color, int x_offset, int y_offset) = 0;
virtual void Get_Size(int *x, int *y) = 0;
virtual int Get_Width(int char_count) = 0;
virtual void Set_Use_Hotkey(bool state, int val) = 0;
Expand All @@ -54,4 +54,4 @@ class DisplayString : public MemoryPoolObject
GameFont *m_font;
DisplayString *m_next;
DisplayString *m_prev;
};
};
8 changes: 8 additions & 0 deletions src/game/client/gui/gadget/gadgetprogressbar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
* LICENSE
*/
#include "gadgetprogressbar.h"
#include "gamewindowmanager.h"

WindowMsgHandledType Gadget_Progress_Bar_System(
GameWindow *progress_bar, unsigned int message, unsigned int data_1, unsigned int data_2)
Expand All @@ -27,3 +28,10 @@ WindowMsgHandledType Gadget_Progress_Bar_System(

return MSG_HANDLED;
}

void Gadget_Progress_Bar_Set_Progress(GameWindow *progress_bar, int progress)
{
if (progress_bar != nullptr) {
g_theWindowManager->Win_Send_System_Msg(progress_bar, GPM_SET_PROGRESS, progress, 0);
}
}
52 changes: 46 additions & 6 deletions src/game/client/gui/gadget/gadgetstatictext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
*/
#include "gadgetstatictext.h"
#include "displaystring.h"
#include "displaystringmanager.h"
#include "gamewindow.h"
#include "gamewindowmanager.h"
#include "keyboard.h"
Expand Down Expand Up @@ -80,10 +81,49 @@ WindowMsgHandledType Gadget_Static_Text_Input(
WindowMsgHandledType Gadget_Static_Text_System(
GameWindow *static_text, unsigned int message, unsigned int data_1, unsigned int data_2)
{
#ifdef GAME_DLL
return Call_Function<WindowMsgHandledType, GameWindow *, unsigned int, unsigned int, unsigned int>(
PICK_ADDRESS(0x005A2DF0, 0x008DFAA7), static_text, message, data_1, data_2);
#else
return MSG_IGNORED;
#endif
switch (message) {
case GGM_GET_LABEL: {
_TextData *st_data = static_cast<_TextData *>(static_text->Win_Get_User_Data());

if (st_data != nullptr && st_data->m_text != nullptr) {
*(reinterpret_cast<Utf16String *>(data_2)) = st_data->m_text->Get_Text();
}

return MSG_HANDLED;
}
case GGM_SET_LABEL: {
_TextData *st_data = static_cast<_TextData *>(static_text->Win_Get_User_Data());

if (st_data != nullptr && st_data->m_text != nullptr) {
st_data->m_text->Set_Text(*(reinterpret_cast<Utf16String *>(data_1)));
}

return MSG_HANDLED;
}
case GWM_CREATE:
return MSG_HANDLED;
case GWM_DESTROY: {
_TextData *st_data = static_cast<_TextData *>(static_text->Win_Get_User_Data());
g_theDisplayStringManager->Free_Display_String(st_data->m_text);
delete st_data;
return MSG_HANDLED;
}
default:
return MSG_IGNORED;
}
}

Utf16String Gadget_Static_Text_Get_Text(GameWindow *static_text)
{
if (static_text != nullptr) {
_TextData *st_data = static_cast<_TextData *>(static_text->Win_Get_User_Data());

if (st_data != nullptr) {
return st_data->m_text->Get_Text();
} else {
return Utf16String::s_emptyString;
}
} else {
return Utf16String::s_emptyString;
}
}
14 changes: 14 additions & 0 deletions src/hooker/setuphooks_zh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -197,13 +197,15 @@
#include "w3dmodeldraw.h"
#include "w3dmouse.h"
#include "w3dpoly.h"
#include "w3dprogressbar.h"
#include "w3dprojectedshadow.h"
#include "w3dpropbuffer.h"
#include "w3droadbuffer.h"
#include "w3dscene.h"
#include "w3dshroud.h"
#include "w3dsmudge.h"
#include "w3dsnow.h"
#include "w3dstatictext.h"
#include "w3dterrainbackground.h"
#include "w3dterraintracks.h"
#include "w3dtreebuffer.h"
Expand Down Expand Up @@ -3470,10 +3472,22 @@ void Setup_Hooks()

// gadgetprogressbar.h
Hook_Any(0x005A2C60, Gadget_Progress_Bar_System);
Hook_Any(0x005A2C90, Gadget_Progress_Bar_Set_Progress);

// gadgetstatictext.h
Hook_Any(0x005A2CC0, Gadget_Static_Text_Input);
Hook_Any(0x005A2DF0, Gadget_Static_Text_System);
Hook_Any(0x005A2EF0, Gadget_Static_Text_Set_Text);
Hook_Any(0x005A2F60, Gadget_Static_Text_Get_Text);

// gadgettabcontrol.h
Hook_Any(0x006D8390, Gadget_Tab_Control_Show_Sub_Pane);

// w3dprogressbar.h
Hook_Any(0x007CB2F0, W3D_Gadget_Progress_Bar_Draw);
Hook_Any(0x007CB520, W3D_Gadget_Progress_Bar_Image_Draw);

// w3dstatictext.h
Hook_Any(0x007CAF30, W3D_Gadget_Static_Text_Draw);
Hook_Any(0x007CB1D0, W3D_Gadget_Static_Text_Image_Draw);
}
183 changes: 179 additions & 4 deletions src/platform/w3dengine/client/gui/gadget/w3dprogressbar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,192 @@
* LICENSE
*/
#include "w3dprogressbar.h"
#include "display.h"
#include "gadgetprogressbar.h"
#include "gamewindowmanager.h"
#include "image.h"

void W3D_Gadget_Progress_Bar_Draw(GameWindow *progress_bar, WinInstanceData *data)
{
#ifdef GAME_DLL
Call_Function<void, GameWindow *, WinInstanceData *>(0x007CB2F0, progress_bar, data);
unsigned int progress = 0;
#ifdef GAME_DLL // temporary since we can't change the definition of Win_Send_System_Msg at this point and we can't cast a
// pointer to an unsigned int on 64 bit
progress = reinterpret_cast<unsigned int>(progress_bar->Win_Get_User_Data());
#endif

int screen_x;
int screen_y;
int width;
int height;
progress_bar->Win_Get_Screen_Position(&screen_x, &screen_y);
progress_bar->Win_Get_Size(&width, &height);

int border_color;
int color;
int bar_border_color;
int bar_color;

if ((progress_bar->Win_Get_Status() & WIN_STATUS_ENABLED) != 0) {
if ((data->m_state & 2) != 0) {
border_color = progress_bar->Win_Get_Instance_Data()->m_hiliteDrawData[0].borderColor;
color = progress_bar->Win_Get_Instance_Data()->m_hiliteDrawData[0].color;
bar_border_color = progress_bar->Win_Get_Instance_Data()->m_hiliteDrawData[4].borderColor;
bar_color = progress_bar->Win_Get_Instance_Data()->m_hiliteDrawData[4].color;
} else {
border_color = progress_bar->Win_Get_Instance_Data()->m_enabledDrawData[0].borderColor;
color = progress_bar->Win_Get_Instance_Data()->m_enabledDrawData[0].color;
bar_border_color = progress_bar->Win_Get_Instance_Data()->m_enabledDrawData[4].borderColor;
bar_color = progress_bar->Win_Get_Instance_Data()->m_enabledDrawData[4].color;
}
} else {
border_color = progress_bar->Win_Get_Instance_Data()->m_disabledDrawData[0].borderColor;
color = progress_bar->Win_Get_Instance_Data()->m_disabledDrawData[0].color;
bar_border_color = progress_bar->Win_Get_Instance_Data()->m_disabledDrawData[4].borderColor;
bar_color = progress_bar->Win_Get_Instance_Data()->m_disabledDrawData[4].color;
}

if (border_color != 0xFFFFFF) {
g_theWindowManager->Win_Open_Rect(border_color, 1.0f, screen_x, screen_y, width + screen_x, screen_y + height);
}

if (color != 0xFFFFFF) {
g_theWindowManager->Win_Fill_Rect(
color, 1.0f, screen_x + 1, screen_y + 1, width + screen_x + 1 - 2, screen_y + 1 + height - 2);
}

if (progress != 0) {
if (bar_border_color != 0xFFFFFF && progress * width / 100 > 1) {
g_theWindowManager->Win_Open_Rect(
bar_border_color, 1.0, screen_x, screen_y, screen_x + progress * width / 100, screen_y + height);
}

if (bar_color != 0xFFFFFF) {
int start_x = screen_x + 1;
int start_y = screen_y + 1;
int end_x = progress * width / 100 + screen_x + 1 - 2;
int end_y = screen_y + 1 + height - 2;

if (end_x - (screen_x + 1) > 1) {
g_theWindowManager->Win_Fill_Rect(bar_color, 1.0f, start_x, screen_y + 1, end_x, screen_y + 1 + height - 2);
g_theWindowManager->Win_Draw_Line(0xFFFFFFFF, 1.0f, start_x, start_y, end_x, start_y);
g_theWindowManager->Win_Draw_Line(0xFFC8C8C8, 1.0f, start_x, start_y, start_x, end_y);
}
}
}
}

void W3D_Gadget_Progress_Bar_Image_Draw(GameWindow *progress_bar, WinInstanceData *data)
{
#ifdef GAME_DLL
Call_Function<void, GameWindow *, WinInstanceData *>(0x007CB520, progress_bar, data);
unsigned int progress = 0;
#ifdef GAME_DLL // temporary since we can't change the definition of Win_Send_System_Msg at this point and we can't cast a
// pointer to an unsigned int on 64 bit
progress = reinterpret_cast<unsigned int>(progress_bar->Win_Get_User_Data());
#endif

int screen_x;
int screen_y;
int width;
int height;
progress_bar->Win_Get_Screen_Position(&screen_x, &screen_y);
progress_bar->Win_Get_Size(&width, &height);

int x = data->m_imageOffset.x;
int y = data->m_imageOffset.y;
const Image *left_end_image;
const Image *right_end_image;
const Image *bar_right_end_image;
const Image *repeating_center_image;
const Image *bar_repeating_center_image;

if ((progress_bar->Win_Get_Status() & WIN_STATUS_ENABLED) != 0) {
if ((data->m_state & 2) != 0) {
left_end_image = progress_bar->Win_Get_Instance_Data()->m_hiliteDrawData[0].image;
right_end_image = progress_bar->Win_Get_Instance_Data()->m_hiliteDrawData[1].image;
bar_right_end_image = progress_bar->Win_Get_Instance_Data()->m_hiliteDrawData[5].image;
repeating_center_image = progress_bar->Win_Get_Instance_Data()->m_hiliteDrawData[2].image;
bar_repeating_center_image = progress_bar->Win_Get_Instance_Data()->m_hiliteDrawData[6].image;
} else {
left_end_image = progress_bar->Win_Get_Instance_Data()->m_enabledDrawData[0].image;
right_end_image = progress_bar->Win_Get_Instance_Data()->m_enabledDrawData[1].image;
bar_right_end_image = progress_bar->Win_Get_Instance_Data()->m_enabledDrawData[5].image;
repeating_center_image = progress_bar->Win_Get_Instance_Data()->m_enabledDrawData[2].image;
bar_repeating_center_image = progress_bar->Win_Get_Instance_Data()->m_enabledDrawData[6].image;
}
} else {
left_end_image = progress_bar->Win_Get_Instance_Data()->m_disabledDrawData[0].image;
right_end_image = progress_bar->Win_Get_Instance_Data()->m_disabledDrawData[1].image;
bar_right_end_image = progress_bar->Win_Get_Instance_Data()->m_disabledDrawData[5].image;
repeating_center_image = progress_bar->Win_Get_Instance_Data()->m_disabledDrawData[2].image;
bar_repeating_center_image = progress_bar->Win_Get_Instance_Data()->m_disabledDrawData[6].image;
}

if (left_end_image != nullptr && right_end_image != nullptr && repeating_center_image != nullptr
&& bar_right_end_image != nullptr) {
int i1 = right_end_image->Get_Image_Width();
int i2 = screen_x + left_end_image->Get_Image_Width();
int i3 = screen_y + y + height;
int i4 = x + screen_x + width - i1;
int i5 = x + i2;
int i6 = i1;
int i7 = y + screen_y;
int i8 = repeating_center_image->Get_Image_Width();
int i9 = i5;
int i10 = y + screen_y + height;

if ((i4 - i5) / i8 > 0) {
int i11 = (i4 - i5) / i8;

do {
g_theWindowManager->Win_Draw_Image(repeating_center_image, i9, i7, i8 + i9, i10, 0xFFFFFFFF);
i8 = repeating_center_image->Get_Image_Width();
i9 += i8;
i11--;
} while (i11 != 0);
}

IRegion2D clip_region;
clip_region.lo.x = i9;
clip_region.lo.y = i7;
clip_region.hi.x = i4;
clip_region.hi.y = i10;

if (i4 - i9 > 0) {
g_theDisplay->Set_Clip_Region(&clip_region);
g_theWindowManager->Win_Draw_Image(
repeating_center_image, i9, i7, i9 + repeating_center_image->Get_Image_Width(), i10, 0xFFFFFFFF);
g_theDisplay->Enable_Clipping(false);
}

g_theWindowManager->Win_Draw_Image(left_end_image, screen_x + x, y + screen_y, i5, i3, 0xFFFFFFFF);
g_theWindowManager->Win_Draw_Image(right_end_image, i4, i7, i4 + i6, i7 + height, 0xFFFFFFFF);
int i12 = bar_repeating_center_image->Get_Image_Width();
int i13 = y + screen_y + 5;
int i14 = progress * (width - 20) / 100 / i12;
int i15 = screen_x + 10;
int i16 = i13 + height - 10;

if (i14 > 0) {
int i17 = progress * (width - 20) / 100 / i12;
do {
g_theWindowManager->Win_Draw_Image(bar_repeating_center_image, i15, i13, i15 + i12, i16, 0xFFFFFFFF);
i12 = bar_repeating_center_image->Get_Image_Width();
i15 += i12;
i17--;
} while (i17);
}

int i18 = i14 * bar_repeating_center_image->Get_Image_Width() + screen_x + 0xA;

if ((width - 20) / bar_repeating_center_image->Get_Image_Width() - i14 > 0) {
int i21 = bar_right_end_image->Get_Image_Width();
int i19 = (width - 20) / bar_repeating_center_image->Get_Image_Width() - i14;

do {
g_theWindowManager->Win_Draw_Image(bar_right_end_image, i18, i13, i21 + i18, i16, 0xFFFFFFFF);
i21 = bar_right_end_image->Get_Image_Width();
i18 += i21;
i19--;
} while (i19);
}
}
}
Loading

0 comments on commit 5b0b6d5

Please sign in to comment.