diff --git a/programs/games/flood-it/trunk/compile_eng.bat b/programs/games/flood-it/trunk/compile_eng.bat new file mode 100644 index 000000000..941a7c90a --- /dev/null +++ b/programs/games/flood-it/trunk/compile_eng.bat @@ -0,0 +1,7 @@ +del lang.h-- +echo #define LANG_ENG 1 >lang.h-- +..\C--\C-- flood-it.c +del flood-it! +rename flood-it.com flood-it +..\C--\kpack flood-it +pause \ No newline at end of file diff --git a/programs/games/flood-it/trunk/compile_rus.bat b/programs/games/flood-it/trunk/compile_rus.bat new file mode 100644 index 000000000..04ffcdc4a --- /dev/null +++ b/programs/games/flood-it/trunk/compile_rus.bat @@ -0,0 +1,7 @@ +del lang.h-- +echo #define LANG_RUS 1 >lang.h-- +..\C--\C-- flood-it.c +del flood-it +rename flood-it.com flood-it +..\C--\kpack flood-it +pause \ No newline at end of file diff --git a/programs/games/flood-it/trunk/flood-it.c b/programs/games/flood-it/trunk/flood-it.c new file mode 100644 index 000000000..fed6941d4 --- /dev/null +++ b/programs/games/flood-it/trunk/flood-it.c @@ -0,0 +1,409 @@ +//Leency 06.10.2011, Flood-it! v2.0, GPL + +#include "lib\kolibri.h" +#include "lib\random.h" + +#ifndef AUTOBUILD +#include "lang.h--" +#endif + +system_colors sc; +proc_info Form; +dword stak[100]; //окно помощи + +//уровни сложности +int DIFFICULTY_LEV_PARAMS[]={ 28, 14, 25, //легко + 17, 28, 50}; //тяжело + +//по-умолчанию "легко" +int BLOCK_SIZE = 28; //размер квадратика +int BLOCKS_NUM = 14; //количество квадратиков по Х и по Y +int MAX_CLICKS = 25; //максимальное количество кликов до выигрыша + +int CLICKS = 0; //сколько ходов уже сделал игрок + +#define USER_PANEL_WIDTH 119 + +//шесть цветов используется в игре для квадратиков, седьмой же (последний) для того, +//чтобы отметить квадратики в процессе заливки +dword FIELD_COLORS[]= {0xf18db6, 0x605ca8, 0xfddc80, 0xdc4a20, 0x46b1e2, 0x7e9d1e, 0x232323, 0}; +char *BOARD_SIZES[]={ "S", "L", 0 }; + + +#ifdef LANG_RUS + char *BUTTON_CAPTIONS[]={ " Ќ®ў п [F2]", " Џ®¬®йм [F1]", " ‚л室 [Esc]", 0}; + char CLICKS_TEXT[]=" Љ«ЁЄЁ: /"; + char LEVELS_TEXT[]="Џ®«Ґ:"; + + char HELP_WINDOW_CAPTION[]="Џ®¬®йм"; + char *HELP_TEXT[]={ "Љ Є ЁЈа вм ў® Flood-it?", + "", + "‡ Ї®«­ЁвҐ Ї®«Ґ ®¤­Ё¬ 梥⮬ §  ®Ја ­ЁзҐ­­®Ґ зЁб«® 室®ў.", + "€Ја  ­ зЁ­ Ґвбп б ўҐае­Ґ© «Ґў®© Є«ҐвЄЁ. ‚лЎҐаЁвҐ 梥в, ­ ¦ ў ­  ®¤Ё­ Ё§", + "Єў ¤а вЁЄ®ў б«Ґў , Ё Є«ҐвЄЁ ®Єа бпвбп нвЁ¬ 梥⮬ - в Є ўл ЇаЁб®Ґ¤Ё­ЁвҐ", + "б®бҐ¤­ЁҐ Є«ҐвЄЁ в®© ¦Ґ ®Єа бЄЁ. ‡ еў вЁвм Ї®«Ґ ­г¦­® §  ¬Ё­Ё¬ «м­®Ґ", + "зЁб«® 室®ў. Џ®и Ј®ў п бва вҐЈЁп б Ё­вҐаҐб­л¬ ЇаЁ­жЁЇ®¬ - Ё§¬Ґ­Ёбм,", + "зв®Ўл Ї®ЎҐ¤Ёвм!", 0}; +#else + char *BUTTON_CAPTIONS[]={ "New Game [F2]", "Help [F1]", "Exit [Esc]", 0}; + char CLICKS_TEXT[]="Clicks: /"; + char LEVELS_TEXT[]="Board:"; + + char HELP_WINDOW_CAPTION[]="Help"; + char *HELP_TEXT[]={ "How to play Flood-it?", + "", + "Flood the whole board with one color within the allowed steps.", + "You start from the top left corner and progress by selecting one", + "of the colored balls on the left. When you change your current area", + "color, every adjacent square with the same color also changes, that", + "way you can flood other areas of the board. Select from 3 sizes of", + "the board and try to flood-it in the least amount of steps!", + "Addictive and Fun!", 0}; +#endif + + +int color_matrix[28*28]; //цвета для поля с квадратиками + +int loose_matrix[14*14]={ +2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 2, 3, 2, 2, +2, 3, 2, 2, 2, 3, 2, 3, 2, 2, 2, 3, 2, 2, +2, 3, 2, 2, 2, 3, 2, 3, 2, 3, 2, 3, 2, 2, +2, 3, 2, 2, 2, 3, 2, 3, 2, 3, 2, 3, 2, 2, +2, 3, 2, 2, 2, 3, 2, 3, 2, 3, 2, 3, 2, 2, +2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 2, 3, 2, 2, +2, 3, 2, 2, 2, 3, 2, 3, 2, 3, 2, 3, 2, 2, +2, 3, 2, 2, 2, 3, 2, 3, 2, 3, 2, 3, 2, 2, +2, 3, 2, 2, 2, 3, 2, 3, 2, 3, 2, 3, 2, 2, +2, 3, 2, 2, 2, 3, 2, 3, 2, 3, 2, 3, 3, 2, +2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 +}; + +int win_matrix[14*14]={ +4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, +4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, +4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 4, 1, 4, +4, 1, 4, 1, 4, 1, 4, 4, 4, 1, 4, 4, 1, 4, +4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 1, 4, 1, 4, +4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 1, 4, +4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 4, 1, 4, +4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 4, 1, 4, +4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 4, 1, 4, +4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 4, 1, 4, +4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 4, 1, 4, +4, 4, 1, 4, 1, 4, 4, 1, 4, 1, 4, 4, 1, 4, +4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, +4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, +}; + +void main() +{ + int key, id; + + new_game(); + + loop() + { + switch(WaitEvent()) + { + case evButton: + id = GetButtonID(); + if (id==1) || (id==4) ExitProcess(); + if (id==2) goto _NEW_GAME_MARK; + if (id==3) goto _HELP_MARK; + if (id>=100) + { + if (color_matrix[0]==id-100) break; //если цвет первой фишки такой же, игнорируем бессмысленный ход + if (CLICKS>=MAX_CLICKS) break; //если игра закончена + + CLICKS++; + draw_clicks_num(); + + fill_field(id-100); + draw_field(); + check_for_end(); //если игра закончена + break; + } + if (id>=10) + { + id=id-10*3; + + if (BLOCK_SIZE == DIFFICULTY_LEV_PARAMS[id]) break; //выбран тот же размер + + BLOCK_SIZE = DIFFICULTY_LEV_PARAMS[id]; //размер квадратика + BLOCKS_NUM = DIFFICULTY_LEV_PARAMS[id+1]; //количество квадратиков по Х и по Y + MAX_CLICKS = DIFFICULTY_LEV_PARAMS[id+2]; //максимальное количество кликов до выигрыша + + new_game(); + + MoveSize(-1, -1, BLOCK_SIZE*BLOCKS_NUM +14+USER_PANEL_WIDTH, BLOCK_SIZE*BLOCKS_NUM +GetSkinWidth()+14); + break; + } + break; + case evKey: + key = GetKey(); + if (key==027) //Escape + ExitProcess(); + if (key==050) //F1 + { + _HELP_MARK: + CreateThread(#help,#stak); + } + if (key==051) //F2 + { + _NEW_GAME_MARK: + new_game(); + draw_clicks_num(); + draw_field(); + } + break; + case evReDraw: + draw_window(); + } + } +} + + +void draw_window() +{ + int i, j; + #define BUTTON_SIZE 28 + + sc.get(); + + DefineAndDrawWindow(300,176, BLOCK_SIZE*BLOCKS_NUM +14+USER_PANEL_WIDTH, BLOCK_SIZE*BLOCKS_NUM +GetSkinWidth()+14, 0x74,sc.work,0,0,"Flood-it!"); + + //проверяем не схлопнуто ли окно в заголовок + GetProcessInfo(#Form, SelfInfo); + if (Form.height==GetSkinWidth()+3) return; + + //закрашиваем фон -> уменьшает перерисовку + for (i=0;i<=4;i++) + { + if (i<>4) + DrawRegion(USER_PANEL_WIDTH+i-5,i, BLOCK_SIZE*BLOCKS_NUM +9-i-i, BLOCK_SIZE*BLOCKS_NUM+9-i-i, sc.work); + else + DrawRegion(USER_PANEL_WIDTH+i-5,i, BLOCK_SIZE*BLOCKS_NUM +9-i-i, BLOCK_SIZE*BLOCKS_NUM+9-i-i, sc.work_graph); //ободок + } + DrawBar(0,0, USER_PANEL_WIDTH-5, BLOCK_SIZE*BLOCKS_NUM+10, sc.work); + + //кнопочки заливки + for (i=0;i<2;i++) + for (j=0;j<3;j++) + DefineButton(j*BUTTON_SIZE+17,i*BUTTON_SIZE+15,BUTTON_SIZE,BUTTON_SIZE, i*3+j+100,FIELD_COLORS[i*3+j]); + + //кнопочки действий + for (j=0;j<3;j++) + { + DefineButton(17,j*25+120, 13*6+6, 20, j+2,sc.work_button); + WriteText(17+4,j*25+127,0x80,sc.work_button_text,BUTTON_CAPTIONS[j],0); + } + + //кнопочки выбора уровня сложности + WriteText(17,BLOCKS_NUM*BLOCK_SIZE-20+7,0x80,sc.work_text,#LEVELS_TEXT,0); + for (j=0;j<2;j++) + { + DefineButton(j*25+56,BLOCKS_NUM*BLOCK_SIZE-20, 20,20, j+10,sc.work_button); + + if (BLOCK_SIZE == DIFFICULTY_LEV_PARAMS[j*3]) EDI=0x800080; + else EDI=sc.work_button_text; + + WriteText(j*25+56+8,BLOCKS_NUM*BLOCK_SIZE-20+7,0x80,EDI,BOARD_SIZES[j],0); + WriteText(j*25+56+9,BLOCKS_NUM*BLOCK_SIZE-20+7,0x80,EDI,BOARD_SIZES[j],0); + } + + draw_clicks_num(); + + draw_field(); + +} + + +void new_game() +{ + int i, j; + + //randomize(); + + CLICKS = 0; + + for (i=0;iold_color_id) continue; //если фишка не нужного цвета идём дальше + if (color_matrix[i*BLOCKS_NUM+j]==MARKED) continue; //если фишка уже отмечена, идём далее + + if (j>0) && (color_matrix[i*BLOCKS_NUM+j-1]==MARKED) color_matrix[i*BLOCKS_NUM+j]=MARKED; //смотрим левый + if (i>0) && (color_matrix[i-1*BLOCKS_NUM+j]==MARKED) color_matrix[i*BLOCKS_NUM+j]=MARKED; //смотрим верхний + if (j=MAX_CLICKS) //если проигрыш + { + if (CLICKS==MAX_CLICKS) //выигрышь на последнем ходе + { + for (i=0;icolor_matrix[0]) goto _LOOSE_MARK; + goto _WIN_MARK; + } + + _LOOSE_MARK: + + for (i=0;i<14;i++) + for (j=0;j<14;j++) + { + if (BLOCK_SIZE == DIFFICULTY_LEV_PARAMS[0]) + { + ii=i; + jj=j; + } + else + { + ii=i*2; + jj=j*2; + } + color_matrix[ii*BLOCKS_NUM+jj]=loose_matrix[i*14+j]; + color_matrix[ii+1*BLOCKS_NUM+jj]=loose_matrix[i*14+j]; + color_matrix[ii*BLOCKS_NUM+jj+1]=loose_matrix[i*14+j]; + color_matrix[ii+1*BLOCKS_NUM+jj+1]=loose_matrix[i*14+j]; + draw_field(); + //Pause(5); + } + + return 1; + } + + for (i=0;icolor_matrix[0]) return 0; + + //всё поле одного цвета и фишек меньше MAX_CLICKS -> победа + + _WIN_MARK: + + for (i=0;i<25;i++) + { + new_game(); + draw_field(); + Pause(7); + } + + CLICKS=MAX_CLICKS; + + for (i=0;i<14;i++) + for (j=0;j<14;j++) + { + if (BLOCK_SIZE == DIFFICULTY_LEV_PARAMS[0]) //заливка для полей разного размера разная + { + ii=i; + jj=j; + } + else + { + ii=i*2; + jj=j*2; + } + color_matrix[ii*BLOCKS_NUM+jj]=win_matrix[i*14+j]; + color_matrix[ii+1*BLOCKS_NUM+jj]=win_matrix[i*14+j]; + color_matrix[ii*BLOCKS_NUM+jj+1]=win_matrix[i*14+j]; + color_matrix[ii+1*BLOCKS_NUM+jj+1]=win_matrix[i*14+j]; + draw_field(); + //Pause(5); + } + return 1; +} + + +void draw_clicks_num() +{ + #define TEXT_X 21 + #define TEXT_Y 92 + + DrawBar(8*6+TEXT_X, TEXT_Y, 6*2,9, sc.work); + + WriteText(TEXT_X,TEXT_Y,0x80,sc.work_text,#CLICKS_TEXT,0); + + if (CLICKS<10) EBX=9*6+TEXT_X; + else EBX=8*6+TEXT_X; + + WriteText(EBX,TEXT_Y,0x80,sc.work_text,IntToStr(CLICKS),0); + + WriteText(11*6+TEXT_X,TEXT_Y,0x80,sc.work_text,IntToStr(MAX_CLICKS),0); +} + + +void draw_field() +{ + int i, j; + int color_id; + + for (i=0;i0; i++;) {}; + + DefineAndDrawWindow(500,200,450,i*13+50,0x34,sc.work,0,0,#HELP_WINDOW_CAPTION); + + WriteText(6,12,0x80,sc.work_text,HELP_TEXT[0],0); //это для жирного шрифта + for (i=0; HELP_TEXT[i]<>0; i++;) WriteText(5,i*13+12,0x80,sc.work_text,HELP_TEXT[i],0); + } +} + + +stop: \ No newline at end of file diff --git a/programs/games/flood-it/trunk/lib/kolibri.h b/programs/games/flood-it/trunk/lib/kolibri.h new file mode 100644 index 000000000..9e68ea207 --- /dev/null +++ b/programs/games/flood-it/trunk/lib/kolibri.h @@ -0,0 +1,220 @@ +//CODED by Veliant, Leency, Nable. GNU GPL licence. + +#startaddress 0 +#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 = #0x00010000; +dword x86esp_reg = #0x00010000; +dword I_Param = 0; +dword I_Path = 0; + +//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 + +//------------------------------------------------------------------------- + + +struct proc_info{ + dword use_cpu; + word pos_in_stack,num_slot,rezerv1; + char name[11]; + char rezerv2; + dword adress,use_memory,ID,left,top,width,height; + word status_slot,rezerv3; + dword work_left,work_top,work_width,work_height; + char status_window; + void GetInfo(dword ECX); + byte reserved[1024-71]; +#define SelfInfo -1 +}; + +inline fastcall void GetProcessInfo(dword EBX, ECX) +{ + EAX = 9; + $int 0x40 +} + +struct system_colors{ + dword frame,grab,grab_button,grab_button_text,grab_text,work,work_button,work_button_text,work_text,work_graph; + void get(); +}; + +void system_colors::get() +{ + EAX = 48; + EBX = 3; + ECX = #frame; + EDX = 40; + $int 0x40 +} + +//------------------------------------------------------------------------------ + +inline fastcall dword WaitEvent(){ + EAX = 10; + $int 0x40 +} + + +inline fastcall word GetKey(){ //Gluk fix + EAX = 2; // just read it key from buffer + $int 0x40 + EAX = EAX >> 8; +} + +inline fastcall word GetButtonID(){ + EAX = 17; + $int 0x40 + EAX = EAX >> 8; +} + +inline fastcall ExitProcess(){ + EAX = -1; // close this program + $int 0x40 +} + +inline fastcall Pause(dword EBX) +{ //Џ г§ , ў б®вле ¤®«пе ᥪ㭤л EBX = value + $mov eax, 5 + $int 0x40 +} + +//------------------------------------------------------------------------------ + +char buffer[11]=""; +inline fastcall dword IntToStr(dword ESI) +{ + $mov edi, #buffer + $mov ecx, 10 + $test esi, esi + $jns f1 + $mov al, '-' + $stosb + $neg esi +f1: + $mov eax, esi + $push -'0' +f2: + $xor edx, edx + $div ecx + $push edx + $test eax, eax + $jnz f2 +f3: + $pop eax + $add al, '0' + $stosb + $jnz f3 + $mov eax, #buffer + $ret +} + + +//------------------------------------------------------------------------------ + + +void DefineAndDrawWindow(dword x,y,sizeX,sizeY,byte mainAreaType,dword mainAreaColour,byte headerType,dword headerColour,EDI) +{ + EAX = 12; // function 12:tell os about windowdraw + EBX = 1; + $int 0x40 + + EBX = x << 16 + sizeX; + ECX = y << 16 + sizeY; + EDX = mainAreaType << 24 | mainAreaColour; + ESI = headerType << 24 | headerColour; + $xor eax,eax + $int 0x40 + + EAX = 12; // function 12:tell os about windowdraw + EBX = 2; + $int 0x40 +} + +inline fastcall MoveSize(int EBX,ECX,EDX,ESI) +{ + EAX = 67; + $int 0x40 +} + +inline fastcall dword CreateThread(dword ECX,EDX) +{ + EAX = 51; + EBX = 1; + $int 0x40 +} + +inline fastcall dword GetSkinWidth() +{ + $push ebx + $mov eax, 48 + $mov ebx, 4 + $int 0x40 + $pop ebx +} + +void WriteText(dword x,y,byte fontType, dword color, EDX, ESI) +{ + EAX = 4; + EBX = x<<16+y; + ECX = fontType<<24+color; + $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 +} + +void DrawRegion(dword x,y,width,height,EDX) +{ + DrawBar(x,y,width,1,EDX); + DrawBar(x,y+height,width,1,EDX); + DrawBar(x,y,1,height,EDX); + DrawBar(x+width,y,1,height+1,EDX); +} + +inline fastcall dword WriteDebug(dword EDX) +{ + $push ebx + $push ecx + $mov eax, 63 + $mov ebx, 1 +next_char: + $mov ecx, DSDWORD[edx] + $or cl, cl + $jz done + $int 0x40 + $inc edx + $jmp next_char +done: + $mov cl, 13 + $int 0x40 + $mov cl, 10 + $int 0x40 + $pop ecx + $pop ebx +} \ No newline at end of file diff --git a/programs/games/flood-it/trunk/lib/random.h b/programs/games/flood-it/trunk/lib/random.h new file mode 100644 index 000000000..11b60c117 --- /dev/null +++ b/programs/games/flood-it/trunk/lib/random.h @@ -0,0 +1,52 @@ +/******************************************************************************* + + MenuetOS MineSweeper + Copyright (C) 2003 Ivan Poddubny + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*******************************************************************************/ + +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; +} \ No newline at end of file