Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
31 halyavin 1
; C4
2
; Copyright (c) 2002 Thomas Mathys
3
; killer@vantage.ch
4
;
5
; This file is part of C4.
6
;
7
; C4 is free software; you can redistribute it and/or modify
8
; it under the terms of the GNU General Public License as published by
9
; the Free Software Foundation; either version 2 of the License, or
10
; (at your option) any later version.
11
;
12
; C4 is distributed in the hope that it will be useful,
13
; but WITHOUT ANY WARRANTY; without even the implied warranty of
14
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
; GNU General Public License for more details.
16
;
17
; You should have received a copy of the GNU General Public License
18
; along with C4; if not, write to the Free Software
19
; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20
 
21
	bits 32
22
	%include 'mos.inc'
23
	section .text
24
 
25
	MOS_HEADER01 start,end
26
 
27
 
28
 
29
;**********************************************************
30
; magic numbers
31
;**********************************************************
32
 
33
; initial player types
34
PL1TYPE_INIT		equ	0
35
PL2TYPE_INIT		equ	4
36
 
37
; window
38
WND_WIDTH		equ	259
39
WND_HEIGHT		equ	300
40
WND_WORKCOLOR		equ	0
41
 
42
; button dimensions
43
BUTTON_HEIGHT		equ	12
44
 
45
BUTTON_NEW_X		equ	14
46
BUTTON_NEW_Y		equ	30
47
BUTTON_NEW_WIDTH	equ	56
48
 
49
BUTTON_SPIN_WIDTH	equ	8
50
BUTTON_PL1DN_X		equ	228
51
BUTTON_PL1DN_Y		equ	30
52
BUTTON_PL1UP_X		equ	(BUTTON_PL1DN_X + BUTTON_SPIN_WIDTH + 1)
53
BUTTON_PL1UP_Y		equ	BUTTON_PL1DN_Y
54
 
55
BUTTON_PL2DN_X		equ	BUTTON_PL1DN_X
56
BUTTON_PL2DN_Y		equ	(BUTTON_PL1DN_Y + 20)
57
BUTTON_PL2UP_X		equ	(BUTTON_PL2DN_X + BUTTON_SPIN_WIDTH + 1)
58
BUTTON_PL2UP_Y		equ	BUTTON_PL2DN_Y
59
 
60
; label dimensions
61
LABEL_PL1_X		equ	90
62
LABEL_PL1_Y		equ	(1 + BUTTON_PL1DN_Y + (BUTTON_HEIGHT-8)/2)
63
LABEL_PL2_X		equ	LABEL_PL1_X
64
LABEL_PL2_Y		equ	(1 + BUTTON_PL2DN_Y + (BUTTON_HEIGHT-8)/2)
65
LABEL_PL1TYPE_X		equ	(LABEL_PL1_X + 10*6)
66
LABEL_PL1TYPE_Y		equ	LABEL_PL1_Y
67
LABEL_PL2TYPE_X		equ	LABEL_PL1TYPE_X
68
LABEL_PL2TYPE_Y		equ	LABEL_PL2_Y
69
LABEL_STATUS_X		equ	14
70
LABEL_STATUS_Y		equ	279
71
LABEL_STATUS_WIDTH	equ	220
131 diamond 72
LABEL_STATUS_HEIGHT	equ	12
31 halyavin 73
 
74
 
75
 
76
; board and stones
77
STONESIZE		equ	32			; stone height and width
78
GRIDX			equ	14			; upper left corner
79
GRIDY			equ	70
80
GRIDSPACING		equ	(STONESIZE + 1)		; space between lines
81
GRIDHEIGHT		equ	(6*GRIDSPACING+1)	; total grid width and height
82
GRIDWIDTH		equ	(7*GRIDSPACING+1)
83
GRIDCOLOR		equ	MOS_RGB(128,128,128)
84
 
85
 
86
 
87
; button id's
88
BT_QUIT			equ	1
89
BT_NEW			equ	2
90
BT_PLAYER1DN		equ	3
91
BT_PLAYER1UP		equ	4
92
BT_PLAYER2DN		equ	5
93
BT_PLAYER2UP		equ	6
94
 
95
 
96
start:
97
	jmp main
98
 
99
%include "pcx.inc"
100
%include "windows.inc"
101
%include "board.inc"
102
%include "rng.inc"
103
; %include "randomai.inc"
104
%include "ai.inc"
105
 
106
 
107
 
108
;**********************************************************
109
; main program
110
;**********************************************************
111
main:
112
	call randomize
113
	call defineWindow
114
	call decrunchImages
115
	call newGame
116
 
117
.msgpump:
118
	; wait for event
119
	mov ebx,1
120
	mov eax,MOS_SC_WAITEVENTTIMEOUT
121
	int 0x40
122
 
123
	; process events
124
	cmp eax,MOS_EVT_REDRAW
125
	je short .redraw
126
	cmp eax,MOS_EVT_KEY
127
	je short .key
128
	cmp eax,MOS_EVT_BUTTON
129
	je short .button
130
 
131
	call pollMouse
132
	call gameLoop
133
	jmp short .msgpump
134
 
135
.redraw:
136
	call defineWindow
137
	jmp short .msgpump
138
.key:
139
	call keyboardInput
140
	jmp short .msgpump
141
.button:
142
	call handleButton
143
	jmp short .msgpump
144
 
145
 
146
 
147
;**********************************************************
148
; button handling function
149
;**********************************************************
150
handleButton:
151
	mov eax,MOS_SC_GETPRESSEDBUTTON		; get button id
152
	int 0x40
153
 
154
	cmp al,1				; button pressed ?
155
	je short .bye				; nope -> nothing to do
156
 
157
	cmp ah,BT_QUIT				; which button has been pressed ?
158
	je short .quit
159
	cmp ah,BT_NEW
160
	je short .new
161
	cmp ah,BT_PLAYER1DN
162
	je short .player1dn
163
	cmp ah,BT_PLAYER1UP
164
	je short .player1up
165
	cmp ah,BT_PLAYER2DN
166
	je short .player2dn
167
	cmp ah,BT_PLAYER2UP
168
	je short .player2up
169
.bye:
170
	ret
171
.quit:
172
	MOS_EXIT
173
.new:
174
	call newGame
175
	ret
176
.player1dn:
177
	mov eax,[player1_type]		; get current type
178
	or eax,eax			; already zero ?
179
	jz .bla
180
	dec eax				; nope -> decrement
181
	mov [player1_type],eax		; write back
182
	mov edi,label_pl1type		; and update label
183
	call updatePlayerType
184
.bla:
185
	ret
186
.player1up:
187
	mov eax,[player1_type]		; get current type
188
	cmp eax,NPLAYERTYPES-1		; already max ?
189
	je .bla2
190
	inc eax				; nope -> increment
191
	mov [player1_type],eax		; write back
192
	mov edi,label_pl1type		; update label
193
	call updatePlayerType
194
.bla2:
195
	ret
196
.player2dn:
197
	mov eax,[player2_type]		; get current type
198
	or eax,eax			; already zero ?
199
	jz .bla3
200
	dec eax				; nope -> decrement
201
	mov [player2_type],eax		; write back
202
	mov edi,label_pl2type		; and update label
203
	call updatePlayerType
204
.bla3:
205
	ret
206
.player2up:
207
	mov eax,[player2_type]
208
	cmp eax,NPLAYERTYPES-1
209
	je .bla4
210
	inc eax
211
	mov [player2_type],eax
212
	mov edi,label_pl2type
213
	call updatePlayerType
214
.bla4:
215
	ret
216
 
217
 
218
 
219
;**********************************************************
220
; window definition function
221
;**********************************************************
222
defineWindow:
223
	MOS_STARTREDRAW
224
 
225
	mov edi,window
226
	call drawWindow
227
 
228
	mov edi,buttons
229
	mov ecx,NBUTTONS
230
	call drawButtons
231
 
232
	mov edi,labels
233
	mov ecx,NLABELS
234
	call drawLabels
235
 
236
	xor eax,eax
237
	call drawBoard
238
 
239
	MOS_ENDREDRAW
240
	ret
241
 
242
 
243
 
244
;**********************************************************
245
; updateStatusText
246
;
247
; input		:	esi = ptr to new string
248
; output	:	status bar is updated
249
; destroys	:	everything
250
;**********************************************************
251
updateStatusText:
252
 
253
	; different text ?
254
	cmp [statusbar + LABEL.caption],esi
255
	je .bye							; nope -> bye
256
	mov dword [statusbar + LABEL.caption],esi		; yeah -> save & redraw
257
 
258
	; clear background
259
     	mov ebx,MOS_DWORD(LABEL_STATUS_X,LABEL_STATUS_WIDTH)
260
     	mov ecx,MOS_DWORD(LABEL_STATUS_Y,LABEL_STATUS_HEIGHT)
261
     	xor edx,edx
262
     	mov eax,MOS_SC_DRAWBAR
263
     	int 0x40
264
 
265
     	; redraw label
266
	mov edi,statusbar
267
	mov ecx,1
268
	call drawLabels
269
.bye:
270
	ret
271
 
272
 
273
 
274
;**********************************************************
275
; updatePlayerType
276
; update player type label
277
; input:	eax = new type
278
;		edi = address label structure to update
279
;**********************************************************
280
updatePlayerType:
281
	mov ebx,PLAYERTYPELEN				; calculate type string address
282
	mul ebx
283
	add eax,playertypes
284
	mov [edi + LABEL.caption],eax			; write address
285
	mov ecx,1					; and redraw label
286
	call drawLabels
287
	ret
288
 
289
 
290
 
291
;**********************************************************
292
; board drawing stuff
293
;**********************************************************
294
 
295
; drawBoard
296
; draw whole board
297
;
298
; input		:	eax nonzero = clear board background
299
drawBoard:
300
 
301
	; clear background ?
302
	or eax,eax
303
	jz .noclear
304
	mov ebx,MOS_DWORD(GRIDX,GRIDWIDTH)
305
	mov ecx,MOS_DWORD(GRIDY,GRIDHEIGHT)
306
	mov edx,WND_WORKCOLOR
307
	mov eax,MOS_SC_DRAWBAR
308
	int 0x40
309
.noclear:
310
	call drawGrid
311
	call drawStones
312
	ret
313
 
314
 
315
 
316
drawGrid:
317
 
318
	; vertical lines
319
	mov ebx,MOS_DWORD(GRIDX,GRIDX)
320
	mov ecx,MOS_DWORD(GRIDY,GRIDY+GRIDHEIGHT-1)
321
	mov edx,GRIDCOLOR
322
	mov eax,MOS_SC_DRAWLINE
323
	mov esi,8
324
.vlines:
325
	int 0x40
326
	add ebx,MOS_DWORD(GRIDSPACING,GRIDSPACING)
327
	dec esi
328
	jnz .vlines
329
 
330
	; horizontal lines
331
	mov ebx,MOS_DWORD(GRIDX,GRIDX+GRIDWIDTH-1)
332
	mov ecx,MOS_DWORD(GRIDY,GRIDY)
333
	mov esi,7
334
.hlines:
335
	int 0x40
336
	add ecx,MOS_DWORD(GRIDSPACING,GRIDSPACING)
337
	dec esi
338
	jnz .hlines
339
 
340
	ret
341
 
342
 
343
drawStones:
344
	mov ebx,6
345
.col:
346
	mov ecx,7
347
.row:
348
	call drawStone
349
	loop .row
350
	dec ebx
351
	jnz .col
352
	ret
353
 
354
 
355
 
356
; ecx = column (1..7)
357
; ebx = row (1..6)
358
drawStone:
359
	pushad
360
 
361
	; see which image to draw.
362
	; the image offset is stored in ebp
363
	mov eax,BWIDTH			; calculate address
364
	mul ebx
365
	add eax,ecx
366
	mov eax,[board+eax*4]		; get stone ?
367
	cmp eax,EMPTY			; empty field -> nothing to do
368
	je .bye
369
	mov ebp,redstone		; assume red stone
370
	cmp eax,PLAYER1			; red ?
371
	je .stoneok			; yeah -> continue
372
	mov ebp,bluestone		; nope -> use blue stone
373
.stoneok:
374
 
375
	; calculate image position (edx)
376
	mov eax,GRIDSPACING
377
	dec ecx
378
	mul ecx
379
	add eax,GRIDX + 1
380
	shl eax,16
381
	mov ecx,eax
382
	mov eax,GRIDSPACING
383
	dec ebx
384
	mul ebx
385
	add eax,GRIDY + 1
386
	mov cx,ax
387
	mov edx,ecx
388
 
389
	; put image (position is already in edx)
390
	mov ebx,ebp				; image address
391
	mov ecx,MOS_DWORD(STONESIZE,STONESIZE)	; image dimensions
392
	mov eax,MOS_SC_PUTIMAGE
393
	int 0x40
394
 
395
.bye:
396
	popad
397
	ret
398
 
399
 
400
 
401
decrunchImages:
402
	mov esi,redpcx			; red stone
403
	mov edi,redstone
404
	mov ebx,REDPCXSIZE
405
	call loadPCX
406
	mov esi,bluepcx			; blue stone
407
	mov edi,bluestone
408
	mov ebx,BLUEPCXSIZE
409
	call loadPCX
410
	ret
411
 
412
 
413
 
414
resetInput:
415
	mov dword [playerinput],0	; no player input
416
	mov dword [mouseinput],0
417
	ret
418
 
419
 
420
 
421
;**********************************************************
422
; newGame
423
; set up everything for a game
424
;
425
; input		:	nothing
426
; output	:	nothing
427
; destroys	:	everything
428
;**********************************************************
429
newGame:
430
	call boardReset			; reset and redraw board
431
	mov eax,1
432
	call drawBoard
433
	call resetInput			; reset input
434
	mov dword [gameover],0		; game is running
435
	ret
436
 
437
 
438
 
439
;**********************************************************
440
; pollMouse
441
; mouse polling routine
442
;
443
; input		:	nothing
444
; output	:	playerinput will be updated, if
445
;			the player clicked on a valid
446
;			field
447
; destroys	:	everything
448
;**********************************************************
449
pollMouse:
450
	mov ebx,2
451
	mov eax,MOS_SC_GETMOUSEPOSITION
452
	int 0x40
453
	and eax,1
454
	jz .mousenotpressed
455
.mousepressed:
456
	mov dword [mouseinput],0
457
	call isActiveApp
458
	or al,al
459
	jz .notactive1
460
	call getMouseCol
461
	mov [mouseinput],eax
462
.notactive1:
463
	ret
464
.mousenotpressed:
465
	call isActiveApp
466
	or al,al
467
	jz .notactive2
468
	call getMouseCol
469
	cmp eax,[mouseinput]
470
	jne .nonewinput
471
	cmp dword [playerinput],0
472
	jne .nonewinput
473
	mov [playerinput],eax
474
.nonewinput:
475
.notactive2:
476
	mov dword [mouseinput],0
477
	ret
478
 
479
 
480
 
481
;**********************************************************
482
; getMouseCol
483
; calculate in which column the mouse is. or so.
484
;
485
; input		:	nothing
486
; output	:	eax = 0 -> mouse outside board
487
;			eax = 1..7 -> column
488
; destroys	:	everything
489
;**********************************************************
490
getMouseCol:
491
 
492
	mov ebx,1			; get mouse position, window relative
493
	mov eax,MOS_SC_GETMOUSEPOSITION
494
	int 0x40
495
 
496
	movzx ebx,ax			; y clipping
497
	cmp ebx,GRIDY
498
	jl .outside
499
	cmp ebx,GRIDY + GRIDHEIGHT - 1
500
	jg .outside
501
 
502
	shr eax,16			; calculate column from x coordinate
503
	sub eax,GRIDX
504
	js .outside			; negative -> outside of board (left)
505
	cdq				; !
506
	mov ebx,GRIDSPACING
507
	div ebx
508
	cmp eax,BWIDTH-3		; right outside of board ?
509
	jg .outside			; yes -> bye
510
 
511
	inc eax				; xform into range [1,7]
512
	ret
513
.outside
514
	xor eax,eax
515
	ret
516
 
517
 
518
 
519
;**********************************************************
520
; isActiveApp
521
; check wether we're the active application
522
;
523
; input		:	nothing
524
; output	:	al nonzero -> we are the active app
525
; destroys	:	everything
526
;**********************************************************
527
isActiveApp:
528
 
529
%define	PROCINFO (ebp-MOS_PROCESSINFO_size)
530
 
531
	enter MOS_PROCESSINFO_size,0
532
 
533
	; get process information
534
	mov eax,MOS_SC_GETPROCESSINFO
535
	lea ebx,[ebp-MOS_PROCESSINFO_size]
536
	mov ecx,-1
537
	int 0x40
538
 
539
	; set al to 1 if we are the active application
540
	cmp ax,[PROCINFO+MOS_PROCESSINFO.windowStackPos]
541
	sete al
542
 
543
	leave
544
	ret
545
%undef PROCINFO
546
 
547
 
548
 
549
;**********************************************************
550
; keyboardInput
551
; keyboard input handler, called from main loop
552
;
553
; input		:	nothing
554
; output	:	playerinput is updated
555
; destroys	:	everything
556
;**********************************************************
557
keyboardInput:
558
	mov eax,MOS_SC_GETKEY		; get key
559
	int 0x40
560
	or al,al			; key available ?
561
	jnz .bye			; no -> bye
562
	cmp dword [playerinput],0	; unprocessed input available ?
563
	jne .bye			; yes -> bye
564
 
565
	sub ah,'1'			; valid key ?
566
	cmp ah,BWIDTH-3
567
	ja .bye				; treat as unsigned : keys below '1' will
568
					; be greater too =)
569
 
570
	mov al,ah			; save input
571
	and eax,255
572
	inc eax
573
	mov [playerinput],eax
574
 
575
.bye:
576
	ret
577
 
578
 
579
 
580
;**********************************************************
581
; gameLoop
582
; game logic code or however you wish to call it.
583
; actually this is not a loop, but is called from
584
; the main loop
585
;**********************************************************
586
gameLoop:
587
 
588
	; if the game is over, return
589
	cmp dword [gameover],0
590
	je .gamerunning
591
	ret
592
.gamerunning:
593
 
594
	call updatePlayerStatusText
595
 
596
	; get move
597
	call getMoveForCurrentPlayer
598
	or eax,eax
599
	jnz .moveok
600
	ret			; no move available -> bye
601
.moveok:
602
 
603
	; make move and update board graphics
604
	mov ebx,[currentplayer]	; ebx = current player, eax contains already move
605
	call boardMakeMove
606
	call drawStones
607
 
608
	; check wether game is over (either by a win or because the board is full)
609
	mov eax,[currentplayer]			; win for current player ?
610
	call boardIsWin
611
	or eax,eax
612
	jz .nowin				; no -> continue
613
	mov esi,player1wins			; yes -> display message...
614
	cmp dword [currentplayer],PLAYER1
615
	je .blubb
616
	mov esi,player2wins
617
.blubb:
618
	call updateStatusText
619
	mov dword [gameover],1			; ...and end game
620
	ret
621
.nowin:
622
	BOARDISFULL				; board full, but no win ?
623
	jnz .notfull				; no -> continue
624
	mov esi,itisadraw			; yes -> display message...
625
	call updateStatusText
626
	mov dword [gameover],1			; ...and end game
627
	ret
628
.notfull:
629
 
630
	; switch players and return to main loop
631
	BOARDSWITCHPLAYERS
632
	ret
633
 
634
 
635
 
636
;**********************************************************
637
; getMoveForCurrentPlayer
638
; returns the move made by the current player
639
; (either cpu or human)
640
;
641
; input		:	nothing
642
; output	:	eax = 0 -> no move made. this is
643
;			usually the case for human players,
644
;			when no valid input is available.
645
;			else eax = move number
646
;**********************************************************
647
getMoveForCurrentPlayer:
648
 
649
	; get type of current player
650
	mov eax,[player1_type]
651
	cmp dword [currentplayer],PLAYER1
652
	je .ok
653
	mov eax,[player2_type]
654
.ok:
655
 
656
	; get move for human/cpu player
657
	or eax,eax
658
	jnz .cpu
659
.human:
660
	mov eax,[playerinput]	; get input
661
	or eax,eax		; input available ?
662
	jz .nomove		; no -> return no move available
663
	call resetInput		; !
664
	BOARDISVALIDMOVE eax	; valid move `?
665
	jz .nomove		; no -> return no move available
666
	ret			; valid move available -> return it (eax)
667
 
668
.cpu:
669
	call dword [aicode]	; call ai machine. cpu level is already in eax
670
	ret
671
.nomove:
672
	xor eax,eax
673
	ret
674
 
675
 
676
 
677
;**********************************************************
678
; update status bar : which player's turn it is
679
;**********************************************************
680
updatePlayerStatusText:
681
	cmp dword [currentplayer],PLAYER2
682
	je .player2
683
	mov esi,player1hmnprmpt
684
	cmp dword [player1_type],0
685
	je .statustextok
686
	mov esi,player1cpuprmpt
687
	jmp short .statustextok
688
.player2:
689
	mov esi,player2hmnprmpt
690
	cmp dword [player2_type],0
691
	je .statustextok
692
	mov esi,player2cpuprmpt
693
.statustextok:
694
	call updateStatusText
695
	ret
696
 
697
 
698
 
699
;**********************************************************
700
; initialized data
701
;**********************************************************
702
 
703
	section .data
704
 
705
;
706
; window definition
707
;
708
windowtitle	db	"C4 0.1",0
709
window:
710
istruc WND
711
	at WND.xposandsize,	dd	MOS_DWORD(0,WND_WIDTH)
712
	at WND.yposandsize,	dd	MOS_DWORD(0,WND_HEIGHT)
713
	at WND.workcolor,	dd	0x03000000 | WND_WORKCOLOR
714
	at WND.grabcolor,	dd	0
715
	at WND.framecolor,	dd	0
716
	at WND.caption,		dd	windowtitle
717
	at WND.captioncolor,	dd	0
718
	at WND.flags,		dd	WND_CENTER | WND_DEFAULT_GRABCOLOR | WND_DEFAULT_FRAMECOLOR | WND_DEFAULT_CAPTIONCOLOR
719
iend
720
 
721
;
722
; button table
723
;
724
buttons:
725
istruc BUTTON						; new
726
	at BUTTON.xposandsize
727
	dd MOS_DWORD(BUTTON_NEW_X,BUTTON_NEW_WIDTH)
728
	dd MOS_DWORD(BUTTON_NEW_Y,BUTTON_HEIGHT)
729
	dd BT_NEW
730
	dd BUTTON_COLOR_WORK
731
iend
732
istruc BUTTON						; player 1 down
733
	at BUTTON.xposandsize
734
	dd MOS_DWORD(BUTTON_PL1DN_X,BUTTON_SPIN_WIDTH)
735
	dd MOS_DWORD(BUTTON_PL1DN_Y,BUTTON_HEIGHT)
736
	dd BT_PLAYER1DN
737
	dd BUTTON_COLOR_WORK
738
iend
739
istruc BUTTON						; player 1 up
740
	at BUTTON.xposandsize
741
	dd MOS_DWORD(BUTTON_PL1UP_X,BUTTON_SPIN_WIDTH)
742
	dd MOS_DWORD(BUTTON_PL1UP_Y,BUTTON_HEIGHT)
743
	dd BT_PLAYER1UP
744
	dd BUTTON_COLOR_WORK
745
iend
746
istruc BUTTON						; player 2 down
747
	at BUTTON.xposandsize
748
	dd MOS_DWORD(BUTTON_PL2DN_X,BUTTON_SPIN_WIDTH)
749
	dd MOS_DWORD(BUTTON_PL2DN_Y,BUTTON_HEIGHT)
750
	dd BT_PLAYER2DN
751
	dd BUTTON_COLOR_WORK
752
iend
753
istruc BUTTON						; player 2 up
754
	at BUTTON.xposandsize
755
	dd MOS_DWORD(BUTTON_PL2UP_X,BUTTON_SPIN_WIDTH)
756
	dd MOS_DWORD(BUTTON_PL2UP_Y,BUTTON_HEIGHT)
757
	dd BT_PLAYER2UP
758
	dd BUTTON_COLOR_WORK
759
iend
760
NBUTTONS	equ	(($-buttons)/BUTTON_size)
761
 
762
 
763
;
764
; label table
765
;
766
 
767
newgame		db	"New game",0
768
down		db	"<",0
769
up		db	">",0
770
pl1		db	"Player 1:",0
771
pl2		db	"Player 2:",0
772
 
773
 
774
playertypes:
775
		db	"Human       ",0
776
PLAYERTYPELEN	equ	($ - playertypes)
777
		db	"CPU level 1 ",0
778
		db	"CPU level 2 ",0
779
		db	"CPU level 3 ",0
780
		db	"CPU level 4 ",0
781
		db	"CPU level 5 ",0
782
		db	"CPU level 6 ",0
783
		db	"CPU level 7 ",0
784
		db	"CPU level 8 ",0
785
NPLAYERTYPES	equ	(($-playertypes)/PLAYERTYPELEN)
786
 
787
 
788
labels:
789
istruc LABEL						; new
790
	at LABEL.position
791
	dd MOS_DWORD(BUTTON_NEW_X+4,1+BUTTON_NEW_Y+(BUTTON_HEIGHT-8)/2)
792
	dd newgame
793
	dd LABEL_COLOR_WORKBUTTON
794
	dd LABEL_BGCOLOR_TRANSPARENT
795
iend
796
istruc LABEL						; player 1 down
797
	at LABEL.position
798
	dd MOS_DWORD(BUTTON_PL1DN_X+(BUTTON_SPIN_WIDTH-4)/2,1+BUTTON_PL1DN_Y+(BUTTON_HEIGHT-8)/2)
799
	dd down
800
	dd LABEL_COLOR_WORKBUTTON
801
	dd LABEL_BGCOLOR_TRANSPARENT
802
iend
803
istruc LABEL						; player 1 up
804
	at LABEL.position
805
	dd MOS_DWORD(1+BUTTON_PL1UP_X+(BUTTON_SPIN_WIDTH-4)/2,1+BUTTON_PL1UP_Y+(BUTTON_HEIGHT-8)/2)
806
	dd up
807
	dd LABEL_COLOR_WORKBUTTON
808
	dd LABEL_BGCOLOR_TRANSPARENT
809
iend
810
istruc LABEL						; player 2 down
811
	at LABEL.position
812
	dd MOS_DWORD(BUTTON_PL2DN_X+(BUTTON_SPIN_WIDTH-4)/2,1+BUTTON_PL2DN_Y+(BUTTON_HEIGHT-8)/2)
813
	dd down
814
	dd LABEL_COLOR_WORKBUTTON
815
	dd LABEL_BGCOLOR_TRANSPARENT
816
iend
817
istruc LABEL						; player 2 up
818
	at LABEL.position
819
	dd MOS_DWORD(1+BUTTON_PL2UP_X+(BUTTON_SPIN_WIDTH-4)/2,1+BUTTON_PL2UP_Y+(BUTTON_HEIGHT-8)/2)
820
	dd up
821
	dd LABEL_COLOR_WORKBUTTON
822
	dd LABEL_BGCOLOR_TRANSPARENT
823
iend
824
istruc LABEL						; player 1
825
	at LABEL.position
826
	dd MOS_DWORD(LABEL_PL1_X,LABEL_PL1_Y)
827
	dd pl1
828
	dd MOS_RGB(255,255,255)
829
	dd LABEL_BGCOLOR_TRANSPARENT
830
iend
831
istruc LABEL						; player 2
832
	at LABEL.position
833
	dd MOS_DWORD(LABEL_PL2_X,LABEL_PL2_Y)
834
	dd pl2
835
	dd MOS_RGB(255,255,255)
836
	dd LABEL_BGCOLOR_TRANSPARENT
837
iend
838
statusbar:						; status bar
839
istruc LABEL
840
	at LABEL.position
841
	dd MOS_DWORD(LABEL_STATUS_X,LABEL_STATUS_Y)
842
	dd 0
843
	dd MOS_RGB(255,255,255)
844
	dd LABEL_BGCOLOR_TRANSPARENT
845
iend
846
label_pl1type:
847
istruc LABEL
848
	at LABEL.position
849
	dd MOS_DWORD(LABEL_PL1TYPE_X,LABEL_PL1TYPE_Y)
850
	dd playertypes+PL1TYPE_INIT*PLAYERTYPELEN
851
	dd MOS_RGB(255,255,255)
852
	dd MOS_RGB(0,0,0)
853
iend
854
label_pl2type:
855
istruc LABEL
856
	at LABEL.position
857
	dd MOS_DWORD(LABEL_PL2TYPE_X,LABEL_PL2TYPE_Y)
858
	dd playertypes+PL2TYPE_INIT*PLAYERTYPELEN
859
	dd MOS_RGB(255,255,255)
860
	dd MOS_RGB(0,0,0)
861
iend
862
NLABELS		equ	(($-labels)/LABEL_size)
863
 
864
 
865
; player types
866
player1_type	dd	PL1TYPE_INIT
867
player2_type	dd	PL2TYPE_INIT
868
 
869
 
870
; status messages
871
player1hmnprmpt	db	"Make your move, player 1.",0
872
player2hmnprmpt db	"Make your move, player 2.",0
873
player1cpuprmpt	db	"Player 1 is thinking, please wait...",0
874
player2cpuprmpt	db	"Player 2 is thinking, please wait...",0
875
itisadraw	db	"It's a draw.",0
876
player1wins	db	"Player 1 wins.",0
877
player2wins	db	"Player 2 wins.",0
878
 
879
 
880
; pointer to ai player. future releases C4 might
881
; or might not support different ai players =)
882
aicode		dd	aiGetMove
883
 
884
 
885
; button images
886
redpcx:		incbin	"red.pcx"
887
REDPCXSIZE	equ	($ - redpcx)
888
bluepcx:	incbin	"blue.pcx"
889
BLUEPCXSIZE	equ	($ - bluepcx)
890
 
891
 
892
 
893
;**********************************************************
894
; uninitialized data
895
;**********************************************************
896
 
897
	section .bss
898
 
899
; player input
900
; 0 	:	no input available
901
; 1..7	:	column to drop stone into
902
playerinput	resd	1
903
 
904
mouseinput	resd	1
905
gameover	resd	1
906
 
907
redstone	resb	STONESIZE*STONESIZE*3
908
bluestone	resb	STONESIZE*STONESIZE*3
909
 
910
end: