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