faluco@225: #include faluco@225: #include faluco@225: #include "sp_vm_api.h" faluco@225: faluco@225: using namespace SourcePawn; faluco@225: faluco@225: #define PI 3.14159265358979323846 faluco@225: faluco@225: inline cell_t ftoc(float val) faluco@225: { faluco@225: return *(cell_t *)&val; faluco@225: } faluco@225: inline float ctof(cell_t val) faluco@225: { faluco@225: return *(float *)&val; faluco@225: } faluco@225: faluco@225: inline float AngleToRadians(float val, int mode) faluco@225: { faluco@225: switch (mode) faluco@225: { faluco@225: case 1: faluco@225: { faluco@225: return (float)((val * PI) / 180.0); faluco@225: } faluco@225: case 2: faluco@225: { faluco@225: return (float)((val * PI) / 200.0); faluco@225: } faluco@225: default: faluco@225: { faluco@225: return val; faluco@225: } faluco@225: } faluco@225: } faluco@225: faluco@225: inline float RadiansToAngle(float val, int mode) faluco@225: { faluco@225: switch (mode) faluco@225: { faluco@225: case 1: faluco@225: { faluco@225: return (float)((val / PI) * 180.0); faluco@225: } faluco@225: case 2: faluco@225: { faluco@225: return (float)((val / PI) * 200.0); faluco@225: } faluco@225: default: faluco@225: { faluco@225: return val; faluco@225: } faluco@225: } faluco@225: } faluco@225: faluco@225: faluco@225: /**************************************** faluco@225: * * faluco@225: * FLOATING POINT NATIVE IMPLEMENTATIONS * faluco@225: * * faluco@225: ****************************************/ faluco@225: faluco@225: faluco@225: static cell_t sm_float(IPluginContext *pCtx, const cell_t *params) faluco@225: { faluco@225: float val = static_cast(params[1]); faluco@225: faluco@225: return ftoc(val); faluco@225: } faluco@225: faluco@225: static cell_t sm_floatabs(IPluginContext *pCtx, const cell_t *params) faluco@225: { faluco@225: float val = ctof(params[1]); faluco@225: val = (val >= 0) ? val : -val; faluco@225: faluco@225: return ftoc(val); faluco@225: } faluco@225: faluco@225: static cell_t sm_floatadd(IPluginContext *pCtx, const cell_t *params) faluco@225: { faluco@225: float val = ctof(params[1]) + ctof(params[2]); faluco@225: faluco@225: return ftoc(val); faluco@225: } faluco@225: faluco@225: static cell_t sm_floatsub(IPluginContext *pCtx, const cell_t *params) faluco@225: { faluco@225: float val = ctof(params[1]) - ctof(params[2]); faluco@225: faluco@225: return ftoc(val); faluco@225: } faluco@225: faluco@225: static cell_t sm_floatmul(IPluginContext *pCtx, const cell_t *params) faluco@225: { faluco@225: float val = ctof(params[1]) * ctof(params[2]); faluco@225: faluco@225: return ftoc(val); faluco@225: } faluco@225: faluco@225: static cell_t sm_floatdiv(IPluginContext *pCtx, const cell_t *params) faluco@225: { faluco@225: float val = ctof(params[1]) / ctof(params[2]); faluco@225: faluco@225: return ftoc(val); faluco@225: } faluco@225: faluco@225: static cell_t sm_floatcmp(IPluginContext *pCtx, const cell_t *params) faluco@225: { faluco@225: float val1 = ctof(params[1]); faluco@225: float val2 = ctof(params[2]); faluco@225: faluco@225: if (val1 > val2) faluco@225: { faluco@225: return 1; faluco@225: } else if (val1 < val2) { faluco@225: return -1; faluco@225: } faluco@225: faluco@225: return 0; faluco@225: } faluco@225: faluco@225: static cell_t sm_floatlog(IPluginContext *pCtx, const cell_t *params) faluco@225: { faluco@225: float val = ctof(params[1]); faluco@225: float base = ctof(params[2]); faluco@225: faluco@225: if ((val <= 0) || (base <= 0)) faluco@225: { faluco@225: //:TODO: error out! logs cant take in negative numbers and log 0=-inf faluco@225: } faluco@225: if (base == 10.0) faluco@225: { faluco@225: val = log10(val); faluco@225: } else { faluco@225: val = log(val) / log(base); faluco@225: } faluco@225: faluco@225: return ftoc(val); faluco@225: } faluco@225: faluco@225: static cell_t sm_floatexp(IPluginContext *pCtx, const cell_t *params) faluco@225: { faluco@225: float val = ctof(params[1]); faluco@225: faluco@225: return ftoc(exp(val)); faluco@225: } faluco@225: faluco@225: static cell_t sm_floatpower(IPluginContext *pCtx, const cell_t *params) faluco@225: { faluco@225: float base = ctof(params[1]); faluco@225: float exponent = ctof(params[2]); faluco@225: faluco@225: return ftoc(pow(base, exponent)); faluco@225: } faluco@225: faluco@225: static cell_t sm_floatsqroot(IPluginContext *pCtx, const cell_t *params) faluco@225: { faluco@225: float val = ctof(params[1]); faluco@225: faluco@225: if (val < 0.0) faluco@225: { faluco@225: //:TODO: error out! we dont support complex numbers faluco@225: } faluco@225: faluco@225: return ftoc(sqrt(val)); faluco@225: } faluco@225: faluco@225: static cell_t sm_floatround(IPluginContext *pCtx, const cell_t *params) faluco@225: { faluco@225: float val = ctof(params[1]); faluco@225: faluco@225: switch (params[2]) faluco@225: { faluco@225: case 1: faluco@225: { faluco@225: val = floor(val); faluco@225: break; faluco@225: } faluco@225: case 2: faluco@225: { faluco@225: val = ceil(val); faluco@225: break; faluco@225: } faluco@225: case 3: faluco@225: { faluco@225: if (val >= 0.0) faluco@225: { faluco@225: val = floor(val); faluco@225: } else { faluco@225: val = ceil(val); faluco@225: } faluco@225: break; faluco@225: } faluco@225: default: faluco@225: { faluco@225: val = (float)floor(val + 0.5); faluco@225: break; faluco@225: } faluco@225: } faluco@225: faluco@225: return ftoc(val); faluco@225: } faluco@225: faluco@225: static cell_t sm_floatstr(IPluginContext *pCtx, const cell_t *params) faluco@225: { faluco@225: char *str; faluco@225: faluco@225: pCtx->LocalToString(params[1], &str); faluco@225: if (!strlen(str)) faluco@225: { faluco@225: return 0; faluco@225: } faluco@225: faluco@225: return ftoc((float)atof(str)); faluco@225: } faluco@225: faluco@225: static cell_t sm_floatfract(IPluginContext *pCtx, const cell_t *params) faluco@225: { faluco@225: float val = ctof(params[1]); faluco@225: val = val - floor(val); faluco@225: faluco@225: return ftoc(val); faluco@225: } faluco@225: faluco@225: static cell_t sm_floatsin(IPluginContext *pCtx, const cell_t *params) faluco@225: { faluco@225: float val = ctof(params[1]); faluco@225: val = sin(AngleToRadians(val, params[2])); faluco@225: faluco@225: return ftoc(val); faluco@225: } faluco@225: faluco@225: static cell_t sm_floatcos(IPluginContext *pCtx, const cell_t *params) faluco@225: { faluco@225: float val = ctof(params[1]); faluco@225: val = cos(AngleToRadians(val, params[2])); faluco@225: faluco@225: return ftoc(val); faluco@225: } faluco@225: faluco@225: static cell_t sm_floattan(IPluginContext *pCtx, const cell_t *params) faluco@225: { faluco@225: float val = ctof(params[1]); faluco@225: val = tan(AngleToRadians(val, params[2])); faluco@225: faluco@225: return ftoc(val); faluco@225: } faluco@225: faluco@225: static cell_t sm_floatasin(IPluginContext *pCtx, const cell_t *params) faluco@225: { faluco@225: float val = ctof(params[1]); faluco@225: val = asin(val); faluco@225: faluco@225: return ftoc(RadiansToAngle(val, params[2])); faluco@225: } faluco@225: faluco@225: static cell_t sm_floatacos(IPluginContext *pCtx, const cell_t *params) faluco@225: { faluco@225: float val = ctof(params[1]); faluco@225: val = acos(val); faluco@225: faluco@225: return ftoc(RadiansToAngle(val, params[2])); faluco@225: } faluco@225: faluco@225: static cell_t sm_floatatan(IPluginContext *pCtx, const cell_t *params) faluco@225: { faluco@225: float val = ctof(params[1]); faluco@225: val = atan(val); faluco@225: faluco@225: return ftoc(RadiansToAngle(val, params[2])); faluco@225: } faluco@225: faluco@225: static cell_t sm_floatatan2(IPluginContext *pCtx, const cell_t *params) faluco@225: { faluco@225: float val1 = ctof(params[1]); faluco@225: float val2 = ctof(params[2]); faluco@225: val1 = atan2(val1, val2); faluco@225: faluco@225: return ftoc(RadiansToAngle(val1, params[3])); faluco@225: }