* Finished working on tiling * Changed how sprite layers work. Sprite layers are now not confined to the limits of the actual canvas but instead will decide where to draw each sprite based on the canvas offset and the sprites location
1668 lines
37 KiB
C++
Executable File
1668 lines
37 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;
|
|
std::string rc_dir_path = "";
|
|
|
|
#else
|
|
|
|
struct dirent *rc_entry;
|
|
std::string rc_dir;
|
|
std::string rc_dir_path = "";
|
|
HANDLE hfind;
|
|
|
|
#endif // RC_LINUX
|
|
|
|
|
|
int rc_cmd_count = 0;
|
|
std::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;
|
|
|
|
struct rc_num_stack_obj
|
|
{
|
|
bool active = false;
|
|
stack<double> data;
|
|
};
|
|
|
|
struct rc_str_stack_obj
|
|
{
|
|
bool active = false;
|
|
stack<std::string> data;
|
|
};
|
|
|
|
vector<rc_num_stack_obj> rc_user_n_stack;
|
|
vector<rc_str_stack_obj> rc_user_s_stack;
|
|
|
|
#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(std::string txt)
|
|
{
|
|
cout << txt;
|
|
}
|
|
|
|
std::string rc_input(std::string prompt)
|
|
{
|
|
#ifdef RC_WINDOWS
|
|
|
|
std::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 (std::string) mb_str;
|
|
|
|
#else
|
|
|
|
std::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(std::string c)
|
|
{
|
|
if(c.length()==0)
|
|
return 0;
|
|
return (uint32_t)to_utf32(utf8_substr(c, 0, 1))[0];
|
|
}
|
|
|
|
inline size_t rc_intern_bufferFromString(std::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 std::string rc_intern_chr(uint32_t n)
|
|
{
|
|
std::string s = cpToUTF8(n);
|
|
//s += (char) n;
|
|
return s;
|
|
}
|
|
|
|
inline std::string rc_intern_insert(std::string src, std::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(std::string in_string, std::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 std::string rc_intern_lcase(std::string u_string)
|
|
{
|
|
std::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 std::string rc_intern_left(std::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(std::string l_string)
|
|
{
|
|
//cout << "DBG_LEN" << endl;
|
|
return utf8_length(l_string);
|
|
}
|
|
|
|
inline std::string rc_intern_ltrim(std::string l_string)
|
|
{
|
|
size_t first_index = l_string.find_first_not_of(" ");
|
|
if(first_index != std::string::npos)
|
|
return l_string.substr(first_index);
|
|
return "";
|
|
}
|
|
|
|
inline std::string rc_intern_mid(std::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 std::string rc_intern_replaceSubstr(std::string src, std::string rpc, size_t pos)
|
|
{
|
|
size_t rpc_i = 0;
|
|
std::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 std::string rc_intern_replace(std::string src, std::string tgt, std::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 != std::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 std::string rc_intern_reverse(std::string rpc_string)
|
|
{
|
|
std::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 std::string rc_intern_right(std::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 std::string rc_intern_rtrim(std::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 "";
|
|
|
|
if(src.find_first_not_of(" ") == std::string::npos)
|
|
return "";
|
|
|
|
return utf8_substr(src,0,i+1);
|
|
}
|
|
|
|
inline size_t rc_intern_size(std::string src)
|
|
{
|
|
return src.length();
|
|
}
|
|
|
|
inline std::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 (std::string)c_buf;
|
|
}
|
|
|
|
inline std::string rc_intern_stringfill(std::string f_string, size_t n)
|
|
{
|
|
std::string f = "";
|
|
for(size_t i = 0; i < n; i++)
|
|
f += f_string;
|
|
return f;
|
|
}
|
|
|
|
inline std::string rc_intern_str(double n)
|
|
{
|
|
std::stringstream ss;
|
|
ss << n;
|
|
return ss.str();
|
|
}
|
|
|
|
inline std::string rc_intern_str_f(double n)
|
|
{
|
|
std::stringstream ss;
|
|
ss << fixed << n;
|
|
return ss.str();
|
|
}
|
|
|
|
inline std::string rc_intern_str_s(double n)
|
|
{
|
|
std::stringstream ss;
|
|
ss << scientific << n;
|
|
return ss.str();
|
|
}
|
|
|
|
inline unsigned long rc_intern_tally(std::string t_string, std::string t_substring)
|
|
{
|
|
size_t found = 0;
|
|
std::string t_str = t_string;
|
|
std::string t_substr = t_substring;
|
|
found = t_str.find(t_substr);
|
|
unsigned long tally_count = 0;
|
|
while( found != std::string::npos)
|
|
{
|
|
tally_count++;
|
|
found = t_str.find(t_substr,found+1);
|
|
}
|
|
return tally_count;
|
|
}
|
|
|
|
inline std::string rc_intern_trim(std::string t_string)
|
|
{
|
|
std::string trim_str = rc_intern_ltrim(rc_intern_rtrim(t_string));
|
|
if(trim_str.compare(" ")==0)
|
|
return "";
|
|
return trim_str;
|
|
}
|
|
|
|
inline std::string rc_intern_ucase(std::string u_string)
|
|
{
|
|
std::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(std::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
|
|
std::string Convert(unsigned int val)
|
|
{
|
|
unsigned int mask = 1 << (sizeof(int) * 8 - 1);
|
|
std::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 std::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"));
|
|
std::string binstr = Convert(n);// bin_str;
|
|
return binstr.substr(binstr.find_first_not_of("0"));
|
|
}
|
|
#else
|
|
|
|
inline std::string rc_intern_bin(uint64_t n)
|
|
{
|
|
std::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 std::string rc_intern_hex(uint64_t n)
|
|
{
|
|
std::stringstream ss;
|
|
ss << hex << n;
|
|
return ss.str();
|
|
}
|
|
|
|
inline double rc_intern_hexInt(std::string n)
|
|
{
|
|
uint64_t x;
|
|
std::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_freeFile()
|
|
{
|
|
for(int i = 0; i < RC_MAX_FILES; i++)
|
|
if(rc_fstream[i] == NULL)
|
|
return i;
|
|
return -1;
|
|
}
|
|
|
|
inline int rc_intern_fileOpen(std::string fo_file, int fo_mode)
|
|
{
|
|
int fo_stream = rc_intern_freeFile();
|
|
|
|
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 -1;
|
|
}
|
|
}
|
|
return fo_stream;
|
|
}
|
|
|
|
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 std::string rc_intern_fileReadLine(int f_stream)
|
|
{
|
|
std::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, std::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, std::string line)
|
|
{
|
|
//cout << "DEBUG: WRITELINE" << endl;
|
|
std::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(std::string src_file, std::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(std::string tgt_file)
|
|
{
|
|
if(remove(tgt_file.c_str())==0)
|
|
return 1;
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
inline int rc_intern_fileExist(std::string tgt_file)
|
|
{
|
|
std::ifstream infile(tgt_file.c_str());
|
|
bool fx = infile.good();
|
|
infile.close();
|
|
return (int)fx;
|
|
}
|
|
|
|
inline int rc_intern_fileMove(std::string src, std::string dst)
|
|
{
|
|
int fm = rename(src.c_str(), dst.c_str());
|
|
if(fm == 0)
|
|
return 1;
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
inline int rc_intern_fileRename(std::string src, std::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(std::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];
|
|
}
|
|
|
|
|
|
#ifndef RC_WINDOWS
|
|
|
|
#ifdef RC_LINUX
|
|
inline int rc_intern_dirChange(std::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(std::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 std::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
|
|
std::string getcwd_str()
|
|
{
|
|
char *buffer = new char[MAXPATHLEN];
|
|
getcwd(buffer,MAXPATHLEN);
|
|
if(buffer != NULL)
|
|
{
|
|
std::string ret(buffer);
|
|
delete[] buffer;
|
|
return ret;
|
|
}
|
|
else
|
|
{
|
|
return std::string();
|
|
}
|
|
}
|
|
|
|
|
|
inline int rc_intern_dirChange(std::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 std::string rc_intern_dir()
|
|
{
|
|
std::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 std::string rc_intern_dir()
|
|
{
|
|
std::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 std::string rc_intern_dirNext()
|
|
{
|
|
if( (rc_entry = readdir(rc_dir))!=NULL)
|
|
return rc_entry->d_name;
|
|
return "";
|
|
}
|
|
|
|
inline int rc_intern_dirCreate(std::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(std::string d_path)
|
|
{
|
|
if(rmdir(d_path.c_str())!=0)
|
|
{
|
|
cout << "ERROR: Could not delete directory" << endl;
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
inline std::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(std::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(std::string dpath)
|
|
{
|
|
return dirExists(dpath);
|
|
}
|
|
|
|
HANDLE hFind;
|
|
WIN32_FIND_DATAW ffd;
|
|
|
|
std::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("*.*"));
|
|
|
|
|
|
std::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 "";
|
|
}
|
|
std::string fname_utf8 = ConvertWideToUtf8(ffd.cFileName);
|
|
return fname_utf8;
|
|
}
|
|
|
|
inline std::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());
|
|
}
|
|
|
|
std::string rc_intern_dirNext()
|
|
{
|
|
if(!FindNextFileW(hFind,&ffd))
|
|
return "";
|
|
return ConvertWideToUtf8(ffd.cFileName);
|
|
}
|
|
|
|
inline int rc_intern_dirCreate(std::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(std::string dpath)
|
|
{
|
|
if(RemoveDirectoryW(ConvertUtf8ToWide(dpath).c_str())==0)
|
|
{
|
|
cout << "ERROR: Could not delete directory" << endl;
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
inline std::string rc_intern_OS()
|
|
{
|
|
return "WINDOWS";
|
|
}
|
|
|
|
#endif // RC_WINDOWS
|
|
|
|
|
|
inline std::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();
|
|
}
|
|
|
|
std::string ZeroPadNumber(int num)
|
|
{
|
|
stringstream ss;
|
|
// the number is converted to string with the help of stringstream
|
|
ss << num;
|
|
std::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;
|
|
}
|
|
|
|
std::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 std::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(std::string rc_sys_cmd)
|
|
{
|
|
#ifdef RC_IOS
|
|
return 0;
|
|
#else
|
|
return system(rc_sys_cmd.c_str());
|
|
#endif
|
|
}
|
|
|
|
inline std::string rc_intern_sysReturnOutput(std::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 std::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 std::string rc_intern_env(std::string v)
|
|
{
|
|
#ifdef RC_WINDOWS
|
|
char * val = new char[32767];
|
|
int n = GetEnvironmentVariable(v.c_str(), val, 32767);
|
|
std::string rtn = "";
|
|
if (n>0)
|
|
rtn = (std::string)val;
|
|
delete val;
|
|
return rtn;
|
|
#else
|
|
char * c = getenv(v.c_str());
|
|
if(c != NULL)
|
|
return (std::string) c;
|
|
return "";
|
|
#endif
|
|
}
|
|
|
|
inline int rc_intern_setEnv(std::string name, std::string value)
|
|
{
|
|
int overwrite = 1;
|
|
#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 std::string rc_intern_prefPath(std::string org_name, std::string app_name)
|
|
{
|
|
return (std::string) SDL_GetPrefPath(org_name.c_str(), app_name.c_str());
|
|
}
|
|
|
|
|
|
inline int rc_intern_createStack_N()
|
|
{
|
|
int id = -1;
|
|
for(int i = 0; i < rc_user_n_stack.size(); i++)
|
|
{
|
|
if(!rc_user_n_stack[i].active)
|
|
{
|
|
id = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(id < 0)
|
|
{
|
|
rc_num_stack_obj usr_stack;
|
|
usr_stack.active = true;
|
|
id = rc_user_n_stack.size();
|
|
rc_user_n_stack.push_back(usr_stack);
|
|
}
|
|
else
|
|
{
|
|
while(!rc_user_n_stack[id].data.empty())
|
|
rc_user_n_stack[id].data.pop();
|
|
rc_user_n_stack[id].active = true;
|
|
}
|
|
|
|
return id;
|
|
}
|
|
|
|
inline int rc_intern_createStack_S()
|
|
{
|
|
int id = -1;
|
|
for(int i = 0; i < rc_user_s_stack.size(); i++)
|
|
{
|
|
if(!rc_user_s_stack[i].active)
|
|
{
|
|
id = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(id < 0)
|
|
{
|
|
rc_str_stack_obj usr_stack;
|
|
usr_stack.active = true;
|
|
id = rc_user_s_stack.size();
|
|
rc_user_s_stack.push_back(usr_stack);
|
|
}
|
|
else
|
|
{
|
|
while(!rc_user_s_stack[id].data.empty())
|
|
rc_user_s_stack[id].data.pop();
|
|
rc_user_s_stack[id].active = true;
|
|
}
|
|
|
|
return id;
|
|
}
|
|
|
|
inline void rc_intern_clearStack_N( int stack_id )
|
|
{
|
|
while(!rc_user_n_stack[stack_id].data.empty())
|
|
rc_user_n_stack[stack_id].data.pop();
|
|
}
|
|
|
|
inline void rc_intern_clearStack_S( int stack_id )
|
|
{
|
|
while(!rc_user_s_stack[stack_id].data.empty())
|
|
rc_user_s_stack[stack_id].data.pop();
|
|
}
|
|
|
|
inline void rc_intern_deleteStack_N( int stack_id )
|
|
{
|
|
rc_intern_clearStack_N(stack_id);
|
|
rc_user_n_stack[stack_id].active = false;
|
|
}
|
|
|
|
inline void rc_intern_deleteStack_S( int stack_id )
|
|
{
|
|
rc_intern_clearStack_S(stack_id);
|
|
rc_user_s_stack[stack_id].active = false;
|
|
}
|
|
|
|
inline void rc_intern_push_n( int stack_id, double n)
|
|
{
|
|
rc_user_n_stack[stack_id].data.push(n);
|
|
}
|
|
|
|
inline void rc_intern_push_s( int stack_id, std::string s)
|
|
{
|
|
rc_user_s_stack[stack_id].data.push(s);
|
|
}
|
|
|
|
inline double rc_intern_pop_n( int stack_id )
|
|
{
|
|
double n = rc_user_n_stack[stack_id].data.top();
|
|
rc_user_n_stack[stack_id].data.pop();
|
|
return n;
|
|
}
|
|
|
|
inline std::string rc_intern_pop_s( int stack_id )
|
|
{
|
|
std::string s = rc_user_s_stack[stack_id].data.top();
|
|
rc_user_s_stack[stack_id].data.pop();
|
|
return s;
|
|
}
|
|
|
|
inline unsigned long rc_intern_n_stack_size( int stack_id )
|
|
{
|
|
return rc_user_n_stack[stack_id].data.size();
|
|
}
|
|
|
|
inline unsigned long rc_intern_s_stack_size( int stack_id )
|
|
{
|
|
return rc_user_s_stack[stack_id].data.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
|
|
std::string rc_intern_evalJS(std::string js_code)
|
|
{
|
|
return emscripten_run_script_string(js_code.c_str());
|
|
}
|
|
#else
|
|
std::string rc_intern_evalJS(std::string js_code)
|
|
{
|
|
return "ONLY IN WEB";
|
|
}
|
|
#endif
|
|
|
|
|
|
//MOBILE OS STUFF
|
|
inline std::string rc_intern_android_getInternalStoragePath()
|
|
{
|
|
#ifdef RC_ANDROID
|
|
return SDL_AndroidGetInternalStoragePath();
|
|
#else
|
|
return "";
|
|
#endif
|
|
}
|
|
|
|
inline std::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
|
|
}
|
|
|
|
std::string rc_intern_android_jni_message(std::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 (std::string)strReturn;
|
|
|
|
#else
|
|
return "";
|
|
#endif
|
|
}
|
|
|
|
#ifdef RC_IOS
|
|
#include "rcbasic_ios_native.h"
|
|
#else
|
|
std::string rc_intern_runtime_utility(std::string arg)
|
|
{
|
|
return "";
|
|
}
|
|
#endif
|
|
|
|
|
|
int rc_numCPUs()
|
|
{
|
|
return SDL_GetCPUCount();
|
|
}
|
|
|
|
#endif // RC_STDLIB_H_INCLUDED
|