home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / grafik / sprites / demosrc / sprdemo.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-02-25  |  14.4 KB  |  446 lines

  1. /**********************************************************************
  2. * sprdemo.c
  3. * A Sprite Toolkit demonstration program
  4. **********************************************************************
  5.                     This file is part of
  6.  
  7.           STK -- The sprite toolkit -- version 1.1
  8.  
  9.               Copyright (C) Jari Karjala 1991
  10.  
  11. The sprite toolkit (STK) is a FreeWare toolkit for creating high
  12. resolution sprite graphics with PCompatible hardware. This toolkit 
  13. is provided as is without any warranty or such thing. See the file
  14. COPYING for further information.
  15.  
  16. **********************************************************************
  17. **********************************************************************/
  18.  
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <alloc.h>
  22. #include <graphics.h>
  23. #include <time.h> 
  24.  
  25. #include "stk.h"            /*** The Sprite Toolkit prototypes ***/
  26.  
  27. #include "smp\anykeya.smp"
  28. #include "smp\anykeyb.smp"
  29. #include "smp\demo.smp"
  30. #include "smp\car.smp"
  31. #include "smp\one1.smp"
  32. #include "smp\one2.smp"
  33. #include "smp\one3.smp"
  34. #include "smp\one4.smp"
  35. #include "smp\two1.smp"
  36. #include "smp\two2.smp"
  37. #include "smp\two3.smp"
  38. #include "smp\two4.smp"
  39.  
  40. ANIM_SPRITE pacer;
  41.  
  42. void error(char *s)
  43. {
  44.     closegraph();
  45.     puts(s);
  46.     exit(255);    
  47. }
  48.  
  49. /**********************************************************************
  50. * Clear three bottom lines of the screen, run pacer amd wait for a key
  51. **********************************************************************/
  52. void wait_key(void)
  53. {
  54.     setfillstyle(EMPTY_FILL,0);
  55.     gr_setactivepage(0);
  56.     bar(0,spr_max_y-30,spr_max_x,spr_max_y);
  57.     gr_setactivepage(1);
  58.     bar(0,spr_max_y-30,spr_max_x,spr_max_y);
  59.     
  60.     spr_anim_start(pacer);
  61.     while (gr_inkey()) {    /** discard previous keys **/
  62.         gr_setactivepage(spr_anim_next_pass());
  63.         spr_regulate_speed();
  64.     }
  65.     while (!gr_inkey()) {   /** wait for a key press **/
  66.         gr_setactivepage(spr_anim_next_pass());
  67.         spr_regulate_speed();
  68.     }
  69.     spr_anim_stop(pacer);
  70.     gr_setactivepage(spr_anim_next_pass());
  71.     
  72.     /** now all sprites have disappeared from both display pages **/
  73.     /** and we can clear the display **/
  74.     gr_setactivepage(0);
  75.     cleardevice();
  76.     gr_setactivepage(1);
  77.     cleardevice();
  78.         
  79. }
  80.  
  81. /**********************************************************************
  82. * Initialize an animated sprite which wanders around the screen when 
  83. * we wait for a keypress.
  84. **********************************************************************/
  85. ANIM_SPRITE init_pacer(void)
  86. {
  87.     ANIM_SPRITE as;
  88.     
  89.     as = spr_anim_create(2, 
  90.                          spr_create(anykeya_width, anykeya_height,
  91.                                     anykeya_shape, anykeya_mask, 8, 1),
  92.                          spr_create(anykeyb_width, anykeyb_height,
  93.                                     anykeyb_shape, anykeyb_mask, 8, 1));
  94.     if (as==NULL)
  95.         return NULL;
  96.  
  97.     spr_anim_set_vector(as, -2, 1);
  98.     spr_anim_set_location(as, (spr_max_x-anykeya_width)/2, spr_max_y-50);
  99.     spr_anim_set_time(as, 0, 10, 0);
  100.     spr_anim_set_limits(as, 0, gr_max_y-60, gr_max_x, gr_max_y);
  101.     return as;
  102. }
  103.  
  104.  
  105. char *first_page_msg[] = {
  106.     "The Sprite Toolkit (STK) - Copyright Jari Karjala 1991",
  107.     "",
  108.     "",
  109.     "The STK functions provide support for sprites which do not",
  110.     "destroy background and whose size can be up to 512x256 pixels.",
  111.     "",
  112.     "Two interfaces are supported: The simple interface which provides",
  113.     "non-animated sprites which can be put on screen and erased.",
  114.     "The other interface supports automatically moving and animated",
  115.     "sprites. Both interfaces support collision detection at pixel",
  116.     "resolution. There is also a possibility to regulate the animation",
  117.     "speed to about 18 frames per second.",
  118.     "",
  119.     "Additional functions provide support for text IO in graphics",
  120.     "mode and direct keyboard reading (multiple simultanous keys).",
  121.     "",
  122.     "Currently only monochrome EGA and Hercules graphics supported.",
  123.     NULL
  124. };
  125.  
  126. /**********************************************************************
  127. * The intro page.
  128. **********************************************************************/
  129. void first_page(void)
  130. {
  131.     int i;
  132.     
  133.     for (i=0; first_page_msg[i]!=NULL && !gr_inkey(); i++)
  134.         gr_dual_xy_printf((spr_max_x-640)/2+48, i*10+32, first_page_msg[i]);
  135.     
  136.     wait_key();
  137. }
  138.  
  139. #define MAX_SPR 8
  140. #define MAX_FRAME 500
  141.  
  142. /**********************************************************************
  143. * Run MAX_SPR sprites by MAX_FRAME one pixel steps
  144. **********************************************************************/
  145. void run_simple_sprites(SPRITE sprites[MAX_SPR], int regulate)
  146. {
  147.     int i,j;
  148.     
  149.     for (i=0; i<MAX_FRAME; i++) {
  150.         for (j=0; j<MAX_SPR; j++)
  151.             spr_put(sprites[j], i, 50+(8+demo_height)*j);
  152.         gr_setactivepage(spr_next_pass());
  153.         if (regulate)
  154.             spr_regulate_speed();
  155.         if (gr_inkey())
  156.             break;
  157.     }
  158. }
  159.  
  160. /**********************************************************************
  161. * Demonstrate the simple sprite interface (SPR functions)
  162. **********************************************************************/
  163. void spr_demo(void)
  164. {
  165.     SPRITE sprites[MAX_SPR];
  166.     int i;
  167.     clock_t t1;
  168.     float t;
  169.     long far_free;
  170.     
  171.     gr_dual_xy_printf(0,0,"Demonstrating the simple sprite interface:");
  172.  
  173.     /**** First create the example sprites and background ****/
  174.     far_free = farcoreleft();
  175.     for (i=0; i<MAX_SPR; i++) {
  176.         sprites[i] = spr_create(demo_width, demo_height,
  177.                                 demo_shape, demo_mask, (1<<(i%4)), i);
  178.         
  179.         if (sprites[i]==NULL)
  180.             error("spr_demo: cannot create sprites");
  181.         
  182.         gr_dual_center_printf(56+(8+demo_height)*i,
  183.             ">> Horizontal resolution %d pixels, %d bytes memory needed <<",
  184.             8/(1<<(i%4)), far_free - farcoreleft());
  185.         far_free = farcoreleft();
  186.     }
  187.  
  188.     gr_dual_xy_printf(0,320,
  189.       "The STK functions used:");
  190.     gr_dual_xy_printf(0,330,
  191.       " spr_create, gr_dual_xy_printf, gr_inkey");
  192.     gr_dual_xy_printf(0,340,
  193.       " spr_put, spr_next_pass, spr_regulate_speed");
  194.     
  195.     /**** Then show some movement ****/
  196.     gr_dual_xy_printf(0,10,"First movement at appr. 18 frames/second...");
  197.     t1 = clock();
  198.     run_simple_sprites(sprites, 1);
  199.     t = (clock() - t1)/CLK_TCK;
  200.     if (t>1.0)
  201.         gr_dual_xy_printf(0,10, "%d frames, %.1f seconds, %.1f frames/second",
  202.                           MAX_FRAME, t, MAX_FRAME/t);
  203.     else
  204.         gr_dual_xy_printf(0,10, "%-50s","Cancelled.");
  205.  
  206.     
  207.     gr_dual_xy_printf(0,20,"Now movement at the fastest speed...");
  208.     t1 = clock();
  209.     run_simple_sprites(sprites, 0);
  210.     t = (clock() - t1)/CLK_TCK;
  211.     if (t>1.0)
  212.         gr_dual_xy_printf(0,20, "%d frames, %.1f seconds, %.1f frames/second",
  213.                           MAX_FRAME, t, MAX_FRAME/t);
  214.     else
  215.         gr_dual_xy_printf(0,20, "%-50s","Cancelled.");
  216.  
  217.     wait_key();
  218.     
  219.     /**** Delete sprites ****/
  220.     for (i=0; i<MAX_SPR; i++)
  221.         spr_delete(sprites[i]);
  222.     gr_setactivepage(spr_next_pass());
  223. }
  224.  
  225. /**********************************************************************
  226. * Demonstrate the collision detections (SPR_HIT functions)
  227. **********************************************************************/
  228. void spr_hit_demo(void)
  229. {
  230.     SPRITE s1,s2,s3;
  231.     int i,j;
  232.     
  233.     gr_dual_xy_printf(0,0,"Demonstrating the collision detection:");
  234.     
  235.     s1 = spr_create(demo_width, demo_height,
  236.                     demo_shape, demo_mask, 8, 1);
  237.     
  238.     s2 = spr_create(demo_width, demo_height,
  239.                     demo_shape, demo_mask, 8, 2);
  240.     
  241.     s3 = spr_create(car_width, car_height,
  242.                     car_shape, car_mask, 8, 3);
  243.     
  244.     gr_dual_xy_printf(0,320,
  245.       "The STK functions used:");
  246.     gr_dual_xy_printf(0,330,
  247.       " spr_create, gr_dual_xy_printf, gr_inkey");
  248.     gr_dual_xy_printf(0,340,
  249.       " spr_put, spr_hit, spr_next_pass, spr_regulate_speed");
  250.     
  251.     gr_dual_xy_printf(0,20,"Collision between UFOs:");
  252.     gr_dual_xy_printf(0,30,"Collision between UFO and car:");
  253.     j = (gr_max_x-car_width)/2;
  254.     for (i=10; i<j; i++) {
  255.         spr_put(s1, gr_max_x - i - 150, 100);
  256.         spr_put(s2, gr_max_x - i*2 - 50, 110);
  257.         spr_put(s3, i*2, 90);
  258.         
  259.         if (spr_hit(s1,s2))
  260.             gr_dual_xy_printf(24*8,20,"YES");
  261.         else
  262.             gr_dual_xy_printf(24*8,20,"no ");
  263.         
  264.         if (spr_hit(s1,s3) || spr_hit(s2,s3))
  265.             gr_dual_xy_printf(32*8,30,"YES");
  266.         else
  267.             gr_dual_xy_printf(32*8,30,"no ");
  268.         
  269.         spr_next_pass();
  270.         spr_regulate_speed();
  271.         if (gr_inkey())
  272.             break;
  273.     }
  274.         
  275.     wait_key();
  276. }
  277.  
  278. #define BOX_LEF 200
  279. #define BOX_RIG (gr_max_x-BOX_LEF)
  280. #define BOX_TOP 100
  281. #define BOX_BOT (gr_max_y-BOX_TOP)
  282.  
  283.  
  284. WORD demo_fx_handler(ANIM_SPRITE aspr, WORD fx, SPRITE spr)
  285. {
  286.     ANIM_SPR_INFO *asi;
  287.     WORD ret_code = SPR_ANIM_FX_RET_RE_PUT;
  288.  
  289.     asi = spr_anim_get_info(aspr);
  290.  
  291.     switch (fx) {
  292.         case SPR_ANIM_FX_TIMEOUT:
  293.             spr_anim_set_vector(aspr, 2-random(5), 2-random(4));
  294.             spr_anim_set_time(aspr, -1, -1, random(500)+200);
  295.             break;
  296.             
  297.         case SPR_ANIM_FX_HIT_X_LIMIT:
  298.             if (asi->x > asi->rig) {
  299.                 spr_anim_set_location(aspr, asi->rig, asi->y);
  300.                 spr_anim_set_vector(aspr, -asi->dx, asi->dy);
  301.             }
  302.             else {
  303.                 spr_anim_set_location(aspr, asi->lef, asi->y);
  304.                 spr_anim_set_vector(aspr, -asi->dx, asi->dy);
  305.             }
  306.             break;
  307.  
  308.         case SPR_ANIM_FX_HIT_Y_LIMIT:
  309.             if (asi->y > asi->bot) {
  310.                 spr_anim_set_location(aspr, asi->x, asi->bot);
  311.                 spr_anim_set_vector(aspr, asi->dx, -asi->dy);
  312.             }
  313.             else {
  314.                 spr_anim_set_location(aspr, asi->x, asi->top);
  315.                 spr_anim_set_vector(aspr, asi->dx, -asi->dy);
  316.             }
  317.             break;
  318.  
  319.         case SPR_ANIM_FX_HIT_SPRITE:
  320.             if (asi->id==2)
  321.                 spr_anim_set_vector(aspr, -asi->dx, asi->dy);
  322.             break;
  323.             
  324.         default:
  325.             ret_code = SPR_ANIM_FX_RET_DELETE;
  326.     }
  327.     return ret_code;
  328. }
  329.  
  330. /**********************************************************************
  331. * Demonstrate the animated sprite interface (SPR_ANIM functions)
  332. **********************************************************************/
  333. void spr_anim_demo(void)
  334. {
  335.     ANIM_SPRITE as1,as2;
  336.     
  337.     gr_dual_xy_printf(0,0,"Demonstrating the animated sprites:");
  338.  
  339.     as1 = spr_anim_create(6, 
  340.                          spr_create(one1_width, one1_height,
  341.                                     one1_shape, one1_mask, 8, 1),
  342.                          spr_create(one2_width, one2_height,
  343.                                     one2_shape, one2_mask, 8, 1),
  344.                          spr_create(one3_width, one3_height,
  345.                                     one3_shape, one3_mask, 8, 1),
  346.                          spr_create(one4_width, one4_height,
  347.                                     one4_shape, one4_mask, 8, 1),
  348.                          spr_create(one3_width, one3_height,
  349.                                     one3_shape, one3_mask, 8, 1),
  350.                          spr_create(one2_width, one2_height,
  351.                                     one2_shape, one2_mask, 8, 1)
  352.                          );
  353.     if (as1==NULL)
  354.         return;
  355.  
  356.     spr_anim_set_limits(as1,BOX_LEF,BOX_TOP,BOX_RIG,BOX_BOT);
  357.     spr_anim_set_vector(as1, 2, 1);
  358.     spr_anim_set_location(as1, BOX_LEF+8, BOX_TOP+8);
  359.     spr_anim_set_fx_handler(as1, SPR_ANIM_FX_ALL, demo_fx_handler);
  360.     spr_anim_set_time(as1, 0, 3, 1000);
  361.     spr_anim_start(as1);
  362.     
  363.     as2 = spr_anim_create(6, 
  364.                          spr_create(two1_width, two1_height,
  365.                                     two1_shape, two1_mask, 8, 2),
  366.                          spr_create(two2_width, two2_height,
  367.                                     two2_shape, two2_mask, 8, 2),
  368.                          spr_create(two3_width, two3_height,
  369.                                     two3_shape, two3_mask, 8, 2),
  370.                          spr_create(two4_width, two4_height,
  371.                                     two4_shape, two4_mask, 8, 2),
  372.                          spr_create(two3_width, two3_height,
  373.                                     two3_shape, two3_mask, 8, 2),
  374.                          spr_create(two2_width, two2_height,
  375.                                     two2_shape, two2_mask, 8, 2)
  376.                          );
  377.     if (as2==NULL) {
  378.         spr_anim_destroy(as1);
  379.         return;
  380.     }
  381.  
  382.     spr_anim_set_limits(as2,BOX_LEF,BOX_TOP,BOX_RIG,BOX_BOT);
  383.     spr_anim_set_vector(as2, 2, -1);
  384.     spr_anim_set_location(as2, BOX_LEF+8, BOX_BOT-two1_height-8);
  385.     spr_anim_set_fx_handler(as2, SPR_ANIM_FX_ALL, demo_fx_handler);
  386.     spr_anim_set_time(as2, 3, 4, 500);
  387.     spr_anim_start(as2);
  388.  
  389.     /*** Sprites ready, draw the bounding box ***/
  390.     gr_setactivepage(1);
  391.     rectangle(BOX_LEF,BOX_TOP,BOX_RIG,BOX_BOT);
  392.     gr_setactivepage(0);
  393.     rectangle(BOX_LEF,BOX_TOP,BOX_RIG,BOX_BOT);
  394.     
  395.     /*** Wait key animates all sprites ***/
  396.     wait_key();
  397.     
  398.     spr_anim_destroy(as1);
  399.     spr_anim_destroy(as2);
  400. }
  401.  
  402. /**********************************************************************
  403. * The last page before DOS.
  404. **********************************************************************/
  405. void last_page(void)
  406. {
  407.     gr_dual_center_printf(100, "That's all, folks.  Thank You!");
  408.  
  409.     wait_key();
  410. }
  411.  
  412. int main(int argc, char **argv)
  413. {
  414.     int i,j;
  415.  
  416.     /**** Detect a suitable graphics mode, start it and init spr module ****/
  417.     gr_detect(GR_TYPE_SPR, &i, &j);
  418.     if (i == -1) {
  419.         puts("Unsupported graphics mode, need EGA or Hercules!");
  420.         return 1;
  421.     }
  422.     gr_text_mode = GR_MODE_CLEAR_FAST;
  423.     gr_start(&i, &j);
  424.     spr_initialize(i);
  425.     if (argc>1)     /** modify pass delay if given **/
  426.         spr_pass_delay = atoi(argv[1]);
  427.  
  428.     pacer = init_pacer();
  429.     if (pacer==NULL)
  430.         error("main: Cannot initialize pacer sprite");
  431.     
  432.     first_page();
  433.     spr_demo();
  434.     spr_hit_demo();
  435.     spr_anim_demo();
  436.     last_page();
  437.     
  438.     /**** No real need to use gr_end since it is bound with atexit() ****/
  439.     gr_end();
  440.     
  441.     return 0;
  442.     
  443. }
  444.