Subversion Repositories Kolibri OS

Rev

Rev 4652 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1805 yogev_ezra 1
#define BUILD_RUS
2
#ifndef __MENUET__
3
#include 
4
#include 
5
#include 
6
#include 
7
#include 
8
#else
9
#include 
10
#include 
11
using namespace Menuet;
12
#define strlen StrLen
13
#define strcpy StrCopy
14
#define memcpy MemCopy
15
#include 
16
const unsigned dectab[] = { 1000000000, 100000000, 10000000, 1000000, 100000,
17
                   10000, 1000, 100, 10, 0 };
18
int sprintf( char *Str, char* Format, ... )
19
{
20
        int i, fmtlinesize, j, k, flag;
21
        unsigned head, tail;
22
        char c;
23
        va_list arglist;
24
        //
25
        va_start(arglist, Format);
26
 
27
        //
28
        fmtlinesize = strlen( Format );
29
        //
30
        if( fmtlinesize == 0 ) return 0;
31
 
32
        //
33
        for( i = 0, j = 0; i < fmtlinesize; i++ )
34
        {
35
                //
36
                c = Format[i];
37
                //
38
                if( c != '%' )
39
                {
40
                        Str[j++] = c;
41
                        continue;
42
                }
43
                //
44
                i++;
45
                //
46
                if( i >= fmtlinesize ) break;
47
 
48
                //
49
                flag = 0;
50
                //
51
                c = Format[i];
52
                if (c == 'l') c = Format[++i];
53
                //
54
                switch( c )
55
                {
56
                //
57
                case '%':
58
                        Str[j++] = c;
59
                        break;
60
                //  
61
                case 's':
62
                        char* str;
63
                        str = va_arg(arglist, char*);
64
                        for( k = 0; ( c = str[k] ) != 0; k++ )
65
                        {
66
                                Str[j++] = c;
67
                        }
68
                        break;
69
                //  
70
                case 'c':
71
                        Str[j++] = va_arg(arglist, int) & 0xFF;
72
                        break;
73
                //      
74
                case 'u':
75
                case 'd':
76
                        head = va_arg(arglist, unsigned);
77
                        for( k = 0; dectab[k] != 0; k++ )
78
                        {
79
                                tail = head % dectab[k];
80
                                head /= dectab[k];
81
                                c = head + '0';
82
                                if( c == '0' )
83
                                {
84
                                        if( flag ) Str[j++] = c;
85
                                }
86
                                else
87
                                {
88
                                        flag++;
89
                                        Str[j++] = c;
90
                                }
91
                                //
92
                                head = tail;
93
                        }
94
                        //
95
                        c = head + '0';
96
                        Str[j++] = c;
97
                        break;
98
                default:
99
                        break;
100
                }
101
        }
102
        //
103
        Str[j] = 0;
104
        return j;
105
}
106
int isdigit(int c)
107
{
108
	return (c>='0' && c<='9');
109
}
110
int atoi(const char* string)
111
{
112
	int res=0;
113
	int sign=0;
114
	const char* ptr;
115
	for (ptr=string; *ptr && *ptr<=' ';ptr++);
116
	if (*ptr=='-') {sign=1;++ptr;}
117
	while (*ptr >= '0' && *ptr <= '9')
118
	{
119
		res = res*10 + *ptr++ - '0';
120
	}
121
	if (sign) res = -res;
122
	return res;
123
}
124
int islower(int c)
125
{
126
	return (c>='a' && c<='z');
127
}
128
int abs(int n)
129
{
130
	return (n<0)?-n:n;
131
}
132
int memcmp(const void* buf1, const void* buf2, unsigned count)
133
{
134
	const char* ptr1 = (const char*)buf1;
135
	const char* ptr2 = (const char*)buf2;
136
	unsigned i=0;
137
	while (i
138
	if (i==count)
139
		return 0;
140
	else if (*ptr1<*ptr2)
141
		return -1;
142
	else
143
		return 1;
144
}
145
void strncpy(char* dest, const char* source, unsigned len)
146
{
147
	char* ptr1 = dest;
148
	const char *ptr2 = source;
149
	for (;len-- && *ptr2; *ptr1++=*ptr2++) ;
150
}
151
unsigned int rand_data[4];
152
 
153
void randomize()
154
{
155
	rand_data[0] = (unsigned int)Clock();
156
	rand_data[1] = (unsigned int)GetPackedTime();
157
	rand_data[2] = (unsigned int)GetPackedDate();
158
	rand_data[3] = (unsigned int)0xA3901BD2 ^ GetPid();
159
}
160
 
161
unsigned int rand()
162
{
163
	rand_data[0] ^= _HashDword(rand_data[3] + 0x2835C013U);
164
	rand_data[1] += _HashDword(rand_data[0]);
165
	rand_data[2] -= _HashDword(rand_data[1]);
166
	rand_data[3] ^= _HashDword(rand_data[2]);
167
	return rand_data[3];
168
}
169
 
170
#define random(k)  (rand() % (k))
171
#define floor Floor
172
double fabs(double x)
173
{
174
	__asm	fld	x
175
	__asm	fabs
176
}
177
#define M_PI       3.14159265358979323846
178
double cos(double x)
179
{
180
	__asm	fld	x
181
	__asm	fcos
182
}
183
double sin(double x)
184
{
185
	__asm	fld	x
186
	__asm	fsin
187
}
188
/*inline void printf(const char* format, ...)
189
{}*/
190
#define printf /* nothing */
191
inline void strcat(char* str1, const char* str2)
192
{strcpy(str1+strlen(str1),str2);}
193
int strncmp(const char* str1, const char* str2, unsigned len)
194
{
195
	for (;len--;)
196
	{
197
		if (*str1 != *str2) break;
198
		if (*str1 == 0)
199
			return 0;
200
		++str1;++str2;
201
	}
202
	if (len==(unsigned)-1)
203
		return 0;
204
	if (*str1 < *str2)
205
		return -1;
206
	return 1;
207
}
208
#define clock Clock
209
typedef unsigned int clock_t;
210
#define CLOCKS_PER_SEC 100
211
#define XK_Left		0xB0
212
#define XK_Right	0xB3
213
#define XK_Up		0xB2
214
#define XK_Down		0xB1
215
#define XK_Return	0x0D
216
#define XK_space	0x20
217
#define XK_Escape	0x1B
218
#define XK_less		'<'
219
#define XK_comma	','
220
#define XK_period	'.'
221
#define XK_greater	'>'
222
#define XK_minus	'-'
223
#define XK_equal	'='
224
#define XK_underscore	'_'
225
#define XK_plus		'+'
226
#define XK_Delete	0xB6
227
#define XK_F8		0x39
228
#define XK_l		'l'
229
#define XK_L		'L'
230
#define XK_F2		0x33
231
#define XK_s		's'
232
#define XK_S		'S'
233
#define XK_slash	'/'
234
#define XK_question	'?'
235
#define XK_n		'n'
236
#define XK_N		'N'
237
#define XK_t		't'
238
#define XK_T		'T'
239
#define XK_r		'r'
240
#define XK_R		'R'
241
#define XK_b		'b'
242
#define XK_B		'B'
243
#define XK_f		'f'
244
#define XK_F		'F'
245
#define assert(a) /* nothing */
246
#include "qsort.c"
247
#endif
248
#include "gr-draw.h"
249
#include "board.h"
250
#include "player.h"
251
#include "buttons.h"
252
#include "sysproc.h"
253
 
254
char *strskipref(char *s1, char *s2)
255
{
256
  int L = strlen(s2);
257
  if (strncmp(s1, s2, L) == 0) return s1 + L;
258
  else return 0;
259
}
260
 
261
class TPlayArray
262
{
263
public:
264
  TPlayArray(int d = 10) : play(0), nplay(0), mplay(0) {}
265
  ~TPlayArray() {Clear();}
266
 
267
  void Clear();
268
  void Add(const PlayWrite &pl);
269
  PlayWrite &operator[](int i) {return play[i];}
270
  int GetNPlay() const {return nplay;}
271
#ifndef __MENUET__
272
  int OpenFile(const char *name, int kind);
273
  int MsgOpenFile(const char *name, int kind);
274
  int SaveFile(const char *name, int num, int kind);
275
  int MsgSaveFile(const char *name, int num, int kind);
276
#endif
277
  void Del(int n);
278
protected:
279
  void Extend(int n = -1);
280
 
281
  PlayWrite *play;
282
  int nplay, mplay;
283
protected:
284
#ifndef __MENUET__
285
  static const char *const search[];
286
  static int AnalizeKind(FILE *f, const int w[], const char *smb = 0);
287
  static int ReadFileTo(FILE *f, char c);
288
  static int ReadFileTo(FILE *f, const char *c);
289
  static int ReadTheText(FILE *f, const char *s);
290
#endif
291
};
292
 
293
#ifndef __MENUET__
294
const char *const TPlayArray::search[] =
295
     {"checkers-", "play:", "text", "bin_1.0\n", "history_", "1.0", "1.1"};
296
#endif
297
 
298
void TPlayArray::Clear()
299
{
300
  if (play) delete[] play;
301
  play = 0; nplay = 0; mplay = 0;
302
}
303
 
304
void TPlayArray::Extend(int n)
305
{
306
  if (n < 0) n = nplay + 1;
307
  if (mplay < n)
308
  {
309
    PlayWrite *p_old = play;
310
    int m_old = mplay;
311
    mplay = n * 2;
312
    play = new PlayWrite[mplay];
313
    if (p_old)
314
    {
315
      for (int i = 0; i < m_old; i++) play[i] = p_old[i];
316
      delete[] p_old;
317
    }
318
  }
319
}
320
 
321
void TPlayArray::Add(const PlayWrite &pl)
322
{
323
  Extend();
324
  play[nplay] = pl;
325
  nplay++;
326
}
327
 
328
#ifndef __MENUET__
329
int TPlayArray::AnalizeKind(FILE *f, const int w[], const char *smb)
330
{
331
  int i, L, was1 = 1;
332
  unsigned char ch;
333
  int fnd[NELEM(search)];
334
  for (i = 0; i < NELEM(search); i++) fnd[i] = 1;
335
  for (L = 0; was1; L++)
336
  {
337
    was1 = 0;
338
    if (fread(&ch, 1, 1, f) != 1) return (L == 0) ? -2 : -1;
339
    for (i = 0; w[i] >= 0; i++) if (fnd[i])
340
    {
341
      if (tolower(ch) != tolower(search[w[i]][L])) fnd[i] = 0;
342
      else
343
      {
344
        was1 = 1;
345
        if (search[w[i]][L+1] == 0)
346
        {
347
          if (smb && smb[0] && fread(&ch, 1, 1, f) == 1)
348
          {
349
            ungetc(ch, f);
350
            if (strchr(smb, tolower(ch)) || isalpha(ch) && strchr(smb, toupper(ch)))
351
            {
352
              break;
353
            }
354
          }
355
          return i;
356
        }
357
      }
358
    }
359
  }
360
  return -10 - L;
361
}
362
 
363
int TPlayArray::ReadFileTo(FILE *f, char c)
364
{
365
  char ch;
366
  do
367
  {
368
    if (fread(&ch, 1, 1, f) != 1) return 0;
369
  }
370
  while(ch != c);
371
  return 1;
372
}
373
 
374
int TPlayArray::ReadFileTo(FILE *f, const char *c)
375
{
376
  char ch;
377
  do
378
  {
379
    if (fread(&ch, 1, 1, f) != 1) return 0;
380
  }
381
  while(!strchr(c, ch));
382
  return 1;
383
}
384
 
385
int TPlayArray::ReadTheText(FILE *f, const char *s)
386
{
387
  char ch;
388
  while (*s)
389
  {
390
    if (fread(&ch, 1, 1, f) != 1 || ch != *s) return 0;
391
    s++;
392
  }
393
  return 1;
394
}
395
 
396
int TPlayArray::OpenFile(const char *name, int kind)
397
{
398
  int k_fnd = 0;
399
  FILE *f = fopen(name, "rb");
400
  if (!f) return -1;
401
  if (kind == -1)
402
  {
403
    const int w[] = {0, -1};
404
    int r = AnalizeKind(f, w);
405
    if (r >= 0) {kind = w[r]; k_fnd = 1;}
406
    else if (r == -11) {kind = 3; k_fnd = 3;}
407
    else {fclose(f); return (kind == -2) ? -2 : -10;}
408
  }
409
  if (kind == 0)
410
  {
411
    if (k_fnd < 1 && !ReadFileTo(f, '-')) {fclose(f); return -10;}
412
    k_fnd = 1;
413
    const int w[] = {1, 4, -1};
414
    int r = AnalizeKind(f, w);
415
    if (r >= 0) {kind = w[r]; k_fnd = 2;}
416
    else {fclose(f); return -10;}
417
  }
418
  if (kind == 1)
419
  {
420
    if (k_fnd < 2 && !ReadFileTo(f, ':')) {fclose(f); return -10;}
421
    k_fnd = 2;
422
    const int w[] = {2, 3, -1};
423
    int r = AnalizeKind(f, w);
424
    if (r >= 0) {kind = w[r]; k_fnd = 3;}
425
    else {fclose(f); return -10;}
426
  }
427
  if (kind == 4)
428
  {
429
    if (k_fnd < 2 && !ReadFileTo(f, '_')) {fclose(f); return -10;}
430
    k_fnd = 2;
431
    const int w[] = {5, 6, -1};
432
    int r = AnalizeKind(f, w, ".1234567890");
433
    if (r >= 0) {kind = w[r]; k_fnd = 3;}
434
    else {fclose(f); return -10;}
435
  }
436
  if (kind == 5) {kind = 3; k_fnd = 0;}
437
  if (kind == 6)
438
  {
439
    if (!ReadFileTo(f, "\n\r")) {fclose(f); return -4;}
440
    k_fnd = 3;
441
    PlayWrite *pl = 0;
442
    int np = THistory::HRead(f, pl);
443
    if (np > 0 && pl)
444
    {
445
      int i;
446
      Extend(nplay + np);
447
      for (i = 0; i < np; i++)
448
      {
449
        if (pl[i].GetN() >= 3) play[nplay++] = pl[i];
450
      }
451
    }
452
    if (pl) delete[] pl;
453
    fclose(f);
454
    return 1;
455
  }
456
  if (kind == 2)
457
  {
458
    printf("kind = 2\n");
459
    unsigned char ch;
460
    do
461
    {
462
      if (fread(&ch, 1, 1, f) != 1) {fclose(f); return -10;}
463
    }
464
    while(!isspace(ch));
465
    PlayWrite pl;
466
    char word[101];
467
    int i, kind = 0;
468
    for (;;)
469
    {
470
      do
471
      {
472
        if (fread(&ch, 1, 1, f) != 1) break;
473
      }
474
      while(ch == 0 || isspace(ch));
475
      if (feof(f)) strcpy(word, "[end]");
476
      else
477
      {
478
        i = 0;
479
        while(ch != 0 && !isspace(ch))
480
        {
481
          if (i < 100) word[i++] = ch;
482
          if (fread(&ch, 1, 1, f) != 1) break;
483
        }
484
        word[i] = 0;
485
      }
486
      if (word[0] != '[')
487
      {
488
        if (kind == 1)
489
        {
490
          if (word[0] != '#' && word[0] != '$' && word[0] != '%')
491
          {
492
            Position pos;
493
            pos.Read(word, 1);
494
            pl.Clear();
495
            pl.Add(0, pos);
496
            kind = 2;
497
          }
498
        }
499
        else if (kind == 2)
500
        {
501
          if (word[0] != '#' && word[0] != '$' && word[0] != '%')
502
          {
503
            for (i = 0; word[i] && word[i] != '.' && word[i] != ','; i++)
504
            {
505
              if (!isdigit((unsigned char)word[i])) {i = -1; break;}
506
            }
507
            if (i == -1)
508
            {
509
              PlayWrite::PMv pmv;
510
              if (pl.GetPosL(pmv.pos) < 0) kind = 3;
511
              else if (!pmv.pos.ReadMv(pmv.mv, word, 1)) kind = 3;
512
              else if (pl.Add(pmv.mv) != 0) kind = 3;
513
            }
514
          }
515
        }
516
      }
517
      else
518
      {
519
        if (kind == 2 || kind == 3)
520
        {
521
          if (pl.GetN() > 0) Add(pl);
522
          pl.Clear();
523
        }
524
        kind = 0;
525
        for (i = 0; word[i]; i++)
526
        {
527
          word[i] = (char)tolower((unsigned char)word[i]);
528
        }
529
        if (strskipref(word, "[end]")) break;
530
        else if (strskipref(word, "[play_v1.1]")) kind = 1;
531
      }
532
    }
533
    fclose(f);
534
    return 1;
535
  }
536
  if (kind == 3)
537
  {
538
    char ch[LEN_WPOS];
539
    if (k_fnd < 3 && !ReadFileTo(f, '\n')) {fclose(f); return -10;}
540
    k_fnd = 3;
541
    do
542
    {
543
      PlayWrite pl;
544
      for (;;)
545
      {
546
        int i;
547
        for (i = 0; i < LEN_WPOS; i++)
548
        {
549
          if (fread(ch + i, 1, 1, f) != 1 || ch[i] < 0) break;
550
        }
551
        if (i < LEN_WPOS) break;
552
        PlayWrite::PMv pmv0, pmv1;
553
        pmv1.pos.Read(ch);
554
        pmv1.pos.Reverse();
555
        if (pl.GetPMvL(pmv0) >= 0)
556
        {
557
          TComputerPlayer::Z z;
558
          z.FindAllMoves(pmv0);
559
          int r;
560
          for (r = 0; r < z.narr; r++)
561
          {
562
            if (memcmp(z.array[r].pos.SH, pmv1.pos.SH, sizeof(pmv1.pos.SH)) == 0)
563
            {
564
              pmv1 = z.array[r];
565
              break;
566
            }
567
          }
568
          if (r < z.narr) pl.Add(pmv1);
569
          else {fclose(f); return -3;}
570
        }
571
        else pl.Add(0, pmv1.pos);
572
      }
573
      if (pl.GetN() > 0) Add(pl);
574
    }
575
    while(!feof(f));
576
    fclose(f);
577
    return 1;
578
  }
579
  fclose(f);
580
  return -10;
581
}
582
 
583
int TPlayArray::MsgOpenFile(const char *name, int kind)
584
{
585
  int n0 = nplay, no_games = 0;
586
  int r = OpenFile(name, kind);
587
  if (r <= 0)
588
  {
589
    if (r == -1)
590
    {
591
#ifdef BUILD_RUS
592
      printf("\n誨:    䠩 \"%s\".\n", name);
593
#else
594
      printf("\nCheckers: Can't open the file \"%s\".\n", name);
595
#endif
596
      return 0;
597
    }
598
    else if (r == -2)
599
    {
600
#ifdef BUILD_RUS
601
      printf("\n誨:  \"%s\" .\n", name);
602
#else
603
      printf("\nCheckers: The file \"%s\" is empty.\n", name);
604
#endif
605
      return 0;
606
    }
607
    else if (r == -3)
608
    {
609
#ifdef BUILD_RUS
610
      printf("\n誨:  \"%s\" 訡.\n", name);
611
#else
612
      printf("\nCheckers: Invalid file \"%s\".\n", name);
613
#endif
614
      return 0;
615
    }
616
    else if (r == -4) no_games = 1;
617
    else if (r == -10)
618
    {
619
#ifdef BUILD_RUS
620
      printf("\n誨:  \"%s\"   ⨯.\n", name);
621
#else
622
      printf("\nCheckers: The file \"%s\" has wrong type.\n", name);
623
#endif
624
      return 0;
625
    }
626
    else
627
    {
628
#ifdef BUILD_RUS
629
      printf("\n誨: 訡  䠩 \"%s\".\n", name);
630
#else
631
      printf("\nCheckers: Error openning the file \"%s\".\n", name);
632
#endif
633
      return 0;
634
    }
635
  }
636
  if (!no_games && nplay > n0) return 1;
637
  else
638
  {
639
#ifdef BUILD_RUS
640
    printf("\n誨:  \"%s\"  ᮤন .\n", name);
641
#else
642
    printf("\nCheckers: File \"%s\" don't contains games.\n", name);
643
#endif
644
    return 0;
645
  }
646
}
647
 
648
int TPlayArray::SaveFile(const char *name, int num, int kind)
649
{
650
  FILE *f = 0;
651
  if (kind == 0 || kind == 1 || kind == 2)
652
  {
653
    f = fopen(name, "wt");
654
    if (!f) return -1;
655
    fprintf(f, "checkers-play:text\n");
656
    int i0 = num, i;
657
    if (num < 0) {i0 = 0; num = nplay-1;}
658
    for (i = i0; i <= num; i++) if (play[i].GetN() > 0)
659
    {
660
      PlayWrite::PMv pmv;
661
      if (play[i].GetPos(pmv.pos, 0) < 0) return -9;
662
      char *str = new char[10 + NUM_CELL];
663
      if (!str) return -5;
664
      pmv.pos.Write(str, 1);
665
      fprintf(f, "\n[Play_v1.1]#%d  %s\n", i - i0 + 1, str);
666
      delete[] str;
667
      int j;
668
      for (j = 1; j < play[i].GetN(); j++)
669
      {
670
        if (play[i].GetPos(pmv.pos, j - 1) < 0) return -9;
671
        if (play[i].GetMove(pmv.mv, j) < 0) return -9;
672
        str = new char[pmv.pos.GetLenMvEx(pmv.mv, 11)];
673
        if (!str) return -5;
674
        pmv.pos.WriteMvEx(pmv.mv, str, 11);
675
        if (j % 2 == 1)
676
        {
677
          int nbytes = fprintf(f, "%d. ", (j + 1) / 2);
678
          while(nbytes++ < 5) fprintf(f, " ");
679
        }
680
        fprintf(f, "%s", str);
681
        if (j % 2 == 0 || j == play[i].GetN() - 1) fprintf(f, "\n");
682
        else fprintf(f, " ,\t");
683
        delete[] str;
684
      }
685
    }
686
    fclose(f);
687
    return 1;
688
  }
689
  else if (kind == -1 || kind == 3)
690
  {
691
    f = fopen(name, "wb");
692
    if (!f) return -1;
693
    if (kind == 3) fprintf(f, "checkers-play:bin_1.0\n");
694
    int i = num;
695
    if (num < 0) {i = 0; num = nplay-1;}
696
    for (; i <= num; i++)
697
    {
698
      char ch[LEN_WPOS];
699
      Position pos;
700
      play[i].GetPosL(pos);
701
      if (!pos.AllCanEat() && !pos.AllCanMove())
702
      {
703
        ch[0] = (pos.wmove == 0) ? char(-3) : char(-1);
704
      }
705
      else ch[0] = char(-2);
706
      fwrite(ch, 1, 1, f);
707
      int j;
708
      for (j = 0; j < play[i].GetN(); j++)
709
      {
710
        Position pos;
711
        play[i].GetPos(pos, j);
712
        pos.Reverse();
713
        pos.Write(ch);
714
        fwrite(ch, LEN_WPOS, 1, f);
715
      }
716
    }
717
    fclose(f);
718
    return 1;
719
  }
720
  if (f) fclose(f);
721
  return -10;
722
}
723
 
724
int TPlayArray::MsgSaveFile(const char *name, int num, int kind)
725
{
726
  int r = SaveFile(name, num, kind);
727
  if (r <= 0)
728
  {
729
    if (r == -1)
730
    {
731
#ifdef BUILD_RUS
732
      printf("\n誨:    䠩 \"%s\"  .\n", name);
733
#else
734
      printf("\nCheckers: Can't open the file \"%s\" to write.\n", name);
735
#endif
736
    }
737
    else if (r == -5)
738
    {
739
#ifdef BUILD_RUS
740
      printf("\n誨:  筮   ࠭ 䠩 \"%s\".\n", name);
741
#else
742
      printf("\nCheckers: Not enough memory to save the file \"%s\".\n", name);
743
#endif
744
    }
745
    else if (r == -10)
746
    {
747
#ifdef BUILD_RUS
748
      printf("\n誨:  \"%s\"   ⨯.\n", name);
749
#else
750
      printf("\nCheckers: The file \"%s\" has wrong type.\n", name);
751
#endif
752
    }
753
    else
754
    {
755
#ifdef BUILD_RUS
756
      printf("\n誨: 訡 ࠭ 䠩 \"%s\".\n", name);
757
#else
758
      printf("\nCheckers: Error saving the file \"%s\".\n", name);
759
#endif
760
    }
761
    return 0;
762
  }
763
  else
764
  {
765
#ifdef BUILD_RUS
766
    printf("\n誨:  \"%s\" ࠭.\n", name);
767
#else
768
    printf("\nCheckers: File \"%s\" saved.\n", name);
769
#endif
770
    return 1;
771
  }
772
}
773
#endif
774
 
775
void TPlayArray::Del(int n)
776
{
777
  if (!play || n < 0 || n >= nplay) return;
778
  else if (nplay <= 1) {Clear(); return;}
779
  int i;
780
  for (i = n; i < nplay - 1; i++) play[i] = play[i+1];
781
  play[nplay - 1].Clear();
782
  nplay--;
783
}
784
 
785
 
786
void SetPlayerString(char *str, int c, TChPlayer *p)
787
{
788
  strcpy(str, c ? "blue: " : "red: ");
789
  if (!p) strcat(str, "input");
790
  else strcat(str, "computer");
791
}
792
 
793
class TMainDraw : public TSomeDraw
794
{
795
public:
796
  TMainDraw() : undo_redo(0), ur_type(-1), cur_play(0),
797
                def_savefile("save.che"), def_savekind(2) {InitButton();}
798
 
799
  virtual void Draw(TGraphDraw *drw, int w, int h)
800
  {
801
    int d = button.GetDelt();
802
    int hh = button.GetHeight(w - 2*d);
803
    if (hh != 0) hh += d;
804
    drw->SetColor(drw->GetBlackColor());
805
    button.Draw(drw, d, h - hh, w - 2*d);
806
  }
807
 
808
  virtual void DrawB(TGraphDraw *drw, TChBoard &board)
809
  {
810
    int urt = (board.GetCurMoveN() <= 0) +
811
            2*(board.GetCurMoveN() >= board.GetNumMove());
812
    if (ur_type != urt) SetButtonKind(board);
813
    Draw(drw, board.GetW(), board.GetH());
814
  }
815
 
816
  virtual TIntPoint GetDSize(int w, int h)
817
  {
818
    int d = button.GetDelt();
819
    int hh = button.GetHeight(w - 2*d);
820
    if (hh != 0) hh += d;
821
    return TIntPoint(0, hh);
822
  }
823
 
824
  virtual int ButtonPnt(int xp, int yp, int w, int h, int &n, int k = 0)
825
  {
826
    int d = button.GetDelt();
827
    int hh = button.GetHeight(w - 2*d);
828
    if (hh != 0) hh += d;
829
    return button.ButtonPnt(xp - d, yp - (h - hh), w - 2*d, n, k);
830
  }
831
 
832
  void InitButton();
833
  void SetButtonKind(const TChBoard &board);
834
  void PressUR(int n, TChBoard &board, TGraphDraw *drw);
835
  void PressLS(int n, TChBoard &board, TGraphDraw *drw);
836
  void CurPlayNorm()
837
  {
838
    if (cur_play < 0 || cur_play >= play.GetNPlay()) cur_play = 0;
839
  }
840
 
841
  TXButtonArray button;
842
  TMultiButton *undo_redo, *play_list;
843
  char player_str[2][50], play_num[2][10];
844
  TPlayArray play;
845
  int cur_play;
846
  char *def_savefile;
847
  int def_savekind;
848
protected:
849
  int ur_type;
850
};
851
 
852
void TMainDraw::InitButton()
853
{
854
  button.Add(1, 80, 22, "new game");
855
  button.Add(6, 60, 22, "list");
856
  button.Add(7, 60, 22, "delete");
857
  play_list = new TMultiButton(20);
858
  play_list->a.Add(26, 20, 22, "1");
859
  play_list->a.Add(21, 20, 22, "-");
860
  play_list->a.Add(23, 37, 22, play_num[0], -2);
861
  play_list->a.Add(22, 20, 22, "+");
862
  play_list->a.Add(27, 37, 22, play_num[1]);
863
  play_list->SetDefW();
864
  button.Add(play_list);
865
  button.Add(24, 50, 22, "clear");
866
#ifndef __MENUET__
867
  button.Add(25, 50, 22, "save");
868
#endif
869
  button.Add(2, 120, 22, player_str[0]);
870
  button.Add(3, 120, 22, player_str[1]);
871
  button.Add(4, 110, 22, "rotate board");
872
  undo_redo = new TMultiButton(10);
873
  undo_redo->a.Add(11, 27, 22, "<<");
874
  undo_redo->a.Add(12, 20, 22, "<");
875
  undo_redo->a.Add(15, 20, 22, "^");
876
  undo_redo->a.Add(13, 20, 22, ">");
877
  undo_redo->a.Add(14, 27, 22, ">>");
878
  undo_redo->SetDefW();
879
  button.Add(undo_redo);
880
  button.Add(5, 60, 22, "exit");
881
}
882
 
883
void TMainDraw::SetButtonKind(const TChBoard &board)
884
{
885
  int thick;
886
  TextButton *txb;
887
  TXButton *bt1;
888
  ur_type = 0;
889
  SetPlayerString(player_str[0], 0, board.GetPlayer(0));
890
  SetPlayerString(player_str[1], 1, board.GetPlayer(1));
891
  int is_drw = !board.GetPViewStatus();
892
  bt1 = button.GetButton(2);
893
  if (bt1) bt1->drw = is_drw;
894
  bt1 = button.GetButton(3);
895
  if (bt1) bt1->drw = is_drw;
896
  if (board.GetCurMoveN() <= 0) {ur_type++; thick = 0;}
897
  else thick =  3;
898
//  txb = dynamic_cast(undo_redo->a.GetButton(11));
899
//  if (txb) txb->thick = thick;
900
//  txb = dynamic_cast(undo_redo->a.GetButton(12));
901
//  if (txb) txb->thick = thick;
902
// we can use simple static cast
903
	((TextButton*)(undo_redo->a.GetButton(11)))->thick = thick;
904
	((TextButton*)(undo_redo->a.GetButton(12)))->thick = thick;
905
  if (board.GetCurMoveN() >= board.GetNumMove()) {ur_type += 2; thick = 0;}
906
  else thick = 3;
907
//  txb = dynamic_cast(undo_redo->a.GetButton(13));
908
//  if (txb) txb->thick = thick;
909
//  txb = dynamic_cast(undo_redo->a.GetButton(14));
910
//  if (txb) txb->thick = thick;
911
	((TextButton*)(undo_redo->a.GetButton(13)))->thick = thick;
912
	((TextButton*)(undo_redo->a.GetButton(14)))->thick = thick;
913
  if (board.GetCurMoveN() < board.GetNumMove() ||
914
     (board.GetPViewStatus() && board.GetGameEnd() <= 0))
915
  {
916
    thick = 3;
917
  }
918
  else thick = 0;
919
//  txb = dynamic_cast(undo_redo->a.GetButton(15));
920
//  if (txb) txb->thick = thick;
921
	((TextButton*)(undo_redo->a.GetButton(15)))->thick = thick;
922
  if (play.GetNPlay() == 0) is_drw = 1;
923
  bt1 = button.GetButton(6);
924
  if (bt1) bt1->drw = is_drw;
925
  bt1 = button.GetButton(7);
926
  if (bt1) bt1->drw = !is_drw;
927
#ifndef __MENUET__
928
  bt1 = button.GetButton(25);
929
  if (bt1) bt1->drw = !is_drw;
930
#endif
931
  is_drw = board.GetPViewStatus() && play.GetNPlay() > 1;
932
  bt1 = button.GetButton(20);
933
  if (bt1) bt1->drw = is_drw;
934
  bt1 = button.GetButton(24);
935
  if (bt1) bt1->drw = is_drw;
936
  if (is_drw)
937
  {
938
    play_num[0][0] = 0; play_num[1][0] = 0;
939
    if (cur_play >= 0) sprintf(play_num[0], "%d", cur_play + 1);
940
    sprintf(play_num[1], "%d", play.GetNPlay());
941
    thick = (cur_play <= 0) ? 0 : 3;
942
#define dynamic_cast static_cast
943
    txb = dynamic_cast(play_list->a.GetButton(21));
944
    if (txb) txb->thick = thick;
945
    txb = dynamic_cast(play_list->a.GetButton(26));
946
    if (txb) txb->thick = thick;
947
    thick = (cur_play >= play.GetNPlay() - 1) ? 0 : 3;
948
    txb = dynamic_cast(play_list->a.GetButton(22));
949
    if (txb) txb->thick = thick;
950
    txb = dynamic_cast(play_list->a.GetButton(27));
951
    if (txb) txb->thick = thick;
952
#undef dynamic_cast
953
  }
954
}
955
 
956
void TMainDraw::PressUR(int n, TChBoard &board, TGraphDraw *drw)
957
{
958
  int mv;
959
  if (n == 11) mv = 0;
960
  else if (n == 12) mv = board.GetCurMoveN() - 1;
961
  else if (n == 13) mv = board.GetCurMoveN() + 1;
962
  else mv = board.GetNumMove();
963
  if (board.SetCurMoveN(mv))
964
  {
965
    SetButtonKind(board);
966
    if (drw && drw->IsDraw())
967
    {
968
      drw->DrawClear();
969
      board.Draw(drw);
970
    }
971
  }
972
  else Draw(drw, board.GetW(), board.GetH());
973
}
974
 
975
void TMainDraw::PressLS(int n, TChBoard &board, TGraphDraw *drw)
976
{
977
  int need_redraw = 0;
978
  if (n == 6)
979
  {
980
    if (!board.GetPViewStatus() || play.GetNPlay() == 0)
981
    {
982
      PlayWrite cur_pw = board.GetPlay();
983
      if (cur_pw.GetN() > 2 || play.GetNPlay() == 0) play.Add(board.GetPlay());
984
      cur_play = play.GetNPlay() - 1;
985
      board.SetPlay(play[cur_play]);
986
      need_redraw = 1;
987
    }
988
  }
989
  else if (n == 7)
990
  {
991
    if (board.GetPViewStatus() && play.GetNPlay() != 0)
992
    {
993
      play.Del(cur_play);
994
      if (play.GetNPlay() >= 1)
995
      {
996
        if (cur_play >= play.GetNPlay()) cur_play--;
997
        board.SetPlay(play[cur_play]);
998
      }
999
      need_redraw = 1;
1000
    }
1001
  }
1002
  else if (n == 21)
1003
  {
1004
    if (cur_play > 0) {board.SetPlay(play[--cur_play]); need_redraw = 1;}
1005
  }
1006
  else if (n == 22)
1007
  {
1008
    if (cur_play < play.GetNPlay() - 1)
1009
    {
1010
      board.SetPlay(play[++cur_play]); need_redraw = 1;
1011
    }
1012
  }
1013
  else if (n == 26)
1014
  {
1015
    if (cur_play > 0)
1016
    {
1017
      cur_play = 0;
1018
      board.SetPlay(play[cur_play]); need_redraw = 1;
1019
    }
1020
  }
1021
  else if (n == 27)
1022
  {
1023
    if (cur_play < play.GetNPlay() - 1)
1024
    {
1025
      cur_play = play.GetNPlay() - 1;
1026
      board.SetPlay(play[cur_play]); need_redraw = 1;
1027
    }
1028
  }
1029
  else if (n == 24) {play.Clear(); cur_play = 0; need_redraw = 1;}
1030
#ifndef __MENUET__
1031
  else if (n == 25)
1032
  {
1033
    if (play.GetNPlay() > 0) play.MsgSaveFile(def_savefile, -1, def_savekind);
1034
  }
1035
  else if (n == 28)
1036
  {
1037
    if (play.GetNPlay() > 0) play.MsgSaveFile(def_savefile, cur_play, def_savekind);
1038
  }
1039
#endif
1040
  if (need_redraw)
1041
  {
1042
    SetButtonKind(board);
1043
    if (drw && drw->IsDraw())
1044
    {
1045
      drw->DrawClear();
1046
      board.Draw(drw);
1047
    }
1048
  }
1049
  else Draw(drw, board.GetW(), board.GetH());
1050
}
1051
 
1052
struct TTimerDraw
1053
{
1054
  TTimerDraw(TChBoard *brd, TGraphDraw *drw) : brd(brd), drw(drw) {}
1055
 
1056
  TChBoard *brd;
1057
  clock_t st, ut, dt;
1058
  double x0;
1059
  TGraphDraw *drw;
1060
 
1061
  static void draw(void *v, int k = 0);
1062
};
1063
 
1064
void TTimerDraw::draw(void *v, int k)
1065
{
1066
  TTimerDraw &d = *(TTimerDraw*)v;
1067
  clock_t t = clock();
1068
  if (k == 0 && t - d.ut < CLOCKS_PER_SEC * 0.01) return;
1069
  if (k > 0)
1070
  {
1071
    d.st = t;
1072
    if (!d.drw || !d.drw->IsDraw()) return;
1073
    d.drw->DrawClear();
1074
    d.brd->Draw(d.drw);
1075
    d.dt = t;
1076
  }
1077
  else if (!d.drw || !d.drw->IsDraw()) return;
1078
  double xold = d.x0;
1079
  if (k >= 0)
1080
  {
1081
    d.x0 = (1 - cos(2.0 * (t - d.st) / CLOCKS_PER_SEC)) / 2;
1082
    d.brd->DrawTimer(d.drw, d.x0, 0);
1083
    d.ut = t;
1084
    if (k == 0 && t - d.dt > CLOCKS_PER_SEC * 0.5)
1085
    {
1086
      d.brd->Draw(d.drw);
1087
      d.dt = t;
1088
    }
1089
  }
1090
  if (k <= 0) d.brd->DrawTimer(d.drw, xold, 1);
1091
}
1092
 
1093
 
1094
struct TMainData
1095
{
1096
  TChBoard board;
1097
  TComputerPlayer player;
1098
  TMainDraw main_draw;
1099
 
1100
  TMainData(int id = 0);
1101
  void InitDef();
1102
  static int EventFunction(const TGraphDraw::event &ev);
1103
  void NewGame(TGraphDraw *drw);
1104
  void RotateBoard(TGraphDraw *drw);
1105
  void PlayerPress(int np, TGraphDraw *drw);
1106
  void GoToCurMove(TGraphDraw *drw);
1107
};
1108
 
1109
TMainData::TMainData(int id) : board(id)
1110
{
1111
  board.SetCheckResize(1);
1112
  board.SetPlayer(1, &player);
1113
  board.SetBottomColor(0);
1114
  board.SetSomeDraw(&main_draw);
1115
  board.SetMinWSize(90, 140);
1116
}
1117
 
1118
void TMainData::InitDef()
1119
{
1120
  if (main_draw.play.GetNPlay() > 0)
1121
  {
1122
    main_draw.CurPlayNorm();
1123
    board.SetPlay(main_draw.play[main_draw.cur_play]);
1124
  }
1125
  main_draw.SetButtonKind(board);
1126
}
1127
 
1128
void TMainData::NewGame(TGraphDraw *drw)
1129
{
1130
  board.NewGame();
1131
  main_draw.SetButtonKind(board);
1132
  if (drw && drw->IsDraw()) {drw->DrawClear(); board.Draw(drw);}
1133
}
1134
 
1135
void TMainData::RotateBoard(TGraphDraw *drw)
1136
{
1137
  board.SetBottomColor(3 - board.GetBottomColor());
1138
  if (drw && drw->IsDraw()) {drw->DrawClear(); board.Draw(drw);}
1139
}
1140
 
1141
void TMainData::PlayerPress(int np, TGraphDraw *drw)
1142
{
1143
  if (np != 0 && np != 1) return;
1144
  if (board.GetPlayer(np)) board.SetPlayer(np, 0);
1145
  else board.SetPlayer(np, &player);
1146
  if (board.GetPlayer(0) && !board.GetPlayer(1))
1147
  {
1148
    board.SetBottomColor(1);
1149
  }
1150
  if (board.GetPlayer(1) && !board.GetPlayer(0))
1151
  {
1152
    board.SetBottomColor(0);
1153
  }
1154
  main_draw.SetButtonKind(board);
1155
  if (drw && drw->IsDraw()) {drw->DrawClear(); board.Draw(drw);}
1156
}
1157
 
1158
void TMainData::GoToCurMove(TGraphDraw *drw)
1159
{
1160
  board.GoToCurMove();
1161
  main_draw.SetButtonKind(board);
1162
  if (drw && drw->IsDraw()) {drw->DrawClear(); board.Draw(drw);}
1163
}
1164
 
1165
int TMainData::EventFunction(const TGraphDraw::event &ev)
1166
{
1167
  if (!ev.any.drw->data) return -100;
1168
  TMainData &data = *(TMainData*)ev.any.drw->data;
1169
  int nbutton, ret = 0;
1170
  switch(ev.type)
1171
  {
1172
  case TGraphDraw::event::button_down:
1173
    if (ev.button.n != 1) break;
1174
    ev.button.drw->OpenDraw();
1175
    if (data.main_draw.ButtonPnt(ev.button.x, ev.button.y,
1176
             data.board.GetW(), data.board.GetH(), nbutton, 1) > 0)
1177
    {
1178
      data.main_draw.Draw(ev.button.drw, data.board.GetW(), data.board.GetH());
1179
      ret |= TGraphDraw::ret_setcapture;
1180
    }
1181
    else data.board.MouseClick(ev.button.drw, ev.button.x, ev.button.y);
1182
    ev.button.drw->CloseDraw();
1183
    break;
1184
  case TGraphDraw::event::mouse_move:
1185
    if (ev.button.n >= 0 && ev.button.n != 1) break;
1186
    ev.button.drw->OpenDraw();
1187
    if (data.main_draw.ButtonPnt(ev.button.x, ev.button.y,
1188
             data.board.GetW(), data.board.GetH(), nbutton, 2) >= 1000)
1189
    {
1190
      data.main_draw.Draw(ev.button.drw, data.board.GetW(), data.board.GetH());
1191
    }
1192
    ev.button.drw->CloseDraw();
1193
    break;
1194
  case TGraphDraw::event::button_up:
1195
    if (ev.button.n != 1) break;
1196
    ev.button.drw->OpenDraw();
1197
    if (data.main_draw.ButtonPnt(ev.button.x, ev.button.y,
1198
             data.board.GetW(), data.board.GetH(), nbutton, 3) > 0)
1199
    {
1200
      switch(nbutton)
1201
      {
1202
      case 1:
1203
        data.NewGame(ev.button.drw);
1204
        break;
1205
      case 2:
1206
      case 3:
1207
        data.PlayerPress(nbutton - 2, ev.button.drw);
1208
        break;
1209
      case 4:
1210
        data.RotateBoard(ev.button.drw);
1211
        break;
1212
      case 5:
1213
        data.main_draw.Draw(ev.button.drw, data.board.GetW(), data.board.GetH());
1214
        ev.button.drw->Quit();
1215
        break;
1216
      case 11:
1217
      case 12:
1218
      case 13:
1219
      case 14:
1220
        data.main_draw.PressUR(nbutton, data.board, ev.button.drw);
1221
        break;
1222
      case 15:
1223
        data.GoToCurMove(ev.button.drw);
1224
        break;
1225
      case 6:
1226
      case 7:
1227
      case 21:
1228
      case 22:
1229
      case 23:
1230
      case 24:
1231
      case 25:
1232
      case 26:
1233
      case 27:
1234
        data.main_draw.PressLS(nbutton, data.board, ev.button.drw);
1235
        break;
1236
      default:
1237
        data.main_draw.Draw(ev.button.drw, data.board.GetW(), data.board.GetH());
1238
        break;
1239
      }
1240
    }
1241
    ev.button.drw->CloseDraw();
1242
    break;
1243
  case TGraphDraw::event::draw:
1244
    ev.button.drw->OpenDraw();
1245
    data.board.Draw(ev.button.drw);
1246
    ev.button.drw->CloseDraw();
1247
    break;
1248
  case TGraphDraw::event::key_down:
1249
    ev.button.drw->OpenDraw();
1250
    if (ev.key.k == XK_Left) data.board.PKeyEvent(ev.button.drw, TChBoard::PLeft);
1251
    else if (ev.key.k == XK_Right) data.board.PKeyEvent(ev.button.drw, TChBoard::PRight);
1252
    else if (ev.key.k == XK_Up) data.board.PKeyEvent(ev.button.drw, TChBoard::PUp);
1253
    else if (ev.key.k == XK_Down) data.board.PKeyEvent(ev.button.drw, TChBoard::PDown);
1254
    else if (ev.key.k == XK_Return || ev.key.k == XK_space)
1255
    {
1256
      data.board.PKeyEvent(ev.button.drw, TChBoard::PEnter);
1257
    }
1258
    else if (ev.key.k == XK_Escape) ev.button.drw->Quit();
1259
    else if (ev.key.k == XK_less) data.main_draw.PressUR(11, data.board, ev.button.drw);
1260
    else if (ev.key.k == XK_comma) data.main_draw.PressUR(12, data.board, ev.button.drw);
1261
    else if (ev.key.k == XK_period) data.main_draw.PressUR(13, data.board, ev.button.drw);
1262
    else if (ev.key.k == XK_greater) data.main_draw.PressUR(14, data.board, ev.button.drw);
1263
    else if (ev.key.k == XK_minus) data.main_draw.PressLS(21, data.board, ev.button.drw);
1264
    else if (ev.key.k == XK_equal) data.main_draw.PressLS(22, data.board, ev.button.drw);
1265
    else if (ev.key.k == XK_underscore) data.main_draw.PressLS(26, data.board, ev.button.drw);
1266
    else if (ev.key.k == XK_plus) data.main_draw.PressLS(27, data.board, ev.button.drw);
1267
    else if (ev.key.k == XK_Delete) data.main_draw.PressLS(7, data.board, ev.button.drw);
1268
    else if (ev.key.k == XK_F8) data.main_draw.PressLS(24, data.board, ev.button.drw);
1269
    else if (ev.key.k == XK_l || ev.key.k == XK_L) data.main_draw.PressLS(6, data.board, ev.button.drw);
1270
#ifndef __MENUET__
1271
    else if (ev.key.k == XK_F2) data.main_draw.PressLS(25, data.board, ev.button.drw);
1272
#endif
1273
    else if (ev.key.k == XK_s || ev.key.k == XK_S) data.main_draw.PressLS(28, data.board, ev.button.drw);
1274
    else if (ev.key.k == XK_slash || ev.key.k == XK_question) data.GoToCurMove(ev.button.drw);
1275
    else if (ev.key.k == XK_n || ev.key.k == XK_N) data.NewGame(ev.button.drw);
1276
    else if (ev.key.k == XK_t || ev.key.k == XK_T) data.RotateBoard(ev.button.drw);
1277
    else if (ev.key.k == XK_r || ev.key.k == XK_R) data.PlayerPress(0, ev.button.drw);
1278
    else if (ev.key.k == XK_b || ev.key.k == XK_B) data.PlayerPress(1, ev.button.drw);
1279
    else if (ev.key.k == XK_f || ev.key.k == XK_F)
1280
    {
1281
      int w, h;
1282
      ev.button.drw->GetSize(w, h);
1283
      ev.button.drw->CloseDraw();
1284
      if (DuplicateProcess() == 0)
1285
      {
1286
        ev.button.drw->ResReinit(w, h);
1287
        data.board.EraseHistory();
1288
      }
1289
    }
1290
    ev.button.drw->CloseDraw();
1291
    break;
1292
  case TGraphDraw::event::close:
1293
    ret = 1;
1294
    break;
1295
  }
1296
  return ret;
1297
}
1298
 
1299
#ifndef __MENUET__
1300
int main(int argc, char **argv)
1301
{
1302
  randomize();
1303
  THistory::InitHFile(argv[0]);
1304
  TMainData data(-1);
1305
  if (argv && argc >= 2)
1306
  {
1307
    int i, kx = 1;
1308
    for (i = 1; i < argc; i++)
1309
    {
1310
      if (kx == 1 && argv[i][0] == '-')
1311
      {
1312
        if (strcmp(argv[i], "--") == 0) kx = 0;
1313
        else if (strcmp(argv[i], "-ssf") == 0) ssf = 1;
1314
        else if (strncmp(argv[i], "-save", 5) == 0)
1315
        {
1316
          int j = 5;
1317
          if (argv[i][j])
1318
          {
1319
            if (argv[i][j] != '=' || !argv[i][j+1])
1320
            {
1321
              data.main_draw.def_savekind = atoi(argv[i] + j);
1322
              while (argv[i][j] && argv[i][j] != '=') j++;
1323
              if (argv[i][j] != '=' || !argv[i][j+1]) continue;
1324
            }
1325
            data.main_draw.def_savefile = argv[i] + j + 1;
1326
          }
1327
        }
1328
        else printf("Checkers: Invalid key %s\n", argv[i]);
1329
      }
1330
      else if (kx == 0 || kx == 1)
1331
      {
1332
        data.main_draw.play.MsgOpenFile(argv[i], -1);
1333
      }
1334
    }
1335
  }
1336
  data.InitDef();
1337
  TMainGraphDraw graph(
1338
#ifdef BUILD_RUS
1339
  "誨"
1340
#else
1341
  "Checkers"
1342
#endif
1343
  );
1344
  TTimerDraw timer_draw(&data.board, &graph);
1345
  data.player.draw = TTimerDraw::draw; data.player.data = &timer_draw;
1346
  graph.evfunc = TMainData::EventFunction; graph.data = &data;
1347
  graph.SetAboutInfo(1);
1348
  graph.Run(TGraphDraw::button_down_mask | TGraphDraw::button_up_mask |
1349
            TGraphDraw::key_down_mask | TGraphDraw::mouse_drag_mask,
1350
            450 + 100 * ssf, 528);
1351
  return 0;
1352
}
1353
#else
1354
 
1355
TMainData* mdata;
1356
TMainGraphDraw* graph;
1357
 
1358
bool MenuetOnStart(TStartData &me_start, TThreadData)
1359
{
1360
	mdata = new TMainData(-1);
1361
	graph = new TMainGraphDraw;
1362
	randomize();
1363
	mdata->InitDef();
1364
	static TTimerDraw timer_draw(&mdata->board, graph);
1365
	mdata->player.draw = TTimerDraw::draw; mdata->player.data = &timer_draw;
1366
	graph->data = mdata;
1367
	me_start.WinData.Title =
1368
#ifdef BUILD_RUS
1369
	"誨"
1370
#else
1371
	"Checkers"
1372
#endif
1373
	;
1374
	me_start.Width = 450 + 100*ssf;
1375
	me_start.Height = 528;
1376
	return true;
1377
}
1378
bool MenuetOnClose(TThreadData)
1379
{
1380
	delete mdata;
1381
	delete graph;
1382
	return true;
1383
}
1384
int MenuetOnIdle(TThreadData)
1385
{return -1;}
1386
void MenuetOnSize(int window_rect[], TThreadData)
1387
{mdata->board.Resize(window_rect[2]-window_rect[0], window_rect[3]-window_rect[1]);}
1388
void MenuetOnKeyPress(TThreadData)
1389
{
1390
	TGraphDraw::event ev;
1391
	ev.type = TGraphDraw::event::key_down;
1392
	ev.any.drw = graph;
1393
	ev.key.k = GetKey();
1394
	mdata->EventFunction(ev);
1395
}
1396
void MenuetOnDraw(void)
1397
{
1398
	TGraphDraw::event ev;
1399
	ev.type = TGraphDraw::event::draw;
1400
	ev.any.drw = graph;
1401
	mdata->EventFunction(ev);
1402
}
1403
void MenuetOnMouse(TThreadData)
1404
{
1405
	short x,y;
1406
	GetMousePosition(x,y);
1407
	int m = GetMouseButton() & 1;
1408
	static int mprev = 0;
1409
	if (m == mprev)
1410
		return;
1411
	mprev = m;
1412
	TGraphDraw::event ev;
1413
	ev.type = m ? TGraphDraw::event::button_down : TGraphDraw::event::button_up;
1414
	ev.any.drw = graph;
1415
	ev.button.n = 1;
1416
	ev.button.x = x;
1417
	ev.button.y = y;
1418
	mdata->EventFunction(ev);
1419
}
1420
#endif