/* * mines - Super Mines game for MS-Dos/Win32/SVGAlib/X11 * * mines.c - main game file * ____________________________________________________________ * * Developed by Ondrej Jombik * Copyright (c) 1997-2000 Condy software inc. * Copyright (c) 2001-2004 Platon SDG, http://platon.sk/ * All rights reserved. * * See README file for more information about this software. * See COPYING file for license information. * * Download the latest version from * http://platon.sk/projects/games/ */ /* $Platon: games/mines/mines.c,v 1.22 2004/04/06 09:54:17 nepto Exp $ */ /* LANGUAGE */ #define LANG_ENGLISH_NEW 0 #define LANG_ENGLISH_OLD 1 #define LANG_SLOVAK 2 #define LANG_ENGLISH LANG_ENGLISH_NEW #define LANGUAGE LANG_ENGLISH /* alter this to change language */ #define PSQUARE_DYNAMIC_ALLOCATION (0) #define ASSERTION_USAGE (1) /* CONSTS */ #if LANGUAGE == LANG_SLOVAK # define EXENAME "mines.exe" # define ERR_ARGC "Pr¡lis vela argumentov v pr¡kazovom riadku." # define ERR_EXEC "Nem“zem spustit" # define ERR_BREAK "Chyba v presmerovan¡ Ctrl-Break." /* N/A */ # define ERR_MOUSE "Tento program potrebuje mys." # define ERR_WRITE "Chyba pri z pise. Plny disk?" # define ERR_MEMORY "Nedostatok volnej pam„te." # define ERR_GRAPH "Chyba grafiky:" # define STR_OK "OK" # define STR_YES "Ano" # define STR_NO "Nie" # define STR_RESET "Reset" # define STR_MORE_INFO "viac info" # define STR_PLAYGROUND_WIDTH "S¡rka pola" # define STR_PLAYGROUND_HEIGHT "Vyska pola" # define STR_INFO_TABLE "Info tabulka" # define STR_PAUSE "P A U Z A" # define STR_CLICK_HERE "Klikni sem pre pokracovanie..." # define STR_WELL_DONE "Hotovo!" # define STR_MINES_REPORT "%u m¡n si zlikvidoval(a) na ploche %ux%u za %u:%02u:%02u" # define STR_ENTER_YOUR_NAME "Zadaj svoje meno:" # define STR_BAD_LUCK "Upsss... SMOLA!" # define STR_PLAY_AGAIN "Chces hrat znovu?" # define STR_HELP "Pomoc" # define STR_OTHER_PROGRAMS "In‚ programy" # define STR_SOURCE_EXAMPLE "Uk zka zdrojov‚ho textu" # define STR_SOURCE_EXAMPLE_2 "Uk zka zdrojov‚ho textu z tohto programu" # define STR_BACK "<--sp„t--" # define STR_DIFFICULTY "Obtiaznost" # define STR_END_GAME "Koniec hry?" # define STR_HALL_OF_FAME "Tabulka najleps¡ch" # define STR_HSC_ENTRY "M¡n:%u / Velkost:%ux%u / Cas:%u:%02u:%02u / D tum:%u.%u.%u" # define STR_LONG_OTHER_PROGRAMS "\ < In‚ programyô?õ Niektor‚ sa nach dzaj£\n\ ôOndrej Jomb¡k ml.õ\n\ >ôHol¡cska 26õ \n\ >ô851 01 Bratislavaõ \n" # define STR_LONG_SOURCE_CODE "\ < Tak toto je cast hlavn‚ho ovl dacieho modulu tohto programu,\n\ ôPlaton SDGõ \n\ >ôHlavna 3õ \n\ >ô927 01 Salaõ \n\ >ôSlovakiaõ \n\ >ôEuropeõ \n" # define STR_LONG_SOURCE_CODE "\ =x1&&x<=x2&&y>=y1&&y<=y2) #define isinnormbutton(x,y,xx,yy) (isinbar(x,y,xx-47,yy-1,xx+47,yy+19)) #define isinnumbutton(x,y,xx,yy) \ (isinbar(x,y,xx-47,yy-1,xx-20,yy+19)?(isinbar(x,y,xx-47,yy+13,xx-37,yy+17)?3:1): \ isinbar(x,y,xx+20,yy-1,xx+47,yy+19)?(isinbar(x,y,xx+37,yy+13,xx+47,yy+17)?4:2):0) #define isininfo(x,y) isinbar(x,y,infox,infoy,infox+INFOXSIZE,infoy+INFOYSIZE) #define underinfo(x,y) (isininfo(xoff+x*barsize,yoff+y*barsize) \ ||isininfo(xoff-1+(x+1)*barsize,yoff+y*barsize) \ ||isininfo(xoff-1+(x+1)*barsize,yoff-1+(y+1)*barsize) \ ||isininfo(xoff+x*barsize,yoff-1+(y+1)*barsize)) #define HideInfo() WriteInfo(0xffff,0xffff) #define ShowInfo() WriteInfo(infox,infoy) #if PLATON_SYSTEM_WIN32 || PLATON_SYSTEM_X11 # define FadeIn() (void)kbhit() # define FadeOut() (void)kbhit() #else # define FadeIn() fade_in(FADESTEPS) # define FadeOut() fade_out(FADESTEPS) #endif #define YES 1 #define NO 0 #define MINE 255-'0' /* So that when it prints, it prints char 0xff */ #define getmines(__nx,__ny,__diff) \ (max(1,((WORD)(((long)(__nx)*(long)(__ny)*(long)(DIFFOFFSET+(__diff)*DIFFPOINT))/100)))) /* INCLUDE */ #include #include #include #include #include #if ASSERTION_USAGE # include #endif #include #if PLATON_SYSTEM_SVGALIB || PLATON_SYSTEM_X11 # include # include # define CLOCK_FNC times(NULL) # define CLOCK_DIV sysconf(_SC_CLK_TCK) #endif #if PLATON_SYSTEM_MSDOS || PLATON_SYSTEM_WIN32 # include # include # define CLOCK_FNC clock() # define CLOCK_DIV CLOCKS_PER_SEC #endif #if PLATON_SYSTEM_WIN32 # include # include #endif #if PLATON_SYSTEM_MSDOS # include #endif #include #include #include #include #include /* #include "data.h" FOR MINES IMAGE */ #include "hiscore.h" #if PLATON_SYSTEM_MSDOS || PLATON_SYSTEM_WIN32 # define RAND_INT(__lo, __hi) (__lo + random(__hi - __lo + 1)) #endif #if PLATON_SYSTEM_SVGALIB || PLATON_SYSTEM_X11 # define RAND_INT(__lo, __hi) (__lo + (random() % (__hi - __lo + 1))) #endif typedef struct stsquare { BYTE value; /* Number of mines in the surround squares */ BYTE sqopen; /* Square is open */ BYTE sqpress; /* Square is pressed */ BYTE sqmark; /* Square is marked */ } STSQUARE; enum desktop_operation { DESKTOP_SAVE = 0, DESKTOP_RESTORE = 1 }; /* /////////////////////////////////////////////////////////////////////// */ /* GLOBAL IDENTIFICATORS */ #if PLATON_SYSTEM_MSDOS extern unsigned _stklen = 65000U; #endif #if PSQUARE_DYNAMIC_ALLOCATION STSQUARE *psquare; #else STSQUARE psquare[MAXNX * MAXNY]; #endif /* All unneccessary question marks will be removed. */ #if LANGUAGE == LANG_SLOVAK char infostr1[]="Super Mines v????????? - (c) 1999 Condy software inc.", infostr2[]="Ondrej Jomb¡k - Gymn zium Bil¡kova 24 - Okt va C - 1998/99", *infostr3[]={" "," MINES ",""," x ",""," Cas "," : : ",""," M¡n ","-- --","","EscMenu","F1Pomoc","F4Pauza"}; char*yesnostr[]={"Ano","Nie",NULL}; #else char infostr1[]="Super Mines v????????? by Ondrej Jombik ", infostr2[]="Copyright (c) 2001-2004 Platon SDG, http://platon.sk/", *infostr3[]={" "," MINES ",""," x ",""," Time "," : : ",""," Mines ","-- --","","EscExit","F1Help ","F4Pause"}; char*yesnostr[]={"Yes","No",NULL}; #endif BYTE barsize, /* pixels by square */ diff=DEFDIFF, itabsize=DEFITABSIZE, /* Info Tab Size */ nx=DEFNX, /* Number of squares in X */ ny=DEFNY; void*infosafe=NULL; WORD xoff, /* Offset of first pixel X */ yoff, infox=30,infoy=30, cmines, /* Mines UN-discovered */ sqclosed; /* Squares still closed */ /* GAME ENDS IF cmines==0 AND sqclosed==0 */ char gastxt[]="\ ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ\n\r\ Ý Þ\n\r\ Ý N'=NSvt/6V | p'=-p | p'-p=2p Þ\n\r\ Ý p=N'(p'-p)=2pN'=NSmtvý/3V Þ\n\r\ Ý F=p/t=NSmtvý/3Vt=NSmvý/3V Þ\n\r\ Ý p=F/S=NSmvý/3VS=Nmvý/3V Þ\n\r\ Ý pV=Nmvý/3 | v=û(3kT/m) Þ\n\r\ Ý pV=NkT | n=m/M=N/Nø Þ\n\r\ Ý pV=nkNøT | R=kNø Þ\n\r\ Ý pV=nRT | p'V'=nRT' Þ\n\r\ Ý nR=pV/T=p'V'/T' Þ\n\r\ Ý constðpV/T Þ\n\r\ Ý constðp ÷> izobar_process Þ\n\r\ Ý constðV ÷> izochor_process Þ\n\r\ Ý constðT ÷> izoterm_process Þ\n\r\ Ý (p+a/Vý)(V-b)=RT ÷> Van_der_Waals Þ\n\r\ Ý Þ\n\r\ ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß"; #if ASSERTION_USAGE BYTE value(int x, int y) { assert(x>=0&&y>=0&&xvalue; } BYTE sqopen(int x, int y) { assert(x>=0&&y>=0&&xsqopen; } BYTE sqpress(int x, int y) { assert(x>=0&&y>=0&&xsqpress; } BYTE sqmark(int x, int y) { assert(x>=0&&y>=0&&xsqmark; } void set_value(int x, int y, BYTE a) { assert(x>=0&&y>=0&&xvalue = a; } void set_sqopen(int x, int y, BYTE a) { assert(x>=0&&y>=0&&xsqopen = a; } void set_sqpress(int x, int y, BYTE a) { assert(x>=0&&y>=0&&xsqpress = a; } void set_sqmark(int x, int y, BYTE a) { assert(x>=0&&y>=0&&xsqmark = a; } #else # define value(x, y) ((psquare + (x) * ny + (y))->value ) # define sqopen(x, y) ((psquare + (x) * ny + (y))->sqopen ) # define sqpress(x, y) ((psquare + (x) * ny + (y))->sqpress ) # define sqmark(x, y) ((psquare + (x) * ny + (y))->sqmark ) # define set_value(x, y, a) ((psquare + (x) * ny + (y))->value = a) # define set_sqopen(x, y, a) ((psquare + (x) * ny + (y))->sqopen = a) # define set_sqpress(x, y, a) ((psquare + (x) * ny + (y))->sqpress = a) # define set_sqmark(x, y, a) ((psquare + (x) * ny + (y))->sqmark = a) #endif /* /////////////////////////////////////////////////////////////////////// */ /* FUNCTIONS DECLARATION */ int brkfnc(void); void koniec(void); void WriteError(void); BYTE MainMenu(void); int GraphInit(void); void SetData(void); void SetMines(); void SetExcludeMines(int ex, int ey); void SetSquare(WORD x,WORD y,BYTE status); void WriteInfo(int x, int y); BYTE DoAll(void); void Help(void); void ShowHelpText(WORD x,WORD y,WORD linesize,WORD defcolor,WORD inscolor,char*helpstr); void OpenSquare(WORD x,WORD y); WORD OpenNearSquares(WORD x,WORD y); void DrawDiffButton(WORD x,WORD y,BYTE diff,BYTE label); void DrawDefWindow(WORD sizex,WORD y1,WORD y2,char*text); void DrawWindow(WORD x1,WORD y1,WORD x2,WORD y2,BYTE bckcolor,BYTE rctcolor); void DrawNormButton(WORD x,WORD y,char*label,char*str,BYTE bckcolor,BYTE rctcolor,BYTE txtcolor); void DrawNumButton(WORD x,WORD y,char*label,WORD num,BYTE bckcolor,BYTE rctcolor,BYTE txtcolor); void DrawNumPlus10(WORD x,WORD y,BYTE c); BYTE YesNo(); BYTE ColorConvert(BYTE value); void fade_out(WORD steps); void fade_in(WORD steps); void desktop_save_or_restore(enum desktop_operation op); /* High scores handling */ void HscTable(void); clock_t time2clock(struct time time); /* strplus.h extract */ char *strdel(char *s); /* /////////////////////////////////////////////////////////////////////// */ /* MAIN */ int main(int argc, char **argv) { register WORD k; gotoxy(1,25); textattr(0x07); for (k=0;k<80;k++) putch('_'); /* putch('Ä'); */ putch('\n'); setcbrk(1); ctrlbrk(brkfnc); atexit(koniec); #if 0 #if PLATON_SYSTEM_MSDOS if (argc>1) { puts(ERR_ARGC); return 1; } { char exename[]=EXENAME; if (strcmpi(exename,argv[0]+strlen(argv[0])-strlen(exename))) { printf("\n%s %s\n",ERR_EXEC,strupr(exename)); return 1; } } #endif #endif if (!initmouse()) { puts(ERR_MOUSE); return 1; } #if PLATON_SYSTEM_MSDOS argc = argc; /* just to prevent warning */ hiscore_init(argv[0], HISCORE_AUTODETECT); #elif PLATON_SYSTEM_WIN32 hiscore_init("c:\\windows\\mines.hsc", 0L); #elif PLATON_SYSTEM_SVGALIB || PLATON_SYSTEM_X11 hiscore_init("/var/lib/games/mines/hiscore.dat", 0L); #else # error hiscore not initialized #endif if (GraphInit() < 0) return 1; strncpy(strchr(infostr1,'?'),__APPVERSION__,strlen(__APPVERSION__)); while (strchr(infostr1,'?')!=NULL) strdel(strchr(infostr1,'?')); while (1) { switch (MainMenu()) { case 0: do { SetData(); SetMines(); } while (DoAll()); #if PSQUARE_DYNAMIC_ALLOCATION # if ASSERTION_USAGE assert(psquare != NULL) # endif free(psquare); psquare = NULL; #endif if (infosafe != NULL) { free(infosafe); infosafe = NULL; } break; case 2: HscTable(); break; case 3: Help(); break; case 4: return 0; } } /* never reached */ } /* ////////////////////////////////////////////////////////////////////// */ /* FUNCTIONS DEFINITIONS */ /************************************************************************* * * * F U N C T I O N S * * * *************************************************************************/ int brkfnc(void) /* {{{ */ { gotoxy(1,1); return(1); } /* }}} */ void koniec(void) /* {{{ */ { my_graph_close(); hiscore_close(); fcloseall(); endstring("MINES"); #if (LANGUAGE == LANG_ENGLISH) epilogue(); #else randomize(); switch (RAND_INT(0, 3)) { case 0: textattr(0x03); cputs(gastxt); break; default: textattr(LIGHTMAGENTA);cputs("\n\r e-mail"); textattr(128+LIGHTMAGENTA);cputs(":"); textattr(WHITE); cputs(" Jombik@pobox.sk"); textattr(LIGHTMAGENTA);cputs("\n\r homepage"); textattr(128+LIGHTMAGENTA);cputs(":"); textattr(WHITE); cputs(" http://Jombik.w3.to"); if (!RAND_INT(0, 2)) { textattr(0x02); cputs("\n\n\n\rSo doN'T foRgeT To ViSit ouR inCreDibLe _talker_ "); textattr(WHITE); cputs("telnet://atlantis.sk:7000\n"); } else{ textattr(LIGHTMAGENTA);cputs("\n\r talker"); textattr(128+LIGHTMAGENTA);cputs(":"); textattr(WHITE); cputs(" telnet://atlantis.sk:7000"); } textattr(GREEN);cputs("\n\n\rThis is an "); textattr(LIGHTCYAN);cputs("eXtreme & precizion "); textattr(LIGHTGREEN);cputs("Neptun "); textattr(GREEN);cputs("software production."); textattr(GREEN);cputs("\n\rEspecially thanx 2 "); textattr(LIGHTCYAN);cputs("neverending "); textattr(LIGHTGREEN);cputs("Wolcaan "); textattr(GREEN);cputs("bug reporting."); break; } textattr(0x07);cputs("\n\r"); #endif } /* }}} */ void WriteError(void) /* {{{ */ { my_graph_close(); puts(ERR_WRITE); exit(1); } /* }}} */ /*----------------------------------------------------------------------*/ BYTE MainMenu(void) /* {{{ */ { register BYTE but; WORD x,y; #if (LANGUAGE == LANG_ENGLISH) char*menustr[]={"New game","Settings","Hall of fame","Information","Quit to OS",NULL}; char*itabstr[]={"Normal","High","Very high"}; char*infostr[]={"Systematically analyzed,","psychically transformed", "and as well as programmed by:","Ondrej Jombik"}; #else char*menustr[]={"Nov  Hra","Nastavenie","Tabulka najleps¡ch","Inform cie","Odchod do DOSu",NULL}; char*itabstr[]={"Norm lna","Velk ","Velmi velk "}; char*infostr[]={"Systematicky analyzoval,","psychicky transformoval", "a v konecnom d“sledku naprogramoval:","Ondrej Jomb¡k"}; #endif FadeOut(); hidemouse(); DrawWindow(0,0,getmaxx(),getmaxy(),BLACK,DARKGRAY); DrawWindow(140,50,getmaxx()-140,110,RED,GREEN); setcolor(LIGHTGREEN);settextstyle(0,0,4); outtextxy(getmaxx()/2+2,82,"M I N E S"); DrawWindow(40,410,getmaxx()-40,440,DARKGRAY,LIGHTGRAY); setcolor(WHITE);settextstyle(0,0,1); outtextxy(getmaxx()/2,420,infostr1); outtextxy(getmaxx()/2,432,infostr2); rangex(111,getmaxx()-111); rangey(196,324); DrawDefWindow(420,195,325,NULL); showmouse(); FadeIn(); while (1) { hidemouse(); DrawDefWindow(420,195,325,NULL); showmouse(); switch (but=menu(menustr,getmaxx()/2,205,0,2,24,BLACK,WHITE)) { case 4: /* Quit to DOS */ hidemouse(); DrawDefWindow(420,195,325,menustr[but]); showmouse(); if (menu(yesnostr,getmaxx()/2,256,0,2,25,RED,LIGHTGREEN)) break; case 0: /* Start game */ case 2: /* Hall of fame */ rangex(0,getmaxx()); rangey(0,getmaxy()); FadeOut(); return(but); case 1: hidemouse(); DrawDefWindow( 420, 195, 325, menustr[but]); DrawNumButton( 190, 254, STR_PLAYGROUND_WIDTH, nx, GREEN, BLUE, WHITE); DrawNumButton( 190, 296, STR_PLAYGROUND_HEIGHT, ny, GREEN, BLUE, WHITE); DrawDiffButton(320, 254, diff,1); DrawNormButton(320, 296, STR_INFO_TABLE, itabstr[itabsize], BLUE, ColorConvert(itabsize+2), WHITE); DrawNormButton(450, 254, "", STR_RESET, RED, WHITE, WHITE); DrawNormButton(450, 296, "", STR_OK, RED, WHITE, WHITE); showmouse(); while (!(but=releasebutton(0,&x,&y))||!isinnormbutton(x,y,450,296)) { if (kbhit()) /* catching characters */ getch(); /* in keyboard buffer */ if (but) { if (isinnormbutton(x,y,450,254) != 0) { /* Reset */ hidemouse(); nx = DEFNX; ny = DEFNY; itabsize = DEFITABSIZE; diff = DEFDIFF; DrawNumButton( 190, 254, STR_PLAYGROUND_WIDTH, nx, GREEN, BLUE, WHITE); DrawNumButton( 190, 296, STR_PLAYGROUND_HEIGHT, ny, GREEN, BLUE, WHITE); DrawNormButton(320, 296, STR_INFO_TABLE, itabstr[itabsize], BLUE, ColorConvert(itabsize+2), WHITE); DrawDiffButton(320, 254, diff, 1); showmouse(); } if (isinnormbutton(x,y,320,296) != 0) { /* Info table */ itabsize++; if (itabsize>2) itabsize=0; hidemouse(); DrawNormButton(320, 296, STR_INFO_TABLE, itabstr[itabsize], BLUE, ColorConvert(itabsize + 2), WHITE); showmouse(); } if ((but=isinnormbutton(x,y,320,254))!=0) { diff++; if (diff>3) diff=0; hidemouse(); DrawDiffButton(320,254,diff,1); showmouse(); } if ((but=isinnumbutton(x,y,190,254))!=0&&((but%2&&nx>1)||(!(but%2)&&nx1)||(!(but%2)&&ny= MINBARSIZE; barsize--) if ((barsize*nx<=getmaxx()+1)&&(barsize*ny<=getmaxy()+1)) break; #if PSQUARE_DYNAMIC_ALLOCATION if ((psquare=(STSQUARE *)calloc(nx*ny,sizeof(STSQUARE))) == NULL) { my_graph_close(); puts(ERR_MEMORY); exit(1); } #endif } /* }}} */ /*----------------------------------------------------------------------*/ void SetMines() /* {{{ */ { SetExcludeMines(-1, -1); } /* }}} */ void SetExcludeMines(int ex, int ey) /* {{{ */ { STSQUARE *p; int i, x, y, a, b; randomize(); cmines = getmines(nx, ny, diff); sqclosed = (nx * ny) - cmines; p = psquare; for (i = nx *ny; i >0; i--, p++) p->value = p->sqopen = p->sqpress = p->sqmark = NO; i = getmines(nx, ny, diff); if (nx * ny - i < 1) ex = ey = -1; /* Disable exclusion if no empty field is available */ for (i = i; i > 0; i--) { do { x = RAND_INT(0, nx - 1); y = RAND_INT(0, ny - 1); } while ((x == ex && y == ey) || value(x, y) == MINE); set_value(x, y, MINE); } for (x=nx-1;x>=0;x--) { for (y=ny-1;y>=0;y--) { if (value(x,y)==MINE) continue; a = x - 1; b = y - 1; i = 0; if (a>=0 && b>=0 && a=0 && b>=0 && a=0 && b>=0 && a=0 && b>=0 && a=0 && b>=0 && a=0 && b>=0 && a=0 && b>=0 && a=0 && b>=0 && atextheight(infostr1)) { outtextxy(getmaxx()/2,yoff/2,infostr1); outtextxy(getmaxx()/2,getmaxy()-yoff/2,infostr2); } else if (yoff>textheight(infostr1)/2) { yoff=getmaxy()+1-ny*barsize; outtextxy(getmaxx()/2,yoff/2,infostr1); } for (x=0;x999) { txt[0]=txt[1]; txt[4]=EOS; } cminesold=cmines; if (isininfo(x,y)) hidemouse(); setcolor(I_BCKCOLOR); outtextxy(infox+INFOXSIZE/2,textheight(infostr3[0])/2+infoy+(9*textheight(infostr3[0])),txt); sprintf(txt,"%03u",cmines); setcolor(I_NUMCOLOR); outtextxy(infox+INFOXSIZE/2,textheight(infostr3[0])/2+infoy+(9*textheight(infostr3[0])),txt); if (isininfo(x,y)) showmouse(); } if ((unsigned) (curr / CLOCK_DIV) != (unsigned) (CLOCK_FNC / CLOCK_DIV)) { /* Update Time */ char txt[30] = "Û ÛÛ ÛÛ"; curr = CLOCK_FNC; if (isininfo(x,y)) hidemouse(); setcolor(I_BCKCOLOR); moveto(infox + INFOXSIZE / 2, textheight(infostr3[0]) / 2 + infoy + (6 * textheight(infostr3[0]))); outtext(txt); sprintf(txt,"%u %02u %02u", (unsigned) (((curr - start) / CLOCK_DIV) / 60) / 60, (unsigned) (((curr - start) / CLOCK_DIV) / 60) % 60, (unsigned) ((curr - start) / CLOCK_DIV) % 60); setcolor(I_NUMCOLOR); outtext(txt); if (isininfo(x,y)) showmouse(); } if (but && isininfo(x, y)) { register int diff_x, diff_y; WORD xx, yy; while (! releasebutton(but - 1, (WORD *) &xx, (WORD *) &yy)) if (kbhit()) /* catching characters */ getch(); /* in keyboard buffer */ diff_x = xx - x; diff_y = yy - y; if (diff_x != 0 || diff_y != 0) WriteInfo((int) infox + diff_x, (int) infoy + diff_y); but = 0; } but &= 3; x = (x-xoff) / barsize; y = (y-yoff) / barsize; if (xold==0xffff) { xold=x; yold=y; } if ((x!=xold||y!=yold)) { /* Position change */ if (xold= 0) { for (k = 0; k <= min(items, HISCORE_MAX_ITEMS - 1); k++) { if (k == items) break; if (hiscore_get_item(&item, k) < 0) WriteError(); if (getmines(nx,ny,diff) > getmines(item.nx,item.ny,item.diff)) break; if (getmines(nx,ny,diff) == getmines(item.nx,item.ny,item.diff)) { if (diff > item.diff) break; if (diff == item.diff) { if (curr < time2clock(item.time)) break; } } if (k == HISCORE_MAX_ITEMS - 1) { k = 0xff; break; } } if (k!=0xff) { register BYTE count=0,c; hidemouse(); DrawDefWindow(550, 207, 273, STR_ENTER_YOUR_NAME); memset(item.name,EOS,HISCORE_NAME_LEN+1); while (((c=getch())!=EOL)||(!strlen(item.name))) { setcolor(BLUE);outtextxy(getmaxx()/2,257,item.name); switch (c) { case EOL:break; case NUL:if (getch()!=DELETE)break; case BS:if (count) {count--;item.name[count]=EOS;} break; default:if (c>=0x20&&c<0xff) /* better than isprint(c) */ if (count < HISCORE_NAME_LEN) { item.name[count] = c; count++; } break; } setcolor(k>2?LIGHTCYAN:ColorConvert(4-k));outtextxy(getmaxx()/2,257,item.name); } showmouse(); item.nx = nx; item.ny = ny; item.diff = diff; getdate(&item.date); item.time.ti_hour = (unsigned) ((curr / CLOCK_DIV) / 60) / 60; item.time.ti_min = (unsigned) ((curr / CLOCK_DIV) / 60) % 60; item.time.ti_sec = (unsigned) (curr / CLOCK_DIV) % 60; if (hiscore_set_item(&item, k) < 0) WriteError(); HscTable(); FadeOut(); } } } } return 0; } /* }}} */ /*----------------------------------------------------------------------*/ void Help(void) /* {{{ */ { WORD x,y; do { char helptext[] = STR_LONG_HELP_TEXT; FadeOut(); hidemouse(); cleardevice(); DrawDefWindow(getmaxx()-30,15,getmaxy()-15,STR_HELP); DrawNormButton(getmaxx()/2,getmaxy()-93,"",STR_OK,RED,WHITE,WHITE); DrawNormButton(40+50,getmaxy()-93,STR_OTHER_PROGRAMS,"Pexeso",BLUE,H_DEFCOLOR,H_INSCOLOR); DrawNormButton(40+75,getmaxy()-78,"","ImageEdit",BLUE,H_DEFCOLOR,H_INSCOLOR); DrawNormButton(40+100,getmaxy()-63,"","2D / 3D",BLUE,H_DEFCOLOR,H_INSCOLOR); DrawNormButton(40+125,getmaxy()-48,"","...",BLUE,H_DEFCOLOR,H_INSCOLOR); DrawWindow(getmaxx()/2-49,getmaxy()-48,getmaxx()-40,getmaxy()-33,MAGENTA,LIGHTCYAN); setcolor(WHITE); outtextxy((getmaxx()/2-49+getmaxx()-40)/2,getmaxy()-40, STR_SOURCE_EXAMPLE_2); ShowHelpText(40,70,12,H_DEFCOLOR,H_INSCOLOR,helptext); showmouse(); FadeIn(); while (1) { if (kbhit()) if (getch()==EOL); /* break; */ if (releasebutton(0,&x,&y)) { if (isinnormbutton(x,y,40+50,getmaxy()-93)|| isinnormbutton(x,y,40+75,getmaxy()-78)|| isinnormbutton(x,y,40+100,getmaxy()-63)|| isinnormbutton(x,y,40+125,getmaxy()-48)){ void*safe; static WORD fontcolor=2; char other_programs_txt[] = STR_LONG_OTHER_PROGRAMS; hidemouse(); if ((safe=malloc(imagesize(229,374,getmaxx()-9,getmaxy()-9)))==NULL)exit(1); getimage(229,374,getmaxx()-9,getmaxy()-9,safe); DrawWindow(229,374,getmaxx()-9,getmaxy()-9,BLUE,WHITE); DrawNormButton((getmaxx()+229)/2,getmaxy()-38,"",STR_BACK,GREEN,WHITE,WHITE); ShowHelpText(280, 392, 15, 11 + (fontcolor++) % 3, WHITE, other_programs_txt); showmouse(); while (!(releasebutton(0,&x,&y)) ||!isinnormbutton(x,y,(getmaxx()+229)/2,getmaxy()-38)) if (kbhit()) getch(); hidemouse(); putimage(229, 374, safe, COPY_PUT); showmouse(); #if ASSERTION_USAGE assert(safe != NULL); #endif free(safe); x = y = 0; } if (isinnormbutton(x,y,getmaxx()/2,getmaxy()-93)) { x=y=0xffff; break; } if (isinbar(x,y,getmaxx()/2-49,getmaxy()-48,getmaxx()-40,getmaxy()-33)) { char zdrojtext[] = STR_LONG_SOURCE_CODE; FadeOut(); hidemouse(); DrawDefWindow(getmaxx(),0,getmaxy(),STR_SOURCE_EXAMPLE); DrawNormButton(getmaxx()/2,getmaxy()-31,"",STR_OK,RED,WHITE,WHITE); ShowHelpText(30,52,12,LIGHTGREEN,LIGHTCYAN,zdrojtext); showmouse(); FadeIn(); while (!(releasebutton(0,&x,&y)) ||!isinnormbutton(x,y,getmaxx()/2,getmaxy()-31)) if (kbhit()) getch(); break; } } } } while (x != 0xffff || y != 0xffff); } /* }}} */ /*----------------------------------------------------------------------*/ void ShowHelpText(WORD x,WORD y,WORD linesize,WORD defcolor,WORD inscolor,char*helpstr) /* {{{ */ { register BYTE count=0; register WORD posx; char*tmpbegin,*tmpend = NULL,*endline; settextstyle(0,0,1); while ((endline=strchr(helpstr,'\n'))!=NULL) { *(endline)=EOS; switch (helpstr[0]) { case'<':posx=x;settextjustify(LEFT_TEXT,CENTER_TEXT);strdel(helpstr);break; case'>':posx=getmaxx()-x;settextjustify(RIGHT_TEXT,CENTER_TEXT);strdel(helpstr);break; default:posx=getmaxx()/2;settextjustify(CENTER_TEXT,CENTER_TEXT);break; } if ((tmpbegin=strchr(helpstr,'ô'))!=NULL&&(tmpbegintmpend))*(helpstr)=SPC; helpstr++; } setcolor(inscolor); outtextxy(posx,y+count*linesize,tmpstr); } helpstr=endline+1; count++; } settextjustify(CENTER_TEXT,CENTER_TEXT); } /* }}} */ /*----------------------------------------------------------------------*/ /* !!! mouse must be turned off when entering function */ void OpenSquare(WORD x, WORD y) /* {{{ */ { char num[2]="0"; register int a,b; settextstyle(0,0,1); set_sqopen(x, y, YES); sqclosed--; if ((num[0]=value(x,y)) != 0) { setcolor(ColorConvert(num[0])); num[0]+='0'; outtextxy(barsize/2+min(getmaxx()-textwidth(num),xoff+barsize*x), 1+barsize/2+min(getmaxy()-textheight(num),yoff+barsize*y),num); } else{ /* Open near squares if the current number is 0 */ a=x-1; b=y-1; if (a>=0 && b>=0 && a=0 && b>=0 && a=0 && b>=0 && a=0 && b>=0 && a=0 && b>=0 && a=0 && b>=0 && a=0 && b>=0 && a=0 && b>=0 && a=0 && b>=0 && a=0 && b>=0 && a=0 && b>=0 && a=0 && b>=0 && a=0 && b>=0 && a=0 && b>=0 && a=0 && b>=0 && a=0 && b>=0 && a=0 && b>=0 && a=0 && b>=0 && a=0 && b>=0 && a=0 && b>=0 && a=0 && b>=0 && a=0 && b>=0 && a=0 && b>=0 && a=0 && b>=0 && asize; struct palettetype curr_pal; curr_pal.size = size; for (l = 0; l < steps; l++) { for (k = 0; k < size; k++) { curr_pal.colors[k] = getdefaultpalette()->colors[k] * (l + 1) / steps; } setallpalette(&curr_pal); } } /* }}} */ void desktop_save_or_restore(enum desktop_operation op) /* {{{ */ { static void *buffer = NULL; static FILE *fhandle = NULL; static int bufsize = 0; static int y_size = 0; register int i; if (op == DESKTOP_SAVE) { if (buffer != NULL) { free(buffer); buffer = NULL; } if (fhandle != NULL) { fclose(fhandle); fhandle = NULL; } for (y_size = getmaxy() + 1; ; y_size = (y_size / 2) + 1) { bufsize = imagesize(0, 0, getmaxx(), y_size - 1); if ((buffer = malloc(bufsize)) != NULL) break; #if PLATON_SYSTEM_X11 /* Desktop save/restore disk swapping/storage mechanism does not properly work with X11 pixmaps due to known issues (see notes nead getimage()/putimage in x11-bgi.c file). Thus if we failed to allocate 8 bytes size buffer, we exit immidiatelly. */ WriteError(); #endif } if (y_size <= getmaxy()) { if ((fhandle = tmpfile()) == NULL) WriteError(); } for (i = 0; i <= getmaxy(); i += y_size) { #if 0 fprintf(stderr, "getimage(0, %d, %d, %d, %p);\n", i, getmaxx(), min(getmaxy(), i + y_size - 1), buffer); #endif getimage(0, i, getmaxx(), min(getmaxy(), i + y_size - 1), buffer); if (i + y_size < getmaxy()) { if (fwrite(buffer, bufsize, 1, fhandle) != 1) WriteError(); } } } else if (op == DESKTOP_RESTORE) { if (fhandle != NULL) rewind(fhandle); for (i = 0; i < getmaxy() + 1 - y_size; i += y_size) ; #if 0 fprintf(stderr, "putimage(0, %d, %p, COPY_PUT);\n", i, buffer); #endif putimage(0, i, buffer, COPY_PUT); for (i -= y_size; i >= 0; i -= y_size) { if (fread(buffer, bufsize, 1, fhandle) != 1) WriteError(); putimage(0, i, buffer, COPY_PUT); } if (buffer != NULL) { free(buffer); buffer = NULL; } if (fhandle != NULL) { fclose(fhandle); fhandle = NULL; } } } /* }}} */ /* /////////////////////////////////////////////// */ void HscTable(void) /* {{{ */ { register BYTE k,l; WORD x,y; HISCORE_ITEM item; char s[80]; hidemouse(); DrawDefWindow(getmaxx(), 0, getmaxy(), STR_HALL_OF_FAME); for (k=0;k2?LIGHTCYAN:ColorConvert(4-k)); outtextxy(10,47+k*40,s); /* STATUS */ settextstyle(0,0,1); sprintf(s, STR_HSC_ENTRY, getmines(item.nx,item.ny,item.diff),item.nx,item.ny, item.time.ti_hour,item.time.ti_min,item.time.ti_sec, item.date.da_day,item.date.da_mon,item.date.da_year); setcolor(k>2?LIGHTCYAN:ColorConvert(4-k)); outtextxy(75,66+k*40,s); for (l=0; s[l]!=EOS; l++) if (!isdigit(s[l])) s[l]=SPC; setcolor(WHITE); outtextxy(75,66+k*40,s); /* DIFF ICON */ settextjustify(CENTER_TEXT,CENTER_TEXT); DrawDiffButton(566,51+k*40,item.diff,k?0:1); } DrawNormButton(getmaxx() / 2, getmaxy() - 31, "", STR_OK, RED, WHITE, WHITE); showmouse(); FadeIn(); while (!(releasebutton(0,&x,&y)) ||!isinnormbutton(x,y,getmaxx()/2,getmaxy()-31)) if (kbhit()) getch(); } /* }}} */ clock_t time2clock(struct time time) /* {{{ */ { return CLOCK_DIV * (long)((long)time.ti_sec+(long)time.ti_min*60+(long)time.ti_hour*3600); } /* }}} */ /* strplus.c extract */ char * strdel(char *s) /* {{{ */ { #if 1 return (char *) memmove(s, s + 1, strlen(s)); #else register int i; for (i = 0; s[i] != '\0'; i++) s[i] = s[i + 1]; return s; #endif } /* }}} */ /* Modeline for ViM {{{ * vim: set ts=4: * vim600: fdm=marker fdl=0 fdc=0: * }}} */