From 5c5c5373cdf96b0a6d324e25abc1a89c2e850eed Mon Sep 17 00:00:00 2001 From: ddevrien Date: Sun, 11 May 2014 10:51:05 +0200 Subject: [PATCH 1/7] Implemented checkbox widget draw function --- src/widget.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/src/widget.c b/src/widget.c index c476beed44..c2d386e705 100644 --- a/src/widget.c +++ b/src/widget.c @@ -37,6 +37,7 @@ static void widget_text_inset(rct_drawpixelinfo *dpi, rct_window *w, int widgetI static void widget_text_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex); static void widget_groupbox_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_checkbox_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); @@ -154,6 +155,8 @@ void widget_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex) widget_scroll_draw(dpi, w, widgetIndex); break; case WWT_CHECKBOX: + widget_checkbox_draw(dpi, w, widgetIndex); + break; case WWT_24: break; case WWT_25: @@ -711,6 +714,46 @@ static void widget_closebox_draw(rct_drawpixelinfo *dpi, rct_window *w, int widg gfx_draw_string_centred_clipped(dpi, widget->image, (void*)0x013CE952, colour, l, t, widget->right - widget->left - 2); } +/** +* +* rct2: 0x006EBAD9 +*/ +static void widget_checkbox_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex) +{ + rct_widget* widget; + int l, t, b; + uint8 colour; + + // Get the widget + widget = &w->widgets[widgetIndex]; + + // Resolve the absolute ltb + l = w->x + widget->left; + t = w->y + widget->top; + b = w->y + widget->bottom; + + // Get the colour + colour = w->colours[widget->colour]; + + // checkbox + gfx_fill_rect_inset(dpi, l, t, l + 9, b - 1, colour, 0x60); + + // fill it when checkbox is pressed + if (widget_is_pressed(w, widgetIndex)) { + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16) = 224; + gfx_draw_string(dpi, (char*)0x009DED72, colour & 0x7F, l, t); + } + + // draw the text + if (widget->image == -1) + return; + + if (widget_is_disabled(w, widgetIndex)) { + colour |= 0x40; + } + gfx_draw_string_left(dpi, widget->image, (char*)0x013CE952, colour, l + 14, t); +} + /** * * rct2: 0x006EBD96 From 52c95e415417d96524261caaaa02610995cd4583 Mon Sep 17 00:00:00 2001 From: ddevrien Date: Sun, 11 May 2014 10:57:56 +0200 Subject: [PATCH 2/7] little addition to checkbox widget --- src/widget.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/widget.c b/src/widget.c index c2d386e705..5da914bf7e 100644 --- a/src/widget.c +++ b/src/widget.c @@ -736,12 +736,14 @@ static void widget_checkbox_draw(rct_drawpixelinfo *dpi, rct_window *w, int widg colour = w->colours[widget->colour]; // checkbox - gfx_fill_rect_inset(dpi, l, t, l + 9, b - 1, colour, 0x60); + if (widget->type != WWT_24) { + gfx_fill_rect_inset(dpi, l, t, l + 9, b - 1, colour, 0x60); - // fill it when checkbox is pressed - if (widget_is_pressed(w, widgetIndex)) { - RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16) = 224; - gfx_draw_string(dpi, (char*)0x009DED72, colour & 0x7F, l, t); + // fill it when checkbox is pressed + if (widget_is_pressed(w, widgetIndex)) { + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16) = 224; + gfx_draw_string(dpi, (char*)0x009DED72, colour & 0x7F, l, t); + } } // draw the text From cd8587243ca353d579e8737d196fd36919d00503 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Sun, 11 May 2014 13:14:43 +0100 Subject: [PATCH 3/7] Initial rewrite of gfx_draw_line --- src/gfx.c | 116 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 115 insertions(+), 1 deletion(-) diff --git a/src/gfx.c b/src/gfx.c index 022b35e1a2..41d464030a 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -98,6 +98,48 @@ void gfx_draw_pixel(rct_drawpixelinfo *dpi, int x, int y, int colour) gfx_fill_rect(dpi, x, y, x, y, colour); } +/* +* rct2: 0x68474C +*/ +void gfx_draw_line_on_buffer(int edi, int ebp, int esi) +{ + //edi ebp + //int edi, ebp, esi; + edi -= RCT2_GLOBAL(0x9ABDBE, sint16); + + if (edi < 0)return; + if (edi >= RCT2_GLOBAL(0x9ABDC2, sint16))return; + + if (!ebp) return; + + ebp++; + esi -= RCT2_GLOBAL(0x9ABDBC, sint16); + if (esi < 0){ + ebp += esi; + if (ebp <= 0)return; + esi = 0; + } + + int eax = esi; + eax += ebp; + eax -= RCT2_GLOBAL(0x9ABDC0, sint16); + if (eax > 0){ + ebp -= eax; + return; + } + eax = RCT2_GLOBAL(0x9ABDC4, sint16); + eax += RCT2_GLOBAL(0x9ABDC0, sint16); + edi *= eax; + edi += esi; + edi += RCT2_GLOBAL(0x9ABDB8, sint32); + eax = RCT2_GLOBAL(0xEDF84A,uint16); + for (int i = 0; i < ebp; ++i){ + *((uint8*)edi) = eax; + edi++; + } +} + + /** * * rct2: 0x00684466 @@ -110,7 +152,79 @@ void gfx_draw_pixel(rct_drawpixelinfo *dpi, int x, int y, int colour) */ void gfx_draw_line(rct_drawpixelinfo *dpi, int x1, int y1, int x2, int y2, int colour) { - RCT2_CALLPROC_X(0x00684466, x1, y1, x2, y2, 0, dpi, colour); + //RCT2_CALLPROC_X(0x00684466, x1, y1, x2, y2, 0, dpi, colour); + + if ((x1 < dpi->x) && (x2 < dpi->x)){ + return;//jump to 0x68474B + } + + if ((y1 < dpi->y) && (y2 < dpi->y)){ + return;//jump to 0x68474B + } + + if ((x1 <= (dpi->x + dpi->width)) && (x2 <= (dpi->x + dpi->width))){ + return;//jump to 0x68474B + } + + if ((y1 <= (dpi->y + dpi->height)) && (y2 <= (dpi->y + dpi->height))){ + return;//jump to 0x68474B + } + + RCT2_GLOBAL(0xEDF84A, uint16) = (uint16)(0xFFFF & colour); + + int bits_pointer; + bits_pointer = dpi->bits; + RCT2_GLOBAL(0x9ABDB8, uint32) = bits_pointer; + RCT2_GLOBAL(0x9ABDBC, uint16) = dpi->x; + RCT2_GLOBAL(0x9ABDBE, uint16) = dpi->y; + RCT2_GLOBAL(0x9ABDC0, uint16) = dpi->width; + RCT2_GLOBAL(0x9ABDC2, uint16) = dpi->height; + RCT2_GLOBAL(0x9ABDC4, uint16) = dpi->pitch; + + int edi = y1; + int esi = x1; + int ebp = colour & 0xFFFF; + int cx = x2 - x1; + if (cx < 0){ + //jump 0x684633 + } + int ax = cx; + int dx = y2 - y1; + if (dx < 0){ + //jump 0x6845AB + } + RCT2_GLOBAL(0xEDF846, uint16) = cx; + RCT2_GLOBAL(0xEDF848, uint16) = dx; + if (dx > cx){ + //jump 0x68456A + } + ax--; + if (ax < 0){ + return;//jump 0x684568 + } + cx /= 2; + cx = -cx; + ebp = 0; + + for (int i = ax; i >= 0; i--){ + ebp++; + cx += RCT2_GLOBAL(0xEDF848, sint16); + if (cx <= 0){ + i--; + if (i < 0){ + gfx_draw_line_on_buffer(edi, ebp, esi); + return; + } + continue; + } + cx -= RCT2_GLOBAL(0xEDF846, sint16); + gfx_draw_line_on_buffer(edi, ebp, esi); + esi += ebp; + edi++; + ebp = 0; + } + return; + } /** From 0ba23fe88633a02de5aa11c8da0e3d98c1f0434d Mon Sep 17 00:00:00 2001 From: ddevrien Date: Sun, 11 May 2014 17:24:52 +0200 Subject: [PATCH 4/7] Some work on options window --- src/addresses.h | 3 + src/strings.h | 24 +++- src/widget.c | 3 +- src/window_dropdown.c | 10 +- src/window_dropdown.h | 2 +- src/window_game_top_toolbar.c | 4 +- src/window_options.c | 206 ++++++++++++++++++++++++---------- 7 files changed, 176 insertions(+), 76 deletions(-) diff --git a/src/addresses.h b/src/addresses.h index a23cc338b0..fab898085c 100644 --- a/src/addresses.h +++ b/src/addresses.h @@ -119,6 +119,9 @@ #define RCT2_ADDRESS_WINDOW_DPI 0x009DEA74 +#define RCT2_ADDRESS_NUM_DSOUND_DEVICES 0x009E2B88 +#define RCT2_ADDRESS_DSOUND_DEVICES 0x009E2B8C + #define RCT2_ADDRESS_CMDLINE 0x009E2D98 #define RCT2_ADDRESS_LAND_RAISE_COST 0x009E2E1C diff --git a/src/strings.h b/src/strings.h index 945299c8c4..c2d2a5e520 100644 --- a/src/strings.h +++ b/src/strings.h @@ -217,6 +217,8 @@ enum { STR_PLACE_SCENERY_TIP = 1159, STR_ADJUST_WATER_TIP = 1160, + STR_OPTIONS = 1168, + STR_BUILD_FOOTPATH_TIP = 1173, STR_CANT_BUILD_FOOTPATH_HERE = 1176, STR_CANT_REMOVE_FOOTPATH_FROM_HERE = 1177, @@ -362,9 +364,14 @@ enum { STR_DISTANCE_AND_SPEED = 2329, STR_TEMPERATURE = 2330, STR_HEIGHT_LABELS = 2331, + STR_UNITS = 2332, + STR_SOUND = 2333, + STR_DISPLAY = 2346, STR_DISPLAY_RESOLUTION = 2360, - STR_TILE_EDGE_SMOOTHING_TIP = 2362, - STR_TURN_GRIDLINES_ON_TIP = 2364, + STR_TILE_SMOOTHING = 2361, + STR_TILE_SMOOTHING_TIP = 2362, + STR_GRIDLINES = 2363, + STR_GRIDLINES_TIP = 2364, //STR_NONE = 2368, STR_LOW = 2369, @@ -415,7 +422,11 @@ enum { STR_PROFIT_PER_WEEK_AND_PARK_VALUE_TIP = 2482, - STR_REAL_NAME_TOGGLE_TIP = 2488, + STR_CONTROLS = 2485, + STR_GENERAL = 2486, + STR_REAL_NAME = 2487, + STR_REAL_NAME_TIP = 2488, + STR_HOTKEY = 2489, STR_ENTER_NAME_INTO_SCENARIO_CHART = 2790, @@ -423,8 +434,9 @@ enum { STR_SORT = 2795, STR_RIDE_LIST_SORT_TIP = 2796, - STR_SCREEN_EDGE_SCROLL_TIP = 2798, - STR_CHANGE_HOTKEY_TIP = 2799, + STR_SCREEN_EDGE_SCROLLING = 2797, + STR_SCREEN_EDGE_SCROLLING_TIP = 2798, + STR_HOTKEY_TIP = 2799, STR_TOTAL_ADMISSIONS = 2800, STR_INCOME_FROM_ADMISSIONS = 2801, @@ -510,6 +522,7 @@ enum { STR_OBJECTIVE = 3322, + STR_SAVE_PLUGIN_DATA = 3333, STR_SAVE_PLUGIN_DATA_TIP = 3334, STR_GAME_TOOLS = 3341, @@ -518,6 +531,7 @@ enum { STR_ROLLER_COASTER_DESIGNER = 3344, STR_TRACK_DESIGNS_MANAGER = 3345, + STR_SOUND_FORCED_SOFTWARE_BUFFER_MIXING = 3362, STR_SOUND_FORCED_SOFTWARE_BUFFER_MIXING_TIP = 3363, STR_TUTORIAL_BEGINNERS = 3385, diff --git a/src/widget.c b/src/widget.c index 5da914bf7e..3aa909e355 100644 --- a/src/widget.c +++ b/src/widget.c @@ -155,9 +155,8 @@ void widget_draw(rct_drawpixelinfo *dpi, rct_window *w, int widgetIndex) widget_scroll_draw(dpi, w, widgetIndex); break; case WWT_CHECKBOX: - widget_checkbox_draw(dpi, w, widgetIndex); - break; case WWT_24: + widget_checkbox_draw(dpi, w, widgetIndex); break; case WWT_25: break; diff --git a/src/window_dropdown.c b/src/window_dropdown.c index 9050dd6c64..14c27202a2 100644 --- a/src/window_dropdown.c +++ b/src/window_dropdown.c @@ -51,7 +51,7 @@ int _dropdown_item_height; int _dropdown_highlighted_index; uint16 gDropdownItemsFormat[64]; -sint32 gDropdownItemsArgs[64]; +sint64 gDropdownItemsArgs[64]; uint32 gDropdownItemsChecked; static void window_dropdown_emptysub() { } @@ -134,8 +134,8 @@ void window_dropdown_show_text_custom_width(int x, int y, int extray, uint8 colo char buffer[256]; // Copy the formats and arguments until all use of it is decompiled - memcpy(0x009DEBA4, gDropdownItemsFormat, 37 * 2); - memcpy(0x009DEBF4, gDropdownItemsArgs, 80 * 4); + memcpy(0x009DEBA4, gDropdownItemsFormat, 40 * 2); + memcpy(0x009DEBF4, gDropdownItemsArgs, 40 * 8); RCT2_GLOBAL(0x009DE518, uint32) &= ~(0x04 | 0x02); if (flags & 0x80) @@ -203,8 +203,8 @@ void window_dropdown_show_image(int x, int y, int extray, uint8 colour, uint8 fl rct_window* w; // Copy the formats and arguments until all use of it is decompiled - memcpy(0x009DEBA4, gDropdownItemsFormat, 37 * 2); - memcpy(0x009DEBF4, gDropdownItemsArgs, 80 * 4); + memcpy(0x009DEBA4, gDropdownItemsFormat, 40 * 2); + memcpy(0x009DEBF4, gDropdownItemsArgs, 40 * 8); RCT2_GLOBAL(0x009DE518, uint32) &= ~(0x04 | 0x02); if (flags & 0x80) diff --git a/src/window_dropdown.h b/src/window_dropdown.h index 14d47a8920..b98598abac 100644 --- a/src/window_dropdown.h +++ b/src/window_dropdown.h @@ -28,7 +28,7 @@ extern int gAppropriateImageDropdownItemsPerRow[]; extern uint16 gDropdownItemsFormat[64]; -extern sint32 gDropdownItemsArgs[64]; +extern sint64 gDropdownItemsArgs[64]; extern uint32 gDropdownItemsChecked; void window_dropdown_show_text(int x, int y, int extray, uint8 colour, uint8 flags, int num_items); diff --git a/src/window_game_top_toolbar.c b/src/window_game_top_toolbar.c index f4c8b26890..d64bb1b862 100644 --- a/src/window_game_top_toolbar.c +++ b/src/window_game_top_toolbar.c @@ -377,8 +377,8 @@ static void window_game_top_toolbar_dropdown() window_about_open(); break; case 4: // options - //window_options_open(); - RCT2_CALLPROC_EBPSAFE(0x006BAC5B); + window_options_open(); + //RCT2_CALLPROC_EBPSAFE(0x006BAC5B); break; case 5: // screenshot RCT2_GLOBAL(RCT2_ADDRESS_SCREENSHOT_COUNTDOWN, sint8) = 10; diff --git a/src/window_options.c b/src/window_options.c index 6899affa08..a9f81e2eeb 100644 --- a/src/window_options.c +++ b/src/window_options.c @@ -22,56 +22,78 @@ #include "strings.h" #include "widget.h" #include "window.h" +#include "window_dropdown.h" static enum WINDOW_OPTIONS_WIDGET_IDX { WIDX_BACKGROUND, WIDX_TITLE, WIDX_CLOSE, - WIDX_SOUND_DROPDOWN = 5, - WIDX_MUSIC = 6, - WIDX_SOUND_QUALITY = 8, - WIDX_CURRENCY = 12, - WIDX_DISTANCE = 14, - WIDX_TEMPERATURE = 16, - WIDX_HEIGHT_LABELS = 18, - WIDX_RESOLUTION = 21, - WIDX_CONSTRUCTION_MARKER = 25 + WIDX_SOUND_GROUP, + WIDX_SOUND, + WIDX_SOUND_DROPDOWN, + WIDX_MUSIC, + WIDX_MUSIC_DROPDOWN, + WIDX_SOUND_QUALITY, + WIDX_SOUND_QUALITY_DROPDOWN, + WIDX_SOUND_SW_BUFFER_CHECKBOX, + WIDX_UNITS_GROUP, + WIDX_CURRENCY, + WIDX_CURRENCY_DROPDOWN, + WIDX_DISTANCE, + WIDX_DISTANCE_DROPDOWN, + WIDX_TEMPERATURE, + WIDX_TEMPERATURE_DROPDOWN, + WIDX_HEIGHT_LABELS, + WIDX_HEIGHT_LABELS_DROPDOWN, + WIDX_DISPLAY_GROUP, + WIDX_RESOLUTION, + WIDX_RESOLUTION_DROPDOWN, + WIDX_TILE_SMOOTHING_CHECKBOX, + WIDX_GRIDLINES_CHECKBOX, + WIDX_CONSTRUCTION_MARKER, + WIDX_CONSTRUCTION_MARKER_DROPDOWN, + WIDX_CONTROLS_GROUP, + WIDX_SCREEN_EDGE_SCROLLING, + WIDX_HOTKEY_DROPDOWN, + WIDX_GENERAL_GROUP, + WIDX_REAL_NAME_CHECKBOX, + WIDX_SAVE_PLUGIN_DATA_CHECKBOX }; static rct_widget window_options_widgets[] = { - { WWT_FRAME, 0, 0, 309, 0, 371, 0x0FFFFFFFF, STR_NONE }, - { WWT_CAPTION, 0, 1, 308, 1, 14, 0x490, STR_WINDOW_TITLE_TIP }, - { WWT_CLOSEBOX, 0, 297, 307, 2, 13, 0x338, STR_CLOSE_WINDOW_TIP }, - { WWT_GROUPBOX, 0, 3, 306, 17, 93, 0x91D, STR_NONE }, - { WWT_DROPDOWN, 0, 10, 299, 31, 42, 0x361, STR_NONE }, + { WWT_FRAME, 0, 0, 309, 0, 371, STR_NONE, STR_NONE }, + { WWT_CAPTION, 0, 1, 308, 1, 14, STR_OPTIONS, STR_WINDOW_TITLE_TIP }, + { WWT_CLOSEBOX, 0, 297, 307, 2, 13, STR_CLOSE_X, STR_CLOSE_WINDOW_TIP }, + { WWT_GROUPBOX, 0, 3, 306, 17, 93, STR_SOUND, STR_NONE }, + { WWT_DROPDOWN, 0, 10, 299, 31, 42, 0x361, STR_NONE }, // sound { WWT_DROPDOWN_BUTTON, 0, 288, 298, 32, 41, 0x36C, STR_NONE }, - { WWT_DROPDOWN, 0, 155, 299, 46, 57, 0x365, STR_NONE }, + { WWT_DROPDOWN, 0, 155, 299, 46, 57, 0x365, STR_NONE }, // music { WWT_DROPDOWN_BUTTON, 0, 288, 298, 47, 56, 0x36C, STR_NONE }, - { WWT_DROPDOWN, 0, 155, 299, 61, 72, 0x366, STR_NONE }, + { WWT_DROPDOWN, 0, 155, 299, 61, 72, 0x366, STR_NONE }, // sound quality { WWT_DROPDOWN_BUTTON, 0, 288, 298, 62, 71, 0x36C, STR_NONE }, - { WWT_CHECKBOX, 0, 10, 299, 76, 87, 0x0D22, STR_SOUND_FORCED_SOFTWARE_BUFFER_MIXING_TIP }, - { WWT_GROUPBOX, 0, 3, 306, 100, 176, 0x91C, STR_NONE }, - { WWT_DROPDOWN, 0, 155, 299, 114, 125, 0x367, STR_NONE }, + { WWT_CHECKBOX, 0, 10, 299, 76, 87, STR_SOUND_FORCED_SOFTWARE_BUFFER_MIXING, STR_SOUND_FORCED_SOFTWARE_BUFFER_MIXING_TIP }, + { WWT_GROUPBOX, 0, 3, 306, 100, 176, STR_UNITS, STR_NONE }, + { WWT_DROPDOWN, 0, 155, 299, 114, 125, 0x367, STR_NONE }, // currency { WWT_DROPDOWN_BUTTON, 0, 288, 298, 115, 124, 0x36C, STR_NONE }, - { WWT_DROPDOWN, 0, 155, 299, 129, 140, 0x368, STR_NONE }, + { WWT_DROPDOWN, 0, 155, 299, 129, 140, 0x368, STR_NONE }, // distance { WWT_DROPDOWN_BUTTON, 0, 288, 298, 130, 139, 0x36C, STR_NONE }, - { WWT_DROPDOWN, 0, 155, 299, 144, 155, 0x36B, STR_NONE }, + { WWT_DROPDOWN, 0, 155, 299, 144, 155, 0x36B, STR_NONE }, // temperature { WWT_DROPDOWN_BUTTON, 0, 288, 298, 145, 154, 0x36C, STR_NONE }, - { WWT_DROPDOWN, 0, 155, 299, 159, 170, 0x364, STR_NONE }, + { WWT_DROPDOWN, 0, 155, 299, 159, 170, 0x364, STR_NONE }, // height labels { WWT_DROPDOWN_BUTTON, 0, 288, 298, 160, 169, 0x36C, STR_NONE }, - { WWT_GROUPBOX, 0, 3, 306, 182, 258, 0x92A, STR_NONE }, - { WWT_DROPDOWN, 0, 155, 299, 196, 207, 0x348, STR_NONE }, + { WWT_GROUPBOX, 0, 3, 306, 182, 258, STR_DISPLAY, STR_NONE }, + { WWT_DROPDOWN, 0, 155, 299, 196, 207, 0x348, STR_NONE }, // resolution { WWT_DROPDOWN_BUTTON, 0, 288, 298, 197, 206, 0x36C, STR_NONE }, - { WWT_CHECKBOX, 0, 10, 299, 212, 223, 0x939, STR_TILE_EDGE_SMOOTHING_TIP }, - { WWT_CHECKBOX, 0, 10, 299, 227, 238, 0x93B, STR_TURN_GRIDLINES_ON_TIP }, - { WWT_DROPDOWN, 0, 155, 299, 241, 252, 0x0FFFFFFFF, STR_NONE }, + { WWT_CHECKBOX, 0, 10, 299, 212, 223, STR_TILE_SMOOTHING, STR_TILE_SMOOTHING_TIP }, + { WWT_CHECKBOX, 0, 10, 299, 227, 238, STR_GRIDLINES, STR_GRIDLINES_TIP }, + { WWT_DROPDOWN, 0, 155, 299, 241, 252, STR_NONE, STR_NONE }, // construction marker { WWT_DROPDOWN_BUTTON, 0, 288, 298, 242, 251, 0x36C, STR_NONE }, - { WWT_GROUPBOX, 0, 3, 306, 264, 310, 0x9B5, STR_NONE }, - { WWT_CHECKBOX, 2, 10, 299, 279, 290, 0x0AED, STR_SCREEN_EDGE_SCROLL_TIP }, - { WWT_DROPDOWN_BUTTON, 0, 26, 185, 293, 304, 0x9B9, STR_CHANGE_HOTKEY_TIP }, - { WWT_GROUPBOX, 0, 3, 306, 317, 365, 0x9B6, STR_NONE }, - { WWT_CHECKBOX, 2, 10, 299, 331, 342, 0x9B7, STR_REAL_NAME_TOGGLE_TIP }, - { WWT_CHECKBOX, 2, 10, 299, 346, 357, 0x0D05, STR_SAVE_PLUGIN_DATA_TIP }, + { WWT_GROUPBOX, 0, 3, 306, 264, 310, STR_CONTROLS, STR_NONE }, + { WWT_CHECKBOX, 2, 10, 299, 279, 290, STR_SCREEN_EDGE_SCROLLING, STR_SCREEN_EDGE_SCROLLING_TIP }, + { WWT_DROPDOWN_BUTTON, 0, 26, 185, 293, 304, STR_HOTKEY, STR_HOTKEY_TIP }, + { WWT_GROUPBOX, 0, 3, 306, 317, 365, STR_GENERAL, STR_NONE }, + { WWT_CHECKBOX, 2, 10, 299, 331, 342, STR_REAL_NAME, STR_REAL_NAME_TIP }, + { WWT_CHECKBOX, 2, 10, 299, 346, 357, STR_SAVE_PLUGIN_DATA, STR_SAVE_PLUGIN_DATA_TIP }, { WIDGETS_END }, }; @@ -79,7 +101,6 @@ static void window_options_emptysub() { } static void window_options_mouseup(); static void window_options_mousedown(); static void window_options_dropdown(); -static void window_options_textinput(); static void window_options_update(); static void window_options_paint(); @@ -129,32 +150,32 @@ void window_options_open() w = window_create_auto_pos(310, 372, window_options_events, WC_OPTIONS, 0); w->widgets = window_options_widgets; - w->enabled_widgets = - (1 << WIDX_CLOSE) | - 0x10 | + w->enabled_widgets = + (1 << WIDX_CLOSE) | + (1 << WIDX_SOUND) | (1 << WIDX_SOUND_DROPDOWN) | - 0x40 | - 0x80 | - 0x100 | - 0x200 | - 0x1000 | - 0x2000 | - 0x4000 | - 0x8000 | - 0x200000 | - 0x400000 | - 0x10000 | - 0x20000 | - 0x20000000 | - 0x10000000 | - 0x80000000 | - 0x2000000 | - 0x4000000 | - 0x40000 | - 0x80000 | - 0x800000 | - 0x1000000 | - 0x400; + (1 << WIDX_MUSIC) | + (1 << WIDX_MUSIC_DROPDOWN) | + (1 << WIDX_SOUND_QUALITY) | + (1 << WIDX_SOUND_QUALITY_DROPDOWN) | + (1 << WIDX_CURRENCY) | + (1 << WIDX_CURRENCY_DROPDOWN) | + (1 << WIDX_DISTANCE) | + (1 << WIDX_DISTANCE_DROPDOWN) | + (1 << WIDX_RESOLUTION) | + (1 << WIDX_RESOLUTION_DROPDOWN) | + (1 << WIDX_TEMPERATURE) | + (1 << WIDX_TEMPERATURE_DROPDOWN) | + (1 << WIDX_HOTKEY_DROPDOWN) | + (1 << WIDX_SCREEN_EDGE_SCROLLING) | + (1 << WIDX_REAL_NAME_CHECKBOX) | + (1 << WIDX_CONSTRUCTION_MARKER) | + (1 << WIDX_CONSTRUCTION_MARKER_DROPDOWN) | + (1 << WIDX_HEIGHT_LABELS) | + (1 << WIDX_HEIGHT_LABELS_DROPDOWN) | + (1 << WIDX_TILE_SMOOTHING_CHECKBOX) | + (1 << WIDX_GRIDLINES_CHECKBOX) | + (1 << WIDX_SOUND_SW_BUFFER_CHECKBOX); // TODO: missing .text:006BAD22 or dword ptr [esi+0Ch], 1 window_init_scroll_widgets(w); @@ -178,7 +199,70 @@ static void window_options_mouseup() */ static void window_options_mousedown() { - RCT2_CALLPROC_EBPSAFE(0x006BB01B); + //RCT2_CALLPROC_EBPSAFE(0x006BB01B); + int numItems, i; + sint64 device; + short widgetIndex; + rct_window *w; + rct_widget *widget; + + __asm mov widgetIndex, dx + __asm mov w, esi + + widget = &w->widgets[widgetIndex - 1]; + + switch (widgetIndex) { + case WIDX_SOUND_DROPDOWN: + numItems = RCT2_GLOBAL(RCT2_ADDRESS_NUM_DSOUND_DEVICES, uint32); + if (numItems == 0) + break; + + window_dropdown_show_text_custom_width( + w->x + widget->left, + w->y + widget->top, + widget->bottom - widget->top + 1, + w->colours[1], + 0x80, + numItems, + widget->right - widget->left - 3 + ); + + // populate the list with the sound devices + device = RCT2_GLOBAL(RCT2_ADDRESS_DSOUND_DEVICES, sint32) + 0x10; + + for (i = 0; i < numItems; i++) { + gDropdownItemsFormat[i] = 1142; + gDropdownItemsArgs[i] = 1170 | (device << 16); + device += 0x210; + } + gDropdownItemsChecked |= (1 << RCT2_GLOBAL(0x9AF280, uint32)); + + break; + case WIDX_HEIGHT_LABELS_DROPDOWN: + RCT2_CALLPROC_EBPSAFE(0x006BB517); + break; + case WIDX_MUSIC_DROPDOWN: + RCT2_CALLPROC_EBPSAFE(0x006BB5A8); + break; + case WIDX_SOUND_QUALITY_DROPDOWN: + RCT2_CALLPROC_EBPSAFE(0x006BB631); + break; + case WIDX_CURRENCY_DROPDOWN: + RCT2_CALLPROC_EBPSAFE(0x006BB494); + break; + case WIDX_DISTANCE_DROPDOWN: + RCT2_CALLPROC_EBPSAFE(0x006BB3E6); + break; + case WIDX_RESOLUTION_DROPDOWN: + RCT2_CALLPROC_EBPSAFE(0x006BB2AF); + break; + case WIDX_TEMPERATURE_DROPDOWN: + RCT2_CALLPROC_EBPSAFE(0x006BB21F); + break; + case WIDX_CONSTRUCTION_MARKER_DROPDOWN: + RCT2_CALLPROC_EBPSAFE(0x006BB18F); + break; + } } /** @@ -245,4 +329,4 @@ static void window_options_paint() w->y + window_options_widgets[WIDX_MUSIC].top + 1); gfx_draw_string_left(dpi, STR_SOUND_QUALITY, w, 0, w->x + 10, w->y + window_options_widgets[WIDX_SOUND_QUALITY].top + 1); -} +} \ No newline at end of file From bf8a032553152683ad56f9de1b9541f219ad379f Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Sun, 11 May 2014 16:50:29 +0100 Subject: [PATCH 5/7] fix dropdown argument arrays --- src/window_dropdown.c | 10 +++++----- src/window_dropdown.h | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/window_dropdown.c b/src/window_dropdown.c index 9050dd6c64..14c27202a2 100644 --- a/src/window_dropdown.c +++ b/src/window_dropdown.c @@ -51,7 +51,7 @@ int _dropdown_item_height; int _dropdown_highlighted_index; uint16 gDropdownItemsFormat[64]; -sint32 gDropdownItemsArgs[64]; +sint64 gDropdownItemsArgs[64]; uint32 gDropdownItemsChecked; static void window_dropdown_emptysub() { } @@ -134,8 +134,8 @@ void window_dropdown_show_text_custom_width(int x, int y, int extray, uint8 colo char buffer[256]; // Copy the formats and arguments until all use of it is decompiled - memcpy(0x009DEBA4, gDropdownItemsFormat, 37 * 2); - memcpy(0x009DEBF4, gDropdownItemsArgs, 80 * 4); + memcpy(0x009DEBA4, gDropdownItemsFormat, 40 * 2); + memcpy(0x009DEBF4, gDropdownItemsArgs, 40 * 8); RCT2_GLOBAL(0x009DE518, uint32) &= ~(0x04 | 0x02); if (flags & 0x80) @@ -203,8 +203,8 @@ void window_dropdown_show_image(int x, int y, int extray, uint8 colour, uint8 fl rct_window* w; // Copy the formats and arguments until all use of it is decompiled - memcpy(0x009DEBA4, gDropdownItemsFormat, 37 * 2); - memcpy(0x009DEBF4, gDropdownItemsArgs, 80 * 4); + memcpy(0x009DEBA4, gDropdownItemsFormat, 40 * 2); + memcpy(0x009DEBF4, gDropdownItemsArgs, 40 * 8); RCT2_GLOBAL(0x009DE518, uint32) &= ~(0x04 | 0x02); if (flags & 0x80) diff --git a/src/window_dropdown.h b/src/window_dropdown.h index 14d47a8920..b98598abac 100644 --- a/src/window_dropdown.h +++ b/src/window_dropdown.h @@ -28,7 +28,7 @@ extern int gAppropriateImageDropdownItemsPerRow[]; extern uint16 gDropdownItemsFormat[64]; -extern sint32 gDropdownItemsArgs[64]; +extern sint64 gDropdownItemsArgs[64]; extern uint32 gDropdownItemsChecked; void window_dropdown_show_text(int x, int y, int extray, uint8 colour, uint8 flags, int num_items); From 45532da9c6bca80698190e6651cbae6895ffad3b Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Sun, 11 May 2014 20:10:32 +0100 Subject: [PATCH 6/7] Rewrote gfx_draw_line_on_buffer after realising how it works --- src/gfx.c | 126 ++++++++++++++++++++++++++++------------------ src/window_park.c | 1 - 2 files changed, 78 insertions(+), 49 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 41d464030a..7beb9bb6a7 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -99,43 +99,46 @@ void gfx_draw_pixel(rct_drawpixelinfo *dpi, int x, int y, int colour) } /* +* Draws a horizontal line of specified colour to a buffer. * rct2: 0x68474C */ -void gfx_draw_line_on_buffer(int edi, int ebp, int esi) +void gfx_draw_line_on_buffer(rct_drawpixelinfo *dpi, char colour, int y, int x, int no_pixels) { - //edi ebp - //int edi, ebp, esi; - edi -= RCT2_GLOBAL(0x9ABDBE, sint16); + y -= dpi->y; - if (edi < 0)return; - if (edi >= RCT2_GLOBAL(0x9ABDC2, sint16))return; + //Check to make sure point is in the y range + if (y < 0)return; + if (y >= dpi->height)return; + //Check to make sure we are drawing at least a pixel + if (!no_pixels) return; - if (!ebp) return; + no_pixels++; + x -= dpi->x; - ebp++; - esi -= RCT2_GLOBAL(0x9ABDBC, sint16); - if (esi < 0){ - ebp += esi; - if (ebp <= 0)return; - esi = 0; + //If x coord outside range leave + if (x < 0){ + //Unless the number of pixels is enough to be in range + no_pixels += x; + if (no_pixels <= 0)return; + //Resets starting point to 0 as we don't draw outside the range + x = 0; } - int eax = esi; - eax += ebp; - eax -= RCT2_GLOBAL(0x9ABDC0, sint16); - if (eax > 0){ - ebp -= eax; - return; + //Ensure that the end point of the line is within range + if (x + no_pixels - dpi->width > 0){ + //If the end point has any pixels outside range + //cut them off. If there are now no pixels return. + no_pixels -= x + no_pixels - dpi->width; + if (no_pixels <= 0)return; } - eax = RCT2_GLOBAL(0x9ABDC4, sint16); - eax += RCT2_GLOBAL(0x9ABDC0, sint16); - edi *= eax; - edi += esi; - edi += RCT2_GLOBAL(0x9ABDB8, sint32); - eax = RCT2_GLOBAL(0xEDF84A,uint16); - for (int i = 0; i < ebp; ++i){ - *((uint8*)edi) = eax; - edi++; + + char* bits_pointer; + //Get the buffer we are drawing to and move to the first coordinate. + bits_pointer = dpi->bits + y*(dpi->pitch + dpi->width) + x; + + //Draw the line to the specified colour + for (; no_pixels > 0; --no_pixels, ++bits_pointer){ + *((uint8*)bits_pointer) = colour; } } @@ -153,6 +156,7 @@ void gfx_draw_line_on_buffer(int edi, int ebp, int esi) void gfx_draw_line(rct_drawpixelinfo *dpi, int x1, int y1, int x2, int y2, int colour) { //RCT2_CALLPROC_X(0x00684466, x1, y1, x2, y2, 0, dpi, colour); + //return; if ((x1 < dpi->x) && (x2 < dpi->x)){ return;//jump to 0x68474B @@ -162,11 +166,11 @@ void gfx_draw_line(rct_drawpixelinfo *dpi, int x1, int y1, int x2, int y2, int c return;//jump to 0x68474B } - if ((x1 <= (dpi->x + dpi->width)) && (x2 <= (dpi->x + dpi->width))){ + if ((x1 > (dpi->x + dpi->width)) && (x2 > (dpi->x + dpi->width))){ return;//jump to 0x68474B } - if ((y1 <= (dpi->y + dpi->height)) && (y2 <= (dpi->y + dpi->height))){ + if ((y1 > (dpi->y + dpi->height)) && (y2 > (dpi->y + dpi->height))){ return;//jump to 0x68474B } @@ -184,41 +188,67 @@ void gfx_draw_line(rct_drawpixelinfo *dpi, int x1, int y1, int x2, int y2, int c int edi = y1; int esi = x1; int ebp = colour & 0xFFFF; - int cx = x2 - x1; - if (cx < 0){ - //jump 0x684633 + int x_diff, y_diff; + x_diff = x2 - x1; + + if (x1 > x2){ + x_diff = -x_diff; + int ax = x_diff; + int dx = y2 - y1; + if (dx < 0){ + RCT2_CALLPROC_X(0x6846C5, ax, x2, x_diff, dx, esi, edi, ebp); + return; + //jump 0x6846C5 + } + RCT2_GLOBAL(0xEDF846, uint16) = x_diff; + RCT2_GLOBAL(0xEDF848, uint16) = y2 - y1; + if (dx > x_diff){ + RCT2_CALLPROC_X(0x684691, ax, x2, x_diff, dx, esi, edi, ebp); + return; + //jump 0x684691 + } + ax--; + if (ax < 0)return; + x_diff /= 2; + x_diff = -x_diff; + ebp = 0; + return;//not finished } - int ax = cx; - int dx = y2 - y1; - if (dx < 0){ + int ax = x_diff; + y_diff = y2 - y1; + if (y1 > y2){ + RCT2_CALLPROC_X(0x6845AB, ax, x2, x_diff, y_diff, esi, edi, ebp); + return; //jump 0x6845AB } - RCT2_GLOBAL(0xEDF846, uint16) = cx; - RCT2_GLOBAL(0xEDF848, uint16) = dx; - if (dx > cx){ + RCT2_GLOBAL(0xEDF846, uint16) = x_diff; + RCT2_GLOBAL(0xEDF848, uint16) = y_diff; + if ((y2 - y1) > (x2 - x1)){ + RCT2_CALLPROC_X(0x68456A, ax, x2, x_diff, y_diff, esi, edi, ebp); + return; //jump 0x68456A } ax--; if (ax < 0){ + RCT2_CALLPROC_X(0x684568, ax, x2, x_diff, y_diff, esi, edi, ebp); return;//jump 0x684568 } - cx /= 2; - cx = -cx; + x_diff /= 2; + x_diff = -x_diff; ebp = 0; for (int i = ax; i >= 0; i--){ ebp++; - cx += RCT2_GLOBAL(0xEDF848, sint16); - if (cx <= 0){ - i--; - if (i < 0){ - gfx_draw_line_on_buffer(edi, ebp, esi); + x_diff += y_diff; + if (x_diff <= 0){ + if (i-1 < 0){ + gfx_draw_line_on_buffer(dpi, (uint16)(0xFFFF & colour), edi, ebp, esi); return; } continue; } - cx -= RCT2_GLOBAL(0xEDF846, sint16); - gfx_draw_line_on_buffer(edi, ebp, esi); + x_diff -= x2 - x1; + gfx_draw_line_on_buffer(dpi, (uint16)(0xFFFF & colour), edi, ebp, esi); esi += ebp; edi++; ebp = 0; diff --git a/src/window_park.c b/src/window_park.c index e01ca4550a..6e3911f424 100644 --- a/src/window_park.c +++ b/src/window_park.c @@ -2139,7 +2139,6 @@ static void window_park_graph_draw_months(rct_drawpixelinfo *dpi, uint8 *history static void window_park_graph_draw_line_a(rct_drawpixelinfo *dpi, uint8 *history, int baseX, int baseY) { int i, x, y, lastX, lastY; - lastX = -1; x = baseX; for (i = 31; i >= 0; i--) { From 84342b07d20354a94ea5597be29c864640077a79 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Sun, 11 May 2014 21:25:18 +0100 Subject: [PATCH 7/7] Replaced decompiled code with bresenhams algorithm. Gfx_draw_line finished. --- src/gfx.c | 136 ++++++++++++++++++++++-------------------------------- 1 file changed, 54 insertions(+), 82 deletions(-) diff --git a/src/gfx.c b/src/gfx.c index 7beb9bb6a7..b2ba5158aa 100644 --- a/src/gfx.c +++ b/src/gfx.c @@ -144,7 +144,7 @@ void gfx_draw_line_on_buffer(rct_drawpixelinfo *dpi, char colour, int y, int x, /** - * + * Draws a line on dpi if within dpi boundaries * rct2: 0x00684466 * dpi (edi) * x1 (ax) @@ -155,106 +155,78 @@ void gfx_draw_line_on_buffer(rct_drawpixelinfo *dpi, char colour, int y, int x, */ void gfx_draw_line(rct_drawpixelinfo *dpi, int x1, int y1, int x2, int y2, int colour) { - //RCT2_CALLPROC_X(0x00684466, x1, y1, x2, y2, 0, dpi, colour); - //return; - + // Check to make sure the line is within the drawing area if ((x1 < dpi->x) && (x2 < dpi->x)){ - return;//jump to 0x68474B + return; } if ((y1 < dpi->y) && (y2 < dpi->y)){ - return;//jump to 0x68474B + return; } - if ((x1 > (dpi->x + dpi->width)) && (x2 > (dpi->x + dpi->width))){ - return;//jump to 0x68474B + if ((x1 >(dpi->x + dpi->width)) && (x2 >(dpi->x + dpi->width))){ + return; } if ((y1 > (dpi->y + dpi->height)) && (y2 > (dpi->y + dpi->height))){ - return;//jump to 0x68474B + return; } - RCT2_GLOBAL(0xEDF84A, uint16) = (uint16)(0xFFFF & colour); + //Bresenhams algorithm - int bits_pointer; - bits_pointer = dpi->bits; - RCT2_GLOBAL(0x9ABDB8, uint32) = bits_pointer; - RCT2_GLOBAL(0x9ABDBC, uint16) = dpi->x; - RCT2_GLOBAL(0x9ABDBE, uint16) = dpi->y; - RCT2_GLOBAL(0x9ABDC0, uint16) = dpi->width; - RCT2_GLOBAL(0x9ABDC2, uint16) = dpi->height; - RCT2_GLOBAL(0x9ABDC4, uint16) = dpi->pitch; - - int edi = y1; - int esi = x1; - int ebp = colour & 0xFFFF; - int x_diff, y_diff; - x_diff = x2 - x1; + //If vertical plot points upwards + int steep = abs(y2 - y1) > abs(x2 - x1); + if (steep){ + int temp_y2 = y2; + int temp_x2 = x2; + y2 = x1; + x2 = y1; + y1 = temp_x2; + x1 = temp_y2; + } + //If line is right to left swap direction if (x1 > x2){ - x_diff = -x_diff; - int ax = x_diff; - int dx = y2 - y1; - if (dx < 0){ - RCT2_CALLPROC_X(0x6846C5, ax, x2, x_diff, dx, esi, edi, ebp); - return; - //jump 0x6846C5 - } - RCT2_GLOBAL(0xEDF846, uint16) = x_diff; - RCT2_GLOBAL(0xEDF848, uint16) = y2 - y1; - if (dx > x_diff){ - RCT2_CALLPROC_X(0x684691, ax, x2, x_diff, dx, esi, edi, ebp); - return; - //jump 0x684691 - } - ax--; - if (ax < 0)return; - x_diff /= 2; - x_diff = -x_diff; - ebp = 0; - return;//not finished + int temp_y2 = y2; + int temp_x2 = x2; + y2 = y1; + x2 = x1; + y1 = temp_y2; + x1 = temp_x2; } - int ax = x_diff; - y_diff = y2 - y1; - if (y1 > y2){ - RCT2_CALLPROC_X(0x6845AB, ax, x2, x_diff, y_diff, esi, edi, ebp); - return; - //jump 0x6845AB - } - RCT2_GLOBAL(0xEDF846, uint16) = x_diff; - RCT2_GLOBAL(0xEDF848, uint16) = y_diff; - if ((y2 - y1) > (x2 - x1)){ - RCT2_CALLPROC_X(0x68456A, ax, x2, x_diff, y_diff, esi, edi, ebp); - return; - //jump 0x68456A - } - ax--; - if (ax < 0){ - RCT2_CALLPROC_X(0x684568, ax, x2, x_diff, y_diff, esi, edi, ebp); - return;//jump 0x684568 - } - x_diff /= 2; - x_diff = -x_diff; - ebp = 0; - for (int i = ax; i >= 0; i--){ - ebp++; - x_diff += y_diff; - if (x_diff <= 0){ - if (i-1 < 0){ - gfx_draw_line_on_buffer(dpi, (uint16)(0xFFFF & colour), edi, ebp, esi); - return; - } - continue; + int delta_x = x2 - x1; + int delta_y = abs(y2 - y1); + int error = delta_x / 2; + int y_step; + int y = y1; + + //Direction of step + if (y1 < y2)y_step = 1; + else y_step = -1; + + for (int x = x1, x_start = x1, no_pixels = 1; x < x2; ++x,++no_pixels){ + //Vertical lines are drawn 1 pixel at a time + if (steep)gfx_draw_line_on_buffer(dpi, colour, x, y, 1); + + error -= delta_y; + if (error < 0){ + //Non vertical lines are drawn with as many pixels in a horizontal line as possible + if (!steep)gfx_draw_line_on_buffer(dpi, colour, y, x_start, no_pixels); + + //Reset non vertical line vars + x_start = x + 1; + no_pixels = 1; + y += y_step; + error += delta_x; + } + + //Catch the case of the last line + if (x + 1 == x2 && !steep){ + gfx_draw_line_on_buffer(dpi, colour, y, x_start, no_pixels); } - x_diff -= x2 - x1; - gfx_draw_line_on_buffer(dpi, (uint16)(0xFFFF & colour), edi, ebp, esi); - esi += ebp; - edi++; - ebp = 0; } return; - } /**