home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / programming / source / apilot.lha / APilot / APilot_Opt / map.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-12-03  |  25.2 KB  |  756 lines

  1. /**************************************************************************
  2.  *
  3.  * map.c -- Functions for reading and drawing the map into
  4.  *          memory.
  5.  *
  6.  *-------------------------------------------------------------------------
  7.  * Authors: Casper Gripenberg  (casper@alpha.hut.fi)
  8.  *          Kjetil Jacobsen  (kjetilja@stud.cs.uit.no)
  9.  *
  10.  */
  11.  
  12. /*------------------------------------------------------------------------*/
  13.  
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <ctype.h>
  17. #include <string.h>
  18. #include <math.h>
  19. #include <intuition/intuition.h>
  20. #include <libraries/dos.h>          /* Official return codes defined here */
  21.  
  22. #include <proto/intuition.h>
  23. #include <proto/graphics.h>
  24.  
  25. #include "map_protos.h"
  26. #include "main_protos.h"
  27. #include "misc_protos.h"
  28. #include "lists_protos.h"
  29. #include "cannon_protos.h"
  30. #include "fuelpod_protos.h"
  31. #ifndef PURE_OS
  32. #include "hline_protos.h"
  33. #endif
  34.  
  35. #include "prefs.h"
  36. #include "common.h"
  37. #include "fuelpod.h"
  38. #include "misc.h"
  39.  
  40. /*------------------------------------------------------------------------*/
  41.  
  42. #define MAXKEYWORD 80   /* Max length of any keyword in the mapfile  */
  43.  
  44. extern AWorld World;    /* From main */
  45. char   **map_file;      /* Here every mapline will be put separately */
  46.  
  47. #define TBLSIZE ('z'-'a')
  48.  
  49. #define up_tbl(ch) u_tbl['z' - tolower(ch)]
  50. #define dn_tbl(ch) d_tbl['z' - tolower(ch)]
  51. #define le_tbl(ch) l_tbl['z' - tolower(ch)]
  52. #define ri_tbl(ch) r_tbl['z' - tolower(ch)]
  53.  
  54. #define test_u(ch) ((ch) < 'a' || (ch) > 'z' ? TRUE : up_tbl(ch))
  55. #define test_d(ch) ((ch) < 'a' || (ch) > 'z' ? TRUE : dn_tbl(ch))
  56. #define test_l(ch) ((ch) < 'a' || (ch) > 'z' ? TRUE : le_tbl(ch))
  57. #define test_r(ch) ((ch) < 'a' || (ch) > 'z' ? TRUE : ri_tbl(ch))
  58.  
  59. /*------------------------------------------------------------------------*/
  60.  
  61. /*
  62.  * Maptables:
  63.  * These determine when to draw lines based on what is around
  64.  * a certain map point. A small kludge. Maybe I'll think of something
  65.  * more elegant later.. Atleast malloc the tables..
  66.  */
  67. void
  68. init_maptables(BOOL u_tbl[], BOOL d_tbl[], BOOL l_tbl[], BOOL r_tbl[])
  69. {
  70.   int i;
  71.  
  72.   for (i = 0; i < TBLSIZE; i++) {
  73.     u_tbl[i] = TRUE;
  74.     d_tbl[i] = TRUE;
  75.     l_tbl[i] = TRUE;
  76.     r_tbl[i] = TRUE;
  77.   }
  78.  
  79.   up_tbl('x') = FALSE;
  80.   up_tbl('q') = FALSE;
  81.   up_tbl('w') = FALSE;
  82.  
  83.   dn_tbl('x') = FALSE;
  84.   dn_tbl('a') = FALSE;
  85.   dn_tbl('s') = FALSE;
  86.  
  87.   le_tbl('x') = FALSE;  
  88.   le_tbl('q') = FALSE;
  89.   le_tbl('a') = FALSE;
  90.   
  91.   ri_tbl('x') = FALSE;
  92.   ri_tbl('w') = FALSE;
  93.   ri_tbl('s') = FALSE;
  94. }
  95.  
  96. /*------------------------------------------------------------------------*/
  97.  
  98. /*
  99.  * init_map -- Should be partially compatible with xpilot mapfiles.
  100.  *
  101.  */
  102. void
  103. init_map( void )
  104. {
  105.   FILE *map_fh;
  106.   int i, x, y; 
  107.   int line      = 0;
  108.   char *char_chunk;
  109.   char line_buf[MAXLINE];
  110.   char keyword[MAXKEYWORD];
  111.   char argument[MAXKEYWORD];
  112.   MAP_Point *point_chunk;
  113.  
  114.   if ( !(map_fh = fopen(prefs.mapname, "r")) )
  115.     cleanExit( RETURN_WARN, "** Mapfile: %s not found\n", prefs.mapname );
  116.  
  117.   /*
  118.    * Parse the mapfile
  119.    */
  120.   while (fgets(line_buf, MAXLINE, map_fh)) {
  121.     line++;
  122.  
  123.     /* Check for comments and empty lines */
  124.     if (line_buf[0] == '#' || line_buf[0] == '\n')
  125.       continue;
  126.  
  127.     if (strlen(line_buf) > MAXKEYWORD)
  128.       cleanExit( RETURN_WARN, "** Mapline %d too long\n", line-1 );
  129.  
  130.     if ( sscanf(line_buf, "%[^:]:%s", keyword, argument) != 2 )
  131.       cleanExit( RETURN_WARN, "** Invalid mapline %d.\n", line-1 );
  132.  
  133.     /* Skip trailing blanks */
  134.     for (i = 0; keyword[i] != '\0'; i++) {
  135.       if (keyword[i] == ' ') {
  136.         keyword[i] = '\0';
  137.         break;
  138.       }
  139.     }
  140.         
  141.     if (stricmp(keyword, "mapWidth") == 0)
  142.       World.Width = atoi(argument);
  143.     else if (stricmp(keyword, "mapHeight") == 0)
  144.       World.Height = atoi(argument);
  145.     else if (stricmp(keyword, "mapData") == 0)
  146.       break;
  147.     else
  148.       printf("** Unsupported keyword %s in mapfile.\n", keyword);
  149.   }
  150.  
  151.   if (World.Width == 0 || World.Height == 0)
  152.     cleanExit( RETURN_WARN, 
  153.                "** Missing map dimension specifications in mapfile %s\n",
  154.                MAPFILE );
  155.  
  156.   /*
  157.    * Allocate space for the maplines
  158.    */
  159.   if ((map_file = (char **) malloc(sizeof(char *) * World.Height)) == NULL)
  160.     cleanExit( RETURN_WARN, "** Could not allocate space for map.\n" );
  161.   if ((char_chunk = (char *) 
  162.        malloc(sizeof(char) * (World.Width * World.Height))) == NULL)
  163.     cleanExit( RETURN_WARN, "** Could not allocate space for map.\n" );
  164.  
  165.   line = 0;
  166.   while (fgets(line_buf, MAXLINE, map_fh)) {
  167.  
  168.     if ( strlen(line_buf) < World.Width )
  169.       cleanExit( RETURN_WARN, "** Mapline %d too short\n", line+1 );
  170.  
  171.     map_file[line] = &char_chunk[line * World.Width];
  172.  
  173.     for (i = 0; i < World.Width; i++)
  174.       map_file[line][i] = line_buf[i];
  175.  
  176.     line++;
  177.     if (line >= World.Height)
  178.       break;
  179.   }
  180.  
  181.   fclose(map_fh);
  182.  
  183.   if (line < World.Height)
  184.     cleanExit( RETURN_WARN, "** Mapfile: Not enough lines.\n" );
  185.  
  186.   if ((World.map_points = (MAP_Point **) 
  187.        malloc(sizeof(MAP_Point *) * World.Width)) == NULL)
  188.     cleanExit( RETURN_WARN, "** Could not allocate space for map.\n" );
  189.   if ((point_chunk = (MAP_Point *)
  190.        malloc(sizeof(MAP_Point) * (World.Width * World.Height))) == NULL)
  191.     cleanExit( RETURN_WARN, "** Could not allocate space for map.\n" );
  192.  
  193.   for ( y = 0; y < World.Height; y++ ) {
  194.     World.map_points[y] = &point_chunk[y * World.Width];
  195.     for ( x = 0; x < World.Width; x++ ) 
  196.       World.map_points[y][x].draw_flags = 0;
  197.   }
  198.  
  199.   prepare_map();
  200.   optimize_map();
  201.  
  202.   free(char_chunk);
  203.   free(map_file);
  204. }
  205.  
  206. /*------------------------------------------------------------------------*/
  207.  
  208. /*
  209.  * prepare_map -- Converts the read mapifile into an internal format
  210.  *                for later use.
  211.  */
  212. void
  213. prepare_map( void )
  214. {
  215.   int x, y;
  216.  
  217.   char *p_line;
  218.   char *c_line;
  219.   char *n_line;
  220.  
  221.   /* True if there should be a line in this 'direction' */
  222.   BOOL u_ch, d_ch, l_ch, r_ch;
  223.  
  224.   BOOL u_tbl[TBLSIZE];
  225.   BOOL d_tbl[TBLSIZE];
  226.   BOOL l_tbl[TBLSIZE];
  227.   BOOL r_tbl[TBLSIZE];
  228.  
  229.   init_maptables(u_tbl, d_tbl, l_tbl, r_tbl);
  230.  
  231.   for ( y = 0; y < World.Height; y++ ) {
  232.  
  233.     if (y == 0) 
  234.        p_line = NULL;
  235.     else        
  236.        p_line = map_file[y-1];
  237.  
  238.     if ( y < World.Height-1 ) 
  239.        n_line = map_file[y+1];
  240.     else
  241.        n_line = NULL;
  242.  
  243.     c_line = map_file[y];
  244.  
  245.     for ( x = 0; x < World.Width; x++ ) {
  246.       if (p_line) u_ch = test_u(p_line[x]);
  247.       else        u_ch = FALSE;
  248.       if (n_line) d_ch = test_d(n_line[x]);
  249.       else        d_ch = FALSE;
  250.       if (x > 0)  l_ch = test_l(c_line[x-1]);
  251.       else        l_ch = FALSE;
  252.       if (x < World.Width-1) r_ch = test_r(c_line[x+1]);
  253.       else                   r_ch = FALSE;
  254.       
  255.       /* Precalculate these..speeds up map rendering (?) */
  256.       World.map_points[y][x].edge_x = x * MAP_BLOCKSIZE;
  257.       World.map_points[y][x].edge_y = y * MAP_BLOCKSIZE;
  258.  
  259.       switch (c_line[x]) {
  260.         case ' ':
  261.           World.map_points[y][x].blocktype = BLOCK_EMPTY;
  262.           break;
  263.         case 'x':
  264.           if ( !u_ch && !d_ch && !l_ch && !r_ch ) {
  265.             World.map_points[y][x].blocktype = BLOCK_FILLED_ND;
  266.             break;
  267.           }
  268.           World.map_points[y][x].blocktype = BLOCK_FILLED;
  269.           if (u_ch) World.map_points[y][x].draw_flags |= DRAW_UP;
  270.           if (d_ch) World.map_points[y][x].draw_flags |= DRAW_DOWN;
  271.           if (l_ch) World.map_points[y][x].draw_flags |= DRAW_LEFT;
  272.           if (r_ch) World.map_points[y][x].draw_flags |= DRAW_RIGHT;
  273.           break;
  274.         case 'a':
  275.           World.map_points[y][x].blocktype = BLOCK_RU;
  276.           if (u_ch) World.map_points[y][x].draw_flags |= DRAW_UP;
  277.           if (r_ch) World.map_points[y][x].draw_flags |= DRAW_RIGHT;
  278.           break;
  279.         case 's':
  280.           World.map_points[y][x].blocktype = BLOCK_LU;
  281.           if (u_ch) World.map_points[y][x].draw_flags |= DRAW_UP;
  282.           if (l_ch) World.map_points[y][x].draw_flags |= DRAW_LEFT;
  283.           break;
  284.         case 'q':
  285.           World.map_points[y][x].blocktype = BLOCK_RD;
  286.           if (d_ch) World.map_points[y][x].draw_flags |= DRAW_DOWN;
  287.           if (r_ch) World.map_points[y][x].draw_flags |= DRAW_RIGHT;
  288.           break;
  289.         case 'w':
  290.           World.map_points[y][x].blocktype = BLOCK_LD;
  291.           if (d_ch) World.map_points[y][x].draw_flags |= DRAW_DOWN;
  292.           if (l_ch) World.map_points[y][x].draw_flags |= DRAW_LEFT;
  293.           break;
  294.         case 'r':
  295.           World.map_points[y][x].blocktype = BLOCK_CU;
  296.           World.map_points[y][x].objectptr = (APTR) alloc_cannon(x,y,C_UP);
  297.           break;
  298.         case 'c':
  299.           World.map_points[y][x].blocktype = BLOCK_CD;
  300.           World.map_points[y][x].objectptr = (APTR) alloc_cannon(x,y,C_DN);
  301.           break;
  302.         case 'f':
  303.           World.map_points[y][x].blocktype = BLOCK_CR;
  304.           World.map_points[y][x].objectptr = (APTR) alloc_cannon(x,y,C_RG);
  305.           break;
  306.         case 'd':
  307.           World.map_points[y][x].blocktype = BLOCK_CL;
  308.           World.map_points[y][x].objectptr = (APTR) alloc_cannon(x,y,C_LF);
  309.           break;
  310.         case '#':
  311.           World.map_points[y][x].blocktype = BLOCK_FUEL;
  312.           World.map_points[y][x].draw_flags |= DRAW_UP    | DRAW_DOWN |
  313.                                                DRAW_RIGHT | DRAW_LEFT;
  314.           World.map_points[y][x].objectptr = (APTR) alloc_fuelpod(x,y);
  315.           break;
  316.         case '_':
  317.           World.map_points[y][x].blocktype = BLOCK_BASE;
  318.           World.map_points[y][x].objectptr = (APTR) alloc_base(x,y);
  319.           break;
  320.         default:
  321.           World.map_points[y][x].blocktype = BLOCK_EMPTY;
  322.           break;
  323.       }
  324.     }
  325.   }
  326. }
  327.  
  328. /*------------------------------------------------------------------------*/
  329.  
  330. /*
  331.  * optimize_map -- Tries to add hints in the map points that will hopefully
  332.  *                 speed up the map drawing.
  333.  */
  334. void
  335. optimize_map(void)
  336. {
  337.   int x, y;
  338.   int ecount, fcount;
  339.   btype  blocktype;
  340.   USHORT dflags, memflags;
  341.  
  342.   for (y = 0; y < World.Height; y++) {
  343.     ecount = fcount = dflags = memflags = 0;
  344.     for (x = World.Width-1; x >= 0; x--) {
  345.       blocktype = World.map_points[y][x].blocktype;
  346.       dflags    = World.map_points[y][x].draw_flags;
  347.  
  348.       if (blocktype == BLOCK_FILLED_ND || blocktype == BLOCK_EMPTY) {
  349.         World.map_points[y][x].empty2Right = ecount;
  350.         ecount++;        
  351.       } else {
  352.         World.map_points[y][x].empty2Right = ecount;
  353.         ecount = 0;
  354.       }
  355.  
  356.       if (blocktype == BLOCK_FILLED) {
  357.         /* We only want to check blocks with horizontal lines */
  358.         if ( !((dflags & DRAW_LEFT) || (dflags & DRAW_RIGHT)) ) {
  359.           if (dflags == memflags) {
  360.             fcount++;
  361.             memflags = dflags;
  362.           } else {
  363.             fcount = 0;
  364.             memflags = dflags;
  365.             World.map_points[y][x].filled2Right = 0;
  366.           }
  367.         } else {
  368.           fcount = 0;
  369.           memflags = 0;
  370.         }
  371.       } else {
  372.         fcount = 0;          
  373.         memflags = 0;
  374.       }
  375.       World.map_points[y][x].filled2Right = fcount;
  376.     }
  377.   }
  378. }
  379.  
  380. /*------------------------------------------------------------------------*/
  381.  
  382. /*
  383.  * draw_map -- Draws the map using the ship local_ship's cordinates
  384.  *             to position the map on the display.
  385.  */
  386. void
  387. draw_map( struct RastPort *wRp, AShip *local_ship, UWORD buf, UWORD nframes )
  388. {
  389.   const int bsz  = MAP_BLOCKSIZE;
  390.   const int bsz1 = MAP_BLOCKSIZE+1;
  391.   const int bsz2 = MAP_BLOCKSIZE/2;
  392.  
  393.   int filled2Right;
  394.  
  395.   int       i, x, y, onoff, xbsz, ybsz;
  396.   int       bp_x, bp_y, start_x, start_y, end_x, end_y;
  397.   int       fuelamount;
  398. #ifndef PURE_OS
  399.   PLANEPTR  bpl0, bpl1;
  400. #endif  
  401.   UBYTE     cannon_pen, map_pen;
  402.   USHORT    d_flags;
  403.   MAP_Point **map_points = World.map_points;
  404.  
  405.   static int p_mapx[MY_BUFFERS];
  406.   static int p_mapy[MY_BUFFERS];
  407.  
  408. #ifndef PURE_OS
  409.   bpl0 = wRp->BitMap->Planes[0];
  410.   bpl1 = wRp->BitMap->Planes[1];
  411. #endif 
  412.  
  413.   /* First clear old map and then draw new */
  414.   for (i = 0; i < 2; i++) {
  415.     switch (i) {
  416.       case 0:
  417.         /* Clear it */
  418.         SetWriteMask(wRp, 2l);
  419.         SetAPen(wRp, 0);
  420.         cannon_pen = 0;
  421.         map_pen    = 0;
  422.         onoff = 0;
  423.         start_x = (p_mapx[buf]-SCR_WIDTH/2)/MAP_BLOCKSIZE;
  424.         start_y = (p_mapy[buf]-SCR_HEIGHT/2)/MAP_BLOCKSIZE;
  425.         end_x = 1+(p_mapx[buf]+SCR_WIDTH/2)/MAP_BLOCKSIZE;
  426.         end_y = 1+(p_mapy[buf]+SCR_HEIGHT/2)/MAP_BLOCKSIZE;
  427.         bp_x = p_mapx[buf]-(SCR_WIDTH+MAP_BLOCKSIZE*2)/2;
  428.         bp_y = p_mapy[buf]-(SCR_HEIGHT+MAP_BLOCKSIZE*2)/2;
  429.         break;
  430.       case 1:
  431.         /* Draw it */
  432.         /* Draw hud first and then the map on the hud. */
  433.         draw_hud(wRp, buf, nframes);
  434.         SetWriteMask(wRp, 2l);
  435.         SetAPen(wRp, 2);
  436.         cannon_pen = 3;
  437.         map_pen    = 2;
  438.         onoff = 1;
  439.         start_x = (local_ship->pos.x-SCR_WIDTH/2)/MAP_BLOCKSIZE;
  440.         start_y = (local_ship->pos.y-SCR_HEIGHT/2)/MAP_BLOCKSIZE;
  441.         end_x = 1+(local_ship->pos.x+SCR_WIDTH/2)/MAP_BLOCKSIZE;
  442.         end_y = 1+(local_ship->pos.y+SCR_HEIGHT/2)/MAP_BLOCKSIZE;
  443.         bp_x = local_ship->pos.x-(SCR_WIDTH+MAP_BLOCKSIZE*2)/2;
  444.         bp_y = local_ship->pos.y-(SCR_HEIGHT+MAP_BLOCKSIZE*2)/2;
  445.         break;
  446.       default:
  447.         /* NOTREACHED */
  448.         break;
  449.     }
  450.  
  451.     start_x = max( 0, start_x );
  452.     start_y = max( 0, start_y );
  453.     end_x = min( World.Width , end_x );
  454.     end_y = min( World.Height, end_y );
  455.  
  456.     WaitBlit();
  457.  
  458.     /* Check for map edges */
  459.     if (start_y == 0) {
  460.       xbsz = map_points[0][start_x].edge_x;
  461.       ybsz = map_points[0][start_x].edge_y;
  462. #ifdef PURE_OS
  463.       HLINE(wRp, xbsz-bp_x, ybsz-bp_y, (end_x-start_x)*bsz)
  464. #else
  465.       HorizontalLine(bpl1, xbsz-bp_x, ybsz-bp_y, (end_x-start_x)*bsz, onoff);
  466. #endif
  467.     }
  468.     if (end_y == World.Height) {
  469.       xbsz = map_points[end_y-1][start_x].edge_x;
  470.       ybsz = map_points[end_y-1][start_x].edge_y;
  471. #ifdef PURE_OS
  472.       HLINE(wRp, xbsz-bp_x, ybsz+bsz-bp_y, (end_x-start_x)*bsz)
  473. #else
  474.       HorizontalLine(bpl1, xbsz-bp_x, ybsz+bsz-bp_y, (end_x-start_x)*bsz, onoff);
  475. #endif
  476.     }
  477.     if (start_x == 0) {
  478.       xbsz = map_points[start_y][0].edge_x;
  479.       ybsz = map_points[start_y][0].edge_y;
  480. #ifdef PURE_OS
  481.       VLINE(wRp, xbsz-bp_x, ybsz-bp_y, (end_y-start_y)*bsz)
  482. #else
  483.       VerticalLine(bpl1, xbsz-bp_x, ybsz-bp_y, (end_y-start_y)*bsz, onoff);
  484. #endif
  485.     }
  486.     if (end_x == World.Width) {
  487.       xbsz = map_points[start_y][end_x-1].edge_x;
  488.       ybsz = map_points[start_y][end_x-1].edge_y;
  489. #ifdef PURE_OS
  490.       VLINE(wRp, xbsz+bsz-bp_x, ybsz-bp_y, (end_y-start_y)*bsz)
  491. #else
  492.       VerticalLine(bpl1, xbsz+bsz-bp_x, ybsz-bp_y, (end_y-start_y)*bsz, onoff);
  493. #endif
  494.     }
  495.  
  496.     for ( y = start_y; y < end_y; y++ ) {
  497.       for ( x = start_x; x < end_x; x++ ) {
  498.         switch (map_points[y][x].blocktype) {
  499.           case BLOCK_EMPTY:
  500.           case BLOCK_FILLED_ND:
  501.             break;
  502.           case BLOCK_FILLED:
  503.             xbsz         = map_points[y][x].edge_x;
  504.             ybsz         = map_points[y][x].edge_y;
  505.             d_flags      = map_points[y][x].draw_flags;
  506.             filled2Right = map_points[y][x].filled2Right;
  507.  
  508.             if (filled2Right > 0) {
  509.               int fillCount, newbsz;
  510.               /* 
  511.                * Hehe, I wonder if this cryptic thingy really speeds things
  512.                * up or slows them down :)
  513.                *
  514.                * What I check here is that we don't draw the 'filled2Right' blocks
  515.                * out of the display area. Hopefully there is a better/faster way
  516.                * to do this(?).
  517.                */
  518.               fillCount = (((filled2Right + x) < end_x) ? (filled2Right+1) : (end_x-x));
  519.               newbsz = (MAP_BLOCKSIZE * fillCount) + 1;
  520. #ifdef PURE_OS
  521.               if (d_flags & DRAW_UP)    { HLINE(wRp, xbsz-bp_x, ybsz-bp_y, newbsz) }
  522.               if (d_flags & DRAW_DOWN)  { HLINE(wRp, xbsz-bp_x, ybsz+bsz-bp_y, newbsz) }
  523. #else
  524.               if (d_flags & DRAW_UP)    { HorizontalLine(bpl1, xbsz-bp_x, ybsz-bp_y, newbsz, onoff); }
  525.               if (d_flags & DRAW_DOWN)  { HorizontalLine(bpl1, xbsz-bp_x, ybsz+bsz-bp_y, newbsz, onoff); }
  526. #endif
  527.               x = x + filled2Right;
  528.             } else {
  529. #ifdef PURE_OS
  530.               if (d_flags & DRAW_UP)    { HLINE(wRp, xbsz-bp_x, ybsz-bp_y, bsz1) }
  531.               if (d_flags & DRAW_DOWN)  { HLINE(wRp, xbsz-bp_x, ybsz+bsz-bp_y, bsz1) }
  532.               if (d_flags & DRAW_LEFT)  { VLINE(wRp, xbsz-bp_x, ybsz-bp_y, bsz1) }
  533.               if (d_flags & DRAW_RIGHT) { VLINE(wRp, xbsz+bsz-bp_x, ybsz-bp_y, bsz1) }
  534. #else
  535.               if (d_flags & DRAW_UP)    { HorizontalLine(bpl1, xbsz-bp_x, ybsz-bp_y, bsz1, onoff); }
  536.               if (d_flags & DRAW_DOWN)  { HorizontalLine(bpl1, xbsz-bp_x, ybsz+bsz-bp_y, bsz1, onoff); }
  537.               if (d_flags & DRAW_LEFT)  { VerticalLine(bpl1, xbsz-bp_x, ybsz-bp_y, bsz1, onoff); }
  538.               if (d_flags & DRAW_RIGHT) { VerticalLine(bpl1, xbsz+bsz-bp_x, ybsz-bp_y, bsz1, onoff); }
  539. #endif
  540.             }
  541.             break;
  542.           case BLOCK_RU:
  543.             xbsz = map_points[y][x].edge_x;
  544.             ybsz = map_points[y][x].edge_y;
  545.             Move(wRp, xbsz-bp_x, ybsz-bp_y);
  546.             Draw(wRp, xbsz+bsz-bp_x, ybsz+bsz-bp_y);
  547.             d_flags = map_points[y][x].draw_flags;
  548.             WaitBlit();
  549. #ifdef PURE_OS
  550.             if (d_flags & DRAW_UP)    { HLINE(wRp, xbsz-bp_x, ybsz-bp_y, bsz1) }
  551.             if (d_flags & DRAW_RIGHT) { VLINE(wRp, xbsz+bsz-bp_x, ybsz-bp_y, bsz1) }
  552. #else
  553.             if (d_flags & DRAW_UP)    { HorizontalLine(bpl1, xbsz-bp_x, ybsz-bp_y, bsz1, onoff); }
  554.             if (d_flags & DRAW_RIGHT) { VerticalLine(bpl1, xbsz+bsz-bp_x, ybsz-bp_y, bsz1, onoff); }
  555. #endif
  556.             break;
  557.           case BLOCK_LU:
  558.             xbsz = map_points[y][x].edge_x;
  559.             ybsz = map_points[y][x].edge_y;
  560.             Move(wRp, xbsz-bp_x, ybsz+bsz-bp_y);
  561.             Draw(wRp, xbsz+bsz-bp_x, ybsz-bp_y);
  562.             d_flags = map_points[y][x].draw_flags;
  563.             WaitBlit();
  564. #ifdef PURE_OS
  565.             if (d_flags & DRAW_UP)   { HLINE(wRp, xbsz-bp_x, ybsz-bp_y, bsz1) }
  566.             if (d_flags & DRAW_LEFT) { VLINE(wRp, xbsz-bp_x, ybsz-bp_y, bsz1) }
  567. #else
  568.             if (d_flags & DRAW_UP)   { HorizontalLine(bpl1, xbsz-bp_x, ybsz-bp_y, bsz1, onoff); }
  569.             if (d_flags & DRAW_LEFT) { VerticalLine(bpl1, xbsz-bp_x, ybsz-bp_y, bsz1, onoff); }
  570. #endif
  571.             break;
  572.           case BLOCK_RD:
  573.             xbsz = map_points[y][x].edge_x;
  574.             ybsz = map_points[y][x].edge_y;
  575.             Move(wRp, xbsz-bp_x, ybsz+bsz-bp_y);
  576.             Draw(wRp, xbsz+bsz-bp_x, ybsz-bp_y);
  577.             d_flags = map_points[y][x].draw_flags;
  578.             WaitBlit();
  579. #ifdef PURE_OS
  580.             if (d_flags & DRAW_DOWN)  { HLINE(wRp, xbsz-bp_x, ybsz+bsz-bp_y, bsz1) }
  581.             if (d_flags & DRAW_RIGHT) { VLINE(wRp, xbsz+bsz-bp_x, ybsz-bp_y, bsz1) }
  582. #else
  583.             if (d_flags & DRAW_DOWN)  { HorizontalLine(bpl1, xbsz-bp_x, ybsz+bsz-bp_y, bsz1, onoff); }
  584.             if (d_flags & DRAW_RIGHT) { VerticalLine(bpl1, xbsz+bsz-bp_x, ybsz-bp_y, bsz1, onoff); }
  585. #endif
  586.             break;
  587.           case BLOCK_LD:
  588.             xbsz = map_points[y][x].edge_x;
  589.             ybsz = map_points[y][x].edge_y;
  590.             Move(wRp, xbsz-bp_x, ybsz-bp_y);
  591.             Draw(wRp, xbsz+bsz-bp_x, ybsz+bsz-bp_y);
  592.             d_flags = map_points[y][x].draw_flags;
  593.             WaitBlit();
  594. #ifdef PURE_OS
  595.             if (d_flags & DRAW_DOWN) { HLINE(wRp, xbsz-bp_x, ybsz+bsz-bp_y, bsz1) }
  596.             if (d_flags & DRAW_LEFT) { VLINE(wRp, xbsz-bp_x, ybsz-bp_y, bsz1) }
  597. #else
  598.             if (d_flags & DRAW_DOWN) { HorizontalLine(bpl1, xbsz-bp_x, ybsz+bsz-bp_y, bsz1, onoff); }
  599.             if (d_flags & DRAW_LEFT) { VerticalLine(bpl1, xbsz-bp_x, ybsz-bp_y, bsz1, onoff); }
  600. #endif
  601.             break;
  602.           case BLOCK_FUEL:
  603.             xbsz = map_points[y][x].edge_x;
  604.             ybsz = map_points[y][x].edge_y;
  605. #ifdef PURE_OS
  606.             HLINE(wRp, xbsz-bp_x, ybsz-bp_y, bsz1)
  607.             HLINE(wRp, xbsz-bp_x, ybsz+bsz-bp_y, bsz1)
  608.             VLINE(wRp, xbsz-bp_x, ybsz-bp_y, bsz1)
  609.             VLINE(wRp, xbsz+bsz-bp_x, ybsz-bp_y, bsz1)
  610. #else
  611.             HorizontalLine(bpl1, xbsz-bp_x, ybsz-bp_y, bsz1, onoff);
  612.             HorizontalLine(bpl1, xbsz-bp_x, ybsz+bsz-bp_y, bsz1, onoff);
  613.             VerticalLine(bpl1, xbsz-bp_x, ybsz-bp_y, bsz1, onoff);
  614.             VerticalLine(bpl1, xbsz+bsz-bp_x, ybsz-bp_y, bsz1, onoff);
  615. #endif
  616.             if (onoff == 1) {
  617.               fuelamount = ( (((((AFuelPod *)map_points[y][x].objectptr)->fuel
  618.                            << SHFTPR) / MAX_PODFUEL) * (MAP_BLOCKSIZE-3))
  619.                            >> SHFTPR );
  620.             } else {
  621.               fuelamount = ((AFuelPod *)
  622.                              map_points[y][x].objectptr)->p_fuel[buf];
  623.             }
  624. #ifdef PURE_OS
  625.             SetWriteMask(wRp,1l); 
  626.             if (onoff == 1) SetAPen(wRp,3); 
  627.             HLINE(wRp, xbsz-bp_x+1, ybsz+bsz-bp_y-1-fuelamount, bsz-2)
  628.             HLINE(wRp, xbsz-bp_x+1, ybsz+bsz-bp_y-2-fuelamount, bsz-2)
  629.             SetWriteMask(wRp,2l); 
  630.             if (onoff == 1) SetAPen(wRp,map_pen); 
  631. #else
  632.             HorizontalLine(bpl0, xbsz-bp_x+1, 
  633.                            ybsz+bsz-bp_y-1-fuelamount, bsz-2, onoff);
  634.             HorizontalLine(bpl0, xbsz-bp_x+1, 
  635.                            ybsz+bsz-bp_y-2-fuelamount, bsz-2, onoff);
  636. #endif
  637.             ((AFuelPod *)map_points[y][x].objectptr)->p_fuel[buf] = fuelamount;
  638.             break;
  639.           case BLOCK_CU:
  640.             /* Check if we should draw the cannon */
  641.             if ( ((ACannon *)map_points[y][x].objectptr)->cstate == DEAD
  642.                  && onoff == 1 )
  643.               break;
  644.             xbsz = map_points[y][x].edge_x;
  645.             ybsz = map_points[y][x].edge_y;
  646.             SetWriteMask(wRp, 3l);
  647.             SetAPen(wRp,cannon_pen); 
  648.             Move(wRp, xbsz-bp_x, ybsz+bsz-bp_y-1);
  649.             Draw(wRp, xbsz+bsz2-bp_x , ybsz+bsz-CAN_HEIGHT-bp_y);
  650.             Draw(wRp, xbsz+bsz-bp_x, ybsz+bsz-bp_y-1);
  651.             WaitBlit();
  652. #ifdef PURE_OS
  653.             HLINE(wRp, xbsz-bp_x, ybsz+bsz-bp_y, bsz1)
  654.             HLINE(wRp, xbsz-bp_x, ybsz+bsz-bp_y, bsz1)
  655. #else
  656.             HorizontalLine(bpl0, xbsz-bp_x, ybsz+bsz-bp_y, bsz1, onoff);
  657.             HorizontalLine(bpl1, xbsz-bp_x, ybsz+bsz-bp_y, bsz1, onoff);
  658. #endif
  659.             SetWriteMask(wRp, 2l);
  660.             SetAPen(wRp,map_pen); 
  661.             break;
  662.           case BLOCK_CD:
  663.             /* Check if we should draw the cannon */
  664.             if ( ((ACannon *)map_points[y][x].objectptr)->cstate == DEAD
  665.                  && onoff == 1 )
  666.               break;
  667.             xbsz = map_points[y][x].edge_x;
  668.             ybsz = map_points[y][x].edge_y;
  669.             SetWriteMask(wRp, 3l);
  670.             SetAPen(wRp,cannon_pen); 
  671.             Move(wRp, xbsz-bp_x, ybsz-bp_y);
  672.             Draw(wRp, xbsz+bsz2-bp_x , ybsz+CAN_HEIGHT-bp_y);
  673.             Draw(wRp, xbsz+bsz-bp_x, ybsz-bp_y);
  674.             WaitBlit();
  675. #ifdef PURE_OS
  676.             HLINE(wRp, xbsz-bp_x, ybsz-bp_y, bsz1)
  677.             HLINE(wRp, xbsz-bp_x, ybsz-bp_y, bsz1)
  678. #else
  679.             HorizontalLine(bpl0, xbsz-bp_x, ybsz-bp_y, bsz1, onoff);
  680.             HorizontalLine(bpl1, xbsz-bp_x, ybsz-bp_y, bsz1, onoff);
  681. #endif
  682.             SetWriteMask(wRp, 2l);
  683.             SetAPen(wRp,map_pen); 
  684.             break;
  685.           case BLOCK_CR:
  686.             /* Check if we should draw the cannon */
  687.             if ( ((ACannon *)map_points[y][x].objectptr)->cstate == DEAD
  688.                  && onoff == 1 )
  689.               break;
  690.             xbsz = map_points[y][x].edge_x;
  691.             ybsz = map_points[y][x].edge_y;
  692.             SetWriteMask(wRp, 3l);
  693.             SetAPen(wRp,cannon_pen); 
  694.             Move(wRp, xbsz-bp_x, ybsz-bp_y);
  695.             Draw(wRp, xbsz+CAN_HEIGHT-bp_x , ybsz+bsz2-bp_y);
  696.             Draw(wRp, xbsz-bp_x, ybsz+bsz-bp_y);
  697.             WaitBlit();
  698. #ifdef PURE_OS
  699.             VLINE(wRp, xbsz-bp_x, ybsz-bp_y, bsz1)
  700.             VLINE(wRp, xbsz-bp_x, ybsz-bp_y, bsz1)
  701. #else
  702.             VerticalLine(bpl0, xbsz-bp_x, ybsz-bp_y, bsz1, onoff);
  703.             VerticalLine(bpl1, xbsz-bp_x, ybsz-bp_y, bsz1, onoff);
  704. #endif
  705.             SetWriteMask(wRp, 2l);
  706.             SetAPen(wRp,map_pen); 
  707.             break;
  708.           case BLOCK_CL:
  709.             /* Check if we should draw the cannon */
  710.             if ( ((ACannon *)map_points[y][x].objectptr)->cstate == DEAD
  711.                  && onoff == 1 )
  712.               break;
  713.             xbsz = map_points[y][x].edge_x;
  714.             ybsz = map_points[y][x].edge_y;
  715.             SetWriteMask(wRp, 3l);
  716.             SetAPen(wRp,cannon_pen); 
  717.             Move(wRp, xbsz+bsz-bp_x, ybsz-bp_y);
  718.             Draw(wRp, xbsz+bsz-CAN_HEIGHT-bp_x , ybsz+bsz2-bp_y);
  719.             Draw(wRp, xbsz+bsz-bp_x, ybsz+bsz-bp_y);
  720.             WaitBlit();
  721. #ifdef PURE_OS
  722.             VLINE(wRp, xbsz+bsz-bp_x, ybsz-bp_y, bsz1)
  723.             VLINE(wRp, xbsz+bsz-bp_x, ybsz-bp_y, bsz1)
  724. #else
  725.             VerticalLine(bpl0, xbsz+bsz-bp_x, ybsz-bp_y, bsz1, onoff);
  726.             VerticalLine(bpl1, xbsz+bsz-bp_x, ybsz-bp_y, bsz1, onoff);
  727. #endif
  728.             SetWriteMask(wRp, 2l);
  729.             SetAPen(wRp,map_pen); 
  730.             break;
  731.           case BLOCK_BASE:
  732.             xbsz = map_points[y][x].edge_x;
  733.             ybsz = map_points[y][x].edge_y;
  734. #ifdef PURE_OS
  735.             SetWriteMask(wRp, 3l); 
  736.             if (onoff == 1) SetAPen(wRp, 3);
  737.             HLINE(wRp, xbsz-bp_x, ybsz+bsz-bp_y, bsz1)
  738.             HLINE(wRp, xbsz-bp_x, ybsz+bsz-bp_y, bsz1)
  739.             if (onoff == 1) SetAPen(wRp, 2);
  740.             SetWriteMask(wRp, 2l);
  741. #else
  742.             HorizontalLine(bpl0, xbsz-bp_x, ybsz+bsz-bp_y, bsz1, onoff);
  743.             HorizontalLine(bpl1, xbsz-bp_x, ybsz+bsz-bp_y, bsz1, onoff);
  744. #endif
  745.             break;
  746.           default:
  747.             break;
  748.         }
  749.         x = x + map_points[y][x].empty2Right;
  750.       }
  751.     }
  752.   }
  753.   p_mapx[buf] = local_ship->pos.x;
  754.   p_mapy[buf] = local_ship->pos.y;
  755. }
  756.