mirror of https://github.com/OpenRCT2/OpenRCT2.git
commit
e17986fbd6
|
@ -2678,7 +2678,7 @@ STR_2676 :???
|
|||
STR_2677 :???
|
||||
STR_2678 :???
|
||||
STR_2679 :???
|
||||
STR_2680 :???
|
||||
STR_2680 :Alle onderzoeken zijn voltooid
|
||||
STR_2681 :{MEDIUMFONT}{BLACK}Krijg 5.000 extra geld
|
||||
STR_2682 :{MEDIUMFONT}{BLACK}Wissel tussen betaalde en gratis entree
|
||||
STR_2683 :{MEDIUMFONT}{BLACK}Alle bezoekers hebben een maximale tevredenheid
|
||||
|
|
|
@ -3459,3 +3459,4 @@ STR_5122 :Show all vehicles sharing a track/ride type
|
|||
STR_5123 :Renew rides
|
||||
STR_5124 :No Six Flags
|
||||
STR_5125 :All destructable
|
||||
STR_5126 :Random title music
|
||||
|
|
|
@ -3471,3 +3471,4 @@ STR_5122 :Show all vehicles sharing a track/ride type
|
|||
STR_5123 :Renew rides
|
||||
STR_5124 :No Six Flags
|
||||
STR_5125 :All destructable
|
||||
STR_5126 :Random title music
|
||||
|
|
|
@ -842,7 +842,7 @@ STR_0837 :Unable to initialize graphics system
|
|||
STR_0838 :CD key code {INT32} is not valid for your RollerCoaster Tycoon 2 CD !{WINDOW_COLOUR_1}{WINDOW_COLOUR_1}Please un-install RollerCoaster Tycoon 2% and re-install with the correct CD Key Code
|
||||
STR_0839 :{UINT16} x {UINT16}
|
||||
STR_0840 :{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{UINT16} x {UINT16}
|
||||
STR_0841 :Desktop window
|
||||
STR_0841 :En une fenêtre
|
||||
STR_0842 :640x480 plein écran
|
||||
STR_0843 :800x600 plein écran
|
||||
STR_0844 :1024x768 plein écran
|
||||
|
@ -1336,10 +1336,10 @@ STR_1331 :{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{VEL
|
|||
STR_1332 :{VELOCITY}
|
||||
STR_1333 :{STRINGID} - {STRINGID}{POP16}
|
||||
STR_1334 :{STRINGID} - {STRINGID} {COMMA16}
|
||||
STR_1335 :{STRINGID} - Entrance{POP16}{POP16}
|
||||
STR_1336 :{STRINGID} - Station {POP16}{COMMA16} Entrance
|
||||
STR_1337 :{STRINGID} - Exit{POP16}{POP16}
|
||||
STR_1338 :{STRINGID} - Station {POP16}{COMMA16} Exit
|
||||
STR_1335 :{STRINGID} - Entrée{POP16}{POP16}
|
||||
STR_1336 :{STRINGID} - Entrée de station {POP16}{COMMA16}
|
||||
STR_1337 :{STRINGID} - Sortie{POP16}{POP16}
|
||||
STR_1338 :{STRINGID} - Sortie de station {POP16}{COMMA16}
|
||||
STR_1339 :{BLACK}No test results yet...
|
||||
STR_1340 :{WINDOW_COLOUR_2}Max. speed: {BLACK}{VELOCITY}
|
||||
STR_1341 :{WINDOW_COLOUR_2}Ride time: {BLACK}{STRINGID}{STRINGID}{STRINGID}{STRINGID}
|
||||
|
@ -1416,7 +1416,7 @@ STR_1411 :{STRINGID} in the way
|
|||
STR_1412 :{WINDOW_COLOUR_3}Data logging not available for this type of ride
|
||||
STR_1413 :{WINDOW_COLOUR_3}Data logging will start when next {STRINGID} leaves {STRINGID}
|
||||
STR_1414 :{SMALLFONT}{BLACK}{DURATION}
|
||||
STR_1415 :{WINDOW_COLOUR_2}Velocity
|
||||
STR_1415 :{WINDOW_COLOUR_2}Vitesse
|
||||
STR_1416 :{WINDOW_COLOUR_2}Altitude
|
||||
STR_1417 :{WINDOW_COLOUR_2}Vert.G's
|
||||
STR_1418 :{WINDOW_COLOUR_2}Lat.G's
|
||||
|
@ -1436,9 +1436,9 @@ STR_1431 :Marche
|
|||
STR_1432 :Heading for {STRINGID}
|
||||
STR_1433 :Queuing for {STRINGID}
|
||||
STR_1434 :Drowning
|
||||
STR_1435 :On {STRINGID}
|
||||
STR_1436 :In {STRINGID}
|
||||
STR_1437 :At {STRINGID}
|
||||
STR_1435 :En {STRINGID}
|
||||
STR_1436 :Dans {STRINGID}
|
||||
STR_1437 :A {STRINGID}
|
||||
STR_1438 :Sitting
|
||||
STR_1439 :(select location)
|
||||
STR_1440 :Mowing grass
|
||||
|
@ -1469,7 +1469,7 @@ STR_1464 :Helix up (small)
|
|||
STR_1465 :Helix up (large)
|
||||
STR_1466 :Helix down (small)
|
||||
STR_1467 :Helix down (large)
|
||||
STR_1468 :Staff
|
||||
STR_1468 :Personnel
|
||||
STR_1469 :Ride must start and end with stations
|
||||
STR_1470 :Station not long enough
|
||||
STR_1471 :{WINDOW_COLOUR_2}Vitesse:
|
||||
|
@ -2681,37 +2681,37 @@ STR_2676 :???
|
|||
STR_2677 :???
|
||||
STR_2678 :???
|
||||
STR_2679 :???
|
||||
STR_2680 :???
|
||||
STR_2681 :???
|
||||
STR_2682 :???
|
||||
STR_2683 :???
|
||||
STR_2684 :???
|
||||
STR_2685 :???
|
||||
STR_2686 :???
|
||||
STR_2687 :???
|
||||
STR_2688 :???
|
||||
STR_2689 :???
|
||||
STR_2690 :???
|
||||
STR_2691 :???
|
||||
STR_2692 :???
|
||||
STR_2693 :???
|
||||
STR_2694 :???
|
||||
STR_2695 :???
|
||||
STR_2696 :???
|
||||
STR_2680 :All research complete
|
||||
STR_2681 :{MEDIUMFONT}{BLACK}Increases your money by 5,000
|
||||
STR_2682 :{MEDIUMFONT}{BLACK}Toggle between Free and Paid Entry
|
||||
STR_2683 :{MEDIUMFONT}{BLACK}Increases every peeps happiness to max
|
||||
STR_2684 :{MEDIUMFONT}{BLACK}Large group of peeps arrive
|
||||
STR_2685 :Simplex Noise Parameters
|
||||
STR_2686 :{WINDOW_COLOUR_2}Low:
|
||||
STR_2687 :{WINDOW_COLOUR_2}High:
|
||||
STR_2688 :{WINDOW_COLOUR_2}Base Frequency:
|
||||
STR_2689 :{WINDOW_COLOUR_2}Octaves:
|
||||
STR_2690 :Map Generation
|
||||
STR_2691 :{WINDOW_COLOUR_2}Base height:
|
||||
STR_2692 :{WINDOW_COLOUR_2}Water level:
|
||||
STR_2693 :{WINDOW_COLOUR_2}Terrain:
|
||||
STR_2694 :Generate
|
||||
STR_2695 :Random terrain
|
||||
STR_2696 :Place trees
|
||||
STR_2697 :???
|
||||
STR_2698 :???
|
||||
STR_2699 :???
|
||||
STR_2700 :???
|
||||
STR_2701 :???
|
||||
STR_2702 :???
|
||||
STR_2703 :???
|
||||
STR_2704 :???
|
||||
STR_2705 :???
|
||||
STR_2706 :???
|
||||
STR_2707 :???
|
||||
STR_2708 :???
|
||||
STR_2709 :???
|
||||
STR_2710 :???
|
||||
STR_2700 :Autosave frequency
|
||||
STR_2701 :Every week
|
||||
STR_2702 :Every 2 weeks
|
||||
STR_2703 :Every month
|
||||
STR_2704 :Every 4 months
|
||||
STR_2705 :Every year
|
||||
STR_2706 :Jamais
|
||||
STR_2707 :Open new window
|
||||
STR_2708 :{WINDOW_COLOUR_1}Are you sure you want to overwrite {STRINGID}?
|
||||
STR_2709 :Overwrite
|
||||
STR_2710 :Type the name of the file.
|
||||
STR_2711 :;
|
||||
STR_2712 :=
|
||||
STR_2713 :,
|
||||
|
@ -2719,50 +2719,50 @@ STR_2714 :-
|
|||
STR_2715 :.
|
||||
STR_2716 :/
|
||||
STR_2717 :'
|
||||
STR_2718 :???
|
||||
STR_2719 :???
|
||||
STR_2720 :???
|
||||
STR_2721 :???
|
||||
STR_2722 :???
|
||||
STR_2723 :???
|
||||
STR_2724 :???
|
||||
STR_2725 :???
|
||||
STR_2726 :???
|
||||
STR_2727 :???
|
||||
STR_2728 :???
|
||||
STR_2729 :???
|
||||
STR_2730 :???
|
||||
STR_2731 :???
|
||||
STR_2732 :???
|
||||
STR_2733 :???
|
||||
STR_2734 :???
|
||||
STR_2735 :???
|
||||
STR_2718 :(up)
|
||||
STR_2719 :(nouveau fichier)
|
||||
STR_2720 :{UINT16}s
|
||||
STR_2721 :{UINT16}s
|
||||
STR_2722 :{UINT16}m {UINT16}s
|
||||
STR_2723 :{UINT16}m {UINT16}s
|
||||
STR_2724 :{UINT16}mins:{UINT16}s
|
||||
STR_2725 :{UINT16}m {UINT16}s
|
||||
STR_2726 :{UINT16}m
|
||||
STR_2727 :{UINT16}m
|
||||
STR_2728 :{UINT16}h {UINT16}m
|
||||
STR_2729 :{UINT16}h {UINT16}m
|
||||
STR_2730 :{UINT16}h {UINT16}m
|
||||
STR_2731 :{UINT16}h {UINT16}m
|
||||
STR_2732 :{COMMA16}ft
|
||||
STR_2733 :{COMMA16}m
|
||||
STR_2734 :{COMMA16}mph
|
||||
STR_2735 :{COMMA16}km/h
|
||||
STR_2736 :{MONTH}, an {COMMA16}
|
||||
STR_2737 :{STRINGID} {MONTH}, an {COMMA16}
|
||||
STR_2738 :???
|
||||
STR_2739 :???
|
||||
STR_2740 :???
|
||||
STR_2741 :???
|
||||
STR_2742 :???
|
||||
STR_2743 :???
|
||||
STR_2738 :Title screen music
|
||||
STR_2739 :Aucun
|
||||
STR_2740 :RollerCoaster Tycoon 1
|
||||
STR_2741 :RollerCoaster Tycoon 2
|
||||
STR_2742 :css50.dat n'est pas trouvé
|
||||
STR_2743 :Copy data\css17.dat from your RCT1 installation to data\css50.dat in your RCT2 installation.
|
||||
STR_2744 :[
|
||||
STR_2745 :\
|
||||
STR_2746 :]
|
||||
STR_2747 :{ENDQUOTES}
|
||||
STR_2748 :Bar
|
||||
STR_2749 :???
|
||||
STR_2750 :???
|
||||
STR_2751 :???
|
||||
STR_2752 :???
|
||||
STR_2753 :???
|
||||
STR_2754 :???
|
||||
STR_2755 :???
|
||||
STR_2756 :???
|
||||
STR_2757 :???
|
||||
STR_2758 :???
|
||||
STR_2759 :???
|
||||
STR_2749 :Mon nouveau scénario
|
||||
STR_2750 :Move all items to top
|
||||
STR_2751 :Move all items to bottom
|
||||
STR_2752 :Clear grass
|
||||
STR_2753 :Mowed grass
|
||||
STR_2754 :Water plants
|
||||
STR_2755 :Fix vandalism
|
||||
STR_2756 :Remove litter
|
||||
STR_2757 :Force Sun
|
||||
STR_2758 :Force Thunder
|
||||
STR_2759 :Zero Clearance
|
||||
# New strings used in the cheats window previously these were ???
|
||||
STR_2760 :+5K Money
|
||||
STR_2760 :+5000 d'argent
|
||||
STR_2761 :Pay For Entrance
|
||||
STR_2762 :Pay For Rides
|
||||
STR_2763 :???
|
||||
|
@ -2771,19 +2771,19 @@ STR_2765 :Large Tram
|
|||
STR_2766 :???
|
||||
STR_2767 :Freeze Climate
|
||||
STR_2768 :Unfreeze Climate
|
||||
STR_2769 :Open Park
|
||||
STR_2770 :Close Park
|
||||
STR_2769 :Ouvrir le parc
|
||||
STR_2770 :Fermer le parc
|
||||
STR_2771 :Slower Gamespeed
|
||||
STR_2772 :Faster Gamespeed
|
||||
STR_2773 :Windowed
|
||||
STR_2774 :Fullscreen
|
||||
STR_2775 :Fullscreen (desktop)
|
||||
STR_2773 :En une fenêtre
|
||||
STR_2774 :Plein écran
|
||||
STR_2775 :Plein écran (desktop)
|
||||
STR_2776 :Langue
|
||||
STR_2777 :{MOVE_X}{SMALLFONT}{STRING}
|
||||
STR_2778 :{RIGHTGUILLEMET}{MOVE_X}{SMALLFONT}{STRING}
|
||||
# End of new strings
|
||||
STR_2779 :???
|
||||
STR_2780 :???
|
||||
STR_2779 :Viewport #{COMMA16}
|
||||
STR_2780 :Extra viewport
|
||||
STR_2781 :{STRINGID}:{MOVE_X}{195}{STRINGID}{STRINGID}
|
||||
STR_2782 :SHIFT +
|
||||
STR_2783 :CTRL +
|
||||
|
@ -2798,14 +2798,14 @@ STR_2791 :Enter name
|
|||
STR_2792 :Please enter your name for the scenario chart:
|
||||
STR_2793 :{SMALLFONT}(Completed by {STRINGID})
|
||||
STR_2794 :{WINDOW_COLOUR_2}Completed by: {BLACK}{STRINGID}{NEWLINE}{WINDOW_COLOUR_2} with a company value of: {BLACK}{CURRENCY}
|
||||
STR_2795 :Sort
|
||||
STR_2795 :Trier
|
||||
STR_2796 :{SMALLFONT}{BLACK}Sort the ride list into order using the information type displayed
|
||||
STR_2797 :Scroll view when pointer at screen edge
|
||||
STR_2798 :{SMALLFONT}{BLACK}Select whether to scroll the view when the mouse pointer is at the screen edge
|
||||
STR_2799 :{SMALLFONT}{BLACK}View or change control key assignments
|
||||
STR_2800 :{WINDOW_COLOUR_2}Total admissions: {BLACK}{COMMA32}
|
||||
STR_2801 :{WINDOW_COLOUR_2}Income from admissions: {BLACK}{CURRENCY2DP}
|
||||
STR_2802 :Map
|
||||
STR_2802 :Plan
|
||||
STR_2803 :{SMALLFONT}{BLACK}Show these guests highlighted on map
|
||||
STR_2804 :{SMALLFONT}{BLACK}Show these staff members highlighted on map
|
||||
STR_2805 :{SMALLFONT}{BLACK}Show map of park
|
||||
|
@ -2984,7 +2984,7 @@ STR_2977 :Staff member name
|
|||
STR_2978 :Enter new name for this member of staff:
|
||||
STR_2979 :Can't name staff member...
|
||||
STR_2980 :Too many banners in game
|
||||
STR_2981 :{RED}No entry - -
|
||||
STR_2981 :{RED}Accès interdit - -
|
||||
STR_2982 :Banner text
|
||||
STR_2983 :Enter new text for this banner:
|
||||
STR_2984 :Can't set new text for banner...
|
||||
|
@ -3059,7 +3059,7 @@ STR_3052 :Golf hole D
|
|||
STR_3053 :Golf hole E
|
||||
STR_3054 :Loading...
|
||||
STR_3055 :Blanc
|
||||
STR_3056 :Translucent
|
||||
STR_3056 :Transparent
|
||||
STR_3057 :{WINDOW_COLOUR_2}Construction Marker:
|
||||
STR_3058 :Brick walls
|
||||
STR_3059 :Hedges
|
||||
|
@ -3160,9 +3160,9 @@ STR_3153 :{SMALLFONT}{BLACK}Scroll {STRINGID} down fast
|
|||
STR_3154 :{SMALLFONT}{BLACK}Scroll {STRINGID} up/down
|
||||
STR_3155 :
|
||||
STR_3156 :
|
||||
STR_3157 :map
|
||||
STR_3158 :graph
|
||||
STR_3159 :list
|
||||
STR_3157 :plan
|
||||
STR_3158 :graphique
|
||||
STR_3159 :liste
|
||||
STR_3160 :RollerCoaster Tycoon 2: Première visite...
|
||||
STR_3161 :RollerCoaster Tycoon 2: Checking object files...
|
||||
STR_3162 :Unable to allocate enough memory
|
||||
|
@ -3170,8 +3170,8 @@ STR_3163 :Installing new data:
|
|||
STR_3164 :{BLACK}{COMMA16} selected (maximum {COMMA16})
|
||||
STR_3165 :
|
||||
STR_3166 :{BLACK}(ID:
|
||||
STR_3167 :{WINDOW_COLOUR_2}Includes: {BLACK}{COMMA16} objects
|
||||
STR_3168 :{WINDOW_COLOUR_2}Text: {BLACK}{STRINGID}
|
||||
STR_3167 :{WINDOW_COLOUR_2}Inclut: {BLACK}{COMMA16} objets
|
||||
STR_3168 :{WINDOW_COLOUR_2}Texte: {BLACK}{STRINGID}
|
||||
STR_3169 :Data for the following object not found:
|
||||
STR_3170 :Not enough space for graphics
|
||||
STR_3171 :Too many objects of this type selected
|
||||
|
@ -3208,7 +3208,7 @@ STR_3201 :Sélection des objets
|
|||
STR_3202 :Editeur de paysage
|
||||
STR_3203 :Liste d'inventions
|
||||
STR_3204 :Sélection des options
|
||||
STR_3205 :Objective Selection
|
||||
STR_3205 :Selection d'objectif
|
||||
STR_3206 :Sauvegarder scénario
|
||||
STR_3207 :Roller Coaster Designer
|
||||
STR_3208 :Track Designs Manager
|
||||
|
@ -3289,9 +3289,9 @@ STR_3282 :{SMALLFONT}{BLACK}Choisir objectif et nom du parc
|
|||
STR_3283 :{SMALLFONT}{BLACK}Select rides to be preserved
|
||||
STR_3284 :Sélection des objectifs
|
||||
STR_3285 :Preserved Rides
|
||||
STR_3286 :{SMALLFONT}{BLACK}Select objective for this scenario
|
||||
STR_3286 :{SMALLFONT}{BLACK}Selecter un objectif pour ce scénario
|
||||
STR_3287 :{WINDOW_COLOUR_2}Objectif:
|
||||
STR_3288 :{SMALLFONT}{BLACK}Select climate
|
||||
STR_3288 :{SMALLFONT}{BLACK}Selecter climat
|
||||
STR_3289 :{WINDOW_COLOUR_2}Climat:
|
||||
STR_3290 :Frais et humide
|
||||
STR_3291 :Chaud
|
||||
|
@ -3325,11 +3325,11 @@ STR_3318 :{SMALLFONT}{BLACK}Select which group this scenario appears in
|
|||
STR_3319 :{WINDOW_COLOUR_2}Scenario Group:
|
||||
STR_3320 :Unable to save scenario file...
|
||||
STR_3321 :New objects installed successfully
|
||||
STR_3322 :{WINDOW_COLOUR_2}Objective: {BLACK}{STRINGID}
|
||||
STR_3322 :{WINDOW_COLOUR_2}Objectif: {BLACK}{STRINGID}
|
||||
STR_3323 :Missing object data, ID:
|
||||
STR_3324 :Requires Add-On Pack:
|
||||
STR_3325 :Requires an Add-On Pack
|
||||
STR_3326 :{WINDOW_COLOUR_2}(no image)
|
||||
STR_3326 :{WINDOW_COLOUR_2}(aucune image)
|
||||
STR_3327 :Starting positions for people not set
|
||||
STR_3328 :Can't advance to next editor stage...
|
||||
STR_3329 :Park entrance not yet built
|
||||
|
@ -3450,3 +3450,11 @@ STR_3443 :Page 4
|
|||
STR_3444 :Page 5
|
||||
STR_3445 :Définir Zone de Patrouille
|
||||
STR_3446 :Annuler Zone de Patrouille
|
||||
|
||||
# New strings, cleaner
|
||||
STR_5120 :Show finances button on toolbar
|
||||
STR_5121 :Show research button on toolbar
|
||||
STR_5122 :Show all vehicles sharing a track/ride type
|
||||
STR_5123 :Renouveler attr.
|
||||
STR_5124 :Pas de Six Flags
|
||||
STR_5125 :All destructable
|
||||
|
|
|
@ -2737,8 +2737,8 @@ STR_2732 :???
|
|||
STR_2733 :???
|
||||
STR_2734 :???
|
||||
STR_2735 :???
|
||||
STR_2736 :???
|
||||
STR_2737 :???
|
||||
STR_2736 :{MONTH}, Year {COMMA16}
|
||||
STR_2737 :{STRINGID} {MONTH}, Year {COMMA16}
|
||||
STR_2738 :???
|
||||
STR_2739 :???
|
||||
STR_2740 :???
|
||||
|
|
|
@ -2737,8 +2737,8 @@ STR_2732 :???
|
|||
STR_2733 :???
|
||||
STR_2734 :???
|
||||
STR_2735 :???
|
||||
STR_2736 :???
|
||||
STR_2737 :???
|
||||
STR_2736 :{MONTH}, año {COMMA16}
|
||||
STR_2737 :{STRINGID} {MONTH}, año {COMMA16}
|
||||
STR_2738 :???
|
||||
STR_2739 :???
|
||||
STR_2740 :???
|
||||
|
|
|
@ -2739,8 +2739,8 @@ STR_2732 :???
|
|||
STR_2733 :???
|
||||
STR_2734 :???
|
||||
STR_2735 :???
|
||||
STR_2736 :???
|
||||
STR_2737 :???
|
||||
STR_2736 :{MONTH}, Year {COMMA16}
|
||||
STR_2737 :{STRINGID} {MONTH}, Year {COMMA16}
|
||||
STR_2738 :???
|
||||
STR_2739 :???
|
||||
STR_2740 :???
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# Version numbers to update
|
||||
!define /ifndef APPV_MAJOR 0
|
||||
!define /ifndef APPV_MINOR 2
|
||||
!define /ifndef APPV_MAINT 0
|
||||
!define /ifndef APPV_MINOR 0
|
||||
!define /ifndef APPV_MAINT 2
|
||||
!define /ifndef APPV_BUILD 0
|
||||
!define /ifndef APPV_EXTRA "-beta"
|
||||
|
||||
|
@ -488,9 +488,14 @@ DoUninstall: ; You have the same version as this installer. This allows you to
|
|||
Quit
|
||||
|
||||
InstallerIsOlder:
|
||||
;MessageBox MB_OK|MB_ICONSTOP \
|
||||
; "You have a newer version of ${APPNAME}.$\nSetup will now exit."
|
||||
;Quit
|
||||
MessageBox MB_OK|MB_ICONSTOP \
|
||||
"You have a newer version of ${APPNAME}.$\nSetup will now exit."
|
||||
Quit
|
||||
"You have a newer version of ${APPNAME}.$\nPlease note downgrading is currently untested."
|
||||
MessageBox MB_OK|MB_ICONQUESTION \
|
||||
"Welcome to ${APPNAMEANDVERSION} Setup.$\nThis will allow you to downgrade from version $OLDVERSION."
|
||||
Goto FinishCallback
|
||||
|
||||
FinishCallback:
|
||||
ClearErrors
|
||||
|
|
11
readme.md
11
readme.md
|
@ -58,7 +58,12 @@ The aim is to completely decompile RollerCoaster Tycoon 2 into C so that cross-p
|
|||
|
||||
# 2 Downloading the game / Building the source code
|
||||
|
||||
A third-party offers [downloadable precompiled builds](https://openrct2.com/download). However, building the project is always recommended.
|
||||
A couple of third parties offer downloadable precompiled builds. However, building the project is always recommended
|
||||
|
||||
[OpenRCT2.com](https://openrct2.com/download)
|
||||
[OpenRCT.net](https://openrct.net/builds.php)
|
||||
|
||||
There is also a Launcher available from [OpenRCT.net](https://openrct.net/download) that will automatically update your build so that you always have the current version as they are released.
|
||||
|
||||
## 2.1 Prerequisites
|
||||
### Windows:
|
||||
|
@ -132,6 +137,8 @@ Translations are in progress for German, Dutch, French, Hungarian, Polish, Spani
|
|||
# 5 More information
|
||||
- [GitHub](https://github.com/IntelOrca/OpenRCT2)
|
||||
- [Facebook](https://www.facebook.com/OpenRCT2)
|
||||
- [Automated Builds](https://openrct2.com/download)
|
||||
- [Automated builds](https://openrct2.com/download)
|
||||
- [Secondary site for automated builds](https://openrct.net/builds.php)
|
||||
- [Launcher that keeps your copy up-to-date](https://openrct.net/download)
|
||||
- [rct2 subreddit](http://www.reddit.com/r/rct/)
|
||||
- [openrct2 subreddit](http://www.reddit.com/r/openrct2)
|
||||
|
|
|
@ -316,6 +316,15 @@
|
|||
|
||||
#define RCT2_ADDRESS_TRACK_LIST 0x00F441EC
|
||||
|
||||
#define RCT2_ADDRESS_CTRL_PRESS_Z_COORDINATE 0x00F64ECC
|
||||
#define RCT2_ADDRESS_SHIFT_PRESS_X_COORDINATE 0x00F64ECE
|
||||
#define RCT2_ADDRESS_SHIFT_PRESS_Y_COORDINATE 0x00F64ED0
|
||||
#define RCT2_ADDRESS_SHIFT_PRESS_Z_VECTOR 0x00F64ED2
|
||||
#define RCT2_ADDRESS_SCENERY_Z_COORDINATE 0x00F64ED4
|
||||
|
||||
#define RCT2_ADDRESS_SCENERY_TOOL_CTRL_PRESSED 0x00F64F12
|
||||
#define RCT2_ADDRESS_SCENERY_TOOL_SHIFT_PRESSED 0x00F64F13
|
||||
|
||||
#define RCT2_ADDRESS_CURRENT_MONTH_YEAR 0x00F663A8
|
||||
#define RCT2_ADDRESS_CURRENT_MONTH_TICKS 0x00F663AA
|
||||
#define RCT2_ADDRESS_SCENARIO_TICKS 0x00F663AC
|
||||
|
|
|
@ -1427,13 +1427,8 @@ int sound_play_panned(int sound_id, int ebx, sint16 x, sint16 y, sint16 z)
|
|||
RCT2_GLOBAL(0x00F438AD, uint8) = 0;
|
||||
int volume = 0;
|
||||
if (ebx == 0x8001) {
|
||||
sint16 x2 = x & 0xFFE0; // round by 32
|
||||
sint16 y2 = y & 0xFFE0;
|
||||
if (x2 < 0x1FFF && y2 < 0x1FFF) {
|
||||
rct_map_element* mapelement = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[((y2 * 256 + x2) & 0xFFFF) / 8];
|
||||
while (map_element_get_type(mapelement) != MAP_ELEMENT_TYPE_SURFACE) {
|
||||
mapelement++;
|
||||
}
|
||||
rct_map_element* mapelement = map_get_surface_element_at(x / 32, y / 32);
|
||||
if (mapelement) {
|
||||
if ((mapelement->base_height * 8) - 5 > z) {
|
||||
RCT2_GLOBAL(0x00F438AD, uint8) = 10;
|
||||
}
|
||||
|
@ -1554,13 +1549,19 @@ void start_title_music()
|
|||
case 2:
|
||||
musicPathId = PATH_ID_CSS17;
|
||||
break;
|
||||
case 3:
|
||||
if (rand() & 1)
|
||||
musicPathId = PATH_ID_CSS50;
|
||||
else
|
||||
musicPathId = PATH_ID_CSS17;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((RCT2_GLOBAL(0x009AF284, uint32) & (1 << 0)) && RCT2_GLOBAL(0x009AF59D, uint8) & 1
|
||||
&& RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_TITLE_DEMO) {
|
||||
if (!RCT2_GLOBAL(0x009AF600, uint8)) {
|
||||
#ifdef USE_MIXER
|
||||
gTitleMusicChannel = Mixer_Play_Music(musicPathId);
|
||||
gTitleMusicChannel = Mixer_Play_Music(musicPathId, true);
|
||||
#else
|
||||
RCT2_GLOBAL(0x014241BC, uint32) = 1;
|
||||
int result = sound_channel_load_file2(3, (char*)get_file_path(musicPathId), 0);
|
||||
|
|
|
@ -31,21 +31,64 @@ extern "C" {
|
|||
|
||||
Mixer gMixer;
|
||||
|
||||
Sample::Sample()
|
||||
Source::~Source()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
unsigned long Source::GetSome(unsigned long offset, const uint8** data, unsigned long length)
|
||||
{
|
||||
if (offset >= Length()) {
|
||||
return 0;
|
||||
}
|
||||
unsigned long size = length;
|
||||
if (offset + length > Length()) {
|
||||
size = Length() - offset;
|
||||
}
|
||||
return Read(offset, data, size);
|
||||
}
|
||||
|
||||
unsigned long Source::Length()
|
||||
{
|
||||
return length;
|
||||
}
|
||||
|
||||
const AudioFormat& Source::Format()
|
||||
{
|
||||
return format;
|
||||
}
|
||||
|
||||
Source_Null::Source_Null()
|
||||
{
|
||||
length = 0;
|
||||
}
|
||||
|
||||
unsigned long Source_Null::Read(unsigned long offset, const uint8** data, unsigned long length)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
Source_Sample::Source_Sample()
|
||||
{
|
||||
data = 0;
|
||||
length = 0;
|
||||
issdlwav = false;
|
||||
}
|
||||
|
||||
Sample::~Sample()
|
||||
Source_Sample::~Source_Sample()
|
||||
{
|
||||
Unload();
|
||||
}
|
||||
|
||||
bool Sample::Load(const char* filename)
|
||||
unsigned long Source_Sample::Read(unsigned long offset, const uint8** data, unsigned long length)
|
||||
{
|
||||
log_verbose("Sample::Load(%s)", filename);
|
||||
*data = &Source_Sample::data[offset];
|
||||
return length;
|
||||
}
|
||||
|
||||
bool Source_Sample::LoadWAV(const char* filename)
|
||||
{
|
||||
log_verbose("Source_Sample::LoadWAV(%s)", filename);
|
||||
|
||||
utf8 utf8filename[512];
|
||||
win1252_to_utf8(utf8filename, filename, sizeof(utf8filename));
|
||||
|
@ -75,9 +118,9 @@ bool Sample::Load(const char* filename)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool Sample::LoadCSS1(const char* filename, unsigned int offset)
|
||||
bool Source_Sample::LoadCSS1(const char* filename, unsigned int offset)
|
||||
{
|
||||
log_verbose("Sample::LoadCSS1(%s, %d)", filename, offset);
|
||||
log_verbose("Source_Sample::LoadCSS1(%s, %d)", filename, offset);
|
||||
|
||||
utf8 utf8filename[512];
|
||||
win1252_to_utf8(utf8filename, filename, sizeof(utf8filename));
|
||||
|
@ -107,13 +150,18 @@ bool Sample::LoadCSS1(const char* filename, unsigned int offset)
|
|||
format.freq = waveformat.nSamplesPerSec;
|
||||
format.format = AUDIO_S16LSB;
|
||||
format.channels = waveformat.nChannels;
|
||||
data = new uint8[length];
|
||||
data = new (std::nothrow) uint8[length];
|
||||
if (!data) {
|
||||
log_verbose("Unable to allocate data");
|
||||
SDL_RWclose(rw);
|
||||
return false;
|
||||
}
|
||||
SDL_RWread(rw, data, length, 1);
|
||||
SDL_RWclose(rw);
|
||||
return true;
|
||||
}
|
||||
|
||||
void Sample::Unload()
|
||||
void Source_Sample::Unload()
|
||||
{
|
||||
if (data) {
|
||||
if (issdlwav) {
|
||||
|
@ -127,16 +175,11 @@ void Sample::Unload()
|
|||
length = 0;
|
||||
}
|
||||
|
||||
bool Sample::Loaded()
|
||||
bool Source_Sample::Convert(AudioFormat format)
|
||||
{
|
||||
return data != 0;
|
||||
}
|
||||
|
||||
bool Sample::Convert(AudioFormat format)
|
||||
{
|
||||
if(Sample::format.format != format.format || Sample::format.channels != format.channels || Sample::format.freq != format.freq){
|
||||
if(Source_Sample::format.format != format.format || Source_Sample::format.channels != format.channels || Source_Sample::format.freq != format.freq){
|
||||
SDL_AudioCVT cvt;
|
||||
if (SDL_BuildAudioCVT(&cvt, Sample::format.format, Sample::format.channels, Sample::format.freq, format.format, format.channels, format.freq) < 0) {
|
||||
if (SDL_BuildAudioCVT(&cvt, Source_Sample::format.format, Source_Sample::format.channels, Source_Sample::format.freq, format.format, format.channels, format.freq) < 0) {
|
||||
return false;
|
||||
}
|
||||
cvt.len = length;
|
||||
|
@ -149,69 +192,149 @@ bool Sample::Convert(AudioFormat format)
|
|||
Unload();
|
||||
data = cvt.buf;
|
||||
length = cvt.len_cvt;
|
||||
Sample::format = format;
|
||||
Source_Sample::format = format;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const uint8* Sample::Data()
|
||||
Source_SampleStream::Source_SampleStream()
|
||||
{
|
||||
return data;
|
||||
length = 0;
|
||||
rw = NULL;
|
||||
buffer = 0;
|
||||
buffersize = 0;
|
||||
}
|
||||
|
||||
unsigned long Sample::Length()
|
||||
Source_SampleStream::~Source_SampleStream()
|
||||
{
|
||||
return length;
|
||||
Unload();
|
||||
}
|
||||
|
||||
Stream::Stream()
|
||||
unsigned long Source_SampleStream::Read(unsigned long offset, const uint8** data, unsigned long length)
|
||||
{
|
||||
sourcetype = SOURCE_NONE;
|
||||
if (length > buffersize) {
|
||||
if (buffer) {
|
||||
delete[] buffer;
|
||||
}
|
||||
|
||||
unsigned long Stream::GetSome(unsigned long offset, const uint8** data, unsigned long length)
|
||||
{
|
||||
unsigned long size = length;
|
||||
switch(sourcetype) {
|
||||
case SOURCE_SAMPLE:
|
||||
if (offset >= sample->Length()) {
|
||||
buffer = new (std::nothrow) uint8[length];
|
||||
if (!buffer) {
|
||||
return 0;
|
||||
}
|
||||
if (offset + length > sample->Length()) {
|
||||
size = sample->Length() - offset;
|
||||
buffersize = length;
|
||||
}
|
||||
*data = &sample->Data()[offset];
|
||||
return size;
|
||||
Sint64 currentposition = SDL_RWtell(rw);
|
||||
if (currentposition == -1) {
|
||||
return 0;
|
||||
}
|
||||
if (currentposition - databegin != offset) {
|
||||
Sint64 newposition = SDL_RWseek(rw, databegin + offset, SEEK_SET);
|
||||
if (newposition == -1) {
|
||||
return 0;
|
||||
}
|
||||
currentposition = newposition;
|
||||
}
|
||||
*data = buffer;
|
||||
int read = SDL_RWread(rw, buffer, 1, length);
|
||||
if (read == -1) {
|
||||
return 0;
|
||||
}
|
||||
return read;
|
||||
}
|
||||
|
||||
bool Source_SampleStream::LoadWAV(SDL_RWops* rw)
|
||||
{
|
||||
Unload();
|
||||
if (rw == NULL) {
|
||||
return false;
|
||||
}
|
||||
Source_SampleStream::rw = rw;
|
||||
Uint32 chunk_id = SDL_ReadLE32(rw);
|
||||
const Uint32 RIFF = 0x46464952;
|
||||
if (chunk_id != RIFF) {
|
||||
log_verbose("Not a WAV file");
|
||||
return false;
|
||||
}
|
||||
Uint32 chunk_size = SDL_ReadLE32(rw);
|
||||
Uint32 chunk_format = SDL_ReadLE32(rw);
|
||||
const Uint32 WAVE = 0x45564157;
|
||||
if (chunk_format != WAVE) {
|
||||
log_verbose("Not in WAVE format");
|
||||
return false;
|
||||
}
|
||||
const Uint32 FMT = 0x20746D66;
|
||||
Uint32 fmtchunk_size = FindChunk(rw, FMT);
|
||||
if (!fmtchunk_size) {
|
||||
log_verbose("Could not find FMT chunk");
|
||||
return false;
|
||||
}
|
||||
Uint64 chunkstart = SDL_RWtell(rw);
|
||||
PCMWAVEFORMAT waveformat;
|
||||
SDL_RWread(rw, &waveformat, sizeof(waveformat), 1);
|
||||
SDL_RWseek(rw, chunkstart + fmtchunk_size, RW_SEEK_SET);
|
||||
if (waveformat.wf.wFormatTag != WAVE_FORMAT_PCM) {
|
||||
log_verbose("Not in proper format");
|
||||
return false;
|
||||
}
|
||||
format.freq = waveformat.wf.nSamplesPerSec;
|
||||
switch (waveformat.wBitsPerSample) {
|
||||
case 8:
|
||||
format.format = AUDIO_U8;
|
||||
break;
|
||||
case 16:
|
||||
format.format = AUDIO_S16LSB;
|
||||
break;
|
||||
default:
|
||||
log_verbose("Invalid bits per sample");
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
format.channels = waveformat.wf.nChannels;
|
||||
const Uint32 DATA = 0x61746164;
|
||||
Uint32 datachunk_size = FindChunk(rw, DATA);
|
||||
if (!datachunk_size) {
|
||||
log_verbose("Could not find DATA chunk");
|
||||
return false;
|
||||
}
|
||||
length = datachunk_size;
|
||||
databegin = SDL_RWtell(rw);
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned long Stream::Length()
|
||||
Uint32 Source_SampleStream::FindChunk(SDL_RWops* rw, Uint32 wanted_id)
|
||||
{
|
||||
switch(sourcetype) {
|
||||
case SOURCE_SAMPLE:
|
||||
return sample->Length();
|
||||
break;
|
||||
Uint32 subchunk_id = SDL_ReadLE32(rw);
|
||||
Uint32 subchunk_size = SDL_ReadLE32(rw);
|
||||
if (subchunk_id == wanted_id) {
|
||||
return subchunk_size;
|
||||
}
|
||||
const Uint32 FACT = 0x74636166;
|
||||
const Uint32 LIST = 0x5453494c;
|
||||
const Uint32 BEXT = 0x74786562;
|
||||
const Uint32 JUNK = 0x4B4E554A;
|
||||
while (subchunk_id == FACT || subchunk_id == LIST || subchunk_id == BEXT || subchunk_id == JUNK) {
|
||||
SDL_RWseek(rw, subchunk_size, RW_SEEK_CUR);
|
||||
subchunk_id = SDL_ReadLE32(rw);
|
||||
subchunk_size = SDL_ReadLE32(rw);
|
||||
if (subchunk_id == wanted_id) {
|
||||
return subchunk_size;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Stream::SetSource_Sample(Sample& sample)
|
||||
void Source_SampleStream::Unload()
|
||||
{
|
||||
sourcetype = SOURCE_SAMPLE;
|
||||
Stream::sample = &sample;
|
||||
if (rw) {
|
||||
SDL_RWclose(rw);
|
||||
rw = NULL;
|
||||
}
|
||||
|
||||
const AudioFormat* Stream::Format()
|
||||
{
|
||||
switch(sourcetype) {
|
||||
case SOURCE_SAMPLE:
|
||||
return &sample->format;
|
||||
break;
|
||||
length = 0;
|
||||
if (buffer) {
|
||||
delete[] buffer;
|
||||
buffer = 0;
|
||||
}
|
||||
return 0;
|
||||
buffersize = 0;
|
||||
}
|
||||
|
||||
Channel::Channel()
|
||||
|
@ -220,10 +343,13 @@ Channel::Channel()
|
|||
SetRate(1);
|
||||
SetVolume(SDL_MIX_MAXVOLUME);
|
||||
oldvolume = 0;
|
||||
oldvolume_l = 0;
|
||||
oldvolume_r = 0;
|
||||
SetPan(0.5f);
|
||||
done = true;
|
||||
stopping = false;
|
||||
stream = 0;
|
||||
source = 0;
|
||||
deletesourceondone = false;
|
||||
}
|
||||
|
||||
Channel::~Channel()
|
||||
|
@ -232,11 +358,14 @@ Channel::~Channel()
|
|||
speex_resampler_destroy(resampler);
|
||||
resampler = 0;
|
||||
}
|
||||
if (deletesourceondone) {
|
||||
delete source;
|
||||
}
|
||||
}
|
||||
|
||||
void Channel::Play(Stream& stream, int loop = MIXER_LOOP_NONE)
|
||||
void Channel::Play(Source& source, int loop = MIXER_LOOP_NONE)
|
||||
{
|
||||
Channel::stream = &stream;
|
||||
Channel::source = &source;
|
||||
Channel::loop = loop;
|
||||
offset = 0;
|
||||
done = false;
|
||||
|
@ -270,8 +399,15 @@ void Channel::SetPan(float pan)
|
|||
if (pan < 0) {
|
||||
Channel::pan = 0;
|
||||
}
|
||||
volume_l = (float)sin((1.0 - Channel::pan) * M_PI / 2.0);
|
||||
volume_r = (float)sin(Channel::pan * M_PI / 2.0);
|
||||
double decibels = (abs(Channel::pan - 0.5) * 2.0) * 100.0;
|
||||
double attenuation = pow(10, decibels / 20.0);
|
||||
if (Channel::pan <= 0.5) {
|
||||
volume_l = 1.0;
|
||||
volume_r = float(1.0 / attenuation);
|
||||
} else {
|
||||
volume_r = 1.0;
|
||||
volume_l = float(1.0 / attenuation);
|
||||
}
|
||||
}
|
||||
|
||||
bool Channel::IsPlaying()
|
||||
|
@ -286,14 +422,25 @@ unsigned long Channel::GetOffset()
|
|||
|
||||
bool Channel::SetOffset(unsigned long offset)
|
||||
{
|
||||
if (stream && offset < stream->Length()) {
|
||||
int samplesize = stream->Format()->channels * stream->Format()->BytesPerSample();
|
||||
if (source && offset < source->Length()) {
|
||||
int samplesize = source->Format().channels * source->Format().BytesPerSample();
|
||||
Channel::offset = (offset / samplesize) * samplesize;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Mixer::Mixer()
|
||||
{
|
||||
effectbuffer = 0;
|
||||
for (int i = 0; i < countof(css1sources); i++) {
|
||||
css1sources[i] = 0;
|
||||
}
|
||||
for (int i = 0; i < countof(musicsources); i++) {
|
||||
musicsources[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Mixer::Init(const char* device)
|
||||
{
|
||||
Close();
|
||||
|
@ -310,10 +457,15 @@ void Mixer::Init(const char* device)
|
|||
format.channels = have.channels;
|
||||
format.freq = have.freq;
|
||||
const char* filename = get_file_path(PATH_ID_CSS1);
|
||||
for (int i = 0; i < SOUND_MAXID; i++) {
|
||||
css1samples[i].LoadCSS1(filename, i);
|
||||
css1samples[i].Convert(format); // convert to audio output format, saves some cpu usage but requires a bit more memory, optional
|
||||
css1streams[i].SetSource_Sample(css1samples[i]);
|
||||
for (int i = 0; i < countof(css1sources); i++) {
|
||||
Source_Sample* source_sample = new Source_Sample;
|
||||
if (source_sample->LoadCSS1(filename, i)) {
|
||||
source_sample->Convert(format); // convert to audio output format, saves some cpu usage but requires a bit more memory, optional
|
||||
css1sources[i] = source_sample;
|
||||
} else {
|
||||
css1sources[i] = &source_null;
|
||||
delete source_sample;
|
||||
}
|
||||
}
|
||||
effectbuffer = new uint8[(have.samples * format.BytesPerSample() * format.channels)];
|
||||
SDL_PauseAudioDevice(deviceid, 0);
|
||||
|
@ -328,7 +480,22 @@ void Mixer::Close()
|
|||
}
|
||||
Unlock();
|
||||
SDL_CloseAudioDevice(deviceid);
|
||||
for (int i = 0; i < countof(css1sources); i++) {
|
||||
if (css1sources[i] && css1sources[i] != &source_null) {
|
||||
delete css1sources[i];
|
||||
css1sources[i] = 0;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < countof(musicsources); i++) {
|
||||
if (musicsources[i] && musicsources[i] != &source_null) {
|
||||
delete musicsources[i];
|
||||
musicsources[i] = 0;
|
||||
}
|
||||
}
|
||||
if (effectbuffer) {
|
||||
delete[] effectbuffer;
|
||||
effectbuffer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Mixer::Lock()
|
||||
|
@ -341,13 +508,14 @@ void Mixer::Unlock()
|
|||
SDL_UnlockAudioDevice(deviceid);
|
||||
}
|
||||
|
||||
Channel* Mixer::Play(Stream& stream, int loop, bool deleteondone)
|
||||
Channel* Mixer::Play(Source& source, int loop, bool deleteondone, bool deletesourceondone)
|
||||
{
|
||||
Lock();
|
||||
Channel* newchannel = new (std::nothrow) Channel();
|
||||
Channel* newchannel = new (std::nothrow) Channel;
|
||||
if (newchannel) {
|
||||
newchannel->Play(stream, loop);
|
||||
newchannel->Play(source, loop);
|
||||
newchannel->deleteondone = deleteondone;
|
||||
newchannel->deletesourceondone = deletesourceondone;
|
||||
newchannel->stopping = false;
|
||||
channels.push_back(newchannel);
|
||||
}
|
||||
|
@ -364,13 +532,20 @@ void Mixer::Stop(Channel& channel)
|
|||
|
||||
bool Mixer::LoadMusic(int pathid)
|
||||
{
|
||||
if (pathid >= PATH_ID_END) {
|
||||
if (pathid >= countof(musicsources)) {
|
||||
return false;
|
||||
}
|
||||
if (!musicsamples[pathid].Loaded()) {
|
||||
if (!musicsources[pathid]) {
|
||||
const char* filename = get_file_path(pathid);
|
||||
musicstreams[pathid].SetSource_Sample(musicsamples[pathid]);
|
||||
return musicsamples[pathid].Load(filename);
|
||||
Source_Sample* source_sample = new Source_Sample;
|
||||
if (source_sample->LoadWAV(filename)) {
|
||||
musicsources[pathid] = source_sample;
|
||||
return true;
|
||||
} else {
|
||||
delete source_sample;
|
||||
musicsources[pathid] = &source_null;
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
|
@ -394,8 +569,8 @@ void SDLCALL Mixer::Callback(void* arg, uint8* stream, int length)
|
|||
|
||||
void Mixer::MixChannel(Channel& channel, uint8* data, int length)
|
||||
{
|
||||
if (channel.stream && !channel.done) {
|
||||
AudioFormat streamformat = *channel.stream->Format();
|
||||
if (channel.source && channel.source->Length() > 0 && !channel.done) {
|
||||
AudioFormat streamformat = channel.source->Format();
|
||||
int loaded = 0;
|
||||
SDL_AudioCVT cvt;
|
||||
cvt.len_ratio = 1;
|
||||
|
@ -409,9 +584,9 @@ void Mixer::MixChannel(Channel& channel, uint8* data, int length)
|
|||
}
|
||||
int samplestoread = (int)((samples - samplesloaded) * rate);
|
||||
int lengthloaded = 0;
|
||||
if (channel.offset < channel.stream->Length()) {
|
||||
if (channel.offset < channel.source->Length()) {
|
||||
bool mustconvert = false;
|
||||
if (MustConvert(*channel.stream)) {
|
||||
if (MustConvert(*channel.source)) {
|
||||
if (SDL_BuildAudioCVT(&cvt, streamformat.format, streamformat.channels, streamformat.freq, Mixer::format.format, Mixer::format.channels, Mixer::format.freq) == -1) {
|
||||
break;
|
||||
}
|
||||
|
@ -420,7 +595,7 @@ void Mixer::MixChannel(Channel& channel, uint8* data, int length)
|
|||
|
||||
const uint8* datastream = 0;
|
||||
int toread = (int)(samplestoread / cvt.len_ratio) * samplesize;
|
||||
int readfromstream = (channel.stream->GetSome(channel.offset, &datastream, toread));
|
||||
int readfromstream = (channel.source->GetSome(channel.offset, &datastream, toread));
|
||||
if (readfromstream == 0) {
|
||||
break;
|
||||
}
|
||||
|
@ -519,7 +694,7 @@ void Mixer::MixChannel(Channel& channel, uint8* data, int length)
|
|||
|
||||
loaded += lengthloaded;
|
||||
|
||||
if (channel.loop != 0 && channel.offset >= channel.stream->Length()) {
|
||||
if (channel.loop != 0 && channel.offset >= channel.source->Length()) {
|
||||
if (channel.loop != -1) {
|
||||
channel.loop--;
|
||||
}
|
||||
|
@ -528,7 +703,9 @@ void Mixer::MixChannel(Channel& channel, uint8* data, int length)
|
|||
} while(loaded < length && channel.loop != 0 && !channel.stopping);
|
||||
|
||||
channel.oldvolume = channel.volume;
|
||||
if (channel.loop == 0 && channel.offset >= channel.stream->Length()) {
|
||||
channel.oldvolume_l = channel.volume_l;
|
||||
channel.oldvolume_r = channel.volume_r;
|
||||
if (channel.loop == 0 && channel.offset >= channel.source->Length()) {
|
||||
channel.done = true;
|
||||
}
|
||||
}
|
||||
|
@ -536,21 +713,19 @@ void Mixer::MixChannel(Channel& channel, uint8* data, int length)
|
|||
|
||||
void Mixer::EffectPanS16(Channel& channel, sint16* data, int length)
|
||||
{
|
||||
float left = channel.volume_l;
|
||||
float right = channel.volume_r;
|
||||
for (int i = 0; i < length * 2; i += 2) {
|
||||
data[i] = (sint16)(data[i] * left);
|
||||
data[i + 1] = (sint16)(data[i + 1] * right);
|
||||
float t = (float)i / (length * 2);
|
||||
data[i] = (sint16)(data[i] * ((1.0 - t) * channel.oldvolume_l + t * channel.volume_l));
|
||||
data[i + 1] = (sint16)(data[i + 1] * ((1.0 - t) * channel.oldvolume_r + t * channel.volume_r));
|
||||
}
|
||||
}
|
||||
|
||||
void Mixer::EffectPanU8(Channel& channel, uint8* data, int length)
|
||||
{
|
||||
float left = channel.volume_l;
|
||||
float right = channel.volume_r;
|
||||
for (int i = 0; i < length * 2; i += 2) {
|
||||
data[i] = (uint8)(data[i] * left);
|
||||
data[i + 1] = (uint8)(data[i + 1] * right);
|
||||
float t = (float)i / (length * 2);
|
||||
data[i] = (uint8)(data[i] * ((1.0 - t) * channel.oldvolume_l + t * channel.volume_l));
|
||||
data[i + 1] = (uint8)(data[i + 1] * ((1.0 - t) * channel.oldvolume_r + t * channel.volume_r));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -574,13 +749,10 @@ void Mixer::EffectFadeU8(uint8* data, int length, int startvolume, int endvolume
|
|||
}
|
||||
}
|
||||
|
||||
bool Mixer::MustConvert(Stream& stream)
|
||||
bool Mixer::MustConvert(Source& source)
|
||||
{
|
||||
const AudioFormat* streamformat = stream.Format();
|
||||
if (!streamformat) {
|
||||
return false;
|
||||
}
|
||||
if (streamformat->format != format.format || streamformat->channels != format.channels || streamformat->freq != format.freq) {
|
||||
const AudioFormat sourceformat = source.Format();
|
||||
if (sourceformat.format != format.format || sourceformat.channels != format.channels || sourceformat.freq != format.freq) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -609,11 +781,11 @@ void Mixer_Init(const char* device)
|
|||
|
||||
void* Mixer_Play_Effect(int id, int loop, int volume, float pan, double rate, int deleteondone)
|
||||
{
|
||||
if (id >= SOUND_MAXID) {
|
||||
if (id >= countof(gMixer.css1sources)) {
|
||||
return 0;
|
||||
}
|
||||
gMixer.Lock();
|
||||
Channel* channel = gMixer.Play(gMixer.css1streams[id], loop, deleteondone != 0);
|
||||
Channel* channel = gMixer.Play(*gMixer.css1sources[id], loop, deleteondone != 0, false);
|
||||
if (channel) {
|
||||
channel->SetVolume(volume);
|
||||
channel->SetPan(pan);
|
||||
|
@ -664,10 +836,33 @@ int Mixer_Channel_SetOffset(void* channel, unsigned long offset)
|
|||
return ((Channel*)channel)->SetOffset(offset);
|
||||
}
|
||||
|
||||
void* Mixer_Play_Music(int pathid)
|
||||
void* Mixer_Play_Music(int pathid, int streaming)
|
||||
{
|
||||
if (streaming) {
|
||||
const char* filename = get_file_path(pathid);
|
||||
|
||||
utf8 utf8filename[512];
|
||||
win1252_to_utf8(utf8filename, filename, sizeof(utf8filename));
|
||||
|
||||
SDL_RWops* rw = SDL_RWFromFile(utf8filename, "rb");
|
||||
if (rw == NULL) {
|
||||
return 0;
|
||||
}
|
||||
Source_SampleStream* source_samplestream = new Source_SampleStream;
|
||||
if (source_samplestream->LoadWAV(rw)) {
|
||||
Channel* channel = gMixer.Play(*source_samplestream, MIXER_LOOP_INFINITE, false, true);
|
||||
if (!channel) {
|
||||
delete source_samplestream;
|
||||
}
|
||||
return channel;
|
||||
} else {
|
||||
delete source_samplestream;
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
if (gMixer.LoadMusic(pathid)) {
|
||||
return gMixer.Play(gMixer.musicstreams[pathid], MIXER_LOOP_INFINITE, false);
|
||||
return gMixer.Play(*gMixer.musicsources[pathid], MIXER_LOOP_INFINITE, false, false);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -43,45 +43,73 @@ struct AudioFormat {
|
|||
int channels;
|
||||
};
|
||||
|
||||
class Sample
|
||||
class Source
|
||||
{
|
||||
public:
|
||||
Sample();
|
||||
~Sample();
|
||||
bool Load(const char* filename);
|
||||
bool LoadCSS1(const char* filename, unsigned int offset);
|
||||
void Unload();
|
||||
bool Loaded();
|
||||
bool Convert(AudioFormat format);
|
||||
const uint8* Data();
|
||||
unsigned long Length();
|
||||
|
||||
friend class Stream;
|
||||
|
||||
private:
|
||||
AudioFormat format;
|
||||
uint8* data;
|
||||
unsigned long length;
|
||||
bool issdlwav;
|
||||
};
|
||||
|
||||
class Stream
|
||||
{
|
||||
public:
|
||||
Stream();
|
||||
virtual ~Source();
|
||||
unsigned long GetSome(unsigned long offset, const uint8** data, unsigned long length);
|
||||
unsigned long Length();
|
||||
void SetSource_Sample(Sample& sample);
|
||||
const AudioFormat* Format();
|
||||
const AudioFormat& Format();
|
||||
|
||||
friend class Mixer;
|
||||
|
||||
protected:
|
||||
virtual unsigned long Read(unsigned long offset, const uint8** data, unsigned long length) = 0;
|
||||
|
||||
AudioFormat format;
|
||||
unsigned long length;
|
||||
};
|
||||
|
||||
class Source_Null : public Source
|
||||
{
|
||||
public:
|
||||
Source_Null();
|
||||
|
||||
protected:
|
||||
unsigned long Read(unsigned long offset, const uint8** data, unsigned long length);
|
||||
};
|
||||
|
||||
class Source_Sample : public Source
|
||||
{
|
||||
public:
|
||||
Source_Sample();
|
||||
~Source_Sample();
|
||||
bool LoadWAV(const char* filename);
|
||||
bool LoadCSS1(const char* filename, unsigned int offset);
|
||||
|
||||
friend class Mixer;
|
||||
|
||||
protected:
|
||||
bool Convert(AudioFormat format);
|
||||
|
||||
private:
|
||||
enum {
|
||||
SOURCE_NONE = 0,
|
||||
SOURCE_SAMPLE
|
||||
} sourcetype;
|
||||
Sample* sample;
|
||||
void Unload();
|
||||
|
||||
uint8* data;
|
||||
bool issdlwav;
|
||||
|
||||
protected:
|
||||
unsigned long Read(unsigned long offset, const uint8** data, unsigned long length);
|
||||
};
|
||||
|
||||
class Source_SampleStream : public Source
|
||||
{
|
||||
public:
|
||||
Source_SampleStream();
|
||||
~Source_SampleStream();
|
||||
bool LoadWAV(SDL_RWops* rw);
|
||||
|
||||
private:
|
||||
Uint32 FindChunk(SDL_RWops* rw, Uint32 wanted_id);
|
||||
void Unload();
|
||||
|
||||
SDL_RWops* rw;
|
||||
Uint64 databegin;
|
||||
uint8* buffer;
|
||||
unsigned long buffersize;
|
||||
|
||||
protected:
|
||||
unsigned long Read(unsigned long offset, const uint8** data, unsigned long length);
|
||||
};
|
||||
|
||||
class Channel
|
||||
|
@ -89,7 +117,7 @@ class Channel
|
|||
public:
|
||||
Channel();
|
||||
~Channel();
|
||||
void Play(Stream& stream, int loop);
|
||||
void Play(Source& source, int loop);
|
||||
void SetRate(double rate);
|
||||
void SetVolume(int volume);
|
||||
void SetPan(float pan);
|
||||
|
@ -105,28 +133,31 @@ private:
|
|||
double rate;
|
||||
int volume;
|
||||
float volume_l, volume_r;
|
||||
float oldvolume_l, oldvolume_r;
|
||||
float pan;
|
||||
bool done;
|
||||
bool deleteondone;
|
||||
bool deletesourceondone;
|
||||
bool stopping;
|
||||
int oldvolume;
|
||||
SpeexResamplerState* resampler;
|
||||
Stream* stream;
|
||||
Source* source;
|
||||
};
|
||||
|
||||
class Mixer
|
||||
{
|
||||
public:
|
||||
Mixer();
|
||||
void Init(const char* device);
|
||||
void Close();
|
||||
void Lock();
|
||||
void Unlock();
|
||||
Channel* Play(Stream& stream, int loop, bool deleteondone);
|
||||
Channel* Play(Source& source, int loop, bool deleteondone, bool deletesourceondone);
|
||||
void Stop(Channel& channel);
|
||||
bool LoadMusic(int pathid);
|
||||
|
||||
Stream css1streams[SOUND_MAXID];
|
||||
Stream musicstreams[PATH_ID_END];
|
||||
Source* css1sources[SOUND_MAXID];
|
||||
Source* musicsources[PATH_ID_END];
|
||||
|
||||
private:
|
||||
static void SDLCALL Callback(void* arg, uint8* data, int length);
|
||||
|
@ -135,14 +166,13 @@ private:
|
|||
void EffectPanU8(Channel& channel, uint8* data, int length);
|
||||
void EffectFadeS16(sint16* data, int length, int startvolume, int endvolume);
|
||||
void EffectFadeU8(uint8* data, int length, int startvolume, int endvolume);
|
||||
bool MustConvert(Stream& stream);
|
||||
bool MustConvert(Source& source);
|
||||
bool Convert(SDL_AudioCVT& cvt, const uint8* data, unsigned long length, uint8** dataout);
|
||||
SDL_AudioDeviceID deviceid;
|
||||
AudioFormat format;
|
||||
uint8* effectbuffer;
|
||||
Sample css1samples[SOUND_MAXID];
|
||||
Sample musicsamples[PATH_ID_END];
|
||||
std::list<Channel*> channels;
|
||||
Source_Null source_null;
|
||||
};
|
||||
|
||||
extern "C"
|
||||
|
@ -158,7 +188,7 @@ void Mixer_Channel_Rate(void* channel, double rate);
|
|||
int Mixer_Channel_IsPlaying(void* channel);
|
||||
unsigned long Mixer_Channel_GetOffset(void* channel);
|
||||
int Mixer_Channel_SetOffset(void* channel, unsigned long offset);
|
||||
void* Mixer_Play_Music(int pathid);
|
||||
void* Mixer_Play_Music(int pathid, int streaming);
|
||||
|
||||
static int DStoMixerVolume(int volume) { return (int)(SDL_MIX_MAXVOLUME * (SDL_pow(10, (float)volume / 2000))); };
|
||||
static float DStoMixerPan(int pan) { return (((float)pan + -DSBPAN_LEFT) / DSBPAN_RIGHT) / 2; };
|
||||
|
|
|
@ -1006,11 +1006,11 @@ void gfx_draw_string(rct_drawpixelinfo *dpi, char *buffer, int colour, int x, in
|
|||
skip_char = 1;
|
||||
break;
|
||||
}
|
||||
ebx = *((uint16*)(buffer - 3));
|
||||
eax = ebx & 0x7FFFF;
|
||||
g1_element = &(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[eax]);
|
||||
uint32 image_id = *((uint32*)(buffer - 3));
|
||||
uint32 image_offset = image_id & 0x7FFFF;
|
||||
g1_element = &(RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[image_offset]);
|
||||
|
||||
gfx_draw_sprite(dpi, ebx, max_x, max_y, 0);
|
||||
gfx_draw_sprite(dpi, image_id, max_x, max_y, 0);
|
||||
|
||||
max_x = max_x + g1_element->width;
|
||||
break;
|
||||
|
|
|
@ -265,7 +265,7 @@ void sub_6BD3A4()
|
|||
for (int i = 200; i < 204; i++)
|
||||
RCT2_ADDRESS(RCT2_ADDRESS_STAFF_MODE_ARRAY, uint8)[i] = STAFF_MODE_WALK;
|
||||
|
||||
sub_6C0C3F();
|
||||
staff_update_greyed_patrol_areas();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
92
src/game.c
92
src/game.c
|
@ -244,7 +244,7 @@ void game_update()
|
|||
if (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) == INPUT_STATE_RESET ||
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) == INPUT_STATE_NORMAL
|
||||
) {
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32)) {
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_VIEWPORT_SCROLLING) {
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) &= ~INPUT_FLAG_VIEWPORT_SCROLLING;
|
||||
break;
|
||||
}
|
||||
|
@ -358,7 +358,7 @@ static int game_check_affordability(int cost)
|
|||
}
|
||||
RCT2_GLOBAL(0x13CE952, uint32) = cost;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = 827;
|
||||
return 0x80000000;
|
||||
return MONEY32_UNDEFINED;
|
||||
}
|
||||
|
||||
static uint32 game_do_command_table[58];
|
||||
|
@ -411,13 +411,13 @@ int game_do_command_p(int command, int *eax, int *ebx, int *ecx, int *edx, int *
|
|||
}
|
||||
cost = *ebx;
|
||||
|
||||
if (cost != 0x80000000) {
|
||||
if (cost != MONEY32_UNDEFINED) {
|
||||
// Check funds
|
||||
insufficientFunds = 0;
|
||||
if (RCT2_GLOBAL(0x009A8C28, uint8) == 1 && !(flags & 4) && !(flags & 0x20) && cost != 0)
|
||||
insufficientFunds = game_check_affordability(cost);
|
||||
|
||||
if (insufficientFunds != 0x80000000) {
|
||||
if (insufficientFunds != MONEY32_UNDEFINED) {
|
||||
*ebx = original_ebx;
|
||||
*edx = original_edx;
|
||||
*esi = original_esi;
|
||||
|
@ -438,7 +438,7 @@ int game_do_command_p(int command, int *eax, int *ebx, int *ecx, int *edx, int *
|
|||
}
|
||||
*edx = *ebx;
|
||||
|
||||
if (*edx != 0x80000000 && *edx < cost)
|
||||
if (*edx != MONEY32_UNDEFINED && *edx < cost)
|
||||
cost = *edx;
|
||||
|
||||
// Decrement nest count
|
||||
|
@ -470,7 +470,7 @@ int game_do_command_p(int command, int *eax, int *ebx, int *ecx, int *edx, int *
|
|||
if (RCT2_GLOBAL(0x009A8C28, uint8) == 0 && (flags & 1) && RCT2_GLOBAL(0x0141F568, uint8) == RCT2_GLOBAL(0x013CA740, uint8) && !(flags & 8))
|
||||
window_error_open(RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TITLE, uint16), RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16));
|
||||
|
||||
return 0x80000000;
|
||||
return MONEY32_UNDEFINED;
|
||||
}
|
||||
|
||||
void pause_toggle()
|
||||
|
@ -655,11 +655,11 @@ int game_load_save(const char *path)
|
|||
|
||||
if (!load_success){
|
||||
set_load_objects_fail_reason();
|
||||
if (RCT2_GLOBAL(0x9DE518,uint32) & (1<<5)){
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_5){
|
||||
RCT2_GLOBAL(0x14241BC, uint32) = 2;
|
||||
//call 0x0040705E Sets cursor position and something else. Calls maybe wind func 8 probably pointless
|
||||
RCT2_GLOBAL(0x14241BC, uint32) = 0;
|
||||
RCT2_GLOBAL(0x9DE518, uint32) &= ~(1<<5);
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) &= ~INPUT_FLAG_5;
|
||||
}
|
||||
title_load();
|
||||
rct2_endupdate();
|
||||
|
@ -797,7 +797,7 @@ char save_game()
|
|||
path_set_extension(path, ".SV6");
|
||||
|
||||
if (scenario_save(path, gConfigGeneral.save_plugin_data ? 1 : 0)) {
|
||||
game_do_command(0, 1047, 0, -1, GAME_COMMAND_0, 0, 0);
|
||||
game_do_command(0, 1047, 0, -1, GAME_COMMAND_SET_RIDE_APPEARANCE, 0, 0);
|
||||
gfx_invalidate_screen();
|
||||
return 1;
|
||||
} else {
|
||||
|
@ -874,21 +874,21 @@ void game_load_or_quit_no_save_prompt()
|
|||
#pragma region Game command function table
|
||||
|
||||
static uint32 game_do_command_table[58] = {
|
||||
0x006B2FC5,
|
||||
0,
|
||||
0x0066397F,
|
||||
0,
|
||||
0x006C511D,
|
||||
0x006C5B69,
|
||||
0,
|
||||
0x006B3F0F,
|
||||
0x006B49D9,
|
||||
0,
|
||||
0,
|
||||
0x006B52D4,
|
||||
0, // 10
|
||||
0,
|
||||
0x006660A8,
|
||||
0x0066640B,
|
||||
0x006E0E01,
|
||||
0,
|
||||
0x006E08F4,
|
||||
0x006E650F,
|
||||
0,
|
||||
|
@ -897,17 +897,17 @@ static uint32 game_do_command_table[58] = {
|
|||
0, // use new_game_command_table, original: 0x00663CCD, // 20
|
||||
0x006B53E9,
|
||||
0x00698D6C, // text input
|
||||
0x0068C542,
|
||||
0x0068C6D1,
|
||||
0,
|
||||
0,
|
||||
0x0068BC01,
|
||||
0x006E66A0,
|
||||
0x006E6878,
|
||||
0,
|
||||
0,
|
||||
0x006C5AE9,
|
||||
0, // use new_game_command_table, original: 0x006BEFA1, 29
|
||||
0x006C09D1, // 30
|
||||
0x006C0B83,
|
||||
0x006C0BB5,
|
||||
0x00669C6D,
|
||||
0, // 30
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0x006649BD,
|
||||
0x006666E7,
|
||||
|
@ -916,20 +916,20 @@ static uint32 game_do_command_table[58] = {
|
|||
0,
|
||||
0, // 40
|
||||
0x006E519A,
|
||||
0x006E5597,
|
||||
0,
|
||||
0x006B893C,
|
||||
0x006B8E1B,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0x006D13FE,
|
||||
0,
|
||||
0x006CDEE4,
|
||||
0x006B9E6D, // 50
|
||||
0x006BA058,
|
||||
0x006E0F26,
|
||||
0x006E56B5,
|
||||
0x006B909A,
|
||||
0x006BA16A,
|
||||
0, // 50
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0x006648E3,
|
||||
0
|
||||
};
|
||||
|
@ -937,21 +937,21 @@ static uint32 game_do_command_table[58] = {
|
|||
void game_command_emptysub(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp) {}
|
||||
|
||||
static GAME_COMMAND_POINTER* new_game_command_table[58] = {
|
||||
game_command_emptysub,
|
||||
game_command_set_ride_appearance,
|
||||
game_command_emptysub,
|
||||
game_pause_toggle,
|
||||
game_command_emptysub,
|
||||
game_command_emptysub,
|
||||
game_load_or_quit,
|
||||
game_command_emptysub,
|
||||
game_command_emptysub,
|
||||
game_command_demolish_ride,
|
||||
game_command_set_ride_status,
|
||||
game_command_emptysub,
|
||||
game_command_set_ride_name, // 10
|
||||
game_command_set_ride_setting,
|
||||
game_command_emptysub,
|
||||
game_command_emptysub,
|
||||
game_command_emptysub,
|
||||
game_command_remove_scenery,
|
||||
game_command_emptysub,
|
||||
game_command_emptysub,
|
||||
game_command_place_footpath,
|
||||
|
@ -960,16 +960,16 @@ static GAME_COMMAND_POINTER* new_game_command_table[58] = {
|
|||
game_command_change_surface_style, // 20
|
||||
game_command_emptysub,
|
||||
game_command_emptysub,
|
||||
game_command_raise_land,
|
||||
game_command_lower_land,
|
||||
game_command_emptysub,
|
||||
game_command_emptysub,
|
||||
game_command_emptysub,
|
||||
game_command_emptysub,
|
||||
game_command_emptysub,
|
||||
game_command_raise_water,
|
||||
game_command_lower_water,
|
||||
game_command_emptysub,
|
||||
game_command_hire_new_staff_member, //game_command_emptysub,
|
||||
game_command_emptysub, // 30
|
||||
game_command_emptysub,
|
||||
game_command_emptysub,
|
||||
game_command_set_staff_patrol, // 30
|
||||
game_command_fire_staff_member,
|
||||
game_command_set_staff_order,
|
||||
game_command_set_park_name,
|
||||
game_command_set_park_open,
|
||||
game_command_emptysub,
|
||||
|
@ -979,20 +979,20 @@ static GAME_COMMAND_POINTER* new_game_command_table[58] = {
|
|||
game_command_set_park_entrance_fee,
|
||||
game_command_update_staff_colour, // 40
|
||||
game_command_emptysub,
|
||||
game_command_remove_fence,
|
||||
game_command_emptysub,
|
||||
game_command_emptysub,
|
||||
game_command_emptysub,
|
||||
game_command_remove_large_scenery,
|
||||
game_command_set_current_loan,
|
||||
game_command_set_research_funding,
|
||||
game_command_emptysub,
|
||||
game_command_start_campaign,
|
||||
game_command_emptysub,
|
||||
game_command_emptysub, // 50
|
||||
game_command_emptysub,
|
||||
game_command_emptysub,
|
||||
game_command_emptysub,
|
||||
game_command_emptysub,
|
||||
game_command_emptysub,
|
||||
game_command_place_banner, // 50
|
||||
game_command_remove_banner,
|
||||
game_command_set_scenery_colour,
|
||||
game_command_set_fence_colour,
|
||||
game_command_set_large_scenery_colour,
|
||||
game_command_set_banner_colour,
|
||||
game_command_emptysub,
|
||||
game_command_clear_scenery
|
||||
};
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#include "common.h"
|
||||
|
||||
enum GAME_COMMAND {
|
||||
GAME_COMMAND_0,
|
||||
GAME_COMMAND_SET_RIDE_APPEARANCE,
|
||||
GAME_COMMAND_1,
|
||||
GAME_COMMAND_TOGGLE_PAUSE, // 2
|
||||
GAME_COMMAND_3, //Has something to do with ride construction
|
||||
|
@ -68,14 +68,14 @@ enum GAME_COMMAND {
|
|||
GAME_COMMAND_41,
|
||||
GAME_COMMAND_REMOVE_FENCE,
|
||||
GAME_COMMAND_43,
|
||||
GAME_COMMAND_44,
|
||||
GAME_COMMAND_REMOVE_LARGE_SCENERY,
|
||||
GAME_COMMAND_SET_CURRENT_LOAN, // 45
|
||||
GAME_COMMAND_SET_RESEARCH_FUNDING, // 46
|
||||
GAME_COMMAND_47,
|
||||
GAME_COMMAND_START_MARKETING_CAMPAIGN, // 48
|
||||
GAME_COMMAND_49,
|
||||
GAME_COMMAND_50, // New banner? (possibly scenery)
|
||||
GAME_COMMAND_51, // Remove banner
|
||||
GAME_COMMAND_PLACE_BANNER, // New banner? (possibly scenery)
|
||||
GAME_COMMAND_REMOVE_BANNER, // Remove banner
|
||||
GAME_COMMAND_52,
|
||||
GAME_COMMAND_53,
|
||||
GAME_COMMAND_54,
|
||||
|
|
28
src/input.c
28
src/input.c
|
@ -283,7 +283,7 @@ static void game_handle_input_mouse(int x, int y, int state)
|
|||
|
||||
if (w->classification != RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_WINDOWCLASS, rct_windowclass) ||
|
||||
w->number != RCT2_GLOBAL(RCT2_ADDRESS_CURSOR_DRAG_WINDOWNUMBER, rct_windownumber) ||
|
||||
!(RCT2_GLOBAL(0x9DE518, uint32)&(1 << 3)))break;
|
||||
!(RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_TOOL_ACTIVE)) break;
|
||||
|
||||
w = window_find_by_number(
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass),
|
||||
|
@ -298,7 +298,7 @@ static void game_handle_input_mouse(int x, int y, int state)
|
|||
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) = 0;
|
||||
if (RCT2_GLOBAL(0x9DE52E, rct_windownumber) != w->number)break;
|
||||
if ((RCT2_GLOBAL(0x9DE518, uint32)&(1 << 3))){
|
||||
if ((RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_TOOL_ACTIVE)){
|
||||
w = window_find_by_number(
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass),
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWNUMBER, rct_windownumber)
|
||||
|
@ -308,7 +308,7 @@ static void game_handle_input_mouse(int x, int y, int state)
|
|||
RCT2_CALLPROC_X(w->event_handlers[WE_TOOL_UP], x, y, 0, (int)RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WIDGETINDEX, uint16), (int)w, 0, 0);
|
||||
}
|
||||
else{
|
||||
if ((RCT2_GLOBAL(0x9DE518, uint32) & (1 << 4)))
|
||||
if ((RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_4))
|
||||
break;
|
||||
|
||||
viewport_interaction_left_click(x, y);
|
||||
|
@ -811,7 +811,7 @@ void process_mouse_over(int x, int y)
|
|||
switch (window->widgets[widgetId].type){
|
||||
|
||||
case WWT_VIEWPORT:
|
||||
if ((RCT2_GLOBAL(0x9DE518, int) & 0x8) == 0) {
|
||||
if ((RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, int) & INPUT_FLAG_TOOL_ACTIVE) == 0) {
|
||||
if (viewport_interaction_left_over(x, y)) {
|
||||
sub_6ED990(CURSOR_HAND_POINT);
|
||||
return;
|
||||
|
@ -897,7 +897,7 @@ void process_mouse_over(int x, int y)
|
|||
*/
|
||||
void process_mouse_tool(int x, int y)
|
||||
{
|
||||
if (RCT2_GLOBAL(0x9DE518, uint32) & (1 << 3))
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_TOOL_ACTIVE)
|
||||
{
|
||||
rct_window* w = window_find_by_number(
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, uint8),
|
||||
|
@ -951,9 +951,9 @@ void input_state_widget_pressed(int x, int y, int state, int widgetIndex, rct_wi
|
|||
window_event_mouse_down_call(w, widgetIndex);
|
||||
}
|
||||
|
||||
if (RCT2_GLOBAL(0x009DE518, uint32) & 1) return;
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_WIDGET_PRESSED) return;
|
||||
|
||||
RCT2_GLOBAL(0x009DE518, uint32) |= 1;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) |= INPUT_FLAG_WIDGET_PRESSED;
|
||||
widget_invalidate_by_number(cursor_w_class, cursor_w_number, widgetIndex);
|
||||
return;
|
||||
case 3:
|
||||
|
@ -976,9 +976,9 @@ void input_state_widget_pressed(int x, int y, int state, int widgetIndex, rct_wi
|
|||
if (cursor_w_class != w->classification || cursor_w_number != w->number || widgetIndex != cursor_widgetIndex)
|
||||
goto dropdown_cleanup;
|
||||
dropdown_index = -1;
|
||||
if (RCT2_GLOBAL(0x9DE518, uint32) & 2){
|
||||
if (!(RCT2_GLOBAL(0x9DE518, uint32) & 4)){
|
||||
RCT2_GLOBAL(0x9DE518, uint32) |= (1 << 2);
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_DROPDOWN_STAY_OPEN){
|
||||
if (!(RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_DROPDOWN_MOUSE_UP)){
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) |= INPUT_FLAG_DROPDOWN_MOUSE_UP;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -986,8 +986,8 @@ void input_state_widget_pressed(int x, int y, int state, int widgetIndex, rct_wi
|
|||
|
||||
window_close_by_class(WC_DROPDOWN);
|
||||
cursor_w = window_find_by_number(cursor_w_class, cursor_w_number);
|
||||
if (RCT2_GLOBAL(0x9DE518, uint32) & 1) {
|
||||
RCT2_GLOBAL(0x9DE518, uint32) &= 0xFFFE;
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_WIDGET_PRESSED) {
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) &= 0xFFFE;
|
||||
widget_invalidate_by_number(cursor_w_class, cursor_w_number, cursor_widgetIndex);
|
||||
}
|
||||
|
||||
|
@ -1030,8 +1030,8 @@ void input_state_widget_pressed(int x, int y, int state, int widgetIndex, rct_wi
|
|||
RCT2_GLOBAL(0x9DE528, uint16) = 0;
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_STATE, uint8) != 5){
|
||||
// Hold down widget and drag outside of area??
|
||||
if (RCT2_GLOBAL(0x9DE518, uint32) & 1){
|
||||
RCT2_GLOBAL(0x9DE518, uint32) &= 0xFFFE;
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_WIDGET_PRESSED){
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) &= 0xFFFE;
|
||||
widget_invalidate_by_number(cursor_w_class, cursor_w_number, cursor_widgetIndex);
|
||||
}
|
||||
return;
|
||||
|
|
|
@ -26,11 +26,12 @@
|
|||
enum {
|
||||
INPUT_FLAG_WIDGET_PRESSED = (1 << 0),
|
||||
|
||||
// Related to dropdowns, set on flag 0x80
|
||||
INPUT_FLAG_1 = (1 << 1),
|
||||
// The dropdown can stay open if the mouse is released, set on flag DROPDOWN_FLAG_STAY_OPEN
|
||||
INPUT_FLAG_DROPDOWN_STAY_OPEN = (1 << 1),
|
||||
|
||||
// Related to dropdowns
|
||||
INPUT_FLAG_2 = (1 << 2),
|
||||
// The mouse has been released and the dropdown is still open
|
||||
// INPUT_FLAG_DROPDOWN_STAY_OPEN is already set if this happens
|
||||
INPUT_FLAG_DROPDOWN_MOUSE_UP = (1 << 2),
|
||||
|
||||
INPUT_FLAG_TOOL_ACTIVE = (1 << 3),
|
||||
|
||||
|
|
|
@ -45,19 +45,34 @@ struct paint_struct{
|
|||
uint32 var_04;
|
||||
uint16 attached_x; // 0x08
|
||||
uint16 attached_y; // 0x0A
|
||||
union {
|
||||
struct {
|
||||
uint8 var_0C;
|
||||
uint8 pad_0D;
|
||||
paint_struct* next_attached_ps; //0x0E
|
||||
uint8 pad_12[2];
|
||||
uint16 pad_12;
|
||||
};
|
||||
struct {
|
||||
uint16 some_x; // 0x0C
|
||||
uint16 some_y; // 0x0E
|
||||
uint16 other_x; // 0x10
|
||||
uint16 other_y; // 0x12
|
||||
};
|
||||
};
|
||||
uint16 x; // 0x14
|
||||
uint16 y; // 0x16
|
||||
uint8 pad_18[2];
|
||||
uint16 var_18;
|
||||
uint8 var_1A;
|
||||
uint8 pad_1B;
|
||||
uint8 var_1B;
|
||||
paint_struct* attached_ps; //0x1C
|
||||
paint_struct* var_20;
|
||||
paint_struct* var_24;
|
||||
uint8 sprite_type; //0x28
|
||||
uint8 var_29;
|
||||
uint16 pad_2A;
|
||||
uint16 map_x; // 0x2C
|
||||
uint16 map_y; // 0x2E
|
||||
rct_map_element *mapElement; // 0x30
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1346,6 +1361,133 @@ void sub_0x68B6C2(){
|
|||
}
|
||||
}
|
||||
|
||||
void sub_688217_helper(uint16 ax, uint8 flag)
|
||||
{
|
||||
paint_struct *ps;
|
||||
paint_struct *ps_next = RCT2_GLOBAL(0x00EE7884, paint_struct*);
|
||||
|
||||
do {
|
||||
ps = ps_next;
|
||||
ps_next = ps_next->var_24;
|
||||
if (ps_next == NULL) return;
|
||||
} while (ax > ps_next->var_18);
|
||||
|
||||
RCT2_GLOBAL(0x00F1AD14, paint_struct*) = ps;
|
||||
|
||||
do {
|
||||
ps = ps->var_24;
|
||||
if (ps == NULL) break;
|
||||
|
||||
if (ps->var_18 > ax + 1) {
|
||||
ps->var_1B = 1 << 7;
|
||||
} else if (ps->var_18 == ax + 1) {
|
||||
ps->var_1B = (1 << 1) | (1 << 0);
|
||||
} else if (ps->var_18 == ax) {
|
||||
ps->var_1B = flag | (1 << 0);
|
||||
}
|
||||
} while (ps->var_18 <= ax + 1);
|
||||
|
||||
ps = RCT2_GLOBAL(0x00F1AD14, paint_struct*);
|
||||
|
||||
while (true) {
|
||||
while (true) {
|
||||
ps_next = ps->var_24;
|
||||
if (ps_next == NULL) return;
|
||||
if (ps_next->var_1B & (1 << 7)) return;
|
||||
if (ps_next->var_1B & (1 << 0)) break;
|
||||
ps = ps_next;
|
||||
}
|
||||
|
||||
ps_next->var_1B &= ~(1 << 0);
|
||||
RCT2_GLOBAL(0x00F1AD18, paint_struct*) = ps;
|
||||
|
||||
uint16 my_attached_x = ps_next->attached_x;
|
||||
uint16 my_attached_y = ps_next->attached_y;
|
||||
uint16 my_some_x = ps_next->some_x;
|
||||
uint16 my_some_y = ps_next->some_y;
|
||||
uint16 my_other_x = ps_next->other_x;
|
||||
uint16 my_other_y = ps_next->other_y;
|
||||
|
||||
while (true) {
|
||||
ps = ps_next;
|
||||
ps_next = ps_next->var_24;
|
||||
if (ps_next == NULL) break;
|
||||
if (ps_next->var_1B & (1 << 7)) break;
|
||||
if (!(ps_next->var_1B & (1 << 1))) continue;
|
||||
|
||||
int yes = 0;
|
||||
switch (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32)) {
|
||||
case 0:
|
||||
if (my_some_y >= ps_next->some_x && my_other_y >= ps_next->attached_y && my_other_x >= ps_next->attached_x
|
||||
&& !(my_some_x < ps_next->some_y && my_attached_y < ps_next->other_y && my_attached_x < ps_next->other_x))
|
||||
yes = 1;
|
||||
break;
|
||||
case 1:
|
||||
if (my_some_y >= ps_next->some_x && my_other_y >= ps_next->attached_y && my_other_x < ps_next->attached_x
|
||||
&& !(my_some_x < ps_next->some_y && my_attached_y < ps_next->other_y && my_attached_x >= ps_next->other_x))
|
||||
yes = 1;
|
||||
break;
|
||||
case 2:
|
||||
if (my_some_y >= ps_next->some_x && my_other_y < ps_next->attached_y && my_other_x < ps_next->attached_x
|
||||
&& !(my_some_x < ps_next->some_y && my_attached_y >= ps_next->other_y && my_attached_x >= ps_next->other_x))
|
||||
yes = 1;
|
||||
break;
|
||||
case 3:
|
||||
if (my_some_y >= ps_next->some_x && my_other_y < ps_next->attached_y && my_other_x >= ps_next->attached_x
|
||||
&& !(my_some_x < ps_next->some_y && my_attached_y >= ps_next->other_y && my_attached_x < ps_next->other_x))
|
||||
yes = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (yes) {
|
||||
ps->var_24 = ps_next->var_24;
|
||||
paint_struct *ps_temp = RCT2_GLOBAL(0x00F1AD18, paint_struct*)->var_24;
|
||||
RCT2_GLOBAL(0x00F1AD18, paint_struct*)->var_24 = ps_next;
|
||||
ps_next->var_24 = ps_temp;
|
||||
ps_next = ps;
|
||||
}
|
||||
}
|
||||
|
||||
ps = RCT2_GLOBAL(0x00F1AD18, paint_struct*);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x00688217
|
||||
*/
|
||||
void sub_688217()
|
||||
{
|
||||
paint_struct *ps = RCT2_GLOBAL(0x00EE7888, paint_struct*);
|
||||
paint_struct *ps_next;
|
||||
RCT2_GLOBAL(0x00EE7888, uint32) += 0x34; // 0x34 is size of paint_struct?
|
||||
RCT2_GLOBAL(0x00EE7884, paint_struct*) = ps;
|
||||
ps->var_24 = NULL;
|
||||
uint32 edi = RCT2_GLOBAL(0x00F1AD0C, uint32);
|
||||
if (edi == -1)
|
||||
return;
|
||||
|
||||
do {
|
||||
ps_next = RCT2_GLOBAL(0x00F1A50C + 4 * edi, paint_struct*);
|
||||
if (ps_next != NULL) {
|
||||
ps->var_24 = ps_next;
|
||||
do {
|
||||
ps = ps_next;
|
||||
ps_next = ps_next->var_24;
|
||||
} while (ps_next != NULL);
|
||||
}
|
||||
} while (++edi <= RCT2_GLOBAL(0x00F1AD10, uint32));
|
||||
|
||||
uint32 eax = RCT2_GLOBAL(0x00F1AD0C, uint32);
|
||||
|
||||
sub_688217_helper(eax & 0xFFFF, 1 << 1);
|
||||
|
||||
eax = RCT2_GLOBAL(0x00F1AD0C, uint32);
|
||||
|
||||
while (++eax < RCT2_GLOBAL(0x00F1AD10, uint32))
|
||||
sub_688217_helper(eax & 0xFFFF, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2:0x00685CBF
|
||||
|
@ -1439,7 +1581,8 @@ void viewport_paint(rct_viewport* viewport, rct_drawpixelinfo* dpi, int left, in
|
|||
sub_0x68615B(0xEE788C); //Memory copy
|
||||
sub_0x68B6C2();
|
||||
//RCT2_CALLPROC_X(0x68B6C2, 0, 0, 0, 0, 0, 0, 0); //Big function call 4 rotation versions
|
||||
RCT2_CALLPROC_X(0x688217, start_x, ebx, ecx, (int)bits_pointer, esi, (int)dpi2, ebp); //Move memory
|
||||
sub_688217();
|
||||
//RCT2_CALLPROC_X(0x688217, start_x, ebx, ecx, (int)bits_pointer, esi, (int)dpi2, ebp); //Move memory
|
||||
sub_688485();
|
||||
//RCT2_CALLPROC_EBPSAFE(0x688485); //Big function call
|
||||
|
||||
|
@ -1466,10 +1609,10 @@ void viewport_paint(rct_viewport* viewport, rct_drawpixelinfo* dpi, int left, in
|
|||
* viewport: edi
|
||||
*/
|
||||
void sub_688972(int screenX, int screenY, sint16 *x, sint16 *y, rct_viewport **viewport) {
|
||||
int my_x, my_y, z;
|
||||
int my_x, my_y, z, interactionType;
|
||||
rct_viewport *myViewport;
|
||||
get_map_coordinates_from_pos(screenX, screenY, 0xFFFE, &my_x, &my_y, &z, NULL, &myViewport);
|
||||
if (z == 0) {
|
||||
get_map_coordinates_from_pos(screenX, screenY, VIEWPORT_INTERACTION_MASK_TERRAIN, &my_x, &my_y, &interactionType, NULL, &myViewport);
|
||||
if (interactionType == VIEWPORT_INTERACTION_ITEM_NONE) {
|
||||
*x = 0x8000;
|
||||
return;
|
||||
}
|
||||
|
@ -1727,6 +1870,79 @@ void viewport_set_visibility(uint8 mode)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores some info about the element pointed at, if requested for this particular type through the interaction mask.
|
||||
* rct2: 0x00688697
|
||||
*/
|
||||
void store_interaction_info(paint_struct *ps)
|
||||
{
|
||||
if (RCT2_GLOBAL(0x0141F569, uint8) == 0) return;
|
||||
|
||||
if (ps->sprite_type == VIEWPORT_INTERACTION_ITEM_NONE
|
||||
|| ps->sprite_type == 11 // 11 as a type seems to not exist, maybe part of the typo mentioned later on.
|
||||
|| ps->sprite_type > VIEWPORT_INTERACTION_ITEM_BANNER) return;
|
||||
|
||||
uint16 mask;
|
||||
if (ps->sprite_type == VIEWPORT_INTERACTION_ITEM_BANNER)
|
||||
// I think CS made a typo here. Let's replicate the original behaviour.
|
||||
mask = 1 << (ps->sprite_type - 3);
|
||||
else
|
||||
mask = 1 << (ps->sprite_type - 1);
|
||||
|
||||
if (!(RCT2_GLOBAL(0x009AC154, uint16) & mask)) {
|
||||
RCT2_GLOBAL(0x009AC148, uint8) = ps->sprite_type;
|
||||
RCT2_GLOBAL(0x009AC149, uint8) = ps->var_29;
|
||||
RCT2_GLOBAL(0x009AC14C, uint32) = ps->map_x;
|
||||
RCT2_GLOBAL(0x009AC14E, uint32) = ps->map_y;
|
||||
RCT2_GLOBAL(0x009AC150, rct_map_element*) = ps->mapElement;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* rct2: 0x0068862C
|
||||
*/
|
||||
void sub_68862C()
|
||||
{
|
||||
rct_drawpixelinfo *dpi = RCT2_GLOBAL(0x0140E9A8, rct_drawpixelinfo*);
|
||||
paint_struct *ps = RCT2_GLOBAL(0x00EE7884, paint_struct*), *old_ps, *next_ps, *attached_ps;
|
||||
uint32 eax = 0xBBBBBBBB, ebx = 0xBBBBBBBB, ecx = 0xBBBBBBBB, edx = 0xBBBBBBBB, esi = 0xBBBBBBBB, edi = 0xBBBBBBBB, ebp = 0xBBBBBBBB;
|
||||
|
||||
while ((ps = ps->var_24) != NULL) {
|
||||
old_ps = ps;
|
||||
|
||||
next_ps = ps;
|
||||
while (next_ps != NULL) {
|
||||
ps = next_ps;
|
||||
ebx = ps->image_id;
|
||||
ecx = ps->x;
|
||||
edx = ps->y;
|
||||
edi = (uint32)dpi;
|
||||
ebp = (uint32)ps;
|
||||
//sub_679023(ps->image_id, ps->x, ps->y, dpi);
|
||||
RCT2_CALLFUNC_X(0x00679023, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
|
||||
store_interaction_info(ps);
|
||||
|
||||
next_ps = ps->var_20;
|
||||
}
|
||||
|
||||
attached_ps = ps->attached_ps;
|
||||
while (attached_ps != NULL) {
|
||||
esi = (uint32)attached_ps;
|
||||
ebp = (uint32)ps;
|
||||
ecx = (attached_ps->attached_x + ps->x) & 0xFFFF;
|
||||
edx = (attached_ps->attached_y + ps->y) & 0xFFFF;
|
||||
ebx = attached_ps->image_id;
|
||||
//sub_679023(ebx, ecx, edx, dpi);
|
||||
RCT2_CALLFUNC_X(0x00679023, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
|
||||
store_interaction_info(ps);
|
||||
|
||||
attached_ps = attached_ps->next_attached_ps;
|
||||
}
|
||||
|
||||
ps = old_ps;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x00685ADC
|
||||
|
@ -1739,7 +1955,7 @@ void viewport_set_visibility(uint8 mode)
|
|||
* 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, rct_viewport **viewport)
|
||||
void get_map_coordinates_from_pos(int screenX, int screenY, int flags, int *x, int *y, int *interactionType, rct_map_element **mapElement, rct_viewport **viewport)
|
||||
{
|
||||
RCT2_GLOBAL(0x9AC154, uint16_t) = flags & 0xFFFF;
|
||||
RCT2_GLOBAL(0x9AC148, uint8_t) = 0;
|
||||
|
@ -1772,12 +1988,12 @@ void get_map_coordinates_from_pos(int screenX, int screenY, int flags, int *x, i
|
|||
RCT2_GLOBAL(0x140E9A8, rct_drawpixelinfo*) = dpi;
|
||||
sub_0x68615B(0xEE788C);
|
||||
sub_0x68B6C2();
|
||||
RCT2_CALLPROC_X(0x688217, 0, 0, 0, 0, 0, 0, 0);
|
||||
RCT2_CALLPROC_X(0x68862C, 0, 0, 0, 0, 0, 0, 0);
|
||||
sub_688217();
|
||||
sub_68862C();
|
||||
}
|
||||
if (viewport != NULL) *viewport = myviewport;
|
||||
}
|
||||
if (z != NULL) *z = RCT2_GLOBAL(0x9AC148, uint8_t);
|
||||
if (interactionType != NULL) *interactionType = RCT2_GLOBAL(0x9AC148, uint8_t);
|
||||
if (x != NULL) *x = (int)RCT2_GLOBAL(0x9AC14C, int16_t);
|
||||
if (y != NULL) *y = (int)RCT2_GLOBAL(0x9AC14E, int16_t);
|
||||
if (mapElement != NULL) *mapElement = RCT2_GLOBAL(0x9AC150, rct_map_element*);
|
||||
|
|
|
@ -46,10 +46,11 @@ enum {
|
|||
|
||||
enum {
|
||||
VIEWPORT_INTERACTION_ITEM_NONE,
|
||||
|
||||
VIEWPORT_INTERACTION_ITEM_SPRITE = 2,
|
||||
VIEWPORT_INTERACTION_ITEM_TERRAIN,
|
||||
VIEWPORT_INTERACTION_ITEM_SPRITE,
|
||||
VIEWPORT_INTERACTION_ITEM_RIDE,
|
||||
VIEWPORT_INTERACTION_ITEM_SCENERY = 5,
|
||||
VIEWPORT_INTERACTION_ITEM_WATER,
|
||||
VIEWPORT_INTERACTION_ITEM_SCENERY,
|
||||
VIEWPORT_INTERACTION_ITEM_FOOTPATH,
|
||||
VIEWPORT_INTERACTION_ITEM_FOOTPATH_ITEM,
|
||||
VIEWPORT_INTERACTION_ITEM_PARK,
|
||||
|
@ -59,6 +60,21 @@ enum {
|
|||
|
||||
};
|
||||
|
||||
enum {
|
||||
VIEWPORT_INTERACTION_MASK_NONE = 0,
|
||||
VIEWPORT_INTERACTION_MASK_TERRAIN = ~(1 << (VIEWPORT_INTERACTION_ITEM_TERRAIN - 1)),
|
||||
VIEWPORT_INTERACTION_MASK_SPRITE = ~(1 << (VIEWPORT_INTERACTION_ITEM_SPRITE - 1)),
|
||||
VIEWPORT_INTERACTION_MASK_RIDE = ~(1 << (VIEWPORT_INTERACTION_ITEM_RIDE - 1)),
|
||||
VIEWPORT_INTERACTION_MASK_WATER = ~(1 << (VIEWPORT_INTERACTION_ITEM_WATER - 1)),
|
||||
VIEWPORT_INTERACTION_MASK_SCENERY = ~(1 << (VIEWPORT_INTERACTION_ITEM_SCENERY - 1)),
|
||||
VIEWPORT_INTERACTION_MASK_FOOTPATH = ~(1 << (VIEWPORT_INTERACTION_ITEM_FOOTPATH - 1)),
|
||||
VIEWPORT_INTERACTION_MASK_FOOTPATH_ITEM = ~(1 << (VIEWPORT_INTERACTION_ITEM_FOOTPATH_ITEM - 1)),
|
||||
VIEWPORT_INTERACTION_MASK_PARK = ~(1 << (VIEWPORT_INTERACTION_ITEM_PARK - 1)),
|
||||
VIEWPORT_INTERACTION_MASK_WALL = ~(1 << (VIEWPORT_INTERACTION_ITEM_WALL - 1)),
|
||||
VIEWPORT_INTERACTION_MASK_LARGE_SCENERY = ~(1 << (VIEWPORT_INTERACTION_ITEM_LARGE_SCENERY - 1)),
|
||||
VIEWPORT_INTERACTION_MASK_BANNER = ~(1 << (VIEWPORT_INTERACTION_ITEM_BANNER - 2)), // Note the -2 for BANNER
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
int type;
|
||||
int x;
|
||||
|
@ -97,7 +113,7 @@ void show_construction_rights();
|
|||
void hide_construction_rights();
|
||||
void viewport_set_visibility(uint8 mode);
|
||||
|
||||
void get_map_coordinates_from_pos(int screenX, int screenY, int flags, int *x, int *y, int *z, rct_map_element **mapElement, rct_viewport **viewport);
|
||||
void get_map_coordinates_from_pos(int screenX, int screenY, int flags, int *x, int *y, int *interactionType, rct_map_element **mapElement, rct_viewport **viewport);
|
||||
|
||||
int viewport_interaction_get_item_left(int x, int y, viewport_interaction_info *info);
|
||||
int viewport_interaction_left_over(int x, int y);
|
||||
|
@ -105,5 +121,6 @@ int viewport_interaction_left_click(int x, int y);
|
|||
int viewport_interaction_get_item_right(int x, int y, viewport_interaction_info *info);
|
||||
int viewport_interaction_right_over(int x, int y);
|
||||
int viewport_interaction_right_click(int x, int y);
|
||||
void sub_68A15E(int screenX, int screenY, short *x, short *y, int *direction, rct_map_element **mapElement);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "../world/map.h"
|
||||
#include "../world/scenery.h"
|
||||
#include "../world/sprite.h"
|
||||
#include "../input.h"
|
||||
#include "viewport.h"
|
||||
|
||||
static void viewport_interaction_remove_scenery(rct_map_element *mapElement, int x, int y);
|
||||
|
@ -58,7 +59,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, NULL);
|
||||
get_map_coordinates_from_pos(x, y, VIEWPORT_INTERACTION_MASK_SPRITE & VIEWPORT_INTERACTION_MASK_RIDE & VIEWPORT_INTERACTION_MASK_PARK, &info->x, &info->y, &info->type, &info->mapElement, NULL);
|
||||
mapElement = info->mapElement;
|
||||
sprite = (rct_sprite*)mapElement;
|
||||
|
||||
|
@ -178,7 +179,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, NULL);
|
||||
get_map_coordinates_from_pos(x, y, ~(VIEWPORT_INTERACTION_MASK_TERRAIN & VIEWPORT_INTERACTION_MASK_WATER), &info->x, &info->y, &info->type, &info->mapElement, NULL);
|
||||
mapElement = info->mapElement;
|
||||
sprite = (rct_sprite*)mapElement;
|
||||
|
||||
|
@ -264,7 +265,7 @@ int viewport_interaction_get_item_right(int x, int y, viewport_interaction_info
|
|||
return info->type;
|
||||
}
|
||||
|
||||
if ((RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & 0x48) != 0x48)
|
||||
if ((RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & (INPUT_FLAG_6 | INPUT_FLAG_TOOL_ACTIVE)) != (INPUT_FLAG_6 | INPUT_FLAG_TOOL_ACTIVE))
|
||||
if (window_find_by_class(WC_RIDE_CONSTRUCTION) == NULL && window_find_by_class(WC_FOOTPATH) == NULL)
|
||||
return info->type = VIEWPORT_INTERACTION_ITEM_NONE;
|
||||
|
||||
|
@ -283,7 +284,7 @@ int viewport_interaction_get_item_right(int x, int y, viewport_interaction_info
|
|||
return info->type;
|
||||
|
||||
case VIEWPORT_INTERACTION_ITEM_FOOTPATH_ITEM:
|
||||
sceneryEntry = RCT2_ADDRESS(0x9ADA50, rct_scenery_entry*)[mapElement->properties.path.additions & 0x0F];
|
||||
sceneryEntry = g_pathBitSceneryEntries[(mapElement->properties.path.additions & 0x0F) - 1];
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 0, uint16) = 1164;
|
||||
if (mapElement->flags & 0x20) {
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 2, uint16) = 3124;
|
||||
|
@ -473,7 +474,7 @@ static void viewport_interaction_remove_park_wall(rct_map_element *mapElement, i
|
|||
{
|
||||
rct_scenery_entry* sceneryEntry;
|
||||
|
||||
sceneryEntry = g_wallSceneryEntries[mapElement->properties.fence.slope];
|
||||
sceneryEntry = g_wallSceneryEntries[mapElement->properties.fence.type];
|
||||
if (sceneryEntry->wall.var_0D != 0xFF){
|
||||
window_sign_small_open(mapElement->properties.fence.item[0]);
|
||||
} else {
|
||||
|
@ -496,12 +497,9 @@ static void viewport_interaction_remove_park_wall(rct_map_element *mapElement, i
|
|||
*/
|
||||
static void viewport_interaction_remove_large_scenery(rct_map_element *mapElement, int x, int y)
|
||||
{
|
||||
int ebx;
|
||||
rct_scenery_entry* sceneryEntry;
|
||||
|
||||
ebx = mapElement->properties.scenerymultiple.type;
|
||||
ebx |= (mapElement->properties.scenerymultiple.index & 0x3) << 8;
|
||||
sceneryEntry = g_largeSceneryEntries[ebx];
|
||||
sceneryEntry = g_largeSceneryEntries[mapElement->properties.scenerymultiple.type & MAP_ELEMENT_LARGE_TYPE_MASK];
|
||||
|
||||
if (sceneryEntry->large_scenery.var_11 != 0xFF){
|
||||
int id = (mapElement->type & 0xC0) |
|
||||
|
@ -514,8 +512,8 @@ static void viewport_interaction_remove_large_scenery(rct_map_element *mapElemen
|
|||
x,
|
||||
1 | ((mapElement->type & 0x3) << 8),
|
||||
y,
|
||||
mapElement->base_height | ((mapElement->properties.scenerymultiple.index >> 2) << 8),
|
||||
GAME_COMMAND_44,
|
||||
mapElement->base_height | ((mapElement->properties.scenerymultiple.type >> 10) << 8),
|
||||
GAME_COMMAND_REMOVE_LARGE_SCENERY,
|
||||
0,
|
||||
0
|
||||
);
|
||||
|
@ -561,3 +559,71 @@ static rct_peep *viewport_interaction_get_closest_peep(int x, int y, int maxDist
|
|||
|
||||
return closestPeep;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x0068A15E
|
||||
*/
|
||||
void sub_68A15E(int screenX, int screenY, short *x, short *y, int *direction, rct_map_element **mapElement)
|
||||
{
|
||||
int my_x, my_y, z, interactionType;
|
||||
rct_map_element *myMapElement;
|
||||
rct_viewport *viewport;
|
||||
get_map_coordinates_from_pos(screenX, screenY, VIEWPORT_INTERACTION_MASK_TERRAIN & VIEWPORT_INTERACTION_MASK_WATER, &my_x, &my_y, &interactionType, &myMapElement, &viewport);
|
||||
|
||||
if (interactionType == VIEWPORT_INTERACTION_ITEM_NONE) {
|
||||
*x = 0x8000;
|
||||
return;
|
||||
}
|
||||
|
||||
RCT2_GLOBAL(0x00F1AD3E, uint8) = interactionType;
|
||||
RCT2_GLOBAL(0x00F1AD30, rct_map_element*) = myMapElement;
|
||||
|
||||
if (interactionType == VIEWPORT_INTERACTION_ITEM_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;
|
||||
}
|
|
@ -192,6 +192,8 @@ enum {
|
|||
STR_LOCATE_SUBJECT_TIP = 1027,
|
||||
STR_OFF_EDGE_OF_MAP = 1028,
|
||||
|
||||
STR_CAN_ONLY_BUILD_THIS_ON_LAND = 1034,
|
||||
|
||||
STR_LOAD_GAME_DIALOG_TITLE = 1036,
|
||||
STR_LOAD_LANDSCAPE_DIALOG_TITLE = 1037,
|
||||
STR_CONVERT_SAVED_GAME_TO_SCENARIO_1038 = 1038,
|
||||
|
@ -319,6 +321,7 @@ enum {
|
|||
|
||||
STR_BUILD_FOOTPATH_TIP = 1173,
|
||||
|
||||
STR_BANNER_SIGN_IN_THE_WAY = 1174,
|
||||
STR_CANT_BUILD_THIS_ON_SLOPED_FOOTPATH = 1175,
|
||||
STR_CANT_BUILD_FOOTPATH_HERE = 1176,
|
||||
STR_CANT_REMOVE_FOOTPATH_FROM_HERE = 1177,
|
||||
|
@ -377,6 +380,7 @@ enum {
|
|||
STR_SHOPS_STALLS_TIP = 1228,
|
||||
|
||||
STR_ROTATE_OBJECTS_90 = 1327,
|
||||
STR_LEVEL_LAND_REQUIRED = 1328,
|
||||
STR_LAUNCH_SPEED = 1329,
|
||||
STR_LAUNCH_SPEED_TIP = 1330,
|
||||
|
||||
|
@ -739,6 +743,8 @@ enum {
|
|||
|
||||
STR_CANT_DEMOLISH_RIDE = 2248,
|
||||
|
||||
STR_CAN_ONLY_BE_BUILT_ACROSS_PATHS = 2252,
|
||||
|
||||
STR_RESEARCH_TRANSPORT_RIDES = 2253,
|
||||
STR_RESEARCH_GENTLE_RIDES = 2254,
|
||||
STR_RESEARCH_ROLLER_COASTERS = 2255,
|
||||
|
@ -1066,6 +1072,8 @@ enum {
|
|||
STR_MUSIC_ACKNOWLEDGEMENTS_ELLIPSIS = 2862,
|
||||
STR_MUSIC_ACKNOWLEDGEMENTS = 2863,
|
||||
|
||||
STR_TOO_MANY_BANNERS_IN_GAME = 2980,
|
||||
|
||||
STR_CHANGE_BANNER_TEXT_TIP = 2986,
|
||||
STR_SET_AS_NO_ENTRY_BANNER_TIP = 2987,
|
||||
STR_DEMOLISH_BANNER_TIP = 2988,
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
typedef int rct_expenditure_type;
|
||||
|
||||
enum {
|
||||
RCT_EXPENDITURE_TYPE_RIDE_CONSRUCTION,
|
||||
RCT_EXPENDITURE_TYPE_RIDE_CONSTRUCTION,
|
||||
RCT_EXPENDITURE_TYPE_RIDE_RUNNING_COSTS,
|
||||
RCT_EXPENDITURE_TYPE_LAND_PURCHASE,
|
||||
RCT_EXPENDITURE_TYPE_LANDSCAPING,
|
||||
|
|
|
@ -907,10 +907,11 @@ int paint_large_scenery(int flags, int ebx, int ecx, int edx, rct_drawpixelinfo*
|
|||
chunk += 1038;
|
||||
}
|
||||
|
||||
scenery_type->large_scenery.var_0C = (uint32)chunk;
|
||||
scenery_type->large_scenery.tiles = (rct_large_scenery_tile*)chunk;
|
||||
|
||||
// skip over large scenery tiles
|
||||
while (*((uint16*)chunk) != 0xFFFF){
|
||||
chunk += 9;
|
||||
chunk += sizeof(rct_large_scenery_tile);
|
||||
}
|
||||
|
||||
chunk += 2;
|
||||
|
@ -937,7 +938,7 @@ int paint_large_scenery(int flags, int ebx, int ecx, int edx, rct_drawpixelinfo*
|
|||
rct_scenery_entry* scenery_type = (rct_scenery_entry*)esi;
|
||||
scenery_type->name = 0;
|
||||
scenery_type->image = 0;
|
||||
scenery_type->large_scenery.var_0C = 0;
|
||||
scenery_type->large_scenery.tiles = 0;
|
||||
scenery_type->large_scenery.scenery_tab_id = 0;
|
||||
scenery_type->large_scenery.var_12 = 0;
|
||||
scenery_type->large_scenery.var_16 = 0;
|
||||
|
|
|
@ -175,6 +175,21 @@ static void sub_693BE5(rct_peep* peep, uint8 al){
|
|||
sub_693B58(peep);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x0069A512
|
||||
*/
|
||||
void remove_peep_from_ride(rct_peep* peep)
|
||||
{
|
||||
if (peep->state == PEEP_STATE_QUEUING) {
|
||||
remove_peep_from_queue(peep);
|
||||
}
|
||||
peep_decrement_num_riders(peep);
|
||||
peep->state = PEEP_STATE_1;
|
||||
peep_window_state_update(peep);
|
||||
sub_693BE5(peep, 0);
|
||||
}
|
||||
|
||||
static void peep_state_reset(rct_peep* peep){
|
||||
peep_decrement_num_riders(peep);
|
||||
peep->state = PEEP_STATE_1;
|
||||
|
@ -198,8 +213,8 @@ void peep_check_if_lost(rct_peep* peep){
|
|||
peep->var_F4 = 230;
|
||||
}
|
||||
peep_insert_new_thought(peep, PEEP_THOUGHT_TYPE_LOST, 0xFF);
|
||||
if (peep->happiness_growth_rate < 30) peep->happiness_growth_rate = 0;
|
||||
else peep->happiness_growth_rate -= 30;
|
||||
|
||||
peep->happiness_growth_rate = max(peep->happiness_growth_rate - 30, 0);
|
||||
}
|
||||
|
||||
/* rct2: 0x69C26B
|
||||
|
@ -211,8 +226,7 @@ void peep_check_cant_find_ride(rct_peep* peep){
|
|||
if (peep->var_C6 == 30 || peep->var_C6 == 60){
|
||||
peep_insert_new_thought(peep, PEEP_THOUGHT_TYPE_CANT_FIND, peep->guest_heading_to_ride_id);
|
||||
|
||||
if (peep->happiness_growth_rate < 30) peep->happiness_growth_rate = 0;
|
||||
else peep->happiness_growth_rate -= 30;
|
||||
peep->happiness_growth_rate = max(peep->happiness_growth_rate - 30, 0);
|
||||
}
|
||||
|
||||
peep->var_C6--;
|
||||
|
@ -237,8 +251,7 @@ void peep_check_cant_find_exit(rct_peep* peep){
|
|||
if (peep->var_C6 == 1){
|
||||
peep_insert_new_thought(peep, PEEP_THOUGHT_TYPE_CANT_FIND_EXIT, 0xFF);
|
||||
|
||||
if (peep->happiness_growth_rate < 30) peep->happiness_growth_rate = 0;
|
||||
else peep->happiness_growth_rate -= 30;
|
||||
peep->happiness_growth_rate = max(peep->happiness_growth_rate - 30, 0);
|
||||
}
|
||||
|
||||
if (--peep->var_C6 == 0) peep->var_C6 = 90;
|
||||
|
@ -558,7 +571,7 @@ void peep_sprite_remove(rct_peep* peep){
|
|||
//RCT2_CALLPROC_X(0x69A535, 0, 0, 0, 0, (int)peep, 0, 0);
|
||||
//return;
|
||||
|
||||
RCT2_CALLPROC_X(0x0069A512, 0, 0, 0, 0, (int)peep, 0, 0);
|
||||
remove_peep_from_ride(peep);
|
||||
invalidate_sprite((rct_sprite*)peep);
|
||||
|
||||
window_close_by_number(WC_PEEP, peep->sprite_index);
|
||||
|
@ -575,7 +588,7 @@ void peep_sprite_remove(rct_peep* peep){
|
|||
|
||||
RCT2_ADDRESS(RCT2_ADDRESS_STAFF_MODE_ARRAY, uint8)[peep->staff_id] = 0;
|
||||
peep->type = 0xFF;
|
||||
sub_6C0C3F();
|
||||
staff_update_greyed_patrol_areas();
|
||||
peep->type = PEEP_TYPE_STAFF;
|
||||
|
||||
news_item_disable_news(NEWS_ITEM_PEEP, peep->sprite_index);
|
||||
|
@ -3109,7 +3122,7 @@ static int peep_update_walking_find_bench(rct_peep* peep){
|
|||
uint8 additions = map_element->properties.path.additions & 0xF;
|
||||
|
||||
if (!additions) return 0;
|
||||
rct_scenery_entry* sceneryEntry = RCT2_ADDRESS(0x9ADA50, rct_scenery_entry*)[additions];
|
||||
rct_scenery_entry* sceneryEntry = g_pathBitSceneryEntries[additions - 1];
|
||||
|
||||
if (!(sceneryEntry->path_bit.var_06 & 0x2))return 0;
|
||||
|
||||
|
@ -3186,7 +3199,7 @@ static int peep_update_walking_find_bin(rct_peep* peep){
|
|||
uint8 additions = map_element->properties.path.additions & 0xF;
|
||||
|
||||
if (!additions) return 0;
|
||||
rct_scenery_entry* sceneryEntry = RCT2_ADDRESS(0x9ADA50, rct_scenery_entry*)[additions];
|
||||
rct_scenery_entry* sceneryEntry = g_pathBitSceneryEntries[additions - 1];
|
||||
|
||||
if (!(sceneryEntry->path_bit.var_06 & 0x1))return 0;
|
||||
|
||||
|
@ -3263,7 +3276,7 @@ static void peep_update_walking_break_scenery(rct_peep* peep){
|
|||
uint8 additions = map_element->properties.path.additions & 0xF;
|
||||
|
||||
if (!additions) return;
|
||||
rct_scenery_entry* sceneryEntry = RCT2_ADDRESS(0x9ADA50, rct_scenery_entry*)[additions];
|
||||
rct_scenery_entry* sceneryEntry = g_pathBitSceneryEntries[additions - 1];
|
||||
|
||||
if (!(sceneryEntry->path_bit.var_06 & 0x4))return;
|
||||
|
||||
|
@ -3439,7 +3452,7 @@ static void peep_update_using_bin(rct_peep* peep){
|
|||
return;
|
||||
}
|
||||
|
||||
rct_scenery_entry* sceneryEntry = RCT2_ADDRESS(0x9ADA50, rct_scenery_entry*)[additions];
|
||||
rct_scenery_entry* sceneryEntry = g_pathBitSceneryEntries[additions - 1];
|
||||
if (!(sceneryEntry->path_bit.var_06 & 1)){
|
||||
peep_state_reset(peep);
|
||||
return;
|
||||
|
@ -3830,7 +3843,7 @@ static int peep_update_patrolling_find_bin(rct_peep* peep){
|
|||
|
||||
if (additions == 0)return 0;
|
||||
|
||||
rct_scenery_entry* sceneryEntry = RCT2_ADDRESS(0x9ADA50, rct_scenery_entry*)[additions];
|
||||
rct_scenery_entry* sceneryEntry = g_pathBitSceneryEntries[additions - 1];
|
||||
|
||||
if (!(sceneryEntry->path_bit.var_06 & 1))
|
||||
return 0;
|
||||
|
@ -4123,7 +4136,7 @@ static void peep_update_walking(rct_peep* peep){
|
|||
|
||||
if (additions){
|
||||
if (!(map_element->properties.path.additions & 0x80)){
|
||||
rct_scenery_entry* sceneryEntry = RCT2_ADDRESS(0x9ADA50, rct_scenery_entry*)[additions];
|
||||
rct_scenery_entry* sceneryEntry = g_pathBitSceneryEntries[additions - 1];
|
||||
|
||||
if (!(sceneryEntry->path_bit.var_06 & 0x2)) ebp = 9;
|
||||
}
|
||||
|
@ -4564,7 +4577,7 @@ void peep_update_crowd_noise()
|
|||
// Load and play crowd noise
|
||||
#ifdef USE_MIXER
|
||||
if (!gCrowdSoundChannel) {
|
||||
gCrowdSoundChannel = Mixer_Play_Music(PATH_ID_CSS2);
|
||||
gCrowdSoundChannel = Mixer_Play_Music(PATH_ID_CSS2, false);
|
||||
}
|
||||
if (gCrowdSoundChannel) {
|
||||
Mixer_Channel_Volume(gCrowdSoundChannel, DStoMixerVolume(volume));
|
||||
|
|
|
@ -389,7 +389,7 @@ typedef struct {
|
|||
uint8 energy; // 0x38
|
||||
uint8 energy_growth_rate; // 0x39
|
||||
uint8 happiness; // 0x3A
|
||||
sint8 happiness_growth_rate; // 0x3B
|
||||
uint8 happiness_growth_rate; // 0x3B
|
||||
uint8 nausea; // 0x3C
|
||||
uint8 nausea_growth_rate; // 0x3D
|
||||
uint8 hunger; // 0x3E
|
||||
|
@ -570,6 +570,7 @@ int peep_check_easteregg_name(int index, rct_peep *peep);
|
|||
int peep_get_easteregg_name_id(rct_peep *peep);
|
||||
int peep_is_mechanic(rct_peep *peep);
|
||||
int peep_has_food(rct_peep* peep);
|
||||
void peep_sprite_remove(rct_peep* peep);
|
||||
|
||||
void peep_window_state_update(rct_peep* peep);
|
||||
void peep_decrement_num_riders(rct_peep* peep);
|
||||
|
@ -583,6 +584,7 @@ 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_ride(rct_peep* peep);
|
||||
void remove_peep_from_queue(rct_peep* peep);
|
||||
|
||||
#endif
|
||||
|
|
117
src/peep/staff.c
117
src/peep/staff.c
|
@ -70,7 +70,7 @@ void game_command_hire_new_staff_member(int* eax, int* ebx, int* ecx, int* edx,
|
|||
RCT2_GLOBAL(0x009DEA62, uint16) = _dx;
|
||||
|
||||
if (RCT2_GLOBAL(0x13573C8, uint16) < 0x190) {
|
||||
*ebx = 0x80000000;
|
||||
*ebx = MONEY32_UNDEFINED;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = STR_TOO_MANY_PEOPLE_IN_GAME;
|
||||
return;
|
||||
}
|
||||
|
@ -82,7 +82,7 @@ void game_command_hire_new_staff_member(int* eax, int* ebx, int* ecx, int* edx,
|
|||
}
|
||||
|
||||
if (i == STAFF_MAX_COUNT) {
|
||||
*ebx = 0x80000000;
|
||||
*ebx = MONEY32_UNDEFINED;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = STR_TOO_MANY_STAFF_IN_GAME;
|
||||
return;
|
||||
}
|
||||
|
@ -96,7 +96,7 @@ void game_command_hire_new_staff_member(int* eax, int* ebx, int* ecx, int* edx,
|
|||
|
||||
if (newPeep == NULL)
|
||||
{
|
||||
*ebx = 0x80000000;
|
||||
*ebx = MONEY32_UNDEFINED;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = STR_TOO_MANY_PEOPLE_IN_GAME;
|
||||
return;
|
||||
}
|
||||
|
@ -211,6 +211,95 @@ void game_command_hire_new_staff_member(int* eax, int* ebx, int* ecx, int* edx,
|
|||
*edi = newPeep->sprite_index;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006C0BB5
|
||||
*/
|
||||
void game_command_set_staff_order(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp)
|
||||
{
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_NEXT_EXPENDITURE_TYPE, uint8) = 40;
|
||||
uint8 order_id = *ebx >> 8;
|
||||
uint16 sprite_id = *edx;
|
||||
if(*ebx & GAME_COMMAND_FLAG_APPLY){
|
||||
rct_peep *peep = &g_sprite_list[sprite_id].peep;
|
||||
if(order_id & 0x80){ // change costume
|
||||
uint8 sprite_type = order_id & ~0x80;
|
||||
sprite_type += 4;
|
||||
peep->sprite_type = sprite_type;
|
||||
peep->flags &= ~PEEP_FLAGS_SLOW_WALK;
|
||||
if(RCT2_ADDRESS(0x00982134, uint8)[sprite_type] & 1){
|
||||
peep->flags |= PEEP_FLAGS_SLOW_WALK;
|
||||
}
|
||||
peep->action_frame = 0;
|
||||
sub_693B58(peep);
|
||||
invalidate_sprite((rct_sprite*)peep);
|
||||
window_invalidate_by_number(WC_PEEP, sprite_id);
|
||||
window_invalidate_by_class(WC_STAFF_LIST);
|
||||
}else{
|
||||
peep->staff_orders = order_id;
|
||||
window_invalidate_by_number(WC_PEEP, sprite_id);
|
||||
window_invalidate_by_class(WC_STAFF_LIST);
|
||||
}
|
||||
}
|
||||
*ebx = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006C09D1
|
||||
*/
|
||||
void game_command_set_staff_patrol(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp)
|
||||
{
|
||||
if(*ebx & GAME_COMMAND_FLAG_APPLY){
|
||||
int x = *eax;
|
||||
int y = *ecx;
|
||||
uint16 sprite_id = *edx;
|
||||
rct_peep *peep = &g_sprite_list[sprite_id].peep;
|
||||
int patrolOffset = peep->staff_id * (64 * 64 / 8);
|
||||
int patrolIndex = ((x & 0x1F80) >> 7) | ((y & 0x1F80) >> 1);
|
||||
int mask = 1 << (patrolIndex & 0x1F);
|
||||
int base = patrolIndex >> 5;
|
||||
|
||||
uint32 *patrolBits = (uint32*)(0x013B0E72 + patrolOffset + (base * 4));
|
||||
*patrolBits ^= mask;
|
||||
|
||||
int ispatrolling = 0;
|
||||
for(int i = 0; i < 128; i++){
|
||||
ispatrolling |= *(uint32*)(0x013B0E72 + patrolOffset + (i * 4));
|
||||
}
|
||||
|
||||
RCT2_ADDRESS(RCT2_ADDRESS_STAFF_MODE_ARRAY, uint8)[peep->staff_id] &= ~2;
|
||||
if(ispatrolling){
|
||||
RCT2_ADDRESS(RCT2_ADDRESS_STAFF_MODE_ARRAY, uint8)[peep->staff_id] |= 2;
|
||||
}
|
||||
|
||||
for(int y2 = 0; y2 < 4; y2++){
|
||||
for(int x2 = 0; x2 < 4; x2++){
|
||||
map_invalidate_tile_full((x & 0x1F80) + (x2 * 32), (y & 0x1F80) + (y2 * 32));
|
||||
}
|
||||
}
|
||||
staff_update_greyed_patrol_areas();
|
||||
}
|
||||
*ebx = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006C0B83
|
||||
*/
|
||||
void game_command_fire_staff_member(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp)
|
||||
{
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_NEXT_EXPENDITURE_TYPE, uint8) = 40;
|
||||
if(*ebx & GAME_COMMAND_FLAG_APPLY){
|
||||
window_close_by_class(WC_FIRE_PROMPT);
|
||||
uint16 sprite_id = *edx;
|
||||
rct_peep *peep = &g_sprite_list[sprite_id].peep;
|
||||
remove_peep_from_ride(peep);
|
||||
peep_sprite_remove(peep);
|
||||
}
|
||||
*ebx = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Updates the colour of the given staff type.
|
||||
*/
|
||||
|
@ -233,29 +322,33 @@ uint16 hire_new_staff_member(uint8 staffType)
|
|||
|
||||
int result = game_do_command_p(GAME_COMMAND_HIRE_NEW_STAFF_MEMBER, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
|
||||
|
||||
if (result == 0x80000000)
|
||||
if (result == MONEY32_UNDEFINED)
|
||||
return 0xFFFF;
|
||||
|
||||
return edi;
|
||||
}
|
||||
|
||||
void sub_6C0C3F()
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006C0C3F
|
||||
*/
|
||||
void staff_update_greyed_patrol_areas()
|
||||
{
|
||||
register rct_peep* peep;
|
||||
rct_peep* peep;
|
||||
|
||||
for (register uint8 staff_type = 0; staff_type < STAFF_TYPE_COUNT; ++staff_type)
|
||||
for (int staff_type = 0; staff_type < STAFF_TYPE_COUNT; ++staff_type)
|
||||
{
|
||||
for (register uint8 i = 0; i < 128; ++i)
|
||||
RCT2_ADDRESS(0x13B0E72 + (staff_type + STAFF_MAX_COUNT) * 512, uint32)[i] = 0;
|
||||
for (int i = 0; i < 128; ++i)
|
||||
RCT2_ADDRESS(0x13B0E72 + ((staff_type + STAFF_MAX_COUNT) * 512), uint32)[i] = 0;
|
||||
|
||||
for (register uint16 sprite_index = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_PEEP, uint16); sprite_index != SPRITE_INDEX_NULL; sprite_index = peep->next)
|
||||
for (uint16 sprite_index = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_PEEP, uint16); sprite_index != SPRITE_INDEX_NULL; sprite_index = peep->next)
|
||||
{
|
||||
peep = GET_PEEP(sprite_index);
|
||||
|
||||
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, uint32)[i];
|
||||
for (int i = 0; i < 128; ++i)
|
||||
RCT2_ADDRESS(0x13B0E72 + ((staff_type + STAFF_MAX_COUNT) * 512), uint32)[i] |= RCT2_ADDRESS(0x13B0E72 + (peep->staff_id * 512), uint32)[i];
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,10 +51,13 @@ enum STAFF_ORDERS{
|
|||
|
||||
void game_command_update_staff_colour(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp);
|
||||
void game_command_hire_new_staff_member(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp);
|
||||
void game_command_set_staff_order(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp);
|
||||
void game_command_set_staff_patrol(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp);
|
||||
void game_command_fire_staff_member(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp);
|
||||
|
||||
void update_staff_colour(uint8 staffType, uint16 color);
|
||||
uint16 hire_new_staff_member(uint8 staffType);
|
||||
void sub_6C0C3F();
|
||||
void staff_update_greyed_patrol_areas();
|
||||
int mechanic_is_location_in_patrol(rct_peep *mechanic, int x, int y);
|
||||
void staff_reset_stats();
|
||||
|
||||
|
|
|
@ -191,6 +191,7 @@ static void platform_resize(int width, int height)
|
|||
rct_drawpixelinfo *screenDPI;
|
||||
int newScreenBufferSize;
|
||||
void *newScreenBuffer;
|
||||
uint32 flags;
|
||||
|
||||
if (_surface != NULL)
|
||||
SDL_FreeSurface(_surface);
|
||||
|
@ -247,6 +248,18 @@ static void platform_resize(int width, int height)
|
|||
window_relocate_windows(width, height);
|
||||
|
||||
gfx_invalidate_screen();
|
||||
|
||||
// Check if the window has been resized in windowed mode and update the config file accordingly
|
||||
// This is called in rct2_update_2 and is only called after resizing a window has finished
|
||||
flags = SDL_GetWindowFlags(gWindow);
|
||||
if ((flags & (SDL_WINDOW_MAXIMIZED | SDL_WINDOW_MINIMIZED |
|
||||
SDL_WINDOW_FULLSCREEN | SDL_WINDOW_FULLSCREEN_DESKTOP)) == 0) {
|
||||
if (width != gConfigGeneral.window_width || height != gConfigGeneral.window_height) {
|
||||
gConfigGeneral.window_width = width;
|
||||
gConfigGeneral.window_height = height;
|
||||
config_save_default();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void platform_update_palette(char* colours, int start_index, int num_colours)
|
||||
|
|
16
src/rct1.c
16
src/rct1.c
|
@ -62,7 +62,7 @@ bool rct1_read_sc4(const char *path, rct1_s4 *s4)
|
|||
long length, decodedLength;
|
||||
bool success;
|
||||
|
||||
if (!readentirefile(path, &buffer, &length)) {
|
||||
if (!readentirefile(path, (void**)&buffer, &length)) {
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_ERROR_TYPE, uint8) = 255;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_ERROR_STRING_ID, uint16) = 3011;
|
||||
return 0;
|
||||
|
@ -92,7 +92,7 @@ bool rct1_read_sv4(const char *path, rct1_s4 *s4)
|
|||
long length, decodedLength;
|
||||
bool success;
|
||||
|
||||
if (!readentirefile(path, &buffer, &length)) {
|
||||
if (!readentirefile(path, (void**)&buffer, &length)) {
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_ERROR_TYPE, uint8) = 255;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_ERROR_STRING_ID, uint16) = 3011;
|
||||
return 0;
|
||||
|
@ -230,17 +230,17 @@ void rct1_fix_landscape()
|
|||
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;
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_NO_MONEY) {
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) |= PARK_FLAGS_NO_MONEY_SCENARIO;
|
||||
} else {
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint8) &= PARK_FLAGS_NO_MONEY_SCENARIO;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) &= ~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;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) |= PARK_FLAGS_PARK_FREE_ENTRY;
|
||||
} else {
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint8) &= ~PARK_FLAGS_PARK_FREE_ENTRY;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) &= ~PARK_FLAGS_PARK_FREE_ENTRY;
|
||||
}
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint8) &= ~PARK_FLAGS_18;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) &= ~PARK_FLAGS_18;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_GUEST_INITIAL_CASH, money16) = clamp(
|
||||
MONEY(10,00),
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_GUEST_INITIAL_CASH, money16),
|
||||
|
|
|
@ -72,6 +72,7 @@ int rct2_init()
|
|||
RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_TICKS, int) = 0;
|
||||
RCT2_GLOBAL(0x009AC310, char*) = RCT2_GLOBAL(RCT2_ADDRESS_CMDLINE, char*);
|
||||
get_system_time();
|
||||
srand(time(0));
|
||||
RCT2_GLOBAL(0x009DEA69, short) = RCT2_GLOBAL(RCT2_ADDRESS_OS_TIME_DAY, short);
|
||||
RCT2_GLOBAL(0x009DEA6B, short) = RCT2_GLOBAL(RCT2_ADDRESS_OS_TIME_MONTH, short);
|
||||
if (!rct2_init_directories())
|
||||
|
|
310
src/ride/ride.c
310
src/ride/ride.c
|
@ -27,12 +27,14 @@
|
|||
#include "../localisation/date.h"
|
||||
#include "../localisation/localisation.h"
|
||||
#include "../management/finance.h"
|
||||
#include "../management/marketing.h"
|
||||
#include "../management/news_item.h"
|
||||
#include "../peep/peep.h"
|
||||
#include "../peep/staff.h"
|
||||
#include "../scenario.h"
|
||||
#include "../util/util.h"
|
||||
#include "../windows/error.h"
|
||||
#include "../world/banner.h"
|
||||
#include "../world/map.h"
|
||||
#include "../world/sprite.h"
|
||||
#include "ride.h"
|
||||
|
@ -556,7 +558,7 @@ int ride_create_ride(ride_list_item listItem)
|
|||
|
||||
esi = GAME_COMMAND_6;
|
||||
game_do_command_p(esi, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
|
||||
return ebx == 0x80000000 ? -1 : edi;
|
||||
return ebx == MONEY32_UNDEFINED ? -1 : edi;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2445,32 +2447,34 @@ int ride_music_params_update(sint16 x, sint16 y, sint16 z, uint8 rideIndex, uint
|
|||
|
||||
uint8 vol1 = -1;
|
||||
uint8 vol2 = -1;
|
||||
if (pany < 0) {
|
||||
pany = -pany;
|
||||
int panx2 = panx;
|
||||
int pany2 = pany;
|
||||
if (pany2 < 0) {
|
||||
pany2 = -pany2;
|
||||
}
|
||||
if (pany > 6143) {
|
||||
pany = 6143;
|
||||
if (pany2 > 6143) {
|
||||
pany2 = 6143;
|
||||
}
|
||||
pany -= 2048;
|
||||
if (pany > 0) {
|
||||
pany = -((pany / 4) - 1024) / 4;
|
||||
vol1 = (uint8)pany;
|
||||
if (pany >= 256) {
|
||||
pany2 -= 2048;
|
||||
if (pany2 > 0) {
|
||||
pany2 = -((pany2 / 4) - 1024) / 4;
|
||||
vol1 = (uint8)pany2;
|
||||
if (pany2 >= 256) {
|
||||
vol1 = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (panx < 0) {
|
||||
panx = -panx;
|
||||
if (panx2 < 0) {
|
||||
panx2 = -panx2;
|
||||
}
|
||||
if (panx > 6143) {
|
||||
panx = 6143;
|
||||
if (panx2 > 6143) {
|
||||
panx2 = 6143;
|
||||
}
|
||||
panx -= 2048;
|
||||
if (panx > 0) {
|
||||
panx = -((panx / 4) - 1024) / 4;
|
||||
vol2 = (uint8)panx;
|
||||
if (panx >= 256) {
|
||||
panx2 -= 2048;
|
||||
if (panx2 > 0) {
|
||||
panx2 = -((panx2 / 4) - 1024) / 4;
|
||||
vol2 = (uint8)panx2;
|
||||
if (panx2 >= 256) {
|
||||
vol2 = -1;
|
||||
}
|
||||
}
|
||||
|
@ -2660,7 +2664,7 @@ void ride_music_update_final()
|
|||
rct_ride_music_info* ride_music_info = &RCT2_GLOBAL(0x009AF1C8, rct_ride_music_info*)[ride_music_params->tuneid];
|
||||
#ifdef USE_MIXER
|
||||
rct_ride_music* ride_music = &gRideMusicList[ebx];
|
||||
ride_music->sound_channel = Mixer_Play_Music(ride_music_info->pathid);
|
||||
ride_music->sound_channel = Mixer_Play_Music(ride_music_info->pathid, true);
|
||||
if (ride_music->sound_channel) {
|
||||
ride_music->volume = ride_music_params->volume;
|
||||
ride_music->pan = ride_music_params->pan;
|
||||
|
@ -2676,7 +2680,7 @@ void ride_music_update_final()
|
|||
}
|
||||
Mixer_Channel_SetOffset(ride_music->sound_channel, offset);
|
||||
} else {
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_MUSIC, uint8) = 0;
|
||||
//RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_MUSIC, uint8) = 0;
|
||||
}
|
||||
#else
|
||||
const char* filename = get_file_path(ride_music_info->pathid);
|
||||
|
@ -2781,13 +2785,13 @@ void game_command_set_ride_setting(int *eax, int *ebx, int *ecx, int *edx, int *
|
|||
if (setting == 0){
|
||||
if (ride->lifecycle_flags & RIDE_LIFECYCLE_BROKEN_DOWN){
|
||||
RCT2_GLOBAL(0x141E9AC, uint16) = 1796;
|
||||
*ebx = 0x80000000;
|
||||
*ebx = MONEY32_UNDEFINED;
|
||||
return;
|
||||
}
|
||||
|
||||
if (ride->status != RIDE_STATUS_CLOSED){
|
||||
RCT2_GLOBAL(0x141E9AC, uint16) = 1006;
|
||||
*ebx = 0x80000000;
|
||||
*ebx = MONEY32_UNDEFINED;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -2796,7 +2800,7 @@ void game_command_set_ride_setting(int *eax, int *ebx, int *ecx, int *edx, int *
|
|||
if (setting == 0 || setting == 4 || setting == 8 || setting == 9)
|
||||
{
|
||||
RCT2_GLOBAL(0x141E9AC, uint16) = 1797;
|
||||
*ebx = 0x80000000;
|
||||
*ebx = MONEY32_UNDEFINED;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -2805,7 +2809,7 @@ void game_command_set_ride_setting(int *eax, int *ebx, int *ecx, int *edx, int *
|
|||
ride->lifecycle_flags & RIDE_LIFECYCLE_CABLE_LIFT &&
|
||||
new_value > 1){
|
||||
RCT2_GLOBAL(0x141E9AC, uint16) = 3141;
|
||||
*ebx = 0x80000000;
|
||||
*ebx = MONEY32_UNDEFINED;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -3590,6 +3594,262 @@ void game_command_set_ride_name(int *eax, int *ebx, int *ecx, int *edx, int *esi
|
|||
*ebx = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006CB7FB
|
||||
*/
|
||||
int ride_get_refund_price(int ride_id)
|
||||
{
|
||||
uint8 oldpaused = RCT2_GLOBAL(RCT2_ADDRESS_GAME_PAUSED, uint8);
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_GAME_PAUSED, uint8) = 0;
|
||||
RCT2_GLOBAL(0x00F4413A, int) = 0;
|
||||
for(int x = 0; x < 8192; x += 32){
|
||||
for(int y = 0; y < 8192; y += 32){
|
||||
int tile_idx = ((y * 256) + x) / 32;
|
||||
rct_map_element* map_element = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[tile_idx];
|
||||
do{
|
||||
if((map_element->type & MAP_ELEMENT_TYPE_MASK) == MAP_ELEMENT_TYPE_TRACK && map_element->properties.track.ride_index == ride_id){
|
||||
int eax, ebx, ecx, edx, esi, edi, ebp;
|
||||
eax = x;
|
||||
ebx = ((map_element->type & MAP_ELEMENT_DIRECTION_MASK) << 8) | 0x01;
|
||||
ecx = y;
|
||||
edx = map_element->properties.track.type;
|
||||
edi = map_element->base_height * 8;
|
||||
if(map_element->properties.track.type == 101){
|
||||
edx = 2 << 8 | map_element->properties.track.ride_index;
|
||||
int oldeax = eax;
|
||||
int oldebx = ebx;
|
||||
int oldecx = ecx;
|
||||
int oldedx = edx;
|
||||
|
||||
ebx = oldebx;
|
||||
ebx |= 0 << 0;
|
||||
RCT2_GLOBAL(0x00F4413A, int) += game_do_command_p(GAME_COMMAND_38, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
|
||||
|
||||
ebx = oldebx;
|
||||
ebx |= 1 << 8;
|
||||
ecx = oldecx;
|
||||
ecx += 16;
|
||||
edx = oldedx;
|
||||
RCT2_GLOBAL(0x00F4413A, int) += game_do_command_p(GAME_COMMAND_38, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
|
||||
|
||||
ebx = oldebx;
|
||||
ebx |= 2 << 8;
|
||||
eax = oldeax;
|
||||
eax += 16;
|
||||
ecx = oldecx;
|
||||
ecx += 16;
|
||||
edx = oldedx;
|
||||
RCT2_GLOBAL(0x00F4413A, int) += game_do_command_p(GAME_COMMAND_38, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
|
||||
|
||||
ebx = oldebx;
|
||||
ebx |= 3 << 8;
|
||||
eax = oldeax;
|
||||
eax += 16;
|
||||
ecx = oldecx;
|
||||
edx = oldedx;
|
||||
RCT2_GLOBAL(0x00F4413A, int) += game_do_command_p(GAME_COMMAND_38, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
|
||||
}else{
|
||||
edx |= 0xFF << 8;
|
||||
edx &= ((map_element->properties.track.sequence & 0xF) << 8) | 0xFF;
|
||||
RCT2_GLOBAL(0x00F4413A, int) += game_do_command_p(GAME_COMMAND_4, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
|
||||
}
|
||||
y -= 32;
|
||||
break;
|
||||
}
|
||||
map_element++;
|
||||
}while(!((map_element - 1)->flags & MAP_ELEMENT_FLAG_LAST_TILE));
|
||||
}
|
||||
}
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_GAME_PAUSED, uint8) = oldpaused;
|
||||
return RCT2_GLOBAL(0x00F4413A, int);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006B49D9
|
||||
*/
|
||||
void game_command_demolish_ride(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp)
|
||||
{
|
||||
uint8 ride_id = *(uint8*)edx;
|
||||
|
||||
RCT2_GLOBAL(0x009DEA5E, uint16) = 0;
|
||||
RCT2_GLOBAL(0x009DEA60, uint16) = 0;
|
||||
RCT2_GLOBAL(0x009DEA62, uint16) = 0;
|
||||
rct_ride *ride = &g_ride_list[ride_id];
|
||||
int x = 0, y = 0, z = 0;
|
||||
if(ride->overall_view != (uint16)-1){
|
||||
x = ((ride->overall_view & 0xFF) * 32) + 16;
|
||||
y = ((ride->overall_view >> 8) * 32) + 16;
|
||||
z = map_element_height(x, y);
|
||||
RCT2_GLOBAL(0x009DEA5E, uint16) = x;
|
||||
RCT2_GLOBAL(0x009DEA60, uint16) = y;
|
||||
RCT2_GLOBAL(0x009DEA62, uint16) = z;
|
||||
}
|
||||
if(!(*ebx & 0x40) && RCT2_GLOBAL(RCT2_ADDRESS_GAME_PAUSED, uint8)){
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = STR_CONSTRUCTION_NOT_POSSIBLE_WHILE_GAME_IS_PAUSED;
|
||||
*ebx = MONEY32_UNDEFINED;
|
||||
return;
|
||||
}else{
|
||||
if(*ebx & GAME_COMMAND_FLAG_APPLY){
|
||||
if(!(*ebx & 8)){
|
||||
window_close_by_number(WC_RIDE_CONSTRUCTION, ride_id);
|
||||
}
|
||||
window_close_by_number(WC_RIDE, ride_id);
|
||||
window_close_by_number(WC_DEMOLISH_RIDE_PROMPT, ride_id);
|
||||
window_close_by_class(WC_NEW_CAMPAIGN);
|
||||
if(RCT2_GLOBAL(0x01358103, uint8) && ride_id == RCT2_GLOBAL(0x01358117, uint8)){
|
||||
RCT2_GLOBAL(0x01358103, uint8) = 0;
|
||||
}
|
||||
if(RCT2_GLOBAL(0x01358107, uint8) && ride_id == RCT2_GLOBAL(0x0135811B, uint8)){
|
||||
RCT2_GLOBAL(0x01358107, uint8) = 0;
|
||||
}
|
||||
ride_clear_for_construction(ride_id);
|
||||
ride_remove_peeps(ride_id);
|
||||
RCT2_CALLPROC_X(0x00696707, 0, 0, 0, ride_id, 0, 0, 0);
|
||||
*ebx = ride_get_refund_price(ride_id);
|
||||
|
||||
RCT2_CALLPROC(0x006CB945);
|
||||
news_item_disable_news(NEWS_ITEM_RIDE, ride_id);
|
||||
|
||||
for(int i = 0; i < MAX_BANNERS; i++){
|
||||
rct_banner *banner = &gBanners[i];
|
||||
if(banner->type != BANNER_NULL && banner->flags & BANNER_FLAG_2 && banner->colour == ride_id){
|
||||
banner->flags &= 0xFB;
|
||||
banner->string_idx = 778;
|
||||
}
|
||||
}
|
||||
|
||||
uint16 spriteIndex;
|
||||
rct_peep *peep;
|
||||
FOR_ALL_GUESTS(spriteIndex, peep){
|
||||
uint8 ride_id_bit = ride_id & 0x3;
|
||||
uint8 ride_id_offset = ride_id / 8;
|
||||
peep->rides_been_on[ride_id_offset] &= ~(1 << ride_id_bit); // clear ride from potentially being in rides_been_on
|
||||
if(peep->state == PEEP_STATE_WATCHING){
|
||||
if(peep->current_ride == ride_id){
|
||||
peep->current_ride = MAX_RIDES;
|
||||
if(peep->time_to_stand >= 50){ // make peep stop watching the ride
|
||||
peep->time_to_stand = 50;
|
||||
}
|
||||
}
|
||||
}
|
||||
// remove any free voucher for this ride from peep
|
||||
if(peep->item_standard_flags & PEEP_ITEM_VOUCHER){
|
||||
if(peep->voucher_type == VOUCHER_TYPE_RIDE_FREE && peep->voucher_arguments == ride_id){
|
||||
peep->item_standard_flags &= ~(PEEP_ITEM_VOUCHER);
|
||||
}
|
||||
}
|
||||
// remove any photos of this ride from peep
|
||||
if(peep->item_standard_flags & PEEP_ITEM_PHOTO){
|
||||
if(peep->photo1_ride_ref == ride_id){
|
||||
peep->item_standard_flags &= ~PEEP_ITEM_PHOTO;
|
||||
}
|
||||
}
|
||||
if(peep->item_extra_flags && PEEP_ITEM_PHOTO2){
|
||||
if(peep->photo2_ride_ref == ride_id){
|
||||
peep->item_extra_flags &= ~PEEP_ITEM_PHOTO2;
|
||||
}
|
||||
}
|
||||
if(peep->item_extra_flags && PEEP_ITEM_PHOTO3){
|
||||
if(peep->photo3_ride_ref == ride_id){
|
||||
peep->item_extra_flags &= ~PEEP_ITEM_PHOTO3;
|
||||
}
|
||||
}
|
||||
if(peep->item_extra_flags && PEEP_ITEM_PHOTO4){
|
||||
if(peep->photo4_ride_ref == ride_id){
|
||||
peep->item_extra_flags &= ~PEEP_ITEM_PHOTO4;
|
||||
}
|
||||
}
|
||||
if(peep->guest_heading_to_ride_id == ride_id){
|
||||
peep->guest_heading_to_ride_id = MAX_RIDES;
|
||||
}
|
||||
if(peep->favourite_ride == ride_id){
|
||||
peep->favourite_ride = MAX_RIDES;
|
||||
}
|
||||
for (int i = 0; i < PEEP_MAX_THOUGHTS; i++) {
|
||||
if(peep->thoughts[i].item == ride_id){
|
||||
// Clear top thought, push others up
|
||||
memmove(&peep->thoughts[i], &peep->thoughts[i + 1], sizeof(rct_peep_thought)*(PEEP_MAX_THOUGHTS - i - 1));
|
||||
peep->thoughts[PEEP_MAX_THOUGHTS - 1].type = PEEP_THOUGHT_TYPE_NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
user_string_free(ride->name);
|
||||
ride->type = RIDE_TYPE_NULL;
|
||||
window_invalidate_by_class(WC_RIDE_LIST);
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PARK_VALUE, money32) = calculate_park_value();
|
||||
RCT2_GLOBAL(0x009DEA5E, uint16) = x;
|
||||
RCT2_GLOBAL(0x009DEA60, uint16) = y;
|
||||
RCT2_GLOBAL(0x009DEA62, uint16) = z;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_NEXT_EXPENDITURE_TYPE, uint8) = RCT_EXPENDITURE_TYPE_RIDE_CONSTRUCTION;
|
||||
return;
|
||||
}else{
|
||||
*ebx = 0;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_NEXT_EXPENDITURE_TYPE, uint8) = RCT_EXPENDITURE_TYPE_RIDE_CONSTRUCTION;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006B2FC5
|
||||
*/
|
||||
void game_command_set_ride_appearance(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp)
|
||||
{
|
||||
if(*ebx & GAME_COMMAND_FLAG_APPLY){
|
||||
uint8 ride_id = *edx;
|
||||
uint8 type = *ebx >> 8;
|
||||
uint8 value = *edx >> 8;
|
||||
int index = *edi;
|
||||
rct_ride *ride = &g_ride_list[ride_id];
|
||||
switch(type){
|
||||
case 0:
|
||||
ride->track_colour_main[index] = value;
|
||||
gfx_invalidate_screen();
|
||||
break;
|
||||
case 1:
|
||||
ride->track_colour_additional[index] = value;
|
||||
gfx_invalidate_screen();
|
||||
break;
|
||||
case 2:
|
||||
*((uint8*)(&ride->vehicle_colours[index])) = value;
|
||||
RCT2_CALLPROC_X(0x006DE102, 0, 0, 0, ride_id, 0, 0, 0);
|
||||
break;
|
||||
case 3:
|
||||
*((uint8*)(&ride->vehicle_colours[index]) + 1) = value;
|
||||
RCT2_CALLPROC_X(0x006DE102, 0, 0, 0, ride_id, 0, 0, 0);
|
||||
break;
|
||||
case 4:
|
||||
ride->track_colour_supports[index] = value;
|
||||
gfx_invalidate_screen();
|
||||
break;
|
||||
case 5:
|
||||
ride->colour_scheme_type &= ~(RIDE_COLOUR_SCHEME_DIFFERENT_PER_TRAIN | RIDE_COLOUR_SCHEME_DIFFERENT_PER_CAR);
|
||||
ride->colour_scheme_type |= value;
|
||||
for(int i = 1; i < countof(ride->vehicle_colours); i++){
|
||||
ride->vehicle_colours[i] = ride->vehicle_colours[0];
|
||||
ride->vehicle_colours_extended[i] = ride->vehicle_colours_extended[0];
|
||||
}
|
||||
RCT2_CALLPROC_X(0x006DE102, 0, 0, 0, ride_id, 0, 0, 0);
|
||||
break;
|
||||
case 6:
|
||||
ride->entrance_style = value;
|
||||
RCT2_GLOBAL(0x01358840, uint8) = value;
|
||||
gfx_invalidate_screen();
|
||||
break;
|
||||
case 7:
|
||||
ride->vehicle_colours_extended[index] = value;
|
||||
RCT2_CALLPROC_X(0x006DE102, 0, 0, 0, ride_id, 0, 0, 0);
|
||||
break;
|
||||
}
|
||||
window_invalidate_by_number(WC_RIDE, ride_id);
|
||||
}
|
||||
*ebx = 0;
|
||||
}
|
||||
|
||||
bool ride_type_has_flag(int rideType, int flag)
|
||||
{
|
||||
return (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + (rideType * 8), uint32) & flag) != 0;
|
||||
|
|
|
@ -764,6 +764,9 @@ void game_command_set_ride_status(int *eax, int *ebx, int *ecx, int *edx, int *e
|
|||
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 ride_get_refund_price(int ride_id);
|
||||
void game_command_demolish_ride(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp);
|
||||
void game_command_set_ride_appearance(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);
|
||||
|
|
|
@ -784,7 +784,7 @@ int sub_6D2189(int* cost, uint8* ride_id){
|
|||
edx = track_design->type | (entry_index << 8);
|
||||
esi = GAME_COMMAND_6;
|
||||
|
||||
if (0x80000000 == game_do_command_p(GAME_COMMAND_6, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp)) return 1;
|
||||
if (MONEY32_UNDEFINED == game_do_command_p(GAME_COMMAND_6, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp)) return 1;
|
||||
|
||||
// bh
|
||||
*ride_id = edi & 0xFF;
|
||||
|
@ -840,7 +840,7 @@ int sub_6D2189(int* cost, uint8* ride_id){
|
|||
edi = sub_6D01B3((*ride_id << 8) | bl, map_size, map_size, z);
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) = backup_park_flags;
|
||||
|
||||
if (edi != 0x80000000){
|
||||
if (edi != MONEY32_UNDEFINED){
|
||||
|
||||
if (!find_object_in_entry_group(&track_design->vehicle_object, &entry_type, &entry_index)){
|
||||
RCT2_GLOBAL(0xF44151, uint8) |= 4;
|
||||
|
|
|
@ -314,7 +314,7 @@ int scenario_load_and_play_from_path(const char *path)
|
|||
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PROFIT, money32) = 0;
|
||||
RCT2_GLOBAL(0x01358334, money32) = 0;
|
||||
RCT2_GLOBAL(0x01358338, uint16) = 0;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_COMPLETED_COMPANY_VALUE, uint32) = 0x80000000;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_COMPLETED_COMPANY_VALUE, uint32) = MONEY32_UNDEFINED;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_TOTAL_ADMISSIONS, uint32) = 0;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INCOME_FROM_ADMISSIONS, uint32) = 0;
|
||||
RCT2_GLOBAL(0x013587D8, uint16) = 63;
|
||||
|
@ -517,7 +517,7 @@ void scenario_objectives_check()
|
|||
park_value = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_PARK_VALUE, sint32);
|
||||
|
||||
|
||||
if ( scenario_completed_company_value != 0x80000000)
|
||||
if ( scenario_completed_company_value != MONEY32_UNDEFINED)
|
||||
return;
|
||||
|
||||
switch (objective_type) {
|
||||
|
|
|
@ -201,7 +201,7 @@ static void window_banner_mouseup()
|
|||
window_close(w);
|
||||
break;
|
||||
case WIDX_BANNER_DEMOLISH:
|
||||
game_do_command(x, 1, y, map_element->base_height | (map_element->properties.banner.position << 8), GAME_COMMAND_51, 0, 0);
|
||||
game_do_command(x, 1, y, map_element->base_height | (map_element->properties.banner.position << 8), GAME_COMMAND_REMOVE_BANNER, 0, 0);
|
||||
break;
|
||||
case WIDX_BANNER_TEXT:
|
||||
window_text_input_open(w, WIDX_BANNER_TEXT, 2982, 2983, gBanners[w->number].string_idx, 0, 32);
|
||||
|
@ -244,7 +244,7 @@ static void window_banner_mousedown(int widgetIndex, rct_window*w, rct_widget* w
|
|||
widget->top + w->y,
|
||||
widget->bottom - widget->top + 1,
|
||||
w->colours[1],
|
||||
0x80,
|
||||
DROPDOWN_FLAG_STAY_OPEN,
|
||||
13,
|
||||
widget->right - widget->left - 3);
|
||||
|
||||
|
|
|
@ -103,7 +103,7 @@ void window_clear_scenery_open()
|
|||
window_init_scroll_widgets(window);
|
||||
window_push_others_below(window);
|
||||
|
||||
RCT2_GLOBAL(0x00F1AD62, uint32) = 0x80000000;
|
||||
RCT2_GLOBAL(0x00F1AD62, uint32) = MONEY32_UNDEFINED;
|
||||
window->colours[0] = 24;
|
||||
window->colours[1] = 24;
|
||||
window->colours[2] = 24;
|
||||
|
@ -209,7 +209,7 @@ static void window_clear_scenery_paint()
|
|||
// Draw cost amount
|
||||
x = (window_clear_scenery_widgets[WIDX_PREVIEW].left + window_clear_scenery_widgets[WIDX_PREVIEW].right) / 2 + w->x;
|
||||
y = window_clear_scenery_widgets[WIDX_PREVIEW].bottom + w->y + 5;
|
||||
if (RCT2_GLOBAL(0x00F1AD62, uint32) != 0x80000000 && RCT2_GLOBAL(0x00F1AD62, uint32) != 0)
|
||||
if (RCT2_GLOBAL(0x00F1AD62, uint32) != MONEY32_UNDEFINED && RCT2_GLOBAL(0x00F1AD62, uint32) != 0)
|
||||
gfx_draw_string_centred(dpi, 986, x, y, 0, (void*)0x00F1AD62);
|
||||
}
|
||||
|
||||
|
|
|
@ -136,9 +136,9 @@ void window_dropdown_show_text_custom_width(int x, int y, int extray, uint8 colo
|
|||
memcpy((void*)0x009DEBA4, gDropdownItemsFormat, 40 * 2);
|
||||
memcpy((void*)0x009DEBF4, gDropdownItemsArgs, 40 * 8);
|
||||
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) &= ~(INPUT_FLAG_1 | INPUT_FLAG_2);
|
||||
if (flags & 0x80)
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) |= INPUT_FLAG_1;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) &= ~(INPUT_FLAG_DROPDOWN_STAY_OPEN | INPUT_FLAG_DROPDOWN_MOUSE_UP);
|
||||
if (flags & DROPDOWN_FLAG_STAY_OPEN)
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) |= INPUT_FLAG_DROPDOWN_STAY_OPEN;
|
||||
|
||||
window_dropdown_close();
|
||||
_dropdown_num_columns = 1;
|
||||
|
@ -213,9 +213,9 @@ void window_dropdown_show_image(int x, int y, int extray, uint8 colour, uint8 fl
|
|||
memcpy((void*)0x009DEBA4, gDropdownItemsFormat, 40 * 2);
|
||||
memcpy((void*)0x009DEBF4, gDropdownItemsArgs, 40 * 8);
|
||||
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) &= ~(INPUT_FLAG_1 | INPUT_FLAG_2);
|
||||
if (flags & 0x80)
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) |= INPUT_FLAG_1;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) &= ~(INPUT_FLAG_DROPDOWN_STAY_OPEN | INPUT_FLAG_DROPDOWN_MOUSE_UP);
|
||||
if (flags & DROPDOWN_FLAG_STAY_OPEN)
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) |= INPUT_FLAG_DROPDOWN_STAY_OPEN;
|
||||
|
||||
// Close existing dropdown
|
||||
window_dropdown_close();
|
||||
|
@ -411,19 +411,6 @@ void window_dropdown_show_colour_available(rct_window *w, rct_widget *widget, ui
|
|||
if (availableColours & (1 << i))
|
||||
numItems++;
|
||||
|
||||
// Show dropdown
|
||||
window_dropdown_show_image(
|
||||
w->x + widget->left,
|
||||
w->y + widget->top,
|
||||
widget->bottom - widget->top + 1,
|
||||
dropdownColour,
|
||||
0x80,
|
||||
numItems,
|
||||
12,
|
||||
12,
|
||||
gAppropriateImageDropdownItemsPerRow[numItems]
|
||||
);
|
||||
|
||||
// Set items
|
||||
for (i = 0; i < 32; i++) {
|
||||
if (availableColours & (1 << i)) {
|
||||
|
@ -434,4 +421,18 @@ void window_dropdown_show_colour_available(rct_window *w, rct_widget *widget, ui
|
|||
gDropdownItemsArgs[i] = ((uint64)i << 32) | (0x20000000 | (i << 19) | 5059);
|
||||
}
|
||||
}
|
||||
|
||||
// Show dropdown
|
||||
window_dropdown_show_image(
|
||||
w->x + widget->left,
|
||||
w->y + widget->top,
|
||||
widget->bottom - widget->top + 1,
|
||||
dropdownColour,
|
||||
DROPDOWN_FLAG_STAY_OPEN,
|
||||
numItems,
|
||||
12,
|
||||
12,
|
||||
gAppropriateImageDropdownItemsPerRow[numItems]
|
||||
);
|
||||
|
||||
}
|
||||
|
|
|
@ -25,6 +25,11 @@
|
|||
|
||||
#define DROPDOWN_SEPARATOR 0
|
||||
|
||||
enum
|
||||
{
|
||||
DROPDOWN_FLAG_STAY_OPEN = (1 << 7)
|
||||
};
|
||||
|
||||
extern int gAppropriateImageDropdownItemsPerRow[];
|
||||
|
||||
extern int gDropdownNumItems;
|
||||
|
|
|
@ -214,7 +214,7 @@ void window_editor_object_selection_open()
|
|||
400,
|
||||
(uint32*)window_editor_object_selection_events,
|
||||
WC_EDITOR_OBJECT_SELECTION,
|
||||
WF_STICK_TO_FRONT
|
||||
WF_10
|
||||
);
|
||||
window->widgets = window_editor_object_selection_widgets;
|
||||
|
||||
|
|
|
@ -507,7 +507,7 @@ static void window_editor_objective_options_show_objective_dropdown(rct_window *
|
|||
w->y + dropdownWidget->top,
|
||||
dropdownWidget->bottom - dropdownWidget->top + 1,
|
||||
w->colours[1],
|
||||
0x80,
|
||||
DROPDOWN_FLAG_STAY_OPEN,
|
||||
numItems,
|
||||
dropdownWidget->right - dropdownWidget->left - 3
|
||||
);
|
||||
|
@ -537,7 +537,7 @@ static void window_editor_objective_options_show_climate_dropdown(rct_window *w)
|
|||
w->y + dropdownWidget->top,
|
||||
dropdownWidget->bottom - dropdownWidget->top + 1,
|
||||
w->colours[1],
|
||||
0x80,
|
||||
DROPDOWN_FLAG_STAY_OPEN,
|
||||
4,
|
||||
dropdownWidget->right - dropdownWidget->left - 3
|
||||
);
|
||||
|
@ -561,7 +561,7 @@ static void window_editor_objective_options_show_category_dropdown(rct_window *w
|
|||
w->y + dropdownWidget->top,
|
||||
dropdownWidget->bottom - dropdownWidget->top + 1,
|
||||
w->colours[1],
|
||||
0x80,
|
||||
DROPDOWN_FLAG_STAY_OPEN,
|
||||
5,
|
||||
dropdownWidget->right - dropdownWidget->left - 3
|
||||
);
|
||||
|
|
|
@ -1049,7 +1049,7 @@ static void window_editor_scenario_options_park_mousedown(int widgetIndex, rct_w
|
|||
w->y + dropdownWidget->top,
|
||||
dropdownWidget->bottom - dropdownWidget->top - 1,
|
||||
w->colours[1],
|
||||
0x80,
|
||||
DROPDOWN_FLAG_STAY_OPEN,
|
||||
2,
|
||||
dropdownWidget->right - dropdownWidget->left - 3
|
||||
);
|
||||
|
|
|
@ -865,7 +865,7 @@ static void window_finances_financial_graph_paint()
|
|||
money32 *balanceHistory = RCT2_ADDRESS(RCT2_ADDRESS_BALANCE_HISTORY, money32);
|
||||
for (i = 0; i < 64; i++) {
|
||||
money32 balance = balanceHistory[i];
|
||||
if (balance == 0x80000000)
|
||||
if (balance == MONEY32_UNDEFINED)
|
||||
continue;
|
||||
|
||||
// Modifier balance then keep halfing until less than 127 pixels
|
||||
|
@ -983,7 +983,7 @@ static void window_finances_park_value_graph_paint()
|
|||
money32 *parkValueHistory = RCT2_ADDRESS(RCT2_ADDRESS_PARK_VALUE_HISTORY, money32);
|
||||
for (i = 0; i < 64; i++) {
|
||||
money32 balance = parkValueHistory[i];
|
||||
if (balance == 0x80000000)
|
||||
if (balance == MONEY32_UNDEFINED)
|
||||
continue;
|
||||
|
||||
// Modifier balance then keep halfing until less than 255 pixels
|
||||
|
@ -1101,7 +1101,7 @@ static void window_finances_profit_graph_paint()
|
|||
money32 *weeklyProfitHistory = RCT2_ADDRESS(RCT2_ADDRESS_WEEKLY_PROFIT_HISTORY, money32);
|
||||
for (i = 0; i < 64; i++) {
|
||||
money32 balance = weeklyProfitHistory[i];
|
||||
if (balance == 0x80000000)
|
||||
if (balance == MONEY32_UNDEFINED)
|
||||
continue;
|
||||
|
||||
// Modifier balance then keep halfing until less than 127 pixels
|
||||
|
@ -1375,7 +1375,7 @@ static void window_finances_research_mousedown(int widgetIndex, rct_window *w, r
|
|||
w->y + dropdownWidget->top,
|
||||
dropdownWidget->bottom - dropdownWidget->top + 1,
|
||||
w->colours[1],
|
||||
0x80,
|
||||
DROPDOWN_FLAG_STAY_OPEN,
|
||||
4,
|
||||
dropdownWidget->right - dropdownWidget->left - 3
|
||||
);
|
||||
|
|
|
@ -667,15 +667,15 @@ static void window_footpath_mousedown_slope(int slope)
|
|||
*/
|
||||
static void window_footpath_set_provisional_path_at_point(int x, int y)
|
||||
{
|
||||
int z, slope, pathType;
|
||||
int slope, pathType, interactionType;
|
||||
rct_map_element *mapElement;
|
||||
|
||||
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, NULL);
|
||||
get_map_coordinates_from_pos(x, y, VIEWPORT_INTERACTION_MASK_FOOTPATH & VIEWPORT_INTERACTION_MASK_TERRAIN, &x, &y, &interactionType, &mapElement, NULL);
|
||||
|
||||
if (z == 0) {
|
||||
if (interactionType == VIEWPORT_INTERACTION_ITEM_NONE) {
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_MAP_SELECTION_FLAGS, uint16) &= ~(1 << 0);
|
||||
footpath_provisional_update();
|
||||
} else {
|
||||
|
@ -695,7 +695,7 @@ static void window_footpath_set_provisional_path_at_point(int x, int y)
|
|||
|
||||
// Set provisional path
|
||||
slope = RCT2_ADDRESS(0x0098D8B4, uint8)[mapElement->properties.surface.slope & 0x1F];
|
||||
if (z == 6)
|
||||
if (interactionType == VIEWPORT_INTERACTION_ITEM_FOOTPATH)
|
||||
slope = mapElement->properties.surface.slope & 7;
|
||||
pathType = (RCT2_GLOBAL(RCT2_ADDRESS_SELECTED_PATH_TYPE, uint8) << 7) + RCT2_GLOBAL(RCT2_ADDRESS_SELECTED_PATH_ID, uint8);
|
||||
|
||||
|
@ -752,7 +752,7 @@ static void window_footpath_set_selection_start_bridge_at_point(int screenX, int
|
|||
*/
|
||||
static void window_footpath_place_path_at_point(int x, int y)
|
||||
{
|
||||
int z, presentType, selectedType, cost;
|
||||
int interactionType, presentType, selectedType, z, cost;
|
||||
rct_map_element *mapElement;
|
||||
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_PATH_ERROR_OCCURED, uint8) != 0)
|
||||
|
@ -760,13 +760,13 @@ 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, NULL);
|
||||
if (z == 0)
|
||||
get_map_coordinates_from_pos(x, y, VIEWPORT_INTERACTION_MASK_FOOTPATH & VIEWPORT_INTERACTION_MASK_TERRAIN, &x, &y, &interactionType, &mapElement, NULL);
|
||||
if (interactionType == VIEWPORT_INTERACTION_ITEM_NONE)
|
||||
return;
|
||||
|
||||
// Set path
|
||||
presentType = RCT2_ADDRESS(0x0098D8B4, uint8)[mapElement->properties.path.type & 0x1F];
|
||||
if (z == 6)
|
||||
if (interactionType == VIEWPORT_INTERACTION_ITEM_FOOTPATH)
|
||||
presentType = mapElement->properties.path.type & 7;
|
||||
z = mapElement->base_height;
|
||||
selectedType = (RCT2_GLOBAL(RCT2_ADDRESS_SELECTED_PATH_TYPE, uint8) << 7) + RCT2_GLOBAL(RCT2_ADDRESS_SELECTED_PATH_ID, uint8);
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "../interface/widget.h"
|
||||
#include "../interface/window.h"
|
||||
#include "../world/footpath.h"
|
||||
#include "../input.h"
|
||||
#include "dropdown.h"
|
||||
#include "error.h"
|
||||
|
||||
|
@ -555,7 +556,7 @@ void window_guest_overview_close(){
|
|||
|
||||
window_get_register(w);
|
||||
|
||||
if (RCT2_GLOBAL(0x9DE518,uint32) & (1<<3)){
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_TOOL_ACTIVE){
|
||||
if (w->classification == RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS,rct_windowclass) &&
|
||||
w->number == RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWNUMBER,rct_windownumber))
|
||||
tool_cancel();
|
||||
|
@ -622,7 +623,7 @@ void window_guest_overview_mouse_up(){
|
|||
|
||||
w->var_48C = peep->x;
|
||||
|
||||
RCT2_CALLPROC_X(0x0069A512, 0, 0, 0, 0, (int)peep, 0, 0);
|
||||
remove_peep_from_ride(peep);
|
||||
invalidate_sprite((rct_sprite*)peep);
|
||||
|
||||
sprite_move(0x8000, peep->y, peep->z, (rct_sprite*)peep);
|
||||
|
@ -645,7 +646,7 @@ void window_guest_overview_mouse_up(){
|
|||
|
||||
/* rct2: 0x696AA0 */
|
||||
void window_guest_set_page(rct_window* w, int page){
|
||||
if (RCT2_GLOBAL(0x9DE518,uint32) & (1 << 3))
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_TOOL_ACTIVE)
|
||||
{
|
||||
if(w->number == RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWNUMBER, rct_windownumber) &&
|
||||
w->classification == RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass))
|
||||
|
@ -1157,9 +1158,9 @@ void window_guest_overview_tool_update(){
|
|||
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_PICKEDUP_PEEP_SPRITE, sint32) = -1;
|
||||
|
||||
int ebx;
|
||||
get_map_coordinates_from_pos(x, y, 0, NULL, NULL, &ebx, NULL, NULL);
|
||||
if (ebx == 0)
|
||||
int interactionType;
|
||||
get_map_coordinates_from_pos(x, y, VIEWPORT_INTERACTION_MASK_NONE, NULL, NULL, &interactionType, NULL, NULL);
|
||||
if (interactionType == VIEWPORT_INTERACTION_ITEM_NONE)
|
||||
return;
|
||||
|
||||
x--;
|
||||
|
@ -1171,7 +1172,7 @@ void window_guest_overview_tool_update(){
|
|||
|
||||
rct_peep* peep;
|
||||
peep = GET_PEEP(w->number);
|
||||
ebx = (RCT2_ADDRESS(0x982708, uint32*)[peep->sprite_type * 2])[22];
|
||||
int ebx = (RCT2_ADDRESS(0x982708, uint32*)[peep->sprite_type * 2])[22];
|
||||
ebx += w->var_492 >> 2;
|
||||
|
||||
int ebp = peep->tshirt_colour << 19;
|
||||
|
@ -1237,8 +1238,7 @@ void window_guest_overview_tool_down(){
|
|||
peep->action_sprite_type = 0xFF;
|
||||
peep->var_C4 = 0;
|
||||
|
||||
peep->happiness_growth_rate -= 10;
|
||||
if (peep->happiness_growth_rate < 0)peep->happiness_growth_rate = 0;
|
||||
peep->happiness_growth_rate = max(peep->happiness_growth_rate - 10, 0);
|
||||
|
||||
sub_693B58(peep);
|
||||
tool_cancel();
|
||||
|
|
|
@ -339,7 +339,7 @@ static void window_guest_list_mousedown(int widgetIndex, rct_window*w, rct_widge
|
|||
w->y + widget->top,
|
||||
widget->bottom - widget->top + 1,
|
||||
w->colours[1],
|
||||
0x80,
|
||||
DROPDOWN_FLAG_STAY_OPEN,
|
||||
_window_guest_list_num_pages,
|
||||
widget->right - widget->left - 3
|
||||
);
|
||||
|
@ -363,7 +363,7 @@ static void window_guest_list_mousedown(int widgetIndex, rct_window*w, rct_widge
|
|||
w->y + widget->top,
|
||||
widget->bottom - widget->top + 1,
|
||||
w->colours[1],
|
||||
0x80,
|
||||
DROPDOWN_FLAG_STAY_OPEN,
|
||||
2,
|
||||
widget->right - widget->left - 3
|
||||
);
|
||||
|
|
|
@ -255,6 +255,10 @@ static void window_loadsave_mouseup()
|
|||
char filename[MAX_PATH], filter[MAX_PATH];
|
||||
int result;
|
||||
|
||||
strcpy(filename, _directory);
|
||||
if (_type & LOADSAVETYPE_SAVE){
|
||||
strcat(filename, (char*)RCT2_ADDRESS_SCENARIO_NAME);
|
||||
}
|
||||
memset(filter, '\0', MAX_PATH);
|
||||
strncpy(filter, "*", MAX_PATH);
|
||||
strncat(filter, _extension, MAX_PATH);
|
||||
|
@ -605,7 +609,7 @@ static void window_loadsave_select(rct_window *w, const char *path)
|
|||
if (scenario_save((char*)path, gConfigGeneral.save_plugin_data ? 1 : 0)) {
|
||||
window_close(w);
|
||||
|
||||
game_do_command(0, 1047, 0, -1, GAME_COMMAND_0, 0, 0);
|
||||
game_do_command(0, 1047, 0, -1, GAME_COMMAND_SET_RIDE_APPEARANCE, 0, 0);
|
||||
gfx_invalidate_screen();
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -319,8 +319,8 @@ static void window_map_mouseup()
|
|||
|
||||
RCT2_GLOBAL(0x9E32D2, sint8) = 0;
|
||||
|
||||
if (!(RCT2_GLOBAL(0x9DE518, sint32) & (1 << 6))) // Remove?
|
||||
RCT2_GLOBAL(0x9DE518, sint32) |= (1 << 6);
|
||||
if (!(RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, sint32) & INPUT_FLAG_6)) // Remove?
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, sint32) |= INPUT_FLAG_6;
|
||||
|
||||
show_gridlines();
|
||||
show_land_rights();
|
||||
|
@ -369,14 +369,19 @@ static void window_map_mouseup()
|
|||
*/
|
||||
static void window_map_mousedown(int widgetIndex, rct_window*w, rct_widget* widget)
|
||||
{
|
||||
// The normal map window doesn't have widget 8 or 9.
|
||||
// I assume these widgets refer to the Scenario Editor's map window.
|
||||
if (widgetIndex == 8) {
|
||||
// These widgets all refer to the Scenario Editor's map window.
|
||||
if (widgetIndex == WIDX_MAP_SIZE_SPINNER_UP) {
|
||||
RCT2_CALLPROC_X(0x0068D641, 0, 0, 0, widgetIndex, (int)w, 0, 0);
|
||||
}
|
||||
else if (widgetIndex == 9) {
|
||||
else if (widgetIndex == WIDX_MAP_SIZE_SPINNER_DOWN) {
|
||||
RCT2_CALLPROC_X(0x0068D6B4, 0, 0, 0, widgetIndex, (int)w, 0, 0);
|
||||
}
|
||||
else if (widgetIndex == WIDX_SET_LAND_RIGHTS)
|
||||
{
|
||||
// When unselecting the land rights tool, reset the size so the number doesn't
|
||||
// stay in the map window.
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_LAND_TOOL_SIZE, sint16) = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -273,7 +273,7 @@ static void window_new_campaign_mousedown(int widgetIndex, rct_window *w, rct_wi
|
|||
w->y + dropdownWidget->top,
|
||||
dropdownWidget->bottom - dropdownWidget->top + 1,
|
||||
w->colours[1],
|
||||
0x80,
|
||||
DROPDOWN_FLAG_STAY_OPEN,
|
||||
numItems,
|
||||
dropdownWidget->right - dropdownWidget->left - 3
|
||||
);
|
||||
|
@ -295,7 +295,7 @@ static void window_new_campaign_mousedown(int widgetIndex, rct_window *w, rct_wi
|
|||
w->y + dropdownWidget->top,
|
||||
dropdownWidget->bottom - dropdownWidget->top + 1,
|
||||
w->colours[1],
|
||||
0x80,
|
||||
DROPDOWN_FLAG_STAY_OPEN,
|
||||
numItems,
|
||||
dropdownWidget->right - dropdownWidget->left - 3
|
||||
);
|
||||
|
|
|
@ -221,7 +221,7 @@ void window_options_open()
|
|||
if (w != NULL)
|
||||
return;
|
||||
|
||||
w = window_create_centred(WW, WH, (uint32*)window_options_events, WC_OPTIONS, WF_STICK_TO_FRONT);
|
||||
w = window_create_centred(WW, WH, (uint32*)window_options_events, WC_OPTIONS, 0);
|
||||
w->widgets = window_options_widgets;
|
||||
w->enabled_widgets =
|
||||
(1ULL << WIDX_CLOSE) |
|
||||
|
@ -396,12 +396,15 @@ static void window_options_mousedown(int widgetIndex, rct_window*w, rct_widget*
|
|||
gDropdownItemsChecked = gConfigGeneral.show_height_as_units ? 1 : 2;
|
||||
break;
|
||||
case WIDX_TITLE_MUSIC_DROPDOWN:
|
||||
num_items = 3;
|
||||
num_items = 4;
|
||||
|
||||
for (i = 0; i < num_items; i++) {
|
||||
for (i = 0; i < num_items - 1; i++) {
|
||||
gDropdownItemsFormat[i] = 1142;
|
||||
gDropdownItemsArgs[i] = 2739 + i;
|
||||
}
|
||||
// Random title music
|
||||
gDropdownItemsFormat[3] = 1142;
|
||||
gDropdownItemsArgs[3] = 5126;
|
||||
|
||||
window_options_show_dropdown(w, widget, num_items);
|
||||
|
||||
|
@ -556,7 +559,7 @@ static void window_options_dropdown()
|
|||
window_options_update_height_markers();
|
||||
break;
|
||||
case WIDX_TITLE_MUSIC_DROPDOWN:
|
||||
if (dropdownIndex == 1 && !platform_file_exists(get_file_path(PATH_ID_CSS50))) {
|
||||
if ((dropdownIndex == 1 || dropdownIndex == 3) && !platform_file_exists(get_file_path(PATH_ID_CSS50))) {
|
||||
window_error_open(2742, 2743);
|
||||
} else {
|
||||
gConfigSound.title_music = (sint8)dropdownIndex;
|
||||
|
@ -837,7 +840,7 @@ static void window_options_paint()
|
|||
gfx_draw_string_left(dpi, 2738, w, 12, w->x + 10, w->y + window_options_widgets[WIDX_TITLE_MUSIC].top + 1);
|
||||
gfx_draw_string_left(
|
||||
dpi,
|
||||
2739 + gConfigSound.title_music,
|
||||
(gConfigSound.title_music == 3 ? 5126 : 2739 + gConfigSound.title_music),
|
||||
NULL,
|
||||
12,
|
||||
w->x + window_options_widgets[WIDX_TITLE_MUSIC].left + 1,
|
||||
|
@ -866,7 +869,7 @@ static void window_options_show_dropdown(rct_window *w, rct_widget *widget, int
|
|||
w->y + widget->top,
|
||||
widget->bottom - widget->top + 1,
|
||||
w->colours[1],
|
||||
0x80,
|
||||
DROPDOWN_FLAG_STAY_OPEN,
|
||||
num_items,
|
||||
widget->right - widget->left - 3
|
||||
);
|
||||
|
|
|
@ -472,7 +472,7 @@ static void window_research_funding_mousedown(int widgetIndex, rct_window *w, rc
|
|||
w->y + dropdownWidget->top,
|
||||
dropdownWidget->bottom - dropdownWidget->top + 1,
|
||||
w->colours[1],
|
||||
0x80,
|
||||
DROPDOWN_FLAG_STAY_OPEN,
|
||||
4,
|
||||
dropdownWidget->right - dropdownWidget->left - 3
|
||||
);
|
||||
|
|
|
@ -2308,7 +2308,7 @@ static void window_ride_vehicle_mousedown(int widgetIndex, rct_window *w, rct_wi
|
|||
w->y + dropdownWidget->top,
|
||||
dropdownWidget->bottom - dropdownWidget->top + 1,
|
||||
w->colours[1],
|
||||
0x80,
|
||||
DROPDOWN_FLAG_STAY_OPEN,
|
||||
numItems,
|
||||
widget->right - dropdownWidget->left
|
||||
);
|
||||
|
@ -2321,7 +2321,7 @@ static void window_ride_vehicle_mousedown(int widgetIndex, rct_window *w, rct_wi
|
|||
w->y + dropdownWidget->top,
|
||||
dropdownWidget->bottom - dropdownWidget->top + 1,
|
||||
w->colours[1],
|
||||
0x80,
|
||||
DROPDOWN_FLAG_STAY_OPEN,
|
||||
ride->var_0CC,
|
||||
widget->right - dropdownWidget->left
|
||||
);
|
||||
|
@ -2343,7 +2343,7 @@ static void window_ride_vehicle_mousedown(int widgetIndex, rct_window *w, rct_wi
|
|||
w->y + dropdownWidget->top,
|
||||
dropdownWidget->bottom - dropdownWidget->top + 1,
|
||||
w->colours[1],
|
||||
0x80,
|
||||
DROPDOWN_FLAG_STAY_OPEN,
|
||||
maxCars - minCars + 1,
|
||||
widget->right - dropdownWidget->left
|
||||
);
|
||||
|
@ -2759,7 +2759,7 @@ static void window_ride_mode_dropdown(rct_window *w, rct_widget *widget)
|
|||
w->y + dropdownWidget->top,
|
||||
dropdownWidget->bottom - dropdownWidget->top + 1,
|
||||
w->colours[1],
|
||||
0,
|
||||
DROPDOWN_FLAG_STAY_OPEN,
|
||||
numAvailableModes,
|
||||
widget->right - dropdownWidget->left
|
||||
);
|
||||
|
@ -2791,7 +2791,7 @@ static void window_ride_load_dropdown(rct_window *w, rct_widget *widget)
|
|||
w->y + dropdownWidget->top,
|
||||
dropdownWidget->bottom - dropdownWidget->top + 1,
|
||||
w->colours[1],
|
||||
0,
|
||||
DROPDOWN_FLAG_STAY_OPEN,
|
||||
5,
|
||||
widget->right - dropdownWidget->left
|
||||
);
|
||||
|
@ -3323,7 +3323,7 @@ static void window_ride_maintenance_mousedown(int widgetIndex, rct_window *w, rc
|
|||
w->y + dropdownWidget->top,
|
||||
dropdownWidget->bottom - dropdownWidget->top + 1,
|
||||
w->colours[1],
|
||||
0,
|
||||
DROPDOWN_FLAG_STAY_OPEN,
|
||||
7,
|
||||
widget->right - dropdownWidget->left
|
||||
);
|
||||
|
@ -3545,9 +3545,9 @@ static void window_ride_set_track_colour_scheme(rct_window *w, int x, int y)
|
|||
|
||||
newColourScheme = (uint8)(*((uint16*)&w->var_494));
|
||||
|
||||
int z;
|
||||
int interactionType;
|
||||
|
||||
get_map_coordinates_from_pos(x, y, -5, &x, &y, &z, &mapElement, NULL);
|
||||
get_map_coordinates_from_pos(x, y, VIEWPORT_INTERACTION_MASK_RIDE, &x, &y, &interactionType, &mapElement, NULL);
|
||||
// Get map coordinates from point
|
||||
/*int eax, ebx, ecx, edx, esi, edi, ebp;
|
||||
eax = x;
|
||||
|
@ -3558,7 +3558,7 @@ static void window_ride_set_track_colour_scheme(rct_window *w, int x, int y)
|
|||
y = ecx & 0xFFFF;
|
||||
mapElement = (rct_map_element*)edx;*/
|
||||
|
||||
if ((/*ebx*/z & 0xFF) != 3)
|
||||
if (interactionType != VIEWPORT_INTERACTION_ITEM_RIDE)
|
||||
return;
|
||||
if (mapElement->properties.track.ride_index != w->number)
|
||||
return;
|
||||
|
@ -3676,7 +3676,7 @@ static void window_ride_colour_mousedown(int widgetIndex, rct_window *w, rct_wid
|
|||
w->y + dropdownWidget->top,
|
||||
dropdownWidget->bottom - dropdownWidget->top + 1,
|
||||
w->colours[1],
|
||||
0,
|
||||
DROPDOWN_FLAG_STAY_OPEN,
|
||||
4,
|
||||
widget->right - dropdownWidget->left
|
||||
);
|
||||
|
@ -3703,7 +3703,7 @@ static void window_ride_colour_mousedown(int widgetIndex, rct_window *w, rct_wid
|
|||
w->y + dropdownWidget->top,
|
||||
dropdownWidget->bottom - dropdownWidget->top + 1,
|
||||
w->colours[1],
|
||||
0,
|
||||
DROPDOWN_FLAG_STAY_OPEN,
|
||||
4,
|
||||
widget->right - dropdownWidget->left
|
||||
);
|
||||
|
@ -3725,7 +3725,7 @@ static void window_ride_colour_mousedown(int widgetIndex, rct_window *w, rct_wid
|
|||
w->y + dropdownWidget->top,
|
||||
dropdownWidget->bottom - dropdownWidget->top + 1,
|
||||
w->colours[1],
|
||||
0x80,
|
||||
DROPDOWN_FLAG_STAY_OPEN,
|
||||
countof(window_ride_entrance_style_list),
|
||||
widget->right - dropdownWidget->left
|
||||
);
|
||||
|
@ -3743,7 +3743,7 @@ static void window_ride_colour_mousedown(int widgetIndex, rct_window *w, rct_wid
|
|||
w->y + dropdownWidget->top,
|
||||
dropdownWidget->bottom - dropdownWidget->top + 1,
|
||||
w->colours[1],
|
||||
0,
|
||||
DROPDOWN_FLAG_STAY_OPEN,
|
||||
rideEntry->max_cars_in_train > 1 ? 3 : 2,
|
||||
widget->right - dropdownWidget->left
|
||||
);
|
||||
|
@ -3766,7 +3766,7 @@ static void window_ride_colour_mousedown(int widgetIndex, rct_window *w, rct_wid
|
|||
w->y + dropdownWidget->top,
|
||||
dropdownWidget->bottom - dropdownWidget->top + 1,
|
||||
w->colours[1],
|
||||
0x80,
|
||||
DROPDOWN_FLAG_STAY_OPEN,
|
||||
numItems,
|
||||
widget->right - dropdownWidget->left
|
||||
);
|
||||
|
@ -3808,22 +3808,22 @@ static void window_ride_colour_dropdown()
|
|||
window_invalidate(w);
|
||||
break;
|
||||
case WIDX_TRACK_MAIN_COLOUR:
|
||||
game_do_command(0, (0 << 8) | 1, 0, (dropdownIndex << 8) | w->number, GAME_COMMAND_0, *((uint16*)&w->var_494), 0);
|
||||
game_do_command(0, (0 << 8) | 1, 0, (dropdownIndex << 8) | w->number, GAME_COMMAND_SET_RIDE_APPEARANCE, *((uint16*)&w->var_494), 0);
|
||||
break;
|
||||
case WIDX_TRACK_ADDITIONAL_COLOUR:
|
||||
game_do_command(0, (1 << 8) | 1, 0, (dropdownIndex << 8) | w->number, GAME_COMMAND_0, *((uint16*)&w->var_494), 0);
|
||||
game_do_command(0, (1 << 8) | 1, 0, (dropdownIndex << 8) | w->number, GAME_COMMAND_SET_RIDE_APPEARANCE, *((uint16*)&w->var_494), 0);
|
||||
break;
|
||||
case WIDX_TRACK_SUPPORT_COLOUR:
|
||||
game_do_command(0, (4 << 8) | 1, 0, (dropdownIndex << 8) | w->number, GAME_COMMAND_0, *((uint16*)&w->var_494), 0);
|
||||
game_do_command(0, (4 << 8) | 1, 0, (dropdownIndex << 8) | w->number, GAME_COMMAND_SET_RIDE_APPEARANCE, *((uint16*)&w->var_494), 0);
|
||||
break;
|
||||
case WIDX_MAZE_STYLE_DROPDOWN:
|
||||
game_do_command(0, (4 << 8) | 1, 0, (dropdownIndex << 8) | w->number, GAME_COMMAND_0, *((uint16*)&w->var_494), 0);
|
||||
game_do_command(0, (4 << 8) | 1, 0, (dropdownIndex << 8) | w->number, GAME_COMMAND_SET_RIDE_APPEARANCE, *((uint16*)&w->var_494), 0);
|
||||
break;
|
||||
case WIDX_ENTRANCE_STYLE_DROPDOWN:
|
||||
game_do_command(0, (6 << 8) | 1, 0, (window_ride_entrance_style_list[dropdownIndex] << 8) | w->number, GAME_COMMAND_0, 0, 0);
|
||||
game_do_command(0, (6 << 8) | 1, 0, (window_ride_entrance_style_list[dropdownIndex] << 8) | w->number, GAME_COMMAND_SET_RIDE_APPEARANCE, 0, 0);
|
||||
break;
|
||||
case WIDX_VEHICLE_COLOUR_SCHEME_DROPDOWN:
|
||||
game_do_command(0, (5 << 8) | 1, 0, (dropdownIndex << 8) | w->number, GAME_COMMAND_0, 0, 0);
|
||||
game_do_command(0, (5 << 8) | 1, 0, (dropdownIndex << 8) | w->number, GAME_COMMAND_SET_RIDE_APPEARANCE, 0, 0);
|
||||
w->var_48C = 0;
|
||||
break;
|
||||
case WIDX_VEHICLE_COLOUR_INDEX_DROPDOWN:
|
||||
|
@ -3831,13 +3831,13 @@ static void window_ride_colour_dropdown()
|
|||
window_invalidate(w);
|
||||
break;
|
||||
case WIDX_VEHICLE_MAIN_COLOUR:
|
||||
game_do_command(0, (2 << 8) | 1, 0, (dropdownIndex << 8) | w->number, GAME_COMMAND_0, w->var_48C, 0);
|
||||
game_do_command(0, (2 << 8) | 1, 0, (dropdownIndex << 8) | w->number, GAME_COMMAND_SET_RIDE_APPEARANCE, w->var_48C, 0);
|
||||
break;
|
||||
case WIDX_VEHICLE_ADDITIONAL_COLOUR_1:
|
||||
game_do_command(0, (3 << 8) | 1, 0, (dropdownIndex << 8) | w->number, GAME_COMMAND_0, w->var_48C, 0);
|
||||
game_do_command(0, (3 << 8) | 1, 0, (dropdownIndex << 8) | w->number, GAME_COMMAND_SET_RIDE_APPEARANCE, w->var_48C, 0);
|
||||
break;
|
||||
case WIDX_VEHICLE_ADDITIONAL_COLOUR_2:
|
||||
game_do_command(0, (7 << 8) | 1, 0, (dropdownIndex << 8) | w->number, GAME_COMMAND_0, w->var_48C, 0);
|
||||
game_do_command(0, (7 << 8) | 1, 0, (dropdownIndex << 8) | w->number, GAME_COMMAND_SET_RIDE_APPEARANCE, w->var_48C, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -4327,21 +4327,24 @@ static void window_ride_music_mousedown(int widgetIndex, rct_window *w, rct_widg
|
|||
window_ride_current_music_style_order[numItems++] = MUSIC_STYLE_CUSTOM_MUSIC_2;
|
||||
}
|
||||
|
||||
for (i = 0; i < numItems; i++) {
|
||||
gDropdownItemsFormat[i] = 1142;
|
||||
gDropdownItemsArgs[i] = STR_MUSIC_STYLE_START + window_ride_current_music_style_order[i];
|
||||
}
|
||||
|
||||
window_dropdown_show_text_custom_width(
|
||||
w->x + dropdownWidget->left,
|
||||
w->y + dropdownWidget->top,
|
||||
dropdownWidget->bottom - dropdownWidget->top + 1,
|
||||
w->colours[1],
|
||||
0,
|
||||
DROPDOWN_FLAG_STAY_OPEN,
|
||||
numItems,
|
||||
widget->right - dropdownWidget->left
|
||||
);
|
||||
|
||||
for (i = 0; i < numItems; i++) {
|
||||
gDropdownItemsFormat[i] = 1142;
|
||||
if (window_ride_current_music_style_order[i] == ride->music)
|
||||
gDropdownItemsChecked = (1 << i);
|
||||
gDropdownItemsArgs[i] = STR_MUSIC_STYLE_START + window_ride_current_music_style_order[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -169,7 +169,7 @@ rct_window *window_construction_open()
|
|||
window_push_others_right(w);
|
||||
show_gridlines();
|
||||
|
||||
RCT2_GLOBAL(0xF44070, uint32) = 0x80000000;
|
||||
RCT2_GLOBAL(0xF44070, uint32) = MONEY32_UNDEFINED;
|
||||
RCT2_GLOBAL(0xF440CD, uint8) = 8;
|
||||
RCT2_GLOBAL(0xF440CE, uint8) = 18;
|
||||
RCT2_GLOBAL(0xF440CF, uint8) = 4;
|
||||
|
@ -307,7 +307,7 @@ void window_construction_mouseup_demolish(rct_window* w){
|
|||
RCT2_CALLPROC_X(0x6C9BA5, 0, 0, 0, 0, (int)w, 0, 0);
|
||||
return;
|
||||
|
||||
RCT2_GLOBAL(0xF44070, uint32) = 0x80000000;
|
||||
RCT2_GLOBAL(0xF44070, uint32) = MONEY32_UNDEFINED;
|
||||
sub_6C9627();
|
||||
|
||||
RCT2_GLOBAL(0xF440B8, uint8) = 3;
|
||||
|
@ -440,7 +440,7 @@ void window_construction_paint()
|
|||
short string_y = RCT2_GLOBAL(0x9D7C08, int16_t) + w->y - 23;
|
||||
if (RCT2_GLOBAL(0xF440A6, uint8_t) != 4) gfx_draw_string_centred(dpi, 1407, string_x, string_y, 0, w);
|
||||
string_y += 11;
|
||||
if (RCT2_GLOBAL(0xF44070, uint32_t) != 0x80000000 && !(RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32_t) & 0x800))
|
||||
if (RCT2_GLOBAL(0xF44070, uint32_t) != MONEY32_UNDEFINED && !(RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32_t) & 0x800))
|
||||
gfx_draw_string_centred(dpi, 1408, string_x, string_y, 0, (void*)0xF44070);
|
||||
}
|
||||
|
||||
|
|
|
@ -253,7 +253,15 @@ static void window_ride_list_mousedown(int widgetIndex, rct_window*w, rct_widget
|
|||
gDropdownItemsFormat[i] = 1142;
|
||||
gDropdownItemsArgs[i] = STR_STATUS + i;
|
||||
}
|
||||
window_dropdown_show_text_custom_width(w->x + widget->left, w->y + widget->top, widget->bottom - widget->top, w->colours[1], 0x80, numItems, widget->right - widget->left - 3);
|
||||
window_dropdown_show_text_custom_width(
|
||||
w->x + widget->left,
|
||||
w->y + widget->top,
|
||||
widget->bottom - widget->top,
|
||||
w->colours[1],
|
||||
DROPDOWN_FLAG_STAY_OPEN,
|
||||
numItems,
|
||||
widget->right - widget->left - 3
|
||||
);
|
||||
gDropdownItemsChecked |= (1 << _window_ride_list_information_type);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -458,13 +458,13 @@ void window_scenery_open()
|
|||
window_scenery_update_scroll(window);
|
||||
show_gridlines();
|
||||
window_scenery_rotation = 3;
|
||||
RCT2_GLOBAL(0x00F64F12, uint8) = 0;
|
||||
RCT2_GLOBAL(0x00F64F13, uint8) = 0;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_SCENERY_TOOL_CTRL_PRESSED, uint8) = 0;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_SCENERY_TOOL_SHIFT_PRESSED, uint8) = 0;
|
||||
window->scenery.selected_scenery_id = -1;
|
||||
window->scenery.hover_counter = 0;
|
||||
window_push_others_below(window);
|
||||
RCT2_GLOBAL(0x00F64F0D, uint8) = 0;
|
||||
RCT2_GLOBAL(0x00F64EB4, uint32) = 0x80000000;
|
||||
RCT2_GLOBAL(0x00F64EB4, uint32) = MONEY32_UNDEFINED;
|
||||
RCT2_GLOBAL(0x00F64EC0, uint16) = 0;
|
||||
window_scenery_is_repaint_scenery_tool_on = 0; // repaint colored scenery tool state
|
||||
window_scenery_is_build_cluster_tool_on = 0; // build cluster tool state
|
||||
|
@ -503,9 +503,9 @@ void window_scenery_close() {
|
|||
|
||||
window_get_register(w);
|
||||
|
||||
RCT2_CALLPROC_EBPSAFE(0x006E2712);
|
||||
scenery_remove_ghost_tool_placement();
|
||||
hide_gridlines();
|
||||
RCT2_CALLPROC_X(0x006CB70A, 0, 0, 0, 0, 0, 0, 0);
|
||||
viewport_set_visibility(0);
|
||||
|
||||
if (window_scenery_is_scenery_tool_active())
|
||||
tool_cancel();
|
||||
|
@ -543,7 +543,7 @@ static void window_scenery_mouseup()
|
|||
case WIDX_SCENERY_ROTATE_OBJECTS_BUTTON:
|
||||
window_scenery_rotation++;
|
||||
window_scenery_rotation = window_scenery_rotation % 4;
|
||||
RCT2_CALLPROC_EBPSAFE(0x006E2712);
|
||||
scenery_remove_ghost_tool_placement();
|
||||
window_invalidate(w);
|
||||
break;
|
||||
case WIDX_SCENERY_REPAINT_SCENERY_BUTTON:
|
||||
|
@ -643,7 +643,7 @@ static void window_scenery_mousedown(int widgetIndex, rct_window* w, rct_widget*
|
|||
if (widgetIndex >= WIDX_SCENERY_TAB_1 && widgetIndex <= WIDX_SCENERY_TAB_20) {
|
||||
window_scenery_active_tab_index = widgetIndex - WIDX_SCENERY_TAB_1;
|
||||
window_invalidate(w);
|
||||
RCT2_GLOBAL(0x00F64EB4, uint32) = 0x80000000;
|
||||
RCT2_GLOBAL(0x00F64EB4, uint32) = MONEY32_UNDEFINED;
|
||||
window_scenery_update_scroll(w);
|
||||
}
|
||||
}
|
||||
|
@ -817,7 +817,7 @@ void window_scenery_scrollmousedown()
|
|||
window_scenery_is_repaint_scenery_tool_on &= 0xFE;
|
||||
sound_play_panned(4, (w->width >> 1) + w->x, 0, 0, 0);
|
||||
w->scenery.hover_counter = -16;
|
||||
RCT2_GLOBAL(0x00F64EB4, uint32) = 0x80000000;
|
||||
RCT2_GLOBAL(0x00F64EB4, uint32) = MONEY32_UNDEFINED;
|
||||
window_invalidate(w);
|
||||
}
|
||||
|
||||
|
@ -1057,7 +1057,7 @@ void window_scenery_paint()
|
|||
price = sceneryEntry->small_scenery.price * 10;
|
||||
}
|
||||
|
||||
if (w->scenery.selected_scenery_id == -1 && RCT2_GLOBAL(0x00F64EB4, uint32) != 0x80000000) {
|
||||
if (w->scenery.selected_scenery_id == -1 && RCT2_GLOBAL(0x00F64EB4, uint32) != MONEY32_UNDEFINED) {
|
||||
price = RCT2_GLOBAL(0x00F64EB4, uint32);
|
||||
}
|
||||
|
||||
|
|
|
@ -174,9 +174,7 @@ void window_sign_open(rct_windownumber number)
|
|||
|
||||
while (1){
|
||||
if (map_element_get_type(map_element) == MAP_ELEMENT_TYPE_SCENERY_MULTIPLE) {
|
||||
int ebx = map_element->properties.scenerymultiple.type;
|
||||
ebx |= (map_element->properties.scenerymultiple.index & 0x3) << 8;
|
||||
rct_scenery_entry* scenery_entry = g_largeSceneryEntries[ebx];
|
||||
rct_scenery_entry* scenery_entry = g_largeSceneryEntries[map_element->properties.scenerymultiple.type & MAP_ELEMENT_LARGE_TYPE_MASK];
|
||||
if (scenery_entry->large_scenery.var_11 != 0xFF){
|
||||
int id = (map_element->type & 0xC0) |
|
||||
((map_element->properties.scenerymultiple.colour[0] & 0xE0) >> 2) |
|
||||
|
@ -242,9 +240,7 @@ static void window_sign_mouseup()
|
|||
case WIDX_SIGN_DEMOLISH:
|
||||
while (1){
|
||||
if (map_element_get_type(map_element) == MAP_ELEMENT_TYPE_SCENERY_MULTIPLE) {
|
||||
int ebx = map_element->properties.scenerymultiple.type;
|
||||
ebx |= (map_element->properties.scenerymultiple.index & 0x3) << 8;
|
||||
rct_scenery_entry* scenery_entry = g_largeSceneryEntries[ebx];
|
||||
rct_scenery_entry* scenery_entry = g_largeSceneryEntries[map_element->properties.scenerymultiple.type & MAP_ELEMENT_LARGE_TYPE_MASK];
|
||||
if (scenery_entry->large_scenery.var_11 != 0xFF){
|
||||
int id = (map_element->type & 0xC0) |
|
||||
((map_element->properties.scenerymultiple.colour[0] & 0xE0) >> 2) |
|
||||
|
@ -259,8 +255,8 @@ static void window_sign_mouseup()
|
|||
x,
|
||||
1 | ((map_element->type&0x3) << 8),
|
||||
y,
|
||||
map_element->base_height | ((map_element->properties.scenerymultiple.index >> 2) << 8),
|
||||
GAME_COMMAND_44,
|
||||
map_element->base_height | ((map_element->properties.scenerymultiple.type >> 10) << 8),
|
||||
GAME_COMMAND_REMOVE_LARGE_SCENERY,
|
||||
0,
|
||||
0);
|
||||
break;
|
||||
|
@ -323,9 +319,7 @@ static void window_sign_dropdown()
|
|||
|
||||
while (1){
|
||||
if (map_element_get_type(map_element) == MAP_ELEMENT_TYPE_SCENERY_MULTIPLE) {
|
||||
int ebx = map_element->properties.scenerymultiple.type;
|
||||
ebx |= (map_element->properties.scenerymultiple.index & 0x3) << 8;
|
||||
rct_scenery_entry* scenery_entry = g_largeSceneryEntries[ebx];
|
||||
rct_scenery_entry* scenery_entry = g_largeSceneryEntries[map_element->properties.scenerymultiple.type & MAP_ELEMENT_LARGE_TYPE_MASK];
|
||||
if (scenery_entry->large_scenery.var_11 != 0xFF){
|
||||
int id = (map_element->type & 0xC0) |
|
||||
((map_element->properties.scenerymultiple.colour[0] & 0xE0) >> 2) |
|
||||
|
@ -337,7 +331,7 @@ static void window_sign_dropdown()
|
|||
map_element++;
|
||||
}
|
||||
|
||||
int edx = map_element->base_height | ((map_element->properties.scenerymultiple.index >> 2) << 8);
|
||||
int edx = map_element->base_height | ((map_element->properties.scenerymultiple.type >> 10) << 8);
|
||||
int ebp = w->list_information_type | (w->var_492 << 8);
|
||||
int ebx = (map_element->type & 0x3) << 8;
|
||||
RCT2_CALLPROC_X(0x6B9B05, x, ebx, y, edx, 0, w->number, ebp);
|
||||
|
@ -501,7 +495,7 @@ void window_sign_small_open(rct_windownumber number){
|
|||
|
||||
while (1){
|
||||
if (map_element_get_type(map_element) == MAP_ELEMENT_TYPE_FENCE) {
|
||||
rct_scenery_entry* scenery_entry = g_wallSceneryEntries[map_element->properties.fence.slope];
|
||||
rct_scenery_entry* scenery_entry = g_wallSceneryEntries[map_element->properties.fence.type];
|
||||
if (scenery_entry->wall.var_0D != 0xFF){
|
||||
if (map_element->properties.fence.item[0] == w->number)
|
||||
break;
|
||||
|
@ -515,7 +509,7 @@ void window_sign_small_open(rct_windownumber number){
|
|||
|
||||
w->list_information_type = map_element->properties.fence.item[1] & 0x1F;
|
||||
w->var_492 = (map_element->properties.fence.item[1] >> 5) | ((map_element->flags&0x60) >> 2);
|
||||
w->var_48C = map_element->properties.fence.slope;
|
||||
w->var_48C = map_element->properties.fence.type;
|
||||
|
||||
view_x += 16;
|
||||
view_y += 16;
|
||||
|
@ -564,7 +558,7 @@ static void window_sign_small_mouseup()
|
|||
case WIDX_SIGN_DEMOLISH:
|
||||
while (1){
|
||||
if (map_element_get_type(map_element) == MAP_ELEMENT_TYPE_FENCE) {
|
||||
rct_scenery_entry* scenery_entry = g_wallSceneryEntries[map_element->properties.fence.slope];
|
||||
rct_scenery_entry* scenery_entry = g_wallSceneryEntries[map_element->properties.fence.type];
|
||||
if (scenery_entry->wall.var_0D != 0xFF){
|
||||
if (map_element->properties.fence.item[0] == w->number)
|
||||
break;
|
||||
|
@ -626,7 +620,7 @@ static void window_sign_small_dropdown()
|
|||
|
||||
while (1){
|
||||
if (map_element_get_type(map_element) == MAP_ELEMENT_TYPE_FENCE) {
|
||||
rct_scenery_entry* scenery_entry = g_wallSceneryEntries[map_element->properties.fence.slope];
|
||||
rct_scenery_entry* scenery_entry = g_wallSceneryEntries[map_element->properties.fence.type];
|
||||
if (scenery_entry->wall.var_0D != 0xFF){
|
||||
if (map_element->properties.fence.item[0] == w->number)
|
||||
break;
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "../world/footpath.h"
|
||||
#include "../world/sprite.h"
|
||||
#include "../world/scenery.h"
|
||||
#include "../input.h"
|
||||
#include "dropdown.h"
|
||||
#include "error.h"
|
||||
|
||||
|
@ -375,7 +376,7 @@ void window_staff_overview_close()
|
|||
|
||||
window_get_register(w);
|
||||
|
||||
if (RCT2_GLOBAL(0x9DE518, uint32) & (1 << 3)){
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_TOOL_ACTIVE){
|
||||
if (w->classification == RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass) &&
|
||||
w->number == RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWNUMBER, rct_windownumber))
|
||||
tool_cancel();
|
||||
|
@ -388,7 +389,7 @@ void window_staff_overview_close()
|
|||
*/
|
||||
void window_staff_set_page(rct_window* w, int page)
|
||||
{
|
||||
if (RCT2_GLOBAL(0x9DE518,uint32) & (1 << 3))
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_INPUT_FLAGS, uint32) & INPUT_FLAG_TOOL_ACTIVE)
|
||||
{
|
||||
if(w->number == RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWNUMBER, rct_windownumber) &&
|
||||
w->classification == RCT2_GLOBAL(RCT2_ADDRESS_TOOL_WINDOWCLASS, rct_windowclass))
|
||||
|
@ -457,7 +458,7 @@ void window_staff_overview_mouseup()
|
|||
|
||||
w->var_48C = peep->x;
|
||||
|
||||
RCT2_CALLPROC_X(0x0069A512, 0, 0, 0, 0, (int)peep, 0, 0);
|
||||
remove_peep_from_ride(peep);
|
||||
invalidate_sprite((rct_sprite*)peep);
|
||||
|
||||
sprite_move( 0x8000, peep->y, peep->z, (rct_sprite*)peep);
|
||||
|
@ -573,19 +574,18 @@ void window_staff_overview_dropdown()
|
|||
|
||||
for (int i = 0; i < 128; i++)
|
||||
{
|
||||
RCT2_GLOBAL(0x13B0E72 + ebx + i * 4, uint32) = 0;
|
||||
RCT2_ADDRESS(0x13B0E72 + (peep->staff_id * 512), uint32)[i] = 0;
|
||||
}
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_STAFF_MODE_ARRAY + edi, uint16) &= 0xFD; // bug??
|
||||
RCT2_ADDRESS(RCT2_ADDRESS_STAFF_MODE_ARRAY, uint8)[peep->staff_id] &= ~2;
|
||||
|
||||
window_invalidate(w);
|
||||
//RCT2_CALLPROC_EBPSAFE(0x006C0C3F);
|
||||
sub_6C0C3F();
|
||||
gfx_invalidate_screen();
|
||||
staff_update_greyed_patrol_areas();
|
||||
}
|
||||
else {
|
||||
if (!tool_set(w, widgetIndex, 22)) {
|
||||
show_gridlines();
|
||||
RCT2_GLOBAL(0x009DEA50, sint16) = w->number;
|
||||
window_invalidate(w);
|
||||
gfx_invalidate_screen();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1085,9 +1085,9 @@ 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, NULL);
|
||||
if (z == 0)
|
||||
int interactionType;
|
||||
get_map_coordinates_from_pos(x, y, VIEWPORT_INTERACTION_MASK_NONE, NULL, NULL, &interactionType, NULL, NULL);
|
||||
if (interactionType == VIEWPORT_INTERACTION_ITEM_NONE)
|
||||
return;
|
||||
|
||||
x--;
|
||||
|
@ -1357,7 +1357,7 @@ void window_staff_options_mousedown(int widgetIndex, rct_window* w, rct_widget*
|
|||
int y = widget->top + w->y;
|
||||
int extray = widget->bottom - widget->top + 1;
|
||||
int width = widget->right - widget->left - 3;
|
||||
window_dropdown_show_text_custom_width(x, y, extray, w->colours[1], 0x80, no_entries, width);
|
||||
window_dropdown_show_text_custom_width(x, y, extray, w->colours[1], DROPDOWN_FLAG_STAY_OPEN, no_entries, width);
|
||||
|
||||
// See above note.
|
||||
gDropdownItemsChecked = item_checked;
|
||||
|
|
|
@ -130,7 +130,7 @@ static void window_title_menu_mousedown(int widgetIndex, rct_window*w, rct_widge
|
|||
w->y + widget->top,
|
||||
widget->bottom - widget->top + 1,
|
||||
w->colours[0] | 0x80,
|
||||
0x80,
|
||||
DROPDOWN_FLAG_STAY_OPEN,
|
||||
3
|
||||
);
|
||||
} else if (widgetIndex == WIDX_GAME_TOOLS) {
|
||||
|
@ -143,7 +143,7 @@ static void window_title_menu_mousedown(int widgetIndex, rct_window*w, rct_widge
|
|||
w->y + widget->top,
|
||||
widget->bottom - widget->top + 1,
|
||||
w->colours[0] | 0x80,
|
||||
0x80,
|
||||
DROPDOWN_FLAG_STAY_OPEN,
|
||||
4
|
||||
);
|
||||
}
|
||||
|
|
|
@ -116,7 +116,7 @@ void window_scenarioselect_open()
|
|||
334,
|
||||
(uint32*)window_scenarioselect_events,
|
||||
WC_SCENARIO_SELECT,
|
||||
WF_STICK_TO_FRONT | WF_10
|
||||
WF_10
|
||||
);
|
||||
window->widgets = window_scenarioselect_widgets;
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -300,75 +300,6 @@ static void window_track_place_draw_mini_preview()
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x0068A15E
|
||||
*/
|
||||
static void sub_68A15E(int screenX, int screenY, short *x, short *y, int *direction, rct_map_element **mapElement)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006D017F
|
||||
|
|
|
@ -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, NULL);
|
||||
get_map_coordinates_from_pos(w->x + (w->width / 2), w->y + (w->height / 2), VIEWPORT_INTERACTION_MASK_NONE, &x, &y, NULL, NULL, NULL);
|
||||
window_scroll_to_location(mainWindow, x, y, map_element_height(x, y));
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
*****************************************************************************/
|
||||
|
||||
#include "../addresses.h"
|
||||
#include "../game.h"
|
||||
#include "../localisation/localisation.h"
|
||||
#include "banner.h"
|
||||
|
||||
rct_banner *gBanners = (rct_banner*)0x0135A124;
|
||||
|
@ -32,3 +34,34 @@ void banner_init() {
|
|||
gBanners[i].type = BANNER_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* rct2: 0x006BA278
|
||||
* Creates a new banner and returns the index of the banner
|
||||
* If the flag GAME_COMMAND_FLAG_APPLY is NOT set then returns
|
||||
* the first unused index but does NOT mark the banner as created.
|
||||
* returns 0xFF on failure.
|
||||
*/
|
||||
int create_new_banner(uint8 flags){
|
||||
int banner_index = 0;
|
||||
for (; banner_index < MAX_BANNERS; banner_index++){
|
||||
if (gBanners[banner_index].type == BANNER_NULL){
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (banner_index == MAX_BANNERS){
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, rct_string_id) = STR_TOO_MANY_BANNERS_IN_GAME;
|
||||
return BANNER_NULL;
|
||||
}
|
||||
|
||||
if (flags & GAME_COMMAND_FLAG_APPLY){
|
||||
rct_banner* banner = &gBanners[banner_index];
|
||||
|
||||
banner->flags = 0;
|
||||
banner->type = 0;
|
||||
banner->string_idx = 778;
|
||||
banner->colour = 2;
|
||||
banner->text_colour = 2;
|
||||
}
|
||||
return banner_index;
|
||||
}
|
|
@ -44,5 +44,6 @@ enum{
|
|||
extern rct_banner *gBanners;
|
||||
|
||||
void banner_init();
|
||||
int create_new_banner(uint8 flags);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -191,8 +191,6 @@ void climate_update()
|
|||
}
|
||||
|
||||
void climate_force_weather(uint8 weather){
|
||||
gClimateNextWeather = 0;
|
||||
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_WEATHER, sint8) = weather;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_WEATHER_GLOOM, sint8) = climate_weather_data[weather].gloom_level;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_RAIN_LEVEL, sint8) = climate_weather_data[weather].rain_level;
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "../util/util.h"
|
||||
#include "footpath.h"
|
||||
#include "map.h"
|
||||
#include "scenery.h"
|
||||
|
||||
void sub_673883(int x, int y, int z);
|
||||
void sub_69A48B(int x, int y, int z);
|
||||
|
@ -201,8 +202,8 @@ static money32 footpath_element_update(int x, int y, rct_map_element *mapElement
|
|||
}
|
||||
|
||||
if (RCT2_GLOBAL(0x00F3EF88, uint16) != 0) {
|
||||
uint8 *unk = RCT2_ADDRESS(0x009ADA50, uint8*)[RCT2_GLOBAL(0x00F3EF88, uint16)];
|
||||
uint16 unk6 = RCT2_GLOBAL(unk + 6, uint16);
|
||||
rct_scenery_entry* scenery_entry = g_pathBitSceneryEntries[RCT2_GLOBAL(0x00F3EF88, uint16) - 1];
|
||||
uint16 unk6 = scenery_entry->path_bit.var_06;
|
||||
|
||||
if ((unk6 & 0x80) && (mapElement->properties.path.type & 4)) {
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, rct_string_id) = STR_CANT_BUILD_THIS_ON_SLOPED_FOOTPATH;
|
||||
|
@ -224,13 +225,13 @@ static money32 footpath_element_update(int x, int y, rct_map_element *mapElement
|
|||
return MONEY32_UNDEFINED;
|
||||
}
|
||||
|
||||
RCT2_GLOBAL(0x00F3EFD9, money32) += RCT2_GLOBAL(unk + 10, money16);
|
||||
RCT2_GLOBAL(0x00F3EFD9, money32) += scenery_entry->path_bit.price;
|
||||
}
|
||||
|
||||
if (flags & (1 << 4))
|
||||
return MONEY32_UNDEFINED;
|
||||
|
||||
if (!(flags & (1 << 6))) {
|
||||
if (flags & (1 << 6)) {
|
||||
if (mapElement->properties.path.additions & 0x0F) {
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, rct_string_id) = STR_NONE;
|
||||
return MONEY32_UNDEFINED;
|
||||
|
@ -259,8 +260,8 @@ static money32 footpath_element_update(int x, int y, rct_map_element *mapElement
|
|||
mapElement->properties.path.additions = (mapElement->properties.path.additions & 0xF0) | RCT2_GLOBAL(0x00F3EF88, uint8);
|
||||
mapElement->flags &= ~0x20;
|
||||
if (RCT2_GLOBAL(0x00F3EF88, uint16) != 0) {
|
||||
uint8 *unk = RCT2_ADDRESS(0x009ADA50, uint8*)[RCT2_GLOBAL(0x00F3EF88, uint16)];
|
||||
uint16 unk6 = RCT2_GLOBAL(unk + 6, uint16);
|
||||
rct_scenery_entry* scenery_entry = g_pathBitSceneryEntries[RCT2_GLOBAL(0x00F3EF88, uint16) - 1];
|
||||
uint16 unk6 = scenery_entry->path_bit.var_06;
|
||||
if (unk6 & 1)
|
||||
mapElement->properties.path.addition_status = 255;
|
||||
}
|
||||
|
@ -288,7 +289,7 @@ static money32 footpath_element_update(int x, int y, rct_map_element *mapElement
|
|||
return RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_NO_MONEY ? 0 : RCT2_GLOBAL(0x00F3EFD9, money32);
|
||||
}
|
||||
|
||||
static money32 footpath_place_real(int type, int x, int y, int z, int slope, int flags)
|
||||
static money32 footpath_place_real(int type, int x, int y, int z, int slope, int flags, uint8 path_bit_type)
|
||||
{
|
||||
rct_map_element *mapElement;
|
||||
|
||||
|
@ -307,7 +308,7 @@ static money32 footpath_place_real(int type, int x, int y, int z, int slope, int
|
|||
|
||||
RCT2_GLOBAL(0x00F3EFD9, money32) = 0;
|
||||
RCT2_GLOBAL(0x00F3EFA4, uint8) = 0;
|
||||
RCT2_GLOBAL(0x00F3EF88, uint16) = 0; // di
|
||||
RCT2_GLOBAL(0x00F3EF88, uint16) = path_bit_type; // di
|
||||
|
||||
if (x >= RCT2_GLOBAL(0x01358830, uint16) || y >= RCT2_GLOBAL(0x01358830, uint16)) {
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, rct_string_id) = STR_OFF_EDGE_OF_MAP;
|
||||
|
@ -344,7 +345,7 @@ void remove_banners_at_element(int x, int y, rct_map_element* mapElement){
|
|||
if (map_element_get_type(mapElement) == MAP_ELEMENT_TYPE_PATH)return;
|
||||
else if (map_element_get_type(mapElement) != MAP_ELEMENT_TYPE_BANNER)continue;
|
||||
|
||||
game_do_command(x, 1, y, mapElement->base_height | mapElement->properties.banner.position << 8, GAME_COMMAND_51, 0, 0);
|
||||
game_do_command(x, 1, y, mapElement->base_height | mapElement->properties.banner.position << 8, GAME_COMMAND_REMOVE_BANNER, 0, 0);
|
||||
mapElement--;
|
||||
}
|
||||
}
|
||||
|
@ -393,7 +394,7 @@ void game_command_place_footpath(int *eax, int *ebx, int *ecx, int *edx, int *es
|
|||
if (*ebx & (1 << 5))
|
||||
RCT2_CALLFUNC_X(0x006A61DE, eax, ebx, ecx, edx, esi, edi, ebp);
|
||||
else
|
||||
*ebx = footpath_place_real((*edx >> 8) & 0xFF, *eax & 0xFFFF, *ecx & 0xFFFF, *edx & 0xFF, (*ebx >> 8) & 0xFF, *ebx & 0xFF);
|
||||
*ebx = footpath_place_real((*edx >> 8) & 0xFF, *eax & 0xFFFF, *ecx & 0xFFFF, *edx & 0xFF, (*ebx >> 8) & 0xFF, *ebx & 0xFF, *edi & 0xFF);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -490,23 +491,22 @@ void footpath_provisional_update()
|
|||
*/
|
||||
void footpath_get_coordinates_from_pos(int screenX, int screenY, int *x, int *y, int *direction, rct_map_element **mapElement)
|
||||
{
|
||||
int z;
|
||||
int z, interactionType;
|
||||
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) {
|
||||
get_map_coordinates_from_pos(screenX, screenY, VIEWPORT_INTERACTION_MASK_FOOTPATH, x, y, &interactionType, &myMapElement, &viewport);
|
||||
if (interactionType != VIEWPORT_INTERACTION_ITEM_FOOTPATH || !(viewport->flags & (VIEWPORT_FLAG_UNDERGROUND_INSIDE | VIEWPORT_FLAG_HIDE_BASE | VIEWPORT_FLAG_HIDE_VERTICAL))) {
|
||||
get_map_coordinates_from_pos(screenX, screenY, VIEWPORT_INTERACTION_MASK_FOOTPATH & VIEWPORT_INTERACTION_MASK_TERRAIN, x, y, &interactionType, &myMapElement, &viewport);
|
||||
if (interactionType == VIEWPORT_INTERACTION_ITEM_NONE) {
|
||||
if (x != NULL) *x = 0x8000;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
RCT2_GLOBAL(0x00F1AD3E, uint8) = z;
|
||||
RCT2_GLOBAL(0x00F1AD3E, uint8) = interactionType;
|
||||
RCT2_GLOBAL(0x00F1AD30, rct_map_element*) = myMapElement;
|
||||
|
||||
if (z == 6) {
|
||||
// mapElement appears to be a footpath
|
||||
if (interactionType == VIEWPORT_INTERACTION_ITEM_FOOTPATH) {
|
||||
z = myMapElement->base_height * 8;
|
||||
if (myMapElement->properties.path.type & (1 << 2))
|
||||
z += 8;
|
||||
|
@ -572,10 +572,10 @@ void footpath_get_coordinates_from_pos(int screenX, int screenY, int *x, int *y,
|
|||
void footpath_bridge_get_info_from_pos(int screenX, int screenY, int *x, int *y, int *direction, rct_map_element **mapElement)
|
||||
{
|
||||
// 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;
|
||||
int interactionType;
|
||||
rct_viewport *viewport;
|
||||
get_map_coordinates_from_pos(screenX, screenY, 0xFFFB, x, y, &z, mapElement, &viewport);
|
||||
if (z == 3
|
||||
get_map_coordinates_from_pos(screenX, screenY, VIEWPORT_INTERACTION_MASK_RIDE, x, y, &interactionType, mapElement, &viewport);
|
||||
if (interactionType == VIEWPORT_INTERACTION_ITEM_RIDE
|
||||
&& viewport->flags & (VIEWPORT_FLAG_UNDERGROUND_INSIDE | VIEWPORT_FLAG_HIDE_BASE | VIEWPORT_FLAG_HIDE_VERTICAL)
|
||||
&& map_element_get_type(*mapElement) == MAP_ELEMENT_TYPE_ENTRANCE) {
|
||||
int ebp = (*mapElement)->properties.entrance.type << 4;
|
||||
|
@ -589,8 +589,8 @@ void footpath_bridge_get_info_from_pos(int screenX, int screenY, int *x, int *y,
|
|||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
get_map_coordinates_from_pos(screenX, screenY, VIEWPORT_INTERACTION_MASK_RIDE & VIEWPORT_INTERACTION_MASK_FOOTPATH & VIEWPORT_INTERACTION_MASK_TERRAIN, x, y, &interactionType, mapElement, &viewport);
|
||||
if (interactionType == VIEWPORT_INTERACTION_ITEM_RIDE && map_element_get_type(*mapElement) == MAP_ELEMENT_TYPE_ENTRANCE) {
|
||||
int ebp = (*mapElement)->properties.entrance.type << 4;
|
||||
int bl = (*mapElement)->properties.entrance.index & 0xF; // Seems to be always 0?
|
||||
// The table at 0x0097B974 is only 48 bytes big
|
||||
|
|
|
@ -48,5 +48,6 @@ void footpath_provisional_remove();
|
|||
void footpath_provisional_update();
|
||||
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);
|
||||
void sub_673883(int x, int y, int z);
|
||||
|
||||
#endif
|
||||
|
|
973
src/world/map.c
973
src/world/map.c
File diff suppressed because it is too large
Load Diff
|
@ -64,13 +64,12 @@ typedef struct {
|
|||
} rct_map_element_entrance_properties;
|
||||
|
||||
typedef struct {
|
||||
uint8 slope; //4
|
||||
uint8 type; //4
|
||||
uint8 item[3]; //5
|
||||
} rct_map_element_fence_properties;
|
||||
|
||||
typedef struct {
|
||||
uint8 type; //4
|
||||
uint8 index; //5
|
||||
uint16 type; //4
|
||||
uint8 colour[2]; //6
|
||||
} rct_map_element_scenerymultiple_properties;
|
||||
|
||||
|
@ -130,6 +129,7 @@ enum {
|
|||
};
|
||||
|
||||
enum {
|
||||
MAP_ELEMENT_FLAG_5 = (1 << 4),
|
||||
MAP_ELEMENT_FLAG_BROKEN = (1 << 5),
|
||||
MAP_ELEMENT_FLAG_LAST_TILE = (1 << 7)
|
||||
};
|
||||
|
@ -212,6 +212,8 @@ enum {
|
|||
#define MAX_MAP_ELEMENTS 196608
|
||||
#define MAX_TILE_MAP_ELEMENT_POINTERS (256 * 256)
|
||||
|
||||
#define MAP_ELEMENT_LARGE_TYPE_MASK 0x3FF
|
||||
|
||||
#define TILE_UNDEFINED_MAP_ELEMENT (rct_map_element*)-1
|
||||
|
||||
typedef struct {
|
||||
|
@ -271,9 +273,23 @@ int sub_68B044();
|
|||
rct_map_element *map_element_insert(int x, int y, int z, int flags);
|
||||
int map_can_construct_with_clear_at(int x, int y, int zLow, int zHigh, void *clearFunc, uint8 bl);
|
||||
int map_can_construct_at(int x, int y, int zLow, int zHigh, uint8 bl);
|
||||
int sub_6BA278(int ebx);
|
||||
|
||||
void game_command_remove_scenery(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp);
|
||||
void game_command_remove_large_scenery(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp);
|
||||
void game_command_remove_banner(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp);
|
||||
void game_command_set_scenery_colour(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp);
|
||||
void game_command_set_fence_colour(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp);
|
||||
void game_command_set_large_scenery_colour(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp);
|
||||
void game_command_set_banner_colour(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp);
|
||||
void game_command_clear_scenery(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp);
|
||||
void game_command_change_surface_style(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp);
|
||||
void game_command_raise_land(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp);
|
||||
void game_command_lower_land(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp);
|
||||
void game_command_raise_water(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp);
|
||||
void game_command_lower_water(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp);
|
||||
void game_command_remove_fence(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp);
|
||||
void game_command_place_banner(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp);
|
||||
|
||||
#define GET_MAP_ELEMENT(x) (&(RCT2_ADDRESS(RCT2_ADDRESS_MAP_ELEMENTS, rct_map_element)[x]))
|
||||
#define TILE_MAP_ELEMENT_POINTER(x) (RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[x])
|
||||
|
|
|
@ -48,7 +48,7 @@ void map_animation_create(int type, int x, int y, int z)
|
|||
{
|
||||
rct_map_animation *aobj = &gAnimatedObjects[0];
|
||||
int numAnimatedObjects = RCT2_GLOBAL(0x0138B580, uint16);
|
||||
for (; numAnimatedObjects > 0; aobj++) {
|
||||
for (int i = 0; i < numAnimatedObjects; i++, aobj++) {
|
||||
if (aobj->x != x)
|
||||
continue;
|
||||
if (aobj->y != y)
|
||||
|
|
|
@ -110,3 +110,89 @@ void scenery_increase_age(int x, int y, rct_map_element *mapElement)
|
|||
map_invalidate_tile(x, y, mapElement->base_height * 8, mapElement->clearance_height * 8);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* 0x006E2712 */
|
||||
void scenery_remove_ghost_tool_placement(){
|
||||
sint16 x, y, z;
|
||||
|
||||
x = RCT2_GLOBAL(0x00F64EC4, sint16);
|
||||
y = RCT2_GLOBAL(0x00F64EC6, sint16);
|
||||
z = RCT2_GLOBAL(0x00F64F09, uint8);
|
||||
|
||||
if (RCT2_GLOBAL(0x00F64F0D, uint8) & (1 << 0)){
|
||||
RCT2_GLOBAL(0x00F64F0D, uint8) &= ~(1 << 0);
|
||||
|
||||
game_do_command(
|
||||
x,
|
||||
105 | (RCT2_GLOBAL(0x00F64F0C, uint8) << 8),
|
||||
y,
|
||||
z | (RCT2_GLOBAL(0x00F64EDA, uint8) << 8),
|
||||
GAME_COMMAND_REMOVE_SCENERY,
|
||||
0,
|
||||
0);
|
||||
}
|
||||
|
||||
if (RCT2_GLOBAL(0x00F64F0D, uint8) & (1 << 1)){
|
||||
RCT2_GLOBAL(0x00F64F0D, uint8) &= ~(1 << 1);
|
||||
|
||||
rct_map_element* map_element = map_get_first_element_at(x / 32, y / 32);
|
||||
|
||||
do{
|
||||
if (map_element_get_type(map_element) != MAP_ELEMENT_TYPE_PATH)
|
||||
continue;
|
||||
|
||||
if (map_element->base_height != z)
|
||||
continue;
|
||||
|
||||
game_do_command(
|
||||
x,
|
||||
233 | (RCT2_GLOBAL(0x00F64F0F, uint8) << 8),
|
||||
y,
|
||||
z | (RCT2_GLOBAL(0x00F64F10, uint8) << 8),
|
||||
GAME_COMMAND_PLACE_PATH,
|
||||
RCT2_GLOBAL(0x00F64EAC, uint32) & 0xFFFF0000,
|
||||
0);
|
||||
break;
|
||||
} while (!map_element_is_last_for_tile(map_element++));
|
||||
}
|
||||
|
||||
if (RCT2_GLOBAL(0x00F64F0D, uint8) & (1 << 2)){
|
||||
RCT2_GLOBAL(0x00F64F0D, uint8) &= ~(1 << 2);
|
||||
|
||||
game_do_command(
|
||||
x,
|
||||
105 | (RCT2_GLOBAL(0x00F64F0C, uint8) << 8),
|
||||
y,
|
||||
RCT2_GLOBAL(0x00F64F11, uint8) |(z << 8),
|
||||
GAME_COMMAND_REMOVE_FENCE,
|
||||
0,
|
||||
0);
|
||||
}
|
||||
|
||||
if (RCT2_GLOBAL(0x00F64F0D, uint8) & (1 << 3)){
|
||||
RCT2_GLOBAL(0x00F64F0D, uint8) &= ~(1 << 3);
|
||||
|
||||
game_do_command(
|
||||
x,
|
||||
105 | (RCT2_GLOBAL(0x00F64EC0, uint8) << 8),
|
||||
y,
|
||||
z,
|
||||
GAME_COMMAND_REMOVE_LARGE_SCENERY,
|
||||
0,
|
||||
0);
|
||||
}
|
||||
|
||||
if (RCT2_GLOBAL(0x00F64F0D, uint8) & (1 << 4)){
|
||||
RCT2_GLOBAL(0x00F64F0D, uint8) &= ~(1 << 4);
|
||||
|
||||
game_do_command(
|
||||
x,
|
||||
105,
|
||||
y,
|
||||
z | (RCT2_GLOBAL(0x00F64EC0, uint8) << 8),
|
||||
GAME_COMMAND_REMOVE_BANNER,
|
||||
0,
|
||||
0);
|
||||
}
|
||||
}
|
|
@ -56,14 +56,27 @@ typedef enum {
|
|||
SMALL_SCENERY_FLAG18 = (1 << 17), // 0x20000
|
||||
SMALL_SCENERY_FLAG19 = (1 << 18), // 0x40000
|
||||
SMALL_SCENERY_FLAG_HAS_SECONDARY_COLOUR = (1 << 19), // 0x80000
|
||||
SMALL_SCENERY_FLAG20 = (1 << 20), // 0x100000
|
||||
SMALL_SCENERY_FLAG21 = (1 << 21), // 0x200000
|
||||
SMALL_SCENERY_FLAG22 = (1 << 22), // 0x400000
|
||||
SMALL_SCENERY_FLAG23 = (1 << 23), // 0x800000
|
||||
SMALL_SCENERY_FLAG24 = (1 << 24), // 0x1000000
|
||||
SMALL_SCENERY_FLAG25 = (1 << 25), // 0x2000000
|
||||
} SMALL_SCENERY_FLAGS;
|
||||
|
||||
typedef struct {
|
||||
sint16 x_offset;
|
||||
sint16 y_offset;
|
||||
sint16 z_offset;
|
||||
uint8 pad_6[3];
|
||||
} rct_large_scenery_tile;
|
||||
|
||||
typedef struct {
|
||||
uint8 tool_id; // 0x06
|
||||
uint8 flags; // 0x07
|
||||
sint16 price; // 0x08
|
||||
sint16 removal_price; // 0x0A
|
||||
uint32 var_0C;
|
||||
rct_large_scenery_tile* tiles; // 0x0C
|
||||
uint8 scenery_tab_id; // 0x10
|
||||
uint8 var_11;
|
||||
uint32 var_12;
|
||||
|
@ -141,6 +154,9 @@ enum {
|
|||
#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)
|
||||
#define g_bannerSceneryEntries ((rct_scenery_entry**)object_entry_groups[OBJECT_TYPE_BANNERS].chunks)
|
||||
|
||||
// Often 0x009ADA50 is used for pathBits this is 1 entry before g_pathBitSceneryEntries and is used
|
||||
// because 0 represents no path bits on a path. So remember to remove 1 when using it for 0x009ADA50
|
||||
#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)
|
||||
|
||||
|
@ -159,5 +175,6 @@ 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();
|
||||
void scenery_remove_ghost_tool_placement();
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue