/* * RISK by Sal Valente * $Id: gg.c,v 1.3 1998/01/04 00:29:30 svalente Exp $ */ #include "risk.h" #include "gg-data.h" #ifndef RISK_DATADIR #define RISK_DATADIR "/home/svalente/src/risk/data" #endif #define RISK_XBM "/risk.xbm" static Region read_region (FILE *); static char *datadir; static Region ter_rg[48]; static Pixmap box[42]; void draw_screen (game *g) { int a, b, x; unsigned int width, height, fheight; Pixmap r_board; char filename[256]; XSizeHints size; long unsigned int bg, fg; datadir = getenv ("RISK_DATADIR"); if (!datadir) datadir = RISK_DATADIR; strcpy (filename, datadir); strcat (filename, RISK_XBM); if (XReadBitmapFile (qd.display, qd.root_window, filename, &width, &height, &r_board, &a, &b) != BitmapSuccess) { perror (filename); exit (0); } fheight = height + MESSAGE_HEIGHT; size.width = width; size.height = fheight; size.min_width = width; size.min_height = fheight; size.max_width = width; size.max_height = fheight; size.flags = USSize | PMinSize | PMaxSize; bg = get_color ("white"); fg = get_color ("black"); g->win = XCreateSimpleWindow (qd.display, qd.root_window, 0, 0, width, fheight, 2, fg, bg); XSetStandardProperties (g->disp, g->win, "Risk", "Risk", None, NULL, 0, &size); XSelectInput (g->disp, g->win, ExposureMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask); g->pix = XCreatePixmap (g->disp, g->win, width, fheight, qd.depth); g->width = width; g->height = height; XMapWindow (g->disp, g->win); XFillRectangle (g->disp, g->pix, g->ClearGC, 0, 0, width, fheight); XCopyPlane (g->disp, r_board, g->pix, g->DrawGC, 0, 0, width, fheight, 0, 0, 1); XDrawLine (g->disp, g->pix, g->DrawGC, 0, height, width, height); XFreePixmap (g->disp, r_board); copy_pixmap (g); for (x = 0; x < 42; x++) { box[x] = XCreatePixmap (qd.display, qd.root_window, BXX, BXY, qd.depth); XCopyArea (g->disp, g->pix, box[x], g->DrawGC, corners[x][0], corners[x][1], BXX, BXY, 0, 0); } g->buttc = 3; g->buttv = (Button *) calloc (sizeof (Button), 3); g->cards_b = b_create (g->win, "Cards", CBX, CBY); g->done_b = b_create (g->win, "Done", DBX, DBY); g->fortify_b = b_create (g->win, "Fortify", FBX, FBY); } void make_regions (game *g) { int x; FILE *f; char buf[255]; message (g, "Hold, creating regions..."); for (x = 1; x <= NUM_REGS; x++) { sprintf (buf, "%s/terr%d", datadir, x); f = fopen (buf, "r"); if (f) { ter_rg[x] = read_region (f); fclose (f); } else { ter_rg[x] = XCreateRegion (); } } } static Region read_region (FILE *f) { Region reg; int a, b, c, d; XRectangle r; reg = XCreateRegion (); while ((fscanf (f, "%d %d %d %d", &a, &b, &c, &d)) != EOF) { r.x = a; r.y = b; r.width = c - a + 1; r.height = d - b + 1; XUnionRectWithRegion (&r, reg, reg); } return reg; } void fill (game *g, char dr, int t) { XRectangle r; XClipBox (ter_rg[t], &r); prepare_fill (g, g->map[t]); XSetRegion (g->disp, g->FillGC, ter_rg[t]); XFillRectangle (g->disp, g->pix, g->FillGC, r.x, r.y, r.width, r.height); if (dr != 'p') XCopyArea (g->disp, g->pix, g->win, g->DrawGC, r.x, r.y, r.width, r.height, r.x, r.y); } void write_armies (game * g, int t) { int x, y, ln; char number[6]; x = corners[t - 1][0]; y = corners[t - 1][1]; if ((g->size)[t] > 0) { XFillRectangle (g->disp, g->pix, g->ClearGC, x, y, BXX, BXY); XDrawRectangle (g->disp, g->pix, g->DrawGC, x, y, BXX, BXY); sprintf (number, "%d", (g->size)[t]); ln = x + (22 - XTextWidth (g->font, number, strlen (number))) / 2; XDrawString (g->disp, g->pix, g->DrawGC, ln, y + 14, number, strlen (number)); } else { XCopyArea (g->disp, box[t - 1], g->pix, g->DrawGC, 0, 0, BXX, BXY, x, y); fill (g, 'p', t); } XCopyArea (g->disp, g->pix, g->win, g->DrawGC, x, y, BXX, BXY, x, y); } int region_of_point (game *g, int x, int y) { int section, country, n; int fheight; fheight = g->height + MESSAGE_HEIGHT; section = (XCOLS * x / g->width) + XCOLS * (YCOLS * y / fheight); for (n = 0; TRUE; n++) { country = countries_in[section][n]; if (country < 0) break; if (XPointInRegion (ter_rg[country], x, y)) return country; } return 0; } void put_name (game * g) { char *player; int d; d = (PNH - g->font->ascent - g->font->descent) / 2; player = g->player[g->p].name; XFillRectangle (g->disp, g->pix, g->ClearGC, PNX, PNY, PNW, PNH); XDrawString (g->disp, g->pix, g->DrawGC, PNX + 7, PNY + g->font->ascent + d, player, strlen (player)); XCopyArea (g->disp, g->pix, g->win, g->DrawGC, PNX, PNY, PNW, PNH, PNX, PNY); colorbar (g); } void colorbar (game * g) { int exists, x, top, height; boolean onbar[MAX_PLAYERS]; XRectangle rect; Region region; rect.x = BRX; rect.y = BRY; rect.width = BRW; rect.height = BRH; region = XCreateRegion (); XUnionRectWithRegion (&rect, region, region); XSetRegion (g->disp, g->FillGC, region); XFillRectangle (g->disp, g->pix, g->ClearGC, BRX+5, BRY+5, BRW-10, BRH-10); exists = 0; for (x = 0; x < MAX_PLAYERS; x++) { onbar[x] = ((g->player[x].playing) && (g->player[x].territories > 0)); if (onbar[x]) exists++; } if (exists == 0) return; top = BRY + 5; height = (BRH - 6) / exists; x = g->p; while (TRUE) { if (onbar[x]) { prepare_fill (g, x); XFillRectangle (g->disp, g->pix, g->FillGC, BRX + 5, top, BRW - 11, height - 6); XDrawRectangle (g->disp, g->pix, g->DrawGC, BRX + 5, top, BRW - 11, height - 6); top += height; } x++; if (x >= MAX_PLAYERS) x = 0; if (x == g->p) break; } XCopyArea (g->disp, g->pix, g->win, g->DrawGC, BRX, BRY, BRW, BRH, BRX, BRY); } void set_invert_region (game * g, int t, XRectangle * rt) { Region boxreg, result; XRectangle r; result = XCreateRegion (); r.x = corners[t - 1][0]; r.y = corners[t - 1][1]; r.width = BXX + 1; r.height = BXY + 1; boxreg = XCreateRegion (); XUnionRectWithRegion (&r, boxreg, boxreg); XSubtractRegion (ter_rg[t], boxreg, result); XSetRegion (g->disp, g->FillGC, result); XSetRegion (g->disp, g->InvertGC, result); XClipBox (result, rt); XDestroyRegion (boxreg); XDestroyRegion (result); } void message (game * g, char *text) { int x, ln; clear_message (g); ln = strlen (text); x = XTextWidth (g->font, text, ln); XDrawString (g->disp, g->pix, g->DrawGC, (g->width - x) / 2, g->height + 10 + g->font->ascent, text, ln); copy_pixmap (g); } void clear_message (game * g) { XFillRectangle (g->disp, g->pix, g->ClearGC, 0, g->height + 1, g->width, MESSAGE_HEIGHT); } void ask (game * g, char *buf, int max) { int x, i, ln; clear_message (g); ln = strlen (buf); x = XTextWidth (g->font, buf, ln); i = XTextWidth (g->font, "w", 1); XDrawString (g->disp, g->pix, g->DrawGC, 3 * i, g->height + 10 + g->font->ascent, buf, ln); copy_pixmap (g); wscanf (g, buf, x + 5 * i, g->height + 10, max); } void handle_expose (game *g, XEvent *event) { int x; for (x = 0; x < g->buttc; x++) if (b_exposed (g->buttv[x], event)) return; copy_pixmap (g); } void copy_pixmap (game *g) { XCopyArea (g->disp, g->pix, g->win, g->DrawGC, 0, 0, g->width, g->height+MESSAGE_HEIGHT, 0, 0); }