From: sparky4 Date: Thu, 22 Jan 2015 18:56:12 +0000 (-0600) Subject: compy4 sync X-Git-Url: http://4ch.mooo.com/gitweb/?p=16.git;a=commitdiff_plain;h=fdda3e0aec6ed31959bf39263116dc5f6a481a4b compy4 sync deleted: 16/Q.BAT new file: 16/fcsp2src.zip deleted: 16/lib/TYPES.H deleted: 16/lib/types.h deleted: 16/q.bat 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 new file: 16/starport2/FCINFO12.TXT new file: 16/starport2/FILE_ID.DIZ new file: 16/starport2/MAKE.BAT new file: 16/starport2/README new file: 16/starport2/SP2.ASM new file: 16/starport2/SP2.COM modified: Project 16.bfproject deleted: SCROLL.SMP new file: doc/CGUIDE_3.TXT modified: makefile modified: pcxtest.exe new file: planarNotes.txt modified: scroll.exe new file: src/lib/PLANAR.C new file: src/lib/ems.c new file: src/lib/ems1.c modified: src/lib/lib_head.h modified: src/lib/modex16.c modified: src/lib/modex16.h new file: src/lib/planar.h new file: src/lib/xmem/xmem.asm new file: src/lib/xmem/xmem.h new file: src/lib/xmem/xmem.txt new file: src/lib/xmem/xmemc.c new file: src/lib/xms.c new file: src/lib/xms.h modified: src/scroll.c modified: src/test2.c modified: test.exe modified: test2.exe --- diff --git a/16/Q.BAT b/16/Q.BAT deleted file mode 100644 index 5d1b5845..00000000 --- a/16/Q.BAT +++ /dev/null @@ -1,5 +0,0 @@ -call hres -vi dos_gfx.cpp -call x -pause -dos_gfx.exe diff --git a/16/fcsp2src.zip b/16/fcsp2src.zip new file mode 100644 index 00000000..48852313 Binary files /dev/null and b/16/fcsp2src.zip differ diff --git a/16/lib/TYPES.H b/16/lib/TYPES.H deleted file mode 100644 index 039653f2..00000000 --- a/16/lib/TYPES.H +++ /dev/null @@ -1,11 +0,0 @@ -/* - * Just some handy typedefs that make it easier to think about the low - * level code - */ - -typedef unsigned char byte; -typedef unsigned short word; -typedef unsigned long dword; -typedef signed char sbyte; -typedef signed short sword; -typedef signed long sdword; diff --git a/16/lib/types.h b/16/lib/types.h deleted file mode 100644 index 039653f2..00000000 --- a/16/lib/types.h +++ /dev/null @@ -1,11 +0,0 @@ -/* - * Just some handy typedefs that make it easier to think about the low - * level code - */ - -typedef unsigned char byte; -typedef unsigned short word; -typedef unsigned long dword; -typedef signed char sbyte; -typedef signed short sword; -typedef signed long sdword; diff --git a/16/q.bat b/16/q.bat deleted file mode 100644 index 5d1b5845..00000000 --- a/16/q.bat +++ /dev/null @@ -1,5 +0,0 @@ -call hres -vi dos_gfx.cpp -call x -pause -dos_gfx.exe 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 00000000..b8aa0167 Binary files /dev/null and b/16/roads/ROADS.EXE differ diff --git a/16/roads/ROADS.GIF b/16/roads/ROADS.GIF new file mode 100644 index 00000000..496b6129 Binary files /dev/null and b/16/roads/ROADS.GIF differ 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)