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;