//////////////////////////////////////////////////////////////////////
//
// Project  : BRender Demo Framework
//            Copyright (c) 1996 Argonaut Technologies Ltd.
//            All rights reserved.
//
// Author   : Steve Williams, October 1996
//
// File     : DOS_BITS.C
//
// Requires : BRender V1.3
//            
//
// Comments : DOS specific module
//
//////////////////////////////////////////////////////////////////////

#include <brender.h>
#include <stdio.h>
#include <stdlib.h>
#include "timing.h"
#include <dosio.h>
#include "dos_bits.h"

// Application defaults ...

#define WIDTH 320
#define HEIGHT 200
#define BPP 8
#define FULLSCREEN 0

 
static DOS_BITS BrDOSApp ;


// Simple Brender diagnostic handler

static void BR_CALLBACK BrDOSWarning(char *message);
static void BR_CALLBACK BrDOSError(char *message);


static br_diaghandler BrDOSErrorHandler = 
{
	"DOS BRender Error Handler",
	BrDOSWarning,
	BrDOSError, 
};



int main( int argc, char **argv )
{
   BrBegin();

   BrErrorHandlerSet(&BrDOSErrorHandler);

   if ( BrDemo_InitApp( argc, argv ) != BRE_OK )
   {
       BrEnd();
       return 0 ;
   }

	// Setup keyboard, mouse and clock

	DOSMouseBegin();
	DOSKeyBegin();
   DOSClockBegin();

   // Ensure that the materials we've set up are valid in this
   // screen mode.
      
   BrMaterialEnum( NULL, BrDemo_Generate_Valid_Materials_Callback, NULL  );

   while (1)
   {
      if ( BrDemo_Render_Loop() != BRE_OK )
         break ;

      Do_Timing( BrDOSApp.screen );
   }

   BrDemo_ShutDown();

	DOSMouseEnd();
	DOSKeyEnd();
   DOSClockEnd();
   BrEnd();

   return 0 ;
}






br_error BrDemo_Allocate_Pixelmaps( char *name,
                      br_pixelmap **screen, 
							 br_pixelmap **back_buffer,
							 br_pixelmap **depth_buffer, 
							 br_pixelmap **palette, 
							 char *palette_filename )
{
	br_error r ;
	
   // Create BRender device
   
   r = BrDevBegin( &BrDOSApp.screen, NULL);

   if ( !BrDOSApp.screen || ( r != BRE_OK ) )
   {
    	char Device[100];
      BrSystemConfigQueryString( BRT_DEFAULT_DEVICE_STR, Device, 100 );

      BR_ERROR1("Could not start device '%s'", Device );
      return BRE_FAIL ;
   }


   if ( palette )
   {
       BrDOSApp.palette = BrPixelmapLoad(palette_filename);

       if ( !palette )
          BR_ERROR0("Could not load palette");
   }
   else	
      BrDOSApp.palette = NULL ;

	if ( BrDOSApp.palette )
   {
      BrPixelmapPaletteSet( BrDOSApp.screen, BrDOSApp.palette );
      BrDOSApp.back_buffer->map = BrDOSApp.palette ;
   }

   // Hardwire for now.

   BrDOSApp.bStretch = BR_FALSE ;

	// Allocate other buffers

   if ( BrDOSApp.bStretch )
		BrDOSApp.back_buffer = BrPixelmapMatchSized( BrDOSApp.screen, BR_PMMATCH_OFFSCREEN, BrDOSApp.Offscreen_Width, BrDOSApp.Offscreen_Height );
	else
	   BrDOSApp.back_buffer = BrPixelmapMatch( BrDOSApp.screen, BR_PMMATCH_OFFSCREEN );

   if ( !BrDOSApp.back_buffer )
      BR_ERROR0("Could not allocate back buffer");
    
	if ( depth_buffer )
   {
      BrDOSApp.depth_buffer = BrPixelmapMatch( BrDOSApp.back_buffer, BR_PMMATCH_DEPTH_16 );
 
      if ( !BrDOSApp.depth_buffer )
         BR_ERROR0("Could not allocate back buffer");
   }
   else
      BrDOSApp.depth_buffer = NULL ;

	*screen = BrDOSApp.screen ;
   *back_buffer = BrDOSApp.back_buffer ;

   if ( depth_buffer )
   	*depth_buffer = BrDOSApp.depth_buffer ;

   if ( palette )
   	*palette = BrDOSApp.palette ;
	
	return BRE_OK ;
}




// Error handler callbacks

static void BR_CALLBACK BrDOSError(char *message)
{
	DOSMouseEnd();
	DOSKeyEnd();
   DOSClockEnd();
   BrEnd();

   printf(message);
   printf("\n\n");
   exit(0);
}


static void BR_CALLBACK BrDOSWarning(char *message)
{
   printf(message);   
}




// These are just stubs for now, and are only here for consistancy
// with the Windows framework. 

void DOSMouseReadAbsolute( br_pixelmap *screen, br_int_32 *mouse_x, br_int_32 *mouse_y )
{
}

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

br_error BrDemo_Restart() {
   return BRE_OK;
}

br_error BrDemo_AddMenuItem(char *Name, void * pCallback) {
   return BRE_OK;
}

br_error BrDemo_PaletteSet(br_pixelmap *pNewPal) {

   BrDOSApp.palette = pNewPal;
   BrPixelmapPaletteSet(BrDOSApp.screen,BrDOSApp.palette);
   BrDOSApp.back_buffer->map = BrDOSApp.palette ;

   return BRE_OK;
}

br_error BrDemo_Refresh_Pointers( br_pixelmap **screen, 
							   br_pixelmap **back_buffer,
							   br_pixelmap **depth_buffer )
{
   return BRE_OK ;
}

//////////////////////////////////////////////////////////////////
//
// Function : BrDemo_Generate_Valid_Materials_Callback
//
// 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 ( ( BrDOSApp.back_buffer->type == BR_PMT_RGB_555 ) ||
        ( BrDOSApp.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 ;
}


