1 /***************************************************************************
2     Core Game Engine Routines.
3 
4     - The main loop which advances the level onto the next segment.
5     - Code to directly control the road hardware. For example, the road
6       split and bonus points routines.
7     - Code to determine whether to initialize certain game modes
8       (Crash state, Bonus points, road split state)
9 
10     Copyright Chris White.
11     See license.txt for more details.
12 ***************************************************************************/
13 
14 #pragma once
15 
16 #include "outrun.hpp"
17 
18 class OInitEngine
19 {
20 public:
21     // Debug: Camera X Offset
22     int16_t camera_x_off;
23 
24     // Is the in-game engine active?
25     bool ingame_engine;
26 
27     // Time to wait before enabling ingame_engine after crash
28     int16_t ingame_counter;
29 
30     // Road Split State
31     // 0 = No Road Split
32     // 1 = Init Road Split
33     // 2 = Road Split
34     // 3 = Beginning of split. User must choose.
35     // 4 = Road physically splits into two individual roads
36     // 5 = Road fully split. Init remove other road
37     // 6 = Road split. Only one road drawn.
38     // 7 = Unknown
39     // 8 = Init Road Merge before checkpoint sign
40     // 9 = Road Merge before checkpoint sign
41     // A = Unknown
42     // B = Checkpoint sign
43     // C = Unused
44     // D = Unused
45     // E = Unused
46     // F = Unused
47     // 10 = Init Bonus Points Sequence
48     // 11 = Bonus Points Sequence
49     uint16_t rd_split_state;
50     enum {SPLIT_NONE, SPLIT_INIT, SPLIT_CHOICE1, SPLIT_CHOICE2};
51 
52     // Upcoming Road Type:
53     // 0 = No change
54     // 1 = Straight road
55     // 2 = Right Bend
56     // 3 = Left Bend
57     int16_t road_type;
58     int16_t road_type_next;
59     enum {ROAD_NOCHANGE, ROAD_STRAIGHT, ROAD_RIGHT, ROAD_LEFT};
60 
61     // End Of Stage Properties
62     //
63     // Bit 0: Fade Sky & Ground Palette To New Entry
64     // Bit 1: Use Current Palette (Don't Bump To Next One)
65     // Bit 2: Use Current Sky Palette For Fade (Don't Bump To Next One)
66     // Bit 3: Loop back to stage 1
67     uint8_t end_stage_props;
68 
69     uint32_t car_increment; // NEEDS REPLACING. Implementing here as a quick hack so routine works
70 
71     // Car X Position
72     // 0000 = Centre of two road generators
73     //
74     // Turning Right REDUCES value, Turning Left INCREASES value
75     //
76     // 0xxx [pos] = Road Generator 1 Position (0 - xxx from centre)
77     // Fxxx [neg] = Road Generator 2 Position (0 + xxx from centre)
78     int16_t car_x_pos;
79     int16_t car_x_old;
80 
81     // Checkpoint Marker
82 
83     // 0  = Checkpoint Not Past
84     // -1 = Checkpoint Past
85     int8_t checkpoint_marker;
86 
87     // Something to do with the increment / curve of the road
88     int16_t road_curve;
89     int16_t road_curve_next;
90 
91     // Road split logic handling to remove split
92     // 0 = Normal Road Rendering
93     // 1 = Road Has Split, Old Road now removed
94     int8_t road_remove_split;
95 
96     // Route Selected
97     // -1 = Left
98     // 0  = Right
99     // But confusingly, these values get swapped by a not instruction
100     int8_t route_selected;
101 
102     // Road Width Change
103     // 0 = No
104     // -1 = In Progress
105     int16_t change_width;
106 
107 	OInitEngine();
108 	~OInitEngine();
109 	void init(int8_t debug_level);
110 
111     void init_road_seg_master();
112     void init_crash_bonus();
113     void update_road();
114     void update_engine();
115     void update_shadow_offset();
116     void set_granular_position();
117     void set_fine_position();
118 
119     void init_bonus(int16_t); // moved here for debugging purposes
120 
121 private:
122     // Road width at merge point
123     const static uint16_t RD_WIDTH_MERGE = 0xD4;
124 
125     // Road width of next section
126     int16_t road_width_next;
127 
128     // Speed at which adjustment to road section occurs
129     int16_t road_width_adj;
130 
131     int16_t granular_rem;
132 
133     uint16_t pos_fine_old;
134 
135     // Road Original Width. Used when adjustments are being made during road split, and end sequence initialisation
136     int16_t road_width_orig;
137 
138     // Used by road merge logic, to control width of road
139     int16_t road_width_merge;
140 
141     // ------------------------------------------------------------------------
142     // Route Information
143     // ------------------------------------------------------------------------
144 
145     // Used as part of road split code.
146     // 0 = Route Info Not Updated
147     // 1 = Route Info Updated
148     int8_t route_updated;
149 
150     void setup_stage1();
151     void check_road_split();
152     void check_stage();
153     void init_split1();
154     void init_split2();
155     void init_split3();
156     void init_split4();
157     void init_split5();
158     void init_split6();
159     void init_split7();
160     void init_split9();
161     void init_split10();
162     void bonus1();
163     void bonus2();
164     void bonus3();
165     void bonus4();
166     void bonus5();
167     void bonus6();
168     void reload_stage1();
169     void init_split_next_level();
170     void test_bonus_mode(bool);
171 };
172 
173 extern OInitEngine oinitengine;