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