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.