Push to git

This commit is contained in:
2025-01-08 09:59:16 -06:00
parent 36d985cc57
commit dad571f169
28 changed files with 983 additions and 181 deletions

View File

@ -1,3 +1,4 @@
#ifndef CROSSLANG_CUSTOM_CONSOLE
#include "CrossLang.hpp"
#include <iostream>
@ -13,14 +14,14 @@ namespace Tesses::CrossLang {
struct termios orig_termios;
static void disableRawMode()
{
tcsetattr(STDIN_FILENO, TCSAFLUSH, &orig_termios);
tcsetattr(0, TCSAFLUSH, &orig_termios);
}
#endif
TObject Console_getEcho(GCList& ls, std::vector<TObject> args)
{
#ifdef CROSSLANG_ENABLE_TERMIOS
struct termios raw;
tcgetattr(STDIN_FILENO, &raw);
tcgetattr(0, &raw);
return (raw.c_lflag & ECHO) > 0;
#endif
@ -33,7 +34,7 @@ namespace Tesses::CrossLang {
bool cooked = std::get<bool>(args[0]);
#ifdef CROSSLANG_ENABLE_TERMIOS
struct termios raw;
tcgetattr(STDIN_FILENO, &raw);
tcgetattr(0, &raw);
if(cooked)
{
raw.c_lflag |= ECHO;
@ -43,7 +44,7 @@ namespace Tesses::CrossLang {
raw.c_lflag &= ~(ECHO);
}
tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw);
tcsetattr(0, TCSAFLUSH, &raw);
#endif
return cooked;
@ -54,7 +55,7 @@ namespace Tesses::CrossLang {
{
#ifdef CROSSLANG_ENABLE_TERMIOS
struct termios raw;
tcgetattr(STDIN_FILENO, &raw);
tcgetattr(0, &raw);
return (raw.c_lflag & ICANON) > 0;
#endif
@ -67,7 +68,7 @@ namespace Tesses::CrossLang {
bool cooked = std::get<bool>(args[0]);
#ifdef CROSSLANG_ENABLE_TERMIOS
struct termios raw;
tcgetattr(STDIN_FILENO, &raw);
tcgetattr(0, &raw);
if(cooked)
{
raw.c_lflag |= ICANON;
@ -77,7 +78,7 @@ namespace Tesses::CrossLang {
raw.c_lflag &= ~(ICANON);
}
tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw);
tcsetattr(0, TCSAFLUSH, &raw);
#endif
return cooked;
@ -88,7 +89,7 @@ namespace Tesses::CrossLang {
{
#ifdef CROSSLANG_ENABLE_TERMIOS
struct termios raw;
tcgetattr(STDIN_FILENO, &raw);
tcgetattr(0, &raw);
return (raw.c_lflag & ISIG) > 0;
#endif
@ -101,7 +102,7 @@ namespace Tesses::CrossLang {
bool cooked = std::get<bool>(args[0]);
#ifdef CROSSLANG_ENABLE_TERMIOS
struct termios raw;
tcgetattr(STDIN_FILENO, &raw);
tcgetattr(0, &raw);
if(cooked)
{
raw.c_lflag |= ISIG;
@ -111,7 +112,7 @@ namespace Tesses::CrossLang {
raw.c_lflag &= ~(ISIG);
}
tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw);
tcsetattr(0, TCSAFLUSH, &raw);
#endif
return cooked;
@ -164,7 +165,7 @@ namespace Tesses::CrossLang {
{
env->permissions.canRegisterConsole=true;
#ifdef CROSSLANG_ENABLE_TERMIOS
tcgetattr(STDIN_FILENO, &orig_termios);
tcgetattr(0, &orig_termios);
atexit(disableRawMode);
#endif
GCList ls(gc);
@ -186,4 +187,5 @@ namespace Tesses::CrossLang {
env->DeclareVariable("Console", dict);
gc->BarrierEnd();
}
}
}
#endif

View File

@ -1,12 +1,13 @@
#include "CrossLang.hpp"
#if defined(CROSSLANG_ENABLE_MBED)
#include <TessesFramework/TessesFrameworkFeatures.h>
#if defined(TESSESFRAMEWORK_ENABLE_MBED)
#include <iostream>
#include <mbedtls/sha1.h>
#include <mbedtls/sha256.h>
#include <mbedtls/sha512.h>
#include <mbedtls/base64.h>
#include <mbedtls/pkcs5.h>
#include <mbedtls/entropy.h>
#include <mbedtls/ctr_drbg.h>
#include <mbedtls/x509.h>
@ -18,8 +19,94 @@
namespace Tesses::CrossLang
{
#if defined(CROSSLANG_ENABLE_MBED)
#if defined(TESSESFRAMEWORK_ENABLE_MBED)
static TObject Crypto_RandomBytes(GCList& ls, std::vector<TObject> args)
{
int64_t size;
std::string personalStr;
if(GetArgument(args,0,size) && GetArgument(args,1,personalStr))
{
mbedtls_entropy_context entropy;
mbedtls_ctr_drbg_context ctr_drbg;
mbedtls_entropy_init(&entropy);
mbedtls_ctr_drbg_init(&ctr_drbg);
int ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, (const unsigned char *) "personalization_string", strlen("personalization_string"));
if(ret != 0)
{
mbedtls_ctr_drbg_free(&ctr_drbg);
mbedtls_entropy_free(&entropy);
return nullptr;
}
std::vector<uint8_t> bytes;
bytes.resize((size_t)size);
ret = mbedtls_ctr_drbg_random(&ctr_drbg, bytes.data(),bytes.size());
if (ret != 0)
{
mbedtls_ctr_drbg_free(&ctr_drbg);
mbedtls_entropy_free(&entropy);
return nullptr;
}
mbedtls_ctr_drbg_free(&ctr_drbg);
mbedtls_entropy_free(&entropy);
TByteArray* ba = TByteArray::Create(ls);
ba->data = bytes;
return ba;
}
return nullptr;
}
static TObject Crypto_PBKDF2(GCList& ls, std::vector<TObject> args)
{
std::string pass;
TByteArray* bArraySalt;
int64_t itterations;
int64_t keylength;
int64_t shanum;
if(GetArgument(args,0,pass) && GetArgumentHeap(args,1, bArraySalt) && GetArgument(args,2, itterations) && GetArgument(args,3,keylength) && GetArgument(args,4,shanum))
{
mbedtls_md_context_t ctx;
mbedtls_md_init(&ctx);
const mbedtls_md_info_t* info = NULL;
switch(shanum)
{
case 1:
info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1);
break;
case 224:
info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA224);
break;
case 256:
info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
break;
default:
case 384:
info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA384);
break;
case 512:
info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA512);
break;
}
mbedtls_md_setup(&ctx, info, 1);
std::vector<uint8_t> key;
key.resize((size_t)keylength);
if(mbedtls_pkcs5_pbkdf2_hmac(&ctx, (const unsigned char*)pass.c_str(), pass.size(), bArraySalt->data.data(), bArraySalt->data.size(), (int)itterations,(uint32_t)key.size(),key.data()) == 0)
{
auto ba = TByteArray::Create(ls);
ba->data = key;
mbedtls_md_free(&ctx);
return ba;
}
mbedtls_md_free(&ctx);
}
return nullptr;
}
static TObject Crypto_Sha1(GCList& ls, std::vector<TObject> args)
{
@ -228,9 +315,9 @@ namespace Tesses::CrossLang
}
return "";
}
return "";
}
static TObject Crypto_Base64Decode(GCList& ls, std::vector<TObject> args)
{
@ -253,58 +340,27 @@ namespace Tesses::CrossLang
}
return "";
}
#endif
void TStd::RegisterCrypto(GC* gc,TRootEnvironment* env)
{
env->permissions.canRegisterCrypto=true;
#if defined(CROSSLANG_ENABLE_MBED)
#if defined(TESSESFRAMEWORK_ENABLE_MBED)
GCList ls(gc);
TDictionary* dict = TDictionary::Create(ls);
dict->DeclareFunction(gc, "PBKDF2","Hash passwords with PBKDF2",{"pass","salt","itterations","keylen","shanum"},Crypto_PBKDF2);
dict->DeclareFunction(gc, "RandomBytes","Create bytearray but with random bytes in it instead of zeros (this uses mbedtls by the way)",{"byteCount","personalString"},Crypto_RandomBytes);
dict->DeclareFunction(gc, "Sha1","Sha1 Algorithm (needed for WebSocket handshake/BitTorrent etc) (don't use unless you have no other choice)",{},Crypto_Sha1);
dict->DeclareFunction(gc, "Sha256","Sha256 Algorithm",{"$is224"},Crypto_Sha256);
dict->DeclareFunction(gc, "Sha512","Sha512 Algorithm",{"$is384"},Crypto_Sha512);
dict->DeclareFunction(gc, "Base64Encode","Sha512 Algorithm",{"data"},Crypto_Base64Encode);
dict->DeclareFunction(gc, "Base64Encode","Base64 encode",{"data"},Crypto_Base64Encode);
dict->DeclareFunction(gc, "Base64Decode","Base64 decode",{"str"},Crypto_Base64Decode);
gc->BarrierBegin();
env->DeclareVariable("Crypto", dict);
gc->BarrierEnd();
dict = TDictionary::Create(ls);
dict->DeclareFunction(gc, "Encode","Encode Base64",{"buffer","offset","count"},[](GCList& ls,std::vector<TObject> args)->TObject{
TByteArray* bArray;
int64_t offset;
int64_t count;
if(!GetArgumentHeap<TByteArray*>(args,0,bArray))
return nullptr;
if(!GetArgument<int64_t>(args,1, offset))
return nullptr;
if(!GetArgument<int64_t>(args,2, count))
return nullptr;
size_t off = (size_t)offset;
size_t len = (size_t)count;
off = std::min(off, bArray->data.size());
len = std::min(len, bArray->data.size()-off);
size_t outLen = ((4 * len / 3) + 3) & ~3;
std::string str(outLen,'\0');
if(mbedtls_base64_encode((unsigned char*)str.data(),str.size(),&outLen,bArray->data.data(),bArray->data.size()) != 0)
return nullptr;
str.resize(outLen);
return str;
//bArray->data.size();
//
});
#endif
}

View File

@ -1,15 +1,55 @@
#include "CrossLang.hpp"
#if defined(CROSSLANG_ENABLE_PLATFORM_FOLDERS)
#include "../sago/platform_folders.h"
#endif
#if defined(_WIN32)
#include <windows.h>
#endif
namespace Tesses::CrossLang
{
#if defined(_WIN32)
static char EnvPathSeperator=';';
#else
static char EnvPathSeperator=':';
#endif
Tesses::Framework::Filesystem::VFSPath GetRealExecutablePath(Tesses::Framework::Filesystem::VFSPath realPath)
{
using namespace Tesses::Framework::Filesystem;
using namespace Tesses::Framework::Http;
LocalFilesystem lfs;
if(!realPath.relative) return realPath;
const char* path = std::getenv("PATH");
#if defined(_WIN32)
const char* pathext = std::getenv("PATHEXT");
auto pext = HttpUtils::SplitString(pathext,";");
pext.push_back({});
auto pathParts = HttpUtils::SplitString(path,";");
for(auto item : pathParts)
{
for(auto item2 : pext)
{
auto newPath = (lfs.SystemToVFSPath(item) / realPath) + item2;
if(lfs.FileExists(newPath)) return newPath;
}
}
return realPath.RelativeCurrentDirectory();
#else
auto pathParts = HttpUtils::SplitString(path,":");
for(auto item : pathParts)
{
auto newPath = lfs.SystemToVFSPath(item) / realPath;
if(lfs.FileExists(newPath)) return newPath;
}
return realPath.RelativeCurrentDirectory();
#endif
}
static std::string GetHomeFolder()
{
#if !defined(SAGO_DISABLE)
#if defined(CROSSLANG_ENABLE_PLATFORM_FOLDERS)
return sago::getHomeDir();
#elif defined(__EMSCRIPTEN__)
return "/home/web_user";
@ -98,7 +138,7 @@ namespace Tesses::CrossLang
}
static TObject Env_getDownloads(GCList& ls, std::vector<TObject> args)
{
#if !defined(SAGO_DISABLE)
#if defined(CROSSLANG_ENABLE_PLATFORM_FOLDERS)
return sago::getDownloadFolder();
#else
return GetHomeFolder() + "/Downloads";
@ -107,7 +147,7 @@ namespace Tesses::CrossLang
static TObject Env_getMusic(GCList& ls, std::vector<TObject> args)
{
#if !defined(SAGO_DISABLE)
#if defined(CROSSLANG_ENABLE_PLATFORM_FOLDERS)
return sago::getMusicFolder();
#else
return GetHomeFolder() + "/Music";
@ -115,7 +155,7 @@ namespace Tesses::CrossLang
}
static TObject Env_getPictures(GCList& ls, std::vector<TObject> args)
{
#if !defined(SAGO_DISABLE)
#if defined(CROSSLANG_ENABLE_PLATFORM_FOLDERS)
return sago::getPicturesFolder();
#else
return GetHomeFolder() + "/Pictures";
@ -123,7 +163,7 @@ namespace Tesses::CrossLang
}
static TObject Env_getVideos(GCList& ls, std::vector<TObject> args)
{
#if !defined(SAGO_DISABLE)
#if defined(CROSSLANG_ENABLE_PLATFORM_FOLDERS)
return sago::getVideoFolder();
#else
return GetHomeFolder() + "/Videos";
@ -131,7 +171,7 @@ namespace Tesses::CrossLang
}
static TObject Env_getDocuments(GCList& ls, std::vector<TObject> args)
{
#if !defined(SAGO_DISABLE)
#if defined(CROSSLANG_ENABLE_PLATFORM_FOLDERS)
return sago::getDocumentsFolder();
#else
return GetHomeFolder() + "/Documents";
@ -139,7 +179,7 @@ namespace Tesses::CrossLang
}
static TObject Env_getConfig(GCList& ls, std::vector<TObject> args)
{
#if !defined(SAGO_DISABLE)
#if defined(CROSSLANG_ENABLE_PLATFORM_FOLDERS)
return sago::getConfigHome();
#else
return GetHomeFolder() + "/Config";
@ -148,7 +188,7 @@ namespace Tesses::CrossLang
static TObject Env_getDesktop(GCList& ls, std::vector<TObject> args)
{
#if !defined(SAGO_DISABLE)
#if defined(CROSSLANG_ENABLE_PLATFORM_FOLDERS)
return sago::getDesktopFolder();
#else
return GetHomeFolder() + "/Desktop";
@ -156,7 +196,7 @@ namespace Tesses::CrossLang
}
static TObject Env_getState(GCList& ls, std::vector<TObject> args)
{
#if !defined(SAGO_DISABLE)
#if defined(CROSSLANG_ENABLE_PLATFORM_FOLDERS)
return sago::getStateDir();
#else
return GetHomeFolder() + "/State";
@ -164,7 +204,7 @@ namespace Tesses::CrossLang
}
static TObject Env_getCache(GCList& ls, std::vector<TObject> args)
{
#if !defined(SAGO_DISABLE)
#if defined(CROSSLANG_ENABLE_PLATFORM_FOLDERS)
return sago::getCacheDir();
#else
return GetHomeFolder() + "/Cache";
@ -172,7 +212,7 @@ namespace Tesses::CrossLang
}
static TObject Env_getData(GCList& ls, std::vector<TObject> args)
{
#if !defined(SAGA_DISABLE)
#if defined(CROSSLANG_ENABLE_PLATFORM_FOLDERS)
return sago::getDataHome();
#else
return GetHomeFolder() + "/Data";
@ -182,6 +222,15 @@ namespace Tesses::CrossLang
{
return GetHomeFolder();
}
static TObject Env_GetRealExecutablePath(GCList& ls, std::vector<TObject> args)
{
Tesses::Framework::Filesystem::VFSPath p;
if(GetArgumentAsPath(args,0,p))
{
return GetRealExecutablePath(p);
}
return Tesses::Framework::Filesystem::VFSPath();
}
void TStd::RegisterEnv(GC* gc, TRootEnvironment* env)
{
@ -203,9 +252,10 @@ namespace Tesses::CrossLang
dict->DeclareFunction(gc,"getData","Get data folder",{},Env_getData);
dict->DeclareFunction(gc,"getUser","Get user folder",{},Env_getUser);
dict->DeclareFunction(gc,"getPlatform","Get platform name",{},Env_getPlatform);
dict->DeclareFunction(gc,"GetRealExecutablePath", "Get the absolute path for executable", {"path"},Env_GetRealExecutablePath);
gc->BarrierBegin();
dict->SetValue("EnvPathSeperator",EnvPathSeperator);
env->SetVariable("Env", dict);
gc->BarrierEnd();
}
}
}

View File

@ -110,6 +110,38 @@ namespace Tesses::CrossLang
return nullptr;
}
static TObject FS_ReadAllText(GCList& ls, std::vector<TObject> args)
{
Tesses::Framework::Filesystem::VFSPath path;
TVFSHeapObject* vfs;
if(GetArgumentHeap(args,0,vfs) && GetArgumentAsPath(args,1,path))
{
auto txtFile = vfs->vfs->OpenFile(path,"rb");
if(txtFile == nullptr) return "";
Tesses::Framework::TextStreams::StreamReader reader(txtFile,true);
return reader.ReadToEnd();
}
return "";
}
static TObject FS_WriteAllText(GCList& ls, std::vector<TObject> args)
{
Tesses::Framework::Filesystem::VFSPath path;
TVFSHeapObject* vfs;
std::string content;
if(GetArgumentHeap(args,0,vfs) && GetArgumentAsPath(args,1,path) && GetArgument(args,2,content))
{
auto txtFile = vfs->vfs->OpenFile(path,"wb");
if(txtFile == nullptr) return nullptr;
Tesses::Framework::TextStreams::StreamWriter writer(txtFile,true);
writer.Write(content);
}
return nullptr;
}
void TStd::RegisterIO(GC* gc,TRootEnvironment* env,bool enableLocalFilesystem)
{
@ -126,6 +158,9 @@ namespace Tesses::CrossLang
dict->SetValue("Local", vfs);
dict->DeclareFunction(gc, "MakeFull", "Make absolute path from relative path",{"path"},FS_MakeFull);
}
dict->DeclareFunction(gc, "ReadAllText","Read all text from file", {"fs","filename"},FS_ReadAllText);
dict->DeclareFunction(gc, "WriteAllText","Write all text to file", {"fs","filename","content"},FS_WriteAllText);
dict->DeclareFunction(gc, "MountableFilesystem","Create a mountable filesystem",{"root"}, FS_MountableFilesystem);
dict->DeclareFunction(gc, "SubdirFilesystem","Create a subdir filesystem",{"fs","subdir"}, FS_SubdirFilesystem);

View File

@ -162,9 +162,9 @@ namespace Tesses::CrossLang
return ctx->NeedToParseFormData();
});
/*dict->DeclareFunction(gc,"ReadString","Read string from request",{},[ctx](Tesses::CrossLang::GCList &ls2, std::vector<Tesses::CrossLang::TObject> args2)->TObject{
dict->DeclareFunction(gc,"ReadString","Read string from request",{},[ctx](Tesses::CrossLang::GCList &ls2, std::vector<Tesses::CrossLang::TObject> args2)->TObject{
return ctx->ReadString();
});*/
});
dict->DeclareFunction(gc,"SendText","Send response text",{"text"},[ctx](Tesses::CrossLang::GCList &ls2, std::vector<Tesses::CrossLang::TObject> args2)->TObject{
std::string text;
@ -392,7 +392,7 @@ namespace Tesses::CrossLang
std::filesystem::path p2 = p.GetFileName();
return HttpUtils::MimeType(p2);
}
return "application/octet-stream";
return std::string("application/octet-stream");
}
static TObject Net_Http_MakeRequest(GCList& ls, std::vector<TObject> args)

View File

@ -1,4 +1,5 @@
#include "CrossLang.hpp"
#if defined(GEKKO)
#include <ogcsys.h>
#include <gccore.h>
@ -9,9 +10,60 @@
#endif
namespace Tesses::CrossLang
{
#if defined(GEKKO)
#if defined(HW_RVL)
static TObject OGC_WPAD_ScanPads(GCList& ls, std::vector<TObject> args)
{
return (int64_t)WPAD_ScanPads();
}
static TObject OGC_WPAD_ButtonsUp(GCList& ls, std::vector<TObject> args)
{
int64_t chan;
if(GetArgument(args,0,chan))
return (int64_t)WPAD_ButtonsUp((int)chan);
return 0;
}
static TObject OGC_WPAD_ButtonsDown(GCList& ls, std::vector<TObject> args)
{
int64_t chan;
if(GetArgument(args,0,chan))
return (int64_t)WPAD_ButtonsDown((int)chan);
return 0;
}
static TObject OGC_WPAD_ButtonsHeld(GCList& ls, std::vector<TObject> args)
{
int64_t chan;
if(GetArgument(args,0,chan))
return (int64_t)WPAD_ButtonsDown((int)chan);
return 0;
}
static TObject OGC_WPAD_BatteryLevel(GCList& ls, std::vector<TObject> args)
{
int64_t chan;
if(GetArgument(args,0,chan))
return (int64_t)WPAD_BatteryLevel((int)chan);
return 0;
}
#endif
#endif
void TStd::RegisterOGC(GC* gc, TRootEnvironment* env)
{
GCList ls(gc);
#if defined(GEKKO)
gc->BarrierBegin();
TDictionary* dict_ogc_pad = TDictionary::Create(ls);
#if defined(HW_RVL)
TDictionary* dict_rvl_wpad = TDictionary::Create(ls);
dict_rvl_wpad->DeclareFunction(gc, "ScanPads","Scan wiimotes",{},OGC_WPAD_ScanPads);
env->DeclareVariable("WPAD", dict_rvl_wpad);
#endif
env->DeclareVariable("PAD", dict_ogc_pad);
gc->BarrierEnd();
#endif
env->permissions.canRegisterOGC=true;
}
}

View File

@ -20,7 +20,58 @@ namespace Tesses::CrossLang
// Environment = []
//})
TDictionary* dict;
if(GetArgumentHeap(args, 0, dict))
{
auto gc = ls.GetGC();
gc->BarrierBegin();
auto fobj = dict->GetValue("FileName");
auto myargs = dict->GetValue("Arguments");
auto env = dict->GetValue("Environment");
std::string filename;
TList* _args;
TList* env;
std::vector<std::string> _args2;
std::vector<std::string> _env;
if(GetObject(fobj,filename))
{
gc->BarrierEnd();
return nullptr;
}
_args2.push_back(filename);
if(GetObjectHeap(myargs,_args))
{
for(auto a : _args->items)
{
std::string a2;
if(GetObject(a,a2))
{
_args2.push_back(a2);
}
}
}
if(GetObjectHeap(myargs,_args))
{
for(auto a : _args->items)
{
std::string a2;
if(GetObject(a,a2))
{
_args2.push_back(a2);
}
}
}
gc->BarrierEnd();
subprocess_create_ex()
}
return nullptr;
}
//#endif
}

View File

@ -5,6 +5,165 @@
namespace Tesses::CrossLang
{
#if defined(CROSSLANG_ENABLE_SDL2)
static void TObjectToRect(TDictionary* dict, SDL_Rect& rect)
{
int64_t number;
auto obj = dict->GetValue("x");
if(GetObject(obj,number)) rect.x = (int)number;
obj = dict->GetValue("y");
if(GetObject(obj,number)) rect.y = (int)number;
obj = dict->GetValue("w");
if(GetObject(obj,number)) rect.w = (int)number;
obj = dict->GetValue("h");
if(GetObject(obj,number)) rect.h = (int)number;
}
static TObject SDL2_RenderDrawRect(GCList& ls, std::vector<TObject> args)
{
TNative* nat;
TDictionary* dict;
if(GetArgumentHeap(args,0, nat) && GetArgumentHeap(args,1,dict))
{
SDL_Rect rect;
TObjectToRect(dict,rect);
return (int64_t)SDL_RenderDrawRect((SDL_Renderer*)nat->GetPointer(), &rect);
}
return nullptr;
}
static TObject SDL2_RenderFillRect(GCList& ls, std::vector<TObject> args)
{
TNative* nat;
TDictionary* dict;
if(GetArgumentHeap(args,0, nat) && GetArgumentHeap(args,1,dict))
{
SDL_Rect rect;
TObjectToRect(dict,rect);
return (int64_t)SDL_RenderFillRect((SDL_Renderer*)nat->GetPointer(), &rect);
}
return nullptr;
}
static TObject SDL2_PollEvent(GCList& ls, std::vector<TObject> args)
{
SDL_Event event;
if(SDL_PollEvent(&event))
{
TDictionary* dict = TDictionary::Create(ls);
ls.GetGC()->BarrierBegin();
dict->SetValue("Type",(int64_t)event.common.type);
dict->SetValue("Timestamp",(int64_t)event.common.timestamp);
switch(event.type)
{
case SDL_DROPBEGIN:
case SDL_DROPCOMPLETE:
dict->SetValue("WindowId",(int64_t)event.drop.windowID);
break;
case SDL_DROPFILE:
dict->SetValue("File", Tesses::Framework::Filesystem::VFSPath(std::string(event.drop.file)));
SDL_free(event.drop.file);
break;
case SDL_DROPTEXT:
dict->SetValue("WindowId",(int64_t)event.drop.windowID);
dict->SetValue("Text", std::string(event.drop.file));
SDL_free(event.drop.file);
break;
case SDL_MOUSEBUTTONUP:
case SDL_MOUSEBUTTONDOWN:
dict->SetValue("WindowId",(int64_t)event.button.windowID);
dict->SetValue("Which",(int64_t)event.button.which);
dict->SetValue("Button",(int64_t)event.button.button);
dict->SetValue("State",(int64_t)event.button.state);
dict->SetValue("Clicks",(int64_t)event.button.clicks);
dict->SetValue("X",(int64_t)event.button.x);
dict->SetValue("Y",(int64_t)event.button.y);
break;
case SDL_MOUSEMOTION:
dict->SetValue("WindowId",(int64_t)event.motion.windowID);
dict->SetValue("Which",(int64_t)event.motion.which);
dict->SetValue("State",(int64_t)event.motion.state);
dict->SetValue("X",(int64_t)event.motion.x);
dict->SetValue("Y",(int64_t)event.motion.y);
dict->SetValue("XRel",(int64_t)event.motion.xrel);
dict->SetValue("YRel",(int64_t)event.motion.yrel);
break;
case SDL_MOUSEWHEEL:
dict->SetValue("Direction", (int64_t)event.wheel.direction);
dict->SetValue("MouseX",(int64_t)event.wheel.mouseX);
dict->SetValue("MouseY",(int64_t)event.wheel.mouseY);
dict->SetValue("PreciseX",(double)event.wheel.preciseX);
dict->SetValue("PreciseY",(double)event.wheel.preciseY);
dict->SetValue("Which",(int64_t)event.wheel.which);
dict->SetValue("WindowId",(int64_t)event.wheel.windowID);
dict->SetValue("X",(int64_t)event.wheel.x);
dict->SetValue("Y",(int64_t)event.wheel.y);
break;
case SDL_KEYUP:
case SDL_KEYDOWN:
dict->SetValue("WindowId",(int64_t)event.key.windowID);
dict->SetValue("Repeat",(int64_t)event.key.repeat);
dict->SetValue("State",(int64_t)event.key.state);
{
TDictionary* dict2=TDictionary::Create(ls);
dict2->SetValue("Mod",(int64_t)event.key.keysym.mod);
dict2->SetValue("Scancode",(int64_t)event.key.keysym.scancode);
dict2->SetValue("Sym",(int64_t)event.key.keysym.sym);
dict->SetValue("Keysym",dict2);
}
break;
case SDL_EventType::SDL_FINGERMOTION:
dict->SetValue("Dx",event.tfinger.dx);
dict->SetValue("Dy",event.tfinger.dy);
//falls into SDL_FINGERUP/DOWN due to having same props
case SDL_EventType::SDL_FINGERUP:
case SDL_EventType::SDL_FINGERDOWN:
dict->SetValue("X",event.tfinger.x);
dict->SetValue("Y",event.tfinger.y);
dict->SetValue("FingerId",(int64_t)event.tfinger.fingerId);
dict->SetValue("Pressure",event.tfinger.pressure);
dict->SetValue("TouchId",(int64_t)event.tfinger.touchId);
dict->SetValue("WindowId",(int64_t)event.tfinger.windowID);
break;
case SDL_EventType::SDL_TEXTINPUT:
dict->SetValue("Text",event.text.text);
dict->SetValue("WindowId",(int64_t)event.text.windowID);
break;
case SDL_EventType::SDL_TEXTEDITING:
dict->SetValue("Text",event.edit.text);
dict->SetValue("Length",(int64_t)event.edit.length);
dict->SetValue("Start",(int64_t)event.edit.start);
dict->SetValue("WindowId",(int64_t)event.edit.windowID);
break;
case SDL_EventType::SDL_TEXTEDITING_EXT:
{
dict->SetValue("Text",event.editExt.text);
dict->SetValue("Length",(int64_t)event.editExt.length);
dict->SetValue("Start",(int64_t)event.editExt.start);
dict->SetValue("WindowId",(int64_t)event.editExt.windowID);
SDL_free(event.editExt.text);
}
break;
case SDL_EventType::SDL_WINDOWEVENT:
{
dict->SetValue("WindowId",(int64_t)event.window.windowID);
dict->SetValue("Event",(int64_t)event.window.event);
dict->SetValue("Data1",(int64_t)event.window.data1);
dict->SetValue("Data2",(int64_t)event.window.data2);
}
break;
}
ls.GetGC()->BarrierEnd();
return dict;
}
return nullptr;
}
static TObject SDL2_RenderPresent(GCList& ls, std::vector<TObject> args)
{
TNative* renderer;
@ -36,6 +195,12 @@ namespace Tesses::CrossLang
}
return Undefined();
}
static TObject SDL2_Init(GCList& ls, std::vector<TObject> args)
{
return (int64_t)SDL_Init(SDL_INIT_EVERYTHING);
}
static TObject SDL2_CreateRenderer(GCList& ls, std::vector<TObject> args)
@ -75,16 +240,42 @@ namespace Tesses::CrossLang
#if defined(CROSSLANG_ENABLE_SDL2)
GCList ls(gc);
TDictionary* dict = TDictionary::Create(ls);
dict->DeclareFunction(gc, "RenderDrawRect","Draw a rectangle using SDL",{"renderer","dictionary_with_x_y_w_h"}, SDL2_RenderDrawRect);
dict->DeclareFunction(gc, "RenderFillRect","Fill a rectangle using SDL",{"renderer","dictionary_with_x_y_w_h"}, SDL2_RenderFillRect);
dict->DeclareFunction(gc, "RenderPresent","Present frame (you are finished with the frame)",{"renderer"},SDL2_RenderPresent);
dict->DeclareFunction(gc, "RenderClear","Clear renderer with renderer draw color",{"renderer"},SDL2_RenderClear);
dict->DeclareFunction(gc, "SetRenderDrawColor","Set SDL2 Renderer Draw Color",{"renderer","r","g","b","a"},SDL2_SetRenderDrawColor);
dict->DeclareFunction(gc, "CreateWindow","Create a SDL2 Window",{"title","x","y","w","h","flags"},SDL2_CreateWindow);
dict->DeclareFunction(gc, "CreateRenderer","Create a SDL2 Renderer",{"window",""},SDL2_CreateRenderer);
dict->DeclareFunction(gc, "CreateRenderer","Create a SDL2 Renderer",{"window",""},SDL2_CreateRenderer);
dict->DeclareFunction(gc, "PollEvent", "Get events",{},SDL2_PollEvent);
dict->DeclareFunction(gc, "Init", "Init SDL2",{},SDL2_Init);
gc->BarrierBegin();
dict->SetValue("DROPBEGIN",(int64_t)SDL_DROPBEGIN);
dict->SetValue("DROPCOMPLETE",(int64_t)SDL_DROPCOMPLETE);
dict->SetValue("DROPFILE",(int64_t)SDL_DROPFILE);
dict->SetValue("DROPTEXT",(int64_t)SDL_DROPTEXT);
dict->SetValue("MOUSEBUTTONUP",(int64_t)SDL_MOUSEBUTTONUP);
dict->SetValue("MOUSEBUTTONDOWN",(int64_t)SDL_MOUSEBUTTONDOWN);
dict->SetValue("MOUSEMOTION",(int64_t)SDL_MOUSEMOTION);
dict->SetValue("KEYUP",(int64_t)SDL_KEYUP);
dict->SetValue("KEYDOWN",(int64_t)SDL_KEYDOWN);
dict->SetValue("FINGERMOTION",(int64_t)SDL_FINGERMOTION);
dict->SetValue("FINGERUP",(int64_t)SDL_FINGERUP);
dict->SetValue("FINGERDOWN",(int64_t)SDL_FINGERDOWN);
dict->SetValue("TEXTINPUT",(int64_t)SDL_TEXTINPUT);
dict->SetValue("TEXTEDITING",(int64_t)SDL_TEXTEDITING);
dict->SetValue("TEXTEDITING_EXT",(int64_t)SDL_TEXTEDITING_EXT);
dict->SetValue("WINDOWEVENT",(int64_t)SDL_WINDOWEVENT);
dict->SetValue("QUIT",(int64_t)SDL_QUIT);
dict->SetValue("WINDOW_RESIZABLE",(int64_t)SDL_WINDOW_RESIZABLE);
dict->SetValue("WINDOW_BORDERLESS",(int64_t)SDL_WINDOW_BORDERLESS);
dict->SetValue("WINDOW_FULLSCREEN",(int64_t)SDL_WINDOW_FULLSCREEN);
dict->SetValue("WINDOW_MAXIMIZED",(int64_t)SDL_WINDOW_MAXIMIZED);
env->DeclareVariable("SDL2", dict);
gc->BarrierEnd();
#endif
}
}
}