void ClipLineInPlace( line_t **inout, vec3d_t norm, fp_t dist ) { fp_t d1, d2; int i; fp_t scl; vec3d_t clip; line_t *l; l = *inout; d1 = Vec3dDotProduct( norm, l->p1 ) - dist; d2 = Vec3dDotProduct( norm, l->p2 ) - dist; if ( d1 > 0.0 && d2 > 0.0 ) { FreeLine( l ); *inout = NULL; return; } if ( d1 <= 0.0 && d2 <= 0.0 ) { return; } scl = d1 / (d1-d2); for ( i = 0; i < 3; i++ ) { clip[i] = l->p1[i] + scl*(l->p2[i]-l->p1[i]); } l = NewLine(); if ( d1 <= 0.0 ) { Vec3dCopy( l->p1, (*inout)->p1 ); Vec3dCopy( l->p2, clip ); FreeLine( *inout ); *inout = l; } else { Vec3dCopy( l->p2, (*inout)->p2 ); Vec3dCopy( l->p1, clip ); FreeLine( *inout ); *inout = l; } }
void FreeLines( line_desc_t *p_lines ) { for( line_desc_t *p_line = p_lines; p_line != NULL; ) { line_desc_t *p_next = p_line->p_next; FreeLine( p_line ); p_line = p_next; } }
Line_Control *DeleteLine( Line_Control *line ) { Line_Control *next; next = (Line_Control *)line->Node.next; _Chain_Extract( &line->Node ); FreeLine( line ); return next; }
void FreeField(void) { void *SavePtr; while(Field!=NULL) { FreeLine(Field->line); SavePtr=Field->next; free(Field); Field=SavePtr; } }
/*--------------------------* * Merge two lines into one * *--------------------------*/ BOOL MergeLines(struct line_node *line, struct InstData *data) { struct line_node *next; char *newbuffer; LONG visual, oldvisual, line_nr; LONG emptyline = FALSE; LONG color = line->line.Color; UWORD flow = line->line.Flow; UWORD separator = line->line.Separator; ENTER(); data->HasChanged = TRUE; if(line->line.Length == 1) { emptyline = TRUE; color = line->next->line.Color; flow = line->next->line.Flow; separator = line->next->line.Separator; } visual = line->visual + line->next->visual; if((newbuffer = MyAllocPooled(data->mypool, line->line.Length+line->next->line.Length+1)) != NULL) { memcpy(newbuffer, line->line.Contents, line->line.Length-1); memcpy(newbuffer+line->line.Length-1, line->next->line.Contents, line->next->line.Length+1); MyFreePooled(data->mypool, line->line.Contents); MyFreePooled(data->mypool, line->next->line.Contents); if(emptyline == TRUE) { if(line->line.Styles != NULL) MyFreePooled(data->mypool, line->line.Styles); line->line.Styles = line->next->line.Styles; if(line->line.Colors != NULL) MyFreePooled(data->mypool, line->line.Colors); line->line.Colors = line->next->line.Colors; } else { UWORD *styles; UWORD *styles1 = line->line.Styles; UWORD *styles2 = line->next->line.Styles; UWORD *colors; UWORD *colors1 = line->line.Colors; UWORD *colors2 = line->next->line.Colors; UWORD length = 12; if(styles1 != NULL) length += *((long *)styles1-1) - 4; if(styles2 != NULL) length += *((long *)styles2-1) - 4; if((styles = MyAllocPooled(data->mypool, length)) != NULL) { unsigned short* t_styles = styles; unsigned short style = 0; SHOWVALUE(DBF_CLIPBOARD, length); SHOWVALUE(DBF_CLIPBOARD, styles); SHOWVALUE(DBF_CLIPBOARD, styles1); SHOWVALUE(DBF_CLIPBOARD, styles2); if(styles2 != NULL) { unsigned short* t_styles2 = styles2; while(*t_styles2++ == 1) { if(*t_styles2 > 0xff) style &= *t_styles2++; else style |= *t_styles2++; } } if(styles1 != NULL) { while(*styles1 != EOS) { if((*styles1 == line->line.Length) && ((~*(styles1+1) & style) == (*(styles1+1) ^ 0xffff))) { style &= *(styles1+1); styles1 += 2; } else { *styles++ = *styles1++; *styles++ = *styles1++; } } SHOWVALUE(DBF_CLIPBOARD, line->line.Styles); MyFreePooled(data->mypool, line->line.Styles); } if(styles2 != NULL) { while(*styles2 != EOS) { if((*styles2 == 1) && (!(*(styles2+1) & style))) { styles2 += 2; } else { *styles++ = *styles2++ + line->line.Length - 1; *styles++ = *styles2++; } } SHOWVALUE(DBF_CLIPBOARD, line->next->line.Styles); MyFreePooled(data->mypool, line->next->line.Styles); } *styles = EOS; line->line.Styles = t_styles; } length = 12; if(colors1 != NULL) length += *((long *)colors1-1) - 4; if(colors2 != NULL) length += *((long *)colors2-1) - 4; if((colors = MyAllocPooled(data->mypool, length)) != NULL) { UWORD *t_colors = colors; UWORD end_color = 0; SHOWVALUE(DBF_CLIPBOARD, length); SHOWVALUE(DBF_CLIPBOARD, colors); SHOWVALUE(DBF_CLIPBOARD, colors1); SHOWVALUE(DBF_CLIPBOARD, colors2); if(colors1 != NULL) { while(*colors1 < line->line.Length && *colors1 != 0xffff) { *colors++ = *colors1++; end_color = *colors1; *colors++ = *colors1++; } SHOWVALUE(DBF_CLIPBOARD, line->line.Colors); MyFreePooled(data->mypool, line->line.Colors); } if(end_color && (colors2 == NULL || *colors2 != 1)) { *colors++ = line->line.Length; *colors++ = 0; } if(colors2 != NULL) { if(*colors2 == 1 && *(colors2+1) == end_color) colors2 += 2; while(*colors2 != 0xffff) { *colors++ = *colors2++ + line->line.Length - 1; *colors++ = *colors2++; } SHOWVALUE(DBF_CLIPBOARD, line->next->line.Colors); MyFreePooled(data->mypool, line->next->line.Colors); } *colors = 0xffff; line->line.Colors = t_colors; } } line->line.Contents = newbuffer; line->line.Length = strlen(newbuffer); next = line->next; line->next = line->next->next; if(line->next != NULL) line->next->previous = line; oldvisual = line->visual; line->visual = VisualHeight(line, data); line->line.Color = color; line->line.Flow = flow; line->line.Separator = separator; FreeLine(next, data); line_nr = LineToVisual(line, data); // handle that we have to scroll up/down due to word wrapping // that occurrs when merging lines if(visual > line->visual) { data->totallines -= 1; if(line_nr+line->visual-1 < data->maxlines) { if(emptyline && line_nr > 0) { if(data->fastbackground) { ScrollUp(line_nr - 1, 1, data); SetCursor(data->CPos_X, data->actualline, TRUE, data); } else DumpText(data->visual_y+line_nr-1, line_nr-1, data->maxlines, TRUE, data); } else { if(data->fastbackground) ScrollUp(line_nr + line->visual - 1, 1, data); else DumpText(data->visual_y+line_nr+line->visual-1, line_nr+line->visual-1, data->maxlines, TRUE, data); } } } else if(visual < line->visual) { data->totallines += 1; if(line_nr+line->visual-1 < data->maxlines) ScrollDown(line_nr + line->visual - 2, 1, data); } if(!(emptyline && (line_nr + line->visual - 1 < data->maxlines))) { LONG t_oldvisual = oldvisual; LONG t_line_nr = line_nr; ULONG c = 0; while((--t_oldvisual) && (t_line_nr++ <= data->maxlines)) c = c + LineCharsWidth(line->line.Contents+c, data); while((c < line->line.Length) && (t_line_nr <= data->maxlines)) c = c + PrintLine(c, line, t_line_nr++, TRUE, data); } if(line_nr + oldvisual == 1 && line->visual == visual-1) { data->visual_y--; data->totallines -= 1; if(data->fastbackground) DumpText(data->visual_y, 0, visual-1, TRUE, data); else DumpText(data->visual_y, 0, data->maxlines, TRUE, data); } RETURN(TRUE); return(TRUE); } else { RETURN(FALSE); return(FALSE); } }
// // In case an allocated line shall be destroyed, call // this instead of ReleaseLine. The allocation strategy on // encoding and decoding might be different, and this is // the encoding release. virtual void DropLine(struct Line *line,UBYTE comp) { FreeLine(line,comp); }
void Step(void) { struct y_list *Input; struct y_list **Output; struct x_list *PrevLine; struct x_list *CurrLine; struct x_list *NextLine; struct y_list *NewYNode; struct x_list *NewXNode; struct x_list *NewLine; struct x_list **Add; void *SavePtr; struct x_list *ScanX; long Y; PrevLine=CurrLine=NextLine=NULL; NewLine=NULL; Count=NULL; Input=Field; Output=&Field; do { /* check if we can jump over empty space */ if(PrevLine==NULL && CurrLine==NULL && NextLine==NULL && NewLine==NULL) { if(Input==NULL) /* if there is no more spots then it is done */ break; NextLine=Input->line; Y=Input->y-1; Input=Input->next; } /* build list of neighbour counts for current line */ Base=&Count; for(ScanX=PrevLine; ScanX!=NULL; ScanX=ScanX->next) { Increment(ScanX->x-1); Increment(ScanX->x); Increment(ScanX->x+1); } Base=&Count; for(ScanX=CurrLine; ScanX!=NULL; ScanX=ScanX->next) { Increment(ScanX->x-1); Increment(ScanX->x+1); } Base=&Count; for(ScanX=NextLine; ScanX!=NULL; ScanX=ScanX->next) { Increment(ScanX->x-1); Increment(ScanX->x); Increment(ScanX->x+1); } while(*Output!=NULL && (*Output)->y<Y-1) Output=&((*Output)->next); /* build into field the new line which was created for previous line */ if(NewLine!=NULL) { if(PrevLine==NULL) { /* insert new record into Y list */ CheckPtr(NewYNode=malloc(sizeof(*NewYNode))); NewYNode->y=Y-1; NewYNode->next=*Output; NewYNode->line=NewLine; *Output=NewYNode; } else { FreeLine((*Output)->line); (*Output)->line=NewLine; } } else { if(PrevLine!=NULL) { /* delete record from Y list */ SavePtr=*Output; FreeLine((*Output)->line); *Output=(*Output)->next; free(SavePtr); } } /* create new line for current line */ NewLine=NULL; Add=
 ScanX=CurrLine; while(Count!=NULL) { while(ScanX!=NULL && ScanX->x<Count->x) ScanX=ScanX->next; /* apply rules of surviving and borning */ if(Count->cnt==3 || (Count->cnt==2 && ScanX!=NULL && Count->x==ScanX->x)) { CheckPtr(NewXNode=malloc(sizeof(*NewXNode))); NewXNode->next=NULL; NewXNode->x=Count->x; *Add=NewXNode; Add=&(NewXNode->next); } SavePtr=Count->next; free(Count); Count=SavePtr; } /* move to the next line */ PrevLine=CurrLine; CurrLine=NextLine; Y++; if(Input!=NULL && Input->y==Y+1) { NextLine=Input->line; Input=Input->next; } else { NextLine=NULL; } } while(1); }
// // Release the line as soon as it is no longer required - this // step goes after GetNextLine on the client. virtual void ReleaseLine(struct Line *line,UBYTE comp) { FreeLine(line,comp); }
void Init() { fp_t *v1, *v2; vec3d_t delta, norm, pos; fp_t dist; int i, j, k, num; vec3d_t norms[65000]; fp_t dists[65000]; polygon_t *polys[65000]; int out[256]; int num2; fp_t min, l; int best; int tmp; vec3d_t vup = { 0.0, 1.0, 0.0 }; polygon_t *poly; for ( i = 0; i < vertexnum; i++ ) { v1 = vertices[i]; // // setup planes // for ( j = 0; j < vertexnum; j++ ) { if ( polys[j] ) { FreePolygon( polys[j] ); polys[j] = NULL; } if ( i == j ) continue; v2 = vertices[j]; Vec3dSub( delta, v2, v1 ); Vec3dUnify2( norm, delta ); Vec3dScale( delta, 0.5, delta ); Vec3dAdd( pos, v1, delta ); dist = Vec3dInitPlane2( norm, pos ); Vec3dCopy( norms[j], norm ); dists[j] = dist; polys[j] = BasePolygonForPlane( norm, dist ); } // // clip each by each // #if 0 for ( j = 0; j < vertexnum; j++ ) { if ( j == i ) continue; for ( k = 0; k < vertexnum; k++ ) { if ( k == i || j == k ) continue; if ( !polys[k] ) continue; if ( polys[j] ) { ClipPolygonInPlace( &polys[j], norms[k], dists[k] ); } else break; } } #else for ( j = 0; j < vertexnum; j++ ) { if ( j == i ) continue; if ( !polys[j] ) continue; for ( k = 0; k < j; k++ ) { if ( k == i ) continue; if ( !polys[k] ) continue; if ( polys[j] ) ClipPolygonInPlace( &polys[j], norms[k], dists[k] ); else goto skip1; } for ( k = 0; k < j; k++ ) { if ( k == i ) continue; if ( !polys[k] ) continue; ClipPolygonInPlace( &polys[k], norms[j], dists[j] ); } skip1: } #endif printf( "v%d: ", i ); verts[i].edgenum = verts[i].trinum = 0; for ( j = 0; j < vertexnum; j++ ) { if ( i == j ) continue; if ( polys[j] ) { if ( verts[i].edgenum == MAX_EDGES_PER_VERTEX ) Error( "edge overflow.\n" ); verts[i].edges[verts[i].edgenum++] = j; printf( "%d ", j ); } } printf( ": %d\n", verts[i].edgenum ); } // } void Init2() { fp_t *v1, *v2; vec3d_t delta, norm, pos; fp_t dist; int i, j, k; vec3d_t norms[65000]; fp_t dists[65000]; line_t *lines[65000]; int out[256]; // polygon_t *poly; for ( i = 0; i < vertexnum; i++ ) { v1 = vertices[i]; // // setup planes // for ( j = 0; j < vertexnum; j++ ) { if ( lines[j] ) { // FreePolygon( polys[j] ); FreeLine( lines[j] ); lines[j] = NULL; } if ( i == j ) continue; v2 = vertices[j]; Vec3dSub( delta, v2, v1 ); Vec3dUnify2( norm, delta ); Vec3dScale( delta, 0.5, delta ); Vec3dAdd( pos, v1, delta ); dist = Vec3dInitPlane2( norm, pos ); Vec3dCopy( norms[j], norm ); dists[j] = dist; lines[j] = BaseLineForPlane( norm, dist ); } // // clip each by each // #if 0 for ( j = 0; j < vertexnum; j++ ) { if ( j == i ) continue; for ( k = 0; k < vertexnum; k++ ) { if ( k == i || j == k ) continue; if ( !polys[k] ) continue; if ( polys[j] ) { ClipPolygonInPlace( &polys[j], norms[k], dists[k] ); } else break; } } #else for ( j = 0; j < vertexnum; j++ ) { if ( j == i ) continue; if ( !lines[j] ) continue; for ( k = 0; k < j; k++ ) { if ( k == i ) continue; if ( !lines[k] ) continue; if ( lines[j] ) ClipLineInPlace( &lines[j], norms[k], dists[k] ); else goto skip1; } for ( k = 0; k < j; k++ ) { if ( k == i ) continue; if ( !lines[k] ) continue; ClipLineInPlace( &lines[k], norms[j], dists[j] ); } skip1: } #endif printf( "v%d: ", i ); verts[i].edgenum = verts[i].trinum = 0; for ( j = 0; j < vertexnum; j++ ) { if ( i == j ) continue; if ( lines[j] ) { if ( verts[i].edgenum == MAX_EDGES_PER_VERTEX ) Error( "edge overflow.\n" ); verts[i].edges[verts[i].edgenum++] = j; printf( "%d ", j ); } } printf( ": %d\n", verts[i].edgenum ); } // } bool_t TestEdge( int v, int vtest ) { int i; for ( i = 0; i < verts[v].edgenum; i++ ) if ( verts[v].edges[i] == vtest ) return true; return false; }
LONG CutBlock2(struct InstData *data, BOOL Clipboard, BOOL NoCut, struct marking *newblock, BOOL update) { LONG tvisual_y, error; LONG startx, stopx; LONG res = 0; struct line_node *startline, *stopline; ENTER(); startx = newblock->startx; stopx = newblock->stopx; startline = newblock->startline; stopline = newblock->stopline; //D(DBF_STARTUP, "CutBlock2: %ld-%ld %lx-%lx %ld %ld", startx, stopx, startline, stopline, Clipboard, NoCut); if(startline != stopline) { struct line_node *c_startline = startline->next; data->update = FALSE; if(Clipboard == TRUE) { if(InitClipboard(data, IFFF_WRITE)) { D(DBF_CLIPBOARD, "writing FORM"); error = PushChunk(data->iff, ID_FTXT, ID_FORM, IFFSIZE_UNKNOWN); SHOWVALUE(DBF_CLIPBOARD, error); ClipChars(startx, startline, startline->line.Length-startx, data); } else { Clipboard = FALSE; } } while(c_startline != stopline) { if(Clipboard == TRUE) { ClipLine(c_startline, data); } if(NoCut == FALSE) { struct line_node *cc_startline = c_startline; MyFreePooled(data->mypool, c_startline->line.Contents); if(c_startline->line.Styles != NULL) MyFreePooled(data->mypool, c_startline->line.Styles); data->totallines -= c_startline->visual; c_startline = c_startline->next; //D(DBF_STARTUP, "FreeLine %08lx", cc_startline); FreeLine(cc_startline, data); } else c_startline = c_startline->next; } if(Clipboard == TRUE) { if(stopx != 0) ClipChars(0, stopline, stopx, data); EndClipSession(data); } if(NoCut == FALSE) { startline->next = stopline; stopline->previous = startline; //D(DBF_STARTUP, "RemoveChars: %ld %ld %08lx %ld", startx, stopx, startline, startline->line.Length); if(startline->line.Length-startx-1 > 0) RemoveChars(startx, startline, startline->line.Length-startx-1, data); if(stopx != 0) RemoveChars(0, stopline, stopx, data); data->CPos_X = startx; data->actualline = startline; MergeLines(startline, data); } } else { if(Clipboard == TRUE) { if(InitClipboard(data, IFFF_WRITE)) { D(DBF_CLIPBOARD, "writing FORM"); error = PushChunk(data->iff, ID_FTXT, ID_FORM, IFFSIZE_UNKNOWN); SHOWVALUE(DBF_CLIPBOARD, error); ClipChars(startx, startline, stopx-startx, data); EndClipSession(data); } if(update == TRUE && NoCut == TRUE) { MarkText(data->blockinfo.startx, data->blockinfo.startline, data->blockinfo.stopx, data->blockinfo.stopline, data); goto end; } } if(NoCut == FALSE) { data->CPos_X = startx; RemoveChars(startx, startline, stopx-startx, data); if(update == TRUE) goto end; } } tvisual_y = LineToVisual(startline, data)-1; if(tvisual_y < 0 || tvisual_y > data->maxlines) { //D(DBF_STARTUP, "ScrollIntoDisplay"); ScrollIntoDisplay(data); tvisual_y = 0; } if(update == TRUE) { //D(DBF_STARTUP, "DumpText! %ld %ld %ld", data->visual_y, tvisual_y, data->maxlines); data->update = TRUE; DumpText(data->visual_y+tvisual_y, tvisual_y, data->maxlines, TRUE, data); } res = tvisual_y; end: RETURN(res); return res; }