# This is a shell archive. Save it in a file, remove anything before # this line, and then unpack it by entering "sh file". Note, it may # create directories; files and directories will be owned by you and # have default permissions. # # This archive contains: # # Makefile # tetris.c # drawing.c # motion.c # tetris.h # echo x - Makefile sed 's/^X//' >Makefile << 'END-of-Makefile' X# X# Copyright (C) 1993 Fariborz ``Skip'' Tavakkolian X# X# $Id: Makefile,v 1.4 93/06/13 12:27:30 fst Exp $ X# X# Description: X# X# $Log: Makefile,v $ X# Revision 1.4 93/06/13 12:27:30 fst X# Added the lint stuff X# X# Revision 1.3 93/06/06 11:05:53 fst X# Changed CFLAGS to -g for debugging by dmdpi X# X# Revision 1.2 93/06/05 22:10:42 fst X# Changed the RCS ``Header'' with ``Id''. X# X# Revision 1.1 93/06/05 22:03:05 fst X# Initial revision X# X XSOURCES = tetris.c drawing.c motion.c XOBJECTS = $(SOURCES:.c=.o) X XTARGET = tetris.m XTARGET_LINT = tetris.lint XCC=dmdcc XCFLAGS=-g X X$(TARGET_LINT): $(SOURCES) X lint -I$(DMD)/include $(SOURCES) X X$(TARGET): $(OBJECTS) X $(CC) -o $(TARGET) $(OBJECTS) X Xdmdtet.shar: X shar Makefile $(SOURCES) tetris.h > dmdtet.shar X Xtetris.o: tetris.h Xmotion.o: tetris.h END-of-Makefile echo x - tetris.c sed 's/^X//' >tetris.c << 'END-of-tetris.c' X/**********************************************************/ X/* */ X/* Copyright (C) 1993 Fariborz ``Skip'' Tavakkolian */ X/* */ X/**********************************************************/ X Xstatic char *RCSid = "$Id: tetris.c,v 1.4 93/06/13 12:28:25 fst Exp $"; X X/* X * Description: X * X * $Log: tetris.c,v $ X * Revision 1.4 93/06/13 12:28:25 fst X * Added casts to satisfy link. X * X * Revision 1.3 93/06/06 11:07:13 fst X * Added the current game piece to the arguments passed to Collapse_Full_Rows X * to allow for checking of only those rows which are effected by the last X * move. X * X * Revision 1.2 93/06/05 22:11:16 fst X * Changed the RCS ``Header'' with ``Id''. X * X * Revision 1.1 93/06/05 22:03:58 fst X * Initial revision X * X */ X X#include X#include X#include X#include X#include "tetris.h" X X/* Library Routines and associated manual page. */ Xvoid bitblt(); Xvoid lprintf(); Xvoid sleep(); XPoint sPtCurrent(); Xint wait(); X X X/* tetris functions */ Xextern char *Gen_Menu_Items(); X X/* local variables */ Xstatic int running = 0; Xstatic int new_piece = 1; Xstatic int fall_speed = FALL_SPEED; Xstatic int p_count = 0; Xstatic int score = 0; X X#define ADJUST_SPEED() \ X{ \ X if (score > 50) \ X { \ X fall_speed = FALL_SPEED - (score / 25); \ X fall_speed = (fall_speed <= 10) ? 10 : fall_speed;\ X } \ X} X XMenu top_level_menu = X{ X 0, 0, 0, Gen_Menu_Items, X}; X Xchar *Gen_Menu_Items(i) X int i; X{ X switch (i) X { X case 0: X return "New Game"; X case 1: X return ((running) ? "Stop" : "Start"); X case 2: X return "Quit"; X default: X return NULL; X } X} X X#define WAIT_TIME 5 X XGamePiece *cgp, *ngp; X X XDo_First_Move() X{ X int middle_x; X X if (! running) X return 0; X X middle_x = BOARD_WIDTH/2 - X (cgp->gmap_arr[cgp->cur]->rect.corner.x - X cgp->gmap_arr[cgp->cur]->rect.origin.x)/2; X X game_board.curpt = fPt(middle_x, 0); X /* X fprintf(stderr, "Do_First_Move(): game_board.curpt is (%d,%d)\n", X game_board.curpt.x, game_board.curpt.y X ); X */ X if (! Move_Piece(cgp, FirstMove)) /* first move and wont fit */ X { X return 0; X } X X return 1; X} X Xstatic Point scoreloc, countloc; XPoint nploc; X Xvoid Show_Score() X{ X char buff[16]; X X /* itoa((long) score, buff); */ X Sprintf(buff, "%4d", score); X string(&largefont, buff, &display, add(Drect.origin, scoreloc), F_STORE); X X /* itoa((long) p_count, buff); */ X Sprintf(buff, "%4d", p_count); X string(&largefont, buff, &display, add(Drect.origin, countloc), F_STORE); X} X Xvoid New_Game() X{ X Point q; X X Clear_Game_Board(); X Draw_Window(); X q = add(Drect.origin, Srect.origin); X scoreloc = string(&largefont, " SCORE ", &display, q, F_STORE); X scoreloc = sub(scoreloc, Drect.origin); X X q = add(q, Pt(0, FONTHEIGHT(largefont))); X countloc = string(&largefont, " PIECES ", &display, q, F_STORE); X countloc = sub(countloc, Drect.origin); X X q = add(q, Pt(0, FONTHEIGHT(largefont))); X nploc = string(&largefont, " NEXT PIECE ", &display, q, F_STORE); X nploc = sub(nploc, Drect.origin); X X ngp = Get_Next_Piece(); X new_piece = 1; X running = 0; X p_count = 0; X score = 0; X fall_speed = FALL_SPEED; X X Show_Score(); X} X Xvoid Collapse_Full_Rows() X{ X int n; X X if (n = Show_Full_Rows(cgp)) X Clear_Full_Rows(n, cgp); X} X Xmain() X{ X extern GamePiece *Get_Next_Piece(); X int bonus; X X Initialize(); X /* cache((char *) 0, A_NO_BOOT & ~A_SHARED); */ X Reshape_Window(); X X request(MOUSE); X New_Game(); X X while (1) X { X alarm(0); X request(MOUSE); X X while (! running) X { X wait(MOUSE); X if ((own() & MOUSE) && button2()) X { X int m = menuhit(&top_level_menu, 2); X switch (m) X { X default: X break; X case 0: X New_Game(); X break; X X case 1: X running = 1; X break; X X case 2: X exit(); X } X } X } X X X alarm(fall_speed); X request(MOUSE|KBD|ALARM); X X while (running) X { X Show_Score(); X if (new_piece) X { X alarm(0); X Collapse_Full_Rows(); X Clear_Shadow_Area(); X cgp = ngp; X ngp = Get_Next_Piece(); X cgp->cur = 0; X Show_Next_Piece(ngp); X X if (! Do_First_Move()) X { X running = 0; X new_piece = 1; X break; X } X p_count++; X new_piece = 0; X ADJUST_SPEED(); X alarm(fall_speed); X } X X wait(ALARM|MOUSE|KBD); X if ((own() & MOUSE) && button2()) X { X int m = menuhit(&top_level_menu, 2); X switch (m) X { X default: X break; X case 0: X New_Game(); X break; X X case 1: X running = 0; X break; X X case 2: X exit(); X } X X if (! running) X break; X } X X if (own() & ALARM) X { X alarm(0); X if (Move_Piece(cgp, Down) < 0) /* resting */ X { X score += cgp->score[cgp->cur]; X new_piece = 1; X continue; X } X X alarm(fall_speed); X } X X if (own() & KBD) X { X switch (kbdchar()) X { X default: X break; X X case 0xE2: /* right arrow */ X case 'l': X (void) Move_Piece(cgp, Right); X break; X X case 0xE3: /* left arrow */ X case 'h': X (void) Move_Piece(cgp, Left); X break; X X case 0xE4: /* home key */ X case 'j': X (void) Move_Piece(cgp, Clockwise); X break; X X case 0xE0: /* up arrow */ X case 'k': X (void) Move_Piece(cgp, CounterClockwise); X break; X X case 0xE1: /* down arrow */ X case ' ': X bonus = BOARD_HEIGHT - game_board.curpt.y; X (void) Move_Piece(cgp, Fall); X score += cgp->score[cgp->cur]; X score += bonus/2; /* give them half the fall distance */ X X /* after a fall, the piece is always resting */ X new_piece = 1; X break; X } X } X } X } X} X END-of-tetris.c echo x - drawing.c sed 's/^X//' >drawing.c << 'END-of-drawing.c' X/**********************************************************/ X/* */ X/* Copyright (C) 1993 Fariborz ``Skip'' Tavakkoian */ X/* */ X/**********************************************************/ X Xstatic char *RCSid = "$Id: drawing.c,v 1.3 93/06/06 11:11:38 fst Exp $"; X X/* X * Description: X * X * $Log: drawing.c,v $ X * Revision 1.3 93/06/06 11:11:38 fst X * Added the current game piece to argument list for Show_Full_Rows and X * Clear_Full_Rows. The two functions were changed to check those rows X * which are effected by the last of move of the current game piece. X * X * Revision 1.2 93/06/05 22:11:32 fst X * Changed the RCS ``Header'' with ``Id''. X * X * Revision 1.1 93/06/05 22:05:24 fst X * Initial revision X * X */ X X#include X#include X#include "tetris.h" X XTexture16 *colors[] = X{ X &T_darkgrey, X (Texture16*) 0, /* black */ X (Texture16*) 0, /* grey */ X (Texture16*) 0, /* grey2 */ X (Texture16*) 0, /* checks */ X (Texture16*) 0, /* background */ X &T_lightgrey, X (Texture16*) 0, X}; X XTexture16 hashmark = X{ X 0x318C, 0x6318, 0xC631, 0x8C63, X 0x18C6, 0x318C, 0x6318, 0xC631, X 0x8C63, 0x18C6, 0x318C, 0x6318, X 0xC631, 0x8C63, 0x18C6, 0x318C, X}; X Xstatic Word brick_bits[] = X{ X 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, X 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, X 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE, X 0xFFFE, 0xFFFE, 0xFFFE, 0x0000, X}; X Xstatic Bitmap a_brick = X{ X (Word *) brick_bits, X 1, X { {0, 0}, {16, 16} }, X (char *) 0, X}; X Xstatic Word shadow_bits[64]; Xstatic Bitmap shadow = X{ X (Word *) shadow_bits, X 1, /* this changes at runtime */ X { {0, 0}, {64, 16} }, /* so does corner.x */ X (char *) 0, X}; X Xstatic Word game_bits[BOARD_HEIGHT]; Xstatic Bitmap game_bitmap = X{ X (Word *) game_bits, X 1, X { {0, 0}, {BOARD_WIDTH+1, BOARD_HEIGHT+1} }, X (char *) 0, X}; X XBoard game_board = X{ X { 0, 0, }, X &game_bitmap, X}; X X/* ================= J - piece ================ */ X X/* ------------------- North ----------------- */ Xstatic Word xJ_n[] = X{ X 0x4000, X 0x4000, X 0xC000, X}; X Xstatic Bitmap xJ_north = X{ X (Word *) xJ_n, X 1, X { {0, 0}, {2, 3} }, X (char *) 0, X}; X Xstatic Word J_n[96]; X Xstatic Bitmap J_north = X{ X (Word *) J_n, X 2, X { {0, 0}, {32, 48} }, X (char *) 0, X}; X X/* ------------------ East ----------------- */ Xstatic Word xJ_e[] = X{ X 0x8000, X 0xE000, X}; X Xstatic Bitmap xJ_east = X{ X (Word *) xJ_e, X 1, X { {0, 0}, {3, 2} }, X (char *) 0, X}; X Xstatic Word J_e[96]; X Xstatic Bitmap J_east = X{ X (Word*) J_e, X 3, X { {0, 0}, {48, 32} }, X (char *) 0, X}; X X/* ------------------- South ------------------ */ Xstatic Word xJ_s[] = X{ X 0xC000, X 0x8000, X 0x8000, X}; X Xstatic Bitmap xJ_south = X{ X (Word *) xJ_s, X 1, X { {0, 0}, {2, 3} }, X (char *) 0, X}; X Xstatic Word J_s[96]; X Xstatic Bitmap J_south = X{ X (Word*) J_s, X 2, X { {0, 0}, {32, 48} }, X (char *) 0, X}; X X X/* ---------------------- West ------------------ */ Xstatic Word xJ_w[] = X{ X 0xE000, X 0x2000, X}; X Xstatic Bitmap xJ_west = X{ X (Word *) xJ_w, X 1, X { {0, 0}, {3, 2} }, X (char *) 0, X}; X Xstatic Word J_w[96]; X Xstatic Bitmap J_west = X{ X (Word*) J_w, X 3, X { {0, 0}, {48, 32} }, X (char *) 0, X}; X X/* =================== L - piece ================== */ X X/* --------------------- North ------------------ */ Xstatic Word xL_n[] = X{ X 0x8000, X 0x8000, X 0xC000, X}; X Xstatic Bitmap xL_north = X{ X (Word *) xL_n, X 1, X { {0, 0}, {2, 3} }, X (char *) 0, X}; X Xstatic Word L_n[96]; X Xstatic Bitmap L_north = X{ X (Word*) L_n, X 2, X { {0, 0}, {32, 48} }, X (char *) 0, X}; X X/* --------------------- East ------------------ */ Xstatic Word xL_e[] = X{ X 0xE000, X 0x8000, X}; X Xstatic Bitmap xL_east = X{ X (Word *) xL_e, X 1, X { {0, 0}, {3, 2} }, X (char *) 0, X}; X Xstatic Word L_e[96]; X Xstatic Bitmap L_east = X{ X (Word*) L_e, X 3, X { {0, 0}, {48, 32} }, X (char *) 0, X}; X X/* -------------------- South ------------------ */ Xstatic Word xL_s[] = X{ X 0xC000, X 0x4000, X 0x4000, X}; X Xstatic Bitmap xL_south = X{ X (Word *) xL_s, X 1, X { {0, 0}, {2, 3} }, X (char *) 0, X}; X Xstatic Word L_s[96]; X Xstatic Bitmap L_south = X{ X (Word*) L_s, X 2, X { {0, 0}, {32, 48} }, X (char *) 0, X}; X X/* --------------------- West ------------------ */ Xstatic Word xL_w[] = X{ X 0x2000, X 0xE000, X}; X Xstatic Bitmap xL_west = X{ X (Word *) xL_w, X 1, X { {0, 0}, {3, 2} }, X (char *) 0, X}; X Xstatic Word L_w[96]; X Xstatic Bitmap L_west = X{ X (Word*) L_w, X 3, X { {0, 0}, {48, 32} }, X (char *) 0, X}; X X/* ================= S - peices ===================== */ X X/* ------------------ North / South ----------------- */ Xstatic Word xS_n[] = X{ X 0x8000, X 0xC000, X 0x4000, X}; X Xstatic Bitmap xS_north = X{ X (Word *) xS_n, X 1, X { {0, 0}, {2, 3} }, X (char *) 0, X}; X Xstatic Word S_n[96]; X Xstatic Bitmap S_north = X{ X (Word *) S_n, X 2, X { {0, 0}, {32, 48} }, X (char *) 0, X}; X X/* ----------------- East / West ------------------ */ Xstatic Word xS_e[] = X{ X 0x6000, X 0xC000, X}; X Xstatic Bitmap xS_east = X{ X (Word *) xS_e, X 1, X { {0, 0}, {3, 2} }, X (char *) 0, X}; X Xstatic Word S_e[96]; X Xstatic Bitmap S_east = X{ X (Word *) S_e, X 3, X { {0, 0}, {48, 32} }, X (char *) 0, X}; X X/* =========================== Z - piece ======================= */ X X/* -------------------------- North/South ---------------------- */ Xstatic Word xZ_n[] = X{ X 0x4000, X 0xC000, X 0x8000, X}; X Xstatic Bitmap xZ_north = X{ X (Word *) xZ_n, X 1, X { {0, 0}, {2, 3} }, X (char *) 0, X}; X Xstatic Word Z_n[96]; Xstatic Bitmap Z_north = X{ X (Word *) Z_n, X 2, X { {0, 0}, {32, 48} }, X (char *) 0, X}; X X/* -------------------------- East/West ---------------------- */ Xstatic Word xZ_e[] = X{ X 0xC000, X 0x6000, X}; X Xstatic Bitmap xZ_east = X{ X (Word *) xZ_e, X 1, X { {0, 0}, {3, 2} }, X (char *) 0, X}; X Xstatic Word Z_e[96]; Xstatic Bitmap Z_east = X{ X (Word *) Z_e, X 3, X { {0, 0}, {48, 32} }, X (char *) 0, X}; X X/* ============================ T - piece ======================= */ X/* ---------------- North -------------- */ Xstatic Word xT_n[] = X{ X 0x8000, X 0xC000, X 0x8000, X}; X Xstatic Bitmap xT_north = X{ X (Word *) xT_n, X 1, X { {0, 0}, {2, 3} }, X (char *) 0, X}; X Xstatic Word T_n[96]; Xstatic Bitmap T_north = X{ X (Word *) T_n, X 2, X { {0, 0}, {32, 48} }, X (char *) 0, X}; X X/* ------------------ East ----------------- */ Xstatic Word xT_e[] = X{ X 0xE000, X 0x4000, X}; Xstatic Bitmap xT_east = X{ X (Word *) xT_e, X 1, X { {0, 0}, {3, 2} }, X (char *) 0, X}; X Xstatic Word T_e[96]; Xstatic Bitmap T_east = X{ X (Word *) T_e, X 3, X { {0, 0}, {48, 32} }, X (char *) 0, X}; X X/* ------------------ South ---------------- */ Xstatic Word xT_s[] = X{ X 0x4000, X 0xC000, X 0x4000, X}; X Xstatic Bitmap xT_south = X{ X (Word *) xT_s, X 1, X { {0, 0}, {2, 3} }, X (char *) 0, X}; X Xstatic Word T_s[96]; Xstatic Bitmap T_south = X{ X (Word *) T_s, X 2, X { {0, 0}, {32, 48} }, X (char *) 0, X}; X X/* -------------------- West ----------------- */ Xstatic Word xT_w[] = X{ X 0x4000, X 0xE000, X}; Xstatic Bitmap xT_west = X{ X (Word *) xT_w, X 1, X { {0, 0}, {3, 2} }, X (char *) 0, X}; X Xstatic Word T_w[96]; Xstatic Bitmap T_west = X{ X (Word *) T_w, X 3, X { {0, 0}, {48, 32} }, X (char *) 0, X}; X X/* ========================= I - piece ===================== */ X X/* ------------------------- North / South ----------------- */ Xstatic Word xI_n[] = X{ X 0x8000, X 0x8000, X 0x8000, X 0x8000, X}; Xstatic Bitmap xI_north = X{ X (Word *) xI_n, X 1, X { {0, 0}, {1, 4} }, X (char *) 0, X}; X Xstatic Word I_n[96]; Xstatic Bitmap I_north = X{ X (Word *) I_n, X 1, X { {0, 0}, {16, 64} }, X (char *) 0, X}; X X/* ------------------------- East / West ------------------- */ Xstatic Word xI_e[] = X{ X 0xF000, X}; Xstatic Bitmap xI_east = X{ X (Word *) xI_e, X 1, X { {0, 0}, {4, 1} }, X (char *) 0, X}; X Xstatic Word I_e[96]; Xstatic Bitmap I_east = X{ X (Word *) I_e, X 4, X { {0, 0}, {64, 16} }, X}; X X/* ======================== Square piece ====================== */ X/* -------------------- North / South / East / West =========== */ Xstatic Word xO_n[] = X{ X 0xC000, X 0xC000, X}; Xstatic Bitmap xO_north = X{ X (Word *) xO_n, X 1, X { {0, 0}, {2, 2} }, X (char *) 0, X}; X Xstatic Word O_n[96]; Xstatic Bitmap O_north = X{ X (Word *) O_n, X 2, X { {0, 0}, {32, 32} }, X (char *) 0, X}; X X X/* ============================================================ */ X Xstatic GamePiece J_Piece = X{ X 0, (Texture16 *) 0, X { 7, 6, 7, 6, }, X { &xJ_north, &xJ_east, &xJ_south, &xJ_west, }, X { &J_north, &J_east, &J_south, &J_west, }, X}; X Xstatic GamePiece L_Piece = X{ X 0, (Texture16 *) 0, X { 7, 6, 7, 6, }, X { &xL_north, &xL_east, &xL_south, &xL_west, }, X { &L_north, &L_east, &L_south, &L_west, }, X}; X Xstatic GamePiece S_Piece = X{ X 0, (Texture16 *) 0, X { 7, 6, 7, 6, }, X { &xS_north, &xS_east, &xS_north, &xS_east, }, X { &S_north, &S_east, &S_north, &S_east, }, X}; X Xstatic GamePiece Z_Piece = X{ X 0, (Texture16 *) 0, X { 7, 6, 7, 6, }, X { &xZ_north, &xZ_east, &xZ_north, &xZ_east, }, X { &Z_north, &Z_east, &Z_north, &Z_east, }, X}; X Xstatic GamePiece T_Piece = X{ X 0, (Texture16 *) 0, X { 5, 6, 5, 5, }, X { &xT_north, &xT_east, &xT_south, &xT_west, }, X { &T_north, &T_east, &T_south, &T_west, }, X}; X Xstatic GamePiece I_Piece = X{ X 0, (Texture16 *) 0, X { 8, 5, 8, 5, }, X { &xI_north, &xI_east, &xI_north, &xI_east, }, X { &I_north, &I_east, &I_north, &I_east, }, X}; X Xstatic GamePiece O_Piece = X{ X 0, (Texture16 *) 0, X { 6, 6, 6, 6, }, X { &xO_north, &xO_north, &xO_north, &xO_north, }, X { &O_north, &O_north, &O_north, &O_north, }, X}; X XGamePiece *Pieces[] = X{ X &O_Piece, X &I_Piece, X &J_Piece, X &L_Piece, X &S_Piece, X &Z_Piece, X &T_Piece, X}; X X/* X * Pick a game piece. any piece... X */ XGamePiece *Get_Next_Piece() X{ X return Pieces[rand() % 7]; X} X X/* X * Set the color of a piece to a texture given. X */ Xvoid Set_Color(smap, col) X Bitmap *smap; X Texture16 *col; X{ X texture(smap, smap->rect, col, F_OR); X texture(smap, smap->rect, col, F_XOR); X} X Xint Show_Full_Rows(gp) X GamePiece *gp; /* the game piece that might have caused full rows */ X{ X int y, xmax, ymax, ymin, rcount; X Word *w; X Bitmap *gbmap = game_board.map; X X if (gp) X { X Bitmap *gpmap = gp->gmap_arr[gp->cur]; X X ymin = game_board.curpt.y; X ymax = game_board.curpt.y + gpmap->rect.corner.y; X } X else X { X ymin = gbmap->rect.origin.y; X ymax = gbmap->rect.corner.y; X } X X xmax = gbmap->rect.corner.x - 1; X X for (rcount = 0, y = ymin; y < ymax; y++) X { X w = addr(gbmap, Pt(0, y)); X if (*w == FULL_ROW_MASK) X { X Rectangle r; X X rcount++; X r.origin = add(add(Drect.origin, Grect.origin), mul(Pt(0, y), 16)); X r.corner = add(r.origin, mul(Pt(xmax, 1), 16)); X texture(&physical, r, &hashmark, F_STORE); X sleep(30); X } X } X X sleep(30); X return rcount; X} X Xvoid Clear_Full_Rows(rcount, gp) X int rcount; X GamePiece *gp; X{ X int y, xmax, ymax, ymin; X Word *w; X Bitmap *gbmap = game_board.map; X X if (gp) X { X Bitmap *gpmap = gp->gmap_arr[gp->cur]; X X ymin = game_board.curpt.y; X ymax = game_board.curpt.y + gpmap->rect.corner.y; X } X else X { X ymin = gbmap->rect.origin.y; X ymax = gbmap->rect.corner.y; X } X X xmax = gbmap->rect.corner.x - 1; X while (rcount--) X { X for (y = ymax-1; y >= ymin; y--) X { X w = addr(gbmap, Pt(0,y)); X if (*w == FULL_ROW_MASK) X { X Point o; X Rectangle r; X X /* move game rows down by 1 row */ X bitblt(gbmap,Rpt(Pt(0,0), Pt(xmax, y)), gbmap, Pt(0,1), F_STORE); X /* clear the top game row */ X rectf(gbmap, Rpt(Pt(0,0), Pt(xmax, 1)), F_CLR); X X /* move displayed rows down by 1 row */ X r.origin = add(Drect.origin, Grect.origin); X r.corner = add(r.origin, mul(Pt(xmax, y), 16)); X o = add(r.origin, mul(Pt(0, 1), 16)); X bitblt(&physical, r, &physical, o, F_STORE); X X /* clear the top display row */ X r.origin = add(Drect.origin, Grect.origin); X r.corner = add(r.origin, mul(Pt(xmax, 1), 16)); X rectf(&physical, r, F_CLR); X break; X } X } X } X} X X/* X * Using the game bitmap create the displayed piece shape. X */ Xvoid Populate_Bitmap(gmap, smap) X Bitmap *gmap, *smap; X{ X int x, y; X int bit; X Word *w; X X if (! eqpt(gmap->rect.origin, Pt(0,0))) X { X /* fprintf(stderr, "Populate_Bitmap(): Internal error\n"); */ X sleep(2); X exit(); X } X if (gmap->rect.corner.x > 4 || gmap->rect.corner.y > 4) X { X /* fprintf(stderr, "Populate_Bitmap(): Internal error\n"); */ X sleep(2); X exit(); X } X X for (y = gmap->rect.origin.y; y < gmap->rect.corner.y; y++) X for (x = gmap->rect.origin.x; x < gmap->rect.corner.x; x++) X { X w = addr(gmap, Pt(x,y)); X X bit = FIRSTBIT >> (x % WORDSIZE); X X /* X * If the bit is set fill the corresponding block X * in game piece's shape bitmap X */ X if ((*w & bit) == bit) X bitblt(&a_brick, a_brick.rect, smap, Pt((x*16),(y*16)), F_STORE); X } X} X Xvoid Clear_Shadow_Area() X{ X rectf(&physical, raddp(Mrect, Drect.origin), F_CLR); X} X Xvoid Display_Shadow_XOR(gp) X GamePiece *gp; X{ X Point origin; X Bitmap *smap = gp->smap_arr[gp->cur]; X X /* Display the shadow */ X X origin = add(Drect.origin, Mrect.origin); X origin = add(origin, Pt(game_board.curpt.x*16, 0)); X X shadow.rect.corner.x = smap->rect.corner.x; X shadow.width = smap->width; X X texture(&shadow, shadow.rect, (Texture16*) brick_bits, F_STORE); X texture(&shadow, shadow.rect, gp->color, F_XOR); X bitblt(&shadow, shadow.rect, &physical, origin, F_XOR); X} X Xvoid Bitblit_Piece_XOR(gp) X GamePiece *gp; X{ X Point origin; X Bitmap *smap = gp->smap_arr[gp->cur]; X Bitmap *gmap = gp->gmap_arr[gp->cur]; X X /* Game board bitmap */ X origin = game_board.curpt; X bitblt(gmap, gmap->rect, game_board.map, origin, F_XOR); X X /* Display bitmap */ X X origin = fPt(add(add(Drect.origin, Grect.origin), mul(origin, 16))); X bitblt(smap, smap->rect, &physical, origin, F_XOR); X Display_Shadow_XOR(gp); X} X Xvoid Bitblit_Display_XOR(gp) X GamePiece *gp; X{ X Point origin; X Bitmap *smap = gp->smap_arr[gp->cur]; X X origin = fPt(add(add(Drect.origin, Grect.origin),mul(game_board.curpt, 16))); X X bitblt(smap, smap->rect, &physical, origin, F_XOR); X Display_Shadow_XOR(gp); X} X Xvoid Bitblit_Game_Board_XOR(gp) X GamePiece *gp; X{ X Point origin; X Bitmap *gmap = gp->gmap_arr[gp->cur]; X X /* Game board bitmap */ X origin = game_board.curpt; X bitblt(gmap, gmap->rect, game_board.map, origin, F_XOR); X} X Xvoid Draw_Window() X{ X Rectangle r; X X r.origin = sub(Srect.origin, Pt(1, 1)); X r.corner = add(Srect.corner, Pt(1, 1)); X r = raddp(r, Drect.origin); X box(&display, r, F_STORE); X X r.origin = sub(Grect.origin, Pt(1, 1)); X r.corner = add(Grect.corner, Pt(1, 1)); X r = raddp(r, Drect.origin); X box(&display, r, F_STORE); X X r.origin = sub(Mrect.origin, Pt(1, 1)); X r.corner = add(Mrect.corner, Pt(1, 1)); X r = raddp(r, Drect.origin); X box(&display, r, F_STORE); X} X Xvoid Clear_Game_Board() X{ X extern Rectangle Grect; X Rectangle r; X X r.origin = add(Drect.origin, Grect.origin); X r.corner = add(Drect.origin, Grect.corner); X X /* rectf(&display, Drect, F_CLR); */ X rectf(&display, r, F_CLR); X rectf(game_board.map, game_board.map->rect, F_CLR); X /* sleep(2); */ X} X Xvoid Show_Next_Piece(np) X GamePiece *np; X{ X Bitmap *smap = np->smap_arr[np->cur]; X Rectangle r; X X r.origin = add(Drect.origin, nploc); X r.corner = add(r.origin, Pt(64, 64)); X rectf(&physical, r, F_CLR); X bitblt(smap, smap->rect, &physical, r.origin, F_STORE); X} END-of-drawing.c echo x - motion.c sed 's/^X//' >motion.c << 'END-of-motion.c' X/**********************************************************/ X/* */ X/* Copyright (C) 1993 Fariborz ``Skip'' Tavakkolian */ X/* */ X/**********************************************************/ X Xstatic char *RCSid = "$Id: motion.c,v 1.2 93/06/05 22:11:28 fst Exp Locker: fst $"; X X/* X * Description: X * X * $Log: motion.c,v $ X * Revision 1.2 93/06/05 22:11:28 fst X * Changed the RCS ``Header'' with ``Id''. X * X * Revision 1.1 93/06/05 22:06:11 fst X * Initial revision X * X */ X X#include X#include X#include X#include "tetris.h" X Xvoid Reshape_Window() X{ X lprintf("Please Reshape Window"); X X request(RESHAPED); X do X { X wait(RESHAPED); X if (P->state & MOVED) X { X P->state &= ~(MOVED|RESHAPED); X } X else if ((P->state & RESHAPED) && !(P->state & MOVED)) X { X P->state &= ~RESHAPED; X P->state |= NO_RESHAPE; X break; X } X } X while (1); X} X X/* X * Initialize the game pieces. X */ Xvoid Init_Pieces() X{ X int i, j; X extern Texture16 *colors[]; X X for (i = 0; i < PIECES_COUNT; i++) X for (j = 0; j < 4; j++) X { X Pieces[i]->color = colors[i]; X Populate_Bitmap(Pieces[i]->gmap_arr[j], Pieces[i]->smap_arr[j]); X Set_Color(Pieces[i]->smap_arr[j], colors[i]); X } X X srand((unsigned) realtime()); /* seed the random number generator */ X} X XRectangle Grect, Srect, Mrect; X X/* X * Set default size for the window. X */ XPoint default_size(x, y, p) X int x,y; X struct Proc *p; X{ X Point q; X X Srect.origin = fPt(TET_INSET + BBW, TET_INSET + BBW); X X Grect.origin = add(Srect.origin, Pt(TEXTWIDTH+2*BBW+TET_INSET, 0)); X Grect.corner = add(Grect.origin, Pt(GBW, GBH)); X X Mrect.origin = add(Grect.origin, Pt(0, 2*BBW+GBH+TET_INSET)); X Mrect.corner = add(Mrect.origin, Pt(GBW, 16)); X X Srect.corner = fPt(Srect.origin.x+TEXTWIDTH, Mrect.corner.y); X X q.x = Grect.corner.x - Srect.origin.x + 2*TET_INSET + 2*BBW + 2*INSET; X q.y = Srect.corner.y - Srect.origin.y + 2*TET_INSET + 2*BBW + 2*INSET; X X return q; X} X X/* X * Initialize the default size function, colors and pieces. X */ Xvoid Initialize() X{ X colors[1] = &T_white; X colors[2] = &T_grey; X colors[3] = &T_grey2; X colors[4] = &T_checks; X colors[5] = &T_background; X X Init_Pieces(); X X P->ctob = default_size; X P->state |= NOCURSEXPAND; X} X Xint Check_Bounds(origin, corner) X Point origin, corner; X{ X /* X fprintf(stderr, "Check_Bounds origin(%d,%d), corner(%d,%d)\n", X origin.x, origin.y, corner.x, corner.y X ); X */ X X if ((! ptinrect(origin, game_board.map->rect)) || X (! ptinrect(corner, game_board.map->rect))) X return 0; X X return 1; X} X Xint Game_Board_Spot_Empty(gmap, pt) X Bitmap *gmap; /* game piece bitmap */ X Point pt; /* origin of game piece in game board bitmap */ X{ X Point gpt, ept; X int x, y, maxx, maxy, bit; X Word *w; X extern Word *addr(); X X ept = add(pt, sub(gmap->rect.corner, gmap->rect.origin)); X if (! Check_Bounds(pt, ept)) X { X /*fprintf(stderr, "Game_Board_Spot_Empty(): Check_Bounds() failed\n");*/ X return 0; X } X X maxy = gmap->rect.corner.y; X maxx = gmap->rect.corner.x; X X /* X For every bit set in the game piece bitmap X if corresponding bit in the game board bitmap, then fail X if all bits in game board are free, succeed. X */ X X for (y = gmap->rect.origin.y; y < maxy; y++) X for (x = gmap->rect.origin.x; x < maxx; x++) X { X w = addr(gmap, Pt(x, y)); X X bit = FIRSTBIT >> (x % WORDSIZE); X X if ((*w & bit) == bit) X { X gpt = add(pt, Pt(x, y)); X X w = addr(game_board.map, gpt); X bit = FIRSTBIT >> (gpt.x % WORDSIZE); X X if ((*w & bit) == bit) X { X /* X fprintf(stderr, X "Game_Board_Spot_Empty(): point(%d,%d) occupied\n", X gpt.x, gpt.y X ); X */ X return 0; X } X } X } X X /* X fprintf(stderr, X "Game_Board_Spot_Empty(): rectangle([%d,%d],[%d,%d]) is open\n", X pt.x, pt.y, ept.x, ept.y X ); X */ X return 1; X} X Xint Can_Move(gp, d, orgpt) X GamePiece *gp; X enum MoveDirection d; X Point *orgpt; X{ X switch ((int) d) X { X case Left: X *orgpt = sub(game_board.curpt, Pt(1, 0)); X break; X case Right: X *orgpt = add(game_board.curpt, Pt(1, 0)); X break; X case Down: X *orgpt = add(game_board.curpt, Pt(0, 1)); X break; X X default: X return 0; X } X X return Game_Board_Spot_Empty(gp->gmap_arr[gp->cur], *orgpt); X} X Xint Can_Rotate(gp, d, orgpt, orient) X GamePiece *gp; X enum MoveDirection d; X Point *orgpt; X int *orient; X{ X Point center; X X switch ((int) d) X { X case Clockwise: X *orient = ((gp->cur + 1 > 3) ? 0 : gp->cur + 1); X break; X case CounterClockwise: X *orient = ((gp->cur - 1 < 0) ? 3 : gp->cur - 1); X break; X default: X return 0; X } X X X /* Center calculations */ X center = add(game_board.curpt, X div( X sub(gp->gmap_arr[gp->cur]->rect.corner, X gp->gmap_arr[gp->cur]->rect.origin X ), X 2) X ); X X /* New origin calculations */ X *orgpt = sub(center, X div( X sub(gp->gmap_arr[*orient]->rect.corner, X gp->gmap_arr[*orient]->rect.origin X ), X 2) X ); X X return Game_Board_Spot_Empty(gp->gmap_arr[*orient], *orgpt); X} X Xint Move_Piece(gp, d) X GamePiece *gp; X enum MoveDirection d; X{ X int new_orientation; X Point new_origin; X int retval; X X switch ((int) d) X { X case FirstMove: X if (! Game_Board_Spot_Empty(gp->gmap_arr[gp->cur], game_board.curpt)) X return 0; X X break; X X case Left: X case Right: X case Down: X Bitblit_Game_Board_XOR(gp); /* first free current location */ X if (! Can_Move(gp, d, &new_origin)) X { X Bitblit_Game_Board_XOR(gp); /* put it back */ X return ((d == Down) ? -1 : 0); X } X X Bitblit_Display_XOR(gp); /* erase old impression */ X game_board.curpt = new_origin; X break; X X case Clockwise: X case CounterClockwise: X Bitblit_Game_Board_XOR(gp); X if (! Can_Rotate(gp, d, &new_origin, &new_orientation)) X { X Bitblit_Game_Board_XOR(gp); /* put it back */ X return 0; X } X X Bitblit_Display_XOR(gp); X gp->cur = new_orientation; X game_board.curpt = new_origin; X break; X X case Fall: X while ((retval = Move_Piece(gp, Down)) > 0) X /* sleep(2) */; X X return retval; X } X X /* X fprintf(stderr, X "Move_Piece(): drawing (0x%x) at game_board location (%d,%d)\n", X gp, game_board.curpt.x, game_board.curpt.y X ); X */ X Bitblit_Piece_XOR(gp); X return 1; X} X X END-of-motion.c echo x - tetris.h sed 's/^X//' >tetris.h << 'END-of-tetris.h' X/**********************************************************/ X/* */ X/* Copyright (C) 1993 Fariborz ``Skip'' Tavakkolian */ X/* All rights reserved */ X/* */ X/**********************************************************/ X X#ident "$Id: tetris.h,v 1.3 93/06/13 12:29:25 fst Exp $" X X/* X * Description: X * X * $Log: tetris.h,v $ X * Revision 1.3 93/06/13 12:29:25 fst X * Added forward declarations, and some external function declarations. X * X * Revision 1.2 93/06/05 22:11:25 fst X * Changed the RCS ``Header'' with ``Id''. X * X * Revision 1.1 93/06/05 22:04:29 fst X * Initial revision X * X */ X X#ifndef _tetris_h X#define _tetris_h X X/* DMD Library Routines */ Xextern void bitblt(); Xextern void lprintf(); Xextern alarm(); Xextern int request(); Xextern int own(); Xextern int wait(); Xextern Point sPtCurrent(); X X X#define DIM(x) (sizeof(x)/sizeof((x)[0])) X X/* NOTE: X Do not set BOARD_WIDTH greater than 16 X */ X#define BOARD_WIDTH 10 X#define BOARD_HEIGHT 30 X#define PIECES_COUNT 7 X X#define TET_INSET 4 X#define BBW 1 X#define CHARCOUNT 18 X#define TEXTWIDTH (FONTWIDTH(largefont)*CHARCOUNT) X#define GBW (BOARD_WIDTH * 16) X#define GBH (BOARD_HEIGHT* 16) X X/* 1 tick = 1/60 of a second */ X#define FALL_SPEED 30 X X/* X FULL_ROW_MASK greater than FFFF wont work X (see drawing.c Collapse_Full_Rows) X */ X#define FULL_ROW_MASK 0xFFC0 X Xextern Texture16 hashmark; X Xenum MoveDirection X{ X FirstMove, X Fall, X Left, X Right, X Down, X Clockwise, X CounterClockwise, X}; X Xenum Boolean X{ X False = 0, X True, X}; X Xtypedef struct X{ X Point curpt; X Bitmap *map; X} Board; X Xextern Board game_board; X Xtypedef struct X{ X int cur; X Texture16 *color; /* color for this game piece */ X int score[4]; /* points scored for each orientation of the piece */ X Bitmap *gmap_arr[4]; /* the game bitmap (one bit per brick) */ X Bitmap *smap_arr[4]; /* shape bit map. This is built from gmap */ X} GamePiece; X Xextern GamePiece *Pieces[]; Xextern Texture16 *colors[]; Xextern Rectangle Srect, Grect, Mrect; Xextern Point nploc; X X#ifdef _STDC_ X# define __(x) x X#else X# define __(x) () X#endif X X/* dmdtetris functions */ Xextern GamePiece *Get_Next_Piece(); X Xextern void Clear_Game_Board (); Xextern void Draw_Window (); Xextern void Clear_Shadow_Area(); Xextern void Reshape_Window (); Xextern void Clear_Full_Rows (); Xextern void Init_Pieces (); Xextern void Initialize (); X Xextern void Show_Next_Piece __((GamePiece* )); Xextern void Bitblit_Game_Board_XOR __((GamePiece* )); Xextern void Bitblit_Display_XOR __((GamePiece* )); Xextern void Bitblit_Piece_XOR __((GamePiece* )); Xextern void Set_Color __((Bitmap*, Texture16* )); Xextern void Populate_Bitmap __((Bitmap*, Bitmap* )); X Xextern int Show_Full_Rows(); X Xextern Point default_size __((int x, int y, struct Proc* )); X X#endif /* _tetris_h */ END-of-tetris.h exit