Rev 131 | Rev 3494 | 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 |
||
1821 | yogev_ezra | 513 | .outside: |
31 | halyavin | 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:",0 |