home *** CD-ROM | disk | FTP | other *** search
/ Game Programming - All in One (3rd Edition) / game_prog_all_in_one_3rd_ed.iso / software / Mappy / mappyal / isodemo.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-06-03  |  9.9 KB  |  340 lines

  1. /* (C)2001 Robin Burrows - Isodemo */
  2.  
  3. #include <stdio.h>
  4. #include <allegro.h>
  5. #include "mappyal.h"
  6.  
  7. #define SWIDTH 640
  8. #define SHEIGHT 480
  9. #define PLAYWIDTH (SWIDTH-20)
  10. #define PLAYHEIGHT (SHEIGHT-20)
  11.  
  12. /* Sprite types */
  13. #define SPR_PLAYER 1
  14. #define SPR_ENEMY 2
  15.  
  16. /* Sprite structure */
  17. typedef struct {
  18. int type, xoff, yoff, xadd, yadd, delay;
  19. /* You could expand this to add animation, hits and other info */
  20. } ASPRITE;
  21.  
  22. static ASPRITE *** spritearray = NULL;    /* Wow, pointer to pointer to pointer */
  23. static ASPRITE * playersprite = NULL;    /* Quick reference to find player */
  24. int playerx, playery;
  25. int scrlxoff = 0;        /* X and Y offset in pixels */
  26. int scrlyoff = 0;
  27. int redraw = 0;            /* Needed if surfaces are lost */
  28. int hwaccel = 0;        /* Enable hardware acceleration if available */
  29. BITMAP * display1, * display2, * backbuffer;    /* For hardware page flipping */
  30. BITMAP * escbmpt;        /* For hit ESC message */
  31.  
  32. int GameInit (void)
  33. {
  34. int i, j;
  35.  
  36.     scrlxoff = 0; scrlyoff = 0;
  37.  
  38. /* Allocate memory for the spritearray and init all cells NULL */
  39.     spritearray = (ASPRITE ***) malloc (mapheight*sizeof(ASPRITE **));
  40.     if (spritearray == NULL) return -1;
  41.     for (j=0;j<mapheight;j++) {
  42.         spritearray[j] = (ASPRITE **) malloc (mapwidth*sizeof(ASPRITE *));
  43.         if (spritearray[j] == NULL) return -1;
  44.         for (i=0;i<mapwidth;i++) spritearray[j][i] = NULL;
  45.     }
  46.  
  47. /* Switch to map layer 1 (sprite layer) and find all the sprites,
  48.  * then allocate them into the sprite array
  49.  */
  50.     MapChangeLayer (1);
  51.     for  (j=0;j<mapheight;j++) {
  52.         for  (i=0;i<mapwidth;i++) {
  53.             switch (MapGetBlock (i, j)->user1) {
  54.                 case SPR_ENEMY: /* Enemy */
  55.                     spritearray[j][i] = (ASPRITE *) malloc (sizeof (ASPRITE));
  56.                     if (spritearray[j][i] == NULL) return -1;
  57.                     spritearray[j][i]->type = SPR_ENEMY;
  58.                     spritearray[j][i]->xoff = 0;
  59.                     spritearray[j][i]->yoff = 0;
  60.                     spritearray[j][i]->xadd = 0;
  61.                     spritearray[j][i]->yadd = 0;
  62.                     spritearray[j][i]->delay = 0;
  63.                     break;
  64.                 case SPR_PLAYER: /* Player */
  65.                     spritearray[j][i] = (ASPRITE *) malloc (sizeof (ASPRITE));
  66.                     playersprite = spritearray[j][i];
  67.                     if (spritearray[j][i] == NULL) return -1;
  68.                     spritearray[j][i]->type = SPR_PLAYER;
  69.                     spritearray[j][i]->xoff = 0;
  70.                     spritearray[j][i]->yoff = 0;
  71.                     spritearray[j][i]->xadd = 0;
  72.                     spritearray[j][i]->yadd = 0;
  73.                     playerx = i;
  74.                     playery = j;
  75.                     break;
  76.                 default:
  77.                     break;
  78.             }
  79.         }
  80.     }
  81.     MapChangeLayer (0);
  82.  
  83.     if (playersprite == NULL) return -1;
  84.     return 0;
  85. }
  86.  
  87. void GameEnd (void)
  88. {
  89. int i, j;
  90.  
  91. /* Free up all the game resources allocated in GameInit */
  92.     if (spritearray != NULL) {
  93.         for (j=0;j<mapheight;j++) {
  94.             if (spritearray[j] != NULL) {
  95.                 for (i=0;i<mapwidth;i++) {
  96.                     if (spritearray[j][i] != NULL) free (spritearray[j][i]);
  97.                 }
  98.                 free (spritearray[j]);
  99.             }
  100.         }
  101.         free (spritearray); spritearray = NULL;
  102.     }
  103. }
  104.  
  105. void RowCallback (int cx, int cy, int dx, int dy)
  106. {
  107. int col = 0;
  108.  
  109.     if (spritearray[cy][cx] == NULL) return;
  110.     if (spritearray[cy][cx]->type == SPR_PLAYER) col = makecol (255,255,0);
  111.     if (spritearray[cy][cx]->type == SPR_ENEMY) col = makecol (255,0,0);
  112.  
  113.     dx += spritearray[cy][cx]->xoff;
  114.     dy += spritearray[cy][cx]->yoff;
  115.     rectfill (backbuffer, dx+4, dy-80, dx+60, dy+15, col);
  116. }
  117.  
  118. void DrawSorted (void)
  119. {
  120. int i;
  121.  
  122. /* Keep player in the middle of the playarea,
  123.  * But don't display anything outside the map array!
  124.   */
  125.     scrlxoff = ((playerx*mapblockgapx)+playersprite->xoff+(mapblockwidth/2))-(PLAYWIDTH/2);
  126.     scrlyoff = (((playery/2)*mapblockgapy)+playersprite->yoff+(mapblockheight/2))-(PLAYHEIGHT/2);
  127.     if (playery&1) { scrlxoff += mapblockstaggerx; scrlyoff += mapblockstaggery; }
  128.  
  129.     if (scrlxoff < 0) scrlxoff = 0;
  130.     if (scrlyoff < 0) scrlyoff = 0;
  131.     if (scrlxoff > ((mapwidth*mapblockgapx)-PLAYWIDTH))
  132.         scrlxoff = ((mapwidth*mapblockgapx)-PLAYWIDTH);
  133.     if (scrlyoff > (((mapheight/2)*mapblockgapy)-(PLAYHEIGHT-400)))
  134.         scrlyoff = (((mapheight/2)*mapblockgapy)-(PLAYHEIGHT-400));
  135.  
  136. /* Here the Map Background layer is drawn... */
  137.     MapDrawBG (backbuffer, scrlxoff, scrlyoff, 10, 10, SWIDTH-20, SHEIGHT-20);
  138.  
  139.     for (i=0;i<((SCREEN_H/(mapblockgapy/2))+14);i++) {
  140.         MapDrawRow (backbuffer, scrlxoff, scrlyoff, 10, 10, SWIDTH-20, SHEIGHT-20, i, RowCallback);
  141.     }
  142.  
  143.     masked_blit (escbmpt, backbuffer, 0, 0, SWIDTH/2-68, SHEIGHT-30, 136, 8);
  144.     textout_centre (backbuffer, font, "Move in 8 directions with arrow keys",
  145.         SWIDTH/2, SHEIGHT-50, makecol (255,255,255));
  146. }
  147.  
  148. void MovePlayer (void)
  149. {
  150. int xdiff, ydiff;
  151.  
  152.     if (playersprite->xoff || playersprite->yoff) {
  153. /* Move the sprite in the direction it is going */
  154.         playersprite->xoff += playersprite->xadd;
  155.         playersprite->yoff += playersprite->yadd;
  156.  
  157. /* If it has reached destination, stop it */
  158.         if (playersprite->xoff == 0 && playersprite->yoff == 0) {
  159.             playersprite->xadd = 0;
  160.             playersprite->yadd = 0;
  161.         }
  162.     } else {
  163.         xdiff = 0; ydiff = 0;
  164.         if (key[KEY_LEFT]) xdiff = -1;
  165.         if (key[KEY_RIGHT]) xdiff = 1;
  166.         if (key[KEY_UP]) ydiff = -1;
  167.         if (key[KEY_DOWN]) ydiff = 1;
  168.  
  169.         if (xdiff == 0 && ydiff == 0) return;
  170.  
  171.         if ((playerx+xdiff) < 2) return;
  172.         if ((playerx+xdiff) >= (mapwidth-2)) return;
  173.         if ((playery+ydiff) < 2) return;
  174.         if ((playery+ydiff) >= (mapheight-2)) return;
  175.  
  176.         if (xdiff == 0) ydiff *= 2;
  177.         if (ydiff != 0 && xdiff != 0) {
  178.             if (!(playery&1)) {
  179.                 if (xdiff == 1) xdiff = 0;
  180.             } else {
  181.                 if (xdiff == -1) xdiff = 0;
  182.             }
  183.         }
  184.  
  185.         if (spritearray[playery+ydiff][playerx+xdiff] != NULL) return;
  186.         if (MapGetBlock(playerx+xdiff, playery+ydiff)->tl) return;
  187.  
  188.         spritearray[playery][playerx] = NULL;
  189.         spritearray[playery+ydiff][playerx+xdiff] = playersprite;
  190.         playery += ydiff; playerx += xdiff;
  191.  
  192.          if (ydiff == 0) {
  193.             playersprite->xoff = (xdiff* -62);
  194.             playersprite->xadd = (xdiff* 2);
  195.             return;
  196.         }
  197.  
  198.         if (ydiff == -2 || ydiff == 2) {
  199.             playersprite->yoff = ((ydiff/2)* -31);
  200.             playersprite->yadd = (ydiff/2);
  201.             return;
  202.         }
  203.  
  204.         if ((playery&1)) {
  205.             if (xdiff == 0) xdiff = 1;
  206.         } else {
  207.             if (xdiff == 0) xdiff = -1;
  208.         }
  209.  
  210.         playersprite->xoff = (xdiff* -30);
  211.         playersprite->xadd = (xdiff* 2);
  212.         playersprite->yoff = (ydiff* -15);
  213.         playersprite->yadd = (ydiff* 1);
  214.  
  215.     }
  216. }
  217.  
  218. void RenderInitDisplays (void)
  219. {
  220. /* Now draw a border to show that DrawMap clips properly */
  221.     if (!hwaccel) {
  222.         rect (backbuffer, 3, 3, SWIDTH-4, SHEIGHT-4, makecol (255, 255, 255));
  223.         rect (backbuffer, 9, 9, SWIDTH-10, SHEIGHT-10, makecol (255, 255, 255));
  224.     } else {
  225.         acquire_bitmap (display1);
  226.         clear (display1);
  227.         rect (display1, 3, 3, SWIDTH-4, SHEIGHT-4, makecol (255, 255, 255));
  228.         rect (display1, 9, 9, SWIDTH-10, SHEIGHT-10, makecol (255, 255, 255));
  229.         release_bitmap (display1);
  230.         acquire_bitmap (display2);
  231.         clear (display2);
  232.         rect (display2, 3, 3, SWIDTH-4, SHEIGHT-4, makecol (255, 255, 255));
  233.         rect (display2, 9, 9, SWIDTH-10, SHEIGHT-10, makecol (255, 255, 255));
  234.         release_bitmap (display2);
  235.     }
  236. }
  237.  
  238. void RedrawNeeded (void)
  239. {
  240.     redraw = 1;
  241. }
  242.  
  243. int main (int argc, char *argv[])
  244. {
  245.     allegro_init();    /* Normal Allegro calls to start with */
  246.     install_timer();
  247.     install_keyboard();
  248.     install_mouse();
  249.  
  250.     set_color_depth (16);
  251.     if (set_gfx_mode (GFX_AUTODETECT, SWIDTH, SHEIGHT, 0, 0)<0) {
  252.         set_color_depth (15);
  253.         if (set_gfx_mode (GFX_AUTODETECT, SWIDTH, SHEIGHT, 0, 0)<0) {
  254.             set_color_depth (32);
  255.             if (set_gfx_mode (GFX_AUTODETECT, SWIDTH, SHEIGHT, 0, 0)<0) {
  256.                 return -1;
  257.             }
  258.         }
  259.     }
  260.  
  261.     set_display_switch_callback (SWITCH_IN, RedrawNeeded);
  262.  
  263.     if (gfx_capabilities&GFX_HW_VRAM_BLIT && gfx_capabilities&GFX_HW_VRAM_BLIT_MASKED) {
  264.         display1 = create_video_bitmap (SWIDTH, SHEIGHT);
  265.         display2 = create_video_bitmap (SWIDTH, SHEIGHT);
  266.         if (display1==NULL || display2==NULL) { MapFreeMem (); exit (0); }
  267.         backbuffer = display2;
  268.         show_video_bitmap (display1);
  269.         if (bitmap_color_depth(screen)==8) set_palette (desktop_palette);
  270.         alert ("Hardware Acceleration detected!", "Vroom, vroom", NULL, "&OK", NULL, 'o', 0);
  271. /* Load the FMP file, exit if error */
  272.         if (MapLoadVRAM ("ISOTST.FMP")) { allegro_exit(); return 0; }
  273.         hwaccel = 1;
  274.     } else {
  275.         backbuffer = create_bitmap (SWIDTH, SHEIGHT);    /* Double buffer */
  276.         if (backbuffer==NULL) { MapFreeMem (); exit (0); }
  277.         clear (screen); clear (backbuffer);
  278.         if (bitmap_color_depth(screen)==8) set_palette (desktop_palette);
  279.         alert ("No Hardware Acceleration!", "Using software", NULL, "&OK", NULL, 'o', 0);
  280. /* Load the FMP file, exit if error */
  281.         if (MapLoad ("ISOTST.FMP")) { allegro_exit(); return 0; }
  282.         hwaccel = 0;
  283.     }
  284.  
  285.     if (bitmap_color_depth(screen)==8) MapSetPal8 ();        /* Set palette */
  286.     MapInitAnims ();                    /* Reset animations */
  287.  
  288. /* Next, put '* Hit ESC to exit*' text on a BITMAP */
  289.     escbmpt = create_bitmap (136, 8);
  290.     if (escbmpt==NULL) { MapFreeMem (); exit (0); }
  291.     clear (escbmpt); text_mode (-1);
  292.         textout (escbmpt, font, "*Hit ESC to exit*", 0, 0, makecol (255, 255, 255));
  293.  
  294.     RenderInitDisplays ();
  295.  
  296.     GameInit ();
  297.  
  298. /* This is the main loop, which is repeated until SPACE or ESC is pressed */
  299.     while (1)
  300.     {
  301.     if (!hwaccel) {
  302. /* Sync in with the screen, and then copy the doublebuffer to display it (software) */
  303.         vsync ();
  304.         blit (backbuffer, screen, 0, 0, 0, 0, SWIDTH, SHEIGHT);
  305.     } else {
  306. /* Sync in with the screen, and then swap display bitmaps (hardware) */
  307.         if (backbuffer==display1) {
  308.             show_video_bitmap (display1); backbuffer = display2;
  309.         } else {
  310.             show_video_bitmap (display2); backbuffer = display1;
  311.         }
  312.     }
  313.  
  314.     if (redraw) {
  315.         RenderInitDisplays ();
  316.         MapRestore ();
  317.         redraw = 0;
  318.     }
  319.  
  320. /* Call this next function to update the animations */
  321.         MapUpdateAnims ();
  322.  
  323.         MovePlayer ();
  324.         DrawSorted ();
  325.         if (key[KEY_ESC]) break;
  326.         if (key[KEY_SPACE]) break;
  327.     }
  328.  
  329. /* When ESC or SPACE has been pressed, it's time to clean up and leave */
  330.     GameEnd ();
  331.     if (!hwaccel) destroy_bitmap (backbuffer);
  332.     destroy_bitmap (escbmpt);
  333.     MapFreeMem ();
  334.     allegro_exit();
  335.     return 0;
  336. }
  337. #ifdef END_OF_MAIN
  338. END_OF_MAIN ();
  339. #endif
  340.