From 48de98433ba65e20dfa759b5d7a4e076e1b9316c Mon Sep 17 00:00:00 2001 From: Nic0Nic0Nii <89110903+Nic0Nic0Nii@users.noreply.github.com> Date: Wed, 21 Feb 2024 16:22:48 +0000 Subject: [PATCH] Add example shader changes Co-authored-by: sigonasr2 --- C++/scripts/build.sh | 34 + C++/scripts/commit.sh | 21 + C++/scripts/debug.sh | 22 + C++/scripts/filelist | 7 + C++/scripts/lines.sh | 14 + C++/scripts/md5 | 7 + C++/scripts/release.sh | 20 + C++/scripts/temp | 0 C++/scripts/web.sh | 46 + C++ProjectTemplate | Bin 0 -> 576120 bytes C++ProjectTemplate.data | 0 C++ProjectTemplate.html | 75 + C++ProjectTemplate.js | 1 + C++ProjectTemplate.wasm | Bin 0 -> 310725 bytes README.md | 33 + assets/test | 0 buildtemplate.html | 75 + dirtblock.png | Bin 0 -> 35629 bytes main.cpp | 65 + pixelGameEngine.cpp | 2 + pixelGameEngine.h | 6708 ++++++++++++++++++++++++++++++++++++++ pixelGameEngine_wasm.o | Bin 0 -> 185477 bytes sig | 10 + utils/.coauthors | 1 + utils/.updateDirectories | 5 + utils/define.sh | 26 + utils/filelist | 5 + utils/main.sh | 28 + utils/md5 | 4 + utils/search.sh | 103 + 30 files changed, 7312 insertions(+) create mode 100755 C++/scripts/build.sh create mode 100755 C++/scripts/commit.sh create mode 100755 C++/scripts/debug.sh create mode 100644 C++/scripts/filelist create mode 100755 C++/scripts/lines.sh create mode 100644 C++/scripts/md5 create mode 100755 C++/scripts/release.sh create mode 100644 C++/scripts/temp create mode 100755 C++/scripts/web.sh create mode 100755 C++ProjectTemplate create mode 100644 C++ProjectTemplate.data create mode 100644 C++ProjectTemplate.html create mode 100644 C++ProjectTemplate.js create mode 100755 C++ProjectTemplate.wasm create mode 100644 README.md create mode 100644 assets/test create mode 100644 buildtemplate.html create mode 100644 dirtblock.png create mode 100644 main.cpp create mode 100644 pixelGameEngine.cpp create mode 100644 pixelGameEngine.h create mode 100644 pixelGameEngine_wasm.o create mode 100755 sig create mode 100644 utils/.coauthors create mode 100644 utils/.updateDirectories create mode 100755 utils/define.sh create mode 100644 utils/filelist create mode 100644 utils/main.sh create mode 100644 utils/md5 create mode 100644 utils/search.sh diff --git a/C++/scripts/build.sh b/C++/scripts/build.sh new file mode 100755 index 0000000..17ade89 --- /dev/null +++ b/C++/scripts/build.sh @@ -0,0 +1,34 @@ +#Compiles the entire program then runs it, producing an executable. If the "test" argument is included, will try and run tests too (in the test folder). If the "full" argument is included, it will recopmile the PixelGameEngine (should it change) +#C++ +printf "Running program...\n\n\n" +output=$(dpkg -l | grep libx11-dev) +if [[ -z $output ]] +then + sudo apt install libx11-dev libpulse-dev mesa-common-dev libpng-dev libstdc++-12-dev +fi +if [ ! -f "pixelGameEngine.o" ] +then + printf "Pixel Game Engine compile object missing. Compiling for the first time..." + g++ ${CUSTOM_PARAMS} -c pixelGameEngine.cpp +fi +if [ "$1" = "test" ] +then + printf "Running tests...\n" + echo "#define TEST_SUITE" > ./test/test.h + if g++ $(find . -type f -name "*.cpp" -not -name "pixelGameEngine.cpp") pixelGameEngine.o ${CUSTOM_PARAMS} -o ${PROJECT_NAME}; then + ./${PROJECT_NAME} "$@" + fi +elif [ "$1" = "full" ] +then + echo "" > ./test/test.h + g++ ${CUSTOM_PARAMS} -c pixelGameEngine.cpp + if g++ $(find . -type f -name "*.cpp" -not -path "./test/*" -not -name "pixelGameEngine.cpp") pixelGameEngine.o ${CUSTOM_PARAMS} -o ${PROJECT_NAME}; then + ./${PROJECT_NAME} "$@" + fi +else + echo "" > ./test/test.h + if g++ $(find . -type f -name "*.cpp" -not -path "./test/*" -not -name "pixelGameEngine.cpp") pixelGameEngine.o ${CUSTOM_PARAMS} -o ${PROJECT_NAME}; then + ./${PROJECT_NAME} "$@" + fi +fi +printf "\n\n" diff --git a/C++/scripts/commit.sh b/C++/scripts/commit.sh new file mode 100755 index 0000000..543a623 --- /dev/null +++ b/C++/scripts/commit.sh @@ -0,0 +1,21 @@ +#Adds a commit message and pushes project to github repository. +#C++ +COMMIT_MESSAGE="$*" +FIRST_LINE=true +while IFS= read -r line +do +if [ "$FIRST_LINE" = true ]; then + COMMIT_MESSAGE+=" + +Co-authored-by: $line" +FIRST_LINE=false +else + COMMIT_MESSAGE+=" +Co-authored-by: $line" +fi +done < utils/.coauthors +git config --global credential.helper store +git add -u +git add * +git commit -m "$COMMIT_MESSAGE" +git push \ No newline at end of file diff --git a/C++/scripts/debug.sh b/C++/scripts/debug.sh new file mode 100755 index 0000000..9bf2513 --- /dev/null +++ b/C++/scripts/debug.sh @@ -0,0 +1,22 @@ +#Compiles the entire program with debug flags then runs it in gdb. If the "test" argument is included, will try and run tests too (in the test folder) +#C++ +printf "Running program...\n\n\n" +output=$(dpkg -l | grep libx11-dev) +if [[ -z $output ]] +then + sudo apt install libx11-dev libpulse-dev mesa-common-dev libpng-dev libstdc++-12-dev +fi +if [ "$1" = "test" ] +then + printf "Running tests...\n" + echo "#define TEST_SUITE" > ./test/test.h + if g++ $(find . -type f -name "*.cpp") -g ${CUSTOM_PARAMS} -o ${PROJECT_NAME}; then + gdb ./${PROJECT_NAME} "$@" + fi +else + echo "" > ./test/test.h + if g++ $(find . -type f -name "*.cpp" -not -path "./test/*") -g ${CUSTOM_PARAMS} -o ${PROJECT_NAME}; then + gdb ./${PROJECT_NAME} "$@" + fi +fi +printf "\n\n" diff --git a/C++/scripts/filelist b/C++/scripts/filelist new file mode 100644 index 0000000..03e1e9a --- /dev/null +++ b/C++/scripts/filelist @@ -0,0 +1,7 @@ +build.sh +commit.sh +debug.sh +lines.sh +release.sh +temp +web.sh diff --git a/C++/scripts/lines.sh b/C++/scripts/lines.sh new file mode 100755 index 0000000..90e6d10 --- /dev/null +++ b/C++/scripts/lines.sh @@ -0,0 +1,14 @@ +#Returns the line counts of your project. +#C++ +shopt -s extglob +ls -1 @(*.h|*.cpp) > temp +while read a; do + if [ "$a" != "pixelGameEngine.h" ] && [ "$a" != "soundwaveEngine.h" ] && [ "$a" != "splash.h" ]; + then + echo -e "$a\n" >> temp2 + fi +done < temp +wc -l $(cat temp2) + +rm temp +rm temp2 \ No newline at end of file diff --git a/C++/scripts/md5 b/C++/scripts/md5 new file mode 100644 index 0000000..e5ca486 --- /dev/null +++ b/C++/scripts/md5 @@ -0,0 +1,7 @@ +build.sh:e307e0388d5f0d16c7f9a39e0177fc47 - +commit.sh:1af81bf417dfb932284d8a14fdd10657 - +debug.sh:8125f303032b6cbc137223df63d10096 - +lines.sh:3b907786f7fc9204025993016c9080de - +release.sh:b1ce8461a303e8e7aa9ed74259db3873 - +temp:d41d8cd98f00b204e9800998ecf8427e - +web.sh:1adf54f3c200922572a24573a0998110 - diff --git a/C++/scripts/release.sh b/C++/scripts/release.sh new file mode 100755 index 0000000..13aa1eb --- /dev/null +++ b/C++/scripts/release.sh @@ -0,0 +1,20 @@ +#Creates a release build that focuses on high runtime performance. Use "full" argument to completely rebuild PGE. +#C++ +printf "Running program...\n\n\n" +output=$(dpkg -l | grep libx11-dev) +if [[ -z $output ]] +then + sudo apt install libx11-dev libpulse-dev mesa-common-dev libpng-dev libstdc++-12-dev +fi +if [ "$1" == "full" ]; then + rm "pixelGameEngine.o" +fi +if [ ! -f "pixelGameEngine.o" ] +then + printf "Pixel Game Engine compile object missing. Compiling for the first time..." + g++ -c pixelGameEngine.cpp +fi +if g++ $(find . -type f -name "*.cpp" -not -path "./test/*" -not -name "pixelGameEngine.cpp") pixelGameEngine.o ${CUSTOM_PARAMS} -o ${PROJECT_NAME}; then + ./${PROJECT_NAME} "$@" +fi +printf "\n\n" diff --git a/C++/scripts/temp b/C++/scripts/temp new file mode 100644 index 0000000..e69de29 diff --git a/C++/scripts/web.sh b/C++/scripts/web.sh new file mode 100755 index 0000000..1097efb --- /dev/null +++ b/C++/scripts/web.sh @@ -0,0 +1,46 @@ +#Compiles emscripten instance of this project for the web. Use "full" argument if your PGE has to be completely rebuilt. Use "headless" argument for a headless version. +#C++ +output=$(dpkg -l | grep libx11-dev) +if [[ -z $output ]] +then + sudo apt install libx11-dev libpulse-dev mesa-common-dev libpng-dev libstdc++-12-dev +fi +if [[ "$1" == "full" || "$2" == "full" ]]; then + rm "pixelGameEngine_wasm.o" +fi +source ../emsdk/emsdk_env.sh +if [ ! -f "pixelGameEngine_wasm.o" ] +then + printf "Pixel Game Engine compile object missing. Compiling for the first time..." + em++ -std=c++20 -O2 ${EMSCRIPTEN_CUSTOM_PARAMS} -s ALLOW_MEMORY_GROWTH=1 -s MAXIMUM_MEMORY=4GB -s MAX_WEBGL_VERSION=2 -s MIN_WEBGL_VERSION=2 -s USE_SDL_MIXER=2 -s USE_LIBPNG=1 -c pixelGameEngine.cpp -o pixelGameEngine_wasm.o +fi +if [ -d "assets" ]; then + em++ -std=c++20 -O2 ${EMSCRIPTEN_CUSTOM_PARAMS} -s ALLOW_MEMORY_GROWTH=1 -s MAXIMUM_MEMORY=4GB -s MAX_WEBGL_VERSION=2 -s MIN_WEBGL_VERSION=2 -s USE_SDL_MIXER=2 -s USE_LIBPNG=1 $(find . -type f -name "*.cpp" -not -path "./test/*" -not -name "pixelGameEngine.cpp") pixelGameEngine_wasm.o -o ${PROJECT_NAME}.html --preload-file ./assets +else + em++ -std=c++20 -O2 ${EMSCRIPTEN_CUSTOM_PARAMS} -s ALLOW_MEMORY_GROWTH=1 -s MAXIMUM_MEMORY=4GB -s MAX_WEBGL_VERSION=2 -s MIN_WEBGL_VERSION=2 -s USE_SDL_MIXER=2 -s USE_LIBPNG=1 $(find . -type f -name "*.cpp" -not -path "./test/*" -not -name "pixelGameEngine.cpp") pixelGameEngine_wasm.o -o ${PROJECT_NAME}.html +fi + +cp buildtemplate.html ${PROJECT_NAME}.html +sed -i "s/_REPLACEME_/$PROJECT_NAME.js/" ${PROJECT_NAME}.html + +if [[ "$1" == "headless" || "$2" == "headless" ]]; then + echo "Running as headless web server" + emrun --no_browser ${PROJECT_NAME}.html +else + emrun --serve_after_close ${PROJECT_NAME}.html +fi + +if [ $? -eq 127 ] +then + echo "Failed to find Emscripten. Running install script." + PWD=$(pwd) + cd .. + git clone https://github.com/emscripten-core/emsdk.git + cd emsdk + git pull + ./emsdk install latest + ./emsdk activate latest + source ./emsdk_env.sh + cd $PWD + echo "Emscripten has been installed. Try running the command again." +fi \ No newline at end of file diff --git a/C++ProjectTemplate b/C++ProjectTemplate new file mode 100755 index 0000000000000000000000000000000000000000..c67847072f2a4ba1ae48fe3f8478553b21e03d50 GIT binary patch literal 576120 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 D#bbQU literal 0 HcmV?d00001 diff --git a/C++ProjectTemplate.data b/C++ProjectTemplate.data new file mode 100644 index 0000000..e69de29 diff --git a/C++ProjectTemplate.html b/C++ProjectTemplate.html new file mode 100644 index 0000000..de51b65 --- /dev/null +++ b/C++ProjectTemplate.html @@ -0,0 +1,75 @@ + + + + + + + + Emscripten-Generated Code + + + + + + + + + + diff --git a/C++ProjectTemplate.js b/C++ProjectTemplate.js new file mode 100644 index 0000000..8e836b2 --- /dev/null +++ b/C++ProjectTemplate.js @@ -0,0 +1 @@ +var Module=typeof Module!="undefined"?Module:{};if(!Module.expectedDataFileDownloads){Module.expectedDataFileDownloads=0}Module.expectedDataFileDownloads++;(function(){if(Module["ENVIRONMENT_IS_PTHREAD"]||Module["$ww"])return;var loadPackage=function(metadata){var PACKAGE_PATH="";if(typeof window==="object"){PACKAGE_PATH=window["encodeURIComponent"](window.location.pathname.toString().substring(0,window.location.pathname.toString().lastIndexOf("/"))+"/")}else if(typeof process==="undefined"&&typeof location!=="undefined"){PACKAGE_PATH=encodeURIComponent(location.pathname.toString().substring(0,location.pathname.toString().lastIndexOf("/"))+"/")}var PACKAGE_NAME="C++ProjectTemplate.data";var REMOTE_PACKAGE_BASE="C++ProjectTemplate.data";if(typeof Module["locateFilePackage"]==="function"&&!Module["locateFile"]){Module["locateFile"]=Module["locateFilePackage"];err("warning: you defined Module.locateFilePackage, that has been renamed to Module.locateFile (using your locateFilePackage for now)")}var REMOTE_PACKAGE_NAME=Module["locateFile"]?Module["locateFile"](REMOTE_PACKAGE_BASE,""):REMOTE_PACKAGE_BASE;var REMOTE_PACKAGE_SIZE=metadata["remote_package_size"];function fetchRemotePackage(packageName,packageSize,callback,errback){if(typeof process==="object"&&typeof process.versions==="object"&&typeof process.versions.node==="string"){require("fs").readFile(packageName,function(err,contents){if(err){errback(err)}else{callback(contents.buffer)}});return}var xhr=new XMLHttpRequest;xhr.open("GET",packageName,true);xhr.responseType="arraybuffer";xhr.onprogress=function(event){var url=packageName;var size=packageSize;if(event.total)size=event.total;if(event.loaded){if(!xhr.addedTotal){xhr.addedTotal=true;if(!Module.dataFileDownloads)Module.dataFileDownloads={};Module.dataFileDownloads[url]={loaded:event.loaded,total:size}}else{Module.dataFileDownloads[url].loaded=event.loaded}var total=0;var loaded=0;var num=0;for(var download in Module.dataFileDownloads){var data=Module.dataFileDownloads[download];total+=data.total;loaded+=data.loaded;num++}total=Math.ceil(total*Module.expectedDataFileDownloads/num);if(Module["setStatus"])Module["setStatus"](`Downloading data... (${loaded}/${total})`)}else if(!Module.dataFileDownloads){if(Module["setStatus"])Module["setStatus"]("Downloading data...")}};xhr.onerror=function(event){throw new Error("NetworkError for: "+packageName)};xhr.onload=function(event){if(xhr.status==200||xhr.status==304||xhr.status==206||xhr.status==0&&xhr.response){var packageData=xhr.response;callback(packageData)}else{throw new Error(xhr.statusText+" : "+xhr.responseURL)}};xhr.send(null)}function handleError(error){console.error("package error:",error)}var fetchedCallback=null;var fetched=Module["getPreloadedPackage"]?Module["getPreloadedPackage"](REMOTE_PACKAGE_NAME,REMOTE_PACKAGE_SIZE):null;if(!fetched)fetchRemotePackage(REMOTE_PACKAGE_NAME,REMOTE_PACKAGE_SIZE,function(data){if(fetchedCallback){fetchedCallback(data);fetchedCallback=null}else{fetched=data}},handleError);function runWithFS(){function assert(check,msg){if(!check)throw msg+(new Error).stack}Module["FS_createPath"]("/","assets",true,true);function DataRequest(start,end,audio){this.start=start;this.end=end;this.audio=audio}DataRequest.prototype={requests:{},open:function(mode,name){this.name=name;this.requests[name]=this;Module["addRunDependency"](`fp ${this.name}`)},send:function(){},onload:function(){var byteArray=this.byteArray.subarray(this.start,this.end);this.finish(byteArray)},finish:function(byteArray){var that=this;Module["FS_createDataFile"](this.name,null,byteArray,true,true,true);Module["removeRunDependency"](`fp ${that.name}`);this.requests[this.name]=null}};var files=metadata["files"];for(var i=0;i{throw toThrow};var ENVIRONMENT_IS_WEB=typeof window=="object";var ENVIRONMENT_IS_WORKER=typeof importScripts=="function";var ENVIRONMENT_IS_NODE=typeof process=="object"&&typeof process.versions=="object"&&typeof process.versions.node=="string";var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var read_,readAsync,readBinary;if(ENVIRONMENT_IS_NODE){var fs=require("fs");var nodePath=require("path");if(ENVIRONMENT_IS_WORKER){scriptDirectory=nodePath.dirname(scriptDirectory)+"/"}else{scriptDirectory=__dirname+"/"}read_=(filename,binary)=>{filename=isFileURI(filename)?new URL(filename):nodePath.normalize(filename);return fs.readFileSync(filename,binary?undefined:"utf8")};readBinary=filename=>{var ret=read_(filename,true);if(!ret.buffer){ret=new Uint8Array(ret)}return ret};readAsync=(filename,onload,onerror,binary=true)=>{filename=isFileURI(filename)?new URL(filename):nodePath.normalize(filename);fs.readFile(filename,binary?undefined:"utf8",(err,data)=>{if(err)onerror(err);else onload(binary?data.buffer:data)})};if(!Module["thisProgram"]&&process.argv.length>1){thisProgram=process.argv[1].replace(/\\/g,"/")}arguments_=process.argv.slice(2);if(typeof module!="undefined"){module["exports"]=Module}process.on("uncaughtException",ex=>{if(ex!=="unwind"&&!(ex instanceof ExitStatus)&&!(ex.context instanceof ExitStatus)){throw ex}});quit_=(status,toThrow)=>{process.exitCode=status;throw toThrow}}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){if(ENVIRONMENT_IS_WORKER){scriptDirectory=self.location.href}else if(typeof document!="undefined"&&document.currentScript){scriptDirectory=document.currentScript.src}if(scriptDirectory.startsWith("blob:")){scriptDirectory=""}else{scriptDirectory=scriptDirectory.substr(0,scriptDirectory.replace(/[?#].*/,"").lastIndexOf("/")+1)}{read_=url=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.send(null);return xhr.responseText};if(ENVIRONMENT_IS_WORKER){readBinary=url=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}}readAsync=(url,onload,onerror)=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=()=>{if(xhr.status==200||xhr.status==0&&xhr.response){onload(xhr.response);return}onerror()};xhr.onerror=onerror;xhr.send(null)}}}else{}var out=Module["print"]||console.log.bind(console);var err=Module["printErr"]||console.error.bind(console);Object.assign(Module,moduleOverrides);moduleOverrides=null;if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"];if(Module["quit"])quit_=Module["quit"];var wasmBinary;if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];if(typeof WebAssembly!="object"){abort("no native wasm support detected")}function intArrayFromBase64(s){if(typeof ENVIRONMENT_IS_NODE!="undefined"&&ENVIRONMENT_IS_NODE){var buf=Buffer.from(s,"base64");return new Uint8Array(buf.buffer,buf.byteOffset,buf.length)}var decoded=atob(s);var bytes=new Uint8Array(decoded.length);for(var i=0;ifilename.startsWith(dataURIPrefix);var isFileURI=filename=>filename.startsWith("file://");var wasmBinaryFile;wasmBinaryFile="C++ProjectTemplate.wasm";if(!isDataURI(wasmBinaryFile)){wasmBinaryFile=locateFile(wasmBinaryFile)}function getBinarySync(file){if(file==wasmBinaryFile&&wasmBinary){return new Uint8Array(wasmBinary)}if(readBinary){return readBinary(file)}throw"both async and sync fetching of the wasm failed"}function getBinaryPromise(binaryFile){if(!wasmBinary&&(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER)){if(typeof fetch=="function"&&!isFileURI(binaryFile)){return fetch(binaryFile,{credentials:"same-origin"}).then(response=>{if(!response["ok"]){throw`failed to load wasm binary file at '${binaryFile}'`}return response["arrayBuffer"]()}).catch(()=>getBinarySync(binaryFile))}else if(readAsync){return new Promise((resolve,reject)=>{readAsync(binaryFile,response=>resolve(new Uint8Array(response)),reject)})}}return Promise.resolve().then(()=>getBinarySync(binaryFile))}function instantiateArrayBuffer(binaryFile,imports,receiver){return getBinaryPromise(binaryFile).then(binary=>WebAssembly.instantiate(binary,imports)).then(receiver,reason=>{err(`failed to asynchronously prepare wasm: ${reason}`);abort(reason)})}function instantiateAsync(binary,binaryFile,imports,callback){if(!binary&&typeof WebAssembly.instantiateStreaming=="function"&&!isDataURI(binaryFile)&&!isFileURI(binaryFile)&&!ENVIRONMENT_IS_NODE&&typeof fetch=="function"){return fetch(binaryFile,{credentials:"same-origin"}).then(response=>{var result=WebAssembly.instantiateStreaming(response,imports);return result.then(callback,function(reason){err(`wasm streaming compile failed: ${reason}`);err("falling back to ArrayBuffer instantiation");return instantiateArrayBuffer(binaryFile,imports,callback)})})}return instantiateArrayBuffer(binaryFile,imports,callback)}function createWasm(){var info={"env":wasmImports,"wasi_snapshot_preview1":wasmImports};function receiveInstance(instance,module){wasmExports=instance.exports;wasmExports=applySignatureConversions(wasmExports);wasmMemory=wasmExports["memory"];updateMemoryViews();wasmTable=wasmExports["__indirect_function_table"];addOnInit(wasmExports["__wasm_call_ctors"]);removeRunDependency("wasm-instantiate");return wasmExports}addRunDependency("wasm-instantiate");function receiveInstantiationResult(result){receiveInstance(result["instance"])}if(Module["instantiateWasm"]){try{return Module["instantiateWasm"](info,receiveInstance)}catch(e){err(`Module.instantiateWasm callback failed with error: ${e}`);return false}}instantiateAsync(wasmBinary,wasmBinaryFile,info,receiveInstantiationResult);return{}}var tempDouble;var tempI64;var ASM_CONSTS={38428:()=>{window.onunload=Module._olc_OnPageUnload},38472:($0,$1)=>{Module.olc_AspectRatio=$0/$1;Module.olc_AssumeDefaultShells=document.querySelectorAll(".emscripten").length>=3?true:false;var olc_ResizeHandler=function(){let isFullscreen=document.fullscreenElement!=null;let width=isFullscreen?window.innerWidth:Module.canvas.parentNode.clientWidth;let height=isFullscreen?window.innerHeight:Module.canvas.parentNode.clientHeight;let viewWidth=width;let viewHeight=width/Module.olc_AspectRatio;if(viewHeight>height){viewWidth=height*Module.olc_AspectRatio;viewHeight=height}viewWidth=parseInt(viewWidth);viewHeight=parseInt(viewHeight);setTimeout(function(){if(Module.olc_AssumeDefaultShells)Module.canvas.parentNode.setAttribute("style","width: 100%; height: 70vh; margin-left: auto; margin-right: auto;");Module.canvas.setAttribute("width",viewWidth);Module.canvas.setAttribute("height",viewHeight);Module.canvas.setAttribute("style",`width: ${viewWidth}px; height: ${viewHeight}px;`);Module._olc_PGE_UpdateWindowSize(viewWidth,viewHeight);Module.canvas.focus()},200)};var olc_Init=function(){if(Module.olc_AspectRatio===undefined){setTimeout(function(){Module.olc_Init()},50);return}let resizeObserver=new ResizeObserver(function(entries){Module.olc_ResizeHandler()}).observe(Module.canvas.parentNode);let mutationObserver=new MutationObserver(function(mutationsList,observer){setTimeout(function(){Module.olc_ResizeHandler()},200)}).observe(Module.canvas.parentNode,{attributes:false,childList:true,subtree:false});window.addEventListener("fullscreenchange",function(e){setTimeout(function(){Module.olc_ResizeHandler()},200)})};Module.olc_ResizeHandler=Module.olc_ResizeHandler!=undefined?Module.olc_ResizeHandler:olc_ResizeHandler;Module.olc_Init=Module.olc_Init!=undefined?Module.olc_Init:olc_Init;Module.olc_Init()}};function ExitStatus(status){this.name="ExitStatus";this.message=`Program terminated with exit(${status})`;this.status=status}var listenOnce=(object,event,func)=>{object.addEventListener(event,func,{"once":true})};var callRuntimeCallbacks=callbacks=>{while(callbacks.length>0){callbacks.shift()(Module)}};var dynCallLegacy=(sig,ptr,args)=>{var f=Module["dynCall_"+sig];return f(ptr,...args)};var wasmTableMirror=[];var wasmTable;var getWasmTableEntry=funcPtr=>{var func=wasmTableMirror[funcPtr];if(!func){if(funcPtr>=wasmTableMirror.length)wasmTableMirror.length=funcPtr+1;wasmTableMirror[funcPtr]=func=wasmTable.get(funcPtr)}return func};var noExitRuntime=Module["noExitRuntime"]||true;class ExceptionInfo{constructor(excPtr){this.excPtr=excPtr;this.ptr=excPtr-24}set_type(type){HEAPU32[this.ptr+4>>>2>>>0]=type}get_type(){return HEAPU32[this.ptr+4>>>2>>>0]}set_destructor(destructor){HEAPU32[this.ptr+8>>>2>>>0]=destructor}get_destructor(){return HEAPU32[this.ptr+8>>>2>>>0]}set_caught(caught){caught=caught?1:0;HEAP8[this.ptr+12>>>0]=caught}get_caught(){return HEAP8[this.ptr+12>>>0]!=0}set_rethrown(rethrown){rethrown=rethrown?1:0;HEAP8[this.ptr+13>>>0]=rethrown}get_rethrown(){return HEAP8[this.ptr+13>>>0]!=0}init(type,destructor){this.set_adjusted_ptr(0);this.set_type(type);this.set_destructor(destructor)}set_adjusted_ptr(adjustedPtr){HEAPU32[this.ptr+16>>>2>>>0]=adjustedPtr}get_adjusted_ptr(){return HEAPU32[this.ptr+16>>>2>>>0]}get_exception_ptr(){var isPointer=___cxa_is_pointer_type(this.get_type());if(isPointer){return HEAPU32[this.excPtr>>>2>>>0]}var adjusted=this.get_adjusted_ptr();if(adjusted!==0)return adjusted;return this.excPtr}}var exceptionLast=0;var uncaughtExceptionCount=0;var convertI32PairToI53Checked=(lo,hi)=>hi+2097152>>>0<4194305-!!lo?(lo>>>0)+hi*4294967296:NaN;function ___cxa_throw(ptr,type,destructor){ptr>>>=0;type>>>=0;destructor>>>=0;var info=new ExceptionInfo(ptr);info.init(type,destructor);exceptionLast=ptr;uncaughtExceptionCount++;throw exceptionLast}var PATH={isAbs:path=>path.charAt(0)==="/",splitPath:filename=>{var splitPathRe=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;return splitPathRe.exec(filename).slice(1)},normalizeArray:(parts,allowAboveRoot)=>{var up=0;for(var i=parts.length-1;i>=0;i--){var last=parts[i];if(last==="."){parts.splice(i,1)}else if(last===".."){parts.splice(i,1);up++}else if(up){parts.splice(i,1);up--}}if(allowAboveRoot){for(;up;up--){parts.unshift("..")}}return parts},normalize:path=>{var isAbsolute=PATH.isAbs(path),trailingSlash=path.substr(-1)==="/";path=PATH.normalizeArray(path.split("/").filter(p=>!!p),!isAbsolute).join("/");if(!path&&!isAbsolute){path="."}if(path&&trailingSlash){path+="/"}return(isAbsolute?"/":"")+path},dirname:path=>{var result=PATH.splitPath(path),root=result[0],dir=result[1];if(!root&&!dir){return"."}if(dir){dir=dir.substr(0,dir.length-1)}return root+dir},basename:path=>{if(path==="/")return"/";path=PATH.normalize(path);path=path.replace(/\/$/,"");var lastSlash=path.lastIndexOf("/");if(lastSlash===-1)return path;return path.substr(lastSlash+1)},join:(...paths)=>PATH.normalize(paths.join("/")),join2:(l,r)=>PATH.normalize(l+"/"+r)};var initRandomFill=()=>{if(typeof crypto=="object"&&typeof crypto["getRandomValues"]=="function"){return view=>crypto.getRandomValues(view)}else if(ENVIRONMENT_IS_NODE){try{var crypto_module=require("crypto");var randomFillSync=crypto_module["randomFillSync"];if(randomFillSync){return view=>crypto_module["randomFillSync"](view)}var randomBytes=crypto_module["randomBytes"];return view=>(view.set(randomBytes(view.byteLength)),view)}catch(e){}}abort("initRandomDevice")};var randomFill=view=>(randomFill=initRandomFill())(view);var PATH_FS={resolve:(...args)=>{var resolvedPath="",resolvedAbsolute=false;for(var i=args.length-1;i>=-1&&!resolvedAbsolute;i--){var path=i>=0?args[i]:FS.cwd();if(typeof path!="string"){throw new TypeError("Arguments to path.resolve must be strings")}else if(!path){return""}resolvedPath=path+"/"+resolvedPath;resolvedAbsolute=PATH.isAbs(path)}resolvedPath=PATH.normalizeArray(resolvedPath.split("/").filter(p=>!!p),!resolvedAbsolute).join("/");return(resolvedAbsolute?"/":"")+resolvedPath||"."},relative:(from,to)=>{from=PATH_FS.resolve(from).substr(1);to=PATH_FS.resolve(to).substr(1);function trim(arr){var start=0;for(;start=0;end--){if(arr[end]!=="")break}if(start>end)return[];return arr.slice(start,end-start+1)}var fromParts=trim(from.split("/"));var toParts=trim(to.split("/"));var length=Math.min(fromParts.length,toParts.length);var samePartsLength=length;for(var i=0;i{idx>>>=0;var endIdx=idx+maxBytesToRead;var endPtr=idx;while(heapOrArray[endPtr]&&!(endPtr>=endIdx))++endPtr;if(endPtr-idx>16&&heapOrArray.buffer&&UTF8Decoder){return UTF8Decoder.decode(heapOrArray.subarray(idx,endPtr))}var str="";while(idx>10,56320|ch&1023)}}return str};var FS_stdin_getChar_buffer=[];var lengthBytesUTF8=str=>{var len=0;for(var i=0;i=55296&&c<=57343){len+=4;++i}else{len+=3}}return len};var stringToUTF8Array=(str,heap,outIdx,maxBytesToWrite)=>{outIdx>>>=0;if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i=55296&&u<=57343){var u1=str.charCodeAt(++i);u=65536+((u&1023)<<10)|u1&1023}if(u<=127){if(outIdx>=endIdx)break;heap[outIdx++>>>0]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;heap[outIdx++>>>0]=192|u>>6;heap[outIdx++>>>0]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;heap[outIdx++>>>0]=224|u>>12;heap[outIdx++>>>0]=128|u>>6&63;heap[outIdx++>>>0]=128|u&63}else{if(outIdx+3>=endIdx)break;heap[outIdx++>>>0]=240|u>>18;heap[outIdx++>>>0]=128|u>>12&63;heap[outIdx++>>>0]=128|u>>6&63;heap[outIdx++>>>0]=128|u&63}}heap[outIdx>>>0]=0;return outIdx-startIdx};function intArrayFromString(stringy,dontAddNull,length){var len=length>0?length:lengthBytesUTF8(stringy)+1;var u8array=new Array(len);var numBytesWritten=stringToUTF8Array(stringy,u8array,0,u8array.length);if(dontAddNull)u8array.length=numBytesWritten;return u8array}var FS_stdin_getChar=()=>{if(!FS_stdin_getChar_buffer.length){var result=null;if(ENVIRONMENT_IS_NODE){var BUFSIZE=256;var buf=Buffer.alloc(BUFSIZE);var bytesRead=0;var fd=process.stdin.fd;try{bytesRead=fs.readSync(fd,buf)}catch(e){if(e.toString().includes("EOF"))bytesRead=0;else throw e}if(bytesRead>0){result=buf.slice(0,bytesRead).toString("utf-8")}else{result=null}}else if(typeof window!="undefined"&&typeof window.prompt=="function"){result=window.prompt("Input: ");if(result!==null){result+="\n"}}else if(typeof readline=="function"){result=readline();if(result!==null){result+="\n"}}if(!result){return null}FS_stdin_getChar_buffer=intArrayFromString(result,true)}return FS_stdin_getChar_buffer.shift()};var TTY={ttys:[],init(){},shutdown(){},register(dev,ops){TTY.ttys[dev]={input:[],output:[],ops:ops};FS.registerDevice(dev,TTY.stream_ops)},stream_ops:{open(stream){var tty=TTY.ttys[stream.node.rdev];if(!tty){throw new FS.ErrnoError(43)}stream.tty=tty;stream.seekable=false},close(stream){stream.tty.ops.fsync(stream.tty)},fsync(stream){stream.tty.ops.fsync(stream.tty)},read(stream,buffer,offset,length,pos){if(!stream.tty||!stream.tty.ops.get_char){throw new FS.ErrnoError(60)}var bytesRead=0;for(var i=0;i0){out(UTF8ArrayToString(tty.output,0));tty.output=[]}},ioctl_tcgets(tty){return{c_iflag:25856,c_oflag:5,c_cflag:191,c_lflag:35387,c_cc:[3,28,127,21,4,0,1,0,17,19,26,0,18,15,23,22,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}},ioctl_tcsets(tty,optional_actions,data){return 0},ioctl_tiocgwinsz(tty){return[24,80]}},default_tty1_ops:{put_char(tty,val){if(val===null||val===10){err(UTF8ArrayToString(tty.output,0));tty.output=[]}else{if(val!=0)tty.output.push(val)}},fsync(tty){if(tty.output&&tty.output.length>0){err(UTF8ArrayToString(tty.output,0));tty.output=[]}}}};var mmapAlloc=size=>{abort()};var MEMFS={ops_table:null,mount(mount){return MEMFS.createNode(null,"/",16384|511,0)},createNode(parent,name,mode,dev){if(FS.isBlkdev(mode)||FS.isFIFO(mode)){throw new FS.ErrnoError(63)}MEMFS.ops_table||={dir:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr,lookup:MEMFS.node_ops.lookup,mknod:MEMFS.node_ops.mknod,rename:MEMFS.node_ops.rename,unlink:MEMFS.node_ops.unlink,rmdir:MEMFS.node_ops.rmdir,readdir:MEMFS.node_ops.readdir,symlink:MEMFS.node_ops.symlink},stream:{llseek:MEMFS.stream_ops.llseek}},file:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr},stream:{llseek:MEMFS.stream_ops.llseek,read:MEMFS.stream_ops.read,write:MEMFS.stream_ops.write,allocate:MEMFS.stream_ops.allocate,mmap:MEMFS.stream_ops.mmap,msync:MEMFS.stream_ops.msync}},link:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr,readlink:MEMFS.node_ops.readlink},stream:{}},chrdev:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr},stream:FS.chrdev_stream_ops}};var node=FS.createNode(parent,name,mode,dev);if(FS.isDir(node.mode)){node.node_ops=MEMFS.ops_table.dir.node;node.stream_ops=MEMFS.ops_table.dir.stream;node.contents={}}else if(FS.isFile(node.mode)){node.node_ops=MEMFS.ops_table.file.node;node.stream_ops=MEMFS.ops_table.file.stream;node.usedBytes=0;node.contents=null}else if(FS.isLink(node.mode)){node.node_ops=MEMFS.ops_table.link.node;node.stream_ops=MEMFS.ops_table.link.stream}else if(FS.isChrdev(node.mode)){node.node_ops=MEMFS.ops_table.chrdev.node;node.stream_ops=MEMFS.ops_table.chrdev.stream}node.timestamp=Date.now();if(parent){parent.contents[name]=node;parent.timestamp=node.timestamp}return node},getFileDataAsTypedArray(node){if(!node.contents)return new Uint8Array(0);if(node.contents.subarray)return node.contents.subarray(0,node.usedBytes);return new Uint8Array(node.contents)},expandFileStorage(node,newCapacity){var prevCapacity=node.contents?node.contents.length:0;if(prevCapacity>=newCapacity)return;var CAPACITY_DOUBLING_MAX=1024*1024;newCapacity=Math.max(newCapacity,prevCapacity*(prevCapacity>>0);if(prevCapacity!=0)newCapacity=Math.max(newCapacity,256);var oldContents=node.contents;node.contents=new Uint8Array(newCapacity);if(node.usedBytes>0)node.contents.set(oldContents.subarray(0,node.usedBytes),0)},resizeFileStorage(node,newSize){if(node.usedBytes==newSize)return;if(newSize==0){node.contents=null;node.usedBytes=0}else{var oldContents=node.contents;node.contents=new Uint8Array(newSize);if(oldContents){node.contents.set(oldContents.subarray(0,Math.min(newSize,node.usedBytes)))}node.usedBytes=newSize}},node_ops:{getattr(node){var attr={};attr.dev=FS.isChrdev(node.mode)?node.id:1;attr.ino=node.id;attr.mode=node.mode;attr.nlink=1;attr.uid=0;attr.gid=0;attr.rdev=node.rdev;if(FS.isDir(node.mode)){attr.size=4096}else if(FS.isFile(node.mode)){attr.size=node.usedBytes}else if(FS.isLink(node.mode)){attr.size=node.link.length}else{attr.size=0}attr.atime=new Date(node.timestamp);attr.mtime=new Date(node.timestamp);attr.ctime=new Date(node.timestamp);attr.blksize=4096;attr.blocks=Math.ceil(attr.size/attr.blksize);return attr},setattr(node,attr){if(attr.mode!==undefined){node.mode=attr.mode}if(attr.timestamp!==undefined){node.timestamp=attr.timestamp}if(attr.size!==undefined){MEMFS.resizeFileStorage(node,attr.size)}},lookup(parent,name){throw FS.genericErrors[44]},mknod(parent,name,mode,dev){return MEMFS.createNode(parent,name,mode,dev)},rename(old_node,new_dir,new_name){if(FS.isDir(old_node.mode)){var new_node;try{new_node=FS.lookupNode(new_dir,new_name)}catch(e){}if(new_node){for(var i in new_node.contents){throw new FS.ErrnoError(55)}}}delete old_node.parent.contents[old_node.name];old_node.parent.timestamp=Date.now();old_node.name=new_name;new_dir.contents[new_name]=old_node;new_dir.timestamp=old_node.parent.timestamp;old_node.parent=new_dir},unlink(parent,name){delete parent.contents[name];parent.timestamp=Date.now()},rmdir(parent,name){var node=FS.lookupNode(parent,name);for(var i in node.contents){throw new FS.ErrnoError(55)}delete parent.contents[name];parent.timestamp=Date.now()},readdir(node){var entries=[".",".."];for(var key of Object.keys(node.contents)){entries.push(key)}return entries},symlink(parent,newname,oldpath){var node=MEMFS.createNode(parent,newname,511|40960,0);node.link=oldpath;return node},readlink(node){if(!FS.isLink(node.mode)){throw new FS.ErrnoError(28)}return node.link}},stream_ops:{read(stream,buffer,offset,length,position){var contents=stream.node.contents;if(position>=stream.node.usedBytes)return 0;var size=Math.min(stream.node.usedBytes-position,length);if(size>8&&contents.subarray){buffer.set(contents.subarray(position,position+size),offset)}else{for(var i=0;i0||position+length>>0)}return{ptr:ptr,allocated:allocated}},msync(stream,buffer,offset,length,mmapFlags){MEMFS.stream_ops.write(stream,buffer,0,length,offset,false);return 0}}};var asyncLoad=(url,onload,onerror,noRunDep)=>{var dep=!noRunDep?getUniqueRunDependency(`al ${url}`):"";readAsync(url,arrayBuffer=>{onload(new Uint8Array(arrayBuffer));if(dep)removeRunDependency(dep)},event=>{if(onerror){onerror()}else{throw`Loading data file "${url}" failed.`}});if(dep)addRunDependency(dep)};var FS_createDataFile=(parent,name,fileData,canRead,canWrite,canOwn)=>{FS.createDataFile(parent,name,fileData,canRead,canWrite,canOwn)};var preloadPlugins=Module["preloadPlugins"]||[];var FS_handledByPreloadPlugin=(byteArray,fullname,finish,onerror)=>{if(typeof Browser!="undefined")Browser.init();var handled=false;preloadPlugins.forEach(plugin=>{if(handled)return;if(plugin["canHandle"](fullname)){plugin["handle"](byteArray,fullname,finish,onerror);handled=true}});return handled};var FS_createPreloadedFile=(parent,name,url,canRead,canWrite,onload,onerror,dontCreateFile,canOwn,preFinish)=>{var fullname=name?PATH_FS.resolve(PATH.join2(parent,name)):parent;var dep=getUniqueRunDependency(`cp ${fullname}`);function processData(byteArray){function finish(byteArray){preFinish?.();if(!dontCreateFile){FS_createDataFile(parent,name,byteArray,canRead,canWrite,canOwn)}onload?.();removeRunDependency(dep)}if(FS_handledByPreloadPlugin(byteArray,fullname,finish,()=>{onerror?.();removeRunDependency(dep)})){return}finish(byteArray)}addRunDependency(dep);if(typeof url=="string"){asyncLoad(url,processData,onerror)}else{processData(url)}};var FS_modeStringToFlags=str=>{var flagModes={"r":0,"r+":2,"w":512|64|1,"w+":512|64|2,"a":1024|64|1,"a+":1024|64|2};var flags=flagModes[str];if(typeof flags=="undefined"){throw new Error(`Unknown file open mode: ${str}`)}return flags};var FS_getMode=(canRead,canWrite)=>{var mode=0;if(canRead)mode|=292|73;if(canWrite)mode|=146;return mode};var FS={root:null,mounts:[],devices:{},streams:[],nextInode:1,nameTable:null,currentPath:"/",initialized:false,ignorePermissions:true,ErrnoError:class{constructor(errno){this.name="ErrnoError";this.errno=errno}},genericErrors:{},filesystems:null,syncFSRequests:0,lookupPath(path,opts={}){path=PATH_FS.resolve(path);if(!path)return{path:"",node:null};var defaults={follow_mount:true,recurse_count:0};opts=Object.assign(defaults,opts);if(opts.recurse_count>8){throw new FS.ErrnoError(32)}var parts=path.split("/").filter(p=>!!p);var current=FS.root;var current_path="/";for(var i=0;i40){throw new FS.ErrnoError(32)}}}}return{path:current_path,node:current}},getPath(node){var path;while(true){if(FS.isRoot(node)){var mount=node.mount.mountpoint;if(!path)return mount;return mount[mount.length-1]!=="/"?`${mount}/${path}`:mount+path}path=path?`${node.name}/${path}`:node.name;node=node.parent}},hashName(parentid,name){var hash=0;for(var i=0;i>>0)%FS.nameTable.length},hashAddNode(node){var hash=FS.hashName(node.parent.id,node.name);node.name_next=FS.nameTable[hash];FS.nameTable[hash]=node},hashRemoveNode(node){var hash=FS.hashName(node.parent.id,node.name);if(FS.nameTable[hash]===node){FS.nameTable[hash]=node.name_next}else{var current=FS.nameTable[hash];while(current){if(current.name_next===node){current.name_next=node.name_next;break}current=current.name_next}}},lookupNode(parent,name){var errCode=FS.mayLookup(parent);if(errCode){throw new FS.ErrnoError(errCode)}var hash=FS.hashName(parent.id,name);for(var node=FS.nameTable[hash];node;node=node.name_next){var nodeName=node.name;if(node.parent.id===parent.id&&nodeName===name){return node}}return FS.lookup(parent,name)},createNode(parent,name,mode,rdev){var node=new FS.FSNode(parent,name,mode,rdev);FS.hashAddNode(node);return node},destroyNode(node){FS.hashRemoveNode(node)},isRoot(node){return node===node.parent},isMountpoint(node){return!!node.mounted},isFile(mode){return(mode&61440)===32768},isDir(mode){return(mode&61440)===16384},isLink(mode){return(mode&61440)===40960},isChrdev(mode){return(mode&61440)===8192},isBlkdev(mode){return(mode&61440)===24576},isFIFO(mode){return(mode&61440)===4096},isSocket(mode){return(mode&49152)===49152},flagsToPermissionString(flag){var perms=["r","w","rw"][flag&3];if(flag&512){perms+="w"}return perms},nodePermissions(node,perms){if(FS.ignorePermissions){return 0}if(perms.includes("r")&&!(node.mode&292)){return 2}else if(perms.includes("w")&&!(node.mode&146)){return 2}else if(perms.includes("x")&&!(node.mode&73)){return 2}return 0},mayLookup(dir){if(!FS.isDir(dir.mode))return 54;var errCode=FS.nodePermissions(dir,"x");if(errCode)return errCode;if(!dir.node_ops.lookup)return 2;return 0},mayCreate(dir,name){try{var node=FS.lookupNode(dir,name);return 20}catch(e){}return FS.nodePermissions(dir,"wx")},mayDelete(dir,name,isdir){var node;try{node=FS.lookupNode(dir,name)}catch(e){return e.errno}var errCode=FS.nodePermissions(dir,"wx");if(errCode){return errCode}if(isdir){if(!FS.isDir(node.mode)){return 54}if(FS.isRoot(node)||FS.getPath(node)===FS.cwd()){return 10}}else{if(FS.isDir(node.mode)){return 31}}return 0},mayOpen(node,flags){if(!node){return 44}if(FS.isLink(node.mode)){return 32}else if(FS.isDir(node.mode)){if(FS.flagsToPermissionString(flags)!=="r"||flags&512){return 31}}return FS.nodePermissions(node,FS.flagsToPermissionString(flags))},MAX_OPEN_FDS:4096,nextfd(){for(var fd=0;fd<=FS.MAX_OPEN_FDS;fd++){if(!FS.streams[fd]){return fd}}throw new FS.ErrnoError(33)},getStreamChecked(fd){var stream=FS.getStream(fd);if(!stream){throw new FS.ErrnoError(8)}return stream},getStream:fd=>FS.streams[fd],createStream(stream,fd=-1){if(!FS.FSStream){FS.FSStream=function(){this.shared={}};FS.FSStream.prototype={};Object.defineProperties(FS.FSStream.prototype,{object:{get(){return this.node},set(val){this.node=val}},isRead:{get(){return(this.flags&2097155)!==1}},isWrite:{get(){return(this.flags&2097155)!==0}},isAppend:{get(){return this.flags&1024}},flags:{get(){return this.shared.flags},set(val){this.shared.flags=val}},position:{get(){return this.shared.position},set(val){this.shared.position=val}}})}stream=Object.assign(new FS.FSStream,stream);if(fd==-1){fd=FS.nextfd()}stream.fd=fd;FS.streams[fd]=stream;return stream},closeStream(fd){FS.streams[fd]=null},chrdev_stream_ops:{open(stream){var device=FS.getDevice(stream.node.rdev);stream.stream_ops=device.stream_ops;stream.stream_ops.open?.(stream)},llseek(){throw new FS.ErrnoError(70)}},major:dev=>dev>>8,minor:dev=>dev&255,makedev:(ma,mi)=>ma<<8|mi,registerDevice(dev,ops){FS.devices[dev]={stream_ops:ops}},getDevice:dev=>FS.devices[dev],getMounts(mount){var mounts=[];var check=[mount];while(check.length){var m=check.pop();mounts.push(m);check.push(...m.mounts)}return mounts},syncfs(populate,callback){if(typeof populate=="function"){callback=populate;populate=false}FS.syncFSRequests++;if(FS.syncFSRequests>1){err(`warning: ${FS.syncFSRequests} FS.syncfs operations in flight at once, probably just doing extra work`)}var mounts=FS.getMounts(FS.root.mount);var completed=0;function doCallback(errCode){FS.syncFSRequests--;return callback(errCode)}function done(errCode){if(errCode){if(!done.errored){done.errored=true;return doCallback(errCode)}return}if(++completed>=mounts.length){doCallback(null)}}mounts.forEach(mount=>{if(!mount.type.syncfs){return done(null)}mount.type.syncfs(mount,populate,done)})},mount(type,opts,mountpoint){var root=mountpoint==="/";var pseudo=!mountpoint;var node;if(root&&FS.root){throw new FS.ErrnoError(10)}else if(!root&&!pseudo){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});mountpoint=lookup.path;node=lookup.node;if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}if(!FS.isDir(node.mode)){throw new FS.ErrnoError(54)}}var mount={type:type,opts:opts,mountpoint:mountpoint,mounts:[]};var mountRoot=type.mount(mount);mountRoot.mount=mount;mount.root=mountRoot;if(root){FS.root=mountRoot}else if(node){node.mounted=mount;if(node.mount){node.mount.mounts.push(mount)}}return mountRoot},unmount(mountpoint){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});if(!FS.isMountpoint(lookup.node)){throw new FS.ErrnoError(28)}var node=lookup.node;var mount=node.mounted;var mounts=FS.getMounts(mount);Object.keys(FS.nameTable).forEach(hash=>{var current=FS.nameTable[hash];while(current){var next=current.name_next;if(mounts.includes(current.mount)){FS.destroyNode(current)}current=next}});node.mounted=null;var idx=node.mount.mounts.indexOf(mount);node.mount.mounts.splice(idx,1)},lookup(parent,name){return parent.node_ops.lookup(parent,name)},mknod(path,mode,dev){var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;var name=PATH.basename(path);if(!name||name==="."||name===".."){throw new FS.ErrnoError(28)}var errCode=FS.mayCreate(parent,name);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.mknod){throw new FS.ErrnoError(63)}return parent.node_ops.mknod(parent,name,mode,dev)},create(path,mode){mode=mode!==undefined?mode:438;mode&=4095;mode|=32768;return FS.mknod(path,mode,0)},mkdir(path,mode){mode=mode!==undefined?mode:511;mode&=511|512;mode|=16384;return FS.mknod(path,mode,0)},mkdirTree(path,mode){var dirs=path.split("/");var d="";for(var i=0;i0,ioctl(stream,cmd,arg){if(!stream.stream_ops.ioctl){throw new FS.ErrnoError(59)}return stream.stream_ops.ioctl(stream,cmd,arg)},readFile(path,opts={}){opts.flags=opts.flags||0;opts.encoding=opts.encoding||"binary";if(opts.encoding!=="utf8"&&opts.encoding!=="binary"){throw new Error(`Invalid encoding type "${opts.encoding}"`)}var ret;var stream=FS.open(path,opts.flags);var stat=FS.stat(path);var length=stat.size;var buf=new Uint8Array(length);FS.read(stream,buf,0,length,0);if(opts.encoding==="utf8"){ret=UTF8ArrayToString(buf,0)}else if(opts.encoding==="binary"){ret=buf}FS.close(stream);return ret},writeFile(path,data,opts={}){opts.flags=opts.flags||577;var stream=FS.open(path,opts.flags,opts.mode);if(typeof data=="string"){var buf=new Uint8Array(lengthBytesUTF8(data)+1);var actualNumBytes=stringToUTF8Array(data,buf,0,buf.length);FS.write(stream,buf,0,actualNumBytes,undefined,opts.canOwn)}else if(ArrayBuffer.isView(data)){FS.write(stream,data,0,data.byteLength,undefined,opts.canOwn)}else{throw new Error("Unsupported data type")}FS.close(stream)},cwd:()=>FS.currentPath,chdir(path){var lookup=FS.lookupPath(path,{follow:true});if(lookup.node===null){throw new FS.ErrnoError(44)}if(!FS.isDir(lookup.node.mode)){throw new FS.ErrnoError(54)}var errCode=FS.nodePermissions(lookup.node,"x");if(errCode){throw new FS.ErrnoError(errCode)}FS.currentPath=lookup.path},createDefaultDirectories(){FS.mkdir("/tmp");FS.mkdir("/home");FS.mkdir("/home/web_user")},createDefaultDevices(){FS.mkdir("/dev");FS.registerDevice(FS.makedev(1,3),{read:()=>0,write:(stream,buffer,offset,length,pos)=>length});FS.mkdev("/dev/null",FS.makedev(1,3));TTY.register(FS.makedev(5,0),TTY.default_tty_ops);TTY.register(FS.makedev(6,0),TTY.default_tty1_ops);FS.mkdev("/dev/tty",FS.makedev(5,0));FS.mkdev("/dev/tty1",FS.makedev(6,0));var randomBuffer=new Uint8Array(1024),randomLeft=0;var randomByte=()=>{if(randomLeft===0){randomLeft=randomFill(randomBuffer).byteLength}return randomBuffer[--randomLeft]};FS.createDevice("/dev","random",randomByte);FS.createDevice("/dev","urandom",randomByte);FS.mkdir("/dev/shm");FS.mkdir("/dev/shm/tmp")},createSpecialDirectories(){FS.mkdir("/proc");var proc_self=FS.mkdir("/proc/self");FS.mkdir("/proc/self/fd");FS.mount({mount(){var node=FS.createNode(proc_self,"fd",16384|511,73);node.node_ops={lookup(parent,name){var fd=+name;var stream=FS.getStreamChecked(fd);var ret={parent:null,mount:{mountpoint:"fake"},node_ops:{readlink:()=>stream.path}};ret.parent=ret;return ret}};return node}},{},"/proc/self/fd")},createStandardStreams(){if(Module["stdin"]){FS.createDevice("/dev","stdin",Module["stdin"])}else{FS.symlink("/dev/tty","/dev/stdin")}if(Module["stdout"]){FS.createDevice("/dev","stdout",null,Module["stdout"])}else{FS.symlink("/dev/tty","/dev/stdout")}if(Module["stderr"]){FS.createDevice("/dev","stderr",null,Module["stderr"])}else{FS.symlink("/dev/tty1","/dev/stderr")}var stdin=FS.open("/dev/stdin",0);var stdout=FS.open("/dev/stdout",1);var stderr=FS.open("/dev/stderr",1)},staticInit(){[44].forEach(code=>{FS.genericErrors[code]=new FS.ErrnoError(code);FS.genericErrors[code].stack=""});FS.nameTable=new Array(4096);FS.mount(MEMFS,{},"/");FS.createDefaultDirectories();FS.createDefaultDevices();FS.createSpecialDirectories();FS.filesystems={"MEMFS":MEMFS}},init(input,output,error){FS.init.initialized=true;Module["stdin"]=input||Module["stdin"];Module["stdout"]=output||Module["stdout"];Module["stderr"]=error||Module["stderr"];FS.createStandardStreams()},quit(){FS.init.initialized=false;for(var i=0;ithis.length-1||idx<0){return undefined}var chunkOffset=idx%this.chunkSize;var chunkNum=idx/this.chunkSize|0;return this.getter(chunkNum)[chunkOffset]};LazyUint8Array.prototype.setDataGetter=function LazyUint8Array_setDataGetter(getter){this.getter=getter};LazyUint8Array.prototype.cacheLength=function LazyUint8Array_cacheLength(){var xhr=new XMLHttpRequest;xhr.open("HEAD",url,false);xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))throw new Error("Couldn't load "+url+". Status: "+xhr.status);var datalength=Number(xhr.getResponseHeader("Content-length"));var header;var hasByteServing=(header=xhr.getResponseHeader("Accept-Ranges"))&&header==="bytes";var usesGzip=(header=xhr.getResponseHeader("Content-Encoding"))&&header==="gzip";var chunkSize=1024*1024;if(!hasByteServing)chunkSize=datalength;var doXHR=(from,to)=>{if(from>to)throw new Error("invalid range ("+from+", "+to+") or no bytes requested!");if(to>datalength-1)throw new Error("only "+datalength+" bytes available! programmer error!");var xhr=new XMLHttpRequest;xhr.open("GET",url,false);if(datalength!==chunkSize)xhr.setRequestHeader("Range","bytes="+from+"-"+to);xhr.responseType="arraybuffer";if(xhr.overrideMimeType){xhr.overrideMimeType("text/plain; charset=x-user-defined")}xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))throw new Error("Couldn't load "+url+". Status: "+xhr.status);if(xhr.response!==undefined){return new Uint8Array(xhr.response||[])}return intArrayFromString(xhr.responseText||"",true)};var lazyArray=this;lazyArray.setDataGetter(chunkNum=>{var start=chunkNum*chunkSize;var end=(chunkNum+1)*chunkSize-1;end=Math.min(end,datalength-1);if(typeof lazyArray.chunks[chunkNum]=="undefined"){lazyArray.chunks[chunkNum]=doXHR(start,end)}if(typeof lazyArray.chunks[chunkNum]=="undefined")throw new Error("doXHR failed!");return lazyArray.chunks[chunkNum]});if(usesGzip||!datalength){chunkSize=datalength=1;datalength=this.getter(0).length;chunkSize=datalength;out("LazyFiles on gzip forces download of the whole file when length is accessed")}this._length=datalength;this._chunkSize=chunkSize;this.lengthKnown=true};if(typeof XMLHttpRequest!="undefined"){if(!ENVIRONMENT_IS_WORKER)throw"Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc";var lazyArray=new LazyUint8Array;Object.defineProperties(lazyArray,{length:{get:function(){if(!this.lengthKnown){this.cacheLength()}return this._length}},chunkSize:{get:function(){if(!this.lengthKnown){this.cacheLength()}return this._chunkSize}}});var properties={isDevice:false,contents:lazyArray}}else{var properties={isDevice:false,url:url}}var node=FS.createFile(parent,name,properties,canRead,canWrite);if(properties.contents){node.contents=properties.contents}else if(properties.url){node.contents=null;node.url=properties.url}Object.defineProperties(node,{usedBytes:{get:function(){return this.contents.length}}});var stream_ops={};var keys=Object.keys(node.stream_ops);keys.forEach(key=>{var fn=node.stream_ops[key];stream_ops[key]=(...args)=>{FS.forceLoadFile(node);return fn(...args)}});function writeChunks(stream,buffer,offset,length,position){var contents=stream.node.contents;if(position>=contents.length)return 0;var size=Math.min(contents.length-position,length);if(contents.slice){for(var i=0;i{FS.forceLoadFile(node);return writeChunks(stream,buffer,offset,length,position)};stream_ops.mmap=(stream,length,position,prot,flags)=>{FS.forceLoadFile(node);var ptr=mmapAlloc(length);if(!ptr){throw new FS.ErrnoError(48)}writeChunks(stream,HEAP8,ptr,length,position);return{ptr:ptr,allocated:true}};node.stream_ops=stream_ops;return node}};var UTF8ToString=(ptr,maxBytesToRead)=>{ptr>>>=0;return ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead):""};var SYSCALLS={DEFAULT_POLLMASK:5,calculateAt(dirfd,path,allowEmpty){if(PATH.isAbs(path)){return path}var dir;if(dirfd===-100){dir=FS.cwd()}else{var dirstream=SYSCALLS.getStreamFromFD(dirfd);dir=dirstream.path}if(path.length==0){if(!allowEmpty){throw new FS.ErrnoError(44)}return dir}return PATH.join2(dir,path)},doStat(func,path,buf){var stat=func(path);HEAP32[buf>>>2>>>0]=stat.dev;HEAP32[buf+4>>>2>>>0]=stat.mode;HEAPU32[buf+8>>>2>>>0]=stat.nlink;HEAP32[buf+12>>>2>>>0]=stat.uid;HEAP32[buf+16>>>2>>>0]=stat.gid;HEAP32[buf+20>>>2>>>0]=stat.rdev;tempI64=[stat.size>>>0,(tempDouble=stat.size,+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+24>>>2>>>0]=tempI64[0],HEAP32[buf+28>>>2>>>0]=tempI64[1];HEAP32[buf+32>>>2>>>0]=4096;HEAP32[buf+36>>>2>>>0]=stat.blocks;var atime=stat.atime.getTime();var mtime=stat.mtime.getTime();var ctime=stat.ctime.getTime();tempI64=[Math.floor(atime/1e3)>>>0,(tempDouble=Math.floor(atime/1e3),+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+40>>>2>>>0]=tempI64[0],HEAP32[buf+44>>>2>>>0]=tempI64[1];HEAPU32[buf+48>>>2>>>0]=atime%1e3*1e3;tempI64=[Math.floor(mtime/1e3)>>>0,(tempDouble=Math.floor(mtime/1e3),+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+56>>>2>>>0]=tempI64[0],HEAP32[buf+60>>>2>>>0]=tempI64[1];HEAPU32[buf+64>>>2>>>0]=mtime%1e3*1e3;tempI64=[Math.floor(ctime/1e3)>>>0,(tempDouble=Math.floor(ctime/1e3),+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+72>>>2>>>0]=tempI64[0],HEAP32[buf+76>>>2>>>0]=tempI64[1];HEAPU32[buf+80>>>2>>>0]=ctime%1e3*1e3;tempI64=[stat.ino>>>0,(tempDouble=stat.ino,+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+88>>>2>>>0]=tempI64[0],HEAP32[buf+92>>>2>>>0]=tempI64[1];return 0},doMsync(addr,stream,len,flags,offset){if(!FS.isFile(stream.node.mode)){throw new FS.ErrnoError(43)}if(flags&2){return 0}var buffer=HEAPU8.slice(addr,addr+len);FS.msync(stream,buffer,offset,len,flags)},varargs:undefined,get(){var ret=HEAP32[+SYSCALLS.varargs>>>2>>>0];SYSCALLS.varargs+=4;return ret},getp(){return SYSCALLS.get()},getStr(ptr){var ret=UTF8ToString(ptr);return ret},getStreamFromFD(fd){var stream=FS.getStreamChecked(fd);return stream}};function ___syscall_fcntl64(fd,cmd,varargs){varargs>>>=0;SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD(fd);switch(cmd){case 0:{var arg=SYSCALLS.get();if(arg<0){return-28}while(FS.streams[arg]){arg++}var newStream;newStream=FS.createStream(stream,arg);return newStream.fd}case 1:case 2:return 0;case 3:return stream.flags;case 4:{var arg=SYSCALLS.get();stream.flags|=arg;return 0}case 12:{var arg=SYSCALLS.getp();var offset=0;HEAP16[arg+offset>>>1>>>0]=2;return 0}case 13:case 14:return 0}return-28}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_ioctl(fd,op,varargs){varargs>>>=0;SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD(fd);switch(op){case 21509:{if(!stream.tty)return-59;return 0}case 21505:{if(!stream.tty)return-59;if(stream.tty.ops.ioctl_tcgets){var termios=stream.tty.ops.ioctl_tcgets(stream);var argp=SYSCALLS.getp();HEAP32[argp>>>2>>>0]=termios.c_iflag||0;HEAP32[argp+4>>>2>>>0]=termios.c_oflag||0;HEAP32[argp+8>>>2>>>0]=termios.c_cflag||0;HEAP32[argp+12>>>2>>>0]=termios.c_lflag||0;for(var i=0;i<32;i++){HEAP8[argp+i+17>>>0]=termios.c_cc[i]||0}return 0}return 0}case 21510:case 21511:case 21512:{if(!stream.tty)return-59;return 0}case 21506:case 21507:case 21508:{if(!stream.tty)return-59;if(stream.tty.ops.ioctl_tcsets){var argp=SYSCALLS.getp();var c_iflag=HEAP32[argp>>>2>>>0];var c_oflag=HEAP32[argp+4>>>2>>>0];var c_cflag=HEAP32[argp+8>>>2>>>0];var c_lflag=HEAP32[argp+12>>>2>>>0];var c_cc=[];for(var i=0;i<32;i++){c_cc.push(HEAP8[argp+i+17>>>0])}return stream.tty.ops.ioctl_tcsets(stream.tty,op,{c_iflag:c_iflag,c_oflag:c_oflag,c_cflag:c_cflag,c_lflag:c_lflag,c_cc:c_cc})}return 0}case 21519:{if(!stream.tty)return-59;var argp=SYSCALLS.getp();HEAP32[argp>>>2>>>0]=0;return 0}case 21520:{if(!stream.tty)return-59;return-28}case 21531:{var argp=SYSCALLS.getp();return FS.ioctl(stream,op,argp)}case 21523:{if(!stream.tty)return-59;if(stream.tty.ops.ioctl_tiocgwinsz){var winsize=stream.tty.ops.ioctl_tiocgwinsz(stream.tty);var argp=SYSCALLS.getp();HEAP16[argp>>>1>>>0]=winsize[0];HEAP16[argp+2>>>1>>>0]=winsize[1]}return 0}case 21524:{if(!stream.tty)return-59;return 0}case 21515:{if(!stream.tty)return-59;return 0}default:return-28}}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}function ___syscall_openat(dirfd,path,flags,varargs){path>>>=0;varargs>>>=0;SYSCALLS.varargs=varargs;try{path=SYSCALLS.getStr(path);path=SYSCALLS.calculateAt(dirfd,path);var mode=varargs?SYSCALLS.get():0;return FS.open(path,flags,mode).fd}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return-e.errno}}var nowIsMonotonic=1;var __emscripten_get_now_is_monotonic=()=>nowIsMonotonic;var __emscripten_throw_longjmp=()=>{throw Infinity};var _abort=()=>{abort("")};var _emscripten_set_main_loop_timing=(mode,value)=>{Browser.mainLoop.timingMode=mode;Browser.mainLoop.timingValue=value;if(!Browser.mainLoop.func){return 1}if(!Browser.mainLoop.running){Browser.mainLoop.running=true}if(mode==0){Browser.mainLoop.scheduler=function Browser_mainLoop_scheduler_setTimeout(){var timeUntilNextTick=Math.max(0,Browser.mainLoop.tickStartTime+value-_emscripten_get_now())|0;setTimeout(Browser.mainLoop.runner,timeUntilNextTick)};Browser.mainLoop.method="timeout"}else if(mode==1){Browser.mainLoop.scheduler=function Browser_mainLoop_scheduler_rAF(){Browser.requestAnimationFrame(Browser.mainLoop.runner)};Browser.mainLoop.method="rAF"}else if(mode==2){if(typeof Browser.setImmediate=="undefined"){if(typeof setImmediate=="undefined"){var setImmediates=[];var emscriptenMainLoopMessageId="setimmediate";var Browser_setImmediate_messageHandler=event=>{if(event.data===emscriptenMainLoopMessageId||event.data.target===emscriptenMainLoopMessageId){event.stopPropagation();setImmediates.shift()()}};addEventListener("message",Browser_setImmediate_messageHandler,true);Browser.setImmediate=function Browser_emulated_setImmediate(func){setImmediates.push(func);if(ENVIRONMENT_IS_WORKER){if(Module["setImmediates"]===undefined)Module["setImmediates"]=[];Module["setImmediates"].push(func);postMessage({target:emscriptenMainLoopMessageId})}else postMessage(emscriptenMainLoopMessageId,"*")}}else{Browser.setImmediate=setImmediate}}Browser.mainLoop.scheduler=function Browser_mainLoop_scheduler_setImmediate(){Browser.setImmediate(Browser.mainLoop.runner)};Browser.mainLoop.method="immediate"}return 0};var _emscripten_get_now;_emscripten_get_now=()=>performance.now();var setMainLoop=(browserIterationFunc,fps,simulateInfiniteLoop,arg,noSetTiming)=>{assert(!Browser.mainLoop.func,"emscripten_set_main_loop: there can only be one main loop function at once: call emscripten_cancel_main_loop to cancel the previous one before setting a new one with different parameters.");Browser.mainLoop.func=browserIterationFunc;Browser.mainLoop.arg=arg;var thisMainLoopId=Browser.mainLoop.currentlyRunningMainloop;function checkIsRunning(){if(thisMainLoopId0){var start=Date.now();var blocker=Browser.mainLoop.queue.shift();blocker.func(blocker.arg);if(Browser.mainLoop.remainingBlockers){var remaining=Browser.mainLoop.remainingBlockers;var next=remaining%1==0?remaining-1:Math.floor(remaining);if(blocker.counted){Browser.mainLoop.remainingBlockers=next}else{next=next+.5;Browser.mainLoop.remainingBlockers=(8*remaining+next)/9}}Browser.mainLoop.updateStatus();if(!checkIsRunning())return;setTimeout(Browser.mainLoop.runner,0);return}if(!checkIsRunning())return;Browser.mainLoop.currentFrameNumber=Browser.mainLoop.currentFrameNumber+1|0;if(Browser.mainLoop.timingMode==1&&Browser.mainLoop.timingValue>1&&Browser.mainLoop.currentFrameNumber%Browser.mainLoop.timingValue!=0){Browser.mainLoop.scheduler();return}else if(Browser.mainLoop.timingMode==0){Browser.mainLoop.tickStartTime=_emscripten_get_now()}Browser.mainLoop.runIter(browserIterationFunc);if(!checkIsRunning())return;if(typeof SDL=="object")SDL.audio?.queueNewAudioData?.();Browser.mainLoop.scheduler()};if(!noSetTiming){if(fps&&fps>0){_emscripten_set_main_loop_timing(0,1e3/fps)}else{_emscripten_set_main_loop_timing(1,1)}Browser.mainLoop.scheduler()}if(simulateInfiniteLoop){throw"unwind"}};var handleException=e=>{if(e instanceof ExitStatus||e=="unwind"){return EXITSTATUS}quit_(1,e)};var runtimeKeepaliveCounter=0;var keepRuntimeAlive=()=>noExitRuntime||runtimeKeepaliveCounter>0;var _proc_exit=code=>{EXITSTATUS=code;if(!keepRuntimeAlive()){Module["onExit"]?.(code);ABORT=true}quit_(code,new ExitStatus(code))};var exitJS=(status,implicit)=>{EXITSTATUS=status;_proc_exit(status)};var _exit=exitJS;var maybeExit=()=>{if(!keepRuntimeAlive()){try{_exit(EXITSTATUS)}catch(e){handleException(e)}}};var callUserCallback=func=>{if(ABORT){return}try{func();maybeExit()}catch(e){handleException(e)}};var safeSetTimeout=(func,timeout)=>setTimeout(()=>{callUserCallback(func)},timeout);var warnOnce=text=>{warnOnce.shown||={};if(!warnOnce.shown[text]){warnOnce.shown[text]=1;if(ENVIRONMENT_IS_NODE)text="warning: "+text;err(text)}};var Browser={mainLoop:{running:false,scheduler:null,method:"",currentlyRunningMainloop:0,func:null,arg:0,timingMode:0,timingValue:0,currentFrameNumber:0,queue:[],pause(){Browser.mainLoop.scheduler=null;Browser.mainLoop.currentlyRunningMainloop++},resume(){Browser.mainLoop.currentlyRunningMainloop++;var timingMode=Browser.mainLoop.timingMode;var timingValue=Browser.mainLoop.timingValue;var func=Browser.mainLoop.func;Browser.mainLoop.func=null;setMainLoop(func,0,false,Browser.mainLoop.arg,true);_emscripten_set_main_loop_timing(timingMode,timingValue);Browser.mainLoop.scheduler()},updateStatus(){if(Module["setStatus"]){var message=Module["statusMessage"]||"Please wait...";var remaining=Browser.mainLoop.remainingBlockers;var expected=Browser.mainLoop.expectedBlockers;if(remaining){if(remaining{assert(img.complete,`Image ${name} could not be decoded`);var canvas=document.createElement("canvas");canvas.width=img.width;canvas.height=img.height;var ctx=canvas.getContext("2d");ctx.drawImage(img,0,0);preloadedImages[name]=canvas;URL.revokeObjectURL(url);onload?.(byteArray)};img.onerror=event=>{err(`Image ${url} could not be decoded`);onerror?.()};img.src=url};preloadPlugins.push(imagePlugin);var audioPlugin={};audioPlugin["canHandle"]=function audioPlugin_canHandle(name){return!Module.noAudioDecoding&&name.substr(-4)in{".ogg":1,".wav":1,".mp3":1}};audioPlugin["handle"]=function audioPlugin_handle(byteArray,name,onload,onerror){var done=false;function finish(audio){if(done)return;done=true;preloadedAudios[name]=audio;onload?.(byteArray)}var b=new Blob([byteArray],{type:Browser.getMimetype(name)});var url=URL.createObjectURL(b);var audio=new Audio;audio.addEventListener("canplaythrough",()=>finish(audio),false);audio.onerror=function audio_onerror(event){if(done)return;err(`warning: browser could not fully decode audio ${name}, trying slower base64 approach`);function encode64(data){var BASE="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";var PAD="=";var ret="";var leftchar=0;var leftbits=0;for(var i=0;i=6){var curr=leftchar>>leftbits-6&63;leftbits-=6;ret+=BASE[curr]}}if(leftbits==2){ret+=BASE[(leftchar&3)<<4];ret+=PAD+PAD}else if(leftbits==4){ret+=BASE[(leftchar&15)<<2];ret+=PAD}return ret}audio.src="data:audio/x-"+name.substr(-3)+";base64,"+encode64(byteArray);finish(audio)};audio.src=url;safeSetTimeout(()=>{finish(audio)},1e4)};preloadPlugins.push(audioPlugin);function pointerLockChange(){Browser.pointerLock=document["pointerLockElement"]===Module["canvas"]||document["mozPointerLockElement"]===Module["canvas"]||document["webkitPointerLockElement"]===Module["canvas"]||document["msPointerLockElement"]===Module["canvas"]}var canvas=Module["canvas"];if(canvas){canvas.requestPointerLock=canvas["requestPointerLock"]||canvas["mozRequestPointerLock"]||canvas["webkitRequestPointerLock"]||canvas["msRequestPointerLock"]||(()=>{});canvas.exitPointerLock=document["exitPointerLock"]||document["mozExitPointerLock"]||document["webkitExitPointerLock"]||document["msExitPointerLock"]||(()=>{});canvas.exitPointerLock=canvas.exitPointerLock.bind(document);document.addEventListener("pointerlockchange",pointerLockChange,false);document.addEventListener("mozpointerlockchange",pointerLockChange,false);document.addEventListener("webkitpointerlockchange",pointerLockChange,false);document.addEventListener("mspointerlockchange",pointerLockChange,false);if(Module["elementPointerLock"]){canvas.addEventListener("click",ev=>{if(!Browser.pointerLock&&Module["canvas"].requestPointerLock){Module["canvas"].requestPointerLock();ev.preventDefault()}},false)}}},createContext(canvas,useWebGL,setInModule,webGLContextAttributes){if(useWebGL&&Module.ctx&&canvas==Module.canvas)return Module.ctx;var ctx;var contextHandle;if(useWebGL){var contextAttributes={antialias:false,alpha:false,majorVersion:2};if(webGLContextAttributes){for(var attribute in webGLContextAttributes){contextAttributes[attribute]=webGLContextAttributes[attribute]}}if(typeof GL!="undefined"){contextHandle=GL.createContext(canvas,contextAttributes);if(contextHandle){ctx=GL.getContext(contextHandle).GLctx}}}else{ctx=canvas.getContext("2d")}if(!ctx)return null;if(setInModule){if(!useWebGL)assert(typeof GLctx=="undefined","cannot set in module if GLctx is used, but we are a non-GL context that would replace it");Module.ctx=ctx;if(useWebGL)GL.makeContextCurrent(contextHandle);Module.useWebGL=useWebGL;Browser.moduleContextCreatedCallbacks.forEach(callback=>callback());Browser.init()}return ctx},destroyContext(canvas,useWebGL,setInModule){},fullscreenHandlersInstalled:false,lockPointer:undefined,resizeCanvas:undefined,requestFullscreen(lockPointer,resizeCanvas){Browser.lockPointer=lockPointer;Browser.resizeCanvas=resizeCanvas;if(typeof Browser.lockPointer=="undefined")Browser.lockPointer=true;if(typeof Browser.resizeCanvas=="undefined")Browser.resizeCanvas=false;var canvas=Module["canvas"];function fullscreenChange(){Browser.isFullscreen=false;var canvasContainer=canvas.parentNode;if((document["fullscreenElement"]||document["mozFullScreenElement"]||document["msFullscreenElement"]||document["webkitFullscreenElement"]||document["webkitCurrentFullScreenElement"])===canvasContainer){canvas.exitFullscreen=Browser.exitFullscreen;if(Browser.lockPointer)canvas.requestPointerLock();Browser.isFullscreen=true;if(Browser.resizeCanvas){Browser.setFullscreenCanvasSize()}else{Browser.updateCanvasDimensions(canvas)}}else{canvasContainer.parentNode.insertBefore(canvas,canvasContainer);canvasContainer.parentNode.removeChild(canvasContainer);if(Browser.resizeCanvas){Browser.setWindowedCanvasSize()}else{Browser.updateCanvasDimensions(canvas)}}Module["onFullScreen"]?.(Browser.isFullscreen);Module["onFullscreen"]?.(Browser.isFullscreen)}if(!Browser.fullscreenHandlersInstalled){Browser.fullscreenHandlersInstalled=true;document.addEventListener("fullscreenchange",fullscreenChange,false);document.addEventListener("mozfullscreenchange",fullscreenChange,false);document.addEventListener("webkitfullscreenchange",fullscreenChange,false);document.addEventListener("MSFullscreenChange",fullscreenChange,false)}var canvasContainer=document.createElement("div");canvas.parentNode.insertBefore(canvasContainer,canvas);canvasContainer.appendChild(canvas);canvasContainer.requestFullscreen=canvasContainer["requestFullscreen"]||canvasContainer["mozRequestFullScreen"]||canvasContainer["msRequestFullscreen"]||(canvasContainer["webkitRequestFullscreen"]?()=>canvasContainer["webkitRequestFullscreen"](Element["ALLOW_KEYBOARD_INPUT"]):null)||(canvasContainer["webkitRequestFullScreen"]?()=>canvasContainer["webkitRequestFullScreen"](Element["ALLOW_KEYBOARD_INPUT"]):null);canvasContainer.requestFullscreen()},exitFullscreen(){if(!Browser.isFullscreen){return false}var CFS=document["exitFullscreen"]||document["cancelFullScreen"]||document["mozCancelFullScreen"]||document["msExitFullscreen"]||document["webkitCancelFullScreen"]||(()=>{});CFS.apply(document,[]);return true},nextRAF:0,fakeRequestAnimationFrame(func){var now=Date.now();if(Browser.nextRAF===0){Browser.nextRAF=now+1e3/60}else{while(now+2>=Browser.nextRAF){Browser.nextRAF+=1e3/60}}var delay=Math.max(Browser.nextRAF-now,0);setTimeout(func,delay)},requestAnimationFrame(func){if(typeof requestAnimationFrame=="function"){requestAnimationFrame(func);return}var RAF=Browser.fakeRequestAnimationFrame;RAF(func)},safeSetTimeout(func,timeout){return safeSetTimeout(func,timeout)},safeRequestAnimationFrame(func){return Browser.requestAnimationFrame(()=>{callUserCallback(func)})},getMimetype(name){return{"jpg":"image/jpeg","jpeg":"image/jpeg","png":"image/png","bmp":"image/bmp","ogg":"audio/ogg","wav":"audio/wav","mp3":"audio/mpeg"}[name.substr(name.lastIndexOf(".")+1)]},getUserMedia(func){window.getUserMedia||=navigator["getUserMedia"]||navigator["mozGetUserMedia"];window.getUserMedia(func)},getMovementX(event){return event["movementX"]||event["mozMovementX"]||event["webkitMovementX"]||0},getMovementY(event){return event["movementY"]||event["mozMovementY"]||event["webkitMovementY"]||0},getMouseWheelDelta(event){var delta=0;switch(event.type){case"DOMMouseScroll":delta=event.detail/3;break;case"mousewheel":delta=event.wheelDelta/120;break;case"wheel":delta=event.deltaY;switch(event.deltaMode){case 0:delta/=100;break;case 1:delta/=3;break;case 2:delta*=80;break;default:throw"unrecognized mouse wheel delta mode: "+event.deltaMode}break;default:throw"unrecognized mouse wheel event: "+event.type}return delta},mouseX:0,mouseY:0,mouseMovementX:0,mouseMovementY:0,touches:{},lastTouches:{},calculateMouseCoords(pageX,pageY){var rect=Module["canvas"].getBoundingClientRect();var cw=Module["canvas"].width;var ch=Module["canvas"].height;var scrollX=typeof window.scrollX!="undefined"?window.scrollX:window.pageXOffset;var scrollY=typeof window.scrollY!="undefined"?window.scrollY:window.pageYOffset;var adjustedX=pageX-(scrollX+rect.left);var adjustedY=pageY-(scrollY+rect.top);adjustedX=adjustedX*(cw/rect.width);adjustedY=adjustedY*(ch/rect.height);return{x:adjustedX,y:adjustedY}},setMouseCoords(pageX,pageY){const{x:x,y:y}=Browser.calculateMouseCoords(pageX,pageY);Browser.mouseMovementX=x-Browser.mouseX;Browser.mouseMovementY=y-Browser.mouseY;Browser.mouseX=x;Browser.mouseY=y},calculateMouseEvent(event){if(Browser.pointerLock){if(event.type!="mousemove"&&"mozMovementX"in event){Browser.mouseMovementX=Browser.mouseMovementY=0}else{Browser.mouseMovementX=Browser.getMovementX(event);Browser.mouseMovementY=Browser.getMovementY(event)}if(typeof SDL!="undefined"){Browser.mouseX=SDL.mouseX+Browser.mouseMovementX;Browser.mouseY=SDL.mouseY+Browser.mouseMovementY}else{Browser.mouseX+=Browser.mouseMovementX;Browser.mouseY+=Browser.mouseMovementY}}else{if(event.type==="touchstart"||event.type==="touchend"||event.type==="touchmove"){var touch=event.touch;if(touch===undefined){return}var coords=Browser.calculateMouseCoords(touch.pageX,touch.pageY);if(event.type==="touchstart"){Browser.lastTouches[touch.identifier]=coords;Browser.touches[touch.identifier]=coords}else if(event.type==="touchend"||event.type==="touchmove"){var last=Browser.touches[touch.identifier];last||=coords;Browser.lastTouches[touch.identifier]=last;Browser.touches[touch.identifier]=coords}return}Browser.setMouseCoords(event.pageX,event.pageY)}},resizeListeners:[],updateResizeListeners(){var canvas=Module["canvas"];Browser.resizeListeners.forEach(listener=>listener(canvas.width,canvas.height))},setCanvasSize(width,height,noUpdates){var canvas=Module["canvas"];Browser.updateCanvasDimensions(canvas,width,height);if(!noUpdates)Browser.updateResizeListeners()},windowedWidth:0,windowedHeight:0,setFullscreenCanvasSize(){if(typeof SDL!="undefined"){var flags=HEAPU32[SDL.screen>>>2>>>0];flags=flags|8388608;HEAP32[SDL.screen>>>2>>>0]=flags}Browser.updateCanvasDimensions(Module["canvas"]);Browser.updateResizeListeners()},setWindowedCanvasSize(){if(typeof SDL!="undefined"){var flags=HEAPU32[SDL.screen>>>2>>>0];flags=flags&~8388608;HEAP32[SDL.screen>>>2>>>0]=flags}Browser.updateCanvasDimensions(Module["canvas"]);Browser.updateResizeListeners()},updateCanvasDimensions(canvas,wNative,hNative){if(wNative&&hNative){canvas.widthNative=wNative;canvas.heightNative=hNative}else{wNative=canvas.widthNative;hNative=canvas.heightNative}var w=wNative;var h=hNative;if(Module["forcedAspectRatio"]&&Module["forcedAspectRatio"]>0){if(w/h>>2>>>0];if(param==12321){var alphaSize=HEAP32[attribList+4>>>2>>>0];EGL.contextAttributes.alpha=alphaSize>0}else if(param==12325){var depthSize=HEAP32[attribList+4>>>2>>>0];EGL.contextAttributes.depth=depthSize>0}else if(param==12326){var stencilSize=HEAP32[attribList+4>>>2>>>0];EGL.contextAttributes.stencil=stencilSize>0}else if(param==12337){var samples=HEAP32[attribList+4>>>2>>>0];EGL.contextAttributes.antialias=samples>0}else if(param==12338){var samples=HEAP32[attribList+4>>>2>>>0];EGL.contextAttributes.antialias=samples==1}else if(param==12544){var requestedPriority=HEAP32[attribList+4>>>2>>>0];EGL.contextAttributes.lowLatency=requestedPriority!=12547}else if(param==12344){break}attribList+=8}}if((!config||!config_size)&&!numConfigs){EGL.setErrorCode(12300);return 0}if(numConfigs){HEAP32[numConfigs>>>2>>>0]=1}if(config&&config_size>0){HEAPU32[config>>>2>>>0]=62002}EGL.setErrorCode(12288);return 1}};function _eglChooseConfig(display,attrib_list,configs,config_size,numConfigs){display>>>=0;attrib_list>>>=0;configs>>>=0;numConfigs>>>=0;return EGL.chooseConfig(display,attrib_list,configs,config_size,numConfigs)}var webgl_enable_WEBGL_draw_instanced_base_vertex_base_instance=ctx=>!!(ctx.dibvbi=ctx.getExtension("WEBGL_draw_instanced_base_vertex_base_instance"));var webgl_enable_WEBGL_multi_draw_instanced_base_vertex_base_instance=ctx=>!!(ctx.mdibvbi=ctx.getExtension("WEBGL_multi_draw_instanced_base_vertex_base_instance"));var webgl_enable_WEBGL_multi_draw=ctx=>!!(ctx.multiDrawWebgl=ctx.getExtension("WEBGL_multi_draw"));var getEmscriptenSupportedExtensions=ctx=>{var supportedExtensions=["EXT_color_buffer_float","EXT_conservative_depth","EXT_disjoint_timer_query_webgl2","EXT_texture_norm16","NV_shader_noperspective_interpolation","WEBGL_clip_cull_distance","EXT_color_buffer_half_float","EXT_depth_clamp","EXT_float_blend","EXT_texture_compression_bptc","EXT_texture_compression_rgtc","EXT_texture_filter_anisotropic","KHR_parallel_shader_compile","OES_texture_float_linear","WEBGL_blend_func_extended","WEBGL_compressed_texture_astc","WEBGL_compressed_texture_etc","WEBGL_compressed_texture_etc1","WEBGL_compressed_texture_s3tc","WEBGL_compressed_texture_s3tc_srgb","WEBGL_debug_renderer_info","WEBGL_debug_shaders","WEBGL_lose_context","WEBGL_multi_draw"];return(ctx.getSupportedExtensions()||[]).filter(ext=>supportedExtensions.includes(ext))};var GL={counter:1,buffers:[],programs:[],framebuffers:[],renderbuffers:[],textures:[],shaders:[],vaos:[],contexts:[],offscreenCanvases:{},queries:[],samplers:[],transformFeedbacks:[],syncs:[],stringCache:{},stringiCache:{},unpackAlignment:4,recordError:errorCode=>{if(!GL.lastError){GL.lastError=errorCode}},getNewId:table=>{var ret=GL.counter++;for(var i=table.length;i{for(var i=0;i>>2>>>0]=id}},getSource:(shader,count,string,length)=>{var source="";for(var i=0;i>>2>>>0]:undefined;source+=UTF8ToString(HEAPU32[string+i*4>>>2>>>0],len)}return source},createContext:(canvas,webGLContextAttributes)=>{if(!canvas.getContextSafariWebGL2Fixed){canvas.getContextSafariWebGL2Fixed=canvas.getContext;function fixedGetContext(ver,attrs){var gl=canvas.getContextSafariWebGL2Fixed(ver,attrs);return ver=="webgl"==gl instanceof WebGLRenderingContext?gl:null}canvas.getContext=fixedGetContext}var ctx=canvas.getContext("webgl2",webGLContextAttributes);if(!ctx)return 0;var handle=GL.registerContext(ctx,webGLContextAttributes);return handle},registerContext:(ctx,webGLContextAttributes)=>{var handle=GL.getNewId(GL.contexts);var context={handle:handle,attributes:webGLContextAttributes,version:webGLContextAttributes.majorVersion,GLctx:ctx};if(ctx.canvas)ctx.canvas.GLctxObject=context;GL.contexts[handle]=context;if(typeof webGLContextAttributes.enableExtensionsByDefault=="undefined"||webGLContextAttributes.enableExtensionsByDefault){GL.initExtensions(context)}return handle},makeContextCurrent:contextHandle=>{GL.currentContext=GL.contexts[contextHandle];Module.ctx=GLctx=GL.currentContext?.GLctx;return!(contextHandle&&!GLctx)},getContext:contextHandle=>GL.contexts[contextHandle],deleteContext:contextHandle=>{if(GL.currentContext===GL.contexts[contextHandle]){GL.currentContext=null}if(typeof JSEvents=="object"){JSEvents.removeAllHandlersOnTarget(GL.contexts[contextHandle].GLctx.canvas)}if(GL.contexts[contextHandle]&&GL.contexts[contextHandle].GLctx.canvas){GL.contexts[contextHandle].GLctx.canvas.GLctxObject=undefined}GL.contexts[contextHandle]=null},initExtensions:context=>{context||=GL.currentContext;if(context.initExtensionsDone)return;context.initExtensionsDone=true;var GLctx=context.GLctx;webgl_enable_WEBGL_draw_instanced_base_vertex_base_instance(GLctx);webgl_enable_WEBGL_multi_draw_instanced_base_vertex_base_instance(GLctx);if(context.version>=2){GLctx.disjointTimerQueryExt=GLctx.getExtension("EXT_disjoint_timer_query_webgl2")}if(context.version<2||!GLctx.disjointTimerQueryExt){GLctx.disjointTimerQueryExt=GLctx.getExtension("EXT_disjoint_timer_query")}webgl_enable_WEBGL_multi_draw(GLctx);getEmscriptenSupportedExtensions(GLctx).forEach(ext=>{if(!ext.includes("lose_context")&&!ext.includes("debug")){GLctx.getExtension(ext)}})}};function _eglCreateContext(display,config,hmm,contextAttribs){display>>>=0;config>>>=0;hmm>>>=0;contextAttribs>>>=0;if(display!=62e3){EGL.setErrorCode(12296);return 0}var glesContextVersion=1;for(;;){var param=HEAP32[contextAttribs>>>2>>>0];if(param==12440){glesContextVersion=HEAP32[contextAttribs+4>>>2>>>0]}else if(param==12344){break}else{EGL.setErrorCode(12292);return 0}contextAttribs+=8}if(glesContextVersion<2||glesContextVersion>3){EGL.setErrorCode(12293);return 0}EGL.contextAttributes.majorVersion=glesContextVersion-1;EGL.contextAttributes.minorVersion=0;EGL.context=GL.createContext(Module["canvas"],EGL.contextAttributes);if(EGL.context!=0){EGL.setErrorCode(12288);GL.makeContextCurrent(EGL.context);Module.useWebGL=true;Browser.moduleContextCreatedCallbacks.forEach(function(callback){callback()});GL.makeContextCurrent(null);return 62004}else{EGL.setErrorCode(12297);return 0}}function _eglCreateWindowSurface(display,config,win,attrib_list){display>>>=0;config>>>=0;attrib_list>>>=0;if(display!=62e3){EGL.setErrorCode(12296);return 0}if(config!=62002){EGL.setErrorCode(12293);return 0}EGL.setErrorCode(12288);return 62006}function _eglDestroyContext(display,context){display>>>=0;context>>>=0;if(display!=62e3){EGL.setErrorCode(12296);return 0}if(context!=62004){EGL.setErrorCode(12294);return 0}GL.deleteContext(EGL.context);EGL.setErrorCode(12288);if(EGL.currentContext==context){EGL.currentContext=0}return 1}function _eglDestroySurface(display,surface){display>>>=0;surface>>>=0;if(display!=62e3){EGL.setErrorCode(12296);return 0}if(surface!=62006){EGL.setErrorCode(12301);return 1}if(EGL.currentReadSurface==surface){EGL.currentReadSurface=0}if(EGL.currentDrawSurface==surface){EGL.currentDrawSurface=0}EGL.setErrorCode(12288);return 1}function _eglGetDisplay(nativeDisplayType){nativeDisplayType>>>=0;EGL.setErrorCode(12288);if(nativeDisplayType!=0&&nativeDisplayType!=1){return 0}return 62e3}function _eglInitialize(display,majorVersion,minorVersion){display>>>=0;majorVersion>>>=0;minorVersion>>>=0;if(display!=62e3){EGL.setErrorCode(12296);return 0}if(majorVersion){HEAP32[majorVersion>>>2>>>0]=1}if(minorVersion){HEAP32[minorVersion>>>2>>>0]=4}EGL.defaultDisplayInitialized=true;EGL.setErrorCode(12288);return 1}function _eglMakeCurrent(display,draw,read,context){display>>>=0;draw>>>=0;read>>>=0;context>>>=0;if(display!=62e3){EGL.setErrorCode(12296);return 0}if(context!=0&&context!=62004){EGL.setErrorCode(12294);return 0}if(read!=0&&read!=62006||draw!=0&&draw!=62006){EGL.setErrorCode(12301);return 0}GL.makeContextCurrent(context?EGL.context:null);EGL.currentContext=context;EGL.currentDrawSurface=draw;EGL.currentReadSurface=read;EGL.setErrorCode(12288);return 1}function _eglSwapBuffers(dpy,surface){dpy>>>=0;surface>>>=0;if(!EGL.defaultDisplayInitialized){EGL.setErrorCode(12289)}else if(!Module.ctx){EGL.setErrorCode(12290)}else if(Module.ctx.isContextLost()){EGL.setErrorCode(12302)}else{EGL.setErrorCode(12288);return 1}return 0}function _eglSwapInterval(display,interval){display>>>=0;if(display!=62e3){EGL.setErrorCode(12296);return 0}if(interval==0)_emscripten_set_main_loop_timing(0,0);else _emscripten_set_main_loop_timing(1,interval);EGL.setErrorCode(12288);return 1}function _eglTerminate(display){display>>>=0;if(display!=62e3){EGL.setErrorCode(12296);return 0}EGL.currentContext=0;EGL.currentReadSurface=0;EGL.currentDrawSurface=0;EGL.defaultDisplayInitialized=false;EGL.setErrorCode(12288);return 1}var readEmAsmArgsArray=[];var readEmAsmArgs=(sigPtr,buf)=>{readEmAsmArgsArray.length=0;var ch;while(ch=HEAPU8[sigPtr++>>>0]){var wide=ch!=105;wide&=ch!=112;buf+=wide&&buf%8?4:0;readEmAsmArgsArray.push(ch==112?HEAPU32[buf>>>2>>>0]:ch==105?HEAP32[buf>>>2>>>0]:HEAPF64[buf>>>3>>>0]);buf+=wide?8:4}return readEmAsmArgsArray};var runEmAsmFunction=(code,sigPtr,argbuf)=>{var args=readEmAsmArgs(sigPtr,argbuf);return ASM_CONSTS[code](...args)};function _emscripten_asm_const_int(code,sigPtr,argbuf){code>>>=0;sigPtr>>>=0;argbuf>>>=0;return runEmAsmFunction(code,sigPtr,argbuf)}var _emscripten_cancel_main_loop=()=>{Browser.mainLoop.pause();Browser.mainLoop.func=null};var _emscripten_date_now=()=>Date.now();function _emscripten_memcpy_js(dest,src,num){dest>>>=0;src>>>=0;num>>>=0;return HEAPU8.copyWithin(dest>>>0,src>>>0,src+num>>>0)}var getHeapMax=()=>4294901760;var growMemory=size=>{var b=wasmMemory.buffer;var pages=(size-b.byteLength+65535)/65536;try{wasmMemory.grow(pages);updateMemoryViews();return 1}catch(e){}};function _emscripten_resize_heap(requestedSize){requestedSize>>>=0;var oldSize=HEAPU8.length;var maxHeapSize=getHeapMax();if(requestedSize>maxHeapSize){return false}var alignUp=(x,multiple)=>x+(multiple-x%multiple)%multiple;for(var cutDown=1;cutDown<=4;cutDown*=2){var overGrownHeapSize=oldSize*(1+.2/cutDown);overGrownHeapSize=Math.min(overGrownHeapSize,requestedSize+100663296);var newSize=Math.min(maxHeapSize,alignUp(Math.max(requestedSize,overGrownHeapSize),65536));var replacement=growMemory(newSize);if(replacement){return true}}return false}var JSEvents={removeAllEventListeners(){while(JSEvents.eventHandlers.length){JSEvents._removeHandler(JSEvents.eventHandlers.length-1)}JSEvents.deferredCalls=[]},inEventHandler:0,deferredCalls:[],deferCall(targetFunction,precedence,argsList){function arraysHaveEqualContent(arrA,arrB){if(arrA.length!=arrB.length)return false;for(var i in arrA){if(arrA[i]!=arrB[i])return false}return true}for(var i in JSEvents.deferredCalls){var call=JSEvents.deferredCalls[i];if(call.targetFunction==targetFunction&&arraysHaveEqualContent(call.argsList,argsList)){return}}JSEvents.deferredCalls.push({targetFunction:targetFunction,precedence:precedence,argsList:argsList});JSEvents.deferredCalls.sort((x,y)=>x.precedence{for(var i=0;icString>2?UTF8ToString(cString):cString;var specialHTMLTargets=[0,typeof document!="undefined"?document:0,typeof window!="undefined"?window:0];var findEventTarget=target=>{target=maybeCStringToJsString(target);var domElement=specialHTMLTargets[target]||(typeof document!="undefined"?document.querySelector(target):undefined);return domElement};var stringToUTF8=(str,outPtr,maxBytesToWrite)=>stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite);var registerFocusEventCallback=(target,userData,useCapture,callbackfunc,eventTypeId,eventTypeString,targetThread)=>{if(!JSEvents.focusEvent)JSEvents.focusEvent=_malloc(256);var focusEventHandlerFunc=(e=event)=>{var nodeName=JSEvents.getNodeNameForTarget(e.target);var id=e.target.id?e.target.id:"";var focusEvent=JSEvents.focusEvent;stringToUTF8(nodeName,focusEvent+0,128);stringToUTF8(id,focusEvent+128,128);if(getWasmTableEntry(callbackfunc)(eventTypeId,focusEvent,userData))e.preventDefault()};var eventHandler={target:findEventTarget(target),eventTypeString:eventTypeString,callbackfunc:callbackfunc,handlerFunc:focusEventHandlerFunc,useCapture:useCapture};return JSEvents.registerOrRemoveHandler(eventHandler)};function _emscripten_set_blur_callback_on_thread(target,userData,useCapture,callbackfunc,targetThread){target>>>=0;userData>>>=0;callbackfunc>>>=0;targetThread>>>=0;return registerFocusEventCallback(target,userData,useCapture,callbackfunc,12,"blur",targetThread)}var findCanvasEventTarget=findEventTarget;function _emscripten_set_canvas_element_size(target,width,height){target>>>=0;var canvas=findCanvasEventTarget(target);if(!canvas)return-4;canvas.width=width;canvas.height=height;return 0}function _emscripten_set_focus_callback_on_thread(target,userData,useCapture,callbackfunc,targetThread){target>>>=0;userData>>>=0;callbackfunc>>>=0;targetThread>>>=0;return registerFocusEventCallback(target,userData,useCapture,callbackfunc,13,"focus",targetThread)}var registerKeyEventCallback=(target,userData,useCapture,callbackfunc,eventTypeId,eventTypeString,targetThread)=>{if(!JSEvents.keyEvent)JSEvents.keyEvent=_malloc(176);var keyEventHandlerFunc=e=>{var keyEventData=JSEvents.keyEvent;HEAPF64[keyEventData>>>3>>>0]=e.timeStamp;var idx=keyEventData>>>2;HEAP32[idx+2>>>0]=e.location;HEAP32[idx+3>>>0]=e.ctrlKey;HEAP32[idx+4>>>0]=e.shiftKey;HEAP32[idx+5>>>0]=e.altKey;HEAP32[idx+6>>>0]=e.metaKey;HEAP32[idx+7>>>0]=e.repeat;HEAP32[idx+8>>>0]=e.charCode;HEAP32[idx+9>>>0]=e.keyCode;HEAP32[idx+10>>>0]=e.which;stringToUTF8(e.key||"",keyEventData+44,32);stringToUTF8(e.code||"",keyEventData+76,32);stringToUTF8(e.char||"",keyEventData+108,32);stringToUTF8(e.locale||"",keyEventData+140,32);if(getWasmTableEntry(callbackfunc)(eventTypeId,keyEventData,userData))e.preventDefault()};var eventHandler={target:findEventTarget(target),eventTypeString:eventTypeString,callbackfunc:callbackfunc,handlerFunc:keyEventHandlerFunc,useCapture:useCapture};return JSEvents.registerOrRemoveHandler(eventHandler)};function _emscripten_set_keydown_callback_on_thread(target,userData,useCapture,callbackfunc,targetThread){target>>>=0;userData>>>=0;callbackfunc>>>=0;targetThread>>>=0;return registerKeyEventCallback(target,userData,useCapture,callbackfunc,2,"keydown",targetThread)}function _emscripten_set_keyup_callback_on_thread(target,userData,useCapture,callbackfunc,targetThread){target>>>=0;userData>>>=0;callbackfunc>>>=0;targetThread>>>=0;return registerKeyEventCallback(target,userData,useCapture,callbackfunc,3,"keyup",targetThread)}function _emscripten_set_main_loop(func,fps,simulateInfiniteLoop){func>>>=0;var browserIterationFunc=getWasmTableEntry(func);setMainLoop(browserIterationFunc,fps,simulateInfiniteLoop)}var getBoundingClientRect=e=>specialHTMLTargets.indexOf(e)<0?e.getBoundingClientRect():{"left":0,"top":0};var fillMouseEventData=(eventStruct,e,target)=>{HEAPF64[eventStruct>>>3>>>0]=e.timeStamp;var idx=eventStruct>>>2;HEAP32[idx+2>>>0]=e.screenX;HEAP32[idx+3>>>0]=e.screenY;HEAP32[idx+4>>>0]=e.clientX;HEAP32[idx+5>>>0]=e.clientY;HEAP32[idx+6>>>0]=e.ctrlKey;HEAP32[idx+7>>>0]=e.shiftKey;HEAP32[idx+8>>>0]=e.altKey;HEAP32[idx+9>>>0]=e.metaKey;HEAP16[idx*2+20>>>0]=e.button;HEAP16[idx*2+21>>>0]=e.buttons;HEAP32[idx+11>>>0]=e["movementX"];HEAP32[idx+12>>>0]=e["movementY"];var rect=getBoundingClientRect(target);HEAP32[idx+13>>>0]=e.clientX-rect.left;HEAP32[idx+14>>>0]=e.clientY-rect.top};var registerMouseEventCallback=(target,userData,useCapture,callbackfunc,eventTypeId,eventTypeString,targetThread)=>{if(!JSEvents.mouseEvent)JSEvents.mouseEvent=_malloc(72);target=findEventTarget(target);var mouseEventHandlerFunc=(e=event)=>{fillMouseEventData(JSEvents.mouseEvent,e,target);if(getWasmTableEntry(callbackfunc)(eventTypeId,JSEvents.mouseEvent,userData))e.preventDefault()};var eventHandler={target:target,allowsDeferredCalls:eventTypeString!="mousemove"&&eventTypeString!="mouseenter"&&eventTypeString!="mouseleave",eventTypeString:eventTypeString,callbackfunc:callbackfunc,handlerFunc:mouseEventHandlerFunc,useCapture:useCapture};return JSEvents.registerOrRemoveHandler(eventHandler)};function _emscripten_set_mousedown_callback_on_thread(target,userData,useCapture,callbackfunc,targetThread){target>>>=0;userData>>>=0;callbackfunc>>>=0;targetThread>>>=0;return registerMouseEventCallback(target,userData,useCapture,callbackfunc,5,"mousedown",targetThread)}function _emscripten_set_mousemove_callback_on_thread(target,userData,useCapture,callbackfunc,targetThread){target>>>=0;userData>>>=0;callbackfunc>>>=0;targetThread>>>=0;return registerMouseEventCallback(target,userData,useCapture,callbackfunc,8,"mousemove",targetThread)}function _emscripten_set_mouseup_callback_on_thread(target,userData,useCapture,callbackfunc,targetThread){target>>>=0;userData>>>=0;callbackfunc>>>=0;targetThread>>>=0;return registerMouseEventCallback(target,userData,useCapture,callbackfunc,6,"mouseup",targetThread)}var registerTouchEventCallback=(target,userData,useCapture,callbackfunc,eventTypeId,eventTypeString,targetThread)=>{if(!JSEvents.touchEvent)JSEvents.touchEvent=_malloc(1696);target=findEventTarget(target);var touchEventHandlerFunc=e=>{var t,touches={},et=e.touches;for(var i=0;i>>3>>>0]=e.timeStamp;var idx=touchEvent>>>2;HEAP32[idx+3>>>0]=e.ctrlKey;HEAP32[idx+4>>>0]=e.shiftKey;HEAP32[idx+5>>>0]=e.altKey;HEAP32[idx+6>>>0]=e.metaKey;idx+=7;var targetRect=getBoundingClientRect(target);var numTouches=0;for(var i in touches){t=touches[i];HEAP32[idx+0>>>0]=t.identifier;HEAP32[idx+1>>>0]=t.screenX;HEAP32[idx+2>>>0]=t.screenY;HEAP32[idx+3>>>0]=t.clientX;HEAP32[idx+4>>>0]=t.clientY;HEAP32[idx+5>>>0]=t.pageX;HEAP32[idx+6>>>0]=t.pageY;HEAP32[idx+7>>>0]=t.isChanged;HEAP32[idx+8>>>0]=t.onTarget;HEAP32[idx+9>>>0]=t.clientX-targetRect.left;HEAP32[idx+10>>>0]=t.clientY-targetRect.top;idx+=13;if(++numTouches>31){break}}HEAP32[touchEvent+8>>>2>>>0]=numTouches;if(getWasmTableEntry(callbackfunc)(eventTypeId,touchEvent,userData))e.preventDefault()};var eventHandler={target:target,allowsDeferredCalls:eventTypeString=="touchstart"||eventTypeString=="touchend",eventTypeString:eventTypeString,callbackfunc:callbackfunc,handlerFunc:touchEventHandlerFunc,useCapture:useCapture};return JSEvents.registerOrRemoveHandler(eventHandler)};function _emscripten_set_touchend_callback_on_thread(target,userData,useCapture,callbackfunc,targetThread){target>>>=0;userData>>>=0;callbackfunc>>>=0;targetThread>>>=0;return registerTouchEventCallback(target,userData,useCapture,callbackfunc,23,"touchend",targetThread)}function _emscripten_set_touchmove_callback_on_thread(target,userData,useCapture,callbackfunc,targetThread){target>>>=0;userData>>>=0;callbackfunc>>>=0;targetThread>>>=0;return registerTouchEventCallback(target,userData,useCapture,callbackfunc,24,"touchmove",targetThread)}function _emscripten_set_touchstart_callback_on_thread(target,userData,useCapture,callbackfunc,targetThread){target>>>=0;userData>>>=0;callbackfunc>>>=0;targetThread>>>=0;return registerTouchEventCallback(target,userData,useCapture,callbackfunc,22,"touchstart",targetThread)}var registerWheelEventCallback=(target,userData,useCapture,callbackfunc,eventTypeId,eventTypeString,targetThread)=>{if(!JSEvents.wheelEvent)JSEvents.wheelEvent=_malloc(104);var wheelHandlerFunc=(e=event)=>{var wheelEvent=JSEvents.wheelEvent;fillMouseEventData(wheelEvent,e,target);HEAPF64[wheelEvent+72>>>3>>>0]=e["deltaX"];HEAPF64[wheelEvent+80>>>3>>>0]=e["deltaY"];HEAPF64[wheelEvent+88>>>3>>>0]=e["deltaZ"];HEAP32[wheelEvent+96>>>2>>>0]=e["deltaMode"];if(getWasmTableEntry(callbackfunc)(eventTypeId,wheelEvent,userData))e.preventDefault()};var eventHandler={target:target,allowsDeferredCalls:true,eventTypeString:eventTypeString,callbackfunc:callbackfunc,handlerFunc:wheelHandlerFunc,useCapture:useCapture};return JSEvents.registerOrRemoveHandler(eventHandler)};function _emscripten_set_wheel_callback_on_thread(target,userData,useCapture,callbackfunc,targetThread){target>>>=0;userData>>>=0;callbackfunc>>>=0;targetThread>>>=0;target=findEventTarget(target);if(!target)return-4;if(typeof target.onwheel!="undefined"){return registerWheelEventCallback(target,userData,useCapture,callbackfunc,9,"wheel",targetThread)}else{return-1}}function _emscripten_set_window_title(title){title>>>=0;return document.title=UTF8ToString(title)}var ENV={};var getExecutableName=()=>thisProgram||"./this.program";var getEnvStrings=()=>{if(!getEnvStrings.strings){var lang=(typeof navigator=="object"&&navigator.languages&&navigator.languages[0]||"C").replace("-","_")+".UTF-8";var env={"USER":"web_user","LOGNAME":"web_user","PATH":"/","PWD":"/","HOME":"/home/web_user","LANG":lang,"_":getExecutableName()};for(var x in ENV){if(ENV[x]===undefined)delete env[x];else env[x]=ENV[x]}var strings=[];for(var x in env){strings.push(`${x}=${env[x]}`)}getEnvStrings.strings=strings}return getEnvStrings.strings};var stringToAscii=(str,buffer)=>{for(var i=0;i>>0]=str.charCodeAt(i)}HEAP8[buffer>>>0]=0};var _environ_get=function(__environ,environ_buf){__environ>>>=0;environ_buf>>>=0;var bufSize=0;getEnvStrings().forEach((string,i)=>{var ptr=environ_buf+bufSize;HEAPU32[__environ+i*4>>>2>>>0]=ptr;stringToAscii(string,ptr);bufSize+=string.length+1});return 0};var _environ_sizes_get=function(penviron_count,penviron_buf_size){penviron_count>>>=0;penviron_buf_size>>>=0;var strings=getEnvStrings();HEAPU32[penviron_count>>>2>>>0]=strings.length;var bufSize=0;strings.forEach(string=>bufSize+=string.length+1);HEAPU32[penviron_buf_size>>>2>>>0]=bufSize;return 0};function _fd_close(fd){try{var stream=SYSCALLS.getStreamFromFD(fd);FS.close(stream);return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}var doReadv=(stream,iov,iovcnt,offset)=>{var ret=0;for(var i=0;i>>2>>>0];var len=HEAPU32[iov+4>>>2>>>0];iov+=8;var curr=FS.read(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr;if(curr>>=0;iovcnt>>>=0;pnum>>>=0;try{var stream=SYSCALLS.getStreamFromFD(fd);var num=doReadv(stream,iov,iovcnt);HEAPU32[pnum>>>2>>>0]=num;return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}function _fd_seek(fd,offset_low,offset_high,whence,newOffset){var offset=convertI32PairToI53Checked(offset_low,offset_high);newOffset>>>=0;try{if(isNaN(offset))return 61;var stream=SYSCALLS.getStreamFromFD(fd);FS.llseek(stream,offset,whence);tempI64=[stream.position>>>0,(tempDouble=stream.position,+Math.abs(tempDouble)>=1?tempDouble>0?+Math.floor(tempDouble/4294967296)>>>0:~~+Math.ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[newOffset>>>2>>>0]=tempI64[0],HEAP32[newOffset+4>>>2>>>0]=tempI64[1];if(stream.getdents&&offset===0&&whence===0)stream.getdents=null;return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}var doWritev=(stream,iov,iovcnt,offset)=>{var ret=0;for(var i=0;i>>2>>>0];var len=HEAPU32[iov+4>>>2>>>0];iov+=8;var curr=FS.write(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr;if(typeof offset!=="undefined"){offset+=curr}}return ret};function _fd_write(fd,iov,iovcnt,pnum){iov>>>=0;iovcnt>>>=0;pnum>>>=0;try{var stream=SYSCALLS.getStreamFromFD(fd);var num=doWritev(stream,iov,iovcnt);HEAPU32[pnum>>>2>>>0]=num;return 0}catch(e){if(typeof FS=="undefined"||!(e.name==="ErrnoError"))throw e;return e.errno}}var _glAttachShader=(program,shader)=>{GLctx.attachShader(GL.programs[program],GL.shaders[shader])};var _glBindBuffer=(target,buffer)=>{if(target==35051){GLctx.currentPixelPackBufferBinding=buffer}else if(target==35052){GLctx.currentPixelUnpackBufferBinding=buffer}GLctx.bindBuffer(target,GL.buffers[buffer])};var _glBindTexture=(target,texture)=>{GLctx.bindTexture(target,GL.textures[texture])};var _glBindVertexArray=vao=>{GLctx.bindVertexArray(GL.vaos[vao])};var _glBindVertexArrayOES=_glBindVertexArray;var _glBlendFunc=(x0,x1)=>GLctx.blendFunc(x0,x1);function _glBufferData(target,size,data,usage){size>>>=0;data>>>=0;if(true){if(data&&size){GLctx.bufferData(target,HEAPU8,usage,data,size)}else{GLctx.bufferData(target,size,usage)}}else{GLctx.bufferData(target,data?HEAPU8.subarray(data>>>0,data+size>>>0):size,usage)}}var _glClear=x0=>GLctx.clear(x0);var _glClearColor=(x0,x1,x2,x3)=>GLctx.clearColor(x0,x1,x2,x3);var _glCompileShader=shader=>{GLctx.compileShader(GL.shaders[shader])};var _glCreateProgram=()=>{var id=GL.getNewId(GL.programs);var program=GLctx.createProgram();program.name=id;program.maxUniformLength=program.maxAttributeLength=program.maxUniformBlockNameLength=0;program.uniformIdCounter=1;GL.programs[id]=program;return id};var _glCreateShader=shaderType=>{var id=GL.getNewId(GL.shaders);GL.shaders[id]=GLctx.createShader(shaderType);return id};var _glDeleteProgram=id=>{if(!id)return;var program=GL.programs[id];if(!program){GL.recordError(1281);return}GLctx.deleteProgram(program);program.name=0;GL.programs[id]=null};var _glDeleteShader=id=>{if(!id)return;var shader=GL.shaders[id];if(!shader){GL.recordError(1281);return}GLctx.deleteShader(shader);GL.shaders[id]=null};function _glDeleteTextures(n,textures){textures>>>=0;for(var i=0;i>>2>>>0];var texture=GL.textures[id];if(!texture)continue;GLctx.deleteTexture(texture);texture.name=0;GL.textures[id]=null}}var _glDrawArrays=(mode,first,count)=>{GLctx.drawArrays(mode,first,count)};var _glEnable=x0=>GLctx.enable(x0);var _glEnableVertexAttribArray=index=>{GLctx.enableVertexAttribArray(index)};function _glGenBuffers(n,buffers){buffers>>>=0;GL.genObject(n,buffers,"createBuffer",GL.buffers)}function _glGenTextures(n,textures){textures>>>=0;GL.genObject(n,textures,"createTexture",GL.textures)}function _glGenVertexArrays(n,arrays){arrays>>>=0;GL.genObject(n,arrays,"createVertexArray",GL.vaos)}var _glGenVertexArraysOES=_glGenVertexArrays;function _glGetShaderInfoLog(shader,maxLength,length,infoLog){length>>>=0;infoLog>>>=0;var log=GLctx.getShaderInfoLog(GL.shaders[shader]);if(log===null)log="(unknown error)";var numBytesWrittenExclNull=maxLength>0&&infoLog?stringToUTF8(log,infoLog,maxLength):0;if(length)HEAP32[length>>>2>>>0]=numBytesWrittenExclNull}var jstoi_q=str=>parseInt(str);var webglGetLeftBracePos=name=>name.slice(-1)=="]"&&name.lastIndexOf("[");var webglPrepareUniformLocationsBeforeFirstUse=program=>{var uniformLocsById=program.uniformLocsById,uniformSizeAndIdsByName=program.uniformSizeAndIdsByName,i,j;if(!uniformLocsById){program.uniformLocsById=uniformLocsById={};program.uniformArrayNamesById={};for(i=0;i0?nm.slice(0,lb):nm;var id=program.uniformIdCounter;program.uniformIdCounter+=sz;uniformSizeAndIdsByName[arrayName]=[sz,id];for(j=0;j>>=0;name=UTF8ToString(name);if(program=GL.programs[program]){webglPrepareUniformLocationsBeforeFirstUse(program);var uniformLocsById=program.uniformLocsById;var arrayIndex=0;var uniformBaseName=name;var leftBrace=webglGetLeftBracePos(name);if(leftBrace>0){arrayIndex=jstoi_q(name.slice(leftBrace+1))>>>0;uniformBaseName=name.slice(0,leftBrace)}var sizeAndId=program.uniformSizeAndIdsByName[uniformBaseName];if(sizeAndId&&arrayIndex{program=GL.programs[program];GLctx.linkProgram(program);program.uniformLocsById=0;program.uniformSizeAndIdsByName={}};var computeUnpackAlignedImageSize=(width,height,sizePerPixel,alignment)=>{function roundedToNextMultipleOf(x,y){return x+y-1&-y}var plainRowSize=width*sizePerPixel;var alignedRowSize=roundedToNextMultipleOf(plainRowSize,alignment);return height*alignedRowSize};var colorChannelsInGlTextureFormat=format=>{var colorChannels={5:3,6:4,8:2,29502:3,29504:4,26917:2,26918:2,29846:3,29847:4};return colorChannels[format-6402]||1};var heapObjectForWebGLType=type=>{type-=5120;if(type==0)return HEAP8;if(type==1)return HEAPU8;if(type==2)return HEAP16;if(type==4)return HEAP32;if(type==6)return HEAPF32;if(type==5||type==28922||type==28520||type==30779||type==30782)return HEAPU32;return HEAPU16};var toTypedArrayIndex=(pointer,heap)=>pointer>>>31-Math.clz32(heap.BYTES_PER_ELEMENT);var emscriptenWebGLGetTexPixelData=(type,format,width,height,pixels,internalFormat)=>{var heap=heapObjectForWebGLType(type);var sizePerPixel=colorChannelsInGlTextureFormat(format)*heap.BYTES_PER_ELEMENT;var bytes=computeUnpackAlignedImageSize(width,height,sizePerPixel,GL.unpackAlignment);return heap.subarray(toTypedArrayIndex(pixels,heap)>>>0,toTypedArrayIndex(pixels+bytes,heap)>>>0)};function _glReadPixels(x,y,width,height,format,type,pixels){pixels>>>=0;if(true){if(GLctx.currentPixelPackBufferBinding){GLctx.readPixels(x,y,width,height,format,type,pixels)}else{var heap=heapObjectForWebGLType(type);var target=toTypedArrayIndex(pixels,heap);GLctx.readPixels(x,y,width,height,format,type,heap,target)}return}var pixelData=emscriptenWebGLGetTexPixelData(type,format,width,height,pixels,format);if(!pixelData){GL.recordError(1280);return}GLctx.readPixels(x,y,width,height,format,type,pixelData)}function _glShaderSource(shader,count,string,length){string>>>=0;length>>>=0;var source=GL.getSource(shader,count,string,length);GLctx.shaderSource(GL.shaders[shader],source)}function _glTexImage2D(target,level,internalFormat,width,height,border,format,type,pixels){pixels>>>=0;if(true){if(GLctx.currentPixelUnpackBufferBinding){GLctx.texImage2D(target,level,internalFormat,width,height,border,format,type,pixels)}else if(pixels){var heap=heapObjectForWebGLType(type);GLctx.texImage2D(target,level,internalFormat,width,height,border,format,type,heap,toTypedArrayIndex(pixels,heap))}else{GLctx.texImage2D(target,level,internalFormat,width,height,border,format,type,null)}return}GLctx.texImage2D(target,level,internalFormat,width,height,border,format,type,pixels?emscriptenWebGLGetTexPixelData(type,format,width,height,pixels,internalFormat):null)}var _glTexParameteri=(x0,x1,x2)=>GLctx.texParameteri(x0,x1,x2);var webglGetUniformLocation=location=>{var p=GLctx.currentProgram;if(p){var webglLoc=p.uniformLocsById[location];if(typeof webglLoc=="number"){p.uniformLocsById[location]=webglLoc=GLctx.getUniformLocation(p,p.uniformArrayNamesById[location]+(webglLoc>0?`[${webglLoc}]`:""))}return webglLoc}else{GL.recordError(1282)}};var _glUniform1f=(location,v0)=>{GLctx.uniform1f(webglGetUniformLocation(location),v0)};var _glUseProgram=program=>{program=GL.programs[program];GLctx.useProgram(program);GLctx.currentProgram=program};function _glVertexAttribPointer(index,size,type,normalized,stride,ptr){ptr>>>=0;GLctx.vertexAttribPointer(index,size,type,!!normalized,stride,ptr)}var _glViewport=(x0,x1,x2,x3)=>GLctx.viewport(x0,x1,x2,x3);var isLeapYear=year=>year%4===0&&(year%100!==0||year%400===0);var arraySum=(array,index)=>{var sum=0;for(var i=0;i<=index;sum+=array[i++]){}return sum};var MONTH_DAYS_LEAP=[31,29,31,30,31,30,31,31,30,31,30,31];var MONTH_DAYS_REGULAR=[31,28,31,30,31,30,31,31,30,31,30,31];var addDays=(date,days)=>{var newDate=new Date(date.getTime());while(days>0){var leap=isLeapYear(newDate.getFullYear());var currentMonth=newDate.getMonth();var daysInCurrentMonth=(leap?MONTH_DAYS_LEAP:MONTH_DAYS_REGULAR)[currentMonth];if(days>daysInCurrentMonth-newDate.getDate()){days-=daysInCurrentMonth-newDate.getDate()+1;newDate.setDate(1);if(currentMonth<11){newDate.setMonth(currentMonth+1)}else{newDate.setMonth(0);newDate.setFullYear(newDate.getFullYear()+1)}}else{newDate.setDate(newDate.getDate()+days);return newDate}}return newDate};var writeArrayToMemory=(array,buffer)=>{HEAP8.set(array,buffer>>>0)};function _strftime(s,maxsize,format,tm){s>>>=0;maxsize>>>=0;format>>>=0;tm>>>=0;var tm_zone=HEAPU32[tm+40>>>2>>>0];var date={tm_sec:HEAP32[tm>>>2>>>0],tm_min:HEAP32[tm+4>>>2>>>0],tm_hour:HEAP32[tm+8>>>2>>>0],tm_mday:HEAP32[tm+12>>>2>>>0],tm_mon:HEAP32[tm+16>>>2>>>0],tm_year:HEAP32[tm+20>>>2>>>0],tm_wday:HEAP32[tm+24>>>2>>>0],tm_yday:HEAP32[tm+28>>>2>>>0],tm_isdst:HEAP32[tm+32>>>2>>>0],tm_gmtoff:HEAP32[tm+36>>>2>>>0],tm_zone:tm_zone?UTF8ToString(tm_zone):""};var pattern=UTF8ToString(format);var EXPANSION_RULES_1={"%c":"%a %b %d %H:%M:%S %Y","%D":"%m/%d/%y","%F":"%Y-%m-%d","%h":"%b","%r":"%I:%M:%S %p","%R":"%H:%M","%T":"%H:%M:%S","%x":"%m/%d/%y","%X":"%H:%M:%S","%Ec":"%c","%EC":"%C","%Ex":"%m/%d/%y","%EX":"%H:%M:%S","%Ey":"%y","%EY":"%Y","%Od":"%d","%Oe":"%e","%OH":"%H","%OI":"%I","%Om":"%m","%OM":"%M","%OS":"%S","%Ou":"%u","%OU":"%U","%OV":"%V","%Ow":"%w","%OW":"%W","%Oy":"%y"};for(var rule in EXPANSION_RULES_1){pattern=pattern.replace(new RegExp(rule,"g"),EXPANSION_RULES_1[rule])}var WEEKDAYS=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];var MONTHS=["January","February","March","April","May","June","July","August","September","October","November","December"];function leadingSomething(value,digits,character){var str=typeof value=="number"?value.toString():value||"";while(str.length0?1:0}var compare;if((compare=sgn(date1.getFullYear()-date2.getFullYear()))===0){if((compare=sgn(date1.getMonth()-date2.getMonth()))===0){compare=sgn(date1.getDate()-date2.getDate())}}return compare}function getFirstWeekStartDate(janFourth){switch(janFourth.getDay()){case 0:return new Date(janFourth.getFullYear()-1,11,29);case 1:return janFourth;case 2:return new Date(janFourth.getFullYear(),0,3);case 3:return new Date(janFourth.getFullYear(),0,2);case 4:return new Date(janFourth.getFullYear(),0,1);case 5:return new Date(janFourth.getFullYear()-1,11,31);case 6:return new Date(janFourth.getFullYear()-1,11,30)}}function getWeekBasedYear(date){var thisDate=addDays(new Date(date.tm_year+1900,0,1),date.tm_yday);var janFourthThisYear=new Date(thisDate.getFullYear(),0,4);var janFourthNextYear=new Date(thisDate.getFullYear()+1,0,4);var firstWeekStartThisYear=getFirstWeekStartDate(janFourthThisYear);var firstWeekStartNextYear=getFirstWeekStartDate(janFourthNextYear);if(compareByDay(firstWeekStartThisYear,thisDate)<=0){if(compareByDay(firstWeekStartNextYear,thisDate)<=0){return thisDate.getFullYear()+1}return thisDate.getFullYear()}return thisDate.getFullYear()-1}var EXPANSION_RULES_2={"%a":date=>WEEKDAYS[date.tm_wday].substring(0,3),"%A":date=>WEEKDAYS[date.tm_wday],"%b":date=>MONTHS[date.tm_mon].substring(0,3),"%B":date=>MONTHS[date.tm_mon],"%C":date=>{var year=date.tm_year+1900;return leadingNulls(year/100|0,2)},"%d":date=>leadingNulls(date.tm_mday,2),"%e":date=>leadingSomething(date.tm_mday,2," "),"%g":date=>getWeekBasedYear(date).toString().substring(2),"%G":getWeekBasedYear,"%H":date=>leadingNulls(date.tm_hour,2),"%I":date=>{var twelveHour=date.tm_hour;if(twelveHour==0)twelveHour=12;else if(twelveHour>12)twelveHour-=12;return leadingNulls(twelveHour,2)},"%j":date=>leadingNulls(date.tm_mday+arraySum(isLeapYear(date.tm_year+1900)?MONTH_DAYS_LEAP:MONTH_DAYS_REGULAR,date.tm_mon-1),3),"%m":date=>leadingNulls(date.tm_mon+1,2),"%M":date=>leadingNulls(date.tm_min,2),"%n":()=>"\n","%p":date=>{if(date.tm_hour>=0&&date.tm_hour<12){return"AM"}return"PM"},"%S":date=>leadingNulls(date.tm_sec,2),"%t":()=>"\t","%u":date=>date.tm_wday||7,"%U":date=>{var days=date.tm_yday+7-date.tm_wday;return leadingNulls(Math.floor(days/7),2)},"%V":date=>{var val=Math.floor((date.tm_yday+7-(date.tm_wday+6)%7)/7);if((date.tm_wday+371-date.tm_yday-2)%7<=2){val++}if(!val){val=52;var dec31=(date.tm_wday+7-date.tm_yday-1)%7;if(dec31==4||dec31==5&&isLeapYear(date.tm_year%400-1)){val++}}else if(val==53){var jan1=(date.tm_wday+371-date.tm_yday)%7;if(jan1!=4&&(jan1!=3||!isLeapYear(date.tm_year)))val=1}return leadingNulls(val,2)},"%w":date=>date.tm_wday,"%W":date=>{var days=date.tm_yday+7-(date.tm_wday+6)%7;return leadingNulls(Math.floor(days/7),2)},"%y":date=>(date.tm_year+1900).toString().substring(2),"%Y":date=>date.tm_year+1900,"%z":date=>{var off=date.tm_gmtoff;var ahead=off>=0;off=Math.abs(off)/60;off=off/60*100+off%60;return(ahead?"+":"-")+String("0000"+off).slice(-4)},"%Z":date=>date.tm_zone,"%%":()=>"%"};pattern=pattern.replace(/%%/g,"\0\0");for(var rule in EXPANSION_RULES_2){if(pattern.includes(rule)){pattern=pattern.replace(new RegExp(rule,"g"),EXPANSION_RULES_2[rule](date))}}pattern=pattern.replace(/\0\0/g,"%");var bytes=intArrayFromString(pattern,false);if(bytes.length>maxsize){return 0}writeArrayToMemory(bytes,s);return bytes.length-1}function _strftime_l(s,maxsize,format,tm,loc){s>>>=0;maxsize>>>=0;format>>>=0;tm>>>=0;loc>>>=0;return _strftime(s,maxsize,format,tm)}var FSNode=function(parent,name,mode,rdev){if(!parent){parent=this}this.parent=parent;this.mount=parent.mount;this.mounted=null;this.id=FS.nextInode++;this.name=name;this.mode=mode;this.node_ops={};this.stream_ops={};this.rdev=rdev};var readMode=292|73;var writeMode=146;Object.defineProperties(FSNode.prototype,{read:{get:function(){return(this.mode&readMode)===readMode},set:function(val){val?this.mode|=readMode:this.mode&=~readMode}},write:{get:function(){return(this.mode&writeMode)===writeMode},set:function(val){val?this.mode|=writeMode:this.mode&=~writeMode}},isFolder:{get:function(){return FS.isDir(this.mode)}},isDevice:{get:function(){return FS.isChrdev(this.mode)}}});FS.FSNode=FSNode;FS.createPreloadedFile=FS_createPreloadedFile;FS.staticInit();Module["FS_createPath"]=FS.createPath;Module["FS_createDataFile"]=FS.createDataFile;Module["FS_createPreloadedFile"]=FS.createPreloadedFile;Module["FS_unlink"]=FS.unlink;Module["FS_createLazyFile"]=FS.createLazyFile;Module["FS_createDevice"]=FS.createDevice;Module["requestFullscreen"]=Browser.requestFullscreen;Module["requestAnimationFrame"]=Browser.requestAnimationFrame;Module["setCanvasSize"]=Browser.setCanvasSize;Module["pauseMainLoop"]=Browser.mainLoop.pause;Module["resumeMainLoop"]=Browser.mainLoop.resume;Module["getUserMedia"]=Browser.getUserMedia;Module["createContext"]=Browser.createContext;var preloadedImages={};var preloadedAudios={};var GLctx;var wasmImports={__cxa_throw:___cxa_throw,__syscall_fcntl64:___syscall_fcntl64,__syscall_ioctl:___syscall_ioctl,__syscall_openat:___syscall_openat,_emscripten_get_now_is_monotonic:__emscripten_get_now_is_monotonic,_emscripten_throw_longjmp:__emscripten_throw_longjmp,abort:_abort,eglChooseConfig:_eglChooseConfig,eglCreateContext:_eglCreateContext,eglCreateWindowSurface:_eglCreateWindowSurface,eglDestroyContext:_eglDestroyContext,eglDestroySurface:_eglDestroySurface,eglGetDisplay:_eglGetDisplay,eglInitialize:_eglInitialize,eglMakeCurrent:_eglMakeCurrent,eglSwapBuffers:_eglSwapBuffers,eglSwapInterval:_eglSwapInterval,eglTerminate:_eglTerminate,emscripten_asm_const_int:_emscripten_asm_const_int,emscripten_cancel_main_loop:_emscripten_cancel_main_loop,emscripten_date_now:_emscripten_date_now,emscripten_get_now:_emscripten_get_now,emscripten_memcpy_js:_emscripten_memcpy_js,emscripten_resize_heap:_emscripten_resize_heap,emscripten_set_blur_callback_on_thread:_emscripten_set_blur_callback_on_thread,emscripten_set_canvas_element_size:_emscripten_set_canvas_element_size,emscripten_set_focus_callback_on_thread:_emscripten_set_focus_callback_on_thread,emscripten_set_keydown_callback_on_thread:_emscripten_set_keydown_callback_on_thread,emscripten_set_keyup_callback_on_thread:_emscripten_set_keyup_callback_on_thread,emscripten_set_main_loop:_emscripten_set_main_loop,emscripten_set_mousedown_callback_on_thread:_emscripten_set_mousedown_callback_on_thread,emscripten_set_mousemove_callback_on_thread:_emscripten_set_mousemove_callback_on_thread,emscripten_set_mouseup_callback_on_thread:_emscripten_set_mouseup_callback_on_thread,emscripten_set_touchend_callback_on_thread:_emscripten_set_touchend_callback_on_thread,emscripten_set_touchmove_callback_on_thread:_emscripten_set_touchmove_callback_on_thread,emscripten_set_touchstart_callback_on_thread:_emscripten_set_touchstart_callback_on_thread,emscripten_set_wheel_callback_on_thread:_emscripten_set_wheel_callback_on_thread,emscripten_set_window_title:_emscripten_set_window_title,environ_get:_environ_get,environ_sizes_get:_environ_sizes_get,fd_close:_fd_close,fd_read:_fd_read,fd_seek:_fd_seek,fd_write:_fd_write,glAttachShader:_glAttachShader,glBindBuffer:_glBindBuffer,glBindTexture:_glBindTexture,glBindVertexArrayOES:_glBindVertexArrayOES,glBlendFunc:_glBlendFunc,glBufferData:_glBufferData,glClear:_glClear,glClearColor:_glClearColor,glCompileShader:_glCompileShader,glCreateProgram:_glCreateProgram,glCreateShader:_glCreateShader,glDeleteProgram:_glDeleteProgram,glDeleteShader:_glDeleteShader,glDeleteTextures:_glDeleteTextures,glDrawArrays:_glDrawArrays,glEnable:_glEnable,glEnableVertexAttribArray:_glEnableVertexAttribArray,glGenBuffers:_glGenBuffers,glGenTextures:_glGenTextures,glGenVertexArraysOES:_glGenVertexArraysOES,glGetShaderInfoLog:_glGetShaderInfoLog,glGetUniformLocation:_glGetUniformLocation,glLinkProgram:_glLinkProgram,glReadPixels:_glReadPixels,glShaderSource:_glShaderSource,glTexImage2D:_glTexImage2D,glTexParameteri:_glTexParameteri,glUniform1f:_glUniform1f,glUseProgram:_glUseProgram,glVertexAttribPointer:_glVertexAttribPointer,glViewport:_glViewport,invoke_ii:invoke_ii,invoke_iii:invoke_iii,invoke_iiii:invoke_iiii,invoke_iiiii:invoke_iiiii,invoke_vi:invoke_vi,invoke_vii:invoke_vii,invoke_viii:invoke_viii,invoke_viiii:invoke_viiii,invoke_viiiiii:invoke_viiiiii,strftime_l:_strftime_l};var wasmExports=createWasm();var ___wasm_call_ctors=()=>(___wasm_call_ctors=wasmExports["__wasm_call_ctors"])();var _main=Module["_main"]=(a0,a1)=>(_main=Module["_main"]=wasmExports["main"])(a0,a1);var _olc_OnPageUnload=Module["_olc_OnPageUnload"]=()=>(_olc_OnPageUnload=Module["_olc_OnPageUnload"]=wasmExports["olc_OnPageUnload"])();var _olc_PGE_UpdateWindowSize=Module["_olc_PGE_UpdateWindowSize"]=(a0,a1)=>(_olc_PGE_UpdateWindowSize=Module["_olc_PGE_UpdateWindowSize"]=wasmExports["olc_PGE_UpdateWindowSize"])(a0,a1);var _malloc=a0=>(_malloc=wasmExports["malloc"])(a0);var setTempRet0=a0=>(setTempRet0=wasmExports["setTempRet0"])(a0);var _setThrew=(a0,a1)=>(_setThrew=wasmExports["setThrew"])(a0,a1);var stackSave=()=>(stackSave=wasmExports["stackSave"])();var stackRestore=a0=>(stackRestore=wasmExports["stackRestore"])(a0);var stackAlloc=a0=>(stackAlloc=wasmExports["stackAlloc"])(a0);var ___cxa_is_pointer_type=a0=>(___cxa_is_pointer_type=wasmExports["__cxa_is_pointer_type"])(a0);var dynCall_viijii=Module["dynCall_viijii"]=(a0,a1,a2,a3,a4,a5,a6)=>(dynCall_viijii=Module["dynCall_viijii"]=wasmExports["dynCall_viijii"])(a0,a1,a2,a3,a4,a5,a6);var dynCall_jiji=Module["dynCall_jiji"]=(a0,a1,a2,a3,a4)=>(dynCall_jiji=Module["dynCall_jiji"]=wasmExports["dynCall_jiji"])(a0,a1,a2,a3,a4);var dynCall_iiiiij=Module["dynCall_iiiiij"]=(a0,a1,a2,a3,a4,a5,a6)=>(dynCall_iiiiij=Module["dynCall_iiiiij"]=wasmExports["dynCall_iiiiij"])(a0,a1,a2,a3,a4,a5,a6);var dynCall_iiiiijj=Module["dynCall_iiiiijj"]=(a0,a1,a2,a3,a4,a5,a6,a7,a8)=>(dynCall_iiiiijj=Module["dynCall_iiiiijj"]=wasmExports["dynCall_iiiiijj"])(a0,a1,a2,a3,a4,a5,a6,a7,a8);var dynCall_iiiiiijj=Module["dynCall_iiiiiijj"]=(a0,a1,a2,a3,a4,a5,a6,a7,a8,a9)=>(dynCall_iiiiiijj=Module["dynCall_iiiiiijj"]=wasmExports["dynCall_iiiiiijj"])(a0,a1,a2,a3,a4,a5,a6,a7,a8,a9);function invoke_iiiii(index,a1,a2,a3,a4){var sp=stackSave();try{return getWasmTableEntry(index)(a1,a2,a3,a4)}catch(e){stackRestore(sp);if(e!==e+0)throw e;_setThrew(1,0)}}function invoke_ii(index,a1){var sp=stackSave();try{return getWasmTableEntry(index)(a1)}catch(e){stackRestore(sp);if(e!==e+0)throw e;_setThrew(1,0)}}function invoke_iiii(index,a1,a2,a3){var sp=stackSave();try{return getWasmTableEntry(index)(a1,a2,a3)}catch(e){stackRestore(sp);if(e!==e+0)throw e;_setThrew(1,0)}}function invoke_iii(index,a1,a2){var sp=stackSave();try{return getWasmTableEntry(index)(a1,a2)}catch(e){stackRestore(sp);if(e!==e+0)throw e;_setThrew(1,0)}}function invoke_vii(index,a1,a2){var sp=stackSave();try{getWasmTableEntry(index)(a1,a2)}catch(e){stackRestore(sp);if(e!==e+0)throw e;_setThrew(1,0)}}function invoke_vi(index,a1){var sp=stackSave();try{getWasmTableEntry(index)(a1)}catch(e){stackRestore(sp);if(e!==e+0)throw e;_setThrew(1,0)}}function invoke_viiiiii(index,a1,a2,a3,a4,a5,a6){var sp=stackSave();try{getWasmTableEntry(index)(a1,a2,a3,a4,a5,a6)}catch(e){stackRestore(sp);if(e!==e+0)throw e;_setThrew(1,0)}}function invoke_viii(index,a1,a2,a3){var sp=stackSave();try{getWasmTableEntry(index)(a1,a2,a3)}catch(e){stackRestore(sp);if(e!==e+0)throw e;_setThrew(1,0)}}function invoke_viiii(index,a1,a2,a3,a4){var sp=stackSave();try{getWasmTableEntry(index)(a1,a2,a3,a4)}catch(e){stackRestore(sp);if(e!==e+0)throw e;_setThrew(1,0)}}function applySignatureConversions(wasmExports){wasmExports=Object.assign({},wasmExports);var makeWrapper_pp=f=>a0=>f(a0)>>>0;var makeWrapper_p=f=>()=>f()>>>0;wasmExports["malloc"]=makeWrapper_pp(wasmExports["malloc"]);wasmExports["stackSave"]=makeWrapper_p(wasmExports["stackSave"]);wasmExports["stackAlloc"]=makeWrapper_pp(wasmExports["stackAlloc"]);return wasmExports}Module["addRunDependency"]=addRunDependency;Module["removeRunDependency"]=removeRunDependency;Module["FS_createPath"]=FS.createPath;Module["FS_createLazyFile"]=FS.createLazyFile;Module["FS_createDevice"]=FS.createDevice;Module["FS_createPreloadedFile"]=FS.createPreloadedFile;Module["FS_createDataFile"]=FS.createDataFile;Module["FS_unlink"]=FS.unlink;var calledRun;dependenciesFulfilled=function runCaller(){if(!calledRun)run();if(!calledRun)dependenciesFulfilled=runCaller};function callMain(){var entryFunction=_main;var argc=0;var argv=0;try{var ret=entryFunction(argc,argv);exitJS(ret,true);return ret}catch(e){return handleException(e)}}function run(){if(runDependencies>0){return}preRun();if(runDependencies>0){return}function doRun(){if(calledRun)return;calledRun=true;Module["calledRun"]=true;if(ABORT)return;initRuntime();preMain();if(Module["onRuntimeInitialized"])Module["onRuntimeInitialized"]();if(shouldRunNow)callMain();postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(function(){setTimeout(function(){Module["setStatus"]("")},1);doRun()},1)}else{doRun()}}if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}var shouldRunNow=true;if(Module["noInitialRun"])shouldRunNow=false;run(); diff --git a/C++ProjectTemplate.wasm b/C++ProjectTemplate.wasm new file mode 100755 index 0000000000000000000000000000000000000000..b180ee7c9a5d2bb35106557729b814d00ca71666 GIT binary patch literal 310725 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ΡL>r$hbd5 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 Wf)Uw9Tvz298j;7BC8i|Koc}K;lIcqT literal 0 HcmV?d00001 diff --git a/README.md b/README.md new file mode 100644 index 0000000..0a3a1b9 --- /dev/null +++ b/README.md @@ -0,0 +1,33 @@ +This repository contains general build scripts and pipelines for all languages that I incorporate in my projects. The goal is to provide an easy retrieval and update system for the project. Each script will be a shell script containing the following template: +```bash + #Short description about what I do + #Language[Folder] + # #The script's code goes in here. + # rm -Rf out/* + # javac -Xlint:unchecked -cp ${PROJECT_DIR}/.. -d ${OUT_DIR} ${PROJECT_DIR}/*.java + # printf "\n\n\nRunning Program...\n\n" + # cd $OUT_DIR + # java ${MAIN_CLASS} "$@" + # ../scripts/clean.sh + +``` +Each language will be in the following structure: +``` + - + -- + ---[script files.sh] +``` + +The `sig` script will display by default any scripts in the `scripts` folder, therefore when creating a project, copy over the scripts folder of the desired language into your project then the `sig` script handles the rest appropriately. If your project requires multiple languages and build setups, then you can use the `sig2` command, which has an additional parameter to specify the language when running it. When setting up a multi-language setup, you'll just copy the entire folder to include the programming language itself. So a multi-language project structure may look something like this: +``` + -C + --scripts + ---build.sh + ---clean.sh + ---make.sh + -Java + --scripts + ---build.sh + ---clean.sh + ---jar.sh +``` diff --git a/assets/test b/assets/test new file mode 100644 index 0000000..e69de29 diff --git a/buildtemplate.html b/buildtemplate.html new file mode 100644 index 0000000..7e6698d --- /dev/null +++ b/buildtemplate.html @@ -0,0 +1,75 @@ + + + + + + + + Emscripten-Generated Code + + + + + + + + + + diff --git a/dirtblock.png b/dirtblock.png new file mode 100644 index 0000000000000000000000000000000000000000..af8bd9194d19cb226b0ebc392c2a80044008ad90 GIT binary patch literal 35629 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 z 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 literal 0 HcmV?d00001 diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..458c7a7 --- /dev/null +++ b/main.cpp @@ -0,0 +1,65 @@ +#define OLC_GFX_OPENGL33 +#include "pixelGameEngine.h" + +using namespace olc; + +#define WIDTH 640 +#define HEIGHT 480 + +class Example : public olc::PixelGameEngine +{ + + +public: + Example() + { + sAppName = "Example"; + } + +public: + olc::Key last; + bool OnUserCreate() override + { + std::cout<<"Test"< +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#pragma endregion + +#define PGE_VER 224 + +// O------------------------------------------------------------------------------O +// | COMPILER CONFIGURATION ODDITIES | +// O------------------------------------------------------------------------------O +#pragma region compiler_config +#define USE_EXPERIMENTAL_FS +#if defined(_WIN32) + #if _MSC_VER >= 1920 && _MSVC_LANG >= 201703L + #undef USE_EXPERIMENTAL_FS + #endif +#endif +#if defined(__linux__) || defined(__MINGW32__) || defined(__EMSCRIPTEN__) || defined(__FreeBSD__) || defined(__APPLE__) + #if __cplusplus >= 201703L + #undef USE_EXPERIMENTAL_FS + #endif +#endif + +#if !defined(OLC_KEYBOARD_UK) + #define OLC_KEYBOARD_UK +#endif + + +#if defined(USE_EXPERIMENTAL_FS) || defined(FORCE_EXPERIMENTAL_FS) + // C++14 + #define _SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING + #include + namespace _gfs = std::experimental::filesystem::v1; +#else + // C++17 + #include + namespace _gfs = std::filesystem; +#endif + +#if defined(UNICODE) || defined(_UNICODE) + #define olcT(s) L##s +#else + #define olcT(s) s +#endif + +#define UNUSED(x) (void)(x) + +// O------------------------------------------------------------------------------O +// | PLATFORM SELECTION CODE, Thanks slavka! | +// O------------------------------------------------------------------------------O + +#if defined(OLC_PGE_HEADLESS) + #define OLC_PLATFORM_HEADLESS + #define OLC_GFX_HEADLESS + #if !defined(OLC_IMAGE_STB) && !defined(OLC_IMAGE_GDI) && !defined(OLC_IMAGE_LIBPNG) + #define OLC_IMAGE_HEADLESS + #endif +#endif + +// Platform +#if !defined(OLC_PLATFORM_WINAPI) && !defined(OLC_PLATFORM_X11) && !defined(OLC_PLATFORM_GLUT) && !defined(OLC_PLATFORM_EMSCRIPTEN) && !defined(OLC_PLATFORM_HEADLESS) + #if !defined(OLC_PLATFORM_CUSTOM_EX) + #if defined(_WIN32) + #define OLC_PLATFORM_WINAPI + #endif + #if defined(__linux__) || defined(__FreeBSD__) + #define OLC_PLATFORM_X11 + #endif + #if defined(__APPLE__) + #define GL_SILENCE_DEPRECATION + #define OLC_PLATFORM_GLUT + #endif + #if defined(__EMSCRIPTEN__) + #define OLC_PLATFORM_EMSCRIPTEN + #endif + #endif +#endif + +// Start Situation +#if defined(OLC_PLATFORM_GLUT) || defined(OLC_PLATFORM_EMSCRIPTEN) + #define PGE_USE_CUSTOM_START +#endif + + + +// Renderer +#if !defined(OLC_GFX_OPENGL10) && !defined(OLC_GFX_OPENGL33) && !defined(OLC_GFX_DIRECTX10) && !defined(OLC_GFX_HEADLESS) + #if !defined(OLC_GFX_CUSTOM_EX) + #if defined(OLC_PLATFORM_EMSCRIPTEN) + #define OLC_GFX_OPENGL33 + #else + #define OLC_GFX_OPENGL10 + #endif + #endif +#endif + +// Image loader +#if !defined(OLC_IMAGE_STB) && !defined(OLC_IMAGE_GDI) && !defined(OLC_IMAGE_LIBPNG) && !defined(OLC_IMAGE_HEADLESS) + #if !defined(OLC_IMAGE_CUSTOM_EX) + #if defined(_WIN32) + #define OLC_IMAGE_GDI + #endif + #if defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || defined(__EMSCRIPTEN__) + #define OLC_IMAGE_LIBPNG + #endif + #endif +#endif + + +// O------------------------------------------------------------------------------O +// | PLATFORM-SPECIFIC DEPENDENCIES | +// O------------------------------------------------------------------------------O +#if !defined(OLC_PGE_HEADLESS) +#if defined(OLC_PLATFORM_WINAPI) + #define _WINSOCKAPI_ // Thanks Cornchipss + #if !defined(VC_EXTRALEAN) + #define VC_EXTRALEAN + #endif + #if !defined(NOMINMAX) + #define NOMINMAX + #endif + + // In Code::Blocks + #if !defined(_WIN32_WINNT) + #ifdef HAVE_MSMF + #define _WIN32_WINNT 0x0600 // Windows Vista + #else + #define _WIN32_WINNT 0x0500 // Windows 2000 + #endif + #endif + + #include + #undef _WINSOCKAPI_ +#endif + +#if defined(OLC_PLATFORM_X11) + namespace X11 + { + #include + #include + } +#endif + +#if defined(OLC_PLATFORM_GLUT) + #if defined(__linux__) + #include + #include + #endif + #if defined(__APPLE__) + #include + #include + #include + #endif +#endif +#endif + +#if defined(OLC_PGE_HEADLESS) +#if defined max +#undef max +#endif +#if defined min +#undef min +#endif +#endif +#pragma endregion + +// O------------------------------------------------------------------------------O +// | olcPixelGameEngine INTERFACE DECLARATION | +// O------------------------------------------------------------------------------O +#pragma region pge_declaration +namespace olc +{ + class PixelGameEngine; + class Sprite; + + // Pixel Game Engine Advanced Configuration + constexpr uint8_t nMouseButtons = 5; + constexpr uint8_t nDefaultAlpha = 0xFF; + constexpr uint32_t nDefaultPixel = (nDefaultAlpha << 24); + constexpr uint8_t nTabSizeInSpaces = 4; + constexpr size_t OLC_MAX_VERTS = 128; + enum rcode { FAIL = 0, OK = 1, NO_FILE = -1 }; + + // O------------------------------------------------------------------------------O + // | olc::Pixel - Represents a 32-Bit RGBA colour | + // O------------------------------------------------------------------------------O + struct Pixel + { + union + { + uint32_t n = nDefaultPixel; + struct { uint8_t r; uint8_t g; uint8_t b; uint8_t a; }; + }; + + enum Mode { NORMAL, MASK, ALPHA, CUSTOM }; + + Pixel(); + Pixel(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha = nDefaultAlpha); + Pixel(uint32_t p); + Pixel& operator = (const Pixel& v) = default; + bool operator ==(const Pixel& p) const; + bool operator !=(const Pixel& p) const; + Pixel operator * (const float i) const; + Pixel operator / (const float i) const; + Pixel& operator *=(const float i); + Pixel& operator /=(const float i); + Pixel operator + (const Pixel& p) const; + Pixel operator - (const Pixel& p) const; + Pixel& operator +=(const Pixel& p); + Pixel& operator -=(const Pixel& p); + Pixel operator * (const Pixel& p) const; + Pixel& operator *=(const Pixel& p); + Pixel inv() const; + }; + + Pixel PixelF(float red, float green, float blue, float alpha = 1.0f); + Pixel PixelLerp(const olc::Pixel& p1, const olc::Pixel& p2, float t); + + + // O------------------------------------------------------------------------------O + // | USEFUL CONSTANTS | + // O------------------------------------------------------------------------------O + static const Pixel + GREY(192, 192, 192), DARK_GREY(128, 128, 128), VERY_DARK_GREY(64, 64, 64), + RED(255, 0, 0), DARK_RED(128, 0, 0), VERY_DARK_RED(64, 0, 0), + YELLOW(255, 255, 0), DARK_YELLOW(128, 128, 0), VERY_DARK_YELLOW(64, 64, 0), + GREEN(0, 255, 0), DARK_GREEN(0, 128, 0), VERY_DARK_GREEN(0, 64, 0), + CYAN(0, 255, 255), DARK_CYAN(0, 128, 128), VERY_DARK_CYAN(0, 64, 64), + BLUE(0, 0, 255), DARK_BLUE(0, 0, 128), VERY_DARK_BLUE(0, 0, 64), + MAGENTA(255, 0, 255), DARK_MAGENTA(128, 0, 128), VERY_DARK_MAGENTA(64, 0, 64), + WHITE(255, 255, 255), BLACK(0, 0, 0), BLANK(0, 0, 0, 0); + + // Thanks to scripticuk and others for updating the key maps + // NOTE: The GLUT platform will need updating, open to contributions ;) + enum Key + { + NONE, + A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, + K0, K1, K2, K3, K4, K5, K6, K7, K8, K9, + F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, + UP, DOWN, LEFT, RIGHT, + SPACE, TAB, SHIFT, CTRL, INS, DEL, HOME, END, PGUP, PGDN, + BACK, ESCAPE, RETURN, ENTER, PAUSE, SCROLL, + NP0, NP1, NP2, NP3, NP4, NP5, NP6, NP7, NP8, NP9, + NP_MUL, NP_DIV, NP_ADD, NP_SUB, NP_DECIMAL, PERIOD, + EQUALS, COMMA, MINUS, + OEM_1, OEM_2, OEM_3, OEM_4, OEM_5, OEM_6, OEM_7, OEM_8, + CAPS_LOCK, ENUM_END + }; + + namespace Mouse + { + static constexpr int32_t LEFT = 0; + static constexpr int32_t RIGHT = 1; + static constexpr int32_t MIDDLE = 2; + }; + + // O------------------------------------------------------------------------------O + // | olc::HWButton - Represents the state of a hardware button (mouse/key/joy) | + // O------------------------------------------------------------------------------O + struct HWButton + { + bool bPressed = false; // Set once during the frame the event occurs + bool bReleased = false; // Set once during the frame the event occurs + bool bHeld = false; // Set true for all frames between pressed and released events + }; + + + + + // O------------------------------------------------------------------------------O + // | olc::vX2d - A generic 2D vector type | + // O------------------------------------------------------------------------------O +#if !defined(OLC_IGNORE_VEC2D) + template + struct v2d_generic + { + T x = 0; + T y = 0; + v2d_generic() : x(0), y(0) {} + v2d_generic(T _x, T _y) : x(_x), y(_y) {} + v2d_generic(const v2d_generic& v) : x(v.x), y(v.y) {} + v2d_generic& operator=(const v2d_generic& v) = default; + T mag() const { return T(std::sqrt(x * x + y * y)); } + T mag2() const { return x * x + y * y; } + v2d_generic norm() const { T r = 1 / mag(); return v2d_generic(x * r, y * r); } + v2d_generic perp() const { return v2d_generic(-y, x); } + v2d_generic floor() const { return v2d_generic(std::floor(x), std::floor(y)); } + v2d_generic ceil() const { return v2d_generic(std::ceil(x), std::ceil(y)); } + v2d_generic max(const v2d_generic& v) const { return v2d_generic(std::max(x, v.x), std::max(y, v.y)); } + v2d_generic min(const v2d_generic& v) const { return v2d_generic(std::min(x, v.x), std::min(y, v.y)); } + v2d_generic cart() { return { std::cos(y) * x, std::sin(y) * x }; } + v2d_generic polar() { return { mag(), std::atan2(y, x) }; } + v2d_generic clamp(const v2d_generic& v1, const v2d_generic& v2) const { return this->max(v1).min(v2); } + v2d_generic lerp(const v2d_generic& v1, const double t) { return this->operator*(T(1.0 - t)) + (v1 * T(t)); } + T dot(const v2d_generic& rhs) const { return this->x * rhs.x + this->y * rhs.y; } + T cross(const v2d_generic& rhs) const { return this->x * rhs.y - this->y * rhs.x; } + v2d_generic operator + (const v2d_generic& rhs) const { return v2d_generic(this->x + rhs.x, this->y + rhs.y); } + v2d_generic operator - (const v2d_generic& rhs) const { return v2d_generic(this->x - rhs.x, this->y - rhs.y); } + v2d_generic operator * (const T& rhs) const { return v2d_generic(this->x * rhs, this->y * rhs); } + v2d_generic operator * (const v2d_generic& rhs) const { return v2d_generic(this->x * rhs.x, this->y * rhs.y); } + v2d_generic operator / (const T& rhs) const { return v2d_generic(this->x / rhs, this->y / rhs); } + v2d_generic operator / (const v2d_generic& rhs) const { return v2d_generic(this->x / rhs.x, this->y / rhs.y); } + v2d_generic& operator += (const v2d_generic& rhs) { this->x += rhs.x; this->y += rhs.y; return *this; } + v2d_generic& operator -= (const v2d_generic& rhs) { this->x -= rhs.x; this->y -= rhs.y; return *this; } + v2d_generic& operator *= (const T& rhs) { this->x *= rhs; this->y *= rhs; return *this; } + v2d_generic& operator /= (const T& rhs) { this->x /= rhs; this->y /= rhs; return *this; } + v2d_generic& operator *= (const v2d_generic& rhs) { this->x *= rhs.x; this->y *= rhs.y; return *this; } + v2d_generic& operator /= (const v2d_generic& rhs) { this->x /= rhs.x; this->y /= rhs.y; return *this; } + v2d_generic operator + () const { return { +x, +y }; } + v2d_generic operator - () const { return { -x, -y }; } + bool operator == (const v2d_generic& rhs) const { return (this->x == rhs.x && this->y == rhs.y); } + bool operator != (const v2d_generic& rhs) const { return (this->x != rhs.x || this->y != rhs.y); } + const std::string str() const { return std::string("(") + std::to_string(this->x) + "," + std::to_string(this->y) + ")"; } + friend std::ostream& operator << (std::ostream& os, const v2d_generic& rhs) { os << rhs.str(); return os; } + operator v2d_generic() const { return { static_cast(this->x), static_cast(this->y) }; } + operator v2d_generic() const { return { static_cast(this->x), static_cast(this->y) }; } + operator v2d_generic() const { return { static_cast(this->x), static_cast(this->y) }; } + }; + + // Note: joshinils has some good suggestions here, but they are complicated to implement at this moment, + // however they will appear in a future version of PGE + template inline v2d_generic operator * (const float& lhs, const v2d_generic& rhs) + { return v2d_generic((T)(lhs * (float)rhs.x), (T)(lhs * (float)rhs.y)); } + template inline v2d_generic operator * (const double& lhs, const v2d_generic& rhs) + { return v2d_generic((T)(lhs * (double)rhs.x), (T)(lhs * (double)rhs.y)); } + template inline v2d_generic operator * (const int& lhs, const v2d_generic& rhs) + { return v2d_generic((T)(lhs * (int)rhs.x), (T)(lhs * (int)rhs.y)); } + template inline v2d_generic operator / (const float& lhs, const v2d_generic& rhs) + { return v2d_generic((T)(lhs / (float)rhs.x), (T)(lhs / (float)rhs.y)); } + template inline v2d_generic operator / (const double& lhs, const v2d_generic& rhs) + { return v2d_generic((T)(lhs / (double)rhs.x), (T)(lhs / (double)rhs.y)); } + template inline v2d_generic operator / (const int& lhs, const v2d_generic& rhs) + { return v2d_generic((T)(lhs / (int)rhs.x), (T)(lhs / (int)rhs.y)); } + + // To stop dandistine crying... + template inline bool operator < (const v2d_generic& lhs, const v2d_generic& rhs) + { return lhs.y < rhs.y || (lhs.y == rhs.y && lhs.x < rhs.x); } + template inline bool operator > (const v2d_generic& lhs, const v2d_generic& rhs) + { return lhs.y > rhs.y || (lhs.y == rhs.y && lhs.x > rhs.x); } + + typedef v2d_generic vi2d; + typedef v2d_generic vu2d; + typedef v2d_generic vf2d; + typedef v2d_generic vd2d; +#endif + + + + + + + // O------------------------------------------------------------------------------O + // | olc::ResourcePack - A virtual scrambled filesystem to pack your assets into | + // O------------------------------------------------------------------------------O + struct ResourceBuffer : public std::streambuf + { + ResourceBuffer(std::ifstream& ifs, uint32_t offset, uint32_t size); + std::vector vMemory; + }; + + class ResourcePack : public std::streambuf + { + public: + ResourcePack(); + ~ResourcePack(); + bool AddFile(const std::string& sFile); + bool LoadPack(const std::string& sFile, const std::string& sKey); + bool SavePack(const std::string& sFile, const std::string& sKey); + ResourceBuffer GetFileBuffer(const std::string& sFile); + bool Loaded(); + private: + struct sResourceFile { uint32_t nSize; uint32_t nOffset; }; + std::map mapFiles; + std::ifstream baseFile; + std::vector scramble(const std::vector& data, const std::string& key); + std::string makeposix(const std::string& path); + }; + + + class ImageLoader + { + public: + ImageLoader() = default; + virtual ~ImageLoader() = default; + virtual olc::rcode LoadImageResource(olc::Sprite* spr, const std::string& sImageFile, olc::ResourcePack* pack) = 0; + virtual olc::rcode SaveImageResource(olc::Sprite* spr, const std::string& sImageFile) = 0; + }; + + + // O------------------------------------------------------------------------------O + // | olc::Sprite - An image represented by a 2D array of olc::Pixel | + // O------------------------------------------------------------------------------O + class Sprite + { + public: + Sprite(); + Sprite(const std::string& sImageFile, olc::ResourcePack* pack = nullptr); + Sprite(int32_t w, int32_t h); + Sprite(const olc::Sprite&) = delete; + ~Sprite(); + + public: + olc::rcode LoadFromFile(const std::string& sImageFile, olc::ResourcePack* pack = nullptr); + + public: + int32_t width = 0; + int32_t height = 0; + enum Mode { NORMAL, PERIODIC, CLAMP }; + enum Flip { NONE = 0, HORIZ = 1, VERT = 2 }; + + public: + void SetSampleMode(olc::Sprite::Mode mode = olc::Sprite::Mode::NORMAL); + Pixel GetPixel(int32_t x, int32_t y) const; + bool SetPixel(int32_t x, int32_t y, Pixel p); + Pixel GetPixel(const olc::vi2d& a) const; + bool SetPixel(const olc::vi2d& a, Pixel p); + Pixel Sample(float x, float y) const; + Pixel Sample(const olc::vf2d& uv) const; + Pixel SampleBL(float u, float v) const; + Pixel SampleBL(const olc::vf2d& uv) const; + Pixel* GetData(); + olc::Sprite* Duplicate(); + olc::Sprite* Duplicate(const olc::vi2d& vPos, const olc::vi2d& vSize); + olc::vi2d Size() const; + std::vector pColData; + Mode modeSample = Mode::NORMAL; + + static std::unique_ptr loader; + }; + + // O------------------------------------------------------------------------------O + // | olc::Decal - A GPU resident storage of an olc::Sprite | + // O------------------------------------------------------------------------------O + class Decal + { + public: + Decal(olc::Sprite* spr, bool filter = false, bool clamp = true); + Decal(const uint32_t nExistingTextureResource, olc::Sprite* spr); + virtual ~Decal(); + void Update(); + void UpdateSprite(); + + public: // But dont touch + int32_t id = -1; + olc::Sprite* sprite = nullptr; + olc::vf2d vUVScale = { 1.0f, 1.0f }; + }; + + enum class DecalMode + { + NORMAL, + ADDITIVE, + MULTIPLICATIVE, + STENCIL, + ILLUMINATE, + WIREFRAME, + MODEL3D, + }; + + enum class DecalStructure + { + LINE, + FAN, + STRIP, + LIST + }; + + // O------------------------------------------------------------------------------O + // | olc::Renderable - Convenience class to keep a sprite and decal together | + // O------------------------------------------------------------------------------O + class Renderable + { + public: + Renderable() = default; + Renderable(Renderable&& r) : pSprite(std::move(r.pSprite)), pDecal(std::move(r.pDecal)) {} + Renderable(const Renderable&) = delete; + olc::rcode Load(const std::string& sFile, ResourcePack* pack = nullptr, bool filter = false, bool clamp = true); + void Create(uint32_t width, uint32_t height, bool filter = false, bool clamp = true); + olc::Decal* Decal() const; + olc::Sprite* Sprite() const; + + private: + std::unique_ptr pSprite = nullptr; + std::unique_ptr pDecal = nullptr; + }; + + + // O------------------------------------------------------------------------------O + // | Auxilliary components internal to engine | + // O------------------------------------------------------------------------------O + + struct DecalInstance + { + olc::Decal* decal = nullptr; + std::vector pos; + std::vector uv; + std::vector w; + std::vector tint; + olc::DecalMode mode = olc::DecalMode::NORMAL; + olc::DecalStructure structure = olc::DecalStructure::FAN; + uint32_t points = 0; + }; + + struct LayerDesc + { + olc::vf2d vOffset = { 0, 0 }; + olc::vf2d vScale = { 1, 1 }; + bool bShow = false; + bool bUpdate = false; + olc::Renderable pDrawTarget; + uint32_t nResID = 0; + std::vector vecDecalInstance; + olc::Pixel tint = olc::WHITE; + std::function funcHook = nullptr; + }; + + class Renderer + { + public: + virtual ~Renderer() = default; + virtual void PrepareDevice() = 0; + virtual olc::rcode CreateDevice(std::vector params, bool bFullScreen, bool bVSYNC) = 0; + virtual olc::rcode DestroyDevice() = 0; + virtual void DisplayFrame() = 0; + virtual void PrepareDrawing() = 0; + virtual void SetDecalMode(const olc::DecalMode& mode) = 0; + virtual void DrawLayerQuad(const olc::vf2d& offset, const olc::vf2d& scale, const olc::Pixel tint) = 0; + virtual void DrawDecal(const olc::DecalInstance& decal) = 0; + virtual uint32_t CreateTexture(const uint32_t width, const uint32_t height, const bool filtered = false, const bool clamp = true) = 0; + virtual void UpdateTexture(uint32_t id, olc::Sprite* spr) = 0; + virtual void ReadTexture(uint32_t id, olc::Sprite* spr) = 0; + virtual uint32_t DeleteTexture(const uint32_t id) = 0; + virtual void ApplyTexture(uint32_t id) = 0; + virtual void UpdateViewport(const olc::vi2d& pos, const olc::vi2d& size) = 0; + virtual void ClearBuffer(olc::Pixel p, bool bDepth) = 0; + static olc::PixelGameEngine* ptrPGE; + }; + + class Platform + { + public: + virtual ~Platform() = default; + virtual olc::rcode ApplicationStartUp() = 0; + virtual olc::rcode ApplicationCleanUp() = 0; + virtual olc::rcode ThreadStartUp() = 0; + virtual olc::rcode ThreadCleanUp() = 0; + virtual olc::rcode CreateGraphics(bool bFullScreen, bool bEnableVSYNC, const olc::vi2d& vViewPos, const olc::vi2d& vViewSize) = 0; + virtual olc::rcode CreateWindowPane(const olc::vi2d& vWindowPos, olc::vi2d& vWindowSize, bool bFullScreen) = 0; + virtual olc::rcode SetWindowTitle(const std::string& s) = 0; + virtual olc::rcode StartSystemEventLoop() = 0; + virtual olc::rcode HandleSystemEvent() = 0; + static olc::PixelGameEngine* ptrPGE; + }; + + class PGEX; + + // The Static Twins (plus one) + static std::unique_ptr renderer; + static std::unique_ptr platform; + static std::map mapKeys; + + // O------------------------------------------------------------------------------O + // | olc::PixelGameEngine - The main BASE class for your application | + // O------------------------------------------------------------------------------O + class PixelGameEngine + { + public: + PixelGameEngine(); + virtual ~PixelGameEngine(); + public: + olc::rcode Construct(int32_t screen_w, int32_t screen_h, int32_t pixel_w, int32_t pixel_h, + bool full_screen = false, bool vsync = false, bool cohesion = false); + olc::rcode Start(); + + public: // User Override Interfaces + // Called once on application startup, use to load your resources + virtual bool OnUserCreate(); + // Called every frame, and provides you with a time per frame value + virtual bool OnUserUpdate(float fElapsedTime); + // Called once on application termination, so you can be one clean coder + virtual bool OnUserDestroy(); + + // Called when a text entry is confirmed with "enter" key + virtual void OnTextEntryComplete(const std::string& sText); + // Called when a console command is executed + virtual bool OnConsoleCommand(const std::string& sCommand); + + + public: // Hardware Interfaces + // Returns true if window is currently in focus + bool IsFocused() const; + // Get the state of a specific keyboard button + HWButton GetKey(Key k) const; + // Get the state of a specific mouse button + HWButton GetMouse(uint32_t b) const; + // Get Mouse X coordinate in "pixel" space + int32_t GetMouseX() const; + // Get Mouse Y coordinate in "pixel" space + int32_t GetMouseY() const; + // Get Mouse Wheel Delta + int32_t GetMouseWheel() const; + // Get the mouse in window space + const olc::vi2d& GetWindowMouse() const; + // Gets the mouse as a vector to keep Tarriest happy + const olc::vi2d& GetMousePos() const; + + static const std::map& GetKeyMap() { return mapKeys; } + + public: // Utility + // Returns the width of the screen in "pixels" + int32_t ScreenWidth() const; + // Returns the height of the screen in "pixels" + int32_t ScreenHeight() const; + // Returns the width of the currently selected drawing target in "pixels" + int32_t GetDrawTargetWidth() const; + // Returns the height of the currently selected drawing target in "pixels" + int32_t GetDrawTargetHeight() const; + // Returns the currently active draw target + olc::Sprite* GetDrawTarget() const; + // Resize the primary screen sprite + void SetScreenSize(int w, int h); + // Specify which Sprite should be the target of drawing functions, use nullptr + // to specify the primary screen + void SetDrawTarget(Sprite* target); + // Gets the current Frames Per Second + uint32_t GetFPS() const; + // Gets last update of elapsed time + float GetElapsedTime() const; + // Gets Actual Window size + const olc::vi2d& GetWindowSize() const; + // Gets pixel scale + const olc::vi2d& GetPixelSize() const; + // Gets actual pixel scale + const olc::vi2d& GetScreenPixelSize() const; + // Gets "screen" size + const olc::vi2d& GetScreenSize() const; + // Gets any files dropped this frame + const std::vector& GetDroppedFiles() const; + const olc::vi2d& GetDroppedFilesPoint() const; + + public: // CONFIGURATION ROUTINES + // Layer targeting functions + void SetDrawTarget(uint8_t layer, bool bDirty = true); + void EnableLayer(uint8_t layer, bool b); + void SetLayerOffset(uint8_t layer, const olc::vf2d& offset); + void SetLayerOffset(uint8_t layer, float x, float y); + void SetLayerScale(uint8_t layer, const olc::vf2d& scale); + void SetLayerScale(uint8_t layer, float x, float y); + void SetLayerTint(uint8_t layer, const olc::Pixel& tint); + void SetLayerCustomRenderFunction(uint8_t layer, std::function f); + + std::vector& GetLayers(); + uint32_t CreateLayer(); + + // Change the pixel mode for different optimisations + // olc::Pixel::NORMAL = No transparency + // olc::Pixel::MASK = Transparent if alpha is < 255 + // olc::Pixel::ALPHA = Full transparency + void SetPixelMode(Pixel::Mode m); + Pixel::Mode GetPixelMode(); + // Use a custom blend function + void SetPixelMode(std::function pixelMode); + // Change the blend factor from between 0.0f to 1.0f; + void SetPixelBlend(float fBlend); + + + + public: // DRAWING ROUTINES + // Draws a single Pixel + virtual bool Draw(int32_t x, int32_t y, Pixel p = olc::WHITE); + bool Draw(const olc::vi2d& pos, Pixel p = olc::WHITE); + // Draws a line from (x1,y1) to (x2,y2) + void DrawLine(int32_t x1, int32_t y1, int32_t x2, int32_t y2, Pixel p = olc::WHITE, uint32_t pattern = 0xFFFFFFFF); + void DrawLine(const olc::vi2d& pos1, const olc::vi2d& pos2, Pixel p = olc::WHITE, uint32_t pattern = 0xFFFFFFFF); + // Draws a circle located at (x,y) with radius + void DrawCircle(int32_t x, int32_t y, int32_t radius, Pixel p = olc::WHITE, uint8_t mask = 0xFF); + void DrawCircle(const olc::vi2d& pos, int32_t radius, Pixel p = olc::WHITE, uint8_t mask = 0xFF); + // Fills a circle located at (x,y) with radius + void FillCircle(int32_t x, int32_t y, int32_t radius, Pixel p = olc::WHITE); + void FillCircle(const olc::vi2d& pos, int32_t radius, Pixel p = olc::WHITE); + // Draws a rectangle at (x,y) to (x+w,y+h) + void DrawRect(int32_t x, int32_t y, int32_t w, int32_t h, Pixel p = olc::WHITE); + void DrawRect(const olc::vi2d& pos, const olc::vi2d& size, Pixel p = olc::WHITE); + // Fills a rectangle at (x,y) to (x+w,y+h) + void FillRect(int32_t x, int32_t y, int32_t w, int32_t h, Pixel p = olc::WHITE); + void FillRect(const olc::vi2d& pos, const olc::vi2d& size, Pixel p = olc::WHITE); + // Draws a triangle between points (x1,y1), (x2,y2) and (x3,y3) + void DrawTriangle(int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t x3, int32_t y3, Pixel p = olc::WHITE); + void DrawTriangle(const olc::vi2d& pos1, const olc::vi2d& pos2, const olc::vi2d& pos3, Pixel p = olc::WHITE); + // Flat fills a triangle between points (x1,y1), (x2,y2) and (x3,y3) + void FillTriangle(int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t x3, int32_t y3, Pixel p = olc::WHITE); + void FillTriangle(const olc::vi2d& pos1, const olc::vi2d& pos2, const olc::vi2d& pos3, Pixel p = olc::WHITE); + // Fill a textured and coloured triangle + void FillTexturedTriangle(std::vector vPoints, std::vector vTex, std::vector vColour, olc::Sprite* sprTex); + void FillTexturedPolygon(const std::vector& vPoints, const std::vector& vTex, const std::vector& vColour, olc::Sprite* sprTex, olc::DecalStructure structure = olc::DecalStructure::LIST); + // Draws an entire sprite at location (x,y) + void DrawSprite(int32_t x, int32_t y, Sprite* sprite, uint32_t scale = 1, uint8_t flip = olc::Sprite::NONE); + void DrawSprite(const olc::vi2d& pos, Sprite* sprite, uint32_t scale = 1, uint8_t flip = olc::Sprite::NONE); + // Draws an area of a sprite at location (x,y), where the + // selected area is (ox,oy) to (ox+w,oy+h) + void DrawPartialSprite(int32_t x, int32_t y, Sprite* sprite, int32_t ox, int32_t oy, int32_t w, int32_t h, uint32_t scale = 1, uint8_t flip = olc::Sprite::NONE); + void DrawPartialSprite(const olc::vi2d& pos, Sprite* sprite, const olc::vi2d& sourcepos, const olc::vi2d& size, uint32_t scale = 1, uint8_t flip = olc::Sprite::NONE); + // Draws a single line of text - traditional monospaced + void DrawString(int32_t x, int32_t y, const std::string& sText, Pixel col = olc::WHITE, uint32_t scale = 1); + void DrawString(const olc::vi2d& pos, const std::string& sText, Pixel col = olc::WHITE, uint32_t scale = 1); + olc::vi2d GetTextSize(const std::string& s); + // Draws a single line of text - non-monospaced + void DrawStringProp(int32_t x, int32_t y, const std::string& sText, Pixel col = olc::WHITE, uint32_t scale = 1); + void DrawStringProp(const olc::vi2d& pos, const std::string& sText, Pixel col = olc::WHITE, uint32_t scale = 1); + olc::vi2d GetTextSizeProp(const std::string& s); + + // Decal Quad functions + void SetDecalMode(const olc::DecalMode& mode); + void SetDecalStructure(const olc::DecalStructure& structure); + // Draws a whole decal, with optional scale and tinting + void DrawDecal(const olc::vf2d& pos, olc::Decal* decal, const olc::vf2d& scale = { 1.0f,1.0f }, const olc::Pixel& tint = olc::WHITE); + // Draws a region of a decal, with optional scale and tinting + void DrawPartialDecal(const olc::vf2d& pos, olc::Decal* decal, const olc::vf2d& source_pos, const olc::vf2d& source_size, const olc::vf2d& scale = { 1.0f,1.0f }, const olc::Pixel& tint = olc::WHITE); + void DrawPartialDecal(const olc::vf2d& pos, const olc::vf2d& size, olc::Decal* decal, const olc::vf2d& source_pos, const olc::vf2d& source_size, const olc::Pixel& tint = olc::WHITE); + // Draws fully user controlled 4 vertices, pos(pixels), uv(pixels), colours + void DrawExplicitDecal(olc::Decal* decal, const olc::vf2d* pos, const olc::vf2d* uv, const olc::Pixel* col, uint32_t elements = 4); + // Draws a decal with 4 arbitrary points, warping the texture to look "correct" + void DrawWarpedDecal(olc::Decal* decal, const olc::vf2d(&pos)[4], const olc::Pixel& tint = olc::WHITE); + void DrawWarpedDecal(olc::Decal* decal, const olc::vf2d* pos, const olc::Pixel& tint = olc::WHITE); + void DrawWarpedDecal(olc::Decal* decal, const std::array& pos, const olc::Pixel& tint = olc::WHITE); + // As above, but you can specify a region of a decal source sprite + void DrawPartialWarpedDecal(olc::Decal* decal, const olc::vf2d(&pos)[4], const olc::vf2d& source_pos, const olc::vf2d& source_size, const olc::Pixel& tint = olc::WHITE); + void DrawPartialWarpedDecal(olc::Decal* decal, const olc::vf2d* pos, const olc::vf2d& source_pos, const olc::vf2d& source_size, const olc::Pixel& tint = olc::WHITE); + void DrawPartialWarpedDecal(olc::Decal* decal, const std::array& pos, const olc::vf2d& source_pos, const olc::vf2d& source_size, const olc::Pixel& tint = olc::WHITE); + // Draws a decal rotated to specified angle, wit point of rotation offset + void DrawRotatedDecal(const olc::vf2d& pos, olc::Decal* decal, const float fAngle, const olc::vf2d& center = { 0.0f, 0.0f }, const olc::vf2d& scale = { 1.0f,1.0f }, const olc::Pixel& tint = olc::WHITE); + void DrawPartialRotatedDecal(const olc::vf2d& pos, olc::Decal* decal, const float fAngle, const olc::vf2d& center, const olc::vf2d& source_pos, const olc::vf2d& source_size, const olc::vf2d& scale = { 1.0f, 1.0f }, const olc::Pixel& tint = olc::WHITE); + // Draws a multiline string as a decal, with tiniting and scaling + void DrawStringDecal(const olc::vf2d& pos, const std::string& sText, const Pixel col = olc::WHITE, const olc::vf2d& scale = { 1.0f, 1.0f }); + void DrawStringPropDecal(const olc::vf2d& pos, const std::string& sText, const Pixel col = olc::WHITE, const olc::vf2d& scale = { 1.0f, 1.0f }); + // Draws a single shaded filled rectangle as a decal + void DrawRectDecal(const olc::vf2d& pos, const olc::vf2d& size, const olc::Pixel col = olc::WHITE); + void FillRectDecal(const olc::vf2d& pos, const olc::vf2d& size, const olc::Pixel col = olc::WHITE); + // Draws a corner shaded rectangle as a decal + void GradientFillRectDecal(const olc::vf2d& pos, const olc::vf2d& size, const olc::Pixel colTL, const olc::Pixel colBL, const olc::Pixel colBR, const olc::Pixel colTR); + // Draws an arbitrary convex textured polygon using GPU + void DrawPolygonDecal(olc::Decal* decal, const std::vector& pos, const std::vector& uv, const olc::Pixel tint = olc::WHITE); + void DrawPolygonDecal(olc::Decal* decal, const std::vector& pos, const std::vector& depth, const std::vector& uv, const olc::Pixel tint = olc::WHITE); + void DrawPolygonDecal(olc::Decal* decal, const std::vector& pos, const std::vector& uv, const std::vector& tint); + void DrawPolygonDecal(olc::Decal* decal, const std::vector& pos, const std::vector& uv, const std::vector& colours, const olc::Pixel tint); + // Draws a line in Decal Space + void DrawLineDecal(const olc::vf2d& pos1, const olc::vf2d& pos2, Pixel p = olc::WHITE); + void DrawRotatedStringDecal(const olc::vf2d& pos, const std::string& sText, const float fAngle, const olc::vf2d& center = { 0.0f, 0.0f }, const olc::Pixel col = olc::WHITE, const olc::vf2d& scale = { 1.0f, 1.0f }); + void DrawRotatedStringPropDecal(const olc::vf2d& pos, const std::string& sText, const float fAngle, const olc::vf2d& center = { 0.0f, 0.0f }, const olc::Pixel col = olc::WHITE, const olc::vf2d& scale = { 1.0f, 1.0f }); + // Clears entire draw target to Pixel + void Clear(Pixel p); + // Clears the rendering back buffer + void ClearBuffer(Pixel p, bool bDepth = true); + // Returns the font image + olc::Sprite* GetFontSprite(); + + // Clip a line segment to visible area + bool ClipLineToScreen(olc::vi2d& in_p1, olc::vi2d& in_p2); + + // Dont allow PGE to mark layers as dirty, so pixel graphics don't update + void EnablePixelTransfer(const bool bEnable = true); + + // Command Console Routines + void ConsoleShow(const olc::Key &keyExit, bool bSuspendTime = true); + bool IsConsoleShowing() const; + void ConsoleClear(); + std::stringstream& ConsoleOut(); + void ConsoleCaptureStdOut(const bool bCapture); + + // Text Entry Routines + void TextEntryEnable(const bool bEnable, const std::string& sText = ""); + std::string TextEntryGetString() const; + int32_t TextEntryGetCursor() const; + bool IsTextEntryEnabled() const; + + + + private: + void UpdateTextEntry(); + void UpdateConsole(); + + public: + + // Experimental Lightweight 3D Routines ================ +#ifdef OLC_ENABLE_EXPERIMENTAL + // Set Manual View Matrix + void LW3D_View(const std::array& m); + // Set Manual World Matrix + void LW3D_World(const std::array& m); + // Set Manual Projection Matrix + void LW3D_Projection(const std::array& m); + + // Draws a vector of vertices, interprted as individual triangles + void LW3D_DrawTriangles(olc::Decal* decal, const std::vector>& pos, const std::vector& tex, const std::vector& col); + + void LW3D_ModelTranslate(const float x, const float y, const float z); + + // Camera convenience functions + void LW3D_SetCameraAtTarget(const float fEyeX, const float fEyeY, const float fEyeZ, + const float fTargetX, const float fTargetY, const float fTargetZ, + const float fUpX = 0.0f, const float fUpY = 1.0f, const float fUpZ = 0.0f); + void LW3D_SetCameraAlongDirection(const float fEyeX, const float fEyeY, const float fEyeZ, + const float fDirX, const float fDirY, const float fDirZ, + const float fUpX = 0.0f, const float fUpY = 1.0f, const float fUpZ = 0.0f); + + // 3D Rendering Flags + void LW3D_EnableDepthTest(const bool bEnableDepth); + void LW3D_EnableBackfaceCulling(const bool bEnableCull); +#endif + public: // Branding + std::string sAppName; + + private: // Inner mysterious workings + olc::Sprite* pDrawTarget = nullptr; + Pixel::Mode nPixelMode = Pixel::NORMAL; + float fBlendFactor = 1.0f; + olc::vi2d vScreenSize = { 256, 240 }; + olc::vf2d vInvScreenSize = { 1.0f / 256.0f, 1.0f / 240.0f }; + olc::vi2d vPixelSize = { 4, 4 }; + olc::vi2d vScreenPixelSize = { 4, 4 }; + olc::vi2d vMousePos = { 0, 0 }; + int32_t nMouseWheelDelta = 0; + olc::vi2d vMousePosCache = { 0, 0 }; + olc::vi2d vMouseWindowPos = { 0, 0 }; + int32_t nMouseWheelDeltaCache = 0; + olc::vi2d vWindowSize = { 0, 0 }; + olc::vi2d vViewPos = { 0, 0 }; + olc::vi2d vViewSize = { 0,0 }; + bool bFullScreen = false; + olc::vf2d vPixel = { 1.0f, 1.0f }; + bool bHasInputFocus = false; + bool bHasMouseFocus = false; + bool bEnableVSYNC = false; + float fFrameTimer = 1.0f; + float fLastElapsed = 0.0f; + int nFrameCount = 0; + bool bSuspendTextureTransfer = false; + Renderable fontRenderable; + std::vector vLayers; + uint8_t nTargetLayer = 0; + uint32_t nLastFPS = 0; + bool bPixelCohesion = false; + DecalMode nDecalMode = DecalMode::NORMAL; + DecalStructure nDecalStructure = DecalStructure::FAN; + std::function funcPixelMode; + std::chrono::time_point m_tp1, m_tp2; + std::vector vFontSpacing; + std::vector vDroppedFiles; + std::vector vDroppedFilesCache; + olc::vi2d vDroppedFilesPoint; + olc::vi2d vDroppedFilesPointCache; + + // Command Console Specific + bool bConsoleShow = false; + bool bConsoleSuspendTime = false; + olc::Key keyConsoleExit = olc::Key::F1; + std::stringstream ssConsoleOutput; + std::streambuf* sbufOldCout = nullptr; + olc::vi2d vConsoleSize; + olc::vi2d vConsoleCursor = { 0,0 }; + olc::vf2d vConsoleCharacterScale = { 1.0f, 2.0f }; + std::vector sConsoleLines; + std::list sCommandHistory; + std::list::iterator sCommandHistoryIt; + + // Text Entry Specific + bool bTextEntryEnable = false; + std::string sTextEntryString = ""; + int32_t nTextEntryCursor = 0; + std::vector> vKeyboardMap; + + + + // State of keyboard + bool pKeyNewState[256] = { 0 }; + bool pKeyOldState[256] = { 0 }; + HWButton pKeyboardState[256] = { 0 }; + + // State of mouse + bool pMouseNewState[nMouseButtons] = { 0 }; + bool pMouseOldState[nMouseButtons] = { 0 }; + HWButton pMouseState[nMouseButtons] = { 0 }; + + // The main engine thread + void EngineThread(); + + + // If anything sets this flag to false, the engine + // "should" shut down gracefully + static std::atomic bAtomActive; + + public: + // "Break In" Functions + void olc_UpdateMouse(int32_t x, int32_t y); + void olc_UpdateMouseWheel(int32_t delta); + void olc_UpdateWindowSize(int32_t x, int32_t y); + void olc_UpdateViewport(); + void olc_ConstructFontSheet(); + void olc_CoreUpdate(); + void olc_PrepareEngine(); + void olc_UpdateMouseState(int32_t button, bool state); + void olc_UpdateKeyState(int32_t key, bool state); + void olc_UpdateMouseFocus(bool state); + void olc_UpdateKeyFocus(bool state); + void olc_Terminate(); + void olc_DropFiles(int32_t x, int32_t y, const std::vector& vFiles); + void olc_Reanimate(); + bool olc_IsRunning(); + + // At the very end of this file, chooses which + // components to compile + virtual void olc_ConfigureSystem(); + + // NOTE: Items Here are to be deprecated, I have left them in for now + // in case you are using them, but they will be removed. + // olc::vf2d vSubPixelOffset = { 0.0f, 0.0f }; + + public: // PGEX Stuff + friend class PGEX; + void pgex_Register(olc::PGEX* pgex); + + private: + std::vector vExtensions; + }; + + + + // O------------------------------------------------------------------------------O + // | PGE EXTENSION BASE CLASS - Permits access to PGE functions from extension | + // O------------------------------------------------------------------------------O + class PGEX + { + friend class olc::PixelGameEngine; + public: + PGEX(bool bHook = false); + + protected: + virtual void OnBeforeUserCreate(); + virtual void OnAfterUserCreate(); + virtual bool OnBeforeUserUpdate(float &fElapsedTime); + virtual void OnAfterUserUpdate(float fElapsedTime); + + protected: + static PixelGameEngine* pge; + }; +} + +#pragma endregion + + +#pragma region opengl33_iface +// In order to facilitate more advanced graphics features, some PGEX +// will rely on shaders. Instead of having each PGEX responsible for +// managing this, for convenience, this interface exists. + +#if defined(OLC_GFX_OPENGL33) + + #if defined(OLC_PLATFORM_WINAPI) + #include + #define CALLSTYLE __stdcall + #endif + + #if defined(__linux__) || defined(__FreeBSD__) + #include + #endif + + #if defined(OLC_PLATFORM_X11) + namespace X11 { + #include + } + #define CALLSTYLE + #endif + + #if defined(__APPLE__) + #define GL_SILENCE_DEPRECATION + #include + #include + #include + #endif + + #if defined(OLC_PLATFORM_EMSCRIPTEN) + #include + #include + #define GL_GLEXT_PROTOTYPES + #include + #include + #define CALLSTYLE + #define GL_CLAMP GL_CLAMP_TO_EDGE + #endif + +namespace olc +{ + typedef char GLchar; + typedef ptrdiff_t GLsizeiptr; + + typedef GLuint CALLSTYLE locCreateShader_t(GLenum type); + typedef GLuint CALLSTYLE locCreateProgram_t(void); + typedef void CALLSTYLE locDeleteShader_t(GLuint shader); + typedef void CALLSTYLE locCompileShader_t(GLuint shader); + typedef void CALLSTYLE locLinkProgram_t(GLuint program); + typedef void CALLSTYLE locDeleteProgram_t(GLuint program); + typedef void CALLSTYLE locAttachShader_t(GLuint program, GLuint shader); + typedef void CALLSTYLE locBindBuffer_t(GLenum target, GLuint buffer); + typedef void CALLSTYLE locBufferData_t(GLenum target, GLsizeiptr size, const void* data, GLenum usage); + typedef void CALLSTYLE locGenBuffers_t(GLsizei n, GLuint* buffers); + typedef void CALLSTYLE locVertexAttribPointer_t(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* pointer); + typedef void CALLSTYLE locEnableVertexAttribArray_t(GLuint index); + typedef void CALLSTYLE locUseProgram_t(GLuint program); + typedef void CALLSTYLE locBindVertexArray_t(GLuint array); + typedef void CALLSTYLE locGenVertexArrays_t(GLsizei n, GLuint* arrays); + typedef void CALLSTYLE locGetShaderInfoLog_t(GLuint shader, GLsizei bufSize, GLsizei* length, GLchar* infoLog); + typedef GLint CALLSTYLE locGetUniformLocation_t(GLuint program, const GLchar* name); + typedef void CALLSTYLE locUniform1f_t(GLint location, GLfloat v0); + typedef void CALLSTYLE locUniform1i_t(GLint location, GLint v0); + typedef void CALLSTYLE locUniform2fv_t(GLint location, GLsizei count, const GLfloat* value); + typedef void CALLSTYLE locActiveTexture_t(GLenum texture); + typedef void CALLSTYLE locGenFrameBuffers_t(GLsizei n, GLuint* ids); + typedef void CALLSTYLE locBindFrameBuffer_t(GLenum target, GLuint fb); + typedef GLenum CALLSTYLE locCheckFrameBufferStatus_t(GLenum target); + typedef void CALLSTYLE locDeleteFrameBuffers_t(GLsizei n, const GLuint* fbs); + typedef void CALLSTYLE locFrameBufferTexture2D_t(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); + typedef void CALLSTYLE locDrawBuffers_t(GLsizei n, const GLenum* bufs); + typedef void CALLSTYLE locBlendFuncSeparate_t(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); + +#if defined(OLC_PLATFORM_WINAPI) + typedef void __stdcall locSwapInterval_t(GLsizei n); +#endif + +#if defined(OLC_PLATFORM_X11) + typedef int(locSwapInterval_t)(X11::Display* dpy, X11::GLXDrawable drawable, int interval); +#endif + +#if defined(OLC_PLATFORM_EMSCRIPTEN) + typedef void CALLSTYLE locShaderSource_t(GLuint shader, GLsizei count, const GLchar* const* string, const GLint* length); + typedef EGLBoolean(locSwapInterval_t)(EGLDisplay display, EGLint interval); +#else + typedef void CALLSTYLE locShaderSource_t(GLuint shader, GLsizei count, const GLchar** string, const GLint* length); +#endif + +} // olc namespace +#endif // OpenGL33 Definitions +#pragma endregion + + +#endif // OLC_PGE_DEF + + +// O------------------------------------------------------------------------------O +// | START OF OLC_PGE_APPLICATION | +// O------------------------------------------------------------------------------O +#ifdef OLC_PGE_APPLICATION +#undef OLC_PGE_APPLICATION + +// O------------------------------------------------------------------------------O +// | olcPixelGameEngine INTERFACE IMPLEMENTATION (CORE) | +// | Note: The core implementation is platform independent | +// O------------------------------------------------------------------------------O +#pragma region pge_implementation +namespace olc +{ + // O------------------------------------------------------------------------------O + // | olc::Pixel IMPLEMENTATION | + // O------------------------------------------------------------------------------O + Pixel::Pixel() + { r = 0; g = 0; b = 0; a = nDefaultAlpha; } + + Pixel::Pixel(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha) + { n = red | (green << 8) | (blue << 16) | (alpha << 24); } // Thanks jarekpelczar + + Pixel::Pixel(uint32_t p) + { n = p; } + + bool Pixel::operator==(const Pixel& p) const + { return n == p.n; } + + bool Pixel::operator!=(const Pixel& p) const + { return n != p.n; } + + Pixel Pixel::operator * (const float i) const + { + float fR = std::min(255.0f, std::max(0.0f, float(r) * i)); + float fG = std::min(255.0f, std::max(0.0f, float(g) * i)); + float fB = std::min(255.0f, std::max(0.0f, float(b) * i)); + return Pixel(uint8_t(fR), uint8_t(fG), uint8_t(fB), a); + } + + Pixel Pixel::operator / (const float i) const + { + float fR = std::min(255.0f, std::max(0.0f, float(r) / i)); + float fG = std::min(255.0f, std::max(0.0f, float(g) / i)); + float fB = std::min(255.0f, std::max(0.0f, float(b) / i)); + return Pixel(uint8_t(fR), uint8_t(fG), uint8_t(fB), a); + } + + Pixel& Pixel::operator *=(const float i) + { + this->r = uint8_t(std::min(255.0f, std::max(0.0f, float(r) * i))); + this->g = uint8_t(std::min(255.0f, std::max(0.0f, float(g) * i))); + this->b = uint8_t(std::min(255.0f, std::max(0.0f, float(b) * i))); + return *this; + } + + Pixel& Pixel::operator /=(const float i) + { + this->r = uint8_t(std::min(255.0f, std::max(0.0f, float(r) / i))); + this->g = uint8_t(std::min(255.0f, std::max(0.0f, float(g) / i))); + this->b = uint8_t(std::min(255.0f, std::max(0.0f, float(b) / i))); + return *this; + } + + Pixel Pixel::operator + (const Pixel& p) const + { + uint8_t nR = uint8_t(std::min(255, std::max(0, int(r) + int(p.r)))); + uint8_t nG = uint8_t(std::min(255, std::max(0, int(g) + int(p.g)))); + uint8_t nB = uint8_t(std::min(255, std::max(0, int(b) + int(p.b)))); + return Pixel(nR, nG, nB, a); + } + + Pixel Pixel::operator - (const Pixel& p) const + { + uint8_t nR = uint8_t(std::min(255, std::max(0, int(r) - int(p.r)))); + uint8_t nG = uint8_t(std::min(255, std::max(0, int(g) - int(p.g)))); + uint8_t nB = uint8_t(std::min(255, std::max(0, int(b) - int(p.b)))); + return Pixel(nR, nG, nB, a); + } + + Pixel& Pixel::operator += (const Pixel& p) + { + this->r = uint8_t(std::min(255, std::max(0, int(r) + int(p.r)))); + this->g = uint8_t(std::min(255, std::max(0, int(g) + int(p.g)))); + this->b = uint8_t(std::min(255, std::max(0, int(b) + int(p.b)))); + return *this; + } + + Pixel& Pixel::operator -= (const Pixel& p) // Thanks Au Lit + { + this->r = uint8_t(std::min(255, std::max(0, int(r) - int(p.r)))); + this->g = uint8_t(std::min(255, std::max(0, int(g) - int(p.g)))); + this->b = uint8_t(std::min(255, std::max(0, int(b) - int(p.b)))); + return *this; + } + + Pixel Pixel::operator * (const Pixel& p) const + { + uint8_t nR = uint8_t(std::min(255.0f, std::max(0.0f, float(r) * float(p.r) / 255.0f))); + uint8_t nG = uint8_t(std::min(255.0f, std::max(0.0f, float(g) * float(p.g) / 255.0f))); + uint8_t nB = uint8_t(std::min(255.0f, std::max(0.0f, float(b) * float(p.b) / 255.0f))); + uint8_t nA = uint8_t(std::min(255.0f, std::max(0.0f, float(a) * float(p.a) / 255.0f))); + return Pixel(nR, nG, nB, nA); + } + + Pixel& Pixel::operator *=(const Pixel& p) + { + this->r = uint8_t(std::min(255.0f, std::max(0.0f, float(r) * float(p.r) / 255.0f))); + this->g = uint8_t(std::min(255.0f, std::max(0.0f, float(g) * float(p.g) / 255.0f))); + this->b = uint8_t(std::min(255.0f, std::max(0.0f, float(b) * float(p.b) / 255.0f))); + this->a = uint8_t(std::min(255.0f, std::max(0.0f, float(a) * float(p.a) / 255.0f))); + return *this; + } + + Pixel Pixel::inv() const + { + uint8_t nR = uint8_t(std::min(255, std::max(0, 255 - int(r)))); + uint8_t nG = uint8_t(std::min(255, std::max(0, 255 - int(g)))); + uint8_t nB = uint8_t(std::min(255, std::max(0, 255 - int(b)))); + return Pixel(nR, nG, nB, a); + } + + Pixel PixelF(float red, float green, float blue, float alpha) + { return Pixel(uint8_t(red * 255.0f), uint8_t(green * 255.0f), uint8_t(blue * 255.0f), uint8_t(alpha * 255.0f)); } + + Pixel PixelLerp(const olc::Pixel& p1, const olc::Pixel& p2, float t) + { return (p2 * t) + p1 * (1.0f - t); } + + // O------------------------------------------------------------------------------O + // | olc::Sprite IMPLEMENTATION | + // O------------------------------------------------------------------------------O + Sprite::Sprite() + { width = 0; height = 0; } + + Sprite::Sprite(const std::string& sImageFile, olc::ResourcePack* pack) + { LoadFromFile(sImageFile, pack); } + + Sprite::Sprite(int32_t w, int32_t h) + { + width = w; height = h; + pColData.resize(width * height); + pColData.resize(width * height, nDefaultPixel); + } + + Sprite::~Sprite() + { pColData.clear(); } + + void Sprite::SetSampleMode(olc::Sprite::Mode mode) + { modeSample = mode; } + + Pixel Sprite::GetPixel(const olc::vi2d& a) const + { return GetPixel(a.x, a.y); } + + bool Sprite::SetPixel(const olc::vi2d& a, Pixel p) + { return SetPixel(a.x, a.y, p); } + + Pixel Sprite::GetPixel(int32_t x, int32_t y) const + { + if (modeSample == olc::Sprite::Mode::NORMAL) + { + if (x >= 0 && x < width && y >= 0 && y < height) + return pColData[y * width + x]; + else + return Pixel(0, 0, 0, 0); + } + else + { + if (modeSample == olc::Sprite::Mode::PERIODIC) + return pColData[abs(y % height) * width + abs(x % width)]; + else + return pColData[std::max(0, std::min(y, height-1)) * width + std::max(0, std::min(x, width-1))]; + } + } + + bool Sprite::SetPixel(int32_t x, int32_t y, Pixel p) + { + if (x >= 0 && x < width && y >= 0 && y < height) + { + pColData[y * width + x] = p; + return true; + } + else + return false; + } + + Pixel Sprite::Sample(float x, float y) const + { + int32_t sx = std::min((int32_t)((x * (float)width)), width - 1); + int32_t sy = std::min((int32_t)((y * (float)height)), height - 1); + return GetPixel(sx, sy); + } + + Pixel Sprite::Sample(const olc::vf2d& uv) const + { + return Sample(uv.x, uv.y); + } + + Pixel Sprite::SampleBL(float u, float v) const + { + u = u * width - 0.5f; + v = v * height - 0.5f; + int x = (int)floor(u); // cast to int rounds toward zero, not downward + int y = (int)floor(v); // Thanks @joshinils + float u_ratio = u - x; + float v_ratio = v - y; + float u_opposite = 1 - u_ratio; + float v_opposite = 1 - v_ratio; + + olc::Pixel p1 = GetPixel(std::max(x, 0), std::max(y, 0)); + olc::Pixel p2 = GetPixel(std::min(x + 1, (int)width - 1), std::max(y, 0)); + olc::Pixel p3 = GetPixel(std::max(x, 0), std::min(y + 1, (int)height - 1)); + olc::Pixel p4 = GetPixel(std::min(x + 1, (int)width - 1), std::min(y + 1, (int)height - 1)); + + return olc::Pixel( + (uint8_t)((p1.r * u_opposite + p2.r * u_ratio) * v_opposite + (p3.r * u_opposite + p4.r * u_ratio) * v_ratio), + (uint8_t)((p1.g * u_opposite + p2.g * u_ratio) * v_opposite + (p3.g * u_opposite + p4.g * u_ratio) * v_ratio), + (uint8_t)((p1.b * u_opposite + p2.b * u_ratio) * v_opposite + (p3.b * u_opposite + p4.b * u_ratio) * v_ratio)); + } + + Pixel Sprite::SampleBL(const olc::vf2d& uv) const + { + return SampleBL(uv.x, uv.y); + } + + Pixel* Sprite::GetData() + { return pColData.data(); } + + + olc::rcode Sprite::LoadFromFile(const std::string& sImageFile, olc::ResourcePack* pack) + { + UNUSED(pack); + return loader->LoadImageResource(this, sImageFile, pack); + } + + olc::Sprite* Sprite::Duplicate() + { + olc::Sprite* spr = new olc::Sprite(width, height); + std::memcpy(spr->GetData(), GetData(), width * height * sizeof(olc::Pixel)); + spr->modeSample = modeSample; + return spr; + } + + olc::Sprite* Sprite::Duplicate(const olc::vi2d& vPos, const olc::vi2d& vSize) + { + olc::Sprite* spr = new olc::Sprite(vSize.x, vSize.y); + for (int y = 0; y < vSize.y; y++) + for (int x = 0; x < vSize.x; x++) + spr->SetPixel(x, y, GetPixel(vPos.x + x, vPos.y + y)); + return spr; + } + + olc::vi2d olc::Sprite::Size() const + { + return { width, height }; + } + + // O------------------------------------------------------------------------------O + // | olc::Decal IMPLEMENTATION | + // O------------------------------------------------------------------------------O + Decal::Decal(olc::Sprite* spr, bool filter, bool clamp) + { + id = -1; + if (spr == nullptr) return; + sprite = spr; + id = renderer->CreateTexture(sprite->width, sprite->height, filter, clamp); + Update(); + } + + Decal::Decal(const uint32_t nExistingTextureResource, olc::Sprite* spr) + { + if (spr == nullptr) return; + id = nExistingTextureResource; + } + + void Decal::Update() + { + if (sprite == nullptr) return; + vUVScale = { 1.0f / float(sprite->width), 1.0f / float(sprite->height) }; + renderer->ApplyTexture(id); + renderer->UpdateTexture(id, sprite); + } + + void Decal::UpdateSprite() + { + if (sprite == nullptr) return; + renderer->ApplyTexture(id); + renderer->ReadTexture(id, sprite); + } + + Decal::~Decal() + { + if (id != -1) + { + renderer->DeleteTexture(id); + id = -1; + } + } + + void Renderable::Create(uint32_t width, uint32_t height, bool filter, bool clamp) + { + pSprite = std::make_unique(width, height); + pDecal = std::make_unique(pSprite.get(), filter, clamp); + } + + olc::rcode Renderable::Load(const std::string& sFile, ResourcePack* pack, bool filter, bool clamp) + { + pSprite = std::make_unique(); + if (pSprite->LoadFromFile(sFile, pack) == olc::rcode::OK) + { + pDecal = std::make_unique(pSprite.get(), filter, clamp); + return olc::rcode::OK; + } + else + { + pSprite.release(); + pSprite = nullptr; + return olc::rcode::NO_FILE; + } + } + + olc::Decal* Renderable::Decal() const + { return pDecal.get(); } + + olc::Sprite* Renderable::Sprite() const + { return pSprite.get(); } + + // O------------------------------------------------------------------------------O + // | olc::ResourcePack IMPLEMENTATION | + // O------------------------------------------------------------------------------O + + + //============================================================= + // Resource Packs - Allows you to store files in one large + // scrambled file - Thanks MaGetzUb for debugging a null char in std::stringstream bug + ResourceBuffer::ResourceBuffer(std::ifstream& ifs, uint32_t offset, uint32_t size) + { + vMemory.resize(size); + ifs.seekg(offset); ifs.read(vMemory.data(), vMemory.size()); + setg(vMemory.data(), vMemory.data(), vMemory.data() + size); + } + + ResourcePack::ResourcePack() { } + ResourcePack::~ResourcePack() { baseFile.close(); } + + bool ResourcePack::AddFile(const std::string& sFile) + { + const std::string file = makeposix(sFile); + + if (_gfs::exists(file)) + { + sResourceFile e; + e.nSize = (uint32_t)_gfs::file_size(file); + e.nOffset = 0; // Unknown at this stage + mapFiles[file] = e; + return true; + } + return false; + } + + bool ResourcePack::LoadPack(const std::string& sFile, const std::string& sKey) + { + // Open the resource file + baseFile.open(sFile, std::ifstream::binary); + if (!baseFile.is_open()) return false; + + // 1) Read Scrambled index + uint32_t nIndexSize = 0; + baseFile.read((char*)&nIndexSize, sizeof(uint32_t)); + + std::vector buffer(nIndexSize); + for (uint32_t j = 0; j < nIndexSize; j++) + buffer[j] = baseFile.get(); + + std::vector decoded = scramble(buffer, sKey); + size_t pos = 0; + auto read = [&decoded, &pos](char* dst, size_t size) { + memcpy((void*)dst, (const void*)(decoded.data() + pos), size); + pos += size; + }; + + auto get = [&read]() -> int { char c; read(&c, 1); return c; }; + + // 2) Read Map + uint32_t nMapEntries = 0; + read((char*)&nMapEntries, sizeof(uint32_t)); + for (uint32_t i = 0; i < nMapEntries; i++) + { + uint32_t nFilePathSize = 0; + read((char*)&nFilePathSize, sizeof(uint32_t)); + + std::string sFileName(nFilePathSize, ' '); + for (uint32_t j = 0; j < nFilePathSize; j++) + sFileName[j] = get(); + + sResourceFile e; + read((char*)&e.nSize, sizeof(uint32_t)); + read((char*)&e.nOffset, sizeof(uint32_t)); + mapFiles[sFileName] = e; + } + + // Don't close base file! we will provide a stream + // pointer when the file is requested + return true; + } + + bool ResourcePack::SavePack(const std::string& sFile, const std::string& sKey) + { + // Create/Overwrite the resource file + std::ofstream ofs(sFile, std::ofstream::binary); + if (!ofs.is_open()) return false; + + // Iterate through map + uint32_t nIndexSize = 0; // Unknown for now + ofs.write((char*)&nIndexSize, sizeof(uint32_t)); + uint32_t nMapSize = uint32_t(mapFiles.size()); + ofs.write((char*)&nMapSize, sizeof(uint32_t)); + for (auto& e : mapFiles) + { + // Write the path of the file + size_t nPathSize = e.first.size(); + ofs.write((char*)&nPathSize, sizeof(uint32_t)); + ofs.write(e.first.c_str(), nPathSize); + + // Write the file entry properties + ofs.write((char*)&e.second.nSize, sizeof(uint32_t)); + ofs.write((char*)&e.second.nOffset, sizeof(uint32_t)); + } + + // 2) Write the individual Data + std::streampos offset = ofs.tellp(); + nIndexSize = (uint32_t)offset; + for (auto& e : mapFiles) + { + // Store beginning of file offset within resource pack file + e.second.nOffset = (uint32_t)offset; + + // Load the file to be added + std::vector vBuffer(e.second.nSize); + std::ifstream i(e.first, std::ifstream::binary); + i.read((char*)vBuffer.data(), e.second.nSize); + i.close(); + + // Write the loaded file into resource pack file + ofs.write((char*)vBuffer.data(), e.second.nSize); + offset += e.second.nSize; + } + + // 3) Scramble Index + std::vector stream; + auto write = [&stream](const char* data, size_t size) { + size_t sizeNow = stream.size(); + stream.resize(sizeNow + size); + memcpy(stream.data() + sizeNow, data, size); + }; + + // Iterate through map + write((char*)&nMapSize, sizeof(uint32_t)); + for (auto& e : mapFiles) + { + // Write the path of the file + size_t nPathSize = e.first.size(); + write((char*)&nPathSize, sizeof(uint32_t)); + write(e.first.c_str(), nPathSize); + + // Write the file entry properties + write((char*)&e.second.nSize, sizeof(uint32_t)); + write((char*)&e.second.nOffset, sizeof(uint32_t)); + } + std::vector sIndexString = scramble(stream, sKey); + uint32_t nIndexStringLen = uint32_t(sIndexString.size()); + // 4) Rewrite Map (it has been updated with offsets now) + // at start of file + ofs.seekp(0, std::ios::beg); + ofs.write((char*)&nIndexStringLen, sizeof(uint32_t)); + ofs.write(sIndexString.data(), nIndexStringLen); + ofs.close(); + return true; + } + + ResourceBuffer ResourcePack::GetFileBuffer(const std::string& sFile) + { return ResourceBuffer(baseFile, mapFiles[sFile].nOffset, mapFiles[sFile].nSize); } + + bool ResourcePack::Loaded() + { return baseFile.is_open(); } + + std::vector ResourcePack::scramble(const std::vector& data, const std::string& key) + { + if (key.empty()) return data; + std::vector o; + size_t c = 0; + for (auto s : data) o.push_back(s ^ key[(c++) % key.size()]); + return o; + }; + + std::string ResourcePack::makeposix(const std::string& path) + { + std::string o; + for (auto s : path) o += std::string(1, s == '\\' ? '/' : s); + return o; + }; + + // O------------------------------------------------------------------------------O + // | olc::PixelGameEngine IMPLEMENTATION | + // O------------------------------------------------------------------------------O + PixelGameEngine::PixelGameEngine() + { + sAppName = "Undefined"; + olc::PGEX::pge = this; + + // Bring in relevant Platform & Rendering systems depending + // on compiler parameters + olc_ConfigureSystem(); + } + + PixelGameEngine::~PixelGameEngine() + {} + + + olc::rcode PixelGameEngine::Construct(int32_t screen_w, int32_t screen_h, int32_t pixel_w, int32_t pixel_h, bool full_screen, bool vsync, bool cohesion) + { + bPixelCohesion = cohesion; + vScreenSize = { screen_w, screen_h }; + vInvScreenSize = { 1.0f / float(screen_w), 1.0f / float(screen_h) }; + vPixelSize = { pixel_w, pixel_h }; + vWindowSize = vScreenSize * vPixelSize; + bFullScreen = full_screen; + bEnableVSYNC = vsync; + vPixel = 2.0f / vScreenSize; + + if (vPixelSize.x <= 0 || vPixelSize.y <= 0 || vScreenSize.x <= 0 || vScreenSize.y <= 0) + return olc::FAIL; + return olc::OK; + } + + + void PixelGameEngine::SetScreenSize(int w, int h) + { + vScreenSize = { w, h }; + vInvScreenSize = { 1.0f / float(w), 1.0f / float(h) }; + for (auto& layer : vLayers) + { + layer.pDrawTarget.Create(vScreenSize.x, vScreenSize.y); + layer.bUpdate = true; + } + SetDrawTarget(nullptr); + renderer->ClearBuffer(olc::BLACK, true); + renderer->DisplayFrame(); + renderer->ClearBuffer(olc::BLACK, true); + renderer->UpdateViewport(vViewPos, vViewSize); + } + +#if !defined(PGE_USE_CUSTOM_START) + olc::rcode PixelGameEngine::Start() + { + if (platform->ApplicationStartUp() != olc::OK) return olc::FAIL; + + // Construct the window + if (platform->CreateWindowPane({ 30,30 }, vWindowSize, bFullScreen) != olc::OK) return olc::FAIL; + olc_UpdateWindowSize(vWindowSize.x, vWindowSize.y); + + // Start the thread + bAtomActive = true; + std::thread t = std::thread(&PixelGameEngine::EngineThread, this); + + // Some implementations may form an event loop here + platform->StartSystemEventLoop(); + + // Wait for thread to be exited + t.join(); + + if (platform->ApplicationCleanUp() != olc::OK) return olc::FAIL; + + return olc::OK; + } +#endif + + void PixelGameEngine::SetDrawTarget(Sprite* target) + { + if (target) + { + pDrawTarget = target; + } + else + { + nTargetLayer = 0; + pDrawTarget = vLayers[0].pDrawTarget.Sprite(); + } + } + + void PixelGameEngine::SetDrawTarget(uint8_t layer, bool bDirty) + { + if (layer < vLayers.size()) + { + pDrawTarget = vLayers[layer].pDrawTarget.Sprite(); + vLayers[layer].bUpdate = bDirty; + nTargetLayer = layer; + } + } + + void PixelGameEngine::EnableLayer(uint8_t layer, bool b) + { if (layer < vLayers.size()) vLayers[layer].bShow = b; } + + void PixelGameEngine::SetLayerOffset(uint8_t layer, const olc::vf2d& offset) + { SetLayerOffset(layer, offset.x, offset.y); } + + void PixelGameEngine::SetLayerOffset(uint8_t layer, float x, float y) + { if (layer < vLayers.size()) vLayers[layer].vOffset = { x, y }; } + + void PixelGameEngine::SetLayerScale(uint8_t layer, const olc::vf2d& scale) + { SetLayerScale(layer, scale.x, scale.y); } + + void PixelGameEngine::SetLayerScale(uint8_t layer, float x, float y) + { if (layer < vLayers.size()) vLayers[layer].vScale = { x, y }; } + + void PixelGameEngine::SetLayerTint(uint8_t layer, const olc::Pixel& tint) + { if (layer < vLayers.size()) vLayers[layer].tint = tint; } + + void PixelGameEngine::SetLayerCustomRenderFunction(uint8_t layer, std::function f) + { if (layer < vLayers.size()) vLayers[layer].funcHook = f; } + + std::vector& PixelGameEngine::GetLayers() + { return vLayers; } + + uint32_t PixelGameEngine::CreateLayer() + { + LayerDesc ld; + ld.pDrawTarget.Create(vScreenSize.x, vScreenSize.y); + vLayers.push_back(std::move(ld)); + return uint32_t(vLayers.size()) - 1; + } + + Sprite* PixelGameEngine::GetDrawTarget() const + { return pDrawTarget; } + + int32_t PixelGameEngine::GetDrawTargetWidth() const + { + if (pDrawTarget) + return pDrawTarget->width; + else + return 0; + } + + int32_t PixelGameEngine::GetDrawTargetHeight() const + { + if (pDrawTarget) + return pDrawTarget->height; + else + return 0; + } + + uint32_t PixelGameEngine::GetFPS() const + { return nLastFPS; } + + bool PixelGameEngine::IsFocused() const + { return bHasInputFocus; } + + HWButton PixelGameEngine::GetKey(Key k) const + { return pKeyboardState[k]; } + + HWButton PixelGameEngine::GetMouse(uint32_t b) const + { return pMouseState[b]; } + + int32_t PixelGameEngine::GetMouseX() const + { return vMousePos.x; } + + int32_t PixelGameEngine::GetMouseY() const + { return vMousePos.y; } + + const olc::vi2d& PixelGameEngine::GetMousePos() const + { return vMousePos; } + + int32_t PixelGameEngine::GetMouseWheel() const + { return nMouseWheelDelta; } + + int32_t PixelGameEngine::ScreenWidth() const + { return vScreenSize.x; } + + int32_t PixelGameEngine::ScreenHeight() const + { return vScreenSize.y; } + + float PixelGameEngine::GetElapsedTime() const + { return fLastElapsed; } + + const olc::vi2d& PixelGameEngine::GetWindowSize() const + { return vWindowSize; } + + const olc::vi2d& PixelGameEngine::GetPixelSize() const + { return vPixelSize; } + + const olc::vi2d& PixelGameEngine::GetScreenPixelSize() const + { return vScreenPixelSize; } + + const olc::vi2d& PixelGameEngine::GetScreenSize() const + { return vScreenSize; } + + const olc::vi2d& PixelGameEngine::GetWindowMouse() const + { return vMouseWindowPos; } + + bool PixelGameEngine::Draw(const olc::vi2d& pos, Pixel p) + { return Draw(pos.x, pos.y, p); } + + // This is it, the critical function that plots a pixel + bool PixelGameEngine::Draw(int32_t x, int32_t y, Pixel p) + { + if (!pDrawTarget) return false; + + if (nPixelMode == Pixel::NORMAL) + { + return pDrawTarget->SetPixel(x, y, p); + } + + if (nPixelMode == Pixel::MASK) + { + if (p.a == 255) + return pDrawTarget->SetPixel(x, y, p); + } + + if (nPixelMode == Pixel::ALPHA) + { + Pixel d = pDrawTarget->GetPixel(x, y); + float a = (float)(p.a / 255.0f) * fBlendFactor; + float c = 1.0f - a; + float r = a * (float)p.r + c * (float)d.r; + float g = a * (float)p.g + c * (float)d.g; + float b = a * (float)p.b + c * (float)d.b; + return pDrawTarget->SetPixel(x, y, Pixel((uint8_t)r, (uint8_t)g, (uint8_t)b/*, (uint8_t)(p.a * fBlendFactor)*/)); + } + + if (nPixelMode == Pixel::CUSTOM) + { + return pDrawTarget->SetPixel(x, y, funcPixelMode(x, y, p, pDrawTarget->GetPixel(x, y))); + } + + return false; + } + + + void PixelGameEngine::DrawLine(const olc::vi2d& pos1, const olc::vi2d& pos2, Pixel p, uint32_t pattern) + { DrawLine(pos1.x, pos1.y, pos2.x, pos2.y, p, pattern); } + + void PixelGameEngine::DrawLine(int32_t x1, int32_t y1, int32_t x2, int32_t y2, Pixel p, uint32_t pattern) + { + int x, y, dx, dy, dx1, dy1, px, py, xe, ye, i; + dx = x2 - x1; dy = y2 - y1; + + auto rol = [&](void) { pattern = (pattern << 1) | (pattern >> 31); return pattern & 1; }; + + olc::vi2d p1(x1, y1), p2(x2, y2); + if (!ClipLineToScreen(p1, p2)) + return; + x1 = p1.x; y1 = p1.y; + x2 = p2.x; y2 = p2.y; + + // straight lines idea by gurkanctn + if (dx == 0) // Line is vertical + { + if (y2 < y1) std::swap(y1, y2); + for (y = y1; y <= y2; y++) if (rol()) Draw(x1, y, p); + return; + } + + if (dy == 0) // Line is horizontal + { + if (x2 < x1) std::swap(x1, x2); + for (x = x1; x <= x2; x++) if (rol()) Draw(x, y1, p); + return; + } + + // Line is Funk-aye + dx1 = abs(dx); dy1 = abs(dy); + px = 2 * dy1 - dx1; py = 2 * dx1 - dy1; + if (dy1 <= dx1) + { + if (dx >= 0) + { + x = x1; y = y1; xe = x2; + } + else + { + x = x2; y = y2; xe = x1; + } + + if (rol()) Draw(x, y, p); + + for (i = 0; x < xe; i++) + { + x = x + 1; + if (px < 0) + px = px + 2 * dy1; + else + { + if ((dx < 0 && dy < 0) || (dx > 0 && dy > 0)) y = y + 1; else y = y - 1; + px = px + 2 * (dy1 - dx1); + } + if (rol()) Draw(x, y, p); + } + } + else + { + if (dy >= 0) + { + x = x1; y = y1; ye = y2; + } + else + { + x = x2; y = y2; ye = y1; + } + + if (rol()) Draw(x, y, p); + + for (i = 0; y < ye; i++) + { + y = y + 1; + if (py <= 0) + py = py + 2 * dx1; + else + { + if ((dx < 0 && dy < 0) || (dx > 0 && dy > 0)) x = x + 1; else x = x - 1; + py = py + 2 * (dx1 - dy1); + } + if (rol()) Draw(x, y, p); + } + } + } + + void PixelGameEngine::DrawCircle(const olc::vi2d& pos, int32_t radius, Pixel p, uint8_t mask) + { DrawCircle(pos.x, pos.y, radius, p, mask); } + + void PixelGameEngine::DrawCircle(int32_t x, int32_t y, int32_t radius, Pixel p, uint8_t mask) + { // Thanks to IanM-Matrix1 #PR121 + if (radius < 0 || x < -radius || y < -radius || x - GetDrawTargetWidth() > radius || y - GetDrawTargetHeight() > radius) + return; + + if (radius > 0) + { + int x0 = 0; + int y0 = radius; + int d = 3 - 2 * radius; + + while (y0 >= x0) // only formulate 1/8 of circle + { + // Draw even octants + if (mask & 0x01) Draw(x + x0, y - y0, p);// Q6 - upper right right + if (mask & 0x04) Draw(x + y0, y + x0, p);// Q4 - lower lower right + if (mask & 0x10) Draw(x - x0, y + y0, p);// Q2 - lower left left + if (mask & 0x40) Draw(x - y0, y - x0, p);// Q0 - upper upper left + if (x0 != 0 && x0 != y0) + { + if (mask & 0x02) Draw(x + y0, y - x0, p);// Q7 - upper upper right + if (mask & 0x08) Draw(x + x0, y + y0, p);// Q5 - lower right right + if (mask & 0x20) Draw(x - y0, y + x0, p);// Q3 - lower lower left + if (mask & 0x80) Draw(x - x0, y - y0, p);// Q1 - upper left left + } + + if (d < 0) + d += 4 * x0++ + 6; + else + d += 4 * (x0++ - y0--) + 10; + } + } + else + Draw(x, y, p); + } + + void PixelGameEngine::FillCircle(const olc::vi2d& pos, int32_t radius, Pixel p) + { FillCircle(pos.x, pos.y, radius, p); } + + void PixelGameEngine::FillCircle(int32_t x, int32_t y, int32_t radius, Pixel p) + { // Thanks to IanM-Matrix1 #PR121 + if (radius < 0 || x < -radius || y < -radius || x - GetDrawTargetWidth() > radius || y - GetDrawTargetHeight() > radius) + return; + + if (radius > 0) + { + int x0 = 0; + int y0 = radius; + int d = 3 - 2 * radius; + + auto drawline = [&](int sx, int ex, int y) + { + for (int x = sx; x <= ex; x++) + Draw(x, y, p); + }; + + while (y0 >= x0) + { + drawline(x - y0, x + y0, y - x0); + if (x0 > 0) drawline(x - y0, x + y0, y + x0); + + if (d < 0) + d += 4 * x0++ + 6; + else + { + if (x0 != y0) + { + drawline(x - x0, x + x0, y - y0); + drawline(x - x0, x + x0, y + y0); + } + d += 4 * (x0++ - y0--) + 10; + } + } + } + else + Draw(x, y, p); + } + + void PixelGameEngine::DrawRect(const olc::vi2d& pos, const olc::vi2d& size, Pixel p) + { DrawRect(pos.x, pos.y, size.x, size.y, p); } + + void PixelGameEngine::DrawRect(int32_t x, int32_t y, int32_t w, int32_t h, Pixel p) + { + DrawLine(x, y, x + w, y, p); + DrawLine(x + w, y, x + w, y + h, p); + DrawLine(x + w, y + h, x, y + h, p); + DrawLine(x, y + h, x, y, p); + } + + void PixelGameEngine::Clear(Pixel p) + { + int pixels = GetDrawTargetWidth() * GetDrawTargetHeight(); + Pixel* m = GetDrawTarget()->GetData(); + for (int i = 0; i < pixels; i++) m[i] = p; + } + + void PixelGameEngine::ClearBuffer(Pixel p, bool bDepth) + { renderer->ClearBuffer(p, bDepth); } + + olc::Sprite* PixelGameEngine::GetFontSprite() + { return fontRenderable.Sprite(); } + + bool PixelGameEngine::ClipLineToScreen(olc::vi2d& in_p1, olc::vi2d& in_p2) + { + // https://en.wikipedia.org/wiki/Cohen%E2%80%93Sutherland_algorithm + static constexpr int SEG_I = 0b0000, SEG_L = 0b0001, SEG_R = 0b0010, SEG_B = 0b0100, SEG_T = 0b1000; + auto Segment = [&vScreenSize = vScreenSize](const olc::vi2d& v) + { + int i = SEG_I; + if (v.x < 0) i |= SEG_L; else if (v.x > vScreenSize.x) i |= SEG_R; + if (v.y < 0) i |= SEG_B; else if (v.y > vScreenSize.y) i |= SEG_T; + return i; + }; + + int s1 = Segment(in_p1), s2 = Segment(in_p2); + + while (true) + { + if (!(s1 | s2)) return true; + else if (s1 & s2) return false; + else + { + int s3 = s2 > s1 ? s2 : s1; + olc::vi2d n; + if (s3 & SEG_T) { n.x = in_p1.x + (in_p2.x - in_p1.x) * (vScreenSize.y - in_p1.y) / (in_p2.y - in_p1.y); n.y = vScreenSize.y; } + else if (s3 & SEG_B) { n.x = in_p1.x + (in_p2.x - in_p1.x) * (0 - in_p1.y) / (in_p2.y - in_p1.y); n.y = 0; } + else if (s3 & SEG_R) { n.x = vScreenSize.x; n.y = in_p1.y + (in_p2.y - in_p1.y) * (vScreenSize.x - in_p1.x) / (in_p2.x - in_p1.x); } + else if (s3 & SEG_L) { n.x = 0; n.y = in_p1.y + (in_p2.y - in_p1.y) * (0 - in_p1.x) / (in_p2.x - in_p1.x); } + if (s3 == s1) { in_p1 = n; s1 = Segment(in_p1); } + else { in_p2 = n; s2 = Segment(in_p2); } + } + } + return true; + } + + void PixelGameEngine::EnablePixelTransfer(const bool bEnable) + { + bSuspendTextureTransfer = !bEnable; + } + + + void PixelGameEngine::FillRect(const olc::vi2d& pos, const olc::vi2d& size, Pixel p) + { FillRect(pos.x, pos.y, size.x, size.y, p); } + + void PixelGameEngine::FillRect(int32_t x, int32_t y, int32_t w, int32_t h, Pixel p) + { + int32_t x2 = x + w; + int32_t y2 = y + h; + + if (x < 0) x = 0; + if (x >= (int32_t)GetDrawTargetWidth()) x = (int32_t)GetDrawTargetWidth(); + if (y < 0) y = 0; + if (y >= (int32_t)GetDrawTargetHeight()) y = (int32_t)GetDrawTargetHeight(); + + if (x2 < 0) x2 = 0; + if (x2 >= (int32_t)GetDrawTargetWidth()) x2 = (int32_t)GetDrawTargetWidth(); + if (y2 < 0) y2 = 0; + if (y2 >= (int32_t)GetDrawTargetHeight()) y2 = (int32_t)GetDrawTargetHeight(); + + for (int i = x; i < x2; i++) + for (int j = y; j < y2; j++) + Draw(i, j, p); + } + + void PixelGameEngine::DrawTriangle(const olc::vi2d& pos1, const olc::vi2d& pos2, const olc::vi2d& pos3, Pixel p) + { DrawTriangle(pos1.x, pos1.y, pos2.x, pos2.y, pos3.x, pos3.y, p); } + + void PixelGameEngine::DrawTriangle(int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t x3, int32_t y3, Pixel p) + { + DrawLine(x1, y1, x2, y2, p); + DrawLine(x2, y2, x3, y3, p); + DrawLine(x3, y3, x1, y1, p); + } + + void PixelGameEngine::FillTriangle(const olc::vi2d& pos1, const olc::vi2d& pos2, const olc::vi2d& pos3, Pixel p) + { FillTriangle(pos1.x, pos1.y, pos2.x, pos2.y, pos3.x, pos3.y, p); } + + // https://www.avrfreaks.net/sites/default/files/triangles.c + void PixelGameEngine::FillTriangle(int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t x3, int32_t y3, Pixel p) + { + auto drawline = [&](int sx, int ex, int ny) { for (int i = sx; i <= ex; i++) Draw(i, ny, p); }; + + int t1x, t2x, y, minx, maxx, t1xp, t2xp; + bool changed1 = false; + bool changed2 = false; + int signx1, signx2, dx1, dy1, dx2, dy2; + int e1, e2; + // Sort vertices + if (y1 > y2) { std::swap(y1, y2); std::swap(x1, x2); } + if (y1 > y3) { std::swap(y1, y3); std::swap(x1, x3); } + if (y2 > y3) { std::swap(y2, y3); std::swap(x2, x3); } + + t1x = t2x = x1; y = y1; // Starting points + dx1 = (int)(x2 - x1); + if (dx1 < 0) { dx1 = -dx1; signx1 = -1; } + else signx1 = 1; + dy1 = (int)(y2 - y1); + + dx2 = (int)(x3 - x1); + if (dx2 < 0) { dx2 = -dx2; signx2 = -1; } + else signx2 = 1; + dy2 = (int)(y3 - y1); + + if (dy1 > dx1) { std::swap(dx1, dy1); changed1 = true; } + if (dy2 > dx2) { std::swap(dy2, dx2); changed2 = true; } + + e2 = (int)(dx2 >> 1); + // Flat top, just process the second half + if (y1 == y2) goto next; + e1 = (int)(dx1 >> 1); + + for (int i = 0; i < dx1;) { + t1xp = 0; t2xp = 0; + if (t1x < t2x) { minx = t1x; maxx = t2x; } + else { minx = t2x; maxx = t1x; } + // process first line until y value is about to change + while (i < dx1) { + i++; + e1 += dy1; + while (e1 >= dx1) { + e1 -= dx1; + if (changed1) t1xp = signx1;//t1x += signx1; + else goto next1; + } + if (changed1) break; + else t1x += signx1; + } + // Move line + next1: + // process second line until y value is about to change + while (1) { + e2 += dy2; + while (e2 >= dx2) { + e2 -= dx2; + if (changed2) t2xp = signx2;//t2x += signx2; + else goto next2; + } + if (changed2) break; + else t2x += signx2; + } + next2: + if (minx > t1x) minx = t1x; + if (minx > t2x) minx = t2x; + if (maxx < t1x) maxx = t1x; + if (maxx < t2x) maxx = t2x; + drawline(minx, maxx, y); // Draw line from min to max points found on the y + // Now increase y + if (!changed1) t1x += signx1; + t1x += t1xp; + if (!changed2) t2x += signx2; + t2x += t2xp; + y += 1; + if (y == y2) break; + } + next: + // Second half + dx1 = (int)(x3 - x2); if (dx1 < 0) { dx1 = -dx1; signx1 = -1; } + else signx1 = 1; + dy1 = (int)(y3 - y2); + t1x = x2; + + if (dy1 > dx1) { // swap values + std::swap(dy1, dx1); + changed1 = true; + } + else changed1 = false; + + e1 = (int)(dx1 >> 1); + + for (int i = 0; i <= dx1; i++) { + t1xp = 0; t2xp = 0; + if (t1x < t2x) { minx = t1x; maxx = t2x; } + else { minx = t2x; maxx = t1x; } + // process first line until y value is about to change + while (i < dx1) { + e1 += dy1; + while (e1 >= dx1) { + e1 -= dx1; + if (changed1) { t1xp = signx1; break; }//t1x += signx1; + else goto next3; + } + if (changed1) break; + else t1x += signx1; + if (i < dx1) i++; + } + next3: + // process second line until y value is about to change + while (t2x != x3) { + e2 += dy2; + while (e2 >= dx2) { + e2 -= dx2; + if (changed2) t2xp = signx2; + else goto next4; + } + if (changed2) break; + else t2x += signx2; + } + next4: + + if (minx > t1x) minx = t1x; + if (minx > t2x) minx = t2x; + if (maxx < t1x) maxx = t1x; + if (maxx < t2x) maxx = t2x; + drawline(minx, maxx, y); + if (!changed1) t1x += signx1; + t1x += t1xp; + if (!changed2) t2x += signx2; + t2x += t2xp; + y += 1; + if (y > y3) return; + } + } + + void PixelGameEngine::FillTexturedTriangle(std::vector vPoints, std::vector vTex, std::vector vColour, olc::Sprite* sprTex) + { + olc::vi2d p1 = vPoints[0]; + olc::vi2d p2 = vPoints[1]; + olc::vi2d p3 = vPoints[2]; + + if (p2.y < p1.y){std::swap(p1.y, p2.y); std::swap(p1.x, p2.x); std::swap(vTex[0].x, vTex[1].x); std::swap(vTex[0].y, vTex[1].y); std::swap(vColour[0], vColour[1]);} + if (p3.y < p1.y){std::swap(p1.y, p3.y); std::swap(p1.x, p3.x); std::swap(vTex[0].x, vTex[2].x); std::swap(vTex[0].y, vTex[2].y); std::swap(vColour[0], vColour[2]);} + if (p3.y < p2.y){std::swap(p2.y, p3.y); std::swap(p2.x, p3.x); std::swap(vTex[1].x, vTex[2].x); std::swap(vTex[1].y, vTex[2].y); std::swap(vColour[1], vColour[2]);} + + olc::vi2d dPos1 = p2 - p1; + olc::vf2d dTex1 = vTex[1] - vTex[0]; + int dcr1 = vColour[1].r - vColour[0].r; + int dcg1 = vColour[1].g - vColour[0].g; + int dcb1 = vColour[1].b - vColour[0].b; + int dca1 = vColour[1].a - vColour[0].a; + + olc::vi2d dPos2 = p3 - p1; + olc::vf2d dTex2 = vTex[2] - vTex[0]; + int dcr2 = vColour[2].r - vColour[0].r; + int dcg2 = vColour[2].g - vColour[0].g; + int dcb2 = vColour[2].b - vColour[0].b; + int dca2 = vColour[2].a - vColour[0].a; + + float dax_step = 0, dbx_step = 0, dcr1_step = 0, dcr2_step = 0, dcg1_step = 0, dcg2_step = 0, dcb1_step = 0, dcb2_step = 0, dca1_step = 0, dca2_step = 0; + olc::vf2d vTex1Step, vTex2Step; + + if (dPos1.y) + { + dax_step = dPos1.x / (float)abs(dPos1.y); + vTex1Step = dTex1 / (float)abs(dPos1.y); + dcr1_step = dcr1 / (float)abs(dPos1.y); + dcg1_step = dcg1 / (float)abs(dPos1.y); + dcb1_step = dcb1 / (float)abs(dPos1.y); + dca1_step = dca1 / (float)abs(dPos1.y); + } + + if (dPos2.y) + { + dbx_step = dPos2.x / (float)abs(dPos2.y); + vTex2Step = dTex2 / (float)abs(dPos2.y); + dcr2_step = dcr2 / (float)abs(dPos2.y); + dcg2_step = dcg2 / (float)abs(dPos2.y); + dcb2_step = dcb2 / (float)abs(dPos2.y); + dca2_step = dca2 / (float)abs(dPos2.y); + } + + olc::vi2d vStart; + olc::vi2d vEnd; + int vStartIdx; + + for (int pass = 0; pass < 2; pass++) + { + if (pass == 0) + { + vStart = p1; vEnd = p2; vStartIdx = 0; + } + else + { + dPos1 = p3 - p2; + dTex1 = vTex[2] - vTex[1]; + dcr1 = vColour[2].r - vColour[1].r; + dcg1 = vColour[2].g - vColour[1].g; + dcb1 = vColour[2].b - vColour[1].b; + dca1 = vColour[2].a - vColour[1].a; + dcr1_step = 0; dcg1_step = 0; dcb1_step = 0; dca1_step = 0; + + if (dPos2.y) dbx_step = dPos2.x / (float)abs(dPos2.y); + if (dPos1.y) + { + dax_step = dPos1.x / (float)abs(dPos1.y); + vTex1Step = dTex1 / (float)abs(dPos1.y); + dcr1_step = dcr1 / (float)abs(dPos1.y); + dcg1_step = dcg1 / (float)abs(dPos1.y); + dcb1_step = dcb1 / (float)abs(dPos1.y); + dca1_step = dca1 / (float)abs(dPos1.y); + } + + vStart = p2; vEnd = p3; vStartIdx = 1; + } + + if (dPos1.y) + { + for (int i = vStart.y; i <= vEnd.y; i++) + { + int ax = int(vStart.x + (float)(i - vStart.y) * dax_step); + int bx = int(p1.x + (float)(i - p1.y) * dbx_step); + + olc::vf2d tex_s(vTex[vStartIdx].x + (float)(i - vStart.y) * vTex1Step.x, vTex[vStartIdx].y + (float)(i - vStart.y) * vTex1Step.y); + olc::vf2d tex_e(vTex[0].x + (float)(i - p1.y) * vTex2Step.x, vTex[0].y + (float)(i - p1.y) * vTex2Step.y); + + olc::Pixel col_s(vColour[vStartIdx].r + uint8_t((float)(i - vStart.y) * dcr1_step), vColour[vStartIdx].g + uint8_t((float)(i - vStart.y) * dcg1_step), + vColour[vStartIdx].b + uint8_t((float)(i - vStart.y) * dcb1_step), vColour[vStartIdx].a + uint8_t((float)(i - vStart.y) * dca1_step)); + + olc::Pixel col_e(vColour[0].r + uint8_t((float)(i - p1.y) * dcr2_step), vColour[0].g + uint8_t((float)(i - p1.y) * dcg2_step), + vColour[0].b + uint8_t((float)(i - p1.y) * dcb2_step), vColour[0].a + uint8_t((float)(i - p1.y) * dca2_step)); + + if (ax > bx) { std::swap(ax, bx); std::swap(tex_s, tex_e); std::swap(col_s, col_e); } + + float tstep = 1.0f / ((float)(bx - ax)); + float t = 0.0f; + + for (int j = ax; j < bx; j++) + { + olc::Pixel pixel = PixelLerp(col_s, col_e, t); + if (sprTex != nullptr) pixel *= sprTex->Sample(tex_s.lerp(tex_e, t)); + Draw(j, i, pixel); + t += tstep; + } + } + } + } + } + + void PixelGameEngine::FillTexturedPolygon(const std::vector& vPoints, const std::vector& vTex, const std::vector& vColour, olc::Sprite* sprTex, olc::DecalStructure structure) + { + if (structure == olc::DecalStructure::LINE) + { + return; // Meaningless, so do nothing + } + + if (vPoints.size() < 3 || vTex.size() < 3 || vColour.size() < 3) + return; + + if (structure == olc::DecalStructure::LIST) + { + for (int tri = 0; tri < vPoints.size() / 3; tri++) + { + std::vector vP = { vPoints[tri * 3 + 0], vPoints[tri * 3 + 1], vPoints[tri * 3 + 2] }; + std::vector vT = { vTex[tri * 3 + 0], vTex[tri * 3 + 1], vTex[tri * 3 + 2] }; + std::vector vC = { vColour[tri * 3 + 0], vColour[tri * 3 + 1], vColour[tri * 3 + 2] }; + FillTexturedTriangle(vP, vT, vC, sprTex); + } + return; + } + + if (structure == olc::DecalStructure::STRIP) + { + for (int tri = 2; tri < vPoints.size(); tri++) + { + std::vector vP = { vPoints[tri - 2], vPoints[tri-1], vPoints[tri] }; + std::vector vT = { vTex[tri - 2], vTex[tri - 1], vTex[tri] }; + std::vector vC = { vColour[tri - 2], vColour[tri - 1], vColour[tri] }; + FillTexturedTriangle(vP, vT, vC, sprTex); + } + return; + } + + if (structure == olc::DecalStructure::FAN) + { + for (int tri = 2; tri < vPoints.size(); tri++) + { + std::vector vP = { vPoints[0], vPoints[tri - 1], vPoints[tri] }; + std::vector vT = { vTex[0], vTex[tri - 1], vTex[tri] }; + std::vector vC = { vColour[0], vColour[tri - 1], vColour[tri] }; + FillTexturedTriangle(vP, vT, vC, sprTex); + } + return; + } + } + + + void PixelGameEngine::DrawSprite(const olc::vi2d& pos, Sprite* sprite, uint32_t scale, uint8_t flip) + { DrawSprite(pos.x, pos.y, sprite, scale, flip); } + + void PixelGameEngine::DrawSprite(int32_t x, int32_t y, Sprite* sprite, uint32_t scale, uint8_t flip) + { + if (sprite == nullptr) + return; + + int32_t fxs = 0, fxm = 1, fx = 0; + int32_t fys = 0, fym = 1, fy = 0; + if (flip & olc::Sprite::Flip::HORIZ) { fxs = sprite->width - 1; fxm = -1; } + if (flip & olc::Sprite::Flip::VERT) { fys = sprite->height - 1; fym = -1; } + + if (scale > 1) + { + fx = fxs; + for (int32_t i = 0; i < sprite->width; i++, fx += fxm) + { + fy = fys; + for (int32_t j = 0; j < sprite->height; j++, fy += fym) + for (uint32_t is = 0; is < scale; is++) + for (uint32_t js = 0; js < scale; js++) + Draw(x + (i * scale) + is, y + (j * scale) + js, sprite->GetPixel(fx, fy)); + } + } + else + { + fx = fxs; + for (int32_t i = 0; i < sprite->width; i++, fx += fxm) + { + fy = fys; + for (int32_t j = 0; j < sprite->height; j++, fy += fym) + Draw(x + i, y + j, sprite->GetPixel(fx, fy)); + } + } + } + + void PixelGameEngine::DrawPartialSprite(const olc::vi2d& pos, Sprite* sprite, const olc::vi2d& sourcepos, const olc::vi2d& size, uint32_t scale, uint8_t flip) + { DrawPartialSprite(pos.x, pos.y, sprite, sourcepos.x, sourcepos.y, size.x, size.y, scale, flip); } + + void PixelGameEngine::DrawPartialSprite(int32_t x, int32_t y, Sprite* sprite, int32_t ox, int32_t oy, int32_t w, int32_t h, uint32_t scale, uint8_t flip) + { + if (sprite == nullptr) + return; + + int32_t fxs = 0, fxm = 1, fx = 0; + int32_t fys = 0, fym = 1, fy = 0; + if (flip & olc::Sprite::Flip::HORIZ) { fxs = w - 1; fxm = -1; } + if (flip & olc::Sprite::Flip::VERT) { fys = h - 1; fym = -1; } + + if (scale > 1) + { + fx = fxs; + for (int32_t i = 0; i < w; i++, fx += fxm) + { + fy = fys; + for (int32_t j = 0; j < h; j++, fy += fym) + for (uint32_t is = 0; is < scale; is++) + for (uint32_t js = 0; js < scale; js++) + Draw(x + (i * scale) + is, y + (j * scale) + js, sprite->GetPixel(fx + ox, fy + oy)); + } + } + else + { + fx = fxs; + for (int32_t i = 0; i < w; i++, fx += fxm) + { + fy = fys; + for (int32_t j = 0; j < h; j++, fy += fym) + Draw(x + i, y + j, sprite->GetPixel(fx + ox, fy + oy)); + } + } + } + + void PixelGameEngine::SetDecalMode(const olc::DecalMode& mode) + { nDecalMode = mode; } + + void PixelGameEngine::SetDecalStructure(const olc::DecalStructure& structure) + { nDecalStructure = structure; } + + void PixelGameEngine::DrawPartialDecal(const olc::vf2d& pos, olc::Decal* decal, const olc::vf2d& source_pos, const olc::vf2d& source_size, const olc::vf2d& scale, const olc::Pixel& tint) + { + olc::vf2d vScreenSpacePos = + { + (pos.x * vInvScreenSize.x) * 2.0f - 1.0f, + -((pos.y * vInvScreenSize.y) * 2.0f - 1.0f) + }; + + + olc::vf2d vScreenSpaceDim = + { + ((pos.x + source_size.x * scale.x) * vInvScreenSize.x) * 2.0f - 1.0f, + -(((pos.y + source_size.y * scale.y) * vInvScreenSize.y) * 2.0f - 1.0f) + }; + + olc::vf2d vWindow = olc::vf2d(vViewSize); + olc::vf2d vQuantisedPos = ((vScreenSpacePos * vWindow) + olc::vf2d(0.5f, 0.5f)).floor() / vWindow; + olc::vf2d vQuantisedDim = ((vScreenSpaceDim * vWindow) + olc::vf2d(0.5f, -0.5f)).ceil() / vWindow; + + DecalInstance di; + di.points = 4; + di.decal = decal; + di.tint = { tint, tint, tint, tint }; + di.pos = { { vQuantisedPos.x, vQuantisedPos.y }, { vQuantisedPos.x, vQuantisedDim.y }, { vQuantisedDim.x, vQuantisedDim.y }, { vQuantisedDim.x, vQuantisedPos.y } }; + olc::vf2d uvtl = (source_pos + olc::vf2d(0.0001f, 0.0001f)) * decal->vUVScale; + olc::vf2d uvbr = (source_pos + source_size - olc::vf2d(0.0001f, 0.0001f)) * decal->vUVScale; + di.uv = { { uvtl.x, uvtl.y }, { uvtl.x, uvbr.y }, { uvbr.x, uvbr.y }, { uvbr.x, uvtl.y } }; + di.w = { 1,1,1,1 }; + di.mode = nDecalMode; + di.structure = nDecalStructure; + vLayers[nTargetLayer].vecDecalInstance.push_back(di); + } + + void PixelGameEngine::DrawPartialDecal(const olc::vf2d& pos, const olc::vf2d& size, olc::Decal* decal, const olc::vf2d& source_pos, const olc::vf2d& source_size, const olc::Pixel& tint) + { + olc::vf2d vScreenSpacePos = + { + (pos.x * vInvScreenSize.x) * 2.0f - 1.0f, + ((pos.y * vInvScreenSize.y) * 2.0f - 1.0f) * -1.0f + }; + + olc::vf2d vScreenSpaceDim = + { + vScreenSpacePos.x + (2.0f * size.x * vInvScreenSize.x), + vScreenSpacePos.y - (2.0f * size.y * vInvScreenSize.y) + }; + + DecalInstance di; + di.points = 4; + di.decal = decal; + di.tint = { tint, tint, tint, tint }; + di.pos = { { vScreenSpacePos.x, vScreenSpacePos.y }, { vScreenSpacePos.x, vScreenSpaceDim.y }, { vScreenSpaceDim.x, vScreenSpaceDim.y }, { vScreenSpaceDim.x, vScreenSpacePos.y } }; + olc::vf2d uvtl = (source_pos) * decal->vUVScale; + olc::vf2d uvbr = uvtl + ((source_size) * decal->vUVScale); + di.uv = { { uvtl.x, uvtl.y }, { uvtl.x, uvbr.y }, { uvbr.x, uvbr.y }, { uvbr.x, uvtl.y } }; + di.w = { 1,1,1,1 }; + di.mode = nDecalMode; + di.structure = nDecalStructure; + vLayers[nTargetLayer].vecDecalInstance.push_back(di); + } + + + void PixelGameEngine::DrawDecal(const olc::vf2d& pos, olc::Decal* decal, const olc::vf2d& scale, const olc::Pixel& tint) + { + olc::vf2d vScreenSpacePos = + { + (pos.x * vInvScreenSize.x) * 2.0f - 1.0f, + ((pos.y * vInvScreenSize.y) * 2.0f - 1.0f) * -1.0f + }; + + olc::vf2d vScreenSpaceDim = + { + vScreenSpacePos.x + (2.0f * (float(decal->sprite->width) * vInvScreenSize.x)) * scale.x, + vScreenSpacePos.y - (2.0f * (float(decal->sprite->height) * vInvScreenSize.y)) * scale.y + }; + + DecalInstance di; + di.decal = decal; + di.points = 4; + di.tint = { tint, tint, tint, tint }; + di.pos = { { vScreenSpacePos.x, vScreenSpacePos.y }, { vScreenSpacePos.x, vScreenSpaceDim.y }, { vScreenSpaceDim.x, vScreenSpaceDim.y }, { vScreenSpaceDim.x, vScreenSpacePos.y } }; + di.uv = { { 0.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 1.0f}, {1.0f, 0.0f} }; + di.w = { 1, 1, 1, 1 }; + di.mode = nDecalMode; + di.structure = nDecalStructure; + vLayers[nTargetLayer].vecDecalInstance.push_back(di); + } + + void PixelGameEngine::DrawExplicitDecal(olc::Decal* decal, const olc::vf2d* pos, const olc::vf2d* uv, const olc::Pixel* col, uint32_t elements) + { + DecalInstance di; + di.decal = decal; + di.pos.resize(elements); + di.uv.resize(elements); + di.w.resize(elements); + di.tint.resize(elements); + di.points = elements; + for (uint32_t i = 0; i < elements; i++) + { + di.pos[i] = { (pos[i].x * vInvScreenSize.x) * 2.0f - 1.0f, ((pos[i].y * vInvScreenSize.y) * 2.0f - 1.0f) * -1.0f }; + di.uv[i] = uv[i]; + di.tint[i] = col[i]; + di.w[i] = 1.0f; + } + di.mode = nDecalMode; + di.structure = nDecalStructure; + vLayers[nTargetLayer].vecDecalInstance.push_back(di); + } + + void PixelGameEngine::DrawPolygonDecal(olc::Decal* decal, const std::vector& pos, const std::vector& uv, const olc::Pixel tint) + { + DecalInstance di; + di.decal = decal; + di.points = uint32_t(pos.size()); + di.pos.resize(di.points); + di.uv.resize(di.points); + di.w.resize(di.points); + di.tint.resize(di.points); + for (uint32_t i = 0; i < di.points; i++) + { + di.pos[i] = { (pos[i].x * vInvScreenSize.x) * 2.0f - 1.0f, ((pos[i].y * vInvScreenSize.y) * 2.0f - 1.0f) * -1.0f }; + di.uv[i] = uv[i]; + di.tint[i] = tint; + di.w[i] = 1.0f; + } + di.mode = nDecalMode; + di.structure = nDecalStructure; + vLayers[nTargetLayer].vecDecalInstance.push_back(di); + } + + void PixelGameEngine::DrawPolygonDecal(olc::Decal* decal, const std::vector& pos, const std::vector& uv, const std::vector &tint) + { + DecalInstance di; + di.decal = decal; + di.points = uint32_t(pos.size()); + di.pos.resize(di.points); + di.uv.resize(di.points); + di.w.resize(di.points); + di.tint.resize(di.points); + for (uint32_t i = 0; i < di.points; i++) + { + di.pos[i] = { (pos[i].x * vInvScreenSize.x) * 2.0f - 1.0f, ((pos[i].y * vInvScreenSize.y) * 2.0f - 1.0f) * -1.0f }; + di.uv[i] = uv[i]; + di.tint[i] = tint[i]; + di.w[i] = 1.0f; + } + di.mode = nDecalMode; + di.structure = nDecalStructure; + vLayers[nTargetLayer].vecDecalInstance.push_back(di); + } + + void PixelGameEngine::DrawPolygonDecal(olc::Decal* decal, const std::vector& pos, const std::vector& uv, const std::vector& colours, const olc::Pixel tint) + { + std::vector newColours(colours.size(), olc::WHITE); + std::transform(colours.begin(), colours.end(), newColours.begin(), + [&tint](const olc::Pixel pin) { return pin * tint; }); + DrawPolygonDecal(decal, pos, uv, newColours); + } + + + void PixelGameEngine::DrawPolygonDecal(olc::Decal* decal, const std::vector& pos, const std::vector& depth, const std::vector& uv, const olc::Pixel tint) + { + DecalInstance di; + di.decal = decal; + di.points = uint32_t(pos.size()); + di.pos.resize(di.points); + di.uv.resize(di.points); + di.w.resize(di.points); + di.tint.resize(di.points); + for (uint32_t i = 0; i < di.points; i++) + { + di.pos[i] = { (pos[i].x * vInvScreenSize.x) * 2.0f - 1.0f, ((pos[i].y * vInvScreenSize.y) * 2.0f - 1.0f) * -1.0f }; + di.uv[i] = uv[i]; + di.tint[i] = tint; + di.w[i] = depth[i]; + } + di.mode = nDecalMode; + di.structure = nDecalStructure; + vLayers[nTargetLayer].vecDecalInstance.push_back(di); + } + +#ifdef OLC_ENABLE_EXPERIMENTAL + // Lightweight 3D + void PixelGameEngine::LW3D_DrawTriangles(olc::Decal* decal, const std::vector>& pos, const std::vector& tex, const std::vector& col) + { + DecalInstance di; + di.decal = decal; + di.points = uint32_t(pos.size()); + di.pos.resize(di.points); + di.uv.resize(di.points); + di.w.resize(di.points); + di.tint.resize(di.points); + for (uint32_t i = 0; i < di.points; i++) + { + di.pos[i] = { pos[i][0], pos[i][1] }; + di.w[i] = pos[i][2]; + di.uv[i] = tex[i]; + di.tint[i] = col[i]; + } + di.mode = DecalMode::MODEL3D; + vLayers[nTargetLayer].vecDecalInstance.push_back(di); + } +#endif + + void PixelGameEngine::DrawLineDecal(const olc::vf2d& pos1, const olc::vf2d& pos2, Pixel p) + { + auto m = nDecalMode; + nDecalMode = olc::DecalMode::WIREFRAME; + DrawPolygonDecal(nullptr, { pos1, pos2 }, { {0, 0}, {0,0} }, p); + nDecalMode = m; + + /*DecalInstance di; + di.decal = nullptr; + di.points = uint32_t(2); + di.pos.resize(di.points); + di.uv.resize(di.points); + di.w.resize(di.points); + di.tint.resize(di.points); + di.pos[0] = { (pos1.x * vInvScreenSize.x) * 2.0f - 1.0f, ((pos1.y * vInvScreenSize.y) * 2.0f - 1.0f) * -1.0f }; + di.uv[0] = { 0.0f, 0.0f }; + di.tint[0] = p; + di.w[0] = 1.0f; + di.pos[1] = { (pos2.x * vInvScreenSize.x) * 2.0f - 1.0f, ((pos2.y * vInvScreenSize.y) * 2.0f - 1.0f) * -1.0f }; + di.uv[1] = { 0.0f, 0.0f }; + di.tint[1] = p; + di.w[1] = 1.0f; + di.mode = olc::DecalMode::WIREFRAME; + di.structure = nDecalStructure; + vLayers[nTargetLayer].vecDecalInstance.push_back(di);*/ + } + + void PixelGameEngine::DrawRectDecal(const olc::vf2d& pos, const olc::vf2d& size, const olc::Pixel col) + { + auto m = nDecalMode; + SetDecalMode(olc::DecalMode::WIREFRAME); + olc::vf2d vNewSize = size;// (size - olc::vf2d(0.375f, 0.375f)).ceil(); + std::array points = { { {pos}, {pos.x, pos.y + vNewSize.y}, {pos + vNewSize}, {pos.x + vNewSize.x, pos.y} } }; + std::array uvs = { {{0,0},{0,0},{0,0},{0,0}} }; + std::array cols = { {col, col, col, col} }; + DrawExplicitDecal(nullptr, points.data(), uvs.data(), cols.data(), 4); + SetDecalMode(m); + + } + + void PixelGameEngine::FillRectDecal(const olc::vf2d& pos, const olc::vf2d& size, const olc::Pixel col) + { + olc::vf2d vNewSize = size;// (size - olc::vf2d(0.375f, 0.375f)).ceil(); + std::array points = { { {pos}, {pos.x, pos.y + vNewSize.y}, {pos + vNewSize}, {pos.x + vNewSize.x, pos.y} } }; + std::array uvs = { {{0,0},{0,0},{0,0},{0,0}} }; + std::array cols = { {col, col, col, col} }; + DrawExplicitDecal(nullptr, points.data(), uvs.data(), cols.data(), 4); + } + + void PixelGameEngine::GradientFillRectDecal(const olc::vf2d& pos, const olc::vf2d& size, const olc::Pixel colTL, const olc::Pixel colBL, const olc::Pixel colBR, const olc::Pixel colTR) + { + std::array points = { { {pos}, {pos.x, pos.y + size.y}, {pos + size}, {pos.x + size.x, pos.y} } }; + std::array uvs = { {{0,0},{0,0},{0,0},{0,0}} }; + std::array cols = { {colTL, colBL, colBR, colTR} }; + DrawExplicitDecal(nullptr, points.data(), uvs.data(), cols.data(), 4); + } + + void PixelGameEngine::DrawRotatedDecal(const olc::vf2d& pos, olc::Decal* decal, const float fAngle, const olc::vf2d& center, const olc::vf2d& scale, const olc::Pixel& tint) + { + DecalInstance di; + di.decal = decal; + di.pos.resize(4); + di.uv = { { 0.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 1.0f}, {1.0f, 0.0f} }; + di.w = { 1, 1, 1, 1 }; + di.tint = { tint, tint, tint, tint }; + di.points = 4; + di.pos[0] = (olc::vf2d(0.0f, 0.0f) - center) * scale; + di.pos[1] = (olc::vf2d(0.0f, float(decal->sprite->height)) - center) * scale; + di.pos[2] = (olc::vf2d(float(decal->sprite->width), float(decal->sprite->height)) - center) * scale; + di.pos[3] = (olc::vf2d(float(decal->sprite->width), 0.0f) - center) * scale; + float c = cos(fAngle), s = sin(fAngle); + for (int i = 0; i < 4; i++) + { + di.pos[i] = pos + olc::vf2d(di.pos[i].x * c - di.pos[i].y * s, di.pos[i].x * s + di.pos[i].y * c); + di.pos[i] = di.pos[i] * vInvScreenSize * 2.0f - olc::vf2d(1.0f, 1.0f); + di.pos[i].y *= -1.0f; + di.w[i] = 1; + } + di.mode = nDecalMode; + di.structure = nDecalStructure; + vLayers[nTargetLayer].vecDecalInstance.push_back(di); + } + + + void PixelGameEngine::DrawPartialRotatedDecal(const olc::vf2d& pos, olc::Decal* decal, const float fAngle, const olc::vf2d& center, const olc::vf2d& source_pos, const olc::vf2d& source_size, const olc::vf2d& scale, const olc::Pixel& tint) + { + DecalInstance di; + di.decal = decal; + di.points = 4; + di.tint = { tint, tint, tint, tint }; + di.w = { 1, 1, 1, 1 }; + di.pos.resize(4); + di.pos[0] = (olc::vf2d(0.0f, 0.0f) - center) * scale; + di.pos[1] = (olc::vf2d(0.0f, source_size.y) - center) * scale; + di.pos[2] = (olc::vf2d(source_size.x, source_size.y) - center) * scale; + di.pos[3] = (olc::vf2d(source_size.x, 0.0f) - center) * scale; + float c = cos(fAngle), s = sin(fAngle); + for (int i = 0; i < 4; i++) + { + di.pos[i] = pos + olc::vf2d(di.pos[i].x * c - di.pos[i].y * s, di.pos[i].x * s + di.pos[i].y * c); + di.pos[i] = di.pos[i] * vInvScreenSize * 2.0f - olc::vf2d(1.0f, 1.0f); + di.pos[i].y *= -1.0f; + } + + olc::vf2d uvtl = source_pos * decal->vUVScale; + olc::vf2d uvbr = uvtl + (source_size * decal->vUVScale); + di.uv = { { uvtl.x, uvtl.y }, { uvtl.x, uvbr.y }, { uvbr.x, uvbr.y }, { uvbr.x, uvtl.y } }; + di.mode = nDecalMode; + di.structure = nDecalStructure; + vLayers[nTargetLayer].vecDecalInstance.push_back(di); + } + + void PixelGameEngine::DrawPartialWarpedDecal(olc::Decal* decal, const olc::vf2d* pos, const olc::vf2d& source_pos, const olc::vf2d& source_size, const olc::Pixel& tint) + { + DecalInstance di; + di.points = 4; + di.decal = decal; + di.tint = { tint, tint, tint, tint }; + di.w = { 1, 1, 1, 1 }; + di.pos.resize(4); + di.uv = { { 0.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 1.0f}, {1.0f, 0.0f} }; + olc::vf2d center; + float rd = ((pos[2].x - pos[0].x) * (pos[3].y - pos[1].y) - (pos[3].x - pos[1].x) * (pos[2].y - pos[0].y)); + if (rd != 0) + { + olc::vf2d uvtl = source_pos * decal->vUVScale; + olc::vf2d uvbr = uvtl + (source_size * decal->vUVScale); + di.uv = { { uvtl.x, uvtl.y }, { uvtl.x, uvbr.y }, { uvbr.x, uvbr.y }, { uvbr.x, uvtl.y } }; + + rd = 1.0f / rd; + float rn = ((pos[3].x - pos[1].x) * (pos[0].y - pos[1].y) - (pos[3].y - pos[1].y) * (pos[0].x - pos[1].x)) * rd; + float sn = ((pos[2].x - pos[0].x) * (pos[0].y - pos[1].y) - (pos[2].y - pos[0].y) * (pos[0].x - pos[1].x)) * rd; + if (!(rn < 0.f || rn > 1.f || sn < 0.f || sn > 1.f)) center = pos[0] + rn * (pos[2] - pos[0]); + float d[4]; for (int i = 0; i < 4; i++) d[i] = (pos[i] - center).mag(); + for (int i = 0; i < 4; i++) + { + float q = d[i] == 0.0f ? 1.0f : (d[i] + d[(i + 2) & 3]) / d[(i + 2) & 3]; + di.uv[i] *= q; di.w[i] *= q; + di.pos[i] = { (pos[i].x * vInvScreenSize.x) * 2.0f - 1.0f, ((pos[i].y * vInvScreenSize.y) * 2.0f - 1.0f) * -1.0f }; + } + di.mode = nDecalMode; + di.structure = nDecalStructure; + vLayers[nTargetLayer].vecDecalInstance.push_back(di); + } + } + + void PixelGameEngine::DrawWarpedDecal(olc::Decal* decal, const olc::vf2d* pos, const olc::Pixel& tint) + { + // Thanks Nathan Reed, a brilliant article explaining whats going on here + // http://www.reedbeta.com/blog/quadrilateral-interpolation-part-1/ + DecalInstance di; + di.points = 4; + di.decal = decal; + di.tint = { tint, tint, tint, tint }; + di.w = { 1, 1, 1, 1 }; + di.pos.resize(4); + di.uv = { { 0.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 1.0f}, {1.0f, 0.0f} }; + olc::vf2d center; + float rd = ((pos[2].x - pos[0].x) * (pos[3].y - pos[1].y) - (pos[3].x - pos[1].x) * (pos[2].y - pos[0].y)); + if (rd != 0) + { + rd = 1.0f / rd; + float rn = ((pos[3].x - pos[1].x) * (pos[0].y - pos[1].y) - (pos[3].y - pos[1].y) * (pos[0].x - pos[1].x)) * rd; + float sn = ((pos[2].x - pos[0].x) * (pos[0].y - pos[1].y) - (pos[2].y - pos[0].y) * (pos[0].x - pos[1].x)) * rd; + if (!(rn < 0.f || rn > 1.f || sn < 0.f || sn > 1.f)) center = pos[0] + rn * (pos[2] - pos[0]); + float d[4]; for (int i = 0; i < 4; i++) d[i] = (pos[i] - center).mag(); + for (int i = 0; i < 4; i++) + { + float q = d[i] == 0.0f ? 1.0f : (d[i] + d[(i + 2) & 3]) / d[(i + 2) & 3]; + di.uv[i] *= q; di.w[i] *= q; + di.pos[i] = { (pos[i].x * vInvScreenSize.x) * 2.0f - 1.0f, ((pos[i].y * vInvScreenSize.y) * 2.0f - 1.0f) * -1.0f }; + } + di.mode = nDecalMode; + di.structure = nDecalStructure; + vLayers[nTargetLayer].vecDecalInstance.push_back(di); + } + } + + void PixelGameEngine::DrawWarpedDecal(olc::Decal* decal, const std::array& pos, const olc::Pixel& tint) + { DrawWarpedDecal(decal, pos.data(), tint); } + + void PixelGameEngine::DrawWarpedDecal(olc::Decal* decal, const olc::vf2d(&pos)[4], const olc::Pixel& tint) + { DrawWarpedDecal(decal, &pos[0], tint); } + + void PixelGameEngine::DrawPartialWarpedDecal(olc::Decal* decal, const std::array& pos, const olc::vf2d& source_pos, const olc::vf2d& source_size, const olc::Pixel& tint) + { DrawPartialWarpedDecal(decal, pos.data(), source_pos, source_size, tint); } + + void PixelGameEngine::DrawPartialWarpedDecal(olc::Decal* decal, const olc::vf2d(&pos)[4], const olc::vf2d& source_pos, const olc::vf2d& source_size, const olc::Pixel& tint) + { DrawPartialWarpedDecal(decal, &pos[0], source_pos, source_size, tint); } + + void PixelGameEngine::DrawStringDecal(const olc::vf2d& pos, const std::string& sText, const Pixel col, const olc::vf2d& scale) + { + olc::vf2d spos = { 0.0f, 0.0f }; + for (auto c : sText) + { + if (c == '\n') + { + spos.x = 0; spos.y += 8.0f * scale.y; + } + else if (c == '\t') + { + spos.x += 8.0f * float(nTabSizeInSpaces) * scale.x; + } + else + { + int32_t ox = (c - 32) % 16; + int32_t oy = (c - 32) / 16; + DrawPartialDecal(pos + spos, fontRenderable.Decal(), {float(ox) * 8.0f, float(oy) * 8.0f}, {8.0f, 8.0f}, scale, col); + spos.x += 8.0f * scale.x; + } + } + } + + void PixelGameEngine::DrawStringPropDecal(const olc::vf2d& pos, const std::string& sText, const Pixel col, const olc::vf2d& scale) + { + olc::vf2d spos = { 0.0f, 0.0f }; + for (auto c : sText) + { + if (c == '\n') + { + spos.x = 0; spos.y += 8.0f * scale.y; + } + else if (c == '\t') + { + spos.x += 8.0f * float(nTabSizeInSpaces) * scale.x; + } + else + { + int32_t ox = (c - 32) % 16; + int32_t oy = (c - 32) / 16; + DrawPartialDecal(pos + spos, fontRenderable.Decal(), { float(ox) * 8.0f + float(vFontSpacing[c - 32].x), float(oy) * 8.0f }, { float(vFontSpacing[c - 32].y), 8.0f }, scale, col); + spos.x += float(vFontSpacing[c - 32].y) * scale.x; + } + } + } + // Thanks Oso-Grande/Sopadeoso For these awesom and stupidly clever Text Rotation routines... duh XD + void PixelGameEngine::DrawRotatedStringDecal(const olc::vf2d& pos, const std::string& sText, const float fAngle, const olc::vf2d& center, const Pixel col, const olc::vf2d& scale) + { + olc::vf2d spos = center; + for (auto c : sText) + { + if (c == '\n') + { + spos.x = center.x; spos.y -= 8.0f; + } + else if (c == '\t') + { + spos.x += 8.0f * float(nTabSizeInSpaces) * scale.x; + } + else + { + int32_t ox = (c - 32) % 16; + int32_t oy = (c - 32) / 16; + DrawPartialRotatedDecal(pos, fontRenderable.Decal(), fAngle, spos, { float(ox) * 8.0f, float(oy) * 8.0f }, { 8.0f, 8.0f }, scale, col); + spos.x -= 8.0f; + } + } + } + + void PixelGameEngine::DrawRotatedStringPropDecal(const olc::vf2d& pos, const std::string& sText, const float fAngle, const olc::vf2d& center, const Pixel col, const olc::vf2d& scale) + { + olc::vf2d spos = center; + for (auto c : sText) + { + if (c == '\n') + { + spos.x = center.x; spos.y -= 8.0f; + } + else if (c == '\t') + { + spos.x += 8.0f * float(nTabSizeInSpaces) * scale.x; + } + else + { + int32_t ox = (c - 32) % 16; + int32_t oy = (c - 32) / 16; + DrawPartialRotatedDecal(pos, fontRenderable.Decal(), fAngle, spos, { float(ox) * 8.0f + float(vFontSpacing[c - 32].x), float(oy) * 8.0f }, { float(vFontSpacing[c - 32].y), 8.0f }, scale, col); + spos.x -= float(vFontSpacing[c - 32].y); + } + } + } + + olc::vi2d PixelGameEngine::GetTextSize(const std::string& s) + { + olc::vi2d size = { 0,1 }; + olc::vi2d pos = { 0,1 }; + for (auto c : s) + { + if (c == '\n') { pos.y++; pos.x = 0; } + else if (c == '\t') { pos.x += nTabSizeInSpaces; } + else pos.x++; + size.x = std::max(size.x, pos.x); + size.y = std::max(size.y, pos.y); + } + return size * 8; + } + + void PixelGameEngine::DrawString(const olc::vi2d& pos, const std::string& sText, Pixel col, uint32_t scale) + { DrawString(pos.x, pos.y, sText, col, scale); } + + void PixelGameEngine::DrawString(int32_t x, int32_t y, const std::string& sText, Pixel col, uint32_t scale) + { + int32_t sx = 0; + int32_t sy = 0; + Pixel::Mode m = nPixelMode; + // Thanks @tucna, spotted bug with col.ALPHA :P + if (m != Pixel::CUSTOM) // Thanks @Megarev, required for "shaders" + { + if (col.a != 255) SetPixelMode(Pixel::ALPHA); + else SetPixelMode(Pixel::MASK); + } + for (auto c : sText) + { + if (c == '\n') + { + sx = 0; sy += 8 * scale; + } + else if (c == '\t') + { + sx += 8 * nTabSizeInSpaces * scale; + } + else + { + int32_t ox = (c - 32) % 16; + int32_t oy = (c - 32) / 16; + + if (scale > 1) + { + for (uint32_t i = 0; i < 8; i++) + for (uint32_t j = 0; j < 8; j++) + if (fontRenderable.Sprite()->GetPixel(i + ox * 8, j + oy * 8).r > 0) + for (uint32_t is = 0; is < scale; is++) + for (uint32_t js = 0; js < scale; js++) + Draw(x + sx + (i * scale) + is, y + sy + (j * scale) + js, col); + } + else + { + for (uint32_t i = 0; i < 8; i++) + for (uint32_t j = 0; j < 8; j++) + if (fontRenderable.Sprite()->GetPixel(i + ox * 8, j + oy * 8).r > 0) + Draw(x + sx + i, y + sy + j, col); + } + sx += 8 * scale; + } + } + SetPixelMode(m); + } + + olc::vi2d PixelGameEngine::GetTextSizeProp(const std::string& s) + { + olc::vi2d size = { 0,1 }; + olc::vi2d pos = { 0,1 }; + for (auto c : s) + { + if (c == '\n') { pos.y += 1; pos.x = 0; } + else if (c == '\t') { pos.x += nTabSizeInSpaces * 8; } + else pos.x += vFontSpacing[c - 32].y; + size.x = std::max(size.x, pos.x); + size.y = std::max(size.y, pos.y); + } + + size.y *= 8; + return size; + } + + void PixelGameEngine::DrawStringProp(const olc::vi2d& pos, const std::string& sText, Pixel col, uint32_t scale) + { DrawStringProp(pos.x, pos.y, sText, col, scale); } + + void PixelGameEngine::DrawStringProp(int32_t x, int32_t y, const std::string& sText, Pixel col, uint32_t scale) + { + int32_t sx = 0; + int32_t sy = 0; + Pixel::Mode m = nPixelMode; + + if (m != Pixel::CUSTOM) + { + if (col.a != 255) SetPixelMode(Pixel::ALPHA); + else SetPixelMode(Pixel::MASK); + } + for (auto c : sText) + { + if (c == '\n') + { + sx = 0; sy += 8 * scale; + } + else if (c == '\t') + { + sx += 8 * nTabSizeInSpaces * scale; + } + else + { + int32_t ox = (c - 32) % 16; + int32_t oy = (c - 32) / 16; + + if (scale > 1) + { + for (int32_t i = 0; i < vFontSpacing[c - 32].y; i++) + for (int32_t j = 0; j < 8; j++) + if (fontRenderable.Sprite()->GetPixel(i + ox * 8 + vFontSpacing[c - 32].x, j + oy * 8).r > 0) + for (int32_t is = 0; is < int(scale); is++) + for (int32_t js = 0; js < int(scale); js++) + Draw(x + sx + (i * scale) + is, y + sy + (j * scale) + js, col); + } + else + { + for (int32_t i = 0; i < vFontSpacing[c - 32].y; i++) + for (int32_t j = 0; j < 8; j++) + if (fontRenderable.Sprite()->GetPixel(i + ox * 8 + vFontSpacing[c - 32].x, j + oy * 8).r > 0) + Draw(x + sx + i, y + sy + j, col); + } + sx += vFontSpacing[c - 32].y * scale; + } + } + SetPixelMode(m); + } + + void PixelGameEngine::SetPixelMode(Pixel::Mode m) + { nPixelMode = m; } + + Pixel::Mode PixelGameEngine::GetPixelMode() + { return nPixelMode; } + + void PixelGameEngine::SetPixelMode(std::function pixelMode) + { + funcPixelMode = pixelMode; + nPixelMode = Pixel::Mode::CUSTOM; + } + + void PixelGameEngine::SetPixelBlend(float fBlend) + { + fBlendFactor = fBlend; + if (fBlendFactor < 0.0f) fBlendFactor = 0.0f; + if (fBlendFactor > 1.0f) fBlendFactor = 1.0f; + } + + std::stringstream& PixelGameEngine::ConsoleOut() + { return ssConsoleOutput; } + + bool PixelGameEngine::IsConsoleShowing() const + { return bConsoleShow; } + + void PixelGameEngine::ConsoleShow(const olc::Key& keyExit, bool bSuspendTime) + { + if (bConsoleShow) + return; + + bConsoleShow = true; + bConsoleSuspendTime = bSuspendTime; + TextEntryEnable(true); + keyConsoleExit = keyExit; + pKeyboardState[keyConsoleExit].bHeld = false; + pKeyboardState[keyConsoleExit].bPressed = false; + pKeyboardState[keyConsoleExit].bReleased = true; + } + + void PixelGameEngine::ConsoleClear() + { sConsoleLines.clear(); } + + void PixelGameEngine::ConsoleCaptureStdOut(const bool bCapture) + { + if(bCapture) + sbufOldCout = std::cout.rdbuf(ssConsoleOutput.rdbuf()); + else + std::cout.rdbuf(sbufOldCout); + } + + void PixelGameEngine::UpdateConsole() + { + if (GetKey(keyConsoleExit).bPressed) + { + TextEntryEnable(false); + bConsoleSuspendTime = false; + bConsoleShow = false; + return; + } + + // Keep Console sizes based in real screen dimensions + vConsoleCharacterScale = olc::vf2d(1.0f, 2.0f) / (olc::vf2d(vViewSize) * vInvScreenSize); + vConsoleSize = (vViewSize / olc::vi2d(8, 16)) - olc::vi2d(2, 4); + + // If console has changed size, simply reset it + if (vConsoleSize.y != sConsoleLines.size()) + { + vConsoleCursor = { 0,0 }; + sConsoleLines.clear(); + sConsoleLines.resize(vConsoleSize.y); + } + + auto TypeCharacter = [&](const char c) + { + if (c >= 32 && c < 127) + { + sConsoleLines[vConsoleCursor.y].append(1, c); + vConsoleCursor.x++; + } + + if( c == '\n' || vConsoleCursor.x >= vConsoleSize.x) + { + vConsoleCursor.y++; vConsoleCursor.x = 0; + } + + if (vConsoleCursor.y >= vConsoleSize.y) + { + vConsoleCursor.y = vConsoleSize.y - 1; + for (size_t i = 1; i < vConsoleSize.y; i++) + sConsoleLines[i - 1] = sConsoleLines[i]; + sConsoleLines[vConsoleCursor.y].clear(); + } + }; + + // Empty out "std::cout", parsing as we go + while (ssConsoleOutput.rdbuf()->sgetc() != -1) + { + char c = ssConsoleOutput.rdbuf()->sbumpc(); + TypeCharacter(c); + } + + // Draw Shadow + GradientFillRectDecal({ 0,0 }, olc::vf2d(vScreenSize), olc::PixelF(0, 0, 0.5f, 0.5f), olc::PixelF(0, 0, 0.25f, 0.5f), olc::PixelF(0, 0, 0.25f, 0.5f), olc::PixelF(0, 0, 0.25f, 0.5f)); + + // Draw the console buffer + SetDecalMode(olc::DecalMode::NORMAL); + for (int32_t nLine = 0; nLine < vConsoleSize.y; nLine++) + DrawStringDecal(olc::vf2d( 1, 1 + float(nLine) ) * vConsoleCharacterScale * 8.0f, sConsoleLines[nLine], olc::WHITE, vConsoleCharacterScale); + + // Draw Input State + FillRectDecal(olc::vf2d(1 + float((TextEntryGetCursor() + 1)), 1 + float((vConsoleSize.y - 1))) * vConsoleCharacterScale * 8.0f, olc::vf2d(8, 8) * vConsoleCharacterScale, olc::DARK_CYAN); + DrawStringDecal(olc::vf2d(1, 1 + float((vConsoleSize.y - 1))) * vConsoleCharacterScale * 8.0f, std::string(">") + TextEntryGetString(), olc::YELLOW, vConsoleCharacterScale); + } + + + const std::vector& PixelGameEngine::GetDroppedFiles() const + { return vDroppedFiles; } + + const olc::vi2d& PixelGameEngine::GetDroppedFilesPoint() const + { return vDroppedFilesPoint; } + + + void PixelGameEngine::TextEntryEnable(const bool bEnable, const std::string& sText) + { + if (bEnable) + { + nTextEntryCursor = int32_t(sText.size()); + sTextEntryString = sText; + bTextEntryEnable = true; + } + else + { + bTextEntryEnable = false; + } + } + + std::string PixelGameEngine::TextEntryGetString() const + { return sTextEntryString; } + + int32_t PixelGameEngine::TextEntryGetCursor() const + { return nTextEntryCursor; } + + bool PixelGameEngine::IsTextEntryEnabled() const + { return bTextEntryEnable; } + + + void PixelGameEngine::UpdateTextEntry() + { + // Check for typed characters + for (const auto& key : vKeyboardMap) + if (GetKey(std::get<0>(key)).bPressed) + { + sTextEntryString.insert(nTextEntryCursor, GetKey(olc::Key::SHIFT).bHeld ? std::get<2>(key) : std::get<1>(key)); + nTextEntryCursor++; + } + + // Check for command characters + if (GetKey(olc::Key::LEFT).bPressed) + nTextEntryCursor = std::max(0, nTextEntryCursor - 1); + if (GetKey(olc::Key::RIGHT).bPressed) + nTextEntryCursor = std::min(int32_t(sTextEntryString.size()), nTextEntryCursor + 1); + if (GetKey(olc::Key::BACK).bPressed && nTextEntryCursor > 0) + { + sTextEntryString.erase(nTextEntryCursor-1, 1); + nTextEntryCursor = std::max(0, nTextEntryCursor - 1); + } + if (GetKey(olc::Key::DEL).bPressed && nTextEntryCursor < sTextEntryString.size()) + sTextEntryString.erase(nTextEntryCursor, 1); + + if (GetKey(olc::Key::UP).bPressed) + { + if (!sCommandHistory.empty()) + { + if (sCommandHistoryIt != sCommandHistory.begin()) + sCommandHistoryIt--; + + nTextEntryCursor = int32_t(sCommandHistoryIt->size()); + sTextEntryString = *sCommandHistoryIt; + } + } + + if (GetKey(olc::Key::DOWN).bPressed) + { + if (!sCommandHistory.empty()) + { + if (sCommandHistoryIt != sCommandHistory.end()) + { + sCommandHistoryIt++; + if (sCommandHistoryIt != sCommandHistory.end()) + { + nTextEntryCursor = int32_t(sCommandHistoryIt->size()); + sTextEntryString = *sCommandHistoryIt; + } + else + { + nTextEntryCursor = 0; + sTextEntryString = ""; + } + } + } + } + + if (GetKey(olc::Key::ENTER).bPressed) + { + if (bConsoleShow) + { + std::cout << ">" + sTextEntryString + "\n"; + if (OnConsoleCommand(sTextEntryString)) + { + sCommandHistory.push_back(sTextEntryString); + sCommandHistoryIt = sCommandHistory.end(); + } + sTextEntryString.clear(); + nTextEntryCursor = 0; + } + else + { + OnTextEntryComplete(sTextEntryString); + TextEntryEnable(false); + } + } + } + + // User must override these functions as required. I have not made + // them abstract because I do need a default behaviour to occur if + // they are not overwritten + + bool PixelGameEngine::OnUserCreate() + { return false; } + + bool PixelGameEngine::OnUserUpdate(float fElapsedTime) + { UNUSED(fElapsedTime); return false; } + + bool PixelGameEngine::OnUserDestroy() + { return true; } + + void PixelGameEngine::OnTextEntryComplete(const std::string& sText) { UNUSED(sText); } + bool PixelGameEngine::OnConsoleCommand(const std::string& sCommand) { UNUSED(sCommand); return false; } + + // Externalised API + void PixelGameEngine::olc_UpdateViewport() + { + int32_t ww = vScreenSize.x * vPixelSize.x; + int32_t wh = vScreenSize.y * vPixelSize.y; + float wasp = (float)ww / (float)wh; + + if (bPixelCohesion) + { + vScreenPixelSize = (vWindowSize / vScreenSize); + vViewSize = (vWindowSize / vScreenSize) * vScreenSize; + } + else + { + vViewSize.x = (int32_t)vWindowSize.x; + vViewSize.y = (int32_t)((float)vViewSize.x / wasp); + + if (vViewSize.y > vWindowSize.y) + { + vViewSize.y = vWindowSize.y; + vViewSize.x = (int32_t)((float)vViewSize.y * wasp); + } + } + + vViewPos = (vWindowSize - vViewSize) / 2; + } + + void PixelGameEngine::olc_UpdateWindowSize(int32_t x, int32_t y) + { + vWindowSize = { x, y }; + olc_UpdateViewport(); + } + + void PixelGameEngine::olc_UpdateMouseWheel(int32_t delta) + { nMouseWheelDeltaCache += delta; } + + void PixelGameEngine::olc_UpdateMouse(int32_t x, int32_t y) + { + // Mouse coords come in screen space + // But leave in pixel space + bHasMouseFocus = true; + vMouseWindowPos = { x, y }; + // Full Screen mode may have a weird viewport we must clamp to + x -= vViewPos.x; + y -= vViewPos.y; + vMousePosCache.x = (int32_t)(((float)x / (float)(vWindowSize.x - (vViewPos.x * 2)) * (float)vScreenSize.x)); + vMousePosCache.y = (int32_t)(((float)y / (float)(vWindowSize.y - (vViewPos.y * 2)) * (float)vScreenSize.y)); + if (vMousePosCache.x >= (int32_t)vScreenSize.x) vMousePosCache.x = vScreenSize.x - 1; + if (vMousePosCache.y >= (int32_t)vScreenSize.y) vMousePosCache.y = vScreenSize.y - 1; + if (vMousePosCache.x < 0) vMousePosCache.x = 0; + if (vMousePosCache.y < 0) vMousePosCache.y = 0; + } + + void PixelGameEngine::olc_UpdateMouseState(int32_t button, bool state) + { pMouseNewState[button] = state; } + + void PixelGameEngine::olc_UpdateKeyState(int32_t key, bool state) + { pKeyNewState[key] = state; } + + void PixelGameEngine::olc_UpdateMouseFocus(bool state) + { bHasMouseFocus = state; } + + void PixelGameEngine::olc_UpdateKeyFocus(bool state) + { bHasInputFocus = state; } + + void PixelGameEngine::olc_DropFiles(int32_t x, int32_t y, const std::vector& vFiles) + { + x -= vViewPos.x; + y -= vViewPos.y; + vDroppedFilesPointCache.x = (int32_t)(((float)x / (float)(vWindowSize.x - (vViewPos.x * 2)) * (float)vScreenSize.x)); + vDroppedFilesPointCache.y = (int32_t)(((float)y / (float)(vWindowSize.y - (vViewPos.y * 2)) * (float)vScreenSize.y)); + if (vDroppedFilesPointCache.x >= (int32_t)vScreenSize.x) vDroppedFilesPointCache.x = vScreenSize.x - 1; + if (vDroppedFilesPointCache.y >= (int32_t)vScreenSize.y) vDroppedFilesPointCache.y = vScreenSize.y - 1; + if (vDroppedFilesPointCache.x < 0) vDroppedFilesPointCache.x = 0; + if (vDroppedFilesPointCache.y < 0) vDroppedFilesPointCache.y = 0; + vDroppedFilesCache = vFiles; + } + + void PixelGameEngine::olc_Reanimate() + { bAtomActive = true; } + + bool PixelGameEngine::olc_IsRunning() + { return bAtomActive; } + + void PixelGameEngine::olc_Terminate() + { bAtomActive = false; } + + void PixelGameEngine::EngineThread() + { + // Allow platform to do stuff here if needed, since its now in the + // context of this thread + if (platform->ThreadStartUp() == olc::FAIL) return; + + // Do engine context specific initialisation + olc_PrepareEngine(); + + // Create user resources as part of this thread + for (auto& ext : vExtensions) ext->OnBeforeUserCreate(); + if (!OnUserCreate()) bAtomActive = false; + for (auto& ext : vExtensions) ext->OnAfterUserCreate(); + + while (bAtomActive) + { + // Run as fast as possible + while (bAtomActive) { olc_CoreUpdate(); } + + // Allow the user to free resources if they have overrided the destroy function + if (!OnUserDestroy()) + { + // User denied destroy for some reason, so continue running + bAtomActive = true; + } + } + + platform->ThreadCleanUp(); + } + + void PixelGameEngine::olc_PrepareEngine() + { + // Start OpenGL, the context is owned by the game thread + if (platform->CreateGraphics(bFullScreen, bEnableVSYNC, vViewPos, vViewSize) == olc::FAIL) return; + + // Construct default font sheet + olc_ConstructFontSheet(); + + // Create Primary Layer "0" + CreateLayer(); + vLayers[0].bUpdate = true; + vLayers[0].bShow = true; + SetDrawTarget(nullptr); + + m_tp1 = std::chrono::system_clock::now(); + m_tp2 = std::chrono::system_clock::now(); + } + + + void PixelGameEngine::olc_CoreUpdate() + { + // Handle Timing + m_tp2 = std::chrono::system_clock::now(); + std::chrono::duration elapsedTime = m_tp2 - m_tp1; + m_tp1 = m_tp2; + + // Our time per frame coefficient + float fElapsedTime = elapsedTime.count(); + fLastElapsed = fElapsedTime; + + if (bConsoleSuspendTime) + fElapsedTime = 0.0f; + + // Some platforms will need to check for events + platform->HandleSystemEvent(); + + // Compare hardware input states from previous frame + auto ScanHardware = [&](HWButton* pKeys, bool* pStateOld, bool* pStateNew, uint32_t nKeyCount) + { + for (uint32_t i = 0; i < nKeyCount; i++) + { + pKeys[i].bPressed = false; + pKeys[i].bReleased = false; + if (pStateNew[i] != pStateOld[i]) + { + if (pStateNew[i]) + { + pKeys[i].bPressed = !pKeys[i].bHeld; + pKeys[i].bHeld = true; + } + else + { + pKeys[i].bReleased = true; + pKeys[i].bHeld = false; + } + } + pStateOld[i] = pStateNew[i]; + } + }; + + ScanHardware(pKeyboardState, pKeyOldState, pKeyNewState, 256); + ScanHardware(pMouseState, pMouseOldState, pMouseNewState, nMouseButtons); + + // Cache mouse coordinates so they remain consistent during frame + vMousePos = vMousePosCache; + nMouseWheelDelta = nMouseWheelDeltaCache; + nMouseWheelDeltaCache = 0; + + vDroppedFiles = vDroppedFilesCache; + vDroppedFilesPoint = vDroppedFilesPointCache; + vDroppedFilesCache.clear(); + + if (bTextEntryEnable) + { + UpdateTextEntry(); + } + + // Handle Frame Update + bool bExtensionBlockFrame = false; + for (auto& ext : vExtensions) bExtensionBlockFrame |= ext->OnBeforeUserUpdate(fElapsedTime); + if (!bExtensionBlockFrame) + { + if (!OnUserUpdate(fElapsedTime)) bAtomActive = false; + + } + for (auto& ext : vExtensions) ext->OnAfterUserUpdate(fElapsedTime); + + if (bConsoleShow) + { + SetDrawTarget((uint8_t)0); + UpdateConsole(); + } + + + + // Display Frame + renderer->UpdateViewport(vViewPos, vViewSize); + renderer->ClearBuffer(olc::BLACK, true); + + // Layer 0 must always exist + vLayers[0].bUpdate = true; + vLayers[0].bShow = true; + SetDecalMode(DecalMode::NORMAL); + renderer->PrepareDrawing(); + + for (auto layer = vLayers.rbegin(); layer != vLayers.rend(); ++layer) + { + if (layer->bShow) + { + if (layer->funcHook == nullptr) + { + renderer->ApplyTexture(layer->pDrawTarget.Decal()->id); + if (!bSuspendTextureTransfer && layer->bUpdate) + { + layer->pDrawTarget.Decal()->Update(); + layer->bUpdate = false; + } + + renderer->DrawLayerQuad(layer->vOffset, layer->vScale, layer->tint); + + // Display Decals in order for this layer + for (auto& decal : layer->vecDecalInstance) + renderer->DrawDecal(decal); + layer->vecDecalInstance.clear(); + } + else + { + // Mwa ha ha.... Have Fun!!! + layer->funcHook(); + } + } + } + + + + // Present Graphics to screen + renderer->DisplayFrame(); + + // Update Title Bar + fFrameTimer += fElapsedTime; + nFrameCount++; + if (fFrameTimer >= 1.0f) + { + nLastFPS = nFrameCount; + fFrameTimer -= 1.0f; + std::string sTitle = "OneLoneCoder.com - Pixel Game Engine - " + sAppName + " - FPS: " + std::to_string(nFrameCount); + platform->SetWindowTitle(sTitle); + nFrameCount = 0; + } + } + + void PixelGameEngine::olc_ConstructFontSheet() + { + std::string data; + data += "?Q`0001oOch0o01o@F40o000000000"; + data += "O000000nOT0063Qo4d8>?7a14Gno94AA4gno94AaOT0>o3`oO400o7QN00000400"; + data += "Of80001oOg<7O7moBGT7O7lABET024@aBEd714AiOdl717a_=TH013Q>00000000"; + data += "720D000V?V5oB3Q_HdUoE7a9@DdDE4A9@DmoE4A;Hg]oM4Aj8S4D84@`00000000"; + data += "OaPT1000Oa`^13P1@AI[?g`1@A=[OdAoHgljA4Ao?WlBA7l1710007l100000000"; + data += "ObM6000oOfMV?3QoBDD`O7a0BDDH@5A0BDD<@5A0BGeVO5ao@CQR?5Po00000000"; + data += "Oc``000?Ogij70PO2D]??0Ph2DUM@7i`2DTg@7lh2GUj?0TO0C1870T?00000000"; + data += "70<4001o?P<7?1QoHg43O;`h@GT0@:@LB@d0>:@hN@L0@?aoN@<0O7ao0000?000"; + data += "OcH0001SOglLA7mg24TnK7ln24US>0PL24U140PnOgl0>7QgOcH0K71S0000A000"; + data += "00H00000@Dm1S007@DUSg00?OdTnH7YhOfTL<7Yh@Cl0700?@Ah0300700000000"; + data += "<008001QL00ZA41a@6HnI<1i@FHLM81M@@0LG81?O`0nC?Y7?`0ZA7Y300080000"; + data += "O`082000Oh0827mo6>Hn?Wmo?6HnMb11MP08@C11H`08@FP0@@0004@000000000"; + data += "00P00001Oab00003OcKP0006@6=PMgl<@440MglH@000000`@000001P00000000"; + data += "Ob@8@@00Ob@8@Ga13R@8Mga172@8?PAo3R@827QoOb@820@0O`0007`0000007P0"; + data += "O`000P08Od400g`<3V=P0G`673IP0`@3>1`00P@6O`P00g`SetPixel(px, py, olc::Pixel(k, k, k, k)); + if (++py == 48) { px++; py = 0; } + } + } + + fontRenderable.Decal()->Update(); + + constexpr std::array vSpacing = { { + 0x03,0x25,0x16,0x08,0x07,0x08,0x08,0x04,0x15,0x15,0x08,0x07,0x15,0x07,0x24,0x08, + 0x08,0x17,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x24,0x15,0x06,0x07,0x16,0x17, + 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x17,0x08,0x08,0x17,0x08,0x08,0x08, + 0x08,0x08,0x08,0x08,0x17,0x08,0x08,0x08,0x08,0x17,0x08,0x15,0x08,0x15,0x08,0x08, + 0x24,0x18,0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x33,0x17,0x17,0x33,0x18,0x17,0x17, + 0x17,0x17,0x17,0x17,0x07,0x17,0x17,0x18,0x18,0x17,0x17,0x07,0x33,0x07,0x08,0x00, } }; + + for (auto c : vSpacing) vFontSpacing.push_back({ c >> 4, c & 15 }); + + // UK Standard Layout +#ifdef OLC_KEYBOARD_UK + vKeyboardMap = + { + {olc::Key::A, "a", "A"}, {olc::Key::B, "b", "B"}, {olc::Key::C, "c", "C"}, {olc::Key::D, "d", "D"}, {olc::Key::E, "e", "E"}, + {olc::Key::F, "f", "F"}, {olc::Key::G, "g", "G"}, {olc::Key::H, "h", "H"}, {olc::Key::I, "i", "I"}, {olc::Key::J, "j", "J"}, + {olc::Key::K, "k", "K"}, {olc::Key::L, "l", "L"}, {olc::Key::M, "m", "M"}, {olc::Key::N, "n", "N"}, {olc::Key::O, "o", "O"}, + {olc::Key::P, "p", "P"}, {olc::Key::Q, "q", "Q"}, {olc::Key::R, "r", "R"}, {olc::Key::S, "s", "S"}, {olc::Key::T, "t", "T"}, + {olc::Key::U, "u", "U"}, {olc::Key::V, "v", "V"}, {olc::Key::W, "w", "W"}, {olc::Key::X, "x", "X"}, {olc::Key::Y, "y", "Y"}, + {olc::Key::Z, "z", "Z"}, + + {olc::Key::K0, "0", ")"}, {olc::Key::K1, "1", "!"}, {olc::Key::K2, "2", "\""}, {olc::Key::K3, "3", "#"}, {olc::Key::K4, "4", "$"}, + {olc::Key::K5, "5", "%"}, {olc::Key::K6, "6", "^"}, {olc::Key::K7, "7", "&"}, {olc::Key::K8, "8", "*"}, {olc::Key::K9, "9", "("}, + + {olc::Key::NP0, "0", "0"}, {olc::Key::NP1, "1", "1"}, {olc::Key::NP2, "2", "2"}, {olc::Key::NP3, "3", "3"}, {olc::Key::NP4, "4", "4"}, + {olc::Key::NP5, "5", "5"}, {olc::Key::NP6, "6", "6"}, {olc::Key::NP7, "7", "7"}, {olc::Key::NP8, "8", "8"}, {olc::Key::NP9, "9", "9"}, + {olc::Key::NP_MUL, "*", "*"}, {olc::Key::NP_DIV, "/", "/"}, {olc::Key::NP_ADD, "+", "+"}, {olc::Key::NP_SUB, "-", "-"}, {olc::Key::NP_DECIMAL, ".", "."}, + + {olc::Key::PERIOD, ".", ">"}, {olc::Key::EQUALS, "=", "+"}, {olc::Key::COMMA, ",", "<"}, {olc::Key::MINUS, "-", "_"}, {olc::Key::SPACE, " ", " "}, + + {olc::Key::OEM_1, ";", ":"}, {olc::Key::OEM_2, "/", "?"}, {olc::Key::OEM_3, "\'", "@"}, {olc::Key::OEM_4, "[", "{"}, + {olc::Key::OEM_5, "\\", "|"}, {olc::Key::OEM_6, "]", "}"}, {olc::Key::OEM_7, "#", "~"}, + + // {olc::Key::TAB, "\t", "\t"} + }; +#endif + } + + void PixelGameEngine::pgex_Register(olc::PGEX* pgex) + { + if (std::find(vExtensions.begin(), vExtensions.end(), pgex) == vExtensions.end()) + vExtensions.push_back(pgex); + } + + + PGEX::PGEX(bool bHook) { if(bHook) pge->pgex_Register(this); } + void PGEX::OnBeforeUserCreate() {} + void PGEX::OnAfterUserCreate() {} + bool PGEX::OnBeforeUserUpdate(float& fElapsedTime) { return false; } + void PGEX::OnAfterUserUpdate(float fElapsedTime) {} + + // Need a couple of statics as these are singleton instances + // read from multiple locations + std::atomic PixelGameEngine::bAtomActive{ false }; + olc::PixelGameEngine* olc::PGEX::pge = nullptr; + olc::PixelGameEngine* olc::Platform::ptrPGE = nullptr; + olc::PixelGameEngine* olc::Renderer::ptrPGE = nullptr; + std::unique_ptr olc::Sprite::loader = nullptr; +}; +#pragma endregion + + +#pragma region platform_headless +namespace olc +{ +#if defined(OLC_GFX_HEADLESS) + class Renderer_Headless : public olc::Renderer + { + public: + virtual void PrepareDevice() {}; + virtual olc::rcode CreateDevice(std::vector params, bool bFullScreen, bool bVSYNC) { return olc::rcode::OK; } + virtual olc::rcode DestroyDevice() { return olc::rcode::OK; } + virtual void DisplayFrame() {} + virtual void PrepareDrawing() {} + virtual void SetDecalMode(const olc::DecalMode& mode) {} + virtual void DrawLayerQuad(const olc::vf2d& offset, const olc::vf2d& scale, const olc::Pixel tint) {} + virtual void DrawDecal(const olc::DecalInstance& decal) {} + virtual uint32_t CreateTexture(const uint32_t width, const uint32_t height, const bool filtered = false, const bool clamp = true) {return 1;}; + virtual void UpdateTexture(uint32_t id, olc::Sprite* spr) {} + virtual void ReadTexture(uint32_t id, olc::Sprite* spr) {} + virtual uint32_t DeleteTexture(const uint32_t id) {return 1;} + virtual void ApplyTexture(uint32_t id) {} + virtual void UpdateViewport(const olc::vi2d& pos, const olc::vi2d& size) {} + virtual void ClearBuffer(olc::Pixel p, bool bDepth) {} + }; +#endif +#if defined(OLC_PLATFORM_HEADLESS) + class Platform_Headless : public olc::Platform + { + public: + virtual olc::rcode ApplicationStartUp() { return olc::rcode::OK; } + virtual olc::rcode ApplicationCleanUp() { return olc::rcode::OK; } + virtual olc::rcode ThreadStartUp() { return olc::rcode::OK; } + virtual olc::rcode ThreadCleanUp() { return olc::rcode::OK; } + virtual olc::rcode CreateGraphics(bool bFullScreen, bool bEnableVSYNC, const olc::vi2d& vViewPos, const olc::vi2d& vViewSize) { return olc::rcode::OK; } + virtual olc::rcode CreateWindowPane(const olc::vi2d& vWindowPos, olc::vi2d& vWindowSize, bool bFullScreen) { return olc::rcode::OK; } + virtual olc::rcode SetWindowTitle(const std::string& s) { return olc::rcode::OK; } + virtual olc::rcode StartSystemEventLoop() { return olc::rcode::OK; } + virtual olc::rcode HandleSystemEvent() { return olc::rcode::OK; } + }; +#endif +} +#pragma endregion + +// O------------------------------------------------------------------------------O +// | olcPixelGameEngine Renderers - the draw-y bits | +// O------------------------------------------------------------------------------O + +#pragma region image_stb +// O------------------------------------------------------------------------------O +// | START IMAGE LOADER: stb_image.h, all systems, very fast | +// O------------------------------------------------------------------------------O +// Thanks to Sean Barrett - https://github.com/nothings/stb/blob/master/stb_image.h +// MIT License - Copyright(c) 2017 Sean Barrett + +// Note you need to download the above file into your project folder, and +// #define OLC_IMAGE_STB +// #define OLC_PGE_APPLICATION +// #include "olcPixelGameEngine.h" + +#if defined(OLC_IMAGE_STB) +#define STB_IMAGE_IMPLEMENTATION +#include "stb_image.h" +namespace olc +{ + class ImageLoader_STB : public olc::ImageLoader + { + public: + ImageLoader_STB() : ImageLoader() + {} + + olc::rcode LoadImageResource(olc::Sprite* spr, const std::string& sImageFile, olc::ResourcePack* pack) override + { + UNUSED(pack); + // clear out existing sprite + spr->pColData.clear(); + // Open file + stbi_uc* bytes = nullptr; + int w = 0, h = 0, cmp = 0; + if (pack != nullptr) + { + ResourceBuffer rb = pack->GetFileBuffer(sImageFile); + bytes = stbi_load_from_memory((unsigned char*)rb.vMemory.data(), rb.vMemory.size(), &w, &h, &cmp, 4); + } + else + { + // Check file exists + if (!_gfs::exists(sImageFile)) return olc::rcode::NO_FILE; + bytes = stbi_load(sImageFile.c_str(), &w, &h, &cmp, 4); + } + + if (!bytes) return olc::rcode::FAIL; + spr->width = w; spr->height = h; + spr->pColData.resize(spr->width * spr->height); + std::memcpy(spr->pColData.data(), bytes, spr->width * spr->height * 4); + delete[] bytes; + return olc::rcode::OK; + } + + olc::rcode SaveImageResource(olc::Sprite* spr, const std::string& sImageFile) override + { + return olc::rcode::OK; + } + }; +} +#endif +// O------------------------------------------------------------------------------O +// | START IMAGE LOADER: stb_image.h | +// O------------------------------------------------------------------------------O +#pragma endregion + + + +#if !defined(OLC_PGE_HEADLESS) + +#pragma region renderer_ogl10 +// O------------------------------------------------------------------------------O +// | START RENDERER: OpenGL 1.0 (the original, the best...) | +// O------------------------------------------------------------------------------O +#if defined(OLC_GFX_OPENGL10) + +#if defined(OLC_PLATFORM_WINAPI) + #include + #include + #if !defined(__MINGW32__) + #pragma comment(lib, "Dwmapi.lib") + #endif + typedef BOOL(WINAPI wglSwapInterval_t) (int interval); + static wglSwapInterval_t* wglSwapInterval = nullptr; + typedef HDC glDeviceContext_t; + typedef HGLRC glRenderContext_t; +#endif + +#if defined(__linux__) || defined(__FreeBSD__) + #include +#endif + +#if defined(OLC_PLATFORM_X11) + namespace X11 + { + #include + } + typedef int(glSwapInterval_t)(X11::Display* dpy, X11::GLXDrawable drawable, int interval); + static glSwapInterval_t* glSwapIntervalEXT; + typedef X11::GLXContext glDeviceContext_t; + typedef X11::GLXContext glRenderContext_t; +#endif + +#if defined(__APPLE__) + #define GL_SILENCE_DEPRECATION + #include + #include + #include +#endif + +namespace olc +{ + class Renderer_OGL10 : public olc::Renderer + { + private: +#if defined(OLC_PLATFORM_GLUT) + bool mFullScreen = false; +#else + glDeviceContext_t glDeviceContext = 0; + glRenderContext_t glRenderContext = 0; +#endif + + bool bSync = false; + olc::DecalMode nDecalMode = olc::DecalMode(-1); // Thanks Gusgo & Bispoo + olc::DecalStructure nDecalStructure = olc::DecalStructure(-1); +#if defined(OLC_PLATFORM_X11) + X11::Display* olc_Display = nullptr; + X11::Window* olc_Window = nullptr; + X11::XVisualInfo* olc_VisualInfo = nullptr; +#endif + + public: + void PrepareDevice() override + { +#if defined(OLC_PLATFORM_GLUT) + //glutInit has to be called with main() arguments, make fake ones + int argc = 0; + char* argv[1] = { (char*)"" }; + glutInit(&argc, argv); + glutInitWindowPosition(0, 0); + glutInitWindowSize(512, 512); + glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH | GLUT_RGBA); + // Creates the window and the OpenGL context for it + glutCreateWindow("OneLoneCoder.com - Pixel Game Engine"); + glEnable(GL_TEXTURE_2D); // Turn on texturing + glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); +#endif + } + + olc::rcode CreateDevice(std::vector params, bool bFullScreen, bool bVSYNC) override + { +#if defined(OLC_PLATFORM_WINAPI) + // Create Device Context + glDeviceContext = GetDC((HWND)(params[0])); + PIXELFORMATDESCRIPTOR pfd = + { + sizeof(PIXELFORMATDESCRIPTOR), 1, + PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, + PFD_TYPE_RGBA, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + PFD_MAIN_PLANE, 0, 0, 0, 0 + }; + + int pf = 0; + if (!(pf = ChoosePixelFormat(glDeviceContext, &pfd))) return olc::FAIL; + SetPixelFormat(glDeviceContext, pf, &pfd); + + if (!(glRenderContext = wglCreateContext(glDeviceContext))) return olc::FAIL; + wglMakeCurrent(glDeviceContext, glRenderContext); + + // Remove Frame cap + wglSwapInterval = (wglSwapInterval_t*)wglGetProcAddress("wglSwapIntervalEXT"); + if (wglSwapInterval && !bVSYNC) wglSwapInterval(0); + bSync = bVSYNC; +#endif + +#if defined(OLC_PLATFORM_X11) + using namespace X11; + // Linux has tighter coupling between OpenGL and X11, so we store + // various "platform" handles in the renderer + olc_Display = (X11::Display*)(params[0]); + olc_Window = (X11::Window*)(params[1]); + olc_VisualInfo = (X11::XVisualInfo*)(params[2]); + + glDeviceContext = glXCreateContext(olc_Display, olc_VisualInfo, nullptr, GL_TRUE); + glXMakeCurrent(olc_Display, *olc_Window, glDeviceContext); + + XWindowAttributes gwa; + XGetWindowAttributes(olc_Display, *olc_Window, &gwa); + glViewport(0, 0, gwa.width, gwa.height); + + glSwapIntervalEXT = nullptr; + glSwapIntervalEXT = (glSwapInterval_t*)glXGetProcAddress((unsigned char*)"glXSwapIntervalEXT"); + + if (glSwapIntervalEXT == nullptr && !bVSYNC) + { + printf("NOTE: Could not disable VSYNC, glXSwapIntervalEXT() was not found!\n"); + printf(" Don't worry though, things will still work, it's just the\n"); + printf(" frame rate will be capped to your monitors refresh rate - javidx9\n"); + } + + if (glSwapIntervalEXT != nullptr && !bVSYNC) + glSwapIntervalEXT(olc_Display, *olc_Window, 0); +#endif + +#if defined(OLC_PLATFORM_GLUT) + mFullScreen = bFullScreen; + if (!bVSYNC) + { +#if defined(__APPLE__) + GLint sync = 0; + CGLContextObj ctx = CGLGetCurrentContext(); + if (ctx) CGLSetParameter(ctx, kCGLCPSwapInterval, &sync); +#endif + } +#else + glEnable(GL_TEXTURE_2D); // Turn on texturing + glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); +#endif + return olc::rcode::OK; + } + + olc::rcode DestroyDevice() override + { +#if defined(OLC_PLATFORM_WINAPI) + wglDeleteContext(glRenderContext); +#endif + +#if defined(OLC_PLATFORM_X11) + glXMakeCurrent(olc_Display, None, NULL); + glXDestroyContext(olc_Display, glDeviceContext); +#endif + +#if defined(OLC_PLATFORM_GLUT) + glutDestroyWindow(glutGetWindow()); +#endif + return olc::rcode::OK; + } + + void DisplayFrame() override + { +#if defined(OLC_PLATFORM_WINAPI) + SwapBuffers(glDeviceContext); + if (bSync) DwmFlush(); // Woooohooooooo!!!! SMOOOOOOOTH! +#endif + +#if defined(OLC_PLATFORM_X11) + X11::glXSwapBuffers(olc_Display, *olc_Window); +#endif + +#if defined(OLC_PLATFORM_GLUT) + glutSwapBuffers(); +#endif + } + + void PrepareDrawing() override + { + + //ClearBuffer(olc::GREEN, true); + glEnable(GL_BLEND); + nDecalMode = DecalMode::NORMAL; + nDecalStructure = DecalStructure::FAN; + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } + + void SetDecalMode(const olc::DecalMode& mode) + { + if (mode != nDecalMode) + { + switch (mode) + { + case olc::DecalMode::NORMAL: + case olc::DecalMode::MODEL3D: + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + break; + case olc::DecalMode::ADDITIVE: + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + break; + case olc::DecalMode::MULTIPLICATIVE: + glBlendFunc(GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA); + break; + case olc::DecalMode::STENCIL: + glBlendFunc(GL_ZERO, GL_SRC_ALPHA); + break; + case olc::DecalMode::ILLUMINATE: + glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA); + break; + case olc::DecalMode::WIREFRAME: + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + break; + } + + nDecalMode = mode; + } + } + + void DrawLayerQuad(const olc::vf2d& offset, const olc::vf2d& scale, const olc::Pixel tint) override + { + glBegin(GL_QUADS); + glColor4ub(tint.r, tint.g, tint.b, tint.a); + glTexCoord2f(0.0f * scale.x + offset.x, 1.0f * scale.y + offset.y); + glVertex3f(-1.0f /*+ vSubPixelOffset.x*/, -1.0f /*+ vSubPixelOffset.y*/, 0.0f); + glTexCoord2f(0.0f * scale.x + offset.x, 0.0f * scale.y + offset.y); + glVertex3f(-1.0f /*+ vSubPixelOffset.x*/, 1.0f /*+ vSubPixelOffset.y*/, 0.0f); + glTexCoord2f(1.0f * scale.x + offset.x, 0.0f * scale.y + offset.y); + glVertex3f(1.0f /*+ vSubPixelOffset.x*/, 1.0f /*+ vSubPixelOffset.y*/, 0.0f); + glTexCoord2f(1.0f * scale.x + offset.x, 1.0f * scale.y + offset.y); + glVertex3f(1.0f /*+ vSubPixelOffset.x*/, -1.0f /*+ vSubPixelOffset.y*/, 0.0f); + glEnd(); + } + + void DrawDecal(const olc::DecalInstance& decal) override + { + SetDecalMode(decal.mode); + + if (decal.decal == nullptr) + glBindTexture(GL_TEXTURE_2D, 0); + else + glBindTexture(GL_TEXTURE_2D, decal.decal->id); + + if (nDecalMode == DecalMode::MODEL3D) + { +#ifdef OLC_ENABLE_EXPERIMENTAL + glMatrixMode(GL_PROJECTION); glPushMatrix(); + glMatrixMode(GL_MODELVIEW); glPushMatrix(); + + glEnable(GL_DEPTH_TEST); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustum(-1.0f, 1.0f, -1.0f, 1.0f, 1, 1000); + + #pragma comment (lib, "winmm.lib") + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0, -40, -200); + glRotatef(float(clock()) * 0.1f, 1, 0, 0); + glRotatef(float(clock()) * 0.1f * 2, 0, 1, 0); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glBegin(GL_TRIANGLES); + + + // Render as 3D Spatial Entity + for (uint32_t n = 0; n < decal.points; n++) + { + glColor4ub(decal.tint[n].r, decal.tint[n].g, decal.tint[n].b, decal.tint[n].a); + glTexCoord2f(decal.uv[n].x, decal.uv[n].y); + glVertex3f(decal.pos[n].x, decal.pos[n].y, decal.w[n]); + } + + glEnd(); + + glMatrixMode(GL_PROJECTION); glPopMatrix(); + glMatrixMode(GL_MODELVIEW); glPopMatrix(); + glDisable(GL_DEPTH_TEST); +#endif + } + else + { + if (nDecalMode == DecalMode::WIREFRAME) + glBegin(GL_LINE_LOOP); + else + { + if(decal.structure == olc::DecalStructure::FAN) + glBegin(GL_TRIANGLE_FAN); + else if(decal.structure == olc::DecalStructure::STRIP) + glBegin(GL_TRIANGLE_STRIP); + else if(decal.structure == olc::DecalStructure::LIST) + glBegin(GL_TRIANGLES); + } + + // Render as 2D Spatial entity + for (uint32_t n = 0; n < decal.points; n++) + { + glColor4ub(decal.tint[n].r, decal.tint[n].g, decal.tint[n].b, decal.tint[n].a); + glTexCoord4f(decal.uv[n].x, decal.uv[n].y, 0.0f, decal.w[n]); + glVertex2f(decal.pos[n].x, decal.pos[n].y); + } + + glEnd(); + } + + + //glDisable(GL_DEPTH_TEST); + } + + uint32_t CreateTexture(const uint32_t width, const uint32_t height, const bool filtered, const bool clamp) override + { + UNUSED(width); + UNUSED(height); + uint32_t id = 0; + glGenTextures(1, &id); + glBindTexture(GL_TEXTURE_2D, id); + if (filtered) + { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + } + else + { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + } + + if (clamp) + { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + } + else + { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + } + + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + return id; + } + + uint32_t DeleteTexture(const uint32_t id) override + { + glDeleteTextures(1, &id); + return id; + } + + void UpdateTexture(uint32_t id, olc::Sprite* spr) override + { + UNUSED(id); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, spr->width, spr->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, spr->GetData()); + } + + void ReadTexture(uint32_t id, olc::Sprite* spr) override + { + glReadPixels(0, 0, spr->width, spr->height, GL_RGBA, GL_UNSIGNED_BYTE, spr->GetData()); + } + + void ApplyTexture(uint32_t id) override + { + glBindTexture(GL_TEXTURE_2D, id); + } + + void ClearBuffer(olc::Pixel p, bool bDepth) override + { + glClearColor(float(p.r) / 255.0f, float(p.g) / 255.0f, float(p.b) / 255.0f, float(p.a) / 255.0f); + glClear(GL_COLOR_BUFFER_BIT); + if (bDepth) glClear(GL_DEPTH_BUFFER_BIT); + } + + void UpdateViewport(const olc::vi2d& pos, const olc::vi2d& size) override + { + glViewport(pos.x, pos.y, size.x, size.y); + } + }; +} +#endif +// O------------------------------------------------------------------------------O +// | END RENDERER: OpenGL 1.0 (the original, the best...) | +// O------------------------------------------------------------------------------O +#pragma endregion + +#pragma region renderer_ogl33 +// O------------------------------------------------------------------------------O +// | START RENDERER: OpenGL 3.3 (3.0 es) (sh-sh-sh-shaders....) | +// O------------------------------------------------------------------------------O +#if defined(OLC_GFX_OPENGL33) + +#if defined(OLC_PLATFORM_WINAPI) + #include + //#include + #if !defined(__MINGW32__) + #pragma comment(lib, "Dwmapi.lib") + #endif + //typedef void __stdcall locSwapInterval_t(GLsizei n); + typedef HDC glDeviceContext_t; + typedef HGLRC glRenderContext_t; + //#define CALLSTYLE __stdcall + #define OGL_LOAD(t, n) (t*)wglGetProcAddress(#n) +#endif +// +//#if defined(__linux__) || defined(__FreeBSD__) +// #include +//#endif + +#if defined(OLC_PLATFORM_X11) + /*namespace X11 + { + #include + } + typedef int(locSwapInterval_t)(X11::Display* dpy, X11::GLXDrawable drawable, int interval);*/ + typedef X11::GLXContext glDeviceContext_t; + typedef X11::GLXContext glRenderContext_t; + //#define CALLSTYLE + #define OGL_LOAD(t, n) (t*)glXGetProcAddress((unsigned char*)#n); +#endif + +//#if defined(__APPLE__) +// #define GL_SILENCE_DEPRECATION +// #include +// #include +// #include +//#endif + +#if defined(OLC_PLATFORM_EMSCRIPTEN) + #include + #include + #define GL_GLEXT_PROTOTYPES + #include + #include + #define CALLSTYLE + typedef EGLBoolean(locSwapInterval_t)(EGLDisplay display, EGLint interval); + #define GL_CLAMP GL_CLAMP_TO_EDGE + #define OGL_LOAD(t, n) n; +#endif + +namespace olc +{ +// typedef char GLchar; +// typedef ptrdiff_t GLsizeiptr; +// typedef GLuint CALLSTYLE locCreateShader_t(GLenum type); +// typedef GLuint CALLSTYLE locCreateProgram_t(void); +// typedef void CALLSTYLE locDeleteShader_t(GLuint shader); +//#if defined(OLC_PLATFORM_EMSCRIPTEN) +// typedef void CALLSTYLE locShaderSource_t(GLuint shader, GLsizei count, const GLchar* const* string, const GLint* length); +//#else +// typedef void CALLSTYLE locShaderSource_t(GLuint shader, GLsizei count, const GLchar** string, const GLint* length); +//#endif +// typedef void CALLSTYLE locCompileShader_t(GLuint shader); +// typedef void CALLSTYLE locLinkProgram_t(GLuint program); +// typedef void CALLSTYLE locDeleteProgram_t(GLuint program); +// typedef void CALLSTYLE locAttachShader_t(GLuint program, GLuint shader); +// typedef void CALLSTYLE locBindBuffer_t(GLenum target, GLuint buffer); +// typedef void CALLSTYLE locBufferData_t(GLenum target, GLsizeiptr size, const void* data, GLenum usage); +// typedef void CALLSTYLE locGenBuffers_t(GLsizei n, GLuint* buffers); +// typedef void CALLSTYLE locVertexAttribPointer_t(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* pointer); +// typedef void CALLSTYLE locEnableVertexAttribArray_t(GLuint index); +// typedef void CALLSTYLE locUseProgram_t(GLuint program); +// typedef void CALLSTYLE locBindVertexArray_t(GLuint array); +// typedef void CALLSTYLE locGenVertexArrays_t(GLsizei n, GLuint* arrays); +// typedef void CALLSTYLE locGetShaderInfoLog_t(GLuint shader, GLsizei bufSize, GLsizei* length, GLchar* infoLog); +// typedef GLint CALLSTYLE locGetUniformLocation_t(GLuint program, const GLchar* name); +// typedef void CALLSTYLE locUniform1f_t(GLint location, GLfloat v0); +// typedef void CALLSTYLE locUniform1i_t(GLint location, GLint v0); +// typedef void CALLSTYLE locUniform2fv_t(GLint location, GLsizei count, const GLfloat* value); +// typedef void CALLSTYLE locActiveTexture_t(GLenum texture); +// typedef void CALLSTYLE locGenFrameBuffers_t(GLsizei n, GLuint* ids); +// typedef void CALLSTYLE locBindFrameBuffer_t(GLenum target, GLuint fb); +// typedef GLenum CALLSTYLE locCheckFrameBufferStatus_t(GLenum target); +// typedef void CALLSTYLE locDeleteFrameBuffers_t(GLsizei n, const GLuint* fbs); +// typedef void CALLSTYLE locFrameBufferTexture2D_t(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +// typedef void CALLSTYLE locDrawBuffers_t(GLsizei n, const GLenum* bufs); +// typedef void CALLSTYLE locBlendFuncSeparate_t(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); + + + + class Renderer_OGL33 : public olc::Renderer + { + private: +#if defined(OLC_PLATFORM_EMSCRIPTEN) + EGLDisplay olc_Display; + EGLConfig olc_Config; + EGLContext olc_Context; + EGLSurface olc_Surface; +#endif + +#if defined(OLC_PLATFORM_GLUT) + bool mFullScreen = false; +#else + #if !defined(OLC_PLATFORM_EMSCRIPTEN) + glDeviceContext_t glDeviceContext = 0; + glRenderContext_t glRenderContext = 0; + #endif +#endif + bool bSync = false; + olc::DecalMode nDecalMode = olc::DecalMode(-1); // Thanks Gusgo & Bispoo +#if defined(OLC_PLATFORM_X11) + X11::Display* olc_Display = nullptr; + X11::Window* olc_Window = nullptr; + X11::XVisualInfo* olc_VisualInfo = nullptr; +#endif + + private: + locCreateShader_t* locCreateShader = nullptr; + locShaderSource_t* locShaderSource = nullptr; + locCompileShader_t* locCompileShader = nullptr; + locDeleteShader_t* locDeleteShader = nullptr; + locCreateProgram_t* locCreateProgram = nullptr; + locDeleteProgram_t* locDeleteProgram = nullptr; + locLinkProgram_t* locLinkProgram = nullptr; + locAttachShader_t* locAttachShader = nullptr; + locBindBuffer_t* locBindBuffer = nullptr; + locBufferData_t* locBufferData = nullptr; + locGenBuffers_t* locGenBuffers = nullptr; + locVertexAttribPointer_t* locVertexAttribPointer = nullptr; + locEnableVertexAttribArray_t* locEnableVertexAttribArray = nullptr; + locUseProgram_t* locUseProgram = nullptr; + locBindVertexArray_t* locBindVertexArray = nullptr; + locGenVertexArrays_t* locGenVertexArrays = nullptr; + locSwapInterval_t* locSwapInterval = nullptr; + locGetShaderInfoLog_t* locGetShaderInfoLog = nullptr; + + uint32_t m_nFS = 0; + uint32_t m_nVS = 0; + uint32_t m_nQuadShader = 0; + uint32_t m_vbQuad = 0; + uint32_t m_vaQuad = 0; + + struct locVertex + { + float pos[3]; + olc::vf2d tex; + olc::Pixel col; + }; + + locVertex pVertexMem[OLC_MAX_VERTS]; + + olc::Renderable rendBlankQuad; + + public: + void PrepareDevice() override + { +#if defined(OLC_PLATFORM_GLUT) + //glutInit has to be called with main() arguments, make fake ones + int argc = 0; + char* argv[1] = { (char*)"" }; + glutInit(&argc, argv); + glutInitWindowPosition(0, 0); + glutInitWindowSize(512, 512); + glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH | GLUT_RGBA); + // Creates the window and the OpenGL context for it + glutCreateWindow("OneLoneCoder.com - Pixel Game Engine"); + glEnable(GL_TEXTURE_2D); // Turn on texturing + glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); +#endif + } + + olc::rcode CreateDevice(std::vector params, bool bFullScreen, bool bVSYNC) override + { + // Create OpenGL Context +#if defined(OLC_PLATFORM_WINAPI) + // Create Device Context + glDeviceContext = GetDC((HWND)(params[0])); + PIXELFORMATDESCRIPTOR pfd = + { + sizeof(PIXELFORMATDESCRIPTOR), 1, + PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, + PFD_TYPE_RGBA, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + PFD_MAIN_PLANE, 0, 0, 0, 0 + }; + + int pf = 0; + if (!(pf = ChoosePixelFormat(glDeviceContext, &pfd))) return olc::FAIL; + SetPixelFormat(glDeviceContext, pf, &pfd); + + if (!(glRenderContext = wglCreateContext(glDeviceContext))) return olc::FAIL; + wglMakeCurrent(glDeviceContext, glRenderContext); + + // Set Vertical Sync + locSwapInterval = OGL_LOAD(locSwapInterval_t, wglSwapIntervalEXT); + if (locSwapInterval && !bVSYNC) locSwapInterval(0); + bSync = bVSYNC; +#endif + +#if defined(OLC_PLATFORM_X11) + using namespace X11; + // Linux has tighter coupling between OpenGL and X11, so we store + // various "platform" handles in the renderer + olc_Display = (X11::Display*)(params[0]); + olc_Window = (X11::Window*)(params[1]); + olc_VisualInfo = (X11::XVisualInfo*)(params[2]); + + glDeviceContext = glXCreateContext(olc_Display, olc_VisualInfo, nullptr, GL_TRUE); + glXMakeCurrent(olc_Display, *olc_Window, glDeviceContext); + + XWindowAttributes gwa; + XGetWindowAttributes(olc_Display, *olc_Window, &gwa); + glViewport(0, 0, gwa.width, gwa.height); + + locSwapInterval = OGL_LOAD(locSwapInterval_t, glXSwapIntervalEXT); + + if (locSwapInterval == nullptr && !bVSYNC) + { + printf("NOTE: Could not disable VSYNC, glXSwapIntervalEXT() was not found!\n"); + printf(" Don't worry though, things will still work, it's just the\n"); + printf(" frame rate will be capped to your monitors refresh rate - javidx9\n"); + } + + if (locSwapInterval != nullptr && !bVSYNC) + locSwapInterval(olc_Display, *olc_Window, 0); +#endif + +#if defined(OLC_PLATFORM_EMSCRIPTEN) + EGLint const attribute_list[] = { EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8, EGL_NONE }; + EGLint const context_config[] = { EGL_CONTEXT_CLIENT_VERSION , 2, EGL_NONE }; + EGLint num_config; + + olc_Display = eglGetDisplay(EGL_DEFAULT_DISPLAY); + eglInitialize(olc_Display, nullptr, nullptr); + eglChooseConfig(olc_Display, attribute_list, &olc_Config, 1, &num_config); + + /* create an EGL rendering context */ + olc_Context = eglCreateContext(olc_Display, olc_Config, EGL_NO_CONTEXT, context_config); + olc_Surface = eglCreateWindowSurface(olc_Display, olc_Config, NULL, nullptr); + eglMakeCurrent(olc_Display, olc_Surface, olc_Surface, olc_Context); + //eglSwapInterval is currently a NOP, plement anyways in case it becomes supported + locSwapInterval = &eglSwapInterval; + locSwapInterval(olc_Display, bVSYNC ? 1 : 0); +#endif + +#if defined(OLC_PLATFORM_GLUT) + mFullScreen = bFullScreen; + if (!bVSYNC) + { +#if defined(__APPLE__) + GLint sync = 0; + CGLContextObj ctx = CGLGetCurrentContext(); + if (ctx) CGLSetParameter(ctx, kCGLCPSwapInterval, &sync); +#endif + } +#else + #if !defined(OLC_PLATFORM_EMSCRIPTEN) + glEnable(GL_TEXTURE_2D); // Turn on texturing + glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); + #endif +#endif + // Load External OpenGL Functions + locCreateShader = OGL_LOAD(locCreateShader_t, glCreateShader); + locCompileShader = OGL_LOAD(locCompileShader_t, glCompileShader); + locShaderSource = OGL_LOAD(locShaderSource_t, glShaderSource); + locDeleteShader = OGL_LOAD(locDeleteShader_t, glDeleteShader); + locCreateProgram = OGL_LOAD(locCreateProgram_t, glCreateProgram); + locDeleteProgram = OGL_LOAD(locDeleteProgram_t, glDeleteProgram); + locLinkProgram = OGL_LOAD(locLinkProgram_t, glLinkProgram); + locAttachShader = OGL_LOAD(locAttachShader_t, glAttachShader); + locBindBuffer = OGL_LOAD(locBindBuffer_t, glBindBuffer); + locBufferData = OGL_LOAD(locBufferData_t, glBufferData); + locGenBuffers = OGL_LOAD(locGenBuffers_t, glGenBuffers); + locVertexAttribPointer = OGL_LOAD(locVertexAttribPointer_t, glVertexAttribPointer); + locEnableVertexAttribArray = OGL_LOAD(locEnableVertexAttribArray_t, glEnableVertexAttribArray); + locUseProgram = OGL_LOAD(locUseProgram_t, glUseProgram); + locGetShaderInfoLog = OGL_LOAD(locGetShaderInfoLog_t, glGetShaderInfoLog); +#if !defined(OLC_PLATFORM_EMSCRIPTEN) + locBindVertexArray = OGL_LOAD(locBindVertexArray_t, glBindVertexArray); + locGenVertexArrays = OGL_LOAD(locGenVertexArrays_t, glGenVertexArrays); +#else + locBindVertexArray = glBindVertexArrayOES; + locGenVertexArrays = glGenVertexArraysOES; +#endif + + // Load & Compile Quad Shader - assumes no errors + m_nFS = locCreateShader(0x8B30); + const GLchar* strFS = +#if defined(__arm__) || defined(OLC_PLATFORM_EMSCRIPTEN) + "#version 300 es\n" + "precision mediump float;" +#else + "#version 330 core\n" +#endif + "out vec4 pixel;\n""in vec2 oTex;\n" + "in vec4 oCol;\n""uniform sampler2D sprTex;\n""void main(){pixel = texture(sprTex, oTex) * oCol;}"; + locShaderSource(m_nFS, 1, &strFS, NULL); + locCompileShader(m_nFS); + + m_nVS = locCreateShader(0x8B31); + const GLchar* strVS = +#if defined(__arm__) || defined(OLC_PLATFORM_EMSCRIPTEN) + "#version 300 es\n" + "precision mediump float;" +#else + "#version 330 core\n" +#endif + "layout(location = 0) in vec3 aPos;\n" + "layout(location = 1) in vec2 aTex;\n" + "layout(location = 2) in vec4 aCol;\n" + "out vec2 oTex;\n" + "out vec4 oCol;\n" + "uniform float mosaic;\n" + "\n" + "void main(){\n" + "float p = 1.0 / aPos.z;\n" + "gl_Position = p * vec4(aPos.x, aPos.y, 0.0, 1.0);\n" + "oTex = p * aTex;\n" + "oCol = vec4(aCol.r,mosaic,0,aCol.a);\n" + "}"; + locShaderSource(m_nVS, 1, &strVS, NULL); + locCompileShader(m_nVS); + + m_nQuadShader = locCreateProgram(); + locAttachShader(m_nQuadShader, m_nFS); + locAttachShader(m_nQuadShader, m_nVS); + locLinkProgram(m_nQuadShader); + + // Create Quad + locGenBuffers(1, &m_vbQuad); + locGenVertexArrays(1, &m_vaQuad); + locBindVertexArray(m_vaQuad); + locBindBuffer(0x8892, m_vbQuad); + + locVertex verts[OLC_MAX_VERTS]; + locBufferData(0x8892, sizeof(locVertex) * OLC_MAX_VERTS, verts, 0x88E0); + locVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(locVertex), 0); locEnableVertexAttribArray(0); + locVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(locVertex), (void*)(3 * sizeof(float))); locEnableVertexAttribArray(1); + locVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(locVertex), (void*)(5 * sizeof(float))); locEnableVertexAttribArray(2); + locBindBuffer(0x8892, 0); + locBindVertexArray(0); + + // Create blank texture for spriteless decals + rendBlankQuad.Create(1, 1); + rendBlankQuad.Sprite()->GetData()[0] = olc::WHITE; + rendBlankQuad.Decal()->Update(); + return olc::rcode::OK; + } + + olc::rcode DestroyDevice() override + { +#if defined(OLC_PLATFORM_WINAPI) + wglDeleteContext(glRenderContext); +#endif + +#if defined(OLC_PLATFORM_X11) + glXMakeCurrent(olc_Display, None, NULL); + glXDestroyContext(olc_Display, glDeviceContext); +#endif + +#if defined(OLC_PLATFORM_GLUT) + glutDestroyWindow(glutGetWindow()); +#endif + +#if defined(OLC_PLATFORM_EMSCRIPTEN) + eglMakeCurrent(olc_Display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + eglDestroyContext(olc_Display, olc_Context); + eglDestroySurface(olc_Display, olc_Surface); + eglTerminate(olc_Display); + olc_Display = EGL_NO_DISPLAY; + olc_Surface = EGL_NO_SURFACE; + olc_Context = EGL_NO_CONTEXT; +#endif + return olc::rcode::OK; + } + + void DisplayFrame() override + { +#if defined(OLC_PLATFORM_WINAPI) + SwapBuffers(glDeviceContext); + if (bSync) DwmFlush(); // Woooohooooooo!!!! SMOOOOOOOTH! +#endif + +#if defined(OLC_PLATFORM_X11) + X11::glXSwapBuffers(olc_Display, *olc_Window); +#endif + +#if defined(OLC_PLATFORM_GLUT) + glutSwapBuffers(); +#endif + +#if defined(OLC_PLATFORM_EMSCRIPTEN) + eglSwapBuffers(olc_Display, olc_Surface); +#endif + } + + void PrepareDrawing() override + { + glEnable(GL_BLEND); + nDecalMode = DecalMode::NORMAL; + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + locUseProgram(m_nQuadShader); + GLint myUniformLocation = glGetUniformLocation(m_nQuadShader, "mosaic"); + glUniform1f(myUniformLocation,1.0f); + locBindVertexArray(m_vaQuad); + +#if defined(OLC_PLATFORM_EMSCRIPTEN) + locVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(locVertex), 0); locEnableVertexAttribArray(0); + locVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(locVertex), (void*)(3 * sizeof(float))); locEnableVertexAttribArray(1); + locVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(locVertex), (void*)(5 * sizeof(float))); locEnableVertexAttribArray(2); +#endif + } + + void SetDecalMode(const olc::DecalMode& mode) override + { + if (mode != nDecalMode) + { + switch (mode) + { + case olc::DecalMode::NORMAL: glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); break; + case olc::DecalMode::ADDITIVE: glBlendFunc(GL_SRC_ALPHA, GL_ONE); break; + case olc::DecalMode::MULTIPLICATIVE: glBlendFunc(GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA); break; + case olc::DecalMode::STENCIL: glBlendFunc(GL_ZERO, GL_SRC_ALPHA); break; + case olc::DecalMode::ILLUMINATE: glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA); break; + case olc::DecalMode::WIREFRAME: glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); break; + } + + nDecalMode = mode; + } + } + + void DrawLayerQuad(const olc::vf2d& offset, const olc::vf2d& scale, const olc::Pixel tint) override + { + locBindBuffer(0x8892, m_vbQuad); + locVertex verts[4] = { + {{-1.0f, -1.0f, 1.0}, {0.0f * scale.x + offset.x, 1.0f * scale.y + offset.y}, tint}, + {{+1.0f, -1.0f, 1.0}, {1.0f * scale.x + offset.x, 1.0f * scale.y + offset.y}, tint}, + {{-1.0f, +1.0f, 1.0}, {0.0f * scale.x + offset.x, 0.0f * scale.y + offset.y}, tint}, + {{+1.0f, +1.0f, 1.0}, {1.0f * scale.x + offset.x, 0.0f * scale.y + offset.y}, tint}, + }; + + locBufferData(0x8892, sizeof(locVertex) * 4, verts, 0x88E0); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + } + + void DrawDecal(const olc::DecalInstance& decal) override + { + SetDecalMode(decal.mode); + if (decal.decal == nullptr) + glBindTexture(GL_TEXTURE_2D, rendBlankQuad.Decal()->id); + else + glBindTexture(GL_TEXTURE_2D, decal.decal->id); + + locBindBuffer(0x8892, m_vbQuad); + + for (uint32_t i = 0; i < decal.points; i++) + pVertexMem[i] = { { decal.pos[i].x, decal.pos[i].y, decal.w[i] }, { decal.uv[i].x, decal.uv[i].y }, decal.tint[i] }; + + locBufferData(0x8892, sizeof(locVertex) * decal.points, pVertexMem, 0x88E0); + + if (nDecalMode == DecalMode::WIREFRAME) + glDrawArrays(GL_LINE_LOOP, 0, decal.points); + else + { + if (decal.structure == olc::DecalStructure::FAN) + glDrawArrays(GL_TRIANGLE_FAN, 0, decal.points); + else if (decal.structure == olc::DecalStructure::STRIP) + glDrawArrays(GL_TRIANGLE_STRIP, 0, decal.points); + else if (decal.structure == olc::DecalStructure::LIST) + glDrawArrays(GL_TRIANGLES, 0, decal.points); + } + } + + uint32_t CreateTexture(const uint32_t width, const uint32_t height, const bool filtered, const bool clamp) override + { + UNUSED(width); + UNUSED(height); + uint32_t id = 0; + glGenTextures(1, &id); + glBindTexture(GL_TEXTURE_2D, id); + + if (filtered) + { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + } + else + { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + } + + if (clamp) + { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + } + else + { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + } +#if !defined(OLC_PLATFORM_EMSCRIPTEN) + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); +#endif + return id; + } + + uint32_t DeleteTexture(const uint32_t id) override + { + glDeleteTextures(1, &id); + return id; + } + + void UpdateTexture(uint32_t id, olc::Sprite* spr) override + { + UNUSED(id); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, spr->width, spr->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, spr->GetData()); + } + + void ReadTexture(uint32_t id, olc::Sprite* spr) override + { + glReadPixels(0, 0, spr->width, spr->height, GL_RGBA, GL_UNSIGNED_BYTE, spr->GetData()); + } + + void ApplyTexture(uint32_t id) override + { + glBindTexture(GL_TEXTURE_2D, id); + } + + void ClearBuffer(olc::Pixel p, bool bDepth) override + { + glClearColor(float(p.r) / 255.0f, float(p.g) / 255.0f, float(p.b) / 255.0f, float(p.a) / 255.0f); + glClear(GL_COLOR_BUFFER_BIT); + if (bDepth) glClear(GL_DEPTH_BUFFER_BIT); + } + + void UpdateViewport(const olc::vi2d& pos, const olc::vi2d& size) override + { + glViewport(pos.x, pos.y, size.x, size.y); + } + }; +} +#endif +// O------------------------------------------------------------------------------O +// | END RENDERER: OpenGL 3.3 (3.0 es) (sh-sh-sh-shaders....) | +// O------------------------------------------------------------------------------O +#pragma endregion + +// O------------------------------------------------------------------------------O +// | olcPixelGameEngine Image loaders | +// O------------------------------------------------------------------------------O + +#pragma region image_gdi +// O------------------------------------------------------------------------------O +// | START IMAGE LOADER: GDI+, Windows Only, always exists, a little slow | +// O------------------------------------------------------------------------------O +#if defined(OLC_IMAGE_GDI) + +#define min(a, b) ((a < b) ? a : b) +#define max(a, b) ((a > b) ? a : b) +#include +#include +#if defined(__MINGW32__) // Thanks Gusgo & Dandistine, but c'mon mingw!! wtf?! + #include +#else + #include +#endif +#include +#undef min +#undef max + +#if !defined(__MINGW32__) + #pragma comment(lib, "gdiplus.lib") + #pragma comment(lib, "Shlwapi.lib") +#endif + +namespace olc +{ + // Thanks @MaGetzUb for this, which allows sprites to be defined + // at construction, by initialising the GDI subsystem + static class GDIPlusStartup + { + public: + GDIPlusStartup() + { + Gdiplus::GdiplusStartupInput startupInput; + GdiplusStartup(&token, &startupInput, NULL); + } + + ULONG_PTR token; + + ~GDIPlusStartup() + { + // Well, MarcusTU thought this was important :D + Gdiplus::GdiplusShutdown(token); + } + } gdistartup; + + class ImageLoader_GDIPlus : public olc::ImageLoader + { + private: + std::wstring ConvertS2W(std::string s) + { +#ifdef __MINGW32__ + wchar_t* buffer = new wchar_t[s.length() + 1]; + mbstowcs(buffer, s.c_str(), s.length()); + buffer[s.length()] = L'\0'; +#else + int count = MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, NULL, 0); + wchar_t* buffer = new wchar_t[count]; + MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, buffer, count); +#endif + std::wstring w(buffer); + delete[] buffer; + return w; + } + + public: + ImageLoader_GDIPlus() : ImageLoader() + {} + + olc::rcode LoadImageResource(olc::Sprite* spr, const std::string& sImageFile, olc::ResourcePack* pack) override + { + // clear out existing sprite + spr->pColData.clear(); + + // Open file + UNUSED(pack); + Gdiplus::Bitmap* bmp = nullptr; + if (pack != nullptr) + { + // Load sprite from input stream + ResourceBuffer rb = pack->GetFileBuffer(sImageFile); + bmp = Gdiplus::Bitmap::FromStream(SHCreateMemStream((BYTE*)rb.vMemory.data(), UINT(rb.vMemory.size()))); + } + else + { + // Check file exists + if (!_gfs::exists(sImageFile)) return olc::rcode::NO_FILE; + + // Load sprite from file + bmp = Gdiplus::Bitmap::FromFile(ConvertS2W(sImageFile).c_str()); + } + + if (bmp->GetLastStatus() != Gdiplus::Ok) return olc::rcode::FAIL; + spr->width = bmp->GetWidth(); + spr->height = bmp->GetHeight(); + + spr->pColData.resize(spr->width * spr->height); + + for (int y = 0; y < spr->height; y++) + for (int x = 0; x < spr->width; x++) + { + Gdiplus::Color c; + bmp->GetPixel(x, y, &c); + spr->SetPixel(x, y, olc::Pixel(c.GetRed(), c.GetGreen(), c.GetBlue(), c.GetAlpha())); + } + delete bmp; + return olc::rcode::OK; + } + + olc::rcode SaveImageResource(olc::Sprite* spr, const std::string& sImageFile) override + { + return olc::rcode::OK; + } + }; +} +#endif +// O------------------------------------------------------------------------------O +// | END IMAGE LOADER: GDI+ | +// O------------------------------------------------------------------------------O +#pragma endregion + +#pragma region image_libpng +// O------------------------------------------------------------------------------O +// | START IMAGE LOADER: libpng, default on linux, requires -lpng (libpng-dev) | +// O------------------------------------------------------------------------------O +#if defined(OLC_IMAGE_LIBPNG) +#include +namespace olc +{ + void pngReadStream(png_structp pngPtr, png_bytep data, png_size_t length) + { + png_voidp a = png_get_io_ptr(pngPtr); + ((std::istream*)a)->read((char*)data, length); + } + + class ImageLoader_LibPNG : public olc::ImageLoader + { + public: + ImageLoader_LibPNG() : ImageLoader() + {} + + olc::rcode LoadImageResource(olc::Sprite* spr, const std::string& sImageFile, olc::ResourcePack* pack) override + { + UNUSED(pack); + + // clear out existing sprite + spr->pColData.clear(); + + //////////////////////////////////////////////////////////////////////////// + // Use libpng, Thanks to Guillaume Cottenceau + // https://gist.github.com/niw/5963798 + // Also reading png from streams + // http://www.piko3d.net/tutorials/libpng-tutorial-loading-png-files-from-streams/ + png_structp png; + png_infop info; + + auto loadPNG = [&]() + { + png_read_info(png, info); + png_byte color_type; + png_byte bit_depth; + png_bytep* row_pointers; + spr->width = png_get_image_width(png, info); + spr->height = png_get_image_height(png, info); + color_type = png_get_color_type(png, info); + bit_depth = png_get_bit_depth(png, info); + if (bit_depth == 16) png_set_strip_16(png); + if (color_type == PNG_COLOR_TYPE_PALETTE) png_set_palette_to_rgb(png); + if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) png_set_expand_gray_1_2_4_to_8(png); + if (png_get_valid(png, info, PNG_INFO_tRNS)) png_set_tRNS_to_alpha(png); + if (color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_PALETTE) + png_set_filler(png, 0xFF, PNG_FILLER_AFTER); + if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + png_set_gray_to_rgb(png); + png_read_update_info(png, info); + row_pointers = (png_bytep*)malloc(sizeof(png_bytep) * spr->height); + for (int y = 0; y < spr->height; y++) { + row_pointers[y] = (png_byte*)malloc(png_get_rowbytes(png, info)); + } + png_read_image(png, row_pointers); + //////////////////////////////////////////////////////////////////////////// + // Create sprite array + spr->pColData.resize(spr->width * spr->height); + // Iterate through image rows, converting into sprite format + for (int y = 0; y < spr->height; y++) + { + png_bytep row = row_pointers[y]; + for (int x = 0; x < spr->width; x++) + { + png_bytep px = &(row[x * 4]); + spr->SetPixel(x, y, Pixel(px[0], px[1], px[2], px[3])); + } + } + + for (int y = 0; y < spr->height; y++) // Thanks maksym33 + free(row_pointers[y]); + free(row_pointers); + png_destroy_read_struct(&png, &info, nullptr); + }; + + png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + if (!png) goto fail_load; + + info = png_create_info_struct(png); + if (!info) goto fail_load; + + if (setjmp(png_jmpbuf(png))) goto fail_load; + + if (pack == nullptr) + { + FILE* f = fopen(sImageFile.c_str(), "rb"); + if (!f) return olc::rcode::NO_FILE; + png_init_io(png, f); + loadPNG(); + fclose(f); + } + else + { + ResourceBuffer rb = pack->GetFileBuffer(sImageFile); + std::istream is(&rb); + png_set_read_fn(png, (png_voidp)&is, pngReadStream); + loadPNG(); + } + + return olc::rcode::OK; + + fail_load: + spr->width = 0; + spr->height = 0; + spr->pColData.clear(); + return olc::rcode::FAIL; + } + + olc::rcode SaveImageResource(olc::Sprite* spr, const std::string& sImageFile) override + { + return olc::rcode::OK; + } + }; +} +#endif +// O------------------------------------------------------------------------------O +// | END IMAGE LOADER: | +// O------------------------------------------------------------------------------O +#pragma endregion + + +// O------------------------------------------------------------------------------O +// | olcPixelGameEngine Platforms | +// O------------------------------------------------------------------------------O + +#pragma region platform_windows +// O------------------------------------------------------------------------------O +// | START PLATFORM: MICROSOFT WINDOWS XP, VISTA, 7, 8, 10 | +// O------------------------------------------------------------------------------O +#if defined(OLC_PLATFORM_WINAPI) + +#if defined(_WIN32) && !defined(__MINGW32__) + #pragma comment(lib, "user32.lib") // Visual Studio Only + #pragma comment(lib, "gdi32.lib") // For other Windows Compilers please add + #pragma comment(lib, "opengl32.lib") // these libs to your linker input +#endif + +namespace olc +{ + class Platform_Windows : public olc::Platform + { + private: + HWND olc_hWnd = nullptr; + std::wstring wsAppName; + + std::wstring ConvertS2W(std::string s) + { +#ifdef __MINGW32__ + wchar_t* buffer = new wchar_t[s.length() + 1]; + mbstowcs(buffer, s.c_str(), s.length()); + buffer[s.length()] = L'\0'; +#else + int count = MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, NULL, 0); + wchar_t* buffer = new wchar_t[count]; + MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, buffer, count); +#endif + std::wstring w(buffer); + delete[] buffer; + return w; + } + + + + public: + virtual olc::rcode ApplicationStartUp() override { return olc::rcode::OK; } + virtual olc::rcode ApplicationCleanUp() override { return olc::rcode::OK; } + virtual olc::rcode ThreadStartUp() override { return olc::rcode::OK; } + + virtual olc::rcode ThreadCleanUp() override + { + renderer->DestroyDevice(); + PostMessage(olc_hWnd, WM_DESTROY, 0, 0); + return olc::OK; + } + + virtual olc::rcode CreateGraphics(bool bFullScreen, bool bEnableVSYNC, const olc::vi2d& vViewPos, const olc::vi2d& vViewSize) override + { + if (renderer->CreateDevice({ olc_hWnd }, bFullScreen, bEnableVSYNC) == olc::rcode::OK) + { + renderer->UpdateViewport(vViewPos, vViewSize); + return olc::rcode::OK; + } + else + return olc::rcode::FAIL; + } + + virtual olc::rcode CreateWindowPane(const olc::vi2d& vWindowPos, olc::vi2d& vWindowSize, bool bFullScreen) override + { + WNDCLASS wc; + wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; + wc.hInstance = GetModuleHandle(nullptr); + wc.lpfnWndProc = olc_WindowEvent; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.lpszMenuName = nullptr; + wc.hbrBackground = nullptr; + wc.lpszClassName = olcT("OLC_PIXEL_GAME_ENGINE"); + RegisterClass(&wc); + + // Define window furniture + DWORD dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; + DWORD dwStyle = WS_CAPTION | WS_SYSMENU | WS_VISIBLE | WS_THICKFRAME; + + olc::vi2d vTopLeft = vWindowPos; + + // Handle Fullscreen + if (bFullScreen) + { + dwExStyle = 0; + dwStyle = WS_VISIBLE | WS_POPUP; + HMONITOR hmon = MonitorFromWindow(olc_hWnd, MONITOR_DEFAULTTONEAREST); + MONITORINFO mi = { sizeof(mi) }; + if (!GetMonitorInfo(hmon, &mi)) return olc::rcode::FAIL; + vWindowSize = { mi.rcMonitor.right, mi.rcMonitor.bottom }; + vTopLeft.x = 0; + vTopLeft.y = 0; + } + + // Keep client size as requested + RECT rWndRect = { 0, 0, vWindowSize.x, vWindowSize.y }; + AdjustWindowRectEx(&rWndRect, dwStyle, FALSE, dwExStyle); + int width = rWndRect.right - rWndRect.left; + int height = rWndRect.bottom - rWndRect.top; + + olc_hWnd = CreateWindowEx(dwExStyle, olcT("OLC_PIXEL_GAME_ENGINE"), olcT(""), dwStyle, + vTopLeft.x, vTopLeft.y, width, height, NULL, NULL, GetModuleHandle(nullptr), this); + + DragAcceptFiles(olc_hWnd, true); + + // Create Keyboard Mapping + mapKeys[0x00] = Key::NONE; + mapKeys[0x41] = Key::A; mapKeys[0x42] = Key::B; mapKeys[0x43] = Key::C; mapKeys[0x44] = Key::D; mapKeys[0x45] = Key::E; + mapKeys[0x46] = Key::F; mapKeys[0x47] = Key::G; mapKeys[0x48] = Key::H; mapKeys[0x49] = Key::I; mapKeys[0x4A] = Key::J; + mapKeys[0x4B] = Key::K; mapKeys[0x4C] = Key::L; mapKeys[0x4D] = Key::M; mapKeys[0x4E] = Key::N; mapKeys[0x4F] = Key::O; + mapKeys[0x50] = Key::P; mapKeys[0x51] = Key::Q; mapKeys[0x52] = Key::R; mapKeys[0x53] = Key::S; mapKeys[0x54] = Key::T; + mapKeys[0x55] = Key::U; mapKeys[0x56] = Key::V; mapKeys[0x57] = Key::W; mapKeys[0x58] = Key::X; mapKeys[0x59] = Key::Y; + mapKeys[0x5A] = Key::Z; + + mapKeys[VK_F1] = Key::F1; mapKeys[VK_F2] = Key::F2; mapKeys[VK_F3] = Key::F3; mapKeys[VK_F4] = Key::F4; + mapKeys[VK_F5] = Key::F5; mapKeys[VK_F6] = Key::F6; mapKeys[VK_F7] = Key::F7; mapKeys[VK_F8] = Key::F8; + mapKeys[VK_F9] = Key::F9; mapKeys[VK_F10] = Key::F10; mapKeys[VK_F11] = Key::F11; mapKeys[VK_F12] = Key::F12; + + mapKeys[VK_DOWN] = Key::DOWN; mapKeys[VK_LEFT] = Key::LEFT; mapKeys[VK_RIGHT] = Key::RIGHT; mapKeys[VK_UP] = Key::UP; + //mapKeys[VK_RETURN] = Key::ENTER;// mapKeys[VK_RETURN] = Key::RETURN; + + mapKeys[VK_BACK] = Key::BACK; mapKeys[VK_ESCAPE] = Key::ESCAPE; mapKeys[VK_RETURN] = Key::ENTER; mapKeys[VK_PAUSE] = Key::PAUSE; + mapKeys[VK_SCROLL] = Key::SCROLL; mapKeys[VK_TAB] = Key::TAB; mapKeys[VK_DELETE] = Key::DEL; mapKeys[VK_HOME] = Key::HOME; + mapKeys[VK_END] = Key::END; mapKeys[VK_PRIOR] = Key::PGUP; mapKeys[VK_NEXT] = Key::PGDN; mapKeys[VK_INSERT] = Key::INS; + mapKeys[VK_SHIFT] = Key::SHIFT; mapKeys[VK_CONTROL] = Key::CTRL; + mapKeys[VK_SPACE] = Key::SPACE; + + mapKeys[0x30] = Key::K0; mapKeys[0x31] = Key::K1; mapKeys[0x32] = Key::K2; mapKeys[0x33] = Key::K3; mapKeys[0x34] = Key::K4; + mapKeys[0x35] = Key::K5; mapKeys[0x36] = Key::K6; mapKeys[0x37] = Key::K7; mapKeys[0x38] = Key::K8; mapKeys[0x39] = Key::K9; + + mapKeys[VK_NUMPAD0] = Key::NP0; mapKeys[VK_NUMPAD1] = Key::NP1; mapKeys[VK_NUMPAD2] = Key::NP2; mapKeys[VK_NUMPAD3] = Key::NP3; mapKeys[VK_NUMPAD4] = Key::NP4; + mapKeys[VK_NUMPAD5] = Key::NP5; mapKeys[VK_NUMPAD6] = Key::NP6; mapKeys[VK_NUMPAD7] = Key::NP7; mapKeys[VK_NUMPAD8] = Key::NP8; mapKeys[VK_NUMPAD9] = Key::NP9; + mapKeys[VK_MULTIPLY] = Key::NP_MUL; mapKeys[VK_ADD] = Key::NP_ADD; mapKeys[VK_DIVIDE] = Key::NP_DIV; mapKeys[VK_SUBTRACT] = Key::NP_SUB; mapKeys[VK_DECIMAL] = Key::NP_DECIMAL; + + // Thanks scripticuk + mapKeys[VK_OEM_1] = Key::OEM_1; // On US and UK keyboards this is the ';:' key + mapKeys[VK_OEM_2] = Key::OEM_2; // On US and UK keyboards this is the '/?' key + mapKeys[VK_OEM_3] = Key::OEM_3; // On US keyboard this is the '~' key + mapKeys[VK_OEM_4] = Key::OEM_4; // On US and UK keyboards this is the '[{' key + mapKeys[VK_OEM_5] = Key::OEM_5; // On US keyboard this is '\|' key. + mapKeys[VK_OEM_6] = Key::OEM_6; // On US and UK keyboards this is the ']}' key + mapKeys[VK_OEM_7] = Key::OEM_7; // On US keyboard this is the single/double quote key. On UK, this is the single quote/@ symbol key + mapKeys[VK_OEM_8] = Key::OEM_8; // miscellaneous characters. Varies by keyboard + mapKeys[VK_OEM_PLUS] = Key::EQUALS; // the '+' key on any keyboard + mapKeys[VK_OEM_COMMA] = Key::COMMA; // the comma key on any keyboard + mapKeys[VK_OEM_MINUS] = Key::MINUS; // the minus key on any keyboard + mapKeys[VK_OEM_PERIOD] = Key::PERIOD; // the period key on any keyboard + mapKeys[VK_CAPITAL] = Key::CAPS_LOCK; + return olc::OK; + } + + virtual olc::rcode SetWindowTitle(const std::string& s) override + { +#ifdef UNICODE + SetWindowText(olc_hWnd, ConvertS2W(s).c_str()); +#else + SetWindowText(olc_hWnd, s.c_str()); +#endif + return olc::OK; + } + + virtual olc::rcode StartSystemEventLoop() override + { + MSG msg; + while (GetMessage(&msg, NULL, 0, 0) > 0) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + return olc::OK; + } + + virtual olc::rcode HandleSystemEvent() override { return olc::rcode::FAIL; } + + // Windows Event Handler - this is statically connected to the windows event system + static LRESULT CALLBACK olc_WindowEvent(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) + { + switch (uMsg) + { + case WM_MOUSEMOVE: + { + // Thanks @ForAbby (Discord) + uint16_t x = lParam & 0xFFFF; uint16_t y = (lParam >> 16) & 0xFFFF; + int16_t ix = *(int16_t*)&x; int16_t iy = *(int16_t*)&y; + ptrPGE->olc_UpdateMouse(ix, iy); + return 0; + } + case WM_SIZE: ptrPGE->olc_UpdateWindowSize(lParam & 0xFFFF, (lParam >> 16) & 0xFFFF); return 0; + case WM_MOUSEWHEEL: ptrPGE->olc_UpdateMouseWheel(GET_WHEEL_DELTA_WPARAM(wParam)); return 0; + case WM_MOUSELEAVE: ptrPGE->olc_UpdateMouseFocus(false); return 0; + case WM_SETFOCUS: ptrPGE->olc_UpdateKeyFocus(true); return 0; + case WM_KILLFOCUS: ptrPGE->olc_UpdateKeyFocus(false); return 0; + case WM_KEYDOWN: ptrPGE->olc_UpdateKeyState(mapKeys[wParam], true); return 0; + case WM_KEYUP: ptrPGE->olc_UpdateKeyState(mapKeys[wParam], false); return 0; + case WM_SYSKEYDOWN: ptrPGE->olc_UpdateKeyState(mapKeys[wParam], true); return 0; + case WM_SYSKEYUP: ptrPGE->olc_UpdateKeyState(mapKeys[wParam], false); return 0; + case WM_LBUTTONDOWN:ptrPGE->olc_UpdateMouseState(0, true); return 0; + case WM_LBUTTONUP: ptrPGE->olc_UpdateMouseState(0, false); return 0; + case WM_RBUTTONDOWN:ptrPGE->olc_UpdateMouseState(1, true); return 0; + case WM_RBUTTONUP: ptrPGE->olc_UpdateMouseState(1, false); return 0; + case WM_MBUTTONDOWN:ptrPGE->olc_UpdateMouseState(2, true); return 0; + case WM_MBUTTONUP: ptrPGE->olc_UpdateMouseState(2, false); return 0; + case WM_DROPFILES: + { + // This is all eww... + HDROP drop = (HDROP)wParam; + + uint32_t nFiles = DragQueryFile(drop, 0xFFFFFFFF, nullptr, 0); + std::vector vFiles; + for (uint32_t i = 0; i < nFiles; i++) + { + TCHAR dfbuffer[256]{}; + uint32_t len = DragQueryFile(drop, i, nullptr, 0); + DragQueryFile(drop, i, dfbuffer, 256); +#ifdef UNICODE + #ifdef __MINGW32__ + char* buffer = new char[len + 1]; + wcstombs(buffer, dfbuffer, len); + buffer[len] = '\0'; + #else + int count = WideCharToMultiByte(CP_UTF8, 0, dfbuffer, -1, NULL, 0, NULL, NULL); + char* buffer = new char[count]; + WideCharToMultiByte(CP_UTF8, 0, dfbuffer, -1, buffer, count, NULL, NULL); + #endif + vFiles.push_back(std::string(buffer)); + delete[] buffer; +#else + vFiles.push_back(std::string(dfbuffer)); +#endif + } + + // Even more eww... + POINT p; DragQueryPoint(drop, &p); + ptrPGE->olc_DropFiles(p.x, p.y, vFiles); + DragFinish(drop); + return 0; + } + break; + + + case WM_CLOSE: ptrPGE->olc_Terminate(); return 0; + case WM_DESTROY: PostQuitMessage(0); DestroyWindow(hWnd); return 0; + } + return DefWindowProc(hWnd, uMsg, wParam, lParam); + } + }; +} +#endif +// O------------------------------------------------------------------------------O +// | END PLATFORM: MICROSOFT WINDOWS XP, VISTA, 7, 8, 10 | +// O------------------------------------------------------------------------------O +#pragma endregion + +#pragma region platform_linux +// O------------------------------------------------------------------------------O +// | START PLATFORM: LINUX | +// O------------------------------------------------------------------------------O +#if defined(OLC_PLATFORM_X11) +namespace olc +{ + class Platform_Linux : public olc::Platform + { + private: + X11::Display* olc_Display = nullptr; + X11::Window olc_WindowRoot; + X11::Window olc_Window; + X11::XVisualInfo* olc_VisualInfo; + X11::Colormap olc_ColourMap; + X11::XSetWindowAttributes olc_SetWindowAttribs; + + public: + virtual olc::rcode ApplicationStartUp() override + { + return olc::rcode::OK; + } + + virtual olc::rcode ApplicationCleanUp() override + { + XDestroyWindow(olc_Display, olc_Window); + return olc::rcode::OK; + } + + virtual olc::rcode ThreadStartUp() override + { + return olc::rcode::OK; + } + + virtual olc::rcode ThreadCleanUp() override + { + renderer->DestroyDevice(); + return olc::OK; + } + + virtual olc::rcode CreateGraphics(bool bFullScreen, bool bEnableVSYNC, const olc::vi2d& vViewPos, const olc::vi2d& vViewSize) override + { + if (renderer->CreateDevice({ olc_Display, &olc_Window, olc_VisualInfo }, bFullScreen, bEnableVSYNC) == olc::rcode::OK) + { + renderer->UpdateViewport(vViewPos, vViewSize); + return olc::rcode::OK; + } + else + return olc::rcode::FAIL; + } + + virtual olc::rcode CreateWindowPane(const olc::vi2d& vWindowPos, olc::vi2d& vWindowSize, bool bFullScreen) override + { + using namespace X11; + XInitThreads(); + + // Grab the deafult display and window + olc_Display = XOpenDisplay(NULL); + olc_WindowRoot = DefaultRootWindow(olc_Display); + + // Based on the display capabilities, configure the appearance of the window + GLint olc_GLAttribs[] = { GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, None }; + olc_VisualInfo = glXChooseVisual(olc_Display, 0, olc_GLAttribs); + olc_ColourMap = XCreateColormap(olc_Display, olc_WindowRoot, olc_VisualInfo->visual, AllocNone); + olc_SetWindowAttribs.colormap = olc_ColourMap; + + // Register which events we are interested in receiving + olc_SetWindowAttribs.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask | + ButtonPressMask | ButtonReleaseMask | PointerMotionMask | FocusChangeMask | StructureNotifyMask; + + // Create the window + olc_Window = XCreateWindow(olc_Display, olc_WindowRoot, vWindowPos.x, vWindowPos.y, + vWindowSize.x, vWindowSize.y, + 0, olc_VisualInfo->depth, InputOutput, olc_VisualInfo->visual, + CWColormap | CWEventMask, &olc_SetWindowAttribs); + + Atom wmDelete = XInternAtom(olc_Display, "WM_DELETE_WINDOW", true); + XSetWMProtocols(olc_Display, olc_Window, &wmDelete, 1); + + XMapWindow(olc_Display, olc_Window); + XStoreName(olc_Display, olc_Window, "OneLoneCoder.com - Pixel Game Engine"); + + if (bFullScreen) // Thanks DragonEye, again :D + { + Atom wm_state; + Atom fullscreen; + wm_state = XInternAtom(olc_Display, "_NET_WM_STATE", False); + fullscreen = XInternAtom(olc_Display, "_NET_WM_STATE_FULLSCREEN", False); + XEvent xev{ 0 }; + xev.type = ClientMessage; + xev.xclient.window = olc_Window; + xev.xclient.message_type = wm_state; + xev.xclient.format = 32; + xev.xclient.data.l[0] = (bFullScreen ? 1 : 0); // the action (0: off, 1: on, 2: toggle) + xev.xclient.data.l[1] = fullscreen; // first property to alter + xev.xclient.data.l[2] = 0; // second property to alter + xev.xclient.data.l[3] = 0; // source indication + XMapWindow(olc_Display, olc_Window); + XSendEvent(olc_Display, DefaultRootWindow(olc_Display), False, + SubstructureRedirectMask | SubstructureNotifyMask, &xev); + XFlush(olc_Display); + XWindowAttributes gwa; + XGetWindowAttributes(olc_Display, olc_Window, &gwa); + vWindowSize.x = gwa.width; + vWindowSize.y = gwa.height; + } + + // Create Keyboard Mapping + mapKeys[0x00] = Key::NONE; + mapKeys[0x61] = Key::A; mapKeys[0x62] = Key::B; mapKeys[0x63] = Key::C; mapKeys[0x64] = Key::D; mapKeys[0x65] = Key::E; + mapKeys[0x66] = Key::F; mapKeys[0x67] = Key::G; mapKeys[0x68] = Key::H; mapKeys[0x69] = Key::I; mapKeys[0x6A] = Key::J; + mapKeys[0x6B] = Key::K; mapKeys[0x6C] = Key::L; mapKeys[0x6D] = Key::M; mapKeys[0x6E] = Key::N; mapKeys[0x6F] = Key::O; + mapKeys[0x70] = Key::P; mapKeys[0x71] = Key::Q; mapKeys[0x72] = Key::R; mapKeys[0x73] = Key::S; mapKeys[0x74] = Key::T; + mapKeys[0x75] = Key::U; mapKeys[0x76] = Key::V; mapKeys[0x77] = Key::W; mapKeys[0x78] = Key::X; mapKeys[0x79] = Key::Y; + mapKeys[0x7A] = Key::Z; + + mapKeys[XK_F1] = Key::F1; mapKeys[XK_F2] = Key::F2; mapKeys[XK_F3] = Key::F3; mapKeys[XK_F4] = Key::F4; + mapKeys[XK_F5] = Key::F5; mapKeys[XK_F6] = Key::F6; mapKeys[XK_F7] = Key::F7; mapKeys[XK_F8] = Key::F8; + mapKeys[XK_F9] = Key::F9; mapKeys[XK_F10] = Key::F10; mapKeys[XK_F11] = Key::F11; mapKeys[XK_F12] = Key::F12; + + mapKeys[XK_Down] = Key::DOWN; mapKeys[XK_Left] = Key::LEFT; mapKeys[XK_Right] = Key::RIGHT; mapKeys[XK_Up] = Key::UP; + mapKeys[XK_KP_Enter] = Key::ENTER; mapKeys[XK_Return] = Key::ENTER; + + mapKeys[XK_BackSpace] = Key::BACK; mapKeys[XK_Escape] = Key::ESCAPE; mapKeys[XK_Linefeed] = Key::ENTER; mapKeys[XK_Pause] = Key::PAUSE; + mapKeys[XK_Scroll_Lock] = Key::SCROLL; mapKeys[XK_Tab] = Key::TAB; mapKeys[XK_Delete] = Key::DEL; mapKeys[XK_Home] = Key::HOME; + mapKeys[XK_End] = Key::END; mapKeys[XK_Page_Up] = Key::PGUP; mapKeys[XK_Page_Down] = Key::PGDN; mapKeys[XK_Insert] = Key::INS; + mapKeys[XK_Shift_L] = Key::SHIFT; mapKeys[XK_Shift_R] = Key::SHIFT; mapKeys[XK_Control_L] = Key::CTRL; mapKeys[XK_Control_R] = Key::CTRL; + mapKeys[XK_space] = Key::SPACE; mapKeys[XK_period] = Key::PERIOD; + + mapKeys[XK_0] = Key::K0; mapKeys[XK_1] = Key::K1; mapKeys[XK_2] = Key::K2; mapKeys[XK_3] = Key::K3; mapKeys[XK_4] = Key::K4; + mapKeys[XK_5] = Key::K5; mapKeys[XK_6] = Key::K6; mapKeys[XK_7] = Key::K7; mapKeys[XK_8] = Key::K8; mapKeys[XK_9] = Key::K9; + + mapKeys[XK_KP_0] = Key::NP0; mapKeys[XK_KP_1] = Key::NP1; mapKeys[XK_KP_2] = Key::NP2; mapKeys[XK_KP_3] = Key::NP3; mapKeys[XK_KP_4] = Key::NP4; + mapKeys[XK_KP_5] = Key::NP5; mapKeys[XK_KP_6] = Key::NP6; mapKeys[XK_KP_7] = Key::NP7; mapKeys[XK_KP_8] = Key::NP8; mapKeys[XK_KP_9] = Key::NP9; + mapKeys[XK_KP_Multiply] = Key::NP_MUL; mapKeys[XK_KP_Add] = Key::NP_ADD; mapKeys[XK_KP_Divide] = Key::NP_DIV; mapKeys[XK_KP_Subtract] = Key::NP_SUB; mapKeys[XK_KP_Decimal] = Key::NP_DECIMAL; + + // These keys vary depending on the keyboard. I've included comments for US and UK keyboard layouts + mapKeys[XK_semicolon] = Key::OEM_1; // On US and UK keyboards this is the ';:' key + mapKeys[XK_slash] = Key::OEM_2; // On US and UK keyboards this is the '/?' key + mapKeys[XK_asciitilde] = Key::OEM_3; // On US keyboard this is the '~' key + mapKeys[XK_bracketleft] = Key::OEM_4; // On US and UK keyboards this is the '[{' key + mapKeys[XK_backslash] = Key::OEM_5; // On US keyboard this is '\|' key. + mapKeys[XK_bracketright] = Key::OEM_6; // On US and UK keyboards this is the ']}' key + mapKeys[XK_apostrophe] = Key::OEM_7; // On US keyboard this is the single/double quote key. On UK, this is the single quote/@ symbol key + mapKeys[XK_numbersign] = Key::OEM_8; // miscellaneous characters. Varies by keyboard. I believe this to be the '#~' key on UK keyboards + mapKeys[XK_equal] = Key::EQUALS; // the '+' key on any keyboard + mapKeys[XK_comma] = Key::COMMA; // the comma key on any keyboard + mapKeys[XK_minus] = Key::MINUS; // the minus key on any keyboard + + mapKeys[XK_Caps_Lock] = Key::CAPS_LOCK; + + return olc::OK; + } + + virtual olc::rcode SetWindowTitle(const std::string& s) override + { + X11::XStoreName(olc_Display, olc_Window, s.c_str()); + return olc::OK; + } + + virtual olc::rcode StartSystemEventLoop() override + { + return olc::OK; + } + + virtual olc::rcode HandleSystemEvent() override + { + using namespace X11; + // Handle Xlib Message Loop - we do this in the + // same thread that OpenGL was created so we dont + // need to worry too much about multithreading with X11 + XEvent xev; + while (XPending(olc_Display)) + { + XNextEvent(olc_Display, &xev); + if (xev.type == Expose) + { + XWindowAttributes gwa; + XGetWindowAttributes(olc_Display, olc_Window, &gwa); + ptrPGE->olc_UpdateWindowSize(gwa.width, gwa.height); + } + else if (xev.type == ConfigureNotify) + { + XConfigureEvent xce = xev.xconfigure; + ptrPGE->olc_UpdateWindowSize(xce.width, xce.height); + } + else if (xev.type == KeyPress) + { + KeySym sym = XLookupKeysym(&xev.xkey, 0); + ptrPGE->olc_UpdateKeyState(mapKeys[sym], true); + XKeyEvent* e = (XKeyEvent*)&xev; // Because DragonEye loves numpads + XLookupString(e, NULL, 0, &sym, NULL); + ptrPGE->olc_UpdateKeyState(mapKeys[sym], true); + } + else if (xev.type == KeyRelease) + { + KeySym sym = XLookupKeysym(&xev.xkey, 0); + ptrPGE->olc_UpdateKeyState(mapKeys[sym], false); + XKeyEvent* e = (XKeyEvent*)&xev; + XLookupString(e, NULL, 0, &sym, NULL); + ptrPGE->olc_UpdateKeyState(mapKeys[sym], false); + } + else if (xev.type == ButtonPress) + { + switch (xev.xbutton.button) + { + case 1: ptrPGE->olc_UpdateMouseState(0, true); break; + case 2: ptrPGE->olc_UpdateMouseState(2, true); break; + case 3: ptrPGE->olc_UpdateMouseState(1, true); break; + case 4: ptrPGE->olc_UpdateMouseWheel(120); break; + case 5: ptrPGE->olc_UpdateMouseWheel(-120); break; + default: break; + } + } + else if (xev.type == ButtonRelease) + { + switch (xev.xbutton.button) + { + case 1: ptrPGE->olc_UpdateMouseState(0, false); break; + case 2: ptrPGE->olc_UpdateMouseState(2, false); break; + case 3: ptrPGE->olc_UpdateMouseState(1, false); break; + default: break; + } + } + else if (xev.type == MotionNotify) + { + ptrPGE->olc_UpdateMouse(xev.xmotion.x, xev.xmotion.y); + } + else if (xev.type == FocusIn) + { + ptrPGE->olc_UpdateKeyFocus(true); + } + else if (xev.type == FocusOut) + { + ptrPGE->olc_UpdateKeyFocus(false); + } + else if (xev.type == ClientMessage) + { + ptrPGE->olc_Terminate(); + } + } + return olc::OK; + } + }; +} +#endif +// O------------------------------------------------------------------------------O +// | END PLATFORM: LINUX | +// O------------------------------------------------------------------------------O +#pragma endregion + +#pragma region platform_glut +// O------------------------------------------------------------------------------O +// | START PLATFORM: GLUT (used to make it simple for Apple) | +// O------------------------------------------------------------------------------O +// +// VERY IMPORTANT!!! The Apple port was originally created by @Mumflr (discord) +// and the repo for the development of this project can be found here: +// https://github.com/MumflrFumperdink/olcPGEMac which contains maccy goodness +// and support on how to setup your build environment. +// +// "MASSIVE MASSIVE THANKS TO MUMFLR" - Javidx9 +#if defined(OLC_PLATFORM_GLUT) +namespace olc { + + class Platform_GLUT : public olc::Platform + { + public: + static std::atomic* bActiveRef; + + virtual olc::rcode ApplicationStartUp() override { + return olc::rcode::OK; + } + + virtual olc::rcode ApplicationCleanUp() override + { + return olc::rcode::OK; + } + + virtual olc::rcode ThreadStartUp() override + { + return olc::rcode::OK; + } + + virtual olc::rcode ThreadCleanUp() override + { + renderer->DestroyDevice(); + return olc::OK; + } + + virtual olc::rcode CreateGraphics(bool bFullScreen, bool bEnableVSYNC, const olc::vi2d& vViewPos, const olc::vi2d& vViewSize) override + { + if (renderer->CreateDevice({}, bFullScreen, bEnableVSYNC) == olc::rcode::OK) + { + renderer->UpdateViewport(vViewPos, vViewSize); + return olc::rcode::OK; + } + else + return olc::rcode::FAIL; + } + + static void ExitMainLoop() { + if (!ptrPGE->OnUserDestroy()) { + *bActiveRef = true; + return; + } + platform->ThreadCleanUp(); + platform->ApplicationCleanUp(); + exit(0); + } + +#if defined(__APPLE__) + static void scrollWheelUpdate(id selff, SEL _sel, id theEvent) { + static const SEL deltaYSel = sel_registerName("deltaY"); + +#if defined(__aarch64__) // Thanks ruarq! + double deltaY = ((double (*)(id, SEL))objc_msgSend)(theEvent, deltaYSel); +#else + double deltaY = ((double (*)(id, SEL))objc_msgSend_fpret)(theEvent, deltaYSel); +#endif + + for (int i = 0; i < abs(deltaY); i++) { + if (deltaY > 0) { + ptrPGE->olc_UpdateMouseWheel(-1); + } + else if (deltaY < 0) { + ptrPGE->olc_UpdateMouseWheel(1); + } + } + } +#endif + static void ThreadFunct() { +#if defined(__APPLE__) + static bool hasEnabledCocoa = false; + if (!hasEnabledCocoa) { + // Objective-C Wizardry + Class NSApplicationClass = objc_getClass("NSApplication"); + + // NSApp = [NSApplication sharedApplication] + SEL sharedApplicationSel = sel_registerName("sharedApplication"); + id NSApp = ((id(*)(Class, SEL))objc_msgSend)(NSApplicationClass, sharedApplicationSel); + // window = [NSApp mainWindow] + SEL mainWindowSel = sel_registerName("mainWindow"); + id window = ((id(*)(id, SEL))objc_msgSend)(NSApp, mainWindowSel); + + // [window setStyleMask: NSWindowStyleMaskClosable | ~NSWindowStyleMaskResizable] + SEL setStyleMaskSel = sel_registerName("setStyleMask:"); + ((void (*)(id, SEL, NSUInteger))objc_msgSend)(window, setStyleMaskSel, 7); + + hasEnabledCocoa = true; + } +#endif + if (!*bActiveRef) { + ExitMainLoop(); + return; + } + glutPostRedisplay(); + } + + static void DrawFunct() { + ptrPGE->olc_CoreUpdate(); + } + + virtual olc::rcode CreateWindowPane(const olc::vi2d& vWindowPos, olc::vi2d& vWindowSize, bool bFullScreen) override + { +#if defined(__APPLE__) + Class GLUTViewClass = objc_getClass("GLUTView"); + + SEL scrollWheelSel = sel_registerName("scrollWheel:"); + bool resultAddMethod = class_addMethod(GLUTViewClass, scrollWheelSel, (IMP)scrollWheelUpdate, "v@:@"); + assert(resultAddMethod); +#endif + + renderer->PrepareDevice(); + + if (bFullScreen) + { + vWindowSize.x = glutGet(GLUT_SCREEN_WIDTH); + vWindowSize.y = glutGet(GLUT_SCREEN_HEIGHT); + glutFullScreen(); + } + else + { + if (vWindowSize.x > glutGet(GLUT_SCREEN_WIDTH) || vWindowSize.y > glutGet(GLUT_SCREEN_HEIGHT)) + { + perror("ERROR: The specified window dimensions do not fit on your screen\n"); + return olc::FAIL; + } + glutReshapeWindow(vWindowSize.x, vWindowSize.y - 1); + } + + // Create Keyboard Mapping + mapKeys[0x00] = Key::NONE; + mapKeys['A'] = Key::A; mapKeys['B'] = Key::B; mapKeys['C'] = Key::C; mapKeys['D'] = Key::D; mapKeys['E'] = Key::E; + mapKeys['F'] = Key::F; mapKeys['G'] = Key::G; mapKeys['H'] = Key::H; mapKeys['I'] = Key::I; mapKeys['J'] = Key::J; + mapKeys['K'] = Key::K; mapKeys['L'] = Key::L; mapKeys['M'] = Key::M; mapKeys['N'] = Key::N; mapKeys['O'] = Key::O; + mapKeys['P'] = Key::P; mapKeys['Q'] = Key::Q; mapKeys['R'] = Key::R; mapKeys['S'] = Key::S; mapKeys['T'] = Key::T; + mapKeys['U'] = Key::U; mapKeys['V'] = Key::V; mapKeys['W'] = Key::W; mapKeys['X'] = Key::X; mapKeys['Y'] = Key::Y; + mapKeys['Z'] = Key::Z; + + mapKeys[GLUT_KEY_F1] = Key::F1; mapKeys[GLUT_KEY_F2] = Key::F2; mapKeys[GLUT_KEY_F3] = Key::F3; mapKeys[GLUT_KEY_F4] = Key::F4; + mapKeys[GLUT_KEY_F5] = Key::F5; mapKeys[GLUT_KEY_F6] = Key::F6; mapKeys[GLUT_KEY_F7] = Key::F7; mapKeys[GLUT_KEY_F8] = Key::F8; + mapKeys[GLUT_KEY_F9] = Key::F9; mapKeys[GLUT_KEY_F10] = Key::F10; mapKeys[GLUT_KEY_F11] = Key::F11; mapKeys[GLUT_KEY_F12] = Key::F12; + + mapKeys[GLUT_KEY_DOWN] = Key::DOWN; mapKeys[GLUT_KEY_LEFT] = Key::LEFT; mapKeys[GLUT_KEY_RIGHT] = Key::RIGHT; mapKeys[GLUT_KEY_UP] = Key::UP; + mapKeys[13] = Key::ENTER; + + mapKeys[127] = Key::BACK; mapKeys[27] = Key::ESCAPE; + mapKeys[9] = Key::TAB; mapKeys[GLUT_KEY_HOME] = Key::HOME; + mapKeys[GLUT_KEY_END] = Key::END; mapKeys[GLUT_KEY_PAGE_UP] = Key::PGUP; mapKeys[GLUT_KEY_PAGE_DOWN] = Key::PGDN; mapKeys[GLUT_KEY_INSERT] = Key::INS; + mapKeys[32] = Key::SPACE; mapKeys[46] = Key::PERIOD; + + mapKeys[48] = Key::K0; mapKeys[49] = Key::K1; mapKeys[50] = Key::K2; mapKeys[51] = Key::K3; mapKeys[52] = Key::K4; + mapKeys[53] = Key::K5; mapKeys[54] = Key::K6; mapKeys[55] = Key::K7; mapKeys[56] = Key::K8; mapKeys[57] = Key::K9; + + // NOTE: MISSING KEYS :O + + glutKeyboardFunc([](unsigned char key, int x, int y) -> void { + switch (glutGetModifiers()) { + case 0: //This is when there are no modifiers + if ('a' <= key && key <= 'z') key -= 32; + break; + case GLUT_ACTIVE_SHIFT: + ptrPGE->olc_UpdateKeyState(Key::SHIFT, true); + break; + case GLUT_ACTIVE_CTRL: + if ('a' <= key && key <= 'z') key -= 32; + ptrPGE->olc_UpdateKeyState(Key::CTRL, true); + break; + case GLUT_ACTIVE_ALT: + if ('a' <= key && key <= 'z') key -= 32; + break; + } + + if (mapKeys[key]) + ptrPGE->olc_UpdateKeyState(mapKeys[key], true); + }); + + glutKeyboardUpFunc([](unsigned char key, int x, int y) -> void { + switch (glutGetModifiers()) { + case 0: //This is when there are no modifiers + if ('a' <= key && key <= 'z') key -= 32; + break; + case GLUT_ACTIVE_SHIFT: + ptrPGE->olc_UpdateKeyState(Key::SHIFT, false); + break; + case GLUT_ACTIVE_CTRL: + if ('a' <= key && key <= 'z') key -= 32; + ptrPGE->olc_UpdateKeyState(Key::CTRL, false); + break; + case GLUT_ACTIVE_ALT: + if ('a' <= key && key <= 'z') key -= 32; + //No ALT in PGE + break; + } + + if (mapKeys[key]) + ptrPGE->olc_UpdateKeyState(mapKeys[key], false); + }); + + //Special keys + glutSpecialFunc([](int key, int x, int y) -> void { + if (mapKeys[key]) + ptrPGE->olc_UpdateKeyState(mapKeys[key], true); + }); + + glutSpecialUpFunc([](int key, int x, int y) -> void { + if (mapKeys[key]) + ptrPGE->olc_UpdateKeyState(mapKeys[key], false); + }); + + glutMouseFunc([](int button, int state, int x, int y) -> void { + switch (button) { + case GLUT_LEFT_BUTTON: + if (state == GLUT_UP) ptrPGE->olc_UpdateMouseState(0, false); + else if (state == GLUT_DOWN) ptrPGE->olc_UpdateMouseState(0, true); + break; + case GLUT_MIDDLE_BUTTON: + if (state == GLUT_UP) ptrPGE->olc_UpdateMouseState(2, false); + else if (state == GLUT_DOWN) ptrPGE->olc_UpdateMouseState(2, true); + break; + case GLUT_RIGHT_BUTTON: + if (state == GLUT_UP) ptrPGE->olc_UpdateMouseState(1, false); + else if (state == GLUT_DOWN) ptrPGE->olc_UpdateMouseState(1, true); + break; + } + }); + + auto mouseMoveCall = [](int x, int y) -> void { + ptrPGE->olc_UpdateMouse(x, y); + }; + + glutMotionFunc(mouseMoveCall); + glutPassiveMotionFunc(mouseMoveCall); + + glutEntryFunc([](int state) -> void { + if (state == GLUT_ENTERED) ptrPGE->olc_UpdateKeyFocus(true); + else if (state == GLUT_LEFT) ptrPGE->olc_UpdateKeyFocus(false); + }); + + glutDisplayFunc(DrawFunct); + glutIdleFunc(ThreadFunct); + + return olc::OK; + } + + virtual olc::rcode SetWindowTitle(const std::string& s) override + { + glutSetWindowTitle(s.c_str()); + return olc::OK; + } + + virtual olc::rcode StartSystemEventLoop() override { + glutMainLoop(); + return olc::OK; + } + + virtual olc::rcode HandleSystemEvent() override + { + return olc::OK; + } + }; + + std::atomic* Platform_GLUT::bActiveRef{ nullptr }; + + //Custom Start + olc::rcode PixelGameEngine::Start() + { + if (platform->ApplicationStartUp() != olc::OK) return olc::FAIL; + + // Construct the window + if (platform->CreateWindowPane({ 30,30 }, vWindowSize, bFullScreen) != olc::OK) return olc::FAIL; + olc_UpdateWindowSize(vWindowSize.x, vWindowSize.y); + + if (platform->ThreadStartUp() == olc::FAIL) return olc::FAIL; + olc_PrepareEngine(); + if (!OnUserCreate()) return olc::FAIL; + Platform_GLUT::bActiveRef = &bAtomActive; + glutWMCloseFunc(Platform_GLUT::ExitMainLoop); + bAtomActive = true; + platform->StartSystemEventLoop(); + + //This code will not even be run but why not + if (platform->ApplicationCleanUp() != olc::OK) return olc::FAIL; + + return olc::OK; + } +} + +#endif +// O------------------------------------------------------------------------------O +// | END PLATFORM: GLUT | +// O------------------------------------------------------------------------------O +#pragma endregion + + + + + +#pragma region platform_emscripten +// O------------------------------------------------------------------------------O +// | START PLATFORM: Emscripten - Totally Game Changing... | +// O------------------------------------------------------------------------------O + +// +// Firstly a big mega thank you to members of the OLC Community for sorting this +// out. Making a browser compatible version has been a priority for quite some +// time, but I lacked the expertise to do it. This awesome feature is possible +// because a group of former strangers got together and formed friendships over +// their shared passion for code. If anything demonstrates how powerful helping +// each other can be, it's this. - Javidx9 + +// Emscripten Platform: MaGetzUb, Moros1138, Slavka, Dandistine, Gorbit99, Bispoo +// also: Ishidex, Gusgo99, SlicEnDicE, Alexio + + +#if defined(OLC_PLATFORM_EMSCRIPTEN) + +#include +#include + +extern "C" +{ + EMSCRIPTEN_KEEPALIVE inline int olc_OnPageUnload() + { olc::platform->ApplicationCleanUp(); return 0; } +} + +namespace olc +{ + class Platform_Emscripten : public olc::Platform + { + public: + + virtual olc::rcode ApplicationStartUp() override + { return olc::rcode::OK; } + + virtual olc::rcode ApplicationCleanUp() override + { ThreadCleanUp(); return olc::rcode::OK; } + + virtual olc::rcode ThreadStartUp() override + { return olc::rcode::OK; } + + virtual olc::rcode ThreadCleanUp() override + { renderer->DestroyDevice(); return olc::OK; } + + virtual olc::rcode CreateGraphics(bool bFullScreen, bool bEnableVSYNC, const olc::vi2d& vViewPos, const olc::vi2d& vViewSize) override + { + if (renderer->CreateDevice({}, bFullScreen, bEnableVSYNC) == olc::rcode::OK) + { + renderer->UpdateViewport(vViewPos, vViewSize); + return olc::rcode::OK; + } + else + return olc::rcode::FAIL; + } + + virtual olc::rcode CreateWindowPane(const olc::vi2d& vWindowPos, olc::vi2d& vWindowSize, bool bFullScreen) override + { + emscripten_set_canvas_element_size("#canvas", vWindowSize.x, vWindowSize.y); + + mapKeys[DOM_PK_UNKNOWN] = Key::NONE; + mapKeys[DOM_PK_A] = Key::A; mapKeys[DOM_PK_B] = Key::B; mapKeys[DOM_PK_C] = Key::C; mapKeys[DOM_PK_D] = Key::D; + mapKeys[DOM_PK_E] = Key::E; mapKeys[DOM_PK_F] = Key::F; mapKeys[DOM_PK_G] = Key::G; mapKeys[DOM_PK_H] = Key::H; + mapKeys[DOM_PK_I] = Key::I; mapKeys[DOM_PK_J] = Key::J; mapKeys[DOM_PK_K] = Key::K; mapKeys[DOM_PK_L] = Key::L; + mapKeys[DOM_PK_M] = Key::M; mapKeys[DOM_PK_N] = Key::N; mapKeys[DOM_PK_O] = Key::O; mapKeys[DOM_PK_P] = Key::P; + mapKeys[DOM_PK_Q] = Key::Q; mapKeys[DOM_PK_R] = Key::R; mapKeys[DOM_PK_S] = Key::S; mapKeys[DOM_PK_T] = Key::T; + mapKeys[DOM_PK_U] = Key::U; mapKeys[DOM_PK_V] = Key::V; mapKeys[DOM_PK_W] = Key::W; mapKeys[DOM_PK_X] = Key::X; + mapKeys[DOM_PK_Y] = Key::Y; mapKeys[DOM_PK_Z] = Key::Z; + mapKeys[DOM_PK_0] = Key::K0; mapKeys[DOM_PK_1] = Key::K1; mapKeys[DOM_PK_2] = Key::K2; + mapKeys[DOM_PK_3] = Key::K3; mapKeys[DOM_PK_4] = Key::K4; mapKeys[DOM_PK_5] = Key::K5; + mapKeys[DOM_PK_6] = Key::K6; mapKeys[DOM_PK_7] = Key::K7; mapKeys[DOM_PK_8] = Key::K8; + mapKeys[DOM_PK_9] = Key::K9; + mapKeys[DOM_PK_F1] = Key::F1; mapKeys[DOM_PK_F2] = Key::F2; mapKeys[DOM_PK_F3] = Key::F3; mapKeys[DOM_PK_F4] = Key::F4; + mapKeys[DOM_PK_F5] = Key::F5; mapKeys[DOM_PK_F6] = Key::F6; mapKeys[DOM_PK_F7] = Key::F7; mapKeys[DOM_PK_F8] = Key::F8; + mapKeys[DOM_PK_F9] = Key::F9; mapKeys[DOM_PK_F10] = Key::F10; mapKeys[DOM_PK_F11] = Key::F11; mapKeys[DOM_PK_F12] = Key::F12; + mapKeys[DOM_PK_ARROW_UP] = Key::UP; mapKeys[DOM_PK_ARROW_DOWN] = Key::DOWN; + mapKeys[DOM_PK_ARROW_LEFT] = Key::LEFT; mapKeys[DOM_PK_ARROW_RIGHT] = Key::RIGHT; + mapKeys[DOM_PK_SPACE] = Key::SPACE; mapKeys[DOM_PK_TAB] = Key::TAB; + mapKeys[DOM_PK_SHIFT_LEFT] = Key::SHIFT; mapKeys[DOM_PK_SHIFT_RIGHT] = Key::SHIFT; + mapKeys[DOM_PK_CONTROL_LEFT] = Key::CTRL; mapKeys[DOM_PK_CONTROL_RIGHT] = Key::CTRL; + mapKeys[DOM_PK_INSERT] = Key::INS; mapKeys[DOM_PK_DELETE] = Key::DEL; mapKeys[DOM_PK_HOME] = Key::HOME; + mapKeys[DOM_PK_END] = Key::END; mapKeys[DOM_PK_PAGE_UP] = Key::PGUP; mapKeys[DOM_PK_PAGE_DOWN] = Key::PGDN; + mapKeys[DOM_PK_BACKSPACE] = Key::BACK; mapKeys[DOM_PK_ESCAPE] = Key::ESCAPE; + mapKeys[DOM_PK_ENTER] = Key::ENTER; mapKeys[DOM_PK_NUMPAD_EQUAL] = Key::EQUALS; + mapKeys[DOM_PK_NUMPAD_ENTER] = Key::ENTER; mapKeys[DOM_PK_PAUSE] = Key::PAUSE; + mapKeys[DOM_PK_SCROLL_LOCK] = Key::SCROLL; + mapKeys[DOM_PK_NUMPAD_0] = Key::NP0; mapKeys[DOM_PK_NUMPAD_1] = Key::NP1; mapKeys[DOM_PK_NUMPAD_2] = Key::NP2; + mapKeys[DOM_PK_NUMPAD_3] = Key::NP3; mapKeys[DOM_PK_NUMPAD_4] = Key::NP4; mapKeys[DOM_PK_NUMPAD_5] = Key::NP5; + mapKeys[DOM_PK_NUMPAD_6] = Key::NP6; mapKeys[DOM_PK_NUMPAD_7] = Key::NP7; mapKeys[DOM_PK_NUMPAD_8] = Key::NP8; + mapKeys[DOM_PK_NUMPAD_9] = Key::NP9; + mapKeys[DOM_PK_NUMPAD_MULTIPLY] = Key::NP_MUL; mapKeys[DOM_PK_NUMPAD_DIVIDE] = Key::NP_DIV; + mapKeys[DOM_PK_NUMPAD_ADD] = Key::NP_ADD; mapKeys[DOM_PK_NUMPAD_SUBTRACT] = Key::NP_SUB; + mapKeys[DOM_PK_NUMPAD_DECIMAL] = Key::NP_DECIMAL; + mapKeys[DOM_PK_PERIOD] = Key::PERIOD; mapKeys[DOM_PK_EQUAL] = Key::EQUALS; + mapKeys[DOM_PK_COMMA] = Key::COMMA; mapKeys[DOM_PK_MINUS] = Key::MINUS; + mapKeys[DOM_PK_CAPS_LOCK] = Key::CAPS_LOCK; + mapKeys[DOM_PK_SEMICOLON] = Key::OEM_1; mapKeys[DOM_PK_SLASH] = Key::OEM_2; mapKeys[DOM_PK_BACKQUOTE] = Key::OEM_3; + mapKeys[DOM_PK_BRACKET_LEFT] = Key::OEM_4; mapKeys[DOM_PK_BACKSLASH] = Key::OEM_5; mapKeys[DOM_PK_BRACKET_RIGHT] = Key::OEM_6; + mapKeys[DOM_PK_QUOTE] = Key::OEM_7; mapKeys[DOM_PK_BACKSLASH] = Key::OEM_8; + + // Keyboard Callbacks + emscripten_set_keydown_callback("#canvas", 0, 1, keyboard_callback); + emscripten_set_keyup_callback("#canvas", 0, 1, keyboard_callback); + + // Mouse Callbacks + emscripten_set_wheel_callback("#canvas", 0, 1, wheel_callback); + emscripten_set_mousedown_callback("#canvas", 0, 1, mouse_callback); + emscripten_set_mouseup_callback("#canvas", 0, 1, mouse_callback); + emscripten_set_mousemove_callback("#canvas", 0, 1, mouse_callback); + + // Touch Callbacks + emscripten_set_touchstart_callback("#canvas", 0, 1, touch_callback); + emscripten_set_touchmove_callback("#canvas", 0, 1, touch_callback); + emscripten_set_touchend_callback("#canvas", 0, 1, touch_callback); + + // Canvas Focus Callbacks + emscripten_set_blur_callback("#canvas", 0, 1, focus_callback); + emscripten_set_focus_callback("#canvas", 0, 1, focus_callback); + +#pragma warning disable format + EM_ASM( window.onunload = Module._olc_OnPageUnload; ); + + // IMPORTANT! - Sorry About This... + // + // In order to handle certain browser based events, such as resizing and + // going to full screen, we have to effectively inject code into the container + // running the PGE. Yes, I vomited about 11 times too when the others were + // convincing me this is the future. Well, this isnt the future, and if it + // were to be, I want no part of what must be a miserable distopian free + // for all of anarchic code injection to get rudimentary events like "Resize()". + // + // Wake up people! Of course theres a spoon. There has to be to keep feeding + // the giant web baby. + + + EM_ASM({ + + // olc_ApsectRatio + // + // Used by olc_ResizeHandler to calculate the viewport from the + // dimensions of the canvas container's element. + Module.olc_AspectRatio = $0 / $1; + + // HACK ALERT! + // + // Here we assume any html shell that uses 3 or more instance of the class "emscripten" + // is using one of the default or minimal emscripten page layouts + Module.olc_AssumeDefaultShells = (document.querySelectorAll('.emscripten').length >= 3) ? true : false; + + // olc_ResizeHandler + // + // Used by olc_Init, and is called when a resize observer and fullscreenchange event is triggered. + var olc_ResizeHandler = function() + { + // are we in fullscreen mode? + let isFullscreen = (document.fullscreenElement != null); + + // get the width of the containing element + let width = (isFullscreen) ? window.innerWidth : Module.canvas.parentNode.clientWidth; + let height = (isFullscreen) ? window.innerHeight : Module.canvas.parentNode.clientHeight; + + // calculate the expected viewport size + let viewWidth = width; + let viewHeight = width / Module.olc_AspectRatio; + + // if we're taller than the containing element, recalculate based on height + if(viewHeight > height) + { + viewWidth = height * Module.olc_AspectRatio; + viewHeight = height; + } + + // ensure resulting viewport is in integer space + viewWidth = parseInt(viewWidth); + viewHeight = parseInt(viewHeight); + + setTimeout(function() + { + // if default shells, apply default styles + if(Module.olc_AssumeDefaultShells) + Module.canvas.parentNode.setAttribute('style', 'width: 100%; height: 70vh; margin-left: auto; margin-right: auto;'); + + // apply viewport dimensions to teh canvas + Module.canvas.setAttribute('width', viewWidth); + Module.canvas.setAttribute('height', viewHeight); + Module.canvas.setAttribute('style', `width: ${viewWidth}px; height: ${viewHeight}px;`); + + // update the PGE window size + Module._olc_PGE_UpdateWindowSize(viewWidth, viewHeight); + + // force focus on our PGE canvas + Module.canvas.focus(); + }, 200); + }; + + + // olc_Init + // + // set up resize observer and fullscreenchange event handler + var olc_Init = function() + { + if(Module.olc_AspectRatio === undefined) + { + setTimeout(function() { Module.olc_Init(); }, 50); + return; + } + + let resizeObserver = new ResizeObserver(function(entries) + { + Module.olc_ResizeHandler(); + }).observe(Module.canvas.parentNode); + + let mutationObserver = new MutationObserver(function(mutationsList, observer) + { + setTimeout(function() { Module.olc_ResizeHandler(); }, 200); + }).observe(Module.canvas.parentNode, { attributes: false, childList: true, subtree: false }); + + window.addEventListener('fullscreenchange', function(e) + { + setTimeout(function() { Module.olc_ResizeHandler();}, 200); + }); + }; + + // set up hooks + Module.olc_ResizeHandler = (Module.olc_ResizeHandler != undefined) ? Module.olc_ResizeHandler : olc_ResizeHandler; + Module.olc_Init = (Module.olc_Init != undefined) ? Module.olc_Init : olc_Init; + + // run everything! + Module.olc_Init(); + + }, vWindowSize.x, vWindowSize.y); // Fullscreen and Resize Observers +#pragma warning restore format + return olc::rcode::OK; + } + + // Interface PGE's UpdateWindowSize, for use in Javascript + void UpdateWindowSize(int width, int height) + { + ptrPGE->olc_UpdateWindowSize(width, height); + } + + //TY Gorbit + static EM_BOOL focus_callback(int eventType, const EmscriptenFocusEvent* focusEvent, void* userData) + { + if (eventType == EMSCRIPTEN_EVENT_BLUR) + { + ptrPGE->olc_UpdateKeyFocus(false); + ptrPGE->olc_UpdateMouseFocus(false); + } + else if (eventType == EMSCRIPTEN_EVENT_FOCUS) + { + ptrPGE->olc_UpdateKeyFocus(true); + ptrPGE->olc_UpdateMouseFocus(true); + } + + return 0; + } + + //TY Moros + static EM_BOOL keyboard_callback(int eventType, const EmscriptenKeyboardEvent* e, void* userData) + { + if (eventType == EMSCRIPTEN_EVENT_KEYDOWN) + ptrPGE->olc_UpdateKeyState(mapKeys[emscripten_compute_dom_pk_code(e->code)], true); + + // THANK GOD!! for this compute function. And thanks Dandistine for pointing it out! + if (eventType == EMSCRIPTEN_EVENT_KEYUP) + ptrPGE->olc_UpdateKeyState(mapKeys[emscripten_compute_dom_pk_code(e->code)], false); + + //Consume keyboard events so that keys like F1 and F5 don't do weird things + return EM_TRUE; + } + + //TY Moros + static EM_BOOL wheel_callback(int eventType, const EmscriptenWheelEvent* e, void* userData) + { + if (eventType == EMSCRIPTEN_EVENT_WHEEL) + ptrPGE->olc_UpdateMouseWheel(-1 * e->deltaY); + + return EM_TRUE; + } + + //TY Bispoo + static EM_BOOL touch_callback(int eventType, const EmscriptenTouchEvent* e, void* userData) + { + // Move + if (eventType == EMSCRIPTEN_EVENT_TOUCHMOVE) + { + ptrPGE->olc_UpdateMouse(e->touches->targetX, e->touches->targetY); + } + + // Start + if (eventType == EMSCRIPTEN_EVENT_TOUCHSTART) + { + ptrPGE->olc_UpdateMouse(e->touches->targetX, e->touches->targetY); + ptrPGE->olc_UpdateMouseState(0, true); + } + + // End + if (eventType == EMSCRIPTEN_EVENT_TOUCHEND) + { + ptrPGE->olc_UpdateMouseState(0, false); + } + + return EM_TRUE; + } + + //TY Moros + static EM_BOOL mouse_callback(int eventType, const EmscriptenMouseEvent* e, void* userData) + { + //Mouse Movement + if (eventType == EMSCRIPTEN_EVENT_MOUSEMOVE) + ptrPGE->olc_UpdateMouse(e->targetX, e->targetY); + + + //Mouse button press + if (e->button == 0) // left click + { + if (eventType == EMSCRIPTEN_EVENT_MOUSEDOWN) + ptrPGE->olc_UpdateMouseState(0, true); + else if (eventType == EMSCRIPTEN_EVENT_MOUSEUP) + ptrPGE->olc_UpdateMouseState(0, false); + } + + if (e->button == 2) // right click + { + if (eventType == EMSCRIPTEN_EVENT_MOUSEDOWN) + ptrPGE->olc_UpdateMouseState(1, true); + else if (eventType == EMSCRIPTEN_EVENT_MOUSEUP) + ptrPGE->olc_UpdateMouseState(1, false); + + } + + if (e->button == 1) // middle click + { + if (eventType == EMSCRIPTEN_EVENT_MOUSEDOWN) + ptrPGE->olc_UpdateMouseState(2, true); + else if (eventType == EMSCRIPTEN_EVENT_MOUSEUP) + ptrPGE->olc_UpdateMouseState(2, false); + + //at the moment only middle mouse needs to consume events. + return EM_TRUE; + } + + return EM_FALSE; + } + + + virtual olc::rcode SetWindowTitle(const std::string& s) override + { emscripten_set_window_title(s.c_str()); return olc::OK; } + + virtual olc::rcode StartSystemEventLoop() override + { return olc::OK; } + + virtual olc::rcode HandleSystemEvent() override + { return olc::OK; } + + static void MainLoop() + { + olc::Platform::ptrPGE->olc_CoreUpdate(); + if (!ptrPGE->olc_IsRunning()) + { + if (ptrPGE->OnUserDestroy()) + { + emscripten_cancel_main_loop(); + platform->ApplicationCleanUp(); + } + else + { + ptrPGE->olc_Reanimate(); + } + } + } + }; + + //Emscripten needs a special Start function + //Much of this is usually done in EngineThread, but that isn't used here + olc::rcode PixelGameEngine::Start() + { + if (platform->ApplicationStartUp() != olc::OK) return olc::FAIL; + + // Construct the window + if (platform->CreateWindowPane({ 30,30 }, vWindowSize, bFullScreen) != olc::OK) return olc::FAIL; + olc_UpdateWindowSize(vWindowSize.x, vWindowSize.y); + + // Some implementations may form an event loop here + if (platform->ThreadStartUp() == olc::FAIL) return olc::FAIL; + + // Do engine context specific initialisation + olc_PrepareEngine(); + + // Consider the "thread" started + bAtomActive = true; + + // Create user resources as part of this thread + for (auto& ext : vExtensions) ext->OnBeforeUserCreate(); + if (!OnUserCreate()) bAtomActive = false; + for (auto& ext : vExtensions) ext->OnAfterUserCreate(); + + platform->StartSystemEventLoop(); + + //This causes a heap memory corruption in Emscripten for some reason + //Platform_Emscripten::bActiveRef = &bAtomActive; + emscripten_set_main_loop(&Platform_Emscripten::MainLoop, 0, 1); + + // Wait for thread to be exited + if (platform->ApplicationCleanUp() != olc::OK) return olc::FAIL; + return olc::OK; + } +} + +extern "C" +{ + EMSCRIPTEN_KEEPALIVE inline void olc_PGE_UpdateWindowSize(int width, int height) + { + emscripten_set_canvas_element_size("#canvas", width, height); + // Thanks slavka + ((olc::Platform_Emscripten*)olc::platform.get())->UpdateWindowSize(width, height); + } +} + +#endif +// O------------------------------------------------------------------------------O +// | END PLATFORM: Emscripten | +// O------------------------------------------------------------------------------O +#pragma endregion + + +#endif // Headless + +// O------------------------------------------------------------------------------O +// | olcPixelGameEngine Auto-Configuration | +// O------------------------------------------------------------------------------O +#pragma region pge_config +namespace olc +{ + void PixelGameEngine::olc_ConfigureSystem() + { + +//#if !defined(OLC_PGE_HEADLESS) + + olc::Sprite::loader = nullptr; + +#if defined(OLC_IMAGE_GDI) + olc::Sprite::loader = std::make_unique(); +#endif + +#if defined(OLC_IMAGE_LIBPNG) + olc::Sprite::loader = std::make_unique(); +#endif + +#if defined(OLC_IMAGE_STB) + olc::Sprite::loader = std::make_unique(); +#endif + +#if defined(OLC_IMAGE_CUSTOM_EX) + olc::Sprite::loader = std::make_unique(); +#endif + + +#if defined(OLC_PLATFORM_HEADLESS) + platform = std::make_unique(); +#endif + +#if defined(OLC_PLATFORM_WINAPI) + platform = std::make_unique(); +#endif + +#if defined(OLC_PLATFORM_X11) + platform = std::make_unique(); +#endif + +#if defined(OLC_PLATFORM_GLUT) + platform = std::make_unique(); +#endif + +#if defined(OLC_PLATFORM_EMSCRIPTEN) + platform = std::make_unique(); +#endif + +#if defined(OLC_PLATFORM_CUSTOM_EX) + platform = std::make_unique(); +#endif + +#if defined(OLC_GFX_HEADLESS) + renderer = std::make_unique(); +#endif + +#if defined(OLC_GFX_OPENGL10) + renderer = std::make_unique(); +#endif + +#if defined(OLC_GFX_OPENGL33) + renderer = std::make_unique(); +#endif + +#if defined(OLC_GFX_OPENGLES2) + renderer = std::make_unique(); +#endif + +#if defined(OLC_GFX_DIRECTX10) + renderer = std::make_unique(); +#endif + +#if defined(OLC_GFX_DIRECTX11) + renderer = std::make_unique(); +#endif + +#if defined(OLC_GFX_CUSTOM_EX) + renderer = std::make_unique(); +#endif + + // Associate components with PGE instance + platform->ptrPGE = this; + renderer->ptrPGE = this; +//#else +// olc::Sprite::loader = nullptr; +// platform = nullptr; +// renderer = nullptr; +//#endif + } +} + +#pragma endregion + +#endif // End OLC_PGE_APPLICATION + +// O------------------------------------------------------------------------------O +// | END OF OLC_PGE_APPLICATION | +// O------------------------------------------------------------------------------O diff --git a/pixelGameEngine_wasm.o b/pixelGameEngine_wasm.o new file mode 100644 index 0000000000000000000000000000000000000000..a2e3c09e937c99a95fda6cb279aa03b84a6c2733 GIT binary patch literal 185477 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 literal 0 HcmV?d00001 diff --git a/sig b/sig new file mode 100755 index 0000000..432ee5d --- /dev/null +++ b/sig @@ -0,0 +1,10 @@ +export AUTO_UPDATE=false + +source utils/define.sh + +define PROJECT_NAME "C++ProjectTemplate" +define CUSTOM_PARAMS "-std=c++17 -lX11 -lGL -lpng -lstdc++fs" +define EMSCRIPTEN_CUSTOM_PARAMS "" +define LANGUAGE "C++" + +source utils/main.sh diff --git a/utils/.coauthors b/utils/.coauthors new file mode 100644 index 0000000..b904d0f --- /dev/null +++ b/utils/.coauthors @@ -0,0 +1 @@ +sigonasr2 diff --git a/utils/.updateDirectories b/utils/.updateDirectories new file mode 100644 index 0000000..56274ea --- /dev/null +++ b/utils/.updateDirectories @@ -0,0 +1,5 @@ +Java/ +C/ +C++/ +scripts/ +utils/ \ No newline at end of file diff --git a/utils/define.sh b/utils/define.sh new file mode 100755 index 0000000..214fc50 --- /dev/null +++ b/utils/define.sh @@ -0,0 +1,26 @@ +export VARS=("") + +export LANGUAGE="" + +function define() { + VARS+=("$1") + value="${*:2}" + eval export "$1"='$value' +} + +if [[ $(pwd) != *"SigScript" && $AUTO_UPDATE = "true" && $1 != "update" ]]; then + source utils/search.sh + + find . -type f -name md5 -delete + find . -type f -name filelist -delete + + #Check for hashes + FILES=$(cat utils/.updateDirectories) + for f in $FILES + do + search $f + check $f + done +else + echo "Dev build, no checks required." +fi \ No newline at end of file diff --git a/utils/filelist b/utils/filelist new file mode 100644 index 0000000..8a9f471 --- /dev/null +++ b/utils/filelist @@ -0,0 +1,5 @@ +.coauthors +.updateDirectories +define.sh +main.sh +search.sh diff --git a/utils/main.sh b/utils/main.sh new file mode 100644 index 0000000..0a4c92a --- /dev/null +++ b/utils/main.sh @@ -0,0 +1,28 @@ +if [ -z "$1" ] + then + echo "" + echo " Usage: ./sig {args}" + echo "" + printf "====\tCurrent Configuration" + printf "\t=====================" + for t in ${VARS[@]} + do + printf "\n\t%-15s%20s" $t ${!t} + done + printf "\n=====================================================" + echo "" + echo "" + echo " Command List:" + FILES=$(ls -1A ./$LANGUAGE/scripts 2>/dev/null | sed -e 's/\.sh$//' | sed -e 's/^/ /') + for f in $FILES + do + if [ -f "./$LANGUAGE/scripts/$f.sh" ]; then + DESC="$(head -n1 ./$LANGUAGE/scripts/$f.sh)" + printf "\n\t%-15s%-65s" $f "${DESC:1}" + fi + done + echo "" + exit +fi + +./$LANGUAGE/scripts/$1.sh "${@:2}" \ No newline at end of file diff --git a/utils/md5 b/utils/md5 new file mode 100644 index 0000000..af3cdec --- /dev/null +++ b/utils/md5 @@ -0,0 +1,4 @@ +.updateDirectories:971afb892e8280cb4c9ad43fb72a46a0 - +define.sh:3ecab0dffe2adfb950f3eb7c7061b750 - +main.sh:4e6e9f0650ec790ce2c4364db94f0caa - +search.sh:30e1842e9a13452ea883bb6516d28e1c - diff --git a/utils/search.sh b/utils/search.sh new file mode 100644 index 0000000..6707c16 --- /dev/null +++ b/utils/search.sh @@ -0,0 +1,103 @@ +function search() { + FILES2=$(ls -A $1 2>/dev/null) + for g in $FILES2 + do + if [ -d $1$g ]; + then + echo "$1$g is a directory" + search $1$g/ + else + echo "$1$g is a file" + if [ $g != "md5" ] && [ $g != "filelist" ] && [ $g != ".package.files" ]; then + if [ $g != ".coauthors" ] && [ $g != "version_info" ]; then + SUM=$(md5sum < $1$g) + echo "$g:$SUM" >> $1md5 + fi + echo "$g" >> $1filelist + else + echo " ignoring $g..." + fi + fi + done +} + +function check() { + echo "Check $1" + FILES2=$(ls -A $1 2>/dev/null) + if [ -f "$1/md5" ]; + then + echo " md5: http://sig.projectdivar.com/sigonasr2/SigScript/raw/branch/main/$1md5" + curl -H 'Cache-Control: no-cache, no-store' -s "http://sig.projectdivar.com/sigonasr2/SigScript/raw/branch/main/$1md5" --output /tmp/out + cmp -s $1/md5 /tmp/out + if [ "$?" -ne 0 ] + then + echo " Differences detected!" + cat /tmp/out + while IFS= read -r line + do + IFS=':' read -ra split <<< $line + g="${split[0]}" + echo "LINE -- $g" + if [ "$g" != "md5" ] && [ "$g" != "filelist" ] && [ "$g" != ".package.files" ]; then + if [ -f $1$g ]; + then + if [ "$g" != ".coauthors" ] && [ "$g" != "version_info" ]; then + echo "++Redownload $1$g..." + if [ -f "$1$g" ]; then + curl -H 'Cache-Control: no-cache, no-store' "http://sig.projectdivar.com/sigonasr2/SigScript/raw/branch/main/$1$g" --output $1$g + else + echo "===Could not find directory, assuming regular scripts directory exists." + curl -H 'Cache-Control: no-cache, no-store' "http://sig.projectdivar.com/sigonasr2/SigScript/raw/branch/main/$1$g" --output $LANGUAGE/scripts/$g + fi + fi + else + echo "++==Downloading $1$g..." + curl -H 'Cache-Control: no-cache, no-store' "http://sig.projectdivar.com/sigonasr2/SigScript/raw/branch/main/$1$g" --output $1$g + fi + fi + done < /tmp/out + fi + fi + if [ -f "$1/filelist" ]; + then + echo " filelist: http://sig.projectdivar.com/sigonasr2/SigScript/raw/branch/main/$1filelist" + curl -H 'Cache-Control: no-cache, no-store' -s "http://sig.projectdivar.com/sigonasr2/SigScript/raw/branch/main/$1filelist" --output /tmp/out + cmp -s $1/filelist /tmp/out + if [ "$?" -ne 0 ] + then + echo " Differences detected!" + cat /tmp/out + while IFS= read -r line + do + IFS=':' read -ra split <<< $line + g="${split[0]}" + echo "LINE -- $g" + if [ "$g" != "md5" ] && [ "$g" != "filelist" ] && [ "$g" != ".package.files" ]; then + if [ -f $1$g ]; + then + if [ "$g" != ".coauthors" ] && [ "$g" != "version_info" ]; then + echo "++Redownload $1$g..." + if [ -f "$1$g" ]; then + curl -H 'Cache-Control: no-cache, no-store' "http://sig.projectdivar.com/sigonasr2/SigScript/raw/branch/main/$1$g" --output $1$g + else + echo "===Could not find directory, assuming regular scripts directory exists." + curl -H 'Cache-Control: no-cache, no-store' "http://sig.projectdivar.com/sigonasr2/SigScript/raw/branch/main/$1$g" --output $LANGUAGE/scripts/$g + fi + fi + else + echo "++==Downloading $1$g..." + curl -H 'Cache-Control: no-cache, no-store' "http://sig.projectdivar.com/sigonasr2/SigScript/raw/branch/main/$1$g" --output $1$g + fi + fi + done < /tmp/out + fi + fi + for g in $FILES2 + do + if [ -d $1$g ]; + then + echo "$1$g is a directory" + check $1$g/ + fi + done +}