diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..1284123 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "src/glkote"] + path = src/glkote + url = https://github.com/erkyrath/glkote.git diff --git a/build.py b/build.py index 4cdb3b5..d2a5535 100755 --- a/build.py +++ b/build.py @@ -11,30 +11,32 @@ # jQuery, but we don't try to include it -- that makes it hard to integrate # Quixe with other web services. We assume that the host page already has # jQuery available (version 1.9 or later). +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function -import sys import re import subprocess +import sys + +regex_debug = re.compile(b';;;.+$', re.M) -regex_debug = re.compile(';;;.+$', re.M) def compress_source(target, srcls): - print 'Writing', target - targetfl = open(target, 'w') - proc = subprocess.Popen(['python', 'tools/rjsmin.py'], - stdin=subprocess.PIPE, - stdout=targetfl) - for src in srcls: - fl = open(src) - dat = fl.read() - dat = regex_debug.sub('', dat) - fl.close() - proc.stdin.write(dat) - proc.stdin.close() - ret = proc.wait() - if (ret): - raise Exception('Process result code %d' % (ret,)) - targetfl.close() + print('Writing', target) + with open(target, 'wb') as targetfl: + proc = subprocess.Popen([sys.executable, 'tools/rjsmin.py'], + stdin=subprocess.PIPE, + stdout=targetfl) + for src in srcls: + with open(src, 'rb') as fl: + dat = fl.read() + dat = regex_debug.sub(b'', dat) + proc.stdin.write(dat) + proc.stdin.close() + ret = proc.wait() + if (ret): + raise Exception('Process result code %d' % (ret,)) compress_source( 'lib/glkote.min.js', [ @@ -49,4 +51,3 @@ def compress_source(target, srcls): 'src/quixe/gi_dispa.js', 'src/quixe/gi_load.js', ]) - diff --git a/lib/glkote.min.js b/lib/glkote.min.js index 8a5f053..36318d0 100644 --- a/lib/glkote.min.js +++ b/lib/glkote.min.js @@ -21,12 +21,8 @@ recording_state.label=iface.recording_label;if(iface.recording_format=='simple') recording_state.format='simple';else recording_state.format='glkote';glkote_log('Transcript recording active: session '+recording_state.sessionId+' "'+recording_state.label+'", destination '+recording_handler_url);}} send_response('init',null,current_metrics);} -function measure_window(){var metrics={};var el,linesize,winsize,line1size,line2size,spansize;el=$('#'+gameport_id);if(!el.length) -return'Cannot find gameport element #'+gameport_id+' in this document.';metrics.width=el.width();metrics.height=el.height();el=$('#layouttest_grid');if(!el.length) -return'Cannot find layouttest_grid element for window measurement.';winsize={width:el.outerWidth(),height:el.outerHeight()};el=$('#layouttest_gridspan');spansize={width:el.outerWidth(),height:el.outerHeight()};el=$('#layouttest_gridline');line1size={width:el.outerWidth(),height:el.outerHeight()};el=$('#layouttest_gridline2');line2size={width:el.outerWidth(),height:el.outerHeight()};metrics.gridcharheight=($('#layouttest_gridline2').position().top --$('#layouttest_gridline').position().top);metrics.gridcharwidth=($('#layouttest_gridspan').width()/8);metrics.gridmarginx=winsize.width-spansize.width;metrics.gridmarginy=winsize.height-(line1size.height+line2size.height);el=$('#layouttest_buffer');if(!el.length) -return'Cannot find layouttest_buffer element for window measurement.';winsize={width:el.outerWidth(),height:el.outerHeight()};el=$('#layouttest_bufferspan');spansize={width:el.outerWidth(),height:el.outerHeight()};el=$('#layouttest_bufferline');line1size={width:el.outerWidth(),height:el.outerHeight()};el=$('#layouttest_bufferline2');line2size={width:el.outerWidth(),height:el.outerHeight()};metrics.buffercharheight=($('#layouttest_bufferline2').position().top --$('#layouttest_bufferline').position().top);metrics.buffercharwidth=($('#layouttest_bufferspan').width()/8);metrics.buffermarginx=winsize.width-spansize.width;metrics.buffermarginy=winsize.height-(line1size.height+line2size.height);metrics.outspacingx=0;metrics.outspacingy=0;metrics.inspacingx=0;metrics.inspacingy=0;if(game_interface.spacing!=undefined){metrics.outspacingx=game_interface.spacing;metrics.outspacingy=game_interface.spacing;metrics.inspacingx=game_interface.spacing;metrics.inspacingy=game_interface.spacing;} +function measure_window(){var metrics={};var linesize,winsize,line1size,line2size,spansize;var gameport=$('#'+gameport_id);if(!gameport.length) +return'Cannot find gameport element #'+gameport_id+' in this document.';metrics.width=gameport.width();metrics.height=gameport.height();var layout_test_pane=$('
');layout_test_pane.css({position:'absolute',visibility:'hidden',left:'-1000px'});var line=$('
');$('',{'class':"Style_normal"}).text('12345678').appendTo(line);var gridwin=$('
',{'class':"WindowFrame GridWindow"});var gridline1=line.clone().addClass('GridLine').appendTo(gridwin);var gridline2=line.clone().addClass('GridLine').appendTo(gridwin);var gridspan=gridline1.children('span');layout_test_pane.append(gridwin);var bufwin=$('
',{'class':"WindowFrame BufferWindow"});var bufline1=line.clone().addClass('BufferLine').appendTo(bufwin);var bufline2=line.clone().addClass('BufferLine').appendTo(bufwin);var bufspan=bufline1.children('span');layout_test_pane.append(bufwin);layout_test_pane.appendTo(gameport);console.log(layout_test_pane);var get_size=function(element){return{width:element.outerWidth(),height:element.outerHeight()};};winsize=get_size(gridwin);spansize=get_size(gridspan);line1size=get_size(gridline1);line2size=get_size(gridline2);metrics.gridcharheight=gridline2.position().top-gridline1.position().top;metrics.gridcharwidth=gridspan.width()/8;metrics.gridmarginx=winsize.width-spansize.width;metrics.gridmarginy=winsize.height-(line1size.height+line2size.height);winsize=get_size(bufwin);spansize=get_size(bufspan);line1size=get_size(bufline1);line2size=get_size(bufline2);metrics.buffercharheight=bufline2.position().top-bufline1.position().top;metrics.buffercharwidth=bufspan.width()/8;metrics.buffermarginx=winsize.width-spansize.width;metrics.buffermarginy=winsize.height-(line1size.height+line2size.height);layout_test_pane.remove();metrics.outspacingx=0;metrics.outspacingy=0;metrics.inspacingx=0;metrics.inspacingy=0;if(game_interface.spacing!=undefined){metrics.outspacingx=game_interface.spacing;metrics.outspacingy=game_interface.spacing;metrics.inspacingx=game_interface.spacing;metrics.inspacingy=game_interface.spacing;} if(game_interface.outspacing!=undefined){metrics.outspacingx=game_interface.outspacing;metrics.outspacingy=game_interface.outspacing;} if(game_interface.inspacing!=undefined){metrics.inspacingx=game_interface.inspacing;metrics.inspacingy=game_interface.inspacing;} if(game_interface.inspacingx!=undefined) @@ -906,10 +902,12 @@ str.bufeof=0;else str.bufeof=str.buflen;if(window.GiDispa) GiDispa.retain_array(buf);} return str;} -function glk_stream_open_resource(filenum,rock){var str;var el=GiLoad.find_data_chunk(filenum);if(!el) +function glk_stream_open_resource(filenum,rock){var str;if(!window.GiLoad||!GiLoad.find_data_chunk) +return null;var el=GiLoad.find_data_chunk(filenum);if(!el) return null;var buf=el.data;var isbinary=(el.type=='BINA');str=gli_new_stream(strtype_Resource,true,false,rock);str.unicode=false;str.isbinary=isbinary;if(buf){str.buf=buf;str.buflen=buf.length;str.bufpos=0;str.bufeof=str.buflen;} return str;} -function glk_stream_open_resource_uni(filenum,rock){var str;var el=GiLoad.find_data_chunk(filenum);if(!el) +function glk_stream_open_resource_uni(filenum,rock){var str;if(!window.GiLoad||!GiLoad.find_data_chunk) +return null;var el=GiLoad.find_data_chunk(filenum);if(!el) return null;var buf=el.data;var isbinary=(el.type=='BINA');str=gli_new_stream(strtype_Resource,true,false,rock);str.unicode=true;str.isbinary=isbinary;if(buf){str.buf=buf;str.buflen=buf.length;str.bufpos=0;str.bufeof=str.buflen;} return str;} function glk_stream_close(str,result){if(!str) diff --git a/lib/quixe.min.js b/lib/quixe.min.js index f727c37..1177108 100644 --- a/lib/quixe.min.js +++ b/lib/quixe.min.js @@ -9,7 +9,7 @@ throw ex;}} function quixe_resume(){try{done_executing=vm_stopped;execute_loop();} catch(ex){qstackdump();Glk.fatal_error("Quixe run: "+show_exception(ex));if(opt_rethrow_exceptions) throw ex;}} -function show_exception(ex){if(typeof(ex)=='string') +function show_exception(ex){if(typeof(ex)==='string') return ex;var res=ex.toString();if(ex.message) res=res+' '+ex.message;if(ex.fileName) res=res+' '+ex.fileName;if(ex.lineNumber) @@ -32,10 +32,10 @@ val=val+(" \""+debugfunc.name+"\"");ls.push(val);} qlog("VM stack dump: "+ls.join(", "));} var bytestring_table=Array(256);var quotechar_table=Array(256);function setup_bytestring_table(){var ix,val;for(ix=0;ix<0x100;ix++){val=ix.toString(16);if(ix<0x10) val="0"+val;bytestring_table[ix]=val;} -for(ix=0;ix<0x100;ix++){if(ix>=0x20&&ix<0x7f){if(ix==0x22||ix==0x27||ix==0x5c) +for(ix=0;ix<0x100;ix++){if(ix>=0x20&&ix<0x7f){if(ix===0x22||ix===0x27||ix===0x5c) val="\\"+String.fromCharCode(ix);else val=String.fromCharCode(ix);} -else if(ix==0x0a){val="\\n";} +else if(ix===0x0a){val="\\n";} else{val="\\x"+bytestring_table[ix];} quotechar_table[ix]=val;}} function ByteRead4(arr,addr){return(arr[addr]*0x1000000)+(arr[addr+1]*0x10000) @@ -64,22 +64,22 @@ function QuoteMem4(addr){if(memmap[addr]) return"0x"+bytestring_table[memmap[addr]]+bytestring_table[memmap[addr+1]]+bytestring_table[memmap[addr+2]]+bytestring_table[memmap[addr+3]];if(memmap[addr+1]) return"0x"+bytestring_table[memmap[addr+1]]+bytestring_table[memmap[addr+2]]+bytestring_table[memmap[addr+3]];if(memmap[addr+2]) return"0x"+bytestring_table[memmap[addr+2]]+bytestring_table[memmap[addr+3]];return"0x"+bytestring_table[memmap[addr+3]];} -function ReadArgByte(addr){if(addr==0xffffffff) +function ReadArgByte(addr){if(addr===0xffffffff) return frame.valstack.pop()&0xFF;else return Mem1(addr);} -function WriteArgByte(addr,val){if(addr==0xffffffff) +function WriteArgByte(addr,val){if(addr===0xffffffff) frame.valstack.push(val&0xFF);else MemW1(addr,val);} -function ReadArgWord(addr){if(addr==0xffffffff) +function ReadArgWord(addr){if(addr===0xffffffff) return frame.valstack.pop();else return Mem4(addr);} -function WriteArgWord(addr,val){if(addr==0xffffffff) +function WriteArgWord(addr,val){if(addr===0xffffffff) frame.valstack.push(val);else MemW4(addr,val);} -function ReadStructField(addr,fieldnum){if(addr==0xffffffff) +function ReadStructField(addr,fieldnum){if(addr===0xffffffff) return frame.valstack.pop();else return Mem4(addr+4*fieldnum);} -function WriteStructField(addr,fieldnum,val){if(addr==0xffffffff) +function WriteStructField(addr,fieldnum,val){if(addr===0xffffffff) frame.valstack.push(val);else MemW4(addr+4*fieldnum,val);} function SetResumeStore(val){resumevalue=val;} @@ -91,9 +91,9 @@ val="0"+val;return("\\u"+val);} else{var val2;val-=0x10000;val2=0xD800+(val>>10);val=0xDC00+(val&0x3FF);return("\\u"+val2.toString(16)+"\\u"+val.toString(16));}} function QuoteStr1ToString(val){return QuoteCharToString(val.charCodeAt(0));} var regexp_string_unsafe=/[^a-zA-Z0-9 .,;:?!=_+()-]/g;function QuoteEscapeString(val){val=val.replace(regexp_string_unsafe,QuoteStr1ToString);return'"'+val+'"';} -function fatal_error(msg){var ix,val;if(arguments.length>1){msg+=" (";for(ix=1;ix1){msg+=" (";for(ix=1;ix=arr.length){qlog("Bad frameptr in serialized stack frame");return undefined;} -arr=arr.splice(frameptr,arr.length);var framelen=ByteRead4(arr,0);var localspos=ByteRead4(arr,4);var rawformat=arr.slice(8,localspos);var localsformat=[];var addr=8;while(1){var loctype=ByteRead1(arr,addr);addr++;var locnum=ByteRead1(arr,addr);addr++;if(loctype==0){break;} -if(loctype!=1&&loctype!=2&&loctype!=4){fatal_error("Invalid local variable size in function header.",loctype);} +arr=arr.splice(frameptr,arr.length);var framelen=ByteRead4(arr,0);var localspos=ByteRead4(arr,4);var rawformat=arr.slice(8,localspos);var localsformat=[];var addr=8;while(1){var loctype=ByteRead1(arr,addr);addr++;var locnum=ByteRead1(arr,addr);addr++;if(loctype===0){break;} +if(loctype!==1&&loctype!==2&&loctype!==4){fatal_error("Invalid local variable size in function header.",loctype);} localsformat.push({size:loctype,count:locnum});} -var vmfunc=new VMFunc(null,null,localsformat,rawformat);var frame=new StackFrame(vmfunc);frame.framestart=frameptr;for(var i=0;i>>0;context.code.push("pc = "+newpc+";");context.vmfunc.pathaddrs[newpc]=true;}} -else{oputil_unload_offstate(context,!unconditional);context.code.push("if (("+operand+")==0 || ("+operand+")==1) {");context.code.push("leave_function();");context.code.push("pop_callstub("+operand+");");context.code.push("}");context.code.push("else {");context.code.push("pc = ("+context.cp+"+("+operand+")-2) >>>0;");context.code.push("}");} +else{oputil_unload_offstate(context,!unconditional);context.code.push("if (("+operand+")===0 || ("+operand+")===1) {");context.code.push("leave_function();");context.code.push("pop_callstub("+operand+");");context.code.push("}");context.code.push("else {");context.code.push("pc = ("+context.cp+"+("+operand+")-2) >>>0;");context.code.push("}");} context.code.push("return;");} var opcode_table={0x0:function(context,operands){},0x10:function(context,operands){context.code.push(operands[2]+"(("+operands[0]+")+("+operands[1]+")) >>>0);");},0x11:function(context,operands){context.code.push(operands[2]+"(("+operands[0]+")-("+operands[1]+")) >>>0);");},0x12:function(context,operands){var sign0=oputil_signify_operand(context,operands[0]);var sign1=oputil_signify_operand(context,operands[1]);context.code.push(operands[2]+"(("+sign0+")*("+sign1+")) >>>0);");},0x13:function(context,operands){var sign0=oputil_signify_operand(context,operands[0]);var sign1=oputil_signify_operand(context,operands[1]);var holdvar=alloc_holdvar(context);context.code.push(holdvar+"=(("+sign0+")/("+sign1+"));");context.code.push("if (!isFinite("+holdvar+")) fatal_error('Division by zero.');");context.code.push(operands[2]+"("+holdvar+">=0)?Math.floor("+holdvar+"):(-Math.floor(-"+holdvar+") >>>0));");},0x14:function(context,operands){var sign0=oputil_signify_operand(context,operands[0]);var sign1=oputil_signify_operand(context,operands[1]);var holdvar=alloc_holdvar(context);context.code.push(holdvar+"=(("+sign0+")%("+sign1+"));");context.code.push("if (!isFinite("+holdvar+")) fatal_error('Modulo division by zero.');");context.code.push(operands[2]+holdvar+" >>>0);");},0x15:function(context,operands){context.code.push(operands[1]+"(-("+operands[0]+")) >>>0);");},0x18:function(context,operands){context.code.push(operands[2]+"(("+operands[0]+")&("+operands[1]+")) >>>0);");},0x19:function(context,operands){context.code.push(operands[2]+"(("+operands[0]+")|("+operands[1]+")) >>>0);");},0x1a:function(context,operands){context.code.push(operands[2]+"(("+operands[0]+")^("+operands[1]+")) >>>0);");},0x1b:function(context,operands){context.code.push(operands[1]+"(~("+operands[0]+")) >>>0);");},0x1c:function(context,operands){if(quot_isconstant(operands[1])){var val=Number(operands[1]);if(val<32) context.code.push(operands[2]+"(("+operands[0]+")<<"+val+") >>>0);");else @@ -190,7 +190,7 @@ context.code.push(operands[2]+"("+operands[0]+")>>>"+val+");");else context.code.push(operands[2]+"0);");} else{context.code.push(operands[2]+"("+operands[1]+"<32) ? ("+operands[0]+">>>"+operands[1]+") : 0);");}},0x20:function(context,operands){oputil_perform_jump(context,operands[0],true);context.path_ends=true;},0x104:function(context,operands){if(quot_isconstant(operands[0])){var newpc=Number(operands[0]);context.code.push("pc = "+newpc+";");context.vmfunc.pathaddrs[newpc]=true;} else{context.code.push("pc = "+operands[0]+";");} -oputil_unload_offstate(context);context.code.push("return;");context.path_ends=true;},0x22:function(context,operands){context.code.push("if (("+operands[0]+")==0) {");oputil_perform_jump(context,operands[1]);context.code.push("}");},0x23:function(context,operands){context.code.push("if (("+operands[0]+")!=0) {");oputil_perform_jump(context,operands[1]);context.code.push("}");},0x24:function(context,operands){context.code.push("if (("+operands[0]+")==("+operands[1]+")) {");oputil_perform_jump(context,operands[2]);context.code.push("}");},0x25:function(context,operands){context.code.push("if (("+operands[0]+")!=("+operands[1]+")) {");oputil_perform_jump(context,operands[2]);context.code.push("}");},0x26:function(context,operands){var sign0=oputil_signify_operand(context,operands[0]);var sign1=oputil_signify_operand(context,operands[1]);context.code.push("if (("+sign0+")<("+sign1+")) {");oputil_perform_jump(context,operands[2]);context.code.push("}");},0x27:function(context,operands){var sign0=oputil_signify_operand(context,operands[0]);var sign1=oputil_signify_operand(context,operands[1]);context.code.push("if (("+sign0+")>=("+sign1+")) {");oputil_perform_jump(context,operands[2]);context.code.push("}");},0x28:function(context,operands){var sign0=oputil_signify_operand(context,operands[0]);var sign1=oputil_signify_operand(context,operands[1]);context.code.push("if (("+sign0+")>("+sign1+")) {");oputil_perform_jump(context,operands[2]);context.code.push("}");},0x29:function(context,operands){var sign0=oputil_signify_operand(context,operands[0]);var sign1=oputil_signify_operand(context,operands[1]);context.code.push("if (("+sign0+")<=("+sign1+")) {");oputil_perform_jump(context,operands[2]);context.code.push("}");},0x2a:function(context,operands){context.code.push("if (("+operands[0]+")<("+operands[1]+")) {");oputil_perform_jump(context,operands[2]);context.code.push("}");},0x2b:function(context,operands){context.code.push("if (("+operands[0]+")>=("+operands[1]+")) {");oputil_perform_jump(context,operands[2]);context.code.push("}");},0x2c:function(context,operands){context.code.push("if (("+operands[0]+")>("+operands[1]+")) {");oputil_perform_jump(context,operands[2]);context.code.push("}");},0x2d:function(context,operands){context.code.push("if (("+operands[0]+")<=("+operands[1]+")) {");oputil_perform_jump(context,operands[2]);context.code.push("}");},0x30:function(context,operands){if(quot_isconstant(operands[1])){var ix;var argc=Number(operands[1]);for(ix=0;ix=("+sign1+")) {");oputil_perform_jump(context,operands[2]);context.code.push("}");},0x28:function(context,operands){var sign0=oputil_signify_operand(context,operands[0]);var sign1=oputil_signify_operand(context,operands[1]);context.code.push("if (("+sign0+")>("+sign1+")) {");oputil_perform_jump(context,operands[2]);context.code.push("}");},0x29:function(context,operands){var sign0=oputil_signify_operand(context,operands[0]);var sign1=oputil_signify_operand(context,operands[1]);context.code.push("if (("+sign0+")<=("+sign1+")) {");oputil_perform_jump(context,operands[2]);context.code.push("}");},0x2a:function(context,operands){context.code.push("if (("+operands[0]+")<("+operands[1]+")) {");oputil_perform_jump(context,operands[2]);context.code.push("}");},0x2b:function(context,operands){context.code.push("if (("+operands[0]+")>=("+operands[1]+")) {");oputil_perform_jump(context,operands[2]);context.code.push("}");},0x2c:function(context,operands){context.code.push("if (("+operands[0]+")>("+operands[1]+")) {");oputil_perform_jump(context,operands[2]);context.code.push("}");},0x2d:function(context,operands){context.code.push("if (("+operands[0]+")<=("+operands[1]+")) {");oputil_perform_jump(context,operands[2]);context.code.push("}");},0x30:function(context,operands){if(quot_isconstant(operands[1])){var ix;var argc=Number(operands[1]);for(ix=0;ix 0) {");context.code.push("if ("+sign1+" > 0) {");context.code.push("vals1 = "+sign1+" % "+sign0+";");context.code.push("} else {");context.code.push("vals1 = "+sign0+" - (-("+sign1+")) % "+sign0+";");context.code.push("}");context.code.push("if (vals1) {");context.code.push("pos = frame.valstack.length - "+sign0+";");context.code.push("roll = frame.valstack.slice(frame.valstack.length-vals1, frame.valstack.length).concat(frame.valstack.slice(pos, frame.valstack.length-vals1));");context.code.push("for (ix=0; ix<"+sign0+"; ix++) { frame.valstack[pos+ix] = roll[ix]; }");context.code.push("roll = undefined;");context.code.push("}");context.code.push("}");},0x54:function(context,operands){oputil_unload_offstate(context);if(quot_isconstant(operands[0])){var ix,holdvar;var pos=Number(operands[0]);for(ix=0;ix0) expr="Math.floor(random_func() * "+val+")";else expr="-Math.floor(random_func() * "+(-val)+")";} else{var sign0=oputil_signify_operand(context,operands[0],true);var holdvar=alloc_holdvar(context);expr=holdvar;context.code.push("if ("+sign0+" > 0)");context.code.push(holdvar+" = Math.floor(random_func() * "+sign0+");");context.code.push("else if ("+sign0+" < 0)");context.code.push(holdvar+" = -Math.floor(random_func() * -"+sign0+");");context.code.push("else");context.code.push(holdvar+" = (Math.floor(random_func() * 0x10000) | (Math.floor(random_func() * 0x10000) << 16)) >>>0;");} -context.code.push(operands[1]+expr+");");},0x111:function(context,operands){context.code.push("set_random("+operands[0]+");");},0x120:function(context,operands){context.offstack.length=0;context.offloc.length=0;context.offlocdirty.length=0;context.code.push("done_executing = true; vm_stopped = true;");context.code.push("return;");context.path_ends=true;},0x121:function(context,operands){context.code.push(operands[0]+"perform_verify());");},0x122:function(context,operands){context.offstack.length=0;context.offloc.length=0;context.offlocdirty.length=0;context.code.push("vm_restart();");context.code.push("return;");context.path_ends=true;},0x123:function(context,operands){oputil_unload_offstate(context);context.varsused["ix"]=true;oputil_push_callstub(context,operands[1]);context.code.push("ix = vm_save("+operands[0]+");");context.code.push("pop_callstub(ix ? 0 : 1);");context.code.push("return;");context.path_ends=true;},0x124:function(context,operands){oputil_unload_offstate(context);context.code.push("if (vm_restore("+operands[0]+")) {");context.code.push("pop_callstub((-1)>>>0);");context.code.push("} else {");oputil_store(context,operands[1],"1");oputil_unload_offstate(context);context.code.push("pc = "+context.cp+";");context.code.push("}");context.code.push("return;");context.path_ends=true;},0x125:function(context,operands){oputil_unload_offstate(context);oputil_push_callstub(context,operands[0]);context.code.push("vm_saveundo();");context.code.push("pop_callstub(0);");context.code.push("return;");context.path_ends=true;},0x126:function(context,operands){oputil_unload_offstate(context);context.code.push("if (vm_restoreundo()) {");context.code.push("pop_callstub((-1)>>>0);");context.code.push("} else {");oputil_store(context,operands[0],"1");oputil_unload_offstate(context);context.code.push("pc = "+context.cp+";");context.code.push("}");context.code.push("return;");context.path_ends=true;},0x127:function(context,operands){context.code.push("protectstart="+operands[0]+";");context.code.push("protectend=protectstart+("+operands[1]+");");context.code.push("if (protectstart==protectend) {") +context.code.push(operands[1]+expr+");");},0x111:function(context,operands){context.code.push("set_random("+operands[0]+");");},0x120:function(context,operands){context.offstack.length=0;context.offloc.length=0;context.offlocdirty.length=0;context.code.push("done_executing = true; vm_stopped = true;");context.code.push("return;");context.path_ends=true;},0x121:function(context,operands){context.code.push(operands[0]+"perform_verify());");},0x122:function(context,operands){context.offstack.length=0;context.offloc.length=0;context.offlocdirty.length=0;context.code.push("vm_restart();");context.code.push("return;");context.path_ends=true;},0x123:function(context,operands){oputil_unload_offstate(context);context.varsused["ix"]=true;oputil_push_callstub(context,operands[1]);context.code.push("ix = vm_save("+operands[0]+");");context.code.push("pop_callstub(ix ? 0 : 1);");context.code.push("return;");context.path_ends=true;},0x124:function(context,operands){oputil_unload_offstate(context);context.code.push("if (vm_restore("+operands[0]+")) {");context.code.push("pop_callstub((-1)>>>0);");context.code.push("} else {");oputil_store(context,operands[1],"1");oputil_unload_offstate(context);context.code.push("pc = "+context.cp+";");context.code.push("}");context.code.push("return;");context.path_ends=true;},0x125:function(context,operands){oputil_unload_offstate(context);oputil_push_callstub(context,operands[0]);context.code.push("vm_saveundo();");context.code.push("pop_callstub(0);");context.code.push("return;");context.path_ends=true;},0x126:function(context,operands){oputil_unload_offstate(context);context.code.push("if (vm_restoreundo()) {");context.code.push("pop_callstub((-1)>>>0);");context.code.push("} else {");oputil_store(context,operands[0],"1");oputil_unload_offstate(context);context.code.push("pc = "+context.cp+";");context.code.push("}");context.code.push("return;");context.path_ends=true;},0x127:function(context,operands){context.code.push("protectstart="+operands[0]+";");context.code.push("protectend=protectstart+("+operands[1]+");");context.code.push("if (protectstart===protectend) {") context.code.push(" protectstart=0; protectend=0;");context.code.push("}");},0x170:function(context,operands){context.varsused["maddr"]=true;context.varsused["mlen"]=true;context.varsused["ix"]=true;context.code.push("mlen="+operands[0]+";");context.code.push("maddr="+operands[1]+";");context.code.push("for (ix=0; ix 0x7fffffff))");context.code.push(" res = 0x7fffffff;");context.code.push(" else");context.code.push(" res = Math.floor(valf);");context.code.push("} else {");context.code.push(" if (isNaN(valf) || !isFinite(valf) || (valf < -0x80000000))");context.code.push(" res = -0x80000000;");context.code.push(" else");context.code.push(" res = Math.ceil(valf);");context.code.push("}");context.code.push(operands[1]+"res>>>0);");},0x192:function(context,operands){context.varsused["valf"]=true;context.varsused["res"]=true;context.code.push("valf = "+oputil_decode_float(context,operands[0])+";");context.code.push("if (!("+operands[0]+" & 0x80000000)) {");context.code.push(" if (isNaN(valf) || !isFinite(valf))");context.code.push(" res = 0x7fffffff;");context.code.push(" else");context.code.push(" res = Math.round(valf);");context.code.push(" if (res > 0x7fffffff) res = 0x7fffffff;");context.code.push("} else {");context.code.push(" if (isNaN(valf) || !isFinite(valf))");context.code.push(" res = -0x80000000;");context.code.push(" else");context.code.push(" res = Math.round(valf);");context.code.push(" if (res < -0x80000000) res = -0x80000000;");context.code.push("}");context.code.push(operands[1]+"res>>>0);");},0x198:function(context,operands){var valf=oputil_decode_float(context,operands[0]);context.code.push(operands[1]+"encode_float(Math.ceil("+valf+")));");},0x199:function(context,operands){var valf=oputil_decode_float(context,operands[0]);context.code.push(operands[1]+"encode_float(Math.floor("+valf+")));");},0x1A0:function(context,operands){var valf0=oputil_decode_float(context,operands[0]);var valf1=oputil_decode_float(context,operands[1]);context.code.push(operands[2]+"encode_float("+valf0+" + "+valf1+"));");},0x1A1:function(context,operands){var valf0=oputil_decode_float(context,operands[0]);var valf1=oputil_decode_float(context,operands[1]);context.code.push(operands[2]+"encode_float("+valf0+" - "+valf1+"));");},0x1A2:function(context,operands){var valf0=oputil_decode_float(context,operands[0]);var valf1=oputil_decode_float(context,operands[1]);context.code.push(operands[2]+"encode_float("+valf0+" * "+valf1+"));");},0x1A3:function(context,operands){var valf0=oputil_decode_float(context,operands[0]);var valf1=oputil_decode_float(context,operands[1]);context.code.push(operands[2]+"encode_float("+valf0+" / "+valf1+"));");},0x1A4:function(context,operands){var valf0=oputil_decode_float(context,operands[0],true);var valf1=oputil_decode_float(context,operands[1],true);context.varsused["modv"]=true;context.varsused["quov"]=true;context.code.push("modv=("+valf0+" % "+valf1+");");context.code.push("quov=encode_float(("+valf0+" - modv) / "+valf1+");");context.code.push("if (quov == 0x0 || quov == 0x80000000) {");context.code.push(" quov = (("+operands[0]+" ^ "+operands[1]+") & 0x80000000) >>>0;");context.code.push("}");context.code.push(operands[2]+"encode_float(modv));");context.code.push(operands[3]+"quov);");},0x1A8:function(context,operands){var valf=oputil_decode_float(context,operands[0]);context.code.push(operands[1]+"encode_float(Math.sqrt("+valf+")));");},0x1A9:function(context,operands){var valf=oputil_decode_float(context,operands[0]);context.code.push(operands[1]+"encode_float(Math.exp("+valf+")));");},0x1AA:function(context,operands){var valf=oputil_decode_float(context,operands[0]);context.code.push(operands[1]+"encode_float(Math.log("+valf+")));");},0x1AB:function(context,operands){context.varsused["valf"]=true;var valf0=oputil_decode_float(context,operands[0],true);var valf1=oputil_decode_float(context,operands[1],true);context.code.push("if ("+operands[0]+" == 0x3f800000) {");context.code.push(" valf = 0x3f800000;");context.code.push("} else if ("+operands[0]+" == 0xbf800000 && ("+operands[1]+" == 0xff800000 || "+operands[1]+" == 0x7f800000)) {");context.code.push(" valf = 0x3f800000;");context.code.push("} else {");context.code.push(" valf=encode_float(Math.pow("+valf0+", "+valf1+"));");context.code.push("}");context.code.push(operands[2]+"valf);");},0x1B0:function(context,operands){var valf=oputil_decode_float(context,operands[0]);context.code.push(operands[1]+"encode_float(Math.sin("+valf+")));");},0x1B1:function(context,operands){var valf=oputil_decode_float(context,operands[0]);context.code.push(operands[1]+"encode_float(Math.cos("+valf+")));");},0x1B2:function(context,operands){var valf=oputil_decode_float(context,operands[0]);context.code.push(operands[1]+"encode_float(Math.tan("+valf+")));");},0x1B3:function(context,operands){var valf=oputil_decode_float(context,operands[0]);context.code.push(operands[1]+"encode_float(Math.asin("+valf+")));");},0x1B4:function(context,operands){var valf=oputil_decode_float(context,operands[0]);context.code.push(operands[1]+"encode_float(Math.acos("+valf+")));");},0x1B5:function(context,operands){var valf=oputil_decode_float(context,operands[0]);context.code.push(operands[1]+"encode_float(Math.atan("+valf+")));");},0x1B6:function(context,operands){var valf0=oputil_decode_float(context,operands[0]);var valf1=oputil_decode_float(context,operands[1]);context.code.push(operands[2]+"encode_float(Math.atan2("+valf0+", "+valf1+")));");},0x1C0:function(context,operands){var val,valf0,valf1,valf2;context.varsused["fequal"]=true;context.varsused["fdiff"]=true;context.code.push("if (("+operands[2]+" & 0x7f800000) == 0x7f800000 && ("+operands[2]+" & 0x007fffff) != 0) {");context.code.push(" fequal = 0;");context.code.push("} else if (("+operands[0]+" == 0xff800000 || "+operands[0]+" == 0x7f800000) && ("+operands[1]+" == 0xff800000 || "+operands[1]+" == 0x7f800000)) {");context.code.push(" fequal = ("+operands[0]+" == "+operands[1]+");");context.code.push("} else {");if(quot_isconstant(operands[2])){val=Number(operands[2]);valf2=""+decode_float(val&0x7fffffff);} +else{context.code.push(operands[1]+"encode_float("+sign0+"));");}},0x191:function(context,operands){context.varsused["valf"]=true;context.varsused["res"]=true;context.code.push("valf = "+oputil_decode_float(context,operands[0])+";");context.code.push("if (!("+operands[0]+" & 0x80000000)) {");context.code.push(" if (isNaN(valf) || !isFinite(valf) || (valf > 0x7fffffff))");context.code.push(" res = 0x7fffffff;");context.code.push(" else");context.code.push(" res = Math.floor(valf);");context.code.push("} else {");context.code.push(" if (isNaN(valf) || !isFinite(valf) || (valf < -0x80000000))");context.code.push(" res = -0x80000000;");context.code.push(" else");context.code.push(" res = Math.ceil(valf);");context.code.push("}");context.code.push(operands[1]+"res>>>0);");},0x192:function(context,operands){context.varsused["valf"]=true;context.varsused["res"]=true;context.code.push("valf = "+oputil_decode_float(context,operands[0])+";");context.code.push("if (!("+operands[0]+" & 0x80000000)) {");context.code.push(" if (isNaN(valf) || !isFinite(valf))");context.code.push(" res = 0x7fffffff;");context.code.push(" else");context.code.push(" res = Math.round(valf);");context.code.push(" if (res > 0x7fffffff) res = 0x7fffffff;");context.code.push("} else {");context.code.push(" if (isNaN(valf) || !isFinite(valf))");context.code.push(" res = -0x80000000;");context.code.push(" else");context.code.push(" res = Math.round(valf);");context.code.push(" if (res < -0x80000000) res = -0x80000000;");context.code.push("}");context.code.push(operands[1]+"res>>>0);");},0x198:function(context,operands){var valf=oputil_decode_float(context,operands[0]);context.code.push(operands[1]+"encode_float(Math.ceil("+valf+")));");},0x199:function(context,operands){var valf=oputil_decode_float(context,operands[0]);context.code.push(operands[1]+"encode_float(Math.floor("+valf+")));");},0x1A0:function(context,operands){var valf0=oputil_decode_float(context,operands[0]);var valf1=oputil_decode_float(context,operands[1]);context.code.push(operands[2]+"encode_float("+valf0+" + "+valf1+"));");},0x1A1:function(context,operands){var valf0=oputil_decode_float(context,operands[0]);var valf1=oputil_decode_float(context,operands[1]);context.code.push(operands[2]+"encode_float("+valf0+" - "+valf1+"));");},0x1A2:function(context,operands){var valf0=oputil_decode_float(context,operands[0]);var valf1=oputil_decode_float(context,operands[1]);context.code.push(operands[2]+"encode_float("+valf0+" * "+valf1+"));");},0x1A3:function(context,operands){var valf0=oputil_decode_float(context,operands[0]);var valf1=oputil_decode_float(context,operands[1]);context.code.push(operands[2]+"encode_float("+valf0+" / "+valf1+"));");},0x1A4:function(context,operands){var valf0=oputil_decode_float(context,operands[0],true);var valf1=oputil_decode_float(context,operands[1],true);context.varsused["modv"]=true;context.varsused["quov"]=true;context.code.push("modv=("+valf0+" % "+valf1+");");context.code.push("quov=encode_float(("+valf0+" - modv) / "+valf1+");");context.code.push("if (quov === 0x0 || quov === 0x80000000) {");context.code.push(" quov = (("+operands[0]+" ^ "+operands[1]+") & 0x80000000) >>>0;");context.code.push("}");context.code.push(operands[2]+"encode_float(modv));");context.code.push(operands[3]+"quov);");},0x1A8:function(context,operands){var valf=oputil_decode_float(context,operands[0]);context.code.push(operands[1]+"encode_float(Math.sqrt("+valf+")));");},0x1A9:function(context,operands){var valf=oputil_decode_float(context,operands[0]);context.code.push(operands[1]+"encode_float(Math.exp("+valf+")));");},0x1AA:function(context,operands){var valf=oputil_decode_float(context,operands[0]);context.code.push(operands[1]+"encode_float(Math.log("+valf+")));");},0x1AB:function(context,operands){context.varsused["valf"]=true;var valf0=oputil_decode_float(context,operands[0],true);var valf1=oputil_decode_float(context,operands[1],true);context.code.push("if ("+operands[0]+" === 0x3f800000) {");context.code.push(" valf = 0x3f800000;");context.code.push("} else if ("+operands[0]+" === 0xbf800000 && ("+operands[1]+" === 0xff800000 || "+operands[1]+" === 0x7f800000)) {");context.code.push(" valf = 0x3f800000;");context.code.push("} else {");context.code.push(" valf=encode_float(Math.pow("+valf0+", "+valf1+"));");context.code.push("}");context.code.push(operands[2]+"valf);");},0x1B0:function(context,operands){var valf=oputil_decode_float(context,operands[0]);context.code.push(operands[1]+"encode_float(Math.sin("+valf+")));");},0x1B1:function(context,operands){var valf=oputil_decode_float(context,operands[0]);context.code.push(operands[1]+"encode_float(Math.cos("+valf+")));");},0x1B2:function(context,operands){var valf=oputil_decode_float(context,operands[0]);context.code.push(operands[1]+"encode_float(Math.tan("+valf+")));");},0x1B3:function(context,operands){var valf=oputil_decode_float(context,operands[0]);context.code.push(operands[1]+"encode_float(Math.asin("+valf+")));");},0x1B4:function(context,operands){var valf=oputil_decode_float(context,operands[0]);context.code.push(operands[1]+"encode_float(Math.acos("+valf+")));");},0x1B5:function(context,operands){var valf=oputil_decode_float(context,operands[0]);context.code.push(operands[1]+"encode_float(Math.atan("+valf+")));");},0x1B6:function(context,operands){var valf0=oputil_decode_float(context,operands[0]);var valf1=oputil_decode_float(context,operands[1]);context.code.push(operands[2]+"encode_float(Math.atan2("+valf0+", "+valf1+")));");},0x1C0:function(context,operands){var val,valf0,valf1,valf2;context.varsused["fequal"]=true;context.varsused["fdiff"]=true;context.code.push("if (("+operands[2]+" & 0x7f800000) === 0x7f800000 && ("+operands[2]+" & 0x007fffff) !== 0) {");context.code.push(" fequal = 0;");context.code.push("} else if (("+operands[0]+" === 0xff800000 || "+operands[0]+" === 0x7f800000) && ("+operands[1]+" === 0xff800000 || "+operands[1]+" === 0x7f800000)) {");context.code.push(" fequal = ("+operands[0]+" === "+operands[1]+");");context.code.push("} else {");if(quot_isconstant(operands[2])){val=Number(operands[2]);valf2=""+decode_float(val&0x7fffffff);} else{val="decode_float(("+operands[2]+") & 0x7fffffff)";valf2=alloc_holdvar(context);context.code.push(valf2+"="+val+";");} -valf0=oputil_decode_float(context,operands[0]);valf1=oputil_decode_float(context,operands[1]);context.code.push(" fdiff = "+valf1+" - "+valf0+";");context.code.push(" fequal = (fdiff <= "+valf2+" && fdiff >= -("+valf2+"));");context.code.push("}");context.code.push("if (fequal) {");oputil_perform_jump(context,operands[3]);context.code.push("}");},0x1C1:function(context,operands){var val,valf0,valf1,valf2;context.varsused["fequal"]=true;context.varsused["fdiff"]=true;context.code.push("if (("+operands[2]+" & 0x7f800000) == 0x7f800000 && ("+operands[2]+" & 0x007fffff) != 0) {");context.code.push(" fequal = 0;");context.code.push("} else if (("+operands[0]+" == 0xff800000 || "+operands[0]+" == 0x7f800000) && ("+operands[1]+" == 0xff800000 || "+operands[1]+" == 0x7f800000)) {");context.code.push(" fequal = ("+operands[0]+" == "+operands[1]+");");context.code.push("} else {");if(quot_isconstant(operands[2])){val=Number(operands[2]);valf2=""+decode_float(val&0x7fffffff);} +valf0=oputil_decode_float(context,operands[0]);valf1=oputil_decode_float(context,operands[1]);context.code.push(" fdiff = "+valf1+" - "+valf0+";");context.code.push(" fequal = (fdiff <= "+valf2+" && fdiff >= -("+valf2+"));");context.code.push("}");context.code.push("if (fequal) {");oputil_perform_jump(context,operands[3]);context.code.push("}");},0x1C1:function(context,operands){var val,valf0,valf1,valf2;context.varsused["fequal"]=true;context.varsused["fdiff"]=true;context.code.push("if (("+operands[2]+" & 0x7f800000) === 0x7f800000 && ("+operands[2]+" & 0x007fffff) !== 0) {");context.code.push(" fequal = 0;");context.code.push("} else if (("+operands[0]+" === 0xff800000 || "+operands[0]+" === 0x7f800000) && ("+operands[1]+" === 0xff800000 || "+operands[1]+" === 0x7f800000)) {");context.code.push(" fequal = ("+operands[0]+" === "+operands[1]+");");context.code.push("} else {");if(quot_isconstant(operands[2])){val=Number(operands[2]);valf2=""+decode_float(val&0x7fffffff);} else{val="decode_float(("+operands[2]+") & 0x7fffffff)";valf2=alloc_holdvar(context);context.code.push(valf2+"="+val+";");} -valf0=oputil_decode_float(context,operands[0]);valf1=oputil_decode_float(context,operands[1]);context.code.push(" fdiff = "+valf1+" - "+valf0+";");context.code.push(" fequal = (fdiff <= "+valf2+" && fdiff >= -("+valf2+"));");context.code.push("}");context.code.push("if (!fequal) {");oputil_perform_jump(context,operands[3]);context.code.push("}");},0x1C2:function(context,operands){valf0=oputil_decode_float(context,operands[0]);valf1=oputil_decode_float(context,operands[1]);context.code.push("if ("+valf0+" < "+valf1+") {");oputil_perform_jump(context,operands[2]);context.code.push("}");},0x1C3:function(context,operands){valf0=oputil_decode_float(context,operands[0]);valf1=oputil_decode_float(context,operands[1]);context.code.push("if ("+valf0+" <= "+valf1+") {");oputil_perform_jump(context,operands[2]);context.code.push("}");},0x1C4:function(context,operands){valf0=oputil_decode_float(context,operands[0]);valf1=oputil_decode_float(context,operands[1]);context.code.push("if ("+valf0+" > "+valf1+") {");oputil_perform_jump(context,operands[2]);context.code.push("}");},0x1C5:function(context,operands){valf0=oputil_decode_float(context,operands[0]);valf1=oputil_decode_float(context,operands[1]);context.code.push("if ("+valf0+" >= "+valf1+") {");oputil_perform_jump(context,operands[2]);context.code.push("}");},0x1C8:function(context,operands){context.code.push("if (("+operands[0]+" & 0x7f800000) == 0x7f800000 && ("+operands[0]+" & 0x007fffff) != 0) {");oputil_perform_jump(context,operands[1]);context.code.push("}");},0x1C9:function(context,operands){context.code.push("if ("+operands[0]+" == 0xff800000 || "+operands[0]+" == 0x7f800000) {");oputil_perform_jump(context,operands[1]);context.code.push("}");},0x130:function(context,operands){var mayblock;if(quot_isconstant(operands[0])) +valf0=oputil_decode_float(context,operands[0]);valf1=oputil_decode_float(context,operands[1]);context.code.push(" fdiff = "+valf1+" - "+valf0+";");context.code.push(" fequal = (fdiff <= "+valf2+" && fdiff >= -("+valf2+"));");context.code.push("}");context.code.push("if (!fequal) {");oputil_perform_jump(context,operands[3]);context.code.push("}");},0x1C2:function(context,operands){valf0=oputil_decode_float(context,operands[0]);valf1=oputil_decode_float(context,operands[1]);context.code.push("if ("+valf0+" < "+valf1+") {");oputil_perform_jump(context,operands[2]);context.code.push("}");},0x1C3:function(context,operands){valf0=oputil_decode_float(context,operands[0]);valf1=oputil_decode_float(context,operands[1]);context.code.push("if ("+valf0+" <= "+valf1+") {");oputil_perform_jump(context,operands[2]);context.code.push("}");},0x1C4:function(context,operands){valf0=oputil_decode_float(context,operands[0]);valf1=oputil_decode_float(context,operands[1]);context.code.push("if ("+valf0+" > "+valf1+") {");oputil_perform_jump(context,operands[2]);context.code.push("}");},0x1C5:function(context,operands){valf0=oputil_decode_float(context,operands[0]);valf1=oputil_decode_float(context,operands[1]);context.code.push("if ("+valf0+" >= "+valf1+") {");oputil_perform_jump(context,operands[2]);context.code.push("}");},0x1C8:function(context,operands){context.code.push("if (("+operands[0]+" & 0x7f800000) === 0x7f800000 && ("+operands[0]+" & 0x007fffff) !== 0) {");oputil_perform_jump(context,operands[1]);context.code.push("}");},0x1C9:function(context,operands){context.code.push("if ("+operands[0]+" === 0xff800000 || "+operands[0]+" === 0x7f800000) {");oputil_perform_jump(context,operands[1]);context.code.push("}");},0x130:function(context,operands){var mayblock;if(quot_isconstant(operands[0])) mayblock=Glk.call_may_not_return(Number(operands[0]));else mayblock=true;context.code.push("tempglkargs.length = "+operands[1]+";");if(quot_isconstant(operands[1])){var ix;var argc=Number(operands[1]);for(ix=0;ix>1);for(ix=0;ix>1);for(ix=0;ix>4)&0x0F);modeaddr++;} -var optype=oplist.formlist[ix];if(optype=="L"){switch(mode){case 8:if(context.offstack.length){operands[ix]=pop_offstack_holdvar(context);} +var optype=oplist.formlist[ix];if(optype==="L"){switch(mode){case 8:if(context.offstack.length){operands[ix]=pop_offstack_holdvar(context);} else{holdvar=alloc_holdvar(context);context.code.push(holdvar+"=frame.valstack.pop();");operands[ix]=holdvar;} continue;case 0:operands[ix]="0";continue;case 1:value=QuoteMem1(cp);cp++;operands[ix]=value;continue;case 2:value=QuoteMem2(cp);cp+=2;operands[ix]=value;continue;case 3:value=QuoteMem4(cp);cp+=4;operands[ix]=value;continue;} -if(mode>=9&&mode<=11){if(mode==9){addr=Mem1(cp);cp++;} -else if(mode==10){addr=Mem2(cp);cp+=2;} -else if(mode==11){addr=Mem4(cp);cp+=4;} +if(mode>=9&&mode<=11){if(mode===9){addr=Mem1(cp);cp++;} +else if(mode===10){addr=Mem2(cp);cp+=2;} +else if(mode===11){addr=Mem4(cp);cp+=4;} if(context.offloc[addr]!==undefined){operands[ix]=context.offloc[addr];continue;} -if(oplist.argsize==4){value="frame.locals["+addr+"]";} -else if(oplist.argsize==2){value="frame.locals["+addr+"] & 0xffff";} +if(oplist.argsize===4){value="frame.locals["+addr+"]";} +else if(oplist.argsize===2){value="frame.locals["+addr+"] & 0xffff";} else{value="frame.locals["+addr+"] & 0xff";} holdvar=alloc_holdvar(context,true);context.code.push(holdvar+"=("+value+");");context.offloc[addr]=holdvar;context.offlocdirty[addr]=false;operands[ix]=holdvar;continue;} switch(mode){case 15:addr=Mem4(cp)+ramstart;cp+=4;break;case 14:addr=Mem2(cp)+ramstart;cp+=2;break;case 13:addr=Mem1(cp)+ramstart;cp++;break;case 7:addr=Mem4(cp);cp+=4;break;case 6:addr=Mem2(cp);cp+=2;break;case 5:addr=Mem1(cp);cp++;break;default:fatal_error("Unknown addressing mode in load operand.");} -if(oplist.argsize==4){value="Mem4("+addr+")";} -else if(oplist.argsize==2){value="Mem2("+addr+")";} +if(oplist.argsize===4){value="Mem4("+addr+")";} +else if(oplist.argsize===2){value="Mem2("+addr+")";} else{value="Mem1("+addr+")";} holdvar=alloc_holdvar(context);context.code.push(holdvar+"=("+value+");");operands[ix]=holdvar;continue;} -else if(optype=="E"){switch(mode){case 8:if(context.offstack.length){operands[ix]=pop_offstack_holdvar(context);} +else if(optype==="E"){switch(mode){case 8:if(context.offstack.length){operands[ix]=pop_offstack_holdvar(context);} else{operands[ix]="frame.valstack.pop()";} continue;case 0:operands[ix]="0";continue;case 1:value=QuoteMem1(cp);cp++;operands[ix]=value;continue;case 2:value=QuoteMem2(cp);cp+=2;operands[ix]=value;continue;case 3:value=QuoteMem4(cp);cp+=4;operands[ix]=value;continue;} -if(mode>=9&&mode<=11){if(mode==9){addr=Mem1(cp);cp++;} -else if(mode==10){addr=Mem2(cp);cp+=2;} -else if(mode==11){addr=Mem4(cp);cp+=4;} +if(mode>=9&&mode<=11){if(mode===9){addr=Mem1(cp);cp++;} +else if(mode===10){addr=Mem2(cp);cp+=2;} +else if(mode===11){addr=Mem4(cp);cp+=4;} if(context.offloc[addr]!==undefined){operands[ix]=context.offloc[addr];continue;} -if(oplist.argsize==4){value="frame.locals["+addr+"]";} -else if(oplist.argsize==2){value="frame.locals["+addr+"] & 0xffff";} +if(oplist.argsize===4){value="frame.locals["+addr+"]";} +else if(oplist.argsize===2){value="frame.locals["+addr+"] & 0xffff";} else{value="frame.locals["+addr+"] & 0xff";} holdvar=alloc_holdvar(context,true);context.code.push(holdvar+"=("+value+");");context.offloc[addr]=holdvar;context.offlocdirty[addr]=false;operands[ix]=holdvar;continue;} switch(mode){case 15:addr=Mem4(cp)+ramstart;cp+=4;break;case 14:addr=Mem2(cp)+ramstart;cp+=2;break;case 13:addr=Mem1(cp)+ramstart;cp++;break;case 7:addr=Mem4(cp);cp+=4;break;case 6:addr=Mem2(cp);cp+=2;break;case 5:addr=Mem1(cp);cp++;break;default:fatal_error("Unknown addressing mode in load operand.");} -if(oplist.argsize==4){value="Mem4("+addr+")";} -else if(oplist.argsize==2){value="Mem2("+addr+")";} +if(oplist.argsize===4){value="Mem4("+addr+")";} +else if(oplist.argsize===2){value="Mem2("+addr+")";} else{value="Mem1("+addr+")";} operands[ix]=value;continue;} -else if(optype=="S"){switch(mode){case 8:holdvar=alloc_holdvar(context,true);context.offstack.push(holdvar);operands[ix]=holdvar+"=(";continue;case 0:operands[ix]="(";continue;} -if(mode>=9&&mode<=11){if(mode==9){addr=Mem1(cp);cp++;} -else if(mode==10){addr=Mem2(cp);cp+=2;} -else if(mode==11){addr=Mem4(cp);cp+=4;} -if(oplist.argsize==4){holdvar=alloc_holdvar(context,true);store_offloc_value(context,addr,holdvar,false);operands[ix]=holdvar+"=(";} -else if(oplist.argsize==2){store_offloc_value(context,addr,undefined);operands[ix]="frame.locals["+addr+"]=(0xffff &";} +else if(optype==="S"){switch(mode){case 8:holdvar=alloc_holdvar(context,true);context.offstack.push(holdvar);operands[ix]=holdvar+"=(";continue;case 0:operands[ix]="(";continue;} +if(mode>=9&&mode<=11){if(mode===9){addr=Mem1(cp);cp++;} +else if(mode===10){addr=Mem2(cp);cp+=2;} +else if(mode===11){addr=Mem4(cp);cp+=4;} +if(oplist.argsize===4){holdvar=alloc_holdvar(context,true);store_offloc_value(context,addr,holdvar,false);operands[ix]=holdvar+"=(";} +else if(oplist.argsize===2){store_offloc_value(context,addr,undefined);operands[ix]="frame.locals["+addr+"]=(0xffff &";} else{store_offloc_value(context,addr,undefined);operands[ix]="frame.locals["+addr+"]=(0xff &";} continue;} switch(mode){case 15:addr=Mem4(cp)+ramstart;cp+=4;break;case 14:addr=Mem2(cp)+ramstart;cp+=2;break;case 13:addr=Mem1(cp)+ramstart;cp++;break;case 7:addr=Mem4(cp);cp+=4;break;case 6:addr=Mem2(cp);cp+=2;break;case 5:addr=Mem1(cp);cp++;break;default:fatal_error("Unknown addressing mode in store operand.");} -if(oplist.argsize==4){value="MemW4("+addr+",";} -else if(oplist.argsize==2){value="MemW2("+addr+",";} +if(oplist.argsize===4){value="MemW4("+addr+",";} +else if(oplist.argsize===2){value="MemW2("+addr+",";} else{value="MemW1("+addr+",";} operands[ix]=value;continue;} -else if(optype=="F"){var funcop=operands.func_store;switch(mode){case 8:funcop.mode=8;funcop.argsize=oplist.argsize;operands[ix]=funcop;continue;case 0:funcop.mode=0;funcop.argsize=oplist.argsize;operands[ix]=funcop;continue;} -if(mode>=9&&mode<=11){if(mode==9){addr=Mem1(cp);cp++;} -else if(mode==10){addr=Mem2(cp);cp+=2;} -else if(mode==11){addr=Mem4(cp);cp+=4;} +else if(optype==="F"){var funcop=operands.func_store;switch(mode){case 8:funcop.mode=8;funcop.argsize=oplist.argsize;operands[ix]=funcop;continue;case 0:funcop.mode=0;funcop.argsize=oplist.argsize;operands[ix]=funcop;continue;} +if(mode>=9&&mode<=11){if(mode===9){addr=Mem1(cp);cp++;} +else if(mode===10){addr=Mem2(cp);cp+=2;} +else if(mode===11){addr=Mem4(cp);cp+=4;} funcop.mode=11;funcop.addr=addr;funcop.argsize=oplist.argsize;operands[ix]=funcop;continue;} switch(mode){case 15:addr=Mem4(cp)+ramstart;cp+=4;break;case 14:addr=Mem2(cp)+ramstart;cp+=2;break;case 13:addr=Mem1(cp)+ramstart;cp++;break;case 7:addr=Mem4(cp);cp+=4;break;case 6:addr=Mem2(cp);cp+=2;break;case 5:addr=Mem1(cp);cp++;break;default:fatal_error("Unknown addressing mode in store operand.");} funcop.mode=15;funcop.addr=addr;funcop.argsize=oplist.argsize;operands[ix]=funcop;continue;} -else if(optype=="C"){switch(mode){case 8:operands[ix]="3,0";continue;case 0:operands[ix]="0,0";continue;} -if(mode>=9&&mode<=11){if(mode==9){addr=Mem1(cp);cp++;} -else if(mode==10){addr=Mem2(cp);cp+=2;} -else if(mode==11){addr=Mem4(cp);cp+=4;} +else if(optype==="C"){switch(mode){case 8:operands[ix]="3,0";continue;case 0:operands[ix]="0,0";continue;} +if(mode>=9&&mode<=11){if(mode===9){addr=Mem1(cp);cp++;} +else if(mode===10){addr=Mem2(cp);cp+=2;} +else if(mode===11){addr=Mem4(cp);cp+=4;} operands[ix]="2,"+addr;continue;} switch(mode){case 15:addr=Mem4(cp)+ramstart;cp+=4;break;case 14:addr=Mem2(cp)+ramstart;cp+=2;break;case 13:addr=Mem1(cp)+ramstart;cp++;break;case 7:addr=Mem4(cp);cp+=4;break;case 6:addr=Mem2(cp);cp+=2;break;case 5:addr=Mem1(cp);cp++;break;default:fatal_error("Unknown addressing mode in store operand.");} operands[ix]="1,"+addr;continue;} else{fatal_error("Unknown operand type.",optype);}} return cp;} -function compile_func(funcaddr){var addr=funcaddr;var functype=Mem1(addr);if(functype!=0xC0&&functype!=0xC1){if(functype>=0xC0&&functype<=0xDF) +function compile_func(funcaddr){var addr=funcaddr;var functype=Mem1(addr);if(functype!==0xC0&&functype!==0xC1){if(functype>=0xC0&&functype<=0xDF) fatal_error("Call to unknown type of function.",addr);else fatal_error("Call to non-function.",addr);} -addr++;var localsformat=[];var rawstart=addr;var ix=0;while(1){var loctype=Mem1(addr);addr++;var locnum=Mem1(addr);addr++;if(loctype==0){break;} -if(loctype!=1&&loctype!=2&&loctype!=4){fatal_error("Invalid local variable size in function header.",loctype);} +addr++;var localsformat=[];var rawstart=addr;var ix=0;while(1){var loctype=Mem1(addr);addr++;var locnum=Mem1(addr);addr++;if(loctype===0){break;} +if(loctype!==1&&loctype!==2&&loctype!==4){fatal_error("Invalid local variable size in function header.",loctype);} localsformat.push({size:loctype,count:locnum});} var rawformat=memmap.slice(rawstart,addr);while(rawformat.length%4) rawformat.push(0);return new VMFunc(funcaddr,addr,localsformat,rawformat);} @@ -389,37 +389,37 @@ return make_code(context.code.join("\n"));} function enter_function(addr,argcount){var ix;total_function_calls++;var accelfunc=accel_address_map[addr];if(accelfunc!==undefined){accel_function_calls++;var val=accelfunc(argcount,tempcallargs);pop_callstub(val);return;} var vmfunc=vmfunc_table[addr];if(vmfunc===undefined){vmfunc=compile_func(addr);if(addr=0;ix--) +newframe.framestart=frame.framestart+frame.framelen+4*frame.valstack.length;stack.push(newframe);frame=newframe;if(vmfunc.functype===0xC0){for(ix=argcount-1;ix>=0;ix--) frame.valstack.push(tempcallargs[ix]);frame.valstack.push(argcount);} else{for(ix=0;ixval) -stack.pop();if(stack.length==0) +stack.pop();if(stack.length===0) fatal_error("Stack evaporated during throw.");frame=stack[stack.length-1];val-=(frame.framestart+frame.framelen);if(val<0) fatal_error("Attempted to throw below the frame value stack.");if(val&3) fatal_error("Attempted to throw to an unaligned address.");val>>>=2;if(val>frame.valstack.length) fatal_error("Attempted to throw beyond the frame value stack.");frame.valstack.length=val;} function pop_callstub(val){var destaddr,desttype;if(isNaN(val)) -fatal_error("Function returned undefined value.");var framestart=frame.valstack.pop();if(framestart!=frame.framestart) +fatal_error("Function returned undefined value.");var framestart=frame.valstack.pop();if(framestart!==frame.framestart) fatal_error("Call stub frameptr ("+framestart+") "+"does not match frame ("+frame.framestart+")");pc=frame.valstack.pop();destaddr=frame.valstack.pop();desttype=frame.valstack.pop();switch(desttype){case 0:return;case 1:MemW4(destaddr,val);return;case 2:frame.locals[destaddr]=val;return;case 3:frame.valstack.push(val);return;case 0x11:fatal_error("String-terminator call stub at end of function call.");return;case 0x10:stream_string(0,pc,0xE1,destaddr);return;case 0x12:stream_num(0,pc,true,destaddr);return;case 0x13:stream_string(0,pc,0xE0,destaddr);return;case 0x14:stream_string(0,pc,0xE2,destaddr);return;default:fatal_error("Unrecognized desttype in callstub.",desttype);}} function store_operand(desttype,destaddr,val){switch(desttype){case 0:return;case 1:MemW4(destaddr,val);return;case 2:frame.locals[destaddr]=val;return;case 3:frame.valstack.push(val);return;default:fatal_error("Unrecognized desttype in callstub.",desttype);}} function store_operand_by_funcop(funcop,val){if(!funcop) -return;switch(funcop.mode){case 8:frame.valstack.push(val);return;case 0:return;case 11:if(funcop.argsize==4){frame.locals[funcop.addr]=(val);} -else if(funcop.argsize==2){frame.locals[funcop.addr]=(0xffff&val);} +return;switch(funcop.mode){case 8:frame.valstack.push(val);return;case 0:return;case 11:if(funcop.argsize===4){frame.locals[funcop.addr]=(val);} +else if(funcop.argsize===2){frame.locals[funcop.addr]=(0xffff&val);} else{frame.locals[funcop.addr]=(0xff&val);} -return;case 15:if(funcop.argsize==4){MemW4(funcop.addr,val);} -else if(funcop.argsize==2){MemW2(funcop.addr,val);} +return;case 15:if(funcop.argsize===4){MemW4(funcop.addr,val);} +else if(funcop.argsize===2){MemW2(funcop.addr,val);} else{MemW1(funcop.addr,val);} return;default:fatal_error("Unknown addressing mode in store func by operand.");}} -function set_random(val){if(val==0){random_func=Math.random;} +function set_random(val){if(val===0){random_func=Math.random;} else{srand_set_seed(val);random_func=srand_get_random;}} var srand_table=undefined;var srand_index1,srand_index2;function srand_set_seed(seed){var i,ii,k,val,loop;if(srand_table===undefined) srand_table=Array(55);srand_table[54]=seed;srand_index1=0;srand_index2=31;k=1;for(i=0;i<55;i++){ii=(21*i)%55;srand_table[ii]=k;k=(seed-k)>>>0;seed=srand_table[ii];} @@ -431,96 +431,96 @@ return 0;if(addr>=endmem) return 0;var tb=Mem1(addr);if(tb>=0xE0){return 3;} if(tb>=0xC0){return 2;} if(tb>=0x70&&tb<=0x7F&&addr>=ramstart){return 1;} -return 0;},2:function func_2_cp__tab(argc,argv){var obj=((argc>0)?argv[0]:0);var id=((argc>1)?argv[1]:0);if(accel_func_map[1](argc,argv)!=1){Glk.glk_put_jstring("\n[** Programming error: tried to find the \".\" of (something) **]\n");return 0;} +return 0;},2:function func_2_cp__tab(argc,argv){var obj=((argc>0)?argv[0]:0);var id=((argc>1)?argv[1]:0);if(accel_func_map[1](argc,argv)!==1){Glk.glk_put_jstring("\n[** Programming error: tried to find the \".\" of (something) **]\n");return 0;} var otab=Mem4(obj+16);if(!otab) -return 0;var max=Mem4(otab);otab+=4;return binary_search(id,2,otab,10,max,0,0);},3:function func_3_ra__pr(argc,argv){var obj=((argc>0)?argv[0]:0);var id=((argc>1)?argv[1]:0);var prop=accel_helper_get_prop(obj,id);if(prop==0) -return 0;return Mem4(prop+4);},4:function func_4_rl__pr(argc,argv){var obj=((argc>0)?argv[0]:0);var id=((argc>1)?argv[1]:0);var prop=accel_helper_get_prop(obj,id);if(prop==0) -return 0;return 4*Mem2(prop+2);},5:function func_5_oc__cl(argc,argv){var zr,prop,inlist,inlistlen,jx;var obj=((argc>0)?argv[0]:0);var cla=((argc>1)?argv[1]:0);zr=accel_func_map[1](argc,argv);if(zr==3) -return(cla==accel_params[5])?1:0;if(zr==2) -return(cla==accel_params[4])?1:0;if(zr!=1) -return 0;if(cla==accel_params[2]){if(accel_helper_obj_in_class(obj)) -return 1;if(obj==accel_params[2]) -return 1;if(obj==accel_params[5]) -return 1;if(obj==accel_params[4]) -return 1;if(obj==accel_params[3]) +return 0;var max=Mem4(otab);otab+=4;return binary_search(id,2,otab,10,max,0,0);},3:function func_3_ra__pr(argc,argv){var obj=((argc>0)?argv[0]:0);var id=((argc>1)?argv[1]:0);var prop=accel_helper_get_prop(obj,id);if(prop===0) +return 0;return Mem4(prop+4);},4:function func_4_rl__pr(argc,argv){var obj=((argc>0)?argv[0]:0);var id=((argc>1)?argv[1]:0);var prop=accel_helper_get_prop(obj,id);if(prop===0) +return 0;return 4*Mem2(prop+2);},5:function func_5_oc__cl(argc,argv){var zr,prop,inlist,inlistlen,jx;var obj=((argc>0)?argv[0]:0);var cla=((argc>1)?argv[1]:0);zr=accel_func_map[1](argc,argv);if(zr===3) +return(cla===accel_params[5])?1:0;if(zr===2) +return(cla===accel_params[4])?1:0;if(zr!==1) +return 0;if(cla===accel_params[2]){if(accel_helper_obj_in_class(obj)) +return 1;if(obj===accel_params[2]) +return 1;if(obj===accel_params[5]) +return 1;if(obj===accel_params[4]) +return 1;if(obj===accel_params[3]) return 1;return 0;} -if(cla==accel_params[3]){if(accel_helper_obj_in_class(obj)) -return 0;if(obj==accel_params[2]) -return 0;if(obj==accel_params[5]) -return 0;if(obj==accel_params[4]) -return 0;if(obj==accel_params[3]) +if(cla===accel_params[3]){if(accel_helper_obj_in_class(obj)) +return 0;if(obj===accel_params[2]) +return 0;if(obj===accel_params[5]) +return 0;if(obj===accel_params[4]) +return 0;if(obj===accel_params[3]) return 0;return 1;} -if((cla==accel_params[5])||(cla==accel_params[4])) +if((cla===accel_params[5])||(cla===accel_params[4])) return 0;if(!accel_helper_obj_in_class(cla)){Glk.glk_put_jstring("\n[** Programming error: tried to apply 'ofclass' with non-class **]\n");return 0;} -prop=accel_helper_get_prop(obj,2);if(prop==0) -return 0;inlist=Mem4(prop+4);if(inlist==0) -return 0;inlistlen=Mem2(prop+2);for(jx=0;jx1)?argv[1]:0);var addr;addr=accel_func_map[3](argc,argv);if(addr==0){if((id>0)&&(id1)?argv[1]:0);var addr;addr=accel_func_map[3](argc,argv);if(addr===0){if((id>0)&&(id0)?argv[0]:0);var id=((argc>1)?argv[1]:0);var indiv_prop_start=accel_params[1];var zr=accel_func_map[1](argc,argv);if(zr==3){if(id==indiv_prop_start+6) -return 1;if(id==indiv_prop_start+7) +return Mem4(addr);},7:function func_7_op__pr(argc,argv){var obj=((argc>0)?argv[0]:0);var id=((argc>1)?argv[1]:0);var indiv_prop_start=accel_params[1];var zr=accel_func_map[1](argc,argv);if(zr===3){if(id===indiv_prop_start+6) +return 1;if(id===indiv_prop_start+7) return 1;return 0;} -if(zr==2){return((id==indiv_prop_start+5)?1:0);} -if(zr!=1) +if(zr===2){return((id===indiv_prop_start+5)?1:0);} +if(zr!==1) return 0;if((id>=indiv_prop_start)&&(id0)?argv[0]:0);var id=((argc>1)?argv[1]:0);if(accel_func_map[1](argc,argv)!=1){Glk.glk_put_jstring("\n[** Programming error: tried to find the \".\" of (something) **]\n");return 0;} +return((accel_func_map[3](argc,argv))?1:0);},8:function func_8_cp__tab(argc,argv){var obj=((argc>0)?argv[0]:0);var id=((argc>1)?argv[1]:0);if(accel_func_map[1](argc,argv)!==1){Glk.glk_put_jstring("\n[** Programming error: tried to find the \".\" of (something) **]\n");return 0;} var otab=Mem4(obj+4*(3+(accel_params[7]>>2)));if(!otab) -return 0;var max=Mem4(otab);otab+=4;return binary_search(id,2,otab,10,max,0,0);},9:function func_9_ra__pr(argc,argv){var obj=((argc>0)?argv[0]:0);var id=((argc>1)?argv[1]:0);var prop=accel_helper_get_prop_new(obj,id);if(prop==0) -return 0;return Mem4(prop+4);},10:function func_10_rl__pr(argc,argv){var obj=((argc>0)?argv[0]:0);var id=((argc>1)?argv[1]:0);var prop=accel_helper_get_prop_new(obj,id);if(prop==0) -return 0;return 4*Mem2(prop+2);},11:function func_11_oc__cl(argc,argv){var zr,prop,inlist,inlistlen,jx;var obj=((argc>0)?argv[0]:0);var cla=((argc>1)?argv[1]:0);zr=accel_func_map[1](argc,argv);if(zr==3) -return(cla==accel_params[5])?1:0;if(zr==2) -return(cla==accel_params[4])?1:0;if(zr!=1) -return 0;if(cla==accel_params[2]){if(accel_helper_obj_in_class(obj)) -return 1;if(obj==accel_params[2]) -return 1;if(obj==accel_params[5]) -return 1;if(obj==accel_params[4]) -return 1;if(obj==accel_params[3]) +return 0;var max=Mem4(otab);otab+=4;return binary_search(id,2,otab,10,max,0,0);},9:function func_9_ra__pr(argc,argv){var obj=((argc>0)?argv[0]:0);var id=((argc>1)?argv[1]:0);var prop=accel_helper_get_prop_new(obj,id);if(prop===0) +return 0;return Mem4(prop+4);},10:function func_10_rl__pr(argc,argv){var obj=((argc>0)?argv[0]:0);var id=((argc>1)?argv[1]:0);var prop=accel_helper_get_prop_new(obj,id);if(prop===0) +return 0;return 4*Mem2(prop+2);},11:function func_11_oc__cl(argc,argv){var zr,prop,inlist,inlistlen,jx;var obj=((argc>0)?argv[0]:0);var cla=((argc>1)?argv[1]:0);zr=accel_func_map[1](argc,argv);if(zr===3) +return(cla===accel_params[5])?1:0;if(zr===2) +return(cla===accel_params[4])?1:0;if(zr!==1) +return 0;if(cla===accel_params[2]){if(accel_helper_obj_in_class(obj)) +return 1;if(obj===accel_params[2]) +return 1;if(obj===accel_params[5]) +return 1;if(obj===accel_params[4]) +return 1;if(obj===accel_params[3]) return 1;return 0;} -if(cla==accel_params[3]){if(accel_helper_obj_in_class(obj)) -return 0;if(obj==accel_params[2]) -return 0;if(obj==accel_params[5]) -return 0;if(obj==accel_params[4]) -return 0;if(obj==accel_params[3]) +if(cla===accel_params[3]){if(accel_helper_obj_in_class(obj)) +return 0;if(obj===accel_params[2]) +return 0;if(obj===accel_params[5]) +return 0;if(obj===accel_params[4]) +return 0;if(obj===accel_params[3]) return 0;return 1;} -if((cla==accel_params[5])||(cla==accel_params[4])) +if((cla===accel_params[5])||(cla===accel_params[4])) return 0;if(!accel_helper_obj_in_class(cla)){Glk.glk_put_jstring("\n[** Programming error: tried to apply 'ofclass' with non-class **]\n");return 0;} -prop=accel_helper_get_prop_new(obj,2);if(prop==0) -return 0;inlist=Mem4(prop+4);if(inlist==0) -return 0;inlistlen=Mem2(prop+2);for(jx=0;jx1)?argv[1]:0);var addr;addr=accel_func_map[9](argc,argv);if(addr==0){if((id>0)&&(id1)?argv[1]:0);var addr;addr=accel_func_map[9](argc,argv);if(addr===0){if((id>0)&&(id0)?argv[0]:0);var id=((argc>1)?argv[1]:0);var indiv_prop_start=accel_params[1];var zr=accel_func_map[1](argc,argv);if(zr==3){if(id==indiv_prop_start+6) -return 1;if(id==indiv_prop_start+7) +return Mem4(addr);},13:function func_13_op__pr(argc,argv){var obj=((argc>0)?argv[0]:0);var id=((argc>1)?argv[1]:0);var indiv_prop_start=accel_params[1];var zr=accel_func_map[1](argc,argv);if(zr===3){if(id===indiv_prop_start+6) +return 1;if(id===indiv_prop_start+7) return 1;return 0;} -if(zr==2){return((id==indiv_prop_start+5)?1:0);} -if(zr!=1) +if(zr===2){return((id===indiv_prop_start+5)?1:0);} +if(zr!==1) return 0;if((id>=indiv_prop_start)&&(id>16;obj=cla;} -accel_helper_temp_args[0]=obj;accel_helper_temp_args[1]=id;prop=accel_func_map[2](2,accel_helper_temp_args);if(prop==0) -return 0;if(accel_helper_obj_in_class(obj)&&(cla==0)){if((id=accel_params[1]+8)) +accel_helper_temp_args[0]=obj;accel_helper_temp_args[1]=id;prop=accel_func_map[2](2,accel_helper_temp_args);if(prop===0) +return 0;if(accel_helper_obj_in_class(obj)&&(cla===0)){if((id=accel_params[1]+8)) return 0;} -if(Mem4(accel_params[6])!=obj){if(Mem1(prop+9)&1) +if(Mem4(accel_params[6])!==obj){if(Mem1(prop+9)&1) return 0;} return prop;} function accel_helper_get_prop_new(obj,id) -{var cla=0;var prop;if(id&0xFFFF0000){cla=Mem4(accel_params[0]+((id&0xFFFF)*4));accel_helper_temp_args[0]=obj;accel_helper_temp_args[1]=cla;if(accel_func_map[11](2,accel_helper_temp_args)==0) +{var cla=0;var prop;if(id&0xFFFF0000){cla=Mem4(accel_params[0]+((id&0xFFFF)*4));accel_helper_temp_args[0]=obj;accel_helper_temp_args[1]=cla;if(accel_func_map[11](2,accel_helper_temp_args)===0) return 0;id=id>>16;obj=cla;} -accel_helper_temp_args[0]=obj;accel_helper_temp_args[1]=id;prop=accel_func_map[8](2,accel_helper_temp_args);if(prop==0) -return 0;if(accel_helper_obj_in_class(obj)&&(cla==0)){if((id=accel_params[1]+8)) +accel_helper_temp_args[0]=obj;accel_helper_temp_args[1]=id;prop=accel_func_map[8](2,accel_helper_temp_args);if(prop===0) +return 0;if(accel_helper_obj_in_class(obj)&&(cla===0)){if((id=accel_params[1]+8)) return 0;} -if(Mem4(accel_params[6])!=obj){if(Mem1(prop+9)&1) +if(Mem4(accel_params[6])!==obj){if(Mem1(prop+9)&1) return 0;} return prop;} -function set_string_table(addr){if(stringtable==addr) -return;decoding_tree=undefined;vmstring_table=undefined;stringtable=addr;if(stringtable==0){return;} +function set_string_table(addr){if(stringtable===addr) +return;decoding_tree=undefined;vmstring_table=undefined;stringtable=addr;if(stringtable===0){return;} var textenv=vmtextenv_table[stringtable];if(textenv===undefined){var dectab=undefined;var tablelen=Mem4(stringtable);var rootaddr=Mem4(stringtable+8);var cache_stringtable=(stringtable+tablelen<=ramstart);if(cache_stringtable){var tmparray=Array(1);build_decoding_tree(tmparray,rootaddr,4,0);dectab=tmparray[0];if(dectab===undefined) fatal_error("Failed to create decoding tree.");} textenv=new VMTextEnv(stringtable,dectab);vmtextenv_table[stringtable]=textenv;} @@ -529,18 +529,18 @@ function set_iosys(mode,rock){switch(mode){case 0:rock=0;break;case 1:break;case iosysmode=mode;iosysrock=rock;var textenv=vmtextenv_table[stringtable];if(textenv===undefined) vmstring_table=undefined;else vmstring_table=textenv.vmstring_tables[iosysmode];} -function build_decoding_tree(cablist,nodeaddr,depth,mask){var ix,type,cab;var depthbit;type=Mem1(nodeaddr);if(type==0&&depth==4){cab=Array(16);cab.type=0;cab.depth=4;cablist[mask]=cab;build_decoding_tree(cab,nodeaddr,0,0);return;} -if(type==0){var leftaddr=Mem4(nodeaddr+1);var rightaddr=Mem4(nodeaddr+5);build_decoding_tree(cablist,leftaddr,depth+1,mask);build_decoding_tree(cablist,rightaddr,depth+1,(mask|(1<>=bitnum;numbits=(8-bitnum);readahead=false;if(!(decoding_tree instanceof Array)){done=true;} cablist=decoding_tree;while(!done){if(numbits<4){var newbyte=Mem1(addr+1);bits|=(newbyte<>=cab.depth;bitnum+=cab.depth;if(bitnum>=8){addr+=1;bitnum-=8;if(readahead){readahead=false;} else{var newbyte=Mem1(addr);bits|=(newbyte<=0x09) -context.code.push("oaddr = Mem4(oaddr);");if(cab.type==0x0B) -context.code.push("oaddr = Mem4(oaddr);");context.code.push("otype = Mem1(oaddr);");retval="retval";done=true;oputil_push_callstub(context,"0x10,"+bitnum,addr);context.code.push("if (otype >= 0xE0 && otype <= 0xFF) {");context.code.push("retval = [oaddr, 0, 0];");context.code.push("}");context.code.push("else if (otype >= 0xC0 && otype <= 0xDF) {");var argc=0;if(cab.type==0x0A||cab.type==0x0B){argc=Mem4(cab.addr+4);for(var ix=0;ix= 0xE0 && otype <= 0xFF) {");context.code.push("retval = [oaddr, 0, 0];");context.code.push("}");context.code.push("else if (otype >= 0xC0 && otype <= 0xDF) {");var argc=0;if(cab.type===0x0A||cab.type===0x0B){argc=Mem4(cab.addr+4);for(var ix=0;ix>=bitnum;node=Mem4(stringtable+8);while(!done){nodetype=Mem1(node);node++;switch(nodetype){case 0x00:if(byt&1) node=Mem4(node+4);else -node=Mem4(node+0);if(bitnum==7){bitnum=0;addr++;byt=Mem1(addr);} +node=Mem4(node+0);if(bitnum===7){bitnum=0;addr++;byt=Mem1(addr);} else{bitnum++;byt>>=1;} break;case 0x01:retval=false;done=true;break;case 0x02:ch=Mem1(node);switch(curiosys){case 2:context.buffer.push(CharToString(ch));break;case 1:oputil_flush_string(context);oputil_push_substring_callstub(context);oputil_push_callstub(context,"0x10,"+bitnum,addr);context.code.push("tempcallargs[0]="+ch+";");context.code.push("enter_function(iosysrock, 1);");retval=true;done=true;break;} node=Mem4(stringtable+8);break;case 0x04:ch=Mem4(node);switch(curiosys){case 2:context.buffer.push(CharToString(ch));break;case 1:oputil_flush_string(context);oputil_push_substring_callstub(context);oputil_push_callstub(context,"0x10,"+bitnum,addr);context.code.push("tempcallargs[0]="+ch+";");context.code.push("enter_function(iosysrock, 1);");retval=true;done=true;break;} -node=Mem4(stringtable+8);break;case 0x03:switch(curiosys){case 2:while(true){ch=Mem1(node);if(ch==0) +node=Mem4(stringtable+8);break;case 0x03:switch(curiosys){case 2:while(true){ch=Mem1(node);if(ch===0) break;context.buffer.push(CharToString(ch));node++;} break;case 1:oputil_flush_string(context);oputil_push_substring_callstub(context);oputil_push_callstub(context,"0x10,"+bitnum,addr);retval="["+node+", 0xE0, 0]";done=true;break;} -node=Mem4(stringtable+8);break;case 0x05:switch(curiosys){case 2:while(true){ch=Mem4(node);if(ch==0) +node=Mem4(stringtable+8);break;case 0x05:switch(curiosys){case 2:while(true){ch=Mem4(node);if(ch===0) break;context.buffer.push(CharToString(ch));node+=4;} break;case 1:oputil_flush_string(context);oputil_push_substring_callstub(context);oputil_push_callstub(context,"0x10,"+bitnum,addr);retval="["+node+", 0xE2, 0]";done=true;break;} -node=Mem4(stringtable+8);break;case 0x08:case 0x09:case 0x0A:case 0x0B:oputil_flush_string(context);oputil_push_substring_callstub(context);context.code.push("var otype, retval;");context.code.push("var oaddr = "+Mem4(node)+";");if(nodetype==0x09||nodetype==0x0B) -context.code.push("oaddr = Mem4(oaddr);");context.code.push("otype = Mem1(oaddr);");retval="retval";done=true;oputil_push_callstub(context,"0x10,"+bitnum,addr);context.code.push("if (otype >= 0xE0 && otype <= 0xFF) {");context.code.push("retval = [oaddr, 0, 0];");context.code.push("}");context.code.push("else if (otype >= 0xC0 && otype <= 0xDF) {");var argc=0;if(nodetype==0x0A||nodetype==0x0B){argc=Mem4(node+4);for(var ix=0;ix= 0xE0 && otype <= 0xFF) {");context.code.push("retval = [oaddr, 0, 0];");context.code.push("}");context.code.push("else if (otype >= 0xC0 && otype <= 0xDF) {");var argc=0;if(nodetype===0x0A||nodetype===0x0B){argc=Mem4(node+4);for(var ix=0;ix=0xE0&&type<=0xFF){fatal_error("Attempt to print unknown type of string.");} @@ -616,18 +616,18 @@ var tempsearchkey=[];function fetch_search_key(addr,len,options){var ix;tempsear tempsearchkey[ix]=Mem1(addr+ix);} else{switch(len){case 4:tempsearchkey[0]=(addr>>24)&0xFF;tempsearchkey[1]=(addr>>16)&0xFF;tempsearchkey[2]=(addr>>8)&0xFF;tempsearchkey[3]=addr&0xFF;break;case 2:tempsearchkey[0]=(addr>>8)&0xFF;tempsearchkey[1]=addr&0xFF;break;case 1:tempsearchkey[0]=addr&0xFF;break;default:throw('Direct search key must hold one, two, or four bytes.');}} return tempsearchkey;} -function linear_search(key,keysize,start,structsize,numstructs,keyoffset,options){var ix,count,match,byt;var retindex=((options&4)!=0);var zeroterm=((options&2)!=0);var keybuf=fetch_search_key(key,keysize,options);for(count=0;count>1;addr=start+val*structsize;for(ix=0;(!cmp)&&ix>1;addr=start+val*structsize;for(ix=0;(!cmp)&&ixbyt2) cmp=1;} if(!cmp){if(retindex) @@ -638,18 +638,18 @@ else{top=val;}} if(retindex) return 0xFFFFFFFF;else return 0;} -function linked_search(key,keysize,start,keyoffset,nextoffset,options){var ix,byt,match;var zeroterm=((options&2)!=0);var keybuf=fetch_search_key(key,keysize,options);while(start!=0){match=true;for(ix=0;match&&ix>23&0xff);if(expo){res=((val&0x7fffff|0x800000)/8388608*Math.pow(2,(expo-127)));} else{res=((val&0x7fffff)/8388608*Math.pow(2,-126));} @@ -660,35 +660,35 @@ function encode_float(val){var absval,fbits;var mant,expo,sign;if(isNaN(val)){re if(!isFinite(val)){if(val<0) return 0xff800000;else return 0x7f800000;} -if(val==0){if(1/val<0) +if(val===0){if(1/val<0) return 0x80000000;else return 0x0;} if(val<0){sign=true;absval=-val;} else{sign=false;absval=val;} expo=Math.floor(Math.log(absval)/Math.log(2));mant=absval/Math.pow(2,expo);if(expo>=128){return(sign?0xff800000:0x7f800000);} else if(expo<-126){mant=mant*Math.pow(2,126+expo);expo=0;} -else if(!(expo==0&&mant==0.0)){expo+=127;mant-=1.0;} +else if(!(expo===0&&mant===0.0)){expo+=127;mant-=1.0;} mant=mant*8388608.0;fbits=(mant+0.4999999999999999)<<0;if(fbits>=8388608){fbits=0;expo++;if(expo>=255){return(sign?0xff800000:0x7f800000);}} if(sign) return((0x80000000)|(expo<<23)|(fbits))>>>0;else return(expo<<23)|(fbits);} var game_image=null;var game_signature=null;var opt_rethrow_exceptions=null;var memmap;var stack;var frame;var vm_started=false;var vm_stopped=false;var tempcallargs;var tempglkargs;var done_executing;var vmfunc_table;var vmtextenv_table;var decoding_tree;var vmstring_table;var random_func;var ramstart;var endgamefile;var origendmem;var stacksize;var startfuncaddr;var origstringtable;var checksum;var pc;var stringtable;var endmem;var protectstart,protectend;var iosysmode,iosysrock;var undostack;var resumefuncop,resumevalue;var heapstart;var usedlist;var freelist;var total_execution_time=0;var total_function_calls=0;var accel_function_calls=0;var total_path_calls=0;var paths_cached=0;var paths_compiled=0;var strings_cached=0;var strings_compiled=0;function setup_vm(){var val,version;if(!game_image) fatal_error("There is no Glulx game file loaded.");vm_started=true;resumefuncop=null;resumevalue=0;memmap=null;stack=[];frame=null;pc=0;if(game_image.length<36) -fatal_error("This is too short to be a valid Glulx file.");val=ByteRead4(game_image,0);if(val!=0x476c756c) +fatal_error("This is too short to be a valid Glulx file.");val=ByteRead4(game_image,0);if(val!==0x476c756c) fatal_error("This is not a valid Glulx file.");version=ByteRead4(game_image,4);if(version<0x20000) fatal_error("This Glulx file is too old a version to execute.");if(version>=0x30200) fatal_error("This Glulx file is too new a version to execute.");ramstart=ByteRead4(game_image,8);endgamefile=ByteRead4(game_image,12);origendmem=ByteRead4(game_image,16);stacksize=ByteRead4(game_image,20);startfuncaddr=ByteRead4(game_image,24);origstringtable=ByteRead4(game_image,28);checksum=ByteRead4(game_image,32);protectstart=0;protectend=0;if(ramstart<0x100||endgamefile0){result.push(0);result.push(zeroes-1);} -while(i0){count=Glk.glk_get_buffer_stream(str,buffer);quetzal=quetzal.concat(buffer.slice(0,count));} quetzal=unpack_iff_chunks(quetzal);if(!quetzal){qlog("vm_restore failed: file is not Quetzal");return false;} -quetzal=quetzal["FORM"];if(!quetzal||ByteReadString(quetzal,0,4)!="IFZS"){qlog("vm_restore failed: file doesn't start with FORM/IFZS header");return false;} +quetzal=quetzal["FORM"];if(!quetzal||ByteReadString(quetzal,0,4)!=="IFZS"){qlog("vm_restore failed: file doesn't start with FORM/IFZS header");return false;} var chunks=unpack_iff_chunks(quetzal.slice(4));if(!chunks["IFhd"]){qlog("vm_restore failed: missing required IFhd chunk");return false;} -for(var i=0;i<128;i++){if(chunks["IFhd"][i]!=game_image[i]){qlog("vm_restore failed: this save image is for a different game");return false;}} +for(var i=0;i<128;i++){if(chunks["IFhd"][i]!==game_image[i]){qlog("vm_restore failed: this save image is for a different game");return false;}} if(!chunks["CMem"]){qlog("vm_restore failed: missing required CMem chunk");return false;} if(!chunks["Stks"]){qlog("vm_restore failed: missing required Stks chunk");return false;} var protect=copy_protected_range();heap_clear();var newendmem=ByteRead4(chunks["CMem"],0);var ram_xor=chunks["CMem"].slice(4);ram_xor=decompress_bytes(ram_xor);while(ram_xor.length10){undostack.shift();}} -function vm_restoreundo(){if(undostack.length==0){return false;} +function vm_restoreundo(){if(undostack.length===0){return false;} var snapshot=undostack.pop();var protect=copy_protected_range();memmap=memmap.slice(0,ramstart).concat(snapshot.ram);endmem=snapshot.endmem;stack=snapshot.stack;frame=stack[stack.length-1];pc=snapshot.pc;heapstart=snapshot.heapstart;usedlist=snapshot.usedlist;freelist=snapshot.freelist;paste_protected_range(protect);return true;} -function change_memsize(newlen,internal){var lx;if(newlen==endmem) +function change_memsize(newlen,internal){var lx;if(newlen===endmem) return;if((!internal)&&heap_is_active()) fatal_error("Cannot resize Glulx memory space while heap is active.");if(newlenendmem) end=endmem;for(ix=0,addr=start;addr>>0;for(ix=0;ix>>0;} -if(newsum!=checksum) +if(newsum!==checksum) return 1;return 0;} function quixe_get_signature(){return game_signature;} function quixe_get_statistics(){var stat={game_image_length:game_image.length,total_execution_time:total_execution_time,total_function_calls:total_function_calls,accel_function_calls:accel_function_calls,total_path_calls:total_path_calls,paths_cached:paths_cached,paths_compiled:paths_compiled,strings_cached:strings_cached,strings_compiled:strings_compiled};return stat;} @@ -759,22 +759,22 @@ for(var i=0,max=freelist.length;isize){freelist.push(new HeapBlock(addr+size,rounded_up_size-size));} usedlist.push(new HeapBlock(addr,size));return addr;} -function heap_free(addr){var pos=heap_binary_search(usedlist,addr);var block=usedlist[pos];if(!block||block.addr!=addr){fatal_error("Tried to free non-existent block");} -usedlist.splice(pos,1);if(usedlist.length==0){change_memsize(heapstart,true);heap_clear();return;} -pos=heap_binary_search(freelist,addr);var next=freelist[pos];if(next&&next.addr==block.end){block=new HeapBlock(addr,block.size+next.size);freelist.splice(pos,1);} -var prev=freelist[pos-1];if(prev&&prev.end==block.addr){block=new HeapBlock(prev.addr,prev.size+block.size);freelist.splice(pos-1,1);pos-=1;} +function heap_free(addr){var pos=heap_binary_search(usedlist,addr);var block=usedlist[pos];if(!block||block.addr!==addr){fatal_error("Tried to free non-existent block");} +usedlist.splice(pos,1);if(usedlist.length===0){change_memsize(heapstart,true);heap_clear();return;} +pos=heap_binary_search(freelist,addr);var next=freelist[pos];if(next&&next.addr===block.end){block=new HeapBlock(addr,block.size+next.size);freelist.splice(pos,1);} +var prev=freelist[pos-1];if(prev&&prev.end===block.addr){block=new HeapBlock(prev.addr,prev.size+block.size);freelist.splice(pos-1,1);pos-=1;} freelist.splice(pos,0,block);} -function assert_heap_valid(){if(!heap_is_active()){if(heapstart!=0) +function assert_heap_valid(){if(!heap_is_active()){if(heapstart!==0) fatal_error("Heap inconsistency: heapstart nonzero");if(usedlist.length>0) fatal_error("Heap inconsistency: usedlist nonempty");if(freelist.length>0) fatal_error("Heap inconsistency: usedlist nonempty");return;} -if(heapstart==0) -fatal_error("Heap inconsistency: heapstart is zero");var addr=heapstart;var upos=0,fpos=0;while(upos   Loading...
-
-This should not be visible -
12345678
12345678
-
12345678
12345678
-
[] ! The following footnote is added to the small print about how to play IF diff --git a/play-full.html b/play-full.html index d62a43b..b4c4a9f 100644 --- a/play-full.html +++ b/play-full.html @@ -57,11 +57,6 @@    Loading...
-
-This should not be visible -
12345678
12345678
-
12345678
12345678
-
diff --git a/play-remote-full.html b/play-remote-full.html index dabcf27..bb44c2d 100644 --- a/play-remote-full.html +++ b/play-remote-full.html @@ -56,11 +56,6 @@    Loading...
-
-This should not be visible -
12345678
12345678
-
12345678
12345678
-
diff --git a/play-remote-onecol.html b/play-remote-onecol.html index ad97417..f7864d1 100644 --- a/play-remote-onecol.html +++ b/play-remote-onecol.html @@ -146,11 +146,6 @@    Loading... -
-This should not be visible -
12345678
12345678
-
12345678
12345678
-
diff --git a/play-remote.html b/play-remote.html index d60dc55..e702e1a 100644 --- a/play-remote.html +++ b/play-remote.html @@ -52,11 +52,6 @@    Loading... -
-This should not be visible -
12345678
12345678
-
12345678
12345678
-
diff --git a/play.html b/play.html index 244e56e..d64db51 100644 --- a/play.html +++ b/play.html @@ -53,11 +53,6 @@    Loading... -
-This should not be visible -
12345678
12345678
-
12345678
12345678
-
diff --git a/src/glkote b/src/glkote new file mode 160000 index 0000000..d405b69 --- /dev/null +++ b/src/glkote @@ -0,0 +1 @@ +Subproject commit d405b69dd647f5b8cabd139f95a6cad43f3cb9c0 diff --git a/src/glkote/dialog.js b/src/glkote/dialog.js deleted file mode 100644 index 0880700..0000000 --- a/src/glkote/dialog.js +++ /dev/null @@ -1,1128 +0,0 @@ -/* Dialog -- a Javascript load/save library for IF interfaces - * Designed by Andrew Plotkin - * - * - * This Javascript library is copyright 2010-15 by Andrew Plotkin. - * It is distributed under the MIT license; see the "LICENSE" file. - * - * This library lets you open a modal dialog box to select a "file" for saving - * or loading data. The web page must have a
with id "windowport" (this - * will be greyed out during the selection process, with the dialog box as a - * child of the div). It should also have the dialog.css stylesheet loaded. - * - * This library also contains utility routines to manage "files", which are - * actually entries in the browser's localStorage object. - * - * The primary function to call: - * - * Dialog.open(tosave, usage, gameid, callback) -- open a file-choosing dialog - * - * The rest of the API concerns file reference objects. A fileref encodes a - * usage and gameid (as above), along with a filename (which can be any string - * at all). This trio specifies a "file", that is, a chunk of data in browser - * local storage. - * - * (These fileref objects are not the same as the filerefs used in the Glk API. - * A Glk fileref contains one of these filerefs, however.) - * - * Dialog.file_construct_ref(filename, usage, gameid) -- create a fileref - * Dialog.file_write(ref, content, israw) -- write data to the file - * Dialog.file_read(ref, israw) -- read data from the file - * Dialog.file_ref_exists(ref) -- returns whether the file exists - * Dialog.file_remove_ref(ref) -- delete the file, if it exists - * - * - * The localStorage format is as follows. Each file is represented as two - * storage keys: "dirent:usage:gameid:filename" and - * "content:usage:gameid:filename". (The filename is last so that it can - * validly contain colons. Since this is a user-entered string, it can contain - * *any* typeable character.) - * - * The "content:" key contains the file content, as a string. (The HTML5 - * browser storage spec says that you can store any serializable data, but the - * browsers have not yet implemented this. Thus the "israw" option in the read - * and write functions.) - * - * The "dirent:" key contains directory information. Currently this looks like - * "created:TIMESTAMP,modified:TIMESTAMP". Future version of this library may - * add a human-readable game name, a text/binary flag, or other data. - */ - -//### accept "return" keystroke for load-select box (already works in Chrome) - -/* Put everything inside the Dialog namespace. */ - -Dialog = function() { - -var dialog_el_id = 'dialog'; - -var is_open = false; -var dialog_callback = null; -var will_save; /* is this a save dialog? */ -var confirming; /* are we in a "confirm" sub-dialog? */ -var editing; /* have we flipped to "edit" mode? */ -var editing_dirent; /* null for the edit selection screen, or a dirent to - display */ -var cur_usage; /* a string representing the file's category */ -var cur_usage_name; /* the file's category as a human-readable string */ -var cur_gameid; /* a string representing the game */ -var cur_filelist; /* the files currently on display */ - -/* Dialog.open(tosave, usage, gameid, callback) -- open a file-choosing dialog - * - * The "tosave" flag should be true for a save dialog, false for a load - * dialog. - * - * The "usage" and "gameid" arguments are arbitrary strings which describe the - * file. These filter the list of files displayed; the dialog will only list - * files that match the arguments. Pass null to either argument (or both) to - * skip filtering. - * - * The "callback" should be a function. This will be called with a fileref - * argument (see below) when the user selects a file. If the user cancels the - * selection, the callback will be called with a null argument. -*/ -function dialog_open(tosave, usage, gameid, callback) { - if (is_open) - throw 'Dialog: dialog box is already open.'; - - if (localStorage == null) - throw 'Dialog: your browser does not support local storage.'; - - dialog_callback = callback; - will_save = tosave; - confirming = false; - editing = false; - editing_dirent = null; - cur_usage = usage; - cur_gameid = gameid; - cur_usage_name = label_for_usage(cur_usage); - - /* Figure out what the root div is called. The dialog box will be - positioned in this div; also, the div will be greyed out by a - translucent rectangle. We use the same default as GlkOte: - "windowport". We also try to interrogate GlkOte to see if that - default has been changed. */ - var root_el_id = 'windowport'; - var iface = window.Game; - if (window.GlkOte) - iface = window.GlkOte.getinterface(); - if (iface && iface.windowport) - root_el_id = iface.windowport; - - var rootel = $('#'+root_el_id); - if (!rootel.length) - throw 'Dialog: unable to find root element #' + root_el_id + '.'; - - /* Create the grey-out screen. */ - var screen = $('#'+dialog_el_id+'_screen'); - if (!screen.length) { - screen = $('
', - { id: dialog_el_id+'_screen' }); - rootel.append(screen); - } - - /* And now, a lot of DOM creation for the dialog box. */ - - var frame = $('#'+dialog_el_id+'_frame'); - if (!frame.length) { - frame = $('
', - { id: dialog_el_id+'_frame' }); - rootel.append(frame); - } - - var dia = $('#'+dialog_el_id); - if (dia.length) - dia.remove(); - - dia = $('
', { id: dialog_el_id }); - - var form, el, row; - - form = $('
'); - form.on('submit', - (will_save ? evhan_accept_save_button : evhan_accept_load_button)); - dia.append(form); - - row = $('
', { 'class': 'DiaButtonsFloat' }); - el = $('