home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Format 115
/
af115sub.adf
/
yahzee.lzx
/
yahzee
/
layout.c
< prev
next >
Wrap
C/C++ Source or Header
|
1998-06-03
|
14KB
|
397 lines
/*
* layout.c
* ========
* Handles layout of display.
*
* Copyright (C) 1994-1998 Håkan L. Younes (lorens@hem.passagen.se)
*/
#include <exec/types.h>
#include <graphics/gfxbase.h>
#include "requesters.h"
#include "rules.h"
#include "draw.h"
#include "layout_const.h"
#include "layout.h"
#include <clib/exec_protos.h>
#include <clib/gadtools_protos.h>
#include <clib/graphics_protos.h>
#include <clib/intuition_protos.h>
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
struct TextAttr topaz8 = {
"topaz.font", 8, 0, FPF_ROMFONT
};
extern struct GfxBase *GfxBase;
extern struct TextFont *romfont;
extern char scr_title[];
extern char win_title[];
extern struct Gadget die_gads[];
extern struct Gadget *roll_gad, *disp_gad, *gt_gads;
extern struct NewGadget new_roll_gad, new_disp_gad;
static void
upper_board_extent (
struct rules *rules,
UBYTE num_players,
BOOL split_board,
UWORD font_w,
UWORD font_h,
UWORD *width,
UWORD *height)
{
*width = (upper_label_len (rules) + 3 * num_players) * font_w +
(num_players + 1) * (INTERWIDTH / 2 + LINEWIDTH) + LINEWIDTH;
*height = (num_upper_labels (rules) + 1) *
(font_h + INTERHEIGHT / 2 + LINEHEIGHT) + LINEHEIGHT;
}
static void
lower_board_extent (
struct rules *rules,
UBYTE num_players,
BOOL split_board,
UWORD font_w,
UWORD font_h,
UWORD *width,
UWORD *height)
{
*width = (lower_label_len (rules) + 3 * num_players) * font_w +
(num_players + 1) * (INTERWIDTH / 2 + LINEWIDTH) + LINEWIDTH;
*height = num_lower_labels (rules) *
(font_h + INTERHEIGHT / 2 + LINEHEIGHT) + LINEHEIGHT;
if (split_board)
*height += font_h + INTERHEIGHT / 2 + LINEHEIGHT;
}
static void
gadget_extent (
struct Screen *scr,
struct rules *rules,
UWORD *width,
UWORD *height,
BOOL vert_gads)
{
if (vert_gads)
{
*width = MAX (new_roll_gad.ng_Width, die_gads[0].Width);
*height = rules->num_dice * (die_gads[0].Height + INTERHEIGHT) +
new_roll_gad.ng_Height + new_disp_gad.ng_Height + INTERHEIGHT;
}
else
{
*width = rules->num_dice * (die_gads[0].Width + INTERWIDTH) +
new_roll_gad.ng_Width + new_disp_gad.ng_Width + INTERWIDTH;
*height = MAX (new_roll_gad.ng_Height, die_gads[0].Height);
}
}
BOOL
layout_display (
struct Screen *scr,
struct Window **win,
struct rules *rules,
UBYTE num_players)
{
register UBYTE n;
BOOL done, split_board, board_romfont, vert_gads;
UWORD used_w, used_h;
UWORD board_w[2], board_h[2];
UWORD gadget_w = 0, gadget_h = 0;
done = FALSE;
for (n = 1; n <= 8 && !done; ++n)
{
split_board = !(n & 1);
board_romfont = (n > 4);
vert_gads = (n + 1) / 2 & 1;
upper_board_extent (rules, num_players, split_board,
(board_romfont) ? ROMFONT_WIDTH :
GfxBase->DefaultFont->tf_XSize,
(board_romfont) ? ROMFONT_HEIGHT :
GfxBase->DefaultFont->tf_YSize,
&board_w[0], &board_h[0]);
lower_board_extent (rules, num_players, split_board,
(board_romfont) ? ROMFONT_WIDTH :
GfxBase->DefaultFont->tf_XSize,
(board_romfont) ? ROMFONT_HEIGHT :
GfxBase->DefaultFont->tf_YSize,
&board_w[1], &board_h[1]);
if (split_board)
{
used_w = board_w[0] + board_w[1] - LINEWIDTH;
used_h = MAX (board_h[0], board_h[1]);
}
else
{
used_w = MAX (board_w[0], board_w[1]);
used_h = board_h[0] + board_h[1] - LINEHEIGHT;
}
gadget_extent (scr, rules, &gadget_w, &gadget_h, vert_gads);
if (vert_gads)
{
used_w += gadget_w + 3 * INTERWIDTH + scr->WBorLeft + scr->WBorRight;
used_h = MAX (used_h, gadget_h) + 2 * INTERHEIGHT + scr->WBorTop +
scr->WBorBottom + scr->Font->ta_YSize + 1;
}
else
{
used_w = MAX (used_w, gadget_w) + 2 * INTERWIDTH +
scr->WBorLeft + scr->WBorRight;
used_h += gadget_h + 3 * INTERHEIGHT + scr->WBorTop +
scr->WBorBottom + scr->Font->ta_YSize + 1;
}
if (used_w <= scr->Width && used_h <= scr->Height)
done = TRUE;
}
if (!done)
{
msg_requester (NULL, "Error Message", "OK", "Screen is too small!");
return FALSE;
}
if (board_romfont && romfont == NULL)
{
if (!(romfont = OpenFont (&topaz8)))
{
msg_requester (NULL, "Error Message", "OK",
"Couldn't open topaz.font!");
return FALSE;
}
}
if (*win == NULL)
{
*win = OpenWindowTags (NULL,
WA_Left, (scr->Width - used_w) / 2,
WA_Top, (scr->Height - used_h) / 2,
WA_Width, used_w,
WA_Height, used_h,
WA_AutoAdjust, FALSE,
WA_Activate, TRUE,
WA_CloseGadget, TRUE,
WA_DepthGadget, TRUE,
WA_DragBar, TRUE,
WA_Title, win_title,
WA_ScreenTitle, scr_title,
WA_PubScreen, scr,
WA_NewLookMenus, TRUE,
WA_IDCMP, BUTTONIDCMP | IDCMP_MOUSEBUTTONS |
IDCMP_MENUPICK | IDCMP_CLOSEWINDOW |
IDCMP_REFRESHWINDOW |
IDCMP_CHANGEWINDOW,
TAG_DONE);
}
else
{
struct IntuiMessage *msg;
BOOL done = FALSE;
delete_scoreboard ((*win)->RPort);
delete_gadgets ((*win)->RPort, die_gads);
RemoveGList (*win, die_gads, -1);
FreeGadgets (gt_gads);
ChangeWindowBox (*win,
(used_w > scr->Width - (*win)->LeftEdge) ?
scr->Width - used_w : (*win)->LeftEdge,
(used_h > scr->Height - (*win)->TopEdge) ?
scr->Height - used_h : (*win)->TopEdge,
used_w, used_h);
WaitPort ((*win)->UserPort);
while (!done && (msg = (struct IntuiMessage *)GetMsg ((*win)->UserPort)))
{
done = (msg->Class == IDCMP_CHANGEWINDOW);
ReplyMsg ((struct Message *)msg);
}
}
if (*win == NULL)
{
msg_requester (NULL, "Error Message", "OK", "Couldn't open window!");
return FALSE;
}
for (n = 0; n < rules->num_dice; ++n)
{
die_gads[n].NextGadget = (n == rules->num_dice - 1) ? NULL :
&die_gads[n + 1];
if (vert_gads)
{
die_gads[n].LeftEdge = used_w - (*win)->BorderRight - INTERWIDTH -
gadget_w + (gadget_w - die_gads[n].Width) / 2;
die_gads[n].TopEdge = ((n > 0) ?
die_gads[n - 1].TopEdge + die_gads[n - 1].Height :
(*win)->BorderTop) + INTERHEIGHT;
}
else
{
die_gads[n].LeftEdge = ((n > 0) ?
die_gads[n - 1].LeftEdge + die_gads[n - 1].Width :
(*win)->BorderLeft) + INTERWIDTH;
die_gads[n].TopEdge = used_h - (*win)->BorderBottom - INTERHEIGHT -
gadget_h + (gadget_h - die_gads[n].Height) / 2;
}
die_gads[n].Flags |= GFLG_DISABLED;
}
AddGList (*win, die_gads, -1, -1, NULL);
if (vert_gads)
{
new_roll_gad.ng_LeftEdge = used_w - (*win)->BorderRight - INTERWIDTH -
gadget_w +
(gadget_w - new_roll_gad.ng_Width) / 2;
new_roll_gad.ng_TopEdge = die_gads[n - 1].TopEdge +
die_gads[n - 1].Height + INTERHEIGHT;
new_disp_gad.ng_LeftEdge = new_roll_gad.ng_LeftEdge;
new_disp_gad.ng_TopEdge = new_roll_gad.ng_TopEdge +
new_roll_gad.ng_Height + INTERHEIGHT;
}
else
{
new_roll_gad.ng_LeftEdge = die_gads[n - 1].LeftEdge +
die_gads[n - 1].Width + INTERWIDTH;
new_roll_gad.ng_TopEdge = used_h - (*win)->BorderBottom - INTERHEIGHT -
gadget_h +
(gadget_h - new_roll_gad.ng_Height) / 2;
new_disp_gad.ng_LeftEdge = new_roll_gad.ng_LeftEdge +
new_roll_gad.ng_Width + INTERWIDTH;
new_disp_gad.ng_TopEdge = new_roll_gad.ng_TopEdge;
}
roll_gad = CreateContext (>_gads);
roll_gad = CreateGadget (BUTTON_KIND, roll_gad, &new_roll_gad, TAG_DONE);
disp_gad = CreateGadget (NUMBER_KIND, roll_gad, &new_disp_gad,
GTNM_Number, 3, GTNM_Border, TRUE, TAG_DONE);
if (disp_gad == NULL)
{
msg_requester (NULL, "Error Message", "OK",
"Couldn't create gadgets!");
return FALSE;
}
AddGList (*win, gt_gads, -1, -1, NULL);
RefreshGadgets (die_gads, *win, NULL);
GT_RefreshWindow (*win, NULL);
SetFont ((*win)->RPort, (board_romfont) ? romfont : GfxBase->DefaultFont);
init_board_grid (*win, rules, num_players, split_board);
draw_scoreboard ((*win)->RPort, rules, num_players);
return TRUE;
}
void
init_board_grid (
struct Window *win,
struct rules *rules,
UBYTE num_players,
BOOL split_board)
{
register UBYTE i, j, prev;
UBYTE limit;
limit = num_upper_labels (rules);
upper_board.left = win->BorderLeft + INTERWIDTH;
upper_board.top = win->BorderTop + INTERHEIGHT;
upper_board_extent (rules, num_players, split_board,
win->RPort->TxWidth, win->RPort->TxHeight,
&upper_board.width, &upper_board.height);
lower_board.left = upper_board.left +
((split_board) ? upper_board.width - LINEWIDTH : 0);
lower_board.top = upper_board.top +
((split_board) ? 0 : upper_board.height - LINEHEIGHT);
lower_board_extent (rules, num_players, split_board,
win->RPort->TxWidth, win->RPort->TxHeight,
&lower_board.width, &lower_board.height);
if (!split_board)
{
upper_board.width = MAX (upper_board.width, lower_board.width);
lower_board.width = upper_board.width;
}
board_grid[0][0].left = upper_board.left + LINEWIDTH;
board_grid[0][0].top = upper_board.top + win->RPort->TxHeight +
INTERHEIGHT / 2 + 2 * LINEHEIGHT;
board_grid[0][0].width = INTERWIDTH / 2 +
upper_label_len (rules) * win->RPort->TxWidth;
if (!split_board)
{
board_grid[0][limit].width = INTERWIDTH / 2 +
lower_label_len (rules) * win->RPort->TxWidth;
board_grid[0][0].width = MAX (board_grid[0][0].width,
board_grid[0][limit].width);
}
board_grid[0][0].height = win->RPort->TxHeight + INTERHEIGHT / 2;
for (i = 1; i <= num_players; ++i)
{
board_grid[i][0].left = board_grid[i - 1][0].left +
board_grid[i - 1][0].width + LINEWIDTH;
board_grid[i][0].top = board_grid[0][0].top;
board_grid[i][0].width = 3 * win->RPort->TxWidth + INTERWIDTH / 2;
board_grid[i][0].height = board_grid[0][0].height;
}
prev = 0;
for (j = 1; j < limit; ++j)
{
if (!rules->labels[j])
++limit;
else
{
for (i = 0; i <= num_players; ++i)
{
board_grid[i][j].left = board_grid[i][prev].left;
board_grid[i][j].top = board_grid[i][prev].top +
board_grid[i][prev].height + LINEHEIGHT;
board_grid[i][j].width = board_grid[i][prev].width;
board_grid[i][j].height = board_grid[i][prev].height;
}
prev = j;
}
}
if (split_board)
{
while (!rules->labels[j])
++j;
board_grid[0][j].left = lower_board.left + LINEWIDTH;
board_grid[0][j].top = board_grid[0][0].top;
board_grid[0][j].width = INTERWIDTH / 2 +
lower_label_len (rules) * win->RPort->TxWidth;
board_grid[0][j].height = board_grid[0][0].height;
for (i = 1; i <= num_players; ++i)
{
board_grid[i][j].left = board_grid[i - 1][j].left +
board_grid[i - 1][j].width + LINEWIDTH;
board_grid[i][j].top = board_grid[0][j].top;
board_grid[i][j].width = 3 * win->RPort->TxWidth + INTERWIDTH / 2;
board_grid[i][j].height = board_grid[0][j].height;
}
prev = j;
++j;
}
for (; j < MAX_LABELS; ++j)
{
if (rules->labels[j])
{
for (i = 0; i <= num_players; ++i)
{
board_grid[i][j].left = board_grid[i][prev].left;
board_grid[i][j].top = board_grid[i][prev].top +
board_grid[i][prev].height + LINEHEIGHT;
board_grid[i][j].width = board_grid[i][prev].width;
board_grid[i][j].height = board_grid[i][prev].height;
}
prev = j;
}
}
}