////////////////////////////////////////////////////////////////////////////////
//
// Copyright 2016 RWS Inc, All Rights Reserved
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of version 2 of the GNU General Public License as published by
// the Free Software Foundation
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
///////////////////////////////////////////////////////////////////////////////
//
//	bmain.cpp
// 
// History: 06/03/2004  RCG added.
//          11/17/2020  Dreamcast port added
//
//////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////
//
// This module was inspired by "RSPiX - The Making of an Engine (RAINBOW
// DESCRIPTION)" by Jeff Diamond, 4/19/95.  Please see that document for
// further details.
//
//////////////////////////////////////////////////////////////////////////////

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <kos.h>

#ifndef WIN32
#include <unistd.h>
#include <sys/param.h>
#endif

#include <time.h>

// Blue //////////////////////////////////////////////////////////////////////
#include "Blue.h"
#include <malloc.h>

// todo
#include "../../../../PVR/pvr.h"

static int16_t ms_sQuit = 0;

extern uint32_t mstats(bool print) 
{    
    struct mallinfo mi = mallinfo();
    if (print)
    {
        printf("max system bytes = %10lu\n system bytes = %10lu\nin use bytes = %10lu\n", 
            (unsigned long)(mi.usmblks),(unsigned long)(mi.arena + mi.hblkhd), (unsigned long)(mi.uordblks + mi.hblkhd));        
    }
    else
    {
        return (uint32_t)(mi.uordblks + mi.hblkhd);
    }    
}

extern void Disp_Init(void);
extern void Key_Init(void);
extern void Joy_Init(void);

extern "C" int __cxa_thread_atexit(void (*func)(), void* obj,
    void* dso_symbol) {
    int __cxa_thread_atexit_impl(void (*)(), void*, void*);
    return __cxa_thread_atexit_impl(func, obj, dso_symbol);
}

//////////////////////////////////////////////////////////////////////////////
// 
//	Call this to init the blue library.  Calls init in the various blue modules
// that needing an init call.
//
// Returns 0 on success.
// 
//////////////////////////////////////////////////////////////////////////////

int16_t rspInitBlue(void)
	{
	int16_t	sRes	= 0;	// Assume success.

#ifdef BETAEXPIRE
    if ( time(NULL) > (BETAEXPIRE + 30 * 24 * 60 * 60) )
    {
        fprintf(stderr, "This beta has expired.\n\n");
        fflush(stderr);
        while (1) _exit(42);
    }
#endif

    pvr_set_pal_format(PVR_PAL_ARGB8888);

    // Set palette entries for text
    pvr_set_pal_entry(512, PACK_ARGB8888(0, 0, 0, 0));
    pvr_set_pal_entry(513, PACK_ARGB8888(255, 255, 255, 255));     
	Disp_Init();    
    Joy_Init();

	return sRes;
	}
		

//////////////////////////////////////////////////////////////////////////////
// 
//	Call this to kill the blue library (IF you called Blu_Init).
//
// Returns nothing.
// 
//////////////////////////////////////////////////////////////////////////////
void rspKillBlue(void)
	{
	    // Kill display module.    	
#ifndef _arch_dreamcast
    SDL_Quit();
#endif
	}

//////////////////////////////////////////////////////////////////////////////
// 
// Does tasks critical to Windows:
//		- Services our Windows message queue.
// Returns nothing.
// 
//////////////////////////////////////////////////////////////////////////////

extern void rspSetQuitStatus(int16_t sQuitStatus);

extern void Key_Event(int,int,bool);

bool GSDLAppIsActive = 1;

extern void rspDoSystem(void)										// Returns nothing.
{ 
    // todo: remove
}

//////////////////////////////////////////////////////////////////////////////
// 
// Sets the current mode with which the rspDoSystem cooperates with the OS.
// 
//////////////////////////////////////////////////////////////////////////////
extern void rspSetDoSystemMode(	// Returns nothing.
	int16_t sCooperativeLevel)		// In:  One of the RSP_DOSYSTEM_* macros 
											// defining what level of cooperation to use.
	{
        /* no-op */
	}

////////////////////////////////////////////////////////////////////////////////
//
// Get system-specific quit status.
//
////////////////////////////////////////////////////////////////////////////////
extern int16_t rspGetQuitStatus(void)				// Returns TRUE if quit detected, FALSE otherwise
	{
	return ms_sQuit;
	}


////////////////////////////////////////////////////////////////////////////////
//
// Set system-specific quit status.
//
// This allows the app to either clear the status to 0 or to set it to whatever
// other value that app might like.
//
////////////////////////////////////////////////////////////////////////////////
extern void rspSetQuitStatus(
	int16_t sStatus)										// In:  New status
	{
	ms_sQuit = sStatus;
	}


//////////////////////////////////////////////////////////////////////////////
// EOF
//////////////////////////////////////////////////////////////////////////////
