// ------------------------------------------------------------------------------------------ void validate_modified_segments(void) { int v,w,v0,seg; char modified_segments[MAX_SEGMENTS]; for (v=0; v<=Highest_segment_index; v++) modified_segments[v] = 0; for (v=0; v<Modified_vertex_index; v++) { v0 = Modified_vertices[v]; for (seg = 0; seg <= Highest_segment_index; seg++) { short *vp = Segments[seg].verts; if (Segments[seg].segnum != -1) for (w=0; w<MAX_VERTICES_PER_SEGMENT; w++) if (*vp++ == v0) modified_segments[seg] = 1; } } for (v=0; v<=Highest_segment_index; v++) if (modified_segments[v]) { int s; // mprintf(0, "Validating segment #%04i\n", v); validate_segment(&Segments[v]); for (s=0; s<MAX_SIDES_PER_SEGMENT; s++) { Num_tilings = 1; assign_default_uvs_to_side(&Segments[v], s); } } }
// ------------------------------------------------------------------------------------------------- // Making Cursegp:Curside planar. // If already planar, return. // for each vertex v on side, not part of another segment // choose the vertex v which can be moved to make all sides of which it is a part planar, minimizing distance moved // if there is no vertex v on side, not part of another segment, give up in disgust // Return value: // 0 curside made planar (or already was) // 1 did not make curside planar int make_curside_planar(void) { int v; sbyte *vp; vms_vector planar_verts[4]; // store coordinates of up to 4 vertices which will make Curside planar, corresponding to each of 4 vertices on side int present_verts[4]; // set to 1 if vertex is present if (side_is_planar_p(Cursegp, Curside)) return 0; // Look at all vertices in side to find a free one. for (v=0; v<4; v++) present_verts[v] = 0; vp = Side_to_verts[Curside]; for (v=0; v<4; v++) { int v1 = vp[v]; // absolute vertex id if (is_free_vertex(Cursegp->verts[v1])) { compute_planar_vert(Cursegp, Curside, Cursegp->verts[v1], &planar_verts[v]); present_verts[v] = 1; } } // Now, for each v for which present_verts[v] == 1, there is a vector (point) in planar_verts[v]. // See which one is closest to the plane defined by the other three points. // Nah...just use the first one we find. for (v=0; v<4; v++) if (present_verts[v]) { med_set_vertex(vp[v],&planar_verts[v]); validate_segment(Cursegp); // -- should propagate tmaps to segments or something here... return 0; } // We tried, but we failed, to make Curside planer. return 1; }
/* Loads an ELF executable from FILE_NAME into the current thread. Stores the executable's entry point into *EIP and its initial stack pointer into *ESP. Returns true if successful, false otherwise. */ bool load (const char *file_name, void (**eip) (void), void **esp) { struct thread *t = thread_current (); struct Elf32_Ehdr ehdr; struct file *file = NULL; off_t file_ofs; bool success = false; int i; /* Allocate and activate page directory. */ t->pagedir = pagedir_create (); if (t->pagedir == NULL) goto done; process_activate (); /* Set up stack. */ if (!setup_stack (esp)){ goto done; } /* Open executable file. */ file = filesys_open (file_name); if (file == NULL) { printf ("load: %s: open failed\n", file_name); goto done; } /* Read and verify executable header. */ if (file_read (file, &ehdr, sizeof ehdr) != sizeof ehdr || memcmp (ehdr.e_ident, "\177ELF\1\1\1", 7) || ehdr.e_type != 2 || ehdr.e_machine != 3 || ehdr.e_version != 1 || ehdr.e_phentsize != sizeof (struct Elf32_Phdr) || ehdr.e_phnum > 1024) { printf ("load: %s: error loading executable\n", file_name); goto done; } /* Read program headers. */ file_ofs = ehdr.e_phoff; for (i = 0; i < ehdr.e_phnum; i++) { struct Elf32_Phdr phdr; if (file_ofs < 0 || file_ofs > file_length (file)) goto done; file_seek (file, file_ofs); if (file_read (file, &phdr, sizeof phdr) != sizeof phdr) goto done; file_ofs += sizeof phdr; switch (phdr.p_type) { case PT_NULL: case PT_NOTE: case PT_PHDR: case PT_STACK: default: /* Ignore this segment. */ break; case PT_DYNAMIC: case PT_INTERP: case PT_SHLIB: goto done; case PT_LOAD: if (validate_segment (&phdr, file)) { bool writable = (phdr.p_flags & PF_W) != 0; uint32_t file_page = phdr.p_offset & ~PGMASK; uint32_t mem_page = phdr.p_vaddr & ~PGMASK; uint32_t page_offset = phdr.p_vaddr & PGMASK; uint32_t read_bytes, zero_bytes; if (phdr.p_filesz > 0) { /* Normal segment. Read initial part from disk and zero the rest. */ read_bytes = page_offset + phdr.p_filesz; zero_bytes = (ROUND_UP (page_offset + phdr.p_memsz, PGSIZE) - read_bytes); } else { /* Entirely zero. Don't read anything from disk. */ read_bytes = 0; zero_bytes = ROUND_UP (page_offset + phdr.p_memsz, PGSIZE); } if (!load_segment (file, file_page, (void *) mem_page, read_bytes, zero_bytes, writable)) goto done; } else goto done; break; } } /* Start address. */ *eip = (void (*) (void)) ehdr.e_entry; success = true; done: /* We arrive here whether the load is successful or not. */ file_close (file); return success; }