📄 gameframe.cpp
字号:
break;
}
case SCENERY_BRIDGE:
numCoords = sizeof(m_pData->bridgeVtx)/ sizeof(short);
CalcScreenCoords(m_pData->bridgeVtx,numCoords,0,zReal);
numPolys = sizeof(m_pData->bridgePolys)/ sizeof(short);
DrawModel(m_pData->bridgePolys,numPolys);
break;
case SCENERY_TELEGRAPHPOLE:
case SCENERY_TELEGRAPHPOLE_END:
numCoords = sizeof(m_pData->telegraphPoleVtx)/ sizeof(short);
CalcScreenCoords(m_pData->telegraphPoleVtx,numCoords,m_sceneryX[i],zReal);
numPolys = sizeof(m_pData->telegraphPolePolys)/ sizeof(short);
DrawModel(m_pData->telegraphPolePolys,numPolys);
if(m_sceneryTypes[i]==SCENERY_TELEGRAPHPOLE)
{
numPolys = sizeof(m_pData->telegraphWirePolys)/ sizeof(short);
DrawModel(m_pData->telegraphWirePolys,numPolys);
}
break;
case SCENERY_FENCE:
case SCENERY_FENCE_END:
numCoords = sizeof(m_pData->fenceVtx)/ sizeof(short);
CalcScreenCoords(m_pData->fenceVtx,numCoords,m_sceneryX[i],zReal); //draw pole
m_pGraph->SetColor(0x303030);
m_pGraph->SetFillColor(0x303030);
m_pGraph->FillRect(m_screenCoords[0],m_screenCoords[1],m_screenCoords[2]-m_screenCoords[0],m_screenCoords[3]-m_screenCoords[1]);
//wire
if(m_sceneryTypes[i]==SCENERY_FENCE)
{
m_pGraph->DrawLine(m_screenCoords[4],m_screenCoords[5],m_screenCoords[6],m_screenCoords[7]);
m_pGraph->DrawLine(m_screenCoords[8],m_screenCoords[9],m_screenCoords[10],m_screenCoords[11]);
}
break;
}
}
if(i==0)
i=m_numSceneryObjects-1;
else
i--;
}while(zReal<4096);
//draw any final trees infront of all scenery
if(treePos>0)
{
do
{
DrawTree(tree);
tree=(tree-1)&3;
}while(tree!=cmp);
}
if(m_isCliff!=0)
{
if(m_isCliff==1)
x=-96;
else
x=96;
zReal=511-(playerPos&511);
do
{
numCoords = sizeof(m_pData->barrierVtx)/ sizeof(short);
CalcScreenCoords(m_pData->barrierVtx,numCoords,x,zReal);
numPolys = sizeof(m_pData->barrierPolys)/ sizeof(short);
DrawModel(m_pData->barrierPolys,numPolys);
zReal+=512;
}while(zReal<4096);
}
}
/*===============================================================================
METHOD: CalcScreenCoords
=============================================================================== */
void GameFrame::CalcScreenCoords(short* pModelCoords, int numCoords, int x, int z)
{
int c;
int sc;
int zReal;
int scale,xPos;
int idx;
sc=0;
for(c=0;c<numCoords;c+=3)
{
zReal=z+pModelCoords[c+2];
if(zReal>4095)
zReal=4095;
//perspective adjust x position
scale=m_distTab[zReal>>5];
idx=(1023-m_pData->roadTable[1023-(zReal>>2)])>>4;
xPos=scale*(x+pModelCoords[c]);
xPos>>=10;
xPos+=128;
m_screenCoords[sc]=(short)(xPos+m_xDrawTab[idx]);
sc++;
m_screenCoords[sc]=(short)m_zDrawTab[idx];
m_screenCoords[sc]-=(pModelCoords[c+1]*scale)>>10;
sc++;
}
}
/*===============================================================================
METHOD: GenerateScenery
=============================================================================== */
void GameFrame::GenerateScenery(int* pScenery)
{
if(pScenery != NULL)
{
int i;
int* pTrack;
pTrack = m_pTrackTable[m_pFrontend->m_currentTrack];
for(i = 0 ; pTrack[i] != END_TRACK; i += 4)
{
if(pTrack[i] == BEND)
{
int ang = pTrack[i + 1];
int z = pTrack[i + 2];
if(ang > 4) //sharp right bend
AddArrows(z, (short)-140, (char)SCENERY_DOUBLE_ARROW);
else if(ang > 2) //right bend
AddArrows(z, (short) -140, (char)SCENERY_ARROW);
else if(ang < -4) //sharp left bend
AddArrows(z, (short)140, (char)SCENERY_DOUBLE_ARROW);
else if(ang < -2) //left bend
AddArrows(z, (short)140, (char)SCENERY_ARROW);
}
}
for(i = 0; pScenery[i] != END_TRACK; i += 4)
{
switch(pScenery[i])
{
case SCENERY_DUCATI:
case SCENERY_LAMPPOST:
AddPosts(pScenery[i+2],pScenery[i+3],(short) pScenery[i+1],(char)pScenery[i]);
break;
case SCENERY_TELEGRAPHPOLE:
AddTelegraphPoles(pScenery[i+2],pScenery[i+3],(short) pScenery[i+1]);
break;
case SCENERY_FENCE:
AddFence(pScenery[i+2],pScenery[i+3],(short) pScenery[i+1]);
break;
case SCENERY_TUNNEL:
m_sceneryTypes[m_numSceneryObjects] = SCENERY_TUNNEL;
m_sceneryX[m_numSceneryObjects] = 0;
m_sceneryZ[m_numSceneryObjects] = pScenery[i + 2];
m_numSceneryObjects++;
break;
default:
m_sceneryTypes[m_numSceneryObjects] = (char)pScenery[i];
m_sceneryX[m_numSceneryObjects]= (short)pScenery[i + 1];
m_sceneryZ[m_numSceneryObjects] = pScenery[i + 2];
m_numSceneryObjects++;
break;
}
}
DBGPRINTF("Track %d Num Scenery Objects = %d", m_pFrontend->m_currentTrack, m_numSceneryObjects);
}
}
/*===============================================================================
METHOD: AddArrows
=============================================================================== */
void GameFrame::AddArrows(int z, short xPos, char type)
{
z -= (1024 * 5) + 0x200;
for(int i = 0; i < 7; i++)
{
m_sceneryX[m_numSceneryObjects] = xPos;
m_sceneryZ[m_numSceneryObjects] = z;
m_sceneryTypes[m_numSceneryObjects] = type;
m_numSceneryObjects++;
z += 1024; //distance to next arrow
}
}
/*===============================================================================
METHOD: AddPosts
=============================================================================== */
void GameFrame::AddPosts(int z, int end, short xPos, char type)
{
do
{
m_sceneryX[m_numSceneryObjects] = xPos;
m_sceneryZ[m_numSceneryObjects] = z;
m_sceneryTypes[m_numSceneryObjects] = type;
m_numSceneryObjects++;
z += 0x400;
if(m_isCliff == 0) //only alternate on no cliff courses
xPos = (short)(0 - xPos);
}while(z <= end);
}
/*===============================================================================
METHOD: AddTelegraphPoles
=============================================================================== */
void GameFrame::AddTelegraphPoles(int z, int end, short xPos)
{
do
{
m_sceneryX[m_numSceneryObjects] = xPos;
m_sceneryZ[m_numSceneryObjects] = z;
if(z + 1024 > end)
m_sceneryTypes[m_numSceneryObjects] = SCENERY_TELEGRAPHPOLE_END;
else
m_sceneryTypes[m_numSceneryObjects] = SCENERY_TELEGRAPHPOLE;
m_numSceneryObjects++;
z += 1024; //length of telegraph pole
}while(z <= end);
}
/*===============================================================================
METHOD: AddFence
=============================================================================== */
void GameFrame::AddFence(int z, int end, short xPos)
{
do
{
m_sceneryX[m_numSceneryObjects] = xPos;
m_sceneryZ[m_numSceneryObjects] = z;
if(z + 512 > end)
m_sceneryTypes[m_numSceneryObjects] = SCENERY_FENCE_END;
else
m_sceneryTypes[m_numSceneryObjects] = SCENERY_FENCE;
m_numSceneryObjects++;
z += 512;
}while(z <= end);
}
/*===============================================================================
METHOD: AddTree
=============================================================================== */
void GameFrame::AddTree(int idx, int z)
{
int r;
//reset tree seed if done a lap
if(z > m_trackLength)
{
m_pTreeRandom->SetSeed(0x12345678);
z &= 4095;
}
r = m_pTreeRandom->NextInt() & 127;
if(((r&1)==1 || (m_isCliff & 2 )== 2) && (m_isCliff & 1) != 1) //only generate trees on left on cliffs
m_treeX[idx]= -278 + r;
else
m_treeX[idx] = r + 150;
r = m_pTreeRandom->NextInt() & 0x300;
m_treeZ[idx] = z + r;
}
/*===============================================================================
METHOD: DrawTree
=============================================================================== */
void GameFrame::DrawTree(int tree)
{
int zReal;
zReal=m_treeZ[tree]-m_zPos[0];
int numCoords;
int numPolys;
if(zReal<0) //create a new tree
{
AddTree(tree,m_zPos[0]+4096);
m_firstTree=(m_firstTree+1)&3;
}
else
{
int t=m_pData->trackTreeType[(m_pFrontend->m_currentTrack<<1)+(tree&1)];
numCoords = m_pData->treeVtxNumTable[t];
CalcScreenCoords(m_pTreeVtxTable[t],numCoords,m_treeX[tree],zReal);
numPolys = m_pData->treePolyElemTable[t];
DrawModel(m_pTreePolyTable[t],numPolys);
if(t>5) //cacti
{
m_pGraph->SetColor(0,160,0);
int x=m_screenCoords[0]+((m_screenCoords[2]-m_screenCoords[0])>>1);
m_pGraph->DrawLine(x,m_screenCoords[1],x,m_screenCoords[3]);
x=m_screenCoords[4]+((m_screenCoords[6]-m_screenCoords[4])>>1);
m_pGraph->DrawLine(x,m_screenCoords[5],x,m_screenCoords[7]);
x=m_screenCoords[6]+((m_screenCoords[8]-m_screenCoords[6])>>1);
m_pGraph->DrawLine(x,m_screenCoords[9],x,m_screenCoords[11]);
}
}
}
/*===============================================================================
METHOD: SortScenery
=============================================================================== */
void GameFrame::SortScenery()
{
boolean bDone;
int tmp;
do
{
bDone=TRUE;
for(int i=0;i<m_numSceneryObjects-1;i++)
{
if(m_sceneryZ[i]>m_sceneryZ[i+1])
{
tmp=m_sceneryZ[i];
m_sceneryZ[i]=m_sceneryZ[i+1];
m_sceneryZ[i+1]=tmp;
tmp=m_sceneryX[i];
m_sceneryX[i]=m_sceneryX[i+1];
m_sceneryX[i+1]=(short)tmp;
tmp=m_sceneryTypes[i];
m_sceneryTypes[i]=m_sceneryTypes[i+1];
m_sceneryTypes[i+1]=(char)tmp;
bDone=FALSE;
}
}
}while(!bDone);
}
/*===============================================================================
METHOD: DrawModel
=============================================================================== */
void GameFrame::DrawModel(short* pModel, int numElems)
{
int idx;
uint32 colour;
int x1,y1;
int x2,y2;
int x3,y3;
int w,h;
colour=m_pGraph->GetColor();
idx=0;
int l=numElems;
while(idx<l)
{
switch (pModel[idx++])
{
case POLY_COLOUR:
colour=pModel[idx++]<<16;
colour|=pModel[idx++]<<8;
colour|=pModel[idx++];
m_pGraph->SetColor(colour);
m_pGraph->SetFillColor(colour);
break;
case POLY_RECT:
x1=m_screenCoords[pModel[idx++]];
y1=m_screenCoords[pModel[idx++]];
w=m_screenCoords[pModel[idx++]]-x1;
h=m_screenCoords[pModel[idx++]]-y1;
m_pGraph->FillRect(x1,y1,w,h);
break;
case POLY_LINE:
x1=m_screenCoords[pModel[idx++]];
y1=m_screenCoords[pModel[idx++]];
x2=m_screenCoords[pModel[idx++]];
y2=m_screenCoords[pModel[idx++]];
m_pGraph->DrawLine(x1,y1,x2,y2);
break;
case POLY_TRI:
x1=m_screenCoords[pModel[idx++]];
y1=m_screenCoords[pModel[idx++]];
x2=m_screenCoords[pModel[idx++]];
y2=m_screenCoords[pModel[idx++]];
x3=m_screenCoords[pModel[idx++]];
y3=m_screenCoords[pModel[idx++]];
m_pGraph->FillTriangle(x1,y1,x2,y2,x3,y3);
break;
case POLY_EMPTY_TRI:
x1=m_screenCoords[pModel[idx++]];
y1=m_screenCoords[pModel[idx++]];
x2=m_screenCoords[pModel[idx++]];
y2=m_screenCoords[pModel[idx++]];
x3=m_screenCoords[pModel[idx++]];
y3=m_screenCoords[pModel[idx++]];
m_pGraph->DrawTriangle(x1,y1,x2,y2,x3,y3);
break;
case POLY_EMPTY_ARC:
x1=m_screenCoords[pModel[idx++]];
y1=m_screenCoords[pModel[idx++]];
w=m_screenCoords[pModel[idx++]]-x1;
h=m_screenCoords[pModel[idx++]]-y1;
m_pGraph->DrawArc(x1,y1,w,h);
break;
case POLY_ARC:
x1=m_screenCoords[pModel[idx++]];
y1=m_screenCoords[pModel[idx++]];
w=m_screenCoords[pModel[idx++]]-x1;
h=m_screenCoords[pModel[idx++]]-y1;
m_pGraph->FillArc(x1,y1,w,h);
break;
case POLY_ROUND_RECT:
x1=m_screenCoords[pModel[idx++]];
y1=m_screenCoords[pModel[idx++]];
w=m_screenCoords[pModel[idx++]]-x1;
h=m_screenCoords[pModel[idx++]]-y1;
m_pGraph->FillRoundRect(x1,y1,w,h,w>>1,h>>1);
break;
}
}
}
/*===============================================================================
METHOD: DrawCanyonScenery
=============================================================================== */
int GameFrame::DrawCanyonScenery(int canyonIdx, int* pTab, int zStop)
{
int l, t, w, s, h;
m_pGraph->SetScreenClip( 0, 36, m_canvasW, m_canvasH);
if(canyonIdx > 0)
{
do
{
if(zStop > pTab[canyonIdx - 1])
return canyonIdx;
else
{
canyonIdx -= 2;
s = pTab[canyonIdx];
h = pTab[--canyonIdx];
w = pTab[--canyonIdx];
t = pTab[--canyonIdx];
l = pTab[--canyonIdx];
m_pGraph->SetColor(m_pData->canyonColours[s]);
m_pGraph->SetFillColor(m_pData->canyonColours[s]);
m_pGraph->FillRect(l,t,w,h);
}
}while(canyonIdx > 0);
}
return 0;
}
/*===============================================================================
METHOD: GetCurrentBend
=============================================================================== */
int GameFrame::GetCurrentBend(int pos)
{
int* pTrackData;
int i;
int dist;
pTrackData = m_pTrackTable[m_pFrontend->m_currentTrack];
i = 0;
do
{
if(pTrackData[i] == BEND)
{
dist = pTrackData[i + 2] - pos;
if(dist < 0x100) //are we on or near this bend?
{
dist = pTrackData[i + 3] - pos;
if(dist > 0)
return pTrackDat
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -