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
157
programs/games/FindNumbers/trunk/FindNumbers.c--
Normal 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:
|
168
programs/games/FindNumbers/trunk/kolibri.h--
Normal 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);
|
||||
}
|
BIN
programs/games/bnc/trunk/bk100.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
programs/games/bnc/trunk/bk5.PNG
Normal file
After Width: | Height: | Size: 2.6 KiB |
22
programs/games/bnc/trunk/bnc.asm
Normal 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
|
||||
|
53
programs/games/bnc/trunk/bnc.txt
Normal 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% проиграли.
|
||||
|
BIN
programs/games/bnc/trunk/bnc4.PNG
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
programs/games/bnc/trunk/bnc6.PNG
Normal file
After Width: | Height: | Size: 1.7 KiB |
205
programs/games/bnc/trunk/code.inc
Normal 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
|
||||
;--------------------------------------
|
||||
}
|
||||
|
35
programs/games/bnc/trunk/data.inc
Normal 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
|
||||
|
||||
}
|
595
programs/games/bnc/trunk/draw.inc
Normal 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
|
1
programs/games/bnc/trunk/lang.inc
Normal file
@ -0,0 +1 @@
|
||||
lang fix ru
|
270
programs/games/bnc/trunk/macros.inc
Normal 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
|
86
programs/games/bnc/trunk/macs.inc
Normal 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
|
||||
}
|
74
programs/games/bnc/trunk/main.inc
Normal 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
|
||||
;
|
||||
}
|
||||
|
1410
programs/games/checkers/trunk/board.h
Normal file
355
programs/games/checkers/trunk/buttons.h
Normal 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
|
||||
|
1420
programs/games/checkers/trunk/checkers.cpp
Normal file
21
programs/games/checkers/trunk/compile.txt
Normal 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.
|
3
programs/games/checkers/trunk/cpp2asm.bat
Normal 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
|
381
programs/games/checkers/trunk/dos-draw.h
Normal 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
|
172
programs/games/checkers/trunk/dosmouse.h
Normal 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
|
BIN
programs/games/checkers/trunk/egavga.bgi
Normal file
295
programs/games/checkers/trunk/gnu-draw.h
Normal 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
|
121
programs/games/checkers/trunk/gr-draw.h
Normal 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
|
185
programs/games/checkers/trunk/hash.h
Normal 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
|
402
programs/games/checkers/trunk/history.h
Normal 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
|
1135
programs/games/checkers/trunk/include/me_func.inc
Normal file
90
programs/games/checkers/trunk/include/me_heap.h
Normal 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_
|
284
programs/games/checkers/trunk/include/me_heap.inc
Normal 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
|
||||
|
||||
;/**/
|
16
programs/games/checkers/trunk/include/me_lib.h
Normal 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_
|
118
programs/games/checkers/trunk/include/me_lib.inc
Normal 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
|
||||
|
90
programs/games/checkers/trunk/include/me_start.inc
Normal 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
|
||||
}
|
626
programs/games/checkers/trunk/include/memheap.h
Normal 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_
|
||||
|
536
programs/games/checkers/trunk/include/menuet.h
Normal 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_
|
||||
|
13
programs/games/checkers/trunk/include/stdarg.h
Normal 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 */
|
49
programs/games/checkers/trunk/include/write_macro.inc
Normal 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
|
||||
}
|
||||
|
2047
programs/games/checkers/trunk/keysym.h
Normal file
4
programs/games/checkers/trunk/makefile
Normal 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
|
10
programs/games/checkers/trunk/me_make.inc
Normal 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"
|
79
programs/games/checkers/trunk/mt-draw.h
Normal 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;
|
||||
}
|
888
programs/games/checkers/trunk/player.h
Normal 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
|
882
programs/games/checkers/trunk/position.h
Normal 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
|
331
programs/games/checkers/trunk/qsort.c
Normal 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;
|
||||
}
|
||||
}
|
27
programs/games/checkers/trunk/sysproc.h
Normal 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
|
BIN
programs/games/checkers/trunk/t2fasm.exe
Normal file
729
programs/games/checkers/trunk/tmplayer.h
Normal 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
|
106
programs/games/checkers/trunk/win-chk.rc
Normal 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
|
||||
}
|
||||
|
||||
|
||||
|
BIN
programs/games/checkers/trunk/win-chk.res
Normal file
530
programs/games/checkers/trunk/win-draw.h
Normal 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
|
3
programs/games/checkers/trunk/winabout.rh
Normal file
@ -0,0 +1,3 @@
|
||||
#define IDC_DEBUG 22003
|
||||
#define IDC_COPYRIGHT 22002
|
||||
#define IDC_VERSION 22001
|
131
programs/games/fara/trunk/KosFile.cpp
Normal 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;
|
||||
}
|
||||
|
26
programs/games/fara/trunk/KosFile.h
Normal 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);
|
||||
};
|
28
programs/games/fara/trunk/MCSMEMM.H
Normal 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 );
|
||||
|
||||
|
||||
|
BIN
programs/games/fara/trunk/Release/pe2kos.exe
Normal file
BIN
programs/games/fara/trunk/bmp2src.exe
Normal file
103
programs/games/fara/trunk/bmp2src/bmp2src.dsp
Normal 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
|
29
programs/games/fara/trunk/bmp2src/bmp2src.dsw
Normal 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>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
BIN
programs/games/fara/trunk/bmp2src/lzmapack.lib
Normal file
166
programs/games/fara/trunk/bmp2src/main.cpp
Normal 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;
|
||||
}
|
3
programs/games/fara/trunk/build_gfx.bat
Normal file
@ -0,0 +1,3 @@
|
||||
bmp2src.exe fara.gfx face.jpg gmplace.jpg mainfish.bmp numbers.bmp
|
||||
|
||||
|
64
programs/games/fara/trunk/crc32.cpp
Normal 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;
|
||||
}
|
18
programs/games/fara/trunk/crc32.h
Normal 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_)
|
BIN
programs/games/fara/trunk/face.bmp
Normal file
After Width: | Height: | Size: 113 KiB |
BIN
programs/games/fara/trunk/face.jpg
Normal file
After Width: | Height: | Size: 8.8 KiB |
19
programs/games/fara/trunk/fara.sln
Normal 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
|
290
programs/games/fara/trunk/fara.vcproj
Normal 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>
|
1585
programs/games/fara/trunk/gameWnd.cpp
Normal file
29
programs/games/fara/trunk/gameWnd.h
Normal 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();
|
||||
|
285
programs/games/fara/trunk/gfxdef.cpp
Normal 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;
|
||||
}
|
||||
|
101
programs/games/fara/trunk/gfxdef.h
Normal 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);
|
||||
};
|
||||
|
BIN
programs/games/fara/trunk/gmplace.bmp
Normal file
After Width: | Height: | Size: 601 KiB |
BIN
programs/games/fara/trunk/gmplace.jpg
Normal file
After Width: | Height: | Size: 38 KiB |
31
programs/games/fara/trunk/grobfar.txt
Normal 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 искривитель).
|
||||
|
||||
Игра заканчивается, если игрок не может составить ни одной комбинации имеющимися у него в распоряжении иероглифами.
|
||||
|
870
programs/games/fara/trunk/kosSyst.cpp
Normal 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();
|
||||
}
|
||||
|
||||
|
197
programs/games/fara/trunk/kosSyst.h
Normal 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();
|
3
programs/games/fara/trunk/lang.h
Normal file
@ -0,0 +1,3 @@
|
||||
#define RUS 1
|
||||
#define ENG 2
|
||||
#define LANG RUS
|
393
programs/games/fara/trunk/lzma_unpack.asm
Normal 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 ?
|
BIN
programs/games/fara/trunk/lzma_unpack.obj
Normal file
80
programs/games/fara/trunk/main.cpp
Normal 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;
|
||||
}
|
||||
|
211
programs/games/fara/trunk/mainWnd.cpp
Normal 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 );
|
||||
}
|
13
programs/games/fara/trunk/mainWnd.h
Normal 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;
|
BIN
programs/games/fara/trunk/mainfish.bmp
Normal file
After Width: | Height: | Size: 74 KiB |
181
programs/games/fara/trunk/mcarray.h
Normal 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;
|
||||
}
|
298
programs/games/fara/trunk/mcsmemm.cpp
Normal 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;
|
||||
}
|
||||
|
BIN
programs/games/fara/trunk/numbers.bmp
Normal file
After Width: | Height: | Size: 7.1 KiB |
361
programs/games/fara/trunk/top10wnd.cpp
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
14
programs/games/fara/trunk/top10wnd.h
Normal 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();
|
||||
|
||||
|
||||
|
735
programs/games/gomoku/trunk/gomoku.asm
Normal 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
|
||||
|
||||
|
3
programs/games/reversi/trunk/Makefile
Normal file
@ -0,0 +1,3 @@
|
||||
OUTFILE = reversi
|
||||
OBJS = reversi.o
|
||||
include $(MENUETDEV)/makefiles/Makefile_for_program
|
619
programs/games/reversi/trunk/reversi.c
Normal 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;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
26
programs/games/rforces/trunk/KosFile.h
Normal 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);
|
||||
};
|
4
programs/games/rforces/trunk/cmp.bat
Normal 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
|
402
programs/games/rforces/trunk/forces_1.1.cpp
Normal 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();
|
||||
}
|
131
programs/games/rforces/trunk/kosFile.cpp
Normal 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;
|
||||
}
|
||||
|
970
programs/games/rforces/trunk/kosSyst.cpp
Normal 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();
|
||||
}
|
||||
|
||||
|
220
programs/games/rforces/trunk/kosSyst.h
Normal 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();
|
329
programs/games/rforces/trunk/mcsmemm.cpp
Normal 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;
|
||||
}
|
||||
|
28
programs/games/rforces/trunk/mcsmemm.h
Normal 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 );
|
||||
|
||||
|
||||
|
95
programs/games/rforces/trunk/mymath.h
Normal 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);
|
||||
}
|