//////////////////////////////////////////////////////////////////////
//
// Project  : BRender Demo Framework
//            Copyright (c) 1996 Argonaut Technologies Ltd.
//            All rights reserved.
//
// Author   : Steve Williams, October 1996
//
// File     : WIN_BITS.C
//
// Requires : BRender V1.3
//            Microsoft DirectX 3, Win95 / NT.
//
// Comments : Windows demo framework main implementation file.
//            See also demomenu.c, timing.c, winkey.c
//
//////////////////////////////////////////////////////////////////////

#include <windows.h>
#include <windowsx.h>
#include <commctrl.h>
#include <memory.h>
#include <mmreg.h>
#include "br_demo.h"
#include "resource.h"
#include "dsif.h"

// Device from device menu to use initially.

#define BR_DEMO_INITIAL_DEVICE 0
#define MAX_DDRAW_DEVICES 5

#define DEVICE_BASE 700

char szOpenFilter[128];
char szFileBuffer[MAX_PATH];
char szFileTitle[MAX_PATH];
char szOpenDLGTitle[64];
char szAnyFileBuffer[MAX_PATH];
char szAnyFileTitle[MAX_PATH];

// Structure to keep track of all framework data.

static WIN_BITS BrWinApp ;

// Keep track of the state of the mouse buttons

static br_boolean bLeftButtonDown = BR_FALSE, bRightButtonDown = BR_FALSE ; 

// These are filled in during the device query functions in demomenu.c

char BrDemo_Device_Name[MAX_DEVICES][20];

// Arguments for DOS parameter passing
int argc;
char *argv[10];

#if BASED_FLOAT
   static char *mmxName="mmx_prmf";
#else
   static char *mmxName="mmx_prmx";
#endif

extern char *DDraw_Devices[MAX_DDRAW_DEVICES]; 

// Don't use any resource IDs between DEVICE_BASE and 
// DEVICE_BASE + ...

// They are used for the screen modes available under the devices menu.


static br_uint_16 current_menu_res_id = DEVICE_BASE ;

static Num_DDraw_Devices = 0 ;
static char *DD_Device_Description[MAX_DDRAW_DEVICES];

// Handle to the current device's sub menu.

static HMENU hDeviceModesMenu ; 
static HMENU hThisDeviceMenu ;
static HMENU hCurrentMenu ;
static HMENU h8BitMenu = NULL ;
static HMENU h15BitMenu = NULL ;
static HMENU h16BitMenu = NULL ;
static HMENU h24BitMenu = NULL ;


// Num of BRender devices we have found
static br_int_32 Num_BRender_Devices = 0 ;

// Handle to Device sub-menu

extern HMENU hDeviceMenu ;

// Used for keeping track of ticks in the Device menu.

br_uint_32 Current_Windowed_ID = 0 ;

extern char BrDemo_Device_Name[MAX_DEVICES][20];



// -----------------------------------------------------------------
// Function : BrDemo_Allocate_Pixelmaps_Int 
//
// Description : Starts up BRender device and allocates necessary
//               pixelmaps. Loads and sets palette.
// -----------------------------------------------------------------

br_error BrDemo_Allocate_Pixelmaps_Int( WIN_BITS_PTR pBrApp )
{
   br_error r ;
   char *DDraw_DeviceStr ;

   if ( pBrApp->DDraw_Device_Num >= 0 )
      DDraw_DeviceStr = DDraw_Devices[pBrApp->DDraw_Device_Num];
   else
      DDraw_DeviceStr = "" ;

   // Create BRender device
   
   if ( pBrApp->bFullScreen )
   {
        r = BrDevBeginVar( &pBrApp->screen, BrDemo_Device_Name[pBrApp->Current_Device],
              BRT_WINDOW_HANDLE_H, pBrApp->hWnd,
              BRT_WINDOW_FULLSCREEN_B, pBrApp->bFullScreen,
              BRT_WIDTH_I32, pBrApp->Width,
              BRT_HEIGHT_I32, pBrApp->Height,
              BRT_PIXEL_BITS_I32, pBrApp->Fullscreen_BPP,
              BRT_DIRECT3D_RENDER_METHOD_T, pBrApp->tRenderStyle,
              BRT_DIRECTDRAW_DEVICENAME_CSTR, DDraw_DeviceStr,
              BR_NULL_TOKEN );
   
       if ( r != BRE_OK )
       {
          BR_ERROR4("Could not start device '%s' full screen %dx%dx%d.", BrDemo_Device_Name[pBrApp->Current_Device], pBrApp->Width, pBrApp->Height, pBrApp->Fullscreen_BPP  );
          return r ;
       }
   }
   else
   {
      r = BrDevBeginVar( &pBrApp->screen, BrDemo_Device_Name[pBrApp->Current_Device],
            BRT_WINDOW_HANDLE_H, pBrApp->hWnd,
            BRT_WINDOW_FULLSCREEN_B, BR_FALSE,
            BRT_DIRECT3D_RENDER_METHOD_T, pBrApp->tRenderStyle,
            BRT_DIRECTDRAW_DEVICENAME_CSTR, DDraw_DeviceStr,
            BR_NULL_TOKEN );

      if ( r != BRE_OK )
      {
         BR_ERROR2( "Could not start device '%s' windowed, %d bpp", BrDemo_Device_Name[pBrApp->Current_Device], pBrApp->Windowed_BPP );
         return r ;
      }
   }

   if ( pBrApp->bUsePalette )
   {
        pBrApp->palette = BrPixelmapLoad(pBrApp->palette_filename);

        if ( pBrApp->palette )
        {
           BrPixelmapPaletteSet( pBrApp->screen, pBrApp->palette );
        }
        else
        {
           pBrApp->palette = NULL ;
           BR_ERROR1("Could not load palette %s", pBrApp->palette_filename );
           return BRE_FAIL ;
        }
   }

    
   // Allocate other buffers

   if ( pBrApp->bStretch )
      pBrApp->back_buffer = BrPixelmapMatchSized( pBrApp->screen, BR_PMMATCH_OFFSCREEN, BrWinApp.Offscreen_Width, BrWinApp.Offscreen_Height );
   else
       pBrApp->back_buffer = BrPixelmapMatch( pBrApp->screen, BR_PMMATCH_OFFSCREEN );

   if ( !pBrApp->back_buffer )
   {
      BR_ERROR0("Could not allocate back buffer");
      return BRE_FAIL ;
   }

   /*
    * Attach palette to back buffer
    */
   pBrApp->back_buffer->map = pBrApp->palette ;

   if ( BrWinApp.bUseZBuffer )
   {
      pBrApp->depth_buffer = BrPixelmapMatch( pBrApp->back_buffer, BR_PMMATCH_DEPTH_16 );
  
      if ( !pBrApp->depth_buffer )
      {
         BR_ERROR0("Could not allocate depth buffer");
         return BRE_FAIL ;
      }
   }
   else 
      pBrApp->depth_buffer = NULL ;

   return BRE_OK ;
}


// -----------------------------------------------------------------
// Function : BrDemo_Refresh_Pointers
//
// Description : Updates app's copy of the pixelmap pointers.
// -----------------------------------------------------------------


br_error BrDemo_Refresh_Pointers( br_pixelmap **screen, 
                        br_pixelmap **back_buffer,
                        br_pixelmap **depth_buffer )
{
    // Load up the app's copy
   
   *screen = BrWinApp.screen ;
    *back_buffer = BrWinApp.back_buffer ;

    if ( depth_buffer )
       *depth_buffer = BrWinApp.depth_buffer ;

   return BRE_OK ;
}


// -----------------------------------------------------------------
// Function : BrDemo_PaletteSet
//
// Description : Sets the palette, and keeps an internal pointer to
// the palette, so we can set it when Windows asks us to.
// -----------------------------------------------------------------

br_error BrDemo_PaletteSet( br_pixelmap *pNewPal )
{
   BrWinApp.palette = pNewPal ;

   BrPixelmapPaletteSet( BrWinApp.screen, BrWinApp.palette );
   BrWinApp.back_buffer = BrWinApp.palette ;
    
   return BRE_OK ;
}


// -----------------------------------------------------------------
// Function : BrDemo_Allocate_Pixelmaps
//
// Description : Creates device using BrDemo_Allocate_Pixelmaps_Int,
// sets app's pointers, and marks the app as active.
// -----------------------------------------------------------------


br_error BrDemo_Allocate_Pixelmaps( char *AppName,
                           br_pixelmap **screen, 
                            br_pixelmap **back_buffer,
                            br_pixelmap **depth_buffer, 
                            br_pixelmap **palette, 
                            char *palette_filename )
{
   br_error r ;
   static bFirstTime = BR_TRUE ;
   static HMENU hMenu ;
   HWND hOldWnd ;
   
   BrWinApp.bUsePalette = palette != NULL ;
   BrWinApp.bUseZBuffer = depth_buffer != NULL ;
   
   if ( AppName )
      BrWinApp.name = AppName ;
   else
      BrWinApp.name = "BRender Demo" ;

   hOldWnd =  BrWinApp.hWnd;

   if ( bFirstTime )
   {
      hMenu = BrDemo_Load_And_Update_Menu(&BrWinApp);
      bFirstTime = BR_FALSE ;
   }
   
   if ( BrWinApp.bFullScreen )
   {
#if 0
           BrWinApp.hWnd = CreateWindowEx(
          WS_EX_TOPMOST,
          //WS_OVERLAPPEDWINDOW,
          "BrDemoClass",
          BrWinApp.name,
          WS_POPUP,
          0, 0,
          GetSystemMetrics( SM_CXSCREEN ),
          GetSystemMetrics( SM_CYSCREEN ),
          NULL,
          NULL,
          GetModuleHandle(NULL),
          NULL );
#else
		/* Only put up a window so I can see the debugger!*/
#if 1
           BrWinApp.hWnd = CreateWindowEx(0, "BrDemoClass", BrWinApp.name, WS_OVERLAPPEDWINDOW,
       CW_USEDEFAULT, CW_USEDEFAULT, 656, 522, NULL, NULL, GetModuleHandle(NULL), NULL);
#else
           BrWinApp.hWnd = CreateWindowEx(
          WS_EX_TOPMOST,
          //WS_OVERLAPPEDWINDOW,
          "BrDemoClass",
          BrWinApp.name,
          WS_POPUP,
          0, 0,
          GetSystemMetrics( SM_CXSCREEN ),
          GetSystemMetrics( SM_CYSCREEN ),
          NULL,
          NULL,
          GetModuleHandle(NULL),
          NULL );
#endif



#endif
   }
   else
   {
           BrWinApp.hWnd = CreateWindowEx(0, "BrDemoClass", BrWinApp.name, WS_OVERLAPPEDWINDOW,
       CW_USEDEFAULT, CW_USEDEFAULT, 656, 522, NULL, NULL, GetModuleHandle(NULL), NULL);
   }

   if ( BrWinApp.hWnd == NULL )
       return BRE_FAIL ;

   // Attach menu
  
   SetMenu( BrWinApp.hWnd, hMenu );

   // Show and update window

   ShowWindow( BrWinApp.hWnd, SW_SHOWDEFAULT );
   UpdateWindow( BrWinApp.hWnd );

//   DestroyWindow(hOldWnd);

   if ( palette_filename  )
       BrWinApp.palette_filename = BrMemStrDup( palette_filename );
   else
      BrWinApp.palette_filename = NULL ;
      
   r =  BrDemo_Allocate_Pixelmaps_Int(&BrWinApp);
   
   if ( r != BRE_OK )
      return r ;

   BrDemo_Refresh_Pointers( screen, back_buffer, depth_buffer );

   if ( palette )
        *palette = BrWinApp.palette ;

   BrWinApp.bActive = BR_TRUE ;
   
	InitialiseSound(BrWinApp.hWnd);
  return BRE_OK ;
}


// -----------------------------------------------------------------
// Function : BrDemo_Remove_Device
//
// Description : Closes down app and current device.
// -----------------------------------------------------------------

br_error BrDemo_Remove_Device( WIN_BITS_PTR pBrApp )
{
   br_error r ;

   // Remove the menu pointer, 'cause we don't want the menu to
   // be freed up when we kill the window.

   SetMenu( BrWinApp.hWnd, NULL );
   
   r = BrDemo_ShutDown();

   BrEnd();

   pBrApp->screen = NULL ;

   return r ;
}


// -----------------------------------------------------------------
// Function : BrDemo_Restart
//
// Description : Allows the app to restart itself by shutting it
//               down, then firing it up again. Currently only
//               used in Forest.
// -----------------------------------------------------------------

br_error BrDemo_Restart()
{
   BrDemo_Remove_Device(&BrWinApp);
   BrDemo_ClearAppMenuItems();
   BrDemo_Initiallise_BRender();

   return BRE_OK ;
}


// -----------------------------------------------------------------
// Function : BrDemo_WindowProc
//
// Description : Windows message handling function.
// -----------------------------------------------------------------

   
static   int client_width, client_height;
static LRESULT CALLBACK BrDemo_WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{   
   switch(message) 
   {
      case WM_COMMAND:
         BrDemo_HandleMenuSelection( &BrWinApp, LOWORD(wParam) );
         break ;
   
      case WM_CLOSE:
		 BrDemo_AboutToQuit();
         BrDemo_Remove_Device(&BrWinApp);
         DestroyWindow(hWnd);
         PostQuitMessage(0);
         break ;


      case WM_LBUTTONDOWN: bLeftButtonDown = BR_TRUE ;
                           SetCapture(hWnd);
                           break ;

      case WM_RBUTTONDOWN: bRightButtonDown = BR_TRUE ;
                           SetCapture(hWnd);
                           break ;


      case WM_LBUTTONUP: bLeftButtonDown = BR_FALSE ;

                         if ( !bRightButtonDown)
                            ReleaseCapture();
                         break ;

      case WM_RBUTTONUP: bRightButtonDown = BR_FALSE ;

                         if ( !bLeftButtonDown)
                           ReleaseCapture();
                         break ;

      case WM_MOUSEMOVE : 
     
        BrWinApp.xMousePos = LOWORD(lParam);  // horizontal position of cursor 
        BrWinApp.yMousePos = HIWORD(lParam);  // vertical position of cursor 
        break ;

       case WM_SYSKEYDOWN :    if ( wParam == VK_RETURN )
                      {
                         BrDemo_Toggle_Fullscreen(&BrWinApp);
                         return 0 ;
                      }
      
      case WM_KEYDOWN : BrWinRegisterKeyState( (br_uint_16) wParam, 1, (br_uint_16) (lParam&0xFFFF) );
                        return 0 ;              
                    

       case WM_KEYUP   : BrWinRegisterKeyState( (br_uint_16) wParam, 0, (br_uint_16) (lParam&0xFFFF) );
                        return 0 ;
                    
       case WM_PALETTECHANGED:
          if((HWND)wParam == hWnd)
             break;

       // Realise palette

       case WM_QUERYNEWPALETTE:
          if( BrWinApp.screen && BrWinApp.palette )
             BrPixelmapPaletteSet( BrWinApp.screen, BrWinApp.palette );
          break;

      // Window size has changed

      case WM_SIZE:

         // Ignore message : On window creation,
         // if we haven't initiallised yet, and when we are in
         // full screen mode.

      client_width  = (int)LOWORD(lParam);
      client_height = (int)HIWORD(lParam);

      if ( (lParam == 0) || !BrWinApp.bActive || BrWinApp.bFullScreen )
         break;

      if ( !BrWinApp.screen )
                  break ;
          
          // Extract client area dimensions

      // Resize screen pixelmap

      BrPixelmapResize( BrWinApp.screen, client_width, client_height );
          
      // If we're not doing a stretch blit, the offscreen and
      // Z buffer will need resizing too.
      
      if ( !BrWinApp.bStretch ) 
      {
         // Resize colour_buffer pixelmap

         if ( BrWinApp.back_buffer )
                BrPixelmapResize( BrWinApp.back_buffer, client_width, client_height );
   
          // Resize depth pixelmap

          if ( BrWinApp.depth_buffer )
            BrPixelmapResize( BrWinApp.depth_buffer, client_width, client_height);
          }

       BrDemo_OnResize();

          break;

   default:
      return DefWindowProc(hWnd, message, wParam, lParam);
   }

   return 0;
}


// -----------------------------------------------------------------
// Function : BrWinError, BrWinWarning
//
// Description : BRender Windows error handler. 
// -----------------------------------------------------------------

static void BR_CALLBACK BrWinError(char *message)
{
    //OutputDebugString( message );

    MessageBox( BrWinApp.hWnd, message, BrWinApp.name, MB_OK );
    PostQuitMessage(0);
}


static void BR_CALLBACK BrWinWarning(char *message)
{
    //OutputDebugString( message );
    MessageBox( BrWinApp.hWnd, message, BrWinApp.name, MB_OK );
}

// Brender diagnostic handler that uses Windows

br_diaghandler BrWinErrorHandler = 
{
   "Windows BRender Error Handler",
   BrWinWarning,
   BrWinError, 
};



// -----------------------------------------------------------------
// Function : BrDemo_Generate_Valid_Materials_Callback
//
// Description : Makes sure that all loaded materials are valid on 
// the current device.
// -----------------------------------------------------------------

br_uint_32 BR_CALLBACK BrDemo_Generate_Valid_Materials_Callback( br_material *pMat, void *user )
{
   if ( ( BrWinApp.back_buffer->type == BR_PMT_RGB_555 ) ||
        ( BrWinApp.back_buffer->type == BR_PMT_RGB_565 ) )
   {
      if ( pMat->colour_map )
      {
         if ( pMat->colour_map->type == BR_PMT_INDEX_8 )
         {
            pMat->flags |= BR_MATF_LIGHT ;
            BrMaterialUpdate( pMat, BR_MATU_ALL );
         }
      }
   }

   return 0 ;
}


// -----------------------------------------------------------------
// Function : BrDemo_Initiallise_BRender
//
// Description : Starts up BRender, initillises error handler,
// keyboard, initialises demo, and makes sure all materials are valid.
// -----------------------------------------------------------------


br_error BrDemo_Initiallise_BRender()
{     
   BrBegin();

   if(BrWinApp.useMmx)
      BrSystemConfigSetString(BRT_BRENDER_DRIVERS_STR,mmxName);
   else
      BrSystemConfigSetString(BRT_BRENDER_DRIVERS_STR,"");

   
   BrErrorHandlerSet(&BrWinErrorHandler);
 
   WinKeyBegin();
  
   // *********************************************************

   // To do : Simulate DOS argc and argv, then send to Init_App

   // *********************************************************
   

   if ( BrDemo_InitApp( argc, argv ) != BRE_OK )
   {
      BR_WARNING0( "Could not initialize application" );
      return BRE_FAIL ;
   }

   BrMaterialEnum( NULL, BrDemo_Generate_Valid_Materials_Callback, NULL  );

   return BRE_OK ;
}


// -----------------------------------------------------------------
// Function : BrDemo_Toggle_Fullscreen
//
// Description : Toggles full screen mode on / off 
//   - via ALT-ENTER keypress.
// -----------------------------------------------------------------


br_error BrDemo_Toggle_Fullscreen( WIN_BITS_PTR pBrApp )
{
    br_error r ;

   // Toggle fullscreen flag

   pBrApp->bFullScreen ^= 1 ;

   // Remove old device. and kill app

   BrDemo_Remove_Device(pBrApp);
   BrDemo_ClearAppMenuItems();

   // Restart app using new device.

   r = BrDemo_Initiallise_BRender();

   if ( r != BRE_OK )
   {
      BR_ERROR0("Could not start device !");
      return r ;
   }
 
   // Check the appropriate device menu entries
   
   BrDemo_SetDeviceMenuChecks(pBrApp);

   return r ;
}


// -----------------------------------------------------------------
// Function : WinMain
//
// Description : It all starts here ...
// -----------------------------------------------------------------

int PASCAL WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    LPSTR lpCmdLine, int nCmdShow)

{
   MSG msg ;
   WNDCLASS wclass;
   br_error r ;

   BrWinApp.useMmx = BR_FALSE ;
   BrWinApp.bActive = BR_FALSE ;
   BrWinApp.Offscreen_Height = 100 ;
   BrWinApp.Offscreen_Width = 100 ;
   BrWinApp.bStretch = BR_FALSE ;    
   BrWinApp.Width = 0 ;
   BrWinApp.Height = 0 ;
   BrWinApp.hInst=hInstance;

   // Parse Command Line

   argv[0] = "DUMMY.EXE";
   argv[1] = strtok(lpCmdLine," ");
   argc = 2;

   szFileBuffer[0]='\0';
   
   if (argv[1]) {
      while (argv[argc] = strtok(NULL," ")) {
         argc++;
      }
   }
   else argc--;

   // This will be overriden in BrDemoOutputFacilityEnumCb if the
   // current device supports windowed mode.

   BrWinApp.bFullScreen = BR_TRUE ;
   
   // Set initial device to software only.
   
   BrWinApp.Current_Device = BR_DEMO_INITIAL_DEVICE ;

   // Register a new window class for BRender output.

   wclass.style = CS_HREDRAW | CS_VREDRAW;
   wclass.lpfnWndProc = BrDemo_WindowProc;
   wclass.cbClsExtra = 0;
   wclass.cbWndExtra = 0;
   wclass.hInstance = hInstance;
   wclass.hIcon = LoadIcon(hInstance, IDI_APPLICATION);
   wclass.hCursor = LoadCursor(NULL, IDC_ARROW);
   wclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
   wclass.lpszMenuName = NULL;
   wclass.lpszClassName = "BrDemoClass";
   RegisterClass(&wclass);
 
   r = BrDemo_Initiallise_BRender();

   if ( r != BRE_OK )
      return 0 ;

   // Redraw menu bar incase the app has added any items
   //  - Currently only done in Forest.

   DrawMenuBar( BrWinApp.hWnd );
   
   while (1)
   {
        if ( PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE ) )
        {
            if( !GetMessage( &msg, NULL, 0, 0 ) )
            {
               return msg.wParam;
            }   

            TranslateMessage(&msg); 
            DispatchMessage(&msg);
        }

      if ( BrDemo_Render_Loop() != BRE_OK )
        break ;

      BrDemo_DoTiming( &BrWinApp );
   }

   PostQuitMessage(0);
   return 0 ;
}

void BrDemo_MakeSmallLoop(void)
{
   MSG msg ;
   if ( PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE ) )
   {
       if( !GetMessage( &msg, NULL, 0, 0 ) )
       {
          return;//msg.wParam;
       }   
       TranslateMessage(&msg); 
       DispatchMessage(&msg);
   }

}


int msx,msy,clw,clh;

// -----------------------------------------------------------------
// Function : WinMouseRead
//
// Description : Emulation of the DOSMouseRead call
// -----------------------------------------------------------------

br_error BR_PUBLIC_ENTRY WinMouseRead( br_int_32 *mouse_x, br_int_32 *mouse_y, br_uint_32 *Buttons )
{
   static br_boolean bFirstTime = BR_TRUE ;
#if 0
   static br_int_32 ox = 0, oy = 0 ;
#endif

   *Buttons = 0 ;
   
   if ( bLeftButtonDown )
      *Buttons |= BR_MSM_BUTTONL ;

   if ( bRightButtonDown )
      *Buttons |= BR_MSM_BUTTONR ;

#if 0
   if ( bFirstTime )
   {
      *mouse_x = 0 ;
      *mouse_y = 0 ;
      bFirstTime = BR_FALSE ;
   }
   else
   {
      *mouse_x += BrWinApp.xMousePos - ox;
      *mouse_y += BrWinApp.yMousePos - oy;
   }

   ox = BrWinApp.xMousePos ;
   oy = BrWinApp.yMousePos ;

#endif

	/* Horrible hack to make mouse position relative to the mouse over the window for a */
	/* fixed resolution of 640x480 */
	msx = BrWinApp.xMousePos ;
	msy = BrWinApp.yMousePos ;

	clw = client_width;
	clh = client_height;
	if ( bFirstTime )
	{
		*mouse_x = 0 ;
		*mouse_y = 0 ;
		bFirstTime = BR_FALSE ;
	}
	if (msy>=0 && msy<=4096 && msx>=0 && msx<=4096 && clw != 0 && clh != 0)
	{

		*mouse_x=((640*msx)/clw)-320;
		*mouse_y=((480*msy)/clh)-240;
	}

   return BRE_OK ;
}


// -----------------------------------------------------------------
// Function : BrDemo_ResizeOffScreenBuffers
//
// Description : Resizes offscreen buffers, as a result of selecting
// one of the View->Stretch menu items.
// -----------------------------------------------------------------


br_error BrDemo_ResizeOffScreenBuffers( WIN_BITS_PTR pBrApp, 
                               br_uint_16 w, br_uint_16 h )
{
   if ( pBrApp->back_buffer )
      BrPixelmapResize( pBrApp->back_buffer, w, h );

   if ( pBrApp->depth_buffer )
      BrPixelmapResize( pBrApp->depth_buffer, w, h );

   BrDemo_OnResize();

   return BRE_OK ;
}

// -----------------------------------------------------------------
// Function : WinMouseReadAbsolute
//
// Description : Gets the absolute mouse coords.
// -----------------------------------------------------------------

void WinMouseReadAbsolute( br_pixelmap *screen, br_int_32 *mouse_x, br_int_32 *mouse_y )
{
    *mouse_x = BrWinApp.xMousePos ;
   *mouse_y = BrWinApp.yMousePos ;
}

// -----------------------------------------------------------------
// Function : WinClockRead
//
// Description : Emulation of DOSClockRead.
// -----------------------------------------------------------------

br_uint_32 BR_PUBLIC_ENTRY WinClockRead()
{
    LARGE_INTEGER This_Time ;
   
   QueryPerformanceCounter( &This_Time );
    
   return This_Time.LowPart ;
}

// -----------------------------------------------------------------
// Function : WinGetClockFreq
//
// Description : Gets frequency of processor's performance counter
//  - only works on Pentium and above.
// -----------------------------------------------------------------

br_uint_32 WinGetClockFreq()
{
   static br_boolean bFirstTime = BR_TRUE ;
   static LARGE_INTEGER Freq ;

   if ( bFirstTime )
    {
        bFirstTime = BR_FALSE ;
        QueryPerformanceFrequency( &Freq );
    }

   return Freq.LowPart ;

}


// -----------------------------------------------------------------
// Function : BrDemo_SetRootActor
//
// Description : Sets the root actor used by some of the Options menu
// callbacks.
// -----------------------------------------------------------------

br_error BrDemo_SetRootActor( br_actor *pActor )
{
   BrWinApp.pRoot = pActor ;
   return BRE_OK ;
}

// -----------------------------------------------------------------
// Function : BrDemo_FileRequest
//
// Description : Opens a file requester with a supplied wild card
// and then picks it or returns NULL.
// -----------------------------------------------------------------

char *BrDemo_FileRequest( char *title, int exist )
{

    DWORD   dwCDErr = 0;
    BOOL    bResult = FALSE;
    UINT    uCharsRead;

	OPENFILENAME    ofn;
    /*
     * Clear out and fill in an OPENFILENAME structure in preparation
     * for creating a common dialog box to open a file.
     */

    memset( szOpenFilter, 0, sizeof(szOpenFilter));
    uCharsRead = LoadString( BrWinApp.hInst, IDS_OPEN_FILTER1,
                szOpenFilter, sizeof(szOpenFilter)) + 1;
    uCharsRead += LoadString( BrWinApp.hInst, IDS_OPEN_FILTER2,
                    &szOpenFilter[uCharsRead],
                    sizeof(szOpenFilter) - uCharsRead ) + 1;
    uCharsRead += LoadString( BrWinApp.hInst, IDS_OPEN_FILTER3,
                    &szOpenFilter[uCharsRead],
                    sizeof(szOpenFilter) - uCharsRead ) + 1;
    LoadString( BrWinApp.hInst, IDS_OPEN_FILTER4,
                    &szOpenFilter[uCharsRead],
                    sizeof(szOpenFilter) - uCharsRead );

	strcpy(szOpenDLGTitle,title);

	strcpy(szFileBuffer,"p:\\cult\\martinp\0");
	memset( &ofn, 0, sizeof(OPENFILENAME));
    ofn.lStructSize = sizeof(OPENFILENAME);
    ofn.hwndOwner   = BrWinApp.hWnd;
    ofn.hInstance   = BrWinApp.hInst;
    ofn.lpstrFilter = szOpenFilter;
    ofn.nFilterIndex    = 1;
    ofn.lpstrFile   = szFileBuffer;
    ofn.nMaxFile    = sizeof(szFileBuffer);
    ofn.lpstrFileTitle  = szFileTitle;
    ofn.nMaxFileTitle   = sizeof(szFileTitle);
    ofn.lpstrDefExt = "3DS";
    ofn.lpstrTitle  = szOpenDLGTitle;
	if (exist)
		ofn.Flags       = OFN_FILEMUSTEXIST;

    bResult = GetOpenFileName( &ofn ); /* Do the dialog box */

    /*
     *  A return of TRUE indicates that the user did not select a filename.
     * The possible reasons are: Cancel was clicked, or an error occured.
     * If Cancel was clicked, the CommDlgExtendedError() function will not
     * return a valid code.  For anything else, an error code will come back.
     */
                    if( bResult == FALSE )
                    {
                        dwCDErr = CommDlgExtendedError();
                        if( dwCDErr )
                        {
                            /* Handle a common dialog box error */
                            //HandleCommDlgError( dwCDErr );
							return NULL;
                        }
                        else    /* Clicked Cancel, so finish msg processing */
                            return NULL;
                    }
                    else
                    {
							return szFileBuffer;
                    }
   return szFileBuffer ;
}


/* Open a file requestor for any type of file open box either for saving or loading */
/* Format of the open filer is: "<long description>\0<wildcard ext>\0 */
/* eg. "3D Studio Files (*.3DS)\0*.3DS\OAll Files (*.*)\0*.*\0" */
char *BrDemo_AnyFileRequest( char *title, int exist ,char *openfilter, char *filebuffer, char *defext)
{

    DWORD   dwCDErr = 0;
    BOOL    bResult = FALSE;
	static int firsttime=BR_TRUE;

	OPENFILENAME    ofn;
    /*
     * Clear out and fill in an OPENFILENAME structure in preparation
     * for creating a common dialog box to open a file.
     */

	memset( &ofn, 0, sizeof(OPENFILENAME));
    ofn.lStructSize = sizeof(OPENFILENAME);
    ofn.hwndOwner   = BrWinApp.hWnd;
    ofn.hInstance   = BrWinApp.hInst;
    ofn.lpstrFilter = openfilter;
    ofn.nFilterIndex    = 1;
    ofn.lpstrFile   = filebuffer;
    ofn.nMaxFile    = 256;
    ofn.lpstrFileTitle  = szFileTitle;
    ofn.nMaxFileTitle   = 256;
    ofn.lpstrDefExt = defext;
    ofn.lpstrTitle  = title;
	if (exist)
		ofn.Flags       = OFN_FILEMUSTEXIST;

    bResult = GetOpenFileName( &ofn ); /* Do the dialog box */

    /*
     *  A return of TRUE indicates that the user did not select a filename.
     * The possible reasons are: Cancel was clicked, or an error occured.
     * If Cancel was clicked, the CommDlgExtendedError() function will not
     * return a valid code.  For anything else, an error code will come back.
     */
                    if( bResult == FALSE )
                    {
                        dwCDErr = CommDlgExtendedError();
                        if( dwCDErr )
                        {
                            /* Handle a common dialog box error */
                            //HandleCommDlgError( dwCDErr );
									return NULL;
                        }
                        else    /* Clicked Cancel, so finish msg processing */
                            return NULL;
                    }
                    else
                    {
							return szFileBuffer;
                    }
   return NULL ;
}

