From b2f86e20e052d9923523e29743172ea98266d28f Mon Sep 17 00:00:00 2001 From: Ian C Date: Tue, 25 Jun 2019 18:37:47 +0000 Subject: Added original Hardwire code. --- hardwire/DEADJIM.WAV | Bin 0 -> 10597 bytes hardwire/FONT8.PCX | Bin 0 -> 4707 bytes hardwire/HWPAL.H | 40 + hardwire/HW_GAME.MID | Bin 0 -> 3472 bytes hardwire/HW_SCORE.MID | Bin 0 -> 6289 bytes hardwire/HW_TITLE.MID | Bin 0 -> 5829 bytes hardwire/MAKEFILE | 11 + hardwire/SPRITE16.PCX | Bin 0 -> 7609 bytes hardwire/SPRITE8.PCX | Bin 0 -> 4707 bytes hardwire/allegro.cfg | 134 +++ hardwire/click.wav | Bin 0 -> 3530 bytes hardwire/endline.wav | Bin 0 -> 26422 bytes hardwire/font8.pds | Bin 0 -> 30728 bytes hardwire/hardwire.c | 2720 ++++++++++++++++++++++++++++++++++++++++++++++++ hardwire/hardwire.dat | Bin 0 -> 61395 bytes hardwire/hardwire.txt | 140 +++ hardwire/hwdat.h | 45 + hardwire/hwscores | Bin 0 -> 180 bytes hardwire/keystr.h | 141 +++ hardwire/pathway.wav | Bin 0 -> 33342 bytes hardwire/pause_bmp.pcx | Bin 0 -> 1843 bytes hardwire/piecemap.h | 222 ++++ hardwire/popsound.wav | Bin 0 -> 9112 bytes hardwire/readme.h | 109 ++ hardwire/sprite16.pds | Bin 0 -> 30728 bytes hardwire/sprite8.pds | Bin 0 -> 30728 bytes 26 files changed, 3562 insertions(+) create mode 100644 hardwire/DEADJIM.WAV create mode 100644 hardwire/FONT8.PCX create mode 100644 hardwire/HWPAL.H create mode 100644 hardwire/HW_GAME.MID create mode 100644 hardwire/HW_SCORE.MID create mode 100644 hardwire/HW_TITLE.MID create mode 100644 hardwire/MAKEFILE create mode 100644 hardwire/SPRITE16.PCX create mode 100644 hardwire/SPRITE8.PCX create mode 100644 hardwire/allegro.cfg create mode 100644 hardwire/click.wav create mode 100644 hardwire/endline.wav create mode 100644 hardwire/font8.pds create mode 100644 hardwire/hardwire.c create mode 100644 hardwire/hardwire.dat create mode 100644 hardwire/hardwire.txt create mode 100644 hardwire/hwdat.h create mode 100644 hardwire/hwscores create mode 100644 hardwire/keystr.h create mode 100644 hardwire/pathway.wav create mode 100644 hardwire/pause_bmp.pcx create mode 100644 hardwire/piecemap.h create mode 100644 hardwire/popsound.wav create mode 100644 hardwire/readme.h create mode 100644 hardwire/sprite16.pds create mode 100644 hardwire/sprite8.pds diff --git a/hardwire/DEADJIM.WAV b/hardwire/DEADJIM.WAV new file mode 100644 index 0000000..473a4df Binary files /dev/null and b/hardwire/DEADJIM.WAV differ diff --git a/hardwire/FONT8.PCX b/hardwire/FONT8.PCX new file mode 100644 index 0000000..88e05fd Binary files /dev/null and b/hardwire/FONT8.PCX differ diff --git a/hardwire/HWPAL.H b/hardwire/HWPAL.H new file mode 100644 index 0000000..5f66a6b --- /dev/null +++ b/hardwire/HWPAL.H @@ -0,0 +1,40 @@ +/* + Auto generated by pcxdes.exe +*/ + +#define BLACK 0 +#define WHITE 1 +#define BLUE 2 +#define RED 3 +#define GREEN 4 +#define CYAN 5 +#define YELLOW 6 +#define PURPLE 7 +#define GREY7 8 +#define GREY6 9 +#define GREY5 10 +#define GREY4 11 +#define GREY3 12 +#define GREY2 13 +#define GREY1 14 +#define BLACKDRAW 15 +#define BASHI 16 +#define BASMID 17 +#define BASLO 18 +#define CHANCOL 19 +#define POINTCOL 20 +#define FILLCHANCOL 21 +#define BLOCK1COL 64 +#define BLOCK2COL 67 +#define BLOCK3COL 70 +#define BLOCK4COL 73 +#define BLOCK5COL 76 +#define BLOCK6COL 79 +#define BLOCK7COL 82 +#define BLOCK8COL 85 +#define PARTCOLMIN 128 +#define PARTCOLMAX 149 +#define STARCOLMIN 150 +#define STARCOLMAX 199 +#define MELTOMIN 200 +#define MELTOMAX 255 diff --git a/hardwire/HW_GAME.MID b/hardwire/HW_GAME.MID new file mode 100644 index 0000000..e73f7f4 Binary files /dev/null and b/hardwire/HW_GAME.MID differ diff --git a/hardwire/HW_SCORE.MID b/hardwire/HW_SCORE.MID new file mode 100644 index 0000000..3be56f4 Binary files /dev/null and b/hardwire/HW_SCORE.MID differ diff --git a/hardwire/HW_TITLE.MID b/hardwire/HW_TITLE.MID new file mode 100644 index 0000000..9e60ed9 Binary files /dev/null and b/hardwire/HW_TITLE.MID differ diff --git a/hardwire/MAKEFILE b/hardwire/MAKEFILE new file mode 100644 index 0000000..cff0d4d --- /dev/null +++ b/hardwire/MAKEFILE @@ -0,0 +1,11 @@ +# $Id$ +# +OPTS=-Wall -O -fomit-frame-pointer +OBJ=hardwire +LIB=-lalleg +HEADER=hwpal.h hwdat.h piecemap.h readme.h keystr.h + +ALL: $(OBJ).exe + +$(OBJ).exe: $(OBJ).c $(HEADER) + $(CC) $(OPTS) -o $(OBJ).exe $(OBJ).c $(LIB) diff --git a/hardwire/SPRITE16.PCX b/hardwire/SPRITE16.PCX new file mode 100644 index 0000000..ed438d5 Binary files /dev/null and b/hardwire/SPRITE16.PCX differ diff --git a/hardwire/SPRITE8.PCX b/hardwire/SPRITE8.PCX new file mode 100644 index 0000000..7af2ec5 Binary files /dev/null and b/hardwire/SPRITE8.PCX differ diff --git a/hardwire/allegro.cfg b/hardwire/allegro.cfg new file mode 100644 index 0000000..b053233 --- /dev/null +++ b/hardwire/allegro.cfg @@ -0,0 +1,134 @@ +# +# Configuration file for the Allegro library. +# +# If you leave a parameter blank, Allegro will autodetect (ie. guess :-) +# +# This file should be kept either in the same directory as your program, +# or in a location pointed to by the "ALLEGRO" environment variable. + + +# graphics driver (there is usually no need to set this) +# 1 = VGA mode 13h 2 = Mode-X +# 3 = VESA 1.x 4 = VBE 2.0 (banked) +# 5 = VBE 2.0 (linear) 6 = VBE/AF +# 7 = Xtended mode 8 = ATI 18800/28800 +# 9 = ATI mach64 10 = Cirrus 64xx +# 11 = Cirrus 54xx 12 = Paradise +# 13 = S3 14 = Trident +# 15 = Tseng ET3000 16 = Tseng ET4000 +# 17 = Video-7 +gfx_card = + + +# name of the keyboard scancode mapping file (this can be a disk .cfg +# file or an object from keyboard.dat). Currently available layouts are: +# BE - Belgium +# DE - Germany +# DVORAK - Dvorak +# ES - Spain +# FI - Finland +# FR - France +# PT - Portugal +# UK - United Kingdom +# US - United States +keyboard = + + +# mouse type: Microsoft, Logitech, or NT (only change if you have problems) +mouse = + + + +[sound] + + +# digital sound output driver +# 0 = none 1 = SB (autodetect breed) +# 2 = SB 1.0 3 = SB 1.5 +# 4 = SB 2.0 5 = SB Pro +# 6 = SB16 7 = GUS (unfinished) +digi_card = + + +# music output driver +# 0 = none 1 = Adlib (autodetect OPL version) +# 2 = OPL2 3 = Dual OPL2 (SB Pro-1) +# 4 = OPL3 5 = SB MIDI interface +# 6 = MPU-401 7 = GUS (unfinished) +# 8 = DIGMID 9 = AWE32 +midi_card = + + +# how many voices to reserve for each driver +digi_voices = +midi_voices = + + +# how loud? (range 0-255) +digi_volume = +midi_volume = + + +# toggling this between 0 and 1 reverses the left/right panning of samples +flip_pan = + + +# SB port address (usually 220) +sb_port = + + +# SB DMA channel (usually 1) +sb_dma = + + +# SB IRQ number (usually 7) +sb_irq = + + +# SB sample frequency (11906, 16129, 22727 or 45454) +sb_freq = + + +# FM synth port address (usually 388) +fm_port = + + +# MPU-401 port address (usually 330) +mpu_port = + + +# instrument definitions for the Adlib driver +ibk_file = +ibk_drum_file = + + +# patch set for the DIGMID driver +patches = + + + +[grabber] + + +# should we make .bak files when saving datafiles? +backups = n + + +# default grid size for grabbing images +xgrid = 16 +ygrid = 16 + + +# edit these shell commands to whatever helper programs you want to use... +data = start /w notepad +bmp = start /w "c:\program files\accessories\mspaint.exe" +rle = start /w "c:\program files\accessories\mspaint.exe" +cmp = start /w "c:\program files\accessories\mspaint.exe" +xcmp = start /w "c:\program files\accessories\mspaint.exe" +pal = start /w "c:\program files\accessories\mspaint.exe" +font = start /w "c:\program files\accessories\mspaint.exe" +samp = start /w "c:\program files\cooledit\cool.exe" +midi = start /w "c:\program files\cakewalk\wincake.exe" + + + diff --git a/hardwire/click.wav b/hardwire/click.wav new file mode 100644 index 0000000..74a37bb Binary files /dev/null and b/hardwire/click.wav differ diff --git a/hardwire/endline.wav b/hardwire/endline.wav new file mode 100644 index 0000000..32b4a6c Binary files /dev/null and b/hardwire/endline.wav differ diff --git a/hardwire/font8.pds b/hardwire/font8.pds new file mode 100644 index 0000000..af4fa29 Binary files /dev/null and b/hardwire/font8.pds differ diff --git a/hardwire/hardwire.c b/hardwire/hardwire.c new file mode 100644 index 0000000..f6b5871 --- /dev/null +++ b/hardwire/hardwire.c @@ -0,0 +1,2720 @@ +/* + Hardwire + (c) 1997 Noddybox + Written using DJGPP v2 and Allegro 3.0 + + Allegro written by Shawn Hargreaves + +*/ +static char version[]="1.0"; + +/* Includes +*/ +#include +#include +#include +#include +#include +#include "hwpal.h" +#include "hwdat.h" +#include "keystr.h" + + +/* Macros +*/ +#define RND(x) (rand()%(x)) +#define CENTRE(s,y,col) textout_centre(img,font8,s,CX,y,col) + + +/* Types and stuff +*/ +#define HISC 5 +#define HISCFILE "hwscores" + +#define GAME_TYPES 3 +#define TETRIS_WIRE 0 +#define COLUMNS_WIRE 1 +#define TETRIS_CLASSIC 2 + +#define SPRSIZE 8 +#define MAXPITWIDTH 12 +#define MINPITWIDTH 6 +#define PITDEPTH 17 +#define PITXOFF (SPRSIZE*2+((MAXPITWIDTH-PITWIDTH)*SPRSIZE/2)) +#define PITYOFF SPRSIZE*4 + +#define PITX(x) (((x)*SPRSIZE)+PITXOFF) +#define PITY(y) (((y)*SPRSIZE)+PITYOFF) + +#define SCOREPX 200 +#define SCOREX (SCOREPX+50) +#define SCOREY 20 + +#define LEVELPX 200 +#define LEVELX (LEVELPX+50) +#define LEVELY 40 + +#define NEXTPX 200 +#define NEXTX (NEXTPX+50) +#define NEXTY 100 + +#define BASECTR (SLOW ? (MODE==TETRIS_CLASSIC ? 30 : 100) : \ + (MODE==TETRIS_CLASSIC ? 50 : 150)) + +#define WEIGHTCTR (SLOW ? (MODE==TETRIS_CLASSIC ? 2 : 8) : \ + (MODE==TETRIS_CLASSIC ? 4 : 12)) + + +#define LEVELCTR(x) (MAX((BASECTR-(x)*WEIGHTCTR),3)) + +#define BOUNCEVAL 10 + +#define KEYBOUNCE(k,x) if (!key[k]) \ + x=0; \ + else \ + if (x) \ + x-- + +#define NODIR -1 +#define LEFT 0 +#define UP 1 +#define RIGHT 2 +#define DOWN 3 +#define PATHLEN (MAXPITWIDTH*PITDEPTH) + +#define ROR(x) ((x) ? ((x)-1) : (3)) +#define ROL(x) (((x)+1)%4) +#define REV(x) (((x)+2)%4) + +int xi[4]={-1,0,1,0}; +int yi[4]={0,-1,0,1}; + +char *modetxt[GAME_TYPES]={"TETRIS WIRE", + "COLUMNS WIRE", + "TETRIS CLASSIC"}; + +typedef struct + { + int data[PITDEPTH][MAXPITWIDTH]; + int id[PITDEPTH][MAXPITWIDTH]; + } Pit; + +Pit pit; + +typedef struct + { + int x,y; + } PathElem; + +typedef struct + { + int len; + PathElem p[PATHLEN]; + } Path; + +typedef struct + { + int score; + int level; + char name[4]; + } Hisc; + +Hisc hisc[GAME_TYPES][HISC] = + { + { + {500,5,"S.V"}, + {250,4,"S.V"}, + {200,3,"S.V"}, + {150,2,"S.V"}, + {100,1,"S.V"}, + }, + { + {500,5,"S.V"}, + {250,4,"S.V"}, + {200,3,"S.V"}, + {150,2,"S.V"}, + {100,1,"S.V"}, + }, + { + {500,5,"S.V"}, + {250,4,"S.V"}, + {200,3,"S.V"}, + {150,2,"S.V"}, + {100,1,"S.V"}, + }, + }; + +/* Key controls +*/ +#define KQUIT KEY_ESC +#define KREADME KEY_I +#define KDEFINE KEY_R +#define KTOGGLE_MODE KEY_F1 +#define KTOGGLE_LEVEL KEY_F2 +#define KTOGGLE_WIDTH KEY_F3 +#define KTOGGLE_MOTION KEY_F4 +#define KTOGGLE_MUSIC KEY_F5 +#define KBORED KEY_F9 +#define DEF_KLEFT KEY_LEFT +#define DEF_KRIGHT KEY_RIGHT +#define DEF_KROTATER KEY_DOWN +#define DEF_KROTATEL KEY_UP +#define DEF_KDROP KEY_SPACE +#define DEF_KPAUSE KEY_P + +int KLEFT= KEY_LEFT; +int KRIGHT= KEY_RIGHT; +int KROTATER= KEY_DOWN; +int KROTATEL= KEY_UP; +int KDROP= KEY_SPACE; +int KPAUSE= DEF_KPAUSE; + +#define GETKEY (keypressed() ? (readkey()>>8) : (-1)) + +int used_keys[129]; + + +/* Object types - defines from less obvious names from DAT file +*/ +#define PIT_TL SPRITE8_000 +#define PIT_ML SPRITE8_001 +#define PIT_BL SPRITE8_002 +#define PIT_BM SPRITE8_003 +#define PIT_BR SPRITE8_004 +#define PIT_MR SPRITE8_005 +#define PIT_TR SPRITE8_006 + +#define CLASSIC_WALL SPRITE8_024 + +#define SPECIAL SPRITE8_007 +#define CROSS SPRITE8_008 +#define UPDOWN SPRITE8_009 +#define ACROSS SPRITE8_010 +#define LEFTDOWN SPRITE8_011 +#define RIGHTDOWN SPRITE8_012 +#define RIGHTUP SPRITE8_013 +#define LEFTUP SPRITE8_014 +#define PATH SPRITE8_015 + +#define BLOCK1SPR SPRITE8_016 +#define BLOCK2SPR SPRITE8_017 +#define BLOCK3SPR SPRITE8_018 +#define BLOCK4SPR SPRITE8_019 +#define BLOCK5SPR SPRITE8_020 +#define BLOCK6SPR SPRITE8_021 +#define BLOCK7SPR SPRITE8_022 +#define BLOCK8SPR SPRITE8_023 + +#define HISC_CURS1 SPRITE16_000 +#define HISC_CURS2 SPRITE16_001 +#define HISC_CURS3 SPRITE16_002 + +#define BLANK (-1) + +#define RNDPIECE (RND((RIGHTUP-CROSS))+CROSS) + +#define SPR(x) (RLE_SPRITE*)dfile[(x)].dat +#define SAM(x) (SAMPLE*)dfile[(x)].dat + + +/* Object and game type control types +*/ +void GenTetrisWirePiece(int special), + RotTetrisWirePiece(int dir); +void GenColumnsWirePiece(int special), + RotColumnsWirePiece(int dir); +void GenTetrisClassicPiece(int special), + RotTetrisClassicPiece(int dir); +void CheckWirePaths(void), + CheckClassicPaths(void); + +typedef struct + { + int ox,oy; + int data[4][4]; + } Piece; + +typedef struct + { + int no; + int piece[5]; + } PieceSet; + +typedef struct + { + void (*gen_piece)(int); + void (*rot_piece)(int); + void (*do_paths)(void); + int special_count; + } GameDefinition; + +typedef struct + { + int x,y; + int level; + int score; + int rotate; + int is_special; + int current_type; + Piece current; + int next_is_special; + int next_type; + Piece next; + } Game; + +GameDefinition gamedef[GAME_TYPES]= + { + { + GenTetrisWirePiece, + RotTetrisWirePiece, + CheckWirePaths, + 40 + }, + { + GenColumnsWirePiece, + RotColumnsWirePiece, + CheckWirePaths, + 60 + }, + { + GenTetrisClassicPiece, + RotTetrisClassicPiece, + CheckClassicPaths, + 99 + } + }; + + +/* Game piece maps - In a seperate include to maintain some semblance + of neatness. Include file must have these arrays : + + PieceSet piece_set[NO_PIECE_SET]; + Piece tetris_map[NO_TETRIS_PIECE]; + int tetris_height[NO_TETRIS_PIECE]; + {anon} tetris_off[NO_TETRIS_PIECE][4].(x|y); + + Note that the columns mapping is handled in an hard coded + way, thanks to it's easiness. + + Also note that the same maps are used for both TETRIS + modes, but the classic mode replaces the wiring sprites + with simple block sprites. +*/ +#include "piecemap.h" + + + +/* Control vars +*/ +int SOUND =TRUE; /* TRUE on doing sound code */ +int MUSIC =TRUE; +int PITWIDTH=MAXPITWIDTH; +int LEVEL =1; +int SCORE =0; +int MODE =TETRIS_WIRE; +int MOTION =TRUE; +int SLOW =FALSE; + + +/* Function defs +*/ +void TitlePage(void); + +void Error(char *msg); + +void ReadMe(void); + +void DefineKeys(void); + +void PlayGame(void); +void GameOver(void); +void EnterHisc(void); + +void SoundFX(int fx); + +void LoadHisc(void); +void SaveHisc(void); + +void Redraw(void); +void Melt(int x1,int y1,int x2,int y2); + +void InitStars(void); +void RemoveStars(void); +void UpdateStars(void); + +void InitParticles(void); +void RemoveParticles(void); +void UpdateParticles(void); +void AddParticle(int x,int y,int xi,int yi); + +void InitScores(void); +void AddScore(char *s,int sc); +void UpdateScores(void); + +int ROL_Piece(int tile); +int ROR_Piece(int tile); + +int FindPathFrom(int sx,int sy,int dir,Path *p); +int FindPath(Path *p); +int FindLoopFrom(int ox,int oy,int x,int y,int dir,Path *p); +int FindLoop(Path *p); +void GetSpecialPath(Path *p); +void DrawPath(Path *p); + +void DrawGameScreen(void); +void RedrawPit(void); +void DrawPiece(void); +void ErasePiece(void); +void DrawInfo(void); + +int MoveOK(int x,int y); +int AddAndCheckIsDead(int id); +void CompressPath(void); +void CompressBlanks(void); +void GameRedraw(void); +void DoPause(void); + + +/* Allegro vars +*/ +#define CX (SCREEN_W/2) +#define CY (SCREEN_H/2) + +BITMAP *img; +BITMAP *workimg; +DATAFILE *dfile; +PALETTE pal; +FONT *font8; +MIDI *title_midi,*game_midi,*score_midi; + + +/* Global vars +*/ +int quit=FALSE; +Game game; + + + +/* ------------------------------------------------------------------------- + MAIN + ------------------------------------------------------------------------- */ + +int main(int argc,char **argv) + +{ + int x,y; + int arg; + int f; + + srand(getpid()); + + /* Parse switchs + */ + arg=1; + while(arghisc[MODE][HISC-1].score) + { + EnterHisc(); + SaveHisc(); + } + + TitlePage(); + } + + return (0); +} + + + +/* ------------------------------------------------------------------------- + UTILS + ------------------------------------------------------------------------- */ + +void Error(char *s) +{ + allegro_exit(); + fprintf(stderr,"%s\n",s); + exit(1); +} + + +/* ------------------------------------------------------------------------- + WIRE ROTATE PIECE UTILS + ------------------------------------------------------------------------- */ + +int ROL_Piece(int tile) +{ + /* This should be in a table, but using sprite numbers for the tile + codes makes that not so neat + */ + switch(tile) + { + case CROSS: + return(CROSS); + break; + + case UPDOWN: + return(ACROSS); + break; + + case ACROSS: + return(UPDOWN); + break; + + case LEFTDOWN: + return(LEFTUP); + break; + + case RIGHTDOWN: + return(LEFTDOWN); + break; + + case LEFTUP: + return(RIGHTUP); + break; + + case RIGHTUP: + return(RIGHTDOWN); + break; + + default: + return(BLANK); + break; + } +} + + +int ROR_Piece(int tile) +{ + /* This should be in a table, but using sprite numbers for the tile + codes makes that not so neat + */ + switch(tile) + { + case CROSS: + return(CROSS); + break; + + case UPDOWN: + return(ACROSS); + break; + + case ACROSS: + return(UPDOWN); + break; + + case LEFTDOWN: + return(RIGHTDOWN); + break; + + case RIGHTDOWN: + return(RIGHTUP); + break; + + case LEFTUP: + return(LEFTDOWN); + break; + + case RIGHTUP: + return(LEFTUP); + break; + + default: + return(BLANK); + break; + } +} + + +/* ------------------------------------------------------------------------- + WIRE PATH UTILS + ------------------------------------------------------------------------- */ + +int Dir(int tile,int dir) +{ + switch(tile) /* This should be in a table, but */ + { /* using sprite numbers for the tile */ + case CROSS: /* codes makes that not so neat */ + return(dir); + break; + + case UPDOWN: + if ((dir==UP)||(dir==DOWN)) + return(dir); + else + return(NODIR); + break; + + case ACROSS: + if ((dir==LEFT)||(dir==RIGHT)) + return(dir); + else + return(NODIR); + break; + + case LEFTDOWN: + if (dir==RIGHT) + return(DOWN); + else if (dir==UP) + return(LEFT); + else + return(NODIR); + break; + + case RIGHTDOWN: + if (dir==LEFT) + return(DOWN); + else if (dir==UP) + return(RIGHT); + else + return(NODIR); + break; + + case LEFTUP: + if (dir==RIGHT) + return(UP); + else if (dir==DOWN) + return(LEFT); + else + return(NODIR); + break; + + case RIGHTUP: + if (dir==LEFT) + return(UP); + else if (dir==DOWN) + return(RIGHT); + else + return(NODIR); + break; + + default: + return(NODIR); + break; + } +} + + +int FindPathFrom(int sx,int sy,int dir,Path *p) +{ + dir=Dir(pit.data[sy][sx],dir); + + if (dir==NODIR) + { + p->len=0; + return (FALSE); + } + + p->p[p->len].x=sx; + p->p[p->len].y=sy; + p->len++; + + sx+=xi[dir]; + sy+=yi[dir]; + + if (sy==-1) + { + return (FALSE); + p->len=0; + } + + if ((sx==-1)||(sx==PITWIDTH)||(sy==PITDEPTH)) + return (TRUE); + else + return (FindPathFrom(sx,sy,dir,p)); +} + + +int FindPath(Path *p) +{ + int f; + + p->len=0; + + for(f=PITDEPTH-1;f>=0;f--) + { + if (FindPathFrom(0,f,RIGHT,p)) + return (TRUE); + + if (FindPathFrom(PITWIDTH-1,f,LEFT,p)) + return (TRUE); + } + + for(f=0;flen=0; + return (FALSE); + } + + p->p[p->len].x=x; + p->p[p->len].y=y; + p->len++; + + x+=xi[dir]; + y+=yi[dir]; + + if ((x==ox)&&(y==oy)) + return (TRUE); + else + return (FindLoopFrom(ox,oy,x,y,dir,p)); +} + + +int FindLoop(Path *p) +{ + int x,y; + + p->len=0; + + for(y=PITDEPTH-1;y>=0;y--) + for(x=0;xp[p->len].x=x; + p->p[p->len].y=y; + p->len++; + } +} + + +void GetSpecialPath(Path *p) +{ + p->len=0; + + if (game.y>0) + GetSpecialPathFromTile(pit.data[game.y-1][game.x],p); + + if (game.y<(PITDEPTH-1)) + GetSpecialPathFromTile(pit.data[game.y+1][game.x],p); + + if (game.x>0) + GetSpecialPathFromTile(pit.data[game.y][game.x-1],p); + + if (game.x<(PITWIDTH-1)) + GetSpecialPathFromTile(pit.data[game.y][game.x+1],p); +} + + +void DrawPath(Path *p) +{ + int f,r; + + SoundFX(PATH_FX); + + for(f=0;flen;f++) + { + pit.data[p->p[f].y][p->p[f].x]=PATH; + + for(r=0;r<5;r++) + AddParticle(PITX(p->p[f].x)+RND(SPRSIZE), + PITY(p->p[f].y)+RND(SPRSIZE), + RND(5)-2,RND(5)-2); + } +} + + +/* ------------------------------------------------------------------------- + SCORE UTILS + ------------------------------------------------------------------------- */ + +#define DSNO 3 +#define DSFADE (SLOW ? (10) : (20)) + +struct + { + char p[80]; + int sc; + int col; + int cnt; + } dispsc[DSNO]; + +void InitScores(void) +{ + int f; + + for(f=0;f=0;f--) + dispsc[f+1]=dispsc[f]; + + strcpy(dispsc[0].p,s); + dispsc[0].sc=sc; + dispsc[0].col=MELTOMAX-1; + dispsc[0].cnt=DSFADE; +} + + +void UpdateScores(void) +{ + int f; + char s[80]; + + for(f=0;fline[y][x])<=MELTOMAX)&&(c>MELTOMIN)) + { + xi=x+RND(4)-1; + yi=y+RND(5)-3; + + xi=MID(x1,xi,mx); + yi=MID(y1,yi,my); + + img->line[yi][xi]=c-1; + } +} + + +void DrawGameScreen(void) +{ + int x,y; + RLE_SPRITE *spr; + + clear(img); + + if (MODE==TETRIS_CLASSIC) + { + for(x=-1;x<=PITWIDTH;x++) + draw_rle_sprite(img,SPR(CLASSIC_WALL),PITX(x),PITY(PITDEPTH)); + + for(y=0;yx,s->y,s->z,&fx,&fy); + *x=(int)fx; + *y=(int)fy; +} + + +void RemoveStars(void) +{ + int x,y; + int f; + + for(f=0;f=MAXSTINC)) + st_inc_xi=-st_inc_xi; + + st_inc_y+=st_inc_yi; + + if ((st_inc_y<=-MAXSTINC)||(st_inc_y>=MAXSTINC)) + st_inc_yi=-st_inc_yi; + + st_inc_z+=st_inc_zi; + + if ((st_inc_z<=-MAXSTINC)||(st_inc_z>=MAXSTINC)) + st_inc_zi=-st_inc_zi; + } + + for(f=0;f(float)STARCUBEXY) + star[f].x-=STARCUBEXY*2; + + star[f].y+=st_inc_y; + + if (star[f].y<(float)-STARCUBEXY) + star[f].y+=STARCUBEXY*2; + + if (star[f].y>(float)STARCUBEXY) + star[f].y-=STARCUBEXY*2; + + star[f].z+=st_inc_z; + + if (star[f].z<=0.0) + star[f].z+=STARCUBEZ; + + if (star[f].z>(float)STARCUBEZ) + star[f].z-=STARCUBEZ; + + StarPos(star+f,&x,&y); + + if (getpixel(img,x,y)==BLACK) + putpixel(img,x,y,star[f].col); + } +} + + +/* ------------------------------------------------------------------------- + PARTCLE ROUTINES + ------------------------------------------------------------------------- */ +#define PARTICLELIFE 25 + +typedef struct Particle + { + int x,y; + int xi,yi; + int col; + int old_col; + int life; + struct Particle *next; + } Particle; + +Particle *part_head=NULL; +Particle *part_tail=NULL; +unsigned int part_cnt; + +void InitParticles(void) +{ + Particle *p; + + while(part_head) + { + p=part_head; + part_head=part_head->next; + free(p); + } + + part_head=NULL; + part_tail=NULL; +} + + +void RemoveParticles(void) +{ + Particle *p; + + p=part_head; + + while(p) + { + if (getpixel(img,p->x,p->y)==p->col) + putpixel(img,p->x,p->y,p->old_col); + p=p->next; + } +} + + +void UpdateParticles(void) +{ + Particle *p; + + /* May as well check, as there'll be more often no particles to do + */ + if (!(p=part_head)) + return; + + /* Looks naff, but it's better in seperate passes to make sure we don't + leave any aftifacts and make the particle routines entirely transparent. + Having said that it does clash with the starfield anyway! + */ + while(p) + { + if (getpixel(img,p->x,p->y)==p->col) + putpixel(img,p->x,p->y,p->old_col); + + p=p->next; + } + + p=part_head; + + while(p) + { + p->x+=p->xi; + p->y+=p->yi; + p->life--; + p->old_col=getpixel(img,p->x,p->y); + + p=p->next; + } + + p=part_head; + + while(p) + { + if (p->life) + putpixel(img,p->x,p->y,p->col); + + p=p->next; + } + + /* Remove dead particles from the list + */ + while((part_head)&&(part_head->life==0)) + { + p=part_head; + part_head=part_head->next; + free(p); + } + + if (!part_head) + part_tail=NULL; +} + + +void AddParticle(int x, int y, int xi, int yi) +{ + Particle *p; + + if (!(p=(Particle *)malloc(sizeof(Particle)))) + Error("malloc(Particle) failed"); + + if ((!xi)&&(!yi)) + xi=1; + + p->x=x; + p->y=y; + p->xi=xi; + p->yi=yi; + p->col=RND(PARTCOLMAX-PARTCOLMIN)+PARTCOLMIN; + p->life=PARTICLELIFE; + p->next=NULL; + + if (part_head) + { + part_tail->next=p; + part_tail=p; + } + else + { + part_head=p; + part_tail=p; + } +} + + +/* ------------------------------------------------------------------------- + DEFINE KEYS + ------------------------------------------------------------------------- */ + +void DefineKeys(void) +{ + static struct {int *key; char *prompt;} kdef[]= + { + {&KLEFT, "Left "}, + {&KRIGHT, "Right "}, + {&KROTATEL,"Rotate clockwise/up "}, + {&KROTATER,"Rotate clockwise/down "}, + {&KDROP, "Drop/fire "}, + {&KPAUSE, "Pause "}, + }; + int k; + int f; + int tx,kx,ty; + + used_keys[KLEFT]=FALSE; + used_keys[KRIGHT]=FALSE; + used_keys[KROTATER]=FALSE; + used_keys[KROTATEL]=FALSE; + used_keys[KDROP]=FALSE; + used_keys[KPAUSE]=FALSE; + + text_mode(0); + f=0; + clear(img); + clear_keybuf(); + + CENTRE("_____________",2,WHITE); + CENTRE("REDEFINE KEYS",0,WHITE); + + while(f<6) + { + tx=10; + kx=10+text_length(font8,kdef[f].prompt); + ty=50+f*16; + + textout(img,font8,kdef[f].prompt,tx,ty,YELLOW); + + Redraw(); + + while((k=GETKEY)==-1); + + *kdef[f].key=k; + + rectfill(img,kx,ty,319,ty+8,BLACK); + textout(img,font8,keystr[k],kx,ty,WHITE); + + if (used_keys[k]) + { + CENTRE("KEY ALREADY USED!",SCREEN_H-8,RED); + Redraw(); + } + else + { + CENTRE(" ",SCREEN_H-8,BLACK); + Redraw(); + used_keys[k]=TRUE; + while (key[k]); + clear_keybuf(); + f++; + } + } + + while(GETKEY!=KEY_SPACE) + { + CENTRE("PRESS SPACE",SCREEN_H-8,RND(16)+1); + Redraw(); + } + + clear_keybuf(); +} + + +/* ------------------------------------------------------------------------- + README FILE + ------------------------------------------------------------------------- */ + +void ReadMe(void) +{ + static char *readme[]= + { +# include "readme.h" + NULL + }; + + char *t; + int l=0; + int p; + int py; + int f; + int y; + + for(f=0;readme[f];f++) + l=f; + + p=l-2; + py=-8; + + while(GETKEY!=KEY_SPACE) + { + clear(img); + + text_mode(BLACK); + for(y=py,f=0;ypiece[RND(ps->no)]; + } + + game.next.ox=tetris_off[game.next_type][0].x; + game.next.oy=tetris_off[game.next_type][0].y; + } +} + + +void RotTetrisWirePiece(int dir) +{ + int x,y; + Piece p; + + if (game.is_special) + return; + + if (dir==LEFT) + { + game.rotate=ROL(game.rotate); + + for(x=0;x<4;x++) + for(y=0;y<4;y++) + p.data[x][3-y]=ROL_Piece(game.current.data[y][x]); + + p.ox=tetris_off[game.current_type][game.rotate].x; + p.oy=tetris_off[game.current_type][game.rotate].y; + } + else + { + game.rotate=ROR(game.rotate); + + for(x=0;x<4;x++) + for(y=0;y<4;y++) + p.data[3-x][y]=ROR_Piece(game.current.data[y][x]); + + p.ox=tetris_off[game.current_type][game.rotate].x; + p.oy=tetris_off[game.current_type][game.rotate].y; + } + + game.current=p; +} + + +/* ------------------------------------------------------------------------- + TETRIS CLASSIC SPECIFIC CODE + ------------------------------------------------------------------------- */ + +void GenTetrisClassicPiece(int special) +{ + static int type_map[NO_TETRIS_PIECE]={BLOCK1SPR, + BLOCK2SPR, + BLOCK3SPR, + BLOCK4SPR, + BLOCK5SPR, + BLOCK6SPR, + BLOCK7SPR}; + int x,y; + + game.current=game.next; + game.current_type=game.next_type; + game.is_special=game.next_is_special; + + game.x=PITWIDTH/2; + + if (game.is_special) + game.y=-1; + else + game.y=-tetris_height[game.current_type]+game.current.oy; + + game.rotate=0; + + game.next_is_special=FALSE; + + game.next_type=RND(NO_TETRIS_PIECE); + + for(x=0;x<4;x++) + for(y=0;y<4;y++) + if (tetris_map[game.next_type].data[y][x]==BLANK) + game.next.data[y][x]=BLANK; + else + game.next.data[y][x]=type_map[game.next_type]; + + game.next.ox=tetris_off[game.next_type][0].x; + game.next.oy=tetris_off[game.next_type][0].y; +} + + +void RotTetrisClassicPiece(int dir) +{ + int x,y; + Piece p; + + if (game.is_special) + return; + + if (dir==LEFT) + { + game.rotate=ROL(game.rotate); + + for(x=0;x<4;x++) + for(y=0;y<4;y++) + p.data[x][3-y]=game.current.data[y][x]; + + p.ox=tetris_off[game.current_type][game.rotate].x; + p.oy=tetris_off[game.current_type][game.rotate].y; + } + else + { + game.rotate=ROR(game.rotate); + + for(x=0;x<4;x++) + for(y=0;y<4;y++) + p.data[3-x][y]=game.current.data[y][x]; + + p.ox=tetris_off[game.current_type][game.rotate].x; + p.oy=tetris_off[game.current_type][game.rotate].y; + } + + game.current=p; +} + + +/* ------------------------------------------------------------------------- + COLUMNS SPECIFIC CODE + ------------------------------------------------------------------------- */ + +void GenColumnsWirePiece(int special) +{ + int x,y; + + game.current=game.next; + game.current_type=game.next_type; + game.is_special=game.next_is_special; + + game.x=PITWIDTH/2; + + if (game.is_special) + game.y=-1; + else + game.y=-3; + + game.rotate=0; + + game.next.ox=0; + game.next.oy=0; + + game.next_is_special=special; + + if (special) + { + for(x=0;x<4;x++) + for(y=0;y<4;y++) + if ((x)||(y)) + game.next.data[y][x]=BLANK; + else + game.next.data[y][x]=SPECIAL; + } + else + { + for(x=0;x<4;x++) + for(y=0;y<4;y++) + if ((x)||(y==3)) + game.next.data[y][x]=BLANK; + else + game.next.data[y][x]=RNDPIECE; + } +} + + +void RotColumnsWirePiece(int dir) +{ + int y,t; + + if (game.is_special) + return; + + if (dir==LEFT) + { + t=game.current.data[0][0]; + + for(y=0;y<2;y++) + game.current.data[y][0]=game.current.data[y+1][0]; + + game.current.data[2][0]=t; + } + else + { + t=game.current.data[2][0]; + + for(y=2;y>0;y--) + game.current.data[y][0]=game.current.data[y-1][0]; + + game.current.data[0][0]=t; + } +} + + +/* ------------------------------------------------------------------------- + PLAY GAME UTILS + ------------------------------------------------------------------------- */ + +int MoveOK(int x, int y) +{ + int cx,cy,nx,ny; + + for(cx=0;cx<4;cx++) + for(cy=0;cy<4;cy++) + if (game.current.data[cy][cx]!=BLANK) + { + nx=x+cx-game.current.ox; + ny=y+cy-game.current.oy; + + if ((nx<0)||(nx>=PITWIDTH)||(ny>=PITDEPTH)) + return(FALSE); + + if ((ny>=0)&&(pit.data[ny][nx]!=BLANK)) + return(FALSE); + } + + return(TRUE); +} + + +int AddAndCheckIsDead(int id) +{ + int cx,cy,nx,ny; + + if (game.is_special) + return(game.y<0); + else + for(cx=0;cx<4;cx++) + for(cy=0;cy<4;cy++) + if (game.current.data[cy][cx]!=BLANK) + { + nx=game.x+cx-game.current.ox; + ny=game.y+cy-game.current.oy; + + if ((nx<0)||(nx>=PITWIDTH)||(ny<0)||(ny>=PITDEPTH)) + return(TRUE); + + pit.data[ny][nx]=game.current.data[cy][cx]; + pit.id[ny][nx]=id; + } + + return(FALSE); +} + + +void UnglueID(int id) +{ + int x,y; + + for(x=0;x=0) + if (pit.data[y][x]!=BLANK) + return (pit.id[y][x]==0); + else + y--; + return(FALSE); +} + + +void CompressBlanks(void) +{ + int x,y,ny; + + for(x=0;x=(2<<16))||(scale<=(0x4000))) + scalei=-scalei; + + Redraw(); + } + + clear_keybuf(); + blit(workimg,img,0,0,0,0,SCREEN_W,SCREEN_H); + Redraw(); +} + + +/* ------------------------------------------------------------------------- + PATH AND SCORE CHECKERS + ------------------------------------------------------------------------- */ + +void CheckWirePaths(void) +{ + int sc; + Path path; + + game.score+=game.level; + + if (game.is_special) + { + GetSpecialPath(&path); + + /* Shouldn't be false anyway... + */ + if (path.len) + { + sc=(path.len*game.level); + game.score+=sc; + AddScore("SPECIAL",sc); + DrawPath(&path); + RedrawPit(); + DrawInfo(); + GameRedraw(); + CompressPath(); + RedrawPit(); + GameRedraw(); + CompressBlanks(); + RedrawPit(); + GameRedraw(); + } + } + + /* Check for paths + */ + while (FindPath(&path)) + { + sc=(path.len*game.level)*10; + game.score+=sc; + AddScore("CIRCUIT",sc); + DrawPath(&path); + RedrawPit(); + DrawInfo(); + GameRedraw(); + CompressPath(); + RedrawPit(); + GameRedraw(); + CompressBlanks(); + RedrawPit(); + GameRedraw(); + } + + /* Check for loops + */ + while (FindLoop(&path)) + { + sc=(path.len*game.level)*10; + game.score+=sc; + AddScore("LOOP",sc); + DrawPath(&path); + RedrawPit(); + DrawInfo(); + GameRedraw(); + CompressPath(); + RedrawPit(); + GameRedraw(); + CompressBlanks(); + RedrawPit(); + GameRedraw(); + } + +} + + +void CheckClassicPaths(void) +{ + Path path; + int x,y; + int rows; + int is_row; + int sc; + + game.score+=game.level; + + /* Check for rows + */ + rows=0; + path.len=0; + + for(y=0;y0) + { + sc=(game.level<<(rows-1))*10; + game.score+=sc; + switch(rows) + { + case 1: + AddScore("Single",sc); + break; + case 2: + AddScore("Double",sc); + break; + case 3: + AddScore("Triple",sc); + break; + case 4: + AddScore("TETRIS!",sc); + break; + } + + DrawPath(&path); + RedrawPit(); + DrawInfo(); + GameRedraw(); + CompressPath(); + RedrawPit(); + GameRedraw(); + } +} + + +/* ------------------------------------------------------------------------- + PLAY GAME + ------------------------------------------------------------------------- */ + +void PlayGame(void) +{ + struct {int rot_r,rot_l,left,right,drop;} bounce; + int mvctr; + int dead; + int no; + int id; + int k; + + bounce.rot_r=0; + bounce.rot_l=0; + bounce.left=0; + bounce.right=0; + bounce.drop=0; + + no=0; + id=1; + dead=FALSE; + mvctr=LEVELCTR(game.level); + + text_mode(0); + clear_keybuf(); + + if (MUSIC) + play_midi(game_midi,TRUE); + + if (MOTION) + InitStars(); + + InitParticles(); + + InitScores(); + + while(!dead) + { + /* Not a switch as some are variables now + */ + k=GETKEY; + + if (k==KQUIT) + dead=TRUE; + + if (k==KPAUSE) + DoPause(); + + if (k==KBORED) + { + game.level++; + DrawInfo(); + } + + /* See if it's time for the block to drop + */ + if (!(mvctr--)) + { + ErasePiece(); + + /* See if piece can move down + */ + if (MoveOK(game.x,game.y+1)) + { + SoundFX(CLICK_FX); + game.y++; + mvctr=LEVELCTR(game.level); + DrawPiece(); + GameRedraw(); + } + else + { + SoundFX(POP_FX); + + if (AddAndCheckIsDead(id++)) + { + /* If dead, setup exit of loop. + */ + dead=TRUE; + DrawPiece(); + } + else + { + /* Check for scoring and paths + */ + (*gamedef[MODE].do_paths)(); + + /* Generate new piece and reset counters + */ + (*gamedef[MODE].gen_piece) + ((id%gamedef[MODE].special_count)==0); + + bounce.rot_r=0; + bounce.rot_l=0; + bounce.left=0; + bounce.right=0; + bounce.drop=0; + + if (++no==(game.level*5)) + { + game.level++; + no=0; + } + + mvctr=LEVELCTR(game.level); + + RedrawPit(); + DrawInfo(); + GameRedraw(); + } + } + } + else + /* If it's not block dropping time, allow it to move + */ + { + ErasePiece(); + + /* Check left/right + */ + if ((key[KLEFT])&&(!bounce.left)) + { + bounce.left=BOUNCEVAL; + + if (MoveOK(game.x-1,game.y)) + game.x--; + } + else if ((key[KRIGHT])&&(!bounce.right)) + { + bounce.right=BOUNCEVAL; + + if (MoveOK(game.x+1,game.y)) + game.x++; + } + + if ((key[KDROP])&&(!bounce.drop)) + { + bounce.drop=BOUNCEVAL; + mvctr=0; + } + + if ((key[KROTATEL])&&(!bounce.rot_l)) + { + (*gamedef[MODE].rot_piece)(LEFT); + + if (MoveOK(game.x,game.y)) + bounce.rot_l=BOUNCEVAL; + else + (*gamedef[MODE].rot_piece)(RIGHT); + } + else if ((key[KROTATER])&&(!bounce.rot_r)) + { + (*gamedef[MODE].rot_piece)(RIGHT); + + if (MoveOK(game.x,game.y)) + bounce.rot_r=BOUNCEVAL; + else + (*gamedef[MODE].rot_piece)(LEFT); + } + + DrawPiece(); + GameRedraw(); + } + + /* Bounce keys + */ + KEYBOUNCE(KROTATEL,bounce.rot_l); + KEYBOUNCE(KROTATER,bounce.rot_r); + KEYBOUNCE(KLEFT,bounce.left); + KEYBOUNCE(KRIGHT,bounce.right); + KEYBOUNCE(KDROP,bounce.drop); + } + + if (MUSIC) + stop_midi(); + + SoundFX(GAMEOVER_FX); +} + + +/* ------------------------------------------------------------------------- + GAME OVER + ------------------------------------------------------------------------- */ + +void GameOver(void) +{ + int f; + int ctr; + int k; + + clear_keybuf(); + text_mode(-1); + + /* Copy game screen to work screen and do some stuff + */ + if (MOTION) + RemoveStars(); + + blit(img,workimg,0,0,0,0,SCREEN_W,SCREEN_H); + + f=0; + + if (SLOW) + ctr=20; + else + ctr=100; + + while((f<(SCREEN_H/2)-1)&&(!((k=GETKEY)==KDROP))&&(!(k==KEY_SPACE))) + { + textout_centre(workimg,font8,"game over",CX,SCREEN_H/2-4,RND(255)); + + stretch_blit(workimg,img,f,f,SCREEN_W-f*2,SCREEN_H-f*2, + 0,0,SCREEN_W,SCREEN_H); + if (SLOW) + { + if (ctr) + ctr--; + else + f+=8; + } + else + { + if (ctr) + ctr--; + else + f+=2; + } + + if (MOTION) + UpdateStars(); + + Redraw(); + } + +} + + +/* ------------------------------------------------------------------------- + ENTER HISCORE + ------------------------------------------------------------------------- */ + +void EnterHisc(void) +{ + static char hisc_let[]="ABCDEFGHIJKLMNOPQRSTUVXYZ. ~<>"; + + char s[80]; + int sc; + int f; + int sl; + int sbx; + int done; + int curs; + int len; + int spr; + int ctr; + int k; + + clear(img); + sl=strlen(hisc_let); + sbx=CX-text_length(font8,hisc_let)/2-3; + len=0; + done=FALSE; + curs=0; + spr=HISC_CURS1; + ctr=0; + + /* Work out which hiscore to use + */ + for(f=0,sc=-1;(fhisc[MODE][f].score) + sc=f; + + for(f=HISC-1;f>sc;f--) + hisc[MODE][f]=hisc[MODE][f-1]; + + strcpy(hisc[MODE][sc].name,""); + hisc[MODE][sc].level=LEVEL; + hisc[MODE][sc].score=game.score; + + if (MUSIC) + play_midi(score_midi,TRUE); + + text_mode(0); + + /* Go and do entry + */ + while(!done) + { + rectfill(img,0,0,SCREEN_W-1,50,BLACK); + + CENTRE(hisc_let,20,WHITE); + + draw_rle_sprite(img,SPR(spr),sbx+curs*8,17); + + if ((ctr++%10)==0) + if (++spr>HISC_CURS3) + spr=HISC_CURS1; + + CENTRE("ENTER YOUR INITIALS",CY,CYAN); + + k=GETKEY; + + if ((k==KLEFT)||(k==KEY_LEFT)) + { + SoundFX(CLICK_FX); + if (len==3) + { + if (curs==sl-2) + curs=sl-1; + else + curs=sl-2; + } + else + { + if (curs) + curs--; + else + curs=sl-1; + } + } + + else if((k==KRIGHT)||(k==KEY_RIGHT)) + { + SoundFX(CLICK_FX); + if (len==3) + { + if (curs==sl-2) + curs=sl-1; + else + curs=sl-2; + } + else + { + if (curs==(sl-1)) + curs=0; + else + curs++; + } + } + else if ((k==KDROP)||(k==KEY_SPACE)) + { + SoundFX(POP_FX); + switch(hisc_let[curs]) + { + case '<': + if (len) + { + len--; + hisc[MODE][sc].name[len]=0; + } + break; + + case '>': + done=TRUE; + break; + + default: + hisc[MODE][sc].name[len]=hisc_let[curs]; + hisc[MODE][sc].name[++len]=0; + + if (len==3) + curs=sl-1; + break; + } + } + + for(f=0;f strings array +README.H Arrayed version of this file for internal README + + + +------------------------------------------------------------------------------- +email: ianc@noddybox.demon.co.uk +URL: http://www.noddybox.demon.co.uk/ + +Please send any bug reports or incompatabilities to the above address. Run +'hardwire -v' to find version number when reporting bugs. TVM. + +You are free to do whatever you want with this code, aside from claim +responsibility for it and charge for it. + + +(c) 1998 noddybox diff --git a/hardwire/hwdat.h b/hardwire/hwdat.h new file mode 100644 index 0000000..33014b0 --- /dev/null +++ b/hardwire/hwdat.h @@ -0,0 +1,45 @@ +/* Allegro datafile object indexes, produced by grabber v3.0 */ +/* Datafile: c:\src\c\hardwire\v1.0\hardwire.dat */ +/* Date: Sat Feb 14 01:03:08 1998 */ +/* Do not hand edit! */ + +#define CLICK_FX 0 /* SAMP */ +#define GAMEMIDI 1 /* MIDI */ +#define GAMEOVER_FX 2 /* SAMP */ +#define GAMEQUIT_FX 3 /* SAMP */ +#define HWFONT 4 /* FONT */ +#define HWPAL 5 /* PAL */ +#define PATH_FX 6 /* SAMP */ +#define PAUSE_BMP 7 /* BMP */ +#define POP_FX 8 /* SAMP */ +#define SCOREMIDI 9 /* MIDI */ +#define SPRITE16_000 10 /* RLE */ +#define SPRITE16_001 11 /* RLE */ +#define SPRITE16_002 12 /* RLE */ +#define SPRITE8_000 13 /* RLE */ +#define SPRITE8_001 14 /* RLE */ +#define SPRITE8_002 15 /* RLE */ +#define SPRITE8_003 16 /* RLE */ +#define SPRITE8_004 17 /* RLE */ +#define SPRITE8_005 18 /* RLE */ +#define SPRITE8_006 19 /* RLE */ +#define SPRITE8_007 20 /* RLE */ +#define SPRITE8_008 21 /* RLE */ +#define SPRITE8_009 22 /* RLE */ +#define SPRITE8_010 23 /* RLE */ +#define SPRITE8_011 24 /* RLE */ +#define SPRITE8_012 25 /* RLE */ +#define SPRITE8_013 26 /* RLE */ +#define SPRITE8_014 27 /* RLE */ +#define SPRITE8_015 28 /* RLE */ +#define SPRITE8_016 29 /* RLE */ +#define SPRITE8_017 30 /* RLE */ +#define SPRITE8_018 31 /* RLE */ +#define SPRITE8_019 32 /* RLE */ +#define SPRITE8_020 33 /* RLE */ +#define SPRITE8_021 34 /* RLE */ +#define SPRITE8_022 35 /* RLE */ +#define SPRITE8_023 36 /* RLE */ +#define SPRITE8_024 37 /* RLE */ +#define TITLEMIDI 38 /* MIDI */ + diff --git a/hardwire/hwscores b/hardwire/hwscores new file mode 100644 index 0000000..bf2f52c Binary files /dev/null and b/hardwire/hwscores differ diff --git a/hardwire/keystr.h b/hardwire/keystr.h new file mode 100644 index 0000000..61f8398 --- /dev/null +++ b/hardwire/keystr.h @@ -0,0 +1,141 @@ +/* + General purpose mapping of keycodes to key presses +*/ + +#ifndef _KEYSTRH + +#define _KEYSTRH + +/* 128 string scan code table +*/ +static char *keystr[128]= + { + "Code 0", /* 0 */ + "Esc", /* KEY_ESC 1 */ + "1", /* KEY_1 2 */ + "2", /* KEY_2 3 */ + "3", /* KEY_3 4 */ + "4", /* KEY_4 5 */ + "5", /* KEY_5 6 */ + "6", /* KEY_6 7 */ + "7", /* KEY_7 8 */ + "8", /* KEY_8 9 */ + "9", /* KEY_9 10 */ + "0", /* KEY_0 11 */ + "-", /* KEY_MINUS 12 */ + "=", /* KEY_EQUALS 13 */ + "Backspace", /* KEY_BACKSPACE 14 */ + "Tab", /* KEY_TAB 15 */ + "Q", /* KEY_Q 16 */ + "W", /* KEY_W 17 */ + "E", /* KEY_E 18 */ + "R", /* KEY_R 19 */ + "T", /* KEY_T 20 */ + "Y", /* KEY_Y 21 */ + "U", /* KEY_U 22 */ + "I", /* KEY_I 23 */ + "O", /* KEY_O 24 */ + "P", /* KEY_P 25 */ + "[", /* KEY_OPENBRACE 26 */ + "]", /* KEY_CLOSEBRACE 27 */ + "Enter", /* KEY_ENTER 28 */ + "Left Ctrl", /* KEY_LCONTROL 29 */ + "A", /* KEY_A 30 */ + "S", /* KEY_S 31 */ + "D", /* KEY_D 32 */ + "F", /* KEY_F 33 */ + "G", /* KEY_G 34 */ + "H", /* KEY_H 35 */ + "J", /* KEY_J 36 */ + "K", /* KEY_K 37 */ + "L", /* KEY_L 38 */ + ";", /* KEY_COLON 39 */ + "'", /* KEY_QUOTE 40 */ + "`", /* KEY_TILDE 41 */ + "Left Shift", /* KEY_LSHIFT 42 */ + "#", /* KEY_BACKSLASH 43 */ + "Z", /* KEY_Z 44 */ + "X", /* KEY_X 45 */ + "C", /* KEY_C 46 */ + "V", /* KEY_V 47 */ + "B", /* KEY_B 48 */ + "N", /* KEY_N 49 */ + "M", /* KEY_M 50 */ + ",", /* KEY_COMMA 51 */ + ".", /* KEY_STOP 52 */ + "/", /* KEY_SLASH 53 */ + "Right Shift", /* KEY_RSHIFT 54 */ + "KP *", /* KEY_ASTERISK 55 */ + "Alt", /* KEY_ALT 56 */ + "Space", /* KEY_SPACE 57 */ + "Caps Lock", /* KEY_CAPSLOCK 58 */ + "F1", /* KEY_F1 59 */ + "F2", /* KEY_F2 60 */ + "F3", /* KEY_F3 61 */ + "F4", /* KEY_F4 62 */ + "F5", /* KEY_F5 63 */ + "F6", /* KEY_F6 64 */ + "F7", /* KEY_F7 65 */ + "F8", /* KEY_F8 66 */ + "F9", /* KEY_F9 67 */ + "F10", /* KEY_F10 68 */ + "Num Lock", /* KEY_NUMLOCK 69 */ + "Scroll Lock", /* KEY_SCRLOCK 70 */ + "Home", /* KEY_HOME 71 */ + "Up", /* KEY_UP 72 */ + "Page Up", /* KEY_PGUP 73 */ + "KP -", /* KEY_MINUS_PAD 74 */ + "Left", /* KEY_LEFT 75 */ + "KP 5", /* KEY_5_PAD 76 */ + "Right", /* KEY_RIGHT 77 */ + "KP +", /* KEY_PLUS_PAD 78 */ + "End", /* KEY_END 79 */ + "Down", /* KEY_DOWN 80 */ + "Page Down", /* KEY_PGDN 81 */ + "Ins", /* KEY_INSERT 82 */ + "Del", /* KEY_DEL 83 */ + "Prt Scr", /* KEY_PRTSCR 84 */ + "F11", /* KEY_F11 87 */ + "F12", /* KEY_F12 88 */ + "Code 89", /* 89 */ + "Code 90", /* 90 */ + "Left Window", /* KEY_LWIN 91 */ + "Right Window", /* KEY_RWIN 92 */ + "Menu", /* KEY_MENU 93 */ + "Code 94", /* 94 */ + "Code 95", /* 95 */ + "Code 96", /* 96 */ + "Code 97", /* 97 */ + "Code 98", /* 98 */ + "Code 99", /* 99 */ + "Pad", /* KEY_PAD 100 */ + "Code 101", /* 101 */ + "Code 102", /* 102 */ + "Code 103", /* 103 */ + "Code 104", /* 104 */ + "Code 105", /* 105 */ + "Code 106", /* 106 */ + "Code 107", /* 107 */ + "Code 108", /* 108 */ + "Code 109", /* 109 */ + "Code 110", /* 110 */ + "Code 111", /* 111 */ + "Code 112", /* 112 */ + "Code 113", /* 113 */ + "Code 114", /* 114 */ + "Code 115", /* 115 */ + "Code 116", /* 116 */ + "Code 117", /* 117 */ + "Code 118", /* 118 */ + "Code 119", /* 119 */ + "Right Ctrl", /* KEY_RCONTROL 120 */ + "Alt Gr", /* KEY_ALTGR 121 */ + "KP /", /* KEY_SLASH2 122 */ + "Pause", /* KEY_PAUSE 123 */ + "Code 124", /* 124 */ + "Code 125", /* 125 */ + "Code 126", /* 126 */ + "Code 127", /* 127 */ + }; + +#endif diff --git a/hardwire/pathway.wav b/hardwire/pathway.wav new file mode 100644 index 0000000..ed14b28 Binary files /dev/null and b/hardwire/pathway.wav differ diff --git a/hardwire/pause_bmp.pcx b/hardwire/pause_bmp.pcx new file mode 100644 index 0000000..e4b1c16 Binary files /dev/null and b/hardwire/pause_bmp.pcx differ diff --git a/hardwire/piecemap.h b/hardwire/piecemap.h new file mode 100644 index 0000000..1844663 --- /dev/null +++ b/hardwire/piecemap.h @@ -0,0 +1,222 @@ + +/* + Define TETRIS mode piece maps + + Object types : + + SPECIAL + CROSS + UPDOWN + ACROSS + LEFTDOWN + RIGHTDOWN + LEFTUP + RIGHTUP + BLANK + +*/ + +#define NO_TETRIS_PIECE 7 + +#define NO_PIECE_SET 11 + +#define TOP_PS 0 +#define BOT_PS 1 +#define LFT_PS 2 +#define RGT_PS 3 +#define L_R_PS 4 +#define U_D_PS 5 +#define CRS_PS 6 +#define L_U_PS 7 +#define L_D_PS 8 +#define R_U_PS 9 +#define R_D_PS 10 + +PieceSet piece_set[NO_PIECE_SET]= + { + { /* TOP_PS */ + 4, + {UPDOWN,CROSS,LEFTDOWN,RIGHTDOWN,BLANK} + }, + + { /* BOT_PS */ + 4, + {UPDOWN,CROSS,LEFTUP,RIGHTUP,BLANK} + }, + + { /* LFT_PS */ + 4, + {ACROSS,CROSS,RIGHTDOWN,RIGHTUP,BLANK} + }, + + { /* RGT_PS */ + 4, + {ACROSS,CROSS,LEFTDOWN,LEFTUP,BLANK} + }, + + { /* L_R_PS */ + 2, + {ACROSS,CROSS,BLANK,BLANK,BLANK} + }, + + { /* U_D_PS */ + 2, + {UPDOWN,CROSS,BLANK,BLANK,BLANK} + }, + + { /* CRS_PS */ + 1, + {CROSS,BLANK,BLANK,BLANK,BLANK} + }, + + { /* L_U_PS */ + 2, + {LEFTUP,CROSS,BLANK,BLANK,BLANK} + }, + + { /* L_D_PS */ + 2, + {LEFTDOWN,CROSS,BLANK,BLANK,BLANK} + }, + + { /* R_U_PS */ + 2, + {RIGHTUP,CROSS,BLANK,BLANK,BLANK} + }, + + { /* R_D_PS */ + 2, + {RIGHTDOWN,CROSS,BLANK,BLANK,BLANK} + } + }; + + +Piece tetris_map[NO_TETRIS_PIECE]= + { + { /* PIECE 1 - LONG */ + 0,0, + { + {BLANK, TOP_PS, BLANK, BLANK}, + {BLANK, U_D_PS, BLANK, BLANK}, + {BLANK, U_D_PS, BLANK, BLANK}, + {BLANK, BOT_PS, BLANK, BLANK}, + } + }, + { /* PIECE 2 - BOX */ + 0,0, + { + {CRS_PS, CRS_PS, BLANK, BLANK}, + {CRS_PS, CRS_PS, BLANK, BLANK}, + {BLANK, BLANK, BLANK, BLANK}, + {BLANK, BLANK, BLANK, BLANK}, + } + }, + { /* PIECE 3 - TEE */ + 0,0, + { + {BLANK, TOP_PS, BLANK, BLANK}, + {LFT_PS, CRS_PS, RGT_PS, BLANK}, + {BLANK, BLANK, BLANK, BLANK}, + {BLANK, BLANK, BLANK, BLANK}, + } + }, + { /* PIECE 4 - LEFT DOGLEG */ + 0,0, + { + {LFT_PS, L_D_PS, BLANK, BLANK}, + {BLANK, U_D_PS, BLANK, BLANK}, + {BLANK, U_D_PS, BLANK, BLANK}, + {BLANK, BLANK, BLANK, BLANK}, + } + }, + { /* PIECE 5 - RIGHT DOGLEG */ + 0,0, + { + {BLANK, R_D_PS, RGT_PS, BLANK}, + {BLANK, U_D_PS, BLANK, BLANK}, + {BLANK, U_D_PS, BLANK, BLANK}, + {BLANK, BLANK, BLANK, BLANK}, + } + }, + { /* PIECE 6 - LEFT S */ + 0,0, + { + {LFT_PS, L_D_PS, BLANK, BLANK}, + {BLANK, R_U_PS, RGT_PS, BLANK}, + {BLANK, BLANK, BLANK, BLANK}, + {BLANK, BLANK, BLANK, BLANK}, + } + }, + { /* PIECE 7 - RIGHT S */ + 0,0, + { + {BLANK, R_D_PS, RGT_PS, BLANK}, + {LFT_PS, L_U_PS, BLANK, BLANK}, + {BLANK, BLANK, BLANK, BLANK}, + {BLANK, BLANK, BLANK, BLANK}, + } + } + }; + + +struct + { + int x,y; + } tetris_off[NO_TETRIS_PIECE][4]= + { + { /* PIECE 1 - LONG */ + {1,1}, + {1,1}, + {2,1}, + {1,2} + }, + { /* PIECE 2 - BOX */ + {0,0}, + {2,0}, + {2,2}, + {0,2} + }, + { /* PIECE 3 - TEE */ + {1,1}, + {2,1}, + {2,2}, + {1,2} + }, + { /* PIECE 4 - LEFT DOGLEG */ + {1,1}, + {2,1}, + {2,2}, + {1,2} + }, + { /* PIECE 5 - RIGHT DOGLEG */ + {1,1}, + {2,1}, + {2,2}, + {1,2} + }, + { /* PIECE 6 - LEFT S */ + {1,1}, + {2,1}, + {2,2}, + {1,2} + }, + { /* PIECE 7 - RIGHT S */ + {1,1}, + {2,1}, + {2,2}, + {1,2} + } + }; + + + +int tetris_height[NO_TETRIS_PIECE]= + { + 4, /* PIECE 1 - LONG */ + 2, /* PIECE 2 - BOX */ + 2, /* PIECE 3 - TEE */ + 3, /* PIECE 4 - LEFT DOGLEG */ + 3, /* PIECE 5 - RIGHT DOGLEG */ + 2, /* PIECE 6 - LEFT S */ + 2 /* PIECE 7 - RIGHT S */ + }; diff --git a/hardwire/popsound.wav b/hardwire/popsound.wav new file mode 100644 index 0000000..e9a4523 Binary files /dev/null and b/hardwire/popsound.wav differ diff --git a/hardwire/readme.h b/hardwire/readme.h new file mode 100644 index 0000000..5a49d12 --- /dev/null +++ b/hardwire/readme.h @@ -0,0 +1,109 @@ +/* + 1234567890123456789012345678901234567890 +*/ + +"@_____________________________________", +"", +"@HARDWIRE", +"@Version 1.0", +"@", +"@Presented by noddybox '98", +"@Written using DJGPP and Allegro 3.0", +"@", +"@Allegro written by Shawn Hargreaves", +"", +"@_____________________________________", +"", +"", +"@RULES FOR WIRE MODE", +"", +"Blocks (or columns) will descend the", +"screen in the time honoured tradition,", +"but with the slight twist of being made", +"up of pieces of circuit board.", +"", +"Rather than making complete horizontal", +"lines you have to make connections", +"between any of the connectors lining", +"the sides and bottom of the pit.", +"", +"A complete connection will cause the", +"circuitry to burn up, making more room", +"for the never ending supply from", +"upstairs.", +"", +"Likewise makeing a completely enclosed", +"loop will induce a current that destroys", +"those pieces of circuit.", +"", +"Every so often a special block will fall", +"that once layed in place will blow up", +"all circuit pieces that match the ones", +"surrounding it.", +"", +"If the blocks (even a special) overflow", +"the top of the pit, it's game over and", +"back to the dole office.", +"", +"", +"@RULES FOR TETRIS CLASSIC MODE", +"", +"Blocks drop down into a pit.", +"", +"Complete horizontal line disappear,", +"causing the lines above to move down.", +"", +"The game is over once the pit overflows.", +"", +"I'm sure you've heard of the idea...", +"", +"", +"", +"@KEYS ON TITLE SCREEN", +"", +"F1 Change game mode ", +"F2 Change game level ", +"F3 Alter pit width ", +"F4 Toggle motion sickness ", +"F5 Toggle music ", +"I View instructions ", +"R Redefine keys ", +"SPACE Play game ", +"ESC Quit back to DOS ", +"", +"", +"", +"@DEFAULT KEYS DURING GAME", +"", +"RIGHT Move block right ", +"LEFT Move block left ", +"UP Rotate block clockwise/up ", +"DOWN Rotate block anti-clockwise/down", +"SPACE Drop block ", +"P Pause ", +"F9 I'm bored. Next level please. ", +"ESC Give up ", +"", +"Movement, Rotate, Drop and Pause keys", +"can be redefined from the title page", +"", +"", +"@HINTS", +"", +"THINK! HARD!!!", +"", +"", +"@-------------------------------------", +"@email: ianc@noddybox.demon.co.uk", +"@URL: http://www.noddybox.demon.co.uk/", +"", +"You are free to do whatever you want", +"with this code, aside from claim", +"responsibility for it and charge for it", +"", +"", +"@(c) 1998 noddybox", +"", +"", +"", +"", diff --git a/hardwire/sprite16.pds b/hardwire/sprite16.pds new file mode 100644 index 0000000..be2341a Binary files /dev/null and b/hardwire/sprite16.pds differ diff --git a/hardwire/sprite8.pds b/hardwire/sprite8.pds new file mode 100644 index 0000000..a13ec4e Binary files /dev/null and b/hardwire/sprite8.pds differ -- cgit v1.2.3