// This may look like C code, but it is really -*- C++ -*- /////////////////////////////////////////////////////////////////////////// // // AMIGA Minesweeper - The event-driven game-loop // // (c) 1992 Hubert Feyrer (c9020@rrzc1.rz.uni-regensburg.de) // /////////////////////////////////////////////////////////////////////////// /* ** Diverse "C"-Header */ #define class _class #define template _template #define IntuitionBase IntuiBase #define GfxBase GraphBase extern "C" { # include # include # include # include # include # include # include # include # include # include # include # include # include # include # include } #undef IntuitionBase #undef GfxBase #undef class #undef template /* ** C++-Header */ #include "mine.h" #include "field.h" void CancelIO(int idle) { if(!idle){ AbortIO(&treq.tr_node); WaitIO(&treq.tr_node); } } //* //* Hauptschleife - das Game an sich und als solches //* GameStat play(int idle) { IntuiMessage *imsg; int firstgame_over=1; // Game Over beim ersten Versuch => nochmal! int first_touch=1; // Timer beim ersten Touch starten if(idle){ OnGadget(gogad,win,NULL); win->Flags &= ~WFLG_RMBTRAP; }else{ SetWindowTitles(win,WIN_T,-1); OffGadget(gogad,win,NULL); win->Flags |= WFLG_RMBTRAP; } GT_RefreshWindow(win,NULL); for(;;){ int isig=1<UserPort->mp_SigBit; // Intuition-Signal-Bit int tsig=1<mp_SigBit; // Timer-Device-Signalbit int sig=Wait( isig|tsig ); if(!idle && (sig & tsig)){ GetMsg(tport); // Timer sofort wieder starten treq.tr_time.tv_secs=1; treq.tr_time.tv_micro=0; SendIO(&treq.tr_node); playtime++; sprintf(ttimegad,"%04d",playtime); GT_SetGadgetAttrs(timegad,win,NULL, GTTX_Text,ttimegad, TAG_END); RefreshGList(timegad,win,NULL,1); } if(sig & isig){ // Message von Intuition while(( imsg=(IntuiMessage *)GT_GetIMsg(win->UserPort) )!=NULL){ switch(imsg->Class){ case IDCMP_CLOSEWINDOW: GT_ReplyIMsg(imsg); if(!first_touch) CancelIO(idle); return GAME_QUIT; case IDCMP_GADGETUP: Gadget *gad = (Gadget *)imsg->IAddress; if(gad==gogad){ CancelIO(idle); return GAME_RESTART; } if(!idle){ if(first_touch){ SendIO(&treq.tr_node); // Timer starten! first_touch=0; } //* //* Gadget kann direkt bestimmt werden. //* Field *f=(Field *)gad->UserData; switch(f->check()){ case GAME_WON: CancelIO(idle); return GAME_WON; case GAME_LOST: { if(firstgame_over){ // Ersatzmine legen int x,y; int i=f->i(); int j=f->j(); for(;;){ x=rnd(lenx); y=rnd(leny); if((x==i && y==j) || minefield[x][y]->cnt()==-1) continue; else break; } f->cnt(0); minefield[x][y]->cnt(-1); calc_cnt(); f->check(); }else{ f->open(); CancelIO(idle); return GAME_LOST; } } break; } firstgame_over=0; } break; case IDCMP_MOUSEBUTTONS: if(!idle){ if(imsg->Code==MENUUP){ //* //* Gadget muß aus Maus-Position ermittelt werden. //* int x=imsg->MouseX; int y=imsg->MouseY; if(x>=X0 && y>=Y0){ int i=(x-X0)/fxs; int j=(y-Y0)/fys; if(inminefield(i,j)){ if(first_touch){ SendIO(&treq.tr_node); // Timer starten! first_touch=0; } if(minefield[i][j]->mark()==GAME_WON){ CancelIO(idle); return GAME_WON; } } } } } break; } GT_ReplyIMsg(imsg); } } } /*NOTREACHED*/ }