Exemplo n.º 1
0
/****************************************************************************
 * TogglePause								    *
 *  - Toggles pause status for game					    *
 *    Easiest method is to simply disable/enable the timer.		    *
 *  - If bCheck is TRUE, returns the current bPaused value, else toggles    *
 ****************************************************************************/
BOOL TogglePause(INT iOption)
{
    static BOOL bSPause, bSuspended = FALSE;
    static BOOL bPaused = TRUE; 	   /* Game pause toggle 	   */

    if (iOption == CHECK)
	return(bPaused);

    else if (iOption == SUSPEND_ON) {
	if (bSuspended) return(TRUE);
	bSuspended = TRUE;
	bSPause = bPaused;
	if (bPaused)
	    return(TRUE);
	}
    else if (iOption == SUSPEND_OFF) {
	if (!bSuspended) return(FALSE);
	bSuspended = FALSE;
	if (bSPause)
	    return(TRUE);
	else
	    bPaused = TRUE;
	}

    else if (iOption == FORCE_PAUSE)
	if (bPaused) return(TRUE);
	else bPaused = FALSE;
    else if (iOption == FORCE_UNPAUSE)
	if (!bPaused) return(FALSE);
	else bPaused = TRUE;


    if (bSuspended)
	CheckMenuItem(hwndMenu, IDM_PAUSE, bSPause);
    else
	CheckMenuItem(hwndMenu, IDM_PAUSE, !bPaused);

    if (bPaused = !bPaused) {
	WinStopTimer(hab, hwndClient, ID_TIMER);
        
	/* Show the pointer if it is currently hidden */
        ShowMouse(TRUE);
        
	return(TRUE);
	}
    else {
	WinStartTimer(hab, hwndClient, ID_TIMER, iTickLen);
        
	/* Hide the pointer if mouse controls are enabled */
	ShowMouse(FALSE);
    
	return(FALSE);
	}
}
Exemplo n.º 2
0
int   main(int argc,char *argv[])
{
   FILE  *f;
   if(argc>=2)
   {
      f=fopen(argv[1],"r");
      if(f==NULL)
      {
         perror(argv[1]);
         return(1);
      }
      Load(f);
      fclose(f);
   }
   else
   {
      f=fopen("field.lif","r");
      if(f!=NULL)
      {
         Load(f);
         fclose(f);
      }
   }

   OpenInterface();
   OwInitialize(root_pal);
   ShowMouse(TRUE);
   SetEventMask(KEYBOARD_EVENTS|MOUSE_EVENTS);
   OwCreate(&StatusWin,0,DOWN,1,1,status_pal);
   OwCreate(&ReadLine,MIDDLE,MIDDLE+5,60,4,readline_pal);
   Life();
   OwExit();
   CloseInterface();
   return(0);
}
Exemplo n.º 3
0
void CMouseHandler::ToggleState(bool shift)
{
	if(!shift){
		if(locked){
			locked=false;
			ShowMouse();
		} else {
			locked=true;
			HideMouse();
		}
	} else {
		CameraTransition(1.0f);

		CCameraController* oldc=currentCamController;
		currentCamControllerNum++;
		if(currentCamControllerNum>=camControllers.size())
			currentCamControllerNum=0;
		int a=0;
		while(a<4 && !camControllers[currentCamControllerNum]->enabled){
			currentCamControllerNum++;
			if(currentCamControllerNum>=camControllers.size())
				currentCamControllerNum=0;
			a++;
		}
		currentCamController=camControllers[currentCamControllerNum];
		currentCamController->SetPos(oldc->SwitchFrom());
		currentCamController->SwitchTo();
	}
}
Exemplo n.º 4
0
void CMouseHandler::ToggleState()
{
	if (locked) {
		locked = false;
		ShowMouse();
	} else {
		locked = true;
		HideMouse();
	}
}
Exemplo n.º 5
0
void CMouseHandler::ToggleMiddleClickScroll()
{
	if (locked) {
		locked = false;
		ShowMouse();
	} else {
		locked = true;
		HideMouse();
	}
}
Exemplo n.º 6
0
/*
     Unhides the mouse.
*/
void UnLockMouse()
{
    LockCounter--;

    if (LockCounter == 0)
    {
       ShowMouse();
       MouseGotoXY(LockedX, LockedY);

       MouseWindow(1, 1, 80, 25);
    }
}
Exemplo n.º 7
0
CMouse::CMouse(const char* path)
{
	char filename[STD_BUF];
	iCount = 0;

    ShowMouse(false);
    Center();

	for (int i=0; i < MAX_MPOINTS; i++)
	{
		snprintf(filename, STD_BUF, "%s/mpoint%02d.png", path, i);
		Point[i] = new CImage(filename, true);
	}
}
Exemplo n.º 8
0
void GUI_Show(int id)
{
  GUI_BaseMenu* o = GUI_Find(id);
  if (o) 
  {  
    o->Hide();
    o->Default();
    o->Show();
    blocked_inputs = 1;
    ShowMouse();
  }
  GUI_menu = o;
  GUI_id = id;
}
Exemplo n.º 9
0
void NPCDialogWindow(NPC *npc,int id)
{
  int c = 0;
  HUDInfo *self;
  self = Pushwindow();
  if(self == NULL)
  {
    fprintf(stdout,"Big problem here, can't make NPC Dialog window.\n");
    return;
  }
  self->state = id;
  self->stealinput = 1;
  self->windowupdate = UpdateNPCDialogWindow;
  self->windowdraw = DrawNPCDialogWindow;
  self->box.w = Camera.w/3;
  self->box.x = Camera.w/2 - self->box.w/2;
  self->box.y = Camera.h * 0.2;
  self->ib = (void *)npc;
  /*Talk Option, if available*/
  if(GetDialogCount(npc))
  {
    c++;
    PicButton(self,1,SDLK_1,"Talk",self->box.x + self->box.w/2  - (BUTTON_W/2),self->box.y + (BUTTON_H + 4)*c,BUTTON_W,BUTTON_H);
  }
  /*Shop Option, if Available*/
  if(GetShopCount(npc))
  {
    c++;
    PicButton(self,2,SDLK_2,"Shop",self->box.x + self->box.w/2  - (BUTTON_W/2),self->box.y + (BUTTON_H + 4)*c,BUTTON_W,BUTTON_H);
  }
  /*Quests Option, if Available*/
  if(GetQuestCount(npc))
  {
    c++;
    PicButton(self,3,SDLK_3,"Quests",self->box.x + self->box.w/2  - (BUTTON_W/2),self->box.y + (BUTTON_H + 4)*c,BUTTON_W,BUTTON_H);
  }
  if(c == 0)
  {
    PopWindow(self->Handle);
    return;
  }
  self->box.h = (BUTTON_H + 4)*(c + 2);
  PicButton(self,0,SDLK_RETURN,"Done",self->box.x + self->box.w/2  - (BUTTON_W/2),self->box.y + self->box.h - BUTTON_H - 4,BUTTON_W,BUTTON_H);
  Pausing++;
  ShowMouse();
}
Exemplo n.º 10
0
void vertex_fill(Vertex *v)
{
	char str[5];
	HideMouse();
	setcolor(YELLOW);  //set the current drawing jor
	setfillstyle(SOLID_FILL,YELLOW);  //set jor to fill in some object
	fillellipse(v->x,v->y,20,20);
	setcolor(MAGENTA);
	outtextxy(v->x-3,v->y-12,v->name);

	setcolor(RED);
     //		setcolor(BLINK);
	sprintf(str,"[%d]",v->number);

	outtextxy(v->x-14,v->y-3,str);

	ShowMouse();
}
Exemplo n.º 11
0
void GetVertices()      //initially take input in form of vertex
{
	char name_v='A';
	vcount=0;

	setcolor(WHITE);
	outtextxy(50,250,"MINIMUM COST SPANNING TREE...(PRESS ENTER TO CONTINUE)") ;
       getch();

       cleardevice;
	setcolor(BLACK);
		outtextxy(50,250,"MINIMUM COST SPANNING TREE...(PRESS ENTER TO CONTINUE)") ;
	setcolor(LIGHTGREEN);
	outtextxy(4,1,"Click with mouse and press enter to add vertex");
       outtextxy(4,10,"Press 1 if creation of vertices are done");
	 InitMouse();
	ShowMouse();

	do
      //	      while(!kbhit())
	{
	   if(IsClick())
		{
			sprintf(vert[vcount].name,"%c",name_v++);
			vert[vcount].x=o.x.cx;
			vert[vcount].y=o.x.dx;
			vert[vcount].i=vcount;
			vert[vcount].number=vcount+1;
			vertex_fill(&vert[vcount],YELLOW);
			vcount++;
		   //	getch();

	    //   if(kbhit())
	      //	     break;
		       if(getch()=='1')
			break;
			}
	}while(vcount<MAX_VERT); //TOTAL VERTEX

	HideMouse();
}
Exemplo n.º 12
0
void ControlsWindow()
{
  HUDInfo *self;
  self = Pushwindow();
  if(self == NULL)
  {
    fprintf(stderr,"Big problem here, can't make Config window.\n");
    return;
  }
  Pause();
  self->stealinput = 1;
  self->windowupdate = UpdateControlsWindow;
  self->windowdraw = DrawControlsWindow;
  self->box.w = Camera.w*0.75;
  self->box.h = Camera.h*0.71;
  self->box.x = Camera.w/2 - self->box.w/2;
  self->box.y = Camera.h * 0.06;
  self->state = 0;
  ShowMouse();
  PicButton(self,0,SDLK_RETURN,"Done",self->box.x + self->box.w - (GetButtonW() + 4),self->box.y + self->box.h - GetButtonH() - 4,GetButtonW(),GetButtonH());
}
Exemplo n.º 13
0
		void SetMode(Mode mode, Window &w)
		{
			if(mouseMode != mode)
			{
				mouseMode = mode;
				if(mode == Captured)
				{
					GetCursorPos(&mouseSavedPos);
					HideMouse();
					oldMousePos = Mouse::Position;
					Mouse::Update(w);
					Mouse::Delta = Vec2f(0, 0);
				}
				else
				{
					SetCursorPos(mouseSavedPos.x, mouseSavedPos.y);
					Mouse::Position = oldMousePos;
					ShowMouse();
				}
			}
		}
Exemplo n.º 14
0
		void Update(Window &w)
		{
			Point2D p;
			GetCursorPos(&p);
			ScreenToClient(w.Handle(), &p);

			if(w.IsActive() && GetMode() == Mode::Captured)
			{
				HideMouse();
				Point2D c(w.ClientRect().HalfSize());
				Mouse::Delta = Vec2f((float)p.x - c.x, (float)p.y - c.y);
				Position += Mouse::Delta;
				ClientToScreen(w.Handle(), &c);
				SetCursorPos(c.x, c.y);
			}
			else
			{
				Position = p;
				ShowMouse();
			}
		}
Exemplo n.º 15
0
void GUI_OpenMenu(int id)
{
  if (GUI_menu) GUI_menu->Hide();
  
  GUI_BaseMenu* xnew = GUI_Find(id);
  if (xnew) 
  {
    xnew->Hide();
    xnew->Default();
    xnew->Show();
    blocked_inputs = 1;
    ShowMouse();
    xnew->parentmid = GUI_id;
    smPlaySample(SM_MENU1, menu_volume);

    // message refresh hack
    int x, y;
    SDL_GetMouseState(&x, &y);
    SDL_WarpMouse(x,y);
  }
  GUI_id = id;
  GUI_menu = xnew;
}
Exemplo n.º 16
0
void CMouseHandler::ToggleState(bool shift)
{
	if(!shift){
		if(locked){
			locked=false;
			ShowMouse();
		} else {
			locked=true;
			HideMouse();
		}
	} else {
		inStateTransit=true;
		transitSpeed=1;

		CCameraController* oldc=currentCamController;
		currentCamControllerNum++;
		if(currentCamControllerNum>=camControllers.size())
			currentCamControllerNum=0;
		currentCamController=camControllers[currentCamControllerNum];
		currentCamController->SetPos(oldc->SwitchFrom());
		currentCamController->SwitchTo();
	}
}
Exemplo n.º 17
0
		void OnActivate(bool active, Window &w)
		{
			if(active)
			{
				if(GetMode() == Mode::Captured)
				{
					GetCursorPos(&mouseSavedPos);
					HideMouse();
					SetCapture(w.Handle());
					Point2D p = (Point2D)w.ClientSize() / 2;
					ClientToScreen(w.Handle(), &p);
					SetCursorPos(p.x, p.y);
				}
			}
			else
			{
				ReleaseCapture();
				ShowMouse();
				if(GetMode() == Mode::Captured)
				{
					SetCursorPos(mouseSavedPos.x, mouseSavedPos.y);
				}
			}
		}
Exemplo n.º 18
0
/****************************************************************************
 * DoCommand								    *
 *  - Handles WM_COMMAND messages for client window.			    *
 *  - Standard client window I/O                                            *
 ****************************************************************************/
VOID DoCommand(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
{
    switch (SHORT1FROMMP(mp1)) {
      case IDM_START1: case IDM_START2:
	/* Start a new 1 or 2 player game. */
        if (iGameMode == GAME_MODE_INIT1 || iGameMode == GAME_MODE_INIT2) {
            TogglePause(FORCE_UNPAUSE);
	    StartGame(SHORT1FROMMP(mp1)-IDM_START);
        }
	break;

      case IDM_PAUSE:
	/* Toggle pause state. */
	TogglePause(TOGGLE);
	break;

      case IDM_STOP:
	/* End game, but don't exit */
	WinPostMsg(hwnd, WM_INITGAME, (MPARAM) 0L, MPVOID);
	break;

      case IDM_3SHIPS: case IDM_4SHIPS: case IDM_5SHIPS:
	/* Select 3, 4, or 5 ships */
	CheckMenuItem(hwndMenu, IDM_SHIPS+prfProfile.iSHIPS, FALSE);
	prfProfile.iSHIPS = SHORT1FROMMP(mp1) - IDM_SHIPS;
	CheckMenuItem(hwndMenu, IDM_SHIPS+prfProfile.iSHIPS, TRUE);
	break;

      case IDM_3PHOTONS: case IDM_4PHOTONS:
      case IDM_6PHOTONS: case IDM_8PHOTONS:
	/* Select 3, 4, 6, or 8 photons */
	CheckMenuItem(hwndMenu, IDM_PHOTONS+prfProfile.iPHOTONS, FALSE);
	prfProfile.iPHOTONS = SHORT1FROMMP(mp1) - IDM_PHOTONS;
	CheckMenuItem(hwndMenu, IDM_PHOTONS+prfProfile.iPHOTONS, TRUE);
	break;

      case IDM_RAPIDFIRE:
	/* Select rapidfire option */
	if (prfProfile.bRAPIDFIRE = !prfProfile.bRAPIDFIRE) {
	    CheckMenuItem(hwndMenu, IDM_RAPIDFIRE, TRUE);
	    EnableMenuItem(hwndMenu, IDM_FIRERATE, TRUE);
	    }
	else {
	    CheckMenuItem(hwndMenu, IDM_RAPIDFIRE, FALSE);
	    EnableMenuItem(hwndMenu, IDM_FIRERATE, FALSE);
	    }
	break;

      case IDM_SLOWRATE: case IDM_MEDRATE: case IDM_FASTRATE:
	CheckMenuItem(hwndMenu, IDM_FIRERATE+prfProfile.iFIRERATE, FALSE);
	prfProfile.iFIRERATE = SHORT1FROMMP(mp1) - IDM_FIRERATE;
	CheckMenuItem(hwndMenu, SHORT1FROMMP(mp1), TRUE);
	break;

      case IDM_SHIELD:
	/* Select shield option */
	if (prfProfile.bSHIELD = !prfProfile.bSHIELD)
	    CheckMenuItem(hwndMenu, IDM_SHIELD, TRUE);
	else
	    CheckMenuItem(hwndMenu, IDM_SHIELD, FALSE);
	break;

      case IDM_MOUSE:
      	/* Allow mouse input for ship control */
        if (prfProfile.bMOUSECONTROL = !prfProfile.bMOUSECONTROL) {
	    /* Hide the pointer if playing a game */
            ShowMouse(FALSE);
            CheckMenuItem(hwndMenu, IDM_MOUSE, TRUE);
        } else {
	    /* Show the pointer if it is currently hidden */
            ShowMouse(TRUE);
            CheckMenuItem(hwndMenu, IDM_MOUSE, FALSE);
        }
        break;
        
      case IDM_KEYS:
	/* Pop up key definition dialog box */
	WinDlgBox(HWND_DESKTOP, hwnd, (PFNWP)KeyDlgProc, NULLHANDLE, IDD_KEY,
        	  NULL);
	break;

      case IDM_FRAME:
	/* This case does not come from the menu, but instead from the	*
	 * accelerator table.						*/
	if (prfProfile.bCONTROLS = !prfProfile.bCONTROLS)
	    ShowFrameControls();
	else
	    HideFrameControls();
	break;

      case IDM_BACKGRND:
	CheckMenuItem(hwndMenu, IDM_BACKGRND,
	    prfProfile.bBACKGRND = !prfProfile.bBACKGRND);
	break;


      case IDM_HELPFORHELP:
	WinSendMsg(hwndHelp, HM_DISPLAY_HELP, MPVOID, MPVOID);
	break;

      case IDM_EXTENDEDHELP:
	WinSendMsg(hwndHelp, HM_EXT_HELP, MPVOID, MPVOID);
	break;

      case IDM_KEYSHELP:
	WinSendMsg(hwndHelp, HM_KEYS_HELP, MPVOID, MPVOID);
	break;

      case IDM_HELPINDEX:
	WinSendMsg(hwndHelp, HM_HELP_INDEX, MPVOID, MPVOID);
	break;

      case IDM_EXIT:
	/* On cancel, tell application to terminate */
	WinPostMsg(hwndFrame, WM_QUIT, MPVOID, MPVOID);
	break;

      case IDM_ABOUT:
	/* Pop up about dialog box */
	WinDlgBox(HWND_DESKTOP, hwnd, (PFNWP)AboutDlgProc, NULLHANDLE,
		  IDD_ABOUT, NULL);
	break;
      }
}
Exemplo n.º 19
0
void GetEdges()   //take weight from user
{        getch();
    //  cleardevice;
	setcolor(BROWN);
	outtextxy(4,1,"Point with mouse and press enter to add vertex");
       outtextxy(4,10,"Press 1 if creation of vertices are done");
	int i,j,p,q,p1,q1;
	int first_v,second_v,flag1,flag2;
  int count1=0,temp1=0;
  // flag1=flag2=0;
	for(i=0;i<vcount;i++)
		for(j=0;j<vcount;j++)
		{
			adj[i][j]=MAX_NUM;
			extra[i][j]=0;
		}
     InitMouse();
	ShowMouse();
		setcolor(LIGHTGREEN);

	outtextxy(10,20,"Create edges");
	outtextxy(4,30,"Presss right mouse click to select first vertex");
       outtextxy(4,40,"Press left mouse click to select other vertex.");
       outtextxy(4,50,"Press any keyboard key when done ");

 while(!kbhit())
{   flag1=flag2=0;
   if(IsClick())
      {if(count1==0&&o.x.bx==2&&temp1==0) //right button is clicked
	{
	    p=o.x.cx;
	    q=o.x.dx;
	    count1=1;
	    o.x.bx=0;
	    temp1=1;
		for(int i=0;i<vcount;i++)
	     {
	       if((dist(vert[i].x,vert[i].y,p,q))<=20&& flag1==0)
	       {    first_v=i;
			 vertex_fill(&vert[first_v],WHITE);
		  //break;
		  flag1=1;
		}
	     }
	  }
	    }
	  //  getch();

	  if(IsClick())
     { if(o.x.bx==1&&count1==1&&temp1==1)
      {
       count1=0;
       p1=o.x.cx;
       q1=o.x.dx;
       temp1=0;


		 for(int j=0;j<vcount;j++)
		 {
		    if(dist(vert[j].x,vert[j].y,p1,q1)<=20&& flag2==0 && j!=first_v)
		    {       second_v=j;
				 vertex_fill(&vert[second_v],WHITE);
				 flag2=1;

		     Edge_fill(&vert[first_v],&vert[second_v],RED,FALSE);
		     adj[first_v][second_v]=adj[second_v][first_v]=-1;
		      //	break;
		    }
		 }
      }
     }


	   }


 }
Exemplo n.º 20
0
//////////////////////////////////////////////////////////////////////////////
//                         Program Entry Point
int main(int argc, char **argv)
{
    int argNumCells;

    (void) randomize();

    if (argc == 2) {
        // Grab argument, convert to integer; init cells with passed arg.
        argNumCells = (int)atoi((char*)argv[1]);
        (void) initializeCells(argNumCells);

        // Display message, showing # of init'ed cells.
        printf("[Game of Life:] Initialized %d Cells.", argNumCells);

        // Wait a second.
        delay(1000);
    }
    // No arguments were passed? Initialize Default # of cells.
    else {
        (void) initializeCells(INIT_CELLS);
        delay(1000);
    }

    // Initialize 0x13H Graphics Mode, 320x200x256
    (void) initgraph();

    // Display program message, copyright etc.
    (void) displayMessage();

    // Draw a border around the cell area.
    (void) drawShadedBorder();

#ifdef __MOUSE_ENABLED
    (void) ShowMouse();
#endif


    // Enter main loop
    while ( !kbhit() )
    {

//////////////////////////////////////////////////////////////////////////////
// From my general feelings I am guessing that opening a bracket in an #ifdef
// expecting to close that bracket if there is a following #ifdef a few lines
// down is somewhat of a different idea.  This technique allows me to let the
// user click per iteration that they want to see.
#ifdef __MOUSE_ENABLED
        (void)ReadMouse();

        if (MOUSE_BUTTON_1_PRESSED) {
#endif
// Display & Process cells, then wait delay time, Reapeat until
// keystroke is enacted.
            (void) displayCells();
            (void) processCells();

#ifdef __MOUSE_ENABLED
            (void) processCells();
        }                           // <-- END funky idea.
#endif

        // @see #define DELAY_TIME
        (void) delay(DELAY_TIME);
    }

#ifdef __MOUSE_ENABLED
    (void) HideMouse();
#endif

    // End graphics mode.
    (void) endgraph();

    // Exit politely.
    return EXIT_SUCCESS;
}
Exemplo n.º 21
0
void Welcome()
{
	Mouse m;


	setbkcolor(WHITE);
	setviewport(40, 40, 600, 440, 1);

	setfillstyle(SOLID_FILL, LIGHTCYAN);
	setcolor(YELLOW);
	rectangle(0, 0, 560, 400);
	floodfill(50, 50, 14);

    setviewport(40, 40, 580, 420, 1);
	rectangle(20, 20, 540, 380);
	setfillstyle(SOLID_FILL, LIGHTMAGENTA);
	floodfill(21, 300, YELLOW);


	setcolor(BLACK);
	settextstyle(TRIPLEX_FONT, HORIZ_DIR, 8);
	outtextxy(110, 55, "Welcome");
	DisChinese("今天你是设计师",170,165,2,2,10,10);


	setcolor(BLUE);
	setfillstyle(SOLID_FILL, YELLOW);
	ellipse(450,335,0,360,60,20);
	floodfill(450, 335, BLUE);
	DisChinese("开始",430,328,1,1,20,DARKGRAY);


	setcolor(WHITE);
	setfillstyle(SOLID_FILL, WHITE);

	arc(260,818,85,130,470);
	arc(270,820,85,130,470);
	arc(285,822,85,130,470);

	line(61,227,74,400);
	line(61,227,164,211);
	line(164,211,174,360);

	line(184,277,254,265);
	line(184,277,190,355);
	line(254,265,260,355);

	bar(85,245,108,270);
	bar(131,245,155,270);
	bar(85,300,108,330);
	bar(131,300,155,330);

	bar(199,287,215,302);
	bar(230,282,246,298);
	bar(199,320,215,335);
	bar(230,320,246,335);


	while (1)
	{
	    ShowMouse();
	    m=ReadMouse();
        if (m.b == 1)
        {
			if (MouseIn(430,305,500,395))
			{
			    HideMouse();
			    cleardevice();
			    closegraph();
				break;
			}
		}
	}
}
Exemplo n.º 22
0
/****************************************************************************
 * ClientWndProc                                                            *
 *  - Typical PM client window procedure.  (see below)                      *
 *  - Standard client window I/O                                            *
 ****************************************************************************/
MRESULT EXPENTRY ClientWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
{
	   RECTL  rcl;
	   SWP	  swp;
	   HPS	  hpsPaint;

    static HPS	  hps;                      /* Permanent HPS                */
    static INT    cx, cy;		    /* Client window dimensions     */
    static BOOL   bSlowUpdateNow = FALSE;   /* Update toggle for asteroids  *
                                             *   and enemy which are slow.  */
    static POINTL ptlCenter;		    /* Center of client window      */

    switch (msg) {
      /* Recieved from WinCreateStdWindow */
      case WM_CREATE:
	/* Get permanent PS for entire window */
	hps = WinGetPS(hwnd);

	/* Load private Asteroid fonts from ASTEROID.DLL */
	if (GpiLoadFonts(hab, "ASTEROID") != GPI_OK) {
            WinReleasePS(hps);
	    WinAlarm(HWND_DESKTOP, WA_WARNING);
	    WinMessageBox(HWND_DESKTOP,NULLHANDLE,
		"Please put ASTEROID.DLL in a directory in your LIBPATH.",
		"Error reading ASTEROID.DLL",
		0,MB_ICONHAND|MB_OK|MB_APPLMODAL);
	    WinPostMsg(hwnd,WM_QUIT,(MPARAM) 0L,(MPARAM) 0L);
	    return (MRESULT) TRUE;
	    }

        /* Register/create logical fonts for use */
	InitFonts(hps);

	/* Display About dialoge box */
	WinDlgBox(HWND_DESKTOP, hwnd, (PFNWP)AboutDlgProc, NULLHANDLE,
		  IDD_ABOUT, NULL);

	return 0;

      /* Recieved during attract mode when user starts game */
      case WM_STARTGAME:
        /* Determine the number of players */
	cPlayers = (INT)LONGFROMMP(mp1);

        /* Initialize each player */
	for (Player=0;Player<cPlayers;Player++) {
	    Level[Player] = 1;
	    Ships[Player] = prfProfile.iSHIPS;
	    DeletePhotons();
	    InitAsteroids();
	    InitEnemy();
	    }

        /* Start with player 1 */
	Player = 0;
	iGameMode = GAME_MODE_NEXT;
	iGameModeCnt = GAME_PAUSE_TIME-1;

	/* Hide the pointer if mouse controls are enabled */
	ShowMouse(FALSE);
        
        /* Paint everything */
	WinSendMsg(hwnd, WM_PAINT, MPVOID, MPVOID);

	return 0;

      /* Recieved at startup and at the completion of a game */
      case WM_INITGAME:
        /* Make mouse visible if we hid it before */
        ShowMouse(TRUE);
        
	/* Fix menu to reflect attract mode */
	EnableMenuItem(hwndMenu, IDM_START, TRUE);
	EnableMenuItem(hwndMenu, IDM_STOP, FALSE);

	/* Initialize player and enemy data structures */
	cPlayers = 0;
	Level[0] = 1;
	for (Player=0;Player<2;Player++) {
	    Score[Player] = 0L;
	    Ships[Player] = 0;
	    DeletePhotons();
	    }
	Player = 0;

	/* Initialize asteroids (and enemy) for attract mode */
	InitAsteroids();
	InitEnemy();

        /* Depending on whether ASTEROID was just started or a game just  *
         *   completed display the "High Score" or "Press 1 or 2" screen. */
	if (SHORT1FROMMP(mp1) == 0) {
	    iGameMode = GAME_MODE_INIT1;
	    iGameModeCnt = GAME_INIT_TIME;
	    }
	else {
	    iGameMode = GAME_MODE_INIT2;
	    iGameModeCnt = GAME_INIT_TIME;
	    }

        /* Paint everything */
	WinSendMsg(hwnd, WM_PAINT, MPVOID, MPVOID);
	return 0;

      /* Usually recieved from the system, sometime forced by the program to *
       *   ensure the screen is not corrupt.                                 */
      case WM_PAINT:
	/* Clear entire window to insure no "droppings" */
	WinQueryWindowRect(hwnd,&rcl);
        WinFillRect(hps, &rcl, CLR_BLACK);
	WinInvalidateRect(hwnd, &rcl, FALSE);

	/* Get the update region and paint it black */
	hpsPaint = WinBeginPaint(hwnd, (HPS)NULL, &rcl);
	WinFillRect(hpsPaint, &rcl, CLR_BLACK);
	WinEndPaint(hpsPaint);

        /* Only in normal play mode should we draw the ship */
	if ((iGameMode == GAME_MODE_PLAY) &&
	    (iShipMode[Player] != EXPLOSION) &&
	    (iShipMode[Player] != HYPERSPACE))
	    DrawShip(hps, cx, cy, DRAW_INIT);
	else if ((iGameMode == GAME_MODE_PLAY) &&
		 (iShipMode[Player] == EXPLOSION))
	    ExplodeShip(hps, cx, cy);

        /* Draw the enemy if it is on the screen */
	if (iEnemyMode[Player] != NONE)
	    if (iEnemyMode[Player] != EXPLOSION)
		DrawEnemy(hps, cx, cy,DRAW_INIT);
	    else
		ExplodeEnemy(hps, cx, cy);

        /* Draw photons and asteroids in all modes but the "Enter your *
         *   initials" mode, otherwise draw that screen.               */
	if (iGameMode != GAME_MODE_HIGH) {
	    DrawPhotons(hps, cx, cy, DRAW_INIT);
	    DrawAsteroids(hps, cx, cy, DRAW_INIT);
	    }
	else
	    DrawHighScore(hps, cx, cy, DRAW_INIT);

        /* Always draw the score */
	DrawScore(hps, cx, cy, DRAW_INIT);

	return 0;

      /* Left mouse button down.  This simulates the move/track function *
       *   in the system menu.                                           */
      case WM_BUTTON1DOWN:
        if (prfProfile.bMOUSECONTROL &&
            iGameMode != GAME_MODE_INIT1 &&
            iGameMode != GAME_MODE_INIT2 &&
            !TogglePause(CHECK)) {
	    UPDATE_FIRE(iShipMode[Player], TRUE);
            return (MRESULT)TRUE;
        }
	return WinSendMsg(hwndFrame, WM_TRACKFRAME,
			 (MPARAM) (SHORT1FROMMP(mp2) | TF_MOVE), MPVOID);

      case WM_BUTTON1UP:
        if (prfProfile.bMOUSECONTROL) {
	    UPDATE_FIRE(iShipMode[Player], FALSE);
            return (MRESULT)TRUE;
        }
        return 0;
        
      /* Left mouse button double clicked.  Toggle frame control display. */
      case WM_BUTTON1DBLCLK:
        if (!prfProfile.bMOUSECONTROL ||
            iGameMode == GAME_MODE_INIT1 ||
            iGameMode == GAME_MODE_INIT2 ||
            TogglePause(CHECK)) {
            if (prfProfile.bCONTROLS = !prfProfile.bCONTROLS)
	    	ShowFrameControls();
            else
	    	HideFrameControls();
        }
	return 0;

      case WM_BUTTON2DOWN:
        if (prfProfile.bMOUSECONTROL) {
	    UPDATE_SHIELD(iShipMode[Player], iShipShieldCnt[Player]);
            return (MRESULT)TRUE;
        }
        return 0;
        
      case WM_BUTTON2CLICK:
        if (prfProfile.bMOUSECONTROL) {
            UPDATE_HYPERSPACE(iShipMode[Player], iShipModeCnt[Player]);
            return (MRESULT)TRUE;
        }
        return 0;
        
      /* Right mouse button double clicked.  Display the about dialog box. */
      case WM_BUTTON2DBLCLK:
        if (!prfProfile.bMOUSECONTROL ||
            iGameMode == GAME_MODE_INIT1 ||
            iGameMode == GAME_MODE_INIT2 ||
            TogglePause(CHECK)) {
            WinDlgBox(HWND_DESKTOP, hwndClient, (PFNWP)AboutDlgProc,
            	      NULLHANDLE, IDD_ABOUT, NULL);
        }
	return 0;

      /* User typed a key.  Most of this is self explanatory. */
      case WM_CHAR:
	ProcessChar((CHAR) (CHARMSG(&msg)->vkey-1),
		    CHARMSG(&msg)->fs & KC_VIRTUALKEY,
		    (CHAR) (CHARMSG(&msg)->chr),
		    (BOOL) !(CHARMSG(&msg)->fs & KC_KEYUP));
	return 0;

      /* User entered a command via the menu bar. */
      case WM_COMMAND:
	DoCommand(hwnd, msg, mp1, mp2);
	return 0;

      /* Suspend/un-suspend game depending on focus */
      case WM_SETFOCUS:
	if ((BOOL) SHORT1FROMMP(mp2))
	    TogglePause(SUSPEND_OFF);
	else if (!prfProfile.bBACKGRND)
	    TogglePause(SUSPEND_ON);
	return 0;

      /* Keep track of the client window size.  Profile information is not *
       *   updated here because there are better places (i.e. at exit)     */
      case WM_SIZE:
	cx = (INT)SHORT1FROMMP(mp2);
	cy = (INT)SHORT2FROMMP(mp2);

      /* Keep track of client window position.  Also updates profile info. */
      case WM_MOVE:
	WinQueryWindowPos(hwndFrame,&swp);
	if (!(swp.fl & SWP_MAXIMIZE) && !(swp.fl & SWP_MINIMIZE)) {
	    prfProfile.x  = swp.x;prfProfile.y   = swp.y;
	    prfProfile.cx = swp.cx;prfProfile.cy = swp.cy;
	    }

	if (swp.fl & SWP_MINIMIZE)
	    if (!prfProfile.bBACKGRND) {
		/* Set icon */
		WinSendMsg(hwndFrame, WM_SETICON,
		    (MPARAM) WinLoadPointer(HWND_DESKTOP, NULLHANDLE,
					    ID_RESOURCE), MPVOID);

		TogglePause(SUSPEND_ON);
		}
	    else
		WinSendMsg(hwndFrame, WM_SETICON, MPVOID, MPVOID);
	else
	    TogglePause(SUSPEND_OFF);

	ptlCenter.x = swp.cx / 2;
        ptlCenter.y = swp.cy / 2;
        WinMapWindowPoints(hwndClient, HWND_DESKTOP, &ptlCenter, 1L);

	return 0;

      /* Recieved approximately 31 times a second.  This is the longest and *
       *   ugliest of the messages, partly because there are so many cases  *
       *   to keep track of, partly because it must be highly optimized.    */
      case WM_TIMER:
        if (prfProfile.bMOUSECONTROL &&
            iGameMode != GAME_MODE_INIT1 &&
            iGameMode != GAME_MODE_INIT2) {                   POINTL ptl;
            static BOOL   bUp, bLeft, bRight;

            WinQueryPointerPos(HWND_DESKTOP, &ptl);
            if (bUp || (ptl.y - ptlCenter.y > 0))
	       	UPDATE_THRUST(iShipMode[Player],
            		      bUp = (ptl.y - ptlCenter.y > 0));
            if (bLeft || (ptlCenter.x - ptl.x > 0))
                UPDATE_LEFT(iShipMode[Player],
                	    bLeft = (ptlCenter.x - ptl.x > 0));
            if (bRight || (ptlCenter.x - ptl.x < 0))
                UPDATE_RIGHT(iShipMode[Player],
                 	     bRight = (ptlCenter.x - ptl.x < 0));
            WinSetPointerPos(HWND_DESKTOP, ptlCenter.x, ptlCenter.y);
        }
        
        /* Determine the current game mode */
	switch (iGameMode) {

          /* Either initialization/attract mode screen. */
	  case GAME_MODE_INIT1: case GAME_MODE_INIT2:
            /* Switch screens when count expires */
	    if (--iGameModeCnt == 0) {
		if (iGameMode == GAME_MODE_INIT1)
		    iGameMode = GAME_MODE_INIT2;
		else
		    iGameMode = GAME_MODE_INIT1;
		iGameModeCnt = GAME_INIT_TIME;

                /* Score must be redrawn because the attract mode screens *
                 *   draw the score differently.                          */
		DrawScore(hps, cx, cy, DRAW_REINIT);
		}

            /* Update photons, asteroids, enemy, and score */
	    UpdatePhotons(hps, cx, cy);
	    if (uiSpeed == SPEED_OS2 || (bSlowUpdateNow = !bSlowUpdateNow)) {
		UpdateAsteroids(hps, cx, cy);
		UpdateEnemy(hps, cx, cy);
		DrawScore(hps, cx, cy, DRAW_REFRESH);
		}
	    break;

          /* Completion of one player's turn or new game */
	  case GAME_MODE_NEXT:
            /* Initially, erase and redraw everything for new player */
	    if (iGameModeCnt-- == GAME_PAUSE_TIME) {
		if ((cPlayers == MAXPLAYERS) &&
                    (Ships[(Player+1) % MAXPLAYERS])) {
		    DrawAsteroids(hps, cx, cy, DRAW_ERASE);
		    DrawPhotons(hps, cx, cy, DRAW_ERASE);
		    Player = (Player+1) % MAXPLAYERS;
		    }
		DrawScore(hps, cx, cy, DRAW_REINIT);
		DrawAsteroids(hps, cx, cy, DRAW_INIT);
		}
            /* During countdown update score and asteroids */
	    else if (iGameModeCnt > 0) {
		if (uiSpeed == SPEED_OS2 || (bSlowUpdateNow = !bSlowUpdateNow)) {
		    DrawScore(hps, cx, cy, DRAW_REFRESH);
		    UpdateAsteroids(hps, cx, cy);
		    }
		}
            /* At end of countdown start the player */
	    else {
		InitShip();
		InitEnemy();
		iGameMode = GAME_MODE_PLAY;
		DrawScore(hps, cx, cy, DRAW_REINIT);
		}
	    break;

          /* Normal play mode */
	  case GAME_MODE_PLAY:
            /* Update ship, photons, asteroids, enemy, and score */
	    UpdateShip(hps, cx, cy);
	    UpdatePhotons(hps, cx, cy);
	    if (uiSpeed == SPEED_OS2 || (bSlowUpdateNow = !bSlowUpdateNow)) {
		UpdateAsteroids(hps, cx, cy);
		UpdateEnemy(hps, cx, cy);
                /* Erase old and draw new scores if there is a change*/
		if (bChangeScore) {
		    bChangeScore = FALSE;
		    DrawScore(hps, cx, cy, DRAW_REINIT);
		    }
                /* Else just refresh the score */
		else
		    DrawScore(hps, cx, cy, DRAW_REFRESH);
		}
	    break;

          /* Game over mode.  This is the longest and ugliest case because  *
           *   conditions are highly dependent on the number of players,    *
           *   multiplayer game status, and the number and order of high    *
           *   scores.                                                      */
	  case GAME_MODE_OVER:
            /* Initially, just update the score and number of ships */
	    if (iGameModeCnt-- == GAME_PAUSE_TIME)
		DrawScore(hps, cx, cy, DRAW_REINIT);

            /* During countdown refresh the score and update the asteroids */
	    else if (iGameModeCnt > 0) {
		if (uiSpeed == SPEED_OS2 || (bSlowUpdateNow = !bSlowUpdateNow)) {
		    DrawScore(hps, cx, cy, DRAW_REFRESH);
		    UpdateAsteroids(hps, cx, cy);
		    }
		}

            /* At the end of the countdown, if there are any other players, *
             *   continue with them.                                        */
	    else {
                /* Countinue on with any remaining players. */
		if ((cPlayers == MAXPLAYERS) &&
                    (Ships[(Player+1) % MAXPLAYERS])) {
                    /* Erase all of the old asteroids. */
		    DrawAsteroids(hps, cx, cy, DRAW_ERASE);

                    /* Setup everything for the next player */
		    Player = (Player+1) % MAXPLAYERS;
		    InitShip();
		    InitEnemy();
		    iGameMode = GAME_MODE_PLAY;
		    DrawAsteroids(hps, cx, cy, DRAW_INIT);
		    DrawScore(hps, cx, cy, DRAW_REINIT);
		    }

                /* Check for new high scores and update table as necessary. */
		else {
                    /* Erase all of the old asteroids. */
		    DrawAsteroids(hps, cx, cy, DRAW_ERASE);


                /* The following if/else block is admittedly a kludge, it is *
                 *   simple and it does work, however.  Ideally it should    *
                 *   sort the high scores and update the high score table in *
                 *   descending order.                                       */

                    /* If player 1 scored higher than player 2 then check *
                     *   player 1 first for a high score.                 */
       		    if (Score[0] > Score[1])
			for (Player=0;Player<cPlayers;Player++)
                            /* If the player's score is > than the lowest, *
                             *   update the high score table.              */
			    if (Score[Player] > prfProfile.lSCORES[9]) {
				UpdateHighScores();
				iGameMode = GAME_MODE_HIGH;
				}
                            /* Otherwise, make sure he is not asked for his *
                             *   initials.                                  */
			    else
				Score[Player] = 0;

                    /* Otherwise, check player 2 first */
		    else
			for (Player=cPlayers;Player>=0;Player--)
                            /* If the player's score is > than the lowest, *
                             *   update the high score table.              */
			    if (Score[Player] > prfProfile.lSCORES[9]) {
				UpdateHighScores();
				iGameMode = GAME_MODE_HIGH;
				}
                            /* Otherwise, make sure he is not asked for his *
                             *   initials.                                  */
			    else
				Score[Player] = 0L;

                    /* If there was no high score, go into attract mode */
		    if (iGameMode != GAME_MODE_HIGH)
			WinSendMsg(hwnd,WM_INITGAME,MPFROMSHORT(1),(MPARAM) 0L);
                    /* Else, check for player 1's initials first then 2's   *
                     * This is not faithful, in the arcade game the player  *
                     *   with the higher score always goes first.           */
		    else {
			if (Score[0] > 0L)
			    Player = 0;
			else
			    Player = 1;
			DrawScore(hps, cx, cy, DRAW_REINIT);
			DrawHighScore(hps, cx, cy, DRAW_INIT);
			}
		    }
		}
	    break;

          /* Mode which prompts players to enter their initials */
	  case GAME_MODE_HIGH:
            /* If the player's position is > 0 then refresh the screen */
	    if (Score[Player] > 0L)
		DrawHighScore(hps, cx, cy, DRAW_REFRESH);
            /* Else, the current player is done go to the next */
	    else if ((cPlayers == MAXPLAYERS) && (Player == 0) &&
		     (Score[1] > 0L)) {
		Player++;
		DrawHighScore(hps, cx, cy, DRAW_REINIT);
		}
            /* If there are no more high scores then go into attract mode */
	    else
		WinSendMsg(hwnd, WM_INITGAME, MPFROMSHORT(1), MPVOID);
	    break;
	  }
	return 0;

      /* Used by help manager */
      case HM_QUERY_KEYS_HELP:
	 return((MRESULT)IDH_CLIENTKEYS);

      /* Recieved always from the system or in the case of an initialization*
       *   error.  Both messages will normally save the profile information.*
       * Ideally the profile section should be moved to a subroutine and the*
       *   the following should be broken into two distinct cases.	    */
      case WM_SAVEAPPLICATION:
      case WM_DESTROY:
	/* If the fonts were not found bApplicationOk will be false, in     *
	 *   that case the window profile information should not be updated.*/
	if (TRUE) {
	    /* Copy window position and size info into profile structure */
	    WinQueryWindowPos(hwndFrame, &swp);
	    if (swp.fl & SWP_MAXIMIZE)
		prfProfile.ulMINMAX = SWP_MAXIMIZE;
	    else if (swp.fl & SWP_MINIMIZE)
		prfProfile.ulMINMAX = SWP_MINIMIZE;
	    else {
		prfProfile.ulMINMAX = 0;
		prfProfile.x  = swp.x;prfProfile.y   = swp.y;
		prfProfile.cx = swp.cx;prfProfile.cy = swp.cy;
		}

	    /* Write profile information */
	    PrfWriteProfileData(HINI_USERPROFILE, szClientClass, "Data",
		&prfProfile, sizeof(PROFILEREC));
	    }

        /* If the application is terminating release the fonts and the hps. */
        if (msg == WM_DESTROY) {
	    /* Make sure mouse is visible if we hid it before */
            ShowMouse(TRUE);
            
	    /* Release font identifiers and DLL resource module */
	    GpiSetCharSet(hps, LCID_DEFAULT);
	    GpiDeleteSetId(hps, LCID_LARGE);
	    GpiDeleteSetId(hps, LCID_SMALL);
	    GpiUnloadFonts(hab, "ASTEROID");

	    /* Release the "permanent" presentation space */
	    WinReleasePS(hps);
            }
	return 0;

      }
    return WinDefWindowProc(hwnd, msg, mp1, mp2);
}