home *** CD-ROM | disk | FTP | other *** search
- #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;
- }
-