Subversion Repositories Kolibri OS

Rev

Rev 1805 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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