diff --git a/src/addresses.h b/src/addresses.h
index fe411534fb..21b1ba53ed 100644
--- a/src/addresses.h
+++ b/src/addresses.h
@@ -64,6 +64,7 @@
#define RCT2_ADDRESS_INPUT_STATE 0x009DE51D
#define RCT2_ADDRESS_CURSOR_DOWN_WINDOWCLASS 0x009DE51F
#define RCT2_ADDRESS_CURSOR_DOWN_WINDOWNUMBER 0x009DE520
+#define RCT2_ADDRESS_CURSOR_DOWN_WIDGETINDEX 0x009DE524
#define RCT2_ADDRESS_TOOLTIP_WINDOW_CLASS 0x009DE533
#define RCT2_ADDRESS_TOOLTIP_WINDOW_NUMBER 0x009DE534
diff --git a/src/gfx.c b/src/gfx.c
index 683e635676..1aa90c691a 100644
--- a/src/gfx.c
+++ b/src/gfx.c
@@ -100,6 +100,22 @@ void gfx_fill_rect(rct_drawpixelinfo *dpi, int left, int top, int right, int bot
RCT2_CALLPROC_X(0x00678AD4, left, right, top, bottom, 0, dpi, colour);
}
+/**
+ *
+ * rct2: 0x006E6F81
+ * dpi (edi)
+ * left (ax)
+ * top (cx)
+ * right (bx)
+ * bottom (dx)
+ * colour (ebp)
+ * _si (si)
+ */
+void gfx_fill_rect_inset(rct_drawpixelinfo* dpi, short left, short top, short right, short bottom, int colour, short _si)
+{
+ RCT2_CALLPROC_X(0x006E6F81, left, right, top, bottom, _si, dpi, colour);
+}
+
/**
*
* rct2: 0x0067A28E
@@ -161,7 +177,9 @@ void gfx_draw_string_centred(rct_drawpixelinfo *dpi, int format, int x, int y, i
*/
void gfx_invalidate_screen()
{
- RCT2_CALLPROC_EBPSAFE(0x006ED7E5);
+ int width = RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, sint16);
+ int height = RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_HEIGHT, sint16);
+ gfx_set_dirty_blocks(0, 0, width, height);
}
/**
@@ -394,4 +412,18 @@ int gfx_draw_string_left_wrapped(rct_drawpixelinfo *dpi, void *format, int x, in
RCT2_CALLFUNC_X(0x006C2105, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
return (sint16)(edx & 0xFFFF) - y;
+}
+
+/**
+ *
+ * rct2: 0x00682702
+ * dpi (edi)
+ * format (esi)
+ * colour (al)
+ * x (cx)
+ * y (dx)
+ */
+void gfx_draw_string(rct_drawpixelinfo *dpi, char *format, int colour, int x, int y)
+{
+ RCT2_CALLPROC_X(0x00682702, colour, 0, x, y, format, dpi, 0);
}
\ No newline at end of file
diff --git a/src/gfx.h b/src/gfx.h
index b34197e2ca..a7ccf14773 100644
--- a/src/gfx.h
+++ b/src/gfx.h
@@ -50,8 +50,9 @@ void gfx_load_g1();
void gfx_clear(rct_drawpixelinfo *dpi, int colour);
void gfx_fill_rect(rct_drawpixelinfo *dpi, int left, int top, int right, int bottom, int colour);
+void gfx_fill_rect_inset(rct_drawpixelinfo* dpi, short left, short top, short right, short bottom, int colour, short _si);
void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y);
-void gfx_draw_string(rct_drawpixelinfo *dpi, char *text, int colour, int x, int y);
+void gfx_draw_string(rct_drawpixelinfo *dpi, char *format, int colour, int x, int y);
void gfx_transpose_palette(int pal, unsigned char product);
void gfx_draw_string_left(rct_drawpixelinfo *dpi, int format, void *args, int colour, int x, int y);
diff --git a/src/strings.c b/src/strings.c
index 8cbef39840..97e605f1b8 100644
--- a/src/strings.c
+++ b/src/strings.c
@@ -18,7 +18,9 @@
* along with this program. If not, see .
*****************************************************************************/
+#include
#include "addresses.h"
+#include "rct2.h"
#include "strings.h"
/**
@@ -31,4 +33,94 @@
void format_string(char *dest, rct_string_id format, void *args)
{
RCT2_CALLPROC_X(0x006C2555, format, 0, args, 0, 0, dest, 0);
+}
+
+void generate_string_file()
+{
+ FILE* f;
+ uint8** str;
+ uint8* c;
+ int i;
+
+ f = fopen("english.txt", "w");
+
+ for (i = 0; i < 4442; i++) {
+ str = ((uint8**)(0x009BF2D4 + (i * 4)));
+ if (*str == (uint8*)0xFFFFFFFF)
+ continue;
+ c = *str;
+
+ fprintf(f, "STR_%04d :", i);
+ while (*c != '\0') {
+ switch (*c) {
+ case 7: fputs("{TINYFONT}", f); break;
+ case 8: fputs("{BIGFONT}", f); break;
+ case 9: fputs("{MEDIUMFONT}", f); break;
+ case 10: fputs("{SMALLFONT}", f); break;
+
+ case 11: fputs("{OUTLINE}", f); break;
+
+ case 34: fputs("{ENDQUOTES}", f); break;
+ case 123: fputs("{COMMA32}", f); break;
+ case 125: fputs("{COMMA2DP32}", f); break;
+ case 126: fputs("{COMMA16}", f); break;
+ case 128: fputs("{CURRENCY2DP}", f); break;
+ case 129: fputs("{CURRENCY}", f); break;
+ case 130: fputs("{STRING}", f); break;
+ case 133: fputs("{MONTHYEAR}", f); break;
+ case 135: fputs("{VELOCITY}", f); break;
+ case 140: fputs("{LENGTH}", f); break;
+ case 141: fputs("{SPRITE}", f); break;
+
+ case 142: fputs("{BLACK}", f); break;
+ case 143: fputs("{GREY}", f); break;
+ case 144: fputs("{WHITE}", f); break;
+ case 145: fputs("{RED}", f); break;
+ case 146: fputs("{GREEN}", f); break;
+ case 147: fputs("{YELLOW}", f); break;
+ case 148: fputs("{TOPAZ}", f); break;
+ case 149: fputs("{CELADON}", f); break;
+ case 150: fputs("{BABYBLUE}", f); break;
+ case 151: fputs("{PALELAVENDER}", f); break;
+ case 152: fputs("{PALEGOLD}", f); break;
+ case 153: fputs("{LIGHTPINK}", f); break;
+ case 154: fputs("{PEARLAQUA}", f); break;
+ case 155: fputs("{PALESILVER}", f); break;
+
+ case 159: fputs("{AMINUSCULE}", f); break;
+ case 160: fputs("{UP}", f); break;
+ case 163: fputs("{POUND}", f); break;
+ case 165: fputs("{YEN}", f); break;
+ case 169: fputs("{COPYRIGHT}", f); break;
+ case 170: fputs("{DOWN}", f); break;
+ case 171: fputs("{LEFTGUILLEMET}", f); break;
+ case 172: fputs("{TICK}", f); break;
+ case 173: fputs("{CROSS}", f); break;
+ case 175: fputs("{RIGHT}", f); break;
+ case 176: fputs("{DEGREE}", f); break;
+ case 178: fputs("{SQUARED}", f); break;
+ case 180: fputs("{OPENQUOTES}", f); break;
+ case 181: fputs("{EURO}", f); break;
+ case 184: fputs("{APPROX}", f); break;
+ case 185: fputs("{POWERNEGATIVEONE}", f); break;
+ case 186: fputs("{BULLET}", f); break;
+ case 187: fputs("{RIGHTGUILLEMET}", f); break;
+ case 188: fputs("{SMALLUP}", f); break;
+ case 189: fputs("{SMALLDOWN}", f); break;
+ case 190: fputs("{LEFT}", f); break;
+ case 191: fputs("{INVERTEDQUESTION}", f); break;
+ default:
+ if (*c < 32 || *c > 127)
+ fprintf(f, "{%d}", *c);
+ else
+ fputc(*c, f);
+ break;
+ }
+
+ c++;
+ }
+ fputc('\n', f);
+ }
+
+ fclose(f);
}
\ No newline at end of file
diff --git a/src/strings.h b/src/strings.h
index c66328bbad..7977c8ec30 100644
--- a/src/strings.h
+++ b/src/strings.h
@@ -26,6 +26,66 @@ typedef unsigned short rct_string_id;
void format_string(char *dest, rct_string_id format, void *args);
void generate_string_file();
+enum {
+ FORMAT_TINYFONT = 7,
+ FORMAT_BIGFONT,
+ FORMAT_MEDIUMFONT,
+ FORMAT_SMALLFONT,
+
+ FORMAT_OUTLINE,
+
+ FORMAT_ENDQUOTES = 34,
+
+ FORMAT_COMMA32 = 123,
+ FORMAT_COMMA2DP32 = 125,
+ FORMAT_COMMA16,
+ FORMAT_CURRENCY2DP = 128,
+ FORMAT_CURRENCY,
+ FORMAT_STRING,
+ FORMAT_MONTHYEAR = 133,
+ FORMAT_VELOCITY = 135,
+ FORMAT_LENGTH = 140,
+ FORMAT_SPRITE = 141,
+
+ FORMAT_BLACK = 142,
+ FORMAT_GREY,
+ FORMAT_WHITE,
+ FORMAT_RED,
+ FORMAT_GREEN,
+ FORMAT_YELLOW,
+ FORMAT_TOPAZ,
+ FORMAT_CELADON,
+ FORMAT_BABYBLUE,
+ FORMAT_PALELAVENDER,
+ FORMAT_PALEGOLD,
+ FORMAT_LIGHTPINK,
+ FORMAT_PEARLAQUA,
+ FORMAT_PALESILVER,
+
+ FORMAT_AMINUSCULE = 159,
+ FORMAT_UP,
+ FORMAT_POUND = 163,
+ FORMAT_YEN = 165,
+ FORMAT_COPYRIGHT = 169,
+ FORMAT_DOWN,
+ FORMAT_LEFTGUILLEMET,
+ FORMAT_TICK,
+ FORMAT_CROSS,
+ FORMAT_RIGHT = 175,
+ FORMAT_DEGREE,
+ FORMAT_SQUARED = 178,
+ FORMAT_OPENQUOTES = 180,
+ FORMAT_EURO = 181,
+ FORMAT_APPROX = 184,
+ FORMAT_POWERNEGATIVEONE,
+ FORMAT_BULLET,
+ FORMAT_RIGHTGUILLEMET,
+ FORMAT_SMALLUP,
+ FORMAT_SMALLDOWN,
+ FORMAT_LEFT,
+ FORMAT_INVERTEDQUESTION
+};
+
enum {
STR_NONE = -1,
diff --git a/src/widget.c b/src/widget.c
index 09bae1fc11..428e70a5b9 100644
--- a/src/widget.c
+++ b/src/widget.c
@@ -19,9 +19,24 @@
*****************************************************************************/
#include
+#include "addresses.h"
+#include "sprites.h"
#include "widget.h"
#include "window.h"
+static void widget_frame_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex);
+static void widget_button_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex);
+static void widget_tab_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex);
+static void widget_flat_button_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex);
+static void widget_caption_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex);
+static void widget_closebox_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex);
+static void widget_scroll_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex);
+static void widget_hscrollbar_draw(rct_drawpixelinfo *dpi, rct_scroll *scroll, int l, int t, int r, int b, int colour);
+static void widget_vscrollbar_draw(rct_drawpixelinfo *dpi, rct_scroll *scroll, int l, int t, int r, int b, int colour);
+static int widget_is_disabled(rct_window *w, int widgetIndex);
+static int widget_is_pressed(rct_window *w, int widgetIndex);
+static int widget_is_highlighted(rct_window *w, int widgetIndex);
+
/**
*
* rct2: 0x006EAF26
@@ -74,4 +89,496 @@ void widget_scroll_update_thumbs(rct_window *w, int widget_index)
view_size += 10;
scroll->v_thumb_bottom = min(y, view_size);
}
+}
+
+void widget_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex)
+{
+ switch (w->widgets[widgetIndex].type) {
+ case WWT_FRAME:
+ widget_frame_draw(dpi, w, widgetIndex);
+ break;
+ case WWT_RESIZE:
+ break;
+ case WWT_IMGBTN:
+ case WWT_4:
+ widget_button_draw(dpi, w, widgetIndex);
+ break;
+ case WWT_5:
+ case WWT_6:
+ case WWT_TRNBTN:
+ case WWT_TAB:
+ widget_tab_draw(dpi, w, widgetIndex);
+ break;
+ case WWT_FLATBTN:
+ widget_flat_button_draw(dpi, w, widgetIndex);
+ break;
+ case WWT_DROPDOWN_BUTTON:
+ case WWT_11:
+ case WWT_13:
+ break;
+ case WWT_12:
+ break;
+ case WWT_14:
+ break;
+ case WWT_15:
+ case WWT_DROPDOWN:
+ case WWT_VIEWPORT:
+ break;
+ case WWT_18:
+ break;
+ case WWT_19:
+ break;
+ case WWT_CAPTION:
+ widget_caption_draw(dpi, w, widgetIndex);
+ break;
+ case WWT_CLOSEBOX:
+ widget_closebox_draw(dpi, w, widgetIndex);
+ break;
+ case WWT_SCROLL:
+ widget_scroll_draw(dpi, w, widgetIndex);
+ break;
+ case WWT_23:
+ case WWT_24:
+ break;
+ case WWT_25:
+ break;
+ }
+}
+
+/**
+ *
+ * rct2: 0x006EB6CE
+ */
+static void widget_frame_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex)
+{
+ rct_widget* widget;
+ int l, t, r, b, press;
+ uint8 colour;
+
+ // Get the widget
+ widget = &w->widgets[widgetIndex];
+
+ // Resolve the absolute ltrb
+ l = w->x + widget->left;
+ t = w->y + widget->top;
+ r = w->x + widget->right;
+ b = w->y + widget->bottom;
+
+ //
+ press = (w->flags & 0x0400 ? 0x80 : 0);
+
+ // Get the colour
+ colour = w->colours[widget->colour];
+
+ // Draw the frame
+ gfx_fill_rect_inset(dpi, l, t, r, b, colour, press);
+
+ // Check if the window can be resized
+ if (!(w->flags & 0x100))
+ return;
+ if (w->min_width == w->max_width && w->min_height == w->max_height)
+ return;
+
+ // Draw the resize sprite at the bottom right corner
+ l = w->x + widget->right - 18;
+ t = w->y + widget->bottom - 18;
+ gfx_draw_sprite(dpi, SPR_RESIZE | 0x20000000 | (colour << 19), l, t);
+}
+
+/**
+ *
+ * rct2: 0x006EB8E5
+ */
+static void widget_button_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex)
+{
+ rct_widget* widget;
+ int l, t, r, b, press;
+ uint32 image;
+ uint8 colour;
+
+ // Get the widget
+ widget = &w->widgets[widgetIndex];
+
+ // Resolve the absolute ltrb
+ l = w->x + widget->left;
+ t = w->y + widget->top;
+ r = w->x + widget->right;
+ b = w->y + widget->bottom;
+
+ // Check if the button is pressed down
+ press = widget_is_pressed(w, widgetIndex) ? 0x20 : 0;
+
+ // Get the colour
+ colour = w->colours[widget->colour];
+
+ // ?
+ if (widget->image == -2) {
+ gfx_fill_rect_inset(dpi, l, t, r, b, colour, press | 0x10);
+ return;
+ }
+
+ // Draw the button
+ gfx_fill_rect_inset(dpi, l, t, r, b, colour, press);
+
+ if (widget->image == -1)
+ return;
+
+ // Draw the image
+ image = widget->image;
+ if (!widget_is_disabled(w, widgetIndex)) {
+ if (image & 0x80000000) {
+ // ?
+ }
+
+ if (image & 0x40000000)
+ image &= ~0x40000000;
+ else
+ image |= colour << 19;
+
+ gfx_draw_sprite(dpi, image, l, t);
+ } else {
+ // ?
+ }
+}
+
+/**
+ *
+ * rct2: 0x006EB806
+ */
+static void widget_tab_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex)
+{
+ rct_widget* widget;
+ int l, t, r, b;
+ uint32 image;
+ uint8 colour;
+
+ // Get the widget
+ widget = &w->widgets[widgetIndex];
+
+ //
+ if (widget->image == -1)
+ return;
+
+ // Check if tab is disabled
+ if (widget_is_disabled(w, widgetIndex))
+ return;
+
+ // Resolve the absolute ltrb
+ l = w->x + widget->left;
+ t = w->y + widget->top;
+ r = w->x + widget->right;
+ b = w->y + widget->bottom;
+
+ // Get the colour
+ colour = w->colours[widget->colour];
+
+ // Check if the tab is pressed down
+ image = widget->image;
+ if (widget_is_pressed(w, widgetIndex))
+ image++;
+
+ if (image & 0x40000000)
+ image &= ~0x40000000;
+ else
+ image |= colour << 19;
+
+ gfx_draw_sprite(dpi, image, l, t);
+}
+
+/**
+ *
+ * rct2: 0x006EB861
+ */
+static void widget_flat_button_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex)
+{
+ rct_widget* widget;
+ int l, t, r, b, state;
+ uint32 image;
+ uint8 colour;
+
+ // Get the widget
+ widget = &w->widgets[widgetIndex];
+
+ // Resolve the absolute ltrb
+ l = w->x + widget->left;
+ t = w->y + widget->top;
+ r = w->x + widget->right;
+ b = w->y + widget->bottom;
+
+ // Check if the button is pressed down
+ state = 0;
+ if (widget_is_pressed(w, widgetIndex))
+ state = 1;
+
+ // Check if the button is highlighted
+ if (state == 0 && widget_is_highlighted(w, widgetIndex))
+ state = 2;
+
+ // Get the colour
+ colour = w->colours[widget->colour];
+
+ if (state == 1)
+ gfx_fill_rect_inset(dpi, l, t, r, b, colour, 0x20);
+ else if (state == 2)
+ gfx_fill_rect_inset(dpi, l, t, r, b, colour, 0x10);
+}
+
+/**
+ *
+ * rct2: 0x006EB2F9
+ */
+static void widget_caption_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex)
+{
+ rct_widget* widget;
+ int l, t, r, b, width, press;
+ uint8 colour;
+
+ // Get the widget
+ widget = &w->widgets[widgetIndex];
+
+ // Resolve the absolute ltrb
+ l = w->x + widget->left;
+ t = w->y + widget->top;
+ r = w->x + widget->right;
+ b = w->y + widget->bottom;
+
+ // Get the colour
+ colour = w->colours[widget->colour];
+
+ //
+ if (w->var_4B8 != -1) {
+ gfx_draw_sprite(dpi, *((char*)(0x013CA742 + w->var_4B8)) << 19, l + 1, t + 1);
+ if (w->width > 638)
+ gfx_draw_sprite(dpi, *((char*)(0x013CA742 + w->var_4B8)) << 19, l + 1 + 638, t + 1);
+ if (w->var_4B9 != -1) {
+ gfx_draw_sprite(dpi, *((char*)(0x013CA742 + w->var_4B9)) << 19, l + 1, t + 1);
+ if (w->width > 638)
+ gfx_draw_sprite(dpi, *((char*)(0x013CA742 + w->var_4B9)) << 19, l + 1 + 638, t + 1);
+ }
+
+ //
+ press = 0x70;
+ if (w->flags & 0x0400)
+ press |= 0x80;
+
+ gfx_fill_rect_inset(dpi, l, t, r, b, colour, press);
+ gfx_fill_rect(dpi, r + 1, t, r + 1, b, *((char*)(0x0141FC47 + (colour * 8))));
+ } else {
+ //
+ press = 0x60;
+ if (w->flags & 0x0400)
+ press |= 0x80;
+
+ gfx_fill_rect_inset(dpi, l, t, r, b, colour, press);
+ gfx_fill_rect(dpi, l + 1, t + 1, r - 1, b - 1, 0x2000000 | 47);
+ }
+
+ // Draw text
+ l = widget->left + w->x + 2;
+ t = widget->top + w->y + 1;
+ width = widget->right - widget->left - 4;
+ if ((widget + 1)->type == WWT_CLOSEBOX) {
+ width -= 10;
+ if ((widget + 2)->type == WWT_CLOSEBOX)
+ width -= 10;
+ }
+ l += width / 2;
+ gfx_draw_string_centred_clipped(dpi, widget->image, (void*)0x013CE952, 34, l, t, width);
+}
+
+/**
+ *
+ * rct2: 0x006EBB85
+ */
+static void widget_closebox_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex)
+{
+ rct_widget* widget;
+ int l, t, r, b, press;
+ uint8 colour;
+
+ // Get the widget
+ widget = &w->widgets[widgetIndex];
+
+ // Resolve the absolute ltrb
+ l = w->x + widget->left;
+ t = w->y + widget->top;
+ r = w->x + widget->right;
+ b = w->y + widget->bottom;
+
+ // Check if the button is pressed down
+ press = 0;
+ if (w->flags & 0x400)
+ press |= 0x80;
+ if (widget_is_pressed(w, widgetIndex))
+ press |= 0x20;
+
+ // Get the colour
+ colour = w->colours[widget->colour];
+
+ // Draw the button
+ gfx_fill_rect_inset(dpi, l, t, r, b, colour, press);
+
+ if (widget->image == -1)
+ return;
+
+ l = w->x + (widget->left + widget->right) / 2 - 1;
+ t = w->y + max(widget->top, (widget->top + widget->bottom) / 2 - 5);
+
+ if (widget_is_disabled(w, widgetIndex))
+ colour |= 0x40;
+
+ gfx_draw_string_centred_clipped(dpi, widget->image, (void*)0x013CE952, colour, l, t, widget->right - widget->left - 2);
+}
+
+/**
+ *
+ * rct2: 0x006EBD96
+ */
+static void widget_scroll_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex)
+{
+ rct_widget* widget;
+ rct_scroll* scroll;
+ int scrollIndex;
+ int l, t, r, b, press, ebp;
+ int cl, ct, cr, cb;
+ uint8 colour;
+ rct_drawpixelinfo scroll_dpi;
+
+ // Get the widget
+ scrollIndex = window_get_scroll_data_index(w, widgetIndex);
+ widget = &w->widgets[widgetIndex];
+ scroll = &w->scrolls[scrollIndex];
+
+ // Resolve the absolute ltrb
+ l = w->x + widget->left;
+ t = w->y + widget->top;
+ r = w->x + widget->right;
+ b = w->y + widget->bottom;
+
+ // Get the colour
+ colour = w->colours[widget->colour];
+
+ // Draw the border
+ gfx_fill_rect_inset(dpi, l, t, r, b, colour, 0x60);
+
+ // Inflate by -1
+ l++;
+ t++;
+ r--;
+ b--;
+
+ // Horizontal scrollbar
+ if (scroll->flags & HSCROLLBAR_VISIBLE)
+ widget_hscrollbar_draw(dpi, scroll, l, b - 10, (scroll->flags & VSCROLLBAR_VISIBLE ? r - 10 : r), b, colour);
+
+ // Vertical scrollbar
+ if (scroll->flags & VSCROLLBAR_VISIBLE)
+ widget_vscrollbar_draw(dpi, scroll, r - 10, t, r, (scroll->flags & HSCROLLBAR_VISIBLE ? b - 10 : b), colour);
+
+ // Contents
+ if (scroll->flags & HSCROLLBAR_VISIBLE)
+ b -= 11;
+ if (scroll->flags & VSCROLLBAR_VISIBLE)
+ r -= 11;
+
+ // Create a new inner scroll dpi
+ scroll_dpi = *dpi;
+
+ // Clip the scroll dpi against the outer dpi
+ cl = max(dpi->x, l);
+ ct = max(dpi->y, t);
+ cr = min(dpi->x + dpi->width, r);
+ cb = min(dpi->y + dpi->height, b);
+
+ // Set the respective dpi attributes
+ scroll_dpi.x = cl - l + scroll->h_left;
+ scroll_dpi.y = ct - t + scroll->v_top;
+ scroll_dpi.width = cr - cl;
+ scroll_dpi.height = cb - ct;
+ scroll_dpi.bits += cl - dpi->x;
+ scroll_dpi.bits += (ct - dpi->y) * (dpi->width + dpi->pitch);
+ scroll_dpi.pitch = (dpi->width + dpi->pitch) - scroll_dpi.width;
+
+ // Draw the scroll contents
+ if (scroll_dpi.width > 0 && scroll_dpi.height > 0)
+ RCT2_CALLPROC_X(w->event_handlers[WE_SCROLL_PAINT], 0, 0, 0, 0, w, &scroll_dpi, 0);
+}
+
+static void widget_hscrollbar_draw(rct_drawpixelinfo *dpi, rct_scroll *scroll, int l, int t, int r, int b, int colour)
+{
+ // Trough
+ gfx_fill_rect(dpi, l + 10, t, r - 10, b, *((char*)(0x0141FC4B + (colour * 8))));
+ gfx_fill_rect(dpi, l + 10, t, r - 10, b, 0x1000000 | *((char*)(0x0141FC47 + (colour * 8))));
+ gfx_fill_rect(dpi, l + 10, t + 2, r - 10, t + 2, *((char*)(0x0141FC47 + (colour * 8))));
+ gfx_fill_rect(dpi, l + 10, t + 3, r - 10, t + 3, *((char*)(0x0141FC4B + (colour * 8))));
+ gfx_fill_rect(dpi, l + 10, t + 7, r - 10, t + 7, *((char*)(0x0141FC47 + (colour * 8))));
+ gfx_fill_rect(dpi, l + 10, t + 8, r - 10, t + 8, *((char*)(0x0141FC4B + (colour * 8))));
+
+ // Left button
+ gfx_fill_rect_inset(dpi, l, t, l + 9, b, colour, (scroll->flags & HSCROLLBAR_LEFT_PRESSED ? 0x20 : 0));
+ gfx_draw_string(dpi, (char*)0x009DED6C, 0, l + 1, t);
+
+ // Thumb
+ gfx_fill_rect_inset(dpi,
+ max(l + 10, l + scroll->h_thumb_left - 1), t,
+ min(r - 10, r + scroll->h_thumb_right - 1), t,
+ colour, (scroll->flags & HSCROLLBAR_THUMB_PRESSED ? 0x20 : 0));
+
+ // Right button
+ gfx_fill_rect_inset(dpi, r - 9, t, r, b, colour, (scroll->flags & HSCROLLBAR_RIGHT_PRESSED ? 0x20 : 0));
+ gfx_draw_string(dpi, (char*)0x009DED6F, 0, r - 6, t);
+}
+
+static void widget_vscrollbar_draw(rct_drawpixelinfo *dpi, rct_scroll *scroll, int l, int t, int r, int b, int colour)
+{
+ // Trough
+ gfx_fill_rect(dpi, l, t + 10, r, b - 10, *((char*)(0x0141FC4B + (colour * 8))));
+ gfx_fill_rect(dpi, l, t + 10, r, b - 10, 0x1000000 | *((char*)(0x0141FC47 + (colour * 8))));
+ gfx_fill_rect(dpi, l + 2, t + 10, l + 2, b - 10, *((char*)(0x0141FC47 + (colour * 8))));
+ gfx_fill_rect(dpi, l + 3, t + 10, l + 3, b - 10, *((char*)(0x0141FC4B + (colour * 8))));
+ gfx_fill_rect(dpi, l + 7, t + 10, l + 7, b - 10, *((char*)(0x0141FC47 + (colour * 8))));
+ gfx_fill_rect(dpi, l + 8, t + 10, l + 8, b - 10, *((char*)(0x0141FC4B + (colour * 8))));
+
+ // Up button
+ gfx_fill_rect_inset(dpi, l, t, r, t + 9, colour, (scroll->flags & VSCROLLBAR_UP_PRESSED ? 0x20 : 0));
+ gfx_draw_string(dpi, (char*)0x009DED66, 0, l + 1, t - 1);
+
+ // Thumb
+ gfx_fill_rect_inset(dpi,
+ l, max(t + 10, t + scroll->v_thumb_top - 1),
+ r, min(b - 10, t + scroll->v_thumb_bottom - 1),
+ colour, (scroll->flags & VSCROLLBAR_THUMB_PRESSED ? 0x20 : 0));
+
+ // Down button
+ gfx_fill_rect_inset(dpi, l, b - 9, r, b, colour, (scroll->flags & VSCROLLBAR_DOWN_PRESSED ? 0x20 : 0));
+ gfx_draw_string(dpi, (char*)0x009DED69, 0, l + 1, b - 8);
+}
+
+static int widget_is_disabled(rct_window *w, int widgetIndex)
+{
+ return w->disabled_widgets & (1LL << widgetIndex);
+}
+
+static int widget_is_pressed(rct_window *w, int widgetIndex)
+{
+ int inputState = RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8);
+
+ if (w->pressed_widgets & (1LL << widgetIndex))
+ return 1;
+ if (inputState == INPUT_STATE_WIDGET_PRESSED || inputState == INPUT_STATE_DROPDOWN_ACTIVE) {
+ if (RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWCLASS, rct_windowclass) != w->classification)
+ return 0;
+ if (RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WINDOWNUMBER, rct_windownumber) != w->number)
+ return 0;
+ if (!(RCT2_GLOBAL(0x009DE518, uint32) & 1))
+ return 0;
+ if (RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DOWN_WIDGETINDEX, sint32) == widgetIndex)
+ return 1;
+ }
+ return 0;
+}
+
+static int widget_is_highlighted(rct_window *w, int widgetIndex)
+{
+ return 0;
}
\ No newline at end of file
diff --git a/src/widget.h b/src/widget.h
index face7f482c..9fb74f805b 100644
--- a/src/widget.h
+++ b/src/widget.h
@@ -29,21 +29,32 @@ typedef enum {
WWT_RESIZE = 2,
WWT_IMGBTN = 3,
WWT_4 = 4,
+ WWT_5 = 5,
+ WWT_6 = 6,
WWT_TRNBTN = 7,
WWT_TAB = 8,
WWT_FLATBTN = 9,
WWT_DROPDOWN_BUTTON = 10,
- WWT_12 = 12,
+ WWT_11,
+ WWT_12,
+ WWT_13,
+ WWT_14,
+ WWT_15,
WWT_DROPDOWN = 16,
WWT_VIEWPORT = 17,
+ WWT_18,
+ WWT_19,
WWT_CAPTION = 20,
WWT_CLOSEBOX = 21,
WWT_SCROLL = 22,
- WWT_25 = 25,
+ WWT_23,
+ WWT_24,
+ WWT_25,
WWT_LAST = 26,
} WINDOW_WIDGET_TYPES;
#define WIDGETS_END WWT_LAST, 0, 0, 0, 0, 0, 0, 0
void widget_scroll_update_thumbs(rct_window *w, int widget_index);
+void widget_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex);
#endif
\ No newline at end of file
diff --git a/src/window.c b/src/window.c
index 95d9169ca2..cb4e169a5b 100644
--- a/src/window.c
+++ b/src/window.c
@@ -592,5 +592,22 @@ static int window_draw_split(rct_window *w, int left, int top, int right, int bo
*/
void window_draw_widgets(rct_window *w, rct_drawpixelinfo *dpi)
{
- RCT2_CALLPROC_X(0x006EB15C, 0, 0, 0, 0, w, dpi, 0);
+ rct_widget *widget;
+ int widgetIndex;
+
+ // RCT2_CALLPROC_X(0x006EB15C, 0, 0, 0, 0, w, dpi, 0);
+ // return;
+
+ if ((w->flags & WF_TRANSPARENT) && !(w->flags & 0x20))
+ gfx_fill_rect(dpi, w->x, w->y, w->x + w->width - 1, w->y + w->height - 1, 0x2000000 | 51);
+
+ widgetIndex = 0;
+ for (widget = w->widgets; widget->type != WWT_LAST; widget++) {
+ // Check if widget is outside the draw region
+ if (w->x + widget->left < dpi->x + dpi->width && w->x + widget->right > dpi->x)
+ if (w->y + widget->top < dpi->y + dpi->height && w->y + widget->bottom > dpi->y)
+ widget_draw(dpi, w, widgetIndex);
+
+ widgetIndex++;
+ }
}
\ No newline at end of file
diff --git a/src/window.h b/src/window.h
index 704c4fc04b..b962edbb3e 100644
--- a/src/window.h
+++ b/src/window.h
@@ -77,12 +77,12 @@ typedef struct {
enum {
HSCROLLBAR_VISIBLE = (1 << 0),
- HSCROLLBAR_LEFT_PRESSED = (1 << 1),
- HSCROLLBAR_THUMB_PRESSED = (1 << 2),
+ HSCROLLBAR_THUMB_PRESSED = (1 << 1),
+ HSCROLLBAR_LEFT_PRESSED = (1 << 2),
HSCROLLBAR_RIGHT_PRESSED = (1 << 3),
VSCROLLBAR_VISIBLE = (1 << 4),
- VSCROLLBAR_UP_PRESSED = (1 << 5),
- VSCROLLBAR_THUMB_PRESSED = (1 << 6),
+ VSCROLLBAR_THUMB_PRESSED = (1 << 5),
+ VSCROLLBAR_UP_PRESSED = (1 << 6),
VSCROLLBAR_DOWN_PRESSED = (1 << 7),
};
@@ -158,8 +158,8 @@ typedef struct rct_window {
sint16 var_4B4;
rct_windowclass classification; // 0x4B6
uint8 pad_4B7;
- uint8 var_4B8;
- uint8 var_4B9;
+ sint8 var_4B8;
+ sint8 var_4B9;
uint8 colours[6]; // 0x4BA
} rct_window;