tag:blogger.com,1999:blog-79991595214238643172024-03-13T15:23:54.964-07:00F.L.A.S.W.F"I program, I dream."
Bruce Jawn's flash blogBrucehttp://www.blogger.com/profile/08115632286488544449noreply@blogger.comBlogger107125tag:blogger.com,1999:blog-7999159521423864317.post-78100303894564464702019-09-17T20:01:00.001-07:002019-09-17T20:03:43.618-07:00Save and Load Binary Files in HTML5<link href="https://sites.google.com/site/flaswfblogger/prism.css" rel="stylesheet"></link>
<script src="https://sites.google.com/site/flaswfblogger/prism.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.0/clipboard.min.js"></script>
In this example, we firstly draw something (shapes & lines) on the canvas, convert it into a bitmap (pixel data) and save the pixel values as a binary file.
<br />
<pre><code class="language-js">//Draw something
ctx.fillStyle = "red";
ctx.fillRect(0, 0, 60, 60);
ctx.beginPath();
ctx.rect(60, 60, 160, 80);
ctx.fillStyle = "blue";
ctx.fill();
ctx.beginPath();
ctx.lineWidth = "5";
ctx.strokeStyle = "green";
ctx.moveTo(6, 160);
ctx.lineTo(240, 360);
ctx.lineTo(60, 800);
ctx.lineTo(800, 60);
ctx.stroke();//draw
//Convert canvas draws into pixels
var buffer = ctx.getImageData(0, 0, w, h);
//https://stackoverflow.com/questions/23451726/saving-binary-data-as-file-using-javascript-from-a-browser
var saveByteArray = (function () {
var a = document.createElement("a");
document.body.appendChild(a);
a.style = "display: none";
return function (data, name) {
var blob = new Blob(data, {type: "octet/stream"}),
url = window.URL.createObjectURL(blob);
a.href = url;
a.download = name;
a.click();
window.URL.revokeObjectURL(url);
};
}());
//Save pixel data (ArrayBuffer) as binary file
saveByteArray([buffer.data], 'example.bf');
</code></pre>
<br />
Then we load the binary file and display the pixel values it stores (as a bitmap) using a new canvas.
<br />
<pre><code class="language-js">//The requestAnimFrame fallback for better and smoother animation
var buffer = ctx.createImageData(w, h);
//http://qnimate.com/an-introduction-to-javascript-blobs-and-file-interface/
var xhr = new XMLHttpRequest();
xhr.open("GET", "./example.bf");
//although we can get the remote data directly into an arraybuffer using the string "arraybuffer" assigned to responseType property. For the sake of example we are putting it into a blob and then copying the blob data into an arraybuffer.
xhr.responseType = "blob";
function analyze_data(blob)
{
var myReader = new FileReader();
myReader.readAsArrayBuffer(blob);
myReader.addEventListener("loadend", function(e)
{
var buf = e.srcElement.result;//arraybuffer object
var buf8 = new Uint8ClampedArray(buf);//first view for copy pixel data to ImageData
var data = new Uint32Array(buf);//second view for setting pixel values
buffer.data.set(buf8);
//we use putImageData() to copy the image data back to the canvas.
ctx.putImageData(buffer, 0, 0);
});
}
xhr.onload = function()
{
analyze_data(xhr.response);
}
xhr.send();
</code></pre>
<br />
Demo & Full Source Code: <a href="http://vvv.flaswf.tk/demo/?url=HTML5SaveLoadBF%2FSave">Create & Save</a>, <a href="http://vvv.flaswf.tk/demo/?url=HTML5SaveLoadBF%2FLoad">Load & Show</a><br />
<br /><div class="blogger-post-footer"><script>
var adfly_id = 821527;
var adfly_advert = 'banner';
var exclude_domains = ['blogger.com', 'blogspot.','amazon.com','chitika.net'];
</script>
<script src="http://adf.ly/js/link-converter.js"></script></div>Brucehttp://www.blogger.com/profile/08115632286488544449noreply@blogger.com1tag:blogger.com,1999:blog-7999159521423864317.post-82307468125898623362019-09-09T20:15:00.000-07:002019-09-09T20:15:04.978-07:00Fast per pixel bitmap animation in HTML5<link href="https://sites.google.com/site/flaswfblogger/prism.css" rel="stylesheet"></link>
<script src="https://sites.google.com/site/flaswfblogger/prism.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.0/clipboard.min.js"></script>
According to this <a href="https://hacks.mozilla.org/2011/12/faster-canvas-pixel-manipulation-with-typed-arrays/">tutorial (Faster Canvas Pixel Manipulation with Typed Arrays)</a>, we can make the code in my <a href="http://bruce-lab.blogspot.com/2019/08/per-pixel-animation-html5-js.html">last post (per pixel bitmap animation in HTML5/JavaScript)</a> faster using Typed Arrays:
<br />
<pre data-line="43-45,56-60,68"><code class="language-js">//The requestAnimFrame fallback for better and smoother animation
window.requestAnimFrame = (function () {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame || window.oRequestAnimationFrame ||
window.msRequestAnimationFrame || function (callback) {
window.setTimeout(callback, 1000 / 60);
};
})();
//Prepare our canvas
var canvas = document.querySelector('#render');
var w = window.innerWidth;
var h = window.innerHeight;
canvas.width = w;
canvas.height = h;
var ctx = canvas.getContext('2d');
var time = Date.now();//record initial time
var buffer = ctx.createImageData(w, h);//The back buffer we used to paint the result into the canvas
//The main render function
//Calculate a color value from elapsed time and [x,y] coordinates (scaled to [0,1])
function render(time, fragcoord) {
/* put the GLSL fragment shader's JavaScript equivalent here. */
//begin of per pixel bitmap manipulation
var x = fragcoord[0]; var y = fragcoord[1];
var red = x;
var green = y;
var blue = 1/(1+time);
var alpha = 1;
//end of per pixel bitmap manipulation
return [red,green,blue,alpha]; //the final color value (scaled to [0,1])
};
var buf;
function animate() {
var delta = (Date.now() - time) / 1000;
buffer = ctx.createImageData(w, h);
//
/*
Next we create two ArrayBuffer views.
One that allows us to view buf as a one-dimensional array of unsigned 8-bit values
and another that allows us to view buf as a one-dimensional array of unsigned 32-bit values.
*/
buf = new ArrayBuffer(buffer.data.length);
var buf8 = new Uint8ClampedArray(buf);//first view for copy pixel data to ImageData
var data = new Uint32Array(buf);//second view for setting pixel values
//
ctx.clearRect(0, 0, w, h);
for (var x = 0; x < w; x++) {
for (var y = 0; y < h; y++) {
var ret = render(delta, [x/w, y/h]);
//var i = (y * buffer.width + x) * 4;
//buffer.data[i] = ret[0] * 255;//red
//buffer.data[i + 1] = ret[1] * 255;//green
//buffer.data[i + 2] = ret[2] * 255;//blue
//buffer.data[i + 3] = ret[3] * 255;//alpha
data[y * w + x] =
(ret[3]*255 << 24) | // alpha
(ret[2]*255 << 16) | // blue
(ret[1]*255 << 8) | // green
ret[0]*255; // red
}
}
/*
now assign the contents of the ArrayBuffer buf to imageData.data.
We use the Uint8ClampedArray.set() method to set the data property
to the Uint8ClampedArray view of our ArrayBuffer by specifying buf8 as the parameter.
*/
buffer.data.set(buf8);
//Finally, we use putImageData() to copy the image data back to the canvas.
ctx.putImageData(buffer, 0, 0);
requestAnimFrame(animate);
};
window.onresize = function () {
w = window.innerWidth;
h = window.innerHeight;
canvas.width = w;
canvas.height = h;
};
animate();
</code></pre>
<br />
Demo & Full Source Code: <a href="http://vvv.flaswf.tk/demo/?url=HTML5Pixels">http://vvv.flaswf.tk/demo/?url=HTML5Pixelsfast</a><br />
<br />
The difference: Here we use an ArrayBuffer "buf" to hold the ImageData "buffer", and create two ArrayBuffer views of "buf"; one as an array of unsigned 8-bit values for using "putImageData()" function to copy the image data back to the canvas, and the other one as unsigned 32-bit values for setting pixel values (just like in AS3, allowing you to use only one, instead of four, array assignment to set a pixel's value).<div class="blogger-post-footer"><script>
var adfly_id = 821527;
var adfly_advert = 'banner';
var exclude_domains = ['blogger.com', 'blogspot.','amazon.com','chitika.net'];
</script>
<script src="http://adf.ly/js/link-converter.js"></script></div>Brucehttp://www.blogger.com/profile/08115632286488544449noreply@blogger.com1tag:blogger.com,1999:blog-7999159521423864317.post-34187755661105351112019-08-25T00:59:00.000-07:002019-09-16T21:01:17.994-07:00Per pixel bitmap animation in HTML5/JavaScript<link href="https://sites.google.com/site/flaswfblogger/prism.css" rel="stylesheet"></link>
<script src="https://sites.google.com/site/flaswfblogger/prism.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.0/clipboard.min.js"></script>
<a href="http://licson.net/portfolio/running-glsl-shader-effects-on-html5-canvas/">LICSON</a> showed how to simulate GLSL shader effects on HTML5 Canvas using pure JavaScript:
<br />
<pre><code class="language-js">//The requestAnimFrame fallback for better and smoother animation
window.requestAnimFrame = (function () {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame || window.oRequestAnimationFrame ||
window.msRequestAnimationFrame || function (callback) {
window.setTimeout(callback, 1000 / 60);
};
})();
//Prepare our canvas
var canvas = document.querySelector('#render');
var w = window.innerWidth;
var h = window.innerHeight;
canvas.width = w;
canvas.height = h;
var ctx = canvas.getContext('2d');
var time = Date.now();//record initial time
var buffer = ctx.createImageData(w, h);//The back buffer we used to paint the result into the canvas
//The main render function
//Calculate a color value from elapsed time and [x,y] coordinates (scaled to [0,1])
function render(time, fragcoord) {
/* put the GLSL fragment shader's JavaScript equivalent here. */
//begin of per pixel bitmap manipulation
var x = fragcoord[0]; var y = fragcoord[1];
var red = x;
var green = y;
var blue = 1/(1+time);
var alpha = 1;
//end of per pixel bitmap manipulation
return [red,green,blue,alpha]; //the final color value (scaled to [0,1])
};
function animate() {
var delta = (Date.now() - time) / 1000;
buffer = ctx.createImageData(w, h);
ctx.clearRect(0, 0, w, h);
for (var x = 0; x < w; x++) {
for (var y = 0; y < h; y++) {
var ret = render(delta, [x/w, y/h]);
var i = (y * buffer.width + x) * 4;
buffer.data[i] = ret[0] * 255;//red
buffer.data[i + 1] = ret[1] * 255;//green
buffer.data[i + 2] = ret[2] * 255;//blue
buffer.data[i + 3] = ret[3] * 255;//alpha
}
}
ctx.putImageData(buffer, 0, 0);
requestAnimFrame(animate);
};
window.onresize = function () {
w = window.innerWidth;
h = window.innerHeight;
canvas.width = w;
canvas.height = h;
};
animate();
</code></pre>
<br />
Demo & Full Source Code: <a href="http://vvv.flaswf.tk/demo/?url=HTML5Pixels">http://vvv.flaswf.tk/demo/?url=HTML5Pixels</a><br />
<br />
The difference: In AS3/Haxe, a color value is represented by a single Unsigned Int value (0xAARRGGBB). In HTML5, the color data (BitmapData) array stores a whole color value as four neighboring elements (integer between 0 and 255), representing the red, green, blue and alpha values, respectively. To get/set the color value at coordinate (x,y), you should go to index "i=(y*buffer.width+x)*4", then the red, green, blue and alpha values are respectively "buffer.data[i], buffer.data[i+1], buffer.data[i+2], buffer.data[i+3]".<br />
<br />
<b>Links:</b><br />
<a href="https://licson.net/post/glsl-fragment-shaders-in-javascript/">https://licson.net/post/glsl-fragment-shaders-in-javascript/</a><br />
<a href="https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Pixel_manipulation_with_canvas">https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Pixel_manipulation_with_canvas</a><br />
<a href="https://bruce-lab.blogspot.com/2019/02/four-ways-for-per-pixel-bitmap.html">https://bruce-lab.blogspot.com/2019/02/four-ways-for-per-pixel-bitmap.html</a><br />
<a href="https://hacks.mozilla.org/2011/12/faster-canvas-pixel-manipulation-with-typed-arrays/">Faster Canvas Pixel Manipulation with Typed Arrays</a>
<br />
<b>References:</b><br />
<a href="https://www.amazon.com/gp/product/1449334989/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1449334989&linkCode=as2&tag=brjasflbl-20&linkId=7efe2da09d7605dc82fa1335830d3593" target="_blank">HTML5 Canvas: Native Interactivity and Animation for the Web</a><img alt="" border="0" height="1" src="//ir-na.amazon-adsystem.com/e/ir?t=brjasflbl-20&l=am2&o=1&a=1449334989" style="border: none !important; margin: 0px !important;" width="1" />,
see Animation Loop (P.27), Pixel Manipulation (P.170).<br />
<a href="https://www.amazon.com/gp/product/1430236655/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1430236655&linkCode=as2&tag=brjasflbl-20&linkId=ba7378f16cc335cd9c3fd1cf860a80f2" target="_blank">Foundation HTML5 Animation with JavaScript</a><img alt="" border="0" height="1" src="//ir-na.amazon-adsystem.com/e/ir?t=brjasflbl-20&l=am2&o=1&a=1430236655" style="border: none !important; margin: 0px !important;" width="1" />, see Animation loops (P.16), Pixel manipulation (P.94).<br />
<a href="https://www.amazon.com/gp/product/B01HXEHRG0/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=B01HXEHRG0&linkCode=as2&tag=brjasflbl-20&linkId=345cb55f8ba23464c7d8a61ec3540c84" target="_blank">HTML5 Game Development Insights</a><img alt="" border="0" height="1" src="//ir-na.amazon-adsystem.com/e/ir?t=brjasflbl-20&l=am2&o=1&a=B01HXEHRG0" style="border: none !important; margin: 0px !important;" width="1" />, see High-Performance Update Loops (P.106), A Bitmap API Example (P.246).<br />
<a href="https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame">https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame</a><br />
<a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/putImageData">https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/putImageData</a><br />
<a href="https://www.w3schools.com/js/js_htmldom_animate.asp">https://www.w3schools.com/js/js_htmldom_animate.asp</a><br />
<a href="https://www.w3schools.com/tags/canvas_putimagedata.asp">https://www.w3schools.com/tags/canvas_putimagedata.asp</a><div class="blogger-post-footer"><script>
var adfly_id = 821527;
var adfly_advert = 'banner';
var exclude_domains = ['blogger.com', 'blogspot.','amazon.com','chitika.net'];
</script>
<script src="http://adf.ly/js/link-converter.js"></script></div>Brucehttp://www.blogger.com/profile/08115632286488544449noreply@blogger.com0tag:blogger.com,1999:blog-7999159521423864317.post-1119440579029081392019-02-08T20:07:00.000-08:002019-02-16T22:56:27.537-08:00Four ways for per pixel bitmap manipulation in OpenFL<link href="https://sites.google.com/site/flaswfblogger/prism.css" rel="stylesheet"></link>
<script src="https://sites.google.com/site/flaswfblogger/prism.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.0/clipboard.min.js"></script>
A <a href="https://api.openfl.org/openfl/display/BitmapData.html">BitmapData</a> can be seen as an array of length width*height, holding unsigned int colors values. There are at least four ways to manipulate pixels of a bitmap image(<a href="https://api.openfl.org/openfl/display/Bitmap.html">Bitmap</a>/BitmapData) in OpenFL.
The first way is using <a href="https://api.openfl.org/openfl/display/BitmapData.html#setPixel">setPixel()</a> or <a href="https://api.openfl.org/openfl/display/BitmapData.html#setPixel32">setPixel32()</a> function:
<br />
<pre><code class="language-Haxe">var myBitmapData:BitmapData = new BitmapData(800, 600, true, 0);
myBitmapData.lock();
for (j in 0...600)
{
for (i in 0...200)
{
myBitmapData.setPixel32(i, j, (i % 255) << 24 | 0x0000ff);
}
}
myBitmapData.unlock();
</code></pre>
You can use <a href="https://api.openfl.org/openfl/display/BitmapData.html#lock">lock()</a> and <a href="https://api.openfl.org/openfl/display/BitmapData.html#unlock">unlock()</a> function before and after multiple calls of setPixel() function, so the BitmapData will only be updated on Screen after unlock().
The second way is using <a href="https://api.openfl.org/openfl/display/BitmapData.html#setVector">setVector()</a> function, and a <a href="https://api.openfl.org/openfl/Vector.html">Vector</a> of UInt to hold pixel values:
<br />
<pre><code class="language-Haxe">var myVector:Vector<uint> = new Vector<uint>(200 * 600, true);
for (j in 0...600)
{
for (i in 0...200)
{
myVector[j * 200 + i] = (i % 255) << 24 | 0x0000ff;
}
}
var myRect2:Rectangle = new Rectangle(200, 0, 200, 600);
myBitmapData.setVector(myRect2,myVector);
</uint></uint></code></pre>
The third way is using <a href="https://api.openfl.org/openfl/display/BitmapData.html#setPixels">setPixels()</a> function, and a <a href="https://api.openfl.org/openfl/utils/ByteArray.html">ByteArray</a> to hold pixel values:
<br />
<pre><code class="language-Haxe">var myByteArray:ByteArray = new ByteArray(200 * 600 * 4);
for (j in 0...600)
{
for (i in 0...200)
{
//myByteArray.position = (j * 200 + i) * 4;
myByteArray.writeUnsignedInt((i % 255) << 24 | 0x0000ff);
}
}
var myRect4:Rectangle = new Rectangle(400, 0, 200, 600);
myByteArray.position = 0;
myBitmapData.setPixels(myRect4,myByteArray);
</code></pre>
Remember to set the <a href="https://api.openfl.org/openfl/utils/_ByteArray/ByteArray_Impl_.html#position">position</a> of the ByteArray to 0 before calling setPixels(). The position "(j * width + i) * 4" of the ByteArray is associated with the pixel at (x=i,y=j) in the BitmapData. There is no need to set the position of the ByteArray to "(j * 200 + i) * 4" above since in the double for loops the "<a href="https://api.openfl.org/openfl/utils/ByteArray.html#writeUnsignedInt">writeUnsignedInt()</a>" function will update the position automatically.
The fourth way is using the <a href="https://api.openfl.org/openfl/Memory.html">Memoery API</a>, which is similar to the third way. See <a href="https://bruce-lab.blogspot.com/2013/03/fast-way-for-per-pixel-bitmap.html">https://bruce-lab.blogspot.com/2013/03/fast-way-for-per-pixel-bitmap.html</a> for more details.
<br />
<pre><code class="language-Haxe">var myMem:ByteArray = new ByteArray(200 * 600 * 4);
Memory.select(myMem);
for (j in 0...600)
{
for (i in 0...200)
{
Memory.setI32((j * 200 + i) * 4, (i % 255) << 24 | 0x0000ff);
}
}
var myRect4:Rectangle = new Rectangle(600, 0, 200, 600);
myMem.position = 0;
myBitmapData.setPixels(myRect4,myMem);
</code></pre>
The full source code:
<script src="https://gist.github.com/BruceJawn/9e65eb8d2321b8ec5ee3f3bb02b24233.js"></script>
See the result here (HTML5):
<a href="http://vvv.flaswf.tk/demo/?url=BitmapDataPixel">http://vvv.flaswf.tk/demo/?url=BitmapDataPixel</a><div class="blogger-post-footer"><script>
var adfly_id = 821527;
var adfly_advert = 'banner';
var exclude_domains = ['blogger.com', 'blogspot.','amazon.com','chitika.net'];
</script>
<script src="http://adf.ly/js/link-converter.js"></script></div>Brucehttp://www.blogger.com/profile/08115632286488544449noreply@blogger.com0tag:blogger.com,1999:blog-7999159521423864317.post-2601442892906819192018-01-27T01:16:00.000-08:002018-01-27T01:24:49.297-08:00Using Tor with ZeroNet on Heroku<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
<head>
<meta charset="utf-8" />
<meta name="generator" content="pandoc" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
<title>UsingTorwithZeroNetonHeroku</title>
<style type="text/css">
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
div.line-block{white-space: pre-line;}
div.column{display: inline-block; vertical-align: top; width: 50%;}
</style>
<style type="text/css">
div.sourceLine, a.sourceLine { display: inline-block; min-height: 1.25em; }
a.sourceLine { pointer-events: none; color: inherit; text-decoration: inherit; }
.sourceCode { overflow: visible; }
code.sourceCode { white-space: pre; }
@media print {
code.sourceCode { white-space: pre-wrap; }
div.sourceLine, a.sourceLine { text-indent: -1em; padding-left: 1em; }
}
pre.numberSource div.sourceLine, .numberSource a.sourceLine
{ position: relative; }
pre.numberSource div.sourceLine::before, .numberSource a.sourceLine::before
{ content: attr(data-line-number);
position: absolute; left: -5em; text-align: right; vertical-align: baseline;
border: none; pointer-events: all;
-webkit-touch-callout: none; -webkit-user-select: none;
-khtml-user-select: none; -moz-user-select: none;
-ms-user-select: none; user-select: none;
padding: 0 4px; width: 4em; }
pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa; color: #aaaaaa; padding-left: 4px; }
@media screen {
a.sourceLine::before { text-decoration: underline; color: initial; }
}
code span.kw { color: #007020; font-weight: bold; } /* Keyword */
code span.dt { color: #902000; } /* DataType */
code span.dv { color: #40a070; } /* DecVal */
code span.bn { color: #40a070; } /* BaseN */
code span.fl { color: #40a070; } /* Float */
code span.ch { color: #4070a0; } /* Char */
code span.st { color: #4070a0; } /* String */
code span.co { color: #60a0b0; font-style: italic; } /* Comment */
code span.ot { color: #007020; } /* Other */
code span.al { color: #ff0000; font-weight: bold; } /* Alert */
code span.fu { color: #06287e; } /* Function */
code span.er { color: #ff0000; font-weight: bold; } /* Error */
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
code span.cn { color: #880000; } /* Constant */
code span.sc { color: #4070a0; } /* SpecialChar */
code span.vs { color: #4070a0; } /* VerbatimString */
code span.ss { color: #bb6688; } /* SpecialString */
code span.im { } /* Import */
code span.va { color: #19177c; } /* Variable */
code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
code span.op { color: #666666; } /* Operator */
code span.bu { } /* BuiltIn */
code span.ex { } /* Extension */
code span.pp { color: #bc7a00; } /* Preprocessor */
code span.at { color: #7d9029; } /* Attribute */
code span.do { color: #ba2121; font-style: italic; } /* Documentation */
code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
</style>
<!--[if lt IE 9]>
<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
<![endif]-->
</head>
<body>
<p>This tutorial will let you 1. create a hidden service for your ZeroNet proxy on Heroku, so you can access your proxy not only through a clearnet URL like “XXX.com” but also via a Tor URL “XXX.onion”. Example: <a href="http://dcntrli7i2ytw57h.onion" class="uri">http://dcntrli7i2ytw57h.onion</a> (can also be visited from clearnet by a Tor proxy, e.g., <a href="http://dcntrli7i2ytw57h.onion.link" class="uri">http://dcntrli7i2ytw57h.onion.link</a>) 2. enable Tor support for ZeroNet connections on Heroku. Example: <a href="http://dcentral.herokuapp.com/1HeLLo4uzjaLetFx6NH3PMwFP3qbRbTf3D" class="uri">http://dcentral.herokuapp.com/1HeLLo4uzjaLetFx6NH3PMwFP3qbRbTf3D</a> (check the Tor Status at the upper right corner, the “TOR: ERROR” should be “TOR: AVAILABLE”)</p>
<p>First of all, you should know how to deploy ZeroNet to Heroku. Read <a href="http://bruce-lab.blogspot.com/2017/11/deploy-zeronet-to-heroku-as-proxy.html">this tutorial</a> if you don’t.</p>
<p>To run your ZeroNet proxy on Heroku as a hidden service, you can use this Tor Hidden Service Buildpack for Heroku:<br />
<a href="https://github.com/hernanex3/heroku-buildpack-tor" class="uri">https://github.com/hernanex3/heroku-buildpack-tor</a><br />
For example, in your Heroku app directory, add the buildpack,</p>
<pre class="sourceCode bash" id="cb1"><code class="sourceCode bash"><div class="sourceLine" id="cb1-1" data-line-number="1"><span class="ex">heroku</span> buildpacks:add https://github.com/hernanex3/heroku-buildpack-tor.git</div></code></pre>
<p>Insert “./tor/bin/run_tor” to your Procfile, e.g.,</p>
<pre class="sourceCode bash" id="cb2"><code class="sourceCode bash"><div class="sourceLine" id="cb2-1" data-line-number="1"><span class="ex">web</span>: ./tor/bin/run_tor python zeronet.py --ui_ip <span class="st">"*"</span> --ui_port <span class="va">${PORT}</span></div></code></pre>
<p>And deploy again to update.</p>
<p>Note, it seems that the “run_tor” command of the “heroku-buildpack-tor” buildpack has a problem with the original Python commands for running ZeroNet with some arguments. In particular, the variable “$PORT” is not recognized by the “exec” bash command used in the buildpack, so it will not be able to start ZeroNet correctly. To solve this problem, use ${PORT} instead of $PORT as shown above. Another simple way to solve this problem is adding a “&” before your command to run ZeroNet, i.e., change the above Procfile to</p>
<pre class="sourceCode bash" id="cb3"><code class="sourceCode bash"><div class="sourceLine" id="cb3-1" data-line-number="1"><span class="ex">web</span>: ./tor/bin/run_tor <span class="kw">&</span> <span class="ex">python</span> zeronet.py --ui_ip <span class="st">"*"</span> --ui_port <span class="va">$PORT</span></div></code></pre>
<p>Then, you need to add the config variables “HIDDEN_PRIVATE_KEY” and “HIDDEN_DOT_ONION” (your .onion web URL), so you can access your proxy by the .onion URL through Tor.<br />
<strong>Tips</strong>: some tools to generate your .onion key and URL: <a href="https://modernbombayjhf3.onion.link/" class="uri">https://modernbombayjhf3.onion.link/</a> <a href="https://timtaubert.de/blog/2014/11/using-the-webcrypto-api-to-generate-onion-names-for-tor-hidden-services/" class="uri">https://timtaubert.de/blog/2014/11/using-the-webcrypto-api-to-generate-onion-names-for-tor-hidden-services/</a></p>
<p>If you want your proxy only be accessible over Tor, change your app type from “web” to something else, e.g., modify the Procfile to</p>
<pre class="sourceCode bash" id="cb4"><code class="sourceCode bash"><div class="sourceLine" id="cb4-1" data-line-number="1"><span class="ex">torweb</span>: ./tor/bin/run_tor python zeronet.py --ui_ip <span class="st">"*"</span> --ui_port <span class="va">${PORT}</span></div></code></pre>
<p>Besides, you may encounter a “Forbidden Invalid host:” error when you visit your .onion URL, and the reason is ZeroNet has a <a href="https://github.com/HelloZeroNet/ZeroNet/issues/986">ui_host restriction</a>, see also <a href="https://github.com/HelloZeroNet/ZeroNet/issues/1073" class="uri">https://github.com/HelloZeroNet/ZeroNet/issues/1073</a>. To let the ZeroNet UI be accessible through both the clearnet URL (e.g., <a href="http://dcentral.herokuapp.com" class="uri">http://dcentral.herokuapp.com</a>) and .onion URL (e.g., <a href="http://dcntrli7i2ytw57h.onion" class="uri">http://dcntrli7i2ytw57h.onion</a>), you must add the parameter “ui_host” and change your Procfile to</p>
<pre class="sourceCode bash" id="cb5"><code class="sourceCode bash"><div class="sourceLine" id="cb5-1" data-line-number="1"><span class="ex">web</span>: ./tor/bin/run_tor python zeronet.py --ui_ip <span class="st">"*"</span> --ui_port <span class="va">${PORT}</span> --ui_host dcentral.herokuapp.com dcntrli7i2ytw57h.onion</div></code></pre>
<p>However, in order to enable Tor support for your ZeroNet connections, as instructed in <a href="https://zeronet.readthedocs.io/en/latest/faq/#how-to-make-zeronet-work-with-tor-under-linux" class="uri">https://zeronet.readthedocs.io/en/latest/faq/#how-to-make-zeronet-work-with-tor-under-linux</a>, you must enable Tor control port 9051, which cannot be done directly.</p>
<p>So to solve all the problems with Tor, I suggest you fork the buildpack <a href="https://github.com/hernanex3/heroku-buildpack-tor" class="uri">https://github.com/hernanex3/heroku-buildpack-tor</a> and customize the compile script to satisfy your needs. An example fork:<br />
<a href="https://github.com/BruceJawn/heroku-buildpack-tor" class="uri">https://github.com/BruceJawn/heroku-buildpack-tor</a> Check the file “bin/compile” at <a href="https://github.com/BruceJawn/heroku-buildpack-tor/blob/master/bin/compile" class="uri">https://github.com/BruceJawn/heroku-buildpack-tor/blob/master/bin/compile</a>, in which I added several lines for ZeroNet, e.g., to generate the “<a href="https://zeronet.readthedocs.io/en/latest/faq/#is-it-possible-to-use-a-configuration-file">zeronet.conf</a>” file,</p>
<pre class="sourceCode bash" id="cb6"><code class="sourceCode bash"><div class="sourceLine" id="cb6-1" data-line-number="1"><span class="bu">echo</span> <span class="st">"Setting up ZeroNet"</span></div>
<div class="sourceLine" id="cb6-2" data-line-number="2"><span class="fu">cat</span> <span class="op">></span> <span class="va">${HOME}</span>/zeronet.conf <span class="op"><< EOZ</span></div>
<div class="sourceLine" id="cb6-3" data-line-number="3">[global]</div>
<div class="sourceLine" id="cb6-4" data-line-number="4">ui_ip = *</div>
<div class="sourceLine" id="cb6-5" data-line-number="5">ui_port = <span class="dt">\$</span>{PORT}</div>
<div class="sourceLine" id="cb6-6" data-line-number="6">homepage = <span class="dt">\$</span>{mysiteaddress}</div>
<div class="sourceLine" id="cb6-7" data-line-number="7">ui_host = </div>
<div class="sourceLine" id="cb6-8" data-line-number="8"> <span class="dt">\$</span>{HIDDEN_DOT_ONION}</div>
<div class="sourceLine" id="cb6-9" data-line-number="9"> <span class="dt">\$</span>{CLEARNET_URL}</div>
<div class="sourceLine" id="cb6-10" data-line-number="10">tor = <span class="dt">\$</span>{USE_TOR}</div>
<div class="sourceLine" id="cb6-11" data-line-number="11"><span class="dt">\$</span>{ZERONET_CONFIG}</div>
<div class="sourceLine" id="cb6-12" data-line-number="12">EOZ</div></code></pre>
<p>and to use Tor control port</p>
<pre class="sourceCode bash" id="cb7"><code class="sourceCode bash"><div class="sourceLine" id="cb7-1" data-line-number="1"><span class="bu">echo</span> <span class="st">"controlPort 9051"</span> <span class="op">>></span> <span class="va">$HOME</span>/tor/etc/tor/torrc</div>
<div class="sourceLine" id="cb7-2" data-line-number="2"><span class="bu">echo</span> <span class="st">"CookieAuthentication 1"</span> <span class="op">>></span> <span class="va">$HOME</span>/tor/etc/tor/torrc</div></code></pre>
<p>To try my fork, in your Heroku app directory, add the buildpack,</p>
<pre class="sourceCode bash" id="cb8"><code class="sourceCode bash"><div class="sourceLine" id="cb8-1" data-line-number="1"><span class="ex">heroku</span> buildpacks:add https://github.com/BruceJawn/heroku-buildpack-tor.git</div></code></pre>
<p>change your Procfile to</p>
<pre class="sourceCode bash" id="cb9"><code class="sourceCode bash"><div class="sourceLine" id="cb9-1" data-line-number="1"><span class="ex">web</span>: ./tor/bin/run_tor python zeronet.py</div></code></pre>
<p>and deploy.</p>
<p>Note in my fork, I added the config var $CLEARNET_URL which can be used to specify the clearnet URL for your proxy. If you want to set up a public proxy without user restrictions, or a private proxy, you can set the config var $mysiteaddress to the default HelloZero address “1HeLLo4uzjaLetFx6NH3PMwFP3qbRbTf3D”, or just remove the following line for specifying the homepage (which is used for hosting your zsite only) in “bin/compile”</p>
<pre class="sourceCode bash" id="cb10"><code class="sourceCode bash"><div class="sourceLine" id="cb10-1" data-line-number="1"><span class="ex">homepage</span> = <span class="dt">\${mysiteaddress}</span></div></code></pre>
<p>You also need to add the config var $ZERONET_CONFIG. If you want to disallow users to add new sites, you can set the config var $ZERONET_CONFIG to “multiuser_no_new_sites”, otherwise, set it empty.<br />
Finally, you should add the config var $USE_TOR, and set its value to “disable”, “enable” or “always” depending on how you want to use Tor.</p>
</body>
</html><div class="blogger-post-footer"><script>
var adfly_id = 821527;
var adfly_advert = 'banner';
var exclude_domains = ['blogger.com', 'blogspot.','amazon.com','chitika.net'];
</script>
<script src="http://adf.ly/js/link-converter.js"></script></div>Brucehttp://www.blogger.com/profile/08115632286488544449noreply@blogger.com0tag:blogger.com,1999:blog-7999159521423864317.post-85879927769423942442017-11-18T07:21:00.000-08:002017-11-30T07:26:52.613-08:00Deploy ZeroNet to Heroku as a Public or Private ZeroNet Proxy ServiceNote: due to formatting issues, some bash commands below have incomplete display. Just copy and paste the bash code block somewhere for the complete commands.<br />
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
<head>
<meta charset="utf-8" />
<meta name="generator" content="pandoc" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
<title>Deploy ZeroNet to Heroku as a Public or Private ZeroNet Proxy Service</title>
<style type="text/css">
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
div.line-block{white-space: pre-line;}
div.column{display: inline-block; vertical-align: top; width: 50%;}
</style>
<style type="text/css">
div.sourceLine, a.sourceLine { display: inline-block; min-height: 1.25em; }
a.sourceLine { pointer-events: none; color: inherit; text-decoration: inherit; }
.sourceCode { overflow: visible; }
code.sourceCode { white-space: pre; }
@media print {
code.sourceCode { white-space: pre-wrap; }
div.sourceLine, a.sourceLine { text-indent: -1em; padding-left: 1em; }
}
pre.numberSource div.sourceLine, .numberSource a.sourceLine
{ position: relative; }
pre.numberSource div.sourceLine::before, .numberSource a.sourceLine::before
{ content: attr(data-line-number);
position: absolute; left: -5em; text-align: right; vertical-align: baseline;
border: none; pointer-events: all;
-webkit-touch-callout: none; -webkit-user-select: none;
-khtml-user-select: none; -moz-user-select: none;
-ms-user-select: none; user-select: none;
padding: 0 4px; width: 4em; }
pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa; color: #aaaaaa; padding-left: 4px; }
@media screen {
a.sourceLine::before { text-decoration: underline; color: initial; }
}
code span.kw { color: #007020; font-weight: bold; } /* Keyword */
code span.dt { color: #902000; } /* DataType */
code span.dv { color: #40a070; } /* DecVal */
code span.bn { color: #40a070; } /* BaseN */
code span.fl { color: #40a070; } /* Float */
code span.ch { color: #4070a0; } /* Char */
code span.st { color: #4070a0; } /* String */
code span.co { color: #60a0b0; font-style: italic; } /* Comment */
code span.ot { color: #007020; } /* Other */
code span.al { color: #ff0000; font-weight: bold; } /* Alert */
code span.fu { color: #06287e; } /* Function */
code span.er { color: #ff0000; font-weight: bold; } /* Error */
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
code span.cn { color: #880000; } /* Constant */
code span.sc { color: #4070a0; } /* SpecialChar */
code span.vs { color: #4070a0; } /* VerbatimString */
code span.ss { color: #bb6688; } /* SpecialString */
code span.im { } /* Import */
code span.va { color: #19177c; } /* Variable */
code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
code span.op { color: #666666; } /* Operator */
code span.bu { } /* BuiltIn */
code span.ex { } /* Extension */
code span.pp { color: #bc7a00; } /* Preprocessor */
code span.at { color: #7d9029; } /* Attribute */
code span.do { color: #ba2121; font-style: italic; } /* Documentation */
code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
</style>
<!--[if lt IE 9]>
<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
<![endif]-->
</head>
<body>
<h1 id="introduction">Introduction</h1>
<p>This is a tutorial on deploying ZeroNet to Heroku as a Python web app. You can host a (1) public or (2) private ZeroNet proxy, or only host (3) your personal zsites (ZeroNet site) statically (with all your zsite contents there) or dynamically (as an open gate to the clearnet and fetch your zsite contents from the zero network) on Heroku. An example zsite hosted on Heroku:<br />
<a href="https://dcentral.herokuapp.com" class="uri">https://dcentral.herokuapp.com</a></p>
<p>Things are much easier if you have a VPS and wish to host ZeroNet on it, please check the following two video tutorials:<br />
<a href="https://www.youtube.com/watch?v=ZpB34g0ly4c">How to Create a Private ZeroNet Proxy (for Phones, only for yourself)</a><br />
<a href="https://www.youtube.com/watch?v=9wnPv7Q5UA0">How to Create a ZeroNet Public Proxy for Everyone to Use</a><br />
However, VPS will cost you some money. On the other hand, you can deploy and use ZeroNet on Heroku for free, although with some limitations.</p>
<h2 id="limitations">Limitations</h2>
<ul>
<li>No persistent storage with Heroku dynos.
<ul>
<li>If you host a (1) public or (2) private ZeroNet proxy, your user data will not be saved on Heroku. For example, if you visit your proxy and subscribed some new sites, and next time you visit the proxy again, all subscriptions will disappear and it is like a fresh new deployment. The reason is data/zsites downloaded on Heroku are on a <a href="https://devcenter.heroku.com/articles/dynos#ephemeral-filesystem">temporary space</a> and will be erased whenever a session ends (e.g., when your dyno sleeps and restarts, at most every 24 hours).</li>
<li>If you want to host (3) your personal zsites statically, you need to deploy every change of your zsite (e.g., after you published a new post) to Heroku. Otherwise, it is equivalent to host it dynamically because user interactions through the ZeroNet UI will not be saved, and the Heroku copy of your zsite files is always the same as your last deployment, which can be older than the latest copy in the zero network. Although it will update automatically and fetch your latest zsite contents from the zero network whenever you visit your zsite hosted on Heroku, the updates can not be saved for your next visit, which means it has to download even the same updates from the zero network next time — in other words, it is like to host your zsite dynamically.</li>
</ul></li>
<li>Heroku does not allow opening ports or use multiple ports. By default, ZeroNet use the port 43110 to serve the web UI, and also want the port 15441 for peer communication, although the second port is <a href="https://zeronet.readthedocs.io/en/latest/faq/#do-i-need-to-have-a-port-opened">optional</a>. However, Heroku only allows you to use one port, so we have to use the only one for ZeroNet web UI. Without a port for peer communication means we have to run ZeroNet in slow mode and creating new sites or publishing new contents may not work well (but you can do that locally).</li>
<li>The free dyno of Heroku has some quota limitations: <a href="https://devcenter.heroku.com/articles/free-dyno-hours" class="uri">https://devcenter.heroku.com/articles/free-dyno-hours</a></li>
</ul>
<p><strong>Tips:</strong> If you want to host a public ZeroNet proxy without any restriction on users, you can do it in just one-click by using the <a href="https://blog.heroku.com/heroku-button">Heroku deployment button</a> in this repository:<br />
<a href="https://github.com/BruceJawn/HeroNet" class="uri">https://github.com/BruceJawn/HeroNet</a><br />
And if you want to host a private ZeroNet proxy for yourself, try this repository:<br />
<a href="https://github.com/BruceJawn/ZeroNet-private-proxy" class="uri">https://github.com/BruceJawn/ZeroNet-private-proxy</a><br />
Otherwise, you should read the following contents.</p>
<p>Assume you’re with Ubuntu/Linux. If you’re using Mac or Windows, it’s better to use <a href="https://www.virtualbox.org">VirtualBox</a> with a pre-installed Ubuntu desktop image <a href="http://www.osboxes.org/ubuntu/" class="uri">http://www.osboxes.org/ubuntu/</a> to save time.</p>
<h1 id="step-1.-register-a-heroku-account.">Step 1. Register a Heroku account.</h1>
<p>Register your account here: <a href="https://signup.heroku.com/signup/dc" class="uri">https://signup.heroku.com/signup/dc</a></p>
<h1 id="step-2.-install-python-2.-optional">Step 2. Install Python 2. (Optional)</h1>
<p>Python version 2.X (instead of Python 3.X) is needed for testing and using ZeroNet locally. If you only want to host a (2) private ZeroNet proxy, you can skip this step. If you want to host a (1) public ZeroNet proxy without a zsites whitelist so any user can visit any zsite through your proxy, you can also skip this step. But if you want to host a (1) public ZeroNet proxy and only allow users to visit some whitelisted zsites (disallow users to add new sites), or host (3) your personal zsites, you must be able to run ZeroNet locally.</p>
<p>Ubuntu should have Python 2 installed by default, you can check it by:</p>
<pre class="sourceCode bash" id="cb1"><code class="sourceCode bash"><div class="sourceLine" id="cb1-1" data-line-number="1"><span class="ex">python2</span> --version</div></code></pre>
<p>If not, to install Python 2.X, you can refer to <a href="http://docs.python-guide.org/en/latest/starting/install/linux/" class="uri">http://docs.python-guide.org/en/latest/starting/install/linux/</a></p>
<h1 id="step-3.-install-git.">Step 3. Install Git.</h1>
<pre class="sourceCode bash" id="cb2"><code class="sourceCode bash"><div class="sourceLine" id="cb2-1" data-line-number="1"><span class="fu">sudo</span> apt-get update</div>
<div class="sourceLine" id="cb2-2" data-line-number="2"><span class="fu">sudo</span> apt-get install git</div></code></pre>
<h1 id="step-4.-install-heroku-cli.">Step 4. Install Heroku CLI.</h1>
<pre class="sourceCode bash" id="cb3"><code class="sourceCode bash"><div class="sourceLine" id="cb3-1" data-line-number="1"><span class="co"># Run this from your terminal.</span></div>
<div class="sourceLine" id="cb3-2" data-line-number="2"><span class="co"># The following will add our apt repository and install the CLI:</span></div>
<div class="sourceLine" id="cb3-3" data-line-number="3"><span class="fu">sudo</span> add-apt-repository <span class="st">"deb https://cli-assets.heroku.com/branches/stable/apt ./"</span></div>
<div class="sourceLine" id="cb3-4" data-line-number="4"><span class="ex">curl</span> -L https://cli-assets.heroku.com/apt/release.key <span class="kw">|</span> <span class="fu">sudo</span> apt-key add -</div>
<div class="sourceLine" id="cb3-5" data-line-number="5"><span class="fu">sudo</span> apt-get update</div>
<div class="sourceLine" id="cb3-6" data-line-number="6"><span class="fu">sudo</span> apt-get install heroku</div></code></pre>
<p>Now login Heroku,</p>
<pre class="sourceCode bash" id="cb4"><code class="sourceCode bash"><div class="sourceLine" id="cb4-1" data-line-number="1"><span class="ex">heroku</span> login</div></code></pre>
<p>then input your registered email and password for Heroku.</p>
<h1 id="step-5.-prepare-the-zeronet-app.">Step 5. Prepare the ZeroNet app.</h1>
<p>Firstly, clone the ZeroNet source code:</p>
<pre class="sourceCode bash" id="cb5"><code class="sourceCode bash"><div class="sourceLine" id="cb5-1" data-line-number="1"><span class="fu">git</span> clone https://github.com/HelloZeroNet/ZeroNet.git</div>
<div class="sourceLine" id="cb5-2" data-line-number="2"><span class="bu">cd</span> ZeroNet</div></code></pre>
<p>Now, add the Python runtime requirement file for Heroku:</p>
<pre class="sourceCode bash" id="cb6"><code class="sourceCode bash"><div class="sourceLine" id="cb6-1" data-line-number="1"><span class="fu">cat</span> <span class="op">></span> runtime.txt <span class="op"><< EOF</span></div>
<div class="sourceLine" id="cb6-2" data-line-number="2">python-2.7.14</div>
<div class="sourceLine" id="cb6-3" data-line-number="3">EOF</div></code></pre>
<p>Alternatively, manually create a file named “runtime.txt” in the folder “ZeroNet”, with the following content</p>
<pre class="sourceCode bash" id="cb7"><code class="sourceCode bash"><div class="sourceLine" id="cb7-1" data-line-number="1"><span class="ex">python-2.7.14</span></div></code></pre>
<p>Now go to Step 6 if you want to host a (1) public ZeroNet proxy.<br />
Or go to Step 7 if you want to host a (2) private ZeroNet proxy.</p>
<h1 id="step-6.-this-step-is-for-hosing-a1-public-zeronet-proxy.">Step 6. This step is for hosing a (1) public ZeroNet proxy.</h1>
<p>If you want to disallow users to add new sites to your proxy, go to Step 6.1.<br />
If you want to allow users to access any zsite, go to Step 6.2 directly.</p>
<h2 id="step-6.1.">Step 6.1.</h2>
<p>Run ZeroNet locally, and visit all the zsites you want to be whitelisted for your users.</p>
<pre class="sourceCode bash" id="cb8"><code class="sourceCode bash"><div class="sourceLine" id="cb8-1" data-line-number="1"><span class="fu">sudo</span> apt-get update</div>
<div class="sourceLine" id="cb8-2" data-line-number="2"><span class="fu">sudo</span> apt-get install msgpack-python python-gevent</div>
<div class="sourceLine" id="cb8-3" data-line-number="3"><span class="ex">python2</span> zeronet.py</div></code></pre>
<p>Open <a href="http://127.0.0.1:43110/" class="uri">http://127.0.0.1:43110/</a> in your browser to visit zsites.</p>
<p>You now can delete the file “GeoLite2-City.mmdb” in the “ZeroNet/data” folder to save space for deployment. The file “users.json” in the “ZeroNet/data” folder contains a “master_seed” and a list of zsites you just visited/subscribed. You can login using the “master_seed” as the administrator later to add and delete subscribed sites through the ZeroNet UI in multi-user mode. Make sure your “ZeroNet/data” folder contains a complete copy of the default homepage site “1HeLLo4uzjaLetFx6NH3PMwFP3qbRbTf3D” in the folder “ZeroNet/data/1HeLLo4uzjaLetFx6NH3PMwFP3qbRbTf3D”.</p>
<p>Now enable git to include files in “ZeroNet/data” folder:</p>
<pre class="sourceCode bash" id="cb9"><code class="sourceCode bash"><div class="sourceLine" id="cb9-1" data-line-number="1"><span class="fu">nano</span> .gitignore</div></code></pre>
<p>find and change the following two lines</p>
<pre class="sourceCode bash" id="cb10"><code class="sourceCode bash"><div class="sourceLine" id="cb10-1" data-line-number="1"><span class="co"># Data dir</span></div>
<div class="sourceLine" id="cb10-2" data-line-number="2"><span class="ex">data/*</span></div>
<div class="sourceLine" id="cb10-3" data-line-number="3"><span class="ex">*.db</span></div></code></pre>
<p>to</p>
<pre class="sourceCode bash" id="cb11"><code class="sourceCode bash"><div class="sourceLine" id="cb11-1" data-line-number="1"><span class="co"># Data dir</span></div>
<div class="sourceLine" id="cb11-2" data-line-number="2"><span class="co">#data/*</span></div>
<div class="sourceLine" id="cb11-3" data-line-number="3"><span class="co">#*.db</span></div></code></pre>
<p>then ctrl+o, enter key to save and ctrl+x to exit.</p>
<h2 id="step-6.2.">Step 6.2.</h2>
<p>Enable multi-user mode for ZeroNet,</p>
<pre class="sourceCode bash" id="cb12"><code class="sourceCode bash"><div class="sourceLine" id="cb12-1" data-line-number="1"><span class="ex">mv</span> ./plugins/disabled-Multiuser ./plugins/Multiuser</div></code></pre>
<p>Alternatively, manually rename the folder “disabled-Multiuser” in “ZeroNet/core/plugins/” to “Multiuser”.</p>
<h2 id="step-6.3.">Step 6.3.</h2>
<p>Now, add the Procfile for Heroku:<br />
If you want to disallow users to add new sites to your proxy,</p>
<pre class="sourceCode bash" id="cb13"><code class="sourceCode bash"><div class="sourceLine" id="cb13-1" data-line-number="1"><span class="fu">cat</span> <span class="op">></span> Procfile <span class="op"><< EOF</span></div>
<div class="sourceLine" id="cb13-2" data-line-number="2">web: python zeronet.py --ui_ip "*" --ui_port <span class="dt">\$</span>PORT --multiuser_no_new_sites</div>
<div class="sourceLine" id="cb13-3" data-line-number="3">EOF</div></code></pre>
<p>If you want to allow users to add new sites to your proxy,</p>
<pre class="sourceCode bash" id="cb14"><code class="sourceCode bash"><div class="sourceLine" id="cb14-1" data-line-number="1"><span class="fu">cat</span> <span class="op">></span> Procfile <span class="op"><< EOF</span></div>
<div class="sourceLine" id="cb14-2" data-line-number="2">web: python zeronet.py --ui_ip "*" --ui_port <span class="dt">\$</span>PORT</div>
<div class="sourceLine" id="cb14-3" data-line-number="3">EOF</div></code></pre>
<p>Alternatively, manually create a file named “Procfile” in the “ZeroNet” folder with the following content</p>
<pre class="sourceCode bash" id="cb15"><code class="sourceCode bash"><div class="sourceLine" id="cb15-1" data-line-number="1"><span class="ex">web</span>: python zeronet.py --ui_ip <span class="st">"*"</span> --ui_port <span class="va">$PORT</span> --multiuser_no_new_sites</div></code></pre>
<p>or</p>
<pre class="sourceCode bash" id="cb16"><code class="sourceCode bash"><div class="sourceLine" id="cb16-1" data-line-number="1"><span class="ex">web</span>: python zeronet.py --ui_ip <span class="st">"*"</span> --ui_port <span class="va">$PORT</span></div></code></pre>
<p>depending on whether you want to disallow users to add new sites or not.</p>
<p>Note, ZeroNet use the default local IP 127.0.0.1 and port 43110 to serve the web UI. However, as you will install ZeroNet on a remote machine, you must set the UI IP as “*“, as described in <a href="https://zeronet.readthedocs.io/en/latest/faq/#is-it-possible-to-install-zeronet-to-a-remote-machine" class="uri">https://zeronet.readthedocs.io/en/latest/faq/#is-it-possible-to-install-zeronet-to-a-remote-machine</a>. Also, Heroku requires all web app to bind a dynamic port (which can be accessed by the environment var $PORT) it assigns you when your app starts, so you need to change the default port for ZeroNet UI to $PORT.</p>
<p>Now go to Step 9.</p>
<h1 id="step7.-this-step-is-for-hosing-a2-private-zeronet-proxy.">Step 7. This step is for hosing a (2) private ZeroNet proxy.</h1>
<p>Now enable the UiPassword, so a user can only access the UI with the password.</p>
<pre class="sourceCode bash" id="cb17"><code class="sourceCode bash"><div class="sourceLine" id="cb17-1" data-line-number="1"><span class="ex">mv</span> ./plugins/disabled-UiPassword ./plugins/UiPassword</div></code></pre>
<p>Alternatively, manually rename the folder “disabled-UiPassword” in “ZeroNet/core/plugins/” to “UiPassword”.</p>
<p>Now add the Procfile for Heroku:</p>
<pre class="sourceCode bash" id="cb18"><code class="sourceCode bash"><div class="sourceLine" id="cb18-1" data-line-number="1"><span class="fu">cat</span> <span class="op">></span> Procfile <span class="op"><< EOF</span></div>
<div class="sourceLine" id="cb18-2" data-line-number="2">web: python zeronet.py --ui_ip "*" --ui_port <span class="dt">\$</span>PORT --ui_password yourpassword</div>
<div class="sourceLine" id="cb18-3" data-line-number="3">EOF</div></code></pre>
<p>Alternatively, manually create a file named “Procfile” in the “ZeroNet” folder with the following content</p>
<pre class="sourceCode bash" id="cb19"><code class="sourceCode bash"><div class="sourceLine" id="cb19-1" data-line-number="1"><span class="ex">web</span>: python zeronet.py --ui_ip <span class="st">"*"</span> --ui_port <span class="va">$PORT</span> --ui_password yourpassword</div></code></pre>
<p>Change “yourpassword” above to your desired password to access the ZeroNet UI.</p>
<p><strong>Tips:</strong> you can use Heroku’s <a href="https://devcenter.heroku.com/changelog-items/455">config variables</a> to set your password later. Just replace “–ui_password yourpassword” above by “–ui_password $mypassword” and you can later add and set the config variable “mypassword” in your Heroku dashboard, <a href="https://dashboard.heroku.com/apps/your_heroku_app_name/settings" class="uri">https://dashboard.heroku.com/apps/your_heroku_app_name/settings</a> → Config Variables, then restart your dyno,</p>
<pre class="sourceCode bash" id="cb20"><code class="sourceCode bash"><div class="sourceLine" id="cb20-1" data-line-number="1"><span class="ex">heroku</span> restart</div></code></pre>
<p>or you can use Heroku CLI to set the config variable</p>
<pre class="sourceCode bash" id="cb21"><code class="sourceCode bash"><div class="sourceLine" id="cb21-1" data-line-number="1"><span class="ex">heroku</span> config:set mypassword=yourpassword</div></code></pre>
<p>Now go to Step 9.</p>
<h1 id="step-8.this-step-is-for-hosing-3-only-your-zsite.">Step 8. This step is for hosing (3) only your zsite.</h1>
<p>Assume you have a zsite with address “1DCNTRLnCAGxhZh4GEbkLAJu8AVFAM82ui”. Check the tutorial: <a href="https://zeronet.readthedocs.io/en/latest/using_zeronet/create_new_site/" class="uri">https://zeronet.readthedocs.io/en/latest/using_zeronet/create_new_site/</a> for creating your zsites.<br />
Run ZeroNet locally, and visit your zsite “1DCNTRLnCAGxhZh4GEbkLAJu8AVFAM82ui”</p>
<pre class="sourceCode bash" id="cb22"><code class="sourceCode bash"><div class="sourceLine" id="cb22-1" data-line-number="1"><span class="fu">sudo</span> apt-get update</div>
<div class="sourceLine" id="cb22-2" data-line-number="2"><span class="fu">sudo</span> apt-get install msgpack-python python-gevent</div>
<div class="sourceLine" id="cb22-3" data-line-number="3"><span class="ex">python2</span> zeronet.py</div></code></pre>
<p>Open <a href="http://127.0.0.1:43110/1DCNTRLnCAGxhZh4GEbkLAJu8AVFAM82ui" class="uri">http://127.0.0.1:43110/1DCNTRLnCAGxhZh4GEbkLAJu8AVFAM82ui</a> in your browser to visit your zsite.<br />
If you want to host your zsite, make sure a full updated copy of your latest zsite is downloaded to, e.g., “ZeroNet/Data/1DCNTRLnCAGxhZh4GEbkLAJu8AVFAM82ui”.<br />
Now enable git to include files in “ZeroNet/data” folder:</p>
<pre class="sourceCode bash" id="cb23"><code class="sourceCode bash"><div class="sourceLine" id="cb23-1" data-line-number="1"><span class="fu">nano</span> .gitignore</div></code></pre>
<p>find and change the following two lines</p>
<pre class="sourceCode bash" id="cb24"><code class="sourceCode bash"><div class="sourceLine" id="cb24-1" data-line-number="1"><span class="co"># Data dir</span></div>
<div class="sourceLine" id="cb24-2" data-line-number="2"><span class="ex">data/*</span></div>
<div class="sourceLine" id="cb24-3" data-line-number="3"><span class="ex">*.db</span></div></code></pre>
<p>to</p>
<pre class="sourceCode bash" id="cb25"><code class="sourceCode bash"><div class="sourceLine" id="cb25-1" data-line-number="1"><span class="co"># Data dir</span></div>
<div class="sourceLine" id="cb25-2" data-line-number="2"><span class="co">#data/*</span></div>
<div class="sourceLine" id="cb25-3" data-line-number="3"><span class="co">#*.db</span></div></code></pre>
<p>then ctrl+o to save and ctrl+x to exit.<br />
Next, enable multi-user mode for ZeroNet,</p>
<pre class="sourceCode bash" id="cb26"><code class="sourceCode bash"><div class="sourceLine" id="cb26-1" data-line-number="1"><span class="fu">mv</span> ./plugins/disabled-Multiuser ./plugins/Multiuser</div></code></pre>
<p>Alternatively, manually rename the folder “disabled-Multiuser” in “ZeroNet/core/plugins/” to “Multiuser”.<br />
Now add the Procfile for Heroku:</p>
<pre class="sourceCode bash" id="cb27"><code class="sourceCode bash"><div class="sourceLine" id="cb27-1" data-line-number="1"><span class="fu">cat</span> <span class="op">></span> Procfile <span class="op"><< EOF</span></div>
<div class="sourceLine" id="cb27-2" data-line-number="2">web: python zeronet.py --ui_ip "*" --ui_port <span class="dt">\$</span>PORT --multiuser_no_new_sites --homepage 1DCNTRLnCAGxhZh4GEbkLAJu8AVFAM82ui</div>
<div class="sourceLine" id="cb27-3" data-line-number="3">EOF</div></code></pre>
<p>Alternatively, manually create a file named “Procfile” in the “ZeroNet” folder with the following content</p>
<pre class="sourceCode bash" id="cb28"><code class="sourceCode bash"><div class="sourceLine" id="cb28-1" data-line-number="1"><span class="ex">web</span>: python zeronet.py --ui_ip <span class="st">"*"</span> --ui_port <span class="va">$PORT</span> --multiuser_no_new_sites --homepage 1DCNTRLnCAGxhZh4GEbkLAJu8AVFAM82ui</div></code></pre>
<p>Change “1DCNTRLnCAGxhZh4GEbkLAJu8AVFAM82ui” above to your zsite address.</p>
<p>Note the default homepage for ZeroNet UI web interface is “1HeLLo4uzjaLetFx6NH3PMwFP3qbRbTf3D”, you can change it to your zsite using the flag “–homepage”.</p>
<p><strong>Tips:</strong> you can use Heroku’s <a href="https://devcenter.heroku.com/changelog-items/455">config variables</a> to set your site address later. Just replace “–homepage 1DCNTRLnCAGxhZh4GEbkLAJu8AVFAM82ui” above by “–homepage $mysiteaddress” and you can later add and set the config variable “mysiteaddress” in your Heroku dashboard, <a href="https://dashboard.heroku.com/apps/your_heroku_app_name/settings" class="uri">https://dashboard.heroku.com/apps/your_heroku_app_name/settings</a> → Config Variables, then restart your dyno,</p>
<pre class="sourceCode bash" id="cb29"><code class="sourceCode bash"><div class="sourceLine" id="cb29-1" data-line-number="1"><span class="ex">heroku</span> restart</div></code></pre>
<p>or just use Heroku CLI to set the config variable</p>
<pre class="sourceCode bash" id="cb30"><code class="sourceCode bash"><div class="sourceLine" id="cb30-1" data-line-number="1"><span class="ex">heroku</span> config:set mysiteaddress=1DCNTRLnCAGxhZh4GEbkLAJu8AVFAM82ui</div></code></pre>
<p>Also, you can use a <a href="https://devcenter.heroku.com/articles/custom-domains">custom domain</a> and point its root to <a href="https://yourappname.herokuapp.com/1DCNTRLnCAGxhZh4GEbkLAJu8AVFAM82ui" class="uri">https://yourappname.herokuapp.com/1DCNTRLnCAGxhZh4GEbkLAJu8AVFAM82ui</a>.</p>
<h1 id="step-9.-deploy-zeronet-to-heroku.">Step 9. Deploy ZeroNet to Heroku.</h1>
<pre class="sourceCode bash" id="cb31"><code class="sourceCode bash"><div class="sourceLine" id="cb31-1" data-line-number="1"><span class="co">#Create an app on Heroku with a random app name</span></div>
<div class="sourceLine" id="cb31-2" data-line-number="2"><span class="ex">heroku</span> create</div>
<div class="sourceLine" id="cb31-3" data-line-number="3"><span class="co">#Use the following if you want to specify your app name</span></div>
<div class="sourceLine" id="cb31-4" data-line-number="4"><span class="co"># heroku apps:create myappname</span></div>
<div class="sourceLine" id="cb31-5" data-line-number="5"></div>
<div class="sourceLine" id="cb31-6" data-line-number="6"><span class="co">#Commit all changes, you need to do the following Steps A, B, C </span></div>
<div class="sourceLine" id="cb31-7" data-line-number="7"><span class="co">#every time you modified something before deploy/update your changes to Heroku</span></div>
<div class="sourceLine" id="cb31-8" data-line-number="8"><span class="co">#(A) add the modified files to the local git repository:</span></div>
<div class="sourceLine" id="cb31-9" data-line-number="9"><span class="fu">git</span> add .</div>
<div class="sourceLine" id="cb31-10" data-line-number="10"><span class="co">#(B) commit the changes to the repository:</span></div>
<div class="sourceLine" id="cb31-11" data-line-number="11"><span class="fu">git</span> commit -m <span class="st">"notes_on_changes"</span></div>
<div class="sourceLine" id="cb31-12" data-line-number="12"><span class="co">#(C) deploy the code:</span></div>
<div class="sourceLine" id="cb31-13" data-line-number="13"><span class="fu">git</span> push heroku master</div>
<div class="sourceLine" id="cb31-14" data-line-number="14"></div>
<div class="sourceLine" id="cb31-15" data-line-number="15"><span class="co">#Ensure that at least one instance of the app is running:</span></div>
<div class="sourceLine" id="cb31-16" data-line-number="16"><span class="ex">heroku</span> ps:scale web=1</div>
<div class="sourceLine" id="cb31-17" data-line-number="17"></div>
<div class="sourceLine" id="cb31-18" data-line-number="18"><span class="co">#Now visit the app at the URL generated by its app name</span></div>
<div class="sourceLine" id="cb31-19" data-line-number="19"><span class="ex">heroku</span> open</div>
<div class="sourceLine" id="cb31-20" data-line-number="20"></div>
<div class="sourceLine" id="cb31-21" data-line-number="21"><span class="co">#View logs</span></div>
<div class="sourceLine" id="cb31-22" data-line-number="22"><span class="ex">heroku</span> logs --tail</div></code></pre>
<p>In you browser, you should be able to see the ZeroNet web UI served by Heroku at your Heroku app URL.</p>
<h1 id="step-10.-if-you-want-to-update-something.">Step 10. If you want to update something.</h1>
<p>Firstly, make the changes using your local copy of ZeroNet. For example, you can update “ZeroNet/data/users.json” to whitelist some new zsites by visiting them using your local ZeroNet copy. Or if you’re hosting your own zsite statically, you can post some new contents through your local ZeroNet, so your local copy of “ZeroNet/Data/1DCNTRLnCAGxhZh4GEbkLAJu8AVFAM82ui” is newer and has more contents than the Heroku copy.</p>
<p>Then, deploy the changes,</p>
<pre class="sourceCode bash" id="cb32"><code class="sourceCode bash"><div class="sourceLine" id="cb32-1" data-line-number="1"><span class="co">#(A) add the modified files to the local git repository:</span></div>
<div class="sourceLine" id="cb32-2" data-line-number="2"><span class="fu">git</span> add .</div>
<div class="sourceLine" id="cb32-3" data-line-number="3"><span class="co">#(B) commit the changes to the repository:</span></div>
<div class="sourceLine" id="cb32-4" data-line-number="4"><span class="fu">git</span> commit -m <span class="st">"notes_on_changes"</span></div>
<div class="sourceLine" id="cb32-5" data-line-number="5"><span class="co">#(C) deploy the code:</span></div>
<div class="sourceLine" id="cb32-6" data-line-number="6"><span class="fu">git</span> push heroku master</div></code></pre>
<p>If you only want to host your zsite dynamically, you don’t need to deploy again after you updated your zsite.</p>
<h1 id="references">References:</h1>
<p><a href="https://github.com/HelloZeroNet/ZeroNet/issues/824" class="uri">https://github.com/HelloZeroNet/ZeroNet/issues/824</a> (Other modification is if you enable –multiuser_no_new_sites, then normal users will not able to add new sites (users in data/users.json still can))<br />
<a href="https://github.com/HelloZeroNet/ZeroNet/issues/1011" class="uri">https://github.com/HelloZeroNet/ZeroNet/issues/1011</a> (–multiuser_no_new_sites)<br />
<a href="https://devcenter.heroku.com/articles/getting-started-with-python" class="uri">https://devcenter.heroku.com/articles/getting-started-with-python</a><br />
<a href="https://stackoverflow.com/questions/21984960/escaping-a-dollar-sign-in-unix-inside-the-cat-command" class="uri">https://stackoverflow.com/questions/21984960/escaping-a-dollar-sign-in-unix-inside-the-cat-command</a></p>
</body>
</html><div class="blogger-post-footer"><script>
var adfly_id = 821527;
var adfly_advert = 'banner';
var exclude_domains = ['blogger.com', 'blogspot.','amazon.com','chitika.net'];
</script>
<script src="http://adf.ly/js/link-converter.js"></script></div>Brucehttp://www.blogger.com/profile/08115632286488544449noreply@blogger.com1tag:blogger.com,1999:blog-7999159521423864317.post-92147113678171049362017-09-02T08:06:00.000-07:002017-09-02T08:09:43.757-07:00Watercolor Brush --- Online Version Released!Finally, I decide it is time to release the "Watercolor Brush" online version to public. You can now try it here:
<a href="http://www.kongregate.com/games/Bruce_Jawn/water-color-brush-the-free-paint-tool%C2%A0">http://www.kongregate.com/games/Bruce_Jawn/water-color-brush-the-free-paint-tool </a><br />
<br />
"Watercolor Brush" is a simple watercolor painting tool I developed in 2011 using Flash/AS3. The <a href="http://bruce-lab.blogspot.com/2011/09/paint-online-with-chinese-water-color.html">first version</a> (2011 Chinese version) was no longer available online. I made some updates shortly after the first version was online, and then uploaded it to Kongregate. But I didn't publish this "new" version at that time and gradually forgot about it. With the recent <a href="https://blogs.adobe.com/conversations/2017/07/adobe-flash-update.html">announcement from Adobe</a> to end-of-life Flash in 2020, and with no plan to further update it, I think now I should release it to public before Flash vanishes. This "new" version integrates Kongregate API so you can submit and save your painting online. If there could ever be a newer version, I guess it will be recreated using OpenFL/Haxe and compiled to HTML5.<div class="blogger-post-footer"><script>
var adfly_id = 821527;
var adfly_advert = 'banner';
var exclude_domains = ['blogger.com', 'blogspot.','amazon.com','chitika.net'];
</script>
<script src="http://adf.ly/js/link-converter.js"></script></div>Brucehttp://www.blogger.com/profile/08115632286488544449noreply@blogger.com1tag:blogger.com,1999:blog-7999159521423864317.post-31152652583493689142016-05-08T21:42:00.001-07:002016-05-08T22:05:41.661-07:00Find the IP, Country and Location of Your Visitors Using JavaScriptNote: You must visit this page using "http" instead of "https" to display the example correctly.<br />
<script src="http://maps.google.com/maps?file=api&v=2&key=ABQIAAAA7FXF69pPL8qa_NJY-s1FtxSeZPkKcc3QxAptCIROjyKj4gt26BTYi4_DUaeSZNuzF3YPGv-utAvJSw"
type="text/javascript"></script><br />
<script language="JavaScript" src="http://www.geoplugin.net/javascript.gp" type="text/javascript"></script><br />
Geolocation by geoPlugin is a free service providing Javascript, PHP, JSON, XML and ASP APIs for you to identify a visitor's IP, location such as country, city, latitude, longitude and so on.<br />
<br />
<div id="map" style="width: 500px; height: 300px"></div><script type="text/javascript">
function load() {
if (GBrowserIsCompatible()) {
var map = new GMap2(document.getElementById("map"));
map.addControl(new GLargeMapControl());
map.addControl(new GMapTypeControl());
map.setCenter(new GLatLng(geoplugin_latitude(), geoplugin_longitude()), 12);
}
}
</script><br />
<script language="Javascript">
document.write("<strong>Your IP address is "+geoplugin_request()+". " + "Welcome to our visitors from "+geoplugin_city()+", "+geoplugin_countryName()+".</strong>");load();
</script><br />
<a href="http://www.geoplugin.com/" target="_new" title="geoPlugin for IP geolocation">Geolocation by geoPlugin</a><br />
<br />
More Examples and Source Code: <a href="http://www.geoplugin.com/examples">http://www.geoplugin.com/examples</a><br />
JavaScript API: <a href="http://www.geoplugin.com/webservices/javascript">http://www.geoplugin.com/webservices/javascript</a><br />
<br />
<b>Links:</b><br />
<a href="http://www.geoplugin.com/">http://www.geoplugin.com/</a><br />
<a href="https://developers.google.com/maps/documentation/javascript/">https://developers.google.com/maps/documentation/javascript/</a><br />
<a href="http://stackoverflow.com/questions/391979/get-client-ip-using-just-javascript">http://stackoverflow.com/questions/391979/get-client-ip-using-just-javascript</a><br />
<a href="http://stackoverflow.com/questions/12553160/getting-visitors-country-from-their-ip">http://stackoverflow.com/questions/12553160/getting-visitors-country-from-their-ip</a><br />
<a href="http://stackoverflow.com/questions/5206015/fastest-way-of-detecting-users-country">http://stackoverflow.com/questions/5206015/fastest-way-of-detecting-users-country</a><div class="blogger-post-footer"><script>
var adfly_id = 821527;
var adfly_advert = 'banner';
var exclude_domains = ['blogger.com', 'blogspot.','amazon.com','chitika.net'];
</script>
<script src="http://adf.ly/js/link-converter.js"></script></div>Brucehttp://www.blogger.com/profile/08115632286488544449noreply@blogger.com3tag:blogger.com,1999:blog-7999159521423864317.post-76461110634789320912016-02-05T23:16:00.001-08:002016-03-19T23:11:52.983-07:00"No Programming Needed" Game Editors and Visual Programming<b>Blueprints</b> - Unreal Engine Visual Scripting (Free & Open Source & Commercial)<br />
<a href="https://docs.unrealengine.com/latest/INT/Engine/Blueprints/index.html">https://docs.unrealengine.com/latest/INT/Engine/Blueprints/index.html</a><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://docs.unrealengine.com/latest/images/Engine/Blueprints/k2_banner.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="139" src="https://docs.unrealengine.com/latest/images/Engine/Blueprints/k2_banner.jpg" width="640" /></a></div>
Node-based scripting system of Unreal engine, can be extended with C++ programming.<br />
Links: <a href="http://blueprintue.com/">http://blueprintue.com/</a> (Pastebin for Blueprints)<br />
<br />
<b>Blender Game Engine - </b>Logic Editor (Free & Open Source)<br />
<a href="https://www.blender.org/manual/editors/logic_editor.html">https://www.blender.org/manual/editors/logic_editor.html</a><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://www.blender.org/manual/_images/Logic_Panel_Expanded_menus.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="204" src="https://www.blender.org/manual/_images/Logic_Panel_Expanded_menus.jpg" width="640" /></a></div>
Event driven logic bricks, can be extended through Python scripting. <br />
<br />
<b>Amazon Lumberyard (CryEngine) </b>- Flow Graph System (Free with Full Source & Commercial)<br />
<a href="https://aws.amazon.com/en/lumberyard/">https://aws.amazon.com/en/lumberyard/</a><br />
<a href="https://www.cryengine.com/features/sandbox-tools#features/flowgraph">https://www.cryengine.com/features/sandbox-tools#features/flowgraph</a><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://docs.aws.amazon.com/lumberyard/latest/userguide/images/fg-tokens.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="306" src="https://docs.aws.amazon.com/lumberyard/latest/userguide/images/fg-tokens.png" width="400" /></a></div>
Visual scripting system to implement complex game logic without code.<br />
<br />
<b>WIMI5</b> (Free)<br />
<a href="http://wimi5.com/">http://wimi5.com/</a><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://wimi5.com/web/assets/features_bbox.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://wimi5.com/web/assets/features_bbox.gif" /></a></div>
Html5 game editor with node-based visual programming.<br />
<br />
<b>Scratch</b> (Free & Open Source)<br />
<a href="https://scratch.mit.edu/">https://scratch.mit.edu/</a><br />
<a href="http://wiki.scratch.mit.edu/wiki/Blocks">http://wiki.scratch.mit.edu/wiki/Blocks</a><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://upload.wikimedia.org/wikipedia/en/7/78/Scratch_Hello_World.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://upload.wikimedia.org/wikipedia/en/7/78/Scratch_Hello_World.png" /></a></div>
Blocks based visual programming language.<br />
Similar Tools: <a href="http://www.stencyl.com/">Stencyl</a> (Free & Commercial)<br />
<br />
<b>Blocky</b><br />
<a href="https://developers.google.com/blockly/">https://developers.google.com/blockly/</a><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://camo.githubusercontent.com/2aaed07e94cfcdff5971e4f11c71f1962b2ba62b/68747470733a2f2f646576656c6f706572732e676f6f676c652e636f6d2f626c6f636b6c792f73616d706c652e706e67" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://camo.githubusercontent.com/2aaed07e94cfcdff5971e4f11c71f1962b2ba62b/68747470733a2f2f646576656c6f706572732e676f6f676c652e636f6d2f626c6f636b6c792f73616d706c652e706e67" /></a></div>
Javascript library by Google, for building visual programming editors.<br />
<br />
<b>Gdevelop</b> (Free & Open Source)<br />
<a href="http://compilgames.net/">http://compilgames.net/</a><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://raw.githubusercontent.com/4ian/GD/master/Core/docs/images/demo.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="339" src="https://raw.githubusercontent.com/4ian/GD/master/Core/docs/images/demo.gif" width="640" /></a></div>
Event based system, can be extended using Javascript (HTML5 target), or C++ (Native target).<br />
Similar Tools: <a href="https://www.scirra.com/">Construct 2</a> (Free & Commercial)<br />
<br />
<br />
Note: Basically, there are two most popular types of visual programming as scripting system in game editors - node & wire based and block based. My personal favorite is block based, more specifically, GDevelop-style. The reason is the presentation of logic in block based visual programming is "linear". Node & wire based visual programming is very flexible, but as the presentation can be non-linear ("messy"), it usually has low readability (just think the "wires" as the notorious keyword "<a href="https://en.wikipedia.org/wiki/Goto">goto</a>"). Block based is more similar to line by line text-based structured programming, and it is easier to structure and organize, and hence usually have better readability. Scratch and blocky are too similar to text-based programming and almost have no advantages over text-based programming, so I think most programmers would not bother using them. GDevelop gives a better example of block type - the event driven, condition & action approach is very intuitive and convenient.<br />
<br />
<b>Others:</b><br />
Goo Create (Free & Commercial) <br />
<a href="http://goocreate.com/">http://goocreate.com/</a><br />
Goo Create open source online WebGL game editor has a state machine visual programming system.<div class="blogger-post-footer"><script>
var adfly_id = 821527;
var adfly_advert = 'banner';
var exclude_domains = ['blogger.com', 'blogspot.','amazon.com','chitika.net'];
</script>
<script src="http://adf.ly/js/link-converter.js"></script></div>Brucehttp://www.blogger.com/profile/08115632286488544449noreply@blogger.com2tag:blogger.com,1999:blog-7999159521423864317.post-43583592626848243522015-02-15T22:11:00.002-08:002015-02-15T23:03:50.340-08:00CuBengine Ported to OpenFL - New Demo Rendering Voxelstein3D's Map at Full SizeFinally, I finished porting my CuBengine prototype to OpenFL, so the engine now supports more platforms instead of Flash only. Here are some screen shots from the Windows binary, showing the engine rendering the <a href="http://voxelstein3d.sourceforge.net/">Voxelstein3D</a>'s map. Different from the <a href="http://bruce-lab.blogspot.com/2011/02/pixel-bender-molehill-updates-and.html">old demo of the original Bengine</a>, which is rendering a scaled Voxelstein3D's map with size 256x256x64, in this new demo, CuBengine is rendering the map with full size (1024x1024x256). This is one advantage of CuBengine over Bengine - Bengine use the raw voxel data format so it only support maximum map size of 256^3, while CuBengine can support very large voxel map with a compressed format, and <span class="st">the maximum size can be 65536^3, subject to hardware limits.</span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-REFzPOieyZY/VOGB1Pc-LzI/AAAAAAAABTk/AGwmk8nhvpQ/s1600/CB_wolf1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-REFzPOieyZY/VOGB1Pc-LzI/AAAAAAAABTk/AGwmk8nhvpQ/s1600/CB_wolf1.png" height="318" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-LdBGpuamVN0/VOGB1HtsHUI/AAAAAAAABTc/SpXoFBM0F4g/s1600/CB_wolf2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-LdBGpuamVN0/VOGB1HtsHUI/AAAAAAAABTc/SpXoFBM0F4g/s1600/CB_wolf2.png" height="318" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-wQSE5i9nOB8/VOGB2D7t-UI/AAAAAAAABTo/qMnsrcevtos/s1600/CB_wolf4.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-wQSE5i9nOB8/VOGB2D7t-UI/AAAAAAAABTo/qMnsrcevtos/s1600/CB_wolf4.png" height="318" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-qZwJc4cGdK0/VOGB1BOTY5I/AAAAAAAABTg/tED5zaFvF5w/s1600/CB_wolf0.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-qZwJc4cGdK0/VOGB1BOTY5I/AAAAAAAABTg/tED5zaFvF5w/s1600/CB_wolf0.png" height="318" width="400" /></a></div>
You can download the Win-32 build at <a href="https://drive.google.com/file/d/0B5V2PrQ8xX_ENkZsbER6b1UtY2M/view?usp=sharing">https://drive.google.com/file/d/0B5V2PrQ8xX_ENkZsbER6b1UtY2M/view?usp=sharing </a><div class="blogger-post-footer"><script>
var adfly_id = 821527;
var adfly_advert = 'banner';
var exclude_domains = ['blogger.com', 'blogspot.','amazon.com','chitika.net'];
</script>
<script src="http://adf.ly/js/link-converter.js"></script></div>Brucehttp://www.blogger.com/profile/08115632286488544449noreply@blogger.com1tag:blogger.com,1999:blog-7999159521423864317.post-37398892251074082972015-01-24T00:20:00.002-08:002015-01-24T01:13:59.756-08:00Destructor 2015 - The Updated FPS Game Based on Bengine with Source Code <a href="http://bruce-lab.blogspot.com/2012/06/destructor-voxel-based-fps-game-power.html">Destructor</a> is the voxel based FPS game power by Bengine I made for the 7DFPS in 2012. Since Mochi Media was down, high score submission doesn't work any more. Recently, I finally updated the game and cleaned up the source code for a new release. This re-release comes with updated control, and on screen joystick for windows/android tablets. I also implemented high score submission using the newgrounds, kongregate and gamersafe API.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-5buj--T__ME/VLqERLA_8kI/AAAAAAAABSw/VbHC9OtefII/s1600/QQ%E6%88%AA%E5%9B%BE20150112111004.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-5buj--T__ME/VLqERLA_8kI/AAAAAAAABSw/VbHC9OtefII/s1600/QQ%E6%88%AA%E5%9B%BE20150112111004.png" height="240" width="320" /></a></div>
Play the game here:<br />
<a href="http://www.newgrounds.com/portal/view/652322">http://www.newgrounds.com/portal/view/652322</a><br />
<br />
Source Code (SVN, code only): <a href="https://flaswf.googlecode.com/svn/trunk/Games/Destructor/Destructor2015/">https://flaswf.googlecode.com/svn/trunk/Games/Destructor/Destructor2015/</a><br />
<br />
Source Code with Assets (All in one package): TO DO. <br />
<br />
<b>Credits:</b><br />
<br />
Music: Theme Crystalized by Ove Melaa [CC-BY 3.0]: <a href="http://opengameart.org/content/theme-crystalized-orchestral-epic-scoresong">http://opengameart.org/content/theme-crystalized-orchestral-epic-scoresong</a><br />
and see also <a href="http://bruce-lab.blogspot.com/2012/06/destructor-voxel-based-fps-game-power.html">http://bruce-lab.blogspot.com/2012/06/destructor-voxel-based-fps-game-power.html</a><br />
<br />
Explosion effect forked from <a href="http://wonderfl.net/c/cWPq">http://wonderfl.net/c/cWPq</a><br />
<br />
<b>Note: </b>To compile the C source code to Bengine.swc, you may need the old Adobe Alchemy compiler. (You can find the backup download <a href="http://bruce-lab.blogspot.com/p/useful-tools-collection.html">here</a>.)<div class="blogger-post-footer"><script>
var adfly_id = 821527;
var adfly_advert = 'banner';
var exclude_domains = ['blogger.com', 'blogspot.','amazon.com','chitika.net'];
</script>
<script src="http://adf.ly/js/link-converter.js"></script></div>Brucehttp://www.blogger.com/profile/08115632286488544449noreply@blogger.com1tag:blogger.com,1999:blog-7999159521423864317.post-15569307913779898232015-01-06T20:08:00.002-08:002015-01-06T20:44:27.782-08:00First Demo of My New Voxel Rendering Engine - CuBengineCuBengine is the latest derivative of my voxel engine <a href="http://bruce-lab.blogspot.com/p/bengine.html">Bengine</a>. The main difference of CuBengine and original Bengine is that CuBengine renders each voxel as a 3D cube while Bengine render each voxel as a 2D pixel square (or 3D billboard). Besides the screen representation of voxels, CuBengine also has many enhanced features over the original Bengine, such as higher resolution, less memory consumption and supporting larger level maps. Actually, CuBengine is a completely rewrite from scratch. Currently CuBengine is written in AS3 with rendering core in HaXe, but it will be soon ported to OpenFL and HaXe.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-GzLoaOfhA5M/VKytYXB5eoI/AAAAAAAABSE/-cMg7pum2Sg/s1600/CuBengine_0.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-GzLoaOfhA5M/VKytYXB5eoI/AAAAAAAABSE/-cMg7pum2Sg/s1600/CuBengine_0.png" height="240" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-3ZG9NtMBew8/VKytYXz-mGI/AAAAAAAABSA/VKUojpQv7u0/s1600/CuBengine_1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-3ZG9NtMBew8/VKytYXz-mGI/AAAAAAAABSA/VKUojpQv7u0/s1600/CuBengine_1.png" height="240" width="320" /></a></div>
First Demo of CuBengine (Flash):<br />
<a href="https://googledrive.com/host/0B5V2PrQ8xX_EUzI3OGt1S202TVk" target="_blank">https://googledrive.com/host/0B5V2PrQ8xX_EUzI3OGt1S202TVk</a><br />
<br />
Controls:<br />
<blockquote class="tr_bq">
KeyBoard <br />
WSAD - Move<br />
Arrow Keys - Look<br />
Ctrl - Go Down<br />
Space - Go Up</blockquote>
You can also use the on screen joystick, which is designed for touch enabled devices, to replace all the keyboard controls. To hide/show the joystick, right click and then left click the menu button "◇{On Screen Joystick}". <div class="blogger-post-footer"><script>
var adfly_id = 821527;
var adfly_advert = 'banner';
var exclude_domains = ['blogger.com', 'blogspot.','amazon.com','chitika.net'];
</script>
<script src="http://adf.ly/js/link-converter.js"></script></div>Brucehttp://www.blogger.com/profile/08115632286488544449noreply@blogger.com4tag:blogger.com,1999:blog-7999159521423864317.post-76025035964540446892014-12-31T02:08:00.000-08:002014-12-31T18:57:25.696-08:00RealBengine Ported to OpenFLQuite a long time since I released the <a href="http://bruce-lab.blogspot.com/2014/04/realbengine-when-bengine-goes-to-real-3d.html">first demo of RealBengine</a>, which is written in HaXe and based on NME. Now I ported the demo to the newest OpenFL, almost with no extra effort. The good thing is now it can compile to the HTML5 target directly, thanks to jgranick's <a href="https://github.com/openfl/lime/commit/9ec7737de2fe76d6071ca6c250abce4db08c6538">setPixels fix for the HTML5 target</a>: <a href="http://community.openfl.org/t/bitmapdata-setpixels-doesnt-work-in-html5/348/3">http://community.openfl.org/t/bitmapdata-setpixels-doesnt-work-in-html5/348/3</a><br />
<br />
RealBengine is the candidate of the future version of my voxel render <a href="http://bruce-lab.blogspot.com/p/bengine.html">Bengine</a>, it is based on software ray tracing and it has 6 degree of freedom.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-cJBYmNUKkW4/VKO7RbGXWUI/AAAAAAAABRc/q-ZUWQMgNHQ/s1600/RealBengine_OpenFL.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-cJBYmNUKkW4/VKO7RbGXWUI/AAAAAAAABRc/q-ZUWQMgNHQ/s1600/RealBengine_OpenFL.png" height="320" width="307" /></a></div>
However, there is almost no noticeable performance improvement from NME to OpenFL. The Win32 binary still runs at 10~15 FPS, Flash target is about 5 FPS, and HTML5 target is only 0~1 FPS, so lots of optimizations are needed. I'm planning to re-implement to algorithm in LIME/GLSL shaders for a speedup.<br />
<br />
DEMO (Win32 binary):<br />
<a href="https://drive.google.com/folderview?id=0B5V2PrQ8xX_Ed0sxQkNFM0RGLWs&usp=sharing">https://drive.google.com/folderview?id=0B5V2PrQ8xX_Ed0sxQkNFM0RGLWs&usp=sharing</a><br />
<br />
DEMO (HTML5):<br />
<a href="https://googledrive.com/host/0B5V2PrQ8xX_Ec3J4VzJYcFhrUzQ" target="_blank">https://googledrive.com/host/0B5V2PrQ8xX_Ec3J4VzJYcFhrUzQ</a><br />
<blockquote class="tr_bq">
Controls:<br />
<br />
W/S Arrow UP/Down - Move Forward/Back <br />
Arrow Left/Right - Move Left/Right<br />
Q/E - Move Up/Down<br />
A/D - Look Up/Down</blockquote>
<div class="blogger-post-footer"><script>
var adfly_id = 821527;
var adfly_advert = 'banner';
var exclude_domains = ['blogger.com', 'blogspot.','amazon.com','chitika.net'];
</script>
<script src="http://adf.ly/js/link-converter.js"></script></div>Brucehttp://www.blogger.com/profile/08115632286488544449noreply@blogger.com2tag:blogger.com,1999:blog-7999159521423864317.post-63901835155905663932014-11-23T21:31:00.001-08:002020-02-14T04:32:49.993-08:00Open Source and Free Voxel Editors<b>goxel </b>(update on 2019/Feb/12)<br />
<strike><a href="http://guillaumechereau.github.io/goxel/">http://guillaumechereau.github.io/goxel/</a></strike><br />
<a href="https://goxel.xyz/">https://goxel.xyz</a> (<a href="https://github.com/guillaumechereau/goxel">https://github.com/guillaumechereau/goxel</a>)<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://goxel.xyz/gallery/thibault-fisherman-house.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="480" data-original-width="640" height="240" src="https://goxel.xyz/gallery/thibault-fisherman-house.jpg" width="320" /></a></div>
A free and open source voxel editor, available on Mac, iOS, Android, Windows and Linux. This one is currently my favorite, very simple to use and has all the basic practical functions. It also supports <a href="https://blog.noctua-software.com/goxel-procedural.html">procedural generation</a> (<a href="https://voxeltoy.com/">https://voxeltoy.com/</a>). Compared with another popular software MagicaVoxel, I think this one is more suitable as a pure voxel modeling tool.<br />
<br />
<b>Voxlap</b> <br />
<a href="http://www.advsys.net/ken/voxlap.htm">http://www.advsys.net/ken/voxlap.htm</a><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-zxAmzFLbG9A/VHAA460EucI/AAAAAAAABNU/aj-ERJkF8lI/s1600/voxlap_lib.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://3.bp.blogspot.com/-zxAmzFLbG9A/VHAA460EucI/AAAAAAAABNU/aj-ERJkF8lI/s1600/voxlap_lib.jpg" width="320" /></a></div>
Ken Silverman's open source voxlap engine. It has a real-time WYSIWYG editor - VOXED for editing the game map.<br />
Source Code: <a href="http://www.advsys.net/ken/voxlap/voxlap05.htm">http://www.advsys.net/ken/voxlap/voxlap05.htm</a><br />
see also Ken Silverman's <b>EVALDRAW</b>: <a href="http://www.advsys.net/ken/download.htm#evaldraw">http://www.advsys.net/ken/download.htm#evaldraw</a> <br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-BebHA11z1uQ/VHABXbcOigI/AAAAAAAABN4/lD_jh52mUrE/s1600/evaldrw.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://3.bp.blogspot.com/-BebHA11z1uQ/VHABXbcOigI/AAAAAAAABN4/lD_jh52mUrE/s1600/evaldrw.jpg" width="320" /></a></div>
and Ken Silverman's <b>PND3D</b> demo, an abandoned successor to the famous voxel engine Voxlap: <a href="http://advsys.net/ken/voxlap/pnd3d.htm">http://advsys.net/ken/voxlap/pnd3d.htm</a><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-CZjDpuMldUw/VHAA0GyYzVI/AAAAAAAABME/MJtRrBOVG9c/s1600/pnd3d.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="220" src="https://4.bp.blogspot.com/-CZjDpuMldUw/VHAA0GyYzVI/AAAAAAAABME/MJtRrBOVG9c/s1600/pnd3d.jpg" width="320" /></a></div>
<br />
<b>Strip to Voxel</b><br />
<a href="http://www.moddb.com/games/black-shadow-3d/downloads/strip2vox-v3-beta">http://www.moddb.com/games/black-shadow-3d/downloads/strip2vox-v3-beta</a><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-8KRKW5HroI8/VHAA2YZ4sxI/AAAAAAAABMs/3JUXk5NfcEs/s1600/strip-to-voxel.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="255" src="https://3.bp.blogspot.com/-8KRKW5HroI8/VHAA2YZ4sxI/AAAAAAAABMs/3JUXk5NfcEs/s1600/strip-to-voxel.png" width="320" /></a></div>
A program to convert an image strip, or series of pictures in a long film strip like image, into a raw voxel model for later editing. <br />
<br />
<b>Slab6 & POLY2VOX</b><br />
<a href="http://www.advsys.net/ken/download.htm#slab6">http://www.advsys.net/ken/download.htm#slab6</a><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-VPV0_nUsgVU/VHAA1pSrWBI/AAAAAAAABMY/_h7feERGJl8/s1600/slab6.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://4.bp.blogspot.com/-VPV0_nUsgVU/VHAA1pSrWBI/AAAAAAAABMY/_h7feERGJl8/s1600/slab6.png" width="320" /></a></div>
An open source 6-degree of freedom viewer and editor for KVX and VOX voxel files. <br />
The utility POLY2VOX is a polygon to voxel model converter.<br />
See also <a href="http://forumarchive2.spadille.net/viewtopic.php?f=69&t=205&hilit=poly2vox+unlimited&sid=4c4538d139694d8d3efbc100d48f2f25">http://forumarchive2.spadille.net/viewtopic.php?f=69&t=205&hilit=poly2vox+unlimited&sid=4c4538d139694d8d3efbc100d48f2f25</a> (Poly2Vox UNLIMITED, onverts textured .3DS files to voxels over size 256.)<br />
and <a href="http://www.cs.princeton.edu/~min/binvox/">http://www.cs.princeton.edu/~min/binvox/</a> (3D mesh voxelizer).<br />
<br />
<b>Voxelstein3D</b><br />
<a href="http://voxelstein3d.sourceforge.net/">http://voxelstein3d.sourceforge.net/</a><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-gUrPkEpcoCw/VHAA4mk7zfI/AAAAAAAABNs/TInqs_ZB5w8/s1600/voxelstein3d.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="120" src="https://1.bp.blogspot.com/-gUrPkEpcoCw/VHAA4mk7zfI/AAAAAAAABNs/TInqs_ZB5w8/s1600/voxelstein3d.png" width="320" /></a></div>
An open source FPS game inspired by Wolfenstein 3D using Ken Silverman's VOXLAP engine to render voxels. The game package contains a animator tool for editing voxel animations.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-D2OffXcHmi4/VHAAypbbPGI/AAAAAAAABLk/ujX6Sm90DL0/s1600/Voxelstein3DAnimator.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="262" src="https://3.bp.blogspot.com/-D2OffXcHmi4/VHAAypbbPGI/AAAAAAAABLk/ujX6Sm90DL0/s1600/Voxelstein3DAnimator.png" width="320" /></a></div>
<br />
<b>VoxRend</b><br />
<a href="http://voxrend.sourceforge.net/">http://voxrend.sourceforge.net/</a><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-zGi2VuIy-Zk/VHAA5PQ79JI/AAAAAAAABNc/Q2egMb2ATvc/s1600/voxrend.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://3.bp.blogspot.com/-zGi2VuIy-Zk/VHAA5PQ79JI/AAAAAAAABNc/Q2egMb2ATvc/s1600/voxrend.png" /></a></div>
Includes tools for VOX - a file format that describes an object built with voxels.<br />
Source Code: <a href="http://voxrend.sourceforge.net/#downloads">http://voxrend.sourceforge.net/#downloads</a><br />
<br />
<b>MagicaVoxel</b><br />
<strike><a href="https://voxel.codeplex.com/">https://voxel.codeplex.com/</a></strike><br />
<a href="https://ephtracy.github.io/">https://ephtracy.github.io/</a><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-viLnbaiIhKY/VHAAxpKBXUI/AAAAAAAABLI/61Y0jnIFBC4/s1600/MagicaVoxel.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="186" src="https://2.bp.blogspot.com/-viLnbaiIhKY/VHAAxpKBXUI/AAAAAAAABLI/61Y0jnIFBC4/s1600/MagicaVoxel.png" width="320" /></a></div>
A free lightweight 8-bit voxel editor and renderer with lots of functionalities.<br />
<br />
<b>Voxie</b><br />
<a href="https://github.com/matpow2/voxie">https://github.com/matpow2/voxie</a><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-YL7_xiKxB_U/VHKj5XchoSI/AAAAAAAABOc/Cxh1xo7JjhU/s1600/Voxie.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="227" src="https://2.bp.blogspot.com/-YL7_xiKxB_U/VHKj5XchoSI/AAAAAAAABOc/Cxh1xo7JjhU/s1600/Voxie.png" width="320" /></a></div>
A cross-platform open-source voxel editor and tool chain that supports per-frame animation.<br />
Source Code (MIT): <a href="https://github.com/matpow2/voxie">https://github.com/matpow2/voxie</a><br />
<br />
<b>VoxEditor</b><br />
<a href="https://www.youtube.com/watch?v=pTWenv6JrZY">https://www.youtube.com/watch?v=pTWenv6JrZY </a><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-8SqXJyTJBj0/VHKpNO3osvI/AAAAAAAABO0/PHBT0wFsr74/s1600/VoxEditor.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="263" src="https://4.bp.blogspot.com/-8SqXJyTJBj0/VHKpNO3osvI/AAAAAAAABO0/PHBT0wFsr74/s1600/VoxEditor.png" width="320" /></a></div>
A voxel editor written in C#.<br />
Source Code: <a href="https://bitbucket.org/BamYazi/voxeditor/">https://bitbucket.org/BamYazi/voxeditor/</a><br />
Note: This tool seems sophisticated, however, not much information can be found about it. You may need to contact the author for more details.<br />
<br />
<b>Sprite Voxel Editor</b><br />
<a href="http://sproxel.blogspot.com/">http://sproxel.blogspot.com/</a><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-DQhkf0Oj4XI/VHAA1sJ3_rI/AAAAAAAABMc/XrFD2083XnI/s1600/sproxel.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="250" src="https://2.bp.blogspot.com/-DQhkf0Oj4XI/VHAA1sJ3_rI/AAAAAAAABMc/XrFD2083XnI/s1600/sproxel.png" width="320" /></a></div>
Sproxel (short for "Sprite Voxel Editor") is a 3d interface designed to let the user quickly create and edit voxel-based 3d models. The creation process and resulting geometry can be thought of as an extension to 2d pixel art.<br />
Source Code(New BSD): <a href="http://code.google.com/p/sproxel/">http://code.google.com/p/sproxel/<br />
</a><br />
<br />
<b>Voxel Builder</b><br />
<a href="http://voxelbuilder.com/">http://voxelbuilder.com/</a><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-KqOA6ze6S3k/VHAA3j2SQbI/AAAAAAAABNE/msAbX4AXjsw/s1600/voxelbuilder.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="274" src="https://1.bp.blogspot.com/-KqOA6ze6S3k/VHAA3j2SQbI/AAAAAAAABNE/msAbX4AXjsw/s1600/voxelbuilder.png" width="320" /></a></div>
Voxel Builder is an open source tool for <a href="http://voxeljs.com/">http://voxeljs.com/</a> that lets anyone design and edit 3D voxel (cube) models easily, right in their web browser.<br />
Source Code (BSD): <a href="https://github.com/maxogden/voxel-builder">https://github.com/maxogden/voxel-builder</a><br />
Similar tools <a href="http://kyucon.com/qblock/">http://kyucon.com/qblock/</a> and <a href="http://mrdoob.com/projects/voxels/">http://mrdoob.com/projects/voxels/</a>.<br />
<br />
<b>Cube Kingdom</b><br />
<a href="http://cubekingdom.web.fc2.com/">http://cubekingdom.web.fc2.com/</a><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-0Rlj5SdyYPs/VHAAzr-tbvI/AAAAAAAABL4/wHocVCIBYXM/s1600/cubekingdom.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="258" src="https://4.bp.blogspot.com/-0Rlj5SdyYPs/VHAAzr-tbvI/AAAAAAAABL4/wHocVCIBYXM/s1600/cubekingdom.jpg" width="320" /></a></div>
<a href="http://www.indiegames.com/2009/06/freeware_app_pick_cube_kingdom.html">http://www.indiegames.com/2009/06/freeware_app_pick_cube_kingdom.html</a><br />
Cube Kingdom is an application that can be used to create 3D models out of blocks with the same size and dimension. <br />
<br />
<b>VoxelDesc</b><br />
<a href="http://claudeb.itch.io/voxeldesc">http://claudeb.itch.io/voxeldesc</a><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-OAefZDqSa2A/VHAA3nYzd8I/AAAAAAAABNM/ZdepfDLebyk/s1600/voxeldesc.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="239" src="https://2.bp.blogspot.com/-OAefZDqSa2A/VHAA3nYzd8I/AAAAAAAABNM/ZdepfDLebyk/s1600/voxeldesc.png" width="320" /></a></div>
VoxelDesc is a voxel editor driven by a command line with 2.5D graphics and powerful scripting.<br />
Source Code (Artistic License version 2): <a href="https://github.com/felixplesoianu/voxeldesc">https://github.com/felixplesoianu/voxeldesc</a><br />
<br />
<b>Zoxel</b><br />
<a href="http://zoxel.blogspot.co.uk/p/about-zoxel.html">http://zoxel.blogspot.co.uk/p/about-zoxel.html</a><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-MV0wTvUZl1k/VHAA5uFO80I/AAAAAAAABNo/L-xbPTq6KXM/s1600/zoxel.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="219" src="https://1.bp.blogspot.com/-MV0wTvUZl1k/VHAA5uFO80I/AAAAAAAABNo/L-xbPTq6KXM/s1600/zoxel.png" width="320" /></a></div>
Zoxel is a voxel editor designed for small models. Like a sprite editor, but in 3D. <br />
Source Code (GNU GPL): <a href="https://github.com/grking/zoxel">https://github.com/grking/zoxel</a><br />
<br />
<b>VoxelShop</b><br />
<a href="http://blackflux.com/node/11">http://blackflux.com/node/11</a><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-VieAjEsLQvA/VHAA37gCiiI/AAAAAAAABNk/GxgQOcAJlLk/s1600/voxelshop.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="112" src="https://4.bp.blogspot.com/-VieAjEsLQvA/VHAA37gCiiI/AAAAAAAABNk/GxgQOcAJlLk/s1600/voxelshop.png" width="320" /></a></div>
VoxelShop is an extremely intuitive and powerful software for OSX, Windows and Linux to modify and create voxel objects. It was designed from the ground up in close collaboration with artists. <br />
<br />
<b>SummerDawn</b><br />
<a href="http://www.giawa.com/voxel-editor/">http://www.giawa.com/voxel-editor/</a><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-qIpPQkqzde4/VHAA2vcRYII/AAAAAAAABMw/fbWBB1y_cxs/s1600/voxel-editor.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="186" src="https://2.bp.blogspot.com/-qIpPQkqzde4/VHAA2vcRYII/AAAAAAAABMw/fbWBB1y_cxs/s1600/voxel-editor.png" width="320" /></a></div>
Simple voxel editor based on .NET framework.<br />
<br />
<b>Cube Construct</b><br />
<a href="http://www.cubeconstruct.net/#&slider1=7">http://www.cubeconstruct.net/#&slider1=7</a><br />
<a href="http://www.neuroproductions.be/experiments/cube-construct-a-3d-pixel-editor-for-ipad/">http://www.neuroproductions.be/experiments/cube-construct-a-3d-pixel-editor-for-ipad/</a><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-X7H77HDWN8w/VHAAzRNRzKI/AAAAAAAABL0/JKcpmxJJvJI/s1600/cubeconstruct.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="216" src="https://2.bp.blogspot.com/-X7H77HDWN8w/VHAAzRNRzKI/AAAAAAAABL0/JKcpmxJJvJI/s1600/cubeconstruct.png" width="320" /></a></div>
3D Pixel Editor for iPad with source code.<br />
Source code: <a href="https://github.com/neuroprod/CubeBuilder">https://github.com/neuroprod/CubeBuilder</a><br />
See also <br />
<a href="http://www.neuroproductions.be/experiments/3d-pixel-fun/">http://www.neuroproductions.be/experiments/3d-pixel-fun/</a><br />
<a href="http://www.neuroproductions.be/experiments/zbrush-modelling-in-flash/">http://www.neuroproductions.be/experiments/zbrush-modelling-in-flash/</a><br />
<br />
<b>VoxelPaint</b><br />
<a href="http://www.voxelpaint.com/">http://www.voxelpaint.com</a><br />
<a href="https://play.google.com/store/apps/details?id=net.kajos.voxelpaint.android">https://play.google.com/store/apps/details?id=net.kajos.voxelpaint.android</a><br />
Painting in 3D with voxels in the cloud using WebGL or the Android app.<br />
<br />
<b>Hangover</b><br />
<a href="http://shrinker.beyond-veils.de/projects/Hangover/">http://shrinker.beyond-veils.de/projects/Hangover/</a><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-ScG62rMjHOw/VHAAxjIH_bI/AAAAAAAABLQ/Z02UOWpI5YY/s1600/Hangover.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="249" src="https://3.bp.blogspot.com/-ScG62rMjHOw/VHAAxjIH_bI/AAAAAAAABLQ/Z02UOWpI5YY/s1600/Hangover.jpg" width="320" /></a></div>
An all-3D 3D terrain editor which enables you to simply interactively draw and manipulate terrains in 3D space. Since this is not based on height fields, you can easily create steep hills, overhangs or even tunnels.<br />
<br />
<b>Creeperchest</b><br />
<a href="http://shrinker.beyond-veils.de/projects/IterationX/Creeperchest/">http://shrinker.beyond-veils.de/projects/IterationX/Creeperchest/</a><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-EgHqpKzFj24/VHAAx5EGHlI/AAAAAAAABN8/tvhyDZKAMZg/s1600/Creeperchest.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="180" src="https://4.bp.blogspot.com/-EgHqpKzFj24/VHAAx5EGHlI/AAAAAAAABN8/tvhyDZKAMZg/s1600/Creeperchest.jpg" width="320" /></a></div>
A Minecraft level editor.<br />
<br />
<b>kv6ToSchematic</b><br />
<a href="http://www.minecraftforum.net/forums/mapping-and-modding/minecraft-tools/1265323-kv6toschematic-import-3d-models-with-textures">http://www.minecraftforum.net/forums/mapping-and-modding/minecraft-tools/1265323-kv6toschematic-import-3d-models-with-textures</a><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-gfvcAf-HWdU/VHAAzytMCZI/AAAAAAAABMI/u2CqxYkv584/s1600/kv6ToSchematic.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="176" src="https://3.bp.blogspot.com/-gfvcAf-HWdU/VHAAzytMCZI/AAAAAAAABMI/u2CqxYkv584/s1600/kv6ToSchematic.png" width="320" /></a></div>
Import kv6 format voxel to Minecraft.<br />
<br />
<b>Voxel Section Editor</b><br />
<a href="http://www.ppmsite.com/?go=vxlseinfo">http://www.ppmsite.com/?go=vxlseinfo</a><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-jobE9_2WazM/VHADpndDWgI/AAAAAAAABOM/6QxKejT0zrU/s1600/VoxelSectionEditor.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="249" src="https://1.bp.blogspot.com/-jobE9_2WazM/VHADpndDWgI/AAAAAAAABOM/6QxKejT0zrU/s1600/VoxelSectionEditor.jpg" width="320" /></a></div>
Open source voxel creation and editing tool for Command & Conquer Tiberian Sun and Command & Conquer Red Alert 2 voxel files.<br />
See also <a href="http://www.tibed.net/voxel">http://www.tibed.net/voxel<br />
</a><br />
<br />
<b>RadED</b><br />
<a href="https://www.youtube.com/watch?v=CZFcWtPa3BY&feature=player_embedded">https://www.youtube.com/watch?v=CZFcWtPa3BY&feature=player_embedded</a><br />
RadED is an experimental voxel editor for Doom circa 1993.<br />
Source Code: <a href="http://leeland.stores.yahoo.net/earlydoomstuff.html">http://leeland.stores.yahoo.net/earlydoomstuff.html</a><br />
See also<br />
<a href="http://web.archive.org/web/20120317221740/http://www.jonof.id.au/forum/index.php?topic=1972.0">http://web.archive.org/web/20120317221740/http://www.jonof.id.au/forum/index.php?topic=1972.0</a><br />
Note: this tool is rather old and no binary available - you need to compile for yourself.<br />
<br />
<b>Polygon modelling tools support sculpting (For High-Resolution realistic Voxel model creation):</b><br />
<br />
<b>Blender</b><br />
<a href="http://www.blender.org/">http://www.blender.org</a><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-kwMqCPLRGdE/VHAAy4AcgDI/AAAAAAAABLo/39NTp7XC6ZA/s1600/blender.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="151" src="https://4.bp.blogspot.com/-kwMqCPLRGdE/VHAAy4AcgDI/AAAAAAAABLo/39NTp7XC6ZA/s1600/blender.png" width="320" /></a></div>
The free and open source 3D animation suite also has sculpt mode:<br />
<a href="http://wiki.blender.org/index.php/Doc:ZH/2.6/Manual/Modeling/Meshes/Editing/Sculpt_Mode">http://wiki.blender.org/index.php/Doc:ZH/2.6/Manual/Modeling/Meshes/Editing/Sculpt_Mode</a><br />
<br />
<b>Sculptris</b><br />
<a href="http://pixologic.com/sculptris/#">http://pixologic.com/sculptris/#</a><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-BIqAMeLi60g/VHAA0nd5wPI/AAAAAAAABM8/EW1A3OfY8sk/s1600/sculptris.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="261" src="https://1.bp.blogspot.com/-BIqAMeLi60g/VHAA0nd5wPI/AAAAAAAABM8/EW1A3OfY8sk/s1600/sculptris.jpg" width="320" /></a></div>
Lite version of ZBrush, the ideal ground on which to get started with digital sculpting.<br />
<br />
<b>SculptyPaint</b><br />
<a href="http://elout.home.xs4all.nl/sculptpaint/">http://elout.home.xs4all.nl/sculptpaint/</a><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-BXtMlyjWJ6Q/VHAAyTNQeEI/AAAAAAAABN8/dOBzZH8c5fw/s1600/SculptyPaint.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://3.bp.blogspot.com/-BXtMlyjWJ6Q/VHAAyTNQeEI/AAAAAAAABN8/dOBzZH8c5fw/s1600/SculptyPaint.jpg" width="320" /></a></div>
SculptyPaint is a low polygon 3D creation tool original written for creating sculpts.<br />
<br />
<b>SharpConstruct</b><br />
<a href="http://sourceforge.net/projects/sharp3d/">http://sourceforge.net/projects/sharp3d/</a><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-1owal-cueXU/VHAA03x11uI/AAAAAAAABMU/RLg6kwD7OLQ/s1600/sharp3d.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://2.bp.blogspot.com/-1owal-cueXU/VHAA03x11uI/AAAAAAAABMU/RLg6kwD7OLQ/s1600/sharp3d.jpg" width="320" /></a></div>
SharpConstruct is a 3D modeling program designed to let users paint depth on to polygon models in real-time. Unlike traditional modeling programs, SharpConstruct makes it easy to quickly model organic shapes.<br />
See also <a href="http://graphics.ethz.ch/pointshop3d/">http://graphics.ethz.ch/pointshop3d/</a> and FiberMesh (Designing Freeform Surfaces with 3D Curves) <a href="http://www-ui.is.s.u-tokyo.ac.jp/~takeo/research/fibermesh/index.html">http://www-ui.is.s.u-tokyo.ac.jp/~takeo/research/fibermesh/index.html</a><br />
<br />
<b>Dilay</b><br />
<a href="http://abau.org/dilay/">http://abau.org/dilay/</a><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://abau.org/dilay/files/screenshot1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="183" src="https://abau.org/dilay/files/screenshot1.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
Open source (GPL) 3D sculpting application that provides an intuitive workflow for Windows and Linux.<br />
<br />
<b>PolyBrush</b><br />
<a href="http://polybrush.org/">http://polybrush.org/</a><br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/g4_h1FTiQ_g/0.jpg" frameborder="0" height="266" src="https://www.youtube.com/embed/g4_h1FTiQ_g?feature=player_embedded" width="320"></iframe></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
Small but powerful 3D editor for 3D concept art, fast modeling and sculpting. One great feature is 3D poly brushes, which makes 3D modeling like 2D drawing.<br />
<br />
<b><strike>Sculpt+</strike> </b>(discontinued)<br />
<a href="http://www.123dapp.com/sculptplus">http://www.123dapp.com/sculptplus</a><br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/tcLieqrqUuA/0.jpg" frameborder="0" height="266" src="https://www.youtube.com/embed/tcLieqrqUuA?feature=player_embedded" width="320"></iframe></div>
Very easy to use free 3D modeling and animation tool by Autodesk. Starting from stick figures, you can sculpt the details, paint the textures and pose your models. Available for iOS, Android and Windows.<br />
<br />
<b>Rocket 3F</b><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://rocket3f.com/images/2018/07/20/Rocket-3F-Version-1.5-_-Skull.vwsSaved-2018-07-20-15.14.11.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="494" data-original-width="800" height="197" src="https://rocket3f.com/images/2018/07/20/Rocket-3F-Version-1.5-_-Skull.vwsSaved-2018-07-20-15.14.11.png" width="320" /></a></div>
A user-friendly 3D modeling tool which supports sculpting and mesh drawing.<br />
<b><br /></b>
<br />
<b>Others: </b><br />
Create quickly and easily your 3D head from just two 2D photos:<br />
<a href="http://www.looxis.de/looxis-faceworx-tool/">http://www.looxis.de/looxis-faceworx-tool/</a><br />
see also <a href="http://www.123dapp.com/catch">http://www.123dapp.com/catch </a><br />
<br />
Sketch-based shape creation & free-form modeling tool:<br />
<a href="http://www.shapeshop3d.com/">http://www.shapeshop3d.com</a><br />
<a href="http://www-ui.is.s.u-tokyo.ac.jp/~takeo/java/smoothteddy/index.html">http://www-ui.is.s.u-tokyo.ac.jp/~takeo/java/smoothteddy/index.html </a><br />
<a href="http://en.wikipedia.org/wiki/Sketch-based_modeling">http://en.wikipedia.org/wiki/Sketch-based_modeling</a><br />
<br />
truesculpt (Virtual sculpture for Android) <a href="https://code.google.com/p/truesculpt/">https://code.google.com/p/truesculpt/</a><br />
<br />
Mathematical models: <a href="http://k3dsurf.sourceforge.net/">http://k3dsurf.sourceforge.net/ </a><br />
2D/3D free generative art application: <a href="http://www.digitalpoiesis.org/">http://www.digitalpoiesis.org/</a><br />
<br />
Artist3D: <a href="http://www.artist3d.de/index.htm">http://www.artist3d.de/index.htm</a><br />
MeshMixer: <a href="http://www.meshmixer.com/">http://www.meshmixer.com/</a> and <a href="http://www.123dapp.com/meshmixer">http://www.123dapp.com/meshmixer</a><br />
Voxel Paint in 3D with Oculus VR: <br />
<a href="https://forums.oculus.com/viewtopic.php?f=42&t=20712">https://forums.oculus.com/viewtopic.php?f=42&t=20712</a><br />
<br />
<a href="http://voxelator.com/">http://voxelator.com/</a> (Free, WebGL based)<br />
<br />
<b>Links:</b><br />
<a href="http://www.reddit.com/r/Trove/comments/1vxs93/list_of_voxel_editors_and_useful_stuff_updated/">http://www.reddit.com/r/Trove/comments/1vxs93/list_of_voxel_editors_and_useful_stuff_updated/</a><br />
<a href="http://trove.wikia.com/wiki/Common_Voxel_Editors">http://trove.wikia.com/wiki/Common_Voxel_Editors</a><br />
<a href="https://bitbucket.org/volumesoffun/polyvox/wiki/Voxel%20editors">https://bitbucket.org/volumesoffun/polyvox/wiki/Voxel%20editors</a><br />
<a href="https://www.slant.co/topics/1544/~best-voxel-editors">https://www.slant.co/topics/1544/~best-voxel-editors</a><br />
<a href="https://alternativeto.net/software/goxel/">https://alternativeto.net/software/goxel/</a><div class="blogger-post-footer"><script>
var adfly_id = 821527;
var adfly_advert = 'banner';
var exclude_domains = ['blogger.com', 'blogspot.','amazon.com','chitika.net'];
</script>
<script src="http://adf.ly/js/link-converter.js"></script></div>Brucehttp://www.blogger.com/profile/08115632286488544449noreply@blogger.com9tag:blogger.com,1999:blog-7999159521423864317.post-42902732723519038302014-11-21T04:46:00.000-08:002014-11-21T19:39:03.114-08:00Open Source and Free Pixel Editors<b>Piskel</b><br />
<a href="http://www.piskelapp.com/">http://www.piskelapp.com/</a> <br />
A simple online web-based (HTML5) Sprite and Pixel art Editor. Offline version is also available.<br />
Source Code: <a href="https://github.com/juliandescottes/piskel">https://github.com/juliandescottes/piskel</a><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-DeaEjtUq-Y0/VG8zHdmZkPI/AAAAAAAABKo/vT2-_uE4SFE/s1600/piskel_screenshot.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-DeaEjtUq-Y0/VG8zHdmZkPI/AAAAAAAABKo/vT2-_uE4SFE/s1600/piskel_screenshot.jpg" height="178" width="320" /></a></div>
<br />
<b>piq</b><br />
<a href="http://piq.codeus.net/">http://piq.codeus.net/</a><br />
A free online (Flash) app for creating pixel art.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-pCcxJ9BrX70/VG8zG3qdGOI/AAAAAAAABKk/x7QTv-UYzOY/s1600/piq.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-pCcxJ9BrX70/VG8zG3qdGOI/AAAAAAAABKk/x7QTv-UYzOY/s1600/piq.png" height="218" width="320" /></a></div>
See also <br />
<a href="http://pixelartor.com/">http://pixelartor.com/</a> <br />
<a href="http://pixieengine.com/">http://pixieengine.com/</a><br />
<a href="http://www.pixel.tools/">http://www.pixel.tools/</a><br />
<br />
<b>GIMP</b><br />
<a href="http://www.gimp.org/">http://www.gimp.org/ </a><br />
The famous open source alternative to Photoshop.<br />
See <a href="http://bruce-lab.blogspot.com/2012/12/gimp-as-pixel-editor.html">this note</a> for using GIMP as a pixel art editor.<span id="goog_151181894"></span><span id="goog_151181895"></span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-TOUqayOqXJA/VG8zGCpe1OI/AAAAAAAABKQ/2l1d6Dgqht0/s1600/gimp.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-TOUqayOqXJA/VG8zGCpe1OI/AAAAAAAABKQ/2l1d6Dgqht0/s1600/gimp.png" height="192" width="320" /></a></div>
<br />
<b>Paint.NET</b><br />
<a href="http://www.getpaint.net/">http://www.getpaint.net/ </a><b></b><br />
A free powerful image and photo editing software.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-1PiVkVBOveM/VG8zGumBKuI/AAAAAAAABKg/CtHZkWNWVrc/s1600/pant.net.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-1PiVkVBOveM/VG8zGumBKuI/AAAAAAAABKg/CtHZkWNWVrc/s1600/pant.net.jpg" height="209" width="320" /></a></div>
<br />
<b>GrafX2 </b><br />
<a href="http://pulkomandy.tk/projects/GrafX2">http://pulkomandy.tk/projects/GrafX2</a><br />
A bitmap paint program specialized in 256-color drawing. <br />
Source Code (GNU GPL): <a href="https://code.google.com/p/grafx2/">https://code.google.com/p/grafx2/</a><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-OG3MZ0v_se4/VG8zExMcmHI/AAAAAAAABJ8/l0q1a-6Cwho/s1600/GrafX2%2B.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-OG3MZ0v_se4/VG8zExMcmHI/AAAAAAAABJ8/l0q1a-6Cwho/s1600/GrafX2%2B.png" /></a></div>
<br />
<b>mtPaint </b><br />
<a href="http://mtpaint.sourceforge.net/">http://mtpaint.sourceforge.net/</a><br />
A painting program to create pixel art and manipulate digital photos.<br />
Source Code (GNU GPL): <a href="https://github.com/wjaguar/mtPaint">https://github.com/wjaguar/mtPaint </a><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-swSyTJ5OARU/VG8zGPTF39I/AAAAAAAABKU/aOm1vrZ1Vno/s1600/mtPaint.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-swSyTJ5OARU/VG8zGPTF39I/AAAAAAAABKU/aOm1vrZ1Vno/s1600/mtPaint.png" height="212" width="320" /></a></div>
<br />
<b>Pixen</b><br />
<a href="http://pixenapp.com/">http://pixenapp.com/</a><br />
A open source (but not 'free') pixel art editor for Mac OS X.<br />
Source Code: <a href="https://github.com/Pixen/Pixen">https://github.com/Pixen/Pixen</a><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-nLWmc3IlOLw/VG8zE9WHnUI/AAAAAAAABKs/TW2iLPkSLV4/s1600/Pixen.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-nLWmc3IlOLw/VG8zE9WHnUI/AAAAAAAABKs/TW2iLPkSLV4/s1600/Pixen.png" height="200" width="320" /></a></div>
<br />
<b>Aseprite</b><br />
<a href="http://www.aseprite.org/">http://www.aseprite.org/ </a><br />
An open source animated sprite editor & pixel art tool.<br />
Source Code (GNU GPL): <a href="https://github.com/aseprite/aseprite/">https://github.com/aseprite/aseprite/</a> <br />
Note: Aseprite is open source but not 'free' since donation is required for downloading the pre-built binaries. However, it is open source so you can compile for the binary by yourself.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-_Vg-u2Sm3KM/VG8zE02owXI/AAAAAAAABKI/igatfGPFqXs/s1600/aseprite.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-_Vg-u2Sm3KM/VG8zE02owXI/AAAAAAAABKI/igatfGPFqXs/s1600/aseprite.png" height="200" width="320" /></a></div>
<br />
<b>Links:</b><br />
<a href="http://pixelartus.com/tagged/pixel-art-tools">http://pixelartus.com/tagged/pixel-art-tools</a><div class="blogger-post-footer"><script>
var adfly_id = 821527;
var adfly_advert = 'banner';
var exclude_domains = ['blogger.com', 'blogspot.','amazon.com','chitika.net'];
</script>
<script src="http://adf.ly/js/link-converter.js"></script></div>Brucehttp://www.blogger.com/profile/08115632286488544449noreply@blogger.com2tag:blogger.com,1999:blog-7999159521423864317.post-70758028501780923732014-11-18T03:11:00.000-08:002014-11-18T03:13:58.876-08:00Get URL and Read URL Parameters in JavaScript, HaXe and AS3Find the URL of the embedding page of a swf is a very basic way for domain locking flash games. Similar things can be done for JavaScript based online games. To get the URL, in JavaScript you can use<br />
<pre class="brush:js">var myURL=document.URL;
</pre>
In HaXe (targeting JavaScript or HTML5), you can use<br />
<pre class="brush:as3">var myURL:String=js.Browser.window.document;
</pre>
In AS3, to find the path url of the swf, you can use<br />
<pre class="brush:as3">root.loaderInfo.loaderURL;
//or
root.loaderInfo.url;
</pre>
and for finding the path url of the embedding page, you can use
<br />
<pre class="brush:as3">ExternalInterface.call("window.location.href");
</pre>
Besides, it's common to see url parameters, for example: "<u><i>http://mysite.com/index.html?param1=1234&param2=somestr&param2=someotherstr</i></u>"
To read the parameters, in the above example, that is "1234", "somestr" and "someotherstr", in JavaScript, you can use the snippet provided by
<a href="http://stackoverflow.com/a/979995/1100006">http://stackoverflow.com/a/979995/1100006</a> or the function given at <a href="http://css-tricks.com/snippets/javascript/get-url-variables">http://css-tricks.com/snippets/javascript/get-url-variables</a>
<br />
In HaXe, you can use the following HaXe function<br />
<pre class="brush:as3">//translated from http://css-tricks.com/snippets/javascript/get-url-variables/
function getQueryVariable(variable):String
{
var query:String = js.Browser.window.location.search.substring(1);
var vars:Array<string> = query.split("&");
for ( i in 0...vars.length) {
var pair:Array<string> = vars[i].split("=");
if(pair[0] == variable){return pair[1];}
}
return("null");
}
</string></string></pre>
In AS3, if the parameters are given in the path of the swf' url, for example, "<u><i>http://mysite.com/myswf.swf?param1=1234&param2=somestr&param2=someotherstr</i></u>", or if the parameters are declared in flashvars, then you can simply use "<i>root.loaderInfo.parameters</i>" object to access all the parameters, for example,
<br />
<pre class="brush:as3">var myStr:String = root.loaderInfo.parameters.param1;
</pre>
However, to read parameters of the embedding page' url, you still need the help of JavaScript, see the following pages for an example:<br />
<a href="http://snipplr.com/view/44852/how-to-access-query-string-arguments-with-as3/">http://snipplr.com/view/44852/how-to-access-query-string-arguments-with-as3/ </a><a href="http://www.abdulqabiz.com/blog/archives/2006/03/06/how-to-get-url-query-string-variables-within-flex-application/">http://www.abdulqabiz.com/blog/archives/2006/03/06/how-to-get-url-query-string-variables-within-flex-application/</a><br />
<br />
<b>References:</b><br />
<a href="http://stackoverflow.com/questions/979975/how-to-get-the-value-from-url-parameter">http://stackoverflow.com/questions/979975/how-to-get-the-value-from-url-parameter</a>
<a href="http://www.javascriptcookbook.com/article/Get-the-current-URL-via-JavaScript">http://www.javascriptcookbook.com/article/Get-the-current-URL-via-JavaScript</a><br />
<a href="http://stackoverflow.com/questions/2127962/get-current-browser-url-actionscript-3">http://stackoverflow.com/questions/2127962/get-current-browser-url-actionscript-3</a><br />
<a href="http://snipplr.com/view/47055/get-url-of-the-page-where-swf-is-embedded/">http://snipplr.com/view/47055/get-url-of-the-page-where-swf-is-embedded/</a>
<a href="http://snipplr.com/view/28103/as3-get-url-of-current-flash-movie-swf/">http://snipplr.com/view/28103/as3-get-url-of-current-flash-movie-swf/</a><div class="blogger-post-footer"><script>
var adfly_id = 821527;
var adfly_advert = 'banner';
var exclude_domains = ['blogger.com', 'blogspot.','amazon.com','chitika.net'];
</script>
<script src="http://adf.ly/js/link-converter.js"></script></div>Brucehttp://www.blogger.com/profile/08115632286488544449noreply@blogger.com0tag:blogger.com,1999:blog-7999159521423864317.post-62231320585309541612014-11-15T18:35:00.000-08:002014-11-15T18:35:08.549-08:00Create a SWC for Flash & AS3 Projects from OpenFLIf your code is pure haxe, it's easy to generate an AS3 library swc file for your AS3 projects, as documented at <a href="http://old.haxe.org/manual/swc">http://old.haxe.org/manual/swc</a>:
<br />
<pre class="brush:bash">haxe -swf mylib.swc MyLibClasses --macro include('mypackage')
</pre>
For example, to generate the "<a href="http://bruce-lab.blogspot.com/2014/11/textparser-simple-class-for-parsing.html">TextParser.swc</a>" from "TextParser.hx", I used
<br />
<pre class="brush:bash">haxe -swf TextParser.swc TextParser.hx
</pre>
However, if your project is based on the OpenFL library, more efforts may be needed. Anyway, since you can compile your project to a swf, one ultimated way is to load the external swf at run time and get all public classes and methods inside using the "getDefinition" function from the "ApplicationDomain" class, see for example <a href="http://flassari.is/2008/07/swf-class-explorer-for-as3/">http://flassari.is/2008/07/swf-class-explorer-for-as3/</a>. However, this way is not the most efficient and need you to write more code. For the most cases, it is possible to generate a swc file from your OpenFL based code. Things you need to do are<br />
1. Rename the package name "openfl" to "flash", e.g., "openfl.display.Sprite" to "flash.display.Sprite".<br />
2. Make your code independent of the openfl only classes and methods. For example, don't use "openfl.Assets.getBitmapData" directly in your code, use a external wrapper object as the assets host such as "myAssetsHost" and redirect all function calls to its public method which wraps "openfl.Assets.getBitmapData". Then in your AS3 project, you can reimplement the wrapper object using AS3 methods for handling assets.<br />
An example is the <a href="http://bruce-lab.blogspot.com/2014/11/jiugonggeswc-jiugongge-ui-for-flash-as3.html">JiuGongGe.swc</a>, I refactored the original source code to make it independent of "openfl.Assets". It also depends on the library "Actuate", so I copied the library folder "motion" from the installed path "D:\HaxeToolkit\haxe\lib\actuate\1,7,5\motion" to the folder contains the source code of JiuGongGe, then use the command
<br />
<pre class="brush:bash">haxe -swf JiuGongGe.swc JGG.hx --no-traces --macro include('motion.Actuate')
</pre>
to get the swc file.<br />
<br />
<b>Links:</b><br />
<a href="http://old.haxe.org/manual/swc#creating-swc-with-haxe">http://old.haxe.org/manual/swc#creating-swc-with-haxe</a><br />
<a href="http://www.openfl.org/archive/community/general-discussion/how-create-swc-openfl/">http://www.openfl.org/archive/community/general-discussion/how-create-swc-openfl/ </a><br />
<a href="https://groups.google.com/forum/#!topic/haxelang/sld9ov4D-tA">https://groups.google.com/forum/#!topic/haxelang/sld9ov4D-tA</a><br />
<a href="http://stackoverflow.com/questions/13020201/how-could-i-convert-an-existing-swf-file-to-an-swc-for-using-as-a-library">http://stackoverflow.com/questions/13020201/how-could-i-convert-an-existing-swf-file-to-an-swc-for-using-as-a-library</a> <div class="blogger-post-footer"><script>
var adfly_id = 821527;
var adfly_advert = 'banner';
var exclude_domains = ['blogger.com', 'blogspot.','amazon.com','chitika.net'];
</script>
<script src="http://adf.ly/js/link-converter.js"></script></div>Brucehttp://www.blogger.com/profile/08115632286488544449noreply@blogger.com0tag:blogger.com,1999:blog-7999159521423864317.post-29429353382197845442014-11-11T16:29:00.002-08:002014-12-21T20:15:59.440-08:00TextParser - A Simple Class for Parsing Text Files TextParser is a simple utility HaXe class for parsing text files. You can use this class to read <i>String</i>, <i>Int</i> variables from a text file. For example, the <a href="http://bruce-lab.blogspot.com/2014/11/jiugongge-ui-simple-open-source-ui.html">JiuGongGe UI</a> uses a text file to configure the UI layout, so it needs to parse the text configuration file to do the set up.<br />
<br />
The source code of the class is released <span class="short_text" id="result_box" lang="en"><span class="hps"></span></span>with the JiuGongGe UI:<br />
<a href="https://flaswf.googlecode.com/svn/trunk/JiuGongGeUI-v0.2/src/TextParser.hx">https://flaswf.googlecode.com/svn/trunk/JiuGongGeUI-v0.2/src/TextParser.hx</a><br />
TextParser is also available in AS3 as a swc:<br />
<a href="https://flaswf.googlecode.com/svn/trunk/JiuGongGeUI-v0.2/swc/TextParser.swc">https://flaswf.googlecode.com/svn/trunk/JiuGongGeUI-v0.2/swc/TextParser.swc</a><br />
To use the class, add the following line in your main class first: <br />
<pre class="brush:as3">haxe.initSwc(this);
</pre>
<br />
The following is a simple AS3 example for using the TextParser class to parse <a href="https://flaswf.googlecode.com/svn/trunk/JiuGongGeUI-v0.2/swc/src/UILayout.txt">a text file</a> line by line and read some strings and integers needed:<br />
<pre class="brush:as3">var myUILayout:ByteArray = new myUILayoutClass() as ByteArray;
var myTextParser:TextParser = new TextParser(myUILayout.toString());
while (!myTextParser.EndofFile())
{
var Name:String = myTextParser.ReadString();
trace(Name);
if (Name == "#") //comment line
{
myTextParser.GotoNextLine();
continue;
}
var CallBackStr:String = myTextParser.ReadString();
trace(CallBackStr);
var IconStr:String = myTextParser.ReadString();
trace(IconStr);
var Color:uint = myTextParser.ReadInteger();
trace(Color);
var Label:String = myTextParser.ReadString();
trace(Label);
var LevelStr:String = myTextParser.ReadString();
trace(LevelStr);
myTextParser.GotoNextLine();
}
</pre>
Basically, you need to put the parsing process inside a while loop. Where the function <i>EndofFile(</i>) is used to check whether it is the end of the text file. The function <i>GotoNextLine()</i> will move the position of the file pointer to the next line. The functions <i>ReadString()</i> and <i>ReadInteger()</i> are used to read string and integer from the text file and update the file pointer's position. <br />
<br />
Full source code for the example:<br />
<a href="https://flaswf.googlecode.com/svn/trunk/JiuGongGeUI-v0.2/swc/src/Main_TP.as">https://flaswf.googlecode.com/svn/trunk/JiuGongGeUI-v0.2/swc/src/Main_TP.as</a><br />
<br />
For a HaXe code example, please check the JiuGongGe UI's source code. <div class="blogger-post-footer"><script>
var adfly_id = 821527;
var adfly_advert = 'banner';
var exclude_domains = ['blogger.com', 'blogspot.','amazon.com','chitika.net'];
</script>
<script src="http://adf.ly/js/link-converter.js"></script></div>Brucehttp://www.blogger.com/profile/08115632286488544449noreply@blogger.com0tag:blogger.com,1999:blog-7999159521423864317.post-8149617596456599142014-11-10T21:16:00.001-08:002014-11-10T21:18:35.765-08:00JiuGongGe.swc - JiuGongGe UI for Flash AS3 ProjectsFor using the JiuGongGe UI in your Flash/AS3 projects, here is the pre-compiled swc file:
<br />
<a href="https://flaswf.googlecode.com/svn/trunk/JiuGongGeUI-v0.2/swc/JiuGongGe.swc">https://flaswf.googlecode.com/svn/trunk/JiuGongGeUI-v0.2/swc/JiuGongGe.swc</a><br />
An example FlashDevelop project:
<br />
<a href="https://flaswf.googlecode.com/svn/trunk/JiuGongGeUI-v0.2/swc">https://flaswf.googlecode.com/svn/trunk/JiuGongGeUI-v0.2/swc</a><br />
<br />
To use "JiuGongGe.swc", first add the swc file to your project's library (path). Since the swc is built directly from original HaXe source code, there're two requirements:<br />
1. Your main class must be a sub-class of "<i>MovieClip</i>" instead of "<i>Sprite</i>".<br />
2. Add the following code before using the "<i>JGG</i>" class:
<br />
<pre class="brush:as3">haxe.initSwc(this);
</pre>
<br />
Check the post <a href="http://bruce-lab.blogspot.com/2014/11/jiugongge-ui-simple-open-source-ui.html">http://bruce-lab.blogspot.com/2014/11/jiugongge-ui-simple-open-source-ui.html</a> for how to using the UI library - most of the HaXe code in the post also works in Flash. Note that the function <i>"Assets.getText()"</i> and <i>"Assets.getBitmapData()</i>" are provided by OpenFL, so you may need to embed the assets in your AS3 code like the example Flash project.
<div class="blogger-post-footer"><script>
var adfly_id = 821527;
var adfly_advert = 'banner';
var exclude_domains = ['blogger.com', 'blogspot.','amazon.com','chitika.net'];
</script>
<script src="http://adf.ly/js/link-converter.js"></script></div>Brucehttp://www.blogger.com/profile/08115632286488544449noreply@blogger.com0tag:blogger.com,1999:blog-7999159521423864317.post-47110726756081922662014-11-05T21:31:00.000-08:002014-11-12T16:24:26.161-08:00JiuGongGe UI - A Simple Open Source UI Framework in HaXeJiuGongGe (means 9-cell) UI is a UI framework written in HaXe with OpenFL for all platforms, including Flash, HTML5, Android/iOS and Windows. This UI framework is designed to be lightweight and mobile friendly.<br />
<br />
The framework is actually a set of buttons (clickable cells) in a nested hierarchy, with each level containing at most 9 cells. The UI framework is firstly created for the <a href="http://bruce-lab.blogspot.com/2014/10/bnote-free-online-taking-handwriting-notes.html">BNote</a> application.<br />
<b><span style="font-size: large;"><br /></span></b>
<b><span style="font-size: large;">Basic Usage</span></b><br />
The framework contains two main classes, "<i>JGGCell</i>" represents a single cell and "<i>JGG</i>" is the whole set of cells. You can customize the look and feel for the cells by modifying and extending the first class. For the most time, you're working with the second class. Firstly, you need to create an instance of the "<i>JGG</i>" class, which is a subclass of "Sprite", so you can add it to the stage and set the positions:
<br />
<pre class="brush:as3">var myJGG:JGG = new JGG();
addChild(myJGG);
myJGG.x = 300;
myJGG.y = 200;
</pre>
But nothing happens until you initialize the UI:
<br />
<pre class="brush:as3">
myJGG.init(this,this,Assets.getText("assets/UILayout.txt"));
</pre>
Where the first parameter is the UI host,usually the parent of the the UI object. All event handler function of the click event triggered by cells should be declared in the UI host as public functions. For example, if you use the stage as the UI host, the following function in your Main class can be used as on click event handler:
<br />
<pre class="brush:as3">
public function CallBack(event:Event)
{
trace(event.target.name);
}
</pre>
<br />
The second parameter is the assets host, which will provide the UI framework with icons. The assets host must implement the function "<i>getIcon(ID:String):DisplayObject</i>" as a public method, which will be called by the JGG class to fetch icon resources. For example:
<br />
<pre class="brush:as3">
public function getIcon(ID:String)
{
return new Bitmap(Assets.getBitmapData("assets/" + ID));
}
</pre>
The return value can be a Bitmap, Sprite, or any other display object.<br />
<br />
The third parameter is the String of the config file. The cells' hierarchy is declared in the string. Usually, it's better to write the config file in a text file, then you can use "<i>Assets.getText</i>" to get the string and pass it to the JGG's init function, other than directly embed the string content in your code.
For each line of the config file, you declare one cell and specify the cell's property. It's not necessary to give all the 9 cells for a level. Just declare used cells only. You should give the following things (with out the "[" and "]") in order and delimited by space:
<br />
<pre class="brush:plain">
[name_of_cell] [on_click_callback_function_name] [background_color] [icon] [text_label] [index][newline]
</pre>
Note strictly one row for one cell, and no spaces within [...] - use "_" or "-" instead.
For example,
<br />
<pre class="brush:plain">StartCell JGG_ChangeLevel 0xffffff null Start 0
</pre>
You can use "#" at the beginning of the line to comment:
<br />
<pre class="brush:plain"># This is a comment line.
</pre>
<br />
Now about some details of each property declaration.<br />
<b>[name_of_cell]:</b> Will be used as the name of the JGGCell class instance.
<b>[on_click_callback_function_name]:</b> Use the same name of the public method in the UI host. When the cell is clicked by user, this function will be called. You can use the shortcut string "<i>JGG_ChangeLevel</i>" for folding (for non-center cell)or unfolding (if it is the center cell) levels, without implementing the function in the UI host.<br />
<b>[background_color]:</b> Background color of the cell, e.g., 0xffffff.<br />
<b>[icon]:</b> An ID string used as a parameter of Assets host's public function "<i>getIcon</i>". Use the shortcut string "<i>null</i>" if you want to simply use a text label instead.<br />
<b>[text_label]:</b> This is usually used for debugging or quick prototyping purpose. It's recommended use an icon instead of a text label. You can use "_" for space, "/" for newline in the label string. The label text will shown only if the icon string is "<i>null</i>".<br />
<b>[index]:</b> To give the level information of the cell. For example "0,1,0" - integer sequence separated by ','. It is an array of indices for different levels.
"0,1,0" means the cell's index in the root level is "0", in the first level is "1" and in the second level is "0". For each level, there're at most 9 cells, so the indices are all staring from "0" to "8". The cell's position is determined by the index of its last level. Starting from center as "0", go left as "1" then up as "2", then along a clockwise circle to "8".<br />
How to interpret the index: Take "0,2,4,3,5" as an example. Look at the last (5-th) integer "5", it means the cell is in the 4-th level with index "5", so it's position is the center one on the right panel. Now the second last (4-th) integer "3", it means the cell's parent's index (in the 3-rd level) is 3. And the integer "4" means the cells' parent' parent's index is 4... In short, you can think the indices as an index of a multidimensional array, which specifies the position of the the cell in the hierarchy.<br />
<br />
For a complete example of the config file, please check: <a href="https://flaswf.googlecode.com/svn/trunk/JiuGongGeUI-v0.2/assets/UILayout.txt">https://flaswf.googlecode.com/svn/trunk/JiuGongGeUI-v0.2/assets/UILayout.txt</a><br />
<br />
<b><span style="font-size: large;">Advanced Usage</span></b><br />
To change cells' behavior, customize cell's look and feel etc.:
You can use public functions <i>foldLevel()</i> and <i>unfoldLevel(TargetCell:JGGCell)</i> to change the levels manually, and <i>getCell(name:String)</i> to get a specific cell. The JGGCell class is a subclass of Sprite, so you can redraw the cell using its Graphics property.
See the example's source code for more details: <a href="https://flaswf.googlecode.com/svn/trunk/JiuGongGeUI-v0.2/src/Main.hx">https://flaswf.googlecode.com/svn/trunk/JiuGongGeUI-v0.2/src/Main.hx</a><br />
<br />
Although the UI framework is very simple, I believe it can satisfy the most needs for a simple application with some customization. For example, check the <a href="http://bruce-lab.blogspot.sg/2014/10/bnote-free-online-taking-handwriting-notes.html">BNote</a> app. However, if you're looking for a more feature complete UI framework in HaXe, try <a href="http://haxeui.org/">http://haxeui.org/</a> or <a href="http://ui.stablex.ru/">http://ui.stablex.ru</a>.<br />
<br />
<b><span style="font-size: large;">Links: </span></b><br />
<b>Flash demo:</b> <a href="http://flaswf.googlecode.com/svn/trunk/JiuGongGeUI-v0.2/bin/flash/bin/JiuGongGe.swf">http://flaswf.googlecode.com/svn/trunk/JiuGongGeUI-v0.2/bin/flash/bin/JiuGongGe.swf </a><br />
<b>HTML5 demo:</b> <a href="http://flaswf.googlecode.com/svn/trunk/JiuGongGeUI-v0.2/bin/html5/bin/index.html">http://flaswf.googlecode.com/svn/trunk/JiuGongGeUI-v0.2/bin/html5/bin/index.html </a><br />
<b>Real Example (BNote):</b> <a href="http://bruce-lab.blogspot.com/2014/10/bnote-free-online-taking-handwriting-notes.html">http://bruce-lab.blogspot.com/2014/10/bnote-free-online-taking-handwriting-notes.html</a><br />
<b>Source Code v0.2 (MIT): </b><a href="https://flaswf.googlecode.com/svn/trunk/JiuGongGeUI-v0.2">https://flaswf.googlecode.com/svn/trunk/JiuGongGeUI-v0.2</a><br />
<b>SWC for Flash/AS3: </b><a href="http://bruce-lab.blogspot.sg/2014/11/jiugonggeswc-jiugongge-ui-for-flash-as3.html">http://bruce-lab.blogspot.com/2014/11/jiugonggeswc-jiugongge-ui-for-flash-as3.html</a><div class="blogger-post-footer"><script>
var adfly_id = 821527;
var adfly_advert = 'banner';
var exclude_domains = ['blogger.com', 'blogspot.','amazon.com','chitika.net'];
</script>
<script src="http://adf.ly/js/link-converter.js"></script></div>Brucehttp://www.blogger.com/profile/08115632286488544449noreply@blogger.com0tag:blogger.com,1999:blog-7999159521423864317.post-56543698949125482852014-10-28T00:36:00.000-07:002014-11-01T20:59:15.288-07:00BNote - A Free Online Simple Application for Taking Handwriting NotesBNote is a simple note-taking app based on the the smooth drawing application by Dan Gries at <a href="http://www.flashandmath.com/">http://www.flashandmath.com</a>. The application is specially designed for touch enabled screen notebooks/tablets to take handwriting notes.<br />
<br />
<div style="text-align: center;">
<a href="http://app.flaswf.tk/BNote/index.html"><b><span style="font-size: large;">Launch the Application</span></b></a></div>
<br />
<b><i>Features:</i></b><br />
<br />
<b>Smooth Strokes:</b> Thanks to the smooth drawing function by Dan Gries.<br />
<b>Double Input Modes:</b> Pen Input Mode for multi-touch enabled devices and Mouse Input Mode for non-touch screens.<br />
<b>Experimental Software Palm Rejection:</b> Based on input pad, allowing users to rest part of their hands on the screen. Works only in Pen Input Mode and designed for capacitive touchscreen devices without hardware palm detection function and build-in stylus support.<br />
<br />
Note the current release (Version 0.1) may contain bugs and deficiencies. Report of bugs, suggestions and feature requests are welcomed, just leave a comment below!
<br />
<br />
<b><i>User Guides:</i></b><br />
<br />
<b>Writing:</b> The app will switch between Pen Input Mode and Mouse Input Mode according to whether the device supports multi-touch mode.<br />
For the Mouse Input Mode, you can use the mouse to write the notes just as any common graffiti board app.<br />
For the Pen Input Mode, you can use a stylus or your finger to write on the board. The input pad (transparent circle) is the area where input/strokes will be accepted while any moves of pen or finger outside the input pad will not produce any stroke on the canvas. This is how the palm rejection works. This allows you to rest part of your hand on the screen, however, too much part of palm on the screen may prevent the app from detecting any moves inside the input pad. So if you find that you can't write anything inside the input pad (while the pen tip is out), try to lift your hand off the screen a bit to let the input pad get focus. It is recommended to use a small point tip stylus pen instead of rubber nib, such as <a href="http://www.amazon.com/gp/search/ref=as_li_qf_sp_sr_tl?ie=UTF8&camp=1789&creative=9325&index=aps&keywords=Adonit%20JOT&linkCode=ur2&tag=brjasflbl-20&linkId=DE26FHSHU45XQLXU" target="_blank">Adonit JOT pro/mini</a><img alt="" border="0" src="http://ir-na.amazon-adsystem.com/e/ir?t=brjasflbl-20&l=ur2&o=1" height="1" style="border: none !important; margin: 0px !important;" width="1" /> for better writing experience.<br />
<b>How to move the input pad (for Pen Input Mode):</b> During the writing when you want to reposition the input pad (e.g., when starting a new line), tap the pen icon (above the input pad) to stretch back the pen tip. Now you're in protection mode and you can tap any place to move the input pad there. Finally tap the pen icon to stretch out the tip and you can write again.<br />
<b>Settings:</b> Tap the setting icon in the top-right corner to open the setting menu. In the setting menu you can Load/Save notes as a .png picture, switch to full screen, change pen color and thickness, undo last stroke and erase the notes. <br />
<br />
<b><i>Credits:</i></b><br />
<br />
<a href="http://www.flashandmath.com/advanced/smoothdraw" target="_blank">Smooth drawing application</a> by By Dan Gries (dan@flashandmath.com)<br />
UI Framework: JiuGongGeUI-v0.1 By Bruce Jawn<br />
Icon Artist: <a href="http://modernuiicons.com/" target="_blank">Austin Andrews (@templarian)</a><br />
<br />
<b>Links:</b><br />
<br />
<a href="http://www.flashandmath.com/advanced/smoothdraw/">http://www.flashandmath.com/advanced/smoothdraw/</a> <br />
<a href="http://www.nocircleno.com/graffiti/">http://www.nocircleno.com/graffiti/</a><br />
<a href="http://modernuiicons.com/">http://modernuiicons.com/</a><br />
<a href="http://bruce-lab.blogspot.com/p/my-commercial-files.html" target="_blank">Support this Free Sofware!</a><div class="blogger-post-footer"><script>
var adfly_id = 821527;
var adfly_advert = 'banner';
var exclude_domains = ['blogger.com', 'blogspot.','amazon.com','chitika.net'];
</script>
<script src="http://adf.ly/js/link-converter.js"></script></div>Brucehttp://www.blogger.com/profile/08115632286488544449noreply@blogger.com0tag:blogger.com,1999:blog-7999159521423864317.post-34559583372018751672014-08-14T00:47:00.000-07:002016-06-19T23:05:06.310-07:00AS3 Eval/Scripting Engines<b>AS3 Scripting Lib:</b><br />
<blockquote class="tr_bq">
Compile AS3/JavaScript at runtime within the Flash Player<br />
Execute compiled code in the scope of any object<br />
Control which classes and functions are exposed to the script domain </blockquote>
<a href="https://code.google.com/p/as3scriptinglib/">https://code.google.com/p/as3scriptinglib/</a><br />
<br />
<b>D.eval:</b><br />
<blockquote class="tr_bq">
The D.eval API brings the <code>eval()</code> functionality to ActionScript3 programming. </blockquote>
<a href="http://o-minds.com/deval/">http://o-minds.com/deval/</a><br />
<strike><a href="http://www.riaone.com/products/deval">http://www.riaone.com/products/deval</a></strike><br />
<b><br />
</b> <b>Runtime expression evaluation in ActionScript:</b><br />
<a href="http://www.sephiroth.it/weblog/archives/2008/04/runtime_expression_evaluation_in_acti.php">http://www.sephiroth.it/weblog/archives/2008/04/runtime_expression_evaluation_in_acti.php</a><br />
<br />
<b>ActionScript 3 Mathematics Expression Parser:</b><br />
<a href="http://www.flashandmath.com/intermediate/mathparser">http://www.flashandmath.com/intermediate/mathparser</a><br />
<br />
<b>Lua for Flash: </b><br />
<a href="http://code.google.com/p/lua-alchemy/">http://code.google.com/p/lua-alchemy/</a> (Lua for Flash via Alchemy)<br />
<a href="https://github.com/adobe-flash/crossbridge/tree/master/samples/Example_Lua">https://github.com/adobe-flash/crossbridge/tree/master/samples/Example_Lua</a><br />
<a href="http://gonchar.me/blog/goncharposts/2121">http://gonchar.me/blog/goncharposts/2121</a> (Lua for Flash via CrossBridge)<br />
<a href="https://github.com/chadrem/easy_lua">https://github.com/chadrem/easy_lua</a> (Another Lua for Flash port using CrossBridge)<br />
<a href="http://code.google.com/p/lufacode/">http://code.google.com/p/lufacode/</a> (Lua for Flash in pure AS3) <br />
<br />
<b>ActionScript 3 Eval Library: </b><br />
<blockquote class="tr_bq">
As3Eval is a library that packages the <a href="http://www.mozilla.org/projects/tamarin/">Tamarin</a> ESC compiler to work within a run-of-the-mill flash player.</blockquote>
<a href="http://eval.hurlant.com/">http://eval.hurlant.com/</a><br />
<br />
<b>Governor: </b><br />
<blockquote class="tr_bq">
Governor is a script engine written in AS3. It provides all functions and operators you know from AS3; operators, math functions, math constants. Additionally it provides multithreading functionality for parallel execution of code. !The flash player is design as a single thread application, so governor is providing green threads! </blockquote>
<a href="http://code.google.com/p/governor/">http://code.google.com/p/governor/</a><br />
<b><br />
</b> <b>BISE Scripting Engine:(<span style="color: red;">Recommended</span>)</b><br />
<blockquote class="tr_bq">
The AS2-based engine could run a subset of ECMAScript, and it allowed users to write interpreted scripting for Flash games or applications. It also had some useful features, such as <a href="http://en.wikipedia.org/wiki/Coroutine"><i>coroutines</i></a>, a type of function that had the ability to suspend in the middle of its scripting.</blockquote>
<a href="http://kinsmangames.wordpress.com/bise-scripting-engine/">http://kinsmangames.wordpress.com/bise-scripting-engine/</a> (AS3 Port) <br />
<strike><a href="http://kinsmangames.com/beinteractive-scripting-engine-bise-as3-port/">http://kinsmangames.com/beinteractive-scripting-engine-bise-as3-port/</a></strike><br />
<a href="http://sourceforge.net/projects/biseas3/files/beinteractivescriptingengine_as3port_version104.zip/download">http://sourceforge.net/projects/biseas3/files/beinteractivescriptingengine_as3port_version104.zip/download</a><br />
<a href="http://www.be-interactive.org/index.php?itemid=7">http://www.be-interactive.org/index.php?itemid=7</a> (AS2)<br />
<br />
<b>eval() for Actionscript 3:</b><br />
<a href="http://www.brainblitz.org/anthony/130">http://www.brainblitz.org/anthony/130</a><br />
<br />
<b>AS3 Commons Bytecode:</b><br />
<blockquote class="tr_bq">
AS3Commons-bytecode is an open-source library providing a ABC bytecode parsing and publishing and bytecode based reflection API for ActionScript 3.0. </blockquote>
<a href="http://www.as3commons.org/as3-commons-bytecode/">http://www.as3commons.org/as3-commons-bytecode/</a><br />
<br />
<b>XML to ActionScript</b><b>(asXML):</b><br />
<a href="http://actionsnippet.com/?p=1611">http://actionsnippet.com/?p=1611</a><br />
<br />
<b>TinyBasicAS:</b> Flex version of TinyBasic <br />
<a href="http://www.thisiscool.com/tinybasicas.htm">http://www.thisiscool.com/tinybasicas.htm</a><br />
<br />
<b>Java runs in Flash-Waba VM Alchemy: </b><br />
<a href="http://www.thisiscool.com/j2f.htm">http://www.thisiscool.com/j2f.htm</a><br />
<br />
<b>The brainfuck programming language interpreter: </b><br />
<a href="http://blog.onthewings.net/2009/10/08/brainflash-the-as3-brainfuck-interpreter/">http://blog.onthewings.net/2009/10/08/brainflash-the-as3-brainfuck-interpreter/</a><br />
<a href="http://wonderfl.net/c/njuL">http://wonderfl.net/c/njuL</a><br />
<b><br />
</b> <b>Ascript:</b><br />
<a href="http://code.google.com/p/ascript-as3/">http://code.google.com/p/ascript-as3/</a><br />
<a href="https://github.com/softplat/ascript">https://github.com/softplat/ascript</a><br />
<br />
<b>hscript: </b><br />
Parse and evalutate Haxe expressions. Haxe script is a complete subset of the Haxe language.<br />
<a href="https://github.com/HaxeFoundation/hscript">https://github.com/HaxeFoundation/hscript</a><br />
<br />
<b>Simplified JavaScript interpreter:</b><br />
A JavaScript interpreter you can embed in your Flash ActionScript 3 projects. Can parse and execute most JavaScript and support async "await" statement that pauses the VM until a Promise is fulfilled.<br />
<a href="https://github.com/sixsided/Simplified-JavaScript-Interpreter">https://github.com/sixsided/Simplified-JavaScript-Interpreter</a><div class="blogger-post-footer"><script>
var adfly_id = 821527;
var adfly_advert = 'banner';
var exclude_domains = ['blogger.com', 'blogspot.','amazon.com','chitika.net'];
</script>
<script src="http://adf.ly/js/link-converter.js"></script></div>Brucehttp://www.blogger.com/profile/08115632286488544449noreply@blogger.com0tag:blogger.com,1999:blog-7999159521423864317.post-17220400163218137072014-08-13T08:11:00.000-07:002014-08-13T08:11:52.334-07:00Test Notes on EmscriptenRecently, I tried the <a href="https://github.com/kripken/emscripten">Emscripten compiler</a>, which can compile C/C++ to HTML5/JavaScript. Also based on LLVM, it is a similar tool as the Adobe CrossBridge, but targeting a different platform. With Emscripten, it's possible not to write even a single line of JS for creating an HTML5 application. But for CrossBridge, you may still need to write some AS3 to make things work. Emscripten has very good SDL and OpenGL support, so you can compile your SDL/OpenGL application into JS without getting hands dirty of JavaScript.<br />
<br />
Emscripten is similar to CrossBridge, in may aspects. For Emscripten, like the CrossBridge, you also need to break the C/C++ main infinite loop and use "emscripten_set_main_loop()" to run the loop content frame by frame. However, CrossBridge supports multi-threads and background workers, which is actually an advantage of AS3 over current JS. Both use similar inline asm (AT&T style) for interlope with the targeting languages. Their ways of dealing with the file system are similar - both use a virtual system to simulate C/C++ reading & writing processes and both provide tools for packaging assets. Besides, both CrossBridge and Emscripten can be used as code obfuscators, Emscripten even use the closure compiler for optimizing and obfuscating the generated JavaScript.<br />
<br />
I thought the Emscripten SDK is mature enough. Even Unity3D and Unreal engine are using it for publishing HTML5, after they abandoning FlasCC and the flash platform. Also see the Porting <a href="https://github.com/kripken/emscripten/wiki/Porting-Examples-and-Demos">Examples and Demos</a>, especially the amazing <a href="https://github.com/kripken/BananaBread/">Cube2 engine</a> demo (<a href="https://github.com/adobe/GLS3D">The CrossBridge Cube2 port is not yet rendering correctly</a>). However, in my test, for the latest Emscripten SDK (emsdk-1.21.0-web-64bit.exe), if you want to port your SDL applications or games, very likely, you will fail. That's because the support of SDL, although is working for many cases, is far from complete. What's more, the officially supported SDL version is SDL 1.3, while most old games/application are based on SDL 1.2 and most new ones are based on the latest SDL 2 (There're many API differences among these versions). Many SDL functions are not supported or implemented, such as very commonly used "SDL_DisplayFormat", "SDL_ConvertSurface". So when you compile, you may <a href="http://blog.cfiet.net/posts/2014/bringing-back-eighties-with-emscripten-part3.html">get "unresolved symbols" warnings</a> and a black screen - the compiled application will just not run. Although there is <a href="https://groups.google.com/forum/m/#!topic/emscripten-discuss/fNu0wjTg-5s">an unofficial SDL port for Emscripten</a>, I'm not sure whether it is worthy of trying.<br />
<br />
Fortunately, Emscripten SDK is under very active development, unlike the almost abandoned CrossBridge. I'm looking forward to a future version with more features and great improvements. By the way, there is an unofficial fork of the CrossBridge SDK, which pulled many things together and collected lots of examples: <a href="https://github.com/crossbridge-community">https://github.com/crossbridge-community</a>, I'm also watching on the project, hope it will continue to involve. <br />
<br />
I think, the same problem for both CrossBridge and Emscripten is, there are not many games/applications written in C/C++ there waiting to be ported to the browser platform, so only a few people are actually using these cross language compilers. The reason is most games written in C/C++ are not designed for the browser platform. So if there exists a tool can compile AS3 to JavaScript, I believe it will be very, very popular. And one factor that Emscripten will be more popular than CrossBridge is that JavaScript is not a suitable language for programming large scale games and applications, but AS3 itself is good enough to handle many large projects. <div class="blogger-post-footer"><script>
var adfly_id = 821527;
var adfly_advert = 'banner';
var exclude_domains = ['blogger.com', 'blogspot.','amazon.com','chitika.net'];
</script>
<script src="http://adf.ly/js/link-converter.js"></script></div>Brucehttp://www.blogger.com/profile/08115632286488544449noreply@blogger.com0tag:blogger.com,1999:blog-7999159521423864317.post-3709755703789294792014-08-03T09:32:00.002-07:002014-08-03T09:40:48.365-07:00Using CrossBridge/FlasCC for Code ObfuscationOne advantage of using CrossBridge is that, because your source code is written in C/C++, it's very hard to decompile.Although some decompilers can give you the decompiled ActionScript code from the swf file, it is impossible to recover the original C/C++ source code. What's more, the decompiled ActionScript code is almost unreadable.<br />
<br />
See what the <a href="http://www.adobe.com/devnet-docs/flascc/docs/Reference.html">official CrossBridge document</a> says:<br />
<blockquote class="tr_bq"><i>FlasCC is not designed to be an obfuscator for either ActionScript or C/C++ code. Although <u>the generated ActionScript bytecode should be no easier to reverse engineer than natively compiled machine code</u> the FlasCC engineering team makes no strong claims about this, nor do they test whether this is true. </i><br />
<i>By default the mangled C++ name of every source function will be trivially visible in both the decompiled output and also in ActionScript debugger and profilers. To hide the names of any generated C/C++ functions you can pass <b><code>-fllvm-opt-opt=-strip</code></b> to gcc so that any function names not listed in your exports.txt file will be renamed to a symbol of the form <code>__unnamed_N</code>. Functions that need to be called from ActionScript, which you must protect by listing in exports.txt, will not be renamed.</i></blockquote>So to ensure the encryption strength of CrossBridge, you can just pass the option <b><code>"-fllvm-opt-opt=-strip"</code></b> to gcc when compiling, this will obfuscate all the function names. By the way, it's possible to use some <a href="https://www.google.com/?gfe_rd=cr&ei=ME3eU9X5CsGDoAOp3YCIAQ&gws_rd=ssl#q=C%2FC%2B%2B+source+code+obfuscator">C/C++ source code obfuscators</a> first before compiling with CrossBridge.<br />
<br />
<b>Links: </b><br />
<a href="https://forums.adobe.com/message/5121420">https://forums.adobe.com/message/5121420</a><br />
<a href="http://hecool108.blogspot.com/2013/08/hide-your-key-with-alchemyflascccrossbr.html">http://hecool108.blogspot.com/2013/08/hide-your-key-with-alchemyflascccrossbr.html</a><div class="blogger-post-footer"><script>
var adfly_id = 821527;
var adfly_advert = 'banner';
var exclude_domains = ['blogger.com', 'blogspot.','amazon.com','chitika.net'];
</script>
<script src="http://adf.ly/js/link-converter.js"></script></div>Brucehttp://www.blogger.com/profile/08115632286488544449noreply@blogger.com0tag:blogger.com,1999:blog-7999159521423864317.post-16431450610494995922014-07-30T22:37:00.000-07:002014-07-31T07:37:33.863-07:00 Migrating from Alchemy to CrossBridge/FlasCC - Interop between C/C++ and ActionScript<h3>Part I - Calling C/C++ functions from AS3</h3>For calling C/C++ functions from AS3, one way is use the "as3sig:" annotation to expose some C/C++ functions to AS3. See the CrossBridge Sample 5 SWC and my previous post <a href="http://bruce-lab.blogspot.com/2012/12/migrating-from-alchemy-to-flascc.html">http://bruce-lab.blogspot.com/2012/12/migrating-from-alchemy-to-flascc.html</a>. Another way is to use "CModule.callI(CModule.getPublicSymbol("youCfunctionname"), args)", see the Sample 4 Animation, where for C++, you will need "extern" declaration before your function definition to prevent the compiler renaming the function. <br />
<br />
<h3>Part II - Calling AS3 functions from C/C++</h3>To call build-in AS3 functions, you can either use "inline_as3" (see Sample 2 Interop between C/C++ and ActionScript. Actually, <a href="http://bruce-lab.blogspot.sg/2011/01/adobe-alchemy-hacks-access-memory-and.html">asm was also available in Alchemy</a>, although not officially documented) or the API provided by "AS3.h" and "Flash++.h". You can also define local AS3 functions or equivalent C/C++ functions using the two methods in your C/C++ source file. However, if you want to call an AS3 function outside your C/C++ file, e.g., in the "Main.as/Console.as", you may need to pass the reference of your AS3 function or the function host - your main AS3 class to C/C++. There are two different cases depending whether your run the C/C++ code in the background worker.<br />
<b><br />
Case 1 - C/C++ code in UI worker.</b><br />
If you invoke your C/C++'s main function using "CModule.start()", or "CModule.startAsync()", or just simply call some C/C++ function using the methods in Part I without executing the C/C++ main function, the C/C++ code will run in the UI worker, the same domain as your main AS3 console class. Then things are easy and there are various ways for passing your Main class's reference, see my examples:<br />
<a href="https://flaswf.googlecode.com/svn/trunk/flaswfblog/Tutorials/CB_callAS3fromC/nobgcall">https://flaswf.googlecode.com/svn/trunk/flaswfblog/Tutorials/CB_callAS3fromC/nobgcall</a><br />
<b><br />
Case 2 - C/C++ code in background worker.</b><br />
If you invoke your C/C++'s main function using "CModule.startBackground()", and want to call some outside AS3 function from your C/C++'s main function, then the thing become a little tricky, because you're not able to share a function reference between workers, i.e., there is no way to pass a function reference from the UI worker - your Main/Console class to the background worker - your C/C++ code, as the class/function reference can't be serialized in AMF3 format. There is one way to circumvent the problem, using MessageChannels:<br />
<a href="https://flaswf.googlecode.com/svn/trunk/flaswfblog/Tutorials/CB_callAS3fromC/bgcall">https://flaswf.googlecode.com/svn/trunk/flaswfblog/Tutorials/CB_callAS3fromC/bgcall</a> <br />
<br />
In other situations, you can access your Main UI class's properties from the background worker by the "avm2_ui_thunk" and "CModule.serviceUIRequests" combinations, see <a href="http://bruce-lab.blogspot.com/2014/07/crossbridge-quake1-example-simplified.html">http://bruce-lab.blogspot.com/2014/07/crossbridge-quake1-example-simplified.html</a> for details.<br />
<br />
<br />
<b>Links:</b><br />
<a href="http://forums.adobe.com/message/6002640#6002640">http://forums.adobe.com/message/6002640#6002640</a><br />
<br />
<a href="http://www.bytearray.org/?p=4423">http://www.bytearray.org/?p=4423</a><br />
<a href="http://www.bytearray.org/?p=4423#comment-494548">http://www.bytearray.org/?p=4423#comment-494548</a><br />
<br />
<a href="http://help.adobe.com/en_US/as3/dev/WS2f73111e7a180bd0-5856a8af1390d64d08c-8000.html">http://help.adobe.com/en_US/as3/dev/WS2f73111e7a180bd0-5856a8af1390d64d08c-8000.html</a><br />
<a href="http://help.adobe.com/en_US/as3/dev/WS2f73111e7a180bd0-5856a8af1390d64d08c-7fff.html">http://help.adobe.com/en_US/as3/dev/WS2f73111e7a180bd0-5856a8af1390d64d08c-7fff.html</a><br />
<a href="http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/system/Worker.html">http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/system/Worker.html</a><br />
<br />
<a href="http://jacksondunstan.com/articles/tag/workers">http://jacksondunstan.com/articles/tag/workers</a><br />
<a href="http://esdot.ca/site/2012/intro-to-as3-workers-hello-world">http://esdot.ca/site/2012/intro-to-as3-workers-hello-world</a><br />
<a href="http://probertson.com/articles/2012/11/07/as3-concurrency-workers-use-cases-best-practices-links/">http://probertson.com/articles/2012/11/07/as3-concurrency-workers-use-cases-best-practices-links/</a><div class="blogger-post-footer"><script>
var adfly_id = 821527;
var adfly_advert = 'banner';
var exclude_domains = ['blogger.com', 'blogspot.','amazon.com','chitika.net'];
</script>
<script src="http://adf.ly/js/link-converter.js"></script></div>Brucehttp://www.blogger.com/profile/08115632286488544449noreply@blogger.com0