// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= //
//
//  Project:   Talina Gaming System (TgS) (∂)
//  File:      TgS (W32) Common - Base Defines.h
//  Author:    Andrew Aye (EMail: mailto:andrew.aye@gmail.com, Web: http://www.andrewaye.com)
//  Version:   4.0
//
// ------------------------------------------------------------------------------------------------------------------------------ //
//
//  Copyright: © 2002-2010, Andrew Aye.  All Rights Reserved.
//
//  This software is free for non-commercial use. Redistribution and use in source and binary forms, with or without modification,
//  are permitted provided that the following conditions are met: 
//    Redistributions of source code must retain this copyright notice, this list of conditions and the following disclaimers. 
//    Redistributions in binary form must reproduce this copyright notice, this list of conditions and the following
//      disclaimers in the documentation and other materials provided with the distribution. 
//
//  Neither the names of the copyright owner nor the names of its contributors may be used to endorse or promote products derived
//  from this software without specific prior written permission. 
//
//  The intellectual property rights of the algorithms used reside with Andrew Aye.  You may not use this software, in whole or
//  in part, in support of any commercial product without the express written consent of the author.
//
//  There is no warranty or other guarantee of fitness of this software for any purpose. It is provided solely "as is".
//
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= //
#if !defined(_TGS_W32_COMMON_BASE_DEFINES_H_)
#define _TGS_W32_COMMON_BASE_DEFINES_H_
#pragma once

// ============================================================================================================================== //
// -- Configuration ------------------------------------------------------------------------------------------------------------- //

#if defined(_M_X64)
    #define _AMD64_
    #define __X64__
#elif defined(_M_IX86)
    #define _X86_
    #define __X86__
#else
    #error Unknown platform
#endif

#if defined(__X64__)
    #define TgCOMPILE_64BIT_POINTER             1
#else
    #define TgCOMPILE_64BIT_POINTER             0
#endif

#define TgS_PASS_BY_VALUE                   0

#include "TgS COMMON/TgS Common - Base - Defines.h"

#undef TgPASSINREG
#undef TgALLOCA
#undef TgFREEA
#undef TgPLATFORM_THREAD
#undef TgPLATFORM_THREAD_TAIL
#undef TgPLATFORM_THREAD_STOP

#if TgS_WIDE_CHAR
    #define UNICODE                             1
#endif


// ============================================================================================================================== //
// -- Compiler Macros ----------------------------------------------------------------------------------------------------------- //

#define DLL_IMPORT                          __declspec(dllimport)       /* Import function from DLL */
#define DLL_EXPORT                          __declspec(dllexport)       /* Export function to DLL */
#define CDECL                               __cdecl                     /* Standard C function */
#define STDCALL                             __stdcall                   /* Standard calling convention */
#define TgFORCEINLINE                       __forceinline               /* Force code to be TgFORCEINLINE */
#define TgINLINE                            __inline
#define TgALIGN(A)                          __declspec(align(A))
#define TgPASSINREG
#define TgTLS                               __declspec( thread )
#define TgALIAS                             
#define TgERROR_NOT_IMPLEMENTED             TgCOMPILER_ASSERT_MSG(TgFALSE, "Not Implemented")
#define TgATOMIC_INT32                      volatile long
#define TgATOMIC_INT64                      volatile __int64
#define TgBREAK_INLINE                      __debugbreak()
#define TgCHAR_PATH_SEPERATOR               '/'
#define TgSTRING_PATH_SEPERATOR             "/"
#define TgEXPECT_TRUE(...)                  (__VA_ARGS__)
#define TgEXPECT_FALSE(...)                 (__VA_ARGS__)


// ============================================================================================================================== //
// -- Code Macros --------------------------------------------------------------------------------------------------------------- //

#define TgMAKE_4CC(A,B,C,D)                 (TgUINT32)((D & 0XFF) << 24) | ((C & 0XFF) << 16) | ((B & 0XFF) << 8) | ((A & 0XFF) << 0)
#define TgCOLOUR_FROM_RGBA(R,G,B,A)         (TgUINT32)((A & 0XFF) << 24) | ((B & 0XFF) << 16) | ((G & 0XFF) << 8) | ((R & 0XFF) << 0)
#define TgCOLOUR_A(COL_U32)                 ((COL_U32 >> 24) & 0xFF)
#define TgCOLOUR_B(COL_U32)                 ((COL_U32 >> 16) & 0xFF)
#define TgCOLOUR_G(COL_U32)                 ((COL_U32 >>  8) & 0xFF)
#define TgCOLOUR_R(COL_U32)                 ((COL_U32      ) & 0xFF)
#define TgFREEA( VAR )                      _freea( VAR );
#define TgPLATFORM_THREAD(A,B)              unsigned int A ( void * B )
#define TgPLATFORM_THREAD_TAIL(A)           _endthreadex( A ); return (A);
#define TgPLATFORM_THREAD_STOP(A)           _endthreadex( A );
#define TgMAIN_FUNCTION                     int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
#define TgMAIN_PLATFORM_GLOBAL_INIT         g_hInstance = hInstance
#define TgMAIN_PLATFORM_GLOBAL_FREE         g_hInstance = 0
#define TgALLOCA( TYPE, COUNT, VAR )                                                                                               \
{                                                                                                                                  \
    VAR =  (TYPE *)_malloca( (COUNT) * sizeof(TYPE) );                                                                             \
    if ((*(unsigned int *)((char*) VAR - _ALLOCA_S_MARKER_SIZE)) == _ALLOCA_S_STACK_MARKER)                                        \
    {                                                                                                                              \
        TgLOGF( KTgCON_CHANEL_LOG | KTgCON_SEVERITY_6, TgT("Allocated %d  bytes of stack\n"),(COUNT) * sizeof(TYPE) );     \
    }                                                                                                                              \
    else                                                                                                                           \
    {                                                                                                                              \
        TgLOGF( KTgCON_CHANEL_LOG | KTgCON_SEVERITY_6, TgT("Allocated %d  bytes of heap\n"), (COUNT) * sizeof(TYPE) );     \
    }                                                                                                                              \
}

#endif //  END  ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////