/* ============================================================================== 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 #include #include #include #include #include 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; } } } } }