#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 #endif #ifdef RC_ANDROID #define RC_GETCWD #endif #include #include #include #include #include #include #include #include #include #include #include #include //file system stuff #include //file system stuff #include //file system stuff #include #include #include #include #ifdef RC_ANDROID #include "SDL.h" #include #else #include #endif // #ifdef RC_WINDOWS #define WIN32_LEAN_AND_MEAN #include #include #include #include #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 data; }; struct rc_str_stack_obj { bool active = false; stack data; }; vector rc_user_n_stack; vector 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(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, char32_t> conv; return conv.from_bytes(s); } inline int rc_intern_asc(std::string c) { 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(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(0x80 | (cp & 0x3F)); cp >>= 6; } utf8[0] |= static_cast(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= 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 l_string; } 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 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 ""; 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 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) { stringstream ss; ss << n; return ss.str(); } inline std::string rc_intern_str_f(double n) { stringstream ss; ss << fixed << n; return ss.str(); } inline std::string rc_intern_str_s(double n) { 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) { return rc_intern_ltrim(rc_intern_rtrim(t_string)); } inline std::string rc_intern_ucase(std::string u_string) { std::string u_string_out = ""; for(size_t i=0;i>= 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) { stringstream ss; ss << hex << n; return ss.str(); } inline double rc_intern_hexInt(std::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_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) { #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 #endif // RC_STDLIB_H_INCLUDED