1557 lines
35 KiB
C++
Executable File
1557 lines
35 KiB
C++
Executable File
#ifndef RC_STDLIB_H_INCLUDED
|
|
#define RC_STDLIB_H_INCLUDED
|
|
|
|
#include "rc_os_defines.h"
|
|
|
|
#define RC_PI 3.14159265359
|
|
|
|
#ifdef RC_MAC
|
|
#define RC_GETCWD
|
|
#include <sys/param.h>
|
|
#endif
|
|
|
|
#ifdef RC_ANDROID
|
|
#define RC_GETCWD
|
|
#endif
|
|
|
|
#include <iostream>
|
|
#include <stdio.h>
|
|
#include <stdexcept>
|
|
#include <iomanip>
|
|
#include <sstream>
|
|
#include <fstream>
|
|
#include <cstdlib>
|
|
#include <cmath>
|
|
#include <ctime>
|
|
#include <stack>
|
|
#include <bitset>
|
|
#include <sys/stat.h> //file system stuff
|
|
#include <sys/types.h> //file system stuff
|
|
#include <unistd.h> //file system stuff
|
|
#include <dirent.h>
|
|
#include <stdlib.h>
|
|
#include <algorithm>
|
|
#include <codecvt>
|
|
|
|
#ifdef RC_ANDROID
|
|
#include "SDL.h"
|
|
#include <jni.h>
|
|
#else
|
|
#include <SDL2/SDL.h>
|
|
#endif
|
|
//
|
|
|
|
|
|
#ifdef RC_WINDOWS
|
|
#define WIN32_LEAN_AND_MEAN
|
|
#include <tchar.h>
|
|
#include <windows.h>
|
|
#include <winbase.h>
|
|
#include <locale>
|
|
#endif // RC_WINDOWS
|
|
|
|
using namespace std;
|
|
|
|
#define RC_MAX_FILES 32
|
|
|
|
#define RC_FILE_IO_TEXT_INPUT 1
|
|
#define RC_FILE_IO_TEXT_OUTPUT 2
|
|
#define RC_FILE_IO_TEXT_APPEND 3
|
|
#define RC_FILE_IO_TEXT_INPUT_UPDATE 4
|
|
#define RC_FILE_IO_TEXT_OUTPUT_UPDATE 5
|
|
#define RC_FILE_IO_TEXT_APPEND_UPDATE 6
|
|
#define RC_FILE_IO_BINARY_INPUT 7
|
|
#define RC_FILE_IO_BINARY_OUTPUT 8
|
|
#define RC_FILE_IO_BINARY_APPEND 9
|
|
#define RC_FILE_IO_BINARY_INPUT_UPDATE 10
|
|
#define RC_FILE_IO_BINARY_OUTPUT_UPDATE 11
|
|
#define RC_FILE_IO_BINARY_APPEND_UPDATE 12
|
|
|
|
#ifndef RC_WINDOWS
|
|
|
|
struct dirent *rc_entry;
|
|
DIR *rc_dir;
|
|
string rc_dir_path = "";
|
|
|
|
#else
|
|
|
|
struct dirent *rc_entry;
|
|
string rc_dir;
|
|
string rc_dir_path = "";
|
|
HANDLE hfind;
|
|
|
|
#endif // RC_LINUX
|
|
|
|
|
|
int rc_cmd_count = 0;
|
|
string * rc_cmd_args;
|
|
|
|
|
|
SDL_RWops * rc_fstream[RC_MAX_FILES];
|
|
bool rc_eof[RC_MAX_FILES];
|
|
|
|
#define MAX_USER_STACKS 16
|
|
int rc_user_active_n_stack = 0;
|
|
int rc_user_active_s_stack = 0;
|
|
|
|
stack<double> rc_user_n_stack[MAX_USER_STACKS];
|
|
stack<string> rc_user_s_stack[MAX_USER_STACKS];
|
|
|
|
#ifdef RC_WINDOWS
|
|
#define MAX_INPUT_LENGTH 32767
|
|
|
|
wchar_t wstr[MAX_INPUT_LENGTH];
|
|
char mb_str[MAX_INPUT_LENGTH * 3 + 1];
|
|
|
|
#endif // RC_WINDOWS
|
|
|
|
|
|
std::string utf8_substr(const std::string& str, unsigned int start, unsigned int leng)
|
|
{
|
|
if (leng==0) { return ""; }
|
|
unsigned int c, i, ix, q, min=std::string::npos, max=std::string::npos;
|
|
for (q=0, i=0, ix=str.length(); i < ix; i++, q++)
|
|
{
|
|
if (q==start){ min=i; }
|
|
if (q<=start+leng || leng==std::string::npos){ max=i; }
|
|
|
|
c = (unsigned char) str[i];
|
|
if (
|
|
//c>=0 &&
|
|
c<=127) i+=0;
|
|
else if ((c & 0xE0) == 0xC0) i+=1;
|
|
else if ((c & 0xF0) == 0xE0) i+=2;
|
|
else if ((c & 0xF8) == 0xF0) i+=3;
|
|
//else if (($c & 0xFC) == 0xF8) i+=4; // 111110bb //byte 5, unnecessary in 4 byte UTF-8
|
|
//else if (($c & 0xFE) == 0xFC) i+=5; // 1111110b //byte 6, unnecessary in 4 byte UTF-8
|
|
else return "";//invalid utf8
|
|
}
|
|
if (q<=start+leng || leng==std::string::npos){ max=i; }
|
|
if (min==std::string::npos || max==std::string::npos) { return ""; }
|
|
return str.substr(min,max-min);
|
|
}
|
|
|
|
std::size_t utf8_length(std::string const &s)
|
|
{
|
|
return std::count_if(s.begin(), s.end(),
|
|
[](char c) { return (static_cast<unsigned char>(c) & 0xC0) != 0x80; } );
|
|
}
|
|
|
|
|
|
void rc_fprint(string txt)
|
|
{
|
|
cout << txt;
|
|
}
|
|
|
|
string rc_input(string prompt)
|
|
{
|
|
#ifdef RC_WINDOWS
|
|
|
|
string line = "";
|
|
cout << prompt;
|
|
|
|
unsigned long read;
|
|
void *con = GetStdHandle(STD_INPUT_HANDLE);
|
|
|
|
ReadConsoleW(con, wstr, MAX_INPUT_LENGTH, &read, NULL);
|
|
|
|
int s_size = WideCharToMultiByte(CP_UTF8, 0, wstr, read, mb_str, sizeof(mb_str), NULL, NULL);
|
|
mb_str[s_size] = 0;
|
|
|
|
if(s_size >= 2)
|
|
{
|
|
if(mb_str[s_size-2]==10 || mb_str[s_size-2]==13)
|
|
mb_str[s_size-2] = 0;
|
|
|
|
if(mb_str[s_size-1]==10 || mb_str[s_size-1]==13)
|
|
mb_str[s_size-1] = 0;
|
|
}
|
|
|
|
return (string) mb_str;
|
|
|
|
#else
|
|
|
|
string line = "";
|
|
cout << prompt;
|
|
getline(cin, line);
|
|
return line;
|
|
|
|
#endif // RC_WINDOWS
|
|
}
|
|
|
|
std::u32string to_utf32(const std::string &s)
|
|
{
|
|
std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> conv;
|
|
return conv.from_bytes(s);
|
|
}
|
|
|
|
inline int rc_intern_asc(string c)
|
|
{
|
|
return (uint32_t)to_utf32(utf8_substr(c, 0, 1))[0];
|
|
}
|
|
|
|
inline size_t rc_intern_bufferFromString(string s, double* buffer)
|
|
{
|
|
for(int i = 0; i < s.length(); i++)
|
|
{
|
|
buffer[i] = (double)((uint32_t)s[i]);
|
|
}
|
|
return s.length();
|
|
}
|
|
|
|
std::string cpToUTF8(uint32_t cp)
|
|
{
|
|
char utf8[4];
|
|
int len = 0;
|
|
|
|
if (cp <= 0x007F)
|
|
{
|
|
utf8[0] = static_cast<char>(cp);
|
|
len = 1;
|
|
}
|
|
else
|
|
{
|
|
if (cp <= 0x07FF)
|
|
{
|
|
utf8[0] = 0xC0;
|
|
len = 2;
|
|
}
|
|
else if (cp <= 0xFFFF)
|
|
{
|
|
utf8[0] = 0xE0;
|
|
len = 3;
|
|
}
|
|
else if (cp <= 0x10FFFF)
|
|
{
|
|
utf8[0] = 0xF0;
|
|
len = 4;
|
|
}
|
|
else
|
|
throw std::invalid_argument("invalid codepoint");
|
|
|
|
for(int i = 1; i < len; ++i)
|
|
{
|
|
utf8[len-i] = static_cast<char>(0x80 | (cp & 0x3F));
|
|
cp >>= 6;
|
|
}
|
|
|
|
utf8[0] |= static_cast<char>(cp);
|
|
}
|
|
|
|
return std::string(utf8, len);
|
|
}
|
|
|
|
inline string rc_intern_chr(uint32_t n)
|
|
{
|
|
string s = cpToUTF8(n);
|
|
//s += (char) n;
|
|
return s;
|
|
}
|
|
|
|
inline string rc_intern_insert(string src, string tgt, size_t pos)
|
|
{
|
|
if(pos < 0 || pos > utf8_length(src))
|
|
return src;
|
|
|
|
return utf8_substr(src, 0, pos) + tgt + utf8_substr(src, pos, utf8_length(src)-pos);
|
|
}
|
|
|
|
inline double rc_intern_instr(string in_string, string in_substring)
|
|
{
|
|
//cout << "Cant find " << rc_sid[INSTR_SUBSTR][0] << " in " << rc_sid[INSTR_STR][0] << endl;
|
|
bool found = false;
|
|
size_t n = 0;//(int)in_string.find(in_substring);
|
|
size_t search_len = utf8_length(in_string) - utf8_length(in_substring);
|
|
size_t sub_len = utf8_length(in_substring);
|
|
for(size_t i = 0; i <= search_len; i++)
|
|
{
|
|
if(utf8_substr(in_string, i, sub_len).compare(in_substring)==0)
|
|
{
|
|
n = i;
|
|
found = true;
|
|
break;
|
|
}
|
|
}
|
|
return found ? (double)n : -1;
|
|
}
|
|
|
|
inline string rc_intern_lcase(string u_string)
|
|
{
|
|
string u_string_out = "";
|
|
for(size_t i=0;i<u_string.length();i++)
|
|
{
|
|
u_string_out += tolower(u_string[i]);
|
|
}
|
|
return u_string_out;
|
|
}
|
|
|
|
inline string rc_intern_left(string l_string, size_t n)
|
|
{
|
|
if(n >= utf8_length(l_string))
|
|
return l_string;
|
|
//cout << "DEBUG -> n = " << n << " : NPOS = " << string::npos << endl;
|
|
return utf8_substr(l_string,0,n);
|
|
}
|
|
|
|
inline size_t rc_intern_length(string l_string)
|
|
{
|
|
//cout << "DBG_LEN" << endl;
|
|
return utf8_length(l_string);
|
|
}
|
|
|
|
inline string rc_intern_ltrim(string l_string)
|
|
{
|
|
size_t first_index = l_string.find_first_not_of(" ");
|
|
if(first_index != string::npos)
|
|
return l_string.substr(first_index);
|
|
return l_string;
|
|
}
|
|
|
|
inline string rc_intern_mid(string m_string, size_t m_start, size_t n)
|
|
{
|
|
//cout << "DBG_MID" << endl;
|
|
if(m_start < 0 || n < 0)
|
|
return "";
|
|
size_t m_string_length = utf8_length(m_string);
|
|
if(m_string_length <= m_start)
|
|
return "";
|
|
if( (m_start+n) >= m_string_length)
|
|
return utf8_substr(m_string, m_start, m_string_length-m_start);
|
|
return utf8_substr(m_string, m_start, n);
|
|
}
|
|
|
|
inline string rc_intern_replaceSubstr(string src, string rpc, size_t pos)
|
|
{
|
|
size_t rpc_i = 0;
|
|
string n_str = utf8_substr(src, 0, pos);
|
|
|
|
if(pos < 0)
|
|
return src;
|
|
|
|
for(size_t i = pos; i < utf8_length(src); i++)
|
|
{
|
|
if(rpc_i < utf8_length(rpc))
|
|
n_str += utf8_substr(rpc,rpc_i,1);
|
|
else
|
|
break;
|
|
rpc_i++;
|
|
}
|
|
if((pos+rpc_i) < utf8_length(src) )
|
|
n_str += utf8_substr(src, pos+rpc_i, utf8_length(src)-(pos+rpc_i));
|
|
return n_str;
|
|
}
|
|
|
|
inline string rc_intern_replace(string src, string tgt, string rpc)
|
|
{
|
|
if(tgt.length()==0)
|
|
return src;
|
|
size_t found_inc = rpc.length() > 0 ? rpc.length() : 1;
|
|
size_t found = 0;
|
|
found = src.find(tgt);
|
|
while( found != string::npos && found < src.length())
|
|
{
|
|
src = src.substr(0,found) + rpc + src.substr(found + tgt.length());
|
|
found = src.find(tgt,found+found_inc);
|
|
}
|
|
return src;
|
|
}
|
|
|
|
inline string rc_intern_reverse(string rpc_string)
|
|
{
|
|
string n_str = "";
|
|
if(rpc_string.length()==0)
|
|
return "";
|
|
|
|
for(size_t i = utf8_length(rpc_string)-1;; i--)
|
|
{
|
|
n_str += utf8_substr(rpc_string, i, 1);
|
|
if(i==0)
|
|
break;
|
|
}
|
|
return n_str;
|
|
}
|
|
|
|
inline string rc_intern_right(string src, size_t n)
|
|
{
|
|
size_t src_length = utf8_length(src);
|
|
if(n < 0)
|
|
return "";
|
|
if(n >= src_length)
|
|
return src;
|
|
return utf8_substr(src,src_length-n, src_length -(src_length-n));
|
|
}
|
|
|
|
inline string rc_intern_rtrim(string src)
|
|
{
|
|
if(src.length()==0)
|
|
return "";
|
|
|
|
size_t i = 0;
|
|
for(i = utf8_length(src)-1; ; i--)
|
|
{
|
|
if(utf8_substr(src,i,1).compare(" ") != 0 || i == 0)
|
|
break;
|
|
}
|
|
if(i < 0)
|
|
return "";
|
|
|
|
return utf8_substr(src,0,i+1);
|
|
}
|
|
|
|
inline size_t rc_intern_size(string src)
|
|
{
|
|
return src.length();
|
|
}
|
|
|
|
inline string rc_intern_stringFromBuffer(double* buffer, size_t buffer_size)
|
|
{
|
|
if(buffer_size <= 0)
|
|
return "";
|
|
|
|
char c_buf[buffer_size+1];
|
|
|
|
for(int i = 0; i < buffer_size; i++)
|
|
{
|
|
c_buf[i] = (uint8_t)buffer[i];
|
|
}
|
|
|
|
c_buf[buffer_size] = '\0';
|
|
return (string)c_buf;
|
|
}
|
|
|
|
inline string rc_intern_stringfill(string f_string, size_t n)
|
|
{
|
|
string f = "";
|
|
for(size_t i = 0; i < n; i++)
|
|
f += f_string;
|
|
return f;
|
|
}
|
|
|
|
inline string rc_intern_str(double n)
|
|
{
|
|
stringstream ss;
|
|
ss << n;
|
|
return ss.str();
|
|
}
|
|
|
|
inline string rc_intern_str_f(double n)
|
|
{
|
|
stringstream ss;
|
|
ss << fixed << n;
|
|
return ss.str();
|
|
}
|
|
|
|
inline string rc_intern_str_s(double n)
|
|
{
|
|
stringstream ss;
|
|
ss << scientific << n;
|
|
return ss.str();
|
|
}
|
|
|
|
inline unsigned long rc_intern_tally(string t_string, string t_substring)
|
|
{
|
|
size_t found = 0;
|
|
string t_str = t_string;
|
|
string t_substr = t_substring;
|
|
found = t_str.find(t_substr);
|
|
unsigned long tally_count = 0;
|
|
while( found != string::npos)
|
|
{
|
|
tally_count++;
|
|
found = t_str.find(t_substr,found+1);
|
|
}
|
|
return tally_count;
|
|
}
|
|
|
|
inline string rc_intern_trim(string t_string)
|
|
{
|
|
return rc_intern_ltrim(rc_intern_rtrim(t_string));
|
|
}
|
|
|
|
inline string rc_intern_ucase(string u_string)
|
|
{
|
|
string u_string_out = "";
|
|
for(size_t i=0;i<u_string.length();i++)
|
|
{
|
|
u_string_out += toupper(u_string[i]);
|
|
}
|
|
return u_string_out;
|
|
}
|
|
|
|
inline double rc_intern_val(string v_string)
|
|
{
|
|
return atof(v_string.c_str());
|
|
}
|
|
|
|
inline double rc_intern_abs(double n)
|
|
{
|
|
if(n < 0)
|
|
return (n * -1);
|
|
else
|
|
return n;
|
|
}
|
|
|
|
inline double rc_intern_aCos(double n)
|
|
{
|
|
return acos(n);
|
|
}
|
|
|
|
inline double rc_intern_andBit(uint64_t a, uint64_t b)
|
|
{
|
|
return (a & b);
|
|
}
|
|
|
|
inline double rc_intern_aSin(double n)
|
|
{
|
|
return asin(n);
|
|
}
|
|
|
|
inline double rc_intern_aTan(double n)
|
|
{
|
|
return atan(n);
|
|
}
|
|
|
|
#ifdef RC_ANDROID
|
|
string Convert(unsigned int val)
|
|
{
|
|
unsigned int mask = 1 << (sizeof(int) * 8 - 1);
|
|
string binstr = "";
|
|
|
|
for(int i = 0; i < sizeof(int) * 8; i++)
|
|
{
|
|
if( (val & mask) == 0 )
|
|
//cout << '0' ;
|
|
binstr += "0";
|
|
else
|
|
//cout << '1' ;
|
|
binstr += "1";
|
|
|
|
mask >>= 1;
|
|
}
|
|
return binstr;
|
|
}
|
|
|
|
inline string rc_intern_bin(uint64_t n)
|
|
{
|
|
//string bin_str = bitset<64>(n).to_string();
|
|
//bin_str = bin_str.substr(bin_str.find_first_not_of("0"));
|
|
string binstr = Convert(n);// bin_str;
|
|
return binstr.substr(binstr.find_first_not_of("0"));
|
|
}
|
|
#else
|
|
|
|
inline string rc_intern_bin(uint64_t n)
|
|
{
|
|
string bin_str = bitset<64>(n).to_string();
|
|
bin_str = bin_str.substr(bin_str.find_first_not_of("0"));
|
|
return bin_str;
|
|
}
|
|
|
|
#endif // RC_ANDROID
|
|
|
|
union rc_cint_u
|
|
{
|
|
int64_t i64;
|
|
int32_t i32[2];
|
|
};
|
|
double rc_intern_cint64(double n)
|
|
{
|
|
rc_cint_u num;
|
|
num.i32[0] = (int32_t)n;
|
|
//cout << "dbg: " << num.i64 << endl;
|
|
return num.i64;
|
|
}
|
|
|
|
double rc_intern_cint32(double n)
|
|
{
|
|
rc_cint_u num;
|
|
num.i64 = (int64_t)n;
|
|
//cout << "dbg1: " << num.i32[0] << endl;
|
|
//cout << "dbg2: " << num.i32[1] << endl;
|
|
return num.i32[0];
|
|
}
|
|
|
|
inline double rc_intern_cos(double angle)
|
|
{
|
|
return cos(angle);
|
|
}
|
|
|
|
inline double rc_intern_exp(double n)
|
|
{
|
|
return exp(n);
|
|
}
|
|
|
|
inline double rc_intern_frac(double n)
|
|
{
|
|
return n - floor(n);
|
|
}
|
|
|
|
inline string rc_intern_hex(uint64_t n)
|
|
{
|
|
stringstream ss;
|
|
ss << hex << n;
|
|
return ss.str();
|
|
}
|
|
|
|
inline double rc_intern_hexInt(string n)
|
|
{
|
|
uint64_t x;
|
|
stringstream ss;
|
|
ss << hex << n;
|
|
ss >> x;
|
|
return (double)x;
|
|
}
|
|
|
|
inline int64_t rc_intern_int(double n)
|
|
{
|
|
return (int64_t)n;
|
|
}
|
|
|
|
inline double rc_intern_log(double n)
|
|
{
|
|
return log(n);
|
|
}
|
|
|
|
inline double rc_intern_max(double a, double b)
|
|
{
|
|
if(a > b)
|
|
return a;
|
|
else
|
|
return b;
|
|
}
|
|
|
|
inline double rc_intern_min(double a, double b)
|
|
{
|
|
if(a < b)
|
|
return a;
|
|
else
|
|
return b;
|
|
}
|
|
|
|
inline double rc_intern_orBit(uint64_t a, uint64_t b)
|
|
{
|
|
return (a | b);
|
|
}
|
|
|
|
inline double rc_intern_radians(double degrees)
|
|
{
|
|
return degrees * (RC_PI/180);
|
|
}
|
|
|
|
inline double rc_intern_degrees(double radians)
|
|
{
|
|
return radians * (180/RC_PI);
|
|
}
|
|
|
|
inline int rc_intern_randomize(double n)
|
|
{
|
|
srand(n);
|
|
return 0;
|
|
}
|
|
|
|
inline int rc_intern_rand(int n)
|
|
{
|
|
return (int)( (rand() / double(RAND_MAX))*(double(n) + ( n < 0 ? 0.001 : -0.001 )) );
|
|
}
|
|
|
|
inline double rc_intern_round(double n)
|
|
{
|
|
return round(n);
|
|
}
|
|
|
|
inline int rc_intern_sign(double n)
|
|
{
|
|
if(n == 0)
|
|
return 0;
|
|
else if(n > 0)
|
|
return 1;
|
|
else
|
|
return -1;
|
|
}
|
|
|
|
inline double rc_intern_sin(double angle)
|
|
{
|
|
return sin(angle);
|
|
}
|
|
|
|
inline double rc_intern_sqrt(double n)
|
|
{
|
|
return sqrt(n);
|
|
}
|
|
|
|
inline double rc_intern_tan(double angle)
|
|
{
|
|
return tan(angle);
|
|
}
|
|
|
|
inline double rc_intern_xorbit(uint64_t a, uint64_t b)
|
|
{
|
|
return (a ^ b);
|
|
}
|
|
|
|
inline int rc_intern_fileOpen(int fo_stream, string fo_file, int fo_mode)
|
|
{
|
|
if(fo_stream >= 0 && fo_stream < RC_MAX_FILES)
|
|
{
|
|
if(rc_fstream[fo_stream] != NULL)
|
|
return 0;
|
|
|
|
rc_eof[fo_stream] = false;
|
|
|
|
switch(fo_mode)
|
|
{
|
|
case RC_FILE_IO_TEXT_INPUT:
|
|
//rc_fstream[fo_stream].open(fo_file.c_str(), fstream::in);
|
|
rc_fstream[fo_stream] = SDL_RWFromFile(fo_file.c_str(), "r");
|
|
//cout << "RC_DEBUG_TEXT_INPUT" << endl;
|
|
break;
|
|
case RC_FILE_IO_TEXT_OUTPUT:
|
|
rc_fstream[fo_stream] = SDL_RWFromFile(fo_file.c_str(),"w");
|
|
break;
|
|
case RC_FILE_IO_TEXT_APPEND:
|
|
rc_fstream[fo_stream] = SDL_RWFromFile(fo_file.c_str(),"a");
|
|
break;
|
|
case RC_FILE_IO_TEXT_INPUT_UPDATE:
|
|
rc_fstream[fo_stream] = SDL_RWFromFile(fo_file.c_str(),"r+");
|
|
break;
|
|
case RC_FILE_IO_TEXT_OUTPUT_UPDATE:
|
|
rc_fstream[fo_stream] = SDL_RWFromFile(fo_file.c_str(),"w+");
|
|
break;
|
|
case RC_FILE_IO_TEXT_APPEND_UPDATE:
|
|
rc_fstream[fo_stream] = SDL_RWFromFile(fo_file.c_str(),"a+");
|
|
break;
|
|
case RC_FILE_IO_BINARY_INPUT:
|
|
rc_fstream[fo_stream] = SDL_RWFromFile(fo_file.c_str(),"rb");
|
|
break;
|
|
case RC_FILE_IO_BINARY_OUTPUT:
|
|
rc_fstream[fo_stream] = SDL_RWFromFile(fo_file.c_str(),"wb");
|
|
break;
|
|
case RC_FILE_IO_BINARY_APPEND:
|
|
rc_fstream[fo_stream] = SDL_RWFromFile(fo_file.c_str(),"ab");
|
|
break;
|
|
case RC_FILE_IO_BINARY_INPUT_UPDATE:
|
|
rc_fstream[fo_stream] = SDL_RWFromFile(fo_file.c_str(),"rb+");
|
|
break;
|
|
case RC_FILE_IO_BINARY_OUTPUT_UPDATE:
|
|
rc_fstream[fo_stream] = SDL_RWFromFile(fo_file.c_str(),"wb+");
|
|
break;
|
|
case RC_FILE_IO_BINARY_APPEND_UPDATE:
|
|
rc_fstream[fo_stream] = SDL_RWFromFile(fo_file.c_str(),"ab+");
|
|
break;
|
|
}
|
|
if(rc_fstream[fo_stream] == NULL)
|
|
{
|
|
//cout << "RC_DEBUG: FILE NOT OPEN" << endl;
|
|
return 0;
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
inline int rc_intern_fileClose(int fc_stream)
|
|
{
|
|
rc_eof[fc_stream] = false;
|
|
|
|
if(rc_fstream[fc_stream] != NULL)
|
|
{
|
|
SDL_RWclose(rc_fstream[fc_stream]);
|
|
rc_fstream[fc_stream] = NULL;
|
|
return 1;
|
|
}
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
inline int rc_intern_fileReadByte(int f_stream)
|
|
{
|
|
unsigned char buf;
|
|
if(SDL_RWread(rc_fstream[f_stream], &buf, 1, 1)==0)
|
|
rc_eof[f_stream] = true;
|
|
|
|
//SDL_RWtell(rc_fstream[f_stream]);
|
|
return (int)buf;
|
|
}
|
|
|
|
inline uint64_t rc_intern_fileReadByteBuffer(int f_stream, double * buf, uint64_t buf_size) //size is in bytes
|
|
{
|
|
uint8_t c_buf[buf_size];
|
|
uint64_t actual_size = SDL_RWread(rc_fstream[f_stream], &c_buf, 1, buf_size);
|
|
|
|
if(actual_size==0)
|
|
rc_eof[f_stream] = true;
|
|
|
|
for(uint64_t i = 0; i < actual_size; i ++)
|
|
buf[i] = (double)c_buf[i];
|
|
|
|
return actual_size;
|
|
}
|
|
|
|
inline uint64_t rc_intern_fileWriteByteBuffer(int f_stream, double * buf, uint64_t buf_size) //size is in bytes
|
|
{
|
|
uint8_t c_buf[buf_size];
|
|
for(uint64_t i = 0; i < buf_size; i++)
|
|
{
|
|
c_buf[i] = (uint8_t)buf[i];
|
|
}
|
|
return SDL_RWwrite(rc_fstream[f_stream], &c_buf, 1, buf_size);
|
|
}
|
|
|
|
inline int rc_intern_fileWriteByte(int f_stream, char wb)
|
|
{
|
|
SDL_RWwrite(rc_fstream[f_stream], &wb, 1, 1);
|
|
return 1;
|
|
}
|
|
|
|
inline string rc_intern_fileReadLine(int f_stream)
|
|
{
|
|
string rline = "";
|
|
unsigned char buf[5];
|
|
if(SDL_RWread(rc_fstream[f_stream], buf, 1, 1)==0)
|
|
{
|
|
rc_eof[f_stream] = true;
|
|
return "";
|
|
}
|
|
while(buf[0]!='\0' && buf[0]!='\n' && buf[0]!='\r')
|
|
{
|
|
rline.append(1,buf[0]);
|
|
if(SDL_RWread(rc_fstream[f_stream], buf, 1, 1)==0)
|
|
{
|
|
rc_eof[f_stream] = true;
|
|
break;
|
|
}
|
|
}
|
|
if(buf[0]=='\r')
|
|
SDL_RWread(rc_fstream[f_stream], buf, 1, 1);
|
|
|
|
return rline;
|
|
}
|
|
|
|
inline int rc_intern_fileWrite(int f_stream, string line)
|
|
{
|
|
//cout << "DEBUG: WRITELINE" << endl;
|
|
if(rc_fstream[f_stream]!=NULL)
|
|
SDL_RWwrite(rc_fstream[f_stream], line.c_str(), line.length(), 1);
|
|
//cout << "WRITELINE_END" << endl;
|
|
return 1;
|
|
}
|
|
|
|
inline int rc_intern_fileWriteLine(int f_stream, string line)
|
|
{
|
|
//cout << "DEBUG: WRITELINE" << endl;
|
|
string line_out = line + "\n";
|
|
if(rc_fstream[f_stream]!=NULL)
|
|
SDL_RWwrite(rc_fstream[f_stream], line_out.c_str(), line_out.length(), 1);
|
|
//cout << "WRITELINE_END" << endl;
|
|
return 1;
|
|
}
|
|
|
|
inline int rc_intern_fileCopy(string src_file, string dst_file)
|
|
{
|
|
std::ifstream src(src_file.c_str(), std::ios::binary);
|
|
std::ofstream dst(dst_file.c_str(), std::ios::binary);
|
|
if(!(src.is_open() && dst.is_open()))
|
|
{
|
|
if(src.is_open())
|
|
src.close();
|
|
if(dst.is_open())
|
|
dst.close();
|
|
return 0;
|
|
}
|
|
dst << src.rdbuf();
|
|
src.close();
|
|
dst.close();
|
|
return 1;
|
|
}
|
|
|
|
inline int rc_intern_fileDelete(string tgt_file)
|
|
{
|
|
if(remove(tgt_file.c_str())==0)
|
|
return 1;
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
inline int rc_intern_fileExist(string tgt_file)
|
|
{
|
|
std::ifstream infile(tgt_file.c_str());
|
|
bool fx = infile.good();
|
|
infile.close();
|
|
return (int)fx;
|
|
}
|
|
|
|
inline int rc_intern_fileMove(string src, string dst)
|
|
{
|
|
int fm = rename(src.c_str(), dst.c_str());
|
|
if(fm == 0)
|
|
return 1;
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
inline int rc_intern_fileRename(string src, string dst)
|
|
{
|
|
int fm = rename(src.c_str(), dst.c_str());
|
|
if(fm == 0)
|
|
return 1;
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
inline unsigned long rc_intern_fileLength(string filename)
|
|
{
|
|
//struct stat st;
|
|
SDL_RWops * fl_file = SDL_RWFromFile(filename.c_str(), "r");
|
|
Sint64 fl_size = SDL_RWsize(fl_file);
|
|
SDL_RWclose(fl_file);
|
|
return fl_size;
|
|
}
|
|
|
|
inline Sint64 rc_intern_fileTell(int f_stream)
|
|
{
|
|
return SDL_RWtell(rc_fstream[f_stream]);
|
|
}
|
|
|
|
inline Sint64 rc_intern_fileSeek(int f_stream, uint64_t pos)
|
|
{
|
|
return SDL_RWseek(rc_fstream[f_stream],pos,RW_SEEK_SET);
|
|
}
|
|
|
|
inline int rc_intern_eof(int f_stream)
|
|
{
|
|
//Uint32 current_pos = SDL_RWtell(rc_fstream[(int)rc_nid[EOF_STREAM][0]]);
|
|
//Uint32 current_pos = SDL_RWseek(rc_fstream[(int)rc_nid[EOF_STREAM][0],0,RW_SEEK_CUR);
|
|
//Uint32 file_eof = SDL_RWseek(rc_fstream[(int)rc_nid[EOF_STREAM][0]],0,RW_SEEK_END);
|
|
//SDL_RWseek(rc_fstream[(int)rc_nid[EOF_STREAM][0]],0,current_pos);
|
|
return rc_eof[f_stream];
|
|
}
|
|
|
|
inline int rc_intern_freeFile()
|
|
{
|
|
for(int i = 0; i < RC_MAX_FILES; i++)
|
|
if(rc_fstream[i] == NULL)
|
|
return i;
|
|
return -1;
|
|
}
|
|
|
|
#ifndef RC_WINDOWS
|
|
|
|
#ifdef RC_LINUX
|
|
inline int rc_intern_dirChange(string ch_path)
|
|
{
|
|
if(chdir(ch_path.c_str())!=0)
|
|
{
|
|
cout << "Error: Could not change directory\n";
|
|
return 2;
|
|
}
|
|
rc_dir_path = get_current_dir_name();
|
|
return 0;
|
|
}
|
|
#endif // RC_LINUX
|
|
|
|
inline int rc_intern_dirExist(string d_path)
|
|
{
|
|
struct stat info;
|
|
|
|
if(stat( d_path.c_str(), &info ) != 0)
|
|
return 0;
|
|
else if(info.st_mode & S_IFDIR)
|
|
return 1;
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
inline string rc_intern_dirFirst ()
|
|
{
|
|
rc_dir = opendir (rc_dir_path.c_str());
|
|
//string s = "";
|
|
|
|
if ((rc_entry = readdir (rc_dir)) != NULL)
|
|
{
|
|
//cout << "ERROR: " << rc_entry->d_name;
|
|
return rc_entry->d_name;
|
|
}
|
|
return "";
|
|
}
|
|
|
|
#ifdef RC_GETCWD
|
|
string getcwd_str()
|
|
{
|
|
char *buffer = new char[MAXPATHLEN];
|
|
getcwd(buffer,MAXPATHLEN);
|
|
if(buffer != NULL)
|
|
{
|
|
string ret(buffer);
|
|
delete[] buffer;
|
|
return ret;
|
|
}
|
|
else
|
|
{
|
|
return string();
|
|
}
|
|
}
|
|
|
|
|
|
inline int rc_intern_dirChange(string ch_path)
|
|
{
|
|
if(chdir(ch_path.c_str())!=0)
|
|
{
|
|
cout << "Error: Could not change directory\n";
|
|
return 2;
|
|
}
|
|
rc_dir_path = getcwd_str();
|
|
return 0;
|
|
}
|
|
|
|
inline string rc_intern_dir()
|
|
{
|
|
string d = getcwd_str();
|
|
//__android_log_print(ANDROID_LOG_ERROR, "RC_DEBUG_DIR", "%s", SDL_GetPrefPath("rcbasic","lucky"));
|
|
if(d.compare("")==0)
|
|
{
|
|
//cout << "Could not get current directory" << endl;
|
|
return "";
|
|
}
|
|
rc_dir_path = d;
|
|
return d;
|
|
}
|
|
|
|
#else
|
|
|
|
inline string rc_intern_dir()
|
|
{
|
|
string d = get_current_dir_name();
|
|
if(d.compare("")==0)
|
|
{
|
|
cout << "Could not get current directory" << endl;
|
|
return "";
|
|
}
|
|
rc_dir_path = d;
|
|
return d;
|
|
}
|
|
|
|
#endif // RC_ANDROID
|
|
|
|
inline string rc_intern_dirNext()
|
|
{
|
|
if( (rc_entry = readdir(rc_dir))!=NULL)
|
|
return rc_entry->d_name;
|
|
return "";
|
|
}
|
|
|
|
inline int rc_intern_dirCreate(string d_path)
|
|
{
|
|
if(mkdir(d_path.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)!=0)
|
|
{
|
|
cout << "ERROR: Could not make directory" << endl;
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
inline int rc_intern_dirDelete(string d_path)
|
|
{
|
|
if(rmdir(d_path.c_str())!=0)
|
|
{
|
|
cout << "ERROR: Could not delete directory" << endl;
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
inline string rc_intern_OS()
|
|
{
|
|
#ifdef RC_WEB
|
|
return "WEB";
|
|
#endif // RC_WEB
|
|
|
|
#ifdef RC_LINUX
|
|
return "LINUX";
|
|
#endif // RC_LINUX
|
|
|
|
#ifdef RC_ANDROID
|
|
return "ANDROID";
|
|
#endif // RC_LINUX
|
|
|
|
#ifdef RC_MAC
|
|
return "MAC";
|
|
#endif // RC_MAC
|
|
|
|
#ifdef RC_IOS
|
|
return "IOS";
|
|
#endif // RC_IOS
|
|
}
|
|
|
|
#else
|
|
|
|
std::string ConvertWideToANSI(const std::wstring& wstr)
|
|
{
|
|
int count = WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), wstr.length(), NULL, 0, NULL, NULL);
|
|
std::string str(count, 0);
|
|
WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), -1, &str[0], count, NULL, NULL);
|
|
return str;
|
|
}
|
|
|
|
std::wstring ConvertAnsiToWide(const std::string& str)
|
|
{
|
|
int count = MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.length(), NULL, 0);
|
|
std::wstring wstr(count, 0);
|
|
MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.length(), &wstr[0], count);
|
|
return wstr;
|
|
}
|
|
|
|
std::string ConvertWideToUtf8(const std::wstring& wstr)
|
|
{
|
|
int count = WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), wstr.length(), NULL, 0, NULL, NULL);
|
|
std::string str(count, 0);
|
|
WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, &str[0], count, NULL, NULL);
|
|
return str;
|
|
}
|
|
|
|
std::wstring ConvertUtf8ToWide(const std::string& str)
|
|
{
|
|
int count = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.length(), NULL, 0);
|
|
std::wstring wstr(count, 0);
|
|
MultiByteToWideChar(CP_UTF8, 0, str.c_str(), str.length(), &wstr[0], count);
|
|
return wstr;
|
|
}
|
|
|
|
inline int rc_intern_dirChange(string dpath)
|
|
{
|
|
if(SetCurrentDirectoryW(ConvertUtf8ToWide(dpath).c_str())==0)
|
|
{
|
|
cout << "[DBG]Error: Could not change directory\n";
|
|
return 2;
|
|
}
|
|
|
|
DWORD nBufferLength = MAX_PATH;
|
|
wchar_t szCurrentDirectory[MAX_PATH + 1];
|
|
GetCurrentDirectoryW(nBufferLength, szCurrentDirectory);
|
|
szCurrentDirectory[MAX_PATH] = '\0';
|
|
|
|
rc_dir_path = ConvertWideToUtf8(szCurrentDirectory);
|
|
return 0;
|
|
}
|
|
|
|
bool dirExists(const std::string& dirName_in)
|
|
{
|
|
DWORD ftyp = GetFileAttributesW(ConvertUtf8ToWide(dirName_in).c_str());
|
|
if (ftyp == INVALID_FILE_ATTRIBUTES)
|
|
return false; //something is wrong with your path!
|
|
|
|
if (ftyp & FILE_ATTRIBUTE_DIRECTORY)
|
|
return true; // this is a directory!
|
|
|
|
return false; // this is not a directory!
|
|
}
|
|
|
|
inline int rc_intern_dirExist(string dpath)
|
|
{
|
|
return dirExists(dpath);
|
|
}
|
|
|
|
HANDLE hFind;
|
|
WIN32_FIND_DATAW ffd;
|
|
|
|
string rc_intern_dirFirst()
|
|
{
|
|
|
|
//char* path = new char[rc_dir_path.length()+1];
|
|
//*path = rc_dir_path.c_str();
|
|
|
|
//for(int i = 0; i < rc_dir_path.length(); i++)
|
|
// path[i] = rc_dir_path[i];
|
|
//path[rc_dir_path.length()] = '\0';
|
|
|
|
//cout << "path = " << path << endl;
|
|
//if (path[_tcslen(path) - 1] != '\\')
|
|
// _tcscat(path, _T("\\"));
|
|
//_tcscat(path, _T("*.*"));
|
|
|
|
|
|
string path = rc_dir_path;
|
|
|
|
if(path.substr(path.length()-1, 1).compare("\\")!=0)
|
|
path += "\\";
|
|
|
|
path += "*.*";
|
|
|
|
//cout << "path2 = " << path << endl;
|
|
|
|
hFind = FindFirstFileW(ConvertUtf8ToWide(path).c_str(), &ffd);
|
|
//delete path;
|
|
//path = NULL;
|
|
if (hFind == INVALID_HANDLE_VALUE)
|
|
{
|
|
cerr << _T("Invalid handle value.") << GetLastError() << endl;
|
|
return "";
|
|
}
|
|
string fname_utf8 = ConvertWideToUtf8(ffd.cFileName);
|
|
return fname_utf8;
|
|
}
|
|
|
|
inline string rc_intern_dir()
|
|
{
|
|
wchar_t buf[MAX_PATH+1];
|
|
GetCurrentDirectoryW(MAX_PATH, buf);
|
|
buf[MAX_PATH] = '/0';
|
|
std::wstring d = buf;
|
|
|
|
if(d.length()==0)
|
|
{
|
|
cout << "Could not get current directory" << endl;
|
|
return "";
|
|
}
|
|
return ConvertWideToUtf8(d.c_str());
|
|
}
|
|
|
|
string rc_intern_dirNext()
|
|
{
|
|
if(!FindNextFileW(hFind,&ffd))
|
|
return "";
|
|
return ConvertWideToUtf8(ffd.cFileName);
|
|
}
|
|
|
|
inline int rc_intern_dirCreate(string dpath)
|
|
{
|
|
if(CreateDirectoryW(ConvertUtf8ToWide(dpath).c_str(),NULL)==0)
|
|
{
|
|
cout << "ERROR: Could not make directory" << endl;
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
inline int rc_intern_dirDelete(string dpath)
|
|
{
|
|
if(RemoveDirectoryW(ConvertUtf8ToWide(dpath).c_str())==0)
|
|
{
|
|
cout << "ERROR: Could not delete directory" << endl;
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
inline string rc_intern_OS()
|
|
{
|
|
return "WINDOWS";
|
|
}
|
|
|
|
#endif // RC_WINDOWS
|
|
|
|
|
|
inline string rc_intern_date()
|
|
{
|
|
time_t t = time(0); // get time now
|
|
struct tm * now = localtime( & t );
|
|
stringstream d;
|
|
if( now->tm_mon+1 < 10)
|
|
d << "0" << now->tm_mon + 1 << "-";
|
|
else
|
|
d << now->tm_mon+1 << "-";
|
|
if(now->tm_mday < 10)
|
|
d << "0" << now->tm_mday << "-";
|
|
else
|
|
d<< now->tm_mday << "-";
|
|
d << (now->tm_year + 1900);
|
|
return d.str();
|
|
}
|
|
|
|
string ZeroPadNumber(int num)
|
|
{
|
|
stringstream ss;
|
|
// the number is converted to string with the help of stringstream
|
|
ss << num;
|
|
string ret;
|
|
ss >> ret;
|
|
// Append zero chars
|
|
int str_length = ret.length();
|
|
for (int i = 0; i < 2 - str_length; i++)
|
|
ret = "0" + ret;
|
|
return ret;
|
|
}
|
|
|
|
string rc_intern_easter(int X)
|
|
{
|
|
stringstream ss; // X = year to compute
|
|
int K, M, S, A, D, R, OG, SZ, OE;
|
|
K = X / 100; // Secular number
|
|
M = 15 + (3 * K + 3) / 4 - (8 * K + 13) / 25; // Secular Moon shift
|
|
S = 2 - (3 * K + 3) / 4; // Secular sun shift
|
|
A = X % 19; // Moon parameter
|
|
D = (19 * A + M) % 30; // Seed for 1st full Moon in spring
|
|
R = D / 29 + (D / 28 - D / 29) * (A / 11); // Calendarian correction quantity
|
|
OG = 21 + D - R; // Easter limit
|
|
SZ = 7 - (X + X / 4 + S) % 7; // 1st sunday in March
|
|
OE = 7 - (OG - SZ) % 7; // Distance Easter sunday from Easter limit in days
|
|
//Easter = DateSerial(X, 3, OG + OE); // Result: Easter sunday as number of days in March
|
|
ss << ZeroPadNumber(((OG + OE)>31)?4:3) << "-" << ZeroPadNumber((((OG + OE)%31)==0)?31:((OG + OE)%31)) << "-" << X;
|
|
return ss.str();
|
|
}
|
|
|
|
inline unsigned long rc_intern_ticks()
|
|
{
|
|
return clock();
|
|
}
|
|
|
|
inline string rc_intern_time()
|
|
{
|
|
time_t t = time(0); // get time now
|
|
struct tm * now = localtime( & t );
|
|
stringstream d;
|
|
if( now->tm_hour < 10)
|
|
d << "0" << now->tm_hour << ":";
|
|
else
|
|
d << now->tm_hour << ":";
|
|
|
|
if(now->tm_min < 10)
|
|
d << "0" << now->tm_min << ":";
|
|
else
|
|
d<< now->tm_min << ":";
|
|
|
|
if(now->tm_sec < 10)
|
|
d << "0" << now->tm_sec;
|
|
else
|
|
d << now->tm_sec;
|
|
return d.str();
|
|
}
|
|
|
|
inline double rc_intern_timer()
|
|
{
|
|
return SDL_GetTicks();
|
|
//return clock() / (double)(CLOCKS_PER_SEC / 1000);
|
|
}
|
|
|
|
inline void rc_intern_wait(double m_sec)
|
|
{
|
|
SDL_Delay(m_sec);
|
|
}
|
|
|
|
inline int rc_intern_system(string rc_sys_cmd)
|
|
{
|
|
#ifdef RC_IOS
|
|
return 0;
|
|
#else
|
|
return system(rc_sys_cmd.c_str());
|
|
#endif
|
|
}
|
|
|
|
inline string rc_intern_sysReturnOutput(string rc_sys_cmd)
|
|
{
|
|
#if defined(RC_ANDROID) || defined(RC_IOS) || defined(RC_WEB)
|
|
return "";
|
|
#else
|
|
const char * cmd = rc_sys_cmd.c_str();
|
|
char buffer[128];
|
|
std::string result = "";
|
|
FILE* pipe = popen(cmd, "r");
|
|
if (!pipe) throw std::runtime_error("popen() failed!");
|
|
try {
|
|
while (fgets(buffer, sizeof buffer, pipe) != NULL) {
|
|
result += buffer;
|
|
}
|
|
} catch (...) {
|
|
pclose(pipe);
|
|
throw;
|
|
}
|
|
pclose(pipe);
|
|
return result;
|
|
#endif
|
|
}
|
|
|
|
inline string rc_intern_command(int num)
|
|
{
|
|
if(num < rc_cmd_count)
|
|
{
|
|
return rc_cmd_args[num];
|
|
}
|
|
return "";
|
|
}
|
|
|
|
inline int rc_intern_numCommands()
|
|
{
|
|
return rc_cmd_count;
|
|
}
|
|
|
|
inline string rc_intern_env(string v)
|
|
{
|
|
#ifdef RC_WINDOWS
|
|
char * val = new char[32767];
|
|
int n = GetEnvironmentVariable(v.c_str(), val, 32767);
|
|
string rtn = "";
|
|
if (n>0)
|
|
rtn = (string)val;
|
|
delete val;
|
|
return rtn;
|
|
#else
|
|
char * c = getenv(v.c_str());
|
|
if(c != NULL)
|
|
return (string) c;
|
|
return "";
|
|
#endif
|
|
}
|
|
|
|
inline int rc_intern_setEnv(string name, string value, int overwrite)
|
|
{
|
|
#ifdef RC_WINDOWS
|
|
//string env_cmd = name + "=" + value;
|
|
return SetEnvironmentVariable(name.c_str(), value.c_str()) ? 1 : 0;
|
|
//return _putenv(name.c_str());
|
|
#else
|
|
return setenv(name.c_str(), value.c_str(), overwrite);
|
|
#endif
|
|
}
|
|
|
|
inline string rc_intern_prefPath(string org_name, string app_name)
|
|
{
|
|
return (string) SDL_GetPrefPath(org_name.c_str(), app_name.c_str());
|
|
}
|
|
|
|
inline int rc_intern_push_n(double n)
|
|
{
|
|
rc_user_n_stack[rc_user_active_n_stack].push(n);
|
|
return 1;
|
|
}
|
|
|
|
inline int rc_intern_push_s(string s)
|
|
{
|
|
rc_user_s_stack[rc_user_active_s_stack].push(s);
|
|
return 1;
|
|
}
|
|
|
|
inline double rc_intern_pop_n()
|
|
{
|
|
double n = rc_user_n_stack[rc_user_active_n_stack].top();
|
|
rc_user_n_stack[rc_user_active_n_stack].pop();
|
|
return n;
|
|
}
|
|
|
|
inline string rc_intern_pop_s()
|
|
{
|
|
string s = rc_user_s_stack[rc_user_active_s_stack].top();
|
|
rc_user_s_stack[rc_user_active_s_stack].pop();
|
|
return s;
|
|
}
|
|
|
|
inline unsigned long rc_intern_n_stack_size()
|
|
{
|
|
return rc_user_n_stack[rc_user_active_n_stack].size();
|
|
}
|
|
|
|
inline unsigned long rc_intern_s_stack_size()
|
|
{
|
|
return rc_user_s_stack[rc_user_active_s_stack].size();
|
|
}
|
|
|
|
inline void rc_intern_getPowerInfo(double * status, double * secs, double * pct)
|
|
{
|
|
int s = 0;
|
|
int p = 0;
|
|
SDL_PowerState p_state = SDL_GetPowerInfo(&s, &p);
|
|
*secs = (double)s;
|
|
*pct = (double)p;
|
|
if(p_state == SDL_POWERSTATE_UNKNOWN)
|
|
*status = 0;
|
|
else if(p_state == SDL_POWERSTATE_ON_BATTERY)
|
|
*status = 1;
|
|
else if(p_state == SDL_POWERSTATE_NO_BATTERY)
|
|
*status = 2;
|
|
else if(p_state == SDL_POWERSTATE_CHARGING)
|
|
*status = 3;
|
|
else if(p_state == SDL_POWERSTATE_CHARGED)
|
|
*status = 4;
|
|
else
|
|
*status = -1;
|
|
}
|
|
|
|
int rc_intern_systemRam()
|
|
{
|
|
return SDL_GetSystemRAM();
|
|
}
|
|
|
|
#ifdef RC_WEB
|
|
string rc_intern_evalJS(string js_code)
|
|
{
|
|
return emscripten_run_script_string(js_code.c_str());
|
|
}
|
|
#else
|
|
string rc_intern_evalJS(string js_code)
|
|
{
|
|
return "ONLY IN WEB";
|
|
}
|
|
#endif
|
|
|
|
|
|
//MOBILE OS STUFF
|
|
inline string rc_intern_android_getInternalStoragePath()
|
|
{
|
|
#ifdef RC_ANDROID
|
|
return SDL_AndroidGetInternalStoragePath();
|
|
#else
|
|
return "";
|
|
#endif
|
|
}
|
|
|
|
inline string rc_intern_android_getExternalStoragePath()
|
|
{
|
|
#ifdef RC_ANDROID
|
|
return SDL_AndroidGetExternalStoragePath();
|
|
#else
|
|
return "";
|
|
#endif
|
|
}
|
|
|
|
inline int rc_intern_android_getExternalStorageState()
|
|
{
|
|
#ifdef RC_ANDROID
|
|
return SDL_AndroidGetExternalStorageState();
|
|
#else
|
|
return 0;
|
|
#endif
|
|
}
|
|
|
|
string rc_intern_android_jni_message(string arg_c)
|
|
{
|
|
#ifdef RC_ANDROID
|
|
|
|
// retrieve the JNI environment.
|
|
JNIEnv* env = (JNIEnv*)SDL_AndroidGetJNIEnv();
|
|
|
|
// retrieve the Java instance of the SDLActivity
|
|
jobject activity = (jobject)SDL_AndroidGetActivity();
|
|
|
|
// find the Java class of the activity. It should be SDLActivity or a subclass of it.
|
|
jclass clazz(env->GetObjectClass(activity));
|
|
|
|
//return "### what the balls :-) ";
|
|
|
|
jmethodID rcbasic_android_method = env->GetStaticMethodID(clazz, "rcbasic_android_interface", "(Ljava/lang/String;)Ljava/lang/String;");
|
|
|
|
jstring arg = env->NewStringUTF(arg_c.c_str());
|
|
|
|
jstring rv = (jstring)env->CallStaticObjectMethod(clazz, rcbasic_android_method, arg);
|
|
const char * strReturn = env->GetStringUTFChars( rv, 0);
|
|
|
|
env->ReleaseStringUTFChars(rv, strReturn);
|
|
|
|
// clean up the local references.
|
|
env->DeleteLocalRef(activity);
|
|
env->DeleteLocalRef(clazz);
|
|
|
|
return (string)strReturn;
|
|
|
|
#else
|
|
return "";
|
|
#endif
|
|
}
|
|
|
|
#ifdef RC_IOS
|
|
#include "rcbasic_ios_native.h"
|
|
#else
|
|
string rc_intern_runtime_utility(string arg)
|
|
{
|
|
return "";
|
|
}
|
|
#endif
|
|
|
|
#endif // RC_STDLIB_H_INCLUDED
|