|
// sketch_161217a/sketch_161217a.pde |
|
|
|
String[] src; |
|
JSONArray tickdatas; |
|
|
|
PFont src_mono, mem_mono; |
|
float src_fs = 18.0; |
|
float src_cx = 160.0; |
|
float src_cy = 180.0; |
|
float src_intvl = 28.0; |
|
|
|
float mem_fs = 15.0; |
|
float mem_cx = 350.0; |
|
float mem_cy = 240.0; |
|
float mem_radius = 80.0; |
|
float circle_radius = 40.0; |
|
float memarrowhead = 10.0; |
|
float memarrowheadangle = PI / 6; |
|
|
|
color memcolor, curcolor, strokecolor; |
|
|
|
float src_intvl_y, mem_radius_edge; |
|
|
|
int startFrame = 5; |
|
int endFrame; |
|
|
|
int tick; |
|
ArrayList<int[]> srcposhistory; |
|
void setup() { |
|
size(640, 360); |
|
frameRate(2); |
|
src_mono = createFont("Consolas", src_fs); |
|
mem_mono = createFont("Consolas", mem_fs); |
|
memcolor = color(0, 0, 120); |
|
curcolor = color(255, 120, 0); |
|
strokecolor = color(255, 240, 160); |
|
src_intvl_y = src_intvl * sqrt(3.0) / 2.0; |
|
mem_radius_edge = mem_radius * sqrt(3.0) / 2.0; |
|
srcposhistory = new ArrayList<int[]>(); |
|
srcposhistory.add(new int[]{0, -5, 0}); |
|
src = loadStrings("../bin2dec.hxg"); |
|
tickdatas = loadJSONArray("../log.json"); |
|
endFrame = startFrame + tickdatas.size(); |
|
} |
|
|
|
void draw() { |
|
background(255); |
|
textAlign(CENTER, CENTER); |
|
tick = -1; |
|
if (frameCount >= startFrame) { |
|
tick = frameCount - startFrame; |
|
} |
|
if (frameCount >= endFrame) { |
|
// 最後の状態でしばらく止めておく |
|
tick = endFrame - startFrame - 1; |
|
} |
|
if (frameCount >= endFrame + startFrame) { |
|
// 終了 |
|
noLoop(); |
|
} |
|
JSONObject tickdata; |
|
if (tick == -1) { |
|
// まだ実行が始まっていない状態 |
|
tickdata = new JSONObject(); |
|
tickdata.setInt("tick", -1); |
|
tickdata.setJSONArray("mem", new JSONArray()); |
|
JSONArray mp = new JSONArray(); |
|
mp.setInt(0, 0); |
|
mp.setInt(1, 0); |
|
mp.setInt(2, 0); |
|
tickdata.setJSONArray("mp", mp); |
|
tickdata.setBoolean("md", false); |
|
} else { |
|
tickdata = tickdatas.getJSONObject(tick); |
|
} |
|
drawMem(tickdata); |
|
drawSrc(tickdata); |
|
textAlign(LEFT); |
|
if (tick >= 0) { |
|
text("t = " + tick, 5, src_fs); |
|
} |
|
saveFrame("anim/######.png"); |
|
} |
|
|
|
PVector getSrcPosition(int x, int y) { |
|
return new PVector( |
|
src_cx + src_intvl * (y * 0.5 + x), |
|
src_cy + src_intvl_y * y |
|
); |
|
} |
|
|
|
void drawSrc(JSONObject tickdata) { |
|
textFont(src_mono); |
|
noStroke(); |
|
fill(255); |
|
rect(0, 0, width / 2, height); |
|
int[] ipp = {}; |
|
int ipd = 0; |
|
if (tick >= 0) { |
|
ipp = tickdata.getJSONArray("ipp").getIntArray(); |
|
ipd = tickdata.getInt("dir", -1); |
|
srcposhistory.add(new int[]{ipp[0], ipp[1], ipd}); |
|
} |
|
float sw = 20.0; |
|
noFill(); |
|
stroke(strokecolor); |
|
for (int i = srcposhistory.size() - 1; i > 0 && sw > 0.0; i--) { |
|
int[] stt = srcposhistory.get(i - 1); |
|
int[] end = srcposhistory.get(i); |
|
PVector sttv = getSrcPosition(stt[0], stt[1]); |
|
PVector endv = getSrcPosition(end[0], end[1]); |
|
strokeWeight(sw); |
|
sw -= 1.0; |
|
if (PVector.sub(endv, sttv).mag() > src_intvl + 1) { |
|
PVector dv = new PVector(src_intvl * 0.5, 0); |
|
dv.rotate(PI * stt[2] / 3); |
|
PVector mv; |
|
mv = PVector.add(sttv, dv); |
|
line(sttv.x, sttv.y, mv.x, mv.y); |
|
mv = PVector.sub(endv, dv); |
|
line(endv.x, endv.y, mv.x, mv.y); |
|
continue; |
|
} |
|
line(sttv.x, sttv.y, endv.x, endv.y); |
|
} |
|
strokeWeight(1); |
|
for (int i = 0; i < src.length; i++) { |
|
String line = src[i]; |
|
for (int j = 0; j < line.length(); j++) { |
|
int x = j - 5, y = i - 5; |
|
char cmd = line.charAt(j); |
|
if (tick >= 0 && x == ipp[0] && y == ipp[1]) { |
|
fill(curcolor); |
|
} else if (cmd == '.') { |
|
fill(160); |
|
} else { |
|
fill(0); |
|
} |
|
PVector vpos = getSrcPosition(x, y); |
|
text(cmd, vpos.x, vpos.y); |
|
} |
|
} |
|
} |
|
|
|
PVector[] getMemEdgePositions(int x, int y, int dir) { |
|
PVector center = new PVector( |
|
mem_cx + mem_radius_edge * 2 * (y * 0.5 + x), |
|
mem_cy + mem_radius * 1.5 * y |
|
); |
|
PVector dv1 = new PVector(mem_radius, 0); |
|
PVector dv2 = new PVector(mem_radius, 0); |
|
dv1.rotate(PI * (dir + 0.5) / 3); |
|
dv2.rotate(PI * (dir - 0.5) / 3); |
|
return new PVector[]{PVector.add(center, dv1), PVector.add(center, dv2)}; |
|
} |
|
|
|
PVector getMemPosition(int x, int y, int dir) { |
|
PVector center = new PVector( |
|
mem_cx + mem_radius_edge * 2 * (y * 0.5 + x), |
|
mem_cy + mem_radius * 1.5 * y |
|
); |
|
PVector dv = new PVector(mem_radius_edge, 0); |
|
dv.rotate(PI * dir / 3); |
|
return center.add(dv); |
|
} |
|
|
|
void drawMemCell(int x, int y, int dir, String data) { |
|
color fillcolor, textcolor; |
|
if (tick >= 164 && x == 1 && y == -1 && dir == -1) { |
|
fillcolor = color(0, 0, 140); |
|
textcolor = 255; |
|
} else { |
|
fillcolor = 250; |
|
textcolor = memcolor; |
|
} |
|
PVector memv = getMemPosition(x, y, dir); |
|
fill(fillcolor); |
|
stroke(0); |
|
ellipse(memv.x, memv.y, circle_radius, circle_radius); |
|
fill(textcolor); |
|
noStroke(); |
|
text(data, memv.x, memv.y); |
|
} |
|
void drawMem(JSONObject tickdata) { |
|
JSONArray mp = tickdata.getJSONArray("mp"); |
|
int mpx = mp.getInt(0), mpy = mp.getInt(1), mpd = mp.getInt(2); |
|
boolean iscw = tickdata.getBoolean("md"); |
|
textFont(mem_mono); |
|
for (int y = -4; y <= 4; y++) { |
|
for (int x = -4; x <= 4; x++) { |
|
for (int dir = -1; dir <= 1; dir++) { |
|
PVector[] eps = getMemEdgePositions(x, y, dir); |
|
noFill(); |
|
if (x == mpx && y == mpy && dir == mpd) { |
|
stroke(curcolor); |
|
strokeWeight(4); |
|
PVector arrowv, arrowend; |
|
if (iscw) { |
|
arrowv = PVector.sub(eps[0], eps[1]); |
|
arrowend = eps[0]; |
|
} else { |
|
arrowv = PVector.sub(eps[1], eps[0]); |
|
arrowend = eps[1]; |
|
} |
|
PVector v1 = arrowv.copy(); |
|
v1.setMag(memarrowhead); |
|
PVector v2 = v1.copy(); |
|
v1.rotate(PI - memarrowheadangle); |
|
v2.rotate(PI + memarrowheadangle); |
|
v1.add(arrowend); |
|
v2.add(arrowend); |
|
line(arrowend.x, arrowend.y, v1.x, v1.y); |
|
line(arrowend.x, arrowend.y, v2.x, v2.y); |
|
} else { |
|
stroke(0); |
|
strokeWeight(1); |
|
} |
|
line(eps[0].x, eps[0].y, eps[1].x, eps[1].y); |
|
strokeWeight(1); |
|
drawMemCell(x, y, dir, "0"); |
|
} |
|
} |
|
} |
|
JSONArray mem = tickdata.getJSONArray("mem"); |
|
int memsize = mem.size(); |
|
for (int i = 0; i < memsize; i++) { |
|
JSONArray memcell = mem.getJSONArray(i); |
|
JSONArray memcellpos = memcell.getJSONArray(0); |
|
int memcelldata = memcell.getInt(1); |
|
int memx = memcellpos.getInt(0); |
|
int memy = memcellpos.getInt(1); |
|
int memd = memcellpos.getInt(2); |
|
PVector memv = getMemPosition(memx, memy, memd); |
|
fill(255); |
|
noStroke(); |
|
ellipse(memv.x, memv.y, circle_radius + 1, circle_radius + 1); |
|
drawMemCell(memx, memy, memd, String.valueOf(memcelldata)); |
|
} |
|
} |