/*H**********************************************************************
* FILENAME : common.h START DATE : 10 Sept 16
*
* DESCRIPTION :
* Common functions to be used with all targets and platforms of SC-CL.
*
* NOTES :
* This file is part of SC-CL's include library.
*
* LICENSE :
*
* Copyright 2016 SC-CL
*
* 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 the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither SC-CL nor its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* * Redistribution of this software in source or binary forms shall be free
* of all charges or fees to the recipient of this software.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL SC-CL BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* AUTHORS :
* Rocko Tompkins
* Nathan James
*H*/
#pragma once
#include "types.h"
/// Swaps the endian of a int or short.
/// The value to be swapped.
///
#define SwapEndian(x) _Generic((x),\
short int: SwapEndian16(x), unsigned short int: SwapEndian16(x),\
default: SwapEndian32(x))
/// Safely divides a and b to avoid division by zero.
/// The left side value.
/// The right side value.
/// The divided value.
#define SafeDiv(x, y) _Generic((x),\
float: DivFloat(x, y), double: DivFloat(x, y),\
default: DivInt(x, y))
/// Swaps the endian of a int to a constant value.
/// The value to be swapped.
///
#define SwapEndian32Const(value) ((((value) & 0xff000000) >> 24) | (((value) & 0x00ff0000) >> 8) | (((value) & 0x0000ff00) << 8) | (((value) & 0x000000ff) << 24))
/// Converts degrees to radians.
/// The value to be converted.
/// The value converted to radians.
#define DegreesToRadians(degrees) (degrees * (PI / 180.0f))
/// Converts radians to degrees.
/// The value to be converted.
/// The value converted to degrees.
#define RadiansToDegrees(radians) (radians * (180.0f / PI))
#if TARGET == TARGET_RDR
#define ftos(flt, precision) _float_to_string(flt, 3, precision)
#else
#define ftos(flt, precision)
#endif
/// Prints the specified string to the subtitle buffer.
/// The string to be printed.
/// The milliseconds that the string should be printed for.
///
void print(const char* str, int ms);
/// Concatinates two strings into one using a global char buffer.
/// The first string to be added to the buffer.
/// The second string to be added to the buffer.
/// The pointer to the global char buffer.
const char* strcatGlobal(const char* str1, const char* str2);
/// Copies str into the global char buffer then concatinates it with the string representation of i.
/// The string to be added to the buffer.
/// The int to be converted and added to the buffer.
/// The pointer to the global char buffer.
const char* straddiGlobal(const char* str, int i);
/// Copies the string representation of i into the global char buffer.
/// The int to be converted and copied to the buffer.
/// The pointer to the global char buffer.
const char* itosGlobal(int i);
/// Prints the string as an exception for 10 seconds then exits the script.
/// The string to be printed.
///
void Throw(const char* str);
/// Prints the string as an warning for 5 seconds.
/// The string to be printed.
///
void Warn(const char* str);
/// Prints the string as an error for 5 seconds.
/// The string to be printed.
///
void Error(const char* str);
/// Swaps the endian of a int.
/// The value to be swapped.
///
int SwapEndian32(int value);
/// Swaps the endian of a short.
/// The value to be swapped.
///
short SwapEndian16(short value);
/// Divides a and b then rounds up.
/// The left side value.
/// The right side value.
/// The ceiled value.
int CeilDivInt(uint a, uint b);
/// Safely divides a and b to avoid division by zero.
/// The left side value.
/// The right side value.
/// The divided value.
int DivInt(int a, int b);
/// Safely divides a and b to avoid division by zero.
/// The left side value.
/// The right side value.
/// The divided value.
float DivFloat(float a, float b);
/// Converts a string representing a float to a float.
/// The string to convert.
/// The converted float value.
float StringToFloat(const char* str);
/// Converts a number to a hex string and stores it in a global char buffer.
/// The value to convert.
/// If to convert the hex result to lower case.
/// A pointer to the global char buffer.
const char* IntToHex(int val, bool isLowercase);
/// Converts a hex string to decimal.
/// Hex string to convert.
/// The decimal result.
int HexToInt(const char* hex);
/// Converts a base 10 integer to a specified base.
/// The base 10 integer.
/// The base to convert to.
/// The decimal representation of the new base.
int IntToBase(int n, int b);
/// Sets a bit at the bitIndex of a pointer to the specified value of bitValue.
/// The pointer to the value that will be changed.
/// The bit index of the bit relative to the pointer.
/// The bit value to be set at the index.
///
void SetBitAtIndex(int* valuePtr, uint bitIndex, bool bitValue);
/// Preforms a modulo operation an a negative number.
/// The left side value.
/// The right side value.
/// The modulo result.
int ModNegitive(int a, int b);
/// Converts a euler angle to a quaternion.
/// The euler angle to be converted.
/// The quaternion result.
quaternion EulerToQuaternion(vector3 euler);
/// Applies slow rotation to a look position eventualy converting it to endPos.
/// The current look position.
/// The end look position.
/// The updated look position.
vector3 RotationLookAtPoint(vector3 pos, vector3 endPos);
#if TARGET == TARGET_RDR
#ifdef _MSC_VER
/// Returns the principal value of the arc cosine of x, expressed in radians.
///
/// Value whose arc cosine is computed, in the interval [-1,+1].
/// If the argument is out of this interval, a domain error occurs.
///
/// Principal arc cosine of x, in the interval [0,pi] radians.
#define acos(x) acosMSC(x)
float acosMSC(float number) {};
#else
float acos(float number);
#endif
#ifdef _MSC_VER
/// Returns the principal value of the arc sine of x, expressed in radians.
///
/// Value whose arc sine is computed, in the interval [-1,+1].
/// If the argument is out of this interval, a domain error occurs.
///
/// Principal arc sine of x, in the interval [-pi/2,+pi/2] radians.
#define asin(number) asinMSC(number)
float asinMSC(float number) {};
#else
float asin(float number);
#endif
#endif
bool CmpLtU(int a, int b);
bool CmpGtU(int a, int b);
int Diff64P(int* x, int* y);
int* Sub64P(int* x, int yLeft, int yRight);
int* Add64P(int* x, int yLeft, int yRight);
int* Push64P(int LeftMost, int RightMost);