home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
047.lha
/
WbLander
/
rocket.c
< prev
next >
Wrap
C/C++ Source or Header
|
1986-11-20
|
13KB
|
636 lines
#include <exec/types.h>
#include <exec/memory.h>
#include <intuition/intuition.h>
#include <graphics/sprite.h>
#include <hardware/custom.h>
#include <stdio.h>
#include <ctype.h>
#define INTUITION_REV 1
#define GRAPHICS_REV 1
#define SAUCERSPEED 200
#define SAUCERDELAY 200
#define ROCKETHEIGHT 16
#define SPRWIDTH 32
#define PIXRATIO 2
#define SCALEFACTOR 100
#define XMAX (640*SCALEFACTOR)
#define YMAX (200*SCALEFACTOR)
#define XMIN (-(SPRWIDTH/PIXRATIO)*SCALEFACTOR)
#define YMIN (-ROCKETHEIGHT*SCALEFACTOR)
#define OK 0
#define LANDED 1
#define CRASHEDGOOD 2
#define CRASHEDBAD 3
#define CRASHEDSAUCER 4
USHORT rocket_image[ROCKETHEIGHT*2] = {
0x0000, 0x0000,
0x0000, 0x0000,
0x0100, 0x0100,
0x0100, 0x0100,
0x0380, 0x0380,
0x0380, 0x0380,
0x07c0, 0x07c0,
0x07c0, 0x07c0,
0x0fe0, 0x0fe0,
0x0fe0, 0x0fe0,
0x0820, 0x0820,
0x0820, 0x0820,
0x0820, 0x0820,
0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000,
};
USHORT flame[3][ROCKETHEIGHT*2] = {
{
0x0000, 0x0000,
0x0000, 0x0000,
0x0100, 0x0100,
0x0100, 0x0100,
0x0380, 0x0380,
0x0380, 0x0380,
0x07c0, 0x07c0,
0x0fc0, 0x37c0,
0x0fe0, 0x0fe0,
0x0fe0, 0x0fe0,
0x0820, 0x0820,
0x0820, 0x0820,
0x0820, 0x0820,
0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000,
},
{
0x0000, 0x0000,
0x0000, 0x0000,
0x0100, 0x0100,
0x0100, 0x0100,
0x0380, 0x0380,
0x0380, 0x0380,
0x07c0, 0x07c0,
0x07e0, 0x07d8,
0x0fe0, 0x0fe0,
0x0fe0, 0x0fe0,
0x0820, 0x0820,
0x0820, 0x0820,
0x0820, 0x0820,
0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000,
},
{
0x0000, 0x0000,
0x0000, 0x0000,
0x0100, 0x0100,
0x0100, 0x0100,
0x0380, 0x0380,
0x0380, 0x0380,
0x07c0, 0x07c0,
0x07c0, 0x07c0,
0x0fe0, 0x0fe0,
0x0fe0, 0x0fe0,
0x0ba0, 0x0c60,
0x0920, 0x0ee0,
0x0920, 0x0aa0,
0x0000, 0x0380,
0x0000, 0x0100,
0x0000, 0x0100,
}
};
USHORT sprite_colors[3] = { 0x0f95, 0x0d44, 0x0fff };
#define SAUCERHEIGHT 5
USHORT saucer_image[3][SAUCERHEIGHT*2] = {
{
0x0ff0, 0x0ff0,
0xffff, 0xffff,
0xb6db, 0x6db6,
0xffff, 0xffff,
0x0ff0, 0x0ff0
},
{
0x0ff0, 0x0ff0,
0xffff, 0xffff,
0x6db6, 0xdb6d,
0xffff, 0xffff,
0x0ff0, 0x0ff0
},
{
0x0ff0, 0x0ff0,
0xffff, 0xffff,
0xdb6d, 0xb6db,
0xffff, 0xffff,
0x0ff0, 0x0ff0
}
};
UWORD *rbuf, *sbuf;
struct SimpleSprite rocket, saucer;
int rocket_sprite, saucer_sprite;
struct Window *window, *badwindow;
struct ViewPort *viewport;
struct Remember *Memory;
/* Intuition always wants to see these declarations */
struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
/* my window structure */
struct NewWindow NewWindow = {
160, 50,
240, 10,
0, 1,
INTUITICKS | CLOSEWINDOW | RAWKEY | ACTIVEWINDOW | INACTIVEWINDOW,
WINDOWCLOSE | SMART_REFRESH | ACTIVATE | WINDOWDRAG | WINDOWDEPTH,
NULL,
NULL,
"Workbench Lander",
NULL,
NULL,
0, 0,
0, 0,
WBENCHSCREEN,
};
struct NewWindow BadWindow = {
160, 11,
240, 10,
0, 1,
ACTIVEWINDOW | INACTIVEWINDOW | CLOSEWINDOW,
WINDOWCLOSE | SMART_REFRESH | WINDOWDRAG | WINDOWDEPTH,
NULL,
NULL,
"Don't land here...",
NULL,
NULL,
0, 0,
0, 0,
WBENCHSCREEN,
};
struct IntuiMessage *NewMessage;
/******************************************************/
/* Main Program */
/* */
/* This is the main body of the program. */
/******************************************************/
int x, y, vx, vy, ax, ay;
int buttons = 0;
char *cycle[] = {
"Workbench Lander",
"Use cursor keys to",
"Land on this window",
"Workbench Lander",
"Don't hit too hard",
"Workbench Lander",
"Don't fall over",
"Workbench Lander",
"Don't get caught",
"Workbench Lander",
"Space is big",
"Space is dark",
"It's hard to find",
"A place to park",
"BURMA SHAVE",
"Workbench Lander",
"Another fine hack",
"by Peter da Silva",
0
};
addflame(n)
int n;
{
buttons |= n;
recalc_rocket();
}
delflame(n)
int n;
{
buttons &= ~n;
recalc_rocket();
}
recalc_rocket()
{
int b, i;
rbuf[0] = rbuf[1] = 0;
for(i = 0; i < 2*ROCKETHEIGHT; i++)
rbuf[i+2] = rocket_image[i];
rbuf[2*ROCKETHEIGHT+2] = 0;
rbuf[2*ROCKETHEIGHT+3] = 0;
for(b = 0; b < 3; b++)
if(buttons & (1<<b))
for(i = 0; i < 2*ROCKETHEIGHT; i++)
rbuf[i+2] |= flame[b][i];
ChangeSprite(viewport, &rocket, rbuf);
}
set_saucer(n)
int n;
{
int i;
sbuf[0] = sbuf[1] = 0;
for(i = 0; i < 2*SAUCERHEIGHT; i++)
sbuf[i+2] = saucer_image[n][i];
sbuf[2*SAUCERHEIGHT+2] = 0;
sbuf[2*SAUCERHEIGHT+3] = 0;
ChangeSprite(viewport, &saucer, sbuf);
}
#define BEGIN_EXPLOSION 0
#define IN_EXPLOSION 1
#define END_EXPLOSION 2
int exploding;
int coloregs;
int counter;
int KeepGoing;
int timeout;
int cycle_position, cycle_timeout;
int saucer_timeout, saucer_x, saucer_y, saucer_cycle, saucer_up;
explode()
{
int i;
if(!exploding) {
counter = 21;
exploding = 1;
}
if(counter-- < 0) {
exploding = 0;
x = y = 200;
vx = 100;
vy = 0;
ax = 0;
ay = 10;
saucer_timeout = SAUCERDELAY;
timeout = 10;
for(i = 0; i < 3; i++)
SetRGB4(viewport, coloregs+1+i,
sprite_colors[i]&0x000F,
(sprite_colors[i]&0x00F0)>>4,
(sprite_colors[i]&0x0F00)>>8);
} else {
for(i = 0; i < 3; i++)
SetRGB4(viewport, coloregs+1+i,
RangeRand(16),
RangeRand(16),
RangeRand(16));
}
}
main()
{
int i;
Memory = NULL;
IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", INTUITION_REV);
if( IntuitionBase == NULL )
{
puts("can't open intuition\n");
cleanup_and_exit(50);
}
GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",GRAPHICS_REV);
if( GfxBase == NULL )
{
puts("can't open graphics library\n");
cleanup_and_exit(50);
}
if(( window = (struct Window *)OpenWindow(&NewWindow) ) == NULL)
{
puts("can't open window\n");
cleanup_and_exit(50);
}
if(( badwindow = (struct Window *)OpenWindow(&BadWindow) ) == NULL)
{
puts("can't open obstacle\n");
cleanup_and_exit(50);
}
viewport = ViewPortAddress(window);
if((rocket_sprite = GetSprite(&rocket, 2)) == -1)
if((rocket_sprite = GetSprite(&rocket, 4)) == -1)
if((rocket_sprite = GetSprite(&rocket, 6)) == -1) {
puts("can't get rocket_sprite\n");
cleanup_and_exit(50);
}
if((saucer_sprite = GetSprite(&saucer, rocket_sprite+1)) == -1) {
puts("can't get saucer_sprite\n");
cleanup_and_exit(50);
}
rocket.x = 0;
rocket.y = 0;
rocket.height = ROCKETHEIGHT;
saucer.x = 0;
saucer.y = 0;
saucer.height = SAUCERHEIGHT;
coloregs = ((rocket_sprite & 0x06)*2)+16;
for(i = 0; i < 3; i++)
SetRGB4(viewport, coloregs+1+i,
sprite_colors[i]&0x000F,
(sprite_colors[i]&0x00F0)>>4,
(sprite_colors[i]&0x0F00)>>8);
if(!(rbuf = AllocRemember(&Memory, 4L * ROCKETHEIGHT + 8L, MEMF_CHIP)))
cleanup_and_exit(50);
if(!(sbuf = AllocRemember(&Memory, 4L * SAUCERHEIGHT + 8L, MEMF_CHIP)))
cleanup_and_exit(50);
buttons = 0;
recalc_rocket();
set_saucer(0);
KeepGoing = TRUE;
timeout = 0;
cycle_timeout = 10;
cycle_position = 0;
saucer_timeout = SAUCERDELAY;
saucer_up = 0;
MoveSprite(viewport, &saucer, -20, -20);
SetWindowTitles(window, -1, "Workbench Lander (C) 1987 by Peter da Silva");
x = y = 200;
vx = 100;
vy = 0;
ax = 0;
ay = 10;
MoveSprite(viewport, &rocket, x/SCALEFACTOR, y/SCALEFACTOR);
while( KeepGoing )
{
Wait((1 << window->UserPort->mp_SigBit) |
(1 << badwindow->UserPort->mp_SigBit));
WaitTOF();
while( NewMessage=(struct IntuiMessage *)GetMsg(badwindow->UserPort) )
{
ReplyMsg( NewMessage );
switch( NewMessage->Class )
{
case CLOSEWINDOW:
KeepGoing = FALSE;
break;
case ACTIVEWINDOW:
SetWindowTitles(badwindow, "...or click here", -1);
break;
case INACTIVEWINDOW:
SetWindowTitles(badwindow, BadWindow.Title, -1);
break;
}
}
while( NewMessage=(struct IntuiMessage *)GetMsg(window->UserPort) )
{
ReplyMsg( NewMessage );
switch( NewMessage->Class )
{
case CLOSEWINDOW:
KeepGoing = FALSE;
break;
case RAWKEY:
switch(NewMessage -> Code) {
case 0x4C:
addflame(4);
ay = -40;
break;
case 0x4C|0x80:
delflame(4);
ay = 10;
break;
case 0x4E:
addflame(1);
ax = 10;
break;
case 0x4F|0x80:
delflame(3);
ax = 0;
break;
case 0x4E|0x80:
delflame(3);
ax = 0;
break;
case 0x4F:
addflame(2);
ax = -10;
break;
}
break;
case ACTIVEWINDOW:
SetWindowTitles(window, cycle[cycle_position], -1);
break;
case INACTIVEWINDOW:
SetWindowTitles(window, "Click me", -1);
break;
case INTUITICKS:
if(exploding) {
explode();
break;
}
if(timeout > 0) {
timeout--;
if(timeout == 0) {
SetWindowTitles(badwindow, BadWindow.Title, -1);
SetWindowTitles(window, cycle[cycle_position], -1);
cycle_timeout = 10;
}
} else if(timeout == 0) {
cycle_timeout--;
if(cycle_timeout <= 0) {
cycle_timeout = 10;
cycle_position++;
if(cycle[cycle_position]==0)
cycle_position = 0;
SetWindowTitles(window, cycle[cycle_position], -1);
}
}
if(saucer_timeout == 0) {
int dx, dy;
if(saucer_up == 0) {
saucer_up = 1;
saucer_x = 200;
saucer_y = 200;
saucer_cycle = 0;
}
set_saucer(saucer_cycle++);
if(saucer_cycle >= 3)
saucer_cycle = 0;
dx = dy = 0;
if(saucer_x < x-SAUCERSPEED)
dx = SAUCERSPEED;
else if(saucer_x > x+SAUCERSPEED)
dx = -SAUCERSPEED;
if(saucer_y < y-SAUCERSPEED)
dy = SAUCERSPEED;
else if(saucer_y > y+SAUCERSPEED)
dy = -SAUCERSPEED;
if(dy == 0) dx += dx/2;
if(dx == 0) dy += dy/2;
saucer_x += dx;
saucer_y += dy;
MoveSprite(viewport, &saucer,
saucer_x/SCALEFACTOR, saucer_y/SCALEFACTOR);
} else {
if(saucer_timeout != -1)
saucer_timeout--;
if(saucer_up) {
saucer_up = 0;
MoveSprite(viewport, &saucer, -20, -20);
}
}
x += vx;
y += vy;
vx += ax;
vy += ay;
if(x > XMAX) x = XMIN;
if(x < XMIN) x = XMAX;
if(y < YMIN) y = YMAX;
if(y > YMAX) y = YMIN;
switch(HitWindow()) {
case OK:
if(ay==0) {
ay = 10;
timeout = 10;
saucer_timeout = SAUCERDELAY;
}
break;
case LANDED:
if(vy >= -2*SCALEFACTOR && vy < 0) {
timeout = 10;
saucer_timeout = SAUCERDELAY;
break;
}
if(vy >= 0 && vy <= SCALEFACTOR &&
vx >= -20 && vx <= 20) {
if(timeout >= 0) {
if(vy <= 30 && vx == 0)
SetWindowTitles(window, "Great Landing!", -1);
else if(vy <= 70 && vx == 0)
SetWindowTitles(window, "Good Landing.", -1);
else
SetWindowTitles(window, "Just made it...", -1);
}
timeout = -1;
vx = vy = 0;
ax = ay = 0;
saucer_timeout = -1;
break;
}
case CRASHEDGOOD:
SetWindowTitles(window, "OUCH! That hurt!", -1);
explode();
break;
case CRASHEDBAD:
SetWindowTitles(badwindow, "OUCH! That hurt!", -1);
explode();
break;
case CRASHEDSAUCER:
SetWindowTitles(window, "GOTCHA!", -1);
explode();
break;
}
MoveSprite(viewport, &rocket,
x/SCALEFACTOR, y/SCALEFACTOR);
break;
} /* end of switch (class) */
} /* end of while ( newmessage )*/
} /* end while ( keepgoing ) */
cleanup_and_exit(0);
} /* end of main */
cleanup_and_exit(flag)
{
if(saucer_sprite > 0)
FreeSprite(saucer_sprite);
if(rocket_sprite > 0)
FreeSprite(rocket_sprite);
FreeRemember(&Memory, TRUE);
if(badwindow)
CloseWindow(badwindow);
if(window)
CloseWindow(window);
if(GfxBase)
CloseLibrary(GfxBase);
if(IntuitionBase)
CloseLibrary(IntuitionBase);
exit(flag);
}
HitWindow()
{
int sx = x/SCALEFACTOR;
int sy = y/SCALEFACTOR;
int ret;
ret = checkwindow(sx, sy, window, 1);
if(!ret)
ret = checkwindow(sx, sy, badwindow, 0);
if(!ret)
ret = checksaucer();
return ret;
}
checkwindow(sx, sy, window, canland)
int sx, sy;
struct Window *window;
int canland;
{
int top = window->TopEdge-ROCKETHEIGHT+3;
int bottom = window->TopEdge+window->Height - 2;
int left = window->LeftEdge-SPRWIDTH+4*PIXRATIO;
int right = window->LeftEdge+window->Width-5*PIXRATIO;
if(sx<left || sx>right) return OK;
if(sy>bottom || sy<top) return OK;
if(canland) {
if(sy>top+3) return CRASHEDGOOD;
if(sx<left+7*PIXRATIO || sx>right-7*PIXRATIO) return CRASHEDGOOD;
return LANDED;
} else {
return CRASHEDBAD;
}
}
checksaucer()
{
int sx, sy, rx, ry, top, bottom, left, right;
if(!saucer_up) return OK;
rx = x/SCALEFACTOR;
ry = y/SCALEFACTOR;
sx = saucer_x/SCALEFACTOR;
sy = saucer_y/SCALEFACTOR;
top = sy-ROCKETHEIGHT+3;
bottom = sy+SAUCERHEIGHT - 2;
left = sx-SPRWIDTH+4*PIXRATIO;
right = sx+SPRWIDTH-5*PIXRATIO;
if(rx<left || rx>right) return OK;
if(ry>bottom || ry<top) return OK;
return CRASHEDSAUCER;
}