Added sources of the following games: bnc, checkers, fara, FindNumbers, gomoku, reversi, rforces, sq_game, sudoku, whowtbam, xonix.

git-svn-id: svn://kolibrios.org@1805 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Yogev Ezra 2011-01-30 10:48:08 +00:00
parent 88fbc24f19
commit c2fbdf929c
126 changed files with 32947 additions and 0 deletions

View File

@ -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<xx; k++)
{
IF (box[k].text==temp)
{
p=2;
BREAK;
}
}
}
return temp;
}
stop:

View File

@ -0,0 +1,168 @@
//CODED by Veliant, Leency, Nable. GNU GPL licence.
#code32 TRUE
char os_name[8] = {'M','E','N','U','E','T','0','1'};
dword os_version = 0x00000001;
dword start_addr = #main;
dword final_addr = #stop+32;
dword alloc_mem = 0x00100000;
dword x86esp_reg = 0x00100000;
dword I_Param = #param;
dword I_Icon = 0x0;
char param[256]="";
//Events
#define evMouse 6
#define evButton 3
#define evKey 2
#define evReDraw 1
//Button options
#define BT_DEL 0x80000000
#define BT_HIDE 0x40000000
#define BT_NOFRAME 0x20000000
#define OLD -1
#define true 1
#define false 0
inline fastcall dword WaitEvent(){
EAX = 10;
$int 0x40
}
inline fastcall word GetKey(){
EAX = 2; // just read this key from buffer
$int 0x40
EAX = EAX >> 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);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@ -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

View File

@ -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% проиграли.

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -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
;--------------------------------------
}

View File

@ -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
}

View File

@ -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

View File

@ -0,0 +1 @@
lang fix ru

View File

@ -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 <eax,ebx,ecx,edx,esi,edi,ebp,esp>
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

View File

@ -0,0 +1,86 @@
;************************************
;******** Œ€Š<EFBFBD>Ž *******************
;************************************
; 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
}

View File

@ -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
;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,355 @@
#ifndef _HEADER_BUTTONS_H
#define _HEADER_BUTTONS_H
#ifndef __MENUET__
#include <string.h>
#include <stdlib.h>
#include <limits.h>
#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

File diff suppressed because it is too large Load Diff

View File

@ -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.

View File

@ -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

View File

@ -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 <graphics.h>
#include <conio.h>
#include <stdio.h>
#include <limits.h>
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

View File

@ -0,0 +1,172 @@
#ifndef _INCLUDE_DOS_MOUSE
#define _INCLUDE_DOS_MOUSE
#include <dos.h>
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

Binary file not shown.

View File

@ -0,0 +1,295 @@
#include "gr-draw.h"
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>
#include <X11/keysym.h>
#include <stdio.h>
#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

View File

@ -0,0 +1,121 @@
#ifndef _GRAPHIC_DRAW_H
#define _GRAPHIC_DRAW_H
#ifndef __MENUET__
#include <limits.h>
#include <string.h>
#ifdef _Windows
# include <windows.h>
#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

View File

@ -0,0 +1,185 @@
#if !defined(HASH_TABLE_H)
#define HASH_TABLE_H
template <class T, class TypeString, class HashFunction>
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 <class T, class TypeString, class HashFunction>
void THashTable<T, TypeString, HashFunction>::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 <class T, class TypeString, class HashFunction>
void THashTable<T, TypeString, HashFunction>::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 <class T, class TypeString, class HashFunction>
inline void THashTable<T, TypeString, HashFunction>::push(const T &x)
{
if (n == stack_size) resize(M + 1);
_push(x);
}
template <class T, class TypeString, class HashFunction>
inline T *THashTable<T, TypeString, HashFunction>::find(const TypeString &x)
{
int i = _find(x);
if (i >= 0) return table[i];
else return 0;
}
template <class T, class TypeString, class HashFunction>
inline void THashTable<T, TypeString, HashFunction>::pop()
{
if (n > 0)
{
n--;
int i = _find_pointer(stack + n);
if (i >= 0) table[i] = NULL;
}
}
template <class T, class TypeString, class HashFunction>
void THashTable<T, TypeString, HashFunction>::_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 <class T, class TypeString, class HashFunction>
int THashTable<T, TypeString, HashFunction>::_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 <class T, class TypeString, class HashFunction>
int THashTable<T, TypeString, HashFunction>::_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 <class T, class TypeString, class HashFunction>
void THashTable<T, TypeString, HashFunction>::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

View File

@ -0,0 +1,402 @@
#ifndef _HEADER_HISTORY_H
#define _HEADER_HISTORY_H
#ifndef __MENUET__
#include <string.h>
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#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<TTableItem, TStr, THash> 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

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,90 @@
#ifndef __MENUET_HEAP_H_INCLUDED_
#define __MENUET_HEAP_H_INCLUDED_
#include <menuet.h>
#include <memheap.h>
// 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_

View File

@ -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
;/**/

View File

@ -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_

View File

@ -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

View File

@ -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
}

View File

@ -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_

View File

@ -0,0 +1,536 @@
#ifndef __MENUET_H_INCLUDED_
#define __MENUET_H_INCLUDED_
#include <me_lib.h>
// 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 <me_func.inc>
// 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_

View File

@ -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 */

View File

@ -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
}

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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"

View File

@ -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;
}

View File

@ -0,0 +1,888 @@
#ifndef _HEADER_PLAYER_H
#define _HEADER_PLAYER_H
#include "position.h"
#include "sysproc.h"
#ifndef __MENUET__
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#endif
template <class tvalue>
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 <class tvalue>
const int TBaseCompPlayer<tvalue>::PKind = 0x2000;
template <class tvalue>
const tvalue TBaseCompPlayer<tvalue>::win_val = (tvalue)10000000L;
template <class tvalue>
void TBaseCompPlayer<tvalue>::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 <class tvalue>
void TBaseCompPlayer<tvalue>::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 <class tvalue>
int TBaseCompPlayer<tvalue>::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 <class tvalue>
int TBaseCompPlayer<tvalue>::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 <class tvalue>
void TBaseCompPlayer<tvalue>::Z::Sort(int n0, int n1)
{
qsort(array + n0, n1 - n0, sizeof(PMvv), ComparePMv);
}
template <class tvalue>
tvalue TBaseCompPlayer<tvalue>::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 <class tvalue>
tvalue TBaseCompPlayer<tvalue>::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 <class tvalue>
tvalue TBaseCompPlayer<tvalue>::GetFullValue(const Position &pos, int num)
{
if (!pos.AllCanMove() && !pos.AllCanEat()) return GetLossValue(pos);
else return GetValue(pos, num);
}
template <class tvalue>
tvalue TBaseCompPlayer<tvalue>::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 <class tvalue>
int TBaseCompPlayer<tvalue>::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<long> TComputerPlayer;
#endif //_HEADER_PLAYER_H

View File

@ -0,0 +1,882 @@
#ifndef _HEADER_POSITION_H
#define _HEADER_POSITION_H
#ifndef __MENUET__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#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

View File

@ -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;
}
}

View File

@ -0,0 +1,27 @@
#ifndef _HEADER_SYSTEM_PROCESS_H
#define _HEADER_SYSTEM_PROCESS_H
#ifndef __MENUET__
#include <stdlib.h>
#include <time.h>
#endif
#if defined __GNUC__
# include <unistd.h>
# 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 <process.h>
# 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

Binary file not shown.

View File

@ -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

View File

@ -0,0 +1,106 @@
#define IDC_DEBUG 22003
#define IDC_COPYRIGHT 22002
#define IDC_VERSION 22001
#include <windows.h>
#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
}

Binary file not shown.

View File

@ -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 <windows.h>
#include <owl\window.h>
#include <owl\framewin.h>
#include <owl\dialog.h>
#include <owl\checkbox.h>
#include <owl\edit.h>
#include <owl\applicat.h>
#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

View File

@ -0,0 +1,3 @@
#define IDC_DEBUG 22003
#define IDC_COPYRIGHT 22002
#define IDC_VERSION 22001

View File

@ -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;
}

View File

@ -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);
};

View File

@ -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 );

Binary file not shown.

Binary file not shown.

View File

@ -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

View File

@ -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>
{{{
}}}
###############################################################################

Binary file not shown.

View File

@ -0,0 +1,166 @@
#include <stdio.h>
#include <stdlib.h>
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 <destination> <src1> <src2> ...\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<argc;i++)
{
FILE* fi = fopen(argv[i], "rb");
if (!fi)
{
printf("Cannot open input file %s\n",argv[i]);
continue;
}
unsigned char buf[0x36];
fread(buf,1,0x36,fi);
if (buf[0] != 'B' || buf[1] != 'M')
{
if (buf[0] != 0xFF || buf[1] != 0xD8)
{
printf("%s: unrecognized type\n",argv[i]);
fclose(fi);
continue;
}
// JPEG
printf("Processing %s ...",argv[i]);
fseek(fi,0,SEEK_END);
unsigned insize = ftell(fi);
void* output = malloc(insize);
unsigned char* ptr = (unsigned char*)output;
*ptr++ = 0xFF;
*ptr++ = 0xD8;
// Now load JPEG file, skipping all APPx markers
fseek(fi,2,SEEK_SET);
bool bOk = false;
for (;;)
{
if (fread(buf,1,4,fi) != 4 || buf[0] != 0xFF)
{
printf("%s: invalid JPEG file\n",argv[i]);
bOk = false;
break;
}
// ignore APPx markers
if (buf[1] >= 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<height;p++)
{
fseek(fi,(height-p-1)*linesize+0x36,SEEK_SET);
fread((char*)input+p*width*3, 1, width*3, fi);
}
fclose(fi);
hea[i-2].sizeX = (short)width;
hea[i-2].sizeY = (short)height;
unsigned uncompressedSize = width*height*3;
hea[i-2].uncompressedSize = uncompressedSize;
hea[i-2].physicalOffset = (i==2) ? 0 :
hea[i-3].physicalOffset+hea[i-3].compressedSize;
printf("Compressing %s ...",argv[i]);
unsigned compressedSize = lzma_compress(input,packed,
uncompressedSize,workmem);
if (compressedSize >= 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<n;i++)
hea[i].physicalOffset += 4+n*sizeof(SCompBmpHeader);
fwrite(&n,4,1,fo);
fwrite(hea,sizeof(SCompBmpHeader),n,fo);
for (i=0;i<n;i++)
{
fwrite(ptrs[i],1,hea[i].compressedSize,fo);
free(ptrs[i]);
}
fclose(fo);
free(hea);
free(workmem);
free(ptrs);
return 0;
}

View File

@ -0,0 +1,3 @@
bmp2src.exe fara.gfx face.jpg gmplace.jpg mainfish.bmp numbers.bmp

View File

@ -0,0 +1,64 @@
#include "kosSyst.h"
#include "CRC32.h"
CCRC32::CCRC32()
{
Dword i, mask, j, k;
for ( i=0xEDB8; 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<length; i++ )
{
mask = (Byte)( ( result ^ buffer[i] ) & 0xFF );
result = ( result >>= 8 ) ^ this->table[mask];
}
*CRC32value = result;
}
Dword CCRC32::GetCRC32(Byte *buffer, Dword length)
{
Dword result;
result = 0xFFFFFFFF;
this->DoCRC32( buffer, length, &result );
return ~result;
}

View File

@ -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_)

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

View File

@ -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

View File

@ -0,0 +1,290 @@
<?xml version="1.0" encoding="windows-1251"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8,00"
Name="fara"
ProjectGUID="{E102A7F0-5525-45CD-8078-82540F673720}"
RootNamespace="fara"
Keyword="Win32Proj"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="Debug"
IntermediateDirectory="Debug"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/fara.exe"
LinkIncremental="2"
GenerateDebugInformation="true"
ProgramDatabaseFile="$(OutDir)/fara.pdb"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="Release"
IntermediateDirectory="Release"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
CharacterSet="0"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="false"
FavorSizeOrSpeed="1"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
IgnoreStandardIncludePath="false"
ExceptionHandling="0"
RuntimeLibrary="0"
StructMemberAlignment="1"
BufferSecurityCheck="false"
RuntimeTypeInfo="false"
UsePrecompiledHeader="0"
AssemblerOutput="4"
WarningLevel="3"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/ALIGN:32"
AdditionalDependencies="lzma_unpack.obj"
OutputFile="$(OutDir)/fara.exe"
LinkIncremental="1"
GenerateManifest="false"
IgnoreAllDefaultLibraries="true"
GenerateDebugInformation="false"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
EntryPointSymbol="crtStartUp"
BaseAddress="0x0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
EmbedManifest="false"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\crc32.cpp"
>
</File>
<File
RelativePath=".\gameWnd.cpp"
>
</File>
<File
RelativePath=".\gfxdef.cpp"
>
</File>
<File
RelativePath=".\KosFile.cpp"
>
</File>
<File
RelativePath=".\kosSyst.cpp"
>
</File>
<File
RelativePath=".\main.cpp"
>
</File>
<File
RelativePath=".\mainWnd.cpp"
>
</File>
<File
RelativePath=".\mcsmemm.cpp"
>
</File>
<File
RelativePath=".\top10wnd.cpp"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath=".\crc32.h"
>
</File>
<File
RelativePath=".\gameWnd.h"
>
</File>
<File
RelativePath=".\gfxdef.h"
>
</File>
<File
RelativePath=".\KosFile.h"
>
</File>
<File
RelativePath=".\kosSyst.h"
>
</File>
<File
RelativePath=".\lang.h"
>
</File>
<File
RelativePath=".\mainWnd.h"
>
</File>
<File
RelativePath=".\mcarray.h"
>
</File>
<File
RelativePath=".\Mcsmemm.h"
>
</File>
<File
RelativePath=".\top10wnd.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

File diff suppressed because it is too large Load Diff

View File

@ -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();

View File

@ -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;j<blockSize;j++)
{
RGB* srcBits = mainBits + blockSize*blockSize*(k+1) + blockSize*j;
a = 0;
for (i=0;i<size;i++)
{
ptrBuf->b = 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;j<size;j++)
{
ptrBuf = buffer + blockSize*blockSize*k + blockSize*delta + delta+j;
RGB* srcBits = tmpBuf + j;
a = 0;
for (i=0;i<size;i++)
{
ptrBuf->b = 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;
}

View File

@ -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);
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 601 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

View File

@ -0,0 +1,31 @@
ГРОБНИЦА ФАРАОНА
Смысл игры состоит в том, чтобы, перемещая иероглифы на входе в очередную комнату гробницы фараона (8Х8), открыть проход.
Вы можете менять местами два иероглифа расположенных рядом по вертикали или горизонтали в случае, если при такой перестановке образуется комбинация из трех или более одинаковых картинок в ряд. Такие ряды тут же исчезают, а свободное место заполняется иероглифами "осыпавшимися" сверху. Недостающие иероглифы генерируются случайным образом.
За исчезающие иероглифы начисляются очки. За комбинацию из иероглифов даются очки по формуле 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 искривитель).
Игра заканчивается, если игрок не может составить ни одной комбинации имеющимися у него в распоряжении иероглифами.

View File

@ -0,0 +1,870 @@
#include "kosSyst.h"
#include <stdarg.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 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();
}

View File

@ -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();

View File

@ -0,0 +1,3 @@
#define RUS 1
#define ENG 2
#define LANG RUS

View File

@ -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 ?

Binary file not shown.

View File

@ -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;
}

View File

@ -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. <20> ç âì ¨£àã";
char mainWndMenuExit[] = "2. ‚ë室";
char mainWndMenuLevel[] = "<EFBFBD> ç «ì­ë© ã஢¥­ì - %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 );
}

View File

@ -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;

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

View File

@ -0,0 +1,181 @@
#define AR_CHUNK_SIZE 64
//
template<class TYPE>
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<class TYPE>
MCArray<TYPE>::MCArray()
{
// óñòàíàâëèâàåì ïåðåìåííûå
this->_dataPtr = NULL;
this->_capacity = 0;
this->_elementsCount = 0;
}
//
template<class TYPE>
MCArray<TYPE>::~MCArray()
{
//
this->_capacity = 0;
this->_elementsCount = 0;
//
if ( this->_dataPtr != NULL )
{
delete this->_dataPtr;
}
}
//
template<class TYPE>
int MCArray<TYPE>::AddExclusive( const TYPE &element )
{
//
if ( this->Find( 0, element ) < 0 )
return this->Add( element );
else
return -1;
}
//
template<class TYPE>
int MCArray<TYPE>::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<class TYPE>
TYPE & MCArray<TYPE>::GetAt( int Ndx )
{
//assert( Ndx >= 0 && Ndx < this->_elementsCount );
return this->_dataPtr[Ndx];
}
//
template<class TYPE>
TYPE & MCArray<TYPE>::operator [] ( int Ndx )
{
return this->GetAt( Ndx );
}
//
template<class TYPE>
int MCArray<TYPE>::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<class TYPE>
int MCArray<TYPE>::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<class TYPE>
void MCArray<TYPE>::Clear()
{
this->_elementsCount = 0;
}
//
template<class TYPE>
int MCArray<TYPE>::GetCount()
{
return this->_elementsCount;
}

View File

@ -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;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

View File

@ -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;
}
}
}

View File

@ -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();

View File

@ -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 '<27>®¢ ï €¢â®',0
txt_go db 'ˆ£à  ®ª®­ç¥­ ',0
txt_tie db '<27>¥â 室®¢',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

View File

@ -0,0 +1,3 @@
OUTFILE = reversi
OBJS = reversi.o
include $(MENUETDEV)/makefiles/Makefile_for_program

View File

@ -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<menuet/os.h>
#include<stdint.h>
#include<stdlib.h>
#include<stdio.h>
#include<ctype.h>
#include<string.h>
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;
}
}
}

View File

@ -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);
};

View File

@ -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

View File

@ -0,0 +1,402 @@
/* Rocket Forces
* Filename: rforces.cpp
* Version 0.1
* Copyright (c) Serial 2007
*/
#include <stdlib.h>
#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();
}

View File

@ -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;
}

View File

@ -0,0 +1,970 @@
#include "kosSyst.h"
#include <stdarg.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 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();
}

View File

@ -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();

View File

@ -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;
}

View File

@ -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 );

View File

@ -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);
}

Some files were not shown because too many files have changed in this diff Show More