void print_section(FILE *f,section *sec) { atom *p; taddr pc=sec->org; fprintf(f,"section %s (attr=<%s> align=%d):\n",sec->name,sec->attr,sec->align); for(p=sec->first; p; p=p->next) { pc=(pc+p->align-1)/p->align*p->align; fprintf(f,"%8llx: ",((unsigned long long)pc)&taddrmask); print_atom(f,p); fprintf(f,"\n"); pc+=atom_size(p,sec,pc); } }
static void resolve_section(section *sec) { atom *p; int done,pass=0; taddr size; do { done=1; if (++pass>=MAXPASSES) { general_error(7,sec->name); break; } if(DEBUG) printf("resolve_section(%s) pass %d\n",sec->name,pass); sec->pc=sec->org; for(p=sec->first; p; p=p->next) { sec->pc=(sec->pc+p->align-1)/p->align*p->align; cur_src=p->src; cur_src->line=p->line; #ifdef HAVE_CPU_OPTS if(p->type==OPTS) { cpu_opts(p->content.opts); } else #endif if(p->type==LABEL) { symbol *label=p->content.label; if(label->type!=LABSYM) ierror(0); if(label->pc!=sec->pc) { if(DEBUG) printf("changing label %s from %lu to %lu\n",label->name, (unsigned long)label->pc,(unsigned long)sec->pc); done=0; label->pc=sec->pc; } } size=atom_size(p,sec,sec->pc); #ifdef CHECK_ATOMSIZE if(size!=p->lastsize) { if(DEBUG) printf("changed size of atom type %d at %lu from %ld to %ld\n", p->type,(unsigned long)sec->pc,(long)p->lastsize,(long)size); done=0; p->lastsize=size; } #endif sec->pc+=size; } } while(errors==0&&!done); }
/* Constructs the GL shapes of the current molecule */ static void build_molecule (ModeInfo *mi, Bool transparent_p) { molecule_configuration *mc = &mcs[MI_SCREEN(mi)]; int wire = MI_IS_WIREFRAME(mi); int i; GLfloat alpha = transparent_p ? shell_alpha : 1.0; int polys = 0; molecule *m = &mc->molecules[mc->which]; if (wire) { glDisable(GL_CULL_FACE); glDisable(GL_LIGHTING); glDisable(GL_LIGHT0); glDisable(GL_DEPTH_TEST); glDisable(GL_NORMALIZE); glDisable(GL_CULL_FACE); } else { glEnable(GL_CULL_FACE); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_DEPTH_TEST); glEnable(GL_NORMALIZE); glEnable(GL_CULL_FACE); } if (!wire) set_atom_color (mi, 0, False, alpha); if (do_bonds) for (i = 0; i < m->nbonds; i++) { const molecule_bond *b = &m->bonds[i]; const molecule_atom *from = get_atom (m->atoms, m->natoms, b->from); const molecule_atom *to = get_atom (m->atoms, m->natoms, b->to); if (wire) { glBegin(GL_LINES); glVertex3f(from->x, from->y, from->z); glVertex3f(to->x, to->y, to->z); glEnd(); polys++; } else { int faces = (mc->scale_down ? TUBE_FACES_2 : TUBE_FACES); # ifdef SMOOTH_TUBE int smooth = True; # else int smooth = False; # endif GLfloat thickness = 0.07 * b->strength; GLfloat cap_size = 0.03; if (thickness > 0.3) thickness = 0.3; polys += tube (from->x, from->y, from->z, to->x, to->y, to->z, thickness, cap_size, faces, smooth, (!do_atoms || do_shells), wire); } } if (!wire && do_atoms) for (i = 0; i < m->natoms; i++) { const molecule_atom *a = &m->atoms[i]; GLfloat size = atom_size (a); set_atom_color (mi, a, False, alpha); polys += sphere (mc, a->x, a->y, a->z, size, wire); } if (do_bbox && !transparent_p) { draw_bounding_box (mi); polys += 4; } mc->polygon_count += polys; }
/* Put the labels on the atoms. This can't be a part of the display list because of the games we play with the translation matrix. */ static void draw_labels (ModeInfo *mi) { molecule_configuration *mc = &mcs[MI_SCREEN(mi)]; int wire = MI_IS_WIREFRAME(mi); molecule *m = &mc->molecules[mc->which]; XFontStruct *xfont = (mc->scale_down ? mc->xfont2 : mc->xfont1); GLuint font_dlist = (mc->scale_down ? mc->font2_dlist : mc->font1_dlist); int i, j; if (!do_labels) return; if (!wire) glDisable (GL_LIGHTING); /* don't light fonts */ for (i = 0; i < m->natoms; i++) { molecule_atom *a = &m->atoms[i]; GLfloat size = atom_size (a); GLfloat m[4][4]; glPushMatrix(); if (!wire) set_atom_color (mi, a, True, 1); /* First, we translate the origin to the center of the atom. Then we retrieve the prevailing modelview matrix (which includes any rotation, wandering, and user-trackball-rolling of the scene. We set the top 3x3 cells of that matrix to be the identity matrix. This removes all rotation from the matrix, while leaving the translation alone. This has the effect of leaving the prevailing coordinate system perpendicular to the camera view: were we to draw a square face, it would be in the plane of the screen. Now we translate by `size' toward the viewer -- so that the origin is *just in front* of the ball. Then we draw the label text, allowing the depth buffer to do its work: that way, labels on atoms will be occluded properly when other atoms move in front of them. This technique (of neutralizing rotation relative to the observer, after both rotations and translations have been applied) is known as "billboarding". */ glTranslatef(a->x, a->y, a->z); /* get matrix */ glGetFloatv (GL_MODELVIEW_MATRIX, &m[0][0]); /* load rot. identity */ m[0][0] = 1; m[1][0] = 0; m[2][0] = 0; m[0][1] = 0; m[1][1] = 1; m[2][1] = 0; m[0][2] = 0; m[1][2] = 0; m[2][2] = 1; glLoadIdentity(); /* reset modelview */ glMultMatrixf (&m[0][0]); /* replace with ours */ glTranslatef (0, 0, (size * 1.1)); /* move toward camera */ glRasterPos3f (0, 0, 0); /* draw text here */ /* Before drawing the string, shift the origin to center the text over the origin of the sphere. */ glBitmap (0, 0, 0, 0, -string_width (xfont, a->label, 0) / 2, -xfont->descent, NULL); for (j = 0; j < strlen(a->label); j++) glCallList (font_dlist + (int)(a->label[j])); glPopMatrix(); } /* More efficient to always call glEnable() with correct values than to call glPushAttrib()/glPopAttrib(), since reading attributes from GL does a round-trip and stalls the pipeline. */ if (!wire) glEnable (GL_LIGHTING); }
static void assemble(void) { section *sec; atom *p; char *attr; int bss; final_pass=1; for(sec=first_section; sec; sec=sec->next) { source *lasterrsrc=NULL; int lasterrline=0; sec->pc=sec->org; attr=sec->attr; bss=0; while(*attr) { if(*attr++=='u') { bss=1; break; } } for(p=sec->first; p; p=p->next) { sec->pc=(sec->pc+p->align-1)/p->align*p->align; cur_src=p->src; cur_src->line=p->line; if(p->list&&p->list->atom==p) { p->list->sec=sec; p->list->pc=sec->pc; } if(p->type==INSTRUCTION) { dblock *db; cur_listing=p->list; db=eval_instruction(p->content.inst,sec,sec->pc); if(pic_check) do_pic_check(db->relocs); cur_listing=0; if(DEBUG) { if(db->size!=instruction_size(p->content.inst,sec,sec->pc)) ierror(0); } /*FIXME: sauber freigeben */ myfree(p->content.inst); p->content.db=db; p->type=DATA; } else if(p->type==DATADEF) { dblock *db; cur_listing=p->list; db=eval_data(p->content.defb->op,p->content.defb->bitsize,sec,sec->pc); if(pic_check) do_pic_check(db->relocs); cur_listing=0; /*FIXME: sauber freigeben */ myfree(p->content.defb); p->content.db=db; p->type=DATA; } else if(p->type==RORG) { sblock *sb; taddr space; if(eval_expr(p->content.roffs,&space,sec,sec->pc)) { space=sec->org+space-sec->pc; if (space>=0) { sb=new_sblock(number_expr(space),1,0); p->content.sb=sb; p->type=SPACE; } else general_error(20); /* rorg is lower than current pc */ } else general_error(30); /* expression must be constant */ } else if(p->type==DATA&&bss) { if(lasterrsrc!=p->src||lasterrline!=p->line) { general_error(31); /* initialized data in bss */ lasterrsrc=p->src; lasterrline=p->line; } } #ifdef HAVE_CPU_OPTS else if(p->type==OPTS) cpu_opts(p->content.opts); #endif else if(p->type==PRINTTEXT) printf("%s\n",p->content.ptext); else if (p->type==PRINTEXPR) { taddr val; eval_expr(p->content.pexpr,&val,sec,sec->pc); printf("%ld (0x%lx)\n",(long)val,(unsigned long)val); } sec->pc+=atom_size(p,sec,sec->pc); } } }
/* Constructs the GL shapes of the current molecule */ static void build_molecule (ModeInfo *mi) { molecule_configuration *mc = &mcs[MI_SCREEN(mi)]; int wire = cur_wire; int i; molecule *m = &mc->molecules[mc->which]; if (wire) { glDisable(GL_CULL_FACE); glDisable(GL_LIGHTING); glDisable(GL_LIGHT0); glDisable(GL_DEPTH_TEST); glDisable(GL_NORMALIZE); glDisable(GL_CULL_FACE); } else { glEnable(GL_CULL_FACE); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_DEPTH_TEST); glEnable(GL_NORMALIZE); glEnable(GL_CULL_FACE); } if (!wire) set_atom_color (mi, 0, False); if (do_bonds) for (i = 0; i < m->nbonds; i++) { molecule_bond *b = &m->bonds[i]; molecule_atom *from = get_atom(m->atoms, m->natoms, b->from, MI_IS_VERBOSE(mi)); molecule_atom *to = get_atom(m->atoms, m->natoms, b->to, MI_IS_VERBOSE(mi)); if (wire) { glBegin(GL_LINES); glVertex3f(from->x, from->y, from->z); glVertex3f(to->x, to->y, to->z); glEnd(); } else { int faces = (scale_down ? TUBE_FACES_2 : TUBE_FACES); # ifdef SMOOTH_TUBE int smooth = True; # else int smooth = False; # endif GLfloat thickness = 0.07 * b->strength; GLfloat cap_size = 0.03; if (thickness > 0.3) thickness = 0.3; tube (from->x, from->y, from->z, to->x, to->y, to->z, thickness, cap_size, faces, smooth, !do_atoms, wire); } } for (i = 0; i < m->natoms; i++) { molecule_atom *a = &m->atoms[i]; int i; if (!wire && do_atoms) { GLfloat size = atom_size (a); set_atom_color (mi, a, False); sphere (a->x, a->y, a->z, size, wire); } if (do_labels) { glPushAttrib (GL_LIGHTING_BIT | GL_DEPTH_BUFFER_BIT); glDisable (GL_LIGHTING); glDisable (GL_DEPTH_TEST); if (!wire) set_atom_color (mi, a, True); glRasterPos3f (a->x, a->y, a->z); { GLdouble mm[17], pm[17]; GLint vp[5]; GLdouble wx=-1, wy=-1, wz=-1; glGetDoublev (GL_MODELVIEW_MATRIX, mm); glGetDoublev (GL_PROJECTION_MATRIX, pm); glGetIntegerv (GL_VIEWPORT, vp); /* Convert 3D coordinates to window coordinates */ gluProject (a->x, a->y, a->z, mm, pm, vp, &wx, &wy, &wz); /* Fudge the window coordinates to center the string */ wx -= string_width (mc->xfont1, a->label) / 2; wy -= mc->xfont1->descent; /* Convert new window coordinates back to 3D coordinates */ gluUnProject (wx, wy, wz, mm, pm, vp, &wx, &wy, &wz); glRasterPos3f (wx, wy, wz); } for (i = 0; i < (int) strlen(a->label); i++) glCallList (mc->font1_dlist + (int)(a->label[i])); glPopAttrib(); } } if (do_bbox) draw_bounding_box (mi); if (do_titles && m->label && *m->label) print_title_string (mi, m->label, 10, MI_HEIGHT(mi) - 10, mc->xfont2->ascent + mc->xfont2->descent); }