From 5e51fc956beed3e307b512776a1fcc9962f82837 Mon Sep 17 00:00:00 2001 From: Michael Steenbeek Date: Tue, 26 May 2015 13:18:50 +0200 Subject: [PATCH 01/32] Add changes to changelog --- distribution/changelog.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index f8557af5ca..6858b5a9c9 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -1,5 +1,11 @@ 0.0.2-beta (2015-05-22) ------------------------------------------------------------------------ +- Feature: Show month before day (e.g. March 14, year 15) +- Feature: Change available object in-game (only available from console) +- Feature: Exit OpenRCT2 to desktop +- Feature: Allow testing of incomplete tracks +- Feature: Twitch integration +- Feature: Hardware display (useful for streaming) - Feature: Allow both types of powered launch (with and without passing the station) for every roller coaster that supported one type in RCT2. - Feature: Localisation of decimal and thousands separators. - Feature: Increase limits for maximum of circuits per roller coaster (20) and people on mazes (64) (up from the old limits of 7 and 16, respectively). From 84516da4a830f3adca9ef5066358460dd92ae58d Mon Sep 17 00:00:00 2001 From: Michael Steenbeek Date: Tue, 26 May 2015 13:19:54 +0200 Subject: [PATCH 02/32] Typo --- distribution/changelog.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 6858b5a9c9..04e303f884 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -1,6 +1,6 @@ 0.0.2-beta (2015-05-22) ------------------------------------------------------------------------ -- Feature: Show month before day (e.g. March 14, year 15) +- Feature: Show month before day (e.g. March 14th, year 15) - Feature: Change available object in-game (only available from console) - Feature: Exit OpenRCT2 to desktop - Feature: Allow testing of incomplete tracks From 6426adb45d41d50d680efd01d0fb9c486ba08cee Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Tue, 26 May 2015 19:28:37 +0100 Subject: [PATCH 03/32] remove asm for set scroll size and add gCurrentAwards --- src/interface/window.h | 14 ++++++++++++++ src/management/award.c | 19 +++++++++---------- src/management/award.h | 2 ++ src/windows/game_bottom_toolbar.c | 29 +++++++---------------------- src/windows/guest.c | 19 ++++++------------- src/windows/guest_list.c | 16 ++++------------ src/windows/map.c | 12 +++++------- src/windows/music_credits.c | 10 ++++------ src/windows/new_ride.c | 18 ++++-------------- src/windows/news.c | 10 +++------- src/windows/park.c | 2 +- src/windows/publisher_credits.c | 10 ++++------ src/windows/ride.c | 23 ++++------------------- src/windows/ride_list.c | 16 +++------------- src/windows/staff_list.c | 22 +++++++--------------- src/windows/title_scenarioselect.c | 16 +++------------- src/world/park.c | 2 +- 17 files changed, 81 insertions(+), 159 deletions(-) diff --git a/src/interface/window.h b/src/interface/window.h index 617412338c..6fcc023d25 100644 --- a/src/interface/window.h +++ b/src/interface/window.h @@ -659,6 +659,13 @@ int window_can_resize(rct_window *w); #define window_cursor_set_registers(cursorId) \ __asm mov ebx, cursorId + #define window_tooltip_get_registers(w, widgetIndex) \ + __asm mov widgetIndex, ax \ + __asm mov w, esi + + #define window_tooltip_set_registers(value) \ + __asm mov ax, value + #else #define window_get_register(w) \ __asm__ ( "mov %["#w"], esi " : [w] "+m" (w) ); @@ -721,6 +728,13 @@ int window_can_resize(rct_window *w); #define window_cursor_set_registers(cursorId) \ __asm__ ( "mov ebx, %[cursorId] " : [cursorId] "+m" (cursorId) ); + + #define window_tooltip_get_registers(w, widgetIndex) \ + __asm__ ( "mov %["#widgetIndex"], ax " : [widgetIndex] "+m" (widgetIndex) ); \ + __asm__ ( "mov %["#w"], esi " : [w] "+m" (w) ); + + #define window_tooltip_set_registers(value) \ + __asm__ ( "mov ax, %[value] " : [value] "+m" (value) ); #endif #endif diff --git a/src/management/award.c b/src/management/award.c index 90f4d8e719..ccf55a4255 100644 --- a/src/management/award.c +++ b/src/management/award.c @@ -51,6 +51,8 @@ int _awardPositiveMap[] = { POSITIVE, // PARK_AWARD_BEST_GENTLE_RIDES }; +rct_award *gCurrentAwards = (rct_award*)RCT2_ADDRESS_AWARD_LIST; + int award_is_positive(int type) { return _awardPositiveMap[type]; @@ -581,7 +583,7 @@ void award_reset() { int i; for (i = 0; i < MAX_AWARDS; i++) - RCT2_ADDRESS(RCT2_ADDRESS_AWARD_LIST, rct_award)[i].time = 0; + gCurrentAwards[i].time = 0; } /** @@ -591,9 +593,6 @@ void award_reset() void award_update_all() { int i, activeAwardTypes, freeAwardEntryIndex; - rct_award *awards; - - awards = RCT2_ADDRESS(RCT2_ADDRESS_AWARD_LIST, rct_award); // Only add new awards if park is open if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_PARK_OPEN) { @@ -601,8 +600,8 @@ void award_update_all() activeAwardTypes = 0; freeAwardEntryIndex = -1; for (i = 0; i < MAX_AWARDS; i++) { - if (awards[i].time != 0) - activeAwardTypes |= (1 << awards[i].type); + if (gCurrentAwards[i].time != 0) + activeAwardTypes |= (1 << gCurrentAwards[i].type); else if (freeAwardEntryIndex == -1) freeAwardEntryIndex = i; } @@ -618,8 +617,8 @@ void award_update_all() // Check if award is deserved if (award_is_deserved(awardType, activeAwardTypes)) { // Add award - awards[freeAwardEntryIndex].type = awardType; - awards[freeAwardEntryIndex].time = 5; + gCurrentAwards[freeAwardEntryIndex].type = awardType; + gCurrentAwards[freeAwardEntryIndex].time = 5; news_item_add_to_queue(NEWS_ITEM_AWARD, STR_NEWS_ITEM_AWARD_MOST_UNTIDY + awardType, 0); window_invalidate_by_class(WC_PARK_INFORMATION); } @@ -628,7 +627,7 @@ void award_update_all() // Decrease award times for (i = 0; i < MAX_AWARDS; i++) - if (awards[i].time != 0) - if (--awards[i].time == 0) + if (gCurrentAwards[i].time != 0) + if (--gCurrentAwards[i].time == 0) window_invalidate_by_class(WC_PARK_INFORMATION); } diff --git a/src/management/award.h b/src/management/award.h index 8e7c965f50..faab09d43c 100644 --- a/src/management/award.h +++ b/src/management/award.h @@ -51,6 +51,8 @@ enum { #define MAX_AWARDS 4 +extern rct_award *gCurrentAwards; + int award_is_positive(int type); void award_reset(); void award_update_all(); diff --git a/src/windows/game_bottom_toolbar.c b/src/windows/game_bottom_toolbar.c index c4f781b8fb..33727efa7e 100644 --- a/src/windows/game_bottom_toolbar.c +++ b/src/windows/game_bottom_toolbar.c @@ -214,31 +214,20 @@ static void window_game_bottom_toolbar_mouseup() static void window_game_bottom_toolbar_tooltip() { int month, day; - short tool_tip_index; + short widgetIndex, result; rct_window *w; - #ifdef _MSC_VER - __asm mov tool_tip_index, ax - #else - __asm__ ( "mov %[tool_tip_index], ax " : [tool_tip_index] "+m" (tool_tip_index) ); - #endif + window_tooltip_get_registers(w, widgetIndex); - #ifdef _MSC_VER - __asm mov w, esi - #else - __asm__ ( "mov %[w], esi " : [w] "+m" (w) ); - #endif - - - switch (tool_tip_index) { + switch (widgetIndex) { case WIDX_MONEY: RCT2_GLOBAL(0x013CE952, int) = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PROFIT, sint32); RCT2_GLOBAL(0x013CE956, int) = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PARK_VALUE, sint32); - tool_tip_index = 0; + result = 0; break; case WIDX_PARK_RATING: RCT2_GLOBAL(0x013CE952, short) = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PARK_RATING, sint16); - tool_tip_index = 0; + result = 0; break; case WIDX_DATE: month = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONTH_YEAR, sint16) & 7; @@ -246,15 +235,11 @@ static void window_game_bottom_toolbar_tooltip() RCT2_GLOBAL(0x013CE952, short) = STR_DATE_DAY_1 + day; RCT2_GLOBAL(0x013CE954, short) = STR_MONTH_MARCH + month; - tool_tip_index = 0; + result = 0; break; } -#ifdef _MSC_VER - __asm mov ax, tool_tip_index -#else - __asm__("mov ax, %[tool_tip_index] " :[tool_tip_index] "+m" (tool_tip_index)); -#endif + window_tooltip_set_registers(result); } /** diff --git a/src/windows/guest.c b/src/windows/guest.c index e7f32b44ab..d5c0550956 100644 --- a/src/windows/guest.c +++ b/src/windows/guest.c @@ -1593,12 +1593,15 @@ void window_guest_rides_tooltip(){ } /* rct2: 0x69784E */ -void window_guest_rides_scroll_get_size(){ +void window_guest_rides_scroll_get_size() +{ rct_window *w; + int width, height; window_get_register(w); - int height = w->no_list_items * 10; + width = 0; + height = w->no_list_items * 10; if (w->selected_list_item != -1){ w->selected_list_item = -1; @@ -1617,17 +1620,7 @@ void window_guest_rides_scroll_get_size(){ window_invalidate(w); } -#ifdef _MSC_VER - __asm mov ecx, 0 -#else - __asm__("mov ecx, 0 "); -#endif - -#ifdef _MSC_VER - __asm mov edx, height -#else - __asm__("mov edx, %[height] " : [height] "+m" (height)); -#endif + window_scrollsize_set_registers(width, height); } /* rct2: 0x006978CC */ diff --git a/src/windows/guest_list.c b/src/windows/guest_list.c index ab844b1047..4fe22575a0 100644 --- a/src/windows/guest_list.c +++ b/src/windows/guest_list.c @@ -418,7 +418,7 @@ static void window_guest_list_update(rct_window *w) */ static void window_guest_list_scrollgetsize() { - int i, y, numGuests, spriteIndex; + int i, y, numGuests, spriteIndex, width, height; rct_window *w; rct_peep *peep; @@ -469,18 +469,10 @@ static void window_guest_list_scrollgetsize() window_invalidate(w); } - #ifdef _MSC_VER - __asm mov ecx, 447 - #else - __asm__ ( "mov ecx, 447 " ); - #endif - - #ifdef _MSC_VER - __asm mov edx, y - #else - __asm__ ( "mov edx, %[y] " : [y] "+m" (y) ); - #endif + width = 447; + height = y; + window_scrollsize_set_registers(width, height); } /** diff --git a/src/windows/map.c b/src/windows/map.c index d5eef11cad..47f7b03098 100644 --- a/src/windows/map.c +++ b/src/windows/map.c @@ -465,15 +465,13 @@ static void window_map_update(rct_window *w) */ static void window_map_scrollgetsize() { + int width, height; + window_map_invalidate(); - #ifdef _MSC_VER - __asm mov ecx, 512 - __asm mov edx, 512 - #else - __asm__ ( "mov ecx, 512 " ); - __asm__ ( "mov edx, 512 " ); - #endif + width = 512; + height = 512; + window_scrollsize_set_registers(width, height); } /** diff --git a/src/windows/music_credits.c b/src/windows/music_credits.c index 2c8891308c..4a6f1c9da3 100644 --- a/src/windows/music_credits.c +++ b/src/windows/music_credits.c @@ -130,13 +130,11 @@ static void window_music_credits_mouseup() */ static void window_music_credits_scrollgetsize() { - int y = 560; + int width, height; - #ifdef _MSC_VER - __asm mov edx, y - #else - __asm__("mov edx, %[y] " : [y] "+m" (y)); - #endif + width = 0; + height = 560; + window_scrollsize_set_registers(width, height); } /** diff --git a/src/windows/new_ride.c b/src/windows/new_ride.c index 082be03649..4d2fb19bc9 100644 --- a/src/windows/new_ride.c +++ b/src/windows/new_ride.c @@ -634,27 +634,17 @@ static void window_new_ride_update(rct_window *w) static void window_new_ride_scrollgetsize() { ride_list_item *listItem = (ride_list_item*)0x00F43523; - int scrollWidth, scrollHeight; + int width, height; int count = 0; while (listItem->type != 255 || listItem->entry_index != 255) { count++; listItem++; } - scrollWidth = 0; - scrollHeight = ((count + 4) / 5) * 116; + width = 0; + height = ((count + 4) / 5) * 116; - #ifdef _MSC_VER - __asm mov ecx, scrollWidth - #else - __asm__ ( "mov ecx, %[scrollWidth] " : [scrollWidth] "+m" (scrollWidth) ); - #endif - - #ifdef _MSC_VER - __asm mov edx, scrollHeight - #else - __asm__ ( "mov edx, %[scrollHeight] " : [scrollHeight] "+m" (scrollHeight) ); - #endif + window_scrollsize_set_registers(width, height); } /** diff --git a/src/windows/news.c b/src/windows/news.c index 1d5935bf58..003bb5b7c0 100644 --- a/src/windows/news.c +++ b/src/windows/news.c @@ -184,9 +184,10 @@ static void window_news_update(rct_window *w) */ static void window_news_scrollgetsize() { - int i, height; + int i, width, height; rct_news_item *newsItems = RCT2_ADDRESS(RCT2_ADDRESS_NEWS_ITEM_LIST, rct_news_item); + width = 0; height = 0; for (i = 11; i < 61; i++) { if (newsItems[i].type == NEWS_ITEM_NULL) @@ -195,12 +196,7 @@ static void window_news_scrollgetsize() height += 42; } - #ifdef _MSC_VER - __asm mov edx, height - #else - __asm__ ( "mov edx, %[height] " : [height] "+m" (height) ); - #endif - + window_scrollsize_set_registers(width, height); } /** diff --git a/src/windows/park.c b/src/windows/park.c index b1d9b4a917..ddba07d4b0 100644 --- a/src/windows/park.c +++ b/src/windows/park.c @@ -1979,7 +1979,7 @@ static void window_park_awards_paint() count = 0; for (i = 0; i < MAX_AWARDS; i++) { - award = &RCT2_ADDRESS(RCT2_ADDRESS_AWARD_LIST, rct_award)[i]; + award = &gCurrentAwards[i]; if (award->time == 0) continue; diff --git a/src/windows/publisher_credits.c b/src/windows/publisher_credits.c index 37896872ce..a517c189a0 100644 --- a/src/windows/publisher_credits.c +++ b/src/windows/publisher_credits.c @@ -130,13 +130,11 @@ static void window_publisher_credits_mouseup() */ static void window_publisher_credits_scrollgetsize() { - int y = 820; + int width, height; -#ifdef _MSC_VER - __asm mov edx, y -#else - __asm__("mov edx, %[y] " : [y] "+m" (y)); -#endif + width = 0; + height = 820; + window_scrollsize_set_registers(width, height); } /** diff --git a/src/windows/ride.c b/src/windows/ride.c index 794fb63314..04c29e33a6 100644 --- a/src/windows/ride.c +++ b/src/windows/ride.c @@ -5081,18 +5081,7 @@ static void window_ride_graphs_scrollgetheight() if (measurement != NULL) width = max(width, measurement->num_items); - // Return size - #ifdef _MSC_VER - __asm mov ecx, width - #else - __asm__ ( "mov ecx, 0 " ); - #endif - - #ifdef _MSC_VER - __asm mov edx, height - #else - __asm__ ( "mov edx, %[height] " : [height] "+m" (height) ); - #endif + window_scrollsize_set_registers(width, height); } /** @@ -5115,12 +5104,12 @@ static void window_ride_graphs_15() static void window_ride_graphs_tooltip() { rct_window *w; - short unused, widgetIndex, result; + short widgetIndex, result; rct_ride *ride; rct_ride_measurement *measurement; rct_string_id stringId; - window_dropdown_get_registers(w, unused, widgetIndex); + window_tooltip_get_registers(w, widgetIndex); result = -1; if (widgetIndex == WIDX_GRAPH) { @@ -5136,11 +5125,7 @@ static void window_ride_graphs_tooltip() } } - #ifdef _MSC_VER - __asm mov ax, result - #else - __asm__ ( "mov ax, %[result] " : [result] "+m" (result) ); - #endif + window_tooltip_set_registers(result); } /** diff --git a/src/windows/ride_list.c b/src/windows/ride_list.c index f327357a61..c7c068366e 100644 --- a/src/windows/ride_list.c +++ b/src/windows/ride_list.c @@ -307,7 +307,7 @@ static void window_ride_list_update(rct_window *w) */ static void window_ride_list_scrollgetsize() { - int top, height; + int top, width, height; rct_window *w; window_get_register(w); @@ -326,18 +326,8 @@ static void window_ride_list_scrollgetsize() window_invalidate(w); } - #ifdef _MSC_VER - __asm mov ecx, 0 - #else - __asm__ ( "mov ecx, 0 " ); - #endif - - #ifdef _MSC_VER - __asm mov edx, height - #else - __asm__ ( "mov edx, %[height] " : [height] "+m" (height) ); - #endif - + width = 0; + window_scrollsize_set_registers(width, height); } /** diff --git a/src/windows/staff_list.c b/src/windows/staff_list.c index d98c37ccc8..c9bce60061 100644 --- a/src/windows/staff_list.c +++ b/src/windows/staff_list.c @@ -348,8 +348,9 @@ void window_staff_list_toolabort() { * * rct2: 0x006BDBE6 */ -void window_staff_list_scrollgetsize() { - int spriteIndex; +void window_staff_list_scrollgetsize() +{ + int i, width, height, spriteIndex; rct_peep *peep; rct_window *w; @@ -368,8 +369,8 @@ void window_staff_list_scrollgetsize() { window_invalidate(w); } - int scrollHeight = staffCount * 10; - int i = scrollHeight - window_staff_list_widgets[WIDX_STAFF_LIST_LIST].bottom + window_staff_list_widgets[WIDX_STAFF_LIST_LIST].top + 21; + height = staffCount * 10; + i = height - window_staff_list_widgets[WIDX_STAFF_LIST_LIST].bottom + window_staff_list_widgets[WIDX_STAFF_LIST_LIST].top + 21; if (i < 0) i = 0; if (i < w->scrolls[0].v_top) { @@ -377,17 +378,8 @@ void window_staff_list_scrollgetsize() { window_invalidate(w); } - #ifdef _MSC_VER - __asm mov ecx, 420 - #else - __asm__("mov ecx, 420 "); - #endif - - #ifdef _MSC_VER - __asm mov edx, scrollHeight - #else - __asm__("mov edx, %[scrollHeight] " : [scrollHeight] "+m" (scrollHeight)); - #endif + width = 420; + window_scrollsize_set_registers(width, height); } /** diff --git a/src/windows/title_scenarioselect.c b/src/windows/title_scenarioselect.c index 7c8a9000d2..90f94b4c04 100644 --- a/src/windows/title_scenarioselect.c +++ b/src/windows/title_scenarioselect.c @@ -192,12 +192,13 @@ static void window_scenarioselect_mousedown(int widgetIndex, rct_window*w, rct_w static void window_scenarioselect_scrollgetsize() { - int i, height; + int i, width, height; rct_window *w; rct_scenario_basic *scenario; window_get_register(w); + width = 0; height = 0; for (i = 0; i < gScenarioListCount; i++) { scenario = &gScenarioList[i]; @@ -207,18 +208,7 @@ static void window_scenarioselect_scrollgetsize() height += 24; } - #ifdef _MSC_VER - __asm mov ecx, 0 - #else - __asm__ ( "mov ecx, 0 " ); - #endif - - #ifdef _MSC_VER - __asm mov edx, height - #else - __asm__ ( "mov edx, %[height] " : [height] "+m" (height) ); - #endif - + window_scrollsize_set_registers(width, height); } /* rct2: 0x6780FE */ diff --git a/src/world/park.c b/src/world/park.c index d487006ad6..2dcdcb164a 100644 --- a/src/world/park.c +++ b/src/world/park.c @@ -435,7 +435,7 @@ static int park_calculate_guest_generation_probability() // Reward or penalties for park awards for (i = 0; i < MAX_AWARDS; i++) { - rct_award *award = &RCT2_ADDRESS(RCT2_ADDRESS_AWARD_LIST, rct_award)[i]; + rct_award *award = &gCurrentAwards[i]; if (award->time == 0) continue; From e394c1d0d388e2caa02a3e985fa5d678e610525f Mon Sep 17 00:00:00 2001 From: Jackson Davis Date: Tue, 26 May 2015 18:29:31 -0700 Subject: [PATCH 04/32] Fix compile error for non-windows --- src/interface/window.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/interface/window.h b/src/interface/window.h index 6fcc023d25..acae56af2c 100644 --- a/src/interface/window.h +++ b/src/interface/window.h @@ -734,7 +734,7 @@ int window_can_resize(rct_window *w); __asm__ ( "mov %["#w"], esi " : [w] "+m" (w) ); #define window_tooltip_set_registers(value) \ - __asm__ ( "mov ax, %[value] " : [value] "+m" (value) ); + __asm__ ( "mov ax, %["#value"] " : [value] "+m" (value) ); #endif #endif From 6c89274bb115b599f8a60d2a90d26da575d95122 Mon Sep 17 00:00:00 2001 From: Ted John Date: Wed, 27 May 2015 04:00:13 +0100 Subject: [PATCH 05/32] Merge Localisation/master into OpenRCT2/develop. --- data/language/dutch.txt | 13 +++++++++++++ data/language/english_us.txt | 13 +++++++++++++ 2 files changed, 26 insertions(+) diff --git a/data/language/dutch.txt b/data/language/dutch.txt index 45b3a01f41..63e0026614 100644 --- a/data/language/dutch.txt +++ b/data/language/dutch.txt @@ -3493,3 +3493,16 @@ STR_5160 :{MONTH} {STRINGID}, jaar {COMMA16} STR_5161 :{WHITE}Datumnotatie: STR_5162 :Dag/maand/jaar STR_5163 :Maand/dag/jaar +STR_5164 :Twitch-kanaalnaam +STR_5165 :Bezoekers namen van volgers geven +STR_5166 :Geeft bezoekers namen van gebruikers die het Twitch-kanaal volgen. +STR_5167 :Bezoekers met Twitch-volgersnamen volgen in berichtengebied +STR_5168 :Zet het bezoekersvolgsysteem aan voor bezoekers die naar Twitch-volgers zijn genoemd. +STR_5169 :Bezoekers namen van gebruikers in de Twitch-chat geven +STR_5170 :Geeft bezoekers namen van gebruikers in de Twitch-chat. +STR_5171 :Bezoekers met Twitch-chatnamen volgen in berichtengebied +STR_5172 :Zet het bezoekersvolgsysteem aan voor bezoekers die naar Twitch-chatters zijn genoemd. +STR_5173 :Twitch-chat als nieuws weergeven +STR_5174 :Zal chatberichten op Twitch die beginnen met !news in het berichtengebied tonen. +STR_5175 :Voer de naam van je Twitch-kanaal in +STR_5176 :Twitch-integratie inschakelen diff --git a/data/language/english_us.txt b/data/language/english_us.txt index 55c8677b3f..1de7d61656 100644 --- a/data/language/english_us.txt +++ b/data/language/english_us.txt @@ -3502,3 +3502,16 @@ STR_5160 :{MONTH} {STRINGID}, Year {COMMA16} STR_5161 :{WHITE}Date Format: STR_5162 :Day/Month/Year STR_5163 :Month/Day/Year +STR_5164 :Twitch Channel name +STR_5165 :Name peeps after followers +STR_5166 :Will name peeps after channel's Twitch followers +STR_5167 :Track follower peeps +STR_5168 :Will turn on tracking information for guests named after channel's Twitch followers +STR_5169 :Name peeps after people in Twitch chat +STR_5170 :Will name peeps after people in Twitch chat +STR_5171 :Track chat peeps +STR_5172 :Will turn on tracking information for guests named after Twitch chat participants +STR_5173 :Pull Twitch chat as news +STR_5174 :Will use Twitch chat messages preceded by !news for in game notifications +STR_5175 :Input the name of your Twitch channel +STR_5176 :Enable Twitch integration From 101fed0dd91c33ddda375a567c53f0ae0b4e9ac5 Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Thu, 28 May 2015 00:16:51 +0100 Subject: [PATCH 06/32] refactor g1Elements pointer and implement sub_68371D --- src/cmdline_sprite.c | 2 +- src/drawing/drawing.c | 8 ++++---- src/drawing/drawing.h | 3 +++ src/drawing/rect.c | 4 ++-- src/drawing/sprite.c | 31 ++++++++++++++++++++++--------- src/drawing/string.c | 18 +++++++++--------- src/game.c | 10 +++++----- src/interface/viewport.c | 4 ++-- src/object.c | 2 +- src/platform/shared.c | 5 ++++- src/windows/install_track.c | 2 +- src/windows/map.c | 2 +- src/windows/track_list.c | 2 +- src/windows/track_place.c | 2 +- 14 files changed, 57 insertions(+), 38 deletions(-) diff --git a/src/cmdline_sprite.c b/src/cmdline_sprite.c index 83c2d1b536..d87ce21a9d 100644 --- a/src/cmdline_sprite.c +++ b/src/cmdline_sprite.c @@ -434,7 +434,7 @@ int cmdline_for_sprite(const char **argv, int argc) fprintf(stderr, "Building: %s\n", spriteFilePath); for (int i = 0; fileExists; i++) { - itoa(i, number, 10); + _itoa(i, number, 10); strcpy(imagePath, resourcePath); if (resourceLength == 0 || (resourcePath[resourceLength - 1] != '/' && resourcePath[resourceLength - 1] != '\\')) strcat(imagePath, "/"); diff --git a/src/drawing/drawing.c b/src/drawing/drawing.c index 901af71bdf..b26c79ad60 100644 --- a/src/drawing/drawing.c +++ b/src/drawing/drawing.c @@ -135,7 +135,7 @@ void gfx_draw_pixel(rct_drawpixelinfo *dpi, int x, int y, int colour) */ void gfx_transpose_palette(int pal, unsigned char product) { - rct_g1_element g1 = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[pal]; + rct_g1_element g1 = g1Elements[pal]; int width = g1.width; int x = g1.x_offset; uint8* dest_pointer = (uint8*)&(RCT2_ADDRESS(0x01424680, uint8)[x * 4]); @@ -161,7 +161,7 @@ void load_palette(){ palette = water_type->image_id; } - rct_g1_element g1 = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[palette]; + rct_g1_element g1 = g1Elements[palette]; int width = g1.width; int x = g1.x_offset; uint8* dest_pointer = (uint8*)&(RCT2_ADDRESS(0x01424680, uint8)[x * 4]); @@ -514,7 +514,7 @@ void redraw_peep_and_rain() if (sprite != -1) { sprite = sprite & 0x7FFFF; - rct_g1_element *g1_elements = &RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[sprite]; + rct_g1_element *g1_elements = &g1Elements[sprite]; int left = RCT2_GLOBAL(RCT2_ADDRESS_PICKEDUP_PEEP_X, sint16) + g1_elements->x_offset; int top = RCT2_GLOBAL(RCT2_ADDRESS_PICKEDUP_PEEP_Y, sint16) + g1_elements->y_offset; int right = left + g1_elements->width; @@ -546,4 +546,4 @@ void redraw_peep_and_rain() } } RCT2_GLOBAL(RCT2_ADDRESS_NO_RAIN_PIXELS, uint32) = 0; -} +} \ No newline at end of file diff --git a/src/drawing/drawing.h b/src/drawing/drawing.h index e258f07654..80f3713e1a 100644 --- a/src/drawing/drawing.h +++ b/src/drawing/drawing.h @@ -64,6 +64,8 @@ extern uint8 text_palette[]; extern int gLastDrawStringX; extern int gLastDrawStringY; +extern rct_g1_element *g1Elements; + // rct_drawpixelinfo* clip_drawpixelinfo(rct_drawpixelinfo* dpi, int left, int width, int top, int height); void gfx_set_dirty_blocks(int left, int top, int right, int bottom); @@ -91,6 +93,7 @@ void gfx_fill_rect_inset(rct_drawpixelinfo* dpi, short left, short top, short ri // sprite int gfx_load_g1(); int gfx_load_g2(); +void sub_68371D(); void gfx_bmp_sprite_to_buffer(uint8* palette_pointer, uint8* unknown_pointer, uint8* source_pointer, uint8* dest_pointer, rct_g1_element* source_image, rct_drawpixelinfo *dest_dpi, int height, int width, int image_type); void gfx_rle_sprite_to_buffer(uint8* source_bits_pointer, uint8* dest_bits_pointer, uint8* palette_pointer, rct_drawpixelinfo *dpi, int image_type, int source_y_start, int height, int source_x_start, int width); void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y, uint32 tertiary_colour); diff --git a/src/drawing/rect.c b/src/drawing/rect.c index ac4558dcf1..e5a4b1e483 100644 --- a/src/drawing/rect.c +++ b/src/drawing/rect.c @@ -109,7 +109,7 @@ void gfx_fill_rect(rct_drawpixelinfo *dpi, int left, int top, int right, int bot // Find colour in colour table? uint16 eax = palette_to_g1_offset[(colour & 0xFF)]; - rct_g1_element g1_element = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[eax]; + rct_g1_element g1_element = g1Elements[eax]; // Fill the rectangle with the colours from the colour table for (int i = 0; i < height>>dpi->zoom_level; ++i) { @@ -211,7 +211,7 @@ void gfx_fill_rect(rct_drawpixelinfo *dpi, int left, int top, int right, int bot esi = RCT2_GLOBAL(0xEDF828,sint32); esi *= 0x40; left = 0; - esi += (uint32)(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS,rct_g1_element)[right]).offset;//??? + esi += (uint32)g1Elements[right].offset;//??? //Not finished //Start of loop return; diff --git a/src/drawing/sprite.c b/src/drawing/sprite.c index 0f102dd57b..edadd6ece4 100644 --- a/src/drawing/sprite.c +++ b/src/drawing/sprite.c @@ -38,6 +38,8 @@ typedef struct { rct_gx g2; +rct_g1_element *g1Elements = (rct_g1_element*)RCT2_ADDRESS_G1_ELEMENTS; + /** * * rct2: 0x00678998 @@ -50,8 +52,6 @@ int gfx_load_g1() rct_g1_header header; unsigned int i; - rct_g1_element *g1Elements = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element); - file = fopen(get_file_path(PATH_ID_G1), "rb"); if (file != NULL) { if (fread(&header, 8, 1, file) == 1) { @@ -118,6 +118,19 @@ int gfx_load_g2() return 0; } +/** + * This function looks like it initialises the 0x009E3CE4 array which references sprites used for background / palette mixing or + * something. Further investigation is needed. + */ +void sub_68371D() +{ + uint8 **unk_9E3CE4 = (uint8**)0x009E3CE4; + + unk_9E3CE4[0] = NULL; + for (int i = 1; i < 8; i++) + unk_9E3CE4[i] = g1Elements[23199 + i].offset; +} + /** * Copies a sprite onto the buffer. There is no compression used on the sprite * image. @@ -405,7 +418,7 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y, uint32 } uint16 palette_offset = palette_to_g1_offset[palette_ref]; - palette_pointer = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[palette_offset].offset; + palette_pointer = g1Elements[palette_offset].offset; } else if (image_type && !(image_type & IMAGE_TYPE_USE_PALETTE)){ RCT2_GLOBAL(0x9E3CDC, uint32) = 0; @@ -416,9 +429,9 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y, uint32 uint32 secondary_offset = palette_to_g1_offset[(image_id >> 24) & 0x1F]; uint32 tertiary_offset = palette_to_g1_offset[tertiary_colour]; - rct_g1_element* primary_colour = &RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[primary_offset]; - rct_g1_element* secondary_colour = &RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[secondary_offset]; - rct_g1_element* tertiary_colour = &RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[tertiary_offset]; + rct_g1_element* primary_colour = &g1Elements[primary_offset]; + rct_g1_element* secondary_colour = &g1Elements[secondary_offset]; + rct_g1_element* tertiary_colour = &g1Elements[tertiary_offset]; memcpy(palette_pointer + 0xF3, &primary_colour->offset[0xF3], 12); memcpy(palette_pointer + 0xCA, &secondary_colour->offset[0xF3], 12); @@ -437,13 +450,13 @@ void gfx_draw_sprite(rct_drawpixelinfo *dpi, int image_id, int x, int y, uint32 //Top int top_type = (image_id >> 19) & 0x1f; uint32 top_offset = palette_to_g1_offset[top_type]; //RCT2_ADDRESS(0x97FCBC, uint32)[top_type]; - rct_g1_element top_palette = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[top_offset]; + rct_g1_element top_palette = g1Elements[top_offset]; memcpy(palette_pointer + 0xF3, top_palette.offset + 0xF3, 12); //Trousers int trouser_type = (image_id >> 24) & 0x1f; uint32 trouser_offset = palette_to_g1_offset[trouser_type]; //RCT2_ADDRESS(0x97FCBC, uint32)[trouser_type]; - rct_g1_element trouser_palette = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[trouser_offset]; + rct_g1_element trouser_palette = g1Elements[trouser_offset]; memcpy(palette_pointer + 0xCA, trouser_palette.offset + 0xF3, 12); } @@ -469,7 +482,7 @@ void gfx_draw_sprite_palette_set(rct_drawpixelinfo *dpi, int image_id, int x, in rct_g1_element* g1_source; if (image_element < SPR_G2_BEGIN) { - g1_source = &(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[image_element]); + g1_source = &g1Elements[image_element]; } else { g1_source = &g2.elements[image_element - SPR_G2_BEGIN]; } diff --git a/src/drawing/string.c b/src/drawing/string.c index 746ebfa9c5..b1c417d4ee 100644 --- a/src/drawing/string.c +++ b/src/drawing/string.c @@ -32,7 +32,7 @@ void gfx_load_character_widths(){ uint8* char_width_pointer = RCT2_ADDRESS(RCT2_ADDRESS_FONT_CHAR_WIDTH, uint8); for (int char_set_offset = 0; char_set_offset < 4*0xE0; char_set_offset+=0xE0){ for (uint8 c = 0; c < 0xE0; c++, char_width_pointer++){ - rct_g1_element g1 = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[c + SPR_CHAR_START + char_set_offset]; + rct_g1_element g1 = g1Elements[c + SPR_CHAR_START + char_set_offset]; int width; if (char_set_offset == 0xE0*3) width = g1.width + 1; @@ -75,7 +75,7 @@ void gfx_load_character_widths(){ } for (int i = 0; i < 0x20; ++i){ - rct_g1_element* g1 = &(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[0x606 + i]); + rct_g1_element* g1 = &g1Elements[0x606 + i]; uint8* unknown_pointer = RCT2_ADDRESS(0x9C3852, uint8) + 0xa12 * i; g1->offset = unknown_pointer; g1->width = 0x40; @@ -138,7 +138,7 @@ int gfx_get_string_width_new_lined(char* buffer){ case 0x10: continue; case FORMAT_INLINE_SPRITE: - g1_element = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[*((uint32*)(curr_char + 1)) & 0x7FFFF]; + g1_element = g1Elements[*((uint32*)(curr_char + 1)) & 0x7FFFF]; width += g1_element.width; curr_char += 4; break; @@ -214,7 +214,7 @@ int gfx_get_string_width(char* buffer) case 0x10: continue; case FORMAT_INLINE_SPRITE: - g1_element = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[*((uint32*)(curr_char+1))&0x7FFFF]; + g1_element = g1Elements[*((uint32*)(curr_char + 1)) & 0x7FFFF]; width += g1_element.width; curr_char += 4; break; @@ -297,7 +297,7 @@ int gfx_clip_string(char* buffer, int width) case 0x10: continue; case FORMAT_INLINE_SPRITE: - g1_element = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[*((uint32*)(curr_char+1))&0x7FFFF]; + g1_element = g1Elements[*((uint32*)(curr_char + 1)) & 0x7FFFF]; clipped_width += g1_element.width; curr_char += 4; continue; @@ -396,7 +396,7 @@ int gfx_wrap_string(char* buffer, int width, int* num_lines, int* font_height) case 0x10: continue; case FORMAT_INLINE_SPRITE: - g1_element = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[*((uint32*)(curr_char + 1)) & 0x7FFFF]; + g1_element = g1Elements[*((uint32*)(curr_char + 1)) & 0x7FFFF]; line_width += g1_element.width; curr_char += 4; break; @@ -718,7 +718,7 @@ void colour_char(uint8 colour, uint16* current_font_flags, uint8* palette_pointe int eax; - rct_g1_element g1_element = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[0x1332]; + rct_g1_element g1_element = g1Elements[0x1332]; eax = ((uint32*)g1_element.offset)[colour & 0xFF]; if (!(*current_font_flags & 2)) { @@ -896,7 +896,7 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in } eax = palette_to_g1_offset[al]; //RCT2_ADDRESS(0x097FCBC, uint32)[al * 4]; - g1_element = &(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[eax]); + g1_element = &g1Elements[eax]; ebx = g1_element->offset[0xF9] + (1 << 8); if (!(*current_font_flags & 2)) { ebx = ebx & 0xFF; @@ -1008,7 +1008,7 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in } uint32 image_id = *((uint32*)(buffer - 3)); uint32 image_offset = image_id & 0x7FFFF; - g1_element = &(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[image_offset]); + g1_element = &g1Elements[image_offset]; gfx_draw_sprite(dpi, image_id, max_x, max_y, 0); diff --git a/src/game.c b/src/game.c index a42b071237..aa7834491e 100644 --- a/src/game.c +++ b/src/game.c @@ -102,7 +102,7 @@ void update_palette_effects() if ((sint32)water_type != -1) { palette = water_type->image_id; } - rct_g1_element g1_element = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[palette]; + rct_g1_element g1_element = g1Elements[palette]; int xoffset = g1_element.x_offset; xoffset = xoffset * 4; for (int i = 0; i < g1_element.width; i++) { @@ -123,7 +123,7 @@ void update_palette_effects() palette = water_type->image_id; } - rct_g1_element g1_element = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[palette]; + rct_g1_element g1_element = g1Elements[palette]; int xoffset = g1_element.x_offset; xoffset = xoffset * 4; for (int i = 0; i < g1_element.width; i++) { @@ -148,7 +148,7 @@ void update_palette_effects() if ((sint32)water_type != -1) { p = water_type->var_06; } - rct_g1_element g1_element = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[q + p]; + rct_g1_element g1_element = g1Elements[q + p]; uint8* vs = &g1_element.offset[j * 3]; uint8* vd = RCT2_ADDRESS(0x01424A18, uint8); int n = 5; @@ -167,7 +167,7 @@ void update_palette_effects() if ((sint32)water_type != -1) { p = water_type->var_0A; } - g1_element = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[q + p]; + g1_element = g1Elements[q + p]; vs = &g1_element.offset[j * 3]; n = 5; for (int i = 0; i < n; i++) { @@ -183,7 +183,7 @@ void update_palette_effects() j = ((uint16)(RCT2_GLOBAL(RCT2_ADDRESS_PALETTE_EFFECT_FRAME_NO, uint32) * -960) * 3) >> 16; p = 1539; - g1_element = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[q + p]; + g1_element = g1Elements[q + p]; vs = &g1_element.offset[j * 3]; vd += 12; n = 3; diff --git a/src/interface/viewport.c b/src/interface/viewport.c index 80b93835be..cd5043b6ea 100644 --- a/src/interface/viewport.c +++ b/src/interface/viewport.c @@ -88,7 +88,7 @@ void viewport_init_all() // Palette from sprites? d = 0; for (i = 4915; i < 4947; i++) { - g1_element = &(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[i]); + g1_element = &g1Elements[i]; *((int*)(0x0141FC44 + d)) = *((int*)(&g1_element->offset[0xF5])); *((int*)(0x0141FC48 + d)) = *((int*)(&g1_element->offset[0xF9])); *((int*)(0x0141FD44 + d)) = *((int*)(&g1_element->offset[0xFD])); @@ -743,7 +743,7 @@ int sub_0x686806(rct_sprite* sprite, int eax, int image_id, int ecx, int edx){ ps->image_id = image_id; - rct_g1_element *g1Element = &RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[image_id & 0x7FFFF]; + rct_g1_element *g1Element = &g1Elements[image_id & 0x7FFFF]; eax = (eax & 0xFF) + RCT2_GLOBAL(0x9DE568, uint16); ecx = (ecx & 0xFF) + RCT2_GLOBAL(0x9DE56C, uint16); diff --git a/src/object.c b/src/object.c index 7f2be9d177..64414d549f 100644 --- a/src/object.c +++ b/src/object.c @@ -396,7 +396,7 @@ int object_chunk_load_image_directory(uint8_t** chunk) RCT2_GLOBAL(RCT2_ADDRESS_TOTAL_NO_IMAGES, uint32_t) = no_images + image_start_no; - rct_g1_element* g1_dest = &RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[image_start_no]; + rct_g1_element* g1_dest = &g1Elements[image_start_no]; // After length of data is the start of all g1 element structs rct_g1_element* g1_source = (rct_g1_element*)(*chunk); diff --git a/src/platform/shared.c b/src/platform/shared.c index 574dfa531e..c6f356b473 100644 --- a/src/platform/shared.c +++ b/src/platform/shared.c @@ -525,7 +525,10 @@ static void platform_create_window() SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, 0); platform_load_cursors(); - RCT2_CALLPROC_EBPSAFE(0x0068371D); + + // TODO This should probably be called somewhere else. It has nothing to do with window creation and can be done as soon as + // g1.dat is loaded. + sub_68371D(); // Get window size width = gConfigGeneral.window_width; diff --git a/src/windows/install_track.c b/src/windows/install_track.c index 922ed382f7..9fa360876d 100644 --- a/src/windows/install_track.c +++ b/src/windows/install_track.c @@ -299,7 +299,7 @@ static void window_install_track_paint() uint16 holes, speed, drops, dropHeight, inversions; fixed32_2dp rating; int x, y, colour, gForces, airTime; - rct_g1_element tmpElement, *subsituteElement, *g1Elements = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element); + rct_g1_element tmpElement, *subsituteElement; window_paint_get_registers(w, dpi); diff --git a/src/windows/map.c b/src/windows/map.c index 47f7b03098..ec4d5332cc 100644 --- a/src/windows/map.c +++ b/src/windows/map.c @@ -893,7 +893,7 @@ static void window_map_scrollpaint() gfx_clear(dpi, 0x0A0A0A0A); - g1_element = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element); + g1_element = &g1Elements[0]; pushed_g1_element = *g1_element; g1_element->offset = RCT2_GLOBAL(RCT2_ADDRESS_MAP_IMAGE_DATA, uint8*); diff --git a/src/windows/track_list.c b/src/windows/track_list.c index f36aa355ea..f7868c1f75 100644 --- a/src/windows/track_list.c +++ b/src/windows/track_list.c @@ -393,7 +393,7 @@ static void window_track_list_paint() uint16 holes, speed, drops, dropHeight, inversions; fixed32_2dp rating; int trackIndex, x, y, colour, gForces, airTime; - rct_g1_element tmpElement, *subsituteElement, *g1Elements = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element); + rct_g1_element tmpElement, *subsituteElement; window_paint_get_registers(w, dpi); diff --git a/src/windows/track_place.c b/src/windows/track_place.c index 6ac32ddad2..099617f42c 100644 --- a/src/windows/track_place.c +++ b/src/windows/track_place.c @@ -596,7 +596,7 @@ static void window_track_place_paint() { rct_window *w; rct_drawpixelinfo *dpi, *clippedDpi; - rct_g1_element tmpElement, *subsituteElement, *g1Elements = RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element); + rct_g1_element tmpElement, *subsituteElement; window_paint_get_registers(w, dpi); From 6f1cd77f3c3efd95b84ed259839f5fc9bc79f9ce Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Thu, 28 May 2015 01:15:58 +0100 Subject: [PATCH 07/32] implement textinput_cancel and refactor textinput event calls --- src/addresses.h | 4 ++++ src/interface/viewport.c | 2 +- src/interface/window.c | 31 +++++++++++++++++++++++++++++++ src/interface/window.h | 2 ++ src/windows/banner.c | 2 +- src/windows/text_input.c | 6 +++--- 6 files changed, 42 insertions(+), 5 deletions(-) diff --git a/src/addresses.h b/src/addresses.h index 4e70688479..962770bc24 100644 --- a/src/addresses.h +++ b/src/addresses.h @@ -230,6 +230,10 @@ #define RCT2_ADDRESS_WINDOW_DPI 0x009DEA74 +#define RCT2_ADDRESS_TEXTINPUT_WIDGETINDEX 0x009DEB88 +#define RCT2_ADDRESS_TEXTINPUT_WINDOWNUMBER 0x009DEB8A +#define RCT2_ADDRESS_TEXTINPUT_WINDOWCLASS 0x009DEB8C + #define RCT2_ADDRESS_DSOUND_BUFFERS 0x009E1AB0 #define RCT2_ADDRESS_NUM_DSOUND_DEVICES 0x009E2B88 #define RCT2_ADDRESS_DSOUND_DEVICES 0x009E2B8C diff --git a/src/interface/viewport.c b/src/interface/viewport.c index cd5043b6ea..74a03069e8 100644 --- a/src/interface/viewport.c +++ b/src/interface/viewport.c @@ -112,7 +112,7 @@ void viewport_init_all() RCT2_GLOBAL(RCT2_ADDRESS_TOOLTIP_NOT_SHOWN_TICKS, sint16) = -1; RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, sint16) = 0; RCT2_GLOBAL(0x009DEA50, sint16) = -1; - RCT2_CALLPROC_EBPSAFE(0x006EE3C3); + textinput_cancel(); format_string((char*)0x0141FA44, STR_CANCEL, NULL); format_string((char*)0x0141F944, STR_OK, NULL); } diff --git a/src/interface/window.c b/src/interface/window.c index 335d425add..03fac892cb 100644 --- a/src/interface/window.c +++ b/src/interface/window.c @@ -2141,3 +2141,34 @@ int window_can_resize(rct_window *w) { return (w->flags & WF_RESIZABLE) && (w->min_width != w->max_width || w->min_height != w->max_height); } + +void window_event_textinput_call(rct_window *w, int widgetIndex, char *text) +{ + RCT2_CALLPROC_X(w->event_handlers[WE_TEXT_INPUT], 0, 0, text != NULL, widgetIndex, (int)w, (int)text, 0); +} + +/** + * + * rct2: 0x006EE3C3 + */ +void textinput_cancel() +{ + rct_window *w; + + // Close the new text input window + window_close_by_class(WC_TEXTINPUT); + + // The following code is only necessary for the old Windows text input dialog. In theory this isn't used anymore, but can + // still be triggered via original code paths. + RCT2_CALLPROC_EBPSAFE(0x0040701D); + if (RCT2_GLOBAL(0x009DEB8C, uint8) != 255) { + RCT2_CALLPROC_EBPSAFE(0x006EE4E2); + w = window_find_by_number( + RCT2_GLOBAL(RCT2_ADDRESS_TEXTINPUT_WINDOWCLASS, rct_windowclass), + RCT2_GLOBAL(RCT2_ADDRESS_TEXTINPUT_WINDOWNUMBER, rct_windownumber) + ); + if (w != NULL) { + window_event_textinput_call(w, RCT2_GLOBAL(RCT2_ADDRESS_TEXTINPUT_WIDGETINDEX, uint16), NULL); + } + } +} \ No newline at end of file diff --git a/src/interface/window.h b/src/interface/window.h index acae56af2c..2a6969a9c0 100644 --- a/src/interface/window.h +++ b/src/interface/window.h @@ -590,8 +590,10 @@ void window_event_resize_call(rct_window* w); void window_event_mouse_down_call(rct_window* w, int widgetIndex); void window_event_invalidate_call(rct_window* w); void window_event_update_call(rct_window *w); +void window_event_textinput_call(rct_window *w, int widgetIndex, char *text); void sub_6EA73F(); +void textinput_cancel(); void window_move_and_snap(rct_window *w, int newWindowX, int newWindowY, int snapProximity); int window_can_resize(rct_window *w); diff --git a/src/windows/banner.c b/src/windows/banner.c index 76626d71cf..febc389481 100644 --- a/src/windows/banner.c +++ b/src/windows/banner.c @@ -207,7 +207,7 @@ static void window_banner_mouseup() window_text_input_open(w, WIDX_BANNER_TEXT, 2982, 2983, gBanners[w->number].string_idx, 0, 32); break; case WIDX_BANNER_NO_ENTRY: - RCT2_CALLPROC_EBPSAFE(0x006EE3C3); + textinput_cancel(); banner->flags ^= BANNER_FLAG_NO_ENTRY; window_invalidate(w); diff --git a/src/windows/text_input.c b/src/windows/text_input.c index d12a5bfe0a..d0b81642a8 100644 --- a/src/windows/text_input.c +++ b/src/windows/text_input.c @@ -240,7 +240,7 @@ static void window_text_input_mouseup(){ // Pass back the text that has been entered. // ecx when zero means text input failed if (calling_w != NULL) - RCT2_CALLPROC_X(calling_w->event_handlers[WE_TEXT_INPUT], 0, 0, 0, calling_widget, (int)calling_w, (int)text_input, 0); + window_event_textinput_call(calling_w, calling_widget, NULL); window_close(w); break; case WIDX_OKAY: @@ -248,7 +248,7 @@ static void window_text_input_mouseup(){ // Pass back the text that has been entered. // ecx when none zero means text input success if (calling_w != NULL) - RCT2_CALLPROC_X(calling_w->event_handlers[WE_TEXT_INPUT], 0, 0, 1, calling_widget, (int)calling_w, (int)text_input, 0); + window_event_textinput_call(calling_w, calling_widget, text_input); window_close(w); } } @@ -340,7 +340,7 @@ static void window_text_input_text(int key, rct_window* w){ // Pass back the text that has been entered. // ecx when none zero means text input success if (calling_w) - RCT2_CALLPROC_X(calling_w->event_handlers[WE_TEXT_INPUT], 0, 0, 1, calling_widget, (int)calling_w, (int)text_input, 0); + window_event_textinput_call(calling_w, calling_widget, text_input); } window_invalidate(w); From 9dc19c6bc236dd1ec6f49d4da75f1cd152bcc652 Mon Sep 17 00:00:00 2001 From: Ted John Date: Thu, 28 May 2015 04:00:22 +0100 Subject: [PATCH 08/32] Merge Localisation/master into OpenRCT2/develop. --- data/language/english_us.txt | 2 +- data/language/german.txt | 26 +++++++++++++------------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/data/language/english_us.txt b/data/language/english_us.txt index 1de7d61656..9e909d51d4 100644 --- a/data/language/english_us.txt +++ b/data/language/english_us.txt @@ -2682,7 +2682,7 @@ STR_2676 :??? STR_2677 :??? STR_2678 :??? STR_2679 :??? -STR_2680 :??? +STR_2680 :All research complete STR_2681 :{MEDIUMFONT}{BLACK}Increases your money by 5,000 STR_2682 :{MEDIUMFONT}{BLACK}Toggle between Free and Paid Entry STR_2683 :{MEDIUMFONT}{BLACK}Increases every peeps happiness to max diff --git a/data/language/german.txt b/data/language/german.txt index 12ede24bc7..d0b42259da 100644 --- a/data/language/german.txt +++ b/data/language/german.txt @@ -769,7 +769,7 @@ STR_0764 :Besucher {INT32} STR_0765 :Besucher {INT32} STR_0766 :Besucher {INT32} STR_0767 :Besucher {INT32} -STR_0768 :Handwerker {INT32} +STR_0768 :Parkpfleger {INT32} STR_0769 :Mechaniker {INT32} STR_0770 :Aufseher {INT32} STR_0771 :Animateur {INT32} @@ -878,8 +878,8 @@ STR_0873 :{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{STRINGID} STR_0874 :{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{STRINGID} STR_0875 :{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{STRINGID} STR_0876 :{BLACK}{DOWN} -STR_0877 :Zu niedrig ! -STR_0878 :Zu hoch ! +STR_0877 :Zu niedrig! +STR_0878 :Zu hoch! STR_0879 :Gelände kann hier nicht tiefer gemacht werden... STR_0880 :Gelände kann hier nicht höher gemacht werden... STR_0881 :Objekt ist im Weg @@ -1432,7 +1432,7 @@ STR_1427 :{WINDOW_COLOUR_2}Besucher: {BLACK}{COMMA32} pro Stunde STR_1428 :{WINDOW_COLOUR_2}Eintrittspreis: STR_1429 :{POP16}{POP16}{POP16}{CURRENCY2DP} STR_1430 :Kostenlos -STR_1431 :Beim Gehen +STR_1431 :Läuft herum STR_1432 :Geht Richtung {STRINGID} STR_1433 :Steht in Schlange für {STRINGID} STR_1434 :Ertrinkt @@ -1701,7 +1701,7 @@ STR_1696 :{SMALLFONT}{BLACK}Besucherinformationen STR_1697 :Können nicht in Wartebereich platziert werden STR_1698 :Können nur in Wartebereich platziert werden STR_1699 :Zu viele Leute im Spiel -STR_1700 :Neuen Handwerker einstellen +STR_1700 :Neuen Parkpfleger einstellen STR_1701 :Neuen Mechaniker einstellen STR_1702 :Neuen Aufseher einstellen STR_1703 :Neuen Animateur einstellen @@ -1742,7 +1742,7 @@ STR_1737 :{COMMA16} STR_1738 :Rundenanzahl kann nicht geändert werden... STR_1739 :Rennen gewonnen von Besucher {INT32} STR_1740 :Rennen wurde gewonnen von {STRINGID} -STR_1741 :Noch nicht gebaut ! +STR_1741 :Noch nicht gebaut! STR_1742 :{WINDOW_COLOUR_2}Max. Besucherzahl: STR_1743 :{SMALLFONT}{BLACK}Höchstzahl zulässiger Personen zu einem Zeitpunkt bei dieser Bahn STR_1744 :{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{COMMA16} @@ -1860,11 +1860,11 @@ STR_1855 :{WINDOW_COLOUR_2}Baudatum: Vor {BLACK}{COMMA16} Jahren STR_1856 :{WINDOW_COLOUR_2}Gewinn pro verkaufter Artikel: {BLACK}{CURRENCY2DP} STR_1857 :{WINDOW_COLOUR_2}Verlust pro verkaufter Artikel: {BLACK}{CURRENCY2DP} STR_1858 :{WINDOW_COLOUR_2}Kosten: {BLACK}{CURRENCY} pro Monat -STR_1859 :Handwerker +STR_1859 :Parkpfleger STR_1860 :Mechaniker STR_1861 :Aufseher STR_1862 :Animateur -STR_1863 :Handwerker +STR_1863 :Parkpfleger STR_1864 :Mechaniker STR_1865 :Aufseher STR_1866 :Animateur @@ -2211,7 +2211,7 @@ STR_2206 :Leerer Getränkekarton STR_2207 :Leeres Saftglas STR_2208 :Bratwurst STR_2209 :Leere Schüssel -STR_2210 :{SMALLFONT}{BLACK}Liste der Handwerker im Park anzeigen +STR_2210 :{SMALLFONT}{BLACK}Liste der Parkpfleger im Park anzeigen STR_2211 :{SMALLFONT}{BLACK}Liste der Mechaniker im Park anzeigen STR_2212 :{SMALLFONT}{BLACK}Liste der Aufseher im Park anzeigen STR_2213 :{SMALLFONT}{BLACK}Liste der Animateure im Park anzeigen @@ -2810,8 +2810,8 @@ STR_2802 :Karte STR_2803 :{SMALLFONT}{BLACK}Diese Besucher auf Karte hervorheben STR_2804 :{SMALLFONT}{BLACK}Diese Mitarbeiter auf Karte hervorheben STR_2805 :{SMALLFONT}{BLACK}Parkkarte anzeigen -STR_2806 :{RED}Die Besucher beschweren sich über den schrecklichen Zustand der Fußwege in Ihrem Park{NEWLINE}Überprüfen Sie, wo Ihre Handwerker sind, und organisieren Sie sie erforderlichenfalls besser -STR_2807 :{RED}Die Besucher beschweren sich über das Müllaufkommen in Ihrem Park{NEWLINE}Überprüfen Sie, wo Ihre Handwerker sind, und organisieren Sie sie erforderlichenfalls besser +STR_2806 :{RED}Die Besucher beschweren sich über den schrecklichen Zustand der Fußwege in Ihrem Park{NEWLINE}Überprüfen Sie, wo Ihre Parkpfleger sind, und organisieren Sie sie erforderlichenfalls besser +STR_2807 :{RED}Die Besucher beschweren sich über das Müllaufkommen in Ihrem Park{NEWLINE}Überprüfen Sie, wo Ihre Parkpfleger sind, und organisieren Sie sie erforderlichenfalls besser STR_2808 :{RED}Die Besucher beschweren sich über den Vandalismus in Ihrem Park{NEWLINE}Überprüfen Sie, wo Ihre Aufseher sind, und organisieren Sie sie erforderlichenfalls besser STR_2809 :{RED}Die Besucher sind hungrig und können nirgendwo etwas finden, um Speisen zu kaufen STR_2810 :{RED}Die Besucher sind durstig und können nirgendwo etwas finden, um Getränke zu kaufen @@ -2836,7 +2836,7 @@ STR_2828 :{WINDOW_COLOUR_2}Auszeichnung f. bunteste Farbschemas STR_2829 :{WINDOW_COLOUR_2}Auszeichnung f. konfuseste Parkanordn. STR_2830 :{WINDOW_COLOUR_2}Auszeichnung f. beste gemäßigte Bahn STR_2831 :{TOPAZ}Ihr Park hat die Auszeichnung `Ungepflegtester Park des Landes' erhalten! -STR_2832 :{TOPAZ}Ihr Park hat die Auszeichnung `Säuberster Park des Landes' erhalten! +STR_2832 :{TOPAZ}Ihr Park hat die Auszeichnung `Sauberster Park des Landes' erhalten! STR_2833 :{TOPAZ}Ihr Park hat die Auszeichnung `Park mit den besten Achterbahnen' erhalten! STR_2834 :{TOPAZ}Ihr Park hat die Auszeichnung `Park mit dem besten Angebot des Landes' erhalten! STR_2835 :{TOPAZ}Ihr Park hat die Auszeichnung `Schönster Park des Landes' erhalten! @@ -2858,7 +2858,7 @@ STR_2850 :Neuer Streckenentwurf erfolgreich installiert STR_2851 :Szenario bereits installiert STR_2852 :Streckenentwurf bereits installiert STR_2853 :Von der örtlichen Behörde verboten! -STR_2854 :{RED}Besucher gelangen nicht zum Eingang von {STRINGID} !{NEWLINE}Bauen Sie einen Fußweg zum Eingang +STR_2854 :{RED}Besucher gelangen nicht zum Eingang von {STRINGID}!{NEWLINE}Bauen Sie einen Fußweg zum Eingang STR_2855 :{RED}{STRINGID} hat keinen Fußweg, der vom Ausgang wegführt!{NEWLINE}Legen Sie einen Fußweg an, der vom Bahnausgang wegführt STR_2856 :{WINDOW_COLOUR_2}Lehrgang STR_2857 :{WINDOW_COLOUR_2}(Drücken Sie eine Taste oder klicken Sie mit der Maus, um die Kontrolle zu übernehmen) From 8da01a1bf750e1ba8abadc88035a8bd143c6733f Mon Sep 17 00:00:00 2001 From: Graham Edgecombe Date: Thu, 28 May 2015 11:52:40 +0100 Subject: [PATCH 09/32] Fix building with -DDISABLE_TWITCH. The gTwitchEnable variable was used in some places without being wrapped around an #ifndef DISABLE_TWITCH block. --- src/windows/top_toolbar.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/windows/top_toolbar.c b/src/windows/top_toolbar.c index e7c49d44d7..66b8bee5de 100644 --- a/src/windows/top_toolbar.c +++ b/src/windows/top_toolbar.c @@ -368,8 +368,10 @@ static void window_top_toolbar_mousedown(int widgetIndex, rct_window*w, rct_widg numItems ); +#ifndef DISABLE_TWITCH if (_menuDropdownIncludesTwitch && gTwitchEnable) gDropdownItemsChecked |= (1 << 10); +#endif break; case WIDX_VIEW_MENU: top_toolbar_init_view_menu(w, widget); @@ -446,9 +448,11 @@ static void window_top_toolbar_dropdown() case DDIDX_EXIT_OPENRCT2: rct2_quit(); break; +#ifndef DISABLE_TWITCH case DDIDX_ENABLE_TWITCH: gTwitchEnable = !gTwitchEnable; break; +#endif } break; case WIDX_VIEW_MENU: From 8c27be2357ed093813166adb179a47b8b294af72 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Thu, 28 May 2015 19:46:59 +0100 Subject: [PATCH 10/32] OpenRCT2 no longer crashes after station abuse. Certain 8cars functions would move station track pieces that would cause the game to crash as they would not be at the correct location. OpenRCT2 will just skip trying to update the tiles of station track that has been modified this way --- src/ride/station.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/ride/station.c b/src/ride/station.c index a35e050c26..c982a44757 100644 --- a/src/ride/station.c +++ b/src/ride/station.c @@ -291,6 +291,10 @@ static void ride_invalidate_station_start(rct_ride *ride, int stationIndex, int y = (ride->station_starts[stationIndex] >> 8) * 32; mapElement = ride_get_station_start_track_element(ride, stationIndex); + // If no station track found return + if (mapElement == NULL) + return; + mapElement->properties.track.sequence &= 0x7F; if (dl != 0) mapElement->properties.track.sequence |= 0x80; From 31e0bdd76fb51f4c1df51e3ccc21e43a3a4798ec Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Thu, 28 May 2015 23:04:02 +0100 Subject: [PATCH 11/32] add partial working screenshot by command line --- projects/openrct2.vcxproj.user | 3 +- src/cmdline.c | 4 +- src/interface/screenshot.c | 147 +++++++++++++++++++++++++++++++++ src/interface/screenshot.h | 2 + src/openrct2.c | 80 ++++++++++-------- src/openrct2.h | 2 + src/platform/windows.c | 1 + 7 files changed, 201 insertions(+), 38 deletions(-) diff --git a/projects/openrct2.vcxproj.user b/projects/openrct2.vcxproj.user index 2b27afde74..0106f0df7f 100644 --- a/projects/openrct2.vcxproj.user +++ b/projects/openrct2.vcxproj.user @@ -4,8 +4,7 @@ $(TargetDir) WindowsLocalDebugger $(TargetDir)\openrct2.exe - - + screenshot "C:\Program Files (x86)\Infogrames\RollerCoaster Tycoon 2\Scenarios\Six Flags Magic Mountain.SC6" "test.png" 16384 8192 c c 0 0 false diff --git a/src/cmdline.c b/src/cmdline.c index 6779415e3c..013af496f2 100644 --- a/src/cmdline.c +++ b/src/cmdline.c @@ -22,6 +22,7 @@ #include #include "addresses.h" #include "cmdline.h" +#include "interface/screenshot.h" #include "openrct2.h" #include "platform/platform.h" #include "util/util.h" @@ -138,7 +139,8 @@ static int cmdline_for_none(const char **argv, int argc) struct { const char *firstArg; cmdline_action action; } cmdline_table[] = { { "intro", cmdline_for_intro }, { "edit", cmdline_for_edit }, - { "sprite", cmdline_for_sprite } + { "sprite", cmdline_for_sprite }, + { "screenshot", cmdline_for_screenshot } }; static int cmdline_call_action(const char **argv, int argc) diff --git a/src/interface/screenshot.c b/src/interface/screenshot.c index 13c2c1a571..289258b248 100644 --- a/src/interface/screenshot.c +++ b/src/interface/screenshot.c @@ -25,9 +25,11 @@ #include "../drawing/drawing.h" #include "../game.h" #include "../localisation/localisation.h" +#include "../openrct2.h" #include "../platform/platform.h" #include "../windows/error.h" #include "screenshot.h" +#include "viewport.h" static const char *_screenshot_format_extension[] = { ".bmp", ".png" }; @@ -273,4 +275,149 @@ int screenshot_dump_png() free(png); return index; +} + +bool screenshot_write_png(rct_drawpixelinfo *dpi, const char *path) +{ + unsigned int error; + unsigned char* png; + size_t pngSize; + LodePNGState state; + + lodepng_state_init(&state); + state.info_raw.colortype = LCT_PALETTE; + + // Get image size + int stride = (dpi->width + 3) & ~3; + + for (int i = 0; i < 256; i++) { + unsigned char r, g, b, a = 255; + + b = RCT2_ADDRESS(0x01424680, uint8)[i * 4 + 0]; + g = RCT2_ADDRESS(0x01424680, uint8)[i * 4 + 1]; + r = RCT2_ADDRESS(0x01424680, uint8)[i * 4 + 2]; + + lodepng_palette_add(&state.info_raw, r, g, b, a); + } + + error = lodepng_encode(&png, &pngSize, dpi->bits, stride, dpi->height, &state); + if (error != 0) { + free(png); + return false; + } else { + error = lodepng_save_file(png, pngSize, path); + if (error != 0) { + free(png); + return false; + } + } + + free(png); + return true; +} + +int cmdline_for_screenshot(const char **argv, int argc) +{ + if (argc != 4 && argc != 8) { + printf("Usage: openrct2 screenshot [ ]\n"); + return -1; + } + + bool customLocation = false; + bool centreMapX = false; + bool centreMapY = false; + int customX, customY, customZoom, customRotation; + + const char *inputPath = argv[0]; + const char *outputPath = argv[1]; + int resolutionWidth = atoi(argv[2]); + int resolutionHeight = atoi(argv[3]); + if (argc == 8) { + customLocation = true; + if (argv[4][0] == 'c') + centreMapX = true; + else + customX = atoi(argv[4]); + if (argv[5][0] == 'c') + centreMapY = true; + else + customY = atoi(argv[5]); + + customZoom = atoi(argv[6]); + customRotation = atoi(argv[7]) & 3; + } + + if (openrct2_initialise()) { + rct2_open_file(inputPath); + + RCT2_GLOBAL(RCT2_ADDRESS_RUN_INTRO_TICK_PART, uint8) = 0; + RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) = SCREEN_FLAGS_PLAYING; + + rct_viewport viewport; + viewport.x = 0; + viewport.y = 0; + viewport.width = resolutionWidth; + viewport.height = resolutionHeight; + viewport.view_width = viewport.width; + viewport.view_height = viewport.height; + viewport.var_11 = 0; + viewport.flags = 0; + + if (customLocation) { + if (centreMapX) + customX = (RCT2_GLOBAL(RCT2_ADDRESS_MAP_SIZE, uint8) / 2) * 32 + 16; + if (centreMapY) + customY = (RCT2_GLOBAL(RCT2_ADDRESS_MAP_SIZE, uint8) / 2) * 32 + 16; + + int x, y; + int z = map_element_height(customX, customY); + switch (customRotation) { + case 0: + x = customY - customX; + y = ((customX + customY) / 2) - z; + break; + case 1: + x = -customY - customX; + y = ((-customX + customY) / 2) - z; + break; + case 2: + x = -customY + customX; + y = ((-customX - customY) / 2) - z; + break; + case 3: + x = customY + customX; + y = ((customX - customY) / 2) - z; + break; + } + + viewport.view_x = x - (viewport.view_width / 2); + viewport.view_y = y - (viewport.view_height / 2); + viewport.zoom = customZoom; + + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint8) = customRotation; + } else { + viewport.view_x = RCT2_GLOBAL(RCT2_ADDRESS_SAVED_VIEW_X, sint16) - (viewport.view_width / 2); + viewport.view_y = RCT2_GLOBAL(RCT2_ADDRESS_SAVED_VIEW_Y, sint16) - (viewport.view_height / 2); + viewport.zoom = RCT2_GLOBAL(RCT2_ADDRESS_SAVED_VIEW_ZOOM_AND_ROTATION, uint16) & 0xFF; + + RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint8) = RCT2_GLOBAL(RCT2_ADDRESS_SAVED_VIEW_ZOOM_AND_ROTATION, uint16) >> 8; + } + + rct_drawpixelinfo dpi; + dpi.x = 0; + dpi.y = 0; + dpi.width = resolutionWidth; + dpi.height = resolutionHeight; + dpi.pitch = 0; + dpi.zoom_level = 0; + dpi.bits = malloc(dpi.width * dpi.height); + + viewport_render(&dpi, &viewport, 0, 0, viewport.width, viewport.height); + + screenshot_write_png(&dpi, outputPath); + + free(dpi.bits); + } + openrct2_dispose(); + return 1; } \ No newline at end of file diff --git a/src/interface/screenshot.h b/src/interface/screenshot.h index 2515ebe79d..3b2c8ae6fa 100644 --- a/src/interface/screenshot.h +++ b/src/interface/screenshot.h @@ -24,4 +24,6 @@ void screenshot_check(); int screenshot_dump(); +int cmdline_for_screenshot(const char **argv, int argc); + #endif \ No newline at end of file diff --git a/src/openrct2.c b/src/openrct2.c index c4457a2c09..7ac409ea88 100644 --- a/src/openrct2.c +++ b/src/openrct2.c @@ -108,24 +108,21 @@ static void openrct2_copy_original_user_files_over() openrct2_copy_files_over((char*)RCT2_ADDRESS_LANDSCAPES_PATH, path, ".sc6"); } -/** - * Launches the game, after command line arguments have been parsed and processed. - */ -void openrct2_launch() +bool openrct2_initialise() { char userPath[MAX_PATH]; platform_get_user_directory(userPath, NULL); if (!platform_ensure_directory_exists(userPath)) { log_fatal("Could not create user directory (do you have write access to your documents folder?)"); - return; + return false; } config_set_defaults(); if (!config_open_default()) { if (!config_find_or_browse_install_directory()) { log_fatal("An RCT2 install directory must be specified!"); - return; + return false; } } @@ -133,8 +130,8 @@ void openrct2_launch() // TODO add configuration option to allow multiple instances if (!platform_lock_single_instance()) { - fprintf(stderr, "OpenRCT2 is already running.\n"); - return; + log_fatal("OpenRCT2 is already running."); + return false; } get_system_info(); @@ -144,46 +141,57 @@ void openrct2_launch() language_open(gConfigGeneral.language); http_init(); if (!rct2_init()) - return; + return false; openrct2_copy_original_user_files_over(); Mixer_Init(NULL); + return true; +} - switch (gOpenRCT2StartupAction) { - case STARTUP_ACTION_INTRO: - RCT2_GLOBAL(RCT2_ADDRESS_RUN_INTRO_TICK_PART, uint8) = 8; - break; - case STARTUP_ACTION_TITLE: - RCT2_GLOBAL(RCT2_ADDRESS_RUN_INTRO_TICK_PART, uint8) = 0; - RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) = SCREEN_FLAGS_TITLE_DEMO; - break; - case STARTUP_ACTION_OPEN: - assert(gOpenRCT2StartupActionPath != NULL); - rct2_open_file(gOpenRCT2StartupActionPath); +/** + * Launches the game, after command line arguments have been parsed and processed. + */ +void openrct2_launch() +{ + if (openrct2_initialise()) { + switch (gOpenRCT2StartupAction) { + case STARTUP_ACTION_INTRO: + RCT2_GLOBAL(RCT2_ADDRESS_RUN_INTRO_TICK_PART, uint8) = 8; + break; + case STARTUP_ACTION_TITLE: + RCT2_GLOBAL(RCT2_ADDRESS_RUN_INTRO_TICK_PART, uint8) = 0; + RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) = SCREEN_FLAGS_TITLE_DEMO; + break; + case STARTUP_ACTION_OPEN: + assert(gOpenRCT2StartupActionPath != NULL); + rct2_open_file(gOpenRCT2StartupActionPath); - RCT2_GLOBAL(RCT2_ADDRESS_RUN_INTRO_TICK_PART, uint8) = 0; - RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) = SCREEN_FLAGS_PLAYING; - break; - case STARTUP_ACTION_EDIT: - if (strlen(gOpenRCT2StartupActionPath) == 0) { - editor_load(); - } else { - editor_load_landscape(gOpenRCT2StartupActionPath); + RCT2_GLOBAL(RCT2_ADDRESS_RUN_INTRO_TICK_PART, uint8) = 0; + RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) = SCREEN_FLAGS_PLAYING; + break; + case STARTUP_ACTION_EDIT: + if (strlen(gOpenRCT2StartupActionPath) == 0) { + editor_load(); + } else { + editor_load_landscape(gOpenRCT2StartupActionPath); + } + break; } - break; + openrct2_loop(); } - - log_verbose("begin openrct2 loop"); - openrct2_loop(); - - http_dispose(); - platform_free(); + openrct2_dispose(); // HACK Some threads are still running which causes the game to not terminate. Investigation required! exit(gExitCode); } +void openrct2_dispose() +{ + http_dispose(); + platform_free(); +} + /** * Run the main game loop until the finished flag is set at 40fps (25ms interval). */ @@ -191,6 +199,8 @@ static void openrct2_loop() { uint32 currentTick, ticksElapsed, lastTick = 0; + log_verbose("begin openrct2 loop"); + _finished = 0; do { currentTick = SDL_GetTicks(); diff --git a/src/openrct2.h b/src/openrct2.h index f265c97833..5cb984fa6e 100644 --- a/src/openrct2.h +++ b/src/openrct2.h @@ -33,7 +33,9 @@ enum { extern int gOpenRCT2StartupAction; extern char gOpenRCT2StartupActionPath[512]; +bool openrct2_initialise(); void openrct2_launch(); +void openrct2_dispose(); void openrct2_finish(); #endif \ No newline at end of file diff --git a/src/platform/windows.c b/src/platform/windows.c index 8ce7bedd9b..eed058f77b 100644 --- a/src/platform/windows.c +++ b/src/platform/windows.c @@ -80,6 +80,7 @@ __declspec(dllexport) int StartOpenRCT(HINSTANCE hInstance, HINSTANCE hPrevInsta if (runGame) openrct2_launch(); + exit(gExitCode); return gExitCode; } From 12d5542861fae096ef17de82b7033ca587bc15eb Mon Sep 17 00:00:00 2001 From: Ted John Date: Fri, 29 May 2015 04:00:17 +0100 Subject: [PATCH 12/32] Merge Localisation/master into OpenRCT2/develop. --- data/language/english_us.txt | 2 +- data/language/german.txt | 240 +++++++++++++++++++---------------- 2 files changed, 132 insertions(+), 110 deletions(-) diff --git a/data/language/english_us.txt b/data/language/english_us.txt index 9e909d51d4..19d49ec620 100644 --- a/data/language/english_us.txt +++ b/data/language/english_us.txt @@ -3490,7 +3490,7 @@ STR_5150 :Enable debugging tools #Thousands separator STR_5151 :, #Decimals separator -STR_5152 :. +STR_5152 :. STR_5153 :RCT1 color scheme STR_5154 :Hardware display STR_5155 :Allow testing of unfinished tracks diff --git a/data/language/german.txt b/data/language/german.txt index d0b42259da..8ad21e01ad 100644 --- a/data/language/german.txt +++ b/data/language/german.txt @@ -564,7 +564,7 @@ STR_0559 : STR_0560 : STR_0561 : STR_0562 : -STR_0563 :Die Fahrgäste sitzen in komfortablen Wagen mit einfachen Beckenhalterungen, in denen Sie gigantische, gemäßigte Gefälle erleben, aber auch viel Zeit oben `in der Luft' verbringen +STR_0563 :Die Fahrgäste sitzen in komfortablen Wagen mit einfachen Beckenhalterungen, in denen sie gigantische, gemäßigte Gefälle erleben, aber auch viel Zeit oben `in der Luft' verbringen STR_0564 :Diese Holzachterbahn ist schnell, rauh, laut und gibt einem das Gefühl, außer Kontrolle zu sein, wobei man häufig `in der Luft' ist STR_0565 :Eine einfache Holzachterbahn mit nur leichten Gefällen und Kurven, bei der die Wagen nur mit Hilfe von seitlichen Führungsrollen und der Schwerkraft auf der Strecke gehalten werden STR_0566 :Voneinander unabhängige Achterbahnwagen rasen auf einer engen Zickzack-Strecke mit scharfen Kurven und kurzen, starken Gefällen @@ -857,7 +857,7 @@ STR_0852 :{WINDOW_COLOUR_2}Grafik von Simon Foster STR_0853 :{WINDOW_COLOUR_2}Sound und Musik von Allister Brimble STR_0854 :{WINDOW_COLOUR_2}Zusätzliche Sounds aufgenommen von David Ellis STR_0855 :{WINDOW_COLOUR_2}Repräsentation von Jacqui Lyons bei Marjacq Ltd. -STR_0856 :{WINDOW_COLOUR_2}Dank gilt:- +STR_0856 :{WINDOW_COLOUR_2}Dank gilt: STR_0857 :{WINDOW_COLOUR_2}Peter James Adcock, Joe Booth und John Wardley STR_0858 :{WINDOW_COLOUR_2} STR_0859 :{WINDOW_COLOUR_2} @@ -946,7 +946,7 @@ STR_0941 :Vertikale Flächen entfernen STR_0942 :Bahnen ausblenden STR_0943 :Szenerie ausblenden STR_0944 :Speichern -STR_0945 :Nicht sp. +STR_0945 :Nicht speich. STR_0946 :Abbrechen STR_0947 :Vor dem Laden speichern? STR_0948 :Vor dem Beenden speichern? @@ -1059,7 +1059,7 @@ STR_1054 :{SMALLFONT}{BLACK}Bahn/Attraktion benennen STR_1055 :{SMALLFONT}{BLACK}Person benennen STR_1056 :{SMALLFONT}{BLACK}Mitarbeiter benennen STR_1057 :Name der Bahn/Attraktion -STR_1058 :Neuen Namen für diese Bahn/Attraktion eingeben:- +STR_1058 :Namen für diese Bahn/Attraktion eingeben: STR_1059 :Bahn/Attraktion kann nicht umbenannt werden... STR_1060 :Ungültiger Bahn-/Attraktionsname STR_1061 :Normaler Modus @@ -1356,8 +1356,8 @@ STR_1351 :{WINDOW_COLOUR_2}Max. negative vertikale G-Kraft: {OUTLINE}{RED}{CO STR_1352 :{WINDOW_COLOUR_2}Max. seitliche G-Kraft: {BLACK}{COMMA2DP32}G STR_1353 :{WINDOW_COLOUR_2}Max. seitliche G-Kraft: {OUTLINE}{RED}{COMMA2DP32}G STR_1354 :{WINDOW_COLOUR_2}Höchste Fallhöhe: {BLACK}{LENGTH} -STR_1355 :{WINDOW_COLOUR_2}Abf.: {BLACK}{COMMA16} -STR_1356 :{WINDOW_COLOUR_2}Umkehr.: {BLACK}{COMMA16} +STR_1355 :{WINDOW_COLOUR_2}Abfälle: {BLACK}{COMMA16} +STR_1356 :{WINDOW_COLOUR_2}Umkehrungen: {BLACK}{COMMA16} STR_1357 :{WINDOW_COLOUR_2}Löcher: {BLACK}{COMMA16} STR_1358 :{WINDOW_COLOUR_2}Gesamtzeit `in der Luft': {BLACK}{COMMA2DP32}Sek. STR_1359 :{WINDOW_COLOUR_2}Wartezeit: {BLACK}{COMMA16} Minute @@ -1454,7 +1454,7 @@ STR_1449 :{SPRITE} {STRINGID}{NEWLINE}({STRINGID}) STR_1450 :{INLINE_SPRITE}{09}{20}{00}{00}{SPRITE} {STRINGID}{NEWLINE}({STRINGID}) STR_1451 :{STRINGID}{NEWLINE}({STRINGID}) STR_1452 :Name des Besuchers -STR_1453 :Namen für diesen Besucher eingeben:- +STR_1453 :Namen für diesen Besucher eingeben: STR_1454 :Besucher kann nicht benannt werden... STR_1455 :Ungültiger Name für Besucher STR_1456 :{WINDOW_COLOUR_2}Ausgegebenes Geld: {BLACK}{CURRENCY2DP} @@ -1701,8 +1701,8 @@ STR_1696 :{SMALLFONT}{BLACK}Besucherinformationen STR_1697 :Können nicht in Wartebereich platziert werden STR_1698 :Können nur in Wartebereich platziert werden STR_1699 :Zu viele Leute im Spiel -STR_1700 :Neuen Parkpfleger einstellen -STR_1701 :Neuen Mechaniker einstellen +STR_1700 :Neuen Parkpfleger einst. +STR_1701 :Neuen Mechaniker einst. STR_1702 :Neuen Aufseher einstellen STR_1703 :Neuen Animateur einstellen STR_1704 :Es kann kein neuer Mitarbeiter eingestellt werden... @@ -1720,7 +1720,7 @@ STR_1715 :{INLINE_SPRITE}{250}{19}{00}{00}{WINDOW_COLOUR_2}Gras mähen STR_1716 :Ungültiger Name für Park STR_1717 :Park kann nicht umbenannt werden... STR_1718 :Parkname -STR_1719 :Geben Sie einen Parknamen ein:- +STR_1719 :Geben Sie einen Parknamen ein: STR_1720 :{SMALLFONT}{BLACK}Park benennen STR_1721 :Park geschlossen STR_1722 :Park eröffnet @@ -1894,7 +1894,7 @@ STR_1889 :{WINDOW_COLOUR_2}Ausfallzeit: {MOVE_X}{255}{BLACK}{COMMA16}% STR_1890 :{SMALLFONT}{BLACK}Auswählen, wie oft ein Mechaniker diese Bahn überprüfen soll STR_1891 :Noch kein {STRINGID} im Park STR_1892 :RollerCoaster Tycoon 2 -STR_1893 :Legen Sie die RollerCoaster Tycoon 2-CD in folgendes Laufwerk ein:- +STR_1893 :Legen Sie die RollerCoaster Tycoon 2-CD in folgendes Laufwerk ein: STR_1894 :{WINDOW_COLOUR_2}{STRINGID} verkauft: {BLACK}{COMMA32} STR_1895 :{SMALLFONT}{BLACK}Neue Bahn/Attraktion bauen STR_1896 :{WINDOW_COLOUR_2}Ausgaben/Einnahmen @@ -1917,7 +1917,7 @@ STR_1912 :{MONTH} STR_1913 :{BLACK}+{CURRENCY2DP} STR_1914 :{BLACK}{CURRENCY2DP} STR_1915 :{RED}{CURRENCY2DP} -STR_1916 :{WINDOW_COLOUR_2}Darleh.: +STR_1916 :{WINDOW_COLOUR_2}Darlehen: STR_1917 :{POP16}{POP16}{POP16}{CURRENCY} STR_1918 :Es können keine weiteren Gelder geliehen werden! STR_1919 :Nicht genügend Geld verfügbar! @@ -2250,8 +2250,8 @@ STR_2245 :Oktober STR_2246 :November STR_2247 :Dezember STR_2248 :Bahn/Attraktion kann nicht abgerissen werden... -STR_2249 :{BABYBLUE}Neue Bahn/Attraktion jetzt verfügbar:-{NEWLINE}{STRINGID} -STR_2250 :{BABYBLUE}Neue/s/r Szenerie/Thema jetzt verfügbar:-{NEWLINE}{STRINGID} +STR_2249 :{BABYBLUE}Neue Bahn/Attraktion jetzt verfügbar:{NEWLINE}{STRINGID} +STR_2250 :{BABYBLUE}Neue Szenerie jetzt verfügbar:{NEWLINE}{STRINGID} STR_2251 :Kann nur auf Wegen gebaut werden! STR_2252 :Kann nur über Wege gebaut werden! STR_2253 :Transportbahnen @@ -2262,8 +2262,8 @@ STR_2257 :Wasserbahnen STR_2258 :Läden & Stände STR_2259 :Szenerie & Thema STR_2260 :Keine Finanzierung -STR_2261 :Mindestfinanzier. -STR_2262 :Normale Finanzier. +STR_2261 :Mindestfinanzierung +STR_2262 :Normale Finanzierung STR_2263 :Höchstfinanzierung STR_2264 :Forschungsfinanzierung STR_2265 :{WINDOW_COLOUR_2}Kosten: {BLACK}{CURRENCY} pro Monat @@ -2354,10 +2354,10 @@ STR_2349 :{WINDOW_COLOUR_2}Lohn: {BLACK}{CURRENCY} pro Monat STR_2350 :{WINDOW_COLOUR_2}Angestellt: {BLACK}{MONTHYEAR} STR_2351 :{WINDOW_COLOUR_2}Gemähte Rasen: {BLACK}{COMMA16} STR_2352 :{WINDOW_COLOUR_2}Bewässerte Beete: {BLACK}{COMMA16} -STR_2353 :{WINDOW_COLOUR_2}Beseit. Abfall: {BLACK}{COMMA16} -STR_2354 :{WINDOW_COLOUR_2}Gel. Mülleimer: {BLACK}{COMMA16} -STR_2355 :{WINDOW_COLOUR_2}Repar. Bahnen: {BLACK}{COMMA16} -STR_2356 :{WINDOW_COLOUR_2}Inspiz. Bahnen: {BLACK}{COMMA16} +STR_2353 :{WINDOW_COLOUR_2}Beseitigter Abfall: {BLACK}{COMMA16} +STR_2354 :{WINDOW_COLOUR_2}Geleerte Mülleimer: {BLACK}{COMMA16} +STR_2355 :{WINDOW_COLOUR_2}Reparierte Bahnen: {BLACK}{COMMA16} +STR_2356 :{WINDOW_COLOUR_2}Inspizierte Bahnen: {BLACK}{COMMA16} STR_2357 :Haus STR_2358 :Einheiten STR_2359 :Echte Werte @@ -2408,8 +2408,8 @@ STR_2403 :Besucherzahl im Park STR_2404 :Monatliche Einkünfte durch Fahrttickets STR_2405 :Bauen Sie 10 Achterb. einer best. Länge STR_2406 :Stellen Sie den Bau von 5 Achterb. fertig -STR_2407 :Darleh. zurückz. u. best. Verkehrsw. err. -STR_2408 :Monatl. Gewinn d. Speisen/Werbeartikel +STR_2407 :Darlehen zurückzahlen und bestimmten Verkehrswert erreichen +STR_2408 :Monatlicher Gewinn durch Speisen/Werbeartikel STR_2409 :{WINDOW_COLOUR_2}Gerade durchgeführte Marketingkampagnen STR_2410 :{BLACK}Keine STR_2411 :{WINDOW_COLOUR_2}Verfügbare Marketingkampagnen @@ -2426,9 +2426,9 @@ STR_2421 :Gratis-{STRINGID} STR_2422 :Werbekampagne für {STRINGID} STR_2423 :Werbekampagne für {STRINGID} STR_2424 :{WINDOW_COLOUR_2}Gutscheine für freien Eintritt in den Park -STR_2425 :{WINDOW_COLOUR_2}Gutscheine für Freifahrt auf best. Bahn -STR_2426 :{WINDOW_COLOUR_2}Gutscheine für halben Eintrittspreis z. Park -STR_2427 :{WINDOW_COLOUR_2}Gutscheine für kostenl. Speise oder Getränk +STR_2425 :{WINDOW_COLOUR_2}Gutscheine für Freifahrt auf bestimmter Bahn +STR_2426 :{WINDOW_COLOUR_2}Gutscheine für halben Eintrittspreis zum Park +STR_2427 :{WINDOW_COLOUR_2}Gutscheine für kostenlose Speise oder Getränk STR_2428 :{WINDOW_COLOUR_2}Werbekampagne für den Park STR_2429 :{WINDOW_COLOUR_2}Werbekampagne für eine bestimmte Bahn STR_2430 :{BLACK}Gutscheine f. freien Eintr. z.{STRINGID} @@ -2483,7 +2483,7 @@ STR_2478 :{SMALLFONT}{BLACK}Geschwindigkeitsdiagramm im Zeitverlauf anzeigen STR_2479 :{SMALLFONT}{BLACK}Höhendiagramm im Zeitverlauf anzeigen STR_2480 :{SMALLFONT}{BLACK}Diagramm der vertikalen Beschleunigung im Zeitverlauf anzeigen STR_2481 :{SMALLFONT}{BLACK}Diagramm der seitlichen Beschleunigung im Zeitverlauf anzeigen -STR_2482 :{SMALLFONT}{BLACK}Gewinn: {CURRENCY} pro Woche, Verkehrswert: {CURRENCY} +STR_2482 :{SMALLFONT}{BLACK}Gewinn: {CURRENCY} pro Woche{NEWLINE}Verkehrswert: {CURRENCY} STR_2483 :{WINDOW_COLOUR_2}Wöchentlicher Gewinn: {BLACK}+{CURRENCY2DP} STR_2484 :{WINDOW_COLOUR_2}Wöchentlicher Gewinn: {RED}{CURRENCY2DP} STR_2485 :Steuerung @@ -2683,9 +2683,9 @@ STR_2677 :??? STR_2678 :??? STR_2679 :??? STR_2680 :Alle Forschungen beendet -STR_2681 :{MEDIUMFONT}{BLACK}Erhöht ihr Geld um 5.000 -STR_2682 :{MEDIUMFONT}{BLACK}Zwischen freiem und kostenpflichtigem Eintritt umschalten -STR_2683 :{MEDIUMFONT}{BLACK}Erhöht die Glücklichkeit aller Besucher zum Maximum +STR_2681 :{MEDIUMFONT}{BLACK}Erhöht Ihr Geld um 5.000 +STR_2682 :{MEDIUMFONT}{BLACK}Zw. freiem und kostenpfl. Eintritt umsch. +STR_2683 :{MEDIUMFONT}{BLACK}Erhöht das Vergnügen der Besucher maximal STR_2684 :{MEDIUMFONT}{BLACK}Eine große Gruppe von Besuchern tritt ein STR_2685 :Simplex Noise Parameters STR_2686 :{WINDOW_COLOUR_2}Niedrig: @@ -2698,7 +2698,7 @@ STR_2692 :{WINDOW_COLOUR_2}Wasserhöhe: STR_2693 :{WINDOW_COLOUR_2}Terrain: STR_2694 :Generieren STR_2695 :Zufälliges Terrain -STR_2696 :Bäume Platzieren +STR_2696 :Bäume platzieren STR_2697 :??? STR_2698 :??? STR_2699 :??? @@ -2710,9 +2710,9 @@ STR_2704 :Alle 4 Monate STR_2705 :Jedes Jahr STR_2706 :Nie STR_2707 :Neues Fenster -STR_2708 :{WINDOW_COLOUR_1}Sind sie sicher, dass sie {STRINGID} überschreiben möchten? +STR_2708 :{WINDOW_COLOUR_1}Sind Sie sicher, dass Sie {STRINGID} überschreiben möchten? STR_2709 :Überschreiben -STR_2710 :Geben sie den Dateinamen ein. +STR_2710 :Geben Sie den Dateinamen ein. STR_2711 :; STR_2712 := STR_2713 :, @@ -2720,24 +2720,24 @@ STR_2714 :- STR_2715 :. STR_2716 :/ STR_2717 :' -STR_2718 :??? -STR_2719 :??? -STR_2720 :??? -STR_2721 :??? -STR_2722 :??? -STR_2723 :??? -STR_2724 :??? -STR_2725 :??? -STR_2726 :??? -STR_2727 :??? -STR_2728 :??? -STR_2729 :??? -STR_2730 :??? -STR_2731 :??? -STR_2732 :??? -STR_2733 :??? -STR_2734 :??? -STR_2735 :??? +STR_2718 :(Hoch) +STR_2719 :(Neue Datei) +STR_2720 :{UINT16}s +STR_2721 :{UINT16}s +STR_2722 :{UINT16}min:{UINT16}s +STR_2723 :{UINT16}min:{UINT16}s +STR_2724 :{UINT16}min:{UINT16}s +STR_2725 :{UINT16}min:{UINT16}s +STR_2726 :{UINT16}min +STR_2727 :{UINT16}min +STR_2728 :{UINT16}h:{UINT16}min +STR_2729 :{UINT16}h:{UINT16}min +STR_2730 :{UINT16}h:{UINT16}min +STR_2731 :{UINT16}h:{UINT16}min +STR_2732 :{COMMA16}ft +STR_2733 :{COMMA16}m +STR_2734 :{COMMA16}mph +STR_2735 :{COMMA16}km/h STR_2736 :{MONTH}, Jahr {COMMA16} STR_2737 :{STRINGID} {MONTH}, Jahr {COMMA16} STR_2738 :Musik im Hauptmenü @@ -2745,7 +2745,7 @@ STR_2739 :Keine STR_2740 :RollerCoaster Tycoon 1 STR_2741 :RollerCoaster Tycoon 2 STR_2742 :css50.dat nicht gefunden -STR_2743 :Kopieren sie data\css17.dat aus ihrem RCT1-Verzeichnis nach data\css50.dat in ihrem RCT2-Verzeichnis. +STR_2743 :Kopieren Sie data\css17.dat aus Ihrem RCT1-Verzeichnis nach data\css50.dat in Ihrem RCT2-Verzeichnis. STR_2744 :[ STR_2745 :\ STR_2746 :] @@ -2753,22 +2753,22 @@ STR_2747 :{ENDQUOTES} STR_2748 :Leiste STR_2749 :Mein neues Szenario # New strings used in the cheats window previously these were ??? -STR_2750 :??? -STR_2751 :??? +STR_2750 :Alle Gegenstände nach oben bewegen +STR_2751 :Alle Gegenstände nach unten bewegen STR_2752 :Gras beseitigen STR_2753 :Rasen mähen STR_2754 :Pflanzen gießen -STR_2755 :Vandalismus beseitigen +STR_2755 :Vandalismus bes. STR_2756 :Müll beseitigen -STR_2757 :Schönes Wetter erzwingen -STR_2758 :Gewitter erzwingen -STR_2759 :Zero Clearance +STR_2757 :Schönes Wetter +STR_2758 :Gewitter +STR_2759 :Kein Zwischenraum STR_2760 :+5000 Geld STR_2761 :Bezahlen für Eintritt STR_2762 :Bezahlen für Bahnen STR_2763 :??? STR_2764 :Glückliche Gäste -STR_2765 :Große Menschenmenge +STR_2765 :Große Straßenbahn STR_2766 :Szenario gewinnen STR_2767 :Wetter stoppen STR_2768 :Wetter fortsetzen @@ -2782,21 +2782,21 @@ STR_2775 :Vollbild (Desktop) STR_2776 :Sprache STR_2777 :{MOVE_X}{SMALLFONT}{STRING} STR_2778 :{RIGHTGUILLEMET}{MOVE_X}{SMALLFONT}{STRING} -STR_2779 :??? -STR_2780 :??? +STR_2779 :Ansichtsfenster {COMMA16} +STR_2780 :Extra Ansichtsfenster # End of new strings STR_2781 :{STRINGID}:{MOVE_X}{195}{STRINGID}{STRINGID} STR_2782 :UMSCHALT + STR_2783 :STRG + STR_2784 :Tastaturkürzel ändern -STR_2785 :{WINDOW_COLOUR_2}Drücken Sie die neue Kürzeltaste für:-{NEWLINE}{OPENQUOTES}{STRINGID}{ENDQUOTES} +STR_2785 :{WINDOW_COLOUR_2}Drücken Sie die neue Kürzeltaste für:{NEWLINE}{OPENQUOTES}{STRINGID}{ENDQUOTES} STR_2786 :{SMALLFONT}{BLACK}Klicken Sie auf die Kürzelbeschreibung, um eine neue Taste auszuwählen STR_2787 :{WINDOW_COLOUR_2}Verkehrswert: {BLACK}{CURRENCY} STR_2788 :{WINDOW_COLOUR_2}Glückwunsch!{NEWLINE}{BLACK}Sie haben Ihr Ziel mit einem Firmenwert von {CURRENCY} erreicht! STR_2789 :{WINDOW_COLOUR_2}Sie haben Ihr Ziel nicht erreicht! STR_2790 :Geben Sie einen Namen in das Szenariodiagramm ein STR_2791 :Namen eingeben -STR_2792 :Geben Sie Ihren Namen für das Szenariodiagramm ein:- +STR_2792 :Geben Sie Ihren Namen für das Szenariodiagramm ein: STR_2793 :{SMALLFONT}(Durchgeführt von {STRINGID}) STR_2794 :{WINDOW_COLOUR_2}Durchgeführt von: {BLACK}{STRINGID}{NEWLINE}{WINDOW_COLOUR_2} mit einem Firmenwert von: {BLACK}{CURRENCY} STR_2795 :Sortieren @@ -2805,7 +2805,7 @@ STR_2797 :Ansicht rollen, wenn Zeiger am Bildschirmrand ist STR_2798 :{SMALLFONT}{BLACK}Wählen Sie aus, ob die Ansicht gerollt werden soll, wenn sich der Mauszeiger am Bildschirmrand befindet STR_2799 :{SMALLFONT}{BLACK}Steuertastenzuweisungen anzeigen oder ändern STR_2800 :{WINDOW_COLOUR_2}Besucher gesammt: {BLACK}{COMMA32} -STR_2801 :{WINDOW_COLOUR_2}Einkünfte durch Eintrittskarten: {BLACK}{CURRENCY2DP} +STR_2801 :{WINDOW_COLOUR_2}Einkünfte d. Eintrittskarten: {BLACK}{CURRENCY2DP} STR_2802 :Karte STR_2803 :{SMALLFONT}{BLACK}Diese Besucher auf Karte hervorheben STR_2804 :{SMALLFONT}{BLACK}Diese Mitarbeiter auf Karte hervorheben @@ -2982,12 +2982,12 @@ STR_2974 :Alternatives Farbschema 3 STR_2975 :{SMALLFONT}{BLACK}Wählen Sie das Farbschema aus, das geändert oder mit dem eine Bahn gestrichen werden soll STR_2976 :{SMALLFONT}{BLACK}Streichen Sie einen bestimmten Bereich dieser Bahn mit dem ausgewählten Farbschema STR_2977 :Mitarbeitername -STR_2978 :Neuen Namen für diesen Mitarbeiter eingeben:- +STR_2978 :Neuen Namen für diesen Mitarbeiter eingeben: STR_2979 :Dieser Mitarbeiter kann nicht benannt werden... STR_2980 :Zu viele Banner im Spiel STR_2981 :{RED}Kein Zutritt - - STR_2982 :Bannertext -STR_2983 :Neuen Text für diesen Banner eingeben:- +STR_2983 :Neuen Text für diesen Banner eingeben: STR_2984 :Neuer Text für den Banner kann nicht erstellt werden... STR_2985 :Banner STR_2986 :{SMALLFONT}{BLACK}Text auf Banner ändern @@ -2997,7 +2997,7 @@ STR_2989 :{SMALLFONT}{BLACK}Hauptfarbe auswählen STR_2990 :{SMALLFONT}{BLACK}Textfarbe auswählen STR_2991 :Schild STR_2992 :Schildtext -STR_2993 :Neuen Text für dieses Schild eingeben:- +STR_2993 :Neuen Text für dieses Schild eingeben: STR_2994 :{SMALLFONT}{BLACK}Text auf Schild ändern STR_2995 :{SMALLFONT}{BLACK}Dieses Schild abreißen STR_2996 :{BLACK}ABC @@ -3260,14 +3260,14 @@ STR_3252 :Max. Darlehensgröße kann nicht weiter erhöht werden! STR_3253 :Max. Darlehensgröße kann nicht weiter reduziert werden! STR_3254 :Zinsrate kann nicht weiter erhöht werden! STR_3255 :Zinsrate kann nicht weiter reduziert werden! -STR_3256 :Weniger aufreg. Bahnen bevorzugt +STR_3256 :Weniger aufregendere Bahnen bevorzugt STR_3257 :{SMALLFONT}{BLACK}Wählen Sie aus, ob die Besucher im Allgemeinen weniger aufregende Bahnen vorziehen STR_3258 :Aufregendere Bahnen bevorzugt STR_3259 :{SMALLFONT}{BLACK}Wählen Sie aus, ob die Besucher im Allgemeinen aufregendere Bahnen vorziehen -STR_3260 :{WINDOW_COLOUR_2}Durchschn. Geld pro Bes.: -STR_3261 :{WINDOW_COLOUR_2}Anfangsvergn. d. Besuch.: -STR_3262 :{WINDOW_COLOUR_2}Anfangshunger d. Besuch.: -STR_3263 :{WINDOW_COLOUR_2}Anfangsdurst d. Besucher: +STR_3260 :{WINDOW_COLOUR_2}Durchschnittliches Geld pro Besucher: +STR_3261 :{WINDOW_COLOUR_2}Anfangsvergnügen der Besucher: +STR_3262 :{WINDOW_COLOUR_2}Anfangshunger der Besucher: +STR_3263 :{WINDOW_COLOUR_2}Anfangsdurst der Besucher: STR_3264 :Dies kann nicht weiter erhöht werden! STR_3265 :Dies kann nicht weiter reduziert werden! STR_3266 :{SMALLFONT}{BLACK}Wählen Sie aus, was der Park für Eintritt und Fahrten verlangt @@ -3298,7 +3298,7 @@ STR_3290 :Kühl und feucht STR_3291 :Warm STR_3292 :Heiß und trocken STR_3293 :Kalt -STR_3294 :Änderung... +STR_3294 :Ändern... STR_3295 :{SMALLFONT}{BLACK}Namen des Parks ändern STR_3296 :{SMALLFONT}{BLACK}Namen des Szenarios ändern STR_3297 :{SMALLFONT}{BLACK}Detailhinweise zu Park/Szenario ändern @@ -3308,9 +3308,9 @@ STR_3300 :{WINDOW_COLOUR_2}Szenarioname: {BLACK}{STRINGID} STR_3301 :{WINDOW_COLOUR_2}Zieldatum: STR_3302 :{WINDOW_COLOUR_2}{MONTHYEAR} STR_3303 :{WINDOW_COLOUR_2}Besucheranzahl: -STR_3304 :{WINDOW_COLOUR_2}Verkehrsw.: +STR_3304 :{WINDOW_COLOUR_2}Verkehrswert: STR_3305 :{WINDOW_COLOUR_2}Mon. Einkünfte: -STR_3306 :{WINDOW_COLOUR_2}Mon. Gewinn: +STR_3306 :{WINDOW_COLOUR_2}Monatlicher Gewinn: STR_3307 :{WINDOW_COLOUR_2}Mindestlänge: STR_3308 :{WINDOW_COLOUR_2}Nervenkitzelwert: STR_3309 :{WINDOW_COLOUR_2}{COMMA16} @@ -3318,9 +3318,9 @@ STR_3310 :{WINDOW_COLOUR_2}{LENGTH} STR_3311 :{WINDOW_COLOUR_2}{COMMA2DP32} STR_3312 :{WINDOW_COLOUR_2}Bahnen/Attrakt. unter Beibehaltungsauftrag: STR_3313 :Szenarioname -STR_3314 :Namen für Szenario eingeben:- +STR_3314 :Namen für Szenario eingeben: STR_3315 :Park-/Szenariodetails -STR_3316 :Beschreibung für dieses Szenario eingeben:- +STR_3316 :Beschreibung für dieses Szenario eingeben: STR_3317 :Noch keine Details STR_3318 :{SMALLFONT}{BLACK}Wählen Sie aus, in welcher Gruppe dieses Szenario vorkommt STR_3319 :{WINDOW_COLOUR_2}Szenariogruppe: @@ -3355,7 +3355,7 @@ STR_3347 :Bahn ist zu lang, enthält zu viele Elemente oder Szenerie ist zu z STR_3348 :Umbenennen STR_3349 :Löschen STR_3350 :Streckenentwurfsname -STR_3351 :Neuen Namen für diesen Streckenentwurf eingeben:- +STR_3351 :Neuen Namen für diesen Streckenentwurf eingeben: STR_3352 :Streckenentwurf kann nicht umbenannt werden... STR_3353 :Neuer Name enthält ungültige Zeichen STR_3354 :Entweder besteht bereits eine Datei mit diesem Namen oder die Datei ist schreibgeschützt @@ -3368,7 +3368,7 @@ STR_3360 :Warnung! STR_3361 :Zu viele Streckenentwürfe dieser Art - einige werden nicht aufgeführt. STR_3362 :Erzwungenes Software-Buffer-Mixing STR_3363 :{SMALLFONT}{BLACK}Diese Option wählen, falls das Spiel jedesmal kurz anhält sobald Töne gespielt werden oder falls ein Rauschen zu hören ist. -STR_3364 :Fortgeschr. +STR_3364 :Fortgeschritten STR_3365 :{SMALLFONT}{BLACK}Ermöglichen Sie die Auswahl einzelner Szenerieobjekte zusätzlich zu Szeneriegruppen STR_3366 :{BLACK}= Bahn STR_3367 :{BLACK}= Imbissstand @@ -3453,38 +3453,60 @@ STR_3445 :Patrouillenbereich festlegen STR_3446 :Patrouillenbereich verwerfen # New strings, cleaner -STR_5120 :Show finances button on toolbar -STR_5121 :Show research button on toolbar -STR_5122 :Show all vehicles sharing a track/ride type -STR_5123 :Renew rides -STR_5124 :No Six Flags -STR_5125 :All destructable -STR_5126 :Random title music -STR_5127 :{SMALLFONT}{BLACK}Disable land elevation -STR_5128 :Selection size -STR_5129 :Enter selection size between {COMMA16} and {COMMA16} -STR_5130 :Map size -STR_5131 :Enter map size between {COMMA16} and {COMMA16} -STR_5132 :Fix all rides -STR_5133 :{SMALLFONT}{BLACK}Adjust smaller area of land rights -STR_5134 :{SMALLFONT}{BLACK}Adjust larger area of land rights -STR_5135 :{SMALLFONT}{BLACK}Buy land rights and construction rights -STR_5136 :Land rights -STR_5137 :Allow lift hill and launch speeds{NEWLINE}up to {VELOCITY} +STR_5120 :Finanzen in der Symbolleiste anzeigen +STR_5121 :Forschung in der Symbolleiste anzeigen +STR_5122 :Fahrzeuge gleicher Strecke/Bahnart anzeigen +STR_5123 :Bahnen erneuern +STR_5124 :Keine Six Flags +STR_5125 :Alles zerstörbar +STR_5126 :Zufällige Titelmusik +STR_5127 :{SMALLFONT}{BLACK}Höhenanpassung deaktivieren +STR_5128 :Auswahlgröße +STR_5129 :Auswahlgröße zwischen {COMMA16} und {COMMA16} eingeben: +STR_5130 :Kartengröße +STR_5131 :Kartengröße zwischen {COMMA16} und {COMMA16} eingeben: +STR_5132 :Bahnen reparieren +STR_5133 :{SMALLFONT}{BLACK}Kleineren Landbereich anpassen +STR_5134 :{SMALLFONT}{BLACK}Größeren Landbereich anpassen +STR_5135 :{SMALLFONT}{BLACK}Kaufe Land- und Baurechte +STR_5136 :Landrechte +STR_5137 :Erlaube Lifthügel- und Antriebsgeschw.{NEWLINE}bis zu {VELOCITY} STR_5138 :{SMALLFONT}{WINDOW_COLOUR_2}{STRINGID} STR_5139 :{WHITE}{STRINGID} -STR_5140 :Disable brakes failure -STR_5141 :Disable all breakdowns -STR_5142 :Normal Speed -STR_5143 :Quick Speed -STR_5144 :Fast Speed -STR_5145 :Turbo Speed -STR_5146 :Hyper Speed -STR_5147 :Show cheats button on toolbar -STR_5148 :{SMALLFONT}{BLACK}Change the game speed -STR_5149 :{SMALLFONT}{BLACK}Open the cheats window -STR_5150 :Enable debugging tools -#Thousands separator +STR_5140 :Deaktiviere Bremsenfehlfunktion +STR_5141 :Deaktiviere alle Störungen +STR_5142 :Normale Geschwindigkeit +STR_5143 :Erhöhte Geschwindigkeit +STR_5144 :Hohe Geschwindigkeit +STR_5145 :Sehr Hohe Geschwindigkeit +STR_5146 :Extreme Geschwindigkeit +STR_5147 :Cheats in der Symbolleiste anzeigen +STR_5148 :{SMALLFONT}{BLACK}Spielgeschwindigkeit ändern +STR_5149 :{SMALLFONT}{BLACK}Cheats anzeigen +STR_5150 :Aktiviere Debugging-Tools STR_5151 :. -#Decimal separator STR_5152 :, +STR_5153 :RCT1 Farbschema +STR_5154 :Hardware display +STR_5155 :Testen unfertiger Bahnen erlauben +STR_5156 :{SMALLFONT}{BLACK}Erlaubt das Testen der meisten Bahnarten, selbst wenn die Strecke nicht fertiggestellt ist, das gilt nicht für den Streckenmodus mit Blockbereichen +STR_5157 :Alle Preise freischalten +STR_5158 :Spiel Beenden +STR_5159 :OpenRCT2 Beenden +STR_5160 :{MONTH} {STRINGID}, Jahr {COMMA16} +STR_5161 :{WHITE}Datumsformat: +STR_5162 :Tag/Monat/Jahr +STR_5163 :Monat/Tag/Jahr +STR_5164 :Twitch-Kanalname +STR_5165 :Parkbesucher nach Followern benennen +STR_5166 :Benennt die Parkbesucher nach den Followern des Twitch-Kanals +STR_5167 :Verfolge Follower-Parkbesucher +STR_5168 :Aktiviert das Sammeln von Informationen für Parkbesucher, die nach Twitch-Followern benannt sind +STR_5169 :Parkbesucher nach Twitch-Chatbenutzern benennen +STR_5170 :Benennt die Parkbesucher nach Twitch-Chatbenutzern +STR_5171 :Verfolge Chat-Parkbesucher +STR_5172 :Aktiviert das Sammeln von Informationen für Parkbesucher, die nach Twitch-Chatbenutzern{NEWLINE}benannt sind +STR_5173 :Erhalte Twitch-Chat als Spielnachrichten +STR_5174 :Benutzt Twitch-Chatnachrichten, welchen !news vorangestellt ist, für Spielbenachrichtigungen +STR_5175 :Name Ihres Twitch-Kanals eingeben: +STR_5176 :Twitch-Integration aktivieren From c6aa17f0530cadc647164b4ac6a8799289726a02 Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Fri, 29 May 2015 20:45:21 +0100 Subject: [PATCH 13/32] add headless game support --- projects/openrct2.vcxproj.user | 2 +- src/interface/screenshot.c | 1 + src/openrct2.c | 13 +++++++++---- src/openrct2.h | 1 + src/platform/shared.c | 3 ++- src/rct2.c | 17 +++++++++++------ 6 files changed, 25 insertions(+), 12 deletions(-) diff --git a/projects/openrct2.vcxproj.user b/projects/openrct2.vcxproj.user index 0106f0df7f..1846f60e7b 100644 --- a/projects/openrct2.vcxproj.user +++ b/projects/openrct2.vcxproj.user @@ -4,7 +4,7 @@ $(TargetDir) WindowsLocalDebugger $(TargetDir)\openrct2.exe - screenshot "C:\Program Files (x86)\Infogrames\RollerCoaster Tycoon 2\Scenarios\Six Flags Magic Mountain.SC6" "test.png" 16384 8192 c c 0 0 + screenshot "C:\Program Files (x86)\Infogrames\RollerCoaster Tycoon 2\Scenarios\Six Flags Magic Mountain.SC6" "test.png" 1920 1080 false diff --git a/src/interface/screenshot.c b/src/interface/screenshot.c index 289258b248..fbb2d217fd 100644 --- a/src/interface/screenshot.c +++ b/src/interface/screenshot.c @@ -347,6 +347,7 @@ int cmdline_for_screenshot(const char **argv, int argc) customRotation = atoi(argv[7]) & 3; } + gOpenRCT2Headless = true; if (openrct2_initialise()) { rct2_open_file(inputPath); diff --git a/src/openrct2.c b/src/openrct2.c index 7ac409ea88..301ff317a4 100644 --- a/src/openrct2.c +++ b/src/openrct2.c @@ -34,6 +34,9 @@ int gOpenRCT2StartupAction = STARTUP_ACTION_TITLE; char gOpenRCT2StartupActionPath[512] = { 0 }; +// This should probably be changed later and allow a custom selection of things to initialise like SDL_INIT +bool gOpenRCT2Headless = false; + /** If set, will end the OpenRCT2 game loop. Intentially private to this module so that the flag can not be set back to 0. */ int _finished; @@ -129,15 +132,17 @@ bool openrct2_initialise() config_save_default(); // TODO add configuration option to allow multiple instances - if (!platform_lock_single_instance()) { + if (!gOpenRCT2Headless && !platform_lock_single_instance()) { log_fatal("OpenRCT2 is already running."); return false; } get_system_info(); - audio_init(); - audio_get_devices(); - get_dsound_devices(); + if (!gOpenRCT2Headless) { + audio_init(); + audio_get_devices(); + get_dsound_devices(); + } language_open(gConfigGeneral.language); http_init(); if (!rct2_init()) diff --git a/src/openrct2.h b/src/openrct2.h index 5cb984fa6e..d2452d5389 100644 --- a/src/openrct2.h +++ b/src/openrct2.h @@ -32,6 +32,7 @@ enum { extern int gOpenRCT2StartupAction; extern char gOpenRCT2StartupActionPath[512]; +extern bool gOpenRCT2Headless; bool openrct2_initialise(); void openrct2_launch(); diff --git a/src/platform/shared.c b/src/platform/shared.c index c6f356b473..fcd34e4027 100644 --- a/src/platform/shared.c +++ b/src/platform/shared.c @@ -28,6 +28,7 @@ #include "../interface/keyboard_shortcut.h" #include "../interface/window.h" #include "../input.h" +#include "../openrct2.h" #include "platform.h" typedef void(*update_palette_func)(char*, int, int); @@ -275,7 +276,7 @@ void platform_update_palette(char* colours, int start_index, int num_colours) colours += 4; } - if (!gConfigGeneral.hardware_display) { + if (!gOpenRCT2Headless && !gConfigGeneral.hardware_display) { surface = SDL_GetWindowSurface(gWindow); if (!surface) { log_fatal("SDL_GetWindowSurface failed %s", SDL_GetError()); diff --git a/src/rct2.c b/src/rct2.c index 81dc31e8b5..e900020c60 100644 --- a/src/rct2.c +++ b/src/rct2.c @@ -96,8 +96,10 @@ int rct2_init() gfx_load_g1(); gfx_load_g2(); gfx_load_character_widths(); - platform_init(); - audio_init1(); + if (!gOpenRCT2Headless) { + platform_init(); + audio_init1(); + } viewport_init_all(); news_item_init_queue(); get_local_time(); @@ -109,7 +111,8 @@ int rct2_init() sub_6BD3A4(); map_init(150); park_init(); - window_title_menu_open(); + if (!gOpenRCT2Headless) + window_title_menu_open(); date_reset(); climate_reset(CLIMATE_COOL_AND_WET); scenery_set_default_placement_configuration(); @@ -117,10 +120,12 @@ int rct2_init() window_guest_list_init_vars_b(); window_staff_list_init_vars(); - title_load(); + if (!gOpenRCT2Headless) { + title_load(); - gfx_clear(RCT2_ADDRESS(RCT2_ADDRESS_SCREEN_DPI, rct_drawpixelinfo), 10); - RCT2_GLOBAL(RCT2_ADDRESS_RUN_INTRO_TICK_PART, uint8) = gConfigGeneral.play_intro ? 8 : 255; + gfx_clear(RCT2_ADDRESS(RCT2_ADDRESS_SCREEN_DPI, rct_drawpixelinfo), 10); + RCT2_GLOBAL(RCT2_ADDRESS_RUN_INTRO_TICK_PART, uint8) = gConfigGeneral.play_intro ? 8 : 255; + } log_verbose("initialising game finished"); return 1; From 3a55c060f7f80ceac0210c7f38b0fbb1d47bcc59 Mon Sep 17 00:00:00 2001 From: rd3k Date: Fri, 29 May 2015 20:59:16 +0100 Subject: [PATCH 14/32] fix #1163 --- data/language/english_uk.txt | 3 ++- src/localisation/string_ids.h | 2 ++ src/windows/options.c | 5 +---- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/data/language/english_uk.txt b/data/language/english_uk.txt index 89e2f667f7..909e981311 100644 --- a/data/language/english_uk.txt +++ b/data/language/english_uk.txt @@ -3509,4 +3509,5 @@ STR_5172 :Will turn on tracking information for guests named after Twitch cha STR_5173 :Pull Twitch chat as news STR_5174 :Will use Twitch chat messages preceded by !news for in game notifications STR_5175 :Input the name of your Twitch channel -STR_5176 :Enable Twitch integration \ No newline at end of file +STR_5176 :Enable Twitch integration +STR_5177 :Fullscreen mode: \ No newline at end of file diff --git a/src/localisation/string_ids.h b/src/localisation/string_ids.h index 8a8bf7c6a7..9786f32fc4 100644 --- a/src/localisation/string_ids.h +++ b/src/localisation/string_ids.h @@ -1422,6 +1422,8 @@ enum { STR_TWITCH_NAME_DESC = 5175, STR_TWITCH_ENABLE = 5176, + STR_FULLSCREEN_MODE = 5177, + // Have to include resource strings (from scenarios and objects) for the time being now that language is partially working STR_COUNT = 32768 }; diff --git a/src/windows/options.c b/src/windows/options.c index 6ab2568dbf..c983ff82c1 100644 --- a/src/windows/options.c +++ b/src/windows/options.c @@ -967,10 +967,7 @@ static void window_options_paint() switch (w->page) { case WINDOW_OPTIONS_PAGE_DISPLAY: gfx_draw_string_left(dpi, STR_DISPLAY_RESOLUTION, w, 0, w->x + 10, w->y + window_options_widgets[WIDX_RESOLUTION].top + 1); - - sprintf(buffer, "%c%c%s", FORMAT_MEDIUMFONT, FORMAT_WINDOW_COLOUR_2, "Fullscreen mode:"); - gfx_draw_string(dpi, buffer, 0, w->x + 10, w->y + window_options_widgets[WIDX_FULLSCREEN].top + 1); - + gfx_draw_string_left(dpi, STR_FULLSCREEN_MODE, w, 12, w->x + 10, w->y + window_options_widgets[WIDX_FULLSCREEN].top + 1); gfx_draw_string_left(dpi, STR_CONSTRUCTION_MARKER, w, 0, w->x + 10, w->y + window_options_widgets[WIDX_CONSTRUCTION_MARKER].top + 1); break; case WINDOW_OPTIONS_PAGE_CULTURE: From 257d3b8469deea02185ae6bfc36b49f7812b77c7 Mon Sep 17 00:00:00 2001 From: rd3k Date: Sat, 30 May 2015 02:48:31 +0100 Subject: [PATCH 15/32] proper cheat and Twitch window tooltips, fix #1167 --- data/language/english_uk.txt | 16 ++++++++++------ src/windows/cheats.c | 32 ++++++++++++++++---------------- 2 files changed, 26 insertions(+), 22 deletions(-) diff --git a/data/language/english_uk.txt b/data/language/english_uk.txt index 909e981311..396d783513 100644 --- a/data/language/english_uk.txt +++ b/data/language/english_uk.txt @@ -3499,15 +3499,19 @@ STR_5162 :Day/Month/Year STR_5163 :Month/Day/Year STR_5164 :Twitch Channel name STR_5165 :Name peeps after followers -STR_5166 :Will name peeps after channel's Twitch followers +STR_5166 :{SMALLFONT}{BLACK}Will name peeps after channel's Twitch followers STR_5167 :Track follower peeps -STR_5168 :Will turn on tracking information for guests named after channel's Twitch followers +STR_5168 :{SMALLFONT}{BLACK}Will turn on tracking information for guests named after channel's Twitch followers STR_5169 :Name peeps after people in Twitch chat -STR_5170 :Will name peeps after people in Twitch chat +STR_5170 :{SMALLFONT}{BLACK}Will name peeps after people in Twitch chat STR_5171 :Track chat peeps -STR_5172 :Will turn on tracking information for guests named after Twitch chat participants +STR_5172 :{SMALLFONT}{BLACK}Will turn on tracking information for guests named after Twitch chat participants STR_5173 :Pull Twitch chat as news -STR_5174 :Will use Twitch chat messages preceded by !news for in game notifications +STR_5174 :{SMALLFONT}{BLACK}Will use Twitch chat messages preceded by !news for in game notifications STR_5175 :Input the name of your Twitch channel STR_5176 :Enable Twitch integration -STR_5177 :Fullscreen mode: \ No newline at end of file +STR_5177 :Fullscreen mode: +STR_5178 :{SMALLFONT}{BLACK}Show financial cheats +STR_5179 :{SMALLFONT}{BLACK}Show guest cheats +STR_5180 :{SMALLFONT}{BLACK}Show park cheats +STR_5181 :{SMALLFONT}{BLACK}Show ride cheats \ No newline at end of file diff --git a/src/windows/cheats.c b/src/windows/cheats.c index decf02ebbc..8b681a24be 100644 --- a/src/windows/cheats.c +++ b/src/windows/cheats.c @@ -106,10 +106,10 @@ static rct_widget window_cheats_money_widgets[] = { { WWT_CAPTION, 0, 1, WW - 2, 1, 14, 3165, STR_WINDOW_TITLE_TIP}, // title bar { WWT_CLOSEBOX, 0, WW - 13, WW - 3, 2, 13, 0x338, STR_CLOSE_WINDOW_TIP}, // close x button { WWT_IMGBTN, 1, 0, WW - 1, 43, WH - 1, 0x0FFFFFFFF, 65535}, // tab content panel - { WWT_TAB, 1, 3, 33, 17, 43, 0x2000144E, 2462}, // tab 1 - { WWT_TAB, 1, 34, 64, 17, 43, 0x2000144E, 2462}, // tab 2 - { WWT_TAB, 1, 65, 95, 17, 43, 0x2000144E, 2462}, // tab 3 - { WWT_TAB, 1, 96, 126, 17, 43, 0x2000144E, 2462}, // tab 4 + { WWT_TAB, 1, 3, 33, 17, 43, 0x2000144E, 5178 }, // tab 1 + { WWT_TAB, 1, 34, 64, 17, 43, 0x2000144E, 5179 }, // tab 2 + { WWT_TAB, 1, 65, 95, 17, 43, 0x2000144E, 5180 }, // tab 3 + { WWT_TAB, 1, 96, 126, 17, 43, 0x2000144E, 5181 }, // tab 4 { WWT_CLOSEBOX, 1, XPL(0), WPL(0), YPL(1), HPL(1), 2760, STR_NONE}, // high money { WWT_CLOSEBOX, 1, XPL(0), WPL(0), YPL(3), HPL(3), 2761, STR_NONE}, //Park Entrance Fee Toggle { WIDGETS_END }, @@ -120,10 +120,10 @@ static rct_widget window_cheats_guests_widgets[] = { { WWT_CAPTION, 0, 1, WW - 2, 1, 14, 3165, STR_WINDOW_TITLE_TIP }, // title bar { WWT_CLOSEBOX, 0, WW - 13, WW - 3, 2, 13, 0x338, STR_CLOSE_WINDOW_TIP }, // close x button { WWT_IMGBTN, 1, 0, WW - 1, 43, WH - 1, 0x0FFFFFFFF, 65535 }, // tab content panel - { WWT_TAB, 1, 3, 33, 17, 43, 0x2000144E, 2462 }, // tab 1 - { WWT_TAB, 1, 34, 64, 17, 43, 0x2000144E, 2462 }, // tab 2 - { WWT_TAB, 1, 65, 95, 17, 43, 0x2000144E, 2462 }, // tab 3 - { WWT_TAB, 1, 96, 126, 17, 43, 0x2000144E, 2462}, // tab 4 + { WWT_TAB, 1, 3, 33, 17, 43, 0x2000144E, 5178 }, // tab 1 + { WWT_TAB, 1, 34, 64, 17, 43, 0x2000144E, 5179 }, // tab 2 + { WWT_TAB, 1, 65, 95, 17, 43, 0x2000144E, 5180 }, // tab 3 + { WWT_TAB, 1, 96, 126, 17, 43, 0x2000144E, 5181 }, // tab 4 { WWT_CLOSEBOX, 1, XPL(0), WPL(0), YPL(1), HPL(1), 2764, STR_NONE}, // happy guests { WWT_CLOSEBOX, 1, XPL(0), WPL(0), YPL(3), HPL(3), 2765, STR_NONE}, // large tram { WIDGETS_END }, @@ -135,10 +135,10 @@ static rct_widget window_cheats_misc_widgets[] = { { WWT_CAPTION, 0, 1, WW - 2, 1, 14, 3165, STR_WINDOW_TITLE_TIP }, // title bar { WWT_CLOSEBOX, 0, WW - 13, WW - 3, 2, 13, 0x338, STR_CLOSE_WINDOW_TIP }, // close x button { WWT_IMGBTN, 1, 0, WW - 1, 43, WH - 1, 0x0FFFFFFFF, 65535 }, // tab content panel - { WWT_TAB, 1, 3, 33, 17, 43, 0x2000144E, 2462 }, // tab 1 - { WWT_TAB, 1, 34, 64, 17, 43, 0x2000144E, 2462 }, // tab 2 - { WWT_TAB, 1, 65, 95, 17, 43, 0x2000144E, 2462}, // tab 3 - { WWT_TAB, 1, 96, 126, 17, 43, 0x2000144E, 2462}, // tab 4 + { WWT_TAB, 1, 3, 33, 17, 43, 0x2000144E, 5178 }, // tab 1 + { WWT_TAB, 1, 34, 64, 17, 43, 0x2000144E, 5179 }, // tab 2 + { WWT_TAB, 1, 65, 95, 17, 43, 0x2000144E, 5180 }, // tab 3 + { WWT_TAB, 1, 96, 126, 17, 43, 0x2000144E, 5181 }, // tab 4 { WWT_CLOSEBOX, 1, XPL(1), WPL(1), YPL(1), HPL(1), 2767, STR_NONE}, // Freeze climate { WWT_CLOSEBOX, 1, XPL(0), WPL(0), YPL(0), HPL(0), 2769, STR_NONE}, // open / close park { WWT_CLOSEBOX, 1, XPL(0), WPL(0), YPL(1), HPL(1), 2759, STR_NONE}, // Zero Clearance @@ -158,10 +158,10 @@ static rct_widget window_cheats_rides_widgets[] = { { WWT_CAPTION, 0, 1, WW - 2, 1, 14, 3165, STR_WINDOW_TITLE_TIP }, // title bar { WWT_CLOSEBOX, 0, WW - 13, WW - 3, 2, 13, 0x338, STR_CLOSE_WINDOW_TIP }, // close x button { WWT_IMGBTN, 1, 0, WW - 1, 43, WH - 1, 0x0FFFFFFFF, 65535 }, // tab content panel - { WWT_TAB, 1, 3, 33, 17, 43, 0x2000144E, 2462 }, // tab 1 - { WWT_TAB, 1, 34, 64, 17, 43, 0x2000144E, 2462 }, // tab 2 - { WWT_TAB, 1, 65, 95, 17, 43, 0x2000144E, 2462}, // tab 3 - { WWT_TAB, 1, 96, 126, 17, 43, 0x2000144E, 2462}, // tab 4 + { WWT_TAB, 1, 3, 33, 17, 43, 0x2000144E, 5178 }, // tab 1 + { WWT_TAB, 1, 34, 64, 17, 43, 0x2000144E, 5179 }, // tab 2 + { WWT_TAB, 1, 65, 95, 17, 43, 0x2000144E, 5180 }, // tab 3 + { WWT_TAB, 1, 96, 126, 17, 43, 0x2000144E, 5181 }, // tab 4 { WWT_CLOSEBOX, 1, XPL(0), WPL(0), YPL(0), HPL(0), 5123, STR_NONE}, // Renew rides { WWT_CLOSEBOX, 1, XPL(1), WPL(1), YPL(0), HPL(0), 5124, STR_NONE}, // Remove flags { WWT_CLOSEBOX, 1, XPL(1), WPL(1), YPL(1), HPL(1), 5125, STR_NONE}, // Make destructable From 7c29d781dc0fa3d330cc0b80e1d63bf5022dd906 Mon Sep 17 00:00:00 2001 From: Ted John Date: Sat, 30 May 2015 04:00:13 +0100 Subject: [PATCH 16/32] Merge Localisation/master into OpenRCT2/develop. --- data/language/german.txt | 137 ++++++++++++++++++++------------------- 1 file changed, 69 insertions(+), 68 deletions(-) diff --git a/data/language/german.txt b/data/language/german.txt index 8ad21e01ad..c99a0e3db9 100644 --- a/data/language/german.txt +++ b/data/language/german.txt @@ -1064,8 +1064,8 @@ STR_1059 :Bahn/Attraktion kann nicht umbenannt werden... STR_1060 :Ungültiger Bahn-/Attraktionsname STR_1061 :Normaler Modus STR_1062 :Durchgängiger Rundenmodus -STR_1063 :Shuttle-Modus (Start bei umgek. Neig.) -STR_1064 :Angetriebener Start +STR_1063 :Shuttle-Modus (Start bei umgekehrter Neigung) +STR_1064 :Angetriebener Start (Station passieren) STR_1065 :Shuttle-Modus STR_1066 :Mietsboot-Modus STR_1067 :Aufwärtsstart @@ -1096,9 +1096,9 @@ STR_1091 :Zirkusmodus STR_1092 :Start nach unten STR_1093 :Schiefes Haus STR_1094 :Freefall-Modus -STR_1095 :Durchgängig. Streckenmodus m. Blockber. -STR_1096 :Angetriebener Start -STR_1097 :Modus mit angetrieb. Start u. Blockber. +STR_1095 :Durchgängiger Streckenmodus mit Blockbereichen +STR_1096 :Angetriebener Start (Station nicht passieren) +STR_1097 :Modus mit angetriebenem Start und Blockbereichen STR_1098 :Geht ans Ende d. {POP16}{STRINGID} STR_1099 :Warten auf Fahrgäste bei {POP16}{STRINGID} STR_1100 :Wartet auf Abfahrt {POP16}{STRINGID} @@ -1149,11 +1149,11 @@ STR_1144 :Eingang für diese Bahn/Attraktion kann nicht gebaut/verschoben wer STR_1145 :Ausgang für diese Bahn/Attraktion kann nicht gebaut/verschoben werden... STR_1146 :Eingang noch nicht gebaut STR_1147 :Ausgang noch nicht gebaut -STR_1148 :Viertellast -STR_1149 :Halblast -STR_1150 :Dreiviertellast -STR_1151 :Volle Last -STR_1152 :Beliebige Last +STR_1148 :Viertelvoll +STR_1149 :Halbvoll +STR_1150 :Dreiviertelvoll +STR_1151 :Voll +STR_1152 :Beliebig STR_1153 :Höhenmarkierungen an Fahrstrecken STR_1154 :Höhenmarkierungen auf dem Gelände STR_1155 :Höhenmarkierungen an Fußwegen @@ -1216,7 +1216,7 @@ STR_1211 :{WINDOW_COLOUR_2}Mindestwartezeit: STR_1212 :{WINDOW_COLOUR_2}Höchstwartezeit: STR_1213 :{SMALLFONT}{BLACK}Wählen Sie die Mindestwartezeit vor der Abfahrt aus STR_1214 :{SMALLFONT}{BLACK}Wählen Sie die Höchstwartezeit vor der Abfahrt aus -STR_1215 :{WINDOW_COLOUR_2}Mit benachb. Stationen synchron. +STR_1215 :{WINDOW_COLOUR_2}Mit benachbarten Stationen synchronisieren STR_1216 :{SMALLFONT}{BLACK}Auswählen, ob Abfahrt mit allen benachbarten Stationen (für `Rennen') synchronisiert werden soll STR_1217 :{COMMA16} Sekunden STR_1218 :{BLACK}{SMALLUP} @@ -1341,14 +1341,14 @@ STR_1336 :{STRINGID} - Station {POP16}{COMMA16} Eingang STR_1337 :{STRINGID} - Ausgang{POP16}{POP16} STR_1338 :{STRINGID} - Station {POP16}{COMMA16} Ausgang STR_1339 :{BLACK}Noch keine Testergebnisse... -STR_1340 :{WINDOW_COLOUR_2}Max. Geschw: {BLACK}{VELOCITY} +STR_1340 :{WINDOW_COLOUR_2}Max. Geschwindigkeit: {BLACK}{VELOCITY} STR_1341 :{WINDOW_COLOUR_2}Fahrtdauer: {BLACK}{STRINGID}{STRINGID}{STRINGID}{STRINGID} STR_1342 :{DURATION} STR_1343 :{DURATION} / STR_1344 :{WINDOW_COLOUR_2}Fahrtlänge: {BLACK}{STRINGID}{STRINGID}{STRINGID}{STRINGID} STR_1345 :{LENGTH} STR_1346 :{LENGTH} / -STR_1347 :{WINDOW_COLOUR_2}Durchschn. G.: {BLACK}{VELOCITY} +STR_1347 :{WINDOW_COLOUR_2}Durchschn. Geschwindigkeit: {BLACK}{VELOCITY} STR_1348 :{WINDOW_COLOUR_2}Max. positive vertikale G-Kraft: {BLACK}{COMMA2DP32}G STR_1349 :{WINDOW_COLOUR_2}Max. positive vertikale G-Kraft: {OUTLINE}{RED}{COMMA2DP32}G STR_1350 :{WINDOW_COLOUR_2}Max. negative vertikale G-Kraft: {BLACK}{COMMA2DP32}G @@ -1356,7 +1356,7 @@ STR_1351 :{WINDOW_COLOUR_2}Max. negative vertikale G-Kraft: {OUTLINE}{RED}{CO STR_1352 :{WINDOW_COLOUR_2}Max. seitliche G-Kraft: {BLACK}{COMMA2DP32}G STR_1353 :{WINDOW_COLOUR_2}Max. seitliche G-Kraft: {OUTLINE}{RED}{COMMA2DP32}G STR_1354 :{WINDOW_COLOUR_2}Höchste Fallhöhe: {BLACK}{LENGTH} -STR_1355 :{WINDOW_COLOUR_2}Abfälle: {BLACK}{COMMA16} +STR_1355 :{WINDOW_COLOUR_2}Stürze: {BLACK}{COMMA16} STR_1356 :{WINDOW_COLOUR_2}Umkehrungen: {BLACK}{COMMA16} STR_1357 :{WINDOW_COLOUR_2}Löcher: {BLACK}{COMMA16} STR_1358 :{WINDOW_COLOUR_2}Gesamtzeit `in der Luft': {BLACK}{COMMA2DP32}Sek. @@ -1432,7 +1432,7 @@ STR_1427 :{WINDOW_COLOUR_2}Besucher: {BLACK}{COMMA32} pro Stunde STR_1428 :{WINDOW_COLOUR_2}Eintrittspreis: STR_1429 :{POP16}{POP16}{POP16}{CURRENCY2DP} STR_1430 :Kostenlos -STR_1431 :Läuft herum +STR_1431 :Geht STR_1432 :Geht Richtung {STRINGID} STR_1433 :Steht in Schlange für {STRINGID} STR_1434 :Ertrinkt @@ -1693,7 +1693,7 @@ STR_1688 :Grundflächengröße 4 x 1 STR_1689 :Klotzbremsen STR_1690 :{WINDOW_COLOUR_2}{STRINGID}{NEWLINE}{BLACK}{STRINGID} STR_1691 :{WINDOW_COLOUR_2} Kosten: {BLACK}{CURRENCY} -STR_1692 :{WINDOW_COLOUR_2} Kosten: {BLACK}von {CURRENCY} +STR_1692 :{WINDOW_COLOUR_2} Kosten: {BLACK}ab {CURRENCY} STR_1693 :{SMALLFONT}{BLACK}Besucher STR_1694 :{SMALLFONT}{BLACK}Personal STR_1695 :{SMALLFONT}{BLACK}Einkünfte und Kosten @@ -1723,7 +1723,7 @@ STR_1718 :Parkname STR_1719 :Geben Sie einen Parknamen ein: STR_1720 :{SMALLFONT}{BLACK}Park benennen STR_1721 :Park geschlossen -STR_1722 :Park eröffnet +STR_1722 :Park geöffnet STR_1723 :Park kann nicht eröffnet werden... STR_1724 :Park kann nicht geschlossen werden... STR_1725 :Land kann nicht gekauft werden... @@ -2312,12 +2312,12 @@ STR_2307 :Entwurf {STRINGID} auswählen STR_2308 :{STRINGID} Streckenentwürfe STR_2309 :Neuen Streckenentwurf installieren STR_2310 :Nach eigenem Entwurf bauen -STR_2311 :{WINDOW_COLOUR_2}Nervenkitzelwert: {BLACK}{COMMA2DP32} (ungef.) -STR_2312 :{WINDOW_COLOUR_2}Intensitätswert: {BLACK}{COMMA2DP32} (ungef.) -STR_2313 :{WINDOW_COLOUR_2}Übelkeitswert: {BLACK}{COMMA2DP32} (ungef.) +STR_2311 :{WINDOW_COLOUR_2}Nervenkitzelwert: {BLACK}{COMMA2DP32} (ungefähr) +STR_2312 :{WINDOW_COLOUR_2}Intensitätswert: {BLACK}{COMMA2DP32} (ungefähr) +STR_2313 :{WINDOW_COLOUR_2}Übelkeitswert: {BLACK}{COMMA2DP32} (ungefähr) STR_2314 :{WINDOW_COLOUR_2}Fahrtlänge: {BLACK}{STRINGID} -STR_2315 :{WINDOW_COLOUR_2}Kosten: {BLACK}ungef. {CURRENCY} -STR_2316 :{WINDOW_COLOUR_2}Erforderl. Platz {BLACK}{COMMA16} x {COMMA16} Blöcke +STR_2315 :{WINDOW_COLOUR_2}Kosten: {BLACK}ungefähr {CURRENCY} +STR_2316 :{WINDOW_COLOUR_2}Erforderlicher Platz: {BLACK}{COMMA16} x {COMMA16} Blöcke STR_2317 :{WINDOW_COLOUR_2}Soundqualität: STR_2318 :Niedrig STR_2319 :Mittel @@ -2488,12 +2488,13 @@ STR_2483 :{WINDOW_COLOUR_2}Wöchentlicher Gewinn: {BLACK}+{CURRENCY2DP} STR_2484 :{WINDOW_COLOUR_2}Wöchentlicher Gewinn: {RED}{CURRENCY2DP} STR_2485 :Steuerung STR_2486 :Allgemein -STR_2487 :Echte Besuchernamen anzeigen +STR_2487 :`Echte' Besuchernamen anzeigen STR_2488 :{SMALLFONT}{BLACK}Zwischen `echten' Besuchernamen und Besucherzahlen umschalten -STR_2489 :Kürzeltasten... +STR_2489 :Tastenkürzel... STR_2490 :Tastaturkürzel -STR_2491 :Tast. zur. -STR_2492 :{SMALLFONT}{BLACK}Alle Kürzeltasten auf Standardeinstellung zurücksetzen +#new +STR_2491 :Tasten zurücksetzen +STR_2492 :{SMALLFONT}{BLACK}Alle Tastenkürzel auf Standardeinstellung zurücksetzen STR_2493 :Oberstes Fenster schließen STR_2494 :Alle freien Fenster schließen STR_2495 :Baumodus abbrechen @@ -2712,7 +2713,7 @@ STR_2706 :Nie STR_2707 :Neues Fenster STR_2708 :{WINDOW_COLOUR_1}Sind Sie sicher, dass Sie {STRINGID} überschreiben möchten? STR_2709 :Überschreiben -STR_2710 :Geben Sie den Dateinamen ein. +STR_2710 :Geben Sie den Dateinamen ein: STR_2711 :; STR_2712 := STR_2713 :, @@ -2722,18 +2723,18 @@ STR_2716 :/ STR_2717 :' STR_2718 :(Hoch) STR_2719 :(Neue Datei) -STR_2720 :{UINT16}s -STR_2721 :{UINT16}s -STR_2722 :{UINT16}min:{UINT16}s -STR_2723 :{UINT16}min:{UINT16}s -STR_2724 :{UINT16}min:{UINT16}s -STR_2725 :{UINT16}min:{UINT16}s -STR_2726 :{UINT16}min -STR_2727 :{UINT16}min -STR_2728 :{UINT16}h:{UINT16}min -STR_2729 :{UINT16}h:{UINT16}min -STR_2730 :{UINT16}h:{UINT16}min -STR_2731 :{UINT16}h:{UINT16}min +STR_2720 :{UINT16}Sek. +STR_2721 :{UINT16}Sek. +STR_2722 :{UINT16}Min:{UINT16}Sek. +STR_2723 :{UINT16}Min:{UINT16}Sek. +STR_2724 :{UINT16}Min:{UINT16}Sek. +STR_2725 :{UINT16}Min:{UINT16}Sek. +STR_2726 :{UINT16}Min. +STR_2727 :{UINT16}Min. +STR_2728 :{UINT16}Stunde:{UINT16}Min. +STR_2729 :{UINT16}Stunde:{UINT16}Min. +STR_2730 :{UINT16}Stunden:{UINT16}Min. +STR_2731 :{UINT16}Stunden:{UINT16}Min. STR_2732 :{COMMA16}ft STR_2733 :{COMMA16}m STR_2734 :{COMMA16}mph @@ -2789,7 +2790,7 @@ STR_2781 :{STRINGID}:{MOVE_X}{195}{STRINGID}{STRINGID} STR_2782 :UMSCHALT + STR_2783 :STRG + STR_2784 :Tastaturkürzel ändern -STR_2785 :{WINDOW_COLOUR_2}Drücken Sie die neue Kürzeltaste für:{NEWLINE}{OPENQUOTES}{STRINGID}{ENDQUOTES} +STR_2785 :{WINDOW_COLOUR_2}Drücken Sie die neue Taste für:{NEWLINE}{OPENQUOTES}{STRINGID}{ENDQUOTES} STR_2786 :{SMALLFONT}{BLACK}Klicken Sie auf die Kürzelbeschreibung, um eine neue Taste auszuwählen STR_2787 :{WINDOW_COLOUR_2}Verkehrswert: {BLACK}{CURRENCY} STR_2788 :{WINDOW_COLOUR_2}Glückwunsch!{NEWLINE}{BLACK}Sie haben Ihr Ziel mit einem Firmenwert von {CURRENCY} erreicht! @@ -2803,7 +2804,7 @@ STR_2795 :Sortieren STR_2796 :{SMALLFONT}{BLACK}Sortieren Sie die Bahnliste in die richtige Reihenfolge mit Hilfe der angezeigten Informationsart STR_2797 :Ansicht rollen, wenn Zeiger am Bildschirmrand ist STR_2798 :{SMALLFONT}{BLACK}Wählen Sie aus, ob die Ansicht gerollt werden soll, wenn sich der Mauszeiger am Bildschirmrand befindet -STR_2799 :{SMALLFONT}{BLACK}Steuertastenzuweisungen anzeigen oder ändern +STR_2799 :{SMALLFONT}{BLACK}Tastenkürzel anzeigen oder ändern STR_2800 :{WINDOW_COLOUR_2}Besucher gesammt: {BLACK}{COMMA32} STR_2801 :{WINDOW_COLOUR_2}Einkünfte d. Eintrittskarten: {BLACK}{CURRENCY2DP} STR_2802 :Karte @@ -2818,23 +2819,23 @@ STR_2810 :{RED}Die Besucher sind durstig und können nirgendwo etwas finden, STR_2811 :{RED}Die Besucher beschweren sich, weil sie die Toiletten in Ihrem Park nicht finden können STR_2812 :{RED}Die Besucher verirren sich oder es kommt zu Staus{NEWLINE}Überprüfen Sie, ob die Anordnung Ihrer Fußwege eventuell verbessert werden muss, damit die Besucher sich zurechtfinden STR_2813 :{RED}Der Eintrittspreis für Ihren Park ist zu hoch!{NEWLINE}Verringern Sie den Eintrittspreis oder verbessern Sie das Parkangebot, um mehr Besucher anzuziehen -STR_2814 :{WINDOW_COLOUR_2}Auszeichnug f. ungepflegtesten Park -STR_2815 :{WINDOW_COLOUR_2}Auszeichnung f. saubersten Park -STR_2816 :{WINDOW_COLOUR_2}Auszeichnung f. Park mit besten Achterbahnen -STR_2817 :{WINDOW_COLOUR_2}Auszeichnung f. Park mit bestem Angebot -STR_2818 :{WINDOW_COLOUR_2}Auszeichnung f. den schönsten Park -STR_2819 :{WINDOW_COLOUR_2}Auszeichnung f. Park m. schlimmst. Ang. -STR_2820 :{WINDOW_COLOUR_2}Auszeichnung f. den sichersten Park -STR_2821 :{WINDOW_COLOUR_2}Auszeichnung f. das beste Personal -STR_2822 :{WINDOW_COLOUR_2}Auszeichnung f. bestes Essen -STR_2823 :{WINDOW_COLOUR_2}Auszeichnung f. schlechtestes Essen -STR_2824 :{WINDOW_COLOUR_2}Auszeichnung f. beste Parktoiletten -STR_2825 :{WINDOW_COLOUR_2}Auszeichnung f. enttäuschendsten Park -STR_2826 :{WINDOW_COLOUR_2}Auszeichnung f. die besten Wasserbahnen -STR_2827 :{WINDOW_COLOUR_2}Auszeichnung f. beste selbstentw. Bahn. -STR_2828 :{WINDOW_COLOUR_2}Auszeichnung f. bunteste Farbschemas -STR_2829 :{WINDOW_COLOUR_2}Auszeichnung f. konfuseste Parkanordn. -STR_2830 :{WINDOW_COLOUR_2}Auszeichnung f. beste gemäßigte Bahn +STR_2814 :{WINDOW_COLOUR_2}Auszeichnung für ungepflegtesten Park +STR_2815 :{WINDOW_COLOUR_2}Auszeichnung für saubersten Park +STR_2816 :{WINDOW_COLOUR_2}Auszeichnung für Park mit den besten Achterbahnen +STR_2817 :{WINDOW_COLOUR_2}Auszeichnung für Park mit bestem Angebot +STR_2818 :{WINDOW_COLOUR_2}Auszeichnung für den schönsten Park +STR_2819 :{WINDOW_COLOUR_2}Auszeichnung für Park mit schlimmstem Angebot +STR_2820 :{WINDOW_COLOUR_2}Auszeichnung für den sichersten Park +STR_2821 :{WINDOW_COLOUR_2}Auszeichnung für das beste Personal +STR_2822 :{WINDOW_COLOUR_2}Auszeichnung für bestes Essen +STR_2823 :{WINDOW_COLOUR_2}Auszeichnung für schlechtestes Essen +STR_2824 :{WINDOW_COLOUR_2}Auszeichnung für beste Parktoiletten +STR_2825 :{WINDOW_COLOUR_2}Auszeichnung für enttäuschendsten Park +STR_2826 :{WINDOW_COLOUR_2}Auszeichnung für die besten Wasserbahnen +STR_2827 :{WINDOW_COLOUR_2}Auszeichnung für beste selbstentwickelte Bahn +STR_2828 :{WINDOW_COLOUR_2}Auszeichnung für bunteste Farbschemas +STR_2829 :{WINDOW_COLOUR_2}Auszeichnung für konfuseste Parkanordnung +STR_2830 :{WINDOW_COLOUR_2}Auszeichnung für beste gemäßigte Bahn STR_2831 :{TOPAZ}Ihr Park hat die Auszeichnung `Ungepflegtester Park des Landes' erhalten! STR_2832 :{TOPAZ}Ihr Park hat die Auszeichnung `Sauberster Park des Landes' erhalten! STR_2833 :{TOPAZ}Ihr Park hat die Auszeichnung `Park mit den besten Achterbahnen' erhalten! @@ -3089,7 +3090,7 @@ STR_3081 :Burgeingang (grau) STR_3082 :Burgeingang (braun) STR_3083 :Dschungeleingang STR_3084 :Blockhütteneingang -STR_3085 :Klassischer/Röm. Eingang +STR_3085 :Klassischer/Römischer Eingang STR_3086 :Abstrakter Eingang STR_3087 :Schnee-/Eis-Eingang STR_3088 :Pagodeneingang @@ -3141,7 +3142,7 @@ STR_3133 :Dies kann nicht auf schrägem Untergrund gebaut werden STR_3134 :{RED}(Der Entwurf enthält Szenerie, die nicht verfügbar ist) STR_3135 :{RED}(Fahrzeugentwurf nicht verfügbar - Dies kann sich auf die Bahn-Performance auswirken) STR_3136 :Warnung: Dieser Entwurf wird mit einer alternativen Fahrzeugart gebaut und könnte möglicherweise nicht wie gewünscht funktionieren -STR_3137 :Nahe Szenerie ausw. +STR_3137 :Nahe Szenerie auswählen STR_3138 :Auswahl zurücksetzen STR_3139 :Kabellift funktioniert nicht in diesem Betriebsmodus STR_3140 :Kabellifthügel muss direkt nach der Station beginnen @@ -3283,8 +3284,8 @@ STR_3275 :Höhere Schwierigkeitsstufe für Besuchergewinnung STR_3276 :{SMALLFONT}{BLACK}Machen Sie das Anlocken von Besuchern schwieriger STR_3277 :{WINDOW_COLOUR_2}Kosten für Landkauf: STR_3278 :{WINDOW_COLOUR_2}Kosten für Erwerb v. Baurechten: -STR_3279 :Freier Eintritt/Bez. pro Fahrt -STR_3280 :Bez. f. Eintritt/Gratis fahren +STR_3279 :Freier Eintritt/Bezahlen pro Fahrt +STR_3280 :Bezahlen für Eintritt/Gratis fahren STR_3281 :{WINDOW_COLOUR_2}Eintrittspreis: STR_3282 :{SMALLFONT}{BLACK}Ziel und Parkname auswählen STR_3283 :{SMALLFONT}{BLACK}Bahnen auswählen, die beibehalten werden sollen @@ -3451,7 +3452,6 @@ STR_3443 :Seite 4 STR_3444 :Seite 5 STR_3445 :Patrouillenbereich festlegen STR_3446 :Patrouillenbereich verwerfen - # New strings, cleaner STR_5120 :Finanzen in der Symbolleiste anzeigen STR_5121 :Forschung in der Symbolleiste anzeigen @@ -3487,7 +3487,7 @@ STR_5150 :Aktiviere Debugging-Tools STR_5151 :. STR_5152 :, STR_5153 :RCT1 Farbschema -STR_5154 :Hardware display +STR_5154 :Anzeige über Hardware durchführen STR_5155 :Testen unfertiger Bahnen erlauben STR_5156 :{SMALLFONT}{BLACK}Erlaubt das Testen der meisten Bahnarten, selbst wenn die Strecke nicht fertiggestellt ist, das gilt nicht für den Streckenmodus mit Blockbereichen STR_5157 :Alle Preise freischalten @@ -3500,13 +3500,14 @@ STR_5163 :Monat/Tag/Jahr STR_5164 :Twitch-Kanalname STR_5165 :Parkbesucher nach Followern benennen STR_5166 :Benennt die Parkbesucher nach den Followern des Twitch-Kanals -STR_5167 :Verfolge Follower-Parkbesucher -STR_5168 :Aktiviert das Sammeln von Informationen für Parkbesucher, die nach Twitch-Followern benannt sind +STR_5167 :Überwache Follower-Parkbesucher +STR_5168 :Überwachungsinformationen zu Parkbesuchern, die nach Twitch-Followern benannt sind, einschalten - (Bei eingeschalteter Überwachung werden Besucheraktivitäten im Nachrichtenbereich angezeigt) STR_5169 :Parkbesucher nach Twitch-Chatbenutzern benennen STR_5170 :Benennt die Parkbesucher nach Twitch-Chatbenutzern -STR_5171 :Verfolge Chat-Parkbesucher -STR_5172 :Aktiviert das Sammeln von Informationen für Parkbesucher, die nach Twitch-Chatbenutzern{NEWLINE}benannt sind +STR_5171 :Überwache Chat-Parkbesucher +STR_5172 :Überwachungsinformationen zu Parkbesuchern, die nach Twitch-Chatbenutzern benannt sind, einschalten - (Bei eingeschalteter Überwachung werden Besucheraktivitäten im Nachrichtenbereich angezeigt) STR_5173 :Erhalte Twitch-Chat als Spielnachrichten STR_5174 :Benutzt Twitch-Chatnachrichten, welchen !news vorangestellt ist, für Spielbenachrichtigungen STR_5175 :Name Ihres Twitch-Kanals eingeben: STR_5176 :Twitch-Integration aktivieren +STR_5177 :Vollbildmodus: From 5c7dc6bb9a7385ba4f6108d80c48d8079dbc5b5c Mon Sep 17 00:00:00 2001 From: zsilencer Date: Fri, 29 May 2015 17:37:00 -0600 Subject: [PATCH 17/32] #1165 --- src/world/map.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/world/map.c b/src/world/map.c index 790e645a90..f021252191 100644 --- a/src/world/map.c +++ b/src/world/map.c @@ -1865,7 +1865,7 @@ void game_command_place_scenery(int* eax, int* ebx, int* ecx, int* edx, int* esi if(RCT2_GLOBAL(0x009D8150, uint8) & 1 || (x <= RCT2_GLOBAL(0x01358836, uint16) && y <= RCT2_GLOBAL(0x01358836, uint16))){ rct_scenery_entry* scenery_entry = (rct_scenery_entry*)object_entry_groups[OBJECT_TYPE_SMALL_SCENERY].chunks[scenery_type]; if((scenery_entry->small_scenery.flags & SMALL_SCENERY_FLAG_FULL_TILE && scenery_entry->small_scenery.flags & (SMALL_SCENERY_FLAG9 | SMALL_SCENERY_FLAG24 | SMALL_SCENERY_FLAG25)) || scenery_entry->small_scenery.flags & SMALL_SCENERY_FLAG9){ - base_height = 0; + quadrant = 0; } int x2 = x; int y2 = y; @@ -1936,7 +1936,6 @@ void game_command_place_scenery(int* eax, int* ebx, int* ecx, int* edx, int* esi } if(!(scenery_entry->small_scenery.flags & SMALL_SCENERY_FLAG24)){ if(scenery_entry->small_scenery.flags & SMALL_SCENERY_FLAG9 && scenery_entry->small_scenery.flags & SMALL_SCENERY_FLAG_FULL_TILE){ - // this stuff that uses rol and ror are untested, couldnt find any scenery with these flags if(scenery_entry->small_scenery.flags & SMALL_SCENERY_FLAG25){ bp ^= 2; bp += rotation; @@ -1948,7 +1947,7 @@ void game_command_place_scenery(int* eax, int* ebx, int* ecx, int* edx, int* esi bp += rotation; bp &= 1; bl = 0xA; - bl = ror8(bl, bp); + bl >>= bp; } } }else{ From 54a37edb44c5704fa1d2a878c152c4bc67fc9913 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Mon, 25 May 2015 17:24:18 +0100 Subject: [PATCH 18/32] Implemented clear scenery update Not tested. --- src/windows/top_toolbar.c | 86 ++++++++++++++++++++++++++++++++++++++- src/world/map.h | 1 + 2 files changed, 86 insertions(+), 1 deletion(-) diff --git a/src/windows/top_toolbar.c b/src/windows/top_toolbar.c index 66b8bee5de..c361e0ecef 100644 --- a/src/windows/top_toolbar.c +++ b/src/windows/top_toolbar.c @@ -1535,6 +1535,90 @@ static void window_top_toolbar_scenery_tool_down(short x, short y, rct_window* w } } +/** +* +* rct2: 0x0068E213 +*/ +void sub_68E213(sint16 x, sint16 y){ + map_invalidate_selection_rect(); + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) &= ~(1 << 0); + + rct_xy16 mapTile = { 0 }; + sub_688972(x, y, &mapTile.x, &mapTile.y, NULL); + + if (mapTile.x == (sint16)0x8000){ + if (RCT2_GLOBAL(0x00F1AD62, money32) != MONEY32_UNDEFINED){ + RCT2_GLOBAL(0x00F1AD62, money32) = MONEY32_UNDEFINED; + window_invalidate_by_class(WC_CLEAR_SCENERY); + return; + } + } + + uint8 state_changed = 0; + + if (!(RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) & (1 << 0))){ + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) |= (1 << 0); + state_changed++; + } + + if (RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_TYPE, uint16) != 4){ + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_TYPE, uint16) = 4; + state_changed++; + } + + sint16 tool_size = RCT2_GLOBAL(RCT2_ADDRESS_LAND_TOOL_SIZE, sint16); + if (tool_size == 0) + tool_size = 1; + + sint16 tool_length = (tool_size - 1) * 32; + + // Move to tool bottom left + mapTile.x -= (tool_size - 1) * 16; + mapTile.y -= (tool_size - 1) * 16; + mapTile.x &= 0xFFE0; + mapTile.y &= 0xFFE0; + + if (RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_X, sint16) != mapTile.x){ + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_X, sint16) = mapTile.x; + state_changed++; + } + + if (RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_Y, sint16) != mapTile.y){ + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_Y, sint16) = mapTile.y; + state_changed++; + } + + mapTile.x += tool_length; + mapTile.y += tool_length; + + if (RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_X, sint16) != mapTile.x){ + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_X, sint16) = mapTile.x; + state_changed++; + } + + if (RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_Y, sint16) != mapTile.y){ + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_Y, sint16) = mapTile.y; + state_changed++; + } + + map_invalidate_selection_rect(); + if (!state_changed) + return; + + money32 cost = map_clear_scenery( + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_X, sint16), + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_Y, sint16), + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_X, sint16), + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_Y, sint16), + 0); + + if (RCT2_GLOBAL(0x00F1AD62, money32) != cost){ + RCT2_GLOBAL(0x00F1AD62, money32) = cost; + window_invalidate_by_class(WC_CLEAR_SCENERY); + return; + } +} + /** * * rct2: 0x0066CB25 @@ -1549,7 +1633,7 @@ static void window_top_toolbar_tool_update() switch (widgetIndex){ case WIDX_CLEAR_SCENERY: - RCT2_CALLPROC_X(0x0068E213, x, y, 0, widgetIndex, (int)w, 0, 0); + sub_68E213(x, y); break; case WIDX_LAND: if (LandPaintMode) diff --git a/src/world/map.h b/src/world/map.h index 6e3ba65b85..89d65937df 100644 --- a/src/world/map.h +++ b/src/world/map.h @@ -279,6 +279,7 @@ rct_map_element *map_element_insert(int x, int y, int z, int flags); int map_can_construct_with_clear_at(int x, int y, int zLow, int zHigh, void *clearFunc, uint8 bl); int map_can_construct_at(int x, int y, int zLow, int zHigh, uint8 bl); int sub_6BA278(int ebx); +money32 map_clear_scenery(int x0, int y0, int x1, int y1, int flags); void game_command_remove_scenery(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp); void game_command_remove_large_scenery(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp); From 573a632e4346f8a4bfc0fb76bcd165eba317a691 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Tue, 26 May 2015 17:55:25 +0100 Subject: [PATCH 19/32] Fix bugs in scenery_clear update Note make a new version of land update to fix cost issue --- src/windows/park.c | 1 + src/windows/top_toolbar.c | 16 ++++++++-------- src/world/map.c | 6 ++++++ 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/windows/park.c b/src/windows/park.c index ddba07d4b0..9a9ea8a061 100644 --- a/src/windows/park.c +++ b/src/windows/park.c @@ -814,6 +814,7 @@ static void window_park_entrance_toolupdate() switch (widgetIndex){ case WIDX_BUY_LAND_RIGHTS: + // Create a new version for this instance as scenery_clear is silly for this RCT2_CALLPROC_X(0x0068E213, x, y, 0, widgetIndex, (int)w, 0, 0); RCT2_GLOBAL(0x00F1AD62, uint32) = game_do_command( RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_X, uint16), diff --git a/src/windows/top_toolbar.c b/src/windows/top_toolbar.c index c361e0ecef..0a4dc6084a 100644 --- a/src/windows/top_toolbar.c +++ b/src/windows/top_toolbar.c @@ -1539,7 +1539,7 @@ static void window_top_toolbar_scenery_tool_down(short x, short y, rct_window* w * * rct2: 0x0068E213 */ -void sub_68E213(sint16 x, sint16 y){ +void top_toolbar_tool_update_scenery_clear(sint16 x, sint16 y){ map_invalidate_selection_rect(); RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) &= ~(1 << 0); @@ -1550,8 +1550,8 @@ void sub_68E213(sint16 x, sint16 y){ if (RCT2_GLOBAL(0x00F1AD62, money32) != MONEY32_UNDEFINED){ RCT2_GLOBAL(0x00F1AD62, money32) = MONEY32_UNDEFINED; window_invalidate_by_class(WC_CLEAR_SCENERY); - return; } + return; } uint8 state_changed = 0; @@ -1606,10 +1606,10 @@ void sub_68E213(sint16 x, sint16 y){ return; money32 cost = map_clear_scenery( - RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_X, sint16), - RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_Y, sint16), - RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_X, sint16), - RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_Y, sint16), + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_X, sint16) / 32, + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_Y, sint16) / 32, + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_X, sint16) / 32, + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_Y, sint16) / 32, 0); if (RCT2_GLOBAL(0x00F1AD62, money32) != cost){ @@ -1633,11 +1633,11 @@ static void window_top_toolbar_tool_update() switch (widgetIndex){ case WIDX_CLEAR_SCENERY: - sub_68E213(x, y); + top_toolbar_tool_update_scenery_clear(x, y); break; case WIDX_LAND: if (LandPaintMode) - // Use the method that allows dragging the selection area + // Create a new version for this instance as scenery_clear is silly for this RCT2_CALLPROC_X(0x0068E213, x, y, 0, widgetIndex, (int)w, 0, 0); else RCT2_CALLPROC_X(0x00664280, x, y, 0, widgetIndex, (int)w, 0, 0); diff --git a/src/world/map.c b/src/world/map.c index 790e645a90..c84d6248a0 100644 --- a/src/world/map.c +++ b/src/world/map.c @@ -1732,6 +1732,12 @@ void game_command_remove_fence(int* eax, int* ebx, int* ecx, int* edx, int* esi, return; } } + + if (!(*ebx & GAME_COMMAND_FLAG_APPLY)){ + *ebx = 0; + return; + } + rct_scenery_entry* scenery_entry = RCT2_ADDRESS(RCT2_ADDRESS_WALL_SCENERY_ENTRIES, rct_scenery_entry*)[map_element->properties.fence.type]; if(scenery_entry->wall.var_0D != 0xFF){ rct_banner* banner = &gBanners[map_element->properties.fence.item[0]]; From 5fa982f08bb773d224c2ddf623b0b481d1fc67c6 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Tue, 26 May 2015 20:36:05 +0100 Subject: [PATCH 20/32] Added tool_update_land Not tested --- src/windows/top_toolbar.c | 187 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 180 insertions(+), 7 deletions(-) diff --git a/src/windows/top_toolbar.c b/src/windows/top_toolbar.c index 0a4dc6084a..5167793671 100644 --- a/src/windows/top_toolbar.c +++ b/src/windows/top_toolbar.c @@ -209,6 +209,9 @@ void toggle_land_window(rct_window *topToolbar, int widgetIndex); void toggle_clear_scenery_window(rct_window *topToolbar, int widgetIndex); void toggle_water_window(rct_window *topToolbar, int widgetIndex); +money32 selection_lower_land(uint8 flags); +money32 selection_raise_land(uint8 flags); + static bool _menuDropdownIncludesTwitch; /** @@ -1619,6 +1622,176 @@ void top_toolbar_tool_update_scenery_clear(sint16 x, sint16 y){ } } +/** +* +* rct2: 0x00664280 +*/ +void top_toolbar_tool_update_land(sint16 x, sint16 y){ + map_invalidate_selection_rect(); + + if (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TOOL, uint8) == 3){ + if (!(RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) & (1 << 0))) + return; + + money32 lower_cost = selection_lower_land(0); + money32 raise_cost = selection_raise_land(0); + + if (RCT2_GLOBAL(RCT2_ADDRESS_LAND_RAISE_COST, money32) != raise_cost || + RCT2_GLOBAL(RCT2_ADDRESS_LAND_LOWER_COST, money32) != lower_cost){ + RCT2_GLOBAL(RCT2_ADDRESS_LAND_RAISE_COST, money32) = raise_cost; + RCT2_GLOBAL(RCT2_ADDRESS_LAND_LOWER_COST, money32) = lower_cost; + window_invalidate_by_class(WC_LAND); + } + return; + } + + sint16 tool_size = RCT2_GLOBAL(RCT2_ADDRESS_LAND_TOOL_SIZE, sint16); + rct_xy16 mapTile = { .x = x, .y = y }; + + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) &= ~(1 << 0); + if (tool_size == 1){ + int direction; + screen_pos_to_map_pos(&mapTile.x, &mapTile.y, &direction); + + if (mapTile.x == (sint16)0x8000){ + money32 lower_cost = MONEY32_UNDEFINED; + money32 raise_cost = MONEY32_UNDEFINED; + + if (RCT2_GLOBAL(RCT2_ADDRESS_LAND_RAISE_COST, money32) != raise_cost || + RCT2_GLOBAL(RCT2_ADDRESS_LAND_LOWER_COST, money32) != lower_cost){ + RCT2_GLOBAL(RCT2_ADDRESS_LAND_RAISE_COST, money32) = raise_cost; + RCT2_GLOBAL(RCT2_ADDRESS_LAND_LOWER_COST, money32) = lower_cost; + window_invalidate_by_class(WC_LAND); + } + return; + } + + uint8 state_changed = 0; + + if (!(RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) & (1 << 0))){ + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) |= (1 << 0); + state_changed++; + } + + if (RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_TYPE, uint16) != direction){ + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_TYPE, uint16) = direction; + state_changed++; + } + + + if (RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_X, sint16) != mapTile.x){ + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_X, sint16) = mapTile.x; + state_changed++; + } + + if (RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_Y, sint16) != mapTile.y){ + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_Y, sint16) = mapTile.y; + state_changed++; + } + + if (RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_X, sint16) != mapTile.x){ + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_X, sint16) = mapTile.x; + state_changed++; + } + + if (RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_Y, sint16) != mapTile.y){ + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_Y, sint16) = mapTile.y; + state_changed++; + } + + map_invalidate_selection_rect(); + if (!state_changed) + return; + + money32 lower_cost = selection_lower_land(0); + money32 raise_cost = selection_raise_land(0); + + if (RCT2_GLOBAL(RCT2_ADDRESS_LAND_RAISE_COST, money32) != raise_cost || + RCT2_GLOBAL(RCT2_ADDRESS_LAND_LOWER_COST, money32) != lower_cost){ + RCT2_GLOBAL(RCT2_ADDRESS_LAND_RAISE_COST, money32) = raise_cost; + RCT2_GLOBAL(RCT2_ADDRESS_LAND_LOWER_COST, money32) = lower_cost; + window_invalidate_by_class(WC_LAND); + } + return; + } + + sub_688972(x, y, &mapTile.x, &mapTile.y, NULL); + + if (mapTile.x == (sint16)0x8000){ + money32 lower_cost = MONEY32_UNDEFINED; + money32 raise_cost = MONEY32_UNDEFINED; + + if (RCT2_GLOBAL(RCT2_ADDRESS_LAND_RAISE_COST, money32) != raise_cost || + RCT2_GLOBAL(RCT2_ADDRESS_LAND_LOWER_COST, money32) != lower_cost){ + RCT2_GLOBAL(RCT2_ADDRESS_LAND_RAISE_COST, money32) = raise_cost; + RCT2_GLOBAL(RCT2_ADDRESS_LAND_LOWER_COST, money32) = lower_cost; + window_invalidate_by_class(WC_LAND); + } + return; + } + + uint8 state_changed = 0; + + if (!(RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) & (1 << 0))){ + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) |= (1 << 0); + state_changed++; + } + + if (RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_TYPE, uint16) != 4){ + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_TYPE, uint16) = 4; + state_changed++; + } + + + if (tool_size == 0) + tool_size = 1; + + sint16 tool_length = (tool_size - 1) * 32; + + // Move to tool bottom left + mapTile.x -= (tool_size - 1) * 16; + mapTile.y -= (tool_size - 1) * 16; + mapTile.x &= 0xFFE0; + mapTile.y &= 0xFFE0; + + if (RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_X, sint16) != mapTile.x){ + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_X, sint16) = mapTile.x; + state_changed++; + } + + if (RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_Y, sint16) != mapTile.y){ + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_Y, sint16) = mapTile.y; + state_changed++; + } + + mapTile.x += tool_length; + mapTile.y += tool_length; + + if (RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_X, sint16) != mapTile.x){ + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_X, sint16) = mapTile.x; + state_changed++; + } + + if (RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_Y, sint16) != mapTile.y){ + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_Y, sint16) = mapTile.y; + state_changed++; + } + + map_invalidate_selection_rect(); + if (!state_changed) + return; + + money32 lower_cost = selection_lower_land(0); + money32 raise_cost = selection_raise_land(0); + + if (RCT2_GLOBAL(RCT2_ADDRESS_LAND_RAISE_COST, money32) != raise_cost || + RCT2_GLOBAL(RCT2_ADDRESS_LAND_LOWER_COST, money32) != lower_cost){ + RCT2_GLOBAL(RCT2_ADDRESS_LAND_RAISE_COST, money32) = raise_cost; + RCT2_GLOBAL(RCT2_ADDRESS_LAND_LOWER_COST, money32) = lower_cost; + window_invalidate_by_class(WC_LAND); + } +} + /** * * rct2: 0x0066CB25 @@ -1640,7 +1813,7 @@ static void window_top_toolbar_tool_update() // Create a new version for this instance as scenery_clear is silly for this RCT2_CALLPROC_X(0x0068E213, x, y, 0, widgetIndex, (int)w, 0, 0); else - RCT2_CALLPROC_X(0x00664280, x, y, 0, widgetIndex, (int)w, 0, 0); + top_toolbar_tool_update_land(x, y); break; case WIDX_WATER: RCT2_CALLPROC_X(0x006E6BDC, x, y, 0, widgetIndex, (int)w, 0, 0); @@ -1709,7 +1882,7 @@ static void window_top_toolbar_tool_down(){ * * rct2: 0x006644DD */ -void selection_raise_land(uint8 flags){ +money32 selection_raise_land(uint8 flags){ int center_x = (RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_X, uint16) + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_X, uint16) ) / 2; @@ -1730,12 +1903,12 @@ void selection_raise_land(uint8 flags){ if (RCT2_GLOBAL(RCT2_ADDRESS_LAND_TOOL_SIZE, sint16) == 0) { int di = 1; - game_do_command(center_x, flags, center_y, dx, GAME_COMMAND_EDIT_LAND_SMOOTH, di, bp); + return game_do_command(center_x, flags, center_y, dx, GAME_COMMAND_EDIT_LAND_SMOOTH, di, bp); } else { int di = RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_TYPE, uint16); - game_do_command(center_x, flags, center_y, dx, GAME_COMMAND_RAISE_LAND, di, bp); + return game_do_command(center_x, flags, center_y, dx, GAME_COMMAND_RAISE_LAND, di, bp); } } @@ -1743,7 +1916,7 @@ void selection_raise_land(uint8 flags){ * * rct2: 0x006645B3 */ -void selection_lower_land(uint8 flags){ +money32 selection_lower_land(uint8 flags){ int center_x = (RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_X, uint16) + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_X, uint16) ) / 2; @@ -1764,11 +1937,11 @@ void selection_lower_land(uint8 flags){ if (RCT2_GLOBAL(RCT2_ADDRESS_LAND_TOOL_SIZE, sint16) == 0) { int di = 0xFFFF; - game_do_command(center_x, flags, center_y, dx, GAME_COMMAND_EDIT_LAND_SMOOTH, di, bp); + return game_do_command(center_x, flags, center_y, dx, GAME_COMMAND_EDIT_LAND_SMOOTH, di, bp); } else { int di = RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_TYPE, uint16); - game_do_command(center_x, flags, center_y, dx, GAME_COMMAND_LOWER_LAND, di, bp); + return game_do_command(center_x, flags, center_y, dx, GAME_COMMAND_LOWER_LAND, di, bp); } } From 24f9898ce6c33ed6737c9003f720766369cfb7de Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Tue, 26 May 2015 20:44:25 +0100 Subject: [PATCH 21/32] Fixed bug with land direction This would cause the cursor to highlight the opposite tile when hovering over bottom left and bottom right --- src/interface/viewport.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/interface/viewport.c b/src/interface/viewport.c index 74a03069e8..35d60909ee 100644 --- a/src/interface/viewport.c +++ b/src/interface/viewport.c @@ -1665,9 +1665,9 @@ void screen_pos_to_map_pos(sint16 *x, sint16 *y, int *direction) } } else { if (mod_y < 16) { - my_direction = 0; - } else { my_direction = 1; + } else { + my_direction = 0; } } } From a59fd26b3d345e3704d280c23aeb16341935221c Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Wed, 27 May 2015 17:40:57 +0100 Subject: [PATCH 22/32] Added update_water Refactored up/down water commands so that it used more standard layout. Not tested. --- src/interface/viewport.c | 6 +- src/windows/top_toolbar.c | 134 +++++++++++++++++++++++++ src/world/map.c | 199 ++++++++++++++++++++------------------ src/world/map.h | 2 + 4 files changed, 243 insertions(+), 98 deletions(-) diff --git a/src/interface/viewport.c b/src/interface/viewport.c index 35d60909ee..41cb43ed47 100644 --- a/src/interface/viewport.c +++ b/src/interface/viewport.c @@ -1955,7 +1955,7 @@ void sub_68862C() * mapElement: edx * viewport: edi */ -void get_map_coordinates_from_pos(int screenX, int screenY, int flags, int *x, int *y, int *interactionType, rct_map_element **mapElement, rct_viewport **viewport) +void get_map_coordinates_from_pos(int screenX, int screenY, int flags, sint16 *x, sint16 *y, int *interactionType, rct_map_element **mapElement, rct_viewport **viewport) { RCT2_GLOBAL(0x9AC154, uint16_t) = flags & 0xFFFF; RCT2_GLOBAL(0x9AC148, uint8_t) = 0; @@ -1994,7 +1994,7 @@ void get_map_coordinates_from_pos(int screenX, int screenY, int flags, int *x, i if (viewport != NULL) *viewport = myviewport; } if (interactionType != NULL) *interactionType = RCT2_GLOBAL(0x9AC148, uint8_t); - if (x != NULL) *x = (int)RCT2_GLOBAL(0x9AC14C, int16_t); - if (y != NULL) *y = (int)RCT2_GLOBAL(0x9AC14E, int16_t); + if (x != NULL) *x = RCT2_GLOBAL(0x9AC14C, int16_t); + if (y != NULL) *y = RCT2_GLOBAL(0x9AC14E, int16_t); if (mapElement != NULL) *mapElement = RCT2_GLOBAL(0x9AC150, rct_map_element*); } \ No newline at end of file diff --git a/src/windows/top_toolbar.c b/src/windows/top_toolbar.c index 5167793671..490c6c6eca 100644 --- a/src/windows/top_toolbar.c +++ b/src/windows/top_toolbar.c @@ -1792,6 +1792,140 @@ void top_toolbar_tool_update_land(sint16 x, sint16 y){ } } +/** +* +* rct2: 0x006E6BDC +*/ +void top_toolbar_tool_update_water(sint16 x, sint16 y){ + map_invalidate_selection_rect(); + + if (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TOOL, uint8) == 3){ + if (!(RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) & (1 << 0))) + return; + + money32 lower_cost = lower_water( + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_X, sint16), + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_Y, sint16), + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_X, sint16), + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_Y, sint16), + 0); + + money32 raise_cost = raise_water( + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_X, sint16), + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_Y, sint16), + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_X, sint16), + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_Y, sint16), + 0); + + if (RCT2_GLOBAL(RCT2_ADDRESS_WATER_RAISE_COST, money32) != raise_cost || + RCT2_GLOBAL(RCT2_ADDRESS_WATER_LOWER_COST, money32) != lower_cost){ + RCT2_GLOBAL(RCT2_ADDRESS_WATER_RAISE_COST, money32) = raise_cost; + RCT2_GLOBAL(RCT2_ADDRESS_WATER_LOWER_COST, money32) = lower_cost; + window_invalidate_by_class(WC_WATER); + } + return; + } + + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) &= ~(1 << 0); + + rct_xy16 mapTile = { 0 }; + int interaction_type = 0; + get_map_coordinates_from_pos( + x, + y, + VIEWPORT_INTERACTION_MASK_TERRAIN & VIEWPORT_INTERACTION_MASK_WATER, + &mapTile.x, + &mapTile.y, + &interaction_type, + NULL, + NULL); + + if (interaction_type == VIEWPORT_INTERACTION_ITEM_NONE){ + if (RCT2_GLOBAL(RCT2_ADDRESS_WATER_RAISE_COST, money32) != MONEY32_UNDEFINED || + RCT2_GLOBAL(RCT2_ADDRESS_WATER_LOWER_COST, money32) != MONEY32_UNDEFINED){ + RCT2_GLOBAL(RCT2_ADDRESS_WATER_RAISE_COST, money32) = MONEY32_UNDEFINED; + RCT2_GLOBAL(RCT2_ADDRESS_WATER_LOWER_COST, money32) = MONEY32_UNDEFINED; + window_invalidate_by_class(WC_WATER); + } + return; + } + + mapTile.x += 16; + mapTile.y += 16; + + uint8 state_changed = 0; + + if (!(RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) & (1 << 0))){ + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) |= (1 << 0); + state_changed++; + } + + if (RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_TYPE, uint16) != 4){ + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_TYPE, uint16) = 4; + state_changed++; + } + + sint16 tool_size = RCT2_GLOBAL(RCT2_ADDRESS_LAND_TOOL_SIZE, sint16); + if (tool_size == 0) + tool_size = 1; + + sint16 tool_length = (tool_size - 1) * 32; + + // Move to tool bottom left + mapTile.x -= (tool_size - 1) * 16; + mapTile.y -= (tool_size - 1) * 16; + mapTile.x &= 0xFFE0; + mapTile.y &= 0xFFE0; + + if (RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_X, sint16) != mapTile.x){ + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_X, sint16) = mapTile.x; + state_changed++; + } + + if (RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_Y, sint16) != mapTile.y){ + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_Y, sint16) = mapTile.y; + state_changed++; + } + + mapTile.x += tool_length; + mapTile.y += tool_length; + + if (RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_X, sint16) != mapTile.x){ + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_X, sint16) = mapTile.x; + state_changed++; + } + + if (RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_Y, sint16) != mapTile.y){ + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_Y, sint16) = mapTile.y; + state_changed++; + } + + map_invalidate_selection_rect(); + if (!state_changed) + return; + + money32 lower_cost = lower_water( + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_X, sint16), + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_Y, sint16), + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_X, sint16), + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_Y, sint16), + 0); + + money32 raise_cost = raise_water( + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_X, sint16), + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_Y, sint16), + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_X, sint16), + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_Y, sint16), + 0); + + if (RCT2_GLOBAL(RCT2_ADDRESS_WATER_RAISE_COST, money32) != raise_cost || + RCT2_GLOBAL(RCT2_ADDRESS_WATER_LOWER_COST, money32) != lower_cost){ + RCT2_GLOBAL(RCT2_ADDRESS_WATER_RAISE_COST, money32) = raise_cost; + RCT2_GLOBAL(RCT2_ADDRESS_WATER_LOWER_COST, money32) = lower_cost; + window_invalidate_by_class(WC_WATER); + } +} + /** * * rct2: 0x0066CB25 diff --git a/src/world/map.c b/src/world/map.c index c84d6248a0..7086d14a7f 100644 --- a/src/world/map.c +++ b/src/world/map.c @@ -1560,68 +1560,59 @@ void game_command_lower_land(int* eax, int* ebx, int* ecx, int* edx, int* esi, i *ebx = cost; } -/** - * - * rct2: 0x006E66A0 - */ -void game_command_raise_water(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp) -{ - int ax = (uint16)*eax; - int ay = (uint16)*ecx; - int bx = (uint16)*edi; - int by = (uint16)*ebp; - - int cost = 0; +money32 raise_water(sint16 x0, sint16 y0, sint16 x1, sint16 y1, uint8 flags){ + money32 cost = 0; uint8 max_height = 0xFF; - for(int yi = ay; yi <= by; yi += 32){ - for(int xi = ax; xi <= bx; xi += 32){ + for (int yi = y0; yi <= y1; yi += 32){ + for (int xi = x0; xi <= x1; xi += 32){ rct_map_element* map_element = map_get_surface_element_at(xi / 32, yi / 32); uint8 height = map_element->base_height; - if(map_element->properties.surface.terrain & 0x1F){ + if (map_element->properties.surface.terrain & 0x1F){ height = (map_element->properties.surface.terrain & 0x1F) * 2; } - if(max_height > height){ + if (max_height > height){ max_height = height; } } } - for(int yi = ay; yi <= by; yi += 32){ - for(int xi = ax; xi <= bx; xi += 32){ + for (int yi = y0; yi <= y1; yi += 32){ + for (int xi = x0; xi <= x1; xi += 32){ rct_map_element* map_element = map_get_surface_element_at(xi / 32, yi / 32); - - if(map_element->base_height <= max_height){ + + if (map_element->base_height <= max_height){ uint8 height = (map_element->properties.surface.terrain & 0x1F); - if(height){ + if (height){ height *= 2; - if(height > max_height){ + if (height > max_height){ continue; } height += 2; - }else{ + } + else{ height = map_element->base_height + 2; } - int eax2 = xi, ebx2 = *ebx, ecx2 = yi, edx2 = (max_height << 8) + height, esi2, edi2, ebp2; - ebx2 = game_do_command_p(GAME_COMMAND_16, &eax2, &ebx2, &ecx2, &edx2, &esi2, &edi2, &ebp2); - if(ebx2 == MONEY32_UNDEFINED){ - *ebx = MONEY32_UNDEFINED; - return; - }else{ - cost += ebx2; + + money32 cost2 = game_do_command(GAME_COMMAND_16, xi, flags, yi, (max_height << 8) + height, 0, 0, 0); + if (cost2 == MONEY32_UNDEFINED){ + return MONEY32_UNDEFINED; + } + else{ + cost += cost2; } } } } - if(*ebx & GAME_COMMAND_FLAG_APPLY){ - int x = ((ax + bx) / 2) + 16; - int y = ((ay + by) / 2) + 16; + if (flags & GAME_COMMAND_FLAG_APPLY){ + int x = ((x0 + x1) / 2) + 16; + int y = ((y0 + y1) / 2) + 16; int z = map_element_height(x, y); sint16 water_height_z = z >> 16; sint16 base_height_z = z; z = water_height_z; - if(!z){ + if (!z){ z = base_height_z; } RCT2_GLOBAL(0x009DEA5E, uint32) = x; @@ -1629,7 +1620,79 @@ void game_command_raise_water(int* eax, int* ebx, int* ecx, int* edx, int* esi, RCT2_GLOBAL(0x009DEA62, uint32) = z; sound_play_panned(SOUND_LAYING_OUT_WATER, 0x8001, x, y, z); } - *ebx = cost; + return cost; +} + +/** + * + * rct2: 0x006E66A0 + */ +void game_command_raise_water(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp) +{ + *ebx = raise_water( + (sint16)*eax, + (sint16)*ecx, + (sint16)*edi, + (sint16)*ebp, + (uint8)*ebx); +} + +money32 lower_water(sint16 x0, sint16 y0, sint16 x1, sint16 y1, uint8 flags){ + money32 cost = 0; + + uint8 min_height = 0; + + for (int yi = y0; yi <= y1; yi += 32){ + for (int xi = x0; xi <= x1; xi += 32){ + rct_map_element* map_element = map_get_surface_element_at(xi / 32, yi / 32); + + uint8 height = map_element->properties.surface.terrain & 0x1F; + if (height){ + height *= 2; + if (height > min_height){ + min_height = height; + } + } + } + } + + for (int yi = y0; yi <= y1; yi += 32){ + for (int xi = x0; xi <= x1; xi += 32){ + rct_map_element* map_element = map_get_surface_element_at(xi / 32, yi / 32); + + uint8 height = (map_element->properties.surface.terrain & 0x1F); + if (height){ + height *= 2; + if (height < min_height){ + continue; + } + height -= 2; + int cost2 = game_do_command(xi, flags, yi, (min_height << 8) + height, GAME_COMMAND_16, 0, 0); + if (cost2 == MONEY32_UNDEFINED){ + return MONEY32_UNDEFINED; + } + else{ + cost += cost2; + } + } + } + } + if (flags & GAME_COMMAND_FLAG_APPLY){ + int x = ((x0 + x1) / 2) + 16; + int y = ((y0 + y1) / 2) + 16; + int z = map_element_height(x, y); + sint16 water_height_z = z >> 16; + sint16 base_height_z = z; + z = water_height_z; + if (!z){ + z = base_height_z; + } + RCT2_GLOBAL(0x009DEA5E, uint32) = x; + RCT2_GLOBAL(0x009DEA60, uint32) = y; + RCT2_GLOBAL(0x009DEA62, uint32) = z; + sound_play_panned(SOUND_LAYING_OUT_WATER, 0x8001, x, y, z); + } + return cost; } /** @@ -1638,66 +1701,12 @@ void game_command_raise_water(int* eax, int* ebx, int* ecx, int* edx, int* esi, */ void game_command_lower_water(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp) { - int ax = (uint16)*eax; - int ay = (uint16)*ecx; - int bx = (uint16)*edi; - int by = (uint16)*ebp; - - int cost = 0; - - uint8 min_height = 0; - - for(int yi = ay; yi <= by; yi += 32){ - for(int xi = ax; xi <= bx; xi += 32){ - rct_map_element* map_element = map_get_surface_element_at(xi / 32, yi / 32); - - uint8 height = map_element->properties.surface.terrain & 0x1F; - if(height){ - height *= 2; - if(height > min_height){ - min_height = height; - } - } - } - } - - for(int yi = ay; yi <= by; yi += 32){ - for(int xi = ax; xi <= bx; xi += 32){ - rct_map_element* map_element = map_get_surface_element_at(xi / 32, yi / 32); - - uint8 height = (map_element->properties.surface.terrain & 0x1F); - if(height){ - height *= 2; - if(height < min_height){ - continue; - } - height -= 2; - int ebx2 = game_do_command(xi, *ebx, yi, (min_height << 8) + height, GAME_COMMAND_16, 0, 0); - if(ebx2 == MONEY32_UNDEFINED){ - *ebx = MONEY32_UNDEFINED; - return; - }else{ - cost += ebx2; - } - } - } - } - if(*ebx & GAME_COMMAND_FLAG_APPLY){ - int x = ((ax + bx) / 2) + 16; - int y = ((ay + by) / 2) + 16; - int z = map_element_height(x, y); - sint16 water_height_z = z >> 16; - sint16 base_height_z = z; - z = water_height_z; - if(!z){ - z = base_height_z; - } - RCT2_GLOBAL(0x009DEA5E, uint32) = x; - RCT2_GLOBAL(0x009DEA60, uint32) = y; - RCT2_GLOBAL(0x009DEA62, uint32) = z; - sound_play_panned(SOUND_LAYING_OUT_WATER, 0x8001, x, y, z); - } - *ebx = cost; + *ebx = lower_water( + (sint16)*eax, + (sint16)*ecx, + (sint16)*edi, + (sint16)*ebp, + (uint8)*ebx); } /** diff --git a/src/world/map.h b/src/world/map.h index 89d65937df..f978ed971b 100644 --- a/src/world/map.h +++ b/src/world/map.h @@ -280,6 +280,8 @@ int map_can_construct_with_clear_at(int x, int y, int zLow, int zHigh, void *cle int map_can_construct_at(int x, int y, int zLow, int zHigh, uint8 bl); int sub_6BA278(int ebx); money32 map_clear_scenery(int x0, int y0, int x1, int y1, int flags); +money32 lower_water(sint16 x0, sint16 y0, sint16 x1, sint16 y1, uint8 flags); +money32 raise_water(sint16 x0, sint16 y0, sint16 x1, sint16 y1, uint8 flags); void game_command_remove_scenery(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp); void game_command_remove_large_scenery(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp); From b2caeaf531195a99d1b2655b6f6f6d897dfa21cb Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Wed, 27 May 2015 18:05:57 +0100 Subject: [PATCH 23/32] Refactor of code slightly Since get_map_coordinates_from_pos returns sint16 values I changed it so that it didn't use sint32 values. --- src/interface/viewport.c | 3 ++- src/interface/viewport.h | 2 +- src/interface/viewport_interaction.c | 13 +++++++++--- src/windows/footpath.c | 11 ++++++++-- src/windows/ride.c | 5 ++++- src/windows/top_toolbar.c | 18 +++++------------ src/windows/viewport.c | 2 +- src/world/footpath.c | 30 ++++++++++++++++++---------- src/world/map.c | 2 +- 9 files changed, 52 insertions(+), 34 deletions(-) diff --git a/src/interface/viewport.c b/src/interface/viewport.c index 41cb43ed47..dab3136038 100644 --- a/src/interface/viewport.c +++ b/src/interface/viewport.c @@ -1609,7 +1609,8 @@ void viewport_paint(rct_viewport* viewport, rct_drawpixelinfo* dpi, int left, in * viewport: edi */ void sub_688972(int screenX, int screenY, sint16 *x, sint16 *y, rct_viewport **viewport) { - int my_x, my_y, z, interactionType; + sint16 my_x, my_y; + int z, interactionType; rct_viewport *myViewport; get_map_coordinates_from_pos(screenX, screenY, VIEWPORT_INTERACTION_MASK_TERRAIN, &my_x, &my_y, &interactionType, NULL, &myViewport); if (interactionType == VIEWPORT_INTERACTION_ITEM_NONE) { diff --git a/src/interface/viewport.h b/src/interface/viewport.h index 7bd3d1b23d..7dcf3243fc 100644 --- a/src/interface/viewport.h +++ b/src/interface/viewport.h @@ -113,7 +113,7 @@ void show_construction_rights(); void hide_construction_rights(); void viewport_set_visibility(uint8 mode); -void get_map_coordinates_from_pos(int screenX, int screenY, int flags, int *x, int *y, int *interactionType, rct_map_element **mapElement, rct_viewport **viewport); +void get_map_coordinates_from_pos(int screenX, int screenY, int flags, sint16 *x, sint16 *y, int *interactionType, rct_map_element **mapElement, rct_viewport **viewport); int viewport_interaction_get_item_left(int x, int y, viewport_interaction_info *info); int viewport_interaction_left_over(int x, int y); diff --git a/src/interface/viewport_interaction.c b/src/interface/viewport_interaction.c index 7c131adaae..6d2ac7152f 100644 --- a/src/interface/viewport_interaction.c +++ b/src/interface/viewport_interaction.c @@ -59,7 +59,10 @@ int viewport_interaction_get_item_left(int x, int y, viewport_interaction_info * if ((RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_TRACK_DESIGNER) && s6Info->var_000 != 6) return info->type = VIEWPORT_INTERACTION_ITEM_NONE; - get_map_coordinates_from_pos(x, y, VIEWPORT_INTERACTION_MASK_SPRITE & VIEWPORT_INTERACTION_MASK_RIDE & VIEWPORT_INTERACTION_MASK_PARK, &info->x, &info->y, &info->type, &info->mapElement, NULL); + rct_xy16 mapCoord = { 0 }; + get_map_coordinates_from_pos(x, y, VIEWPORT_INTERACTION_MASK_SPRITE & VIEWPORT_INTERACTION_MASK_RIDE & VIEWPORT_INTERACTION_MASK_PARK, &mapCoord.x, &mapCoord.y, &info->type, &info->mapElement, NULL); + info->x = mapCoord.x; + info->y = mapCoord.y; mapElement = info->mapElement; sprite = (rct_sprite*)mapElement; @@ -179,7 +182,10 @@ int viewport_interaction_get_item_right(int x, int y, viewport_interaction_info if ((RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_TRACK_DESIGNER) && s6Info->var_000 != 6) return info->type = VIEWPORT_INTERACTION_ITEM_NONE; - get_map_coordinates_from_pos(x, y, ~(VIEWPORT_INTERACTION_MASK_TERRAIN & VIEWPORT_INTERACTION_MASK_WATER), &info->x, &info->y, &info->type, &info->mapElement, NULL); + rct_xy16 mapCoord = { 0 }; + get_map_coordinates_from_pos(x, y, ~(VIEWPORT_INTERACTION_MASK_TERRAIN & VIEWPORT_INTERACTION_MASK_WATER), &mapCoord.x, &mapCoord.y, &info->type, &info->mapElement, NULL); + info->x = mapCoord.x; + info->y = mapCoord.y; mapElement = info->mapElement; sprite = (rct_sprite*)mapElement; @@ -566,7 +572,8 @@ static rct_peep *viewport_interaction_get_closest_peep(int x, int y, int maxDist */ void sub_68A15E(int screenX, int screenY, short *x, short *y, int *direction, rct_map_element **mapElement) { - int my_x, my_y, z, interactionType; + sint16 my_x, my_y; + int z, interactionType; rct_map_element *myMapElement; rct_viewport *viewport; get_map_coordinates_from_pos(screenX, screenY, VIEWPORT_INTERACTION_MASK_TERRAIN & VIEWPORT_INTERACTION_MASK_WATER, &my_x, &my_y, &interactionType, &myMapElement, &viewport); diff --git a/src/windows/footpath.c b/src/windows/footpath.c index 64e9e9fa3a..fa50c57605 100644 --- a/src/windows/footpath.c +++ b/src/windows/footpath.c @@ -673,7 +673,10 @@ static void window_footpath_set_provisional_path_at_point(int x, int y) map_invalidate_selection_rect(); RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) &= ~(1 << 2); - get_map_coordinates_from_pos(x, y, VIEWPORT_INTERACTION_MASK_FOOTPATH & VIEWPORT_INTERACTION_MASK_TERRAIN, &x, &y, &interactionType, &mapElement, NULL); + rct_xy16 mapCoord = { 0 }; + get_map_coordinates_from_pos(x, y, VIEWPORT_INTERACTION_MASK_FOOTPATH & VIEWPORT_INTERACTION_MASK_TERRAIN, &mapCoord.x, &mapCoord.y, &interactionType, &mapElement, NULL); + x = mapCoord.x; + y = mapCoord.y; if (interactionType == VIEWPORT_INTERACTION_ITEM_NONE) { RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) &= ~(1 << 0); @@ -760,7 +763,11 @@ static void window_footpath_place_path_at_point(int x, int y) footpath_provisional_update(); - get_map_coordinates_from_pos(x, y, VIEWPORT_INTERACTION_MASK_FOOTPATH & VIEWPORT_INTERACTION_MASK_TERRAIN, &x, &y, &interactionType, &mapElement, NULL); + rct_xy16 mapCoord = { 0 }; + get_map_coordinates_from_pos(x, y, VIEWPORT_INTERACTION_MASK_FOOTPATH & VIEWPORT_INTERACTION_MASK_TERRAIN, &mapCoord.x, &mapCoord.y, &interactionType, &mapElement, NULL); + x = mapCoord.x; + y = mapCoord.y; + if (interactionType == VIEWPORT_INTERACTION_ITEM_NONE) return; diff --git a/src/windows/ride.c b/src/windows/ride.c index 04c29e33a6..6f93696dce 100644 --- a/src/windows/ride.c +++ b/src/windows/ride.c @@ -3565,7 +3565,10 @@ static void window_ride_set_track_colour_scheme(rct_window *w, int x, int y) int interactionType; - get_map_coordinates_from_pos(x, y, VIEWPORT_INTERACTION_MASK_RIDE, &x, &y, &interactionType, &mapElement, NULL); + rct_xy16 mapCoord = { 0 }; + get_map_coordinates_from_pos(x, y, VIEWPORT_INTERACTION_MASK_RIDE, &mapCoord.x, &mapCoord.y, &interactionType, &mapElement, NULL); + x = mapCoord.x; + y = mapCoord.y; // Get map coordinates from point /*int eax, ebx, ecx, edx, esi, edi, ebp; eax = x; diff --git a/src/windows/top_toolbar.c b/src/windows/top_toolbar.c index 490c6c6eca..b64e2f6583 100644 --- a/src/windows/top_toolbar.c +++ b/src/windows/top_toolbar.c @@ -729,7 +729,8 @@ static void repaint_scenery_tool_down(sint16 x, sint16 y, sint16 widgetIndex){ //RCT2_CALLPROC_X(0x6E2CC6, x, y, 0, widgetIndex, 0, 0, 0); //return; // ax, cx, bl - int grid_x, grid_y, type; + sint16 grid_x, grid_y; + int type; // edx rct_map_element* map_element; uint16 flags = @@ -1051,10 +1052,7 @@ void sub_6E1F34(sint16 x, sint16 y, uint16 selected_scenery, sint16* grid_x, sin int interaction_type = 0; rct_map_element* map_element; - int map_x, map_y; - get_map_coordinates_from_pos(x, y, flags, &map_x, &map_y, &interaction_type, &map_element, NULL); - *grid_x = (sint16)map_x; - *grid_y = (sint16)map_y; + get_map_coordinates_from_pos(x, y, flags, grid_x, grid_y, &interaction_type, &map_element, NULL); if (interaction_type == VIEWPORT_INTERACTION_ITEM_NONE) { @@ -1133,10 +1131,7 @@ void sub_6E1F34(sint16 x, sint16 y, uint16 selected_scenery, sint16* grid_x, sin int interaction_type = 0; rct_map_element* map_element; - int map_x, map_y; - get_map_coordinates_from_pos(x, y, flags, &map_x, &map_y, &interaction_type, &map_element, NULL); - *grid_x = (sint16)map_x; - *grid_y = (sint16)map_y; + get_map_coordinates_from_pos(x, y, flags, grid_x, grid_y, &interaction_type, &map_element, NULL); if (interaction_type == VIEWPORT_INTERACTION_ITEM_NONE) { @@ -1284,10 +1279,7 @@ void sub_6E1F34(sint16 x, sint16 y, uint16 selected_scenery, sint16* grid_x, sin int interaction_type = 0; rct_map_element* map_element; - int map_x, map_y; - get_map_coordinates_from_pos(x, y, flags, &map_x, &map_y, &interaction_type, &map_element, NULL); - *grid_x = (sint16)map_x; - *grid_y = (sint16)map_y; + get_map_coordinates_from_pos(x, y, flags, grid_x, grid_y, &interaction_type, &map_element, NULL); if (interaction_type == VIEWPORT_INTERACTION_ITEM_NONE) { diff --git a/src/windows/viewport.c b/src/windows/viewport.c index 0caaa347fe..f3a446c11b 100644 --- a/src/windows/viewport.c +++ b/src/windows/viewport.c @@ -153,7 +153,7 @@ static void window_viewport_mouseup() { short widgetIndex; rct_window *w, *mainWindow; - int x, y; + sint16 x, y; window_widget_get_registers(w, widgetIndex); diff --git a/src/world/footpath.c b/src/world/footpath.c index 6c937d7d93..5cc366dc8b 100644 --- a/src/world/footpath.c +++ b/src/world/footpath.c @@ -493,9 +493,11 @@ void footpath_get_coordinates_from_pos(int screenX, int screenY, int *x, int *y, int z, interactionType; rct_map_element *myMapElement; rct_viewport *viewport; - get_map_coordinates_from_pos(screenX, screenY, VIEWPORT_INTERACTION_MASK_FOOTPATH, x, y, &interactionType, &myMapElement, &viewport); + rct_xy16 map_pos = { 0 }; + + get_map_coordinates_from_pos(screenX, screenY, VIEWPORT_INTERACTION_MASK_FOOTPATH, &map_pos.x, &map_pos.y, &interactionType, &myMapElement, &viewport); if (interactionType != VIEWPORT_INTERACTION_ITEM_FOOTPATH || !(viewport->flags & (VIEWPORT_FLAG_UNDERGROUND_INSIDE | VIEWPORT_FLAG_HIDE_BASE | VIEWPORT_FLAG_HIDE_VERTICAL))) { - get_map_coordinates_from_pos(screenX, screenY, VIEWPORT_INTERACTION_MASK_FOOTPATH & VIEWPORT_INTERACTION_MASK_TERRAIN, x, y, &interactionType, &myMapElement, &viewport); + get_map_coordinates_from_pos(screenX, screenY, VIEWPORT_INTERACTION_MASK_FOOTPATH & VIEWPORT_INTERACTION_MASK_TERRAIN, &map_pos.x, &map_pos.y, &interactionType, &myMapElement, &viewport); if (interactionType == VIEWPORT_INTERACTION_ITEM_NONE) { if (x != NULL) *x = 0x8000; return; @@ -512,16 +514,15 @@ void footpath_get_coordinates_from_pos(int screenX, int screenY, int *x, int *y, } RCT2_GLOBAL(0x00F1AD3C, uint16) = z; - RCT2_GLOBAL(0x00F1AD34, sint16) = *x; - RCT2_GLOBAL(0x00F1AD36, sint16) = *y; - RCT2_GLOBAL(0x00F1AD38, sint16) = *x + 31; - RCT2_GLOBAL(0x00F1AD3A, sint16) = *y + 31; + RCT2_GLOBAL(0x00F1AD34, sint16) = map_pos.x; + RCT2_GLOBAL(0x00F1AD36, sint16) = map_pos.y; + RCT2_GLOBAL(0x00F1AD38, sint16) = map_pos.x + 31; + RCT2_GLOBAL(0x00F1AD3A, sint16) = map_pos.y + 31; - *x += 16; - *y += 16; + map_pos.x += 16; + map_pos.y += 16; rct_xy16 start_vp_pos = screen_coord_to_viewport_coord(viewport, screenX, screenY); - rct_xy16 map_pos = { *x, *y }; for (int i = 0; i < 5; i++) { if (RCT2_GLOBAL(0x00F1AD3E, uint8) != 6) { @@ -573,7 +574,12 @@ void footpath_bridge_get_info_from_pos(int screenX, int screenY, int *x, int *y, // First check if we point at an entrance or exit. In that case, we would want the path coming from the entrance/exit. int interactionType; rct_viewport *viewport; - get_map_coordinates_from_pos(screenX, screenY, VIEWPORT_INTERACTION_MASK_RIDE, x, y, &interactionType, mapElement, &viewport); + + rct_xy16 map_pos = { 0 }; + get_map_coordinates_from_pos(screenX, screenY, VIEWPORT_INTERACTION_MASK_RIDE, &map_pos.x, &map_pos.y, &interactionType, mapElement, &viewport); + *x = map_pos.x; + *y = map_pos.y; + if (interactionType == VIEWPORT_INTERACTION_ITEM_RIDE && viewport->flags & (VIEWPORT_FLAG_UNDERGROUND_INSIDE | VIEWPORT_FLAG_HIDE_BASE | VIEWPORT_FLAG_HIDE_VERTICAL) && map_element_get_type(*mapElement) == MAP_ELEMENT_TYPE_ENTRANCE) { @@ -588,7 +594,9 @@ void footpath_bridge_get_info_from_pos(int screenX, int screenY, int *x, int *y, } } - get_map_coordinates_from_pos(screenX, screenY, VIEWPORT_INTERACTION_MASK_RIDE & VIEWPORT_INTERACTION_MASK_FOOTPATH & VIEWPORT_INTERACTION_MASK_TERRAIN, x, y, &interactionType, mapElement, &viewport); + get_map_coordinates_from_pos(screenX, screenY, VIEWPORT_INTERACTION_MASK_RIDE & VIEWPORT_INTERACTION_MASK_FOOTPATH & VIEWPORT_INTERACTION_MASK_TERRAIN, &map_pos.x, &map_pos.y, &interactionType, mapElement, &viewport); + *x = map_pos.x; + *y = map_pos.y; if (interactionType == VIEWPORT_INTERACTION_ITEM_RIDE && map_element_get_type(*mapElement) == MAP_ELEMENT_TYPE_ENTRANCE) { int ebp = (*mapElement)->properties.entrance.type << 4; int bl = (*mapElement)->properties.entrance.index & 0xF; // Seems to be always 0? diff --git a/src/world/map.c b/src/world/map.c index 7086d14a7f..891f55dfc5 100644 --- a/src/world/map.c +++ b/src/world/map.c @@ -1595,7 +1595,7 @@ money32 raise_water(sint16 x0, sint16 y0, sint16 x1, sint16 y1, uint8 flags){ height = map_element->base_height + 2; } - money32 cost2 = game_do_command(GAME_COMMAND_16, xi, flags, yi, (max_height << 8) + height, 0, 0, 0); + money32 cost2 = game_do_command(xi, flags, yi, (max_height << 8) + height, GAME_COMMAND_16, 0, 0); if (cost2 == MONEY32_UNDEFINED){ return MONEY32_UNDEFINED; } From 5578a166631df52be51e27f3af28e4fa742d982d Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Thu, 28 May 2015 19:33:09 +0100 Subject: [PATCH 24/32] Started update_scenery --- src/windows/top_toolbar.c | 48 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/src/windows/top_toolbar.c b/src/windows/top_toolbar.c index b64e2f6583..d15b84eade 100644 --- a/src/windows/top_toolbar.c +++ b/src/windows/top_toolbar.c @@ -1918,6 +1918,52 @@ void top_toolbar_tool_update_water(sint16 x, sint16 y){ } } +/** +* +* rct2: 0x006E287B +*/ +void top_toolbar_tool_update_scenery(sint16 x, sint16 y){ + map_invalidate_selection_rect(); + map_invalidate_map_selection_tiles(); + + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) &= ~((1 << 0) | (1 << 1)); + + if (window_scenery_is_repaint_scenery_tool_on) + return; + + sint16 selected_tab = window_scenery_selected_scenery_by_tab[window_scenery_active_tab_index]; + + if (selected_tab == -1){ + scenery_remove_ghost_tool_placement(); + return; + } + + uint8 scenery_type = (selected_tab & 0xFF00) >> 8; + uint8 selected_scenery = selected_tab & 0xFF; + rct_xy16 mapTile = { 0 }; + uint32 parameter1, parameter2, parameter3; + + sub_6E1F34(x, y, selected_tab, &mapTile.x, &mapTile.y, ¶meter1, ¶meter2, ¶meter3); + + if (mapTile.x == (sint16)0x8000){ + scenery_remove_ghost_tool_placement(); + return; + } + + switch (scenery_type){ + case 0: + break; + case 1: + break; + case 2: + break; + case 3: + break; + case 4: + break; + } +} + /** * * rct2: 0x0066CB25 @@ -1942,7 +1988,7 @@ static void window_top_toolbar_tool_update() top_toolbar_tool_update_land(x, y); break; case WIDX_WATER: - RCT2_CALLPROC_X(0x006E6BDC, x, y, 0, widgetIndex, (int)w, 0, 0); + top_toolbar_tool_update_water(x, y); break; case WIDX_SCENERY: RCT2_CALLPROC_X(0x006E287B, x, y, 0, widgetIndex, (int)w, 0, 0); From eef779378ec67f2acd8635505805e19ee7924903 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Thu, 28 May 2015 22:07:39 +0100 Subject: [PATCH 25/32] Added more of update_scenery Only large scenery missing --- src/windows/top_toolbar.c | 166 +++++++++++++++++++++++++++++++++++++- 1 file changed, 165 insertions(+), 1 deletion(-) diff --git a/src/windows/top_toolbar.c b/src/windows/top_toolbar.c index d15b84eade..95e8eeffab 100644 --- a/src/windows/top_toolbar.c +++ b/src/windows/top_toolbar.c @@ -1918,6 +1918,15 @@ void top_toolbar_tool_update_water(sint16 x, sint16 y){ } } +money32 sub_6E24F6(rct_xy16 map_tile, uint32 parameter_1, uint32 parameter_2, uint32 parameter_3, uint16 selected_tab){ + + int eax = map_tile.x, ebx = parameter_1, ecx = map_tile.y, edx = parameter_2, esi = 0, ebp = selected_tab, edi = parameter_3; + + RCT2_CALLFUNC_X(0x006E24F6, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); + + return (money32)ebx; +} + /** * * rct2: 0x006E287B @@ -1950,16 +1959,171 @@ void top_toolbar_tool_update_scenery(sint16 x, sint16 y){ return; } + rct_scenery_entry* scenery; + uint8 bl; + money32 cost; + switch (scenery_type){ case 0: + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) |= (1 << 0); + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_X, sint16) = mapTile.x; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_Y, sint16) = mapTile.y; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_X, sint16) = mapTile.x; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_Y, sint16) = mapTile.y; + + scenery = g_smallSceneryEntries[selected_scenery]; + + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_TYPE, uint16) = 4; + if (!(scenery->small_scenery.flags & SMALL_SCENERY_FLAG_FULL_TILE)){ + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_TYPE, uint16) = ((parameter2 & 0xFF) ^ 2) + 6; + } + + map_invalidate_selection_rect(); + + // If no change in ghost placement + if ((RCT2_GLOBAL(0x00F64F0D, uint8) & (1 << 0)) && + mapTile.x == RCT2_GLOBAL(0x00F64EC4, sint16) && + mapTile.y == RCT2_GLOBAL(0x00F64EC6, sint16) && + (parameter2 & 0xFF) == RCT2_GLOBAL(0x00F64F0E, uint8)&& + RCT2_GLOBAL(RCT2_ADDRESS_SCENERY_Z_COORDINATE, sint16) == RCT2_GLOBAL(0x00F64F0A, sint16) && + RCT2_GLOBAL(0x00F64EDA, uint16) == selected_tab){ + return; + } + + scenery_remove_ghost_tool_placement(); + + RCT2_GLOBAL(0x00F64F0E, uint8) = (parameter2 & 0xFF); + RCT2_GLOBAL(0x00F64F0A, sint16) = RCT2_GLOBAL(RCT2_ADDRESS_SCENERY_Z_COORDINATE, sint16); + + bl = 1; + if (RCT2_GLOBAL(RCT2_ADDRESS_SCENERY_Z_COORDINATE, sint16) != 0 && + RCT2_GLOBAL(RCT2_ADDRESS_SCENERY_TOOL_SHIFT_PRESSED, uint8) != 0){ + bl = 20; + } + + for (; bl != 0; bl--){ + cost = sub_6E24F6( + mapTile, + parameter1, + parameter2, + parameter3, + selected_tab); + + if (cost != MONEY32_UNDEFINED) + break; + RCT2_GLOBAL(RCT2_ADDRESS_SCENERY_Z_COORDINATE, sint16) += 8; + } + + RCT2_GLOBAL(0x00F64EB4, money32) = cost; break; case 1: + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) |= (1 << 0); + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_X, sint16) = mapTile.x; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_Y, sint16) = mapTile.y; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_X, sint16) = mapTile.x; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_Y, sint16) = mapTile.y; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_TYPE, uint16) = 4; + + map_invalidate_selection_rect(); + + // If no change in ghost placement + if ((RCT2_GLOBAL(0x00F64F0D, uint8) & (1 << 1)) && + mapTile.x == RCT2_GLOBAL(0x00F64EC4, sint16) && + mapTile.y == RCT2_GLOBAL(0x00F64EC6, sint16) && + (parameter2 & 0xFF) == RCT2_GLOBAL(0x00F64F09, uint8)){ + return; + } + + scenery_remove_ghost_tool_placement(); + + cost = sub_6E24F6( + mapTile, + parameter1, + parameter2, + parameter3, + selected_tab); + + RCT2_GLOBAL(0x00F64EB4, money32) = cost; break; case 2: + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) |= (1 << 0); + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_X, sint16) = mapTile.x; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_Y, sint16) = mapTile.y; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_X, sint16) = mapTile.x; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_Y, sint16) = mapTile.y; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_TYPE, uint16) = 10 + parameter2 & 0xFF; + + map_invalidate_selection_rect(); + + // If no change in ghost placement + if ((RCT2_GLOBAL(0x00F64F0D, uint8) & (1 << 2)) && + mapTile.x == RCT2_GLOBAL(0x00F64EC4, sint16) && + mapTile.y == RCT2_GLOBAL(0x00F64EC6, sint16) && + (parameter2 & 0xFF) == RCT2_GLOBAL(0x00F64F11, uint8) && + RCT2_GLOBAL(RCT2_ADDRESS_SCENERY_Z_COORDINATE, sint16) == RCT2_GLOBAL(0x00F64F0A, sint16) + ){ + return; + } + + scenery_remove_ghost_tool_placement(); + + RCT2_GLOBAL(0x00F64F11, uint8) = (parameter2 & 0xFF); + RCT2_GLOBAL(0x00F64F0A, sint16) = RCT2_GLOBAL(RCT2_ADDRESS_SCENERY_Z_COORDINATE, sint16); + + bl = 1; + if (RCT2_GLOBAL(RCT2_ADDRESS_SCENERY_Z_COORDINATE, sint16) != 0 && + RCT2_GLOBAL(RCT2_ADDRESS_SCENERY_TOOL_SHIFT_PRESSED, uint8) != 0){ + bl = 20; + } + + cost = 0; + for (; bl != 0; bl--){ + cost = sub_6E24F6( + mapTile, + parameter1, + parameter2, + parameter3, + selected_tab); + + if (cost != MONEY32_UNDEFINED) + break; + RCT2_GLOBAL(RCT2_ADDRESS_SCENERY_Z_COORDINATE, sint16) += 8; + } + + RCT2_GLOBAL(0x00F64EB4, money32) = cost; break; case 3: + //6e29f2 break; case 4: + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) |= (1 << 0); + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_X, sint16) = mapTile.x; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_Y, sint16) = mapTile.y; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_X, sint16) = mapTile.x; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_Y, sint16) = mapTile.y; + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_TYPE, uint16) = 4; + + map_invalidate_selection_rect(); + + // If no change in ghost placement + if ((RCT2_GLOBAL(0x00F64F0D, uint8) & (1 << 4)) && + mapTile.x == RCT2_GLOBAL(0x00F64EC4, sint16) && + mapTile.y == RCT2_GLOBAL(0x00F64EC6, sint16) && + (parameter2 & 0xFF) == RCT2_GLOBAL(0x00F64F09, uint8) && + ((parameter2 >> 8) & 0xFF) == RCT2_GLOBAL(0x00F64EC0, uint8)){ + return; + } + + scenery_remove_ghost_tool_placement(); + + cost = sub_6E24F6( + mapTile, + parameter1, + parameter2, + parameter3, + selected_tab); + + RCT2_GLOBAL(0x00F64EB4, money32) = cost; break; } } @@ -1991,7 +2155,7 @@ static void window_top_toolbar_tool_update() top_toolbar_tool_update_water(x, y); break; case WIDX_SCENERY: - RCT2_CALLPROC_X(0x006E287B, x, y, 0, widgetIndex, (int)w, 0, 0); + top_toolbar_tool_update_scenery(x, y); break; } } From e04f649d2ad675928fd2ec3fb9156274ef824caa Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Fri, 29 May 2015 19:08:46 +0100 Subject: [PATCH 26/32] Added scenery_large_update From quick test seems to be working --- src/windows/top_toolbar.c | 59 ++++++++++++++++++++++++++++++++++++++- src/world/map.h | 1 + 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/src/windows/top_toolbar.c b/src/windows/top_toolbar.c index 95e8eeffab..f0eee8cfe6 100644 --- a/src/windows/top_toolbar.c +++ b/src/windows/top_toolbar.c @@ -2093,7 +2093,64 @@ void top_toolbar_tool_update_scenery(sint16 x, sint16 y){ RCT2_GLOBAL(0x00F64EB4, money32) = cost; break; case 3: - //6e29f2 + scenery = g_largeSceneryEntries[selected_scenery]; + rct_xy16* selectedTile = gMapSelectionTiles; + + for (rct_large_scenery_tile* tile = scenery->large_scenery.tiles; tile->x_offset != (sint16)0xFFFF; tile++){ + rct_xy16 tileLocation = { + .x = tile->x_offset, + .y = tile->y_offset + }; + + rotate_map_coordinates(&tileLocation.x, &tileLocation.y, (parameter1 >> 8) & 0xFF); + + tileLocation.x += mapTile.x; + tileLocation.y += mapTile.y; + + selectedTile->x = tileLocation.x; + selectedTile->y = tileLocation.y; + selectedTile++; + } + selectedTile->x = 0xFFFF; + + RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) |= (1 << 1); + map_invalidate_map_selection_tiles(); + + // If no change in ghost placement + if ((RCT2_GLOBAL(0x00F64F0D, uint8) & (1 << 3)) && + mapTile.x == RCT2_GLOBAL(0x00F64EC4, sint16) && + mapTile.y == RCT2_GLOBAL(0x00F64EC6, sint16) && + RCT2_GLOBAL(RCT2_ADDRESS_SCENERY_Z_COORDINATE, sint16) == RCT2_GLOBAL(0x00F64F0A, sint16) && + (parameter3 & 0xFFFF) == RCT2_GLOBAL(0x00F64EDA, uint16)){ + return; + } + + scenery_remove_ghost_tool_placement(); + + RCT2_GLOBAL(0x00F64EDA, uint16) = (parameter3 & 0xFFFF); + RCT2_GLOBAL(0x00F64F0A, sint16) = RCT2_GLOBAL(RCT2_ADDRESS_SCENERY_Z_COORDINATE, sint16); + + bl = 1; + if (RCT2_GLOBAL(RCT2_ADDRESS_SCENERY_Z_COORDINATE, sint16) != 0 && + RCT2_GLOBAL(RCT2_ADDRESS_SCENERY_TOOL_SHIFT_PRESSED, uint8) != 0){ + bl = 20; + } + + cost = 0; + for (; bl != 0; bl--){ + cost = sub_6E24F6( + mapTile, + parameter1, + parameter2, + parameter3, + selected_tab); + + if (cost != MONEY32_UNDEFINED) + break; + RCT2_GLOBAL(RCT2_ADDRESS_SCENERY_Z_COORDINATE, sint16) += 8; + } + + RCT2_GLOBAL(0x00F64EB4, money32) = cost; break; case 4: RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) |= (1 << 0); diff --git a/src/world/map.h b/src/world/map.h index f978ed971b..7d9337fa12 100644 --- a/src/world/map.h +++ b/src/world/map.h @@ -279,6 +279,7 @@ rct_map_element *map_element_insert(int x, int y, int z, int flags); int map_can_construct_with_clear_at(int x, int y, int zLow, int zHigh, void *clearFunc, uint8 bl); int map_can_construct_at(int x, int y, int zLow, int zHigh, uint8 bl); int sub_6BA278(int ebx); +void rotate_map_coordinates(sint16* x, sint16* y, uint8 rotation); money32 map_clear_scenery(int x0, int y0, int x1, int y1, int flags); money32 lower_water(sint16 x0, sint16 y0, sint16 x1, sint16 y1, uint8 flags); money32 raise_water(sint16 x0, sint16 y0, sint16 x1, sint16 y1, uint8 flags); From 2532e9aad26d72e9a208fdf275f80162f773cb0f Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Sat, 30 May 2015 07:04:15 +0100 Subject: [PATCH 27/32] Added try_place_ghost_scenery. Ghost scenery placement is now performed by OpenRCT2 game commands. --- src/windows/top_toolbar.c | 159 +++++++++++++++++++++++++++++++++++--- 1 file changed, 150 insertions(+), 9 deletions(-) diff --git a/src/windows/top_toolbar.c b/src/windows/top_toolbar.c index f0eee8cfe6..739a9a6316 100644 --- a/src/windows/top_toolbar.c +++ b/src/windows/top_toolbar.c @@ -1918,13 +1918,154 @@ void top_toolbar_tool_update_water(sint16 x, sint16 y){ } } -money32 sub_6E24F6(rct_xy16 map_tile, uint32 parameter_1, uint32 parameter_2, uint32 parameter_3, uint16 selected_tab){ +/* rct2: 0x006E24F6 + * On failure returns MONEY32_UNDEFINED + * On success places ghost scenery and returns cost to place proper + */ +money32 try_place_ghost_scenery(rct_xy16 map_tile, uint32 parameter_1, uint32 parameter_2, uint32 parameter_3, uint16 selected_tab){ + scenery_remove_ghost_tool_placement(); - int eax = map_tile.x, ebx = parameter_1, ecx = map_tile.y, edx = parameter_2, esi = 0, ebp = selected_tab, edi = parameter_3; + uint8 scenery_type = (selected_tab & 0xFF00) >> 8; + uint8 selected_scenery = selected_tab & 0xFF; + money32 cost = 0; + rct_map_element* mapElement; - RCT2_CALLFUNC_X(0x006E24F6, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); + switch (scenery_type){ + case 0: + // Small Scenery + //6e252b + cost = game_do_command( + map_tile.x, + parameter_1 | 0x69, + map_tile.y, + parameter_2, + GAME_COMMAND_PLACE_SCENERY, + parameter_3, + RCT2_GLOBAL(0x00F64ED4, sint16)); - return (money32)ebx; + if (cost == MONEY32_UNDEFINED) + return cost; + + RCT2_GLOBAL(0x00F64EC4, sint16) = map_tile.x; + RCT2_GLOBAL(0x00F64EC6, sint16) = map_tile.y; + RCT2_GLOBAL(0x00F64EC0, uint16) = (uint16)(parameter_3 & 0xFFFF); + RCT2_GLOBAL(0x00F64EDA, sint16) = selected_tab; + + mapElement = RCT2_GLOBAL(0x00F64EBC, rct_map_element*); + RCT2_GLOBAL(0x00F64F09, uint8) = mapElement->base_height; + RCT2_GLOBAL(0x00F64F0C, uint8) = mapElement->type; + if (RCT2_GLOBAL(0x00F64F14, uint8) & (1 << 1)){ + viewport_set_visibility(4); + } + else{ + viewport_set_visibility(5); + } + + RCT2_GLOBAL(0x00F64F0D, uint8) |= (1 << 0); + break; + case 1: + // Path Bits + //6e265b + cost = game_do_command( + map_tile.x, + parameter_1 | 0xE9, + map_tile.y, + parameter_2, + GAME_COMMAND_PLACE_PATH, + parameter_3, + 0); + + if (cost == MONEY32_UNDEFINED) + return cost; + + RCT2_GLOBAL(0x00F64EC4, sint16) = map_tile.x; + RCT2_GLOBAL(0x00F64EC6, sint16) = map_tile.y; + RCT2_GLOBAL(0x00F64F09, uint8) = (parameter_2 & 0xFF); + RCT2_GLOBAL(0x00F64F0F, uint8) = ((parameter_1 >> 8) & 0xFF); + RCT2_GLOBAL(0x00F64F10, uint8) = ((parameter_2 >> 8) & 0xFF); + RCT2_GLOBAL(0x00F64EAC, uint32) = parameter_3; + + RCT2_GLOBAL(0x00F64F0D, uint8) |= (1 << 1); + break; + case 2: + // Walls + //6e26b0 + cost = game_do_command( + map_tile.x, + parameter_1 | 0x69, + map_tile.y, + parameter_2, + GAME_COMMAND_41, + RCT2_GLOBAL(0x00F64ED4, uint16), + RCT2_GLOBAL(0x00F64F15, uint16)); + + if (cost == MONEY32_UNDEFINED) + return cost; + + RCT2_GLOBAL(0x00F64EC4, sint16) = map_tile.x; + RCT2_GLOBAL(0x00F64EC6, sint16) = map_tile.y; + RCT2_GLOBAL(0x00F64F11, uint8) = (parameter_2 & 0xFF); + + mapElement = RCT2_GLOBAL(0x00F64EBC, rct_map_element*); + RCT2_GLOBAL(0x00F64F09, uint8) = mapElement->base_height; + + RCT2_GLOBAL(0x00F64F0D, uint8) |= (1 << 2); + break; + case 3: + // Large Scenery + //6e25a7 + cost = game_do_command( + map_tile.x, + parameter_1 | 0x69, + map_tile.y, + parameter_2, + GAME_COMMAND_43, + parameter_3, + RCT2_GLOBAL(0x00F64ED4, uint16)); + + if (cost == MONEY32_UNDEFINED) + return cost; + + RCT2_GLOBAL(0x00F64EC4, sint16) = map_tile.x; + RCT2_GLOBAL(0x00F64EC6, sint16) = map_tile.y; + RCT2_GLOBAL(0x00F64EC0, uint8) = ((parameter_1 >> 8) & 0xFF); + + mapElement = RCT2_GLOBAL(0x00F64EBC, rct_map_element*); + RCT2_GLOBAL(0x00F64F09, uint8) = mapElement->base_height; + + if (RCT2_GLOBAL(0x00F64F14, uint8) & (1 << 1)){ + viewport_set_visibility(4); + } + else{ + viewport_set_visibility(5); + } + + RCT2_GLOBAL(0x00F64F0D, uint8) |= (1 << 3); + break; + case 4: + // Banners + //6e2612 + cost = game_do_command( + map_tile.x, + parameter_1 | 0x69, + map_tile.y, + parameter_2, + GAME_COMMAND_PLACE_BANNER, + parameter_3, + 0); + + if (cost == MONEY32_UNDEFINED) + return cost; + + RCT2_GLOBAL(0x00F64EC4, sint16) = map_tile.x; + RCT2_GLOBAL(0x00F64EC6, sint16) = map_tile.y; + RCT2_GLOBAL(0x00F64F09, uint8) = (parameter_2 & 0xFF); + RCT2_GLOBAL(0x00F64EC0, uint8) = ((parameter_2 >> 8) & 0xFF); + RCT2_GLOBAL(0x00F64F0D, uint8) |= (1 << 4); + break; + } + + return cost; } /** @@ -2002,7 +2143,7 @@ void top_toolbar_tool_update_scenery(sint16 x, sint16 y){ } for (; bl != 0; bl--){ - cost = sub_6E24F6( + cost = try_place_ghost_scenery( mapTile, parameter1, parameter2, @@ -2036,7 +2177,7 @@ void top_toolbar_tool_update_scenery(sint16 x, sint16 y){ scenery_remove_ghost_tool_placement(); - cost = sub_6E24F6( + cost = try_place_ghost_scenery( mapTile, parameter1, parameter2, @@ -2078,7 +2219,7 @@ void top_toolbar_tool_update_scenery(sint16 x, sint16 y){ cost = 0; for (; bl != 0; bl--){ - cost = sub_6E24F6( + cost = try_place_ghost_scenery( mapTile, parameter1, parameter2, @@ -2138,7 +2279,7 @@ void top_toolbar_tool_update_scenery(sint16 x, sint16 y){ cost = 0; for (; bl != 0; bl--){ - cost = sub_6E24F6( + cost = try_place_ghost_scenery( mapTile, parameter1, parameter2, @@ -2173,7 +2314,7 @@ void top_toolbar_tool_update_scenery(sint16 x, sint16 y){ scenery_remove_ghost_tool_placement(); - cost = sub_6E24F6( + cost = try_place_ghost_scenery( mapTile, parameter1, parameter2, From 0954687973c944c56156aa3b6da89528d3b5a3f1 Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Sat, 30 May 2015 10:00:33 +0100 Subject: [PATCH 28/32] Refactor ofviewport code slightly Fix potential water height bug --- src/interface/screenshot.c | 2 +- src/interface/viewport.c | 78 ++++++++++++++++++++------------------ 2 files changed, 43 insertions(+), 37 deletions(-) diff --git a/src/interface/screenshot.c b/src/interface/screenshot.c index fbb2d217fd..7b915c0348 100644 --- a/src/interface/screenshot.c +++ b/src/interface/screenshot.c @@ -371,7 +371,7 @@ int cmdline_for_screenshot(const char **argv, int argc) customY = (RCT2_GLOBAL(RCT2_ADDRESS_MAP_SIZE, uint8) / 2) * 32 + 16; int x, y; - int z = map_element_height(customX, customY); + int z = map_element_height(customX, customY) & 0xFFFF; switch (customRotation) { case 0: x = customY - customX; diff --git a/src/interface/viewport.c b/src/interface/viewport.c index 74a03069e8..dea4b08741 100644 --- a/src/interface/viewport.c +++ b/src/interface/viewport.c @@ -821,7 +821,7 @@ void sub_0x6736FC(rct_litter* litter, int ebx, int edx){ * Paint Quadrant * rct2: 0x0069E8B0 */ -void sub_0x69E8B0(uint32 eax, uint32 ecx){ +void sub_0x69E8B0(uint16 eax, uint16 ecx){ uint32 _eax = eax, _ecx = ecx; rct_drawpixelinfo* dpi; @@ -1231,36 +1231,42 @@ void sub_68B35F(int ax, int cx) void sub_0x68B6C2(){ rct_drawpixelinfo* dpi = RCT2_GLOBAL(0x140E9A8, rct_drawpixelinfo*); sint16 ax, bx, cx, dx; + uint16 num_vertical_quadrants = 0; + rct_xy16 mapTile; switch (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32)){ case 0: - ax = dpi->y; - bx = dpi->x; + mapTile.x = dpi->x & 0xFFE0; + mapTile.y = (dpi->y - 16) & 0xFFE0; + + bx = mapTile.x / 2; + mapTile.x = mapTile.y - bx; + mapTile.y = mapTile.y + bx; - ax -= 16; - bx &= 0xFFE0; - ax &= 0xFFE0; - bx >>= 1; - cx = ax; - ax -= bx; - cx += bx; - ax &= 0xFFE0; - cx &= 0xFFE0; - dx = dpi->height; - dx += 2128; - dx >>= 5; - for (int i = dx; i > 0; --i){ - sub_68B35F(ax, cx); - sub_0x69E8B0(ax, cx); - cx += 0x20; - ax -= 0x20; - sub_0x69E8B0(ax, cx); - ax += 0x20; - sub_68B35F(ax, cx); - sub_0x69E8B0(ax, cx); - ax += 0x20; - cx -= 0x20; - sub_0x69E8B0(ax, cx); - cx += 0x20; + mapTile.x &= 0xFFE0; + mapTile.y &= 0xFFE0; + + num_vertical_quadrants = (dpi->height + 2128) / 32; + + for (; num_vertical_quadrants > 0; --num_vertical_quadrants){ + sub_68B35F(mapTile.x, mapTile.y); + sub_0x69E8B0(mapTile.x, mapTile.y); + + mapTile.x -= 32; + mapTile.y += 32; + + sub_0x69E8B0(mapTile.x, mapTile.y); + + mapTile.x += 32; + + sub_68B35F(mapTile.x, mapTile.y); + sub_0x69E8B0(mapTile.x, mapTile.y); + + mapTile.x += 32; + mapTile.y -= 32; + + sub_0x69E8B0(mapTile.x, mapTile.y); + + mapTile.y += 32; } break; case 1: @@ -1513,8 +1519,8 @@ void viewport_paint(rct_viewport* viewport, rct_drawpixelinfo* dpi, int left, in left &= bitmask; top &= bitmask; - RCT2_GLOBAL(RCT2_ADDRESS_VIEWPORT_PAINT_X, uint16) = left; - RCT2_GLOBAL(RCT2_ADDRESS_VIEWPORT_PAINT_Y, uint16) = top; + RCT2_GLOBAL(RCT2_ADDRESS_VIEWPORT_PAINT_X, sint16) = left; + RCT2_GLOBAL(RCT2_ADDRESS_VIEWPORT_PAINT_Y, sint16) = top; RCT2_GLOBAL(RCT2_ADDRESS_VIEWPORT_PAINT_WIDTH, uint16) = width; RCT2_GLOBAL(RCT2_ADDRESS_VIEWPORT_PAINT_HEIGHT, uint16) = height; @@ -1522,11 +1528,11 @@ void viewport_paint(rct_viewport* viewport, rct_drawpixelinfo* dpi, int left, in RCT2_GLOBAL(RCT2_ADDRESS_VIEWPORT_PAINT_PITCH, uint16) = (dpi->width + dpi->pitch) - width; - int x = (sint16)(left - (sint16)(viewport->view_x & bitmask)); + sint16 x = (sint16)(left - (sint16)(viewport->view_x & bitmask)); x >>= viewport->zoom; x += viewport->x; - int y = (sint16)(top - (sint16)(viewport->view_y & bitmask)); + sint16 y = (sint16)(top - (sint16)(viewport->view_y & bitmask)); y >>= viewport->zoom; y += viewport->y; @@ -1534,16 +1540,16 @@ void viewport_paint(rct_viewport* viewport, rct_drawpixelinfo* dpi, int left, in RCT2_GLOBAL(RCT2_ADDRESS_VIEWPORT_PAINT_BITS_PTR, uint8*) = bits_pointer; rct_drawpixelinfo* dpi2 = RCT2_ADDRESS(RCT2_ADDRESS_VIEWPORT_DPI, rct_drawpixelinfo); - dpi2->y = RCT2_GLOBAL(RCT2_ADDRESS_VIEWPORT_PAINT_Y, uint16); + dpi2->y = RCT2_GLOBAL(RCT2_ADDRESS_VIEWPORT_PAINT_Y, sint16); dpi2->height = RCT2_GLOBAL(RCT2_ADDRESS_VIEWPORT_PAINT_HEIGHT, uint16); dpi2->zoom_level = (uint8)RCT2_GLOBAL(RCT2_ADDRESS_VIEWPORT_ZOOM, uint16); //Splits the screen into 32 pixel columns and renders them. - for (x = RCT2_GLOBAL(RCT2_ADDRESS_VIEWPORT_PAINT_X, uint16) & 0xFFFFFFE0; - x < RCT2_GLOBAL(RCT2_ADDRESS_VIEWPORT_PAINT_X, uint16) + RCT2_GLOBAL(RCT2_ADDRESS_VIEWPORT_PAINT_WIDTH, uint16); + for (x = RCT2_GLOBAL(RCT2_ADDRESS_VIEWPORT_PAINT_X, sint16) & 0xFFFFFFE0; + x < RCT2_GLOBAL(RCT2_ADDRESS_VIEWPORT_PAINT_X, sint16) + RCT2_GLOBAL(RCT2_ADDRESS_VIEWPORT_PAINT_WIDTH, uint16); x += 32){ - int start_x = RCT2_GLOBAL(RCT2_ADDRESS_VIEWPORT_PAINT_X, uint16); + int start_x = RCT2_GLOBAL(RCT2_ADDRESS_VIEWPORT_PAINT_X, sint16); int width_col = RCT2_GLOBAL(RCT2_ADDRESS_VIEWPORT_PAINT_WIDTH, uint16); bits_pointer = RCT2_GLOBAL(RCT2_ADDRESS_VIEWPORT_PAINT_BITS_PTR, uint8*); int pitch = RCT2_GLOBAL(RCT2_ADDRESS_VIEWPORT_PAINT_PITCH, uint16); From 3bd3fccb572357964ba62bfbf99296cab6ec64be Mon Sep 17 00:00:00 2001 From: Duncan Frost Date: Sat, 30 May 2015 10:15:29 +0100 Subject: [PATCH 29/32] Fix rotation disapearing sprites This was caused by the sprite quadrant assignment not being reset when a new rotation was assigned --- projects/openrct2.vcxproj.user | 2 +- src/editor.c | 2 +- src/game.c | 5 +++-- src/game.h | 2 +- src/interface/screenshot.c | 2 ++ src/interface/window.c | 2 +- src/scenario.c | 2 +- src/title.c | 2 +- 8 files changed, 11 insertions(+), 8 deletions(-) diff --git a/projects/openrct2.vcxproj.user b/projects/openrct2.vcxproj.user index 1846f60e7b..42ca88b12a 100644 --- a/projects/openrct2.vcxproj.user +++ b/projects/openrct2.vcxproj.user @@ -4,7 +4,7 @@ $(TargetDir) WindowsLocalDebugger $(TargetDir)\openrct2.exe - screenshot "C:\Program Files (x86)\Infogrames\RollerCoaster Tycoon 2\Scenarios\Six Flags Magic Mountain.SC6" "test.png" 1920 1080 + screenshot "C:\GOG Games\RollerCoaster Tycoon 2 Triple Thrill Pack\Scenarios\Six Flags Magic Mountain.SC6" "test.png" 16000 8000 c c 0 0 false diff --git a/src/editor.c b/src/editor.c index b51cd723f2..ada8445aa8 100644 --- a/src/editor.c +++ b/src/editor.c @@ -598,7 +598,7 @@ static void editor_finalise_main_view() w->saved_view_y -= viewport->view_height >> 1; window_invalidate(w); - sub_69E9A7(); + reset_all_sprite_quadrant_placements(); scenery_set_default_placement_configuration(); window_new_ride_init_vars(); RCT2_GLOBAL(0x009DEB7C, uint16) = 0; diff --git a/src/game.c b/src/game.c index aa7834491e..7923bcff6d 100644 --- a/src/game.c +++ b/src/game.c @@ -705,7 +705,7 @@ int game_load_save(const char *path) mainWindow->saved_view_y -= mainWindow->viewport->view_height >> 1; window_invalidate(mainWindow); - sub_69E9A7(); + reset_all_sprite_quadrant_placements(); scenery_set_default_placement_configuration(); window_new_ride_init_vars(); RCT2_GLOBAL(0x009DEB7C, uint16) = 0; @@ -722,8 +722,9 @@ int game_load_save(const char *path) /* * * rct2: 0x0069E9A7 + * Call after a rotation or loading of a save to reset sprite quadrants */ -void sub_69E9A7() +void reset_all_sprite_quadrant_placements() { for (rct_sprite* spr = g_sprite_list; spr < (rct_sprite*)RCT2_ADDRESS_SPRITES_NEXT_INDEX; spr++) if (spr->unknown.sprite_identifier != 0xFF) diff --git a/src/game.h b/src/game.h index 2b2e4cf914..9a07a8dcc1 100644 --- a/src/game.h +++ b/src/game.h @@ -97,7 +97,7 @@ void game_reduce_game_speed(); void game_create_windows(); void game_update(); void game_logic_update(); -void sub_69E9A7(); +void reset_all_sprite_quadrant_placements(); void update_palette_effects(); int game_do_command(int eax, int ebx, int ecx, int edx, int esi, int edi, int ebp); diff --git a/src/interface/screenshot.c b/src/interface/screenshot.c index 7b915c0348..8ac45e77c5 100644 --- a/src/interface/screenshot.c +++ b/src/interface/screenshot.c @@ -396,6 +396,8 @@ int cmdline_for_screenshot(const char **argv, int argc) viewport.zoom = customZoom; RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint8) = customRotation; + + reset_all_sprite_quadrant_placements(); } else { viewport.view_x = RCT2_GLOBAL(RCT2_ADDRESS_SAVED_VIEW_X, sint16) - (viewport.view_width / 2); viewport.view_y = RCT2_GLOBAL(RCT2_ADDRESS_SAVED_VIEW_Y, sint16) - (viewport.view_height / 2); diff --git a/src/interface/window.c b/src/interface/window.c index 03fac892cb..0c79b4257a 100644 --- a/src/interface/window.c +++ b/src/interface/window.c @@ -1220,7 +1220,7 @@ void window_rotate_camera(rct_window *w) window_invalidate(w); sub_688956(); - sub_69E9A7(); + reset_all_sprite_quadrant_placements(); } /** diff --git a/src/scenario.c b/src/scenario.c index 69c7742e6d..4fdae3f241 100644 --- a/src/scenario.c +++ b/src/scenario.c @@ -248,7 +248,7 @@ int scenario_load_and_play_from_path(const char *path) mainWindow->saved_view_y -= mainWindow->viewport->view_height >> 1; window_invalidate(mainWindow); - sub_69E9A7(); + reset_all_sprite_quadrant_placements(); window_new_ride_init_vars(); // Set the scenario pseduo-random seeds diff --git a/src/title.c b/src/title.c index a747336f5c..411ff5c612 100644 --- a/src/title.c +++ b/src/title.c @@ -203,7 +203,7 @@ static void title_update_showcase() } window_invalidate(w); - sub_69E9A7(); + reset_all_sprite_quadrant_placements(); window_new_ride_init_vars(); sub_684AC3(); scenery_set_default_placement_configuration(); From 0b058cfab0f1e64fd15b1c95b046e2d98128854b Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Sat, 30 May 2015 12:54:10 +0100 Subject: [PATCH 30/32] finish giant screenshots and bugs --- src/interface/screenshot.c | 61 ++++++++++++++++++++++++++------------ 1 file changed, 42 insertions(+), 19 deletions(-) diff --git a/src/interface/screenshot.c b/src/interface/screenshot.c index fbb2d217fd..21674bc123 100644 --- a/src/interface/screenshot.c +++ b/src/interface/screenshot.c @@ -318,33 +318,45 @@ bool screenshot_write_png(rct_drawpixelinfo *dpi, const char *path) int cmdline_for_screenshot(const char **argv, int argc) { - if (argc != 4 && argc != 8) { + bool giantScreenshot = argc == 5 && _stricmp(argv[2], "giant") == 0; + if (argc != 4 && argc != 8 && !giantScreenshot) { printf("Usage: openrct2 screenshot [ ]\n"); + printf("Usage: openrct2 screenshot giant \n"); return -1; } bool customLocation = false; bool centreMapX = false; bool centreMapY = false; - int customX, customY, customZoom, customRotation; + int resolutionWidth, resolutionHeight, customX, customY, customZoom, customRotation; const char *inputPath = argv[0]; const char *outputPath = argv[1]; - int resolutionWidth = atoi(argv[2]); - int resolutionHeight = atoi(argv[3]); - if (argc == 8) { + if (giantScreenshot) { + resolutionWidth = 0; + resolutionHeight = 0; customLocation = true; - if (argv[4][0] == 'c') - centreMapX = true; - else - customX = atoi(argv[4]); - if (argv[5][0] == 'c') - centreMapY = true; - else - customY = atoi(argv[5]); + centreMapX = true; + centreMapY = true; + customZoom = atoi(argv[3]); + customRotation = atoi(argv[4]) & 3; + } else { + resolutionWidth = atoi(argv[2]); + resolutionHeight = atoi(argv[3]); + if (argc == 8) { + customLocation = true; + if (argv[4][0] == 'c') + centreMapX = true; + else + customX = atoi(argv[4]); + if (argv[5][0] == 'c') + centreMapY = true; + else + customY = atoi(argv[5]); - customZoom = atoi(argv[6]); - customRotation = atoi(argv[7]) & 3; + customZoom = atoi(argv[6]); + customRotation = atoi(argv[7]) & 3; + } } gOpenRCT2Headless = true; @@ -354,6 +366,15 @@ int cmdline_for_screenshot(const char **argv, int argc) RCT2_GLOBAL(RCT2_ADDRESS_RUN_INTRO_TICK_PART, uint8) = 0; RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) = SCREEN_FLAGS_PLAYING; + int mapSize = RCT2_GLOBAL(RCT2_ADDRESS_MAP_SIZE, uint16); + if (resolutionWidth == 0 || resolutionHeight == 0) { + resolutionWidth = (mapSize * 32 * 2) >> customZoom; + resolutionHeight = (mapSize * 32 * 1) >> customZoom; + + resolutionWidth += 8; + resolutionHeight += 128; + } + rct_viewport viewport; viewport.x = 0; viewport.y = 0; @@ -366,9 +387,9 @@ int cmdline_for_screenshot(const char **argv, int argc) if (customLocation) { if (centreMapX) - customX = (RCT2_GLOBAL(RCT2_ADDRESS_MAP_SIZE, uint8) / 2) * 32 + 16; + customX = (mapSize / 2) * 32 + 16; if (centreMapY) - customY = (RCT2_GLOBAL(RCT2_ADDRESS_MAP_SIZE, uint8) / 2) * 32 + 16; + customY = (mapSize / 2) * 32 + 16; int x, y; int z = map_element_height(customX, customY); @@ -391,8 +412,8 @@ int cmdline_for_screenshot(const char **argv, int argc) break; } - viewport.view_x = x - (viewport.view_width / 2); - viewport.view_y = y - (viewport.view_height / 2); + viewport.view_x = x - ((viewport.view_width << customZoom) / 2); + viewport.view_y = y - ((viewport.view_height << customZoom) / 2); viewport.zoom = customZoom; RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint8) = customRotation; @@ -404,6 +425,8 @@ int cmdline_for_screenshot(const char **argv, int argc) RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint8) = RCT2_GLOBAL(RCT2_ADDRESS_SAVED_VIEW_ZOOM_AND_ROTATION, uint16) >> 8; } + sub_69E9A7(); + rct_drawpixelinfo dpi; dpi.x = 0; dpi.y = 0; From 4bb4b197dd6d2ef380a07e54f9f62c6dcf3e0e6b Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Sat, 30 May 2015 13:06:36 +0100 Subject: [PATCH 31/32] make small change to screenshot command line --- src/interface/screenshot.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/interface/screenshot.c b/src/interface/screenshot.c index 2ded7156c1..632c6eaba9 100644 --- a/src/interface/screenshot.c +++ b/src/interface/screenshot.c @@ -417,8 +417,6 @@ int cmdline_for_screenshot(const char **argv, int argc) viewport.zoom = customZoom; RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint8) = customRotation; - - reset_all_sprite_quadrant_placements(); } else { viewport.view_x = RCT2_GLOBAL(RCT2_ADDRESS_SAVED_VIEW_X, sint16) - (viewport.view_width / 2); viewport.view_y = RCT2_GLOBAL(RCT2_ADDRESS_SAVED_VIEW_Y, sint16) - (viewport.view_height / 2); @@ -427,7 +425,8 @@ int cmdline_for_screenshot(const char **argv, int argc) RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint8) = RCT2_GLOBAL(RCT2_ADDRESS_SAVED_VIEW_ZOOM_AND_ROTATION, uint16) >> 8; } - sub_69E9A7(); + // Ensure sprites appear regardless of rotation + reset_all_sprite_quadrant_placements(); rct_drawpixelinfo dpi; dpi.x = 0; From b1e94bf110298dfa0f6087943ffa0892f1da0578 Mon Sep 17 00:00:00 2001 From: Michael Steenbeek Date: Sat, 30 May 2015 14:35:59 +0200 Subject: [PATCH 32/32] Consistently use colons after labels that are followed by a dropdown --- data/language/english_uk.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/data/language/english_uk.txt b/data/language/english_uk.txt index 396d783513..8b89d1d103 100644 --- a/data/language/english_uk.txt +++ b/data/language/english_uk.txt @@ -2702,7 +2702,7 @@ STR_2696 :Place trees STR_2697 :??? STR_2698 :??? STR_2699 :??? -STR_2700 :Autosave frequency +STR_2700 :Autosave frequency: STR_2701 :Every week STR_2702 :Every 2 weeks STR_2703 :Every month @@ -2740,7 +2740,7 @@ STR_2734 :{COMMA16}mph STR_2735 :{COMMA16}km/h STR_2736 :{MONTH}, Year {COMMA16} STR_2737 :{STRINGID} {MONTH}, Year {COMMA16} -STR_2738 :Title screen music +STR_2738 :Title screen music: STR_2739 :None STR_2740 :RollerCoaster Tycoon 1 STR_2741 :RollerCoaster Tycoon 2 @@ -2779,7 +2779,7 @@ STR_2772 :Faster Gamespeed STR_2773 :Windowed STR_2774 :Fullscreen STR_2775 :Fullscreen (desktop) -STR_2776 :Language +STR_2776 :Language: STR_2777 :{MOVE_X}{SMALLFONT}{STRING} STR_2778 :{RIGHTGUILLEMET}{MOVE_X}{SMALLFONT}{STRING} STR_2779 :Viewport #{COMMA16} @@ -3514,4 +3514,4 @@ STR_5177 :Fullscreen mode: STR_5178 :{SMALLFONT}{BLACK}Show financial cheats STR_5179 :{SMALLFONT}{BLACK}Show guest cheats STR_5180 :{SMALLFONT}{BLACK}Show park cheats -STR_5181 :{SMALLFONT}{BLACK}Show ride cheats \ No newline at end of file +STR_5181 :{SMALLFONT}{BLACK}Show ride cheats