This is Minimatrix.m in view mode; [Download] [Up]
/* * This is the view from which NextMatrix and TetMatrix inherit. * * The major data structures are. * id *iconMatrix; Holds the id of the block that is in the current * (row, column). */ #import <appkit/NXImage.h> #import <appkit/nextstd.h> #import <dpsclient/psops.h> #import "Minimatrix.h" @implementation Minimatrix - initFrame:(const NXRect *)frameRect { return [self initFrame:frameRect bitmap:nil numRows:0 numCols:0]; } - initFrame:(const NXRect *)frameRect numRows:(int)rowsHigh numCols:(int)colsWide { return [self initFrame:frameRect bitmap:nil numRows:rowsHigh numCols:colsWide]; } - initFrame:(const NXRect *)frameRect bitmap:theBitmap numRows :(int)rowsHigh numCols :(int)colsWide { [super initFrame:frameRect]; numRows = rowsHigh; numCols = colsWide; NX_MALLOC(iconMatrix, id, numRows * numCols); backgroundGray = NX_LTGRAY; inset.width = inset.height = 0.0; insetBounds = bounds; intercell = elementSize = inset; [self setBitmap:theBitmap]; return self; } /* * Return the id of the bitmap at (row,column) if one exists, else nil. */ - bitmapAt:(int)row :(int)column { return (row < 0 || column < 0 || row >= numRows || column >= numCols) ? nil : *(iconMatrix + row * numCols + column); } - displayAt:(int)row :(int)column { NXRect destRect; NXSetRect(&destRect, inset.width + column * (intercell.width + elementSize.width), inset.height + row * (intercell.width + elementSize.width), elementSize.width + intercell.width, elementSize.height + intercell.height); return [self display:&destRect :1]; } - drawSelf:(const NXRect *)rects :(int)rectCount { int rowc, colc; int rectc; NXRect destRect; id *iconMatrixPiece; const NXRect *rectp; static int bsides[] = {NX_YMIN, NX_XMAX, NX_YMAX, NX_XMIN, NX_YMIN, NX_XMAX, NX_YMAX, NX_XMIN}; static float bgrays[] = {NX_WHITE, NX_WHITE, NX_DKGRAY, NX_DKGRAY, NX_LTGRAY, NX_WHITE, NX_DKGRAY, NX_DKGRAY}; PSsetgray(backgroundGray); NXRectFillList(rects, rectCount); // Clear old areas destRect = bounds; // Draw the insetRect around the border of the game when a Piece // intersects with the border. if ((inset.width || inset.height) && !NXContainsRect(&insetBounds, rects)) { NXDrawTiledRects(&destRect, (NXRect *)0, bsides, bgrays, 8); } NXSetRect(&destRect, inset.width + intercell.width, inset.height + intercell.height, elementSize.width, elementSize.height); iconMatrixPiece = iconMatrix; // Redraw all of the Pieces that have changed for (rowc = 0; rowc < numRows; rowc++) { for (colc = 0; colc < numCols; colc++) { if (*iconMatrixPiece) { rectc = rectCount; rectp = rects; while (rectc--) { if (NXIntersectsRect(&destRect, rectp++)) { // If we assume the piece contains no alpha then we could use // NX_COPY [*iconMatrixPiece composite:NX_SOVER toPoint:&destRect.origin]; break; } } } // Add block's width + space b/w each block to get new X coord destRect.origin.x += elementSize.width + intercell.width; iconMatrixPiece++; // Do next column in iconMatrix } destRect.origin.x = inset.width + intercell.width; // Add the block's height + intercell.height destRect.origin.y += elementSize.height + intercell.height; } return self; } /* * Private method. */ - getIntercell:(NXSize *)aSize { *aSize = intercell; return self; } - getRect:(NXRect *)theRect for:(int)row :(int)column { theRect->size = elementSize; // Get block's image size return [self point:&theRect->origin for:row :column]; } /* * Calculate the TetrisView coordinate given the Tetrix (row,column) */ - point:(NXPoint *)thePoint for:(int)row :(int)column { thePoint->x = inset.width + (column + 1) * intercell.width + column * elementSize.width; thePoint->y = inset.height + (row + 1) * intercell.height + row * elementSize.height; return self; } - setBackgroundGray:(float)gray { backgroundGray = gray; return self; } - setBitmap:theBitmap { id *iconMatrixPiece; #ifdef DEBUG printf("setBitmap\n"); #endif iconMatrixPiece = iconMatrix + numRows * numCols; while (iconMatrixPiece > iconMatrix) *--iconMatrixPiece = theBitmap; if (theBitmap) [theBitmap getSize:&elementSize]; return self; } /* * Set the current (row, column) of the iconMatrix equal to the id of * the block that was just dropped. * * There is a bug in this program. Occasionally, an invalid row * is generated. * * theBitmap row, col = (24, 6) * theBitmap row, col = (23, 6) * theBitmap row, col = (23, 7) * theBitmap row, col = (25, 3) * theBitmap row, col = (698590, 3) */ - setBitmap:theBitmap at:(int)row :(int)column { if (row < numRows && row >= 0 && column < numCols && column >= 0) { *(iconMatrix + row * numCols + column) = theBitmap; } else { fprintf(stderr, "Invalid row %d in Minimatrix::setBitmap\n", row); } return self; } /* * The size of the image (TIFF or PS) we are using to build the block. * Currently 16x16 is the image size. */ - setElementSize:(const NXSize *)aSize { elementSize = *aSize; return self; } /* * Set the number of pixels away from the border the pieces will be. */ - setInset:(const NXSize *)aSize { inset = *aSize; insetBounds = bounds; NXInsetRect(&insetBounds, inset.width, inset.height); return self; } /* * Set the amount of space to leave between each cell. */ - setIntercell:(const NXSize *)aSize { intercell = *aSize; return self; } - free { NX_FREE(iconMatrix); return [super free]; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.