This is Card.m in view mode; [Download] [Up]
/* indent:4 tabsize:8 font:fixed-width */ #import "Card.h" /*----------------------------------------------------------------------------- | | Card Globals | | The arrays _CardPipPositions and _CardCardPips provide information about | the positioning of pips on cards. There are 17 possible positions, | described in pipPositions, which are selectively refrerred to for each of | 13 possible card values by a character string. | | The letters A-Q are used to represent pips present in the given card. | | The id's _CardFront, _CardBack etc... are images shared by all instances | of Card | \----------------------------------------------------------------------------*/ static NXPoint _CardPipPositions[] = { {17, 121}, {40, 121}, {63, 121}, {40, 104}, {40, 95}, {17, 86}, {63, 86}, {17, 69}, {40, 69}, {63, 69}, {17, 52}, {63, 52}, {40, 43}, {40, 34}, {17, 17}, {40, 17}, {63, 17} }; char *_CardCardPips[] = { "I", "BP", "BIP", "ACOQ", "ACIOQ", "ACHJOQ", "ACEHJOQ", "ACEHJMOQ", "ACFGIKLOQ", "ACDFGKLNOQ", "CO", "CO", "AQ" }; static id _CardFrontImage, _CardBackImage, _CardSymbolsImage, _CardKingClubsImage, _CardKingDiamondsImage, _CardKingHeartsImage, _CardKingSpadesImage, _CardQueenClubsImage, _CardQueenDiamondsImage, _CardQueenHeartsImage, _CardQueenSpadesImage, _CardJackClubsImage, _CardJackDiamondsImage, _CardJackHeartsImage, _CardJackSpadesImage, _CardAceOfSpadesImage; static id _preDrawnImage[52]; static BOOL _preDrawnImagesAvailable; static BOOL _setCustomImage; @implementation Card /*---------------------------------------------------------------------------- | | + initialize | | returns: (id) [super initialize] | |----------------------------------------------------------------------------- | | Initialize the private pasteboard type used by the CardPileView and load | all images used by the CardPileView class. | \----------------------------------------------------------------------------*/ + initialize { if (self == [Card class]) { _CardFrontImage = [NXImage findImageNamed:"Card"]; _CardBackImage = [NXImage findImageNamed:"Back"]; _CardKingClubsImage = [NXImage findImageNamed:"KingClubs"]; _CardKingDiamondsImage = [NXImage findImageNamed:"KingDiamonds"]; _CardKingHeartsImage = [NXImage findImageNamed:"KingHearts"]; _CardKingSpadesImage = [NXImage findImageNamed:"KingSpades"]; _CardQueenClubsImage = [NXImage findImageNamed:"QueenClubs"]; _CardQueenDiamondsImage = [NXImage findImageNamed:"QueenDiamonds"]; _CardQueenHeartsImage = [NXImage findImageNamed:"QueenHearts"]; _CardQueenSpadesImage = [NXImage findImageNamed:"QueenSpades"]; _CardJackClubsImage = [NXImage findImageNamed:"JackClubs"]; _CardJackDiamondsImage = [NXImage findImageNamed:"JackDiamonds"]; _CardJackHeartsImage = [NXImage findImageNamed:"JackHearts"]; _CardJackSpadesImage = [NXImage findImageNamed:"JackSpades"]; _CardAceOfSpadesImage = [NXImage findImageNamed:"AceOfSpades"]; _CardSymbolsImage = [NXImage findImageNamed:"Symbols"]; } [super initialize]; return self; } /*---------------------------------------------------------------------------- | | + drawCardImages | | returns: (id) self | |----------------------------------------------------------------------------- | | Draws the pre-cached images for every card in the deck. | \----------------------------------------------------------------------------*/ + drawCardImages { id tempCard; int i,j; NXSize aSize; if(_preDrawnImagesAvailable) return self; // don't draw again [_CardFrontImage getSize:&aSize]; for(i=0; i<4; i++){ for(j=0; j<13; j++){ tempCard = [[Card alloc] initSuit:i value:j faceUp:YES]; _preDrawnImage[(i*13)+j] = [[NXImage alloc] initSize:&aSize]; [_preDrawnImage[(i*13)+j] useDrawMethod:@selector(preDrawCard:) inObject:tempCard]; if([_preDrawnImage[(i*13)+j] lockFocus]) [_preDrawnImage[(i*13)+j] unlockFocus]; [tempCard free]; } } _preDrawnImagesAvailable = YES; return self; } /*---------------------------------------------------------------------------- | | + freeCardImages | | returns: (id) self | |----------------------------------------------------------------------------- | | Frees the pre-cached images for every card in the deck. | \----------------------------------------------------------------------------*/ + freeCardImages { int i; if(!_preDrawnImagesAvailable) return self; // don't free again for(i=0; i<52; i++){ [_preDrawnImage[i] free]; } _preDrawnImagesAvailable = NO; return self; } /*---------------------------------------------------------------------------- | | + setCardBackImage:(id)theImage | | returns: (id) self | |----------------------------------------------------------------------------- | | Sets the image used to draw the card backs. | \----------------------------------------------------------------------------*/ + setCardBackImage:theImage { if(theImage){ if(_setCustomImage) [_CardBackImage free]; _CardBackImage = [theImage copyFromZone:[self zone]]; _setCustomImage = YES; } return self; } /*---------------------------------------------------------------------------- | | + setCardBack:(CardBack)aBack | | returns: (id) self | |----------------------------------------------------------------------------- | | Sets the image used to draw the card backs. | \----------------------------------------------------------------------------*/ + setCardBack:(CardBack)aBack { if(_setCustomImage) [_CardBackImage free]; _setCustomImage = NO; switch (aBack) { case CS_DEFAULT: _CardBackImage = [NXImage findImageNamed:"Back"]; break; case CS_TRAD: _CardBackImage = [NXImage findImageNamed:"TradBack"]; break; case CS_SHIP: _CardBackImage = [NXImage findImageNamed:"Ship"]; break; default: _CardBackImage = [NXImage findImageNamed:"Back"]; break; } return self; } /*---------------------------------------------------------------------------- | | - init | | returns: (id) [self initSuit:value:upsideDown:] | |----------------------------------------------------------------------------- | | Acts as a cover for initSuit:value:faceUp: | \----------------------------------------------------------------------------*/ - init { return [self initSuit:CS_ACE value:CS_CLUBS faceUp:NO]; } /*--------------------------------------------------------------------------- | | - initSuit:(CardSuit) aSuit value:(CardValue) aValue | | returns: (id) [self initSuit:value:faceUp:] | |---------------------------------------------------------------------------- | | Acts as a cover for initSuit:value:faceUp: | \----------------------------------------------------------------------------*/ - initSuit:(CardSuit)aSuit value:(CardValue)aValue { return [self initSuit:aSuit value:aValue faceUp:NO]; } /*--------------------------------------------------------------------------- | | - initSuit:(CardSuit)aSuit value:(CardValue)aValue | faceUp:(BOOL)anOrientation | | returns: (id) [super init] | |---------------------------------------------------------------------------- | | Initializes a Card object to the given suit, value and orientation | \----------------------------------------------------------------------------*/ - initSuit:(CardSuit)aSuit value:(CardValue)aValue faceUp:(BOOL)anOrientation { suit = aSuit; value = aValue; faceUp = anOrientation; return [super init]; } /*--------------------------------------------------------------------------- | | - copyFromZone:(NXZone *)zone | | returns: (id) an object which is a duplicate of the sender | |---------------------------------------------------------------------------- | | Create a copy of a card. | \----------------------------------------------------------------------------*/ - copyFromZone:(NXZone *)zone { return [[Card allocFromZone:zone] initSuit:suit value:value faceUp:faceUp]; } /*--------------------------------------------------------------------------- | | - setSuit:(CardSuit)aSuit | | returns: (id) self | |---------------------------------------------------------------------------- | | Changes the card suit | \----------------------------------------------------------------------------*/ - setSuit:(CardSuit)aSuit { suit = aSuit; return self; } /*--------------------------------------------------------------------------- | | - setValue:(CardValue)aValue | | returns: (id) self | |---------------------------------------------------------------------------- | | Changes the card value | \----------------------------------------------------------------------------*/ - setValue:(CardValue)aValue { value = aValue; return self; } /*--------------------------------------------------------------------------- | | - flip | | returns: (id) self | |---------------------------------------------------------------------------- | | Turn the card over | \----------------------------------------------------------------------------*/ - flip { faceUp = !faceUp; return self; } /*--------------------------------------------------------------------------- | | - setFaceUp:(BOOL)anOrientation | | returns: (id) self | |---------------------------------------------------------------------------- | | Turn the card to a specific orientation | \----------------------------------------------------------------------------*/ - setFaceUp:(BOOL)anOrientation { faceUp = anOrientation; return self; } /*--------------------------------------------------------------------------- | | - (CardSuit) suit | | returns: (CardSuit) The card's suit | |---------------------------------------------------------------------------- | | Allow a client to determine the suit of a card | \----------------------------------------------------------------------------*/ - (CardSuit)suit { return suit; } /*--------------------------------------------------------------------------- | | - (CardValue) value | | returns: (CardValue) The card's value | |---------------------------------------------------------------------------- | | Allow a client to determine the value of a card | \----------------------------------------------------------------------------*/ - (CardValue)value { return value; } /*--------------------------------------------------------------------------- | | - (BOOL)isFaceUp | | returns: (BOOL) YES if the card is face up | | (BOOL) NO otherwise | |---------------------------------------------------------------------------- | | Allow a client to determine the orientation of a card | \----------------------------------------------------------------------------*/ - (BOOL)isFaceUp { return faceUp; } /*--------------------------------------------------------------------------- | | - (CardColor) cardColor | | returns: (CardColor) The card's color | |---------------------------------------------------------------------------- | | Allow a client to determine the color of a card, as derrived from the | suit of the card | \----------------------------------------------------------------------------*/ - (CardColor)cardColor { if ((suit == CS_SPADES) || (suit == CS_CLUBS)) { return CS_BLACK; } return CS_RED; } /*--------------------------------------------------------------------------- | | - preDrawCard :(id) theImage | | returns: (id) self | |---------------------------------------------------------------------------- | | Pre draw a visual representation of ourself. | \----------------------------------------------------------------------------*/ - preDrawCard:theImage { NXPoint thePoint={0.,0.}; [self drawOutlineAt:&thePoint]; [self drawContentsAt:&thePoint]; return self; } /*--------------------------------------------------------------------------- | | - drawCardAt :(NXPoint *) thePoint | | returns: (id) self | |---------------------------------------------------------------------------- | | Draw a visual representation of ourself at a given location. | \----------------------------------------------------------------------------*/ - drawCardAt:(NXPoint *)thePoint { if(_preDrawnImagesAvailable && faceUp){ [_preDrawnImage[(suit*13)+value] composite:NX_SOVER toPoint:thePoint]; return self; } [self drawOutlineAt:thePoint]; [self drawContentsAt:thePoint]; return self; } /*--------------------------------------------------------------------------- | | - drawOutlineAt:(NXPoint *)thePoint | | returns: (id) self | |---------------------------------------------------------------------------- | | Draw the outline of a card at a given location. | \----------------------------------------------------------------------------*/ - drawOutlineAt:(NXPoint *)thePoint { [_CardFrontImage composite:NX_SOVER toPoint:thePoint]; return self; } /*--------------------------------------------------------------------------- | | - drawContentsAt:(NXPoint *)thePoint | | returns: (id) self | |---------------------------------------------------------------------------- | | Draw our contents at a given location | \----------------------------------------------------------------------------*/ - drawContentsAt:(NXPoint *)thePoint { if (!faceUp) { /*------------------------------------------------------ | | Draw the back of the card | \------------------------------------------------------*/ NXPoint destPoint = {thePoint->x + 8, thePoint->y + 7}; [_CardBackImage composite:NX_SOVER toPoint:&destPoint]; } else { /*--------------------------------------------------------- | | Draw the upper left / lower right value indicator | \---------------------------------------------------------*/ { NXRect sourceRect = {value * 22, 80, 11, 20}; NXPoint destPoint = {thePoint->x + 4, thePoint->y + 141}; if (([self cardColor] == CS_RED)) { sourceRect.origin.x += 11; } [_CardSymbolsImage composite:NX_SOVER fromRect:&sourceRect toPoint:&destPoint]; sourceRect.origin.y -= 20; destPoint.x = thePoint->x + 92; destPoint.y = thePoint->y + 6; [_CardSymbolsImage composite:NX_SOVER fromRect:&sourceRect toPoint:&destPoint]; } /*---------------------------------------------------------- | | Draw the upper left / lower right suit indicator | \----------------------------------------------------------*/ { NXRect sourceRect = {suit * 13, 15, 13, 15}; NXPoint destPoint = {thePoint->x + 3, thePoint->y + 126}; [_CardSymbolsImage composite:NX_SOVER fromRect:&sourceRect toPoint:&destPoint]; sourceRect.origin.x += 52; destPoint.x = thePoint->x + 91; destPoint.y = thePoint->y + 26; [_CardSymbolsImage composite:NX_SOVER fromRect:&sourceRect toPoint:&destPoint]; } /*--------------------------------------------------------- | | Draw special card images for face cards and the | ace of spades | \---------------------------------------------------------*/ { NXPoint destPoint = {thePoint->x + 16, thePoint->y + 16}; switch (value) { case CS_JACK: switch (suit) { case CS_CLUBS: [_CardJackClubsImage composite:NX_SOVER toPoint:&destPoint]; break; case CS_DIAMONDS: [_CardJackDiamondsImage composite:NX_SOVER toPoint:&destPoint]; break; case CS_HEARTS: [_CardJackHeartsImage composite:NX_SOVER toPoint:&destPoint]; break; case CS_SPADES: [_CardJackSpadesImage composite:NX_SOVER toPoint:&destPoint]; break; } return self; case CS_QUEEN: switch (suit) { case CS_CLUBS: [_CardQueenClubsImage composite:NX_SOVER toPoint:&destPoint]; break; case CS_DIAMONDS: [_CardQueenDiamondsImage composite:NX_SOVER toPoint:&destPoint]; break; case CS_HEARTS: [_CardQueenHeartsImage composite:NX_SOVER toPoint:&destPoint]; break; case CS_SPADES: [_CardQueenSpadesImage composite:NX_SOVER toPoint:&destPoint]; break; } return self; case CS_KING: switch (suit) { case CS_CLUBS: [_CardKingClubsImage composite:NX_SOVER toPoint:&destPoint]; break; case CS_DIAMONDS: [_CardKingDiamondsImage composite:NX_SOVER toPoint:&destPoint]; break; case CS_HEARTS: [_CardKingHeartsImage composite:NX_SOVER toPoint:&destPoint]; break; case CS_SPADES: [_CardKingSpadesImage composite:NX_SOVER toPoint:&destPoint]; break; } return self; default: break; } /*---------------------------------------------------- | | Not only draw the special image for the ace of | spades, but avoid the standard suit pip drawing | \----------------------------------------------------*/ if ((value == CS_ACE) && (suit == CS_SPADES)) { [_CardAceOfSpadesImage composite:NX_SOVER toPoint:&destPoint]; return self; } } /*------------------------------------------------------ | | Draw suit pips on the card based on patterns | defined by the _CardCardSymbols and | _CardCardPips arrays | \------------------------------------------------------*/ { NXRect suitRect = {suit * 26, 31, 26, 29}; NXRect upsideSuitRect = {104 + suit * 26, 31, 26, 29}; char *pipString = _CardCardPips[value]; while (*pipString) { NXPoint tempPoint = _CardPipPositions[*pipString - 'A']; tempPoint.x += thePoint->x; tempPoint.y += thePoint->y; [_CardSymbolsImage composite:NX_SOVER fromRect:(*pipString < 'K') ? &suitRect : &upsideSuitRect toPoint:&tempPoint]; pipString++; } } } return self; } /*--------------------------------------------------------------------------- | | - read:(NXTypedStream *)theStream | | returns: (int) self | |---------------------------------------------------------------------------- | | Dearchive a Card. | \----------------------------------------------------------------------------*/ - read:(NXTypedStream *)theStream { [super read:theStream]; NXReadTypes(theStream, "iic", &suit, &value, &faceUp); return self; } /*--------------------------------------------------------------------------- | | - write:(NXTypedStream *) theStream | | returns: (int) self | |---------------------------------------------------------------------------- | | Archive a Card. | \----------------------------------------------------------------------------*/ - write:(NXTypedStream *)theStream { [super write:theStream]; NXWriteTypes(theStream, "iic", &suit, &value, &faceUp); return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.