/*
==============================================================================
WordUp Graphics Toolkit Version 5.0
Demonstration Program 62
Yet another scrolling example to demonstrate some simple techniques.
The program uses rather small sprites and allows the user to configure
window size. Frame rates are calculated and displayed at the end of the
program. Elevators are available by pressing UP ARROW when standing on one.
▒▒▒ PROJECT ▒▒▒
This program requires the WGT5_WC.LIB and WSCR_WC.LIB files to be linked.
▒▒▒ DATA FILES ▒▒▒
MUN.WMP, MUNCHMAP.SPR, MUNCHKIN.SPR
WATCOM C++ VERSION
==============================================================================
*/
#include <dos.h>
#include <malloc.h>
#include <stdio.h>
#include <conio.h>
#include <wgt5.h>
#include <wgtscrol.h>
typedef short tiletypes[256];
#define YOU 37
void checkfeet (void);
void checkhead (short);
void checkright (void);
void checkleft (void);
void findelevators (void);
void upelev (void);
void downelev (void);
void checkelevators (void);
void moveguys (void);
short ox,oy,dir,anim;
short jumping,addy;
short spx,spy;
int timer;
// The number of times the screen is updated
long updates;
short feet1, feet2, head1, head2;
short windx, windy;
wgtmap munchmap; // our world map
tiletypes munchtypes;
#define UP 72
#define DOWN 80
#define LEFT 75
#define RIGHT 77
#define CTRL 29
#define ESC 1
#define NUM_SPR 51
#define NUM_TILE 255
#define NUM_OBJ 101
#define TILE_SIZE 16
#define MAINWIN 0
color palette[256]; // our palette of colours
block munchtiles[NUM_TILE]; // our blocks for the map
block munchsprites[NUM_SPR]; // our sprites
scrollsprite munchobj[NUM_OBJ];
short i;
typedef struct {
short curheight;
short origy, origx;
short timer;
} elevator;
short replace[200];
short elevup = -1;
short oldmode;
elevator elev[30];
short numelev = 0;
void timerctr (void)
{
timer++;
}
void main (void)
{
oldmode = wgetmode ();
if (!vgadetected ())
{
printf ("VGA is required to run this program...");
exit (1);
}
printf ("WGT Example #62\n\n");
printf ("8-WAY SCROLLING DEMO\n");
printf ("Arrow keys move, CTRL jumps. Up/down looks in direction or operates\n");
printf ("elevators. ESC quits the program.\n");
printf ("\n\nWindow Width (2-20):");
scanf ("%i", &windx);
printf ("\nWindow Height (2-12):");
scanf ("%i", &windy);
vga256 ();
wloadsprites (palette, "munchmap.spr", munchtiles, 0, NUM_TILE - 1);
wloadsprites (palette, "munchkin.spr", munchsprites, 0, NUM_SPR - 1);
wsetpalette (0, 255, palette);
winitscroll (MAINWIN, NORMAL, - 1, windx, windy, munchtiles);
memset (&munchobj[0], 0, sizeof (scrollsprite)*NUM_OBJ);
munchmap = wloadmap (MAINWIN, "mun.wmp", munchtypes, munchobj);
findelevators ();
wnormscreen ();
wcls (0);
wshowwindow (MAINWIN, 0, 0);
installkbd ();
munchobj[YOU].on = 1;
munchobj[YOU].x = 16;
munchobj[YOU].y = 242;
munchobj[YOU].num = 1;
jumping = 0; addy = 0;
anim = 2;
timer = 0;
winittimer ();
wstarttimer (timerctr, TICKS(100));
do {
spx = 0;
spy = 0;
ox = munchobj[YOU].x;
oy = munchobj[YOU].y;
if (jumping == 1)
addy += 2;
if (addy > 15)
addy = 15;
if ((kbdon[CTRL]) && (jumping == 0))
{
jumping = 1;
addy = - 14;
}
if (kbdon[LEFT])
{
munchobj[YOU].x -= 8;
checkleft ();
if (dir != 1)
{
dir = 1;
anim = 5;
}
anim++;
if (anim > 8)
anim = 5;
}
else if (kbdon[RIGHT])
{
munchobj[YOU].x += 8;
checkright ();
if (dir != 2)
{
dir = 2;
anim = 1;
}
anim++;
if (anim > 4)
anim = 1;
}
munchobj[YOU].num = anim;
if (munchobj[YOU].x == ox)
if (dir == 1)
munchobj[YOU].num = 9;
else munchobj[YOU].num = 1;
munchobj[YOU].y += addy;
if (munchobj[YOU].y < 0)
munchobj[YOU].y = 0;
if (addy < 0)
checkhead (0);
if ((jumping == 1))
if (dir == 1)
munchobj[YOU].num = 6;
else munchobj[YOU].num = 2;
checkfeet ();
spx = munchobj[YOU].x - worldx[MAINWIN] - windowmaxx[MAINWIN] / 2 - 1;
spy = munchobj[YOU].y - worldy[MAINWIN] - windowmaxy[MAINWIN] / 2 - 1;
if (kbdon[UP])
{
if ((feet1 == 105) || (feet2 == 105))
upelev ();
else
spy = - 4;
}
if (kbdon[DOWN])
{
if ((feet1 == 105) || (feet2 == 105))
downelev ();
else
spy = + 4;
}
checkelevators ();
// make sure they come back down when not standing on them
moveguys ();
wscrollwindow (MAINWIN, spx, spy);
wshowobjects (MAINWIN, 1, NUM_OBJ - 1, munchsprites, munchobj);
wputblock (0, 0, scrollblock[MAINWIN], NORMAL);
nosound ();
updates++;
} while (kbdon[ESC] != 1); /* until ESC key is pressed */
wstoptimer ();
wdonetimer ();
uninstallkbd ();
wendscroll (MAINWIN);
wfreesprites (munchtiles, 0, NUM_TILE - 1);
wfreesprites (munchsprites, 0, NUM_SPR - 1);
wfreemap (munchmap);
wsetmode (oldmode);
printf ("\nElapsed time (microseconds): %d", timer);
printf ("\n# updates: %d", updates);
printf ("\nMicroseconds per frame: %g", (float)(timer) / (float)(updates));
printf ("\nAverage frame rate: %2.2f frames/sec\n", (float)updates / ((float)(timer) / 100.0));
}
void checkright (void)
{
short j,k;
short x;
j = wgetworldblock (MAINWIN, munchobj[YOU].x + 16, munchobj[YOU].y + 1);
k = wgetworldblock (MAINWIN, munchobj[YOU].x + 16, munchobj[YOU].y + 15);
if ((j >= 100) | (k >= 100))
{
x = munchobj[YOU].x / TILE_SIZE;
munchobj[YOU].x = x * TILE_SIZE;
}
}
void checkleft (void)
{
short j, k;
short x;
j = wgetworldblock (MAINWIN, munchobj[YOU].x, munchobj[YOU].y);
k = wgetworldblock (MAINWIN, munchobj[YOU].x, munchobj[YOU].y + 15);
if ((j >= 100) || (k >= 100))
{
x = munchobj[YOU].x / TILE_SIZE;
x++;
munchobj[YOU].x = x * TILE_SIZE;
}
}
void checkfeet (void)
{
short j, k, y;
feet1 = wgetworldblock (MAINWIN, munchobj[YOU].x, munchobj[YOU].y + 16);
feet2 = wgetworldblock (MAINWIN, munchobj[YOU].x + 15, munchobj[YOU].y + 16);
if ((feet1 < 50) && (feet2 < 50))
jumping = 1;
else
{
y = munchobj[YOU].y / TILE_SIZE;
munchobj[YOU].y = y * TILE_SIZE;
jumping = 0;
addy = 0;
}
}
void checkhead (short usingelev)
{
short j, k, y;
head1 = wgetworldblock (MAINWIN, munchobj[YOU].x, munchobj[YOU].y - 1);
head2 = wgetworldblock (MAINWIN, munchobj[YOU].x + 15, munchobj[YOU].y - 1);
if ((head1 < 50) && (head2 < 50))
jumping = 1;
else
{
y = munchobj[YOU].y / TILE_SIZE;
if (!usingelev)
y++;
munchobj[YOU].y = y * TILE_SIZE;
jumping = 0;
addy = 0;
}
}
void findelevators (void)
{
short i, j, k;
for (i = 0; i <= mapheight[MAINWIN]; i++)
for (j = 0; j <= mapwidth[MAINWIN]; j++)
{
k = wgetworldblock (MAINWIN, j*16, i*16);
if (k == 105)
{
elev[numelev].curheight = i;
elev[numelev].origx = j;
elev[numelev].origy = i;
elev[numelev].timer = 0;
for (k = 0; k < 200; k++)
replace[k] = 0;
numelev++;
}
}
}
void upelev (void)
{
short ii, jj;
for (ii = 0; ii < numelev; ii++)
{
if ((elev[ii].origx >= (munchobj[YOU].x / 16) - 1)
&& (elev[ii].curheight >= (munchobj[YOU].y / 16) - 1)
&& (elev[ii].origx <= (munchobj[YOU].x / 16) + 1)
&& (elev[ii].curheight <= (munchobj[YOU].y / 16) + 1)
&& ((elevup == - 1) | (elevup == ii))
&& (munchobj[YOU].y > 16))
{
checkhead (1);
if ((head1 < 50) && (head2 < 50))
{
replace[elev[ii].curheight - 1] = wgetworldblock (MAINWIN, elev[ii].origx * 16, (elev[ii].curheight - 1) * 16);
wputworldblock (MAINWIN, elev[ii].origx * 16, elev[ii].curheight * 16, 104);
wputworldblock (MAINWIN, elev[ii].origx * 16, (elev[ii].curheight - 1)*16, 105);
elev[ii].curheight--;
elevup = ii;
munchobj[YOU].y -= 16;
elev[ii].timer = 10;
}
}
}
}
void downelev (void)
{
short ii, jj;
for (ii = 0; ii < numelev; ii++)
{
if ((elev[ii].origx >= (munchobj[YOU].x / 16) - 1)
&& (elev[ii].curheight >= (munchobj[YOU].y / 16) - 1)
&& (elev[ii].origx <= (munchobj[YOU].x / 16) + 1)
&& (elev[ii].curheight <= (munchobj[YOU].y / 16) + 1)
&& (elev[ii].curheight != elev[ii].origy))
{
wputworldblock (MAINWIN, elev[ii].origx * 16, elev[ii].curheight * 16, replace[elev[ii].curheight]);
wputworldblock (MAINWIN, elev[ii].origx * 16, (elev[ii].curheight + 1) * 16, 105);
elev[ii].curheight++;
if (elev[ii].curheight == elev[ii].origy)
elevup = - 1;
munchobj[YOU].y += 16;
elev[ii].timer = 10;
}
}
}
void checkelevators (void)
{
short ii;
for (ii = 0; ii < numelev; ii++)
{
if ((elev[ii].curheight != elev[ii].origy))
{
if (elev[ii].timer == 0)
{
wputworldblock (MAINWIN, elev[ii].origx * 16, elev[ii].curheight * 16, replace[elev[ii].curheight]);
wputworldblock (MAINWIN, elev[ii].origx * 16, (elev[ii].curheight + 1) * 16, 105);
elev[ii].curheight++;
if (elev[ii].curheight == elev[ii].origy)
elevup = - 1;
elev[ii].timer = 0;
}
else elev[ii].timer--;
}
}
}
void moveguys (void)
{
short j, k;
for (i = 0; i <= 36; i++)
{
if (munchobj[i].on == 1)
if (munchsprites[munchobj[i].num] != NULL)
// sprite made
{
if (is_in_window (MAINWIN, munchobj[i].x, munchobj[i].y, 100))
{
if (munchobj[i].num < 16) // walking right
{
munchobj[i].num++;
if (munchobj[i].num > 15) munchobj[i].num = 12;
// walking animation loop
munchobj[i].x += 3;
j = wgetworldblock (MAINWIN, munchobj[i].x + 16, munchobj[i].y + 16);
k = wgetworldblock (MAINWIN, munchobj[i].x + 16, munchobj[i].y + 8);
if ((j < 50) | (k >= 50)) munchobj[i].num = 16;
}
if (munchobj[i].num > 15) // walking left
{
munchobj[i].num++;
if (munchobj[i].num > 19) munchobj[i].num = 16;
// walking animation loop
munchobj[i].x -= 3;
j = wgetworldblock (MAINWIN, munchobj[i].x, munchobj[i].y + 16);
k = wgetworldblock (MAINWIN, munchobj[i].x, munchobj[i].y + 8);
if ((j < 50) || (k >= 50)) munchobj[i].num = 12;
}
}
}
}
}