From 140ee1097713ced33183725e484ecfa175b8d650 Mon Sep 17 00:00:00 2001 From: sparky4 Date: Wed, 10 Dec 2014 18:27:36 -0600 Subject: [PATCH 1/1] I found a thing new file: 16/roads/ANIM.C new file: 16/roads/BOOKENDS.C new file: 16/roads/FX.C new file: 16/roads/FX.H new file: 16/roads/INITROAD.C new file: 16/roads/INITW.C new file: 16/roads/KEYS.H new file: 16/roads/MAKEFILE.MAK new file: 16/roads/READ.ME new file: 16/roads/ROADS.C new file: 16/roads/ROADS.EXE new file: 16/roads/ROADS.GIF new file: 16/roads/ROADS.H new file: 16/roads/TILEIO.C new file: 16/roads/TILES.H new file: 16/roads/VERSION.H --- 16/roads/ANIM.C | 344 +++++++++++++++++++++++++++++++ 16/roads/BOOKENDS.C | 97 +++++++++ 16/roads/FX.C | 95 +++++++++ 16/roads/FX.H | 32 +++ 16/roads/INITROAD.C | 467 ++++++++++++++++++++++++++++++++++++++++++ 16/roads/INITW.C | 153 ++++++++++++++ 16/roads/KEYS.H | 31 +++ 16/roads/MAKEFILE.MAK | 42 ++++ 16/roads/READ.ME | 54 +++++ 16/roads/ROADS.C | 330 +++++++++++++++++++++++++++++ 16/roads/ROADS.EXE | Bin 0 -> 67438 bytes 16/roads/ROADS.GIF | Bin 0 -> 11488 bytes 16/roads/ROADS.H | 143 +++++++++++++ 16/roads/TILEIO.C | 178 ++++++++++++++++ 16/roads/TILES.H | 123 +++++++++++ 16/roads/VERSION.H | 22 ++ 16 files changed, 2111 insertions(+) create mode 100644 16/roads/ANIM.C create mode 100644 16/roads/BOOKENDS.C create mode 100644 16/roads/FX.C create mode 100644 16/roads/FX.H create mode 100644 16/roads/INITROAD.C create mode 100644 16/roads/INITW.C create mode 100644 16/roads/KEYS.H create mode 100644 16/roads/MAKEFILE.MAK create mode 100644 16/roads/READ.ME create mode 100644 16/roads/ROADS.C create mode 100644 16/roads/ROADS.EXE create mode 100644 16/roads/ROADS.GIF create mode 100644 16/roads/ROADS.H create mode 100644 16/roads/TILEIO.C create mode 100644 16/roads/TILES.H create mode 100644 16/roads/VERSION.H diff --git a/16/roads/ANIM.C b/16/roads/ANIM.C new file mode 100644 index 00000000..0f3aa7e0 --- /dev/null +++ b/16/roads/ANIM.C @@ -0,0 +1,344 @@ +#define ANIM_C + +#include +#include +#include "roads.h" +#include "tiles.h" + +extern int far *topography; /* BACKGROUND TILE LIST (ARRAY) */ +extern int far *terrain; /* FOREGROUND TILE LIST (ARRAY) */ +extern int view_x, view_y; /* VIEW AREA (UPPER LEFT CORNER) */ +extern int viewpage; /* CURRENTLY VIEWED PAGE */ + +int frogmode; +int frogwatchmode=0; +int animatemode=1; + +/* ANIMATION VARIABLES */ +struct ANIMATION fire, water1, water2, uranium, frog; +struct ANIMATION *anim_list[ANIM_LIST_TOTAL]; + +/* + * + * Animates all cells to the next frame. + * + */ +void animate (void) +{ + register int x, y; + int a, i, tile; + long time; + int total_updates=0; + + gogofrog(); + time=fg_getclock(); + + /* UPDATE ALL ANIM TYPES FOR NEXT FRAME IF TIME TO DO SO */ + for (a=0; anext<1) /* EVENT_DRIVEN ANIMATION */ + { + if (anim_list[a]->next==-1) /* EVENT OCCURING! */ + { + anim_list[a]->next=0; /* TURN EVENT OFF */ + total_updates++; + } + } + + else if (anim_list[a]->next<=time) /* IS ANIM READY FOR NEXT FRAME? */ + { + anim_list[a]->next=time+anim_list[a]->delay; /* SET NEXT FRAME TIME */ + anim_list[a]->current+=1; + if (anim_list[a]->current>=anim_list[a]->first+anim_list[a]->total) + anim_list[a]->current=anim_list[a]->first; + total_updates++; + } + } + + if (total_updates==0) return; /* NO ANIMATION TODAY. SORRY */ + + /* VISUALLY UPDATE ALL VIEWABLE ANIMATIONS */ + for (y=0; yanm!=terrain[i]) a++; + tile=anim_list[a]->current; + + /* COPY TILE TO MIX THEN TO CURRENT SCREEN */ + pagecopy_tile_op (topography[i], MIXING_TILE, TILEPAGE, TILEPAGE); + pagecopy_tile_tr (tile, MIXING_TILE, TILEPAGE, TILEPAGE); + pagecopy_tile_op (MIXING_TILE, VIEW_TILE(x,y), TILEPAGE, viewpage); + } + } +} + +#define UP 1 +#define DOWN 2 +#define LEFT 3 +#define RIGHT 4 +#define CHANCE_FROG_NOT_TURN 95 + +/* + * + * Move frog somewhere new. + * + */ +void gogofrog (void) +{ + int fails=0, r, suc; + int newx, newy; + static int x, y; + static int facing=RIGHT; + static int walking=FALSE; + static long nextfrog; + + if (frogmode==3) return; /* NO FROG! GO AWAY */ + + if (frogmode==2) + { + terrain[WORLD_TILE(x,y)]=EMPTY_TILE; + update_tile (WORLD_TILE(x,y)); + frogmode=3; + return; + } + + if (frogmode==1) + { + if (nextfrog>fg_getclock()) + return; /* NOT TIME TO ANIMATE OUR FROGGIE */ + + frog.next=-1; /* TURN ON ANIMATION EVENT FLAG */ + + /* DETERMINE IF FROG CHANGES FACING */ + if (random(100)>CHANCE_FROG_NOT_TURN) + { + walking=FALSE; + + NEW_FACING: + + /* CHANGE FACING */ + r=random(100); + switch (facing) + { + case RIGHT: + case LEFT: + if (r<50) facing=UP; + else facing=DOWN; + break; + + case DOWN: + case UP: + if (r<50) facing=RIGHT; + else facing=LEFT; + break; + } + + /* UPDATE FACING IMAGE */ + switch (facing) + { + case RIGHT: frog.current=FROG_FACE_RIGHT; break; + case LEFT: frog.current=FROG_FACE_LEFT; break; + case DOWN: frog.current=FROG_FACE_DOWN; break; + case UP: frog.current=FROG_FACE_UP; break; + } + nextfrog=fg_getclock()+frog.delay; + return; + } + + /* DETERMINE IF FROG STARTS/STOPS WALKING */ + if (walking==FALSE) + { + walking=TRUE; + switch (facing) + { + case RIGHT: frog.current=FROG_WALK_RIGHT; break; + case LEFT: frog.current=FROG_WALK_LEFT; break; + case DOWN: frog.current=FROG_WALK_DOWN; break; + case UP: frog.current=FROG_WALK_UP; break; + } + + frog.next=-1; /* TURN ON ANIMATION EVENT FLAG */ + nextfrog=fg_getclock()+frog.delay; + return; + } + + /* DETERMINE IF WE CAN WALK OUR FROGGIE THIS WAY! */ + newx=x; + newy=y; + switch (facing) + { + case RIGHT: newx++; break; + case LEFT: newx--; break; + case DOWN: newy++; break; + case UP: newy--; break; + } + + /* CAN'T MOVE -- OBSTRUCTION OR END OF WORLD! */ + if (newx<0 || newy<0 || newx>=WORLD_WIDTH || newy>=WORLD_HEIGHT + || terrain[WORLD_TILE(newx,newy)]!=EMPTY_TILE) + { + /* UPDATE FACING IMAGE TO REFLECT FROG STANDS FAST */ + if (random(100)<50) switch (facing) + { + case RIGHT: frog.current=FROG_FACE_RIGHT; break; + case LEFT: frog.current=FROG_FACE_LEFT; break; + case DOWN: frog.current=FROG_FACE_DOWN; break; + case UP: frog.current=FROG_FACE_UP; break; + } + else + { + frog.next=-1; + goto NEW_FACING; + } + nextfrog=fg_getclock()+frog.delay; + return; + } + + /* CAN MOVE! MOVE FROG ALONG */ + switch (facing) + { + case RIGHT: + if (++frog.current>=FROG_NUM_WALKS+FROG_WALK_RIGHT) + frog.current=FROG_WALK_RIGHT; + break; + + case LEFT: + if (++frog.current>=FROG_NUM_WALKS+FROG_WALK_LEFT) + frog.current=FROG_WALK_LEFT; + break; + + case DOWN: + if (++frog.current>=FROG_NUM_WALKS+FROG_WALK_DOWN) + frog.current=FROG_WALK_DOWN; + break; + + case UP: + if (++frog.current>=FROG_NUM_WALKS+FROG_WALK_UP) + frog.current=FROG_WALK_UP; + break; + + } + + /* DON'T MOVE FROG'S X/Y AT CERTAIN FRAMES */ + if (frog.current==FROG_WALK_UP+1 || + frog.current==FROG_WALK_UP+3 || + frog.current==FROG_WALK_LEFT+1 || + frog.current==FROG_WALK_LEFT+3 || + frog.current==FROG_WALK_RIGHT+1 || + frog.current==FROG_WALK_RIGHT+3 || + frog.current==FROG_WALK_DOWN+1 || + frog.current==FROG_WALK_DOWN+3 ) + { + frog.next=-1; + nextfrog=fg_getclock()+frog.delay; + return; + } + + terrain[WORLD_TILE(x,y)]=EMPTY_TILE; + terrain[WORLD_TILE(newx,newy)]=ANM_FROG; + frog.next=-1; + +/* + * + * Simply put, frog watch mode doesn't work. + * I got to the point where I said, gosh darnit, who needs + * to watch a stinking frog anyway? It's left as is... + * + */ + if (frogwatchmode) + { + + if (newx>x) if (view_x0) view_x--; + else if (newy>y) if (view_y0) view_y--; + redraw (NONFLIP_REFRESH); +/* if (newx>x) suc=redraw (NONFLIP_SCROLL_RIGHT); + else if (newxy) suc=redraw (NONFLIP_SCROLL_DOWN); + else if (newy=50) /* COULDN'T PLACE FROG */ + { + fg_music ("L64EC.DE.C$"); + frogmode=3; + frog.next=0; + return; + } + + terrain[WORLD_TILE(x,y)]=ANM_FROG; /* INSTALL FROG! */ + frog.next=-1; /* UPDATE EVENT */ + frogmode=1; + nextfrog=fg_getclock()+frog.delay; + + return; +} + +/* + * + * Initializes any animation information, as in at the program start. + * + */ +void init_anim (void) +{ + fire.first=fire.current=34; + fire.total=6; + fire.delay=1; + fire.next=fg_getclock()+fire.delay; + fire.anm=ANM_FIRE; + + water1.first=water1.current=60; + water1.total=3; + water1.delay=3; + water1.next=fg_getclock()+water1.delay; + water1.anm=ANM_WATER1; + + water2.first=water2.current=63; + water2.total=3; + water2.delay=4; + water2.next=fg_getclock()+water2.delay; + water2.anm=ANM_WATER2; + + uranium.first=uranium.current=66; + uranium.total=10; + uranium.delay=4; + uranium.next=fg_getclock()+uranium.delay; + uranium.anm=ANM_URANIUM; + + frog.first=frog.current=FROG_FACE_RIGHT; + frog.total=FROG_NUM_WALKS; + frog.delay=3; + frog.next=-1; + frog.anm=ANM_FROG; + + anim_list[0]=&fire; + anim_list[1]=&water1; + anim_list[2]=&water2; + anim_list[3]=&uranium; + anim_list[4]=&frog; +} + diff --git a/16/roads/BOOKENDS.C b/16/roads/BOOKENDS.C new file mode 100644 index 00000000..0daa74a9 --- /dev/null +++ b/16/roads/BOOKENDS.C @@ -0,0 +1,97 @@ +#define BOOKENDS_C + +#include +#include +#include +#include +#include "roads.h" +#include "fx.h" /* FOR FADING */ +#include "version.h" /* FOR HEADER */ + +extern int far *topography; /* BACKGROUND TILE LIST (ARRAY) */ +extern int far *terrain; /* FOREGROUND TILE LIST (ARRAY) */ +extern int viewpage; /* CURRENTLY VIEWED PAGE */ + +int startup_vmode=-1; /* STARTUP VIDEO MODE TO RETURN TO AT PROGRAM END */ + +/* + * + * Initializes/Sets-up the video mode and paging. + * + */ +void init_video (void) +{ + /* INITIALIZE VIDEO MODE */ + if (fg_testmode (VMODE, VPAGES)==0) + { + printf ("Sorry, your video card does not support mode %d.\n", VMODE); + exit (1); + } + + startup_vmode=fg_getmode(); + fg_setcolor(0); + fg_setmode (VMODE); + fg_erase(); + + /* SETUP SPRITE IMAGES */ + fg_setpage (TILEPAGE); + fg_erase(); + fg_showgif (IMAGES, 0); + fg_setpage (viewpage); + fg_erase(); + fg_tcdefine (0,1); /* TREAT COLOR 0 AS TRANSPARENT */ +} + +/* + * + * "Officially" shuts down the program. Restores video, frees + * allocated data including fonts, unhooks Sound Blaster, + * and (optionally) exits with a message and errorcode + * + */ +void program_shutdown (char *msg, int errcode) +{ + fg_kbinit(0); /* UNLATCH LOW-LEVEL KEYBOARD HANDLER */ + + /* FREE DATA */ + if (topography!=NULL) farfree (topography); + if (terrain!=NULL) farfree (terrain); + + /* RESTORE ORIGINAL VIDEO MODE TO USER */ + if (startup_vmode!=-1) + { + fade_out_all (); + fg_setmode (startup_vmode); + fg_reset(); + } + + /* FREE FONTS AND SOUND BLASTER SOMEWHERE IN HERE */ + + printf (HEADER); /* PRINT HEADER */ + + /* REPORT MESSAGE */ + if (*msg!=NULL) + printf ("ROADS: %s\n", msg); + + /* QUIT WITH ERROR CODE, IF SUPPLIED ONE */ + if (errcode!=-1) + exit (errcode); + + /* OTHERWISE, RETURN TO CALLER WHO WILL HANDLE EXITING */ + else return; +} + +/* + * + * Initialize dynamic data, which is freed with program_shutdown() + * + */ +void init_data (void) +{ + topography=farcalloc (WORLD_TILES_TOTAL,sizeof (int)); + terrain=farcalloc (WORLD_TILES_TOTAL,sizeof (int)); + + if (topography==NULL || terrain==NULL) + program_shutdown ("Not enough memory -- It's not my fault, I swear!", 1); +} + diff --git a/16/roads/FX.C b/16/roads/FX.C new file mode 100644 index 00000000..034c623d --- /dev/null +++ b/16/roads/FX.C @@ -0,0 +1,95 @@ +#define FX_C + +#include /* FOR PALETTE AND KEYHIT FUNCTIONS */ +#include "fx.h" +#include "roads.h" /* FOR ANIMATE FUNCTION */ + +/* FX.C-specific DEFINITIONS */ +#define FADESTEPS 32 /* Number of gradations in the fade -- KEEP BELOW 256 */ +#define SETDACS_DELAY 0 /* Number of clock ticks to wait between gradations */ + +/****************************************************************************\ +* * +* fade_in * +* * +* Fade one or more DACs from black to their target colors. * +* * +\****************************************************************************/ + +void fade_in (int DACstart, int DACend) +{ + register int j, i; + int k, n, temp; + char new_palette [VCOLORS*3]; /* Temporarily stores palette */ + char key1, key2; /* USED FOR FOR KEYCHECK */ + + if (DACend0) break; + } + + for (k=0, n=DACstart*3, j = DACstart; j <= DACend; j++) + { + new_palette[k++] = (long) (default_palette[n++] * i) / FADESTEPS; + new_palette[k++] = (long) (default_palette[n++] * i) / FADESTEPS; + new_palette[k++] = (long) (default_palette[n++] * i) / FADESTEPS; + } + + fg_setdacs (DACstart, DACend-DACstart+1, new_palette); + fg_waitfor (SETDACS_DELAY); + if (animatewhilefading) animate(); + } +} + +/****************************************************************************\ +* * +* fade_out * +* * +* Fade one or more DACs from their current colors to black. * +* * +\****************************************************************************/ + +void fade_out (int DACstart, int DACend) +{ + register int j, i; + int k, n, temp; + char new_palette [VCOLORS*3]; /* Temporarily stores palette */ + char key1, key2; /* USED FOR FOR KEYCHECK */ + + if (DACend= 0; i--) + { + if (abortfadeonkeyhit) + { + fg_intkey (&key1, &key2); + if (key1+key2>0) break; + } + + for (k=0, n=DACstart*3, j = DACstart; j <= DACend; j++) + { + new_palette[k++] = (long) (default_palette[n++] * i) / FADESTEPS; + new_palette[k++] = (long) (default_palette[n++] * i) / FADESTEPS; + new_palette[k++] = (long) (default_palette[n++] * i) / FADESTEPS; + } + fg_setdacs (DACstart, DACend-DACstart+1, new_palette); + fg_waitfor (SETDACS_DELAY); + if (animatewhilefading) animate(); + } +} + diff --git a/16/roads/FX.H b/16/roads/FX.H new file mode 100644 index 00000000..ca98a7f4 --- /dev/null +++ b/16/roads/FX.H @@ -0,0 +1,32 @@ +#ifndef __MEM_H +#include +#endif + +/* DEFINITIONS */ +#define VCOLORS 256 /* Number of screen colors */ + +/* GLOBAL VARIABLES */ +#ifdef FX_C +char default_palette[VCOLORS*3]; /* Stores the palette before fades */ +char empty_palette[VCOLORS*3]; /* Stores an empty palette for quick clearing */ +char abortfadeonkeyhit=0; /* Quit fading on keyhit? */ +char animatewhilefading=1; /* Animate screen while performing fade? */ +#else +extern char default_palette[VCOLORS*3]; +extern char empty_palette[VCOLORS*3]; +extern char abortfadeonkeyhit; +extern char animatewhilefading; +#endif + +/* PROTOTYPES */ +void fade_in (int DACstart, int DACend); +void fade_out (int DACstart, int DACend); + +/* MACROS */ +#define fade_init() fg_getdacs (0, VCOLORS, default_palette); /* COPY PALETTE */ +#define fade_blackout() memset (empty_palette, 0, VCOLORS*3);\ + fg_setdacs(0, VCOLORS, empty_palette); /* SET DACS TO ZERO */ + +#define fade_out_all() fade_out(0,255) +#define fade_in_all() fade_in(0,255) + diff --git a/16/roads/INITROAD.C b/16/roads/INITROAD.C new file mode 100644 index 00000000..c83effe3 --- /dev/null +++ b/16/roads/INITROAD.C @@ -0,0 +1,467 @@ +#define INITROAD_C + +#include +#include +#include +#include "roads.h" +#include "tiles.h" + +extern int far *topography; /* BACKGROUND TILE LIST (ARRAY) */ +extern int far *terrain; /* FOREGROUND TILE LIST (ARRAY) */ + +/* FOR AI - NUMBER OF ROADS TO PLACE ON SCREEN */ +#define MAX_ROADS ((WORLD_WIDTH+WORLD_HEIGHT)/2) +#define MIN_ROADS ((WORLD_WIDTH+WORLD_HEIGHT)/8) +#define CHANCE_CROSSROAD 75 /* 3/4 CHANCE OF A CROSSROAD VS T */ + +/* DIRECTIONS */ +#define NUM_DIRECTIONS 4 +#define FIRST_DIRECTION 1 + +#define DIRECTION_UP 1 +#define DIRECTION_DOWN 2 +#define DIRECTION_LEFT 3 +#define DIRECTION_RIGHT 4 + +#define ROAD_LEADERS 12 /* USED IN CREATE_ROADS */ + +/* + * + * Randomly creates roads and places them in the foreground tile list. + * This function overwrites other non-road foreground tiles. + * (To prevent this, call this function first.) + * + */ +void create_roads (void) +{ + int entry, keepgoing=TRUE, direction, chance; + int x,y,nextx,nexty; /* LOCATION OF CURRENTLY PLACED ROAD TILE */ + int roads_left; /* NUMBER OF COMPLETE ROADS LEFT TO PLACE */ + int failed_roads=0; + int current_tile; + + /* ROADS ARE PICKED FROM THESE LISTS -- INCREASE ROAD_LEADERS */ + /* AND ADD ROAD TILES TO THESE LISTS TO INCREASE CHANCE OF */ + /* SPECIFIED ROADS BEING PLACED */ + int roads_to_right [ROAD_LEADERS] = { ROAD_H, ROAD_H, ROAD_UR, ROAD_DR, + ROAD_H, ROAD_H, ROAD_H, ROAD_H, + ROAD_H, ROAD_H, ROAD_H, ROAD_H, }; + int roads_to_left [ROAD_LEADERS] = { ROAD_H, ROAD_H, ROAD_UL, ROAD_DL, + ROAD_H, ROAD_H, ROAD_H, ROAD_H, + ROAD_H, ROAD_H, ROAD_H, ROAD_H, }; + int roads_to_down [ROAD_LEADERS] = { ROAD_V, ROAD_V, ROAD_UL, ROAD_UR, + ROAD_V, ROAD_V, ROAD_V, ROAD_V, + ROAD_V, ROAD_V, ROAD_V, ROAD_V, }; + int roads_to_up [ROAD_LEADERS] = { ROAD_V, ROAD_V, ROAD_DL, ROAD_DR, + ROAD_V, ROAD_V, ROAD_V, ROAD_V, + ROAD_V, ROAD_V, ROAD_V, ROAD_V, }; + + roads_left=random (MAX_ROADS-MIN_ROADS)+MIN_ROADS; + + /************************************************\ + * PLACE FIRST TILE AT WORLD SCREEN EDGE * + \************************************************/ + + while (roads_left-- && failed_roads<=MAX_FAILS) + { + /* PICK RANDOM ENTRY POINT */ + keepgoing=TRUE; + entry=random(NUM_DIRECTIONS)+FIRST_DIRECTION; + switch (entry) + { +/********/ case DIRECTION_UP: /* TOP ENTRY */ + + x=random(WORLD_WIDTH); y=0; + current_tile=terrain[WORLD_TILE(x,y)]; + + if (!isroad(current_tile)) + { + current_tile=terrain[WORLD_TILE(x,y)]= + roads_to_up[random(ROAD_LEADERS)]; + direction=roadexit(current_tile, DIRECTION_DOWN); + break; + } + + else + { + roads_left++; + failed_roads++; + keepgoing=FALSE; + break; + } + +/********/ case DIRECTION_DOWN: /* BOTTOM ENTRY */ + + x=random(WORLD_WIDTH); y=WORLD_HEIGHT-1; + current_tile=terrain[WORLD_TILE(x,y)]; + + if (!isroad(current_tile)) + { + current_tile=terrain[WORLD_TILE(x,y)]= + roads_to_down[random(ROAD_LEADERS)]; + direction=roadexit(current_tile, DIRECTION_UP); + } + + else + { + roads_left++; + failed_roads++; + keepgoing=FALSE; + } + break; + +/********/ case DIRECTION_LEFT: /* LEFT ENTRY */ + + x=0; y=random(WORLD_HEIGHT); + current_tile=terrain[WORLD_TILE(x,y)]; + + if (!isroad(current_tile)) + { + current_tile=terrain[WORLD_TILE(x,y)]= + roads_to_left[random(ROAD_LEADERS)]; + direction=roadexit(current_tile, DIRECTION_RIGHT); + } + + else + { + roads_left++; + failed_roads++; + keepgoing=FALSE; + } + break; + +/********/ case DIRECTION_RIGHT: /* RIGHT ENTRY */ + + x=WORLD_WIDTH-1; y=random(WORLD_HEIGHT); + current_tile=terrain[WORLD_TILE(x,y)]; + + if (!isroad(current_tile)) + { + current_tile=terrain[WORLD_TILE(x,y)]= + roads_to_right[random(ROAD_LEADERS)]; + direction=roadexit(current_tile, DIRECTION_LEFT); + } + + else + { + roads_left++; + failed_roads++; + keepgoing=FALSE; + } + break; + } + + /************************************************\ + * PLACE SUBSEQUENT TILES AWAY FROM ENTRY POINT * + \************************************************/ + + while (keepgoing) + { + switch (direction) + { +/********/ case DIRECTION_UP: /* UP */ + + if (--y<0) + { + keepgoing=FALSE; + break; + } + + current_tile=terrain[WORLD_TILE(x,y)]; + if (!isroad(current_tile)) + { + current_tile=terrain[WORLD_TILE(x,y)]= + roads_to_down[random(ROAD_LEADERS)]; + direction=roadexit(current_tile, DIRECTION_UP); + } + + else /* INTERSECTION OCCURS */ + { + if (random(100)>=CHANCE_CROSSROAD && + terrain[WORLD_TILE(x,y-1)]==EMPTY_TILE) + { + keepgoing=FALSE; + terrain[WORLD_TILE(x,y)]=makeintersection + (current_tile, DIRECTION_DOWN); + } + + else /* CROSSROAD AND CONTINUE */ + { + terrain[WORLD_TILE(x,y)]=makeintersection + (makeintersection(current_tile, DIRECTION_UP), + DIRECTION_DOWN); /* ADD BOTH RAMPS */ + } + } + break; + +/********/ case DIRECTION_DOWN: /* DOWN */ + + if (++y>=WORLD_HEIGHT) + { + keepgoing=FALSE; + break; + } + + current_tile=terrain[WORLD_TILE(x,y)]; + if (!isroad(current_tile)) + { + current_tile=terrain[WORLD_TILE(x,y)]= + roads_to_up[random(ROAD_LEADERS)]; + direction=roadexit(current_tile, DIRECTION_DOWN); + } + + else /* INTERSECTION OCCURS */ + { + if (random(100)>=CHANCE_CROSSROAD && + terrain[WORLD_TILE(x,y+1)]==EMPTY_TILE) + + { + keepgoing=FALSE; + terrain[WORLD_TILE(x,y)]=makeintersection + (current_tile, DIRECTION_UP); + } + + else /* CROSSROAD AND CONTINUE */ + { + terrain[WORLD_TILE(x,y)]=makeintersection + (makeintersection(current_tile, DIRECTION_DOWN), + DIRECTION_UP); /* ADD BOTH RAMPS */ + } + } + break; + +/********/ case DIRECTION_LEFT: /* LEFT */ + + if (--x<0) + { + keepgoing=FALSE; + break; + } + + current_tile=terrain[WORLD_TILE(x,y)]; + if (!isroad(current_tile)) + { + current_tile=terrain[WORLD_TILE(x,y)]= + roads_to_right[random(ROAD_LEADERS)]; + direction=roadexit(current_tile, DIRECTION_LEFT); + } + + else /* INTERSECTION OCCURS */ + { + if (random(100)>=CHANCE_CROSSROAD && + terrain[WORLD_TILE(x-1,y)]==EMPTY_TILE) + + { + keepgoing=FALSE; + terrain[WORLD_TILE(x,y)]=makeintersection + (current_tile, DIRECTION_RIGHT); + } + + else /* CROSSROAD AND CONTINUE */ + { + terrain[WORLD_TILE(x,y)]=makeintersection + (makeintersection(current_tile, DIRECTION_LEFT), + DIRECTION_RIGHT); /* ADD BOTH RAMPS */ + } + } + break; + +/********/ case DIRECTION_RIGHT: /* RIGHT */ + + if (++x>=WORLD_WIDTH) + { + keepgoing=FALSE; + break; + } + + current_tile=terrain[WORLD_TILE(x,y)]; + if (!isroad(current_tile)) + { + current_tile=terrain[WORLD_TILE(x,y)]= + roads_to_left[random(ROAD_LEADERS)]; + direction=roadexit(current_tile, DIRECTION_RIGHT); + } + + else /* INTERSECTION OCCURS */ + { + if (random(100)>=CHANCE_CROSSROAD && + terrain[WORLD_TILE(x+1,y)]==EMPTY_TILE) + + { + keepgoing=FALSE; + terrain[WORLD_TILE(x,y)]=makeintersection + (current_tile, DIRECTION_LEFT); + } + + else /* CROSSROAD AND CONTINUE */ + { + terrain[WORLD_TILE(x,y)]=makeintersection + (makeintersection(current_tile, DIRECTION_RIGHT), + DIRECTION_LEFT); /* ADD BOTH RAMPS */ + } + } + break; + } /* "DIRECTION" HERE */ + } /* STOP "KEEPGOING" HERE */ + } +} + +/* + * + * Returns the unspecified direction in an angled road. + * + */ +int roadexit (int road, int direction) +{ + switch (direction) + { + case DIRECTION_UP: /* up */ + if (road==ROAD_V) return DIRECTION_UP; + if (road==ROAD_UL) return DIRECTION_LEFT; + if (road==ROAD_UR) return DIRECTION_RIGHT; + break; + + case DIRECTION_DOWN: /* down */ + if (road==ROAD_V) return DIRECTION_DOWN; + if (road==ROAD_DL) return DIRECTION_LEFT; + if (road==ROAD_DR) return DIRECTION_RIGHT; + break; + + case DIRECTION_LEFT: /* left */ + if (road==ROAD_DR) return DIRECTION_UP; + if (road==ROAD_UR) return DIRECTION_DOWN; + if (road==ROAD_H) return DIRECTION_LEFT; + break; + + case DIRECTION_RIGHT: /* right */ + if (road==ROAD_DL) return DIRECTION_UP; + if (road==ROAD_UL) return DIRECTION_DOWN; + if (road==ROAD_H) return DIRECTION_RIGHT; + break; + } + + fg_music ("A$"); + return ERROR_TILE; +} + +/* + * + * Adds a road (ramp) to the specified road, and returns the + * tile number of what the new road is made of. + * + */ +int makeintersection (int road, int ramp) +{ + switch (road) + { + case ROAD_X: /* Å */ + return ROAD_X; + + case ROAD_V: /* ³ */ + if (ramp==DIRECTION_LEFT) return ROAD_TL; + if (ramp==DIRECTION_RIGHT) return ROAD_TR; + return ROAD_V; + + case ROAD_H: /* Ä */ + if (ramp==DIRECTION_UP) return ROAD_TU; + if (ramp==DIRECTION_DOWN) return ROAD_TD; + return ROAD_H; + + case ROAD_UR: /* Ú */ + if (ramp==DIRECTION_UP) return ROAD_TR; + if (ramp==DIRECTION_LEFT) return ROAD_TD; + return ROAD_UR; + + case ROAD_UL: /* ¿ */ + if (ramp==DIRECTION_UP) return ROAD_TL; + if (ramp==DIRECTION_RIGHT) return ROAD_TD; + return ROAD_UL; + + case ROAD_DR: /* À */ + if (ramp==DIRECTION_DOWN) return ROAD_TR; + if (ramp==DIRECTION_LEFT) return ROAD_TU; + return ROAD_DR; + + case ROAD_DL: /* Ù */ + if (ramp==DIRECTION_DOWN) return ROAD_TL; + if (ramp==DIRECTION_RIGHT) return ROAD_TU; + return ROAD_DL; + + case ROAD_TL: /* ´ */ + if (ramp==DIRECTION_RIGHT) return ROAD_X; + return ROAD_TL; + + case ROAD_TR: /* Ã */ + if (ramp==DIRECTION_LEFT) return ROAD_X; + return ROAD_TR; + + case ROAD_TU: /* Á */ + if (ramp==DIRECTION_DOWN) return ROAD_X; + return ROAD_TU; + + case ROAD_TD: /* Â */ + if (ramp==DIRECTION_UP) return ROAD_X; + return ROAD_TD; + } + + fg_music ("A$"); + return ERROR_TILE; +} + +/* + AI USED IN ROAD FUNCTIONS: + pick random entry point on one of the four sides + place subsequent tiles with tendency to move from screen + place subsequent tiles with tendency use V or H pieces if just used + if hit existing tile, either + a) cross over road and continue, using X tile + b) terminate road with a T + repeat until MAX_ROADS complete +*/ + +/* + * + * Adds edges to places where grass and dirt meet. + * Called by init_background() to liven up background display. + * + */ +void add_dirt_edges (void) +{ + register int x, y; + int tile; + + /* ADD 90 DEGREE EDGES */ + for (y=0; y=0) tile+=isgrass(topography[WORLD_TILE(x,y-1)]); + if (x+1=0) tile+=isgrass(topography[WORLD_TILE(x-1,y)])*8; + + /* CONVERT BINARY TILE NUMBER TO ACTUAL */ + switch (tile) + { + case 1: tile=DIRTEDGE_U; break; + case 2: tile=DIRTEDGE_R; break; + case 3: tile=DIRTEDGE_UR; break; + case 4: tile=DIRTEDGE_D; break; + case 5: tile=DIRTEDGE_UD; break; + case 6: tile=DIRTEDGE_RD; break; + case 7: tile=DIRTEDGE_URD; break; + case 8: tile=DIRTEDGE_L; break; + case 9: tile=DIRTEDGE_UL; break; + case 10: tile=DIRTEDGE_RL; break; + case 11: tile=DIRTEDGE_URL; break; + case 12: tile=DIRTEDGE_DL; break; + case 13: tile=DIRTEDGE_UDL; break; + case 14: tile=DIRTEDGE_RDL; break; + case 15: tile=DIRTEDGE_URDL; break; + case 0: tile=topography[WORLD_TILE(x,y)]; break; /* NO CHANGE */ + } + topography[WORLD_TILE(x,y)]=tile; /* CHANGE TILE */ + } +} + diff --git a/16/roads/INITW.C b/16/roads/INITW.C new file mode 100644 index 00000000..9501d47c --- /dev/null +++ b/16/roads/INITW.C @@ -0,0 +1,153 @@ +#define INITW_C + +#include +#include +#include "roads.h" +#include "tiles.h" + +extern int view_x, view_y; /* VIEW AREA (UPPER LEFT CORNER) */ +extern int viewpage; /* CURRENTLY VIEWED PAGE */ +extern int startup_vmode; /* VIDEO MODE STARTUP SETTINGS, -1 IF NOT INIT */ + +int far *topography; /* BACKGROUND TILE LIST (ARRAY) */ +int far *terrain; /* FOREGROUND TILE LIST (ARRAY) */ +int world_type=75; /* TENDENCY TO GRASS */ +int edgemode=1; /* BLOCKY GRASS/DIRT OR EDGED? */ +extern int frogmode; + +/* + * + * Loads the world foreground tile list with roads. + * + */ +void init_foreground(void) +{ + register int x, tile, fails; + + /* INITIALIZE FOREGROUND */ + for (x=0; x=CHANCE_LAND_GROUPING) /* NO GROUPING */ + { + if (random(100)>=world_type) landtype_here=1; + else landtype_here=0; + } + + if (landtype_here==0) topography[x]= + random (NUM_GRASS_TILES)+FIRST_GRASS_TILE; /* GRASS */ + else topography[x]= + random (NUM_DIRT_TILES)+FIRST_DIRT_TILE; /* DIRT */ + } + + /* DO FIRST COLUMN */ + for (y=1; y=CHANCE_LAND_GROUPING) /* NO GROUPING */ + { + if (random(100)>=world_type) landtype_here=1; + else landtype_here=0; + } + + if (landtype_here==0) topography[WORLD_TILE(0,y)]= + random (NUM_GRASS_TILES)+FIRST_GRASS_TILE; /* GRASS */ + else topography[WORLD_TILE(0,y)]= + random (NUM_DIRT_TILES)+FIRST_DIRT_TILE; /* DIRT */ + } + + /* DO SUBSEQUENT ROWS */ + for (y=1; y=CHANCE_LAND_GROUPING) /* UNGROUP */ + { + if (random(100)>=world_type) landtype_here=1; + else landtype_here=0; + } + else if (random(2)) landtype_here=landtype_up; + + if (landtype_here==0) topography[WORLD_TILE(x,y)]= + random (NUM_GRASS_TILES)+FIRST_GRASS_TILE; /* GRASS */ + else topography[WORLD_TILE(x,y)]= + random (NUM_DIRT_TILES)+FIRST_DIRT_TILE; /* DIRT */ + } + + if (edgemode) add_dirt_edges (); +} + +/* + * + * Initializes background and foreground tile lists. + * + */ +void init_world(void) +{ + init_background(); + init_foreground(); + view_x=random(WORLD_WIDTH-VIEW_WIDTH); + view_y=random(WORLD_HEIGHT-VIEW_HEIGHT); +} diff --git a/16/roads/KEYS.H b/16/roads/KEYS.H new file mode 100644 index 00000000..8958c78b --- /dev/null +++ b/16/roads/KEYS.H @@ -0,0 +1,31 @@ +#define KEYS_H + +/* KEY DEFINITIONS */ +#define KEY_ENTER 13 + +/* SCAN CODE DEFINITIONS */ +#define SCAN_A 30 +#define SCAN_B 48 +#define SCAN_C 46 +#define SCAN_E 18 +#define SCAN_F 33 +#define SCAN_G 34 +#define SCAN_K 37 +#define SCAN_Q 16 +#define SCAN_R 19 +#define SCAN_S 31 +#define SCAN_T 20 +#define SCAN_W 17 + +#define SCAN_SPACE 57 +#define SCAN_ENTER 28 +#define SCAN_ESC 1 + +#define SCAN_LEFTSHIFT 42 +#define SCAN_RIGHTSHIFT 54 + +#define SCAN_UP 72 +#define SCAN_DOWN 80 +#define SCAN_LEFT 75 +#define SCAN_RIGHT 77 + diff --git a/16/roads/MAKEFILE.MAK b/16/roads/MAKEFILE.MAK new file mode 100644 index 00000000..a6914571 --- /dev/null +++ b/16/roads/MAKEFILE.MAK @@ -0,0 +1,42 @@ +# Makefile +.autodepend + +############################################## Main file name +NAME = roads +############################################## Object files +OBJ1 = anim.obj bookends.obj initroad.obj fx.obj +OBJ= $(OBJ1) roads.obj initw.obj tileio.obj +############################################## Memory Model (ex: s for small) +MODEL = s +############################################## Supplementary dependencies +SUP = +############################################## Path to headers +INCPATH = c:\borlandc\include +############################################## Path to libraries +LIBPATH = c:\borlandc\lib +############################################## Libraries to search +LIBS = c$(MODEL) fg$(MODEL) +############################# emu math$(MODEL) +############################################## Compilation Flags +COMPFLAGS = -Z -G -O2 -c -H -m$(MODEL) -I$(INCPATH) +############################################## Linking Flags +LINKFLAGS = -x -L$(LIBPATH) + + +####### +# Implicit Definitions -- compilation +####### +.c.obj: + BCC $(COMPFLAGS) {$< } + + +####### +# Explicit Definitions -- linking +####### +$(NAME).exe: $(OBJ) $(SUP) + TLINK $(LINKFLAGS) @&&! +c0$(MODEL) $(OBJ) +$(NAME) + +$(LIBS) +! diff --git a/16/roads/READ.ME b/16/roads/READ.ME new file mode 100644 index 00000000..7f5db3bb --- /dev/null +++ b/16/roads/READ.ME @@ -0,0 +1,54 @@ +4/1/94 + +Don and I have decided to charge $50 for ROADS, plus $150 for the source +code. + +4/2/94 + +April Fools. + +ROADS is an attempt to play around with tiles and tiling methods. +We were working on ROADS before Diana Gruber's PC Techniques +articles on tiling came out, and I thought it would be nice to share +some code showing a different mechanism for tiling. It was written +using Borland C++ 3.1 (by choice) and Fastgraph from Ted Gruber +Software. + +ROADS uses 16x16 tiles that were drawn in Autodesk Animator. They +are stored on a hidden page in Mode-X and screen-to-screen copied as +needed. ROADS implements page flipping, so the frame rate will max +out at 70fps (although I only get 29fps on my 386/40). The screen +scroll rate is 16 pixels, although 4 pixel scrolling could be added +fairly easily by doing partial-tile copies. The scrolling is pretty +fast because, like in Diana Gruber's article, we copy the still +valid portion of the screen to the new page, then update the new +tiles. + +Tiles can animate (I'm pretty proud of my fire pit animation), even +while scrolling, and fading. The fading algorithm is based on a +previous upload to the Dusk Devil BBS -- I took out the floating +point calculations and made some modifications. There's also a +walking frog with red sneakers. To discover what keys you can press +when the program is running, type ROADS /?. "Frog watch mode" +doesn't work -- I wrote some bad code, and decided it wasn't worth +fixing. So much for the hacker ethic. + +The program uses Fastgraph's keyboard handler, so you can press, for +example, down and right arrows together, and the view will scroll +down right. + +Feel free to take any of the code you like for your own use. I'm +providing it because ... uh ... because I'm altruistic? Nah. The +program doesn't really DO anything, just tests out some tiling +algorithms. Don flipped when I said I wanted to distribute the +code, but when I reminded him that ROADS was an exercise in +futility, he agreed we should share the pain. + +If you have any questions, comments, or conversation, I'd be pleased +to hear from you. Have fun! + +Dust Devil BBS (Home of Fastgraph): Eric Lund +Delphi: ELUND or elund@delphi.com +GEnie: e.lund1 though I think I going to cancel it +Compuserve: 74041,1147 or 74041.1147@compuserve.com + diff --git a/16/roads/ROADS.C b/16/roads/ROADS.C new file mode 100644 index 00000000..2d153c8a --- /dev/null +++ b/16/roads/ROADS.C @@ -0,0 +1,330 @@ +#define ROADS_C + +#include +#include +#include +#include /* FOR RANDOM */ +#include "roads.h" +#include "tiles.h" /* DUE TO R AND C CHEATS */ +#include "fx.h" /* FOR FADING STUFF */ +#include "version.h" /* INFO ON THIS VERSION */ +#include "keys.h" /* KEY AND SCANCODE DEFINITIONS */ + +extern int far *topography; /* BACKGROUND TILE LIST (ARRAY) */ +extern int far *terrain; /* FOREGROUND TILE LIST (ARRAY) */ +extern int view_x, view_y; /* VIEW AREA (UPPER LEFT CORNER) */ +extern int viewpage; /* CURRENTLY VIEWED PAGE */ +extern int world_type; /* TENDENCY TO GRASS */ + +extern int edgemode; /* BLOCKY GRASS/DIRT OR EDGED? */ +extern int animatemode; +extern int frogmode; +extern int frogwatchmode; + +int keyboardmode=0; + +/* PROTOTYPES FOR INTERNAL FUNCTIONS */ +void time_test (void); +void cheat (int type); +void toggle_mode (int type); +void make_world (int type); +void view_tile_page (void); +void move_view (void); +int keycheck (void); +void init_all (void); +void gogofrog (void); + +#pragma argsused +void main (int argc, char *argv[]) +{ + char quitting_time=0; /* QUIT PROGRAM LOOP */ + + printf (HEADER); + + if (argc>1) + { + printf (KEY_HELP); + exit (2); + } + + printf ("Loading ... [Escape quits] ... [Type ROADS /? for more keys!]\n"); + init_all(); /* INITIALIZE ALL SYSTEMS */ + + while (!quitting_time) /* LOOP FOREVER */ + { + quitting_time=keycheck(); /* CHECK FOR REGULAR KEYS */ + if (animatemode) animate(); /* PERFORM ALL ANIMATIONS */ + } + + program_shutdown("Thank you for running ROADS!", 0); +} + +#define TIMETEST_LENGTH 10 /* TIME TEST LENGTH IN SECONDS */ + +/* + * + * Performs time testing to try and guess a FPS. + * + */ +void time_test (void) +{ + int x, dir; + long end_time; + int frames_shown[2]; + + for (x=0; x<2; x++) /* TEST TWICE, ONCE WITH ANIMATION */ + { + while (redraw(SCROLL_UL)); /* SCROLL UPPER LEFT TO START */ + fg_music ("L64FAC.AE.B$"); + frames_shown[x]=0; dir=0; + end_time=TIMETEST_LENGTH*182/10; + end_time+=fg_getclock(); + + while (fg_getclock()100) right=100; + if (left>100) left=100; + if (up>100) up=100; + if (down>100) down=100; + + /* IF "TAP" KEYBOARD MODE IS ON, DON'T MOVE UNTIL KEYS RELEASED */ + if (keyboardmode && (right>1 || left>1 || up>1 || down>1)) return; + + /* MOVE, CHECKING FOR DIAGONAL MOVEMENT FIRST */ + if (up && right) redraw (SCROLL_UR); + else if (down && left) redraw (SCROLL_DL); + else if (up && left) redraw (SCROLL_UL); + else if (down && right) redraw (SCROLL_DR); + else if (right) redraw (SCROLL_RIGHT); + else if (left) redraw (SCROLL_LEFT); + else if (up) redraw (SCROLL_UP); + else if (down) redraw (SCROLL_DOWN); +} + +/* + * + * Initializes all systems and brings display up. + * + */ +void init_all (void) +{ + fg_kbinit(1); /* LATCH LOW-LEVEL KEYBOARD HANDLER */ + randomize(); /* ALLOW RANDOMIZATIONS */ + + init_anim(); /* CALL BEFORE WORLD CREATION */ + init_data(); /* CALL BEFORE WORLD CREATION */ + init_world(); /* RANDOMIZE THE WORLD */ + init_video(); /* SET OUR VIDEO MODE ETC. */ + + fade_init(); /* ALLOW FADING */ + fade_blackout(); /* SET ALL COLORS TO BLACK */ + redraw(REFRESH); /* DRAW THE SCREEN (UNSEEN) */ + fade_in_all(); /* FADE IN SCREEN */ +} + +/* + * + * Keycheck checks all keys and reacts upon them. + * Returns 1 if a key has indicated the user has requested to quit. + * + */ +int keycheck (void) +{ + if (fg_kbtest(SCAN_T)) time_test(); + if (fg_kbtest(SCAN_C)) cheat (0); + if (fg_kbtest(SCAN_R)) cheat (1); + if (fg_kbtest(SCAN_A)) toggle_mode(0); + if (fg_kbtest(SCAN_E)) toggle_mode(1); + if (fg_kbtest(SCAN_K)) toggle_mode(2); + if (fg_kbtest(SCAN_W)) toggle_mode(3); + if (fg_kbtest(SCAN_F)) + { + fg_music ("L50O4BAFDEF.$"); + switch (frogmode) + { + case 1: frogmode=2; break; + case 3: frogmode=0; break; + } + } + if (fg_kbtest(SCAN_G)) /* RERANDOMIZE GRASS/DIRT TENDENCY */ + { + world_type=random(100); + fg_music ("S1L20C..B..A..$"); + } + if (fg_kbtest(SCAN_SPACE)) make_world (0); + if (fg_kbtest(SCAN_B)) make_world (1); + if (fg_kbtest(SCAN_ENTER)) make_world (2); + if (fg_kbtest(SCAN_S)) view_tile_page(); + + move_view(); /* RESPOND TO ARROW KEYS MOVING VIEW */ + + if (fg_kbtest(SCAN_ESC) || fg_kbtest(SCAN_Q)) /* ESCAPE TO QUIT */ + return 1; + + return 0; +} + diff --git a/16/roads/ROADS.EXE b/16/roads/ROADS.EXE new file mode 100644 index 0000000000000000000000000000000000000000..b8aa0167ad4233b238161dc928875aaf6d7c01fb GIT binary patch literal 67438 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 literal 0 HcmV?d00001 diff --git a/16/roads/ROADS.GIF b/16/roads/ROADS.GIF new file mode 100644 index 0000000000000000000000000000000000000000..496b61298d1f0b5c5a970dad8045420724a141e7 GIT binary patch literal 11488 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 G0028n3FssM literal 0 HcmV?d00001 diff --git a/16/roads/ROADS.H b/16/roads/ROADS.H new file mode 100644 index 00000000..d4e10a95 --- /dev/null +++ b/16/roads/ROADS.H @@ -0,0 +1,143 @@ +#define ROADS_H + +/* GENERIC TILING DEFINITIONS */ + +#define WORLD_WIDTH 105 /* IN TILES, WIDTH OF "PLAYFIELD" */ +#define WORLD_HEIGHT 100 /* IN TILES, HEIGHT OF "PLAYFIELD" */ +#define WORLD_TILES_TOTAL 10500 /* (WORLD_WIDTH*WORLD_HEIGHT) */ + +#define TILE_WIDTH 16 /* IN PIXELS, WIDTH OF TILE */ +#define TILE_HEIGHT 16 /* IN PIXELS, HEIGHT OF TILE */ +#define VIEW_WIDTH 20 /* (SCREEN_WIDTH/TILE_WIDTH) */ +#define VIEW_HEIGHT 15 /* (SCREEN_HEIGHT/TILE_HEIGHT) */ +#define VIEW_TILES_TOTAL 300 /* (VIEW_WIDTH*VIEW_HEIGHT) */ +#define MIXING_TILE 299 /* (VIEW_TILES_TOTAL-1) */ +#define EMPTY_TILE -1 /* STANDARD INDEX FOR A SEE-THROUGH TILE */ +#define ERROR_TILE -2 /* STANDARD INDEX FOR ERRORS! */ + +/* PROTOTYPES */ + +void create_roads (void); +int roadexit (int road, int direction); +int makeintersection (int road, int ramp); +void init_foreground (void); +void init_background (void); +void add_dirt_edges (void); +void init_world(void); +int redraw (int draw_type); +void init_video (void); +void init_data (void); +void program_shutdown (char *msg, int errcode); +void place_tile_block (int x1, int y1, int x2, int y2); +void init_anim (void); +void animate (void); +void update_tile (int tile); +void gogofrog (void); + +/* VIDEO MODE DEFINITIONS */ +#define VMODE 22 +#define VPAGES 3 +#define SCREEN_WIDTH 320 +#define SCREEN_HEIGHT 240 +#define IMAGES "roads.gif" /* IMAGE CONTAINING TILES */ + +/* VIDEO PAGE DEFINITIONS */ +#define VIEWPAGE1 0 +#define VIEWPAGE2 1 +#define TILEPAGE 2 + +/* STANDARD DEFINITIONS */ +#define FALSE 0 +#define TRUE 1 + +/* CHECKS IF A TILE IS A ROAD OR NOT */ +#define isroad(r) (r>=FIRST_ROAD_TILE && r<=LAST_ROAD_TILE) + +#define REFRESH 0 +#define SCROLL_UP 1 +#define SCROLL_DOWN 2 +#define SCROLL_LEFT 3 +#define SCROLL_RIGHT 4 +#define SCROLL_UR 5 +#define SCROLL_DR 6 +#define SCROLL_DL 7 +#define SCROLL_UL 8 +#define NONFLIP_SCROLL_UP 11 +#define NONFLIP_SCROLL_DOWN 12 +#define NONFLIP_SCROLL_LEFT 13 +#define NONFLIP_SCROLL_RIGHT 14 +#define NONFLIP_REFRESH 15 + +#define MAX_FAILS 50 /* MAXIMUM NUMBER OF ATTEMPTS TO PLACE TILES */ + +/* + * + * MACROS TO CONVERT TILES FROM "ROW/COLUMN" FORMAT TO "INDEX" FORMAT + * + */ + + /* WORLD SPACE CONVERSIONS */ +#define WORLD_TILE(x,y) ((x)+(y)*WORLD_WIDTH) /* CONVERTS DUAL X,Y TO SINGLE */ +#define WORLD_TILE_X(z) ((z)%WORLD_WIDTH) /* CONVERTS SINGLE TO DUAL X */ +#define WORLD_TILE_Y(z) ((z)/WORLD_WIDTH) /* CONVERTS SINGLE TO DUAL Y */ + + /* VIEW SPACE CONVERSIONS */ +#define VIEW_TILE(x,y) ((x)+(y)*VIEW_WIDTH) /* CONVERTS DUAL X,Y TO SINGLE */ +#define VIEW_TILE_X(z) ((z)%VIEW_WIDTH) /* CONVERTS SINGLE TO DUAL X */ +#define VIEW_TILE_Y(z) ((z)/VIEW_WIDTH) /* CONVERTS SINGLE TO DUAL Y */ + +/* RETURNS 1 IF A SINGLE WORLD TILE INDEX IS WITHIN THE VIEWING SCREEN */ +#define is_viewable(x) (WORLD_TILE_X(x)>=view_x && \ + WORLD_TILE_X(x)=view_y && \ + WORLD_TILE_Y(x)