Merge pull request #8 from IntelOrca/develop

Fast forward
This commit is contained in:
Michael Steenbeek 2015-04-14 18:51:48 +02:00
commit 2b0e3df6c1
82 changed files with 3521 additions and 1097 deletions

View File

@ -11,7 +11,7 @@ Includes all git commit authors. Aliases are GitHub user names.
## Implementation (RCT2)
* Ted John (IntelOrca)
* Duncan Frost (duncanspumpkin)
* Peter Hill (ZedFree) - String handling, misc.
* Peter Hill (ZedThree) - String handling, misc.
* (qcz) - Scenery window, misc.
* Matthias Lanzinger (lnz) - Climate, finance, scenario, ride reachability
* (zsilencer) - Audio, misc.
@ -19,6 +19,7 @@ Includes all git commit authors. Aliases are GitHub user names.
* (hexdec) - Misc.
* Dennis Devriendt (ddevrien) - Misc.
* Maciek Baron (MaciekBaron) - Misc.
* Michael Steenbeek (Gymnasiast) - Cheats and misc. features
* (AngeloG) - Scrollbar input, misc.
* (jcdavis) - Misc.
* (marcotc) - Rain drawing, misc.
@ -80,4 +81,4 @@ Representation by Jacqui Lyons at Mar jacq Ltd.
Thanks to: Peter James Adcock, Joe Booth, and John Wardley
Licensed to Infogrames Interactive Inc.
Licensed to Infogrames Interactive Inc.

View File

@ -1062,7 +1062,7 @@ STR_1060 :Ongeldige attractienaam
STR_1061 :Normale modus
STR_1062 :Voortdurend circuit
STR_1063 :Lancering via achterwaartse optakeling
STR_1064 :Lancering
STR_1064 :Lancering (station passeren)
STR_1065 :Shuttlemodus
STR_1066 :Bootverhuurmodus
STR_1067 :Opwaartse lancering
@ -1094,7 +1094,7 @@ STR_1092 :Neerwaartse lancering
STR_1093 :Crookedhousemodus
STR_1094 :Vrijevalmodus
STR_1095 :Voortdurend circuit met blokken
STR_1096 :Lancering
STR_1096 :Lancering (station niet passeren)
STR_1097 :Lancering met blokken
STR_1098 :Gaat naar het einde van {POP16}{STRINGID}
STR_1099 :Wacht op passagiers op {POP16}{STRINGID}
@ -3448,3 +3448,6 @@ STR_3446 :Werkgebied wissen
STR_5120 :'Financiën'-knop in de werkbalk tonen
STR_5121 :'Onderzoek'-knop in de werkbalk tonen
STR_5122 :Alle voertuigen met hetzelfde baan- of attractietype tonen
STR_5123 :Attr. vernieuwen
STR_5124 :Six Flags weg
STR_5125 :Afbreekbaar maken

View File

@ -1778,7 +1778,7 @@ STR_1773 :Only one on-ride photo section allowed per ride
STR_1774 :Only one cable lift hill allowed per ride
STR_1775 :Off
STR_1776 :On
STR_1777 :{WINDOW_COLOUR_2}Music:
STR_1777 :{WINDOW_COLOUR_2}Music
STR_1778 :{STRINGID} - -
STR_1779 :{INLINE_SPRITE}{254}{19}{00}{00} Panda costume
STR_1780 :{INLINE_SPRITE}{255}{19}{00}{00} Tigre costume
@ -2342,7 +2342,7 @@ STR_2337 :Deutschmark (DM)
STR_2338 :Yen ({YEN})
STR_2339 :Peseta (Pts)
STR_2340 :Lira (L)
STR_2341 :Guilders (Dfl.)
STR_2341 :Guilders (fl.)
STR_2342 :Krona (kr)
STR_2343 :Euros ({EURO})
STR_2344 :Imperial
@ -3458,3 +3458,4 @@ 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

View File

@ -1065,7 +1065,7 @@ STR_1060 :Invalid ride/attraction name
STR_1061 :Normal mode
STR_1062 :Continuous circuit mode
STR_1063 :Reverse-Incline launched shuttle mode
STR_1064 :Powered launch
STR_1064 :Powered launch (passing station)
STR_1065 :Shuttle mode
STR_1066 :Boat hire mode
STR_1067 :Upward launch
@ -1097,7 +1097,7 @@ STR_1092 :Downward launch
STR_1093 :Crooked house mode
STR_1094 :Freefall drop mode
STR_1095 :Continuous circuit block sectioned mode
STR_1096 :Powered launch
STR_1096 :Powered launch (without passing station)
STR_1097 :Powered launch block sectioned mode
STR_1098 :Moving to end of {POP16}{STRINGID}
STR_1099 :Waiting for passengers at {POP16}{STRINGID}
@ -3468,3 +3468,6 @@ STR_3446 :Cancel Patrol Area
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

View File

@ -3,97 +3,97 @@
# Use # at the beginning of a line to leave a comment.
STR_0000 :
STR_0001 :{STRINGID} {COMMA16}
STR_0002 :Ride
STR_0003 :Ride
STR_0002 :Attraction
STR_0003 :Attraction
STR_0004 :Suspended Swinging Coaster
STR_0005 :Ride
STR_0005 :Attraction
STR_0006 :Junior Roller Coaster
STR_0007 :Miniature Railway
STR_0008 :Monorail
STR_0009 :Mini Suspended Coaster
STR_0010 :Ride
STR_0011 :Ride
STR_0012 :Ride
STR_0010 :Attraction
STR_0011 :Attraction
STR_0012 :Attraction
STR_0013 :Car Ride
STR_0014 :Ride
STR_0015 :Ride
STR_0016 :Ride
STR_0014 :Attraction
STR_0015 :Attraction
STR_0016 :Attraction
STR_0017 :Looping Roller Coaster
STR_0018 :Ride
STR_0019 :Ride
STR_0018 :Attraction
STR_0019 :Attraction
STR_0020 :Chairlift
STR_0021 :Ride
STR_0022 :Ride
STR_0023 :Ride
STR_0024 :Ride
STR_0025 :Ride
STR_0026 :Ride
STR_0027 :Ride
STR_0028 :Ride
STR_0029 :Ride
STR_0021 :Attraction
STR_0022 :Attraction
STR_0023 :Attraction
STR_0024 :Attraction
STR_0025 :Attraction
STR_0026 :Attraction
STR_0027 :Attraction
STR_0028 :Attraction
STR_0029 :Attraction
STR_0030 :Stall
STR_0031 :Stall
STR_0032 :Stall
STR_0033 :Stall
STR_0034 :Stall
STR_0035 :Ride
STR_0035 :Attraction
STR_0036 :Stall
STR_0037 :Kiosk
STR_0038 :Restroom
STR_0039 :Ride
STR_0040 :Ride
STR_0041 :Ride
STR_0042 :Ride
STR_0043 :Ride
STR_0038 :Toilettes
STR_0039 :Attraction
STR_0040 :Attraction
STR_0041 :Attraction
STR_0042 :Attraction
STR_0043 :Attraction
STR_0044 :Reverse Freefall Coaster
STR_0045 :Lift
STR_0046 :Ride
STR_0047 :Ride
STR_0048 :Ride
STR_0049 :Ride
STR_0050 :Ride
STR_0051 :Ride
STR_0052 :Ride
STR_0046 :Attraction
STR_0047 :Attraction
STR_0048 :Attraction
STR_0049 :Attraction
STR_0050 :Attraction
STR_0051 :Attraction
STR_0052 :Attraction
STR_0053 :Hyper-Twister Roller Coaster
STR_0054 :Wooden Roller Coaster
STR_0055 :Side-Friction Roller Coaster
STR_0056 :Wild Mouse
STR_0057 :Multi-Dimension Roller Coaster
STR_0058 :Ride
STR_0058 :Attraction
STR_0059 :Aerial Inverted Roller Coaster
STR_0060 :Ride
STR_0061 :Ride
STR_0062 :Ride
STR_0063 :Ride
STR_0064 :Ride
STR_0060 :Attraction
STR_0061 :Attraction
STR_0062 :Attraction
STR_0063 :Attraction
STR_0064 :Attraction
STR_0065 :Suspended Monorail
STR_0066 :Ride
STR_0067 :Ride
STR_0066 :Attraction
STR_0067 :Attraction
STR_0068 :Heartline Twister Coaster
STR_0069 :Ride
STR_0070 :Ride
STR_0071 :Ride
STR_0072 :Ride
STR_0073 :Ride
STR_0074 :Ride
STR_0075 :Ride
STR_0069 :Attraction
STR_0070 :Attraction
STR_0071 :Attraction
STR_0072 :Attraction
STR_0073 :Attraction
STR_0074 :Attraction
STR_0075 :Attraction
STR_0076 :Water Coaster
STR_0077 :Ride
STR_0078 :Ride
STR_0079 :Ride
STR_0080 :Ride
STR_0081 :Ride
STR_0082 :Ride
STR_0083 :Ride
STR_0084 :Ride
STR_0085 :Ride
STR_0086 :Ride
STR_0087 :Ride
STR_0088 :Ride
STR_0077 :Attraction
STR_0078 :Attraction
STR_0079 :Attraction
STR_0080 :Attraction
STR_0081 :Attraction
STR_0082 :Attraction
STR_0083 :Attraction
STR_0084 :Attraction
STR_0085 :Attraction
STR_0086 :Attraction
STR_0087 :Attraction
STR_0088 :Attraction
STR_0089 :Mini Roller Coaster
STR_0090 :Ride
STR_0091 :Ride
STR_0092 :Ride
STR_0090 :Attraction
STR_0091 :Attraction
STR_0092 :Attraction
STR_0093 :
STR_0094 :
STR_0095 :
@ -973,7 +973,7 @@ STR_0968 :+360{DEGREE}
STR_0969 :+405{DEGREE}
STR_0970 :+450{DEGREE}
STR_0971 :+495{DEGREE}
STR_0972 :Cancel
STR_0972 :Annuler
STR_0973 :OK
STR_0974 :Rides
STR_0975 :Shops and Stalls
@ -1065,7 +1065,7 @@ STR_1060 :Invalid ride/attraction name
STR_1061 :Normal mode
STR_1062 :Continuous circuit mode
STR_1063 :Reverse-Incline launched shuttle mode
STR_1064 :Powered launch
STR_1064 :Lancement (avec passage de la station)
STR_1065 :Shuttle mode
STR_1066 :Boat hire mode
STR_1067 :Upward launch
@ -1097,7 +1097,7 @@ STR_1092 :Downward launch
STR_1093 :Crooked house mode
STR_1094 :Freefall drop mode
STR_1095 :Continuous circuit block sectioned mode
STR_1096 :Powered launch
STR_1096 :Lancement (sans passage de la station)
STR_1097 :Powered launch block sectioned mode
STR_1098 :Moving to end of {POP16}{STRINGID}
STR_1099 :Waiting for passengers at {POP16}{STRINGID}
@ -1272,13 +1272,13 @@ STR_1267 :Cars
STR_1268 :{COMMA16} car
STR_1269 :{COMMA16} cars
STR_1270 :Car {COMMA16}
STR_1271 :building
STR_1272 :buildings
STR_1273 :Building
STR_1274 :Buildings
STR_1275 :{COMMA16} building
STR_1276 :{COMMA16} buildings
STR_1277 :Building {COMMA16}
STR_1271 :bâtiment
STR_1272 :bâtiments
STR_1273 :Bâtiment
STR_1274 :Bâtiment
STR_1275 :{COMMA16} bâtiment
STR_1276 :{COMMA16} bâtiments
STR_1277 :Bâtiment {COMMA16}
STR_1278 :structure
STR_1279 :structures
STR_1280 :Structure
@ -1431,7 +1431,7 @@ STR_1426 :Queue Line
STR_1427 :{WINDOW_COLOUR_2}Clients: {BLACK}{COMMA32} par heure
STR_1428 :{WINDOW_COLOUR_2}Admission price:
STR_1429 :{POP16}{POP16}{POP16}{CURRENCY2DP}
STR_1430 :Free
STR_1430 :Gratuit
STR_1431 :Marche
STR_1432 :Heading for {STRINGID}
STR_1433 :Queuing for {STRINGID}
@ -1453,7 +1453,7 @@ STR_1448 :Watching new ride being constructed
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 :Guest's name
STR_1452 :Nom du visiteur
STR_1453 :Enter name for this guest:
STR_1454 :Can't name guest...
STR_1455 :Invalid name for guest
@ -1464,7 +1464,7 @@ STR_1459 :Track style
STR_1460 :{SMALLFONT}{BLACK}'U' shaped open track
STR_1461 :{SMALLFONT}{BLACK}'O' shaped enclosed track
STR_1462 :Too steep for lift hill
STR_1463 :Guests
STR_1463 :Visiteurs
STR_1464 :Helix up (small)
STR_1465 :Helix up (large)
STR_1466 :Helix down (small)
@ -1472,7 +1472,7 @@ STR_1467 :Helix down (large)
STR_1468 :Staff
STR_1469 :Ride must start and end with stations
STR_1470 :Station not long enough
STR_1471 :{WINDOW_COLOUR_2}Speed:
STR_1471 :{WINDOW_COLOUR_2}Vitesse:
STR_1472 :{SMALLFONT}{BLACK}Speed of this ride
STR_1473 :{WINDOW_COLOUR_2}Excitement rating: {BLACK}{COMMA2DP32} ({STRINGID})
STR_1474 :{WINDOW_COLOUR_2}Excitement rating: {BLACK}Not yet available
@ -1673,7 +1673,7 @@ STR_1668 :{WINDOW_COLOUR_2}Satisfaction: {BLACK}Unknown
STR_1669 :{WINDOW_COLOUR_2}Satisfaction: {BLACK}{COMMA16}%
STR_1670 :{WINDOW_COLOUR_2}Total customers: {BLACK}{COMMA32}
STR_1671 :{WINDOW_COLOUR_2}Total profit: {BLACK}{CURRENCY2DP}
STR_1672 :Brakes
STR_1672 :Freins
STR_1673 :Spinning Control Toggle Track
STR_1674 :Brake speed
STR_1675 :{POP16}{VELOCITY}
@ -1694,7 +1694,7 @@ STR_1689 :Block brakes
STR_1690 :{WINDOW_COLOUR_2}{STRINGID}{NEWLINE}{BLACK}{STRINGID}
STR_1691 :{WINDOW_COLOUR_2} Cost: {BLACK}{CURRENCY}
STR_1692 :{WINDOW_COLOUR_2} Cost: {BLACK}from {CURRENCY}
STR_1693 :{SMALLFONT}{BLACK}Guests
STR_1693 :{SMALLFONT}{BLACK}Visiteurs
STR_1694 :{SMALLFONT}{BLACK}Staff
STR_1695 :{SMALLFONT}{BLACK}Income and costs
STR_1696 :{SMALLFONT}{BLACK}Customer information
@ -1711,7 +1711,7 @@ STR_1706 :{SMALLFONT}{BLACK}Move this person to a new location
STR_1707 :Too many staff in game
STR_1708 :{SMALLFONT}{BLACK}Set patrol area for this staff member
STR_1709 :Sack staff
STR_1710 :Yes
STR_1710 :Oui
STR_1711 :{WINDOW_COLOUR_1}Are you sure you want to sack {STRINGID}?
STR_1712 :{INLINE_SPRITE}{247}{19}{00}{00}{WINDOW_COLOUR_2}Sweep footpaths
STR_1713 :{INLINE_SPRITE}{248}{19}{00}{00}{WINDOW_COLOUR_2}Water gardens
@ -2334,7 +2334,7 @@ STR_2329 :{WINDOW_COLOUR_2}Distance and Speed:
STR_2330 :{WINDOW_COLOUR_2}Temperature:
STR_2331 :{WINDOW_COLOUR_2}Height Labels:
STR_2332 :Units
STR_2333 :Sound
STR_2333 :Son
STR_2334 :Pounds ({POUND})
STR_2335 :Dollars ($)
STR_2336 :Franc (F)
@ -2342,7 +2342,7 @@ STR_2337 :Deutschmark (DM)
STR_2338 :Yen ({YEN})
STR_2339 :Peseta (Pts)
STR_2340 :Lira (L)
STR_2341 :Guilders (Dfl.)
STR_2341 :Florins (fl.)
STR_2342 :Krona (kr)
STR_2343 :Euros ({EURO})
STR_2344 :Imperial
@ -2386,7 +2386,7 @@ STR_2381 :{SMALLFONT}{BLACK}Adjust larger area of water
STR_2382 :Land
STR_2383 :Water
STR_2384 :{WINDOW_COLOUR_2}Votre objectif:
STR_2385 :{BLACK}None
STR_2385 :{BLACK}Aucun
STR_2386 :{BLACK}To have at least {COMMA16} guests in your park at the end of {MONTHYEAR}, with a park rating of at least 600
STR_2387 :{BLACK}To achieve a park value of at least {POP16}{POP16}{CURRENCY} at the end of {PUSH16}{PUSH16}{PUSH16}{MONTHYEAR}
STR_2388 :{BLACK}Have Fun!
@ -2398,7 +2398,7 @@ STR_2393 :{BLACK}To have 10 different types of roller coasters operating in y
STR_2394 :{BLACK}To finish building all 5 of the partially built roller coasters in this park, designing them to achieve excitement ratings of at least {POP16}{POP16}{COMMA2DP32} each
STR_2395 :{BLACK}To repay your loan and achieve a park value of at least {POP16}{POP16}{CURRENCY}
STR_2396 :{BLACK}To achieve a monthly profit from food, drink and merchandise sales of at least {POP16}{POP16}{CURRENCY}
STR_2397 :None
STR_2397 :Aucun
STR_2398 :Number of guests at a given date
STR_2399 :Park value at a given date
STR_2400 :Have fun
@ -2412,7 +2412,7 @@ STR_2407 :Repay loan and achieve a given park value
STR_2408 :Monthly profit from food/merchandise
STR_2409 :{WINDOW_COLOUR_2}Campagnes marketing en cours
STR_2410 :{BLACK}Aucune
STR_2411 :{WINDOW_COLOUR_2}Campagnes marrketing disponibles
STR_2411 :{WINDOW_COLOUR_2}Campagnes marketing disponibles
STR_2412 :{SMALLFONT}{BLACK}Commencer campagne marketing
STR_2413 :{BLACK}({CURRENCY2DP} per week)
STR_2414 :(Not Selected)
@ -2737,8 +2737,8 @@ STR_2732 :???
STR_2733 :???
STR_2734 :???
STR_2735 :???
STR_2736 :???
STR_2737 :???
STR_2736 :{MONTH}, an {COMMA16}
STR_2737 :{STRINGID} {MONTH}, an {COMMA16}
STR_2738 :???
STR_2739 :???
STR_2740 :???
@ -2778,7 +2778,7 @@ STR_2772 :Faster Gamespeed
STR_2773 :Windowed
STR_2774 :Fullscreen
STR_2775 :Fullscreen (desktop)
STR_2776 :Language
STR_2776 :Langue
STR_2777 :{MOVE_X}{SMALLFONT}{STRING}
STR_2778 :{RIGHTGUILLEMET}{MOVE_X}{SMALLFONT}{STRING}
# End of new strings
@ -3058,7 +3058,7 @@ STR_3051 :Golf hole C
STR_3052 :Golf hole D
STR_3053 :Golf hole E
STR_3054 :Loading...
STR_3055 :White
STR_3055 :Blanc
STR_3056 :Translucent
STR_3057 :{WINDOW_COLOUR_2}Construction Marker:
STR_3058 :Brick walls
@ -3133,8 +3133,8 @@ STR_3126 :{WINDOW_COLOUR_2}Intensity Factor: {BLACK}+{COMMA16}%
STR_3127 :{WINDOW_COLOUR_2}Nausea Factor: {BLACK}+{COMMA16}%
STR_3128 :Save Track Design
STR_3129 :Save Track Design with Scenery
STR_3130 :Save
STR_3131 :Cancel
STR_3130 :Sauvegarder
STR_3131 :Annuler
STR_3132 :{BLACK}Click items of scenery to select them to be saved with track design...
STR_3133 :Unable to build this on a slope
STR_3134 :{RED}(Design includes scenery which is unavailable)
@ -3316,7 +3316,7 @@ STR_3309 :{WINDOW_COLOUR_2}{COMMA16}
STR_3310 :{WINDOW_COLOUR_2}{LENGTH}
STR_3311 :{WINDOW_COLOUR_2}{COMMA2DP32}
STR_3312 :{WINDOW_COLOUR_2}Rides/attractions under a preservation order:
STR_3313 :Scenario Name
STR_3313 :Nom du scénario:
STR_3314 :Enter name for scenario:
STR_3315 :Park/Scenario Details
STR_3316 :Décrire ce scénario:

View File

@ -2738,8 +2738,8 @@ STR_2732 :???
STR_2733 :???
STR_2734 :???
STR_2735 :???
STR_2736 :???
STR_2737 :???
STR_2736 :{MONTH}, Jahr {COMMA16}
STR_2737 :{STRINGID} {MONTH}, Jahr {COMMA16}
STR_2738 :???
STR_2739 :???
STR_2740 :???
@ -2769,7 +2769,7 @@ STR_2762 :Bezahlen für Bahnen
STR_2763 :???
STR_2764 :Glückliche Gäste
STR_2765 :Große Menschenmenge
STR_2766 :???
STR_2766 :Szenario gewinnen
STR_2767 :Wetter stoppen
STR_2768 :Wetter fortsetzen
STR_2769 :Park öffnen
@ -2782,9 +2782,9 @@ STR_2775 :Vollbild (Desktop)
STR_2776 :Sprache
STR_2777 :{MOVE_X}{SMALLFONT}{STRING}
STR_2778 :{RIGHTGUILLEMET}{MOVE_X}{SMALLFONT}{STRING}
# End of new strings
STR_2779 :???
STR_2780 :???
# End of new strings
STR_2781 :{STRINGID}:{MOVE_X}{195}{STRINGID}{STRINGID}
STR_2782 :UMSCHALT +
STR_2783 :STRG +

View File

@ -2737,8 +2737,8 @@ STR_2732 :???
STR_2733 :???
STR_2734 :???
STR_2735 :???
STR_2736 :???
STR_2737 :???
STR_2736 :{MONTH}, anno {COMMA16}
STR_2737 :{STRINGID} {MONTH}, anno {COMMA16}
STR_2738 :???
STR_2739 :???
STR_2740 :???

View File

@ -62,6 +62,7 @@
<ClCompile Include="..\src\platform\unix.c" />
<ClCompile Include="..\src\platform\osx.c" />
<ClCompile Include="..\src\platform\windows.c" />
<ClCompile Include="..\src\rct1.c" />
<ClCompile Include="..\src\rct2.c" />
<ClCompile Include="..\src\ride\ride.c" />
<ClCompile Include="..\src\ride\ride_data.c" />
@ -93,6 +94,7 @@
<ClCompile Include="..\src\windows\footpath.c" />
<ClCompile Include="..\src\windows\game_bottom_toolbar.c" />
<ClCompile Include="..\src\windows\guest_list.c" />
<ClCompile Include="..\src\windows\install_track.c" />
<ClCompile Include="..\src\windows\land.c" />
<ClCompile Include="..\src\windows\loadsave.c" />
<ClCompile Include="..\src\windows\main.c" />
@ -198,7 +200,6 @@
<ClInclude Include="..\src\util\util.h" />
<ClInclude Include="..\src\windows\dropdown.h" />
<ClInclude Include="..\src\windows\error.h" />
<ClInclude Include="..\src\windows\scenery.h" />
<ClInclude Include="..\src\windows\tooltip.h" />
<ClInclude Include="..\src\world\banner.h" />
<ClInclude Include="..\src\world\climate.h" />

View File

@ -357,14 +357,12 @@
<ClCompile Include="..\src\windows\ride_construction.c">
<Filter>Source\Windows</Filter>
</ClCompile>
<ClCompile Include="..\lib\lodepng\lodepng.c" />
<ClCompile Include="..\src\interface\keyboard_shortcut.c">
<Filter>Source\Interface</Filter>
</ClCompile>
<ClCompile Include="..\src\interface\viewport_interaction.c">
<Filter>Source\Interface</Filter>
</ClCompile>
<ClCompile Include="..\lib\lodepng\lodepng.c" />
<ClCompile Include="..\src\world\footpath.c">
<Filter>Source\World</Filter>
</ClCompile>
@ -386,7 +384,7 @@
<ClCompile Include="..\src\localisation\user.c">
<Filter>Source\Localisation</Filter>
</ClCompile>
<ClCompile Include="..\lib\libspeex\resample.c;..\lib\lodepng\lodepng.c" />
<ClCompile Include="..\lib\lodepng\lodepng.c" />
<ClCompile Include="..\src\windows\editor_inventions_list.c">
<Filter>Source\Windows</Filter>
</ClCompile>
@ -430,6 +428,12 @@
<ClCompile Include="..\src\world\scenery.c">
<Filter>Source\World</Filter>
</ClCompile>
<ClCompile Include="..\src\rct1.c">
<Filter>Source</Filter>
</ClCompile>
<ClCompile Include="..\src\windows\install_track.c">
<Filter>Source\Windows</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\src\management\award.h">
@ -486,9 +490,6 @@
<ClInclude Include="..\src\windows\error.h">
<Filter>Source\Windows</Filter>
</ClInclude>
<ClInclude Include="..\src\windows\scenery.h">
<Filter>Source\Windows</Filter>
</ClInclude>
<ClInclude Include="..\src\windows\tooltip.h">
<Filter>Source\Windows</Filter>
</ClInclude>

View File

@ -21,7 +21,9 @@
#ifndef _ADDRESSES_H_
#define _ADDRESSES_H_
#ifdef _MSC_VER
#pragma warning(disable : 4731)
#endif
#define RCT2_ADDRESS(address, type) ((type*)(address))
#define RCT2_GLOBAL(address, type) (*((type*)(address)))

View File

@ -357,13 +357,13 @@ static void config_save_property_value(FILE *file, uint8 type, value_union *valu
else fwrite("false", 5, 1, file);
break;
case CONFIG_VALUE_TYPE_UINT8:
fprintf(file, "%d", value->value_uint8);
fprintf(file, "%u", value->value_uint8);
break;
case CONFIG_VALUE_TYPE_UINT16:
fprintf(file, "%d", value->value_uint16);
fprintf(file, "%u", value->value_uint16);
break;
case CONFIG_VALUE_TYPE_UINT32:
fprintf(file, "%d", value->value_uint32);
fprintf(file, "%u", value->value_uint32);
break;
case CONFIG_VALUE_TYPE_SINT8:
fprintf(file, "%d", value->value_sint8);

View File

@ -593,7 +593,7 @@ void gfx_draw_sprite_palette_set(rct_drawpixelinfo *dpi, int image_id, int x, in
ecx >>= 3;//SAR
int eax = ((int)no_pixels)<<8;
ecx = -ecx;//Odd
eax = eax & 0xFF00 + *(source_pointer+1);
eax = (eax & 0xFF00) + *(source_pointer+1);
total_no_pixels -= ecx;
source_pointer += 2;
ebx = (uint32)new_source_pointer - eax;

View File

@ -1044,7 +1044,7 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in
uint32 char_offset = al - 0x20 + *current_font_sprite_base;
RCT2_GLOBAL(0x00EDF81C, uint32) = (IMAGE_TYPE_USE_PALETTE << 28);
gfx_draw_sprite_palette_set(dpi, (IMAGE_TYPE_USE_PALETTE << 28) | char_offset + SPR_CHAR_START, max_x, max_y, palette_pointer, NULL);
gfx_draw_sprite_palette_set(dpi, ((IMAGE_TYPE_USE_PALETTE << 28) | char_offset) + SPR_CHAR_START, max_x, max_y, palette_pointer, NULL);
max_x += (RCT2_ADDRESS(RCT2_ADDRESS_FONT_CHAR_WIDTH, uint8)[char_offset] & 0xFF);
continue;
}

View File

@ -41,14 +41,13 @@
#include "world/climate.h"
#include "world/map.h"
#include "world/park.h"
#include "world/scenery.h"
#include "world/sprite.h"
static void set_all_land_owned();
static int editor_load_landscape_from_sv4(const char *path);
static int editor_load_landscape_from_sc4(const char *path);
static int editor_read_sc4(char *src, int length);
static int editor_read_sv4(char *src, int length);
static int editor_read_s4(rct1_s4 *data);
static void editor_finalise_main_view();
static int editor_read_s6(const char *path);
/**
@ -125,8 +124,6 @@ void editor_convert_save_to_scenario()
{
rct_s6_info *s6Info = (rct_s6_info*)0x0141F570;
char savedGamePath[MAX_PATH];
rct_window *w;
rct_viewport *viewport;
tool_cancel();
if (!show_convert_saved_game_to_scenario_dialog(savedGamePath))
@ -155,7 +152,6 @@ void editor_convert_save_to_scenario()
rct_stex_entry* stex = g_stexEntries[0];
if ((int)stex != 0xFFFFFFFF) {
object_unload(0, &object_entry_groups[OBJECT_TYPE_SCENARIO_TEXT].entries[0]);
//RCT2_CALLPROC_EBPSAFE(0x006A9FC0);
reset_loaded_objects();
format_string(s6Info->details, STR_NO_DETAILS_YET, NULL);
@ -168,39 +164,7 @@ void editor_convert_save_to_scenario()
viewport_init_all();
news_item_init_queue();
window_editor_main_open();
// Initialise main view
w = window_get_main();
viewport = w->viewport;
w->viewport_target_sprite = -1;
w->saved_view_x = RCT2_GLOBAL(RCT2_ADDRESS_SAVED_VIEW_X, sint16);
w->saved_view_y = RCT2_GLOBAL(RCT2_ADDRESS_SAVED_VIEW_Y, sint16);
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;
int cx = RCT2_GLOBAL(RCT2_ADDRESS_SAVED_VIEW_ZOOM_AND_ROTATION, sint16) - viewport->zoom;
if (cx != 0) {
if (cx >= 0) {
viewport->view_width <<= cx;
viewport->view_height <<= cx;
} else {
cx = -cx;
viewport->view_width >>= cx;
viewport->view_height >>= cx;
}
}
w->saved_view_x -= viewport->view_width >> 1;
w->saved_view_y -= viewport->view_height >> 1;
window_invalidate(w);
sub_69E9A7();
RCT2_CALLPROC_EBPSAFE(0x006DFEE4);
window_new_ride_init_vars();
RCT2_GLOBAL(0x009DEB7C, uint16) = 0;
load_palette();
gfx_invalidate_screen();
editor_finalise_main_view();
RCT2_GLOBAL(0x009DEA66, uint16) = 0;
}
@ -290,17 +254,17 @@ static void set_all_land_owned()
}
/**
*
* rct2: 0x006BD3A4
*/
void sub_6BD3A4() {
for (short i = 0; i < 200; i++) {
*
* rct2: 0x006BD3A4
*/
void sub_6BD3A4()
{
for (int i = 0; i < 200; i++)
RCT2_ADDRESS(RCT2_ADDRESS_STAFF_MODE_ARRAY, uint8)[i] = STAFF_MODE_NONE;
}
for (short i = 200; i < 204; i++) {
for (int i = 200; i < 204; i++)
RCT2_ADDRESS(RCT2_ADDRESS_STAFF_MODE_ARRAY, uint8)[i] = STAFF_MODE_WALK;
}
//RCT2_CALLPROC_EBPSAFE(0x006C0C3F);
sub_6C0C3F();
}
@ -327,415 +291,43 @@ void editor_load_landscape(const char *path)
editor_read_s6(path);
}
/**
*
* rct2: 0x00666DFD
*/
static void sub_666DFD()
{
int x, y;
rct_map_element *mapElement;
x = RCT2_GLOBAL(0x013573EA, uint16);
y = RCT2_GLOBAL(0x013573EC, uint16);
if (x == 0x8000)
return;
x /= 32;
y /= 32;
mapElement = map_get_first_element_at(x, y);
do {
if (map_element_get_type(mapElement) == MAP_ELEMENT_TYPE_ENTRANCE) {
if (mapElement->properties.entrance.type == ENTRANCE_TYPE_PARK_ENTRANCE) {
mapElement->properties.entrance.path_type = 0;
break;
}
}
} while (!map_element_is_last_for_tile(mapElement++));
}
/**
*
* rct2: 0x0069F06A
*/
static void sub_69F06A()
{
RCT2_CALLPROC_EBPSAFE(0x0069F06A); return;
// TODO, bug with the following code
RCT2_GLOBAL(0x013CE770, uint32) |= (1 << 0) | (1 << 1) | (1 << 14) | (1 << 2) | (1 << 3);
if (!(RCT2_GLOBAL(0x013CE770, uint32) & (1 << 4))) {
RCT2_GLOBAL(0x013CE770, uint32) |= (1 << 4);
banner_init(); // 6B9CB0
}
if (!(RCT2_GLOBAL(0x013CE770, uint32) & (1 << 6))) {
RCT2_GLOBAL(0x013CE770, uint32) |= (1 << 6);
RCT2_CALLPROC_EBPSAFE(0x0069E891);
}
RCT2_GLOBAL(0x013CE770, uint32) |= (1 << 7);
if (!(RCT2_GLOBAL(0x013CE770, uint32) & (1 << 8))) {
RCT2_GLOBAL(0x013CE770, uint32) |= (1 << 8);
sub_666DFD();
}
if (!(RCT2_GLOBAL(0x013CE770, uint32) & (1 << 9))) {
RCT2_GLOBAL(0x013CE770, uint32) |= (1 << 9);
RCT2_CALLPROC_EBPSAFE(0x0069E89B);
}
if (!(RCT2_GLOBAL(0x013CE770, uint32) & (1 << 13))) {
RCT2_GLOBAL(0x013CE770, uint32) |= (1 << 13);
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SIZE_UNITS, uint16) = 127 * 32;
RCT2_GLOBAL(RCT2_ADDRESS_MAP_MAXIMUM_X_Y, uint16) = 4350;
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SIZE_UNITS, uint16) = 128;
RCT2_GLOBAL(0x01358836, uint16) = 4095;
}
if (!(RCT2_GLOBAL(0x013CE770, uint32) & (1 << 15))) {
RCT2_GLOBAL(0x013CE770, uint32) |= (1 << 15);
RCT2_GLOBAL(0x01358838, uint32) = 0;
}
RCT2_GLOBAL(0x013CE770, uint32) |= (1 << 16) | (1 << 18) | (1 << 19);
}
/**
*
* rct2: 0x006A2B62
*/
static void sub_6A2B62()
{
int i;
rct_sprite *sprite;
rct_ride *ride;
map_element_iterator it;
RCT2_CALLPROC_EBPSAFE(0x0069F007);
// Free sprite user strings
for (i = 0; i < MAX_SPRITES; i++) {
sprite = &g_sprite_list[i];
if (sprite->unknown.sprite_identifier != 255)
user_string_free(sprite->unknown.name_string_idx);
}
reset_sprite_list();
// Free ride user strings
FOR_ALL_RIDES(i, ride)
user_string_free(ride->name);
ride_init_all();
RCT2_GLOBAL(RCT2_ADDRESS_GUESTS_IN_PARK, uint16) = 0;
RCT2_GLOBAL(RCT2_ADDRESS_GUESTS_HEADING_FOR_PARK, uint16) = 0;
RCT2_GLOBAL(0x01357BC8, uint16) = 0;
RCT2_GLOBAL(0x013573FE, uint8) = 0;
RCT2_CALLPROC_EBPSAFE(0x0069F44B);
sub_69F06A();
RCT2_CALLPROC_EBPSAFE(0x0069F143);
RCT2_CALLPROC_EBPSAFE(0x0069F2D0);
RCT2_CALLPROC_EBPSAFE(0x0069F3AB);
// Fix paths and remove all ride track / entrance / exit
map_element_iterator_begin(&it);
do {
switch (map_element_get_type(it.element)) {
case MAP_ELEMENT_TYPE_PATH:
if (it.element->type & 1) {
it.element->properties.path.type &= 0xF7;
it.element->properties.path.addition_status = 255;
}
break;
case MAP_ELEMENT_TYPE_TRACK:
RCT2_CALLPROC_EBPSAFE(0x006A7594);
sub_6A6AA7(it.x * 32, it.y * 32, it.element);
map_element_remove(it.element);
map_element_iterator_restart_for_tile(&it);
break;
case MAP_ELEMENT_TYPE_ENTRANCE:
if (it.element->properties.entrance.type != ENTRANCE_TYPE_PARK_ENTRANCE) {
RCT2_CALLPROC_EBPSAFE(0x006A7594);
sub_6A6AA7(it.x * 32, it.y * 32, it.element);
map_element_remove(it.element);
map_element_iterator_restart_for_tile(&it);
}
break;
}
} while (map_element_iterator_next(&it));
object_unload_all();
RCT2_CALLPROC_EBPSAFE(0x0069F53D);
reset_loaded_objects();
RCT2_CALLPROC_EBPSAFE(0x006A2730);
RCT2_CALLPROC_EBPSAFE(0x006A2956);
RCT2_CALLPROC_EBPSAFE(0x006A29B9);
RCT2_CALLPROC_EBPSAFE(0x006A2A68);
RCT2_CALLPROC_EBPSAFE(0x0069F509);
RCT2_CALLPROC_EBPSAFE(0x00685675);
RCT2_CALLPROC_EBPSAFE(0x0068585B);
climate_reset(RCT2_GLOBAL(RCT2_ADDRESS_CLIMATE, uint8));
RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) = SCREEN_FLAGS_SCENARIO_EDITOR;
viewport_init_all();
news_item_init_queue();
window_editor_main_open();
rct_s6_header *s6Header = (rct_s6_header*)0x009E34E4;
rct_s6_info *s6Info = (rct_s6_info*)0x0141F570;
s6Info->var_000 = 1;
s6Info->category = 4;
format_string(s6Info->details, STR_NO_DETAILS_YET, NULL);
s6Info->name[0] = 0;
if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint8) & PARK_FLAGS_NO_MONEY) {
RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint8) |= PARK_FLAGS_NO_MONEY_SCENARIO;
} else {
RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint8) &= PARK_FLAGS_NO_MONEY_SCENARIO;
}
if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_ENTRANCE_FEE, money16) == MONEY_FREE) {
RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint8) |= PARK_FLAGS_PARK_FREE_ENTRY;
} else {
RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint8) &= ~PARK_FLAGS_PARK_FREE_ENTRY;
}
RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint8) &= ~PARK_FLAGS_18;
RCT2_GLOBAL(RCT2_ADDRESS_GUEST_INITIAL_CASH, money16) = clamp(
MONEY(10,00),
RCT2_GLOBAL(RCT2_ADDRESS_GUEST_INITIAL_CASH, money16),
MONEY(100,00)
);
RCT2_GLOBAL(RCT2_ADDRESS_INITIAL_CASH, money32) = min(
MONEY(10000,00),
RCT2_GLOBAL(RCT2_ADDRESS_INITIAL_CASH, money32)
);
RCT2_CALLPROC_EBPSAFE(0x0069E89B);
sub_69E869();//RCT2_CALLPROC_EBPSAFE(0x0069E869);
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_LOAN, money32) = clamp(
MONEY(0,00),
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_LOAN, money32),
MONEY(5000000,00)
);
RCT2_GLOBAL(RCT2_ADDRESS_MAXIMUM_LOAN, money32) = clamp(
MONEY(0,00),
RCT2_GLOBAL(RCT2_ADDRESS_MAXIMUM_LOAN, money32),
MONEY(5000000,00)
);
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_INTEREST_RATE, uint8) = clamp(
5,
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_INTEREST_RATE, uint8),
80
);
if (
RCT2_GLOBAL(RCT2_ADDRESS_OBJECTIVE_TYPE, uint8) == OBJECTIVE_NONE ||
RCT2_GLOBAL(RCT2_ADDRESS_OBJECTIVE_TYPE, uint8) == OBJECTIVE_HAVE_FUN ||
RCT2_GLOBAL(RCT2_ADDRESS_OBJECTIVE_TYPE, uint8) == OBJECTIVE_BUILD_THE_BEST
) {
RCT2_GLOBAL(RCT2_ADDRESS_OBJECTIVE_TYPE, uint8) = OBJECTIVE_GUESTS_BY;
RCT2_GLOBAL(RCT2_ADDRESS_OBJECTIVE_YEAR, uint8) = 4;
RCT2_GLOBAL(RCT2_ADDRESS_OBJECTIVE_NUM_GUESTS, uint16) = 1000;
}
RCT2_GLOBAL(0x01358774, uint16) = 0;
// Initialise main view
rct_window *w = window_get_main();
rct_viewport *viewport = w->viewport;
w->viewport_target_sprite = -1;
w->saved_view_x = RCT2_GLOBAL(RCT2_ADDRESS_SAVED_VIEW_X, sint16);
w->saved_view_y = RCT2_GLOBAL(RCT2_ADDRESS_SAVED_VIEW_Y, sint16);
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;
int cx = RCT2_GLOBAL(RCT2_ADDRESS_SAVED_VIEW_ZOOM_AND_ROTATION, sint16) - viewport->zoom;
if (cx != 0) {
if (cx >= 0) {
viewport->view_width <<= cx;
viewport->view_height <<= cx;
} else {
cx = -cx;
viewport->view_width >>= cx;
viewport->view_height >>= cx;
}
}
w->saved_view_x -= viewport->view_width >> 1;
w->saved_view_y -= viewport->view_height >> 1;
window_invalidate(w);
sub_69E9A7();
RCT2_CALLPROC_EBPSAFE(0x006DFEE4);
window_new_ride_init_vars();
RCT2_GLOBAL(0x009DEB7C, uint16) = 0;
load_palette();
gfx_invalidate_screen();
RCT2_GLOBAL(0x009DEA66, uint16) = 0;
}
/**
*
* rct2: 0x006A2B02
*/
static int editor_load_landscape_from_sv4(const char *path)
{
FILE *fp;
long fpLength;
char *fpBuffer;
rct1_s4 *s4;
// Open file
fp = fopen(path, "rb");
if (fp == NULL) {
RCT2_GLOBAL(RCT2_ADDRESS_ERROR_TYPE, uint8) = 255;
RCT2_GLOBAL(RCT2_ADDRESS_ERROR_STRING_ID, uint16) = 3011;
s4 = malloc(sizeof(rct1_s4));
if (!rct1_read_sv4(path, s4)) {
free(s4);
return 0;
}
rct1_import_s4(s4);
free(s4);
// Read whole file into a buffer
fpLength = fsize(fp);
fpBuffer = malloc(fpLength);
fread(fpBuffer, fpLength, 1, fp);
fclose(fp);
editor_read_sv4(fpBuffer, fpLength);
free(fpBuffer);
sub_6A2B62();
rct1_fix_landscape();
editor_finalise_main_view();
RCT2_GLOBAL(0x009DEA66, uint16) = 0;
return 1;
}
static int editor_load_landscape_from_sc4(const char *path)
{
FILE *fp;
long fpLength;
char *fpBuffer;
rct1_s4 *s4;
// Open file
fp = fopen(path, "rb");
if (fp == NULL) {
RCT2_GLOBAL(RCT2_ADDRESS_ERROR_TYPE, uint8) = 255;
RCT2_GLOBAL(RCT2_ADDRESS_ERROR_STRING_ID, uint16) = 3011;
s4 = malloc(sizeof(rct1_s4));
if (!rct1_read_sc4(path, s4)) {
free(s4);
return 0;
}
rct1_import_s4(s4);
free(s4);
// Get length
fseek(fp, 0, SEEK_END);
fpLength = ftell(fp);
rewind(fp);
// Read whole file into a buffer
fpBuffer = malloc(fpLength);
fread(fpBuffer, fpLength, 1, fp);
fclose(fp);
editor_read_sc4(fpBuffer, fpLength);
free(fpBuffer);
sub_6A2B62();
return 1;
}
static int editor_read_sc4(char *src, int length)
{
int decodedLength;
rct1_s4 *data;
int fileType = sawyercoding_detect_file_type(src, length);
data = malloc(sizeof(rct1_s4));
decodedLength = (fileType & FILE_VERSION_MASK) == FILE_VERSION_RCT1 ?
sawyercoding_decode_sv4(src, (char*)data, length) :
sawyercoding_decode_sc4(src, (char*)data, length);
if (decodedLength != sizeof(rct1_s4)) {
free(data);
return 0;
}
editor_read_s4(data);
free(data);
return 1;
}
static int editor_read_sv4(char *src, int length)
{
int decodedLength;
rct1_s4 *data;
data = malloc(sizeof(rct1_s4));
decodedLength = sawyercoding_decode_sv4(src, (char*)data, length);
if (decodedLength != sizeof(rct1_s4)) {
free(data);
return 0;
}
editor_read_s4(data);
free(data);
return 1;
}
static void read(void *dst, void *src, int length)
{
memcpy(dst, src, length);
}
/**
*
* rct2: 0x0069EEA0
*/
static int editor_read_s4(rct1_s4 *src)
{
int i;
rct_banner *banner;
read((void*)RCT2_ADDRESS_CURRENT_MONTH_YEAR, &src->month, 16);
memset((void*)RCT2_ADDRESS_MAP_ELEMENTS, 0, 0x30000 * sizeof(rct_map_element));
read((void*)RCT2_ADDRESS_MAP_ELEMENTS, src->map_elements, sizeof(src->map_elements));
read((void*)0x010E63B8, &src->unk_counter, 4 + sizeof(src->sprites));
for (i = 0; i < MAX_BANNERS; i++)
gBanners[i].type = 255;
read((void*)0x013573BC, &src->next_sprite_index, 12424);
for (i = 0; i < MAX_BANNERS; i++) {
banner = &gBanners[i];
if (banner->type != 255 && banner->string_idx != 3458)
banner->string_idx = 778;
}
read((void*)0x0135A8F4, &src->string_table, 0x2F51C);
memset((void*)0x013CA672, 0, 204);
read((void*)0x0138B580, &src->map_animations, 0x258F2);
read((void*)0x013C6A72, &src->patrol_areas, sizeof(src->patrol_areas));
char *esi = (char*)0x13C6A72;
char *edi = (char*)0x13B0E72;
int ebx, edx = 116;
do {
ebx = 32;
do {
memcpy(edi, esi, 4); esi += 4; edi += 4;
memset(edi, 0, 4); edi += 4;
} while (--ebx > 0);
memset(edi, 0, 64); edi += 64;
} while (--edx > 0);
edi += 0xA800;
edx = 4;
do {
ebx = 32;
do {
memcpy(edi, esi, 4); esi += 4; edi += 4;
memset(edi, 0, 4); edi += 4;
} while (--ebx);
memset(edi, 0, 64); edi += 64;
} while (--edx);
read((void*)0x013CA672, &src->unk_1F42AA, 116);
read((void*)0x013CA73A, &src->unk_1F431E, 4);
read((void*)0x013CA73E, &src->unk_1F4322, 0x41EA);
rct1_fix_landscape();
editor_finalise_main_view();
RCT2_GLOBAL(0x009DEA66, uint16) = 0;
return 1;
}
@ -836,7 +428,7 @@ static int editor_read_s6(const char *path)
// Check expansion pack
// RCT2_CALLPROC_EBPSAFE(0x006757E6);
reset_loaded_objects();//RCT2_CALLPROC_EBPSAFE(0x006A9FC0);
reset_loaded_objects();
map_update_tile_pointers();
map_remove_all_rides();
@ -865,8 +457,8 @@ static int editor_read_s6(const char *path)
RCT2_GLOBAL(0x01357BC8, uint16) = 0;
RCT2_GLOBAL(0x013573FE, uint16) = 0;
if (s6Header->type != S6_TYPE_SCENARIO) {
RCT2_CALLPROC_EBPSAFE(0x00685675);
RCT2_CALLPROC_EBPSAFE(0x0068585B);
research_populate_list_random();
research_remove_non_separate_vehicle_types();
if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_NO_MONEY)
RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) |= PARK_FLAGS_NO_MONEY_SCENARIO;
@ -889,7 +481,7 @@ static int editor_read_s6(const char *path)
RCT2_GLOBAL(0x013573DC, uint32) = min(RCT2_GLOBAL(0x013573DC, uint32), 100000);
RCT2_CALLPROC_EBPSAFE(0x0069E89B);
RCT2_CALLPROC_EBPSAFE(0x0069E869);
sub_69E869();
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_LOAN, money32) = clamp(
MONEY(0,00),
@ -915,7 +507,7 @@ static int editor_read_s6(const char *path)
rct_stex_entry* stex = g_stexEntries[0];
if ((int)stex != 0xFFFFFFFF) {
object_unload(0, &object_entry_groups[OBJECT_TYPE_SCENARIO_TEXT].entries[0]);
reset_loaded_objects();//RCT2_CALLPROC_EBPSAFE(0x006A9FC0);
reset_loaded_objects();
format_string(s6Info->details, STR_NO_DETAILS_YET, NULL);
s6Info->name[0] = 0;
@ -925,40 +517,7 @@ static int editor_read_s6(const char *path)
viewport_init_all();
news_item_init_queue();
window_editor_main_open();
// Initialise main view
rct_window *w = window_get_main();
rct_viewport *viewport = w->viewport;
w->viewport_target_sprite = -1;
w->saved_view_x = RCT2_GLOBAL(RCT2_ADDRESS_SAVED_VIEW_X, sint16);
w->saved_view_y = RCT2_GLOBAL(RCT2_ADDRESS_SAVED_VIEW_Y, sint16);
int zoom_difference = (RCT2_GLOBAL(RCT2_ADDRESS_SAVED_VIEW_ZOOM_AND_ROTATION, sint16) & 0xFF) - viewport->zoom;
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;
if (zoom_difference != 0) {
if (zoom_difference >= 0) {
viewport->view_width <<= zoom_difference;
viewport->view_height <<= zoom_difference;
} else {
zoom_difference = -zoom_difference;
viewport->view_width >>= zoom_difference;
viewport->view_height >>= zoom_difference;
}
}
w->saved_view_x -= viewport->view_width >> 1;
w->saved_view_y -= viewport->view_height >> 1;
window_invalidate(w);
sub_69E9A7();
RCT2_CALLPROC_EBPSAFE(0x006DFEE4);
window_new_ride_init_vars();
RCT2_GLOBAL(0x009DEB7C, uint16) = 0;
load_palette();
gfx_invalidate_screen();
editor_finalise_main_view();
return 1;
}
@ -1011,3 +570,38 @@ void editor_open_windows_for_current_step()
break;
}
}
static void editor_finalise_main_view()
{
rct_window *w = window_get_main();
rct_viewport *viewport = w->viewport;
w->viewport_target_sprite = -1;
w->saved_view_x = RCT2_GLOBAL(RCT2_ADDRESS_SAVED_VIEW_X, sint16);
w->saved_view_y = RCT2_GLOBAL(RCT2_ADDRESS_SAVED_VIEW_Y, sint16);
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;
int zoom_difference = RCT2_GLOBAL(RCT2_ADDRESS_SAVED_VIEW_ZOOM_AND_ROTATION, sint16) - viewport->zoom;
if (zoom_difference != 0) {
if (zoom_difference >= 0) {
viewport->view_width <<= zoom_difference;
viewport->view_height <<= zoom_difference;
} else {
zoom_difference = -zoom_difference;
viewport->view_width >>= zoom_difference;
viewport->view_height >>= zoom_difference;
}
}
w->saved_view_x -= viewport->view_width >> 1;
w->saved_view_y -= viewport->view_height >> 1;
window_invalidate(w);
sub_69E9A7();
scenery_set_default_placement_configuration();
window_new_ride_init_vars();
RCT2_GLOBAL(0x009DEB7C, uint16) = 0;
load_palette();
gfx_invalidate_screen();
}

View File

@ -51,6 +51,7 @@
#include "world/climate.h"
#include "world/map_animation.h"
#include "world/park.h"
#include "world/scenery.h"
#include "world/sprite.h"
#include "world/water.h"
@ -452,7 +453,7 @@ int game_do_command_p(int command, int *eax, int *ebx, int *ecx, int *edx, int *
if (RCT2_GLOBAL(0x0141F568, uint8) == RCT2_GLOBAL(0x013CA740, uint8)) {
// Create a +/- money text effect
if (cost != 0)
RCT2_CALLPROC_X(0x0069C5D0, 0, cost, 0, 0, 0, 0, 0);
money_effect_create(cost);
}
}
@ -472,6 +473,15 @@ int game_do_command_p(int command, int *eax, int *ebx, int *ecx, int *edx, int *
return 0x80000000;
}
void pause_toggle()
{
RCT2_GLOBAL(RCT2_ADDRESS_GAME_PAUSED, uint32) ^= 1;
window_invalidate_by_class(WC_TOP_TOOLBAR);
if (RCT2_GLOBAL(RCT2_ADDRESS_GAME_PAUSED, uint32) & 1)
pause_sounds();
else
unpause_sounds();
}
/**
*
@ -479,14 +489,9 @@ int game_do_command_p(int command, int *eax, int *ebx, int *ecx, int *edx, int *
*/
void game_pause_toggle(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp)
{
if (*ebx & GAME_COMMAND_FLAG_APPLY) {
RCT2_GLOBAL(RCT2_ADDRESS_GAME_PAUSED, uint32) ^= 1;
window_invalidate_by_class(WC_TOP_TOOLBAR);
if (RCT2_GLOBAL(RCT2_ADDRESS_GAME_PAUSED, uint32) & 1)
pause_sounds();
else
unpause_sounds();
}
if (*ebx & GAME_COMMAND_FLAG_APPLY)
pause_toggle();
*ebx = 0;
}
@ -664,7 +669,7 @@ int game_load_save(const char *path)
// The rest is the same as in scenario load and play
reset_loaded_objects();
map_update_tile_pointers();
reset_0x69EBE4();// RCT2_CALLPROC_EBPSAFE(0x0069EBE4);
reset_0x69EBE4();
RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) = SCREEN_FLAGS_PLAYING;
viewport_init_all();
game_create_windows();
@ -691,7 +696,7 @@ int game_load_save(const char *path)
window_invalidate(mainWindow);
sub_69E9A7();
RCT2_CALLPROC_EBPSAFE(0x006DFEE4);
scenery_set_default_placement_configuration();
window_new_ride_init_vars();
RCT2_GLOBAL(0x009DEB7C, uint16) = 0;
if (RCT2_GLOBAL(0x0013587C4, uint32) == 0) // this check is not in scenario play

View File

@ -109,6 +109,7 @@ void game_reduce_game_speed();
void game_load_or_quit_no_save_prompt();
int game_load_save(const char *path);
void game_pause_toggle(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp);
void pause_toggle();
char save_game();
void rct2_exit();
void rct2_exit_reason(rct_string_id title, rct_string_id body);

View File

@ -25,6 +25,7 @@
#include "keyboard_shortcut.h"
#include "viewport.h"
#include "window.h"
#include "widget.h"
typedef void (*shortcut_action)();
@ -171,7 +172,45 @@ static void shortcut_rotate_view()
static void shortcut_rotate_construction_object()
{
RCT2_CALLPROC_EBPSAFE(0x006E4182);
rct_window *w;
// Rotate scenery
w = window_find_by_class(WC_SCENERY);
if (w != NULL && !widget_is_disabled(w, 25) && w->widgets[25].type != WWT_EMPTY) {
window_event_mouse_up_call(w, 25);
return;
}
// Rotate construction track piece
w = window_find_by_class(WC_RIDE_CONSTRUCTION);
if (w != NULL && !widget_is_disabled(w, 32) && w->widgets[32].type != WWT_EMPTY) {
// Check if building a maze...
if (w->widgets[32].tooltip != 1761) {
window_event_mouse_up_call(w, 32);
return;
}
}
// Rotate track design preview
w = window_find_by_class(WC_TRACK_DESIGN_LIST);
if (w != NULL && !widget_is_disabled(w, 5) && w->widgets[5].type != WWT_EMPTY) {
window_event_mouse_up_call(w, 5);
return;
}
// Rotate track design placement
w = window_find_by_class(WC_TRACK_DESIGN_PLACE);
if (w != NULL && !widget_is_disabled(w, 3) && w->widgets[3].type != WWT_EMPTY) {
window_event_mouse_up_call(w, 3);
return;
}
// Rotate park entrance
w = window_find_by_class(WC_MAP);
if (w != NULL && !widget_is_disabled(w, 20) && w->widgets[20].type != WWT_EMPTY) {
window_event_mouse_up_call(w, 20);
return;
}
}
static void shortcut_underground_view_toggle()
@ -308,14 +347,11 @@ static void shortcut_show_financial_information()
static void shortcut_show_research_information()
{
rct_window *window;
if (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & (SCREEN_FLAGS_SCENARIO_EDITOR | SCREEN_FLAGS_TRACK_DESIGNER | SCREEN_FLAGS_TRACK_MANAGER))) {
// Open new ride window
RCT2_CALLPROC_EBPSAFE(0x006B3CFF);
window = window_find_by_class(WC_CONSTRUCT_RIDE);
if (window != NULL)
window_event_mouse_up_call(window, 10);
if (gConfigInterface.toolbar_show_research)
window_research_open();
else
window_new_ride_open_research();
}
}
@ -386,7 +422,7 @@ static void shortcut_show_map()
static void shortcut_screenshot()
{
RCT2_CALLPROC_EBPSAFE(0x006E4034); // set screenshot countdown to 2
RCT2_GLOBAL(RCT2_ADDRESS_SCREENSHOT_COUNTDOWN, uint8) = 2;
}
static void shortcut_reduce_game_speed()

View File

@ -223,74 +223,37 @@ void viewport_update_pointers()
*vp = NULL;
}
void sub_689174(sint16* x, sint16* y, sint16 *z, uint8 curr_rotation){
/**
* edx is assumed to be (and always is) the current rotation, so it is not needed as parameter.
* rct2: 0x00689174
*/
void sub_689174(sint16* x, sint16* y, sint16 *z)
{
//RCT2_CALLFUNC_X(0x00689174, (int*)&x, (int*)&y, (int*)&z, &curr_rotation, (int*)&window, (int*)&viewport, &ebp);
sint16 start_x = *x;
sint16 start_y = *y;
sint16 height = 0;
switch (curr_rotation){
case 0:
for (int i = 0; i < 6; ++i){
*x = start_y - start_x / 2 + height;
*y = start_y + start_x / 2 + height;
height = map_element_height((0xFFFF) & *x, (0xFFFF) & *y);
// HACK: This is to prevent the x and y values being set to values outside
// of the map. This can happen when the height is larger than the map size.
if (*x > RCT2_GLOBAL(RCT2_ADDRESS_MAP_MAXIMUM_X_Y, sint16) && *y > RCT2_GLOBAL(RCT2_ADDRESS_MAP_MAXIMUM_X_Y, sint16)){
*x = start_y - start_x / 2;
*y = start_y + start_x / 2;
}
rct_xy16 pos;
for (int i = 0; i < 6; i++) {
pos = viewport_coord_to_map_coord(start_x, start_y, height);
height = map_element_height((0xFFFF) & pos.x, (0xFFFF) & pos.y);
// HACK: This is to prevent the x and y values being set to values outside
// of the map. This can happen when the height is larger than the map size.
sint16 max = RCT2_GLOBAL(RCT2_ADDRESS_MAP_MAXIMUM_X_Y, sint16);
if (pos.x > max && pos.y > max) {
int x_corr[] = { -1, 1, 1, -1 };
int y_corr[] = { -1, -1, 1, 1 };
uint32 rotation = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32);
pos.x += x_corr[rotation] * height;
pos.y += y_corr[rotation] * height;
}
break;
case 1:
for (int i = 0; i < 6; ++i){
*x = -start_y - start_x / 2 - height;
*y = start_y - start_x / 2 + height;
height = map_element_height((0xFFFF) & *x, (0xFFFF) & *y);
// HACK: This is to prevent the x and y values being set to values outside
// of the map. This can happen when the height is larger than the map size.
if (*x > RCT2_GLOBAL(RCT2_ADDRESS_MAP_MAXIMUM_X_Y, sint16) && *y > RCT2_GLOBAL(RCT2_ADDRESS_MAP_MAXIMUM_X_Y, sint16)){
*x = -start_y - start_x / 2;
*y = start_y - start_x / 2;
}
}
break;
case 2:
for (int i = 0; i < 6; ++i){
*x = -start_y + start_x / 2 - height;
*y = -start_y - start_x / 2 - height;
height = map_element_height((0xFFFF) & *x, (0xFFFF) & *y);
// HACK: This is to prevent the x and y values being set to values outside
// of the map. This can happen when the height is larger than the map size.
if (*x > RCT2_GLOBAL(RCT2_ADDRESS_MAP_MAXIMUM_X_Y, sint16) && *y > RCT2_GLOBAL(RCT2_ADDRESS_MAP_MAXIMUM_X_Y, sint16)){
*x = -start_y + start_x / 2;
*y = -start_y - start_x / 2;
}
}
break;
case 3:
for (int i = 0; i < 6; ++i){
*x = start_x / 2 + start_y + height;
*y = start_x / 2 - start_y - height;
height = map_element_height((0xFFFF) & *x, (0xFFFF) & *y);
// HACK: This is to prevent the x and y values being set to values outside
// of the map. This can happen when the height is larger than the map size.
if (*x > RCT2_GLOBAL(RCT2_ADDRESS_MAP_MAXIMUM_X_Y, sint16) && *y > RCT2_GLOBAL(RCT2_ADDRESS_MAP_MAXIMUM_X_Y, sint16)){
*x = start_y + start_x / 2;
*y = -start_y + start_x / 2;
}
}
break;
}
*x = pos.x;
*y = pos.y;
*z = height;
}
@ -475,7 +438,7 @@ void viewport_update_position(rct_window *window)
if (window->viewport_target_sprite != -1){
rct_sprite* sprite = &g_sprite_list[window->viewport_target_sprite];
int height = map_element_height(0xFFFF & sprite->unknown.x, 0xFFFF & sprite->unknown.y) & 0xFFFF - 16;
int height = (map_element_height(0xFFFF & sprite->unknown.x, 0xFFFF & sprite->unknown.y) & 0xFFFF) - 16;
int underground = sprite->unknown.z < height;
viewport_set_underground_flag(underground, window, viewport);
@ -494,8 +457,7 @@ void viewport_update_position(rct_window *window)
sint16 y = viewport->view_height / 2 + window->saved_view_y;
sint16 z;
int curr_rotation = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32);
sub_689174(&x, &y, &z, curr_rotation);
sub_689174(&x, &y, &z);
viewport_set_underground_flag(0, window, viewport);
//RCT2_CALLPROC_X(0x006E7A15, x, y, z, 0, (int)window, (int)viewport, 0);
@ -1491,18 +1453,117 @@ void viewport_paint(rct_viewport* viewport, rct_drawpixelinfo* dpi, int left, in
//RCT2_CALLPROC_X(0x00685CBF, left, top, 0, right, (int)viewport, (int)dpi, bottom);
}
/**
*
* rct2: 0x00688972
* In:
* screen_x: eax
* screen_y: ebx
* Out:
* x: ax
* y: bx
* map_element: edx ?
* viewport: edi
*/
void sub_688972(int screenX, int screenY, sint16 *x, sint16 *y, rct_viewport **viewport) {
int my_x, my_y, z;
rct_viewport *myViewport;
get_map_coordinates_from_pos(screenX, screenY, 0xFFFE, &my_x, &my_y, &z, NULL, &myViewport);
if (z == 0) {
*x = 0x8000;
return;
}
RCT2_GLOBAL(0x00F1AD34, sint16) = my_x;
RCT2_GLOBAL(0x00F1AD36, sint16) = my_y;
RCT2_GLOBAL(0x00F1AD38, sint16) = my_x + 31;
RCT2_GLOBAL(0x00F1AD3A, sint16) = my_y + 31;
rct_xy16 start_vp_pos = screen_coord_to_viewport_coord(myViewport, screenX, screenY);
rct_xy16 map_pos = { my_x + 16, my_y + 16 };
for (int i = 0; i < 5; i++) {
z = map_element_height(map_pos.x, map_pos.y);
map_pos = viewport_coord_to_map_coord(start_vp_pos.x, start_vp_pos.y, z);
map_pos.x = clamp(RCT2_GLOBAL(0x00F1AD34, sint16), map_pos.x, RCT2_GLOBAL(0x00F1AD38, sint16));
map_pos.y = clamp(RCT2_GLOBAL(0x00F1AD36, sint16), map_pos.y, RCT2_GLOBAL(0x00F1AD3A, sint16));
}
*x = map_pos.x;
*y = map_pos.y;
if (viewport != NULL) *viewport = myViewport;
}
/**
*
* rct2: 0x0068958D
*/
void screen_pos_to_map_pos(short *x, short *y)
void screen_pos_to_map_pos(sint16 *x, sint16 *y, int *direction)
{
int eax, ebx, ecx, edx, esi, edi, ebp;
eax = *x;
ebx = *y;
RCT2_CALLFUNC_X(0x0068958D, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
*x = eax & 0xFFFF;
*y = ebx & 0xFFFF;
sub_688972(*x, *y, x, y, NULL);
if (*x == 0x8000)
return;
int my_direction;
int dist_from_center_x = abs(*x % 32);
int dist_from_center_y = abs(*y % 32);
if (dist_from_center_x > 8 && dist_from_center_x < 24 &&
dist_from_center_y > 8 && dist_from_center_y < 24) {
my_direction = 4;
} else {
sint16 mod_x = *x & 0x1F;
sint16 mod_y = *y & 0x1F;
if (mod_x <= 16) {
if (mod_y < 16) {
my_direction = 2;
} else {
my_direction = 3;
}
} else {
if (mod_y < 16) {
my_direction = 0;
} else {
my_direction = 1;
}
}
}
*x = *x & ~0x1F;
*y = *y & ~0x1F;
if (direction != NULL) *direction = my_direction;
}
rct_xy16 screen_coord_to_viewport_coord(rct_viewport *viewport, uint16 x, uint16 y)
{
rct_xy16 ret;
ret.x = ((x - viewport->x) << viewport->zoom) + viewport->view_x;
ret.y = ((y - viewport->y) << viewport->zoom) + viewport->view_y;
return ret;
}
rct_xy16 viewport_coord_to_map_coord(int x, int y, int z)
{
rct_xy16 ret;
switch (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32)) {
case 0:
ret.x = -x / 2 + y + z;
ret.y = x / 2 + y + z;
break;
case 1:
ret.x = -x / 2 - y - z;
ret.y = -x / 2 + y + z;
break;
case 2:
ret.x = x / 2 - y - z;
ret.y = -x / 2 - y - z;
break;
case 3:
ret.x = x / 2 + y + z;
ret.y = x / 2 - y - z;
break;
}
return ret;
}
/**
@ -1676,28 +1737,29 @@ void viewport_set_visibility(uint8 mode)
* y: cx
* z: bl
* mapElement: edx
* viewport: edi
*/
void get_map_coordinates_from_pos(int screenX, int screenY, int flags, int *x, int *y, int *z, rct_map_element **mapElement)
void get_map_coordinates_from_pos(int screenX, int screenY, int flags, int *x, int *y, int *z, rct_map_element **mapElement, rct_viewport **viewport)
{
RCT2_GLOBAL(0x9AC154, uint16_t) = flags & 0xFFFF;
RCT2_GLOBAL(0x9AC148, uint8_t) = 0;
rct_window* window = window_find_from_point(screenX, screenY);
if (window != NULL && window->viewport != NULL)
{
rct_viewport* viewport = window->viewport;
rct_viewport* myviewport = window->viewport;
RCT2_GLOBAL(0x9AC138 + 4, int16_t) = screenX;
RCT2_GLOBAL(0x9AC138 + 6, int16_t) = screenY;
screenX -= (int)viewport->x;
screenY -= (int)viewport->y;
if (screenX >= 0 && screenX < (int)viewport->width && screenY >= 0 && screenY < (int)viewport->height)
screenX -= (int)myviewport->x;
screenY -= (int)myviewport->y;
if (screenX >= 0 && screenX < (int)myviewport->width && screenY >= 0 && screenY < (int)myviewport->height)
{
screenX <<= viewport->zoom;
screenY <<= viewport->zoom;
screenX += (int)viewport->view_x;
screenY += (int)viewport->view_y;
RCT2_GLOBAL(RCT2_ADDRESS_VIEWPORT_ZOOM, uint16_t) = viewport->zoom;
screenX &= (0xFFFF << viewport->zoom) & 0xFFFF;
screenY &= (0xFFFF << viewport->zoom) & 0xFFFF;
screenX <<= myviewport->zoom;
screenY <<= myviewport->zoom;
screenX += (int)myviewport->view_x;
screenY += (int)myviewport->view_y;
RCT2_GLOBAL(RCT2_ADDRESS_VIEWPORT_ZOOM, uint16_t) = myviewport->zoom;
screenX &= (0xFFFF << myviewport->zoom) & 0xFFFF;
screenY &= (0xFFFF << myviewport->zoom) & 0xFFFF;
RCT2_GLOBAL(RCT2_ADDRESS_VIEWPORT_PAINT_X, int16_t) = screenX;
RCT2_GLOBAL(RCT2_ADDRESS_VIEWPORT_PAINT_Y, int16_t) = screenY;
rct_drawpixelinfo* dpi = RCT2_ADDRESS(RCT2_ADDRESS_VIEWPORT_DPI, rct_drawpixelinfo);
@ -1713,6 +1775,7 @@ void get_map_coordinates_from_pos(int screenX, int screenY, int flags, int *x, i
RCT2_CALLPROC_X(0x688217, 0, 0, 0, 0, 0, 0, 0);
RCT2_CALLPROC_X(0x68862C, 0, 0, 0, 0, 0, 0, 0);
}
if (viewport != NULL) *viewport = myviewport;
}
if (z != NULL) *z = RCT2_GLOBAL(0x9AC148, uint8_t);
if (x != NULL) *x = (int)RCT2_GLOBAL(0x9AC14C, int16_t);

View File

@ -82,9 +82,12 @@ void viewport_update_position(rct_window *window);
void viewport_render(rct_drawpixelinfo *dpi, rct_viewport *viewport, int left, int top, int right, int bottom);
void viewport_paint(rct_viewport* viewport, rct_drawpixelinfo* dpi, int left, int top, int right, int bottom);
void sub_689174(sint16* x, sint16* y, sint16 *z, uint8 curr_rotation);
void sub_689174(sint16* x, sint16* y, sint16 *z);
void screen_pos_to_map_pos(short *x, short *y);
rct_xy16 screen_coord_to_viewport_coord(rct_viewport *viewport, uint16 x, uint16 y);
rct_xy16 viewport_coord_to_map_coord(int x, int y, int z);
void sub_688972(int screenX, int screenY, sint16 *x, sint16 *y, rct_viewport **viewport);
void screen_pos_to_map_pos(sint16 *x, sint16 *y, int *direction);
void show_gridlines();
void hide_gridlines();
@ -94,7 +97,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 *z, rct_map_element **mapElement);
void get_map_coordinates_from_pos(int screenX, int screenY, int flags, int *x, int *y, int *z, 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);

View File

@ -58,7 +58,7 @@ 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, 0xFF79, &info->x, &info->y, &info->type, &info->mapElement);
get_map_coordinates_from_pos(x, y, 0xFF79, &info->x, &info->y, &info->type, &info->mapElement, NULL);
mapElement = info->mapElement;
sprite = (rct_sprite*)mapElement;
@ -178,7 +178,7 @@ 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, 9, &info->x, &info->y, &info->type, &info->mapElement);
get_map_coordinates_from_pos(x, y, 9, &info->x, &info->y, &info->type, &info->mapElement, NULL);
mapElement = info->mapElement;
sprite = (rct_sprite*)mapElement;

View File

@ -41,23 +41,23 @@ rct_window* g_window_list = RCT2_ADDRESS(RCT2_ADDRESS_WINDOW_LIST, rct_window);
// converted from uint16 values at 0x009A41EC - 0x009A4230
// these are percentage coordinates of the viewport to center to, if a window is obscuring a location, the next is tried
float window_scroll_locations[][2] = {
0.5f, 0.5f,
0.75f, 0.5f,
0.25f, 0.5f,
0.5f, 0.75f,
0.5f, 0.25f,
0.75f, 0.75f,
0.75f, 0.25f,
0.25f, 0.75f,
0.25f, 0.25f,
0.125f, 0.5f,
0.875f, 0.5f,
0.5f, 0.125f,
0.5f, 0.875f,
0.875f, 0.125f,
0.875f, 0.875f,
0.125f, 0.875f,
0.125f, 0.125f,
{0.5f, 0.5f},
{0.75f, 0.5f},
{0.25f, 0.5f},
{0.5f, 0.75f},
{0.5f, 0.25f},
{0.75f, 0.75f},
{0.75f, 0.25f},
{0.25f, 0.75f},
{0.25f, 0.25f},
{0.125f, 0.5f},
{0.875f, 0.5f},
{0.5f, 0.125f},
{0.5f, 0.875f},
{0.875f, 0.125f},
{0.875f, 0.875f},
{0.125f, 0.875f},
{0.125f, 0.125f},
};
static void window_all_wheel_input();
@ -642,7 +642,7 @@ int window_find_widget_from_point(rct_window *w, int x, int y)
int i, widget_index;
// Invalidate the window
RCT2_CALLPROC_X(w->event_handlers[WE_INVALIDATE], 0, 0, 0, 0, (int)w, 0, 0);
window_event_invalidate_call(w);
// Find the widget at point x, y
widget_index = -1;
@ -1140,14 +1140,24 @@ void window_scroll_to_location(rct_window *w, int x, int y, int z)
}
}
/**
*
* rct2: 0x00688956
*/
void sub_688956()
{
rct_window *w;
for (w = RCT2_NEW_WINDOW - 1; w >= g_window_list; w--)
RCT2_CALLPROC_X(w->event_handlers[WE_UNKNOWN_14], 0, 0, 0, 0, (int)w, 0, 0);
}
/**
*
* rct2: 0x0068881A
*/
void window_rotate_camera(rct_window *w)
{
//RCT2_CALLPROC_X(0x0068881A, 0, 0, 0, 0, (int)w, 0, 0);
rct_viewport *viewport = w->viewport;
if (viewport == NULL)
return;
@ -1156,12 +1166,9 @@ void window_rotate_camera(rct_window *w)
sint16 y = (viewport->height >> 1) + viewport->y;
sint16 z;
uint8 rot = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint8);
int ecx, edx, esi, edi = (int)viewport, ebp;
//has something to do with checking if middle of the viewport is obstructed
RCT2_CALLFUNC_X(0x00688972, (int*)&x, (int*)&y, &ecx, &edx, &esi, &edi, &ebp);
rct_viewport *other = (rct_viewport*)edi;
rct_viewport *other;
sub_688972(x, y, &x, &y, &other);
// other != viewport probably triggers on viewports in ride or guest window?
// x is 0x8000 if middle of viewport is obstructed by another window?
@ -1169,12 +1176,12 @@ void window_rotate_camera(rct_window *w)
x = (viewport->view_width >> 1) + viewport->view_x;
y = (viewport->view_height >> 1) + viewport->view_y;
sub_689174(&x, &y, &z, rot);
sub_689174(&x, &y, &z);
} else {
z = map_element_height(x, y);
}
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32) = (rot + 1) % 4;
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32) = (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32) + 1) % 4;
int new_x, new_y;
center_2d_coordinates(x, y, z, &new_x, &new_y, viewport);
@ -1186,8 +1193,7 @@ void window_rotate_camera(rct_window *w)
window_invalidate(w);
RCT2_CALLPROC_EBPSAFE(0x00688956);
sub_688956();
sub_69E9A7();
}
@ -1345,7 +1351,7 @@ void window_draw(rct_window *w, int left, int top, int right, int bottom)
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_WINDOW_COLOUR_4, uint8) = v->colours[3] & 0x7F;
// Invalidate the window
RCT2_CALLPROC_X(v->event_handlers[WE_INVALIDATE], 0, 0, 0, 0, (int)v, 0, 0);
window_event_invalidate_call(v);
// Paint the window
RCT2_CALLPROC_X(v->event_handlers[WE_PAINT], 0, 0, 0, 0, (int)v, (int)dpi, 0);
@ -1484,8 +1490,8 @@ void window_resize(rct_window *w, int dw, int dh)
w->width = clamp(w->min_width, w->width + dw, w->max_width);
w->height = clamp(w->min_height, w->height + dh, w->max_height);
RCT2_CALLPROC_X(w->event_handlers[WE_RESIZE], w->width, w->height, 0, 0, (int)w, 0, 0);
RCT2_CALLPROC_X(w->event_handlers[WE_INVALIDATE], 0, 0, 0, 0, (int)w, 0, 0);
window_event_resize_call(w);
window_event_invalidate_call(w);
// Update scroll widgets
for (i = 0; i < 3; i++) {
@ -1906,7 +1912,7 @@ void sub_6EA73F()
for (w = RCT2_LAST_WINDOW; w >= g_window_list; w--) {
window_update_scroll_widgets(w);
window_invalidate_pressed_image_buttons(w);
RCT2_CALLPROC_X(w->event_handlers[WE_RESIZE], 0, 0, 0, 0, (int)w, 0, 0);
window_event_resize_call(w);
}
}

View File

@ -393,6 +393,7 @@ enum {
WC_EDTIOR_OBJECTIVE_OPTIONS = 46,
WC_MANAGE_TRACK_DESIGN = 47,
WC_TRACK_DELETE_PROMPT = 48,
WC_INSTALL_TRACK = 49,
WC_CLEAR_SCENERY = 50,
WC_CHEATS = 110,
WC_RESEARCH = 111,
@ -425,7 +426,8 @@ enum {
LOADSAVETYPE_GAME = 0 << 1,
LOADSAVETYPE_LANDSCAPE = 1 << 1,
LOADSAVETYPE_SCENARIO = 2 << 1
LOADSAVETYPE_SCENARIO = 2 << 1,
LOADSAVETYPE_TRACK = 3 << 1,
};
@ -540,7 +542,9 @@ void window_ride_construct(rct_window *w);
void window_ride_list_open();
rct_window * window_construction_open();
void window_track_place_open();
void window_new_ride_open();
rct_window *window_new_ride_open();
rct_window *window_new_ride_open_research();
void window_install_track_open(const char* path);
void window_banner_open(rct_windownumber number);
void window_sign_open(rct_windownumber number);
void window_sign_small_open(rct_windownumber number);

View File

@ -47,7 +47,7 @@ typedef struct {
// Rate is relative to 0.1 GBP
int rate;
char symbol[8];
char affix;
int affix;
} rct_currency_spec;
// List of currency formats

View File

@ -519,7 +519,7 @@ static int award_is_deserved_most_confusing_layout(int awardType, int activeAwar
continue;
peepsCounted++;
if (peep->thoughts[0].var_2 <= 5 && peep->thoughts[0].type == PEEP_THOUGHT_TYPE_LOST || peep->thoughts[0].type == PEEP_THOUGHT_TYPE_CANT_FIND)
if (peep->thoughts[0].var_2 <= 5 && (peep->thoughts[0].type == PEEP_THOUGHT_TYPE_LOST || peep->thoughts[0].type == PEEP_THOUGHT_TYPE_CANT_FIND))
peepsLost++;
}
@ -631,4 +631,4 @@ void award_update_all()
if (awards[i].time != 0)
if (--awards[i].time == 0)
window_invalidate_by_class(WC_PARK_INFORMATION);
}
}

View File

@ -28,6 +28,8 @@
#include "../world/sprite.h"
#include "news_item.h"
rct_news_item *newsItems = RCT2_ADDRESS(RCT2_ADDRESS_NEWS_ITEM_LIST, rct_news_item);
void window_game_bottom_toolbar_invalidate_news_item();
static int news_item_get_new_history_slot();
@ -320,16 +322,17 @@ void news_item_open_subject(int type, int subject)
window = window_find_by_class(WC_TOP_TOOLBAR);
if (window != NULL) {
window_invalidate(window);
if (tool_set(window, 9, 0)){
RCT2_CALLPROC_X(0x006E1172, (subject & 0xFFFF), 0, subject, 0, 0, 0, 0);
if (!tool_set(window, 9, 0)) {
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) |= INPUT_FLAG_6;
window_scenery_open();
}
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) |= INPUT_FLAG_6;
window_scenery_open();
}
}
// Switch to new scenery tab
RCT2_CALLPROC_X(0x006E1172, (subject & 0xFFFF), 0, subject, 0, 0, 0, 0);
window = window_find_by_class(WC_SCENERY);
if (window != NULL)
window_event_mouse_down_call(window, 4 + subject);
break;
case NEWS_ITEM_PEEPS:
// Open guest list to right tab
@ -343,3 +346,29 @@ void news_item_open_subject(int type, int subject)
break;
}
}
/**
* rct2: 0x0066E407
*/
void news_item_disable_news(uint8 type, uint32 assoc) {
rct_news_item* newsItem = newsItems;
while (newsItem->type != NEWS_ITEM_NULL) {
if (type == newsItem->type && assoc == newsItem->assoc) {
newsItem->flags |= 0x1;
if (newsItem == RCT2_ADDRESS(RCT2_ADDRESS_NEWS_ITEM_LIST, rct_news_item)) {
window_game_bottom_toolbar_invalidate_news_item();
}
}
newsItem++;
}
newsItem = &newsItems[11]; //0x13CB2D8
while (newsItem->type != NEWS_ITEM_NULL) {
if (type == newsItem->type && assoc == newsItem->assoc) {
newsItem->flags |= 0x1;
window_invalidate_by_class(WC_RECENT_NEWS);
}
newsItem++;
}
}

View File

@ -58,5 +58,6 @@ void news_item_close_current();
void news_item_get_subject_location(int type, int subject, int *x, int *y, int *z);
void news_item_add_to_queue(uint8 type, rct_string_id string_id, uint32 assoc);
void news_item_open_subject(int type, int subject);
void news_item_disable_news(uint8 type, uint32 assoc);
#endif

View File

@ -31,7 +31,7 @@
const int _researchRate[] = { 0, 160, 250, 400 };
// 0x01358844[500]
extern rct_research_item *gResearchItems = (rct_research_item*)RCT2_RESEARCH_ITEMS;
rct_research_item *gResearchItems = (rct_research_item*)RCT2_RESEARCH_ITEMS;
// 0x00EE787C
uint8 gResearchUncompletedCategories;
@ -189,7 +189,7 @@ void research_finish_item(sint32 entryIndex)
if (rideEntry2->var_008 & 0x2000)
continue;
if (rideEntry2->var_00C == ecx || rideEntry2->var_00D == ecx || rideEntry2->var_00E == ecx)
if (rideEntry2->ride_type[0] == ecx || rideEntry2->ride_type[1] == ecx || rideEntry2->ride_type[2] == ecx)
RCT2_ADDRESS(0x001357424, uint32)[i >> 5] |= 1 << (i & 0x1F);
}
}
@ -326,6 +326,149 @@ void sub_684AC3(){
RCT2_GLOBAL(RCT2_ADDRESS_RESEARH_PROGRESS, uint16) = 0;
}
/**
*
* rct2: 0x0068585B
*/
void research_remove_non_separate_vehicle_types()
{
rct_research_item *researchItem, *researchItem2;
researchItem = gResearchItems;
while ((researchItem + 1)->entryIndex != RESEARCHED_ITEMS_END) {
researchItem++;
}
do {
loopBeginning:
if (
researchItem != gResearchItems &&
researchItem->entryIndex != RESEARCHED_ITEMS_SEPERATOR &&
researchItem->entryIndex != RESEARCHED_ITEMS_END &&
researchItem->entryIndex >= 0x10000
) {
rct_ride_type *rideEntry = GET_RIDE_ENTRY(researchItem->entryIndex & 0xFF);
if (!(rideEntry->var_008 & 0x3000)) {
// Check if ride type already exists further up for a vehicle type that isn't displayed as a ride
researchItem2 = researchItem - 1;
do {
if (
researchItem2->entryIndex != RESEARCHED_ITEMS_SEPERATOR &&
researchItem2->entryIndex >= 0x10000
) {
rideEntry = GET_RIDE_ENTRY(researchItem2->entryIndex & 0xFF);
if (!(rideEntry->var_008 & 0x3000)) {
if (((researchItem->entryIndex >> 8) & 0xFF) == ((researchItem2->entryIndex >> 8) & 0xFF)) {
// Remove item
researchItem2 = researchItem;
do {
*researchItem2 = *(researchItem2 + 1);
} while ((researchItem2++)->entryIndex != RESEARCHED_ITEMS_END);
goto loopBeginning;
}
}
}
} while ((researchItem2--) != gResearchItems);
}
}
} while ((researchItem--) != gResearchItems);
}
/**
*
* rct2: 0x006857FA
*/
static void research_insert_unresearched(int entryIndex, int category)
{
rct_research_item *researchItem, *researchItem2;
researchItem = gResearchItems;
do {
if (researchItem->entryIndex == RESEARCHED_ITEMS_END) {
// Insert slot
researchItem2 = researchItem;
while (researchItem2->entryIndex != RESEARCHED_ITEMS_END_2) {
researchItem2++;
}
memmove(researchItem + 1, researchItem, (researchItem2 - researchItem + 1) * sizeof(rct_research_item));
// Place new item
researchItem->entryIndex = entryIndex;
researchItem->category = category;
break;
}
} while (entryIndex != (researchItem++)->entryIndex);
}
/**
*
* rct2: 0x00685826
*/
static void research_insert_researched(int entryIndex, int category)
{
rct_research_item *researchItem, *researchItem2;
researchItem = gResearchItems;
do {
if (researchItem->entryIndex == RESEARCHED_ITEMS_SEPERATOR) {
// Insert slot
researchItem2 = researchItem;
while (researchItem2->entryIndex != RESEARCHED_ITEMS_END_2) {
researchItem2++;
}
memmove(researchItem + 1, researchItem, (researchItem2 - researchItem + 1) * sizeof(rct_research_item));
// Place new item
researchItem->entryIndex = entryIndex;
researchItem->category = category;
break;
}
} while (entryIndex != (researchItem++)->entryIndex);
}
static void research_insert(int researched, int entryIndex, int category)
{
if (researched)
research_insert_researched(entryIndex, category);
else
research_insert_unresearched(entryIndex, category);
}
/**
*
* rct2: 0x00685675
*/
void research_populate_list_random()
{
rct_ride_type *rideEntry;
rct_scenery_set_entry *scenerySetEntry;
int rideType, researched;
// Rides
for (int i = 0; i < 128; i++) {
rideEntry = GET_RIDE_ENTRY(i);
if (rideEntry == (rct_ride_type*)-1)
continue;
researched = (scenario_rand() & 0xFF) > 128;
for (int j = 0; j < 3; j++) {
rideType = rideEntry->ride_type[j];
if (rideType != 255)
research_insert(researched, 0x10000 | (rideType << 8) | i, rideEntry->category[0]);
}
}
// Scenery
for (int i = 0; i < 19; i++) {
scenerySetEntry = g_scenerySetEntries[i];
if (scenerySetEntry == (rct_scenery_set_entry*)-1)
continue;
researched = (scenario_rand() & 0xFF) > 85;
research_insert(researched, i, RESEARCH_CATEGORY_SCENERYSET);
}
}
void research_set_funding(int amount)
{
game_do_command(0, GAME_COMMAND_FLAG_APPLY, 0, amount, GAME_COMMAND_SET_RESEARCH_FUNDING, 0, 0);

View File

@ -48,6 +48,16 @@ enum {
RESEARCH_STAGE_FINISHED_ALL
};
enum {
RESEARCH_CATEGORY_TRANSPORT,
RESEARCH_CATEGORY_GENTLE,
RESEARCH_CATEGORY_ROLLERCOASTER,
RESEARCH_CATEGORY_THRILL,
RESEARCH_CATEGORY_WATER,
RESEARCH_CATEGORY_SHOP,
RESEARCH_CATEGORY_SCENERYSET
};
extern rct_research_item *gResearchItems;
extern uint8 gResearchUncompletedCategories;
@ -55,6 +65,8 @@ void research_reset_items();
void research_update_uncompleted_types();
void research_update();
void sub_684AC3();
void research_remove_non_separate_vehicle_types();
void research_populate_list_random();
void research_set_funding(int amount);
void research_set_priority(int activeCategories);

View File

@ -638,14 +638,13 @@ int paint_ride_entry(int flags, int ebx, int ecx, int edx, rct_drawpixelinfo* dp
rideVehicleEntry->var_10 = bh;
}
uint16 no_positions = *peep_loading_positions++;
uint8 no_positions = *peep_loading_positions++;
if (no_positions == 0xFF)
{
no_positions = *((uint16*)peep_loading_positions);
// The no_positions is 16 bit skip over
peep_loading_positions += 2;
}
rideVehicleEntry->peep_loading_positions = peep_loading_positions;
peep_loading_positions += no_positions;
}
}
@ -653,7 +652,7 @@ int paint_ride_entry(int flags, int ebx, int ecx, int edx, rct_drawpixelinfo* dp
if (RCT2_GLOBAL(0x9ADAFD, uint8_t) == 0)
{
for (int i = 0; i < 3; ++i){
sint16 dl = (&ride_type->var_00C)[i];
int dl = ride_type->ride_type[i];
if (dl == 0xFF)continue;
@ -676,7 +675,7 @@ int paint_ride_entry(int flags, int ebx, int ecx, int edx, rct_drawpixelinfo* dp
// 0x6DEBAA
if (RCT2_GLOBAL(0x9ADAF4, sint32) != 0xFFFFFFFF) *RCT2_GLOBAL(0x9ADAF4, uint16*) = 0;
int di = ride_type->var_00C | (ride_type->var_00D << 8) | (ride_type->var_00E << 16);
int di = ride_type->ride_type[0] | (ride_type->ride_type[1] << 8) | (ride_type->ride_type[2] << 16);
if (ride_type->var_008 & 0x1000) di |= 0x1000000;
@ -711,7 +710,7 @@ int paint_ride_entry(int flags, int ebx, int ecx, int edx, rct_drawpixelinfo* dp
rideVehicleEntry->no_vehicle_images = 0;
rideVehicleEntry->var_16 = 0;
if (rideVehicleEntry->var_12 & 0x400){
if (!(rideVehicleEntry->var_12 & 0x400)){
rideVehicleEntry->var_0E = 0;
rideVehicleEntry->var_0F = 0;
rideVehicleEntry->var_10 = 0;
@ -742,10 +741,10 @@ int paint_ride_entry(int flags, int ebx, int ecx, int edx, rct_drawpixelinfo* dp
if (!((flags >> 8) & 0xFF))
{
int image_id = ride_type->images_offset;
if (ride_type->var_00C == 0xFF)
if (ride_type->ride_type[0] == 0xFF)
{
image_id++;
if (ride_type->var_00D == 0xFF) image_id++;
if (ride_type->ride_type[1] == 0xFF) image_id++;
}
gfx_draw_sprite(dpi, image_id, x - 56, y - 56, ebp);
return flags;
@ -758,11 +757,11 @@ int paint_ride_entry(int flags, int ebx, int ecx, int edx, rct_drawpixelinfo* dp
int format_args = ride_type->description;
if (!(ride_type->var_008 & 0x1000))
{
format_args = ride_type->var_00C;
format_args = ride_type->ride_type[0];
if ((format_args & 0xFF) == 0xFF)
{
format_args = ride_type->var_00D;
if ((format_args & 0xFF) == 0xFF) format_args = ride_type->var_00E;
format_args = ride_type->ride_type[1];
if ((format_args & 0xFF) == 0xFF) format_args = ride_type->ride_type[2];
}
format_args += 0x200;
}
@ -1623,10 +1622,10 @@ rct_object_entry *object_get_next(rct_object_entry *entry)
pos += 4;
// Skip
pos += *pos++ * 16;
pos += *pos * 16 + 1;
// Skip theme objects
pos += *pos++ * 16;
pos += *pos * 16 + 1;
// Skip
pos += 4;

View File

@ -649,11 +649,11 @@ static uint32 install_object_entry(rct_object_entry* entry, rct_object_entry* in
// When made of two parts i.e Wooden Roller Coaster (Dream Woodie Cars)
if ((objectType == OBJECT_TYPE_RIDE) && !((((rct_ride_type*)chunk)->var_008) & 0x1000)) {
rct_ride_type* ride_type = (rct_ride_type*)chunk;
rct_string_id obj_string = ride_type->var_00C;
rct_string_id obj_string = ride_type->ride_type[0];
if (obj_string == 0xFF){
obj_string = ride_type->var_00D;
obj_string = ride_type->ride_type[1];
if (obj_string == 0xFF) {
obj_string = ride_type->var_00E;
obj_string = ride_type->ride_type[2];
}
}

View File

@ -41,6 +41,7 @@ static int peep_empty_container_standard_flag(rct_peep* peep);
static int peep_empty_container_extra_flag(rct_peep* peep);
static int peep_should_find_bench(rct_peep* peep);
static void peep_stop_purchase_thought(rct_peep* peep, uint8 ride_type);
static void sub_693BAB(rct_peep* peep);
const char *gPeepEasterEggNames[] = {
"MICHAEL SCHUMACHER",
@ -293,7 +294,7 @@ int peep_update_action(sint16* x, sint16* y, sint16* xy_distance, rct_peep* peep
return 1;
}
int* edi = RCT2_ADDRESS(0x982708, uint32*)[peep->sprite_type * 2];
uint32* edi = RCT2_ADDRESS(0x982708, uint32*)[peep->sprite_type * 2];
uint8* _edi = (uint8*)(edi[peep->action_sprite_type * 2 + 1]);
peep->action_frame++;
int ebx = _edi[peep->action_frame + 1];
@ -378,12 +379,12 @@ void set_sprite_type(rct_peep* peep, uint8 type){
if (peep->state == PEEP_STATE_SITTING){
peep->action = PEEP_ACTION_NONE_1;
peep->var_6F = 7;
RCT2_CALLPROC_X(0x693BAB, 0, 0, 0, 0, (int)peep, 0, 0);
sub_693BAB(peep);
}
if (peep->state == PEEP_STATE_WATCHING){
peep->action = PEEP_ACTION_NONE_1;
peep->var_6F = 2;
RCT2_CALLPROC_X(0x693BAB, 0, 0, 0, 0, (int)peep, 0, 0);
sub_693BAB(peep);
}
}
@ -530,9 +531,8 @@ void peep_update_sprite_type(rct_peep* peep){
void peep_window_state_update(rct_peep* peep){
rct_window* w = window_find_by_number(WC_PEEP, peep->sprite_index);
if (w){
RCT2_CALLPROC_X(w->event_handlers[WE_INVALIDATE], 0, 0, 0, 0, (int)w, 0, 0);
}
if (w != NULL)
window_event_invalidate_call(w);
if (peep->type == PEEP_TYPE_GUEST){
// Update action label
@ -568,7 +568,7 @@ void peep_sprite_remove(rct_peep* peep){
if (peep->type == PEEP_TYPE_GUEST){
window_invalidate_by_class(WC_GUEST_LIST);
RCT2_CALLPROC_X(0x0066E407, 2, 0, peep->sprite_index, 0, 0, 0, 0);
news_item_disable_news(NEWS_ITEM_PEEP_ON_RIDE, peep->sprite_index);
}
else{
window_invalidate_by_class(WC_STAFF_LIST);
@ -578,7 +578,7 @@ void peep_sprite_remove(rct_peep* peep){
sub_6C0C3F();
peep->type = PEEP_TYPE_STAFF;
RCT2_CALLPROC_X(0x0066E407, 3, 0, peep->sprite_index, 0, 0, 0, 0);
news_item_disable_news(NEWS_ITEM_PEEP, peep->sprite_index);
}
sprite_remove((rct_sprite*)peep);
}
@ -756,7 +756,7 @@ void peep_update_sitting(rct_peep* peep){
invalidate_sprite((rct_sprite*)peep);
peep->action = 254;
peep->var_6F = 7;
RCT2_CALLPROC_X(0x693BAB, 0, 0, 0, 0, (int)peep, 0, 0);
sub_693BAB(peep);
peep->sub_state++;
@ -832,8 +832,12 @@ void peep_update_sitting(rct_peep* peep){
}
}
/* rct2: 0x006966A9 */
static void remove_peep_from_queue(rct_peep* peep){
/**
*
* rct2: 0x006966A9
*/
void remove_peep_from_queue(rct_peep* peep)
{
rct_ride* ride = GET_RIDE(peep->current_ride);
uint8 cur_station = peep->current_ride_station;
@ -913,8 +917,8 @@ static void peep_go_to_ride_entrance(rct_peep* peep, rct_ride* ride){
uint8 shift_multiplier = 21;
rct_ride_type* ride_type = GET_RIDE_ENTRY(ride->subtype);
if (ride_type->vehicles[ride_type->var_014].var_12 & (1 << 3) ||
ride_type->vehicles[ride_type->var_014].var_14 & 0x5000){
if (ride_type->vehicles[ride_type->default_vehicle].var_12 & (1 << 3) ||
ride_type->vehicles[ride_type->default_vehicle].var_14 & 0x5000){
shift_multiplier = 32;
}
@ -1110,7 +1114,7 @@ void peep_update_ride_sub_state_1(rct_peep* peep){
if (peep_update_action(&x, &y, &xy_distance, peep))
{
uint8 vehicle = ride_entry->var_014;
uint8 vehicle = ride_entry->default_vehicle;
if (ride_entry->vehicles[vehicle].var_12 & (1 << 3) ||
ride_entry->vehicles[vehicle].var_14 & ((1 << 14) | (1<<12)))
@ -1320,7 +1324,7 @@ static void peep_go_to_ride_exit(rct_peep* peep, rct_ride* ride, sint16 x, sint1
sint16 shift_multiplier = 20;
rct_ride_type* ride_type = GET_RIDE_ENTRY(ride->subtype);
rct_ride_type_vehicle* vehicle_entry = &ride_type->vehicles[ride_type->var_014];
rct_ride_type_vehicle* vehicle_entry = &ride_type->vehicles[ride_type->default_vehicle];
if (vehicle_entry->var_12 & (1 << 3) ||
vehicle_entry->var_14 & 0x5000){
shift_multiplier = 32;
@ -1510,7 +1514,7 @@ static void peep_update_ride_sub_state_2(rct_peep* peep){
if (ride->status == RIDE_STATUS_OPEN &&
++peep->var_AC != 0 &&
!(GET_VEHICLE(ride->vehicles[peep->current_train]))->var_48 & (1 << 4))
!((GET_VEHICLE(ride->vehicles[peep->current_train]))->var_48 & (1 << 4)))
return;
if (ride->mode != RIDE_MODE_FORWARD_ROTATION &&
@ -1642,7 +1646,7 @@ static void peep_update_ride_sub_state_7(rct_peep* peep){
}
ride_entry = GET_RIDE_ENTRY(ride->subtype);
vehicle_entry = &ride_entry->vehicles[ride_entry->var_014];
vehicle_entry = &ride_entry->vehicles[ride_entry->default_vehicle];
uint8 shift_multiplier = 12;
if (vehicle_entry->var_14 & (1 << 14)){
@ -1787,7 +1791,7 @@ static void peep_update_ride_prepare_for_state_9(rct_peep* peep){
sint16 shift_multiplier = 20;
rct_ride_type* ride_type = GET_RIDE_ENTRY(ride->subtype);
rct_ride_type_vehicle* vehicle_entry = &ride_type->vehicles[ride_type->var_014];
rct_ride_type_vehicle* vehicle_entry = &ride_type->vehicles[ride_type->default_vehicle];
if (vehicle_entry->var_14 & 0x5000){
shift_multiplier = 32;
}
@ -1990,7 +1994,7 @@ static void peep_udpate_ride_sub_state_13(rct_peep* peep){
sint16 shift_multiplier = 20;
rct_ride_type* ride_type = GET_RIDE_ENTRY(ride->subtype);
rct_ride_type_vehicle* vehicle_entry = &ride_type->vehicles[ride_type->var_014];
rct_ride_type_vehicle* vehicle_entry = &ride_type->vehicles[ride_type->default_vehicle];
if (vehicle_entry->var_14 & 0x5000){
shift_multiplier = 32;
}
@ -2784,24 +2788,25 @@ static void peep_update_watering(rct_peep* peep){
rct_map_element* map_element = map_get_first_element_at(x / 32, y / 32);
for (;; map_element++){
if (map_element_get_type(map_element) == MAP_ELEMENT_TYPE_SCENERY){
if (abs(((int)peep->next_z) - map_element->base_height) <= 4){
rct_scenery_entry* scenery_entry = g_smallSceneryEntries[map_element->properties.scenery.type];
do{
if (map_element_get_type(map_element) != MAP_ELEMENT_TYPE_SCENERY)
continue;
if (abs(((int)peep->next_z) - map_element->base_height) > 4)
continue;
rct_scenery_entry* scenery_entry = g_smallSceneryEntries[map_element->properties.scenery.type];
if (scenery_entry->small_scenery.flags& SMALL_SCENERY_FLAG6){
map_element->properties.scenery.age = 0;
gfx_invalidate_scrollingtext(x, y, map_element->base_height * 8, map_element->clearance_height * 8);
peep->staff_gardens_watered++;
peep->var_45 |= (1 << 4);
}
}
}
if (map_element_is_last_for_tile(map_element)) {
peep_state_reset(peep);
return;
}
}
if (!(scenery_entry->small_scenery.flags & SMALL_SCENERY_FLAG_CAN_BE_WATERED))
continue;
map_element->properties.scenery.age = 0;
gfx_invalidate_scrollingtext(x, y, map_element->base_height * 8, map_element->clearance_height * 8);
peep->staff_gardens_watered++;
peep->var_45 |= (1 << 4);
} while (!map_element_is_last_for_tile(map_element++));
peep_state_reset(peep);
}
}
@ -2988,7 +2993,7 @@ static void peep_update_watching(rct_peep* peep){
peep->action = 0xFE;
peep->var_6F = 2;
RCT2_CALLPROC_X(0x693BAB, 0, 0, 0, 0, (int)peep, 0, 0);
sub_693BAB(peep);
peep->sub_state++;
@ -3473,8 +3478,8 @@ static void peep_update_using_bin(rct_peep* peep){
uint8 bp = RCT2_ADDRESS(0x97EFCC, uint8)[cur_container];
int x, y;
x = peep->x + scenario_rand() & 7 - 3;
y = peep->y + scenario_rand() & 7 - 3;
x = peep->x + (scenario_rand() & 7) - 3;
y = peep->y + (scenario_rand() & 7) - 3;
RCT2_CALLPROC_X(0x67375D, x, scenario_rand() & 3, y, peep->z, 0, 0, bp);
peep->item_standard_flags &= ~(1 << cur_container);
@ -3504,8 +3509,8 @@ static void peep_update_using_bin(rct_peep* peep){
uint8 bp = RCT2_ADDRESS(0x97EFE8, uint8)[cur_container];
int x, y;
x = peep->x + scenario_rand() & 7 - 3;
y = peep->y + scenario_rand() & 7 - 3;
x = peep->x + (scenario_rand() & 7) - 3;
y = peep->y + (scenario_rand() & 7) - 3;
RCT2_CALLPROC_X(0x67375D, x, scenario_rand() & 3, y, peep->z, 0, 0, bp);
peep->item_extra_flags &= ~(1 << cur_container);
@ -3760,32 +3765,27 @@ static int peep_update_patrolling_find_watering(rct_peep* peep){
do {
if (map_element_get_type(map_element) != MAP_ELEMENT_TYPE_SCENERY){
map_element++;
continue;
}
uint8 z_diff = abs(peep->next_z - map_element->base_height);
if (z_diff >= 4){
map_element++;
continue;
}
rct_scenery_entry* sceneryEntry = g_smallSceneryEntries[map_element->properties.scenery.type];
if (!(sceneryEntry->small_scenery.flags & SMALL_SCENERY_FLAG_CAN_BE_WATERED)){
map_element++;
continue;
}
if (map_element->properties.scenery.age < 55){
if (chosen_position >= 4){
map_element++;
continue;
}
if (map_element->properties.scenery.age < 40){
map_element++;
continue;
}
}
@ -3801,7 +3801,7 @@ static int peep_update_patrolling_find_watering(rct_peep* peep){
peep->destination_tolerence = 3;
return 1;
} while (!map_element_is_last_for_tile(map_element));
} while (!map_element_is_last_for_tile(map_element++));
}
return 0;
}
@ -5308,3 +5308,18 @@ void peep_set_map_tooltip(rct_peep *peep)
RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 12, uint32) = arg1;
}
}
void sub_693BAB(rct_peep* peep) {
uint8 bl = peep->var_6F;
if (bl != peep->action_sprite_type) {
invalidate_sprite((rct_sprite*)peep);
peep->action_sprite_type = bl;
uint8* edx = RCT2_ADDRESS(0x98270C, uint8*)[peep->sprite_type * 2];
peep->sprite_width = edx[bl * 4];
peep->sprite_height_negative = edx[bl * 4 + 1];
peep->sprite_height_positive = edx[bl * 4 + 2];
invalidate_sprite((rct_sprite*)peep);
}
}

View File

@ -583,5 +583,6 @@ void peep_insert_new_thought(rct_peep *peep, uint8 thought_type, uint8 thought_a
void peep_set_map_tooltip(rct_peep *peep);
void sub_693B58(rct_peep* peep);
void remove_peep_from_queue(rct_peep* peep);
#endif

View File

@ -255,7 +255,7 @@ void sub_6C0C3F()
if (peep->type == PEEP_TYPE_STAFF && staff_type == peep->staff_type)
{
for (register uint8 i = 0; i < 128; ++i)
RCT2_ADDRESS(0x13B0E72 + (staff_type + STAFF_MAX_COUNT) * 512, uint32)[i] |= RCT2_ADDRESS(0x13B0E72 + (peep->staff_id * 512) * 512, uint32)[i];
RCT2_ADDRESS(0x13B0E72 + (staff_type + STAFF_MAX_COUNT) * 512, uint32)[i] |= RCT2_ADDRESS(0x13B0E72 + peep->staff_id * 512, uint32)[i];
}
}
@ -291,4 +291,24 @@ int mechanic_is_location_in_patrol(rct_peep *mechanic, int x, int y)
return 1;
return staff_is_location_in_patrol_area(mechanic, x, y);
}
/**
*
* rct2: 0x006C1955
*/
void staff_reset_stats()
{
uint16 spriteIndex;
rct_peep *peep;
FOR_ALL_STAFF(spriteIndex, peep) {
peep->time_in_park = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONTH_YEAR, uint16);
peep->staff_lawns_mown = 0;
peep->staff_rides_fixed = 0;
peep->staff_gardens_watered = 0;
peep->staff_rides_inspected = 0;
peep->staff_litter_swept = 0;
peep->staff_bins_emptied = 0;
}
}

View File

@ -44,7 +44,9 @@ enum STAFF_ORDERS{
STAFF_ORDERS_SWEEPING = (1 << 0),
STAFF_ORDERS_WATER_FLOWERS = (1 << 1),
STAFF_ORDERS_EMPTY_BINS = (1 << 2),
STAFF_ORDERS_MOWING = (1 << 3)
STAFF_ORDERS_MOWING = (1 << 3),
STAFF_ORDERS_INSPECT_RIDES = (1 << 0),
STAFF_ORDERS_FIX_RIDES = (1 << 1)
};
void game_command_update_staff_colour(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp);
@ -54,5 +56,6 @@ void update_staff_colour(uint8 staffType, uint16 color);
uint16 hire_new_staff_member(uint8 staffType);
void sub_6C0C3F();
int mechanic_is_location_in_patrol(rct_peep *mechanic, int x, int y);
void staff_reset_stats();
#endif

View File

@ -20,8 +20,8 @@
#ifdef _WIN32
#include <shlobj.h>
#include <windows.h>
#include <shlobj.h>
#include <SDL_syswm.h>
#include "../addresses.h"
#include "../cmdline.h"

1105
src/rct1.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -343,5 +343,10 @@ typedef struct{
uint16 start_track_data_AA_CF; // 0xC4
}rct_track_td4; // Information based off RCTTechDepot
bool rct1_read_sc4(const char *path, rct1_s4 *s4);
bool rct1_read_sv4(const char *path, rct1_s4 *s4);
void rct1_import_s4(rct1_s4 *s4);
void rct1_fix_landscape();
#endif

View File

@ -43,6 +43,7 @@
#include "world/map.h"
#include "world/park.h"
#include "world/climate.h"
#include "world/scenery.h"
#include "world/sprite.h"
typedef struct tm tm_t;
@ -94,7 +95,7 @@ int rct2_init()
gfx_load_g1();
gfx_load_character_widths();
platform_init();
audio_init1();//RCT2_CALLPROC_EBPSAFE(0x006BA8E0); // init_audio();
audio_init1();
viewport_init_all();
news_item_init_queue();
get_local_time();
@ -103,13 +104,13 @@ int rct2_init()
reset_sprite_list();
ride_init_all();
window_guest_list_init_vars_a();
sub_6BD3A4();// RCT2_CALLPROC_EBPSAFE(0x006BD3A4); //Peep?
sub_6BD3A4();
map_init(150);
park_init();
RCT2_CALLPROC_EBPSAFE(0x0066B5C0); // 0x0066B5C0 (part of 0x0066B3E8) screen_game_create_windows()
window_title_menu_open();
date_reset();
climate_reset(CLIMATE_COOL_AND_WET);
RCT2_CALLPROC_EBPSAFE(0x006DFEE4);
scenery_set_default_placement_configuration();
window_new_ride_init_vars();
window_guest_list_init_vars_b();
window_staff_list_init_vars();

View File

@ -735,7 +735,7 @@ static void ride_remove_peeps(int rideIndex)
peep_decrement_num_riders(peep);
if (peep->state == PEEP_STATE_QUEUING_FRONT && peep->sub_state == 0)
RCT2_CALLPROC_X(0x006966A9, 0, 0, 0, 0, (int)peep, 0, 0);
remove_peep_from_queue(peep);
invalidate_sprite((rct_sprite*)peep);
@ -1714,14 +1714,18 @@ rct_peep *find_closest_mechanic(int x, int y, int forInspection)
if (peep->staff_type != STAFF_TYPE_MECHANIC)
continue;
if (forInspection) {
if ((peep->state != PEEP_STATE_HEADING_TO_INSPECTION || peep->sub_state >= 4) && peep->state != PEEP_STATE_PATROLLING)
if (!forInspection) {
if (peep->state == PEEP_STATE_HEADING_TO_INSPECTION){
if (peep->sub_state >= 4)
continue;
}
else if (peep->state != PEEP_STATE_PATROLLING)
continue;
if (!(peep->staff_orders & 2))
if (!(peep->staff_orders & STAFF_ORDERS_FIX_RIDES))
continue;
} else {
if (peep->state != PEEP_STATE_PATROLLING || !(peep->staff_orders & 1))
if (peep->state != PEEP_STATE_PATROLLING || !(peep->staff_orders & STAFF_ORDERS_INSPECT_RIDES))
continue;
}
@ -3590,3 +3594,81 @@ bool ride_type_has_flag(int rideType, int flag)
{
return (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + (rideType * 8), uint32) & flag) != 0;
}
/*
* The next six functions are helpers to access ride data at the offset 10E &
* 110. We believe it stores three distinct values in the following format:
*
* unknown1: bits 9-11
* unknown2: bits 6-8
* unknown3: low 5 bits
*/
int get_var_10E_unk_1(rct_ride* ride) {
return (ride->var_10E >> 8) & 0x7;
}
int get_var_10E_unk_2(rct_ride* ride) {
return (ride->var_10E >> 5) & 0x7;
}
int get_var_10E_unk_3(rct_ride* ride) {
return ride->var_10E & 0x1F;
}
int get_var_110_unk_1(rct_ride* ride) {
return (ride->var_110 >> 8) & 0x7;
}
int get_var_110_unk_2(rct_ride* ride) {
return (ride->var_110 >> 5) & 0x7;
}
int get_var_110_unk_3(rct_ride* ride) {
return ride->var_110 & 0x1F;
}
int get_var_112_unk_1(rct_ride* ride) {
return (ride->var_112 >> 11) & 0x3F;
}
int get_var_112_unk_2(rct_ride* ride) {
return (ride->var_112 >> 8) & 7;
}
int get_var_112_unk_3(rct_ride* ride) {
return (ride->var_112 >> 5) & 7;
}
int get_var_112_unk_4(rct_ride* ride) {
return ride->var_112 & 0x1F;
}
bool ride_has_spinning_tunnel(rct_ride *ride) {
return ride->special_track_elements & RIDE_ELEMENT_TUNNEL_SPLASH_OR_RAPIDS;
}
bool ride_has_water_splash(rct_ride *ride) {
return ride->special_track_elements & RIDE_ELEMENT_TUNNEL_SPLASH_OR_RAPIDS;
}
bool ride_has_rapids(rct_ride *ride) {
return ride->special_track_elements & RIDE_ELEMENT_TUNNEL_SPLASH_OR_RAPIDS;
}
bool ride_has_log_reverser(rct_ride *ride) {
return ride->special_track_elements & RIDE_ELEMENT_REVERSER_OR_WATERFALL;
}
bool ride_has_waterfall(rct_ride *ride) {
return ride->special_track_elements & RIDE_ELEMENT_REVERSER_OR_WATERFALL;
}
bool ride_has_whirlpool(rct_ride *ride) {
return ride->special_track_elements & RIDE_ELEMENT_WHIRLPOOL;
}
uint8 ride_get_helix_sections(rct_ride *ride) {
// Helix sections stored in the low 5 bits.
return ride->special_track_elements & 0x1F;
}

View File

@ -97,32 +97,33 @@ typedef struct{
* size: unknown
*/
typedef struct {
rct_string_id name; // 0x000
rct_string_id description; // 0x002
uint32 images_offset; // 0x004
rct_string_id name; // 0x000
rct_string_id description; // 0x002
uint32 images_offset; // 0x004
uint32 var_008;
// 0xC, D, E are related
uint8 var_00C;
uint8 var_00D;
uint8 var_00E;
uint8 min_cars_in_train; // 0x00F
uint8 max_cars_in_train; // 0x010
uint8 var_011;
uint8 var_012;
uint8 var_013;
uint8 var_014;
uint8 pad_015[0x5];
rct_ride_type_vehicle vehicles[4]; // 0x1A
uint8 ride_type[3]; // 0x00C
uint8 min_cars_in_train; // 0x00F
uint8 max_cars_in_train; // 0x010
uint8 cars_per_flat_ride; // 0x011
uint8 zero_cars; // 0x012
uint8 tab_vehicle; // 0x013
uint8 default_vehicle; // 0x014
uint8 front_vehicle; // 0x015
uint8 second_vehicle; // 0x016
uint8 rear_vehicle; // 0x017
uint8 third_vehicle; // 0x018
uint8 pad_019;
rct_ride_type_vehicle vehicles[4]; // 0x1A
uint32 var_1AE;
sint8 excitement_multipler; // 0x1B2
sint8 intensity_multipler; // 0x1B3
sint8 nausea_multipler; // 0x1B4
uint8 pad_1B5;
uint32 var_1B6;
uint8 pad_1BA[0x04];
uint8 category[2]; // 0x1BE
uint8 shop_item; // 0x1C0
uint8 shop_item_secondary; // 0x1C1
sint8 excitement_multipler; // 0x1B2
sint8 intensity_multipler; // 0x1B3
sint8 nausea_multipler; // 0x1B4
uint8 max_height; // 0x1B5
uint32 enabledTrackPieces; // 0x1B6
uint32 enabledTrackPiecesAdditional; // 0x1BA
uint8 category[2]; // 0x1BE
uint8 shop_item; // 0x1C0
uint8 shop_item_secondary; // 0x1C1
} rct_ride_type;
/**
@ -172,11 +173,17 @@ typedef struct {
};
uint8 pad_0D1[0x3];
uint8 measurement_index; // 0x0D4
uint8 var_0D5;
uint8 pad_0D6[0x2];
// bits 0 through 4 are the number of helix sections
// bit 5: spinning tunnel, water splash, or rapids
// bit 6: log reverser, waterfall
// bit 7: whirlpool
uint8 special_track_elements; // 0x0D5
uint8 pad_0D6[2];
// Divide this value by 29127 to get the human-readable max speed
// (in RCT2, display_speed = (max_speed * 9) >> 18)
sint32 max_speed; // 0x0D8
sint32 average_speed; // 0x0DC
uint8 pad_0E0[0x4];
uint8 pad_0E0[4];
sint32 length[4]; // 0x0E4
uint16 time[4]; // 0x0F4
fixed16_2dp max_positive_vertical_g; // 0x0FC
@ -193,9 +200,9 @@ typedef struct {
uint8 drops; // 0x115 (??XX XXXX)
uint8 pad_116;
uint8 highest_drop_height; // 0x117
uint32 var_118;
uint8 pad_11C[0x02];
uint8 var_11E;
sint32 sheltered_length; // 0x118
uint8 pad_11C[0x2];
uint8 num_sheltered_sections; // 0x11E
uint8 var_11F;
sint16 var_120;
sint16 var_122;
@ -644,6 +651,13 @@ enum {
RIDE_MEASUREMENT_FLAG_G_FORCES = 1 << 2
};
// Constants for ride->special_track_elements
enum {
RIDE_ELEMENT_TUNNEL_SPLASH_OR_RAPIDS = 1 << 5,
RIDE_ELEMENT_REVERSER_OR_WATERFALL = 1 << 6,
RIDE_ELEMENT_WHIRLPOOL = 1 << 7
};
enum {
RIDE_TYPE_FLAG_HAS_TRACK_COLOUR_MAIN = 1 << 0,
RIDE_TYPE_FLAG_HAS_TRACK_COLOUR_ADDITIONAL = 1 << 1,
@ -751,6 +765,25 @@ void ride_set_name(int rideIndex, const char *name);
void game_command_set_ride_name(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp);
void game_command_set_ride_setting(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp);
int get_var_10E_unk_1(rct_ride* ride);
int get_var_10E_unk_2(rct_ride* ride);
int get_var_10E_unk_3(rct_ride* ride);
int get_var_110_unk_1(rct_ride* ride);
int get_var_110_unk_2(rct_ride* ride);
int get_var_110_unk_3(rct_ride* ride);
int get_var_112_unk_1(rct_ride* ride);
int get_var_112_unk_2(rct_ride* ride);
int get_var_112_unk_3(rct_ride* ride);
int get_var_112_unk_4(rct_ride* ride);
uint8 ride_get_helix_sections(rct_ride *ride);
bool ride_has_spinning_tunnel(rct_ride *ride);
bool ride_has_water_splash(rct_ride *ride);
bool ride_has_rapids(rct_ride *ride);
bool ride_has_log_reverser(rct_ride *ride);
bool ride_has_waterfall(rct_ride *ride);
bool ride_has_whirlpool(rct_ride *ride);
bool ride_type_has_flag(int rideType, int flag);
#endif

View File

@ -881,3 +881,97 @@ const rct_ride_entrance_definition RideEntranceDefinitions[12] = {
{ 22840, 33, 19 }, // RIDE_ENTRANCE_STYLE_PAGODA
{ 22856, 33, 2 } // RIDE_ENTRANCE_STYLE_SPACE
};
// Data read from 0x0097D7C9 4 bytes at a time
const uint8 RideLiftHillAdjustments[0x60] = {
7, // Spiral Roller coaster
4, // Stand Up Coaster
4, // Suspended Swinging
5, // Inverted
4, // Steel Mini Coaster
5, // Mini Railroad
5, // Monorail
4, // Mini Suspended Coaster
5, // Bumper Boats
4, // Wooden Wild Mine/Mouse
4, // Steeplechase/Motorbike/Soap Box Derby
5, // Car Ride
5, // Launched Freefall
4, // Bobsleigh Coaster
5, // Observation Tower
4, // Looping Roller Coaster
4, // Dinghy Slide
4, // Mine Train Coaster
5, // Chairlift
4, // Corkscrew Roller Coaster
5, // Maze
5, // Spiral Slide
5, // Go Karts
5, // Log Flume
5, // River Rapids
5, // Bumper Cars
5, // Pirate Ship
5, // Swinging Inverter Ship
5, // Food Stall
5, // (none)
5, // Drink Stall
5, // (none)
5, // Shop (all types)
5, // Merry Go Round
5, // Balloon Stall (maybe)
5, // Information Kiosk
5, // Bathroom
5, // Ferris Wheel
5, // Motion Simulator
5, // 3D Cinema
5, // Gravitron
5, // Space Rings
5, // Reverse Freefall Coaster
5, // Elevator
4, // Vertical Drop Roller Coaster
5, // ATM
5, // Twist
5, // Haunted House
5, // First Aid
5, // Circus Show
5, // Ghost Train
5, // Twister Roller Coaster
5, // Wooden Roller Coaster
3, // Side-Friction Roller Coaster
4, // Wild Mouse
4, // Multi Dimension Coaster
4, // (none)
4, // Flying Roller Coaster
4, // (none)
3, // Virginia Reel
5, // Splash Boats
5, // Mini Helicopters
4, // Lay-down Roller Coaster
5, // Suspended Monorail
4, // (none)
3, // Reverser Roller Coaster
4, // Heartline Twister Roller Coaster
5, // Mini Golf
5, // Giga Coaster
5, // Roto-Drop
5, // Flying Saucers
5, // Crooked House
5, // Monorail Cycles
4, // Compact Inverted Coaster
4, // Water Coaster
5, // Air Powered Vertical Coaster
4, // Inverted Hairpin Coaster
5, // Magic Carpet
5, // Submarine Ride
5, // River Rafts
5, // (none)
5, // Enterprise
5, // (none)
5, // (none)
5, // (none)
4, // (none)
4, // Inverted Impulse Coaster
4, // Mini Roller Coaster
5, // Mine Ride
4 // LIM Launched Roller Coaster
};

View File

@ -49,5 +49,6 @@ extern const uint8 RideAvailableModes[];
extern const uint8 RideAvailableBreakdowns[];
extern const rct_ride_entrance_definition RideEntranceDefinitions[12];
extern const uint8 RideLiftHillAdjustments[0x60];
#endif
#endif

View File

@ -436,7 +436,7 @@ static uint16 ride_compute_upkeep(rct_ride *ride)
dl = dl & 3;
upkeep += trackCost * dl;
uint32 totalLength = (ride->length[0] + ride->length[1] + ride->length[2] + ride->length[3]) >> 16;
uint32 totalLength = ride_get_total_length(ride) >> 16;
// The data originally here was 20's and 0's. The 20's all represented
// rides that had tracks. The 0's were fixed rides like crooked house or
@ -572,7 +572,7 @@ static void set_unreliability_factor(rct_ride *ride)
// possibility. Range is [3, 7]. values are here:
// https://gist.github.com/kevinburke/123977c4884ccadbec70. Consider
// inlining this per ride
uint8 lift_speed_adjustment = RCT2_ADDRESS(0x0097D7C9, uint8)[ride->type * 4];
uint8 lift_speed_adjustment = RideLiftHillAdjustments[ride->type];
ride->unreliability_factor += (ride->lift_hill_speed - lift_speed_adjustment) * 2;
}
@ -599,17 +599,179 @@ static int sub_65E72D(rct_ride *ride)
return edx & 0xFFFF;
}
static rating_tuple get_var_10E_rating(rct_ride* ride) {
int var_10E_unk_1 = get_var_10E_unk_1(ride);
int var_10E_unk_2 = get_var_10E_unk_2(ride);
int var_10E_unk_3 = get_var_10E_unk_3(ride);
int excitement = (var_10E_unk_1 * 0x28000) >> 16;
excitement += var_10E_unk_2 * 3;
excitement += (var_10E_unk_3 * 63421) >> 16;
int intensity = (var_10E_unk_1 * 81920) >> 16;
intensity += (var_10E_unk_2 * 49152) >> 16;
intensity += (var_10E_unk_3 * 21140) >> 16;
int nausea = var_10E_unk_1 * 5;
nausea += (var_10E_unk_2 * 0x3200) >> 16;
nausea += (var_10E_unk_3 * 42281) >> 16;
rating_tuple rating = { excitement, intensity, nausea };
return rating;
}
/**
* rct2: 0x0065DF72
*/
static rating_tuple get_var_110_rating(rct_ride* ride) {
int var_10E_unk_1 = get_var_10E_unk_1(ride);
int var_10E_unk_2 = get_var_10E_unk_2(ride);
int var_10E_unk_3 = get_var_10E_unk_3(ride);
int excitement = (var_10E_unk_1 * 0x3c000) >> 16;
excitement += (var_10E_unk_2 * 0x3c000) >> 16;
excitement += (var_10E_unk_3 * 73992) >> 16;
int intensity = (var_10E_unk_1 * 0x14000) >> 16;
intensity += (var_10E_unk_2 * 49152) >> 16;
intensity += (var_10E_unk_3 * 21140) >> 16;
int nausea = var_10E_unk_1 * 5;
nausea += (var_10E_unk_2 * 0x32000) >> 16;
nausea += (var_10E_unk_3 * 48623) >> 16;
rating_tuple rating = { excitement, intensity, nausea };
return rating;
}
/**
* rct2: 0x0065E047
*/
static rating_tuple get_var_112_rating(rct_ride *ride) {
int al;
al = get_var_112_unk_1(ride);
al = min(al, 4);
int excitement = (al * 0x78000) >> 16;
al = get_var_112_unk_1(ride);
al = min(al, 8);
int nausea = (al * 0x78000) >> 16;
al = get_var_112_unk_2(ride);
al = min(al, 6);
excitement += (al * 273066) >> 16;
al = get_var_112_unk_3(ride);
al = min(al, 6);
excitement += (al * 0x3aaaa) >> 16;
al = get_var_112_unk_4(ride);
al = min(al, 7);
excitement += (al * 187245) >> 16;
rating_tuple rating = { excitement, 0, nausea };
return rating;
}
/**
* rct2: 0x0065E0F2
*/
static rating_tuple get_inversions_ratings(uint8 inversions) {
inversions = inversions & 0x1F;
int a = min(inversions, 6);
int excitement = (a * 0x1aaaaa) >> 16;
int intensity = inversions * 5;
int nausea = (inversions * 0x15aaaa) >> 16;
rating_tuple rating = { excitement, intensity, nausea };
return rating;
}
/*
*
*/
static rating_tuple get_special_track_elements_rating(uint8 type, rct_ride *ride) {
int excitement = 0, intensity = 0, nausea = 0;
if (type == RIDE_TYPE_GHOST_TRAIN) {
if (ride_has_spinning_tunnel(ride)) {
excitement += 40;
intensity += 25;
nausea += 55;
}
} else if (type == RIDE_TYPE_LOG_FLUME) {
// Reverser for log flume
if (ride_has_log_reverser(ride)) {
excitement += 48;
intensity += 55;
nausea += 65;
}
} else {
if (ride_has_water_splash(ride)) {
excitement += 50;
intensity += 30;
nausea += 20;
}
if (ride_has_waterfall(ride)) {
excitement += 55;
intensity += 30;
}
if (ride_has_whirlpool(ride)) {
excitement += 35;
intensity += 20;
nausea += 23;
}
}
uint8 helix_sections = ride_get_helix_sections(ride);
int al = min(helix_sections, 9);
excitement += (al * 254862) >> 16;
al = min(helix_sections, 11);
intensity += (al * 148945) >> 16;
al = max(helix_sections - 5, 0);
al = min(al, 10);
nausea += (al * 0x140000) >> 16;
rating_tuple rating = { excitement, intensity, nausea };
return rating;
}
/**
* rct2: 0x0065DDD1
*/
static rating_tuple sub_65DDD1(rct_ride *ride)
{
int eax, ebx, ecx, edx, esi, edi, ebp;
edi = (int)ride;
RCT2_CALLFUNC_X(0x0065DDD1, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
int excitement = 0, intensity = 0, nausea = 0;
rating_tuple rating = { ebx, ecx, ebp };
rating_tuple special_track_element_rating = get_special_track_elements_rating(ride->type, ride);
excitement += special_track_element_rating.excitement;
intensity += special_track_element_rating.intensity;
nausea += special_track_element_rating.nausea;
rating_tuple var_10E_rating = get_var_10E_rating(ride);
excitement += var_10E_rating.excitement;
intensity += var_10E_rating.intensity;
nausea += var_10E_rating.nausea;
rating_tuple var_110_rating = get_var_110_rating(ride);
excitement += var_110_rating.excitement;
intensity += var_110_rating.intensity;
nausea += var_110_rating.nausea;
rating_tuple var_112_rating = get_var_112_rating(ride);
excitement += var_112_rating.excitement;
intensity += var_112_rating.intensity;
nausea += var_112_rating.nausea;
rating_tuple inversions_rating = get_inversions_ratings(ride->inversions);
excitement += inversions_rating.excitement;
intensity += inversions_rating.intensity;
nausea += inversions_rating.nausea;
rating_tuple rating = { excitement, intensity, nausea };
return rating;
}
@ -619,11 +781,34 @@ static rating_tuple sub_65DDD1(rct_ride *ride)
*/
static rating_tuple sub_65E1C2(rct_ride *ride)
{
int eax, ebx, ecx, edx, esi, edi, ebp;
edi = (int)ride;
RCT2_CALLFUNC_X(0x0065E1C2, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
int sheltered_length_shifted = (ride->sheltered_length) >> 16;
uint32 eax = min(sheltered_length_shifted, 1000);
int excitement = (eax * 9175) >> 16;
rating_tuple rating = { ebx, ecx, ebp };
eax = min(sheltered_length_shifted, 2000);
int intensity = (eax * 0x2666) >> 16;
eax = min(sheltered_length_shifted, 1000);
int nausea = (eax * 0x4000) >> 16;
/*eax = (ride->var_11C * 30340) >> 16;*/
/*nausea += eax;*/
if (ride->num_sheltered_sections & 0x40) {
excitement += 20;
nausea += 15;
}
if (ride->num_sheltered_sections & 0x20) {
excitement += 20;
nausea += 15;
}
uint8 lowerval = ride->num_sheltered_sections & 0x1F;
lowerval = min(lowerval, 11);
excitement += (lowerval * 774516) >> 16;
rating_tuple rating = { excitement, intensity, nausea };
return rating;
}
@ -653,7 +838,7 @@ static rating_tuple ride_ratings_get_gforce_ratings(rct_ride *ride)
// Apply lateral G force factor
result.excitement += (min(FIXED_2DP(1,50), ride->max_lateral_g) * 26214) >> 16;
result.intensity += (ride->max_lateral_g * 65536) >> 16;
result.intensity += ride->max_lateral_g;
result.nausea += (ride->max_lateral_g * 21845) >> 16;
// Very high lateral G force penalty
@ -765,7 +950,7 @@ static void ride_ratings_calculate_mine_train_coaster(rct_ride *ride)
ratings.nausea = RIDE_RATING(2,10);
// Apply length of ride factor
totalLength = (ride->length[0] + ride->length[1] + ride->length[2] + ride->length[3]) >> 16;
totalLength = ride_get_total_length(ride) >> 16;
ratings.excitement += (min(6000, totalLength) * 764) >> 16;
// Apply racing coaster factor
@ -883,7 +1068,7 @@ static void ride_ratings_calculate_maze(rct_ride *ride)
// Apply size factor
int unk = min(ride->maze_tiles, 100);
ratings.excitement += unk;
ratings.intensity += unk / 2;
ratings.intensity += unk * 2;
ratings.excitement += (ride_ratings_get_scenery_score(ride) * 22310) >> 16;
@ -1241,11 +1426,11 @@ static void ride_ratings_calculate_elevator(rct_ride *ride)
ratings.nausea = RIDE_RATING(0,30);
// Apply length factor
totalLength = ride->length[0] + ride->length[1] + ride->length[2] + ride->length[3];
ratings.excitement += ((totalLength >> 16) * 45875) >> 16;
totalLength = ride_get_total_length(ride) >> 16;
ratings.excitement += (totalLength * 45875) >> 16;
ratings.excitement += (sub_65E277() * 11183) >> 16;
ratings.excitement += (ride_ratings_get_scenery_score(ride) * 83662) >> 16;
ratings.nausea += ((totalLength >> 16) * 26214) >> 16;
ratings.nausea += (totalLength * 26214) >> 16;
ride_ratings_apply_intensity_penalty(&ratings);
ride_ratings_apply_adjustments(ride, &ratings);
@ -1343,7 +1528,7 @@ static void ride_ratings_calculate_mini_golf(rct_ride *ride)
ratings.nausea = RIDE_RATING(0,00);
// Apply length factor
int length = (ride->length[0] + ride->length[1] + ride->length[2] + ride->length[3]) >> 16;
int length = ride_get_total_length(ride) >> 16;
ratings.excitement += (min(6000, length) * 873) >> 16;
// Apply ?

View File

@ -448,10 +448,10 @@ void track_load_list(ride_list_item item)
//RCT2_CALLPROC_X(0x006CED50, 0, 0, 0, *((uint16*)&item), 0, 0, 0);
}
static void read(void *dst, void **src, int length)
static void read(void *dst, char **src, int length)
{
memcpy(dst, *src, length);
*((char**)src) += length;
*src += length;
}
/**
@ -553,13 +553,13 @@ rct_track_td6* load_track_design(const char *path)
// Edit the colours to use the new versions
// Unsure why it is 67
edi = (uint8*)&track_design->vehicle_colours;
for (i = 0; i < 67; i++)
*edi++ = RCT2_ADDRESS(0x0097F0BC, uint8)[*edi];
for (i = 0; i < 67; i++, edi++)
*edi = RCT2_ADDRESS(0x0097F0BC, uint8)[*edi];
// Edit the colours to use the new versions
edi = (uint8*)&track_design->track_spine_colour;
for (i = 0; i < 12; i++)
*edi++ = RCT2_ADDRESS(0x0097F0BC, uint8)[*edi];
for (i = 0; i < 12; i++, edi++)
*edi = RCT2_ADDRESS(0x0097F0BC, uint8)[*edi];
// Highest drop height is 1bit = 3/4 a meter in td6
// Highest drop height is 1bit = 1/3 a meter in td4
@ -1349,3 +1349,132 @@ int save_track_design(uint8 rideIndex){
gfx_invalidate_screen();
return 1;
}
/**
*
* rct2: 0x006D399D
*/
rct_track_design *temp_track_get_info(char* path, uint8** preview)
{
rct_track_design *trackDesign;
uint8 *trackDesignList = RCT2_ADDRESS(RCT2_ADDRESS_TRACK_LIST, uint8);
int i;
trackDesign = NULL;
// Check if track design has already been loaded
for (i = 0; i < 4; i++) {
if (RCT2_ADDRESS(RCT2_ADDRESS_TRACK_DESIGN_INDEX_CACHE, uint32)[i] == 0) {
trackDesign = &RCT2_GLOBAL(RCT2_ADDRESS_TRACK_DESIGN_CACHE, rct_track_design*)[i];
break;
}
}
if (trackDesign == NULL) {
// Load track design
i = RCT2_GLOBAL(RCT2_ADDRESS_TRACK_DESIGN_NEXT_INDEX_CACHE, uint32)++;
if (RCT2_GLOBAL(RCT2_ADDRESS_TRACK_DESIGN_NEXT_INDEX_CACHE, uint32) >= 4)
RCT2_GLOBAL(RCT2_ADDRESS_TRACK_DESIGN_NEXT_INDEX_CACHE, uint32) = 0;
RCT2_ADDRESS(RCT2_ADDRESS_TRACK_DESIGN_INDEX_CACHE, uint32)[i] = 0;
rct_track_td6* loaded_track = NULL;
log_verbose("Loading track: %s", path);
if (!(loaded_track = load_track_design(path))) {
if (preview != NULL) *preview = NULL;
log_error("Failed to load track: %s", path);
return NULL;
}
trackDesign = &RCT2_GLOBAL(RCT2_ADDRESS_TRACK_DESIGN_CACHE, rct_track_design*)[i];
object_unload_all();
if (loaded_track->type == RIDE_TYPE_NULL){
if (preview != NULL) *preview = NULL;
log_error("Failed to load track (ride type null): %s", path);
return NULL;
}
if (!object_load(0, &loaded_track->vehicle_object, NULL)){
if (preview != NULL) *preview = NULL;
log_error("Failed to load track (vehicle load fail): %s", path);
return NULL;
}
// Copy the track design apart from the preview image
memcpy(&trackDesign->track_td6, loaded_track, sizeof(rct_track_td6));
// Load in a new preview image, calculate cost variable, calculate var_06
draw_track_preview((uint8**)trackDesign->preview);
//RCT2_CALLPROC_X(0x006D1EF0, 0, 0, 0, 0, 0, (int)&trackDesign->preview, 0);
trackDesign->track_td6.cost = RCT2_GLOBAL(RCT2_ADDRESS_TRACK_DESIGN_COST, money32);
trackDesign->track_td6.var_06 = RCT2_GLOBAL(0x00F44151, uint8) & 7;
}
// Set preview to correct preview image based on rotation
if (preview != NULL)
*preview = trackDesign->preview[RCT2_GLOBAL(RCT2_ADDRESS_TRACK_PREVIEW_ROTATION, uint8)];
return trackDesign;
}
void window_track_list_format_name(char *dst, const char *src, char colour, char quotes)
{
if (colour != 0)
*dst++ = colour;
if (quotes != 0)
*dst++ = FORMAT_OPENQUOTES;
while (*src != '.' && *src != 0) {
*dst++ = *src++;
}
if (quotes != 0)
*dst++ = FORMAT_ENDQUOTES;
*dst = 0;
}
/**
*
* rct2: 0x006D40B2
* returns 0 for copy fail, 1 for success, 2 for file exists.
*/
int install_track(char* source_path, char* dest_name){
// Make a copy of the track name (no extension)
char track_name[MAX_PATH] = { 0 };
char* dest = track_name;
char* dest_name_pointer = dest_name;
while (*dest_name_pointer != '.') *dest++ = *dest_name_pointer++;
// Check if .TD4 file exists under that name
char* temp_extension_pointer = dest;
strcat(track_name, ".TD4");
char dest_path[MAX_PATH];
subsitute_path(dest_path, RCT2_ADDRESS(RCT2_ADDRESS_TRACKS_PATH, char), track_name);
if (platform_file_exists(dest_path))
return 2;
// Allow a concat onto the track_name but before extension
*temp_extension_pointer = '\0';
// Check if .TD6 file exists under that name
strcat(track_name, ".TD6");
subsitute_path(dest_path, RCT2_ADDRESS(RCT2_ADDRESS_TRACKS_PATH, char), track_name);
if (platform_file_exists(dest_path))
return 2;
// Set path for actual copy
subsitute_path(dest_path, RCT2_ADDRESS(RCT2_ADDRESS_TRACKS_PATH, char), dest_name);
return platform_file_copy(source_path, dest_path);
}

View File

@ -411,6 +411,7 @@ extern const rct_trackdefinition *gTrackDefinitions;
void track_load_list(ride_list_item item);
int sub_67726A(const char *path);
rct_track_design *track_get_info(int index, uint8** preview);
rct_track_design *temp_track_get_info(char* path, uint8** preview);
rct_track_td6* load_track_design(const char *path);
int track_rename(const char *text);
int track_delete();
@ -418,5 +419,7 @@ void reset_track_list_cache();
int track_is_connected_by_shape(rct_map_element *a, rct_map_element *b);
int sub_6D01B3(int bl, int x, int y, int z);
int save_track_design(uint8 rideIndex);
int install_track(char* source_path, char* dest_name);
void window_track_list_format_name(char *dst, const char *src, char colour, char quotes);
#endif

View File

@ -229,7 +229,7 @@ void vehicle_sounds_update()
vehicle_sound->id = (uint16)-1;
}
label26:
1;
;
}
//for (rct_vehicle_sound_params* vehicle_sound_params = &RCT2_GLOBAL(0x00F438B4, rct_vehicle_sound_params); ; vehicle_sound_params++) {
@ -534,7 +534,7 @@ void vehicle_sounds_update()
}
}
label114:
1;
;
}
}
}

View File

@ -30,6 +30,7 @@
#include "management/research.h"
#include "management/news_item.h"
#include "object.h"
#include "peep/staff.h"
#include "platform/platform.h"
#include "ride/ride.h"
#include "scenario.h"
@ -38,6 +39,7 @@
#include "util/util.h"
#include "world/map.h"
#include "world/park.h"
#include "world/scenery.h"
#include "world/sprite.h"
#include "world/water.h"
@ -174,7 +176,7 @@ int scenario_load(const char *path)
reset_loaded_objects();
map_update_tile_pointers();
reset_0x69EBE4();// RCT2_CALLPROC_EBPSAFE(0x0069EBE4);
reset_0x69EBE4();
return 1;
}
@ -258,7 +260,7 @@ int scenario_load_and_play_from_path(const char *path)
if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, sint32) & PARK_FLAGS_NO_MONEY_SCENARIO)
RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, sint32) |= PARK_FLAGS_NO_MONEY;
sub_684AC3();
RCT2_CALLPROC_EBPSAFE(0x006DFEE4);
scenery_set_default_placement_configuration();
news_item_init_queue();
if (RCT2_GLOBAL(RCT2_ADDRESS_OBJECTIVE_TYPE, uint8) != OBJECTIVE_NONE)
window_park_objective_open();
@ -322,9 +324,9 @@ int scenario_load_and_play_from_path(const char *path)
award_reset();
reset_all_ride_build_dates();
date_reset();
RCT2_CALLPROC_EBPSAFE(0x00674576);
duck_remove_all();
park_calculate_size();
RCT2_CALLPROC_EBPSAFE(0x006C1955);
staff_reset_stats();
RCT2_GLOBAL(0x01358840, uint8) = 0;
memset((void*)0x001358102, 0, 20);
RCT2_GLOBAL(0x00135882E, uint16) = 0;
@ -1133,7 +1135,7 @@ int scenario_save(char *path, int flags)
fclose(file);
if (!(flags & 0x80000000))
reset_loaded_objects();//RCT2_CALLPROC_EBPSAFE(0x006A9FC0);
reset_loaded_objects();
gfx_invalidate_screen();
RCT2_GLOBAL(0x009DEA66, uint16) = 0;

View File

@ -256,8 +256,8 @@ typedef struct {
uint16 suggested_max_guests;
uint16 word_0135883E;
uint8 word_01358840;
uint8 word_01358841;
uint8 pad_01358842[4];
uint8 rct1_water_colour;
uint8 pad_01358842[2];
rct_research_item research_items[500];
uint16 word_01359208;
char scenario_name[64];

View File

@ -18,6 +18,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/
#include <time.h>
#include "addresses.h"
#include "audio/audio.h"
#include "config.h"
@ -37,6 +38,7 @@
#include "world/climate.h"
#include "world/map.h"
#include "world/park.h"
#include "world/scenery.h"
#include "world/sprite.h"
static const int gOldMusic = 0;
@ -93,7 +95,7 @@ void title_load()
log_verbose("loading title");
if (RCT2_GLOBAL(RCT2_ADDRESS_GAME_PAUSED, uint8) & 1)
RCT2_CALLPROC_X(0x00667C15, 0, 1, 0, 0, 0, 0, 0);//Game pause toggle
pause_toggle();
RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) = SCREEN_FLAGS_TITLE_DEMO;
@ -102,17 +104,17 @@ void title_load()
reset_sprite_list();
ride_init_all();
window_guest_list_init_vars_a();
sub_6BD3A4(); // RCT2_CALLPROC_EBPSAFE(0x006BD3A4);
sub_6BD3A4();
map_init(150);
park_init();
date_reset();
climate_reset(CLIMATE_COOL_AND_WET);
RCT2_CALLPROC_EBPSAFE(0x006DFEE4);
scenery_set_default_placement_configuration();
window_new_ride_init_vars();
window_guest_list_init_vars_b();
window_staff_list_init_vars();
map_update_tile_pointers(); //RCT2_CALLPROC_EBPSAFE(0x0068AFFD);
reset_0x69EBE4();// RCT2_CALLPROC_EBPSAFE(0x0069EBE4);
map_update_tile_pointers();
reset_0x69EBE4();
viewport_init_all();
news_item_init_queue();
title_create_windows();
@ -130,14 +132,12 @@ void title_load()
*/
static void title_create_windows()
{
// RCT2_CALLPROC_EBPSAFE(0x0066B3E8);
window_main_open();
window_title_menu_open();
window_title_exit_open();
window_title_options_open();
window_title_logo_open();
RCT2_CALLPROC_EBPSAFE(0x0066B905);
window_resize_gui(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, sint16), RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_HEIGHT, sint16));
}
/**
@ -206,7 +206,7 @@ static void title_update_showcase()
sub_69E9A7();
window_new_ride_init_vars();
sub_684AC3();
RCT2_CALLPROC_EBPSAFE(0x006DFEE4);
scenery_set_default_placement_configuration();
news_item_init_queue();
gfx_invalidate_screen();
RCT2_GLOBAL(0x009DEA66, sint16) = 0;

View File

@ -81,6 +81,32 @@ long fsize(FILE *fp)
return size;
}
bool readentirefile(const char *path, void **outBuffer, long *outLength)
{
FILE *fp;
long fpLength;
void *fpBuffer;
// Open file
fp = fopen(path, "rb");
if (fp == NULL)
return 0;
// Get length
fseek(fp, 0, SEEK_END);
fpLength = ftell(fp);
rewind(fp);
// Read whole file into a buffer
fpBuffer = malloc(fpLength);
fread(fpBuffer, fpLength, 1, fp);
fclose(fp);
*outBuffer = fpBuffer;
*outLength = fpLength;
return 1;
}
int bitscanforward(int source)
{
int i;

View File

@ -30,6 +30,7 @@ int mph_to_kmph(int mph);
const char *path_get_filename(const char *path);
void path_set_extension(char *path, const char *extension);
long fsize(FILE *fp);
bool readentirefile(const char *path, void **outBuffer, long *outLength);
int bitscanforward(int source);
bool strequals(const char *a, const char *b, int length, bool caseInsensitive);

View File

@ -29,6 +29,7 @@
#include "../scenario.h"
#include "../sprites.h"
#include "../world/climate.h"
#include "../world/footpath.h"
#include "../world/park.h"
#include "../world/sprite.h"
@ -70,7 +71,8 @@ enum WINDOW_CHEATS_WIDGET_IDX {
WIDX_REMOVE_LITTER,
WIDX_WIN_SCENARIO,
WIDX_RENEW_RIDES = 8,
WIDX_REMOVE_SIX_FLAGS
WIDX_REMOVE_SIX_FLAGS,
WIDX_MAKE_DESTRUCTIBLE
};
#pragma region MEASUREMENTS
@ -155,8 +157,9 @@ static rct_widget window_cheats_rides_widgets[] = {
{ 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_CLOSEBOX, 1, XPL(0), WPL(0), YPL(7), HPL(7), 5123, STR_NONE}, // Renew rides
{ WWT_CLOSEBOX, 1, XPL(0), WPL(0), YPL(8), HPL(8), 5124, STR_NONE}, // Remove flags
{ 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
{ WIDGETS_END },
};
@ -315,7 +318,7 @@ static uint32 window_cheats_page_enabled_widgets[] = {
(1 << WIDX_CLOSE) | (1 << WIDX_TAB_1) | (1 << WIDX_TAB_2) | (1 << WIDX_TAB_3) | (1 << WIDX_TAB_4) | (1 << WIDX_HIGH_MONEY) | (1 << WIDX_PARK_ENTRANCE_FEE),
(1 << WIDX_CLOSE) | (1 << WIDX_TAB_1) | (1 << WIDX_TAB_2) | (1 << WIDX_TAB_3) | (1 << WIDX_TAB_4) | (1 << WIDX_HAPPY_GUESTS) | (1 << WIDX_TRAM_GUESTS),
(1 << WIDX_CLOSE) | (1 << WIDX_TAB_1) | (1 << WIDX_TAB_2) | (1 << WIDX_TAB_3) | (1 << WIDX_TAB_4) | (1 << WIDX_FREEZE_CLIMATE) | (1 << WIDX_OPEN_CLOSE_PARK) | (1 << WIDX_DECREASE_GAME_SPEED) | (1 << WIDX_INCREASE_GAME_SPEED) | (1 << WIDX_ZERO_CLEARANCE) | (1 << WIDX_WEATHER_SUN) | (1 << WIDX_WEATHER_THUNDER) | (1 << WIDX_CLEAR_GRASS) | (1 << WIDX_MOWED_GRASS) | (1 << WIDX_WATER_PLANTS) | (1 << WIDX_FIX_VANDALISM) | (1 << WIDX_REMOVE_LITTER) | (1 << WIDX_WIN_SCENARIO),
(1 << WIDX_CLOSE) | (1 << WIDX_TAB_1) | (1 << WIDX_TAB_2) | (1 << WIDX_TAB_3) | (1 << WIDX_TAB_4) | (1 << WIDX_RENEW_RIDES) | (1 << WIDX_REMOVE_SIX_FLAGS)
(1 << WIDX_CLOSE) | (1 << WIDX_TAB_1) | (1 << WIDX_TAB_2) | (1 << WIDX_TAB_3) | (1 << WIDX_TAB_4) | (1 << WIDX_RENEW_RIDES) | (1 << WIDX_REMOVE_SIX_FLAGS) | (1 << WIDX_MAKE_DESTRUCTIBLE)
};
static void window_cheats_draw_tab_images(rct_drawpixelinfo *dpi, rct_window *w);
@ -430,6 +433,18 @@ static void cheat_remove_six_flags()
window_invalidate_by_class(WC_RIDE);
}
static void cheat_make_destructible()
{
int i;
rct_ride *ride;
FOR_ALL_RIDES(i, ride)
{
if (ride->lifecycle_flags & RIDE_LIFECYCLE_INDESTRUCTIBLE)
ride->lifecycle_flags&=~RIDE_LIFECYCLE_INDESTRUCTIBLE;
}
window_invalidate_by_class(WC_RIDE);
}
static void cheat_clear_loan()
{
// TODO, this sets the loan but stops loan borrowing from working, possible due to cheat detection stuff
@ -631,6 +646,9 @@ static void window_cheats_rides_mouseup()
case WIDX_REMOVE_SIX_FLAGS:
cheat_remove_six_flags();
break;
case WIDX_MAKE_DESTRUCTIBLE:
cheat_make_destructible();
break;
}
}
@ -754,17 +772,16 @@ static void window_cheats_misc_tool_update()
map_invalidate_selection_rect();
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) &= ~(1 << 0);
int temp_y = y + 16;
int eax = x, ecx = 0, edx = widgetIndex, edi = 0, esi = (int)w, ebp = 0;
RCT2_CALLFUNC_X(0x689726, &eax, &temp_y, &ecx, &edx, &esi, &edi, &ebp);
if (eax != 0x8000){
int map_x, map_y;
footpath_get_coordinates_from_pos(x, y + 16, &map_x, &map_y, NULL, NULL);
if (map_x != 0x8000){
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) |= 1;
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_TYPE, uint16) = 4;
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_X, uint16) = eax;
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_X, uint16) = eax;
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_Y, uint16) = temp_y;
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_Y, uint16) = temp_y;
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_X, uint16) = map_x;
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_X, uint16) = map_x;
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_Y, uint16) = map_y;
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_Y, uint16) = map_y;
map_invalidate_selection_rect();
}
@ -781,9 +798,8 @@ static void window_cheats_misc_tool_down()
if (widgetIndex != WIDX_ZERO_CLEARANCE) return;
int dest_x = x, dest_y = y, ecx = 0, edx = widgetIndex, edi = 0, esi = (int)w, ebp = 0;
dest_y += 16;
RCT2_CALLFUNC_X(0x689726, &dest_x, &dest_y, &ecx, &edx, &esi, &edi, &ebp);
int dest_x, dest_y;
footpath_get_coordinates_from_pos(x, y + 16, &dest_x, &dest_y, NULL, NULL);
if (dest_x == 0x8000)return;

View File

@ -31,6 +31,7 @@
#include "../platform/platform.h"
#include "../title.h"
#include "../util/util.h"
#include "../world/scenery.h"
#include "error.h"
enum {
@ -167,7 +168,7 @@ void window_editor_bottom_toolbar_jump_back_to_object_selection() {
void window_editor_bottom_toolbar_jump_back_to_landscape_editor() {
window_close_all();
RCT2_CALLPROC_EBPSAFE(0x006DFED0);
RCT2_CALLPROC_EBPSAFE(0x006DFEE4);
scenery_set_default_placement_configuration();
g_editor_step = EDITOR_STEP_LANDSCAPE_EDITOR;
window_map_open();
gfx_invalidate_screen();
@ -228,7 +229,7 @@ void window_editor_bottom_toolbar_jump_forward_from_object_selection()
RCT2_CALLPROC_EBPSAFE(0x0066F6E3);
} else {
RCT2_CALLPROC_EBPSAFE(0x006DFED0);
RCT2_CALLPROC_EBPSAFE(0x006DFEE4);
scenery_set_default_placement_configuration();
RCT2_GLOBAL(0x00141F570, uint8) = 1;
window_map_open();
gfx_invalidate_screen();

View File

@ -24,6 +24,7 @@
#include "../interface/widget.h"
#include "../interface/window.h"
#include "../localisation/localisation.h"
#include "../management/research.h"
#include "../object.h"
#include "../ride/track.h"
#include "../scenario.h"
@ -255,8 +256,8 @@ static void window_editor_object_selection_close()
reset_loaded_objects();
object_free_scenario_text();
RCT2_CALLPROC_EBPSAFE(0x6AB316);
RCT2_CALLPROC_EBPSAFE(0x685675);
RCT2_CALLPROC_EBPSAFE(0x68585B);
research_populate_list_random();
research_remove_non_separate_vehicle_types();
window_new_ride_init_vars();
}
@ -302,12 +303,7 @@ static void window_editor_object_selection_mouseup()
}
window_invalidate(w);
int eax, ebx, ecx, edx, esi, edi, ebp;
RCT2_CALLFUNC_X(0x00674FCE, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
if (eax == 1) {
window_close(w);
RCT2_CALLPROC_EBPSAFE(0x006D386D);
}
window_loadsave_open(LOADSAVETYPE_LOAD | LOADSAVETYPE_TRACK);
break;
}
}
@ -610,8 +606,8 @@ static void window_editor_object_selection_paint()
text++;
} while (*(text - 1) != 0);
text += 4;
text += *text++ * 16;
text += *text++ * 16;
text += *text * 16 + 1;
text += *text * 16 + 1;
if (RCT2_GLOBAL(text, uint32) & 0x1000000) {
strcpy(stringBuffer, name);
@ -819,7 +815,7 @@ static void window_editor_object_selection_manage_tracks()
RCT2_GLOBAL(0xF44157, uint8) = entry_index;
rct_ride_type* ride_entry = GET_RIDE_ENTRY(entry_index);
uint8* ride_type_array = &ride_entry->var_00C;
uint8* ride_type_array = &ride_entry->ride_type[0];
int ride_type;
for (int i = 0; (ride_type = ride_type_array[i]) == 0xFF; i++);

View File

@ -1513,8 +1513,8 @@ static void window_finances_set_page(rct_window *w, int page)
w->width = 530;
w->height = 257;
}
RCT2_CALLPROC_X(w->event_handlers[WE_RESIZE], 0, 0, 0, 0, (int)w, 0, 0);
RCT2_CALLPROC_X(w->event_handlers[WE_INVALIDATE], 0, 0, 0, 0, (int)w, 0, 0);
window_event_resize_call(w);
window_event_invalidate_call(w);
window_init_scroll_widgets(w);
window_invalidate(w);

View File

@ -673,7 +673,7 @@ 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, 0xFFDE, &x, &y, &z, &mapElement);
get_map_coordinates_from_pos(x, y, 0xFFDE, &x, &y, &z, &mapElement, NULL);
if (z == 0) {
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) &= ~(1 << 0);
@ -716,7 +716,7 @@ static void window_footpath_set_selection_start_bridge_at_point(int screenX, int
map_invalidate_selection_rect();
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) &= ~(1 << 0) & ~(1 << 2);
sub_68A0C9(screenX, screenY, &x, &y, &direction, &mapElement);
footpath_bridge_get_info_from_pos(screenX, screenY, &x, &y, &direction, &mapElement);
if (x == 0x8000)
return;
@ -760,7 +760,7 @@ static void window_footpath_place_path_at_point(int x, int y)
footpath_provisional_update();
get_map_coordinates_from_pos(x, y, 0xFFDE, &x, &y, &z, &mapElement);
get_map_coordinates_from_pos(x, y, 0xFFDE, &x, &y, &z, &mapElement, NULL);
if (z == 0)
return;
@ -794,7 +794,7 @@ static void window_footpath_start_bridge_at_point(int screenX, int screenY)
int x, y, z, direction;
rct_map_element *mapElement;
sub_68A0C9(screenX, screenY, &x, &y, &direction, &mapElement);
footpath_bridge_get_info_from_pos(screenX, screenY, &x, &y, &direction, &mapElement);
if (x == 0x8000)
return;

View File

@ -32,6 +32,7 @@
#include "../interface/viewport.h"
#include "../interface/widget.h"
#include "../interface/window.h"
#include "../world/footpath.h"
#include "dropdown.h"
#include "error.h"
@ -568,7 +569,7 @@ void window_guest_overview_resize(){
window_get_register(w);
window_guest_disable_widgets(w);
RCT2_CALLPROC_X(w->event_handlers[WE_INVALIDATE], 0, 0, 0, 0, (int)w, 0, 0);
window_event_invalidate_call(w);
widget_invalidate(w, WIDX_MARQUEE);
@ -676,10 +677,8 @@ void window_guest_set_page(rct_window* w, int page){
w->widgets = window_guest_page_widgets[page];
window_guest_disable_widgets(w);
window_invalidate(w);
RCT2_CALLPROC_X(w->event_handlers[WE_RESIZE], 0, 0, 0, 0, (int)w, 0, 0);
RCT2_CALLPROC_X(w->event_handlers[WE_INVALIDATE], 0, 0, 0, 0, (int)w, 0, 0);
window_event_resize_call(w);
window_event_invalidate_call(w);
window_init_scroll_widgets(w);
window_invalidate(w);
@ -730,7 +729,7 @@ void window_guest_viewport_init(rct_window* w){
}
if (peep->x == SPRITE_LOCATION_NULL && final_check){
rct_ride* ride = &(RCT2_ADDRESS(RCT2_ADDRESS_RIDE_LIST, rct_ride)[peep->current_ride]);
int x = ride->overall_view & 0xFF * 32 + 16;
int x = (ride->overall_view & 0xFF) * 32 + 16;
int y = (ride->overall_view >> 8) * 32 + 16;
int height = map_element_height(x, y);
height += 32;
@ -768,7 +767,7 @@ void window_guest_viewport_init(rct_window* w){
viewport_flags |= VIEWPORT_FLAG_GRIDLINES;
}
RCT2_CALLPROC_X(w->event_handlers[WE_INVALIDATE], 0, 0, 0, 0, (int)w, 0, 0);
window_event_invalidate_call(w);
w->viewport_focus_coordinates.x = focus.coordinate.x;
w->viewport_focus_coordinates.y = focus.coordinate.y;
@ -1143,24 +1142,23 @@ void window_guest_overview_tool_update(){
map_invalidate_selection_rect();
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) &= ~(1 << 0);
int temp_y = y + 16;
int eax = x, ecx = 0, edx = widgetIndex, edi = 0, esi = (int)w, ebp = 0;
RCT2_CALLFUNC_X(0x689726, &eax, &temp_y, &ecx, &edx, &esi, &edi, &ebp);
if (eax != 0x8000){
int map_x, map_y;
footpath_get_coordinates_from_pos(x, y + 16, &map_x, &map_y, NULL, NULL);
if (map_x != 0x8000){
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) |= 1;
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_TYPE, uint16) = 4;
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_X, uint16) = eax;
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_X, uint16) = eax;
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_Y, uint16) = temp_y;
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_Y, uint16) = temp_y;
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_X, uint16) = map_x;
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_X, uint16) = map_x;
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_A_Y, uint16) = map_y;
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_B_Y, uint16) = map_y;
map_invalidate_selection_rect();
}
RCT2_GLOBAL(RCT2_ADDRESS_PICKEDUP_PEEP_SPRITE, sint32) = -1;
int ebx;
get_map_coordinates_from_pos(x, y, 0, NULL, NULL, &ebx, NULL);
get_map_coordinates_from_pos(x, y, 0, NULL, NULL, &ebx, NULL, NULL);
if (ebx == 0)
return;
@ -1176,8 +1174,8 @@ void window_guest_overview_tool_update(){
ebx = (RCT2_ADDRESS(0x982708, uint32*)[peep->sprite_type * 2])[22];
ebx += w->var_492 >> 2;
ebp = peep->tshirt_colour << 19;
ecx = peep->trousers_colour << 24;
int ebp = peep->tshirt_colour << 19;
int ecx = peep->trousers_colour << 24;
ebx |= ebp | ecx | 0xA0000000;
RCT2_GLOBAL(RCT2_ADDRESS_PICKEDUP_PEEP_SPRITE, uint32) = ebx;
@ -1193,9 +1191,9 @@ void window_guest_overview_tool_down(){
if (widgetIndex != WIDX_PICKUP) return;
int dest_x = x, dest_y = y, ecx = 0, edx = widgetIndex, edi = 0, esi = (int)w, ebp = 0;
dest_y += 16;
RCT2_CALLFUNC_X(0x689726, &dest_x, &dest_y, &ecx, &edx, &esi, &edi, &ebp);
int dest_x, dest_y;
rct_map_element *mapElement;
footpath_get_coordinates_from_pos(x, y + 16, &dest_x, &dest_y, NULL, &mapElement);
if (dest_x == 0x8000)return;
@ -1207,7 +1205,7 @@ void window_guest_overview_tool_down(){
int tile_y = dest_y & 0xFFE0;
int tile_x = dest_x & 0xFFE0;
int dest_z = ((uint8*)edx)[2] * 8 + 16;
int dest_z = mapElement->base_height * 8 + 16;
if (!map_is_location_owned(tile_x, tile_y, dest_z)){
window_error_open(0x785,-1);

492
src/windows/install_track.c Normal file
View File

@ -0,0 +1,492 @@
/*****************************************************************************
* Copyright (c) 2014 Ted John
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
*
* This file is part of OpenRCT2.
*
* OpenRCT2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/
#include "../addresses.h"
#include "../audio/audio.h"
#include "../editor.h"
#include "../localisation/localisation.h"
#include "../interface/widget.h"
#include "../interface/window.h"
#include "../ride/ride.h"
#include "../ride/track.h"
#include "../sprites.h"
#include "error.h"
enum {
WIDX_BACKGROUND,
WIDX_TITLE,
WIDX_CLOSE,
WIDX_TRACK_PREVIEW,
WIDX_ROTATE,
WIDX_TOGGLE_SCENERY,
WIDX_INSTALL,
WIDX_CANCEL
};
static rct_widget window_install_track_widgets[] = {
{ WWT_FRAME, 0, 0, 401, 0, 399, 0xFFFFFFFF, STR_NONE },
{ WWT_CAPTION, 0, 1, 400, 1, 14, 2309, STR_WINDOW_TITLE_TIP },
{ WWT_CLOSEBOX, 0, 389, 399, 2, 13, STR_CLOSE_X, STR_CLOSE_WINDOW_TIP },
{ WWT_FLATBTN, 0, 15, 386, 18, 236, 0xFFFFFFFF, STR_NONE },
{ WWT_FLATBTN, 0, 376, 399, 374, 397, 5169, STR_ROTATE_90_TIP },
{ WWT_FLATBTN, 0, 376, 399, 350, 373, 5171, STR_TOGGLE_SCENERY_TIP },
{ WWT_DROPDOWN_BUTTON, 0, 303, 397, 241, 252, 3378, STR_NONE },
{ WWT_DROPDOWN_BUTTON, 0, 303, 397, 256, 267, 3379, STR_NONE },
{ WIDGETS_END },
};
static void window_install_track_emptysub() { }
static void window_install_track_close();
static void window_install_track_mouseup();
static void window_install_track_invalidate();
static void window_install_track_paint();
static void window_install_track_text_input();
static void* window_install_track_events[] = {
(uint32*)window_install_track_close,
(uint32*)window_install_track_mouseup,
(uint32*)window_install_track_emptysub,
(uint32*)window_install_track_emptysub,
(uint32*)window_install_track_emptysub,
(uint32*)window_install_track_emptysub,
(uint32*)window_install_track_emptysub,
(uint32*)window_install_track_emptysub,
(uint32*)window_install_track_emptysub,
(uint32*)window_install_track_emptysub,
(uint32*)window_install_track_emptysub,
(uint32*)window_install_track_emptysub,
(uint32*)window_install_track_emptysub,
(uint32*)window_install_track_emptysub,
(uint32*)window_install_track_emptysub,
(uint32*)window_install_track_emptysub,
(uint32*)window_install_track_emptysub,
(uint32*)window_install_track_emptysub,
(uint32*)window_install_track_emptysub,
(uint32*)window_install_track_text_input,
(uint32*)window_install_track_emptysub,
(uint32*)window_install_track_emptysub,
(uint32*)window_install_track_emptysub,
(uint32*)window_install_track_emptysub,
(uint32*)window_install_track_emptysub,
(uint32*)window_install_track_invalidate,
(uint32*)window_install_track_paint,
(uint32*)window_install_track_emptysub
};
ride_list_item _window_install_track_item;
char track_dest_name[MAX_PATH];
char track_path[MAX_PATH];
/**
*
* rct2: 0x006D386D
*/
void window_install_track_open(const char* path)
{
rct_window *w;
int x, y;
void *mem;
window_close_by_class(WC_EDITOR_OBJECT_SELECTION);
window_close_construction_windows();
ride_list_item item = {
.type = 0xFF,
.entry_index = 0
};
_window_install_track_item = item;
mem = malloc(1285292);
if (mem == NULL)
return;
RCT2_GLOBAL(RCT2_ADDRESS_TRACK_DESIGN_CACHE, void*) = mem;
RCT2_GLOBAL(RCT2_ADDRESS_TRACK_DESIGN_SCENERY_TOGGLE, uint8) = 0;
RCT2_GLOBAL(RCT2_ADDRESS_TRACK_PREVIEW_ROTATION, uint8) = 2;
reset_track_list_cache();
x = RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, uint16) / 2 - 201;
y = max(28, RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_HEIGHT, uint16) / 2 - 200);
w = window_create(x, y, 402, 400, (uint32*)window_install_track_events, WC_INSTALL_TRACK, 0);
w->widgets = window_install_track_widgets;
w->enabled_widgets = (1 << WIDX_CLOSE) | (1 << WIDX_ROTATE) | (1 << WIDX_TOGGLE_SCENERY) | (1 << WIDX_INSTALL) | (1 << WIDX_CANCEL);
window_init_scroll_widgets(w);
w->colours[0] = 26;
w->colours[1] = 26;
w->colours[2] = 26;
w->track_list.var_482 = 0;
w->track_list.var_484 = 0;
window_push_others_right(w);
memset(track_path, 0, MAX_PATH - 1);
strcpy(track_path, path);
char* track_name_pointer = track_path;
while (*track_name_pointer++ != '\0');
while (*--track_name_pointer != '\\');
track_name_pointer++;
strcpy(track_dest_name, track_name_pointer);
window_invalidate(w);
}
/**
*
* rct2: 0x006CFB82
*/
static void window_install_track_select(rct_window *w, int index)
{
uint8 *trackDesignItem, *trackDesignList = RCT2_ADDRESS(RCT2_ADDRESS_TRACK_LIST, uint8);
rct_track_design *trackDesign;
w->track_list.var_480 = index;
sound_play_panned(SOUND_CLICK_1, w->x + (w->width / 2), 0, 0, 0);
if (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_TRACK_MANAGER) && index == 0) {
window_close(w);
ride_construct_new(_window_install_track_item);
return;
}
if (RCT2_GLOBAL(0x00F44153, uint8) != 0)
RCT2_GLOBAL(RCT2_ADDRESS_TRACK_DESIGN_SCENERY_TOGGLE, uint8) = 1;
if (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_TRACK_MANAGER))
index--;
trackDesignItem = trackDesignList + (index * 128);
RCT2_GLOBAL(0x00F4403C, uint8*) = trackDesignItem;
window_track_list_format_name(
(char*)0x009BC313,
trackDesignItem,
RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_TRACK_MANAGER ?
0 :
FORMAT_WHITE,
1);
char track_path[MAX_PATH] = { 0 };
subsitute_path(track_path, (char*)RCT2_ADDRESS_TRACKS_PATH, trackDesignItem);
if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_TRACK_MANAGER) {
window_track_manage_open();
return;
}
if (!load_track_design(track_path)) {
w->track_list.var_480 = 0xFFFF;
window_invalidate(w);
return;
}
trackDesign = track_get_info(index, NULL);
if (trackDesign == NULL) return;
if (trackDesign->track_td6.var_06 & 4)
window_error_open(STR_THIS_DESIGN_WILL_BE_BUILT_WITH_AN_ALTERNATIVE_VEHICLE_TYPE, -1);
window_close(w);
window_track_place_open();
}
/**
*
* rct2: 0x006D41DC
*/
static void window_install_track_close()
{
free(RCT2_GLOBAL(RCT2_ADDRESS_TRACK_DESIGN_CACHE, void*));
}
/**
*
* rct2: 0x006D407A
*/
static void window_install_track_mouseup()
{
rct_window *w;
short widgetIndex, result;
window_widget_get_registers(w, widgetIndex);
switch (widgetIndex) {
case WIDX_CLOSE:
case WIDX_CANCEL:
window_close(w);
break;
case WIDX_ROTATE:
RCT2_GLOBAL(RCT2_ADDRESS_TRACK_PREVIEW_ROTATION, uint8)++;
RCT2_GLOBAL(RCT2_ADDRESS_TRACK_PREVIEW_ROTATION, uint8) %= 4;
window_invalidate(w);
break;
case WIDX_TOGGLE_SCENERY:
RCT2_GLOBAL(RCT2_ADDRESS_TRACK_DESIGN_SCENERY_TOGGLE, uint8) ^= 1;
reset_track_list_cache();
window_invalidate(w);
break;
case WIDX_INSTALL:
result = install_track(track_path, track_dest_name);
if (result == 1)
window_close(w);
else if(result == 0){
window_error_open(3380, 3382);
window_close(w);
}
else{
// Copy the track name into the string buffer.
window_track_list_format_name(RCT2_ADDRESS(0x009BC677, char), track_dest_name, 0, 0);
window_text_input_open(w, WIDX_INSTALL, 3383, 3384, 3165, 0, 255);
}
break;
}
}
/**
*
* rct2: 0x006D3B06
*/
static void window_install_track_invalidate()
{
rct_window *w;
window_get_register(w);
w->pressed_widgets |= 1 << WIDX_TRACK_PREVIEW;
if (RCT2_GLOBAL(RCT2_ADDRESS_TRACK_DESIGN_SCENERY_TOGGLE, uint8) == 0)
w->pressed_widgets |= (1 << WIDX_TOGGLE_SCENERY);
else
w->pressed_widgets &= ~(1 << WIDX_TOGGLE_SCENERY);
if (w->track_list.var_482 != 0xFFFF) {
w->disabled_widgets &= ~(1 << WIDX_TRACK_PREVIEW);
}
else {
w->disabled_widgets |= (1 << WIDX_TRACK_PREVIEW);
}
}
/**
*
* rct2: 0x006D3B1F
*/
static void window_install_track_paint()
{
rct_window *w;
rct_drawpixelinfo *dpi;
rct_widget *widget;
rct_track_design *trackDesign = NULL;
uint8 *image, *trackDesignList = RCT2_ADDRESS(RCT2_ADDRESS_TRACK_LIST, uint8);
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);
window_paint_get_registers(w, dpi);
window_draw_widgets(w, dpi);
if (w->track_list.var_482 == 0xFFFF)
return;
// Track preview
widget = &window_install_track_widgets[WIDX_TRACK_PREVIEW];
x = w->x + widget->left + 1;
y = w->y + widget->top + 1;
colour = RCT2_GLOBAL(0x0141FC44 + (w->colours[0] * 8), uint8);
gfx_fill_rect(dpi, x, y, x + 369, y + 216, colour);
//call 6d3993 (load track)
trackDesign = temp_track_get_info(track_path, &image);
if (trackDesign == NULL)
return;
rct_track_td6* track_td6 = &trackDesign->track_td6;
subsituteElement = &g1Elements[0];
tmpElement = *subsituteElement;
subsituteElement->offset = image;
subsituteElement->width = 370;
subsituteElement->height = 217;
subsituteElement->x_offset = 0;
subsituteElement->y_offset = 0;
subsituteElement->flags = G1_FLAG_BMP;
gfx_draw_sprite(dpi, 0, x, y, 0);
*subsituteElement = tmpElement;
x = w->x + (widget->left + widget->right) / 2;
y = w->y + widget->bottom - 12;
RCT2_GLOBAL(0x00F44153, uint8) = 0;
// Warnings
if (track_td6->var_06 & 1) {
RCT2_GLOBAL(0x00F44153, uint8) = 1;
if (RCT2_GLOBAL(RCT2_ADDRESS_TRACK_DESIGN_SCENERY_TOGGLE, uint8) == 0) {
// Scenery not available
gfx_draw_string_centred_clipped(dpi, STR_DESIGN_INCLUDES_SCENERY_WHICH_IS_UNAVAILABLE, NULL, 0, x, y, 368);
y -= 10;
}
}
// Track design name
window_track_list_format_name((char*)0x009BC677, (char*)0x009E3504, FORMAT_WINDOW_COLOUR_1, 1);
gfx_draw_string_centred_clipped(dpi, 3165, NULL, 0, x, y, 368);
// Information
x = w->x + widget->left + 1;
y = w->y + widget->bottom + 2;
// 0x006D3CF1 -- 0x006d3d71 missing
if (track_td6->var_6C & 0x80000000) {
// Six flags logo
gfx_draw_sprite(dpi, SPR_SIX_FLAGS, w->x + widget->right - 50, y + 4, 0);
}
// Stats
rating = track_td6->excitement * 10;
gfx_draw_string_left(dpi, STR_TRACK_LIST_EXCITEMENT_RATING, &rating, 0, x, y);
y += 10;
rating = track_td6->intensity * 10;
gfx_draw_string_left(dpi, STR_TRACK_LIST_INTENSITY_RATING, &rating, 0, x, y);
y += 10;
rating = track_td6->nausea * 10;
gfx_draw_string_left(dpi, STR_TRACK_LIST_NAUSEA_RATING, &rating, 0, x, y);
y += 14;
if (track_td6->type != RIDE_TYPE_MAZE) {
if (track_td6->type == RIDE_TYPE_MINI_GOLF) {
// Holes
holes = track_td6->holes & 0x1F;
gfx_draw_string_left(dpi, STR_HOLES, &holes, 0, x, y);
y += 10;
}
else {
// Maximum speed
speed = ((track_td6->max_speed << 16) * 9) >> 18;
gfx_draw_string_left(dpi, STR_MAX_SPEED, &speed, 0, x, y);
y += 10;
// Average speed
speed = ((track_td6->average_speed << 16) * 9) >> 18;
gfx_draw_string_left(dpi, STR_AVERAGE_SPEED, &speed, 0, x, y);
y += 10;
}
// Ride length
RCT2_GLOBAL(0x013CE952 + 0, uint16) = 1345;
RCT2_GLOBAL(0x013CE952 + 2, uint16) = track_td6->ride_length;
gfx_draw_string_left_clipped(dpi, STR_TRACK_LIST_RIDE_LENGTH, (void*)0x013CE952, 0, x, y, 214);
y += 10;
}
if (ride_type_has_flag(track_td6->type, RIDE_TYPE_FLAG_HAS_G_FORCES)) {
// Maximum positive vertical Gs
gForces = track_td6->max_positive_vertical_g * 32;
gfx_draw_string_left(dpi, STR_MAX_POSITIVE_VERTICAL_G, &gForces, 0, x, y);
y += 10;
// Maximum negative verical Gs
gForces = track_td6->max_negitive_vertical_g * 32;
gfx_draw_string_left(dpi, STR_MAX_NEGATIVE_VERTICAL_G, &gForces, 0, x, y);
y += 10;
// Maximum lateral Gs
gForces = track_td6->max_lateral_g * 32;
gfx_draw_string_left(dpi, STR_MAX_LATERAL_G, &gForces, 0, x, y);
y += 10;
if (track_td6->var_07 / 4 >= 2) {
if (track_td6->total_air_time != 0) {
// Total air time
airTime = track_td6->total_air_time * 25;
gfx_draw_string_left(dpi, STR_TOTAL_AIR_TIME, &airTime, 0, x, y);
y += 10;
}
}
}
if (ride_type_has_flag(track_td6->type, RIDE_TYPE_FLAG_HAS_DROPS)) {
// Drops
drops = track_td6->drops & 0x3F;
gfx_draw_string_left(dpi, STR_DROPS, &drops, 0, x, y);
y += 10;
// Drop height is multiplied by 0.75
dropHeight = (track_td6->highest_drop_height + (track_td6->highest_drop_height / 2)) / 2;
gfx_draw_string_left(dpi, STR_HIGHEST_DROP_HEIGHT, &drops, 0, x, y);
y += 10;
}
if (track_td6->type != RIDE_TYPE_MINI_GOLF) {
inversions = track_td6->inversions & 0x1F;
if (inversions != 0) {
// Inversions
gfx_draw_string_left(dpi, STR_INVERSIONS, &inversions, 0, x, y);
y += 10;
}
}
y += 4;
if (track_td6->space_required_x != 0xFF) {
// Space required
RCT2_GLOBAL(0x013CE952 + 0, uint16) = track_td6->space_required_x;
RCT2_GLOBAL(0x013CE952 + 2, uint16) = track_td6->space_required_y;
gfx_draw_string_left(dpi, STR_TRACK_LIST_SPACE_REQUIRED, (void*)0x013CE952, 0, x, y);
y += 10;
}
if (track_td6->cost != 0) {
gfx_draw_string_left(dpi, STR_TRACK_LIST_COST_AROUND, &track_td6->cost, 0, x, y);
y += 14;
}
}
/**
*
* rct2: 0x006D40A7
*/
static void window_install_track_text_input(){
short widgetIndex;
rct_window *w;
char _cl;
char* text;
window_text_input_get_registers(w, widgetIndex, _cl, text);
if (_cl == 0)
{
window_close(w);
return;
}
if (widgetIndex == WIDX_INSTALL){
char* extension_pointer = track_dest_name;
while (*extension_pointer++ != '.');
--extension_pointer;
strcat(text, extension_pointer);
strcpy(track_dest_name, text);
window_event_mouse_up_call(w, WIDX_INSTALL);
}
}

View File

@ -154,6 +154,9 @@ rct_window *window_loadsave_open(int type)
case (LOADSAVETYPE_SAVE | LOADSAVETYPE_SCENARIO) :
w->widgets[WIDX_TITLE].image = STR_SAVE_SCENARIO;
break;
case (LOADSAVETYPE_LOAD | LOADSAVETYPE_TRACK) :
w->widgets[WIDX_TITLE].image = 1039;
break;
}
w->no_list_items = 0;
@ -200,6 +203,25 @@ rct_window *window_loadsave_open(int type)
window_loadsave_populate_list(includeNewItem, TRUE, path, ".sc6");
break;
case LOADSAVETYPE_TRACK:
/*
Uncomment when user tracks are separated
platform_get_user_directory(path, "tracks");
if (!platform_ensure_directory_exists(path)) {
fprintf(stderr, "Unable to create tracks directory.");
window_close(w);
return NULL;
}
*/
strcpy(path, RCT2_ADDRESS(RCT2_ADDRESS_TRACKS_PATH, char));
ch = strchr(path, '*');
if (ch != NULL)
*ch = 0;
window_loadsave_populate_list(includeNewItem, TRUE, path, ".td?");
break;
}
w->no_list_items = _listItemsCount;
window_init_scroll_widgets(w);
@ -253,6 +275,9 @@ static void window_loadsave_mouseup()
case (LOADSAVETYPE_SAVE | LOADSAVETYPE_SCENARIO) :
result = platform_open_common_file_dialog(0, (char*)language_get_string(STR_SAVE_SCENARIO), filename, filter, _extension);
break;
case (LOADSAVETYPE_LOAD | LOADSAVETYPE_TRACK) :
result = platform_open_common_file_dialog(1, (char*)language_get_string(1039), filename, filter, _extension);
break;
}
if (result){
if (!hasExtension(filename, _extension)){
@ -626,6 +651,10 @@ static void window_loadsave_select(rct_window *w, const char *path)
}
}
break;
case (LOADSAVETYPE_LOAD | LOADSAVETYPE_TRACK) :
window_install_track_open(path);
window_close_by_class(WC_LOADSAVE);
break;
}
}

View File

@ -25,7 +25,7 @@
#include "../interface/viewport.h"
#include "../interface/window.h"
#include "../sprites.h"
#include "../windows/scenery.h"
#include "../world/scenery.h"
enum WINDOW_MAP_WIDGET_IDX {

View File

@ -25,8 +25,8 @@
#include "../interface/viewport.h"
#include "../interface/window.h"
#include "../sprites.h"
#include "../windows/scenery.h"
#include "../world/mapgen.h"
#include "../world/scenery.h"
#include "dropdown.h"
enum {

View File

@ -326,7 +326,7 @@ static void window_new_ride_populate_list()
nextListItem->entry_index = rideEntryIndex;
nextListItem++;
} else if (dh & 4) {
if (rideType == rideEntry->var_00C) {
if (rideType == rideEntry->ride_type[0]) {
nextListItem--;
nextListItem->type = rideType;
nextListItem->entry_index = rideEntryIndex;
@ -382,13 +382,13 @@ static void window_new_ride_scroll_to_focused_ride(rct_window *w)
*
* rct2: 0x006B3CFF
*/
void window_new_ride_open()
rct_window *window_new_ride_open()
{
rct_window *w;
w = window_bring_to_front_by_class(WC_CONSTRUCT_RIDE);
if (w != NULL)
return;
return w;
// Not sure what these windows are
window_close_by_class(WC_TRACK_DESIGN_LIST);
@ -427,6 +427,17 @@ void window_new_ride_open()
w->width = 1;
window_new_ride_refresh_widget_sizing(w);
window_new_ride_scroll_to_focused_ride(w);
return w;
}
rct_window *window_new_ride_open_research()
{
rct_window *w;
w = window_new_ride_open();
window_new_ride_set_page(w, WINDOW_NEW_RIDE_PAGE_RESEARCH);
return w;
}
/**
@ -866,9 +877,9 @@ static void window_new_ride_scrollpaint()
// Draw ride image
rideEntry = rideEntries[listItem->entry_index];
int image_id = rideEntry->images_offset;
if (listItem->type != rideEntry->var_00C) {
if (listItem->type != rideEntry->ride_type[0]) {
image_id++;
if (listItem->type != rideEntry->var_00D)
if (listItem->type != rideEntry->ride_type[1])
image_id++;
}
RCT2_CALLPROC_X(0x00681DE2, 0, 29013, x + 2, y + 2, 0xA0, (int)dpi, image_id);

View File

@ -888,10 +888,8 @@ static void window_options_set_page(rct_window *w, int page)
w->frame_no = 0;
window_invalidate(w);
RCT2_CALLPROC_X(w->event_handlers[WE_RESIZE], 0, 0, 0, 0, (int)w, 0, 0);
RCT2_CALLPROC_X(w->event_handlers[WE_INVALIDATE], 0, 0, 0, 0, (int)w, 0, 0);
window_event_resize_call(w);
window_event_invalidate_call(w);
window_init_scroll_widgets(w);
window_invalidate(w);
}

View File

@ -812,7 +812,7 @@ static void window_park_entrance_toolupdate()
if (widgetIndex == WIDX_BUY_LAND_RIGHTS) {
map_invalidate_selection_rect();
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) &= 0xFFFE;
screen_pos_to_map_pos(&x, &y);
screen_pos_to_map_pos(&x, &y, NULL);
if (x != SPRITE_LOCATION_NULL) {
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) |= 1;
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_TYPE, uint16) = 4;
@ -1018,7 +1018,7 @@ static void window_park_init_viewport(rct_window *w)
}
// Call invalidate event
RCT2_CALLPROC_X(w->event_handlers[WE_INVALIDATE], 0, 0, 0, 0, (int)w, 0, 0);
window_event_invalidate_call(w);
w->viewport_focus_coordinates.x = x;
w->viewport_focus_coordinates.y = y;

View File

@ -620,8 +620,8 @@ static void window_research_set_page(rct_window *w, int page)
w->width = 320;
w->height = 207;
}
RCT2_CALLPROC_X(w->event_handlers[WE_RESIZE], 0, 0, 0, 0, (int)w, 0, 0);
RCT2_CALLPROC_X(w->event_handlers[WE_INVALIDATE], 0, 0, 0, 0, (int)w, 0, 0);
window_event_resize_call(w);
window_event_invalidate_call(w);
window_init_scroll_widgets(w);
window_invalidate(w);

View File

@ -1035,7 +1035,7 @@ static void window_ride_draw_tab_vehicle(rct_drawpixelinfo *dpi, rct_window *w)
dpi->y *= 2;
}
rct_ride_type_vehicle* rideVehicleEntry = &rideEntry->vehicles[RCT2_ADDRESS(0x00F64E38, uint8)[rideEntry->var_013]];
rct_ride_type_vehicle* rideVehicleEntry = &rideEntry->vehicles[RCT2_ADDRESS(0x00F64E38, uint8)[rideEntry->tab_vehicle]];
height += rideVehicleEntry->var_0A;
vehicleColour = ride_get_vehicle_colour(ride, 0);
@ -1421,9 +1421,8 @@ static void window_ride_set_page(rct_window *w, int page)
window_ride_disable_tabs(w);
window_invalidate(w);
RCT2_CALLPROC_X(w->event_handlers[WE_RESIZE], 0, 0, 0, 0, (int)w, 0, 0);
RCT2_CALLPROC_X(w->event_handlers[WE_INVALIDATE], 0, 0, 0, 0, (int)w, 0, 0);
window_event_resize_call(w);
window_event_invalidate_call(w);
window_init_scroll_widgets(w);
window_invalidate(w);
@ -1477,7 +1476,7 @@ static void window_ride_init_viewport(rct_window *w)
focus.sprite.sprite_id = ride->vehicles[eax];
rct_ride_type* ride_entry = ride_get_entry(ride);
if (ride_entry->var_013 != 0){
if (ride_entry->tab_vehicle != 0){
rct_vehicle* vehicle = GET_VEHICLE(focus.sprite.sprite_id);
focus.sprite.sprite_id = vehicle->next_vehicle_on_train;
}
@ -1535,7 +1534,7 @@ static void window_ride_init_viewport(rct_window *w)
viewport_flags |= VIEWPORT_FLAG_GRIDLINES;
}
RCT2_CALLPROC_X(w->event_handlers[WE_INVALIDATE], 0, 0, 0, 0, (int)w, 0, 0);
window_event_invalidate_call(w);
w->viewport_focus_coordinates.x = focus.coordinate.x;
w->viewport_focus_coordinates.y = focus.coordinate.y;
@ -1896,7 +1895,7 @@ static void window_ride_main_update(rct_window *w)
// Update tab animation
w->frame_no++;
RCT2_CALLPROC_X(w->event_handlers[WE_INVALIDATE], 0, 0, 0, 0, (int)w, 0, 0);
window_event_invalidate_call(w);
widget_invalidate(w, WIDX_TAB_1);
// Update status
@ -2348,9 +2347,9 @@ static void window_ride_vehicle_mousedown(int widgetIndex, rct_window *w, rct_wi
gDropdownItemsFormat[i] = 1142;
gDropdownItemsArgs[i] = 1024;
if (cars - rideEntry->var_012 > 1)
if (cars - rideEntry->zero_cars > 1)
gDropdownItemsArgs[i]++;
gDropdownItemsArgs[i] |= (cars - rideEntry->var_012) << 16;
gDropdownItemsArgs[i] |= (cars - rideEntry->zero_cars) << 16;
}
gDropdownItemsChecked = (1 << (ride->num_cars_per_train - minCars));
@ -2402,7 +2401,7 @@ static void window_ride_vehicle_dropdown()
static void window_ride_vehicle_update(rct_window *w)
{
w->frame_no++;
RCT2_CALLPROC_X(w->event_handlers[WE_INVALIDATE], 0, 0, 0, 0, (int)w, 0, 0);
window_event_invalidate_call(w);
widget_invalidate(w, WIDX_TAB_2);
}
@ -2436,7 +2435,7 @@ static void window_ride_vehicle_invalidate()
RCT2_GLOBAL(0x013CE952 + 2, uint32) = ride->name_arguments;
// Widget setup
carsPerTrain = ride->num_cars_per_train - rideEntry->var_012;
carsPerTrain = ride->num_cars_per_train - rideEntry->zero_cars;
// Vehicle type
window_ride_vehicle_widgets[WIDX_VEHICLE_TYPE].image = rideEntry->name;
@ -2452,7 +2451,7 @@ static void window_ride_vehicle_invalidate()
}
// Trains
if (rideEntry->var_011 > 1) {
if (rideEntry->cars_per_flat_ride > 1) {
window_ride_vehicle_widgets[WIDX_VEHICLE_TRAINS].type = WWT_DROPDOWN;
window_ride_vehicle_widgets[WIDX_VEHICLE_TRAINS_DROPDOWN].type = WWT_DROPDOWN_BUTTON;
} else {
@ -2461,7 +2460,7 @@ static void window_ride_vehicle_invalidate()
}
// Cars per train
if (rideEntry->var_012 + 1 < rideEntry->max_cars_in_train) {
if (rideEntry->zero_cars + 1 < rideEntry->max_cars_in_train) {
window_ride_vehicle_widgets[WIDX_VEHICLE_CARS_PER_TRAIN].image = carsPerTrain > 1 ? 1023 : 1022;
window_ride_vehicle_widgets[WIDX_VEHICLE_CARS_PER_TRAIN].type = WWT_DROPDOWN;
window_ride_vehicle_widgets[WIDX_VEHICLE_CARS_PER_TRAIN_DROPDOWN].type = WWT_DROPDOWN_BUTTON;
@ -2946,7 +2945,7 @@ static void window_ride_operating_update(rct_window *w)
rct_ride *ride;
w->frame_no++;
RCT2_CALLPROC_X(w->event_handlers[WE_INVALIDATE], 0, 0, 0, 0, (int)w, 0, 0);
window_event_invalidate_call(w);
widget_invalidate(w, WIDX_TAB_3);
ride = GET_RIDE(w->number);
@ -2988,7 +2987,7 @@ static void window_ride_operating_invalidate()
w->pressed_widgets &= ~0x44700000;
// Lift hill speed
if ((rideEntry->var_1B6 & RCT2_ADDRESS(0x01357444, uint32)[ride->type]) & 8) {
if ((rideEntry->enabledTrackPieces & RCT2_ADDRESS(0x01357444, uint32)[ride->type]) & 8) {
window_ride_operating_widgets[WIDX_LIFT_HILL_SPEED_LABEL].type = WWT_24;
window_ride_operating_widgets[WIDX_LIFT_HILL_SPEED].type = WWT_SPINNER;
window_ride_operating_widgets[WIDX_LIFT_HILL_SPEED_INCREASE].type = WWT_DROPDOWN_BUTTON;
@ -3356,7 +3355,7 @@ static void window_ride_maintenance_update(rct_window *w)
rct_ride *ride;
w->frame_no++;
RCT2_CALLPROC_X(w->event_handlers[WE_INVALIDATE], 0, 0, 0, 0, (int)w, 0, 0);
window_event_invalidate_call(w);
widget_invalidate(w, WIDX_TAB_4);
ride = GET_RIDE(w->number);
@ -3542,7 +3541,7 @@ static void window_ride_set_track_colour_scheme(rct_window *w, int x, int y)
int z;
get_map_coordinates_from_pos(x, y, -5, &x, &y, &z, &mapElement);
get_map_coordinates_from_pos(x, y, -5, &x, &y, &z, &mapElement, NULL);
// Get map coordinates from point
/*int eax, ebx, ecx, edx, esi, edi, ebp;
eax = x;
@ -3844,7 +3843,7 @@ static void window_ride_colour_dropdown()
static void window_ride_colour_update(rct_window *w)
{
w->frame_no++;
RCT2_CALLPROC_X(w->event_handlers[WE_INVALIDATE], 0, 0, 0, 0, (int)w, 0, 0);
window_event_invalidate_call(w);
widget_invalidate(w, WIDX_TAB_5);
widget_invalidate(w, WIDX_VEHICLE_PREVIEW);
}
@ -4179,7 +4178,7 @@ static void window_ride_colour_scrollpaint()
// ?
colour = (ride->colour_scheme_type & 3) == RIDE_COLOUR_SCHEME_DIFFERENT_PER_CAR ?
w->var_48C : rideEntry->var_013;
w->var_48C : rideEntry->tab_vehicle;
rct_ride_type_vehicle* rideVehicleEntry = &rideEntry->vehicles[RCT2_ADDRESS(0x00F64E38, uint8)[colour]];
@ -4369,7 +4368,7 @@ static void window_ride_music_dropdown()
static void window_ride_music_update(rct_window *w)
{
w->frame_no++;
RCT2_CALLPROC_X(w->event_handlers[WE_INVALIDATE], 0, 0, 0, 0, (int)w, 0, 0);
window_event_invalidate_call(w);
widget_invalidate(w, WIDX_TAB_6);
}
@ -4639,7 +4638,7 @@ static void window_ride_measurements_dropdown()
static void window_ride_measurements_update(rct_window *w)
{
w->frame_no++;
RCT2_CALLPROC_X(w->event_handlers[WE_INVALIDATE], 0, 0, 0, 0, (int)w, 0, 0);
window_event_invalidate_call(w);
widget_invalidate(w, WIDX_TAB_7);
}
@ -5011,9 +5010,9 @@ static void window_ride_graphs_update(rct_window *w)
int x;
w->frame_no++;
RCT2_CALLPROC_X(w->event_handlers[WE_INVALIDATE], 0, 0, 0, 0, (int)w, 0, 0);
window_event_invalidate_call(w);
widget_invalidate(w, WIDX_TAB_8);
RCT2_CALLPROC_X(w->event_handlers[WE_INVALIDATE], 0, 0, 0, 0, (int)w, 0, 0);
window_event_invalidate_call(w);
widget_invalidate(w, WIDX_GRAPH);
widget = &window_ride_graphs_widgets[WIDX_GRAPH];
@ -5041,7 +5040,7 @@ static void window_ride_graphs_scrollgetheight()
window_get_register(w);
RCT2_CALLPROC_X(w->event_handlers[WE_INVALIDATE], 0, 0, 0, 0, (int)w, 0, 0);
window_event_invalidate_call(w);
// Set minimum size
width = window_ride_graphs_widgets[WIDX_GRAPH].right - window_ride_graphs_widgets[WIDX_GRAPH].left - 2;
@ -5447,7 +5446,7 @@ static void window_ride_income_update(rct_window *w)
rct_ride *ride;
w->frame_no++;
RCT2_CALLPROC_X(w->event_handlers[WE_INVALIDATE], 0, 0, 0, 0, (int)w, 0, 0);
window_event_invalidate_call(w);
widget_invalidate(w, WIDX_TAB_9);
ride = GET_RIDE(w->number);
@ -5731,7 +5730,7 @@ static void window_ride_customer_update(rct_window *w)
if (w->var_492 >= 24)
w->var_492 = 0;
RCT2_CALLPROC_X(w->event_handlers[WE_INVALIDATE], 0, 0, 0, 0, (int)w, 0, 0);
window_event_invalidate_call(w);
widget_invalidate(w, WIDX_TAB_10);
ride = GET_RIDE(w->number);

View File

@ -32,7 +32,11 @@
#include "../world/scenery.h"
#include "../world/sprite.h"
#include "dropdown.h"
#include "scenery.h"
#define WINDOW_SCENERY_WIDTH 634
#define WINDOW_SCENERY_HEIGHT 142
#define SCENERY_BUTTON_WIDTH 66
#define SCENERY_BUTTON_HEIGHT 80
enum {
WINDOW_SCENERY_TAB_1,
@ -174,7 +178,10 @@ static rct_widget window_scenery_widgets[] = {
{ WIDGETS_END },
};
static sint16 window_scenery_tab_entries[0x14][SCENERY_ENTRIES_BY_TAB + 1];
// rct2: 0x00F64F2C
sint16 window_scenery_tab_entries[20][SCENERY_ENTRIES_BY_TAB + 1];
void window_scenery_update_scroll(rct_window *w);
/**
* Was part of 0x006DFA00
@ -221,7 +228,8 @@ void init_scenery_entry(rct_scenery_entry *sceneryEntry, int index, uint8 scener
*
* rct2: 0x006DFA00
*/
void init_scenery() {
void init_scenery()
{
bool enabledScenerySets[0x14] = { false };
for (int scenerySetIndex = 0; scenerySetIndex < 0x14; scenerySetIndex++) {
@ -367,6 +375,37 @@ void init_scenery() {
window_invalidate_by_class(WC_SCENERY);
}
/**
*
* rct2: 0x006DFEE4
*/
void scenery_set_default_placement_configuration()
{
window_scenery_rotation = 3;
window_scenery_primary_colour = 26;
window_scenery_secondary_colour = 18;
window_scenery_tertiary_colour = 24;
init_scenery();
for (int i = 0; i < 20; i++)
window_scenery_selected_scenery_by_tab[i] = -1;
for (int i = 0; i < 20; i++) {
if (window_scenery_tab_entries[i][0] != -1) {
window_scenery_active_tab_index = i;
return;
}
}
for (int i = 0; i < 16; i++) {
rct_widget *tabWidget = &window_scenery_widgets[WIDX_SCENERY_TAB_1 + i];
if (tabWidget->type != WWT_EMPTY) {
window_scenery_active_tab_index = i;
return;
}
}
}
/**
*
* rct2: 0x006E0FEF
@ -416,7 +455,7 @@ void window_scenery_open()
(1 << WIDX_SCENERY_BUILD_CLUSTER_BUTTON);
window_init_scroll_widgets(window);
RCT2_CALLPROC_X(0x006E1EB4, 0, 0, 0, 0, (int)window, 0, 0);
window_scenery_update_scroll(window);
show_gridlines();
window_scenery_rotation = 3;
RCT2_GLOBAL(0x00F64F12, uint8) = 0;

View File

@ -1,39 +0,0 @@
/*****************************************************************************
* Copyright (c) 2014 Dániel Tar
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
*
* This file is part of OpenRCT2.
*
* OpenRCT2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/
#ifndef _WINDOW_SCENERY_H_
#define _WINDOW_SCENERY_H_
#define WINDOW_SCENERY_WIDTH 0x27A
#define WINDOW_SCENERY_HEIGHT 0x8E
#define SCENERY_BUTTON_WIDTH 66
#define SCENERY_BUTTON_HEIGHT 80
#define SCENERY_ENTRIES_BY_TAB 128
#define window_scenery_active_tab_index RCT2_GLOBAL(0x00F64EDC, uint8)
#define window_scenery_selected_scenery_by_tab RCT2_ADDRESS(0x00F64EDD, sint16)
#define window_scenery_is_build_cluster_tool_on RCT2_GLOBAL(0x00F64F1A, uint8)
#define window_scenery_is_repaint_scenery_tool_on RCT2_GLOBAL(0x00F64F19, uint8)
#define window_scenery_rotation RCT2_GLOBAL(0x00F64F05, uint8)
#define window_scenery_primary_colour RCT2_GLOBAL(0x00F64F06, uint8)
#define window_scenery_secondary_colour RCT2_GLOBAL(0x00F64F07, uint8)
#define window_scenery_tertiary_colour RCT2_GLOBAL(0x00F64F08, uint8)
#endif

View File

@ -27,6 +27,7 @@
#include "../peep/peep.h"
#include "../peep/staff.h"
#include "../sprites.h"
#include "../world/footpath.h"
#include "../world/sprite.h"
#include "../world/scenery.h"
#include "dropdown.h"
@ -332,9 +333,8 @@ void window_staff_open(rct_peep* peep)
window_staff_disable_widgets(w);
window_init_scroll_widgets(w);
window_staff_viewport_init(w);
if (g_sprite_list[w->number].peep.state == PEEP_STATE_PICKED) {
RCT2_CALLPROC_X(w->event_handlers[WE_MOUSE_UP], 0, 0, 0, 10, (int)w, 0, 0);
}
if (g_sprite_list[w->number].peep.state == PEEP_STATE_PICKED)
window_event_mouse_up_call(w, WIDX_CHECKBOX_3);
}
/**
@ -421,8 +421,8 @@ void window_staff_set_page(rct_window* w, int page)
window_staff_disable_widgets(w);
window_invalidate(w);
RCT2_CALLPROC_X(w->event_handlers[WE_RESIZE], 0, 0, 0, 0, (int)w, 0, 0);
RCT2_CALLPROC_X(w->event_handlers[WE_INVALIDATE], 0, 0, 0, 0, (int)w, 0, 0);
window_event_resize_call(w);
window_event_invalidate_call(w);
window_init_scroll_widgets(w);
window_invalidate(w);
@ -1086,7 +1086,7 @@ void window_staff_overview_tool_update(){
RCT2_GLOBAL(RCT2_ADDRESS_PICKEDUP_PEEP_SPRITE, sint32) = -1;
int z;
get_map_coordinates_from_pos(x, y, 0, NULL, NULL, &z, NULL);
get_map_coordinates_from_pos(x, y, 0, NULL, NULL, &z, NULL, NULL);
if (z == 0)
return;
@ -1116,9 +1116,9 @@ void window_staff_overview_tool_down(){
if (widgetIndex == WIDX_PICKUP){
int dest_x = x, dest_y = y, ecx = 0, edx = widgetIndex, edi = 0, esi = (int)w, ebp = 0;
dest_y += 16;
RCT2_CALLFUNC_X(0x689726, &dest_x, &dest_y, &ecx, &edx, &esi, &edi, &ebp);
int dest_x, dest_y;
rct_map_element *mapElement;
footpath_get_coordinates_from_pos(x, y + 16, &dest_x, &dest_y, NULL, &mapElement);
if (dest_x == 0x8000)return;
@ -1130,7 +1130,7 @@ void window_staff_overview_tool_down(){
int tile_y = dest_y & 0xFFE0;
int tile_x = dest_x & 0xFFE0;
int dest_z = ((uint8*)edx)[2] * 8 + 16;
int dest_z = mapElement->base_height * 8 + 16;
if (!map_is_location_owned(tile_x, tile_y, dest_z)){
window_error_open(0x785, -1);
@ -1166,8 +1166,8 @@ void window_staff_overview_tool_down(){
RCT2_GLOBAL(0x9DE550, sint32) = -1;
}
else if (widgetIndex == WIDX_PATROL){
int dest_x = x, dest_y = y, ecx = 0, edx = widgetIndex, edi = 0, esi = (int)w, ebp = 0;
RCT2_CALLFUNC_X(0x689726, &dest_x, &dest_y, &ecx, &edx, &esi, &edi, &ebp);
int dest_x, dest_y;
footpath_get_coordinates_from_pos(x, y, &dest_x, &dest_y, NULL, NULL);
if (dest_x == 0x8000)return;
@ -1279,7 +1279,7 @@ void window_staff_viewport_init(rct_window* w){
viewport_flags |= VIEWPORT_FLAG_GRIDLINES;
}
RCT2_CALLPROC_X(w->event_handlers[WE_INVALIDATE], 0, 0, 0, 0, (int)w, 0, 0);
window_event_invalidate_call(w);
w->viewport_focus_sprite.sprite_id = focus.sprite_id;
w->viewport_focus_sprite.type = focus.type;
@ -1318,9 +1318,8 @@ void window_staff_options_mousedown(int widgetIndex, rct_window* w, rct_widget*
init_scenery();
int ebx = 0;
for (int i = 0; i < 19;++i){
sint16* ebp = RCT2_ADDRESS(0xF64F2C, sint16*)[i];
if (*ebp != -1){
for (int i = 0; i < 19; i++) {
if (window_scenery_tab_entries[i][0] != -1) {
rct_scenery_set_entry* scenery_entry = g_scenerySetEntries[i];
ebx |= scenery_entry->var_10A;
}

View File

@ -182,8 +182,8 @@ static void window_scenarioselect_mousedown(int widgetIndex, rct_window*w, rct_w
w->selected_tab = widgetIndex - 4;
w->var_494 = 0;
window_invalidate(w);
RCT2_CALLPROC_X(w->event_handlers[WE_RESIZE], 0, 0, 0, 0, (int)w, 0, 0);
RCT2_CALLPROC_X(w->event_handlers[WE_INVALIDATE], 0, 0, 0, 0, (int)w, 0, 0);
window_event_resize_call(w);
window_event_invalidate_call(w);
window_init_scroll_widgets(w);
window_invalidate(w);
}

View File

@ -79,7 +79,7 @@ void window_tooltip_reset(int x, int y)
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) &= ~(1 << 4);
}
extern uint8* gTooltip_text_buffer = RCT2_ADDRESS(RCT2_ADDRESS_TOOLTIP_TEXT_BUFFER, uint8);
uint8* gTooltip_text_buffer = RCT2_ADDRESS(RCT2_ADDRESS_TOOLTIP_TEXT_BUFFER, uint8);
/**
*
* rct2: 0x006EA10D

View File

@ -29,8 +29,8 @@
#include "../interface/window.h"
#include "../interface/viewport.h"
#include "../localisation/localisation.h"
#include "../world/scenery.h"
#include "dropdown.h"
#include "scenery.h"
enum {
WIDX_PAUSE,

View File

@ -94,24 +94,6 @@ static void* window_track_list_events[] = {
ride_list_item _window_track_list_item;
void window_track_list_format_name(char *dst, const char *src, char colour, char quotes)
{
if (colour != 0)
*dst++ = colour;
if (quotes != 0)
*dst++ = FORMAT_OPENQUOTES;
while (*src != '.' && *src != 0) {
*dst++ = *src++;
}
if (quotes != 0)
*dst++ = FORMAT_ENDQUOTES;
*dst = 0;
}
/**
*
* rct2: 0x006CF1A2

View File

@ -304,14 +304,69 @@ static void window_track_place_draw_mini_preview()
*
* rct2: 0x0068A15E
*/
static void sub_68A15E(int x, int y, short *ax, short *bx)
static void sub_68A15E(int screenX, int screenY, short *x, short *y, int *direction, rct_map_element **mapElement)
{
int eax, ebx, ecx, edx, esi, edi, ebp;
eax = x;
ebx = y;
RCT2_CALLFUNC_X(0x0068A15E, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
*ax = *((short*)&eax);
*bx = *((short*)&ebx);
int my_x, my_y, z;
rct_map_element *myMapElement;
rct_viewport *viewport;
get_map_coordinates_from_pos(screenX, screenY, 0xFFF6, &my_x, &my_y, &z, &myMapElement, &viewport);
if (z == 0) {
*x = 0x8000;
return;
}
RCT2_GLOBAL(0x00F1AD3E, uint8) = z;
RCT2_GLOBAL(0x00F1AD30, rct_map_element*) = myMapElement;
if (z == 4) {
// myMapElement appears to be water
z = myMapElement->properties.surface.terrain;
z = (z & MAP_ELEMENT_WATER_HEIGHT_MASK) << 4;
}
RCT2_GLOBAL(0x00F1AD3C, uint16) = z;
RCT2_GLOBAL(0x00F1AD34, sint16) = my_x;
RCT2_GLOBAL(0x00F1AD36, sint16) = my_y;
RCT2_GLOBAL(0x00F1AD38, sint16) = my_x + 31;
RCT2_GLOBAL(0x00F1AD3A, sint16) = my_y + 31;
rct_xy16 start_vp_pos = screen_coord_to_viewport_coord(viewport, screenX, screenY);
rct_xy16 map_pos = { my_x + 16, my_y + 16 };
for (int i = 0; i < 5; i++) {
if (RCT2_GLOBAL(0x00F1AD3E, uint8) != 4) {
z = map_element_height(map_pos.x, map_pos.y);
} else {
z = RCT2_GLOBAL(0x00F1AD3C, uint16);
}
map_pos = viewport_coord_to_map_coord(start_vp_pos.x, start_vp_pos.y, z);
map_pos.x = clamp(RCT2_GLOBAL(0x00F1AD34, sint16), map_pos.x, RCT2_GLOBAL(0x00F1AD38, sint16));
map_pos.y = clamp(RCT2_GLOBAL(0x00F1AD36, sint16), map_pos.y, RCT2_GLOBAL(0x00F1AD3A, sint16));
}
// Determine to which edge the cursor is closest
int myDirection;
int mod_x = map_pos.x & 0x1F;
int mod_y = map_pos.y & 0x1F;
if (mod_x < mod_y) {
if (mod_x + mod_y < 32) {
myDirection = 0;
} else {
myDirection = 1;
}
} else {
if (mod_x + mod_y < 32) {
myDirection = 3;
} else {
myDirection = 2;
}
}
*x = map_pos.x & ~0x1F;
*y = map_pos.y & ~0x1F;
if (direction != NULL) *direction = myDirection;
if (mapElement != NULL) *mapElement = myMapElement;
}
/**
@ -483,7 +538,7 @@ static void window_track_place_toolupdate()
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) &= ~7;
// Get the tool map position
sub_68A15E(x, y, &x, &y);
sub_68A15E(x, y, &x, &y, NULL, NULL);
if (x == (short)0x8000) {
window_track_place_clear_provisional();
return;
@ -545,7 +600,7 @@ static void window_track_place_tooldown()
map_invalidate_map_selection_tiles();
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) &= ~7;
sub_68A15E(x, y, &x, &y);
sub_68A15E(x, y, &x, &y, NULL, NULL);
if (x == (short)0x8000)
return;

View File

@ -176,7 +176,7 @@ static void window_viewport_mouseup()
case WIDX_LOCATE:
mainWindow = window_get_main();
if (mainWindow != NULL) {
get_map_coordinates_from_pos(w->x + (w->width / 2), w->y + (w->height / 2), 0, &x, &y, NULL, NULL);
get_map_coordinates_from_pos(w->x + (w->width / 2), w->y + (w->height / 2), 0, &x, &y, NULL, NULL, NULL);
window_scroll_to_location(mainWindow, x, y, map_element_height(x, y));
}
break;

View File

@ -21,6 +21,7 @@
#include "../addresses.h"
#include "../game.h"
#include "../localisation/localisation.h"
#include "../util/util.h"
#include "footpath.h"
#include "map.h"
@ -473,20 +474,137 @@ void footpath_provisional_update()
footpath_provisional_remove();
}
/**
* Determines the location of the footpath at which we point with the cursor. If no footpath is underneath the cursor,
* then return the location of the ground tile. Besides the location it also computes the direction of the yellow arrow
* when we are going to build a footpath bridge/tunnel.
* rct2: 0x00689726
* In:
* screenX: eax
* screenY: ebx
* Out:
* x: ax
* y: bx
* direction: ecx
* mapElement: edx
*/
void footpath_get_coordinates_from_pos(int screenX, int screenY, int *x, int *y, int *direction, rct_map_element **mapElement)
{
int z;
rct_map_element *myMapElement;
rct_viewport *viewport;
get_map_coordinates_from_pos(screenX, screenY, 0xFFDF, x, y, &z, &myMapElement, &viewport);
if (z != 6 || !(viewport->flags & (VIEWPORT_FLAG_UNDERGROUND_INSIDE | VIEWPORT_FLAG_HIDE_BASE | VIEWPORT_FLAG_HIDE_VERTICAL))) {
get_map_coordinates_from_pos(screenX, screenY, 0xFFDE, x, y, &z, &myMapElement, &viewport);
if (z == 0) {
if (x != NULL) *x = 0x8000;
return;
}
}
RCT2_GLOBAL(0x00F1AD3E, uint8) = z;
RCT2_GLOBAL(0x00F1AD30, rct_map_element*) = myMapElement;
if (z == 6) {
// mapElement appears to be a footpath
z = myMapElement->base_height * 8;
if (myMapElement->properties.path.type & (1 << 2))
z += 8;
}
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;
*x += 16;
*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) {
z = map_element_height(map_pos.x, map_pos.y);
} else {
z = RCT2_GLOBAL(0x00F1AD3C, uint16);
}
map_pos = viewport_coord_to_map_coord(start_vp_pos.x, start_vp_pos.y, z);
map_pos.x = clamp(RCT2_GLOBAL(0x00F1AD34, sint16), map_pos.x, RCT2_GLOBAL(0x00F1AD38, sint16));
map_pos.y = clamp(RCT2_GLOBAL(0x00F1AD36, sint16), map_pos.y, RCT2_GLOBAL(0x00F1AD3A, sint16));
}
// Determine to which edge the cursor is closest
uint32 myDirection;
int mod_x = map_pos.x & 0x1F, mod_y = map_pos.y & 0x1F;
if (mod_x < mod_y) {
if (mod_x + mod_y < 32) {
myDirection = 0;
} else {
myDirection = 1;
}
} else {
if (mod_x + mod_y < 32) {
myDirection = 3;
} else {
myDirection = 2;
}
}
if (x != NULL) *x = map_pos.x & ~0x1F;
if (y != NULL) *y = map_pos.y & ~0x1F;
if (direction != NULL) *direction = myDirection;
if (mapElement != NULL) *mapElement = myMapElement;
// We should get the rct_map_element from 0x00F1AD30 here, but we set it earlier to our myMapElement anyway.
}
/**
*
* rct2: 0x0068A0C9
* screenX: eax
* screenY: ebx
* x: ax
* y: bx
* direction: cl
* mapElement: edx
*/
void sub_68A0C9(int screenX, int screenY, int *x, int *y, int *direction, rct_map_element **mapElement)
void footpath_bridge_get_info_from_pos(int screenX, int screenY, int *x, int *y, int *direction, rct_map_element **mapElement)
{
int eax, ebx, ecx, edx, esi, edi, ebp;
eax = screenX;
ebx = screenY;
RCT2_CALLFUNC_X(0x0068A0C9, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
if (x != NULL) *x = *((uint16*)&eax);
if (y != NULL) *y = *((uint16*)&ebx);
if (direction != NULL) *direction = *((uint8*)&ecx);
if (mapElement != NULL) *mapElement = (rct_map_element*)edx;
// First check if we point at an entrance or exit. In that case, we would want the path coming from the entrance/exit.
int z;
rct_viewport *viewport;
get_map_coordinates_from_pos(screenX, screenY, 0xFFFB, x, y, &z, mapElement, &viewport);
if (z == 3
&& viewport->flags & (VIEWPORT_FLAG_UNDERGROUND_INSIDE | VIEWPORT_FLAG_HIDE_BASE | VIEWPORT_FLAG_HIDE_VERTICAL)
&& map_element_get_type(*mapElement) == MAP_ELEMENT_TYPE_ENTRANCE) {
int ebp = (*mapElement)->properties.entrance.type << 4;
int bl = (*mapElement)->properties.entrance.index & 0xF;
if (RCT2_GLOBAL(0x0097B974 + ebp + bl, uint16) & 0xF) {
int bx = bitscanforward(RCT2_GLOBAL(0x0097B974 + ebp + bl, uint16));
bx += (*mapElement)->type;
bx &= 3;
if (direction != NULL) *direction = bx;
return;
}
}
get_map_coordinates_from_pos(screenX, screenY, 0xFFDA, x, y, &z, mapElement, &viewport);
if (z == 3 && 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?
// The table at 0x0097B974 is only 48 bytes big
if (RCT2_GLOBAL(0x0097B974 + ebp + bl, uint16) & 0xF) {
int bx = bitscanforward(RCT2_GLOBAL(0x0097B974 + ebp + bl, uint16));
bx += (*mapElement)->type; // First two bits seem to contain the direction of entrance/exit
bx &= 3;
if (direction != NULL) *direction = bx;
return;
}
}
// We point at something else
footpath_get_coordinates_from_pos(screenX, screenY, x, y, direction, mapElement);
}
/**

View File

@ -46,6 +46,7 @@ void footpath_remove(int x, int y, int z, int flags);
money32 footpath_provisional_set(int type, int x, int y, int z, int slope);
void footpath_provisional_remove();
void footpath_provisional_update();
void sub_68A0C9(int screenX, int screenY, int *x, int *y, int *direction, rct_map_element **mapElement);
void footpath_get_coordinates_from_pos(int screenX, int screenY, int *x, int *y, int *direction, rct_map_element **mapElement);
void footpath_bridge_get_info_from_pos(int screenX, int screenY, int *x, int *y, int *direction, rct_map_element **mapElement);
#endif

View File

@ -22,6 +22,7 @@
#define _USE_MATH_DEFINES
#endif
#include <math.h>
#include <time.h>
#include "../addresses.h"
#include "../object.h"
#include "map.h"
@ -445,7 +446,7 @@ static void mapgen_blob_fill(int height)
for (int x = left; x <= right; x++)
if (x >= firstLand && x <= lastLand)
landX[x, y] = 1;
landX[x * _heightSize + y] = 1;
}
// Do the same for Y
@ -474,7 +475,7 @@ static void mapgen_blob_fill(int height)
}
for (int y = top; y <= bottom; y++) {
if (y >= firstLand && y <= lastLand && landX[x, y]) {
if (y >= firstLand && y <= lastLand && landX[x * _heightSize + y]) {
// Not only do we know its landlocked to both x and y
// we can change the land too
set_height(x, y, BLOB_HEIGHT);

View File

@ -710,6 +710,11 @@ void game_command_remove_park_entrance(int *eax, int *ebx, int *ecx, int *edx, i
}
entranceIndex = park_get_entrance_index(x, y, z);
if (entranceIndex == -1) {
*ebx = 0;
return;
}
RCT2_ADDRESS(RCT2_ADDRESS_PARK_ENTRANCE_X, uint16)[entranceIndex] = 0x8000;
direction = (RCT2_ADDRESS(RCT2_ADDRESS_PARK_ENTRANCE_DIRECTION, uint8)[entranceIndex] - 1) & 3;
z = (*edx & 0xFF) * 2;

View File

@ -135,6 +135,8 @@ enum {
PATH_BIT_FLAG_JUMPING_FOUNTAIN_SNOW = 1 << 5
};
#define SCENERY_ENTRIES_BY_TAB 128
#define g_smallSceneryEntries ((rct_scenery_entry**)object_entry_groups[OBJECT_TYPE_SMALL_SCENERY].chunks)
#define g_largeSceneryEntries ((rct_scenery_entry**)object_entry_groups[OBJECT_TYPE_LARGE_SCENERY].chunks)
#define g_wallSceneryEntries ((rct_scenery_entry**)object_entry_groups[OBJECT_TYPE_WALLS].chunks)
@ -142,8 +144,20 @@ enum {
#define g_pathBitSceneryEntries ((rct_scenery_entry**)object_entry_groups[OBJECT_TYPE_PATH_BITS].chunks)
#define g_scenerySetEntries ((rct_scenery_set_entry**)object_entry_groups[OBJECT_TYPE_SCENERY_SETS].chunks)
#define window_scenery_active_tab_index RCT2_GLOBAL(0x00F64EDC, uint8)
#define window_scenery_selected_scenery_by_tab RCT2_ADDRESS(0x00F64EDD, sint16)
#define window_scenery_is_build_cluster_tool_on RCT2_GLOBAL(0x00F64F1A, uint8)
#define window_scenery_is_repaint_scenery_tool_on RCT2_GLOBAL(0x00F64F19, uint8)
#define window_scenery_rotation RCT2_GLOBAL(0x00F64F05, uint8)
#define window_scenery_primary_colour RCT2_GLOBAL(0x00F64F06, uint8)
#define window_scenery_secondary_colour RCT2_GLOBAL(0x00F64F07, uint8)
#define window_scenery_tertiary_colour RCT2_GLOBAL(0x00F64F08, uint8)
extern sint16 window_scenery_tab_entries[20][SCENERY_ENTRIES_BY_TAB + 1];
void init_scenery();
void scenery_update_tile(int x, int y);
void scenery_update_age(int x, int y, rct_map_element *mapElement);
void scenery_set_default_placement_configuration();
#endif

View File

@ -22,6 +22,7 @@
#include "../audio/audio.h"
#include "../interface/viewport.h"
#include "../localisation/date.h"
#include "../localisation/localisation.h"
#include "../scenario.h"
#include "fountain.h"
#include "sprite.h"
@ -397,6 +398,23 @@ void duck_press(rct_duck *duck)
sound_play_panned(SOUND_QUACK, 0x8001, duck->x, duck->y, duck->z);
}
/**
*
* rct: 0x00674576
*/
void duck_remove_all()
{
rct_unk_sprite* sprite;
uint16 spriteIndex, nextSpriteIndex;
for (spriteIndex = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_MISC, uint16); spriteIndex != SPRITE_INDEX_NULL; spriteIndex = nextSpriteIndex) {
sprite = &(g_sprite_list[spriteIndex].unknown);
nextSpriteIndex = sprite->next;
if (sprite->misc_identifier == SPRITE_MISC_DUCK)
sprite_remove((rct_sprite*)sprite);
}
}
static const rct_xy16 _moneyEffectMoveOffset[] = {
{ 1, -1 },
{ 1, 1 },
@ -404,6 +422,77 @@ static const rct_xy16 _moneyEffectMoveOffset[] = {
{ -1, -1 }
};
/**
*
* rct: 0x0067351F
*/
void money_effect_create_at(money32 value, int x, int y, int z)
{
rct_money_effect *moneyEffect;
rct_string_id stringId;
char buffer[128];
moneyEffect = (rct_money_effect*)create_sprite(2);
if (moneyEffect == NULL)
return;
moneyEffect->value = value;
moneyEffect->var_14 = 64;
moneyEffect->var_09 = 20;
moneyEffect->var_15 = 30;
moneyEffect->sprite_identifier = SPRITE_IDENTIFIER_MISC;
sprite_move(x, y, z, (rct_sprite*)moneyEffect);
moneyEffect->misc_identifier = SPRITE_MISC_MONEY_EFFECT;
moneyEffect->num_movements = 0;
moneyEffect->move_delay = 0;
stringId = 1388;
if (value < 0) {
value *= -1;
stringId = 1399;
}
format_string(buffer, stringId, &value);
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, uint16) = 224;
moneyEffect->offset_x = -(gfx_get_string_width(buffer) / 2);
moneyEffect->wiggle = 0;
}
/**
*
* rct: 0x0069C5D0
*/
void money_effect_create(money32 value)
{
rct_window *mainWindow;
rct_viewport *mainViewport;
rct_xyz16 mapPosition;
mapPosition.x = RCT2_GLOBAL(0x009DEA5E, uint16);
mapPosition.y = RCT2_GLOBAL(0x009DEA60, uint16);
mapPosition.z = RCT2_GLOBAL(0x009DEA62, uint16);
if (mapPosition.x == (sint16)0x8000) {
mainWindow = window_get_main();
if (mainWindow == NULL)
return;
mainViewport = mainWindow->viewport;
mapPosition.x = mainViewport->x + (mainViewport->width / 2);
mapPosition.y = mainViewport->y + (mainViewport->height / 2);
int eax = mapPosition.x, ebx = mapPosition.y, ecx, edx, esi, edi, ebp;
RCT2_CALLFUNC_X(0x00688972, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
mapPosition.x = eax;
mapPosition.y = ebx;
if (mapPosition.x == (sint16)0x8000)
return;
mapPosition.z = map_element_height(mapPosition.x, mapPosition.y) & 0xFFFF;
}
mapPosition.z += 10;
money_effect_create_at(-value, mapPosition.x, mapPosition.y, mapPosition.z);
}
/**
*
* rct: 0x00673232

View File

@ -191,10 +191,14 @@ typedef struct {
sint16 x; // 0x0E
sint16 y; // 0x10
sint16 z; // 0x12
uint8 pad_14[0x10];
uint8 var_14;
uint8 var_15;
uint8 pad_16[0xE];
uint16 move_delay; // 0x24
uint16 num_movements; // 0x26
uint8 pad_28[0x1E];
money32 value; // 0x28
uint8 pad_2C[0x18];
sint16 offset_x; // 0x44
uint16 wiggle; // 0x46
} rct_money_effect;
@ -234,6 +238,8 @@ void create_balloon(int x, int y, int z, int colour, uint8 bl);
void balloon_press(rct_balloon *balloon);
void create_duck(int targetX, int targetY);
void duck_press(rct_duck *duck);
void duck_remove_all();
void money_effect_create(money32 value);
rct_sprite *create_sprite(uint8 bl);
void reset_sprite_list();
void reset_0x69EBE4();