1 /*************************************************************************** 2 Attract Mode: Animated OutRun Logo Graphic 3 4 The logo is built from multiple sprite components. 5 6 Copyright Chris White. 7 See license.txt for more details. 8 ***************************************************************************/ 9 10 #include "stdint.hpp" 11 #include "engine/osprites.hpp" 12 #include "engine/outils.hpp" 13 #include "engine/ologo.hpp" 14 15 OLogo ologo; 16 17 const uint8_t OLogo::bg_pal[] = { 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9A, 0x9B, 0x9C }; 18 OLogo()19OLogo::OLogo() 20 { 21 } 22 ~OLogo()23OLogo::~OLogo() 24 { 25 } 26 enable(int16_t y)27void OLogo::enable(int16_t y) 28 { 29 y_off = -y; 30 31 entry_start = OSprites::SPRITE_ENTRIES - 0x10; 32 33 // Enable block of sprites 34 for (int i = entry_start; i < entry_start + 7; i++) 35 { 36 osprites.jump_table[i].init(i); 37 } 38 39 palm_frames[0] = outrun.adr.sprite_logo_palm1; 40 palm_frames[1] = outrun.adr.sprite_logo_palm2; 41 palm_frames[2] = outrun.adr.sprite_logo_palm3; 42 palm_frames[3] = outrun.adr.sprite_logo_palm2; 43 palm_frames[4] = outrun.adr.sprite_logo_palm1; 44 palm_frames[5] = outrun.adr.sprite_logo_palm2; 45 palm_frames[6] = outrun.adr.sprite_logo_palm3; 46 palm_frames[7] = outrun.adr.sprite_logo_palm2; 47 48 setup_sprite1(); 49 setup_sprite2(); 50 setup_sprite3(); 51 setup_sprite4(); 52 setup_sprite5(); 53 setup_sprite6(); 54 setup_sprite7(); 55 } 56 disable()57void OLogo::disable() 58 { 59 // Enable block of sprites 60 for (int i = entry_start; i < entry_start + 7; i++) 61 { 62 osprites.jump_table[i].control &= ~OSprites::ENABLE; 63 } 64 } 65 tick()66void OLogo::tick() 67 { 68 sprite_logo_bg(); 69 sprite_logo_car(); 70 sprite_logo_bird1(); 71 sprite_logo_bird2(); 72 sprite_logo_road(); 73 sprite_logo_palm(); 74 sprite_logo_text(); 75 } 76 77 // Animated Background Oval Sprite. setup_sprite1()78void OLogo::setup_sprite1() 79 { 80 oentry *e = &osprites.jump_table[entry_start + 0]; 81 e->x = 0; 82 e->y = 0x70 - y_off; 83 e->road_priority = 0xFF; 84 e->priority = 0x1FA; 85 e->zoom = 0x7F; 86 e->pal_src = 0x99; 87 e->addr = outrun.adr.sprite_logo_bg; 88 osprites.map_palette(e); 89 } 90 91 // Sprite Car Graphic setup_sprite2()92void OLogo::setup_sprite2() 93 { 94 oentry *e = &osprites.jump_table[entry_start + 1]; 95 e->x = -3; 96 e->y = 0x88 - y_off; 97 e->road_priority = 0x100; 98 e->priority = 0x1FB; 99 e->zoom = 0x7F; 100 e->pal_src = 0x6E; 101 e->addr = outrun.adr.sprite_logo_car; 102 osprites.map_palette(e); 103 } 104 105 // Sprite Flying Bird #1 setup_sprite3()106void OLogo::setup_sprite3() 107 { 108 oentry *e = &osprites.jump_table[entry_start + 2]; 109 e->x = 0x8; 110 e->y = 0x4E - y_off; 111 e->road_priority = 0x102; 112 e->priority = 0x1FD; 113 e->zoom = 0x7F; 114 e->counter = 0; 115 e->pal_src = 0x8B; 116 e->addr = outrun.adr.sprite_logo_bird1; 117 osprites.map_palette(e); 118 } 119 120 // Sprite Flying Bird #2 setup_sprite4()121void OLogo::setup_sprite4() 122 { 123 oentry *e = &osprites.jump_table[entry_start + 3]; 124 e->x = 0x8; 125 e->y = 0x4E - y_off; 126 e->road_priority = 0x102; 127 e->priority = 0x1FD; 128 e->zoom = 0x7F; 129 e->counter = 0x20; 130 e->pal_src = 0x8C; 131 e->addr = outrun.adr.sprite_logo_bird2; 132 osprites.map_palette(e); 133 } 134 135 // Sprite Road Base Section setup_sprite5()136void OLogo::setup_sprite5() 137 { 138 oentry *e = &osprites.jump_table[entry_start + 4]; 139 e->x = -0x20; 140 e->y = 0x8F - y_off; 141 e->road_priority = 0x101; 142 e->priority = 0x1FC; 143 e->zoom = 0x7F; 144 e->pal_src = 0x6E; 145 e->addr = outrun.adr.sprite_logo_base; 146 osprites.map_palette(e); 147 } 148 149 // Palm Tree setup_sprite6()150void OLogo::setup_sprite6() 151 { 152 oentry *e = &osprites.jump_table[entry_start + 5]; 153 e->x = -0x40; 154 e->y = 0x6D - y_off; 155 e->road_priority = 0x102; 156 e->priority = 0x1FD; 157 e->zoom = 0x7F; 158 e->pal_src = 0x65; 159 e->addr = outrun.adr.sprite_logo_palm1; 160 osprites.map_palette(e); 161 } 162 163 // OutRun logo text setup_sprite7()164void OLogo::setup_sprite7() 165 { 166 oentry *e = &osprites.jump_table[entry_start + 6]; 167 e->x = 0x11; 168 e->y = 0x65 - y_off; 169 e->road_priority = 0x103; 170 e->priority = 0x1FE; 171 e->zoom = 0x7F; 172 e->counter = 0; 173 e->pal_src = 0x65; 174 e->addr = outrun.adr.sprite_logo_text; 175 osprites.map_palette(e); 176 } 177 178 // Draw Background of OutRun logo in attract mode sprite_logo_bg()179void OLogo::sprite_logo_bg() 180 { 181 oentry *e = &osprites.jump_table[entry_start + 0]; 182 e->reload++; 183 uint16_t d0 = e->reload; 184 uint16_t d1 = d0 - 1; 185 d1 ^= d0; 186 187 // Map new palette 188 if (d1 & BIT_3) 189 { 190 e->pal_src = bg_pal[outils::random() & 7]; 191 osprites.map_palette(e); 192 } 193 194 osprites.do_spr_order_shadows(e); 195 } 196 sprite_logo_car()197void OLogo::sprite_logo_car() 198 { 199 oentry *e = &osprites.jump_table[entry_start + 1]; 200 // Flicker background palette of car 201 e->reload++; 202 e->pal_src = ((e->reload & 2) >> 1) ? 0x8A : 0x6E; 203 osprites.map_palette(e); 204 osprites.do_spr_order_shadows(e); 205 } 206 sprite_logo_bird1()207void OLogo::sprite_logo_bird1() 208 { 209 oentry *e = &osprites.jump_table[entry_start + 2]; 210 e->counter++; 211 212 // Set Bird X Value 213 uint16_t index = (e->counter << 1) & 0xFF; 214 int8_t bird_x = roms.rom0.read8(DATA_MOVEMENT + index); // Note we sign the value here 215 int8_t zoom = bird_x >> 3; 216 e->x = (bird_x >> 3) + 8; 217 218 // Set Zoom Lookup 219 e->zoom = zoom + 0x70; 220 221 // Set Bird Y Value 222 index = (index << 1) & 0xFF; 223 int8_t bird_y = roms.rom0.read8(DATA_MOVEMENT + index); // Note we sign the value here 224 e->y = (bird_y >> 5) + 0x4E - y_off; 225 226 // Set Frame 227 e->reload++; 228 uint16_t frame = (e->reload & 4) >> 2; 229 e->addr = frame ? outrun.adr.sprite_logo_bird2 : outrun.adr.sprite_logo_bird1; 230 osprites.do_spr_order_shadows(e); 231 } 232 sprite_logo_bird2()233void OLogo::sprite_logo_bird2() 234 { 235 oentry *e = &osprites.jump_table[entry_start + 3]; 236 e->counter++; 237 238 // Set Bird X Value 239 uint16_t index = (e->counter << 1) & 0xFF; 240 int8_t bird_x = roms.rom0.read8(DATA_MOVEMENT + index); // Note we sign the value here 241 int8_t zoom = bird_x >> 3; 242 e->x = (bird_x >> 3) - 2; // Different from sprite_logo_bird1 243 244 // Set Zoom Lookup 245 e->zoom = zoom + 0x70; 246 247 // Set Bird Y Value 248 index = (index << 1) & 0xFF; 249 int8_t bird_y = roms.rom0.read8(DATA_MOVEMENT + index); // Note we sign the value here 250 e->y = (bird_y >> 5) + 0x52 - y_off; // Different from sprite_logo_bird1 251 252 // Set Frame 253 e->reload++; 254 uint16_t frame = (e->reload & 4) >> 2; 255 e->addr = frame ? outrun.adr.sprite_logo_bird2 : outrun.adr.sprite_logo_bird1; 256 osprites.do_spr_order_shadows(e); 257 } 258 sprite_logo_road()259void OLogo::sprite_logo_road() 260 { 261 osprites.do_spr_order_shadows(&osprites.jump_table[entry_start + 4]); 262 } 263 sprite_logo_palm()264void OLogo::sprite_logo_palm() 265 { 266 oentry *e = &osprites.jump_table[entry_start + 5]; 267 e->reload++; // Increment frame number 268 e->addr = palm_frames[(e->reload & 0xE) >> 1]; 269 osprites.do_spr_order_shadows(e); 270 } 271 sprite_logo_text()272void OLogo::sprite_logo_text() 273 { 274 osprites.do_spr_order_shadows(&osprites.jump_table[entry_start + 6]); 275 } 276 277 // Blit Only: Used when frame skipping blit()278void OLogo::blit() 279 { 280 for (int i = 0; i < 7; i++) 281 osprites.do_spr_order_shadows(&osprites.jump_table[entry_start + i]); 282 } 283