Forum Postings 2001 April

collected and (very little) formatted by addie walti


The start of a thread is on top right below the title

how to fix CCline corruption
Transparent Textures (of the car)
Unused Jam Ids
cameras (scenery not showing up)
No pit side determination

gp2/gp3 palette

end of file


Anyone know how to fix CCline corruption????

Posted by Chris Neira from

I have set the CCline but it appears erratic and corrupted when I use my track, and I do not know why... ...Any surgestions?

Posted by Speedee from

Hi Chris,
the CC line is very tricky to implement. The inbuilt functions for it in the TE are only experimental, and do not work correctly.
To create a good CC line you need to create a section of the line and then test it in the game to see that it is in the right spot (the TE does not show the CC line position correctly).
Keep adding CC line sections & testing/adjusting until finished.
Note that the CC line should follow the optimal driving line.

WARNING: The CC line should be done last. This is because if the track is changed in any way it throws out the CC line, and may even make the track unloadable. If this happens, then the only solution is to remove the CC line completely and start again.


Posted by addie from

yes, cc-line editing means pretty much of work, where you need a good and stable installation of gp3 and TE where you can switch tasks anytime.

i wrote a guide about this subject, which is published on my TEIC-pages

follow "writings". cc-line editing for gp3 is the same as for gp2, with the small difference, gp3 freezes if the cc-line is going haywire "too much", so you have to be more careful as with gp2 ...


Posted by SDI from

This is how GP3 creates the CC line:





- val6

- val8


GP3Seg *pFirstSeg = ...;
int length, radius, radius_diff_avg;
short startx = 0, startangle = 0;
short shiftx = 0, shiftangle = 0;

void CreateCCLine(BYTE *pCCLineData)
WORD *pSector = (WORD*)pCCLineData;
GP3Car *pCar = array_of_all_carstructs;
GP3Seg *pSeg = pFirstSeg;

pCar-pSeg = pSeg;
pCar-wSpeedAngleZ = pSeg-wAngleZ;

if (isoff(pSector[0], 0x800) && ison(pSector[0], 0x8000))
pCar-wSegPosX = pSector[1];

for (;;) {
WORD *pCurSector = pSector;
WORD flags = ParseCCLineSector(&pSector); // also updates pSector

if (flags == 0)
break; // end of ccline data
if (isallon(flags, 0x8800)) {
pCar-wSegPosX = startx;
pCar-wSpeedAngleZ = startangle;
if (radius == 0)
pCar-wSpeedAngleZ += shiftangle;
if (isoff(flags, 0x800) && ison(flags, 0x8000)) {
pCurSector[1] = pCar-wSegPosX;
pCurSector[2] = pCar-wSpeedAngleZ;


for (i=0; ilength; i++) {
// store it
pSeg-wCCLineRAngle = pCar-wSpeedAngleZ - pSeg-wAngleZ;
pSeg-wCCLine = pCar-wSegPosX;
// get next segment
pSeg++; // next segment
if (pSeg = pAfterLastSeg) {
if (pSeg = pFirstPitSeg) {
if (pSeg = pAfterLastPitSeg)
pSeg = pAfterLastPitSeg-1;
} else
pSeg -= num_track_segs; // cyclic
pCar-pSeg = pSeg;
ProcessCCLineSegment(pCar, pSeg);
if (i length-1 && radius != 0 && radius_diff_avg != 0) {
radius += radius_diff_avg;

WORD ParseCCLineSector(WORD **ppSector) {
WORD val1, val2, val3, val4, val5, val6, val7, val8;
WORD *pSector = *ppSector;

val1 = *pSector++;
if (val1 != 0) {
length = val1 & 0x7ff;

if (ison(val1, 0x8000)) {
val2 = startx = *pSector++;
val3 = startangle = *pSector++;

val4 = *pSector++;

radius_diff_avg = 0;

val5 = *pSector++;
radius = val5;
if (ison(val1, 0x4000)) {
val6 = *pSector++;
radius = (val5 16) | val6;
if (isoff(val1, 0x1000))
radius = 3;

if (ison(val1, 0x2000)) {
int radius2;

val7 = *pSector++;
radius2 = val7;
if (ison(val1, 0x4000)) {
val8 = *pSector++;
radius2 = (val7 16) | val8;
if (isoff(val1, 0x1000))
radius2 = 3;
radius_diff_avg = (radius2 - radius) / length;

if (radius != 0) {
shiftx = val4 2;
shiftangle = 0;
} else {
shiftx = 0;
shiftangle = val4;

return val1;

////////////////////////////////////////////////////////////////////// //

int tmpX = 0, tmpY = 0;
int tmp1 = 0, tmp2 = 0, tmp3 = 0, tmp4 = 0,
tmp5 = 0, tmp6 = 0, tmp7 = 0, tmp8 = 0;

void ProcessCCLineSector(GP3Car *pCar)
int x, y, r;
GP3Seg *pSeg = pCar-pSeg;

pCar-wSegPosY = (pCar-wSegPosX * pSeg-wAngleZChangeMulPI) / 0x8000;

y = (int)pCar-wSegPosY;
x = (int)pCar-wSegPosX;

tmp3 = Cos(pSeg-wAngleZ);
tmp4 = Sin(pSeg-wAngleZ);

tmpY = (pSeg-wPosY 3) | (pSeg-bFineOffset_21 4) // segment ypos
+ (y * tmp3 - x * tmp4) 14 // rotated segment sub ypos
+ shiftx * Cos(pCar-wSpeedAngleZ);

tmpX = (pSeg-wPosX 3) | (pSeg-bFineOffset_21 & 7) // segment xpos
+ (y * tmp4 + x * tmp3) 14 // rotated segment sub xpos
+ shiftx * Sin(pCar-wSpeedAngleZ);

r = radius;
if (r != 0) {
if (r 0)
r = -r;
tmp3 = pCar-wSpeedAngleZ;
if (radius = 0)
tmp3 += 0x4000;
tmp3 -= 0x4000;
CCLine_Unk(); // in: tmp3. out: tmp3, tmp4
tmpX += MulDiv(tmp4, r, 130);
tmpY += MulDiv(tmp3, r, 130);

void HandleChangedRadius(GP3Car *pCar)
short a = pCar-wSpeedAngleZ;
int diff = radius_diff_avg;

if (radius 0) {
a -= 0x4000; // sub 90 deg
diff = -diff;
} else
a += 0x4000; // add 90 deg
tmpX += diff * Sin(a);
tmpY += diff * Cos(a);

void ProcessCCLineSegment(GP3Car *pCar, GP3Seg *pSeg)
short a1;
int t1, t2, t3, t4;

// normalise
tmp5 = tmpX - (pSeg-wPosX 3) | (pSeg-bFineOffset_21 & 7);
tmp6 = tmpY - (pSeg-wPosY 3) | (pSeg-bFineOffset_21 4);

a1 = pSeg-wAngleZ - pSeg-wAngleZChangeMulPI / PI;

tmp3 = a1;
CCLine_Unk(); // in/out: tmp3
tmp1 = tmp5;
tmp2 = tmp6;
tmp5 = (Mul64(tmp3, tmp5) - Mul64(tmp4, tmp2)) 30;
tmp6 = (Mul64(tmp3, tmp6) + Mul64(tmp4, tmp1)) 30;

if (radius == 0) {
tmp2 = pCar-wSpeedAngleZ - a1;
tmp1 = SinBig(tmp2);
tmp2 = CosBig(tmp2);
tmp6 = MulDiv(tmp1, tmp6, tmp2);
pCar-wSegPosX = tmp5 - tmp6;
} else {
int r, a2;
tmp1 = Sqrt64(Mul64(radius, radius) - Mul64(tmp6, tmp6));
if (radius 0)
tmp1 = -tmp1;
pCar-wSegPosX = tmp5 - tmp1;
tmp2 = tmp6;
r = radius;
if (r 0)
r = -r;
for (; r = 0x7f00; r = 1) {
tmp1 = 1;
tmp2 = 1;
a2 = ATan2((short)tmp1, (short)tmp2);
if (radius 0)
a2 += 0x4000;
a2 -= 0x4000;
pCar-wSpeedAngleZ = a2 + a1;

void CCLine_Unk()
int a = tmp3;
int s = Sin(a);
if (s 0)
s = -s;
if (s 0x2000) { // 0.5
int c, t;
tmp3 = SinBig(a);
c = Cos(a);
if (c 0)
tmp4 = -tmp4;
// swap tmp3 and tmp4
t = tmp3;
tmp3 = tmp4;
tmp4 = t;
} else {
tmp3 = CosBig(a);
s = Sin(a);
if (s 0)
tmp4 = -tmp4;

void CCLine_Unk2()
// gets edge size
LONGLONG t = Mul64(0x40000000, 0x40000000) - Mul64(tmp3, tmp3);
if (t 0)
t = 0;
tmp4 = Sqrt(t);

Posted by David Schneider from

Hello Guyyzz

SDI: Nice nummbers, but can you explain what they mean?? I don`t understand anything.

Is it something new? And is it now possible to creat a Tool which makes the CC-Line for our Tracks???
I think i don`t need to mentation that it would be great!!!


Posted by SDI from

No, it's not new, I transcribed this several months ago from the gp3 disassembly. This is how gp3 creates the cc line so you have the best chance of drawing the cc line correctly in an editor if you make a routine similar to this. But since nobody has enough free time it ain't gonna happen :)


Transparent Textures (of the car)

Posted by Jimmy from

Does any one know if it's possible to create transparent ares on the textures of the car???



Unused Jam Ids

Posted by Andrew from

Hi I need a list of unused jam Ids for gp3, I could find out myself but if someone knew it would save me a bit of time. Also any news of a decent hw jam editor that at least has some functions of the gp2 and gp3 software version, i really need one as I cant change the size of textures, or add new ones into jam files.

Posted by John Verheijen from

You can find a list of the used JamID's on Addie's site.

And James is working on a HW JamEditor.

Posted by Andrew from

Thanks, I had a look on addies site but obviously not hard enough, Do you know how far the editor is into development, because I am having massive problems trying to convert yunis and plk's silverstone jams (size etc), and what would take about an hour is taking me ages!


cameras (scenery not showing up)

Posted by Andrew Smart from

when i insert a new camera into melbourne it works fine but you cannot see any of the scenery. and at a certain point, the scenery does then appear but it sort of scrolls down the track and dissapears again. Please help

Posted by addie from

you have set the arguments of the new cameras to similar values that the next and previous camera ? in particular the unknowns ?

Posted by addie from

i knew there is a bell ringing.

andrew please have a look at the thread "camera unknowns" in the january 2001 issue of the trackediting forum posting collection @
maybe the posting of marek michalak helps.


No pit side determination!!!

Posted by François Robert from

Hi! I'm new in track editing! I need a hint... In the sanity check I always get the same message No pit side determination 0x88, 0x89!! What should I do to change this???

Posted by Azzuro from

Put the command 0x88 or 0x89 in the pitsector were the pitbuilding is. Look at for details.


gp2/gp3 palette

Posted by Matteo Nunziati from

There is a fast way to convert the gp3 palette in a gp2 one?


end of list