
 /* Grafik.c : alles rechnerabhängige */

#include "Adt.h"

#include <exec/memory.h>
#include <intuition/intuitionbase.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#include <libraries/filehandler.h>
#include <clib/intuition_protos.h>
#include <clib/graphics_protos.h>
#include <clib/dos_protos.h>

#include <ctype.h>
#include <stdio.h>
#include <fcntl.h>

//#include <functions.h>

extern void SpielstaerkeAnzeige(void);
extern void DruckeProtokoll();

extern int Spielstaerke;

 /* Library-Base-Pointer: */
struct GfxBase *GfxBase = 0L;
struct IntuitionBase *IntuitionBase = 0L;

struct Screen *scr = 0L;
struct Window *win = 0L;
struct RastPort *rp;
UWORD bline;

 /* Protokoll- und Spielbrett-Datei-Handles: */
struct FileHandle *pfh = 0L;
struct FileHandle *sfh = 0L;

 /* Zeichensatz: */
struct TextAttr font =
  { (STRPTR)"topaz.font", TOPAZ_EIGHTY, FS_NORMAL, FPF_ROMFONT };

struct NewScreen ns =
  { 0, 0, 640, 256, 1, 0, 1, HIRES, CUSTOMSCREEN, &font, (UBYTE *)
  "chss v1.1", NULL, NULL };
struct NewWindow nw =
  { 0, 11, 640, 245, 0, 1, CLOSEWINDOW | MOUSEBUTTONS | RAWKEY, WINDOWCLOSE |
  SMART_REFRESH | ACTIVATE | RMBTRAP, NULL, NULL, (UBYTE *)"Spielbrett - <F1> - <F3> ändert Spielstärke, <F5> druckt Protokoll aus",
  NULL, NULL, 0, 0, 0, 0, CUSTOMSCREEN };

 /* Lade-Fenster: */
struct NewWindow nwl =
  { 89, 90, 462, 87, 0, 1, GADGETUP, SMART_REFRESH | ACTIVATE, NULL,
  NULL, (UBYTE *)"Spielnamen eingeben", NULL, NULL, 0, 0, 0, 0,
  CUSTOMSCREEN };
unsigned char strbuf[25];
struct StringInfo str4 =
  { strbuf, NULL, 0, 25, 0, 0, 0, 25, 0, 0, NULL, 0, NULL };
struct Gadget gad4 =
  { NULL, 131, 48, 200, 8, GADGHCOMP, RELVERIFY | STRINGCENTER, STRGADGET,
  NULL, NULL, NULL, 0, (APTR)&str4, 4, NULL };

 /* Sicherheitsabfrage-Fenster: */
struct NewWindow nws =
  { 175, 73, 290, 109, 0, 1, GADGETUP, SMART_REFRESH | ACTIVATE | RMBTRAP,
  NULL, NULL, (UBYTE *)"Sicherheitsabfrage", NULL, NULL, 0, 0, 0, 0,
  CUSTOMSCREEN };
struct Gadget gad1 =
  { NULL, 20, 38, 70, 60, GADGHCOMP, RELVERIFY, BOOLGADGET, NULL, NULL,
  NULL, 0, NULL, 1, NULL };
struct Gadget gad2 =
  { NULL, 110, 38, 70, 60, GADGHCOMP, RELVERIFY, BOOLGADGET, NULL, NULL,
  NULL, 0, NULL, 2, NULL };
struct Gadget gad3 =
  { NULL, 200, 38, 70, 60, GADGHCOMP, RELVERIFY, BOOLGADGET, NULL, NULL,
  NULL, 0, NULL, 3, NULL };

 /* Schachfigurenbilder: */
USHORT *bilder = 0L;
USHORT rohbilder[ 720 ] = {
   /* wbauer auf weiss: */
  0xffff, 0xffff, 0xff00, 0xffff, 0xffff, 0xff00, 0xffff, 0xffff, 0xff00,
  0xffff, 0xffff, 0xff00, 0xffff, 0xffff, 0xff00, 0xffff, 0xffff, 0xff00,
  0xffff, 0x03ff, 0xff00, 0xfffe, 0xfdff, 0xff00, 0xfffd, 0xfcff, 0xff00,
  0xfffe, 0xfdff, 0xff00, 0xffff, 0x7bff, 0xff00, 0xffff, 0x7bff, 0xff00,
  0xfffe, 0xfdff, 0xff00, 0xfffd, 0xfe7f, 0xff00, 0xfffb, 0xffbf, 0xff00,
  0xffe7, 0xff9f, 0xff00, 0xffcf, 0xffcf, 0xff00, 0xffc0, 0x000f, 0xff00,
  0xffff, 0xffff, 0xff00, 0xffff, 0xffff, 0xff00,
   /* wspringer auf weiss: */
  0xffff, 0xffff, 0xff00, 0xffff, 0xffff, 0xff00, 0xfffc, 0x007f, 0xff00,
  0xfff1, 0xff3f, 0xff00, 0xff8f, 0x9f07, 0xff00, 0xff9f, 0xff7f, 0xff00,
  0xffc0, 0x7f1f, 0xff00, 0xffff, 0xbf4f, 0xff00, 0xffff, 0x3f7f, 0xff00,
  0xfffe, 0x7f1f, 0xff00, 0xfffc, 0xfee7, 0xff00, 0xfffd, 0xfeff, 0xff00,
  0xfffb, 0xff7f, 0xff00, 0xfff3, 0xff3f, 0xff00, 0xfff7, 0xffbf, 0xff00,
  0xffef, 0xff9f, 0xff00, 0xffcf, 0xffcf, 0xff00, 0xffc0, 0x000f, 0xff00,
  0xffff, 0xffff, 0xff00, 0xffff, 0xffff, 0xff00,
   /* wlaeufer auf weiss: */
  0xffff, 0xffff, 0xff00, 0xffff, 0xffff, 0xff00, 0xffff, 0xe3ff, 0xff00,
  0xffff, 0x1bff, 0xff00, 0xffff, 0x773f, 0xff00, 0xffff, 0x743f, 0xff00,
  0xffff, 0x717f, 0xff00, 0xffff, 0x7e7f, 0xff00, 0xffff, 0x7eff, 0xff00,
  0xffff, 0x7eff, 0xff00, 0xfffe, 0x7cff, 0xff00, 0xfffd, 0xfcff, 0xff00,
  0xfffd, 0xfeff, 0xff00, 0xfffb, 0xff7f, 0xff00, 0xfff3, 0xff3f, 0xff00,
  0xfff7, 0xffbf, 0xff00, 0xffef, 0xff9f, 0xff00, 0xffe0, 0x001f, 0xff00,
  0xffff, 0xffff, 0xff00, 0xffff, 0xffff, 0xff00,
   /* wturm auf weiss: */
  0xffff, 0xffff, 0xff00, 0xffff, 0xffff, 0xff00, 0xfff9, 0x227f, 0xff00,
  0xfff9, 0x227f, 0xff00, 0xfffa, 0xdd7f, 0xff00, 0xfffb, 0xff7f, 0xff00,
  0xfffb, 0xff7f, 0xff00, 0xfffb, 0xff7f, 0xff00, 0xfffb, 0xff7f, 0xff00,
  0xfffb, 0xff7f, 0xff00, 0xfffb, 0xff7f, 0xff00, 0xfffb, 0xff7f, 0xff00,
  0xfffb, 0xff7f, 0xff00, 0xfffb, 0xff7f, 0xff00, 0xfff3, 0xff3f, 0xff00,
  0xfff7, 0xffbf, 0xff00, 0xffef, 0xff9f, 0xff00, 0xffe0, 0x001f, 0xff00,
  0xffff, 0xffff, 0xff00, 0xffff, 0xffff, 0xff00,
   /* wdame auf weiss: */
  0xffff, 0xffff, 0xff00, 0xffff, 0xffff, 0xff00, 0xfff9, 0xf39f, 0xff00,
  0xfffc, 0x621f, 0xff00, 0xfffc, 0x817f, 0xff00, 0xfffe, 0xfeff, 0xff00,
  0xfffe, 0x3dff, 0xff00, 0xffff, 0xbdff, 0xff00, 0xffff, 0xb9ff, 0xff00,
  0xffff, 0xbbff, 0xff00, 0xffff, 0xb9ff, 0xff00, 0xffff, 0x19ff, 0xff00,
  0xfffe, 0x44ff, 0xff00, 0xfff8, 0xfe7f, 0xff00, 0xfff3, 0xff3f, 0xff00,
  0xfff7, 0xffbf, 0xff00, 0xffef, 0xff9f, 0xff00, 0xffe0, 0x001f, 0xff00,
  0xffff, 0xffff, 0xff00, 0xffff, 0xffff, 0xff00,
   /* wkoenig auf weiss: */
  0xffff, 0xffff, 0xff00, 0xffff, 0xcfff, 0xff00, 0xffff, 0x03ff, 0xff00,
  0xffff, 0xcfff, 0xff00, 0xffff, 0xcfff, 0xff00, 0xfffe, 0x01ff, 0xff00,
  0xffff, 0x7bff, 0xff00, 0xfffe, 0x79ff, 0xff00, 0xfffe, 0xfdff, 0xff00,
  0xfffe, 0xfcff, 0xff00, 0xfffc, 0x30ff, 0xff00, 0xfffd, 0x8eff, 0xff00,
  0xfff9, 0xfeff, 0xff00, 0xfff9, 0xfe7f, 0xff00, 0xfff2, 0x013f, 0xff00,
  0xfff7, 0xffbf, 0xff00, 0xffef, 0xff9f, 0xff00, 0xffe0, 0x001f, 0xff00,
  0xffff, 0xffff, 0xff00, 0xffff, 0xffff, 0xff00,
   /* wbauer auf schwarz: */
  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  0x0000, 0xfc00, 0x0000, 0x0001, 0xfe00, 0x0000, 0x0003, 0xff00, 0x0000,
  0x0001, 0xfe00, 0x0000, 0x0000, 0xfc00, 0x0000, 0x0000, 0xfc00, 0x0000,
  0x0001, 0xfe00, 0x0000, 0x0003, 0xff80, 0x0000, 0x0007, 0xffc0, 0x0000,
  0x001f, 0xffe0, 0x0000, 0x003f, 0xfff0, 0x0000, 0x003f, 0xfff0, 0x0000,
  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
   /* wspringer auf schwarz: */
  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0003, 0xff80, 0x0000,
  0x000f, 0xffc0, 0x0000, 0x007f, 0x9ff8, 0x0000, 0x007f, 0xff80, 0x0000,
  0x003f, 0xffe0, 0x0000, 0x0000, 0x7fb0, 0x0000, 0x0000, 0xff80, 0x0000,
  0x0001, 0xffe0, 0x0000, 0x0003, 0xff18, 0x0000, 0x0003, 0xff00, 0x0000,
  0x0007, 0xff80, 0x0000, 0x000f, 0xffc0, 0x0000, 0x000f, 0xffc0, 0x0000,
  0x001f, 0xffe0, 0x0000, 0x003f, 0xfff0, 0x0000, 0x003f, 0xfff0, 0x0000,
  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
   /* wlaeufer auf schwarz: */
  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1c00, 0x0000,
  0x0000, 0xfc00, 0x0000, 0x0000, 0xf8c0, 0x0000, 0x0000, 0xfbc0, 0x0000,
  0x0000, 0xff80, 0x0000, 0x0000, 0xff80, 0x0000, 0x0000, 0xff00, 0x0000,
  0x0000, 0xff00, 0x0000, 0x0001, 0xff00, 0x0000, 0x0003, 0xff00, 0x0000,
  0x0003, 0xff00, 0x0000, 0x0007, 0xff80, 0x0000, 0x000f, 0xffc0, 0x0000,
  0x000f, 0xffc0, 0x0000, 0x001f, 0xffe0, 0x0000, 0x001f, 0xffe0, 0x0000,
  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
   /* wturm auf schwarz: */
  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0006, 0xdd80, 0x0000,
  0x0006, 0xdd80, 0x0000, 0x0007, 0xff80, 0x0000, 0x0007, 0xff80, 0x0000,
  0x0007, 0xff80, 0x0000, 0x0007, 0xff80, 0x0000, 0x0007, 0xff80, 0x0000,
  0x0007, 0xff80, 0x0000, 0x0007, 0xff80, 0x0000, 0x0007, 0xff80, 0x0000,
  0x0007, 0xff80, 0x0000, 0x0007, 0xff80, 0x0000, 0x000f, 0xffc0, 0x0000,
  0x000f, 0xffc0, 0x0000, 0x001f, 0xffe0, 0x0000, 0x001f, 0xffe0, 0x0000,
  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
   /* wdame auf schwarz: */
  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0006, 0x0c60, 0x0000,
  0x0003, 0x9de0, 0x0000, 0x0003, 0xff80, 0x0000, 0x0001, 0xff00, 0x0000,
  0x0001, 0xfe00, 0x0000, 0x0000, 0x7e00, 0x0000, 0x0000, 0x7e00, 0x0000,
  0x0000, 0x7c00, 0x0000, 0x0000, 0x7e00, 0x0000, 0x0000, 0xde00, 0x0000,
  0x0001, 0xc700, 0x0000, 0x0007, 0xff80, 0x0000, 0x000f, 0xffc0, 0x0000,
  0x000f, 0xffc0, 0x0000, 0x001f, 0xffe0, 0x0000, 0x001f, 0xffe0, 0x0000,
  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
   /* wkoenig auf schwarz: */
  0x0000, 0x0000, 0x0000, 0x0000, 0x3000, 0x0000, 0x0000, 0xfc00, 0x0000,
  0x0000, 0x3000, 0x0000, 0x0000, 0x3000, 0x0000, 0x0001, 0xfe00, 0x0000,
  0x0000, 0xfc00, 0x0000, 0x0001, 0xfe00, 0x0000, 0x0001, 0xfe00, 0x0000,
  0x0001, 0xff00, 0x0000, 0x0003, 0x3300, 0x0000, 0x0003, 0x8f00, 0x0000,
  0x0007, 0xff00, 0x0000, 0x0007, 0xff80, 0x0000, 0x000e, 0x01c0, 0x0000,
  0x000f, 0xffc0, 0x0000, 0x001f, 0xffe0, 0x0000, 0x001f, 0xffe0, 0x0000,
  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 };
struct Image bild = { 0, 0, 40, 20, 1, 0, 1, 0, 0 };

 /* für NotierZug und NotierAdd: */
int zuege = -1, nfarbe = schwarz;


OeffneDisplay()
{
    int i, j;

     /* Speicher für Bilder der Schachfiguren: */
    if(( bilder = (USHORT *)AllocMem( 2880L, MEMF_CHIP )) == 0L ) {
        SchliesseDisplay(); exit( 1 );
    }
    for( i=0; i<360; i++ ) {
        *(bilder+i) = rohbilder[ i ];
        *(bilder+i+360) = rohbilder[ i+360 ];
        *(bilder+i+720) = ~rohbilder[ i+360 ];
        *(bilder+i+1080) = ~rohbilder[ i ];
    }

     /* Libraries öffnen: */
    if(( GfxBase = (struct GfxBase *)
      OpenLibrary( "graphics.library", 0L )) == 0L ) {
        SchliesseDisplay(); exit( 1 );
    }
    if(( IntuitionBase = (struct IntuitionBase *)
      OpenLibrary( "intuition.library", 0L )) == 0L ) {
        SchliesseDisplay(); exit( 1 );
    }

     /* Screen und Window öffnen: */
    if(( scr = OpenScreen( &ns )) == 0L ) {
        SchliesseDisplay(); exit( 1 );
    }
    nw.Screen = scr;
    if(( win = OpenWindow( &nw )) == 0L ) {
        SchliesseDisplay(); exit( 1 );
    }
    rp = win->RPort;
    bline = rp->TxBaseline;

     /* Spielbrett umrahmen: */
    HLinie( 44, 20, 383 );      VLinie( 382, 20, 189 );
    HLinie( 383, 189, 44 );     VLinie( 44, 189, 20 );
    HLinie( 48, 22, 379 );      VLinie( 378, 22, 187 );
    HLinie( 379, 187, 48 );     VLinie( 48, 187, 22 );
    HLinie( 52, 24, 375 );      VLinie( 374, 24, 185 );
    HLinie( 375, 185, 52 );     VLinie( 52, 185, 24 );

    HLinie( 24, 212, 383 );     HLinie( 24, 214, 383 );
    HLinie( 24, 231, 383 );     HLinie( 24, 233, 383 );
    for( i=0; i<4; i++ )
        HLinie( 64 + i*80, 213, 103 + i*80 );
    for( i=0; i<5; i++ )
        HLinie( 24 + i*80, 232, 63 + i*80 );
    Move( rp, 76L, (long)219+bline );
    Text( rp, "Dezember '92 von Robert Junghans", 32L );

    VLinie( 404, 22, 181 );     VLinie( 408, 22, 181 );
    VLinie( 610, 22, 181 );     VLinie( 614, 22, 181 );
    for( i=0; i<4; i++ ) {
        VLinie( 406, 22 + i*40, 41 + i*40 );
        VLinie( 612, 42 + i*40, 61 + i*40 );
    }
    Move( rp, 474L, (long)20+bline );
    Text( rp, "Zugliste:", 9L );

    VLinie( 404, 194, 233 );    VLinie( 408, 194, 233 );
    VLinie( 610, 194, 233 );    VLinie( 614, 194, 233 );
    VLinie( 406, 194, 213 );    VLinie( 612, 214, 233 );
    Move( rp, 478L, (long)196+bline );
    Text( rp, "Zuginfo:", 8L );
}

ZeichneBrett( s, fa )
    Figur s[ 9 ][ 9 ];
    Farbe fa;
{
    static char buchst[ 2 ][ 9 ] = { "hgfedcba", "abcdefgh" };
    static char zahl[ 2 ][ 9 ]   = { "12345678", "87654321" };
    int ufarw, i, j;
    Feld fe;

     /* Spielfeldbezeichnungen am Rand: */
    ufarw = fa == weiss;
    for( i=0; i<8; i++ ) {
        Move( rp, 28L, (long)31 + i*20 + bline );
        Text( rp, &(zahl[ ufarw ][ i ]), 1L );
        Move( rp, (long)70 + i*40, (long)194+bline );
        Text( rp, &(buchst[ ufarw ][ i ]), 1L );
    }

     /* indiv. Umrahmung des Spielbrettes: */
    SetAPen( rp, (long)ufarw );
    HLinie( 94, 21, 133 );      HLinie( 174, 21, 213 );
    HLinie( 254, 21, 293 );     HLinie( 334, 21, 381 );
    VLinie( 380, 21, 44 );      VLinie( 380, 65, 84 );
    VLinie( 380, 105, 124 );    VLinie( 380, 145, 164 );
    HLinie( 333, 188, 294 );    HLinie( 253, 188, 214 );
    HLinie( 173, 188, 134 );    HLinie( 93, 188, 46 );
    VLinie( 46, 188, 165 );     VLinie( 46, 144, 125 );
    VLinie( 46, 104, 85 );      VLinie( 46, 64, 45 );
    SetAPen( rp, (long)!ufarw );
    HLinie( 46, 21, 93 );       HLinie( 134, 21, 173 );
    HLinie( 214, 21, 253 );     HLinie( 294, 21, 333 );
    VLinie( 380, 45, 64 );      VLinie( 380, 85, 104 );
    VLinie( 380, 125, 144 );    VLinie( 380, 165, 188 );
    HLinie( 381, 188, 334 );    HLinie( 293, 188, 254 );
    HLinie( 213, 188, 174 );    HLinie( 133, 188, 94 );
    VLinie( 46, 164, 145 );     VLinie( 46, 124, 105 );
    VLinie( 46, 84, 65 );       VLinie( 46, 44, 21 );
    SetAPen( rp, 1L );

     /* Spielbrett mit Figuren zeichnen: */
    for( i=1; i<=8; i++ )
        for( j=1; j<=8; j++ ) {
            fe = i << 4 | j;
            ZeichneFigur( s[ i ][ j ], fe, fa );
        }
}

struct Ereignis * WarteEreignis( s, fa, sp )
    Figur s[ 9 ][ 9 ];
    Farbe fa;
    Special sp;
{
    static struct Ereignis e;
    struct IntuiMessage *msg;
    Feld feld1, feld;
    ULONG class,code;
    SHORT x, y;
    int sx, sy, fx, fy, ok;
    Figur merk;

    feld1 = 0;
    while( 1 ) {
         /* eine Message holen: */
        while(( msg = (struct IntuiMessage *)GetMsg( win->UserPort )) == 0L )
            Wait( 1L << win->UserPort->mp_SigBit );
        class = msg->Class;
        code = msg->Code;
        x = msg->MouseX;
        y = msg->MouseY;
        ReplyMsg( msg );

        if( class & CLOSEWINDOW ) {
            e.ereignistyp = ende;
            return( &e );
        } else if( class & RAWKEY ) {
          /*
           * F1 bis F3 ändert die Spielstärke
           */
          if( code >= 0x50 && code <= 0x52 ) {
            /*
             * OK, liegt im Bereich
             */
            Spielstaerke=2+(code-0x50);
            if( Spielstaerke < 2 )
              Spielstaerke=2;
            if( Spielstaerke > 4 )
              Spielstaerke=4;
            SpielstaerkeAnzeige();
          } else if( code == 0x54 ) {
            /*
             * Ausdrucken
             */
            DruckeProtokoll();
          }
        } else { /* kann nur MOUSEBUTTONS sein */
             /* Feldkoordinaten ermitteln: */
            if( fa == weiss) {
                fx = (x-14)/40; fy = (204-y)/20;
            } else {
                fx = (413-x)/40; fy = (y-5)/20;
            }

             /* prüfen, ob halbwegs annehmbar geklickt: */
            if( fx >= 1 && fx <= 8 && fy >= 1 && fy <= 8 ) {
                feld = fx << 4 | fy;
                 /* ist es das zweite Klicken und 'ordentlicher' Zug? */
                if( feld1 && ZugOK( s, feld1, feld, sp ) ) {

                     /* prüfen, ob Spieler nicht ins Schach zieht: */
                    sx = feld1 >> 4;    sy = feld1 & yposmask;
                    merk = s[ fx ][ fy ];
                    s[ fx ][ fy ] = s[ sx ][ sy ];
                    s[ sx ][ sy ] = leer;
                    ok = !IstSchach( s, fa, 0, sp );
                    s[ sx ][ sy ] = s[ fx ][ fy ];
                    s[ fx ][ fy ] = merk;

                    if( ok ) { /* prima Zug, wird genommen */
                        e.ereignistyp = zugs;
                        e.zug.figur = s[ sx ][ sy ];
                        e.zug.start = feld1;
                        e.zug.ziel = feld;
                        return( &e );
                    }
                } else /* vielleicht das erste Klicken */
                    if( (s[ fx ][ fy ] & farbmask) == fa)
                        feld1 = feld;
            }
        }
    }
}

WillLaden( s, sp )
    Figur s[ 9 ][ 9 ];
    Special *sp;
{
    struct Window *winl;
    struct RastPort *rpl;
    struct IntuiMessage *msg;
    unsigned char sbuf[36], pbuf[35];

    nwl.Screen = scr;
    if(( winl = OpenWindow( &nwl )) == 0L )
	return 0;
    rpl = winl->RPort;

    Move( rpl, 23L, (long)21+bline );
    Text( rpl, "Geben Sie bitte einen Namen für das zu ladende Spiel", 52L );
    Move( rpl, 15L, (long)29+bline );
    Text( rpl, "bzw. unter dem das Spiel gespeichert werden soll, ein:", 54L );
    Move( rpl, 130L, 47L );	Draw( rpl, 331L, 47L );
    Draw( rpl, 331L, 56L );	Draw( rpl, 130L, 56L );
    Draw( rpl, 130L, 47L );
    Move( rpl, 45L, (long)67+bline );
    Text( rpl, "<Return> = neues Spiel, kein Speichern erwünscht.", 49L );
    AddGadget( winl, &gad4, -1L );
    Delay( 10L );
    ActivateGadget( &gad4, winl, NULL );

     /* auf die Return-Taste warten: */
    while(( msg = (struct IntuiMessage *)GetMsg( winl->UserPort )) == 0L )
	Wait( 1L << winl->UserPort->mp_SigBit );
    ReplyMsg( msg );
    CloseWindow( winl );

     /* MessagePort-queue des 'Haupt'-Windows leeren: */
    while( msg = (struct IntuiMessage *)GetMsg( win->UserPort ) )
	ReplyMsg( msg );

     /* kein Name? */
    if( !strcmp( strbuf, "" ) )
	return 0;

    strcpy( sbuf, strbuf );	strcat( sbuf, ".spielbrett" );
    strcpy( pbuf, strbuf );	strcat( pbuf, ".protokoll" );
    if( pfh = Open( pbuf, MODE_OLDFILE ) ) {
	if( sfh = Open( sbuf, MODE_OLDFILE ) ) {
	    LadeBrett( s, sp );
	    Seek( pfh, 0L, OFFSET_END );
	    return 1;
	} else {
	    Close( pfh );
	    pfh = 0L;
	    return 0;
	}
    } else {
	if( pfh = Open( pbuf, MODE_NEWFILE ) ) {
	    if( sfh = Open( sbuf, MODE_NEWFILE ) ) {
		return 0;
	    } else {
		Close( pfh );
		pfh = 0L;
		return 0;
	    }
	}
    }
}

WillBeenden( s, sp )
    Figur s[ 9 ][ 9 ];
    Special sp;
{
    struct Window *wins;
    struct RastPort *rps;
    struct IntuiMessage *msg;
    USHORT id;

     /* Window öffnen: */
    nws.Screen = scr;
    if(( wins = OpenWindow( &nws )) == 0L )
        return 1;
    rps = wins->RPort;

    Move( rps, 29L, (long)20+bline );
    Text( rps, "Wollen Sie das Spiel beenden?", 29L );
    Move( rps, 20L, 38L );      Draw( rps, 89L, 38L );
    Draw( rps, 89L, 97L );      Draw( rps, 20L, 97L );
    Draw( rps, 20L, 38L );      Move( rps, 200L, 38L );
    Draw( rps, 269L, 38L );     Draw( rps, 269L, 97L );
    Draw( rps, 200L, 97L );     Draw( rps, 200L, 38L );
    Move( rps, 47L, (long)64+bline );   Text( rps, "ja", 2L );
    Move( rps, 227L, (long)64+bline );  Text( rps, "nö", 2L );
    AddGadget( wins, &gad1, -1L );
    AddGadget( wins, &gad3, -1L );

    if( pfh ) {
	Move( rps, 110L, 38L );	    Draw( rps, 179L, 38L );
	Draw( rps, 179L, 97L );	    Draw( rps, 110L, 97L );
	Draw( rps, 110L, 38L );
	Move( rps, 117L, (long)64+bline );  Text( rps, "sichern", 7L );
        AddGadget( wins, &gad2, -1L );
    }

     /* auf Entscheidung warten: */
    while(( msg = (struct IntuiMessage *)GetMsg( wins->UserPort )) == 0L )
        Wait( 1L << wins->UserPort->mp_SigBit );
    id = ((struct Gadget *)msg->IAddress)->GadgetID;
    ReplyMsg( msg );
    CloseWindow( wins );

     /* MessagePort-queue des 'Haupt'-Windows leeren: */
    while( msg = (struct IntuiMessage *)GetMsg( win->UserPort ) )
        ReplyMsg( msg );

     /* evtl. Spielbrett sichern: */
    if( id == 2 )
        SicherBrett( s, sp );

    return( id == 1 );
}

SicherBrett( s, sp )
    Figur s[ 9 ][ 9 ];
    Special sp;
{
    int i, j;

    Seek( sfh, 0L, OFFSET_BEGINNING );
    for( i=1; i<=8; i++ )
	for( j=1; j<=8; j++ )
	    Write( sfh, &s[ i ][ j ], (long)sizeof( Figur ) );
    Write( sfh, &sp, (long)sizeof( Special ) );
    Write( sfh, &zuege, (long)sizeof(int) );
}

LadeBrett( s, sp )
    Figur s[ 9 ][ 9 ];
    Special *sp;
{
    int i, j;

    Seek( sfh, 0L, OFFSET_BEGINNING );
    for( i=1; i<=8; i++ )
	for( j=1; j<=8; j++ )
	    Read( sfh, &s[ i ][ j ], (long)sizeof( Figur ) );
    Read( sfh, sp, (long)sizeof( Special ) );
    Read( sfh, &zuege, (long)sizeof(int) );
}

SchliesseDisplay()
{
     /* Window und Screen schliessen: */
    if( win )
        CloseWindow( win );
    if( scr )
        CloseScreen( scr );

     /* Libraries schliessen: */
    if( IntuitionBase )
        CloseLibrary( IntuitionBase );
    if( GfxBase )
        CloseLibrary( GfxBase );

     /* Dateien schliessen: */
    if( pfh )
	Close( pfh );
    if( sfh )
	Close( sfh );

     /* Speicher für Bilder freigeben: */
    if( bilder )
        FreeMem( bilder, 2880L );
}

ZeichneFigur( fi, fe, fa )
    Figur fi;
    Feld fe;
    Farbe fa;
{
    int hgrunds;
    int px, py, x, y;

     /* Bildschirmposition und Spielbrettfarbe: */
    px = fe >> 4;
    py = fe & yposmask;
    hgrunds = px + py & 1 ? 0 : 1;
    if( fa == weiss ) {
        x = 14 + px*40; y = 185 - py*20;
    } else {
        x = 374 - px*40; y = 5 + py*20;
    }

    if( fi == leer ) {
        SetAPen( rp, (long)!hgrunds );
        RectFill( rp, (long)x, (long)y, (long)x+39, (long)y+19 );
        SetAPen( rp, 1L );
    } else {
        bild.ImageData = bilder + (fi & farbmask)*90 + hgrunds*360 +
          ((fi & figmask)-1)*60;
        DrawImage( rp, &bild, (long)x, (long)y );
    }
}

BlinkFeld( fe, fa )
    Feld fe;
    Farbe fa;
{
    int fx, fy, x, y, i;

     /* Bildschirmposition: */
    fx = fe >> 4;
    fy = fe & yposmask;
    if( fa == weiss ) {
        x = 14+fx*40; y = 185-fy*20;
    } else {
        x = 374-fx*40; y = 5+fy*20;
    }

    SetDrMd( rp, JAM1 | COMPLEMENT );
    for( i=0; i<4; i++ ) {
        RectFill( rp, (long)x+2, (long)y+1, (long)x+37, (long)y+18 );
        if( i < 3 )
            Delay( 15L );
    }
    SetDrMd( rp, JAM1 );
}

NotierZug( str )
    char *str;
{
    char num[ 5 ];

    nfarbe = (nfarbe == weiss) ? schwarz : weiss;
    if( nfarbe == weiss ) {
        zuege ++;
        sprintf( num, "%3d.", zuege+1 );
        if( zuege >= 19 ) {
            ClipBlit( rp, 410L, 40L, rp, 410L, 32L, 200L, 144L, (long)0xc0 );
            SetAPen( rp, 0L );
            RectFill( rp, 410L, 176L, 609L, 183L );
            SetAPen( rp, 1L );
            Move( rp, 420L, (long)176+bline );
            Text( rp, num, 4L );
            Move( rp, 462L, (long)176+bline );
        } else {
            Move( rp, 420L, (long)32+zuege*8+bline );
            Text( rp, num, 4L );
            Move( rp, 462L, (long)32+zuege*8+bline );
        }
	if( pfh ) {
	    Write( pfh, "\n", 1L );
	    Write( pfh, num, 4L );
	    Write( pfh, "   ", 3L );
	}
    } else {
        if( zuege >= 18 )
            Move( rp, 536L, (long)176+bline );
        else
            Move( rp, 536L, (long)32+zuege*8+bline );
	if( pfh )
	    Write( pfh, "\t       ", 8L );
    }

    Text( rp, str, (long)strlen(str) );
    if( pfh )
	Write( pfh, str, (long)strlen(str) );
}

NotierAdd( str )
    char *str;
{
    int x, y;

    x = (nfarbe == weiss) ? 510 : 584;
    y = (zuege >= 18) ? 176 : 32+zuege*8;

    Move( rp, (long)x, (long)y+bline );
    Text( rp, str, (long)strlen(str) );
    if( pfh )
	Write( pfh, str, (long)strlen(str) );
}

ZeichneStat( s, zs )
    Figur s[ 9 ][ 9 ];
    struct Zugstat *zs;
{
    char line1[ 25 ], line2[ 25 ], line3[ 25 ];

    if( zs ) { /* neue Statistik: */
        sprintf( line1, "%7ld Züge in %2ld:%2ld,%2ld", zs->knoten,
          zs->zeit/6000, zs->zeit/100%60, zs->zeit%100 );
        if( (zs->zeit/100%60) < 10 ) line1[ 19 ] = '0';
        if( (zs->zeit%100) < 10 )    line1[ 22 ] = '0';
        sprintf( line2, "ca. %5d Züge/Sekunde",
          (int)(zs->knoten*100/zs->zeit) );
        sprintf( line3, "Wertung f. weiss: %-5d", zs->wertung );

        Move( rp, 414L, (long)208+bline );  Text( rp, line1, 24L );
        Move( rp, 422L, (long)216+bline );  Text( rp, line2, 22L );
        Move( rp, 418L, (long)224+bline );  Text( rp, line3, 23L );
    } else { /* alte Statistik löschen: */
        SetAPen( rp, 0L );
        RectFill( rp, 414L, 208L, 605L, 231L );
        SetAPen( rp, 1L );
    }
}

HLinie( xvon, yvon, xbis )
    int xvon, yvon, xbis;
{
    Move( rp, (long)xvon, (long)yvon );
    Draw( rp, (long)xbis, (long)yvon );
}

VLinie( xvon, yvon, ybis )
    int xvon, yvon, ybis;
{
     /* doppelte Strichstärke wg. HIRES */
    Move( rp, (long)xvon, (long)yvon );
    Draw( rp, (long)xvon, (long)ybis );
    Move( rp, (long)xvon+1, (long)yvon );
    Draw( rp, (long)xvon+1, (long)ybis );
}

Zeit( zeit )
    long *zeit;
{
    static long stamp1[ 3 ];
    long stamp2[ 3 ];

    if( zeit ) { /* Stoppuhr stoppen, Zeit ermitteln: */
        DateStamp( stamp2 );
        *zeit = (stamp2[ 0 ]-stamp1[ 0 ])*8640000L +
          (stamp2[ 1 ]-stamp1[ 1 ])*6000 + (stamp2[ 2 ]-stamp1[ 2 ])*2;
    } else /* Stoppuhr starten: */
        DateStamp( stamp1 );
}

struct Knoten * GibKnoten()
{
    return( AllocMem( (long)sizeof( struct Knoten ), 0L ) );
}

NimmKnoten( k )
    struct Knoten *k;
{
    FreeMem( k, (long)sizeof( struct Knoten ) );
}

extern int Spielstaerke;

static char dummybuf[100];

void SpielstaerkeAnzeige()
{
  strcpy(dummybuf,"chss V1.1a - Spielstärke: ");
  if( Spielstaerke == 2 )
    strcat( dummybuf,"Einfach (geht schnell)");
  else if( Spielstaerke == 3 )
    strcat( dummybuf,"Mittel (dauert länger)");
  else
    strcat( dummybuf,"Schwer (Geduld ist gefragt)");

  SetWindowTitles( win, -1, dummybuf );
}

void DruckeProtokoll()
{
  BOOL Abort=FALSE;
  char zeichen;

  if( pfh ) {
    FILE *druck=fopen("prt:","w");
    if( druck ) {
      Seek( pfh, 0L, OFFSET_BEGINNING );
	  while( (Read( pfh, &zeichen, 1) > 0) && Abort==FALSE )
	    if( fwrite(&zeichen,1,1,druck) != 1 )
	      Abort=TRUE;
      Seek( pfh, 0L, OFFSET_END );
      fclose( druck );
    }
  }
}
