; ; CHESS CLIENT for CHESSCLUB.COM (VT) ; ; Compile with FASM for Menuet ; appname equ 'Chess Client for Chessclub.com ' version equ '0.2' use32 org 0x0 db 'MENUET01' ; header dd 0x01 ; header version dd START ; entry point dd I_END ; image size dd 0x100000 ; required memory dd 0x100000 ; esp dd 0x0 , 0x0 ; I_Param , I_Path include 'lang.inc' include '..\..\..\macros.inc' pawn_color: dd 0x000000 dd 0x222222 dd 0x444444 dd 0xf0f0f0 dd 0xc0c0c0 dd 0xa0a0a0 dd 0xa0a0a0 dd 0x707070 dd 0xb0b0b0 dd 0xc0c0c0 dd 0xd0d0d0 dd 0xd8d8d8 dd 0xe0e0e0 dd 0xe8e8e8 dd 0x00ff00 dd 0xffffff texts equ board_old+80*30 text equ texts+80*32*4 START: ; start of execution mov esi,chess_bmp mov edi,0x10000+18*3 mov ebx,0 mov ecx,0 newp: xor eax,eax mov al,[esi] and al,0xf0 shr al,4 shl eax,2 mov eax,[pawn_color+eax] mov [edi+0],eax xor eax,eax mov al,[esi] and al,0x0f shl eax,2 mov eax,[pawn_color+eax] mov [edi+3],eax add edi,6 add esi,1 inc ebx cmp ebx,23 jbe newp sub edi,12 mov ebx,0 inc ecx cmp ecx,279 jb newp ; Clear the screen memory mov eax, ' ' mov edi,text mov ecx,80*30 /4 cld rep stosd call draw_window still: call check_for_board call board_changed call draw_board ; check connection status mov eax,53 mov ebx,6 mov ecx,[socket] mcall mov ebx, [socket_status] mov [socket_status], eax cmp eax, ebx je waitev call display_status waitev: mov eax,23 ; wait here for event mov ebx,20 mcall cmp eax,1 ; redraw request ? je red cmp eax,2 ; key in buffer ? je key cmp eax,3 ; button in buffer ? je button ; any data from the socket? mov eax, 53 mov ebx, 2 mov ecx, [socket] mcall cmp eax, 0 jne read_input jmp still read_input: push ecx mov eax, 53 mov ebx, 3 mov ecx, [socket] mcall pop ecx call handle_data push ecx mov eax, 53 mov ebx, 2 mov ecx, [socket] mcall pop ecx cmp eax, 0 jne read_input call draw_text jmp still check_for_board: pusha mov esi,text-80 news: add esi,80 cmp esi,text+80*10 je board_not_found cmp [esi+12],dword '----' je cfb1 jmp news cfb1: cmp [esi+16*80+12],dword '----' je cfb2 jmp news cfb2: cmp [esi+2*80+12],dword '+---' jne news cmp [esi+4*80+12],dword '+---' jne news board_found: mov edi,chess_board mov ecx,80*18 cld rep movsb board_not_found: popa ret yst dd 150 textx equ 10 ysts equ 410 boardx dd 45 boardy dd 45 boardxs dd 44 boardys dd 44 conx equ 420 cony equ 118 dconx equ 420 dcony equ 148 statusx equ 420 statusy equ 178 drsq: push eax ebx mov ecx,ebx mov ebx,eax mov eax,ebx add eax,ecx imul ebx,[boardxs] add ebx,[boardx] shl ebx,16 imul ecx,[boardys] add ecx,[boardy] shl ecx,16 add ebx,[boardxs] add ecx,[boardys] mov edx,[sq_black] test eax,1 jnz dbl22 mov edx,[sq_white] dbl22: mov eax,13 mcall pop ebx eax ret draw_pawn: ; edi,0 ; white / black ; esi,0 ; from position 2 , 20 square ; eax,2 ; board x ; ebx,0 ; board y pusha call drsq cmp esi,20 jne no_sqd popa ret no_sqd: imul eax,[boardxs] imul ebx,[boardys] add eax,[boardx] add ebx,[boardy] imul esi,44*45*3 add esi,0x10000+18*3 mov ecx,43 dp0: pusha mov ecx,44 ldp1: pusha mov ecx,ebx mov ebx,eax mov edx,[esi] and edx,0xffffff mov eax,1 cmp edx,0x00ff00 je nowp cmp edi,1 jne nobl shr edx,1 and edx,0x7f7f7f nobl: mcall nowp: popa add esi,3 add eax,1 dec ecx jnz ldp1 popa add ebx,1 add esi,3*44 dec ecx jnz dp0 popa ret board_changed: pusha mov eax,0 mov esi,chess_board bcl1: add eax,[esi] add esi,4 cmp esi,chess_board+19*80 jb bcl1 cmp eax,[checksum] je bcl2 mov [changed],1 bcl2: mov [checksum],eax popa ret checksum dd 0 changed db 1 draw_board: pusha cmp [changed],1 jne no_change_in_board mov [changed],0 mov eax,0 mov ebx,0 scan_board: push eax ebx mov esi,ebx imul esi,2 imul esi,80 add esi,80 imul eax,4 add eax,10 add esi,eax movzx edx,word [chess_board+esi] cmp dx,[board_old+esi] je empty_slot mov ecx,13 newseek2: mov edi,ecx imul edi,8 sub edi,8 cmp dx,[edi+nappulat] je foundnappula2 loop newseek2 jmp empty_slot foundnappula2: mov esi,[edi+nappulat+4] mov edi,0 cmp dl,'*' jne nnbb mov edi,1 nnbb: mov eax,[esp+4] mov ebx,[esp] call draw_pawn empty_slot: pop ebx eax inc eax cmp eax,8 jb scan_board mov eax,0 inc ebx cmp ebx,8 jb scan_board mov esi,chess_board mov edi,board_old mov ecx,80*19 cld rep movsb mov eax,13 mov ebx,[boardx] sub ebx,14 shl ebx,16 add ebx,8 mov ecx,[boardy] shl ecx,16 add ecx,46*8 mov edx,[wcolor] mcall mov eax,4 ; numbers at left mov ebx,[boardx] sub ebx,14 shl ebx,16 add ebx,[boardy] add ebx,18 mov ecx,[tcolor] mov edx,chess_board+80+5 mov esi,3 db1: mcall add edx,80*2 add ebx,[boardxs] cmp edx,chess_board+80*16 jb db1 mov eax,13 mov ebx,[boardx] shl ebx,16 add ebx,8*46 mov ecx,[boardys] imul ecx,8 add ecx,[boardy] add ecx,8 shl ecx,16 add ecx,10 mov edx,[wcolor] mcall mov eax,4 ; letters at bottom mov ebx,[boardx] add ebx,3 shl ebx,16 mov bx,word [boardys] imul bx,8 add ebx,[boardy] add ebx,8 mov ecx,[tcolor] mov edx,chess_board+80*17+8 mov esi,4 db3: mcall mov edi,[boardxs] shl edi,16 add ebx,edi add edx,4 cmp edx,chess_board+80*17+8+4*8 jb db3 ; print player times mov edi,74 cmp [chess_board+80+5],byte '1' jne nowww2 mov edi,371 nowww2: mov eax,13 mov ebx,(conx)*65536+100 mov ecx,edi shl ecx,16 add ecx,10 mov edx,[wcolor] mcall mov eax,4 mov ebx,(conx)*65536 add ebx,edi mov ecx,[tcolor] mov edx,chess_board+80*7+59-1 mov esi,20 mcall mov edi,74 cmp [chess_board+80+5],byte '1' je nowww mov edi,371 nowww: mov eax,13 mov ebx,(conx)*65536+100 mov ecx,edi shl ecx,16 add ecx,10 mov edx,[wcolor] mcall mov eax,4 mov ebx,(conx)*65536 add ebx,edi mov ecx,[tcolor] mov edx,chess_board+80*9+59-1 mov esi,20 mcall ; move # mov eax,13 mov ebx,conx*65536+120 mov ecx,200*65536+10 mov edx,[wcolor] mcall mov eax,4 mov ebx,conx*65536 add ebx,200 mov ecx,[tcolor] mov edx,chess_board+80*1+46 mov esi,30 mcall no_change_in_board: popa ret handle_data: ; Telnet servers will want to negotiate options about our terminal window ; just reject them all. ; Telnet options start with the byte 0xff and are 3 bytes long. mov al, [telnetstate] cmp al, 0 je state0 cmp al, 1 je state1 cmp al, 2 je state2 jmp hd001 state0: cmp bl, 255 jne hd001 mov al, 1 mov [telnetstate], al ret state1: mov al, 2 mov [telnetstate], al ret state2: mov al, 0 mov [telnetstate], al mov [telnetrep+2], bl mov edx, 3 mov eax,53 mov ebx,7 mov ecx,[socket] mov esi, telnetrep mcall ret hd001: cmp bl,13 ; BEGINNING OF LINE jne nobol mov ecx,[pos] add ecx,1 boll1: sub ecx,1 mov eax,ecx xor edx,edx mov ebx,80 div ebx cmp edx,0 jne boll1 mov [pos],ecx call check_for_board jmp newdata nobol: cmp bl,10 ; LINE DOWN jne nolf addx1: add [pos],dword 1 mov eax,[pos] xor edx,edx mov ecx,80 div ecx cmp edx,0 jnz addx1 mov eax,[pos] jmp cm1 nolf: cmp bl,9 ; TAB jne notab add [pos],dword 8 jmp newdata notab: cmp bl,8 ; BACKSPACE jne nobasp mov eax,[pos] dec eax mov [pos],eax mov [eax+text],byte 32 mov [eax+text+60*80],byte 0 jmp newdata nobasp: cmp bl,15 ; CHARACTER jbe newdata mov eax,[pos] mov [eax+text],bl mov eax,[pos] add eax,1 cm1: mov ebx,[scroll+4] imul ebx,80 cmp eax,ebx jb noeaxz mov esi,text+80 mov edi,text mov ecx,ebx cld rep movsb mov eax,ebx sub eax,80 noeaxz: mov [pos],eax newdata: ret red: ; REDRAW WINDOW call draw_window jmp still key: ; KEY mov eax,2 ; send to modem mcall mov ebx, [socket_status] cmp ebx, 4 ; connection open? jne still ; no, so ignore key shr eax,8 cmp eax,178 ; ARROW KEYS jne noaup mov al,'A' call arrow jmp still noaup: cmp eax,177 jne noadown mov al,'B' call arrow jmp still noadown: cmp eax,179 jne noaright mov al,'C' call arrow jmp still noaright: cmp eax,176 jne noaleft mov al,'D' call arrow jmp still noaleft: modem_out: call to_modem jmp still button: ; BUTTON mov eax,17 mcall cmp ah,1 ; CLOSE PROGRAM jne noclose mov eax,53 mov ebx,8 mov ecx,[socket] mcall mov eax,-1 mcall noclose: cmp ah, 4 ; connect jne notcon mov eax, [socket_status] cmp eax, 4 je still call connect jmp still notcon: cmp ah,5 ; disconnect jne notdiscon call disconnect jmp still notdiscon: jmp still arrow: push eax mov al,27 call to_modem mov al,'[' call to_modem pop eax call to_modem ret to_modem: pusha push ax mov [tx_buff], al mov edx, 1 cmp al, 13 jne tm_000 mov edx, 2 tm_000: mov eax,53 mov ebx,7 mov ecx,[socket] mov esi, tx_buff mcall pop bx mov al, [echo] cmp al, 0 je tm_001 push bx call handle_data pop bx cmp bl, 13 jne tm_002 mov bl, 10 call handle_data tm_002: call draw_text tm_001: popa ret disconnect: mov eax,53 mov ebx,8 mov ecx,[socket] mcall ret connect: pusha mov ecx, 1000 ; local port starting at 1000 getlp: inc ecx push ecx mov eax, 53 mov ebx, 9 mcall pop ecx cmp eax, 0 ; is this local port in use? jz getlp ; yes - so try next mov eax,53 mov ebx,5 mov dl, [ip_address + 3] shl edx, 8 mov dl, [ip_address + 2] shl edx, 8 mov dl, [ip_address + 1] shl edx, 8 mov dl, [ip_address] mov esi, edx movzx edx, word [port] ; telnet port id mov edi,1 ; active open mcall mov [socket], eax popa ret ; ********************************************* ; ******* WINDOW DEFINITIONS AND DRAW ******** ; ********************************************* draw_window: pusha mov eax,12 mov ebx,1 mcall mov eax,14 mcall mov ebx,eax mov ecx,eax shr ebx,16 and ebx,0xffff and ecx,0xffff shr ebx,1 shr ecx,1 sub ebx,275 sub ecx,235 shl ebx,16 shl ecx,16 mov eax,0 ; DRAW WINDOW mov bx,550 mov cx,470 mov edx,[wcolor] add edx,0x14000000 mov edi,title mcall call display_status mov eax,8 ; BUTTON 4: Connect mov ebx,conx*65536+80 mov ecx,cony*65536+15 mov esi,[wbutton] mov edx,4 mcall mov eax,4 ; Button text mov ebx,(conx+4)*65536+cony+4 mov ecx,0xffffff mov edx,cont mov esi,conlen-cont mcall mov eax,8 ; BUTTON 5: disconnect mov ebx,dconx*65536+80 mov ecx,dcony*65536+15 mov edx,5 mov esi,[wbutton] mcall mov eax,4 ; Button text mov ebx,(dconx+4)*65536+dcony+4 mov ecx,0x00ffffff mov edx,dist mov esi,dislen-dist mcall xor eax,eax mov edi,text+80*30 mov ecx,80*30 /4 cld rep stosd call draw_text mov [changed],1 mov edi,board_old mov ecx,80*19 mov al,0 cld rep stosb mov eax,4 mov ebx,conx*65536+52 mov ecx,[tcolor] mov edx,quick_start mov esi,30 prqs: mcall add ebx,10 add edx,30 cmp [edx],byte 'x' jne prqs mov eax,12 mov ebx,2 mcall popa ret display_status: pusha ; draw status bar mov eax, 13 mov ebx, statusx*65536+80 mov ecx, statusy*65536 + 16 mov edx, [wcolor] mcall mov esi,contlen-contt ; display connected status mov edx, contt mov eax, [socket_status] cmp eax, 4 ; 4 is connected je pcon mov esi,discontlen-discontt mov edx, discontt pcon: mov eax,4 ; status text mov ebx,statusx*65536+statusy+2 mov ecx,[tcolor] mcall popa ret nappulat: dd '*P ',5 dd '*K ',3 dd '*Q ',4 dd '*R ',0 dd '*N ',1 dd '*B ',2 dd ' ',20 dd 'P ',5 dd 'K ',3 dd 'Q ',4 dd 'R ',0 dd 'N ',1 dd 'B ',2 row dd 0x0 col dd 0x0 draw_text: mov esi,text+80*24 mov edi,texts+80*3 dtl1: cmp [esi],dword 'logi' je add_text cmp [esi],dword 'aics' je add_text cmp [esi],dword 'You ' je add_text cmp [esi],dword 'Your' je add_text cmp [esi],dword 'Game' je add_text cmp [esi],dword 'Ille' je add_text cmp [esi],dword 'No s' je add_text sub esi,80 cmp esi,text jge dtl1 dtl2: mov eax,13 mov ebx,10*65536+532 mov ecx,420*65536+40 mov edx,[wtcom] mcall mov eax,4 mov ebx,10*65536+420 mov ecx,[wtxt] mov edx,texts mov esi,80 dtl3: mcall add edx,80 add ebx,10 cmp edx,texts+4*80 jb dtl3 ret add_text: pusha cld mov ecx,80 rep movsb popa sub esi,80 sub edi,80 cmp edi,texts jb dtl2 jmp dtl1 read_string: mov edi,string mov eax,'_' mov ecx,[string_length] inc ecx cld rep stosb call print_text mov edi,string f11: mov eax,10 mcall cmp eax,2 jne read_done mov eax,2 mcall shr eax,8 cmp eax,13 je read_done cmp eax,8 jnz nobsl cmp edi,string jz f11 sub edi,1 mov [edi],byte '_' call print_text jmp f11 nobsl: cmp eax,dword 31 jbe f11 cmp eax,dword 95 jb keyok sub eax,32 keyok: mov [edi],al call print_text inc edi mov esi,string add esi,[string_length] cmp esi,edi jnz f11 read_done: call print_text ret print_text: pusha mov eax,13 mov ebx,[string_x] shl ebx,16 add ebx,[string_length] imul bx,6 mov ecx,[string_y] shl ecx,16 mov cx,8 mov edx,[wcolor] mcall mov eax,4 mov ebx,[string_x] shl ebx,16 add ebx,[string_y] mov ecx,[tcolor] mov edx,string mov esi,[string_length] mcall popa ret ; DATA AREA telnetrep db 0xff,0xfc,0x00 telnetstate db 0 string_length dd 16 string_x dd 200 string_y dd 60 string db '________________' tx_buff db 0, 10 ip_address db 204,178,125,65 port dw 5051 ; 0,0 echo db 1 socket dd 0x0 socket_status dd 0x0 pos dd 80 * 22 scroll dd 1 dd 24 wbutton dd 0x336688 wtcom dd 0x336688 ; 0x666666 wtxt dd 0xffffff wcolor dd 0xe0e0e0 tcolor dd 0x000000 sq_black dd 0x336688 ; 666666 sq_white dd 0xffffff title db appname,version,0 setipt db ' . . .' setiplen: setportt db ' ' setportlen: cont db 'Connect' conlen: dist db 'Disconnect' dislen: contt db 'Connected' contlen: discontt db 'Disconnected' discontlen: echot db 'Echo On' echolen: echoot db 'Echo Off' echoolen: quick_start: db '( OPPONENT ) ' times 16 db ' 1' db 'Quick start: ' db ' ' db '1 Connect ' db '2 login: "guest" ' db '3 aics% "seek 10 0" ' db ' (for a player) ' db ' (wait) ' db '4 Play eg. "e7e5" ' db ' or "d2d4" ' db '5 aics% "resign" ' db ' (quit game) ' db '6 Disconnect ' times 5 db ' ' db '( YOU ) ' db 'x' chess_board: times 80 db 0 db ' 8 *R *N *B *Q *K *B *N *R' db ' ' times 80 db 0 db ' 7 *P *P *P *P *P *P *P *P' db ' ' times 80 db 0 db ' 6 ' db ' ' times 80 db 0 db ' 5 ' db ' ' times 80 db 0 db ' 4 ' db ' ' times 80 db 0 db ' 3 ' db ' ' times 80 db 0 db ' 2 P P P P P P P P ' db ' ' times 80 db 0 db ' 1 R N B Q K B N R ' db ' ' times 80 db 0 db ' a b c d e f g h ' db ' ' times 80*20 db 0 chess_bmp: file 'chess.bmp':22*3+4+24*2 board_old: I_END: