/*
Curblaster
Copyright (C) 2022 Gwyn Ciesla
+ Copyright (C) 2023 Matthew Mondor
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
*/
+#include <err.h>
#include <ncurses.h>
#include <cstring>
#include <cstdlib>
#include <time.h>
#include <cstdio>
#include <math.h>
+#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
-#include <unistd.h>
+#include <signal.h>
+#include <stdbool.h>
+#include <stdlib.h>
#include <string>
+#include <termios.h>
+#include <unistd.h>
#include <vector>
+#ifdef __USE_SDL__
#include "SDL2/SDL.h"
#include "SDL2/SDL_mixer.h"
+#endif
#include "game_object.h"
#include "check_collision.h"
#include "init.h"
#include "draw.h"
#include "powerup.h"
+#ifdef __USE_SDL__
#include "play_sound_effect.h"
+#endif
#include "mishaps.h"
#include "enemy_shoot.h"
+#include "randmac.h"
+
+
+
+/*
+ * Stable game clock and related utilities
+ * Try this at 15, it's already limit, try 30!
+ */
+
+#define ANIM_FPS 10 /* 10Hz ticks */
+#define TEMP_SHIELD (ANIM_FPS * 2) /* 2 secs */
+
+static void clock_init(void);
+static void sighandler(int);
+static void cleanup(void);
+
+static bool clock_expired = false;
+
+static int uc = ERR;
+
+static WINDOW *win = NULL;
+
+void
+clock_init(void)
+{
+ struct sigaction act;
+ struct itimerval itv;
+
+ /* Setup signal handler */
+ act.sa_handler = sighandler;
+ act.sa_flags = 0; /* ~SA_RESTART to detect interruptions */
+ if (sigemptyset(&act.sa_mask) != 0)
+ err(EXIT_FAILURE, "sigemptyset()");
+ if (sigaction(SIGALRM, &act, NULL) != 0)
+ err(EXIT_FAILURE, "sigaction(SIGALRM)");
+ if (sigaction(SIGINT, &act, NULL) != 0)
+ err(EXIT_FAILURE, "sigaction(SIGINT)");
+ if (sigaction(SIGTERM, &act, NULL) != 0)
+ err(EXIT_FAILURE, "sigaction(SIGTERM)");
+ if (sigaction(SIGHUP, &act, NULL) != 0)
+ err(EXIT_FAILURE, "sigaction(SIGHUP)");
+
+ /* Setup interval timer */
+ timerclear(&itv.it_interval);
+ timerclear(&itv.it_value);
+ itv.it_interval.tv_sec = 0;
+ itv.it_interval.tv_usec = 1000000 / ANIM_FPS;
+ itv.it_value.tv_sec = itv.it_interval.tv_sec;
+ itv.it_value.tv_usec = itv.it_interval.tv_usec;
+ if (setitimer(ITIMER_REAL, &itv, NULL) != 0)
+ err(EXIT_FAILURE, "setitimer()");
+}
+
+static void
+sighandler(int sig)
+{
+
+ switch (sig) {
+ case SIGALRM:
+ clock_expired = true;
+ break;
+ case SIGINT:
+ case SIGTERM: /* FALLTHROUGH */
+ case SIGHUP: /* FALLTHROUGH */
+ exit(EXIT_SUCCESS);
+ break;
+ }
+}
+
+static void
+cleanup(void)
+{
+
+ if (win != NULL) {
+ endwin();
+ win = NULL;
+ }
+}
+
+/*
+ * This getch(3) variant is designed to wait until the next clock tick and to
+ * return user input if any, also using the curses internal terminal sequence
+ * interpretation for special keys like arrows. ERR is returned if there was
+ * no user input. The wgetch(3) function reads in blocking mode and could
+ * wait forever, but is awaken by the regular interval timer that sets an
+ * expired flag. If it awakes because of user input before the timer expired,
+ * we record the key and block on read again. This ensures that unlike with
+ * halfdelay(3), we have a stable clock even when extensive user input occurs.
+ */
+static int
+stable_getch(void)
+{
+ int c;
+
+ (void)keypad(win, TRUE);
+ (void)timeout(-1);
+
+ for (clock_expired = false; !clock_expired; ) {
+ if ((c = wgetch(win)) != ERR)
+ uc = c;
+ }
+
+ c = uc;
+ uc = ERR;
+
+ return c;
+}
+
+
+/*
+ * On some systems like OSX [n]curses endwin() is not enough to properly
+ * restore the original terminal state. We can do it explicitly.
+ */
+
+static void term_save(void);
+static void term_load(void);
+
+static struct termios old_tios;
+
+static void
+term_save(void)
+{
+
+ if (tcgetattr(STDIN_FILENO, &old_tios) == -1)
+ err(EXIT_FAILURE, "tcgetattr()");
+ /* Exit cleanup hook to restore normal terminal */
+ (void)atexit(term_load);
+
+}
+
+static void
+term_load(void)
+{
+
+ (void)tcsetattr(STDIN_FILENO, TCSAFLUSH, &old_tios);
+}
+
+
+
+static void tempshield(void);
+
+int shieldup = 0;
+int temp_shield = 0;
+int super_shield = 0;
+
+static void
+tempshield(void)
+{
+
+ shieldup = 1;
+ temp_shield = TEMP_SHIELD;
+ super_shield += TEMP_SHIELD;
+}
+
+
const int podmax = 8;
const int bulletmax = 10;
int tripshot = 0;
int laser = 0;
int missile = 0;
-int super_shield = 0;
int sound = 1;
int newgame = 0;
if(argc==2&&strcmp(argv[1], "--nosound")==0){ sound = 0; };
- srand(time(NULL));
+ SRAND(time(NULL));
level = 1;
score = 0;
//pods
game_object pods[podmax] = {
- { 2, 1, 18, rand()%620, 0, 0, 1, 0, 0 },
- { 3, 1, 18, rand()%620, 0, 0, 1, 0, 0 },
- { 4, 1, 18, rand()%620, 0, 0, 1, 0, 0 },
- { 5, 1, 18, rand()%620, 0, 0, 1, 0, 0 },
- { 6, 1, 18, rand()%620, 0, 0, 1, 0, 0 },
- { 7, 1, 18, rand()%620, 0, 0, 1, 0, 0 },
- { 8, 1, 18, rand()%620, 0, 0, 1, 0, 0 },
- { 9, 1, 18, rand()%620, 0, 0, 1, 0, 0 }
+ { 2, 1, 18, RAND()%620, 0, 0, 1, 0, 0 },
+ { 3, 1, 18, RAND()%620, 0, 0, 1, 0, 0 },
+ { 4, 1, 18, RAND()%620, 0, 0, 1, 0, 0 },
+ { 5, 1, 18, RAND()%620, 0, 0, 1, 0, 0 },
+ { 6, 1, 18, RAND()%620, 0, 0, 1, 0, 0 },
+ { 7, 1, 18, RAND()%620, 0, 0, 1, 0, 0 },
+ { 8, 1, 18, RAND()%620, 0, 0, 1, 0, 0 },
+ { 9, 1, 18, RAND()%620, 0, 0, 1, 0, 0 }
};
for(int podloop = 0; podloop<podmax; podloop=podloop+2){
- if(rand()%1000>=500){
+ if(RAND()%1000>=500){
pods[podloop].direction = 4;
} else {
pods[podloop].direction = 6;
};
for(int podloop = 1; podloop<podmax+1; podloop=podloop+2){
- if(rand()%1000>=500){
+ if(RAND()%1000>=500){
pods[podloop].direction = 4;
} else {
pods[podloop].direction = 6;
//landers
game_object landers[landermax] = {
- { 60, 1, rand()%16, rand()%620, 0, 0, 1, 0, 0 },
- { 61, 1, rand()%16, rand()%620, 0, 0, 1, 0, 0 },
- { 62, 1, rand()%16, rand()%620, 0, 0, 1, 0, 0 },
- { 63, 1, rand()%16, rand()%620, 0, 0, 1, 0, 0 },
- { 64, 0, rand()%16, rand()%620, 0, 0, 1, 0, 0 },
- { 65, 0, rand()%16, rand()%620, 0, 0, 1, 0, 0 },
- { 66, 0, rand()%16, rand()%620, 0, 0, 1, 0, 0 },
- { 67, 0, rand()%16, rand()%620, 0, 0, 1, 0, 0 },
- { 68, 0, rand()%16, rand()%620, 0, 0, 1, 0, 0 },
- { 69, 0, rand()%16, rand()%620, 0, 0, 1, 0, 0 },
- { 70, 0, rand()%16, rand()%620, 0, 0, 1, 0, 0 },
- { 71, 0, rand()%16, rand()%620, 0, 0, 1, 0, 0 }
+ { 60, 1, RAND()%16, RAND()%620, 0, 0, 1, 0, 0 },
+ { 61, 1, RAND()%16, RAND()%620, 0, 0, 1, 0, 0 },
+ { 62, 1, RAND()%16, RAND()%620, 0, 0, 1, 0, 0 },
+ { 63, 1, RAND()%16, RAND()%620, 0, 0, 1, 0, 0 },
+ { 64, 0, RAND()%16, RAND()%620, 0, 0, 1, 0, 0 },
+ { 65, 0, RAND()%16, RAND()%620, 0, 0, 1, 0, 0 },
+ { 66, 0, RAND()%16, RAND()%620, 0, 0, 1, 0, 0 },
+ { 67, 0, RAND()%16, RAND()%620, 0, 0, 1, 0, 0 },
+ { 68, 0, RAND()%16, RAND()%620, 0, 0, 1, 0, 0 },
+ { 69, 0, RAND()%16, RAND()%620, 0, 0, 1, 0, 0 },
+ { 70, 0, RAND()%16, RAND()%620, 0, 0, 1, 0, 0 },
+ { 71, 0, RAND()%16, RAND()%620, 0, 0, 1, 0, 0 }
};
for(int landerloop = 0; landerloop<landermax; landerloop++){
- if(rand()%1000>=500){
+ if(RAND()%1000>=500){
landers[landerloop].direction = 4;
} else {
landers[landerloop].direction = 6;
//crawlers
game_object crawlers[crawlermax] = {
- { 30, 1, 18, rand()%620, 0, 0, 1, 0, 0 },
- { 31, 1, 18, rand()%620, 0, 0, 1, 0, 0 },
- { 32, 0, 18, rand()%620, 0, 0, 1, 0, 0 },
- { 33, 0, 18, rand()%620, 0, 0, 1, 0, 0 },
- { 34, 0, 18, rand()%620, 0, 0, 1, 0, 0 },
- { 35, 0, 18, rand()%620, 0, 0, 1, 0, 0 }
+ { 30, 1, 18, RAND()%620, 0, 0, 1, 0, 0 },
+ { 31, 1, 18, RAND()%620, 0, 0, 1, 0, 0 },
+ { 32, 0, 18, RAND()%620, 0, 0, 1, 0, 0 },
+ { 33, 0, 18, RAND()%620, 0, 0, 1, 0, 0 },
+ { 34, 0, 18, RAND()%620, 0, 0, 1, 0, 0 },
+ { 35, 0, 18, RAND()%620, 0, 0, 1, 0, 0 }
};
for(int crawlerloop = 0; crawlerloop<crawlermax; crawlerloop++){
- if(rand()%1000>=500){
+ if(RAND()%1000>=500){
crawlers[crawlerloop].direction = 4;
} else {
crawlers[crawlerloop].direction = 6;
missiles[missileloop].chase = -1;
};
- initscr();
+ clock_init();
+ term_save();
+
+ if ((win = initscr()) == NULL)
+ err(EXIT_FAILURE, "initscr()");
//Check screen size 80x24 and exit if not big enough
int maxx, maxy;
exit(1);
};
+ (void)atexit(cleanup);
+
//main loop
int loopvar = 0;
int alertleft = 0;
int alertright = 0;
int smartbombs = 2;
- int shieldup = 0;
int drawlaser = 0;
cbreak();
- halfdelay(1);
+ halfdelay(1); /* XXX */
noecho();
//print title screen
//Version
mvprintw(12,34,"Version %1.2f",version);
- //Copyright
+ //Copyright/credits
mvprintw(14,22,"Copyright (C) 2022 Gwyn Ciesla");
+ mvprintw(15,22,"Copyright (C) 2023 Matthew Mondor");
//player, lander, pods, gate
mvprintw(17,5,"<_==> - - - - ");
mvprintw(23,79,"-");
//load sound, music
+#ifdef __USE_SDL__
Mix_Chunk *shotsound = NULL;
int shotchannel = -1;
Mix_Chunk *boomsound = NULL;
int levelendchannel = -1;
Mix_Music *title = NULL;
+#endif
char *env_tty;
env_tty = getenv("SSH_TTY");
struct stat datatest;
+#ifdef __USE_SDL__
if(env_tty == NULL && sound == 1){
int audio_rate = 22050;
int audio_channels = 6;
int audio_buffers = 4096;
-
SDL_Init(SDL_INIT_AUDIO);
if(Mix_OpenAudio(audio_rate, audio_format, audio_channels, audio_buffers)) {
//start title music
Mix_PlayMusic(title, -1);
+#else
+ sound = 0;
+#endif
+
+ tempshield();
//hold until SPACE pressed
pause_game = 0;
counter++;
//halfdelay(1);
};
-
+
+#ifdef __USE_SDL__
Mix_HaltMusic();
Mix_FreeMusic(title);
title = NULL;
+#endif
while(loopvar == 0){
int input = 0;
-
+
clear();
+ /* Without this the next wrefresh() clears twice producing unnecessary
+ * flickering on some terminals. */
+ clearok(win, FALSE);
+
// Draw board
draw_board(score, lives, level, shieldsleft, missile);
pods[podloop].vtime = 1;
pods[podloop].chase = -1;
pods[podloop].speed = 1;
- if(rand()%1000>=500){
+ if(RAND()%1000>=500){
pods[podloop].direction = 4;
} else {
pods[podloop].direction = 6;
missiles[missileloop] = process_motion(missiles[missileloop], player);
//missiles[missileloop] = age_bullet(missiles[missileloop]); //Something to think about
} else {
+#ifdef __USE_SDL__
drawlocation = boom_object(drawlocation, boomstuff, missiles[missileloop], boomsound, boomchannel);
+#else
+ drawlocation = boom_object(drawlocation, boomstuff, missiles[missileloop]);
+#endif
missiles[missileloop] = object_out(missiles[missileloop]);
};
};
};
if(landers[landerloop].chase>=0&&landers[landerloop].phase==4){ //decode which pod to kill
pods[landers[landerloop].chase] = object_out(pods[landers[landerloop].chase]);
+#ifdef __USE_SDL__
crazies[landerloop] = encrazify(landers[landerloop], crazies[landerloop], crazifysound, crazifychannel);
+#else
+ crazies[landerloop] = encrazify(landers[landerloop], crazies[landerloop]);
+#endif
landers[landerloop] = object_out(landers[landerloop]);
};
};
//alerts
if(alertright>0){
if(alertright%2==0){
+#ifdef __USE_SDL__
warningchannel = play_sound_effect(warningsound, warningchannel);
+#endif
mvprintw(19,50," >> ");
};
alertright--;
};
if(alertleft>0){
if(alertleft%2==0){
+#ifdef __USE_SDL__
warningchannel = play_sound_effect(warningsound, warningchannel);
+#endif
mvprintw(19,40," << ");
};
alertleft--;
mvprintw(23,79,"|");
- input = getch();
+ input = stable_getch();
//quit
if(input=='q'){
+ char quit;
cbreak();
clear();
- printw("Really quit? (y/n)");
- char quit = getch();
+ printw("Really quit (y/n)? ");
+ for (quit = ERR; quit != 'y' && quit != 'n'; quit = getch()) ;
if(quit=='y'){
printw("\nBye Bye!\n");
loopvar=1;
if(shieldup==0){
if(shieldsleft>=1){
shieldup=1;
+#ifdef __USE_SDL__
shieldupchannel = play_sound_effect(shieldupsound, shieldupchannel);
+#endif
};
} else {
shieldup=0;
+#ifdef __USE_SDL__
shielddownchannel = play_sound_effect(shielddownsound, shielddownchannel);
+#endif
};
};
//deplete shields if necessary.
if(shieldup==1){
+ if (temp_shield > 0) {
+ if (--temp_shield == 0)
+ shieldup = 0;
+ } else
if(shieldsleft>0){
shieldsleft--;
} else {
shieldup=0;
+#ifdef __USE_SDL__
shielddownchannel = play_sound_effect(shielddownsound, shielddownchannel);
+#endif
};
};
//check for / process direction change
- if(input==66||input==68||input==67||input==65||input==69){
+ switch (input) {
+ case KEY_UP:
+ case '8': /* FALLTHROUGH */
+ case 'i': /* FALLTHROUGH */
+ input = 8;
+ break;
+ case KEY_DOWN:
+ case '2': /* FALLTHROUGH */
+ case 'k': /* FALLTHROUGH */
+ case 'm': /* FALLTHROUGH */
+ input = 2;
+ break;
+ case KEY_LEFT:
+ case '4': /* FALLTHROUGH */
+ case 'j': /* FALLTHROUGH */
+ input = 4;
+ break;
+ case KEY_RIGHT:
+ case '6': /* FALLTHROUGH */
+ case 'l': /* FALLTHROUGH */
+ input = 6;
+ break;
+ case '5': /* Apparently unused */
+ input = 5;
+ break;
+ }
+ if(input==8||input==2||input==4||input==6||input==5){
player = process_direction(player, input);
};
//check for powerup pickup
for(int puploop = 0; puploop<4; puploop++){
if((powerups[puploop].active==1)&&(check_collision(powerups[puploop], player)==1)){
+#ifdef __USE_SDL__
puptakechannel = play_sound_effect(puptakesound, puptakechannel);
+#endif
powerups[puploop] = object_out(powerups[puploop]);
if(strncmp(powerups[puploop].line0, "T", 1)==0){
tripshot = tripshot + 100;
//check for / process pod pickup
for(int podloop = 0; podloop<podmax; podloop++){
if((pod_in==0)&&(pods[podloop].active==1)&&(check_collision(pods[podloop], player)==1)){
+#ifdef __USE_SDL__
pickupchannel = play_sound_effect(pickupsound, pickupchannel);
+#endif
pod_in = pods[podloop].number;
pods[podloop].chase = -1;
//stop the chase if we steal the pod
//if pod in hand, check for gate dropoff
if(pod_in>0){
if((abs(player.y-gate.y)<player.speed)&&(player.x>10)){
+#ifdef __USE_SDL__
dropoffchannel = play_sound_effect(dropoffsound, dropoffchannel);
+#endif
//set pod inactive
for(int podloop = 0; podloop<podmax; podloop++){ if(pod_in==pods[podloop].number){ pods[podloop] = object_out(pods[podloop]); }; };
//if laser, do that
if(laser>0){
drawlaser=1;
+#ifdef __USE_SDL__
laserchannel = play_sound_effect(lasersound, laserchannel);
+#endif
//kill landers
for(int landerloop = 0; landerloop<landermax; landerloop++){
if(((abs(player.y-landers[landerloop].y)<=80)||(abs(player.y-landers[landerloop].y)>=540))&&(player.x==landers[landerloop].x)&&((player.face==0&&(landers[landerloop].y<player.y))||(player.face==1&&(landers[landerloop].y>player.y)))){
const game_object power_obj = landers[landerloop];
+#ifdef __USE_SDL__
determine_powerup(powerups, power_obj, 800, pupcreatesound, pupcreatechannel);
drawlocation = boom_object(drawlocation, boomstuff, landers[landerloop], boomsound, boomchannel);
+#else
+ determine_powerup(powerups, power_obj, 800);
+ drawlocation = boom_object(drawlocation, boomstuff, landers[landerloop]);
+#endif
landers[landerloop] = object_out(landers[landerloop]);
score = score + 15;
};
for(int crazyloop = 0; crazyloop<landermax; crazyloop++){
if(((abs(player.y-crazies[crazyloop].y)<=80)||(abs(player.y-crazies[crazyloop].y)>=540))&&(player.x==crazies[crazyloop].x)&&((player.face==0&&(crazies[crazyloop].y<player.y))||(player.face==1&&(crazies[crazyloop].y>player.y)))){
const game_object power_obj = crazies[crazyloop];
+#ifdef __USE_SDL__
determine_powerup(powerups, power_obj, 800, pupcreatesound, pupcreatechannel);
drawlocation = boom_object(drawlocation, boomstuff, crazies[crazyloop], boomsound, boomchannel);
+#else
+ determine_powerup(powerups, power_obj, 800);
+ drawlocation = boom_object(drawlocation, boomstuff, crazies[crazyloop]);
+#endif
crazies[crazyloop] = object_out(crazies[crazyloop]);
score = score + 15;
};
for(int crawlerloop = 0; crawlerloop<crawlermax; crawlerloop++){
if(((abs(player.y-crawlers[crawlerloop].y)<=80)||(abs(player.y-crawlers[crawlerloop].y)>=540))&&(player.x==crawlers[crawlerloop].x)&&((player.face==0&&(crawlers[crawlerloop].y<player.y))||(player.face==1&&(crawlers[crawlerloop].y>player.y)))){
const game_object power_obj = crawlers[crawlerloop];
+#ifdef __USE_SDL__
determine_powerup(powerups, power_obj, 800, pupcreatesound, pupcreatechannel);
drawlocation = boom_object(drawlocation, boomstuff, crawlers[crawlerloop], boomsound, boomchannel);
+#else
+ determine_powerup(powerups, power_obj, 800);
+ drawlocation = boom_object(drawlocation, boomstuff, crawlers[crawlerloop]);
+#endif
crawlers[crawlerloop] = object_out(crawlers[crawlerloop]);
score = score + 15;
};
bosses[bossloop].phase = bosses[bossloop].phase - 5;
if(bosses[bossloop].phase<=0){
const game_object power_obj = bosses[bossloop];
+#ifdef __USE_SDL__
determine_powerup(powerups, power_obj, 600, pupcreatesound, pupcreatechannel);
drawlocation = boom_object(drawlocation, boomstuff, bosses[bossloop], boomsound, boomchannel);
+#else
+ determine_powerup(powerups, power_obj, 600);
+ drawlocation = boom_object(drawlocation, boomstuff, bosses[bossloop]);
+#endif
bosses[bossloop] = object_out(bosses[bossloop]);
score = score + 75;
};
laser--;
} else {
//shot sound
+#ifdef __USE_SDL__
if(sound==1){shotchannel = play_sound_effect(shotsound, shotchannel);};
+#endif
//get next inactive bullet, give it player's direction, speed, height, location +speed in direction, active.
for(int bulletloop = 0; bulletloop<bulletmax; bulletloop++){
if(bullets[bulletloop].active==0){
for(int landerloop = 0; landerloop<landermax; landerloop++){
if(landers[landerloop].active==1){
if((abs(player.y-landers[landerloop].y)<=40)||(abs(player.y-landers[landerloop].y)>=580)){
+#ifdef __USE_SDL__
determine_powerup(powerups, landers[landerloop], 800, pupcreatesound, pupcreatechannel);
drawlocation = boom_object(drawlocation, boomstuff, landers[landerloop], boomsound, boomchannel);
+#else
+ determine_powerup(powerups, landers[landerloop], 800);
+ drawlocation = boom_object(drawlocation, boomstuff, landers[landerloop]);
+#endif
landers[landerloop] = object_out(landers[landerloop]);
score = score + 5;
};
for(int crazyloop = 0; crazyloop<landermax; crazyloop++){
if(crazies[crazyloop].active==1){
if((abs(player.y-crazies[crazyloop].y)<=40)||(abs(player.y-crazies[crazyloop].y)>=580)){
+#ifdef __USE_SDL__
drawlocation = boom_object(drawlocation, boomstuff, crazies[crazyloop], boomsound, boomchannel);
+#else
+ drawlocation = boom_object(drawlocation, boomstuff, crazies[crazyloop]);
+#endif
crazies[crazyloop] = object_out(crazies[crazyloop]);
score = score + 5;
};
for(int crawlerloop = 0; crawlerloop<crawlermax; crawlerloop++){
if(crawlers[crawlerloop].active==1){
if((abs(player.y-crawlers[crawlerloop].y)<=40)||(abs(player.y-crawlers[crawlerloop].y)>=580)){
+#ifdef __USE_SDL__
drawlocation = boom_object(drawlocation, boomstuff, crawlers[crawlerloop], boomsound, boomchannel);
+#else
+ drawlocation = boom_object(drawlocation, boomstuff, crawlers[crawlerloop]);
+#endif
crawlers[crawlerloop] = object_out(crawlers[crawlerloop]);
score = score + 5;
};
if((abs(player.y-bosses[bossloop].y)<=40)||(abs(player.y-bosses[bossloop].y)>=580)){
bosses[bossloop].phase = bosses[bossloop].phase - 5;
if(bosses[bossloop].phase<=0){
+#ifdef __USE_SDL__
drawlocation = boom_object(drawlocation, boomstuff, bosses[bossloop], boomsound, boomchannel);
+#else
+ drawlocation = boom_object(drawlocation, boomstuff, bosses[bossloop]);
+#endif
bosses[bossloop] = object_out(bosses[bossloop]);
score = score + 50;
};
if(landers[landerloop].active==1){
if(check_collision(bullets[bulletloop], landers[landerloop])==1){
//kill lander and bullet
+#ifdef __USE_SDL__
determine_powerup(powerups, landers[landerloop], 800, pupcreatesound, pupcreatechannel);
drawlocation = boom_object(drawlocation, boomstuff, landers[landerloop], boomsound, boomchannel);
+#else
+ determine_powerup(powerups, landers[landerloop], 800);
+ drawlocation = boom_object(drawlocation, boomstuff, landers[landerloop]);
+#endif
landers[landerloop] = object_out(landers[landerloop]);
bullets[bulletloop] = object_out(bullets[bulletloop]);
//add to score
if(crazies[crazyloop].active==1){
if(check_collision(bullets[bulletloop], crazies[crazyloop])==1){
//kill crazy and bullet
- determine_powerup(powerups, crazies[crazyloop], 800, pupcreatesound, pupcreatechannel);
+#ifdef __USE_SDL__
+ determine_powerup(powerups, crazies[crazyloop], 800, pupcreatesound, pupcreatechannel);
drawlocation = boom_object(drawlocation, boomstuff, crazies[crazyloop], boomsound, boomchannel);
+#else
+ determine_powerup(powerups, crazies[crazyloop], 800);
+ drawlocation = boom_object(drawlocation, boomstuff, crazies[crazyloop]);
+#endif
crazies[crazyloop] = object_out(crazies[crazyloop]);
bullets[bulletloop] = object_out(bullets[bulletloop]);
//add to score
if(crawlers[crawlerloop].active==1){
if(check_collision(bullets[bulletloop], crawlers[crawlerloop])==1){
//kill crawler and bullet
+#ifdef __USE_SDL__
determine_powerup(powerups, crawlers[crawlerloop], 800, pupcreatesound, pupcreatechannel);
drawlocation = boom_object(drawlocation, boomstuff, crawlers[crawlerloop], boomsound, boomchannel);
+#else
+ determine_powerup(powerups, crawlers[crawlerloop], 800);
+ drawlocation = boom_object(drawlocation, boomstuff, crawlers[crawlerloop]);
+#endif
crawlers[crawlerloop] = object_out(crawlers[crawlerloop]);
bullets[bulletloop] = object_out(bullets[bulletloop]);
//add to score
//hurt or kill boss, kill bullet
bosses[bossloop].phase = bosses[bossloop].phase - 1;
if(bosses[bossloop].phase<=0){
+#ifdef __USE_SDL__
determine_powerup(powerups, bosses[bossloop], 600, pupcreatesound, pupcreatechannel);
drawlocation = boom_object(drawlocation, boomstuff, bosses[bossloop], boomsound, boomchannel);
+#else
+ determine_powerup(powerups, bosses[bossloop], 600);
+ drawlocation = boom_object(drawlocation, boomstuff, bosses[bossloop]);
+#endif
bosses[bossloop] = object_out(bosses[bossloop]);
bullets[bulletloop] = object_out(bullets[bulletloop]);
//add to score
lives--;
//add to score
score = score + 10;
+#ifdef __USE_SDL__
drawlocation = boom_object(drawlocation, boomstuff, player, boomsound, boomchannel);
+#else
+ drawlocation = boom_object(drawlocation, boomstuff, player);
+#endif
newgame = life_loss(lives, score);
player = player_init(player);
+ tempshield();
drawlocation = player.y-20;
//kill any carried pods
if(pod_in>0){
if(shieldup==1&&super_shield>0){
for(int shieldloop = 0; shieldloop<12; shieldloop++){
if(check_collision(landers[landerloop], shields[shieldloop])==1){
+#ifdef __USE_SDL__
drawlocation = boom_object(drawlocation, boomstuff, landers[landerloop], boomsound, boomchannel);
+#else
+ drawlocation = boom_object(drawlocation, boomstuff, landers[landerloop]);
+#endif
landers[landerloop] = object_out(landers[landerloop]);
score = score + 10;
};
lives--;
//add to score
score = score + 10;
+#ifdef __USE_SDL__
drawlocation = boom_object(drawlocation, boomstuff, player, boomsound, boomchannel);
+#else
+ drawlocation = boom_object(drawlocation, boomstuff, player);
+#endif
newgame = life_loss(lives, score);
player = player_init(player);
+ tempshield();
drawlocation = player.y-20;
//kill any carried pods
if(pod_in>0){
if(shieldup==1&&super_shield>0){
for(int shieldloop = 0; shieldloop<12; shieldloop++){
if(check_collision(crazies[crazyloop], shields[shieldloop])==1){
+#ifdef __USE_SDL__
drawlocation = boom_object(drawlocation, boomstuff, crazies[crazyloop], boomsound, boomchannel);
+#else
+ drawlocation = boom_object(drawlocation, boomstuff, crazies[crazyloop]);
+#endif
crazies[crazyloop] = object_out(crazies[crazyloop]);
score = score + 10;
};
lives--;
//add to score
score = score + 10;
+#ifdef __USE_SDL__
drawlocation = boom_object(drawlocation, boomstuff, player, boomsound, boomchannel);
+#else
+ drawlocation = boom_object(drawlocation, boomstuff, player);
+#endif
newgame = life_loss(lives, score);
player = player_init(player);
+ tempshield();
drawlocation = player.y-20;
//kill any carried pods
if(pod_in>0){
if(shieldup==1&&super_shield>0){
for(int shieldloop = 0; shieldloop<12; shieldloop++){
if(check_collision(crawlers[crawlerloop], shields[shieldloop])==1){
+#ifdef __USE_SDL__
drawlocation = boom_object(drawlocation, boomstuff, crawlers[crawlerloop], boomsound, boomchannel);
+#else
+ drawlocation = boom_object(drawlocation, boomstuff, crawlers[crawlerloop]);
+#endif
crawlers[crawlerloop] = object_out(crawlers[crawlerloop]);
score = score + 10;
};
if(check_collision(player, bosses[bossloop])==1){
//kill player only
lives--;
+#ifdef __USE_SDL__
drawlocation = boom_object(drawlocation, boomstuff, player, boomsound, boomchannel);
+#else
+ drawlocation = boom_object(drawlocation, boomstuff, player);
+#endif
newgame = life_loss(lives, score);
player = player_init(player);
+ tempshield();
drawlocation = player.y-20;
//kill any carried pods
if(pod_in>0){
if(missiles[missileloop].active == 1){
if(check_collision(landers[missiles[missileloop].chase], missiles[missileloop])==1){
//kill missile and lander
+#ifdef __USE_SDL__
drawlocation = boom_object(drawlocation, boomstuff, landers[missiles[missileloop].chase], boomsound, boomchannel);
drawlocation = boom_object(drawlocation, boomstuff, missiles[missileloop], boomsound, boomchannel);
+#else
+ drawlocation = boom_object(drawlocation, boomstuff, landers[missiles[missileloop].chase]);
+ drawlocation = boom_object(drawlocation, boomstuff, missiles[missileloop]);
+#endif
landers[missiles[missileloop].chase] = object_out(landers[missiles[missileloop].chase]);
missiles[missileloop] = object_out(missiles[missileloop]);
};
// Lander shots
for(int landerloop = 0; landerloop<landermax; landerloop++){
if(landers[landerloop].active==1&&landers[landerloop].chase<=0){
- if(rand()%1000>500){
+ if(RAND()%1000>500){
// lander shoot
for(int landershotloop = 0; landershotloop<landershotmax; landershotloop++){
if(landershot[landershotloop].active==0){
+#ifdef __USE_SDL__
landershot[landershotloop] = enemy_shoot(landers[landerloop], player, landershot[landershotloop], enshotchannel, enshotsound);
+#else
+ landershot[landershotloop] = enemy_shoot(landers[landerloop], player, landershot[landershotloop]);
+#endif
break;
};
};
// Crazy shots
for(int crazyloop = 0; crazyloop<landermax; crazyloop++){
if(crazies[crazyloop].active==1){
- if(rand()%1000>200){
+ if(RAND()%1000>200){
// crazy shoot
for(int crazyshotloop = 0; crazyshotloop<landershotmax; crazyshotloop++){
if(landershot[crazyshotloop].active==0){
+#ifdef __USE_SDL__
landershot[crazyshotloop] = enemy_shoot(crazies[crazyloop], player, landershot[crazyshotloop], enshotchannel, enshotsound);
+#else
+ landershot[crazyshotloop] = enemy_shoot(crazies[crazyloop], player, landershot[crazyshotloop]);
+#endif
break;
};
};
// Crawler shots
for(int crawlerloop = 0; crawlerloop<crawlermax; crawlerloop++){
if(crawlers[crawlerloop].active==1&&crawlers[crawlerloop].chase<=0){
- if(rand()%1000>500){
+ if(RAND()%1000>500){
// crawler shoot
for(int crawlershotloop = 0; crawlershotloop<landershotmax; crawlershotloop++){
if(landershot[crawlershotloop].active==0){
+#ifdef __USE_SDL__
landershot[crawlershotloop] = enemy_shoot(crawlers[crawlerloop], player, landershot[crawlershotloop], enshotchannel, enshotsound);
+#else
+ landershot[crawlershotloop] = enemy_shoot(crawlers[crawlerloop], player, landershot[crawlershotloop]);
+#endif
break;
};
};
// boss shots
for(int bossloop = 0; bossloop<6; bossloop++){
if(bosses[bossloop].active==1){
- if(rand()%1000>100){
+ if(RAND()%1000>100){
// boss shoot
for(int bossshotloop = 0; bossshotloop<landershotmax; bossshotloop++){
if(landershot[bossshotloop].active==0){
+#ifdef __USE_SDL__
landershot[bossshotloop] = enemy_shoot(bosses[bossloop], player, landershot[bossshotloop], enshotchannel, enshotsound);
+#else
+ landershot[bossshotloop] = enemy_shoot(bosses[bossloop], player, landershot[bossshotloop]);
+#endif
break;
};
};
//kill landershot and player
lives--;
landershot[landershotloop] = object_out(landershot[landershotloop]);
+#ifdef __USE_SDL__
drawlocation = boom_object(drawlocation, boomstuff, player, boomsound, boomchannel);
+#else
+ drawlocation = boom_object(drawlocation, boomstuff, player);
+#endif
newgame = life_loss(lives, score);
player = player_init(player);
+ tempshield();
drawlocation = player.y-20;
//kill any carried pods
if(pod_in>0){
//Reset level
level = 1;
//Drop shields
+ /* XXX
shieldup = 0;
+ */
+ tempshield();
+ player.speed = 0;
+ player.vspeed = 0;
//Zero laser
laser = 0;
//Zero triple shot
//decide to grab a pod
for(int landerloop = 0; landerloop<landermax; landerloop++){
if(landers[landerloop].active==1&&landers[landerloop].chase==-1){
- //if(rand()%10000<=10){
- if(rand()%1000<=10){
+ //if(RAND()%10000<=10){
+ if(RAND()%1000<=10){
//choose a pod
for(int podloop = 0; podloop<podmax; podloop++){
if(landers[landerloop].chase==-1&&pods[podloop].chase==-1&&pods[podloop].active==1){
if(missiles[missileloop].chase==-1){
missiles[missileloop].chase = landerloop;
//play missle launch sound
+#ifdef __USE_SDL__
missilechannel = play_sound_effect(missilesound, missilechannel);
+#endif
//init missle
missiles[missileloop] = missile_init(missiles[missileloop], player, landers[landerloop]);
missile--;
//crazy the landers
for(int landerloop = 0; landerloop<landermax; landerloop++){
if(landers[landerloop].active==1){
+#ifdef __USE_SDL__
crazies[landerloop] = encrazify(landers[landerloop], crazies[landerloop], crazifysound, crazifychannel);
+#else
+ crazies[landerloop] = encrazify(landers[landerloop], crazies[landerloop]);
+#endif
landers[landerloop] = object_out(landers[landerloop]);
};
};
bosscount = 0;
for(int bossloop = 0; bossloop<6; bossloop++){ bosscount = bosscount + bosses[bossloop].active; };
if(landercount<=0&&bosscount<=0){
+#ifdef __USE_SDL__
levelendchannel = play_sound_effect(levelendsound, levelendchannel);
+#endif
//Tally bonuses
//Award lives, if any
if(lives<4){lives++;};
halfdelay(1);
//Advance level
level++;
- //Drop shields
- shieldup = 0;
+ //Drop shields XXX
+ //shieldup = 0;
+ tempshield();
+ // Reset speed
+ player.speed = 0;
+ player.vspeed = 0;
//Reactivate pods if not zombied
if((level-1) % 4 == 0){
for(int podloop = 0; podloop<podmax; podloop++){ pods[podloop] = pod_init(pods[podloop]); };
};
};
};
-
+ //wrefresh(win);
}; //end main loop
+#ifdef __USE_SDL__
if(sound==1){
Mix_FreeChunk(shotsound);
Mix_FreeChunk(boomsound);
Mix_CloseAudio();
SDL_Quit();
};
+#endif
- endwin();
-
- return 0;
+ exit(EXIT_SUCCESS);
}