// ECE 476 MISSILE COMMAND PROJECT: MISSILE CODE
//
// CEM OZKAYNAK, BRIAN SMITH
// Contact co37@cornell.edu,
bcs27@cornell.edu
//
//video gen and sound
//D.5 is sync:1000 ohm + diode to 75 ohm resistor
//D.6 is video:330 ohm + diode to 75 ohm
resistor
//B.3 is sound
and should have a 10k resistor to gnd
#pragma regalloc-
//I allocate the registers myself
#pragma optsize-
//optimize for speed
#include <Mega32.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <delay.h>
//cycles = 63.625 * 16 Note NTSC is 63.55
//but this line duration makes each frame exactly
1/60 sec
//which is nice for keeping a realtime clock
#define lineTime 1018
#define begin {
#define end
}
#define ScreenTop 30
#define ScreenBot 230
#define width 126
#define height 78
#define max 8
// Maximum missile count per
level
#define max_intercept 8
#define citycount 5
//game states
#define PRNT_INTRO
1
#define GET_INTRO
2
#define PRNT_DIF
3
#define GET_DIF
4
#define GAME_INIT 5
#define RUN_GAME 6
#define PRNT_GAMEOVER 7
#define GET_GAMEOVER 8
#define RESTART 9
#define PAUSE 10
//NOTE that v1 to v8 and i must be in
registers!
register char v1 @4;
register char v2 @5;
register char v3 @6;
register char v4 @7;
register char v5 @8;
register char v6 @9;
register char v7 @10;
register char v8 @11;
register int i @12;
#pragma regalloc+
char syncON, syncOFF;
int LineCount;
int time, vint;
unsigned char gamestate, printcount, level,
justfired, justfiredr, temp, temp2;
unsigned long score;
unsigned long eeprom highscore;
unsigned char m_index, mpw;
unsigned char i_index, icount;
unsigned char c_index, deadcities, fastcount,
fastcount2;
unsigned char cstatus[citycount], mstatus[max],
istatus[max_intercept];
unsigned char curx, cury;
unsigned int mtimer[max];
unsigned char mx[max],my[max],mxp[max],myp[max],m_theta[max];
unsigned int mxp_long[max],myp_long[max];
unsigned char
ix[max_intercept],iy[max_intercept],ixf[max_intercept],iyf[max_intercept],ixp[max_intercept],iyp[max_intercept],xbox[max_intercept],ybox[max_intercept];
unsigned int
ixp_long[max_intercept],iyp_long[max_intercept];
char screen[1600], t, ts[10];
flash char cu1[]="MISSILE";
flash char cu2[]="COMMAND";
//flash char mc[]="MISSILECOMMAND";
flash char clb[]="CLICK2BEGIN";
flash char diff[]="DIFFICULTY";
flash char scorestr[]="SCORE";
flash char highstr[]="HIGH";
flash char easy[]="NKOREA";
flash char med[] ="
flash char hard[]="
flash char lose[]="BOOM";
flash char paused[]="P";
flash char pmenu[]="E";
char tempstr[10];
flash unsigned char start_max[] = {48, 71, 89, 105,
119, 126, 126, 126, 126, 126};
flash unsigned char start_min[] = {2, 2, 2, 2, 2,
7, 21, 37, 55, 78};
flash unsigned char del_start[] = {46, 69, 87, 103,
117, 119, 105, 89, 71, 48};
flash unsigned char cx[] = {3,28,44,82,104}; // X locations of Cities;
// Indexed by increasing difficulty levels
flash unsigned int mvy[] = {64, 128, 192, 255}; // Missile Y-Velocity [Pixels/(8
Frames)]
flash unsigned int time2gnd[] = {308, 152, 102,
77}; // Time to Ground [8 Frames]
flash signed int mvx[10][4] =
{
64,128,192,255,
45,90,134,179,
30,60,90,119,
17,34,51,69,
6,11,17,22,
-6,-11,-17,-22,
-17,-34,-51,-69,
-30,-60,-90,-119,
-45,-90,-134,-179,
-64,-128,-192,-255};
flash signed int ivx[42][26] =
{
-256,-255,-254,-252,-250,-247,-243,-240,-236,-231,-227,-222,-217,-212,-208,-203,-198,-193,-189,-184,-180,-175,-171,-167,-163,-159,
-256,-255,-254,-252,-249,-246,-242,-238,-234,-229,-224,-219,-214,-209,-204,-199,-194,-189,-184,-179,-175,-170,-166,-162,-158,-154,
-256,-255,-253,-251,-248,-245,-241,-236,-231,-226,-221,-216,-211,-205,-200,-195,-189,-184,-179,-175,-170,-165,-161,-157,-153,-149,
-256,-255,-253,-250,-247,-243,-239,-234,-229,-224,-218,-212,-207,-201,-195,-190,-185,-179,-174,-169,-165,-160,-155,-151,-147,-143,
-256,-255,-253,-250,-246,-242,-237,-232,-226,-220,-214,-208,-202,-196,-190,-185,-179,-174,-169,-164,-159,-154,-150,-145,-141,-137,
-256,-255,-252,-249,-245,-240,-235,-229,-223,-217,-210,-204,-197,-191,-185,-179,-173,-168,-162,-157,-153,-148,-143,-139,-135,-131,
-256,-254,-252,-248,-243,-238,-232,-226,-219,-212,-205,-199,-192,-185,-179,-173,-167,-161,-156,-151,-146,-141,-137,-133,-129,-125,
-256,-254,-251,-247,-242,-236,-229,-222,-215,-207,-200,-193,-186,-179,-172,-166,-160,-154,-149,-144,-139,-134,-130,-126,-122,-118,
-256,-254,-250,-245,-239,-233,-225,-217,-209,-201,-194,-186,-179,-172,-165,-158,-152,-147,-141,-136,-131,-127,-122,-118,-114,-111,
-256,-253,-249,-244,-237,-229,-221,-212,-203,-195,-186,-178,-171,-163,-157,-150,-144,-138,-133,-128,-123,-119,-114,-111,-107,-103,
-255,-253,-248,-241,-233,-224,-215,-206,-196,-187,-178,-170,-162,-154,-147,-141,-135,-129,-124,-119,-114,-110,-106,-102,-99,-96,
-255,-252,-246,-238,-229,-219,-208,-198,-188,-178,-169,-160,-152,-144,-137,-131,-125,-120,-114,-110,-105,-101,-97,-94,-91,-87,
-255,-251,-244,-234,-223,-212,-200,-188,-177,-167,-158,-149,-141,-133,-126,-120,-114,-109,-104,-100,-96,-92,-88,-85,-82,-79,
-255,-250,-241,-229,-216,-203,-189,-177,-165,-155,-145,-136,-128,-121,-114,-109,-103,-98,-94,-89,-86,-82,-79,-76,-73,-70,
-255,-248,-236,-222,-206,-191,-176,-163,-151,-140,-131,-122,-114,-108,-101,-96,-91,-86,-82,-78,-75,-72,-69,-66,-64,-61,
-254,-244,-229,-211,-193,-175,-160,-146,-134,-124,-114,-106,-99,-93,-87,-82,-78,-74,-70,-67,-64,-61,-59,-56,-54,-52,
-253,-239,-218,-195,-174,-155,-140,-126,-114,-105,-96,-89,-83,-77,-73,-68,-64,-61,-58,-55,-53,-50,-48,-46,-44,-43,
-251,-229,-200,-172,-149,-130,-114,-102,-92,-83,-76,-70,-65,-61,-57,-53,-50,-47,-45,-43,-41,-39,-37,-36,-34,-33,
-246,-208,-169,-137,-114,-97,-85,-75,-67,-60,-55,-50,-46,-43,-40,-38,-35,-34,-32,-30,-29,-27,-26,-25,-24,-23,
-229,-160,-114,-87,-70,-59,-50,-44,-39,-35,-32,-29,-27,-25,-23,-22,-20,-19,-18,-17,-16,-16,-15,-14,-14,-13,
-114,-50,-32,-23,-18,-15,-13,-11,-10,-9,-8,-7,-7,-6,-6,-5,-5,-5,-5,-4,-4,-4,-4,-4,-3,-3,
181,95,62,46,36,30,25,22,20,18,16,15,13,12,12,11,10,10,9,9,8,8,8,7,7,7,
238,181,136,106,86,72,62,54,48,43,40,36,33,31,29,27,25,24,23,22,21,20,19,18,17,17,
248,217,181,151,127,109,95,84,75,68,62,57,53,49,46,43,40,38,36,34,33,31,30,29,28,26,
252,233,207,181,158,139,123,110,100,91,83,77,71,66,62,58,55,52,49,47,45,43,41,39,38,36,
253,241,222,201,181,163,147,133,121,111,103,95,89,83,78,73,69,65,62,59,56,54,52,50,48,46,
254,246,232,215,198,181,166,152,140,129,120,112,105,98,92,87,82,78,74,71,68,65,62,60,57,55,
255,248,238,224,210,195,181,168,156,145,136,127,119,112,106,100,95,90,86,82,79,75,72,69,67,64,
255,250,242,231,219,206,193,181,170,159,149,141,133,125,119,113,107,102,97,93,89,85,82,79,76,73,
255,251,245,236,225,214,203,192,181,171,161,153,145,137,130,124,118,113,108,103,99,95,91,88,85,82,
255,252,247,239,231,221,211,201,191,181,172,163,155,148,141,134,128,123,118,113,108,104,100,97,93,90,
256,253,248,242,235,226,217,208,199,190,181,173,165,158,151,144,138,132,127,122,117,113,109,105,102,98,
256,253,250,244,238,230,222,214,206,197,189,181,173,166,159,153,147,141,136,131,126,121,117,113,109,106,
256,254,251,246,240,234,227,219,211,204,196,188,181,174,167,161,155,149,144,139,134,129,125,121,117,113,
256,254,251,247,242,236,230,223,216,209,202,195,188,181,175,168,162,157,151,146,141,137,132,128,124,120,
256,254,252,248,244,239,233,227,220,214,207,200,194,187,181,175,169,164,158,153,148,144,139,135,131,127,
256,255,252,249,245,241,236,230,224,218,212,205,199,193,187,181,175,170,165,160,155,150,146,141,137,133,
256,255,253,250,247,242,238,233,227,221,216,210,204,198,192,187,181,176,171,166,161,156,152,147,143,139,
256,255,253,251,248,244,240,235,230,225,219,214,208,202,197,192,186,181,176,171,166,162,157,153,149,145,
256,255,253,251,248,245,241,237,232,227,222,217,212,207,201,196,191,186,181,176,172,167,163,159,154,151,
256,255,254,252,249,246,242,239,234,230,225,220,215,210,205,200,195,190,186,181,176,172,168,164,160,156,
256,255,254,252,250,247,244,240,236,232,227,223,218,214,209,204,199,195,190,185,181,177,172,168,164,161
};
flash signed int ivy[42][26] =
{
8,21,33,45,57,69,80,90,100,110,119,127,135,143,150,156,162,168,173,178,182,187,191,194,198,201,
9,22,35,48,60,72,83,94,105,114,124,132,140,148,155,161,167,173,178,183,187,191,195,198,201,204,
9,23,37,50,63,76,87,99,109,119,129,137,146,153,160,166,172,178,183,187,192,195,199,202,205,208,
10,25,39,53,67,80,92,104,114,125,134,143,151,159,165,172,177,183,188,192,196,200,203,207,209,212,
10,26,41,56,70,84,97,109,120,130,140,149,157,164,171,177,183,188,193,197,201,204,208,211,213,216,
11,28,44,60,75,89,102,114,126,137,146,155,163,170,177,183,188,193,198,202,206,209,212,215,217,220,
12,30,47,63,79,94,108,121,132,143,153,162,170,177,183,189,194,199,203,207,210,214,216,219,221,224,
13,32,50,68,85,100,114,128,140,150,160,169,176,183,189,195,200,204,208,212,215,218,221,223,225,227,
14,34,54,73,91,107,122,135,147,158,167,176,183,190,196,201,206,210,214,217,220,222,225,227,229,231,
15,37,59,79,97,114,130,143,156,166,175,184,191,197,203,207,212,215,219,222,224,227,229,231,233,234,
16,41,64,86,105,123,139,153,165,175,184,192,198,204,209,214,218,221,224,227,229,231,233,235,236,237,
18,45,70,94,114,133,149,162,174,184,193,200,206,211,216,220,223,226,229,231,233,235,237,238,239,241,
20,50,78,103,125,144,160,173,185,194,202,208,214,219,223,226,229,232,234,236,237,239,240,241,243,243,
23,57,87,114,137,157,172,185,195,204,211,217,222,226,229,232,234,236,238,240,241,242,244,245,245,246,
27,65,99,128,152,171,186,197,207,214,220,225,229,232,235,237,239,241,242,244,245,246,247,247,248,249,
32,76,114,145,169,186,200,210,218,224,229,233,236,238,241,242,244,245,246,247,248,249,249,250,250,251,
39,92,134,165,188,203,215,223,229,234,237,240,242,244,246,247,248,249,249,250,251,251,251,252,252,252,
50,114,160,189,208,221,229,235,239,242,244,246,248,249,250,250,251,252,252,252,253,253,253,253,254,254,
70,149,193,216,229,237,242,245,247,249,250,251,252,252,253,253,254,254,254,254,254,255,255,255,255,255,
114,200,229,241,246,249,251,252,253,254,254,254,255,255,255,255,255,255,255,255,255,256,256,256,256,256,
229,251,254,255,255,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,
181,238,248,252,253,254,255,255,255,255,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,
95,181,217,233,241,246,248,250,251,252,253,253,254,254,254,255,255,255,255,255,255,255,255,255,255,255,
62,136,181,207,222,232,238,242,245,247,248,250,251,251,252,252,253,253,253,254,254,254,254,254,255,255,
46,106,151,181,201,215,224,231,236,239,242,244,246,247,248,249,250,251,251,252,252,252,253,253,253,253,
36,86,127,158,181,198,210,219,225,231,235,238,240,242,244,245,247,248,248,249,250,250,251,251,252,252,
30,72,109,139,163,181,195,206,214,221,226,230,234,236,239,241,242,244,245,246,247,248,248,249,250,250,
25,62,95,123,147,166,181,193,203,211,217,222,227,230,233,236,238,240,241,242,244,245,246,246,247,248,
22,54,84,110,133,152,168,181,192,201,208,214,219,223,227,230,233,235,237,239,240,241,243,244,244,245,
20,48,75,100,121,140,156,170,181,191,199,206,211,216,220,224,227,230,232,234,236,238,239,240,242,243,
18,43,68,91,111,129,145,159,171,181,190,197,204,209,214,218,221,225,227,230,232,234,235,237,238,240,
16,40,62,83,103,120,136,149,161,172,181,189,196,202,207,212,216,219,222,225,227,230,232,233,235,236,
15,36,57,77,95,112,127,141,153,163,173,181,188,195,200,205,210,214,217,220,223,225,228,230,231,233,
13,33,53,71,89,105,119,133,145,155,165,173,181,188,194,199,204,208,212,215,218,221,223,226,228,230,
12,31,49,66,83,98,112,125,137,148,158,166,174,181,187,193,198,202,207,210,214,217,219,222,224,226,
12,29,46,62,78,92,106,119,130,141,151,159,167,175,181,187,192,197,201,205,209,212,215,218,220,222,
11,27,43,58,73,87,100,113,124,134,144,153,161,168,175,181,187,192,196,200,204,207,211,213,216,219,
10,25,40,55,69,82,95,107,118,128,138,147,155,162,169,175,181,186,191,195,199,203,206,209,212,215,
10,24,38,52,65,78,90,102,113,123,132,141,149,157,164,170,176,181,186,190,195,198,202,205,208,211,
9,23,36,49,62,74,86,97,108,118,127,136,144,151,158,165,171,176,181,186,190,194,198,201,204,207,
9,22,34,47,59,71,82,93,103,113,122,131,139,146,153,160,166,171,176,181,185,190,193,197,200,203,
8,21,33,45,56,68,79,89,99,108,117,126,134,141,148,155,161,166,172,176,181,185,189,193,196,199
};
//define some character bitmaps
//5x7 characters
flash int cities[3][8]={
// City
0b0000111011110000,
0b0000101011010000,
0b0000111010110000,
0b0001101011011100,
0b0001111110110100,
0b0001101011011100,
0b1101111110110100,
0b1111111111111111,
//
0b0000000000000000,
0b0000000000000000,
0b0001000000000000,
0b0001100000100000,
0b0001100001100000,
0b0011111011110000,
0b0110111110111000,
0b1111011111011111,
//
Wrecked City
0b0000000000000000,
0b0000000000000000,
0b0000000000000000,
0b0000000000000000,
0b0000000000000000,
0b0000100001000000,
0b0011110011100110,
0b1111111111111111};
flash char explosion[2][5]={
//
Explosion Frame1
0b00000,
0b00100,
0b01110,
0b00100,
0b00000,
//
Explosion Frame2
0b01110,
0b11111,
0b11111,
0b11111,
0b01110};
//Point plot lookup table
//One bit masks
flash char
pos[8]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
//define some character bitmaps
//5x7 characters
flash char bitmap[38][7]={
//0
0b01110000,
0b10001000,
0b10011000,
0b10101000,
0b11001000,
0b10001000,
0b01110000,
//1
0b00100000,
0b01100000,
0b00100000,
0b00100000,
0b00100000,
0b00100000,
0b01110000,
//2
0b01110000,
0b10001000,
0b00001000,
0b00010000,
0b00100000,
0b01000000,
0b11111000,
//3
0b11111000,
0b00010000,
0b00100000,
0b00010000,
0b00001000,
0b10001000,
0b01110000,
//4
0b00010000,
0b00110000,
0b01010000,
0b10010000,
0b11111000,
0b00010000,
0b00010000,
//5
0b11111000,
0b10000000,
0b11110000,
0b00001000,
0b00001000,
0b10001000,
0b01110000,
//6
0b01000000,
0b10000000,
0b10000000,
0b11110000,
0b10001000,
0b10001000,
0b01110000,
//7
0b11111000,
0b00001000,
0b00010000,
0b00100000,
0b01000000,
0b10000000,
0b10000000,
//8
0b01110000,
0b10001000,
0b10001000,
0b01110000,
0b10001000,
0b10001000,
0b01110000,
//9
0b01110000,
0b10001000,
0b10001000,
0b01111000,
0b00001000,
0b00001000,
0b00010000,
//A
0b01110000,
0b10001000,
0b10001000,
0b10001000,
0b11111000,
0b10001000,
0b10001000,
//B
0b11110000,
0b10001000,
0b10001000,
0b11110000,
0b10001000,
0b10001000,
0b11110000,
//C
0b01110000,
0b10001000,
0b10000000,
0b10000000,
0b10000000,
0b10001000,
0b01110000,
//D
0b11110000,
0b10001000,
0b10001000,
0b10001000,
0b10001000,
0b10001000,
0b11110000,
//E
0b11111000,
0b10000000,
0b10000000,
0b11111000,
0b10000000,
0b10000000,
0b11111000,
//F
0b11111000,
0b10000000,
0b10000000,
0b11111000,
0b10000000,
0b10000000,
0b10000000,
//G
0b01110000,
0b10001000,
0b10000000,
0b10011000,
0b10001000,
0b10001000,
0b01110000,
//H
0b10001000,
0b10001000,
0b10001000,
0b11111000,
0b10001000,
0b10001000,
0b10001000,
//I
0b01110000,
0b00100000,
0b00100000,
0b00100000,
0b00100000,
0b00100000,
0b01110000,
//J
0b00111000,
0b00010000,
0b00010000,
0b00010000,
0b00010000,
0b10010000,
0b01100000,
//K
0b10001000,
0b10010000,
0b10100000,
0b11000000,
0b10100000,
0b10010000,
0b10001000,
//L
0b10000000,
0b10000000,
0b10000000,
0b10000000,
0b10000000,
0b10000000,
0b11111000,
//M
0b10001000,
0b11011000,
0b10101000,
0b10101000,
0b10001000,
0b10001000,
0b10001000,
//N
0b10001000,
0b10001000,
0b11001000,
0b10101000,
0b10011000,
0b10001000,
0b10001000,
//O
0b01110000,
0b10001000,
0b10001000,
0b10001000,
0b10001000,
0b10001000,
0b01110000,
//P
0b11110000,
0b10001000,
0b10001000,
0b11110000,
0b10000000,
0b10000000,
0b10000000,
//Q
0b01110000,
0b10001000,
0b10001000,
0b10001000,
0b10101000,
0b10010000,
0b01101000,
//R
0b11110000,
0b10001000,
0b10001000,
0b11110000,
0b10100000,
0b10010000,
0b10001000,
//S
0b01111000,
0b10000000,
0b10000000,
0b01110000,
0b00001000,
0b00001000,
0b11110000,
//T
0b11111000,
0b00100000,
0b00100000,
0b00100000,
0b00100000,
0b00100000,
0b00100000,
//U
0b10001000,
0b10001000,
0b10001000,
0b10001000,
0b10001000,
0b10001000,
0b01110000,
//V
0b10001000,
0b10001000,
0b10001000,
0b10001000,
0b10001000,
0b01010000,
0b00100000,
//W
0b10001000,
0b10001000,
0b10001000,
0b10101000,
0b10101000,
0b10101000,
0b01010000,
//X
0b10001000,
0b10001000,
0b01010000,
0b00100000,
0b01010000,
0b10001000,
0b10001000,
//Y
0b10001000,
0b10001000,
0b10001000,
0b01010000,
0b00100000,
0b00100000,
0b00100000,
//Z
0b11111000,
0b00001000,
0b00010000,
0b00100000,
0b01000000,
0b10000000,
0b11111000,
//figure1
0b01110000,
0b00100000,
0b01110000,
0b10101000,
0b00100000,
0b01010000,
0b10001000,
//figure2
0b01110000,
0b10101000,
0b01110000,
0b00100000,
0b00100000,
0b01010000,
0b10001000};
//================================
//3x5 font numbers, then letters
//packed two per definition for fast
//copy to the screen at x-position divisible by 4
flash char smallbitmap[39][5]={
//0
0b11101110,
0b10101010,
0b10101010,
0b10101010,
0b11101110,
//1
0b01000100,
0b11001100,
0b01000100,
0b01000100,
0b11101110,
//2
0b11101110,
0b00100010,
0b11101110,
0b10001000,
0b11101110,
//3
0b11101110,
0b00100010,
0b11101110,
0b00100010,
0b11101110,
//4
0b10101010,
0b10101010,
0b11101110,
0b00100010,
0b00100010,
//5
0b11101110,
0b10001000,
0b11101110,
0b00100010,
0b11101110,
//6
0b11001100,
0b10001000,
0b11101110,
0b10101010,
0b11101110,
//7
0b11101110,
0b00100010,
0b01000100,
0b10001000,
0b10001000,
//8
0b11101110,
0b10101010,
0b11101110,
0b10101010,
0b11101110,
//9
0b11101110,
0b10101010,
0b11101110,
0b00100010,
0b01100110,
//:
0b00000000,
0b01000100,
0b00000000,
0b01000100,
0b00000000,
//=
0b00000000,
0b11101110,
0b00000000,
0b11101110,
0b00000000,
//blank
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
//A
0b11101110,
0b10101010,
0b11101110,
0b10101010,
0b10101010,
//B
0b11001100,
0b10101010,
0b11101110,
0b10101010,
0b11001100,
//C
0b11101110,
0b10001000,
0b10001000,
0b10001000,
0b11101110,
//D
0b11001100,
0b10101010,
0b10101010,
0b10101010,
0b11001100,
//E
0b11101110,
0b10001000,
0b11101110,
0b10001000,
0b11101110,
//F
0b11101110,
0b10001000,
0b11101110,
0b10001000,
0b10001000,
//G
0b11101110,
0b10001000,
0b10001000,
0b10101010,
0b11101110,
//H
0b10101010,
0b10101010,
0b11101110,
0b10101010,
0b10101010,
//I
0b11101110,
0b01000100,
0b01000100,
0b01000100,
0b11101110,
//J
0b00100010,
0b00100010,
0b00100010,
0b10101010,
0b11101110,
//K
0b10001000,
0b10101010,
0b11001100,
0b11001100,
0b10101010,
//L
0b10001000,
0b10001000,
0b10001000,
0b10001000,
0b11101110,
//M
0b10101010,
0b11101110,
0b11101110,
0b10101010,
0b10101010,
//N
0b00000000,
0b11001100,
0b10101010,
0b10101010,
0b10101010,
//O
0b01000100,
0b10101010,
0b10101010,
0b10101010,
0b01000100,
//P
0b11101110,
0b10101010,
0b11101110,
0b10001000,
0b10001000,
//Q
0b01000100,
0b10101010,
0b10101010,
0b11101110,
0b01100110,
//R
0b11101110,
0b10101010,
0b11001100,
0b11101110,
0b10101010,
//S
0b11101110,
0b10001000,
0b11101110,
0b00100010,
0b11101110,
//T
0b11101110,
0b01000100,
0b01000100,
0b01000100,
0b01000100,
//U
0b10101010,
0b10101010,
0b10101010,
0b10101010,
0b11101110,
//V
0b10101010,
0b10101010,
0b10101010,
0b10101010,
0b01000100,
//W
0b10101010,
0b10101010,
0b11101110,
0b11101110,
0b10101010,
//X
0b00000000,
0b10101010,
0b01000100,
0b01000100,
0b10101010,
//Y
0b10101010,
0b10101010,
0b01000100,
0b01000100,
0b01000100,
//Z
0b11101110,
0b00100010,
0b01000100,
0b10001000,
0b11101110
};
//==================================
//This is the sync generator and raster generator.
It MUST be entered from
//sleep mode to get accurate timing of the sync
pulses
#pragma warn-
interrupt [TIM1_COMPA] void t1_cmpA(void)
begin
//start the
Horizontal sync pulse
PORTD =
syncON;
//update
the curent scanline number
LineCount++;
//begin
inverted (Vertical) synch after line 247
if
(LineCount==248)
begin
syncON =
0b00100000;
syncOFF =
0;
end
//back to
regular sync after line 250
if
(LineCount==251)
begin
syncON =
0;
syncOFF =
0b00100000;
end
//start new
frame after line 262
if
(LineCount==263)
begin
LineCount = 1;
end
delay_us(2); //adjust to make 5 us pulses
//end sync
pulse
PORTD =
syncOFF;
if
(LineCount<ScreenBot && LineCount>=ScreenTop)
begin
//compute byte index for beginning of the next line
//left-shift 4 would be individual lines
//
<<3 means line-double the pixels
//The
0xfff8 truncates the odd line bit
//i=(LineCount-ScreenTop)<<3 & 0xfff8; //
#asm
push
r16
lds r12, _LineCount
lds r13, _Linecount+1
ldi r16, 30
sub r12, r16
ldi r16,0
sbc r13, r16
lsl r12
rol r13
lsl r12
rol r13
lsl r12
rol r13
mov r16,r12
andi
r16,0xf0
mov r12,r16
pop
r16
#endasm
//load
16 registers with screen info
#asm
push
r14
push
r15
push
r16
push
r17
push r18
push
r19
push
r26
push
r27
ldi r26,low(_screen) ;base address of screen
ldi r27,high(_screen)
add r26,r12 ;offset into screen (add i)
adc r27,r13
ld r4,x+ ;load 16 registers and inc pointer
ld r5,x+
ld r6,x+
ld r7,x+
ld r8,x+
ld r9,x+
ld r10,x+
ld r11,x+
ld r12,x+
ld r13,x+
ld r14,x+
ld r15,x+
ld
r16,x+
ld r17,x+
ld r18,x+
ld r19,x
pop r27
pop r26
#endasm
delay_us(4); //adjust to center
image on screen
//blast 16 bytes to the screen
#asm
;but first a macro to make the code
shorter
;the
macro takes a register number as a parameter
;and
dumps its bits serially to portD.6
;the
nop can be eliminated to make the display narrower
.macro
videobits ;regnum
BST
@0,7
IN R30,0x12
BLD R30,6
nop
OUT 0x12,R30
BST @0,6
IN R30,0x12
BLD R30,6
nop
OUT 0x12,R30
BST @0,5
IN R30,0x12
BLD R30,6
nop
OUT 0x12,R30
BST @0,4
IN R30,0x12
BLD R30,6
nop
OUT 0x12,R30
BST @0,3
IN R30,0x12
BLD R30,6
nop
OUT 0x12,R30
BST @0,2
IN R30,0x12
BLD R30,6
nop
OUT 0x12,R30
BST @0,1
IN R30,0x12
BLD R30,6
nop
OUT 0x12,R30
BST @0,0
IN R30,0x12
BLD R30,6
nop
OUT 0x12,R30
.endm
videobits
r4 ;video line -- byte 1
videobits r5 ;byte 2
videobits r6 ;byte 3
videobits r7 ;byte 4
videobits r8 ;byte 5
videobits r9 ;byte 6
videobits r10 ;byte 7
videobits r11 ;byte 8
videobits r12 ;byte 9
videobits r13 ;byte 10
videobits r14 ;byte 11
videobits r15 ;byte 12
videobits r16 ;byte 13
videobits r17 ;byte 14
videobits r18 ;byte 15
videobits r19 ;byte 16
clt ;clear video after the last pixel on the
line
IN R30,0x12
BLD R30,6
OUT 0x12,R30
pop
r19
pop
r18
pop
r17
pop
r16
pop
r15
pop
r14
#endasm
end
end
#pragma warn+
//==================================
//plot one point
//at x,y with color 1=white 0=black 2=invert
#pragma warn-
void video_pt(char x, char y, char c)
begin
#asm
; i=(x>>3) + ((int)y<<4) ; the byte with the pixel in it
push
r16
ldd
r30,y+2 ;get x
lsr r30
lsr r30
lsr
r30 ;divide
x by 8
ldd
r12,y+1 ;get y
lsl r12 ;mult
y by 16
clr r13
lsl r12
rol r13
lsl r12
rol r13
lsl r12
rol r13
add
r12, r30 ;add in x/8
;v2 =
screen[i]; r5
;v3 =
pos[x & 7]; r6
;v4 =
c r7
ldi
r30,low(_screen)
ldi
r31,high(_screen)
add
r30, r12
adc
r31, r13
ld
r5,Z ;get
screen byte
ldd
r26,y+2 ;get x
ldi
r27,0
andi
r26,0x07 ;form x & 7
ldi
r30,low(_pos*2)
ldi
r31,high(_pos*2)
add
r30,r26
adc
r31,r27
lpm
r6,Z
ld
r16,y ;get c
;if
(v4==1) screen[i] = v2 | v3 ;
;if
(v4==0) screen[i] = v2 & ~v3;
;if
(v4==2) screen[i] = v2 ^ v3 ;
cpi
r16,1
brne
tst0
or r5,r6
tst0:
cpi
r16,0
brne
tst2
com r6
and
r5,r6
tst2:
cpi
r16,2
brne
writescrn
eor
r5,r6
writescrn:
ldi r30,low(_screen)
ldi
r31,high(_screen)
add
r30, r12
adc
r31, r13
st Z,
r5 ;write the byte back to the screen
pop r16
#endasm
end
#pragma warn+
//==================================
// put a big character on the screen
// c is index into bitmap
void video_putchar(char x, char y, char c)
begin
v7 = x;
for (v6=0;v6<7;v6++)
begin
v1 =
bitmap[c][v6];
v8 =
y+v6;
video_pt(v7, v8, (v1 &
0x80)==0x80);
video_pt(v7+1, v8, (v1 & 0x40)==0x40);
video_pt(v7+2, v8, (v1 & 0x20)==0x20);
video_pt(v7+3, v8, (v1 & 0x10)==0x10);
video_pt(v7+4, v8, (v1 & 0x08)==0x08);
end
end
//==================================
// put a string of big characters on the screen
void video_puts(char x, char y, char *str)
begin
char i
;
for
(i=0; str[i]!=0; i++)
begin
if
(str[i]>=0x30 && str[i]<=0x3a)
video_putchar(x,y,str[i]-0x30);
else
video_putchar(x,y,str[i]-0x40+9);
x
= x+6;
end
end
//==================================
// put a string of big characters from flash on the
screen
void video_putsf(char x, char y, flash char *str)
begin
char i
;
for
(i=0; str[i]!=0; i++)
begin
if
(str[i]>=0x30 && str[i]<=0x3a)
video_putchar(x,y,str[i]-0x30);
else
video_putchar(x,y,str[i]-0x40+9);
x
= x+6;
end
end
//==================================
// put a small character on the screen
// x-cood must be on divisible by 4
// c is index into bitmap
void video_smallchar(char x, char y, char c)
begin
char
mask;
i=((int)x>>3)
+ ((int)y<<4) ;
if (x
== (x & 0xf8)) mask = 0x0f; //f8
else
mask = 0xf0;
screen[i]
= (screen[i] & mask) |
(smallbitmap[c][0] & ~mask);
screen[i+16] = (screen[i+16] & mask) |
(smallbitmap[c][1] & ~mask);
screen[i+32] = (screen[i+32] & mask) | (smallbitmap[c][2] &
~mask);
screen[i+48] = (screen[i+48] & mask) | (smallbitmap[c][3] &
~mask);
screen[i+64] = (screen[i+64] & mask) |
(smallbitmap[c][4] & ~mask);
end
//==================================
// put a string of small characters on the screen
// x-cood must be on divisible by 4
void video_putsmalls(char x, char y, char *str)
begin
char i
;
for
(i=0; str[i]!=0; i++)
begin
if
(str[i]>=0x30 && str[i]<=0x3a)
video_smallchar(x,y,str[i]-0x30);
else
video_smallchar(x,y,str[i]-0x40+12);
x
= x+4;
end
end
//==================================
// put a string of small characters from flash on
the screen
// x-cood must be on divisible by 4
void video_putsmallsf(char x, char y, flash char
*str)
begin
char i
;
for
(i=0; str[i]!=0; i++)
begin
if
(str[i]>=0x30 && str[i]<=0x3a)
video_smallchar(x,y,str[i]-0x30);
else
video_smallchar(x,y,str[i]-0x40+12);
x
= x+4;
end
end
//==================================
// put a city on the screen
// c is index into bitmap
void video_putcity(char x, char y, char c)
begin
v7 = x;
for
(v6=0;v6<8;v6++)
begin
vint
= cities[c][v6];
v8 =
y+v6;
video_pt(v7, v8, (vint &
0x8000)==0x8000);
video_pt(v7+1, v8, (vint & 0x4000)==0x4000);
video_pt(v7+2, v8, (vint & 0x2000)==0x2000);
video_pt(v7+3, v8, (vint & 0x1000)==0x1000);
video_pt(v7+4, v8, (vint & 0x800)==0x800);
video_pt(v7+5, v8, (vint & 0x400)==0x400);
video_pt(v7+6, v8, (vint & 0x200)==0x200);
video_pt(v7+7, v8, (vint & 0x100)==0x100);
video_pt(v7+8, v8, (vint & 0x80)==0x80);
video_pt(v7+9, v8, (vint & 0x40)==0x40);
video_pt(v7+10, v8, (vint & 0x20)==0x20);
video_pt(v7+11, v8, (vint & 0x10)==0x10);
video_pt(v7+12, v8, (vint & 0x08)==0x08);
video_pt(v7+13, v8, (vint & 0x04)==0x04);
video_pt(v7+14, v8, (vint & 0x02)==0x02);
video_pt(v7+15, v8, (vint & 0x01)==0x01);
end
end
//==================================
//plot a line
//at x1,y1 to x2,y2 with color 1=white 0=black
2=invert
//NOTE: this function requires signed chars
//Code is from David Rodgers,
//"Procedural Elements of Computer
Graphics",1985
void video_line(char x1, char y1, char x2, char y2,
char c)
begin
int e;
signed
char dx,dy,j, temp;
signed
char s1,s2, xchange;
signed char x,y;
x = x1;
y = y1;
dx =
cabs(x2-x1);
dy =
cabs(y2-y1);
s1 =
csign(x2-x1);
s2 =
csign(y2-y1);
xchange
= 0;
if
(dy>dx)
begin
temp
= dx;
dx
= dy;
dy
= temp;
xchange
= 1;
end
e =
((int)dy<<1) - dx;
for
(j=0; j<=dx; j++)
begin
video_pt(x,y,c)
;
if
(e>=0)
begin
if
(xchange==1) x = x + s1;
else
y = y + s2;
e
= e - ((int)dx<<1);
end
if
(xchange==1) y = y + s2;
else
x = x + s1;
e
= e + ((int)dy<<1);
end
end
//==================================
//return the value of one point
//at x,y with color 1=white 0=black 2=invert
char video_set(char x, char y)
begin
//The
following construction
//detects exactly one bit at the x,y location
i=((int)x>>3)
+ ((int)y<<4) ;
return (
screen[i] & 1<<(7-(x & 0x7)));
end
//==================================
// set up the ports and timers
void initialize(void)
begin
//init
timer 1 to generate sync
OCR1A =
lineTime; //One NTSC line
TCCR1B = 9;
//full speed; clear-on-match
TCCR1A =
0x00; //turn off pwm and oc lines
TIMSK =
0x10; //enable interrupt T1 cmp
//init
ports
DDRD =
0xf0; //video out and switches
//D.5 is
sync:1000 ohm + diode to 75 ohm resistor
//D.6 is
video:330 ohm + diode to 75 ohm resistor
DDRB =
0x00;
DDRC =
0x00;
//initialize synch constants
LineCount =
1;
syncON =
0b00000000;
syncOFF =
0b00100000;
//side
lines
video_line(0,0,0,99,1);
video_line(width,0,width,99,1);
//top line
& bottom lines
video_line(0,0,width,0,1);
video_line(0,99,width,99,1);
video_line(0,11,width,11,1);
video_line(0,89,width,89,1);
//Print
"MISSILE COMMAND"
video_putsf(15,2,cu1);
video_putsf(64,2,cu2);
//Print
"SCORE" and "HIGH"
score = 0;
video_putsmallsf(4,92,scorestr);
video_putsmallsf(72,92,highstr);
sprintf(tempstr,"%08d",highscore); // Convert score to string
video_putsmalls(92,92,tempstr);
//init
software timer
t=0;
time=0;
m_index=0;
c_index=0;
i_index=0;
//init
variables
printcount=0;
gamestate=PRNT_INTRO;
justfired =
1;
icount = 0;
//init
cursor
curx = 64;
cury=50;
video_pt(curx+1,cury,2);
video_pt(curx-1,cury,2);
video_pt(curx,cury+1,2);
video_pt(curx,cury-1,2);
//enable
sleep mode
MCUCR =
0b10000000;
#asm
("sei");
end
//------------------------------------------------------------
void main(void)
begin
initialize();
// Begin
Game
//The
following loop executes once/video line during lines
//1-230,
then does all of the frame-end processing
while(1)
begin
//stall
here until next line starts
//sleep
enable; mode=idle
//use
sleep to make entry into sync ISR uniform time
#asm
("sleep");
//generates a quasi random from 1-20 by counting once per line.
//must
divide the result by 2 (before using), or else we would only get 1,3,5, ect
//in the
linecount == 231 code, because both 10 and 262 are divisable by 2
fastcount++;
if
(fastcount == 20)
fastcount = 0;
//another
quasirandom counter
fastcount2++;
if
(fastcount2 == 249)
fastcount2 = 0;
//The
following code executes during the vertical blanking
//Code
here can be as long as
//a total
of 60 lines x 63.5 uSec/line x 8 cycles/uSec
if
(LineCount==231)
begin
//erase old cursor (redrawn AFTER
updating the screen
if (curx>1 &&
curx<width-1 && cury<=87 && cury>=13)
begin
video_pt(curx+1,cury,2);
video_pt(curx-1,cury,2);
video_pt(curx,cury+1,2);
video_pt(curx,cury-1,2);
end
curx
= PINB; //Get
x-coordinate from mouse
cury = PINC; //Get y-coordinate from mouse
switch (gamestate)
begin
case PRNT_INTRO:
// Only Print Part of the Menu in
any one Frame
switch (printcount)
begin
case 0:
// All Cities are Healthy (Healthy=2,
Wounded=1, Dead=0)
deadcities = 0;
icount = 0;
for (temp=0;
temp<citycount; temp++)
cstatus[temp]
= 2;
//All
interceptor are ready (ready = 0, detonating (second stage) = 1-4, detonating
(first stage) = 5-6, in flight = 7)
for(temp=0;
temp<max_intercept; temp++)
istatus[temp]
= 0;
//All Missiles
are ready (ready = 0, detonated >= 49, in flight = 50)
for(temp=0;
temp<max; temp++)
mstatus[temp]
= 0;
score = 0;
sprintf(tempstr,"%08d",score); // Convert score to string
video_putsmalls(28,92,tempstr);
break;
case
1:
//Print
"Click Mouse to Begin"
video_putsmallsf(36,50,clb);
gamestate=GET_INTRO;
break;
end
printcount++;
break;
case GET_INTRO:
printcount=0;
// Check for button press
if (PIND.2)
begin
gamestate=PRNT_DIF;
video_line(32,50,76,50,0);
video_line(32,51,76,51,0);
video_line(32,52,76,52,0);
video_line(32,53,76,53,0);
video_line(32,54,76,54,0);
end
break;
case PRNT_DIF:
// Print Menu
if
(printcount == 0)
begin
video_putsf(30,30,diff);
printcount++;
end
else
if (printcount==1)
begin
video_pt(30,43,1);
video_putsf(32,40,easy);
printcount++;
end
else
begin
video_pt(30,53,1);
video_pt(30,63,1);
video_putsf(32,50,med);
video_putsf(32,60,hard);
printcount=11; //
Prepare for clear screen
justfired
= 1;
gamestate=GET_DIF;
end
break;
case GET_DIF:
if (!PIND.2) //look for mouse button release
justfired
= 0;
if (PIND.2 && !justfired)
begin
if
(curx>=30 && curx<70)
begin
if
(cury>=40 && cury<=49) level=1;
else
if
(cury>=50 && cury<=59) level=2;
else
if (cury>=60 && cury<=69) level=3;
//
difficulty level detemines number of missiles per wave (mpw)
switch
(level)
begin
case
1: mpw=4; break;
case 2: mpw=6; break;
case
3: mpw=8; break;
end
gamestate=GAME_INIT;
justfired
= 1;
justfiredr
= 0;
end
end
break;
case GAME_INIT: // Clear Screen
if (printcount<=85)
begin
video_line(1,printcount+1,width-1,printcount+1,0);
video_line(1,printcount+2,width-1,printcount+2,0);
video_line(1,printcount+3,width-1,printcount+3,0);
printcount=printcount+3;
end
else
begin
gamestate=RUN_GAME;
printcount=0;
end
break;
case RUN_GAME:
// VIDEO GENERATION
SCHEME
// UPDATE/DRAW ONLY
if (!PIND.2) //check for mouse
button release
justfired = 0;
if
(!PIND.1)
justfiredr = 0;
// Check for Right-button click
(Pause/Exit)
if (PIND.1 && !justfiredr)
begin
justfiredr = 1;
gamestate=PAUSE; // Can be overwritten in frame by
GAME_OVER
end
// INTERCEPTOR SCHEME
switch (istatus[i_index])
begin
case 0:
// Generate One Interceptor
if (PIND.2 &&
icount<max_intercept && !justfired)
begin
justfired
= 1; // so we will wait for release to fire another
//
Interceptor Target Location
ixf[i_index]=
curx;
iyf[i_index]
= cury-2;
//
Determine which box mouse coordinates fall into
//
Determine xbox # and ybox #
ybox[i_index]
= (char)(26-((cury-13)/3))-1;
xbox[i_index]
= (char)(curx/3)-1;
//
Interceptor Launch Location
ix[i_index]=66;
iy[i_index]=89;
//
Current Interceptor Position = Interceptor Launch Location
ixp[i_index]=66;
iyp[i_index]=89;
ixp_long[i_index]
= 0x4200;
iyp_long[i_index]
= 0x5900;
istatus[i_index]=7; // Interceptor is Alive (Alive=7, Partial
Detonation=5-6, Full Det=1-4 Dead=0)
icount++; // Interceptors Fired
end
break;
case 1:
//interceptor done exploding
// Draw Interceptor
Explosion
v7
= ixp[i_index];
for
(v6=0;v6<5;v6++)
begin
v8 = iyp[i_index]+v6;
video_pt(v7+2, v8, 0);
video_pt(v7+1, v8, 0);
video_pt(v7, v8, 0);
video_pt(v7-1, v8, 0);
video_pt(v7-2, v8, 0);
end
// decrement state
istatus[i_index]--;
//give
user an interceptor back
icount--;
break;
case
2:
case
3:
case
4:
case
6:
istatus[i_index]--;
break;
case 5:
//interceptor exploding
// Draw Interceptor
Explosion
v7
= ixp[i_index];
for
(v6=0;v6<5;v6++)
begin
v1 = explosion[1][v6];
v8 = iyp[i_index]+v6;
video_pt(v7+2, v8, (v1 &
0x10)==0x10);
video_pt(v7+1, v8, (v1 &
0x08)==0x08);
video_pt(v7, v8, (v1 & 0x04)==0x04);
video_pt(v7-1, v8, (v1 & 0x02)==0x02);
video_pt(v7-2, v8, (v1 &
0x01)==0x01);
end
// decrement state
istatus[i_index]--;
break;
case 7:
// For Alive
Interceptor
video_pt(ixp[i_index],iyp[i_index],0);
// Update Interceptor Position
ixp_long[i_index]=ixp_long[i_index]+(ivx[xbox[i_index]][ybox[i_index]]<<1);
iyp_long[i_index]=iyp_long[i_index]-(ivy[xbox[i_index]][ybox[i_index]]<<1);
ixp[i_index]=(char)(ixp_long[i_index]>>8);
iyp[i_index]=(char)(iyp_long[i_index]>>8);
//iyp[i_index]--;
//
Draw Current Interceptor Position
video_pt(ixp[i_index],iyp[i_index],1);
//
Check Interceptor Target Location
if
(iyp[i_index]<=iyf[i_index])
begin
//
Draw Interceptor Explosion
v7
= ixp[i_index];
for
(v6=0;v6<5;v6++)
begin
v1 = explosion[0][v6];
v8 = iyp[i_index]+v6;
video_pt(v7+2, v8, (v1 &
0x10)==0x10);
video_pt(v7+1, v8, (v1 &
0x08)==0x08);
video_pt(v7, v8, (v1 & 0x04)==0x04);
video_pt(v7-1, v8, (v1 &
0x02)==0x02);
video_pt(v7-2, v8, (v1 &
0x01)==0x01);
end
//
decrement state
istatus[i_index]--;
end
break;
end
//end switch (istatus[i_index])
video_pt(66,
89, 1); //redraw
pixel that sometimes gets cleared by interceptors
//
CITY SCHEME
temp=2-cstatus[c_index];
video_putcity(cx[c_index],81,temp);
//
MISSILE SCHEME
switch
(mstatus[m_index])
begin
case
0: //generate a missile
if
(m_index<mpw)
begin
//Missile
Launch angle (angle in degrees = 45 - 10*m_theta[m_index])
m_theta[m_index]
= fastcount>>1; //use quasi random
number, but divide by 2 to get number from 0-9
//
Missile Launch Location
//
Start x0-coordinate
//
random number limited to the values that will have the missile land on screen
mx[m_index]=start_min[m_theta[m_index]]+(fastcount2%(del_start[m_theta[m_index]]));
//
Start y0-coordinate
my[m_index]=13;
//
Current Missile Position = Missile Launch Location
mxp[m_index]=mx[m_index];
myp[m_index]=13;
mxp_long[m_index]
= ((int)(mx[m_index]))<<8;
myp_long[m_index]
= 0xd00;
mstatus[m_index]
= 50;
mtimer[m_index]=time2gnd[level];
end
break;
// For Alive Missile
case 50:
//erase end of missile tail
video_pt(mxp[m_index],myp[m_index],0);
// Update Missile
Position
mxp_long[m_index]=mxp_long[m_index]+mvx[m_theta[m_index]][level];
myp_long[m_index]=myp_long[m_index]+mvy[level];
mxp[m_index]=(char)(mxp_long[m_index]>>8);
myp[m_index]=(char)(myp_long[m_index]>>8);
temp2
= 1;
//
Check Missile Explosion Conditions
//
1.
if
(myp[m_index] > 80 && video_set(mxp[m_index],myp[m_index]))
begin
//
Determine Which City Was Hit
temp=0;
for(temp
= 0; temp<citycount; temp++)
begin
if
((mxp[m_index] > cx[temp]) && (mxp[m_index] < cx[temp]+16)
&& (cstatus[temp]!=0)) //found the hit city
begin
cstatus[temp]--;
mstatus[m_index]=1;
//set missile status to detonated
if (cstatus[temp]==0) deadcities++;
end
end
end
// 2. Check All Interceptors For Impact
for
(temp=1;temp<=max_intercept;temp++)
begin
if (istatus[temp]
== 7) //
Interceptor is Alive
begin
if((mxp[m_index]
<= ixp[temp]+1) && (myp[m_index] <= iyp[temp]+1) &&
(mxp[m_index] >= ixp[temp]-1) && (myp[m_index] >=
iyp[temp]-1))
begin
mstatus[m_index]--; //set missile status to destroyed
temp2
= 0; //dont redraw
the missile
score
= score + 10*level; // Update Score for
Successful Intercept
istatus[temp]
= 6;
end
end
if
((istatus[temp]) < 7 && (istatus[temp] > 4)) // Interceptor Partially Detonated
begin
if((mxp[m_index]
<= ixp[temp]+3) && (myp[m_index] <= iyp[temp]+3) && (mxp[m_index]
>= ixp[temp]-3) && (myp[m_index] >= iyp[temp]-3))
begin
mstatus[m_index]--; //set missile status to destroyed
temp2
= 0; //dont redraw
the missile
score
= score + 10*level; // Update Score for
Successful Intercept
end
end
if
((istatus[temp]) < 5 && (istatus[temp] > 0)) // Interceptor Fully Detonated
begin
if((mxp[m_index]
<= ixp[temp]+5) && (myp[m_index] <= iyp[temp]+5) &&
(mxp[m_index] >= ixp[temp]-5) && (myp[m_index] >=
iyp[temp]-5))
begin
mstatus[m_index]--; //set missile status to destroyed
temp2
= 0; //dont redraw
the missile
score
= score + 10*level; // Update Score for
Successful Intercept
end
end
end
// 3. Check All Exploding Missiles For
Impact
for (temp=1;temp<=max;temp++)
begin
if
((mstatus[temp] > 42) && (mstatus[temp] < 50) &&
temp2) // Other Missile is Exploding and
we havent already counted this missile as dead
begin
if((mxp[m_index]
<= mxp[temp]+5) && (myp[m_index] <= myp[temp]+5) &&
(mxp[m_index] >= mxp[temp]-5) && (myp[m_index] >=
myp[temp]-5))
begin
mstatus[m_index]--; //set missile status to destroyed
temp2
= 0; //dont redraw
the missile
score
= score + 20*level; // Update Score for
Successful Intercept
end
end
end
//
Draw Current Missile Position
//video_line(mx[index],my[index],mxp[index],mxy[index],1);
video_pt(mxp[m_index],myp[m_index],temp2);
break;
//mstatus == 50
case 49:
//
Draw Missile Explosion
v7 =
mxp[m_index];
for
(v6=0;v6<5;v6++)
begin
v1 = explosion[1][v6];
v8 = myp[m_index]+v6;
video_pt(v7+2, v8, (v1 &
0x10)==0x10);
video_pt(v7+1, v8, (v1 & 0x08)==0x08);
video_pt(v7, v8, (v1 &
0x04)==0x04);
video_pt(v7-1, v8, (v1 & 0x02)==0x02);
video_pt(v7-2, v8, (v1 & 0x01)==0x01);
end
// decrement state
mstatus[m_index]--;
break;
case 43:
//
Erase Missile Explosion
v7 =
mxp[m_index];
for
(v6=0;v6<5;v6++)
begin
v8 = myp[m_index]+v6;
video_pt(v7+2, v8, 0);
video_pt(v7+1, v8, 0);
video_pt(v7, v8, 0);
video_pt(v7-1, v8, 0);
video_pt(v7-2, v8, 0);
end
// decrement state
mstatus[m_index]--;
break;
default:
mstatus[m_index]--;
end // switch
(mstatus[m_index])
//Print score
sprintf(tempstr,"%08d",score); //
Convert score to string
video_putsmalls(28,92,tempstr);
//
CHECK GAMEOVER
if (deadcities==citycount)
gamestate=PRNT_GAMEOVER;
else //decrement couters for missiles, etc
begin
if
(mtimer[m_index]==0) //check if missile
has reached ground
mstatus[m_index]=0;
mtimer[m_index]--;
if
(c_index == citycount-1)
c_index = 0;
else
c_index++;
if
(m_index == max-1)
m_index = 0;
else
m_index++;
if
(i_index == max_intercept-1)
i_index
= 0;
else
i_index++;
end
break; // END CASE 'RUN_GAME'
case PRNT_GAMEOVER:
video_putsf(48,15,lose);
// Check High Score Condition
if
(score>highscore)
highscore=score;
sprintf(tempstr,"%08d",highscore); // Convert score to string
video_putsmalls(92,92,tempstr);
gamestate = GET_GAMEOVER;
justfired
= 0;
printcount = 88;
break;
case GET_GAMEOVER:
if
(printcount>=25)
begin
printcount--;
if (printcount>=80)
video_line(130-printcount,printcount,70+(printcount-80),printcount,1);
else if(printcount>=55)
video_line(50,printcount,70,printcount,1);
else
if(printcount>=50)
video_line(50-4*(55-printcount),printcount,70+4*(55-printcount),printcount,1);
else if(printcount>=30)
video_line(30,printcount,90,printcount,1);
else
video_line(50-4*(printcount-25),printcount,70+4*(printcount-25),printcount,1);
end
else
begin
// Check Left Button Press
if
(PIND.2)
begin
printcount = 11;
gamestate=RESTART; // Restart Game
end
end
break;
case RESTART: //print count must equal
11 on entry
if
(printcount<=85)
begin
video_line(1,printcount+1,width-1,printcount+1,0);
video_line(1,printcount+2,width-1,printcount+2,0);
video_line(1,printcount+3,width-1,printcount+3,0);
printcount=printcount+3;
end
else
begin
video_line(1,87,width-1,87,0);
video_line(1,88,width-1,88,0);
gamestate=PRNT_INTRO;
printcount=0;
end
break;
case
PAUSE:
if
(!PIND.1) //look for release of rt btn
justfiredr
= 0;
if
(PIND.1 && !justfiredr)
begin
justfiredr
= 1;
gamestate=RUN_GAME;
//
Clear E
video_line(3,13,8,13,0);
video_line(3,14,8,14,0);
video_line(3,15,8,15,0);
video_line(3,16,8,16,0);
video_line(3,17,8,17,0);
video_line(3,18,8,18,0);
video_line(3,19,8,19,0);
//
Clear P
video_line(120,2,125,2,0);
video_line(120,3,125,3,0);
video_line(120,4,125,4,0);
video_line(120,5,125,5,0);
video_line(120,6,125,6,0);
video_line(120,7,125,7,0);
video_line(120,8,125,8,0);
end
else
if (PIND.2==1 && curx<=7 && cury<=19)
begin
//
Check High Score Condition
if
(score>highscore)
highscore=score;
gamestate=RESTART; //clear screen and restart
//
Clear P
video_line(120,2,125,2,0);
video_line(120,3,125,3,0);
video_line(120,4,125,4,0);
video_line(120,5,125,5,0);
video_line(120,6,125,6,0);
video_line(120,7,125,7,0);
video_line(120,8,125,8,0);
printcount
= 11;
end
else
begin
video_putsf(3,13,pmenu);
// 'E' for return to Menu option
video_putsf(120,2,paused); // 'P' to indicate game is paused
end
break;
end
// END SWITCH
//draw new cursor
if (curx>1 && curx<width-1
&& cury<=87 && cury>=13)
begin
video_pt(curx+1,cury,2);
video_pt(curx-1,cury,2);
video_pt(curx,cury+1,2);
video_pt(curx,cury-1,2);
end
end //line 231
end //while
end //main