|
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 */