home *** CD-ROM | disk | FTP | other *** search
- /**********************************************************************
- * sprdemo.c
- *
- * A Sprite Toolkit demonstration program
- *
- **********************************************************************
- This file is part of
-
- STK -- The sprite toolkit -- version 1.1
-
- Copyright (C) Jari Karjala 1991
-
- The sprite toolkit (STK) is a FreeWare toolkit for creating high
- resolution sprite graphics with PCompatible hardware. This toolkit
- is provided as is without any warranty or such thing. See the file
- COPYING for further information.
-
- **********************************************************************
- **********************************************************************/
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <alloc.h>
- #include <graphics.h>
- #include <time.h>
-
- #include "stk.h" /*** The Sprite Toolkit prototypes ***/
-
- #include "smp\anykeya.smp"
- #include "smp\anykeyb.smp"
- #include "smp\demo.smp"
- #include "smp\car.smp"
- #include "smp\one1.smp"
- #include "smp\one2.smp"
- #include "smp\one3.smp"
- #include "smp\one4.smp"
- #include "smp\two1.smp"
- #include "smp\two2.smp"
- #include "smp\two3.smp"
- #include "smp\two4.smp"
-
- ANIM_SPRITE pacer;
-
- void error(char *s)
- {
- closegraph();
- puts(s);
- exit(255);
- }
-
- /**********************************************************************
- * Clear three bottom lines of the screen, run pacer amd wait for a key
- **********************************************************************/
- void wait_key(void)
- {
- setfillstyle(EMPTY_FILL,0);
- gr_setactivepage(0);
- bar(0,spr_max_y-30,spr_max_x,spr_max_y);
- gr_setactivepage(1);
- bar(0,spr_max_y-30,spr_max_x,spr_max_y);
-
- spr_anim_start(pacer);
- while (gr_inkey()) { /** discard previous keys **/
- gr_setactivepage(spr_anim_next_pass());
- spr_regulate_speed();
- }
- while (!gr_inkey()) { /** wait for a key press **/
- gr_setactivepage(spr_anim_next_pass());
- spr_regulate_speed();
- }
- spr_anim_stop(pacer);
- gr_setactivepage(spr_anim_next_pass());
-
- /** now all sprites have disappeared from both display pages **/
- /** and we can clear the display **/
- gr_setactivepage(0);
- cleardevice();
- gr_setactivepage(1);
- cleardevice();
-
- }
-
- /**********************************************************************
- * Initialize an animated sprite which wanders around the screen when
- * we wait for a keypress.
- **********************************************************************/
- ANIM_SPRITE init_pacer(void)
- {
- ANIM_SPRITE as;
-
- as = spr_anim_create(2,
- spr_create(anykeya_width, anykeya_height,
- anykeya_shape, anykeya_mask, 8, 1),
- spr_create(anykeyb_width, anykeyb_height,
- anykeyb_shape, anykeyb_mask, 8, 1));
- if (as==NULL)
- return NULL;
-
- spr_anim_set_vector(as, -2, 1);
- spr_anim_set_location(as, (spr_max_x-anykeya_width)/2, spr_max_y-50);
- spr_anim_set_time(as, 0, 10, 0);
- spr_anim_set_limits(as, 0, gr_max_y-60, gr_max_x, gr_max_y);
- return as;
- }
-
-
- char *first_page_msg[] = {
- "The Sprite Toolkit (STK) - Copyright Jari Karjala 1991",
- "",
- "",
- "The STK functions provide support for sprites which do not",
- "destroy background and whose size can be up to 512x256 pixels.",
- "",
- "Two interfaces are supported: The simple interface which provides",
- "non-animated sprites which can be put on screen and erased.",
- "The other interface supports automatically moving and animated",
- "sprites. Both interfaces support collision detection at pixel",
- "resolution. There is also a possibility to regulate the animation",
- "speed to about 18 frames per second.",
- "",
- "Additional functions provide support for text IO in graphics",
- "mode and direct keyboard reading (multiple simultanous keys).",
- "",
- "Currently only monochrome EGA and Hercules graphics supported.",
- NULL
- };
-
- /**********************************************************************
- * The intro page.
- **********************************************************************/
- void first_page(void)
- {
- int i;
-
- for (i=0; first_page_msg[i]!=NULL && !gr_inkey(); i++)
- gr_dual_xy_printf((spr_max_x-640)/2+48, i*10+32, first_page_msg[i]);
-
- wait_key();
- }
-
- #define MAX_SPR 8
- #define MAX_FRAME 500
-
- /**********************************************************************
- * Run MAX_SPR sprites by MAX_FRAME one pixel steps
- **********************************************************************/
- void run_simple_sprites(SPRITE sprites[MAX_SPR], int regulate)
- {
- int i,j;
-
- for (i=0; i<MAX_FRAME; i++) {
- for (j=0; j<MAX_SPR; j++)
- spr_put(sprites[j], i, 50+(8+demo_height)*j);
- gr_setactivepage(spr_next_pass());
- if (regulate)
- spr_regulate_speed();
- if (gr_inkey())
- break;
- }
- }
-
- /**********************************************************************
- * Demonstrate the simple sprite interface (SPR functions)
- **********************************************************************/
- void spr_demo(void)
- {
- SPRITE sprites[MAX_SPR];
- int i;
- clock_t t1;
- float t;
- long far_free;
-
- gr_dual_xy_printf(0,0,"Demonstrating the simple sprite interface:");
-
- /**** First create the example sprites and background ****/
- far_free = farcoreleft();
- for (i=0; i<MAX_SPR; i++) {
- sprites[i] = spr_create(demo_width, demo_height,
- demo_shape, demo_mask, (1<<(i%4)), i);
-
- if (sprites[i]==NULL)
- error("spr_demo: cannot create sprites");
-
- gr_dual_center_printf(56+(8+demo_height)*i,
- ">> Horizontal resolution %d pixels, %d bytes memory needed <<",
- 8/(1<<(i%4)), far_free - farcoreleft());
- far_free = farcoreleft();
- }
-
- gr_dual_xy_printf(0,320,
- "The STK functions used:");
- gr_dual_xy_printf(0,330,
- " spr_create, gr_dual_xy_printf, gr_inkey");
- gr_dual_xy_printf(0,340,
- " spr_put, spr_next_pass, spr_regulate_speed");
-
- /**** Then show some movement ****/
- gr_dual_xy_printf(0,10,"First movement at appr. 18 frames/second...");
- t1 = clock();
- run_simple_sprites(sprites, 1);
- t = (clock() - t1)/CLK_TCK;
- if (t>1.0)
- gr_dual_xy_printf(0,10, "%d frames, %.1f seconds, %.1f frames/second",
- MAX_FRAME, t, MAX_FRAME/t);
- else
- gr_dual_xy_printf(0,10, "%-50s","Cancelled.");
-
-
- gr_dual_xy_printf(0,20,"Now movement at the fastest speed...");
- t1 = clock();
- run_simple_sprites(sprites, 0);
- t = (clock() - t1)/CLK_TCK;
- if (t>1.0)
- gr_dual_xy_printf(0,20, "%d frames, %.1f seconds, %.1f frames/second",
- MAX_FRAME, t, MAX_FRAME/t);
- else
- gr_dual_xy_printf(0,20, "%-50s","Cancelled.");
-
- wait_key();
-
- /**** Delete sprites ****/
- for (i=0; i<MAX_SPR; i++)
- spr_delete(sprites[i]);
- gr_setactivepage(spr_next_pass());
- }
-
- /**********************************************************************
- * Demonstrate the collision detections (SPR_HIT functions)
- **********************************************************************/
- void spr_hit_demo(void)
- {
- SPRITE s1,s2,s3;
- int i,j;
-
- gr_dual_xy_printf(0,0,"Demonstrating the collision detection:");
-
- s1 = spr_create(demo_width, demo_height,
- demo_shape, demo_mask, 8, 1);
-
- s2 = spr_create(demo_width, demo_height,
- demo_shape, demo_mask, 8, 2);
-
- s3 = spr_create(car_width, car_height,
- car_shape, car_mask, 8, 3);
-
- gr_dual_xy_printf(0,320,
- "The STK functions used:");
- gr_dual_xy_printf(0,330,
- " spr_create, gr_dual_xy_printf, gr_inkey");
- gr_dual_xy_printf(0,340,
- " spr_put, spr_hit, spr_next_pass, spr_regulate_speed");
-
- gr_dual_xy_printf(0,20,"Collision between UFOs:");
- gr_dual_xy_printf(0,30,"Collision between UFO and car:");
- j = (gr_max_x-car_width)/2;
- for (i=10; i<j; i++) {
- spr_put(s1, gr_max_x - i - 150, 100);
- spr_put(s2, gr_max_x - i*2 - 50, 110);
- spr_put(s3, i*2, 90);
-
- if (spr_hit(s1,s2))
- gr_dual_xy_printf(24*8,20,"YES");
- else
- gr_dual_xy_printf(24*8,20,"no ");
-
- if (spr_hit(s1,s3) || spr_hit(s2,s3))
- gr_dual_xy_printf(32*8,30,"YES");
- else
- gr_dual_xy_printf(32*8,30,"no ");
-
- spr_next_pass();
- spr_regulate_speed();
- if (gr_inkey())
- break;
- }
-
- wait_key();
- }
-
- #define BOX_LEF 200
- #define BOX_RIG (gr_max_x-BOX_LEF)
- #define BOX_TOP 100
- #define BOX_BOT (gr_max_y-BOX_TOP)
-
-
- WORD demo_fx_handler(ANIM_SPRITE aspr, WORD fx, SPRITE spr)
- {
- ANIM_SPR_INFO *asi;
- WORD ret_code = SPR_ANIM_FX_RET_RE_PUT;
-
- asi = spr_anim_get_info(aspr);
-
- switch (fx) {
- case SPR_ANIM_FX_TIMEOUT:
- spr_anim_set_vector(aspr, 2-random(5), 2-random(4));
- spr_anim_set_time(aspr, -1, -1, random(500)+200);
- break;
-
- case SPR_ANIM_FX_HIT_X_LIMIT:
- if (asi->x > asi->rig) {
- spr_anim_set_location(aspr, asi->rig, asi->y);
- spr_anim_set_vector(aspr, -asi->dx, asi->dy);
- }
- else {
- spr_anim_set_location(aspr, asi->lef, asi->y);
- spr_anim_set_vector(aspr, -asi->dx, asi->dy);
- }
- break;
-
- case SPR_ANIM_FX_HIT_Y_LIMIT:
- if (asi->y > asi->bot) {
- spr_anim_set_location(aspr, asi->x, asi->bot);
- spr_anim_set_vector(aspr, asi->dx, -asi->dy);
- }
- else {
- spr_anim_set_location(aspr, asi->x, asi->top);
- spr_anim_set_vector(aspr, asi->dx, -asi->dy);
- }
- break;
-
- case SPR_ANIM_FX_HIT_SPRITE:
- if (asi->id==2)
- spr_anim_set_vector(aspr, -asi->dx, asi->dy);
- break;
-
- default:
- ret_code = SPR_ANIM_FX_RET_DELETE;
- }
- return ret_code;
- }
-
- /**********************************************************************
- * Demonstrate the animated sprite interface (SPR_ANIM functions)
- **********************************************************************/
- void spr_anim_demo(void)
- {
- ANIM_SPRITE as1,as2;
-
- gr_dual_xy_printf(0,0,"Demonstrating the animated sprites:");
-
- as1 = spr_anim_create(6,
- spr_create(one1_width, one1_height,
- one1_shape, one1_mask, 8, 1),
- spr_create(one2_width, one2_height,
- one2_shape, one2_mask, 8, 1),
- spr_create(one3_width, one3_height,
- one3_shape, one3_mask, 8, 1),
- spr_create(one4_width, one4_height,
- one4_shape, one4_mask, 8, 1),
- spr_create(one3_width, one3_height,
- one3_shape, one3_mask, 8, 1),
- spr_create(one2_width, one2_height,
- one2_shape, one2_mask, 8, 1)
- );
- if (as1==NULL)
- return;
-
- spr_anim_set_limits(as1,BOX_LEF,BOX_TOP,BOX_RIG,BOX_BOT);
- spr_anim_set_vector(as1, 2, 1);
- spr_anim_set_location(as1, BOX_LEF+8, BOX_TOP+8);
- spr_anim_set_fx_handler(as1, SPR_ANIM_FX_ALL, demo_fx_handler);
- spr_anim_set_time(as1, 0, 3, 1000);
- spr_anim_start(as1);
-
- as2 = spr_anim_create(6,
- spr_create(two1_width, two1_height,
- two1_shape, two1_mask, 8, 2),
- spr_create(two2_width, two2_height,
- two2_shape, two2_mask, 8, 2),
- spr_create(two3_width, two3_height,
- two3_shape, two3_mask, 8, 2),
- spr_create(two4_width, two4_height,
- two4_shape, two4_mask, 8, 2),
- spr_create(two3_width, two3_height,
- two3_shape, two3_mask, 8, 2),
- spr_create(two2_width, two2_height,
- two2_shape, two2_mask, 8, 2)
- );
- if (as2==NULL) {
- spr_anim_destroy(as1);
- return;
- }
-
- spr_anim_set_limits(as2,BOX_LEF,BOX_TOP,BOX_RIG,BOX_BOT);
- spr_anim_set_vector(as2, 2, -1);
- spr_anim_set_location(as2, BOX_LEF+8, BOX_BOT-two1_height-8);
- spr_anim_set_fx_handler(as2, SPR_ANIM_FX_ALL, demo_fx_handler);
- spr_anim_set_time(as2, 3, 4, 500);
- spr_anim_start(as2);
-
- /*** Sprites ready, draw the bounding box ***/
- gr_setactivepage(1);
- rectangle(BOX_LEF,BOX_TOP,BOX_RIG,BOX_BOT);
- gr_setactivepage(0);
- rectangle(BOX_LEF,BOX_TOP,BOX_RIG,BOX_BOT);
-
- /*** Wait key animates all sprites ***/
- wait_key();
-
- spr_anim_destroy(as1);
- spr_anim_destroy(as2);
- }
-
- /**********************************************************************
- * The last page before DOS.
- **********************************************************************/
- void last_page(void)
- {
- gr_dual_center_printf(100, "That's all, folks. Thank You!");
-
- wait_key();
- }
-
- int main(int argc, char **argv)
- {
- int i,j;
-
- /**** Detect a suitable graphics mode, start it and init spr module ****/
- gr_detect(GR_TYPE_SPR, &i, &j);
- if (i == -1) {
- puts("Unsupported graphics mode, need EGA or Hercules!");
- return 1;
- }
- gr_text_mode = GR_MODE_CLEAR_FAST;
- gr_start(&i, &j);
- spr_initialize(i);
- if (argc>1) /** modify pass delay if given **/
- spr_pass_delay = atoi(argv[1]);
-
- pacer = init_pacer();
- if (pacer==NULL)
- error("main: Cannot initialize pacer sprite");
-
- first_page();
- spr_demo();
- spr_hit_demo();
- spr_anim_demo();
- last_page();
-
- /**** No real need to use gr_end since it is bound with atexit() ****/
- gr_end();
-
- return 0;
-
- }
-