/* * Entity action / stop counting * * ASM 2143 */ void e_sbonus_stop(U8 e) { ent_ents[e].sprite = 0; /* invisible */ if (!e_sbonus_counting) return; if (u_trigbox(e, ENT_XRICK.x + 0x0C, ENT_XRICK.y + 0x0A)) { /* rick is within trigger box */ e_sbonus_counting = FALSE; /* stop counting */ ent_ents[e].n = 0; /* deactivate entity */ game_score += e_sbonus_bonus; /* add bonus to score */ #ifdef ENABLE_SOUND syssnd_play(WAV_SBONUS2, 1); #endif /* make sure the entity won't be activated again */ map_marks[ent_ents[e].mark].ent |= MAP_MARK_NACT; } else { /* keep counting */ if (--e_sbonus_counter == 0) { e_sbonus_counter = 0x1e; if (e_sbonus_bonus) e_sbonus_bonus--; } } }
/* * Entity action * * ASM 242C */ void e_bonus_action(U8 e) { #define seq c1 if (ent_ents[e].seq == 0) { if (e_rick_boxtest(e)) { game_score += 500; #ifdef ENABLE_SOUND syssnd_play(WAV_BONUS, 1); #endif map_marks[ent_ents[e].mark].ent |= MAP_MARK_NACT; ent_ents[e].seq = 1; ent_ents[e].sprite = 0xad; ent_ents[e].front = TRUE; ent_ents[e].y -= 0x08; } } else if (ent_ents[e].seq > 0 && ent_ents[e].seq < 10) { ent_ents[e].seq++; ent_ents[e].y -= 2; } else { ent_ents[e].n = 0; } }
/* * Music */ void game_setmusic(char *name, U8 loop) { if (music_snd) game_stopmusic(); music_snd = syssnd_load(name); if (music_snd) { music_snd->dispose = TRUE; /* music is always "fire and forget" */ syssnd_play(music_snd, loop); } }
/* * Entity action / start counting * * ASM 2182 */ void e_sbonus_start(U8 e) { ent_ents[e].sprite = 0; /* invisible */ if (u_trigbox(e, ENT_XRICK.x + 0x0C, ENT_XRICK.y + 0x0A)) { /* rick is within trigger box */ ent_ents[e].n = 0; e_sbonus_counting = TRUE; /* 6DD5 */ e_sbonus_counter = 0x1e; /* 6DDB */ e_sbonus_bonus = 2000; /* 291A-291D */ #ifdef ENABLE_SOUND syssnd_play(WAV_SBONUS1, 1); #endif } }
/* * Initialize bullet */ void e_bullet_init(U16 x, U16 y) { E_BULLET_ENT.n = 0x02; E_BULLET_ENT.x = x; E_BULLET_ENT.y = y + 0x0006; if (game_dir == LEFT) { e_bullet_offsx = -0x08; E_BULLET_ENT.sprite = 0x21; } else { e_bullet_offsx = 0x08; E_BULLET_ENT.sprite = 0x20; } #ifdef ENABLE_SOUND syssnd_play(WAV_BULLET, 1); #endif }
/* * Go zombie * * ASM 1851 */ void e_rick_gozombie(void) { #ifdef ENABLE_CHEATS if (game_cheat2) return; #endif /* already zombie? */ if E_RICK_STTST(E_RICK_STZOMBIE) return; #ifdef ENABLE_SOUND syssnd_play(WAV_DIE, 1); #endif E_RICK_STSET(E_RICK_STZOMBIE); offsy = -0x0400; offsx = (E_RICK_ENT.x > 0x80 ? -3 : +3); ylow = 0; E_RICK_ENT.front = TRUE; }
/* * Action function for e_rick * * ASM 12CA */ void e_rick_action(UNUSED(U8 e)) { static U8 stopped = FALSE; /* is this the most elegant way? */ e_rick_action2(); scrawl = E_RICK_STTST(E_RICK_STCRAWL); if E_RICK_STTST(E_RICK_STZOMBIE) return; /* * set sprite */ if E_RICK_STTST(E_RICK_STSTOP) { E_RICK_ENT.sprite = (game_dir ? 0x17 : 0x0B); #ifdef ENABLE_SOUND if (!stopped) { syssnd_play(WAV_STICK, 1); stopped = TRUE; } #endif return; } stopped = FALSE; if E_RICK_STTST(E_RICK_STSHOOT) { E_RICK_ENT.sprite = (game_dir ? 0x16 : 0x0A); return; } if E_RICK_STTST(E_RICK_STCLIMB) { E_RICK_ENT.sprite = (((E_RICK_ENT.x ^ E_RICK_ENT.y) & 0x04) ? 0x18 : 0x0c); #ifdef ENABLE_SOUND seq = (seq + 1) & 0x03; if (seq == 0) syssnd_play(WAV_WALK, 1); #endif return; } if E_RICK_STTST(E_RICK_STCRAWL) { E_RICK_ENT.sprite = (game_dir ? 0x13 : 0x07); if (E_RICK_ENT.x & 0x04) E_RICK_ENT.sprite++; #ifdef ENABLE_SOUND seq = (seq + 1) & 0x03; if (seq == 0) syssnd_play(WAV_CRAWL, 1); #endif return; } if E_RICK_STTST(E_RICK_STJUMP) { E_RICK_ENT.sprite = (game_dir ? 0x15 : 0x06); return; } seq++; if (seq >= 0x14) { #ifdef ENABLE_SOUND syssnd_play(WAV_WALK, 1); #endif seq = 0x04; } #ifdef ENABLE_SOUND else if (seq == 0x0C) syssnd_play(WAV_WALK, 1); #endif E_RICK_ENT.sprite = (seq >> 2) + 1 + (game_dir ? 0x0c : 0x00); }
/* * Action sub-function for e_rick. * * ASM 13BE */ void e_rick_action2(void) { U8 env0, env1; S16 x, y; U32 i; E_RICK_STRST(E_RICK_STSTOP|E_RICK_STSHOOT); /* if zombie, run dedicated function and return */ if E_RICK_STTST(E_RICK_STZOMBIE) { e_rick_z_action(); return; } /* climbing? */ if E_RICK_STTST(E_RICK_STCLIMB) goto climbing; /* * NOT CLIMBING */ E_RICK_STRST(E_RICK_STJUMP); /* calc y */ i = (E_RICK_ENT.y << 8) + offsy + ylow; y = i >> 8; /* test environment */ u_envtest(E_RICK_ENT.x, y, E_RICK_STTST(E_RICK_STCRAWL), &env0, &env1); /* stand up, if possible */ if (E_RICK_STTST(E_RICK_STCRAWL) && !env0) E_RICK_STRST(E_RICK_STCRAWL); /* can move vertically? */ if (env1 & (offsy < 0 ? MAP_EFLG_VERT|MAP_EFLG_SOLID|MAP_EFLG_SPAD : MAP_EFLG_VERT|MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_WAYUP)) goto vert_not; /* * VERTICAL MOVE */ E_RICK_STSET(E_RICK_STJUMP); /* killed? */ if (env1 & MAP_EFLG_LETHAL) { e_rick_gozombie(); return; } /* save */ E_RICK_ENT.y = y; ylow = i; /* climb? */ if ((env1 & MAP_EFLG_CLIMB) && (control_status & (CONTROL_UP|CONTROL_DOWN))) { offsy = 0x0100; E_RICK_STSET(E_RICK_STCLIMB); return; } /* fall */ offsy += 0x0080; if (offsy > 0x0800) { offsy = 0x0800; ylow = 0; } /* * HORIZONTAL MOVE */ horiz: /* should move? */ if (!(control_status & (CONTROL_LEFT|CONTROL_RIGHT))) { seq = 2; /* no: reset seq and return */ return; } if (control_status & CONTROL_LEFT) { /* move left */ x = E_RICK_ENT.x - 2; game_dir = LEFT; if (x < 0) { /* prev submap */ game_chsm = TRUE; E_RICK_ENT.x = 0xe2; return; } } else { /* move right */ x = E_RICK_ENT.x + 2; game_dir = RIGHT; if (x >= 0xe8) { /* next submap */ game_chsm = TRUE; E_RICK_ENT.x = 0x04; return; } } /* still within this map: test environment */ u_envtest(x, E_RICK_ENT.y, E_RICK_STTST(E_RICK_STCRAWL), &env0, &env1); /* save x-position if it is possible to move */ if (!(env1 & (MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_WAYUP))) { E_RICK_ENT.x = x; if (env1 & MAP_EFLG_LETHAL) e_rick_gozombie(); } /* end */ return; /* * NO VERTICAL MOVE */ vert_not: if (offsy < 0) { /* not climbing + trying to go _up_ not possible -> hit the roof */ E_RICK_STSET(E_RICK_STJUMP); /* fall back to the ground */ E_RICK_ENT.y &= 0xF8; offsy = 0; ylow = 0; goto horiz; } /* else: not climbing + trying to go _down_ not possible -> standing */ /* align to ground */ E_RICK_ENT.y &= 0xF8; E_RICK_ENT.y |= 0x03; ylow = 0; /* standing on a super pad? */ if ((env1 & MAP_EFLG_SPAD) && offsy >= 0X0200) { offsy = (control_status & CONTROL_UP) ? 0xf800 : 0x00fe - offsy; #ifdef ENABLE_SOUND syssnd_play(WAV_PAD, 1); #endif goto horiz; } offsy = 0x0100; /* reset*/ /* standing. firing ? */ if (scrawl || !(control_status & CONTROL_FIRE)) goto firing_not; /* * FIRING */ if (control_status & (CONTROL_LEFT|CONTROL_RIGHT)) { /* stop */ if (control_status & CONTROL_RIGHT) { game_dir = RIGHT; e_rick_stop_x = E_RICK_ENT.x + 0x17; } else { game_dir = LEFT; e_rick_stop_x = E_RICK_ENT.x; } e_rick_stop_y = E_RICK_ENT.y + 0x000E; E_RICK_STSET(E_RICK_STSTOP); return; } if (control_status == (CONTROL_FIRE|CONTROL_UP)) { /* bullet */ E_RICK_STSET(E_RICK_STSHOOT); /* not an automatic gun: shoot once only */ if (trigger) return; else trigger = TRUE; /* already a bullet in the air ... that's enough */ if (E_BULLET_ENT.n) return; /* else use a bullet, if any available */ if (!game_bullets) return; #ifdef ENABLE_CHEATS if (!game_cheat1) game_bullets--; #endif /* initialize bullet */ e_bullet_init(E_RICK_ENT.x, E_RICK_ENT.y); return; } trigger = FALSE; /* not shooting means trigger is released */ seq = 0; /* reset */ if (control_status == (CONTROL_FIRE|CONTROL_DOWN)) { /* bomb */ /* already a bomb ticking ... that's enough */ if (E_BOMB_ENT.n) return; /* else use a bomb, if any available */ if (!game_bombs) return; #ifdef ENABLE_CHEATS if (!game_cheat1) game_bombs--; #endif /* initialize bomb */ e_bomb_init(E_RICK_ENT.x, E_RICK_ENT.y); return; } return; /* * NOT FIRING */ firing_not: if (control_status & CONTROL_UP) { /* jump or climb */ if (env1 & MAP_EFLG_CLIMB) { /* climb */ E_RICK_STSET(E_RICK_STCLIMB); return; } offsy = -0x0580; /* jump */ ylow = 0; #ifdef ENABLE_SOUND syssnd_play(WAV_JUMP, 1); #endif goto horiz; } if (control_status & CONTROL_DOWN) { /* crawl or climb */ if ((env1 & MAP_EFLG_VERT) && /* can go down */ !(control_status & (CONTROL_LEFT|CONTROL_RIGHT)) && /* + not moving horizontaly */ (E_RICK_ENT.x & 0x1f) < 0x0a) { /* + aligned -> climb */ E_RICK_ENT.x &= 0xf0; E_RICK_ENT.x |= 0x04; E_RICK_STSET(E_RICK_STCLIMB); } else { /* crawl */ E_RICK_STSET(E_RICK_STCRAWL); goto horiz; } } goto horiz; /* * CLIMBING */ climbing: /* should move? */ if (!(control_status & (CONTROL_UP|CONTROL_DOWN|CONTROL_LEFT|CONTROL_RIGHT))) { seq = 0; /* no: reset seq and return */ return; } if (control_status & (CONTROL_UP|CONTROL_DOWN)) { /* up-down: calc new y and test environment */ y = E_RICK_ENT.y + ((control_status & CONTROL_UP) ? -0x02 : 0x02); u_envtest(E_RICK_ENT.x, y, E_RICK_STTST(E_RICK_STCRAWL), &env0, &env1); if (env1 & (MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_WAYUP) && !(control_status & CONTROL_UP)) { /* FIXME what? */ E_RICK_STRST(E_RICK_STCLIMB); return; } if (!(env1 & (MAP_EFLG_SOLID|MAP_EFLG_SPAD|MAP_EFLG_WAYUP)) || (env1 & MAP_EFLG_WAYUP)) { /* ok to move, save */ E_RICK_ENT.y = y; if (env1 & MAP_EFLG_LETHAL) { e_rick_gozombie(); return; } if (!(env1 & (MAP_EFLG_VERT|MAP_EFLG_CLIMB))) { /* reached end of climb zone */ offsy = (control_status & CONTROL_UP) ? -0x0300 : 0x0100; #ifdef ENABLE_SOUND if (control_status & CONTROL_UP) syssnd_play(WAV_JUMP, 1); #endif E_RICK_STRST(E_RICK_STCLIMB); return; } } } if (control_status & (CONTROL_LEFT|CONTROL_RIGHT)) { /* left-right: calc new x and test environment */ if (control_status & CONTROL_LEFT) { x = E_RICK_ENT.x - 0x02; if (x < 0) { /* (i.e. negative) prev submap */ game_chsm = TRUE; /*6dbd = 0x00;*/ E_RICK_ENT.x = 0xe2; return; } } else { x = E_RICK_ENT.x + 0x02; if (x >= 0xe8) { /* next submap */ game_chsm = TRUE; /*6dbd = 0x01;*/ E_RICK_ENT.x = 0x04; return; } } u_envtest(x, E_RICK_ENT.y, E_RICK_STTST(E_RICK_STCRAWL), &env0, &env1); if (env1 & (MAP_EFLG_SOLID|MAP_EFLG_SPAD)) return; E_RICK_ENT.x = x; if (env1 & MAP_EFLG_LETHAL) { e_rick_gozombie(); return; } if (env1 & (MAP_EFLG_VERT|MAP_EFLG_CLIMB)) return; E_RICK_STRST(E_RICK_STCLIMB); if (control_status & CONTROL_UP) offsy = -0x0300; } }
/* * Main introduction * * return: SCREEN_RUNNING, SCREEN_DONE, SCREEN_EXIT */ U8 screen_introMain(void) { static U8 seq = 0; static U8 seen = 0; static U8 first = TRUE; static U8 period = 0; static U32 tm = 0; U8 i, s[32]; //char tutu[50]; //sprintf(tutu,"seen %d ctrl=%d seq=%d, %d %d ",seen,control_status,seq, 0 , SCREEN_TIMEOUT); //slPrint(tutu,slLocate(2,14)); //slPrintHex(control_status,slLocate(1,2)); if (seq == 0) { draw_tilesBank = 0; if (first == TRUE) seq = 1; else seq = 4; period = game_period; game_period = 50; game_rects = &draw_SCREENRECT; #ifdef ENABLE_SOUND game_setmusic("sounds/tune5.wav", -1); #endif } syssnd_play(music_snd, 1); //sprintf(tutu,"seen %d ctrl=%d seq=%d, %d %d ",seen,control_status,seq, 0 , SCREEN_TIMEOUT); //slPrint(tutu,slLocate(2,15)); switch (seq) { case 1: /* dispay hall of fame */ sysvid_clear(); tm = sys_gettime(); #ifdef GFXPC /* Rick Dangerous title */ draw_tllst = (U8 *)screen_imainrdt; draw_setfb(32, 16); draw_filter = 0xaaaa; draw_tilesList(); /* Core Design copyright + press space to start */ draw_tllst = (U8 *)screen_imaincdc; draw_setfb(64, 80); draw_filter = 0x5555; draw_tilesList(); #endif #ifdef GFXST draw_pic(0, 0, 0x140, 0xc8, pic_splash); #endif seq = 2; break; case 2: /* wait for key pressed or timeout */ if (control_status & CONTROL_FIRE) { //slPrint("2 key pressed",slLocate(3,3)); seq = 3; } else if (sys_gettime() - tm > SCREEN_TIMEOUT) { seen++; //while(1); seq = 4; //control_status =0; } //char fff2[50]; //sprintf ( fff2,"2 not press %d %d", control_status, CONTROL_FIRE); //slPrint(fff2,slLocate(3,3)); break; case 3: /* wait for key released */ if (!(control_status & CONTROL_FIRE)) { if (seen++ == 0) seq = 4; else seq = 7; //while(1); } //control_status =0; break; case 4: /* display Rick Dangerous title and Core Design copyright */ //slPrint("case 3 ",slLocate(3,3)); sysvid_clear(); tm = sys_gettime(); /* hall of fame title */ #ifdef GFXPC draw_tllst = (U8 *)screen_imainhoft; draw_setfb(32, 0); draw_filter = 0xaaaa; draw_tilesList(); #endif #ifdef GFXST draw_pic(0, 0, 0x140, 0x20, pic_haf); #endif /* hall of fame content */ draw_setfb(56, 40); #ifdef GFXPC draw_filter = 0x5555; #endif for (i = 0; i < 8; i++) { sprintf((char *)s, "%06d@@@....@@@%s", game_hscores[i].score, game_hscores[i].name); s[26] = '\377'; s[27] = '\377'; s[28] = '\376'; draw_tllst = s; draw_tilesList(); } seq = 5; break; case 5: /* wait for key pressed or timeout */ if (control_status & CONTROL_FIRE) { //slPrint("5 key pressed",slLocate(3,3)); // if (!(control_status & CONTROL_FIRE)) seq = 6; } else if (sys_gettime() - tm > SCREEN_TIMEOUT) { seen++; seq = 1; } break; case 6: /* wait for key released */ if (!(control_status & CONTROL_FIRE)) { if (seen++ == 0) seq = 1; else seq = 7; //while(1); } //else //control_status =0; break; } if (control_status & CONTROL_EXIT) /* check for exit request */ return SCREEN_EXIT; if (seq == 7) { /* we're done */ sysvid_clear(); seq = 0; seen = 0; first = FALSE; game_period = period; return SCREEN_DONE; } else return SCREEN_RUNNING; }