mirror of
https://github.com/DaedalusX64/daedalus.git
synced 2025-04-02 10:21:48 -04:00
762 lines
22 KiB
JavaScript
762 lines
22 KiB
JavaScript
/*jshint jquery:true browser:true */
|
|
|
|
(function (daedalus) {'use strict';
|
|
var $dlistOutput;
|
|
var $dlistState;
|
|
var $dlistScrub;
|
|
var debugBailAfter = -1;
|
|
var debugNumOps = 0;
|
|
|
|
var state = {};
|
|
|
|
daedalus.init = function () {
|
|
|
|
$dlistOutput = $('#dlist');
|
|
$dlistState = $('.dl-state');
|
|
|
|
$dlistScrub = $('.scrub');
|
|
$dlistScrub.find('input').change(function () {
|
|
setScrubTime($(this).val() | 0);
|
|
});
|
|
setScrubRange(0);
|
|
|
|
$('#ctrl-break').click(function () {
|
|
$.post('/dldebugger?action=break', function(data) {
|
|
// Update the scrubber based on the new length of disassembly
|
|
debugNumOps = data.num_ops > 0 ? (data.num_ops-1) : 0;
|
|
setScrubRange(debugNumOps);
|
|
|
|
// If debugBailAfter hasn't been set (e.g. by hleHalt), stop at the end of the list
|
|
var time_to_show = (debugBailAfter == -1) ? debugNumOps : debugBailAfter;
|
|
setScrubTime(time_to_show);
|
|
|
|
$.post('/dldebugger?dump', function (ret) {
|
|
var $pre = $('<pre />');
|
|
$pre.html(ret);
|
|
$dlistOutput.html($pre);
|
|
|
|
// FIXME: setScrubTime here? At least need to set position.
|
|
});
|
|
});
|
|
});
|
|
$('#ctrl-resume').click(function () {
|
|
$.post('/dldebugger?action=resume');
|
|
});
|
|
$('#ctrl-prev').click(function () {
|
|
if (debugBailAfter > 0) {
|
|
setScrubTime(debugBailAfter - 1);
|
|
}
|
|
});
|
|
$('#ctrl-next').click(function () {
|
|
if (debugBailAfter < debugNumOps) {
|
|
setScrubTime(debugBailAfter + 1);
|
|
}
|
|
});
|
|
};
|
|
|
|
// FIXME: we should reuse n64js/hle.js :)
|
|
function setScrubText(x, max) {
|
|
$dlistScrub.find('.scrub-text').html('uCode op ' + x + '/' + max + '.');
|
|
}
|
|
|
|
function setScrubRange(max) {
|
|
var $slider = $dlistScrub.find('input');
|
|
$slider.attr({
|
|
min: 0,
|
|
max: max,
|
|
value: max
|
|
});
|
|
$slider.val(max);
|
|
setScrubText(max, max);
|
|
}
|
|
|
|
function setScrubTime(t) {
|
|
debugBailAfter = t;
|
|
setScrubText(debugBailAfter, debugNumOps);
|
|
|
|
var $instr = $dlistOutput.find('#I' + debugBailAfter );
|
|
if ($instr.length) {
|
|
$dlistOutput.scrollTop($dlistOutput.scrollTop() + $instr.position().top -
|
|
$dlistOutput.height()/2 + $instr.height()/2);
|
|
}
|
|
$dlistOutput.find('.hle-detail').hide();
|
|
$instr.find('.hle-detail').show();
|
|
|
|
$dlistOutput.find('.hle-instr').removeAttr('style');
|
|
$instr.css('background-color', 'rgb(255,255,204)');
|
|
|
|
$.post('/dldebugger?scrub=' + t, function(data) {
|
|
$('#screen').attr({src: '/dldebugger?screen'});
|
|
|
|
state = data;
|
|
state.rdpOtherModeH = parseInt(data.rdpOtherModeH, 16);
|
|
state.rdpOtherModeL = parseInt(data.rdpOtherModeL, 16);
|
|
state.combine.hi = parseInt(data.combine.hi, 16);
|
|
state.combine.lo = parseInt(data.combine.lo, 16);
|
|
state.fillColor = parseInt(data.fillColor, 16);
|
|
state.envColor = parseInt(data.envColor, 16);
|
|
state.primColor = parseInt(data.primColor, 16);
|
|
state.blendColor = parseInt(data.blendColor, 16);
|
|
state.fogColor = parseInt(data.fogColor, 16);
|
|
|
|
updateStateUI();
|
|
});
|
|
}
|
|
|
|
|
|
function makeColourText(r,g,b,a) {
|
|
var t = r + ', ' + g + ', ' + b + ', ' + a;
|
|
|
|
if ((r<128 && g<128) ||
|
|
(g<128 && b<128) ||
|
|
(b<128 && r<128)) {
|
|
return '<span style="color: white; background-color: rgb(' + r + ',' + g + ',' + b + ')">' + t + '</span>';
|
|
}
|
|
return '<span style="background-color: rgb(' + r + ',' + g + ',' + b + ')">' + t + '</span>';
|
|
}
|
|
|
|
function makeColorTextRGBA(col) {
|
|
var r = (col >>> 24) & 0xff;
|
|
var g = (col >>> 16) & 0xff;
|
|
var b = (col >>> 8) & 0xff;
|
|
var a = (col ) & 0xff;
|
|
|
|
return makeColourText(r,g,b,a);
|
|
}
|
|
|
|
function makeColorTextABGR(col) {
|
|
var r = (col ) & 0xff;
|
|
var g = (col >>> 8) & 0xff;
|
|
var b = (col >>> 16) & 0xff;
|
|
var a = (col >>> 24) & 0xff;
|
|
|
|
return makeColourText(r,g,b,a);
|
|
}
|
|
|
|
function updateStateUI() {
|
|
|
|
//$dlistState.find('#dl-geometrymode-content').html(buildStateTab());
|
|
//$dlistState.find('#dl-vertices-content').html(buildVerticesTab());
|
|
$dlistState.find('#dl-textures-content').html(buildTexturesTab());
|
|
$dlistState.find('#dl-combiner-content').html(buildCombinerTab());
|
|
$dlistState.find('#dl-rdp-content').html(buildRDPTab());
|
|
}
|
|
|
|
function getDefine(m, v) {
|
|
for (var d in m) {
|
|
if (m[d] === v)
|
|
return d;
|
|
}
|
|
return n64js.toString32(v);
|
|
}
|
|
var imageFormatTypes = {
|
|
G_IM_FMT_RGBA: 0,
|
|
G_IM_FMT_YUV: 1,
|
|
G_IM_FMT_CI: 2,
|
|
G_IM_FMT_IA: 3,
|
|
G_IM_FMT_I: 4
|
|
};
|
|
|
|
var imageSizeTypes = {
|
|
G_IM_SIZ_4b: 0,
|
|
G_IM_SIZ_8b: 1,
|
|
G_IM_SIZ_16b: 2,
|
|
G_IM_SIZ_32b: 3
|
|
};
|
|
|
|
var renderModeFlags = {
|
|
AA_EN: 0x0008,
|
|
Z_CMP: 0x0010,
|
|
Z_UPD: 0x0020,
|
|
IM_RD: 0x0040,
|
|
CLR_ON_CVG: 0x0080,
|
|
CVG_DST_CLAMP: 0,
|
|
CVG_DST_WRAP: 0x0100,
|
|
CVG_DST_FULL: 0x0200,
|
|
CVG_DST_SAVE: 0x0300,
|
|
ZMODE_OPA: 0,
|
|
ZMODE_INTER: 0x0400,
|
|
ZMODE_XLU: 0x0800,
|
|
ZMODE_DEC: 0x0c00,
|
|
CVG_X_ALPHA: 0x1000,
|
|
ALPHA_CVG_SEL: 0x2000,
|
|
FORCE_BL: 0x4000,
|
|
TEX_EDGE: 0x0000 /* used to be 0x8000 */
|
|
};
|
|
|
|
var blendColourSources = [
|
|
'G_BL_CLR_IN',
|
|
'G_BL_CLR_MEM',
|
|
'G_BL_CLR_BL',
|
|
'G_BL_CLR_FOG'
|
|
];
|
|
|
|
var blendSourceFactors = [
|
|
'G_BL_A_IN',
|
|
'G_BL_A_FOG',
|
|
'G_BL_A_SHADE',
|
|
'G_BL_0'
|
|
];
|
|
|
|
var blendDestFactors = [
|
|
'G_BL_1MA',
|
|
'G_BL_A_MEM',
|
|
'G_BL_1',
|
|
'G_BL_0'
|
|
];
|
|
|
|
function blendOpText(v) {
|
|
var m1a = (v>>>12)&0x3;
|
|
var m1b = (v>>> 8)&0x3;
|
|
var m2a = (v>>> 4)&0x3;
|
|
var m2b = (v>>> 0)&0x3;
|
|
|
|
return blendColourSources[m1a] + ',' + blendSourceFactors[m1b] + ',' + blendColourSources[m2a] + ',' + blendDestFactors[m2b];
|
|
}
|
|
|
|
function getRenderModeFlagsText(data) {
|
|
var t = '';
|
|
|
|
if (data & renderModeFlags.AA_EN) t += '|AA_EN';
|
|
if (data & renderModeFlags.Z_CMP) t += '|Z_CMP';
|
|
if (data & renderModeFlags.Z_UPD) t += '|Z_UPD';
|
|
if (data & renderModeFlags.IM_RD) t += '|IM_RD';
|
|
if (data & renderModeFlags.CLR_ON_CVG) t += '|CLR_ON_CVG';
|
|
|
|
var cvg = data & 0x0300;
|
|
if (cvg === renderModeFlags.CVG_DST_CLAMP) t += '|CVG_DST_CLAMP';
|
|
else if (cvg === renderModeFlags.CVG_DST_WRAP) t += '|CVG_DST_WRAP';
|
|
else if (cvg === renderModeFlags.CVG_DST_FULL) t += '|CVG_DST_FULL';
|
|
else if (cvg === renderModeFlags.CVG_DST_SAVE) t += '|CVG_DST_SAVE';
|
|
|
|
var zmode = data & 0x0c00;
|
|
if (zmode === renderModeFlags.ZMODE_OPA) t += '|ZMODE_OPA';
|
|
else if (zmode === renderModeFlags.ZMODE_INTER) t += '|ZMODE_INTER';
|
|
else if (zmode === renderModeFlags.ZMODE_XLU) t += '|ZMODE_XLU';
|
|
else if (zmode === renderModeFlags.ZMODE_DEC) t += '|ZMODE_DEC';
|
|
|
|
if (data & renderModeFlags.CVG_X_ALPHA) t += '|CVG_X_ALPHA';
|
|
if (data & renderModeFlags.ALPHA_CVG_SEL) t += '|ALPHA_CVG_SEL';
|
|
if (data & renderModeFlags.FORCE_BL) t += '|FORCE_BL';
|
|
|
|
var c0 = t.length > 0 ? t.substr(1) : '0';
|
|
|
|
var blend = data >>> G_MDSFT_BLENDER;
|
|
|
|
var c1 = 'GBL_c1(' + blendOpText(blend>>>2) + ') | GBL_c2(' + blendOpText(blend) + ') /*' + n64js.toString16(blend) + '*/';
|
|
|
|
return c0 + ', ' + c1;
|
|
}
|
|
|
|
// G_SETOTHERMODE_L sft: shift count
|
|
var G_MDSFT_ALPHACOMPARE = 0;
|
|
var G_MDSFT_ZSRCSEL = 2;
|
|
var G_MDSFT_RENDERMODE = 3;
|
|
var G_MDSFT_BLENDER = 16;
|
|
|
|
var G_AC_MASK = 3 << G_MDSFT_ALPHACOMPARE;
|
|
var G_ZS_MASK = 1 << G_MDSFT_ZSRCSEL;
|
|
|
|
function getAlphaCompareType() {
|
|
return state.rdpOtherModeL & G_AC_MASK;
|
|
}
|
|
|
|
function getCoverageTimesAlpha() {
|
|
return (state.rdpOtherModeL & renderModeFlags.CVG_X_ALPHA) !== 0; // fragment coverage (0) or alpha (1)?
|
|
}
|
|
|
|
function getAlphaCoverageSelect() {
|
|
return (state.rdpOtherModeL & renderModeFlags.ALPHA_CVG_SEL) !== 0; // use fragment coverage * fragment alpha
|
|
}
|
|
|
|
//G_SETOTHERMODE_H shift count
|
|
var G_MDSFT_BLENDMASK = 0;
|
|
var G_MDSFT_ALPHADITHER = 4;
|
|
var G_MDSFT_RGBDITHER = 6;
|
|
var G_MDSFT_COMBKEY = 8;
|
|
var G_MDSFT_TEXTCONV = 9;
|
|
var G_MDSFT_TEXTFILT = 12;
|
|
var G_MDSFT_TEXTLUT = 14;
|
|
var G_MDSFT_TEXTLOD = 16;
|
|
var G_MDSFT_TEXTDETAIL = 17;
|
|
var G_MDSFT_TEXTPERSP = 19;
|
|
var G_MDSFT_CYCLETYPE = 20;
|
|
var G_MDSFT_COLORDITHER = 22;
|
|
var G_MDSFT_PIPELINE = 23;
|
|
|
|
var G_PM_MASK = 1 << G_MDSFT_PIPELINE;
|
|
var G_CYC_MASK = 3 << G_MDSFT_CYCLETYPE;
|
|
var G_TP_MASK = 1 << G_MDSFT_TEXTPERSP;
|
|
var G_TD_MASK = 3 << G_MDSFT_TEXTDETAIL;
|
|
var G_TL_MASK = 1 << G_MDSFT_TEXTLOD;
|
|
var G_TT_MASK = 3 << G_MDSFT_TEXTLUT;
|
|
var G_TF_MASK = 3 << G_MDSFT_TEXTFILT;
|
|
var G_TC_MASK = 7 << G_MDSFT_TEXTCONV;
|
|
var G_CK_MASK = 1 << G_MDSFT_COMBKEY;
|
|
var G_CD_MASK = 3 << G_MDSFT_RGBDITHER;
|
|
var G_AD_MASK = 3 << G_MDSFT_ALPHADITHER;
|
|
|
|
var pipelineModeValues = {
|
|
G_PM_1PRIMITIVE: 1 << G_MDSFT_PIPELINE,
|
|
G_PM_NPRIMITIVE: 0 << G_MDSFT_PIPELINE
|
|
};
|
|
|
|
var cycleTypeValues = {
|
|
G_CYC_1CYCLE: 0 << G_MDSFT_CYCLETYPE,
|
|
G_CYC_2CYCLE: 1 << G_MDSFT_CYCLETYPE,
|
|
G_CYC_COPY: 2 << G_MDSFT_CYCLETYPE,
|
|
G_CYC_FILL: 3 << G_MDSFT_CYCLETYPE
|
|
};
|
|
|
|
var texturePerspValues = {
|
|
G_TP_NONE: 0 << G_MDSFT_TEXTPERSP,
|
|
G_TP_PERSP: 1 << G_MDSFT_TEXTPERSP
|
|
};
|
|
|
|
var textureDetailValues = {
|
|
G_TD_CLAMP: 0 << G_MDSFT_TEXTDETAIL,
|
|
G_TD_SHARPEN: 1 << G_MDSFT_TEXTDETAIL,
|
|
G_TD_DETAIL: 2 << G_MDSFT_TEXTDETAIL
|
|
};
|
|
|
|
var textureLODValues = {
|
|
G_TL_TILE: 0 << G_MDSFT_TEXTLOD,
|
|
G_TL_LOD: 1 << G_MDSFT_TEXTLOD
|
|
};
|
|
|
|
var textureLUTValues = {
|
|
G_TT_NONE: 0 << G_MDSFT_TEXTLUT,
|
|
G_TT_RGBA16: 2 << G_MDSFT_TEXTLUT,
|
|
G_TT_IA16: 3 << G_MDSFT_TEXTLUT
|
|
};
|
|
|
|
var textureFilterValues = {
|
|
G_TF_POINT: 0 << G_MDSFT_TEXTFILT,
|
|
G_TF_AVERAGE: 3 << G_MDSFT_TEXTFILT,
|
|
G_TF_BILERP: 2 << G_MDSFT_TEXTFILT
|
|
};
|
|
|
|
var textureConvertValues = {
|
|
G_TC_CONV: 0 << G_MDSFT_TEXTCONV,
|
|
G_TC_FILTCONV: 5 << G_MDSFT_TEXTCONV,
|
|
G_TC_FILT: 6 << G_MDSFT_TEXTCONV
|
|
};
|
|
|
|
var combineKeyValues = {
|
|
G_CK_NONE: 0 << G_MDSFT_COMBKEY,
|
|
G_CK_KEY: 1 << G_MDSFT_COMBKEY
|
|
};
|
|
|
|
var colorDitherValues = {
|
|
G_CD_MAGICSQ: 0 << G_MDSFT_RGBDITHER,
|
|
G_CD_BAYER: 1 << G_MDSFT_RGBDITHER,
|
|
G_CD_NOISE: 2 << G_MDSFT_RGBDITHER,
|
|
G_CD_DISABLE: 3 << G_MDSFT_RGBDITHER
|
|
};
|
|
|
|
var alphaDitherValues = {
|
|
G_AD_PATTERN: 0 << G_MDSFT_ALPHADITHER,
|
|
G_AD_NOTPATTERN: 1 << G_MDSFT_ALPHADITHER,
|
|
G_AD_NOISE: 2 << G_MDSFT_ALPHADITHER,
|
|
G_AD_DISABLE: 3 << G_MDSFT_ALPHADITHER
|
|
};
|
|
|
|
var alphaCompareValues = {
|
|
G_AC_NONE: 0 << G_MDSFT_ALPHACOMPARE,
|
|
G_AC_THRESHOLD: 1 << G_MDSFT_ALPHACOMPARE,
|
|
G_AC_DITHER: 3 << G_MDSFT_ALPHACOMPARE
|
|
};
|
|
|
|
var depthSourceValues = {
|
|
G_ZS_PIXEL: 0 << G_MDSFT_ZSRCSEL,
|
|
G_ZS_PRIM: 1 << G_MDSFT_ZSRCSEL
|
|
};
|
|
|
|
function getCycleType() {
|
|
return state.rdpOtherModeH & G_CYC_MASK;
|
|
}
|
|
|
|
|
|
function getClampMirrorWrapText(clamp, mirror) {
|
|
if (clamp && mirror) return 'G_TX_MIRROR|G_TX_CLAMP';
|
|
if (clamp) return 'G_TX_CLAMP';
|
|
if (mirror) return 'G_TX_MIRROR';
|
|
|
|
return 'G_TX_WRAP';
|
|
}
|
|
|
|
function buildTexture(tile_idx) {
|
|
var tile = state.tiles[tile_idx];
|
|
if (tile && tile.texture && tile.texture.data && tile.texture.width > 0 && tile.texture.height > 0) {
|
|
// Copy + scale texture data.
|
|
var scale = 8;
|
|
var w = tile.texture.width * scale;
|
|
var h = tile.texture.height * scale;
|
|
var $canvas = $( '<canvas width="' + w + '" height="' + h + '" style="background-color: black" />', {'width':w, 'height':h} );
|
|
var dst_ctx = $canvas[0].getContext('2d');
|
|
|
|
var dst_img_data = dst_ctx.createImageData(w, h);
|
|
|
|
var src = Base64.decodeArray(tile.texture.data);
|
|
var dst = dst_img_data.data;
|
|
var src_row_stride = tile.texture.width*4;
|
|
var dst_row_stride = dst_img_data.width*4;
|
|
|
|
// Repeat last pixel across all lines
|
|
var x;
|
|
var y;
|
|
for (y = 0; y < h; ++y) {
|
|
|
|
var src_offset = src_row_stride * Math.floor(y/scale);
|
|
var dst_offset = dst_row_stride * y;
|
|
|
|
for (x = 0; x < w; ++x) {
|
|
var o = src_offset + Math.floor(x/scale)*4;
|
|
dst[dst_offset+0] = src[o+0];
|
|
dst[dst_offset+1] = src[o+1];
|
|
dst[dst_offset+2] = src[o+2];
|
|
dst[dst_offset+3] = src[o+3];
|
|
dst_offset += 4;
|
|
}
|
|
}
|
|
|
|
dst_ctx.putImageData(dst_img_data, 0, 0);
|
|
|
|
return $canvas;
|
|
}
|
|
}
|
|
|
|
function buildTexturesTab() {
|
|
var $d = $('<div />');
|
|
|
|
$d.append(buildTilesTable());
|
|
|
|
var i, $t;
|
|
for (i = 0; i < 8; ++i) {
|
|
$t = buildTexture(i);
|
|
if ($t) {
|
|
$d.append($t);
|
|
}
|
|
}
|
|
|
|
return $d;
|
|
}
|
|
|
|
function buildTilesTable() {
|
|
var tiles = state.tiles;
|
|
var tile_fields = [
|
|
'tile #',
|
|
'format',
|
|
'size',
|
|
'line',
|
|
'tmem',
|
|
'palette',
|
|
'cm_s',
|
|
'mask_s',
|
|
'shift_s',
|
|
'cm_t',
|
|
'mask_t',
|
|
'shift_t',
|
|
'left',
|
|
'top',
|
|
'right',
|
|
'bottom'
|
|
];
|
|
|
|
var $table = $('<table class="table table-condensed" style="width: auto"></table>');
|
|
var $tr = $('<tr><th>' + tile_fields.join('</th><th>') + '</th></tr>');
|
|
$table.append($tr);
|
|
|
|
var i;
|
|
for (i = 0; i < tiles.length; ++i) {
|
|
var tile = tiles[i];
|
|
|
|
// Ignore any tiles that haven't been set up.
|
|
if (tile.format === -1 || (tile.format === 0 && tile.size === 0)) {
|
|
continue;
|
|
}
|
|
|
|
var vals = [];
|
|
vals.push(i);
|
|
vals.push(getDefine(imageFormatTypes, tile.format));
|
|
vals.push(getDefine(imageSizeTypes, tile.size));
|
|
vals.push(tile.line);
|
|
vals.push(tile.tmem);
|
|
vals.push(tile.palette);
|
|
vals.push(getClampMirrorWrapText(tile.clamp_s, tile.mirror_s));
|
|
vals.push(tile.mask_s);
|
|
vals.push(tile.shift_s);
|
|
vals.push(getClampMirrorWrapText(tile.clamp_t, tile.mirror_t));
|
|
vals.push(tile.mask_t);
|
|
vals.push(tile.shift_t);
|
|
vals.push(tile.left / 4.0);
|
|
vals.push(tile.top / 4.0);
|
|
vals.push(tile.right / 4.0);
|
|
vals.push(tile.bottom / 4.0);
|
|
|
|
$tr = $('<tr><td>' + vals.join('</td><td>') + '</td></tr>');
|
|
$table.append($tr);
|
|
}
|
|
|
|
return $table;
|
|
}
|
|
|
|
function buildRDPTab() {
|
|
|
|
var l = state.rdpOtherModeL;
|
|
var h = state.rdpOtherModeH;
|
|
var vals = {
|
|
alphaCompare: getDefine(alphaCompareValues, l & G_AC_MASK),
|
|
depthSource: getDefine(depthSourceValues, l & G_ZS_MASK),
|
|
renderMode: getRenderModeFlagsText(l),
|
|
|
|
//var G_MDSFT_BLENDMASK = 0;
|
|
alphaDither: getDefine(alphaDitherValues, h & G_AD_MASK),
|
|
colorDither: getDefine(colorDitherValues, h & G_CD_MASK),
|
|
combineKey: getDefine(combineKeyValues, h & G_CK_MASK),
|
|
textureConvert: getDefine(textureConvertValues, h & G_TC_MASK),
|
|
textureFilter: getDefine(textureFilterValues, h & G_TF_MASK),
|
|
textureLUT: getDefine(textureLUTValues, h & G_TT_MASK),
|
|
textureLOD: getDefine(textureLODValues, h & G_TL_MASK),
|
|
texturePersp: getDefine(texturePerspValues, h & G_TP_MASK),
|
|
textureDetail: getDefine(textureDetailValues, h & G_TD_MASK),
|
|
cycleType: getDefine(cycleTypeValues, h & G_CYC_MASK),
|
|
pipelineMode: getDefine(pipelineModeValues, h & G_PM_MASK)
|
|
};
|
|
|
|
var $table = $('<table class="table table-condensed" style="width: auto;"></table>');
|
|
|
|
var $tr, i;
|
|
for (i in vals) {
|
|
if (vals.hasOwnProperty(i)) {
|
|
$tr = $('<tr><td>' + i + '</td><td>' + vals[i] + '</td></tr>');
|
|
$table.append($tr);
|
|
}
|
|
}
|
|
return $table;
|
|
}
|
|
|
|
function buildColorsTable() {
|
|
var $table = $('<table class="table table-condensed" style="width: auto;"></table>');
|
|
|
|
var colors =[
|
|
'fillColor',
|
|
'envColor',
|
|
'primColor',
|
|
'blendColor',
|
|
'fogColor'
|
|
];
|
|
|
|
var i;
|
|
for (i = 0; i < colors.length; ++i) {
|
|
var col = state[colors[i]];
|
|
$('<tr><td>' + colors[i] + '</td><td>' + makeColorTextABGR( col ) + '</td></tr>').appendTo($table);
|
|
}
|
|
|
|
return $table;
|
|
}
|
|
|
|
function buildCombinerTab() {
|
|
|
|
var $p = $('<pre class="combine"></pre>');
|
|
|
|
$p.append(getDefine(cycleTypeValues, getCycleType()) + '\n');
|
|
$p.append(buildColorsTable());
|
|
$p.append(decodeSetCombine(state.combine.hi, state.combine.lo));
|
|
|
|
return $p;
|
|
}
|
|
|
|
var kMulInputRGB = [
|
|
'Combined ', 'Texel0 ',
|
|
'Texel1 ', 'Primitive ',
|
|
'Shade ', 'Env ',
|
|
'KeyScale ', 'CombinedAlph',
|
|
'Texel0_Alpha', 'Texel1_Alpha',
|
|
'Prim_Alpha ', 'Shade_Alpha ',
|
|
'Env_Alpha ', 'LOD_Frac ',
|
|
'PrimLODFrac ', 'K5 ',
|
|
'0 ', '0 ',
|
|
'0 ', '0 ',
|
|
'0 ', '0 ',
|
|
'0 ', '0 ',
|
|
'0 ', '0 ',
|
|
'0 ', '0 ',
|
|
'0 ', '0 ',
|
|
'0 ', '0 '
|
|
];
|
|
var kSubAInputRGB = [
|
|
'Combined ', 'Texel0 ',
|
|
'Texel1 ', 'Primitive ',
|
|
'Shade ', 'Env ',
|
|
'1 ', 'Noise ',
|
|
'0 ', '0 ',
|
|
'0 ', '0 ',
|
|
'0 ', '0 ',
|
|
'0 ', '0 '
|
|
];
|
|
var kSubBInputRGB = [
|
|
'Combined ', 'Texel0 ',
|
|
'Texel1 ', 'Primitive ',
|
|
'Shade ', 'Env ',
|
|
'KeyCenter ', 'K4 ',
|
|
'0 ', '0 ',
|
|
'0 ', '0 ',
|
|
'0 ', '0 ',
|
|
'0 ', '0 '
|
|
];
|
|
var kAddInputRGB = [
|
|
'Combined ', 'Texel0 ',
|
|
'Texel1 ', 'Primitive ',
|
|
'Shade ', 'Env ',
|
|
'1 ', '0 '
|
|
];
|
|
|
|
|
|
var kSubInputA = [
|
|
'Combined ', 'Texel0 ',
|
|
'Texel1 ', 'Primitive ',
|
|
'Shade ', 'Env ',
|
|
'PrimLODFrac ', '0 '
|
|
];
|
|
var kMulInputA = [
|
|
'Combined ', 'Texel0 ',
|
|
'Texel1 ', 'Primitive ',
|
|
'Shade ', 'Env ',
|
|
'1 ', '0 '
|
|
];
|
|
var kAddInputA = [
|
|
'Combined ', 'Texel0 ',
|
|
'Texel1 ', 'Primitive ',
|
|
'Shade ', 'Env ',
|
|
'1 ', '0 '
|
|
];
|
|
|
|
function decodeSetCombine(mux0, mux1) {
|
|
//
|
|
var aRGB0 = (mux0>>>20)&0x0F; // c1 c1 // a0
|
|
var bRGB0 = (mux1>>>28)&0x0F; // c1 c2 // b0
|
|
var cRGB0 = (mux0>>>15)&0x1F; // c1 c3 // c0
|
|
var dRGB0 = (mux1>>>15)&0x07; // c1 c4 // d0
|
|
|
|
var aA0 = (mux0>>>12)&0x07; // c1 a1 // Aa0
|
|
var bA0 = (mux1>>>12)&0x07; // c1 a2 // Ab0
|
|
var cA0 = (mux0>>> 9)&0x07; // c1 a3 // Ac0
|
|
var dA0 = (mux1>>> 9)&0x07; // c1 a4 // Ad0
|
|
|
|
var aRGB1 = (mux0>>> 5)&0x0F; // c2 c1 // a1
|
|
var bRGB1 = (mux1>>>24)&0x0F; // c2 c2 // b1
|
|
var cRGB1 = (mux0>>> 0)&0x1F; // c2 c3 // c1
|
|
var dRGB1 = (mux1>>> 6)&0x07; // c2 c4 // d1
|
|
|
|
var aA1 = (mux1>>>21)&0x07; // c2 a1 // Aa1
|
|
var bA1 = (mux1>>> 3)&0x07; // c2 a2 // Ab1
|
|
var cA1 = (mux1>>>18)&0x07; // c2 a3 // Ac1
|
|
var dA1 = (mux1>>> 0)&0x07; // c2 a4 // Ad1
|
|
|
|
var decoded = '';
|
|
|
|
decoded += 'RGB0 = (' + kSubAInputRGB[aRGB0] + ' - ' + kSubBInputRGB[bRGB0] + ') * ' + kMulInputRGB[cRGB0] + ' + ' + kAddInputRGB[dRGB0] + '\n';
|
|
decoded += ' A0 = (' + kSubInputA [ aA0] + ' - ' + kSubInputA [ bA0] + ') * ' + kMulInputA [ cA0] + ' + ' + kAddInputA [ dA0] + '\n';
|
|
decoded += 'RGB1 = (' + kSubAInputRGB[aRGB1] + ' - ' + kSubBInputRGB[bRGB1] + ') * ' + kMulInputRGB[cRGB1] + ' + ' + kAddInputRGB[dRGB1] + '\n';
|
|
decoded += ' A1 = (' + kSubInputA [ aA1] + ' - ' + kSubInputA [ bA1] + ') * ' + kMulInputA [ cA1] + ' + ' + kAddInputA [ dA1] + '\n';
|
|
|
|
return decoded;
|
|
}
|
|
|
|
|
|
var Base64 = {
|
|
lookup : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
|
|
decodeArray : function (str) {
|
|
if ((str.length % 4) !== 0)
|
|
throw 'Length should be multiple of 4 bytes';
|
|
var outl = (str.length / 4) * 3;
|
|
if (str.charAt(str.length-1) === '=') outl--;
|
|
if (str.charAt(str.length-2) === '=') outl--;
|
|
|
|
var arr = new Uint8Array(outl);
|
|
var outi = 0;
|
|
|
|
var i;
|
|
for (i = 0; i < str.length; i += 4) {
|
|
var a = this.lookup.indexOf(str.charAt(i+0));
|
|
var b = this.lookup.indexOf(str.charAt(i+1));
|
|
var c = this.lookup.indexOf(str.charAt(i+2));
|
|
var d = this.lookup.indexOf(str.charAt(i+3));
|
|
|
|
var c0 = (a << 2) | (b >>> 4);
|
|
var c1 = ((b & 15) << 4) | (c >>> 2);
|
|
var c2 = ((c & 3) << 6) | d;
|
|
|
|
arr[outi++] = c0;
|
|
if (c !== 64) {
|
|
arr[outi++] = c1;
|
|
}
|
|
if (d !== 64) {
|
|
arr[outi++] = c2;
|
|
}
|
|
}
|
|
|
|
if (outi != outl)
|
|
throw "Didn't decode the correct number of bytes";
|
|
|
|
return arr;
|
|
}
|
|
};
|
|
|
|
|
|
function padString(v,len) {
|
|
var t = v.toString();
|
|
while (t.length < len) {
|
|
t = '0' + t;
|
|
}
|
|
return t;
|
|
}
|
|
|
|
function toHex(r, bits) {
|
|
r = Number(r);
|
|
if (r < 0) {
|
|
r = 0xFFFFFFFF + r + 1;
|
|
}
|
|
|
|
var t = r.toString(16);
|
|
|
|
if (bits) {
|
|
var len = Math.floor(bits / 4); // 4 bits per hex char
|
|
while (t.length < len) {
|
|
t = '0' + t;
|
|
}
|
|
}
|
|
|
|
return t;
|
|
}
|
|
|
|
function toString8(v) {
|
|
return '0x' + toHex((v&0xff)>>>0, 8);
|
|
}
|
|
function toString16(v) {
|
|
return '0x' + toHex((v&0xffff)>>>0, 16);
|
|
}
|
|
function toString32(v) {
|
|
return '0x' + toHex(v, 32);
|
|
}
|
|
|
|
function toString64(hi, lo) {
|
|
var t = toHex(lo, 32);
|
|
var u = toHex(hi, 32);
|
|
return '0x' + u + t;
|
|
}
|
|
|
|
var n64js = {};
|
|
n64js.padString = padString;
|
|
n64js.toHex = toHex;
|
|
n64js.toString8 = toString8;
|
|
n64js.toString16 = toString16;
|
|
n64js.toString32 = toString32;
|
|
n64js.toString64 = toString64;
|
|
|
|
}(window.daedalus = window.daedalus || {}));
|
|
|
|
$(document).ready(function(){
|
|
daedalus.init();
|
|
});
|