mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2024-11-25 18:33:11 +00:00
working on pixel editor
This commit is contained in:
parent
15e6efd01d
commit
112cbeda1e
20
css/ui.css
20
css/ui.css
@ -48,13 +48,13 @@
|
|||||||
left:0;
|
left:0;
|
||||||
right:0;
|
right:0;
|
||||||
background-color: #666;
|
background-color: #666;
|
||||||
overflow: hidden;;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
div.workspace {
|
#workspace {
|
||||||
background-color:#999;
|
background-color:#333;
|
||||||
|
width:50%;
|
||||||
}
|
}
|
||||||
div.editor {
|
div.editor {
|
||||||
width:50%;
|
|
||||||
line-height:1.25;
|
line-height:1.25;
|
||||||
font-size:12pt;
|
font-size:12pt;
|
||||||
}
|
}
|
||||||
@ -182,6 +182,8 @@ a.dropdown-toggle {
|
|||||||
border-radius:6px 0 6px 6px;
|
border-radius:6px 0 6px 6px;
|
||||||
}
|
}
|
||||||
.emubevel {
|
.emubevel {
|
||||||
|
width:100%;
|
||||||
|
height:100%;
|
||||||
padding:4%;
|
padding:4%;
|
||||||
background:#333;
|
background:#333;
|
||||||
}
|
}
|
||||||
@ -204,3 +206,13 @@ canvas.pixelated {
|
|||||||
image-rendering: pixelated; /* Awesome future-browsers */
|
image-rendering: pixelated; /* Awesome future-browsers */
|
||||||
-ms-interpolation-mode: nearest-neighbor; /* IE */
|
-ms-interpolation-mode: nearest-neighbor; /* IE */
|
||||||
}
|
}
|
||||||
|
.palbtn {
|
||||||
|
width:2em;
|
||||||
|
height:2em;
|
||||||
|
border-style:none;
|
||||||
|
}
|
||||||
|
.selected {
|
||||||
|
border-width:2px;
|
||||||
|
border-color:white;
|
||||||
|
border-style:dotted;
|
||||||
|
}
|
||||||
|
54
index.html
54
index.html
@ -7,6 +7,21 @@ body {
|
|||||||
overflow: hidden !important;
|
overflow: hidden !important;
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
}
|
}
|
||||||
|
.pixeditback {
|
||||||
|
position:absolute;
|
||||||
|
z-index:100;
|
||||||
|
width:100%;
|
||||||
|
height:100%;
|
||||||
|
padding:50px;
|
||||||
|
border-width:4px;
|
||||||
|
border-color:#333;
|
||||||
|
border-style:solid;
|
||||||
|
background-color:rgba(64, 64, 64, 0.5);
|
||||||
|
}
|
||||||
|
#pixeditframe {
|
||||||
|
width:100%;
|
||||||
|
height:100%;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
<link rel="stylesheet" href="css/ui.css">
|
<link rel="stylesheet" href="css/ui.css">
|
||||||
</head>
|
</head>
|
||||||
@ -61,6 +76,9 @@ body {
|
|||||||
<button id="dbg_memory" type="submit" title="Show Memory" style="display:none"><span class="glyphicon glyphicon-sunglasses" aria-hidden="true"></span></button>
|
<button id="dbg_memory" type="submit" title="Show Memory" style="display:none"><span class="glyphicon glyphicon-sunglasses" aria-hidden="true"></span></button>
|
||||||
<button id="dbg_profile" type="submit" title="Show Profile" style="display:none"><span class="glyphicon glyphicon-stats" aria-hidden="true"></span></button>
|
<button id="dbg_profile" type="submit" title="Show Profile" style="display:none"><span class="glyphicon glyphicon-stats" aria-hidden="true"></span></button>
|
||||||
</span>
|
</span>
|
||||||
|
<span class="btn_group view_group" id="tools_bar">
|
||||||
|
<button id="dbg_bitmap" type="submit" title="Edit Bitmap"><span class="glyphicon glyphicon-camera" aria-hidden="true"></span></button>
|
||||||
|
</span>
|
||||||
<span id="best_in_firefox" style="display:none;font-size:12px;font-style:italic;float:right;color:#666">Note: Works best in Firefox</span>
|
<span id="best_in_firefox" style="display:none;font-size:12px;font-style:italic;float:right;color:#666">Note: Works best in Firefox</span>
|
||||||
</div>
|
</div>
|
||||||
<div id="notebook">
|
<div id="notebook">
|
||||||
@ -99,39 +117,9 @@ body {
|
|||||||
<a target="_new" href="https://www.amazon.com/Making-8-bit-Arcade-Games-C/dp/1545484759">
|
<a target="_new" href="https://www.amazon.com/Making-8-bit-Arcade-Games-C/dp/1545484759">
|
||||||
Making 8-bit Arcade Games in C</a>
|
Making 8-bit Arcade Games in C</a>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="pixeditback" class="pixeditback" style="display:none">
|
||||||
<div id="welcomeModal" class="modal fade">
|
<iframe id="pixeditframe" src="pixels.html">
|
||||||
<div class="modal-dialog modal-lg" role="document">
|
</iframe>
|
||||||
<div class="modal-content">
|
|
||||||
<div class="modal-header">
|
|
||||||
<h3 class="modal-title">Welcome to 8bitworkshop!</h3>
|
|
||||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
|
||||||
<span aria-hidden="true">×</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="modal-body">
|
|
||||||
<p>What would you like to start programming?</p>
|
|
||||||
<div class="container-fluid">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-6">
|
|
||||||
<img data-dismiss="modal" class="img-responsive" data-platform="vcs" src="images/atarivcs.jpg" alt="Atari 2600 four-switch wood veneer version, dating from 1980-1982 (photo by Evan Amos)"/>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-6">
|
|
||||||
<img data-dismiss="modal" class="img-responsive" data-platform="vicdual" src="images/arcadegames.jpg" alt="Galaxian arcade system board (photo by Dennis van Zuijlekom, CC BY-SA 2.0)"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-3 col-md-offset-2">
|
|
||||||
<button type="button" class="btn btn-secondary" data-platform="vcs" data-dismiss="modal">Atari VCS</button>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-3 col-md-offset-2">
|
|
||||||
<button type="button" class="btn btn-secondary" data-platform="vicdual" data-dismiss="modal">Arcade Games</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="jquery/jquery-2.2.3.min.js"></script>
|
<script src="jquery/jquery-2.2.3.min.js"></script>
|
||||||
|
71
pixels.html
Normal file
71
pixels.html
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<title>8bitworkshop Pixel Editor</title>
|
||||||
|
<style type="text/css" media="screen">
|
||||||
|
body {
|
||||||
|
overflow: hidden !important;
|
||||||
|
font-size: 11px;
|
||||||
|
}
|
||||||
|
.pixels {
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<link rel="stylesheet" href="css/ui.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div id="controls_top">
|
||||||
|
<span id="palette_group" class="palette_group">
|
||||||
|
</span>
|
||||||
|
<span style="float:right">
|
||||||
|
<button id="btn_cancel" type="submit" title="Cancel">Discard <span class="glyphicon glyphicon-remove" aria-hidden="true"></span></button>
|
||||||
|
<button id="btn_saveandclose" type="submit" title="Save and Close">Save and Close <span class="glyphicon glyphicon-save" aria-hidden="true"></span></button>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="notebook">
|
||||||
|
<div id="maineditor" class="emubevel">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="jquery/jquery-2.2.3.min.js"></script>
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="bootstrap/css/bootstrap.min.css">
|
||||||
|
<script src="bootstrap/js/bootstrap.min.js"></script>
|
||||||
|
<script src="FileSaver.js/FileSaver.min.js"></script>
|
||||||
|
<script src="src/util.js"></script>
|
||||||
|
<script src="src/pixed/pixeleditor.js"></script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
if (window.self === window.top) {
|
||||||
|
/*
|
||||||
|
var datastr = "{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, { 0x7e,0x81,0x95,0xb1,0xb1,0x95,0x81,0x7e }, { 0x7e,0xff,0xeb,0xcf,0xcf,0xeb,0xff,0x7e }, { 0x0e,0x1f,0x3f,0x7e,0x3f,0x1f,0x0e,0x00 }, { 0x08,0x1c,0x3e,0x7f,0x3e,0x1c,0x08,0x00 }, { 0x38,0x3a,0x9f,0xff,0x9f,0x3a,0x38,0x00 }, { 0x10,0x38,0xbc,0xff,0xbc,0x38,0x10,0x00 }, { 0x00,0x00,0x18,0x3c,0x3c,0x18,0x00,0x00 }, { 0xff,0xff,0xe7,0xc3,0xc3,0xe7,0xff,0xff }, { 0x00,0x3c,0x66,0x42,0x42,0x66,0x3c,0x00 }";
|
||||||
|
var fmt = {w:8,h:8,bpp:1,count:8};
|
||||||
|
var palette = [0xff000000, 0xffffffff];
|
||||||
|
*/
|
||||||
|
var paldatastr = " 0x00, 0x03, 0x19, 0x50, 0x52, 0x07, 0x1f, 0x37, 0xe0, 0xa4, 0xfd, 0xff, 0x38, 0x70, 0x7f, 0xf8, ";
|
||||||
|
var fmt = {w:14,h:16,bpp:4,brev:1};
|
||||||
|
var datastr = "0x00,0x00,0xef,0xef,0xe0,0x00,0x00, 0x00,0xee,0xee,0xfe,0xee,0xe0,0x00, 0x0e,0xed,0xef,0xef,0xed,0xee,0x00, 0x0e,0xee,0xdd,0xdd,0xde,0xee,0x00, 0x0e,0xee,0xed,0xde,0xee,0xee,0x00, 0x00,0xee,0xee,0xde,0xee,0xe0,0x00, 0x00,0xee,0xee,0xde,0xee,0xe0,0x00, 0x00,0x00,0xed,0xdd,0xe0,0x00,0x0d, 0xdd,0xdd,0xee,0xee,0xed,0xdd,0xd0, 0x0d,0xee,0xee,0xee,0xee,0xee,0x00, 0x0e,0xe0,0xee,0xee,0xe0,0xee,0x00, 0x0e,0xe0,0xee,0xee,0xe0,0xee,0x00, 0x0e,0xe0,0xdd,0xdd,0xd0,0xde,0x00, 0x0d,0x00,0xee,0x0e,0xe0,0x0d,0x00, 0x00,0x00,0xed,0x0e,0xe0,0x00,0x00, 0x00,0x0d,0xdd,0x0d,0xdd,0x00,0x18,";
|
||||||
|
pixelEditorReceiveMessage({data:{fmt:fmt,bytestr:datastr,palfmt:{pal:332,n:16},palstr:paldatastr}});
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
window.addEventListener("message", pixelEditorReceiveMessage, false);
|
||||||
|
window.addEventListener("resize", pixelEditorResize, false);
|
||||||
|
window.addEventListener("keypress", pixelEditorKeypress, false);
|
||||||
|
|
||||||
|
$("#btn_cancel").click(function(e) {
|
||||||
|
if (confirm("Sure you want to cancel and discard?")) {
|
||||||
|
postToParentWindow({close:true});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
$("#btn_saveandclose").click(function(e) {
|
||||||
|
postToParentWindow({close:true,save:true});
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -63,7 +63,6 @@ struct {
|
|||||||
//
|
//
|
||||||
|
|
||||||
void main();
|
void main();
|
||||||
void _sdcc_heap_init(void); // for malloc()
|
|
||||||
|
|
||||||
// start routine @ 0x0
|
// start routine @ 0x0
|
||||||
// set stack pointer, enable interrupts
|
// set stack pointer, enable interrupts
|
||||||
@ -79,7 +78,6 @@ __asm
|
|||||||
LDIR
|
LDIR
|
||||||
__endasm;
|
__endasm;
|
||||||
|
|
||||||
_sdcc_heap_init();
|
|
||||||
main();
|
main();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,8 +11,6 @@ function noise() {
|
|||||||
function __createCanvas(mainElement, width, height) {
|
function __createCanvas(mainElement, width, height) {
|
||||||
// TODO
|
// TODO
|
||||||
var fsElement = document.createElement('div');
|
var fsElement = document.createElement('div');
|
||||||
fsElement.style.position = "relative";
|
|
||||||
fsElement.style.overflow = "hidden";
|
|
||||||
fsElement.classList.add("emubevel");
|
fsElement.classList.add("emubevel");
|
||||||
|
|
||||||
var canvas = document.createElement('canvas');
|
var canvas = document.createElement('canvas');
|
||||||
|
304
src/pixed/pixeleditor.js
Normal file
304
src/pixed/pixeleditor.js
Normal file
@ -0,0 +1,304 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
function PixelEditor(parentDiv, width, height, palette, initialData) {
|
||||||
|
|
||||||
|
function createCanvas() {
|
||||||
|
var c = document.createElement('canvas');
|
||||||
|
c.width = width;
|
||||||
|
c.height = height;
|
||||||
|
c.classList.add("pixels");
|
||||||
|
c.classList.add("pixelated");
|
||||||
|
//canvas.tabIndex = "-1"; // Make it focusable
|
||||||
|
$(parentDiv).empty().append(c);
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateImage() {
|
||||||
|
ctx.putImageData(pixdata, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function fitCanvas() {
|
||||||
|
var w = $(parentDiv).width();
|
||||||
|
var h = $(parentDiv).height();
|
||||||
|
pixcanvas.style.height = Math.floor(h)+"px";
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
this.resize = fitCanvas;
|
||||||
|
|
||||||
|
palette = new Uint32Array(palette);
|
||||||
|
var pixcanvas = createCanvas();
|
||||||
|
var ctx = pixcanvas.getContext('2d');
|
||||||
|
var pixdata = ctx.createImageData(pixcanvas.width, pixcanvas.height);
|
||||||
|
var pixints = new Uint32Array(pixdata.data.buffer);
|
||||||
|
for (var i=0; i<pixints.length; i++) {
|
||||||
|
pixints[i] = initialData ? palette[initialData[i]] : palette[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
updateImage();
|
||||||
|
fitCanvas();
|
||||||
|
createPaletteButtons();
|
||||||
|
|
||||||
|
function revrgb(x) {
|
||||||
|
var y = 0;
|
||||||
|
y |= ((x >> 0) & 0xff) << 16;
|
||||||
|
y |= ((x >> 8) & 0xff) << 8;
|
||||||
|
y |= ((x >> 16) & 0xff) << 0;
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
function createPaletteButtons() {
|
||||||
|
var span = $("#palette_group").empty();
|
||||||
|
for (var i=0; i<palette.length; i++) {
|
||||||
|
var btn = $('<button class="palbtn">');
|
||||||
|
var rgb = palette[i] & 0xffffff;
|
||||||
|
var color = "#" + hex(revrgb(rgb), 6);
|
||||||
|
btn.click(setCurrentColor.bind(this, i));
|
||||||
|
btn.attr('id', 'palcol_' + i);
|
||||||
|
btn.css('backgroundColor', color).text(i.toString(16));
|
||||||
|
if ((rgb & 0x808080) != 0x808080) { btn.css('color', 'white'); }
|
||||||
|
span.append(btn);
|
||||||
|
}
|
||||||
|
setCurrentColor(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPixelByOffset(ofs) {
|
||||||
|
var oldrgba = pixints[ofs];
|
||||||
|
for (var i=0; i<palette.length; i++) {
|
||||||
|
if (oldrgba == palette[i]) return i;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPixel(x, y) {
|
||||||
|
var ofs = x+y*pixcanvas.width;
|
||||||
|
return getPixelByOffset(ofs);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setPixel(x, y, col) {
|
||||||
|
var ofs = x+y*pixcanvas.width;
|
||||||
|
var oldrgba = pixints[ofs];
|
||||||
|
var rgba = palette[col];
|
||||||
|
if (oldrgba != rgba) {
|
||||||
|
pixints[ofs] = rgba;
|
||||||
|
updateImage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPositionFromEvent(e) {
|
||||||
|
var x = Math.floor(e.offsetX * width / pxls.width());
|
||||||
|
var y = Math.floor(e.offsetY * height / pxls.height());
|
||||||
|
return {x:x, y:y};
|
||||||
|
}
|
||||||
|
|
||||||
|
function setCurrentColor(col) {
|
||||||
|
if (curpalcol != col) {
|
||||||
|
if (curpalcol >= 0)
|
||||||
|
$("#palcol_" + curpalcol).removeClass('selected');
|
||||||
|
curpalcol = col;
|
||||||
|
$("#palcol_" + col).addClass('selected');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.setCurrentColor = setCurrentColor;
|
||||||
|
|
||||||
|
var curpalcol = -1;
|
||||||
|
setCurrentColor(1);
|
||||||
|
|
||||||
|
var dragcol = 1;
|
||||||
|
var dragging = false;
|
||||||
|
|
||||||
|
var pxls = $(pixcanvas);
|
||||||
|
pxls.mousedown(function(e) {
|
||||||
|
var pos = getPositionFromEvent(e);
|
||||||
|
dragcol = getPixel(pos.x, pos.y) == curpalcol ? 0 : curpalcol;
|
||||||
|
setPixel(pos.x, pos.y, curpalcol);
|
||||||
|
dragging = true;
|
||||||
|
})
|
||||||
|
.mousemove(function(e) {
|
||||||
|
var pos = getPositionFromEvent(e);
|
||||||
|
if (dragging) {
|
||||||
|
setPixel(pos.x, pos.y, dragcol);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.mouseup(function(e) {
|
||||||
|
var pos = getPositionFromEvent(e);
|
||||||
|
setPixel(pos.x, pos.y, dragcol);
|
||||||
|
dragging = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
this.getImageColors = function() {
|
||||||
|
var pixcols = new Uint8Array(pixints.length);
|
||||||
|
for (var i=0; i<pixints.length; i++)
|
||||||
|
pixcols[i] = getPixelByOffset(i);
|
||||||
|
return pixcols;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseHexBytes(s) {
|
||||||
|
var arr = [];
|
||||||
|
var re = /0x([0-9a-f]+)/gi;
|
||||||
|
var m;
|
||||||
|
while (m = re.exec(s)) {
|
||||||
|
if (m[0].startsWith('0x'))
|
||||||
|
arr.push(parseInt(m[1],16));
|
||||||
|
else
|
||||||
|
arr.push(parseInt(m[1]));
|
||||||
|
}
|
||||||
|
return arr;
|
||||||
|
}
|
||||||
|
|
||||||
|
function replaceHexBytes(s, bytes) {
|
||||||
|
var result = "";
|
||||||
|
var re = /0x([0-9a-f]+)/gi;
|
||||||
|
var m;
|
||||||
|
var li = 0;
|
||||||
|
var i = 0;
|
||||||
|
while (m = re.exec(s)) {
|
||||||
|
result += s.slice(li, re.lastIndex - m[0].length);
|
||||||
|
li = re.lastIndex;
|
||||||
|
if (m[0].startsWith('0x'))
|
||||||
|
result += "0x" + hex(bytes[i++]);
|
||||||
|
else
|
||||||
|
result += bytes[i++].toString();
|
||||||
|
}
|
||||||
|
result += s.slice(li);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function convertBytesToImages(bytes, fmt) {
|
||||||
|
var count = fmt.count ? fmt.count : 1;
|
||||||
|
var width = fmt.w;
|
||||||
|
var height = fmt.h;
|
||||||
|
var bytesperline = fmt.sl ? fmt.sl : Math.ceil(fmt.w * fmt.bpp / 8);
|
||||||
|
//console.log(width,height,bytesperline);
|
||||||
|
var mask = (1 << fmt.bpp)-1;
|
||||||
|
var images = [];
|
||||||
|
var nplanes = fmt.np ? fmt.np : 1;
|
||||||
|
for (var n=0; n<count; n++) {
|
||||||
|
var imgdata = [];
|
||||||
|
for (var y=0; y<height; y++) {
|
||||||
|
var ofs = n*bytesperline*height + y*bytesperline;
|
||||||
|
var shift = 0;
|
||||||
|
for (var x=0; x<width; x++) {
|
||||||
|
var color = 0;
|
||||||
|
for (var p=0; p<nplanes; p++) {
|
||||||
|
var byte = bytes[ofs + p*(fmt.pofs|0)];
|
||||||
|
color |= ((fmt.brev ? byte>>(8-shift-fmt.bpp) : byte>>shift) & mask) << (p*fmt.bpp);
|
||||||
|
}
|
||||||
|
imgdata.push(color);
|
||||||
|
shift += fmt.bpp;
|
||||||
|
if (shift >= 8) {
|
||||||
|
ofs += 1;
|
||||||
|
shift = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
images.push(imgdata);
|
||||||
|
}
|
||||||
|
return images;
|
||||||
|
}
|
||||||
|
|
||||||
|
function convertImagesToBytes(images, fmt) {
|
||||||
|
var count = fmt.count ? fmt.count : 1;
|
||||||
|
var width = fmt.w;
|
||||||
|
var height = fmt.h;
|
||||||
|
var bytesperline = fmt.sl ? fmt.sl : Math.ceil(fmt.w * fmt.bpp / 8);
|
||||||
|
var mask = (1 << fmt.bpp)-1;
|
||||||
|
var nplanes = fmt.np ? fmt.np : 1;
|
||||||
|
var i = 0;
|
||||||
|
var bytes = new Uint8Array(bytesperline * height * nplanes * count);
|
||||||
|
for (var n=0; n<count; n++) {
|
||||||
|
var imgdata = images[n];
|
||||||
|
for (var y=0; y<height; y++) {
|
||||||
|
var ofs = n*bytesperline*height + y*bytesperline;
|
||||||
|
var shift = 0;
|
||||||
|
for (var x=0; x<width; x++) {
|
||||||
|
var color = imgdata[i++];
|
||||||
|
for (var p=0; p<nplanes; p++) {
|
||||||
|
bytes[ofs + p*(fmt.pofs|0)] |= fmt.brev ? (color << (8-shift-fmt.bpp)) : (color << shift);
|
||||||
|
/* TODO
|
||||||
|
var byte = bytes[ofs + p*(fmt.pofs|0)];
|
||||||
|
color |= ((fmt.brev ? byte>>(8-shift-fmt.bpp) : byte>>shift) & mask) << (p*fmt.bpp);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
shift += fmt.bpp;
|
||||||
|
if (shift >= 8) {
|
||||||
|
ofs += 1;
|
||||||
|
shift = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
function convertPaletteBytes(arr,r0,r1,g0,g1,b0,b1) {
|
||||||
|
var result = [];
|
||||||
|
for (var i=0; i<arr.length; i++) {
|
||||||
|
var d = arr[i];
|
||||||
|
var rgb = 0xff000000;
|
||||||
|
rgb |= ((d >> r0) & ((1<<r1)-1)) << (0+8-r1);
|
||||||
|
rgb |= ((d >> g0) & ((1<<g1)-1)) << (8+8-g1);
|
||||||
|
rgb |= ((d >> b0) & ((1<<b1)-1)) << (16+8-b1);
|
||||||
|
result.push(rgb);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
var currentPixelEditor;
|
||||||
|
var parentSource;
|
||||||
|
var parentOrigin;
|
||||||
|
var allimages;
|
||||||
|
var currentFormat;
|
||||||
|
var currentByteStr;
|
||||||
|
var currentPaletteStr;
|
||||||
|
var currentPaletteFmt;
|
||||||
|
|
||||||
|
function pixelEditorReceiveMessage(e) {
|
||||||
|
console.log(e.data);
|
||||||
|
parentSource = e.source;
|
||||||
|
parentOrigin = e.origin;
|
||||||
|
currentFormat = e.data.fmt;
|
||||||
|
currentByteStr = e.data.bytestr;
|
||||||
|
currentPaletteFmt = e.data.palfmt;
|
||||||
|
currentPaletteStr = e.data.palstr;
|
||||||
|
var bytes = parseHexBytes(e.data.bytestr);
|
||||||
|
allimages = convertBytesToImages(bytes, e.data.fmt);
|
||||||
|
var palette = [0xff000000, 0xffffffff]; // TODO
|
||||||
|
if (currentPaletteStr) {
|
||||||
|
var palbytes = parseHexBytes(e.data.palstr);
|
||||||
|
var rr = Math.floor(Math.abs(currentPaletteFmt.pal/100) % 10);
|
||||||
|
var gg = Math.floor(Math.abs(currentPaletteFmt.pal/10) % 10);
|
||||||
|
var bb = Math.floor(Math.abs(currentPaletteFmt.pal) % 10);
|
||||||
|
if (currentPaletteFmt.pal >= 0)
|
||||||
|
palette = convertPaletteBytes(palbytes, 0, rr, rr, gg, rr+gg, bb);
|
||||||
|
else
|
||||||
|
palette = convertPaletteBytes(palbytes, rr+gg, bb, rr, gg, 0, rr);
|
||||||
|
}
|
||||||
|
currentPixelEditor = new PixelEditor(maineditor, e.data.fmt.w, e.data.fmt.h, palette, allimages[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function postToParentWindow(data) {
|
||||||
|
if (data.save) {
|
||||||
|
allimages[0] = currentPixelEditor.getImageColors();
|
||||||
|
data.bytes = convertImagesToBytes(allimages, currentFormat);
|
||||||
|
data.bytestr = replaceHexBytes(currentByteStr, data.bytes);
|
||||||
|
}
|
||||||
|
parentSource.postMessage(data, "*");
|
||||||
|
}
|
||||||
|
|
||||||
|
function pixelEditorResize(e) {
|
||||||
|
if (currentPixelEditor) {
|
||||||
|
currentPixelEditor.resize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function pixelEditorKeypress(e) {
|
||||||
|
if (!currentPixelEditor) return;
|
||||||
|
var c = e.charCode;
|
||||||
|
if (c >= 48 && c <= 57) {
|
||||||
|
currentPixelEditor.setCurrentColor(c-48);
|
||||||
|
} else if (c >= 97 && c <= 102) {
|
||||||
|
currentPixelEditor.setCurrentColor(c-97+10);
|
||||||
|
}
|
||||||
|
}
|
60
src/ui.js
60
src/ui.js
@ -390,6 +390,7 @@ function invertMap(m) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function setCompileOutput(data) {
|
function setCompileOutput(data) {
|
||||||
|
// TODO: kills current selection
|
||||||
sourcefile = new SourceFile(data.lines);
|
sourcefile = new SourceFile(data.lines);
|
||||||
if (data.asmlines) {
|
if (data.asmlines) {
|
||||||
assemblyfile = new SourceFile(data.asmlines, data.intermediate.listing);
|
assemblyfile = new SourceFile(data.asmlines, data.intermediate.listing);
|
||||||
@ -1006,6 +1007,61 @@ function toggleProfileWindow() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleWindowMessage(e) {
|
||||||
|
console.log("window message", e.data);
|
||||||
|
if (e.data.bytes) {
|
||||||
|
editor.replaceSelection(e.data.bytestr);
|
||||||
|
}
|
||||||
|
if (e.data.close) {
|
||||||
|
$("#pixeditback").hide(250);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function openBitmapEditorWithParams(fmt, bytestr, palfmt, palstr) {
|
||||||
|
$("#pixeditback").show(250);
|
||||||
|
pixeditframe.contentWindow.postMessage({fmt:fmt, bytestr:bytestr, palfmt:palfmt, palstr:palstr}, '*');
|
||||||
|
}
|
||||||
|
|
||||||
|
function lookBackwardsForJSONComment(line) {
|
||||||
|
var re = /[/][*]([{].+[}])[*][/]/;
|
||||||
|
while (--line >= 0) {
|
||||||
|
var s = editor.getLine(line);
|
||||||
|
var m = re.exec(s);
|
||||||
|
if (m) {
|
||||||
|
var jsontxt = m[1].replace(/([A-Za-z]+):/g, '"$1":'); // fix lenient JSON
|
||||||
|
var obj = JSON.parse(jsontxt);
|
||||||
|
var start = {obj:obj, line:line, ch:s.indexOf(m[0])+m[0].length};
|
||||||
|
line--;
|
||||||
|
while (++line < editor.lineCount()) {
|
||||||
|
if (editor.getLine(line).indexOf(';') >= 0) {
|
||||||
|
var end = {line:line, ch:editor.getLine(line).length};
|
||||||
|
return {obj:obj, start:start, end:end};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function openBitmapEditorAtCursor() {
|
||||||
|
if ($("#pixeditback").is(":visible")) {
|
||||||
|
$("#pixeditback").hide(250);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var data = lookBackwardsForJSONComment(getCurrentLine());
|
||||||
|
if (data && data.obj && data.obj.w>0 && data.obj.h>0 && data.obj.bpp>0) {
|
||||||
|
var paldata = lookBackwardsForJSONComment(data.start.line-1);
|
||||||
|
var palbytestr;
|
||||||
|
if (paldata) {
|
||||||
|
palbytestr = editor.getRange(paldata.start, paldata.end);
|
||||||
|
paldata = paldata.obj;
|
||||||
|
}
|
||||||
|
editor.setSelection(data.end, data.start);
|
||||||
|
openBitmapEditorWithParams(data.obj, editor.getSelection(), paldata, palbytestr);
|
||||||
|
} else {
|
||||||
|
alert("No bitmap spec found in format /*{w:,h:,bpp:,count:...}*/");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function setupDebugControls(){
|
function setupDebugControls(){
|
||||||
$("#dbg_reset").click(resetAndDebug);
|
$("#dbg_reset").click(resetAndDebug);
|
||||||
$("#dbg_pause").click(pause);
|
$("#dbg_pause").click(pause);
|
||||||
@ -1027,6 +1083,7 @@ function setupDebugControls(){
|
|||||||
$("#dbg_disasm").click(toggleDisassembly).show();
|
$("#dbg_disasm").click(toggleDisassembly).show();
|
||||||
}
|
}
|
||||||
$("#disassembly").hide();
|
$("#disassembly").hide();
|
||||||
|
$("#dbg_bitmap").click(openBitmapEditorAtCursor);
|
||||||
$(".dropdown-menu").collapse({toggle: false});
|
$(".dropdown-menu").collapse({toggle: false});
|
||||||
$("#item_new_file").click(_createNewFile);
|
$("#item_new_file").click(_createNewFile);
|
||||||
$("#item_share_file").click(_shareFile);
|
$("#item_share_file").click(_shareFile);
|
||||||
@ -1076,7 +1133,6 @@ function showWelcomeMessage() {
|
|||||||
tour.init();
|
tour.init();
|
||||||
setTimeout(function() { tour.start(); }, 2000);
|
setTimeout(function() { tour.start(); }, 2000);
|
||||||
}
|
}
|
||||||
if (qs['redir']) delete qs['redir'];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////
|
///////////////////////////////////////////////////
|
||||||
@ -1155,7 +1211,6 @@ function startPlatform() {
|
|||||||
// try to load last file (redirect)
|
// try to load last file (redirect)
|
||||||
var lastid = localStorage.getItem("__lastid_"+platform_id) || localStorage.getItem("__lastid");
|
var lastid = localStorage.getItem("__lastid_"+platform_id) || localStorage.getItem("__lastid");
|
||||||
localStorage.removeItem("__lastid");
|
localStorage.removeItem("__lastid");
|
||||||
qs['redir'] = '1';
|
|
||||||
gotoPresetNamed(lastid || PRESETS[0].id);
|
gotoPresetNamed(lastid || PRESETS[0].id);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1186,6 +1241,7 @@ function loadSharedFile(sharekey) {
|
|||||||
// start
|
// start
|
||||||
function startUI(loadplatform) {
|
function startUI(loadplatform) {
|
||||||
installErrorHandler();
|
installErrorHandler();
|
||||||
|
window.addEventListener("message", handleWindowMessage, false);
|
||||||
// add default platform?
|
// add default platform?
|
||||||
platform_id = qs['platform'] || localStorage.getItem("__lastplatform");
|
platform_id = qs['platform'] || localStorage.getItem("__lastplatform");
|
||||||
if (!platform_id) {
|
if (!platform_id) {
|
||||||
|
Loading…
Reference in New Issue
Block a user