home *** CD-ROM | disk | FTP | other *** search
/ Teach Yourself Game Programming in 21 Days / TYGAMES_R.ISO / source / day_03 / strfield.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-07-25  |  9.1 KB  |  375 lines

  1.  
  2. // I N C L U D E S ///////////////////////////////////////////////////////////
  3.  
  4. #include <dos.h>
  5. #include <bios.h>
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <math.h>
  9. #include <conio.h>
  10.  
  11. // D E F I N E S /////////////////////////////////////////////////////////////
  12.  
  13. #define NUM_STARS  75
  14.  
  15. #define PLANE_1    1
  16. #define PLANE_2    2
  17. #define PLANE_3    3
  18.  
  19. #define VGA256     0x13
  20. #define TEXT_MODE  0x03
  21.  
  22. #define ROM_CHAR_SET_SEG 0xF000  // segment of 8x8 ROM character set
  23. #define ROM_CHAR_SET_OFF 0xFA6E  // begining offset of 8x8 ROM character set
  24.  
  25. #define CHAR_WIDTH        8      // size of characters
  26. #define CHAR_HEIGHT       8
  27.  
  28. #define SCREEN_WIDTH      (unsigned int)320 // mode 13h screen dimensions
  29. #define SCREEN_HEIGHT     (unsigned int)200
  30.  
  31. // P R O T O T Y P E S ///////////////////////////////////////////////////////
  32.  
  33. void Blit_Char(int xc,int yc,char c,int color,int trans_flag);
  34.  
  35. void Blit_String(int x,int y,int color, char *string,int trans_flag);
  36.  
  37. void Plot_Pixel_Fast(int x,int y,unsigned char color);
  38.  
  39. void Init_Stars(void);
  40.  
  41. void Set_Video_Mode(int mode);
  42.  
  43. void Delay(int clicks);
  44.  
  45. // S T R U C T U R E S ///////////////////////////////////////////////////////
  46.  
  47. // data structure for a single star
  48.  
  49. typedef struct star_typ
  50.         {
  51.         int x,y;    // position of star
  52.         int plane;  // which plane is star in
  53.         int color;  // color of star
  54.  
  55.         } star, *star_ptr;
  56.  
  57.  
  58. // G L O B A L S /////////////////////////////////////////////////////////////
  59.  
  60. unsigned char far *video_buffer = (char far *)0xA0000000L; // vram byte ptr
  61.  
  62. unsigned char far *rom_char_set = (char far *)0xF000FA6EL; // rom characters 8x8
  63.  
  64. int star_first=1;  // flags first time into star field
  65.  
  66. star stars[NUM_STARS]; // the star field
  67.  
  68. int velocity_1=2,      // the speeds of each plane
  69.     velocity_2=4,
  70.     velocity_3=6;
  71.  
  72.  
  73. // F U N C T I O N S ////////////////////////////////////////////////////////
  74.  
  75. void Blit_Char(int xc,int yc,char c,int color,int trans_flag)
  76. {
  77. // this function uses the rom 8x8 character set to blit a character on the
  78. // video screen, notice the trick used to extract bits out of each character
  79. // byte that comprises a line
  80.  
  81. int offset,x,y;
  82. char far *work_char;
  83. unsigned char bit_mask = 0x80;
  84.  
  85. // compute starting offset in rom character lookup table
  86.  
  87. work_char = rom_char_set + c * CHAR_HEIGHT;
  88.  
  89. // compute offset of character in video buffer
  90.  
  91. offset = (yc << 8) + (yc << 6) + xc;
  92.  
  93. for (y=0; y<CHAR_HEIGHT; y++)
  94.     {
  95.     // reset bit mask
  96.  
  97.     bit_mask = 0x80;
  98.  
  99.     for (x=0; x<CHAR_WIDTH; x++)
  100.         {
  101.         // test for transparent pixel i.e. 0, if not transparent then draw
  102.  
  103.         if ((*work_char & bit_mask))
  104.              video_buffer[offset+x] = color;
  105.  
  106.         else if (!trans_flag)  // takes care of transparency
  107.             video_buffer[offset+x] = 0;
  108.  
  109.         // shift bit mask
  110.  
  111.         bit_mask = (bit_mask>>1);
  112.  
  113.         } // end for x
  114.  
  115.     // move to next line in video buffer and in rom character data area
  116.  
  117.     offset      += SCREEN_WIDTH;
  118.     work_char++;
  119.  
  120.     } // end for y
  121.  
  122. } // end Blit_Char
  123.  
  124. //////////////////////////////////////////////////////////////////////////////
  125.  
  126. void Blit_String(int x,int y,int color, char *string,int trans_flag)
  127. {
  128. // this function blits an entire string on the screen with fixed spacing
  129. // between each character.  it calls blit_char.
  130.  
  131. int index;
  132.  
  133. for (index=0; string[index]!=0; index++)
  134.      {
  135.  
  136.      Blit_Char(x+(index<<3),y,string[index],color,trans_flag);
  137.  
  138.      } /* end while */
  139.  
  140. } /* end Blit_String */
  141.  
  142. ///////////////////////////////////////////////////////////////////////////////
  143.  
  144. void Plot_Pixel_Fast(int x,int y,unsigned char color)
  145. {
  146.  
  147. // plots the pixel in the desired color a little quicker using binary shifting
  148. // to accomplish the multiplications
  149.  
  150. // use the fact that 320*y = 256*y + 64*y = y<<8 + y<<6
  151.  
  152. video_buffer[((y<<8) + (y<<6)) + x] = color;
  153.  
  154. } // end Plot_Pixel_Fast
  155.  
  156. //////////////////////////////////////////////////////////////////////////////
  157.  
  158. void Init_Stars(void)
  159. {
  160.  
  161. // this function will initialize the star field
  162.  
  163. int index;
  164.  
  165. // for each star choose a position, plane and color
  166.  
  167. for (index=0; index<NUM_STARS; index++)
  168.     {
  169.     // initialize each star to a velocity, position and color
  170.  
  171.     stars[index].x     = rand()%320;
  172.     stars[index].y     = rand()%180;
  173.  
  174.     // decide what star plane the star is in
  175.  
  176.     switch(rand()%3)
  177.           {
  178.           case 0: // plane 1- the farthest star plane
  179.                {
  180.                // set velocity and color
  181.  
  182.                stars[index].plane = 1;
  183.                stars[index].color = 8;
  184.  
  185.                } break;
  186.  
  187.           case 1: // plane 2-The medium distance star plane
  188.                {
  189.  
  190.                stars[index].plane = 2;
  191.                stars[index].color = 7;
  192.  
  193.                } break;
  194.  
  195.           case 2: // plane 3-The nearest star plane
  196.                {
  197.  
  198.                stars[index].plane = 3;
  199.                stars[index].color = 15;
  200.  
  201.                } break;
  202.  
  203.           } // end switch
  204.  
  205.     } // end for index
  206.  
  207. } // end Init_Stars
  208.  
  209. //////////////////////////////////////////////////////////////////////////////
  210.  
  211. void Set_Video_Mode(int mode)
  212. {
  213.  
  214. // use the video interrupt 10h to set the video mode to the sent value
  215.  
  216. union REGS inregs,outregs;
  217.  
  218. inregs.h.ah = 0;                    // set video mode sub-function
  219. inregs.h.al = (unsigned char)mode;  // video mode to change to
  220.  
  221. _int86(0x10, &inregs, &outregs);
  222.  
  223. } // end Set_Video_Mode
  224.  
  225. /////////////////////////////////////////////////////////////////////////////
  226.  
  227. void Delay(int clicks)
  228. {
  229. // this function uses the internal time keeper timer i.e. the one that goes
  230. // at 18.2 clicks/sec to to a time delay.  You can find a 32 bit value of
  231. // this timer at 0000:046Ch
  232.  
  233. unsigned int far *clock = (unsigned int far *)0x0000046CL;
  234.  
  235. unsigned int now;
  236.  
  237. // get current time
  238.  
  239. now = *clock;
  240.  
  241. // wait till time has gone past current time plus the amount we eanted to
  242. // wait.  Note each click is approx. 55 milliseconds.
  243.  
  244. while(abs(*clock - now) < clicks){}
  245.  
  246. } // end Delay
  247.  
  248. // M A I N ///////////////////////////////////////////////////////////////////
  249.  
  250. void main(void)
  251. {
  252.  
  253. int done=0, // exit flag
  254.     index;  // loop index
  255.  
  256. // set video mode to 320x200 256 color mode
  257.  
  258. Set_Video_Mode(VGA256);
  259.  
  260. // initialize the star field data structure
  261.  
  262. Init_Stars();
  263.  
  264. // begin main event loop
  265.  
  266. while(!done)
  267.      {
  268.  
  269.      // test if user is trying to do something
  270.  
  271.      if (kbhit())
  272.         {
  273.         // what key was pressed ?
  274.  
  275.         switch(getch())
  276.               {
  277.               case '-': // slow down star field
  278.                    {
  279.                    // decrease velocity of each plane
  280.  
  281.                    velocity_1-=1;
  282.                    velocity_2-=2;
  283.                    velocity_3-=3;
  284.  
  285.                    } break;
  286.  
  287.               case '=': // speed up star field
  288.                    {
  289.                    // increase velocity of each plane
  290.                    velocity_1+=1;
  291.                    velocity_2+=2;
  292.                    velocity_3+=3;
  293.  
  294.                    } break;
  295.  
  296.               case 'q': // user is exiting
  297.                    {
  298.                    done=1;
  299.                    } break;
  300.  
  301.               default:break;
  302.  
  303.               } // end switch
  304.  
  305.         } // end if kbhit
  306.  
  307.      // move the star fields
  308.  
  309.      for (index=0; index<NUM_STARS; index++)
  310.          {
  311.  
  312.          // erase the star
  313.  
  314.          Plot_Pixel_Fast(stars[index].x,stars[index].y,0);
  315.  
  316.          // move the star and test for off screen condition
  317.  
  318.          // each star is in a different plane so test which plane star is
  319.          // in so that proper velocity may be used
  320.  
  321.          switch(stars[index].plane)
  322.                {
  323.                case PLANE_1: // the slowest plane
  324.                     {
  325.                     stars[index].x+=velocity_1;
  326.                     } break;
  327.  
  328.                case PLANE_2: // the medium speed plane
  329.                     {
  330.                     stars[index].x+=velocity_2;
  331.                     } break;
  332.  
  333.                case PLANE_3: // the fastest plane (near)
  334.                     {
  335.                     stars[index].x+=velocity_3;
  336.                     } break;
  337.  
  338.                 } // end switch
  339.  
  340.          // test if star went off screen
  341.  
  342.          if (stars[index].x > 319 ) // off right edge?
  343.             stars[index].x=(stars[index].x-320); // wrap around
  344.          else
  345.          if (stars[index].x < 0) // off left edge?
  346.              stars[index].x = (320+stars[index].x); // wrap around
  347.  
  348.          // draw the star at new position
  349.  
  350.          Plot_Pixel_Fast(stars[index].x,stars[index].y,stars[index].color);
  351.  
  352.          } // end for
  353.  
  354.      // draw the directions again
  355.  
  356.      Blit_String(0,0,1, "Press '+' or '-' to change speed.",1);
  357.  
  358.      Blit_String(88,180,2, "Press 'Q' to exit.",1);
  359.  
  360.      // wait a second so we can see the stars, otherwise it will look like
  361.      // warp speed!
  362.  
  363.      Delay(1);
  364.  
  365.      } // end while
  366.  
  367. // reset back set video mode to 320x200 256 color mode
  368.  
  369. Set_Video_Mode(TEXT_MODE);
  370.  
  371. } // end main
  372.  
  373.  
  374.  
  375.