eliot/wxwin/printout.cc
Olivier Teulière b102aafbcd Support for 3 different game modes:
- 'Training' mode: same behaviour as before
  - 'Duplicate' mode: all the players (who can be human players or AI
    players) have the same rack, and the best word is played on the
    board
  - 'Free game' mode: the players (human or AI) have different racks,
    and they play one after another

Status:
  - Core: the main functions are written, but the API could be more
    homogeneous between the different modes.
  - Interfaces: the text interface is almost up-to-date, but the
    wxwindows one only supports Training mode.
  - AI: Currently, AI players always play the best word, which is
    optimal in Duplicate mode but not in FreeGame mode. Other strategies
    will be written in the future.
  - Handling of saved games is broken: a game can be saved and loaded,
    but no information about the mode and the players is stored, so it
    crashes whatever you do after loading the game.
2004-08-07 18:10:42 +00:00

303 lines
8.7 KiB
C++

/* Eliot */
/* Copyright (C) 1999 Antoine Fraboulet */
/* Antoine.Fraboulet@free.fr */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 2 of the License, or */
/* (at your option) any later version. */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program; if not, write to the Free Software */
/* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* $Id: printout.cc,v 1.2 2004/08/07 18:10:42 ipkiss Exp $ */
#include <stdio.h>
#include "ewx.h"
#include "dic.h"
#include "game.h"
#include "configdb.h"
#include "printout.h"
bool
GamePrintout::OnPrintPage(int page)
{
wxDC *dc = GetDC();
if (dc)
{
if (page == 1)
DrawPage(dc);
return TRUE;
}
else
return FALSE;
}
bool
GamePrintout::HasPage(int pageNum)
{
return pageNum == 1;
}
bool
GamePrintout::OnBeginDocument(int startPage, int endPage)
{
if (!wxPrintout::OnBeginDocument(startPage, endPage))
return FALSE;
return TRUE;
}
void
GamePrintout::GetPageInfo(int *minPage, int *maxPage, int *selPageFrom, int *selPageTo)
{
*minPage = 1;
*maxPage = 1;
*selPageFrom = 1;
*selPageTo = 1;
}
void
GamePrintout::SetSpaces(wxString* str, int spaces)
{
size_t i;
wxString strs = "";
if (str->Len() == 0)
return ;
for(i=0; i < (str->Len()-1); i++) {
strs = strs + str->GetChar(i);
strs = strs + wxString(' ',spaces);
}
strs = strs + str->GetChar(str->Len() - 1);
*str = strs;
}
void
GamePrintout::DrawStringJustif(wxDC *dc, wxString *str, long x, long y, long w,
enum Justif justif, int spaces)
{
long wtext,htext;
SetSpaces(str,spaces);
dc->GetTextExtent(*str,&wtext,&htext);
switch (justif)
{
case LEFT:
break;
case CENTER:
x = x + (w - wtext) / 2;
break;
case RIGHT:
x = x + w - wtext;
break;
}
dc->DrawText(*str,x,y);
}
void
GamePrintout::DrawHeadingLine(wxDC *dc, long heightH, float mmToLogical)
{
long i,x,w,y;
wxString str;
x = config.getMarginX() + config.getDxBegin();
y = config.getMarginY() + config.getDyT1();
for(i=0; i<5; i++)
{
w = config.getDxText(i);
str = config.getNameH(i);
DrawStringJustif(dc,&str,
(long) (mmToLogical*x),
(long) (mmToLogical*y),
(long) (mmToLogical*w),
config.getJustifH(i),
config.getSpacesH(i));
x += w + config.getDxEnd() + config.getDxBegin();
}
}
void
GamePrintout::DrawTextLine(wxDC *dc, int numline, long basey, long heightT, float mmToLogical)
{
#define DIM(i) \
x += w + config.getDxEnd() + config.getDxBegin(); \
w = config.getDxText(i)
#define DRW(i) \
DrawStringJustif(dc,&str,(long) (mmToLogical*x), \
(long) (mmToLogical*y), \
(long) (mmToLogical*w), \
config.getJustifT(i), \
config.getSpacesT(i))
//
//
long x,y,w;
char buff[400];
wxString str;
x = config.getMarginX() + config.getDxBegin();
y = basey + config.getDyT1()
+ numline * (config.getDyT1() + heightT + config.getDyT2());
w = config.getDxText(0);
str = "";
// num
if (numline < Game_getnrounds(game)) {
str << (numline + 1);
DRW(0);
}
// rack
DIM(1);
if (numline < Game_getnrounds(game)) {
Game_getplayedrack(game,numline,buff);
str = buff;
DRW(1);
}
// word
DIM(2);
if ((numline > 0) && (numline <= Game_getnrounds(game))) {
Game_getplayedword(game,numline - 1,buff);
str = buff;
DRW(2);
}
// pos
DIM(3);
if ((numline > 0) && (numline <= Game_getnrounds(game))) {
Game_getplayedcoord(game,numline - 1,buff);
str = buff;
DRW(3);
}
// pts
DIM(4);
if ((numline > 0) && (numline <= Game_getnrounds(game))) {
sprintf(buff,"%d",Game_getplayedpoints(game,numline - 1));
str = buff;
DRW(4);
}
// total points
if (numline == Game_getnrounds(game) + 1) {
str << Game_getplayerpoints(game, 0);
DRW(4);
}
#undef DIM
#undef DRW
}
void
GamePrintout::DrawPage(wxDC *dc)
{
/*
* Scaling.
*/
// Get the logical pixels per inch of screen and printer
int dcSizeW, dcSizeH;
int pageWidthPix, pageHeightPix;
int ppiScreenX, ppiScreenY;
int ppiPrinterX, ppiPrinterY;
GetPPIScreen(&ppiScreenX, &ppiScreenY);
GetPPIPrinter(&ppiPrinterX, &ppiPrinterY);
dc->GetSize(&dcSizeW, &dcSizeH);
GetPageSizePixels(&pageWidthPix, &pageHeightPix);
// This scales the DC so that the printout roughly represents the
// the screen scaling. The text point size _should_ be the right size
// but in fact is too small for some reason. This is a detail that will
// need to be addressed at some point but can be fudged for the
// moment.
float scale = (float)((float)ppiPrinterX/(float)ppiScreenX);
// Now we have to check in case our real page size is reduced
// (e.g. because we're drawing to a print preview memory DC)
// If printer pageWidth == current DC width, then this doesn't
// change. But w might be the preview bitmap width, so scale down.
float overallScaleX = scale * (float)(dcSizeW/(float)pageWidthPix);
float overallScaleY = scale * (float)(dcSizeH/(float)pageHeightPix);
dc->SetUserScale(overallScaleX, overallScaleY);
float mmToLogical = (float)(ppiPrinterX/(scale*25.1));
long i,basey;
long heightH, heightT;
wxFont Hfont = config.getFont(PRINTHFONT);
wxFont Tfont = config.getFont(PRINTTFONT);
wxColour *wxBlack = wxTheColourDatabase->FindColour("BLACK");
wxColour *wxWhite = wxTheColourDatabase->FindColour("WHITE");
wxPen *blackPen = wxThePenList->FindOrCreatePen(*wxBlack, 1, wxSOLID);
wxBrush *whiteBrush = wxTheBrushList->FindOrCreateBrush(*wxWhite, wxSOLID);
dc->SetPen(* blackPen);
dc->SetBrush(* whiteBrush);
dc->SetFont(Hfont);
heightH = (long) (dc->GetCharHeight() / mmToLogical);
DrawHeadingLine(dc,heightH,mmToLogical);
basey = config.getMarginY() + config.getDyH1() + heightH + config.getDyH2();
dc->SetFont(Tfont);
heightT = (long) (dc->GetCharHeight() / mmToLogical);
for(i=0; i < (Game_getnrounds(game)+3);i++) {
DrawTextLine(dc,i,basey,heightT,mmToLogical);
}
dc->SetFont(wxNullFont);
DrawGameLines(dc,heightH,heightT,mmToLogical,overallScaleX,overallScaleY);
}
void
GamePrintout::DrawGameLines(wxDC *dc, long heightH, long heightT,
float mmToLogical, float overallScaleX,
float overallScaleY)
{
int i, nTextLines;
long col,lin, StartX, StartY;
long HeadHeight, LineHeight;
long TextStart, TextHeight, TextBottom, TextRight;
float SCALE = config.getPrintLineScale();
dc->SetUserScale(SCALE,SCALE);
nTextLines = Game_getnrounds(game) + 2;
StartX = config.getMarginX();
StartY = config.getMarginY();
HeadHeight = config.getDyH1() + heightH + config.getDyH2();
LineHeight = config.getDyT1() + heightT + config.getDyT2();
TextStart = StartY + HeadHeight;
TextHeight = nTextLines * LineHeight;
TextBottom = TextStart + TextHeight;
//
// columns
//
float scalefactorX = mmToLogical * overallScaleX / SCALE;
float scalefactorY = mmToLogical * overallScaleY / SCALE;
col = StartX;
for(i=0; i<=5; i++) {
dc->DrawLine((long) (col * scalefactorX),
(long) (StartY * scalefactorY),
(long) (col * scalefactorX),
(long) (TextBottom * scalefactorY));
col += i == 5 ? 0 : config.getDxBegin() + config.getDxText(i) + config.getDxEnd();
}
TextRight = col;
//
// rows
//
lin = StartY;
for(i=0; i <= (nTextLines + 1); i++) {
dc->DrawLine((long) (StartX * scalefactorX),
(long) (lin * scalefactorY),
(long) (TextRight * scalefactorX),
(long) (lin * scalefactorY));
lin = StartY + HeadHeight + i * LineHeight;
}
}