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