From 6dabbaea610fac92ddba8c6f3e7a5d5e9cd494bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Sch=C3=BCtz?= Date: Wed, 27 Sep 2017 18:52:54 +0200 Subject: [PATCH] Add comments --- master/character.c | 16 +++---- master/drawing.c | 7 ++-- master/level.c | 73 ++++++++++++++++---------------- master/level.h | 4 +- master/main.c | 102 +++++++++++++++++++++++++++++---------------- slave/main.c | 9 ++-- 6 files changed, 121 insertions(+), 90 deletions(-) diff --git a/master/character.c b/master/character.c index e4ff7d4..9c0e723 100644 --- a/master/character.c +++ b/master/character.c @@ -633,20 +633,21 @@ void move(struct Character* character) character->jumpstate = 1; } if (protagonist->x < character->x) - moveleft(character); - else if (protagonist->x > character->x) - moveright(character); - else - draw(character); + moveleft(character); + else if (protagonist->x > character->x) + moveright(character); + else + draw(character); break; case BOMB: break; - case BOSS_DRAGON_AIR: if (character->y < CEILING_Y + 16 && (character->x < 20 || character->x > DISPLAY_WIDTH - character->width - 20) - && really_random_below(3) == 0) // 1/5 probability to attack + && really_random_below(3) == 0) // 1/3 probability to attack { + // move down towards the middle of the screen, + // then move up again while continuing in the previous horizontal direction character->movement = BOSS_DRAGON_ATTACK; if (character->x > DISPLAY_WIDTH / 2) character->direction = DIRECTION_LEFT; @@ -675,7 +676,6 @@ void move(struct Character* character) break; case XPARASITE: break; - case SECROB: if (character->x >= DISPLAY_WIDTH - character->width - 8) { diff --git a/master/drawing.c b/master/drawing.c index c620e31..d1b4dd9 100644 --- a/master/drawing.c +++ b/master/drawing.c @@ -198,7 +198,6 @@ void movedoorleft() page(x + 33, 24, 0xFF); } } - } void movedoorright() @@ -243,7 +242,7 @@ void drawdoorright_closed() i = 0; } } - + drawsprite(154, 20, 6, 5, doorright); } @@ -260,7 +259,7 @@ void drawdoorleft_closed() i = 0; } } - + drawsprite(0, 20, 6, 5, doorleft); } @@ -594,5 +593,5 @@ void drawletters(uint8_t x, uint8_t y, char* string) x += width + 1; } } -} +} diff --git a/master/level.c b/master/level.c index 1506b07..4ccf982 100644 --- a/master/level.c +++ b/master/level.c @@ -26,8 +26,10 @@ long obstacle(uint8_t x, uint8_t y) { if (y >= CEILING_Y && y < CEILING_Y + 4) // ceiling return 1l; + // left door else if (doors & 0b00000010 && (x < 4 || (y >= DOOR_Y && x < 6))) return 1l; + // right door else if (doors & 0b00000001 && (x >= DISPLAY_WIDTH - 4 || (y >= DOOR_Y && x >= DISPLAY_WIDTH - 6))) return 1l; 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) return 1l; else if (rechargeroom && y <= CEILING_Y + 4*5) return 1l; + // water/spikes else if (y >= FLOOR_Y && y < FLOOR_Y + 4) return nofloor & (3l << x / 16 * 2); else if (y >= 19 * 4 && y < 20 * 4) @@ -46,7 +49,6 @@ long obstacle(uint8_t x, uint8_t y) return !(platforms_24 & (3l << (x / 16 * 2))); else return 0l; - } long obstacle_hill(uint8_t x) @@ -62,13 +64,9 @@ long obstacle_levelpos(uint8_t x, uint8_t y, long level_pos) long platforms_24 = random(); platforms_24 |= 3l << 0; // no hill at the display boundary platforms_24 |= 3l << 2 * (DISPLAY_WIDTH/16 - 1); - long nofloor = random(); - //nofloor = INT32_MAX; // turn off water - + if (y >= CEILING_Y && y < CEILING_Y + 4) // ceiling return 1l; - else if (y >= FLOOR_Y && y < FLOOR_Y + 4) - return nofloor & (3l << x / 16 * 2); else if (y >= 19 * 4 && y < 20 * 4) return !(platforms_19 & (3l << (x / PLATFORM_WIDTH * 2))); else if (y >= 13 * 4 && y < 14 * 4) @@ -82,15 +80,15 @@ long obstacle_levelpos(uint8_t x, uint8_t y, long level_pos) void redraw() { clear(); - + drawlabels(); - + // print ceiling for (uint8_t x = 0; x < DISPLAY_WIDTH; x++) { page(x, 5, pgm_read_byte_near(ceilingsprite + x % 16)); } - + drawplatform(); drawfloor(); @@ -116,17 +114,18 @@ void redraw() { draw(energytankstruct); } - + if (rechargeroom) { drawrechargeroom(); } - + draw(protagonist); } void selectfloor() { + // random floor sprite const uint8_t* rotatedfloorsprite = NULL; switch (random_below(7)) { @@ -162,6 +161,8 @@ void selectfloor() ceilingsprite = floorsprite; leftrotatedfloorsprite = rotatedfloorsprite; rightrotatedfloorsprite = rotatedfloorsprite; + + // select from water and spikes switch (random_below(2)) { case 0: @@ -181,7 +182,7 @@ void newlevelpos() for (uint8_t i = 0; i < NUM_MONSTERS; ++i) monsters[i]->look = LOOK_HIDDEN; - + if ((level >= 0 && level % BOSS_LEVEL_DISTANCE == BOSS_LEVEL_DISTANCE - 2) // recharge level || (level < 0 && (level - 1) % BOSS_LEVEL_DISTANCE == 0)) { @@ -190,7 +191,7 @@ void newlevelpos() platforms_24 = UINT32_MAX; nofloor = UINT32_MAX; doors = 0b00000011; - + rechargeroom = true; } else if ((level >= 0 && level % BOSS_LEVEL_DISTANCE == BOSS_LEVEL_DISTANCE - 1) // boss level @@ -205,9 +206,9 @@ void newlevelpos() platforms_24 = UINT32_MAX; nofloor = UINT32_MAX; doors = 0b00000011; - + bosslevel = true; - + monsters[0]->direction = 1 - protagonist->direction; // look at the protagonist switch(random_below(4)) @@ -263,6 +264,7 @@ void newlevelpos() platforms_24 |= 1l << 0; // no hill at the display boundary platforms_24 |= 1l << 2 * (DISPLAY_WIDTH/16 - 1); + // set nofloor to a new random value as long as the door is not reachable do { nofloor = random(); @@ -277,9 +279,9 @@ void newlevelpos() } } while (!is_door_reachable()); - + doors = 0; - + // draw door to previous level if (level_pos == 0) { @@ -316,12 +318,13 @@ void newlevelpos() } } + // initialize monsters, their look, position etc. for (uint8_t i = 0; i < NUM_MONSTERS; ++i) { initcharacter(monsters[i]); if (monsters[i]->look == LOOK_HIDDEN) continue; - + monsters[i]->x = (DISPLAY_WIDTH - monsters[i]->width) / 2; 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) { @@ -359,12 +362,12 @@ void newlevelpos() } } } - + for (uint8_t i = 0; i < NUM_FIREBALLS; ++i) { fireballs[i]->movement = HIDDEN; } - + // no water/spikes when there is a frog/sidehopper // these would otherwise fall into the void for (uint8_t i = 0; i < NUM_MONSTERS; ++i) @@ -404,16 +407,16 @@ void newlevelpos() } } } - + for (uint8_t i = 0; i < NUM_MONSTERS; ++i) { xparasites[i]->movement = HIDDEN; } - + if (bosslevel) { + // show a nice message informing about the boss's abilities redraw(); - char line[2][MAX_STRING_LEN]; switch (monsters[0]->look) { @@ -451,10 +454,10 @@ void newlevelpos() } delay(1000); } - - redraw(); + left_door_open = false; right_door_open = false; + redraw(); } void newlevel() @@ -464,14 +467,14 @@ void newlevel() uart_putc('i'); else uart_putc('j'); - + eeprom_write_block(&level, &level_stored, sizeof level); - + level_seed = initial_level + level * (2 * MAX_LEVEL_WIDTH + 1); - + srand(level_seed); srandom(level_seed); - + max_level_pos = random_below(MAX_LEVEL_WIDTH); if (protagonist->x > DISPLAY_WIDTH / 2) @@ -488,9 +491,9 @@ void newlevel() protagonist->x = DISPLAY_WIDTH - 6 - protagonist->width - 1; protagonist->direction = DIRECTION_LEFT; } - + protagonist->y = FLOOR_Y - protagonist->height; - + selectfloor(); newlevelpos(); @@ -500,7 +503,7 @@ void newgame() { protagonist->look = LOOK_PROTAGONIST; initcharacter(protagonist); - + if (initial_level == 0) // start a new game { initial_level = getMsTimer(); @@ -533,18 +536,18 @@ void newgame() protagonist->x = 0; // make the protagonist appear on the right else protagonist->x = DISPLAY_WIDTH; // make the protagonist appear on the left - + for (uint8_t i = 0; i < NUM_ROCKETS; ++i) { projectiles[i]->look = LOOK_ROCKET; initcharacter(projectiles[i]); } - + bombstruct->look = LOOK_BOMB; initcharacter(bombstruct); left_door_open = true; right_door_open = true; - + newlevel(); } diff --git a/master/level.h b/master/level.h index a3ba3da..098888d 100644 --- a/master/level.h +++ b/master/level.h @@ -71,11 +71,13 @@ bool rechargeroom; bool recharging; bool bosslevel; +// whether there is an obstacle at x, y at the current level_pos long obstacle(uint8_t x, uint8_t y); -// whether there is a platform at 96<=y<100 +// whether there is a platform at 96 <= y < 100 long obstacle_hill(uint8_t x); +// whether there is an obstacle at x, y at level_pos long obstacle_levelpos(uint8_t x, uint8_t y, long level_pos); void redraw(); diff --git a/master/main.c b/master/main.c index a3032d1..998a1cf 100644 --- a/master/main.c +++ b/master/main.c @@ -33,14 +33,13 @@ uint32_t nextfireballjumpevent[NUM_FIREBALLS]; uint32_t nextfireevent = 0; uint32_t nextrechargeevent = 0; - void init(); void takingdamage(uint8_t damage) { uint32_t blink_for = 650; protagonist->health = protagonist->health - damage; - if(protagonist->health > 0) + if (protagonist->health > 0) { eeprom_write_byte(&health_stored, protagonist->health); drawnumber(29, 1, protagonist->health); @@ -53,7 +52,7 @@ void takingdamage(uint8_t damage) blink_for = 2000; } uint32_t blinking_time = getMsTimer(); - while(blinking_time + blink_for >= getMsTimer()) + while (blinking_time + blink_for >= getMsTimer()) { // make protagonist and energy level blink (latter only if energy <= 0) hide(protagonist); @@ -86,13 +85,11 @@ void takingdamage(uint8_t damage) else if ((x == 28 || x == 131) && (y >= 17 && y < 21)) { page (x, y, 0xFF); - - } else { page(x, y, 0); - + if (y == 20 && x == DISPLAY_WIDTH - 1) { drawletters(40, 18, "PRESS A TO RESTART"); @@ -102,7 +99,6 @@ void takingdamage(uint8_t damage) { drawcolor(28, 21, 104, 1, 0b00000011); } - } delay(30); } @@ -158,7 +154,6 @@ void getAchievement() } delay(2000); redraw(); - } bool open_door_projectile(struct Character* projectile) @@ -275,8 +270,8 @@ void monstertakedamage(uint8_t i, uint8_t damage) // i is the index of the monst int main(void) { - init(); - + init(); + // show splash screen until button A is pressed initial_level = eeprom_read_dword(&initial_level_stored); drawsplash(initial_level != 0); @@ -285,6 +280,8 @@ int main(void) if (B_A) { initial_level = 0; // start a new game + + // show a little manual clear(); drawsprite(20, 5, 8, 3, Abutton); drawletters(30, 5, "SHOOT A ROCKET"); @@ -303,8 +300,7 @@ int main(void) break; } } - - + struct Character protagonist_; protagonist = &protagonist_; @@ -314,7 +310,7 @@ int main(void) nextmonsterjumpevent[i] = 0; monsters[i] = &monsters_[i]; } - + for (uint8_t i = 0; i < NUM_ROCKETS; ++i) { nextprojectilevent[i]=0; @@ -328,25 +324,22 @@ int main(void) { xparasites[i] = &xparasites_[i]; } - + for (uint8_t i = 0; i < NUM_FIREBALLS; ++i) { nextfireballmoveevent[i] = 0; nextfireballjumpevent[i] = 0; fireballs[i] = &fireballs_[i]; } - + struct Character bomb_; bombstruct = &bomb_; - - left_door_open = true; - right_door_open = true; - + newgame(); - + while (1) { - //monster in Bewegung + // monster movement for (uint8_t i = 0; i < NUM_MONSTERS; ++i) { if(monsters[i]->movement != HIDDEN && nextmonstermoveevent[i] < getMsTimer()) @@ -360,8 +353,9 @@ int main(void) nextmonsterjumpevent[i] = getMsTimer() + monsters[i]->y_pace; } } + // end monster movement - //Protagonist kann sich bewegen + // protagonist movement if (nextmoveevent < getMsTimer()) { if (B_RIGHT) @@ -492,6 +486,7 @@ int main(void) { protagonist->jumpstate = 1; } + // end protagonist movement // change level when protagonist touches the door if (doors & 0b00000001 @@ -533,9 +528,10 @@ int main(void) } } - //PROJECTILE + // projectile for (uint8_t i = 0; i < NUM_ROCKETS; ++i) - { + { + // shoot a rocket if (projectiles[i]->movement == HIDDEN && num_rockets > 0 && nextshootevent < getMsTimer() @@ -614,6 +610,8 @@ int main(void) } } } + + // projecctile movement else if (projectiles[i]->movement != HIDDEN && nextprojectilevent[i] < getMsTimer()) { @@ -622,6 +620,7 @@ int main(void) nextprojectilevent[i] = getMsTimer() + 35; } + // projectile collision with monsters for (uint8_t j = 0; j < NUM_MONSTERS; ++j) { if (projectiles[i]->movement != HIDDEN && monsters[j]->movement != HIDDEN && collision(projectiles[i], monsters[j])) @@ -631,11 +630,12 @@ int main(void) } } } - //PROJECTILE END + // end projectile - //BOMB + // bomb if (nextbombevent < getMsTimer()) { + // bomb falls down if (bombstruct->movement != HIDDEN) { jump(bombstruct); @@ -657,6 +657,7 @@ int main(void) } nextbombevent = getMsTimer() + 20; } + // lay a bomb else if (B_B && num_bombs > 0) { bombstruct->x = protagonist->x; @@ -670,6 +671,7 @@ int main(void) nextbombevent = getMsTimer() + 100; } } + // bomb explosion if (bombstruct->movement != HIDDEN) { if (explode < getMsTimer()) @@ -760,9 +762,10 @@ int main(void) draw(bombstruct); } } - //BOMB END + // end bomb - if (protagonist->y > DISPLAY_HEIGHT - protagonist->height) //PROTAGONIST fell into water/spikes + // check if protagonist fell into water/spikes + if (protagonist->y > DISPLAY_HEIGHT - protagonist->height) { hide(protagonist); drawfloor(); @@ -794,17 +797,19 @@ int main(void) for (uint8_t i = 0; i < NUM_MONSTERS; ++i) { - if (monsters[i]->movement != HIDDEN && monsters[i]->y > DISPLAY_HEIGHT - monsters[i]->height) //MONSTER fell into water/spikes + // check if monster fell into water/spikes + if (monsters[i]->movement != HIDDEN && monsters[i]->y > DISPLAY_HEIGHT - monsters[i]->height) { hide(monsters[i]); drawfloor(); } - //KNOCKBACK after collision + // collision between protagonist and monster if (monsters[i]->movement != HIDDEN && collision(protagonist, monsters[i])) { // if the monster is right of the protagonist if (monsters[i]->x + monsters[i]->width/2 >= protagonist->x + protagonist->width) { + // knockback to the left uint8_t j = 0; while (protagonist->x + protagonist->width + DIST_AFTER_DAMAGE > monsters[i]->x) { @@ -818,14 +823,18 @@ int main(void) draw(monsters[i]); delay(50); } + // if the protagonist can't move far enough because of an obstacle, + // the monster is moved to the right instead while (protagonist->x + protagonist->width + DIST_AFTER_DAMAGE > monsters[i]->x) { if (!moveright(monsters[i])) break; } } + // if the monster is left of the protagonist else { + // knockback to the right uint8_t j = 0; while (monsters[i]->x + monsters[i]->width + DIST_AFTER_DAMAGE > protagonist->x) { @@ -839,6 +848,8 @@ int main(void) draw(monsters[i]); delay(50); } + // if the protagonist can't move far enough because of an obstacle, + // the monster is moved to the left instead while (monsters[i]->x + monsters[i]->width + DIST_AFTER_DAMAGE > protagonist->x) { if (!moveleft(monsters[i])) @@ -851,6 +862,7 @@ int main(void) for (uint8_t i = 0; i < NUM_MONSTERS; ++i) { + // collision between protagonist and xparasite if (xparasites[i]->movement != HIDDEN && collision(protagonist, xparasites[i])) { hide(xparasites[i]); @@ -875,8 +887,10 @@ int main(void) } } + // energy tank if(energytankstruct->movement != HIDDEN) { + // the energy tank cannot be overridden by monster sprites draw(energytankstruct); } if(energytankstruct->movement != HIDDEN && collision(protagonist, energytankstruct)) @@ -893,8 +907,13 @@ int main(void) drawnumber(29, 1, protagonist->health); } } - else if (monsters[0]->look == LOOK_NEO_RIDLEY_DRAGON) + // end energy tank + + // special things for bosses + // Neo Ridley shoots fireballs + if (monsters[0]->look == LOOK_NEO_RIDLEY_DRAGON) { + // at most 3 fireballs at a time for (uint8_t i = 0; i < 3; ++i) { if (fireballs[i]->movement == HIDDEN && monsters[0]->movement != HIDDEN && monsters[0]->movement != BOSS_DRAGON_ATTACK && nextfireevent < getMsTimer()) @@ -938,11 +957,15 @@ int main(void) } } } + // Secrob shoots arrows else if (monsters[0]->look == LOOK_BOSS_SECROB) { - if (really_random_below(1000) == 0 && monsters[0]->jumpstate == ON_THE_GROUND && monsters[0]->x > 6 + fireballs[0]->width && monsters[0]->x < DISPLAY_WIDTH - 6 - monsters[0]->width - fireballs[0]->width) + if (really_random_below(1000) == 0 && + monsters[0]->jumpstate == ON_THE_GROUND && + monsters[0]->x > 6 + fireballs[0]->width && + monsters[0]->x < DISPLAY_WIDTH - 6 - monsters[0]->width - fireballs[0]->width) { - if(fireballs[0]->movement == HIDDEN && fireballs[1]->movement == HIDDEN && + if (fireballs[0]->movement == HIDDEN && fireballs[1]->movement == HIDDEN && fireballs[2]->movement == HIDDEN && fireballs[3]->movement == HIDDEN) { fireballs[0]->y = fireballs[2]->y = monsters[0]->y + 4; @@ -972,6 +995,9 @@ int main(void) nextmonstermoveevent[0] = nextmonsterjumpevent[0] = getMsTimer() + 1500; } } + // end special things for bosses + + // fireballs for (uint8_t i = 0; i < NUM_FIREBALLS; ++i) { if (fireballs[i]->movement != HIDDEN && nextfireballmoveevent[i] < getMsTimer()) @@ -998,7 +1024,9 @@ int main(void) } } } - + // end fireballs + + // recharge room if (rechargeroom && protagonist->x + protagonist->width < DISPLAY_WIDTH/2 + 12 && protagonist->x > DISPLAY_WIDTH/2 - 11 @@ -1037,9 +1065,10 @@ int main(void) } nextrechargeevent = getMsTimer() + 100; } + // end recharge room - //PAUSE SCREEN - if(B_PAUSE) + // pause screen + if (B_PAUSE) { pauseTimer = 1; while (B_PAUSE); // wait until button is released @@ -1050,6 +1079,7 @@ int main(void) redraw(); pauseTimer = 0; } + // end pause screen } } diff --git a/slave/main.c b/slave/main.c index 3ab118b..50a4731 100644 --- a/slave/main.c +++ b/slave/main.c @@ -176,17 +176,14 @@ int main() { for (uint8_t i = 0; i < EFFECT; ++i) { - //tmp += state[i] >> 8; // saw - tmp += ((state[i] >> 8) & 0x80) << 1; // square - /*if (state[i] < 0x8000) // triangle - tmp += state[i] >> 7; - else - tmp += (0xFFFF - (state[i] & 0x7FFF << 1)) >> 8;*/ + // square wave + tmp += ((state[i] >> 8) & 0x80) << 1; state[i] += increment[i]; } } // >> 7 to make fx louder + // saw wave tmp += state[EFFECT] >> 7; state[EFFECT] += increment[EFFECT];