· 7 years ago · Jan 05, 2019, 06:30 AM
1#include <stdio.h>
2#include <string.h>
3#include <stdlib.h>
4#include <math.h>
5#include "tables.h"
6
7
8/*
9more of a quality of life
10feature to keep track of
11my selection between functions
12*/
13
14char * script = NULL;
15int scriptLength = 0;
16
17//counters to esimate execution time
18unsigned int waits = 0;
19unsigned int longwaits = 0;
20
21void wait(){
22 waits++;
23}
24
25void printFileBuffer(char * arg){
26 FILE * mPtr = fopen("script.txt","w");
27 fprintf(mPtr,"$${\n");
28
29 fprintf(mPtr,"%s\n",arg);
30 free(arg);
31
32 fprintf(mPtr,"UNSET(@done);\n");
33 fprintf(mPtr,"}$$\n");
34 fclose(mPtr);
35
36 printf("done\n estimated execution time: %i \n",longwaits + waits);
37}
38
39short commandBuffer = 50;
40
41void toScript(char* message){
42 _Bool printing = 0;
43 if(printing){
44 short length = strlen(message);
45 scriptLength += length;
46 script = realloc(script,scriptLength + 1);
47 strncat(script,message,length);
48 }
49}
50
51void comment(char * message){
52 char comment[80] = "// ";
53 strncat(comment,message,80);
54 strncat(comment," \n",80);
55 toScript(comment);
56}
57
58_Bool mask(unsigned char type){
59 _Bool mask[] = {0,0,0,0,0,0,0,0,0,0,0};
60 return mask[type];
61}
62
63char *blockTable[][16] ={
64 {"air","air"},
65 {"observor","machine_Base"},
66 {"redstone","redstone_Off","redstone_Off","redstone_Off","redstone_Off","redstone_Off"},
67 {"redstone_Block","redstone_Off"},
68 {"redstone_Lamp","redstone_Lamp"},
69 {"redstone_repeater","redstone_Tile","redstone_Off","generic_Wood","redstone_Off"},
70 {"redstone_torch","generic_Wood","redstone_On"},
71 {"slab","slab"},
72 {"sticky_piston","machine_Base","generic_Wood","slime"},
73 {"piston","machine_Base","generic_Wood"},
74 {"wood","wood"},
75 {"wool","wool"},
76 {"ice","ice"}
77};
78
79unsigned char blockLookup(char* type){
80 size_t numElements = sizeof(blockTable) / sizeof(blockTable[0]);
81 for(size_t i = 0; i < numElements; i++){
82 if(!strncmp(type,blockTable[i][0],strlen(blockTable[i][0])) && strlen(type) == strlen(blockTable[i][0])){
83 return i;
84 }
85 }
86 //error not in table
87 printf("blockLookup() - what is %s?\n",type);
88 return -1;
89}
90
91size_t partCount(unsigned char type){
92 for(int i = 1; i < 16; i++){
93 if(blockTable[type][i] == NULL){
94 return i - 1;
95 }
96 }
97 return 16;
98}
99
100char* getPartnameForBlock(unsigned char type, unsigned char part){
101 unsigned char numTypes = sizeof(blockTable) / sizeof(blockTable[0]);
102 unsigned char numParts = sizeof(blockTable[type]) / sizeof(blockTable[type][0]);
103 if(type < numTypes){
104 if(part < numParts){
105 return blockTable[type][part + 1];
106 }
107 else{
108 //error not in table
109 printf("getPartnameForBlock() - what is %i?\n",part);
110 return "NULL"; //lol
111 }
112 }
113 else{
114 //error not in table
115 printf("getPartnameForBlock() - what is %i?\n",type);
116 return "NULL"; //lol
117 }
118}
119
120char* reverseBlockLookup(unsigned char type){
121 unsigned char numElements = sizeof(blockTable) / sizeof(blockTable[0]);
122 if(type < numElements)
123 return blockTable[type][0];
124 else{
125 //error not in table
126 printf("reverseBlockLookup() - what is %i?\n",type);
127 return "NULL"; //lol
128 }
129}
130
131//this set is disjointed from the blockTable as in their order and apperarance of materials are NOT and CAN NOT BE the same
132char *partTable[] ={
133 "air",
134 "machine_Base",
135 "redstone_Off",
136 "redstone_On",
137 "redstone_Lamp",
138 "redstone_Tile",
139 "generic_Wood",
140 "slab",
141 "slime",
142 "wood",
143 "wool",
144 "ice"
145};
146
147unsigned char PartLookup(char* partName){
148 size_t numParts = sizeof(partTable) / sizeof(partTable[0]);
149 for(size_t part = 0; part < numParts; part++){
150 if(!strncmp(partName,partTable[part],strlen(partTable[part])) && strlen(partName) == strlen(partTable[part])){
151 return part;
152 }
153 }
154
155 //error not in table
156 printf("PartLookup() - what is %s?\n",partName);
157 return -1;
158}
159
160char* reversePartLookup(unsigned char part){
161 unsigned char numElements = sizeof(partTable) / sizeof(partTable[0]);
162 if(part < numElements)
163 return partTable[part];
164 else{
165 //error not in table
166 printf("reversePartLookup() - what is %i?\n",part);
167 return "NULL"; //lol
168 }
169}
170
171unsigned int collorLookup(int value, unsigned char part){
172
173 //minecraft wool RGB values
174 unsigned int woolMap[16] = {
175 0xE9ECEC,0xF07613,0xBD44B3,0x3AAFD9,
176 0xF8C627,0x70B919,0xED8DAC,0x3E4447,
177 0x8E8E86,0x158991,0x792AAC,0x35399D,
178 0x724728,0x546D1B,0xA12722,0x141519
179 };
180
181 unsigned int woodmap[4] = {
182 0xc15000,0x397a03,0x02367f,0x89057a
183 };
184
185 if (part == PartLookup("wood")) return woodmap[value];
186 else if(part == PartLookup("wool")) return woolMap[value];
187
188 else if(part == PartLookup("redstone_Off")) return 0x560000;
189 else if(part == PartLookup("redstone_On")) return 0xd10000;
190 else if(part == PartLookup("slime")) return 0xA9C54E;
191 else if(part == PartLookup("generic_Wood")) return 0xffdb8e;
192 else if(part == PartLookup("machine_Base")) return 0x3d3d3d;
193 else if(part == PartLookup("redstone_Tile")) return 0xa8a8a8;
194 else if(part == PartLookup("redstone_Lamp")) return 0x751d0b;
195 else if(part == PartLookup("slab")) return 0x8d9093;
196 else if(part == PartLookup("ice")) return 0xa5c8ff;
197 else if(part == PartLookup("air")) return 0x000000;
198
199 printf("collorLookup() - could not find collor for %s\n",reversePartLookup(part));
200 return 0;
201}
202
203struct block{
204 unsigned char type;
205 unsigned char value;
206 char relDir;
207};
208
209// x z y
210struct block ***map;
211
212struct point{
213 short x;
214 short z;
215 short y;
216};
217
218//Block map
219//keep track of raw size for convienience
220short mapW = 1,mapH = 1,mapD = 1;
221//teh extent of the canvas as a function of 2 of its corners
222short mapXA = 0,mapZA = 0,mapYA = 0,mapXB = 0,mapZB = 0,mapYB = 0;
223
224//keep track of raw size for convienience
225short selW = 1,selH = 1,selD = 1; //if i really have a selection larger than 255 i have a problem...
226//pos1/pos2
227short selXA = 0,selZA = 0,selYA = 0,selXB = 0,selZB = 0,selYB = 0;
228
229//can be placed anywhere and wil show the selection
230void showSelection(unsigned int counter){
231 printf("SEL #%-3i H:%-5iW:%-5iD:%-5i A X:%-5iY:%-5iZ:%-5i B X:%-5iY:%-5iZ:%-5i\n",counter,selH,selW,selD,selXA,selZA,selYA,selXB,selZB,selYB);
232}
233
234//can be placed anywhere and wil show the selection
235void showMap(unsigned int counter){
236 printf("MAP #%-3i H:%-5iW:%-5iD:%-5i A X:%-5iY:%-5iZ:%-5i B X:%-5iY:%-5iZ:%-5i\n",counter,mapH,mapW,mapD,mapXA,mapZA,mapYA,mapXB,mapZB,mapYB);
237}
238
239_Bool outofBounds(){
240 return(selXA < mapXA || selZA < mapZA || selYA < mapYA || selXB > mapXB || selZB > mapZB || selYB > mapYB);
241}
242
243short* getSelExtent(char Dir){
244 switch (Dir) {
245 case 'l': if(selXA > selXB) return &selXA; else return &selXB; break;
246 case 'r': if(selXA < selXB) return &selXA; else return &selXB; break;
247 case 'u': if(selZA > selZB) return &selZA; else return &selZB; break;
248 case 'd': if(selZA < selZB) return &selZA; else return &selZB; break;
249 case 'f': if(selYA > selYB) return &selYA; else return &selYB; break;
250 case 'b': if(selYA < selYB) return &selYA; else return &selYB; break;
251 }
252 return NULL; //error
253}
254
255short* getMapExtent(char Dir){
256 switch (Dir) {
257 case 'l': if(mapXA > mapXB) return &mapXA; else return &mapXB; break;
258 case 'r': if(mapXB < mapXA) return &mapXB; else return &mapXA; break;
259 case 'u': if(mapZA > mapZB) return &mapZA; else return &mapZB; break;
260 case 'd': if(mapZB < mapZA) return &mapZB; else return &mapZA; break;
261 case 'f': if(mapYA > mapYB) return &mapYA; else return &mapYB; break;
262 case 'b': if(mapYB < mapYA) return &mapYB; else return &mapYA; break;
263 }
264 return NULL; //error
265}
266
267struct extents{
268 short l;
269 short r;
270 short u;
271 short d;
272 short f;
273 short b;
274};
275
276struct extents getAllSelExtents(){
277 struct extents ret;
278 ret.l = (selXA > selXB? selXA:selXB);
279 ret.r = (selXA < selXB? selXA:selXB);
280 ret.u = (selZA > selZB? selZA:selZB);
281 ret.d = (selZA < selZB? selZA:selZB);
282 ret.f = (selYA > selYB? selYA:selYB);
283 ret.b = (selYA < selYB? selYA:selYB);
284 return ret;
285}
286
287struct extents getAllMapExtents(){
288 struct extents ret;
289 ret.l = (mapXA > mapXB? mapXA:mapXB);
290 ret.r = (mapXA < mapXB? mapXA:mapXB);
291 ret.u = (mapZA > mapZB? mapZA:mapZB);
292 ret.d = (mapZA < mapZB? mapZA:mapZB);
293 ret.f = (mapYA > mapYB? mapYA:mapYB);
294 ret.b = (mapYA < mapYB? mapYA:mapYB);
295 return ret;
296}
297
298//RGB masks
299unsigned int R = 0xFF0000;
300unsigned int G = 0x00FF00;
301unsigned int B = 0x0000FF;
302
303void tint(unsigned int *A, unsigned int C){
304 *A = (*A & ~R) | (((*A & R) + C) & R);
305 *A = (*A & ~G) | (((*A & G) + C) & G);
306 *A = (*A & ~B) | (((*A & B) + C) & B);
307}
308
309void printPixel(unsigned int collor,FILE * _Ptr){
310 int pixel[3];
311 pixel[0] = (collor & R) >> 16;
312 pixel[1] = (collor & G) >> 8;
313 pixel[2] = (collor & B);
314 fprintf(_Ptr,"%i %i %i ",pixel[0],pixel[1],pixel[2]);
315}
316
317void darken(unsigned int* whole,float scaler){
318 // remove old part then get new part ... getting the new part was hard...
319 *whole = (*whole & ~R) | (((int)((*whole & R) * (scaler / 2)) & R) + (((*whole & R)/3) & R));
320 *whole = (*whole & ~G) | (((int)((*whole & G) * (scaler / 2)) & G) + (((*whole & G)/3) & G));
321 *whole = (*whole & ~B) | (((int)((*whole & B) * (scaler / 2)) & B) + (((*whole & B)/3) & B));
322}
323
324_Bool inSel(short x,short z,short y){
325 struct extents sel = getAllSelExtents();
326 return (x <= sel.l && x >= sel.r && z <= sel.u && z >= sel.d && y <= sel.f && y >= sel.b);
327}
328
329void buildImmages(){
330
331 unsigned int selCollor = 0xDBDADC;
332
333 unsigned int backround = 0x201020;
334
335 printf("%i %i %i\n",mapW,mapH,mapD);
336
337 FILE * Top = fopen("topView.pnm","w");
338 fprintf(Top,"P3\n");
339 fprintf(Top,"%i %i\n",mapW,mapD);
340 printf("%i %i\n",mapW,mapD);
341 fprintf(Top,"255\n");
342
343 for(short y = mapD - 1; y >=0; y--){
344 for(short x = mapW - 1; x >= 0; x--){
345 unsigned int collor = backround;
346 for(short z = 0; z < mapH; z++){
347 int blockCollor = collorLookup(map[x][z][y].value,PartLookup(getPartnameForBlock(map[x][z][y].type,0)));
348 if(blockCollor > 0){
349 collor = blockCollor;
350 float scaler = (float)z / (mapH);
351 darken(&collor,scaler);
352 }
353 }
354 if(inSel(x,selZA,y)){
355 tint(&collor,selCollor);
356 }
357 printPixel(collor,Top);
358 }
359 fprintf(Top,"\n");
360 }
361 fclose(Top);
362
363 FILE * Front = fopen("frontview.pnm","w");
364 fprintf(Front,"P3\n");
365 fprintf(Front,"%i %i\n",mapW,mapH);
366 printf("%i %i\n",mapW,mapH);
367 fprintf(Front,"255\n");
368
369 for(short z = mapH - 1; z >= 0; z--){
370 for(short x = mapW - 1; x >= 0; x--){
371 unsigned int collor = backround;
372 for(short y = mapD - 1; y >= 0; y--){
373 int blockCollor = collorLookup(map[x][z][y].value,PartLookup(getPartnameForBlock(map[x][z][y].type,0)));
374 if(blockCollor != 0){
375 collor = blockCollor;
376 float scaler = (float)(mapD - y) / mapD;
377 darken(&collor,scaler);
378 }
379 }
380 if(inSel(x,z,selYA)){
381 tint(&collor,selCollor);
382 }
383 printPixel(collor,Front);
384 }
385 fprintf(Front,"\n");
386 }
387 fclose(Front);
388
389 FILE * Left = fopen("leftview.pnm","w");
390 fprintf(Left,"P3\n");
391 fprintf(Left,"%i %i\n",mapD,mapH);
392 printf("%i %i\n",mapD,mapH);
393 fprintf(Left,"255\n");
394
395 for(short z = mapH - 1; z >= 0; z--){
396 for(short y = mapD - 1; y >= 0; y--){
397 unsigned int collor = backround;
398 for(short x = 0; x < mapW; x++){
399 int blockCollor = collorLookup(map[x][z][y].value,PartLookup(getPartnameForBlock(map[x][z][y].type,0)));
400 if(blockCollor != 0){
401 collor = blockCollor;
402 float scaler = (float)(mapW - x) / mapW;
403 darken(&collor,scaler);
404 }
405 }
406 if(inSel(selXA,z,y)){
407 tint(&collor,selCollor);
408 }
409 printPixel(collor,Left);
410 }
411 fprintf(Left,"\n");
412 }
413 fclose(Left);
414}
415
416void updateSelDementions(char Dir){
417 if(Dir == 'u' || Dir == 'd')//if the direction is up or down the selection will get shorter
418 selH = (*getSelExtent('u') - *getSelExtent('d')) + 1;
419 else if(Dir == 'l' || Dir == 'r')//if the direction is left or right the selection will get thinner
420 selW = (*getSelExtent('l') - *getSelExtent('r')) + 1;
421 else if(Dir == 'f' || Dir == 'b')//if the direction is forward or backward the selection will get shallower
422 selD = (*getSelExtent('f') - *getSelExtent('b')) + 1;
423}
424
425//allocate more memory
426void expandBlockMap(unsigned short change, char Dir){
427
428 if(mapW > 500 || mapH > 500 || mapD > 500){
429 printf("WARNING LARGE MAP!\n");
430 buildImmages();
431 getchar();
432 showMap(0);
433 }
434
435 if(Dir == 'l' || Dir == 'u' || Dir == 'f'){
436 *getMapExtent(Dir) += change; // twards positive numbers get bigger
437 }
438 if(Dir == 'r' || Dir == 'd' || Dir == 'b'){
439 *getMapExtent(Dir) -= change; // twards negitive numbers get smaller
440 }
441
442 unsigned short tempW = mapW;
443 unsigned short tempH = mapH;
444 unsigned short tempD = mapD;
445
446 //calculate the highth the selW and the breadth...
447 if(Dir == 'r' || Dir == 'l')//if the direction is left or right the map will get thinner
448 mapW = abs(mapXB - mapXA) + 1;
449 else if(Dir == 'u' || Dir == 'd')//if the direction is up or down the map will get shorter
450 mapH = abs(mapZB - mapZA) + 1;
451 else if(Dir == 'f' || Dir == 'b')//if the direction is forward or backward the map will get shallower
452 mapD = abs(mapYB - mapYA) + 1;
453
454 //memory allocation
455 if(Dir == 'r' || Dir == 'l'){
456 map = realloc(map,mapW * sizeof(struct block**));
457 for(short i = tempW; i < mapW; i++){
458 map[i] = malloc(mapH * sizeof(struct block*));
459 for(short j = 0; j < mapH; j++){
460 map[i][j] = malloc(mapD * sizeof(struct block));
461 for(short k = 0; k < mapD; k++){
462 map[i][j][k].type = 0;
463 map[i][j][k].value = 0;
464 }
465 }
466 }
467 //shift data
468 if(Dir == 'r'){
469 unsigned short shiftAmt = mapW - tempW;
470 for(short i = mapW - 1; i >= shiftAmt; i--){
471 map[i] = map[i-shiftAmt];
472 }
473 //reallocate new empty space (unshifted portion)
474 for(short i = shiftAmt - 1; i >= 0; i--){
475 map[i] = malloc(mapH * sizeof(struct block*));
476 for(short j = 0; j < mapH; j++){
477 map[i][j] = malloc(mapD * sizeof(struct block));
478 for(short k = 0; k < mapD; k++){
479 map[i][j][k].type = 0;
480 map[i][j][k].value = 0;
481 }
482 }
483 }
484 }
485 if(Dir == 'r'){
486 //adjust selection for shift
487 selXA += change;
488 selXB += change;
489 mapXA += change;
490 mapXB += change;
491 }
492 }
493
494 else if(Dir == 'u' || Dir == 'd'){
495 for(short i = 0; i < mapW; i++){
496 map[i] = realloc(map[i],mapH * sizeof(struct block*));
497 for(short j = tempH; j < mapH; j++){
498 map[i][j] = malloc(mapD * sizeof(struct block));
499 for(short k = 0; k < mapD; k++){
500 map[i][j][k].type = 0;
501 map[i][j][k].value = 0;
502 }
503 }
504 //shift data
505 if(Dir == 'd'){
506 unsigned short shiftAmt = mapH - tempH;
507 for(short j = mapH - 1; j >= shiftAmt; j--){
508 map[i][j] = map[i][j-shiftAmt];
509 }
510 //reallocate new empty space (unshifted portion)
511 for(short j = shiftAmt - 1; j >= 0; j--){
512 map[i][j] = malloc(mapD * sizeof(struct block));
513 for(short k = 0; k < mapD; k++){
514 map[i][j][k].type = 0;
515 map[i][j][k].value = 0;
516 }
517 }
518 }
519 }
520 if(Dir == 'd'){
521 //adjust selection for shift
522 selZA += change;
523 selZB += change;
524 mapZA += change;
525 mapZB += change;
526 }
527 }
528
529 else if(Dir == 'f' || Dir == 'b'){
530 for(short i = 0; i < mapW; i++){
531 for(short j = 0; j < mapH; j++){
532 map[i][j] = realloc(map[i][j],mapD * sizeof(struct block));
533 for(short k = tempD; k < mapD; k++){
534 map[i][j][k].type = 0;
535 map[i][j][k].value = 0;
536 }
537 //shift data
538 if(Dir == 'b'){
539 unsigned short shiftAmt = mapD - tempD;
540 for(short k = mapD - 1; k >= shiftAmt; k--){
541 map[i][j][k].type = map[i][j][k-shiftAmt].type;
542 map[i][j][k].value = map[i][j][k-shiftAmt].value;
543 map[i][j][k].relDir = map[i][j][k-shiftAmt].relDir;
544 }
545 //0 the data unshifted
546 for(short k = shiftAmt - 1; k >= 0; k--){
547 map[i][j][k].type = 0;
548 map[i][j][k].value = 0;
549 }
550 }
551 }
552 }
553 }
554 if(Dir == 'b'){
555 //adjust selection for shift
556 selYA += change;
557 selYB += change;
558 mapYA += change;
559 mapYB += change;
560 }
561}
562
563void checkAndExpand(unsigned short distance,char Dir){
564
565 //test a shifted cuboid to //moves, stacks and annything you want to check at a distance
566 //if distacne is 0 the test is the selection ;)
567 short selPos = *getSelExtent(Dir) + distance; // twards positive numbers
568 short selNeg = *getSelExtent(Dir) - distance; // twards negitive numbers
569
570 short getmapExtent = *getMapExtent(Dir);
571
572 if(Dir == 'l' || Dir == 'u' || Dir == 'f'){
573 if(selPos > getmapExtent){
574 expandBlockMap(selPos - getmapExtent,Dir);
575 }
576 }
577 if(Dir == 'r' || Dir == 'd' || Dir == 'b'){
578 if(selNeg < getmapExtent){
579 expandBlockMap(getmapExtent - selNeg,Dir);
580 }
581 }
582}
583
584
585
586void waitUntlDone(){
587 char *command = "UNSET(@done); log(waiting for done); DO; WAIT(20ms); UNTIL(@done); log(Done!); \n";
588 toScript(command);
589 longwaits++;
590}
591
592void replace(char* typeA, _Bool specificA,char valueA, char* typeB,_Bool specificB, char valueB){
593 char command[commandBuffer];
594 snprintf(command,commandBuffer,"echo(//replace %s",typeA);
595 toScript(command);
596 if(specificA){
597 snprintf(command,commandBuffer,":%i",valueA);
598 toScript(command);
599 }
600 snprintf(command,commandBuffer," %s",typeB);
601 toScript(command);
602 if(specificB){
603 snprintf(command,commandBuffer,":%i",valueB);
604 toScript(command);
605 }
606 toScript(");\n");
607 waitUntlDone();
608
609 //in memory
610 struct extents selExt = getAllSelExtents();
611
612 for(short i = selExt.r; i <= selExt.l; i++){
613 for(short j = selExt.d; j <= selExt.u; j++){
614 for(short k = selExt.b; k <= selExt.f; k++){
615 if(blockLookup(typeA) == map[i][j][k].type){
616 struct block B;
617 B.type = blockLookup(typeB);
618 if(specificB)
619 B.value = valueB;
620 else
621 B.value = 0;
622 if((specificA && valueA == map[i][j][k].value) || !specificA){
623 map[i][j][k] = B;
624 }
625 }
626 }
627 }
628 }
629}
630
631//commands i can do
632void setBlock(struct block B, _Bool wait){
633
634 //unpack B
635 char* type = reverseBlockLookup(B.type);
636 unsigned char value = B.value;
637
638 //in game
639 char command[commandBuffer];
640 snprintf(command,commandBuffer,"echo(//set %s:%i);\n",type,value);
641 toScript(command);
642 if(wait)
643 waitUntlDone();
644 //in memory
645 struct extents selExt = getAllSelExtents();
646
647 for(short i = selExt.r; i <= selExt.l; i++){
648 for(short j = selExt.d; j <= selExt.u; j++){
649 for(short k = selExt.b; k <= selExt.f; k++){
650 map[i][j][k] = B;
651 }
652 }
653 }
654}
655
656void overlay(char* type, unsigned char value){
657 char command[commandBuffer];
658 snprintf(command,commandBuffer,"echo(//overlay %s:%i);\n",type,value);
659 toScript(command);
660
661 checkAndExpand(1,'u');
662 waitUntlDone();
663
664 //in memory
665 struct extents selExt = getAllSelExtents();
666
667 for(short i = selExt.r; i <= selExt.l; i++){
668 for(short k = selExt.b; k <= selExt.f; k++){
669 for(short j = selExt.u; j >= selExt.d; j--){ //height last
670
671 //get block
672 struct block B;
673 B.type = blockLookup(type);
674 B.value = value;
675
676 //only fill in air and the block under it is not air
677 if(map[i][j][k].type != 0){
678 map[i][j + 1][k] = B; //place block
679 break; //only place 1 block per xz coordinate (only the top portion of the selected blocks)
680 }
681 }
682 }
683 }
684}
685
686//can be placed anywhere and wil shift the selection
687void selectionShift(char Dir, unsigned short amount){
688 //smol switch (relitivlely speaking)
689 checkAndExpand(amount,Dir);
690 switch (Dir) {
691 case 'l': selXA += amount; selXB += amount; break;
692 case 'r': selXA -= amount; selXB -= amount; break;
693 case 'u': selZA += amount; selZB += amount; break;
694 case 'd': selZA -= amount; selZB -= amount; break;
695 case 'f': selYA += amount; selYB += amount; break;
696 case 'b': selYA -= amount; selYB -= amount; break;
697 }
698}
699
700void shift(unsigned short amount,char Dir){
701 if(amount > 0){
702 char command[commandBuffer];
703 snprintf(command,commandBuffer,"echo(//shift %i %c);\n",amount,Dir);
704 toScript(command);
705 selectionShift(Dir,amount);
706 wait();
707 }
708}
709
710struct block*** copySel(){
711 struct extents selExt = getAllSelExtents();
712 struct block*** ret = malloc(selW * sizeof(struct block**));
713 for(short i = selExt.r; i <= selExt.l; i++){
714 ret[i-selExt.r] = malloc(selH * sizeof(struct block*));
715 for(short j = selExt.d; j <= selExt.u; j++){
716 ret[i-selExt.r][j-selExt.d] = malloc(selD * sizeof(struct block));
717 for(short k = selExt.b; k <= selExt.f; k++){
718
719 //get blocks, the right blocks and put them right in the right location
720 ret[i-selExt.r][j-selExt.d][k-selExt.b].type = map[i][j][k].type;
721 ret[i-selExt.r][j-selExt.d][k-selExt.b].value = map[i][j][k].value;
722
723 //remove old block
724 map[i][j][k].type = 0;
725 map[i][j][k].value = 0;
726 }
727 }
728 }
729 return ret;
730}
731
732void pasteSel(struct block*** arg,short amount, char Dir){
733
734 struct extents selExt = getAllSelExtents();
735
736 for(short i = selExt.r; i <= selExt.l; i++){
737 for(short j = selExt.d; j <= selExt.u; j++){
738 for(short k = selExt.b; k <= selExt.f; k++){
739
740 //calculate new position of block. Keep unchanged coordinates the same with default values
741 unsigned short blockBX = i;
742 unsigned short blockBY = j;
743 unsigned short blockBZ = k;
744
745 switch (Dir) { //must only movve in one direction
746 case 'l': blockBX += amount; break;
747 case 'u': blockBY += amount; break;
748 case 'f': blockBZ += amount; break;
749 case 'r': blockBX -= amount; break;
750 case 'd': blockBY -= amount; break;
751 case 'b': blockBZ -= amount; break;
752 }
753 //place block
754 map[blockBX][blockBY][blockBZ] = arg[i-selExt.r][j-selExt.d][k-selExt.b];
755 }
756 }
757 }
758}
759
760void move(unsigned short amount,_Bool shift, char Dir){
761 char command[commandBuffer];
762 snprintf(command,commandBuffer,"echo(//move %i %c",amount,Dir);
763 toScript(command);
764 //preemtivle test the area im moving into b/c its not in the selection
765 checkAndExpand(amount,Dir); //wow that was easy
766
767 if (shift){
768 toScript(" -s);\n");
769 }
770 else{
771 toScript(");\n");
772 }
773 waitUntlDone();
774
775 //in memory
776
777 struct block*** temp = copySel();
778 //although these forloops are identical i must run through them twice or els ill run into undisiered effects of the blocks being moved multiple times
779 pasteSel(temp,amount,Dir);
780
781 //free the copy
782 struct extents selExt = getAllSelExtents();
783 for(short i = selExt.r; i <= selExt.l; i++){
784 for(short j = selExt.d; j <= selExt.u; j++){
785 free(temp[i-selExt.r][j-selExt.d]);
786 }
787 free(temp[i-selExt.r]);
788 }
789 free(temp);
790
791 //shift after operation
792 if (shift){
793 //looks framilliar? it should its the smol switch again, whre moving the selection
794 selectionShift(Dir,amount);
795 }
796}
797
798void stack(short amount,char Dir, char* options){
799 if(amount > 0){
800
801 char command[commandBuffer];
802 snprintf(command,commandBuffer,"echo(//stack %i %c",amount,Dir);
803 toScript(command);
804
805 _Bool preserveAir = 0;
806
807 for(unsigned int i = 0; i < strlen(options); i++){
808 snprintf(command,commandBuffer," -%c",options[i]);
809 toScript(command);
810 preserveAir |= options[i] == 'a';
811 }
812 toScript(");\n");
813
814 waitUntlDone();
815
816 //this is going to be a pain..
817
818 //check last stack tile distacne
819 //determin how much to shift the test selection based on the size of the dimention of the
820 //selection paralel to the direction...
821 short shift = 0;
822 switch (Dir) {
823 case 'l':
824 case 'r':
825 shift = selW * amount; break;//that was easyer that i thought, its the same both ways
826 case 'u':
827 case 'd':
828 shift = selH * amount; break;
829 case 'f':
830 case 'b':
831 shift = selD * amount; break;
832 }
833
834 //check shifted region
835 checkAndExpand(shift,Dir);
836
837 //get extents
838 struct extents selExt = getAllSelExtents();
839
840 //now the real painfull part
841 for(short p = 0; p < amount; p++){ //amount to tile
842 for(short i = selExt.r; i <= selExt.l; i++){
843 for(short j = selExt.d; j <= selExt.u; j++){
844 for(short k = selExt.b; k <= selExt.f; k++){
845
846 //get new origin
847 short blockBX = i;
848 short blockBY = j;
849 short blockBZ = k;
850
851 switch (Dir) { //now direction really matters
852 case 'l': blockBX += selW * (p+1); break;
853 case 'u': blockBY += selH * (p+1); break;
854 case 'f': blockBZ += selD * (p+1); break;
855 case 'r': blockBX -= selW * (p+1); break; //1h so changing the sign is all i have to do here well that was easyer that i thought it would be...
856 case 'd': blockBY -= selH * (p+1); break;
857 case 'b': blockBZ -= selD * (p+1); break;
858 }
859
860 //new block = old block
861 if(!preserveAir || !map[i][j][k].type == 0){
862 map[blockBX][blockBY][blockBZ] = map[i][j][k];
863 }
864 }
865 }
866 }
867 }
868
869 //shift after block operation
870 for(unsigned int i = 0; i < strlen(options); i++){
871 if(options[i] == 's'){
872 //looks framilliar? it should its the smol switch again, whre moving the selection
873 selectionShift(Dir,shift);
874 }
875 }
876 }
877}
878
879void expand(unsigned short amount,char Dir){
880 if(amount <= 0){
881 return;
882 }
883
884 wait();
885 char command[commandBuffer];
886 snprintf(command,commandBuffer,"echo(//expand %i %c);\n",amount,Dir);
887 toScript(command);
888
889 //check to allocate memory to expand into
890 checkAndExpand(amount,Dir);
891
892 //this is a lot smaller than the 1ge switch i had before lol
893 if(Dir == 'l' || Dir == 'u' || Dir == 'f'){
894 *getSelExtent(Dir) += amount;
895 }
896 if(Dir == 'r' || Dir == 'd' || Dir == 'b'){
897 *getSelExtent(Dir) -= amount;
898 }
899
900 //calculate the hight the selW and the breth
901 updateSelDementions(Dir);
902}
903
904char oppDir(char Dir){
905 switch (Dir) {
906 case 'l': return 'r';
907 case 'r': return 'l';
908 case 'u': return 'd';
909 case 'd': return 'u';
910 case 'b': return 'f';
911 case 'f': return 'b';
912 default : printf("oppDir() - Invalid Direction recieved :%c > %i\n",Dir,Dir);
913 }
914 return '\0';
915}
916
917//turns direction 90 degrees left or right from current direction
918char turnDir(char Dir, char turnDir){
919 char dirNum = 0; //default number negitive to catch errors
920 switch (Dir) { //base on 1 so never goes below 0, unless there is an error
921 case 'r': dirNum = 0; break;
922 case 'f': dirNum = 1; break;
923 case 'l': dirNum = 2; break;
924 case 'b': dirNum = 3; break;
925 default : printf("turnDir() - Invalid Turn Direction recieved :%c\n",Dir);
926 }
927 if(turnDir == 'l'){
928 dirNum++;
929 dirNum %= 4;
930 }
931 else{
932 dirNum--;
933 if(dirNum < 0)
934 dirNum = 3;
935 }
936 switch (dirNum) {
937 case 0: return 'r';
938 case 1: return 'f';
939 case 2: return 'l';
940 case 3: return 'b';
941 }
942 return '\0'; //null when something went wrong
943}
944
945void contract(unsigned short amount,char Dir){
946 wait();
947
948 char command[commandBuffer];
949 snprintf(command,commandBuffer,"echo(//contract %i %c);\n",amount,Dir);
950 toScript(command);
951
952 //big ol switch mk2
953 //no need to check for map expansion lol im contracting
954 if(Dir == 'l' || Dir == 'u' || Dir == 'f'){
955 *getSelExtent(oppDir(Dir)) += amount;
956 }
957 if(Dir == 'r' || Dir == 'd' || Dir == 'b'){
958 *getSelExtent(oppDir(Dir)) -= amount;
959 }
960
961 //calculate the hight the selW and the breth
962 updateSelDementions(Dir);
963}
964
965void setRepeater(char Dir){
966 comment("placing repeater based on direction");
967 char* type = "redstone_repeater";
968 unsigned char offset = 0;
969 switch (Dir) {
970 case 'f': offset = 0; break;
971 case 'r': offset = 1; break;
972 case 'b': offset = 2; break;
973 case 'l': offset = 3; break;
974 }
975
976 char dirSet[4] = {(0+offset)%4,(1+offset)%4,(2+offset)%4,(3+offset)%4};
977
978 //pack B
979 struct block B;
980 B.type = blockLookup(type);
981 printf("recording direction %c \n",Dir);
982 B.relDir = Dir;
983
984 //place block depenting on dirrection and offset on actual Dir
985 toScript("if(DIRECTION == \"N\"); ");
986 B.value = dirSet[0]; setBlock(B,0);
987 toScript("elseif(DIRECTION == \"E\"); ");
988 B.value = dirSet[1]; setBlock(B,0);
989 toScript("elseif(DIRECTION == \"S\"); ");
990 B.value = dirSet[2]; setBlock(B,0);
991 toScript("elseif(DIRECTION == \"W\"); ");
992 B.value = dirSet[3]; setBlock(B,0);
993 toScript("endif;\n");
994 comment("wait at end of if");
995 waitUntlDone();
996}
997
998void setredTorch(char Dir){
999 if(Dir != 'u')
1000 comment("placing torch based on direction");
1001 char* type = "redstone_torch";
1002
1003 //pack B
1004 struct block B;
1005 B.type = blockLookup(type);
1006 printf("recording direction %c \n",Dir);
1007 B.relDir = Dir;
1008
1009 //even bigger switch
1010 switch (Dir) {
1011 case 'u': B.value = 5,setBlock(B,0); break;
1012 case 'r':
1013 toScript("if(DIRECTION == \"W\"); ");
1014 B.value = 4,setBlock(B,0);
1015 toScript("elseif(DIRECTION == \"E\"); ");
1016 B.value = 3,setBlock(B,0);
1017 toScript("elseif(DIRECTION == \"N\"); ");
1018 B.value = 1,setBlock(B,0);
1019 toScript("elseif(DIRECTION == \"S\"); ");
1020 B.value = 2,setBlock(B,0);
1021 toScript("endif; \n");
1022 break;
1023 case 'l':
1024 toScript("if(DIRECTION == \"W\"); ");
1025 B.value = 3,setBlock(B,0);
1026 toScript("elseif(DIRECTION == \"E\"); ");
1027 B.value = 4,setBlock(B,0);
1028 toScript("elseif(DIRECTION == \"N\"); ");
1029 B.value = 2,setBlock(B,0);
1030 toScript("elseif(DIRECTION == \"S\"); ");
1031 B.value = 1,setBlock(B,0);
1032 toScript("endif;\n");
1033 break;
1034 case 'f':
1035 toScript("if(DIRECTION == \"W\"); ");
1036 B.value = 2,setBlock(B,0);
1037 toScript("elseif(DIRECTION == \"E\"); ");
1038 B.value = 1,setBlock(B,0);
1039 toScript("elseif(DIRECTION == \"N\"); ");
1040 B.value = 4,setBlock(B,0);
1041 toScript("elseif(DIRECTION == \"S\"); ");
1042 B.value = 3,setBlock(B,0);
1043 toScript("endif;\n");
1044 break;
1045 case 'b':
1046 toScript("if(DIRECTION == \"W\"); ");
1047 B.value = 1,setBlock(B,0);
1048 toScript("elseif(DIRECTION == \"E\"); ");
1049 B.value = 2,setBlock(B,0);
1050 toScript("elseif(DIRECTION == \"N\"); ");
1051 B.value = 3,setBlock(B,0);
1052 toScript("elseif(DIRECTION == \"S\"); ");
1053 B.value = 4,setBlock(B,0);
1054 toScript("endif;\n");
1055 break;
1056 }
1057 if(Dir != 'u')
1058 comment("wait at end of if");
1059 waitUntlDone();
1060}
1061
1062void setObservor(char Dir){
1063 if(Dir != 'u' && Dir != 'd')
1064 comment("placing observor based on direction");
1065 char* type = "observor";
1066
1067 //pack B
1068 struct block B;
1069 B.type = blockLookup(type);
1070 printf("recording direction %c \n",Dir);
1071 B.relDir = Dir;
1072
1073 //even bigger switch mk 2
1074 switch (Dir) {
1075 case 'u':
1076 B.value = 0,setBlock(B,0);
1077 break;
1078 case 'd':
1079 B.value = 1,setBlock(B,0);
1080 break;
1081 case 'r':
1082 toScript("if(DIRECTION == \"W\"); ");
1083 B.value = 3,setBlock(B,0);
1084 toScript("elseif(DIRECTION == \"E\"); ");
1085 B.value = 2,setBlock(B,0);
1086 toScript("elseif(DIRECTION == \"N\"); ");
1087 B.value = 4,setBlock(B,0);
1088 toScript("elseif(DIRECTION == \"S\"); ");
1089 B.value = 5,setBlock(B,0);
1090 toScript("endif;\n");
1091 break;
1092 case 'l':
1093 toScript("if(DIRECTION == \"W\"); ");
1094 B.value = 2,setBlock(B,0);
1095 toScript("elseif(DIRECTION == \"E\"); ");
1096 B.value = 3,setBlock(B,0);
1097 toScript("elseif(DIRECTION == \"N\"); ");
1098 B.value = 5,setBlock(B,0);
1099 toScript("elseif(DIRECTION == \"S\"); ");
1100 B.value = 4,setBlock(B,0);
1101 toScript("endif;\n");
1102 break;
1103 case 'f':
1104 toScript("if(DIRECTION == \"W\"); ");
1105 B.value = 5,setBlock(B,0);
1106 toScript("elseif(DIRECTION == \"E\"); ");
1107 B.value = 4,setBlock(B,0);
1108 toScript("elseif(DIRECTION == \"N\"); ");
1109 B.value = 3,setBlock(B,0);
1110 toScript("elseif(DIRECTION == \"S\"); ");
1111 B.value = 2,setBlock(B,0);
1112 toScript("endif;\n");
1113 break;
1114 case 'b':
1115 toScript("if(DIRECTION == \"W\"); ");
1116 B.value = 4,setBlock(B,0);
1117 toScript("elseif(DIRECTION == \"E\"); ");
1118 B.value = 5,setBlock(B,0);
1119 toScript("elseif(DIRECTION == \"N\"); ");
1120 B.value = 2,setBlock(B,0);
1121 toScript("elseif(DIRECTION == \"S\"); ");
1122 B.value = 3,setBlock(B,0);
1123 toScript("endif;\n");
1124 break;
1125 }
1126 if(Dir != 'u' && Dir != 'd')
1127 comment("wait at end of if");
1128 waitUntlDone();
1129}
1130
1131void setPiston(char Dir, _Bool sticky){
1132 if(Dir != 'u' && Dir != 'd')
1133 comment("placing piston based on direction");
1134
1135 char* type;
1136
1137 if(sticky)
1138 type = "sticky_piston";
1139 else
1140 type = "piston";
1141
1142 //pack B
1143 struct block B;
1144 B.type = blockLookup(type);
1145 printf("recording direction %c \n",Dir);
1146 B.relDir = Dir;
1147
1148 //even bigger switch mk 3
1149 switch (Dir) {
1150 case 'u': B.value = 1,setBlock(B,0); break;
1151 case 'd': B.value = 0,setBlock(B,0); break;
1152 case 'l':
1153 toScript("if(DIRECTION == \"W\"); ");
1154 B.value = 3,setBlock(B,0);
1155 toScript("elseif(DIRECTION == \"E\"); ");
1156 B.value = 2,setBlock(B,0);
1157 toScript("elseif(DIRECTION == \"N\"); ");
1158 B.value = 4,setBlock(B,0);
1159 toScript("elseif(DIRECTION == \"S\"); ");
1160 B.value = 5,setBlock(B,0);
1161 toScript("endif;\n");
1162 break;
1163 case 'r':
1164 toScript("if(DIRECTION == \"W\"); ");
1165 B.value = 2,setBlock(B,0);
1166 toScript("elseif(DIRECTION == \"E\"); ");
1167 B.value = 3,setBlock(B,0);
1168 toScript("elseif(DIRECTION == \"N\"); ");
1169 B.value = 5,setBlock(B,0);
1170 toScript("elseif(DIRECTION == \"S\"); ");
1171 B.value = 4,setBlock(B,0);
1172 toScript("endif;\n");
1173 break;
1174 case 'b':
1175 toScript("if(DIRECTION == \"W\"); ");
1176 B.value = 5,setBlock(B,0);
1177 toScript("elseif(DIRECTION == \"E\"); ");
1178 B.value = 4,setBlock(B,0);
1179 toScript("elseif(DIRECTION == \"N\"); ");
1180 B.value = 3,setBlock(B,0);
1181 toScript("elseif(DIRECTION == \"S\"); ");
1182 B.value = 2,setBlock(B,0);
1183 toScript("endif;\n");
1184 break;
1185 case 'f':
1186 toScript("if(DIRECTION == \"W\"); ");
1187 B.value = 4,setBlock(B,0);
1188 toScript("elseif(DIRECTION == \"E\"); ");
1189 B.value = 5,setBlock(B,0);
1190 toScript("elseif(DIRECTION == \"N\"); ");
1191 B.value = 2,setBlock(B,0);
1192 toScript("elseif(DIRECTION == \"S\"); ");
1193 B.value = 3,setBlock(B,0);
1194 toScript("endif;\n");
1195 break;
1196 }
1197 if(Dir != 'u' && Dir != 'd')
1198 comment("wait at end of if");
1199 waitUntlDone();
1200}
1201
1202unsigned char wire(short inStrength,unsigned char outToll, unsigned char value, unsigned short amount, char Dir){
1203
1204 //pack B
1205 struct block B;
1206 B.type = blockLookup("wool");
1207 B.value = value;
1208
1209 comment("wire");
1210 //current position of end of selection
1211 unsigned short pos = 0;
1212 //current state of the output strength
1213 short outStrength = inStrength - amount;
1214 //support structure for redstone
1215 setBlock(B,1);
1216 stack(amount,Dir,"");
1217 //shift up to do redstone
1218 shift(1,'u');
1219 //check to see if the wire is longer than the input strength
1220 //if so it is safe to place the first repeater where the signal ends
1221 if(inStrength < amount && outStrength < outToll){
1222 shift(inStrength,Dir);
1223 pos += inStrength;
1224 setRepeater(Dir);
1225 outStrength = 16 + pos - amount;
1226 }
1227 //check to see if there is enough room for at least 1 full 16 line
1228 if((amount - inStrength - 1) / 16 > 0){
1229 shift(16,Dir);
1230 setRepeater(Dir);
1231 //check to see if there is at least one more if so use stack to fill in the rest
1232 if(((amount - inStrength - 1) / 16 > 0)){
1233 expand(15,oppDir(Dir));
1234 //-s option ensures im at the end of the lines and in position for the final line if needed
1235 stack(((amount - inStrength) / 16) - 1,Dir,"s");
1236 contract(15,Dir);
1237 }
1238 pos += ((amount - inStrength) / 16) * 16;
1239 outStrength = 16 + pos - amount;
1240 if((amount - inStrength) % 16 == 0){
1241 move(1,0,oppDir(Dir));
1242 outStrength--;
1243 }
1244 }
1245 //if the output is still too weak go to the end and place a repeater just behind it
1246 //this will boost the output to the proper strength reguardless of previous actions
1247 if(outStrength < outToll){
1248 shift(amount - pos - 1,Dir);
1249 pos += amount - pos - 1;
1250 setRepeater(Dir);
1251 outStrength = 16 + pos - amount;
1252 shift(1,Dir);
1253 outStrength = 15;
1254 }
1255 //if the output is proper strength go to end
1256 else{
1257 shift(amount - pos,Dir);
1258 pos += amount - pos;
1259 }
1260 //place redstone
1261 expand(amount,oppDir(Dir));
1262 replace("air",0,0,"redstone",0,0);
1263 contract(amount,Dir);
1264 //go back down into end position
1265 shift(1,'d');
1266
1267 comment("endwire");
1268
1269 return outStrength;
1270}
1271
1272struct vector{
1273 short xCmp;
1274 short yCmp;
1275 short zCmp;
1276};
1277
1278//used to get the vector from one point to another
1279struct vector getPointVector(struct point a, struct point b){
1280 struct vector ret;
1281 ret.xCmp = b.x - a.x;
1282 ret.yCmp = b.z - a.z;
1283 ret.zCmp = b.y - a.y;
1284 return ret;
1285}
1286
1287//returns the distance of a vector using pythagrians theorm
1288float getDistance(struct vector arg){
1289 float ret = sqrt((arg.xCmp * arg.xCmp) + (arg.yCmp * arg.yCmp) + (arg.zCmp * arg.zCmp));
1290 return ret;
1291}
1292
1293void line(char* type, unsigned char value){
1294 comment("line");
1295
1296 char command[commandBuffer];
1297 snprintf(command,commandBuffer,"echo(//line %s:%i)\n",type,value);
1298 toScript(command);
1299
1300 waitUntlDone();
1301
1302 struct point a;
1303 a.x = selXA;
1304 a.z = selZA;
1305 a.y = selYA;
1306
1307 struct point b;
1308 b.x = selXB;
1309 b.z = selZB;
1310 b.y = selYB;
1311
1312 //get the distance from a to b
1313 struct vector aTob = getPointVector(a,b);
1314
1315 //get extents
1316 struct extents selExt = getAllSelExtents();
1317
1318 //now the real painfull part
1319 for(short i = selExt.r; i <= selExt.l; i++){
1320 for(short j = selExt.d; j <= selExt.u; j++){
1321 for(short k = selExt.b; k <= selExt.f; k++){
1322 //block location
1323 struct point c;
1324 c.x = i;
1325 c.z = j;
1326 c.y = k;
1327
1328 //get the distance from a to c and from c to b
1329 struct vector aToc = getPointVector(a,c);
1330 struct vector cTob = getPointVector(b,c);
1331
1332 //if the sum of the distances from a to c and from c to b are the same as from a to b, c must be on the line from a to b
1333 if(getDistance(aToc) + getDistance(cTob) == getDistance(aTob)){
1334 struct block B;
1335 B.type = blockLookup(type);
1336 B.value = value;
1337
1338 //place block at point c
1339 map[i][j][k] = B;
1340 }
1341 }
1342 }
1343 }
1344 comment("endline");
1345}
1346
1347void stairs(char* type, unsigned char value, char Dir, char up, char distance){
1348 comment("stairs");
1349 expand(distance,Dir);
1350 expand(distance,up);
1351 line(type,value);
1352 shift(1,'u');
1353 line("redstone",0);
1354 shift(1,'d');
1355 contract((distance),Dir);
1356 contract((distance),up);
1357 comment("endstairs");
1358}
1359
1360//clear selection
1361void delete(){
1362 comment("delete");
1363
1364 char command[commandBuffer];
1365 snprintf(command,commandBuffer,"echo(//set 0);");
1366 toScript(command);
1367
1368 waitUntlDone();
1369 //get extents
1370 struct extents selExt = getAllSelExtents();
1371
1372 //now the real painfull part
1373 for(short i = selExt.r; i <= selExt.l; i++){
1374 for(short j = selExt.d; j <= selExt.u; j++){
1375 for(short k = selExt.b; k <= selExt.f; k++){
1376
1377 // printf("%i %i %i > %i %i\n",blockX,blockY,blockZ,B.type,B.value);
1378 map[i][j][k].type = 0;
1379 map[i][j][k].value = 0;
1380 }
1381 }
1382 }
1383 comment("enddelete");
1384}
1385
1386void buildDecoderTop(short inBits, char Dir, char stSide, unsigned char rows, unsigned char box){
1387
1388 //pack B
1389 struct block bottom;
1390 bottom.type = blockLookup("wood");
1391 bottom.value = 2;
1392
1393 struct block top;
1394 top.type = blockLookup("wood");
1395 top.value = 3;
1396
1397 comment("buildDecoderTop");
1398 unsigned short entries = pow(2,inBits);
1399 //build top structure
1400 //single bit
1401 setBlock(bottom,1);
1402 overlay("redstone",0);
1403 shift(1,Dir);
1404 shift(1,'u');
1405 setObservor(Dir);
1406 shift(1,Dir);
1407 setBlock(top,1);
1408 shift(1,'d');
1409 setPiston('d',1);
1410 expand(2,oppDir(Dir));
1411 expand(1,'u');
1412 expand(1,oppDir(stSide));
1413 //stack it to the other 5 places
1414 stack(inBits - 1,oppDir(stSide),"");
1415
1416 //change the wool collors to make it look better
1417 shift(2,oppDir(stSide));
1418 replace("wood",1,2,"wood",1,0); //bottom
1419 replace("wood",1,3,"wood",1,1); //top
1420 //do the 3 other middle bits all at once
1421 stack(inBits - 3,oppDir(stSide),""); // -2 for not the first and last bit and an additional -1 becuase its the 3 middle bits
1422 shift(2,stSide);
1423
1424 //expand selection to stack to rest of entries
1425 expand(((inBits - 1) * 2) - 1,oppDir(stSide));
1426 //stack it to the rest of the entries
1427 stack(entries - 1,Dir,"");
1428
1429 //change the wool collors to make it look better
1430 for(short j = 0; j < rows; j++){
1431 for(short k = 0; k < 4; k++){
1432 //took me quite a while to come up with this specific pattern, it better look good
1433 int collor = collorMap[((box >> 2) & 1) ^ ((k >> 1) & 1)][(k & 1)][(box&3) ^ j];
1434 replace("wood",1,k,"wool",1,collor); //bottom
1435 }
1436 stack((entries / rows) - 1,Dir,"");
1437 if(j != rows - 1){
1438 shift(entries / rows * 3,Dir);
1439 }
1440 }
1441 shift((entries / rows * 3) * (rows - 1),oppDir(Dir));
1442
1443 //go to binary Pattern
1444 contract((inBits - 1) * 2,stSide);
1445 contract(2,Dir);
1446 contract(1,'d');
1447 shift(1,'d');
1448 comment("endbuildDecoderTop");
1449}
1450
1451void fillBinPtrn(short inBits, unsigned char significance[], char Dir, char stSide){
1452
1453 //pack B
1454 struct block B;
1455 B.type = blockLookup("redstone_Block");
1456 B.value = 0;
1457
1458 comment("fillBinPtrn");
1459 //number of entries
1460 unsigned short entries = pow(2,inBits);
1461
1462 //encode the decoder (binary with custom bit encoding)
1463 for(short iB = 0; iB < inBits; iB++){
1464 //create bases
1465 //bottom side (inverted bits)
1466 shift(1,'d');
1467 setBlock(B,1);
1468 if(significance[iB] > 1){
1469 expand(2,Dir);
1470 stack(significance[iB]-1,Dir,"");
1471 contract(2,oppDir(Dir));
1472 }
1473 //top side (normal bits)
1474 shift(1,'u');
1475 shift(significance[iB] * 3,Dir);
1476 setBlock(B,1);
1477 if(significance[iB] > 1){
1478 expand(2,oppDir(Dir));
1479 stack(significance[iB]-1,Dir,"");
1480 contract(2,Dir);
1481 }
1482 shift(significance[iB] * 3,oppDir(Dir));
1483
1484 //stack to rest of entries
1485 if(entries / significance[iB] > 2){
1486 //expand to get both sides
1487 expand(1,'d');
1488 expand(6*significance[iB]-1,Dir);
1489 stack((entries / (significance[iB] * 2)-1),Dir,"a");
1490 contract(6*significance[iB]-1,oppDir(Dir));
1491 contract(1,'u');
1492 }
1493 //go to next bit
1494 if(iB != inBits - 1){
1495 shift(2,oppDir(stSide));
1496 }
1497 }
1498
1499 //return from pattern
1500 shift(((inBits - 1) * 2),stSide);
1501 shift(1,'u');
1502 shift(2,oppDir(Dir));
1503 comment("endfillBinPtrn");
1504}
1505
1506void buildDecoder(short inBits,char Dir,char stSide,unsigned char rows,unsigned char significance[],unsigned char box){
1507 comment("buildDecoder");
1508 //scripted actions to build top structure
1509 buildDecoderTop(inBits,Dir,stSide,rows,box);
1510 //fills in binary pattern
1511 fillBinPtrn(inBits,significance,Dir,stSide);
1512 comment("endbuildDecoder");
1513}
1514
1515void tower(unsigned char amount,char up, unsigned char value){
1516
1517 //pack B
1518 struct block B;
1519 B.type = blockLookup("wool");
1520 B.value = value;
1521
1522 comment("tower");
1523 amount--;
1524 if(amount > 0){
1525 if(up == 'u'){
1526 setBlock(B,1);
1527 overlay("redstone",0);
1528 shift(2,'u');
1529 setObservor(up);
1530 if(amount > 1){
1531 stack(amount - 1,'u',"s");
1532 }
1533 overlay("wool",value);
1534 }
1535 else{
1536 setObservor('d');
1537 if(amount > 1){
1538 stack(amount - 1,'d',"s");
1539 }
1540 shift(1,'d');
1541 setBlock(B,1);
1542 shift(1,'d');
1543 }
1544 }
1545 comment("endtower");
1546}
1547
1548void flipFlop(char Dir){
1549
1550 //pack B
1551 struct block B;
1552 B.type = blockLookup("redstone_Block");
1553 B.value = 0;
1554
1555 comment("FlipFlop");
1556 shift(1,'u');
1557 shift(1,Dir);
1558 setPiston(Dir,1);
1559 shift(1,Dir);
1560 setBlock(B,1);
1561 shift(1,Dir);
1562 shift(1,'d');
1563 comment("endFlipFlop");
1564}
1565
1566void buildOutLines(unsigned char outBits, short inBits,char inSide, char outSide, char stSide){
1567 comment("buildOutLines");
1568
1569 char num_levels;
1570
1571 if(outBits > (inBits - 1)){ //this mess or
1572 num_levels = outBits / (inBits - 1);
1573 if(outBits % (inBits - 1) > 1){ //the last level can handle one more then the rest so only increase if the overflow is greater than 1
1574 num_levels++;
1575 }
1576 }
1577 else{
1578 num_levels = 1; // just one
1579 }
1580
1581 unsigned short entries = pow(2,inBits);
1582
1583 //pack B
1584 struct block B1;
1585 B1.type = blockLookup("wool");
1586 B1.value = 5;
1587
1588 //pack B
1589 struct block B2;
1590 B2.type = blockLookup("wool");
1591 B2.value = 7;
1592
1593 //create 1 1x15 wire section
1594 setBlock(B1,1); //a little touch to make it look a little better
1595 shift(1,oppDir(inSide));
1596 setBlock(B2,1);
1597 stack(13,oppDir(inSide),""); //1x15 wire section
1598 shift(1,inSide);
1599 shift(1,'u');
1600 setRepeater(outSide); //place first repeater at end of first output wire
1601 expand(14,oppDir(inSide));
1602 replace("air",0,0,"redstone",1,0); //plce redstone on wire
1603
1604 expand(1,stSide);
1605 expand(1,'d');
1606
1607
1608 //outputs remaining to wire
1609 unsigned char bits = outBits;
1610
1611 expand(2,'d');
1612 if(num_levels > 1){
1613 stack(inBits - 2,oppDir(stSide),"");
1614 bits -= inBits - 1;
1615 stack(num_levels - 1,'d',"");
1616 shift(4,'d');
1617 if(num_levels > 2){
1618 expand((num_levels - 3) * 4,'d');
1619 stack(inBits - 2,oppDir(stSide),"");
1620 contract((num_levels - 3) * 4,'d');
1621 bits -= (inBits - 1) * (num_levels - 2); //just made a (inBits - 2) x (num_levels - 2) box of out lines
1622 shift(4,'d');
1623 }
1624 //last leel
1625 //prevent the area around the encoder from being affected by a stack
1626 move(1,0,stSide);
1627 shift(1,stSide);
1628 stack(1,oppDir(stSide),"");
1629 shift(1,oppDir(stSide));
1630 stack(bits - 1,oppDir(stSide),"");
1631 shift((num_levels - 1) * 4,'u');
1632 }
1633 else{
1634 stack(bits - 1,oppDir(stSide),"");
1635 }
1636
1637
1638 //extend wire sections to the end
1639 expand(((inBits - 1) * 2) - 1,oppDir(stSide)); //expand selection to selecto the 4 1x15 wire sections (expand 2 extra for next operation)
1640 expand((num_levels - 1) * 4,'d');
1641
1642 unsigned char wireStacks = entries / 5; // the number of enteries * the length of each entry / the length or each line reduced
1643 unsigned char trimAmt = (entries * 3) - ((wireStacks) * 15) + 1;
1644
1645 //trim of ends
1646 stack(1,oppDir(inSide),""); //stack the 4 1x15 wire once
1647 shift(trimAmt,oppDir(inSide));
1648 stack(wireStacks-1,oppDir(inSide),""); //then stack to the rest 1() - with the strange shift
1649 shift(trimAmt,inSide);
1650
1651 //negate expantion for wire extension and bring selection to 1x1x1
1652 contract(((inBits - 1) * 2), stSide);
1653 contract((num_levels * 4) - 1,'u');
1654 contract(3,oppDir(inSide));
1655 contract(11,inSide);
1656
1657 //shift selection up into position for next operation
1658 shift(1,'u');
1659 shift(1,stSide);
1660 comment("endbuildOutLines");
1661}
1662
1663void buildandSupport(short inBits, unsigned char outBits, short inSide, char stSide){
1664
1665 comment("buildandSupport");
1666
1667 char num_levels = (outBits / inBits) + 1;
1668 unsigned short entries = pow(2,inBits);
1669
1670 //pack B
1671 struct block B;
1672 B.type = blockLookup("wool");
1673 B.value = 4;
1674
1675 setBlock(B,1);
1676 overlay("redstone",0);
1677 expand(1,'u'); //include redstone
1678 expand(2,oppDir(inSide)); //make selection 3 blocks wide
1679 stack(entries-1,oppDir(inSide),""); //stack to rest of entries
1680 expand((entries-1) * 3,oppDir(inSide)); //expand selection to rest of entries
1681
1682 if(num_levels > 1){
1683 expand(2,'d');
1684 stack(num_levels - 1,'d',"");
1685 expand((num_levels - 1) * 4,'d');
1686 //stack into structure with a option to not overwrite blocks
1687 stack((inBits * 2) - 1,oppDir(stSide),"a");
1688 delete(); //remove start blocks
1689 contract(((num_levels - 1) * 4) + 2,'u');
1690 }
1691 else{
1692 stack((inBits * 2) - 1,oppDir(stSide),"a");
1693 delete(); //remove start blocks
1694 }
1695
1696 //collaps and shift selection for encoding
1697 contract(((entries-1) * 3) + 2,inSide);
1698 contract(1,'d');
1699 shift(1,oppDir(stSide));
1700 comment("endbuildandSupport");
1701}
1702
1703void dataEntry(char* type, unsigned char value, unsigned char entry,char inSide,char stSide, unsigned char max){
1704
1705 comment("dataEntry");
1706
1707 // buildImmages();
1708 // getchar();
1709
1710 //next entry
1711 unsigned char shiftcount = 1;
1712 unsigned char pos = 0;
1713 for(short oB = max - 1; oB >= 0; oB--){ //get the most significant bit first
1714 if((1 & entry >> oB)){
1715 shift(shiftcount,oppDir(stSide));
1716 pos += shiftcount;
1717 replace("wool",1,4,type,1,value);//looks better i think
1718 shift(1,inSide);
1719 setredTorch(inSide);
1720 shift(2,'d');
1721 replace("wool",1,7,type,1,value);//looks better i think
1722 shift(2,'u');
1723 shift(1,oppDir(inSide));
1724 //the next one is at least 2 shifts away
1725 shiftcount = 2;
1726 }
1727 //if no command inbetween shifts increase next shift amount
1728 else{
1729 //the next one is 2 more than it is currently
1730 shiftcount += 2;
1731 }
1732 }
1733 //return to start
1734 if(pos != 0){
1735 shift(pos,stSide);
1736 pos -= pos;
1737 }
1738 comment("enddataEntry");
1739}
1740
1741void lvlDown(char stSide){
1742
1743 //pack B
1744 struct block B;
1745 B.type = blockLookup("wool");
1746 B.value = 4;
1747
1748 comment("lvlDown");
1749 shift(1,stSide);
1750 setredTorch(stSide);
1751 shift(2,'d');
1752 setBlock(B,1);
1753 overlay("redstone",0);
1754 shift(1,oppDir(stSide));
1755 setredTorch(oppDir(stSide));
1756 shift(2,'d');
1757 comment("endlvlDown");
1758}
1759
1760void buildEncoder(unsigned char rows, unsigned char collumns,unsigned char Table[rows][collumns],short inBits, unsigned char outBits, char stSide,char inSide, char outSide){
1761 comment("buildEncoder");
1762
1763 //how manny num_levels of outputs will i need?
1764 char num_levels = (outBits / inBits) + 1;
1765 unsigned short entries = pow(2,inBits);
1766
1767 //build encoder sturcture middle section (big nand gate per entry)
1768
1769 //get to start of output wires
1770 shift(4,'d');
1771 shift(1,oppDir(stSide));
1772
1773 //nothing mutch to see here just some scripted actions to build support structures
1774 buildOutLines(outBits,inBits,inSide,outSide,stSide);
1775 buildandSupport(inBits,outBits,inSide,stSide);
1776
1777 //start encoding...
1778 for(unsigned char row = 0; row < rows; row++){
1779 for(unsigned char col = 0; col < collumns; col++){
1780 if(Table[row][col] != 0){
1781 unsigned char entry = Table[row][col];// get entry to encode from table
1782 unsigned char offset = 0;
1783 unsigned char towers = 0;
1784 for(unsigned char level = 0; level < num_levels; level++){
1785 unsigned char partition; //the part of the entry left to encode
1786 unsigned char max;
1787 if(level < num_levels - 1){ //all but the last level
1788 max = inBits - 1; //how manny bits i can write this level
1789 partition = entry >> (outBits - (max + offset)); //get the next most significant bunch first
1790 }
1791 else{
1792 if(outBits > inBits - 1){
1793 max = (outBits - ((num_levels - 1) * (inBits - 1))); //the rest of the bits can fit
1794 }
1795 else{
1796 max = outBits; //all of the bits can fit
1797 }
1798 partition = entry;
1799 }
1800
1801 if (level == num_levels - 1 && num_levels > 1){
1802 shift(1,stSide);
1803 }
1804 unsigned char dataValue = entry % 16;
1805 dataEntry("wool",dataValue,partition,inSide,stSide, max);
1806 if (level == num_levels - 1 && num_levels > 1){
1807 shift(1,oppDir(stSide));
1808 }
1809 if((level != num_levels - 1) && (entry >> (outBits - (max + offset))) != 0){ //only encode data if there is data left to encode
1810 lvlDown(stSide); //some more scripted actions
1811 towers++; //keep track of how far down i am
1812 }
1813 offset += max;
1814 }
1815 if(num_levels > 1){
1816 shift(towers * 4,'u');
1817 }
1818 }
1819 //next entry
1820 shift(3,oppDir(inSide));
1821 }
1822 }
1823 //go back to origin
1824 shift((entries * 3) + 3,inSide);
1825 shift(2,'u');
1826 comment("endbuildEncoder");
1827}
1828
1829void buildSegment(char Dir){
1830 comment("buildSegment");
1831
1832 //pack B
1833 struct block B;
1834 B.type = blockLookup("redstone_Lamp");
1835 B.value = 0;
1836
1837 shift(1,Dir);
1838 setBlock(B,1);
1839 stack(2,Dir,"");
1840 shift(1,oppDir(Dir));
1841 comment("endbuildSegment");
1842}
1843
1844void seperateNibble(char* type, unsigned char value, char inSide, char stSide){
1845 comment("seperateNibble");
1846
1847 //pack B
1848 struct block B;
1849 B.type = blockLookup(type);
1850 B.value = value;
1851
1852 shift(6,oppDir(inSide));
1853 shift(2,'d');
1854 shift(1,stSide);
1855 setBlock(B,1);
1856 expand(1,'u');
1857 stack(5,'u',"");
1858 contract(1,'d');
1859 shift(2,'u');
1860 shift(6,inSide);
1861 shift(1,oppDir(stSide));
1862 comment("endseperateNibble");
1863}
1864
1865void build7segLights(char* type, unsigned char value, char stSide, char inSide){
1866 comment("build7segLights");
1867
1868 //get to corner of display
1869 shift(1,stSide);
1870 shift(5,oppDir(inSide));
1871 shift(3,'d');
1872
1873 //pack ice
1874 struct block ice;
1875 ice.type = blockLookup("ice");
1876 ice.value = value;
1877
1878 //pack case
1879 struct block casing;
1880 casing.type = blockLookup(type);
1881 casing.value = 15;
1882
1883 expand(12,'u');
1884 expand(8,oppDir(stSide));
1885 expand(1,oppDir(inSide));
1886 setBlock(casing,1);
1887 contract(1,oppDir(inSide));
1888 contract(1,oppDir(stSide));
1889 contract(1,stSide);
1890 replace("wool",0,0,type,1,value);
1891 contract(1,oppDir('u'));
1892 contract(1,oppDir('d'));
1893 setBlock(ice,1);
1894 shift(1,inSide);
1895 contract(1,oppDir(stSide));
1896 contract(5,stSide);
1897 contract(9,'d');
1898 contract(1,'u');
1899
1900 for(short i = 0; i < 2;i++){
1901 buildSegment('u');
1902 buildSegment('r');
1903 if(i != 2)
1904 shift(4,'u');
1905 }
1906 shift(4,oppDir(stSide));
1907 for(short i = 0; i < 2;i++){
1908 buildSegment('d');
1909 if(i != 2){
1910 buildSegment('l');
1911 shift(4,'d');
1912 }
1913 }
1914 //return to origin
1915 shift(5,stSide);
1916 shift(5,inSide);
1917 shift(1,'u');
1918 comment("endbuild7segLights");
1919}
1920
1921void LWire(char Dir, char inSide, _Bool move){
1922
1923 comment("LWire");
1924 unsigned char value = 7;
1925 if(move){
1926 wire(10,4,value,2,oppDir(inSide));
1927 shift(1,Dir);
1928 wire(10,4,value,2,oppDir(inSide));
1929 }
1930 else{
1931 wire(10,4,value,4,oppDir(inSide));
1932 }
1933 shift(4,inSide);
1934 comment("endLWire");
1935}
1936
1937void stairWire(char Dir, char up, char inSide, _Bool move){
1938 comment("stairWire");
1939 char* type = "wool";
1940 unsigned char value = 7;
1941 stairs(type,value,oppDir(inSide),up,2);
1942 if(move)
1943 shift(1,Dir);
1944 wire(10,4,value,2,oppDir(inSide));
1945 shift(4,inSide);
1946 shift(2,oppDir(up));
1947 comment("endstairWire");
1948}
1949
1950void build7segWires(char inSide,char stSide){
1951 comment("build7segWires");
1952
1953 //1
1954 LWire(oppDir(stSide),inSide,1);
1955 shift(1,oppDir(stSide));
1956 //2
1957 stairWire(oppDir(stSide),'u',inSide,1);
1958 shift(1,oppDir(stSide));
1959 //3
1960 stairWire(stSide,'d',inSide,1);
1961 shift(3,oppDir(stSide));
1962 //4
1963 LWire(stSide,inSide,1);
1964 shift(4,'u');
1965 //5
1966 LWire(stSide,inSide,0);
1967 shift(2,stSide);
1968 //6
1969 stairWire(stSide,'u',inSide,0);
1970 shift(2,stSide);
1971 //7
1972 LWire(stSide,inSide,0);
1973 //return to origin
1974 shift(1,stSide);
1975 comment("endbuild7segWires");
1976}
1977
1978
1979void buildOutput(unsigned char nibbles, char stSide, char backward){
1980 comment("buildOutput");
1981
1982 short inBits = 4;
1983 unsigned char outBits = 7;
1984 unsigned char significance[] = {8,4,2,1};
1985 unsigned char rows = 1;
1986 unsigned char collumns = 16;
1987
1988 for(unsigned char nibble = 0; nibble < nibbles; nibble++){
1989 buildDecoder(inBits,backward,stSide,rows,significance,nibble);
1990 buildEncoder(rows,collumns,segmentTable[0],inBits,outBits,stSide,oppDir(backward),backward);
1991
1992 char dataValue = (nibble / 2) % 16;
1993
1994 shift(49,backward);
1995 shift(8,'d');
1996 build7segLights("wool",dataValue,'l','f');
1997 if(nibble % 2 == 0 && nibble)
1998 seperateNibble("wool",7,oppDir(backward),stSide);
1999 build7segWires('f','l');
2000 shift(49,oppDir(backward));
2001 shift(4,'u');
2002
2003
2004 if(nibble != nibbles - 1)
2005 shift(inBits * 2,oppDir(stSide));
2006 }
2007 comment("endbuildOutput");
2008}
2009
2010struct bussLocation{
2011 //location of bit 0
2012 char direction; //the direction the buss is running
2013 char stSide;// the side of the most significant bit
2014};
2015
2016
2017struct buss{
2018 char* name;
2019 unsigned char* collors;
2020 unsigned char* strength;
2021 unsigned char width;
2022 struct bussLocation loc;
2023};
2024
2025void freeBuss(struct buss arg){
2026 printf("free(%s)\n",arg.name);
2027 // free(arg.name);
2028 free(arg.collors);
2029 free(arg.strength);
2030}
2031
2032struct buss buildStables(struct buss roundKey, char Dir,char stSide){
2033 comment("buildStables");
2034
2035 short inBits = 6;
2036 unsigned char outBits = 4;
2037 unsigned char significance[] = {32,8,4,2,1,16};
2038 unsigned char boxes = 8;
2039 unsigned char rows = 4;
2040 unsigned char collumns = 16;
2041
2042 struct buss ret;
2043 ret.width = outBits * boxes;
2044 ret.collors = malloc(ret.width);
2045 ret.strength = malloc(ret.width);
2046
2047 for(unsigned char box = 0; box < boxes; box++){
2048 buildDecoder(inBits,Dir,stSide,rows,significance,box);
2049 buildEncoder(rows,collumns,stables[box],inBits,outBits,stSide,oppDir(Dir),oppDir(Dir));
2050 for(int i = 0; i < outBits; i++){
2051 ret.collors[(box*outBits )+ i] = box % 16;
2052 }
2053 if(box != boxes - 1)
2054 shift(inBits * 2,oppDir(stSide));
2055 else{
2056 shift(((boxes - 1) * (inBits * 2) - 1),stSide);
2057 shift(4,'d');
2058 }
2059 }
2060
2061 //terminate key
2062 freeBuss(roundKey);
2063
2064
2065 ret.loc.direction = oppDir(Dir);
2066 ret.loc.stSide = stSide;
2067 ret.name = "Stable Results";
2068 comment("endbuildStables");
2069 return ret;
2070}
2071
2072void printBussInfo(struct buss arg,char* state){
2073 printf("BUSS INFO *********\n");
2074 printf("Buss :%12s \n",arg.name);
2075 printf("Width :%12i \n",arg.width);
2076 printf("Collors :");
2077 for(int i = 0; i < arg.width; i++){
2078 if(i % 8 == 0){
2079 printf("\n");
2080 }
2081 printf("%2i ",arg.collors[i]);
2082 }
2083 printf("\n");
2084 printf("Strength :");
2085 for(int i = 0; i < arg.width; i++){
2086 if(i % 8 == 0){
2087 printf("\n");
2088 }
2089 printf("%2i ",arg.strength[i]);
2090 }
2091 printf("\n");
2092 printf("State :%12s\n",state);
2093 printf("BUSS LOCATON ******\n");
2094 printf("Dir :%12c \n",arg.loc.direction);
2095 printf("stSide:%12c \n",arg.loc.stSide);
2096 printf("*******************\n");
2097 printf("\n");
2098}
2099
2100struct buss buildPermute(char* name,struct buss inBuss, unsigned char permTable[], unsigned char permLength, unsigned char groupSize, unsigned char groupSpacing, char forward, char stSide, char inSide,_Bool startAtIn, _Bool stayAtOut){
2101 comment("buildPermute");
2102 if(startAtIn){
2103 if(stSide == inSide){
2104 shift(2,'u');
2105 shift(2,oppDir(inSide));
2106 shift(2,oppDir(forward));
2107 }
2108 else{
2109 shift(2,'u');
2110 shift(permLength * 2,oppDir(inSide));
2111 shift(2,oppDir(forward));
2112 }
2113 }
2114
2115 struct buss outBuss;
2116 outBuss.width = permLength;
2117 outBuss.collors = malloc(permLength);
2118 outBuss.strength = malloc(permLength);
2119 outBuss.name = name;
2120 outBuss.loc.direction = oppDir(forward);
2121 outBuss.loc.stSide = stSide;
2122
2123 for(short i = 0; i < permLength; i++){
2124 unsigned char group = (permTable[i] - 1) / groupSize;
2125 unsigned char extLength = group * groupSpacing;
2126 unsigned char outLength = (permTable[i] * 2) + extLength;
2127 short inLength;
2128
2129 //wool collor for theis line
2130 char dataValueIn = inBuss.collors[permTable[i] - 1];
2131 unsigned char inStreangth = inBuss.strength[permTable[i] - 1];
2132
2133 unsigned char dataValueOut = i % 16;
2134 outBuss.collors[i] = dataValueOut;
2135
2136 //go to end
2137 shift(outLength,forward);
2138 //go down to bottom
2139 shift(2,'d');
2140
2141 //determin input length based on side
2142 if(stSide == inSide)
2143 inLength = (i + 1) * 2;
2144 else
2145 inLength = ((permLength - i)*2);
2146
2147 //shift to input
2148 shift(inLength,inSide);
2149
2150 //wire to input
2151 inStreangth = wire(inStreangth,4,dataValueIn,inLength,oppDir(inSide));
2152
2153 //where the busses meet
2154 stairs("redstone_Lamp",0,oppDir(forward),'u',2);
2155
2156 //wire to output
2157 inStreangth = wire(inStreangth,4,dataValueOut,outLength - 2,oppDir(forward));
2158
2159 //output reached record its strength
2160 outBuss.strength[i] = inStreangth;
2161
2162 //dont shift at the end
2163 if(i != permLength -1){
2164 shift(2,oppDir(stSide));
2165 }
2166 }
2167 shift((permLength -1) * 2,stSide);
2168
2169 if(!stayAtOut){
2170 if(stSide == inSide){
2171 shift(2,'d');
2172 shift(2,inSide);
2173 shift(2,forward);
2174 }
2175 else{
2176 shift(2,'d');
2177 shift(permLength * 2,inSide);
2178 shift(2,forward);
2179 }
2180 }
2181
2182 //old buss is terminated
2183 // freeBuss(inBuss);
2184
2185 comment("endbuildPermute");
2186 return outBuss;
2187}
2188
2189void breakout(unsigned char value,char outSide){
2190 comment("breakout");
2191
2192 //pack B
2193 struct block B;
2194 B.type = blockLookup("wool");
2195 B.value = value;
2196
2197 shift(1,outSide);
2198 setBlock(B,1);
2199 shift(1,'u');
2200 setRepeater(outSide);
2201 shift(5,'d');
2202 shift(1,oppDir(outSide));
2203 comment("endbreakout");
2204}
2205
2206void shiftBit(unsigned char value, char shiftDir, char outSide, unsigned char shift_amt){
2207 comment("shiftBit");
2208
2209 //pack B
2210 struct block B;
2211 B.type = blockLookup("wool");
2212 B.value = value;
2213
2214 setBlock(B,1);
2215 if(shift_amt == 1){
2216 shift(1,shiftDir);
2217 setredTorch(shiftDir);
2218 shift(1,'u');
2219 setBlock(B,1);
2220 shift(1,oppDir(shiftDir));
2221 setredTorch(oppDir(shiftDir));
2222 shift(1,'u');
2223 setBlock(B,1);
2224 }
2225 for(unsigned char i = 0; i < 2 * shift_amt; i++){
2226 if((i != (3 * shift_amt) - 1)){
2227 shift(1,shiftDir);
2228 setredTorch(shiftDir);
2229 shift(1,'u');
2230 setBlock(B,1);
2231 }
2232 }
2233 breakout(value,outSide);
2234 comment("endshiftBit");
2235}
2236
2237void cycleBit(char *type, unsigned char value,char shiftDir, char inSide, char outSide, unsigned char shift_amt, unsigned char shiftLength, unsigned char bitIndex){
2238
2239 //pack B
2240 struct block B;
2241 B.type = blockLookup("redstone_Lamp");
2242 B.value = 0;
2243
2244 comment("cycleBit");
2245 setBlock(B,1);
2246 shift(1,'d');
2247 unsigned char strength = 13;
2248 shift(1,oppDir(inSide));
2249 stairs(type,value,oppDir(inSide),'u',1);
2250 strength -= 1;
2251 strength = wire(strength,4,value,(bitIndex * 2),oppDir(inSide));
2252 stairs(type,value,oppDir(shiftDir),'u',2);
2253 strength -= 2;
2254 strength = wire(strength,2,value,(shiftLength * 2) - (3 + (shift_amt * 2) - 1),oppDir(shiftDir));
2255 strength = wire(strength,5,value,(bitIndex * 2),outSide);
2256 stairs(type,value,inSide,'u',1);
2257 strength -= 1;
2258 shift(1,'u');
2259 shift(1,outSide);
2260 setBlock(B,1);
2261 breakout(value,outSide);
2262 comment("endcycleBit");
2263}
2264
2265struct buss keyShiftSide(struct buss key,_Bool half,unsigned char shiftIndex){
2266 comment("keyShiftSide");
2267
2268 char Stside = key.loc.stSide;
2269 char outSide = oppDir(key.loc.direction);
2270 char inSide = outSide;
2271
2272 unsigned char shiftLength = PC1Length / 2;
2273 unsigned char shift_amt = keyshifts[shiftIndex]; //(1 or 2) but could be annything
2274
2275 unsigned char offset;
2276 if(half){
2277 offset = shiftLength;
2278 }
2279 else{
2280 offset = 0;
2281 }
2282
2283 struct buss temp;
2284 temp.collors = malloc(shift_amt);
2285 temp.strength = malloc(shift_amt);
2286
2287 for(unsigned char i = 0; i < shiftLength; i++){
2288 if(i < shift_amt){
2289 cycleBit("wool",key.collors[i + offset],Stside,inSide,outSide,shift_amt,shiftLength,i); //cycle bit to other side
2290 shift((shiftLength * 2) - (shift_amt * 2) - 2, Stside); //move selection back to this side
2291 short index = i + offset + shiftLength - shift_amt;
2292 temp.collors[i] = key.collors[index]; //save collor into temp for when i need it later (swap)
2293 key.collors[index] = key.collors[i + offset]; //get collor from other side
2294 key.strength[index] = 15;
2295 }
2296 else{
2297 short index = i + offset - shift_amt;
2298 shiftBit(key.collors[i + offset],Stside,outSide,shift_amt); //shift over by amount
2299 shift((shift_amt * 2) + 2, oppDir(Stside));
2300 if((i >= shiftLength - shift_amt)){ //get the collor from the the temp buss because this is actually a swap
2301 key.collors[index] = temp.collors[(i + shift_amt) - shiftLength];
2302 key.strength[index] = 15;
2303 }
2304 else{ //get the collor to the left
2305 key.collors[index] = key.collors[i + offset];
2306 key.strength[index] = 15;
2307 }
2308 }
2309 }
2310
2311 //get back to start at end of second shift
2312 if(half)
2313 shift((PC1Length) * 2,Stside);
2314
2315 comment("endkeyShiftSide");
2316 return key;
2317}
2318
2319struct buss Keyshift(struct buss key,unsigned char shiftIndex){
2320 comment("Keyshift");
2321 key = keyShiftSide(key,0,shiftIndex);
2322 key = keyShiftSide(key,1,shiftIndex);
2323 shift(4,'u');
2324 comment("endKeyshift");
2325 return key;
2326}
2327
2328struct buss setKeySchedual(){
2329 comment("setKeySchedual");
2330
2331 char PC1stSide = 'r';
2332 char PC1inSide = 'r';
2333 char PC1outSide = 'f';
2334
2335 char PC2stSide = 'b';
2336 char PC2inSide = 'b';
2337 char PC2outSide = 'l';
2338
2339 struct buss key;
2340 key.collors = malloc(64); //input key
2341 key.strength = malloc(64); //input key
2342
2343 for(int i = 0; i < 64; i++){
2344 key.collors[i] = i% 16;
2345 key.strength[i] = 10;
2346 }
2347
2348 struct buss PC1Results = buildPermute("PC1",key,PC1,PC1Length,1,0,PC1outSide,PC1stSide,PC1inSide,1,1);
2349
2350 shift(1,'u');
2351
2352 size_t num_shifts = sizeof(keyshifts) / sizeof(keyshifts[0]);
2353
2354 struct buss roundKey;
2355
2356 for(size_t i = 0; i < num_shifts; i++){
2357 roundKey = Keyshift(PC1Results,i);
2358 if(i != num_shifts - 1)
2359 buildPermute("PC2",roundKey,PC2,PC2Length,1,0,PC2outSide,PC2stSide,PC2inSide,1,0);
2360 else
2361 roundKey = buildPermute("PC2",roundKey,PC2,PC2Length,1,0,PC2outSide,PC2stSide,PC2inSide,1,1); //stay at end at end and only get the buss info at end
2362 }
2363 comment("endsetKeySchedual");
2364 return roundKey;
2365}
2366
2367//i have no idea what this value does all i know it is in RGB format
2368unsigned int KaLookup(unsigned char part){
2369 if(part == PartLookup("ice")) return 0x030303;
2370 else if(part == PartLookup("slime")) return 0x030303;
2371 else if(part == PartLookup("redstone_On")) return 0x505050;
2372 else return 0x000000;
2373}
2374
2375//i have no idea what this value does all i know it is in RGB format
2376unsigned int KsLookup(unsigned char part){
2377 if(part == PartLookup("ice")) return 0x030303;
2378 else if(part == PartLookup("slime")) return 0x030303;
2379 else return 0x000000;
2380}
2381
2382//i have no idea what this value does all i know it is in RGB format
2383unsigned int TfLookup(unsigned char part){
2384 if(part == PartLookup("ice")) return 0x030303;
2385 else if(part == PartLookup("slime")) return 0x030303;
2386 else return 0x000000;
2387}
2388
2389//illumination format 4 for transparrant materials
2390char illumLookup(unsigned char part){
2391 if(part == PartLookup("ice")) return 4;
2392 else if(part == PartLookup("slime")) return 4;
2393 else return 0;
2394}
2395
2396//how mutch the light is disolved while passing through transparrand material
2397float dLookup(unsigned char part){
2398 if(part == PartLookup("ice")) return .3;
2399 else if(part == PartLookup("slime")) return .6;
2400 else return 1;
2401}
2402
2403float NsLookup(unsigned char part){
2404 return .3;
2405}
2406
2407float sharpnessLookup(unsigned char part){
2408 return 60;
2409}
2410
2411float NiLookup(unsigned char part){
2412 return .7;
2413}
2414
2415void printMaterial(FILE * Mtl,unsigned char value,unsigned char part){
2416 unsigned int Ka = KaLookup(part);
2417 unsigned int Kd = collorLookup(value,part);
2418 unsigned int Ks = KsLookup(part);
2419 unsigned int Tf = TfLookup(part);
2420 char illum = illumLookup(part);
2421 float d = dLookup(part);
2422 float Ns = NsLookup(part);
2423 float sharpness = sharpnessLookup(part);
2424 float Ni = NiLookup(part);
2425
2426
2427 fprintf(Mtl,"\n############################\n\n");
2428 fprintf(Mtl,"newmtl %s:%i\n\n",reversePartLookup(part),value);
2429
2430 fprintf(Mtl,"# Collor Data #\n");
2431 fprintf(Mtl,"Ka %.4f %.4f %.4f \n",(float)(Ka & R)/R,(float)(Ka & G)/G,(float)(Ka & B)/B);
2432 fprintf(Mtl,"Kd %.4f %.4f %.4f \n",(float)(Kd & R)/R,(float)(Kd & G)/G,(float)(Kd & B)/B);
2433 fprintf(Mtl,"Ks %.4f %.4f %.4f \n",(float)(Ks & R)/R,(float)(Ks & G)/G,(float)(Ks & B)/B);
2434 fprintf(Mtl,"Tf %.4f %.4f %.4f \n",(float)(Tf & R)/R,(float)(Tf & G)/G,(float)(Tf & B)/B);
2435
2436 fprintf(Mtl,"# Reflection Data #\n");
2437 fprintf(Mtl,"illum %i\n",illum);
2438 fprintf(Mtl,"d %.1f\n",d);
2439 fprintf(Mtl,"Ns %.1f\n",Ns);
2440 fprintf(Mtl,"sharpness %.4f\n",sharpness);
2441 fprintf(Mtl,"Ni %.1f\n",Ni);
2442}
2443
2444void buildMaterialLibrary(){
2445
2446 FILE * Mtl = fopen("virtexMap.mtl","w");//file pointer
2447
2448 size_t numParts = sizeof(partTable) / sizeof(partTable[0]);
2449
2450 unsigned char woolID = PartLookup("wool");
2451 unsigned char woodID = PartLookup("wood");
2452
2453 for(int i = 0; i < 16; i++){
2454 printMaterial(Mtl,i,woolID);
2455 }
2456
2457 for(int i = 0; i < 4; i++){
2458 printMaterial(Mtl,i,woodID);
2459 }
2460
2461 for(size_t i = 0; i < numParts; i++){
2462 if(i != woolID && i != woodID){ //exclude these because we did them in a different for loop
2463 printMaterial(Mtl,0,i);
2464 }
2465 }
2466 fclose(Mtl);
2467}
2468
2469void showReferenceTable(unsigned char referenceTable[6][4],_Bool facePresent[6],_Bool schedualVirtex[8]){
2470 printf(" -- Ref Table --\n");
2471 for(int i = 0; i < 8; i++){
2472 printf("%i ",schedualVirtex[i]);
2473 }
2474 printf("\n");
2475 for(int i = 0; i < 6; i++){
2476 printf("%i ",facePresent[i]);
2477 }
2478 printf("\n");
2479 for(int i = 0; i < 6; i++){
2480 if(facePresent[i]){
2481 for(int j = 0; j < 4; j++){
2482 printf("%i",referenceTable[i][j] - 1);
2483 }
2484 printf("\n");
2485 }
2486 }
2487 printf("\n");
2488}
2489
2490void reflowTable(unsigned char referenceTable[6][4],_Bool facePresent[6],_Bool schedualVirtex[8]){
2491 _Bool change;
2492 // getchar();
2493 do {
2494 for(int k = 1; k < 8; k++){
2495 showReferenceTable(referenceTable,facePresent,schedualVirtex);
2496 getchar();
2497 change = 0;
2498 if(!schedualVirtex[k - 1] && schedualVirtex[k]){
2499 schedualVirtex[k - 1] = 1;
2500 schedualVirtex[k] = 0;
2501 for(int i = 0; i < 6; i++){
2502 if(facePresent[i]){
2503 for(int j = 0; j < 4; j++){
2504 if(referenceTable[i][j] - 1 == k)
2505 referenceTable[i][j]--;
2506 change = 1;
2507 }
2508 }
2509 }
2510 }
2511 }
2512 } while(change);
2513 showReferenceTable(referenceTable,facePresent,schedualVirtex);
2514}
2515
2516struct redShape{
2517 _Bool extend[8];
2518};
2519
2520struct redShape getRedStoneShape(short x, short z, short y){
2521
2522 char redType = blockLookup("redstone");
2523
2524 _Bool lastX = (x == mapW - 1);
2525 _Bool frstX = (x == 0);
2526 _Bool lastZ = (z == mapH - 1);
2527 _Bool frstZ = (z == 0);
2528 _Bool lastY = (y == mapD - 1);
2529 _Bool frstY = (y == 0);
2530
2531 _Bool L = !lastX && map[x+1][z][y].type != 0;
2532 _Bool R = !frstX && map[x-1][z][y].type != 0;
2533 _Bool B = !lastY && map[x][z][y+1].type != 0;
2534 _Bool F = !frstY && map[x][z][y-1].type != 0;
2535
2536 _Bool LU = !lastZ && !lastX && map[x+1][z+1][y].type == redType;
2537 _Bool RU = !lastZ && !frstX && map[x-1][z+1][y].type == redType;
2538 _Bool BU = !lastZ && !lastY && map[x][z+1][y+1].type == redType;
2539 _Bool FU = !lastZ && !frstY && map[x][z+1][y-1].type == redType;
2540
2541 _Bool LD = !lastX && !frstZ && map[x+1][z-1][y].type == redType;
2542 _Bool RD = !frstX && !frstZ && map[x-1][z-1][y].type == redType;
2543 _Bool BD = !frstZ && !lastY && map[x][z-1][y+1].type == redType;
2544 _Bool FD = !frstZ && !frstY && map[x][z-1][y-1].type == redType;
2545
2546 struct redShape ret;
2547
2548 ret.extend[0] = (L || (!L && LD));
2549 ret.extend[1] = (R || (!R && RD));
2550 ret.extend[2] = (B || (!B && BD));
2551 ret.extend[3] = (F || (!F && FD));
2552
2553 ret.extend[4] = LU;
2554 ret.extend[5] = RU;
2555 ret.extend[6] = BU;
2556 ret.extend[7] = FU;
2557
2558 return ret;
2559}
2560
2561_Bool smallBlock(char type){
2562 _Bool small = (type == 0 || type == blockLookup("redstone") || type == blockLookup("redstone_repeater") || type == blockLookup("redstone_torch") || type == blockLookup("ice"));
2563 return small;
2564}
2565
2566struct subVoxel{
2567 //weather or not the subVoxel exists entierly
2568 _Bool exist;
2569 //demention modifyers
2570 //L R F B U D
2571 float D_mod[6];
2572 //what faces are present
2573 _Bool faces[6];
2574};
2575
2576struct subVoxelPack{
2577 //each sub subVoxel
2578 struct subVoxel* voxs;
2579 //number of subsubVoxels
2580 unsigned char num_vox;
2581};
2582
2583unsigned char numerateDir(char Dir){
2584 switch(Dir){
2585 case 'l': return 0;
2586 case 'r': return 1;
2587 case 'f': return 2;
2588 case 'b': return 3;
2589 case 'u': return 4;
2590 case 'd': return 5;
2591 default : printf("numerateDir() - Invalid Direction recieved :%c > %i\n",Dir,Dir);
2592 }
2593 return 0;
2594}
2595
2596struct subVoxelPack getsubVoxels(short x, short z, short y){
2597
2598 unsigned char type = map[x][z][y].type;
2599 char Dir = map[x][z][y].relDir;
2600
2601 char adjacent[6];
2602
2603 adjacent[0] = (x == mapW - 1? 0 : map[x + 1][z][y].type);
2604 adjacent[1] = (x == 0? 0 : map[x - 1][z][y].type);
2605 adjacent[2] = (y == mapD - 1? 0 : map[x][z][y + 1].type);
2606 adjacent[3] = (y == 0? 0 : map[x][z][y - 1].type);
2607 adjacent[4] = (z == mapH - 1? 0 : map[x][z + 1][y].type);
2608 adjacent[5] = (z == 0? 0 : map[x][z - 1][y].type);
2609
2610 struct subVoxelPack ret;
2611
2612 //allocate memory and record number of voxels posible
2613 size_t num_vox = partCount(type);
2614 ret.num_vox = num_vox;
2615 ret.voxs = malloc(num_vox * sizeof(struct subVoxel));
2616
2617 for(int i = 0; i < 6; i++){
2618 //full cube
2619 ret.voxs[0].D_mod[i] = .5;
2620 }
2621
2622 if(type == blockLookup("sticky_piston")){
2623
2624 unsigned char N_RD = numerateDir(oppDir(Dir));
2625 unsigned char N_D = numerateDir(Dir);
2626
2627 //they all exist (this is only really usefull for redstone...)
2628 ret.voxs[0].exist = 1;
2629 ret.voxs[1].exist = 1;
2630 ret.voxs[2].exist = 1;
2631
2632 float H_depth = 0.3; //head thickness
2633 float N_depth = -(.5 - H_depth); //negitive thickness
2634 float B_depth = .5 - H_depth; //base thickness
2635 float S_Depth = .05; //slime thickness
2636 float SN_depth = N_depth - .2;
2637
2638 for(int i = 0; i < 6; i++){
2639 //default depth untill direction is considerered
2640 ret.voxs[2].D_mod[i] = .5 + S_Depth;
2641 ret.voxs[1].D_mod[i] = .5;
2642 //remove faces adjacent to big blocks
2643 ret.voxs[0].faces[i] = smallBlock(adjacent[i]);
2644 ret.voxs[1].faces[i] = smallBlock(adjacent[i]);
2645 ret.voxs[2].faces[i] = 1;
2646 }
2647
2648 //boi do i love refactoring this is a lot better than a huge switch statement with tons of different indexes
2649 //DIMENTIONS
2650 ret.voxs[0].D_mod[N_D] = B_depth;
2651 ret.voxs[1].D_mod[N_RD] = N_depth;
2652 ret.voxs[2].D_mod[N_RD] = SN_depth;
2653 //FACES
2654 ret.voxs[0].faces[N_D] = 0;
2655 ret.voxs[1].faces[N_RD] = 0;
2656 }
2657
2658 //a bunch of if then logic to set up possible transforms
2659 if(type == blockLookup("redstone")){
2660 float height = 0.2;
2661 float depth = .5 - height;
2662 float negHeight = -(.5 - height);
2663
2664 struct redShape redShape;
2665 redShape = getRedStoneShape(x,z,y);
2666 ret.voxs[0].D_mod[4] = negHeight;
2667 ret.voxs[0].exist = 1;
2668 for(int i = 0; i < 6; i++){
2669 ret.voxs[0].faces[5] = smallBlock(adjacent[5]);
2670 ret.voxs[0].faces[4] = 1;
2671 ret.voxs[0].faces[i] = (i != 5 && i != 4 && !redShape.extend[i]);
2672
2673 if(i != 5 && i != 4){
2674 ret.voxs[0].D_mod[i] = depth;
2675 }
2676 }
2677 for(size_t i = 1; i < num_vox; i++){
2678 ret.voxs[i].exist = redShape.extend[(i - 1) % 5];
2679 if(ret.voxs[i].exist){
2680 ret.voxs[i].faces[5] = smallBlock(adjacent[5]);
2681 ret.voxs[i].faces[4] = 1;
2682 ret.voxs[i].D_mod[5] = .5;
2683 for(int j = 0; j < 4; j++){
2684 ret.voxs[i].faces[j] = 1;
2685 ret.voxs[i].D_mod[j] = depth;
2686 }
2687
2688 if(redShape.extend[i + 3]){
2689 ret.voxs[i].D_mod[4] = .5 + height;
2690 ret.voxs[i].faces[i - 1] = 0;
2691 }
2692 else{
2693 ret.voxs[i].D_mod[4] = negHeight;
2694 ret.voxs[i].faces[i - 1] = 0;
2695 }
2696
2697 ret.voxs[i].D_mod[i-1] = .5;
2698
2699 switch(i - 1){
2700 case 0: ret.voxs[i].D_mod[1] = negHeight; ret.voxs[i].faces[1] = redShape.extend[i + 3]; break;
2701 case 1: ret.voxs[i].D_mod[0] = negHeight; ret.voxs[i].faces[0] = redShape.extend[i + 3]; break;
2702 case 2: ret.voxs[i].D_mod[3] = negHeight; ret.voxs[i].faces[3] = redShape.extend[i + 3]; break;
2703 case 3: ret.voxs[i].D_mod[2] = negHeight; ret.voxs[i].faces[2] = redShape.extend[i + 3]; break;
2704 }
2705 }
2706 }
2707 }
2708
2709 else if(type == blockLookup("slab")){
2710 ret.voxs[0].D_mod[5] = 0; //how far up from
2711 }
2712
2713 else if(type == blockLookup("redstone_torch")){
2714
2715 unsigned char N_RD = numerateDir(oppDir(Dir));
2716 unsigned char N_D = numerateDir(Dir);
2717
2718 //both voxels always exist
2719 ret.voxs[0].exist = 1;
2720 ret.voxs[1].exist = 1;
2721
2722 //defaults untill shifted
2723 for(int i = 0; i < 6; i++){
2724 //handle
2725 ret.voxs[0].D_mod[i] = .15;
2726 //head
2727 ret.voxs[1].D_mod[i] = .2; //slightly thiccer
2728 //all faces present by default undill direction is considered
2729 ret.voxs[1].faces[i] = 1;
2730 ret.voxs[0].faces[i] = 1;
2731 }
2732
2733 //extend base of handle twards connecting block
2734 //shift head over a bit awway from connecting block moves .1 tward Dir
2735
2736 //DIMENTIONS
2737 ret.voxs[0].D_mod[N_RD] = .5;
2738 ret.voxs[1].D_mod[N_RD] = .1;
2739 ret.voxs[1].D_mod[N_D] = .3;
2740 //FACES
2741 ret.voxs[0].faces[N_D] = 0;
2742 ret.voxs[0].faces[N_RD] = 0;
2743 }
2744
2745 //"redstone_repeater","redstone_Tile","redstone_Off","generic_Wood","redstone_Off"},
2746 else if(type == blockLookup("redstone_repeater")){
2747
2748 unsigned char N_RD = numerateDir(oppDir(Dir));
2749 unsigned char N_D = numerateDir(Dir);
2750
2751 ret.voxs[0].exist = 1;
2752 ret.voxs[1].exist = 1;
2753 ret.voxs[2].exist = 1;
2754 ret.voxs[3].exist = 0;
2755
2756 for(int i = 0; i < 6; i++){
2757 //all true, unless i is 5 and the block below isnt small (or air)
2758 ret.voxs[0].faces[i] = !(i == 5 && !smallBlock(adjacent[5]));
2759 ret.voxs[1].faces[i] = 1;
2760 ret.voxs[2].faces[i] = 1;
2761
2762 ret.voxs[1].D_mod[i] = .12;
2763 ret.voxs[2].D_mod[i] = .1;
2764 }
2765
2766 //DIMENTIONS
2767 ret.voxs[0].D_mod[4] = -.2;
2768 ret.voxs[1].D_mod[4] = -.15;
2769 ret.voxs[1].D_mod[5] = .2;
2770 ret.voxs[1].D_mod[N_RD] = .4;
2771 ret.voxs[1].D_mod[N_D] = .1;
2772
2773 //FACES
2774 ret.voxs[1].faces[5] = 0;
2775 }
2776
2777 else if(type == blockLookup("ice")){
2778 ret.voxs[0].exist = 1;
2779 for(int i = 0; i < 6; i++){
2780 //only true if the adjacent block is small
2781 ret.voxs[0].faces[i] = adjacent[i] == 0;
2782 }
2783 }
2784
2785 else{
2786 ret.voxs[0].exist = 1;
2787 for(int i = 0; i < 6; i++){
2788 //only place face if adjacent side is small or if the block above is a repeater
2789 ret.voxs[0].faces[i] = smallBlock(adjacent[i]) && !(i == 4 && adjacent[4] == blockLookup("redstone_repeater")); //this is nice
2790 }
2791 }
2792 return ret;
2793}
2794
2795struct virtex{
2796 float x;
2797 float z;
2798 float y;
2799};
2800
2801void printFaceQuad(FILE * Obj,unsigned char v_index[4], int vc){
2802 fprintf(Obj,"f %i %i %i %i\n",v_index[0] + vc,v_index[1] + vc,v_index[2] + vc,v_index[3] + vc);
2803}
2804
2805void printVirtex(FILE * Obj,struct virtex v){
2806 fprintf(Obj,"v %.2f %.2f %.2f\n",v.x,v.z,v.y);
2807}
2808
2809void printsubVoxel(FILE * Obj, struct subVoxel vox, int vc, short x, short z, short y){
2810
2811 //virtex map to blace a cuboid
2812 _Bool vMap[8][3] = {
2813 {1,0,0},
2814 {0,0,0},
2815 {0,0,1},
2816 {1,0,1},
2817 {1,1,0},
2818 {1,1,1},
2819 {0,1,1},
2820 {0,1,0},
2821 };
2822
2823 struct virtex v[8];
2824
2825 //apply transform
2826 for(int i = 0; i < 8; i++){
2827 if(vMap[i][0]) v[i].x = x + vox.D_mod[0];
2828 else v[i].x = x - vox.D_mod[1];
2829 if(vMap[i][2]) v[i].y = y + vox.D_mod[2];
2830 else v[i].y = y - vox.D_mod[3];
2831 if(vMap[i][1]) v[i].z = z + vox.D_mod[4];
2832 else v[i].z = z - vox.D_mod[5];
2833 }
2834
2835 for(int i = 0; i < 8; i++){
2836 printVirtex(Obj,v[i]);
2837 }
2838
2839 unsigned char referenceTable[6][4] = {
2840 {6,4,1,5}, //left
2841 {8,2,3,7}, //right
2842 {7,3,4,6}, //front
2843 {5,1,2,8}, //back
2844 {5,8,7,6}, //top
2845 {1,4,3,2}, //bottom
2846 };
2847
2848 //refectored aww yeee :D
2849 for( int i = 0; i < 6; i++){
2850 if(vox.faces[i]){
2851 printFaceQuad(Obj,referenceTable[i],vc - 8);
2852 }
2853 }
2854}
2855
2856//create .obj file from bock map
2857void buildWaveFront(){
2858 FILE * Obj = fopen("virtexMap.obj","w");//file pointer
2859
2860 fprintf(Obj,"mtllib virtexMap.mtl\n");
2861
2862 int vc = 0;//virtex count
2863
2864 for(short x = 0; x < mapW; x++){
2865 for(short z = 0; z < mapH; z++){
2866 for(short y = 0; y < mapD; y++){
2867 if(map[x][z][y].type != 0){
2868 char type = map[x][z][y].type;
2869 unsigned char data = map[x][z][y].value;
2870
2871 struct subVoxelPack voxPack;
2872
2873 voxPack = getsubVoxels(x,z,y);
2874
2875 for(int i = 0; i < voxPack.num_vox; i++){
2876 if(voxPack.voxs[i].exist){
2877 //these blocks have different materials based on the datavalue
2878 fprintf(Obj,"usemtl ");
2879 if(type == blockLookup("wool") || type == blockLookup("wood"))
2880 fprintf(Obj,"%s:%i\n",getPartnameForBlock(type,i),data);
2881 //the rest are just 0
2882 else fprintf(Obj,"%s:0\n",getPartnameForBlock(type,i));
2883 vc += 8; //current count of all virtexes
2884 printsubVoxel(Obj,voxPack.voxs[i],vc,x,z,y);
2885 }
2886 }
2887 free(voxPack.voxs);
2888 }
2889 }
2890 }
2891 }
2892 fclose(Obj); //close file pointer
2893}
2894
2895struct buss bussStraight(struct buss arg, short distance){
2896 comment("bussStraight");
2897 unsigned char width = arg.width;
2898 char bussDir = arg.loc.direction;
2899 for(unsigned char i = 0; i < width; i++){
2900 arg.strength[i] = wire(arg.strength[i],5,arg.collors[i],distance,bussDir);
2901 if(i != width - 1){
2902 shift(2,oppDir(arg.loc.stSide));
2903 shift(distance,oppDir(bussDir));
2904 }
2905 }
2906 shift((width - 1) * 2,arg.loc.stSide);
2907 comment("endbussStraight");
2908 return arg;
2909}
2910
2911void tower2(unsigned char value,unsigned char levels){
2912
2913 //pack B
2914 struct block B;
2915 B.type = blockLookup("wool");
2916 B.value = value;
2917
2918 comment("tower2");
2919 setBlock(B,1);
2920 shift(1,'u');
2921 setredTorch('u');
2922 expand(1,'d');
2923 stack(levels,'u',"s");
2924 replace("redstone_torch",0,0,"redstone",1,0);
2925 contract(1,'d');
2926 comment("endtower2");
2927}
2928
2929struct buss bussUp(_Bool type, struct buss arg, short distance, char up, _Bool flip){
2930 comment("bussUp");
2931
2932 if(flip){
2933 arg.loc.direction = oppDir(arg.loc.direction);
2934 }
2935
2936 char Dir = arg.loc.direction;
2937
2938
2939 unsigned char width = arg.width;
2940 for(unsigned char i = 0; i < width; i++){
2941
2942 //pack B
2943 struct block B;
2944 B.type = blockLookup("wool");
2945 B.value = arg.collors[i+1];
2946
2947 if(type){
2948 if(i == 0){
2949 tower(distance,up,arg.collors[0]);
2950
2951 flipFlop(Dir);
2952
2953 expand(distance - 2,oppDir(up));
2954 expand(1,oppDir(arg.loc.stSide));
2955
2956 if(up == 'd'){
2957 shift(3,oppDir(Dir));
2958 shift(2,'u');
2959 stack(arg.width - 1,oppDir(arg.loc.stSide),"");
2960 }
2961 else{
2962 expand(2,'d');
2963 shift(3,oppDir(Dir));
2964 stack(arg.width - 1,oppDir(arg.loc.stSide),"");
2965 contract(2,'u');
2966 }
2967
2968 shift(1,up);
2969 contract(distance - 2,up);
2970 expand(2,Dir);
2971 stack(arg.width - 1,oppDir(arg.loc.stSide),"");
2972 contract(2,oppDir(Dir));
2973 contract(1,arg.loc.stSide);
2974 }
2975 if(i != width - 1){
2976 shift(2,oppDir(arg.loc.stSide));
2977 setBlock(B,1);
2978 }
2979 else{
2980 shift(1,'d');
2981 shift(3,Dir);
2982 }
2983 arg.strength[i] = 14;
2984 }
2985 else{
2986 tower2(arg.collors[i],distance / 2);
2987 if(i != width - 1){
2988 shift(distance,oppDir(up));
2989 shift(2,oppDir(arg.loc.stSide));
2990 }
2991 }
2992 }
2993 shift((width - 1) * 2,arg.loc.stSide);
2994 comment("endbussUp");
2995 return arg;
2996}
2997
2998struct buss bussStairs(struct buss arg, short distance, char up){
2999 comment("bussStairs");
3000 char Dir = arg.loc.direction;
3001 unsigned char width = arg.width;
3002 for(unsigned char i = 0; i < width; i++){
3003 stairs("wool",arg.collors[i],Dir,up,distance);
3004 if(i != width - 1){
3005 shift(2,oppDir(arg.loc.stSide));
3006 shift(distance,oppDir(up));
3007 shift(distance,oppDir(Dir));
3008 }
3009 }
3010 shift((width - 1) * 2,arg.loc.stSide);
3011 comment("endbussStairs");
3012 return arg;
3013}
3014
3015struct buss createTestBuss(char* name,unsigned char width,char direction, char stSide){
3016 struct buss ret;
3017 ret.name = name;
3018 ret.width = width;
3019 ret.collors = malloc(width);
3020 ret.strength = malloc(width);
3021 ret.loc.stSide = stSide;
3022 ret.loc.direction = direction;
3023 for(int i = 0; i < width; i++){
3024 ret.strength[i] = 3;
3025 ret.collors[i] = i % 16;
3026 }
3027 return ret;
3028}
3029
3030void freeBlockMap(){
3031 printf("free W%i D%i H%i %lu \n",mapW,mapD,mapH,mapW*mapD*mapH * sizeof(struct block));
3032 for(short i = 0; i < mapW; i++){
3033 for(short j = 0; j < mapH; j++){
3034 free(map[i][j]);
3035 }
3036 free(map[i]);
3037 }
3038 free(map);
3039 printf("free(bMap.map);\n");
3040}
3041
3042void bitXOR1(char Dir){
3043
3044 //pack B1
3045 struct block B1;
3046 B1.type = blockLookup("wool");
3047 B1.value = 5;
3048
3049 //pack B2
3050 struct block B2;
3051 B2.type = blockLookup("wool");
3052 B2.value = 4;
3053
3054 comment("bitXOR1");
3055 setBlock(B1,1);
3056 shift(1,'u');
3057 setRepeater(Dir);
3058 shift(2,'d');
3059 shift(1,Dir);
3060 setBlock(B2,1);
3061 overlay("redstone",0);
3062 shift(2,'u');
3063 setBlock(B1,1);
3064 overlay("redstone",0);
3065 shift(1,Dir);
3066 shift(1,'u');
3067 setBlock(B1,1);
3068 shift(1,Dir);
3069 setredTorch(Dir);
3070 expand(1,oppDir(Dir));
3071 expand(1,'d');
3072 stack(1,'d',"s");
3073 contract(1,oppDir(Dir));
3074 contract(1,'u');
3075 shift(1,'u');
3076 setredTorch('u');
3077 shift(3,'d');
3078 wire(14,1,4,1,Dir);
3079 shift(1,Dir);
3080 shift(1,'u');
3081 setBlock(B2,1);
3082 shift(1,'u');
3083 setredTorch('u');
3084 shift(1,'u');
3085 setBlock(B1,1);
3086 overlay("redstone",0);
3087 comment("endbitXOR1");
3088}
3089
3090void bitXOR2(char Dir){
3091
3092 //pack B1
3093 struct block B1;
3094 B1.type = blockLookup("wool");
3095 B1.value = 5;
3096
3097 //pack B2
3098 struct block B2;
3099 B2.type = blockLookup("wool");
3100 B2.value = 4;
3101
3102 comment("bitXOR2");
3103 shift(1,Dir);
3104 shift(1,'u');
3105 setBlock(B2,1);
3106 expand(1,'u');
3107 stack(1,'u',"");
3108 shift(1,'u');
3109 stack(1,'u',"");
3110 shift(1,'d');
3111 shift(1,Dir);
3112 contract(1,'u');
3113 setBlock(B1,1);
3114 expand(1,'d');
3115 stack(1,'u',"");
3116 expand(1,oppDir(Dir));
3117 expand(3,'u');
3118 stack(1,Dir,"");
3119 shift(1,Dir);
3120 stack(2,Dir,"");
3121 shift(1,oppDir(Dir));
3122 contract(3,'d');
3123 contract(1,'u');
3124 contract(1,oppDir(Dir));
3125 setredTorch(oppDir(Dir));
3126 shift(2,'u');
3127 setredTorch(oppDir(Dir));
3128 shift(1,'u');
3129 shift(1,Dir);
3130 setRepeater(Dir);
3131 shift(2,'d');
3132 setredTorch(Dir);
3133 shift(2,'d');
3134 setredTorch(Dir);
3135 shift(1,'u');
3136 shift(1,Dir);
3137 setRepeater(Dir);
3138 shift(2,'u');
3139 setRepeater(oppDir(Dir));
3140 shift(1,'u');
3141 shift(1,Dir);
3142 setRepeater(Dir);
3143 shift(2,'d');
3144 setredTorch('u');
3145 shift(1,'u');
3146 shift(1,Dir);
3147 setRepeater(Dir);
3148 shift(2,'d');
3149 setRepeater(oppDir(Dir));
3150 shift(1,'u');
3151 shift(1,Dir);
3152 setredTorch(oppDir(Dir));
3153 shift(2,'d');
3154 setredTorch(oppDir(Dir));
3155 shift(4,'u');
3156 setRepeater(Dir);
3157 shift(1,Dir);
3158 comment("endbitXOR2");
3159}
3160
3161struct buss XOR(_Bool XORType,struct buss inBitsA, struct buss inBitsB){
3162 comment("XOR");
3163 unsigned char width = inBitsA.width;
3164 char stSide = inBitsA.loc.stSide;
3165 char Dir = inBitsA.loc.direction;
3166
3167 if(width != inBitsB.width){
3168 printf("*** Warning Unequal Buss Size XOR1 ***\n");
3169 printf("%s XOR %s\n",inBitsA.name,inBitsB.name);
3170 }
3171
3172 if((XORType && inBitsA.loc.direction != inBitsB.loc.direction) || (!XORType && inBitsA.loc.direction != oppDir(inBitsB.loc.direction))){
3173 printf("*** Warning BussDirection missmatch ***\n");
3174 printf("%s XOR %s\n",inBitsA.name,inBitsB.name);
3175 }
3176
3177 if(XORType){
3178 bitXOR1(Dir);
3179 expand(4,oppDir(Dir));
3180 expand(1,'u');
3181 expand(3,'d');
3182 expand(1,oppDir(stSide));
3183 stack(width - 1,oppDir(stSide),"");
3184 contract(1,stSide);
3185 contract(4,Dir);
3186 contract(1,'d');
3187 contract(3,'u');
3188 }
3189 else{
3190 bitXOR2(Dir);
3191 expand(6,oppDir(Dir));
3192 expand(4,'d');
3193 expand(1,oppDir(stSide));
3194 stack(width - 1,oppDir(stSide),"");
3195 contract(1,stSide);
3196 contract(6,Dir);
3197 contract(4,'u');
3198 }
3199 freeBuss(inBitsB);
3200
3201 comment("endXOR");
3202 return inBitsA; //more modifacations to A may be needed (new collors?)
3203}
3204
3205struct buss* allocateBlock(){
3206 struct buss* Block = malloc(2 * sizeof(struct buss));
3207 Block[0].name = "left_Block";
3208 Block[0].loc.direction = 'b';
3209 Block[1].name = "Right_Block";
3210 Block[1].loc.direction = 'f';
3211 for(unsigned char H = 0; H < 2; H++){ //both halves
3212 Block[H].width = PLength;
3213 Block[H].loc.stSide = 'l';
3214 Block[H].collors = malloc(PLength);
3215 Block[H].strength = malloc(PLength);
3216 Block[H].collors = malloc(PLength);
3217 Block[H].strength = malloc(PLength);
3218 for(int i = 0; i < PLength; i++){
3219 Block[H].collors[i] = i % 16;
3220 Block[H].strength[i] = 10;
3221 }
3222 }
3223 return Block;
3224}
3225
3226struct buss turnBuss(struct buss arg, char direction,_Bool flip, unsigned char depth){
3227 comment("turnBuss");
3228 char oldDir = arg.loc.direction;
3229 char newDir = turnDir(oldDir,direction);
3230
3231 short width = arg.width;
3232
3233 for(int i = 0; i < width; i++){
3234 if(flip){
3235 if(arg.loc.stSide == newDir){
3236 arg.strength[i] = wire(arg.strength[i],1,arg.collors[i],((width - 1) - i) * 2,oldDir);
3237 tower(depth,'d',arg.collors[i]);
3238 arg.strength[i] = wire(16,1,arg.collors[i],i * 2,newDir);
3239 if(i != width -1){
3240 shift(((width - 1) - i) * 2,oppDir(oldDir));
3241 shift(i * 2,oppDir(newDir));
3242 shift(2,oppDir(newDir));
3243 shift(depth,'u');
3244 }
3245 }
3246 else{
3247 arg.strength[i] = wire(arg.strength[i],1,arg.collors[i],i * 2,oldDir);
3248 tower(depth,'d',arg.collors[i]);
3249 arg.strength[i] = wire(16,1,arg.collors[i],((width - 1) - i) * 2,newDir);
3250 if(i != width -1){
3251 shift(i * 2,oppDir(oldDir));
3252 shift(((width - 1) - i) * 2,oppDir(newDir));
3253 shift(2,newDir);
3254 shift(depth,'u');
3255 }
3256 }
3257 }
3258 else{
3259 if(arg.loc.stSide == newDir){
3260 arg.strength[i] = wire(arg.strength[i],1,arg.collors[i],i * 2,oldDir);
3261 arg.strength[i] = wire(arg.strength[i],1,arg.collors[i],i * 2,newDir);
3262 if(i != width -1){
3263 shift(i * 2,oppDir(oldDir));
3264 shift(i * 2,oppDir(newDir));
3265 shift(2,oppDir(newDir));
3266 }
3267 }
3268 else{
3269 arg.strength[i] = wire(arg.strength[i],1,arg.collors[i],((width - 1) - i) * 2,oldDir);
3270 arg.strength[i] = wire(arg.strength[i],1,arg.collors[i],((width - 1) - i) * 2,newDir);
3271 if(i != width -1){
3272 shift(((width - 1) - i) * 2,oppDir(oldDir));
3273 shift(((width - 1) - i) * 2,oppDir(newDir));
3274 shift(2,newDir);
3275 }
3276 }
3277 }
3278 }
3279 if(!flip){
3280 if(arg.loc.stSide != newDir){
3281 shift((width - 1) * 2,oldDir);
3282 }
3283 else{
3284 shift((width - 1) * 2,oppDir(oldDir));
3285 }
3286 }
3287 else{
3288 if(arg.loc.stSide != newDir){
3289 shift((width - 1) * 2,oppDir(oldDir));
3290 }
3291 else{
3292 shift((width - 1) * 2,oldDir);
3293 }
3294 arg.loc.stSide = oppDir(arg.loc.stSide);
3295
3296 }
3297 arg.loc.direction = newDir;
3298 arg.loc.stSide = turnDir(arg.loc.stSide,direction);
3299 comment("endturnBuss");
3300 return arg;
3301}
3302
3303struct buss bussFlipFlop(struct buss arg){
3304 flipFlop(arg.loc.direction);
3305 shift(1,'u');
3306 shift(1,oppDir(arg.loc.direction));
3307 expand(1,oppDir(arg.loc.direction));
3308 expand(1,oppDir(arg.loc.stSide));
3309 stack(arg.width - 1,oppDir(arg.loc.stSide),"");
3310 contract(1,arg.loc.stSide);
3311 shift(1,arg.loc.direction);
3312 contract(1,arg.loc.direction);
3313 shift(1,'d');
3314 for(short i = 0; i < arg.width; i++){
3315 arg.strength[i] = 15;
3316 }
3317 return arg;
3318}
3319
3320struct buss halfSwapSides(struct buss inBuss,short amount,char Dir){
3321 comment("halfSwapSides");
3322
3323 short bits = inBuss.width;
3324
3325 for(short i = 0; i < 4; i++){
3326
3327 struct buss subBuss;
3328 subBuss.width = bits/4;
3329 subBuss.collors = malloc(subBuss.width);
3330 subBuss.strength = malloc(subBuss.width);
3331 subBuss.name = "Bit_Shift_Sub_Buss";
3332 subBuss.loc.stSide = inBuss.loc.stSide;
3333 subBuss.loc.direction = inBuss.loc.direction;
3334
3335 for(short j = 0; j < bits/4; j++){
3336 subBuss.collors[j] = inBuss.collors[(i * bits/4) + j];
3337 subBuss.strength[j] = inBuss.strength[(i * bits/4) + j];
3338 }
3339
3340 if(i != 3){
3341 subBuss = bussStraight(subBuss,3);
3342 subBuss = turnBuss(subBuss,Dir,1,6 - (i * 2));
3343 }
3344 else{
3345 subBuss = bussUp(1,subBuss,2,'u',0);
3346 subBuss = turnBuss(subBuss,Dir,1,2);
3347 }
3348
3349 subBuss = bussStraight(subBuss,(((amount - 2) - (bits/4 - 1)) * 2) + 4);
3350 char shiftDir = oppDir(subBuss.loc.direction);
3351
3352 subBuss = turnBuss(subBuss,Dir,0,0); //direction not used
3353 subBuss = bussStraight(subBuss,2);
3354
3355 if(i != 3){
3356 subBuss = bussUp(1,subBuss,6 - (i * 2),'u',0);
3357 shift(1,subBuss.loc.direction);
3358 subBuss = bussStraight(subBuss,1);
3359 }
3360 else{
3361 subBuss = bussFlipFlop(subBuss);
3362 printBussInfo(subBuss,"afterFlip");
3363 shift(1,subBuss.loc.direction);
3364 subBuss = bussStraight(subBuss,1);
3365 }
3366 if(i != 3){
3367 shift(4,oppDir(subBuss.loc.direction));
3368 }
3369 shift((((amount - 2) - (bits/4 - 1)) * 2) + 2,shiftDir);
3370
3371 for(short j = 0; j < bits/4; j++){
3372 inBuss.collors[(i * bits/4) + j] = subBuss.collors[j];
3373 inBuss.strength[(i * bits/4) + j] = subBuss.strength[j];
3374 }
3375
3376 }
3377 inBuss.loc.direction = oppDir(inBuss.loc.direction);
3378 comment("endhalfSwapSides");
3379 return inBuss;
3380}
3381
3382struct buss* buildRound(struct buss roundKey, struct buss* block){
3383 comment("buildRound");
3384
3385 char roundDir = roundKey.loc.direction;
3386 char roundStSide = roundKey.loc.stSide;
3387 bussUp(1,roundKey,4,'d',0);
3388 shift(1,'d');
3389 bussStraight(roundKey,0);
3390 shift(5,'u');
3391 shift(8,roundDir);
3392 bussStraight(roundKey,(PLength * 2) + 1);
3393 struct buss sBoxResults = buildStables(roundKey,roundDir,roundStSide);
3394 struct buss PResults = buildPermute("P_Results",sBoxResults,P,PLength,4,4,'f',oppDir(roundDir),roundDir,1,1);
3395 shift(6,'d');
3396 shift(1,'b');
3397 shift(((PLength * 2)),roundDir);
3398 struct buss EResults = buildPermute("E_Results",block[1],E,ELength,1,0,roundDir,'b','b',1,1);
3399 bussStraight(EResults,(PLength * 2) - 1);
3400 shift(1,'u');
3401 shift(8,oppDir(roundDir));
3402 XOR(0,roundKey,EResults);
3403 shift(8,'d');
3404 shift(2,roundDir);
3405 shift(3,'b');
3406 bussUp(0,block[0],4,'u',0);
3407 shift(1,'u');
3408 shift(1,'f');
3409 block[0] = XOR(1,block[0],PResults);
3410 block[0] = bussStraight(block[0],1);
3411 block[0] = halfSwapSides(block[0],PLength,oppDir(roundDir));
3412 block[1] = bussUp(0,block[1],8,'u',0);
3413 shift(14,'d');
3414 block[1] = bussStraight(block[1],(roundKey.width * 2) + 4);
3415 block[1] = bussUp(1,block[1],6,'u',0);
3416 shift(roundKey.width, roundDir);
3417 block[1] = halfSwapSides(block[1],PLength,oppDir(roundDir));
3418 shift(roundKey.width,oppDir(roundDir));
3419 block[1] = bussUp(0,block[1],4,'u',0);
3420 block[1] = bussStraight(block[1],(roundKey.width * 2) + 3);
3421 block[1] = bussUp(0,block[1],4,'u',0);
3422 comment("endbuildRound");
3423 return block;
3424}
3425
3426struct buss* bussTap(struct buss arg,char direction){
3427
3428 //pack B
3429 struct block B;
3430 B.type = blockLookup("redstone_Lamp");
3431 B.value = 0;
3432
3433 comment("bussTap");
3434
3435 char oldDir = arg.loc.direction;
3436 char newDir = turnDir(oldDir,direction);
3437
3438 short width = arg.width;
3439
3440 struct buss* ret = malloc(2 * sizeof(struct buss));
3441 for(int i = 0; i < 2; i ++){
3442 ret[i].collors = malloc(width);
3443 ret[i].strength = malloc(width);
3444 ret[i].loc.stSide = arg.loc.stSide;
3445 ret[i].width = arg.width;
3446 }
3447
3448 ret[1].loc.direction = newDir;
3449 ret[0].loc.direction = oldDir;
3450
3451 for(int i = 0; i < width; i++){
3452
3453 ret[0].collors[i] = arg.collors[i];
3454 ret[1].collors[i] = arg.collors[i];
3455
3456 short longDist = ((width - 1) - i) * 2;
3457 short shortDist = i * 2;
3458
3459 if(arg.loc.stSide == newDir){
3460 arg.strength[i] = wire(arg.strength[i],1,arg.collors[i],longDist,oldDir);
3461 shift(1,'u');
3462 setRepeater(oldDir);
3463 shift(1,oldDir);
3464 setBlock(B,1);
3465 shift(1,'d');
3466 shift(1,oldDir);
3467 ret[0].strength[i] = wire(15,1,arg.collors[i],shortDist,oldDir);
3468 shift(shortDist + 1,oppDir(oldDir));
3469 shift(1,'d');
3470 ret[1].strength[i] = wire(15,1,arg.collors[i],0,newDir);
3471 shift(1,'d');
3472 ret[1].strength[i] = wire(ret[1].strength[i],1,arg.collors[i],shortDist + 1,newDir);
3473 shift(2,'u');
3474 if(i != width - 1){
3475 shift(longDist + 1,oppDir(oldDir));
3476 shift(shortDist + 3,oppDir(newDir));
3477 }
3478 else{
3479 shift(longDist + 1,oppDir(newDir));
3480 shift(1,oppDir(oldDir));
3481 }
3482 }
3483 else{
3484 arg.strength[i] = wire(arg.strength[i],1,arg.collors[i],shortDist,oldDir);
3485 shift(1,'u');
3486 setRepeater(oldDir);
3487 shift(1,oldDir);
3488 setBlock(B,1);
3489 shift(1,'d');
3490 shift(1,oldDir);
3491 ret[0].strength[i] = wire(15,1,arg.collors[i],longDist,oldDir);
3492 shift(longDist + 1,oppDir(oldDir));
3493 shift(1,'d');
3494 ret[1].strength[i] = wire(15,1,arg.collors[i],0,newDir);
3495 shift(1,'d');
3496 ret[1].strength[i] = wire(ret[1].strength[i],1,arg.collors[i],longDist + 1,newDir);
3497 shift(2,'u');
3498 if(i != width - 1){
3499 shift(shortDist + 1,oppDir(oldDir));
3500 shift((longDist + 1) - 2,oppDir(newDir));
3501 }
3502 else{
3503 shift(shortDist + 1,oppDir(newDir));
3504 shift(1,oppDir(oldDir));
3505 }
3506 }
3507 }
3508 ret[1].loc.stSide = turnDir(ret[1].loc.stSide,direction);
3509 if(arg.loc.stSide != newDir){
3510 shift((width - 1) * 2,oppDir(oldDir));
3511 }
3512 else{
3513 shift((width - 1) * 2,oldDir);
3514 }
3515 ret[1].loc.stSide = oppDir(ret[1].loc.stSide);
3516
3517 comment("endbussTap");
3518 return ret;
3519}
3520
3521struct buss* buildRoundKeyBuss(struct buss roundKey){
3522
3523 short spaceBetween = 8;
3524
3525 comment("buildRoundKeyBuss");
3526 struct buss* DESKeys = bussTap(roundKey,'l');
3527 DESKeys[0].name = "encrypt";
3528 DESKeys[1].name = "decrypt";
3529 printBussInfo(DESKeys[1],"beforeBussDown");
3530 shift(4,'d');
3531 for(int i = 1; i < 16; i++){
3532 bussTap(roundKey,'l');
3533 if(i != 15)
3534 shift(4,'d');
3535 }
3536 shift(roundKey.width * 2,oppDir(roundKey.loc.stSide));
3537 shift(2,'d');
3538 shift(1,roundKey.loc.direction);
3539
3540 for(int i = 0; i < 16; i++){
3541 bussStraight(DESKeys[1],(i * 2) + 4);
3542 struct buss outKey = bussUp(1,DESKeys[1],(i * 8) + spaceBetween,'d',1);
3543 shift(1,outKey.loc.direction);
3544 bussStraight(outKey,(i * 2));
3545 shift(3,outKey.loc.direction);
3546 if(i != 15){
3547 shift(3,DESKeys[1].loc.direction);
3548 shift((i * 8) + spaceBetween + 4,'u');
3549 }
3550 }
3551
3552 freeBuss(roundKey);
3553 comment("endbuildRoundKeyBuss");
3554 return DESKeys;
3555}
3556
3557int main(){
3558
3559 //memory allocation
3560 map = malloc(mapW * sizeof(struct block**));
3561 map[0] = malloc(mapH * sizeof(struct block*));
3562 map[0][0] = malloc(mapD * sizeof(struct block));
3563
3564
3565 // struct buss Test = createTestBuss("TEST_1",48,'r','b');
3566 // struct buss* block = allocateBlock();
3567
3568 buildOutput(2,'l','b');
3569
3570 // buildStables(Test,'r','b');
3571
3572 // buildOutLines(7,4,'f','b','l');
3573
3574
3575 // Test = turnBuss(Test,'r',1,2);
3576 // Test = bussStraight(Test,3);
3577 // Test = turnBuss(Test,'r',1,2);
3578
3579 // Test = bussFlipFlop(Test);
3580
3581 // buildRound(Test,block);
3582
3583 // buildRoundKeyBuss(Test);
3584
3585 // bussTap(Test,'l');
3586
3587 // setKeySchedual();
3588
3589 // Test = turnBuss(Test,'l',1,2,'u');
3590
3591 buildMaterialLibrary();
3592 buildWaveFront();
3593 // buildImmages();
3594 // printFileBuffer(script);
3595
3596 //end portion of main (freeing and closing pointers)
3597 freeBlockMap();
3598
3599 return 0;
3600}