@@ -26,8 +26,10 @@ long obstacle(uint8_t x, uint8_t y)
26
26
{
27
27
if (y >= CEILING_Y && y < CEILING_Y + 4 ) // ceiling
28
28
return 1l ;
29
+ // left door
29
30
else if (doors & 0b00000010 && (x < 4 || (y >= DOOR_Y && x < 6 )))
30
31
return 1l ;
32
+ // right door
31
33
else if (doors & 0b00000001 && (x >= DISPLAY_WIDTH - 4 || (y >= DOOR_Y && x >= DISPLAY_WIDTH - 6 )))
32
34
return 1l ;
33
35
else if (rechargeroom && x >= DISPLAY_WIDTH /2 - 12 && x < DISPLAY_WIDTH /2 + 12 && (y >= 23 * 4 || y < 17 * 4 ))
@@ -36,6 +38,7 @@ long obstacle(uint8_t x, uint8_t y)
36
38
return 1l ;
37
39
else if (rechargeroom && y <= CEILING_Y + 4 * 5 )
38
40
return 1l ;
41
+ // water/spikes
39
42
else if (y >= FLOOR_Y && y < FLOOR_Y + 4 )
40
43
return nofloor & (3l << x / 16 * 2 );
41
44
else if (y >= 19 * 4 && y < 20 * 4 )
@@ -46,7 +49,6 @@ long obstacle(uint8_t x, uint8_t y)
46
49
return !(platforms_24 & (3l << (x / 16 * 2 )));
47
50
else
48
51
return 0l ;
49
-
50
52
}
51
53
52
54
long obstacle_hill (uint8_t x )
@@ -62,13 +64,9 @@ long obstacle_levelpos(uint8_t x, uint8_t y, long level_pos)
62
64
long platforms_24 = random ();
63
65
platforms_24 |= 3l << 0 ; // no hill at the display boundary
64
66
platforms_24 |= 3l << 2 * (DISPLAY_WIDTH /16 - 1 );
65
- long nofloor = random ();
66
- //nofloor = INT32_MAX; // turn off water
67
-
67
+
68
68
if (y >= CEILING_Y && y < CEILING_Y + 4 ) // ceiling
69
69
return 1l ;
70
- else if (y >= FLOOR_Y && y < FLOOR_Y + 4 )
71
- return nofloor & (3l << x / 16 * 2 );
72
70
else if (y >= 19 * 4 && y < 20 * 4 )
73
71
return !(platforms_19 & (3l << (x / PLATFORM_WIDTH * 2 )));
74
72
else if (y >= 13 * 4 && y < 14 * 4 )
@@ -82,15 +80,15 @@ long obstacle_levelpos(uint8_t x, uint8_t y, long level_pos)
82
80
void redraw ()
83
81
{
84
82
clear ();
85
-
83
+
86
84
drawlabels ();
87
-
85
+
88
86
// print ceiling
89
87
for (uint8_t x = 0 ; x < DISPLAY_WIDTH ; x ++ )
90
88
{
91
89
page (x , 5 , pgm_read_byte_near (ceilingsprite + x % 16 ));
92
90
}
93
-
91
+
94
92
drawplatform ();
95
93
drawfloor ();
96
94
@@ -116,17 +114,18 @@ void redraw()
116
114
{
117
115
draw (energytankstruct );
118
116
}
119
-
117
+
120
118
if (rechargeroom )
121
119
{
122
120
drawrechargeroom ();
123
121
}
124
-
122
+
125
123
draw (protagonist );
126
124
}
127
125
128
126
void selectfloor ()
129
127
{
128
+ // random floor sprite
130
129
const uint8_t * rotatedfloorsprite = NULL ;
131
130
switch (random_below (7 ))
132
131
{
@@ -162,6 +161,8 @@ void selectfloor()
162
161
ceilingsprite = floorsprite ;
163
162
leftrotatedfloorsprite = rotatedfloorsprite ;
164
163
rightrotatedfloorsprite = rotatedfloorsprite ;
164
+
165
+ // select from water and spikes
165
166
switch (random_below (2 ))
166
167
{
167
168
case 0 :
@@ -181,7 +182,7 @@ void newlevelpos()
181
182
182
183
for (uint8_t i = 0 ; i < NUM_MONSTERS ; ++ i )
183
184
monsters [i ]-> look = LOOK_HIDDEN ;
184
-
185
+
185
186
if ((level >= 0 && level % BOSS_LEVEL_DISTANCE == BOSS_LEVEL_DISTANCE - 2 ) // recharge level
186
187
|| (level < 0 && (level - 1 ) % BOSS_LEVEL_DISTANCE == 0 ))
187
188
{
@@ -190,7 +191,7 @@ void newlevelpos()
190
191
platforms_24 = UINT32_MAX ;
191
192
nofloor = UINT32_MAX ;
192
193
doors = 0b00000011 ;
193
-
194
+
194
195
rechargeroom = true;
195
196
}
196
197
else if ((level >= 0 && level % BOSS_LEVEL_DISTANCE == BOSS_LEVEL_DISTANCE - 1 ) // boss level
@@ -205,9 +206,9 @@ void newlevelpos()
205
206
platforms_24 = UINT32_MAX ;
206
207
nofloor = UINT32_MAX ;
207
208
doors = 0b00000011 ;
208
-
209
+
209
210
bosslevel = true;
210
-
211
+
211
212
monsters [0 ]-> direction = 1 - protagonist -> direction ; // look at the protagonist
212
213
213
214
switch (random_below (4 ))
@@ -263,6 +264,7 @@ void newlevelpos()
263
264
platforms_24 |= 1l << 0 ; // no hill at the display boundary
264
265
platforms_24 |= 1l << 2 * (DISPLAY_WIDTH /16 - 1 );
265
266
267
+ // set nofloor to a new random value as long as the door is not reachable
266
268
do
267
269
{
268
270
nofloor = random ();
@@ -277,9 +279,9 @@ void newlevelpos()
277
279
}
278
280
}
279
281
while (!is_door_reachable ());
280
-
282
+
281
283
doors = 0 ;
282
-
284
+
283
285
// draw door to previous level
284
286
if (level_pos == 0 )
285
287
{
@@ -316,12 +318,13 @@ void newlevelpos()
316
318
}
317
319
}
318
320
321
+ // initialize monsters, their look, position etc.
319
322
for (uint8_t i = 0 ; i < NUM_MONSTERS ; ++ i )
320
323
{
321
324
initcharacter (monsters [i ]);
322
325
if (monsters [i ]-> look == LOOK_HIDDEN )
323
326
continue ;
324
-
327
+
325
328
monsters [i ]-> x = (DISPLAY_WIDTH - monsters [i ]-> width ) / 2 ;
326
329
if (monsters [i ]-> look == LOOK_BOSS_MEGACOREX || monsters [i ]-> look == LOOK_BOSS_SECROB || monsters [i ]-> look == LOOK_BOSS_ZAZABI || monsters [i ]-> look == LOOK_NEO_RIDLEY_DRAGON )
327
330
{
@@ -359,12 +362,12 @@ void newlevelpos()
359
362
}
360
363
}
361
364
}
362
-
365
+
363
366
for (uint8_t i = 0 ; i < NUM_FIREBALLS ; ++ i )
364
367
{
365
368
fireballs [i ]-> movement = HIDDEN ;
366
369
}
367
-
370
+
368
371
// no water/spikes when there is a frog/sidehopper
369
372
// these would otherwise fall into the void
370
373
for (uint8_t i = 0 ; i < NUM_MONSTERS ; ++ i )
@@ -404,16 +407,16 @@ void newlevelpos()
404
407
}
405
408
}
406
409
}
407
-
410
+
408
411
for (uint8_t i = 0 ; i < NUM_MONSTERS ; ++ i )
409
412
{
410
413
xparasites [i ]-> movement = HIDDEN ;
411
414
}
412
-
415
+
413
416
if (bosslevel )
414
417
{
418
+ // show a nice message informing about the boss's abilities
415
419
redraw ();
416
-
417
420
char line [2 ][MAX_STRING_LEN ];
418
421
switch (monsters [0 ]-> look )
419
422
{
@@ -451,10 +454,10 @@ void newlevelpos()
451
454
}
452
455
delay (1000 );
453
456
}
454
-
455
- redraw ();
457
+
456
458
left_door_open = false;
457
459
right_door_open = false;
460
+ redraw ();
458
461
}
459
462
460
463
void newlevel ()
@@ -464,14 +467,14 @@ void newlevel()
464
467
uart_putc ('i' );
465
468
else
466
469
uart_putc ('j' );
467
-
470
+
468
471
eeprom_write_block (& level , & level_stored , sizeof level );
469
-
472
+
470
473
level_seed = initial_level + level * (2 * MAX_LEVEL_WIDTH + 1 );
471
-
474
+
472
475
srand (level_seed );
473
476
srandom (level_seed );
474
-
477
+
475
478
max_level_pos = random_below (MAX_LEVEL_WIDTH );
476
479
477
480
if (protagonist -> x > DISPLAY_WIDTH / 2 )
@@ -488,9 +491,9 @@ void newlevel()
488
491
protagonist -> x = DISPLAY_WIDTH - 6 - protagonist -> width - 1 ;
489
492
protagonist -> direction = DIRECTION_LEFT ;
490
493
}
491
-
494
+
492
495
protagonist -> y = FLOOR_Y - protagonist -> height ;
493
-
496
+
494
497
selectfloor ();
495
498
496
499
newlevelpos ();
@@ -500,7 +503,7 @@ void newgame()
500
503
{
501
504
protagonist -> look = LOOK_PROTAGONIST ;
502
505
initcharacter (protagonist );
503
-
506
+
504
507
if (initial_level == 0 ) // start a new game
505
508
{
506
509
initial_level = getMsTimer ();
@@ -533,18 +536,18 @@ void newgame()
533
536
protagonist -> x = 0 ; // make the protagonist appear on the right
534
537
else
535
538
protagonist -> x = DISPLAY_WIDTH ; // make the protagonist appear on the left
536
-
539
+
537
540
for (uint8_t i = 0 ; i < NUM_ROCKETS ; ++ i )
538
541
{
539
542
projectiles [i ]-> look = LOOK_ROCKET ;
540
543
initcharacter (projectiles [i ]);
541
544
}
542
-
545
+
543
546
bombstruct -> look = LOOK_BOMB ;
544
547
initcharacter (bombstruct );
545
548
546
549
left_door_open = true;
547
550
right_door_open = true;
548
-
551
+
549
552
newlevel ();
550
553
}
0 commit comments