Beispiel #1
0
void
reset_room()
{
    int roomnum;
    char *quad_name;
    room_t scratch;

    memset(&scratch, 0, sizeof(room_t));

    cprintf("Number of room to reset: ");
    quad_name = get_name(3);

    if (strlen(quad_name) < 1)
	return;

    roomnum = atoi(quad_name);

    scratch = readquad(roomnum);

    scratch.highest = 0;
    cprintf("Are you really sure you want to reset %s>?\n", scratch.name);
    if (yesno() == YES) {
	write_quad(scratch, roomnum);
	log_sysop_action("reset %s %d.%s>", config.forum, roomnum, scratch.name);
    } else {
	cprintf("Ok then. No resetting done this time.\n\n");
    }
    return;
}
Beispiel #2
0
void write_functions()
{
    fprintf(output, "main_loop:\n");
    fprintf(output, "\tcall func_main\n");
    fprintf(output, "\tgoto main_loop\n");

    List *functions = (List *) bytecode->functions;
    while(functions->data != NULL)
    {
        Function *function = functions->data;
        // Write function label
        fprintf(output, "func_%s:\n", function->name);

        // A stack frame needs 1 byte per static variable + 1 byte for saved frame pointer
        int frame_width = list_length(function->symbol_table) + 1;
        printf("Need to allocate %i byte stack frame for function %s\n", frame_width, function->name);

        fprintf(output, "; Saving frame pointer\n");
        fprintf(output, "\tmovf H'0c', 0\n"); // Load top of stack - 1 into FSR
        fprintf(output, "\taddlw -1\n");
        fprintf(output, "\tmovwf H'04'\n");
        fprintf(output, "\tmovf H'0c', 0\n"); // Store the current frame pointer into the top of the stack
        fprintf(output, "\tmovwf H'00'\n");
        fprintf(output, "\tmovlw %i\n", frame_width); // Now set the new frame pointer
        fprintf(output, "\tsubwf H'0c'\n\n");

        allocate_variables(function->symbol_table);

        List *quads = function->statements;
        while(quads->data != NULL)
        {
            Quad *quad = quads->data;
            write_quad(quad, function);
            quads = quads->next;
        }

        // Restore previous frame pointer and return
        fprintf(output, "; Restoring previous frame pointer\n");
        fprintf(output, "\tmovf H'0c', 0\n"); // Load previous frame pointer
        fprintf(output, "\taddlw %i\n", frame_width - 1);
        fprintf(output, "\tmovwf H'04'\n");
        fprintf(output, "\tmovf H'00', 0\n");
        fprintf(output, "\tmovwf H'0c'\n");
        fprintf(output, "\treturn\n\n");
        
        functions = functions->next;
    }

    fprintf(output, "\tend\n");
}
Beispiel #3
0
int main(int argc, char** argv) {
    if(argc >= 2) {
        if(strcmp(argv[1], "--help") == 0) {
            print_usage();
            exit(2);
        }
    }
    int c;
    int errflg = 0;

    int male = 1;
    float D = 9.0;        // default value, can be changed as a command line argument
    float P = 2;          // default value, can be changed as a command line argument
    float theta = M_PI/3; // 60 degrees, the standard, can be changed as a command line argument

    float screwHeight = 20; // height of entire screw (without a head)
                            // TODO maybe add ability to add a head
    float outerDiameter = -1;

    int segments = 72; // number of segments to approximate a circle, 
                        // higher the number, higher the resolution 
                        // (and file size) of the stl file

    while((c = getopt(argc, argv, "fP:D:a:h:s:o:")) != -1) {
        switch(c) {
            case 'f':
                male = 0;
                break;
            case 'P':
                P = atof(optarg);
                break;
            case 'D':
                D = atof(optarg);
                break;
            case 'a':
                theta = atof(optarg)*M_PI/180;
                break;
            case 'h':
                screwHeight = atof(optarg);
                break;
            case 's':
                segments = atoi(optarg);
                break;
            case 'o':
                outerDiameter = atof(optarg);
                break;
            case '?':
                fprintf(stderr, "Unrecognized option: '-%c'\n", optopt);
                errflg++;
                break;
        }
    }

    if(outerDiameter <= D) {
        outerDiameter = D+1;
    }

    if(errflg || optind >= argc) {
        print_usage();
        exit(2);
    }

    char *file = argv[optind];

    FILE *outf;

    outf = fopen(file, "wb");
    if(!outf) {
        fprintf(stderr, "Can't write to file: %s\n", file);
        exit(2);
    }

    char header[81] = {0};
    // TODO add some settings summary to header string
    snprintf(header, 81, "Created with stl_threads.");

    fwrite(header, 80, 1, outf);

    // writing 0 to num_tris for now, will update it at the end.
    uint32_t num_tris = 0;
    fwrite(&num_tris, 4, 1, outf);

    // ISO metric screw thread standard designates screw threads 
    // as M followed by diameter D, a multiplication sign, and then 
    // the pitch P (e.g. M8x1.25). Other standards designate standard
    // pitches for a given diameter (e.g. M8 means the same as M8x1.25).
    //
    // See http://en.wikipedia.org/wiki/ISO_metric_screw_thread
    //
    // The standard assumes a theta of 60 degrees, but we allow
    // theta to change, for ease of manufacturing. Certain 3D printers
    // may not be able to print without drooping at 60 degrees.

    int female = !male;

    // equations vary from wikipedia because we're not assuming a 60 degree theta
    // and we're allowing cutting off different amounts than H/8
    // and H/4 from the tip and troughs

    float tantheta_2 = tan(theta/2);
    float H = P/(2*tantheta_2); 
    float Htip = H/8;
    float Htrough = H/4;
    float Hdiff = H-Htip-Htrough;

    float Pdiff = Hdiff*tantheta_2;
    float Ptip = 2*Htip*tantheta_2;
    float Ptrough = 2*Htrough*tantheta_2;

    float Dmin = D-2*Hdiff;
    float Dmin_2 = Dmin/2;
    float D_2 = D/2;
    float fD = outerDiameter/2;


    /*
    // my ascii representation of image at 
    // (http://en.wikipedia.org/wiki/ISO_metric_screw_thread)
    // with my own added variables
    
                |<--H->|
                |      |
    |           |      |
    |-------------. pt5|   ------   // pt5 is the same as pt1 one cycle later
    |    ^      |/|    |      ^
    |    |      . |    |     Ptrough
    |    |       \|    |      v
    |    |        . pt4|   ------
    |    |         \   |
    |    |        ( \  |
    |            (   . pt3  ------
    |    P      (    |\        ^
    |          theta | .       Ptip
    |    |      (    |/        v
    |    |       (   . pt2  ------
    |    |        ( /          ^
    |    v         / |         Pdiff
    |-------------. pt1     ------ 
    |            /|  |
    |           . |  |
    |<---Dmin/2-->|  |
    |                |
    |                |
    |<-----D/2------>|
    */

    vec pt1,pt2,pt3,pt4,pt5;      

    pt1.x = Dmin_2;
    pt1.y = 0;
    pt1.z = 0;
    pt1.w = 1;

    pt2.x = D_2;
    pt2.y = 0;
    pt2.z = Pdiff;
    pt2.w = 1;

    pt3.x = D_2;
    pt3.y = 0;
    pt3.z = Pdiff+Ptip;
    pt3.w = 1;

    pt4.x = Dmin_2;
    pt4.y = 0;
    pt4.z = 2*Pdiff+Ptip;
    pt4.w = 1;

    pt5.x = Dmin_2; // not used, instead pt1 one full cycle later is used
    pt5.y = 0;      // to avoid floating point errors
    pt5.z = P;
    pt5.w = 1;

    int total_segments = (screwHeight/P-1)*segments;

    vec origin = {0};
    vec top = {0};
    top.z = screwHeight;

    vec up = {0};
    up.z = 1;

    vec down = {0};
    down.z = -1;

    float anginc = (float)360/segments;
    vec sliced8Int;
    int needsExtraTris = 0;

    for(int i = -segments; i < total_segments+segments; i++) {
        vec p1,p2,p3,p4,p5;
        vec p1n,p2n,p3n,p4n,p5n;

        vec ob1,ob1n;
        vec ot1,ot1n;

        float ango = (float)360*((i+segments)%segments)/segments;
        float angno = (float)360*((i+segments)%segments+1)/segments;

        float cosao = cos(ango*M_PI/180);
        float sinao = sin(ango*M_PI/180);

        float cosano = cos(angno*M_PI/180);
        float sinano = sin(angno*M_PI/180);

        ob1.x = fD*cosao;
        ob1.y = fD*sinao;
        ob1.z = 0;

        ob1n.x = fD*cosano;
        ob1n.y = fD*sinano;
        ob1n.z = 0;

        ot1.x = fD*cosao;
        ot1.y = fD*sinao;
        ot1.z = screwHeight;

        ot1n.x = fD*cosano;
        ot1n.y = fD*sinano;
        ot1n.z = screwHeight;

        float ang = (float)360*i/segments;
        float angn = (float)360*(i+1)/segments;
        float angc = (float)360*(i+segments)/segments;
        float angnc = (float)360*(i+1+segments)/segments;

        float cosa = cos(ang*M_PI/180);
        float sina = sin(ang*M_PI/180);

        float cosan = cos(angn*M_PI/180);
        float sinan = sin(angn*M_PI/180);

        float cosanc = cos(angnc*M_PI/180);
        float sinanc = sin(angnc*M_PI/180);

        float cosac = cos(angc*M_PI/180);
        float sinac = sin(angc*M_PI/180);

        float z = P*ang/360;
        float zn = P*angn/360;
        float zc = P*angc/360;
        float znc = P*angnc/360;

        mat t;
        mat tn;
        mat tc;
        mat tnc;

        t.xx = cosa;
        t.xy = sina;
        t.xz = 0;
        t.xw = 0;

        t.yx = -sina;
        t.yy = cosa;
        t.yz = 0;
        t.yw = 0;

        t.zx = 0;
        t.zy = 0;
        t.zz = 1;
        t.zw = 0;

        t.tx = 0;
        t.ty = 0;
        t.tz = z;
        t.tw = 1;

        tn.xx = cosan;
        tn.xy = sinan;
        tn.xz = 0;
        tn.xw = 0;

        tn.yx = -sinan;
        tn.yy = cosan;
        tn.yz = 0;
        tn.yw = 0;

        tn.zx = 0;
        tn.zy = 0;
        tn.zz = 1;
        tn.zw = 0;

        tn.tx = 0;
        tn.ty = 0;
        tn.tz = zn;
        tn.tw = 1;

        tnc.xx = cosanc;
        tnc.xy = sinanc;
        tnc.xz = 0;
        tnc.xw = 0;

        tnc.yx = -sinanc;
        tnc.yy = cosanc;
        tnc.yz = 0;
        tnc.yw = 0;

        tnc.zx = 0;
        tnc.zy = 0;
        tnc.zz = 1;
        tnc.zw = 0;

        tnc.tx = 0;
        tnc.ty = 0;
        tnc.tz = znc;
        tnc.tw = 1;

        tc.xx = cosac;
        tc.xy = sinac;
        tc.xz = 0;
        tc.xw = 0;

        tc.yx = -sinac;
        tc.yy = cosac;
        tc.yz = 0;
        tc.yw = 0;

        tc.zx = 0;
        tc.zy = 0;
        tc.zz = 1;
        tc.zw = 0;

        tc.tx = 0;
        tc.ty = 0;
        tc.tz = zc;
        tc.tw = 1;

        vec_mat_mult(&pt1, &t, &p1);
        vec_mat_mult(&pt2, &t, &p2);
        vec_mat_mult(&pt3, &t, &p3);
        vec_mat_mult(&pt4, &t, &p4);
        vec_mat_mult(&pt1, &tc, &p5); // using pt1 with a transform of 1 
                                      // full cycle around to avoid 
                                      // floating point roundoff errors

        vec_mat_mult(&pt1, &tn, &p1n);
        vec_mat_mult(&pt2, &tn, &p2n);
        vec_mat_mult(&pt3, &tn, &p3n);
        vec_mat_mult(&pt4, &tn, &p4n);
        vec_mat_mult(&pt1, &tnc, &p5n); // using pt1 with a transform of 1
                                        // full cycle around to avoid 
                                        // floating point roundoff errors

        if(i < 0) {
            int wrote_outer_tri = 0;

            vec int1,int2;
            int tris_written;
            if(write_sliced_tri(outf, &p1,&p1n,&p2n,female,&origin,&up,&int1,&int2,&tris_written)) {
                if(male) {
                    write_tri(outf,&int2,&origin,&int1,0);
                    num_tris += 1;
                } else {
                    if(wrote_outer_tri) {
                        write_tri(outf,&int2,&int1,&ob1,0);
                        num_tris += 1;
                    } else {
                        write_tri(outf,&int1,&ob1n,&ob1,0);
                        write_tri(outf,&int2,&int1,&ob1,0);
                        wrote_outer_tri = 1;
                        num_tris += 2;
                    }
                }
            }
            num_tris += tris_written;

            if(write_sliced_tri(outf, &p1,&p2n,&p2,female,&origin,&up,&int1,&int2,&tris_written)) {
                if(male) {
                    write_tri(outf,&int2,&origin,&int1,female);
                    num_tris += 1;
                } else {
                    if(wrote_outer_tri) {
                        write_tri(outf,&int2,&int1,&ob1,0);
                        num_tris += 1;
                    } else {
                        write_tri(outf,&int1,&ob1n,&ob1,0);
                        write_tri(outf,&int2,&int1,&ob1,0);
                        wrote_outer_tri = 1;
                        num_tris += 2;
                    }
                }
            }
            num_tris += tris_written;

            if(write_sliced_tri(outf, &p2,&p2n,&p3n,female,&origin,&up,&int1,&int2,&tris_written)) {
                if(male) {
                    write_tri(outf,&int2,&origin,&int1,female);
                    num_tris += 1;
                } else {
                    if(wrote_outer_tri) {
                        write_tri(outf,&int2,&int1,&ob1,0);
                        num_tris += 1;
                    } else {
                        write_tri(outf,&int1,&ob1n,&ob1,0);
                        write_tri(outf,&int2,&int1,&ob1,0);
                        wrote_outer_tri = 1;
                        num_tris += 2;
                    }
                }
            }
            num_tris += tris_written;


            if(write_sliced_tri(outf, &p2,&p3n,&p3,female,&origin,&up,&int1,&int2,&tris_written)) {
                if(male) {
                    write_tri(outf,&int2,&origin,&int1,female);
                    num_tris += 1;
                } else {
                    if(wrote_outer_tri) {
                        write_tri(outf,&int2,&int1,&ob1,0);
                        num_tris += 1;
                    } else {
                        write_tri(outf,&int1,&ob1n,&ob1,0);
                        write_tri(outf,&int2,&int1,&ob1,0);
                        wrote_outer_tri = 1;
                        num_tris += 2;
                    }
                }
            }
            num_tris += tris_written;

            if(write_sliced_tri(outf, &p3,&p3n,&p4n,female,&origin,&up,&int1,&int2,&tris_written)) {
                if(male) {
                    write_tri(outf,&int2,&origin,&int1,female);
                    num_tris += 1;
                } else {
                    if(wrote_outer_tri) {
                        write_tri(outf,&int2,&int1,&ob1,0);
                        num_tris += 1;
                    } else {
                        write_tri(outf,&int1,&ob1n,&ob1,0);
                        write_tri(outf,&int2,&int1,&ob1,0);
                        wrote_outer_tri = 1;
                        num_tris += 2;
                    }
                }
            }
            num_tris += tris_written;

            if(write_sliced_tri(outf, &p3,&p4n,&p4,female,&origin,&up,&int1,&int2,&tris_written)) {
                if(male) {
                    write_tri(outf,&int2,&origin,&int1,female);
                    num_tris += 1;
                } else {
                    if(wrote_outer_tri) {
                        write_tri(outf,&int2,&int1,&ob1,0);
                        num_tris += 1;
                    } else {
                        write_tri(outf,&int1,&ob1n,&ob1,0);
                        write_tri(outf,&int2,&int1,&ob1,0);
                        wrote_outer_tri = 1;
                        num_tris += 2;
                    }
                }
            }
            num_tris += tris_written;

            if(write_sliced_tri(outf, &p4,&p4n,&p5n,female,&origin,&up,&int1,&int2,&tris_written)) {
                if(male) {
                    write_tri(outf,&int2,&origin,&int1,female);
                    num_tris += 1;
                } else {
                    if(wrote_outer_tri) {
                        write_tri(outf,&int2,&int1,&ob1,0);
                        num_tris += 1;
                    } else {
                        write_tri(outf,&int1,&ob1n,&ob1,0);
                        write_tri(outf,&int2,&int1,&ob1,0);
                        wrote_outer_tri = 1;
                        num_tris += 2;
                    }
                }
            }
            num_tris += tris_written;

            if(write_sliced_tri(outf, &p4,&p5n,&p5,female,&origin,&up,&int1,&int2,&tris_written)) {
                if(male) {
                    write_tri(outf,&int2,&origin,&int1,female);
                    num_tris += 1;
                } else {
                    if(wrote_outer_tri) {
                        write_tri(outf,&int2,&int1,&ob1,0);
                        num_tris += 1;
                    } else {
                        write_tri(outf,&int1,&ob1n,&ob1,0);
                        write_tri(outf,&int2,&int1,&ob1,0);
                        wrote_outer_tri = 1;
                        num_tris += 2;
                    }
                }
            }
            num_tris += tris_written;

        } else if(i >= total_segments) {
            int wrote_outer_tri = 0;
            vec int1,int2;
            int tris_written;
            if(write_sliced_tri(outf, &p1,&p1n,&p2n,female,&top,&down,&int1,&int2,&tris_written)) {
                if(male) {
                    write_tri(outf,&int1,&top,&int2,female);
                    num_tris += 1;
                } else {
                    if(wrote_outer_tri) {
                        write_tri(outf,&int2,&int1,&ot1,1);
                        num_tris += 1;
                    } else {
                        write_tri(outf,&int1,&ot1n,&ot1,1);
                        write_tri(outf,&int2,&int1,&ot1,1);
                        wrote_outer_tri = 1;
                        num_tris += 2;
                    }
                }

                if(i == total_segments+segments-1 && needsExtraTris) {
                    write_tri(outf, &int1,&p1n,&sliced8Int,female);
                    num_tris += 1;

                    if(male) {
                        write_tri(outf, &int1,&sliced8Int,&top,female);
                        num_tris += 1;
                    } else {
                        write_tri(outf, &int1,&sliced8Int,&ot1n,female);
                        num_tris += 1;
                    }
                }
            }
            num_tris += tris_written;

            if(write_sliced_tri(outf, &p1,&p2n,&p2,female,&top,&down,&int1,&int2,&tris_written)) {
                if(male) {
                    write_tri(outf,&int1,&top,&int2,female);
                    num_tris += 1;
                } else {
                    if(wrote_outer_tri) {
                        write_tri(outf,&int2,&int1,&ot1,1);
                        num_tris += 1;
                    } else {
                        write_tri(outf,&int1,&ot1n,&ot1,1);
                        write_tri(outf,&int2,&int1,&ot1,1);
                        wrote_outer_tri = 1;
                        num_tris += 2;
                    }
                }
            }
            num_tris += tris_written;

            if(write_sliced_tri(outf, &p2,&p2n,&p3n,female,&top,&down,&int1,&int2,&tris_written)) {
                if(male) {
                    write_tri(outf,&int1,&top,&int2,female);
                    num_tris += 1;
                } else {
                    if(wrote_outer_tri) {
                        write_tri(outf,&int2,&int1,&ot1,1);
                        num_tris += 1;
                    } else {
                        write_tri(outf,&int1,&ot1n,&ot1,1);
                        write_tri(outf,&int2,&int1,&ot1,1);
                        wrote_outer_tri = 1;
                        num_tris += 2;
                    }
                }
            }
            num_tris += tris_written;


            if(write_sliced_tri(outf, &p2,&p3n,&p3,female,&top,&down,&int1,&int2,&tris_written)) {
                if(male) {
                    write_tri(outf,&int1,&top,&int2,female);
                    num_tris += 1;
                } else {
                    if(wrote_outer_tri) {
                        write_tri(outf,&int2,&int1,&ot1,1);
                        num_tris += 1;
                    } else {
                        write_tri(outf,&int1,&ot1n,&ot1,1);
                        write_tri(outf,&int2,&int1,&ot1,1);
                        wrote_outer_tri = 1;
                        num_tris += 2;
                    }
                }
            }
            num_tris += tris_written;

            if(write_sliced_tri(outf, &p3,&p3n,&p4n,female,&top,&down,&int1,&int2,&tris_written)) {
                if(male) {
                    write_tri(outf,&int1,&top,&int2,female);
                    num_tris += 1;
                } else {
                    if(wrote_outer_tri) {
                        write_tri(outf,&int2,&int1,&ot1,1);
                        num_tris += 1;
                    } else {
                        write_tri(outf,&int1,&ot1n,&ot1,1);
                        write_tri(outf,&int2,&int1,&ot1,1);
                        wrote_outer_tri = 1;
                        num_tris += 2;
                    }
                }
            }
            num_tris += tris_written;

            if(write_sliced_tri(outf, &p3,&p4n,&p4,female,&top,&down,&int1,&int2,&tris_written)) {
                if(male) {
                    write_tri(outf,&int1,&top,&int2,female);
                    num_tris += 1;
                } else {
                    if(wrote_outer_tri) {
                        write_tri(outf,&int2,&int1,&ot1,1);
                        num_tris += 1;
                    } else {
                        write_tri(outf,&int1,&ot1n,&ot1,1);
                        write_tri(outf,&int2,&int1,&ot1,1);
                        wrote_outer_tri = 1;
                        num_tris += 2;
                    }
                }
            }
            num_tris += tris_written;

            if(write_sliced_tri(outf, &p4,&p4n,&p5n,female,&top,&down,&int1,&int2,&tris_written)) {
                if(male) {
                    write_tri(outf,&int1,&top,&int2,female);
                    num_tris += 1;
                } else {
                    if(wrote_outer_tri) {
                        write_tri(outf,&int2,&int1,&ot1,1);
                        num_tris += 1;
                    } else {
                        write_tri(outf,&int1,&ot1n,&ot1,1);
                        write_tri(outf,&int2,&int1,&ot1,1);
                        wrote_outer_tri = 1;
                        num_tris += 2;
                    }
                }
            }
            num_tris += tris_written;

            if(write_sliced_tri(outf, &p4,&p5n,&p5,female,&top,&down,&int1,&int2,&tris_written)) {
                if(male) {
                    write_tri(outf,&int1,&top,&int2,female);
                    num_tris += 1;
                } else {
                    if(wrote_outer_tri) {
                        write_tri(outf,&int2,&int1,&ot1,1);
                        num_tris += 1;
                    } else {
                        write_tri(outf,&int1,&ot1n,&ot1,1);
                        write_tri(outf,&int2,&int1,&ot1,1);
                        wrote_outer_tri = 1;
                        num_tris += 2;
                    }
                }
                if(i == total_segments && !vec_equals(&int2,&p5)) {
                    needsExtraTris = 1;
                    vec_copy(&int2,&sliced8Int);
                }
            }
            num_tris += tris_written;
        } else {
            write_quad(outf, &p1,&p1n,&p2n,&p2,female);
            write_quad(outf, &p2,&p2n,&p3n,&p3,female);
            write_quad(outf, &p3,&p3n,&p4n,&p4,female);
            write_quad(outf, &p4,&p4n,&p5n,&p5,female);
            num_tris += 8;
        }
    }

    if(female) {
        for(int i = 0; i < segments; i++) {
            vec ob1,ob1n;
            vec ot1,ot1n;

            float ang = (float)360*i/segments;
            float angn = (float)360*(i+1)/segments;

            float cosa = cos(ang*M_PI/180);
            float sina = sin(ang*M_PI/180);

            float cosan = cos(angn*M_PI/180);
            float sinan = sin(angn*M_PI/180);

            ob1.x = fD*cosa;
            ob1.y = fD*sina;
            ob1.z = 0;

            ob1n.x = fD*cosan;
            ob1n.y = fD*sinan;
            ob1n.z = 0;

            ot1.x = fD*cosa;
            ot1.y = fD*sina;
            ot1.z = screwHeight;

            ot1n.x = fD*cosan;
            ot1n.y = fD*sinan;
            ot1n.z = screwHeight;

            write_quad(outf,&ob1,&ob1n,&ot1n,&ot1,0);
            num_tris += 2;
        }
    }

    fseek(outf, 80, SEEK_SET);
    fwrite(&num_tris, 4, 1, outf);

    fclose(outf);

    return 0;
}
Beispiel #4
0
// returns true if triangle intersects plane, int1 and int2 will be set
// to the intersection points
// returns false if all points are above or below the plane
int write_sliced_tri(FILE *f,
                      vec *p1,
                      vec *p2,
                      vec *p3,
                      int rev,
                      vec *p,  // point that lies in the slicing plane  
                      vec *n,   // normal of slicing plane, keep points in the direction of normal
                      vec *int1, // output, intersecting pt1, returned only if intersection occurs
                      vec *int2, // output, intersecting pt2, returned only if intersection occurs
                      int *tris) // output, number of tris written
                      {
    vec trin;
    tri_normal(p1,p2,p3,rev,&trin);

    point_state_t state1;
    point_state_t state2;
    point_state_t state3;

    state1 = point_state(p1,p,n);
    state2 = point_state(p2,p,n);
    state3 = point_state(p3,p,n);

    if((state1 == ABOVE || state1 == ON) && 
       (state2 == ABOVE || state2 == ON) && 
       (state3 == ABOVE || state3 == ON)) {
        // all points are above or on plane, write tri normally
        write_tri(f,p1,p2,p3,rev);
        *tris = 1;
        return 0;
    } else if((state1 == BELOW || state1 == ON) &&
              (state2 == BELOW || state2 == ON) && 
              (state3 == BELOW || state3 == ON)) {
        // all points are below or on plane, cull entire tri
        *tris = 0;
        return 0;
    } else {
        // triangle intersects plane

        if(state1 == ON) {
            vec tmp1,tmp2;
            float r;

            vec_copy(p1, int1);

            vec_sub(p2,p3,&tmp1);
            vec_sub(p,p3,&tmp2);
            r = vec_dot(n,&tmp2)/vec_dot(n,&tmp1);

            int2->x = p3->x + r*tmp1.x;
            int2->y = p3->y + r*tmp1.y;
            int2->z = p3->z + r*tmp1.z;

            if(state2 == ABOVE) {
                write_tri(f,p1,p2,int2,rev);
            } else {
                write_tri(f,p1,int2,p3,rev);
            }
            *tris = 1;
            return 1;
        }

        if(state2 == ON) {
            vec tmp1,tmp2;
            float r;

            vec_copy(p2, int1);

            vec_sub(p1,p3,&tmp1);
            vec_sub(p,p3,&tmp2);
            r = vec_dot(n,&tmp2)/vec_dot(n,&tmp1);

            int2->x = p3->x + r*tmp1.x;
            int2->y = p3->y + r*tmp1.y;
            int2->z = p3->z + r*tmp1.z;

            if(state1 == ABOVE) {
                write_tri(f,p1,p2,int2,rev);
            } else {
                write_tri(f,p2,p3,int2,rev);
            }
            *tris = 1;
            return 1;
        }

        if(state3 == ON) {
            vec tmp1,tmp2;
            float r;

            vec_copy(p3, int2);

            vec_sub(p1,p2,&tmp1);
            vec_sub(p,p2,&tmp2);
            r = vec_dot(n,&tmp2)/vec_dot(n,&tmp1);

            int1->x = p2->x + r*tmp1.x;
            int1->y = p2->y + r*tmp1.y;
            int1->z = p2->z + r*tmp1.z;

            if(state1 == ABOVE) {
                write_tri(f,p1,int1,p3,rev);
            } else {
                write_tri(f,int1,p2,p3,rev);
            }
            *tris = 1;
            return 1;
        }

        if((state1 == ABOVE && state2 == ABOVE) ||
            (state1 == BELOW && state2 == BELOW)) {
            vec tmp1,tmp2,tmp3;
            float r1,r2;

            vec_sub(p2,p3,&tmp1);
            vec_sub(p1,p3,&tmp2);
            vec_sub(p,p3,&tmp3);

            r1 = vec_dot(n,&tmp3)/vec_dot(n,&tmp1);
            r2 = vec_dot(n,&tmp3)/vec_dot(n,&tmp2);

            int1->x = p3->x + r1*tmp1.x;
            int1->y = p3->y + r1*tmp1.y;
            int1->z = p3->z + r1*tmp1.z;

            int2->x = p3->x + r2*tmp2.x;
            int2->y = p3->y + r2*tmp2.y;
            int2->z = p3->z + r2*tmp2.z;

            if(state3 == ABOVE) {
                write_tri(f,int1,p3,int2,rev);
                *tris = 1;
            } else {
                write_quad(f,p1,p2,int1,int2,rev);
                *tris = 2;
            }
            return 1;
        }

        if((state2 == ABOVE && state3 == ABOVE) ||
            (state2 == BELOW && state3 == BELOW)) {
            vec tmp1,tmp2,tmp3;
            float r1,r2;

            vec_sub(p2,p1,&tmp1);
            vec_sub(p3,p1,&tmp2);
            vec_sub(p,p1,&tmp3);

            r1 = vec_dot(n,&tmp3)/vec_dot(n,&tmp1);
            r2 = vec_dot(n,&tmp3)/vec_dot(n,&tmp2);

            int1->x = p1->x + r1*tmp1.x;
            int1->y = p1->y + r1*tmp1.y;
            int1->z = p1->z + r1*tmp1.z;

            int2->x = p1->x + r2*tmp2.x;
            int2->y = p1->y + r2*tmp2.y;
            int2->z = p1->z + r2*tmp2.z;

            if(state1 == ABOVE) {
                write_tri(f,p1,int1,int2,rev);
                *tris = 1;
            } else {
                write_quad(f,int1,p2,p3,int2,rev);
                *tris = 2;
            }
            return 1;
        }

        if((state1 == ABOVE && state3 == ABOVE) || 
            (state1 == BELOW && state3 == BELOW)) {
            vec tmp1,tmp2,tmp3;
            float r1,r2;

            vec_sub(p1,p2,&tmp1);
            vec_sub(p3,p2,&tmp2);
            vec_sub(p,p2,&tmp3);

            r1 = vec_dot(n,&tmp3)/vec_dot(n,&tmp1);
            r2 = vec_dot(n,&tmp3)/vec_dot(n,&tmp2);

            int1->x = p2->x + r1*tmp1.x;
            int1->y = p2->y + r1*tmp1.y;
            int1->z = p2->z + r1*tmp1.z;

            int2->x = p2->x + r2*tmp2.x;
            int2->y = p2->y + r2*tmp2.y;
            int2->z = p2->z + r2*tmp2.z;

            if(state2 == ABOVE) {
                write_tri(f,int1,p2,int2,rev);
                *tris = 1;
            } else {
                write_quad(f,p1,int1,int2,p3,rev);
                *tris = 2;
            }
            return 1;
        }
    }


    *tris = 0;
    return 0;
}
Beispiel #5
0
void
editroom()
{
    char command;
    int done;

    /* don't mung Lobby>, Mail> or Yells> if you're 'only' Sysop */
    if ((curr_rm <= 5) && (usersupp->priv < PRIV_WIZARD)) {
	cprintf("\1f\1rNope. Only %ss can edit this %s.\1a\n",
		config.wizard, config.forum);
	return;
    }
    need_rewrite = done = FALSE;
    quickroom = readquad(curr_rm);	/* read in current settings */

    while (!done) {
	/* display room information */
	cprintf("\1w\1f------------------------------------------------------------------\n");
	cprintf("\n\1r[\1w1\1r] \1gEdit %s Name\1w : \1%c%s\1g.", config.forum,
		(quickroom.flags & QR_PRIVATE) ? 'r' :
		(quickroom.flags & (QR_ANONONLY | QR_ANON2)) ? 'p' : 'g',
		quickroom.name);

	cprintf("\n\1r[\1w3\1r] \1gEdit %s Type\1w: ", config.forum);
	cprintf("%s", (quickroom.flags & QR_PRIVATE) ? "\1rPRIVATE " : "\1gPUBLIC ");
	cprintf("\1g %s.", config.forum);

	cprintf("\n\1r[\1w4\1r] \1gEdit Message Type\1w: ");
	cprintf("%s %s", (quickroom.flags & QR_ANONONLY) ? "\1bANONYMOUS ONLY" :
	((quickroom.flags & QR_ANON2) ? "\1bANONYMOUS OPTION" : "\1gNORMAL"),
	    (quickroom.flags & QR_ALIASNAME) ? "\1w(\1bALIASNAME\1w)" : "");

	cprintf("\n\1r[\1w5\1r] \1gSubjectLines \1w: ");
	cprintf("%s", (quickroom.flags & QR_SUBJECTLINE) ? "\1gYEP." : "\1rNOOOOOOOOO!");

	cprintf("\n\1r[\1w6\1r] \1gDescribed    \1w: ");
	cprintf("%s", (quickroom.flags & QR_DESCRIBED) ? "\1gYEP." : "\1rNOOOOOOOOO!");

	IFSYSOP {
	    cprintf("\n\1r[\1w7\1r] \1gReadOnly     \1w: ");
	    cprintf("%s", (quickroom.flags & QR_READONLY) ? "\1gYEP." : "\1rNOOOOOOOOO!");

	    cprintf("\n\1r[\1w8\1r] \1gNoZap        \1w: ");
	    cprintf("%s", (quickroom.flags & QR_NOZAP) ? "\1gYEP." : "\1rNOOOOOOOOO!");

	    cprintf("\n\1r[\1w9\1r] \1gIN-USE       \1w: ");
	    cprintf("%s", (quickroom.flags & QR_INUSE) ? "\1gYEP." : "\1rNOOOOOOOOO!");

	    cprintf("\n\1r[\1w0\1r] \1gGuessname    \1w: ");
	    cprintf("%s", (quickroom.flags & QR_GUESSNAME) ? "\1gYEP." : "\1rNOOOOOOOOO!");

	    cprintf("\n\1r[\1wA\1r] \1gMaximum number of messages\1w: %d.",
		    quickroom.maxmsg);
	    cprintf("\n\1r[\1wB\1r] \1gHighest message number\1w: %ld.",
		    quickroom.highest);
	    cprintf("\n\1r[\1wC\1r] \1gLowest message number \1w: %ld.",
		    quickroom.lowest);
	    cprintf("\n\1r[\1wD\1r] \1g%s category \1w: \1y%s.", config.forum, quickroom.category);

	    cprintf("\n\n\1wDon't fiddle with A, B, and C unless you KNOW what you're doing!\n");
	}

	cprintf("\1rField to change \1w:\n");
	cprintf("\1w<\1renter\1w>\1g to exit. ");
	command = get_single("134567890ABCD\n\r");

	if (command == '\n' || command == '\r')
	    done = TRUE;
	else
	    edit_room_field(&quickroom, curr_rm, command);
    }				/* end while */

    if (need_rewrite == TRUE) {
	cprintf("\1rSave changes \1w(\1ry/n\1w)\1r? ");
	if (yesno() == NO) {
	    /* reload old quickroom and return */
	    quickroom = readquad(curr_rm);
	} else {
	    write_quad(quickroom, curr_rm);
	    log_sysop_action("roomedited %s>", quickroom.name);
	}
    }
}
Beispiel #6
0
void
create_room()
{
    int number;
    char command, *quad_name;

    for (number = 0; number < MAXQUADS; number++)
	if (!(readquad(number).flags & QR_INUSE)) {
	    cprintf("\n\1f\1gFound an unused %s at slot \1y%d\1g.\n", config.forum, number);
	    cprintf("\1gStop searching and use this position? \1w(\1rY\1w/\1rn\1w): \1c");
	    if (yesno_default(YES) == YES) {
		cprintf("\1f\1gInstall %s into slot \1y%d\1g? \1w(\1rY\1w/\1rn\1w): \1c", config.forum, number);
		if (yesno_default(YES) == NO)
		    return;
		else
		    break;
	    } else
		continue;
	}
    if (number >= MAXQUADS) {
	cprintf("\1f\1rNo unused %s was found.\n", config.forum);
	return;
    }
    cprintf("\1f\1rPlease keep the length of the name under 36 characters.\n                      |------------------------------------|\n\1f\1gName for new %s\1w: \1c", config.forum);
    quad_name = get_name(3);

    if (strlen(quad_name) == 0)
	return;
    if (get_room_number(quad_name) != -1) {
	cprintf("\1rA %s named '%s' already exists.\n", config.forum, quad_name);
	return;
    }
    curr_rm = number;
    quickroom = readquad(curr_rm);

    strcpy(quickroom.name, quad_name);
    quickroom.generation++;
    quickroom.lowest = ++quickroom.highest;
    quickroom.maxmsg = 100;
    quickroom.flags = QR_INUSE;

    cprintf("\1f\1g%s%s ",
	    config.forum,
	    "Type: \1w<\1y1\1w> \1gPublic \1w<\1y2\1w> \1rPrivate : \1c");

    command = get_single("12");

    if (command == '1') {	/* public room */
	cprintf("\1rThe %s will be PUBLIC.\n\n", config.forum);
	quickroom.flags &= ~QR_PRIVATE;
    } else {			/* invite -- just private flag, guessname off */
	cprintf("\1rThe %s will be INVITE ONLY.\n\n", config.forum);
	quickroom.flags |= QR_PRIVATE;
	if (quickroom.generation >= 100)
	    quickroom.generation = 10;
    }

    write_quad(quickroom, curr_rm);
    gotocurr();			/* takes care of self invite.. no matter, sysop anyways */
    log_sysop_action("created %s: %s> ", config.forum, quickroom.name);

    editroom();
    change_forum_info();
    qc_edit_room();
}
Beispiel #7
0
void
killroom()
{

    char temprmname[50];

    quickroom = readquad(curr_rm);

    if ((curr_rm < 11) && (usersupp->priv < PRIV_WIZARD)) {
	cprintf("\1f\1gOnly a \1w%s\1g can delete this %s.\n", config.wizard, config.forum);
	return;
    }
    if (curr_rm != CURSE_FORUM) {
	cprintf("\n\1f\1rAre you \1w!SURE!\1r you want to Delete this %s??? (y/n)",
		config.forum);
	if (yesno() == NO)
	    return;

	quickroom.flags = 0;
	strcpy(temprmname, quickroom.name);
	strcpy(quickroom.name, "");
	if (quickroom.flags & QR_INUSE)
	    quickroom.flags ^= QR_INUSE;

	cprintf( _("\1f\1rErase all messages in this forum? \1w(\1rrecommended\1w) (\1rY\1w/\1rn\1w) \1c"));
    } else
	cprintf("\n\1f\1rAre you \1w!SURE!\1r you want Clean The Dungeon? (Y/n) ");

    if (yesno_default(YES) == YES) {
	erase_all_messages(quickroom.highest);
	quickroom.highest = quickroom.lowest = 0;
	/*
	 * Trash posts from SQL table
	 */
	cprintf("\1f\1rRemoving messages with forum_id \1y%u\1r from message table... \1a", curr_rm);
	if ((mono_sql_mes_erase_forum(curr_rm)) == 0)
	    cprintf("\1f\1gok.\1a\n");
	else
	    cprintf("\1f\1rerror!\1a (logged)\n");

#ifdef USE_RATING
	/*
	 * Trash ratings from SQL table
	 */
	cprintf("\1f\1rRemoving messages with forum_id \1y%u\1r from rating table... \1a", curr_rm);
	if ((mono_sql_rat_erase_forum(curr_rm)) == 0)
	    cprintf("\1f\1gok.\1a\n");
	else
	    cprintf("\1f\1rerror!\1a(logged)\n");
#endif
    } else if (curr_rm == CURSE_FORUM)
	return;

    cprintf("\1f\1rResetting speedyforum... ");
    write_quad(quickroom, curr_rm);
    cprintf("\1gdone.\1a\n");

    if (curr_rm == CURSE_FORUM)
	log_sysop_action("Cleaned the Dungeon.");
    else {
	log_sysop_action("deleted %s: %d.%s>", config.forum, curr_rm, (strlen(temprmname)) ? temprmname : " (Quadrant had no name)");
	_sql_qc_zero_forum_categories(curr_rm);
    }

    curr_rm = 0;
    gotocurr();
}