Example #1
0
//---------------------------------------------------------------------------------------
static void ProcessPGNCmd_Release( tGroupRegistration* pGroup, const tNmea2KMsg *pMsg, tcPgn65280NavicoData* pPgn )
{
    int result;

    UNUSED_PARAM( pMsg );

    if (pGroup->state == State_IsMaster)
    {
        // current master has given up
        assert( pMsg->sourceAddr == pGroup->master );

        result = AppCommand( pGroup, ArbitrationCmd_MasterQuit, pPgn->flags, pPgn->data24 );
        if (result == ARBITRATION_OK_ACQUIRE && IsAllowedToAcquire( pGroup ))
        {
            DoSend( pGroup, ArbitrationPGNCmd_Acquire );
        }
        else
        {
            pGroup->state = State_NoMaster;
            pGroup->timer = TIMEOUT_NOMASTER_FIRST;
        }
    }
    else if (pGroup->state == State_Master)
    {
        // assert my authority
        DoSend( pGroup, ArbitrationPGNCmd_Master );
    }
}
Example #2
0
//---------------------------------------------------------------------------------------
static void ProcessPGNCmd_Acquire( tGroupRegistration* pGroup, const tNmea2KMsg *pMsg, tcPgn65280NavicoData* pPgn )
{
    int cmp;
    int result;
    eState state;

    state = pGroup->state;
    if (state != State_Acquire && state != State_Master)
        return;

    if (pGroup->statusFlags & (ArbitrationFlags_Watcher|ArbitrationFlags_NotSuitable))
    {
        assert( 0 );
        return;
    }

    cmp = ComparePriorities( pGroup, pMsg->sourceAddr, pPgn->flags, pPgn->data24 );
    if (cmp < 0)
    {
        // they are better than me
        if (state == State_Master)
        {
            // but I'm already master, see if we want to allow them to take over
            result = AppCommand( pGroup, ArbitrationCmd_MasterChallenge, pPgn->flags, pPgn->data24 );
            if (result == ARBITRATION_OK_RELEASE)
            {
                // we've had enough, let them take over
                MasterRelease( pGroup, tTrue );
            }
            else
            {
                // assert my authority
                DoSend( pGroup, ArbitrationPGNCmd_Master );
            }
        }
        else
        {
            // give up trying to be the master
            pGroup->state = State_Unknown;
            pGroup->timer = TIMEOUT_ACQUIRE_ABORTED;
            ClearSend( pGroup );
        }
    }
    else
    {
        assert( cmp > 0 );   //TODO: should never be the same, but what if it is?

        // assume I'm better than them
        if (state == State_Master)
        {
            // assert my authority
            DoSend( pGroup, ArbitrationPGNCmd_Master );
        }
    }
}
Example #3
0
//---------------------------------------------------------------------------------------
static void ProcessPGNCmd_Member( tGroupRegistration* pGroup, const tNmea2KMsg *pMsg, tcPgn65280NavicoData* pPgn )
{
    int result;

    UNUSED_PARAM( pMsg );

    result = AppCommand( pGroup, 
        ((pPgn->command == ArbitrationPGNCmd_NewMember)? ArbitrationCmd_NewMemberInfo : ArbitrationCmd_MemberInfo), pPgn->flags, pPgn->data24 );
    if (pGroup->state == State_Master)
    {
        if (result == ARBITRATION_OK_RELEASE)
        {
            // we've had enough, let them take over
            MasterRelease( pGroup, tTrue );
        }
        else
        {
            // let them know I'm the boss
            DoSend( pGroup, ArbitrationPGNCmd_Master );
        }
    }
}
Example #4
0
//---------------------------------------------------------------------------------------
static int ComparePriorities( tGroupRegistration* pGroup, tNad addr, uint8_t flags, uint32_t groupData )
{
    tNad myAddr;
    int result;
    uint8_t myFlags = pGroup->statusFlags & (ArbitrationFlags_Watcher|ArbitrationFlags_NotSuitable);
    uint8_t theirFlags = flags & (ArbitrationFlags_Watcher|ArbitrationFlags_NotSuitable);

    if (myFlags != theirFlags)
    {
        return (myFlags < theirFlags)? +3 : -3;
    }

    result = AppCommand( pGroup, ArbitrationCmd_CompareGroupData, flags, groupData );
    switch (result)
    {
    case ArbitrationCmp_Worse:  return -2;
    case ArbitrationCmp_Better: return +2;
    case ArbitrationCmp_Same:   break;
    default:  assert( 0 );
    }

    myAddr = CurrentNmea2KNad( s_Handle, GetMainDeviceIndex(s_Handle) );
    return (addr < myAddr)? -1 : +1;
}
Example #5
0
/////////////////////////////////////////////////////////////////////////////
// AppWndProc( hwnd, uiMessage, wParam, lParam )
//
// The window proc for the app's main (tiled) window.  This processes all
// of the parent window's messages.
//
LONG FAR PASCAL _export AppWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
    PAINTSTRUCT ps;
    HDC hdc;
    BOOL f;

		//is it the registered message?  (this proc is called after the creation
		//of the msgApp).

	 if (msg == msgApp) {				
 		 if (bShowRendering) {
		 	HDC hdc = GetDC(hwndApp);
		 	AppPaint(hwndApp, hdc);
		 	ReleaseDC(hwndApp, hdc);
		 	bShowRendering = (int)wParam;	//sent a 0 to turn off bShowRendering.
		 }
	    return 0L;
	 }
		
		//well, how about standard Windows messages?

    switch (msg)
    {
    case WM_CREATE:
			//let WM_SIZE do all the work.
	      break;

    case WM_ACTIVATEAPP:
		    bAppActive = (BOOL)wParam;
			wt_reset_input();
			// *** Remap the system colors and deal with the palette
			AppActivate(bAppActive);

			if (hpalApp)
			{
				HDC hdc = GetDC(hwnd);

				UnrealizeObject(hpalApp);
				SelectPalette(hdc, hpalApp, FALSE);
				RealizePalette(hdc);

				ReleaseDC(hwnd, hdc);
			}
			break;

    case WM_SIZE:			
			wt_reset_input();
		   nBitmapW = LOWORD(lParam);			//new size.
		   nBitmapH = HIWORD(lParam);

			nBitmapW /= StretchFactor;
			nBitmapH /= StretchFactor;

			//Windows DIBs, including WinG bitmaps, are always a multiple of 
			//32-bits wide.  For us, using the typical 8-bit per pixel bitmap,
			//that means we need to ensure the width is a multiple of 4.  This
			//is important because the WT engine treats a bitmap's width and 
			//pitch as one - there is no way for WT to draw into a bitmap
			//using a width different than the pitch.  So we force the bitmap's
			//width to be a multiple of 4, to be both Windows and WT compatible.
			//Note we could have patched WT to deal with the concept of a 
			//bitmap pitch, but that's too much change.

			nBitmapW = ((nBitmapW+3)/4)*4;

			if(Buffer)
			{						//resizing, minimizing, maximizing.
			 	HBITMAP hbm;
			   int Counter;

				//Create a new 8-bit WinGBitmap with the new size
				BufferHeader.Header.biWidth = nBitmapW;
				BufferHeader.Header.biHeight = nBitmapH * Orientation;

				//probably don't need to do this, but do it anyway.
			   for(Counter = 0;Counter < 256;Counter++) {
				    	BufferHeader.aColors[Counter].rgbRed   = ColorTable[Counter].rgbRed;
				    	BufferHeader.aColors[Counter].rgbGreen = ColorTable[Counter].rgbGreen;
				    	BufferHeader.aColors[Counter].rgbBlue  = ColorTable[Counter].rgbBlue;
				    	BufferHeader.aColors[Counter].rgbReserved = 0;
				}

				hbm = WinG.pCreateBitmap(Buffer,
					(BITMAPINFO *)&BufferHeader, &pBuffer);

				//  Select it in and delete the old one
				hbm = (HBITMAP)SelectObject(Buffer, hbm);
				DeleteObject(hbm);

   			PatBlt(Buffer, 0,0,nBitmapW,nBitmapH, BLACKNESS);

	         wt_set_fb_mem(pBuffer);		//tell WT about new bitmap address.
			   wt_reinit(nBitmapW,nBitmapH);  //and about new bitmap size.
				wt_render();					//and have WT render a frame.

			}
			else						//first time.
			{
				//  Create a new WinGDC and 8-bit WinGBitmap

				HBITMAP hbm;
			   int Counter;

				//  Get WinG to recommend the fastest DIB format

				if(WinG.pRecommendDIBFormat((BITMAPINFO *)&BufferHeader))
				{
					//  make sure it's 8bpp and remember the orientation

					BufferHeader.Header.biBitCount = 8;
					BufferHeader.Header.biCompression = BI_RGB;
					Orientation = BufferHeader.Header.biHeight;
					if (Orientation > 0) {
						DebugMsg("WT requires a top-down bitmap!\nYou are about to hit a brick wall at 90 MPH!");
						PostQuitMessage(1);		//works but slams palette.  bummer.
					}
				}
				else
				{
					//  set it up ourselves
	
					BufferHeader.Header.biSize = sizeof(BITMAPINFOHEADER);
					BufferHeader.Header.biPlanes = 1;
					BufferHeader.Header.biBitCount = 8;
					BufferHeader.Header.biCompression = BI_RGB;
					BufferHeader.Header.biSizeImage = 0;
					BufferHeader.Header.biClrUsed = 0;
					BufferHeader.Header.biClrImportant = 0;
				}

				BufferHeader.Header.biWidth = nBitmapW;
				BufferHeader.Header.biHeight = nBitmapH * Orientation;

//#define BAD_PALETTE_CODE
#ifdef BAD_PALETTE_CODE
//This code sets an incorrect palette, but at least you can still use
//regular windows tools.  Good for debugging.
			   HDC Screen;
			   RGBQUAD *pColorTable;

				//  create an identity palette from the DIB's color table

				//  get the 20 system colors as PALETTEENTRIES
    
			    Screen = GetDC(0);

			    GetSystemPaletteEntries(Screen,0,10,LogicalPalette.aEntries);
			    GetSystemPaletteEntries(Screen,246,10,
								LogicalPalette.aEntries + 246);

				ReleaseDC(0,Screen);

				// initialize the logical palette and DIB color table

			    for(Counter = 0;Counter < 10;Counter++)
			    {
			    	// copy the system colors into the DIB header
			    	// WinG will do this in WinGRecommendDIBFormat,
			    	// but it may have failed above so do it here anyway
			    	
			    	BufferHeader.aColors[Counter].rgbRed =
			    					LogicalPalette.aEntries[Counter].peRed;
			    	BufferHeader.aColors[Counter].rgbGreen =
			    					LogicalPalette.aEntries[Counter].peGreen;
			    	BufferHeader.aColors[Counter].rgbBlue =
			    					LogicalPalette.aEntries[Counter].peBlue;
			    	BufferHeader.aColors[Counter].rgbReserved = 0;

   					LogicalPalette.aEntries[Counter].peFlags = 0;

			    	BufferHeader.aColors[Counter + 246].rgbRed =
		    					LogicalPalette.aEntries[Counter + 246].peRed;
			    	BufferHeader.aColors[Counter + 246].rgbGreen =
		    					LogicalPalette.aEntries[Counter + 246].peGreen;
			    	BufferHeader.aColors[Counter + 246].rgbBlue =
		    					LogicalPalette.aEntries[Counter + 246].peBlue;
			    	BufferHeader.aColors[Counter + 246].rgbReserved = 0;

   					LogicalPalette.aEntries[Counter + 246].peFlags = 0;
   				}

            for (i=0; i<256; i++) {
               ColorTable[i].rgbRed = 0;
               ColorTable[i].rgbGreen = 0;
               ColorTable[i].rgbBlue = 0;
            }

            nColors = wt_load_palette();
            for (i=0; i<nColors; i++) {
               int r,g,b;
               wt_get_palette_entry(i,&r,&g,&b);
               ColorTable[i].rgbRed = r;
               ColorTable[i].rgbGreen = g;
               ColorTable[i].rgbBlue = b;
            }
            pColorTable = &ColorTable[0];

			    for(Counter = 10;Counter < 246;Counter++)
			    {
			    	// copy from the original color table to the WinGBitmap's
			    	// color table and the logical palette

			    	BufferHeader.aColors[Counter].rgbRed =
    					LogicalPalette.aEntries[Counter].peRed =
    						pColorTable[Counter].rgbRed;
			    	BufferHeader.aColors[Counter].rgbGreen =
    					LogicalPalette.aEntries[Counter].peGreen =
    						pColorTable[Counter].rgbGreen;
			    	BufferHeader.aColors[Counter].rgbBlue =
    					LogicalPalette.aEntries[Counter].peBlue =
    						pColorTable[Counter].rgbBlue;
			    	BufferHeader.aColors[Counter].rgbReserved = 0;
  					LogicalPalette.aEntries[Counter].peFlags = PC_NOCOLLAPSE;
			    }

			    hpalApp = CreatePalette((LOGPALETTE *)&LogicalPalette);
#else
//GOOD_PALETTE_CODE
//Working palette code.  Has correct colors. And identity.  Same frame
//rate as bad palette code.  This really hoses Windows colors, so
//a GUI debugger's windows are really hard to read.  I couldn't read the
//Symantec IDDE's windows - so I #ifdef'd the bad palette code in for
//debugging.
//Anyway, this code works.  Need 3 things for identity, as far as I can tell:
//1. you have to be writing to your bitmap using a specific palette, 
//2. this palette has to be made into a Windows palette, and selected.
//3. this palette has to be copied into the BitmapInfo header of the WinG
//   bitmap, before creating it (actually as a parameter to creating it).
//
				ClearSystemPalette();
				CreateWTPalette();

			    for(Counter = 0;Counter < 256;Counter++) {
				    	BufferHeader.aColors[Counter].rgbRed   = ColorTable[Counter].rgbRed;
				    	BufferHeader.aColors[Counter].rgbGreen = ColorTable[Counter].rgbGreen;
				    	BufferHeader.aColors[Counter].rgbBlue  = ColorTable[Counter].rgbBlue;
				    	BufferHeader.aColors[Counter].rgbReserved = 0;
				}
#endif
			    
				//  Create a WinGDC and Bitmap, then select away
				Buffer = WinG.pCreateDC();
				hbm = WinG.pCreateBitmap(Buffer,
					(BITMAPINFO *)&BufferHeader, &pBuffer);

				//  Store the old hbitmap to select back in before deleting
				gbmOldMonoBitmap = (HBITMAP)SelectObject(Buffer, hbm);

   			PatBlt(Buffer, 0,0,nBitmapW,nBitmapH, BLACKNESS);

            wt_set_fb_mem(pBuffer);		//hack to get around WT's code.
            strcpy(szDefaultWorldFileName, szModulePath);
            strcat(szDefaultWorldFileName, DEFAULT_WORLD_FILEPATH);
            wt_init(szDefaultWorldFileName, nBitmapW,nBitmapH); 
				AppSetCaption(DEFAULT_WORLD_FILETITLE);

            wt_render();
			}
			bWTinitialized = TRUE;		
            break;

		case WM_KEYDOWN:
						//set WT's keyboard array, then do a WT cycle.
				switch (wParam) {
					case VK_UP:
						kbPressed[kbUpArrow] = 1; break;
					case VK_DOWN:
						kbPressed[kbDownArrow] = 1; break;
					case VK_LEFT:
						kbPressed[kbLeftArrow] = 1; break;
					case VK_RIGHT:
						kbPressed[kbRightArrow] = 1; break;
					case VK_CONTROL:
						kbPressed[kbCtrl] = 1; break;
					case VK_ESCAPE:
						kbPressed[kbEsc] = 1; 
						//DestroyWindow() here?  let's check to ensure that func
						//  will send the proper msgs to close stuff.
						break;
					case VK_SPACE:
						kbPressed[kbSpace] = 1; break;
					case VK_SHIFT:
						kbPressed[kbLeftShift] = 1; break;
					case VK_TAB:
						kbPressed[kbAlt] = 1; break;
				}

					//tried using wt_input/wt_render/InvalidateRect sequence
					//here, but was sometimes jerky (missed frames, actually), 
					//if there was too much keyboard activity.  
					//I think windows was collapsing queued/pending
					//WM_PAINT messages, so that the app got one instead of a 
					//sudden stream.  Anyhow now I draw immediately, and it works
					//great.  Note that AppIdle() processing is required to
					//have acceleration/deceleration/monsters/events occur without
					//keyboard input.  I guess a timer could also be used.
					//So I ended up using this helper routine to repaint.

				AppDoCycle();
				break;

		case WM_KEYUP:
						//set WT's keyboard array, then do a WT cycle.
				switch (wParam) {
					case VK_UP:
						kbPressed[kbUpArrow] = 0; break;
					case VK_DOWN:
						kbPressed[kbDownArrow] = 0; break;
					case VK_LEFT:
						kbPressed[kbLeftArrow] = 0; break;
					case VK_RIGHT:
						kbPressed[kbRightArrow] = 0; break;
					case VK_CONTROL:
						kbPressed[kbCtrl] = 0; break;
					case VK_ESCAPE:
						kbPressed[kbEsc] = 0; break;
					case VK_SPACE:
						kbPressed[kbSpace] = 0; break;
					case VK_SHIFT:
						kbPressed[kbLeftShift] = 0; break;
					case VK_TAB:
						kbPressed[kbAlt] = 0; break;
				}

				AppDoCycle();
				break;

		case WM_LBUTTONDOWN:
				break;

		case WM_RBUTTONDOWN:
				break;

      case WM_MOUSEMOVE:
        	break;

      case WM_COMMAND:
            return AppCommand(hwnd,msg,wParam,lParam);

		case WM_DESTROY:
            PostQuitMessage(0);
            break;

      case WM_CLOSE:
		 	   break;

      case WM_PALETTECHANGED:
		    	if ((HWND)wParam == hwnd)
					break;

	    // fall through to WM_QUERYNEWPALETTE

		case WM_QUERYNEWPALETTE:
		    hdc = GetDC(hwnd);

		    if (hpalApp)
				SelectPalette(hdc, hpalApp, FALSE);
	
		    f = RealizePalette(hdc);
		    ReleaseDC(hwnd,hdc);
	
		    if (f)
				InvalidateRect(hwnd,NULL,TRUE);
	
		    return f;
	
	     case WM_PAINT:
		    hdc = BeginPaint(hwnd,&ps);
			 SelectPalette(hdc, hpalApp, FALSE);
			 RealizePalette(hdc);
		    AppPaint (hwnd,hdc);
	       EndPaint(hwnd,&ps);
	       return 0L;
	    }
	return DefWindowProc(hwnd,msg,wParam,lParam);
}
Example #6
0
//---------------------------------------------------------------------------------------
static void ProcessPGNCmd_Master( tGroupRegistration* pGroup, const tNmea2KMsg *pMsg, tcPgn65280NavicoData* pPgn )
{
    int cmp;
    int result;

    if (pGroup->state == State_Master)
    {
        // bad news, more than one device thinks its the master
        assert( (pGroup->statusFlags & ArbitrationFlags_Watcher) == 0 );

        ClearSend( pGroup );
        cmp = ComparePriorities( pGroup, pMsg->sourceAddr, pPgn->flags, pPgn->data24 );
        if (cmp < 0)
        {
            // they're better than me, let them retain master status
            result = AppCommandLocal( pGroup, ArbitrationCmd_MasterRelease, 0 );
            assert( result >= 0 );

            //SendCommand( pGroup, ArbitrationPGNCmd_Defer, 0 );

            pGroup->state = State_IsMaster;
            pGroup->timer = TIMEOUT_MASTER_RELEASED;
            pGroup->master = pMsg->sourceAddr;
            result = AppCommand( pGroup, ArbitrationCmd_MasterKnown, pPgn->flags, pPgn->data24 );
            assert( result >= 0 );
        }
        else
        {
            assert( cmp > 0 );   //TODO: should never be the same, but what if it is?

            // I'm better than them, reassert my authority
            DoSend( pGroup, ArbitrationPGNCmd_Master );
        }
    }
    else
    {
        if (pGroup->options & ArbitrationOpt_AutoChallenge)
        {
            cmp = ComparePriorities( pGroup, pMsg->sourceAddr, pPgn->flags, pPgn->data24 );
            if (cmp > 1)
            {
                result = AppCommand( pGroup, ArbitrationCmd_MasterWeak, pPgn->flags, pPgn->data24 );
                if (result == ARBITRATION_OK_ACQUIRE && IsAllowedToAcquire( pGroup ))
                {
                    DoSend( pGroup, ArbitrationPGNCmd_Acquire );
                    return;
                }
            }
        }

        if (pGroup->state != State_IsMaster)
        {
            pGroup->state = State_IsMaster;
            pGroup->master = pMsg->sourceAddr;
            result = AppCommand( pGroup, ArbitrationCmd_MasterKnown, pPgn->flags, pPgn->data24 );
            assert( result >= 0 );
        }
        else if (pGroup->master != pMsg->sourceAddr)
        {
            pGroup->master = pMsg->sourceAddr;
            result = AppCommand( pGroup, ArbitrationCmd_MasterChanged, pPgn->flags, pPgn->data24 );
            assert( result >= 0 );
        }
        pGroup->timer = TIMEOUT_MASTER_CHECK;
    }
}