/* import * as THREE from "three"; */ const STATE_NULL = 0; const STATE_STOP = 2; const STATE_RUN = 3; const STATE_PAUSE = 4; const CALL_OVERFLOW = 4096 ; const MONO_FONT = "sometype" ; var µB = null ; var µX = null ; var µj = 0; var µsync = false; var µret = 0; var µs = 0 ; let µl = 0 ; var µI = null ; var µV = null ; var µA = null ; class Runtime { $state = STATE_NULL ; CONFIG = null; task_node = null ; runtime_start_time = 0; cpu_max_usage = .5 ; jpf = 1 ; wait = 1 ; waited = 0 ; request_frame = null; $Config = null; $Math = new module_Math(); $Basic = null; $D2 = null ; $D3 = null ; $Sprite = null ; $Data = null ; $Craft = null ; FPS = null ; CALL = null ; STRUCT = null ; constructor() { Log( "RUNTIME()" ); this.Speed(7); } Reset() { this.Stop(); µX = null ; } RuntimeError( message ) { var html = "<label>Runtime Error</label><p>"+message+"</p><p>Line "+µs+"</p>" ; var C = { 'html':html, 'style':"error" } ; Guru( "RT ERROR="+message ) ; µsync = true ; General.Pause(); } async Load( C ) { this.Stop() ; this.CONFIG = C ; if( C.url == µX?.url ) { Log("Module reuse"); this.$state = STATE_STOP ; General.Run(); } else { Log( "import="+C.url + " vs " + µX?.url ); µX = null; try { await import(C.url).then( (module)=> { if( module ) { Log("Module loaded"); this.$state = STATE_STOP ; µX = new module.default(); µX.url = this.CONFIG.url; General.Boot(); General.Run(); } else { } } ); } catch($e) { this.RuntimeError( "Invalid code. Try gain." ); CatchError($e); } } } Speed($speed) { let $X = [.5,1,2,4,8,15,30,60]; if( $speed < 0 ) { this.jpf = 1; this.wait = $X[-$speed]; } else { this.jpf = ($X[$speed]/60) * (1000/60) * this.cpu_max_usage; this.wait = 0; } } RunInit() { this.runtime_start_time = new Date().getTime() / 1000.0 ; Log( "RunInit new config" ); this.$Config = new module_Config(); this.$Basic?.Dispose(); this.$Basic = new module_Basic(); this.$D2?.Dispose(); this.$D2 = new module_D2; this.$D3?.Dispose(); this.$D3 = new module_D3; this.$Sprite?.Dispose(); this.$Sprite = new module_Sprite; this.$Data?.Dispose(); this.$Data = new module_Data ; this.$Craft?.Dispose(); this.$Craft = new module_Craft ; General.RefitWindow(); µj = 1 ; µI = [] ; µA = [] ; µV = new Array(µX.vars).fill(0); this.FPS = { frame:0, count:0, dt:0, last_frame:0, average:0 } ; this.CALL = [] ; this.STRUCT = {}; Log( "RunInit() done" ); } Run() { this.task_node = Rain.GetTaskNode("runtime") ; if( this.$state == STATE_NULL ) { alert("state_null"); return false; } else if( this.$state == STATE_RUN ) { return true ; } else if( this.$state == STATE_PAUSE ) { this.$state = STATE_RUN; return true ; } else if( this.$state == STATE_STOP ) { this.RunInit(); this.$state = STATE_RUN ; this.Runtime(); return true ; } else { Log("--"+this.$state); return false; } } Stop() { µj = 0 ; cancelAnimationFrame( this.request_frame ); if( this.$state == STATE_STOP || this.$state == STATE_NULL ) { return false ; } else { this.$state = STATE_STOP ; var $dt = (new Date().getTime() / 1000.0) - this.runtime_start_time; return true ; } } Pause() { if( this.$state == STATE_RUN ) { this.$state = STATE_PAUSE; return true; } else if( this.$state == STATE_PAUSE ) { return true ; } else { return false; } } Runtime() { if( this.FPS.last_frame ) { let dt = performance.now() - this.FPS.last_frame ; this.FPS.frame ++ ; this.FPS.count ++ ; this.FPS.dt += dt ; if( this.FPS.dt > 1000 ) { this.FPS.average = this.FPS.average ? (this.FPS.average*5+this.FPS.count)/6 : this.FPS.count ; this.FPS.count = 0 ; this.FPS.dt = 0 ; } } this.FPS.last_frame = performance.now(); if( ! µB || ! µX ) { Log( "! Runtime *BREAK*" ); return false; } else if( this.$state == STATE_STOP || this.$state == STATE_NULL ) { return; } else if( this.$state == STATE_PAUSE ) { } else if( this.waited > 0 ) { this.waited -- ; } else { this.Jumps(); µB.$D3?.Update(); this.waited = this.wait ; } if( µj != 0 ) { this.request_frame = requestAnimationFrame( this.Runtime.bind(µB) ); } else { this.Stop(); } } Jumps() { let $jumps = this.jpf ; let $loop_time = performance.now(); let $dt = 0 ; µsync = false ; while( $jumps>0 && µj !=0 ) { try { µX["Seg_"+µj](); } catch($e) { CatchError( $e ); this.Stop(); break; } if( µsync == true ) { break; } else if( this.wait != 0 ) { $jumps --; } else { $dt = performance.now() - $loop_time; if( $dt > this.jpf ) { break; } } } } Jmp(to, back) { if( µX["Seg_"+to] === undefined ) { this.RuntimeError( "Gosub Label not found" ); } else if( this.CALL.length > CALL_OVERFLOW ) { this.RuntimeError( "Gosub loop / Call stack overflow" ); } else { this.CALL.push(back); µj = to ; } } Ret() { µj = this.CALL.pop() ; } Stg() { let ARG = Array.prototype.slice.call(arguments); let id = ARG.join() ; let value = this.STRUCT[id]??0 ; return value ; } Sts() { let ARG = Array.prototype.slice.call(arguments); let value = ARG.shift(); let id = ARG.join() ; this.STRUCT[id] = value ; } LayerScreenshot( task_id ) { let merge = document.createElement("CANVAS"); merge.width = 1920 ; merge.height = 1080 ; let format = this.$Config.GetBestFormat(16/9, this.$Config.width, this.$Config.$height) ; let ox = (this.$Config.width-format.width)/2 ; let oy = (this.$Config.height-format.height)/2 ; let ctx = merge.getContext("2d",{willReadFrequently:true}); ctx.fillStyle = this.$Config.background_rgba ; ctx.fillRect(ox, oy, format.width, format.height); let SCREENS = [] ; for( let id in µB.$D2.SCREEN ) { SCREENS.push(µB.$D2.SCREEN[id]); } SCREENS.push( µB.$Basic.Screen ); SCREENS.push( { canvas:µB.$D3.canvas, alpha:1 } ) ; let count = SCREENS.length ; while( count > 0 ) { let min = 1000 ; let next_index = null ; for( let index in SCREENS ) { if( SCREENS[index] ) { let z = SCREENS[index].canvas.style.zIndex ; if( z < min ) { min = z ; next_index = index ; } } } if( next_index === null ) { break; } else { Log( "Merge SS z="+min +","+ SCREENS[next_index].canvas.className ) ; ctx.globalAlpha = SCREENS[next_index].alpha ; ctx.drawImage(SCREENS[next_index].canvas,ox,oy,format.width,format.height,0,0,merge.width,merge.height); SCREENS[next_index] = false ; count -- ; } } SCREENS = null ; let image = merge.toDataURL('image/jpeg',0.95); merge.remove(); return image ; } };