714 lines
19 KiB
C++
714 lines
19 KiB
C++
#include "SCENE.h"
|
|
|
|
|
|
#define MaximumSearchDepth 1024
|
|
#define MinimumToAcceptForPoint 5
|
|
#define MinimumToAcceptForEnterVEC 10
|
|
u32 MinimumToAcceptForVEC = 150;
|
|
u32 MinimumLenght = 5;
|
|
|
|
float LinearityCoef = 3.0f;
|
|
float LinearityCoef_OL = 0.15f;
|
|
float LinearityCoef_SURF =1.0f;
|
|
float OptimizeErrorCoef = 50.f;
|
|
float OptimizeErrorCoef_PASS1 = 50.f;
|
|
float OptimizeErrorCoef_PASS2 = 20.f;
|
|
u32 ModeSurf = 0;
|
|
u32 DrawDot = 0;
|
|
u32 DrawDotZC = 0;
|
|
u32 Optimize = 0;
|
|
|
|
|
|
typedef struct LineVec_
|
|
{
|
|
s32 XBase;
|
|
s32 YBase;
|
|
s32 XEnd;
|
|
s32 YEnd;
|
|
s32 *CurrentPtr;
|
|
s32 Pitch;
|
|
MAP *CheckMap;
|
|
u32 TAG;
|
|
|
|
float Lenght;
|
|
float DevLenght;
|
|
|
|
u32 Strenght;
|
|
u32 Number;
|
|
}
|
|
LineVec;
|
|
|
|
typedef struct ScreenDot_
|
|
{
|
|
float X,Y;
|
|
float Error;
|
|
s16 LinkIndex;
|
|
|
|
s16 EdgeNumb;
|
|
s16 Edge1;
|
|
s16 Edge2;
|
|
|
|
} ScreenDot;
|
|
|
|
typedef struct ScreenLine_
|
|
{
|
|
s16 Index1;
|
|
s16 Index2;
|
|
s16 Valid;
|
|
u16 Angle;
|
|
} ScreenLine;
|
|
|
|
|
|
LineVec LineStack[MaximumSearchDepth+1];
|
|
|
|
#define MODE_SURFACE
|
|
int REC_VEC(LineVec *CurrentLine,u32 Depth)
|
|
{
|
|
if (Depth > MaximumSearchDepth) return 0;
|
|
LineStack[Depth] = *CurrentLine;
|
|
if (Depth)
|
|
{
|
|
if (ModeSurf)
|
|
{
|
|
CurrentLine->Lenght = CurrentLine->XEnd * CurrentLine->YEnd / 2.0f;
|
|
if (abs(CurrentLine->DevLenght - CurrentLine->Lenght) > LinearityCoef_SURF)
|
|
return 1;
|
|
} else
|
|
{
|
|
if (Depth > MinimumLenght)
|
|
{
|
|
float DX,DY,DEV;
|
|
DX = CurrentLine->XEnd - LineStack[Depth - MinimumLenght].XEnd;
|
|
DY = CurrentLine->YEnd - LineStack[Depth - MinimumLenght].YEnd;
|
|
CurrentLine->Lenght = DX * DX + DY*DY;
|
|
DEV =CurrentLine->DevLenght - LineStack[Depth - MinimumLenght].DevLenght;
|
|
CurrentLine->Lenght = sqrt(CurrentLine->Lenght);
|
|
if (DEV > CurrentLine->Lenght + LinearityCoef)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
} else
|
|
{
|
|
float DX,DY,DEV;
|
|
CurrentLine->Lenght = CurrentLine->XEnd * CurrentLine->XEnd + CurrentLine->YEnd*CurrentLine->YEnd;
|
|
CurrentLine->Lenght = sqrt(CurrentLine->Lenght);
|
|
DEV = CurrentLine->DevLenght;
|
|
if (DEV > CurrentLine->Lenght + LinearityCoef)
|
|
return 0;
|
|
}
|
|
}
|
|
} else
|
|
CurrentLine->Lenght = 0.0f;
|
|
|
|
|
|
*CurrentLine->CurrentPtr &= ~0x40000;
|
|
*CurrentLine->CurrentPtr |= 0x80000;
|
|
CurrentLine->Strenght += *CurrentLine->CurrentPtr & 0xffff ;
|
|
CurrentLine->Number++;
|
|
|
|
for (int PCounter = 0 ; PCounter < 8 ; PCounter++)
|
|
{
|
|
s32 X,Y;
|
|
X = (((PCounter & 1) << 1)&3) - 1;
|
|
Y = (((PCounter+1) & 2)&3) - 1;
|
|
if (PCounter > 3)
|
|
{
|
|
s32 K;
|
|
K = X;
|
|
X = (X - Y)/2;
|
|
Y = (K + Y)/2;
|
|
}
|
|
s32 *NewPtr,*OldPtr;
|
|
OldPtr = CurrentLine->CurrentPtr;
|
|
NewPtr = CurrentLine->CurrentPtr + X + Y * CurrentLine->Pitch;
|
|
if(*NewPtr & 0x40000)
|
|
{
|
|
float DevLe;
|
|
|
|
if (ModeSurf)
|
|
DevLe = X * (CurrentLine->YEnd * 2 + Y) / 2.0f;
|
|
else
|
|
DevLe = sqrt((float)(X * X + Y * Y));
|
|
|
|
CurrentLine->CurrentPtr = NewPtr;
|
|
CurrentLine->XEnd += X;
|
|
CurrentLine->YEnd += Y;
|
|
|
|
CurrentLine->DevLenght += DevLe;
|
|
if (REC_VEC(CurrentLine,Depth+1))
|
|
return 1;
|
|
CurrentLine->DevLenght -= DevLe;
|
|
CurrentLine->CurrentPtr = OldPtr;
|
|
CurrentLine->XEnd -= X;
|
|
CurrentLine->YEnd -= Y;
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
int SET_VEC(LineVec *CurrentLine,u32 Value)
|
|
{
|
|
*CurrentLine->CurrentPtr = Value;
|
|
for (int X = -1 ; X < 2 ; X ++)
|
|
for (int Y = -1 ; Y < 2 ; Y ++)
|
|
{
|
|
CurrentLine->CurrentPtr += X + Y * CurrentLine->Pitch;
|
|
if (*CurrentLine->CurrentPtr & 0x80000)
|
|
SET_VEC(CurrentLine,Value);
|
|
CurrentLine->CurrentPtr -= X + Y * CurrentLine->Pitch;
|
|
}
|
|
return 0;
|
|
}
|
|
int RESET_VEC(LineVec *CurrentLine)
|
|
{
|
|
*CurrentLine->CurrentPtr &= ~0x80000;
|
|
*CurrentLine->CurrentPtr |= 0x40000;
|
|
for (int X = -1 ; X < 2 ; X ++)
|
|
for (int Y = -1 ; Y < 2 ; Y ++)
|
|
{
|
|
CurrentLine->CurrentPtr += X + Y * CurrentLine->Pitch;
|
|
if (*CurrentLine->CurrentPtr & 0x80000)
|
|
RESET_VEC(CurrentLine);
|
|
CurrentLine->CurrentPtr -= X + Y * CurrentLine->Pitch;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
ScreenDot AllScreenDot[16384];
|
|
u32 AllScreenDotNP[16384];
|
|
u32 AllScreenDotNumber;
|
|
ScreenLine AllScreenLines[16384];
|
|
u32 AllScreenLinesNumber;
|
|
|
|
int Line_compare( const void *arg1, const void *arg2 )
|
|
{
|
|
ScreenLine *L1, *L2;
|
|
L1 = (ScreenLine *)arg1;
|
|
L2 = (ScreenLine *)arg2;
|
|
if (L1->Index1 < L2->Index1)
|
|
return -1;
|
|
else
|
|
if (L1->Index1 > L2->Index1)
|
|
return 1;
|
|
else
|
|
if (L1->Index2 < L2->Index2)
|
|
return -1;
|
|
if (L1->Index2 > L2->Index2)
|
|
return 1;
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
void COMPRESS_LINES()
|
|
{
|
|
if (!AllScreenLinesNumber) return;
|
|
for (int Counter = 0 ; Counter < AllScreenLinesNumber ; Counter++)
|
|
{
|
|
if (AllScreenLines[Counter].Index1 > AllScreenLines[Counter].Index2)
|
|
{
|
|
u32 SWAP;
|
|
SWAP = AllScreenLines[Counter].Index1;
|
|
AllScreenLines[Counter].Index1 = AllScreenLines[Counter].Index2;
|
|
AllScreenLines[Counter].Index2 = SWAP;
|
|
}
|
|
}
|
|
qsort(AllScreenLines,AllScreenLinesNumber,sizeof(ScreenLine),Line_compare);
|
|
ScreenLine*NewSL;
|
|
NewSL = AllScreenLines;
|
|
int Counter;
|
|
for (Counter = 0 ; Counter < AllScreenLinesNumber-1 ; Counter++)
|
|
{
|
|
if (AllScreenDot[AllScreenLines[Counter].Index1].LinkIndex != AllScreenDot[AllScreenLines[Counter].Index2].LinkIndex)
|
|
{
|
|
if (!((AllScreenDot[AllScreenLines[Counter].Index1].LinkIndex == AllScreenDot[AllScreenLines[Counter+1].Index1].LinkIndex) &&
|
|
(AllScreenDot[AllScreenLines[Counter].Index2].LinkIndex == AllScreenDot[AllScreenLines[Counter+1].Index2].LinkIndex)))
|
|
{
|
|
*(NewSL++) = AllScreenLines[Counter];
|
|
}
|
|
}
|
|
}
|
|
*(NewSL++) = AllScreenLines[Counter];
|
|
AllScreenLinesNumber = (u32)(NewSL - AllScreenLines);
|
|
}
|
|
|
|
float GET_LENGHT(ScreenDot *P1,ScreenDot *P2)
|
|
{
|
|
float Dx,Dy;
|
|
Dx = P1->X - P2->X;
|
|
Dy = P1->Y - P2->Y;
|
|
return (Dx * Dx + Dy * Dy);
|
|
}
|
|
|
|
void EVALUATE_ERROR()
|
|
{
|
|
for (int Counter = 0 ; Counter < AllScreenDotNumber ; Counter++)
|
|
{
|
|
ScreenDot *P1,*P2,*P3;
|
|
P2 = AllScreenDot + Counter;
|
|
if (AllScreenDot[Counter].EdgeNumb == 2)
|
|
{
|
|
if (AllScreenLines[P2->Edge1].Index1 == Counter)
|
|
P1 = AllScreenDot + AllScreenLines[P2->Edge1].Index2;
|
|
else
|
|
P1 = AllScreenDot + AllScreenLines[P2->Edge1].Index1;
|
|
if (AllScreenLines[P2->Edge2].Index1 == Counter)
|
|
P3 = AllScreenDot + AllScreenLines[P2->Edge2].Index2;
|
|
else
|
|
P3 = AllScreenDot + AllScreenLines[P2->Edge2].Index1;
|
|
float LEr1,LEr2,LEr3;
|
|
LEr1 = sqrt(GET_LENGHT(P1,P2));
|
|
LEr2 = sqrt(GET_LENGHT(P2,P3));
|
|
LEr3 = sqrt(GET_LENGHT(P1,P3));
|
|
LEr1 = abs(LEr1 + LEr2 - LEr3);
|
|
/* P2->Error = LEr1 + LEr2 - LEr3 + 0.001f;
|
|
P2->Error *= P2->Error;*/
|
|
LEr1 = (P2->X - P1->X) * (P2->Y + P1->Y) / 2.0f;
|
|
LEr1 += (P3->X - P2->X) * (P3->Y + P2->Y) / 2.0f;
|
|
LEr1 += (P1->X - P3->X) * (P1->Y + P3->Y) / 2.0f;
|
|
P2->Error = OptimizeErrorCoef * abs(LEr1)/sqrt(GET_LENGHT(P1,P3)) + 0.000001f;
|
|
P2->Error *= P2->Error ;//*/
|
|
/* P2->Error = OptimizeErrorCoef * LEr1 + 0.00001f;
|
|
P2->Error *= P2->Error ;*/
|
|
|
|
} else
|
|
P2->Error = 1000.0f;
|
|
}
|
|
}
|
|
|
|
void LINE_MERGE()
|
|
{
|
|
EVALUATE_ERROR();
|
|
//return;
|
|
for (int Counter = 0 ; Counter < AllScreenLinesNumber ; Counter++)
|
|
{
|
|
if (AllScreenLines[Counter].Index1 > AllScreenLines[Counter].Index2)
|
|
{
|
|
u32 SWAP;
|
|
SWAP = AllScreenLines[Counter].Index1;
|
|
AllScreenLines[Counter].Index1 = AllScreenLines[Counter].Index2;
|
|
AllScreenLines[Counter].Index2 = SWAP;
|
|
}
|
|
}
|
|
|
|
for (int Counter = 0 ; Counter < AllScreenLinesNumber ; Counter++)
|
|
{
|
|
float Dist;
|
|
ScreenDot *P1,*P2,*Swp;
|
|
if ((AllScreenDot[AllScreenLines[Counter].Index1].LinkIndex == AllScreenLines[Counter].Index1) &&
|
|
(AllScreenDot[AllScreenLines[Counter].Index2].LinkIndex == AllScreenLines[Counter].Index2))
|
|
{
|
|
P1 = AllScreenDot + AllScreenLines[Counter].Index1;
|
|
P2 = AllScreenDot + AllScreenLines[Counter].Index2;
|
|
if (P1 > P2)
|
|
{
|
|
Swp = P1;P1 = P2; P2 = Swp;
|
|
}
|
|
if (P1 != P2)
|
|
{
|
|
Dist = GET_LENGHT(P1,P2);
|
|
if ((Dist < 64) && (P2->EdgeNumb == 1) && (P1->EdgeNumb == 1))
|
|
{
|
|
AllScreenLines[Counter].Index2 = AllScreenLines[Counter].Index1;
|
|
AllScreenLines[Counter].Valid = 0;
|
|
} else//*/
|
|
if (
|
|
(P2->Error < 1000.0f) &&
|
|
(P1->Error < 1000.0f) //||
|
|
//(Dist < 5)
|
|
)
|
|
{
|
|
float Div;
|
|
//if ((P1 != P2) && ((P2->EdgeNumb == 2) || (P1->EdgeNumb == 2)/*&& (P1->EdgeNumb == 2)*/))
|
|
{
|
|
Div = 1.0f / (P1->Error + P2->Error);
|
|
P1->X = (P1->X * P1->Error + P2->X * P2->Error) * Div;
|
|
P1->Y = (P1->Y * P1->Error + P2->Y * P2->Error) * Div;
|
|
P1->Error = P1->Error + P2->Error + 100000.0f;
|
|
P2->Error = P1->Error + P2->Error + 100000.0f;
|
|
P2->LinkIndex = P1 - AllScreenDot;
|
|
P2->EdgeNumb = 0;
|
|
AllScreenLines[Counter].Index2 = AllScreenLines[Counter].Index1;
|
|
AllScreenLines[Counter].Valid = 0;//*/
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
void VEC_COMPRESS()
|
|
{
|
|
ScreenDot *NewSD;
|
|
ScreenLine*NewSL;
|
|
|
|
if (!AllScreenLinesNumber) return;
|
|
if (!AllScreenDotNumber) return;
|
|
|
|
NewSD = AllScreenDot;
|
|
for (int Counter = 0 ; Counter < AllScreenDotNumber ; Counter++)
|
|
{
|
|
u32 K;
|
|
K = Counter;
|
|
while (AllScreenDot[K].LinkIndex != K ) {K = AllScreenDot[K].LinkIndex;};
|
|
AllScreenDot[Counter].LinkIndex = K;
|
|
AllScreenDot[Counter].EdgeNumb = 0;
|
|
}
|
|
for (int Counter = 0 ; Counter < AllScreenLinesNumber ; Counter++)
|
|
{
|
|
AllScreenLines[Counter].Index1 = AllScreenDot[AllScreenLines[Counter].Index1].LinkIndex;
|
|
AllScreenLines[Counter].Index2 = AllScreenDot[AllScreenLines[Counter].Index2].LinkIndex;
|
|
AllScreenDot[AllScreenDot[AllScreenLines[Counter].Index1].LinkIndex].EdgeNumb++;
|
|
AllScreenDot[AllScreenDot[AllScreenLines[Counter].Index2].LinkIndex].EdgeNumb++;
|
|
}
|
|
|
|
for (int Counter = 0 ; Counter < AllScreenDotNumber ; Counter++)
|
|
{
|
|
ScreenDot *P1,*P2;
|
|
P1 = &AllScreenDot[Counter];
|
|
P2 = &AllScreenDot[AllScreenDot[Counter].LinkIndex];
|
|
AllScreenDotNP[Counter] = (u32)(NewSD - AllScreenDot);
|
|
|
|
if ((P1 == P2) && P1->EdgeNumb)
|
|
{
|
|
/* Create New Entry */
|
|
*NewSD = *P1;
|
|
NewSD ->LinkIndex = (u32)(NewSD - AllScreenDot);
|
|
NewSD -> EdgeNumb = 0;
|
|
NewSD++;
|
|
}
|
|
}
|
|
AllScreenDotNumber = (u32)(NewSD - AllScreenDot);
|
|
|
|
for (int Counter = 0 ; Counter < AllScreenDotNumber ; Counter++)
|
|
{
|
|
AllScreenDot[Counter].LinkIndex = Counter;
|
|
}
|
|
COMPRESS_LINES();
|
|
|
|
NewSL = AllScreenLines;
|
|
for (int Counter = 0 ; Counter < AllScreenLinesNumber ; Counter++)
|
|
{
|
|
NewSL->Index1 = AllScreenDotNP[AllScreenLines[Counter].Index1];
|
|
NewSL->Index2 = AllScreenDotNP[AllScreenLines[Counter].Index2];
|
|
|
|
if ((NewSL->Index1 != NewSL->Index2) && AllScreenLines[Counter].Valid)
|
|
{
|
|
NewSL->Valid = AllScreenLines[Counter].Valid;
|
|
if (AllScreenDot[NewSL->Index1].EdgeNumb==0)
|
|
AllScreenDot[NewSL->Index1].Edge1 = (u32)(NewSL - AllScreenLines);
|
|
else
|
|
if (AllScreenDot[NewSL->Index1].EdgeNumb==1)
|
|
AllScreenDot[NewSL->Index1].Edge2 = (u32)(NewSL - AllScreenLines);
|
|
|
|
if (AllScreenDot[NewSL->Index2].EdgeNumb==0)
|
|
AllScreenDot[NewSL->Index2].Edge1 = (u32)(NewSL - AllScreenLines);
|
|
else
|
|
if (AllScreenDot[NewSL->Index2].EdgeNumb==1)
|
|
AllScreenDot[NewSL->Index2].Edge2 = (u32)(NewSL - AllScreenLines);
|
|
AllScreenDot[NewSL->Index1].EdgeNumb ++;
|
|
AllScreenDot[NewSL->Index2].EdgeNumb ++;
|
|
NewSL++;
|
|
}
|
|
}
|
|
AllScreenLinesNumber = (u32)(NewSL - AllScreenLines);
|
|
}
|
|
|
|
|
|
|
|
void VECTORIZE_MAP(MAP *MapSRC,MAP *MapDST)
|
|
{
|
|
u32 TAG = 1;
|
|
START_RASTER(Vectorization);
|
|
SET_BORDER(MapSRC,10,0);
|
|
for (int X = 1 ; X < MapSRC->SX-1 ; X++)
|
|
for (int Y = 1 ; Y < MapSRC->SY-1 ; Y++)
|
|
{
|
|
s32 *LV;
|
|
LV = (MapSRC->GetBase() + X + MapSRC->PITCH * Y);
|
|
if ((*LV & 0xffff) < MinimumToAcceptForPoint)
|
|
*LV = 0;
|
|
if ((DrawDotZC) && (*LV & 0x40000))
|
|
{
|
|
LV = (MapDST->GetBase() + X + MapDST->PITCH * Y);
|
|
*LV = 0xff00;
|
|
}//*/
|
|
|
|
}
|
|
AllScreenDotNumber = 0;
|
|
AllScreenLinesNumber = 0;
|
|
for (int X = 1 ; X < MapSRC->SX-1 ; X++)
|
|
{
|
|
for (int Y = 1 ; Y < MapSRC->SY-1 ; Y++)
|
|
{
|
|
LineVec LV;
|
|
LV.CurrentPtr = MapSRC->GetBase() + X + MapSRC->PITCH * Y;
|
|
if ((*LV.CurrentPtr & 0x40000)
|
|
&& ((*LV.CurrentPtr & 0xffff)> MinimumToAcceptForEnterVEC)
|
|
)
|
|
{
|
|
LV.Pitch = MapSRC->PITCH;
|
|
LV.XEnd = LV.XBase = X;
|
|
LV.YEnd = LV.YBase = Y;
|
|
LV.XEnd = 0;
|
|
LV.YEnd = 0;
|
|
LV.TAG = TAG++;
|
|
LV.CheckMap = MapSRC;
|
|
LV.Strenght = 0;
|
|
LV.Number = 0;
|
|
LV.Lenght = 0.0f;
|
|
LV.DevLenght = 0.0f;
|
|
|
|
REC_VEC(&LV,0);
|
|
LV.XEnd += X;
|
|
LV.YEnd += Y;
|
|
LV.Strenght <<= 2;
|
|
if ((LV.Strenght < MinimumToAcceptForVEC<<2) || (LV.Number<MinimumLenght))
|
|
{
|
|
SET_VEC(&LV,0);
|
|
}
|
|
else
|
|
//LV.Strenght /= LV.Number;
|
|
{
|
|
u32 Color;
|
|
TAG++;
|
|
Color = 0;
|
|
if (TAG & 1) Color |= 0x80;
|
|
if (TAG & 2) Color |= 0x80<<8;
|
|
if (TAG & 4) Color |= 0x80<<16;
|
|
if (TAG & 8) Color |= 0x40;
|
|
if (TAG & 16) Color |= 0x40<<8;
|
|
if (TAG & 32) Color |= 0x40<<16;
|
|
Color |= 0x1000000 ;
|
|
// Color = 0x100ffff;
|
|
SET_VEC(&LV,Color);
|
|
#define BitcRadius 1
|
|
AllScreenLines[AllScreenLinesNumber].Index1 = AllScreenDotNumber;
|
|
AllScreenLines[AllScreenLinesNumber].Index2 = AllScreenDotNumber+1;
|
|
AllScreenLines[AllScreenLinesNumber].Valid = 1;
|
|
if ((LV.Strenght < MinimumToAcceptForVEC<<2) /*|| (LV.Number<=1)*/)
|
|
{
|
|
//SET_VEC(&LV,0);
|
|
AllScreenLines[AllScreenLinesNumber].Valid = 2;
|
|
} else
|
|
{
|
|
if (AllScreenLinesNumber < 16383)
|
|
AllScreenLinesNumber++;
|
|
|
|
AllScreenDot[AllScreenDotNumber].X = X + 0.5f;
|
|
AllScreenDot[AllScreenDotNumber].Y = Y + 0.5f;
|
|
AllScreenDot[AllScreenDotNumber].Error = 0.0001f;//*LV.CurrentPtr & 0xffff;
|
|
AllScreenDot[AllScreenDotNumber].LinkIndex = AllScreenDotNumber;
|
|
AllScreenDot[AllScreenDotNumber].EdgeNumb = 1;
|
|
if (AllScreenDotNumber < 16383)
|
|
AllScreenDotNumber++;
|
|
|
|
|
|
AllScreenDot[AllScreenDotNumber].X = LV.XEnd + 0.5f;
|
|
AllScreenDot[AllScreenDotNumber].Y = LV.YEnd + 0.5f;
|
|
AllScreenDot[AllScreenDotNumber].Error = 0.0001f;//*(MapSRC->GetBase() + LV.XEnd + MapSRC->PITCH * LV.YEnd)& 0xffff;
|
|
AllScreenDot[AllScreenDotNumber].LinkIndex = AllScreenDotNumber;
|
|
AllScreenDot[AllScreenDotNumber].EdgeNumb = 1;
|
|
if (AllScreenDotNumber < 16383)
|
|
AllScreenDotNumber++;
|
|
}
|
|
}
|
|
}
|
|
*LV.CurrentPtr &= ~0x40000;
|
|
}
|
|
}
|
|
|
|
for (int X = 1 ; X < MapSRC->SX-1 ; X++)
|
|
for (int Y = 1 ; Y < MapSRC->SY-1 ; Y++)
|
|
{
|
|
s32 *LV;
|
|
LV = (MapSRC->GetBase() + X + MapSRC->PITCH * Y);
|
|
if (*LV & 0x1000000)
|
|
{
|
|
*LV &= ~(0x80000+0x40000);
|
|
*LV |= 0x40000;
|
|
}//*/
|
|
|
|
}
|
|
|
|
STOP_RASTER(Vectorization);
|
|
return;
|
|
/* Add line from lenght 0 */
|
|
SET(MapSRC,0);
|
|
/* PLOT w/ dot number */
|
|
for (int C = 0 ; C < AllScreenDotNumber ; C++)
|
|
{
|
|
s32 *Ptr;
|
|
Ptr = MapSRC->GetBase() + (s32)AllScreenDot[C].X + MapSRC->PITCH * (s32)AllScreenDot[C].Y;
|
|
*Ptr = C + 1;
|
|
}
|
|
|
|
for (int C = 0 ; C < AllScreenDotNumber ; C++)
|
|
{
|
|
s32 *Ptr;
|
|
u32 Counter;
|
|
for (int PCounter = 0 ; PCounter < 8 ; PCounter++)
|
|
{
|
|
s32 X,Y;
|
|
X = (((PCounter & 1) << 1)&3) - 1;
|
|
Y = (((PCounter+1) & 2)&3) - 1;
|
|
if (PCounter > 3)
|
|
{
|
|
s32 K;
|
|
K = X;
|
|
X = (X - Y)/2;
|
|
Y = (K + Y)/2;
|
|
}
|
|
Ptr = MapSRC->GetBase() + (s32)AllScreenDot[C].X + X + MapSRC->PITCH * ((s32)AllScreenDot[C].Y + Y);
|
|
if (*Ptr)
|
|
{
|
|
AllScreenLines[AllScreenLinesNumber].Index1 = C;
|
|
AllScreenLines[AllScreenLinesNumber].Index2 = *Ptr - 1;
|
|
AllScreenLines[AllScreenLinesNumber].Valid = 1;
|
|
if (AllScreenLinesNumber < 16383) AllScreenLinesNumber++;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!AllScreenLinesNumber) return;
|
|
if (!AllScreenDotNumber) return;
|
|
/* Optimize */
|
|
|
|
VEC_COMPRESS();
|
|
|
|
for (int Counter = 0 ; Counter < AllScreenLinesNumber ; Counter++)
|
|
{
|
|
ScreenDot *P1,*P2;
|
|
P1 = &AllScreenDot[AllScreenDot[AllScreenLines[Counter].Index1].LinkIndex];
|
|
P2 = &AllScreenDot[AllScreenDot[AllScreenLines[Counter].Index2].LinkIndex];
|
|
DrawLine(MapDST,P1->X,P1->Y,P2->X,P2->Y,0x8000);
|
|
}
|
|
|
|
|
|
u32 AllScreenLinesNumberSave,AllScreenDotNumberSave;
|
|
AllScreenLinesNumberSave = AllScreenDotNumberSave = 0;
|
|
|
|
if (Optimize)
|
|
{
|
|
OptimizeErrorCoef = OptimizeErrorCoef_PASS1;
|
|
while ( (AllScreenLinesNumberSave != AllScreenLinesNumber) &&
|
|
(AllScreenDotNumberSave != AllScreenDotNumber))
|
|
{
|
|
AllScreenLinesNumberSave = AllScreenLinesNumber;
|
|
AllScreenDotNumberSave = AllScreenDotNumber;
|
|
LINE_MERGE();
|
|
VEC_COMPRESS();
|
|
};//*/
|
|
AllScreenLinesNumberSave = AllScreenDotNumberSave = 0;
|
|
OptimizeErrorCoef = OptimizeErrorCoef_PASS2;
|
|
while ( (AllScreenLinesNumberSave != AllScreenLinesNumber) &&
|
|
(AllScreenDotNumberSave != AllScreenDotNumber))
|
|
{
|
|
AllScreenLinesNumberSave = AllScreenLinesNumber;
|
|
AllScreenDotNumberSave = AllScreenDotNumber;
|
|
LINE_MERGE();
|
|
VEC_COMPRESS();
|
|
};//*/
|
|
}
|
|
|
|
//VEC_COMPRESS();
|
|
/* Render */
|
|
EVALUATE_ERROR();
|
|
/* for (int Counter = 0 ; Counter < AllScreenDotNumber ; Counter++)
|
|
{
|
|
AllScreenDot[Counter].X += (u32)(rand()% 4);
|
|
AllScreenDot[Counter].Y += (u32)(rand()% 4);
|
|
} //*/
|
|
|
|
|
|
SET(MapDST,0xffffff);
|
|
for (int Counter = 0 ; Counter < AllScreenLinesNumber ; Counter++)
|
|
{
|
|
ScreenDot *P1,*P2;
|
|
P1 = &AllScreenDot[AllScreenDot[AllScreenLines[Counter].Index1].LinkIndex];
|
|
P2 = &AllScreenDot[AllScreenDot[AllScreenLines[Counter].Index2].LinkIndex];
|
|
u32 Color = 0;
|
|
if (Counter & 1) Color |= 0x80;
|
|
if (Counter & 2) Color |= 0x80<<8;
|
|
if (Counter & 4) Color |= 0x80<<16;
|
|
if (Counter & 8) Color |= 0x40;
|
|
if (Counter & 16) Color |= 0x40<<8;
|
|
if (Counter & 32) Color |= 0x40<<16;
|
|
Color = 0;
|
|
if (AllScreenLines[Counter].Valid == 1)
|
|
DrawLine(MapDST,P1->X,P1->Y,P2->X,P2->Y,Color);
|
|
else
|
|
DrawLine(MapDST,P1->X,P1->Y,P2->X,P2->Y,Color);//*/
|
|
}
|
|
void DrawCross(MAP *image, POINT p, u32 color, int len, char orient = 3);
|
|
for (int Counter = 0 ; Counter < AllScreenDotNumber ; Counter++)
|
|
{
|
|
if (DrawDot)
|
|
{
|
|
/* if (AllScreenDot[Counter].EdgeNumb != 2)
|
|
{
|
|
POINT p;
|
|
p.x = AllScreenDot[Counter].X;
|
|
p.y = AllScreenDot[Counter].Y;
|
|
u32 Color;
|
|
Color = AllScreenDot[Counter].Error * 10;
|
|
if (Color > 255) Color = 255;
|
|
Color |= Color<<8;
|
|
Color |= Color<<8;
|
|
DrawQuad( MapDST,p.x-2,p.y-2,p.x+2,p.y+2,Color,1);
|
|
|
|
// DrawCross(MapDST,p,Color, 1);
|
|
} //*/
|
|
if (AllScreenDot[Counter].EdgeNumb == 2)
|
|
{
|
|
POINT p;
|
|
p.x = AllScreenDot[Counter].X;
|
|
p.y = AllScreenDot[Counter].Y;
|
|
u32 Color;
|
|
Color = AllScreenDot[Counter].Error * 10;
|
|
if (Color > 255) Color = 255;
|
|
Color |= Color<<8;
|
|
Color |= Color<<8;
|
|
//DrawQuad( MapDST,p.x-2,p.y-2,p.x+2,p.y+2,Color,1);
|
|
DrawCross(MapDST,p,Color, 1);
|
|
}
|
|
if (AllScreenDot[Counter].EdgeNumb == 0)
|
|
{
|
|
POINT p;
|
|
p.x = AllScreenDot[Counter].X;
|
|
p.y = AllScreenDot[Counter].Y;
|
|
u32 Color;
|
|
Color = AllScreenDot[Counter].Error * 10;
|
|
Color = 255;
|
|
Color |= Color<<8;
|
|
Color |= Color<<8;
|
|
//DrawQuad( MapDST,p.x-2,p.y-2,p.x+2,p.y+2,Color,1);
|
|
DrawCross(MapDST,p,Color, 1);
|
|
} /*else
|
|
|
|
if (AllScreenDot[Counter].EdgeNumb > 2)
|
|
{
|
|
POINT p;
|
|
p.x = AllScreenDot[Counter].X;
|
|
p.y = AllScreenDot[Counter].Y;
|
|
DrawCross(MapDST,p,0xff0000, 1);
|
|
} /*else
|
|
if (AllScreenDot[Counter].EdgeNumb)
|
|
{
|
|
POINT p;
|
|
p.x = AllScreenDot[Counter].X;
|
|
p.y = AllScreenDot[Counter].Y;
|
|
DrawCross(MapDST,p, 0xffffff , 1);
|
|
} //*/
|
|
}
|
|
}//*/
|
|
char DEG[1024];
|
|
sprintf(DEG,"NPE:%d NLE:%d",AllScreenDotNumber,AllScreenLinesNumber);
|
|
DRawTEXT_Soft_B((u8*)DEG,(u32*)MapDST->GetBase(),0,40,MapDST->SX, MapDST->SY, 0xff0000);
|
|
|
|
STOP_RASTER(Vectorization);
|
|
|
|
}
|