diff --git a/CMakeLists.txt b/CMakeLists.txt index c1352fc..082193f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,6 +21,7 @@ option(CROSSLANG_FETCHCONTENT "Use fetchcontent" ON) option(CROSSLANG_ENABLE_CONFIG_ENVVAR "Allow setting config directory via the environment variable CROSSLANG_CONFIG" ON) option(CROSSLANG_ENABLE_FFI "Enable libffi" OFF) + option(CROSSLANG_CUSTOM_CONSOLE "Enable custom Console" OFF) #if(CROSSLANG_ENABLE_DOXYGEN) @@ -380,18 +381,19 @@ target_link_libraries(crossthumbnailer PUBLIC TessesFramework::tessesframework) endif() endif() endif() -install(TARGETS crossc DESTINATION bin) -install(TARGETS crossvm DESTINATION bin) -install(TARGETS crossint DESTINATION bin) -install(TARGETS crossdump DESTINATION bin) -install(TARGETS crosslang DESTINATION bin) -install(TARGETS crossarchiveextract DESTINATION bin) -install(TARGETS crossarchivecreate DESTINATION bin) -install(TARGETS crossasm DESTINATION bin) -install(TARGETS crossdisasm DESTINATION bin) -install(TARGETS crossmerge DESTINATION bin) +install(TARGETS crossc DESTINATION "${CMAKE_INSTALL_BINDIR}") +install(TARGETS crossvm DESTINATION "${CMAKE_INSTALL_BINDIR}") +install(TARGETS crossint DESTINATION "${CMAKE_INSTALL_BINDIR}") +install(TARGETS crossdump DESTINATION "${CMAKE_INSTALL_BINDIR}") +install(TARGETS crosslang DESTINATION "${CMAKE_INSTALL_BINDIR}") +install(TARGETS crossarchiveextract DESTINATION "${CMAKE_INSTALL_BINDIR}") +install(TARGETS crossarchivecreate DESTINATION "${CMAKE_INSTALL_BINDIR}") +install(TARGETS crossasm DESTINATION "${CMAKE_INSTALL_BINDIR}") +install(TARGETS crossdisasm DESTINATION "${CMAKE_INSTALL_BINDIR}") +install(TARGETS crossmerge DESTINATION "${CMAKE_INSTALL_BINDIR}") if(NOT WIN32) -install(TARGETS crossthumbnailer DESTINATION bin) +install(TARGETS crossthumbnailer DESTINATION "${CMAKE_INSTALL_BINDIR}") + configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/crossvm-binfmt.conf.in "${CMAKE_CURRENT_BINARY_DIR}/crossvm-binfmt.conf" INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/binfmt.d) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/crossvm-binfmt.conf" diff --git a/src/runtime_methods/console.cpp b/src/runtime_methods/console.cpp index 2119ded..1774d04 100644 --- a/src/runtime_methods/console.cpp +++ b/src/runtime_methods/console.cpp @@ -193,6 +193,16 @@ namespace Tesses::CrossLang { { return TStreamHeapObject::Create(ls, new Tesses::Framework::Streams::FileStream(stderr,false,"w",false)); } + TObject Console_Clear(GCList& ls, std::vector args) + { + //because I just really want a clear function + #if defined(_WIN32) + system("cls"); + #else + std::cout << "\x1b[2J\x1b[H" << std::flush; //because of wii and stuff (dont want to rely on clear command) + #endif + return Undefined(); + } void TStd::RegisterConsole(GC* gc,TRootEnvironment* env) { env->permissions.canRegisterConsole=true; @@ -210,13 +220,14 @@ namespace Tesses::CrossLang { #endif GCList ls(gc); TDictionary* dict = TDictionary::Create(ls); + dict->DeclareFunction(gc,"getEcho","Get whether terminal is echoing characters read",{},Console_getEcho); dict->DeclareFunction(gc,"setEcho","Set whether terminal is echoing characters read",{"flag"},Console_setEcho); dict->DeclareFunction(gc,"getCanonical","Get whether terminal is buffering line by line (true) or byte by byte (false)",{},Console_getCanonical); dict->DeclareFunction(gc,"setCanonical","Set whether terminal is buffering line by line (true) or byte by byte (false)",{"flag"},Console_setCanonical); dict->DeclareFunction(gc,"getSignals","Get whether terminal is sending signals for CTRL+C (true) or via read (false)",{},Console_getSignals); dict->DeclareFunction(gc,"setSignals","Set whether terminal is sending signals for CTRL+C (true) or via read (false)",{"flag"},Console_setSignals); - + dict->DeclareFunction(gc,"Clear", "Clear the console",{},Console_Clear); dict->DeclareFunction(gc,"Read", "Reads a byte from stdin",{},Console_Read); dict->DeclareFunction(gc,"ReadLine","Reads line from stdin",{},Console_ReadLine); dict->DeclareFunction(gc,"Write","Write text \"text\" to stdout",{"text"},Console_Write); diff --git a/src/runtime_methods/crypto.cpp b/src/runtime_methods/crypto.cpp index 1025fdc..a91ae17 100644 --- a/src/runtime_methods/crypto.cpp +++ b/src/runtime_methods/crypto.cpp @@ -6,6 +6,7 @@ namespace Tesses::CrossLang { static TObject Crypto_RandomBytes(GCList& ls, std::vector args) { + int64_t size; std::string personalStr; if(GetArgument(args,0,size) && GetArgument(args,1,personalStr)) @@ -110,6 +111,70 @@ namespace Tesses::CrossLang dict->DeclareFunction(gc, "Base64Encode","Base64 encode",{"data"},Crypto_Base64Encode); dict->DeclareFunction(gc, "Base64Decode","Base64 decode",{"str"},Crypto_Base64Decode); + dict->DeclareFunction(gc, "Sha1", "Hash with sha1 algorithm (please don't use sha1 unless you need to)",{"strm"}, [](GCList& ls, std::vector args)->TObject { + TByteArray* baSrc; + TStreamHeapObject* sho; + + if(GetArgumentHeap(args, 0, sho)) + { + auto bytes = Sha1::ComputeHash(sho->stream); + auto ba = TByteArray::Create(ls); + ba->data = bytes; + return ba; + } + if(GetArgumentHeap(args,0,baSrc)) + { + auto bytes = Sha1::ComputeHash(baSrc->data.data(), baSrc->data.size()); + auto ba = TByteArray::Create(ls); + ba->data = bytes; + return ba; + } + return Undefined(); + }); + dict->DeclareFunction(gc, "Sha256", "Hash with sha256 algorithm",{"strm","$is224"}, [](GCList& ls, std::vector args)->TObject { + TByteArray* baSrc; + TStreamHeapObject* sho; + bool is224=false; + GetArgument(args,1,is224); + + if(GetArgumentHeap(args, 0, sho)) + { + auto bytes = Sha256::ComputeHash(sho->stream,is224); + auto ba = TByteArray::Create(ls); + ba->data = bytes; + return ba; + } + if(GetArgumentHeap(args,0,baSrc)) + { + auto bytes = Sha256::ComputeHash(baSrc->data.data(), baSrc->data.size(), is224); + auto ba = TByteArray::Create(ls); + ba->data = bytes; + return ba; + } + return Undefined(); + }); + dict->DeclareFunction(gc, "Sha512", "Hash with sha512 algorithm",{"strm","$is384"}, [](GCList& ls, std::vector args)->TObject { + TByteArray* baSrc; + TStreamHeapObject* sho; + bool is384=false; + GetArgument(args,1,is384); + + if(GetArgumentHeap(args, 0, sho)) + { + auto bytes = Sha512::ComputeHash(sho->stream,is384); + auto ba = TByteArray::Create(ls); + ba->data = bytes; + return ba; + } + if(GetArgumentHeap(args,0,baSrc)) + { + auto bytes = Sha512::ComputeHash(baSrc->data.data(), baSrc->data.size(), is384); + auto ba = TByteArray::Create(ls); + ba->data = bytes; + return ba; + } + return Undefined(); + }); gc->BarrierBegin(); env->DeclareVariable("Crypto", dict); gc->BarrierEnd(); diff --git a/src/runtime_methods/ogc.cpp b/src/runtime_methods/ogc.cpp index 2bd4b23..9c39611 100644 --- a/src/runtime_methods/ogc.cpp +++ b/src/runtime_methods/ogc.cpp @@ -62,6 +62,14 @@ namespace Tesses::CrossLang dict_rvl_wpad->SetValue("BUTTON_A",(int64_t)WPAD_BUTTON_A); dict_rvl_wpad->SetValue("BUTTON_B",(int64_t)WPAD_BUTTON_B); dict_rvl_wpad->SetValue("BUTTON_HOME",(int64_t)WPAD_BUTTON_HOME); + dict_rvl_wpad->SetValue("BUTTON_UP",(int64_t)WPAD_BUTTON_UP); + dict_rvl_wpad->SetValue("BUTTON_DOWN",(int64_t)WPAD_BUTTON_DOWN); + dict_rvl_wpad->SetValue("BUTTON_LEFT",(int64_t)WPAD_BUTTON_LEFT); + dict_rvl_wpad->SetValue("BUTTON_RIGHT",(int64_t)WPAD_BUTTON_RIGHT); + dict_rvl_wpad->SetValue("BUTTON_1",(int64_t)WPAD_BUTTON_1); + dict_rvl_wpad->SetValue("BUTTON_2",(int64_t)WPAD_BUTTON_2); + dict_rvl_wpad->SetValue("BUTTON_PLUS",(int64_t)WPAD_BUTTON_PLUS); + dict_rvl_wpad->SetValue("BUTTON_MINUS",(int64_t)WPAD_BUTTON_MINUS); env->DeclareVariable("WPAD", dict_rvl_wpad); #endif diff --git a/src/runtime_methods/vm.cpp b/src/runtime_methods/vm.cpp index 28b3b7c..ae2dd3d 100644 --- a/src/runtime_methods/vm.cpp +++ b/src/runtime_methods/vm.cpp @@ -430,6 +430,33 @@ namespace Tesses::CrossLang Tesses::Framework::TF_RunEventLoop(); return Undefined(); }); + dict->DeclareFunction(gc, "Merge", "Merge crvm files", {"srcVFS","sourcePath","destVFS"},[](GCList& ls, std::vector args)->TObject { + TVFSHeapObject* srcVFS; + TVFSHeapObject* destVFS; + Tesses::Framework::Filesystem::VFSPath sourcePath; + if(GetArgumentHeap(args,0, srcVFS) && GetArgumentAsPath(args,1,sourcePath) && GetArgumentHeap(args,2,destVFS)) + return Merge(srcVFS->vfs, sourcePath, destVFS->vfs); + return Undefined(); + }); + dict->DeclareFunction(gc, "Disassemble","Disassemble crvm file",{"strm","vfs","$generateJSON","$extractResources"},[](GCList& ls, std::vector args)->TObject { + TStreamHeapObject* strm; + TVFSHeapObject* vfs; + bool generateJSON=true; + bool extractResources=true; + if(GetArgumentHeap(args,0,strm) && GetArgumentHeap(args,1, vfs)) + { + GetArgument(args,2,generateJSON); + GetArgument(args,3,extractResources); + Disassemble(strm->stream,vfs->vfs, generateJSON, extractResources); + } + return Undefined(); + }); + dict->DeclareFunction(gc, "Assemble", "Assemble crvm file",{"vfs"},[](GCList& ls, std::vector args)->TObject { + TVFSHeapObject* vfs; + if(GetArgumentHeap(args,0, vfs)) + return Assemble(vfs->vfs); + return Undefined(); + }); gc->BarrierBegin(); diff --git a/src/vm/vm.cpp b/src/vm/vm.cpp index cdac4bd..d71dfac 100644 --- a/src/vm/vm.cpp +++ b/src/vm/vm.cpp @@ -1,6 +1,4 @@ - #include "CrossLang.hpp" -#include #include #include #include @@ -8,6 +6,8 @@ #include #include #include + + namespace Tesses::CrossLang { thread_local CallStackEntry* current_function=nullptr; @@ -2841,6 +2841,81 @@ namespace Tesses::CrossLang { else if(std::holds_alternative(instance)) { std::string str = std::get(instance); + if(key == "ToLower") + { + for(size_t i = 0; i < str.size(); i++) + { + if(str[i] >= 'A' && str[i] <= 'Z') + { + str[i] = 'a' + (str[i] - 'A'); + } + } + cse.back()->Push(gc, str); + return false; + } + if(key == "ToUpper") + { + + for(size_t i = 0; i < str.size(); i++) + { + if(str[i] >= 'a' && str[i] <= 'z') + { + str[i] = 'A' + (str[i] - 'a'); + } + } + cse.back()->Push(gc, str); + return false; + } + if(key == "PadLeft") + { + int64_t pad; + char padChar=' '; + + if(args.size() == 0 || args.size() > 2) + { + throw VMException("String.PadLeft must only accept 1 or 2 arguments"); + + } + + if(GetArgument(args,0, pad)) + { + if((size_t)pad < str.size()) { + cse.back()->Push(gc, str); + return false; + } + GetArgument(args,1, padChar); + size_t diff = (size_t)pad - str.size(); + str.insert(str.begin(),diff, padChar); + cse.back()->Push(gc, str); + return false; + } + else throw VMException("String.PadLeft must have a long for width"); + } + if(key == "PadRight") + { + int64_t pad; + char padChar=' '; + + if(args.size() == 0 || args.size() > 2) + { + throw VMException("String.PadRight must only accept 1 or 2 arguments"); + + } + + if(GetArgument(args,0, pad)) + { + if((size_t)pad < str.size()) { + cse.back()->Push(gc, str); + return false; + } + GetArgument(args,1, padChar); + size_t diff = (size_t)pad - str.size(); + str.insert(str.end(),diff, padChar); + cse.back()->Push(gc, str); + return false; + } + else throw VMException("String.PadRight must have a long for width"); + } if(key == "IndexOf") { std::string str2; @@ -4327,6 +4402,14 @@ namespace Tesses::CrossLang { } } + if(key == "ToCHeaderFile") + { + std::string name = "NONAME"; + GetArgument(args,0,name); + + cse.back()->Push(gc, Tesses::Framework::Text::GenerateCHeaderFile(bArray->data,name)); + return false; + } if(key == "CopyTo") { //CopyTo(destBuff, offsetSrc, offsetDest, length)