|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T d
Length: 30627 (0x77a3)
Types: TextFile
Names: »draw.c«
└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987
└─⟦this⟧ »EUUGD18/X/Dragon/draw.c«
/******************************************************************************
* Dragon - a version of Mah-Jongg for X Windows
*
* Author: Gary E. Barnes May 1989
*
* draw.c - Deals with the Mah-Jongg board. Setup and drawing.
******************************************************************************/
#include "main.h"
#include "board.h"
extern long time();
static void Board_Expose();
extern void Button_Expose();
extern void Button_Press();
extern void Button_Release();
extern void Do_Button_Configuration();
extern void Draw_Text();
extern void Draw_Score();
extern void Draw_Spring();
extern void Draw_Summer();
extern void Draw_Fall();
extern void Draw_Winter();
extern void Draw_Bamboo();
extern void Draw_Mum();
extern void Draw_Orchid();
extern void Draw_Plum();
extern void Draw_GDragon();
extern void Draw_RDragon();
extern void Draw_WDragon();
extern void Draw_East();
extern void Draw_West();
extern void Draw_North();
extern void Draw_South();
extern void Draw_Bam1();
extern void Draw_Bam2();
extern void Draw_Bam3();
extern void Draw_Bam4();
extern void Draw_Bam5();
extern void Draw_Bam6();
extern void Draw_Bam7();
extern void Draw_Bam8();
extern void Draw_Bam9();
extern void Draw_Dot1();
extern void Draw_Dot2();
extern void Draw_Dot3();
extern void Draw_Dot4();
extern void Draw_Dot5();
extern void Draw_Dot6();
extern void Draw_Dot7();
extern void Draw_Dot8();
extern void Draw_Dot9();
extern void Draw_Crak1();
extern void Draw_Crak2();
extern void Draw_Crak3();
extern void Draw_Crak4();
extern void Draw_Crak5();
extern void Draw_Crak6();
extern void Draw_Crak7();
extern void Draw_Crak8();
extern void Draw_Crak9();
/*--Index into this array using a tile number in order to get the procedure
* that knows how to draw the face of that tile. */
typedef void (*Draw_Xyz)();
void Draw_Error() { (void)fprintf( stderr, "Drew tile face 0??\n" ); return; }
Draw_Xyz Faces[1+NFACES] = {
Draw_Error,
Draw_Spring, Draw_Summer, Draw_Fall, Draw_Winter,
Draw_Bamboo, Draw_Mum, Draw_Orchid, Draw_Plum,
Draw_GDragon, Draw_RDragon, Draw_WDragon,
Draw_East, Draw_West, Draw_North, Draw_South,
Draw_Bam1, Draw_Bam2, Draw_Bam3, Draw_Bam4, Draw_Bam5,
Draw_Bam6, Draw_Bam7, Draw_Bam8, Draw_Bam9,
Draw_Dot1, Draw_Dot2, Draw_Dot3, Draw_Dot4, Draw_Dot5,
Draw_Dot6, Draw_Dot7, Draw_Dot8, Draw_Dot9,
Draw_Crak1, Draw_Crak2, Draw_Crak3, Draw_Crak4, Draw_Crak5,
Draw_Crak6, Draw_Crak7, Draw_Crak8, Draw_Crak9
};
\f
void Hilite_Tile( row, col )
int row;
int col;
/******************************************************************************
* row - Specifies the row of the tile to hilite
* col - specifies the column of the tile to hilite
*
* Called to hilite a tile face.
******************************************************************************/
{
register Board_Position bp = &Board_Tiles[row][col];
XPoint pnts[20];
int pnti = 0;
int x, y, w, h;
int left, bottom, left_bottom;
#define PNT(X,Y) \
DEBUG_ERROR(pnti >= XtNumber(pnts),"HT pnts overflow!\n"); \
pnts[pnti].x = X; pnts[pnti].y = Y; ++pnti
;
/*--See if we are one of the very special tiles on top. */
DEBUG_CALL(Hilite_Tile);
if (Board_Tiles[SPEC4].level > 0) {
if (row == 3) {
if (col == 6) {
x = bp->x + Side_X * 4 + 1;
y = bp->y - Side_Y * 4 + 1;
w = Tile_Width / 2;
h = Tile_Height / 2;
PNT( x, y );
PNT( Tile_Width, 0 );
PNT( 0, h-1 );
PNT( -(w+1), 0 );
PNT( 0, h+1 );
PNT( -(w-1), 0 );
PNT( 0, -Tile_Height );
goto Hilite;
} else if (col == 7) {
x = bp->x + Side_X * 4 + 1;
y = bp->y - Side_Y * 4 + 1;
w = Board_Tiles[3][7].x - Board_Tiles[SPEC4].x + 3 * Side_X;
h = Tile_Height / 2;
PNT( x, y );
PNT( Tile_Width, 0 );
PNT( 0, Tile_Height );
PNT( -w, 0 );
PNT( 0, -(h+1) );
PNT( -(Tile_Width-w), 0 );
PNT( 0, -(h-1) );
goto Hilite;
}
} else if (row == 4) {
if (col == 6) {
x = bp->x + Side_X * 4 + 1;
y = bp->y - Side_Y * 4 + 1;
w = Tile_Width / 2;
h = Tile_Height / 2;
PNT( x, y );
PNT( w-1, 0 );
PNT( 0, h + Side_Y );
PNT( w+1, 0 );
PNT( 0, h - Side_Y );
PNT( -Tile_Width, 0 );
PNT( 0, -Tile_Height );
goto Hilite;
} else if (col == 7) {
x = bp->x + Side_X * 4 + 1;
y = bp->y - Side_Y * 4 + 1;
w = Board_Tiles[4][7].x - Board_Tiles[SPEC4].x + 3 * Side_X;
h = Tile_Height / 2;
PNT( x + Tile_Width - w, y );
PNT( w, 0 );
PNT( 0, Tile_Height );
PNT( -Tile_Width, 0 );
PNT( 0, -(h - Side_Y) );
PNT( Tile_Width - w, 0 );
PNT( 0, -(h + Side_Y) );
goto Hilite;
}
}
}
/*--We are a normal tile that may be partially overlapped by some other
* normal tile. */
x = bp->x + Side_X * bp->level + 1;
y = bp->y - Side_Y * bp->level + 1;
w = Tile_Width;
h = Tile_Height;
if (col > 0) {
left = Board_Tiles[row][col-1].level - bp->level;
if (left < 0) { left = 0; }
if (row < 7) {
left_bottom = Board_Tiles[row+1][col-1].level - bp->level;
if (left_bottom < 0) { left_bottom = 0; }
} else {
left_bottom = 0;
}
} else {
left = 0;
left_bottom = 0;
}
if (row < 7) {
bottom = Board_Tiles[row+1][col].level - bp->level;
if (bottom < 0) { bottom = 0; }
} else {
bottom = 0;
}
if (bottom > left_bottom && Tile_Width == 28) { left_bottom = bottom; }
if (left > 0) {
w = left * Side_X;
} else {
w = 0;
}
PNT( x + w, y );
PNT( Tile_Width - w, 0 );
if (bottom > 0) {
h = bottom * Side_Y;
} else {
h = 0;
}
PNT( 0, Tile_Height - h );
if (left_bottom <= left && left_bottom <= bottom) {
PNT( -(Tile_Width - bottom*Side_X), 0 );
if (left != bottom) {
PNT( (left-bottom)*Side_X, (bottom-left)*Side_Y );
}
PNT( 0, -(Tile_Height - h) );
} else if (left_bottom <= left) { /* left_bottom > bottom */
PNT( -(Tile_Width - left_bottom*Side_X), 0 );
if (left_bottom != left ) {
PNT( 0, (bottom-left_bottom)*Side_Y );
PNT( (left-left_bottom)*Side_X, (left_bottom-left)*Side_Y );
PNT( 0, -(Tile_Height - left * Side_Y) );
} else {
PNT( 0, -(Tile_Height - h) );
}
} else if (left_bottom <= bottom) { /* left_bottom > left */
if (left_bottom == bottom) {
PNT( -(Tile_Width-w), 0 );
PNT( 0, -(Tile_Height-h) );
} else {
PNT( -(Tile_Width - bottom * Side_X), 0 );
PNT( (left_bottom-bottom)*Side_X, (bottom-left_bottom)*Side_Y );
PNT( -left_bottom*Side_X, 0 );
PNT( 0, -(Tile_Height - left_bottom * Side_Y) );
}
} else { /* left_bottom > bottom && left_bottom > left */
PNT( -(Tile_Width - left_bottom * Side_X), 0 );
PNT( 0, (bottom-left_bottom)*Side_Y );
PNT( (left-left_bottom)*Side_X, 0 );
PNT( 0, -(Tile_Height - left_bottom * Side_Y) );
}
/*--Now do it. */
Hilite :
XFillPolygon( XtDisplay(Board), XtWindow(Board), Xor_GC,
pnts, (Cardinal)pnti, Convex, CoordModePrevious );
DEBUG_RETURN(Hilite_Tile);
} /* Hilite_Tile */
\f
static void Clear_Tile( bp, left, bottom )
register Board_Position bp;
int left;
int bottom;
/******************************************************************************
* bp - Specifies the Board_Position to draw
* left - Specifies the level of the tile on the left of this thile
* bottom - Specifies the level of the tile at the bottom of this tile
*
* We clear (make totally white) the space occupied by the image of this tile.
* We clear the face and the left and bottom sides. Any shadowing caused by
* the last drawing of this tile is the responsibility of the caller.
******************************************************************************/
{
XPoint Poly[10];
int Polyi;
#undef PNT
#define PNT(XX,YY) \
DEBUG_ERROR(Polyi >= XtNumber(Poly),"Tile: Poly overflow!!\n" ); \
Poly[Polyi].x = (XX); \
Poly[Polyi].y = (YY); \
++Polyi
;
/*--We will circle the tile outline clockwise. */
DEBUG_CALL(Clear_Tile);
Polyi = 0;
/*--Start with the upper left corner of the tile side. This is the "bottom"
* of that tile side if it has one. Leave x/y at the upper-left corner of the
* tile face. */
if (left >= bp->level) {
left = bp->level;
PNT( bp->x + Side_X * bp->level, bp->y - Side_Y * bp->level );
} else {
PNT( bp->x + Side_X * left, bp->y - Side_Y * left );
PNT( Side_X * (bp->level - left), - Side_Y * (bp->level - left) );
}
/*--Cross the top and the right side of the tile. */
PNT( Tile_Width + 1, 0 );
PNT( 0, Tile_Height + 1 );
/*--Now do the bottom side of the tile. */
if (bottom < bp->level) {
PNT( - Side_X * (bp->level - bottom), Side_Y * (bp->level - bottom) );
} else {
bottom = bp->level;
}
PNT( -(Tile_Width + 1), 0 );
/*--Now go up the left side of the tile. */
if (left != bottom) {
PNT( Side_X * (left - bottom), - Side_Y * (left - bottom) );
}
PNT( 0, -(Tile_Height + 1) );
/*--Do the actual clearing. */
XFillPolygon( XtDisplay(Board), XtWindow(Board), Reverse_GC,
Poly, (Cardinal)Polyi, Convex, CoordModePrevious );
DEBUG_RETURN(Clear_Tile);
} /* Clear_Tile */
\f
static void Tile( row, col )
int row;
int col;
/******************************************************************************
* row - Specifies the tile to draw
* col - Specifies the tile to draw
*
* Called to draw a tile. We draw the face, the sides, and the shadow.
******************************************************************************/
{
register Board_Position bp= &Board_Tiles[row][col];
XPoint Poly[100];
int Polyi;
int left;
int bottom;
int curx;
int cury;
int sidex;
int sidey;
int i, j, k, l, m;
#undef PNT
#define PNT(XX,YY) \
DEBUG_ERROR(Polyi >= XtNumber(Poly), "Tile: Poly overflow!!\n" ); \
Poly[Polyi].x = (XX); \
Poly[Polyi].y = (YY); \
++Polyi
;
/*--This tile no longer needs drawing. */
DEBUG_CALL(Tile);
bp->draw = FALSE;
/*--Determine the level of the tile on the left of this tile. */
if (col > 0) {
if (col == SPEC1col && row == SPEC1row) {
left = Board_Tiles[SPEC2].level;
} else if (col == SPEC2col && row == SPEC2row) {
if (Board_Tiles[3][12].level == 0 ||
Board_Tiles[4][12].level == 0) {
left = 0;
} else {
left = 1;
}
} else {
left = Board_Tiles[row][col-1].level;
}
} else {
left = 0;
}
/*--Determine the level of the tile at the bottom of this tile. */
if (row < 7) {
bottom = Board_Tiles[row+1][col].level;
} else {
bottom = 0;
}
/*--Clear the area that will be covered by this tile. */
Clear_Tile( bp, left, bottom );
/*--Draw the tile face. */
(*(Faces[bp->tiles[bp->level-1]]))( bp->x + bp->level * Side_X + 1,
bp->y - bp->level * Side_Y + 1 );
/*--Now draw the tile edges. */
if (Tile_Control & BLACKSIDE) {
/*--We want black/gray sides. */
XDrawRectangle( XtDisplay(Board), XtWindow(Board), Normal_GC,
bp->x + bp->level * Side_X,
bp->y - bp->level * Side_Y,
Tile_Width + 1, Tile_Height + 1 );
if (left < bp->level) {
Polyi = 0;
PNT( bp->x + left * Side_X, bp->y - left * Side_Y );
PNT( (bp->level - left) * Side_X, (left - bp->level) * Side_Y );
PNT( 0, Tile_Height + 1 );
PNT( (left - bp->level) * Side_X, (bp->level - left) * Side_Y );
PNT( 0, -(Tile_Height + 1) );
XFillPolygon( XtDisplay(Board), XtWindow(Board),
((Tile_Control & GRAYSIDE) ? Gray_GC : Normal_GC),
Poly, (Cardinal)Polyi, Convex, CoordModePrevious );
XDrawLines( XtDisplay(Board), XtWindow(Board), Normal_GC,
Poly, (Cardinal)Polyi, CoordModePrevious );
}
if (bottom < bp->level) {
Polyi = 0;
PNT( bp->x + bp->level * Side_X,
bp->y - bp->level * Side_Y + Tile_Height + 1 );
PNT( Tile_Width + 1, 0 );
PNT( (bottom - bp->level) * Side_X, (bp->level - bottom) * Side_Y);
PNT( -(Tile_Width + 1), 0 );
PNT( (bp->level - bottom) * Side_X, (bottom - bp->level) * Side_Y);
XFillPolygon( XtDisplay(Board), XtWindow(Board),
((Tile_Control & GRAYSIDE) ? Gray_GC : Normal_GC),
Poly, (Cardinal)Polyi, Convex, CoordModePrevious );
XDrawLines( XtDisplay(Board), XtWindow(Board), Normal_GC,
Poly, (Cardinal)Polyi, CoordModePrevious );
}
/*--We want line'ed sides. */
} else {
Polyi = 0;
if (left >= bp->level) {
PNT( bp->x + Side_X * bp->level, bp->y - Side_Y * bp->level );
} else {
/*--First we draw the left side. We leave x/y at the bottom left corner of
* the tile face when we are done. */
#define LSEGS 7 /* keep this an odd number */
sidex = Side_X * (bp->level - left);
sidey = Side_Y * (bp->level - left);
j = sidex;
if (Tile_Width == 28 && bp->level - left == 1) {
PNT( bp->x + Side_X * left, bp->y - Side_Y * left - sidey );
PNT( 0, Tile_Height + 1 + sidey );
k = 0;
} else {
PNT( bp->x + Side_X * left, bp->y - Side_Y * left );
PNT(0, Tile_Height + 1 );
k = sidey;
}
PNT( sidex, -sidey );
i = Tile_Height / (LSEGS+1);
m = Tile_Height - i * (LSEGS+1);
for (l = LSEGS; l > 0; --l) {
cury = -i;
if (m > 0) { cury -= 1; --m; }
PNT( 0, cury );
PNT( -j, k );
j = -j;
k = -k;
}
PNT( 0, -i-1 );
PNT( sidex, k );
}
PNT( 0, Tile_Height + 1 );
/*--Draw the left edge of the tile and then draw the bottom side of the tile.
* We leave x/y at the bottom right corner of the tile face when we are done.
*/
#define RSEGS 6 /* keep this an even number */
if (bottom < bp->level) {
sidex = Side_X * (bp->level - bottom);
sidey = Side_Y * (bp->level - bottom);
i = Tile_Width / (RSEGS+1);
m = Tile_Width - i * (RSEGS+1);
if (Tile_Width == 28 && bp->level - bottom == 1) {
j = 0;
} else {
j = sidex;
}
k = sidey;
for (l = RSEGS; l > 0; --l) {
curx = i;
if (m > 0) { curx += 1; --m; }
PNT( curx, 0 );
PNT( -j, k );
j = -j;
k = -k;
}
PNT( i+1, 0 );
PNT( -j, sidey );
PNT( -(Tile_Width + 1 + sidex - j), 0 );
PNT( sidex, -sidey );
}
PNT( Tile_Width + 1, 0 );
/*--Draw the right side. */
PNT( 0, -(Tile_Height + 1) );
/*--Draw the top side. */
PNT( -(Tile_Width + 1), 0 );
/*--Draw all of those edges. */
XDrawLines( XtDisplay(Board), XtWindow(Board),
((Tile_Control & GRAYSIDE) ? Gray_GC : Normal_GC),
Poly, (Cardinal)Polyi, CoordModePrevious );
}
/*--Now draw the tile shadow. */
if (Tile_Control & SHADOW) {
int top, right;
Boolean top_right;
/*--Determine the level of the tile on the right of this tile. */
if (col == SPEC1col) {
if (row == SPEC2row) {
right = Board_Tiles[SPEC1].level;
} else if (row == SPEC3row) {
right = 0;
} else {
right = 0;
}
} else {
right = Board_Tiles[row][col+1].level;
}
/*--Determine the level of the tile at the top of this tile. */
if (row > 0) {
top = Board_Tiles[row-1][col].level;
} else {
top = 0;
}
/*--Do we have an upper-right tile? */
if (row > 0 &&
Board_Tiles[row-1][col+1].level >= bp->level) {
top_right = TRUE;
} else if (row == SPEC3row && col == SPEC3col &&
Board_Tiles[3][1].level > 0) {
top_right = TRUE;
} else if (row == 4 && col == 12 &&
Board_Tiles[SPEC2].level > 0) {
top_right = TRUE;
} else {
top_right = FALSE;
}
/*--Draw the upper shadow if necessary. */
if (top < bp->level) {
Polyi = 0;
PNT( bp->x + bp->level * Side_X - 1,
bp->y - bp->level * Side_Y );
PNT( Shadow_X, -Shadow_Y );
if (top_right) {
i = Shadow_X;
} else {
i = 0;
}
PNT( Tile_Width + 3 - i, 0 );
PNT( -(Shadow_X - i), Shadow_Y );
PNT( -(Tile_Width + 3), 0 );
XFillPolygon( XtDisplay(Board), XtWindow(Board), Over_GC,
Poly, (Cardinal)Polyi, Convex, CoordModePrevious );
}
/*--Now work on the right shadow. It may need to be drawn in pieces. */
Polyi = 0;
/*--If SPEC3 has both neighbors then don't draw the right shadow. */
if (row == SPEC3row && col == SPEC3col) {
if (Board_Tiles[3][1].level > 0) {
if (Board_Tiles[4][1].level > 0) {
right = bp->level;
/*--If SPEC3 has only the upper neighbor then draw just the lower shadow. */
} else {
i = bp->y - Board_Tiles[3][1].y;
PNT( Board_Tiles[4][1].x + Side_X, Board_Tiles[4][1].y );
PNT( Shadow_X, 0 );
PNT( 0, i - Shadow_Y);
PNT( -Shadow_X, Shadow_Y );
PNT( 0, -i );
right = bp->level;
}
/*--If SPEC3 has only the lower neighbor then draw just the upper shadow. */
} else if (Board_Tiles[4][1].level > 0) {
i = Board_Tiles[4][1].y - bp->y;
PNT( bp->x + bp->level * Side_X + Tile_Width + 1 + 1,
bp->y - bp->level * Side_Y );
PNT( Shadow_X, -Shadow_Y );
PNT( 0, i + Shadow_Y );
PNT( -Shadow_X, 0 );
PNT( 0, -i );
right = bp->level;
}
/*--If SPEC2's upper neighbor is there then draw that tile's upper shadow. */
} else if (row == 3 && col == 12 && Board_Tiles[SPEC2].level > 0) {
i = Board_Tiles[SPEC2].y - bp->y;
PNT( bp->x + bp->level * Side_X + Tile_Width + 1 + 1,
bp->y - bp->level * Side_Y );
PNT( Shadow_X, -Shadow_Y );
PNT( 0, i + Shadow_Y );
PNT( -Shadow_X, 0 );
PNT( 0, -i );
right = bp->level;
/*--If SPEC2's lower neighbor is there then draw that tile's lower shadow. */
} else if (row == 4 && col == 12 && Board_Tiles[SPEC2].level > 0) {
i = bp->y - Board_Tiles[SPEC2].y;
PNT( Board_Tiles[SPEC2].x + Side_X,
Board_Tiles[SPEC2].y + Tile_Height + 1);
PNT( Shadow_X, 0 );
PNT( 0, i - Shadow_Y);
PNT( -Shadow_X, Shadow_Y );
PNT( 0, -i );
right = bp->level;
}
/*--If required, draw a normal right shadow that may be truncated by an upper
* right neighbor. */
if (right < bp->level) {
Polyi = 0;
if (top_right) {
i = Shadow_Y;
} else {
i = 0;
}
PNT( bp->x + bp->level * Side_X + Tile_Width + 1 + 1,
bp->y - bp->level * Side_Y );
PNT( Shadow_X, -(Shadow_Y-i) );
PNT( 0, Tile_Height + 1 - i );
PNT( -Shadow_X, Shadow_Y );
PNT( 0, -(Tile_Height + 1) );
}
/*--Draw any right shadow that may have been requested. */
if (Polyi > 0) {
XFillPolygon( XtDisplay(Board), XtWindow(Board), Over_GC,
Poly, (Cardinal)Polyi, Convex, CoordModePrevious );
}
}
/*--Now check for hiliting. */
if (Board_State != s_Sample) {
if (Click1 == bp) {
Hilite_Tile( Click1_Row, Click1_Col );
} else if (Click2 == bp) {
Hilite_Tile( Click2_Row, Click2_Col );
}
}
DEBUG_RETURN(Tile);
} /* Tile */
\f
void Draw_All_Tiles()
/******************************************************************************
* Draws all visible tiles.
******************************************************************************/
{
int i,j;
/*--Draw the rightmost special tiles. */
DEBUG_CALL(Draw_All_Tiles);
if (Board_Tiles[SPEC1].draw && Board_Tiles[SPEC1].level > 0) {
Tile( SPEC1row, SPEC1col );
}
if (Board_Tiles[SPEC2].draw && Board_Tiles[SPEC2].level > 0) {
Tile( SPEC2row, SPEC2col );
}
/*--Draw the current game. Draw the normally placed tiles. */
for (i = 0; i <= 7; ++i) {
for (j = 12; j >= 1; --j) {
if (Board_Tiles[i][j].draw && Board_Tiles[i][j].level > 0) {
Tile( i, j );
}
}
}
/*--Now draw the other special tiles. */
if (Board_Tiles[SPEC4].draw && Board_Tiles[SPEC4].level > 0) {
Tile( SPEC4row, SPEC4col );
}
if (Board_Tiles[SPEC3].draw && Board_Tiles[SPEC3].level > 0) {
Tile( SPEC3row, SPEC3col );
}
Draw_Score( Score,
(int)(Board_Tile0_X + 14 * (Tile_Width + 1)),
(int)(Board_Tile0_Y + 8 * (Tile_Height + 1)) );
DEBUG_RETURN(Draw_All_Tiles);
} /* Draw_All_Tiles */
\f
static void Sample( face, x, y )
int face;
int x;
int y;
/******************************************************************************
* Draw one sample tile.
******************************************************************************/
{
XDrawRectangle( XtDisplay(Board), XtWindow(Board), Normal_GC,
x, y, Tile_Width+1, Tile_Height+1 );
(*(Faces[face]))( x+1, y+1 );
} /* Sample */
\f
/*ARGSUSED*/
static void Tile_Samples()
/******************************************************************************
* Called when we want to display all tiles as a sampler.
******************************************************************************/
{
int x = Board_Tile0_X + 2 * Tile_Width;
int y = Board_Tile0_Y;
/*--Clear the board. */
DEBUG_CALL(Tile_Samples);
/*--Draw sample tiles. */
Draw_Text( "Flower", Board_Tile0_X, y );
Draw_Text( "Flower", Board_Tile0_X+1, y );
Sample( 5, (int)(x + (Tile_Width + 1)*0), y );/*Draw_Bamboo*/
Sample( 6, (int)(x + (Tile_Width + 1)*1), y );/*Draw_Mum*/
Sample( 7, (int)(x + (Tile_Width + 1)*2), y );/*Draw_Orchid*/
Sample( 8, (int)(x + (Tile_Width + 1)*3), y );/*Draw_Plum*/
y += (int)Tile_Height + 1;
Draw_Text( "Season", Board_Tile0_X, y );
Draw_Text( "Season", Board_Tile0_X+1, y );
Sample( 1, (int)(x + (Tile_Width + 1)*0), y );/*Draw_Spring*/
Sample( 2, (int)(x + (Tile_Width + 1)*1), y );/*Draw_Summer*/
Sample( 3, (int)(x + (Tile_Width + 1)*2), y );/*Draw_Fall*/
Sample( 4, (int)(x + (Tile_Width + 1)*3), y );/*Draw_Winter*/
y += (int)Tile_Height + 1;
Draw_Text( "Dragon", Board_Tile0_X, y );
Draw_Text( "Dragon", Board_Tile0_X+1, y );
Sample( 10, (int)(x + (Tile_Width + 1)*1), y );/*Draw_RDragon*/
Sample( 11, (int)(x + (Tile_Width + 1)*2), y );/*Draw_WDragon*/
Sample( 9, (int)(x + (Tile_Width + 1)*0), y );/*Draw_GDragon*/
y += (int)Tile_Height + 1;
Draw_Text( "Wind", Board_Tile0_X, y );
Draw_Text( "Wind", Board_Tile0_X+1, y );
Sample( 12, (int)(x + (Tile_Width + 1)*0), y );/*Draw_East*/
Sample( 13, (int)(x + (Tile_Width + 1)*1), y );/*Draw_West*/
Sample( 14, (int)(x + (Tile_Width + 1)*2), y );/*Draw_North*/
Sample( 15, (int)(x + (Tile_Width + 1)*3), y );/*Draw_South*/
y += (int)Tile_Height + 1;
Draw_Text( "Bam", Board_Tile0_X, y );
Draw_Text( "Bam", Board_Tile0_X+1, y );
Sample( 16, (int)(x + (Tile_Width + 1)*0), y );/*Draw_Bam1*/
Sample( 17, (int)(x + (Tile_Width + 1)*1), y );/*Draw_Bam2*/
Sample( 18, (int)(x + (Tile_Width + 1)*2), y );/*Draw_Bam3*/
Sample( 19, (int)(x + (Tile_Width + 1)*3), y );/*Draw_Bam4*/
Sample( 20, (int)(x + (Tile_Width + 1)*4), y );/*Draw_Bam5*/
Sample( 21, (int)(x + (Tile_Width + 1)*5), y );/*Draw_Bam6*/
Sample( 22, (int)(x + (Tile_Width + 1)*6), y );/*Draw_Bam7*/
Sample( 23, (int)(x + (Tile_Width + 1)*7), y );/*Draw_Bam8*/
Sample( 24, (int)(x + (Tile_Width + 1)*8), y );/*Draw_Bam9*/
y += (int)Tile_Height + 1;
Draw_Text( "Dot", Board_Tile0_X, y );
Draw_Text( "Dot", Board_Tile0_X+1, y );
Sample( 25, (int)(x + (Tile_Width + 1)*0), y );/*Draw_Dot1*/
Sample( 26, (int)(x + (Tile_Width + 1)*1), y );/*Draw_Dot2*/
Sample( 27, (int)(x + (Tile_Width + 1)*2), y );/*Draw_Dot3*/
Sample( 28, (int)(x + (Tile_Width + 1)*3), y );/*Draw_Dot4*/
Sample( 29, (int)(x + (Tile_Width + 1)*4), y );/*Draw_Dot5*/
Sample( 30, (int)(x + (Tile_Width + 1)*5), y );/*Draw_Dot6*/
Sample( 31, (int)(x + (Tile_Width + 1)*6), y );/*Draw_Dot7*/
Sample( 32, (int)(x + (Tile_Width + 1)*7), y );/*Draw_Dot8*/
Sample( 33, (int)(x + (Tile_Width + 1)*8), y );/*Draw_Dot9*/
y += (int)Tile_Height + 1;
Draw_Text( "Crak", Board_Tile0_X, y );
Draw_Text( "Crak", Board_Tile0_X+1, y );
Sample( 34, (int)(x + (Tile_Width + 1)*0), y );/*Draw_Crak1*/
Sample( 35, (int)(x + (Tile_Width + 1)*1), y );/*Draw_Crak2*/
Sample( 36, (int)(x + (Tile_Width + 1)*2), y );/*Draw_Crak3*/
Sample( 37, (int)(x + (Tile_Width + 1)*3), y );/*Draw_Crak4*/
Sample( 38, (int)(x + (Tile_Width + 1)*4), y );/*Draw_Crak5*/
Sample( 39, (int)(x + (Tile_Width + 1)*5), y );/*Draw_Crak6*/
Sample( 40, (int)(x + (Tile_Width + 1)*6), y );/*Draw_Crak7*/
Sample( 41, (int)(x + (Tile_Width + 1)*7), y );/*Draw_Crak8*/
Sample( 42, (int)(x + (Tile_Width + 1)*8), y );/*Draw_Crak9*/
XFlush( XtDisplay(Board) );
DEBUG_RETURN(Tile_Samples);
} /* Tile_Samples */
\f
/*ARGSUSED*/
void Show_Samples( w, event, params, num_params )
Widget w;
XEvent *event;
String *params;
Cardinal *num_params;
/******************************************************************************
* Called when the Samples button is presses. Display or un-display the sample
* tiles.
******************************************************************************/
{
XClearArea( XtDisplay(Board), XtWindow(w),
0, Board_Tile0_Y - Side_Y - Shadow_Y, 0, 0, FALSE );
if (Board_State == s_Normal) {
Board_State = s_Sample;
Tile_Samples();
} else {
Board_State = s_Normal;
Board_Expose( w, event, params, num_params );
}
} /* Show_Samples */
\f
/*ARGSUSED*/
static void Board_Expose( w, event, params, num_params )
Widget w;
XEvent *event;
String *params;
Cardinal *num_params;
/******************************************************************************
* Called when the Board receives an Expose event.
******************************************************************************/
{
int i,j;
XEvent event2;
/*--Getting multiple events; at least when we start. */
DEBUG_CALL(Board_Expose);
while (XCheckWindowEvent( XtDisplay(Board), XtWindow(Board),
ExposureMask, &event2 )) { }
/*--Draw the correct stuff. We might not want the current game. */
if (Board_State == s_Sample) {
Tile_Samples();
return;
}
/*--Draw the entire board. */
for (i = 0; i < NROWS; ++i) {
for (j = 0; j < NCOLS; ++j) {
if (Board_Tiles[i][j].level > 0) {
Board_Tiles[i][j].draw = TRUE;
}
}
}
Draw_All_Tiles();
/*--Make sure that it all goes out to the server. */
XFlush( XtDisplay(Board) );
DEBUG_RETURN(Board_Expose);
} /* Board_Expose */
\f
/*ARGSUSED*/
static void Board_Configure( w, event, params, num_params )
Widget w;
XConfigureEvent *event;
String *params;
Cardinal *num_params;
/******************************************************************************
* Called when the Board receives a ConfigureNotify event.
******************************************************************************/
{
extern void Configure_Tiles();
int old_height = Tile_Height;
/*--Calculate the new Board size. */
DEBUG_CALL(Board_Configure);
Board_Width = event->width;
Board_Height = event->height;
Tile_Width = (Board_Width-9) / 15 - 1;
Tile_Height = (Board_Height-9) / 10 - 1;
/*--Pick a tile size based upon the size of the board. */
if (Tile_Width >= 80 && Tile_Height >= 96) {
Tile_Width = 80;
Tile_Height = 96;
Configure_Tiles( 5 );
} else if (Tile_Width >= 68 && Tile_Height >= 80) {
Tile_Width = 68;
Tile_Height = 80;
Configure_Tiles( 4 );
} else if (Tile_Width >= 56 && Tile_Height >= 64) {
Tile_Width = 56;
Tile_Height = 64;
Configure_Tiles( 3 );
} else if (Tile_Width >= 40 && Tile_Height >= 48) {
Tile_Width = 40;
Tile_Height = 48;
Configure_Tiles( 2 );
} else {
Tile_Width = 28;
Tile_Height = 32;
Configure_Tiles( 1 );
}
/*--Figure the real 0,0 coordinate. */
Board_Tile0_X = 4;
Board_Tile0_Y = 4 + 2 * Tile_Height;
/*--Figure the Shadow and Side sizes. */
Shadow_X = Tile_Width / 10;
Shadow_Y = Tile_Height / 10;
Side_X = (Tile_Width / 10) & ~1;
Side_Y = (Tile_Height / 10) & ~1;
/*--See if we need to repaint. */
if (old_height != Tile_Height) {
Do_Button_Configuration();
Set_Tile_Controls();
XClearArea( XtDisplay(Board), XtWindow(Board), 0, 0, 0, 0, TRUE );
}
DEBUG_RETURN(Board_Configure);
} /* Board_Configure */
\f
void Board_Setup()
/******************************************************************************
* Called to set up and create the Board widget.
******************************************************************************/
{
#undef SETARG
#define SETARG(name,value) \
DEBUG_ERROR(argi >= XtNumber(args), "BS args overrun!\n" ); \
XtSetArg( args[argi], name, (XtArgVal)value ); ++argi;
#undef ACTION
#define ACTION(Name,Proc) \
DEBUG_ERROR(roui >= XtNumber(Routines), "BS Routines overrun!\n" ); \
Routines[roui].string = Name; \
Routines[roui].proc = (XtActionProc)Proc; \
++roui
static char actions[] = "<Expose>: ButtonExpose() BoardExpose()\n\
<Configure>: BoardConfigure()\n\
<Btn1Down>: ButtonPress() TilePress()\n\
<Btn1Up>: ButtonRelease() TileRelease()\n\
<Btn2Down>: TileHints()\n\
<Btn3Down>: TileRemove()\n";
XtActionsRec Routines[20];
int roui = 0;
Arg args[40];
int argi = 0;
/*--Define the various routines that we will be calling for various events
* on the Board. */
DEBUG_CALL(Board_Setup);
ACTION( "BoardConfigure", Board_Configure );
ACTION( "BoardExpose", Board_Expose );
ACTION( "ButtonExpose", Button_Expose );
ACTION( "ButtonPress", Button_Press );
ACTION( "ButtonRelease", Button_Release );
ACTION( "TileHints", Hints );
ACTION( "TileRemove", Tile_Remove );
ACTION( "TilePress", Tile_Press );
ACTION( "TileRelease", Tile_Release );
XtAddActions( Routines, (Cardinal)roui );
/*--Set up the various arguments to our Board. */
SETARG( XtNcursor, Dragon_Resources.Cursor );
SETARG( XtNtranslations, XtParseTranslationTable( actions ) );
/*--Now actually create the board. */
Board = XtCreateManagedWidget( "board", simpleWidgetClass, Dragon,
args, (Cardinal)argi );
XtRealizeWidget( Dragon );
/*--Give the tiles a default initial size. */
{ XConfigureEvent event;
event.width = Board->core.width;
event.height = Board->core.height;
Board_Configure( (Widget)Board, &event,
(String*)NULL, (Cardinal*)NULL );
}
/*--Give the buttons a default initial size based upon the Tile sizes. */
Do_Button_Configuration();
/*--Set up the random number generator. */
{ extern char *initstate();
static char data[32];
(void)initstate( (unsigned)time((long*)0), &data[0], sizeof(data) );
#if 0
(void)initstate( 123456, &data[0], sizeof(data) );
#endif
}
/*--Set up the initial game. */
Setup_New_Game();
DEBUG_RETURN(Board_Setup);
} /* Board_Setup */