diff --git a/programs/games/FindNumbers/trunk/FindNumbers.c-- b/programs/games/FindNumbers/trunk/FindNumbers.c-- new file mode 100644 index 0000000000..a44cf1cb24 --- /dev/null +++ b/programs/games/FindNumbers/trunk/FindNumbers.c-- @@ -0,0 +1,157 @@ +//(C) Artemonische, 2010 + +#pragma option meos +//#include "..\lib\kolibri.h--" //砥 ⥪ KolibriOS API +#include "kolibri.h--" + +int find=10; +struct + { + int x; + int y; + int button_id; + int mark; + int text; + }box[81]; + +void main() +{ + int button,tempi,tempj; + randomize(); + initialization(); + draw_window(); + draw_buttons(); + loop() + { + switch(WaitEvent()) + { + CASE evButton: + button=GetButtonID(); + IF (button==1) + { + ExitProcess(); + } + IF (button==582) + { + find=10; + initialization(); + draw_window(); + draw_buttons(); + } + if (button>500) && (button<582) && (box[button-500].text == find) + { + box[button-500].mark=2; + find++; + if (find==91) + { + draw_window(); + } + else + { + DeleteButton(button); + tempi=box[button-500].y*30-30; + tempj=30*box[button-500].x-16; + DrawBar(tempi,tempj,30,30,0xDCFFDC); + DrawBar(70,289,16,8,0xDCFFDC); + DrawBar(252,289,16,8,0xDCFFDC); + WriteNumber(70,289,0x80,0,find); + WriteNumber(252,289,0x80,0,90-find+1); + } + } + BREAK; + CASE evKey: //᫨ ந諮 ⨥ + IF (GetKey()==051) + { + find=10; + initialization(); + draw_window(); + draw_buttons(); + } + BREAK; + CASE evReDraw: + draw_window(); + draw_buttons(); + BREAK; + } + } + ExitProcess(); +} + +void draw_window() +{ + WindowRedrawStatus(1); //砫 ᮢ + DefineAndDrawWindow(300,176,280,340,0x34,0xDCFFDC,0,0,"FindNumbers v1.1"); //㥬 + DrawBar(0,13,271,1,0x0CFF0C); // ᢥ + DrawBar(0,285,271,1,0x0CFF0C); + DrawBar(0,299,271,1,0x0CFF0C); // ᭨ + if (find<=90) + { + WriteText(4,4,0x80,0x000000," ᫠ 10 90 浪..."); + WriteText(4,289,0x80,0x000000,"饬 ᫮: "); + WriteText(162,289,0x80,0x000000,"⠫ : "); + WriteNumber(70,289,0x80,0,find); + WriteNumber(252,289,0x80,0,90-find+1); + DrawFlatButton(155,300,115,14,582,0xAFFFAF," (F2)"); + WriteText(4,304,0x80,0x000000,"Made by Artemonische,2010"); + } + IF (find==91) + { + WriteText(70,100,0x80,0x000000," 諨 ᫠! :)"); + DrawFlatButton(100,110,70,20,582,0xE4DFE1," (F2)"); + } + WindowRedrawStatus(2); // ᮢ +} + +void draw_buttons() +{ +int i,tempi,tempj; + for (i=1;i<=81;i++) + { + IF (box[i].mark==1) + { + tempi=box[i].y*30-30; + tempj=30*box[i].x-16; + DefineButton(tempi,tempj,29,29,box[i].button_id,0xAFFFAF); + WriteNumber(tempi+11,tempj+11,0x80,0,box[i].text); + } + } +} + +void initialization() +{ +int i,j,t; +t=0; + FOR (i=1;i<=9;i++) + { + FOR (j=1;j<=9;j++) + { + t++; + box[t].x=j; + box[t].y=i; + box[t].mark=1; + box[t].button_id=500+t; + box[t].text=Generate(t); + } + } +} + +int Generate(int xx) +{ + int temp,k,p; + p=2; + WHILE (p==2) + { + temp=random(81)+10; + p=1; + FOR (k=1; k> 8; +} + +inline fastcall word GetButtonID(){ + EAX = 17; + $int 0x40 + EAX = EAX >> 8; +} + +inline fastcall dword strlen(dword EDI){ + EAX=0; + ECX=-1; + $REPNE $SCASB + EAX-=2+ECX; +} + +byte WindowRePaint=0; +inline fastcall void WindowRedrawStatus(dword EBX) +{ + EAX = 12; // function 12:tell os about windowdraw + $int 0x40 + IF (EBX==1) WindowRePaint=1; ELSE WindowRePaint=0; +} + +void DefineAndDrawWindow(dword x,y,sizeX,sizeY,byte mainAreaType,dword mainAreaColour,byte headerType,dword headerColour,EDI) +{ + EBX = x << 16 + sizeX; + ECX = y << 16 + sizeY; + EDX = mainAreaType << 24 | mainAreaColour; + ESI = headerType << 24 | headerColour; + $xor eax,eax + $int 0x40 +} + + +void WriteText(dword x,y,byte fontType, dword color, EDX, ESI) +{ + EAX = 4; + EBX = x<<16+y; + ECX = fontType<<24+color; + $int 0x40; +} + +void WriteNumber(dword x,y,byte fontType, ESI, ECX) +{ +EAX = 47; +EBX = 2<<16; +EDX = x<<16+y; +ESI = fontType<<24+ESI; +$int 0x40; +} + + + +void DrawBar(dword x,y,w,h,EDX) +{ + EAX = 13; + EBX = x<<16+w; + ECX = y<<16+h; + $int 0x40 +} + +void DefineButton(dword x,y,w,h,EDX,ESI) +{ + EAX = 8; + EBX = x<<16+w; + ECX = y<<16+h; + $int 0x40 +} + +inline fastcall void DeleteButton(dword EDX) +{ + EAX = 8; + EDX += BT_DEL; + $int 0x40; +} + +void DrawFlatButton(dword x,y,width,height,id,color,text) +{ + DrawRegion_3D(x,y,width,height,0x94AECE,0x94AECE); + DrawRegion_3D(x+1,y+1,width-2,height-2,0xFFFFFF,0xC7C7C7); + DrawBar(x+2,y+2,width-3,height-3,color); // + IF (id<>0) DefineButton(x,y,width,height,id+BT_HIDE,0xEFEBEF); // + WriteText(-strlen(text)*6+width/2+x+1,height/2-3+y,0x80,0,text,0); +} + + +dword generator; // random number generator - + +:int random(int max) +// get pseudo-random number - +{ + $rdtsc // eax & edx + $xor eax,edx + $not eax + + EBX = generator; + $ror ebx,3 + $xor ebx,0xdeadbeef + EBX += EAX; + generator = EBX; + + EAX += EBX; + EAX = EAX % max; + return EAX; +} + +:randomize() +// initialize random number generator - +{ + asm + { + mov eax,3 + int 0x40 + ror eax,16 + } + generator = EAX; +} + +inline fastcall ExitProcess(){ + EAX = -1; // close this program + $int 0x40 +} + +void DrawRegion_3D(dword x,y,width,height,color1,color2) +{ + DrawBar(x,y,width+1,1,color1); + DrawBar(x,y+1,1,height-1,color1); + DrawBar(x+width,y+1,1,height,color2); + DrawBar(x,y+height,width,1,color2); +} \ No newline at end of file diff --git a/programs/games/bnc/trunk/bk100.png b/programs/games/bnc/trunk/bk100.png new file mode 100644 index 0000000000..dc317c26e0 Binary files /dev/null and b/programs/games/bnc/trunk/bk100.png differ diff --git a/programs/games/bnc/trunk/bk5.PNG b/programs/games/bnc/trunk/bk5.PNG new file mode 100644 index 0000000000..08811b6fc5 Binary files /dev/null and b/programs/games/bnc/trunk/bk5.PNG differ diff --git a/programs/games/bnc/trunk/bnc.asm b/programs/games/bnc/trunk/bnc.asm new file mode 100644 index 0000000000..1aa4909a0e --- /dev/null +++ b/programs/games/bnc/trunk/bnc.asm @@ -0,0 +1,22 @@ +;************************************************ +;* Bulls-and-Cows */ Kolibri OS /* +;************************* 25/10/2007 ********* +include 'main.inc' ; main.inc +include 'data.inc' ; data.inc +include 'code.inc' ; code.inc +include 'macs.inc' ; macs.inc +include 'macros.inc' ; standard macro definitions - mcall & all-all-all + + BeginProgram + call clears + call rndseed + call rnew + + main_loop + + CODE_SECTION + + DATA_SECTION + + EndProgram + diff --git a/programs/games/bnc/trunk/bnc.txt b/programs/games/bnc/trunk/bnc.txt new file mode 100644 index 0000000000..7cfb2c3be6 --- /dev/null +++ b/programs/games/bnc/trunk/bnc.txt @@ -0,0 +1,53 @@ +Bulls-and-Cows v0.01 --- bnc.bin --- http://kolibrios.org + +Logical game. You must guess secret 4-digit number (Non-repeated). +Input your move by keys from '0' to '9', edit it by 'BackSpace', +and place into game by 'Enter'. + +'Bull' stands for the digit is in right place. +'Cow' means it is present, but is placed wrong. +Program gives you total info from which you may deduce next move. +Your aim is - 4 bulls. 9 moves is more then enought. + + (* *) + + , . + , ;)) + ... + + - , + 0 9, . + , + . + + : , + - +, - , 1 . + , - . + , + , . + . + + . 4 - . + , . + + : + . +1234567890 ENTER. + BackSpace. + , + . ( + ), ... + - . + + + bnc4.png, bnc6.png - ... + + bk100.png - 100 . +, 5-6 . - 95% + () . 7 - 100% + , +, . + , 7 , +100% . + diff --git a/programs/games/bnc/trunk/bnc4.PNG b/programs/games/bnc/trunk/bnc4.PNG new file mode 100644 index 0000000000..0f81d0e2a6 Binary files /dev/null and b/programs/games/bnc/trunk/bnc4.PNG differ diff --git a/programs/games/bnc/trunk/bnc6.PNG b/programs/games/bnc/trunk/bnc6.PNG new file mode 100644 index 0000000000..a63ca6f1ca Binary files /dev/null and b/programs/games/bnc/trunk/bnc6.PNG differ diff --git a/programs/games/bnc/trunk/code.inc b/programs/games/bnc/trunk/code.inc new file mode 100644 index 0000000000..87664802a3 --- /dev/null +++ b/programs/games/bnc/trunk/code.inc @@ -0,0 +1,205 @@ +macro CODE_SECTION + +{ +;+-----------------------------------+ Uses:eax,ebx,edx +;|-------Random Number Generator-----|---------------------------| +;+-----------------------------------+ + rndseed: ; + mov eax,26 ; func 26 subfunc 9 + mov ebx,9 ; + int 0x40 ; + mov dword[seed],eax ; system time from boot + random9: ; RND=[0..9] + mov eax,3 ; + int 0x40 ; get current time + shr eax,16 ; seconds in al + add eax,dword[seed] ; + imul eax,0x15a4e35 ; random formula rv=rv*0x15a4e35+1 + inc eax ; return (rv&0x7FFFFFFF)%N + mov dword[seed],eax ; + and eax,0x07FFFFFFF ; + mov ebx,10 ; N=10 + xor edx,edx ; + div bx ; eax/ebx= int[result]+rest + add dl,'0' ; DL='0'..'9' - rest + ret ; +;================================================= + rnew: ; New Random Secret Number + xor esi,esi ;---------------------------- + LoopBegin lb1,0 ; + rn: call random9 ; DL=RND('0'..'9') + xor edi,edi ; + lb2: cmp byte[nA+edi],dl ; + je rn ; + inc edi ; + cmp edi,4 ; 4 digit + jne lb2 ; + mov byte[nA+esi],dl ;nA - secret number without double digits + inc esi ;nA - 4 bytes of non-repeated digits '0'..'9' + LoopEnd lb1,4 ; + ret ; +;------------------------------------- + numStr: inc dword[turn] ; turn++ + mov ebx,dword[turn] ; + push ebx ; + pop ecx ; ebx=ecx=turn + add cl,'0' ; + add ch,':' ; + dec ebx ; -1 + shl ebx,4 ; *16 + mov word[tStr+ebx],cx; begin string by turn number +':' + ret +;------------------------------------- + paint_list: + LoopBegin lbList,0 + mov ebx,ecx + shl ebx,4 ; *16 + mov edx,tStr + add edx,ebx + add ebx,25*65536 ;x + add ebx,45 ;y + mov eax,4 ;func 4 + mov ecx,cTxt ;color + mov esi,16 ;line length + int 0x40 + LoopEnd lbList,9 ; + ret +;-INPUT------------------------------------ KEYBOARD INPUT ----------- + input: ;ah - key code + mov byte[char],ah ;char<-ah + cmp ah,13 ;13- enter + jne @f + jmp _enter + @@: + cmp ah,8 ;8 - del backSpace <=| + jne @f + jmp _back + @@: + + cmp ah,'0' ; '0'..'9' + jae @f + ret + @@: cmp ah,'9' + jbe @f + ret ; if not - return subroutine + @@: +;------------------------pressed:0123456789----------- + cmp byte[posn],4 + je @f ;full line - do nothing + call ptrStr ;esi - pointer at tStr + xor eax,eax + add al,byte[posn] + add esi,eax ;+posn + mov al,byte[char] + mov byte[esi+3],al ;esi+3 = place 4 digits + inc byte[posn] ;next digit + @@: ret +;------------------------ + _enter: + cmp byte[posn],4 ; Enter Turn + je @f + ret + @@: + call check ; check input for difference + cmp eax,0 + je @f + ret + @@: + call bcalculate ; calc b+c + call numStr ; 'N:' next string number + mov byte[posn],0 ; new line + ret +;------------------------ + _back: cmp byte[posn],0 ; empty input - do nothing + je @f + dec byte[posn] + call ptrStr ;esi = pointer at tStr + xor eax,eax + add al,byte[posn] ; byte of esi +posn + add esi,eax ;+posn + mov byte[esi+3],' ' + @@: ret +;===========================================--end - input - + ptrStr: ; esi=tStr+turn*16 + mov esi,dword[turn] + shl esi,4 + add esi,tStr + ret +;------------------------ + clears: mov ecx,160 + clr1: mov byte[tStr+ecx],0;' ' + loop clr1 + mov byte[tStr],0;' ' + mov byte[posn],0 + mov dword[turn],0 + ret +;-------------------------CHECK---Input--[1234]------- + check: ; check for similar digits (equal) + call ptrStr ; esi ...pointer + ;mov esi,dword[turn] + ;shl esi,4 + ;add esi,tStr + xor eax,eax + xor edi,edi ; edi - counter 0..3 + xor ecx,ecx + lb4ch: mov dl,byte[esi+ecx+3] + cmp byte[esi+edi+3],dl + jne @f + inc eax ; =equivalent +1 + @@: + inc edi ; + cmp edi,4 ; cycle ,4 digits + jne lb4ch ; + xor edi,edi ; edi - counter 0..3 + + inc ecx + cmp ecx,4 + jne lb4ch + + sub eax,4 ; must be 4, if more - doubles present + ret + + bcalculate: ;------------------; calc b:+c: + call ptrStr ; esi ... + add esi,3 + ;inc esi + ;inc esi ;+3 + ;inc esi ; ...- pointer to Line + LoopBegin lbBu1,0 ;bull count cycle ecx=0..3 + mov bl,byte[nA+ecx] + mov dl,byte[esi+ecx] + cmp bl,dl + jne @f + inc byte[nBul] + @@: + LoopEnd lbBu1,4 + + mov ax,'B:' ; output Bulls + mov word[esi+6],ax + mov al,byte[nBul] + add al,'0' + mov byte[esi+8],al + + LoopBegin lbCo2,0 ;Cows count cycle ecx=0..3 + mov dl,byte[esi+ecx] + xor edi,edi ; cycle edi=0..3 + lb3: mov bl,byte[nA+edi] + cmp bl,dl + jne @f + inc byte[nCow] ;Cows+Bulls + @@: inc edi ; + cmp edi,4 ; + jne lb3 ; + LoopEnd lbCo2,4 ;endcycle ecx + + mov ax,'C:' ; output Cows + mov word[esi+10],ax + mov al,byte[nCow] + sub al,byte[nBul] + add al,'0' + mov byte[esi+12],al + mov dword[nBul],0 ;nCow=posn=char=0 + ret +;-------------------------------------- +} + diff --git a/programs/games/bnc/trunk/data.inc b/programs/games/bnc/trunk/data.inc new file mode 100644 index 0000000000..6190181f32 --- /dev/null +++ b/programs/games/bnc/trunk/data.inc @@ -0,0 +1,35 @@ +;#************************** +;#* BNC-DATA * +;#************************** 25/10/2007 +macro DATA_SECTION +{ +;----------------------------------------------------------------------------- + header: db 'Bulls-and-Cows v0.01 ' + new: db 'New' +;--------------------------------- + nBul: db 0 + nCow: db 0 +;--------------------------------- + posn: db 0 ;position 0-4 : 4 - finish -enter + char: db 0 + ; + nA: dd 0 + turn: dd 0 + seed: dd 0 + ; + tStr: ; table of Strings = 10*(16) bytes +;------------------------------------------- + rb 160 + ;-- '0123456789ABCDEF'--- + ;-- 1: 1234 B:4 C:0 --- + ;db ' ';1 + ;db ' ';2 + ;db ' ';3 + ;db ' ';4 + ;db ' ';5 + ;db ' ';6 + ;db ' ';7 + ;db ' ';8 + ;db ' ';9 + +} diff --git a/programs/games/bnc/trunk/draw.inc b/programs/games/bnc/trunk/draw.inc new file mode 100644 index 0000000000..744c90a995 --- /dev/null +++ b/programs/games/bnc/trunk/draw.inc @@ -0,0 +1,595 @@ + +DrawLine: + + mov eax,38 + mov ebx,[Line.x1] + mov ecx,[Line.y1] + mov edx,[Line.color] + shl ebx,16 + shl ecx,16 + add ebx,[Line.x2] + add ecx,[Line.y2] + mcall + + ret + +DrawPixel: + + xor eax,eax + inc al + mov ebx,[Pixel.x] + mov ecx,[Pixel.y] + mov edx,[Pixel.color] + mcall + + ret + +RectangleContour: + + mov eax,38 + mov ebx,[Rectangle.x] + mov ecx,[Rectangle.y] + mov edx,[Rectangle.color] + mov esi,ebx + mov edi,ecx + shl ebx,16 + shl ecx,16 + add ebx,esi + add ecx,edi + add ebx,[Rectangle.width] + mcall + + mov eax,38 + mov ebx,[Rectangle.x] + mov ecx,[Rectangle.y] + mov edx,[Rectangle.color] + add ecx,[Rectangle.height] + mov esi,ebx + mov edi,ecx + shl ebx,16 + shl ecx,16 + add ebx,esi + add ecx,edi + add ebx,[Rectangle.width] + mcall + + mov eax,38 + mov ebx,[Rectangle.x] + mov ecx,[Rectangle.y] + mov edx,[Rectangle.color] + mov esi,ebx + mov edi,ecx + shl ebx,16 + shl ecx,16 + add ebx,esi + add ecx,edi + add ecx,[Rectangle.height] + mcall + + mov eax,38 + mov ebx,[Rectangle.x] + mov ecx,[Rectangle.y] + mov edx,[Rectangle.color] + add ebx,[Rectangle.width] + mov esi,ebx + mov edi,ecx + shl ebx,16 + shl ecx,16 + add ebx,esi + add ecx,edi + add ecx,[Rectangle.height] + mcall + + ret + +;eax -first color +;ebx- second color +;OUT +;eax - averege color +calculate_average_color: + + and eax,0xffffff + and ebx,0xffffff + + mov [b_min],al + mov [b_max],bl + shr eax,8 + shr ebx,8 + mov [g_min],al + mov [g_max],bl + shr eax,8 + shr ebx,8 + mov [r_min],al + mov [r_max],bl + + xor eax,eax + xor ebx,ebx + mov al,[r_max] + mov bl,[r_min] + add eax,ebx + shr eax,1 + mov [r],al + + xor eax,eax + xor ebx,ebx + mov al,[g_max] + mov bl,[g_min] + add eax,ebx + shr eax,1 + mov [g],al + + xor eax,eax + xor ebx,ebx + mov al,[b_max] + mov bl,[b_min] + add eax,ebx + shr eax,1 + mov [b],al + + xor eax,eax + mov al,[r] + shl eax,8 + mov al,[g] + shl eax,8 + mov al,[b] + + ret + +;eax -color +;ebx- sub value +;OUT +;eax - sabved color +calculate_sabved_color: + + and eax,0xffffff + + mov [b],al + shr eax,8 + mov [g],al + shr eax,8 + mov [r],al + + sub [r],bl + sub [g],bl + sub [b],bl + + xor eax,eax + mov al,[r] + shl eax,8 + mov al,[g] + shl eax,8 + mov al,[b] + + ret + +DrawString: + + mov ebx,[Button.text] + call GetLengthString + mov esi,eax + + mov eax,4 + mov ebx,[Font.x] + shl ebx,16 + add ebx,[Font.y] + mov ecx,[Button.textcolor] + mov edx,[Button.text] + mcall + + ret + +;eax -first color +;ebx- second color +;ecx- x coordinat of rectangle +;edx- y coordinat of rectangle +;esi- rectangle size x +;edi- rectangle size y + +rectangle_gradient_right: + + mov [line_coordinat_x],ecx + mov [line_coordinat_y],edx + mov [line_size_x],esi + mov [line_size_y],edi + + mov ecx,esi + mov edx,dword pointer + call gradient + + mov ecx,[line_coordinat_y] + shl ecx,16 + add ecx,[line_coordinat_y] + add ecx,[line_size_y] + + mov eax,[line_size_x] + add [line_coordinat_x],eax + + mov esi,dword pointer + mov edi,[line_size_x] + + next_vertical_line_draw_right: + + mov eax,38 + mov ebx,[line_coordinat_x] + shl ebx,16 + add ebx,[line_coordinat_x] + mov edx,[esi] + and edx,0xffffff + mcall + + add esi,3 + sub [line_coordinat_x],1 + + dec edi + jnz next_vertical_line_draw_right + + ret + +;eax -first color +;ebx- second color +;ecx- x coordinat of rectangle +;edx- y coordinat of rectangle +;esi- rectangle size x +;edi- rectangle size y + +rectangle_gradient_left: + + mov [line_coordinat_x],ecx + mov [line_coordinat_y],edx + mov [line_size_x],esi + mov [line_size_y],edi + + mov ecx,esi + mov edx,dword pointer + call gradient + + mov ecx,[line_coordinat_y] + shl ecx,16 + add ecx,[line_coordinat_y] + add ecx,[line_size_y] + + mov esi,dword pointer + mov edi,[line_size_x] + + next_vertical_line_draw_left: + + mov eax,38 + mov ebx,[line_coordinat_x] + shl ebx,16 + add ebx,[line_coordinat_x] + mov edx,[esi] + and edx,0xffffff + mcall + + add esi,3 + add [line_coordinat_x],1 + + dec edi + jnz next_vertical_line_draw_left + + ret + +;eax -first color +;ebx- second color +;ecx- x coordinat of rectangle +;edx- y coordinat of rectangle +;esi- rectangle size x +;edi- rectangle size y + +rectangle_gradient_up: + + mov [line_coordinat_x],ecx + mov [line_coordinat_y],edx + mov [line_size_x],esi + mov [line_size_y],edi + + mov ecx,edi + mov edx,dword pointer + call gradient + + mov ebx,[line_coordinat_x] + shl ebx,16 + add ebx,[line_coordinat_x] + add ebx,[line_size_x] + + mov eax,[line_size_y] + add [line_coordinat_y],eax + + mov esi,dword pointer + mov edi,[line_size_y] + + next_horizontal_line_draw_up: + + mov eax,38 + mov ecx,[line_coordinat_y] + shl ecx,16 + add ecx,[line_coordinat_y] + mov edx,[esi] + and edx,0xffffff + mcall + + add esi,3 + sub [line_coordinat_y],1 + + dec edi + jnz next_horizontal_line_draw_up + + ret + +;eax -first color +;ebx- second color +;ecx- x coordinat of rectangle +;edx- y coordinat of rectangle +;esi- rectangle size x +;edi- rectangle size y + +rectangle_gradient_down: + + mov [line_coordinat_x],ecx + mov [line_coordinat_y],edx + mov [line_size_x],esi + mov [line_size_y],edi + + mov ecx,edi + mov edx,dword pointer + call gradient + + mov ebx,[line_coordinat_x] + shl ebx,16 + add ebx,[line_coordinat_x] + add ebx,[line_size_x] + + mov esi,dword pointer + mov edi,[line_size_y] + + next_horizontal_line_draw_down: + + mov eax,38 + mov ecx,[line_coordinat_y] + shl ecx,16 + add ecx,[line_coordinat_y] + mov edx,[esi] + and edx,0xffffff + mcall + + add esi,3 + add [line_coordinat_y],1 + + dec edi + jnz next_horizontal_line_draw_down + + ret + +;eax -first color +;ebx- second color +;ecx- length of line +;edx- pointer to memory for colors of gradient + +gradient: + + mov [length],ecx + + and eax,0xffffff + and eax,0xffffff + + mov [b_min],al + mov [b_max],bl + shr eax,8 + shr ebx,8 + mov [g_min],al + mov [g_max],bl + shr eax,8 + shr ebx,8 + mov [r_min],al + mov [r_max],bl + + mov eax,[length] + dec eax + mov [v],eax + fild [v] + + xor eax,eax + mov al,[r_max] + sub al,[r_min] + mov [v],eax + fild [v] + fdiv st0,st1 + fstp [step_r] + + xor eax,eax + mov al,[g_max] + sub al,[g_min] + mov [v],eax + fild [v] + fdiv st0,st1 + fstp [step_g] + + xor eax,eax + mov al,[b_max] + sub al,[b_min] + mov [v],eax + fild [v] + fdiv st0,st1 + fstp [step_b] + + fstp [v] + + xor eax,eax + mov al,[r_min] + mov [r],al + mov [v],eax + fild [v] + fstp [r_f] + + xor eax,eax + mov al,[g_min] + mov [g],al + mov [v],eax + fild [v] + fstp [g_f] + + xor eax,eax + mov al,[b_min] + mov [b],al + mov [v],eax + fild [v] + fstp [b_f] + + next_gradient_color_save: + + xor ebx,ebx + xor eax,eax + mov al,[r] + mov bl,al + shl eax,8 + mov al,[g] + shl eax,8 + mov al,[b] + + mov [edx],ax + mov [edx+2],bl + + fld [step_r] + fld [r_f] + fadd st0,st1 + fst [r_f] + fistp [v] + xor eax,eax + mov eax,[v] + mov [r],al + fstp [v] + + fld [step_g] + fld [g_f] + fadd st0,st1 + fst [g_f] + fistp [v] + xor eax,eax + mov eax,[v] + mov [g],al + fstp [v] + + fld [step_b] + fld [b_f] + fadd st0,st1 + fst [b_f] + fistp [v] + xor eax,eax + mov eax,[v] + mov [b],al + fstp [v] + + add edx,3 + + dec ecx + jnz next_gradient_color_save + + ret + +;IN +;NON +;OUT +;variable [skin_height] + +get_skin_height: + + pushad + + mov eax,48 + mov ebx,4 + int 0x40 + + mov [skin_height],eax + popad + + ret +;eax - x +;ebx - y +;ecx - size x +;edx - size y +;esi - pointer to memory for rectangle +SaveFonForRectangle: + + mov [Rectangle.x],eax + mov [Rectangle.y],ebx + mov [Rectangle.width],ecx + mov [Rectangle.height],edx + mov [PointerToMem],esi + + ;get bytes per string + mov eax,61 + mov ebx,2 + mcall + mov [BitsPerPixel],eax + + mov eax,61 + mov ebx,3 + mcall + mov [BytesPerString],eax + + + ;get window coordinats + mov eax,9 + mov ebx,dword IPC_table + or ecx,-1 + mcall + + mov eax,dword[IPC_table+34] + mov ebx,dword[IPC_table+38] + ;mov ecx,dword[IPC_table+42] + ;mov edx,dword[IPC_table+46] + ;mov [WindowCoordinatX],eax + ;mov [WindowCoordinatY],ebx + ;mov [WindowSizeX],ecx + ;mov [WindowSizeY],edx + + add eax,[Rectangle.x] + add ebx,[Rectangle.y] + + imul ebx,[BytesPerString] + mov esi,[Rectangle.width] + + cmp [BitsPerPixel],24 + jne no_24 + + lea eax,[eax+eax*2] + lea esi,[esi+esi*2] + mov edi,3 + jmp exit_bits_per_pixel + no_24: + + shl eax,2 + shl esi,2 + mov edi,4 + exit_bits_per_pixel: + + add eax,ebx + + mov ebx,[BytesPerString] + sub ebx,esi + mov [offset],ebx + + mov esi,[PointerToMem] + mov edx,[Rectangle.height] + next_string_pixels_save: + + mov ecx,[Rectangle.width] + next_pixel_save: + + mov ebx,[gs:eax] + and ebx,0xffffff + mov [esi],bx + shr ebx,16 + mov [esi+2],bl + + add esi,3 + add eax,edi + dec ecx + jnz next_pixel_save + + add eax,[offset] + dec edx + jnz next_string_pixels_save + + exit_: + ret diff --git a/programs/games/bnc/trunk/lang.inc b/programs/games/bnc/trunk/lang.inc new file mode 100644 index 0000000000..30c0149bd9 --- /dev/null +++ b/programs/games/bnc/trunk/lang.inc @@ -0,0 +1 @@ +lang fix ru \ No newline at end of file diff --git a/programs/games/bnc/trunk/macros.inc b/programs/games/bnc/trunk/macros.inc new file mode 100644 index 0000000000..50d2745750 --- /dev/null +++ b/programs/games/bnc/trunk/macros.inc @@ -0,0 +1,270 @@ +; new application structure +macro meos_app_start + { + use32 + org 0x0 + + db 'MENUET01' + dd 0x01 + dd __start + dd __end + dd __memory + dd __stack + + if used __params & ~defined __params + dd __params + else + dd 0x0 + end if + + dd 0x0 + } +MEOS_APP_START fix meos_app_start + +macro code + { + __start: + } +CODE fix code + +macro data + { + __data: + } +DATA fix data + +macro udata + { + if used __params & ~defined __params + __params: + db 0 + __end: + rb 255 + else + __end: + end if + __udata: + } +UDATA fix udata + +macro meos_app_end + { + align 32 + rb 2048 + __stack: + __memory: + __end: + } +MEOS_APP_END fix meos_app_end + + +; macro for defining multiline text data +struc mstr [sstring] + { + forward + local ssize + virtual at 0 + db sstring + ssize = $ + end virtual + dd ssize + db sstring + common + dd -1 + } + + +; strings +macro sz name,[data] { ; from MFAR [mike.dld] + common + if used name + label name + end if + forward + if used name + db data + end if + common + if used name + .size = $-name + end if +} + +macro lsz name,[lng,data] { ; from MFAR [mike.dld] + common + if used name + label name + end if + forward + if (used name)&(lang eq lng) + db data + end if + common + if used name + .size = $-name + end if +} + + + +; easy system call macro +macro mpack dest, hsrc, lsrc +{ + if (hsrc eqtype 0) & (lsrc eqtype 0) + mov dest, (hsrc) shl 16 + lsrc + else + if (hsrc eqtype 0) & (~lsrc eqtype 0) + mov dest, (hsrc) shl 16 + add dest, lsrc + else + mov dest, hsrc + shl dest, 16 + add dest, lsrc + end if + end if +} + +macro __mov reg,a,b { ; mike.dld + if (~a eq)&(~b eq) + mpack reg,a,b + else if (~a eq)&(b eq) + mov reg,a + end if +} + +macro mcall a,b,c,d,e,f { ; mike.dld + __mov eax,a + __mov ebx,b + __mov ecx,c + __mov edx,d + __mov esi,e + __mov edi,f + int 0x40 +} + + + +; optimize the code for size +__regs fix + +macro add arg1,arg2 + { + if (arg2 eqtype 0) + if (arg2) = 1 + inc arg1 + else + add arg1,arg2 + end if + else + add arg1,arg2 + end if + } + +macro sub arg1,arg2 + { + if (arg2 eqtype 0) + if (arg2) = 1 + dec arg1 + else + sub arg1,arg2 + end if + else + sub arg1,arg2 + end if + } + +macro mov arg1,arg2 + { + if (arg1 in __regs) & ((arg2 eqtype 0) | (arg2 eqtype '0')) + if (arg2) = 0 + xor arg1,arg1 + else if (arg2) = 1 + xor arg1,arg1 + inc arg1 + else if (arg2) = -1 + or arg1,-1 + else if (arg2) > -128 & (arg2) < 128 + push arg2 + pop arg1 + else + mov arg1,arg2 + end if + else + mov arg1,arg2 + end if + } + + +macro struct name + { + virtual at 0 + name name + sizeof.#name = $ - name + end virtual + } + +; structures used in MeOS +struc process_information + { + .cpu_usage dd ? ; +0 + .window_stack_position dw ? ; +4 + .window_stack_value dw ? ; +6 + .not_used1 dw ? ; +8 + .process_name rb 12 ; +10 + .memory_start dd ? ; +22 + .used_memory dd ? ; +26 + .PID dd ? ; +30 + .x_start dd ? ; +34 + .y_start dd ? ; +38 + .x_size dd ? ; +42 + .y_size dd ? ; +46 + .slot_state dw ? ; +50 + dw ? ; +52 - reserved + .client_left dd ? ; +54 + .client_top dd ? ; +58 + .client_width dd ? ; +62 + .client_height dd ? ; +66 + .wnd_state db ? ; +70 + rb (1024-71) + } +struct process_information + +struc system_colors + { + .frame dd ? + .grab dd ? + .grab_button dd ? + .grab_button_text dd ? + .grab_text dd ? + .work dd ? + .work_button dd ? + .work_button_text dd ? + .work_text dd ? + .work_graph dd ? + } +struct system_colors + + +; constants + +; events +EV_IDLE = 0 +EV_TIMER = 0 +EV_REDRAW = 1 +EV_KEY = 2 +EV_BUTTON = 3 +EV_EXIT = 4 +EV_BACKGROUND = 5 +EV_MOUSE = 6 +EV_IPC = 7 +EV_STACK = 8 + +; event mask bits for function 40 +EVM_REDRAW = 1b +EVM_KEY = 10b +EVM_BUTTON = 100b +EVM_EXIT = 1000b +EVM_BACKGROUND = 10000b +EVM_MOUSE = 100000b +EVM_IPC = 1000000b +EVM_STACK = 10000000b \ No newline at end of file diff --git a/programs/games/bnc/trunk/macs.inc b/programs/games/bnc/trunk/macs.inc new file mode 100644 index 0000000000..15e087071c --- /dev/null +++ b/programs/games/bnc/trunk/macs.inc @@ -0,0 +1,86 @@ +;************************************ +;******** ******************* +;************************************ +; Constants= colors +;-----------------------梥:0xRRGGBB +cBLACK = 0x000000 ; +cRED = 0xFF0000 ; +cYELLOW = 0xFFFF00 ; +cGREEN = 0x00FF00 ; +cNAVY = 0x0000FF ; ᨭ +cMAGENTA = 0xFF00FF ; +cBLUE = 0x00FFFF ; 㡮 +cWHITE = 0xFFFFFF ; +cBROWN = 0x554433 ; 筥 +cB equ cBLACK +cW equ cWHITE + +macro BeginProgram + { + use32 + org 0x0 + + db 'MENUET01' + dd 0x01 + dd __start + dd __end + dd __memory ; 0x10000 + dd __stack ; 0x10000 + dd 0x0 ; dd __params + dd 0x0 + __start: + } + +macro EndProgram + { + align 32 + rb 256 ;512 + __end: + __stack: + __memory: + } + + +macro LoopBegin lab,begi +{ + push ecx ; ECX->STACK store old + mov ecx,begi + lab: + push ecx ; ECX->STACK counter store +} + +macro LoopEnd lab,endi +{ + pop ecx ;ECX<-STACK counter restore + inc ecx + cmp ecx,endi + jne lab + pop ecx ;ECX<-STACK restore old +} + +macro SetEventMask mmm +{ + mov eax,40 + mov ebx,mmm + int 0x40 +} + +macro redraw_begin +{ + mov eax,12 + mov ebx,1 + int 0x40 +} + +macro redraw_end +{ + mov eax,12 + mov ebx,2 + int 0x40 +} + +macro EventIs eee,lll +{ + cmp eax,eee + je lll +} diff --git a/programs/games/bnc/trunk/main.inc b/programs/games/bnc/trunk/main.inc new file mode 100644 index 0000000000..82c9839a8e --- /dev/null +++ b/programs/games/bnc/trunk/main.inc @@ -0,0 +1,74 @@ +;#*************** +;#* BNC.MAIN() +;#*************** +cTxt equ 0x10000000 +cTxtW equ 0x10FFFFFF + +macro main_loop +{ +draw_window: + redraw_begin +;------------------------------ + ;--- MainWindow + mcall 0,100*65536+250,100*65536+250,0x02FFFFFF ,0x808899AA ,0xFFAAcc + ;--- MainWindow TitleBar + mcall 4,8*65536+8,0x00224422,header,20 + ;--- Button - Close MainWindow + mcall 8,230*65536+12, 5*65536+12, 100 ,0xFF6611 + ;--- Button - "New" ... + mcall 8,190*65536+50,25*65536+15, 200 ,0xAA66CC + mcall 4,205*65536+30,cTxtW,new,3 + ;--- Button - "Turn" ... + ;mcall 8,190*65536+50,50*65536+15, 150 ,0x116611 +;-----------------------------1234-secret-number---show + ; mcall 4, 50*65536+30,cTxt ,nA,4 +;-----------------------------9-lines- + call paint_list + redraw_end +;============================= + event_wait: + mcall 23,100 +;------------------------------------------------------------------------------- +; event in eax - and what will happen +;------------------------------------------------------------------------------- + EventIs EV_REDRAW,draw_window ; redraw window + EventIs EV_KEY,key ; pressed key + EventIs EV_BUTTON,button ; one clicks button + jmp event_wait ; returns at point of waiting for +;------------------------------------------------------------------------------- +; Events handler +;------------------------------------------------------------------------------- +key: ; + mov eax,2 ; key code in ah. + int 0x40 ; + cmp ah,27 ; ESC? + je close ; exit on ESC + + call input ; input 0-9,Enter,<_BackSpace + + jmp draw_window ; event_wait ; +button: ; + mov eax,17 ; button ID in ah + int 0x40 ; +;------------------------------------------------------------------------------- +; Buttons handler +;------------------------------------------------------------------------------- + cmp ah,100 ; id=100("Close window")? + jne noclose ; + close: ; + mov eax,-1 ; CLOSE all + int 0x40 ; + noclose: ; + cmp ah,150 ; id=150 "Turn" + je @F + call rnew ; id=200 "New" ->nA + + call clears + jmp draw_window ;event_wait + + @@: + call paint_list + jmp event_wait +; +} + diff --git a/programs/games/checkers/trunk/board.h b/programs/games/checkers/trunk/board.h new file mode 100644 index 0000000000..59f3edfb28 --- /dev/null +++ b/programs/games/checkers/trunk/board.h @@ -0,0 +1,1410 @@ +#ifndef _HEADER_BOARD_H +#define _HEADER_BOARD_H + +#ifndef __MENUET__ +#include +#include +#include +#include +#include +#include +#endif +#include "position.h" +#include "history.h" +#include "gr-draw.h" + +int ssf = 0; + +struct TIntPoint +{ + TIntPoint() {} + TIntPoint(int x, int y) : x(x), y(y) {} + TIntPoint(const TIntPoint &p) : x(p.x), y(p.y) {} + + TIntPoint &operator=(const TIntPoint &p) {x = p.x; y = p.y; return *this;} + + int x, y; +}; + +struct TRealPoint +{ + TRealPoint() {} + TRealPoint(double x, double y) : x(x), y(y) {} + TRealPoint(const TRealPoint &p) : x(p.x), y(p.y) {} + TRealPoint(const TIntPoint &p) : x(p.x), y(p.y) {} + + TRealPoint &operator=(const TRealPoint &p) {x = p.x; y = p.y; return *this;} + TRealPoint &operator=(const TIntPoint &p) {x = p.x; y = p.y; return *this;} + + TIntPoint Round() {return TIntPoint((int)floor(x+0.5), (int)floor(y+0.5));} + + double x, y; +}; + +struct TProjectivePoint +{ + TProjectivePoint() {} + TProjectivePoint(const TProjectivePoint &p) : x(p.x), y(p.y), z(p.z) {} + TProjectivePoint(double x, double y, double z = 1) : x(x), y(y), z(z) {} + TProjectivePoint(const TIntPoint &p, double z = 1) : x(p.x), y(p.y), z(z) {} + TProjectivePoint(const TRealPoint &p, double z = 1) : x(p.x), y(p.y), z(z) {} + + int IsCorrect() const {return fabs(x) > Eps || fabs(y) > Eps || fabs(z) > Eps;} + int IsFinite() const; + TRealPoint rpnt() const; + int rpnt(TRealPoint &p) const; + TIntPoint pnt() const; + int pnt(TIntPoint &p) const; + + TProjectivePoint &operator=(const TProjectivePoint &p); + TProjectivePoint &operator=(const TIntPoint &p) {x = p.x; y = p.y; z = 1; return *this;} + TProjectivePoint &operator=(const TRealPoint &p) {x = p.x; y = p.y; z = 1; return *this;} + TProjectivePoint &operator*=(int n) {x *= n; y *= n; z *= n; return *this;} + friend TProjectivePoint operator*(const TProjectivePoint &p, int n) + {return TProjectivePoint(p.x * n, p.y * n, p.z * n);} + friend TProjectivePoint operator*(int n, const TProjectivePoint &p) + {return TProjectivePoint(n * p.x, n * p.y, n * p.z);} + TProjectivePoint &operator*=(double n) {x *= n; y *= n; z *= n; return *this;} + friend TProjectivePoint operator*(const TProjectivePoint &p, double n) + {return TProjectivePoint(p.x * n, p.y * n, p.z * n);} + friend TProjectivePoint operator*(double n, const TProjectivePoint &p) + {return TProjectivePoint(n * p.x, n * p.y, n * p.z);} + + double px() const {return x/z;} + double py() const {return y/z;} + + double x, y, z; + + static const double Eps, FR; +}; + +const double TProjectivePoint::Eps = 1e-12; +const double TProjectivePoint::FR = 1e+4; + +inline int TProjectivePoint::IsFinite() const +{ + double fz = fabs(z); + return fz > Eps && fabs(x) < fz * FR && fabs(y) < fz * FR; +} + +TRealPoint TProjectivePoint::rpnt() const +{ + if (!IsFinite()) return TRealPoint(0, 0); + else return TRealPoint(x/z, y/z); +} + +inline int TProjectivePoint::rpnt(TRealPoint &p) const +{ + if (!IsFinite()) {p.x = 0; p.y = 0; return 0;} + else {p.x = x/z; p.y = y/z; return 1;} +} + +inline TIntPoint TProjectivePoint::pnt() const +{ + if (!IsFinite()) return TIntPoint(INT_MIN, INT_MIN); + else return TIntPoint((int)floor(x/z + 0.5), (int)floor(y/z + 0.5)); +} + +inline int TProjectivePoint::pnt(TIntPoint &p) const +{ + if (!IsFinite()) {p.x = INT_MIN; p.y = INT_MIN; return 0;} + else + { + p.x = (int)floor(x/z + 0.5); + p.y = (int)floor(y/z + 0.5); + return 1; + } +} + +TProjectivePoint &TProjectivePoint::operator=(const TProjectivePoint &p) +{ + x = p.x; y = p.y; z = p.z; + return *this; +} + + +class TProjectiveMap +{ +public: + TProjectiveMap() {} + TProjectiveMap(int n) {p[0].x = p[1].y = p[2].z = n; + p[0].y = p[0].z = p[1].x = p[1].z = p[2].x = p[2].y = 0;} + TProjectiveMap(const TProjectiveMap &map) + {p[0] = map.p[0]; p[1] = map.p[1]; p[2] = map.p[2];} + TProjectiveMap(const TProjectivePoint pnt[]) + {p[0] = pnt[0]; p[1] = pnt[1]; p[2] = pnt[2];} + TProjectiveMap(const TProjectivePoint &p0, const TProjectivePoint &p1, + const TProjectivePoint &p2) {p[0] = p0; p[1] = p1; p[2] = p2;} + + TProjectiveMap &operator=(const TProjectiveMap &map) + {p[0] = map.p[0]; p[1] = map.p[1]; p[2] = map.p[2]; return *this;} + TProjectiveMap &operator=(const TProjectivePoint pnt[]) + {p[0] = pnt[0]; p[1] = pnt[1]; p[2] = pnt[2]; return *this;} + TProjectiveMap &operator=(int n) {p[0].x = p[1].y = p[2].z = n; + p[0].y = p[0].z = p[1].x = p[1].z = p[2].x = p[2].y = 0; return *this;} + + TProjectivePoint operator()(const TProjectivePoint &point) const; + friend TProjectiveMap operator*(const TProjectiveMap &a, const TProjectiveMap &b); + TProjectiveMap &operator*=(const TProjectiveMap &b); + TProjectiveMap &operator*=(int n) {p[0] *= n; p[1] *= n; p[2] *= n; return *this;} + friend TProjectiveMap operator*(const TProjectiveMap &a, int n) + {return TProjectiveMap(a.p[0] * n, a.p[1] * n, a.p[2] * n);} + friend TProjectiveMap operator*(int n, const TProjectiveMap &b) + {return TProjectiveMap(n * b.p[0], n * b.p[1], n * b.p[2]);} + TProjectiveMap Reversed() const; + TProjectiveMap &Reverse() {return (*this) = Reversed();} + friend TProjectiveMap operator/(const TProjectiveMap &a, const TProjectiveMap &b) + {return a * b.Reversed();} + TProjectiveMap &operator/=(const TProjectiveMap &b) {return (*this) *= b.Reversed();} + TProjectiveMap &operator/=(int n) {if (!n) (*this) = 0; return *this;} + TProjectivePoint Reversed(const TProjectivePoint &point) const; + + TProjectivePoint operator()(double x, double y, double z = 1) const + {return (*this)(TProjectivePoint(x, y, z));} + TProjectivePoint Reversed(double x, double y, double z = 1) const + {return Reversed(TProjectivePoint(x, y, z));} + + TProjectiveMap &Set4(const TProjectivePoint &a0, const TProjectivePoint &a1, + const TProjectivePoint &a2, const TProjectivePoint &a3); + TProjectiveMap &Set4(const TProjectivePoint a[]) {return Set4(a[0], a[1], a[2], a[3]);} + TProjectiveMap &Set4to4(const TProjectivePoint a[], const TProjectivePoint b[]) + {return Set4(b) /= TProjectiveMap().Set4(a);} + TProjectiveMap &Set4to4(const TProjectivePoint &a0, const TProjectivePoint &a1, + const TProjectivePoint &a2, const TProjectivePoint &a3, + const TProjectivePoint b[]) + {return Set4(b) /= TProjectiveMap().Set4(a0, a1, a2, a3);} + TProjectiveMap &Set4to4(const TProjectivePoint a[], + const TProjectivePoint &b0, const TProjectivePoint &b1, + const TProjectivePoint &b2, const TProjectivePoint &b3) + {return Set4(b0, b1, b2, b2) /= TProjectiveMap().Set4(a);} + TProjectiveMap &Set4to4(const TProjectivePoint &a0, const TProjectivePoint &a1, + const TProjectivePoint &a2, const TProjectivePoint &a3, + const TProjectivePoint &b0, const TProjectivePoint &b1, + const TProjectivePoint &b2, const TProjectivePoint &b3) + {return Set4(b0, b1, b2, b2) /= TProjectiveMap().Set4(a0, a1, a2, a3);} + +public: + TProjectivePoint p[3]; +}; + +TProjectivePoint TProjectiveMap::operator()(const TProjectivePoint &point) const +{ + return TProjectivePoint(p[0].x * point.x + p[1].x * point.y + p[2].x * point.z, + p[0].y * point.x + p[1].y * point.y + p[2].y * point.z, + p[0].z * point.x + p[1].z * point.y + p[2].z * point.z); +} + +TProjectiveMap operator*(const TProjectiveMap &a, const TProjectiveMap &b) +{ + return TProjectiveMap(a(b.p[0]), a(b.p[1]), a(b.p[2])); +} + +TProjectiveMap &TProjectiveMap::operator*=(const TProjectiveMap &b) +{ + TProjectivePoint p0 = (*this)(b.p[0]), p1 = (*this)(b.p[1]), p2 = (*this)(b.p[2]); + p[0] = p0; p[1] = p1; p[2] = p2; + return *this; +} + +TProjectiveMap TProjectiveMap::Reversed() const +{ + return TProjectiveMap(TProjectivePoint(p[1].y * p[2].z - p[2].y * p[1].z, + p[2].y * p[0].z - p[0].y * p[2].z, p[0].y * p[1].z - p[1].y * p[0].z), + TProjectivePoint(p[1].z * p[2].x - p[2].z * p[1].x, + p[2].z * p[0].x - p[0].z * p[2].x, p[0].z * p[1].x - p[1].z * p[0].x), + TProjectivePoint(p[1].x * p[2].y - p[2].x * p[1].y, + p[2].x * p[0].y - p[0].x * p[2].y, p[0].x * p[1].y - p[1].x * p[0].y)); +} + +TProjectivePoint TProjectiveMap::Reversed(const TProjectivePoint &point) const +{ + return TProjectivePoint((p[1].y * p[2].z - p[2].y * p[1].z) * point.x + + (p[1].z * p[2].x - p[2].z * p[1].x) * point.y + + (p[1].x * p[2].y - p[2].x * p[1].y) * point.z, + (p[2].y * p[0].z - p[0].y * p[2].z) * point.x + + (p[2].z * p[0].x - p[0].z * p[2].x) * point.y + + (p[2].x * p[0].y - p[0].x * p[2].y) * point.z, + (p[0].y * p[1].z - p[1].y * p[0].z) * point.x + + (p[0].z * p[1].x - p[1].z * p[0].x) * point.y + + (p[0].x * p[1].y - p[1].x * p[0].y) * point.z); +} + +TProjectiveMap &TProjectiveMap::Set4(const TProjectivePoint &a0, + const TProjectivePoint &a1, const TProjectivePoint &a2, const TProjectivePoint &a3) +{ + p[0] = a0; p[1] = a1; p[2] = a2; + TProjectivePoint K = Reversed(a3); + p[0] *= K.x; p[1] *= K.y; p[2] *= K.z; + return *this; +} + + +TRealPoint r_circle_pnt[13]; +TRealPoint r_star_pnt[13]; +const double r_star_large = 1.2, r_star_small = 0.8; +const double r_ch_lines[] = {0.8, 0.7, 0.6, 0.5}; + +void InitBoardData() +{ + int i, len; + double a, r; + len = NELEM(r_circle_pnt) - 1; + for (i = 0; i < len; i++) + { + a = 2 * i * M_PI / len; + r_circle_pnt[i].x = cos(a); + r_circle_pnt[i].y = sin(a); + } + r_circle_pnt[len] = r_circle_pnt[0]; + len = sizeof(r_star_pnt) / sizeof(r_star_pnt[0]) - 1; + for (i = 0; i < len; i++) + { + a = 2 * i * M_PI / len; + r = (i % 2) ? r_star_small : r_star_large; + r_star_pnt[i].x = cos(a) * r; + r_star_pnt[i].y = sin(a) * r; + } + r_star_pnt[len] = r_star_pnt[0]; +} + +class TChBoard; + +class TSomeDraw +{ +public: + TSomeDraw() {} + + virtual void Draw(TGraphDraw *drw, int w, int h) = 0; + virtual void DrawB(TGraphDraw *drw, TChBoard &brd); + virtual TIntPoint GetDSize(int w, int h) {return TIntPoint(INT_MIN, INT_MIN);} +}; + +class TChBoard +{ +public: + TChBoard(int id = 0); + + TProjectiveMap Get4PMap() const; + int GetW() const {return width;} + int GetH() const {return height;} + void ClearWH() {width = -1; height = -1;} + void Resize(int w, int h); + void Resize(TIntPoint size) {Resize(size.x, size.y);} + + TIntPoint PlToWin(double x, double y) const; + TIntPoint PlToWin(TRealPoint rp) const {return PlToWin(rp.x, rp.y);} + TRealPoint WinToPl(int x, int y) const; + TRealPoint WinToPl(TIntPoint p) const {return WinToPl(p.x, p.y);} + + void NewGame(); + int CanPlayerMove() const {return !IsPlayView && !game_end && !player[MainPos.wmove];} + + void Draw(TGraphDraw *drw); + int ResizeDraw(TGraphDraw *drw, int w, int h); + int CheckResize(TGraphDraw *drw); + int HaveCheckResize() const {return check_resize;} + void SetCheckResize(int cr) {check_resize = cr;} + int MouseClick(TGraphDraw *drw, int x, int y); + void UnMove(TGraphDraw *drw); + + int CMove(TGraphDraw *drw, int x, int y); + int AutoMove(TGraphDraw *drw, int nmove = 0, int draw_check = 1); + + enum PKey {PNull, PEnter, PLeft, PRight, PUp, PDown}; + PKey GetKeySide(PKey key); + int PKeyEvent(TGraphDraw *drw, PKey key = PEnter); +protected: + enum TextLineType {TLT_Main, TLT_Move, TLT_Wait, TLT_GameEnd, TLT_WrongMove, + TLT_PlDidntMove, TLT_PlWrongMove, TLT_WrongColor, + TLT_WfCell, TLT_WnfCell, TLT_WMustEat, TLT_WMustEatMore, + TLT_WNoMove, TLT_WChBack, TLT_WNotDm, TLT_WOnlyDiag, + TLT_WEatYour, TLT_WMoreOne, TLT_WNotDmE, TLT_WMustEatMoreD, + TLT_WTurnBack}; + void GetTextLine(char str[]) const; + void DrawTextLine(TGraphDraw *drw) const; + void LineB(TGraphDraw *drw, double x1, double y1, double x2, double y2) const; + void DrawCh(TGraphDraw *drw, double x0, double y0, const TRealPoint pnt[], int npnt, + int L = NELEM(r_ch_lines)) const; + void DrawIL(TGraphDraw *drw, double x0, double y0, int L) const; + void MoveErase(); + void CurPointClear(TGraphDraw *drw) const; + void RenewMPos() {if (MainPlay.GetPos(MainPos, CurMoveN) < 0) MainPos.Init();} + void PrintLMove(); + void SetNoMove(TGraphDraw *drw = 0, int force = 1); + TextLineType GetTLTfromA(int s) const; + void ChangeTLT(TGraphDraw *drw, TextLineType t); + TextLineType GetSimpleTLT() const; +public: + void ResetTextLine(TGraphDraw *drw); + TChPlayer *GetPlayer(int k) const {return player[k];} + void SetPlayer(int k, TChPlayer *pl) {player[k] = pl;} + int GetBottomColor() const {return BottomColor;} + void SetBottomColor(int c) {BottomColor = c & 1;} +public: + enum {textlineh = 14, min_brd = 120, max_delt = 20, min_brdsize = 70}; + int GetTextLineY() const; + TSomeDraw *GetSomeDraw() const {return some_draw;} + void SetSomeDraw(TSomeDraw *drw) {some_draw = drw;} + TIntPoint GetMinWSize() const {return min_wsize;} + void SetMinWSize(TIntPoint mws) {min_wsize = mws; Resize(width, height);} + void SetMinWSize(int w, int h) {SetMinWSize(TIntPoint(w, h));} + void DrawTimer(TGraphDraw *drw, double t, int wh = 0) const; + int GetNumMove() const {return MainPlay.GetN() - 1;} + int GetCurMoveN() const {return CurMoveN;} + int SetCurMoveN(int n, TGraphDraw *drw = 0); + int SetPlay(const PlayWrite &play); + PlayWrite GetPlay() const {return MainPlay;} + int GetPViewStatus() const {return IsPlayView;} + void SetPViewStatus(int pv) {IsPlayView = pv;} + void GoToCurMove(); + int GetGameEnd() const {return game_end;} + void EraseHistory() {hist_inited = 0;} + int ReinitHistory(); +protected: + double dw_delt, dw_cell; + int width, height; + TProjectiveMap PoleMap; + Position MainPos; + int BottomColor; + unsigned char TheMove[NUM_CELL]; + unsigned char Eaten[NUM_CELL]; + unsigned char BecameD; + TIntPoint CurPoint; + int game_end; + int check_resize; + TIntPoint delta_size; + TextLineType text_line_type; + PlayWrite MainPlay; + TChPlayer *player[2]; + TSomeDraw *some_draw; + TIntPoint min_wsize; + int CurMoveN, IsPlayView; + THistory history; + int hist_inited; +}; + +inline void TSomeDraw::DrawB(TGraphDraw *drw, TChBoard &brd) +{ + Draw(drw, brd.GetW(), brd.GetH()); +} + +void TChBoard::MoveErase() +{ + TheMove[0] = 0; + Eaten[0] = 0; + BecameD = 0; +} + +TChBoard::TChBoard(int id) : history(id) +{ + InitBoardData(); + player[0] = player[1] = 0; + dw_delt = 0.3; + dw_cell = 1; + BottomColor = 0; + check_resize = 0; + delta_size.x = 0; delta_size.y = 0; + some_draw = 0; + min_wsize.x = 80; min_wsize.y = 80; + ClearWH(); + Resize(400, 400); + NewGame(); +} + +TProjectiveMap TChBoard::Get4PMap() const +{ + return TProjectiveMap().Set4(TRealPoint(-dw_delt, -dw_delt), + TRealPoint(NW_CELL*dw_cell + dw_delt, -dw_delt), + TRealPoint(NW_CELL*dw_cell + dw_delt, NW_CELL*dw_cell + dw_delt), + TRealPoint(-dw_delt, NW_CELL*dw_cell + dw_delt)); +} + +void TChBoard::Resize(int w, int h) +{ + width = w; height = h; + if (width < min_wsize.x) width = min_wsize.x; + if (height < min_wsize.y) height = min_wsize.y; + for (;;) + { + if (some_draw) + { + TIntPoint dsz = some_draw->GetDSize(width, height); + if (dsz.x >= 0 && dsz.y >= 0) delta_size = dsz; + } + int change = 0; + if (width < delta_size.x + min_brdsize) + { + width = delta_size.x + min_brdsize; + change++; + } + if (height < delta_size.y + min_brdsize + textlineh) + { + height = delta_size.y + min_brdsize + textlineh; + change++; + } + if (!some_draw || !change) break; + } + double sx = max_delt, dx = width - 2*sx - delta_size.x; + double sy = max_delt, dy = height - 2*sy - delta_size.y - textlineh; + if (dy < min_brd) + { + double d = (min_brd - dy) / 2; + if (d > sy) d = sy; + sy -= d; dy += 2*d; + } + if (dx < min_brd) + { + double d = (min_brd - dx) / 2; + if (d > sx) d = sx; + sx -= d; dx += 2*d; + } + if (dy > dx) {sy += (dy - dx) / 2; dy = dx;} + double tx = (dx - dy * dy / dx) / 3; + PoleMap.Set4(TRealPoint(sx, sy + dy - 70*ssf), TRealPoint(sx + dx, sy + dy), + TRealPoint(sx + dx - tx, sy), TRealPoint(sx + tx, sy + 40*ssf)); + PoleMap /= Get4PMap(); +} + +TIntPoint TChBoard::PlToWin(double x, double y) const +{ + if (BottomColor == 1) y = NW_CELL*dw_cell - y; + else x = NW_CELL*dw_cell - x; + /**/if (ssf) y += 0.6 * sin(x);/**/ + return PoleMap(x, y).pnt(); +} + +TRealPoint TChBoard::WinToPl(int x, int y) const +{ + TRealPoint rpnt; + if (PoleMap.Reversed(x, y).rpnt(rpnt)) + { + /**/if (ssf) rpnt.y -= 0.6 * sin(rpnt.x);/**/ + if (BottomColor == 1) rpnt.y = NW_CELL*dw_cell - rpnt.y; + else rpnt.x = NW_CELL*dw_cell - rpnt.x; + return rpnt; + } + else return TRealPoint(-dw_cell - dw_delt, -dw_cell - dw_delt); +} + +void TChBoard::NewGame() +{ + int k; + MoveErase(); + MainPos.Init(); + MainPlay.Clear(); + for (k = 0; k < NW_CELL * 3 / 2; k++) MainPos.SH[k] = 1; + for (k = 0; k < NW_CELL * 3 / 2; k++) MainPos.SH[NUM_CELL - k - 1] = 2; + MainPlay.Add(0, MainPos); + CurMoveN = 0; + text_line_type = TLT_Main; + game_end = 0; + CurPoint.x = -1; CurPoint.y = -1; + IsPlayView = 0; + printf("\nCheckers: New game.\n"); + EraseHistory(); +} + +int TChBoard::GetTextLineY() const +{ + int y = height - (max_delt + textlineh + delta_size.y); + int i, j; + for (i = 0; i <= 1; i++) for (j = 0; j <= 1; j++) + { + TRealPoint corner; + corner.x = (2*i - 1) * dw_delt + i * NW_CELL * dw_cell; + corner.y = (2*j - 1) * dw_delt + j * NW_CELL * dw_cell; + TIntPoint wcr = PlToWin(corner); + if (wcr.x != INT_MIN && wcr.y != INT_MIN) + { + if (y < wcr.y) y = wcr.y; + } + } + y -= textlineh; + if (y > height - delta_size.y - 2*textlineh) + { + y = height - delta_size.y - 2*textlineh; + } + return (y + height - delta_size.y) / 2; +} + +#ifdef BUILD_RUS +#define aCheckersGame " 誨." +#define aRedMoves " 室." +#define aBlueMoves " 室." +#define aWait "." +#define aRedWins " 먣ࠫ." +#define aBlueWins " 먣ࠫ." +#define aDraw "." +#define aRed " " +#define aBlue " " +#define aMadeWrongMove "ᤥ ࠢ 室." +#define aNoMove " ᬮ ᤥ 室." +#define aEndGame " ." +#define aYouWin " ( 먣ࠫ)" +#define aYouLose " ( நࠫ)" +#define aRedWin " ( 먣ࠫ)" +#define aBlueWin " ( 먣ࠫ)" +#define aWrongMove " 室." +#define aNotYourChecker " 誠." +#define aFreeCell " ⪠ ." +#define aNotFreeCell "誨 室 ⮫쪮 ᢮ ⪨." +#define aMustEat " ." +#define aMustEatMore " ." +#define aCheckerNoMove " ⮩ 誨 室." +#define aNoBack "誨 室 ." +#define aNotDamka " ." +#define aOnlyDiag "誨 室 ⮫쪮 ." +#define aEatYour "誨 ᢮." +#define aMoreOne " 誨 ࠧ." +#define aNoTurnBack "誨 ࠧ稢 ⨨." +#else +#define aCheckersGame "The checkers game." +#define aRedMoves "Red moves." +#define aBlueMoves "Blue moves." +#define aWait "Please wait." +#define aRedWins "Red wins." +#define aBlueWins "Blue wins." +#define aDraw "Draw." +#define aRed "Red " +#define aBlue "Blue " +#define aMadeWrongMove "make a wrong move." +#define aNoMove "could not make a move." +#define aEndGame "End of the game." +#define aYouWin " (You win)" +#define aYouLose " (You lose)" +#define aRedWin " (Red win)" +#define aBlueWin " (Blue win)" +#define aWrongMove "Wrong move." +#define aNotYourChecker "It isn't your checker." +#define aFreeCell "The cell is free." +#define aNotFreeCell "Checkers may be moved only on a free cell." +#define aMustEat "You must eat a checker." +#define aMustEatMore "You must eat more checkers." +#define aCheckerNoMove "The checker have no moves." +#define aNoBack "Checkers may not be moved back." +#define aNotDamka "It is not a damka." +#define aOnlyDiag "Checkers may be moved only along diagonal." +#define aEatYour "You may not eat your checkers." +#define aMoreOne "You may not eat more than one checker at a time." +#define aNoTurnBack "Checkers may not turn back when eating." +#endif + +void TChBoard::GetTextLine(char str[]) const +{ + str[0] = 0; + int g = (game_end - 1) % 2, h = 0; + switch(text_line_type) + { + case TLT_Main: + strcpy(str, aCheckersGame); + break; + case TLT_Move: + if (MainPos.wmove == 0) + { + strcpy(str, aRedMoves); + } + else strcpy(str, aBlueMoves); + break; + case TLT_Wait: + strcpy(str, aWait); + break; + case TLT_GameEnd: + case TLT_PlDidntMove: + case TLT_PlWrongMove: + if (!game_end) break; + if (text_line_type == TLT_GameEnd) + { + if (game_end == 1) strcpy(str, aRedWins); + else if (game_end == 2) strcpy(str, aBlueWins); + else if (game_end == 5) strcpy(str, aDraw); + } + if (!str[0]) + { + if (game_end >= 1 && game_end <= 4) + { + if (g == 0) strcpy(str, aRed); + else strcpy(str, aBlue); + if (text_line_type == TLT_PlWrongMove) + { + strcat(str, aMadeWrongMove); + } + else strcat(str, aNoMove); + h = 1; + } + else strcpy(str, aEndGame); + } + if (game_end >= 1 && game_end <= 4) + { + if (!IsPlayView && player[1-g] && !player[g]) + { + strcat(str, aYouWin); + } + else if (!IsPlayView && player[g] && !player[1-g]) + { + strcat(str, aYouLose); + } + else if (h && g == 0) strcat(str, aRedWin); + else if (h && g == 1) strcat(str, aBlueWin); + } + break; + case TLT_WrongMove: + strcpy(str, aWrongMove); + break; + case TLT_WrongColor: + strcpy(str, aNotYourChecker); + break; + case TLT_WfCell: + strcpy(str, aFreeCell); + break; + case TLT_WnfCell: + strcpy(str, aNotFreeCell); + break; + case TLT_WMustEat: + strcpy(str, aMustEat); + break; + case TLT_WMustEatMore: + case TLT_WMustEatMoreD: + strcpy(str, aMustEatMore); + break; + case TLT_WNoMove: + strcpy(str, aCheckerNoMove); + break; + case TLT_WChBack: + strcpy(str, aNoBack); + break; + case TLT_WNotDm: + case TLT_WNotDmE: + strcpy(str, aNotDamka); + break; + case TLT_WOnlyDiag: + strcpy(str, aOnlyDiag); + break; + case TLT_WEatYour: + strcpy(str, aEatYour); + break; + case TLT_WMoreOne: + strcpy(str, aMoreOne); + break; + case TLT_WTurnBack: + strcpy(str, aNoTurnBack); + break; + } +} + +void TChBoard::DrawTextLine(TGraphDraw *drw) const +{ + if (!drw || !drw->IsDraw()) return; + char str[100]; + GetTextLine(str); + if (str[0]) drw->DrawText(10, GetTextLineY(), str); +} + +void TChBoard::ResetTextLine(TGraphDraw *drw) +{ + if (!game_end && text_line_type != TLT_Move) ChangeTLT(drw, TLT_Move); +} + +void TChBoard::LineB(TGraphDraw *drw, double x1, double y1, double x2, double y2) const +{ + if (!drw || !drw->IsDraw()) return; + TIntPoint p1 = PlToWin(x1, y1), p2 = PlToWin(x2, y2); + if (p1.x != INT_MIN && p1.y != INT_MIN && p2.x != INT_MIN && p2.y != INT_MIN) + { + drw->DrawLine(p1.x, p1.y, p2.x, p2.y); + } +} + +void TChBoard::DrawCh(TGraphDraw *drw, double x0, double y0, const TRealPoint pnt[], int npnt, int L) const +{ + if (!drw || !drw->IsDraw()) return; + int i, j; + for (j = 0; j < L; j++) + { + for (i = 0; i < npnt - 1; i++) + { + LineB(drw, x0 + pnt[i].x * dw_cell * r_ch_lines[j] / 2, + y0 + pnt[i].y * dw_cell * r_ch_lines[j] / 2, + x0 + pnt[i+1].x * dw_cell * r_ch_lines[j] / 2, + y0 + pnt[i+1].y * dw_cell * r_ch_lines[j] / 2); + } + } +} + +void TChBoard::DrawIL(TGraphDraw *drw, double x0, double y0, int L) const +{ + if (!drw || !drw->IsDraw()) return; + int i, j; + if (L == 0 || L == 1) + { + const int numDST[2] = {2, 4}; + const double DST[2][4] = {{0.96, 0.88}, {0.8, 0.76, 0.72, 0.68}}; + const int MULT[4][4] = {{-1, -1, -1, 1}, {-1, 1, 1, 1}, + {-1, -1, 1, -1}, {1, -1, 1, 1}}; + for (i = 0; i < numDST[L]; i++) for (j = 0; j < 4; j++) + { + LineB(drw, x0 + dw_cell * DST[L][i] * MULT[j][0] / 2, + y0 + dw_cell * DST[L][i] * MULT[j][1] / 2, + x0 + dw_cell * DST[L][i] * MULT[j][2] / 2, + y0 + dw_cell * DST[L][i] * MULT[j][3] / 2); + } + } + else if (L == 2) + { + const double DP[] = {0.85, 0.90, 0.95}; + const int numDP = NELEM(DP); + for (i = 0; i < numDP; i++) for (j = -1; j <= 1; j += 2) + { + LineB(drw, x0 - j * dw_cell * DP[i] / 2, + y0 - dw_cell * DP[numDP - i - 1] / 2, + x0 + j * dw_cell * DP[numDP - i - 1] / 2, + y0 + dw_cell * DP[i] / 2); + } + } +} + +void TChBoard::Draw(TGraphDraw *drw) +{ + if (!drw || !drw->IsDraw()) return; + if (CheckResize(drw)) drw->DrawClear(); + int i, j, k, kn; + unsigned long black = drw->GetBlackColor(); + unsigned long red = drw->CreateColor(65535u, 0, 0); + unsigned long green = drw->CreateColor(0, 49151u, 0); + unsigned long blue = drw->CreateColor(0, 0, 65535u); + drw->SetColor(black); + for (i = -1; i <= NW_CELL + 1; i++) for (j = -1; j <= NW_CELL; j++) + { + if (i < 0 || i > NW_CELL || j >= 0 && j < NW_CELL) + { + double mval = dw_cell * NW_CELL + dw_delt; + double x, y0, y1; + if (i < 0) x = -dw_delt; + else if (i > NW_CELL) x = mval; + else x = i * dw_cell; + if (j < 0) y0 = -dw_delt; + else if (j > NW_CELL) y0 = mval; + else y0 = j * dw_cell; + if ((j+1) < 0) y1 = -dw_delt; + else if ((j+1) > NW_CELL) y1 = mval; + else y1 = (j+1) * dw_cell; + LineB(drw, x, y0, x, y1); + } + } + for (i = -1; i <= NW_CELL; i++) for (j = -1; j <= NW_CELL + 1; j++) + { + if (j < 0 || j > NW_CELL || i >= 0 && i < NW_CELL) + { + double mval = dw_cell * NW_CELL + dw_delt; + double x0, x1, y; + if (i < 0) x0 = -dw_delt; + else if (i > NW_CELL) x0 = mval; + else x0 = i * dw_cell; + if ((i+1) < 0) x1 = -dw_delt; + else if ((i+1) > NW_CELL) x1 = mval; + else x1 = (i+1) * dw_cell; + if (j < 0) y = -dw_delt; + else if (j > NW_CELL) y = mval; + else y = j * dw_cell; + LineB(drw, x0, y, x1, y); + } + } + for (i = -1; i <= 1; i += 2) + { + drw->SetColor((i < 0) ? red : blue); + for (j = -1; j <= 1; j += 2) + { + double c = dw_cell * NW_CELL / 2; + double d = (dw_cell/2 > dw_delt) ? dw_delt : dw_cell/2; + LineB(drw, c + j * (c + 0.5*d), c + i * (c - 0.5*d), + c + j * (c + 0.5*d), c + i * (c - 3.5*d)); + LineB(drw, c + j * (c + 0.5*d), c + i * (c - 3.5*d), + c + j * (c + 0.2*d), c + i * (c - 2.5*d)); + LineB(drw, c + j * (c + 0.5*d), c + i * (c - 3.5*d), + c + j * (c + 0.8*d), c + i * (c - 2.5*d)); + LineB(drw, c + j * (c + 0.2*d), c + i * (c - 2.5*d), + c + j * (c + 0.8*d), c + i * (c - 2.5*d)); + } + } + for (i = 0; i < NW_CELL; i++) for (j = 0; j < NW_CELL; j++) + { + if (!PoleCpos(i, j)) + { + drw->SetColor(black); + LineB(drw, (i+0.33) * dw_cell, j * dw_cell, (i+0.33) * dw_cell, (j+1) * dw_cell); + LineB(drw, (i+0.67) * dw_cell, j * dw_cell, (i+0.67) * dw_cell, (j+1) * dw_cell); + LineB(drw, i * dw_cell, (j+0.33) * dw_cell, (i+1) * dw_cell, (j+0.33) * dw_cell); + LineB(drw, i * dw_cell, (j+0.67) * dw_cell, (i+1) * dw_cell, (j+0.67) * dw_cell); + LineB(drw, i * dw_cell, j * dw_cell, (i+1) * dw_cell, (j+1) * dw_cell); + LineB(drw, (i+1) * dw_cell, j * dw_cell, i * dw_cell, (j+1) * dw_cell); + } + else + { + k = PoleToNum(i, j); + kn = MainPos.SH[k]; + if (TheMove[0] > 0 && k == TheMove[1]) + { + if (kn == 1 || kn == 2) kn = 5; + else if (kn == 3 || kn == 4) kn = 6; + } + if (TheMove[0] > 0 && k == TheMove[TheMove[0]]) + { + kn = MainPos.SH[TheMove[1]]; + if (kn <= 2 && BecameD) kn += 2; + } + if (kn == 1) + { + drw->SetColor(red); + DrawCh(drw, (i+0.5)*dw_cell, (j+0.5)*dw_cell, + r_circle_pnt, NELEM(r_circle_pnt)); + } + else if (kn == 2) + { + drw->SetColor(blue); + DrawCh(drw, (i+0.5)*dw_cell, (j+0.5)*dw_cell, + r_circle_pnt, NELEM(r_circle_pnt)); + } + else if (kn == 3) + { + drw->SetColor(red); + DrawCh(drw, (i+0.5)*dw_cell, (j+0.5)*dw_cell, + r_star_pnt, NELEM(r_star_pnt)); + } + else if (kn == 4) + { + drw->SetColor(blue); + DrawCh(drw, (i+0.5)*dw_cell, (j+0.5)*dw_cell, + r_star_pnt, NELEM(r_star_pnt)); + } + else if (kn == 5) + { + drw->SetColor(green); + DrawCh(drw, (i+0.5)*dw_cell, (j+0.5)*dw_cell, + r_circle_pnt, NELEM(r_circle_pnt), 2); + } + else if (kn == 6) + { + drw->SetColor(green); + DrawCh(drw, (i+0.5)*dw_cell, (j+0.5)*dw_cell, + r_circle_pnt, NELEM(r_circle_pnt), 2); + } + } + } + for (k = 1; k <= Eaten[0]; k++) + { + if (TheMove[0] <= 0 || Eaten[k] != TheMove[TheMove[0]]) + { + NumToPole(Eaten[k], i, j); + kn = MainPos.SH[Eaten[k]]; + if (kn) + { + if (kn == 1 || kn == 3) drw->SetColor(blue); + else if (kn == 2 || kn == 4) drw->SetColor(red); + DrawIL(drw, (i+0.5)*dw_cell, (j+0.5)*dw_cell, 2); + } + } + } + if (TheMove[0] > 0) + { + NumToPole(TheMove[TheMove[0]], i, j); + drw->SetColor(green); + DrawIL(drw, (i+0.5)*dw_cell, (j+0.5)*dw_cell, 1); + } + if (CurPoint.x >= 0 && CurPoint.y >= 0) + { + drw->SetColor(green); + DrawIL(drw, (CurPoint.x+0.5)*dw_cell, (CurPoint.y+0.5)*dw_cell, 0); + } + drw->SetColor(black); + DrawTextLine(drw); + if (some_draw) some_draw->DrawB(drw, *this); + drw->FreeColor(red); + drw->FreeColor(green); + drw->FreeColor(blue); +} + +int TChBoard::ResizeDraw(TGraphDraw *drw, int w, int h) +{ + int w0 = width, h0 = height; + Resize(w, h); + if (drw && drw->IsDraw() && (width != w0 || height != h0)) + { + drw->DrawClear(); + Draw(drw); + return 1; + } + else return 0; +} + +int TChBoard::CheckResize(TGraphDraw *drw) +{ + if (!drw || !check_resize) return 0; + int w, h; + drw->GetSize(w, h); + if (w < 0 || h < 0) return 0; + int w0 = width, h0 = height; + Resize(w, h); + return width != w0 || height != h0; +} + +void TChBoard::CurPointClear(TGraphDraw *drw) const +{ + if (!drw || !drw->IsDraw()) return; + drw->SetColor(drw->GetWhiteColor()); + DrawIL(drw, (CurPoint.x+0.5)*dw_cell, (CurPoint.y+0.5)*dw_cell, 0); +} + +int TChBoard::MouseClick(TGraphDraw *drw, int x, int y) +{ + TRealPoint rpnt = WinToPl(x, y); + if (rpnt.x < -dw_delt || rpnt.y < -dw_delt || + rpnt.x > NW_CELL*dw_cell + dw_delt || + rpnt.y > NW_CELL*dw_cell + dw_delt) return -1; + if (CurPoint.x >= 0 && CurPoint.y >= 0) + { + CurPointClear(drw); + CurPoint.x = -1; CurPoint.y = -1; + Draw(drw); + } + ResetTextLine(drw); + if (AutoMove(drw)) return 3; + if (!CanPlayerMove()) return 0; + int i = (int)floor(rpnt.x / dw_cell), j = (int)floor(rpnt.y / dw_cell); + if (i < 0 || j < 0 || i >= NW_CELL || j >= NW_CELL) return 0; + if (!PoleCpos(i, j)) return 1; + return 2 + CMove(drw, i, j); +} + +TChBoard::PKey TChBoard::GetKeySide(PKey key) +{ + if (key != PLeft && key != PRight && key != PUp && key != PDown) return key; + TIntPoint a0 = PlToWin(4*dw_cell, 0); + TIntPoint a1 = PlToWin(4*dw_cell, 8*dw_cell); + TIntPoint b0 = PlToWin(0, 4*dw_cell); + TIntPoint b1 = PlToWin(8*dw_cell, 4*dw_cell); + double ax = a0.x - a1.x, ay = a0.y - a1.y; + double bx = b0.x - b1.x, by = b0.y - b1.y; + double t; + if (a0.x == INT_MIN || a0.y == INT_MIN || a1.x == INT_MIN || + a1.y == INT_MIN || fabs(ax) < 0.5 && fabs(ay) < 0.5) + { + ax = 0, ay = 1; + } + if (b0.x == INT_MIN || b0.y == INT_MIN || b1.x == INT_MIN || + b1.y == INT_MIN || fabs(bx) < 0.5 && fabs(by) < 0.5) + { + bx = 1, by = 0; + } + t = fabs(ax) + fabs(ay); ax /= t; ay /= t; + t = fabs(bx) + fabs(by); bx /= t; by /= t; + if (fabs(ax) <= fabs(bx)) + { + if (key == PLeft) return (bx > 0) ? PRight : PLeft; + if (key == PRight) return (bx > 0) ? PLeft : PRight; + if (key == PUp) return (ay > 0) ? PDown : PUp; + if (key == PDown) return (ay > 0) ? PUp : PDown; + } + else + { + if (key == PLeft) return (ax > 0) ? PDown : PUp; + if (key == PRight) return (ax > 0) ? PUp : PDown; + if (key == PUp) return (by > 0) ? PRight : PLeft; + if (key == PDown) return (by > 0) ? PLeft : PRight; + } + return PNull; +} + +int TChBoard::PKeyEvent(TGraphDraw *drw, PKey key) +{ + ResetTextLine(drw); + if (AutoMove(drw)) return 3; + if (!CanPlayerMove()) return 0; + key = GetKeySide(key); + if (CurPoint.x < 0 || CurPoint.y < 0 || + CurPoint.x >= NW_CELL || CurPoint.y >= NW_CELL) + { + CurPoint.x = NW_CELL / 2; + CurPoint.y = NW_CELL / 2; + Draw(drw); + return 1; + } + if (key == PEnter) return 2 + CMove(drw, CurPoint.x, CurPoint.y); + if (drw && drw->IsDraw() && CheckResize(drw)) + { + drw->DrawClear(); + Draw(drw); + } + if (key == PLeft) + { + if (CurPoint.x == 0) return 0; + CurPointClear(drw); + CurPoint.x--; + Draw(drw); + return 1; + } + else if (key == PRight) + { + if (CurPoint.x == NW_CELL - 1) return 0; + CurPointClear(drw); + CurPoint.x++; + Draw(drw); + return 1; + } + else if (key == PUp) + { + if (CurPoint.y == 0) return 0; + CurPointClear(drw); + CurPoint.y--; + Draw(drw); + return 1; + } + else if (key == PDown) + { + if (CurPoint.y == NW_CELL - 1) return 0; + CurPointClear(drw); + CurPoint.y++; + Draw(drw); + return 1; + } + else return 0; +} + +void TChBoard::UnMove(TGraphDraw *drw) +{ + MoveErase(); + if (drw && drw->IsDraw()) + { + drw->DrawClear(); + Draw(drw); + } +} + +TChBoard::TextLineType TChBoard::GetTLTfromA(int s) const +{ + if (s >= 0) return TLT_Main; + switch(s) + { + case Position::AWColor: return TLT_WrongColor; + case Position::AfCell: return TLT_WfCell; + case Position::AnfCell: return TLT_WnfCell; + case Position::AMustEat: return TLT_WMustEat; + case Position::AMustEatMore: return TLT_WMustEatMore; + case Position::AMustEatMoreD: return TLT_WMustEatMoreD; + case Position::ANoMove: return TLT_WNoMove; + case Position::AChBack: return TLT_WChBack; + case Position::ANotDm: return TLT_WNotDm; + case Position::ANotDmE: return TLT_WNotDmE; + case Position::AOnlyDiag: return TLT_WOnlyDiag; + case Position::AEatYour: return TLT_WEatYour; + case Position::AMoreOne: return TLT_WMoreOne; + case Position::ATurnBack: return TLT_WTurnBack; + default: return TLT_WrongMove; + } +} + +void TChBoard::ChangeTLT(TGraphDraw *drw, TextLineType t) +{ + if (text_line_type == t) return; + if (drw && drw->IsDraw()) + { + drw->SetColor(drw->GetWhiteColor()); + DrawTextLine(drw); + } + text_line_type = t; + if (drw && drw->IsDraw()) + { + drw->SetColor(drw->GetBlackColor()); + DrawTextLine(drw); + } +} + +TChBoard::TextLineType TChBoard::GetSimpleTLT() const +{ + if (game_end && CurMoveN >= MainPlay.GetN() - 1) return TLT_GameEnd; + else return TLT_Move; +} + +inline int TChBoard::ReinitHistory() +{ + if (history.Play(MainPlay)) {hist_inited = 1; return 1;} + else {hist_inited = 0; return 0;} +} + +void TChBoard::PrintLMove() +{ + PlayWrite::PMv pmv; + if (MainPlay.GetMoveL(pmv.mv) >= 0) + { + MainPlay.GetPosL(pmv.pos, 1); + char *s = new char[pmv.pos.GetLenMvEx(pmv.mv, 11)]; + if (s) + { + pmv.pos.WriteMvEx(pmv.mv, s, 11); + printf("Checkers: %s%s\n", (pmv.pos.wmove == 1) ? "..." : "", s); + delete[] s; + } + if (!hist_inited) ReinitHistory(); + else history.Move(pmv.pos, pmv.mv, MainPlay.GetN() - 1); + } +} + +int TChBoard::CMove(TGraphDraw *drw, int x, int y) +{ + if (AutoMove(drw)) return 1; + if (!CanPlayerMove()) return 0; + if (!game_end && text_line_type != TLT_Move) ChangeTLT(drw, TLT_Move); + int k = PoleToNum(x, y), s; + if (TheMove[0] > 0) + { + if (!PoleCpos(x, y) || k == TheMove[TheMove[0]]) {UnMove(drw); return 1;} + int e = 1; + s = MainPos.AMove(TheMove, k, e); + if (s < 0) + { + ChangeTLT(drw, GetTLTfromA(s)); + return 0; + } + if (s < NUM_CELL) Eaten[++Eaten[0]] = (unsigned char)s; + TheMove[++TheMove[0]] = (unsigned char)k; + BecameD = BecameD || MainPos.BecameD(k, MainPos.SH[TheMove[1]]); + if (e == 0) + { + if (MainPlay.Add(TheMove) != 0) + { + ChangeTLT(drw, TLT_WrongMove); + return 0; + } + CurMoveN = MainPlay.GetN() - 1; + MoveErase(); + RenewMPos(); + PrintLMove(); + if (AutoMove(drw)) return 1; + } + if (drw && drw->IsDraw()) + { + drw->DrawClear(); + Draw(drw); + } + return 1; + } + else + { + if (!PoleCpos(x, y)) return 0; + s = MainPos.AChCell(k); + if (s != 1) + { + ChangeTLT(drw, GetTLTfromA(s)); + return 0; + } + TheMove[0] = 1; + TheMove[1] = (unsigned char)k; + Draw(drw); + return 1; + } +} + +void TChBoard::SetNoMove(TGraphDraw *drw, int force) +{ + if (!force && CurPoint.x < 0 && CurPoint.y < 0 && TheMove[0] == 0 && Eaten[0] == 0) + { + return; + } + CurPoint.x = -1; CurPoint.y = -1; + MoveErase(); + if (drw && drw->IsDraw()) + { + drw->DrawClear(); + Draw(drw); + } +} + +int TChBoard::AutoMove(TGraphDraw *drw, int nmove, int draw_check) +{ + if (game_end || IsPlayView) {SetNoMove(drw, 0); return 0;} + if (CurMoveN < MainPlay.GetN() - 1) + { + CurMoveN = MainPlay.GetN() - 1; + RenewMPos(); + SetNoMove(drw); + return 2; + } + if (!MainPos.AllCanEat() && !MainPos.AllCanMove()) + { + game_end = 2 - MainPos.wmove; + ChangeTLT(drw, TLT_GameEnd); + if (!player[game_end - 1]) printf("Checkers: You win.\n"); + else printf("Checkers: You lose.\n"); + SetNoMove(drw); + return 3; + } + else if (draw_check > 0 && MainPlay.IsDraw()) + { + game_end = 5; + ChangeTLT(drw, TLT_GameEnd); + printf("Checkers: Draw.\n"); + SetNoMove(drw); + return 3; + } + if (!player[MainPos.wmove]) return 0; + TIntPoint CurP0 = CurPoint; + if (CurPoint.x >= 0 && CurPoint.y >= 0) + { + if (drw) CurPointClear(drw); + CurPoint.x = -1; CurPoint.y = -1; + } + MoveErase(); + int k; + for (k = 0; player[MainPos.wmove] && (k < nmove || nmove == 0); k++) + { + TChPlayer::PMv pmv; + pmv.pos = MainPos; + Position::SetNullMv(pmv.mv); + MainPlay.GetMoveL(pmv.mv); + text_line_type = TLT_Move; + if (!player[MainPos.wmove]->Move(pmv)) + { + text_line_type = TLT_PlDidntMove; + game_end = 4 - MainPos.wmove; + break; + } + if (MainPlay.Add(pmv.mv) != 0) + { + text_line_type = TLT_PlWrongMove; + game_end = 4 - MainPos.wmove; + break; + } + CurMoveN = MainPlay.GetN() - 1; + MoveErase(); + RenewMPos(); + PrintLMove(); + if (!MainPos.AllCanEat() && !MainPos.AllCanMove()) + { + game_end = 2 - MainPos.wmove; + text_line_type = TLT_GameEnd; + if (!player[game_end - 1]) printf("Checkers: You win.\n"); + else printf("Checkers: You lose.\n"); + break; + } + else if (draw_check >= 0 && MainPlay.IsDraw()) + { + game_end = 5; + text_line_type = TLT_GameEnd; + printf("Checkers: Draw.\n"); + break; + } + } + if (!game_end) + { + text_line_type = TLT_Move; + CurPoint = CurP0; + } + if (drw && drw->IsDraw()) + { + drw->DrawClear(); + Draw(drw); + } + return 1; +} + +void TChBoard::DrawTimer(TGraphDraw *drw, double t, int wh) const +{ + if (!drw || !drw->IsDraw()) return; + if (wh) drw->SetColor(drw->GetWhiteColor()); + else drw->SetColor(drw->GetBlackColor()); + double r1 = dw_delt * 0.4, r2 = dw_delt * 0.45; + double x = t * dw_cell * NW_CELL, y = -dw_delt / 2; + if (MainPos.wmove == 1) + { + x = dw_cell * NW_CELL - x; + y = dw_cell * NW_CELL - y; + } + LineB(drw, x - r1, y - r2, x + r2, y + r1); + LineB(drw, x - r2, y - r1, x + r1, y + r2); + LineB(drw, x - r1, y + r2, x + r2, y - r1); + LineB(drw, x - r2, y + r1, x + r1, y - r2); + if (wh) + { + int i, j, jj; + drw->SetColor(drw->GetBlackColor()); + for (i = -1; i <= NW_CELL; i++) + { + double mval = dw_cell * NW_CELL + dw_delt; + double x0, x1, y; + if (i < 0) x0 = -dw_delt; + else if (i > NW_CELL) x0 = mval; + else x0 = i * dw_cell; + if ((i+1) < 0) x1 = -dw_delt; + else if ((i+1) > NW_CELL) x1 = mval; + else x1 = (i+1) * dw_cell; + if (fabs(x0 - x) < dw_delt || fabs(x1 - x) < dw_delt) + { + for (jj = 0; jj <= 1; jj++) + { + if (MainPos.wmove == 1) j = NW_CELL + jj; + else j = -jj; + if (j < 0 || j > NW_CELL || i >= 0 && i < NW_CELL) + { + if (j < 0) y = -dw_delt; + else if (j > NW_CELL) y = mval; + else y = j * dw_cell; + LineB(drw, x0, y, x1, y); + } + } + } + } + } +} + +int TChBoard::SetCurMoveN(int n, TGraphDraw *drw) +{ + int nmove = MainPlay.GetN() - 1; + if (n > nmove) n = nmove; + if (n < 0) n = 0; + if (CurMoveN != n) + { + CurMoveN = n; + RenewMPos(); + if (n < nmove) + { + MoveErase(); + CurPoint.x = -1; CurPoint.y = -1; + } + text_line_type = GetSimpleTLT(); + if (drw && drw->IsDraw()) + { + drw->DrawClear(); + Draw(drw); + } + return 1; + } + else return 0; +} + +int TChBoard::SetPlay(const PlayWrite &play) +{ + if (play.GetN() <= 0) return 0; + MainPlay = play; + MoveErase(); + CurPoint.x = -1; CurPoint.y = -1; + CurMoveN = INT_MIN; + SetCurMoveN(play.GetN()); + if (!MainPos.AllCanEat() && !MainPos.AllCanMove()) game_end = 2 - MainPos.wmove; + else if (MainPlay.IsDraw()) game_end = 5; + else game_end = 0; + text_line_type = GetSimpleTLT(); + IsPlayView = 1; + EraseHistory(); + return 1; +} + +void TChBoard::GoToCurMove() +{ + if (!MainPos.AllCanEat() && !MainPos.AllCanMove() || + MainPlay.IsDraw(CurMoveN + 1)) return; + MainPlay.ClearFrom(CurMoveN + 1); + MoveErase(); + game_end = 0; + text_line_type = GetSimpleTLT(); + IsPlayView = 0; +} + +#endif //_HEADER_BOARD_H diff --git a/programs/games/checkers/trunk/buttons.h b/programs/games/checkers/trunk/buttons.h new file mode 100644 index 0000000000..ac0dbba432 --- /dev/null +++ b/programs/games/checkers/trunk/buttons.h @@ -0,0 +1,355 @@ +#ifndef _HEADER_BUTTONS_H +#define _HEADER_BUTTONS_H + +#ifndef __MENUET__ +#include +#include +#include +#endif +#include "gr-draw.h" + +struct TXButton +{ + TXButton(int n = -1, int w = 100, int h = 20) : num(n), w(w), h(h), drw(1) {} + TXButton(const TXButton &b) : w(b.w), h(b.h) {} + + TXButton &operator=(const TXButton &b) {w = b.w; h = b.h; num = b.num; return *this;} + + virtual void Draw(TGraphDraw *drw, int x0, int y0, + unsigned long dcolor, unsigned long lcolor, unsigned long tcolor, int ins = 0); + virtual int ButtonPnt(int xp, int yp, int &n, int kind = 0); + + int num, w, h, drw; +}; + +void TXButton::Draw(TGraphDraw *drw, int x0, int y0, + unsigned long dcolor, unsigned long /*lcolor*/, + unsigned long /*tcolor*/, int /*ins*/) +{ + if (!drw || !drw->IsDraw()) return; + drw->SetColor(dcolor); + drw->DrawLine(x0, y0, x0 + w, y0); + drw->DrawLine(x0, y0, x0, y0 + h); + drw->DrawLine(x0 + w, y0, x0 + w, y0 + h); + drw->DrawLine(x0, y0 + h, x0 + w, y0 + h); +} + +int TXButton::ButtonPnt(int xp, int yp, int &n, int /*kind*/) +{ + n = num; + return (xp >= 0 && yp >= 0 && xp <= w && yp <= h) ? 1 : INT_MIN; +} + + +struct TextButton : public TXButton +{ + enum {thick_def = 3}; + + TextButton(int n = -1, int w = 100, int h = 20, char *text = 0, int thick = thick_def) + : TXButton(n, w, h), text(text), thick(thick) {CheckDefW();} + TextButton(const TXButton &b, char *text = 0, int thick = thick_def) + : TXButton(b), text(text), thick(thick) {CheckDefW();} + TextButton(const TextButton &b) : TXButton(b), text(b.text), thick(b.thick) {} + + TextButton &operator=(const TextButton &b); + + virtual void Draw(TGraphDraw *drw, int x0, int y0, + unsigned long dcolor, unsigned long lcolor, unsigned long tcolor, int ins = 0); + void CheckDefW(); + + int thick; + char *text; +}; + +inline TextButton &TextButton::operator=(const TextButton &b) +{ + text = b.text; + TXButton::operator=(b); + return *this; +} + +void TextButton::Draw(TGraphDraw *drw, int x0, int y0, + unsigned long dcolor, unsigned long lcolor, unsigned long tcolor, int ins) +{ + if (!drw || !drw->IsDraw()) return; + int i; + if (thick <= -1 && thick >= -5) + { + drw->SetColor(dcolor); + for (i = 0; i < -thick; i++) + { + drw->DrawLine(x0 + i, y0 + i, x0 + w - i, y0 + i); + drw->DrawLine(x0 + i, y0 + i, x0 + i, y0 + h - i); + drw->DrawLine(x0 + w - i, y0 + i, x0 + w - i, y0 + h - i); + drw->DrawLine(x0 + i, y0 + h - i, x0 + w - i, y0 + h - i); + } + } + else if (thick > 0) + { + for (i = 0; i < thick; i++) + { + drw->SetColor(ins ? dcolor : lcolor); + drw->DrawLine(x0 + i, y0 + i, x0 + w - i, y0 + i); + drw->DrawLine(x0 + i, y0 + i, x0 + i, y0 + h - i); + drw->SetColor(ins ? lcolor : dcolor); + drw->DrawLine(x0 + w - i, y0 + i, x0 + w - i, y0 + h - i); + drw->DrawLine(x0 + i, y0 + h - i, x0 + w - i, y0 + h - i); + } + } + else TXButton::Draw(drw, x0, y0, dcolor, lcolor, tcolor, ins); + if (text) + { + drw->SetColor(tcolor); + drw->DrawText(x0 + 7, y0 + (h - drw->GetTextH(text)) / 2, text); + } +} + +inline void TextButton::CheckDefW() +{ + if (w < 0 && text) w = 15 + strlen(text) * 8; +} + +class TXButtonArray +{ +public: + TXButtonArray(int d = 10) : button(0), nbutton(0), mbutton(0), + delt(d), ins(-1), k_ins(0) {} + ~TXButtonArray() {Clear();} + + void Clear(); + void Add(TXButton *bt); + void Add(int n = -1, int w = 100, int h = 20, char *str = 0, + int thick = TextButton::thick_def); + TXButton *operator[](int i) {return button[i];} + int GetNButton() const {return nbutton;} + int GetInsert() const {return ins;} + TXButton *GetButton(int n); + + int GetDelt() const {return delt;} + void SetDelt(int d) {delt = d;} + + int GetParam(int w, int p) const; + int GetNumStr(int w) const {return GetParam(w, 0);} + int GetHeight(int w) const {return GetParam(w, 1);} + int GetFWidth() const; + + void Draw(TGraphDraw *drw, int x0, int y0, int w); + void Draw(TGraphDraw *drw, int x0, int y0, int w, + unsigned long dcolor, unsigned long lcolor, unsigned long tcolor, int insd = 1); + int ButtonPnt(int xp, int yp, int w, int &n, int kind = 0); +protected: + void Extend(int n = -1); + + TXButton **button; + int nbutton, mbutton; + int delt; + int ins, k_ins; +}; + +void TXButtonArray::Clear() +{ + int i; + if (button) + { + for (i = 0; i < nbutton; i++) if (button[i]) delete button[i]; + delete[] button; + } + button = 0; nbutton = 0; mbutton = 0; +} + +void TXButtonArray::Extend(int n) +{ + if (n < 0) n = nbutton + 1; + if (mbutton < n) + { + typedef TXButton *TXButtonPnt; + TXButton **b_old = button; + int m_old = mbutton; + mbutton = n * 2; + button = new TXButtonPnt[mbutton]; + for (int i = 0; i < mbutton; i++) button[i] = 0; + if (b_old) + { + for (int i = 0; i < m_old; i++) button[i] = b_old[i]; + delete[] b_old; + } + } +} + +void TXButtonArray::Add(TXButton *bt) +{ + Extend(); + if (button[nbutton]) delete[] button[nbutton]; + button[nbutton] = bt; + nbutton++; +} + +void TXButtonArray::Add(int n, int w, int h, char *str, int thick) +{ + if (thick < 0 && !str) Add(new TXButton(n, w, h)); + else Add(new TextButton(n, w, h, str, thick)); +} + +TXButton *TXButtonArray::GetButton(int n) +{ + int i; + for (i = 0; i < nbutton; i++) + { + if (button[i] && button[i]->num == n) return button[i]; + } + return 0; +} + +int TXButtonArray::GetFWidth() const +{ + int i, x = 0; + for (i = 0; i < nbutton; i++) + { + if (button[i] && button[i]->drw > 0) x += button[i]->w + delt; + } + if (x != 0) x -= delt; + return x; +} + +int TXButtonArray::GetParam(int w, int p) const +{ + int i, k = 0; + int x = 0, y = 0, ym = 0; + for (i = 0; i < nbutton; i++) if (button[i] && button[i]->drw > 0) + { + int xx = x + button[i]->w + delt; + if (x != 0 && xx > w + delt) + { + k++; y += ym + delt; ym = 0; + x = 0; xx = x + button[i]->w + delt; + } + x = xx; + if (ym < button[i]->h) ym = button[i]->h; + } + if (x != 0) {k++; y += ym;} + else if (y != 0) y -= delt; + if (p == 0) return k; + else if (p == 1) return y; + else return -1; +} + +void TXButtonArray::Draw(TGraphDraw *drw, int x0, int y0, int w) +{ + const unsigned short power_gray = 49152U; + unsigned long black = drw->GetBlackColor(); + unsigned long grey = drw->CreateColor(power_gray, power_gray, power_gray); + Draw(drw, x0, y0, w, black, grey, black, 1); + drw->FreeColor(grey); +} + +void TXButtonArray::Draw(TGraphDraw *drw, int x0, int y0, int w, + unsigned long dcolor, unsigned long lcolor, unsigned long tcolor, int insd) +{ + int i; + int x = 0, y = 0, ym = 0; + if (!insd && ins >= 0) k_ins = 2; + for (i = 0; i < nbutton; i++) if (button[i] && button[i]->drw > 0) + { + int xx = x + button[i]->w + delt; + if (x != 0 && xx > w + delt) + { + y += ym + delt; ym = 0; + x = 0; xx = x + button[i]->w + delt; + } + button[i]->Draw(drw, x0 + x, y0 + y, + dcolor, lcolor, tcolor, k_ins == 1 && ins == i); + x = xx; + if (ym < button[i]->h) ym = button[i]->h; + } +} + +int TXButtonArray::ButtonPnt(int xp, int yp, int w, int &n, int kind) +{ + int i; + int x = 0, y = 0, ym = 0; + if (ins < 0 && (kind == 2 || kind == 3)) return INT_MIN; + for (i = 0; i < nbutton; i++) if (button[i] && button[i]->drw > 0) + { + int xx = x + button[i]->w + delt; + if (x != 0 && xx > w + delt) + { + y += ym + delt; ym = 0; + x = 0; xx = x + button[i]->w + delt; + } + if (ins < 0 || i == ins) + { + int wh = button[i]->ButtonPnt(xp - x, yp - y, n, kind); + if (n == -1) n = i; + if (i == ins) + { + if (kind == 1) return wh; + else if (kind == 2) + { + if (wh == INT_MIN || n < 0) + { + if (k_ins != 2) {k_ins = 2; n = -10; return 1000;} + } + else if (k_ins != 1) {k_ins = 1; return 1000;} + return wh; + } + else if (kind == 3) + { + if (wh == INT_MIN) + { + n = -10; + if (k_ins == 1) wh = 1000; + } + k_ins = 0; ins = -1; + return wh; + } + else return wh; + } + else if (wh != INT_MIN) + { + if (kind == 1) {ins = i; k_ins = 1; return wh;} + else if (kind == 2 || kind == 3) return INT_MIN; + else return wh; + } + } + x = xx; + if (ym < button[i]->h) ym = button[i]->h; + } + n = -10; + return INT_MIN; +} + +struct TMultiButton : public TXButton +{ + TMultiButton(int n = -1, int w = 100, int h = 20, int d = 2) + : TXButton(n, w, h), a(d) {} + + virtual void Draw(TGraphDraw *drw, int x0, int y0, unsigned long dcolor, + unsigned long lcolor, unsigned long tcolor, int ins = 0); + virtual int ButtonPnt(int xp, int yp, int &n, int kind = 0); + + void SetDefW(); + + TXButtonArray a; +}; + +void TMultiButton::Draw(TGraphDraw *drw, int x0, int y0, unsigned long dcolor, + unsigned long lcolor, unsigned long tcolor, int ins) +{ + a.Draw(drw, x0, y0, w, dcolor, lcolor, tcolor, ins); +} + +int TMultiButton::ButtonPnt(int xp, int yp, int &n, int kind) +{ + if (a.GetInsert() < 0 && (xp < 0 || yp < 0 || xp > w || yp > h)) return INT_MIN; + return a.ButtonPnt(xp, yp, w, n, kind); +} + +void TMultiButton::SetDefW() +{ + w = a.GetFWidth(); + if (w < 0) w = 0; + h = a.GetHeight(w); +} + +#endif //_HEADER_BUTTONS_H + diff --git a/programs/games/checkers/trunk/checkers.cpp b/programs/games/checkers/trunk/checkers.cpp new file mode 100644 index 0000000000..a197773d6d --- /dev/null +++ b/programs/games/checkers/trunk/checkers.cpp @@ -0,0 +1,1420 @@ +#define BUILD_RUS +#ifndef __MENUET__ +#include +#include +#include +#include +#include +#else +#include +#include +using namespace Menuet; +#define strlen StrLen +#define strcpy StrCopy +#define memcpy MemCopy +#include +const unsigned dectab[] = { 1000000000, 100000000, 10000000, 1000000, 100000, + 10000, 1000, 100, 10, 0 }; +int sprintf( char *Str, char* Format, ... ) +{ + int i, fmtlinesize, j, k, flag; + unsigned head, tail; + char c; + va_list arglist; + // + va_start(arglist, Format); + + // + fmtlinesize = strlen( Format ); + // + if( fmtlinesize == 0 ) return 0; + + // + for( i = 0, j = 0; i < fmtlinesize; i++ ) + { + // + c = Format[i]; + // + if( c != '%' ) + { + Str[j++] = c; + continue; + } + // + i++; + // + if( i >= fmtlinesize ) break; + + // + flag = 0; + // + c = Format[i]; + if (c == 'l') c = Format[++i]; + // + switch( c ) + { + // + case '%': + Str[j++] = c; + break; + // + case 's': + char* str; + str = va_arg(arglist, char*); + for( k = 0; ( c = str[k] ) != 0; k++ ) + { + Str[j++] = c; + } + break; + // + case 'c': + Str[j++] = va_arg(arglist, int) & 0xFF; + break; + // + case 'u': + case 'd': + head = va_arg(arglist, unsigned); + for( k = 0; dectab[k] != 0; k++ ) + { + tail = head % dectab[k]; + head /= dectab[k]; + c = head + '0'; + if( c == '0' ) + { + if( flag ) Str[j++] = c; + } + else + { + flag++; + Str[j++] = c; + } + // + head = tail; + } + // + c = head + '0'; + Str[j++] = c; + break; + default: + break; + } + } + // + Str[j] = 0; + return j; +} +int isdigit(int c) +{ + return (c>='0' && c<='9'); +} +int atoi(const char* string) +{ + int res=0; + int sign=0; + const char* ptr; + for (ptr=string; *ptr && *ptr<=' ';ptr++); + if (*ptr=='-') {sign=1;++ptr;} + while (*ptr >= '0' && *ptr <= '9') + { + res = res*10 + *ptr++ - '0'; + } + if (sign) res = -res; + return res; +} +int islower(int c) +{ + return (c>='a' && c<='z'); +} +int abs(int n) +{ + return (n<0)?-n:n; +} +int memcmp(const void* buf1, const void* buf2, unsigned count) +{ + const char* ptr1 = (const char*)buf1; + const char* ptr2 = (const char*)buf2; + unsigned i=0; + while (i' +#define XK_minus '-' +#define XK_equal '=' +#define XK_underscore '_' +#define XK_plus '+' +#define XK_Delete 0xB6 +#define XK_F8 0x39 +#define XK_l 'l' +#define XK_L 'L' +#define XK_F2 0x33 +#define XK_s 's' +#define XK_S 'S' +#define XK_slash '/' +#define XK_question '?' +#define XK_n 'n' +#define XK_N 'N' +#define XK_t 't' +#define XK_T 'T' +#define XK_r 'r' +#define XK_R 'R' +#define XK_b 'b' +#define XK_B 'B' +#define XK_f 'f' +#define XK_F 'F' +#define assert(a) /* nothing */ +#include "qsort.c" +#endif +#include "gr-draw.h" +#include "board.h" +#include "player.h" +#include "buttons.h" +#include "sysproc.h" + +char *strskipref(char *s1, char *s2) +{ + int L = strlen(s2); + if (strncmp(s1, s2, L) == 0) return s1 + L; + else return 0; +} + +class TPlayArray +{ +public: + TPlayArray(int d = 10) : play(0), nplay(0), mplay(0) {} + ~TPlayArray() {Clear();} + + void Clear(); + void Add(const PlayWrite &pl); + PlayWrite &operator[](int i) {return play[i];} + int GetNPlay() const {return nplay;} +#ifndef __MENUET__ + int OpenFile(const char *name, int kind); + int MsgOpenFile(const char *name, int kind); + int SaveFile(const char *name, int num, int kind); + int MsgSaveFile(const char *name, int num, int kind); +#endif + void Del(int n); +protected: + void Extend(int n = -1); + + PlayWrite *play; + int nplay, mplay; +protected: +#ifndef __MENUET__ + static const char *const search[]; + static int AnalizeKind(FILE *f, const int w[], const char *smb = 0); + static int ReadFileTo(FILE *f, char c); + static int ReadFileTo(FILE *f, const char *c); + static int ReadTheText(FILE *f, const char *s); +#endif +}; + +#ifndef __MENUET__ +const char *const TPlayArray::search[] = + {"checkers-", "play:", "text", "bin_1.0\n", "history_", "1.0", "1.1"}; +#endif + +void TPlayArray::Clear() +{ + if (play) delete[] play; + play = 0; nplay = 0; mplay = 0; +} + +void TPlayArray::Extend(int n) +{ + if (n < 0) n = nplay + 1; + if (mplay < n) + { + PlayWrite *p_old = play; + int m_old = mplay; + mplay = n * 2; + play = new PlayWrite[mplay]; + if (p_old) + { + for (int i = 0; i < m_old; i++) play[i] = p_old[i]; + delete[] p_old; + } + } +} + +void TPlayArray::Add(const PlayWrite &pl) +{ + Extend(); + play[nplay] = pl; + nplay++; +} + +#ifndef __MENUET__ +int TPlayArray::AnalizeKind(FILE *f, const int w[], const char *smb) +{ + int i, L, was1 = 1; + unsigned char ch; + int fnd[NELEM(search)]; + for (i = 0; i < NELEM(search); i++) fnd[i] = 1; + for (L = 0; was1; L++) + { + was1 = 0; + if (fread(&ch, 1, 1, f) != 1) return (L == 0) ? -2 : -1; + for (i = 0; w[i] >= 0; i++) if (fnd[i]) + { + if (tolower(ch) != tolower(search[w[i]][L])) fnd[i] = 0; + else + { + was1 = 1; + if (search[w[i]][L+1] == 0) + { + if (smb && smb[0] && fread(&ch, 1, 1, f) == 1) + { + ungetc(ch, f); + if (strchr(smb, tolower(ch)) || isalpha(ch) && strchr(smb, toupper(ch))) + { + break; + } + } + return i; + } + } + } + } + return -10 - L; +} + +int TPlayArray::ReadFileTo(FILE *f, char c) +{ + char ch; + do + { + if (fread(&ch, 1, 1, f) != 1) return 0; + } + while(ch != c); + return 1; +} + +int TPlayArray::ReadFileTo(FILE *f, const char *c) +{ + char ch; + do + { + if (fread(&ch, 1, 1, f) != 1) return 0; + } + while(!strchr(c, ch)); + return 1; +} + +int TPlayArray::ReadTheText(FILE *f, const char *s) +{ + char ch; + while (*s) + { + if (fread(&ch, 1, 1, f) != 1 || ch != *s) return 0; + s++; + } + return 1; +} + +int TPlayArray::OpenFile(const char *name, int kind) +{ + int k_fnd = 0; + FILE *f = fopen(name, "rb"); + if (!f) return -1; + if (kind == -1) + { + const int w[] = {0, -1}; + int r = AnalizeKind(f, w); + if (r >= 0) {kind = w[r]; k_fnd = 1;} + else if (r == -11) {kind = 3; k_fnd = 3;} + else {fclose(f); return (kind == -2) ? -2 : -10;} + } + if (kind == 0) + { + if (k_fnd < 1 && !ReadFileTo(f, '-')) {fclose(f); return -10;} + k_fnd = 1; + const int w[] = {1, 4, -1}; + int r = AnalizeKind(f, w); + if (r >= 0) {kind = w[r]; k_fnd = 2;} + else {fclose(f); return -10;} + } + if (kind == 1) + { + if (k_fnd < 2 && !ReadFileTo(f, ':')) {fclose(f); return -10;} + k_fnd = 2; + const int w[] = {2, 3, -1}; + int r = AnalizeKind(f, w); + if (r >= 0) {kind = w[r]; k_fnd = 3;} + else {fclose(f); return -10;} + } + if (kind == 4) + { + if (k_fnd < 2 && !ReadFileTo(f, '_')) {fclose(f); return -10;} + k_fnd = 2; + const int w[] = {5, 6, -1}; + int r = AnalizeKind(f, w, ".1234567890"); + if (r >= 0) {kind = w[r]; k_fnd = 3;} + else {fclose(f); return -10;} + } + if (kind == 5) {kind = 3; k_fnd = 0;} + if (kind == 6) + { + if (!ReadFileTo(f, "\n\r")) {fclose(f); return -4;} + k_fnd = 3; + PlayWrite *pl = 0; + int np = THistory::HRead(f, pl); + if (np > 0 && pl) + { + int i; + Extend(nplay + np); + for (i = 0; i < np; i++) + { + if (pl[i].GetN() >= 3) play[nplay++] = pl[i]; + } + } + if (pl) delete[] pl; + fclose(f); + return 1; + } + if (kind == 2) + { + printf("kind = 2\n"); + unsigned char ch; + do + { + if (fread(&ch, 1, 1, f) != 1) {fclose(f); return -10;} + } + while(!isspace(ch)); + PlayWrite pl; + char word[101]; + int i, kind = 0; + for (;;) + { + do + { + if (fread(&ch, 1, 1, f) != 1) break; + } + while(ch == 0 || isspace(ch)); + if (feof(f)) strcpy(word, "[end]"); + else + { + i = 0; + while(ch != 0 && !isspace(ch)) + { + if (i < 100) word[i++] = ch; + if (fread(&ch, 1, 1, f) != 1) break; + } + word[i] = 0; + } + if (word[0] != '[') + { + if (kind == 1) + { + if (word[0] != '#' && word[0] != '$' && word[0] != '%') + { + Position pos; + pos.Read(word, 1); + pl.Clear(); + pl.Add(0, pos); + kind = 2; + } + } + else if (kind == 2) + { + if (word[0] != '#' && word[0] != '$' && word[0] != '%') + { + for (i = 0; word[i] && word[i] != '.' && word[i] != ','; i++) + { + if (!isdigit((unsigned char)word[i])) {i = -1; break;} + } + if (i == -1) + { + PlayWrite::PMv pmv; + if (pl.GetPosL(pmv.pos) < 0) kind = 3; + else if (!pmv.pos.ReadMv(pmv.mv, word, 1)) kind = 3; + else if (pl.Add(pmv.mv) != 0) kind = 3; + } + } + } + } + else + { + if (kind == 2 || kind == 3) + { + if (pl.GetN() > 0) Add(pl); + pl.Clear(); + } + kind = 0; + for (i = 0; word[i]; i++) + { + word[i] = (char)tolower((unsigned char)word[i]); + } + if (strskipref(word, "[end]")) break; + else if (strskipref(word, "[play_v1.1]")) kind = 1; + } + } + fclose(f); + return 1; + } + if (kind == 3) + { + char ch[LEN_WPOS]; + if (k_fnd < 3 && !ReadFileTo(f, '\n')) {fclose(f); return -10;} + k_fnd = 3; + do + { + PlayWrite pl; + for (;;) + { + int i; + for (i = 0; i < LEN_WPOS; i++) + { + if (fread(ch + i, 1, 1, f) != 1 || ch[i] < 0) break; + } + if (i < LEN_WPOS) break; + PlayWrite::PMv pmv0, pmv1; + pmv1.pos.Read(ch); + pmv1.pos.Reverse(); + if (pl.GetPMvL(pmv0) >= 0) + { + TComputerPlayer::Z z; + z.FindAllMoves(pmv0); + int r; + for (r = 0; r < z.narr; r++) + { + if (memcmp(z.array[r].pos.SH, pmv1.pos.SH, sizeof(pmv1.pos.SH)) == 0) + { + pmv1 = z.array[r]; + break; + } + } + if (r < z.narr) pl.Add(pmv1); + else {fclose(f); return -3;} + } + else pl.Add(0, pmv1.pos); + } + if (pl.GetN() > 0) Add(pl); + } + while(!feof(f)); + fclose(f); + return 1; + } + fclose(f); + return -10; +} + +int TPlayArray::MsgOpenFile(const char *name, int kind) +{ + int n0 = nplay, no_games = 0; + int r = OpenFile(name, kind); + if (r <= 0) + { + if (r == -1) + { +#ifdef BUILD_RUS + printf("\n誨: 䠩 \"%s\".\n", name); +#else + printf("\nCheckers: Can't open the file \"%s\".\n", name); +#endif + return 0; + } + else if (r == -2) + { +#ifdef BUILD_RUS + printf("\n誨: \"%s\" .\n", name); +#else + printf("\nCheckers: The file \"%s\" is empty.\n", name); +#endif + return 0; + } + else if (r == -3) + { +#ifdef BUILD_RUS + printf("\n誨: \"%s\" 訡.\n", name); +#else + printf("\nCheckers: Invalid file \"%s\".\n", name); +#endif + return 0; + } + else if (r == -4) no_games = 1; + else if (r == -10) + { +#ifdef BUILD_RUS + printf("\n誨: \"%s\" ⨯.\n", name); +#else + printf("\nCheckers: The file \"%s\" has wrong type.\n", name); +#endif + return 0; + } + else + { +#ifdef BUILD_RUS + printf("\n誨: 訡 䠩 \"%s\".\n", name); +#else + printf("\nCheckers: Error openning the file \"%s\".\n", name); +#endif + return 0; + } + } + if (!no_games && nplay > n0) return 1; + else + { +#ifdef BUILD_RUS + printf("\n誨: \"%s\" ᮤন .\n", name); +#else + printf("\nCheckers: File \"%s\" don't contains games.\n", name); +#endif + return 0; + } +} + +int TPlayArray::SaveFile(const char *name, int num, int kind) +{ + FILE *f = 0; + if (kind == 0 || kind == 1 || kind == 2) + { + f = fopen(name, "wt"); + if (!f) return -1; + fprintf(f, "checkers-play:text\n"); + int i0 = num, i; + if (num < 0) {i0 = 0; num = nplay-1;} + for (i = i0; i <= num; i++) if (play[i].GetN() > 0) + { + PlayWrite::PMv pmv; + if (play[i].GetPos(pmv.pos, 0) < 0) return -9; + char *str = new char[10 + NUM_CELL]; + if (!str) return -5; + pmv.pos.Write(str, 1); + fprintf(f, "\n[Play_v1.1]#%d %s\n", i - i0 + 1, str); + delete[] str; + int j; + for (j = 1; j < play[i].GetN(); j++) + { + if (play[i].GetPos(pmv.pos, j - 1) < 0) return -9; + if (play[i].GetMove(pmv.mv, j) < 0) return -9; + str = new char[pmv.pos.GetLenMvEx(pmv.mv, 11)]; + if (!str) return -5; + pmv.pos.WriteMvEx(pmv.mv, str, 11); + if (j % 2 == 1) + { + int nbytes = fprintf(f, "%d. ", (j + 1) / 2); + while(nbytes++ < 5) fprintf(f, " "); + } + fprintf(f, "%s", str); + if (j % 2 == 0 || j == play[i].GetN() - 1) fprintf(f, "\n"); + else fprintf(f, " ,\t"); + delete[] str; + } + } + fclose(f); + return 1; + } + else if (kind == -1 || kind == 3) + { + f = fopen(name, "wb"); + if (!f) return -1; + if (kind == 3) fprintf(f, "checkers-play:bin_1.0\n"); + int i = num; + if (num < 0) {i = 0; num = nplay-1;} + for (; i <= num; i++) + { + char ch[LEN_WPOS]; + Position pos; + play[i].GetPosL(pos); + if (!pos.AllCanEat() && !pos.AllCanMove()) + { + ch[0] = (pos.wmove == 0) ? char(-3) : char(-1); + } + else ch[0] = char(-2); + fwrite(ch, 1, 1, f); + int j; + for (j = 0; j < play[i].GetN(); j++) + { + Position pos; + play[i].GetPos(pos, j); + pos.Reverse(); + pos.Write(ch); + fwrite(ch, LEN_WPOS, 1, f); + } + } + fclose(f); + return 1; + } + if (f) fclose(f); + return -10; +} + +int TPlayArray::MsgSaveFile(const char *name, int num, int kind) +{ + int r = SaveFile(name, num, kind); + if (r <= 0) + { + if (r == -1) + { +#ifdef BUILD_RUS + printf("\n誨: 䠩 \"%s\" .\n", name); +#else + printf("\nCheckers: Can't open the file \"%s\" to write.\n", name); +#endif + } + else if (r == -5) + { +#ifdef BUILD_RUS + printf("\n誨: 筮 ࠭ 䠩 \"%s\".\n", name); +#else + printf("\nCheckers: Not enough memory to save the file \"%s\".\n", name); +#endif + } + else if (r == -10) + { +#ifdef BUILD_RUS + printf("\n誨: \"%s\" ⨯.\n", name); +#else + printf("\nCheckers: The file \"%s\" has wrong type.\n", name); +#endif + } + else + { +#ifdef BUILD_RUS + printf("\n誨: 訡 ࠭ 䠩 \"%s\".\n", name); +#else + printf("\nCheckers: Error saving the file \"%s\".\n", name); +#endif + } + return 0; + } + else + { +#ifdef BUILD_RUS + printf("\n誨: \"%s\" ࠭.\n", name); +#else + printf("\nCheckers: File \"%s\" saved.\n", name); +#endif + return 1; + } +} +#endif + +void TPlayArray::Del(int n) +{ + if (!play || n < 0 || n >= nplay) return; + else if (nplay <= 1) {Clear(); return;} + int i; + for (i = n; i < nplay - 1; i++) play[i] = play[i+1]; + play[nplay - 1].Clear(); + nplay--; +} + + +void SetPlayerString(char *str, int c, TChPlayer *p) +{ + strcpy(str, c ? "blue: " : "red: "); + if (!p) strcat(str, "input"); + else strcat(str, "computer"); +} + +class TMainDraw : public TSomeDraw +{ +public: + TMainDraw() : undo_redo(0), ur_type(-1), cur_play(0), + def_savefile("save.che"), def_savekind(2) {InitButton();} + + virtual void Draw(TGraphDraw *drw, int w, int h) + { + int d = button.GetDelt(); + int hh = button.GetHeight(w - 2*d); + if (hh != 0) hh += d; + drw->SetColor(drw->GetBlackColor()); + button.Draw(drw, d, h - hh, w - 2*d); + } + + virtual void DrawB(TGraphDraw *drw, TChBoard &board) + { + int urt = (board.GetCurMoveN() <= 0) + + 2*(board.GetCurMoveN() >= board.GetNumMove()); + if (ur_type != urt) SetButtonKind(board); + Draw(drw, board.GetW(), board.GetH()); + } + + virtual TIntPoint GetDSize(int w, int h) + { + int d = button.GetDelt(); + int hh = button.GetHeight(w - 2*d); + if (hh != 0) hh += d; + return TIntPoint(0, hh); + } + + virtual int ButtonPnt(int xp, int yp, int w, int h, int &n, int k = 0) + { + int d = button.GetDelt(); + int hh = button.GetHeight(w - 2*d); + if (hh != 0) hh += d; + return button.ButtonPnt(xp - d, yp - (h - hh), w - 2*d, n, k); + } + + void InitButton(); + void SetButtonKind(const TChBoard &board); + void PressUR(int n, TChBoard &board, TGraphDraw *drw); + void PressLS(int n, TChBoard &board, TGraphDraw *drw); + void CurPlayNorm() + { + if (cur_play < 0 || cur_play >= play.GetNPlay()) cur_play = 0; + } + + TXButtonArray button; + TMultiButton *undo_redo, *play_list; + char player_str[2][50], play_num[2][10]; + TPlayArray play; + int cur_play; + char *def_savefile; + int def_savekind; +protected: + int ur_type; +}; + +void TMainDraw::InitButton() +{ + button.Add(1, 80, 22, "new game"); + button.Add(6, 60, 22, "list"); + button.Add(7, 60, 22, "delete"); + play_list = new TMultiButton(20); + play_list->a.Add(26, 20, 22, "1"); + play_list->a.Add(21, 20, 22, "-"); + play_list->a.Add(23, 37, 22, play_num[0], -2); + play_list->a.Add(22, 20, 22, "+"); + play_list->a.Add(27, 37, 22, play_num[1]); + play_list->SetDefW(); + button.Add(play_list); + button.Add(24, 50, 22, "clear"); +#ifndef __MENUET__ + button.Add(25, 50, 22, "save"); +#endif + button.Add(2, 120, 22, player_str[0]); + button.Add(3, 120, 22, player_str[1]); + button.Add(4, 110, 22, "rotate board"); + undo_redo = new TMultiButton(10); + undo_redo->a.Add(11, 27, 22, "<<"); + undo_redo->a.Add(12, 20, 22, "<"); + undo_redo->a.Add(15, 20, 22, "^"); + undo_redo->a.Add(13, 20, 22, ">"); + undo_redo->a.Add(14, 27, 22, ">>"); + undo_redo->SetDefW(); + button.Add(undo_redo); + button.Add(5, 60, 22, "exit"); +} + +void TMainDraw::SetButtonKind(const TChBoard &board) +{ + int thick; + TextButton *txb; + TXButton *bt1; + ur_type = 0; + SetPlayerString(player_str[0], 0, board.GetPlayer(0)); + SetPlayerString(player_str[1], 1, board.GetPlayer(1)); + int is_drw = !board.GetPViewStatus(); + bt1 = button.GetButton(2); + if (bt1) bt1->drw = is_drw; + bt1 = button.GetButton(3); + if (bt1) bt1->drw = is_drw; + if (board.GetCurMoveN() <= 0) {ur_type++; thick = 0;} + else thick = 3; +// txb = dynamic_cast(undo_redo->a.GetButton(11)); +// if (txb) txb->thick = thick; +// txb = dynamic_cast(undo_redo->a.GetButton(12)); +// if (txb) txb->thick = thick; +// we can use simple static cast + ((TextButton*)(undo_redo->a.GetButton(11)))->thick = thick; + ((TextButton*)(undo_redo->a.GetButton(12)))->thick = thick; + if (board.GetCurMoveN() >= board.GetNumMove()) {ur_type += 2; thick = 0;} + else thick = 3; +// txb = dynamic_cast(undo_redo->a.GetButton(13)); +// if (txb) txb->thick = thick; +// txb = dynamic_cast(undo_redo->a.GetButton(14)); +// if (txb) txb->thick = thick; + ((TextButton*)(undo_redo->a.GetButton(13)))->thick = thick; + ((TextButton*)(undo_redo->a.GetButton(14)))->thick = thick; + if (board.GetCurMoveN() < board.GetNumMove() || + (board.GetPViewStatus() && board.GetGameEnd() <= 0)) + { + thick = 3; + } + else thick = 0; +// txb = dynamic_cast(undo_redo->a.GetButton(15)); +// if (txb) txb->thick = thick; + ((TextButton*)(undo_redo->a.GetButton(15)))->thick = thick; + if (play.GetNPlay() == 0) is_drw = 1; + bt1 = button.GetButton(6); + if (bt1) bt1->drw = is_drw; + bt1 = button.GetButton(7); + if (bt1) bt1->drw = !is_drw; +#ifndef __MENUET__ + bt1 = button.GetButton(25); + if (bt1) bt1->drw = !is_drw; +#endif + is_drw = board.GetPViewStatus() && play.GetNPlay() > 1; + bt1 = button.GetButton(20); + if (bt1) bt1->drw = is_drw; + bt1 = button.GetButton(24); + if (bt1) bt1->drw = is_drw; + if (is_drw) + { + play_num[0][0] = 0; play_num[1][0] = 0; + if (cur_play >= 0) sprintf(play_num[0], "%d", cur_play + 1); + sprintf(play_num[1], "%d", play.GetNPlay()); + thick = (cur_play <= 0) ? 0 : 3; +#define dynamic_cast static_cast + txb = dynamic_cast(play_list->a.GetButton(21)); + if (txb) txb->thick = thick; + txb = dynamic_cast(play_list->a.GetButton(26)); + if (txb) txb->thick = thick; + thick = (cur_play >= play.GetNPlay() - 1) ? 0 : 3; + txb = dynamic_cast(play_list->a.GetButton(22)); + if (txb) txb->thick = thick; + txb = dynamic_cast(play_list->a.GetButton(27)); + if (txb) txb->thick = thick; +#undef dynamic_cast + } +} + +void TMainDraw::PressUR(int n, TChBoard &board, TGraphDraw *drw) +{ + int mv; + if (n == 11) mv = 0; + else if (n == 12) mv = board.GetCurMoveN() - 1; + else if (n == 13) mv = board.GetCurMoveN() + 1; + else mv = board.GetNumMove(); + if (board.SetCurMoveN(mv)) + { + SetButtonKind(board); + if (drw && drw->IsDraw()) + { + drw->DrawClear(); + board.Draw(drw); + } + } + else Draw(drw, board.GetW(), board.GetH()); +} + +void TMainDraw::PressLS(int n, TChBoard &board, TGraphDraw *drw) +{ + int need_redraw = 0; + if (n == 6) + { + if (!board.GetPViewStatus() || play.GetNPlay() == 0) + { + PlayWrite cur_pw = board.GetPlay(); + if (cur_pw.GetN() > 2 || play.GetNPlay() == 0) play.Add(board.GetPlay()); + cur_play = play.GetNPlay() - 1; + board.SetPlay(play[cur_play]); + need_redraw = 1; + } + } + else if (n == 7) + { + if (board.GetPViewStatus() && play.GetNPlay() != 0) + { + play.Del(cur_play); + if (play.GetNPlay() >= 1) + { + if (cur_play >= play.GetNPlay()) cur_play--; + board.SetPlay(play[cur_play]); + } + need_redraw = 1; + } + } + else if (n == 21) + { + if (cur_play > 0) {board.SetPlay(play[--cur_play]); need_redraw = 1;} + } + else if (n == 22) + { + if (cur_play < play.GetNPlay() - 1) + { + board.SetPlay(play[++cur_play]); need_redraw = 1; + } + } + else if (n == 26) + { + if (cur_play > 0) + { + cur_play = 0; + board.SetPlay(play[cur_play]); need_redraw = 1; + } + } + else if (n == 27) + { + if (cur_play < play.GetNPlay() - 1) + { + cur_play = play.GetNPlay() - 1; + board.SetPlay(play[cur_play]); need_redraw = 1; + } + } + else if (n == 24) {play.Clear(); cur_play = 0; need_redraw = 1;} +#ifndef __MENUET__ + else if (n == 25) + { + if (play.GetNPlay() > 0) play.MsgSaveFile(def_savefile, -1, def_savekind); + } + else if (n == 28) + { + if (play.GetNPlay() > 0) play.MsgSaveFile(def_savefile, cur_play, def_savekind); + } +#endif + if (need_redraw) + { + SetButtonKind(board); + if (drw && drw->IsDraw()) + { + drw->DrawClear(); + board.Draw(drw); + } + } + else Draw(drw, board.GetW(), board.GetH()); +} + +struct TTimerDraw +{ + TTimerDraw(TChBoard *brd, TGraphDraw *drw) : brd(brd), drw(drw) {} + + TChBoard *brd; + clock_t st, ut, dt; + double x0; + TGraphDraw *drw; + + static void draw(void *v, int k = 0); +}; + +void TTimerDraw::draw(void *v, int k) +{ + TTimerDraw &d = *(TTimerDraw*)v; + clock_t t = clock(); + if (k == 0 && t - d.ut < CLOCKS_PER_SEC * 0.01) return; + if (k > 0) + { + d.st = t; + if (!d.drw || !d.drw->IsDraw()) return; + d.drw->DrawClear(); + d.brd->Draw(d.drw); + d.dt = t; + } + else if (!d.drw || !d.drw->IsDraw()) return; + double xold = d.x0; + if (k >= 0) + { + d.x0 = (1 - cos(2.0 * (t - d.st) / CLOCKS_PER_SEC)) / 2; + d.brd->DrawTimer(d.drw, d.x0, 0); + d.ut = t; + if (k == 0 && t - d.dt > CLOCKS_PER_SEC * 0.5) + { + d.brd->Draw(d.drw); + d.dt = t; + } + } + if (k <= 0) d.brd->DrawTimer(d.drw, xold, 1); +} + + +struct TMainData +{ + TChBoard board; + TComputerPlayer player; + TMainDraw main_draw; + + TMainData(int id = 0); + void InitDef(); + static int EventFunction(const TGraphDraw::event &ev); + void NewGame(TGraphDraw *drw); + void RotateBoard(TGraphDraw *drw); + void PlayerPress(int np, TGraphDraw *drw); + void GoToCurMove(TGraphDraw *drw); +}; + +TMainData::TMainData(int id) : board(id) +{ + board.SetCheckResize(1); + board.SetPlayer(1, &player); + board.SetBottomColor(0); + board.SetSomeDraw(&main_draw); + board.SetMinWSize(90, 140); +} + +void TMainData::InitDef() +{ + if (main_draw.play.GetNPlay() > 0) + { + main_draw.CurPlayNorm(); + board.SetPlay(main_draw.play[main_draw.cur_play]); + } + main_draw.SetButtonKind(board); +} + +void TMainData::NewGame(TGraphDraw *drw) +{ + board.NewGame(); + main_draw.SetButtonKind(board); + if (drw && drw->IsDraw()) {drw->DrawClear(); board.Draw(drw);} +} + +void TMainData::RotateBoard(TGraphDraw *drw) +{ + board.SetBottomColor(3 - board.GetBottomColor()); + if (drw && drw->IsDraw()) {drw->DrawClear(); board.Draw(drw);} +} + +void TMainData::PlayerPress(int np, TGraphDraw *drw) +{ + if (np != 0 && np != 1) return; + if (board.GetPlayer(np)) board.SetPlayer(np, 0); + else board.SetPlayer(np, &player); + if (board.GetPlayer(0) && !board.GetPlayer(1)) + { + board.SetBottomColor(1); + } + if (board.GetPlayer(1) && !board.GetPlayer(0)) + { + board.SetBottomColor(0); + } + main_draw.SetButtonKind(board); + if (drw && drw->IsDraw()) {drw->DrawClear(); board.Draw(drw);} +} + +void TMainData::GoToCurMove(TGraphDraw *drw) +{ + board.GoToCurMove(); + main_draw.SetButtonKind(board); + if (drw && drw->IsDraw()) {drw->DrawClear(); board.Draw(drw);} +} + +int TMainData::EventFunction(const TGraphDraw::event &ev) +{ + if (!ev.any.drw->data) return -100; + TMainData &data = *(TMainData*)ev.any.drw->data; + int nbutton, ret = 0; + switch(ev.type) + { + case TGraphDraw::event::button_down: + if (ev.button.n != 1) break; + ev.button.drw->OpenDraw(); + if (data.main_draw.ButtonPnt(ev.button.x, ev.button.y, + data.board.GetW(), data.board.GetH(), nbutton, 1) > 0) + { + data.main_draw.Draw(ev.button.drw, data.board.GetW(), data.board.GetH()); + ret |= TGraphDraw::ret_setcapture; + } + else data.board.MouseClick(ev.button.drw, ev.button.x, ev.button.y); + ev.button.drw->CloseDraw(); + break; + case TGraphDraw::event::mouse_move: + if (ev.button.n >= 0 && ev.button.n != 1) break; + ev.button.drw->OpenDraw(); + if (data.main_draw.ButtonPnt(ev.button.x, ev.button.y, + data.board.GetW(), data.board.GetH(), nbutton, 2) >= 1000) + { + data.main_draw.Draw(ev.button.drw, data.board.GetW(), data.board.GetH()); + } + ev.button.drw->CloseDraw(); + break; + case TGraphDraw::event::button_up: + if (ev.button.n != 1) break; + ev.button.drw->OpenDraw(); + if (data.main_draw.ButtonPnt(ev.button.x, ev.button.y, + data.board.GetW(), data.board.GetH(), nbutton, 3) > 0) + { + switch(nbutton) + { + case 1: + data.NewGame(ev.button.drw); + break; + case 2: + case 3: + data.PlayerPress(nbutton - 2, ev.button.drw); + break; + case 4: + data.RotateBoard(ev.button.drw); + break; + case 5: + data.main_draw.Draw(ev.button.drw, data.board.GetW(), data.board.GetH()); + ev.button.drw->Quit(); + break; + case 11: + case 12: + case 13: + case 14: + data.main_draw.PressUR(nbutton, data.board, ev.button.drw); + break; + case 15: + data.GoToCurMove(ev.button.drw); + break; + case 6: + case 7: + case 21: + case 22: + case 23: + case 24: + case 25: + case 26: + case 27: + data.main_draw.PressLS(nbutton, data.board, ev.button.drw); + break; + default: + data.main_draw.Draw(ev.button.drw, data.board.GetW(), data.board.GetH()); + break; + } + } + ev.button.drw->CloseDraw(); + break; + case TGraphDraw::event::draw: + ev.button.drw->OpenDraw(); + data.board.Draw(ev.button.drw); + ev.button.drw->CloseDraw(); + break; + case TGraphDraw::event::key_down: + ev.button.drw->OpenDraw(); + if (ev.key.k == XK_Left) data.board.PKeyEvent(ev.button.drw, TChBoard::PLeft); + else if (ev.key.k == XK_Right) data.board.PKeyEvent(ev.button.drw, TChBoard::PRight); + else if (ev.key.k == XK_Up) data.board.PKeyEvent(ev.button.drw, TChBoard::PUp); + else if (ev.key.k == XK_Down) data.board.PKeyEvent(ev.button.drw, TChBoard::PDown); + else if (ev.key.k == XK_Return || ev.key.k == XK_space) + { + data.board.PKeyEvent(ev.button.drw, TChBoard::PEnter); + } + else if (ev.key.k == XK_Escape) ev.button.drw->Quit(); + else if (ev.key.k == XK_less) data.main_draw.PressUR(11, data.board, ev.button.drw); + else if (ev.key.k == XK_comma) data.main_draw.PressUR(12, data.board, ev.button.drw); + else if (ev.key.k == XK_period) data.main_draw.PressUR(13, data.board, ev.button.drw); + else if (ev.key.k == XK_greater) data.main_draw.PressUR(14, data.board, ev.button.drw); + else if (ev.key.k == XK_minus) data.main_draw.PressLS(21, data.board, ev.button.drw); + else if (ev.key.k == XK_equal) data.main_draw.PressLS(22, data.board, ev.button.drw); + else if (ev.key.k == XK_underscore) data.main_draw.PressLS(26, data.board, ev.button.drw); + else if (ev.key.k == XK_plus) data.main_draw.PressLS(27, data.board, ev.button.drw); + else if (ev.key.k == XK_Delete) data.main_draw.PressLS(7, data.board, ev.button.drw); + else if (ev.key.k == XK_F8) data.main_draw.PressLS(24, data.board, ev.button.drw); + else if (ev.key.k == XK_l || ev.key.k == XK_L) data.main_draw.PressLS(6, data.board, ev.button.drw); +#ifndef __MENUET__ + else if (ev.key.k == XK_F2) data.main_draw.PressLS(25, data.board, ev.button.drw); +#endif + else if (ev.key.k == XK_s || ev.key.k == XK_S) data.main_draw.PressLS(28, data.board, ev.button.drw); + else if (ev.key.k == XK_slash || ev.key.k == XK_question) data.GoToCurMove(ev.button.drw); + else if (ev.key.k == XK_n || ev.key.k == XK_N) data.NewGame(ev.button.drw); + else if (ev.key.k == XK_t || ev.key.k == XK_T) data.RotateBoard(ev.button.drw); + else if (ev.key.k == XK_r || ev.key.k == XK_R) data.PlayerPress(0, ev.button.drw); + else if (ev.key.k == XK_b || ev.key.k == XK_B) data.PlayerPress(1, ev.button.drw); + else if (ev.key.k == XK_f || ev.key.k == XK_F) + { + int w, h; + ev.button.drw->GetSize(w, h); + ev.button.drw->CloseDraw(); + if (DuplicateProcess() == 0) + { + ev.button.drw->ResReinit(w, h); + data.board.EraseHistory(); + } + } + ev.button.drw->CloseDraw(); + break; + case TGraphDraw::event::close: + ret = 1; + break; + } + return ret; +} + +#ifndef __MENUET__ +int main(int argc, char **argv) +{ + randomize(); + THistory::InitHFile(argv[0]); + TMainData data(-1); + if (argv && argc >= 2) + { + int i, kx = 1; + for (i = 1; i < argc; i++) + { + if (kx == 1 && argv[i][0] == '-') + { + if (strcmp(argv[i], "--") == 0) kx = 0; + else if (strcmp(argv[i], "-ssf") == 0) ssf = 1; + else if (strncmp(argv[i], "-save", 5) == 0) + { + int j = 5; + if (argv[i][j]) + { + if (argv[i][j] != '=' || !argv[i][j+1]) + { + data.main_draw.def_savekind = atoi(argv[i] + j); + while (argv[i][j] && argv[i][j] != '=') j++; + if (argv[i][j] != '=' || !argv[i][j+1]) continue; + } + data.main_draw.def_savefile = argv[i] + j + 1; + } + } + else printf("Checkers: Invalid key %s\n", argv[i]); + } + else if (kx == 0 || kx == 1) + { + data.main_draw.play.MsgOpenFile(argv[i], -1); + } + } + } + data.InitDef(); + TMainGraphDraw graph( +#ifdef BUILD_RUS + "誨" +#else + "Checkers" +#endif + ); + TTimerDraw timer_draw(&data.board, &graph); + data.player.draw = TTimerDraw::draw; data.player.data = &timer_draw; + graph.evfunc = TMainData::EventFunction; graph.data = &data; + graph.SetAboutInfo(1); + graph.Run(TGraphDraw::button_down_mask | TGraphDraw::button_up_mask | + TGraphDraw::key_down_mask | TGraphDraw::mouse_drag_mask, + 450 + 100 * ssf, 528); + return 0; +} +#else + +TMainData* mdata; +TMainGraphDraw* graph; + +bool MenuetOnStart(TStartData &me_start, TThreadData) +{ + mdata = new TMainData(-1); + graph = new TMainGraphDraw; + randomize(); + mdata->InitDef(); + static TTimerDraw timer_draw(&mdata->board, graph); + mdata->player.draw = TTimerDraw::draw; mdata->player.data = &timer_draw; + graph->data = mdata; + me_start.WinData.Title = +#ifdef BUILD_RUS + "誨" +#else + "Checkers" +#endif + ; + me_start.Width = 450 + 100*ssf; + me_start.Height = 528; + return true; +} +bool MenuetOnClose(TThreadData) +{ + delete mdata; + delete graph; + return true; +} +int MenuetOnIdle(TThreadData) +{return -1;} +void MenuetOnSize(int window_rect[], TThreadData) +{mdata->board.Resize(window_rect[2]-window_rect[0], window_rect[3]-window_rect[1]);} +void MenuetOnKeyPress(TThreadData) +{ + TGraphDraw::event ev; + ev.type = TGraphDraw::event::key_down; + ev.any.drw = graph; + ev.key.k = GetKey(); + mdata->EventFunction(ev); +} +void MenuetOnDraw(void) +{ + TGraphDraw::event ev; + ev.type = TGraphDraw::event::draw; + ev.any.drw = graph; + mdata->EventFunction(ev); +} +void MenuetOnMouse(TThreadData) +{ + short x,y; + GetMousePosition(x,y); + int m = GetMouseButton() & 1; + static int mprev = 0; + if (m == mprev) + return; + mprev = m; + TGraphDraw::event ev; + ev.type = m ? TGraphDraw::event::button_down : TGraphDraw::event::button_up; + ev.any.drw = graph; + ev.button.n = 1; + ev.button.x = x; + ev.button.y = y; + mdata->EventFunction(ev); +} +#endif diff --git a/programs/games/checkers/trunk/compile.txt b/programs/games/checkers/trunk/compile.txt new file mode 100644 index 0000000000..43175c8c18 --- /dev/null +++ b/programs/games/checkers/trunk/compile.txt @@ -0,0 +1,21 @@ +1. . + Borland C++ ( + ), FASM 1.64. +cpp2asm.bat ++- TASM-, + FASM-. + , , f_checkers.asm equ + . + - , fasm f_checkers.asm checkers. + +2. Linux. + make. Linux- . + . + DOS (cp866). + checkers.cpp +("#define BUILD_RUS"), *.cpp *.h dos2unix. + +3. DOS/Windows. + Borland C++ for DOS/Windows . + Borland C++, +checkers.cpp Windows win-chk.rc; + DOS egavga.bgi. diff --git a/programs/games/checkers/trunk/cpp2asm.bat b/programs/games/checkers/trunk/cpp2asm.bat new file mode 100644 index 0000000000..279fe4a332 --- /dev/null +++ b/programs/games/checkers/trunk/cpp2asm.bat @@ -0,0 +1,3 @@ +bcc32 -S -v- -R- -6 -a4 -O2 -Og -Oi -Ov -OS -k- -x- -D__MENUET__ -Iinclude checkers.cpp +echo include "me_make.inc" > f_checkers.asm +t2fasm < checkers.asm >> f_checkers.asm \ No newline at end of file diff --git a/programs/games/checkers/trunk/dos-draw.h b/programs/games/checkers/trunk/dos-draw.h new file mode 100644 index 0000000000..b1d530f51b --- /dev/null +++ b/programs/games/checkers/trunk/dos-draw.h @@ -0,0 +1,381 @@ +#include "gr-draw.h" + +#ifndef _DOS_GRAPHIC_DRAW_H +#define _DOS_GRAPHIC_DRAW_H + +#include "dosmouse.h" +#include "keysym.h" +#include +#include +#include +#include + +class TDosGraphDraw : public TGraphDraw +{ +public: + TDosGraphDraw(const char *s = 0); + ~TDosGraphDraw() {} +public: + static unsigned long GetKeySym(unsigned int key); +protected: + unsigned long bgcolor; + int quit; + TCursorVisible cursor; +public: + unsigned long GetBlackColor() {return 0;} + unsigned long GetWhiteColor() {return 15;} + unsigned long CreateColor(unsigned short red, + unsigned short green, unsigned short blue); + void FreeColor(unsigned long c) {} + unsigned long GetBgColor() {return bgcolor;} + void SetBgColor(unsigned long c) {bgcolor = c;} + + int GetStatus() {return (graphresult() == grOk) ? 1 : 0;} + int Init() {return 0;} + int Run(int evmask = 0, int w = INT_MIN, int h = INT_MIN); + + void GetSize(int &w, int &h); + int OpenDraw(); + int IsDraw() {return graphresult() == grOk && cursor.IsHidden();} + void CloseDraw() {cursor.Show();} + + int SetColor(unsigned long c); + int DrawLine(int x0, int y0, int x1, int y1); + int DrawText(int x0, int y0, char *text); + int DrawClear(); + int GetTextH(const char *s) {return 8;} + int GetTextW(const char *s) {return 8 * sizeof(s);} + void Quit(int q = 1) {quit = (q > 0) ? q : 0;} +}; + +unsigned long TDosGraphDraw::GetKeySym(unsigned int key) +{ + switch(key) + { + case 331: return XK_Left; + case 333: return XK_Right; + case 328: return XK_Up; + case 336: return XK_Down; + case 13: return XK_Return; + case 32: return XK_space; + case 27: return XK_Escape; + case 44: return XK_comma; + case 46: return XK_period; + case 60: return XK_comma; + case 62: return XK_period; + case 45: return XK_minus; + case 61: return XK_equal; + case 95: return XK_underscore; + case 43: return XK_plus; + case 339: return XK_Delete; + case 47: return XK_slash; + case 63: return XK_question; + case 315: return XK_F1; + case 316: return XK_F2; + case 317: return XK_F3; + case 318: return XK_F4; + case 319: return XK_F5; + case 320: return XK_F6; + case 321: return XK_F7; + case 322: return XK_F8; + case 323: return XK_F9; + case 324: return XK_F10; + case 389: return XK_F11; + case 390: return XK_F12; + case 97: return XK_a; + case 98: return XK_b; + case 99: return XK_c; + case 100: return XK_d; + case 101: return XK_e; + case 102: return XK_f; + case 103: return XK_g; + case 104: return XK_h; + case 105: return XK_i; + case 106: return XK_j; + case 107: return XK_k; + case 108: return XK_l; + case 109: return XK_m; + case 110: return XK_n; + case 111: return XK_o; + case 112: return XK_p; + case 113: return XK_q; + case 114: return XK_r; + case 115: return XK_s; + case 116: return XK_t; + case 117: return XK_u; + case 118: return XK_v; + case 119: return XK_w; + case 120: return XK_x; + case 121: return XK_y; + case 122: return XK_z; + case 65: return XK_A; + case 66: return XK_B; + case 67: return XK_C; + case 68: return XK_D; + case 69: return XK_E; + case 70: return XK_F; + case 71: return XK_G; + case 72: return XK_H; + case 73: return XK_I; + case 74: return XK_J; + case 75: return XK_K; + case 76: return XK_L; + case 77: return XK_M; + case 78: return XK_N; + case 79: return XK_O; + case 80: return XK_P; + case 81: return XK_Q; + case 82: return XK_R; + case 83: return XK_S; + case 84: return XK_T; + case 85: return XK_U; + case 86: return XK_V; + case 87: return XK_W; + case 88: return XK_X; + case 89: return XK_Y; + case 90: return XK_Z; + default: return XK_VoidSymbol; + } +} + +TDosGraphDraw::TDosGraphDraw(const char *s) : TGraphDraw(s) +{ + bgcolor = GetWhiteColor(); +} + +unsigned long TDosGraphDraw::CreateColor(unsigned short red, + unsigned short green, unsigned short blue) +{ + const unsigned short PD = 12288U, PM = 36863U, PL = 65535U; + const unsigned short COLOR[16][3] = + {{0U, 0U, 0U}, {0U, 0U, PM}, {0U, PM, 0U}, {0U, PM, PM}, + {PM, 0U, 0U}, {PM, 0U, PM}, {PM, PM, 0U}, {PM, PM, PM}, + {PD, PD, PD}, {PD, PD, PL}, {PD, PL, PD}, {PD, PL, PL}, + {PL, PD, PD}, {PL, PD, PL}, {PL, PL, PD}, {PL, PL, PL}}; + int b[3]; + if (red > green) + { + if (green > blue) {b[0] = 4; b[1] = 2; b[2] = 1;} + else if (red > blue) {b[0] = 4; b[1] = 1; b[2] = 2;} + else {b[0] = 1; b[1] = 4; b[2] = 2;} + } + else + { + if (red > blue) {b[0] = 2; b[1] = 4; b[2] = 1;} + else if (green > blue) {b[0] = 2; b[1] = 1; b[2] = 4;} + else {b[0] = 1; b[1] = 2; b[2] = 4;} + } + int i, j, c, c0 = 0; + long d, d0 = LONG_MAX; + for (j = 0; j <= 8; j += 8) for (i = 0, c = j; i <= 3; c |= b[i++]) + { + d = labs((long)red - COLOR[c][0]) + labs((long)green - COLOR[c][1]) + + labs((long)blue - COLOR[c][2]); + if (d0 >= d) {d0 = d; c0 = c;} + } + return c0; +} + +void TDosGraphDraw::GetSize(int &w, int &h) +{ + if (graphresult() == grOk) + { + w = getmaxx() + 1; h = getmaxy() + 1; + } + else TGraphDraw::GetSize(w, h); +} + +int TDosGraphDraw::OpenDraw() +{ + if (graphresult() == grOk) + { + cursor.Hide(); + return 1; + } + else return 0; +} + +int TDosGraphDraw::SetColor(unsigned long c) +{ + if (!IsDraw()) return 0; + else {setcolor((int)c); return 1;} +} + +int TDosGraphDraw::DrawLine(int x0, int y0, int x1, int y1) +{ + if (!IsDraw()) return 0; + else {line(x0, y0, x1, y1); return 1;} +} + +int TDosGraphDraw::DrawText(int x0, int y0, char *text) +{ + if (!IsDraw()) return 0; + else {outtextxy(x0, y0, text); return 1;} +} + +int TDosGraphDraw::DrawClear() +{ + if (!IsDraw()) return 0; + setbkcolor((int)bgcolor); setcolor((int)bgcolor); + bar(0, 0, getmaxx(), getmaxy()); + setbkcolor(0); + return 1; +} + +int TDosGraphDraw::Run(int evmask, int /*w*/, int /*h*/) +{ + if (!evfunc) return -2; + int wasgraph = graphresult(); + if (!wasgraph) + { + int gdriver = DETECT, gmode, errorcode; + initgraph(&gdriver, &gmode, ""); + if ((errorcode = graphresult()) != grOk) + { + printf("Graphics error: %s\n", grapherrormsg(errorcode)); + return -1; + } + } + event ev; + int ch = INT_MIN, stpr = 0; + int old_mx = -1000, old_my = -1000; + clock_t old_mtime = clock(); + int show_cur = TCursorVisible::C.IsShowed(); + freopen("NUL", "wt", stdout); + quit = 0; + while (quit == 0) + { + if (stpr == 0) + { + ev.type = event::start; + ev.any.drw = this; + evfunc(ev); + CloseDraw(); + stpr = 1; + } + else if (stpr == 1) + { + ev.type = event::draw; + ev.any.drw = this; + evfunc(ev); + CloseDraw(); + stpr = 2; + } + else if (ch >= 0 && (evmask & key_down_mask)) + { + ev.type = event::key_up; + ev.key.drw = this; + ev.key.k = ch; + evfunc(ev); + CloseDraw(); + ch = INT_MIN; + } + else if (kbhit()) + { + if (MouseStatus && TCursorVisible::C.IsShowed() && + (unsigned long)(clock() - old_mtime) > 5 * CLK_TCK) + { + TCursorVisible::C.Hide(); + old_mtime = clock(); + } + int ch = (unsigned char)getch(); + if (!ch && kbhit()) ch = 0x100 | (unsigned char)getch(); + if (evmask & key_down_mask) + { + ev.type = event::key_down; + ev.key.drw = this; + ev.key.k = GetKeySym(ch); + evfunc(ev); + CloseDraw(); + } + } + else if (MouseStatus && (evmask & (button_down_mask | + button_up_mask | mouse_move_mask | mouse_drag_mask))) + { + int k, x, y, z; + for (k = 0; k < MouseStatus; k++) + { + z = GetButtonDown(k, x, y); + if (z) + { + TCursorVisible::C.Show(); + old_mx = x; old_my = y; + old_mtime = clock(); + if (evmask & button_down_mask) + { + ev.type = event::button_down; + ev.button.drw = this; + ev.button.x = x; ev.button.y = y; + ev.button.n = k + 1; + evfunc(ev); + CloseDraw(); + } + old_mtime = clock(); + k = -1; break; + } + z = GetButtonUp(k, x, y); + if (z) + { + TCursorVisible::C.Show(); + old_mx = x; old_my = y; + old_mtime = clock(); + if (evmask & button_up_mask) + { + ev.type = event::button_up; + ev.button.drw = this; + ev.button.x = x; ev.button.y = y; + ev.button.n = k + 1; + evfunc(ev); + CloseDraw(); + } + k = -1; break; + } + } + if (k >= 0) + { + z = PosCursor(x, y); + if (x != old_mx || y != old_my) + { + TCursorVisible::C.Show(); + old_mx = x; old_my = y; + old_mtime = clock(); + if (evmask & (mouse_move_mask | mouse_drag_mask)) + { + for (k = 0; k < MouseStatus; k++) + { + if (z & (1 << k)) break; + } + if (evmask & ((k == MouseStatus) ? mouse_move_mask : mouse_drag_mask)) + { + ev.type = event::mouse_move; + ev.button.drw = this; + ev.button.x = x; ev.button.y = y; + ev.button.n = (k >= MouseStatus) ? 0 : (k + 1); + evfunc(ev); + CloseDraw(); + } + } + } + else if (TCursorVisible::C.IsShowed() && + (unsigned long)(clock() - old_mtime) > 30 * CLK_TCK) + { + TCursorVisible::C.Hide(); + old_mtime = clock(); + } + } + } + if (quit == 1) + { + ev.type = event::close; + ev.any.drw = this; + Quit(evfunc(ev)); + CloseDraw(); + } + } + TCursorVisible::C.Set(show_cur); + if (!wasgraph) closegraph(); + freopen("CON", "wt", stdout); + return quit; +} + +#endif //_DOS_GRAPHIC_DRAW_H diff --git a/programs/games/checkers/trunk/dosmouse.h b/programs/games/checkers/trunk/dosmouse.h new file mode 100644 index 0000000000..4627429e00 --- /dev/null +++ b/programs/games/checkers/trunk/dosmouse.h @@ -0,0 +1,172 @@ +#ifndef _INCLUDE_DOS_MOUSE +#define _INCLUDE_DOS_MOUSE + +#include + +inline int GetMouseStatus() +{ + int a, b; + _AX = 0; + geninterrupt(0x33); + a = _AX; b = _BX; + if (!a) return 0; + else return b; +} + +class TCursorVisible +{ +public: + TCursorVisible(int s = 1) : visible(1) {if (!s) Hide();} + ~TCursorVisible() {Show();} + + int IsShowed() const {return visible;} + int IsHidden() const {return !visible;} + int Show() + { + if (!visible) {_AX = 1; geninterrupt(0x33); visible = 1; return 1;} + else return 0; + } + int Hide() + { + if (visible) {_AX = 2; geninterrupt(0x33); visible = 0; return 1;} + else return 0; + } + int Set(int v) {return v ? Show() : Hide();} +private: + int visible; +public: + class T_C + { + public: + ~T_C() {Hide();} + + int IsShowed() const {return visible;} + int IsHidden() const {return !visible;} + int Show() + { + if (!visible) {_AX = 1; geninterrupt(0x33); visible = 1; return 1;} + else return 0; + } + int Hide() + { + if (visible) {_AX = 2; geninterrupt(0x33); visible = 0; return 1;} + else return 0; + } + int Set(int v) {return v ? Show() : Hide();} + private: + T_C() : visible(0) {} + friend class TCursorVisible; + + int visible; + }; + + static T_C C; +}; + +extern int MouseStatus; + +inline void SetShowCursor(int show) +{ + if (MouseStatus) + { + _AX = show ? 1 : 2; + geninterrupt(0x33); + } +} + +inline void ShowCursor() +{ + if (MouseStatus) + { + _AX = 1; + geninterrupt(0x33); + } +} + +inline void HideCursor() +{ + if (MouseStatus) + { + _AX = 2; + geninterrupt(0x33); + } +} + +inline int PosCursor(int &x, int &y) +{ + if (MouseStatus) + { + int xx, yy, r; + _AX = 3; + geninterrupt(0x33); + xx = _CX; yy = _DX; + r = _BX; + x = xx; y = yy; + return r; + } + else return 0; +} + +inline int SetPosCursor(int x, int y) +{ + if (MouseStatus) + { + _AX = 4; _CX = x; _DX = y; + geninterrupt(0x33); + return _BX; + } + else return 0; +} + +inline int GetButtonDown(int n, int &x, int &y) +{ + if (MouseStatus) + { + int xx, yy, r; + _AX = 5; _BX = n; + geninterrupt(0x33); + xx = _CX; yy = _DX; + r = _BX; + x = xx; y = yy; + return r; + } + else return 0; +} + +inline int GetButtonUp(int n, int &x, int &y) +{ + if (MouseStatus) + { + int xx, yy, r; + _AX = 6; _BX = n; + geninterrupt(0x33); + xx = _CX; yy = _DX; + r = _BX; + x = xx; y = yy; + return r; + } + else return 0; +} + +inline void BoundCursorX(int x1, int x2) +{ + if (MouseStatus) + { + _AX = 7; _CX = x1; _DX = x2; + geninterrupt(0x33); + } +} + +inline void BoundCursorY(int y1, int y2) +{ + if (MouseStatus) + { + _AX = 8; _CX = y1; _DX = y2; + geninterrupt(0x33); + } +} + +int MouseStatus = GetMouseStatus(); +TCursorVisible::T_C TCursorVisible::C; + +#endif //_INCLUDE_DOS_MOUSE diff --git a/programs/games/checkers/trunk/egavga.bgi b/programs/games/checkers/trunk/egavga.bgi new file mode 100644 index 0000000000..800163160d Binary files /dev/null and b/programs/games/checkers/trunk/egavga.bgi differ diff --git a/programs/games/checkers/trunk/gnu-draw.h b/programs/games/checkers/trunk/gnu-draw.h new file mode 100644 index 0000000000..5ef95207a9 --- /dev/null +++ b/programs/games/checkers/trunk/gnu-draw.h @@ -0,0 +1,295 @@ +#include "gr-draw.h" +#include +#include +#include +#include +#include + +#ifndef _GNU_GRAPHIC_DRAW_H +#define _GNU_GRAPHIC_DRAW_H + +class TGnuGraphDraw : public TGraphDraw +{ +public: + TGnuGraphDraw(const char *s = 0); + ~TGnuGraphDraw(); + + static unsigned long GetKeySym(unsigned int key) {return key;} + + unsigned long GetBlackColor(); + unsigned long GetWhiteColor(); + unsigned long CreateColor(unsigned short red, + unsigned short green, unsigned short blue); + void FreeColor(unsigned long c); + unsigned int GetBgColor() const {return bgcolor;} + void SetBgColor(unsigned long c) {bgcolor = c;} + + int GetStatus() {return disp ? (win ? 1 : 0) : (-1);} + int Init() {return disp ? 0 : -1;} + int Run(int evmask = 0, int w = INT_MIN, int h = INT_MIN); + + void GetSize(int &w, int &h); + int OpenDraw(); + int IsDraw() {return disp && win && prGC;} + void CloseDraw() {if (prGC) {XFreeGC(disp, prGC); prGC = 0;}} + + int SetColor(unsigned long c); + int DrawLine(int x0, int y0, int x1, int y1); + int DrawText(int x0, int y0, char *text); + int DrawClear(); + int GetTextH(const char *s) {return 10;} + int GetTextW(const char *s) {return 6 * strlen(s);} + void Quit(int q = 1) {quit = (q > 0) ? q : 0;} + void ResReinit(int w = INT_MIN, int h = INT_MIN); +protected: + void InitDisplay(); + void InitWindow(int w = INT_MIN, int h = INT_MIN); +protected: + int quit; + unsigned long bgcolor; + Display *disp; + Window win; + int ScrNum; + GC prGC; + Mask xmask; +}; + +TGnuGraphDraw::TGnuGraphDraw(const char *s /*= 0*/) : TGraphDraw(s), prGC(0) +{ + xmask = 0; + InitDisplay(); +} + +TGnuGraphDraw::~TGnuGraphDraw() +{ + CloseDraw(); + if (disp) XCloseDisplay(disp); +} + +void TGnuGraphDraw::InitDisplay() +{ + disp = XOpenDisplay(NULL); + if (disp) ScrNum = DefaultScreen(disp); + else + { + int L = 100; + if (title) L += strlen(title); + char *str = new char[L]; + if (str) + { + strcpy(str, "\n"); + if (title && title[0]) {strcat(str, title); strcat(str, ": ");} + strcat(str, "Can't connect to X Server.\n"); + printf("%s", str); + } + } + bgcolor = GetWhiteColor(); +} + +unsigned long TGnuGraphDraw::GetBlackColor() +{ + if (disp) return BlackPixel(disp, ScrNum); + else return TGraphDraw::GetBlackColor(); +} + +unsigned long TGnuGraphDraw::GetWhiteColor() +{ + if (disp) return WhitePixel(disp, ScrNum); + else return TGraphDraw::GetWhiteColor(); +} + +unsigned long TGnuGraphDraw::CreateColor(unsigned short red, + unsigned short green, unsigned short blue) +{ + if (disp) + { + XColor color; + color.red = red; color.green = green; color.blue = blue; + if (XAllocColor(disp, DefaultColormap(disp, ScrNum), &color)) + { + return color.pixel; + } + else return BlackPixel(disp, ScrNum); + } + else return TGraphDraw::CreateColor(red, green, blue); +} + +void TGnuGraphDraw::FreeColor(unsigned long c) +{ + if (disp && c != BlackPixel(disp, ScrNum)) + { + XFreeColors(disp, DefaultColormap(disp, ScrNum), &c, 1, 0); + } +} + +void TGnuGraphDraw::GetSize(int &w, int &h) +{ + if (disp) + { + int x, y; + Window w_ret; + unsigned int br, dr, width = 0, height = 0; + XGetGeometry(disp, win, &w_ret, &x, &y, &width, &height, &br, &dr); + w = width; h = height; + } + else TGraphDraw::GetSize(w, h); +} + +int TGnuGraphDraw::OpenDraw() +{ + if (!disp && !win) return 0; + if (!prGC) prGC = XCreateGC(disp, win, 0, NULL); + return 1; +} + +int TGnuGraphDraw::SetColor(unsigned long c) +{ + if (!disp || !prGC) return 0; + XSetForeground(disp, prGC, c); + return 1; +} + +int TGnuGraphDraw::DrawLine(int x0, int y0, int x1, int y1) +{ + if (!disp || !prGC) return 0; + XDrawLine(disp, win, prGC, x0, y0, x1, y1); + return 1; +} + +int TGnuGraphDraw::DrawText(int x0, int y0, char *text) +{ + if (!disp || !prGC) return 0; + XDrawString(disp, win, prGC, x0, y0 + GetTextH(text), text, strlen(text)); + return 1; +} + +int TGnuGraphDraw::DrawClear() +{ + if (!disp || !prGC) return 0; + XClearWindow(disp, win); + return 1; +} + +void TGnuGraphDraw::InitWindow(int w, int h) +{ + if (w <= 0 || h <= 0) TGraphDraw::GetSize(w, h); + win = XCreateSimpleWindow(disp, RootWindow(disp, ScrNum), + 100, 100, w, h, 2, BlackPixel(disp, ScrNum), GetBgColor()); + XSelectInput(disp, win, xmask); + XMapWindow(disp, win); +} + +void TGnuGraphDraw::ResReinit(int w, int h) +{ + if (disp) {free(disp); disp = 0;} + InitDisplay(); + if (!disp) exit(1); + else if (win) InitWindow(w, h); +} + +int TGnuGraphDraw::Run(int evmask, int w, int h) +{ + if (!disp) return -1; + if (!evfunc) return -2; + xmask = ExposureMask; + if (evmask & button_down_mask) xmask |= ButtonPressMask; + if (evmask & button_up_mask) xmask |= ButtonReleaseMask; + if (evmask & key_down_mask) xmask |= KeyPressMask; + if (evmask & key_up_mask) xmask |= KeyReleaseMask; + if (evmask & mouse_move_mask) xmask |= PointerMotionMask; + if (evmask & mouse_drag_mask) + { + xmask |= ButtonMotionMask | Button1MotionMask | Button2MotionMask | + Button3MotionMask | Button4MotionMask | Button5MotionMask; + } + InitWindow(w, h); + XEvent xevent; + KeySym sym; + char str[50]; + event ev; + int stpr = 0; + quit = 0; + while (quit == 0) + { + if (stpr == 0) + { + ev.type = event::start; + ev.any.drw = this; + evfunc(ev); + CloseDraw(); + stpr = 1; + } + else + { + XNextEvent(disp, &xevent); + switch(xevent.type) + { + case Expose: + if (xevent.xexpose.count != 0) break; + ev.type = event::draw; + ev.any.drw = this; + evfunc(ev); + CloseDraw(); + break; + case ButtonPress: + ev.type = event::button_down; + ev.button.drw = this; + ev.button.x = xevent.xbutton.x; + ev.button.y = xevent.xbutton.y; + ev.button.n = xevent.xbutton.button; + evfunc(ev); + CloseDraw(); + break; + case ButtonRelease: + ev.type = event::button_up; + ev.button.drw = this; + ev.button.x = xevent.xbutton.x; + ev.button.y = xevent.xbutton.y; + ev.button.n = xevent.xbutton.button; + evfunc(ev); + CloseDraw(); + break; + case MotionNotify: + ev.type = event::mouse_move; + ev.button.drw = this; + ev.button.x = xevent.xbutton.x; + ev.button.y = xevent.xbutton.y; + ev.button.n = xevent.xbutton.button; + evfunc(ev); + CloseDraw(); + break; + case KeyPress: + memset(str, 0, 20); + XLookupString(&xevent.xkey, str, 20, &sym, 0); + ev.type = event::key_down; + ev.key.drw = this; + ev.key.k = (unsigned long)sym; + evfunc(ev); + CloseDraw(); + break; + case KeyRelease: + memset(str, 0, 20); + XLookupString(&xevent.xkey, str, 20, &sym, 0); + ev.type = event::key_up; + ev.key.drw = this; + ev.key.k = (unsigned long)sym; + evfunc(ev); + CloseDraw(); + break; + } + } + if (quit == 1) + { + ev.type = event::close; + ev.any.drw = this; + Quit(evfunc(ev)); + CloseDraw(); + } + } + CloseDraw(); + XDestroyWindow(disp, win); + win = 0; + return quit; +} + +#endif //_GNU_GRAPHIC_DRAW_H diff --git a/programs/games/checkers/trunk/gr-draw.h b/programs/games/checkers/trunk/gr-draw.h new file mode 100644 index 0000000000..4d86003f94 --- /dev/null +++ b/programs/games/checkers/trunk/gr-draw.h @@ -0,0 +1,121 @@ +#ifndef _GRAPHIC_DRAW_H +#define _GRAPHIC_DRAW_H + +#ifndef __MENUET__ +#include +#include + +#ifdef _Windows +# include +#endif +#else +#define LONG_MIN (-2147483647L-1) /* minimum signed long value */ +#define INT_MIN LONG_MIN +#endif + +class TGraphDraw +{ +public: + union event + { + enum evtype {noevent = 0, draw, button_down, button_up, + mouse_move, key_down, key_up, start, close} type; + + struct evany + { + evtype type; + TGraphDraw *drw; + } any; + + struct evbutton : public evany + { + int x, y, n; + } button; + + struct evkey : public evany + { + unsigned long k; + } key; + }; + + enum {button_down_mask = 0x1, button_up_mask = 0x2, key_down_mask = 0x4, + key_up_mask = 0x8, mouse_move_mask = 0x10, mouse_drag_mask = 0x20}; + + enum {ret_setcapture = 0x10}; +public: + TGraphDraw(const char *s = 0) : title(0), about_info(0), + evfunc(0), id(0), data(0) {CopyTitle(s);} + ~TGraphDraw() {FreeTitle();} + + virtual unsigned long GetBlackColor() {return 0;} + virtual unsigned long GetWhiteColor() {return 0xFFFFFFL;} + virtual unsigned long CreateColor(unsigned short red, + unsigned short green, unsigned short blue); + virtual void FreeColor(unsigned long c) {} + virtual unsigned long GetBgColor() {return GetWhiteColor();} + virtual void SetBgColor(unsigned long c) {} + + virtual void SetTitle(const char *s) {CopyTitle(s);} + const char *GetTitle() const {return title;} + + virtual int GetStatus() {return 0;} //1 - can draw, 0 - can't draw, <0 - error + virtual int Init() {return 0;} + virtual void UnInit() {} + virtual int Run(int evmask = 0, int w = INT_MIN, int h = INT_MIN) {return -100;} + + virtual void GetSize(int &w, int &h) {w = 200; h = 200;} + virtual int OpenDraw() {return 0;} + virtual int IsDraw() {return 0;} + virtual void CloseDraw() {} + + virtual int SetColor(unsigned long c) {return 0;} + virtual int DrawLine(int x0, int y0, int x1, int y1) {return 0;} + virtual int DrawText(int x0, int y0, char *text) {return 0;} + virtual int DrawClear() {return 0;} + virtual int GetTextH(const char *s) {return 16;} + virtual int GetTextW(const char *s) {return 8 * strlen(s);} + virtual void Quit(int q = 1) {} + virtual void ResReinit(int w = INT_MIN, int h = INT_MIN) {} + virtual int GetAboutInfo() {return about_info;} + virtual void SetAboutInfo(int inf) {about_info = inf;} +protected: + void FreeTitle() {if (title) {delete[] title; title = 0;}} + void CopyTitle(const char *s); + char *title; + int about_info; +public: + int (*evfunc)(const event &ev); + int id; + void *data; +}; + +unsigned long TGraphDraw::CreateColor(unsigned short red, + unsigned short green, unsigned short blue) +{ + return (unsigned long)(red >> 8) + ((unsigned long)(green >> 8) << 8) + + ((unsigned long)(blue >> 8) << 16); +} + +void TGraphDraw::CopyTitle(const char *s) +{ + FreeTitle(); + if (s) {title = new char[strlen(s) + 1]; strcpy(title, s);} +} + +#if defined __GNUC__ +# include "gnu-draw.h" + typedef TGnuGraphDraw TMainGraphDraw; +#elif defined __MENUET__ +# include "mt-draw.h" + typedef TKlbrGraphDraw TMainGraphDraw; +#elif defined _Windows +# include "win-draw.h" + typedef TWinGraphDraw TMainGraphDraw; +#elif defined __MSDOS__ +# include "dos-draw.h" + typedef TDosGraphDraw TMainGraphDraw; +#else + typedef TGraphDraw TMainGraphDraw; +#endif + +#endif //_GRAPHIC_DRAW_H diff --git a/programs/games/checkers/trunk/hash.h b/programs/games/checkers/trunk/hash.h new file mode 100644 index 0000000000..376bd2319e --- /dev/null +++ b/programs/games/checkers/trunk/hash.h @@ -0,0 +1,185 @@ +#if !defined(HASH_TABLE_H) +#define HASH_TABLE_H + +template +class THashTable +{ +public: + THashTable(int _m = -1) {MemInit(_m);} + ~THashTable() {null();} + + int hash1(const TypeString &x) const {return func1(x);} + int hash2(const TypeString &x) const {return 2*func2(x) + 1;} + + void null(); + int IsNull() const {return M >= 0;} + int NumElem() const {return n;} + int MaxNumElem() const {return stack_size;} + int GetM() const {return M;} + int TableSize() const {return 1 << M;} + + void resize(int _m); + void push(const T &x); + T *find(const TypeString &x); + void pop(); + + T &last() {return stack[n-1];} + const T &last() const {return stack[n-1];} + T &first() {return stack[0];} + const T &first() const {return stack[0];} + T &operator[](int i) {return stack[i];} + const T &operator[](int i) const {return stack[i];} + T *operator()() {return stack;} + const T *operator()() const {return stack;} +protected: + void _push(const T &x); + int _find_pointer(const T *p) const; + int _find(const TypeString &x) const; + void MemInit(int _m); +protected: + int M; + int stack_size; + int n; + T **table; + T *stack; +protected: + HashFunction func1, func2; +}; + +template +void THashTable::null() +{ + if (table) delete[] table; + if (stack) delete[] stack; + M = -1; + table = 0; + stack = 0; + stack_size = 0; + n = 0; + func1.init(-1); + func2.init(-1); +} + +template +void THashTable::resize(int _m) +{ + delete[] table; + T *stp = stack; + int np = n; + MemInit(_m); + for (int i = 0; i < np && n < stack_size; i++) _push(stp[i]); + if (stp) delete[] stp; +} + +template +inline void THashTable::push(const T &x) +{ + if (n == stack_size) resize(M + 1); + _push(x); +} + +template +inline T *THashTable::find(const TypeString &x) +{ + int i = _find(x); + if (i >= 0) return table[i]; + else return 0; +} + +template +inline void THashTable::pop() +{ + if (n > 0) + { + n--; + int i = _find_pointer(stack + n); + if (i >= 0) table[i] = NULL; + } +} + +template +void THashTable::_push(const T &x) +{ + int h1 = hash1(x); + int h2 = hash2(x); + int i = h1; + stack[n] = x; + do + { + if (table[i] == NULL) + { + table[i] = stack + n; + break; + } + i = (i + h2) & ((1 << M) - 1); + } + while (i != h1); + n++; +} + +template +int THashTable::_find_pointer(const T *p) const +{ + if (n > 0) + { + int h1 = hash1(*p); + int h2 = hash2(*p); + int i = h1; + do + { + if (table[i] == NULL) break; + if (table[i] == p) return i; + i = (i + h2) & ((1 << M) - 1); + } + while (i != h1); + } + return -1; +} + +template +int THashTable::_find(const TypeString &x) const +{ + if (n > 0) + { + int h1 = hash1(x); + int h2 = hash2(x); + int i = h1; + do + { + if (table[i] == NULL) break; + if ((*table[i]) == x) return i; + i = (i + h2) & ((1 << M) - 1); + } + while (i != h1); + } + return -1; +} + +template +void THashTable::MemInit(int _m) +{ + M = _m; + if (M < 0) + { + M = -1; + stack_size = 0; + table = 0; + stack = 0; + n = 0; + func1.init(-1); + func2.init(-1); + } + else + { + if (M < 3) M = 3; + stack_size = (1 << M) / 3; + table = new T*[1 << M]; + for (int i = 0; i < (1 << M); i++) table[i] = NULL; + stack = new T[stack_size]; + n = 0; + func1.init(M); + func2.init(M-1); + } +} + +#endif // HASH_TABLE_H diff --git a/programs/games/checkers/trunk/history.h b/programs/games/checkers/trunk/history.h new file mode 100644 index 0000000000..5ba1f7199d --- /dev/null +++ b/programs/games/checkers/trunk/history.h @@ -0,0 +1,402 @@ +#ifndef _HEADER_HISTORY_H +#define _HEADER_HISTORY_H + +#ifndef __MENUET__ +#include +#include +#include +#include +#endif +#include "position.h" +#include "hash.h" +#include "sysproc.h" + +class THistory +{ +#ifndef __MENUET__ +public: + static char FileName[1024]; +#endif +public: + THistory(int id = 0) {if (id >= 0) Hid = NHid++; else Hid = id;} + + int GetId() const {return Hid;} + static int GetNId() {return NHid;} + + int Start(const Position &pos) const; + int Move(const Position &pos, const unsigned char mv[], int nmove) const; + int Play(const PlayWrite &play) const; + +#ifndef __MENUET__ + static int InitHFile(char *dname = 0); + static int HRead(FILE *f, PlayWrite *&play); +protected: + int Print(const char *str) const; +#endif + + int Hid; + + static int NHid; +protected: + struct TStr + { + TStr(const char *ss = 0) : s(0) {(*this) = ss;} + TStr(const TStr &ss) : s(0) {(*this) = ss.s;} + ~TStr() {(*this) = 0;} + + TStr &operator=(const char *ss); + TStr &operator=(const TStr &ss) {return (*this) = ss.s;} + + operator char*() {return s;} + operator const char*() const {return s;} + char &operator*() {return *s;} + const char &operator*() const {return *s;} + char &operator[](int i) {return s[i];} + const char &operator[](int i) const {return s[i];} + void Extend(int n); + + friend int operator==(const TStr &s1, const TStr &s2) + {return strcmp(s1, s2) == 0;} + friend int operator==(const char *s1, const TStr &s2) + {return strcmp(s1, s2) == 0;} + friend int operator==(const TStr &s1, const char *s2) + {return strcmp(s1, s2) == 0;} + friend int operator!=(const TStr &s1, const TStr &s2) + {return strcmp(s1, s2) != 0;} + friend int operator!=(const char *s1, const TStr &s2) + {return strcmp(s1, s2) != 0;} + friend int operator!=(const TStr &s1, const char *s2) + {return strcmp(s1, s2) != 0;} + friend int operator>=(const TStr &s1, const TStr &s2) + {return strcmp(s1, s2) >= 0;} + friend int operator>=(const char *s1, const TStr &s2) + {return strcmp(s1, s2) >= 0;} + friend int operator>=(const TStr &s1, const char *s2) + {return strcmp(s1, s2) >= 0;} + friend int operator<=(const TStr &s1, const TStr &s2) + {return strcmp(s1, s2) <= 0;} + friend int operator<=(const char *s1, const TStr &s2) + {return strcmp(s1, s2) <= 0;} + friend int operator<=(const TStr &s1, const char *s2) + {return strcmp(s1, s2) <= 0;} + friend int operator>(const TStr &s1, const TStr &s2) + {return strcmp(s1, s2) > 0;} + friend int operator>(const char *s1, const TStr &s2) + {return strcmp(s1, s2) > 0;} + friend int operator>(const TStr &s1, const char *s2) + {return strcmp(s1, s2) > 0;} + friend int operator<(const TStr &s1, const TStr &s2) + {return strcmp(s1, s2) < 0;} + friend int operator<(const char *s1, const TStr &s2) + {return strcmp(s1, s2) < 0;} + friend int operator<(const TStr &s1, const char *s2) + {return strcmp(s1, s2) < 0;} + + char *s; + }; + + class THash + { + public: + void init(int _m); + int operator()(const TStr &str) const; + protected: + int m; + int K[16]; + }; + + struct TTableItem + { + TTableItem(const char *s = 0, int k = 0) : str(s), k(k) {} + TTableItem(const TStr &s, int k = 0) : str(s), k(k) {} + TTableItem(const TTableItem &t) : str(t.str), k(t.k) {} + + operator TStr&() {return str;} + operator const TStr&() const {return str;} + + TStr str; + int k; + }; +}; + +#ifndef __MENUET__ +char THistory::FileName[1024] = "history.che"; +#endif +int THistory::NHid = 0; + +#ifndef __MENUET__ +int THistory::Print(const char *str) const +{ + char *line = new char[30 + strlen(str)]; + if (!line) return 0; + unsigned long pr_id = GetProcessId(); + if (Hid == -1) sprintf(line, "%lu %s\n", pr_id, str); + else if (Hid < 0) sprintf(line, "%lu%c %s\n", pr_id, (char)Hid, str); + else sprintf(line, "%lu:%d %s\n", pr_id, Hid, str); + FILE *f = fopen(FileName, "at"); + if (!f) + { + clock_t cc = clock(); + do {f = fopen(FileName, "at");} + while(!f && (clock() - cc) <= 0.05 * CLOCKS_PER_SEC); + } + if (!f) {delete[] line; return 0;} + fputs(line, f); + fclose(f); + delete[] line; + return 1; +} +#endif + +int THistory::Start(const Position &pos) const +{ + char str[20 + NUM_CELL] = "Start "; + if (!pos.Write(str + strlen(str), 1)) return 0; +#ifndef __MENUET__ + if (!Print(str)) return 0; +#endif + return 1; +} + +int THistory::Move(const Position &pos, const unsigned char mv[], int nmove) const +{ + char *str = new char[15 + pos.GetLenMvEx(mv, 11)]; + if (!str) return 0; + sprintf(str, "%d.%s ", (nmove + 1) / 2, (nmove % 2 == 0) ? ".." : ""); + pos.WriteMvEx(mv, str + strlen(str), 11); +#ifndef __MENUET__ + if (!Print(str)) {delete[] str; return 0;} +#endif + delete[] str; + return 1; +} + +int THistory::Play(const PlayWrite &play) const +{ + if (play.GetN() <= 0) return 0; + Position pos; + if (play.GetPos(pos, 0) < 0) return 0; + if (!Start(pos)) return 0; + int i; + unsigned char mv[NUM_CELL]; + for (i = 1; i < play.GetN(); i++) + { + if (play.GetPos(pos, i - 1) < 0) return 0; + if (play.GetMove(mv, i) < 0) return 0; + if (!Move(pos, mv, i)) return 0; + } + return 1; +} + +#ifndef __MENUET__ +int THistory::InitHFile(char *dname) +{ + if (dname && dname[0]) + { + char fnm[1024]; + strcpy(fnm, dname); + int i; + for (i = strlen(fnm) - 1; i >= 0; i--) + { + if (fnm[i] == DIR_SEPARATOR) break; + } + if (i >= 0) + { + strcpy(fnm + i + 1, FileName); + strcpy(FileName, fnm); + } + } + int e = 1; + FILE *f = fopen(FileName, "rt"); + if (f) {e = feof(f); fclose(f);} + if (!e) return 0; + f = fopen(FileName, "wt"); + if (!f) return -1; + fputs("checkers-history_1.1\n", f); + fclose(f); + return 1; +} +#endif + +THistory::TStr &THistory::TStr::operator=(const char *ss) +{ + if (s) delete[] s; + if (ss) + { + s = new char[strlen(ss) + 1]; + strcpy(s, ss); + } + else s = 0; + return *this; +} + +void THistory::TStr::Extend(int n) +{ + if (n <= 0) {(*this) = 0; return;} + char *ss = s; + s = new char[n+1]; + if (ss) + { + strncpy(s, ss, n); + s[n] = 0; + delete[] ss; + } + else s[0] = 0; +} + +void THistory::THash::init(int _m) +{ + m = _m; + for (int i = 0; i < 16; i++) + { + K[i] = (2*random(32767) + 1) & ((1 << m) - 1); + } +} + +int THistory::THash::operator()(const TStr &str) const +{ + int i, r = 0; + const char *s = str; + for (i = 0; *s; i = (i+1) & 15) r += *(s++) * K[i]; + r &= (1 << m) - 1; + return r; +} + +#ifndef __MENUET__ +int THistory::HRead(FILE *f, PlayWrite *&play) +{ + const int MAX_INP_WORD = 100; + int nplay = 0, mplay = 10; + play = new PlayWrite[mplay]; + THashTable table; + TStr word; + char inp_word[MAX_INP_WORD + 1]; + int r, maxword = 0; + unsigned char ch; + int i, k = 0, kind = 0, wasspace = 1, nmove = 0; + for (;;) + { + r = (fread(&ch, 1, 1, f) == 1); + if (!r || isspace(ch)) + { + if (!wasspace) + { + if (kind == 0) kind = 1; + else if (kind == 2) + { + for (i = 0; inp_word[i]; i++) + { + inp_word[i] = (char)tolower((unsigned char)inp_word[i]); + } + if (strcmp(inp_word, "start") == 0) kind = 5; + else kind = -1; + inp_word[0] = 0; k = 0; + } + else if (kind == 3) + { + nmove *= 2; + if (k <= 1) nmove--; + inp_word[0] = 0; + k = 0; kind = 4; + } + else if (kind == 4) + { + TTableItem *n_pl = table.find(word); + if (!n_pl) kind = -1; + else if (nmove < 1 || nmove > play[n_pl->k].GetN()) kind = -1; + else + { + PlayWrite::PMv pmv; + if (play[n_pl->k].GetPos(pmv.pos, nmove - 1) < 0) kind = -1; + else if (!pmv.pos.ReadMv(pmv.mv, inp_word, 1)) kind = -1; + else + { + play[n_pl->k].ClearFrom(nmove); + if (play[n_pl->k].Add(pmv.mv) != 0) kind = -1; + else {k = n_pl->k; kind = 11;} + } + } + } + else if (kind == 5) + { + Position pos; + pos.Read(inp_word, 1); + if (pos.IsNull()) kind = -1; + else + { + TTableItem *n_pl = table.find(word); + if (!n_pl) + { + table.push(TTableItem(word, nplay)); + n_pl = table.find(word); + } + if (!n_pl) kind = -1; + else + { + if (nplay >= mplay) + { + PlayWrite *play0 = play; + int mplay0 = mplay; + mplay = 2*nplay + 3; + play = new PlayWrite[mplay]; + if (play0) + { + for (i = 0; i < mplay0; i++) play[i] = play0[i]; + delete[] play0; + } + } + n_pl->k = nplay++; + play[n_pl->k].Add(0, pos); + k = n_pl->k; kind = 12; + } + } + } + } + if (!r || ch == '\n' || ch == '\r') + { + k = 0; + kind = 0; + if (!r) break; + } + wasspace = 1; + } + else + { + if (kind == 0) + { + if (k >= maxword) word.Extend(2*k + 3); + word[k++] = ch; + word[k] = 0; + } + else if (kind == 1) + { + if (isdigit(ch)) {nmove = ch - '0'; k = 0; kind = 3;} + else + { + inp_word[0] = ch; + inp_word[1] = 0; + k = 1; kind = 2; + } + } + else if (kind == 2 || kind == 4 || kind == 5) + { + if (k < MAX_INP_WORD) + { + inp_word[k++] = ch; + inp_word[k] = 0; + } + } + else if (kind == 3) + { + if (k == 0 && isdigit(ch)) nmove = 10 * nmove + ch - '0'; + else if (ch == '.') k++; + else kind = -1; + } + wasspace = 0; + } + } + return nplay; +} +#endif + +#endif //_HEADER_HISTORY_H diff --git a/programs/games/checkers/trunk/include/me_func.inc b/programs/games/checkers/trunk/include/me_func.inc new file mode 100644 index 0000000000..f0fab935ce --- /dev/null +++ b/programs/games/checkers/trunk/include/me_func.inc @@ -0,0 +1,1135 @@ +;const int +MENUET_BORDER_SIZE = 4; +;const int +MENUET_HEADER_SIZE = 20; + +;const int +MENUET_THREAD_DATA_USER = 0; // Thread data begin from the user dword +;const int +MENUET_THREAD_DATA_ST_BEGIN = 1; // Stack beginning follows after the user dword +;const int +MENUET_THREAD_DATA_NEXT = 2; +;const int +MENUET_THREAD_DATA_PID = 3; +;const int +MENUET_THREAD_DATA_FLAG = 4; +;const int +MENUET_THREAD_DATA_X = 5; +;const int +MENUET_THREAD_DATA_Y = 6; +;const int +MENUET_THREAD_DATA_C_WINDOW = 7; +;const int +MENUET_THREAD_DATA_C_HEADER = 8; +;const int +MENUET_THREAD_DATA_C_BORDER = 9; +;const int +MENUET_THREAD_DATA_C_TITLE = 10; +;const int +MENUET_THREAD_DATA_TITLE = 11; +;const int +MENUET_THREAD_DATA_PICTURE = 12; +;const int +MENUET_THREAD_DATA_SZ_PICT = 13; +;const int +MENUET_THREAD_DATA_LAST_SX = 14; +;const int +MENUET_THREAD_DATA_LAST_SY = 15; +;const int +MENUET_THREAD_DATA_LEN = 16; + +;const int +MENUET_MUTEX_MAX_TIME_WAIT = 20; + +;const int +MENUET_FILE_BLOCK_SIZE = 512; + +;const int +MENUET_FILE_MEMORY_OS_NEED = 4096; + +;/*** + +macro segment name +{ + segment name + if name eq _init_ | name eq _INIT_ +Menuet_SegmentInit: + else if name eq _exit_ | name eq _EXIT_ +Menuet_SegmentExit: + end if +} + +macro endseg name +{ + if name eq _init_ | name eq _INIT_ +Menuet_SegmentInitEnd: + else if name eq _exit_ | name eq _EXIT_ +Menuet_SegmentExitEnd: + end if + endseg name +} + +macro Menuet_Put_MovEaxVal_Ret address,val +{ + mov byte [address],0xB8 + mov dword [address+4],0xC089C300 + mov dword [address+1],val +} + +define @Menuet@Main$qv +nextdef MenuetEntryPoint + and esp,not 3 + sub esp,1024 + mov eax,9 + mov ebx,esp + mov ecx,-1 + int 0x40 + mov ebx,[esp+26] + mov edx,[esp+30] + lea eax,[ebx-0x20] + add esp,1024 + cmp esp,eax + cmova esp,eax + and esp,not 3 + xor eax,eax + cld + mov edi,@Menuet@_ThreadTable + mov ecx,256 + rep stos dword [edi] + mov esi,@Menuet@GetPid$qv + mov edi,@Menuet@_ThreadSavedBegProc + movs dword [edi],[esi] + movs dword [edi],[esi] + mov esi,@Menuet@GetThreadData$qv + movs dword [edi],[esi] + movs dword [edi],[esi] + Menuet_Put_MovEaxVal_Ret @Menuet@GetPid$qv,edx +if defined MenuetHeapInit + mov ecx,esp + push ebx + push ecx + push U_END + call MenuetHeapInit ; Initialize a dynamic heap and create new memory in its begin. + pop ecx ; Parameters: begin of a new heap, end of data to create in + mov [esp+4],eax ; the begin of a heap. Return address of the created data. + mov dword [esp],0 +else + xor eax,eax + push eax + push eax +end if + call @Menuet@ThreadMain$qpvt1 +nextdef Menuet_ThreadFinish + add esp,8 +if defined MenuetHeapFreeAndThreadFinish + test eax,eax + jz Menuet_ThreadFinish_end + push dword @Menuet@_ExitProcessNow + push eax + call MenuetHeapFreeAndThreadFinish ; Free the given memory and finish the thread, +end if ; should exit process if second argument points to not zero. +Menuet_ThreadFinish_end: + or eax,-1 + int 0x40 +enddef + +define @Menuet@ThreadMain$qpvt1 + xchg ebx,[esp+4] + xchg ebp,[esp+8] + push esi + push edi + sub esp,MENUET_THREAD_DATA_LEN*4 + mov [esp],ebx + mov [esp+4],ebp + mov eax,40 + mov ebx,0x27 + int 0x40 + mov ebx,esp + cmp byte [@Menuet@_ThreadSavedBegProc],0x90 + jz Menuet_main_else_first_check + Menuet_Put_MovEaxVal_Ret @Menuet@GetThreadData$qv,esp +if defined Menuet_SegmentInit & defined Menuet_SegmentInitEnd + push Menuet_SegmentInitEnd + push Menuet_SegmentInit + jmp Menuet_main_after_first_check +end if +Menuet_main_else_first_check: + xor eax,eax + push eax + push eax +Menuet_main_after_first_check: + push ebx + call @@Menuet@_CallStart$qppvpvt2 + add esp,12 + test al,al + jnz Menuet_main_test_close_first + jmp Menuet_main_end +Menuet_main_close_first: + btr dword [esp+MENUET_THREAD_DATA_FLAG*4],31 + push esp + call @@MenuetOnClose$qppv + pop ecx + test al,al + jnz Menuet_main_end +Menuet_main_test_close_first: + cmp dword [esp+MENUET_THREAD_DATA_FLAG*4],0 + jl Menuet_main_close_first +; push esp +; push dword 1 +; call @Menuet@Redraw$qippv +; add esp,8 +Menuet_main_paint_msg: + or dword [esp+MENUET_THREAD_DATA_FLAG*4],3 + sub esp,1024 + mov eax,9 + mov ebx,esp + mov ecx,-1 + int 0x40 + mov eax,[esp+34] + mov ebx,[esp+38] + mov ecx,[esp+42] + mov edx,[esp+46] + add esp,1024 + cmp ecx,[esp+MENUET_THREAD_DATA_LAST_SX*4] + jnz Menuet_main_size + cmp edx,[esp+MENUET_THREAD_DATA_LAST_SY*4] + jz Menuet_main_paint +Menuet_main_size: + mov [esp+MENUET_THREAD_DATA_LAST_SX*4],ecx + mov [esp+MENUET_THREAD_DATA_LAST_SY*4],edx + push edx + push ecx + push ebx + push eax + lea ecx,[esp+16] + mov edx,esp + push ecx + push edx + call @@MenuetOnSize$qpippv + add esp,24 + test dword [esp+MENUET_THREAD_DATA_FLAG*4],3 + jz Menuet_main_cycle +Menuet_main_paint: + cmp dword [esp+MENUET_THREAD_DATA_FLAG*4],0 + jl Menuet_main_close + push esp + push dword 0 + call @Menuet@Redraw$qippv + add esp,8 +Menuet_main_cycle: + mov eax,11 +Menuet_main_message: + cmp dword [esp+MENUET_THREAD_DATA_FLAG*4],0 + jl Menuet_main_close + int 0x40 + test eax,eax + jnz Menuet_main_on_message + cmp dword [esp+MENUET_THREAD_DATA_FLAG*4],0 + jne Menuet_main_paint + push esp + call @@MenuetOnIdle$qppv + pop ecx + test eax,eax + jz Menuet_main_cycle + jl Menuet_main_wait_message + mov ebx,eax + mov eax,23 + jmp Menuet_main_message +Menuet_main_wait_message: + mov eax,10 + jmp Menuet_main_message +Menuet_main_key_press: + push esp + call @@MenuetOnKeyPress$qppv + pop ecx + jmp Menuet_main_cycle +Menuet_main_mouse: + push esp + call @@MenuetOnMouse$qppv + pop ecx + jmp Menuet_main_cycle +Menuet_main_on_message: + dec eax + jz Menuet_main_paint_msg + dec eax + jz Menuet_main_key_press + cmp eax,4 + jz Menuet_main_mouse + dec eax + jnz Menuet_main_cycle +Menuet_main_button: + mov eax,17 + int 0x40 + test al,al + jnz Menuet_main_cycle +Menuet_main_close: + btr dword [esp+MENUET_THREAD_DATA_FLAG*4],31 + push esp + call @@MenuetOnClose$qppv + pop ecx + test al,al + jz Menuet_main_button +Menuet_main_end: + mov ebx,esp + lock dec dword [@Menuet@_ThreadNumber] +if defined Menuet_SegmentExit & defined Menuet_SegmentExitEnd + jnz Menuet_main_else_last_check + push Menuet_SegmentExitEnd + push Menuet_SegmentExit + jmp Menuet_main_after_last_check +end if +Menuet_main_else_last_check: + xor eax,eax + push eax + push eax +Menuet_main_after_last_check: + push ebx + call @@Menuet@_RemoveThreadData$qppvpvt2 + add esp,12 + lock inc dword [@Menuet@_ThreadScanCount+4] + mov ebx,1 + jmp Menuet_main_end_wait +Menuet_main_end_wait_loop: + mov eax,5 + int 0x40 + shl ebx,1 + cmp ebx,MENUET_MUTEX_MAX_TIME_WAIT + jna Menuet_main_end_wait + mov ebx,MENUET_MUTEX_MAX_TIME_WAIT +Menuet_main_end_wait: + cmp dword [@Menuet@_ExitProcessNow],0 + jnz @Menuet@ExitProcess$qv + cmp dword [@Menuet@_ThreadScanCount],0 + jnz Menuet_main_end_wait_loop + lock dec dword [@Menuet@_ThreadScanCount+4] + mov ebp,[esp+4] + mov ebx,[esp] + add esp,MENUET_THREAD_DATA_LEN*4 + mov eax,ebp + pop edi + pop esi + xchg ebp,[esp+8] + xchg ebx,[esp+4] + ret +enddef + +macro call func +{ + if func eq __chkstk + sub esp,eax + else + call func + end if +} + +define @Menuet@Redraw$qippv + push ebp + mov ebp,[esp+12] + mov edx,[ebp+MENUET_THREAD_DATA_FLAG*4] + cmp dword [esp+8],0 + jl Menuet_redraw_only_inv + jz Menuet_redraw_no_frame + or dl,2 +Menuet_redraw_no_frame: + bt edx,30 + jnc Menuet_redraw_begin + or dl,1 + mov [ebp+MENUET_THREAD_DATA_FLAG*4],edx + jmp Menuet_redraw_end +Menuet_redraw_only_inv: + test dl,3 + jnz Menuet_redraw_no_frame +Menuet_redraw_end: + pop ebp + ret +Menuet_redraw_begin: + push ebx + push esi + push edi + and dword [ebp+MENUET_THREAD_DATA_FLAG*4],0xFFFFFFFC + mov eax,12 + mov ebx,1 + int 0x40 + test dl,2 + jz Menuet_redraw_picture + push 48 + pop eax + push 4 + pop ebx + int 0x40 + mov ebx,[ebp+MENUET_THREAD_DATA_X*4] + add ebx,2*5-1 + mov ecx,[ebp+MENUET_THREAD_DATA_Y*4] + add cx,ax + add ecx,5-1 + mov edx,[ebp+MENUET_THREAD_DATA_C_WINDOW*4] +; mov esi,[ebp+MENUET_THREAD_DATA_C_HEADER*4] +; mov edi,[ebp+MENUET_THREAD_DATA_C_BORDER*4] + mov edi,[ebp+MENUET_THREAD_DATA_TITLE*4] + xor eax,eax + int 0x40 +; mov edx,[ebp+MENUET_THREAD_DATA_TITLE*4] +; test edx,edx +; jz Menuet_redraw_picture +; mov edi,edx +; mov ecx,0xFFFFFFFF +; xor al,al +; cld +; repnz scas byte [edi] +; not ecx +; mov esi,ecx +; dec esi +; jz Menuet_redraw_picture +; mov eax,4 +; mov ebx,0x00070007 +; mov ecx,[ebp+MENUET_THREAD_DATA_C_TITLE*4] +; int 0x40 +Menuet_redraw_picture: +; mov esi,[ebp+MENUET_THREAD_DATA_PICTURE*4] +; test esi,esi +; jz Menuet_redraw_end_draw +; mov ecx,[ebp+MENUET_THREAD_DATA_SZ_PICT*4] +; jecxz Menuet_redraw_end_draw +; mov al,byte [ebp+MENUET_THREAD_DATA_C_WINDOW*4+3] +; and al,15 +; mov edx,MENUET_BORDER_SIZE*65536+MENUET_HEADER_SIZE +; cmp al,3 +; jnz Menuet_redraw_no_skin +; mov eax,48 +; mov ebx,4 +; int 0x40 +; mov dx,ax +;Menuet_redraw_no_skin: +; mov eax,7 +; mov ebx,esi +; int 0x40 + call @@MenuetOnDraw$qv +Menuet_redraw_end_draw: + mov eax,12 + mov ebx,2 + int 0x40 + pop edi + pop esi + pop ebx + pop ebp + ret +enddef + +define @Menuet@MoveWindow$qxpxi + push ebx + push esi + mov eax,[esp+12] + mov ebx,[eax] + mov ecx,[eax+4] + mov edx,[eax+8] + mov esi,[eax+12] + mov eax,67 + int 0x40 + pop esi + pop ebx + ret +enddef + +define @Menuet@Abort$qv + push dword [@Menuet@DebugPrefix] + call @Menuet@DebugPutString$qpxc + mov dword [esp],Menuet_abort_string + call @Menuet@DebugPutString$qpxc + pop ecx +nextdef @Menuet@ExitProcess$qv + lock bts dword [@Menuet@_ExitProcessNow],0 + jc Menuet_exit_process_wait + sub esp,1024 + mov eax,9 + mov ebx,esp + mov ecx,-1 + int 0x40 + mov esi,eax + mov edi,[esp+30] +Menuet_exit_process_loop: + mov eax,9 + mov ebx,esp + mov ecx,esi + int 0x40 + mov eax,[esp+30] + cmp eax,edi + jz Menuet_exit_process_continue + mov ebx,eax + or bl,15 + inc ebx + jz Menuet_exit_process_continue + mov ebx,eax + call Menuet_HashInt + movzx eax,al + mov eax,dword [@Menuet@_ThreadTable+eax*4] + jmp Menuet_exit_process_test +Menuet_exit_process_next: + mov eax,dword [eax+MENUET_THREAD_DATA_NEXT*4] +Menuet_exit_process_test: + test eax,eax + jz Menuet_exit_process_continue + cmp ebx,[eax+MENUET_THREAD_DATA_PID*4] + jnz Menuet_exit_process_next + mov eax,18 + mov ebx,2 + mov ecx,esi + int 0x40 +Menuet_exit_process_continue: + dec esi + jnl Menuet_exit_process_loop + add esp,1024 + mov dword [@Menuet@_ExitProcessNow],-1 +if defined EMULATOR + int3 + call 0x76543210 +end if +Menuet_exit_process_end: + mov dword [@Menuet@_ThreadMutex],0 + or eax,-1 + int 0x40 +Menuet_exit_process_wait: + mov eax,5 + mov ebx,1 +Menuet_exit_process_wait_loop: + cmp dword [@Menuet@_ExitProcessNow],0 + jl Menuet_exit_process_end + int 0x40 + shl ebx,1 + cmp ebx,MENUET_MUTEX_MAX_TIME_WAIT + jna Menuet_exit_process_wait_loop + mov ebx,MENUET_MUTEX_MAX_TIME_WAIT + jmp Menuet_exit_process_wait_loop +enddef + +define @Menuet@ExitThread$qppv,@Menuet@ThreadMain$qpvt1 + mov esp,[esp+4] + jmp Menuet_main_end +enddef + +define @Menuet@ReturnMessageLoop$qppv,@Menuet@ThreadMain$qpvt1 + mov esp,[esp+4] + bt dword [esp+MENUET_THREAD_DATA_FLAG*4],30 + jc Menuet_main_end + jmp Menuet_main_cycle +enddef + +define @Menuet@Delay$qui + push ebx + mov eax,5 + mov ebx,[esp+8] + int 0x40 + pop ebx + ret +enddef + +define @Menuet@Clock$qv + push ebx + mov eax,26 + mov ebx,9 + int 0x40 + pop ebx + ret +enddef + +define @Menuet@GetPackedTime$qv + mov eax,3 + int 0x40 + ret +enddef + +define @Menuet@GetTime$qpi + mov eax,3 + int 0x40 + mov edx,[esp+4] + movzx ecx,al + shr ecx,4 + and al,0x0F + imul ecx,10 + add cl,al + mov dword [edx+8],ecx + mov cl,ah + shr ecx,4 + and ah,0x0F + imul ecx,10 + add cl,ah + mov dword [edx+4],ecx + bswap eax + mov cl,ah + shr ecx,4 + and ah,0x0F + imul ecx,10 + add cl,ah + mov dword [edx],ecx + ret +enddef + +define @Menuet@GetPackedDate$qv + mov eax,29 + int 0x40 + ret +enddef + +define @Menuet@GetDate$qpi + mov eax,29 + int 0x40 + mov edx,[esp+4] + movzx ecx,al + shr ecx,4 + and al,0x0F + imul ecx,10 + add cl,al + mov dword [edx+4],ecx + mov cl,ah + shr ecx,4 + and ah,0x0F + imul ecx,10 + add cl,ah + mov dword [edx],ecx + bswap eax + mov cl,ah + shr ecx,4 + and ah,0x0F + imul ecx,10 + add cl,ah + mov dword [edx+8],ecx + ret +enddef + +define @Menuet@ReadCommonColors$qpui + push ebx + mov eax,48 + mov ebx,3 + mov ecx,[esp+8] + mov edx,40 + int 0x40 + pop ebx + ret +enddef + +define @Menuet@GetProcessInfo$qpuipct1t1piui + push ebx + push esi + push edi + sub esp,1024 + mov eax,9 + mov ebx,esp + mov ecx,[1024+12+24+esp] + int 0x40 + xor edi,edi + or edi,[1024+12+4+esp] + jz Menuet_get_proc_info_no_usecpu + mov ecx,[esp] + mov [edi],ecx + xor edi,edi +Menuet_get_proc_info_no_usecpu: + or edi,[1024+12+8+esp] + jz Menuet_get_proc_info_no_name + lea esi,[esp+10] + cld + movs dword [edi],[esi] + movs dword [edi],[esi] + movs dword [edi],[esi] + mov byte [edi],0 + xor edi,edi +Menuet_get_proc_info_no_name: + or edi,[1024+12+12+esp] + jz Menuet_get_proc_info_no_mem + mov ecx,[esp+26] + mov [edi],ecx + xor edi,edi +Menuet_get_proc_info_no_mem: + or edi,[1024+12+16+esp] + jz Menuet_get_proc_info_no_pid + mov ecx,[esp+30] + mov [edi],ecx + xor edi,edi +Menuet_get_proc_info_no_pid: + or edi,[1024+12+20+esp] + jz Menuet_get_proc_info_no_rect + lea esi,[esp+34] + cld + movs dword [edi],[esi] + movs dword [edi],[esi] + movs dword [edi],[esi] + movs dword [edi],[esi] + xor edi,edi +Menuet_get_proc_info_no_rect: + add esp,1024 + pop edi + pop esi + pop ebx + ret +enddef + +define @Menuet@GetPid$qv + push ebx + sub esp,1024 + mov eax,9 + mov ebx,esp + mov ecx,-1 + int 0x40 + mov eax,[esp+30] + add esp,1024 + pop ebx + ret +enddef + +define @Menuet@GetPid$qppv + mov ecx,[esp+4] + mov eax,[ecx+MENUET_THREAD_DATA_PID*4] + ret +enddef + +define @Menuet@_HashByte$qui +nextdef @Menuet@_HashWord$qui +nextdef @Menuet@_HashDword$qui + mov eax,[esp+4] +nextdef Menuet_HashInt + mul dword [Menuet_hash_int_val0] + xor eax,edx + bswap eax + mul dword [Menuet_hash_int_val1] + shrd eax,edx,14 + bswap eax + lea eax,[eax+4*eax] + ror eax,9 + ret +Menuet_hash_int_val0: + dd 0xA82F94C5 +Menuet_hash_int_val1: + dd 0x9193780B +enddef + +define @Menuet@GetThreadData$qv + call @Menuet@GetPid$qv + push eax + call @Menuet@GetThreadData$qui + pop ecx + ret +enddef + +define @Menuet@GetThreadData$qui + mov eax,[esp+4] + call Menuet_HashInt + movzx eax,al + cmp dword [@Menuet@_ThreadScanCount+4],0 + jnz Menuet_get_thread_data_wait +Menuet_get_thread_data_nowait: + lock inc dword [@Menuet@_ThreadScanCount] + mov eax,dword [@Menuet@_ThreadTable+eax*4] + mov ecx,[esp+4] + jmp Menuet_get_thread_data_test +Menuet_get_thread_data_loop: + mov eax,dword [eax+MENUET_THREAD_DATA_NEXT*4] +Menuet_get_thread_data_test: + test eax,eax + jz Menuet_get_thread_data_end + cmp ecx,[eax+MENUET_THREAD_DATA_PID*4] + jnz Menuet_get_thread_data_loop +Menuet_get_thread_data_end: + lock dec dword [@Menuet@_ThreadScanCount] + ret +Menuet_get_thread_data_wait: + push eax + push ebx + mov eax,5 + mov ebx,1 +Menuet_get_thread_data_wait_loop: + int 0x40 + cmp dword [@Menuet@_ThreadScanCount+4],0 + jz Menuet_get_thread_data_wait_end + shl ebx,1 + cmp ebx,MENUET_MUTEX_MAX_TIME_WAIT + jna Menuet_get_thread_data_wait_loop + mov ebx,MENUET_MUTEX_MAX_TIME_WAIT + jmp Menuet_get_thread_data_wait_loop +Menuet_get_thread_data_wait_end: + pop ebx + pop eax + jmp Menuet_get_thread_data_nowait +enddef + +define @Menuet@_GetSkinHeader$qv + push ebx + mov eax,48 + mov ebx,4 + int 0x40 + pop ebx + ret +enddef + +define @Menuet@GetScreenSize$qrust1 + mov eax,14 + int 0x40 + mov ecx,[esp+8] + mov word [ecx],ax + mov ecx,[esp+4] + shr eax,16 + mov word [ecx],ax + ret +enddef + +define Menuet_MutexLockNoWait + pop eax + xor al,al + ret +enddef + +define Menuet_MutexLockWait + push ebx + mov eax,5 + xor ebx,ebx +Menuet_lock_wait_cycle: + int 0x40 + shl byte [ecx],1 + jz Menuet_lock_wait_cycle + pop ebx + mov al,1 + ret +enddef + +define Menuet_MutexLockWaitTime + cmp dword [esp+12],0 + jng Menuet_MutexLockWait + push ebx + push edx + mov edx,[esp+20] + mov eax,26 + mov ebx,9 + int 0x40 + add edx,eax +Menuet_lock_wait_time_cycle: + mov eax,5 + xor ebx,ebx + int 0x40 + shl byte [ecx],1 + jnz Menuet_lock_wait_time_ret_true + mov eax,26 + mov ebx,9 + int 0x40 + cmp eax,edx + js Menuet_lock_wait_time_cycle + pop edx + pop ebx + pop eax + xor al,al + ret +Menuet_lock_wait_time_ret_true: + pop edx + pop ebx + mov al,1 + ret +enddef + +define Menuet_MutexLock + shl byte [ecx],1 + jnz Menuet_lock_first + call eax +Menuet_lock_first: + mov al,1 + ret +enddef + +define @Menuet@TryLock$qp13Menuet@TMutex + mov eax,Menuet_MutexLockNoWait + mov ecx,[esp+4] + jmp Menuet_MutexLock +enddef + +define @Menuet@Lock$qp13Menuet@TMutex + mov eax,Menuet_MutexLockWait + mov ecx,[esp+4] + jmp Menuet_MutexLock +enddef + +define @Menuet@LockTime$qp13Menuet@TMutexi + mov eax,Menuet_MutexLockWaitTime + mov ecx,[esp+4] + jmp Menuet_MutexLock +enddef + +define @Menuet@UnLock$qp13Menuet@TMutex + mov ecx,[esp+4] + shr byte [ecx],1 + jz Menuet_unlock_pause + ret +Menuet_unlock_pause: + mov byte [ecx],0x40 + push ebx + mov eax,5 + xor ebx,ebx + int 0x40 + pop ebx + ret +enddef + +define Menuet_MutexLockRec + shl byte [ecx],1 + jng Menuet_lock_first + cmp dword [ecx+4],edx + jz Menuet_lock_rec_self + call eax +Menuet_lock_rec_first: + mov al,1 + mov dword [ecx+4],edx + ret +Menuet_lock_rec_self: + mov al,1 + add dword [ecx],0x100 + jc Menuet_lock_rec_overflow + ret +Menuet_lock_rec_overflow: + push dword [@Menuet@DebugPrefix] + call @Menuet@DebugPutString$qpxc + mov dword [esp],Menuet_try_lock_rec_overflow_string + call @Menuet@DebugPutString$qpxc + pop ecx + jmp @Menuet@Abort$qv +enddef + +define @Menuet@TryLock$qp16Menuet@TRecMutexui + mov eax,Menuet_MutexLockNoWait + mov ecx,[esp+4] + mov edx,[esp+8] + jmp Menuet_MutexLockRec +enddef + +define @Menuet@Lock$qp16Menuet@TRecMutexui + mov eax,Menuet_MutexLockWait + mov ecx,[esp+4] + mov edx,[esp+8] + jmp Menuet_MutexLockRec +enddef + +define @Menuet@LockTime$qp16Menuet@TRecMutexiui + mov eax,Menuet_MutexLockWaitTime + mov ecx,[esp+4] + mov edx,[esp+12] + jmp Menuet_MutexLockRec +enddef + +define @Menuet@UnLock$qp16Menuet@TRecMutexui + mov ecx,[esp+4] + mov edx,[esp+8] + cmp dword [ecx+4],edx + jnz Menuet_unlock_rec_notlocked + sub dword [ecx],0x100 + jnc Menuet_unlock_rec_end + add dword [ecx],0x100 + shl byte [ecx],1 + shr byte [ecx],2 + jng Menuet_unlock_rec_pause +Menuet_unlock_rec_end: + ret +Menuet_unlock_rec_pause: + mov byte [ecx],0x20 + push ebx + mov eax,5 + xor ebx,ebx + int 0x40 + pop ebx + ret +Menuet_unlock_rec_notlocked: + push dword [@Menuet@DebugPrefix] + call @Menuet@DebugPutString$qpxc + mov dword [esp],Menuet_unlock_rec_notlocked_string + call @Menuet@DebugPutString$qpxc + pop ecx + jmp @Menuet@Abort$qv +enddef + +define @Menuet@DebugPutChar$qc + mov cl,byte [esp+4] + cmp cl,13 + jz Menuet_debug_put_char_ret + push ebx + cmp cl,10 + jz Menuet_debug_put_char_enter +Menuet_debug_put_char_after_cmp: + mov eax,63 + mov ebx,1 + int 0x40 + pop ebx +Menuet_debug_put_char_ret: + ret +Menuet_debug_put_char_enter: + mov cl,13 + mov eax,63 + mov ebx,1 + int 0x40 + mov cl,10 + jmp Menuet_debug_put_char_after_cmp +enddef + +define @Menuet@DebugPutString$qpxc + push esi + push dword 0 + mov esi,dword [esp+12] + jmp Menuet_debug_put_string_test +Menuet_debug_put_string_loop: + mov dword [esp],eax + call @Menuet@DebugPutChar$qc + inc esi +Menuet_debug_put_string_test: + xor eax,eax + or al,[esi] + test al,al + jnz Menuet_debug_put_string_loop + pop ecx + pop esi + ret +enddef + +define @Menuet@GetKey$qv + mov eax,2 + int 0x40 + test al,al + jnz Menuet_get_key_eof + movzx eax,ah + ret +Menuet_get_key_eof: + mov eax,-1 + ret +enddef + +define @Menuet@GetMouseButton$qv + push ebx + mov eax,37 + mov ebx,2 + int 0x40 + pop ebx + ret +enddef + +define @Menuet@GetMousePosition$qrst1o + push ebx + mov eax,37 + xor ebx,ebx + cmp byte [esp+16],0 + jnz Menuet_get_mouse_pos_absolute + inc ebx +Menuet_get_mouse_pos_absolute: + int 0x40 + mov ecx,[esp+12] + mov word [ecx],ax + mov ecx,[esp+8] + shr eax,16 + mov word [ecx],ax + pop ebx + ret +enddef + +define @Menuet@WasThreadCreated$qv + cmp byte [@Menuet@_ThreadSavedBegProc],0x90 + setz al + ret +enddef + +define @Menuet@CreateThread$qpvuit1 + push ebx + mov edx,[esp+16] + mov ebx,[esp+12] + test edx,edx + jnz Menuet_create_thread_after_new +if defined MenuetHeapAlloc + cmp ebx,4096 + jnb Menuet_create_thread_alloc + mov ebx,STACKSIZE +Menuet_create_thread_alloc: + push ebx + call MenuetHeapAlloc ; Create new dynamic memory of the given size + pop ecx + test eax,eax + jnz Menuet_create_thread_mem_created +end if + or eax,-1 + jmp Menuet_create_thread_end +Menuet_create_thread_mem_created: + lea edx,[eax+ebx] +Menuet_create_thread_after_new: + neg ebx + jz Menuet_create_thread_test_first + add ebx,edx +Menuet_create_thread_test_first: + cmp byte [@Menuet@_ThreadSavedBegProc],0x90 + jnz Menuet_create_thread_init +Menuet_create_thread_fill_stack: + lock inc dword [@Menuet@_ThreadNumber] + and edx,not 3 + sub edx,12 + mov ecx,[esp+8] + mov dword [edx+8],ebx + mov dword [edx+4],ecx + mov dword [edx],Menuet_ThreadFinish + mov eax,51 + mov ebx,1 + mov ecx,@Menuet@ThreadMain$qpvt1 + int 0x40 + mov ebx,eax + or bl,15 + inc ebx + jnz Menuet_create_thread_end + lock dec dword [@Menuet@_ThreadNumber] +if defined MenuetHeapFree + or ebx,[edx+8] + jz Menuet_create_thread_end + push ebx + call MenuetHeapFree ; Delete the given dynamic memory + pop ecx +end if +Menuet_create_thread_end: + pop ebx + ret +Menuet_create_thread_init: + push esi + push edi + cld + mov esi,@Menuet@_ThreadSavedBegProc + mov edi,@Menuet@GetPid$qv + movs dword [edi],[esi] + movs dword [edi],[esi] + mov edi,@Menuet@GetThreadData$qv + movs dword [edi],[esi] + movs dword [edi],[esi] + mov eax,0x90909090 + mov edi,@Menuet@_ThreadSavedBegProc + stos dword [edi] + stos dword [edi] + stos dword [edi] + stos dword [edi] + pop edi + pop esi + jmp Menuet_create_thread_fill_stack +enddef + +define @Menuet@_FileAccess$qpv + push ebx + mov eax,58 + mov ebx,[esp+8] + int 0x40 + mov ecx,[esp+8] + mov [ecx],ebx + pop ebx + cmp eax,5 + jz Menuet_file_access_ret_zero + ret +Menuet_file_access_ret_zero: + xor eax,eax + ret +enddef + +__pure_error_: + jmp $ + +define Menuet_abort_string + db 'Abnormal program termination.',10,0 +newdef Menuet_try_lock_rec_overflow_string + db 'Recursive mutex lock count overflow.',10,0 +newdef Menuet_unlock_rec_notlocked_string + db 'Recursive mutex unlock error.',10,0 +enddef + +include "me_lib.inc" + +;/**/ + diff --git a/programs/games/checkers/trunk/include/me_heap.h b/programs/games/checkers/trunk/include/me_heap.h new file mode 100644 index 0000000000..5954d8edfc --- /dev/null +++ b/programs/games/checkers/trunk/include/me_heap.h @@ -0,0 +1,90 @@ +#ifndef __MENUET_HEAP_H_INCLUDED_ +#define __MENUET_HEAP_H_INCLUDED_ + +#include +#include + +// Menuet memory heap interface. + +namespace Menuet // All menuet functions, types and data are nested in the (Menuet) namespace. +{ + void *Alloc(unsigned int size); + void *ReAlloc(void *mem, unsigned int size); + void Free(void *mem); +} + +#ifdef __MENUET__ + +namespace Menuet +{ + +// Global variables + + MemoryHeap::TFreeSpace _MenuetFreeSpace; + MemoryHeap::TMemBlock _MenuetMemBlock; + TMutex _MemHeapMutex = MENUET_MUTEX_INIT; + +// Functions + + void *_HeapInit(void *begin, void *use_end, void *end) + { + MemoryHeap::InitFreeSpace(_MenuetFreeSpace); + _MenuetMemBlock = MemoryHeap::CreateBlock(begin, end, _MenuetFreeSpace); + unsigned int use_beg = (unsigned int)MemoryHeap::BlockBegin(_MenuetMemBlock) + + MemoryHeap::BlockAddSize - MemoryHeap::BlockEndSize; + unsigned int use_size = (unsigned int)use_end; + if (use_size <= use_beg) return 0; + else use_size -= use_beg; + return MemoryHeap::Alloc(_MenuetFreeSpace, use_size); + } + + bool _SetUseMemory(unsigned int use_mem); + + int _RecalculateUseMemory(unsigned int use_mem); + + void *Alloc(unsigned int size) + { + if (!size) return 0; + Lock(&_MemHeapMutex); + void *res = MemoryHeap::Alloc(_MenuetFreeSpace, size); + if (!res) + { + unsigned use_mem = (unsigned int)MemoryHeap::BlockEndFor(_MenuetMemBlock, size); + if (_SetUseMemory(_RecalculateUseMemory(use_mem))) + { + res = MemoryHeap::Alloc(_MenuetFreeSpace, size); + } + } + UnLock(&_MemHeapMutex); + return res; + } + + void *ReAlloc(void *mem, unsigned int size) + { + Lock(&_MemHeapMutex); + void *res = MemoryHeap::ReAlloc(_MenuetFreeSpace, mem, size); + if (!res && size) + { + unsigned use_mem = (unsigned int)MemoryHeap::BlockEndFor(_MenuetMemBlock, size); + if (_SetUseMemory(_RecalculateUseMemory(use_mem))) + { + res = MemoryHeap::ReAlloc(_MenuetFreeSpace, mem, size); + } + } + UnLock(&_MemHeapMutex); + return res; + } + + void Free(void *mem) + { + Lock(&_MemHeapMutex); + MemoryHeap::Free(_MenuetFreeSpace, mem); + UnLock(&_MemHeapMutex); + } + + void _FreeAndThreadFinish(void *mem, int *exit_proc_now); +} + +#endif // def __MENUET__ + +#endif // ndef __MENUET_HEAP_H_INCLUDED_ diff --git a/programs/games/checkers/trunk/include/me_heap.inc b/programs/games/checkers/trunk/include/me_heap.inc new file mode 100644 index 0000000000..6a32667508 --- /dev/null +++ b/programs/games/checkers/trunk/include/me_heap.inc @@ -0,0 +1,284 @@ +;/*** + +MenuetHeapInit = @@Menuet@_HeapInit$qpvt1t1 + +MenuetHeapAlloc = @@Menuet@Alloc$qui + +MenuetHeapReAlloc = @@Menuet@ReAlloc$qpvui + +MenuetHeapFree = @@Menuet@Free$qpv + +MenuetHeapFreeAndThreadFinish = @Menuet@_FreeAndThreadFinish$qpvpi + +define @Menuet@_SetUseMemory$qui + push ebx + mov eax,64 + mov ebx,1 + mov ecx,[esp+8] + int 0x40 + pop ebx + test eax,eax + jnz Menuet_set_use_memory_nomem + push ecx + push dword [@Menuet@_MenuetMemBlock] + call @@MemoryHeap@ResizeBlock$q20MemoryHeap@TMemBlockpv + add esp,8 + mov al,1 + ret +Menuet_set_use_memory_nomem: + xor al,al + ret +enddef + +define @Menuet@_RecalculateUseMemory$qui + mov eax,dword [esp+4] + mov ecx,(U_END + 3) and not 3 + cmp eax,ecx + jna Menuet_recalculate_use_memory_min + push ebx + sub eax,ecx + mov ebx,6 + mul ebx + dec ebx + div ebx + add eax,((U_END + 3) and not 3) + 3 + and eax,not 3 + pop ebx + ret +Menuet_recalculate_use_memory_min: + mov eax,ecx + ret +enddef + +define @Menuet@_FreeAndThreadFinish$qpvpi + mov ebx,1 + mov ecx,[esp+8] + jmp Menuet_heap_free_tf_wait +Menuet_heap_free_tf_wait_loop: + mov eax,5 + int 0x40 + shl ebx,1 + cmp ebx,MENUET_MUTEX_MAX_TIME_WAIT + jna Menuet_heap_free_tf_wait + mov ebx,MENUET_MUTEX_MAX_TIME_WAIT +Menuet_heap_free_tf_wait: + cmp dword [ecx],0 + jnz @Menuet@ExitProcess$qv + lock bts dword [@Menuet@_MemHeapMutex],0 + jc Menuet_heap_free_tf_wait_loop + push dword [esp+4] + push @Menuet@_MenuetFreeSpace + call @@MemoryHeap@Free$qr21MemoryHeap@TFreeSpacepv + add esp,8 + mov byte [@Menuet@_MemHeapMutex],0x40 + or eax,-1 + int 0x40 +enddef + +macro call func +{ + if func eq @MemoryHeap@_FirstNotZeroBit$qui + bsf eax,[esp] + else if func eq @MemoryHeap@_CopyMemItemArray$quiuiui + xchg edi,[esp] + xchg esi,[esp+4] + mov ecx,[esp+8] + cld + sub ecx,esi + shr ecx,2 + rep movs dword [edi],[esi] + xchg edi,[esp] + xchg esi,[esp+4] + else + call func + end if +} + +@$bnwa$qui = @@Menuet@Alloc$qui +@$bnew$qui = @@Menuet@Alloc$qui + +@$bdla$qpv = @@Menuet@Free$qpv +@$bdele$qpv = @@Menuet@Free$qpv + +define @_vector_new_ldtc_$qpvuiuiuit1uit1 +.var_2C = -0Ch +.var_28 = -8 +.var_24 = -4 +.arg_0 = 8 +.arg_4 = 0Ch +.arg_8 = 10h +.arg_C = 14h +.arg_10 = 18h + push ebp + mov ebp, esp + add esp, -0Ch + push ebx + push esi + push edi + mov edi, [ebp+.arg_10] + mov esi, [ebp+.arg_C] + cmp dword [ebp+.arg_0], 0 + jnz .loc_10070 + mov edx, [ebp+.arg_4] + imul edx, [ebp+.arg_8] + test esi, 10h + jz @f + add edx, 4 +@@: + push edx + call @$bnwa$qui + pop ecx + mov [ebp+.arg_0], eax + test eax, eax + jz .ret + mov dword [ebp+.var_2C], 1 + jmp @f +.loc_10070: + and dword [ebp+.var_2C], 0 +@@: + test esi, 10h + jz @f + mov edx, [ebp+.arg_0] + mov ecx, [ebp+.arg_8] + mov [edx], ecx + add dword [ebp+.arg_0], 4 +@@: + mov eax, [ebp+.arg_0] + test edi, edi + jz .ret + mov ecx, [ebp+.arg_8] + mov [ebp+.var_28], ecx + mov ebx, eax + jmp .loc_100EF +.loc_100B0: + mov eax, esi + and eax, 7 + dec eax + jz .loc_100CB + dec eax + jz .loc_100D1 + dec eax + jz .loc_100D6 + dec eax + dec eax + jz .loc_100DC + jmp $ +.loc_100CB: + push ebx + call edi + pop ecx + jmp .loc_100EC +.loc_100D1: +.loc_100DC: + push ebx + call edi + jmp .loc_100EC +.loc_100D6: + mov eax, ebx + call edi +.loc_100EC: + add ebx, [ebp+.arg_4] +.loc_100EF: + dec dword [ebp+.var_28] + jns .loc_100B0 + mov eax, [ebp+.arg_0] +.ret: + pop edi + pop esi + pop ebx + mov esp, ebp + pop ebp + ret +enddef + +define @_vector_delete_ldtc_$qpvuiuiuit1 +.arg_0 = 8 +.arg_4 = 0Ch +.arg_8 = 10h +.arg_C = 14h +.arg_10 = 18h + push ebp + mov ebp, esp + push ebx + push esi + push edi + mov edi, [ebp+.arg_C] + mov esi, edi + and esi, 10h + and edi, 8 + cmp dword [ebp+.arg_0], 0 + jz .ret + test esi, esi + jz @f + mov ecx, [ebp+.arg_0] + mov eax, [ecx-4] + mov [ebp+.arg_8], eax +@@: + mov ebx, [ebp+.arg_8] + dec ebx + imul ebx, [ebp+.arg_4] + add ebx, [ebp+.arg_0] + jmp .loc_100D3 +.loc_1008B: + mov eax, [ebp+.arg_C] + and eax, 7 + dec eax + jz .loc_1009E + dec eax + jz .loc_100A9 + dec eax + jz .loc_100B1 + dec eax + dec eax + jz .loc_100BD + jmp $ +.loc_1009E: + push 2 + push ebx + call dword [ebp+.arg_10] + add esp, 8 + jmp .loc_100D0 +.loc_100A9: + push 2 + push ebx + call dword [ebp+.arg_10] + jmp .loc_100D0 +.loc_100B1: + mov edx, 2 + mov eax, ebx + call dword [ebp+.arg_10] + jmp .loc_100D0 +.loc_100BD: + push 2 + push ebx + call dword [ebp+.arg_10] +.loc_100D0: + sub ebx, [ebp+.arg_4] +.loc_100D3: + dec dword [ebp+.arg_8] + jns .loc_1008B + test esi, esi + jz @f + sub dword [ebp+.arg_0], 4 +@@: + test edi, edi + jz @f + push dword [ebp+.arg_0] + call @$bdla$qpv + pop ecx + jmp .ret +@@: + mov eax, [ebp+.arg_0] + jmp .reteax +.ret: + xor eax, eax +.reteax: + pop edi + pop esi + pop ebx + mov esp, ebp + pop ebp + ret +enddef + +;/**/ diff --git a/programs/games/checkers/trunk/include/me_lib.h b/programs/games/checkers/trunk/include/me_lib.h new file mode 100644 index 0000000000..48cebb6c7b --- /dev/null +++ b/programs/games/checkers/trunk/include/me_lib.h @@ -0,0 +1,16 @@ +#ifndef __MENUET_LIB_H_INCLUDED_ +#define __MENUET_LIB_H_INCLUDED_ + +// Menuet interface. + +namespace Menuet // All menuet functions, types and data are nested in the (Menuet) namespace. +{ + unsigned int StrLen(const char *str); + char *StrCopy(char *dest, const char *src); + void *MemCopy(void *dest, const void *src, unsigned int n); + void *MemSet(void *s, char c, unsigned int n); + + double Floor(double x); +} + +#endif // __MENUET_LIB_H_INCLUDED_ diff --git a/programs/games/checkers/trunk/include/me_lib.inc b/programs/games/checkers/trunk/include/me_lib.inc new file mode 100644 index 0000000000..7be9ab3fac --- /dev/null +++ b/programs/games/checkers/trunk/include/me_lib.inc @@ -0,0 +1,118 @@ +define @Menuet@StrLen$qpxc + push edi + cld + mov edi,[esp+8] + mov ecx,-1 + xor al,al + repnz scas byte [edi] + not ecx + lea eax,[ecx-1] + pop edi + ret +enddef + +define @Menuet@StrCopy$qpcpxc + push esi + push edi + cld + mov edi,[esp+16] + mov ecx,-1 + mov esi,edi + xor al,al + repnz scas byte [edi] + not ecx + mov edi,[esp+12] + mov edx,ecx + mov eax,edi + shr ecx,2 + rep movs dword [edi],[esi] + mov ecx,edx + and ecx,3 + rep movs byte [edi],[esi] + pop edi + pop esi + ret +enddef + +define @Menuet@MemCopy$qpvpxvui + push esi + push edi + cld + mov edi,[esp+12] + mov eax,edi + mov ecx,[esp+20] + mov esi,[esp+16] + mov edx,ecx + shr ecx,2 + rep movs dword [edi],[esi] + mov ecx,edx + and ecx,3 + rep movs byte [edi],[esi] + pop edi + pop esi + ret +enddef + +define @Menuet@MemSet$qpvcui + push edi + cld + mov edi,[esp+8] + mov al,[esp+12] + mov ah,al + mov dx,ax + shl eax,16 + mov ax,dx + mov ecx,[esp+16] + mov edx,ecx + shr ecx,2 + rep stos dword [edi] + mov ecx,edx + and ecx,3 + rep stos byte [edi] + pop edi + mov eax,[esp+4] + ret +enddef + +define __ftol + sub esp,12 + wait + fstcw word [esp+8] + wait + mov al,[esp+9] + or byte [esp+9],0x0c + fldcw word [esp+8] + fistp qword [esp] + mov [esp+9],al + fldcw word [esp+8] + mov eax,[esp] + mov edx,[esp+4] + add esp,12 + ret +enddef + +define @Menuet@Floor$qd + fld qword [esp+4] + mov ax,[esp+10] + shl ax,1 + cmp ax,0x8680 + ja Menuet_floor_end + mov ch,4 + sub esp,2 + wait + fstcw word [esp] + mov ax,0xf3ff + wait + mov dx,[esp] + and ax,dx + or ah,ch + mov [esp],ax + fldcw word [esp] + frndint + mov [esp],dx + fldcw word [esp] + add esp,2 +Menuet_floor_end: + ret +enddef + diff --git a/programs/games/checkers/trunk/include/me_start.inc b/programs/games/checkers/trunk/include/me_start.inc new file mode 100644 index 0000000000..36e1bcf24b --- /dev/null +++ b/programs/games/checkers/trunk/include/me_start.inc @@ -0,0 +1,90 @@ +use32 +org 0x0 + db 'MENUET01' + dd 0x1 + dd MenuetEntryPoint + dd I_END + dd U_END+STACKSIZE+HEAPSIZE + dd U_END+STACKSIZE + dd 0x0,0x0 + +ptr equ +offset equ +short equ +tbyte equ tword + +PTR equ +OFFSET equ +SHORT equ +TBYTE equ TWORD + +macro movsb a,b +{ + if a eq & b eq + movsb + else + movsx a,b + end if +} + +macro movsw a,b +{ + if a eq & b eq + movsw + else + movsx a,b + end if +} + +macro segment name {} + +macro endseg name {} + +macro usedef [link] +{ + common + if ~link eq + virtual at 0 + forward + dd link + common + end virtual + end if +} + +macro define x,[link] +{ + common + if x eq + else if used x + x: + usedef link +} + +macro enddef [link] +{ + common + usedef link + end if +} + +macro newdef x,[link] +{ + common + end if + if x eq + else if used x + x: + usedef link +} + +macro nextdef x,[link] +{ + common + usedef x + end if + if x eq + else if used x + x: + usedef link +} diff --git a/programs/games/checkers/trunk/include/memheap.h b/programs/games/checkers/trunk/include/memheap.h new file mode 100644 index 0000000000..bf8aa101fc --- /dev/null +++ b/programs/games/checkers/trunk/include/memheap.h @@ -0,0 +1,626 @@ +#ifndef __MEMORY_HEAP_RBTREE_H_INCLUDED_ +#define __MEMORY_HEAP_RBTREE_H_INCLUDED_ + +namespace MemoryHeap +{ + typedef unsigned int TMemItem; + + enum {NumTreeSmall = 8 * sizeof(TMemItem)}; + +// Memory heap interface. + + struct TFreeSpace + { + TMemItem Small[NumTreeSmall], Min, SmallMask; + }; + + struct TMemBlock + { + TMemItem *Begin; + }; + + bool BlockValid(const TMemBlock &block); // Is the given memory block valid? + void *BlockBegin(const TMemBlock &block); // Return the beginning address of the block. + void *BlockEnd(const TMemBlock &block); // Return the ending address of the block. + TFreeSpace &BlockFreeSpace(const TMemBlock &block); // Return the free space of the block. + + void InitFreeSpace(TFreeSpace &fs); // Initialize the free space. + TMemBlock NullBlock(); // Return null invalid block. + TMemBlock CreateBlock(void *begin, void *end, TFreeSpace &fs); + // Create a memory block with the given begin and end and add free space of it to (fs), + //_ give (BlockAddSize) bytes of the block for it's data. + //_ (Program can alloc (end - begin - BlockAddSize) bytes after it, + //_ that must be not less than (MemMinSize) ). + TMemBlock CreateBlock(void *begin, void *end); + // Create a memory block with the given begin and end and new free space for it, + //_ give (BlockAddSizeFS) bytes of the block for it's data. + //_ (Program can alloc (end - begin - BlockAddSizeFS) bytes after it, + //_ that must be not less than (MemMinSize) ). + void ResizeBlock(TMemBlock block, void *new_end); // Resize the memory block to the given new end. + void RemoveBlock(TMemBlock block); // Remove the given memory block. + + void *BlockEndFor(TMemBlock block, unsigned int size); + // Return the new end of the block needed for (ResizeBlock) to alloc the given size of memory. + unsigned int BlockSize(TMemBlock block); // Return the size of the given block. + unsigned int MemSize(void *mem); // Return the size of the allocced memory. + + void *Alloc(TFreeSpace &fs, unsigned int size); + // Alloc a memory in the given free space, give (MemAddSize) bytes for it's data. + void *ReAlloc(TFreeSpace &fs, unsigned int size, void *mem); + // ReAlloc the given memory, it must lie in the block with the given free space. + void Free(TFreeSpace &fs, void *mem); + // Free the given memory, it must lie in the block with the given free space. + +// Macro definitions. + +#define MEMORY_HEAP_ALIGN_DOWN(s) (MemoryHeap::TMemItem(s) & ~(MemoryHeap::MemAlign - 1)) +#define MEMORY_HEAP_ALIGN_UP(s) ((MemoryHeap::TMemItem(s) + (MemoryHeap::MemAlign - 1)) & ~(MemoryHeap::MemAlign - 1)) +#define MEMORY_HEAP_ITEM(s,k) ( ((MemoryHeap::TMemItem*)(s))[(k)] ) +#define MEMORY_HEAP_NEXT(s) (MEMORY_HEAP_ITEM((s),-1)) +#define MEMORY_HEAP_PREV(s) (MEMORY_HEAP_ITEM((s),-2)) +#define MEMORY_HEAP_FREE(s) (MEMORY_HEAP_ITEM((s),-1) & 1) + +// Constants. + + enum {MemAlign = sizeof(TMemItem)}; + enum {MemAddSize = MEMORY_HEAP_ALIGN_UP(2 * sizeof(TMemItem))}; + enum {BlockEndSize = MemAddSize}; + enum {BlockAddSize = MEMORY_HEAP_ALIGN_UP(4 * sizeof(TMemItem)) + BlockEndSize}; + enum {BlockAddSizeFS = BlockAddSize + BlockEndSize + MEMORY_HEAP_ALIGN_UP(sizeof(TFreeSpace))}; + enum {MemMinSize = MEMORY_HEAP_ALIGN_UP(2 * sizeof(TMemItem))}; + +// Inline functions. + + inline bool BlockValid(const TMemBlock &block) {return block.Begin != 0;} + + inline void *BlockBegin(const TMemBlock &block) {return (void*)block.Begin;} + + inline void *BlockEnd(const TMemBlock &block) {return block.Begin ? (void*)block.Begin[1] : 0;} + + inline TFreeSpace &BlockFreeSpace(const TMemBlock &block) {return *(TFreeSpace*)block.Begin[0];} + + inline TMemBlock NullBlock() {TMemBlock block; block.Begin = 0; return block;} + + inline void *BlockEndFor(TMemBlock block, unsigned int size) + { + TMemItem last = (TMemItem)block.Begin[1]; + TMemItem prevlast = MEMORY_HEAP_PREV(last); + return (void*)( (MEMORY_HEAP_FREE(prevlast) ? prevlast : last) + MemAddSize + + ((size <= MemMinSize) ? MemMinSize : MEMORY_HEAP_ALIGN_UP(size)) ); + } + + inline unsigned int BlockSize(TMemBlock block) + { + if (!block.Begin) return 0; + return (unsigned int)(block.Begin[1] - (TMemItem)block.Begin); + } + + inline unsigned int MemSize(void *mem) + { + if (!mem) return 0; + TMemItem c = (TMemItem)mem; + return MEMORY_HEAP_NEXT(c) - c - MemAddSize; + } + +// Free space item functions. + + TMemItem _FirstNotZeroBit(TMemItem i) + { + TMemItem r = 0; + while ((i >>= 1) != 0) r++; + return r; + } + + void _RBTreeRotate(TMemItem parent, TMemItem item, int side) + { + TMemItem temp = MEMORY_HEAP_ITEM(parent,0); + MEMORY_HEAP_ITEM(item,0) = temp; + if (temp) + { + if (MEMORY_HEAP_ITEM(temp,2) == parent) + { + MEMORY_HEAP_ITEM(temp,2) = item; + } + else MEMORY_HEAP_ITEM(temp,3) = item; + } + temp = MEMORY_HEAP_ITEM(item,side^1); + if (temp) MEMORY_HEAP_ITEM(temp,0) = parent; + MEMORY_HEAP_ITEM(parent,side) = temp; + MEMORY_HEAP_ITEM(parent,0) = item; + MEMORY_HEAP_ITEM(item,side^1) = parent; + temp = MEMORY_HEAP_ITEM(parent,1); + MEMORY_HEAP_ITEM(parent,1) = MEMORY_HEAP_ITEM(item,1); + MEMORY_HEAP_ITEM(item,1) = temp; + } + + void InitFreeSpace(TFreeSpace &fs) + { + TMemItem i; + for (i = 0; i <= NumTreeSmall; i++) fs.Small[i] = 0; + fs.Min = 0; fs.SmallMask = 0; + } + + void _FreeAdd(TFreeSpace &fs, TMemItem item) + { + TMemItem size = MEMORY_HEAP_NEXT(item) - item; + if (size < MemAddSize + MemMinSize + MemAlign * NumTreeSmall) + { + TMemItem s = (size - (MemAddSize + MemMinSize)) / MemAlign; + TMemItem &addto = fs.Small[s]; + MEMORY_HEAP_ITEM(item,1) = (TMemItem)(&addto); + MEMORY_HEAP_ITEM(item,0) = (TMemItem)addto; + if (addto) MEMORY_HEAP_ITEM(addto,1) = item; + addto = item; + fs.SmallMask |= TMemItem(1) << s; + return; + } + TMemItem addto = fs.Min, parent, temp; + MEMORY_HEAP_ITEM(item,2) = 0; + MEMORY_HEAP_ITEM(item,3) = 0; + if (!addto) + { + MEMORY_HEAP_ITEM(item,0) = 0; + MEMORY_HEAP_ITEM(item,1) = 1; + fs.Min = item; + return; + } + MEMORY_HEAP_ITEM(item,1) = 0; + TMemItem side = 2; + if (MEMORY_HEAP_NEXT(addto) - addto >= size) fs.Min = item; + else + { + for (;;) + { + parent = MEMORY_HEAP_ITEM(addto,0); + if (!parent) break; + if (MEMORY_HEAP_NEXT(parent) - parent < size) addto = parent; + else break; + } + for (;;) + { + if (MEMORY_HEAP_NEXT(addto) - addto < size) + { + temp = MEMORY_HEAP_ITEM(addto,3); + if (!temp) {side = 3; break;} + addto = temp; + } + else + { + temp = MEMORY_HEAP_ITEM(addto,2); + if (!temp) break; + addto = temp; + } + } + } + MEMORY_HEAP_ITEM(item,0) = addto; + MEMORY_HEAP_ITEM(addto,side) = item; + for (;;) + { + if (MEMORY_HEAP_ITEM(addto,1) != 0) return; + parent = MEMORY_HEAP_ITEM(addto,0); + temp = MEMORY_HEAP_ITEM(parent,2); + if (temp == addto) + { + temp = MEMORY_HEAP_ITEM(parent,3); + side = 2; + } + else side = 3; + if (!temp || MEMORY_HEAP_ITEM(temp,1) != 0) break; + MEMORY_HEAP_ITEM(addto,1) = 1; + MEMORY_HEAP_ITEM(temp,1) = 1; + item = parent; + addto = MEMORY_HEAP_ITEM(item,0); + if (!addto) return; + MEMORY_HEAP_ITEM(item,1) = 0; + } + if (MEMORY_HEAP_ITEM(addto,side) != item) + { + temp = MEMORY_HEAP_ITEM(item,side); + if (temp) MEMORY_HEAP_ITEM(temp,0) = addto; + MEMORY_HEAP_ITEM(addto,side^1) = temp; + MEMORY_HEAP_ITEM(addto,0) = item; + MEMORY_HEAP_ITEM(item,side) = addto; + MEMORY_HEAP_ITEM(item,0) = parent; + MEMORY_HEAP_ITEM(parent,side) = item; + } + else item = addto; + _RBTreeRotate(parent, item, side); + } + + void _FreeDel(TFreeSpace &fs, TMemItem item) + { + TMemItem size = MEMORY_HEAP_NEXT(item) - item; + if (size < MemAddSize + MemMinSize + MemAlign * NumTreeSmall) + { + TMemItem prev = MEMORY_HEAP_ITEM(item,1); + TMemItem next = MEMORY_HEAP_ITEM(item,0); + MEMORY_HEAP_ITEM(prev,0) = next; + if (next) MEMORY_HEAP_ITEM(next,1) = prev; + else + { + TMemItem s = (size - (MemAddSize + MemMinSize)) / MemAlign; + if (!fs.Small[s]) fs.SmallMask &= ~(TMemItem(1) << s); + } + return; + } + TMemItem parent, temp, second, add; + TMemItem side = 2; + temp = MEMORY_HEAP_ITEM(item,3); + if (temp) + { + for (;;) + { + second = temp; + temp = MEMORY_HEAP_ITEM(temp,2); + if (!temp) break; + } + if (fs.Min == item) fs.Min = second; + add = MEMORY_HEAP_ITEM(second,3); + parent = MEMORY_HEAP_ITEM(second,0); + if (parent == item) {parent = second; side = 3;} + else + { + temp = MEMORY_HEAP_ITEM(item,3); + MEMORY_HEAP_ITEM(second,3) = temp; + MEMORY_HEAP_ITEM(temp,0) = second; + } + temp = MEMORY_HEAP_ITEM(item,2); + MEMORY_HEAP_ITEM(second,2) = temp; + if (temp) MEMORY_HEAP_ITEM(temp,0) = second; + temp = MEMORY_HEAP_ITEM(item,0); + MEMORY_HEAP_ITEM(second,0) = temp; + if (temp) + { + if (MEMORY_HEAP_ITEM(temp,2) == item) + { + MEMORY_HEAP_ITEM(temp,2) = second; + } + else MEMORY_HEAP_ITEM(temp,3) = second; + } + MEMORY_HEAP_ITEM(parent,side) = add; + if (add) MEMORY_HEAP_ITEM(add,0) = parent; + bool color = MEMORY_HEAP_ITEM(second,1); + MEMORY_HEAP_ITEM(second,1) = MEMORY_HEAP_ITEM(item,1); + if (!color) return; + } + else + { + if (fs.Min == item) fs.Min = MEMORY_HEAP_ITEM(item,0); + add = MEMORY_HEAP_ITEM(item,2); + parent = MEMORY_HEAP_ITEM(item,0); + if (add) MEMORY_HEAP_ITEM(add,0) = parent; + if (parent) + { + if (MEMORY_HEAP_ITEM(parent,2) == item) + { + MEMORY_HEAP_ITEM(parent,2) = add; + } + else + { + MEMORY_HEAP_ITEM(parent,3) = add; + side = 3; + } + } + else + { + if (add) MEMORY_HEAP_ITEM(add,1) = 1; + return; + } + if (!MEMORY_HEAP_ITEM(item,1)) return; + } + if (add && !MEMORY_HEAP_ITEM(add,1)) + { + MEMORY_HEAP_ITEM(add,1) = 1; + return; + } + for (;;) + { + second = MEMORY_HEAP_ITEM(parent,side^1); + if (!MEMORY_HEAP_ITEM(second,1)) + { + _RBTreeRotate(parent, second, side^1); + second = MEMORY_HEAP_ITEM(parent,side^1); + } + temp = MEMORY_HEAP_ITEM(second,side^1); + if (temp && !MEMORY_HEAP_ITEM(temp,1)) + { + MEMORY_HEAP_ITEM(temp,1) = 1; + break; + } + temp = MEMORY_HEAP_ITEM(second,side); + if (temp && !MEMORY_HEAP_ITEM(temp,1)) + { + _RBTreeRotate(second, temp, side); + MEMORY_HEAP_ITEM(second,1) = 1; + second = temp; + break; + } + MEMORY_HEAP_ITEM(second,1) = 0; + if (!MEMORY_HEAP_ITEM(parent,1)) + { + MEMORY_HEAP_ITEM(parent,1) = 1; + return; + } + second = parent; + parent = MEMORY_HEAP_ITEM(second,0); + if (!parent) return; + if (MEMORY_HEAP_ITEM(parent,2) == second) side = 2; + else side = 3; + } + _RBTreeRotate(parent, second, side^1); + } + + TMemItem _FreeFindAfter(TMemItem item, TMemItem size) + { + if (!item) return 0; + TMemItem paritem, s; + if (MEMORY_HEAP_NEXT(item) - item >= size) return item; + for (;;) + { + paritem = MEMORY_HEAP_ITEM(item,0); + if (!paritem) break; + s = MEMORY_HEAP_NEXT(paritem) - paritem; + if (s == size) return paritem; + if (s < size) item = paritem; + else break; + } + MEMORY_HEAP_ITEM(item,3); + for (;;) + { + if (!item) return paritem; + s = MEMORY_HEAP_NEXT(item) - item; + if (s == size) return item; + if (s < size) item = MEMORY_HEAP_ITEM(item,3); + else + { + paritem = item; + item = MEMORY_HEAP_ITEM(item,2); + } + } + } + + TMemItem _FreeFind(TFreeSpace &fs, TMemItem size) + { + TMemItem item, nextitem, s; + if (size < MemAddSize + MemMinSize + MemAlign * NumTreeSmall) + { + TMemItem m, t; + s = (size - (MemAddSize + MemMinSize)) / MemAlign; + item = fs.Small[s]; + if (item) return item; + if (size < MemAlign * NumTreeSmall) + { + t = size / MemAlign; + m = fs.SmallMask >> t; + if (m) return fs.Small[t + _FirstNotZeroBit(m)]; + else if (fs.Min) return fs.Min; + } + else + { + item = _FreeFindAfter(fs.Min, size + 1 + MemAddSize + MemMinSize); + if (item) return item; + } + m = fs.SmallMask >> s; + if (m) return fs.Small[s + _FirstNotZeroBit(m)]; + else return fs.Min; + } + item = _FreeFindAfter(fs.Min, ++size); + if (!item) return 0; + s = MEMORY_HEAP_NEXT(item) - item; + if (s == size) return item; + size += MemAddSize + MemMinSize; + if (s >= size) return item; + nextitem = _FreeFindAfter(item, size); + return nextitem ? nextitem : item; + } + +// Block functions. + + inline void _CreateBlockEnd(TMemBlock &block, TFreeSpace &fs, TMemItem c, TMemItem e) + { + block.Begin[0] = (TMemItem)(&fs); + if (e - c < TMemItem(MemAddSize + MemMinSize)) + { + MEMORY_HEAP_NEXT(c) = 0; + block.Begin[1] = c; + } + else + { + MEMORY_HEAP_NEXT(c) = e + 1; + _FreeAdd(fs, c); + MEMORY_HEAP_PREV(e) = c; + MEMORY_HEAP_NEXT(e) = 0; + block.Begin[1] = e; + } + } + + TMemBlock CreateBlock(void *begin, void *end, TFreeSpace &fs) + { + TMemBlock block = {0}; + TMemItem b = MEMORY_HEAP_ALIGN_UP(begin); + TMemItem e = MEMORY_HEAP_ALIGN_DOWN(end); + if (e <= b || e - b < TMemItem(BlockAddSize - MemAddSize)) return block; + block.Begin = (TMemItem*)b; + b += MEMORY_HEAP_ALIGN_UP(4 * sizeof(TMemItem)); + MEMORY_HEAP_PREV(b) = 0; + _CreateBlockEnd(block, fs, b, e); + return block; + } + + TMemBlock CreateBlock(void *begin, void *end) + { + TMemBlock block = {0}; + TMemItem b = MEMORY_HEAP_ALIGN_UP(begin); + TMemItem e = MEMORY_HEAP_ALIGN_DOWN(end); + if (e <= b || e - b < TMemItem(BlockAddSizeFS - MemAddSize)) return block; + block.Begin = (TMemItem*)b; + b += MEMORY_HEAP_ALIGN_UP(4 * sizeof(TMemItem)); + TMemItem c = b + MemAddSize + MEMORY_HEAP_ALIGN_UP(sizeof(TFreeSpace)); + MEMORY_HEAP_PREV(b) = 0; + MEMORY_HEAP_NEXT(b) = c; + MEMORY_HEAP_PREV(c) = b; + InitFreeSpace(*(TFreeSpace*)b); + _CreateBlockEnd(block, *(TFreeSpace*)b, c, e); + return block; + } + + void ResizeBlock(TMemBlock block, void *new_end) + { + if (!BlockValid(block)) return; + TMemItem e = MEMORY_HEAP_ALIGN_DOWN(new_end); + TMemItem c = block.Begin[1]; + TFreeSpace &fs = *(TFreeSpace*)block.Begin[0]; + do + { + if (c == e) return; + else if (c > e) + { + while ((c = MEMORY_HEAP_PREV(c)) > e) + { + if (MEMORY_HEAP_FREE(c)) _FreeDel(fs, c); + } + if (!c) {block.Begin = 0; return;} + if (MEMORY_HEAP_FREE(c)) + { + _FreeDel(fs, c); + if (e - c < TMemItem(MemAddSize + MemMinSize)) e = c; + else + { + MEMORY_HEAP_NEXT(c) = e + 1; + _FreeAdd(*(TFreeSpace*)block.Begin[0], c); + break; + } + } + else if (e - c >= TMemItem(MemAddSize + MemMinSize)) + { + MEMORY_HEAP_NEXT(c) = e; break; + } + MEMORY_HEAP_NEXT(c) = 0; + block.Begin[1] = c; + if (c == e) return; + } + TMemItem pc = MEMORY_HEAP_PREV(c); + if (pc && MEMORY_HEAP_FREE(pc)) _FreeDel(fs, c = pc); + else if (e - c < TMemItem(MemAddSize + MemMinSize)) return; + MEMORY_HEAP_NEXT(c) = e + 1; + _FreeAdd(fs, c); + } while(false); + MEMORY_HEAP_PREV(e) = c; + MEMORY_HEAP_NEXT(e) = 0; + block.Begin[1] = e; + } + + void RemoveBlock(TMemBlock block) + { + if (!BlockValid(block)) return; + TMemItem e = block.Begin[1]; + TFreeSpace &fs = *(TFreeSpace*)block.Begin[0]; + while ((e = MEMORY_HEAP_PREV(e)) != 0) + { + if (MEMORY_HEAP_FREE(e)) _FreeDel(fs, e); + } + block.Begin = 0; + } + +// Free space functions. + + void _CopyMemItemArray(TMemItem dest, TMemItem src, TMemItem end) + { + TMemItem k = (end - src) / sizeof(TMemItem); + TMemItem *d = (TMemItem*)dest; + TMemItem *s = (TMemItem*)src; + while (k--) *(d++) = *(s++); + } + + void *Alloc(TFreeSpace &fs, unsigned int size) + { + if (!size) return 0; + TMemItem s = MEMORY_HEAP_ALIGN_UP(size) + MemAddSize; + if (s < MemAddSize + MemMinSize) s = MemAddSize + MemMinSize; + TMemItem c = _FreeFind(fs, s); + if (!c) return 0; + _FreeDel(fs, c); + TMemItem nc = --MEMORY_HEAP_NEXT(c); + TMemItem mc = c + s; + if (nc - (MemAddSize + MemMinSize) >= mc) + { + MEMORY_HEAP_NEXT(c) = mc; + MEMORY_HEAP_PREV(mc) = c; + MEMORY_HEAP_NEXT(mc) = nc + 1; + MEMORY_HEAP_PREV(nc) = mc; + _FreeAdd(fs, mc); + } + return (void*)c; + } + + void *ReAlloc(TFreeSpace &fs, void *mem, unsigned int size) + { + if (!mem) return Alloc(fs, size); + if (!size) {Free(fs, mem); return 0;} + TMemItem s = MEMORY_HEAP_ALIGN_UP(size) + MemAddSize; + TMemItem c = (TMemItem)mem; + TMemItem mc = MEMORY_HEAP_NEXT(c); + TMemItem nc = MEMORY_HEAP_NEXT(mc); + if (--nc & 1) nc = mc; + if (s < MemAddSize + MemMinSize) s = MemAddSize + MemMinSize; + if (nc - c < s) + { + mem = Alloc(fs, size); + if (mem) + { + _CopyMemItemArray((TMemItem)mem, c, mc - MemAddSize); + Free(fs, (void*)c); + return mem; + } + else + { + TMemItem pc = MEMORY_HEAP_PREV(c); + if (pc && MEMORY_HEAP_FREE(pc) && nc - pc >= s) + { + _FreeDel(fs, pc); + _CopyMemItemArray(pc, c, mc - MemAddSize); + c = pc; + } + else return 0; + } + } + if (mc < nc) _FreeDel(fs, mc); + mc = c + s; + if (nc - (MemAddSize + MemMinSize) >= mc) + { + MEMORY_HEAP_NEXT(c) = mc; + MEMORY_HEAP_PREV(mc) = c; + MEMORY_HEAP_NEXT(mc) = nc + 1; + MEMORY_HEAP_PREV(nc) = mc; + _FreeAdd(fs, mc); + } + else + { + MEMORY_HEAP_NEXT(c) = nc; + MEMORY_HEAP_PREV(nc) = c; + } + return (void*)c; + } + + int free_a = 0; + + void Free(TFreeSpace &fs, void *mem) + { + TMemItem c = (TMemItem)mem; + if (!c) return; + TMemItem pc = MEMORY_HEAP_PREV(c); + TMemItem mc = MEMORY_HEAP_NEXT(c); + TMemItem nc = MEMORY_HEAP_NEXT(mc); + if (--nc & 1) nc = mc; + else _FreeDel(fs, mc); + if (free_a == 1) return; + if (pc && MEMORY_HEAP_FREE(pc)) _FreeDel(fs, c = pc); + MEMORY_HEAP_NEXT(c) = nc + 1; + MEMORY_HEAP_PREV(nc) = c; + if (free_a == 2) return; + _FreeAdd(fs, c); + } +} + +#endif // ndef __MEMORY_HEAP_RBTREE_H_INCLUDED_ + diff --git a/programs/games/checkers/trunk/include/menuet.h b/programs/games/checkers/trunk/include/menuet.h new file mode 100644 index 0000000000..74e0bff50f --- /dev/null +++ b/programs/games/checkers/trunk/include/menuet.h @@ -0,0 +1,536 @@ +#ifndef __MENUET_H_INCLUDED_ +#define __MENUET_H_INCLUDED_ + +#include + +// Menuet interface. + +namespace Menuet // All menuet functions, types and data are nested in the (Menuet) namespace. +{ + const char *DebugPrefix = "User program: "; + + struct TWindowData // Data for drawing a window. + { + unsigned short WindowType, HeaderType; + unsigned long WindowColor, HeaderColor, BorderColor, TitleColor; + const char *Title; + }; + + struct TStartData // This structure is used only for MenuetOnStart function. + { + unsigned short Left, Width, Top, Height; // Initial window rectangle. + TWindowData WinData; + }; + + typedef void **TThreadData; // Thread data are the fast identifier of thread, contains user dword in + //_ the zero element and stack beginning (or zero if it is unknown) in the first element. + //_ The stack will be deleted from dynamic memory at the finish of the thread if stack beginning is not zero. + + struct TMutex; // Simple mutex can be locked only once at a time. +#define MENUET_MUTEX_INIT {} // Simple mutex initializer, cat be redefined in a realization of the library + + struct TRecMutex; // Recursive mutex can be locked many times by a single thread at a time. +#define MENUET_REC_MUTEX_INIT {} // Recursive mutex initializer, cat be redefined in a realization of the library + + // Some functions have two forms: the fast form with (thread_data) parameter and the form without it. + // Note: pass only thread data of current thread as (thread_data) parameter to these functions. + + void Main(); // Main function is called at program startup. + void* ThreadMain(void *user = 0, void *stack_begin = 0); + // Called at thread startup, (user) is placed in thread data as a user dword, + //_ (stack_begin) is placed in thread data as a stack beginning. + //_ Return new value of stack beginning that can be changed in the thread data. + void GetWindowData(TWindowData &win_data); // Write current window data to (win_data). + void GetWindowData(TWindowData &win_data, TThreadData thread_data); + void SetWindowData(const TWindowData &win_data); // Replace current window data by (win_data). + void SetWindowData(const TWindowData &win_data, TThreadData thread_data); + void CloseWindow(); // Close current window when returning to message loop. + void CloseWindow(TThreadData thread_data); + void Redraw(int frame = 0); // Redraw current window immediately, if (frame) is positive redraw the frame too, + void Redraw(int frame, TThreadData thread_data); //_ if (frame) is negative redraw only invalideted window. + void Invalidate(int frame = 0); // Redraw current window when no message will be is the queue, + void Invalidate(int frame, TThreadData thread_data); //_ if (frame) is positive redraw the frame too, + //_ if (frame) is negative do nothing. + void MoveWindow(const int window_rect[/* 4 */]); // Move and resize current window. + + void Abort(); // Abnormally terminate a program. + void ExitProcess(); // Exit from the process, don't call any destructors of global varyables + void ExitThread(); // Exit from the current thread + void ExitThread(TThreadData thread_data); + void ReturnMessageLoop(); // Return to the message loop of the thread. Exit from the thread + void ReturnMessageLoop(TThreadData thread_data); //_ if it is called from (MenuetOnStart). + + void Delay(unsigned int time); // Delay the execution of the program during (time) hundredth seconds. + unsigned int Clock(); // Return the time from starting of the system to this moment in hundredth of seconds. + int GetPackedTime(); // Return the current time of day in binary-decimal format 0x00SSMMHH. + void GetTime(int t[/* 3 */]); // Write the current time to (t): t[0] = second, t[1] = minute, t[2] = hour. + int GetPackedDate(); // Return the current date in binary-decimal format 0x00YYDDMM. + void GetDate(int d[/* 3 */]); // Write the current date to (d): d[0] = day, d[1] = month, d[2] = year. + void GetTimeDate(int t[/* 6 */]); // Write the current time and date to (t): t[0] = second, + //_ t[1] = minute, t[2] = hour, t[3] = day, t[4] = month, t[5] = year. + void ReadCommonColors(unsigned int colors[/* 10 */]); // Writes standart window colors to (colors). + unsigned int GetProcessInfo(unsigned int *use_cpu, char process_name[/* 13 */], unsigned int *use_memory, + unsigned int *pid, int window_rect[/* 4 */], unsigned int pid_for = -1); + // Write (pid_for) process information to variables parameters points, return + //_ the number of processes. (pid_for) equal to (-1) means current process. + unsigned int GetPid(); // Return the current thread identifier (pid). + unsigned int GetPid(TThreadData thread_data); + TThreadData GetThreadData(); // Return the thread data of the current thread. + TThreadData GetThreadData(unsigned int pid); // Return the thread data of the thread with the given pid. + + void* GetPicture(unsigned short &width, unsigned short &height); + void* GetPicture(unsigned short &width, unsigned short &height, TThreadData thread_data); + // Return the picture on the window and write its width and height to (width) and (height). + void SetPicture(void *picture, unsigned short width, unsigned short height); + void SetPicture(void *picture, unsigned short width, unsigned short height, TThreadData thread_data); + // Replace the picture on the window by the given picture with the given width and height. + void GetBorderHeader(unsigned short &border_size, unsigned short &header_size); + void GetBorderHeader(unsigned short &border_size, unsigned short &header_size, TThreadData thread_data); + // Write the border thickness to (border_size) and header height to (header_size). + void GetClientSize(unsigned short &width, unsigned short &height); + void GetClientSize(unsigned short &width, unsigned short &height, TThreadData thread_data); + // Write the client area width and height to (width) and (height) parameters. + void GetClientSize(unsigned short &width, unsigned short &height, int win_width, int win_height); + void GetClientSize(unsigned short &width, unsigned short &height, int win_width, int win_height, TThreadData thread_data); + // Write the client area size of window with the width (win_width) + //_ and height (win_height) to (width) and (height) parameters. + void GetScreenSize(unsigned short &width, unsigned short &height); + // Write the screen width and height to (width) and (height) parameters. + + void InitMutex(TMutex *mutex); // Initialize the simple mutex. + void InitRecMutex(TRecMutex *mutex); // Initialize the recursive mutex. + bool TryLock(TMutex *mutex); // Try to lock the mutex without waitting, return true if lock. + bool TryLock(TRecMutex *mutex); + bool TryLock(TRecMutex *mutex, TThreadData thread_data); + bool TryLock(TRecMutex *mutex, unsigned int pid); + void Lock(TMutex *mutex); // Lock mutex and wait for it if this necessary. + void Lock(TRecMutex *mutex); + void Lock(TRecMutex *mutex, TThreadData thread_data); + void Lock(TRecMutex *mutex, unsigned int pid); + bool LockTime(TMutex *mutex, int time); + bool LockTime(TRecMutex *mutex, int time); // Lock mutex and wait for it during (time) hundredth seconds. + bool LockTime(TRecMutex *mutex, int time, TThreadData thread_data); + bool LockTime(TRecMutex *mutex, int time, unsigned int pid); + void UnLock(TMutex *mutex); // Unlock mutex + void UnLock(TRecMutex *mutex); + void UnLock(TRecMutex *mutex, TThreadData thread_data); + void UnLock(TRecMutex *mutex, unsigned int pid); + + void DebugPutChar(char c); // Put the character to the debug board. + void DebugPutString(const char *s); // Put the string to the debug board. + int GetKey(); // Return key pressed by user or -1 if no key was pressed. + int GetMouseButton(); // Return buttons pressed: 0 - no buttons, 1 - left button, 2 - right button, 3 - both buttons. + void GetMousePosition(short &x, short &y, bool absolute = false); + // Write mouse position to (x) and (y): absolute if (absolute) is true and relative the window otherwise. + void GetMousePosPicture(short &x, short &y); + + int GetThreadNumber(); // Return the number of threads currently executing. + bool WasThreadCreated(); // Return true if there was created at least one thread except the main thred. + unsigned int CreateThread(void *user = 0, unsigned int stack_size = 0, void *stack_end = 0); + // Create a new thread with the user dword (user) and stack pointer (stack_end). + //_ If (stack_end) is zero, create stack in dynamic memory of size (stack_size) or + //_ the same size as the main thread if (stack_size) less that 4096. Set the beginning + //_ of the stack if (stack_end) is zero or (stack_size) is not zero, in this case stack + //_ will be deleted automaticaly from dynamic memory at the finish of the thread. +} + +// Function, defined outside. + +bool MenuetOnStart(Menuet::TStartData &me_start, Menuet::TThreadData thread_data); + // Window will be created iff return value is true. +bool MenuetOnClose(Menuet::TThreadData thread_data); // Window will be closed iff return value is true. +int MenuetOnIdle(Menuet::TThreadData thread_data); // Return the time to wait next message. +void MenuetOnSize(int window_rect[/* 4 */], Menuet::TThreadData thread_data); // When the window is resized. +void MenuetOnKeyPress(Menuet::TThreadData thread_data); // When user press a key. +void MenuetOnMouse(Menuet::TThreadData thread_data); // When user move a mouse. + +#ifdef __MENUET__ + +namespace Menuet +{ +// Structures. + + struct TMutex // Simple mutex can be locked only once at a time. + { + unsigned int mut; + }; +#undef MENUET_MUTEX_INIT +#define MENUET_MUTEX_INIT {0x40} // Simple mutex initializer, cat be redefined in a realization of the library + + struct TRecMutex // Recursive mutex can be locked many times by a single thread at a time. + { + unsigned int mut, pid; + }; +#undef MENUET_REC_MUTEX_INIT +#define MENUET_REC_MUTEX_INIT {0x20,-1} // Recursive mutex initializer, cat be redefined in a realization of the library + +// Global variables. + + volatile TThreadData _ThreadTable[256]; + volatile unsigned int _ThreadScanCount[2] = {0, 0}; + volatile int _ThreadNumber = 1; + volatile int _ExitProcessNow = 0; + TMutex _ThreadMutex = MENUET_MUTEX_INIT; + unsigned int _ThreadSavedBegProc[4]; + +// Inline functions. + + inline void GetWindowData(TWindowData &win_data) {GetWindowData(win_data, GetThreadData());} + + inline void SetWindowData(const TWindowData &win_data) {SetWindowData(win_data, GetThreadData());} + + inline void CloseWindow() {CloseWindow(GetThreadData());} + + inline void Redraw(int frame) {Redraw(frame, GetThreadData());} + + inline void Invalidate(int frame) {Invalidate(frame, GetThreadData());} + + inline void* GetPicture(unsigned short &width, unsigned short &height) + { + return GetPicture(width, height, GetThreadData()); + } + + inline void SetPicture(void *picture, unsigned short width, unsigned short height) + { + SetPicture(picture, width, height, GetThreadData()); + } + + inline void GetBorderHeader(unsigned short &border_size, unsigned short &header_size) + { + GetBorderHeader(border_size, header_size, GetThreadData()); + } + + inline void GetClientSize(unsigned short &width, unsigned short &height) + { + unsigned int pid; + int rect[4]; + GetProcessInfo(0, 0, 0, &pid, rect); + GetClientSize(width, height, rect[2], rect[3], GetThreadData(pid)); + } + + inline void GetClientSize(unsigned short &width, unsigned short &height, TThreadData thread_data) + { + int rect[4]; + GetProcessInfo(0, 0, 0, 0, rect); + GetClientSize(width, height, rect[2], rect[3], thread_data); + } + + inline void GetClientSize(unsigned short &width, unsigned short &height, int win_width, int win_height) + { + GetClientSize(width, height, win_width, win_height, GetThreadData()); + } + + inline void GetTimeDate(int t[/* 6 */]) {GetTime(t); GetDate(t + 3);} + + inline void InitMutex(TMutex *mutex) {mutex->mut = 0;} + + inline void InitRecMutex(TRecMutex *mutex) {mutex->mut = 0; mutex->pid = -1;} + + inline bool TryLock(TRecMutex *mutex) {return TryLock(mutex, GetPid());} + + inline bool TryLock(TRecMutex *mutex, TThreadData thread_data) {return TryLock(mutex, GetPid(thread_data));} + + inline void Lock(TRecMutex *mutex) {Lock(mutex, GetPid());} + + inline void Lock(TRecMutex *mutex, TThreadData thread_data) {Lock(mutex, GetPid(thread_data));} + + inline bool LockTime(TRecMutex *mutex, int time) {return LockTime(mutex, time, GetPid());} + + inline bool LockTime(TRecMutex *mutex, int time, TThreadData thread_data) + {return LockTime(mutex, time, GetPid(thread_data));} + + inline void UnLock(TRecMutex *mutex) {UnLock(mutex, GetPid());} + + inline void UnLock(TRecMutex *mutex, TThreadData thread_data) {UnLock(mutex, GetPid(thread_data));} + + inline int GetThreadNumber() {return _ThreadNumber;} + +// Constants from fasm. + +#include + +// Functions. + + unsigned char _HashByte(unsigned int value); + unsigned short _HashWord(unsigned int value); + unsigned int _HashDword(unsigned int value); + + void _GetStartData(TStartData &start_data, TThreadData thread_data) + { + start_data.Left = (unsigned short)((unsigned long)thread_data[MENUET_THREAD_DATA_X] >> 16); + start_data.Width = (unsigned short)((unsigned long)thread_data[MENUET_THREAD_DATA_X]); + start_data.Top = (unsigned short)((unsigned long)thread_data[MENUET_THREAD_DATA_Y] >> 16); + start_data.Height = (unsigned short)((unsigned long)thread_data[MENUET_THREAD_DATA_Y]); + GetWindowData(start_data.WinData, thread_data); + } + + void _SetStartData(const TStartData &start_data, TThreadData thread_data) + { + (unsigned long&)thread_data[MENUET_THREAD_DATA_X] = + ((unsigned int)start_data.Left << 16) | start_data.Width; + (unsigned long&)thread_data[MENUET_THREAD_DATA_Y] = + ((unsigned int)start_data.Top << 16) | start_data.Height; + SetWindowData(start_data.WinData, thread_data); + } + + void _ApplyCommonColors(TWindowData &win_data) + { + unsigned int colors[10]; + ReadCommonColors(colors); + win_data.WindowColor = colors[5]; + win_data.HeaderColor = colors[1]; + win_data.BorderColor = colors[0]; + win_data.TitleColor = colors[4]; + } + + void _SetValueFunctionPriority(void *beg, int n) + { + int k, i; + unsigned char num[256]; + for (i = 0; i < 256; i++) num[i] = 0; + for (k = 0; k < n; k++) + { + i = ((unsigned char*)beg + 6*k)[1]; + ((unsigned char*)beg + 6*k)[0] = num[i]; + if (num[i] != 255) num[i]++; + } + } + + void _CallFunctionPriority(void *beg, void *end, bool reverse = false) + { + struct _Local + { + static int cmp(void *beg, int i, int j) + { + unsigned char *x = (unsigned char*)beg + 6*i; + unsigned char *y = (unsigned char*)beg + 6*j; + if (*(unsigned short*)x < *(unsigned short*)y) return -1; + if (*(unsigned short*)x > *(unsigned short*)y) return 1; + return 0; + } + + static void swap(void *beg, int i, int j) + { + unsigned char *x = (unsigned char*)beg + 6*i; + unsigned char *y = (unsigned char*)beg + 6*j; + short s; + int t; + s = *(short*)x; *(short*)x = *(short*)y; *(short*)y = s; + x += 2; y += 2; + t = *(int*)x; *(int*)x = *(int*)y; *(int*)y = t; + } + + static void call(void *beg, int i) + { + unsigned char *x = (unsigned char*)beg + 6*i; + (*(void(**)())(x+2))(); + } + }; + + if (!beg || !end || end <= beg) return; + int i, j, k, m, n; + n = ((unsigned char*)end - (unsigned char*)beg) / 6; + if (n <= 0) return; + _SetValueFunctionPriority(beg, n); + m = n; k = n; + while (m > 1) + { + if (k > 0) k--; + else _Local::swap(beg, 0, --m); + j = k; + for (;;) + { + i = j; + if (2*i + 1 >= m) break; + if (_Local::cmp(beg, 2*i + 1, j) > 0) j = 2*i + 1; + if (2*i + 2 < m && _Local::cmp(beg, 2*i + 2, j) > 0) j = 2*i + 2; + if (i == j) break; + _Local::swap(beg, i, j); + } + } + if (!reverse) + { + for (k = 0; k < n; k++) _Local::call(beg, k); + } + else + { + for (k = n-1; k >= 0; k--) _Local::call(beg, k); + } + } + + bool _CallStart(TThreadData thread_data, void *init = 0, void *init_end = 0) + { + struct _TThreadDataTemplate + { + unsigned int data[12]; + }; + static const _TThreadDataTemplate _ThreadDataTemplate = + {{3, 0x00320100, 0x00320100, 0x33FFFFFF, 0x806060FF, 0x00000000, 0x00FFFF40, 0, 0, 0, -1, -1}}; + + unsigned int pid = GetPid(); + volatile TThreadData *thread_table_item; + Lock(&_ThreadMutex); + if (_ExitProcessNow) ExitProcess(); + thread_table_item = &_ThreadTable[_HashByte(pid)]; + thread_data[MENUET_THREAD_DATA_NEXT] = (void*)*thread_table_item; + (unsigned int&)thread_data[MENUET_THREAD_DATA_PID] = pid; + *(_TThreadDataTemplate*)(thread_data + MENUET_THREAD_DATA_FLAG) = _ThreadDataTemplate; + *thread_table_item = thread_data; + UnLock(&_ThreadMutex); + if (_ExitProcessNow) ExitProcess(); + _CallFunctionPriority(init, init_end, false); + TStartData start_data; + _GetStartData(start_data, thread_data); +// _ApplyCommonColors(start_data.WinData); + (unsigned int&)thread_data[MENUET_THREAD_DATA_FLAG] |= 0x40000000; + thread_data[MENUET_THREAD_DATA_TITLE] = (void*)(&start_data); + if (!MenuetOnStart(start_data, thread_data)) return false; + (unsigned int&)thread_data[MENUET_THREAD_DATA_FLAG] &= ~0x40000000; + _SetStartData(start_data, thread_data); + return true; + } + + void _RemoveThreadData(TThreadData thread_data, void *exit = 0, void *exit_end = 0) + { + _CallFunctionPriority(exit, exit_end, true); + volatile TThreadData *thread_table_item; + Lock(&_ThreadMutex); + if (_ExitProcessNow) ExitProcess(); + thread_table_item = &_ThreadTable[_HashByte(GetPid(thread_data))]; + while (*thread_table_item) + { + if (*thread_table_item == thread_data) + { + *thread_table_item = (TThreadData)thread_data[MENUET_THREAD_DATA_NEXT]; + break; + } + thread_table_item = (TThreadData*)(*thread_table_item + MENUET_THREAD_DATA_NEXT); + } + UnLock(&_ThreadMutex); + if (_ExitProcessNow) ExitProcess(); + } + + void GetWindowData(TWindowData &win_data, TThreadData thread_data) + { + if ((unsigned int)thread_data[MENUET_THREAD_DATA_FLAG] & 0x40000000) + { + win_data = ((TStartData*)thread_data[MENUET_THREAD_DATA_TITLE])->WinData; + return; + } + win_data.WindowType = (unsigned short)((unsigned int)thread_data[MENUET_THREAD_DATA_C_WINDOW] >> 24); + win_data.HeaderType = (unsigned short)((unsigned int)thread_data[MENUET_THREAD_DATA_C_HEADER] >> 24); + win_data.WindowColor = (unsigned int)thread_data[MENUET_THREAD_DATA_C_WINDOW] & 0xFFFFFF; + win_data.HeaderColor = (unsigned int)thread_data[MENUET_THREAD_DATA_C_HEADER] & 0xFFFFFF; + win_data.BorderColor = (unsigned int)thread_data[MENUET_THREAD_DATA_C_BORDER] & 0xFFFFFF; + win_data.TitleColor = (unsigned int)thread_data[MENUET_THREAD_DATA_C_TITLE] & 0xFFFFFF; + win_data.Title = (char*)thread_data[MENUET_THREAD_DATA_TITLE]; + } + + void SetWindowData(const TWindowData &win_data, TThreadData thread_data) + { + if ((unsigned int)thread_data[MENUET_THREAD_DATA_FLAG] & 0x40000000) + { + ((TStartData*)thread_data[MENUET_THREAD_DATA_TITLE])->WinData = win_data; + return; + } + (unsigned int&)thread_data[MENUET_THREAD_DATA_C_WINDOW] = + ((unsigned int)win_data.WindowType << 24) | (win_data.WindowColor & 0xFFFFFF); + (unsigned int&)thread_data[MENUET_THREAD_DATA_C_HEADER] = + ((unsigned int)win_data.HeaderType << 24) | (win_data.HeaderColor & 0xFFFFFF); + (unsigned int&)thread_data[MENUET_THREAD_DATA_C_BORDER] = win_data.BorderColor & 0xFFFFFF; + (unsigned int&)thread_data[MENUET_THREAD_DATA_C_TITLE] = win_data.TitleColor & 0xFFFFFF; + thread_data[MENUET_THREAD_DATA_TITLE] = (void*)win_data.Title; + Invalidate(1, thread_data); + } + + void CloseWindow(TThreadData thread_data) + { + (unsigned int&)thread_data[MENUET_THREAD_DATA_FLAG] |= 0x80000000; + } + + void Invalidate(int frame, TThreadData thread_data) + { + if (frame < 0) return; + (unsigned int&)thread_data[MENUET_THREAD_DATA_FLAG] |= (frame ? 3 : 1); + } + + void* GetPicture(unsigned short &width, unsigned short &height, TThreadData thread_data) + { + width = (unsigned short)((unsigned int)thread_data[MENUET_THREAD_DATA_SZ_PICT] >> 16); + height = (unsigned short)((unsigned int)thread_data[MENUET_THREAD_DATA_SZ_PICT]); + return (void*)thread_data[MENUET_THREAD_DATA_PICTURE]; + } + + void SetPicture(void *picture, unsigned short width, unsigned short height, TThreadData thread_data) + { + thread_data[MENUET_THREAD_DATA_PICTURE] = (void*)picture; + (unsigned int&)thread_data[MENUET_THREAD_DATA_SZ_PICT] = + (width == 0 || height == 0) ? 0 : (((unsigned int)width << 16) | height); + Invalidate(0, thread_data); + } + + int _GetSkinHeader(); + + void GetBorderHeader(unsigned short &border_size, unsigned short &header_size, TThreadData thread_data) + { + int win_type = ((unsigned int)thread_data[MENUET_THREAD_DATA_FLAG] & 0x40000000) ? + ((TStartData*)thread_data[MENUET_THREAD_DATA_TITLE])->WinData.WindowType : + ((unsigned int)thread_data[MENUET_THREAD_DATA_C_WINDOW] >> 24); + border_size = MENUET_BORDER_SIZE; + header_size = short(((win_type & 15) == 3) ? _GetSkinHeader() : MENUET_HEADER_SIZE); + } + + void GetClientSize(unsigned short &width, unsigned short &height, + int win_width, int win_height, TThreadData thread_data) + { + const int MAX_SIZE = 32767; + unsigned short border_size, header_size; + GetBorderHeader(border_size, header_size, thread_data); + win_width -= 2 * border_size; + win_height -= border_size + header_size; + if (win_width < 0) win_width = 0; + else if (win_width > MAX_SIZE) win_width = MAX_SIZE; + if (win_height < 0) win_height = 0; + else if (win_height > MAX_SIZE) win_height = MAX_SIZE; + width = (unsigned short)win_width; + height = (unsigned short)win_height; + } + + void GetMousePosPicture(short &x, short &y) + { + unsigned short dx, dy; + GetMousePosition(x, y); + GetBorderHeader(dx, dy); + x -= dx; y -= dy; + } +} + +#else // def __MENUET__ + +namespace Menuet +{ + struct TMutex + { + unsigned int mut; + + TMutex(); + ~TMutex(); + }; +#undef MENUET_MUTEX_INIT +#define MENUET_MUTEX_INIT TMutex() + + struct TRecMutex + { + unsigned int mut; + + TRecMutex(); + ~TRecMutex(); + }; +#undef MENUET_REC_MUTEX_INIT +#define MENUET_REC_MUTEX_INIT TRecMutex() +} + +#endif // else: def __MENUET__ + +#endif // ndef __MENUET_H_INCLUDED_ + diff --git a/programs/games/checkers/trunk/include/stdarg.h b/programs/games/checkers/trunk/include/stdarg.h new file mode 100644 index 0000000000..7abd7592eb --- /dev/null +++ b/programs/games/checkers/trunk/include/stdarg.h @@ -0,0 +1,13 @@ +#ifndef __STDARG_H +#define __STDARG_H + +typedef void *va_list; + +#define __size(x) ((sizeof(x)+sizeof(int)-1) & ~(sizeof(int)-1)) + +#define va_start(ap, parmN) ((void)((ap) = (va_list)((char *)(&parmN)+__size(parmN)))) +#define va_arg(ap, type) (*(type *)(((*(char **)&(ap))+=__size(type))-(__size(type)))) +#define va_end(ap) ((void)0) + + +#endif /* __STDARG_H */ diff --git a/programs/games/checkers/trunk/include/write_macro.inc b/programs/games/checkers/trunk/include/write_macro.inc new file mode 100644 index 0000000000..3015f65896 --- /dev/null +++ b/programs/games/checkers/trunk/include/write_macro.inc @@ -0,0 +1,49 @@ +macro writestr [arg] +{ + common + + local straddr + local strend + pushad + push straddr + push strend + jmp @Menuet@DebugPutString$qpxc + straddr db arg,0 + strend: + pop eax + popad +} + +macro writeint arg +{ + push dword arg + xchg eax,[esp] + pushad + push eax + call @DebugPutNumber$qi + pop eax + popad + pop eax +} + +macro write [arg] +{ + forward + + if arg eq + else if arg eq endline + writestr 10 + else if arg eqtype '' + writestr arg + else + writeint arg + end if +} + +macro writeln [arg] +{ + common + + write arg,endline +} + diff --git a/programs/games/checkers/trunk/keysym.h b/programs/games/checkers/trunk/keysym.h new file mode 100644 index 0000000000..f120d49556 --- /dev/null +++ b/programs/games/checkers/trunk/keysym.h @@ -0,0 +1,2047 @@ +#ifndef _INCLUDE_KEY_SYM_H +#define _INCLUDE_KEY_SYM_H + +/* $Xorg: keysym.h,v 1.4 2001/02/09 02:03:23 xorgcvs Exp $ */ + +/*********************************************************** + +Copyright 1987, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ +/* $XFree86: xc/include/keysym.h,v 1.4 2001/12/14 19:53:26 dawes Exp $ */ + +/* default keysyms */ +#define XK_MISCELLANY +#define XK_XKB_KEYS +#define XK_LATIN1 +#define XK_LATIN2 +#define XK_LATIN3 +#define XK_LATIN4 +#define XK_LATIN8 +#define XK_LATIN9 +#define XK_CAUCASUS +#define XK_GREEK +#define XK_KATAKANA +#define XK_ARABIC +#define XK_CYRILLIC +#define XK_HEBREW +#define XK_THAI +#define XK_KOREAN +#define XK_ARMENIAN +#define XK_GEORGIAN +#define XK_VIETNAMESE +#define XK_CURRENCY + + + +/* keysym definitions */ + +#define XK_VoidSymbol 0xFFFFFF /* void symbol */ + +#ifdef XK_MISCELLANY +/* + * TTY Functions, cleverly chosen to map to ascii, for convenience of + * programming, but could have been arbitrary (at the cost of lookup + * tables in client code. + */ + +#define XK_BackSpace 0xFF08 /* back space, back char */ +#define XK_Tab 0xFF09 +#define XK_Linefeed 0xFF0A /* Linefeed, LF */ +#define XK_Clear 0xFF0B +#define XK_Return 0xFF0D /* Return, enter */ +#define XK_Pause 0xFF13 /* Pause, hold */ +#define XK_Scroll_Lock 0xFF14 +#define XK_Sys_Req 0xFF15 +#define XK_Escape 0xFF1B +#define XK_Delete 0xFFFF /* Delete, rubout */ + + + +/* International & multi-key character composition */ + +#define XK_Multi_key 0xFF20 /* Multi-key character compose */ +#define XK_Codeinput 0xFF37 +#define XK_SingleCandidate 0xFF3C +#define XK_MultipleCandidate 0xFF3D +#define XK_PreviousCandidate 0xFF3E + +/* Japanese keyboard support */ + +#define XK_Kanji 0xFF21 /* Kanji, Kanji convert */ +#define XK_Muhenkan 0xFF22 /* Cancel Conversion */ +#define XK_Henkan_Mode 0xFF23 /* Start/Stop Conversion */ +#define XK_Henkan 0xFF23 /* Alias for Henkan_Mode */ +#define XK_Romaji 0xFF24 /* to Romaji */ +#define XK_Hiragana 0xFF25 /* to Hiragana */ +#define XK_Katakana 0xFF26 /* to Katakana */ +#define XK_Hiragana_Katakana 0xFF27 /* Hiragana/Katakana toggle */ +#define XK_Zenkaku 0xFF28 /* to Zenkaku */ +#define XK_Hankaku 0xFF29 /* to Hankaku */ +#define XK_Zenkaku_Hankaku 0xFF2A /* Zenkaku/Hankaku toggle */ +#define XK_Touroku 0xFF2B /* Add to Dictionary */ +#define XK_Massyo 0xFF2C /* Delete from Dictionary */ +#define XK_Kana_Lock 0xFF2D /* Kana Lock */ +#define XK_Kana_Shift 0xFF2E /* Kana Shift */ +#define XK_Eisu_Shift 0xFF2F /* Alphanumeric Shift */ +#define XK_Eisu_toggle 0xFF30 /* Alphanumeric toggle */ +#define XK_Kanji_Bangou 0xFF37 /* Codeinput */ +#define XK_Zen_Koho 0xFF3D /* Multiple/All Candidate(s) */ +#define XK_Mae_Koho 0xFF3E /* Previous Candidate */ + +/* 0xFF31 thru 0xFF3F are under XK_KOREAN */ + +/* Cursor control & motion */ + +#define XK_Home 0xFF50 +#define XK_Left 0xFF51 /* Move left, left arrow */ +#define XK_Up 0xFF52 /* Move up, up arrow */ +#define XK_Right 0xFF53 /* Move right, right arrow */ +#define XK_Down 0xFF54 /* Move down, down arrow */ +#define XK_Prior 0xFF55 /* Prior, previous */ +#define XK_Page_Up 0xFF55 +#define XK_Next 0xFF56 /* Next */ +#define XK_Page_Down 0xFF56 +#define XK_End 0xFF57 /* EOL */ +#define XK_Begin 0xFF58 /* BOL */ + + +/* Misc Functions */ + +#define XK_Select 0xFF60 /* Select, mark */ +#define XK_Print 0xFF61 +#define XK_Execute 0xFF62 /* Execute, run, do */ +#define XK_Insert 0xFF63 /* Insert, insert here */ +#define XK_Undo 0xFF65 /* Undo, oops */ +#define XK_Redo 0xFF66 /* redo, again */ +#define XK_Menu 0xFF67 +#define XK_Find 0xFF68 /* Find, search */ +#define XK_Cancel 0xFF69 /* Cancel, stop, abort, exit */ +#define XK_Help 0xFF6A /* Help */ +#define XK_Break 0xFF6B +#define XK_Mode_switch 0xFF7E /* Character set switch */ +#define XK_script_switch 0xFF7E /* Alias for mode_switch */ +#define XK_Num_Lock 0xFF7F + +/* Keypad Functions, keypad numbers cleverly chosen to map to ascii */ + +#define XK_KP_Space 0xFF80 /* space */ +#define XK_KP_Tab 0xFF89 +#define XK_KP_Enter 0xFF8D /* enter */ +#define XK_KP_F1 0xFF91 /* PF1, KP_A, ... */ +#define XK_KP_F2 0xFF92 +#define XK_KP_F3 0xFF93 +#define XK_KP_F4 0xFF94 +#define XK_KP_Home 0xFF95 +#define XK_KP_Left 0xFF96 +#define XK_KP_Up 0xFF97 +#define XK_KP_Right 0xFF98 +#define XK_KP_Down 0xFF99 +#define XK_KP_Prior 0xFF9A +#define XK_KP_Page_Up 0xFF9A +#define XK_KP_Next 0xFF9B +#define XK_KP_Page_Down 0xFF9B +#define XK_KP_End 0xFF9C +#define XK_KP_Begin 0xFF9D +#define XK_KP_Insert 0xFF9E +#define XK_KP_Delete 0xFF9F +#define XK_KP_Equal 0xFFBD /* equals */ +#define XK_KP_Multiply 0xFFAA +#define XK_KP_Add 0xFFAB +#define XK_KP_Separator 0xFFAC /* separator, often comma */ +#define XK_KP_Subtract 0xFFAD +#define XK_KP_Decimal 0xFFAE +#define XK_KP_Divide 0xFFAF + +#define XK_KP_0 0xFFB0 +#define XK_KP_1 0xFFB1 +#define XK_KP_2 0xFFB2 +#define XK_KP_3 0xFFB3 +#define XK_KP_4 0xFFB4 +#define XK_KP_5 0xFFB5 +#define XK_KP_6 0xFFB6 +#define XK_KP_7 0xFFB7 +#define XK_KP_8 0xFFB8 +#define XK_KP_9 0xFFB9 + + + +/* + * Auxilliary Functions; note the duplicate definitions for left and right + * function keys; Sun keyboards and a few other manufactures have such + * function key groups on the left and/or right sides of the keyboard. + * We've not found a keyboard with more than 35 function keys total. + */ + +#define XK_F1 0xFFBE +#define XK_F2 0xFFBF +#define XK_F3 0xFFC0 +#define XK_F4 0xFFC1 +#define XK_F5 0xFFC2 +#define XK_F6 0xFFC3 +#define XK_F7 0xFFC4 +#define XK_F8 0xFFC5 +#define XK_F9 0xFFC6 +#define XK_F10 0xFFC7 +#define XK_F11 0xFFC8 +#define XK_L1 0xFFC8 +#define XK_F12 0xFFC9 +#define XK_L2 0xFFC9 +#define XK_F13 0xFFCA +#define XK_L3 0xFFCA +#define XK_F14 0xFFCB +#define XK_L4 0xFFCB +#define XK_F15 0xFFCC +#define XK_L5 0xFFCC +#define XK_F16 0xFFCD +#define XK_L6 0xFFCD +#define XK_F17 0xFFCE +#define XK_L7 0xFFCE +#define XK_F18 0xFFCF +#define XK_L8 0xFFCF +#define XK_F19 0xFFD0 +#define XK_L9 0xFFD0 +#define XK_F20 0xFFD1 +#define XK_L10 0xFFD1 +#define XK_F21 0xFFD2 +#define XK_R1 0xFFD2 +#define XK_F22 0xFFD3 +#define XK_R2 0xFFD3 +#define XK_F23 0xFFD4 +#define XK_R3 0xFFD4 +#define XK_F24 0xFFD5 +#define XK_R4 0xFFD5 +#define XK_F25 0xFFD6 +#define XK_R5 0xFFD6 +#define XK_F26 0xFFD7 +#define XK_R6 0xFFD7 +#define XK_F27 0xFFD8 +#define XK_R7 0xFFD8 +#define XK_F28 0xFFD9 +#define XK_R8 0xFFD9 +#define XK_F29 0xFFDA +#define XK_R9 0xFFDA +#define XK_F30 0xFFDB +#define XK_R10 0xFFDB +#define XK_F31 0xFFDC +#define XK_R11 0xFFDC +#define XK_F32 0xFFDD +#define XK_R12 0xFFDD +#define XK_F33 0xFFDE +#define XK_R13 0xFFDE +#define XK_F34 0xFFDF +#define XK_R14 0xFFDF +#define XK_F35 0xFFE0 +#define XK_R15 0xFFE0 + +/* Modifiers */ + +#define XK_Shift_L 0xFFE1 /* Left shift */ +#define XK_Shift_R 0xFFE2 /* Right shift */ +#define XK_Control_L 0xFFE3 /* Left control */ +#define XK_Control_R 0xFFE4 /* Right control */ +#define XK_Caps_Lock 0xFFE5 /* Caps lock */ +#define XK_Shift_Lock 0xFFE6 /* Shift lock */ + +#define XK_Meta_L 0xFFE7 /* Left meta */ +#define XK_Meta_R 0xFFE8 /* Right meta */ +#define XK_Alt_L 0xFFE9 /* Left alt */ +#define XK_Alt_R 0xFFEA /* Right alt */ +#define XK_Super_L 0xFFEB /* Left super */ +#define XK_Super_R 0xFFEC /* Right super */ +#define XK_Hyper_L 0xFFED /* Left hyper */ +#define XK_Hyper_R 0xFFEE /* Right hyper */ +#endif /* XK_MISCELLANY */ + +/* + * ISO 9995 Function and Modifier Keys + * Byte 3 = 0xFE + */ + +#ifdef XK_XKB_KEYS +#define XK_ISO_Lock 0xFE01 +#define XK_ISO_Level2_Latch 0xFE02 +#define XK_ISO_Level3_Shift 0xFE03 +#define XK_ISO_Level3_Latch 0xFE04 +#define XK_ISO_Level3_Lock 0xFE05 +#define XK_ISO_Group_Shift 0xFF7E /* Alias for mode_switch */ +#define XK_ISO_Group_Latch 0xFE06 +#define XK_ISO_Group_Lock 0xFE07 +#define XK_ISO_Next_Group 0xFE08 +#define XK_ISO_Next_Group_Lock 0xFE09 +#define XK_ISO_Prev_Group 0xFE0A +#define XK_ISO_Prev_Group_Lock 0xFE0B +#define XK_ISO_First_Group 0xFE0C +#define XK_ISO_First_Group_Lock 0xFE0D +#define XK_ISO_Last_Group 0xFE0E +#define XK_ISO_Last_Group_Lock 0xFE0F + +#define XK_ISO_Left_Tab 0xFE20 +#define XK_ISO_Move_Line_Up 0xFE21 +#define XK_ISO_Move_Line_Down 0xFE22 +#define XK_ISO_Partial_Line_Up 0xFE23 +#define XK_ISO_Partial_Line_Down 0xFE24 +#define XK_ISO_Partial_Space_Left 0xFE25 +#define XK_ISO_Partial_Space_Right 0xFE26 +#define XK_ISO_Set_Margin_Left 0xFE27 +#define XK_ISO_Set_Margin_Right 0xFE28 +#define XK_ISO_Release_Margin_Left 0xFE29 +#define XK_ISO_Release_Margin_Right 0xFE2A +#define XK_ISO_Release_Both_Margins 0xFE2B +#define XK_ISO_Fast_Cursor_Left 0xFE2C +#define XK_ISO_Fast_Cursor_Right 0xFE2D +#define XK_ISO_Fast_Cursor_Up 0xFE2E +#define XK_ISO_Fast_Cursor_Down 0xFE2F +#define XK_ISO_Continuous_Underline 0xFE30 +#define XK_ISO_Discontinuous_Underline 0xFE31 +#define XK_ISO_Emphasize 0xFE32 +#define XK_ISO_Center_Object 0xFE33 +#define XK_ISO_Enter 0xFE34 + +#define XK_dead_grave 0xFE50 +#define XK_dead_acute 0xFE51 +#define XK_dead_circumflex 0xFE52 +#define XK_dead_tilde 0xFE53 +#define XK_dead_macron 0xFE54 +#define XK_dead_breve 0xFE55 +#define XK_dead_abovedot 0xFE56 +#define XK_dead_diaeresis 0xFE57 +#define XK_dead_abovering 0xFE58 +#define XK_dead_doubleacute 0xFE59 +#define XK_dead_caron 0xFE5A +#define XK_dead_cedilla 0xFE5B +#define XK_dead_ogonek 0xFE5C +#define XK_dead_iota 0xFE5D +#define XK_dead_voiced_sound 0xFE5E +#define XK_dead_semivoiced_sound 0xFE5F +#define XK_dead_belowdot 0xFE60 +#define XK_dead_hook 0xFE61 +#define XK_dead_horn 0xFE62 + +#define XK_First_Virtual_Screen 0xFED0 +#define XK_Prev_Virtual_Screen 0xFED1 +#define XK_Next_Virtual_Screen 0xFED2 +#define XK_Last_Virtual_Screen 0xFED4 +#define XK_Terminate_Server 0xFED5 + +#define XK_AccessX_Enable 0xFE70 +#define XK_AccessX_Feedback_Enable 0xFE71 +#define XK_RepeatKeys_Enable 0xFE72 +#define XK_SlowKeys_Enable 0xFE73 +#define XK_BounceKeys_Enable 0xFE74 +#define XK_StickyKeys_Enable 0xFE75 +#define XK_MouseKeys_Enable 0xFE76 +#define XK_MouseKeys_Accel_Enable 0xFE77 +#define XK_Overlay1_Enable 0xFE78 +#define XK_Overlay2_Enable 0xFE79 +#define XK_AudibleBell_Enable 0xFE7A + +#define XK_Pointer_Left 0xFEE0 +#define XK_Pointer_Right 0xFEE1 +#define XK_Pointer_Up 0xFEE2 +#define XK_Pointer_Down 0xFEE3 +#define XK_Pointer_UpLeft 0xFEE4 +#define XK_Pointer_UpRight 0xFEE5 +#define XK_Pointer_DownLeft 0xFEE6 +#define XK_Pointer_DownRight 0xFEE7 +#define XK_Pointer_Button_Dflt 0xFEE8 +#define XK_Pointer_Button1 0xFEE9 +#define XK_Pointer_Button2 0xFEEA +#define XK_Pointer_Button3 0xFEEB +#define XK_Pointer_Button4 0xFEEC +#define XK_Pointer_Button5 0xFEED +#define XK_Pointer_DblClick_Dflt 0xFEEE +#define XK_Pointer_DblClick1 0xFEEF +#define XK_Pointer_DblClick2 0xFEF0 +#define XK_Pointer_DblClick3 0xFEF1 +#define XK_Pointer_DblClick4 0xFEF2 +#define XK_Pointer_DblClick5 0xFEF3 +#define XK_Pointer_Drag_Dflt 0xFEF4 +#define XK_Pointer_Drag1 0xFEF5 +#define XK_Pointer_Drag2 0xFEF6 +#define XK_Pointer_Drag3 0xFEF7 +#define XK_Pointer_Drag4 0xFEF8 +#define XK_Pointer_Drag5 0xFEFD + +#define XK_Pointer_EnableKeys 0xFEF9 +#define XK_Pointer_Accelerate 0xFEFA +#define XK_Pointer_DfltBtnNext 0xFEFB +#define XK_Pointer_DfltBtnPrev 0xFEFC + +#endif + +/* + * 3270 Terminal Keys + * Byte 3 = 0xFD + */ + +#ifdef XK_3270 +#define XK_3270_Duplicate 0xFD01 +#define XK_3270_FieldMark 0xFD02 +#define XK_3270_Right2 0xFD03 +#define XK_3270_Left2 0xFD04 +#define XK_3270_BackTab 0xFD05 +#define XK_3270_EraseEOF 0xFD06 +#define XK_3270_EraseInput 0xFD07 +#define XK_3270_Reset 0xFD08 +#define XK_3270_Quit 0xFD09 +#define XK_3270_PA1 0xFD0A +#define XK_3270_PA2 0xFD0B +#define XK_3270_PA3 0xFD0C +#define XK_3270_Test 0xFD0D +#define XK_3270_Attn 0xFD0E +#define XK_3270_CursorBlink 0xFD0F +#define XK_3270_AltCursor 0xFD10 +#define XK_3270_KeyClick 0xFD11 +#define XK_3270_Jump 0xFD12 +#define XK_3270_Ident 0xFD13 +#define XK_3270_Rule 0xFD14 +#define XK_3270_Copy 0xFD15 +#define XK_3270_Play 0xFD16 +#define XK_3270_Setup 0xFD17 +#define XK_3270_Record 0xFD18 +#define XK_3270_ChangeScreen 0xFD19 +#define XK_3270_DeleteWord 0xFD1A +#define XK_3270_ExSelect 0xFD1B +#define XK_3270_CursorSelect 0xFD1C +#define XK_3270_PrintScreen 0xFD1D +#define XK_3270_Enter 0xFD1E +#endif + +/* + * Latin 1 + * Byte 3 = 0 + */ +#ifdef XK_LATIN1 +#define XK_space 0x020 +#define XK_exclam 0x021 +#define XK_quotedbl 0x022 +#define XK_numbersign 0x023 +#define XK_dollar 0x024 +#define XK_percent 0x025 +#define XK_ampersand 0x026 +#define XK_apostrophe 0x027 +#define XK_quoteright 0x027 /* deprecated */ +#define XK_parenleft 0x028 +#define XK_parenright 0x029 +#define XK_asterisk 0x02a +#define XK_plus 0x02b +#define XK_comma 0x02c +#define XK_minus 0x02d +#define XK_period 0x02e +#define XK_slash 0x02f +#define XK_0 0x030 +#define XK_1 0x031 +#define XK_2 0x032 +#define XK_3 0x033 +#define XK_4 0x034 +#define XK_5 0x035 +#define XK_6 0x036 +#define XK_7 0x037 +#define XK_8 0x038 +#define XK_9 0x039 +#define XK_colon 0x03a +#define XK_semicolon 0x03b +#define XK_less 0x03c +#define XK_equal 0x03d +#define XK_greater 0x03e +#define XK_question 0x03f +#define XK_at 0x040 +#define XK_A 0x041 +#define XK_B 0x042 +#define XK_C 0x043 +#define XK_D 0x044 +#define XK_E 0x045 +#define XK_F 0x046 +#define XK_G 0x047 +#define XK_H 0x048 +#define XK_I 0x049 +#define XK_J 0x04a +#define XK_K 0x04b +#define XK_L 0x04c +#define XK_M 0x04d +#define XK_N 0x04e +#define XK_O 0x04f +#define XK_P 0x050 +#define XK_Q 0x051 +#define XK_R 0x052 +#define XK_S 0x053 +#define XK_T 0x054 +#define XK_U 0x055 +#define XK_V 0x056 +#define XK_W 0x057 +#define XK_X 0x058 +#define XK_Y 0x059 +#define XK_Z 0x05a +#define XK_bracketleft 0x05b +#define XK_backslash 0x05c +#define XK_bracketright 0x05d +#define XK_asciicircum 0x05e +#define XK_underscore 0x05f +#define XK_grave 0x060 +#define XK_quoteleft 0x060 /* deprecated */ +#define XK_a 0x061 +#define XK_b 0x062 +#define XK_c 0x063 +#define XK_d 0x064 +#define XK_e 0x065 +#define XK_f 0x066 +#define XK_g 0x067 +#define XK_h 0x068 +#define XK_i 0x069 +#define XK_j 0x06a +#define XK_k 0x06b +#define XK_l 0x06c +#define XK_m 0x06d +#define XK_n 0x06e +#define XK_o 0x06f +#define XK_p 0x070 +#define XK_q 0x071 +#define XK_r 0x072 +#define XK_s 0x073 +#define XK_t 0x074 +#define XK_u 0x075 +#define XK_v 0x076 +#define XK_w 0x077 +#define XK_x 0x078 +#define XK_y 0x079 +#define XK_z 0x07a +#define XK_braceleft 0x07b +#define XK_bar 0x07c +#define XK_braceright 0x07d +#define XK_asciitilde 0x07e + +#define XK_nobreakspace 0x0a0 +#define XK_exclamdown 0x0a1 +#define XK_cent 0x0a2 +#define XK_sterling 0x0a3 +#define XK_currency 0x0a4 +#define XK_yen 0x0a5 +#define XK_brokenbar 0x0a6 +#define XK_section 0x0a7 +#define XK_diaeresis 0x0a8 +#define XK_copyright 0x0a9 +#define XK_ordfeminine 0x0aa +#define XK_guillemotleft 0x0ab /* left angle quotation mark */ +#define XK_notsign 0x0ac +#define XK_hyphen 0x0ad +#define XK_registered 0x0ae +#define XK_macron 0x0af +#define XK_degree 0x0b0 +#define XK_plusminus 0x0b1 +#define XK_twosuperior 0x0b2 +#define XK_threesuperior 0x0b3 +#define XK_acute 0x0b4 +#define XK_mu 0x0b5 +#define XK_paragraph 0x0b6 +#define XK_periodcentered 0x0b7 +#define XK_cedilla 0x0b8 +#define XK_onesuperior 0x0b9 +#define XK_masculine 0x0ba +#define XK_guillemotright 0x0bb /* right angle quotation mark */ +#define XK_onequarter 0x0bc +#define XK_onehalf 0x0bd +#define XK_threequarters 0x0be +#define XK_questiondown 0x0bf +#define XK_Agrave 0x0c0 +#define XK_Aacute 0x0c1 +#define XK_Acircumflex 0x0c2 +#define XK_Atilde 0x0c3 +#define XK_Adiaeresis 0x0c4 +#define XK_Aring 0x0c5 +#define XK_AE 0x0c6 +#define XK_Ccedilla 0x0c7 +#define XK_Egrave 0x0c8 +#define XK_Eacute 0x0c9 +#define XK_Ecircumflex 0x0ca +#define XK_Ediaeresis 0x0cb +#define XK_Igrave 0x0cc +#define XK_Iacute 0x0cd +#define XK_Icircumflex 0x0ce +#define XK_Idiaeresis 0x0cf +#define XK_ETH 0x0d0 +#define XK_Eth 0x0d0 /* deprecated */ +#define XK_Ntilde 0x0d1 +#define XK_Ograve 0x0d2 +#define XK_Oacute 0x0d3 +#define XK_Ocircumflex 0x0d4 +#define XK_Otilde 0x0d5 +#define XK_Odiaeresis 0x0d6 +#define XK_multiply 0x0d7 +#define XK_Ooblique 0x0d8 +#define XK_Oslash XK_Ooblique +#define XK_Ugrave 0x0d9 +#define XK_Uacute 0x0da +#define XK_Ucircumflex 0x0db +#define XK_Udiaeresis 0x0dc +#define XK_Yacute 0x0dd +#define XK_THORN 0x0de +#define XK_Thorn 0x0de /* deprecated */ +#define XK_ssharp 0x0df +#define XK_agrave 0x0e0 +#define XK_aacute 0x0e1 +#define XK_acircumflex 0x0e2 +#define XK_atilde 0x0e3 +#define XK_adiaeresis 0x0e4 +#define XK_aring 0x0e5 +#define XK_ae 0x0e6 +#define XK_ccedilla 0x0e7 +#define XK_egrave 0x0e8 +#define XK_eacute 0x0e9 +#define XK_ecircumflex 0x0ea +#define XK_ediaeresis 0x0eb +#define XK_igrave 0x0ec +#define XK_iacute 0x0ed +#define XK_icircumflex 0x0ee +#define XK_idiaeresis 0x0ef +#define XK_eth 0x0f0 +#define XK_ntilde 0x0f1 +#define XK_ograve 0x0f2 +#define XK_oacute 0x0f3 +#define XK_ocircumflex 0x0f4 +#define XK_otilde 0x0f5 +#define XK_odiaeresis 0x0f6 +#define XK_division 0x0f7 +#define XK_oslash 0x0f8 +#define XK_ooblique XK_oslash +#define XK_ugrave 0x0f9 +#define XK_uacute 0x0fa +#define XK_ucircumflex 0x0fb +#define XK_udiaeresis 0x0fc +#define XK_yacute 0x0fd +#define XK_thorn 0x0fe +#define XK_ydiaeresis 0x0ff +#endif /* XK_LATIN1 */ + +/* + * Latin 2 + * Byte 3 = 1 + */ + +#ifdef XK_LATIN2 +#define XK_Aogonek 0x1a1 +#define XK_breve 0x1a2 +#define XK_Lstroke 0x1a3 +#define XK_Lcaron 0x1a5 +#define XK_Sacute 0x1a6 +#define XK_Scaron 0x1a9 +#define XK_Scedilla 0x1aa +#define XK_Tcaron 0x1ab +#define XK_Zacute 0x1ac +#define XK_Zcaron 0x1ae +#define XK_Zabovedot 0x1af +#define XK_aogonek 0x1b1 +#define XK_ogonek 0x1b2 +#define XK_lstroke 0x1b3 +#define XK_lcaron 0x1b5 +#define XK_sacute 0x1b6 +#define XK_caron 0x1b7 +#define XK_scaron 0x1b9 +#define XK_scedilla 0x1ba +#define XK_tcaron 0x1bb +#define XK_zacute 0x1bc +#define XK_doubleacute 0x1bd +#define XK_zcaron 0x1be +#define XK_zabovedot 0x1bf +#define XK_Racute 0x1c0 +#define XK_Abreve 0x1c3 +#define XK_Lacute 0x1c5 +#define XK_Cacute 0x1c6 +#define XK_Ccaron 0x1c8 +#define XK_Eogonek 0x1ca +#define XK_Ecaron 0x1cc +#define XK_Dcaron 0x1cf +#define XK_Dstroke 0x1d0 +#define XK_Nacute 0x1d1 +#define XK_Ncaron 0x1d2 +#define XK_Odoubleacute 0x1d5 +#define XK_Rcaron 0x1d8 +#define XK_Uring 0x1d9 +#define XK_Udoubleacute 0x1db +#define XK_Tcedilla 0x1de +#define XK_racute 0x1e0 +#define XK_abreve 0x1e3 +#define XK_lacute 0x1e5 +#define XK_cacute 0x1e6 +#define XK_ccaron 0x1e8 +#define XK_eogonek 0x1ea +#define XK_ecaron 0x1ec +#define XK_dcaron 0x1ef +#define XK_dstroke 0x1f0 +#define XK_nacute 0x1f1 +#define XK_ncaron 0x1f2 +#define XK_odoubleacute 0x1f5 +#define XK_udoubleacute 0x1fb +#define XK_rcaron 0x1f8 +#define XK_uring 0x1f9 +#define XK_tcedilla 0x1fe +#define XK_abovedot 0x1ff +#endif /* XK_LATIN2 */ + +/* + * Latin 3 + * Byte 3 = 2 + */ + +#ifdef XK_LATIN3 +#define XK_Hstroke 0x2a1 +#define XK_Hcircumflex 0x2a6 +#define XK_Iabovedot 0x2a9 +#define XK_Gbreve 0x2ab +#define XK_Jcircumflex 0x2ac +#define XK_hstroke 0x2b1 +#define XK_hcircumflex 0x2b6 +#define XK_idotless 0x2b9 +#define XK_gbreve 0x2bb +#define XK_jcircumflex 0x2bc +#define XK_Cabovedot 0x2c5 +#define XK_Ccircumflex 0x2c6 +#define XK_Gabovedot 0x2d5 +#define XK_Gcircumflex 0x2d8 +#define XK_Ubreve 0x2dd +#define XK_Scircumflex 0x2de +#define XK_cabovedot 0x2e5 +#define XK_ccircumflex 0x2e6 +#define XK_gabovedot 0x2f5 +#define XK_gcircumflex 0x2f8 +#define XK_ubreve 0x2fd +#define XK_scircumflex 0x2fe +#endif /* XK_LATIN3 */ + + +/* + * Latin 4 + * Byte 3 = 3 + */ + +#ifdef XK_LATIN4 +#define XK_kra 0x3a2 +#define XK_kappa 0x3a2 /* deprecated */ +#define XK_Rcedilla 0x3a3 +#define XK_Itilde 0x3a5 +#define XK_Lcedilla 0x3a6 +#define XK_Emacron 0x3aa +#define XK_Gcedilla 0x3ab +#define XK_Tslash 0x3ac +#define XK_rcedilla 0x3b3 +#define XK_itilde 0x3b5 +#define XK_lcedilla 0x3b6 +#define XK_emacron 0x3ba +#define XK_gcedilla 0x3bb +#define XK_tslash 0x3bc +#define XK_ENG 0x3bd +#define XK_eng 0x3bf +#define XK_Amacron 0x3c0 +#define XK_Iogonek 0x3c7 +#define XK_Eabovedot 0x3cc +#define XK_Imacron 0x3cf +#define XK_Ncedilla 0x3d1 +#define XK_Omacron 0x3d2 +#define XK_Kcedilla 0x3d3 +#define XK_Uogonek 0x3d9 +#define XK_Utilde 0x3dd +#define XK_Umacron 0x3de +#define XK_amacron 0x3e0 +#define XK_iogonek 0x3e7 +#define XK_eabovedot 0x3ec +#define XK_imacron 0x3ef +#define XK_ncedilla 0x3f1 +#define XK_omacron 0x3f2 +#define XK_kcedilla 0x3f3 +#define XK_uogonek 0x3f9 +#define XK_utilde 0x3fd +#define XK_umacron 0x3fe +#endif /* XK_LATIN4 */ + +/* + * Latin-8 + * Byte 3 = 18 + */ +#ifdef XK_LATIN8 +#define XK_Babovedot 0x12a1 +#define XK_babovedot 0x12a2 +#define XK_Dabovedot 0x12a6 +#define XK_Wgrave 0x12a8 +#define XK_Wacute 0x12aa +#define XK_dabovedot 0x12ab +#define XK_Ygrave 0x12ac +#define XK_Fabovedot 0x12b0 +#define XK_fabovedot 0x12b1 +#define XK_Mabovedot 0x12b4 +#define XK_mabovedot 0x12b5 +#define XK_Pabovedot 0x12b7 +#define XK_wgrave 0x12b8 +#define XK_pabovedot 0x12b9 +#define XK_wacute 0x12ba +#define XK_Sabovedot 0x12bb +#define XK_ygrave 0x12bc +#define XK_Wdiaeresis 0x12bd +#define XK_wdiaeresis 0x12be +#define XK_sabovedot 0x12bf +#define XK_Wcircumflex 0x12d0 +#define XK_Tabovedot 0x12d7 +#define XK_Ycircumflex 0x12de +#define XK_wcircumflex 0x12f0 +#define XK_tabovedot 0x12f7 +#define XK_ycircumflex 0x12fe +#endif /* XK_LATIN8 */ + +/* + * Latin-9 (a.k.a. Latin-0) + * Byte 3 = 19 + */ + +#ifdef XK_LATIN9 +#define XK_OE 0x13bc +#define XK_oe 0x13bd +#define XK_Ydiaeresis 0x13be +#endif /* XK_LATIN9 */ + +/* + * Katakana + * Byte 3 = 4 + */ + +#ifdef XK_KATAKANA +#define XK_overline 0x47e +#define XK_kana_fullstop 0x4a1 +#define XK_kana_openingbracket 0x4a2 +#define XK_kana_closingbracket 0x4a3 +#define XK_kana_comma 0x4a4 +#define XK_kana_conjunctive 0x4a5 +#define XK_kana_middledot 0x4a5 /* deprecated */ +#define XK_kana_WO 0x4a6 +#define XK_kana_a 0x4a7 +#define XK_kana_i 0x4a8 +#define XK_kana_u 0x4a9 +#define XK_kana_e 0x4aa +#define XK_kana_o 0x4ab +#define XK_kana_ya 0x4ac +#define XK_kana_yu 0x4ad +#define XK_kana_yo 0x4ae +#define XK_kana_tsu 0x4af +#define XK_kana_tu 0x4af /* deprecated */ +#define XK_prolongedsound 0x4b0 +#define XK_kana_A 0x4b1 +#define XK_kana_I 0x4b2 +#define XK_kana_U 0x4b3 +#define XK_kana_E 0x4b4 +#define XK_kana_O 0x4b5 +#define XK_kana_KA 0x4b6 +#define XK_kana_KI 0x4b7 +#define XK_kana_KU 0x4b8 +#define XK_kana_KE 0x4b9 +#define XK_kana_KO 0x4ba +#define XK_kana_SA 0x4bb +#define XK_kana_SHI 0x4bc +#define XK_kana_SU 0x4bd +#define XK_kana_SE 0x4be +#define XK_kana_SO 0x4bf +#define XK_kana_TA 0x4c0 +#define XK_kana_CHI 0x4c1 +#define XK_kana_TI 0x4c1 /* deprecated */ +#define XK_kana_TSU 0x4c2 +#define XK_kana_TU 0x4c2 /* deprecated */ +#define XK_kana_TE 0x4c3 +#define XK_kana_TO 0x4c4 +#define XK_kana_NA 0x4c5 +#define XK_kana_NI 0x4c6 +#define XK_kana_NU 0x4c7 +#define XK_kana_NE 0x4c8 +#define XK_kana_NO 0x4c9 +#define XK_kana_HA 0x4ca +#define XK_kana_HI 0x4cb +#define XK_kana_FU 0x4cc +#define XK_kana_HU 0x4cc /* deprecated */ +#define XK_kana_HE 0x4cd +#define XK_kana_HO 0x4ce +#define XK_kana_MA 0x4cf +#define XK_kana_MI 0x4d0 +#define XK_kana_MU 0x4d1 +#define XK_kana_ME 0x4d2 +#define XK_kana_MO 0x4d3 +#define XK_kana_YA 0x4d4 +#define XK_kana_YU 0x4d5 +#define XK_kana_YO 0x4d6 +#define XK_kana_RA 0x4d7 +#define XK_kana_RI 0x4d8 +#define XK_kana_RU 0x4d9 +#define XK_kana_RE 0x4da +#define XK_kana_RO 0x4db +#define XK_kana_WA 0x4dc +#define XK_kana_N 0x4dd +#define XK_voicedsound 0x4de +#define XK_semivoicedsound 0x4df +#define XK_kana_switch 0xFF7E /* Alias for mode_switch */ +#endif /* XK_KATAKANA */ + +/* + * Arabic + * Byte 3 = 5 + */ + +#ifdef XK_ARABIC +#define XK_Farsi_0 0x590 +#define XK_Farsi_1 0x591 +#define XK_Farsi_2 0x592 +#define XK_Farsi_3 0x593 +#define XK_Farsi_4 0x594 +#define XK_Farsi_5 0x595 +#define XK_Farsi_6 0x596 +#define XK_Farsi_7 0x597 +#define XK_Farsi_8 0x598 +#define XK_Farsi_9 0x599 +#define XK_Arabic_percent 0x5a5 +#define XK_Arabic_superscript_alef 0x5a6 +#define XK_Arabic_tteh 0x5a7 +#define XK_Arabic_peh 0x5a8 +#define XK_Arabic_tcheh 0x5a9 +#define XK_Arabic_ddal 0x5aa +#define XK_Arabic_rreh 0x5ab +#define XK_Arabic_comma 0x5ac +#define XK_Arabic_fullstop 0x5ae +#define XK_Arabic_0 0x5b0 +#define XK_Arabic_1 0x5b1 +#define XK_Arabic_2 0x5b2 +#define XK_Arabic_3 0x5b3 +#define XK_Arabic_4 0x5b4 +#define XK_Arabic_5 0x5b5 +#define XK_Arabic_6 0x5b6 +#define XK_Arabic_7 0x5b7 +#define XK_Arabic_8 0x5b8 +#define XK_Arabic_9 0x5b9 +#define XK_Arabic_semicolon 0x5bb +#define XK_Arabic_question_mark 0x5bf +#define XK_Arabic_hamza 0x5c1 +#define XK_Arabic_maddaonalef 0x5c2 +#define XK_Arabic_hamzaonalef 0x5c3 +#define XK_Arabic_hamzaonwaw 0x5c4 +#define XK_Arabic_hamzaunderalef 0x5c5 +#define XK_Arabic_hamzaonyeh 0x5c6 +#define XK_Arabic_alef 0x5c7 +#define XK_Arabic_beh 0x5c8 +#define XK_Arabic_tehmarbuta 0x5c9 +#define XK_Arabic_teh 0x5ca +#define XK_Arabic_theh 0x5cb +#define XK_Arabic_jeem 0x5cc +#define XK_Arabic_hah 0x5cd +#define XK_Arabic_khah 0x5ce +#define XK_Arabic_dal 0x5cf +#define XK_Arabic_thal 0x5d0 +#define XK_Arabic_ra 0x5d1 +#define XK_Arabic_zain 0x5d2 +#define XK_Arabic_seen 0x5d3 +#define XK_Arabic_sheen 0x5d4 +#define XK_Arabic_sad 0x5d5 +#define XK_Arabic_dad 0x5d6 +#define XK_Arabic_tah 0x5d7 +#define XK_Arabic_zah 0x5d8 +#define XK_Arabic_ain 0x5d9 +#define XK_Arabic_ghain 0x5da +#define XK_Arabic_tatweel 0x5e0 +#define XK_Arabic_feh 0x5e1 +#define XK_Arabic_qaf 0x5e2 +#define XK_Arabic_kaf 0x5e3 +#define XK_Arabic_lam 0x5e4 +#define XK_Arabic_meem 0x5e5 +#define XK_Arabic_noon 0x5e6 +#define XK_Arabic_ha 0x5e7 +#define XK_Arabic_heh 0x5e7 /* deprecated */ +#define XK_Arabic_waw 0x5e8 +#define XK_Arabic_alefmaksura 0x5e9 +#define XK_Arabic_yeh 0x5ea +#define XK_Arabic_fathatan 0x5eb +#define XK_Arabic_dammatan 0x5ec +#define XK_Arabic_kasratan 0x5ed +#define XK_Arabic_fatha 0x5ee +#define XK_Arabic_damma 0x5ef +#define XK_Arabic_kasra 0x5f0 +#define XK_Arabic_shadda 0x5f1 +#define XK_Arabic_sukun 0x5f2 +#define XK_Arabic_madda_above 0x5f3 +#define XK_Arabic_hamza_above 0x5f4 +#define XK_Arabic_hamza_below 0x5f5 +#define XK_Arabic_jeh 0x5f6 +#define XK_Arabic_veh 0x5f7 +#define XK_Arabic_keheh 0x5f8 +#define XK_Arabic_gaf 0x5f9 +#define XK_Arabic_noon_ghunna 0x5fa +#define XK_Arabic_heh_doachashmee 0x5fb +#define XK_Farsi_yeh 0x5fc +#define XK_Arabic_farsi_yeh XK_Farsi_yeh +#define XK_Arabic_yeh_baree 0x5fd +#define XK_Arabic_heh_goal 0x5fe +#define XK_Arabic_switch 0xFF7E /* Alias for mode_switch */ +#endif /* XK_ARABIC */ + +/* + * Cyrillic + * Byte 3 = 6 + */ +#ifdef XK_CYRILLIC +#define XK_Cyrillic_GHE_bar 0x680 +#define XK_Cyrillic_ghe_bar 0x690 +#define XK_Cyrillic_ZHE_descender 0x681 +#define XK_Cyrillic_zhe_descender 0x691 +#define XK_Cyrillic_KA_descender 0x682 +#define XK_Cyrillic_ka_descender 0x692 +#define XK_Cyrillic_KA_vertstroke 0x683 +#define XK_Cyrillic_ka_vertstroke 0x693 +#define XK_Cyrillic_EN_descender 0x684 +#define XK_Cyrillic_en_descender 0x694 +#define XK_Cyrillic_U_straight 0x685 +#define XK_Cyrillic_u_straight 0x695 +#define XK_Cyrillic_U_straight_bar 0x686 +#define XK_Cyrillic_u_straight_bar 0x696 +#define XK_Cyrillic_HA_descender 0x687 +#define XK_Cyrillic_ha_descender 0x697 +#define XK_Cyrillic_CHE_descender 0x688 +#define XK_Cyrillic_che_descender 0x698 +#define XK_Cyrillic_CHE_vertstroke 0x689 +#define XK_Cyrillic_che_vertstroke 0x699 +#define XK_Cyrillic_SHHA 0x68a +#define XK_Cyrillic_shha 0x69a + +#define XK_Cyrillic_SCHWA 0x68c +#define XK_Cyrillic_schwa 0x69c +#define XK_Cyrillic_I_macron 0x68d +#define XK_Cyrillic_i_macron 0x69d +#define XK_Cyrillic_O_bar 0x68e +#define XK_Cyrillic_o_bar 0x69e +#define XK_Cyrillic_U_macron 0x68f +#define XK_Cyrillic_u_macron 0x69f + +#define XK_Serbian_dje 0x6a1 +#define XK_Macedonia_gje 0x6a2 +#define XK_Cyrillic_io 0x6a3 +#define XK_Ukrainian_ie 0x6a4 +#define XK_Ukranian_je 0x6a4 /* deprecated */ +#define XK_Macedonia_dse 0x6a5 +#define XK_Ukrainian_i 0x6a6 +#define XK_Ukranian_i 0x6a6 /* deprecated */ +#define XK_Ukrainian_yi 0x6a7 +#define XK_Ukranian_yi 0x6a7 /* deprecated */ +#define XK_Cyrillic_je 0x6a8 +#define XK_Serbian_je 0x6a8 /* deprecated */ +#define XK_Cyrillic_lje 0x6a9 +#define XK_Serbian_lje 0x6a9 /* deprecated */ +#define XK_Cyrillic_nje 0x6aa +#define XK_Serbian_nje 0x6aa /* deprecated */ +#define XK_Serbian_tshe 0x6ab +#define XK_Macedonia_kje 0x6ac +#define XK_Ukrainian_ghe_with_upturn 0x6ad +#define XK_Byelorussian_shortu 0x6ae +#define XK_Cyrillic_dzhe 0x6af +#define XK_Serbian_dze 0x6af /* deprecated */ +#define XK_numerosign 0x6b0 +#define XK_Serbian_DJE 0x6b1 +#define XK_Macedonia_GJE 0x6b2 +#define XK_Cyrillic_IO 0x6b3 +#define XK_Ukrainian_IE 0x6b4 +#define XK_Ukranian_JE 0x6b4 /* deprecated */ +#define XK_Macedonia_DSE 0x6b5 +#define XK_Ukrainian_I 0x6b6 +#define XK_Ukranian_I 0x6b6 /* deprecated */ +#define XK_Ukrainian_YI 0x6b7 +#define XK_Ukranian_YI 0x6b7 /* deprecated */ +#define XK_Cyrillic_JE 0x6b8 +#define XK_Serbian_JE 0x6b8 /* deprecated */ +#define XK_Cyrillic_LJE 0x6b9 +#define XK_Serbian_LJE 0x6b9 /* deprecated */ +#define XK_Cyrillic_NJE 0x6ba +#define XK_Serbian_NJE 0x6ba /* deprecated */ +#define XK_Serbian_TSHE 0x6bb +#define XK_Macedonia_KJE 0x6bc +#define XK_Ukrainian_GHE_WITH_UPTURN 0x6bd +#define XK_Byelorussian_SHORTU 0x6be +#define XK_Cyrillic_DZHE 0x6bf +#define XK_Serbian_DZE 0x6bf /* deprecated */ +#define XK_Cyrillic_yu 0x6c0 +#define XK_Cyrillic_a 0x6c1 +#define XK_Cyrillic_be 0x6c2 +#define XK_Cyrillic_tse 0x6c3 +#define XK_Cyrillic_de 0x6c4 +#define XK_Cyrillic_ie 0x6c5 +#define XK_Cyrillic_ef 0x6c6 +#define XK_Cyrillic_ghe 0x6c7 +#define XK_Cyrillic_ha 0x6c8 +#define XK_Cyrillic_i 0x6c9 +#define XK_Cyrillic_shorti 0x6ca +#define XK_Cyrillic_ka 0x6cb +#define XK_Cyrillic_el 0x6cc +#define XK_Cyrillic_em 0x6cd +#define XK_Cyrillic_en 0x6ce +#define XK_Cyrillic_o 0x6cf +#define XK_Cyrillic_pe 0x6d0 +#define XK_Cyrillic_ya 0x6d1 +#define XK_Cyrillic_er 0x6d2 +#define XK_Cyrillic_es 0x6d3 +#define XK_Cyrillic_te 0x6d4 +#define XK_Cyrillic_u 0x6d5 +#define XK_Cyrillic_zhe 0x6d6 +#define XK_Cyrillic_ve 0x6d7 +#define XK_Cyrillic_softsign 0x6d8 +#define XK_Cyrillic_yeru 0x6d9 +#define XK_Cyrillic_ze 0x6da +#define XK_Cyrillic_sha 0x6db +#define XK_Cyrillic_e 0x6dc +#define XK_Cyrillic_shcha 0x6dd +#define XK_Cyrillic_che 0x6de +#define XK_Cyrillic_hardsign 0x6df +#define XK_Cyrillic_YU 0x6e0 +#define XK_Cyrillic_A 0x6e1 +#define XK_Cyrillic_BE 0x6e2 +#define XK_Cyrillic_TSE 0x6e3 +#define XK_Cyrillic_DE 0x6e4 +#define XK_Cyrillic_IE 0x6e5 +#define XK_Cyrillic_EF 0x6e6 +#define XK_Cyrillic_GHE 0x6e7 +#define XK_Cyrillic_HA 0x6e8 +#define XK_Cyrillic_I 0x6e9 +#define XK_Cyrillic_SHORTI 0x6ea +#define XK_Cyrillic_KA 0x6eb +#define XK_Cyrillic_EL 0x6ec +#define XK_Cyrillic_EM 0x6ed +#define XK_Cyrillic_EN 0x6ee +#define XK_Cyrillic_O 0x6ef +#define XK_Cyrillic_PE 0x6f0 +#define XK_Cyrillic_YA 0x6f1 +#define XK_Cyrillic_ER 0x6f2 +#define XK_Cyrillic_ES 0x6f3 +#define XK_Cyrillic_TE 0x6f4 +#define XK_Cyrillic_U 0x6f5 +#define XK_Cyrillic_ZHE 0x6f6 +#define XK_Cyrillic_VE 0x6f7 +#define XK_Cyrillic_SOFTSIGN 0x6f8 +#define XK_Cyrillic_YERU 0x6f9 +#define XK_Cyrillic_ZE 0x6fa +#define XK_Cyrillic_SHA 0x6fb +#define XK_Cyrillic_E 0x6fc +#define XK_Cyrillic_SHCHA 0x6fd +#define XK_Cyrillic_CHE 0x6fe +#define XK_Cyrillic_HARDSIGN 0x6ff +#endif /* XK_CYRILLIC */ + +/* + * Greek + * Byte 3 = 7 + */ + +#ifdef XK_GREEK +#define XK_Greek_ALPHAaccent 0x7a1 +#define XK_Greek_EPSILONaccent 0x7a2 +#define XK_Greek_ETAaccent 0x7a3 +#define XK_Greek_IOTAaccent 0x7a4 +#define XK_Greek_IOTAdieresis 0x7a5 +#define XK_Greek_IOTAdiaeresis XK_Greek_IOTAdieresis /* old typo */ +#define XK_Greek_OMICRONaccent 0x7a7 +#define XK_Greek_UPSILONaccent 0x7a8 +#define XK_Greek_UPSILONdieresis 0x7a9 +#define XK_Greek_OMEGAaccent 0x7ab +#define XK_Greek_accentdieresis 0x7ae +#define XK_Greek_horizbar 0x7af +#define XK_Greek_alphaaccent 0x7b1 +#define XK_Greek_epsilonaccent 0x7b2 +#define XK_Greek_etaaccent 0x7b3 +#define XK_Greek_iotaaccent 0x7b4 +#define XK_Greek_iotadieresis 0x7b5 +#define XK_Greek_iotaaccentdieresis 0x7b6 +#define XK_Greek_omicronaccent 0x7b7 +#define XK_Greek_upsilonaccent 0x7b8 +#define XK_Greek_upsilondieresis 0x7b9 +#define XK_Greek_upsilonaccentdieresis 0x7ba +#define XK_Greek_omegaaccent 0x7bb +#define XK_Greek_ALPHA 0x7c1 +#define XK_Greek_BETA 0x7c2 +#define XK_Greek_GAMMA 0x7c3 +#define XK_Greek_DELTA 0x7c4 +#define XK_Greek_EPSILON 0x7c5 +#define XK_Greek_ZETA 0x7c6 +#define XK_Greek_ETA 0x7c7 +#define XK_Greek_THETA 0x7c8 +#define XK_Greek_IOTA 0x7c9 +#define XK_Greek_KAPPA 0x7ca +#define XK_Greek_LAMDA 0x7cb +#define XK_Greek_LAMBDA 0x7cb +#define XK_Greek_MU 0x7cc +#define XK_Greek_NU 0x7cd +#define XK_Greek_XI 0x7ce +#define XK_Greek_OMICRON 0x7cf +#define XK_Greek_PI 0x7d0 +#define XK_Greek_RHO 0x7d1 +#define XK_Greek_SIGMA 0x7d2 +#define XK_Greek_TAU 0x7d4 +#define XK_Greek_UPSILON 0x7d5 +#define XK_Greek_PHI 0x7d6 +#define XK_Greek_CHI 0x7d7 +#define XK_Greek_PSI 0x7d8 +#define XK_Greek_OMEGA 0x7d9 +#define XK_Greek_alpha 0x7e1 +#define XK_Greek_beta 0x7e2 +#define XK_Greek_gamma 0x7e3 +#define XK_Greek_delta 0x7e4 +#define XK_Greek_epsilon 0x7e5 +#define XK_Greek_zeta 0x7e6 +#define XK_Greek_eta 0x7e7 +#define XK_Greek_theta 0x7e8 +#define XK_Greek_iota 0x7e9 +#define XK_Greek_kappa 0x7ea +#define XK_Greek_lamda 0x7eb +#define XK_Greek_lambda 0x7eb +#define XK_Greek_mu 0x7ec +#define XK_Greek_nu 0x7ed +#define XK_Greek_xi 0x7ee +#define XK_Greek_omicron 0x7ef +#define XK_Greek_pi 0x7f0 +#define XK_Greek_rho 0x7f1 +#define XK_Greek_sigma 0x7f2 +#define XK_Greek_finalsmallsigma 0x7f3 +#define XK_Greek_tau 0x7f4 +#define XK_Greek_upsilon 0x7f5 +#define XK_Greek_phi 0x7f6 +#define XK_Greek_chi 0x7f7 +#define XK_Greek_psi 0x7f8 +#define XK_Greek_omega 0x7f9 +#define XK_Greek_switch 0xFF7E /* Alias for mode_switch */ +#endif /* XK_GREEK */ + +/* + * Technical + * Byte 3 = 8 + */ + +#ifdef XK_TECHNICAL +#define XK_leftradical 0x8a1 +#define XK_topleftradical 0x8a2 +#define XK_horizconnector 0x8a3 +#define XK_topintegral 0x8a4 +#define XK_botintegral 0x8a5 +#define XK_vertconnector 0x8a6 +#define XK_topleftsqbracket 0x8a7 +#define XK_botleftsqbracket 0x8a8 +#define XK_toprightsqbracket 0x8a9 +#define XK_botrightsqbracket 0x8aa +#define XK_topleftparens 0x8ab +#define XK_botleftparens 0x8ac +#define XK_toprightparens 0x8ad +#define XK_botrightparens 0x8ae +#define XK_leftmiddlecurlybrace 0x8af +#define XK_rightmiddlecurlybrace 0x8b0 +#define XK_topleftsummation 0x8b1 +#define XK_botleftsummation 0x8b2 +#define XK_topvertsummationconnector 0x8b3 +#define XK_botvertsummationconnector 0x8b4 +#define XK_toprightsummation 0x8b5 +#define XK_botrightsummation 0x8b6 +#define XK_rightmiddlesummation 0x8b7 +#define XK_lessthanequal 0x8bc +#define XK_notequal 0x8bd +#define XK_greaterthanequal 0x8be +#define XK_integral 0x8bf +#define XK_therefore 0x8c0 +#define XK_variation 0x8c1 +#define XK_infinity 0x8c2 +#define XK_nabla 0x8c5 +#define XK_approximate 0x8c8 +#define XK_similarequal 0x8c9 +#define XK_ifonlyif 0x8cd +#define XK_implies 0x8ce +#define XK_identical 0x8cf +#define XK_radical 0x8d6 +#define XK_includedin 0x8da +#define XK_includes 0x8db +#define XK_intersection 0x8dc +#define XK_union 0x8dd +#define XK_logicaland 0x8de +#define XK_logicalor 0x8df +#define XK_partialderivative 0x8ef +#define XK_function 0x8f6 +#define XK_leftarrow 0x8fb +#define XK_uparrow 0x8fc +#define XK_rightarrow 0x8fd +#define XK_downarrow 0x8fe +#endif /* XK_TECHNICAL */ + +/* + * Special + * Byte 3 = 9 + */ + +#ifdef XK_SPECIAL +#define XK_blank 0x9df +#define XK_soliddiamond 0x9e0 +#define XK_checkerboard 0x9e1 +#define XK_ht 0x9e2 +#define XK_ff 0x9e3 +#define XK_cr 0x9e4 +#define XK_lf 0x9e5 +#define XK_nl 0x9e8 +#define XK_vt 0x9e9 +#define XK_lowrightcorner 0x9ea +#define XK_uprightcorner 0x9eb +#define XK_upleftcorner 0x9ec +#define XK_lowleftcorner 0x9ed +#define XK_crossinglines 0x9ee +#define XK_horizlinescan1 0x9ef +#define XK_horizlinescan3 0x9f0 +#define XK_horizlinescan5 0x9f1 +#define XK_horizlinescan7 0x9f2 +#define XK_horizlinescan9 0x9f3 +#define XK_leftt 0x9f4 +#define XK_rightt 0x9f5 +#define XK_bott 0x9f6 +#define XK_topt 0x9f7 +#define XK_vertbar 0x9f8 +#endif /* XK_SPECIAL */ + +/* + * Publishing + * Byte 3 = a + */ + +#ifdef XK_PUBLISHING +#define XK_emspace 0xaa1 +#define XK_enspace 0xaa2 +#define XK_em3space 0xaa3 +#define XK_em4space 0xaa4 +#define XK_digitspace 0xaa5 +#define XK_punctspace 0xaa6 +#define XK_thinspace 0xaa7 +#define XK_hairspace 0xaa8 +#define XK_emdash 0xaa9 +#define XK_endash 0xaaa +#define XK_signifblank 0xaac +#define XK_ellipsis 0xaae +#define XK_doubbaselinedot 0xaaf +#define XK_onethird 0xab0 +#define XK_twothirds 0xab1 +#define XK_onefifth 0xab2 +#define XK_twofifths 0xab3 +#define XK_threefifths 0xab4 +#define XK_fourfifths 0xab5 +#define XK_onesixth 0xab6 +#define XK_fivesixths 0xab7 +#define XK_careof 0xab8 +#define XK_figdash 0xabb +#define XK_leftanglebracket 0xabc +#define XK_decimalpoint 0xabd +#define XK_rightanglebracket 0xabe +#define XK_marker 0xabf +#define XK_oneeighth 0xac3 +#define XK_threeeighths 0xac4 +#define XK_fiveeighths 0xac5 +#define XK_seveneighths 0xac6 +#define XK_trademark 0xac9 +#define XK_signaturemark 0xaca +#define XK_trademarkincircle 0xacb +#define XK_leftopentriangle 0xacc +#define XK_rightopentriangle 0xacd +#define XK_emopencircle 0xace +#define XK_emopenrectangle 0xacf +#define XK_leftsinglequotemark 0xad0 +#define XK_rightsinglequotemark 0xad1 +#define XK_leftdoublequotemark 0xad2 +#define XK_rightdoublequotemark 0xad3 +#define XK_prescription 0xad4 +#define XK_minutes 0xad6 +#define XK_seconds 0xad7 +#define XK_latincross 0xad9 +#define XK_hexagram 0xada +#define XK_filledrectbullet 0xadb +#define XK_filledlefttribullet 0xadc +#define XK_filledrighttribullet 0xadd +#define XK_emfilledcircle 0xade +#define XK_emfilledrect 0xadf +#define XK_enopencircbullet 0xae0 +#define XK_enopensquarebullet 0xae1 +#define XK_openrectbullet 0xae2 +#define XK_opentribulletup 0xae3 +#define XK_opentribulletdown 0xae4 +#define XK_openstar 0xae5 +#define XK_enfilledcircbullet 0xae6 +#define XK_enfilledsqbullet 0xae7 +#define XK_filledtribulletup 0xae8 +#define XK_filledtribulletdown 0xae9 +#define XK_leftpointer 0xaea +#define XK_rightpointer 0xaeb +#define XK_club 0xaec +#define XK_diamond 0xaed +#define XK_heart 0xaee +#define XK_maltesecross 0xaf0 +#define XK_dagger 0xaf1 +#define XK_doubledagger 0xaf2 +#define XK_checkmark 0xaf3 +#define XK_ballotcross 0xaf4 +#define XK_musicalsharp 0xaf5 +#define XK_musicalflat 0xaf6 +#define XK_malesymbol 0xaf7 +#define XK_femalesymbol 0xaf8 +#define XK_telephone 0xaf9 +#define XK_telephonerecorder 0xafa +#define XK_phonographcopyright 0xafb +#define XK_caret 0xafc +#define XK_singlelowquotemark 0xafd +#define XK_doublelowquotemark 0xafe +#define XK_cursor 0xaff +#endif /* XK_PUBLISHING */ + +/* + * APL + * Byte 3 = b + */ + +#ifdef XK_APL +#define XK_leftcaret 0xba3 +#define XK_rightcaret 0xba6 +#define XK_downcaret 0xba8 +#define XK_upcaret 0xba9 +#define XK_overbar 0xbc0 +#define XK_downtack 0xbc2 +#define XK_upshoe 0xbc3 +#define XK_downstile 0xbc4 +#define XK_underbar 0xbc6 +#define XK_jot 0xbca +#define XK_quad 0xbcc +#define XK_uptack 0xbce +#define XK_circle 0xbcf +#define XK_upstile 0xbd3 +#define XK_downshoe 0xbd6 +#define XK_rightshoe 0xbd8 +#define XK_leftshoe 0xbda +#define XK_lefttack 0xbdc +#define XK_righttack 0xbfc +#endif /* XK_APL */ + +/* + * Hebrew + * Byte 3 = c + */ + +#ifdef XK_HEBREW +#define XK_hebrew_doublelowline 0xcdf +#define XK_hebrew_aleph 0xce0 +#define XK_hebrew_bet 0xce1 +#define XK_hebrew_beth 0xce1 /* deprecated */ +#define XK_hebrew_gimel 0xce2 +#define XK_hebrew_gimmel 0xce2 /* deprecated */ +#define XK_hebrew_dalet 0xce3 +#define XK_hebrew_daleth 0xce3 /* deprecated */ +#define XK_hebrew_he 0xce4 +#define XK_hebrew_waw 0xce5 +#define XK_hebrew_zain 0xce6 +#define XK_hebrew_zayin 0xce6 /* deprecated */ +#define XK_hebrew_chet 0xce7 +#define XK_hebrew_het 0xce7 /* deprecated */ +#define XK_hebrew_tet 0xce8 +#define XK_hebrew_teth 0xce8 /* deprecated */ +#define XK_hebrew_yod 0xce9 +#define XK_hebrew_finalkaph 0xcea +#define XK_hebrew_kaph 0xceb +#define XK_hebrew_lamed 0xcec +#define XK_hebrew_finalmem 0xced +#define XK_hebrew_mem 0xcee +#define XK_hebrew_finalnun 0xcef +#define XK_hebrew_nun 0xcf0 +#define XK_hebrew_samech 0xcf1 +#define XK_hebrew_samekh 0xcf1 /* deprecated */ +#define XK_hebrew_ayin 0xcf2 +#define XK_hebrew_finalpe 0xcf3 +#define XK_hebrew_pe 0xcf4 +#define XK_hebrew_finalzade 0xcf5 +#define XK_hebrew_finalzadi 0xcf5 /* deprecated */ +#define XK_hebrew_zade 0xcf6 +#define XK_hebrew_zadi 0xcf6 /* deprecated */ +#define XK_hebrew_qoph 0xcf7 +#define XK_hebrew_kuf 0xcf7 /* deprecated */ +#define XK_hebrew_resh 0xcf8 +#define XK_hebrew_shin 0xcf9 +#define XK_hebrew_taw 0xcfa +#define XK_hebrew_taf 0xcfa /* deprecated */ +#define XK_Hebrew_switch 0xFF7E /* Alias for mode_switch */ +#endif /* XK_HEBREW */ + +/* + * Thai + * Byte 3 = d + */ + +#ifdef XK_THAI +#define XK_Thai_kokai 0xda1 +#define XK_Thai_khokhai 0xda2 +#define XK_Thai_khokhuat 0xda3 +#define XK_Thai_khokhwai 0xda4 +#define XK_Thai_khokhon 0xda5 +#define XK_Thai_khorakhang 0xda6 +#define XK_Thai_ngongu 0xda7 +#define XK_Thai_chochan 0xda8 +#define XK_Thai_choching 0xda9 +#define XK_Thai_chochang 0xdaa +#define XK_Thai_soso 0xdab +#define XK_Thai_chochoe 0xdac +#define XK_Thai_yoying 0xdad +#define XK_Thai_dochada 0xdae +#define XK_Thai_topatak 0xdaf +#define XK_Thai_thothan 0xdb0 +#define XK_Thai_thonangmontho 0xdb1 +#define XK_Thai_thophuthao 0xdb2 +#define XK_Thai_nonen 0xdb3 +#define XK_Thai_dodek 0xdb4 +#define XK_Thai_totao 0xdb5 +#define XK_Thai_thothung 0xdb6 +#define XK_Thai_thothahan 0xdb7 +#define XK_Thai_thothong 0xdb8 +#define XK_Thai_nonu 0xdb9 +#define XK_Thai_bobaimai 0xdba +#define XK_Thai_popla 0xdbb +#define XK_Thai_phophung 0xdbc +#define XK_Thai_fofa 0xdbd +#define XK_Thai_phophan 0xdbe +#define XK_Thai_fofan 0xdbf +#define XK_Thai_phosamphao 0xdc0 +#define XK_Thai_moma 0xdc1 +#define XK_Thai_yoyak 0xdc2 +#define XK_Thai_rorua 0xdc3 +#define XK_Thai_ru 0xdc4 +#define XK_Thai_loling 0xdc5 +#define XK_Thai_lu 0xdc6 +#define XK_Thai_wowaen 0xdc7 +#define XK_Thai_sosala 0xdc8 +#define XK_Thai_sorusi 0xdc9 +#define XK_Thai_sosua 0xdca +#define XK_Thai_hohip 0xdcb +#define XK_Thai_lochula 0xdcc +#define XK_Thai_oang 0xdcd +#define XK_Thai_honokhuk 0xdce +#define XK_Thai_paiyannoi 0xdcf +#define XK_Thai_saraa 0xdd0 +#define XK_Thai_maihanakat 0xdd1 +#define XK_Thai_saraaa 0xdd2 +#define XK_Thai_saraam 0xdd3 +#define XK_Thai_sarai 0xdd4 +#define XK_Thai_saraii 0xdd5 +#define XK_Thai_saraue 0xdd6 +#define XK_Thai_sarauee 0xdd7 +#define XK_Thai_sarau 0xdd8 +#define XK_Thai_sarauu 0xdd9 +#define XK_Thai_phinthu 0xdda +#define XK_Thai_maihanakat_maitho 0xdde +#define XK_Thai_baht 0xddf +#define XK_Thai_sarae 0xde0 +#define XK_Thai_saraae 0xde1 +#define XK_Thai_sarao 0xde2 +#define XK_Thai_saraaimaimuan 0xde3 +#define XK_Thai_saraaimaimalai 0xde4 +#define XK_Thai_lakkhangyao 0xde5 +#define XK_Thai_maiyamok 0xde6 +#define XK_Thai_maitaikhu 0xde7 +#define XK_Thai_maiek 0xde8 +#define XK_Thai_maitho 0xde9 +#define XK_Thai_maitri 0xdea +#define XK_Thai_maichattawa 0xdeb +#define XK_Thai_thanthakhat 0xdec +#define XK_Thai_nikhahit 0xded +#define XK_Thai_leksun 0xdf0 +#define XK_Thai_leknung 0xdf1 +#define XK_Thai_leksong 0xdf2 +#define XK_Thai_leksam 0xdf3 +#define XK_Thai_leksi 0xdf4 +#define XK_Thai_lekha 0xdf5 +#define XK_Thai_lekhok 0xdf6 +#define XK_Thai_lekchet 0xdf7 +#define XK_Thai_lekpaet 0xdf8 +#define XK_Thai_lekkao 0xdf9 +#endif /* XK_THAI */ + +/* + * Korean + * Byte 3 = e + */ + +#ifdef XK_KOREAN + +#define XK_Hangul 0xff31 /* Hangul start/stop(toggle) */ +#define XK_Hangul_Start 0xff32 /* Hangul start */ +#define XK_Hangul_End 0xff33 /* Hangul end, English start */ +#define XK_Hangul_Hanja 0xff34 /* Start Hangul->Hanja Conversion */ +#define XK_Hangul_Jamo 0xff35 /* Hangul Jamo mode */ +#define XK_Hangul_Romaja 0xff36 /* Hangul Romaja mode */ +#define XK_Hangul_Codeinput 0xff37 /* Hangul code input mode */ +#define XK_Hangul_Jeonja 0xff38 /* Jeonja mode */ +#define XK_Hangul_Banja 0xff39 /* Banja mode */ +#define XK_Hangul_PreHanja 0xff3a /* Pre Hanja conversion */ +#define XK_Hangul_PostHanja 0xff3b /* Post Hanja conversion */ +#define XK_Hangul_SingleCandidate 0xff3c /* Single candidate */ +#define XK_Hangul_MultipleCandidate 0xff3d /* Multiple candidate */ +#define XK_Hangul_PreviousCandidate 0xff3e /* Previous candidate */ +#define XK_Hangul_Special 0xff3f /* Special symbols */ +#define XK_Hangul_switch 0xFF7E /* Alias for mode_switch */ + +/* Hangul Consonant Characters */ +#define XK_Hangul_Kiyeog 0xea1 +#define XK_Hangul_SsangKiyeog 0xea2 +#define XK_Hangul_KiyeogSios 0xea3 +#define XK_Hangul_Nieun 0xea4 +#define XK_Hangul_NieunJieuj 0xea5 +#define XK_Hangul_NieunHieuh 0xea6 +#define XK_Hangul_Dikeud 0xea7 +#define XK_Hangul_SsangDikeud 0xea8 +#define XK_Hangul_Rieul 0xea9 +#define XK_Hangul_RieulKiyeog 0xeaa +#define XK_Hangul_RieulMieum 0xeab +#define XK_Hangul_RieulPieub 0xeac +#define XK_Hangul_RieulSios 0xead +#define XK_Hangul_RieulTieut 0xeae +#define XK_Hangul_RieulPhieuf 0xeaf +#define XK_Hangul_RieulHieuh 0xeb0 +#define XK_Hangul_Mieum 0xeb1 +#define XK_Hangul_Pieub 0xeb2 +#define XK_Hangul_SsangPieub 0xeb3 +#define XK_Hangul_PieubSios 0xeb4 +#define XK_Hangul_Sios 0xeb5 +#define XK_Hangul_SsangSios 0xeb6 +#define XK_Hangul_Ieung 0xeb7 +#define XK_Hangul_Jieuj 0xeb8 +#define XK_Hangul_SsangJieuj 0xeb9 +#define XK_Hangul_Cieuc 0xeba +#define XK_Hangul_Khieuq 0xebb +#define XK_Hangul_Tieut 0xebc +#define XK_Hangul_Phieuf 0xebd +#define XK_Hangul_Hieuh 0xebe + +/* Hangul Vowel Characters */ +#define XK_Hangul_A 0xebf +#define XK_Hangul_AE 0xec0 +#define XK_Hangul_YA 0xec1 +#define XK_Hangul_YAE 0xec2 +#define XK_Hangul_EO 0xec3 +#define XK_Hangul_E 0xec4 +#define XK_Hangul_YEO 0xec5 +#define XK_Hangul_YE 0xec6 +#define XK_Hangul_O 0xec7 +#define XK_Hangul_WA 0xec8 +#define XK_Hangul_WAE 0xec9 +#define XK_Hangul_OE 0xeca +#define XK_Hangul_YO 0xecb +#define XK_Hangul_U 0xecc +#define XK_Hangul_WEO 0xecd +#define XK_Hangul_WE 0xece +#define XK_Hangul_WI 0xecf +#define XK_Hangul_YU 0xed0 +#define XK_Hangul_EU 0xed1 +#define XK_Hangul_YI 0xed2 +#define XK_Hangul_I 0xed3 + +/* Hangul syllable-final (JongSeong) Characters */ +#define XK_Hangul_J_Kiyeog 0xed4 +#define XK_Hangul_J_SsangKiyeog 0xed5 +#define XK_Hangul_J_KiyeogSios 0xed6 +#define XK_Hangul_J_Nieun 0xed7 +#define XK_Hangul_J_NieunJieuj 0xed8 +#define XK_Hangul_J_NieunHieuh 0xed9 +#define XK_Hangul_J_Dikeud 0xeda +#define XK_Hangul_J_Rieul 0xedb +#define XK_Hangul_J_RieulKiyeog 0xedc +#define XK_Hangul_J_RieulMieum 0xedd +#define XK_Hangul_J_RieulPieub 0xede +#define XK_Hangul_J_RieulSios 0xedf +#define XK_Hangul_J_RieulTieut 0xee0 +#define XK_Hangul_J_RieulPhieuf 0xee1 +#define XK_Hangul_J_RieulHieuh 0xee2 +#define XK_Hangul_J_Mieum 0xee3 +#define XK_Hangul_J_Pieub 0xee4 +#define XK_Hangul_J_PieubSios 0xee5 +#define XK_Hangul_J_Sios 0xee6 +#define XK_Hangul_J_SsangSios 0xee7 +#define XK_Hangul_J_Ieung 0xee8 +#define XK_Hangul_J_Jieuj 0xee9 +#define XK_Hangul_J_Cieuc 0xeea +#define XK_Hangul_J_Khieuq 0xeeb +#define XK_Hangul_J_Tieut 0xeec +#define XK_Hangul_J_Phieuf 0xeed +#define XK_Hangul_J_Hieuh 0xeee + +/* Ancient Hangul Consonant Characters */ +#define XK_Hangul_RieulYeorinHieuh 0xeef +#define XK_Hangul_SunkyeongeumMieum 0xef0 +#define XK_Hangul_SunkyeongeumPieub 0xef1 +#define XK_Hangul_PanSios 0xef2 +#define XK_Hangul_KkogjiDalrinIeung 0xef3 +#define XK_Hangul_SunkyeongeumPhieuf 0xef4 +#define XK_Hangul_YeorinHieuh 0xef5 + +/* Ancient Hangul Vowel Characters */ +#define XK_Hangul_AraeA 0xef6 +#define XK_Hangul_AraeAE 0xef7 + +/* Ancient Hangul syllable-final (JongSeong) Characters */ +#define XK_Hangul_J_PanSios 0xef8 +#define XK_Hangul_J_KkogjiDalrinIeung 0xef9 +#define XK_Hangul_J_YeorinHieuh 0xefa + +/* Korean currency symbol */ +#define XK_Korean_Won 0xeff + +#endif /* XK_KOREAN */ + +/* + * Armenian + * Byte 3 = 0x14 + */ + +#ifdef XK_ARMENIAN +#define XK_Armenian_eternity 0x14a1 +#define XK_Armenian_ligature_ew 0x14a2 +#define XK_Armenian_full_stop 0x14a3 +#define XK_Armenian_verjaket 0x14a3 +#define XK_Armenian_parenright 0x14a4 +#define XK_Armenian_parenleft 0x14a5 +#define XK_Armenian_guillemotright 0x14a6 +#define XK_Armenian_guillemotleft 0x14a7 +#define XK_Armenian_em_dash 0x14a8 +#define XK_Armenian_dot 0x14a9 +#define XK_Armenian_mijaket 0x14a9 +#define XK_Armenian_separation_mark 0x14aa +#define XK_Armenian_but 0x14aa +#define XK_Armenian_comma 0x14ab +#define XK_Armenian_en_dash 0x14ac +#define XK_Armenian_hyphen 0x14ad +#define XK_Armenian_yentamna 0x14ad +#define XK_Armenian_ellipsis 0x14ae +#define XK_Armenian_exclam 0x14af +#define XK_Armenian_amanak 0x14af +#define XK_Armenian_accent 0x14b0 +#define XK_Armenian_shesht 0x14b0 +#define XK_Armenian_question 0x14b1 +#define XK_Armenian_paruyk 0x14b1 +#define XK_Armenian_AYB 0x14b2 +#define XK_Armenian_ayb 0x14b3 +#define XK_Armenian_BEN 0x14b4 +#define XK_Armenian_ben 0x14b5 +#define XK_Armenian_GIM 0x14b6 +#define XK_Armenian_gim 0x14b7 +#define XK_Armenian_DA 0x14b8 +#define XK_Armenian_da 0x14b9 +#define XK_Armenian_YECH 0x14ba +#define XK_Armenian_yech 0x14bb +#define XK_Armenian_ZA 0x14bc +#define XK_Armenian_za 0x14bd +#define XK_Armenian_E 0x14be +#define XK_Armenian_e 0x14bf +#define XK_Armenian_AT 0x14c0 +#define XK_Armenian_at 0x14c1 +#define XK_Armenian_TO 0x14c2 +#define XK_Armenian_to 0x14c3 +#define XK_Armenian_ZHE 0x14c4 +#define XK_Armenian_zhe 0x14c5 +#define XK_Armenian_INI 0x14c6 +#define XK_Armenian_ini 0x14c7 +#define XK_Armenian_LYUN 0x14c8 +#define XK_Armenian_lyun 0x14c9 +#define XK_Armenian_KHE 0x14ca +#define XK_Armenian_khe 0x14cb +#define XK_Armenian_TSA 0x14cc +#define XK_Armenian_tsa 0x14cd +#define XK_Armenian_KEN 0x14ce +#define XK_Armenian_ken 0x14cf +#define XK_Armenian_HO 0x14d0 +#define XK_Armenian_ho 0x14d1 +#define XK_Armenian_DZA 0x14d2 +#define XK_Armenian_dza 0x14d3 +#define XK_Armenian_GHAT 0x14d4 +#define XK_Armenian_ghat 0x14d5 +#define XK_Armenian_TCHE 0x14d6 +#define XK_Armenian_tche 0x14d7 +#define XK_Armenian_MEN 0x14d8 +#define XK_Armenian_men 0x14d9 +#define XK_Armenian_HI 0x14da +#define XK_Armenian_hi 0x14db +#define XK_Armenian_NU 0x14dc +#define XK_Armenian_nu 0x14dd +#define XK_Armenian_SHA 0x14de +#define XK_Armenian_sha 0x14df +#define XK_Armenian_VO 0x14e0 +#define XK_Armenian_vo 0x14e1 +#define XK_Armenian_CHA 0x14e2 +#define XK_Armenian_cha 0x14e3 +#define XK_Armenian_PE 0x14e4 +#define XK_Armenian_pe 0x14e5 +#define XK_Armenian_JE 0x14e6 +#define XK_Armenian_je 0x14e7 +#define XK_Armenian_RA 0x14e8 +#define XK_Armenian_ra 0x14e9 +#define XK_Armenian_SE 0x14ea +#define XK_Armenian_se 0x14eb +#define XK_Armenian_VEV 0x14ec +#define XK_Armenian_vev 0x14ed +#define XK_Armenian_TYUN 0x14ee +#define XK_Armenian_tyun 0x14ef +#define XK_Armenian_RE 0x14f0 +#define XK_Armenian_re 0x14f1 +#define XK_Armenian_TSO 0x14f2 +#define XK_Armenian_tso 0x14f3 +#define XK_Armenian_VYUN 0x14f4 +#define XK_Armenian_vyun 0x14f5 +#define XK_Armenian_PYUR 0x14f6 +#define XK_Armenian_pyur 0x14f7 +#define XK_Armenian_KE 0x14f8 +#define XK_Armenian_ke 0x14f9 +#define XK_Armenian_O 0x14fa +#define XK_Armenian_o 0x14fb +#define XK_Armenian_FE 0x14fc +#define XK_Armenian_fe 0x14fd +#define XK_Armenian_apostrophe 0x14fe +#define XK_Armenian_section_sign 0x14ff +#endif /* XK_ARMENIAN */ + +/* + * Georgian + * Byte 3 = 0x15 + */ + +#ifdef XK_GEORGIAN +#define XK_Georgian_an 0x15d0 +#define XK_Georgian_ban 0x15d1 +#define XK_Georgian_gan 0x15d2 +#define XK_Georgian_don 0x15d3 +#define XK_Georgian_en 0x15d4 +#define XK_Georgian_vin 0x15d5 +#define XK_Georgian_zen 0x15d6 +#define XK_Georgian_tan 0x15d7 +#define XK_Georgian_in 0x15d8 +#define XK_Georgian_kan 0x15d9 +#define XK_Georgian_las 0x15da +#define XK_Georgian_man 0x15db +#define XK_Georgian_nar 0x15dc +#define XK_Georgian_on 0x15dd +#define XK_Georgian_par 0x15de +#define XK_Georgian_zhar 0x15df +#define XK_Georgian_rae 0x15e0 +#define XK_Georgian_san 0x15e1 +#define XK_Georgian_tar 0x15e2 +#define XK_Georgian_un 0x15e3 +#define XK_Georgian_phar 0x15e4 +#define XK_Georgian_khar 0x15e5 +#define XK_Georgian_ghan 0x15e6 +#define XK_Georgian_qar 0x15e7 +#define XK_Georgian_shin 0x15e8 +#define XK_Georgian_chin 0x15e9 +#define XK_Georgian_can 0x15ea +#define XK_Georgian_jil 0x15eb +#define XK_Georgian_cil 0x15ec +#define XK_Georgian_char 0x15ed +#define XK_Georgian_xan 0x15ee +#define XK_Georgian_jhan 0x15ef +#define XK_Georgian_hae 0x15f0 +#define XK_Georgian_he 0x15f1 +#define XK_Georgian_hie 0x15f2 +#define XK_Georgian_we 0x15f3 +#define XK_Georgian_har 0x15f4 +#define XK_Georgian_hoe 0x15f5 +#define XK_Georgian_fi 0x15f6 +#endif /* XK_GEORGIAN */ + +/* + * Azeri (and other Turkic or Caucasian languages of ex-USSR) + * Byte 3 = 0x16 + */ + +#ifdef XK_CAUCASUS +/* latin */ +#define XK_Ccedillaabovedot 0x16a2 +#define XK_Xabovedot 0x16a3 +#define XK_Qabovedot 0x16a5 +#define XK_Ibreve 0x16a6 +#define XK_IE 0x16a7 +#define XK_UO 0x16a8 +#define XK_Zstroke 0x16a9 +#define XK_Gcaron 0x16aa +#define XK_Obarred 0x16af +#define XK_ccedillaabovedot 0x16b2 +#define XK_xabovedot 0x16b3 +#define XK_Ocaron 0x16b4 +#define XK_qabovedot 0x16b5 +#define XK_ibreve 0x16b6 +#define XK_ie 0x16b7 +#define XK_uo 0x16b8 +#define XK_zstroke 0x16b9 +#define XK_gcaron 0x16ba +#define XK_ocaron 0x16bd +#define XK_obarred 0x16bf +#define XK_SCHWA 0x16c6 +#define XK_schwa 0x16f6 +/* those are not really Caucasus, but I put them here for now */ +/* For Inupiak */ +#define XK_Lbelowdot 0x16d1 +#define XK_Lstrokebelowdot 0x16d2 +#define XK_lbelowdot 0x16e1 +#define XK_lstrokebelowdot 0x16e2 +/* For Guarani */ +#define XK_Gtilde 0x16d3 +#define XK_gtilde 0x16e3 +#endif /* XK_CAUCASUS */ + +/* + * Vietnamese + * Byte 3 = 0x1e + */ + +#ifdef XK_VIETNAMESE +#define XK_Abelowdot 0x1ea0 +#define XK_abelowdot 0x1ea1 +#define XK_Ahook 0x1ea2 +#define XK_ahook 0x1ea3 +#define XK_Acircumflexacute 0x1ea4 +#define XK_acircumflexacute 0x1ea5 +#define XK_Acircumflexgrave 0x1ea6 +#define XK_acircumflexgrave 0x1ea7 +#define XK_Acircumflexhook 0x1ea8 +#define XK_acircumflexhook 0x1ea9 +#define XK_Acircumflextilde 0x1eaa +#define XK_acircumflextilde 0x1eab +#define XK_Acircumflexbelowdot 0x1eac +#define XK_acircumflexbelowdot 0x1ead +#define XK_Abreveacute 0x1eae +#define XK_abreveacute 0x1eaf +#define XK_Abrevegrave 0x1eb0 +#define XK_abrevegrave 0x1eb1 +#define XK_Abrevehook 0x1eb2 +#define XK_abrevehook 0x1eb3 +#define XK_Abrevetilde 0x1eb4 +#define XK_abrevetilde 0x1eb5 +#define XK_Abrevebelowdot 0x1eb6 +#define XK_abrevebelowdot 0x1eb7 +#define XK_Ebelowdot 0x1eb8 +#define XK_ebelowdot 0x1eb9 +#define XK_Ehook 0x1eba +#define XK_ehook 0x1ebb +#define XK_Etilde 0x1ebc +#define XK_etilde 0x1ebd +#define XK_Ecircumflexacute 0x1ebe +#define XK_ecircumflexacute 0x1ebf +#define XK_Ecircumflexgrave 0x1ec0 +#define XK_ecircumflexgrave 0x1ec1 +#define XK_Ecircumflexhook 0x1ec2 +#define XK_ecircumflexhook 0x1ec3 +#define XK_Ecircumflextilde 0x1ec4 +#define XK_ecircumflextilde 0x1ec5 +#define XK_Ecircumflexbelowdot 0x1ec6 +#define XK_ecircumflexbelowdot 0x1ec7 +#define XK_Ihook 0x1ec8 +#define XK_ihook 0x1ec9 +#define XK_Ibelowdot 0x1eca +#define XK_ibelowdot 0x1ecb +#define XK_Obelowdot 0x1ecc +#define XK_obelowdot 0x1ecd +#define XK_Ohook 0x1ece +#define XK_ohook 0x1ecf +#define XK_Ocircumflexacute 0x1ed0 +#define XK_ocircumflexacute 0x1ed1 +#define XK_Ocircumflexgrave 0x1ed2 +#define XK_ocircumflexgrave 0x1ed3 +#define XK_Ocircumflexhook 0x1ed4 +#define XK_ocircumflexhook 0x1ed5 +#define XK_Ocircumflextilde 0x1ed6 +#define XK_ocircumflextilde 0x1ed7 +#define XK_Ocircumflexbelowdot 0x1ed8 +#define XK_ocircumflexbelowdot 0x1ed9 +#define XK_Ohornacute 0x1eda +#define XK_ohornacute 0x1edb +#define XK_Ohorngrave 0x1edc +#define XK_ohorngrave 0x1edd +#define XK_Ohornhook 0x1ede +#define XK_ohornhook 0x1edf +#define XK_Ohorntilde 0x1ee0 +#define XK_ohorntilde 0x1ee1 +#define XK_Ohornbelowdot 0x1ee2 +#define XK_ohornbelowdot 0x1ee3 +#define XK_Ubelowdot 0x1ee4 +#define XK_ubelowdot 0x1ee5 +#define XK_Uhook 0x1ee6 +#define XK_uhook 0x1ee7 +#define XK_Uhornacute 0x1ee8 +#define XK_uhornacute 0x1ee9 +#define XK_Uhorngrave 0x1eea +#define XK_uhorngrave 0x1eeb +#define XK_Uhornhook 0x1eec +#define XK_uhornhook 0x1eed +#define XK_Uhorntilde 0x1eee +#define XK_uhorntilde 0x1eef +#define XK_Uhornbelowdot 0x1ef0 +#define XK_uhornbelowdot 0x1ef1 +#define XK_Ybelowdot 0x1ef4 +#define XK_ybelowdot 0x1ef5 +#define XK_Yhook 0x1ef6 +#define XK_yhook 0x1ef7 +#define XK_Ytilde 0x1ef8 +#define XK_ytilde 0x1ef9 +#define XK_Ohorn 0x1efa /* U+01a0 */ +#define XK_ohorn 0x1efb /* U+01a1 */ +#define XK_Uhorn 0x1efc /* U+01af */ +#define XK_uhorn 0x1efd /* U+01b0 */ + +#define XK_combining_tilde 0x1e9f /* U+0303 */ +#define XK_combining_grave 0x1ef2 /* U+0300 */ +#define XK_combining_acute 0x1ef3 /* U+0301 */ +#define XK_combining_hook 0x1efe /* U+0309 */ +#define XK_combining_belowdot 0x1eff /* U+0323 */ +#endif /* XK_VIETNAMESE */ + +#ifdef XK_CURRENCY +#define XK_EcuSign 0x20a0 +#define XK_ColonSign 0x20a1 +#define XK_CruzeiroSign 0x20a2 +#define XK_FFrancSign 0x20a3 +#define XK_LiraSign 0x20a4 +#define XK_MillSign 0x20a5 +#define XK_NairaSign 0x20a6 +#define XK_PesetaSign 0x20a7 +#define XK_RupeeSign 0x20a8 +#define XK_WonSign 0x20a9 +#define XK_NewSheqelSign 0x20aa +#define XK_DongSign 0x20ab +#define XK_EuroSign 0x20ac +#endif + + +#endif //_INCLUDE_KEY_SYM_H diff --git a/programs/games/checkers/trunk/makefile b/programs/games/checkers/trunk/makefile new file mode 100644 index 0000000000..045c71ebd6 --- /dev/null +++ b/programs/games/checkers/trunk/makefile @@ -0,0 +1,4 @@ +checkers : checkers.o + g++ -L/usr/X11R6/lib -lX11 -o checkers checkers.o +checkers.o : checkers.cpp board.h position.h player.h tmplayer.h buttons.h history.h hash.h gr-draw.h gnu-draw.h sysproc.h + g++ -c checkers.cpp diff --git a/programs/games/checkers/trunk/me_make.inc b/programs/games/checkers/trunk/me_make.inc new file mode 100644 index 0000000000..173c2eb927 --- /dev/null +++ b/programs/games/checkers/trunk/me_make.inc @@ -0,0 +1,10 @@ +;//NAME// checkers.cpp +;//COMPILER// bcc32 -S -v- -R- -6 -a4 -O2 -Og -Oi -Ov -OS -k- -D__MENUET__ -Iinclude +;//UTIL_PATH// . + +STACKSIZE equ 102400 +HEAPSIZE equ 102400 + +include "include\me_start.inc" +include "include\me_func.inc" +include "include\me_heap.inc" diff --git a/programs/games/checkers/trunk/mt-draw.h b/programs/games/checkers/trunk/mt-draw.h new file mode 100644 index 0000000000..3adce2b73a --- /dev/null +++ b/programs/games/checkers/trunk/mt-draw.h @@ -0,0 +1,79 @@ +unsigned long cur_color; +class TKlbrGraphDraw : public TGraphDraw +{ +public: + virtual int SetColor(unsigned long c) {cur_color=c;return 1;} + virtual int DrawLine(int x0, int y0, int x1, int y1); + virtual int DrawText(int x0, int y0, char* text); + virtual int IsDraw(void) {return 1;} + virtual int DrawClear(); + virtual unsigned long CreateColor(unsigned short red, + unsigned short green, unsigned short blue); + virtual void GetSize(int &w, int &h); + virtual int GetTextH(const char *s) {return 10;} + virtual int GetTextW(const char *s) {return 6 * strlen(s);} + virtual void Quit(int q = 1) {CloseWindow();} +}; +int TKlbrGraphDraw::DrawLine(int x0, int y0, int x1, int y1) +{ + asm mov ebx, x0 + asm shl ebx, 16 + asm add ebx, x1 + asm mov ecx, y0 + asm shl ecx, 16 + asm add ecx, y1 + asm mov edx, [cur_color] + asm push 38 + asm pop eax + asm int 40h + return 1; +} +int TKlbrGraphDraw::DrawText(int x0, int y0, char* text) +{ + asm mov ebx, x0 + asm shl ebx, 16 + asm add ebx, y0 + asm mov ecx, [cur_color] + asm or ecx, 0xC0000000 + asm mov edx, text + asm mov edi, 0xFFFFFF + asm push 4 + asm pop eax + asm int 40h + return 1; +} +int TKlbrGraphDraw::DrawClear(void) +{ + int w,h; + GetSize(w,h); + asm mov ebx, w + asm mov ecx, h + asm mov edx, 0xFFFFFF + asm push 13 + asm pop eax + asm int 40h + return 1; +} +unsigned long TKlbrGraphDraw::CreateColor(unsigned short red, + unsigned short green, unsigned short blue) +{ + return (unsigned long)(blue >> 8) + ((unsigned long)(green >> 8) << 8) + + ((unsigned long)(red >> 8) << 16); +} +void TKlbrGraphDraw::GetSize(int &w, int &h) +{ + int width, height; + asm sub esp, 1024 + asm mov ebx, esp + asm or ecx, -1 + asm push 9 + asm pop eax + asm int 40h + asm mov eax, [esp+62] + asm mov width, eax + asm mov eax, [esp+66] + asm mov height, eax + asm add esp, 1024 + w = width; + h = height; +} diff --git a/programs/games/checkers/trunk/player.h b/programs/games/checkers/trunk/player.h new file mode 100644 index 0000000000..8eff1ce459 --- /dev/null +++ b/programs/games/checkers/trunk/player.h @@ -0,0 +1,888 @@ +#ifndef _HEADER_PLAYER_H +#define _HEADER_PLAYER_H + +#include "position.h" +#include "sysproc.h" +#ifndef __MENUET__ +#include +#include +#include +#endif + +template +class TBaseCompPlayer : public TChPlayer +{ +public: + static const int PKind; + static const tvalue win_val; +public: + TBaseCompPlayer() : draw(0), data(0) {} + + virtual int PlayerID() {return PKind;} + virtual int Move(PMv &pmv); + + struct PMvv : public PMv + { + tvalue val; + }; + + struct Z + { + Z(int marr = 400) : narr(0), marr(marr) {array = new PMvv[marr];} + ~Z() {Clear();} + + void Clear() {if (array) {delete[] array; array = 0;} marr = 0; narr = 0;} + void AddPos(int n); + void AddPos() {AddPos(narr + 1);} + int FindAllMoves(PMv pmv, int onlyeat = 0); + void FindSideEats(PMv &pmv, int k, int sx, int sy); + + static int ComparePMv(const void *v1, const void *v2); + void Sort(int n0, int n1); + + int marr, narr; + PMvv *array; + }; + + static tvalue GetLossValue(const Position &pos); + virtual tvalue GetValue(const Position &pos, int num = 0); + tvalue GetFullValue(const Position &pos, int num = 0); + tvalue FindBMove(Z &z, int num, PMvv *pmv, int zn = -1, + tvalue a = -2 * win_val, tvalue b = 2 * win_val); +public: + void (*draw)(void*, int = 0); + void *data; +}; + +template +const int TBaseCompPlayer::PKind = 0x2000; + +template +const tvalue TBaseCompPlayer::win_val = (tvalue)10000000L; + +template +void TBaseCompPlayer::Z::AddPos(int n) +{ + if (marr < n) + { + int m0 = marr; + PMvv *arr0 = array; + marr = 2*n + 10; + array = new PMvv[marr]; + if (arr0) + { + int i; + for (i = 0; i < m0; i++) array[i] = arr0[i]; + delete[] arr0; + } + } +} + +template +void TBaseCompPlayer::Z::FindSideEats(PMv &pmv, int k, int sx, int sy) +{ + int x, y; + NumToPole(k, x, y); + if (pmv.pos.SH[k] == pmv.pos.wmove + 1) + { + int xx = x + 2*sx, yy = y + 2*sy; + if (xx >= 0 && xx < NW_CELL && yy >= 0 && yy < NW_CELL) + { + int kk = PoleToNum(xx, yy); + if (pmv.pos.SH[kk] == 0) + { + int k1 = PoleToNum(x + sx, y + sy); + char nk1 = pmv.pos.SH[k1]; + if (nk1 == 2 - pmv.pos.wmove || nk1 == 4 - pmv.pos.wmove) + { + char SH_k1 = pmv.pos.SH[k1]; + pmv.pos.Del(k1); pmv.pos.Move(k, kk); + if (pmv.pos.wmove == 0 && yy == NW_CELL - 1 || + pmv.pos.wmove == 1 && yy == 0) pmv.pos.SH[kk] += (char)2; + pmv.mv[++pmv.mv[0]] = (char)kk; + int nold = narr; + FindSideEats(pmv, kk, sx, sy); + FindSideEats(pmv, kk, sy, -sx); + FindSideEats(pmv, kk, -sy, sx); + if (narr == nold) + { + AddPos(); + (PMv&)array[narr] = pmv; + array[narr].pos.wmove = !pmv.pos.wmove; + narr++; + } + pmv.mv[0]--; + pmv.pos.SH[k1] = SH_k1; pmv.pos.Del(kk); + pmv.pos.SH[k] = char(pmv.pos.wmove + 1); + } + } + } + } + else if (pmv.pos.SH[k] == pmv.pos.wmove + 3) + { + int i, i0, i1; + if (sx < 0) i0 = x; + else i0 = NW_CELL - x - 1; + if (sy < 0) i1 = y; + else i1 = NW_CELL - y - 1; + if (i0 > i1) i0 = i1; + if (i0 >= 2) + { + pmv.pos.Del(k); + pmv.mv[0]++; + i1 = -1; + int kk, kk1; + char SH_kk1; + int nold = narr; + for (i = 1; i <= i0; i++) + { + kk = PoleToNum(x + i*sx, y + i*sy); + char chh = pmv.pos.SH[kk]; + if (chh) + { + if (i1 >= 0 || (chh != 2 - pmv.pos.wmove && chh != 4 - pmv.pos.wmove)) break; + else + { + i1 = i; kk1 = kk; + SH_kk1 = chh; + pmv.pos.Del(kk1); + } + } + else if (i1 >= 0) + { + pmv.pos.SH[kk] = char(pmv.pos.wmove + 3); + pmv.mv[pmv.mv[0]] = (char)kk; + if (i == i1+1) FindSideEats(pmv, kk, sx, sy); + FindSideEats(pmv, kk, sy, -sx); + FindSideEats(pmv, kk, -sy, sx); + pmv.pos.Del(kk); + } + } + if (narr == nold && i1 >= 0) + { + while (--i > i1) + { + kk = PoleToNum(x + i*sx, y + i*sy); + AddPos(); + (PMv&)array[narr] = pmv; + array[narr].pos.SH[kk] = char(pmv.pos.wmove + 3); + array[narr].mv[pmv.mv[0]] = (char)kk; + array[narr].pos.wmove = !pmv.pos.wmove; + narr++; + } + } + pmv.mv[0]--; + pmv.pos.SH[k] = char(pmv.pos.wmove + 3); + if (i1 >= 0) pmv.pos.SH[kk1] = SH_kk1; + } + } +} + +template +int TBaseCompPlayer::Z::FindAllMoves(PMv pmv, int onlyeat) +{ + int k, nold = narr, was_eat = 1; + pmv.mv[0] = 1; + for (k = 0; k < NUM_CELL; k++) + { + if (pmv.pos.SH[k] == pmv.pos.wmove + 1 || pmv.pos.SH[k] == pmv.pos.wmove + 3) + { + pmv.mv[1] = (char)k; + FindSideEats(pmv, k, 1, 1); + FindSideEats(pmv, k, 1, -1); + FindSideEats(pmv, k, -1, 1); + FindSideEats(pmv, k, -1, -1); + } + } + if (narr == nold) + { + was_eat = 0; + if (!onlyeat) + { + pmv.mv[0] = 2; + for (k = 0; k < NUM_CELL; k++) + { + if (pmv.pos.SH[k] == pmv.pos.wmove + 1) + { + pmv.mv[1] = (char)k; + int x, x0, x1, y; + NumToPole(k, x0, y); + if (pmv.pos.wmove == 1) y--; else y++; + if (y >= 0 && y < NW_CELL) + { + int kk; + x1 = (x0--) + 1; + for (x = x0; x <= x1; x += 2) if (x >= 0 && x < NW_CELL) + { + kk = PoleToNum(x, y); + if (pmv.pos.SH[kk] == 0) + { + AddPos(); + (PMv&)array[narr] = pmv; + array[narr].pos.Del(k); + if (pmv.pos.wmove == 0 && y == NW_CELL - 1 || + pmv.pos.wmove == 1 && y == 0) + { + array[narr].pos.Add(kk, char(pmv.pos.wmove + 3)); + } + else array[narr].pos.Add(kk, char(pmv.pos.wmove + 1)); + array[narr].mv[2] = (char)kk; + array[narr].pos.wmove = !pmv.pos.wmove; + narr++; + } + } + } + } + else if (pmv.pos.SH[k] == pmv.pos.wmove + 3) + { + pmv.mv[1] = (char)k; + int x, y, sx, sy; + NumToPole(k, x, y); + for (sx = -1; sx <= 1; sx += 2) if (x + sx >= 0 && x + sx < NW_CELL) + { + for (sy = -1; sy <= 1; sy += 2) if (y + sy >= 0 && y + sy < NW_CELL) + { + int i, i0, i1; + if (sx < 0) i0 = x; + else i0 = NW_CELL - x - 1; + if (sy < 0) i1 = y; + else i1 = NW_CELL - y - 1; + if (i0 > i1) i0 = i1; + for (i = 1; i <= i0; i++) + { + int kk = PoleToNum(x + i*sx, y + i*sy); + if (pmv.pos.SH[kk]) break; + AddPos(); + (PMv&)array[narr] = pmv; + array[narr].pos.Move(k, kk); + array[narr].mv[2] = (char)kk; + array[narr].pos.wmove = !pmv.pos.wmove; + narr++; + } + } + } + } + } + } + } + pmv.mv[0] = 0; + return was_eat; +} + +template +int TBaseCompPlayer::Z::ComparePMv(const void *v1, const void *v2) +{ + PMvv *pmv1 = (PMvv*)v1, *pmv2 = (PMvv*)v2; + if (pmv1->val < pmv2->val) return -1; + else if (pmv1->val > pmv2->val) return 1; + else return 0; +} + +template +void TBaseCompPlayer::Z::Sort(int n0, int n1) +{ + qsort(array + n0, n1 - n0, sizeof(PMvv), ComparePMv); +} + + +template +tvalue TBaseCompPlayer::GetLossValue(const Position &pos) +{ + tvalue val = -win_val - 1000021L; + for (int i = 0; i < NUM_CELL; i++) + { + if (pos.SH[i] == 1 + pos.wmove) val -= 10000L; + else if (pos.SH[i] == 2 - pos.wmove) val -= 100L; + else if (pos.SH[i] == 3 + pos.wmove) val -= 80000L; + else if (pos.SH[i] == 4 - pos.wmove) val -= 100L; + } + return val; +} + +template +tvalue TBaseCompPlayer::GetValue(const Position &pos, int num) +{ + tvalue val = 0; + if (num == 0) + { + int NumDM0 = 0, NumDM1 = 0; + for (int i = 0; i < NUM_CELL; i++) + { + short PreimSHPos[32] = {243, 243, 243, 245, + 240, 240, 240, 240, + 244, 244, 244, 244, + 245, 248, 248, 245, + 249, 250, 250, 248, + 256, 260, 260, 256, + 280, 280, 280, 260, + 280, 280, 280, 280}; + if (pos.SH[i] == 1 + pos.wmove) + { + val += PreimSHPos[pos.wmove ? (NUM_CELL - 1 - i) : i]; + } + else if (pos.SH[i] == 2 - pos.wmove) + { + val -= PreimSHPos[pos.wmove ? i : (NUM_CELL - 1 - i)]; + } + else if (pos.SH[i] == 3 + pos.wmove) NumDM1++; + else if (pos.SH[i] == 4 - pos.wmove) NumDM0++; + } + if (NumDM1 > 0) + { + val += 560; NumDM1--; + if (NumDM1 > 0) + { + val += 432; NumDM1--; + val += NumDM1 * 384; + } + } + if (NumDM0 > 0) + { + val -= 560; NumDM0--; + if (NumDM0 > 0) + { + val -= 432; NumDM0--; + val -= NumDM0 * 384; + } + } + } + if (num == 1) + { + char NSH1 = 0, NSH0 = 0, NDM1 = 0, NDM0 = 0; + int i; + for (i = 0; i < 32; i++) + { + if (pos.SH[i] == 1 + pos.wmove) NSH1++; + else if (pos.SH[i] == 2 - pos.wmove) NSH0++; + else if (pos.SH[i] == 3 + pos.wmove) NDM1++; + else if (pos.SH[i] == 4 - pos.wmove) NDM0++; + } + if (NDM1 > 0 && NDM0 > 0 && NSH1 + NSH0 < 3) + { + unsigned char HwoBD = 0; + char Sh0BD = 1, Sh1BD = 1; + for (i = 0; i < 8; i++) + { + char ShBD = pos.SH[PoleToNum(i, 7 - i)]; + if (ShBD == 1 + pos.wmove) Sh1BD++; + else if (ShBD == 2 - pos.wmove) Sh0BD++; + else if (ShBD == 3 + pos.wmove) HwoBD |= 2; + else if (ShBD == 4 - pos.wmove) HwoBD |= 1; + } + if (HwoBD == 2) val += 128 / Sh0BD; + if (HwoBD == 1) val -= 128 / Sh1BD; + if (NDM1 >= 3 && NDM0 == 1 && NSH1 == 0 && NSH0 == 0 && HwoBD == 1) + { + char Best4P[4][2] = {{0,9}, {4,13}, {31,22}, {27,18}}; + char Add = 0; + for (i = 0; i < 4; i++) + { + Add |= char((pos.SH[Best4P[i][0]] == 3 + pos.wmove) * 3 + + (pos.SH[Best4P[i][1]] == 3 + pos.wmove)); + } + if (Add >= 4) val += 32; + else if (Add == 3) val += 24; + else if (Add >= 1) val += 16; + } + else if (NDM0 >= 3 && NDM1 == 1 && NSH0 == 0 && NSH1 == 0 && HwoBD == 2) + { + char Best4P[4][2] = {{0,9}, {4,13}, {31,22}, {27,18}}; + char Add = 0; + for (i = 0; i < 4; i++) + { + Add |= char((pos.SH[Best4P[i][0]] == 4 - pos.wmove) * 3 + + (pos.SH[Best4P[i][1]] == 4 - pos.wmove)); + } + if (Add >= 4) val -= 32; + else if (Add == 3) val -= 24; + else if (Add >= 1) val -= 16; + } + } + else + { + for (i = 0; i < NUM_CELL; i++) + { + char Color = char(pos.SH[i] - 1); + if (Color == 0 || Color == 1) + { + char qi = Color ? char(NUM_CELL - 1 - i) : char(i); + char Zn = Color ? char(-1) : char(1); + char PreZ = (Color == pos.wmove) ? char(1) : char(-1); + if (pos.SH[i + Zn * 8] != 2 - Color) + { + if (qi / 4 == 2) + { + char IsFree = 0; + if (pos.SH[i - Zn * 4] == 2 - Color) IsFree += (char)2; + else if (qi != 8) + { + if (pos.SH[i - Zn ] == 2 - Color || + pos.SH[i - Zn * 9] == 2 - Color) IsFree += (char)2; + else if (Color != pos.wmove) + if (pos.SH[i - Zn * 5] == 2 - Color) IsFree++; + } + if (qi == 11) IsFree += (char)2; + else if (pos.SH[i + Zn ] == 2 - Color || + pos.SH[i - Zn * 3] == 2 - Color || + pos.SH[i - Zn * 7] == 2 - Color) IsFree += (char)2; + else if (Color != pos.wmove && qi != 10) + { + if (pos.SH[i - Zn * 2] == 2 - Color) IsFree++; + } + if (IsFree < 3) val += PreZ * 176 / (1 + NDM0 + NDM1); + else if (qi == 9 || qi == 10) + { + val += PreZ * 128 / (1 + NDM0 + NDM1); + } + } + else if (qi / 4 == 3) + { + char IsFree = 0; + if (pos.SH[i - Zn * 12] == 2 - Color) + { + if (Color == pos.wmove) IsFree += (char)11; + else IsFree += (char)12; + } + else if (pos.SH[i - Zn * 4] == 2 - Color) IsFree += (char)11; + else if (qi == 15) IsFree += (char)5; + else if (pos.SH[i - Zn * 7] == 2 - Color) IsFree += (char)9; + else if (pos.SH[i + Zn] == 2 - Color) IsFree += (char)8; + else if (pos.SH[i - Zn * 11] == 2 - Color) + { + if (Color == pos.wmove) IsFree += (char)5; + else IsFree += (char)7; + } + else if (pos.SH[i - Zn * 3] == 2 - Color) IsFree += (char)5; + else if (qi != 14) + { + if (pos.SH[i - Zn * 6] == 2 - Color) IsFree += (char)3; + else if (Color != pos.wmove) + { + if (pos.SH[i - Zn * 10] == 2 - Color) IsFree++; + } + } + if (qi == 12) IsFree += (char)7; + else if (pos.SH[i - Zn * 13] == 2 - Color) + { + if (Color == pos.wmove) IsFree += (char)11; + else IsFree += (char)12; + } + else if (pos.SH[i - Zn * 5] == 2 - Color) IsFree += (char)11; + else if (pos.SH[i - Zn * 9] == 2 - Color) IsFree += (char)9; + else if (pos.SH[i - Zn] == 2 - Color) IsFree += (char)8; + else if (qi != 13) + { + if (pos.SH[i - Zn * 14] == 2 - Color) + { + if (Color == pos.wmove) IsFree += (char)5; + else IsFree += (char)7; + } + else if (pos.SH[i - Zn * 6] == 2 - Color) IsFree += (char)5; + else if (pos.SH[i - Zn * 10] == 2 - Color) IsFree += (char)3; + else if (Color != pos.wmove && qi != 14) + { + if (pos.SH[i - Zn * 15] == 2 - Color) IsFree++; + } + } + if (IsFree < ((Color == pos.wmove) ? 14 : 12)) + { + val += PreZ * 160 / (1 + NDM0 + NDM1); + } + } + } + } + } + } + } + if (num == 2) + { + char NSH1 = 0, NSH0 = 0, NDM1 = 0, NDM0 = 0; + for (int i = 0; i < NUM_CELL; i++) + { + if (pos.SH[i] == 1 + pos.wmove) NSH1++; + else if (pos.SH[i] == 2 - pos.wmove) NSH0++; + else if (pos.SH[i] == 3 + pos.wmove) NDM1++; + else if (pos.SH[i] == 4 - pos.wmove) NDM0++; + } + if (NDM1 > 0 && NDM0 > 0 && NSH1 == 0 && NSH0 == 0) + { + short PrP = 0; + char Cpos3 = -1; + if (NDM1 == 3 && NDM0 == 1 && NSH1 == 0 && NSH0 == 0) Cpos3 = 1; + else if (NDM1 == 1 && NDM0 == 3 && NSH1 == 0 && NSH0 == 0) Cpos3 = 0; + if (Cpos3 >= 0) + { + for (int Osm = 0; Osm <= 1; Osm++) for (int Csm = 0; Csm <= 1; Csm++) + { + char PosSH[7][3] = {{13, 17, 18}, {6, 17, 18}, {9, 21, 22}, + {17, 18, 19}, {9, 10, 15}, {11, 14, 18}, {2, 14, 18}}; + for (char PosNi = 0; PosNi < 7; PosNi++) + { + bool IsPosR = 1; + for (char ShNi = 0; ShNi < 3; ShNi++) + { + char DNomSh = (Csm == 1) ? char(31 - PosSH[PosNi][ShNi]) + : char(PosSH[PosNi][ShNi]); + if (Osm == 1) + { + int x, y; + NumToPole(DNomSh, x, y); + DNomSh = (char)PoleToNum(y, x); + } + if (pos.SH[DNomSh] != 3 + (Cpos3 == pos.wmove)) IsPosR = 0; + } + if (IsPosR) + { + if (PosNi == 3) + { + if (Cpos3 == 1) + { + if (pos.SH[(Csm == 1) ? 29 : 2] != + 4 - (Cpos3 == pos.wmove) && pos.SH[(Csm == 1) ? 11 : 20] != + 4 - (Cpos3 == pos.wmove)) PrP = 216; + } + else + { + bool PrPZ = 1; + for (int i = 0; i < 6; i++) + if (pos.SH[PoleToNum((Csm == 1) ? (i + 2) : i, + (Csm == 1) ? (7 - i) : (5 - i))] == + 4 - (Cpos3 == pos.wmove)) PrPZ = 0; + if (PrPZ) PrP = -216; + } + } + else if (PosNi == 4) + { + if (Cpos3 == 1) + { + if (pos.SH[ 0] != 4 - (Cpos3 == pos.wmove) && + pos.SH[ 4] != 4 - (Cpos3 == pos.wmove) && + pos.SH[27] != 4 - (Cpos3 == pos.wmove) && + pos.SH[31] != 4 - (Cpos3 == pos.wmove)) + { + PrP = 216; + } + } + else + { + if (pos.SH[(Csm == Osm) ? 4 : 0] != 4 - (Cpos3 == pos.wmove) && + pos.SH[(Csm == Osm) ? 8 : 5] != 4 - (Cpos3 == pos.wmove) && + pos.SH[(Csm == Osm) ? 26 : 23] != 4 - (Cpos3 == pos.wmove) && + pos.SH[(Csm == Osm) ? 31 : 27] != 4 - (Cpos3 == pos.wmove)) + { + PrP = -216; + } + } + } + else if (PosNi == 5) + { + char DNomSh = (Cpos3 == 1) ? ((Osm == 1) ? (char)16 : (char)6) + : ((Osm == 1) ? (char)20 : (char)2); + if (Csm == 1) DNomSh = char(31 - DNomSh); + if (pos.SH[DNomSh] == 4 - (Cpos3 == pos.wmove)) + { + PrP = (Cpos3 == 1) ? short(160) : short(-160); + } + } + else if (PosNi == 6) + { + if (Cpos3 == 1) + { + if (pos.SH[ 1] == 4 - (Cpos3 == pos.wmove) || + pos.SH[12] == 4 - (Cpos3 == pos.wmove) || + pos.SH[19] == 4 - (Cpos3 == pos.wmove) || + pos.SH[30] == 4 - (Cpos3 == pos.wmove)) + { + PrP = 168; + } + } + else + { + if (pos.SH[(Csm == 1) ? 15 : 6] == 4 - (Cpos3 == pos.wmove) || + pos.SH[(Csm == 1) ? 25 : 16] == 4 - (Cpos3 == pos.wmove)) + { + PrP = -168; + } + } + } + else PrP = short(((Cpos3 == 1) ? 1 : -1) * ((PosNi == 0) ? 200 : 208)); + } + } + } + } + if (PrP == 0) + { + unsigned char HwoBD = 0; + char NShSBD = 0; + for (int i = 0; i < 8; i++) + { + char ShBD = pos.SH[PoleToNum(i, 7 - i)]; + if (ShBD == 3 + pos.wmove) {HwoBD |= 2; NShSBD++;} + else if (ShBD == 4 - pos.wmove) {HwoBD |= 1; NShSBD++;} + } + if (NDM1 >= 3 && NDM0 == 1 && NSH1 == 0 && NSH0 == 0 && HwoBD == 2) + { + if (NShSBD >= 1) val -= NShSBD - 1; + if (pos.SH[ 3] == 3 + pos.wmove) val--; + if (pos.SH[28] == 3 + pos.wmove) val--; + char Drg1 = 0, DrgPS = 0; + bool Drg1p = 0; + for (int i = 0; i < 7; i++) + { + char Sh7D = pos.SH[PoleToNum(i, i + 1)]; + if (Sh7D == 3 + pos.wmove) {Drg1++; DrgPS |= 1;} + else if (Sh7D == 4 - pos.wmove) Drg1p = 1; + Sh7D = pos.SH[PoleToNum(i + 1, i)]; + if (Sh7D == 3 + pos.wmove) {Drg1++; DrgPS |= 2;} + else if (Sh7D == 4 - pos.wmove) Drg1p = 1; + } + if (pos.SH[0] == 3 + pos.wmove || pos.SH[4] == 3 + pos.wmove || + pos.SH[27] == 3 + pos.wmove || pos.SH[31] == 3 + pos.wmove) + {if (Drg1p) val += 4; else val -= 1;} + if ((pos.SH[14] == 3 + pos.wmove) == (pos.SH[17] == 3 + pos.wmove)) + {if (Drg1 == 1) val += 2;} + else + { + if (Drg1 >= 2) + { + if (Drg1 > 2) val -= 1; + if (DrgPS == 3) val += 4; + if (Drg1p) val += 4; else val += 16; + if (!Drg1p && DrgPS) + { + Drg1 = 0; Drg1p = 0; DrgPS = 0; + for (int i = 0; i < 6; i++) + { + char Sh7D = pos.SH[PoleToNum(i, 5 - i)]; + if (Sh7D == 3 + pos.wmove) {Drg1++; DrgPS |= 1;} + else if (Sh7D == 4 - pos.wmove) Drg1p = 1; + Sh7D = pos.SH[PoleToNum(i + 2, 7 - i)]; + if (Sh7D == 3 + pos.wmove) {Drg1++; DrgPS |= 2;} + else if (Sh7D == 4 - pos.wmove) Drg1p = 1; + } + if (pos.SH[2] == 3 + pos.wmove || pos.SH[11] == 3 + pos.wmove || + pos.SH[20] == 3 + pos.wmove || pos.SH[29] == 3 + pos.wmove) + val += 4; + if ((pos.SH[14] == 3 + pos.wmove) + ? (pos.SH[13] == 3 + pos.wmove || pos.SH[22] == 3 + pos.wmove) + : (pos.SH[ 9] == 3 + pos.wmove || pos.SH[18] == 3 + pos.wmove)) + { + if (Drg1 >= 2) + { + if (DrgPS == 3) val += 4; + if (Drg1p) val += 4; else val += 16; + } + else if (Drg1 == 1) val += 1; + } + else if (Drg1 == 1) val += 2; + } + } + } + } + else if (NDM0 >= 3 && NDM1 == 1 && NSH0 == 0 && NSH1 == 0 && HwoBD == 1) + { + if (NShSBD >= 1) val += NShSBD - 1; + if (pos.SH[ 3] == 4 - pos.wmove) val++; + if (pos.SH[28] == 4 - pos.wmove) val++; + char Drg1 = 0, DrgPS = 0; + bool Drg1p = 0; + for (int i = 0; i < 7; i++) + { + char Sh7D = pos.SH[PoleToNum(i, i + 1)]; + if (Sh7D == 4 - pos.wmove) {Drg1++; DrgPS |= 1;} + else if (Sh7D == 3 + pos.wmove) Drg1p = 1; + Sh7D = pos.SH[PoleToNum(i + 1, i)]; + if (Sh7D == 4 - pos.wmove) {Drg1++; DrgPS |= 2;} + else if (Sh7D == 3 + pos.wmove) Drg1p = 1; + } + if (pos.SH[0] == 4 - pos.wmove || pos.SH[4] == 4 - pos.wmove || + pos.SH[27] == 4 - pos.wmove || pos.SH[31] == 4 - pos.wmove) + {if (Drg1p) val -= 4; else val += 1;} + if ((pos.SH[14] == 4 - pos.wmove) == (pos.SH[17] == 4 - pos.wmove)) + {if (Drg1 == 1) val -= 2;} + else + { + if (Drg1 >= 2) + { + if (Drg1 > 2) val += 1; + if (DrgPS == 3) val -= 4; + if (Drg1p) val -= 4; else val -= 16; + if (!Drg1p && DrgPS) + { + Drg1 = 0; Drg1p = 0; DrgPS = 0; + for (int i = 0; i < 6; i++) + { + char Sh7D = pos.SH[PoleToNum(i, 5 - i)]; + if (Sh7D == 4 - pos.wmove) {Drg1++; DrgPS |= 1;} + else if (Sh7D == 3 + pos.wmove) Drg1p = 1; + Sh7D = pos.SH[PoleToNum(i + 2, 7 - i)]; + if (Sh7D == 4 - pos.wmove) {Drg1++; DrgPS |= 2;} + else if (Sh7D == 3 + pos.wmove) Drg1p = 1; + } + if (pos.SH[2] == 4 - pos.wmove || pos.SH[11] == 4 - pos.wmove || + pos.SH[20] == 4 - pos.wmove || pos.SH[29] == 4 - pos.wmove) + { + val -= 4; + } + if ((pos.SH[14] == 4 - pos.wmove) + ? (pos.SH[13] == 4 - pos.wmove || pos.SH[22] == 4 - pos.wmove) + : (pos.SH[ 9] == 4 - pos.wmove || pos.SH[18] == 4 - pos.wmove)) + { + if (Drg1 >= 2) + { + if (DrgPS == 3) val -= 4; + if (Drg1p) val -= 4; else val -= 16; + } + else if (Drg1 == 1) val -= 1; + } + else if (Drg1 == 1) val -= 2; + } + } + } + } + else if (NDM1 >= 3 && NDM0 == 1 && NSH1 == 0 && NSH0 == 0 && HwoBD == 1) + { + char Best4P[4][2] = {{0,9}, {4,13}, {31,22}, {27,18}}; + char Add = 0; + for (int i = 0; i < 4; i++) + { + Add |= char((pos.SH[Best4P[i][0]] == 3 + pos.wmove) * 3 + + (pos.SH[Best4P[i][1]] == 3 + pos.wmove)); + } + if (Add >= 4) val += 3; + else if (Add == 3) val += 2; + else if (Add >= 1) val += 1; + } + else if (NDM0 >= 3 && NDM1 == 1 && NSH0 == 0 && NSH1 == 0 && HwoBD == 2) + { + char Best4P[4][2] = {{0,9}, {4,13}, {31,22}, {27,18}}; + char Add = 0; + for (int i = 0; i < 4; i++) + { + Add |= char((pos.SH[Best4P[i][0]] == 4 - pos.wmove) * 3 + + (pos.SH[Best4P[i][1]] == 4 - pos.wmove)); + } + if (Add >= 4) val -= 3; + else if (Add == 3) val -= 2; + else if (Add >= 1) val -= 1; + } + } + else val += PrP; + } + } + return val; +} + +template +tvalue TBaseCompPlayer::GetFullValue(const Position &pos, int num) +{ + if (!pos.AllCanMove() && !pos.AllCanEat()) return GetLossValue(pos); + else return GetValue(pos, num); +} + +template +tvalue TBaseCompPlayer::FindBMove(Z &z, int num, + PMvv *pmv, int zn, tvalue a, tvalue b) +{ + assert(b > a); + assert(num >= 0); + if (num >= 3 && draw) draw(data); + int nlast = z.narr; + if (zn < 0) {z.AddPos(); z.array[zn = z.narr++] = *pmv;} + if (pmv) pmv->mv[0] = 0; + int n0 = z.narr; + int was_eat = z.FindAllMoves(z.array[zn], num <= 0); + int n1 = z.narr; + tvalue val; + if (n1 == n0) + { + assert(!z.array[zn].pos.AllCanEat()); + assert(num == 0 || !z.array[zn].pos.AllCanMove()); + if (num > 0 || !z.array[zn].pos.AllCanMove()) val = GetLossValue(z.array[zn].pos); + else val = GetValue(z.array[zn].pos, 0); + } + else if (pmv && n1 == n0 + 1 && nlast < n0) + { + *pmv = z.array[n0]; + if (!z.array[n0].pos.AllCanMove() && !z.array[n0].pos.AllCanMove()) + { + val = -1 - GetLossValue(z.array[n0].pos); + } + else + { + val = -GetValue(z.array[n0].pos, 0); + n1 = -1; + } + } + else + { + int k, opt; + if (num >= 2) + { + if (pmv && n1 > n0 + 1) + { + for (k = 0; k < 2*(n1 - n0); k++) + { + int i0 = n0 + random(n1 - n0), i1 = n0 + random(n1 - n0 - 1); + if (i1 >= i0) i1++; + PMvv t_pmv = z.array[i0]; + z.array[i0] = z.array[i1]; + z.array[i1] = t_pmv; + } + } + for (k = n0; k < n1; k++) z.array[k].val = GetFullValue(z.array[k].pos); + z.Sort(n0, n1); + } + tvalue cc = 2 * win_val; + tvalue dval = was_eat ? 0 : GetValue(z.array[zn].pos, num); + tvalue aa = -b, bb = -a; + if (aa < -win_val) aa--; + else if (aa > win_val) aa++; + else aa += dval; + if (bb < -win_val) bb--; + else if (bb > win_val) bb++; + else bb += dval; + for (k = n0; k < n1 && bb > aa; k++) + { + tvalue vk; + vk = FindBMove(z, num-1+was_eat, 0, k, aa, bb); + if (vk < cc) + { + opt = k; cc = vk; + if (bb > cc) bb = cc; + } + } + if (cc < -win_val) cc++; + else if (cc > win_val) cc--; + else cc -= dval; + val = -cc; + assert(opt >= n0 && opt < n1); + if (pmv) *pmv = z.array[opt]; + } + z.array[zn].val = val; + z.narr = nlast; + if (pmv) + { + if (n1 >= 0) printf("Checkers: value = %ld\n", val); + else printf("Checkers: value = ?\n"); + } + return val; +} + +template +int TBaseCompPlayer::Move(PMv &pmv) +{ + Z z; + PMvv zpmv; + (PMv&)zpmv = pmv; + if (draw) draw(data, 1); + FindBMove(z, 6, &zpmv); + if (draw) draw(data, -1); + if (zpmv.mv[0] == 0) return 0; + pmv = zpmv; + return 1; +} + +typedef TBaseCompPlayer TComputerPlayer; + +#endif //_HEADER_PLAYER_H diff --git a/programs/games/checkers/trunk/position.h b/programs/games/checkers/trunk/position.h new file mode 100644 index 0000000000..30599a773f --- /dev/null +++ b/programs/games/checkers/trunk/position.h @@ -0,0 +1,882 @@ +#ifndef _HEADER_POSITION_H +#define _HEADER_POSITION_H + +#ifndef __MENUET__ +#include +#include +#include +#include +#endif + +#define NELEM(a) (sizeof(a) / sizeof((a)[0])) + +const int NW_CELL = 8; + +const int NUM_CELL = NW_CELL * NW_CELL / 2; +const int LEN_WPOS = (NUM_CELL + 2) / 3; + +inline int PoleCpos(int i, int j) +{ + return (i + j) % 2 != 0; +} + +inline int PoleToNum(int i, int j) +{ + return j * (NW_CELL / 2) + i/2; +} + +inline void NumToPole(int k, int &i, int &j) +{ + j = k / (NW_CELL / 2); + i = k % (NW_CELL / 2); + i *= 2; + if (j % 2 == 0) i++; +} + +class Position +{ +public: + char SH[NUM_CELL]; + char wmove; + + Position() {Init();} + Position(const Position &p); + Position& operator=(const Position &p); + + void Init(); + int IsNull() const; + void Add(int np, char sh) {SH[np] = sh;} + void Del(int np) {SH[np] = 0;} + void Move(int np0, int np1) {if (np0 != np1) {SH[np1] = SH[np0]; SH[np0] = 0;}} + static int BecameD(int np, char ch); + + enum {AWrong = -1, AWColor = -2, AfCell = -3, AnfCell = -4, + AMustEatMore = -5, AMustEat = -6, ANoMove = -7, AChBack = -8, + ANotDm = -9, AOnlyDiag = -10, AEatYour = -11, AMoreOne = -12, + ANotDmE = -13, AMustEatMoreD = -14, ATurnBack = -15}; + + int ScanSide(int x, int y, int sx, int sy, int sh_k = -1) const; + int CanEat(int k, int psx = 0, int psy = 0, int sh_k = -1) const; + int CanMove(int k) const; + int AChCell(int k); + int AMove(const unsigned char MV[], int k = -1, int &mkmove = *(int*)0); + int AllCanEat(int w = -1) const; + int AllCanMove(int w = -1) const; + + char *Write(char WP[], int how = 0) const; + Position &Read(const char WP[], int how = 0); + static char *WriteMv(const unsigned char mv[], char WP[], int how = 0); + int WriteMvEx(const unsigned char mv[], char WP[], int how = 0) const; + static unsigned char *ReadMv(unsigned char mv[], const char WP[], int how = 0); + static int GetLenMv(const unsigned char mv[], int how = 0); + int GetLenMvEx(const unsigned char mv[], int how = 0) const; + static int GetLenMwr(const char WP[], int how = 0); + static void SetNullMv(unsigned char mv[]) {mv[0] = 0;} + void Reverse(); +}; + +Position::Position(const Position &p) : wmove(p.wmove) +{ + for(int i = 0; i < NUM_CELL; i++) SH[i] = p.SH[i]; +} + +Position& Position::operator=(const Position &p) +{ + wmove = p.wmove; + for(int i = 0; i < NUM_CELL; i++) SH[i] = p.SH[i]; + return *this; +} + +void Position::Init() +{ + wmove = 0; + for (int i = 0; i < NUM_CELL; i++) SH[i] = 0; +} + +int Position::IsNull() const +{ + for (int i = 0; i < NUM_CELL; i++) if (SH[i] != 0) return 0; + return 1; +} + +inline int Position::BecameD(int np, char ch) +{ + int x, y; + NumToPole(np, x, y); + return ch == 1 && y == NW_CELL - 1 || ch == 2 && y == 0; +} + +char *Position::Write(char WP[], int how) const +{ + if (how == 0) + { + int i = 0, j; + for (j = 0; i < NUM_CELL; j++) + { + WP[j] = SH[i++]; + if (i < NUM_CELL) {WP[j] *= (char)5; WP[j] += SH[i++];} + if (i < NUM_CELL) {WP[j] *= (char)5; WP[j] += SH[i++];} + if (i >= NUM_CELL) {WP[j] *= (char)2; WP[j] += wmove;} + WP[j]++; + } + } + else if (how == 1) + { + int i; + for (i = NUM_CELL - 1; i >= 0; i--) + { + if (SH[i] < 0 || SH[i] >= 5) return 0; + } + for (i = 0; i < NUM_CELL; i++) + { + const char SYMBOL[5] = {'0', 'R', 'B', 'X', 'Z'}; + WP[i] = SYMBOL[SH[NUM_CELL - 1 - i]]; + } + WP[NUM_CELL] = ':'; + WP[NUM_CELL + 1] = (wmove == 0) ? 'r' : 'b'; + WP[NUM_CELL + 2] = 0; + } + return WP; +} + +Position &Position::Read(const char WP[], int how) +{ + if (how == 0) + { + int i = 0, j, ii; + for (j = 0; i < NUM_CELL; j++) + { + unsigned int cwp = WP[j] - 1; + if (i >= NUM_CELL - 3) + { + wmove = char(cwp % 2); + cwp /= 2; + ii = NUM_CELL - 1; + } + else ii = i + 2; + while(ii >= i) {SH[ii--] = char(cwp % 5); cwp /= 5;} + i += 3; + } + } + else if (how == 1) + { + int i; + wmove = 0; + for (i = 0; i < NUM_CELL; i++) + { + switch(WP[i]) + { + case '0': + case '-': case '.': + case 'F': case 'f': + SH[NUM_CELL - 1 - i] = 0; + break; + case '1': + case 'A': case 'a': + case 'R': case 'r': + SH[NUM_CELL - 1 - i] = 1; + break; + case '2': + case 'B': case 'b': + case 'S': case 's': + SH[NUM_CELL - 1 - i] = 2; + break; + case '3': + case 'W': case 'w': + case 'X': case 'x': + SH[NUM_CELL - 1 - i] = 3; + break; + case '4': + case 'Y': case 'y': + case 'Z': case 'z': + SH[NUM_CELL - 1 - i] = 4; + break; + default: + Init(); + return *this; + } + } + if (WP[NUM_CELL] == ':') + { + char c = WP[NUM_CELL + 1]; + if (c == 'B' || c == 'b' || c == 'S' || c == 's' || + c == 'Y' || c == 'y' || c == 'Z' || c == 'z') + { + wmove = 1; + } + } + } + return *this; +} + +char *Position::WriteMv(const unsigned char mv[], char WP[], int how) +{ + int i, nmv = 0; + if (mv) nmv = mv[0]; + if (how == 0) + { + WP[0] = char(nmv + 1); + for (i = 1; i <= nmv; i++) WP[i] = char(mv[i] + 1); + } + else if (how == 1) + { + int j = 0; + for (i = 1; i <= nmv; i++) + { + int x, y; + NumToPole(mv[i], x, y); + WP[j++] = char('a' + NW_CELL - 1 - x); + int r = sprintf(WP + j, "%d", 1 + y); + if (r > 0) j += r; + if (i != nmv) WP[j++] = '-'; + } + WP[j] = 0; + } + return WP; +} + +unsigned char *Position::ReadMv(unsigned char mv[], const char WP[], int how) +{ + int i; + if (how == 0) + { + mv[0] = char(WP[0] - 1); + for (i = 1; i <= mv[0]; i++) mv[i] = char(WP[i] - 1); + } + else if (how == 1) + { + int j = 0, x = -1, y = -1; + mv[0] = 0; + for (;;) + { + if (isdigit(WP[j])) + { + y = atoi(WP + j) - 1; + while (isdigit(WP[j])) j++; + } + else if (islower(WP[j])) x = NW_CELL - 1 - (WP[j++] - 'a'); + else + { + if (x >= 0 && y >= 0 && x < NW_CELL && y < NW_CELL) + { + mv[++mv[0]] = (char)PoleToNum(x, y); + } + else if (y >= 0 && y < NUM_CELL) mv[++mv[0]] = (char)(NUM_CELL - 1 - y); + x = -1; y = -1; + if (WP[j] == '-' || WP[j] == '*' || WP[j] == ':') j++; + else break; + } + if (x >= 0 && y >= 0 && x < NW_CELL && y < NW_CELL) + { + mv[++mv[0]] = (char)PoleToNum(x, y); + x = -1; y = -1; + } + } + } + return mv; +} + +int Position::GetLenMv(const unsigned char mv[], int how) +{ + if (how == 0) return mv ? (1 + mv[0]) : 1; + else if (how == 1) + { + int i, j = 0; + if (!mv) return 1; + for (i = 1; i <= mv[0]; i++) + { + int x, y; + NumToPole(mv[i], x, y); + j++; y++; + while(y > 0) {j++; y /= 10;} + if (i != mv[0]) j++; + } + return ++j; + } + else return 0; +} + +int Position::GetLenMwr(const char WP[], int how) +{ + if (how == 0) return (unsigned char)WP[0]; + else if (how == 1) + { + int j; + for (j = 0; WP[j] == '-' || WP[j] == '*' || + WP[j] == ':' || isdigit(j) || islower(j); j++); + return j + 1; + } + else return 0; +} + +inline int Position::GetLenMvEx(const unsigned char mv[], int how) const +{ + return WriteMvEx(mv, 0, how); +} + +int Position::WriteMvEx(const unsigned char mv[], char WP[], int how) const +{ + if (how == 11) + { + Position pos = *this; + int p, L = 0, was_d = 0; + for (p = 1; p <= mv[0]; p++) + { + if (!was_d && pos.SH[mv[p]] > 2) + { + if (WP) WP[L] = '*'; + L++; + was_d = 1; + } + int x0, y0, x1, y1; + NumToPole(mv[p], x0, y0); + if (WP) + { + WP[L++] = char('a' + NW_CELL - 1 - x0); + int r = sprintf(WP + L, "%d", 1 + y0); + if (r > 0) L += r; + } + else + { + L++; + int g = y0 + 1; + while(g > 0) {L++; g /= 10;} + } + if (p >= mv[0]) break; + NumToPole(mv[p+1], x1, y1); + int mi = abs(x1 - x0), i, eat = -1; + if (mi > 0 && mi == abs(y1 - y0)) + { + int sx = (x1 > x0) ? 1 : -1; + int sy = (y1 > y0) ? 1 : -1; + for (i = 1; i < mi; i++) + { + int r = PoleToNum(x0 + i * sx, y0 + i * sy); + if (pos.SH[r] != 0) + { + eat = r; + pos.Del(r); + } + } + } + if (WP) WP[L] = (eat >= 0) ? ':' : '-'; + L++; + if (pos.SH[mv[p]] == 1 && y1 == NW_CELL - 1) pos.SH[mv[p]] = 3; + else if (pos.SH[mv[p]] == 2 && y1 == 0) pos.SH[mv[p]] = 4; + pos.Move(mv[p], mv[p+1]); + } + if (WP) WP[L] = 0; + L++; + return L; + } + else + { + if (WP) WriteMv(mv, WP, how); + return GetLenMv(mv, how); + } +} + +int Position::ScanSide(int x, int y, int sx, int sy, int sh_k) const +{ + if (sh_k < 0) sh_k = SH[PoleToNum(x, y)]; + if (sh_k < 1 || sh_k > 4) return -2; + if (sh_k >= 2) sh_k -= 2; + int i, i0, i1, f = 0, g = 0; + if (sx < 0) i0 = x; + else i0 = NW_CELL - x - 1; + if (sy < 0) i1 = y; + else i1 = NW_CELL - y - 1; + if (i0 > i1) i0 = i1; + for (i = 1; i <= i0; i++) + { + char nk = SH[PoleToNum(x + i*sx, y + i*sy)]; + if (nk) + { + if (f || (nk != 3 - sh_k && nk != 5 - sh_k)) return g; + else f = 1; + } + else if (f) return (i == 2) ? 4 : (2 + g); + else if (i == 1) g = 1; + } + return g; +} + +int Position::CanEat(int k, int psx, int psy, int sh_k) const +{ + int x, y, sx, sy; + if (sh_k < 0) sh_k = SH[k]; + if (sh_k < 1 || sh_k > 6) return 0; + NumToPole(k, x, y); + if (sh_k > 4) + { + int i, i0, i1, f = 0; + if (-psx < 0) i0 = x; + else i0 = NW_CELL - x - 1; + if (-psy < 0) i1 = y; + else i1 = NW_CELL - y - 1; + if (i0 > i1) i0 = i1; + for (i = 1; i <= i0; i++) + { + int nk = SH[PoleToNum(x - i*psx, y - i*psy)]; + if (nk) + { + if (f || (nk != 7 - sh_k && nk != 9 - sh_k)) break; + else f = 1; + } + else + { + if (f) return 1; + if (ScanSide(x - i*psx, y - i*psy, psy, -psx, sh_k-2) >= 2) return 1; + if (ScanSide(x - i*psx, y - i*psy, -psy, psx, sh_k-2) >= 2) return 1; + } + } + } + else for (sx = -1; sx <= 1; sx += 2) if (x + 2*sx >= 0 && x + 2*sx < NW_CELL) + { + for (sy = -1; sy <= 1; sy += 2) + { + if ((sx != psx || sy != psy) && y + 2*sy >= 0 && y + 2*sy < NW_CELL) + { + if (sh_k <= 2) + { + if (SH[PoleToNum(x + 2*sx, y + 2*sy)] == 0) + { + int nk = SH[PoleToNum(x + sx, y + sy)]; + if (nk == 3 - sh_k || nk == 5 - sh_k) return 1; + } + } + else if (ScanSide(x, y, sx, sy, sh_k) >= 2) return 1; + } + } + } + return 0; +} + +int Position::CanMove(int k) const +{ + int x, y, xx, yy, y1, y2; + NumToPole(k, x, y); + if (SH[k] == 1) y1 = y2 = y + 1; + else if (SH[k] == 2) y1 = y2 = y - 1; + else if (SH[k] != 3 && SH[k] != 4) return 0; + else {y1 = y - 1; y2 = y + 1;} + for (yy = y1; yy <= y2; yy += 2) if (yy >= 0 && yy < NW_CELL) + { + for (xx = x - 1; xx <= x + 1; xx += 2) if (xx >= 0 && xx < NW_CELL) + { + if (SH[PoleToNum(xx, yy)] == 0) return 1; + } + } + return 0; +} + +int Position::AChCell(int k) +{ + if (k < 0 || k >= NUM_CELL) return AWrong; + if (SH[k] == 0) return AfCell; + if (SH[k] != 1 + wmove && SH[k] != 3 + wmove) return AWColor; + if (CanEat(k)) return 1; + if (AllCanEat()) return AMustEat; + if (CanMove(k)) return 1; + return ANoMove; +} + +int Position::AMove(const unsigned char MV[], int k, int &mkmove) +{ + if (k >= NUM_CELL) return AWrong; + if (MV[0] <= 0) + { + if (k < 0) return NUM_CELL; + int s = AChCell(k); + if (s < 0) return s; + else return NUM_CELL; + } + if (MV[0] == 1 && k < 0) + { + int s = AChCell(MV[1]); + if (s < 0) return s; + else return NUM_CELL; + } + if (SH[MV[1]] == 0) return AfCell; + if (SH[MV[1]] != 1 + wmove && SH[MV[1]] != 3 + wmove) return AWColor; + int i, mi, p, MV_L, MV_N = MV[0], eat = -1, r; + int psx = 0, psy = 0; + if (k >= 0) MV_N++; + Position pos = *this; + for (p = 1; p < MV_N; p++) + { + int x0, y0, x1, y1, i_eat; + if (p < MV[0]) MV_L = MV[p+1]; + else if (k < 0) break; + else MV_L = k; + if (pos.SH[MV_L] != 0) return AnfCell; + NumToPole(MV[p], x0, y0); + NumToPole(MV_L, x1, y1); + mi = abs(x1 - x0); + if (mi <= 0 || mi != abs(y1 - y0)) return AOnlyDiag; + int sx = (x1 > x0) ? 1 : -1; + int sy = (y1 > y0) ? 1 : -1; + if (sx == psx && sy == psy) return ATurnBack; + psx = -sx; psy = -sy; + eat = -1; i_eat = -1; + for (i = 1; i < mi; i++) + { + r = PoleToNum(x0 + i * sx, y0 + i * sy); + if (pos.SH[r] != 0) + { + if (eat >= 0) return AMoreOne; + if (pos.SH[r] != 2 - wmove && pos.SH[r] != 4 - wmove) return AEatYour; + eat = r; i_eat = i; + pos.Del(r); + } + } + if (eat >= 0) + { + if (pos.SH[MV[p]] <= 2 && mi != 2) return ANotDmE; + } + else + { + if (MV_N > 2) return AMustEatMore; + if (pos.SH[MV[p]] <= 2) + { + if (mi != 1) return ANotDm; + if (wmove == 0 && y1 < y0 || wmove == 1 && y1 > y0) return AChBack; + } + if (AllCanEat()) return AMustEat; + } + if (i_eat >= 0 && pos.SH[MV[p]] > 2) + { + if (!pos.CanEat(MV_L, psx, psy, pos.SH[MV[p]])) + { + if (pos.CanEat(PoleToNum(x0 + i_eat*sx, y0 + i_eat*sy), + psx, psy, pos.SH[MV[p]] + 2)) + { + return AMustEatMoreD; + } + } + } + if (wmove == 0 && y1 == NW_CELL - 1) pos.SH[MV[p]] = 3; + else if (wmove == 1 && y1 == 0) pos.SH[MV[p]] = 4; + pos.Move(MV[p], MV_L); + } + if (&mkmove) + { + int end = MV_N > 1 && (eat < 0 || !pos.CanEat(MV_L, psx, psy)); + if (mkmove == 1 && end) + { + *this = pos; + wmove = !wmove; + } + if (end) mkmove = 0; + else + { + if (MV_N > 1 && eat >= 0) mkmove = AMustEatMore; + else mkmove = AWrong; + } + } + if (k < 0 || eat < 0) eat = NUM_CELL; + return eat; +} + +int Position::AllCanEat(int w) const +{ + int k; + if (w < 0) w = wmove; + for (k = 0; k < NUM_CELL; k++) + { + if ((SH[k] == w+1 || SH[k] == w+3) && CanEat(k)) return 1; + } + return 0; +} + +int Position::AllCanMove(int w) const +{ + int k; + if (w < 0) w = wmove; + for (k = 0; k < NUM_CELL; k++) + { + if ((SH[k] == w+1 || SH[k] == w+3) && CanMove(k)) return 1; + } + return 0; +} + +void Position::Reverse() +{ + int i; + for (i = 0; i <= (NUM_CELL-1) / 2; i++) + { + int sh1 = SH[i], sh2 = SH[NUM_CELL - 1 - i]; + if (sh1 == 1) sh1 = 2; + else if (sh1 == 2) sh1 = 1; + else if (sh1 == 3) sh1 = 4; + else if (sh1 == 4) sh1 = 3; + if (sh2 == 1) sh2 = 2; + else if (sh2 == 2) sh2 = 1; + else if (sh2 == 3) sh2 = 4; + else if (sh2 == 4) sh2 = 3; + SH[i] = (char)sh2; SH[NUM_CELL - 1 - i] = (char)sh1; + } + wmove = !wmove; +} + + +class PlayWrite +{ +public: + PlayWrite() : play(0), mplay(0), nplay(0), start(0), mstart(0), nstart(0) {} + PlayWrite(const PlayWrite &pl) : play(0), mplay(0), nplay(0), + start(0), mstart(0), nstart(0) {(*this) = pl;} + ~PlayWrite() {Clear();} + + void Clear(); + PlayWrite &operator=(const PlayWrite &pl); + int GetN() const {return nstart - 1;} + int GetLen() const {return nplay - sizeof(int);} + + struct PMv + { + Position pos; + unsigned char mv[NUM_CELL]; + }; + + void Add(const unsigned char move[], const Position &pos); + void Add(const PMv &pmv) {Add(pmv.mv, pmv.pos);} + int Add(const unsigned char move[]); + int GetMove(unsigned char move[], int k) const; + int GetPos(Position &pos, int k) const; + int GetPMv(PMv &pmv, int k) const; + int GetMoveL(unsigned char move[], int k = 0) const + {return GetMove(move, nstart - 2 - k);} + int GetPosL(Position &pos, int k = 0) const {return GetPos(pos, nstart - 2 - k);} + int GetPMvL(PMv &pmv, int k = 0) const {return GetPMv(pmv, nstart - 2 - k);} + int ClearFrom(int k = 0); + int IsDraw(int nmove = -1); +protected: + void IncPlay(int k); + void IncStart(int k); + void IncStart() {IncStart(nstart + 1);} + void AddStart() {IncStart(); start[nstart++] = nplay;} + void Split(); + void SplitClear(); +protected: + char *play; + int *start; + int mplay, nplay, mstart, nstart; +}; + +void PlayWrite::Clear() +{ + if (play) + { + if ((*(int*)play) > 0) (*(int*)play)--; + else delete[] play; + } + play = 0; mplay = 0; nplay = 0; + if (start) + { + if (start[0] > 0) start[0]--; + else delete[] start; + } + start = 0; mstart = 0; nstart = 0; +} + +void PlayWrite::Split() +{ + if (play && (*(int*)play) > 0) + { + (*(int*)play)--; + char *play0 = play; + mplay = nplay; + play = new char[mplay]; + memcpy(play, play0, nplay * sizeof(play[0])); + (*(int*)play) = 0; + } + if (start && start[0] > 0) + { + start[0]--; + int *start0 = start; + mstart = nstart; + start = new int[mstart]; + memcpy(start, start0, nstart * sizeof(start[0])); + start[0] = 0; + } +} + +void PlayWrite::SplitClear() +{ + if (play && (*(int*)play) > 0) + { + (*(int*)play)--; + play = 0; + nplay = 0; mplay = 0; + } + if (start && start[0] > 0) + { + start[0]--; + start = 0; + nstart = 0; mstart = 0; + } +} + +PlayWrite &PlayWrite::operator=(const PlayWrite &pl) +{ + if (&pl != this) + { + play = pl.play; + (*(int*)play)++; + nplay = pl.nplay; mplay = pl.mplay; + start = pl.start; + start[0]++; + nstart = pl.nstart; mstart = pl.mstart; + } + return *this; +} + +void PlayWrite::IncPlay(int k) +{ + if (mplay < k) + { + int m0 = mplay; + char *play0 = play; + mplay = 2*k + 10; + play = new char[mplay]; + memcpy(play, play0, m0 * sizeof(play[0])); + (*(int*)play) = 0; + if (play0) + { + if ((*(int*)play0) > 0) (*(int*)play0)--; + else delete[] play0; + } + } +} + +void PlayWrite::IncStart(int k) +{ + if (mstart < k) + { + int m0 = mstart; + int *start0 = start; + mstart = 2*k + 10; + start = new int[mstart]; + memcpy(start, start0, m0 * sizeof(start[0])); + start[0] = 0; + if (start0) + { + if (start0[0] > 0) start0[0]--; + else delete[] start0; + } + } +} + +void PlayWrite::Add(const unsigned char move[], const Position &pos) +{ + Split(); + int k = Position::GetLenMv(move); + if (nstart < 1) nstart = 1; + if (nplay < sizeof(int)) nplay = sizeof(int); + AddStart(); + IncPlay(nplay + k + LEN_WPOS); + Position::WriteMv(move, play + nplay, 0); + nplay += k; + pos.Write(play + nplay, 0); + nplay += LEN_WPOS; +} + +int PlayWrite::Add(const unsigned char move[]) +{ + if (nstart <= 1) return 1; + Position pos; + GetPosL(pos); + int mkmove = 1; + int res = pos.AMove(move, -1, mkmove); + if (res < 0) return res; + else if (mkmove != 0) return mkmove; + Add(move, pos); + return 0; +} + +int PlayWrite::GetMove(unsigned char move[], int k) const +{ + if (!play || !start) return -1; + k++; + if (k <= 0 || k >= nstart) return -1; + Position::ReadMv(move, play + start[k], 0); + return Position::GetLenMv(move); +} + +int PlayWrite::GetPos(Position &pos, int k) const +{ + if (!play || !start) return -1; + k++; + if (k <= 0 || k >= nstart) return -1; + int mlen = Position::GetLenMwr(play + start[k], 0); + pos.Read(play + start[k] + mlen, 0); + return LEN_WPOS; +} + +int PlayWrite::GetPMv(PMv &pmv, int k) const +{ + if (!play || !start) return -1; + k++; + if (k <= 0 || k >= nstart) return -1; + Position::ReadMv(pmv.mv, play + start[k], 0); + int mlen = Position::GetLenMv(pmv.mv); + pmv.pos.Read(play + start[k] + mlen, 0); + return mlen + LEN_WPOS; +} + +int PlayWrite::ClearFrom(int k) +{ + if (!play || !start) return 0; + k++; + if (k >= nstart) return 0; + if (k <= 1) {Clear(); return 2;} + nplay = start[k]; + nstart = k; + return 1; +} + +int PlayWrite::IsDraw(int nmove) +{ + nmove++; + if (nmove <= 0 || nmove > nstart) nmove = nstart; + if (!start || nmove <= 3) return 0; + int i, j, k, draw = 0; + for (i = 1; i < nmove; i++) + { + k = 1; + char *p1 = play + start[i] + Position::GetLenMwr(play + start[i], 0); + for (j = 1; j < i; j++) + { + char *p2 = play + start[j] + Position::GetLenMwr(play + start[j], 0); + if (memcmp(p1, p2, LEN_WPOS) == 0) k++; + } + if (k >= 3) {draw = 1; break;} + } + return draw; +} + + +class TChPlayer +{ +public: + TChPlayer() {} + + typedef struct PlayWrite::PMv PMv; + + virtual int PlayerID() {return 0;} + virtual int Move(PMv &pmv) = 0; + + int Move(Position &pos, char mv[]); +}; + +int TChPlayer::Move(Position &pos, char mv[]) +{ + PMv pmv; + pmv.pos = pos; memcpy(pmv.mv, mv, sizeof(pmv.mv)); + int res = Move(pmv); + pos = pmv.pos; memcpy(mv, pmv.mv, sizeof(pmv.mv)); + return res; +} + +#endif //_HEADER_POSITION_H diff --git a/programs/games/checkers/trunk/qsort.c b/programs/games/checkers/trunk/qsort.c new file mode 100644 index 0000000000..6edc89a627 --- /dev/null +++ b/programs/games/checkers/trunk/qsort.c @@ -0,0 +1,331 @@ +static void shortsort(char *lo, char *hi, unsigned width, + int (*comp)(const void *, const void *)); + +static void swap(char *p, char *q, unsigned width); + +/* this parameter defines the cutoff between using quick sort and + insertion sort for arrays; arrays with lengths shorter or equal to the + below value use insertion sort */ + +#define CUTOFF 8 /* testing shows that this is good value */ + +#define STKSIZ (8*sizeof(void*) - 2) + +/*** +*qsort(base, num, wid, comp) - quicksort function for sorting arrays +* +*Purpose: +* quicksort the array of elements +* side effects: sorts in place +* maximum array size is number of elements times size of elements, +* but is limited by the virtual address space of the processor +* +*Entry: +* char *base = pointer to base of array +* unsigned num = number of elements in the array +* unsigned width = width in bytes of each array element +* int (*comp)() = pointer to function returning analog of strcmp for +* strings, but supplied by user for comparing the array elements. +* it accepts 2 pointers to elements. +* Returns neg if 1<2, 0 if 1=2, pos if 1>2. +* +*Exit: +* returns void +* +*******************************************************************************/ + +void qsort ( + void *base, + unsigned num, + unsigned width, + int (*comp)(const void *, const void *) + ) +{ + /* Note: the number of stack entries required is no more than + 1 + log2(num), so 30 is sufficient for any array */ + char *lo, *hi; /* ends of sub-array currently sorting */ + char *mid; /* points to middle of subarray */ + char *loguy, *higuy; /* traveling pointers for partition step */ + unsigned size; /* size of the sub-array */ + char *lostk[STKSIZ], *histk[STKSIZ]; + int stkptr; /* stack for saving sub-array to be processed */ + + if (num < 2) + return; /* nothing to do */ + + stkptr = 0; /* initialize stack */ + + lo = (char *)base; + hi = (char *)base + width * (num-1); /* initialize limits */ + + /* this entry point is for pseudo-recursion calling: setting + lo and hi and jumping to here is like recursion, but stkptr is + preserved, locals aren't, so we preserve stuff on the stack */ +recurse: + + size = (hi - lo) / width + 1; /* number of el's to sort */ + + /* below a certain size, it is faster to use a O(n^2) sorting method */ + if (size <= CUTOFF) { + shortsort(lo, hi, width, comp); + } + else { + /* First we pick a partitioning element. The efficiency of the + algorithm demands that we find one that is approximately the median + of the values, but also that we select one fast. We choose the + median of the first, middle, and last elements, to avoid bad + performance in the face of already sorted data, or data that is made + up of multiple sorted runs appended together. Testing shows that a + median-of-three algorithm provides better performance than simply + picking the middle element for the latter case. */ + + mid = lo + (size / 2) * width; /* find middle element */ + + /* Sort the first, middle, last elements into order */ + if (comp(lo, mid) > 0) { + swap(lo, mid, width); + } + if (comp(lo, hi) > 0) { + swap(lo, hi, width); + } + if (comp(mid, hi) > 0) { + swap(mid, hi, width); + } + + /* We now wish to partition the array into three pieces, one consisting + of elements <= partition element, one of elements equal to the + partition element, and one of elements > than it. This is done + below; comments indicate conditions established at every step. */ + + loguy = lo; + higuy = hi; + + /* Note that higuy decreases and loguy increases on every iteration, + so loop must terminate. */ + for (;;) { + /* lo <= loguy < hi, lo < higuy <= hi, + A[i] <= A[mid] for lo <= i <= loguy, + A[i] > A[mid] for higuy <= i < hi, + A[hi] >= A[mid] */ + + /* The doubled loop is to avoid calling comp(mid,mid), since some + existing comparison funcs don't work when passed the same + value for both pointers. */ + + if (mid > loguy) { + do { + loguy += width; + } while (loguy < mid && comp(loguy, mid) <= 0); + } + if (mid <= loguy) { + do { + loguy += width; + } while (loguy <= hi && comp(loguy, mid) <= 0); + } + + /* lo < loguy <= hi+1, A[i] <= A[mid] for lo <= i < loguy, + either loguy > hi or A[loguy] > A[mid] */ + + do { + higuy -= width; + } while (higuy > mid && comp(higuy, mid) > 0); + + /* lo <= higuy < hi, A[i] > A[mid] for higuy < i < hi, + either higuy == lo or A[higuy] <= A[mid] */ + + if (higuy < loguy) + break; + + /* if loguy > hi or higuy == lo, then we would have exited, so + A[loguy] > A[mid], A[higuy] <= A[mid], + loguy <= hi, higuy > lo */ + + swap(loguy, higuy, width); + + /* If the partition element was moved, follow it. Only need + to check for mid == higuy, since before the swap, + A[loguy] > A[mid] implies loguy != mid. */ + + if (mid == higuy) + mid = loguy; + + /* A[loguy] <= A[mid], A[higuy] > A[mid]; so condition at top + of loop is re-established */ + } + + /* A[i] <= A[mid] for lo <= i < loguy, + A[i] > A[mid] for higuy < i < hi, + A[hi] >= A[mid] + higuy < loguy + implying: + higuy == loguy-1 + or higuy == hi - 1, loguy == hi + 1, A[hi] == A[mid] */ + + /* Find adjacent elements equal to the partition element. The + doubled loop is to avoid calling comp(mid,mid), since some + existing comparison funcs don't work when passed the same value + for both pointers. */ + + higuy += width; + if (mid < higuy) { + do { + higuy -= width; + } while (higuy > mid && comp(higuy, mid) == 0); + } + if (mid >= higuy) { + do { + higuy -= width; + } while (higuy > lo && comp(higuy, mid) == 0); + } + + /* OK, now we have the following: + higuy < loguy + lo <= higuy <= hi + A[i] <= A[mid] for lo <= i <= higuy + A[i] == A[mid] for higuy < i < loguy + A[i] > A[mid] for loguy <= i < hi + A[hi] >= A[mid] */ + + /* We've finished the partition, now we want to sort the subarrays + [lo, higuy] and [loguy, hi]. + We do the smaller one first to minimize stack usage. + We only sort arrays of length 2 or more.*/ + + if ( higuy - lo >= hi - loguy ) { + if (lo < higuy) { + lostk[stkptr] = lo; + histk[stkptr] = higuy; + ++stkptr; + } /* save big recursion for later */ + + if (loguy < hi) { + lo = loguy; + goto recurse; /* do small recursion */ + } + } + else { + if (loguy < hi) { + lostk[stkptr] = loguy; + histk[stkptr] = hi; + ++stkptr; /* save big recursion for later */ + } + + if (lo < higuy) { + hi = higuy; + goto recurse; /* do small recursion */ + } + } + } + + /* We have sorted the array, except for any pending sorts on the stack. + Check if there are any, and do them. */ + + --stkptr; + if (stkptr >= 0) { + lo = lostk[stkptr]; + hi = histk[stkptr]; + goto recurse; /* pop subarray from stack */ + } + else + return; /* all subarrays done */ +} + + +/*** +*shortsort(hi, lo, width, comp) - insertion sort for sorting short arrays +*shortsort_s(hi, lo, width, comp, context) - insertion sort for sorting short arrays +* +*Purpose: +* sorts the sub-array of elements between lo and hi (inclusive) +* side effects: sorts in place +* assumes that lo < hi +* +*Entry: +* char *lo = pointer to low element to sort +* char *hi = pointer to high element to sort +* unsigned width = width in bytes of each array element +* int (*comp)() = pointer to function returning analog of strcmp for +* strings, but supplied by user for comparing the array elements. +* it accepts 2 pointers to elements, together with a pointer to a context +* (if present). Returns neg if 1<2, 0 if 1=2, pos if 1>2. +* void *context - pointer to the context in which the function is +* called. This context is passed to the comparison function. +* +*Exit: +* returns void +* +*Exceptions: +* +*******************************************************************************/ + +static void shortsort ( + char *lo, + char *hi, + unsigned width, + int (*comp)(const void *, const void *) + ) +{ + char *p, *max; + + /* Note: in assertions below, i and j are alway inside original bound of + array to sort. */ + + while (hi > lo) { + /* A[i] <= A[j] for i <= j, j > hi */ + max = lo; + for (p = lo+width; p <= hi; p += width) { + /* A[i] <= A[max] for lo <= i < p */ + if (comp(p, max) > 0) { + max = p; + } + /* A[i] <= A[max] for lo <= i <= p */ + } + + /* A[i] <= A[max] for lo <= i <= hi */ + + swap(max, hi, width); + + /* A[i] <= A[hi] for i <= hi, so A[i] <= A[j] for i <= j, j >= hi */ + + hi -= width; + + /* A[i] <= A[j] for i <= j, j > hi, loop top condition established */ + } + /* A[i] <= A[j] for i <= j, j > lo, which implies A[i] <= A[j] for i < j, + so array is sorted */ +} + +/*** +*swap(a, b, width) - swap two elements +* +*Purpose: +* swaps the two array elements of size width +* +*Entry: +* char *a, *b = pointer to two elements to swap +* unsigned width = width in bytes of each array element +* +*Exit: +* returns void +* +*Exceptions: +* +*******************************************************************************/ + +static void swap ( + char *a, + char *b, + unsigned width + ) +{ + char tmp; + + if ( a != b ) + /* Do the swap one character at a time to avoid potential alignment + problems. */ + while ( width-- ) { + tmp = *a; + *a++ = *b; + *b++ = tmp; + } +} diff --git a/programs/games/checkers/trunk/sysproc.h b/programs/games/checkers/trunk/sysproc.h new file mode 100644 index 0000000000..caba2c2d71 --- /dev/null +++ b/programs/games/checkers/trunk/sysproc.h @@ -0,0 +1,27 @@ +#ifndef _HEADER_SYSTEM_PROCESS_H +#define _HEADER_SYSTEM_PROCESS_H + +#ifndef __MENUET__ +#include +#include +#endif + +#if defined __GNUC__ +# include +# define DIR_SEPARATOR ('/') + inline long GetProcessId() {return (long)getpid();} + inline long DuplicateProcess() {return (long)fork();} + inline int random(int m) {return ((unsigned long)rand()) % m;} + inline void randomize() {srand(time(0));} +#elif defined __TURBOC__ && !defined __MENUET__ +# include +# define DIR_SEPARATOR ('\\') + inline long GetProcessId() {return (long)getpid();} + inline long DuplicateProcess() {return -1;} +#else +# define DIR_SEPARATOR ('\\') + inline long GetProcessId() {return 0;} + inline long DuplicateProcess() {return -1;} +#endif + +#endif //_HEADER_SYSTEM_PROCESS_H diff --git a/programs/games/checkers/trunk/t2fasm.exe b/programs/games/checkers/trunk/t2fasm.exe new file mode 100644 index 0000000000..cad968b59c Binary files /dev/null and b/programs/games/checkers/trunk/t2fasm.exe differ diff --git a/programs/games/checkers/trunk/tmplayer.h b/programs/games/checkers/trunk/tmplayer.h new file mode 100644 index 0000000000..f797a53baf --- /dev/null +++ b/programs/games/checkers/trunk/tmplayer.h @@ -0,0 +1,729 @@ +#ifndef _HEADER_TMP_PLAYER_H +#define _HEADER_TMP_PLAYER_H + +#include "player.h" + +class CompPosition : public Position +{ +public: + bool Move; + + CompPosition() : Position() {Move = 1;} + CompPosition(CompPosition &p, bool IsChange = 0) : Position(p) + {Move = p.Move + IsChange;} + CompPosition& operator=(CompPosition &p) + {for(int i = 0; i < 32; i++) SH[i] = p.SH[i]; Move = p.Move; return *this;} + CompPosition& Init(Position &p, bool MoveColor = 1) + {for(int i = 0; i < 32; i++) SH[i] = p.SH[i]; Move = MoveColor; return *this;} +}; + +namespace ComputerMove +{ +#define BCM_START -256 +#define BCM_ISM1 -257 + + class BestMove; + bool MoveEat(BestMove* BM); + bool MovePr(BestMove* BM); + + class BestMove + { + public: + BestMove (CompPosition &Pos1, BestMove *par = 0) + {Pos = Pos1; Parent = par; NMax = 0;} + + void StartMove() + { + if (Parent->NomP == BCM_ISM1) return; + if (Parent->NomP == BCM_START) NomP = 258; else NomP = Parent->NomP; + if (!MoveEat(this)) + { + bool IsNP256 = 0, IsNP258 = 0; + if (NomP == 258) IsNP258 = 1; + if (NomP == 256) + { + IsNP256 = 1; int NSH1 = 0; int NSH0 = 0; + for (int i = 0; i < 32; i++) + { + if (Pos.SH[i] == 1 + Pos.Move) NSH1 += 1; + else if (Pos.SH[i] == 2 - Pos.Move) NSH0 += 1; + else if (Pos.SH[i] == 3 + Pos.Move) NSH1 += 6; + else if (Pos.SH[i] == 4 - Pos.Move) NSH0 += 6; + } + int NSH = NSH0 * NSH1; + if (NSH > 100) NomP = 0; else if (NSH > 30) NomP = 1; + else if (NSH > 5) NomP = 2; else NomP = 3; + } + else if (NomP == 0) NomP = BCM_ISM1; else NomP--; + if (!MovePr(this)) + { + NextPreim = -16777472; + for (int i = 0; i < 32; i++) + { + if (Pos.SH[i] == 1 + Pos.Move) NextPreim -= 512; + else if (Pos.SH[i] == 2 - Pos.Move) NextPreim -= 32; + else if (Pos.SH[i] == 3 + Pos.Move) NextPreim -= 4096; + else if (Pos.SH[i] == 4 - Pos.Move) NextPreim -= 32; + } + } + else if (NomP == BCM_ISM1) + { + char NomDM0 = 0, NomDM1 = 0; + NextPreim = 0; + for (int i = 0; i < 32; i++) + { + short PreimSHPos[32] = {243, 243, 243, 245, + 240, 240, 240, 240, + 244, 244, 244, 244, + 245, 248, 248, 245, + 249, 250, 250, 248, + 256, 260, 260, 256, + 280, 280, 280, 260, + 280, 280, 280, 280}; + if (Pos.SH[i] == 1 + Pos.Move) + NextPreim += PreimSHPos[Pos.Move ? (31 - i) : i]; + else if (Pos.SH[i] == 2 - Pos.Move) + NextPreim -= PreimSHPos[Pos.Move ? i : (31 - i)]; + else if (Pos.SH[i] == 3 + Pos.Move) NomDM1++; + else if (Pos.SH[i] == 4 - Pos.Move) NomDM0++; + } + if (NomDM1 > 0) + { + NextPreim += 560; NomDM1--; + if (NomDM1 > 0) + { + NextPreim += 432; NomDM1--; + NextPreim += long(NomDM1) * 384; + } + } + if (NomDM0 > 0) + { + NextPreim -= 560; NomDM0--; + if (NomDM0 > 0) + { + NextPreim -= 432; NomDM0--; + NextPreim -= long(NomDM0) * 384; + } + } + } + else if (IsNP256 && NextPreim < 16777216 && NextPreim > -16777216) + { + char NSH1 = 0, NSH0 = 0, NDM1 = 0, NDM0 = 0; + for (int i = 0; i < 32; i++) + { + if (Pos.SH[i] == 1 + Pos.Move) NSH1++; + else if (Pos.SH[i] == 2 - Pos.Move) NSH0++; + else if (Pos.SH[i] == 3 + Pos.Move) NDM1++; + else if (Pos.SH[i] == 4 - Pos.Move) NDM0++; + } + if (NDM1 > 0 && NDM0 > 0 && NSH1 + NSH0 < 3) + { + unsigned char HwoBD = 0; char Sh0BD = 1, Sh1BD = 1; + for (int i = 0; i < 8; i++) + { + char ShBD = Pos.SH[PoleToNum(i, 7 - i)]; + if (ShBD == 1 + Pos.Move) Sh1BD++; + else if (ShBD == 2 - Pos.Move) Sh0BD++; + else if (ShBD == 3 + Pos.Move) HwoBD |= 2; + else if (ShBD == 4 - Pos.Move) HwoBD |= 1; + } + if (HwoBD == 2) NextPreim += 128 / Sh0BD; + if (HwoBD == 1) NextPreim -= 128 / Sh1BD; + if (NDM1 >= 3 && NDM0 == 1 && NSH1 == 0 && NSH0 == 0 && HwoBD == 1) + { + char Best4P[4][2] = {{0,9}, {4,13}, {31,22}, {27,18}}; + char Add = 0; + for (int i = 0; i < 4; i++) Add |= + (char(Pos.SH[Best4P[i][0]] == 3 + Pos.Move) * 3 + + char(Pos.SH[Best4P[i][1]] == 3 + Pos.Move)); + if (Add >= 4) NextPreim += 32; else if (Add == 3) NextPreim += 24; + else if (Add >= 1) NextPreim += 16; + } + else if (NDM0 >= 3 && NDM1 == 1 && NSH0 == 0 && NSH1 == 0 && HwoBD == 2) + { + char Best4P[4][2] = {{0,9}, {4,13}, {31,22}, {27,18}}; + char Add = 0; + for (int i = 0; i < 4; i++) Add |= + (char(Pos.SH[Best4P[i][0]] == 4 - Pos.Move) * 3 + + char(Pos.SH[Best4P[i][1]] == 4 - Pos.Move)); + if (Add >= 4) NextPreim -= 32; else if (Add == 3) NextPreim -= 24; + else if (Add >= 1) NextPreim -= 16; + } + } + else + { + for (int i = 0; i < 32; i++) + { + char Color = Pos.SH[i] - 1; + if (Color == 0 || Color == 1) + { + char qi = Color ? (31 - i) : i; + char Zn = Color ? -1 : 1; + char PreZ = (Color == Pos.Move) ? 1 : -1; + if (Pos.SH[i + Zn * 8] != 2 - Color) + { + if (qi / 4 == 2) + { + char IsFree = 0; + if (Pos.SH[i - Zn * 4] == 2 - Color) IsFree += 2; + else if (qi != 8) + { + if (Pos.SH[i - Zn ] == 2 - Color || + Pos.SH[i - Zn * 9] == 2 - Color) IsFree += 2; + else if (Color != Pos.Move) + if (Pos.SH[i - Zn * 5] == 2 - Color) IsFree++; + } + if (qi == 11) IsFree += 2; + else if (Pos.SH[i + Zn ] == 2 - Color || + Pos.SH[i - Zn * 3] == 2 - Color || + Pos.SH[i - Zn * 7] == 2 - Color) IsFree += 2; + else if (Color != Pos.Move && qi != 10) + if (Pos.SH[i - Zn * 2] == 2 - Color) IsFree++; + if (IsFree < 3) NextPreim += PreZ * 176 / (1 + NDM0 + NDM1); + else if (qi == 9 || qi == 10) NextPreim += + PreZ * 128 / (1 + NDM0 + NDM1); + } + else if (qi / 4 == 3) + { + char IsFree = 0; + if (Pos.SH[i - Zn * 12] == 2 - Color) + {if (Color == Pos.Move) IsFree += 11; else IsFree += 12;} + else if (Pos.SH[i - Zn * 4] == 2 - Color) IsFree += 11; + else if (qi == 15) IsFree += 5; + else if (Pos.SH[i - Zn * 7] == 2 - Color) IsFree += 9; + else if (Pos.SH[i + Zn] == 2 - Color) IsFree += 8; + else if (Pos.SH[i - Zn * 11] == 2 - Color) + {if (Color == Pos.Move) IsFree += 5; else IsFree += 7;} + else if (Pos.SH[i - Zn * 3] == 2 - Color) IsFree += 5; + else if (qi != 14) + { + if (Pos.SH[i - Zn * 6] == 2 - Color) IsFree += 3; + else if (Color != Pos.Move) + if (Pos.SH[i - Zn * 10] == 2 - Color) IsFree++; + } + if (qi == 12) IsFree += 7; + else if (Pos.SH[i - Zn * 13] == 2 - Color) + {if (Color == Pos.Move) IsFree += 11; else IsFree += 12;} + else if (Pos.SH[i - Zn * 5] == 2 - Color) IsFree += 11; + else if (Pos.SH[i - Zn * 9] == 2 - Color) IsFree += 9; + else if (Pos.SH[i - Zn] == 2 - Color) IsFree += 8; + else if (qi != 13) + { + if (Pos.SH[i - Zn * 14] == 2 - Color) + {if (Color == Pos.Move) IsFree += 5; else IsFree += 7;} + else if (Pos.SH[i - Zn * 6] == 2 - Color) IsFree += 5; + else if (Pos.SH[i - Zn * 10] == 2 - Color) IsFree += 3; + else if (Color != Pos.Move && qi != 14) + if (Pos.SH[i - Zn * 15] == 2 - Color) IsFree++; + } + if (IsFree < ((Color == Pos.Move) ? 14 : 12)) + NextPreim += PreZ * 160 / (1 + NDM0 + NDM1); + } + } + } + } + } + } + else if (IsNP258 && NextPreim < 16777216 && NextPreim > -16777216) + { + char NSH1 = 0, NSH0 = 0, NDM1 = 0, NDM0 = 0; + for (int i = 0; i < 32; i++) + { + if (Pos.SH[i] == 1 + Pos.Move) NSH1++; + else if (Pos.SH[i] == 2 - Pos.Move) NSH0++; + else if (Pos.SH[i] == 3 + Pos.Move) NDM1++; + else if (Pos.SH[i] == 4 - Pos.Move) NDM0++; + } + if (NDM1 > 0 && NDM0 > 0 && NSH1 == 0 && NSH0 == 0) + { + short PrP = 0; char Cpos3 = -1; + if (NDM1 == 3 && NDM0 == 1 && NSH1 == 0 && NSH0 == 0) Cpos3 = 1; + else if (NDM1 == 1 && NDM0 == 3 && NSH1 == 0 && NSH0 == 0) Cpos3 = 0; + if (Cpos3 >= 0) + { + for (char Osm = 0; Osm <= 1; Osm++) for (char Csm = 0; Csm <= 1; Csm++) + { + char PosSH[7][3] = {{13, 17, 18}, {6, 17, 18}, {9, 21, 22}, + {17, 18, 19}, {9, 10, 15}, {11, 14, 18}, {2, 14, 18}}; + for (char PosNi = 0; PosNi < 7; PosNi++) + { + bool IsPosR = 1; + for (char ShNi = 0; ShNi < 3; ShNi++) + { + char DNomSh = (Csm == 1) ? (31 - PosSH[PosNi][ShNi]) + : PosSH[PosNi][ShNi]; + if (Osm == 1) {int x, y; NumToPole(DNomSh, x, y); + DNomSh = PoleToNum(y, x);} + if (Pos.SH[DNomSh] != 3 + (Cpos3 == Pos.Move)) IsPosR = 0; + } + if (IsPosR) + { + if (PosNi == 3) + { + if (Cpos3 == 1) {if (Pos.SH[(Csm == 1) ? 29 : 2] != + 4 - (Cpos3 == Pos.Move) && Pos.SH[(Csm == 1) ? 11 : 20] + != 4 - (Cpos3 == Pos.Move)) PrP = 216;} + else + { + bool PrPZ = 1; + for (int i = 0; i < 6; i++) + if (Pos.SH[PoleToNum((Csm == 1) ? (i + 2) : i, + (Csm == 1) ? (7 - i) : (5 - i))] == + 4 - (Cpos3 == Pos.Move)) PrPZ = 0; + if (PrPZ) PrP = -216; + } + } + else if (PosNi == 4) + { + if (Cpos3 == 1) + {if (Pos.SH[ 0] != 4 - (Cpos3 == Pos.Move) + && Pos.SH[ 4] != 4 - (Cpos3 == Pos.Move) + && Pos.SH[27] != 4 - (Cpos3 == Pos.Move) + && Pos.SH[31] != 4 - (Cpos3 == Pos.Move)) PrP = 216;} + else {if (Pos.SH[(Csm == Osm) ? 4 : 0] != 4 - (Cpos3 == Pos.Move) + && Pos.SH[(Csm == Osm) ? 8 : 5] != 4 - (Cpos3 == Pos.Move) + && Pos.SH[(Csm == Osm) ? 26 : 23] != 4 - (Cpos3 == Pos.Move) + && Pos.SH[(Csm == Osm) ? 31 : 27] != 4 - (Cpos3 == Pos.Move)) + PrP = -216;} + } + else if (PosNi == 5) + { + char DNomSh = (Cpos3 == 1) ? ((Osm == 1) ? 16 : 6) + : ((Osm == 1) ? 20 : 2); + if (Csm == 1) DNomSh = 31 - DNomSh; + if (Pos.SH[DNomSh] == 4 - (Cpos3 == Pos.Move)) + PrP = (Cpos3 == 1) ? 160 : -160; + } + else if (PosNi == 6) + { + if (Cpos3 == 1) + {if (Pos.SH[ 1] == 4 - (Cpos3 == Pos.Move) + || Pos.SH[12] == 4 - (Cpos3 == Pos.Move) + || Pos.SH[19] == 4 - (Cpos3 == Pos.Move) + || Pos.SH[30] == 4 - (Cpos3 == Pos.Move)) PrP = 168;} + else + {if (Pos.SH[(Csm == 1) ? 15 : 6] == 4 - (Cpos3 == Pos.Move) + || Pos.SH[(Csm == 1) ? 25 : 16] == 4 - (Cpos3 == Pos.Move)) + PrP = -168;} + } + else PrP = ((Cpos3 == 1) ? 1 : -1) * ((PosNi == 0) ? 200 : 208); + } + } + } + } + if (PrP == 0) + { + unsigned char HwoBD = 0; char NShSBD = 0; + for (int i = 0; i < 8; i++) + { + char ShBD = Pos.SH[PoleToNum(i, 7 - i)]; + if (ShBD == 3 + Pos.Move) {HwoBD |= 2; NShSBD++;} + else if (ShBD == 4 - Pos.Move) {HwoBD |= 1; NShSBD++;} + } + if (NDM1 >= 3 && NDM0 == 1 && NSH1 == 0 && NSH0 == 0 && HwoBD == 2) + { + if (NShSBD >= 1) NextPreim -= NShSBD - 1; + if (Pos.SH[ 3] == 3 + Pos.Move) NextPreim--; + if (Pos.SH[28] == 3 + Pos.Move) NextPreim--; + char Drg1 = 0; bool Drg1p = 0; char DrgPS = 0; + for (int i = 0; i < 7; i++) + { + char Sh7D = Pos.SH[PoleToNum(i, i + 1)]; + if (Sh7D == 3 + Pos.Move) {Drg1++; DrgPS |= 1;} + else if (Sh7D == 4 - Pos.Move) Drg1p = 1; + Sh7D = Pos.SH[PoleToNum(i + 1, i)]; + if (Sh7D == 3 + Pos.Move) {Drg1++; DrgPS |= 2;} + else if (Sh7D == 4 - Pos.Move) Drg1p = 1; + } + if (Pos.SH[0] == 3 + Pos.Move || Pos.SH[4] == 3 + Pos.Move || + Pos.SH[27] == 3 + Pos.Move || Pos.SH[31] == 3 + Pos.Move) + {if (Drg1p) NextPreim += 4; else NextPreim -= 1;} + if ((Pos.SH[14] == 3 + Pos.Move) == (Pos.SH[17] == 3 + Pos.Move)) + {if (Drg1 == 1) NextPreim += 2;} + else + { + if (Drg1 >= 2) + { + if (Drg1 > 2) NextPreim -= 1; + if (DrgPS == 3) NextPreim += 4; + if (Drg1p) NextPreim += 4; else NextPreim += 16; + if (!Drg1p && DrgPS) + { + Drg1 = 0; Drg1p = 0; DrgPS = 0; + for (int i = 0; i < 6; i++) + { + char Sh7D = Pos.SH[PoleToNum(i, 5 - i)]; + if (Sh7D == 3 + Pos.Move) {Drg1++; DrgPS |= 1;} + else if (Sh7D == 4 - Pos.Move) Drg1p = 1; + Sh7D = Pos.SH[PoleToNum(i + 2, 7 - i)]; + if (Sh7D == 3 + Pos.Move) {Drg1++; DrgPS |= 2;} + else if (Sh7D == 4 - Pos.Move) Drg1p = 1; + } + if (Pos.SH[2] == 3 + Pos.Move || Pos.SH[11] == 3 + Pos.Move || + Pos.SH[20] == 3 + Pos.Move || Pos.SH[29] == 3 + Pos.Move) + NextPreim += 4; + if ((Pos.SH[14] == 3 + Pos.Move) + ? (Pos.SH[13] == 3 + Pos.Move || Pos.SH[22] == 3 + Pos.Move) + : (Pos.SH[ 9] == 3 + Pos.Move || Pos.SH[18] == 3 + Pos.Move)) + { + if (Drg1 >= 2) + { + if (DrgPS == 3) NextPreim += 4; + if (Drg1p) NextPreim += 4; else NextPreim += 16; + } + else if (Drg1 == 1) NextPreim += 1; + } + else if (Drg1 == 1) NextPreim += 2; + } + } + } + } + else if (NDM0 >= 3 && NDM1 == 1 && NSH0 == 0 && NSH1 == 0 && HwoBD == 1) + { + if (NShSBD >= 1) NextPreim += NShSBD - 1; + if (Pos.SH[ 3] == 4 - Pos.Move) NextPreim++; + if (Pos.SH[28] == 4 - Pos.Move) NextPreim++; + char Drg1 = 0; bool Drg1p = 0; char DrgPS = 0; + for (int i = 0; i < 7; i++) + { + char Sh7D = Pos.SH[PoleToNum(i, i + 1)]; + if (Sh7D == 4 - Pos.Move) {Drg1++; DrgPS |= 1;} + else if (Sh7D == 3 + Pos.Move) Drg1p = 1; + Sh7D = Pos.SH[PoleToNum(i + 1, i)]; + if (Sh7D == 4 - Pos.Move) {Drg1++; DrgPS |= 2;} + else if (Sh7D == 3 + Pos.Move) Drg1p = 1; + } + if (Pos.SH[0] == 4 - Pos.Move || Pos.SH[4] == 4 - Pos.Move || + Pos.SH[27] == 4 - Pos.Move || Pos.SH[31] == 4 - Pos.Move) + {if (Drg1p) NextPreim -= 4; else NextPreim += 1;} + if ((Pos.SH[14] == 4 - Pos.Move) == (Pos.SH[17] == 4 - Pos.Move)) + {if (Drg1 == 1) NextPreim -= 2;} + else + { + if (Drg1 >= 2) + { + if (Drg1 > 2) NextPreim += 1; + if (DrgPS == 3) NextPreim -= 4; + if (Drg1p) NextPreim -= 4; else NextPreim -= 16; + if (!Drg1p && DrgPS) + { + Drg1 = 0; Drg1p = 0; DrgPS = 0; + for (int i = 0; i < 6; i++) + { + char Sh7D = Pos.SH[PoleToNum(i, 5 - i)]; + if (Sh7D == 4 - Pos.Move) {Drg1++; DrgPS |= 1;} + else if (Sh7D == 3 + Pos.Move) Drg1p = 1; + Sh7D = Pos.SH[PoleToNum(i + 2, 7 - i)]; + if (Sh7D == 4 - Pos.Move) {Drg1++; DrgPS |= 2;} + else if (Sh7D == 3 + Pos.Move) Drg1p = 1; + } + if (Pos.SH[2] == 4 - Pos.Move || Pos.SH[11] == 4 - Pos.Move || + Pos.SH[20] == 4 - Pos.Move || Pos.SH[29] == 4 - Pos.Move) + NextPreim -= 4; + if ((Pos.SH[14] == 4 - Pos.Move) + ? (Pos.SH[13] == 4 - Pos.Move || Pos.SH[22] == 4 - Pos.Move) + : (Pos.SH[ 9] == 4 - Pos.Move || Pos.SH[18] == 4 - Pos.Move)) + { + if (Drg1 >= 2) + { + if (DrgPS == 3) NextPreim -= 4; + if (Drg1p) NextPreim -= 4; else NextPreim -= 16; + } + else if (Drg1 == 1) NextPreim -= 1; + } + else if (Drg1 == 1) NextPreim -= 2; + } + } + } + } + else if (NDM1 >= 3 && NDM0 == 1 && NSH1 == 0 && NSH0 == 0 && HwoBD == 1) + { + char Best4P[4][2] = {{0,9}, {4,13}, {31,22}, {27,18}}; + char Add = 0; + for (int i = 0; i < 4; i++) Add |= + (char(Pos.SH[Best4P[i][0]] == 3 + Pos.Move) * 3 + + char(Pos.SH[Best4P[i][1]] == 3 + Pos.Move)); + if (Add >= 4) NextPreim += 3; else if (Add == 3) NextPreim += 2; + else if (Add >= 1) NextPreim += 1; + } + else if (NDM0 >= 3 && NDM1 == 1 && NSH0 == 0 && NSH1 == 0 && HwoBD == 2) + { + char Best4P[4][2] = {{0,9}, {4,13}, {31,22}, {27,18}}; + char Add = 0; + for (int i = 0; i < 4; i++) Add |= + (char(Pos.SH[Best4P[i][0]] == 4 - Pos.Move) * 3 + + char(Pos.SH[Best4P[i][1]] == 4 - Pos.Move)); + if (Add >= 4) NextPreim -= 3; else if (Add == 3) NextPreim -= 2; + else if (Add >= 1) NextPreim -= 1; + } + } + else NextPreim += PrP; + } + } + } + Parent->TakeMove(Pos, -NextPreim); + } + + void TakeMove(CompPosition &Pos1, long Preim) + { + if (Preim >= 16777216) Preim--; else if (Preim <= -16777216) Preim++; + bool b = (NMax == 0 || Preim > NextPreim); if (NMax == 0) NMax = 1; + if (!b && Preim == NextPreim) {b = (random(NMax + 1) == 0); NMax++;} + if (b) {if (NomP == BCM_START) *NextPos = Pos1; NextPreim = Preim;} + } + + CompPosition Pos; int NomP; BestMove *Parent; + + CompPosition *NextPos; char NMax; long NextPreim; + }; + + class MoveEatParam + { + public: + char Home; + char Eaten[15]; char NomEat; + BestMove* BM; + + MoveEatParam(){} + + char RealPlase(char N) + { + char RP; + if (N == Home) RP = 0; else RP = BM->Pos.SH[N]; + for (int i = 0; i < NomEat; i++) if (N == Eaten[i]) RP = 0; + return RP; + } + }; + + void EatContinue(MoveEatParam& MEP, bool IsDMC, char Start, char Kurs) + { + bool IsCanEat = 0; + int x, y; NumToPole(Start, x, y); + if (y == 7 - MEP.BM->Pos.Move * 7) IsDMC = 1; + if (IsDMC) + { + int KursY = Kurs / abs(Kurs); int KursX = Kurs - KursY * 2; + for (int i = x, j = y; + i >= 0 && j >= 0 && i < 8 && j < 8; + i += KursX, j += KursY) + { + int Shash = MEP.RealPlase(PoleToNum(i, j)); + if (Shash == 2 - MEP.BM->Pos.Move || Shash == 4 - MEP.BM->Pos.Move) + { + if (i + KursX >= 0 && j + KursY >= 0 && i + KursX < 8 && j + KursY < 8) + if (MEP.RealPlase(PoleToNum(i + KursX, j + KursY)) == 0) + { + IsCanEat = 1; + MEP.Eaten[MEP.NomEat++] = PoleToNum(i, j); + EatContinue(MEP, 1, PoleToNum(i + KursX, j + KursY), + KursX + 2 * KursY); + MEP.NomEat--; + } + break; + } + else if (Shash == 1 + MEP.BM->Pos.Move || Shash == 3 + MEP.BM->Pos.Move) break; + else for (int Rotate = -1; Rotate <= 1; Rotate += 2) + for (int i1 = i + KursY * Rotate, j1 = j - KursX * Rotate; + i1 >= 0 && j1 >= 0 && i1 < 8 && j1 < 8; + i1 += KursY * Rotate, j1 -= KursX * Rotate) + { + int Shash = MEP.RealPlase(PoleToNum(i1, j1)); + if (Shash == 2 - MEP.BM->Pos.Move || Shash == 4 - MEP.BM->Pos.Move) + { + if (i1 + KursY * Rotate >= 0 && j1 - KursX * Rotate >= 0 && + i1 + KursY * Rotate < 8 && j1 - KursX * Rotate < 8) + if (MEP.RealPlase(PoleToNum(i1 + KursY * Rotate, j1 - KursX * Rotate)) == 0) + { + IsCanEat = 1; + MEP.Eaten[MEP.NomEat++] = PoleToNum(i1, j1); + EatContinue(MEP, 1, PoleToNum(i1 + KursY * Rotate, + j1 - KursX * Rotate), + KursY * Rotate - 2 * KursX * Rotate); + MEP.NomEat--; + } + break; + } + else if (Shash == 1 + MEP.BM->Pos.Move || Shash == 3 + MEP.BM->Pos.Move) break; + } + } + if (!IsCanEat) + { + for (int ii = x, jj = y; ii >= 0 && jj >= 0 && + ii < 8 && jj < 8; ii += KursX, jj += KursY) + { + if (MEP.RealPlase(PoleToNum(ii, jj)) != 0) break; + BestMove BMove(MEP.BM->Pos, MEP.BM); BMove.Pos.SH[MEP.Home] = 0; + for (int i = 0; i < MEP.NomEat; i++) {BMove.Pos.SH[MEP.Eaten[i]] = 0;} + BMove.Pos.SH[PoleToNum(ii, jj)] = 3 + MEP.BM->Pos.Move; + BMove.Pos.Move = !BMove.Pos.Move; + BMove.StartMove(); + } + } + } + else + { + for (int i = -1; i <= 1; i += 2) for (int j = -1; j <= 1; j += 2) + if (i + 2 * j != -Kurs) if (x + 2 * i >= 0 + && y + 2 * j >= 0 && x + 2*i < 8 && y + 2 * j < 8) + { + char FESH = PoleToNum(x + i, y + j); char FESHrp = MEP.RealPlase(FESH); + char FMSH = PoleToNum(x + 2 * i, y + 2 * j); + if ((FESHrp == 2 - MEP.BM->Pos.Move || FESHrp == 4 - MEP.BM->Pos.Move) + && MEP.RealPlase(FMSH) == 0) + { + IsCanEat = 1; + MEP.Eaten[MEP.NomEat++] = FESH; + EatContinue(MEP, 0, FMSH, i + 2 * j); + MEP.NomEat--; + } + } + if (!IsCanEat) + { + BestMove BMove(MEP.BM->Pos, MEP.BM); BMove.Pos.SH[MEP.Home] = 0; + for (int i = 0; i < MEP.NomEat; i++) {BMove.Pos.SH[MEP.Eaten[i]] = 0;} + BMove.Pos.SH[Start] = 1 + MEP.BM->Pos.Move; + BMove.Pos.Move = !BMove.Pos.Move; + BMove.StartMove(); + } + } + } + + bool MoveEat(BestMove* BM) + { + bool IsCanEat = 0; + MoveEatParam MEP; MEP.BM = BM; + for (MEP.Home = 0; MEP.Home < 32; MEP.Home++) + { + if (BM->Pos.SH[MEP.Home] == 1 + BM->Pos.Move) + { + int x, y; NumToPole(MEP.Home, x, y); + for (int i = -1; i <= 1; i += 2) for (int j = -1; j <= 1; j += 2) + if (x + 2*i >= 0 && y + 2*j >= 0 && x + 2*i < 8 && y + 2*j < 8) + { + int FESH = PoleToNum(x + i, y + j); + int FMSH = PoleToNum(x + 2 * i, y + 2 * j); + if ((BM->Pos.SH[FESH] == 2 - BM->Pos.Move || BM->Pos.SH[FESH] == 4 - BM->Pos.Move) + && BM->Pos.SH[FMSH] == 0) + { + IsCanEat = 1; + MEP.NomEat = 1; MEP.Eaten[0] = FESH; + EatContinue(MEP, 0, FMSH, i + 2 * j); + } + } + } + else if (BM->Pos.SH[MEP.Home] == 3 + BM->Pos.Move) + { + int x, y; NumToPole(MEP.Home, x, y); + for (int i = -1; i <= 1; i += 2) for (int j = -1; j <= 1; j += 2) + for (int a = x + i, b = y + j; + a >= 0 && b >= 0 && a < 8 && b < 8; + a += i, b += j) + { + char Shash = PoleToNum(a, b); + char Shash1 = PoleToNum(a + i, b + j); + if (BM->Pos.SH[Shash] == 2 - BM->Pos.Move || BM->Pos.SH[Shash] == 4 - BM->Pos.Move) + { + if (a + i >= 0 && b + j >= 0 && a + i < 8 && b + j < 8) + if (BM->Pos.SH[Shash1] == 0) + { + IsCanEat = 1; + MEP.NomEat = 1; MEP.Eaten[0] = Shash; + EatContinue(MEP, 1, Shash1, i + 2 * j); + } + break; + } + else if (BM->Pos.SH[Shash] == 1 + BM->Pos.Move || BM->Pos.SH[Shash] == 3 + BM->Pos.Move) break; + } + } + } + return IsCanEat; + } + + bool MovePr(BestMove* BM) + { + bool IsCanMove = 0; + for (int N = 0; N < 32; N++) + { + if (BM->Pos.SH[N] == 1 + BM->Pos.Move) + { + int x, y; NumToPole(N, x, y); + int j = 1 - 2 * BM->Pos.Move; + for (int i = -1; i <= 1; i += 2) + if (x + i >= 0 && y + j >= 0 && x + i < 8 && y + j < 8) + { + int FMSH = PoleToNum(x + i, y + j); + if (BM->Pos.SH[FMSH] == 0) + { + IsCanMove = 1; + BestMove BMove(BM->Pos, BM); BMove.Pos.SH[N] = 0; + BMove.Pos.SH[FMSH] = 1 + BM->Pos.Move + 2 * + (y + j == 7 - BM->Pos.Move * 7); + BMove.Pos.Move = !BMove.Pos.Move; + BMove.StartMove(); + } + } + } + else if (BM->Pos.SH[N] == 3 + BM->Pos.Move) + { + int x, y; NumToPole(N, x, y); + for (int i = -1; i <= 1; i += 2) for (int j = -1; j <= 1; j += 2) + for (int a = x + i, b = y + j; + a >= 0 && b >= 0 && a < 8 && b < 8; + a += i, b += j) + { + if (BM->Pos.SH[PoleToNum(a, b)] != 0) break; + IsCanMove = 1; + BestMove BMove(BM->Pos, BM); BMove.Pos.SH[N] = 0; + BMove.Pos.SH[PoleToNum(a, b)] = 3 + BM->Pos.Move; + BMove.Pos.Move = !BMove.Pos.Move; + BMove.StartMove(); + } + } + } + return IsCanMove; + } + + int StartMove(Position& Pos, bool CompColor) + { + CompPosition Pos1; Pos1.Init(Pos, CompColor); + BestMove MainMove(Pos1); MainMove.NomP = BCM_START; + MainMove.NextPos = &Pos1; + if (!MoveEat(&MainMove)) if (!MovePr(&MainMove)) return 1; + Pos = Pos1; MainMove.Pos = Pos1; + MainMove.NomP = BCM_ISM1; + if (!MoveEat(&MainMove)) if (!MovePr(&MainMove)) return -1; + return 0; + } + +#undef BCM_ISM1 +#undef BCM_START +} + + +class TemporaryPlayer : public TChPlayer +{ +public: + TemporaryPlayer() {} + + virtual int Move(PMv &pmv); +}; + +int TemporaryPlayer::Move(PMv &pmv) +{ + TComputerPlayer::Z z; + z.FindAllMoves(pmv); + if (z.narr <= 0) return 0; + int r, s = ComputerMove::StartMove(pmv.pos, pmv.pos.wmove); + if (s > 0) return 0; + for (r = 0; r < z.narr; r++) + { + if (memcmp(z.array[r].pos.SH, pmv.pos.SH, sizeof(pmv.pos.SH)) == 0) + { + pmv = z.array[r]; + return 1; + } + } + return 0; +} + +#endif //_HEADER_TMP_PLAYER_H diff --git a/programs/games/checkers/trunk/win-chk.rc b/programs/games/checkers/trunk/win-chk.rc new file mode 100644 index 0000000000..43b8b332ba --- /dev/null +++ b/programs/games/checkers/trunk/win-chk.rc @@ -0,0 +1,106 @@ +#define IDC_DEBUG 22003 +#define IDC_COPYRIGHT 22002 +#define IDC_VERSION 22001 +#include +#include "winabout.rh" + + +WinDrawIcon ICON +{ +'00 00 01 00 01 00 20 20 10 00 00 00 00 00 E8 02' +'00 00 16 00 00 00 28 00 00 00 20 00 00 00 40 00' +'00 00 01 00 04 00 00 00 00 00 80 02 00 00 00 00' +'00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00' +'00 00 00 00 80 00 00 80 00 00 00 80 80 00 80 00' +'00 00 80 00 80 00 80 80 00 00 C0 C0 C0 00 80 80' +'80 00 00 00 FF 00 00 FF 00 00 00 FF FF 00 FF 00' +'00 00 FF 00 FF 00 FF FF 00 00 FF FF FF 00 00 00' +'00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00' +'00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00' +'00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00' +'00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00' +'00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00' +'00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00' +'00 00 00 11 11 11 11 11 11 00 00 00 00 00 00 00' +'00 19 11 11 11 11 11 11 11 10 11 00 00 00 00 00' +'19 11 19 11 11 11 11 11 01 11 01 01 00 00 00 19' +'11 91 91 11 11 11 11 11 11 01 10 10 11 00 01 91' +'91 11 19 11 11 11 11 11 11 11 01 11 00 00 01 91' +'19 91 91 11 11 11 11 11 11 01 10 10 11 00 99 19' +'91 19 11 99 99 99 99 99 99 10 11 00 00 00 99 11' +'91 99 99 99 99 99 99 99 99 99 99 11 10 00 99 19' +'99 99 99 11 11 11 11 11 11 99 99 99 91 00 91 99' +'99 11 11 11 11 11 11 11 11 11 11 99 99 00 99 99' +'11 91 11 99 99 99 99 99 99 11 19 11 99 90 19 91' +'99 19 99 91 11 11 11 11 19 99 91 99 19 91 19 91' +'91 99 99 19 19 99 99 91 91 99 99 19 19 91 19 91' +'91 99 99 19 19 99 99 91 91 99 99 19 19 91 19 91' +'99 19 99 91 11 11 11 11 19 99 91 99 19 91 01 99' +'11 91 11 99 99 99 99 99 99 11 19 11 99 10 00 19' +'99 11 11 11 11 11 11 11 11 11 11 99 91 00 00 01' +'11 99 99 11 11 11 11 11 11 99 99 11 10 00 00 00' +'00 11 11 99 99 99 99 99 99 11 11 00 00 00 00 00' +'00 00 00 11 11 11 11 11 11 00 00 00 00 00 00 00' +'00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00' +'00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00' +'00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00' +'00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00' +'00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00' +'00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF' +'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' +'FF FF FF FF FF FF FF C0 03 FF FC 00 00 3F F0 00' +'00 0F C0 00 00 03 80 00 00 01 80 00 00 01 00 00' +'00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00' +'00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00' +'00 00 80 00 00 01 C0 00 00 03 E0 00 00 07 FC 00' +'00 3F FF C0 03 FF FF FF FF FF FF FF FF FF FF FF' +'FF FF FF FF FF FF FF FF FF FF FF FF FF FF' +} + + +1 VERSIONINFO +FILEVERSION 1, 0, 1, 0 +PRODUCTVERSION 1, 0, 1, 0 +FILEFLAGSMASK 0 +FILEFLAGS VS_FFI_FILEFLAGSMASK +FILEOS VOS__WINDOWS32 +FILETYPE VFT_APP +{ + BLOCK "StringFileInfo" + { + BLOCK "040904E4" + { + VALUE "FileDescription", "Checkers for Windows\000" + VALUE "FileVersion", "1.01\000" + VALUE "InternalName", "Checkers\000" + VALUE "LegalCopyright", "Copyright 2003. Rumyantsev Andrey.\000" + VALUE "OriginalFilename", "WinCheckers.exe\000" + VALUE "ProductName", "Checkers\000" + VALUE "ProductVersion", "1.01\000" + } + + } + + BLOCK "VarFileInfo" + { + VALUE "Translation", 0x0409, 0x04e4 + } + +} + +IDD_ABOUT1 DIALOG 41, 33, 204, 65 +EXSTYLE WS_EX_DLGMODALFRAME +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "About Checkers" +FONT 8, "MS Sans Serif" +{ + CONTROL "Version", IDC_VERSION, "STATIC", SS_CENTER | SS_NOPREFIX | WS_CHILD | WS_VISIBLE | WS_GROUP, 28, 14, 174, 8 + CONTROL "C H E C K E R S", -1, "STATIC", SS_CENTER | SS_NOPREFIX | WS_CHILD | WS_VISIBLE | WS_GROUP, 28, 4, 174, 8 + CONTROL "", IDC_COPYRIGHT, "STATIC", SS_CENTER | SS_NOPREFIX | WS_CHILD | WS_VISIBLE | WS_GROUP, 28, 27, 174, 17 + CONTROL "", IDC_DEBUG, "STATIC", SS_RIGHT | SS_NOPREFIX | WS_CHILD | WS_VISIBLE | WS_GROUP, 136, 55, 66, 8 + CONTROL "WinDrawIcon", -1, "STATIC", SS_ICON | WS_CHILD | WS_VISIBLE, 8, 8, 21, 20 + CONTROL "OK", IDOK, "BUTTON", BS_DEFPUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 76, 46, 40, 14 +} + + + diff --git a/programs/games/checkers/trunk/win-chk.res b/programs/games/checkers/trunk/win-chk.res new file mode 100644 index 0000000000..84c657dca1 Binary files /dev/null and b/programs/games/checkers/trunk/win-chk.res differ diff --git a/programs/games/checkers/trunk/win-draw.h b/programs/games/checkers/trunk/win-draw.h new file mode 100644 index 0000000000..af9cd06688 --- /dev/null +++ b/programs/games/checkers/trunk/win-draw.h @@ -0,0 +1,530 @@ +#ifndef _Windows +# error Can't include this file without windows +#endif + +#include "gr-draw.h" + +#ifndef _WIN_GRAPHIC_DRAW_H +#define _WIN_GRAPHIC_DRAW_H + +#include "winabout.h" +#include "keysym.h" +#include +#include +#include +#include +#include +#include +#include + +#define main OwlMain + +class TWinGraphDraw : public TGraphDraw +{ +public: + TWinGraphDraw(const char *s = 0); + ~TWinGraphDraw(); +public: + static const int CM_ABOUT; + static unsigned long GetKeySym(unsigned int key); +protected: + class TDrwWindow : public TWindow + { + public: + TDrwWindow(TWinGraphDraw *drw) : TWindow(), win_draw(drw) + { + Init((TWindow*)NULL, 0, 0); + } + + TColor GetBkgndColor() const {return BkgndColor;} + protected: + void SetupWindow(); + bool CanClose(); + void Paint(TDC &dc, bool erase, TRect &rect); + void EvSize(uint sizeType, TSize &size) {Invalidate();} + void EvLButtonDblClk(uint modKeys, TPoint& point) {EvLButtonDown(modKeys, point);} + void EvLButtonDown(uint modKeys, TPoint& point); + void EvLButtonUp(uint modKeys, TPoint& point); + void EvRButtonDblClk(uint modKeys, TPoint& point) {EvRButtonDown(modKeys, point);} + void EvRButtonDown(uint modKeys, TPoint& point); + void EvRButtonUp(uint modKeys, TPoint& point); + void EvMButtonDblClk(uint modKeys, TPoint& point) {EvMButtonDown(modKeys, point);} + void EvMButtonDown(uint modKeys, TPoint& point); + void EvMButtonUp(uint modKeys, TPoint& point); + void EvMouseMove(uint modKeys, TPoint& point); + void EvKeyDown(uint key, uint repeatCount, uint flags); + void EvKeyUp(uint key, uint repeatCount, uint flags); + public: + TWinGraphDraw *win_draw; + + DECLARE_RESPONSE_TABLE(TDrwWindow); + }; + + class TDrwFrameWindow : public TFrameWindow + { + public: + TDrwFrameWindow(TWindow *parent, TDrwWindow *client); + protected: + virtual void SetupWindow(); + void EvSysCommand(uint cmdType, TPoint& point); + public: + TWinGraphDraw *win_draw; + + DECLARE_RESPONSE_TABLE(TDrwFrameWindow); + }; + + class TDrwApplication : public TApplication + { + public: + TDrwApplication(TWinGraphDraw *drw, int w = 0, int h = 0) + : def_w(w), def_h(h), win_draw(drw) {} + + void InitMainWindow() + { + win_draw->win = new TDrwWindow(win_draw); + SetMainWindow(new TDrwFrameWindow(0, win_draw->win)); + GetMainWindow()->SetIcon(this, "WinDrawIcon"); + GetMainWindow()->SetIconSm(this, "WinDrawIcon"); + if (def_w > 0 && def_h > 0) + { + GetMainWindow()->Attr.W = def_w + 2*GetSystemMetrics(SM_CXFRAME); + GetMainWindow()->Attr.H = def_h + + GetSystemMetrics(SM_CYCAPTION) + 2*GetSystemMetrics(SM_CYFRAME); + } + } + public: + int def_w, def_h; + TWinGraphDraw *win_draw; + }; + + friend class TDrwWindow; + friend class TDrwApplication; +protected: + TDrwApplication app; + TDrwWindow *win; + TDC *dc; + int kind_dc; + TColor bgcolor; + int evmask, quit; +public: + unsigned long GetBgColor(); + void SetBgColor(unsigned long c); + void SetTitle(const char *s); + + int GetStatus() {return win ? 1 : 0;} + int Init() {return 0;} + int Run(int evmask = 0, int w = INT_MIN, int h = INT_MIN); + + void GetSize(int &w, int &h); + int OpenDraw(); + int IsDraw() {return win && dc;} + void CloseDraw(); + + int SetColor(unsigned long c); + int DrawLine(int x0, int y0, int x1, int y1); + int DrawText(int x0, int y0, char *text); + int DrawClear(); + int GetTextH(const char *s); + int GetTextW(const char *s); + void Quit(int q = 1); +}; + +const int TWinGraphDraw::CM_ABOUT = 7128; + +unsigned long TWinGraphDraw::GetKeySym(uint key) +{ + switch(key) + { + case 37: return XK_Left; + case 39: return XK_Right; + case 38: return XK_Up; + case 40: return XK_Down; + case 13: return XK_Return; + case 32: return XK_space; + case 27: return XK_Escape; + case 188: return XK_comma; + case 190: return XK_period; + case 189: return XK_minus; + case 187: return XK_equal; + case 46: return XK_Delete; + case 191: return XK_slash; + case 112: return XK_F1; + case 113: return XK_F2; + case 114: return XK_F3; + case 115: return XK_F4; + case 116: return XK_F5; + case 117: return XK_F6; + case 118: return XK_F7; + case 119: return XK_F8; + case 120: return XK_F9; + case 121: return XK_F10; + case 122: return XK_F11; + case 123: return XK_F12; + case 65: return XK_a; + case 66: return XK_b; + case 67: return XK_c; + case 68: return XK_d; + case 69: return XK_e; + case 70: return XK_f; + case 71: return XK_g; + case 72: return XK_h; + case 73: return XK_i; + case 74: return XK_j; + case 75: return XK_k; + case 76: return XK_l; + case 77: return XK_m; + case 78: return XK_n; + case 79: return XK_o; + case 80: return XK_p; + case 81: return XK_q; + case 82: return XK_r; + case 83: return XK_s; + case 84: return XK_t; + case 85: return XK_u; + case 86: return XK_v; + case 87: return XK_w; + case 88: return XK_x; + case 89: return XK_y; + case 90: return XK_z; + default: return XK_VoidSymbol; + } +} + +TWinGraphDraw::TWinGraphDraw(const char *s) + : TGraphDraw(s), app(this), dc(0), kind_dc(0) +{ + bgcolor = GetWhiteColor(); +} + +TWinGraphDraw::~TWinGraphDraw() +{ + CloseDraw(); + dc = 0; kind_dc = 0; win = 0; +} + +unsigned long TWinGraphDraw::GetBgColor() +{ + if (win) bgcolor = win->GetBkgndColor(); + return bgcolor.GetValue(); +} + +void TWinGraphDraw::SetBgColor(unsigned long c) +{ + bgcolor.SetValue(c); + if (win) win->SetBkgndColor(bgcolor); +} + +void TWinGraphDraw::SetTitle(const char *s) +{ + TGraphDraw::SetTitle(s); + if (win) win->SetCaption(s); +} + +int TWinGraphDraw::Run(int evmask, int w, int h) +{ + if (!evfunc) return -2; + this->evmask = evmask; + app.def_w = w; app.def_h = h; + quit = 0; + app.Run(); + return quit; +} + +void TWinGraphDraw::GetSize(int &w, int &h) +{ + if (win) + { + TRect rect; + win->GetWindowRect(rect); + w = rect.Width(); h = rect.Height(); + } + else TGraphDraw::GetSize(w, h); +} + +int TWinGraphDraw::OpenDraw() +{ + if (!win) return 0; + if (!dc) {dc = new TWindowDC(*win); kind_dc = 1;} + return 1; +} + +void TWinGraphDraw::CloseDraw() +{ + if (dc && kind_dc == 1) delete dc; + if (kind_dc <= 2) {dc = 0; kind_dc = 0;} +} + +int TWinGraphDraw::SetColor(unsigned long c) +{ + if (!win || !dc) return 0; + TColor color(c); + dc->SelectObject((TPen)color); + dc->SetTextColor(color); + return 1; +} + +int TWinGraphDraw::DrawLine(int x0, int y0, int x1, int y1) +{ + if (!win || !dc) return 0; + dc->MoveTo(x0, y0); + dc->LineTo(x1, y1); + return 1; +} + +int TWinGraphDraw::DrawText(int x0, int y0, char *text) +{ + if (!win || !dc) return 0; + dc->TextOut(x0, y0, text); + return 1; +} + +int TWinGraphDraw::DrawClear() +{ + if (!win || !dc) return 0; + dc->FillRect(TRect(TPoint(0, 0), win->GetWindowRect().Size()), bgcolor); + return 1; +} + +int TWinGraphDraw::GetTextH(const char *s) +{ + if (win) + { + TFont fnt = win->GetWindowFont(); + return fnt.GetHeight(); + } + else return TGraphDraw::GetTextH(s); +} + +int TWinGraphDraw::GetTextW(const char *s) +{ + if (win) + { + TFont fnt = win->GetWindowFont(); + return fnt.GetMaxWidth() * strlen(s); + } + else return TGraphDraw::GetTextW(s); +} + +void TWinGraphDraw::Quit(int q) +{ + quit = q; + if (quit <= 0) quit = 0; + else if (win) win->PostMessage(WM_CLOSE); +} + +DEFINE_RESPONSE_TABLE1(TWinGraphDraw::TDrwFrameWindow, TFrameWindow) + EV_WM_SYSCOMMAND, +END_RESPONSE_TABLE; + +TWinGraphDraw::TDrwFrameWindow::TDrwFrameWindow(TWindow *parent, TDrwWindow *client) + : TFrameWindow(parent, client->win_draw->GetTitle(), client) +{ + win_draw = client->win_draw; +} + +void TWinGraphDraw::TDrwFrameWindow::SetupWindow() +{ + TFrameWindow::SetupWindow(); + if (win_draw->GetAboutInfo() > 0) + { + TMenu menu = GetSystemMenu(false); + menu.AppendMenu(MF_SEPARATOR); + menu.AppendMenu(MF_STRING, CM_ABOUT, "&About"); + } +} + +void TWinGraphDraw::TDrwFrameWindow::EvSysCommand(uint cmdType, TPoint& point) +{ + if (cmdType == CM_ABOUT) + { + char dia_name[50] = "IDD_ABOUT"; + int dia_num = win_draw->GetAboutInfo(); + if (dia_num > 0) + { + itoa(dia_num, dia_name + strlen(dia_name), 10); + TAboutDialog(this, dia_name).Execute(); + } + } + else TFrameWindow::EvSysCommand(cmdType, point); +} + +DEFINE_RESPONSE_TABLE1(TWinGraphDraw::TDrwWindow, TWindow) + EV_WM_MOUSEMOVE, + EV_WM_LBUTTONDBLCLK, + EV_WM_LBUTTONDOWN, + EV_WM_LBUTTONUP, + EV_WM_RBUTTONDBLCLK, + EV_WM_RBUTTONDOWN, + EV_WM_RBUTTONUP, + EV_WM_MBUTTONDBLCLK, + EV_WM_MBUTTONDOWN, + EV_WM_MBUTTONUP, + EV_WM_SIZE, + EV_WM_KEYDOWN, + EV_WM_KEYUP, +END_RESPONSE_TABLE; + +void TWinGraphDraw::TDrwWindow::SetupWindow() +{ + TWindow::SetupWindow(); + if (!win_draw || !win_draw->evfunc || win_draw->quit > 0) return; + event ev; + ev.type = event::start; + ev.any.drw = win_draw; + win_draw->evfunc(ev); + win_draw->CloseDraw(); +} + +bool TWinGraphDraw::TDrwWindow::CanClose() +{ + if (!win_draw || !win_draw->evfunc || win_draw->quit > 1) return true; + event ev; + ev.type = event::close; + ev.any.drw = win_draw; + win_draw->quit = win_draw->evfunc(ev); + if (win_draw->quit <= 0) win_draw->quit = 0; + win_draw->CloseDraw(); + return win_draw->quit != 0; +} + +void TWinGraphDraw::TDrwWindow::Paint(TDC &dc, bool, TRect&) +{ + if (!win_draw || !win_draw->evfunc || win_draw->quit > 0) return; + win_draw->CloseDraw(); + win_draw->dc = &dc; win_draw->kind_dc = 2; + event ev; + ev.type = event::draw; + ev.any.drw = win_draw; + win_draw->evfunc(ev); + win_draw->CloseDraw(); +} + +void TWinGraphDraw::TDrwWindow::EvLButtonDown(uint /*modKeys*/, TPoint& point) +{ + if (!win_draw || !win_draw->evfunc || win_draw->quit > 0 || + !(win_draw->evmask & button_down_mask)) return; + event ev; + ev.type = event::button_down; + ev.button.drw = win_draw; + ev.button.n = 1; + ev.button.x = point.x; + ev.button.y = point.y; + int r = win_draw->evfunc(ev); + if (r >= 0 && (r & ret_setcapture)) SetCapture(); + win_draw->CloseDraw(); +} + +void TWinGraphDraw::TDrwWindow::EvLButtonUp(uint /*modKeys*/, TPoint& point) +{ + ReleaseCapture(); + if (!win_draw || !win_draw->evfunc || win_draw->quit > 0 || + !(win_draw->evmask & button_up_mask)) return; + event ev; + ev.type = event::button_up; + ev.button.drw = win_draw; + ev.button.n = 1; + ev.button.x = point.x; + ev.button.y = point.y; + win_draw->evfunc(ev); + win_draw->CloseDraw(); +} + +void TWinGraphDraw::TDrwWindow::EvRButtonDown(uint /*modKeys*/, TPoint& point) +{ + if (!win_draw || !win_draw->evfunc || win_draw->quit > 0 || + !(win_draw->evmask & button_down_mask)) return; + event ev; + ev.type = event::button_down; + ev.button.drw = win_draw; + ev.button.n = 2; + ev.button.x = point.x; + ev.button.y = point.y; + int r = win_draw->evfunc(ev); + if (r >= 0 && (r & ret_setcapture)) SetCapture(); + win_draw->CloseDraw(); +} + +void TWinGraphDraw::TDrwWindow::EvRButtonUp(uint /*modKeys*/, TPoint& point) +{ + ReleaseCapture(); + if (!win_draw || !win_draw->evfunc || win_draw->quit > 0 || + !(win_draw->evmask & button_up_mask)) return; + event ev; + ev.type = event::button_up; + ev.button.drw = win_draw; + ev.button.n = 2; + ev.button.x = point.x; + ev.button.y = point.y; + win_draw->evfunc(ev); + win_draw->CloseDraw(); +} + +void TWinGraphDraw::TDrwWindow::EvMButtonDown(uint /*modKeys*/, TPoint& point) +{ + if (!win_draw || !win_draw->evfunc || win_draw->quit > 0 || + !(win_draw->evmask & button_down_mask)) return; + event ev; + ev.type = event::button_down; + ev.button.drw = win_draw; + ev.button.n = 3; + ev.button.x = point.x; + ev.button.y = point.y; + int r = win_draw->evfunc(ev); + if (r >= 0 && (r & ret_setcapture)) SetCapture(); + win_draw->CloseDraw(); +} + +void TWinGraphDraw::TDrwWindow::EvMButtonUp(uint /*modKeys*/, TPoint& point) +{ + ReleaseCapture(); + if (!win_draw || !win_draw->evfunc || win_draw->quit > 0 || + !(win_draw->evmask & button_up_mask)) return; + event ev; + ev.type = event::button_up; + ev.button.drw = win_draw; + ev.button.n = 3; + ev.button.x = point.x; + ev.button.y = point.y; + win_draw->evfunc(ev); + win_draw->CloseDraw(); +} + +void TWinGraphDraw::TDrwWindow::EvMouseMove(uint /*modKeys*/, TPoint& point) +{ + if (!win_draw || !win_draw->evfunc || win_draw->quit > 0 || + !(win_draw->evmask & (mouse_move_mask | mouse_drag_mask))) return; + event ev; + ev.type = event::mouse_move; + ev.button.drw = win_draw; + ev.button.n = -1; + ev.button.x = point.x; + ev.button.y = point.y; + win_draw->evfunc(ev); + win_draw->CloseDraw(); +} + +void TWinGraphDraw::TDrwWindow::EvKeyDown(uint key, uint /*repeatCount*/, uint /*flags*/) +{ + if (!win_draw || !win_draw->evfunc || win_draw->quit > 0 || + !(win_draw->evmask & key_down_mask)) return; + event ev; + ev.type = event::key_down; + ev.key.drw = win_draw; + ev.key.k = GetKeySym(key); + win_draw->evfunc(ev); + win_draw->CloseDraw(); +} + +void TWinGraphDraw::TDrwWindow::EvKeyUp(uint key, uint /*repeatCount*/, uint /*flags*/) +{ + if (!win_draw || !win_draw->evfunc || win_draw->quit > 0 || + !(win_draw->evmask & key_up_mask)) return; + event ev; + ev.type = event::key_up; + ev.key.drw = win_draw; + ev.key.k = GetKeySym(key); + win_draw->evfunc(ev); + win_draw->CloseDraw(); +} + +#endif //_WIN_GRAPHIC_DRAW_H diff --git a/programs/games/checkers/trunk/winabout.rh b/programs/games/checkers/trunk/winabout.rh new file mode 100644 index 0000000000..306b2a8703 --- /dev/null +++ b/programs/games/checkers/trunk/winabout.rh @@ -0,0 +1,3 @@ +#define IDC_DEBUG 22003 +#define IDC_COPYRIGHT 22002 +#define IDC_VERSION 22001 diff --git a/programs/games/fara/trunk/KosFile.cpp b/programs/games/fara/trunk/KosFile.cpp new file mode 100644 index 0000000000..fe29fa73d0 --- /dev/null +++ b/programs/games/fara/trunk/KosFile.cpp @@ -0,0 +1,131 @@ +#include "kosSyst.h" +#include "kosfile.h" + + +CKosFile::CKosFile(char *fileName) +{ + // + this->fileInfo.bufferPtr = new Byte[FILE_BUFFER_SIZE]; + // + this->filePointer = 0; + this->bufferPointer = 0; + this->validBuffer = false; + // + strcpy( this->fileInfo.fileURL, fileName ); +} + + +CKosFile::~CKosFile(void) +{ + // + delete this->fileInfo.bufferPtr; +} + + +void CKosFile::ValidateBuffer() +{ + // + if ( this->validBuffer ) + { + // + if ( this->filePointer < this->bufferPointer + || this->filePointer >= (this->bufferPointer + FILE_BUFFER_SIZE) ) + { + // + this->validBuffer = false; + } + } +} + + +void CKosFile::UpdateBuffer(void) +{ + // + if ( ! this->validBuffer ) + { + // + this->fileInfo.OffsetLow = this->filePointer / OS_BLOCK_SIZE; + this->fileInfo.OffsetHigh = 0; + // + this->bufferPointer = this->fileInfo.OffsetLow * OS_BLOCK_SIZE; + // + this->fileInfo.dataCount = FILE_BUFFER_BLOCKS; + // + this->fileInfo.rwMode = 0; + // + Dword rr = kos_FileSystemAccess( &(this->fileInfo) ); + this->validBuffer = ( rr == 0 ) || ( rr == 6 ); + } +} + + +int CKosFile::Seek(int seekFrom, int seekStep) +{ + // + switch ( seekFrom ) + { + // + case SEEK_SET: + // + this->filePointer = seekStep; + break; + // + case SEEK_CUR: + // + this->filePointer += seekStep; + break; + } + // + this->ValidateBuffer(); + // + return this->filePointer; +} + + +int CKosFile::Read(Byte *targetPtr, int readCount) +{ + int bufferLeast, result; + + // + result = 0; + // + do + { + // + this->UpdateBuffer(); + // + if ( ! this->validBuffer ) return result; + // + bufferLeast = FILE_BUFFER_SIZE - (this->filePointer - this->bufferPointer); + // + if ( bufferLeast > readCount ) bufferLeast = readCount; + // + if ( bufferLeast ) + { + // + memcpy( + targetPtr, + this->fileInfo.bufferPtr + (this->filePointer - this->bufferPointer), + bufferLeast + ); + // + targetPtr += bufferLeast; + readCount -= bufferLeast; + this->filePointer += bufferLeast; + // + result += bufferLeast; + } + // + this->ValidateBuffer(); + } + while ( readCount > 0 ); + // + return result; +} + + +int CKosFile::Write(Byte *sourcePtr, int writeCount) +{ + return 0; +} + diff --git a/programs/games/fara/trunk/KosFile.h b/programs/games/fara/trunk/KosFile.h new file mode 100644 index 0000000000..5f7c18e9bc --- /dev/null +++ b/programs/games/fara/trunk/KosFile.h @@ -0,0 +1,26 @@ +#pragma once + +#define SEEK_SET 0 +#define SEEK_CUR 1 + +#define FILE_BUFFER_SIZE 512 +#define OS_BLOCK_SIZE 1 +#define FILE_BUFFER_BLOCKS (FILE_BUFFER_SIZE / OS_BLOCK_SIZE) + + +class CKosFile +{ +public: + CKosFile(char *fileName); + virtual ~CKosFile(void); + virtual int Read(Byte *targetPtr, int readCount); + virtual int Write(Byte *sourcePtr, int writeCount); + virtual int Seek(int seekFrom, int seekStep); +protected: + int filePointer; + int bufferPointer; + bool validBuffer; + kosFileInfo fileInfo; + virtual void ValidateBuffer(void); + virtual void UpdateBuffer(void); +}; diff --git a/programs/games/fara/trunk/MCSMEMM.H b/programs/games/fara/trunk/MCSMEMM.H new file mode 100644 index 0000000000..42d61eaadb --- /dev/null +++ b/programs/games/fara/trunk/MCSMEMM.H @@ -0,0 +1,28 @@ +// + +struct MemBlock +{ + Dword Size; + Dword Addr; + MemBlock *Next; + MemBlock *Previous; +}; + + +#define INITIALQUEUESIZE (32 * 4) + +#define FALSE 0 +#define TRUE -1 + +#define MB_FREE 0 +#define MB_USER 1 + +#define SIZE_ALIGN 4 + + + +Byte *allocmem( Dword reqsize ); +Dword freemem( void *vaddress ); + + + diff --git a/programs/games/fara/trunk/Release/pe2kos.exe b/programs/games/fara/trunk/Release/pe2kos.exe new file mode 100644 index 0000000000..139e746398 Binary files /dev/null and b/programs/games/fara/trunk/Release/pe2kos.exe differ diff --git a/programs/games/fara/trunk/bmp2src.exe b/programs/games/fara/trunk/bmp2src.exe new file mode 100644 index 0000000000..984adf2174 Binary files /dev/null and b/programs/games/fara/trunk/bmp2src.exe differ diff --git a/programs/games/fara/trunk/bmp2src/bmp2src.dsp b/programs/games/fara/trunk/bmp2src/bmp2src.dsp new file mode 100644 index 0000000000..3b3ad354ac --- /dev/null +++ b/programs/games/fara/trunk/bmp2src/bmp2src.dsp @@ -0,0 +1,103 @@ +# Microsoft Developer Studio Project File - Name="bmp2src" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=bmp2src - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "bmp2src.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "bmp2src.mak" CFG="bmp2src - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "bmp2src - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "bmp2src - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "bmp2src - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib lzmapack.lib /nologo /subsystem:console /machine:I386 /opt:nowin98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "bmp2src - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib lzmapack.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "bmp2src - Win32 Release" +# Name "bmp2src - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\main.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/programs/games/fara/trunk/bmp2src/bmp2src.dsw b/programs/games/fara/trunk/bmp2src/bmp2src.dsw new file mode 100644 index 0000000000..04bd5dd271 --- /dev/null +++ b/programs/games/fara/trunk/bmp2src/bmp2src.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "bmp2src"=.\bmp2src.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/programs/games/fara/trunk/bmp2src/lzmapack.lib b/programs/games/fara/trunk/bmp2src/lzmapack.lib new file mode 100644 index 0000000000..f24c03846e Binary files /dev/null and b/programs/games/fara/trunk/bmp2src/lzmapack.lib differ diff --git a/programs/games/fara/trunk/bmp2src/main.cpp b/programs/games/fara/trunk/bmp2src/main.cpp new file mode 100644 index 0000000000..90047be385 --- /dev/null +++ b/programs/games/fara/trunk/bmp2src/main.cpp @@ -0,0 +1,166 @@ +#include +#include + +extern "C" __stdcall lzma_set_dict_size(unsigned logdictsize); +extern "C" __stdcall lzma_compress( + const void* source, + void* destination, + unsigned length, + void* workmem); + +typedef struct +{ + short int sizeX; + short int sizeY; + int compressedSize; + int physicalOffset; + int uncompressedSize; +} SCompBmpHeader; + +int main(int argc, char* argv[]) +{ + if (argc < 3) + { + printf("Usage: bmp2src ...\n"); + return 1; + } + FILE* fo = fopen(argv[1], "wb"); + if (!fo) + { + printf("Cannot create destination file\n"); + return 2; + } + int n=0; + SCompBmpHeader* hea = (SCompBmpHeader*)malloc((argc-2)*sizeof(SCompBmpHeader)); + void** ptrs = (void**)malloc((argc-2)*4); + lzma_set_dict_size(20); + void* workmem = (void*)malloc(0x509000 + (1<<20)*19/2); + for (int i=2;i= 0xE0 && buf[1] <= 0xEF) + { + fseek(fi,buf[2]*256 + buf[3] - 2,SEEK_CUR); + continue; + } + unsigned len = buf[2]*256 + buf[3] + 2; + fseek(fi,-4,SEEK_CUR); + fread(ptr,1,len,fi); + if (buf[1]>=0xC0 && buf[1]<=0xCF && buf[1]!=0xC4 && buf[1]!=0xC8 && buf[1]!=0xCC) + { + // found SOFn marker + hea[i-2].sizeX = (unsigned char)ptr[4+3]*256 + (unsigned char)ptr[4+4]; + hea[i-2].sizeY = (unsigned char)ptr[4+1]*256 + (unsigned char)ptr[4+2]; + bOk = true; + } + ptr += len; + if (buf[1] == 0xDA) + { + // SOS marker + len = insize - ftell(fi); + fread(ptr,1,len,fi); + ptr += len; + break; + } + } + if (!bOk) {printf(" invalid\n");free(ptr);continue;} + hea[i-2].compressedSize = ptr - (unsigned char*)output; + hea[i-2].uncompressedSize = hea[i-2].compressedSize - 1; + hea[i-2].physicalOffset = (i==2) ? 0 : + hea[i-3].physicalOffset+hea[i-3].compressedSize; + ptrs[i-2] = output; + ++n; + printf(" OK\n"); + continue; + } + if (buf[0x1C] != 24) + { + printf("Input file %s is not 24-bit BMP\n",argv[i]); + fclose(fi); + continue; + } + int width = *(int*)(buf+0x12); + int linesize = (width*3+3)&~3; + int height = *(int*)(buf+0x16); + void* input = malloc(width*height*3); + void* packed = malloc(9*width*height*3/8 + 0x80); + for (int p=0;p= uncompressedSize) + { + compressedSize = uncompressedSize; + free(packed); + ptrs[i-2] = input; + } + else + { + ptrs[i-2] = packed; + free(input); + } + printf(" %d -> %d\n",uncompressedSize, compressedSize); + hea[i-2].compressedSize = compressedSize; + ++n; + } + for (i=0;i= 0x8320; i-- ) + { + mask = i; + for ( j=0; j<8; j++ ) + { + k = mask; + mask >>= 1; + if ( k & 1 ) + { + mask ^= 0xEDB88320; + } + this->table[i & 0xFF] = mask; + } + } +} + + +Dword CCRC32::InitCRC32() +{ + return 0xFFFFFFFF; +} + + +Dword CCRC32::FinalizeCRC32(Dword d) +{ + return ~d; +} + + +void CCRC32::DoCRC32(Byte *buffer, Dword length, Dword *CRC32value) +{ + Dword result, i; + Byte mask; + + result = *CRC32value; + + for ( i=0; i>= 8 ) ^ this->table[mask]; + } + *CRC32value = result; +} + + +Dword CCRC32::GetCRC32(Byte *buffer, Dword length) +{ + Dword result; + + result = 0xFFFFFFFF; + + this->DoCRC32( buffer, length, &result ); + + return ~result; +} diff --git a/programs/games/fara/trunk/crc32.h b/programs/games/fara/trunk/crc32.h new file mode 100644 index 0000000000..2aceabb227 --- /dev/null +++ b/programs/games/fara/trunk/crc32.h @@ -0,0 +1,18 @@ +#if !defined(AFX_CRC32_H__1F375B73_5C72_4711_B464_7212EFC14AAE__INCLUDED_) +#define AFX_CRC32_H__1F375B73_5C72_4711_B464_7212EFC14AAE__INCLUDED_ + +class CCRC32 +{ +private: + Dword table[256]; + + +public: + Dword GetCRC32( Byte *buffer, Dword length ); + void DoCRC32( Byte *buffer, Dword length, Dword *CRC32value ); + Dword FinalizeCRC32( Dword ); + Dword InitCRC32(); + CCRC32(); +}; + +#endif // !defined(AFX_CRC32_H__1F375B73_5C72_4711_B464_7212EFC14AAE__INCLUDED_) diff --git a/programs/games/fara/trunk/face.bmp b/programs/games/fara/trunk/face.bmp new file mode 100644 index 0000000000..34ff774115 Binary files /dev/null and b/programs/games/fara/trunk/face.bmp differ diff --git a/programs/games/fara/trunk/face.jpg b/programs/games/fara/trunk/face.jpg new file mode 100644 index 0000000000..d706f12532 Binary files /dev/null and b/programs/games/fara/trunk/face.jpg differ diff --git a/programs/games/fara/trunk/fara.sln b/programs/games/fara/trunk/fara.sln new file mode 100644 index 0000000000..d181336476 --- /dev/null +++ b/programs/games/fara/trunk/fara.sln @@ -0,0 +1,19 @@ +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fara", "fara.vcproj", "{E102A7F0-5525-45CD-8078-82540F673720}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E102A7F0-5525-45CD-8078-82540F673720}.Debug|Win32.ActiveCfg = Release|Win32 + {E102A7F0-5525-45CD-8078-82540F673720}.Debug|Win32.Build.0 = Release|Win32 + {E102A7F0-5525-45CD-8078-82540F673720}.Release|Win32.ActiveCfg = Release|Win32 + {E102A7F0-5525-45CD-8078-82540F673720}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/programs/games/fara/trunk/fara.vcproj b/programs/games/fara/trunk/fara.vcproj new file mode 100644 index 0000000000..392a3e72c2 --- /dev/null +++ b/programs/games/fara/trunk/fara.vcproj @@ -0,0 +1,290 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/programs/games/fara/trunk/gameWnd.cpp b/programs/games/fara/trunk/gameWnd.cpp new file mode 100644 index 0000000000..833dab8997 --- /dev/null +++ b/programs/games/fara/trunk/gameWnd.cpp @@ -0,0 +1,1585 @@ +// + +#include "kosSyst.h" +#include "KosFile.h" +#include "gfxdef.h" +#include "gameWnd.h" +#include "mcarray.h" +#include "lang.h" + +// +#define EMPTY_PLACE 0 + +#define LEVEL_PROGRESS_LEFT (132+1) +#define LEVEL_PROGRESS_TOP (388+21) +#define LEVEL_PROGRESS_HEIGHT 4 +#define LEVEL_PROGRESS_WIDTH 329 +#define LEVEL_PROGRESS_COLOUR 0xDF2933 + +#define BONUS_SOMEBLOCK_TOP (120+21) +#define BONUS_SOMEBLOCK_LEFT (46+1) +#define BONUS_FREEBLOCK_TOP (163+21) +#define BONUS_FREEBLOCK_LEFT (9+1) +#define BONUS_DIAGBLOCK_TOP (213+21) +#define BONUS_DIAGBLOCK_LEFT (48+1) +#define BONUS_PROGRESS_HEIGHT 37 +#define BONUS_PROGRESS_WIDTH 4 + +#define LEVEL_SCORE_BASE 50 + +// +CKosBitmap gameFace; +CKosBitmap gameBlocks; +CKosBitmap gameNumbers; +CKosBitmap gameBlocksZ[4]; +// +CFishka *fishki[blocksNum]; + +// +char *gameWndTitle; +#if LANG == RUS +char gameWndTitle1[] = "࠮ ⥡ :)"; +char gameWndTitle2[] = " ..."; +char gameOverText[] = " ண !"; +#else +char gameWndTitle1[] = "Pharaoh waits for you :)"; +char gameWndTitle2[] = "Well..."; +char gameOverText[] = "No further way!"; +#endif +// +Word gcx, gcy; +// +#define mapSize 8 +// +// +#define blocksLeft (134+2) +#define blocksTop (43+22) +// +#define blockTypesNum 10 +// +Byte gameMap[mapSize * mapSize]; +// +int gameLevel; +// +int maxGameLevel; +int startGameLevel; +// +Dword playerScore; +// +int insertedBlocksCount; +// +int levelBlocksLimit; +// +int selectedBlock; +// * 1024 +int levelProgressStep; +// +int levelProgressCount; +// +struct sRemoveBlock +{ + short int ndx; + short int value; + sRemoveBlock() + { + this->ndx = 0; + this->value = 0; + }; + sRemoveBlock( int pNdx, int pValue ) + { + this->ndx = pNdx; + this->value = pValue; + }; +}; +bool operator == ( const sRemoveBlock &b1, const sRemoveBlock &b2 ) +{ + return b1.ndx == b2.ndx; +}; +MCArray toRemoveList; +// +MCArray toFallList; +// +bool mouseButtonDisabled; +// +bool freezeBonuses = false; +// +int bonusSomeBlockProgressStep; +int bonusSomeBlockProgressCount; +// +int bonusFreeBlockProgressStep; +int bonusFreeBlockProgressCount; +// +int bonusDiagBlockProgressStep; +int bonusDiagBlockProgressCount; + + + +#define SELECTED_BLOCK_NONE -1 + +// +int bonusSomeBlock; +// +int bonusSomeBlockCount; +// , , +int bonusSomeBlockEdge; +#define BONUS_SOMEBLOCK_SELECTED -2 +// +bool bonusFreeBlock; +int bonusFreeBlockCount; +int bonusFreeBlockEdge; +#define BONUS_FREEBLOCK_SELECTED -3 +// +int bonusDiagBlock; +int bonusDiagBlockCount; +int bonusDiagBlockEdge; +#define BONUS_DIAGBLOCK_SELECTED -4 +// +void drawScore(); +// +void drawBonuses(); +// +void drawLevelNum(); +// +void fadeOutBlocks(); +// +void fallDownBlocks(); + + +void ClearGameMeters() +{ + // + kos_DrawBar( + LEVEL_PROGRESS_LEFT, + LEVEL_PROGRESS_TOP, + LEVEL_PROGRESS_WIDTH, + LEVEL_PROGRESS_HEIGHT, + 0 + ); + // + // some + kos_DrawBar( + 33+1, + 118+21, + BONUS_PROGRESS_WIDTH, + BONUS_PROGRESS_HEIGHT, + 0 + ); + // free + kos_DrawBar( + 58+1, + 166+21, + BONUS_PROGRESS_WIDTH, + BONUS_PROGRESS_HEIGHT, + 0 + ); + // diag + kos_DrawBar( + 37+1, + 213+21, + BONUS_PROGRESS_WIDTH, + BONUS_PROGRESS_HEIGHT, + 0 + ); +} + + +// +void drawGameMeters() +{ + // + ClearGameMeters(); + // + kos_DrawBar( + LEVEL_PROGRESS_LEFT, + LEVEL_PROGRESS_TOP, + levelProgressCount, + LEVEL_PROGRESS_HEIGHT, + LEVEL_PROGRESS_COLOUR + ); + // + if ( bonusSomeBlockProgressCount > 0 ) + // some + kos_DrawBar( + 33+1, + 118+21+BONUS_PROGRESS_HEIGHT-bonusSomeBlockProgressCount, + BONUS_PROGRESS_WIDTH, + bonusSomeBlockProgressCount, + LEVEL_PROGRESS_COLOUR + ); + // + if ( bonusFreeBlockProgressCount > 0 ) + // free + kos_DrawBar( + 58+1, + 166+21+BONUS_PROGRESS_HEIGHT-bonusFreeBlockProgressCount, + BONUS_PROGRESS_WIDTH, + bonusFreeBlockProgressCount, + LEVEL_PROGRESS_COLOUR + ); + // + if ( bonusDiagBlockProgressCount > 0 ) + // diag + kos_DrawBar( + 37+1, + 213+21+BONUS_PROGRESS_HEIGHT-bonusDiagBlockProgressCount, + BONUS_PROGRESS_WIDTH, + bonusDiagBlockProgressCount, + LEVEL_PROGRESS_COLOUR + ); +} + + +//////////////////////////////////////////////////////////////////////////////// +void SetLevelVariables() +{ + selectedBlock = -1; + levelBlocksLimit = ( gameLevel > 5 ) ? LEVEL_SCORE_BASE * ( gameLevel + 1 ) : LEVEL_SCORE_BASE * ( 11 - gameLevel ); + insertedBlocksCount = 0; + // + levelProgressCount = 0; + levelProgressStep = ( LEVEL_PROGRESS_WIDTH * 1024 ) / levelBlocksLimit; + // + bonusSomeBlockEdge = levelBlocksLimit / 4; + bonusFreeBlockEdge = levelBlocksLimit / 3; + bonusDiagBlockEdge = levelBlocksLimit / 2; + // + bonusSomeBlockProgressStep = ( BONUS_PROGRESS_HEIGHT * 1024 ) / bonusSomeBlockEdge; + bonusSomeBlockProgressCount = ( ( ( bonusSomeBlockCount > bonusSomeBlockEdge ) ? bonusSomeBlockEdge : bonusSomeBlockCount ) * bonusSomeBlockProgressStep ) / 1024; + // + bonusFreeBlockProgressStep = ( BONUS_PROGRESS_HEIGHT * 1024 ) / bonusFreeBlockEdge; + bonusFreeBlockProgressCount = ( ( ( bonusFreeBlockCount > bonusFreeBlockEdge ) ? bonusFreeBlockEdge : bonusFreeBlockCount ) * bonusFreeBlockProgressStep ) / 1024; + // + bonusDiagBlockProgressStep = ( BONUS_PROGRESS_HEIGHT * 1024 ) / bonusDiagBlockEdge; + bonusDiagBlockProgressCount = ( ( ( bonusDiagBlockCount > bonusDiagBlockEdge ) ? bonusDiagBlockEdge : bonusDiagBlockCount ) * bonusDiagBlockProgressStep ) / 1024; +} + + +// +int GetScoreByBlocks( int blocksCount ) +{ + int limit, update, i, j, acc; + + // + if ( blocksCount < 3 ) return 0; + // + limit = 20 * blocksNum * gameLevel; + // + update = gameLevel; + acc = 1; + // + j = blocksCount - 3; + // + for ( i = 0; i < j; i++ ) + { + // + acc *= gameLevel + 1; + // + if ( ( update + acc ) > limit ) return limit; + } + // + return update + acc; +} + + + +// +int insertNewBlocks() +{ + int i, j, k, ndx, result, btn; + + // + toFallList.Clear(); + // + result = 0; + // + btn = gameLevel > 5 ? blockTypesNum : 5 + gameLevel; + // + ndx = ( mapSize * mapSize ) - mapSize; + // + for ( i = 0; i < mapSize; i++ ) + { + for ( j = 0; j < mapSize; j++ ) + { + // + k = ndx + i - ( j * mapSize ); + // + if ( gameMap[k] == EMPTY_PLACE ) + { + // + for ( ; j < (mapSize-1); j++ ) + { + // + gameMap[k] = gameMap[k-mapSize]; + toFallList.AddExclusive( k ); + k -= mapSize; + } + // + gameMap[i] = ( rtlRand() % btn ) + 1; + toFallList.AddExclusive( i ); + // + result++; + // + break; + } + } + } + // + insertedBlocksCount += result; + // + return result; +} + + +// , +// +int findBlockLines() +{ + int x, y, ndx; + int removeCount = 0; + + // + toRemoveList.Clear(); + // + for ( y = 0; y < mapSize; y++ ) + { + // + for ( x = 0; x < mapSize; x++ ) + { + // + ndx = x + ( y * mapSize ); + // + if ( gameMap[ndx] == EMPTY_PLACE ) continue; + // + if ( x < (mapSize - 2) ) + { + // + if ( + ( gameMap[ndx] == gameMap[ndx+1] && gameMap[ndx] == gameMap[ndx+2] ) + || ( BONUS_FREE_BLOCK == gameMap[ndx] && gameMap[ndx+1] == gameMap[ndx+2] ) + || ( gameMap[ndx] == gameMap[ndx+1] && BONUS_FREE_BLOCK == gameMap[ndx+2] ) + || ( gameMap[ndx] == gameMap[ndx+2] && BONUS_FREE_BLOCK == gameMap[ndx+1] ) + ) + { + // , + toRemoveList.AddExclusive( sRemoveBlock( ndx, gameMap[ndx] ) ); + toRemoveList.AddExclusive( sRemoveBlock( ndx+1, gameMap[ndx+1] ) ); + toRemoveList.AddExclusive( sRemoveBlock( ndx+2, gameMap[ndx+2] ) ); + } + } + // + if ( y < (mapSize - 2) ) + { + // + if ( + ( gameMap[ndx] == gameMap[ndx+mapSize] && gameMap[ndx] == gameMap[ndx+mapSize+mapSize] ) + || ( BONUS_FREE_BLOCK == gameMap[ndx] && gameMap[ndx+mapSize] == gameMap[ndx+mapSize+mapSize] ) + || ( gameMap[ndx] == gameMap[ndx+mapSize] && BONUS_FREE_BLOCK == gameMap[ndx+mapSize+mapSize] ) + || ( gameMap[ndx] == gameMap[ndx+mapSize+mapSize] && BONUS_FREE_BLOCK == gameMap[ndx+mapSize] ) + ) + { + // , + toRemoveList.AddExclusive( sRemoveBlock( ndx, gameMap[ndx] ) ); + toRemoveList.AddExclusive( sRemoveBlock( ndx+mapSize, gameMap[ndx+mapSize] ) ); + toRemoveList.AddExclusive( sRemoveBlock( ndx+mapSize+mapSize, gameMap[ndx+mapSize+mapSize] ) ); + } + } + } + } + // + return toRemoveList.GetCount(); +} + + +// - +bool checkGameOut() +{ + int x, y, ndx; + + // + ndx = 0; + // + for ( y = 0; y < mapSize; y++ ) + { + // + for ( x = 0; x < mapSize; x++ ) + { + // + if ( x < (mapSize - 1) ) + { + // + if ( gameMap[ndx] == gameMap[ndx+1] ) + { + // + // + if ( bonusSomeBlock == gameMap[ndx] ) return false; + if ( bonusFreeBlock ) return false; + // + if ( y > 0 ) + { + // + if ( x > 0 ) + { + // + if ( gameMap[ndx-mapSize-1] == gameMap[ndx] ) return false; + } + // + if ( x < (mapSize - 2) ) + { + // + if ( gameMap[ndx-mapSize+2] == gameMap[ndx] ) return false; + } + } + // + if ( x > 1 ) + { + // + if ( gameMap[ndx-2] == gameMap[ndx] ) return false; + } + // + if ( x < (mapSize - 3) ) + { + // + if ( gameMap[ndx+3] == gameMap[ndx] ) return false; + } + // + if ( y < (mapSize - 1) ) + { + // + if ( x > 0 ) + { + // + if ( gameMap[ndx+mapSize-1] == gameMap[ndx] ) return false; + } + // + if ( x < (mapSize - 2) ) + { + // + if ( gameMap[ndx+mapSize+2] == gameMap[ndx] ) return false; + } + } + // + if ( bonusDiagBlock > 0 ) + { + // + if ( y > 0 ) + { + // + if ( x > 1 ) + { + // + if ( gameMap[ndx-mapSize-2] == gameMap[ndx] ) return false; + } + // + if ( gameMap[ndx-mapSize] == gameMap[ndx] ) return false; + // + if ( x < (mapSize - 2) ) + { + // + if ( gameMap[ndx-mapSize+1] == gameMap[ndx] ) return false; + } + // + if ( x < (mapSize - 3) ) + { + // + if ( gameMap[ndx-mapSize+3] == gameMap[ndx] ) return false; + } + } + // + if ( y < (mapSize - 1) ) + { + // + if ( x > 1 ) + { + // + if ( gameMap[ndx+mapSize-2] == gameMap[ndx] ) return false; + } + // + if ( gameMap[ndx+mapSize] == gameMap[ndx] ) return false; + // + if ( x < (mapSize - 2) ) + { + // + if ( gameMap[ndx+mapSize+1] == gameMap[ndx] ) return false; + } + // + if ( x < (mapSize - 3) ) + { + // + if ( gameMap[ndx+mapSize+3] == gameMap[ndx] ) return false; + } + } + } // + } + } + // + if ( x < (mapSize - 2) ) + { + // + if ( gameMap[ndx] == gameMap[ndx+2] ) + { + // + // + if ( bonusSomeBlock == gameMap[ndx] ) return false; + if ( bonusFreeBlock ) return false; + // + if ( y > 0 ) + { + // + if ( gameMap[ndx-mapSize+1] == gameMap[ndx] ) return false; + } + // + if ( y < (mapSize-1) ) + { + // + if ( gameMap[ndx+mapSize+1] == gameMap[ndx] ) return false; + } + // + if ( bonusDiagBlock > 0 ) + { + // + if ( y > 0 ) + { + // + if ( gameMap[ndx-mapSize] == gameMap[ndx] ) return false; + // + if ( gameMap[ndx-mapSize+2] == gameMap[ndx] ) return false; + } + // + if ( y < (mapSize-1) ) + { + // + if ( gameMap[ndx+mapSize] == gameMap[ndx] ) return false; + // + if ( gameMap[ndx+mapSize+2] == gameMap[ndx] ) return false; + } + } + } + } + // + if ( y < (mapSize - 1) ) + { + // + if ( gameMap[ndx] == gameMap[ndx+mapSize] ) + { + // + // + if ( bonusSomeBlock == gameMap[ndx] ) return false; + if ( bonusFreeBlock ) return false; + // + if ( x > 0 ) + { + // + if ( y > 0 ) + { + // + if ( gameMap[ndx-1-mapSize] == gameMap[ndx] ) return false; + } + // + if ( y < (mapSize - 2) ) + { + // + if ( gameMap[ndx-1+(2*mapSize)] == gameMap[ndx] ) return false; + } + } + // + if ( y > 1 ) + { + // + if ( gameMap[ndx-(2*mapSize)] == gameMap[ndx] ) return false; + } + // + if ( y < (mapSize - 3) ) + { + // + if ( gameMap[ndx+(3*mapSize)] == gameMap[ndx] ) return false; + } + // + if ( x < (mapSize - 1) ) + { + // + if ( y > 0 ) + { + // + if ( gameMap[ndx+1-mapSize] == gameMap[ndx] ) return false; + } + // + if ( y < (mapSize - 2) ) + { + // + if ( gameMap[ndx+1+(2*mapSize)] == gameMap[ndx] ) return false; + } + } + // + if ( bonusDiagBlock > 0 ) + { + // + if ( x > 0 ) + { + // + if ( y > 1 ) + { + // + if ( gameMap[ndx-1-(2*mapSize)] == gameMap[ndx] ) return false; + } + // + if ( gameMap[ndx-1] == gameMap[ndx] ) return false; + // + if ( y < (mapSize - 2) ) + { + // + if ( gameMap[ndx-1+mapSize] == gameMap[ndx] ) return false; + } + // + if ( y < (mapSize - 3) ) + { + // + if ( gameMap[ndx-1+(3*mapSize)] == gameMap[ndx] ) return false; + } + } + // + if ( x < (mapSize - 1) ) + { + // + if ( y > 1 ) + { + // + if ( gameMap[ndx+1-(2*mapSize)] == gameMap[ndx] ) return false; + } + // + if ( gameMap[ndx+1] == gameMap[ndx] ) return false; + // + if ( y < (mapSize - 2) ) + { + // + if ( gameMap[ndx+1+mapSize] == gameMap[ndx] ) return false; + } + // + if ( y < (mapSize - 3) ) + { + // + if ( gameMap[ndx+1+(3*mapSize)] == gameMap[ndx] ) return false; + } + } + } // + } + } + // + if ( y < (mapSize - 2) ) + { + // + if ( gameMap[ndx] == gameMap[ndx+(2*mapSize)] ) + { + // + // + if ( bonusSomeBlock == gameMap[ndx] ) return false; + if ( bonusFreeBlock ) return false; + // + if ( x > 0 ) + { + // + if ( gameMap[ndx-1+mapSize] == gameMap[ndx] ) return false; + } + // + if ( x < (mapSize-1) ) + { + // + if ( gameMap[ndx+1+mapSize] == gameMap[ndx] ) return false; + } + // + if ( bonusDiagBlock > 0 ) + { + // + if ( x > 0 ) + { + // + if ( gameMap[ndx-1] == gameMap[ndx] ) return false; + // + if ( gameMap[ndx-1+(2*mapSize)] == gameMap[ndx] ) return false; + } + // + if ( x < (mapSize-1) ) + { + // + if ( gameMap[ndx+1] == gameMap[ndx] ) return false; + // + if ( gameMap[ndx+1+(2*mapSize)] == gameMap[ndx] ) return false; + } + } + } + } + // + ndx++; + } + } + // + gameWndTitle = gameWndTitle2; + // + return true; +} + + +// +bool exterminateLines() +{ + int deletedBlocks, btn, i, j; + bool needRedrawBonus = false; + + // + btn = gameLevel > 5 ? blockTypesNum : 5 + gameLevel; + // + playerScore += GetScoreByBlocks( deletedBlocks = findBlockLines() ); + // + if ( ! freezeBonuses ) + { + // + if ( gameLevel >= 2 && bonusSomeBlock <= 0 ) bonusSomeBlockCount += deletedBlocks; + if ( gameLevel >= 3 && !bonusFreeBlock ) bonusFreeBlockCount += deletedBlocks; + if ( gameLevel >= 4 && bonusDiagBlock <= 0 ) bonusDiagBlockCount += deletedBlocks; + // + if ( + ( bonusSomeBlockCount >= bonusSomeBlockEdge || ( gameLevel >= 2 && deletedBlocks >= 4 ) ) + && bonusSomeBlock <= 0 + ) + { + bonusSomeBlock = ( rtlRand() % btn ) + 1; + needRedrawBonus = true; + if ( bonusSomeBlockCount >= bonusSomeBlockEdge ) bonusSomeBlockCount = 0; + } + if ( bonusSomeBlockCount >= bonusSomeBlockEdge ) bonusSomeBlockCount = 0; + // + if ( bonusFreeBlockCount >= bonusFreeBlockEdge || ( gameLevel >=3 && deletedBlocks >= 5 ) ) + { + bonusFreeBlock = true; + needRedrawBonus = true; + if ( bonusFreeBlockCount >= bonusFreeBlockEdge ) bonusFreeBlockCount = 0; + } + if ( bonusFreeBlockCount >= bonusFreeBlockEdge ) bonusFreeBlockCount = 0; + // + if ( bonusDiagBlockCount >= bonusDiagBlockEdge || ( gameLevel >= 4 && deletedBlocks >= 6 ) ) + { + bonusDiagBlock = 3; + needRedrawBonus = true; + if ( bonusDiagBlockCount >= bonusDiagBlockEdge ) bonusDiagBlockCount = 0; + } + if ( bonusDiagBlockCount >= bonusDiagBlockEdge ) bonusDiagBlockCount = 0; + // + bonusSomeBlockProgressCount = ( ( ( bonusSomeBlockCount > bonusSomeBlockEdge ) ? bonusSomeBlockEdge : bonusSomeBlockCount ) * bonusSomeBlockProgressStep ) / 1024; + // + bonusFreeBlockProgressCount = ( ( ( bonusFreeBlockCount > bonusFreeBlockEdge ) ? bonusFreeBlockEdge : bonusFreeBlockCount ) * bonusFreeBlockProgressStep ) / 1024; + // + bonusDiagBlockProgressCount = ( ( ( bonusDiagBlockCount > bonusDiagBlockEdge ) ? bonusDiagBlockEdge : bonusDiagBlockCount ) * bonusDiagBlockProgressStep ) / 1024; + // + if ( needRedrawBonus ) drawBonuses(); + } + // + j = toRemoveList.GetCount(); + // + for ( i = 0; i < j; i++ ) + { + gameMap[toRemoveList[i].ndx] = EMPTY_PLACE; + } + // + return toRemoveList.GetCount() > 0; +} + + +// +void initGameMap() +{ + int i, localScore, localInserted, btn; + + // + btn = gameLevel > 5 ? blockTypesNum : 5 + gameLevel; + // + for ( i = 0; i < (mapSize * mapSize); i++ ) + { + gameMap[i] = ( rtlRand() % btn ) + 1; + } + // + localScore = playerScore; + localInserted = insertedBlocksCount; + // + freezeBonuses = true; + // + while ( exterminateLines() ) + { + while ( insertNewBlocks() > 0 ); + } + // + freezeBonuses = false; + // + playerScore = localScore; + insertedBlocksCount = localInserted; +} + + +// +void drawBonuses() +{ + // + kos_PutImage( + selectedBlock != BONUS_SOMEBLOCK_SELECTED ? + fishki[bonusSomeBlock]->GetBits() : + fishki[bonusSomeBlock]->GetHighlightedBits(), + blockSize, blockSize, + BONUS_SOMEBLOCK_LEFT, BONUS_SOMEBLOCK_TOP + ); + // + kos_PutImage( + bonusFreeBlock ? + ( + selectedBlock != BONUS_FREEBLOCK_SELECTED ? + fishki[BONUS_FREE_BLOCK]->GetBits() : + fishki[BONUS_FREE_BLOCK]->GetHighlightedBits() + ) : + fishki[0]->GetBits(), + blockSize, blockSize, + BONUS_FREEBLOCK_LEFT, BONUS_FREEBLOCK_TOP + ); + // + kos_PutImage( + bonusDiagBlock > 0 ? + fishki[bonusDiagBlock+BONUS_DIAG_BLOCK-1]->GetBits() : + fishki[0]->GetBits(), + blockSize, blockSize, + BONUS_DIAGBLOCK_LEFT, BONUS_DIAGBLOCK_TOP + ); +} + + +// +void drawGameMap() +{ + int i, j, ndx; + + // + for ( i = 0; i < mapSize; i++ ) + { + // + for ( j = 0; j < mapSize; j++ ) + { + // + ndx = (i*mapSize) + j; + // + kos_PutImage( + ndx != selectedBlock ? + fishki[gameMap[ndx]]->GetBits() : + fishki[gameMap[ndx]]->GetHighlightedBits(), + blockSize, blockSize, + (j * blockSize) + blocksLeft, + (i * blockSize) + blocksTop + ); + } + } +} + + +// "" +int mX, mY; + +// "" +bool mouseLButtonDown() +{ + static bool isDown = false; + Dword buttons; + + // + kos_GetMouseState( buttons, mX, mY ); + // + if ( mouseButtonDisabled ) return false; + // + if ( ( buttons & 1 ) ) + { + if ( isDown ) + return false; + else + { + isDown = true; + return true; + } + } + else + { + if ( isDown ) + { + isDown = false; + } + return false; + } +} + +// +void flipTwoBlocks( int ndx1, int ndx2 ) +{ + Word blX, blY, selX, selY; + Byte fishCode; + + // + blX = ( ndx1 % mapSize ) * blockSize + blocksLeft; + blY = ( ndx1 / mapSize ) * blockSize + blocksTop; + selX = ( ndx2 % mapSize ) * blockSize + blocksLeft; + selY = ( ndx2 / mapSize ) * blockSize + blocksTop; + // + fishCode = gameMap[ndx1]; + gameMap[ndx1] = gameMap[ndx2]; + gameMap[ndx2] = fishCode; + // + kos_PutImage( + fishki[gameMap[ndx1]]->GetBits(), + blockSize, blockSize, + blX, + blY + ); + // + kos_PutImage( + fishki[gameMap[ndx2]]->GetBits(), + blockSize, blockSize, + selX, + selY + ); +} + + +// +int GameLoop() +{ + int result, ndx, blX, blY, selX, selY, ddX, ddY, nSel; + Byte keyCode, mCode; + bool needDecBonus; + Dword buttonID; + + // + gameWndTitle = gameWndTitle1; + gameFace.GetSize( gcx, gcy ); + gameLevel = startGameLevel; + playerScore = 0; + bonusSomeBlock = 0; + bonusFreeBlock = false; + bonusDiagBlock = 0; + bonusSomeBlockCount = 0; + bonusFreeBlockCount = 0; + bonusDiagBlockCount = 0; + bonusSomeBlockProgressCount = 0; + bonusFreeBlockProgressCount = 0; + bonusDiagBlockProgressCount = 0; + SetLevelVariables(); + mouseButtonDisabled = false; + initGameMap(); + // + kos_ChangeWindow( -1, -1, gcx + 1, gcy + 21 ); + // + for ( result = GM_NONE; result == GM_NONE; ) + { + switch( kos_WaitForEvent() ) + { + // + case 1: + DrawGameWindow(); + break; + + // + case 2: + if ( kos_GetKey( keyCode ) ) + { + // + switch ( keyCode ) + { + case 0x1B: + result = GM_ABORT; + break; + + default: + break; + } + } + break; + + // + case 3: + if ( kos_GetButtonID( buttonID ) ) + { + switch ( buttonID ) + { + case 0xA: + result = GM_ABORT; + break; + + default: + break; + } + } + + // + case 6: + // ? + if ( mouseLButtonDown() ) + { + // + blX = mX - blocksLeft; + blY = mY - blocksTop; + // ? + if ( blX >= 0 && blX < (mapSize * blockSize) + && blY >= 0 && blY < (mapSize * blockSize) ) + { + // + blX /= blockSize; + blY /= blockSize; + // + ndx = blX + ( blY * mapSize ); + // , + if ( ndx >= 0 && ndx < (mapSize * mapSize) ) + { + // + kos_WindowRedrawStatus( WRS_BEGIN ); + // + if ( selectedBlock == SELECTED_BLOCK_NONE ) + { + // + selectedBlock = ndx; + // + kos_PutImage( + fishki[gameMap[selectedBlock]]->GetHighlightedBits(), + blockSize, blockSize, + ( selectedBlock % mapSize ) * blockSize + blocksLeft, + ( selectedBlock / mapSize ) * blockSize + blocksTop + ); + } + else // + { + if ( selectedBlock >= 0 ) + { + // + selX = selectedBlock % mapSize; + selY = selectedBlock / mapSize; + // ? + if ( ndx != selectedBlock ) + { + // + ddX = selX - blX; + ddY = selY - blY; + needDecBonus = ( bonusDiagBlock > 0 && abs(ddX) == 1 && abs(ddY) == 1 ); + // + if ( + ( abs(ddX) == 1 && ddY == 0 ) + || ( abs(ddY) == 1 && ddX == 0 ) + || needDecBonus + ) + { + // + flipTwoBlocks( ndx, selectedBlock ); + // + kos_Pause( 16 ); + // + if ( findBlockLines() > 0 ) + { + // + if ( needDecBonus ) + { + // + --bonusDiagBlock; + // + drawBonuses(); + } + // + selectedBlock = SELECTED_BLOCK_NONE; + // + while ( exterminateLines() ) + { + // + fadeOutBlocks(); + // + //drawGameMap(); + //drawScore(); + // + //kos_Pause( 25 ); + // + while ( insertNewBlocks() > 0 ) + { + // + fallDownBlocks(); + // + //drawGameMap(); + //kos_Pause( 30 ); + } + } + // + drawScore(); + // + levelProgressCount = ( ( ( insertedBlocksCount > levelBlocksLimit ) ? levelBlocksLimit : insertedBlocksCount ) * levelProgressStep ) / 1024; + // + drawGameMeters(); + // + if ( insertedBlocksCount > levelBlocksLimit ) + { + kos_Pause( 50 ); + gameLevel++; + SetLevelVariables(); + // + //initGameMap(); + // + //DrawGameWindow(); + // + drawGameMeters(); + drawLevelNum(); + } + else + // + if ( mouseButtonDisabled = checkGameOut() ) + { + // + DrawGameWindow(); + } + } + else + { + // , + flipTwoBlocks( ndx, selectedBlock ); + // + selectedBlock = SELECTED_BLOCK_NONE; + } + } + else // + { + // + kos_PutImage( + fishki[gameMap[selectedBlock]]->GetBits(), + blockSize, blockSize, + selX * blockSize + blocksLeft, + selY * blockSize + blocksTop + ); + // + selectedBlock = ndx; + // + kos_PutImage( + fishki[gameMap[selectedBlock]]->GetHighlightedBits(), + blockSize, blockSize, + blX * blockSize + blocksLeft, + blY * blockSize + blocksTop + ); + } + } + else // + { + // + kos_PutImage( + fishki[gameMap[selectedBlock]]->GetBits(), + blockSize, blockSize, + selX * blockSize + blocksLeft, + selY * blockSize + blocksTop + ); + // + selectedBlock = SELECTED_BLOCK_NONE; + } + } + else + // + { + // + mCode = gameMap[ndx]; + // + switch ( selectedBlock ) + { + case BONUS_SOMEBLOCK_SELECTED: + gameMap[ndx] = bonusSomeBlock; + break; + + case BONUS_FREEBLOCK_SELECTED: + gameMap[ndx] = BONUS_FREE_BLOCK; + break; + + default: + break; + } + // + if ( findBlockLines() > 0 ) + { + // + switch ( selectedBlock ) + { + case BONUS_SOMEBLOCK_SELECTED: + bonusSomeBlock = 0; + break; + + case BONUS_FREEBLOCK_SELECTED: + bonusFreeBlock = false; + break; + + default: + break; + } + // + drawBonuses(); + drawGameMap(); + kos_Pause( 16 ); + // + // + selectedBlock = SELECTED_BLOCK_NONE; + // + while ( exterminateLines() ) + { + // + fadeOutBlocks(); + // + //drawGameMap(); + //drawScore(); + // + //kos_Pause( 25 ); + // + while ( insertNewBlocks() > 0 ) + { + // + fallDownBlocks(); + // + //drawGameMap(); + //kos_Pause( 30 ); + } + } + // + drawScore(); + // + levelProgressCount = ( ( ( insertedBlocksCount > levelBlocksLimit ) ? levelBlocksLimit : insertedBlocksCount ) * levelProgressStep ) / 1024; + // + drawGameMeters(); + // + if ( insertedBlocksCount > levelBlocksLimit ) + { + kos_Pause( 50 ); + gameLevel++; + SetLevelVariables(); + // + //initGameMap(); + // + //DrawGameWindow(); + // + drawGameMeters(); + drawLevelNum(); + } + else + // + mouseButtonDisabled = checkGameOut(); + } + else + // + { + // + gameMap[ndx] = mCode; + // + selectedBlock = ndx; + // + kos_PutImage( + fishki[gameMap[selectedBlock]]->GetHighlightedBits(), + blockSize, blockSize, + blX * blockSize + blocksLeft, + blY * blockSize + blocksTop + ); + // + drawBonuses(); + } + } + } + // + kos_DefineButton( + 444+1, 2+21, + 54, 20, + 0x6000000A, + 0 + ); + // + kos_WindowRedrawStatus( WRS_END ); + } + } + else + // + { + nSel = 0; + // + if ( mX >= BONUS_SOMEBLOCK_LEFT && (mX - BONUS_SOMEBLOCK_LEFT) <= blockSize + && mY >= BONUS_SOMEBLOCK_TOP && (mY - BONUS_SOMEBLOCK_TOP ) <= blockSize ) + { + // + nSel = BONUS_SOMEBLOCK_SELECTED; + } + // + if ( mX >= BONUS_FREEBLOCK_LEFT && (mX - BONUS_FREEBLOCK_LEFT) <= blockSize + && mY >= BONUS_FREEBLOCK_TOP && (mY - BONUS_FREEBLOCK_TOP ) <= blockSize ) + { + // + nSel = BONUS_FREEBLOCK_SELECTED; + } + // + if ( mX >= BONUS_DIAGBLOCK_LEFT && (mX - BONUS_DIAGBLOCK_LEFT) <= blockSize + && mY >= BONUS_DIAGBLOCK_TOP && (mY - BONUS_DIAGBLOCK_TOP ) <= blockSize ) + { + // + nSel = BONUS_DIAGBLOCK_SELECTED; + } + // + if ( nSel != 0 ) + { + // + if ( selectedBlock > 0 ) + { + // + kos_PutImage( + fishki[gameMap[selectedBlock]]->GetBits(), + blockSize, blockSize, + (selectedBlock % mapSize) * blockSize + blocksLeft, + (selectedBlock / mapSize) * blockSize + blocksTop + ); + } + // + if ( selectedBlock != nSel ) + selectedBlock = nSel; + else + selectedBlock = SELECTED_BLOCK_NONE; + // + drawBonuses(); + } + } + + } + // + break; + + default: + break; + } + } + // + kos_DefineButton( + 0, 0, + 0, 0, + 0x8000000A, + 0 + ); + // + if ( gameLevel > maxGameLevel ) maxGameLevel = gameLevel; + // + return result; +} + +// +void drawLevelNum() +{ + Word startX; + + // + if ( gameLevel > 9 ) + { + // + startX = LEVEL_LEFT; + // + kos_PutImage( + gameNumbers.GetBits() + ( ( gameLevel / 10 ) * NUM_WIDTH * NUM_HEIGHT ), + NUM_WIDTH, NUM_HEIGHT, + startX, LEVEL_TOP + ); + // + startX += NUM_WIDTH; + } + else + { + // + startX = LEVEL_LEFT + ( (LEVEL_WIDTH - NUM_WIDTH) / 2 ); + } + // + kos_PutImage( + gameNumbers.GetBits() + ( ( gameLevel % 10 ) * NUM_WIDTH * NUM_HEIGHT ), + NUM_WIDTH, NUM_HEIGHT, + startX, LEVEL_TOP + ); +} + +// +void drawScore() +{ + Word startX; + int i, j; + char strNum[8]; + + // + sprintf( strNum, "%U", playerScore ); + // + j = strlen( strNum ); + // + startX = SCORE_LEFT + ( ( SCORE_WIDTH - ( NUM_WIDTH * j ) ) / 2 ); + // + for ( i = 0; i < j; i++ ) + { + // + kos_PutImage( + gameNumbers.GetBits() + ( ( strNum[i] - '0' ) * NUM_WIDTH * NUM_HEIGHT ), + NUM_WIDTH, NUM_HEIGHT, + startX, SCORE_TOP + ); + // + startX += NUM_WIDTH; + } +} + + +// +void DrawGameWindow() +{ + // + kos_WindowRedrawStatus( WRS_BEGIN ); + // + kos_DefineAndDrawWindow( + WNDLEFT, WNDTOP, + gcx + 1, gcy + 21, + 0, 0x0, + 0, WNDHEADCOLOUR, + WNDHEADCOLOUR + ); + // + kos_WriteTextToWindow( + 4, 7, + 0x10, WNDTITLECOLOUR, + gameWndTitle, strlen(gameWndTitle) + ); + // + gameFace.Draw( 1, 21 ); + drawGameMap(); + drawGameMeters(); + drawBonuses(); + // + drawLevelNum(); + drawScore(); + // + if ( mouseButtonDisabled ) + { + // + kos_DrawBar( + ( gcx + 1 - 160 ) / 2, ( gcy + 21 - 32 ) / 2, + 160, 32, + 0x2383B3 + ); + // + kos_WriteTextToWindow( + ( gcx + 1 - sizeof( gameOverText ) * 6 ) / 2, ( gcy + 21 - 9 ) / 2, + 0x0, 0xF7F7F7, + gameOverText, + sizeof( gameOverText ) + ); + } + // + kos_DefineButton( + 444+1, 2+21, + 54, 20, + 0x6000000A, + 0 + ); + // + kos_WindowRedrawStatus( WRS_END ); +} + + +// +void fadeOutBlocks() +{ + int i, j, k, ndx, x, y; + + // + j = toRemoveList.GetCount(); + // + for ( k = 0; k < 4; k++ ) + { + // + __asm{ + push eax + push ebx + mov eax, 18 + mov ebx, 14 + int 0x40 + pop eax + pop ebx + } + // + for ( i = 0; i < j; i++ ) + { + // + ndx = toRemoveList[i].ndx; + y = ndx / mapSize; + x = ndx % mapSize; + // + kos_PutImage( + gameBlocksZ[k].GetBits() + ( (toRemoveList[i].value - 1) * blockSize * blockSize ), + blockSize, blockSize, + (x * blockSize) + blocksLeft, + (y * blockSize) + blocksTop + ); + } + // + kos_Pause( 3 ); + } + //clear + for ( i = 0; i < j; i++ ) + { + // + ndx = toRemoveList[i].ndx; + y = ndx / mapSize; + x = ndx % mapSize; + // + kos_DrawBar( + (x * blockSize) + blocksLeft, + (y * blockSize) + blocksTop, + blockSize, blockSize, 0 + ); + } + // + kos_Pause( 16 ); +} + + +// +void fallDownBlocks() +{ + int i, j, k, ndx, x, y, height, offset; + + // + j = toFallList.GetCount(); + // + for ( k = 1; k <= blockSize; k += 2 ) + { + // + __asm{ + push eax + push ebx + mov eax, 18 + mov ebx, 14 + int 0x40 + pop eax + pop ebx + } + // + for ( i = 0; i < j; i++ ) + { + // + ndx = toFallList[i]; + // + y = ( ( ( ndx / mapSize ) - 1 ) * blockSize ) + k; + if ( y < 0 ) + { + y = 0; + height = k; + offset = blockSize - k; + } + else + { + offset = 0; + height = blockSize; + } + // + x = ( ndx % mapSize ) * blockSize; + // + kos_PutImage( + fishki[gameMap[ndx]]->GetBits() + ( offset * blockSize ), + blockSize, height, + x + blocksLeft, + y + blocksTop + ); + } + // + kos_Pause( 1 ); + } +} diff --git a/programs/games/fara/trunk/gameWnd.h b/programs/games/fara/trunk/gameWnd.h new file mode 100644 index 0000000000..b82f9b0ef0 --- /dev/null +++ b/programs/games/fara/trunk/gameWnd.h @@ -0,0 +1,29 @@ +// gameWnd.h + +extern CKosBitmap gameFace; +extern CKosBitmap gameBlocks; +extern CKosBitmap gameNumbers; +extern CKosBitmap gameBlocksZ[4]; +extern CFishka *fishki[blocksNum]; +extern Dword playerScore; + +#define GM_NONE 0 +#define GM_TOP10 1 +#define GM_ABORT 2 + +#define NUM_WIDTH 12 +#define NUM_HEIGHT 20 + +#define SCORE_LEFT (9+2) +#define SCORE_TOP (57+22) +#define SCORE_WIDTH 72 + +#define LEVEL_LEFT (66+2) +#define LEVEL_TOP (89+22) +#define LEVEL_WIDTH 24 + +// +void DrawGameWindow(); +// +int GameLoop(); + diff --git a/programs/games/fara/trunk/gfxdef.cpp b/programs/games/fara/trunk/gfxdef.cpp new file mode 100644 index 0000000000..16a48f271a --- /dev/null +++ b/programs/games/fara/trunk/gfxdef.cpp @@ -0,0 +1,285 @@ +#include "kosSyst.h" +#include "KosFile.h" +#include "gfxdef.h" +#include "crc32.h" + +extern "C" void __stdcall lzma_decompress( + const void* source, + void* destination, + unsigned dest_length); + +struct export_item +{ + const char* name; + const void* func; +}; + +typedef void* (__stdcall *img_decode_t)(const void* data, unsigned len, void* parameters); +typedef void (__stdcall *img_to_rgb2_t)(const void* image, void* destination); +typedef void (__stdcall *img_destroy_t)(void* image); +typedef void (__stdcall *img_lib_init_t)(void); // really fastcall with 4 args, but called from asm code + +img_lib_init_t img_lib_init = NULL; +img_decode_t img_decode = NULL; +img_to_rgb2_t img_to_rgb2 = NULL; +img_destroy_t img_destroy = NULL; + +export_item* libini_exports = NULL; +static const char libini_name[] = "/sys/lib/libimg.obj"; + +extern "C" int strcmp(const char* str1, const char* str2); +#pragma intrinsic(strcmp) + +void jpeg_decompress( + const void* source, + unsigned source_length, + void* destination, + unsigned dest_length) +{ + if (!libini_exports) + { + __asm + { + mov eax, 68 + mov ebx, 19 + mov ecx, offset libini_name + int 40h + mov [libini_exports], eax + } + if (!libini_exports) + { + rtlDebugOutString("Cannot load libimg.obj"); + kos_ExitApp(); + } + for (export_item* p = libini_exports; p->name; p++) + { + if (!strcmp(p->name,"lib_init")) + img_lib_init = (img_lib_init_t)p->func; + else if (!strcmp(p->name,"img_decode")) + img_decode = (img_decode_t)p->func; + else if (!strcmp(p->name,"img_to_rgb2")) + img_to_rgb2 = (img_to_rgb2_t)p->func; + else if (!strcmp(p->name,"img_destroy")) + img_destroy = (img_destroy_t)p->func; + } + if (!img_lib_init || !img_decode || !img_to_rgb2 || !img_destroy) + { + rtlDebugOutString("Required exports were not found in libimg.obj"); + kos_ExitApp(); + } + __asm + { + mov eax, offset kos_malloc + mov ebx, offset kos_free + mov ecx, offset kos_realloc + call img_lib_init + } + } + void* image = img_decode(source, source_length, NULL); + if (!image) + { + rtlDebugOutString("JPEG error"); + kos_ExitApp(); + } + img_to_rgb2(image, destination); + img_destroy(image); +} + +////// CKosBitmap + +CKosBitmap::CKosBitmap() +{ + this->bmpID = -1; + this->buffer = NULL; + this->sizeX = 0; + this->sizeY = 0; +} + + +CKosBitmap::~CKosBitmap() +{ + if ( this->buffer != NULL ) delete this->buffer; +} + + +// 㧪 ᦠ⮣ 䠩 +bool CKosBitmap::LoadFromArch( SCompBmpHeader *bmpArchDesc, CKosFile *fromFile, int ID ) +{ + Byte *tmpBuff; + + // + if ( this->buffer != NULL ) + { + delete this->buffer; + this->buffer = NULL; + } + // + this->buffer = new RGB[bmpArchDesc->sizeX * bmpArchDesc->sizeY]; + // + tmpBuff = new Byte[bmpArchDesc->compressedSize]; + // + fromFile->Seek( SEEK_SET, bmpArchDesc->physicalOffset ); + if ( fromFile->Read( tmpBuff, bmpArchDesc->compressedSize ) == bmpArchDesc->compressedSize ) + { + // + if ( bmpArchDesc->compressedSize == bmpArchDesc->uncompressedSize+1) + { + // JPEG image + jpeg_decompress( tmpBuff, bmpArchDesc->compressedSize, + this->buffer, bmpArchDesc->sizeX * bmpArchDesc->sizeY * 3); + } + else if ( bmpArchDesc->compressedSize != bmpArchDesc->uncompressedSize ) + { + // LZMA-packed BMP + lzma_decompress( tmpBuff, this->buffer, bmpArchDesc->uncompressedSize); + } + else + { + // + memcpy( (Byte *)(this->buffer), tmpBuff, bmpArchDesc->compressedSize ); + } + // + this->sizeX = bmpArchDesc->sizeX; + this->sizeY = bmpArchDesc->sizeY; + this->bmpID = ID; + } + // + delete tmpBuff; + // + return true; +} + + +// 뢥 ⨭ +void CKosBitmap::Draw( Word x, Word y ) +{ + // + if ( this->buffer != NULL ) + // + kos_PutImage( this->buffer, this->sizeX, this->sizeY, x, y ); +} + + +// 㪠⥫ +RGB * CKosBitmap::GetBits() +{ + return this->buffer; +} + + +// ࠧ ⨭ +void CKosBitmap::GetSize( Word &cx, Word &cy ) +{ + cx = this->sizeX; + cy = this->sizeY; +} + +// ᮧ ⨭ 襩 +void CKosBitmap::Scale(Word size, RGB *mainBits) +{ + buffer = new RGB[(sizeX=blockSize)*(sizeY=blockSize*11)]; + memset((Byte*)buffer,0,3*blockSize*blockSize*11); + RGB* tmpBuf = new RGB[blockSize*size]; + for (int k=0;k<11;k++) + { + int delta = (blockSize - size)/2; + int i,j; + int a; + int d1 = blockSize/size; + int d2 = (blockSize-d1*(size))*256/size; + // ᣫ ਧ⠫ + RGB* ptrBuf = tmpBuf; + for (j=0;jb = srcBits->b + (srcBits[1].b-srcBits[0].b)*a/256; + ptrBuf->g = srcBits->g + (srcBits[1].g-srcBits[0].g)*a/256; + ptrBuf->r = srcBits->r + (srcBits[1].r-srcBits[0].r)*a/256; + ptrBuf++; + srcBits += d1; + a += d2; + if (a >= 256) + { + a -= 256; + srcBits++; + } + } + } + // ᣫ ⨪ + for (j=0;jb = srcBits->b + (srcBits[size].b-srcBits[0].b)*a/256; + ptrBuf->g = srcBits->g + (srcBits[size].g-srcBits[0].g)*a/256; + ptrBuf->r = srcBits->r + (srcBits[size].r-srcBits[0].r)*a/256; + ptrBuf += blockSize; + srcBits += d1*size; + a += d2; + if (a >= 256) + { + a -= 256; + srcBits += size; + } + } + } + } + delete tmpBuf; +} + + +////////////////////// CFishka /////////////////////// + +CFishka::CFishka( CKosBitmap *fromBmp, int yOffset, RGB insColour ) +{ + int i, c; + + // + this->bits = fromBmp->GetBits() + (yOffset * blockSize); + this->transColour = insColour; + // + this->highLighted = new RGB[blockSize * blockSize]; + // + for ( i = 0; i < (blockSize * blockSize); i++ ) + { + // + this->highLighted[i] = this->bits[i]; + // + if ( this->highLighted[i] != this->transColour ) + { + c = ( this->highLighted[i].b * 185 ) / 100; + this->highLighted[i].b = (c > 255) ? 255 : c; + c = ( this->highLighted[i].g * 185 ) / 100; + this->highLighted[i].g = (c > 255) ? 255 : c; + c = ( this->highLighted[i].r * 185 ) / 100; + this->highLighted[i].r = (c > 255) ? 255 : c; + } + } +} + +// +CFishka::~CFishka() +{ + // + delete this->highLighted; +} + + +// +RGB * CFishka::GetBits() +{ + return this->bits; +} + +// +RGB * CFishka::GetHighlightedBits() +{ + return this->highLighted; +} + diff --git a/programs/games/fara/trunk/gfxdef.h b/programs/games/fara/trunk/gfxdef.h new file mode 100644 index 0000000000..06aea424ab --- /dev/null +++ b/programs/games/fara/trunk/gfxdef.h @@ -0,0 +1,101 @@ +// gfxdef.h + +#define MAIN_FACE_NDX 0 +#define GAME_FACE_NDX 1 +#define BUTTONS_NDX 2 +#define NUMBERS_NDX 3 + +#define BONUS_FREE_BLOCK 11 +#define BONUS_DIAG_BLOCK 12 + +#define WNDLEFT 64 +#define WNDTOP 64 +#define WNDHEADCOLOUR 0xD4C233 +#define WNDTITLECOLOUR 0x47151C + +// +#define blockSize 41 +#define blocksNum 15 + +extern int maxGameLevel; +extern int startGameLevel; + +#define START_LEVEL 1 + +//// +//struct CPoint +//{ +// int x, y; +// // +// CPoint() +// { +// this->x = 0; +// this->y = 0; +// }; +// // +// CPoint( int iX, int iY ) +// { +// this->x = iX; +// this->y = iY; +// }; +// // +// CPoint( CPoint &pt ) +// { +// this->x = pt.x; +// this->y = pt.y; +// }; +//}; + + +// +struct SCompBmpHeader +{ + short int sizeX; + short int sizeY; + int compressedSize; + int physicalOffset; + int uncompressedSize; +}; + + +// +class CKosBitmap +{ +protected: + int bmpID; + RGB *buffer; + Word sizeX; + Word sizeY; +public: + CKosBitmap(); + ~CKosBitmap(); + // + bool LoadFromArch( SCompBmpHeader *bmpArchDesc, CKosFile *fromFile, int ID ); + // + void Draw( Word x, Word y ); + // + RGB *GetBits(); + // + void GetSize( Word &cx, Word &cy ); + // + void Scale(Word size, RGB* mainBits); +}; + + +// +class CFishka +{ +protected: + // + RGB *bits; + // + RGB transColour; + // + RGB *highLighted; +public: + CFishka( CKosBitmap *fromBmp, int yOffset, RGB insColour ); + virtual ~CFishka(); + virtual RGB * GetBits(void); + virtual RGB * GetHighlightedBits(void); +}; + diff --git a/programs/games/fara/trunk/gmplace.bmp b/programs/games/fara/trunk/gmplace.bmp new file mode 100644 index 0000000000..be7ea65b43 Binary files /dev/null and b/programs/games/fara/trunk/gmplace.bmp differ diff --git a/programs/games/fara/trunk/gmplace.jpg b/programs/games/fara/trunk/gmplace.jpg new file mode 100644 index 0000000000..b57b3f4c2d Binary files /dev/null and b/programs/games/fara/trunk/gmplace.jpg differ diff --git a/programs/games/fara/trunk/grobfar.txt b/programs/games/fara/trunk/grobfar.txt new file mode 100644 index 0000000000..7dc44c8500 --- /dev/null +++ b/programs/games/fara/trunk/grobfar.txt @@ -0,0 +1,31 @@ + + + + , , (88), . + + , . , "" . . + + . L+(L+1)^(N-3), 20*L*N, N - , L - . + + , , ( ). , . + +1- - 500 +2- - 450 +3- - 400 +4- - 350 +5- - 300 +6- - 50*(L+1) + + + 6 . , 10 (.. 5- 10 , ). + + 2- 4- , "" - ( ), " " , . + + 3- 5- , " " , . + + 4- 6- , " " , , , 3 ( ) . + + 1 (1 , 1 1 ). + + , . + diff --git a/programs/games/fara/trunk/kosSyst.cpp b/programs/games/fara/trunk/kosSyst.cpp new file mode 100644 index 0000000000..3f388ddb18 --- /dev/null +++ b/programs/games/fara/trunk/kosSyst.cpp @@ -0,0 +1,870 @@ +#include "kosSyst.h" +#include + +#define atexitBufferSize 32 + + +char pureCallMessage[] = "PURE function call!"; + +char *kosExePath = NULL; + +// +void (__cdecl *atExitList[atexitBufferSize])(); +int atExitFnNum = 0; +// +int __cdecl atexit( void (__cdecl *func )( void )) +{ + // + if ( atExitFnNum < atexitBufferSize ) + { + // + atExitList[atExitFnNum++] = func; + return 0; + } + else + { + return 1; + } +} + + +// +Dword RandomSeed = 1; +// +void rtlSrand( Dword seed ) +{ + RandomSeed = seed; +} +// +Dword rtlRand( void ) +{ + // 0x80000776 + + Dword dwi, i; + + for ( i = 0; i < 32; i++ ) + { + + dwi = RandomSeed & 0x80000776; + + __asm{ + mov eax, dwi + mov edx, eax + bswap eax + xor eax, edx + xor al, ah + setpo al + movzx eax, al + mov dwi, eax + } + + RandomSeed = ( RandomSeed << 1 ) | ( dwi & 1 ); + } + + return RandomSeed; +} + +// +void * __cdecl memcpy( void *dst, const void *src, size_t bytesCount ) +{ + __asm{ + mov edi, dst + mov eax, dst + mov esi, src + mov ecx, bytesCount + rep movsb + } +} + +// +void memset( Byte *dst, Byte filler, Dword count ) +{ + // + __asm{ + mov edi, dst + mov al, filler + mov ecx, count + rep stosb + } +} + +// +Dword rtlInterlockedExchange( Dword *target, Dword value ) +{ +// Dword result; + + // + __asm{ + mov eax, value + mov ebx, target + xchg eax, [ebx] +// mov result, eax + } + // +// return result; +} + + +////////////////////////////////////////////////////////////////////// +// +// +// + +char * __cdecl strcpy( char *target, const char *source ) +{ + char *result = target; + + while( target[0] = source[0] ) + { + target++; + source++; + } + + return result; +} + + +////////////////////////////////////////////////////////////////////// +// +// +// + +char * __cdecl strrchr( const char * string, int c ) +{ + char *cPtr; + + // + for ( cPtr = (char *)string + strlen( string ); cPtr >= string; cPtr-- ) + { + // + if ( *cPtr == c ) return cPtr; + } + // + return NULL; +} + + +////////////////////////////////////////////////////////////////////// +// +// +// + +int __cdecl strlen( const char *line ) +{ + int i; + + for( i=0; line[i] != 0; i++ ); + return i; +} + + + +////////////////////////////////////////////////////////////////////// +// +// +// + +unsigned int num2hex( unsigned int num ) +{ + if( num < 10 ) + return num + '0'; + return num - 10 + 'A'; +} + + +////////////////////////////////////////////////////////////////////// +// +// +// + +Dword dectab[] = { 1000000000, 100000000, 10000000, 1000000, 100000, + 10000, 1000, 100, 10, 0 }; + +// +void sprintf( char *Str, char* Format, ... ) +{ + int i, fmtlinesize, j, k, flag; + Dword head, tail; + char c; + va_list arglist; + // + va_start(arglist, Format); + + // + fmtlinesize = strlen( Format ); + // + if( fmtlinesize == 0 ) return; + + // + for( i = 0, j = 0; i < fmtlinesize; i++ ) + { + // + c = Format[i]; + // + if( c != '%' ) + { + Str[j++] = c; + continue; + } + // + i++; + // + if( i >= fmtlinesize ) break; + + // + flag = 0; + // + c = Format[i]; + // + switch( c ) + { + // + case '%': + Str[j++] = c; + break; + // + case 'S': + Byte* str; + str = va_arg(arglist, Byte*); + for( k = 0; ( c = str[k] ) != 0; k++ ) + { + Str[j++] = c; + } + break; + // + case 'B': + k = va_arg(arglist, int) & 0xFF; + Str[j++] = num2hex( ( k >> 4 ) & 0xF ); + Str[j++] = num2hex( k & 0xF ); + break; + // + case 'C': + Str[j++] = va_arg(arglist, int) & 0xFF; + break; + // + case 'X': + Dword val; + val = va_arg(arglist, Dword); + for( k = 7; k >= 0; k-- ) + { + // + c = num2hex ( ( val >> (k * 4) ) & 0xF ); + // + if( c == '0' ) + { + if( flag ) Str[j++] = c; + } + else + { + flag++; + Str[j++] = c; + } + } + // + if( flag == 0 ) Str[j++] = '0'; + break; + // + case 'U': + head = va_arg(arglist, Dword); + tail = 0; + for( k = 0; dectab[k] != 0; k++ ) + { + tail = head % dectab[k]; + head /= dectab[k]; + c = head + '0'; + if( c == '0' ) + { + if( flag ) Str[j++] = c; + } + else + { + flag++; + Str[j++] = c; + } + // + head = tail; + } + // + c = head + '0'; + Str[j++] = c; + break; + // 64- + case 'Q': + unsigned int low_dword, high_dword; + low_dword = va_arg(arglist, unsigned int); + high_dword = va_arg(arglist, unsigned int); + for( k = 7; k >= 0; k-- ) + { + // + c = num2hex ( ( ( high_dword + 1) >> (k * 4) ) & 0xF ); + // + if( c == '0' ) + { + if( flag ) Str[j++] = c; + } + else + { + flag++; + Str[j++] = c; + } + } + // + for( k=7; k >= 0; k-- ) + { + // + c = num2hex ( ( low_dword >> (k * 4) ) & 0xF ); + // + if( c == '0' ) + { + if( flag ) Str[j++] = c; + } + else + { + flag++; + Str[j++] = c; + } + } + // + if( flag == 0 ) Str[j++] = '0'; + // + break; + // + default: + break; + } + } + // + Str[j] = 0; +} + + +// -1 +void kos_ExitApp() +{ + int i; + + // + for ( i = atExitFnNum - 1; i >= 0; i-- ) + { + // + atExitList[i](); + } + // + __asm{ + mov eax, -1 + int 0x40 + } +} + + +// 0 +void kos_DefineAndDrawWindow( + Word x, Word y, + Word sizeX, Word sizeY, + Byte mainAreaType, + Dword mainAreaColour, + Byte headerType, + Dword headerColour, + Dword borderColour + ) +{ + Dword arg1, arg2, arg3, arg4; + + // + arg1 = ( x << 16 ) + sizeX; + arg2 = ( y << 16 ) + sizeY; + arg3 = ( mainAreaType << 24 ) | mainAreaColour; + arg4 = ( headerType << 24 ) | headerColour; + // + __asm{ + mov eax, 0 + mov ebx, arg1 + mov ecx, arg2 + mov edx, arg3 + mov esi, arg4 + mov edi, borderColour + int 0x40 + } +} + + +// 1 +void kos_PutPixel( Dword x, Dword y, Dword colour ) +{ + // + __asm{ + mov eax, 1 + mov ebx, x + mov ecx, y + mov edx, colour + int 0x40 + } +} + + +// 2 +bool kos_GetKey( Byte &keyCode ) +{ + Dword result; + + // + __asm{ + mov eax, 2 + int 0x40 + mov result, eax + } + // + keyCode = result >> 8; + // + return ( result & 0xFF ) == 0; +} + + +// 3 +Dword kos_GetSystemClock() +{ +// Dword result; + + // + __asm{ + mov eax, 3 + int 0x40 +// mov result, eax + } + // +// return result; +} + + +// 4 +void kos_WriteTextToWindow( + Word x, + Word y, + Byte fontType, + Dword textColour, + char *textPtr, + Dword textLen + ) +{ + Dword arg1, arg2; + + // + arg1 = ( x << 16 ) | y; + arg2 = ( fontType << 24 ) | textColour; + // + __asm{ + mov eax, 4 + mov ebx, arg1 + mov ecx, arg2 + mov edx, textPtr + mov esi, textLen + int 0x40 + } +} + + +// 5 , +void kos_Pause( Dword value ) +{ + // + __asm{ + mov eax, 5 + mov ebx, value + int 0x40 + } +} + + +// 7 +void kos_PutImage( RGB * imagePtr, Word sizeX, Word sizeY, Word x, Word y ) +{ + Dword arg1, arg2; + + // + arg1 = ( sizeX << 16 ) | sizeY; + arg2 = ( x << 16 ) | y; + // + __asm{ + mov eax, 7 + mov ebx, imagePtr + mov ecx, arg1 + mov edx, arg2 + int 0x40 + } +} + + + +// 8 +void kos_DefineButton( Word x, Word y, Word sizeX, Word sizeY, Dword buttonID, Dword colour ) +{ + Dword arg1, arg2; + + // + arg1 = ( x << 16 ) | sizeX; + arg2 = ( y << 16 ) | sizeY; + // + __asm{ + mov eax, 8 + mov ebx, arg1 + mov ecx, arg2 + mov edx, buttonID + mov esi, colour + int 0x40 + } +} + + +// 9 - +Dword kos_ProcessInfo( sProcessInfo *targetPtr, Dword processID ) +{ +// Dword result; + + // + __asm{ + mov eax, 9 + mov ebx, targetPtr + mov ecx, processID + int 0x40 +// mov result, eax + } + // +// return result; +} + + +// 10 +Dword kos_WaitForEvent() +{ +// Dword result; + + __asm{ + mov eax, 10 + int 0x40 +// mov result, eax + } + +// return result; +} + + +// 11 +Dword kos_CheckForEvent() +{ +// Dword result; + + __asm{ + mov eax, 11 + int 0x40 +// mov result, eax + } + +// return result; +} + + +// 12 +void kos_WindowRedrawStatus( Dword status ) +{ + __asm{ + mov eax, 12 + mov ebx, status + int 0x40 + } +} + + +// 13 +void kos_DrawBar( Word x, Word y, Word sizeX, Word sizeY, Dword colour ) +{ + Dword arg1, arg2; + + // + arg1 = ( x << 16 ) | sizeX; + arg2 = ( y << 16 ) | sizeY; + // + __asm{ + mov eax, 13 + mov ebx, arg1 + mov ecx, arg2 + mov edx, colour + int 0x40 + } +} + + +// 17 +bool kos_GetButtonID( Dword &buttonID ) +{ + Dword result; + + // + __asm{ + mov eax, 17 + int 0x40 + mov result, eax + } + // + buttonID = result >> 8; + // + return (result & 0xFF) == 0; +} + + +// 23 +Dword kos_WaitForEvent( Dword timeOut ) +{ +// Dword result; + + __asm{ + mov eax, 23 + mov ebx, timeOut + int 0x40 +// mov result, eax + } + +// return result; +} + + +// "" 37 +void kos_GetMouseState( Dword & buttons, int & cursorX, int & cursorY ) +{ + Dword mB; + Word curX; + Word curY; + sProcessInfo sPI; + + // + __asm{ + mov eax, 37 + mov ebx, 0 + int 0x40 + mov curY, ax + shr eax, 16 + mov curX, ax + mov eax, 37 + mov ebx, 2 + int 0x40 + mov mB, eax + } + // + kos_ProcessInfo( &sPI ); + // + buttons = mB; + cursorX = curX - sPI.processInfo.x_start; + cursorY = curY - sPI.processInfo.y_start; +} + + +// 40 +void kos_SetMaskForEvents( Dword mask ) +{ + // + __asm{ + mov eax, 40 + mov ebx, mask + int 0x40 + } +} + + +// 47 +void kos_DisplayNumberToWindow( + Dword value, + Dword digitsNum, + Word x, + Word y, + Dword colour, + eNumberBase nBase, + bool valueIsPointer + ) +{ + Dword arg1, arg2; + + // + arg1 = ( valueIsPointer ? 1 : 0 ) | + ( ((Byte)nBase) << 8 ) | + ( ( digitsNum & 0x1F ) << 16 ); + arg2 = ( x << 16 ) | y; + // + __asm{ + mov eax, 47 + mov ebx, arg1 + mov ecx, value + mov edx, arg2 + mov esi, colour + int 0x40 + } +} + + +// 70 +Dword kos_FileSystemAccess( kosFileInfo *fileInfo ) +{ +// Dword result; + + // + __asm{ + mov eax, 70 + mov ebx, fileInfo + int 0x40 +// mov result, eax + } + // +// return result; +} + + +// 63 +void kos_DebugOutChar( char ccc ) +{ + // + __asm{ + mov eax, 63 + mov ebx, 1 + mov cl, ccc + int 0x40 + } +} + + +// 66 +void kos_SetKeyboardDataMode( Dword mode ) +{ + // + __asm{ + mov eax, 66 + mov ebx, 1 + mov ecx, mode + int 0x40 + } +} + + +// +void rtlDebugOutString( char *str ) +{ + // + for ( ; str[0] != 0; str++ ) + { + kos_DebugOutChar( str[0] ); + } + // + kos_DebugOutChar( 13 ); + kos_DebugOutChar( 10 ); +} + + +// -- +__declspec(naked) void* __stdcall kos_malloc(Dword size) +{ + __asm + { + push ebx + push ecx + mov ecx, [esp+12] + mov eax, 68 + mov ebx, 12 + int 0x40 + pop ecx + pop ebx + ret 4 + } +} +__declspec(naked) void __stdcall kos_free(void* mptr) +{ + __asm + { + push ebx + push ecx + mov ecx, [esp+12] + mov eax, 68 + mov ebx, 13 + int 0x40 + pop ecx + pop ebx + ret 4 + } +} +__declspec(naked) void* __stdcall kos_realloc(void* mptr, Dword size) +{ + __asm + { + push ebx + push ecx + push edx + mov eax, 68 + mov ebx, 20 + mov ecx, [esp+20] + mov edx, [esp+16] + int 0x40 + pop edx + pop ecx + pop ebx + ret 8 + } +} + +// 67 , == -1 +void kos_ChangeWindow( Dword x, Dword y, Dword sizeX, Dword sizeY ) +{ + // + __asm{ + mov eax, 67 + mov ebx, x + mov ecx, y + mov edx, sizeX + mov esi, sizeY + int 0x40 + } +} + + + +// +int __cdecl _purecall() +{ + rtlDebugOutString( pureCallMessage ); + kos_ExitApp(); + return 0; +} + + +// +// +#pragma section(".CRT$XCA",long,read,write) +#pragma section(".CRT$XCZ",long,read,write) +typedef void (__cdecl *_PVFV)(void); +__declspec(allocate(".CRT$XCA")) _PVFV __xc_a[1] = { NULL }; +__declspec(allocate(".CRT$XCZ")) _PVFV __xc_z[1] = { NULL }; +// +#pragma comment(linker, "/merge:.CRT=.rdata") +// +void crtStartUp() +{ + // + __asm + { + mov eax, 68 + mov ebx, 11 + int 40h + } + // , NULL' + for ( _PVFV *pbegin = __xc_a; pbegin < __xc_z; pbegin++ ) + { + // + if ( *pbegin != NULL ) + (**pbegin)(); + } + // + rtlSrand( kos_GetSystemClock() ); + // + kosExePath = *((char **)0x20); + // + kos_Main(); + // + kos_ExitApp(); +} + + diff --git a/programs/games/fara/trunk/kosSyst.h b/programs/games/fara/trunk/kosSyst.h new file mode 100644 index 0000000000..7c8323dcdb --- /dev/null +++ b/programs/games/fara/trunk/kosSyst.h @@ -0,0 +1,197 @@ +typedef unsigned __int32 Dword; +typedef unsigned __int16 Word; +typedef unsigned __int8 Byte; +typedef unsigned __int32 size_t; + +#define NULL 0 + +#define MAX_PATH 256 + +#define FO_READ 0 +#define FO_WRITE 2 + +#define EM_WINDOW_REDRAW 1 +#define EM_KEY_PRESS 2 +#define EM_BUTTON_CLICK 4 +#define EM_APP_CLOSE 8 +#define EM_DRAW_BACKGROUND 16 +#define EM_MOUSE_EVENT 32 +#define EM_IPC 64 +#define EM_NETWORK 256 + +#define KM_CHARS 0 +#define KM_SCANS 1 + +#define WRS_BEGIN 1 +#define WRS_END 2 + +#define PROCESS_ID_SELF -1 + +#define abs(a) (a<0?0-a:a) + + +struct kosFileInfo +{ + Dword rwMode; + Dword OffsetLow; + Dword OffsetHigh; + Dword dataCount; + Byte *bufferPtr; + char fileURL[MAX_PATH]; +}; + + +struct RGB +{ + Byte b; + Byte g; + Byte r; + // + RGB() {}; + // + RGB( Dword value ) + { + r = value >> 16; + g = value >> 8; + b = value; + }; + // + bool operator != ( RGB &another ) + { + return this->b != another.b || this->g != another.g || this->r != another.r; + }; + // + bool operator == ( RGB &another ) + { + return this->b == another.b && this->g == another.g && this->r == another.r; + }; +}; + + +union sProcessInfo +{ + Byte rawData[1024]; + struct + { + Dword cpu_usage; + Word window_stack_position; + Word window_stack_value; + Word reserved1; + char process_name[12]; + Dword memory_start; + Dword used_memory; + Dword PID; + Dword x_start; + Dword y_start; + Dword x_size; + Dword y_size; + Word slot_state; + } processInfo; +}; + +// +extern char *kosExePath; + +// +void crtStartUp(); +// +int __cdecl _purecall(); +// +int __cdecl atexit( void (__cdecl *func )( void )); +// +void rtlSrand( Dword seed ); +Dword rtlRand( void ); +// +char * __cdecl strcpy( char *target, const char *source ); +int __cdecl strlen( const char *line ); +char * __cdecl strrchr( const char * string, int c ); +// +void * __cdecl memcpy( void *dst, const void *src, size_t bytesCount ); +// +void memset( Byte *dst, Byte filler, Dword count ); +// +void sprintf( char *Str, char* Format, ... ); +// +Dword rtlInterlockedExchange( Dword *target, Dword value ); +// -1 +void kos_ExitApp(); +// 0 +void kos_DefineAndDrawWindow( + Word x, Word y, + Word sizeX, Word sizeY, + Byte mainAreaType, Dword mainAreaColour, + Byte headerType, Dword headerColour, + Dword borderColour + ); +// 1 +void kos_PutPixel( Dword x, Dword y, Dword colour ); +// 2 +bool kos_GetKey( Byte &keyCode ); +// 3 +Dword kos_GetSystemClock(); +// 4 +void kos_WriteTextToWindow( + Word x, Word y, + Byte fontType, + Dword textColour, + char *textPtr, + Dword textLen + ); +// 7 +void kos_PutImage( RGB * imagePtr, Word sizeX, Word sizeY, Word x, Word y ); +// 8 +void kos_DefineButton( Word x, Word y, Word sizeX, Word sizeY, Dword buttonID, Dword colour ); +// 5 , +void kos_Pause( Dword value ); +// 9 - +Dword kos_ProcessInfo( sProcessInfo *targetPtr, Dword processID = PROCESS_ID_SELF ); +// 10 +Dword kos_WaitForEvent(); +// 11 +Dword kos_CheckForEvent(); +// 12 +void kos_WindowRedrawStatus( Dword status ); +// 13 +void kos_DrawBar( Word x, Word y, Word sizeX, Word sizeY, Dword colour ); +// 17 +bool kos_GetButtonID( Dword &buttonID ); +// 23 +Dword kos_WaitForEvent( Dword timeOut ); +// +enum eNumberBase +{ + nbDecimal = 0, + nbHex, + nbBin +}; +// "" 37 +void kos_GetMouseState( Dword & buttons, int & cursorX, int & cursorY ); +// 40 +void kos_SetMaskForEvents( Dword mask ); +// 47 +void kos_DisplayNumberToWindow( + Dword value, + Dword digitsNum, + Word x, + Word y, + Dword colour, + eNumberBase nBase = nbDecimal, + bool valueIsPointer = false + ); +// 58 +Dword kos_FileSystemAccess( kosFileInfo *fileInfo ); +// 63 +void kos_DebugOutChar( char ccc ); +// +void rtlDebugOutString( char *str ); +// 64 , == -1 +void kos_ChangeWindow( Dword x, Dword y, Dword sizeX, Dword sizeY ); +// 68.12/13/20 +void* __stdcall kos_malloc(Dword size); +void __stdcall kos_free(void* mptr); +void* __stdcall kos_realloc(void* mptr, Dword size); +// 66 +void kos_SetKeyboardDataMode( Dword mode ); + +// +void kos_Main(); diff --git a/programs/games/fara/trunk/lang.h b/programs/games/fara/trunk/lang.h new file mode 100644 index 0000000000..ef15793f1a --- /dev/null +++ b/programs/games/fara/trunk/lang.h @@ -0,0 +1,3 @@ +#define RUS 1 +#define ENG 2 +#define LANG RUS \ No newline at end of file diff --git a/programs/games/fara/trunk/lzma_unpack.asm b/programs/games/fara/trunk/lzma_unpack.asm new file mode 100644 index 0000000000..e0ec3e102e --- /dev/null +++ b/programs/games/fara/trunk/lzma_unpack.asm @@ -0,0 +1,393 @@ +; Exports only one function: +; void __stdcall lzma_decompress( +; const void* source, +; void* destination, +; unsigned dest_length); + + format COFF + +section '.text' code + +pb equ 2 ; pos state bits +lp equ 0 ; literal pos state bits +lc equ 3 ; literal context bits +posStateMask equ ((1 shl pb)-1) +literalPosMask equ ((1 shl lp)-1) + +kNumPosBitsMax = 4 +kNumPosStatesMax = (1 shl kNumPosBitsMax) + +kLenNumLowBits = 3 +kLenNumLowSymbols = (1 shl kLenNumLowBits) +kLenNumMidBits = 3 +kLenNumMidSymbols = (1 shl kLenNumMidBits) +kLenNumHighBits = 8 +kLenNumHighSymbols = (1 shl kLenNumHighBits) + +LenChoice = 0 +LenChoice2 = 1 +LenLow = 2 +LenMid = (LenLow + (kNumPosStatesMax shl kLenNumLowBits)) +LenHigh = (LenMid + (kNumPosStatesMax shl kLenNumMidBits)) +kNumLenProbs = (LenHigh + kLenNumHighSymbols) + +kNumStates = 12 +kNumLitStates = 7 +kStartPosModelIndex = 4 +kEndPosModelIndex = 14 +kNumFullDistances = (1 shl (kEndPosModelIndex/2)) +kNumPosSlotBits = 6 +kNumLenToPosStates = 4 +kNumAlignBits = 4 +kAlignTableSize = (1 shl kNumAlignBits) +kMatchMinLen = 2 + +IsMatch = 0 +IsRep = 0xC0 ; (IsMatch + (kNumStates shl kNumPosBitsMax)) +IsRepG0 = 0xCC ; (IsRep + kNumStates) +IsRepG1 = 0xD8 ; (IsRepG0 + kNumStates) +IsRepG2 = 0xE4 ; (IsRepG1 + kNumStates) +IsRep0Long = 0xF0 ; (IsRepG2 + kNumStates) +PosSlot = 0x1B0 ; (IsRep0Long + (kNumStates shl kNumPosBitsMax)) +SpecPos = 0x2B0 ; (PosSlot + (kNumLenToPosStates shl kNumPosSlotBits)) +Align_ = 0x322 ; (SpecPos + kNumFullDistances - kEndPosModelIndex) +Lencoder = 0x332 ; (Align_ + kAlignTableSize) +RepLencoder = 0x534 ; (Lencoder + kNumLenProbs) +Literal = 0x736 ; (RepLencoder + kNumLenProbs) + +LZMA_BASE_SIZE = 1846 ; must be ==Literal +LZMA_LIT_SIZE = 768 + +kNumTopBits = 24 +kTopValue = (1 shl kNumTopBits) + +kNumBitModelTotalBits = 11 +kBitModelTotal = (1 shl kNumBitModelTotalBits) +kNumMoveBits = 5 + +RangeDecoderBitDecode: +; in: eax->prob +; out: CF=bit + push edx + mov edx, [range] + shr edx, kNumBitModelTotalBits + imul edx, [eax] + cmp [code_], edx + jae .ae + mov [range], edx + mov edx, kBitModelTotal + sub edx, [eax] + shr edx, kNumMoveBits + add [eax], edx +.n: + pushfd + call update_decoder + popfd + pop edx + ret +.ae: + sub [range], edx + sub [code_], edx + mov edx, [eax] + shr edx, kNumMoveBits + sub [eax], edx + stc + jmp .n + +update_decoder: + cmp byte [range+3], 0 ;cmp dword [range], kTopValue + jnz @f ;jae @f + shl dword [range], 8 + shl dword [code_], 8 + push eax + mov eax, [inptr] + mov al, [eax] + inc dword [inptr] + mov byte [code_], al + pop eax +@@: ret + +LzmaLenDecode: +; in: eax->prob, edx=posState +; out: ecx=len + +; LenChoice==0 +; add eax, LenChoice*4 + call RangeDecoderBitDecode + jnc .0 + add eax, (LenChoice2-LenChoice)*4 + call RangeDecoderBitDecode + jc @f + mov cl, kLenNumMidBits + shl edx, cl + lea eax, [eax + (LenMid-LenChoice2)*4 + edx*4] + call RangeDecoderBitTreeDecode + add ecx, kLenNumLowSymbols + ret +@@: + add eax, (LenHigh-LenChoice2)*4 + mov cl, kLenNumHighBits + call RangeDecoderBitTreeDecode + add ecx, kLenNumLowSymbols + kLenNumMidSymbols + ret +.0: + mov cl, kLenNumLowBits + shl edx, cl + lea eax, [eax + LenLow*4 + edx*4] +RangeDecoderBitTreeDecode: +; in: eax->probs,ecx=numLevels +; out: ecx=length; destroys edx + push edi + xor edx, edx + inc edx + mov edi, edx + xchg eax, edi +@@: + push eax + lea eax, [edi+edx*4] + call RangeDecoderBitDecode + pop eax + adc dl, dl + add al, al + loop @b + sub dl, al + pop edi + mov ecx, edx + ret + +; void __stdcall lzma_decompress( +; const void* source, +; void* destination, +; unsigned dest_length); +lzma_decompress equ _lzma_decompress@12 +public lzma_decompress +lzma_decompress: + push esi edi ebx ebp + mov esi, [esp+4*4+4] ; source + xor ebp, ebp + mov edi, code_ + inc esi + lodsd + bswap eax + stosd + xor eax, eax + dec eax + stosd + stosd + stosd + stosd + xchg eax, esi + stosd + mov ecx, Literal + (LZMA_LIT_SIZE shl (lc+lp)) + mov eax, kBitModelTotal/2 + mov edi, p + rep stosd + mov edi, [esp+4*4+8] ; destination + mov ebx, edi + add ebx, [esp+4*4+12] ; dest_length +.main_loop: + cmp edi, ebx + jae .main_loop_done + mov edx, edi + and edx, posStateMask + push eax ; al = previous byte + mov eax, ebp + shl eax, kNumPosBitsMax+2 + lea eax, [p + IsMatch*4 + eax + edx*4] + call RangeDecoderBitDecode + pop eax + jc .1 + movzx eax, al +if literalPosMask + mov ah, dl + and ah, literalPosMask +end if + shr eax, 8-lc + imul eax, LZMA_LIT_SIZE*4 + add eax, p+Literal*4 + mov cl, 1 + cmp ebp, kNumLitStates + jb .literal + mov dl, [edi + esi] +.lx0: + add dl, dl + setc ch + push eax + lea eax, [eax+ecx*4+0x100*4] + call RangeDecoderBitDecode + pop eax + adc cl, cl + jc .lx1 + xor ch, cl + test ch, 1 + mov ch, 0 + jz .lx0 +.literal: +@@: + push eax + lea eax, [eax+ecx*4] + call RangeDecoderBitDecode + pop eax + adc cl, cl + jnc @b +.lx1: + mov eax, ebp + cmp al, 4 + jb @f + cmp al, 10 + mov al, 3 + jb @f + mov al, 6 +@@: sub ebp, eax + xchg eax, ecx +.stosb_main_loop: + stosb + jmp .main_loop +.1: + lea eax, [p + IsRep*4 + ebp*4] + call RangeDecoderBitDecode + jnc .10 + add eax, (IsRepG0 - IsRep)*4 ;lea eax, [p + IsRepG0*4 + ebp*4] + call RangeDecoderBitDecode + jc .111 + mov eax, ebp + shl eax, kNumPosBitsMax+2 + lea eax, [p + IsRep0Long*4 + eax + edx*4] + call RangeDecoderBitDecode + jc .1101 + cmp ebp, 7 + sbb ebp, ebp + lea ebp, [ebp+ebp+11] + mov al, [edi + esi] + jmp .stosb_main_loop +.111: + add eax, (IsRepG1 - IsRepG0) * 4 ;lea eax, [p + IsRepG1*4 + ebp*4] + call RangeDecoderBitDecode + xchg esi, [rep1] + jnc @f + add eax, (IsRepG2 - IsRepG1) * 4 ;lea eax, [p + IsRepG2*4 + ebp*4] + call RangeDecoderBitDecode + xchg esi, [rep2] + jnc @f + xchg esi, [rep3] +@@: +.1101: + mov eax, p + RepLencoder*4 + call LzmaLenDecode + push 8 + jmp .rmu +.10: + xchg esi, [rep1] + xchg esi, [rep2] + mov [rep3], esi + mov eax, p + Lencoder*4 + call LzmaLenDecode + push kNumLenToPosStates-1 + pop eax + cmp eax, ecx + jb @f + mov eax, ecx +@@: + push ecx + push kNumPosSlotBits + pop ecx + shl eax, cl + shl eax, 2 + add eax, p+PosSlot*4 + call RangeDecoderBitTreeDecode + mov esi, ecx + cmp ecx, kStartPosModelIndex + jb .l6 + push ecx + xor eax, eax + inc eax + shr ecx, 1 + adc al, al + dec ecx + shl eax, cl + mov esi, eax + pop edx + cmp edx, kEndPosModelIndex + jae .l5 + sub eax, edx + shl eax, 2 + add eax, p + (SpecPos - 1)*4 + jmp .l59 +.l5: + sub ecx, kNumAlignBits +; call RangeDecoderDecodeDirectBits +;RangeDecoderDecodeDirectBits: + xor eax, eax +.l: + shr dword [range], 1 + add eax, eax + mov edx, [code_] + sub edx, [range] + jb @f + mov [code_], edx + inc eax +@@: + call update_decoder + loop .l +; ret + mov cl, kNumAlignBits + shl eax, cl + add esi, eax + mov eax, p+Align_*4 +.l59: +; call RangeDecoderReverseBitTreeDecode_addesi +;_RangeDecoderReverseBitTreeDecode_addesi: +; in: eax->probs,ecx=numLevels +; out: esi+=length; destroys edx + push edi ecx + xor edx, edx + inc edx + xor edi, edi +@@: + push eax + lea eax, [eax+edx*4] + call RangeDecoderBitDecode + lahf + adc edx, edx + sahf + rcr edi, 1 + pop eax + loop @b + pop ecx + rol edi, cl + add esi, edi + pop edi +; ret +.l6: + pop ecx + not esi + push 7 +.rmu: + cmp ebp, 7 + pop ebp + jb @f + inc ebp + inc ebp + inc ebp +@@: +.repmovsb: + inc ecx + push esi + add esi, edi + rep movsb + lodsb + pop esi + jmp .stosb_main_loop +.main_loop_done: + pop ebp ebx edi esi + ret 12 + +section '.bss' data +p rd LZMA_BASE_SIZE + (LZMA_LIT_SIZE shl (lc+lp)) +code_ dd ? +range dd ? +rep1 dd ? +rep2 dd ? +rep3 dd ? +inptr dd ? +previousByte db ? diff --git a/programs/games/fara/trunk/lzma_unpack.obj b/programs/games/fara/trunk/lzma_unpack.obj new file mode 100644 index 0000000000..ef8c1f1626 Binary files /dev/null and b/programs/games/fara/trunk/lzma_unpack.obj differ diff --git a/programs/games/fara/trunk/main.cpp b/programs/games/fara/trunk/main.cpp new file mode 100644 index 0000000000..c50b3dad36 --- /dev/null +++ b/programs/games/fara/trunk/main.cpp @@ -0,0 +1,80 @@ +#include "kosSyst.h" +#include "kosFile.h" +#include "gfxdef.h" +#include "mainWnd.h" +#include "gameWnd.h" +#include "top10wnd.h" + + + + +void kos_Main() +{ + int hdrNum, i; + SCompBmpHeader *hdrList; + char *cPtr; + + // + cPtr = strrchr( kosExePath, '/' ); + // ;) +/* if ( cPtr == NULL ) + { + // + rtlDebugOutString( "Invalid path to executable." ); + // + return; + }*/ + // + cPtr[1] = 0; + // + strcpy( top10FilePath, kosExePath ); + // + strcpy( top10FilePath + ((cPtr - kosExePath) + 1), "fara.t10" ); + // + PrepareTop10(); + // + strcpy( cPtr + 1, "fara.gfx" ); + // + CKosFile gfxRes( kosExePath ); + + // + if ( gfxRes.Read( (Byte *)&hdrNum, sizeof(hdrNum) ) != sizeof(hdrNum) ) return; + // + hdrList = new SCompBmpHeader[hdrNum]; + // + gfxRes.Read( (Byte *)hdrList, sizeof(SCompBmpHeader) * hdrNum ); + // + mainWndFace.LoadFromArch( &(hdrList[MAIN_FACE_NDX]), &gfxRes, MAIN_FACE_NDX ); + gameFace.LoadFromArch( &(hdrList[GAME_FACE_NDX]), &gfxRes, GAME_FACE_NDX ); + gameBlocks.LoadFromArch( &(hdrList[BUTTONS_NDX]), &gfxRes, BUTTONS_NDX ); + gameNumbers.LoadFromArch( &(hdrList[NUMBERS_NDX]), &gfxRes, NUMBERS_NDX ); + // + for ( i = 0; i < 4; i++ ) + gameBlocksZ[i].Scale(32-i*8,gameBlocks.GetBits()); + // + delete hdrList; + // + for ( i = 0; i < blocksNum; i++ ) + { + // + fishki[i] = new CFishka( &gameBlocks, i * blockSize, RGB(0x0) ); + } + // + maxGameLevel = START_LEVEL; + // + kos_SetMaskForEvents( 0x27 ); + // + while ( MainWndLoop() == MW_START_GAME ) + { + GameLoop(); + Top10Loop(); + } + // + for ( i = 0; i < blocksNum; i++ ) + { + delete fishki[i]; + } + // + delete hdrList; +} + diff --git a/programs/games/fara/trunk/mainWnd.cpp b/programs/games/fara/trunk/mainWnd.cpp new file mode 100644 index 0000000000..3999cad071 --- /dev/null +++ b/programs/games/fara/trunk/mainWnd.cpp @@ -0,0 +1,211 @@ +#include "kosSyst.h" +#include "KosFile.h" +#include "gfxdef.h" +#include "mainWnd.h" +#include "lang.h" + + +// +RGB bmPMButton[] = { + 0xCCCCCC, 0xCCCCCC, 0x000000, 0x000000, 0xCCCCCC, 0xCCCCCC, + 0xCCCCCC, 0xCCCCCC, 0x000000, 0x000000, 0xCCCCCC, 0xCCCCCC, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0xCCCCCC, 0xCCCCCC, 0x000000, 0x000000, 0xCCCCCC, 0xCCCCCC, + 0xCCCCCC, 0xCCCCCC, 0x000000, 0x000000, 0xCCCCCC, 0xCCCCCC, +}; + + +// +#if LANG == RUS +char mainWndTitle[] = "PHARAON's CRYPT"; +char mainWndCopyright[] = "(C) MMVI by Rabid Rabbit"; +char mainWndMenuStart[] = "1. "; +char mainWndMenuExit[] = "2. 室"; +char mainWndMenuLevel[] = "砫 ஢ - %U"; +#else +char mainWndTitle[] = "PHARAON's CRYPT"; +char mainWndCopyright[] = "(C) MMVI by Rabid Rabbit"; +char mainWndMenuStart[] = "1. Start game"; +char mainWndMenuExit[] = "2. Exit"; +char mainWndMenuLevel[] = "Starting level - %U"; +#endif +// +CKosBitmap mainWndFace; +// +Word mcx, mcy; + +#define BT_SIZE_X_MINUS 4 +#define BT_SIZE_X_PLUS 5 + +// +int MainWndLoop() +{ + Byte keyCode; + Dword buttonID; + int result; + static bool firstTime = true; + + // + startGameLevel = maxGameLevel; + // + if ( firstTime ) + { + // + mainWndFace.GetSize( mcx, mcy ); + // + firstTime = false; + // + DrawMainWindow(); + } + // + kos_ChangeWindow( -1, -1, mcx + 1, mcy + 21 ); + // + for ( result = MW_NONE; result == MW_NONE; ) + { + switch( kos_WaitForEvent() ) + { + case 1: + DrawMainWindow(); + break; + + case 2: + if ( kos_GetKey( keyCode ) ) + { + // + switch ( keyCode ) + { + case '1': + result = MW_START_GAME; + break; + + case '2': + result = MW_EXIT_APP; + break; + + default: + break; + } + } + break; + + case 3: + if ( kos_GetButtonID( buttonID ) ) + { + // + switch ( buttonID ) + { + // + case BT_SIZE_X_MINUS: + if ( --startGameLevel < 1 ) + startGameLevel = 1; + else + DrawMainWindow(); + break; + + // + case BT_SIZE_X_PLUS: + if ( ++startGameLevel > maxGameLevel ) + startGameLevel = maxGameLevel; + else + DrawMainWindow(); + break; + + // + default: + break; + } + } + + default: + break; + } + } + // + kos_DefineButton( + 0, 0, + 0, 0, + BT_SIZE_X_MINUS + 0x80000000, + 0 + ); + // + kos_DefineButton( + 0, 0, + 0, 0, + BT_SIZE_X_PLUS + 0x80000000, + 0 + ); + // + return result; +} + + +// (1) +void DrawMainWindow() +{ + char line[64]; + + // + kos_WindowRedrawStatus( WRS_BEGIN ); + // + kos_DefineAndDrawWindow( + WNDLEFT, WNDTOP, + mcx + 1, mcy + 21, + 0, 0x0, + 0, WNDHEADCOLOUR, + WNDHEADCOLOUR + ); + // + kos_WriteTextToWindow( + 4, 7, + 0x10, WNDTITLECOLOUR, + mainWndTitle, sizeof(mainWndTitle)-1 + ); + // + mainWndFace.Draw( 1, 21 ); + // + kos_WriteTextToWindow( + 8, 32, + 0, 0x0, + mainWndMenuStart, sizeof(mainWndMenuStart)-1 + ); + // + kos_WriteTextToWindow( + 8, 48, + 0, 0x0, + mainWndMenuExit, sizeof(mainWndMenuExit)-1 + ); + // + sprintf( line, mainWndMenuLevel, startGameLevel); + kos_WriteTextToWindow( + 8, 64, + 0, 0x0, + line, strlen( line ) + ); + // + kos_DefineButton( + mcx - 29, 64, + 12, 12, + BT_SIZE_X_MINUS, + 0xCCCCCC + ); + // + kos_PutImage( bmPMButton + 12, 6, 2, mcx - 29 + 3, 69 ); + // + kos_DefineButton( + mcx - 16, 64, + 12, 12, + BT_SIZE_X_PLUS, + 0xCCCCCC + ); + // + kos_PutImage( bmPMButton, 6, 6, mcx - 16 + 3, 67 ); + // + kos_WriteTextToWindow( + 8, mcy - 16 + 21, + 0, 0x000066, + mainWndCopyright, sizeof(mainWndCopyright)-1 + ); + // + kos_WindowRedrawStatus( WRS_END ); +} diff --git a/programs/games/fara/trunk/mainWnd.h b/programs/games/fara/trunk/mainWnd.h new file mode 100644 index 0000000000..13978fc431 --- /dev/null +++ b/programs/games/fara/trunk/mainWnd.h @@ -0,0 +1,13 @@ +// mainWnd.h + +#define MW_NONE 0 +#define MW_EXIT_APP 1 +#define MW_START_GAME 2 + + +// +int MainWndLoop(); +// (1) +void DrawMainWindow(); +// +extern CKosBitmap mainWndFace; diff --git a/programs/games/fara/trunk/mainfish.bmp b/programs/games/fara/trunk/mainfish.bmp new file mode 100644 index 0000000000..4b52b4df07 Binary files /dev/null and b/programs/games/fara/trunk/mainfish.bmp differ diff --git a/programs/games/fara/trunk/mcarray.h b/programs/games/fara/trunk/mcarray.h new file mode 100644 index 0000000000..f0d06814e1 --- /dev/null +++ b/programs/games/fara/trunk/mcarray.h @@ -0,0 +1,181 @@ +#define AR_CHUNK_SIZE 64 + +// +template +class MCArray +{ +protected: + TYPE * _dataPtr; + int _elementsCount; + int _capacity; + +public: + MCArray(); + virtual ~MCArray(); + virtual int Add( const TYPE &element ); + virtual int AddExclusive( const TYPE &element ); + virtual TYPE & GetAt( int Ndx ); + virtual TYPE & operator [] ( int Ndx ); + virtual int Find( int startNdx, const TYPE & element ); + virtual int RemoveAt( int Ndx ); + virtual void Clear(void); + virtual int GetCount(void); +}; + +// + + +// +template +MCArray::MCArray() +{ + // + this->_dataPtr = NULL; + this->_capacity = 0; + this->_elementsCount = 0; +} + + +// +template +MCArray::~MCArray() +{ + // + this->_capacity = 0; + this->_elementsCount = 0; + // + if ( this->_dataPtr != NULL ) + { + delete this->_dataPtr; + } +} + + +// +template +int MCArray::AddExclusive( const TYPE &element ) +{ + // + if ( this->Find( 0, element ) < 0 ) + return this->Add( element ); + else + return -1; +} + + +// +template +int MCArray::Add( const TYPE &element ) +{ + TYPE * dPtr; + + // ? + if ( this->_elementsCount >= this->_capacity ) + { + // + dPtr = new TYPE [this->_capacity + AR_CHUNK_SIZE]; + // + if ( dPtr == NULL ) + { + // + return -1; + } + + if ( this->_capacity > 0 ) + { + // + memcpy( dPtr, this->_dataPtr, sizeof(TYPE) * this->_capacity ); + // + delete this->_dataPtr; + } + // + this->_capacity += AR_CHUNK_SIZE; + // + this->_dataPtr = dPtr; + } + + // + this->_dataPtr[this->_elementsCount] = element; + //memcpy( this->_dataPtr + this->_elementsCount, &element, sizeof(TYPE) ); + + // + return ++this->_elementsCount; +} + + +// +template +TYPE & MCArray::GetAt( int Ndx ) +{ + //assert( Ndx >= 0 && Ndx < this->_elementsCount ); + return this->_dataPtr[Ndx]; +} + + +// +template +TYPE & MCArray::operator [] ( int Ndx ) +{ + return this->GetAt( Ndx ); +} + + +// +template +int MCArray::Find( int startNdx, const TYPE & element ) +{ + int i; + + if ( startNdx < 0 || startNdx >= this->_elementsCount ) + { + return -1; + } + + for ( i = startNdx; i < this->_elementsCount; i++ ) + { + if ( element == this->_dataPtr[i] ) + { + return i; + } + } + + return -1; +} + + +// +template +int MCArray::RemoveAt( int Ndx ) +{ + int mn; + + if ( Ndx < 0 || Ndx >= this->_elementsCount ) + { + return 0; + } + + mn = this->_elementsCount - Ndx; + + if ( mn != 1 ) + { + memcpy( this->_dataPtr + Ndx, this->_dataPtr + Ndx + 1, sizeof(TYPE) * ( mn - 1 ) ); + } + + this->_elementsCount--; + return 1; +} + + +// +template +void MCArray::Clear() +{ + this->_elementsCount = 0; +} + +// +template +int MCArray::GetCount() +{ + return this->_elementsCount; +} diff --git a/programs/games/fara/trunk/mcsmemm.cpp b/programs/games/fara/trunk/mcsmemm.cpp new file mode 100644 index 0000000000..cfc0c4adcc --- /dev/null +++ b/programs/games/fara/trunk/mcsmemm.cpp @@ -0,0 +1,298 @@ +// memman.cpp : Defines the entry point for the console application. +// + +#include "kosSyst.h" +#include "mcsmemm.h" + + +void * __cdecl operator new ( size_t count, size_t element_size ) +{ + return allocmem( (Dword)(count * element_size) ); +} + +void * __cdecl operator new [] ( size_t amount ) +{ + return allocmem( (Dword)amount ); +} + +void * __cdecl operator new ( size_t amount ) +{ + return allocmem( (Dword)amount ); +} + +void __cdecl operator delete ( void *pointer ) +{ + if ( pointer != NULL ) freemem( pointer ); +} + +void __cdecl operator delete [] ( void *pointer ) +{ + if ( pointer != NULL ) freemem( pointer ); +} + + +// +Dword mmMutex = FALSE; +MemBlock *rootfree = NULL; +MemBlock *rootuser = NULL; +bool mmInitialized = false; +Byte *mmHeapTop = NULL; + + +// +Byte *allocmem( Dword reqsize ) +{ + MemBlock *BlockForCheck; + MemBlock *LastKnownGood; + Dword tail; + Byte *address; + + // + if( ( tail = reqsize % SIZE_ALIGN ) != 0 ) + { + reqsize += SIZE_ALIGN - tail; + } + + LastKnownGood = NULL; + + // + while ( rtlInterlockedExchange( &mmMutex, TRUE ) ) + { + // + kos_Pause( 1 ); + } + + // + if( rootfree != NULL ) + { + for ( BlockForCheck = rootfree; ; BlockForCheck = BlockForCheck->Next ) + { + if ( BlockForCheck->Size >= reqsize ) + { + // + if ( LastKnownGood != NULL ) + { + if ( LastKnownGood->Size >= BlockForCheck->Size ) + LastKnownGood = BlockForCheck; + } + else + LastKnownGood = BlockForCheck; + if ( LastKnownGood->Size == reqsize ) + break; + } + if ( BlockForCheck->Next == NULL ) + break; + } + } + + if ( LastKnownGood != NULL ) + { + // + tail = LastKnownGood->Size - reqsize; + if ( tail >= ( sizeof(MemBlock) + SIZE_ALIGN ) ) + { + // + BlockForCheck = (MemBlock *)( ( (Byte *)LastKnownGood ) + tail ); + BlockForCheck->Size = reqsize; + // + if( rootuser != NULL ) + { + BlockForCheck->Next = rootuser; + rootuser->Previous = BlockForCheck; + BlockForCheck->Previous = NULL; + rootuser = BlockForCheck; + } + else + { + rootuser = BlockForCheck; + BlockForCheck->Next = NULL; + BlockForCheck->Previous = NULL; + } + + // + LastKnownGood->Size = tail - sizeof(MemBlock); + address = ( (Byte *)BlockForCheck ) + sizeof(MemBlock); + + // + rtlInterlockedExchange( &mmMutex, FALSE ); + + return address; + } + else + { + // + // + if ( LastKnownGood->Previous != NULL ) + { + LastKnownGood->Previous->Next = LastKnownGood->Next; + } + else + { + // + rootfree = LastKnownGood->Next; + } + if( LastKnownGood->Next != NULL ) + { + LastKnownGood->Next->Previous = LastKnownGood->Previous; + } + // + if( rootuser != NULL ) + { + LastKnownGood->Next = rootuser; + rootuser->Previous = LastKnownGood; + LastKnownGood->Previous = NULL; + rootuser = LastKnownGood; + } + else + { + rootuser = LastKnownGood; + LastKnownGood->Next = NULL; + LastKnownGood->Previous = NULL; + } + // + address = ( (Byte *)LastKnownGood ) + sizeof(MemBlock); + + // + rtlInterlockedExchange( &mmMutex, FALSE ); + + return address; + } + } + else + { + // + LastKnownGood = (MemBlock *)kos_malloc( + (reqsize > 0x10000 - sizeof(MemBlock)) ? (reqsize + sizeof(MemBlock)) : 0x10000); + if (LastKnownGood != NULL) + { + LastKnownGood->Size = reqsize; + // + LastKnownGood->Next = rootuser; + LastKnownGood->Previous = NULL; + if (rootuser != NULL) + rootuser->Previous = LastKnownGood; + rootuser = LastKnownGood; + // + if (reqsize < 0x10000 - sizeof(MemBlock)) + { + MemBlock* free = (MemBlock*)((Byte*)LastKnownGood + sizeof(MemBlock) + reqsize); + free->Next = rootfree; + free->Previous = NULL; + if (rootfree != NULL) + rootfree->Previous = free; + rootfree = free; + } + address = (Byte*)LastKnownGood + sizeof(MemBlock); + // + rtlInterlockedExchange(&mmMutex, FALSE); + + return address; + } + } + + // + rtlInterlockedExchange( &mmMutex, FALSE ); + + // + rtlDebugOutString( "allocmem failed." ); + kos_ExitApp(); + // + return NULL; +} + +// +Dword freemem( void *vaddress ) +{ + Dword result; + + Byte *checknext, *address = (Byte *)vaddress; + + // + while ( rtlInterlockedExchange( &mmMutex, TRUE ) ) + { + // + kos_Pause( 1 ); + } + + MemBlock *released = (MemBlock *)( address - sizeof(MemBlock) ); + + result = released->Size; + + // + if ( released->Previous != NULL ) + { + released->Previous->Next = released->Next; + } + else + { + rootuser = released->Next; + } + if ( released->Next != NULL ) + { + released->Next->Previous = released->Previous; + } + // + released->Next = rootfree; + released->Previous = NULL; + rootfree = released; + if ( released->Next != NULL ) + { + released->Next->Previous = released; + } + + // + checknext = (Byte *)(rootfree) + ( rootfree->Size + sizeof(MemBlock) ); + // + for ( released = rootfree->Next; released != NULL; released = released->Next ) + { + if ( checknext == (Byte *)released ) + { + // + // + released->Previous->Next = released->Next; + if( released->Next != NULL ) + { + released->Next->Previous = released->Previous; + } + // + rootfree->Size += released->Size + sizeof(MemBlock); + break; + } + } + // , . + checknext = (Byte *)(rootfree); + // + if ( released == NULL ) + { + for ( released = rootfree->Next; released != NULL; released = released->Next ) + { + if ( checknext == (Byte *)released + ( released->Size + sizeof(MemBlock) ) ) + { + // + // + released->Size += rootfree->Size + sizeof(MemBlock); + // + released->Previous->Next = released->Next; + if ( released->Next != NULL ) + { + released->Next->Previous = released->Previous; + } + // + if ( rootfree->Next != NULL ) + { + rootfree->Next->Previous = released; + } + released->Next = rootfree->Next; + released->Previous = NULL; + rootfree = released; + break; + } + } + } + + // + rtlInterlockedExchange( &mmMutex, FALSE ); + + return result; +} + diff --git a/programs/games/fara/trunk/numbers.bmp b/programs/games/fara/trunk/numbers.bmp new file mode 100644 index 0000000000..85b2c54926 Binary files /dev/null and b/programs/games/fara/trunk/numbers.bmp differ diff --git a/programs/games/fara/trunk/top10wnd.cpp b/programs/games/fara/trunk/top10wnd.cpp new file mode 100644 index 0000000000..6314bcc85d --- /dev/null +++ b/programs/games/fara/trunk/top10wnd.cpp @@ -0,0 +1,361 @@ +// top10wnd.cpp + +#include "kosSyst.h" +#include "KosFile.h" +#include "gfxdef.h" +#include "gameWnd.h" +#include "mcarray.h" +#include "top10wnd.h" +#include "lang.h" + +// +char top10FilePath[MAX_PATH]; + +// +struct hiScoreHero +{ + char name[12]; + Dword score; + // + hiScoreHero() + { + // + this->ClearName(); + this->score = 0; + }; + // + void ClearName() + { + memset( (Byte *)(this->name), '.', sizeof(this->name) ); + }; +}; + +// +hiScoreHero heroTbl[TOP_TBL_SIZE]; + +// +struct hiScoreFile +{ + Byte block[512]; + kosFileInfo fi; + // + hiScoreFile() + { + int i; + + // + this->fi.OffsetLow = this->fi.OffsetHigh = 0; + this->fi.dataCount = 0; + this->fi.bufferPtr = this->block; + this->fi.rwMode = 0; + memcpy( this->fi.fileURL, top10FilePath, strlen( top10FilePath ) + 1); + // + for ( i = 0; i < ( sizeof( this->block ) / sizeof( Dword ) ); i++ ) + { + // + ((Dword *)(this->block))[i] = rtlRand(); + } + }; + // + virtual ~hiScoreFile() + {} + // + bool LoadFromDisk() + { + bool result; + int i; + Dword j, k; + Byte *bPtr; + + // + this->fi.rwMode = FO_READ; + this->fi.OffsetLow = this->fi.OffsetHigh = 0; + this->fi.dataCount = 512; + result = kos_FileSystemAccess( &(this->fi) ) == 0; + // + if ( result ) + { + // + rtlSrand( ((Dword *)(this->block))[(sizeof(this->block) / sizeof(Dword)) - 1] ); + // + for ( i = 0; i < (sizeof( heroTbl ) * 5); i++ ) + { + // Dword + j = rtlRand() % (sizeof(this->block) - 7); + k = ( rtlRand() % 31 ) + 1; + // + bPtr = this->block + j; + // + __asm{ + mov edx, bPtr + mov ecx, k + mov eax, [edx] + bswap eax + ror eax, cl + mov [edx], eax + } + } + // + rtlSrand( kos_GetSystemClock() ); + } + // + return result; + }; + // + bool SaveToDisk() + { + int i; + Dword *rndList; + Byte *bPtr; + Dword k, keyLock; + + // + rndList = new Dword[(sizeof( heroTbl ) * 5) * 2]; + // + keyLock = rtlRand(); + // + for ( i = 0; i < (sizeof( heroTbl ) * 5); i++ ) + { + // + rndList[i * 2] = rtlRand() % (sizeof(this->block) - 7); + rndList[(i * 2) + 1] = ( rtlRand() % 31 ) + 1; + } + // + for ( i = (sizeof( heroTbl ) * 5) - 1; i >= 0; i-- ) + { + // + bPtr = this->block + rndList[i * 2]; + k = rndList[(i * 2) + 1]; + // + __asm{ + mov edx, bPtr + mov ecx, k + mov eax, [edx] + rol eax, cl + bswap eax + mov [edx], eax + } + } + // + delete rndList; + // + ((Dword *)(this->block))[(sizeof(this->block) / sizeof(Dword)) - 1] = keyLock; + // + this->fi.rwMode = FO_WRITE; + this->fi.dataCount = 512; + return kos_FileSystemAccess( &( this->fi) ) == 0; + }; +}; + + +/// +hiScoreFile *top10Heroes = NULL; + +// +#if LANG == RUS +char Top10WndTitle[] = "Top 10"; +char top10str1[] = "ENTER - Ok."; +char top10str2[] = "ESC - 室 "; +#else +char Top10WndTitle[] = "Top 10"; +char top10str1[] = "Enter - name Ok."; +char top10str2[] = "Esc - leave to menu"; +#endif +int enterName = -1; +int enterCharNdx = 0; + + +// +void ReleaseTop10() +{ + // + if ( top10Heroes != NULL ) + { + // + memcpy( top10Heroes->block, heroTbl, sizeof(heroTbl) ); + // + top10Heroes->SaveToDisk(); + // + delete top10Heroes; + } +} + + +// +void PrepareTop10() +{ + // + top10Heroes = new hiScoreFile; + // + atexit( ReleaseTop10 ); + // + if ( top10Heroes->LoadFromDisk() ) + { + // + memcpy( heroTbl, top10Heroes->block, sizeof(heroTbl) ); + } +} + + +// +void SetUpTop10() +{ + int i, j; + Byte keyCode; + + // + while ( kos_CheckForEvent() == 2 ) kos_GetKey( keyCode ); + // + kos_SetKeyboardDataMode( KM_CHARS ); + // + kos_ChangeWindow( -1, -1, TOP10_WND_SIZE_X, TOP10_WND_SIZE_Y ); + // + for ( i = 0; i < TOP_TBL_SIZE; i++ ) + { + // + if ( heroTbl[i].score < playerScore ) + { + // + for ( j = TOP_TBL_SIZE - 1; j > i; j-- ) + { + // + heroTbl[j] = heroTbl[j-1]; + } + // + heroTbl[i].ClearName(); + heroTbl[i].score = playerScore; + // + enterName = i; + enterCharNdx = 0; + // + break; + } + } +} + + +// +void DrawTop10Window() +{ + int i; + + // + kos_DefineAndDrawWindow( + 100, 100, + TOP10_WND_SIZE_X, TOP10_WND_SIZE_Y, + 0, 0, + 0, 0x2040A0, + 0x2040A0 + ); + // + kos_WriteTextToWindow( + 4, 4, + 0x0, 0x42D2E2, + Top10WndTitle, + sizeof( Top10WndTitle ) - 1 + ); + // + for ( i = 0; i < TOP_TBL_SIZE; i++ ) + { + // + kos_WriteTextToWindow( + 6, 21 + 2 + (i * 10), + 0x0, enterName != i ? 0xFFFFFF : 0x00FF00, + heroTbl[i].name, + sizeof( heroTbl[0].name ) + ); + // + kos_DisplayNumberToWindow( + heroTbl[i].score, + 8, + 112, 21 + 2 + (i * 10), + 0xFFFF55, + nbDecimal, + false + ); + } + // + kos_WriteTextToWindow( + 6, 21 + 6 + (i * 10), + 0x10, 0x1060D0, + enterName >= 0 ? top10str1 : top10str2, + enterName >= 0 ? sizeof(top10str1) - 1 : sizeof(top10str2) - 1 + ); +} + + +// +void Top10Loop() +{ + Byte keyCode; + + // + SetUpTop10(); + // + while ( true ) + { + switch ( kos_WaitForEvent() ) + { + // + case 1: + DrawTop10Window(); + break; + // + case 2: + // + kos_GetKey( keyCode ); + // + if ( enterName < 0 ) + { + // + if ( keyCode == 0x1b ) + { + // + return; + } + } + else + { + // + switch ( keyCode ) + { + // + case 13: + // + enterName = -1; + break; + // + case 8: + // + if ( enterCharNdx > 0 ) + { + // + heroTbl[enterName].name[--enterCharNdx] = '.'; + } + break; + // + default: + if ( keyCode >= 0x20 ) + { + // + heroTbl[enterName].name[enterCharNdx++] = keyCode; + // + if ( enterCharNdx >= sizeof(heroTbl[0].name) ) + { + // + enterName = -1; + } + } + break; + } + // + DrawTop10Window(); + } + // + break; + // + default: + break; + } + } +} \ No newline at end of file diff --git a/programs/games/fara/trunk/top10wnd.h b/programs/games/fara/trunk/top10wnd.h new file mode 100644 index 0000000000..a09ddaafa2 --- /dev/null +++ b/programs/games/fara/trunk/top10wnd.h @@ -0,0 +1,14 @@ +// top10wnd.h + +#define TOP_TBL_SIZE 10 +#define TOP10_WND_SIZE_X 176 +#define TOP10_WND_SIZE_Y 144 + +extern char top10FilePath[MAX_PATH]; +// +void Top10Loop(); +// +void PrepareTop10(); + + + diff --git a/programs/games/gomoku/trunk/gomoku.asm b/programs/games/gomoku/trunk/gomoku.asm new file mode 100644 index 0000000000..6d4f774392 --- /dev/null +++ b/programs/games/gomoku/trunk/gomoku.asm @@ -0,0 +1,735 @@ +;http://sources.ru/pascal/gamestxt/go-moku.zip + +N equ 19 ; Size of the board + +use32 + org 0x0 + db 'MENUET01' + dd 0x1 + dd START + dd I_END + dd (I_END+200+13*N*N) and not 3 + dd (I_END+200+13*N*N) and not 3 + dd 0x0,0x0 + +include 'macros.inc' +include 'lang.inc' + +AttackFactor dw 1 ; Importance of attack (1..16) + +START: + + mcall 40,100111b + mcall 40,100111b + mcall 3 + mov [rsx1],ax + shr eax,16 + mov [rsx2],ax + +redraw_all: + mcall 12,1 + mcall 48,4 + xchg eax,ecx + add ecx,100*65536+(16*N+26) + mcall 0,100*65536+(16*N+12),,0x34FFFFFF,,title + mcall 38,2*65536+(16*N),20*65536+20,0x00a0a0a0;000000 + mov edi,N + @@: add ecx,16*65536+16 + mcall + dec edi + jnz @b + push cx + mov ecx,20*65536 + pop cx + mcall ,1*65536+1 + mov edi,N + @@: add ebx,16*65536+16 + mcall + dec edi + jnz @b + + mcall 8,3*65536+40,3*65536+12,2,0xFFFFFF + mcall ,50*65536+40,,3, + mcall 4,7*65536+5,0x80000000,txt_buttons + mcall 12,2 + + +draw_pole: +; mcall 48,4 +; xchg eax,ecx +; add ecx,100*65536+(16*N+26) +; mcall 0,100*65536+(16*N+12),,0x74FFFFFF,,title + + mov esi,Board + mov edi,N*N-N + mov ebp,N + mov ebx,(1+5)*65536+(21+5-1) + call print_board + bt [flags],0 + jnc @f + mcall 4,100*65536+6,0x800000ff,txt_go +@@: bt [flags],3 + jnc @f + mcall 4,100*65536+6,0x800000ff,txt_tie + jmp still +@@: + bt [flags],2 + jnc still + ret +still: + mcall 10 + + dec al + jz redraw_all + dec al + jz key + dec al + jz button + sub al,3 + jz mouse + jmp still + +key: + mcall 2 + btr [flags],2 + cmp ah,97 + jne @f +.auto: bts [flags],2 + jmp mouse.auto +@@: cmp ah,110 + je button.new_game + jmp still + +button: + mcall 17 + cmp ah,1 + jne @f + mcall -1 +@@: cmp ah,2 + jne key.auto +.new_game: + mov [TotalLines],2 * 2 * (N * (N - 4) + (N - 4) * (N - 4)) + mov [WinningLine],0x0 + mov [X],(N + 1)/2 + mov [Y],(N + 1)/2 + mov [flags],0 + mov edi,Board + mov ecx,(13*N*N/4)+1 + xor eax,eax + cld +@@: stosd + loop @b + jmp redraw_all + +print_board: + cmp byte [esi],0 ; + je .null + cmp byte [esi],1 ;X + je .one + cmp byte [esi],2 ;O + je .two + bts [flags],4 + cmp byte [esi],3 ; + je .one + jmp .two ;0 + +.end: + inc esi + dec ebp + jnz print_board + test edi,edi + jz @f + sub edi,N + mov ebp,N + add ebx,-N*16*65536+16 + jmp print_board +@@: ret + +.one: + mov ecx,0xd04ba010 + bt [flags],4 + jnc @f + mov ecx,0xd0ff0000 + btr [flags],4 +@@: push edi + mcall 4,,,txt_x,,0xffffff + pop edi +.null: + add ebx,16*65536;+16 + jmp .end +.two: + mov ecx,0xd000459a + bt [flags],4 + jnc @f + mov ecx,0xd0ff0000 + btr [flags],4 +@@: push edi + mcall 4,,,txt_o,,0xffffff + pop edi + jmp .null + + +draw_one_symbol: + movzx eax,[X] + mov ebx,16 + mul ebx + shl eax,16 + add eax,(1+5)*65536; + mov ax,[Y] + mov ecx,16 + mul cx + add ax,(21+5-1) + xchg eax,ebx + + movzx eax,[Y] + push ebx + mov ebx,N + mul bx + mov bx,[X] + add ax,bx + pop ebx + mov esi,Board + add esi,eax + mov edi,0 + mov ebp,1 + call print_board +ret + + +mouse: + bt [flags],5 + jc still + mcall 37,2 + test eax,eax + jz still + mcall 37,1 + mov dx,ax + shr eax,16 + cmp dx,20 + jbe still + cmp dx,(16*N+20) + jge still + cmp ax,1 + jbe still + cmp ax,(16*N) + jge still + + bt [flags],0 + jc still + bt [flags],3 + jc still + sub ax,1 + push dx + xor edx,edx + mov cx,16 + div cx + pop dx + mov [X],ax + push ax + sub dx,20 + mov ax,dx + xor dx,dx + div cx + mov [Y],ax + xor dx,dx + mov cx,N + mul cx + pop dx + add ax,dx + cmp ax,N*N + jge still + mov esi,Board + + cmp byte [esi+eax],0 + jne still + +.auto: bt [flags],0 + jc .end + bt [flags],3 + jc .end + + btr [flags],1 ;0 - 室 ப + bt [flags],2 + jnc @f + call FindMove +@@: call MakeMove + call draw_one_symbol + bt [flags],0 + jc .end + + bts [flags],1 ;1 - 室 cpu + call FindMove + call MakeMove + call draw_one_symbol +.end: bt [flags],0 + jnc @f + call BlinkRow + btr [flags],2 +@@:; mcall 12,1 + bt [flags],3 + jc @f + bt [flags],2 + jnc @f + call draw_pole + jmp .auto +@@: jmp draw_pole + + + + +winline: dw 1,0, 1,1, 1,-1, 0,1 ;X,Y +BlinkRow: + movzx ecx,[WinningLine] + mov eax,[winline+(ecx-1)*4] + push ax ;Dx + shr eax,16 + push ax ;Dy + movzx eax,[Y] + mov si,N + mul si + add ax,[X] + mov cl,[Board+eax] +@@: movzx eax,[Y] + add ax,[esp] + mov [Y],ax + test eax,eax + jz .ret + cmp eax,N-1 + jg .ret + movzx ebx,[X] + add bx,[esp+2] + mov [X],bx + test ebx,ebx + jz .ret + cmp ebx,N-1 + jg .ret + mov si,N + mul si + add ax,bx + cmp byte [Board+eax],cl + je @b + +.ret: mov edi,5 + mov esi,N +@@: movzx eax,[Y] + sub ax,[esp] + mov [Y],ax + mul si + movzx ebx,[X] + sub bx,[esp+2] + mov [X],bx + add ax,bx + cmp byte [Board+eax],cl + jne .1 + add byte [Board+eax],2 +.1: dec edi + jnz @b + add esp,4 +ret + + + +Max dw ? + +FindMove: + mov [Max],0 + mov [X],((N+1) / 2) + mov [Y],((N+1) / 2) + movzx eax,[Y] + mov ah,N + mul ah + add ax,[X] + cmp byte [Board+eax],0 + jne @f + mov [Max],4 +@@: xor ecx,ecx +.loop: + cmp byte [Board+ecx],0 + jne .check_loop + movzx eax, word [Value+ecx*2] + bt [flags],1 + jc @f + movzx eax, word [Value+(N*N+ecx)*2] + @@: + mov ebx,16 + add bx,[AttackFactor] + mul bx + shr eax,4 ;div 16 + mov bx,[Value+2*(N*N+ecx)] + bt [flags],1 + jc @f + mov bx,[Value+2*(ecx)] + @@: + add bx,ax + mov eax,4 + call random + add bx,ax + cmp bx,[Max] + jbe .check_loop + mov [Max],bx + xor edx,edx + mov eax,ecx + mov ebx,N + div ebx + mov [X],dx + mov [Y],ax +.check_loop: + inc ecx + cmp ecx,N*N + jb .loop +ret + + +MakeMove: + xor eax,eax + mov esi,N + +.1: movzx ecx,[X] ;ecx=X1, eax=K, edx=Y1 + inc cl + movzx edx,[Y] + inc dl + sub cl,al + xor edi,edi + test ecx,ecx + jz .1_ + cmp ecx,N-4 + jg .1_ + dec cl + dec dl + push eax edx + mov eax,edx + mul esi + add eax,ecx + call .Add + bt [flags],0 + jnc .11 + cmp [WinningLine],0x0 + jne .11 + mov [WinningLine],1 + .11: mov eax,[esp];edx + mul esi + add eax,ecx + push eax + mov eax,[esp+4];edx + mul esi + add eax,edi + add eax,ecx + mov ebx,eax + pop eax + call .Update + inc edi + cmp edi,4 + jbe .11 + pop edx eax +.1_: inc eax + cmp eax,4 + jbe .1 + + xor eax,eax + +.2: movzx ecx,[X] + inc cl + movzx edx,[Y] + inc dl + xor edi,edi + sub cl,al + sub dl,al + test ecx,ecx + jz .2_ + cmp ecx,N-4 + jg .2_ + test edx,edx + jz .2_ + cmp edx,N-4 + jg .2_ + dec cl + dec dl + push eax edx + mov eax,edx + mul esi + add eax,ecx + add eax,1*N*N + call .Add + bt [flags],0 + jnc .21 + cmp [WinningLine],0x0 + jne .21 + mov [WinningLine],2 + .21: mov eax,[esp];edx + mul esi + add eax,ecx + add eax,1*N*N + push eax + mov eax,[esp+4];edx + add eax,edi + mul esi + add eax,edi + add eax,ecx + mov ebx,eax + pop eax + call .Update + inc edi + cmp edi,4 + jbe .21 + pop edx eax +.2_: inc eax + cmp eax,4 + jbe .2 + + xor eax,eax + +.3: movzx ecx,[X] + inc cl + movzx edx,[Y] + inc dl + xor edi,edi + add cl,al + sub dl,al + cmp ecx,5 + jb .3_ + cmp ecx,N + jg .3_ + test edx,edx + jz .3_ + cmp edx,N-4 + jg .3_ + dec cl + dec dl + push eax edx + mov eax,edx + mul esi + add eax,ecx + add eax,3*N*N + call .Add + bt [flags],0 + jnc .31 + cmp [WinningLine],0 + jne .31 + mov [WinningLine],3 + .31: mov eax,[esp];edx + mul esi + add eax,ecx + add eax,3*N*N + push eax + mov eax,[esp+4];edx + add eax,edi + mul esi + add eax,ecx + sub eax,edi + mov ebx,eax + pop eax + call .Update + inc edi + cmp edi,4 + jbe .31 + pop edx eax +.3_: inc eax + cmp eax,4 + jbe .3 + + xor eax,eax + +.4: movzx ecx,[X] + inc cl + movzx edx,[Y] + inc dl + xor edi,edi + sub dl,al + test edx,edx + jz .4_ + cmp edx,N-4 + jg .4_ + dec cl + dec dl + push eax edx + mov eax,edx + mul esi + add eax,ecx + add eax,2*N*N + call .Add + bt [flags],0 + jnc .41 + cmp [WinningLine],0 + jne .41 + mov [WinningLine],4 + .41: mov eax,[esp];edx + mul esi + add eax,ecx + add eax,2*N*N + push eax + mov eax,[esp+4];edx + add eax,edi + mul esi + add eax,ecx + mov ebx,eax + pop eax + call .Update + inc edi + cmp edi,4 + jbe .41 + pop edx eax +.4_: inc eax + cmp eax,4 + jbe .4 + + movzx eax,[Y] + mul esi + add ax,[X] + bt [flags],1 + jc @f + mov byte [Board+eax],1 + jmp .end +@@: + mov byte [Board+eax],2 +.end: cmp [TotalLines],0 + jne @f + bts [flags],3 +@@: +ret + +.Add: + bt [flags],1 + jnc .Add_player + inc byte [Line+eax] + cmp byte [Line+eax],1 + jne @f + dec [TotalLines] +@@: cmp byte [Line+eax],5 + jb @f + bts [flags],0 ; 祭 +@@: +ret +.Add_player: + inc byte [Line+eax+4*N*N] + cmp byte [Line+eax+4*N*N],1 + jne @f + dec [TotalLines] +@@: cmp byte [Line+eax+4*N*N],5 + jb @f + bts [flags],0 ; 祭 +@@: +ret + +.Update: +;eax ࠬ, ebx ன + push edi + bt [flags],1 + jnc .Update_player + cmp byte [Line+eax+4*N*N],0 + jne .else_cpu + push eax + movzx edi, byte [Line+eax] + mov ax, word [edi*2+2+Weight] + sub ax, word [edi*2+Weight] + add [Value+ebx*2],ax + pop eax + jmp .Update_end + .else_cpu: + cmp byte [Line+eax],1 + jne .Update_end + push eax + movzx edi, byte [Line+eax+4*N*N] + mov ax, word [edi*2+2+Weight] + sub [Value+ebx*2+N*N*2],ax + pop eax + jmp .Update_end +.Update_player: + cmp byte [Line+eax],0 + jne .else_player + push eax + movzx edi, byte [Line+eax+4*N*N] + mov ax, word [edi*2+2+Weight] + mov di, word [edi*2+Weight] + sub ax,di + add [Value+ebx*2+2*N*N],ax + pop eax + jmp .Update_end + .else_player: + cmp byte [Line+eax+4*N*N],1 + jne .Update_end + push eax + movzx edi, byte [Line+eax] + mov ax, word [edi*2+2+Weight] + sub [Value+ebx*2],ax + pop eax +.Update_end: + pop edi +ret + + +align 4 +rsx1 dw ?;0x4321 +rsx2 dw ?;0x1234 +random: ; ASCL + push ecx ebx edi edx + mov cx,ax + mov ax,[rsx1] + mov bx,[rsx2] + mov si,ax + mov di,bx + mov dl,ah + mov ah,al + mov al,bh + mov bh,bl + xor bl,bl + rcr dl,1 + rcr ax,1 + rcr bx,1 + add bx,di + adc ax,si + add bx,0x62e9 + adc ax,0x3619 + mov [rsx1],bx + mov [rsx2],ax + xor dx,dx + cmp ax,0 + je nodiv + cmp cx,0 + je nodiv + div cx +nodiv: + mov ax,dx + pop edx edi ebx ecx + and eax,0000ffffh +ret + + + +txt_x db 'X',0 +txt_o db 'O',0 +if lang eq ru +title db '',0 +txt_buttons db ' ',0 +txt_go db ' 祭',0 +txt_tie db ' 室',0 +else +title db 'Gomoku',0 +txt_go db 'Game over',0 +txt_tie db 'Tie game',0 +txt_buttons db 'New Auto',0 +endf + + +Weight dw 0,0,4,20,100,500,0 + + +WinningLine db 0 +TotalLines dw 0 + +X dw 0 +Y dw 0 + +flags rw 1 +; 0: 祭 +;1: 0-室 ப, 1- +;2: autoplay +;3: 室 ௠ +;4: print_board - 뤥 梥⮬ 5- ⮪ + +I_END: +align 16 +Board rb N*N +Value rw N*N*2 ;ࢠ - , - ப +Line rb 4*N*N*2 + + diff --git a/programs/games/reversi/trunk/Makefile b/programs/games/reversi/trunk/Makefile new file mode 100644 index 0000000000..6bf4de36ab --- /dev/null +++ b/programs/games/reversi/trunk/Makefile @@ -0,0 +1,3 @@ +OUTFILE = reversi +OBJS = reversi.o +include $(MENUETDEV)/makefiles/Makefile_for_program diff --git a/programs/games/reversi/trunk/reversi.c b/programs/games/reversi/trunk/reversi.c new file mode 100644 index 0000000000..967b03d726 --- /dev/null +++ b/programs/games/reversi/trunk/reversi.c @@ -0,0 +1,619 @@ +// +// KReversi.java +// The Othello Game, based on the algorithm of Muffy Barkocy +// (muffy@fish.com). +// +// The strategy is very very simple. The best move for the computer +// is the move that flip more pieces (preferring boards line and +// corners) and give less pieces to move to the opponent. +// +// Author: Alex "Kazuma" Garbagnati (kazuma@energy.it) +// Date: 20 Jan 96 +// L.R.: 26 Jan 96 +// Note: +// + + + +#include +#include +#include +#include +#include +#include + +typedef unsigned int u32; + +int YSHIFT= 33; + +int ENGLISH = 0; // +int ITALIAN = 1; // Languages +int EXTERNAL = 2; // + +#define BLACK 0x000000; // +#define BLACK_S 0x333333; // +#define WHITE 0xffffff; // Colors +#define WHITE_S 0xaaaaaa; // + + +int NOMOVE = 0; // +int REALMOVE = 1; // Type of move +int PSEUDOMOVE = 2; // + +int Empty = 0; // +int User = 1; // Board's owners +int Computer = 2; // + +#define true 1 +#define false 0 + +int UserMove = true; +int GameOver = false; +int CopyWinOn = false; +int StillInitiated = false; // This solve a little + // problem on reinit. + +int TheBoard[8][8]; // Board +int Score[8][8]; +int OpponentScore[8][8]; + + + + // + // DrawBoard + // (paint the Othello Board, a 8X8 green square table) + // + // Input: graphic (Graphics) + // Output: none + // Notes: + // + void DrawBoard() { + int i; + for(i=0;i<=8;i++) + { + __asm__ __volatile__("int $0x40"::"a"(38),"b"(320),"c"(YSHIFT+(YSHIFT+(40*i))*65536+40*i),"d"(0x555555)); + __menuet__line((40*i),YSHIFT,(40*i),353,0x555555); // horizontal + + } + + } + // End of DrawBoard + + + // + // DrawPiece + // (paint a piece, black or white, I'm using an 8x8 array, so + // from the input values for rows and cols must be + // subtracted 1) + // + // Input: who (int), + // column (int), + // row (int) + // Output: none + // Notes: + // + void DrawPiece(int Who, int Col, int Row) { + int pCol = (40*(Col-1)+1); + int pRow = YSHIFT+(40*(Row-1)+1); + u32 pColor,pShadow; + + if (Who == User) { + pColor = BLACK; + pShadow = BLACK_S; + } else { + pColor = WHITE; + pShadow = WHITE_S; + } + TheBoard[Col-1][Row-1] = Who; + + __menuet__bar(pCol+9,pRow+9,19,19,pColor); + } + // End of DrawPiece + + + // + // MsgWhoMove + // (paint the message informing who's move) + // + // Input: is user ? (int) + // Output: none + // Notes: + // + void MsgWhoMove(int UM) { + } + // End of MsgWhoMove + + + // + // FlipRow + // (calculate number of pieces are flipped by a move + // and return it. Eventually do the complete or pseudo + // move) + // + // Input: who (int) + // which board (int[][]) + // position col, row (int) + // direction col, row (int) + // make move ? (int) + // + int FlipRow(int Who, int WhichBoard[8][8] , int C, int R, + int CInc, int RInc, int MakeMove) { + int NewCol; + int NewRow; + int Opponent = User + Computer - Who; + int CNT = 0; + + NewCol = C - 1; + NewRow = R - 1; + while (true) { + if (((NewCol+CInc) < 0) || ((NewCol+CInc) > 7) || + ((NewRow+RInc) < 0) || ((NewRow+RInc) > 7)) { + return 0; + } + if (WhichBoard[NewCol+CInc][NewRow+RInc] == Opponent) { + CNT++; + NewCol += CInc; + NewRow += RInc; + } else if (WhichBoard[NewCol+CInc][NewRow+RInc] == Empty) { + return 0; + } else { + break; + } + } + if (MakeMove != NOMOVE) { + C--; + R--; + int v; + for(v=0; v<=CNT; v++) { + if (MakeMove == REALMOVE) { + DrawPiece(Who, C+1, R+1); + } else { + WhichBoard[C][R] = Who; + } + C += CInc; + R += RInc; + } + } + return CNT; + } + // End of FlipRow + + + // + // IsLegalMove + // (verify that the move is legal) + // + // Input: who (int) + // board (int[][]) + // position col, row (int) + // Output: is legal ? (int) + // Notes: + // + int IsLegalMove(int Who, int WhichBoard[8][8] , int C, int R) { + if (WhichBoard[C-1][R-1] != Empty) { + return false; + } + int CInc,RInc; + for (CInc=-1; CInc<2; CInc++) { + for (RInc=-1; RInc<2; RInc++) { + if (FlipRow(Who, WhichBoard, C, R, CInc, RInc, NOMOVE) > 0) { + return true; + } + } + } + return false; + } + // End of IsLegalMove + + + // + // MakeMove + // (make the move) + // + // Input: who (int) + // position col, row (int) + // Output: false=EndGame, true=next player (int) + // Notes: + // + int MakeMove(int Who, int C, int R) { + int CInc,RInc; + for (CInc=-1; CInc<2; CInc++) { + for (RInc=-1; RInc<2; RInc++) { + FlipRow(Who, TheBoard, C, R, CInc, RInc, REALMOVE); + } + } + if (IsBoardComplete() || + ((!ThereAreMoves(Computer, TheBoard)) && (!ThereAreMoves(User, TheBoard)))) { + return false; + } + int Opponent = (User + Computer) - Who; + if (ThereAreMoves(Opponent, TheBoard)) { + UserMove = !UserMove; + } + return true; + } + // End of MakeMove + + + // + // EndGame + // (shows the winning message) + // + // Input: none + // Output: none + // Notes: + // + void EndGame() { + int CompPieces = 0; + int UserPieces = 0; + char *WinMsg_W = "Computer Won"; + char *WinMsg_L = "User Won"; + char *WinMsg_T = "???"; + char *TheMsg; + + int StrWidth; + + int c,r; + for (c=0; c<8; c++) { + for (r=0; r<8; r++) { + if (TheBoard[c][r] == Computer) { + CompPieces++; + } else { + UserPieces++; + } + } + } + if (CompPieces > UserPieces) { + TheMsg = WinMsg_W; + } else if (UserPieces > CompPieces) { + TheMsg = WinMsg_L; + } else { + TheMsg = WinMsg_T; + } + + __menuet__write_text(100,8,0xff0000,TheMsg,strlen(TheMsg)); + + } + // End of EndGame + + + // + // IsBoardComplete + // (checks if the board is complete) + // + // Input: none + // Output: the board is complete ? (int) + // Notes: + // + int IsBoardComplete() { + int i,j; + for (i=0; i<8; i++) { + for (j=0; j<8; j++) { + if (TheBoard[i][j] == Empty) { + return false; + } + } + } + return true; + } + // End of IsBoardComplete + + + // + // ThereAreMoves + // (checks if there are more valid moves for the + // player) + // + // Input: player (int) + // board (int[][]) + // Output: there are moves ? (int) + // Notes: + // + int ThereAreMoves(int Who, int WhichBoard[8][8] ) { + int i,j; + for (i=1; i<=8; i++) { + for (j=1; j<=8; j++) { + if (IsLegalMove(Who, WhichBoard, i, j)) { + return true; + } + } + } + return false; + } + // End of ThereAreMoves + + + // + // CalcOpponentScore + // (calculate the totalScore of opponent after + // a move) + // + // Input: position x, y (int) + // Output: score (int) + // Notes: + // + int CalcOpponentScore(int CP, int RP) { + int OpScore = 0; + int tempBoard[8][8]; // = new int[8][8]; + int c,r; + for (c=0; c<8; c++) { + for (r=0; r<8; r++) { + tempBoard[c][r] = TheBoard[c][r]; + } + } + int CInc,RInc; + for (CInc=-1; CInc<2; CInc++) { + for (RInc=-1; RInc<2; RInc++) { + FlipRow(Computer, tempBoard, CP+1, RP+1, CInc, RInc, PSEUDOMOVE); + } + } + if (ThereAreMoves(User, tempBoard)) { + int C,R; + for (C=0; C<8; C++) { + for (R=0; R<8; R++) { + OpScore += RankMove(User, tempBoard, C, R); + } + } + } + return OpScore; + } + // End of CalcOpponentScore() + + + // + // RankMoves + // (rank all moves for the computer) + // + // Input: none + // Output: none + // Notes: + // + void RankMoves() { + int C,R; + for (C=0; C<8; C++) { + for (R=0; R<8; R++) { + Score[C][R] = RankMove(Computer, TheBoard, C, R); + if (Score[C][R] != 0) { + OpponentScore[C][R] = CalcOpponentScore(C, R); + } else { + OpponentScore[C][R] = 0; + } + } + } + } + // End of RankMoves + + + // + // RankMove + // (rank a move for a player on a board) + // + // Input: who moves (int) + // on which board (int[][]) + // position col, row (int) + // Output: flipped pieces (int) + // Notes: best are corner, then border lines, + // worst are line near to border lines + // + int RankMove(int Who, int WhichBoard[8][8], int Col, int Row) { + int CNT = 0; + int MV = 0; + + if (WhichBoard[Col][Row] != Empty) { + return 0; + } + int CInc,RInc; + for (CInc=-1; CInc<2; CInc++) { + for (RInc=-1; RInc<2; RInc++) { + MV = FlipRow(Who, WhichBoard, Col+1, Row+1, CInc, RInc, NOMOVE); + CNT += MV; + } + } + if (CNT > 0) { + if (((Col == 0) || (Col == 7)) || + ((Row == 0) || (Row == 7))) { + CNT = 63; + } + if (((Col == 0) || (Col == 7)) && + ((Row == 0) || (Row == 7))) { + CNT = 64; + } + if ((((Col == 0) || (Col == 7)) && (Row == 1) || (Row == 6)) && + (((Col == 1) || (Col == 6)) && (Row == 0) || (Row == 7)) && + (((Col == 1) || (Col == 6)) && (Row == 1) || (Row == 6))) { + CNT = 1; + } + } + return CNT; + } + // End of RankMove + + + // + // BestMove + // (calculate and execute the best move) + // + // Input: none + // Output: value, col & row (int[3]) + // Notes: + // + void BestMove (int retval[3]) { + + retval[0] = -998; // move value; + retval[1] = 0; // column + retval[2] = 0; // row + + RankMoves(); + int C,R; + for (C=0; C<8; C++) { + for (R=0; R<8; R++) { + if ((Score[C][R] == 0) && (OpponentScore[C][R] == 0)) { + Score[C][R] = -999; + } else if (Score[C][R] != 64) { + Score[C][R] = Score[C][R] - OpponentScore[C][R]; + } + } + } + for (C=0; C<8; C++) { + for (R=0; R<8; R++) { + if (Score[C][R] > retval[0]) { + retval[1] = C; + retval[2] = R; + retval[0] = Score[C][R]; + } + } + } + retval[1]++; + retval[2]++; +// return retval; + } + // End of BestMove + + + + + // + // paint + // + void paint() { +// MsgWhoMove(UserMove); + if (!CopyWinOn) { + int i,j; + for (i=0; i<8; i++) { + for (j=0; j<8; j++) { + if (TheBoard[i][j] != Empty) { + DrawPiece(TheBoard[i][j], i+1, j+1); + } + } + } +// } else { +// ShowAbout(); + } + } + // End of paint + + + // + // init + // + void init() { + // This is the right size of the applet 321x387 +// resize(321,387); + // I set twice the language. That's because if anybody + // forget a string in an external language file, are + // used english strings. + if (!StillInitiated) { + StillInitiated = true; + } + int i,j; + for (i=0; i<8; i++) { + for (j=0; j<8; j++) { + TheBoard[i][j] = 0; + } + } + TheBoard[3][3] = User; + TheBoard[3][4] = Computer; + TheBoard[4][3] = Computer; + TheBoard[4][4] = User; + UserMove = true; +// MsgWhoMove(true); + // repaint(); + } + // End of init + + + + + +void paint_win(void) +{ + __menuet__window_redraw(1); + __menuet__define_window(100,100,330,400,0x33777777,0,"Reversi"); + __menuet__make_button(2,2,40,20,3,0xe0e0e0); + __menuet__write_text(8,8,0x333333,"New",3); + __menuet__window_redraw(2); +} + +void app_main(void) +{ + int i; + u32 mouse_coord; + u32 mouse_butn; + int X,Y; + + int TheCol, TheRow; + int BMove[3]; + int BX, BY; + int retval = false; + + + __menuet__set_bitfield_for_wanted_events(EVENT_REDRAW + EVENT_KEY + EVENT_BUTTON + EVENT_MOUSE_CHANGE); + paint_win(); + DrawBoard(); + init(); + paint(); + + for(;;) + { + i=__menuet__wait_for_event(); + switch(i) + { + case 1: + paint_win(); + DrawBoard(); + paint(); + continue; + case 2: + __menuet__getkey(); + continue; + case 3: + if(__menuet__get_button_id()==1) { + __menuet__sys_exit();} + else + paint_win(); + init(); + DrawBoard(); + paint(); + continue; + case 4: + continue; + case 5: + continue; + case 6: + __asm__ __volatile__("int $0x40":"=a"(mouse_butn):"0"(37),"b"(2)); + __asm__ __volatile__("int $0x40":"=a"(mouse_coord):"0"(37),"b"(1)); + X = mouse_coord >> 16; + Y = mouse_coord & 0xffff; + + // Process a normal click in the board + BX = X; + BY = Y - YSHIFT; + + + if ((BY >= 0) && (BY <= 321) && + (mouse_butn !=0) && (UserMove)) { + TheCol = (int)((BX/40)+1); + TheRow = (int)((BY/40)+1); + + if (IsLegalMove(User, TheBoard, TheCol, TheRow)) { + retval = MakeMove(User, TheCol, TheRow); + while (retval && (!UserMove)) { + //MsgWhoMove(UserMove); + BestMove(BMove); + + retval = MakeMove(Computer, BMove[1], BMove[2]); + //MsgWhoMove(UserMove); + } + if (!retval) { + EndGame(); + } + } + paint(); + } + continue; + + + } + } +} + diff --git a/programs/games/rforces/trunk/KosFile.h b/programs/games/rforces/trunk/KosFile.h new file mode 100644 index 0000000000..5f7c18e9bc --- /dev/null +++ b/programs/games/rforces/trunk/KosFile.h @@ -0,0 +1,26 @@ +#pragma once + +#define SEEK_SET 0 +#define SEEK_CUR 1 + +#define FILE_BUFFER_SIZE 512 +#define OS_BLOCK_SIZE 1 +#define FILE_BUFFER_BLOCKS (FILE_BUFFER_SIZE / OS_BLOCK_SIZE) + + +class CKosFile +{ +public: + CKosFile(char *fileName); + virtual ~CKosFile(void); + virtual int Read(Byte *targetPtr, int readCount); + virtual int Write(Byte *sourcePtr, int writeCount); + virtual int Seek(int seekFrom, int seekStep); +protected: + int filePointer; + int bufferPointer; + bool validBuffer; + kosFileInfo fileInfo; + virtual void ValidateBuffer(void); + virtual void UpdateBuffer(void); +}; diff --git a/programs/games/rforces/trunk/cmp.bat b/programs/games/rforces/trunk/cmp.bat new file mode 100644 index 0000000000..59b663e8a2 --- /dev/null +++ b/programs/games/rforces/trunk/cmp.bat @@ -0,0 +1,4 @@ +"C:\Program Files\Microsoft Visual Studio 8\VC\bin\cl" /c /O2 /nologo /GS- /GR- /fp:fast rforces.cpp kosFile.cpp kosSyst.cpp mcsmemm.cpp +"C:\Program Files\Microsoft Visual Studio 8\VC\bin\link" /nologo /manifest:no /entry:crtStartUp /subsystem:native /base:0 /fixed /align:16 /nodefaultlib rforces.obj kosFile.obj kosSyst.obj mcsmemm.obj +pe2kos rforces.exe rforces +pause \ No newline at end of file diff --git a/programs/games/rforces/trunk/forces_1.1.cpp b/programs/games/rforces/trunk/forces_1.1.cpp new file mode 100644 index 0000000000..06a589cc1d --- /dev/null +++ b/programs/games/rforces/trunk/forces_1.1.cpp @@ -0,0 +1,402 @@ +/* Rocket Forces + * Filename: rforces.cpp + * Version 0.1 + * Copyright (c) Serial 2007 + */ + + +#include + +#include "kosSyst.h" +#include "kosFile.h" +#include "mymath.h" +#include "properties.h" +#include "objects.h" +#include "rforces.h" + + +const char header[] = GAME_NAME; +cCursor *cursor; +cGun *gun = new cGun; +cCross **crosses = new cCross*[R_COUNT]; +cRocket **rockets = new cRocket*[R_COUNT]; +cBomb **bombs = new cBomb*[B_COUNT]; +cExplode **explodes = new cExplode*[R_COUNT + B_COUNT]; +cBuilding *house = new cBuilding(); +Dword *cur_handle; +int score = 0, health = 100; + +struct MouseState +{ + int x, y, lbclick; + Dword buttons; +} ms; + + +void kos_Main() +{ + Dword frame_start, frame_end; + OnStart(); + Menu(); + for (;;) + { + frame_start = kos_GetTime(); + switch (kos_CheckForEvent()) + { + case 1: + DrawWindow(); + break; + case 2: // key pressed, read it and ignore + Byte keyCode; + kos_GetKey(keyCode); + if (keyCode == 27) + { + OnExit(); + } + break; + case 3: // button pressed; we have only one button, close + OnExit(); + break; + case 6: // ( ; ) + OnMouseMove(); + if (ms.lbclick == 1) + { + OnLMBClick(); + } + break; + default: + OnMouseMove(); + break; + } + DrawBombs(); + DrawRocketsAndCrosses(); + DrawExplodes(); + frame_end = kos_GetTime(); + if (frame_end - frame_start < FRAME_TIME) + { + kos_Pause(FRAME_TIME - (frame_end - frame_start)); + } + if (health <= 0) + { + OnExit(); + } + } +} + +void DrawWindow() +{ + kos_WindowRedrawStatus(1); + kos_DefineAndDrawWindow(10, 40, WINDOW_WIDTH + 8, WINDOW_HEIGHT + 25, 0x33, BG_COLOR, 0, 0, (Dword)header); + kos_WindowRedrawStatus(2); + + kos_WindowRedrawStatus(1); /// DEL!!!!11 + + OnMouseMove(); + + // Draw buildings + for (int i = 20; i < 5 * 50; i += 50) + { + house->Draw(i, 467, H_COLOR); + } + for (int i = 8 * 50; i < 13 * 50; i += 50) + { + house->Draw(i, 467, H_COLOR); + } + +} + +void DrawBombs() +{ + for (int i = 0; i < B_COUNT; i++) + { + if (bombs[i]->IsEnabled() == 0) + { + int rnd; + rnd = rtlRand() % B_POSSIBILITY; + if (rnd == 1) + { + rnd = 10 + rtlRand() % 620; + bombs[i]->Enable(rnd, 0, 4, 9, rnd + 2, 0); + } + } + else + { + if (bombs[i]->cy > gun->cy + 5) + { + health -= 5; + if (explodes[R_COUNT + i]->IsEnabled() == 1) + { + explodes[R_COUNT + i]->Disable(BG_COLOR); + } + explodes[R_COUNT + i]->Enable(bombs[i]->cx, bombs[i]->cy); + bombs[i]->Disable(BG_COLOR); + } + else + { + bombs[i]->cy += B_SPEED; + bombs[i]->DrawAngle(bombs[i]->cx, 639, B_COLOR); + } + } + } +} + +void DrawRocketsAndCrosses() +{ + double a; + for (int i = 0; i < R_COUNT; i++) + { + if (crosses[i]->IsEnabled() == 1) + { + if (sqrt(((long int) (crosses[i]->x - rockets[i]->cx) * (crosses[i]->x - rockets[i]->cx)) + ((long int) (crosses[i]->y - rockets[i]->cy) * (crosses[i]->y - rockets[i]->cy))) < 5) + { + if (explodes[i]->IsEnabled() == 1) + { + explodes[i]->Disable(BG_COLOR); + } + explodes[i]->Enable(crosses[i]->x, crosses[i]->y); + crosses[i]->Disable(BG_COLOR); + rockets[i]->Disable(BG_COLOR); + } + else + { + crosses[i]->Draw(CROSS_COLOR); + if (rockets[i]->cx - crosses[i]->x == 0) + { + a = M_PI / 2; + } + else + { + a = atan((double)(rockets[i]->cy - crosses[i]->y) / (double)(rockets[i]->cx - crosses[i]->x)); + if (rockets[i]->cx - crosses[i]->x < 0) a += M_PI; + } + rockets[i]->cx = round_int(rockets[i]->cx - R_SPEED * cos(a)); + rockets[i]->cy = round_int(rockets[i]->cy - R_SPEED * sin(a)); + rockets[i]->DrawAngle(crosses[i]->x, crosses[i]->y, R_COLOR); + } + } + } +} + +void DrawExplodes() +{ + for (int i = 0; i < R_COUNT + B_COUNT; i++) + { + if (explodes[i]->IsEnabled() == 1) + { + explodes[i]->DrawNext(EXP_COLOR); + for (int j = 0; j < B_COUNT; j++) + { + if ( bombs[j]->IsEnabled() == 1 && + bombs[j]->cx > explodes[i]->cx - explodes[i]->step - 1 && bombs[j]->cx < explodes[i]->cx + explodes[i]->step + 1 && + bombs[j]->cy + 5 > explodes[i]->cy - explodes[i]->step - 1 && bombs[j]->cy + 5 < explodes[i]->cy + explodes[i]->step + 1 + ) + { + score += B_COUNT + 2; + if (explodes[R_COUNT + j]->IsEnabled() == 1) + { + explodes[R_COUNT + j]->Disable(BG_COLOR); + } + explodes[R_COUNT + j]->Enable(bombs[j]->cx, bombs[j]->cy); + bombs[j]->Disable(BG_COLOR); + } + } + } + } +} + +void OnMouseMove() +{ + Dword old_buttons = ms.buttons; + kos_GetMouseWindowXY(ms.x, ms.y); + kos_GetMouseButtonsState(ms.buttons); + if ((old_buttons & 0x00000001) == 0 && (ms.buttons & 0x00000001) == 1) + { + ms.lbclick = 1; + } + else + { + ms.lbclick = 0; + } + + + kos_WriteTextToWindow(8, 10, 0, TEXT_COLOR, "Population: %", 16); + kos_DisplayNumberToWindowBg(health, 3, 79, 10, TEXT_COLOR, BG_COLOR, nbDecimal, false); + kos_WriteTextToWindow(8, 22, 0, TEXT_COLOR, "Score:", 6); + kos_DisplayNumberToWindowBg(score, 4, 49, 22, TEXT_COLOR, BG_COLOR, nbDecimal, false); + + if (ms.x >= 0 && ms.x < WINDOW_WIDTH && ms.y >= 0 && ms.y < WINDOW_HEIGHT) + { + gun->DrawAngle(ms.x, ms.y, G_COLOR); + } + + if (HARDWARE_CURSOR == 0) + { + cursor->Draw(ms.x, ms.y, CUR_COLOR); + } + + /*if (DEBUG == 1) + { + kos_DisplayNumberToWindowBg(ms.x, 3, WINDOW_WIDTH - 30, 10, TEXT_COLOR, BG_COLOR, nbDecimal, false); + kos_DisplayNumberToWindowBg(ms.y, 3, WINDOW_WIDTH - 30, 22, TEXT_COLOR, BG_COLOR, nbDecimal, false); + kos_DisplayNumberToWindowBg(ms.buttons, 1, WINDOW_WIDTH - 30, 34, TEXT_COLOR, BG_COLOR, nbDecimal, false); + }*/ + +} + +void OnLMBClick() +{ + if (ms.y < gun->cy - 10) + { + double a; + int j = -1; + for (int i = 0; i < R_COUNT; i++) + { + if (crosses[i]->IsEnabled() == 0) + { + if (j >= -1) j = i; + } + else if (ms.x > crosses[i]->x - 10 && ms.x < crosses[i]->x + 10 && ms.y > crosses[i]->y - 10 && ms.y < crosses[i]->y + 10) + { + j = -2; + break; + } + } + if (j >= 0) + { + if (score > 0) score -= 1; + crosses[j]->Enable(ms.x, ms.y); + if (gun->cx - ms.x == 0) + { + a = M_PI/2; + } + else + { + a = atan((double)gun->cy - ms.y / (double) gun->cx - ms.x); + if (gun->cx - ms.x < 0) a += M_PI; + } + rockets[j]->Enable(round_int(gun->cx - 15 * cos(a)) - 2, round_int(gun->cy - 15 * sin(a)) - 5, 3, 6, round_int(gun->cx - 15 * cos(a)), round_int(gun->cy - 15 * sin(a))); + } + } +} + +void OnRMBClick() +{ +} + +void ChangeCursor() +{ + Dword *cur = new Dword[1024]; + for (int i = 0; i < 1024; i++) + { + cur[i] = 0x00000000; + } + if (HARDWARE_CURSOR == 1) + { + Dword cur_color = 0xFF000000 | CUR_COLOR; + cur[0 * 32 + 5] = cur_color; + cur[1 * 32 + 5] = cur_color; + cur[2 * 32 + 5] = cur_color; + cur[2 * 32 + 3] = cur_color; + cur[2 * 32 + 4] = cur_color; + cur[2 * 32 + 6] = cur_color; + cur[3 * 32 + 2] = cur_color; + cur[4 * 32 + 2] = cur_color; + cur[5 * 32 + 2] = cur_color; + cur[5 * 32 + 1] = cur_color; + cur[5 * 32 + 0] = cur_color; + + cur[5 * 32 + 5] = cur_color; + + cur[8 * 32 + 4] = cur_color; + cur[8 * 32 + 5] = cur_color; + cur[8 * 32 + 6] = cur_color; + cur[8 * 32 + 7] = cur_color; + cur[9 * 32 + 5] = cur_color; + cur[10 * 32 + 5] = cur_color; + cur[7 * 32 + 8] = cur_color; + cur[6 * 32 + 8] = cur_color; + cur[5 * 32 + 8] = cur_color; + cur[5 * 32 + 9] = cur_color; + cur[5 * 32 + 10] = cur_color; + } + cur_handle = kos_LoadMouseCursor(cur, 0x05050002); + delete[] cur; + kos_SetMouseCursor(cur_handle); +} + +void Menu() +{ + NewGame(); +} + +void NewGame() +{ + gun->DrawAngle((WINDOW_WIDTH / 2) - 5, WINDOW_HEIGHT - 20, G_COLOR); +} + +void OnStart() +{ + if (HARDWARE_CURSOR == 0) + { + cursor = new cCursor(); + } + ChangeCursor(); + + gun->Enable((WINDOW_WIDTH / 2) - 10, WINDOW_HEIGHT - 30, 10, 20, (WINDOW_WIDTH / 2) - 5, WINDOW_HEIGHT - 20); + + for (int i = 0; i < R_COUNT; i++) + { + crosses[i] = new cCross(); + rockets[i] = new cRocket(); + } + for (int i = 0; i < B_COUNT; i++) + { + bombs[i] = new cBomb(); + } + for (int i = 0; i < R_COUNT + B_COUNT; i++) + { + explodes[i] = new cExplode(); + } + + rtlSrand(kos_GetTime()); + + DrawWindow(); + kos_SetMaskForEvents(39); +} + +void OnExit() +{ + kos_WriteTextToWindow(WINDOW_WIDTH / 2 - 35, WINDOW_HEIGHT / 2 - 10, 0, TEXT_COLOR, "Game Over", 9); + + //while(kos_WaitForEvent() != 2); + kos_Pause(200); + + /*kos_DeleteMouseCursor(cur_handle); + + for (int i = 0; i < R_COUNT; i++) + { + delete crosses[i]; + delete rockets[i]; + } + for (int i = 0; i < B_COUNT; i++) + { + delete bombs[i]; + } + for (int i = 0; i < R_COUNT + B_COUNT; i++) + { + delete explodes[i]; + } + delete[] crosses; + delete[] rockets; + delete[] bombs; + delete[] explodes; + + delete gun; + delete house; + if (HARDWARE_CURSOR == 0) + { + delete cursor; + }*/ + + kos_ExitApp(); +} diff --git a/programs/games/rforces/trunk/kosFile.cpp b/programs/games/rforces/trunk/kosFile.cpp new file mode 100644 index 0000000000..1bf8c33fcd --- /dev/null +++ b/programs/games/rforces/trunk/kosFile.cpp @@ -0,0 +1,131 @@ +#include "kosSyst.h" +#include "kosfile.h" + + +CKosFile::CKosFile(char *fileName) +{ + // + this->fileInfo.bufferPtr = new Byte[FILE_BUFFER_SIZE]; + // + this->filePointer = 0; + this->bufferPointer = 0; + this->validBuffer = false; + // + strcpy( this->fileInfo.fileURL, fileName ); +} + + +CKosFile::~CKosFile(void) +{ + // + delete this->fileInfo.bufferPtr; +} + + +void CKosFile::ValidateBuffer() +{ + // + if ( this->validBuffer ) + { + // + if ( this->filePointer < this->bufferPointer + || this->filePointer >= (this->bufferPointer + FILE_BUFFER_SIZE) ) + { + // + this->validBuffer = false; + } + } +} + + +void CKosFile::UpdateBuffer(void) +{ + // + if ( ! this->validBuffer ) + { + // + this->fileInfo.OffsetLow = this->filePointer / OS_BLOCK_SIZE; + this->fileInfo.OffsetHigh = 0; + // + this->bufferPointer = this->fileInfo.OffsetLow * OS_BLOCK_SIZE; + // + this->fileInfo.dataCount = FILE_BUFFER_BLOCKS; + // + this->fileInfo.rwMode = 0; + // + Dword rr = kos_FileSystemAccess( &(this->fileInfo) ); + this->validBuffer = ( rr == 0 ); + } +} + + +int CKosFile::Seek(int seekFrom, int seekStep) +{ + // + switch ( seekFrom ) + { + // + case SEEK_SET: + // + this->filePointer = seekStep; + break; + // + case SEEK_CUR: + // + this->filePointer += seekStep; + break; + } + // + this->ValidateBuffer(); + // + return this->filePointer; +} + + +int CKosFile::Read(Byte *targetPtr, int readCount) +{ + int bufferLeast, result; + + // + result = 0; + // + do + { + // + this->UpdateBuffer(); + // + if ( ! this->validBuffer ) return result; + // + bufferLeast = FILE_BUFFER_SIZE - (this->filePointer - this->bufferPointer); + // + if ( bufferLeast > readCount ) bufferLeast = readCount; + // + if ( bufferLeast ) + { + // + memcpy( + targetPtr, + this->fileInfo.bufferPtr + (this->filePointer - this->bufferPointer), + bufferLeast + ); + // + targetPtr += bufferLeast; + readCount -= bufferLeast; + this->filePointer += bufferLeast; + // + result += bufferLeast; + } + // + this->ValidateBuffer(); + } + while ( readCount > 0 ); + // + return result; +} + + +int CKosFile::Write(Byte *sourcePtr, int writeCount) +{ + return 0; +} + diff --git a/programs/games/rforces/trunk/kosSyst.cpp b/programs/games/rforces/trunk/kosSyst.cpp new file mode 100644 index 0000000000..7f32412691 --- /dev/null +++ b/programs/games/rforces/trunk/kosSyst.cpp @@ -0,0 +1,970 @@ +#include "kosSyst.h" +#include + +#define atexitBufferSize 32 + + +char pureCallMessage[] = "PURE function call!"; + +char *kosExePath = NULL; + +// +void (__cdecl *atExitList[atexitBufferSize])(); +int atExitFnNum = 0; +// +int __cdecl atexit( void (__cdecl *func )( void )) +{ + // + if ( atExitFnNum < atexitBufferSize ) + { + // + atExitList[atExitFnNum++] = func; + return 0; + } + else + { + return 1; + } +} + + +// +Dword RandomSeed = 1; +// +void rtlSrand( Dword seed ) +{ + RandomSeed = seed; +} +// +Dword rtlRand( void ) +{ + // 0x80000776 + + Dword dwi, i; + + for ( i = 0; i < 32; i++ ) + { + + dwi = RandomSeed & 0x80000776; + + __asm{ + mov eax, dwi + mov edx, eax + bswap eax + xor eax, edx + xor al, ah + setpo al + movzx eax, al + mov dwi, eax + } + + RandomSeed = ( RandomSeed << 1 ) | ( dwi & 1 ); + } + + return RandomSeed; +} + +// +void * __cdecl memcpy( void *dst, const void *src, size_t bytesCount ) +{ + __asm{ + mov edi, dst + mov eax, dst + mov esi, src + mov ecx, bytesCount + rep movsb + } +} + +// +void memset( Byte *dst, Byte filler, Dword count ) +{ + // + __asm{ + mov edi, dst + mov al, filler + mov ecx, count + rep stosb + } +} + +// +Dword rtlInterlockedExchange( Dword *target, Dword value ) +{ +// Dword result; + + // + __asm{ + mov eax, value + mov ebx, target + xchg eax, [ebx] +// mov result, eax + } + // +// return result; +} + + +////////////////////////////////////////////////////////////////////// +// +// +// + +char * __cdecl strcpy( char *target, const char *source ) +{ + char *result = target; + + while( target[0] = source[0] ) + { + target++; + source++; + } + + return result; +} + + +////////////////////////////////////////////////////////////////////// +// +// +// + +char * __cdecl strrchr( const char * string, int c ) +{ + char *cPtr; + + // + for ( cPtr = (char *)string + strlen( string ); cPtr >= string; cPtr-- ) + { + // + if ( *cPtr == c ) return cPtr; + } + // + return NULL; +} + + +////////////////////////////////////////////////////////////////////// +// +// +// + +int __cdecl strlen( const char *line ) +{ + int i; + + for( i=0; line[i] != 0; i++ ); + return i; +} + + + +////////////////////////////////////////////////////////////////////// +// +// +// + +unsigned int num2hex( unsigned int num ) +{ + if( num < 10 ) + return num + '0'; + return num - 10 + 'A'; +} + + +////////////////////////////////////////////////////////////////////// +// +// +// + +Dword dectab[] = { 1000000000, 100000000, 10000000, 1000000, 100000, + 10000, 1000, 100, 10, 0 }; + +// +void sprintf( char *Str, char* Format, ... ) +{ + int i, fmtlinesize, j, k, flag; + Dword head, tail; + char c; + va_list arglist; + // + va_start(arglist, Format); + + // + fmtlinesize = strlen( Format ); + // + if( fmtlinesize == 0 ) return; + + // + for( i = 0, j = 0; i < fmtlinesize; i++ ) + { + // + c = Format[i]; + // + if( c != '%' ) + { + Str[j++] = c; + continue; + } + // + i++; + // + if( i >= fmtlinesize ) break; + + // + flag = 0; + // + c = Format[i]; + // + switch( c ) + { + // + case '%': + Str[j++] = c; + break; + // + case 'S': + Byte* str; + str = va_arg(arglist, Byte*); + for( k = 0; ( c = str[k] ) != 0; k++ ) + { + Str[j++] = c; + } + break; + // + case 'B': + k = va_arg(arglist, int) & 0xFF; + Str[j++] = num2hex( ( k >> 4 ) & 0xF ); + Str[j++] = num2hex( k & 0xF ); + break; + // + case 'C': + Str[j++] = va_arg(arglist, int) & 0xFF; + break; + // + case 'X': + Dword val; + val = va_arg(arglist, Dword); + for( k = 7; k >= 0; k-- ) + { + // + c = num2hex ( ( val >> (k * 4) ) & 0xF ); + // + if( c == '0' ) + { + if( flag ) Str[j++] = c; + } + else + { + flag++; + Str[j++] = c; + } + } + // + if( flag == 0 ) Str[j++] = '0'; + break; + // + case 'U': + head = va_arg(arglist, Dword); + tail = 0; + for( k = 0; dectab[k] != 0; k++ ) + { + tail = head % dectab[k]; + head /= dectab[k]; + c = head + '0'; + if( c == '0' ) + { + if( flag ) Str[j++] = c; + } + else + { + flag++; + Str[j++] = c; + } + // + head = tail; + } + // + c = head + '0'; + Str[j++] = c; + break; + // 64- + case 'Q': + unsigned int low_dword, high_dword; + low_dword = va_arg(arglist, unsigned int); + high_dword = va_arg(arglist, unsigned int); + for( k = 7; k >= 0; k-- ) + { + // + c = num2hex ( ( ( high_dword + 1) >> (k * 4) ) & 0xF ); + // + if( c == '0' ) + { + if( flag ) Str[j++] = c; + } + else + { + flag++; + Str[j++] = c; + } + } + // + for( k=7; k >= 0; k-- ) + { + // + c = num2hex ( ( low_dword >> (k * 4) ) & 0xF ); + // + if( c == '0' ) + { + if( flag ) Str[j++] = c; + } + else + { + flag++; + Str[j++] = c; + } + } + // + if( flag == 0 ) Str[j++] = '0'; + // + break; + // + default: + break; + } + } + // + Str[j] = 0; +} + + +// -1 +void kos_ExitApp() +{ + int i; + + // + for ( i = atExitFnNum - 1; i >= 0; i-- ) + { + // + atExitList[i](); + } + // + __asm{ + mov eax, -1 + int 0x40 + } +} + + +// 0 +void kos_DefineAndDrawWindow( + Word x, Word y, + Word sizeX, Word sizeY, + Byte mainAreaType, + Dword mainAreaColour, + Byte headerType, + Dword headerColour, + Dword borderColour + ) +{ + Dword arg1, arg2, arg3, arg4; + + // + arg1 = ( x << 16 ) + sizeX; + arg2 = ( y << 16 ) + sizeY; + arg3 = ( mainAreaType << 24 ) | mainAreaColour; + arg4 = ( headerType << 24 ) | headerColour; + // + __asm{ + mov eax, 0 + mov ebx, arg1 + mov ecx, arg2 + mov edx, arg3 + mov esi, arg4 + mov edi, borderColour + int 0x40 + } +} + + +// 1 +void kos_PutPixel( Dword x, Dword y, Dword colour ) +{ + // + __asm{ + mov eax, 1 + mov ebx, x + mov ecx, y + mov edx, colour + int 0x40 + } +} + + +// 2 +bool kos_GetKey( Byte &keyCode ) +{ + Dword result; + + // + __asm{ + mov eax, 2 + int 0x40 + mov result, eax + } + // + keyCode = result >> 8; + // + return ( result & 0xFF ) == 0; +} + + +// 3 +Dword kos_GetSystemClock() +{ +// Dword result; + + // + __asm{ + mov eax, 3 + int 0x40 +// mov result, eax + } + // +// return result; +} + + +// 4 +void kos_WriteTextToWindow( + Word x, + Word y, + Byte fontType, + Dword textColour, + char *textPtr, + Dword textLen + ) +{ + Dword arg1, arg2; + + // + arg1 = ( x << 16 ) | y; + arg2 = ( fontType << 24 ) | textColour; + // + __asm{ + mov eax, 4 + mov ebx, arg1 + mov ecx, arg2 + mov edx, textPtr + mov esi, textLen + int 0x40 + } +} + + +// 5 , +void kos_Pause( Dword value ) +{ + // + __asm{ + mov eax, 5 + mov ebx, value + int 0x40 + } +} + + +// 7 +void kos_PutImage( RGB * imagePtr, Word sizeX, Word sizeY, Word x, Word y ) +{ + Dword arg1, arg2; + + // + arg1 = ( sizeX << 16 ) | sizeY; + arg2 = ( x << 16 ) | y; + // + __asm{ + mov eax, 7 + mov ebx, imagePtr + mov ecx, arg1 + mov edx, arg2 + int 0x40 + } +} + + + +// 8 +void kos_DefineButton( Word x, Word y, Word sizeX, Word sizeY, Dword buttonID, Dword colour ) +{ + Dword arg1, arg2; + + // + arg1 = ( x << 16 ) | sizeX; + arg2 = ( y << 16 ) | sizeY; + // + __asm{ + mov eax, 8 + mov ebx, arg1 + mov ecx, arg2 + mov edx, buttonID + mov esi, colour + int 0x40 + } +} + + +// 9 - +Dword kos_ProcessInfo( sProcessInfo *targetPtr, Dword processID ) +{ +// Dword result; + + // + __asm{ + mov eax, 9 + mov ebx, targetPtr + mov ecx, processID + int 0x40 +// mov result, eax + } + // +// return result; +} + + +// 10 +Dword kos_WaitForEvent() +{ +// Dword result; + + __asm{ + mov eax, 10 + int 0x40 +// mov result, eax + } + +// return result; +} + + +// 11 +Dword kos_CheckForEvent() +{ +// Dword result; + + __asm{ + mov eax, 11 + int 0x40 +// mov result, eax + } + +// return result; +} + + +// 12 +void kos_WindowRedrawStatus( Dword status ) +{ + __asm{ + mov eax, 12 + mov ebx, status + int 0x40 + } +} + + +// 13 +void kos_DrawBar( Word x, Word y, Word sizeX, Word sizeY, Dword colour ) +{ + Dword arg1, arg2; + + // + arg1 = ( x << 16 ) | sizeX; + arg2 = ( y << 16 ) | sizeY; + // + __asm{ + mov eax, 13 + mov ebx, arg1 + mov ecx, arg2 + mov edx, colour + int 0x40 + } +} + + +// 17 +bool kos_GetButtonID( Dword &buttonID ) +{ + Dword result; + + // + __asm{ + mov eax, 17 + int 0x40 + mov result, eax + } + // + buttonID = result >> 8; + // + return (result & 0xFF) == 0; +} + + +// 23 +Dword kos_WaitForEvent( Dword timeOut ) +{ +// Dword result; + + __asm{ + mov eax, 23 + mov ebx, timeOut + int 0x40 +// mov result, eax + } + +// return result; +} + +// 26.9 +Dword kos_GetTime() +{ + __asm{ + mov eax, 26 + mov ebx, 9 + int 0x40 + } +} + +// 37 "" +void kos_GetMouseState( Dword & buttons, int & cursorX, int & cursorY ) +{ + Dword mB; + Word curX; + Word curY; + sProcessInfo sPI; + + // + __asm{ + mov eax, 37 + mov ebx, 0 + int 0x40 + mov curY, ax + shr eax, 16 + mov curX, ax + mov eax, 37 + mov ebx, 2 + int 0x40 + mov mB, eax + } + // + kos_ProcessInfo( &sPI ); + // + buttons = mB; + cursorX = curX - sPI.processInfo.x_start; + cursorY = curY - sPI.processInfo.y_start; +} + +// 37.1 "" +void kos_GetMouseWindowXY( int & cursorX, int & cursorY ) +{ + Word curX; + Word curY; + + __asm{ + mov eax, 37 + mov ebx, 1 + int 0x40 + + mov ebx, eax + shr eax, 16 + and ebx, 0xffff + + mov curX, ax + mov curY, bx + } + + cursorX = curX; + cursorY = curY; +} + +// 37.2 "" +void kos_GetMouseButtonsState( Dword & buttons ) +{ + Dword mB; + + __asm{ + mov eax, 37 + mov ebx, 2 + int 0x40 + mov mB, eax + } + + buttons = mB; +} + +// 37.4 "" +Dword * kos_LoadMouseCursor( Dword * cursor, Dword loadstate ) +{ + //Dword handle; + __asm{ + mov eax, 37 + mov ebx, 4 + mov edx, loadstate + mov ecx, cursor + int 0x40 + //mov handle, eax + } + //return handle; +} + +// 37.5 "" +Dword * kos_SetMouseCursor( Dword * handle ) +{ + //Dword handle; + __asm{ + mov eax, 37 + mov ebx, 5 + mov ecx, handle + int 0x40 + //mov handle, eax + } + //return handle; +} + +// 37.6 "" +void kos_DeleteMouseCursor( Dword * handle ) +{ + __asm{ + mov eax, 37 + mov ebx, 6 + mov ecx, handle + int 0x40 + } +} + +// 38 +void kos_DrawLine( Word x1, Word y1, Word x2, Word y2, Dword colour ) +{ + Dword arg1, arg2; + + // + arg1 = ( x1 << 16 ) | x2; + arg2 = ( y1 << 16 ) | y2; + // + __asm{ + mov eax, 38 + mov ebx, arg1 + mov ecx, arg2 + mov edx, colour + int 0x40 + } +} + + +// 40 +void kos_SetMaskForEvents( Dword mask ) +{ + // + __asm{ + mov eax, 40 + mov ebx, mask + int 0x40 + } +} + + +// 47 +void kos_DisplayNumberToWindow( + Dword value, + Dword digitsNum, + Word x, + Word y, + Dword colour, + eNumberBase nBase, + bool valueIsPointer + ) +{ + Dword arg1, arg2; + + // + arg1 = ( valueIsPointer ? 1 : 0 ) | + ( ((Byte)nBase) << 8 ) | + ( ( digitsNum & 0x1F ) << 16 ); + arg2 = ( x << 16 ) | y; + // + __asm{ + mov eax, 47 + mov ebx, arg1 + mov ecx, value + mov edx, arg2 + mov esi, colour + int 0x40 + } +} + +// 47 c +void kos_DisplayNumberToWindowBg( + Dword value, + Dword digitsNum, + Word x, + Word y, + Dword colour, + Dword bgcolour, + eNumberBase nBase, + bool valueIsPointer + ) +{ + Dword arg1, arg2; + + // + arg1 = ( valueIsPointer ? 1 : 0 ) | + ( ((Byte)nBase) << 8 ) | + ( ( digitsNum & 0x1F ) << 16 ); + arg2 = ( x << 16 ) | y; + // + __asm{ + mov eax, 47 + mov ebx, arg1 + mov ecx, value + mov edx, arg2 + mov esi, colour + or esi, 0x40000000 + mov edi, bgcolour + int 0x40 + } +} + + +// 70 +Dword kos_FileSystemAccess( kosFileInfo *fileInfo ) +{ +// Dword result; + + // + __asm{ + mov eax, 70 + mov ebx, fileInfo + int 0x40 +// mov result, eax + } + // +// return result; +} + + +// 63 +void kos_DebugOutChar( char ccc ) +{ + // + __asm{ + mov eax, 63 + mov ebx, 1 + mov cl, ccc + int 0x40 + } +} + + +// 66 +void kos_SetKeyboardDataMode( Dword mode ) +{ + // + __asm{ + mov eax, 66 + mov ebx, 1 + mov ecx, mode + int 0x40 + } +} + + +// +void rtlDebugOutString( char *str ) +{ + // + for ( ; str[0] != 0; str++ ) + { + kos_DebugOutChar( str[0] ); + } + // + kos_DebugOutChar( 13 ); + kos_DebugOutChar( 10 ); +} + + +// 64 , +bool kos_ApplicationMemoryResize( Dword targetSize ) +{ + Dword result; + + // + __asm{ + mov eax, 64 + mov ebx, 1 + mov ecx, targetSize + int 0x40 + mov result, eax + } + // + return result == 0; +} + + +// 67 , == -1 +void kos_ChangeWindow( Dword x, Dword y, Dword sizeX, Dword sizeY ) +{ + // + __asm{ + mov eax, 67 + mov ebx, x + mov ecx, y + mov edx, sizeX + mov esi, sizeY + int 0x40 + } +} + + + +// +int __cdecl _purecall() +{ + rtlDebugOutString( pureCallMessage ); + kos_ExitApp(); + return 0; +} + + +// +// +//#pragma section(".CRT$XCA",long,read,write) +//#pragma section(".CRT$XCZ",long,read,write) +#pragma data_seg(".CRT$XCA") +#pragma data_seg(".CRT$XCZ") +typedef void (__cdecl *_PVFV)(void); +__declspec(allocate(".CRT$XCA")) _PVFV __xc_a[1] = { NULL }; +__declspec(allocate(".CRT$XCZ")) _PVFV __xc_z[1] = { NULL }; +// +#pragma comment(linker, "/merge:.CRT=.rdata") +// +void crtStartUp() +{ + // , NULL' + for ( _PVFV *pbegin = __xc_a; pbegin < __xc_z; pbegin++ ) + { + // + if ( *pbegin != NULL ) + (**pbegin)(); + } + // + rtlSrand( kos_GetSystemClock() ); + // + kosExePath = *((char **)0x20); + // + kos_Main(); + // + kos_ExitApp(); +} + + diff --git a/programs/games/rforces/trunk/kosSyst.h b/programs/games/rforces/trunk/kosSyst.h new file mode 100644 index 0000000000..a69c4b8bc5 --- /dev/null +++ b/programs/games/rforces/trunk/kosSyst.h @@ -0,0 +1,220 @@ +typedef unsigned __int32 Dword; +typedef unsigned __int16 Word; +typedef unsigned __int8 Byte; +//typedef unsigned __int32 size_t; + +#define NULL 0 + +#define MAX_PATH 256 + +#define FO_READ 0 +#define FO_WRITE 2 + +#define EM_WINDOW_REDRAW 1 +#define EM_KEY_PRESS 2 +#define EM_BUTTON_CLICK 4 +#define EM_APP_CLOSE 8 +#define EM_DRAW_BACKGROUND 16 +#define EM_MOUSE_EVENT 32 +#define EM_IPC 64 +#define EM_NETWORK 256 + +#define KM_CHARS 0 +#define KM_SCANS 1 + +#define WRS_BEGIN 1 +#define WRS_END 2 + +#define PROCESS_ID_SELF -1 + +#define abs(a) (a<0?0-a:a) + + +struct kosFileInfo +{ + Dword rwMode; + Dword OffsetLow; + Dword OffsetHigh; + Dword dataCount; + Byte *bufferPtr; + char fileURL[MAX_PATH]; +}; + + +struct RGB +{ + Byte b; + Byte g; + Byte r; + // + RGB() {}; + // + RGB( Dword value ) + { + r = value >> 16; + g = value >> 8; + b = value; + }; + // + bool operator != ( RGB &another ) + { + return this->b != another.b || this->g != another.g || this->r != another.r; + }; + // + bool operator == ( RGB &another ) + { + return this->b == another.b && this->g == another.g && this->r == another.r; + }; +}; + + +union sProcessInfo +{ + Byte rawData[1024]; + struct + { + Dword cpu_usage; + Word window_stack_position; + Word window_stack_value; + Word reserved1; + char process_name[12]; + Dword memory_start; + Dword used_memory; + Dword PID; + Dword x_start; + Dword y_start; + Dword x_size; + Dword y_size; + Word slot_state; + } processInfo; +}; + +// +extern char *kosExePath; + +// +void crtStartUp(); +// +int __cdecl _purecall(); +// +int __cdecl atexit( void (__cdecl *func )( void )); +// +void rtlSrand( Dword seed ); +Dword rtlRand( void ); +// +char * __cdecl strcpy( char *target, const char *source ); +int __cdecl strlen( const char *line ); +char * __cdecl strrchr( const char * string, int c ); +// +void * __cdecl memcpy( void *dst, const void *src, size_t bytesCount ); +// +void memset( Byte *dst, Byte filler, Dword count ); +// +void sprintf( char *Str, char* Format, ... ); +// +Dword rtlInterlockedExchange( Dword *target, Dword value ); +// -1 +void kos_ExitApp(); +// 0 +void kos_DefineAndDrawWindow( + Word x, Word y, + Word sizeX, Word sizeY, + Byte mainAreaType, Dword mainAreaColour, + Byte headerType, Dword headerColour, + Dword borderColour + ); +// 1 +void kos_PutPixel( Dword x, Dword y, Dword colour ); +// 2 +bool kos_GetKey( Byte &keyCode ); +// 3 +Dword kos_GetSystemClock(); +// 4 +void kos_WriteTextToWindow( + Word x, Word y, + Byte fontType, + Dword textColour, + char *textPtr, + Dword textLen + ); +// 7 +void kos_PutImage( RGB * imagePtr, Word sizeX, Word sizeY, Word x, Word y ); +// 8 +void kos_DefineButton( Word x, Word y, Word sizeX, Word sizeY, Dword buttonID, Dword colour ); +// 5 , +void kos_Pause( Dword value ); +// 9 +Dword kos_ProcessInfo( sProcessInfo *targetPtr, Dword processID = PROCESS_ID_SELF ); +// 10 +Dword kos_WaitForEvent(); +// 11 +Dword kos_CheckForEvent(); +// 12 +void kos_WindowRedrawStatus( Dword status ); +// 13 +void kos_DrawBar( Word x, Word y, Word sizeX, Word sizeY, Dword colour ); +// 17 +bool kos_GetButtonID( Dword &buttonID ); +// 23 +Dword kos_WaitForEvent( Dword timeOut ); +// 26.9 +Dword kos_GetTime(); +// +enum eNumberBase +{ + nbDecimal = 0, + nbHex, + nbBin +}; +// 37 "" +void kos_GetMouseState( Dword & buttons, int & cursorX, int & cursorY ); +// 37.1 "" +void kos_GetMouseWindowXY( int & cursorX, int & cursorY ); +// 37.2 "" +void kos_GetMouseButtonsState( Dword & buttons ); +// 37.4 "" +Dword * kos_LoadMouseCursor( Dword * cursor, Dword loadstate ); +// 37.5 "" +Dword * kos_SetMouseCursor( Dword * handle ); +// 37.6 "" +void kos_DeleteMouseCursor( Dword * handle ); +// 38 +void kos_DrawLine( Word x1, Word y1, Word x2, Word y2, Dword colour ); +// 40 +void kos_SetMaskForEvents( Dword mask ); +// 47 +void kos_DisplayNumberToWindow( + Dword value, + Dword digitsNum, + Word x, + Word y, + Dword colour, + eNumberBase nBase = nbDecimal, + bool valueIsPointer = false + ); +// 47 c +void kos_DisplayNumberToWindowBg( + Dword value, + Dword digitsNum, + Word x, + Word y, + Dword colour, + Dword bgcolour, + eNumberBase nBase = nbDecimal, + bool valueIsPointer = false + ); +// 58 +Dword kos_FileSystemAccess( kosFileInfo *fileInfo ); +// 63 +void kos_DebugOutChar( char ccc ); +// +void rtlDebugOutString( char *str ); +// 64 , == -1 +void kos_ChangeWindow( Dword x, Dword y, Dword sizeX, Dword sizeY ); +// 67 , +bool kos_ApplicationMemoryResize( Dword targetSize ); +// 66 +void kos_SetKeyboardDataMode( Dword mode ); + +// +void kos_Main(); diff --git a/programs/games/rforces/trunk/mcsmemm.cpp b/programs/games/rforces/trunk/mcsmemm.cpp new file mode 100644 index 0000000000..20feab80f6 --- /dev/null +++ b/programs/games/rforces/trunk/mcsmemm.cpp @@ -0,0 +1,329 @@ +// memman.cpp : Defines the entry point for the console application. +// + +#include "kosSyst.h" +#include "mcsmemm.h" + + +void * __cdecl operator new ( size_t count, size_t element_size ) +{ + return allocmem( (Dword)(count * element_size) ); +} + +void * __cdecl operator new [] ( size_t amount ) +{ + return allocmem( (Dword)amount ); +} + +void * __cdecl operator new ( size_t amount ) +{ + return allocmem( (Dword)amount ); +} + +void __cdecl operator delete ( void *pointer ) +{ + if ( pointer != NULL ) freemem( pointer ); +} + +void __cdecl operator delete [] ( void *pointer ) +{ + if ( pointer != NULL ) freemem( pointer ); +} + + +// +Dword mmMutex = FALSE; +MemBlock *rootfree = NULL; +MemBlock *rootuser = NULL; +bool mmInitialized = false; +Byte *mmHeapTop = NULL; + + +// +Byte * AllocMemFromSystem( Dword reqSize ) +{ + Byte *result; + sProcessInfo pInfo; + + // + if ( mmInitialized ) + { + result = mmHeapTop; + } + else + { + // + kos_ProcessInfo( &pInfo ); + // + result = (Byte *)(pInfo.processInfo.used_memory + 1); + // + mmInitialized = true; + } + // + if ( ! kos_ApplicationMemoryResize( ((Dword)result) + reqSize ) ) + { + result = NULL; + } + // + mmHeapTop = result + reqSize; + // + return result; +} + + +// +Byte *allocmem( Dword reqsize ) +{ + MemBlock *BlockForCheck; + MemBlock *LastKnownGood; + Dword tail; + Byte *address; + + // + if( ( tail = reqsize % SIZE_ALIGN ) != 0 ) + { + reqsize += SIZE_ALIGN - tail; + } + + LastKnownGood = NULL; + + // + while ( rtlInterlockedExchange( &mmMutex, TRUE ) ) + { + // + kos_Pause( 1 ); + } + + // + if( rootfree != NULL ) + { + for ( BlockForCheck = rootfree; ; BlockForCheck = BlockForCheck->Next ) + { + if ( BlockForCheck->Size >= reqsize ) + { + // + if ( LastKnownGood != NULL ) + { + if ( LastKnownGood->Size >= BlockForCheck->Size ) + LastKnownGood = BlockForCheck; + } + else + LastKnownGood = BlockForCheck; + if ( LastKnownGood->Size == reqsize ) + break; + } + if ( BlockForCheck->Next == NULL ) + break; + } + } + + if ( LastKnownGood != NULL ) + { + // + tail = LastKnownGood->Size - reqsize; + if ( tail >= ( sizeof(MemBlock) + SIZE_ALIGN ) ) + { + // + BlockForCheck = (MemBlock *)( ( (Byte *)LastKnownGood ) + tail ); + BlockForCheck->Size = reqsize; + // + if( rootuser != NULL ) + { + BlockForCheck->Next = rootuser; + rootuser->Previous = BlockForCheck; + BlockForCheck->Previous = NULL; + rootuser = BlockForCheck; + } + else + { + rootuser = BlockForCheck; + BlockForCheck->Next = NULL; + BlockForCheck->Previous = NULL; + } + + // + LastKnownGood->Size = tail - sizeof(MemBlock); + address = ( (Byte *)BlockForCheck ) + sizeof(MemBlock); + + // + rtlInterlockedExchange( &mmMutex, FALSE ); + + return address; + } + else + { + // + // + if ( LastKnownGood->Previous != NULL ) + { + LastKnownGood->Previous->Next = LastKnownGood->Next; + } + else + { + // + rootfree = LastKnownGood->Next; + } + if( LastKnownGood->Next != NULL ) + { + LastKnownGood->Next->Previous = LastKnownGood->Previous; + } + // + if( rootuser != NULL ) + { + LastKnownGood->Next = rootuser; + rootuser->Previous = LastKnownGood; + LastKnownGood->Previous = NULL; + rootuser = LastKnownGood; + } + else + { + rootuser = LastKnownGood; + LastKnownGood->Next = NULL; + LastKnownGood->Previous = NULL; + } + // + address = ( (Byte *)LastKnownGood ) + sizeof(MemBlock); + + // + rtlInterlockedExchange( &mmMutex, FALSE ); + + return address; + } + } + else + { + // + LastKnownGood = (MemBlock *)AllocMemFromSystem( reqsize + sizeof(MemBlock) ); + // + if( LastKnownGood != NULL ) + { + LastKnownGood->Size = reqsize; + // + if( rootuser != NULL ) + { + LastKnownGood->Next = rootuser; + rootuser->Previous = LastKnownGood; + LastKnownGood->Previous = NULL; + rootuser = LastKnownGood; + } + else + { + rootuser = LastKnownGood; + LastKnownGood->Next = NULL; + LastKnownGood->Previous = NULL; + } + address = ( (Byte *)LastKnownGood ) + sizeof(MemBlock); + + // + rtlInterlockedExchange( &mmMutex, FALSE ); + + return address; + } + } + + // + rtlInterlockedExchange( &mmMutex, FALSE ); + + // + rtlDebugOutString( "allocmem failed." ); + kos_ExitApp(); + // + return NULL; +} + +// +Dword freemem( void *vaddress ) +{ + Dword result; + + Byte *checknext, *address = (Byte *)vaddress; + + // + while ( rtlInterlockedExchange( &mmMutex, TRUE ) ) + { + // + kos_Pause( 1 ); + } + + MemBlock *released = (MemBlock *)( address - sizeof(MemBlock) ); + + result = released->Size; + + // + if ( released->Previous != NULL ) + { + released->Previous->Next = released->Next; + } + else + { + rootuser = released->Next; + } + if ( released->Next != NULL ) + { + released->Next->Previous = released->Previous; + } + // + released->Next = rootfree; + released->Previous = NULL; + rootfree = released; + if ( released->Next != NULL ) + { + released->Next->Previous = released; + } + + // + checknext = (Byte *)(rootfree) + ( rootfree->Size + sizeof(MemBlock) ); + // + for ( released = rootfree->Next; released != NULL; released = released->Next ) + { + if ( checknext == (Byte *)released ) + { + // + // + released->Previous->Next = released->Next; + if( released->Next != NULL ) + { + released->Next->Previous = released->Previous; + } + // + rootfree->Size += released->Size + sizeof(MemBlock); + break; + } + } + // , . + checknext = (Byte *)(rootfree); + // + if ( released == NULL ) + { + for ( released = rootfree->Next; released != NULL; released = released->Next ) + { + if ( checknext == (Byte *)released + ( released->Size + sizeof(MemBlock) ) ) + { + // + // + released->Size += rootfree->Size + sizeof(MemBlock); + // + released->Previous->Next = released->Next; + if ( released->Next != NULL ) + { + released->Next->Previous = released->Previous; + } + // + if ( rootfree->Next != NULL ) + { + rootfree->Next->Previous = released; + } + released->Next = rootfree->Next; + released->Previous = NULL; + rootfree = released; + break; + } + } + } + + // + rtlInterlockedExchange( &mmMutex, FALSE ); + + return result; +} + diff --git a/programs/games/rforces/trunk/mcsmemm.h b/programs/games/rforces/trunk/mcsmemm.h new file mode 100644 index 0000000000..42d61eaadb --- /dev/null +++ b/programs/games/rforces/trunk/mcsmemm.h @@ -0,0 +1,28 @@ +// + +struct MemBlock +{ + Dword Size; + Dword Addr; + MemBlock *Next; + MemBlock *Previous; +}; + + +#define INITIALQUEUESIZE (32 * 4) + +#define FALSE 0 +#define TRUE -1 + +#define MB_FREE 0 +#define MB_USER 1 + +#define SIZE_ALIGN 4 + + + +Byte *allocmem( Dword reqsize ); +Dword freemem( void *vaddress ); + + + diff --git a/programs/games/rforces/trunk/mymath.h b/programs/games/rforces/trunk/mymath.h new file mode 100644 index 0000000000..6d911d875c --- /dev/null +++ b/programs/games/rforces/trunk/mymath.h @@ -0,0 +1,95 @@ +/* Rocket Forces + * Filename: mymath.h + * Version 0.1 + * Copyright (c) Serial 2007 + */ + + +extern "C" int _fltused = 0; + +#define M_PI 3.14159265358979323846 + +inline double sin(double x) +{ + __asm fld x + __asm fsin +} + +inline double cos(double x) +{ + __asm fld x + __asm fcos +} + +inline double sqrt(double x) +{ + __asm fld x + __asm fsqrt +} + +inline double acos(double x) +{ + __asm fld x + __asm fld st(0) + __asm fmul st,st(1) + __asm fld1 + __asm fsubrp st(1),st(0) + __asm fsqrt + __asm fxch st(1) + __asm fpatan +} + +inline double atan(double x) +{ + double res = acos(1 / sqrt(1 + x * x)); + if (x < 0) + { + res *= -1; + } + return res; +} + +inline int round_int(double x) +{ + int i; + static const float round_to_nearest = 0.5f; + __asm + { + fld x + fadd st, st(0) + fadd round_to_nearest + fistp i + sar i, 1 + } + return i; +} + +inline int floor_int(double x) +{ + int i; + static const float round_toward_m_i = -0.5f; + __asm + { + fld x + fadd st, st (0) + fadd round_toward_m_i + fistp i + sar i, 1 + } + return i; +} + +inline int ceil_int(double x) +{ + int i; + static const float round_toward_p_i = -0.5f; + __asm + { + fld x + fadd st, st (0) + fsubr round_toward_p_i + fistp i + sar i, 1 + } + return (-i); +} diff --git a/programs/games/rforces/trunk/objects.h b/programs/games/rforces/trunk/objects.h new file mode 100644 index 0000000000..c9c36a3c71 --- /dev/null +++ b/programs/games/rforces/trunk/objects.h @@ -0,0 +1,466 @@ +/* Rocket Forces + * Filename: objects.h + * Version 0.1 + * Copyright (c) Serial 2007 + */ + + +void ppx(int x, int y, int color); +void pline(int x1, int y1, int x2, int y2, int color); +void draw4(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4, int color); + + +class cBuilding +{ +public: + void Draw(int x, int y, int color) + { + draw4(x, y, x+10, y-5, x+20, y, x, y, color); + draw4(x, y, x+20, y, x+20, y+11, x, y+11, color); + draw4(x+3, y+3, x+8, y+3, x+8, y+8, x+3, y+8, color); + draw4(x+15, y+3, x+20, y+3, x+20, y+11, x+15, y+11, color); + } +}; + +class cCursor +{ +public: + cCursor() + { + cx = -1; + cy = -1; + } + void Delete(int color) + { + ppx(cx, cy, color); + + ppx(cx-3, cy, color); + ppx(cx-4, cy, color); + ppx(cx-5, cy, color); + ppx(cx, cy-3, color); + ppx(cx, cy-4, color); + ppx(cx, cy-5, color); + ppx(cx-1, cy-3, color); + ppx(cx-2, cy-3, color); + ppx(cx-3, cy-3, color); + ppx(cx-3, cy-2, color); + ppx(cx-3, cy-1, color); + ppx(cx+1, cy-3, color); + + ppx(cx+3, cy, color); + ppx(cx+4, cy, color); + ppx(cx+5, cy, color); + ppx(cx, cy+3, color); + ppx(cx, cy+4, color); + ppx(cx, cy+5, color); + ppx(cx+1, cy+3, color); + ppx(cx+2, cy+3, color); + ppx(cx+3, cy+3, color); + ppx(cx+3, cy+2, color); + ppx(cx+3, cy+1, color); + ppx(cx+1, cy-3, color); + ppx(cx-1, cy+3, color); + } + void Draw(int x, int y, int color) + { + if (cx!=x || cy!=y) + { + Delete(BG_COLOR); + cx = x; + cy = y; + ppx(cx, cy, color); + + ppx(cx-3, cy, color); + ppx(cx-4, cy, color); + ppx(cx-5, cy, color); + ppx(cx, cy-3, color); + ppx(cx, cy-4, color); + ppx(cx, cy-5, color); + ppx(cx-1, cy-3, color); + ppx(cx-2, cy-3, color); + //ppx(cx-3, cy-3, color); + ppx(cx-3, cy-2, color); + ppx(cx-3, cy-1, color); + ppx(cx+1, cy-3, color); + + ppx(cx+3, cy, color); + ppx(cx+4, cy, color); + ppx(cx+5, cy, color); + ppx(cx, cy+3, color); + ppx(cx, cy+4, color); + ppx(cx, cy+5, color); + ppx(cx+1, cy+3, color); + ppx(cx+2, cy+3, color); + //ppx(cx+3, cy+3, color); + ppx(cx+3, cy+2, color); + ppx(cx+3, cy+1, color); + ppx(cx+1, cy-3, color); + ppx(cx-1, cy+3, color); + } + } +private: + int cx, cy; +}; + +class cExplode +{ +public: + cExplode() + { + cx = -1; + cy = -1; + } + void Enable(int cx, int cy) + { + step = 1; + cExplode::cx = cx; + cExplode::cy = cy; + } + int IsEnabled(void) + { + if (cx==-1 && cy==-1) + { + return 0; + } + else + { + return 1; + } + } + void Draw(int r, int color) + { + int d=3-2*r, x=-1, y=r; + while (x++=EXP_RAD) + { + Disable(BG_COLOR); + } + else + { + Draw(step, BG_COLOR); + Draw(++step, color); + } + } + void Disable(int color) + { + Draw(step, color); + cx = -1; + cy = -1; + } + int cx, cy; + int step; +}; + +class cRocket +{ +public: + cRocket() + { + cx = -1; + cy = -1; + } + void Enable(int x, int y, int width, int height, int cx, int cy) + { + coord[0][0] = x; + coord[0][1] = y; + coord[1][0] = x+width; + coord[1][1] = y; + coord[2][0] = x+width; + coord[2][1] = y+height; + coord[3][0] = x; + coord[3][1] = y+height; + cRocket::cx = cx; + cRocket::cy = cy; + for (int j=0; j<4; j++) + { + dist[j] = sqrt((double)((coord[j][0]-cx)*(coord[j][0]-cx)+(coord[j][1]-cy)*(coord[j][1]-cy))); + fi[j] = acos((coord[j][0]-cx)/dist[j]); + if (coord[j][1]0; i--) + { + fire[i][0] = fire[i-1][0]; + fire[i][1] = fire[i-1][1]; + } + fire[0][0] = cx; + fire[0][1] = cy; + for (int i=1; i<4; i++) + { + if (fire[i][0]!=-1 || fire[i][1]!=-1) ppx(fire[i][0], fire[i][1], SMOKE_COLOR); + } + } + void Disable(int color) + { + for (int i=0; i<4; i++) + { + ppx(fire[i][0], fire[i][1], color); + fire[i][0] = 0; + fire[i][1] = 0; + } + Draw(color); + cx = -1; + cy = -1; + } + int cx, cy; + protected: + int coord[4][2]; + double dist[4]; + double fi[4]; + int fire[4][2]; +}; + +class cBomb: public cRocket +{ +public: + void Draw(int color) + { + draw4(coord[0][0], coord[0][1], coord[1][0], coord[1][1], coord[2][0], coord[2][1], coord[3][0], coord[3][1], color); + ppx(cx-1, coord[2][1]+1, color); + ppx(cx, coord[2][1]+1, color); + ppx(cx+1, coord[2][1]+1, color); + for (int i=1; i<4; i++) + { + if (fire[i][0]!=-1 || fire[i][1]!=-1) + { + if (i==1) + { + ppx(fire[i][0]-1, fire[i][1], BG_COLOR); + ppx(fire[i][0]+1, fire[i][1], BG_COLOR); + } + else + { + ppx(fire[i][0], fire[i][1], BG_COLOR); + } + } + } + } + void DrawAngle(int mx, int my, int color) + { + // Delete old rectangle + Draw(BG_COLOR); + + // Draw new rectangle + for (int j=0; j<4; j++) + { + coord[j][1] += B_SPEED; + } + draw4(coord[0][0], coord[0][1], coord[1][0], coord[1][1], coord[2][0], coord[2][1], coord[3][0], coord[3][1], color); + ppx(cx-1, coord[2][1]+1, color); + ppx(cx, coord[2][1]+1, color); + ppx(cx+1, coord[2][1]+1, color); + for (int i=3; i>0; i--) + { + fire[i][0] = fire[i-1][0]; + fire[i][1] = fire[i-1][1]; + } + fire[0][0] = cx; + fire[0][1] = cy; + for (int i=1; i<4; i++) + { + if (fire[i][0]!=-1 || fire[i][1]!=-1) + { + if (i==1) + { + ppx(fire[i][0]-1, fire[i][1], SMOKE_COLOR); + ppx(fire[i][0]+1, fire[i][1], SMOKE_COLOR); + } + else + { + ppx(fire[i][0], fire[i][1], SMOKE_COLOR); + } + } + } + } + void Disable(int color) + { + for (int i=0; i<4; i++) + { + ppx(fire[i][0], fire[i][1], color); + fire[i][0] = 0; + fire[i][1] = 0; + } + Draw(color); + cx = -1; + cy = -1; + } +}; + +class cGun: public cRocket +{ +public: + void Enable(int x, int y, int width, int height, int cx, int cy) + { + old_mx = -1; + old_my = -1; + coord[0][0] = x; + coord[0][1] = y; + coord[1][0] = x+width; + coord[1][1] = y; + coord[2][0] = x+width; + coord[2][1] = y+height; + coord[3][0] = x; + coord[3][1] = y+height; + cRocket::cx = cx; + cRocket::cy = cy; + for (int j=0; j<4; j++) + { + dist[j] = sqrt((double)((coord[j][0]-cx)*(coord[j][0]-cx)+(coord[j][1]-cy)*(coord[j][1]-cy))); + fi[j] = acos((coord[j][0]-cx)/dist[j]); + if (coord[j][1]= 0 && x < WINDOW_WIDTH && y >= 0 && y < WINDOW_HEIGHT) kos_PutPixel(x, y, color); +} + +void pline(int x1, int y1, int x2, int y2, int color) +{ + kos_DrawLine(x1, y1, x2, y2, color); +} + + +void draw4(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4, int color) +{ + pline(x1, y1, x2, y2, color); + pline(x2, y2, x3, y3, color); + pline(x3, y3, x4, y4, color); + pline(x4, y4, x1, y1, color); +} diff --git a/programs/games/rforces/trunk/pe2kos.exe b/programs/games/rforces/trunk/pe2kos.exe new file mode 100644 index 0000000000..bef0e7ce2d Binary files /dev/null and b/programs/games/rforces/trunk/pe2kos.exe differ diff --git a/programs/games/rforces/trunk/properties.h b/programs/games/rforces/trunk/properties.h new file mode 100644 index 0000000000..2d2b2ee6f1 --- /dev/null +++ b/programs/games/rforces/trunk/properties.h @@ -0,0 +1,46 @@ +/* Rocket Forces + * Filename: properties.h + * Version 0.1 + * Copyright (c) Serial 2007 + */ + + +// Color defines +#define BLACK 0x00000000 +#define BLUE 0x000000FF +#define GREEN 0x0000FF00 +#define RED 0x00FF0000 +#define LIGHTGRAY 0x00C0C0C0 +#define DARKGRAY 0x00808080 +#define YELLOW 0x00FFFF00 +#define WHITE 0x00FFFFFF + +// Visual properties +#define GAME_NAME "Rocket Forces v0.1 (F2 - new game, Esc - exit) " +#define BG_COLOR BLACK +#define TEXT_COLOR WHITE +#define CUR_COLOR GREEN +#define CROSS_COLOR RED +#define G_COLOR WHITE +#define R_COLOR GREEN +#define B_COLOR BLUE +#define EXP_COLOR YELLOW +#define H_COLOR LIGHTGRAY +#define SMOKE_COLOR LIGHTGRAY + +// Game properties +// R == Rocket +// B == Bomb +// EXP == Explode +int R_COUNT = 6; +int R_SPEED = 9; +int B_COUNT = 5; +int B_SPEED = 4; +int B_POSSIBILITY = 200; +int EXP_RAD = 12; +int FRAME_TIME = 5; +int HARDWARE_CURSOR = 0; +int DEBUG = 0; + +#define WINDOW_WIDTH 640 +#define WINDOW_HEIGHT 480 diff --git a/programs/games/rforces/trunk/rforces.cpp b/programs/games/rforces/trunk/rforces.cpp new file mode 100644 index 0000000000..ead1855cc8 --- /dev/null +++ b/programs/games/rforces/trunk/rforces.cpp @@ -0,0 +1,379 @@ +/* Rocket Forces + * Filename: rforces.cpp + * Version 0.1.1 + * Copyright (c) Serial 2007 + */ + + +#include + +#include "kosSyst.h" +#include "kosFile.h" +#include "mymath.h" +#include "properties.h" +#include "objects.h" +#include "rforces.h" + + +const char header[] = GAME_NAME; +cCursor *cursor; +cGun *gun = new cGun; +cCross **crosses = new cCross*[R_COUNT]; +cRocket **rockets = new cRocket*[R_COUNT]; +cBomb **bombs = new cBomb*[B_COUNT]; +cExplode **explodes = new cExplode*[R_COUNT + B_COUNT]; +cBuilding *house = new cBuilding(); +Dword *cur_handle; +int score, health; + +struct MouseState +{ + int x, y, lbclick; + Dword buttons; +} ms; + + +void kos_Main() +{ + Dword frame_start, frame_end; + OnStart(); + Menu(); + for (;;) + { + frame_start = kos_GetTime(); + switch (kos_CheckForEvent()) + { + case 1: + DrawWindow(); + break; + case 2: // key pressed, read it and ignore + Byte keyCode; + kos_GetKey(keyCode); + if (keyCode == 27) + { + OnExit(); + } + if (keyCode == 51) + { + OnStart(); + } + break; + case 3: // button pressed; we have only one button, close + OnExit(); + break; + case 6: // ( ; ) + OnMouseMove(); + if (ms.lbclick == 1) + { + OnLMBClick(); + } + break; + default: + OnMouseMove(); + break; + } + DrawBombs(); + DrawRocketsAndCrosses(); + DrawExplodes(); + frame_end = kos_GetTime(); + if (frame_end - frame_start < FRAME_TIME) + { + kos_Pause(FRAME_TIME - (frame_end - frame_start)); + } + if (health <= 0) + { + OnExit(); + } + } +} + +void DrawWindow() +{ + kos_WindowRedrawStatus(1); + kos_DefineAndDrawWindow(10, 40, WINDOW_WIDTH + 8, WINDOW_HEIGHT + 25, 0x33, BG_COLOR, 0, 0, (Dword)header); + kos_WindowRedrawStatus(2); + + OnMouseMove(); + + // Draw buildings + for (int i = 20; i < 5 * 50; i += 50) + { + house->Draw(i, 467, H_COLOR); + } + for (int i = 8 * 50; i < 13 * 50; i += 50) + { + house->Draw(i, 467, H_COLOR); + } + +} + +void DrawBombs() +{ + for (int i = 0; i < B_COUNT; i++) + { + if (bombs[i]->IsEnabled() == 0) + { + int rnd; + rnd = rtlRand() % B_POSSIBILITY; + if (rnd == 1) + { + rnd = 10 + rtlRand() % 620; + bombs[i]->Enable(rnd, 0, 4, 9, rnd + 2, 0); + } + } + else + { + if (bombs[i]->cy > gun->cy + 5) + { + health -= 5; + if (explodes[R_COUNT + i]->IsEnabled() == 1) + { + explodes[R_COUNT + i]->Disable(BG_COLOR); + } + explodes[R_COUNT + i]->Enable(bombs[i]->cx, bombs[i]->cy); + bombs[i]->Disable(BG_COLOR); + } + else + { + bombs[i]->cy += B_SPEED; + bombs[i]->DrawAngle(bombs[i]->cx, 639, B_COLOR); + } + } + } +} + +void DrawRocketsAndCrosses() +{ + double a; + for (int i = 0; i < R_COUNT; i++) + { + if (crosses[i]->IsEnabled() == 1) + { + if (sqrt(((long int) (crosses[i]->x - rockets[i]->cx) * (crosses[i]->x - rockets[i]->cx)) + ((long int) (crosses[i]->y - rockets[i]->cy) * (crosses[i]->y - rockets[i]->cy))) < 5) + { + if (explodes[i]->IsEnabled() == 1) + { + explodes[i]->Disable(BG_COLOR); + } + explodes[i]->Enable(crosses[i]->x, crosses[i]->y); + crosses[i]->Disable(BG_COLOR); + rockets[i]->Disable(BG_COLOR); + } + else + { + crosses[i]->Draw(CROSS_COLOR); + if (rockets[i]->cx - crosses[i]->x == 0) + { + a = M_PI / 2; + } + else + { + a = atan((double)(rockets[i]->cy - crosses[i]->y) / (double)(rockets[i]->cx - crosses[i]->x)); + if (rockets[i]->cx - crosses[i]->x < 0) a += M_PI; + } + rockets[i]->cx = round_int(rockets[i]->cx - R_SPEED * cos(a)); + rockets[i]->cy = round_int(rockets[i]->cy - R_SPEED * sin(a)); + rockets[i]->DrawAngle(crosses[i]->x, crosses[i]->y, R_COLOR); + } + } + } +} + +void DrawExplodes() +{ + for (int i = 0; i < R_COUNT + B_COUNT; i++) + { + if (explodes[i]->IsEnabled() == 1) + { + explodes[i]->DrawNext(EXP_COLOR); + for (int j = 0; j < B_COUNT; j++) + { + if ( bombs[j]->IsEnabled() == 1 && + bombs[j]->cx > explodes[i]->cx - explodes[i]->step - 1 && bombs[j]->cx < explodes[i]->cx + explodes[i]->step + 1 && + bombs[j]->cy + 5 > explodes[i]->cy - explodes[i]->step - 1 && bombs[j]->cy + 5 < explodes[i]->cy + explodes[i]->step + 1 + ) + { + score += B_COUNT + 2; + if (explodes[R_COUNT + j]->IsEnabled() == 1) + { + explodes[R_COUNT + j]->Disable(BG_COLOR); + } + explodes[R_COUNT + j]->Enable(bombs[j]->cx, bombs[j]->cy); + bombs[j]->Disable(BG_COLOR); + } + } + } + } +} + +void OnMouseMove() +{ + Dword old_buttons = ms.buttons; + kos_GetMouseWindowXY(ms.x, ms.y); + kos_GetMouseButtonsState(ms.buttons); + if ((old_buttons & 0x00000001) == 0 && (ms.buttons & 0x00000001) == 1) + { + ms.lbclick = 1; + } + else + { + ms.lbclick = 0; + } + + + kos_WriteTextToWindow(8, 10, 0, TEXT_COLOR, "Population: %", 16); + kos_DisplayNumberToWindowBg(health, 3, 79, 10, TEXT_COLOR, BG_COLOR, nbDecimal, false); + kos_WriteTextToWindow(8, 22, 0, TEXT_COLOR, "Score:", 6); + kos_DisplayNumberToWindowBg(score, 4, 49, 22, TEXT_COLOR, BG_COLOR, nbDecimal, false); + + if (ms.x >= 0 && ms.x < WINDOW_WIDTH && ms.y >= 0 && ms.y < WINDOW_HEIGHT) + { + gun->DrawAngle(ms.x, ms.y, G_COLOR); + } + + if (HARDWARE_CURSOR == 0) + { + cursor->Draw(ms.x, ms.y, CUR_COLOR); + } + + /*if (DEBUG == 1) + { + kos_DisplayNumberToWindowBg(ms.x, 3, WINDOW_WIDTH - 30, 10, TEXT_COLOR, BG_COLOR, nbDecimal, false); + kos_DisplayNumberToWindowBg(ms.y, 3, WINDOW_WIDTH - 30, 22, TEXT_COLOR, BG_COLOR, nbDecimal, false); + kos_DisplayNumberToWindowBg(ms.buttons, 1, WINDOW_WIDTH - 30, 34, TEXT_COLOR, BG_COLOR, nbDecimal, false); + }*/ + +} + +void OnLMBClick() +{ + if (ms.y < gun->cy - 10) + { + double a; + int j = -1; + for (int i = 0; i < R_COUNT; i++) + { + if (crosses[i]->IsEnabled() == 0) + { + if (j >= -1) j = i; + } + else if (ms.x > crosses[i]->x - 10 && ms.x < crosses[i]->x + 10 && ms.y > crosses[i]->y - 10 && ms.y < crosses[i]->y + 10) + { + j = -2; + break; + } + } + if (j >= 0) + { + if (score > 0) score -= 1; + crosses[j]->Enable(ms.x, ms.y); + if (gun->cx - ms.x == 0) + { + a = M_PI/2; + } + else + { + a = atan((double)gun->cy - ms.y / (double) gun->cx - ms.x); + if (gun->cx - ms.x < 0) a += M_PI; + } + rockets[j]->Enable(round_int(gun->cx - 15 * cos(a)) - 2, round_int(gun->cy - 15 * sin(a)) - 5, 3, 6, round_int(gun->cx - 15 * cos(a)), round_int(gun->cy - 15 * sin(a))); + } + } +} + +void OnRMBClick() +{ +} + +void ChangeCursor() +{ + Dword *cur = new Dword[1024]; + for (int i = 0; i < 1024; i++) + { + cur[i] = 0x00000000; + } + if (HARDWARE_CURSOR == 1) + { + Dword cur_color = 0xFF000000 | CUR_COLOR; + cur[0 * 32 + 5] = cur_color; + cur[1 * 32 + 5] = cur_color; + cur[2 * 32 + 5] = cur_color; + cur[2 * 32 + 3] = cur_color; + cur[2 * 32 + 4] = cur_color; + cur[2 * 32 + 6] = cur_color; + cur[3 * 32 + 2] = cur_color; + cur[4 * 32 + 2] = cur_color; + cur[5 * 32 + 2] = cur_color; + cur[5 * 32 + 1] = cur_color; + cur[5 * 32 + 0] = cur_color; + + cur[5 * 32 + 5] = cur_color; + + cur[8 * 32 + 4] = cur_color; + cur[8 * 32 + 5] = cur_color; + cur[8 * 32 + 6] = cur_color; + cur[8 * 32 + 7] = cur_color; + cur[9 * 32 + 5] = cur_color; + cur[10 * 32 + 5] = cur_color; + cur[7 * 32 + 8] = cur_color; + cur[6 * 32 + 8] = cur_color; + cur[5 * 32 + 8] = cur_color; + cur[5 * 32 + 9] = cur_color; + cur[5 * 32 + 10] = cur_color; + } + cur_handle = kos_LoadMouseCursor(cur, 0x05050002); + delete[] cur; + kos_SetMouseCursor(cur_handle); +} + +void Menu() +{ + NewGame(); +} + +void NewGame() +{ + gun->DrawAngle((WINDOW_WIDTH / 2) - 5, WINDOW_HEIGHT - 20, G_COLOR); +} + +void OnStart() +{ + if (HARDWARE_CURSOR == 0) + { + cursor = new cCursor(); + } + ChangeCursor(); + + gun->Enable((WINDOW_WIDTH / 2) - 10, WINDOW_HEIGHT - 30, 10, 20, (WINDOW_WIDTH / 2) - 5, WINDOW_HEIGHT - 20); + + for (int i = 0; i < R_COUNT; i++) + { + crosses[i] = new cCross(); + rockets[i] = new cRocket(); + } + for (int i = 0; i < B_COUNT; i++) + { + bombs[i] = new cBomb(); + } + for (int i = 0; i < R_COUNT + B_COUNT; i++) + { + explodes[i] = new cExplode(); + } + + health = 100; + score = 0; + + rtlSrand(kos_GetTime()); + + DrawWindow(); + kos_SetMaskForEvents(39); +} + +void OnExit() +{ + kos_WriteTextToWindow(WINDOW_WIDTH / 2 - 35, WINDOW_HEIGHT / 2 - 10, 0, TEXT_COLOR, "Game Over", 9); + + kos_Pause(200); + + kos_ExitApp(); +} diff --git a/programs/games/rforces/trunk/rforces.h b/programs/games/rforces/trunk/rforces.h new file mode 100644 index 0000000000..6c9f60d5da --- /dev/null +++ b/programs/games/rforces/trunk/rforces.h @@ -0,0 +1,19 @@ +/* Rocket Forces + * Filename: rforces.h + * Version 0.1 + * Copyright (c) Serial 2007 + */ + + +void DrawWindow(); +void DrawBombs(); +void DrawRocketsAndCrosses(); +void DrawExplodes(); +void OnMouseMove(); +void OnLMBClick(); +void OnRMBClick(); +void ChangeCursor(); +void Menu(); +void NewGame(); +void OnStart(); +void OnExit(); diff --git a/programs/games/sq_game/trunk/MACROS.INC b/programs/games/sq_game/trunk/MACROS.INC new file mode 100644 index 0000000000..14185dbfce --- /dev/null +++ b/programs/games/sq_game/trunk/MACROS.INC @@ -0,0 +1,269 @@ +; new application structure +macro meos_app_start + { + use32 + org 0x0 + + db 'MENUET01' + dd 0x01 + dd __start + dd __end + dd __memory + dd __stack + + if used __params & ~defined __params + dd __params + else + dd 0x0 + end if + + dd 0x0 + } +MEOS_APP_START fix meos_app_start + +macro code + { + __start: + } +CODE fix code + +macro data + { + __data: + } +DATA fix data + +macro udata + { + if used __params & ~defined __params + __params: + db 0 + __end: + rb 255 + else + __end: + end if + __udata: + } +UDATA fix udata + +macro meos_app_end + { + align 32 + rb 2048 + __stack: + __memory: + } +MEOS_APP_END fix meos_app_end + + +; macro for defining multiline text data +struc mstr [sstring] + { + forward + local ssize + virtual at 0 + db sstring + ssize = $ + end virtual + dd ssize + db sstring + common + dd -1 + } + + +; strings +macro sz name,[data] { ; from MFAR [mike.dld] + common + if used name + label name + end if + forward + if used name + db data + end if + common + if used name + .size = $-name + end if +} + +macro lsz name,[lng,data] { ; from MFAR [mike.dld] + common + if used name + label name + end if + forward + if (used name)&(lang eq lng) + db data + end if + common + if used name + .size = $-name + end if +} + + + +; easy system call macro +macro mpack dest, hsrc, lsrc +{ + if (hsrc eqtype 0) & (lsrc eqtype 0) + mov dest, (hsrc) shl 16 + lsrc + else + if (hsrc eqtype 0) & (~lsrc eqtype 0) + mov dest, (hsrc) shl 16 + add dest, lsrc + else + mov dest, hsrc + shl dest, 16 + add dest, lsrc + end if + end if +} + +macro __mov reg,a,b { ; mike.dld + if (~a eq)&(~b eq) + mpack reg,a,b + else if (~a eq)&(b eq) + mov reg,a + end if +} + +macro mcall a,b,c,d,e,f { ; mike.dld + __mov eax,a + __mov ebx,b + __mov ecx,c + __mov edx,d + __mov esi,e + __mov edi,f + int 0x40 +} + + + +; optimize the code for size +__regs fix + +macro add arg1,arg2 + { + if (arg2 eqtype 0) + if (arg2) = 1 + inc arg1 + else + add arg1,arg2 + end if + else + add arg1,arg2 + end if + } + +macro sub arg1,arg2 + { + if (arg2 eqtype 0) + if (arg2) = 1 + dec arg1 + else + sub arg1,arg2 + end if + else + sub arg1,arg2 + end if + } + +macro mov arg1,arg2 + { + if (arg1 in __regs) & ((arg2 eqtype 0) | (arg2 eqtype '0')) + if (arg2) = 0 + xor arg1,arg1 + else if (arg2) = 1 + xor arg1,arg1 + inc arg1 + else if (arg2) = -1 + or arg1,-1 + else if (arg2) > -128 & (arg2) < 128 + push arg2 + pop arg1 + else + mov arg1,arg2 + end if + else + mov arg1,arg2 + end if + } + + +macro struct name + { + virtual at 0 + name name + sizeof.#name = $ - name + end virtual + } + +; structures used in MeOS +struc process_information + { + .cpu_usage dd ? ; +0 + .window_stack_position dw ? ; +4 + .window_stack_value dw ? ; +6 + .not_used1 dw ? ; +8 + .process_name rb 12 ; +10 + .memory_start dd ? ; +22 + .used_memory dd ? ; +26 + .PID dd ? ; +30 + .x_start dd ? ; +34 + .y_start dd ? ; +38 + .x_size dd ? ; +42 + .y_size dd ? ; +46 + .slot_state dw ? ; +50 + dw ? ; +52 - reserved + .client_left dd ? ; +54 + .client_top dd ? ; +58 + .client_width dd ? ; +62 + .client_height dd ? ; +66 + .wnd_state db ? ; +70 + rb (1024-71) + } +struct process_information + +struc system_colors + { + .frame dd ? + .grab dd ? + .grab_button dd ? + .grab_button_text dd ? + .grab_text dd ? + .work dd ? + .work_button dd ? + .work_button_text dd ? + .work_text dd ? + .work_graph dd ? + } +struct system_colors + + +; constants + +; events +EV_IDLE = 0 +EV_TIMER = 0 +EV_REDRAW = 1 +EV_KEY = 2 +EV_BUTTON = 3 +EV_EXIT = 4 +EV_BACKGROUND = 5 +EV_MOUSE = 6 +EV_IPC = 7 +EV_STACK = 8 + +; event mask bits for function 40 +EVM_REDRAW = 1b +EVM_KEY = 10b +EVM_BUTTON = 100b +EVM_EXIT = 1000b +EVM_BACKGROUND = 10000b +EVM_MOUSE = 100000b +EVM_IPC = 1000000b +EVM_STACK = 10000000b \ No newline at end of file diff --git a/programs/games/sq_game/trunk/SQ_GAME.ASM b/programs/games/sq_game/trunk/SQ_GAME.ASM new file mode 100644 index 0000000000..790a555e27 --- /dev/null +++ b/programs/games/sq_game/trunk/SQ_GAME.ASM @@ -0,0 +1,246 @@ +; SQ_game for MenuetOS +; Author: Alexei Ershov aka ealex +; E-mail: e-al[at]yandex[dot]ru +; Fidonet: 2:469/335.38 +; slightly optimized by diamond +; english translation by diamond (two strings in end of source) + + + BtnSize equ 32 ; ࠧ + BtnSpace equ 10 ; ஬⮪ + NofBtn equ 4 ; ࠧ (3-15) + Color1 equ 0xcc0000 + Color2 equ 0x00cc00 + + FieldSize = (BtnSize+BtnSpace)*NofBtn + BtnSpace*3 + center = FieldSize / 2 + + + use32 ; 32- ० ᥬ + org 0x0 ; + + db 'MENUET01' ; 8- 䨪 MenuetOS + dd 0x01 ; (ᥣ 1) + dd START ; ࢮ + dd I_END ; ࠧ ணࠬ + dd 0x1000 ; ⢮ + dd 0x1000 ; 設 + dd 0x0 ; ࠬ஢ ( ᯮ) + dd 0x0 ; १ࢨ஢ + +include 'lang.inc' +include 'MACROS.INC' ; ᥬ騪! + + +START: + call Game_Init +red: + call Draw_Window + +still: + mcall 10 ; 㭪 10 - ᮡ + dec eax + jz red + dec eax + jnz button + + key: ; + mov al, 2 + int 0x40 + jmp still +;--------------------------------------------------------------------- + +button: + mov al, 17 ; 17 - 䨪 ⮩ + int 0x40 + cmp ah, 1 ; ᫨ ஬ 1, 室 + je .exit + + cmp ah, 2 ; ᫨ 2, 稭 + je START + + ; + inc dword [moves] ; 㢥稢 ᫮ 室 + + shr eax, 8 ; eax 䨪 ⮩ + + mov dh, NofBtn + div dh ; al = ax( ) / NofBtn + ; ah = ⮪ (. 㭮) + mov ebx, eax ; ࠭ ⭮ ⮪ ebx + + ; al\ah 0 1 2 3 + ; +-+ +-+ +-+ +-+ + ; 1 |4| |5| |6| |7| + ; +-+ +-+ +-+ +-+ + + ; +-+ +-+ +-+ +-+ + ; 2 |8| |9| |10 |11 + ; +-+ +-+ +-+ +-+ + + ; +-+ +-+ +-+ +-+ + ; 3 |12 |13 |14 |15 + ; +-+ +-+ +-+ +-+ + + ; +-+ +-+ +-+ +-+ + ; 4 |16 |17 |18 |19 + ; +-+ +-+ +-+ +-+ + +; 塞 梥 ⮫ + shr eax, 8 ; eax = ah + mov edi, field + add edi, eax ; edi 㪠 ᪮ ⫡ + mov ecx, NofBtn +@@: + not byte[edi] ; 塞 梥 ᥬ ⮫ + dec ecx + add edi, NofBtn + test ecx, ecx + jnz @r + +; 塞 梥 ப + mov eax, ebx ; ⠭ eax + dec eax + mov dl, NofBtn + mul dl ; ax = al * NofBtn + mov edi, field + add edi, eax ; edi 㪠 ᪮ ப + mov ecx, NofBtn +@@: + not byte [edi] ; 塞 梥 ᥩ ப + dec ecx + inc edi + test ecx, ecx + jnz @r +; ⮩ 2 ࠧ ( ࠡ뢠 ப ⮫), +; .. ⠫ ࢮ砫 +; 塞 梥 ⮩ + shr ebx, 8 ; ebx = ⮪ (ah 㭪) + not byte [field+eax+ebx] + jmp red + + + + .exit: + mcall -1 ; ணࠬ + + +;---------------------------------------------------------------------------- +; Draw_Window +;---------------------------------------------------------------------------- +Draw_Window: + + mcall 12, 1 + mcall 0, 200*65536+FieldSize,\ + 200*65536+FieldSize+20+20+20,\ + 0x03AABBCC, 0x805080D0, 0x005080D0 + mcall 4, 8*65536+8, 0x10DDEEFF, header, header_e - header + + mcall 8, BtnSpace*2*65536 + 83,\ + (FieldSize+BtnSpace+20)*65536+ 15, 2 + mcall 4, (BtnSpace*2+3)*65536+(BtnSize+BtnSpace)*NofBtn+BtnSpace*4+20+4,\ + 0x10DDEEFF, strNew, strNew_e - strNew + mcall 4, (center - 25) * 65536 + 30, 0, strMovs, strMovs_e - strMovs + mcall 47, 4*65536+1, moves, (center + 2 ) * 65536 + 30, 0 + + + + mov ecx, (20+20+BtnSpace-BtnSize)*65536+BtnSize + mov edx, NofBtn ; 䨪 ࢮ + ; 㭮 + +buttons: ; 㥬 窨 + mov eax, edx + mov dh, NofBtn + div dh ; al = ax / dh, ah - ⮪ + mov dh, 0 + test ah, ah ; ᫨ ah = 0, 稭 + jnz @f + add ecx, (BtnSize+BtnSpace)*65536 + mov ebx, BtnSpace*2*65536+BtnSize +@@: + mov esi, Color1 ; + cmp byte [field-NofBtn+edx], 0 ; field-NofBtn+_ + jz @f ; 梥 + mov esi, Color2 +@@: + mcall 8, + add ebx, (BtnSize+BtnSpace)*65536 + inc edx ; 室 ᫥饩 + cmp edx, NofBtn*(NofBtn+1) + jb buttons + + mcall 12, 2 ; 㭪 12: ᮮ ᮢ + +ret + +;---------------------------------------------------------------------------- +; Game_Init +;---------------------------------------------------------------------------- +Game_Init: + and [moves], 0 ; 㫨 ⢮ 室 + + call random ; eax 砩 ᫮ + mov ecx, NofBtn * NofBtn ; ecx - + mov bh, 0 ; 㤥 + ; 1 eax, bh - ᪮쪮 +button_init: ; 㦥 ᯮ짮 + shr eax, 1 ; 訩 䫠 CF + ; ᨬ 祭 + ; bl 뢠 -1 0 + sbb bl, bl + mov [field + ecx - 1], bl + + inc bh + cmp bh, 32 ; ᫨ ᯮ짮 32 eax + jb @f ; 砩 ᫮ + call random + mov bh, 0 +@@: + loop button_init + +ret + +;---------------------------------------------------------------------------- +; random - +;---------------------------------------------------------------------------- +random: mov eax,[generator] + add eax,-43ab45b5h + ror eax,1 + xor eax,32c4324fh + ror eax,1 + mov [generator],eax + ; --- IVAN --- + mov eax,26 + mov ebx,9 + int 0x40 + xor eax,0xdeadbeef + add eax,[generator] + ; --- IVAN --- + ret + +;============================================================================ + +field db NofBtn * NofBtn dup(0) +moves dd 0 +generator dd 0 + +if lang eq ru +header db 'Game' +header_e: +strMovs db '' ; '' +strMovs_e: +strNew db ' ' ; ' ' +strNew_e: +else +header db 'Game' +header_e: +strMovs db 'MOVE' +strMovs_e: +strNew db ' New game' +strNew_e: +end if + + + +I_END: ; ⪠ ணࠬ diff --git a/programs/games/sq_game/trunk/build_en.bat b/programs/games/sq_game/trunk/build_en.bat new file mode 100644 index 0000000000..146614a2d3 --- /dev/null +++ b/programs/games/sq_game/trunk/build_en.bat @@ -0,0 +1,4 @@ +@echo lang fix en >lang.inc +@fasm sq_game.asm sq_game +@erase lang.inc +@pause \ No newline at end of file diff --git a/programs/games/sq_game/trunk/build_ru.bat b/programs/games/sq_game/trunk/build_ru.bat new file mode 100644 index 0000000000..e634b5f805 --- /dev/null +++ b/programs/games/sq_game/trunk/build_ru.bat @@ -0,0 +1,4 @@ +@echo lang fix ru >lang.inc +@fasm sq_game.asm sq_game +@erase lang.inc +@pause \ No newline at end of file diff --git a/programs/games/sudoku/trunk/SudokuSolve.pas b/programs/games/sudoku/trunk/SudokuSolve.pas new file mode 100644 index 0000000000..692496e2d3 --- /dev/null +++ b/programs/games/sudoku/trunk/SudokuSolve.pas @@ -0,0 +1,423 @@ +;unit SudokuSolve; + +;interface + +;type +; TSudokuBoard=array[0..8,0..8] of byte;// + +; function CheckSudoku(var Map: TSudokuBoard): boolean; +; // true + +; function Solve(var Map: TSudokuBoard): integer; +; // +; //Result = 1; - +; //Result = -1; - + +; procedure CopyArray(var Dst: TSudokuBoard;Src: TSudokuBoard); + +;implementation + +;type +; TSudokuPt=record // +; mini,minj,variances: byte; +; end; + +;var +; TempMap: TSudokuBoard;// +; Pt: TSudokuPt; // +; i,j: byte; // + + + +align 4 +CheckSudoku: +pushad +;function CheckSudoku(var Map: TSudokuBoard): boolean; ; esi! +;var +; i,j,x,y: byte; +; Zap: set of byte; +;begin + +;// +; for i:=0 to 8 do +; begin +; Zap:=[]; +; for j:=0 to 8 do +; if Map[i,j]<>0 then +; if Map[i,j] in Zap then +; begin +; Result:=false; +; Exit; +; end else +; Zap:=Zap+[Map[i,j]]; +; end; + xor ecx,ecx + xor eax,eax + xor edx,edx + mov bx,0x0909 +.1: mov al, byte [esi+ecx] + test al,al + jz @f + btc dx,ax + jc .ret_false + @@: + add cl,9 + dec bl + jnz .1 +; test [flags],1 shl 15 +; jz @f +; cmp edx,1022 ;1111111110b +; jne .ret_false +;@@: + bt [flags],15 + jnc @f + cmp dx,1022 ;1111111110 + jne .ret_false +@@: + sub cl,9*9-1 + xor edx,edx + mov bl,9 + dec bh + jnz .1 + + +;// +; for j:=0 to 8 do +; begin +; Zap:=[]; +; for i:=0 to 8 do +; if Map[i,j]<>0 then +; if Map[i,j] in Zap then +; begin +; Result:=false; +; Exit; +; end else +; Zap:=Zap+[Map[i,j]] +; end; + + xor ecx,ecx + xor eax,eax + xor edx,edx + mov bx,0x0909 +.2: mov al, byte [esi+ecx] + test al,al + jz @f + btc dx,ax + jc .ret_false + @@: + inc ecx + dec bl + jnz .2 + bt [flags],15 + jnc @f + cmp dx,1022 ;1111111110 + jne .ret_false +@@: + xor edx,edx + mov bl,9 + dec bh + jnz .2 + +;// +;for i:=0 to 2 do +; for j:=0 to 2 do +; begin +; zap:=[]; +; for x:=0 to 2 do +; for y:=0 to 2 do +; if map[i*3+y,j*3+x]<>0 then +; if map[i*3+y,j*3+x] in Zap then +; begin +; Result:=false; +; exit; +; end else +; Zap:=zap+[map[i*3+y,j*3+x]]; +; end; +;Result:=true; +;end; + mov ecx,0x0303 ;ij + xor eax,eax + xor edx,edx + mov ebx,0x0303 ;xy + +.3: movzx eax,ch + dec al + lea eax,[eax*2+eax] + add al,bl ;i*3+y + dec al + mov edi,eax + movzx eax,cl + dec al + lea eax,[eax*2+eax] + add al,bh ;j*3+x + dec al + xchg eax,edi + mov ah,9 + mul ah + add eax,edi ;i*3+y,j*3+x + mov al,[esi+eax] + test al,al + jz @f + btc dx,ax + jc .ret_false + @@: + dec bl + jnz .3 + mov bl,3 + dec bh + jnz .3 + bt [flags],15 + jnc @f + cmp dx,1022 ;1111111110 + jne .ret_false +@@: + mov bx,0x0303 + xor edx,edx + dec cl + jnz .3 + mov cl,3 + dec ch + jnz .3 +popad +clc +ret +.ret_false: +popad +stc +ret + +_iRet dw ? + +Pt: +.mini db ? +.minj db ? +.variances db ? + +bFree db ? +nVariances db ? +nMinVariances db ? + +align 4 +FindMinPoint: + pushad + mov [bFree],0 + mov [nMinVariances],10 + mov cx,0x0909 ;ij +.1: movzx eax,ch + mov ah,9 + dec al + mul ah + add al,cl + dec al + cmp byte [esi+eax],0 + je @f +.11: dec cl + jnz .1 + mov cl,9 + dec ch + jnz .1 + jmp .3 + +@@: mov [nVariances],0 + mov [bFree],1 + mov ebx,1 +.2: mov [esi+eax],bl + call CheckSudoku + jc @f + inc [nVariances] +@@: inc ebx + cmp ebx,9 + jbe .2 + + mov byte [esi+eax],0 + mov dl,[nVariances] + cmp dl,0 + je .11 + cmp dl,[nMinVariances] + jnb .11 + mov [Pt.mini],ch + mov [Pt.minj],cl + mov [Pt.variances],dl + mov [nMinVariances],dl + jmp .11 + +.3: cmp [bFree],1 + jne @f + cmp [nMinVariances],10 + jge @f + mov [_iRet],1 + popad + ret +@@: cmp [bFree],1 + jne @f + mov [_iRet],-1 + popad + ret +@@: mov [_iRet],0 + popad +ret + + +; // MinPt +; //Result = -1; - , +; //Result = 1; - , +; //Result = 0; - +;function FindMinPoint(var MinPt: TSudokuPt;var Map: TSudokuBoard): integer; +;var +;nVariances,nMinVariances,variance: byte; +;bFree: boolean; +;begin +;bFree:= false; +;nMinVariances:=10; +;for i:=0 to 8 do +; for j:=0 to 8 do +; begin +; if Map[i,j]<>0 then continue; +; nVariances := 0; +; bFree := true; +; for variance:=1 to 9 do +; begin +; map[i,j]:=variance; +; if CheckSudoku(Map) then inc(nVariances); +; end; +; Map[i,j]:=0; +; if nVariances=0 then continue; +; if nVariances < nMinVariances then +; begin +; MinPt.mini:=i; +; MInPt.minj:=j; +; MinPt.variances:=nVariances; +; nMinVariances := nVariances; +; end; +; end; +;if (bFree) and (nMinVariances<10) then // , +; begin +; Result:=1; +; Exit; +; end; +;if bFree then // , +; begin +; Result:=-1; +; exit; +; end; +;result:=0; // +;end; + + + +;procedure CopyArray(var Dst: TSudokuBoard;Src: TSudokuBoard); +;begin +;for i:=0 to 8 do +; for j:=0 to 8 do +; Dst[i,j]:=Src[i,j]; +;end; + +CopyArray: + push ecx eax + xor ecx,ecx +@@: mov al,[esi+ecx] + mov [edi+ecx],al + inc ecx + cmp ecx,9*9 + jb @b + pop eax ecx +ret + + + +align 4 +Solve: + pushad +if DEBUG +dbg_dec esp +dbg_dec ecx +mcall 5,1 +endf + call FindMinPoint + cmp [_iRet],0 + jne @f + mov [_iRet],1 + popad + ret + @@: + cmp [_iRet],-1 + jne @f + popad + ret +@@: + push esi edi + mov edi,TempMap + call CopyArray + pop edi esi + mov ecx,1 + movzx eax, byte [Pt.mini] + dec al + mov ah,9 + mul ah + add al,byte [Pt.minj] + dec al +.1: mov byte [esi+eax],cl + call CheckSudoku + jnc @f +.2: inc ecx + cmp ecx,9 + jbe .1 +; jmp .1 +@@: call Solve + cmp [_iRet],-1 + jne @f + push esi edi + mov edi,TempMap + xchg esi,edi + call CopyArray + pop edi esi + popad + ret +@@: cmp [_iRet],1 + jne .3 + popad + ret +.3: mov [_iRet],0 + popad +ret + +;function Solve(var Map: TSudokuBoard): integer; +;var +; variance: byte; +; iRet: integer; +;begin +;// : +;iRet:=FindMinPoint(Pt,Map); +;if (iRet = 0) then +; begin +; result:=1;// +; exit; +; end else +;if (iRet = -1) then // +; begin +; result:=-1; +; exit; +; end; + +;CopyArray(TempMap,Map); // , +;for variance:=1 to 9 do +;begin +; Map[pt.mini,pt.minj]:=variance; // 1 9 +; if not CheckSudoku(Map) then continue; // . . +; iRet:=Solve(Map); // +; if iRet=-1 then // +; begin +; CopyArray(Map,tempmap); // +; continue; +; end; +;if iRet=1 then // +; begin +; Result:=1; +; exit; +; end; +;end; +;Result:=0; +;end; + +;end. + diff --git a/programs/games/sudoku/trunk/editbox_ex.mac b/programs/games/sudoku/trunk/editbox_ex.mac new file mode 100644 index 0000000000..938904c57c --- /dev/null +++ b/programs/games/sudoku/trunk/editbox_ex.mac @@ -0,0 +1,194 @@ + +ch_struc_size=36 +ed_struc_size=76 +ch_flag_en=10b + +ch_left equ [edi] ;न 砫 ᮢ +ch_top equ [edi+2] ;न 砫 ᮢ +ch_text_margin equ [edi+4] ;=4 ﭨ אַ㣮쭨 祪 +ch_size equ [edi+8] ;12 ࠧ 祪 +ch_color equ [edi+12] ;梥 checkbox +ch_border_color equ [edi+16] ; or [edi+4] ;梥 ࠬ checkbox ᠬ⥫쭮 +ch_text_color equ [edi+20];[edi+4] ;梥 ⥪ +ch_text_ptr equ [edi+24] ;㪠⥫ 砫 ⥪⮢ ப +ch_text_length equ [edi+28] +ch_flags equ [edi+32] ;䫠 + +ed_width equ [edi] ;ਭ +ed_left equ [edi+4] ; +ed_top equ [edi+8] ; +ed_color equ [edi+12] ;梥 䮭 +shift_color equ [edi+16] ;=0x6a9480 ਬ 쥬 梥 +ed_focus_border_color equ [edi+20] ;梥 ࠬ +ed_blur_border_color equ [edi+24] ;梥 ⨢ +ed_text_color equ [edi+28] ;梥 ⥪ +ed_max equ [edi+32] ;- ᨬ ᨬ쭮 +ed_text equ [edi+36] ;㪠⥫ +ed_mouse_variable equ [edi+40] ; 㪠⥫ ६ /㯯 +ed_flags equ [edi+44] ;䫠 +bp_flags equ [ebp+44] ; 楤 edi ᯮ, 㪠⥫ ࠭ ebp +ed_size equ [edi+48] ;- ᨬ +bp_size equ [ebp+48] ;- ᨬ, 樨 ᯫ ebp edi +ed_pos equ [edi+52] ; +ed_offset equ [edi+56] ;ᬥ饭 +cl_curs_x equ [edi+60] ;।饥 न +cl_curs_y equ [edi+64] ;।饥 न +ed_shift_pos equ [edi+68] ; +ed_shift_pos_old equ [edi+72] ;஥ + +ed_struc_size=76 +struc edit_box width,left,top,color,shift_color,focus_border_color,\ + blur_border_color,text_color,max,text,mouse_variable,flags,size,pos +{ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;Bit mask from editbox +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +ed_figure_only= 1000000000000000b ; ᨬ +ed_always_focus= 100000000000000b +ed_focus= 10b ;䮪 ਫ +ed_shift_on= 1000b ;᫨ ⠭ - shift,᫨ ⠭, 㦥 - 㤥ন shift +ed_shift_on_off=1111111111110111b +ed_shift= 100b ;砥 ⨨ shift .. ᫨ +ed_shift_off= 1111111111111011b +ed_shift_bac= 10000b ; ⪨ 뤥 shift .. ⠭ 뤥 +ed_shift_bac_cl=1111111111101111b ;⪠ 㤠 뤥 +ed_shift_cl= 1111111111100011b +ed_shift_mcl= 1111111111111011b +ed_left_fl= 100000b +ed_right_fl= 1111111111011111b +ed_offset_fl= 1000000b +ed_offset_cl= 1111111110111111b +ed_insert= 10000000b +ed_insert_cl= 1111111101111111b +ed_mouse_on = 100000000b +ed_mous_adn_b= 100011000b +ed_mouse_on_off=1111111011111111b +ed_height=14 ; + +.width dd width +.left dd left +.top dd top +.color dd color +.shift_color dd shift_color +.focus_border_color dd focus_border_color +.blur_border_color dd blur_border_color +.text_color dd text_color +.max dd max +.text dd text +.mouse_variable dd mouse_variable +.flags dd flags+0 +.size dd size+0 +.pos dd pos+0 +.offset dd 0 +.cl_curs_x dd 0 +.cl_curs_y dd 0 +.shift dd 0 +.shift_old dd 0 +} +macro edit_boxes_set_sys_color start,end,color_table +{ + mov edi,start + mov ecx,((end-start)/ed_struc_size) + mov esi,color_table +@@: + mov eax,dword [esi+36] + mov ebx,dword [esi+20] + push dword eax + pop dword ed_focus_border_color + shr bh,1 + shr bl,1 + shr ah,1 + shr al,1 + add ah,bh + add al,bl + ror eax,16 + ror ebx,16 + shr bl,1 + shr al,1 + add al,bl + ror eax,16 + mov dword ed_blur_border_color,eax + mov dword shift_color,eax + add edi,ed_struc_size + loop @b +} +macro get_sys_colors col_buf +{ + ;mov eax,48 + push 48 + pop eax + ;mov ebx,3 + push 3 + pop ebx + ;mov ecx,col_buf + push col_buf + pop ecx + ;mov edx,40 + push 40 + pop edx + mcall +} +macro check_boxes_set_sys_color start,end,color_table +{ +ch_left equ [edi] ;न 砫 ᮢ +ch_top equ [edi+2] ;न 砫 ᮢ +ch_text_margin equ [edi+4] ;=4 ﭨ אַ㣮쭨 祪 +ch_size equ [edi+8] ;12 ࠧ 祪 +ch_color equ [edi+12] ;梥 checkbox +ch_border_color equ [edi+16] ; or [edi+4] ;梥 ࠬ checkbox ᠬ⥫쭮 +ch_text_color equ [edi+20];[edi+4] ;梥 ⥪ +ch_text_ptr equ [edi+24] ;㪠⥫ 砫 ⥪⮢ ப +ch_text_length equ [edi+28] +ch_flags equ [edi+32] ;䫠 + + +;ch_left equ [edi] ;न 砫 ᮢ +;ch_top equ [edi+2] ;न 砫 ᮢ +;ch_color equ [edi+4] ;梥 checkbox +;ch_border_color equ [edi+8] ;梥 ࠬ checkbox +;ch_text_color equ [edi+12] ;梥 ⥪ +;ch_text_ptr equ [edi+16] ;㪠⥫ 砫 ⥪⮢ ப +;ch_text_length equ [edi+20] ; (2^64 ⠪ ⥪) +;ch_flags equ [edi+24] ;䫠 + + mov edi,start + mov ecx,((end-start)/ch_struc_size) + mov esi,color_table +@@: + push dword [esi+32] + pop dword ch_text_color + push dword [esi+36] + pop dword ch_border_color + add edi,ch_struc_size + loop @b +} +struc check_box left,top,ch_text_margin,ch_size,color,border_color,text_color,text,ch_text_length,flags +{ ; ࠬ஢ 祪 +ch_flag_en=10b +.left: dw left ;+0 ; +.top: dw top ; +.ch_text_margin: dd ch_text_margin ;ﭨ אַ㣮쭨 祪 +.ch_size: dd ch_size ;ࠧ 祪 , ਬ 12 +.color: dd color ;梥 祪 +.border_color: dd border_color ;梥 ࠬ +.text_color: dd text_color ;梥 +.text: dd text ; ணࠬ ᯮ ⥪ +.ch_text_length: dd ch_text_length ; ப ᨬ +.flags: dd flags+0 ; 䫠 +} +struc option_box point_gr,left,top,op_text_margin,op_size,color,border_color,text_color,text,op_text_length,flags +{ ; ࠬ஢ 祪 +op_flag_en=10b +.option_group: dd point_gr +.left: dw left ;+0 ; +.top: dw top ; +.ch_text_margin: dd op_text_margin ;ﭨ אַ㣮쭨 祪 +.ch_size: dd op_size ;ࠧ 祪 , ਬ 12 +.color: dd color ;梥 祪 +.border_color: dd border_color ;梥 ࠬ +.text_color: dd text_color ;梥 +.text: dd text ; ணࠬ ᯮ ⥪ +.ch_text_length: dd op_text_length ; ப ᨬ +.flags: dd flags+0 ; 䫠 +} + diff --git a/programs/games/sudoku/trunk/sudoku.asm b/programs/games/sudoku/trunk/sudoku.asm new file mode 100644 index 0000000000..879644948d --- /dev/null +++ b/programs/games/sudoku/trunk/sudoku.asm @@ -0,0 +1,1162 @@ +; 4.11.2009 staper@inbox.ru + +; 2.06.2010 fixed a little bug in check + +;based on http://sources.codenet.ru/download/1599/Sudoku.html + +; ࠢ 㣫 ᯮ , +; 㢥稢 ࠧ. + +; ணࠬ ஢ ப ࠬ஢; । +; 䠩 祩. + +; ⠭ : +; n - ᣥ஢ ⠡ +; c - ஢ 襭 +; ஡ - 襭 +; +- - ஢ ᫮ +; t - ਮ⠭/ ᥪ㭤 +; i - ᢮ ਬ +; r - +; l - 㧨 䠩 +; s - ࠭ 䠩 +; a - ࠭ 襭 䠩 + +use32 +org 0x0 + db 'MENUET01' + dd 0x1, START, I_END, (D_END+10000) and not 3, (D_END+10000) and not 3, buf_cmd_lin, cur_dir_path + +Difficult db 0 ;᫮ [0..9] +Difficult_array db 80,75,68,59,50,45,40,36,32,25 + +;: +Bckgrd_clr equ 0xffffff ;䮭 +Brdr_line_clr equ 0x780000 ; ࠭栬 +Inter_line_clr equ 0xb0b0b0 ;७ +Square_clr equ 0xdddddd ;梥 +Fix_nmb_clr equ 0x335533;0 ;筮 祭 +Chg_nmb_clr equ 0;x008d8d ;६ 祭 +Text_clr equ 0x000000 ;⥪ +Message_clr equ 0x0000ff ;ᮮ饭 + +DEBUG equ 0 + +macro dbg_dec num +{pushad +newline +debug_print_dec num +popad +} + +include 'macros.inc' +;include 'debug.inc' +include 'editbox_ex.mac' +include 'lang.inc' +include 'SudokuSolve.pas' + + +START: + mcall 40,7 + mcall 3 + mov [rsx1],ax + ror eax,16 + mov [rsx2],ax + rol eax,7 + mov [rsx3],ax + rol eax,7 + mov [rsx4],ax + +; call LOAD_LIB ;loading Box_Lib library + +; This is the part of the macros for load any library/libraries by +LOAD_LIB: + mcall 68,19,system_path ; load of sys directory + test eax,eax + jnz .end_steep + + bts [flags],7 +; ret + jmp .end + +.end_steep: + +; initialize import + mov edx, eax + mov esi,myimport +.import_loop: + lodsd + test eax, eax + jz .import_done + push edx +.import_find: + mov ebx, [ds:edx] + test ebx, ebx + jz .exit ;import_not_found + push eax +.lp: + mov cl, [ds:eax] + cmp cl, [ds:ebx] + jnz .import_find_next + test cl, cl + jz .import_found + inc eax + inc ebx + jmp .lp +.import_find_next: + pop eax + add edx, 8 + jmp .import_find +.import_found: + pop eax + mov eax, [ds:edx+4] + mov [esi-4], eax + pop edx + jmp .import_loop +.exit: + add esp,4 + + bts [flags],7 +;ret + jmp .end + +.import_done: + btr [flags],7 + +;।塞 ப ࠬࠬ + mov esi,buf_cmd_lin + xor eax,eax +@@: cmp byte [esi+eax],0 + je @f + inc eax + jmp @b +@@: mov dword [edit1.size],eax + mov dword [edit1.pos],eax +;ret +.end: + + bt [flags],7 + jc @f + mcall 68,11 + cmp dword [edit1.pos],0 + je @f + call load_sudoku + jnc redraw_all +@@: jmp key.new_game + + +redraw_all: + mcall 12,1 + mcall 48,4 + add eax,100*65536+(24*9+67) + mov ecx,eax + mcall 0,100*65536+(24*9+12),,(0x34000000+Bckgrd_clr),,title + mcall 38,1*65536+(24*9+1),21*65536+21,Brdr_line_clr + mov edx,Inter_line_clr + mov edi,3 + mov esi,3 + @@: add ecx,24*65536+24 + mcall + dec esi + jnz @b + mov esi,3 + push edx + mcall ,,,Brdr_line_clr + pop edx + dec edi + jnz @b + mcall ,1*65536+1,22*65536+236,Inter_line_clr;0xe7e6a0 + mov edx,Inter_line_clr + mov edi,3 + mov esi,3 + push edx + mcall ,,,Brdr_line_clr + pop edx + + @@: add ebx,24*65536+24 + mcall + dec esi + jnz @b + mov esi,3 + push edx + mcall ,,,Brdr_line_clr + pop edx + dec edi + jnz @b + + mcall 8,<208,8>,<257,8>,2,0xbbbbbb + mcall 4,<5,5>,(0x80000000+Text_clr),txt.new + mcall ,<105,5>,,txt.dif + mcall ,<5,258>,,txt.space + mcall ,<5,246>,,txt.check + mcall ,<129,246>,,txt.time + mcall ,<5,285>,,txt.own_map + mcall ,<5,296>,,txt.solve + mcall ,<90,296>,,txt.load + mcall ,<5,306>,,txt.save + mcall ,<90,306>,,txt.save_solve + + bts [flags],5 + call Timer.0 + call show_level + + push dword Map;esi; mov esi,Map + mcall 12,2 +draw_pole: + if DEBUG + call SysMsgBoardNum ;show esp + endf + + movzx eax,[Y] + dec al + mov ebx,9 + mul bl + mov bl,[X] + add al,bl + pop esi ; mov esi,Map + push eax ;稪 + mov edi,81-9 + mov ebp,9 + mov ebx,1*65536+21 + mov ecx,21*65536+41 + call out_numbers + pop eax + bt [flags],2 + jc key.0 + +still: + mcall 23,10 + test eax,eax + jz Timer + + dec al + jz redraw_all + dec al + jz key + dec al + jnz still +;button: + mcall 17 + cmp ah,1 + jne @f + mcall -1 +@@: cmp ah,2 + jne still + btc [flags],9 + mcall 48,4 + add eax,(24*9+67) + mov esi,eax + bt [flags],9 + jnc @f + add esi,40 +@@: mcall 67,100,100,(24*9+12), + jmp still +key: + mcall 2 + cmp ah,32 ;஡ +jne @f + btc [flags],3 + jc .todraw + push dword SolveMap + jmp draw_pole + .todraw: + push dword Map + jmp draw_pole +@@: + bt [flags],3 + jnc @f + bts [flags],2 + push eax + push dword Map + jmp draw_pole +.0: pop eax + btr [flags],2 + btr [flags],3 +@@: cmp ah,108 ;l + jne @f + bt [flags],7 + jc still + bt [flags],6 + jc still + bts [flags],8 + call window_load_save + jmp still +@@: cmp ah,115 ;s + jne @f + btr [flags],10 +.sresh: bt [flags],7 + jc still + bt [flags],6 + jc still + btr [flags],8 + call window_load_save + jmp still +@@: cmp ah,97 ;a + jne @f + bts [flags],10 + jmp .sresh +@@: cmp ah,116 ;t + jne @f + btc [flags],1 + jnc still + mcall 26,9 + sub eax,[Ticks_new] + push eax + mov eax,[Ticks] + mov ebx,100 + mul ebx + pop ecx + sub ecx,eax + add [Ticks_new],ecx + jmp still + +@@: cmp ah,105 ;i + jne @f + xor ecx,ecx + .105_0: + mov byte [SolveMap+ecx],0 + mov byte [Map+ecx],0 + inc ecx + cmp ecx,9*9 + jb .105_0 + jmp .todraw + +@@: cmp ah,114 ;r + jne .43 + xor ecx,ecx + .114_0: + mov al,[Map+ecx] + cmp al,9 + jbe @f + sub al,10 + @@: + mov [SolveMap+ecx],al + inc ecx + cmp ecx,9*9 + jb .114_0 + mov esi,SolveMap + call Solve + cmp [_iRet],1 + jne @f + mov edx,txt.check_yes + call Show_message + jmp still + @@: ; 襭 + xor ecx,ecx + @@: + mov byte [SolveMap+ecx],0 + inc ecx + cmp ecx,9*9 + jb @b + mov edx,txt.nosolve + call Show_message + jmp still + +.43: cmp ah,43 ;+ + jne .45 + cmp [Difficult],9 + je still + inc [Difficult] + call show_level + jmp still +.45: ;- + cmp ah,45 + jne .99 + cmp [Difficult],0 + je still + dec [Difficult] + call show_level + jmp still + +.99: ;Check + cmp ah,99 + jne .39 + bts [flags],15 + xor ecx,ecx + mov edx,txt.check_no +; @@: mov al,byte [Map+ecx] +; cmp byte [SolveMap+ecx],al +; jne @f +; inc ecx +; cmp ecx,9*9 +; jb @b + @@: mov al,byte [Map+ecx] ;७ᨬ 祭 ६ ᨢ + cmp al,9 + jbe .991 + sub al,10 + .991: + mov [TempMap+ecx],al + inc ecx + cmp ecx,9*9 + jb @b + mov esi,TempMap + call CheckSudoku + jc @f + mov edx,txt.check_yes + @@: btr [flags],15 + call Show_message + jmp .todraw + +.39: cmp ah,0x39 + ja .110 + cmp ah,0x30 + jb still + sub ah,0x30 + mov cl,ah + + movzx eax,[Y] + dec al + mov ebx,9 + mul bl + mov bl,[X] + dec bl + add al,bl + mov esi,Map + cmp byte [esi+eax],9 + jg still + mov [esi+eax],cl + jmp .onedraw + +.110: cmp ah,110 ;n + jne .176 +.new_game: + call GeneratePlayBoard + mov [Ticks],0 + mcall 26,9 + mov [Ticks_new],eax + jmp redraw_all + +.176: cmp ah,176 ; + jne .177 + call draw_one_symbol + dec [X] + cmp [X],1 + jge @f + mov [X],9 +@@: jmp .onedraw +.177: cmp ah,177 + jne .178 + call draw_one_symbol + inc [Y] + cmp [Y],9 + jbe @f + mov [Y],1 +@@: jmp .onedraw +.178: cmp ah,178 + jne .179 + call draw_one_symbol + dec [Y] + cmp [Y],1 + jge @f + mov [Y],9 +@@: jmp .onedraw +.179: cmp ah,179 + jne still + call draw_one_symbol + inc [X] + cmp [X],9 + jbe @f + mov [X],1 +@@: +.onedraw: + bts [flags],4 + call draw_one_symbol + jmp still ;.todraw + +show_level: + movzx ecx,[Difficult] + mcall 47,0x10000,,<205,5>,(0x50000000+Text_clr),Bckgrd_clr +ret + +Show_message: + mcall 4,<5,269>,(0xd0000000+Message_clr),,,Bckgrd_clr +ret + +Timer: + bt [flags],1 + jc still + mcall 26,9 + sub eax,[Ticks_new] + mov ebx,100 + xor edx,edx + div ebx + cmp eax,[Ticks] + je still + mov [Ticks],eax +.1: mov ebx,60 + xor edx,edx + div ebx + push eax + mov ecx,edx + mcall 47,0x00020000,,<206,246>,(0x40000000+Text_clr),Bckgrd_clr + pop ecx + mov edx,189*65536+246 + mcall + bt [flags],5 + jnc @f + btr [flags],5 + ret +@@: jmp still +.0: mov eax,[Ticks] + jmp .1 + +draw_one_symbol: + movzx eax,[X] + mov ebx,24*65536+24 + mul ebx + xchg eax,ebx + add ebx,(1*65536+21-24*65536+24) + movzx eax,[Y] + mov ecx,24*65536+24 + mul ecx + xchg eax,ecx + add ecx,(21*65536+41-24*65536+24) + movzx eax,[Y] + dec al + push ebx + mov ebx,9 + mul bl + mov bl,[X] + add al,bl + dec al + pop ebx + mov esi,Map + add esi,eax + push dword 0 ; + bt [flags],4 + jnc @f + mov dword [esp],1 ; + btr [flags],4 +@@: mov edi,0 + mov ebp,1 + call out_numbers + pop eax +ret + + +out_numbers: + push ebx ecx esi + shr ebx,16 + inc bx + shl ebx,16 + add ebx,23 + shr ecx,16 + inc cx + shl ecx,16 + add ecx,23 + mov edx,Bckgrd_clr + push ebp + dec dword [esp+4*5] + jnz @f + mov edx,Square_clr +@@: mcall 13 + pop ebp + pop esi + + cmp byte [esi],0 + je .null + cmp byte [esi],9 + jbe .changeable_number + cmp byte [esi],19 + jbe .fixed_number + jmp .null +.end: + inc esi + dec ebp + jnz out_numbers + test edi,edi + jz @f + sub edi,9 + mov ebp,9 + add ebx,-9*24*65536-9*24 + add ecx,24*65536+24 + jmp out_numbers + @@: +ret + +.fixed_number: + push esi + shr ebx,16 + shr ecx,16 + mov dx,bx + shl edx,16 + mov dx,cx + add edx,8*65536+4 + movzx ebx,byte [esi] + sub ebx,10 + dec ebx + shl ebx,4 + add ebx,FONT + mov ecx,8*65536+16 + push esi ebp edi + mov edi,Pltr.fx + cmp dword [esp+4*7],0 + jne @f + mov edi,Pltr.fxk +@@: mov esi,1 + mov ebp,0 + mcall 65 + pop edi ebp esi +.1: pop esi ecx ebx + add ebx,24*65536+24 + jmp .end + +.null: + pop ecx ebx + add ebx,24*65536+24 + jmp .end +.changeable_number: + push esi + shr ebx,16 + shr ecx,16 + mov dx,bx + shl edx,16 + mov dx,cx + add edx,8*65536+4 + movzx ebx,byte [esi] + dec ebx + shl ebx,4 + add ebx,FONT + mov ecx,8*65536+16 + push esi ebp edi + mov edi,Pltr.ch + cmp dword [esp+4*7],0 + jne @f + mov edi,Pltr.chk +@@: mov esi,1 + mov ebp,0 + mcall 65 + pop edi ebp esi + jmp .1 + + + +GeneratePlayBoard: +;i db 0 +;j db 0 +;RandI db 0 +;RandJ db 0 +;iRet db 0 +;//㥬 襭 +;m: +;for i:=0 to 8 do +; for j:=0 to 8 do +; begin +; Map[i,j]:=0; +; SolveMap[i,j]:=0; +; RealMap[i,j]:=0; +; end; + mov edi,Map + mov esi,SolveMap + mov edx,RealMap + xor ecx,ecx + @@: + mov byte [edi+ecx],0 + mov byte [esi+ecx],0 + mov byte [edx+ecx],0 + inc ecx + cmp ecx,9*9 + jb @b + +;//⠢ ࠭ ᪮쪮 ᥫ +;for i:=1 to 21 do +; begin +; RandI:=random(9); +; RandJ:=random(9); +; if SolveMap[RandI,RandJ]=0 then +; begin +; SolveMap[RandI,RandJ]:=random(9)+1; +; if not CheckSudoku(SolveMap) then +; begin +; SolveMap[RandI,RandJ]:=0; +; Continue; +; end; +; end else Continue; +; end; + + mov ecx,21 +.1: mov eax,9 + call random + mov ebx,eax + mov eax,9 + call random + mov ah,9 + mul ah + add eax,ebx ;RandI,RandJ + cmp byte [esi+eax],0 + jne .loop + mov ebx,eax + mov eax,9 + call random + mov byte [esi+ebx],al + call CheckSudoku + jnc .loop + mov byte [esi+ebx],0 + .loop: + loop .1 + + +;//蠥 㤮 +;iRet:=Solve(SolveMap); +;if iRet<>1 then goto m; +;i:=1; + + mov esi,SolveMap + call Solve + cmp [_iRet],1 + jne GeneratePlayBoard + + movzx ecx,[Difficult] + movzx ecx,byte [Difficult_array+ecx] + +;case Difficult of +;1: +; while i<=42 do +; begin +; RandI:=random(9); +; RandJ:=random(9); +; if RealMap[RandI,RandJ]<>0 then Continue else +; RealMap[RandI,RandJ]:=SolveMap[RandI,RandJ]; +; inc(i); +; end; +;2: +; while i<=32 do +; begin +; RandI:=random(9); +; RandJ:=random(9); +; if RealMap[RandI,RandJ]<>0 then Continue else +; RealMap[RandI,RandJ]:=SolveMap[RandI,RandJ]; +; inc(i); +; end; +;3: +; while i<=25 do +; begin +; RandI:=random(9); +; RandJ:=random(9); +; if RealMap[RandI,RandJ]<>0 then Continue else +; RealMap[RandI,RandJ]:=SolveMap[RandI,RandJ]; +; inc(i); +; end; +;end; + +.2: + mov eax,9 + call random + mov ebx,eax + mov eax,9 + call random + mov ah,9 + mul ah + cmp al,81 + jb @f + dec al + @@: + add eax,ebx ;RandI,RandJ + cmp byte [RealMap+eax],0 + jne .loop2 + add byte [SolveMap+eax],10 + mov bl,[SolveMap+eax] + mov byte [RealMap+eax],bl + .loop2: + loop .2 + +;for i:=0 to 8 do +; for j:=0 to 8 do +; Map[i,j]:=RealMap[i,j]; +;end; + + xor ecx,ecx +@@: mov al,[RealMap+ecx] + mov [Map+ecx],al + inc ecx + cmp ecx,9*9 + jb @b +ret + + + + +align 4 +rsx1 dw ?;0x4321 +rsx2 dw ?;0x1234 +rsx3 dw ?;0x62e9 +rsx4 dw ?;0x3619 +random: ; ASCL + push ecx ebx esi edx + mov cx,ax + mov ax,[rsx1] + mov bx,[rsx2] + mov si,ax + mov di,bx + mov dl,ah + mov ah,al + mov al,bh + mov bh,bl + xor bl,bl + rcr dl,1 + rcr ax,1 + rcr bx,1 + add bx,di + adc ax,si + add bx,[rsx3] + adc ax,[rsx4] + sub [rsx3],di + adc [rsx4],si + mov [rsx1],bx + mov [rsx2],ax + xor dx,dx + cmp ax,0 + je nodiv + cmp cx,0 + je nodiv + div cx +nodiv: + mov ax,dx + pop edx esi ebx ecx + and eax,0000ffffh +ret + + + +if DEBUG +SysMsgBoardNum: ;warning: destroys eax,ebx,ecx,esi + mov ebx,esp + mov ecx,8 + mov esi,(number_to_out+1) +.1: + mov eax,ebx + and eax,0xF + add al,'0' + cmp al,(10+'0') + jb @f + add al,('A'-'0'-10) +@@: + mov [esi+ecx],al + shr ebx,4 + loop .1 + dec esi + mcall 71,1,number_to_out +ret + +number_to_out db '0x00000000',13,10,0 +endf + + + +window_load_save: + popad + mcall 51,1,.thread,(threat_stack+32*4) + pushad + ret +.thread: + bts [flags],6 +.red: + mcall 12,1 + mov edi,txt.load + bt [flags],8 + jc @f + mov edi,txt.save + bt [flags],10 + jnc @f + mov edi,txt.save_solve +@@: mcall 0,50*65536+300,0x70*65536+60,(0x34000000+Bckgrd_clr),, + mcall 8,<245,43>,<2,14>,100,0xaaaaaa + mcall 4,<252,5>,(0x80000000+Text_clr),txt.enter + push dword edit1 + call [edit_box_draw] + mcall 12,2 +.still: + mcall 10 + dec al + jz .red + dec al + jz .key + dec al + jz .button + jmp .still +.button: + mcall 17,1 + cmp ah,1 + jne @f + .end: btr [flags],6 + mcall -1 + @@: cmp ah,100 + jne .still + bt [flags],8 + jc .ld + .sv: call save_sudoku + jnc .end + jmp .err + .ld: call load_sudoku + jnc .end + .err: mcall 4,<5,19>,(0x80000000+Text_clr),txt.error + jmp .still + + +.key: + mcall 2 + cmp ah,13 + jne @f + bt [flags],8 + jc .ld + jmp .sv + @@: cmp ah,27 + je .end + push dword edit1 + call [edit_box_key] + jmp .still + + +save_sudoku: + mov [_size],9*(9+2) + mcall 68,12,[_size] + test eax,eax + jnz @f + stc + ret + +@@: mov [_buffer],eax + mov edx,Map + bt [flags],10 + jnc @f + mov edx,SolveMap +@@: mov esi,eax;[_buffer] + mov ecx,[_size] + xor edi,edi + dec edi + mov ebx,9 +.1: test ecx,ecx + jz .end + test ebx,ebx + jz .2 + inc edi + dec ebx + mov al,[edx+edi] + test al,al + jnz @f + mov byte [esi+edi],0x23 + loop .1 + jmp .end +@@: cmp al,9 + jbe @f + sub al,10 +@@: add al,48 + mov byte [esi+edi],al + loop .1 + jmp .end +.2: mov ebx,9 + mov byte [esi+edi+1],13 + mov byte [esi+edi+2],10 + add esi,2 + sub ecx,2 + jmp .1 + + +.end: mov [func_70.func_n],2 + push [_size] + pop [func_70.param3] + push [_buffer] + pop [func_70.param4] + mov [func_70.name],buf_cmd_lin + mcall 70,func_70 + cmp al,0 ;࠭ 㤠筮? + je @f + mcall 68,13,[_buffer] + stc + ret +@@: mcall 68,13,[_buffer] + clc +ret + +load_sudoku: + mov [func_70.func_n],5 + mov [func_70.param3],0 + mov [func_70.param4],bufferfinfo + mov [func_70.name],buf_cmd_lin + mcall 70,func_70 + test al,al ;䠩 ? + jz @f + stc + ret + @@: mov eax, dword [bufferfinfo+32] ;㥬 ࠧ 䠩 + cmp eax,81 + jge @f + stc + ret +@@: cmp eax,100 + jb @f + stc + ret + +_size dd 0 +_buffer dd 0 + +@@: mov [_size],eax + mcall 68,12,[_size] + test eax,eax + jnz @f + stc + ret ;訡 뤥 + @@: + mov [_buffer],eax + mov [func_70.func_n],0 + mov [func_70.name],buf_cmd_lin + push dword [_size] + pop dword [func_70.param3] + push dword [_buffer] + pop dword [func_70.param4] + mcall 70,func_70 + test eax,eax + jz @f + stc + ret ;訡 ⥭ +@@: + + mov edx,Map + mov esi,[_buffer] + mov ecx,[_size] + xor edi,edi + dec edi +.1: test ecx,ecx + jz .end + inc edi + mov al,[esi+edi] + cmp al,0x23 + jne @f + mov byte [edx+edi],0 + loop .1 + jmp .end +@@: cmp al,13 + jne @f + add esi,2 + dec edi + sub ecx,2 + jmp .1 +@@: sub al,48 + mov byte [edx+edi],al + loop .1 +.end: mcall 68,13,[_buffer] + + xor ecx,ecx +@@: mov byte [SolveMap+ecx],0 + inc ecx + cmp ecx,9*9 + jb @b + + mov [Ticks],0 + mcall 26,9 + mov [Ticks_new],eax + + clc +ret + + + + +align 4 +myimport: +edit_box_draw dd aEdit_box_draw +edit_box_key dd aEdit_box_key +edit_box_mouse dd aEdit_box_mouse +version_ed dd aVersion_ed + dd 0 + dd 0 +aEdit_box_draw db 'edit_box',0 +aEdit_box_key db 'edit_box_key',0 +aEdit_box_mouse db 'edit_box_mouse',0 +aVersion_ed db 'version_ed',0 + +edit1 edit_box 240,2,2,Bckgrd_clr,0x6a9480,0,0xAABBCC,0,4096,buf_cmd_lin,ed_focus,2,0,0 + +func_70: + .func_n dd ? + .param1 dd 0 + .param2 dd 0 + .param3 dd ? + .param4 dd ? + .rezerv db 0 + .name dd ? + +if lang eq ru +title db '㤮',0 +txt: +.dif db " (+/-):",0 +.new db ' (N)',0 +.space db '襭 (஡)',0 +.check db '஢ (C)',0 +.check_yes db '襭 ',0 +.check_no = .nosolve +.time db "६ (T) :",0 +.own_map db ' ᢮ 㤮 襭 (I)',0 +.nosolve db ' 襭 ',0 +.solve db ' (R)',0 +.save db '࠭ (S)',0 +.save_solve db '࠭ 襭 (A)',0 +.error db '訡',0 +.load db '㧨 (L)',0 +.enter db 'Enter',0 +else +title db 'Sudoku',0 +txt: +.dif db "Difficult (+/-)",0 +.new db 'New (N)',0 +.space db 'Solution (Space)',0 +.check db 'Check (C)',0 +.check_yes db 'Right ',0 +.check_no db 'Not right ',0 +.time db " Time (T) :",0 +.own_map db 'Input your own Sudoku (I)',0 +.nosolve db 'It is not solved',0 +.solve db 'Solve (R)',0 +.save db 'Save (S)',0 +.save_solve db 'Save solution (A)',0 +.error db 'Error';,0 +.load db 'Load (L)',0 +.enter db 'Enter',0 +endf + +system_path db '/sys/lib/' +boxlib_name db 'box_lib.obj',0 + +X db 1 +Y db 1 + +Pltr: +.ch dd Bckgrd_clr,Chg_nmb_clr +.chk dd Square_clr,Chg_nmb_clr +.fx dd Bckgrd_clr,Fix_nmb_clr +.fxk dd Square_clr,Fix_nmb_clr + +align 4 +FONT file "SUDOKU.FNT" +;: + + +I_END: +align 16 +Map rb 9*9 +SolveMap rb 9*9 +RealMap rb 9*9 +TempMap rb 9*9 + +cur_dir_path rb 4096 +buf_cmd_lin rb 4096 +bufferfinfo rb 40 +Ticks_new rd 1 ;dd 0 +Ticks rd 1 ;dd 0 +flags rw 1 +threat_stack rd 32 ;: times 32 dd 0 + +D_END: +; 0: . । draw_pole +;1: 1-⠩ +;2: draw_pole key +;3: 1- +;4: in draw_one_symbol +;5: in Timer +;6: 1 ࠭ ࠭/㧪 +;7: box_lib is not loaded +;8: 0 - ࠭ 1 - 㧨 +;9: 1 - 㢥 +;10: 1 - ࠭ 襭 +;15 1 - ஢ઠ ⨨ ( CheckSudoku) \ No newline at end of file diff --git a/programs/games/sudoku/trunk/sudoku.fnt b/programs/games/sudoku/trunk/sudoku.fnt new file mode 100644 index 0000000000..cfce09f81c Binary files /dev/null and b/programs/games/sudoku/trunk/sudoku.fnt differ diff --git a/programs/games/whowtbam/trunk/wwtbam.cpp b/programs/games/whowtbam/trunk/wwtbam.cpp new file mode 100644 index 0000000000..8bca2619f8 --- /dev/null +++ b/programs/games/whowtbam/trunk/wwtbam.cpp @@ -0,0 +1,1283 @@ +// " ?" +// by (Dron2004) + +#include +#include + +char sVersion[] = " 0.1"; + +int status=0; + +bool needcleanup = false; // , ... +int questioncount = 0; // +int currentquestion = 0; // (1, 2, ..., 15) + +int askedquestions[15]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + +char friendsAdvice[1]={' '}; + +char summs[][16]={"0","100","200","300","500","1000","2000","4000","8000","16000","32000","64000","125000","250000","500000","1000000"}; +char * question; +char * answerA; +char * answerB; +char * answerC; +char * answerD; +Byte correctanswer=0x00; + +int questionlength=0; +int answerAlength=0; +int answerBlength=0; +int answerClength=0; +int answerDlength=0; + +bool na50available = true; +bool callfriendavailable = true; +bool zalavailable = true; + +int zalA=0; +int zalB=0; +int zalC=0; +int zalD=0; + + + +bool drawA = true; +bool drawB = true; +bool drawC = true; +bool drawD = true; + + + + +char * tempquestion; +char * tempanswerA; +char * tempanswerB; +char * tempanswerC; +char * tempanswerD; +Byte tempcorrectanswer=0x00; +int tempquestionlength=0; +int tempanswerAlength=0; +int tempanswerBlength=0; +int tempanswerClength=0; +int tempanswerDlength=0; + + + + +const char header[]=" ஬ Kolibri OS"; +void app_halt(); + +char * filepathname; // +void getFilePathName(){ + int lastslashindex=0; + char ourfilename[]="appdata.dat"; + int tmpcnt=0; + + for (tmpcnt=0;tmpcnt0){ + basefile.Read (inputbyte,1); + if (inputbyte[0]==0x10){ + skipsleft--; + } + inputbyte[0]=0x00; + } + + // + basefile.Read (inputbyte,1); + + // , + // ( ; 1000000 , + // 100 :-))) + + if (inputbyte[0]==0x05) //˸ + { + if (currentquestion > 5){ //˸ - 1 5 + goto regenerate; // 6 - + } + } + if (inputbyte[0]==0x06) // + { + if ((currentquestion < 6)||(currentquestion > 10)){ // - 6 10 + goto regenerate; + } + } + if (inputbyte[0]==0x07) // + { + if (currentquestion < 11){ // - 11 15 + goto regenerate; + } + } + + + for (int counter=0; counter 0){ + basefile2.Read (inputbyte,1); + if (inputbyte[0]==0x10){ + skipsleft--; + } + inputbyte[0]=0x00; + } + + basefile2.Read (inputbyte,1); // - . . + + // + int currentbyte=0; + while (inputbyte[0]!=0x01){ + basefile2.Read (inputbyte,1); + if (inputbyte[0]!=0x01){tempquestion[currentbyte]=inputbyte[0];} + currentbyte++; + } + tempquestion[currentbyte]='\n'; + + // A + currentbyte=0; + while (inputbyte[0]!=0x02){ + basefile2.Read (inputbyte,1); + if (inputbyte[0]!=0x02){tempanswerA[currentbyte]=inputbyte[0];} + currentbyte++; + } + tempanswerA[currentbyte]='\n'; + + // B + currentbyte=0; + while (inputbyte[0]!=0x03){ + basefile2.Read (inputbyte,1); + if (inputbyte[0]!=0x03){tempanswerB[currentbyte]=inputbyte[0];} + currentbyte++; + } + tempanswerB[currentbyte]='\n'; + + // C + currentbyte=0; + while (inputbyte[0]!=0x04){ + basefile2.Read (inputbyte,1); + if (inputbyte[0]!=0x04){tempanswerC[currentbyte]=inputbyte[0];} + currentbyte++; + } + tempanswerC[currentbyte]='\n'; + + // D + currentbyte=0; + while (inputbyte[0]!=0x08){ + basefile2.Read (inputbyte,1); + if (inputbyte[0]!=0x08){tempanswerD[currentbyte]=inputbyte[0];} + currentbyte++; + } + tempanswerD[currentbyte]='\n'; + + basefile2.Read (inputbyte,1); // - + tempcorrectanswer=inputbyte[0]; + // Ѩ!!!!!! !!!! ! + + //. . + questionlength = 0; + answerAlength = 0; + answerBlength = 0; + answerClength = 0; + answerDlength = 0; + // + questionlength=tempquestionlength; + question = new char[questionlength]; + for (int cd=0; cd - ", 0); + kos_WriteTextToWindow (10,85,0x80,0x770000, " - 室", 0); + + kos_WriteTextToWindow (10,150,0x80,0x000000, "(C) 2008 ३ 堩 aka Dron2004", 0); + //kos_DisplayNumberToWindow (questioncount,3,40,60,0x000000, nbDecimal, false); + } + if (status==1){ // + + kos_DrawBar(0,0,610,174,0xEEEEFF); + + kos_WriteTextToWindow (10,10,0x0,0x000000, question, questionlength-1); + + if (drawA==true){ + kos_WriteTextToWindow (10,40,0x80,0x000000, "A. ", 0); + kos_WriteTextToWindow (30,40,0x0,0x000000, answerA, answerAlength-1); + } + if (drawB==true){ + kos_WriteTextToWindow (10,60,0x80,0x000000, "B. ", 0); + kos_WriteTextToWindow (30,60,0x0,0x000000, answerB, answerBlength-1); + } + if (drawC==true){ + kos_WriteTextToWindow (10,80,0x80,0x000000, "C. ", 0); + kos_WriteTextToWindow (30,80,0x0,0x000000, answerC, answerClength-1); + } + if (drawD==true){ + kos_WriteTextToWindow (10,100,0x80,0x000000, "D. ", 0); + kos_WriteTextToWindow (30,100,0x0,0x000000, answerD, answerDlength-1); + } + if (na50available==true){kos_WriteTextToWindow (30,150,0x80,0x000000, "<7> 50 50", 0);} + if (callfriendavailable==true){kos_WriteTextToWindow (150,150,0x80,0x000000, "<8> ", 0);} + if (zalavailable==true){kos_WriteTextToWindow (280,150,0x80,0x000000, "<9> ᪠ ", 0);} + + if((na50available==false)&&(callfriendavailable==false)&&(zalavailable==false)) {kos_WriteTextToWindow (30,150,0x80,0x000000, " - 죨 ", 0);} + + kos_WriteTextToWindow (430,130,0x80,0x000000, " ", 0); + kos_WriteTextToWindow (500,130,0x80,0x000000, summs[currentquestion], 0); + + kos_WriteTextToWindow (430,150,0x80,0x000000, " ", 0); + kos_WriteTextToWindow (500,150,0x80,0x000000, summs[currentquestion-1], 0); + + + + } + if (status==2){ // " - " + kos_DrawBar(0,0,610,174,0xDDFFDD); + kos_WriteTextToWindow (10,10,0x80,0x000000, ", ࠢ ⢥!", 0); + + kos_WriteTextToWindow (10,150,0x80,0x000000, " - த", 0); + } + if (status==3){ // , !!! + kos_DrawBar(0,0,610,174,0x00FF00); + kos_WriteTextToWindow (10,10,0x80,0x000000, " 먣ࠫ !!!", 0); + kos_WriteTextToWindow (10,150,0x80,0x000000, " - 室", 0); + } + if (status==4){ // + kos_DrawBar(0,0,610,174,0xAAFFFF); + kos_WriteTextToWindow (10,10,0x80,0x000000, " ᮢ ⢥", 0); + kos_WriteTextToWindow (165,10,0x80,0x000000, friendsAdvice, 0); + kos_WriteTextToWindow (10,150,0x80,0x000000, " - த", 0); + } + if (status==5){ // + kos_DrawBar(0,0,610,174,0xAAFFFF); + kos_WriteTextToWindow (10,10,0x80,0x000000, " 㤨ਨ । ⠪:", 0); + if (drawA==true){ + kos_WriteTextToWindow (10,30,0x80,0x000000, "⢥ A: ", 0); + kos_DisplayNumberToWindow(zalA,3,60,30,0x000000,nbDecimal,0); + kos_WriteTextToWindow (80,30,0x80,0x000000, "%", 0); + } + if (drawB==true){ + kos_WriteTextToWindow (10,45,0x80,0x000000, "⢥ B: ", 0); + kos_DisplayNumberToWindow(zalB,3,60,45,0x000000,nbDecimal,0); + kos_WriteTextToWindow (80,45,0x80,0x000000, "%", 0); + } + if (drawC==true){ + kos_WriteTextToWindow (10,60,0x80,0x000000, "⢥ C: ", 0); + kos_DisplayNumberToWindow(zalC,3,60,60,0x000000,nbDecimal,0); + kos_WriteTextToWindow (80,60,0x80,0x000000, "%", 0); + } + if (drawD==true){ + kos_WriteTextToWindow (10,75,0x80,0x000000, "⢥ D: ", 0); + kos_DisplayNumberToWindow(zalD,3,60,75,0x000000,nbDecimal,0); + kos_WriteTextToWindow (80,75,0x80,0x000000, "%", 0); + } + + + + + + kos_WriteTextToWindow (10,150,0x80,0x000000, " - த", 0); + } + + if (status==6){ // ;-) + kos_DrawBar(0,0,610,174,0xBBFFBB); + kos_WriteTextToWindow (10,10,0x80,0x000000, " ࠫ 죨 諨. 먣 ⠢:", 0); + kos_WriteTextToWindow (10,20,0x80,0x000000, summs[currentquestion-1], 0); + kos_WriteTextToWindow (10,150,0x80,0x000000, " - 室", 0); + } + if (status==-1){ // :-( + kos_DrawBar(0,0,610,174,0xFF8888); + kos_WriteTextToWindow (10,10,0x80,0x000000, " ᮦ, 訡... ࠢ ⢥ -", 0); + + switch (correctanswer){ + case 0x01: + kos_WriteTextToWindow (10,25,0x80,0x000000, "A. ", 0); + kos_WriteTextToWindow (30,25,0x0,0x000000, answerA, answerAlength-1); + break; + case 0x02: + kos_WriteTextToWindow (10,25,0x80,0x000000, "B. ", 0); + kos_WriteTextToWindow (30,25,0x0,0x000000, answerB, answerBlength-1); + break; + case 0x03: + kos_WriteTextToWindow (10,25,0x80,0x000000, "C. ", 0); + kos_WriteTextToWindow (30,25,0x0,0x000000, answerC, answerClength-1); + break; + case 0x04: + kos_WriteTextToWindow (10,25,0x80,0x000000, "D. ", 0); + kos_WriteTextToWindow (30,25,0x0,0x000000, answerD, answerDlength-1); + break; + } + kos_WriteTextToWindow (10,50,0x80,0x000000, " १ 먣ࠫ:", 0); + + if (currentquestion<6) {kos_WriteTextToWindow (220,50,0x80,0x000000,summs[0], 0);} + if ((currentquestion>5)&&(currentquestion<11)) {kos_WriteTextToWindow (220,50,0x80,0x000000,summs[5], 0);} + if (currentquestion>10) {kos_WriteTextToWindow (220,50,0x80,0x000000,summs[10], 0);} + + + + + kos_WriteTextToWindow (10,150,0x80,0x000000, " - 室", 0); + } + + kos_WindowRedrawStatus(2); + +} + + + +void call_friend(){ + int tmpcodee; + + recode5: + tmpcodee =(rtlRand()%10)+1; + int tmpbyte; + + if (currentquestion < 6 ){ + if (tmpcodee>3){ // + if (correctanswer==0x01) {friendsAdvice[0]='A';} + if (correctanswer==0x02) {friendsAdvice[0]='B';} + if (correctanswer==0x03) {friendsAdvice[0]='C';} + if (correctanswer==0x04) {friendsAdvice[0]='D';} + } + else // + { + + int tmpbyte2=0; + recode51: + int tmpcodee2=(rtlRand()%4)+1; + + switch(tmpcodee2){ + case 1: + friendsAdvice[0]='A'; + break; + case 2: + friendsAdvice[0]='B'; + break; + case 3: + friendsAdvice[0]='C'; + break; + case 4: + friendsAdvice[0]='D'; + break; + } + } + + } + + if ((currentquestion > 5) && (currentquestion<11)){ + if (tmpcodee>5){ // + if (correctanswer==0x01) {friendsAdvice[0]='A';} + if (correctanswer==0x02) {friendsAdvice[0]='B';} + if (correctanswer==0x03) {friendsAdvice[0]='C';} + if (correctanswer==0x04) {friendsAdvice[0]='D';} + } + else // + { + + int tmpbyte2=0; + recode52: + int tmpcodee2=(rtlRand()%4)+1; + switch(tmpcodee2){ + case 1: + friendsAdvice[0]='A'; + break; + case 2: + friendsAdvice[0]='B'; + break; + case 3: + friendsAdvice[0]='C'; + break; + case 4: + friendsAdvice[0]='D'; + break; + } + } + + } + + if (currentquestion > 10){ + if (tmpcodee>7){ // + if (correctanswer==0x01) {friendsAdvice[0]='A';} + if (correctanswer==0x02) {friendsAdvice[0]='B';} + if (correctanswer==0x03) {friendsAdvice[0]='C';} + if (correctanswer==0x04) {friendsAdvice[0]='D';} + } + else // + { + + int tmpbyte2=0; + recode53: + int tmpcodee2=(rtlRand()%4)+1; + + switch(tmpcodee2){ + case 1: + friendsAdvice[0]='A'; + break; + case 2: + friendsAdvice[0]='B'; + break; + case 3: + friendsAdvice[0]='C'; + break; + case 4: + friendsAdvice[0]='D'; + break; + } + } + + if ((friendsAdvice[0]=='A')&&(drawA==false)){goto recode5;} + if ((friendsAdvice[0]=='B')&&(drawB==false)){goto recode5;} + if ((friendsAdvice[0]=='C')&&(drawC==false)){goto recode5;} + if ((friendsAdvice[0]=='D')&&(drawD==false)){goto recode5;} + } + + + + + + +} + +void call_zal(){ // + int maxpercent=0; + for (int tmpc=0; tmpc<(16-currentquestion);tmpc=tmpc+2){ + maxpercent=(rtlRand()%101); + if (maxpercent>50) {break;} + } + + if ((drawA==true)&&(drawB==true)&&(drawC==true)&&(drawD==true)){ + switch (correctanswer){ + case 0x01: + zalA=maxpercent; + zalB=(rtlRand()%(101-zalA)); + zalC=(rtlRand()%(101-zalA-zalB)); + zalD=100-zalA-zalB-zalC; + break; + + case 0x02: + zalB=maxpercent; + zalA=(rtlRand()%(101-zalB)); + zalC=(rtlRand()%(101-zalA-zalB)); + zalD=100-zalA-zalB-zalC; + break; + + case 0x03: + zalC=maxpercent; + zalB=(rtlRand()%(101-zalC)); + zalA=(rtlRand()%(101-zalC-zalB)); + zalD=100-zalA-zalB-zalC; + break; + + case 0x04: + zalD=maxpercent; + zalB=(rtlRand()%(101-zalD)); + zalC=(rtlRand()%(101-zalD-zalB)); + zalA=100-zalD-zalB-zalC; + break; + } + } + else + { + if ((drawA==true)&&(drawB==true)){ + if (correctanswer==0x01){ + zalA=maxpercent; + zalB=100-zalA; + } + else + { + zalB=maxpercent; + zalA=100-zalB; + } + } + if ((drawA==true)&&(drawC==true)){ + if (correctanswer==0x01){ + zalA=maxpercent; + zalC=100-zalA; + } + else + { + zalC=maxpercent; + zalA=100-zalC; + } + } + if ((drawA==true)&&(drawD==true)){ + if (correctanswer==0x01){ + zalA=maxpercent; + zalD=100-zalA; + } + else + { + zalD=maxpercent; + zalA=100-zalD; + } + } + + if ((drawB==true)&&(drawC==true)){ + if (correctanswer==0x02){ + zalB=maxpercent; + zalC=100-zalB; + } + else + { + zalC=maxpercent; + zalB=100-zalC; + } + } + if ((drawB==true)&&(drawD==true)){ + if (correctanswer==0x02){ + zalB=maxpercent; + zalD=100-zalB; + } + else + { + zalD=maxpercent; + zalB=100-zalD; + } + } + + if ((drawC==true)&&(drawD==true)){ + if (correctanswer==0x03){ + zalC=maxpercent; + zalD=100-zalC; + } + else + { + zalD=maxpercent; + zalC=100-zalD; + } + } + + } +} + +void kos_Main(){ + rtlSrand(kos_GetSystemClock() / 10000); + getFilePathName(); + prepareFileData(); + draw_window(); + while (true){ + + switch (kos_WaitForEvent()){ + case 1: + draw_window(); + break; + case 2: + Byte keyCode; + kos_GetKey(keyCode); + + if (status==0){ // + if (keyCode==27){ + app_halt(); + } + if (keyCode==13){ + currentquestion=1; + status=1; + loadquestion(); + ////// !!!!!!! ///////// + draw_window(); + + } + } + if (status==1){ // + + if (keyCode==8){ + status=6; + draw_window(); + } + + if (drawA==true){ + if ((keyCode==49)||(keyCode==97)||(keyCode==65)){ + if (correctanswer==0x01){ + status=2; + } + else + { + status=-1; + } + drawA = true; + drawB = true; + drawC = true; + drawD = true; + + draw_window(); + } + } + + if (drawB==true){ + if ((keyCode==50)||(keyCode==98)||(keyCode==66)){ + if (correctanswer==0x02){ + status=2; + } + else + { + status=-1; + } + drawA = true; + drawB = true; + drawC = true; + drawD = true; + + draw_window(); + } + } + if (drawC==true){ + if ((keyCode==51)||(keyCode==99)||(keyCode==67)){ + if (correctanswer==0x03){ + status=2; + } + else + { + status=-1; + } + drawA = true; + drawB = true; + drawC = true; + drawD = true; + + draw_window(); + } + } + if (drawD==true){ + if ((keyCode==52)||(keyCode==100)||(keyCode==68)){ + if (correctanswer==0x04){ + status=2; + } + else + { + status=-1; + } + drawA = true; + drawB = true; + drawC = true; + drawD = true; + + draw_window(); + } + } + + if (callfriendavailable==true){ // " " + if (keyCode==56){ + callfriendavailable=false; + status=4; + call_friend(); + draw_window(); + } + } + + if (zalavailable==true){ // + if (keyCode==57){ + zalavailable=false; + status=5; + call_zal(); + draw_window(); + } + } + + if (na50available==true){ // "50 50" + if (keyCode==55){ + + if (correctanswer==0x01){ + drawA=true; + + int tmpcodee; + + recode1: + tmpcodee =(rtlRand()%3)+1; + + int tmpbyte; + + switch(tmpcodee){ + case 1: + drawB=true; + drawC=false; + drawD=false; + break; + case 2: + drawB=false; + drawC=true; + drawD=false; + case 3: + drawB=false; + drawC=false; + drawD=true; + + } + } + if (correctanswer==0x02){ + drawB=true; + + int tmpcodee; + + recode2: + tmpcodee =(rtlRand()%3)+1; + + int tmpbyte; + + + switch(tmpcodee){ + case 1: + drawA=true; + drawC=false; + drawD=false; + break; + case 2: + drawA=false; + drawC=true; + drawD=false; + case 3: + drawA=false; + drawC=false; + drawD=true; + + } + } + if (correctanswer==0x03){ + drawC=true; + + int tmpcodee; + + recode3: + tmpcodee =(rtlRand()%3)+1; + int tmpbyte; + + + switch(tmpcodee){ + case 1: + drawB=true; + drawA=false; + drawD=false; + break; + case 2: + drawB=false; + drawA=true; + drawD=false; + case 3: + drawB=false; + drawA=false; + drawD=true; + + } + } + if (correctanswer==0x04){ + drawA=true; + + int tmpcodee; + + recode4: + tmpcodee =(rtlRand()%3)+1; + + int tmpbyte; + + + switch(tmpcodee){ + case 1: + drawB=true; + drawC=false; + drawA=false; + break; + case 2: + drawB=false; + drawC=true; + drawA=false; + case 3: + drawB=false; + drawC=false; + drawA=true; + + } + } + na50available=false; + draw_window(); + + } + } + + } + if (status==2){ // " - !" + if (keyCode==13){ + if (currentquestion<15){ + currentquestion++; + status=1; + loadquestion(); + draw_window(); + } + else + { + status=3; + draw_window(); + } + + } + } + if (status==3){ // + if (keyCode==27){ + app_halt(); + } + } + if (status==4){ // + if (keyCode==13){ + status=1; + draw_window(); + } + } + if (status==5){ // + if (keyCode==13){ + status=1; + draw_window(); + } + } + if (status==6){ // ;-) + if (keyCode==27){ + app_halt(); + } + } + if (status==-1){ // :-( + if (keyCode==27){ + app_halt(); + } + } + + //kos_DrawBar(38,118,50,130,0xBBBBBB); + //kos_DisplayNumberToWindow (keyCode,3,40,120,0x000000, nbDecimal, false); + + + break; + case 3: + app_halt(); + break; + } + + } +} + + +void app_halt(){ + delete filepathname; + + if (needcleanup==true){ + delete question; + delete answerA; + delete answerB; + delete answerC; + delete answerD; + } + kos_ExitApp(); +} diff --git a/programs/games/xonix/trunk/MCSMEMM.H b/programs/games/xonix/trunk/MCSMEMM.H new file mode 100644 index 0000000000..42d61eaadb --- /dev/null +++ b/programs/games/xonix/trunk/MCSMEMM.H @@ -0,0 +1,28 @@ +// + +struct MemBlock +{ + Dword Size; + Dword Addr; + MemBlock *Next; + MemBlock *Previous; +}; + + +#define INITIALQUEUESIZE (32 * 4) + +#define FALSE 0 +#define TRUE -1 + +#define MB_FREE 0 +#define MB_USER 1 + +#define SIZE_ALIGN 4 + + + +Byte *allocmem( Dword reqsize ); +Dword freemem( void *vaddress ); + + + diff --git a/programs/games/xonix/trunk/Release/pe2kos.exe b/programs/games/xonix/trunk/Release/pe2kos.exe new file mode 100644 index 0000000000..bef0e7ce2d Binary files /dev/null and b/programs/games/xonix/trunk/Release/pe2kos.exe differ diff --git a/programs/games/xonix/trunk/fatest.sln b/programs/games/xonix/trunk/fatest.sln new file mode 100644 index 0000000000..80c2e07567 --- /dev/null +++ b/programs/games/xonix/trunk/fatest.sln @@ -0,0 +1,19 @@ +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fatest", "fatest.vcproj", "{9A6F70FC-7AC8-4C42-9B67-FD65BE79F79A}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {9A6F70FC-7AC8-4C42-9B67-FD65BE79F79A}.Debug|Win32.ActiveCfg = Debug|Win32 + {9A6F70FC-7AC8-4C42-9B67-FD65BE79F79A}.Debug|Win32.Build.0 = Debug|Win32 + {9A6F70FC-7AC8-4C42-9B67-FD65BE79F79A}.Release|Win32.ActiveCfg = Release|Win32 + {9A6F70FC-7AC8-4C42-9B67-FD65BE79F79A}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/programs/games/xonix/trunk/fatest.vcproj b/programs/games/xonix/trunk/fatest.vcproj new file mode 100644 index 0000000000..a2e32f872d --- /dev/null +++ b/programs/games/xonix/trunk/fatest.vcproj @@ -0,0 +1,246 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/programs/games/xonix/trunk/kosSyst.cpp b/programs/games/xonix/trunk/kosSyst.cpp new file mode 100644 index 0000000000..af685c0927 --- /dev/null +++ b/programs/games/xonix/trunk/kosSyst.cpp @@ -0,0 +1,829 @@ +#include "kosSyst.h" + +#define atexitBufferSize 32 + + +char pureCallMessage[] = "PURE function call!"; + +char *kosExePath = NULL; + +// +void (__cdecl *atExitList[atexitBufferSize])(); +int atExitFnNum = 0; +// +int __cdecl atexit( void (__cdecl *func )( void )) +{ + // + if ( atExitFnNum < atexitBufferSize ) + { + // + atExitList[atExitFnNum++] = func; + return 0; + } + else + { + return 1; + } +} + + +// +Dword RandomSeed = 1; +// +void rtlSrand( Dword seed ) +{ + RandomSeed = seed; +} +// +Dword rtlRand( void ) +{ + // 0x80000776 + + Dword dwi, i; + + for ( i = 0; i < 32; i++ ) + { + + dwi = RandomSeed & 0x80000776; + + __asm{ + mov eax, dwi + mov edx, eax + bswap eax + xor eax, edx + xor al, ah + setpo al + movzx eax, al + mov dwi, eax + } + + RandomSeed = ( RandomSeed << 1 ) | ( dwi & 1 ); + } + + return RandomSeed; +} + +// +void * __cdecl memcpy( void *dst, const void *src, size_t bytesCount ) +{ + __asm{ + mov edi, dst + mov eax, dst + mov esi, src + mov ecx, bytesCount + rep movsb + } +} + +// +void memset( Byte *dst, Byte filler, Dword count ) +{ + // + __asm{ + mov edi, dst + mov al, filler + mov ecx, count + rep stosb + } +} + +// +Dword rtlInterlockedExchange( Dword *target, Dword value ) +{ +// Dword result; + + // + __asm{ + mov eax, value + mov ebx, target + xchg eax, [ebx] +// mov result, eax + } + // +// return result; +} + + +////////////////////////////////////////////////////////////////////// +// +// +// + +char * __cdecl strcpy( char *target, const char *source ) +{ + char *result = target; + + while( target[0] = source[0] ) + { + target++; + source++; + } + + return result; +} + + +////////////////////////////////////////////////////////////////////// +// +// +// + +char * __cdecl strrchr( const char * string, int c ) +{ + char *cPtr; + + // + for ( cPtr = (char *)string + strlen( string ); cPtr >= string; cPtr-- ) + { + // + if ( *cPtr == c ) return cPtr; + } + // + return NULL; +} + + +////////////////////////////////////////////////////////////////////// +// +// +// + +int __cdecl strlen( const char *line ) +{ + int i; + + for( i=0; line[i] != 0; i++ ); + return i; +} + + + +////////////////////////////////////////////////////////////////////// +// +// +// + +unsigned int num2hex( unsigned int num ) +{ + if( num < 10 ) + return num + '0'; + return num - 10 + 'A'; +} + + +////////////////////////////////////////////////////////////////////// +// +// +// + +Dword dectab[] = { 1000000000, 100000000, 10000000, 1000000, 100000, + 10000, 1000, 100, 10, 0 }; + +// +void sprintk( char *Str, PRINTK *arg ) +{ + int i, fmtlinesize, j, ac, k, flag; + Dword head, tail; + char c; + + // + ac = 0; + + // + fmtlinesize = strlen( arg->fmtline ); + // + if( fmtlinesize == 0 ) return; + + // + for( i = 0, j = 0; i < fmtlinesize; i++ ) + { + // + c = arg->fmtline[i]; + // + if( c != '%' ) + { + Str[j++] = c; + continue; + } + // + i++; + // + if( i >= fmtlinesize ) break; + + // + flag = 0; + // + c = arg->fmtline[i]; + // + switch( c ) + { + // + case '%': + Str[j++] = c; + break; + // + case 'S': + for( k = 0; ( c = ((Byte *)arg->args[ac])[k] ) != 0; k++ ) + { + Str[j++] = c; + } + ac++; + break; + // + case 'B': + k = (int)(arg->args[ac]) & 0xFF; + Str[j++] = num2hex( ( k >> 4 ) & 0xF ); + Str[j++] = num2hex( k & 0xF ); + ac++; + break; + // + case 'C': + Str[j++] = (int)(arg->args[ac]) & 0xFF; + ac++; + break; + // + case 'X': + for( k = 7; k >= 0; k-- ) + { + // + c = num2hex ( ( (Dword)(arg->args[ac]) >> (k * 4) ) & 0xF ); + // + if( c == '0' ) + { + if( flag ) Str[j++] = c; + } + else + { + flag++; + Str[j++] = c; + } + } + // + if( flag == 0 ) Str[j++] = '0'; + ac++; + break; + // + case 'U': + head = (Dword)(arg->args[ac]); + tail = 0; + for( k = 0; dectab[k] != 0; k++ ) + { + tail = head % dectab[k]; + head /= dectab[k]; + c = head + '0'; + if( c == '0' ) + { + if( flag ) Str[j++] = c; + } + else + { + flag++; + Str[j++] = c; + } + // + head = tail; + } + // + c = head + '0'; + Str[j++] = c; + ac++; + break; + // 64- + case 'Q': + for( k = 7; k >= 0; k-- ) + { + // + c = num2hex ( ( *((unsigned int *)(arg->args[ac]) + 1) >> (k * 4) ) & 0xF ); + // + if( c == '0' ) + { + if( flag ) Str[j++] = c; + } + else + { + flag++; + Str[j++] = c; + } + } + // + for( k=7; k >= 0; k-- ) + { + // + c = num2hex ( ( *((unsigned int *)(arg->args[ac])) >> (k * 4) ) & 0xF ); + // + if( c == '0' ) + { + if( flag ) Str[j++] = c; + } + else + { + flag++; + Str[j++] = c; + } + } + // + if( flag == 0 ) Str[j++] = '0'; + // + ac++; + break; + // + default: + break; + } + } + // + Str[j] = 0; +} + + +// -1 +void kos_ExitApp() +{ + int i; + + // + for ( i = atExitFnNum - 1; i >= 0; i-- ) + { + // + atExitList[i](); + } + // + __asm{ + mov eax, -1 + int 0x40 + } +} + + +// 0 +void kos_DefineAndDrawWindow( + Word x, Word y, + Word sizeX, Word sizeY, + Byte mainAreaType, + Dword mainAreaColour, + Byte headerType, + Dword headerColour, + Dword borderColour + ) +{ + Dword arg1, arg2, arg3, arg4; + + // + arg1 = ( x << 16 ) + sizeX; + arg2 = ( y << 16 ) + sizeY; + arg3 = ( mainAreaType << 24 ) | mainAreaColour; + arg4 = ( headerType << 24 ) | headerColour; + // + __asm{ + mov eax, 0 + mov ebx, arg1 + mov ecx, arg2 + mov edx, arg3 + mov esi, arg4 + mov edi, borderColour + int 0x40 + } +} + + +// 1 +void kos_PutPixel( Dword x, Dword y, Dword colour ) +{ + // + __asm{ + mov eax, 1 + mov ebx, x + mov ecx, y + mov edx, colour + int 0x40 + } +} + + +// 2 +bool kos_GetKey( Byte &keyCode ) +{ + Dword result; + + // + __asm{ + mov eax, 2 + int 0x40 + mov result, eax + } + // + keyCode = result >> 8; + // + return ( result & 0xFF ) == 0; +} + + +// 3 +Dword kos_GetSystemClock() +{ +// Dword result; + + // + __asm{ + mov eax, 3 + int 0x40 +// mov result, eax + } + // +// return result; +} + + +// 4 +void kos_WriteTextToWindow( + Word x, + Word y, + Byte fontType, + Dword textColour, + char *textPtr, + Dword textLen + ) +{ + Dword arg1, arg2; + + // + arg1 = ( x << 16 ) | y; + arg2 = ( fontType << 24 ) | textColour; + // + __asm{ + mov eax, 4 + mov ebx, arg1 + mov ecx, arg2 + mov edx, textPtr + mov esi, textLen + int 0x40 + } +} + + +// 5 , +void kos_Pause( Dword value ) +{ + // + __asm{ + mov eax, 5 + mov ebx, value + int 0x40 + } +} + + +// 7 +void kos_PutImage( RGB * imagePtr, Word sizeX, Word sizeY, Word x, Word y ) +{ + Dword arg1, arg2; + + // + arg1 = ( sizeX << 16 ) | sizeY; + arg2 = ( x << 16 ) | y; + // + __asm{ + mov eax, 7 + mov ebx, imagePtr + mov ecx, arg1 + mov edx, arg2 + int 0x40 + } +} + + + +// 8 +void kos_DefineButton( Word x, Word y, Word sizeX, Word sizeY, Dword buttonID, Dword colour ) +{ + Dword arg1, arg2; + + // + arg1 = ( x << 16 ) | sizeX; + arg2 = ( y << 16 ) | sizeY; + // + __asm{ + mov eax, 8 + mov ebx, arg1 + mov ecx, arg2 + mov edx, buttonID + mov esi, colour + int 0x40 + } +} + + +// 9 - +Dword kos_ProcessInfo( sProcessInfo *targetPtr, Dword processID ) +{ +// Dword result; + + // + __asm{ + mov eax, 9 + mov ebx, targetPtr + mov ecx, processID + int 0x40 +// mov result, eax + } + // +// return result; +} + + +// 10 +Dword kos_WaitForEvent() +{ +// Dword result; + + __asm{ + mov eax, 10 + int 0x40 +// mov result, eax + } + +// return result; +} + + +// 11 +Dword kos_CheckForEvent() +{ +// Dword result; + + __asm{ + mov eax, 11 + int 0x40 +// mov result, eax + } + +// return result; +} + + +// 12 +void kos_WindowRedrawStatus( Dword status ) +{ + __asm{ + mov eax, 12 + mov ebx, status + int 0x40 + } +} + + +// 13 +void kos_DrawBar( Word x, Word y, Word sizeX, Word sizeY, Dword colour ) +{ + Dword arg1, arg2; + + // + arg1 = ( x << 16 ) | sizeX; + arg2 = ( y << 16 ) | sizeY; + // + __asm{ + mov eax, 13 + mov ebx, arg1 + mov ecx, arg2 + mov edx, colour + int 0x40 + } +} + + +// 17 +bool kos_GetButtonID( Dword &buttonID ) +{ + Dword result; + + // + __asm{ + mov eax, 17 + int 0x40 + mov result, eax + } + // + buttonID = result >> 8; + // + return (result & 0xFF) == 0; +} + + +// 23 +Dword kos_WaitForEvent( Dword timeOut ) +{ +// Dword result; + + __asm{ + mov eax, 23 + mov ebx, timeOut + int 0x40 +// mov result, eax + } + +// return result; +} + + +// "" 37 +void kos_GetMouseState( Dword & buttons, int & cursorX, int & cursorY ) +{ + Dword mB; + Word curX; + Word curY; + sProcessInfo sPI; + + // + __asm{ + mov eax, 37 + mov ebx, 0 + int 0x40 + mov curY, ax + shr eax, 16 + mov curX, ax + mov eax, 37 + mov ebx, 2 + int 0x40 + mov mB, eax + } + // + kos_ProcessInfo( &sPI ); + // + buttons = mB; + cursorX = curX - sPI.processInfo.x_start; + cursorY = curY - sPI.processInfo.y_start; +} + + +// 40 +void kos_SetMaskForEvents( Dword mask ) +{ + // + __asm{ + mov eax, 40 + mov ebx, mask + int 0x40 + } +} + + +// 47 +void kos_DisplayNumberToWindow( + Dword value, + Dword digitsNum, + Word x, + Word y, + Dword colour, + eNumberBase nBase, + bool valueIsPointer + ) +{ + Dword arg1, arg2; + + // + arg1 = ( valueIsPointer ? 1 : 0 ) | + ( ((Byte)nBase) << 8 ) | + ( ( digitsNum & 0x1F ) << 16 ); + arg2 = ( x << 16 ) | y; + // + __asm{ + mov eax, 47 + mov ebx, arg1 + mov ecx, value + mov edx, arg2 + mov esi, colour + int 0x40 + } +} + + +// 70 +Dword kos_FileSystemAccess( kosFileInfo *fileInfo ) +{ +// Dword result; + + // + __asm{ + mov eax, 70 + mov ebx, fileInfo + int 0x40 +// mov result, eax + } + // +// return result; +} + + +// 63 +void kos_DebugOutChar( char ccc ) +{ + // + __asm{ + mov eax, 63 + mov ebx, 1 + mov cl, ccc + int 0x40 + } +} + + +// 66 +void kos_SetKeyboardDataMode( Dword mode ) +{ + // + __asm{ + mov eax, 66 + mov ebx, 1 + mov ecx, mode + int 0x40 + } +} + + +// +void rtlDebugOutString( char *str ) +{ + // + for ( ; str[0] != 0; str++ ) + { + kos_DebugOutChar( str[0] ); + } + // + kos_DebugOutChar( 13 ); + kos_DebugOutChar( 10 ); +} + + +// 64 , +bool kos_ApplicationMemoryResize( Dword targetSize ) +{ + Dword result; + + // + __asm{ + mov eax, 64 + mov ebx, 1 + mov ecx, targetSize + int 0x40 + mov result, eax + } + // + return result == 0; +} + + +// 67 , == -1 +void kos_ChangeWindow( Dword x, Dword y, Dword sizeX, Dword sizeY ) +{ + // + __asm{ + mov eax, 67 + mov ebx, x + mov ecx, y + mov edx, sizeX + mov esi, sizeY + int 0x40 + } +} + + + +// +int __cdecl _purecall() +{ + rtlDebugOutString( pureCallMessage ); + kos_ExitApp(); + return 0; +} + + +// +// +#pragma section(".CRT$XCA",long,read,write) +#pragma section(".CRT$XCZ",long,read,write) +typedef void (__cdecl *_PVFV)(void); +__declspec(allocate(".CRT$XCA")) _PVFV __xc_a[1] = { NULL }; +__declspec(allocate(".CRT$XCZ")) _PVFV __xc_z[1] = { NULL }; +// +#pragma comment(linker, "/merge:.CRT=.rdata") +// +void crtStartUp() +{ + // , NULL' + for ( _PVFV *pbegin = __xc_a; pbegin < __xc_z; pbegin++ ) + { + // + if ( *pbegin != NULL ) + (**pbegin)(); + } + // + rtlSrand( kos_GetSystemClock() ); + // + kosExePath = *((char **)0x20); + // + kos_Main(); + // + kos_ExitApp(); +} + + diff --git a/programs/games/xonix/trunk/kosSyst.h b/programs/games/xonix/trunk/kosSyst.h new file mode 100644 index 0000000000..aed509e253 --- /dev/null +++ b/programs/games/xonix/trunk/kosSyst.h @@ -0,0 +1,201 @@ +typedef unsigned __int32 Dword; +typedef unsigned __int16 Word; +typedef unsigned __int8 Byte; +typedef unsigned __int32 size_t; + +#define NULL 0 + +#define MAX_PATH 256 + +#define FO_READ 0 +#define FO_WRITE 2 + +#define EM_WINDOW_REDRAW 1 +#define EM_KEY_PRESS 2 +#define EM_BUTTON_CLICK 4 +#define EM_APP_CLOSE 8 +#define EM_DRAW_BACKGROUND 16 +#define EM_MOUSE_EVENT 32 +#define EM_IPC 64 +#define EM_NETWORK 256 + +#define KM_CHARS 0 +#define KM_SCANS 1 + +#define WRS_BEGIN 1 +#define WRS_END 2 + +#define PROCESS_ID_SELF -1 + +#define abs(a) (a<0?0-a:a) + + +struct kosFileInfo +{ + Dword rwMode; + Dword offsetLow; + Dword offsetHigh; + Dword dataCount; + Byte *bufferPtr; + char fileURL[MAX_PATH]; +}; + + +struct RGB +{ + Byte b; + Byte g; + Byte r; + // + RGB() {}; + // + RGB( Dword value ) + { + r = value >> 16; + g = value >> 8; + b = value; + }; + // + bool operator != ( RGB &another ) + { + return this->b != another.b || this->g != another.g || this->r != another.r; + }; + // + bool operator == ( RGB &another ) + { + return this->b == another.b && this->g == another.g && this->r == another.r; + }; +}; + + +union sProcessInfo +{ + Byte rawData[1024]; + struct + { + Dword cpu_usage; + Word window_stack_position; + Word window_stack_value; + Word reserved1; + char process_name[12]; + Dword memory_start; + Dword used_memory; + Dword PID; + Dword x_start; + Dword y_start; + Dword x_size; + Dword y_size; + Word slot_state; + } processInfo; +}; + +struct PRINTK +{ + char *fmtline; + Dword args[11]; +}; + +// +extern char *kosExePath; + +// +void crtStartUp(); +// +int __cdecl _purecall(); +// +int __cdecl atexit( void (__cdecl *func )( void )); +// +void rtlSrand( Dword seed ); +Dword rtlRand( void ); +// +char * __cdecl strcpy( char *target, const char *source ); +int __cdecl strlen( const char *line ); +char * __cdecl strrchr( const char * string, int c ); +// +void * __cdecl memcpy( void *dst, const void *src, size_t bytesCount ); +// +void memset( Byte *dst, Byte filler, Dword count ); +// +void sprintk( char *Str, PRINTK *arg ); +// +Dword rtlInterlockedExchange( Dword *target, Dword value ); +// -1 +void kos_ExitApp(); +// 0 +void kos_DefineAndDrawWindow( + Word x, Word y, + Word sizeX, Word sizeY, + Byte mainAreaType, Dword mainAreaColour, + Byte headerType, Dword headerColour, + Dword borderColour + ); +// 1 +void kos_PutPixel( Dword x, Dword y, Dword colour ); +// 2 +bool kos_GetKey( Byte &keyCode ); +// 3 +Dword kos_GetSystemClock(); +// 4 +void kos_WriteTextToWindow( + Word x, Word y, + Byte fontType, + Dword textColour, + char *textPtr, + Dword textLen + ); +// 7 +void kos_PutImage( RGB * imagePtr, Word sizeX, Word sizeY, Word x, Word y ); +// 8 +void kos_DefineButton( Word x, Word y, Word sizeX, Word sizeY, Dword buttonID, Dword colour ); +// 5 , +void kos_Pause( Dword value ); +// 9 - +Dword kos_ProcessInfo( sProcessInfo *targetPtr, Dword processID = PROCESS_ID_SELF ); +// 10 +Dword kos_WaitForEvent(); +// 11 +Dword kos_CheckForEvent(); +// 12 +void kos_WindowRedrawStatus( Dword status ); +// 13 +void kos_DrawBar( Word x, Word y, Word sizeX, Word sizeY, Dword colour ); +// 17 +bool kos_GetButtonID( Dword &buttonID ); +// 23 +Dword kos_WaitForEvent( Dword timeOut ); +// +enum eNumberBase +{ + nbDecimal = 0, + nbHex, + nbBin +}; +// "" 37 +void kos_GetMouseState( Dword & buttons, int & cursorX, int & cursorY ); +// 40 +void kos_SetMaskForEvents( Dword mask ); +// 47 +void kos_DisplayNumberToWindow( + Dword value, + Dword digitsNum, + Word x, + Word y, + Dword colour, + eNumberBase nBase = nbDecimal, + bool valueIsPointer = false + ); +// 58 +Dword kos_FileSystemAccess( kosFileInfo *fileInfo ); +// 63 +void kos_DebugOutChar( char ccc ); +// +void rtlDebugOutString( char *str ); +// 64 , == -1 +void kos_ChangeWindow( Dword x, Dword y, Dword sizeX, Dword sizeY ); +// 67 , +bool kos_ApplicationMemoryResize( Dword targetSize ); +// 66 +void kos_SetKeyboardDataMode( Dword mode ); + +// +void kos_Main(); diff --git a/programs/games/xonix/trunk/lang.h b/programs/games/xonix/trunk/lang.h new file mode 100644 index 0000000000..ef15793f1a --- /dev/null +++ b/programs/games/xonix/trunk/lang.h @@ -0,0 +1,3 @@ +#define RUS 1 +#define ENG 2 +#define LANG RUS \ No newline at end of file diff --git a/programs/games/xonix/trunk/logo.bmp b/programs/games/xonix/trunk/logo.bmp new file mode 100644 index 0000000000..be7959501c Binary files /dev/null and b/programs/games/xonix/trunk/logo.bmp differ diff --git a/programs/games/xonix/trunk/main.cpp b/programs/games/xonix/trunk/main.cpp new file mode 100644 index 0000000000..32f76bb106 --- /dev/null +++ b/programs/games/xonix/trunk/main.cpp @@ -0,0 +1,2500 @@ +#include "kosSyst.h" +#include "mcarray.h" +#include "lang.h" + + +// +RGB bmEmpty[] = { + 0x201010, 0x101020, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, + 0x101010, 0x102010, 0x201010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, + 0x101010, 0x101010, 0x101020, 0x102010, 0x101010, 0x101010, 0x101010, 0x101010, + 0x101010, 0x101010, 0x101010, 0x201010, 0x101020, 0x101010, 0x101010, 0x101010, + 0x101010, 0x101010, 0x101010, 0x101010, 0x102010, 0x201010, 0x101010, 0x101010, + 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101020, 0x102010, 0x101010, + 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x201010, 0x101020, + 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x102010 +}; + + +// +RGB bmHero[] = { + 0x2020E0, 0x2020E0, 0x2020E0, 0x2020E0, 0x2020E0, 0x2020E0, 0x2020E0, 0x2020C0, + 0x2020E0, 0x2020E0, 0x2020E0, 0x2020E0, 0x2020E0, 0x2020E0, 0x2020C0, 0x2020A0, + 0x2020E0, 0x2020E0, 0x2020C0, 0x2020C0, 0x2020C0, 0x2020C0, 0x2020A0, 0x2020A0, + 0x2020E0, 0x2020E0, 0x2020C0, 0x2020C0, 0x2020C0, 0x2020C0, 0x2020A0, 0x2020A0, + 0x2020E0, 0x2020E0, 0x2020C0, 0x2020C0, 0x2020C0, 0x2020C0, 0x2020A0, 0x2020A0, + 0x2020E0, 0x2020E0, 0x2020C0, 0x2020C0, 0x2020C0, 0x2020C0, 0x2020A0, 0x2020A0, + 0x2020E0, 0x2020C0, 0x2020A0, 0x2020A0, 0x2020A0, 0x2020A0, 0x2020A0, 0x2020A0, + 0x2020C0, 0x2020A0, 0x2020A0, 0x2020A0, 0x2020A0, 0x2020A0, 0x2020A0, 0x2020A0 +}; + + +// +RGB bmSuperHero[] = { + 0x5720D0, 0x5720D0, 0x5720D0, 0x5720D0, 0x5720D0, 0x5720D0, 0x5720D0, 0x5720B0, + 0x5720D0, 0x5720D0, 0x5720D0, 0x5720D0, 0x5720D0, 0x5720D0, 0x5720B0, 0x572090, + 0x5720D0, 0x5720D0, 0x5720B0, 0x5720B0, 0x5720B0, 0x5720B0, 0x572090, 0x572090, + 0x5720D0, 0x5720D0, 0x5720B0, 0x5720B0, 0x5720B0, 0x5720B0, 0x572090, 0x572090, + 0x5720D0, 0x5720D0, 0x5720B0, 0x5720B0, 0x5720B0, 0x5720B0, 0x572090, 0x572090, + 0x5720D0, 0x5720D0, 0x5720B0, 0x5720B0, 0x5720B0, 0x5720B0, 0x572090, 0x572090, + 0x5720D0, 0x5720B0, 0x572090, 0x572090, 0x572090, 0x572090, 0x572090, 0x572090, + 0x5720B0, 0x572090, 0x572090, 0x572090, 0x572090, 0x572090, 0x572090, 0x572090 +}; + + +// , +RGB bmEnemy1[] = { + 0xE02020, 0xE02020, 0xE02020, 0xE02020, 0xE02020, 0xE02020, 0xE02020, 0xC02020, + 0xE02020, 0xE02020, 0xE02020, 0xE02020, 0xE02020, 0xE02020, 0xC02020, 0xA02020, + 0xE02020, 0xE02020, 0xC02020, 0xC02020, 0xC02020, 0xC02020, 0xA02020, 0xA02020, + 0xE02020, 0xE02020, 0xC02020, 0xC02020, 0xC02020, 0xC02020, 0xA02020, 0xA02020, + 0xE02020, 0xE02020, 0xC02020, 0xC02020, 0xC02020, 0xC02020, 0xA02020, 0xA02020, + 0xE02020, 0xE02020, 0xC02020, 0xC02020, 0xC02020, 0xC02020, 0xA02020, 0xA02020, + 0xE02020, 0xC02020, 0xA02020, 0xA02020, 0xA02020, 0xA02020, 0xA02020, 0xA02020, + 0xC02020, 0xA02020, 0xA02020, 0xA02020, 0xA02020, 0xA02020, 0xA02020, 0xA02020 +}; + + +// , +RGB bmEnemy2[] = { + 0xE08020, 0xE08020, 0xE08020, 0xE08020, 0xE08020, 0xE08020, 0xE08020, 0xC08020, + 0xE08020, 0xE08020, 0xE08020, 0xE08020, 0xE08020, 0xE08020, 0xC08020, 0xA08020, + 0xE08020, 0xE08020, 0xC08020, 0xC08020, 0xC08020, 0xC08020, 0xA08020, 0xA08020, + 0xE08020, 0xE08020, 0xC08020, 0xC08020, 0xC08020, 0xC08020, 0xA08020, 0xA08020, + 0xE08020, 0xE08020, 0xC08020, 0xC08020, 0xC08020, 0xC08020, 0xA08020, 0xA08020, + 0xE08020, 0xE08020, 0xC08020, 0xC08020, 0xC08020, 0xC08020, 0xA08020, 0xA08020, + 0xE08020, 0xC08020, 0xA08020, 0xA08020, 0xA08020, 0xA08020, 0xA08020, 0xA08020, + 0xC08020, 0xA08020, 0xA08020, 0xA08020, 0xA08020, 0xA08020, 0xA08020, 0xA08020 +}; + + +// +RGB bmWall[] = { + 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xCCCCCC, + 0xFFFFFF, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xAAAAAA, + 0xFFFFFF, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xAAAAAA, + 0xFFFFFF, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xAAAAAA, + 0xFFFFFF, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xAAAAAA, + 0xFFFFFF, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xAAAAAA, + 0xFFFFFF, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xCCCCCC, 0xAAAAAA, + 0xCCCCCC, 0xAAAAAA, 0xAAAAAA, 0xAAAAAA, 0xAAAAAA, 0xAAAAAA, 0xAAAAAA, 0xAAAAAA +}; + + +// +RGB bmTrack[] = { + 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, + 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, + 0x101010, 0x101010, 0x101010, 0x1010F0, 0x1010F0, 0x101010, 0x101010, 0x101010, + 0x101010, 0x101010, 0x1010F0, 0x1010F0, 0x1010F0, 0x1010F0, 0x101010, 0x101010, + 0x101010, 0x101010, 0x1010F0, 0x1010F0, 0x1010F0, 0x1010F0, 0x101010, 0x101010, + 0x101010, 0x101010, 0x101010, 0x1010F0, 0x1010F0, 0x101010, 0x101010, 0x101010, + 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, + 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010 +}; + + +// +RGB bmSuperTrack[] = { + 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, + 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, + 0x101010, 0x101010, 0x101010, 0x5310D0, 0x5310D0, 0x101010, 0x101010, 0x101010, + 0x101010, 0x101010, 0x5310D0, 0x5310D0, 0x5310D0, 0x5310D0, 0x101010, 0x101010, + 0x101010, 0x101010, 0x5310D0, 0x5310D0, 0x5310D0, 0x5310D0, 0x101010, 0x101010, + 0x101010, 0x101010, 0x101010, 0x5310D0, 0x5310D0, 0x101010, 0x101010, 0x101010, + 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, + 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010, 0x101010 +}; + + +// +RGB bmFlip[] = { + 0x101010, 0xF0F0F0, 0x101010, 0xF0F0F0, 0x101010, 0xF0F0F0, 0x101010, 0xF0F0F0, + 0xF0F0F0, 0x101010, 0xF0F0F0, 0x101010, 0xF0F0F0, 0x101010, 0xF0F0F0, 0x101010, + 0x101010, 0xF0F0F0, 0x101010, 0xF0F0F0, 0x101010, 0xF0F0F0, 0x101010, 0xF0F0F0, + 0xF0F0F0, 0x101010, 0xF0F0F0, 0x101010, 0xF0F0F0, 0x101010, 0xF0F0F0, 0x101010, + 0x101010, 0xF0F0F0, 0x101010, 0xF0F0F0, 0x101010, 0xF0F0F0, 0x101010, 0xF0F0F0, + 0xF0F0F0, 0x101010, 0xF0F0F0, 0x101010, 0xF0F0F0, 0x101010, 0xF0F0F0, 0x101010, + 0x101010, 0xF0F0F0, 0x101010, 0xF0F0F0, 0x101010, 0xF0F0F0, 0x101010, 0xF0F0F0, + 0xF0F0F0, 0x101010, 0xF0F0F0, 0x101010, 0xF0F0F0, 0x101010, 0xF0F0F0, 0x101010 +}; + + +// +RGB bmBonus1[] = { + 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xCCCCCC, + 0xFFFFFF, 0xCCCCCC, 0xCCCCCC, 0x44AC44, 0x44AC44, 0xCCCCCC, 0xCCCCCC, 0xAAAAAA, + 0xFFFFFF, 0xCCCCCC, 0x44AC44, 0x44AC44, 0x44AC44, 0x44AC44, 0xCCCCCC, 0xAAAAAA, + 0xFFFFFF, 0x44AC44, 0x44AC44, 0x0C8C0C, 0x0C8C0C, 0x44AC44, 0x44AC44, 0xAAAAAA, + 0xFFFFFF, 0x44AC44, 0x44AC44, 0x0C8C0C, 0x0C8C0C, 0x44AC44, 0x44AC44, 0xAAAAAA, + 0xFFFFFF, 0xCCCCCC, 0x44AC44, 0x44AC44, 0x44AC44, 0x44AC44, 0xCCCCCC, 0xAAAAAA, + 0xFFFFFF, 0xCCCCCC, 0xCCCCCC, 0x44AC44, 0x44AC44, 0xCCCCCC, 0xCCCCCC, 0xAAAAAA, + 0xCCCCCC, 0xAAAAAA, 0xAAAAAA, 0xAAAAAA, 0xAAAAAA, 0xAAAAAA, 0xAAAAAA, 0xAAAAAA +}; + + +// +RGB bmBonus2[] = { + 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xCCCCCC, + 0xFFFFFF, 0xCCCCCC, 0xD41414, 0xCCCCCC, 0xCCCCCC, 0xD41414, 0xCCCCCC, 0xAAAAAA, + 0xFFFFFF, 0xD41414, 0xD41414, 0xD41414, 0xD41414, 0xD41414, 0xD41414, 0xAAAAAA, + 0xFFFFFF, 0xD41414, 0xD41414, 0xD41414, 0xD41414, 0xD41414, 0xD41414, 0xAAAAAA, + 0xFFFFFF, 0xD41414, 0xD41414, 0xD41414, 0xD41414, 0xD41414, 0xD41414, 0xAAAAAA, + 0xFFFFFF, 0xCCCCCC, 0xD41414, 0xD41414, 0xD41414, 0xD41414, 0xCCCCCC, 0xAAAAAA, + 0xFFFFFF, 0xCCCCCC, 0xCCCCCC, 0xD41414, 0xD41414, 0xCCCCCC, 0xCCCCCC, 0xAAAAAA, + 0xCCCCCC, 0xAAAAAA, 0xAAAAAA, 0xAAAAAA, 0xAAAAAA, 0xAAAAAA, 0xAAAAAA, 0xAAAAAA +}; + + +// +RGB bmPMButton[] = { + 0xCCCCCC, 0xCCCCCC, 0x000000, 0x000000, 0xCCCCCC, 0xCCCCCC, + 0xCCCCCC, 0xCCCCCC, 0x000000, 0x000000, 0xCCCCCC, 0xCCCCCC, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0xCCCCCC, 0xCCCCCC, 0x000000, 0x000000, 0xCCCCCC, 0xCCCCCC, + 0xCCCCCC, 0xCCCCCC, 0x000000, 0x000000, 0xCCCCCC, 0xCCCCCC, +}; + + +// +void DrawAppWindow(); +// +void DrawTop10Window(); +// +void initWorldMap(); +// +void drawWorldMap(); +// +void clearWorldMap(); +// +void drawWorldMapForFlip(); +// +void drawWndTitleGo(); +// +void ApplyMapDiffs( bool drawTitle = true ); +// +int GetCompletePercents(); + + +#define EAT_ENEMY_BONUS 100 + +#define BEFORE_START_LEVEL 100 +#define BONUS1_LIFETIME 250 +#define BONUS1_IND_HSIZE 6 + +#define MIN_LOOP_DELAY 1 +#define MAX_LOOP_DELAY 20 +#define DEFAULT_LOOP_DELAY 12 + +#define blockSize 8 + +#define ENTRY_WND_SIZE_X 400 +#define ENTRY_WND_SIZE_Y 144 + +#define TOP10_WND_SIZE_X 176 +#define TOP10_WND_SIZE_Y 144 + +#define MAX_X_SIZE 96 +#define MIN_X_SIZE 48 +#define MAX_Y_SIZE 56 +#define MIN_Y_SIZE 28 + +#define flipMapSize ((mapSizeX * mapSizeY) / 4) +#define wndXOffet 1 +#define wndYOffset 22 +#define freeSpaceCount ((mapSizeX - 4) * (mapSizeY - 4)) +// +#define gmEmpty 0 +#define gmHero 1 +#define gmEnemy1 2 +#define gmEnemy2 3 +#define gmWall 4 +#define gmTrack 5 +#define gmFlip 6 +#define gmBonus1 7 +#define gmBonus2 8 +#define gmSuperHero 9 +#define gmSuperTrack 10 +#define gmProbe 11 + +#define appStateEntry 0 +#define appStateGo 1 +#define appStateHideMap 2 +#define appStateShowMap 3 +#define appStatePause 4 +#define appStateAfterDeath 5 +#define appStateTop10 6 + +#define spacePerEnemy 30 + + +#define BT_SIZE_X_PLUS 2 +#define BT_SIZE_X_MINUS 3 +#define BT_LOOP_PLUS 4 +#define BT_LOOP_MINUS 5 +#define BT_SIZE_Y_PLUS 6 +#define BT_SIZE_Y_MINUS 7 + +#define TOP_TBL_SIZE 10 + + +// +struct hiScoreHero +{ + char name[12]; + Dword score; + // + hiScoreHero() + { + // + this->ClearName(); + this->score = 0; + }; + // + void ClearName() + { + memset( (Byte *)(this->name), '.', sizeof(this->name) ); + }; +}; + +// +char top10FilePath[MAX_PATH]; +hiScoreHero heroTbl[TOP_TBL_SIZE]; + +// +struct hiScoreFile +{ + Byte block[512]; + kosFileInfo fi; + // + hiScoreFile() + { + int i; + + // + this->fi.offsetLow = this->fi.offsetHigh = 0; + this->fi.dataCount = 0; + this->fi.bufferPtr = this->block; + this->fi.rwMode = 0; + memcpy( this->fi.fileURL, top10FilePath, sizeof( top10FilePath ) ); + // + for ( i = 0; i < ( sizeof( this->block ) / sizeof( Dword ) ); i++ ) + { + // + ((Dword *)(this->block))[i] = rtlRand(); + } + }; + // + virtual ~hiScoreFile() + {} + // + bool LoadFromDisk() + { + bool result; + int i; + Dword j, k; + Byte *bPtr; + + // + this->fi.rwMode = FO_READ; + this->fi.dataCount = 512; + result = kos_FileSystemAccess( &(this->fi) ) == 0; + // + if ( result ) + { + // + rtlSrand( ((Dword *)(this->block))[(sizeof(this->block) / sizeof(Dword)) - 1] ); + // + for ( i = 0; i < (sizeof( heroTbl ) * 5); i++ ) + { + // Dword + j = rtlRand() % (sizeof(this->block) - 7); + k = ( rtlRand() % 31 ) + 1; + // + bPtr = this->block + j; + // + __asm{ + mov edx, bPtr + mov ecx, k + mov eax, [edx] + bswap eax + ror eax, cl + mov [edx], eax + } + } + // + rtlSrand( kos_GetSystemClock() ); + } + // + return result; + }; + // + bool SaveToDisk() + { + int i; + Dword *rndList; + Byte *bPtr; + Dword k, keyLock; + + // + rndList = new Dword[(sizeof( heroTbl ) * 5) * 2]; + // + keyLock = rtlRand(); + // + for ( i = 0; i < (sizeof( heroTbl ) * 5); i++ ) + { + // + rndList[i * 2] = rtlRand() % (sizeof(this->block) - 7); + rndList[(i * 2) + 1] = ( rtlRand() % 31 ) + 1; + } + // + for ( i = (sizeof( heroTbl ) * 5) - 1; i >= 0; i-- ) + { + // + bPtr = this->block + rndList[i * 2]; + k = rndList[(i * 2) + 1]; + // + __asm{ + mov edx, bPtr + mov ecx, k + mov eax, [edx] + rol eax, cl + bswap eax + mov [edx], eax + } + } + // + delete rndList; + // + ((Dword *)(this->block))[(sizeof(this->block) / sizeof(Dword)) - 1] = keyLock; + // + this->fi.rwMode = FO_WRITE; + this->fi.dataCount = 512; + return kos_FileSystemAccess( &( this->fi) ) == 0; + }; +}; + +/// +hiScoreFile *top10Heroes = NULL; + + +// +char MainWindowTitle[] = "XONIX (C) MMVI by Rabid Rabbit"; +#if LANG == RUS +char goWndTitle[] = "஢ %U, 襭 %U%%, : %U, : %U"; +char menuStr1[] = "1. "; +char menuStr2[] = "2. 室"; +char menuStr3[] = "ࠢ: - ࠢ ."; +char menuStr4[] = "SPACE - 㧠, ESC - 室 ."; +char thatsAllStr[] = " 祭."; +char worldSizeStr[] = " %U x %U ⮢."; +char mainLoopDelayStr[] = " %U"; +char top10str1[] = "ENTER - Ok."; +char top10str2[] = "ESC - 室 "; +#else +char goWndTitle[] = "Level %U, completed %U%%, lives: %U, scores: %U"; +char menuStr1[] = "1. Start game"; +char menuStr2[] = "2. Exit"; +char menuStr3[] = "Control: ARROWS - direction of movement."; +char menuStr4[] = "SPACE - pause, ESC - leave to menu."; +char thatsAllStr[] = "Game finished."; +char worldSizeStr[] = "Field size %U x %U cells."; +char mainLoopDelayStr[] = "Speed %U"; +char top10str1[] = "Enter - name Ok."; +char top10str2[] = "ESC - leave to menu"; +#endif +// +Byte beep1[] = { 0x90, 0x33, 0 }; +// +Byte *heroPtr = NULL; +int heroDX = 0, heroDY = 0, lastMoveDirection = 0; +// +Byte * worldMap = NULL; +// +int wndSizeX = ENTRY_WND_SIZE_X; +int wndSizeY = ENTRY_WND_SIZE_Y; +int mapSizeX = 64; +int mapSizeY = 32; +int loopDelay = DEFAULT_LOOP_DELAY; +int currentLevel = 1; +int appState = appStateEntry; +int levelFillEdge = 0; +int levelFillCount = 0; +int lifeCount = 0; +int flipMapCount = 0; +bool noBonus = false; +bool goToNextLevel = false; +bool bonus1Set = false; +bool bonus2Set = false; +int bonus1Count = 0; +int currentHero = gmHero; +int currentTrack = gmTrack; +Dword scoreCount = 0; +int enterName = -1; +int enterCharNdx = 0; +// +MCArray fillList; + +// +struct flipMapEl +{ + Word x, y; +}; + +// +flipMapEl *flipMapPtr = NULL; + + +// +RGB *mapColours[] = { + bmEmpty, + bmHero, + bmEnemy1, + bmEnemy2, + bmWall, + bmTrack, + bmFlip, + bmBonus1, + bmBonus2, + bmSuperHero, + bmSuperTrack, + NULL +}; + + +// +struct sMapDiff +{ + Byte *elPtr; + Byte mapEl; + // + sMapDiff() {}; + // + sMapDiff( Byte *sElPtr, Byte sMapEl ) + { + this->elPtr = sElPtr; + this->mapEl = sMapEl; + }; +}; + + +// +class CMapDiff : public MCArray +{ +public: + virtual int Add( const sMapDiff &element ) + { + element.elPtr[0] = element.mapEl; + return MCArray::Add( element ); + } +}; + + +// +CMapDiff mapDiffList; +MCArray sTrackList; + + +// +class CGenericEnemy +{ +public: + // + Byte *ePtr; + int dx, dy; + // + virtual bool Move(void) = 0; +}; + +class CWallEnemy : public CGenericEnemy +{ +public: + virtual bool Move(void); +}; + +class CSpaceEnemy : public CGenericEnemy +{ +public: + virtual bool Move(void); +}; + + + +// +bool CWallEnemy::Move() +{ + int ddx; + Byte *nextPtr; + Byte mapEl, dirMap; + bool result, border; + + // + result = false; + border = false; + // + ddx = ( this->ePtr - worldMap ) % mapSizeX; + // + if ( ddx == 0 && this->dx < 0 ) + { + border = true; + this->dx = 0 - this->dx; + } + // + if ( ddx == (mapSizeX - 1) && this->dx > 0 ) + { + border = true; + this->dx = 0 - this->dx; + } + // + ddx = ( this->ePtr - worldMap ) / mapSizeX; + // + if ( ddx == 0 && this->dy < 0 ) + { + border = true; + this->dy = 0 - this->dy; + } + // + if ( ddx == (mapSizeY - 1) && this->dy > 0 ) + { + border = true; + this->dy = 0 - this->dy; + } + // , + nextPtr = this->ePtr + ( this->dx + this->dy ); + // + mapEl = nextPtr[0]; + // + // + switch ( mapEl ) + { + // + case gmHero: + if ( sTrackList.GetCount() <= 0 ) + { + result = true; + break; + } + + // , - + case gmSuperHero: + case gmSuperTrack: + case gmTrack: + case gmEnemy2: + case gmEmpty: + // + dirMap = 0; + // -dx +dy + mapEl = this->ePtr[this->dy - this->dx]; + if ( mapEl == gmEmpty + || mapEl == gmTrack + || mapEl == gmEnemy2 + || mapEl == gmSuperHero + || mapEl == gmSuperTrack + ) dirMap |= 1; + // +dy + mapEl = this->ePtr[this->dy]; + if ( mapEl == gmEmpty + || mapEl == gmTrack + || mapEl == gmEnemy2 + || mapEl == gmSuperHero + || mapEl == gmSuperTrack + ) dirMap |= 2; + // +dx + mapEl = this->ePtr[this->dx]; + if ( mapEl == gmEmpty + || mapEl == gmTrack + || mapEl == gmEnemy2 + || mapEl == gmSuperHero + || mapEl == gmSuperTrack + ) dirMap |= 4; + // +dx -dy + mapEl = this->ePtr[this->dx - this->dy]; + if ( mapEl == gmEmpty + || mapEl == gmTrack + || mapEl == gmEnemy2 + || mapEl == gmSuperHero + || mapEl == gmSuperTrack + ) dirMap |= 8; + // + switch ( dirMap ) + { + case 2: + case 3: + this->dy = 0 - this->dy; + break; + + case 4: + case 12: + this->dx = 0 - this->dx; + break; + + default: + this->dx = 0 - this->dx; + this->dy = 0 - this->dy; + break; + } + // + nextPtr = this->ePtr + ( this->dx + this->dy ); + // + mapEl = nextPtr[0]; + // + switch ( mapEl ) + { + // + case gmHero: + if ( sTrackList.GetCount() <= 0 ) + { + result = true; + } + + // + case gmSuperHero: + case gmSuperTrack: + case gmTrack: + case gmEmpty: + case gmEnemy2: + break; + + // + default: + // + mapDiffList.Add( sMapDiff( this->ePtr, gmWall ) ); + // + this->ePtr = nextPtr; + // + mapDiffList.Add( sMapDiff( this->ePtr, gmEnemy1 ) ); + break; + } + // + break; + + // + default: + // + mapDiffList.Add( sMapDiff( this->ePtr, gmWall ) ); + // + this->ePtr = nextPtr; + // + mapDiffList.Add( sMapDiff( this->ePtr, gmEnemy1 ) ); + // + break; + + } + // + return result; +} + +// +bool CSpaceEnemy::Move() +{ + Byte *nextPtr; + Byte mapEl, dirMap; + bool result, heroTrack; + + // + result = false; + // + heroTrack = ( sTrackList.GetCount() > 0 ); + // , + nextPtr = this->ePtr + ( this->dx + this->dy ); + // + mapEl = nextPtr[0]; + // + switch ( mapEl ) + { + // + case gmTrack: + result = true; + break; + + // + case gmHero: + if ( heroTrack ) + { + result = true; + break; + } + + // + case gmSuperHero: + case gmSuperTrack: + case gmBonus1: + case gmBonus2: + case gmEnemy1: + case gmWall: + // + dirMap = 0; + // -dx +dy + mapEl = this->ePtr[this->dy - this->dx]; + if ( mapEl == gmWall || + mapEl == gmEnemy1 || + mapEl == gmBonus1 || + mapEl == gmBonus2 || + mapEl == gmSuperHero || + mapEl == gmSuperTrack || + ( mapEl == gmHero && !heroTrack ) + ) dirMap |= 1; + // +dy + mapEl = this->ePtr[this->dy]; + if ( mapEl == gmWall || + mapEl == gmEnemy1 || + mapEl == gmBonus1 || + mapEl == gmBonus2 || + mapEl == gmSuperHero || + mapEl == gmSuperTrack || + ( mapEl == gmHero && !heroTrack ) + ) dirMap |= 2; + // +dx + mapEl = this->ePtr[this->dx]; + if ( mapEl == gmWall || + mapEl == gmEnemy1 || + mapEl == gmBonus1 || + mapEl == gmBonus2 || + mapEl == gmSuperHero || + mapEl == gmSuperTrack || + ( mapEl == gmHero && !heroTrack ) + ) dirMap |= 4; + // +dx -dy + mapEl = this->ePtr[this->dx - this->dy]; + if ( mapEl == gmWall || + mapEl == gmEnemy1 || + mapEl == gmBonus1 || + mapEl == gmBonus2 || + mapEl == gmSuperHero || + mapEl == gmSuperTrack || + ( mapEl == gmHero && !heroTrack ) + ) dirMap |= 8; + // + switch ( dirMap ) + { + case 2: + case 3: + this->dy = 0 - this->dy; + break; + + case 4: + case 12: + this->dx = 0 - this->dx; + break; + + default: + this->dx = 0 - this->dx; + this->dy = 0 - this->dy; + break; + } + // + nextPtr = this->ePtr + ( this->dx + this->dy ); + // + mapEl = nextPtr[0]; + // + switch ( mapEl ) + { + // + case gmTrack: + result = true; + break; + + // + case gmHero: + if ( heroTrack ) + { + result = true; + break; + } + + // + case gmSuperHero: + case gmSuperTrack: + case gmBonus1: + case gmBonus2: + case gmWall: + case gmEnemy1: + break; + + // + default: + // + mapDiffList.Add( sMapDiff( this->ePtr, gmEmpty ) ); + // + this->ePtr = nextPtr; + // + mapDiffList.Add( sMapDiff( this->ePtr, gmEnemy2 ) ); + break; + } + // + break; + + // + default: + // + mapDiffList.Add( sMapDiff( this->ePtr, gmEmpty ) ); + // + this->ePtr = nextPtr; + // + mapDiffList.Add( sMapDiff( this->ePtr, gmEnemy2 ) ); + // + break; + + } + // + + // + return result; +} + + +// +MCArray mapEnemies; + + +// +void xonixFree(void) +{ + clearWorldMap(); + if ( flipMapPtr != NULL ) + { + delete flipMapPtr; + flipMapPtr = NULL; + } +} + + +// +void checkAndSetBonus2() +{ + Dword i; + + // + if ( (!bonus2Set) + && rtlRand() < 0x40000000 + && lifeCount < 3 + && GetCompletePercents() > 50 ) + { + // + bonus2Set = true; + // + for ( i = rtlRand() % (mapSizeX * mapSizeY); worldMap[i] != gmWall; i = rtlRand() % (mapSizeX * mapSizeY) ); + // + mapDiffList.Add( sMapDiff( worldMap + i, gmBonus2 ) ); + } +} + + +// +void ChangeHero() +{ + if ( bonus1Count < 1 ) + { + currentHero = gmHero; + currentTrack = gmTrack; + } + else + { + currentHero = gmSuperHero; + currentTrack = gmSuperTrack; + } +} + + +// +void checkAndSetBonus1() +{ + Dword i; + + // + if ( (!bonus1Set) + && rtlRand() > 0x80000000 + && lifeCount < 2 + && GetCompletePercents() > 75 ) + { + // + bonus1Set = true; + // + for ( i = rtlRand() % (mapSizeX * mapSizeY); worldMap[i] != gmWall; i = rtlRand() % (mapSizeX * mapSizeY) ); + // + mapDiffList.Add( sMapDiff( worldMap + i, gmBonus1 ) ); + } +} + + +// +void CreateFlipMap(void) +{ + Word i, j; + int ndx, ndx2, k; + flipMapEl el; + static int lastMapSizeX = 0, lastMapSizeY = 0; + + // + if ( lastMapSizeX != mapSizeX || lastMapSizeY != mapSizeY ) + { + // + lastMapSizeX = mapSizeX; + lastMapSizeY = mapSizeY; + // + if ( flipMapPtr != NULL ) + { + delete flipMapPtr; + flipMapPtr = NULL; + } + } + // + if ( flipMapPtr == NULL ) + { + flipMapPtr = new flipMapEl[flipMapSize]; + // + ndx = 0; + // + for ( i = 0; i < mapSizeY; i += 2 ) + { + for ( j = 0; j < mapSizeX; j += 2 ) + { + // + flipMapPtr[ndx].x = j; + flipMapPtr[ndx].y = i; + // + ndx++; + } + } + } + // + for ( k = 0; k < flipMapSize; k++ ) + { + // + ndx = rtlRand() % flipMapSize; + ndx2 = rtlRand() % flipMapSize; + // + el = flipMapPtr[ndx]; + flipMapPtr[ndx] = flipMapPtr[ndx2]; + flipMapPtr[ndx2] = el; + } +} + + +// +bool ProcessEndTrack() +{ + int i, j, k, m; + bool noFill; + Byte *mPtr, *findPtr; + + // + j = sTrackList.GetCount(); + // + scoreCount += j; + // + for ( i = 0; i < j; i++ ) + { + // + mapDiffList.Add( sMapDiff( sTrackList[i], gmWall ) ); + } + // + levelFillCount -= j; + // + sTrackList.Clear(); + // + heroPtr += heroDX + heroDY; + mapDiffList.Add( sMapDiff( heroPtr, currentHero ) ); + // + heroDX = 0; + heroDY = 0; + lastMoveDirection = 0; + // + mPtr = worldMap; + // + for ( i = 0; i < mapSizeY; i++ ) + { + for ( j = 0; j < mapSizeX; j++ ) + { + // + if ( mPtr[0] == gmEmpty ) + { + // + fillList.Clear(); + // + noFill = false; + // + fillList.Add( mPtr ); + // + mPtr[0] = gmProbe; + // + for ( k = 0; k < fillList.GetCount(); k++ ) + { + // + findPtr = fillList[k] + 1; + // + switch ( findPtr[0] ) + { + case gmEmpty: + fillList.Add( findPtr ); + findPtr[0] = gmProbe; + break; + case gmEnemy2: + noFill = true; + break; + default: + break; + } + // + findPtr = fillList[k] - 1; + // + switch ( findPtr[0] ) + { + case gmEmpty: + fillList.Add( findPtr ); + findPtr[0] = gmProbe; + break; + case gmEnemy2: + noFill = true; + break; + default: + break; + } + // + findPtr = fillList[k] - mapSizeX; + // + switch ( findPtr[0] ) + { + case gmEmpty: + fillList.Add( findPtr ); + findPtr[0] = gmProbe; + break; + case gmEnemy2: + noFill = true; + break; + default: + break; + } + // + findPtr = fillList[k] + mapSizeX; + // + switch ( findPtr[0] ) + { + case gmEmpty: + fillList.Add( findPtr ); + findPtr[0] = gmProbe; + break; + case gmEnemy2: + noFill = true; + break; + default: + break; + } + } + // + if ( noFill ) + { + // + fillList.Clear(); + } + else + { + // + m = fillList.GetCount(); + // + scoreCount += m; + // + for ( k = 0; k < m; k++ ) + { + // + mapDiffList.Add( sMapDiff( fillList[k], gmWall ) ); + } + // + levelFillCount -= m; + } + } + else + { + mPtr++; + } + } + } + // + mPtr = worldMap; + // + for ( i = 0; i < mapSizeY; i++ ) + { + for ( j = 0; j < mapSizeX; j++ ) + { + // + if ( mPtr[0] == gmProbe ) mPtr[0] = gmEmpty; + // + mPtr++; + } + } + // + checkAndSetBonus1(); + checkAndSetBonus2(); + // + ApplyMapDiffs(); + // + return levelFillCount <= levelFillEdge; +} + + +// +void EatEnemy( Byte *enemyPos ) +{ + bool Eat = true; + int i, j; + + // + while ( Eat ) + { + // + Eat = false; + // + j = mapEnemies.GetCount(); + // + for ( i = 0; i < j; i++ ) + { + // + if ( mapEnemies[i]->ePtr == enemyPos ) + { + // + delete mapEnemies[i]; + // + mapEnemies.RemoveAt( i ); + // + Eat = true; + // + scoreCount += EAT_ENEMY_BONUS; + // + break; + } + } + } +} + + +// +bool MoveHero() +{ + int ddx; + Byte *nextPtr; + Byte mapEl; + bool result; + + // + if ( heroDX == 0 && heroDY == 0 ) return false; + // + result = false; + // + nextPtr = heroPtr + ( heroDX + heroDY ); + // + ddx = ( ( heroPtr - worldMap ) % mapSizeX ) - ( ( nextPtr - worldMap ) % mapSizeX ); + // + if ( ddx < -1 || ddx > 1 || nextPtr < worldMap || nextPtr >= ( worldMap + ( mapSizeX * mapSizeY ) ) ) + { + heroDX = 0; + heroDY = 0; + return false; + } + + + // + mapEl = nextPtr[0]; + // + if ( sTrackList.GetCount() > 0 ) + { + // + switch ( mapEl ) + { + // + case gmEmpty: + sTrackList.Add( nextPtr ); + break; + // + case gmBonus1: + bonus1Count = BONUS1_LIFETIME; + ChangeHero(); + goToNextLevel = ProcessEndTrack(); + return false; + break; + // + case gmBonus2: + lifeCount++; + goToNextLevel = ProcessEndTrack(); + return false; + break; + // + case gmWall: + goToNextLevel = ProcessEndTrack(); + return false; + break; + // + case gmEnemy1: + if ( bonus1Count > 0 ) + { + // + EatEnemy( nextPtr ); + // + goToNextLevel = ProcessEndTrack(); + // + return false; + break; + } + else + { + // + return true; + } + break; + // + case gmEnemy2: + if ( bonus1Count > 0 ) + { + // + EatEnemy( nextPtr ); + sTrackList.Add( nextPtr ); + break; + } + else + { + // + return true; + } + break; + // + default: + return true; + break; + } + } + else + { + // + switch ( mapEl ) + { + // + case gmEmpty: + sTrackList.Add( nextPtr ); + break; + // + case gmBonus1: + bonus1Count = BONUS1_LIFETIME; + break; + // + case gmBonus2: + lifeCount++; + break; + // + case gmWall: + break; + // + case gmEnemy1: + if ( bonus1Count > 0 ) + { + EatEnemy( nextPtr ); + } + else + { + result = true; + } + break; + // + case gmEnemy2: + if ( bonus1Count > 0 ) + { + EatEnemy( nextPtr ); + sTrackList.Add( nextPtr ); + } + else + { + result = true; + } + break; + // + default: + result = true; + break; + } + } + + // + mapDiffList.Add( sMapDiff( heroPtr, sTrackList.GetCount() <= 1 ? gmWall : currentTrack ) ); + heroPtr = nextPtr; + mapDiffList.Add( sMapDiff( heroPtr, currentHero ) ); + + return result; +} + + +// +bool MoveEnemies() +{ + bool result; + int i, j, ir; + + // + result = false; + ir = 0; + // + j = mapEnemies.GetCount(); + // + for ( i = 0; i < j; i++ ) + { + ir += ( mapEnemies[i]->Move() ? 1 : 0 ); + } + // + result = ( ir != 0 ); + // + return result; +} + + +// +void ApplyMapDiffs( bool drawTitle ) +{ + int i, j; + + // + kos_WindowRedrawStatus( 1 ); + // + if ( drawTitle ) drawWndTitleGo(); + // + j = mapDiffList.GetCount(); + // + for ( i = 0; i < j; i++ ) + { + //// + //kos_DrawBar( + // wndXOffet + ( ( ( mapDiffList[i].elPtr - worldMap ) % mapSizeX ) * blockSize ), + // wndYOffset + ( ( ( mapDiffList[i].elPtr - worldMap ) / mapSizeX ) * blockSize ), + // blockSize, blockSize, + // mapColours[mapDiffList[i].mapEl] + //); + // + kos_PutImage( + mapColours[mapDiffList[i].mapEl], + blockSize, + blockSize, + wndXOffet + ( ( ( mapDiffList[i].elPtr - worldMap ) % mapSizeX ) * blockSize ), + wndYOffset + ( ( ( mapDiffList[i].elPtr - worldMap ) / mapSizeX ) * blockSize ) + ); + } + // + kos_WindowRedrawStatus( 2 ); + // + mapDiffList.Clear(); +} + + +// +void DeadHeroProcess() +{ + int i, j; + Byte *mPtr = beep1; + + // beep + __asm{ + mov eax, 55 + mov ebx, eax + mov esi, mPtr + push eax + int 0x40 + pop eax + } + // + j = sTrackList.GetCount(); + // + for ( i = 0; i < j; i++ ) + { + // + mapDiffList.Add( sMapDiff( sTrackList[i], gmEmpty ) ); + } + // + mapDiffList.Add( sMapDiff( heroPtr, sTrackList.GetCount() > 0 ? gmEmpty : gmWall ) ); + // + sTrackList.Clear(); + // + heroPtr = worldMap; + // + while ( heroPtr[0] != gmWall ) heroPtr++; + // + mapDiffList.Add( sMapDiff( heroPtr, gmHero ) ); + // + noBonus = true; + // + lifeCount--; + // + heroDX = 0; + heroDY = 0; + lastMoveDirection = 0; +} + + +// +bool CheckForNextLevel() +{ + // + if ( goToNextLevel ) + { + // + CreateFlipMap(); + goToNextLevel = false; + currentLevel++; + appState = appStateHideMap; + flipMapCount = 0; + return true; + } + + // + return false; +} + + +// +void SetGameVars() +{ + // + currentLevel = 1; + lifeCount = 3; + noBonus = true; + bonus1Set = false; + bonus2Set = false; + bonus1Count = 0; + goToNextLevel = false; + currentHero = gmHero; + currentTrack = gmTrack; + scoreCount = 0; + enterName = -1; + // + wndSizeX = ((mapSizeX*blockSize)+2); + wndSizeY = ((mapSizeY*blockSize)+23); + // + kos_ChangeWindow( -1, -1, wndSizeX, wndSizeY ); +} + +// +void SetEntryVars() +{ + // + wndSizeX = ENTRY_WND_SIZE_X; + wndSizeY = ENTRY_WND_SIZE_Y; + // + kos_ChangeWindow( -1, -1, wndSizeX, wndSizeY ); + kos_SetKeyboardDataMode( KM_SCANS ); +} + + +// +void ReleaseTop10() +{ + // + if ( top10Heroes != NULL ) + { + // + memcpy( top10Heroes->block, heroTbl, sizeof(heroTbl) ); + // + top10Heroes->SaveToDisk(); + // + delete top10Heroes; + } +} + + +// +void PrepareTop10() +{ + // + top10Heroes = new hiScoreFile; + // + atexit( ReleaseTop10 ); + // + if ( top10Heroes->LoadFromDisk() ) + { + // + memcpy( heroTbl, top10Heroes->block, sizeof(heroTbl) ); + } +} + + +// +void SetUpTop10() +{ + int i, j; + Byte keyCode; + + // + while ( kos_CheckForEvent() == 2 ) kos_GetKey( keyCode ); + // + kos_SetKeyboardDataMode( KM_CHARS ); + // + kos_ChangeWindow( -1, -1, TOP10_WND_SIZE_X, TOP10_WND_SIZE_Y ); + // + for ( i = 0; i < TOP_TBL_SIZE; i++ ) + { + // + if ( heroTbl[i].score < scoreCount ) + { + // + for ( j = TOP_TBL_SIZE - 1; j > i; j-- ) + { + // + heroTbl[j] = heroTbl[j-1]; + } + // + heroTbl[i].ClearName(); + heroTbl[i].score = scoreCount; + // + enterName = i; + enterCharNdx = 0; + // + break; + } + } +} + + +// +// +// +void kos_Main() +{ + Dword buttonID; + Byte keyCode; + Byte *bPtr; + bool workOn = true; + char *cPtr; + + // + cPtr = strrchr( kosExePath, '/' ); + // ;) + if ( cPtr == NULL ) + { + // + rtlDebugOutString( "Invalid path to executable." ); + // + return; + } + // + cPtr[1] = 0; + // + strcpy( top10FilePath, kosExePath ); + // + strcpy( top10FilePath + ((cPtr - kosExePath) + 1), "xonix.t10" ); + + // + kos_SetKeyboardDataMode( KM_SCANS ); + // + PrepareTop10(); + + // + while( workOn ) + { + switch ( appState ) + { + // + case appStateEntry: + switch ( kos_WaitForEvent() ) + { + // + case 1: + DrawAppWindow(); + break; + + // + case 2: + kos_GetKey( keyCode ); + switch ( keyCode ) + { + // + case 2: + // + appState = appStateGo; + SetGameVars(); + initWorldMap(); + DrawAppWindow(); + break; + + // + case 3: + xonixFree(); + workOn = false; + break; + } + break; + // + case 3: + // + if ( ! kos_GetButtonID( buttonID ) ) break; + // + switch ( buttonID ) + { + // + case BT_SIZE_X_PLUS: + mapSizeX += 2; + if ( mapSizeX > MAX_X_SIZE ) mapSizeX = MAX_X_SIZE; + break; + // + case BT_SIZE_X_MINUS: + mapSizeX -= 2; + if ( mapSizeX < MIN_X_SIZE ) mapSizeX = MIN_X_SIZE; + break; + // + case BT_SIZE_Y_PLUS: + mapSizeY += 2; + if ( mapSizeY > MAX_Y_SIZE ) mapSizeY = MAX_Y_SIZE; + break; + // + case BT_SIZE_Y_MINUS: + mapSizeY -= 2; + if ( mapSizeY < MIN_Y_SIZE ) mapSizeY = MIN_Y_SIZE; + break; + // + case BT_LOOP_MINUS: + loopDelay++;; + if ( loopDelay > MAX_LOOP_DELAY ) loopDelay = MAX_LOOP_DELAY; + break; + // + case BT_LOOP_PLUS: + loopDelay--;; + if ( loopDelay < MIN_LOOP_DELAY ) loopDelay = MIN_LOOP_DELAY; + break; + // + default: + break; + } + DrawAppWindow(); + break; + // + default: + break; + } + break; + // + case appStateGo: + // + kos_Pause( loopDelay ); + // + if ( bonus1Count > 0 ) bonus1Count--; + // + ChangeHero(); + // + switch( kos_WaitForEvent( 1 ) ) + { + // + case 0: + if ( MoveHero() ) + { + // + DeadHeroProcess(); + } + else + { + // + if ( CheckForNextLevel() ) + { + break; + } + } + if ( MoveEnemies() ) + { + // + DeadHeroProcess(); + } + ApplyMapDiffs(); + break; + // + case 1: + DrawAppWindow(); + break; + + // + case 2: + do kos_GetKey( keyCode ); while ( keyCode & 0x80 ); + switch ( keyCode ) + { + // + case 0x1: + SetEntryVars(); + appState = appStateEntry; + clearWorldMap(); + DrawAppWindow(); + continue; + + // + case 0x39: + appState = appStatePause; + break; + + // + case 0x48: + heroDX = 0; + if ( lastMoveDirection == 0x50 ) + { + heroDY = 0; + lastMoveDirection = 0; + } + else + { + heroDY = -mapSizeX; + lastMoveDirection = 0x48; + } + break; + + // + case 0x50: + heroDX = 0; + if ( lastMoveDirection == 0x48 ) + { + heroDY = 0; + lastMoveDirection = 0; + } + else + { + heroDY = mapSizeX; + lastMoveDirection = 0x50; + } + break; + + // + case 0x4B: + heroDY = 0; + if ( lastMoveDirection == 0x4D ) + { + heroDX = 0; + lastMoveDirection = 0; + } + else + { + heroDX = -1; + lastMoveDirection = 0x4B; + } + break; + + // + case 0x4D: + heroDY = 0; + if ( lastMoveDirection == 0x4B ) + { + heroDX = 0; + lastMoveDirection = 0; + } + else + { + heroDX = 1; + lastMoveDirection = 0x4D; + } + break; + } + // + if ( MoveHero() ) + { + // + DeadHeroProcess(); + } + else + { + // + if ( CheckForNextLevel() ) + { + break; + } + } + if ( MoveEnemies() ) + { + // + DeadHeroProcess(); + } + ApplyMapDiffs(); + break; + + // + default: + // + if ( MoveHero() ) + { + // + DeadHeroProcess(); + } + if ( MoveEnemies() ) + { + // + DeadHeroProcess(); + } + ApplyMapDiffs(); + break; + } + // + if ( lifeCount <= 0 ) + { + appState = appStateAfterDeath; + DrawAppWindow(); + } + // + break; + + // + case appStateAfterDeath: + switch ( kos_WaitForEvent() ) + { + // + case 1: + DrawAppWindow(); + break; + // + case 2: + do kos_GetKey( keyCode ); while ( keyCode & 0x80 ); + if ( keyCode != 0 ) + { + // + appState = appStateTop10; + SetUpTop10(); + DrawAppWindow(); + } + break; + // + case 3: + if ( kos_GetButtonID( buttonID ) ) + { + // + if ( buttonID == 1 ) + { + // + appState = appStateTop10; + SetUpTop10(); + DrawAppWindow(); + } + } + // + default: + break; + } + break; + + // + case appStateTop10: + switch ( kos_WaitForEvent() ) + { + // + case 1: + DrawAppWindow(); + break; + // + case 2: + // + kos_GetKey( keyCode ); + // + if ( enterName < 0 ) + { + // + if ( keyCode == 0x1b ) + { + // + SetEntryVars(); + clearWorldMap(); + appState = appStateEntry; + DrawAppWindow(); + } + } + else + { + // + switch ( keyCode ) + { + // + case 13: + // + enterName = -1; + break; + // + case 8: + // + if ( enterCharNdx > 0 ) + { + // + heroTbl[enterName].name[--enterCharNdx] = '.'; + } + break; + // + default: + if ( keyCode >= 0x20 ) + { + // + heroTbl[enterName].name[enterCharNdx++] = keyCode; + // + if ( enterCharNdx >= sizeof(heroTbl[0].name) ) + { + // + enterName = -1; + } + } + break; + } + // + DrawAppWindow(); + } + // + break; + // + default: + break; + } + break; + + // + case appStatePause: + switch ( kos_WaitForEvent() ) + { + case 1: + DrawAppWindow(); + break; + + case 2: + do kos_GetKey( keyCode ); while ( keyCode & 0x80 ); + if ( keyCode != 0 ) + { + // + appState = appStateGo; + } + break; + + default: + break; + } + break; + + // + case appStateHideMap: + // + switch ( kos_WaitForEvent( 1 ) ) + { + case 1: + DrawAppWindow(); + break; + case 2: + while ( kos_GetKey( keyCode ) ); + break; + default: + bPtr = worldMap + (flipMapPtr[flipMapCount].x + (flipMapPtr[flipMapCount].y * mapSizeX)); + mapDiffList.Add( sMapDiff( bPtr, gmFlip ) ); + mapDiffList.Add( sMapDiff( bPtr + 1, gmFlip ) ); + mapDiffList.Add( sMapDiff( bPtr + mapSizeX, gmFlip ) ); + mapDiffList.Add( sMapDiff( bPtr + (mapSizeX + 1), gmFlip ) ); + ApplyMapDiffs( false ); + break; + } + // + flipMapCount++; + // + if ( flipMapCount >= flipMapSize ) + { + flipMapCount = 0; + appState = appStateShowMap; + DrawAppWindow(); + } + break; + // + case appStateShowMap: + // + switch ( kos_WaitForEvent( 1 ) ) + { + case 1: + DrawAppWindow(); + break; + default: + break; + } + // + flipMapCount++; + // + if ( flipMapCount >= BEFORE_START_LEVEL ) + { + clearWorldMap(); + flipMapCount = 0; + initWorldMap(); + appState = appStateGo; + DrawAppWindow(); + } + // + break; + } + } +} + + +// +void DrawEntryScreen() +{ + PRINTK pr; + char line[64]; + + // + kos_DefineAndDrawWindow( + 100, 100, + wndSizeX, wndSizeY, + 0, 0, + 0, 0x2040A0, + 0x2040A0 + ); + // + kos_WriteTextToWindow( + 4, 4, + 0x10, 0x42D2E2, + MainWindowTitle, + sizeof( MainWindowTitle ) - 1 + ); + // + kos_WriteTextToWindow( + 8, 32, + 0x10, 0x12FF12, + menuStr1, + sizeof( menuStr1 ) - 1 + ); + // + kos_WriteTextToWindow( + 8, 48, + 0x10, 0x12FF12, + menuStr2, + sizeof( menuStr2 ) - 1 + ); + // + kos_WriteTextToWindow( + 8, 80, + 0x10, 0xD0FF12, + menuStr3, + sizeof( menuStr3 ) - 1 + ); + // + kos_WriteTextToWindow( + 8, 96, + 0x10, 0xD0FF12, + menuStr4, + sizeof( menuStr4 ) - 1 + ); + // + pr.fmtline = worldSizeStr; + pr.args[0] = mapSizeX; + pr.args[1] = mapSizeY; + sprintk( line, &pr ); + // + kos_WriteTextToWindow( + 8, 112, + 0x10, 0x12C0D0, + line, + strlen( line ) + ); + // X + kos_DefineButton( + ENTRY_WND_SIZE_X - 58, 112, + 12, 12, + BT_SIZE_X_MINUS, + 0xCCCCCC + ); + // + kos_PutImage( bmPMButton + 12, 6, 2, ENTRY_WND_SIZE_X - 58 + 3, 117 ); + // + kos_DefineButton( + ENTRY_WND_SIZE_X - 45, 112, + 12, 12, + BT_SIZE_X_PLUS, + 0xCCCCCC + ); + // + kos_PutImage( bmPMButton, 6, 6, ENTRY_WND_SIZE_X - 45 + 3, 115 ); + // Y + kos_DefineButton( + ENTRY_WND_SIZE_X - 29, 112, + 12, 12, + BT_SIZE_Y_MINUS, + 0xCCCCCC + ); + // + kos_PutImage( bmPMButton + 12, 6, 2, ENTRY_WND_SIZE_X - 29 + 3, 117 ); + // + kos_DefineButton( + ENTRY_WND_SIZE_X - 16, 112, + 12, 12, + BT_SIZE_Y_PLUS, + 0xCCCCCC + ); + // + kos_PutImage( bmPMButton, 6, 6, ENTRY_WND_SIZE_X - 16 + 3, 115 ); + // + // + pr.fmtline = mainLoopDelayStr; + pr.args[0] = MAX_LOOP_DELAY + MIN_LOOP_DELAY - loopDelay; + sprintk( line, &pr ); + // + kos_WriteTextToWindow( + 8, 128, + 0x10, 0x12C0D0, + line, + strlen( line ) + ); + // + kos_DefineButton( + ENTRY_WND_SIZE_X - 29, 128, + 12, 12, + BT_LOOP_MINUS, + 0xCCCCCC + ); + // + kos_PutImage( bmPMButton + 12, 6, 2, ENTRY_WND_SIZE_X - 29 + 3, 133 ); + // + kos_DefineButton( + ENTRY_WND_SIZE_X - 16, 128, + 12, 12, + BT_LOOP_PLUS, + 0xCCCCCC + ); + // + kos_PutImage( bmPMButton, 6, 6, ENTRY_WND_SIZE_X - 16 + 3, 131 ); +} + + +// +void DrawAppWindow() +{ + // + kos_WindowRedrawStatus( 1 ); + + switch ( appState ) + { + // + case appStateTop10: + DrawTop10Window(); + break; + // + case appStateEntry: + // + DrawEntryScreen(); + break; + // + case appStateGo: + case appStateShowMap: + case appStatePause: + drawWorldMap(); + break; + // + case appStateAfterDeath: + // + drawWorldMap(); + // + kos_DefineButton( + ( wndSizeX / 2 ) - 64, + ( wndSizeY / 2 ) - 16, + 128, 32, + 1, + 0x136793 + ); + // + kos_WriteTextToWindow( + ( wndSizeX / 2 ) - ( sizeof( thatsAllStr ) * 4 ), + ( wndSizeY / 2 ) - 4, + 0x10, 0xFFFFFF, + thatsAllStr, + sizeof ( thatsAllStr ) - 1 + ); + + // + break; + // + case appStateHideMap: + drawWorldMapForFlip(); + break; + } + // + kos_WindowRedrawStatus( 2 ); +} + + +// +void initWorldMap() +{ + int i, j, m, allocSize; + CWallEnemy *we; + CSpaceEnemy *se; + + // + allocSize = mapSizeX * mapSizeY; + worldMap = new Byte[allocSize]; + // + __asm{ + mov edi, worldMap + mov ecx, allocSize + mov al, gmEmpty + rep stosb + } + + + // + levelFillEdge = ( ( currentLevel + 1 ) * spacePerEnemy ) + currentLevel; + levelFillCount = freeSpaceCount; + // + if ( ! noBonus ) + { + lifeCount++; + } + // + noBonus = false; + bonus1Set = false; + bonus2Set = false; + bonus1Count = 0; + goToNextLevel = false; + currentHero = gmHero; + currentTrack = gmTrack; + + // + for ( i = 0; i < mapSizeX; i++ ) + { + // + worldMap[i] = gmWall; + worldMap[mapSizeX + i] = gmWall; + // + worldMap[((mapSizeY-2)*mapSizeX) + i] = gmWall; + worldMap[((mapSizeY-1)*mapSizeX) + i] = gmWall; + } + // + for ( i = 2; i < (mapSizeY-2); i++ ) + { + // + worldMap[(i*mapSizeX)] = gmWall; + worldMap[(i*mapSizeX) + 1] = gmWall; + worldMap[(i*mapSizeX) + mapSizeX - 2] = gmWall; + worldMap[(i*mapSizeX) + mapSizeX - 1] = gmWall; + } + // + heroPtr = worldMap + ( mapSizeX / 2 ); + heroPtr[0] = gmHero; + heroDX = 0; + heroDY = 0; + // + for ( i = 0; i < currentLevel; i++ ) + { + // + for ( + j = ( rtlRand() % (mapSizeX * (mapSizeY - 2)) ) + (mapSizeX * 2); + worldMap[j] != gmWall; + j = rtlRand() % (mapSizeX * mapSizeY) + ); + // + we = new CWallEnemy(); + // + we->ePtr = worldMap + j; + we->dx = rtlRand() & 1 ? 1 : -1; + we->dy = rtlRand() & 1 ? mapSizeX : -mapSizeX; + // + mapEnemies.Add( we ); + // + worldMap[j] = gmEnemy1; + } + // + m = currentLevel + 1; + // + for ( i = 0; i < m; i++ ) + { + // + for ( + j = rtlRand() % (mapSizeX * mapSizeY); + worldMap[j] != gmEmpty; + j = rtlRand() % (mapSizeX * mapSizeY) + ); + // + se = new CSpaceEnemy(); + // + se->ePtr = worldMap + j; + se->dx = rtlRand() & 1 ? 1 : -1; + se->dy = rtlRand() & 1 ? mapSizeX : -mapSizeX; + // + mapEnemies.Add( se ); + // + worldMap[j] = gmEnemy2; + } +} + + +// +void drawWorldMap() +{ + // + kos_DefineAndDrawWindow( + 100, 100, + wndSizeX, wndSizeY, + 0, 0, + 0, 0x2040A0, + 0x2040A0 + ); + // + drawWndTitleGo(); + // + drawWorldMapForFlip(); +} + + +// +int GetCompletePercents() +{ + int n1, n2; + + // + n1 = freeSpaceCount - levelFillCount; + n2 = freeSpaceCount - levelFillEdge; + // + return ( n1 >= n2 ) ? 100 : ( n1 * 100 ) / n2; +} + + +// +void drawWndTitleGo() +{ + PRINTK pr; + char line[64]; + + // + kos_DrawBar( + 1, 1, + wndSizeX - 2, 18, + 0x2040A0 + ); + + // + pr.fmtline = goWndTitle; + pr.args[0] = currentLevel; + pr.args[1] = GetCompletePercents(); + pr.args[2] = lifeCount; + pr.args[3] = scoreCount; + sprintk( line, &pr ); + // + kos_WriteTextToWindow( + 4, 4, + 0x10, 0x42D2E2, + line, + strlen( line ) + ); + // + if ( bonus1Count > 0 ) + { + // + kos_DrawBar( + 2, 22 - BONUS1_IND_HSIZE - 1, + wndSizeX - 4, BONUS1_IND_HSIZE, + 0x2040A0 + ); + // + kos_DrawBar( + 2, 22 - BONUS1_IND_HSIZE - 1, + ( bonus1Count * ( wndSizeX - 4 ) ) / BONUS1_LIFETIME, BONUS1_IND_HSIZE, + 0x5720B0 + ); + } +} + +// +void drawWorldMapForFlip() +{ + int i, j; + Byte *mPtr = worldMap; + + // + for ( i = 0; i < mapSizeY; i++ ) + { + // + for ( j = 0; j < mapSizeX; j++ ) + { + //// + //kos_DrawBar( + // wndXOffet + ( j * blockSize ), + // wndYOffset + ( i * blockSize ), + // blockSize, blockSize, + // mapColours[*mPtr] + //); + // + kos_PutImage( + mapColours[*mPtr], + blockSize, + blockSize, + wndXOffet + ( j * blockSize ), + wndYOffset + ( i * blockSize ) + ); + // + mPtr++; + } + } +} + + +// +void clearWorldMap() +{ + int i, j; + + // + sTrackList.Clear(); + fillList.Clear(); + mapDiffList.Clear(); + // + j = mapEnemies.GetCount(); + // + for ( i = 0; i < j; i++ ) + { + // + delete mapEnemies[i]; + } + // + mapEnemies.Clear(); + // + if ( worldMap != NULL ) + { + delete worldMap; + worldMap = NULL; + } +} + + +// +char Top10WndTitle[] = "Top 10"; + +// +void DrawTop10Window() +{ + int i; + + // + kos_DefineAndDrawWindow( + 100, 100, + TOP10_WND_SIZE_X, TOP10_WND_SIZE_Y, + 0, 0, + 0, 0x2040A0, + 0x2040A0 + ); + // + kos_WriteTextToWindow( + 4, 4, + 0x0, 0x42D2E2, + Top10WndTitle, + sizeof( Top10WndTitle ) - 1 + ); + // + for ( i = 0; i < TOP_TBL_SIZE; i++ ) + { + // + kos_WriteTextToWindow( + 6, wndYOffset + 2 + (i * 10), + 0x0, enterName != i ? 0xFFFFFF : 0x00FF00, + heroTbl[i].name, + sizeof( heroTbl[0].name ) + ); + // + kos_DisplayNumberToWindow( + heroTbl[i].score, + 8, + 112, wndYOffset + 2 + (i * 10), + 0xFFFF55, + nbDecimal, + false + ); + } + // + kos_WriteTextToWindow( + 6, wndYOffset + 6 + (i * 10), + 0x10, 0x1060D0, + enterName >= 0 ? top10str1 : top10str2, + enterName >= 0 ? sizeof(top10str1) - 1 : sizeof(top10str2) - 1 + ); +} + + diff --git a/programs/games/xonix/trunk/mcarray.h b/programs/games/xonix/trunk/mcarray.h new file mode 100644 index 0000000000..48e338ec05 --- /dev/null +++ b/programs/games/xonix/trunk/mcarray.h @@ -0,0 +1,167 @@ +#define AR_CHUNK_SIZE 64 + +// +template +class MCArray +{ +protected: + TYPE * _dataPtr; + int _elementsCount; + int _capacity; + +public: + MCArray(); + ~MCArray(); + virtual int Add( const TYPE &element ); + TYPE & GetAt( int Ndx ); + TYPE & operator [] ( int Ndx ); + int Find( int startNdx, TYPE & element ); + int RemoveAt( int Ndx ); + void Clear(void); + int GetCount(void); +}; + +// + + +// +template +MCArray::MCArray() +{ + // + this->_dataPtr = NULL; + this->_capacity = 0; + this->_elementsCount = 0; +} + + +// +template +MCArray::~MCArray() +{ + // + this->_capacity = 0; + this->_elementsCount = 0; + // + if ( this->_dataPtr != NULL ) + { + delete this->_dataPtr; + } +} + + +// +template +int MCArray::Add( const TYPE &element ) +{ + TYPE * dPtr; + + // ? + if ( this->_elementsCount >= this->_capacity ) + { + // + dPtr = new TYPE [this->_capacity + AR_CHUNK_SIZE]; + // + if ( dPtr == NULL ) + { + // + return -1; + } + + if ( this->_capacity > 0 ) + { + // + memcpy( dPtr, this->_dataPtr, sizeof(TYPE) * this->_capacity ); + // + delete this->_dataPtr; + } + // + this->_capacity += AR_CHUNK_SIZE; + // + this->_dataPtr = dPtr; + } + + // + memcpy( this->_dataPtr + this->_elementsCount, &element, sizeof(TYPE) ); + + // + return ++this->_elementsCount; +} + + +// +template +TYPE & MCArray::GetAt( int Ndx ) +{ + //assert( Ndx >= 0 && Ndx < this->_elementsCount ); + return this->_dataPtr[Ndx]; +} + + +// +template +TYPE & MCArray::operator [] ( int Ndx ) +{ + return this->GetAt( Ndx ); +} + + +// +template +int MCArray::Find( int startNdx, TYPE & element ) +{ + int i; + + if ( startNdx < 0 || startNdx >= this->_elementsCount ) + { + return -1; + } + + for ( i = startNdx; i < this->_elementsCount; i++ ) + { + if ( element == this->_dataPtr[i] ) + { + return i; + } + } + + return -1; +} + + +// +template +int MCArray::RemoveAt( int Ndx ) +{ + int mn; + + if ( Ndx < 0 || Ndx >= this->_elementsCount ) + { + return 0; + } + + mn = this->_elementsCount - Ndx; + + if ( mn != 1 ) + { + memcpy( this->_dataPtr + Ndx, this->_dataPtr + Ndx + 1, sizeof(TYPE) * ( mn - 1 ) ); + } + + this->_elementsCount--; + return 1; +} + + +// +template +void MCArray::Clear() +{ + this->_elementsCount = 0; +} + +// +template +int MCArray::GetCount() +{ + return this->_elementsCount; +} diff --git a/programs/games/xonix/trunk/mcsmemm.cpp b/programs/games/xonix/trunk/mcsmemm.cpp new file mode 100644 index 0000000000..20feab80f6 --- /dev/null +++ b/programs/games/xonix/trunk/mcsmemm.cpp @@ -0,0 +1,329 @@ +// memman.cpp : Defines the entry point for the console application. +// + +#include "kosSyst.h" +#include "mcsmemm.h" + + +void * __cdecl operator new ( size_t count, size_t element_size ) +{ + return allocmem( (Dword)(count * element_size) ); +} + +void * __cdecl operator new [] ( size_t amount ) +{ + return allocmem( (Dword)amount ); +} + +void * __cdecl operator new ( size_t amount ) +{ + return allocmem( (Dword)amount ); +} + +void __cdecl operator delete ( void *pointer ) +{ + if ( pointer != NULL ) freemem( pointer ); +} + +void __cdecl operator delete [] ( void *pointer ) +{ + if ( pointer != NULL ) freemem( pointer ); +} + + +// +Dword mmMutex = FALSE; +MemBlock *rootfree = NULL; +MemBlock *rootuser = NULL; +bool mmInitialized = false; +Byte *mmHeapTop = NULL; + + +// +Byte * AllocMemFromSystem( Dword reqSize ) +{ + Byte *result; + sProcessInfo pInfo; + + // + if ( mmInitialized ) + { + result = mmHeapTop; + } + else + { + // + kos_ProcessInfo( &pInfo ); + // + result = (Byte *)(pInfo.processInfo.used_memory + 1); + // + mmInitialized = true; + } + // + if ( ! kos_ApplicationMemoryResize( ((Dword)result) + reqSize ) ) + { + result = NULL; + } + // + mmHeapTop = result + reqSize; + // + return result; +} + + +// +Byte *allocmem( Dword reqsize ) +{ + MemBlock *BlockForCheck; + MemBlock *LastKnownGood; + Dword tail; + Byte *address; + + // + if( ( tail = reqsize % SIZE_ALIGN ) != 0 ) + { + reqsize += SIZE_ALIGN - tail; + } + + LastKnownGood = NULL; + + // + while ( rtlInterlockedExchange( &mmMutex, TRUE ) ) + { + // + kos_Pause( 1 ); + } + + // + if( rootfree != NULL ) + { + for ( BlockForCheck = rootfree; ; BlockForCheck = BlockForCheck->Next ) + { + if ( BlockForCheck->Size >= reqsize ) + { + // + if ( LastKnownGood != NULL ) + { + if ( LastKnownGood->Size >= BlockForCheck->Size ) + LastKnownGood = BlockForCheck; + } + else + LastKnownGood = BlockForCheck; + if ( LastKnownGood->Size == reqsize ) + break; + } + if ( BlockForCheck->Next == NULL ) + break; + } + } + + if ( LastKnownGood != NULL ) + { + // + tail = LastKnownGood->Size - reqsize; + if ( tail >= ( sizeof(MemBlock) + SIZE_ALIGN ) ) + { + // + BlockForCheck = (MemBlock *)( ( (Byte *)LastKnownGood ) + tail ); + BlockForCheck->Size = reqsize; + // + if( rootuser != NULL ) + { + BlockForCheck->Next = rootuser; + rootuser->Previous = BlockForCheck; + BlockForCheck->Previous = NULL; + rootuser = BlockForCheck; + } + else + { + rootuser = BlockForCheck; + BlockForCheck->Next = NULL; + BlockForCheck->Previous = NULL; + } + + // + LastKnownGood->Size = tail - sizeof(MemBlock); + address = ( (Byte *)BlockForCheck ) + sizeof(MemBlock); + + // + rtlInterlockedExchange( &mmMutex, FALSE ); + + return address; + } + else + { + // + // + if ( LastKnownGood->Previous != NULL ) + { + LastKnownGood->Previous->Next = LastKnownGood->Next; + } + else + { + // + rootfree = LastKnownGood->Next; + } + if( LastKnownGood->Next != NULL ) + { + LastKnownGood->Next->Previous = LastKnownGood->Previous; + } + // + if( rootuser != NULL ) + { + LastKnownGood->Next = rootuser; + rootuser->Previous = LastKnownGood; + LastKnownGood->Previous = NULL; + rootuser = LastKnownGood; + } + else + { + rootuser = LastKnownGood; + LastKnownGood->Next = NULL; + LastKnownGood->Previous = NULL; + } + // + address = ( (Byte *)LastKnownGood ) + sizeof(MemBlock); + + // + rtlInterlockedExchange( &mmMutex, FALSE ); + + return address; + } + } + else + { + // + LastKnownGood = (MemBlock *)AllocMemFromSystem( reqsize + sizeof(MemBlock) ); + // + if( LastKnownGood != NULL ) + { + LastKnownGood->Size = reqsize; + // + if( rootuser != NULL ) + { + LastKnownGood->Next = rootuser; + rootuser->Previous = LastKnownGood; + LastKnownGood->Previous = NULL; + rootuser = LastKnownGood; + } + else + { + rootuser = LastKnownGood; + LastKnownGood->Next = NULL; + LastKnownGood->Previous = NULL; + } + address = ( (Byte *)LastKnownGood ) + sizeof(MemBlock); + + // + rtlInterlockedExchange( &mmMutex, FALSE ); + + return address; + } + } + + // + rtlInterlockedExchange( &mmMutex, FALSE ); + + // + rtlDebugOutString( "allocmem failed." ); + kos_ExitApp(); + // + return NULL; +} + +// +Dword freemem( void *vaddress ) +{ + Dword result; + + Byte *checknext, *address = (Byte *)vaddress; + + // + while ( rtlInterlockedExchange( &mmMutex, TRUE ) ) + { + // + kos_Pause( 1 ); + } + + MemBlock *released = (MemBlock *)( address - sizeof(MemBlock) ); + + result = released->Size; + + // + if ( released->Previous != NULL ) + { + released->Previous->Next = released->Next; + } + else + { + rootuser = released->Next; + } + if ( released->Next != NULL ) + { + released->Next->Previous = released->Previous; + } + // + released->Next = rootfree; + released->Previous = NULL; + rootfree = released; + if ( released->Next != NULL ) + { + released->Next->Previous = released; + } + + // + checknext = (Byte *)(rootfree) + ( rootfree->Size + sizeof(MemBlock) ); + // + for ( released = rootfree->Next; released != NULL; released = released->Next ) + { + if ( checknext == (Byte *)released ) + { + // + // + released->Previous->Next = released->Next; + if( released->Next != NULL ) + { + released->Next->Previous = released->Previous; + } + // + rootfree->Size += released->Size + sizeof(MemBlock); + break; + } + } + // , . + checknext = (Byte *)(rootfree); + // + if ( released == NULL ) + { + for ( released = rootfree->Next; released != NULL; released = released->Next ) + { + if ( checknext == (Byte *)released + ( released->Size + sizeof(MemBlock) ) ) + { + // + // + released->Size += rootfree->Size + sizeof(MemBlock); + // + released->Previous->Next = released->Next; + if ( released->Next != NULL ) + { + released->Next->Previous = released->Previous; + } + // + if ( rootfree->Next != NULL ) + { + rootfree->Next->Previous = released; + } + released->Next = rootfree->Next; + released->Previous = NULL; + rootfree = released; + break; + } + } + } + + // + rtlInterlockedExchange( &mmMutex, FALSE ); + + return result; +} + diff --git a/programs/games/xonix/trunk/resource.h b/programs/games/xonix/trunk/resource.h new file mode 100644 index 0000000000..fff35ca30a --- /dev/null +++ b/programs/games/xonix/trunk/resource.h @@ -0,0 +1,15 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by fatest.rc +// + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif