diff --git a/src_rebuild/Game/C/camera.c b/src_rebuild/Game/C/camera.c index 9b3c9c318..0263482ad 100644 --- a/src_rebuild/Game/C/camera.c +++ b/src_rebuild/Game/C/camera.c @@ -574,28 +574,7 @@ void PlaceCameraInCar(PLAYER *lp, int BumperCam) viewer_position.vx = 0; viewer_position.vy = 0; - - if (cp == NULL) - { - viewer_position.vz = 0; - if(lp->pPed) - viewer_position.vy += lp->pPed->head_pos; - } - else if (cp->ap.carCos != NULL) // [A] prevent crash from happening - { - viewer_position.vy = 7; - viewer_position.vz = cp->ap.carCos->colBox.vz - 80; - } - - // [A] handle REDRIVER2 dedicated look back button - if ((paddCamera & CAMERA_PAD_LOOK_BACK) == CAMERA_PAD_LOOK_BACK || (paddCamera & CAMERA_PAD_LOOK_BACK_DED)) - viewer_position.vz = 0; - - angle = baseDir & 0xfff; - - lp->cameraPos.vx = basePos[0] + FIXEDH(rcossin_tbl[angle * 2] * viewer_position.vz); - lp->cameraPos.vy = viewer_position.vy - basePos[1]; - lp->cameraPos.vz = basePos[2] + FIXEDH(rcossin_tbl[angle * 2 + 1] * viewer_position.vz); + viewer_position.vz = 0; TurnHead(lp); @@ -605,61 +584,57 @@ void PlaceCameraInCar(PLAYER *lp, int BumperCam) else camera_angle.vy = (lp->headPos >> 16) - baseDir & 0xfff; - SetGeomScreen(scr_z = gCameraDefaultScrZ); - - if (cp == NULL) + if (cp) { - ClearMem((char *)&inv_camera_matrix, sizeof(MATRIX)); + // build custom matrix using car draw matrix + InvertMatrix(&cp->hd.drawCarMat, &inv_camera_matrix); - angle = 2048U - baseDir & 0xfff; + if (!((paddCamera & CAMERA_PAD_LOOK_BACK) == CAMERA_PAD_LOOK_BACK || (paddCamera & CAMERA_PAD_LOOK_BACK_DED))) + { + viewer_position.vz += cp->ap.carCos->colBox.vz - 250; - inv_camera_matrix.m[0][0] = rcossin_tbl[angle * 2 + 1]; - inv_camera_matrix.m[0][2] = rcossin_tbl[angle * 2]; - inv_camera_matrix.m[1][1] = 4096; - inv_camera_matrix.m[2][0] = -inv_camera_matrix.m[0][2]; - inv_camera_matrix.m[2][2] = inv_camera_matrix.m[0][0]; - } - else - { - InvertMatrix(&cp->hd.drawCarMat, &inv_camera_matrix); - } + _RotMatrixY(&inv_camera_matrix, 2048); + _RotMatrixY(&inv_camera_matrix, (lp->headPos >> 16)); + } - // [A] handle REDRIVER2 dedicated look back button - if ((paddCamera & CAMERA_PAD_LOOK_BACK) == CAMERA_PAD_LOOK_BACK || (paddCamera & CAMERA_PAD_LOOK_BACK_DED)) - { - if (cp != NULL) - viewer_position.vz = 170; + MulMatrix0(&aspect, &inv_camera_matrix, &inv_camera_matrix); + InvertMatrix(&inv_camera_matrix, &camera_matrix); + + face_camera_work.m[0][0] = ONE; + face_camera_work.m[0][2] = 0; + face_camera_work.m[2][0] = 0; + face_camera_work.m[2][2] = ONE; + + RotMatrixY(-(camera_angle.vy & 0xfff), &face_camera_work); + MulMatrix0(&inv_camera_matrix, &face_camera_work, &face_camera); + + viewer_position.vy = -40; + + SetRotMatrix(&camera_matrix); + _MatrixRotate(&viewer_position); + + lp->cameraPos.vx = basePos[0] + viewer_position.vx; + lp->cameraPos.vy = viewer_position.vy - basePos[1]; + lp->cameraPos.vz = basePos[2] + viewer_position.vz; } - else + else { - _RotMatrixY(&inv_camera_matrix, 2048); - _RotMatrixY(&inv_camera_matrix, (lp->headPos >> 16)); - - if (cp != NULL) - viewer_position.vz = -170; - else - _RotMatrixX(&inv_camera_matrix, -tannerLookAngle.vx); - } - - MulMatrix0(&aspect, &inv_camera_matrix, &inv_camera_matrix); - InvertMatrix(&inv_camera_matrix, &camera_matrix); + camera_angle.vx = -tannerLookAngle.vx; - face_camera_work.m[0][0] = 4096; - face_camera_work.m[0][2] = 0; - face_camera_work.m[2][0] = 0; - face_camera_work.m[2][2] = 4096; + // pedestrian camera is much simpler + BuildWorldMatrix(); - RotMatrixY(-camera_angle.vy & 0xfff, &face_camera_work); - MulMatrix0(&inv_camera_matrix, &face_camera_work, &face_camera); + viewer_position.vy += lp->pPed->head_pos - 25; + //viewer_position.vz += 45; - viewer_position.vy = -40; + angle = -baseDir & 0xfff; - SetRotMatrix(&camera_matrix); - _MatrixRotate(&viewer_position); + lp->cameraPos.vx = basePos[0] + FIXEDH(rcossin_tbl[angle * 2] * viewer_position.vz); + lp->cameraPos.vy = viewer_position.vy - basePos[1]; + lp->cameraPos.vz = basePos[2] - FIXEDH(rcossin_tbl[angle * 2 + 1] * viewer_position.vz); + } - lp->cameraPos.vx += viewer_position.vx; - lp->cameraPos.vy += viewer_position.vy; - lp->cameraPos.vz += viewer_position.vz; + SetGeomScreen(scr_z = gCameraDefaultScrZ); switch_detail_distance = 10000; } diff --git a/src_rebuild/Game/C/debris.c b/src_rebuild/Game/C/debris.c index 6ae12e005..8aaa30520 100644 --- a/src_rebuild/Game/C/debris.c +++ b/src_rebuild/Game/C/debris.c @@ -564,8 +564,7 @@ int AllocateLeaf(void) // [D] [T] void ReleaseLeaf(short num) { - next_leaf--; - leaf_alloc[next_leaf] = num; + leaf_alloc[--next_leaf] = num; } // [D] [T] @@ -580,12 +579,11 @@ void AddLeaf(VECTOR *Position, int num_leaves, int Type) Position->vy = -Position->vy; Position->pad = MapHeight(Position); - for (i = 0; i < num_leaves; i++) { num = AllocateLeaf(); - if (num < 0) + if (num == -1) return; LEAF* myleaf = &leaf[num]; @@ -603,7 +601,7 @@ void AddLeaf(VECTOR *Position, int num_leaves, int Type) myleaf->position.pad = Position->pad; myleaf->life = 600; - myleaf->flags = 2; + myleaf->flags = 0x2; myleaf->direction.vx = 0; myleaf->direction.vy = 0; @@ -681,7 +679,7 @@ void SwirlLeaves(CAR_DATA *cp) XDiff = plpos.vx - lpLeaf->position.vx; ZDiff = plpos.vz - lpLeaf->position.vz; - if ((lpLeaf->flags & 2) && + if ((lpLeaf->flags & 0x2) && lpLeaf->position.vy + plpos.vy > -180 && XDiff > -360 && XDiff < 360 && ZDiff > -360 && ZDiff < 360) { @@ -878,8 +876,7 @@ int AllocateDebris(void) // [D] [T] void ReleaseDebris(short num) { - next_debris--; - debris_alloc[next_debris] = num; + debris_alloc[--next_debris] = num; } @@ -895,8 +892,7 @@ int AllocateSmoke(void) // [D] [T] void ReleaseSmoke(short num) { - next_smoke--; - smoke_alloc[next_smoke] = num; + smoke_alloc[--next_smoke] = num; } // [D] [T] @@ -2533,7 +2529,7 @@ void Setup_Debris(VECTOR *ipos, VECTOR *ispeed, int num_debris, int type) mydebris->type = type & 7; mydebris->life = 128; - mydebris->flags = 2; + mydebris->flags = 0x2; mydebris->pos = i & 0x1f; } } @@ -2558,7 +2554,7 @@ void Setup_Smoke(VECTOR *ipos, int start_w, int end_w, int SmokeType, int WheelS mysmoke->final_w = end_w; mysmoke->position.vz = ipos->vz; mysmoke->step = end_w - start_w >> 7 << 2; - mysmoke->flags = 0x1006; + mysmoke->flags = 0x1000 | 0x4 | 0x2; mysmoke->life = 20; mysmoke->halflife = 10; @@ -2577,7 +2573,7 @@ void Setup_Smoke(VECTOR *ipos, int start_w, int end_w, int SmokeType, int WheelS mysmoke->position.vy = ipos->vy; mysmoke->position.vz = ipos->vz + (rand() & 9); - mysmoke->flags = 0x2006; + mysmoke->flags = 0x2000 | 0x4 | 0x2; mysmoke->transparency = 140; mysmoke->t_step = 5; mysmoke->step = 1; @@ -2600,7 +2596,7 @@ void Setup_Smoke(VECTOR *ipos, int start_w, int end_w, int SmokeType, int WheelS mysmoke->start_w = start_w; mysmoke->final_w = end_w; - mysmoke->flags = 0x2006; + mysmoke->flags = 0x2000 | 0x4 | 0x2; mysmoke->life = 40; mysmoke->halflife = 20; } @@ -2612,7 +2608,7 @@ void Setup_Smoke(VECTOR *ipos, int start_w, int end_w, int SmokeType, int WheelS mysmoke->position.vy = ipos->vy; mysmoke->position.vz = ipos->vz + (rand() & 7); - mysmoke->flags = 0x4006; + mysmoke->flags = 0x4000 | 0x4 | 0x2; mysmoke->transparency = 55; mysmoke->t_step = 2; mysmoke->step = 1; @@ -2623,7 +2619,7 @@ void Setup_Smoke(VECTOR *ipos, int start_w, int end_w, int SmokeType, int WheelS mysmoke->position.vx = ipos->vx + (rand() & 0x3f); mysmoke->position.vy = ipos->vy; mysmoke->position.vz = ipos->vz + (rand() & 0x3f); - mysmoke->flags = 22; + mysmoke->flags = 0x10 | 0x4 | 0x2; if (SmokeType == 5) // UNUSED { @@ -2650,7 +2646,7 @@ void Setup_Smoke(VECTOR *ipos, int start_w, int end_w, int SmokeType, int WheelS mysmoke->position.vx = ipos->vx; mysmoke->position.vy = ipos->vy; mysmoke->position.vz = ipos->vz; - mysmoke->flags = 0x46; + mysmoke->flags = 0x40 | 0x4 | 0x2; mysmoke->transparency = 160; mysmoke->step = 20; mysmoke->t_step = 5; @@ -2663,7 +2659,7 @@ void Setup_Smoke(VECTOR *ipos, int start_w, int end_w, int SmokeType, int WheelS { mysmoke->position.vx = ipos->vx + (rand() & 0x3f); mysmoke->position.vy = ipos->vy; - mysmoke->flags = 0x26; + mysmoke->flags = 0x20 | 0x4 | 0x2; mysmoke->transparency = 60; mysmoke->t_step = 5; mysmoke->start_w = start_w; @@ -2725,7 +2721,7 @@ void Setup_Sparks(VECTOR *ipos, VECTOR *ispeed, int num_sparks, char SparkType) { num = AllocateSmoke(); - if (num < 0) + if (num == -1) return; mysmoke = &smoke[num]; @@ -2740,7 +2736,7 @@ void Setup_Sparks(VECTOR *ipos, VECTOR *ispeed, int num_sparks, char SparkType) mysmoke->step = seed & 0x3f; mysmoke->drift.vx = 2; - mysmoke->flags = 10; + mysmoke->flags = 0x8 | 0x2; vx = ispeed->vx; vy = ispeed->vy; @@ -2790,7 +2786,10 @@ void DisplayDebris(DEBRIS *debris, char type) debrisvec.vy = debris->position.vy - camera_position.vy; debrisvec.vz = debris->position.vz - camera_position.vz; - if (debrisvec.vx >= -10000 && debrisvec.vz >= -10000 && 10000 >= debrisvec.vx && 10000 >= debrisvec.vz) + if (debrisvec.vx >= -10000 && + debrisvec.vz >= -10000 && + debrisvec.vx <= 10000 && + debrisvec.vz <= 10000) { tv = debris_rot_table[debris->type & 7] + (debris->pos >> 3 & 0x1fU); @@ -3087,9 +3086,9 @@ void HandleDebris(void) db = debris; i = next_debris; - while (i >= 0) + while (i > 0) { - if (db->flags & 2) + if (db->flags & 0x2) { DisplayDebris(db, 0); @@ -3122,150 +3121,143 @@ void HandleDebris(void) i = next_leaf; // Move leaves - while (i >= 0) + while (i > 0) { - if (lf->flags & 2) + if (lf->flags & 0x2) { DisplayDebris((DEBRIS *)lf, lf->type); if (pauseflag == 0) { - if (lf->life != 1) + if (lf->life == 1) { - if (pauseflag == 0) - { - int sn1, sn2, cs1, cs2; - - GetSmokeDrift(&Drift); - - Height = -(lf->position.pad + 20); - - // first we move debris - // SwirlLeaves basically changed direction vector - // in order to lift leaf from ground fast - if (lf->position.vy < Height) - { - lf->position.vx += lf->direction.vx + Drift.vx; - lf->position.vy += lf->direction.vy + Drift.vy; - lf->position.vz += lf->direction.vz + Drift.vz; - - lf->pos += lf->step; - lf->pos &= 0xff; - } - else - { - lf->position.vy = Height; - } - - lf->sin_index1 += lf->sin_addition1; - lf->sin_index2 += lf->sin_addition2; - lf->sin_index1 &= 0xfff; - lf->sin_index2 &= 0xfff; - - sn1 = rcossin_tbl[lf->sin_index1 * 2]; - sn2 = rcossin_tbl[lf->sin_index2 * 2]; - - cs1 = rcossin_tbl[lf->sin_index1 * 2 + 1]; - cs2 = rcossin_tbl[lf->sin_index2 * 2 + 1]; - - // then we compute completely new direction - lf->direction.vy = ((sn1 + sn2) >> 0xb) + 4; - lf->direction.vx = ((sn1 + sn2) * 5 >> 0xb); - lf->direction.vz = ((cs1 + cs2) * 5 >> 0xb); - } + lf->flags = 0; + ReleaseLeaf(lf->num); } else { - lf->flags = 0; - ReleaseLeaf(lf->num); + int sn1, sn2, cs1, cs2; + + GetSmokeDrift(&Drift); + + Height = -(lf->position.pad + 20); + + // first we move debris + // SwirlLeaves basically changed direction vector + // in order to lift leaf from ground fast + if (lf->position.vy < Height) + { + lf->position.vx += lf->direction.vx + Drift.vx; + lf->position.vy += lf->direction.vy + Drift.vy; + lf->position.vz += lf->direction.vz + Drift.vz; + + lf->pos += lf->step; + lf->pos &= 0xff; + } + else + { + lf->position.vy = Height; + } + + lf->sin_index1 += lf->sin_addition1; + lf->sin_index2 += lf->sin_addition2; + lf->sin_index1 &= 0xfff; + lf->sin_index2 &= 0xfff; + + sn1 = rcossin_tbl[lf->sin_index1 * 2]; + sn2 = rcossin_tbl[lf->sin_index2 * 2]; + + cs1 = rcossin_tbl[lf->sin_index1 * 2 + 1]; + cs2 = rcossin_tbl[lf->sin_index2 * 2 + 1]; + + // then we compute completely new direction + lf->direction.vy = ((sn1 + sn2) >> 0xb) + 4; + lf->direction.vx = ((sn1 + sn2) * 5 >> 0xb); + lf->direction.vz = ((cs1 + cs2) * 5 >> 0xb); } } } - - i--; lf++; + i--; } for (i = 0; i < MAX_SMOKE; i++) { sm = &smoke[i]; - if (sm->flags & 2) + if (sm->flags & 0x2) { - if (sm->flags & 4) + if (sm->flags & 0x8) + { + DisplaySpark(sm); // yup, smoke particles are sparks too + } + else if (sm->flags & 0x4) { - if (sm->flags & 0x8000) + if (sm->flags & 0x8000) DisplayWater(sm); // Really obsolete, water was only a thing in Driver 1 - else + else DisplaySmoke(sm); + } + } - if (pauseflag == 0) + if (sm->flags & 0x2 && pauseflag == 0) + { + if (sm->flags & 0x8000) + { + // OBSOLETE DRIVER 1 CODE + /* + ROUTE_DATA routeData; + ROADS_GetRouteData(sm->position.vx - sm->start_w, sm->position.vz - sm->start_w, &routeData); + ROADS_GetRouteData(sm->position.vx + sm->start_w, sm->position.vz + sm->start_w, &routeData); + + if (sm->start_w < 800 && (modelpointers[routeData.type]->shape_flags & MODEL_FLAG_ALLEY)) + sm->start_w += sm->step; + else*/ + sm->start_w -= sm->step; + } + else if (sm->flags & 0x8) + { + sm->position.vx += sm->drift_change.vx; + sm->position.vy += sm->drift_change.vy; + sm->position.vz += sm->drift_change.vz; + sm->drift_change.vy += 6; + + if (sm->drift.vx == 0) { - if (sm->flags & 0x8000) - { - // OBSOLETE DRIVER 1 CODE - /* - ROUTE_DATA routeData; - ROADS_GetRouteData(sm->position.vx - sm->start_w, sm->position.vz - sm->start_w, &routeData); - ROADS_GetRouteData(sm->position.vx + sm->start_w, sm->position.vz + sm->start_w, &routeData); - - if (sm->start_w < 800 && (modelpointers[routeData.type]->shape_flags & MODEL_FLAG_ALLEY)) - sm->start_w += sm->step; - else*/ - sm->start_w -= sm->step; - } - else - { - if (sm->start_w < 800) - sm->start_w += sm->step; + sm->final_tail_pos.vx += sm->drift_change.vx; + sm->final_tail_pos.vy += sm->drift_change.vy - 12; + sm->final_tail_pos.vz += sm->drift_change.vz; + } + else + { + sm->drift.vx -= 1; + } - sm->position.vx += sm->drift.vx; - sm->position.vy += sm->drift.vy; - sm->position.vz += sm->drift.vz; - - if (sm->halflife < sm->life) - { - sm->drift.vx -= sm->drift_change.vx; - sm->drift.vy -= sm->drift_change.vy; - sm->drift.vz -= sm->drift_change.vz; - } - } + if (sm->position.vy > 0) + { + sm->flags = 0; + ReleaseSmoke(sm->num); + continue; } } - - if (sm->flags & 8) + else { - // yup, smoke particles are sparks too - DisplaySpark(sm); + if (sm->start_w < 800) + sm->start_w += sm->step; - if(pauseflag == 0) + sm->position.vx += sm->drift.vx; + sm->position.vy += sm->drift.vy; + sm->position.vz += sm->drift.vz; + + if (sm->halflife < sm->life) { - sm->position.vx += sm->drift_change.vx; - sm->position.vy += sm->drift_change.vy; - sm->position.vz += sm->drift_change.vz; - sm->drift_change.vy += 6; - - if (sm->drift.vx == 0) - { - sm->final_tail_pos.vx += sm->drift_change.vx; - sm->final_tail_pos.vy += sm->drift_change.vy - 12; - sm->final_tail_pos.vz += sm->drift_change.vz; - } - else - { - sm->drift.vx -= 1; - } - - if (sm->position.vy > 0) - { - sm->flags = 0; - ReleaseSmoke(sm->num); - continue; - } + sm->drift.vx -= sm->drift_change.vx; + sm->drift.vy -= sm->drift_change.vy; + sm->drift.vz -= sm->drift_change.vz; } } - - if ((sm->flags & 0x900C) && pauseflag == 0) + + if (sm->flags & 0x900C) { sm->transparency -= sm->t_step; @@ -3275,7 +3267,7 @@ void HandleDebris(void) sm->life = 1; } - if (--sm->life == 0) + if (--sm->life == 0) { sm->flags = 0; ReleaseSmoke(sm->num); diff --git a/src_rebuild/Game/C/motion_c.c b/src_rebuild/Game/C/motion_c.c index 01ccaafb9..9505ae8af 100644 --- a/src_rebuild/Game/C/motion_c.c +++ b/src_rebuild/Game/C/motion_c.c @@ -1815,9 +1815,6 @@ void TannerShadow(PEDESTRIAN* pDrawingPed, VECTOR* pPedPos, SVECTOR* pLightPos, int Tangle; - // [A] not supported by emulator - // proposed change: double buffering of VRAM (one used as render target, second as texture) - memset((u_char*)&d, 0, sizeof(VECTOR)); SetDefDrawEnv(&drEnv, 0, current->draw.clip.y, 320, 256); @@ -1910,7 +1907,7 @@ void TannerShadow(PEDESTRIAN* pDrawingPed, VECTOR* pPedPos, SVECTOR* pLightPos, addPrim(current->ot + (z0 * 2 + z3 * 6 >> 6), &ft4TannerShadow[current->id]); //SubdivShadow(z0, z1, z2, z3, ft4TannerShadow + current->id); - + { // store vectors cp = camera_position; @@ -1945,7 +1942,7 @@ void TannerShadow(PEDESTRIAN* pDrawingPed, VECTOR* pPedPos, SVECTOR* pLightPos, SetGeomScreen(scr_z); BuildWorldMatrix(); } - + SetDefDrawEnv(&drEnv, rectTannerWindow.x, rectTannerWindow.y, rectTannerWindow.w, rectTannerWindow.h); drEnv.dfe = 0; // we're drawing into VRAM - don't draw on screen drEnv.dtd = 0; // [A] no need in dithering diff --git a/src_rebuild/Game/C/pedest.c b/src_rebuild/Game/C/pedest.c index 6820b2961..df0203091 100644 --- a/src_rebuild/Game/C/pedest.c +++ b/src_rebuild/Game/C/pedest.c @@ -469,9 +469,6 @@ void DrawAllPedestrians(void) { PEDESTRIAN* pPed; - //MATRIX mStore; - //gte_ReadRotMatrix(&mStore); - pPed = pUsedPeds; while (pPed != NULL) { @@ -502,9 +499,6 @@ void DrawAllPedestrians(void) } /* - // THIS IS OLD AND PROBABLY NOT NEEDED - gte_SetRotMatrix(&mStore); - pPed = pUsedPeds; while (pPed != NULL) { diff --git a/src_rebuild/PsyX/src/GTE/PsyX_GTE.C b/src_rebuild/PsyX/src/GTE/PsyX_GTE.C index 6b1f3346e..0637cf2d5 100644 --- a/src_rebuild/PsyX/src/GTE/PsyX_GTE.C +++ b/src_rebuild/PsyX/src/GTE/PsyX_GTE.C @@ -43,10 +43,9 @@ static int m_sf; static long long m_mac0; static long long m_mac3; -#define tgte_mvmva(sf, mx, v, cv, lm) ( 0x0400012 | \ - ((sf)<<19) | ((mx)<<17) | ((v)<<15) | ((cv)<<13) | ((lm)<<10) ) - -unsigned int gte_leadingzerocount(unsigned int lzcs) { +unsigned int gte_leadingzerocount(unsigned int lzcs) +{ +#if 0 // OLD AND SLOW WAY unsigned int lzcr = 0; if ((lzcs & 0x80000000) == 0) @@ -57,9 +56,28 @@ unsigned int gte_leadingzerocount(unsigned int lzcs) { lzcs <<= 1; } - const int t = tgte_mvmva(1, 2, 3, 1, 1); - return lzcr; +#endif + + if (!lzcs) + return 32; + + // perform fast bit scan + + unsigned int lzcr = lzcs; + static char debruijn32[32] = { + 0, 31, 9, 30, 3, 8, 13, 29, 2, 5, 7, 21, 12, 24, 28, 19, + 1, 10, 4, 14, 6, 22, 25, 20, 11, 15, 23, 26, 16, 27, 17, 18 + }; + + lzcr |= lzcr >> 1; + lzcr |= lzcr >> 2; + lzcr |= lzcr >> 4; + lzcr |= lzcr >> 8; + lzcr |= lzcr >> 16; + lzcr++; + + return debruijn32[lzcr * 0x076be629 >> 27]; } int LIM(int value, int max, int min, unsigned int flag) { @@ -302,9 +320,11 @@ bool PGXP_GetCacheData(PGXPVData& out, uint lookup, ushort indexhint) return false; } - int start = indexhint - 8; // index hint allows us to start from specific index + // index hint allows us to start from specific index + int start = max(0, indexhint - 8); + int end = g_pgxpVertexIndex;// min(start + 256, g_pgxpVertexIndex); - for (int i = max(0, start); i < g_pgxpVertexIndex; i++) + for (int i = start; i < end; i++) { if (g_pgxpCache[i].lookup == lookup) { diff --git a/src_rebuild/PsyX/src/GTE/half_float.cpp b/src_rebuild/PsyX/src/GTE/half_float.cpp index dfe3b61e9..4a9751c5c 100644 --- a/src_rebuild/PsyX/src/GTE/half_float.cpp +++ b/src_rebuild/PsyX/src/GTE/half_float.cpp @@ -1,55 +1,56 @@ #include "COMMON/half_float.h" +#include -half::half(const float x) +// see https://gist.github.com/rygorous/2156668 + +union FP32 { - union + uint u; + float f; + struct { - float floatI; - unsigned int i; + uint Mantissa : 23; + uint Exponent : 8; + uint Sign : 1; }; +}; - floatI = x; +union FP16 +{ + unsigned short u; + struct + { + uint Mantissa : 10; + uint Exponent : 5; + uint Sign : 1; + }; +}; - // unsigned int i = *((unsigned int *) &x); - int e = ((i >> 23) & 0xFF) - 112; - int m = i & 0x007FFFFF; +half::half(const float x) +{ + // this is a approximate solution + FP32 f = *(FP32*)&x; + FP32 f32infty = { 255 << 23 }; + FP32 f16max = { (127 + 16) << 23 }; + FP32 magic = { 15 << 23 }; + FP32 expinf = { (255 ^ 31) << 23 }; + uint sign_mask = 0x80000000u; + FP16 o = { 0 }; - sh = (i >> 16) & 0x8000; - if (e <= 0) - { - // Denorm - m = ((m | 0x00800000) >> (1 - e)) + 0x1000; - sh |= (m >> 13); - } - else if (e == 143) - { - sh |= 0x7C00; - if (m != 0) - { - // NAN - m >>= 13; - sh |= m | (m == 0); - } - } + uint sign = f.u & sign_mask; + f.u ^= sign; + + if (!(f.f < f32infty.u)) // Inf or NaN + o.u = f.u ^ expinf.u; else { - m += 0x1000; - if (m & 0x00800000) - { - // Mantissa overflow - m = 0; - e++; - } - if (e >= 31) - { - // Exponent overflow - sh |= 0x7C00; - } - else - { - sh |= (e << 10) | (m >> 13); - } + if (f.f > f16max.f) f.f = f16max.f; + f.f *= magic.f; } + + o.u = f.u >> 13; // Take the mantissa bits + o.u |= sign >> 16; + sh = o.u; } half::half(const half& other) @@ -59,38 +60,25 @@ half::half(const half& other) half::operator float() const { - union - { - unsigned int s; - float result; - }; + FP16 h = { sh }; - s = (sh & 0x8000) << 16; - unsigned int e = (sh >> 10) & 0x1F; - unsigned int m = sh & 0x03FF; + static const FP32 magic = { 113 << 23 }; + static const uint shifted_exp = 0x7c00 << 13; // exponent mask after shift + FP32 o; - if (e == 0) - { - // +/- 0 - if (m == 0) return result; + o.u = (h.u & 0x7fff) << 13; // exponent/mantissa bits + uint exp = shifted_exp & o.u; // just the exponent + o.u += (127 - 15) << 23; // exponent adjust - // Denorm - while ((m & 0x0400) == 0) - { - m += m; - e--; - } - e++; - m &= ~0x0400; - } - else if (e == 31) + // handle exponent special cases + if (exp == shifted_exp) // Inf/NaN? + o.u += (128 - 16) << 23; // extra exp adjust + else if (exp == 0) // Zero/Denormal? { - // INF / NAN - s |= 0x7F800000 | (m << 13); - return result; + o.u += 1 << 23; // extra exp adjust + o.f -= magic.f; // renormalize } - s |= ((e + 112) << 23) | (m << 13); - - return result; + o.u |= (h.u & 0x8000) << 16; // sign bit + return o.f; } diff --git a/src_rebuild/PsyX/src/RENDER/PsyX_RENDER.C b/src_rebuild/PsyX/src/RENDER/PsyX_RENDER.C index cfcd786e2..011a8c80c 100644 --- a/src_rebuild/PsyX/src/RENDER/PsyX_RENDER.C +++ b/src_rebuild/PsyX/src/RENDER/PsyX_RENDER.C @@ -36,7 +36,10 @@ RECT16 g_PreviousOffscreen = { 0,0,0,0 }; ShaderID g_PreviousShader = -1; -TextureID g_vramTexture = -1; +TextureID g_vramTexturesDouble[2]; +TextureID g_vramTexture; +int g_vramTextureIdx = 0; + TextureID g_fbTexture = -1; TextureID g_offscreenRTTexture = -1; @@ -204,8 +207,9 @@ void PBO_Download(GrPBO& pbo) #endif } -GLuint g_glVertexArray; -GLuint g_glVertexBuffer; +GLuint g_glVertexArray[2]; +GLuint g_glVertexBuffer[2]; +int g_curVertexBuffer = 0; GLuint g_glBlitFramebuffer; GrPBO g_glFramebufferPBO; @@ -440,8 +444,8 @@ int GR_InitialiseRender(char* windowName, int width, int height, int fullscreen) void GR_Shutdown() { #if defined(RENDERER_OGL) || defined(OGLES) - glDeleteVertexArrays(1, &g_glVertexArray); - glDeleteBuffers(1, &g_glVertexBuffer); + glDeleteVertexArrays(2, g_glVertexArray); + glDeleteBuffers(2, g_glVertexBuffer); PBO_Destroy(g_glFramebufferPBO); PBO_Destroy(g_glOffscreenPBO); @@ -450,7 +454,9 @@ void GR_Shutdown() glDeleteFramebuffers(1, &g_glOffscreenFramebuffer); glDeleteFramebuffers(1, &g_glVRAMFramebuffer); - GR_DestroyTexture(g_vramTexture); + GR_DestroyTexture(g_vramTexturesDouble[0]); + GR_DestroyTexture(g_vramTexturesDouble[1]); + GR_DestroyTexture(g_whiteTexture); GR_DestroyTexture(g_fbTexture); GR_DestroyTexture(g_offscreenRTTexture); @@ -461,9 +467,7 @@ void GR_BeginScene() { g_lastBoundTexture = 0; -#if defined(RENDERER_OGL) || defined(OGLES) - glBindVertexArray(g_glVertexArray); - +#if defined(RENDERER_OGL) || defined(OGLES) glClearDepth(1.0f); glClear(GL_DEPTH_BUFFER_BIT); glClear(GL_STENCIL_BUFFER_BIT); @@ -963,10 +967,13 @@ int GR_InitialisePSX() // gen VRAM textures. // double-buffered { - glGenTextures(1, &g_vramTexture); + int i; + glGenTextures(2, g_vramTexturesDouble); + + for(i = 0; i < 2; i++) { - glBindTexture(GL_TEXTURE_2D, g_vramTexture); + glBindTexture(GL_TEXTURE_2D, g_vramTexturesDouble[i]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); @@ -992,31 +999,18 @@ int GR_InitialisePSX() // gen vertex buffer and index buffer { - glGenBuffers(1, &g_glVertexBuffer); - glGenVertexArrays(1, &g_glVertexArray); - - glBindVertexArray(g_glVertexArray); + int i; - glBindBuffer(GL_ARRAY_BUFFER, g_glVertexBuffer); - glBufferData(GL_ARRAY_BUFFER, sizeof(GrVertex) * MAX_NUM_POLY_BUFFER_VERTICES, NULL, GL_DYNAMIC_DRAW); + glGenBuffers(2, g_glVertexBuffer); + glGenVertexArrays(2, g_glVertexArray); - glEnableVertexAttribArray(a_position); - glEnableVertexAttribArray(a_texcoord); - glEnableVertexAttribArray(a_color); - glEnableVertexAttribArray(a_extra); - -#if defined(USE_PGXP) - glVertexAttribPointer(a_position, 4, GL_FLOAT, GL_FALSE, sizeof(GrVertex), &((GrVertex*)NULL)->x); - glVertexAttribPointer(a_zw, 4, GL_FLOAT, GL_FALSE, sizeof(GrVertex), &((GrVertex*)NULL)->z); - - glEnableVertexAttribArray(a_zw); -#else - glVertexAttribPointer(a_position, 4, GL_SHORT, GL_FALSE, sizeof(GrVertex), &((GrVertex*)NULL)->x); -#endif + for (i = 0; i < 2; i++) + { + glBindVertexArray(g_glVertexArray[i]); - glVertexAttribPointer(a_texcoord, 4, GL_UNSIGNED_BYTE, GL_FALSE, sizeof(GrVertex), &((GrVertex*)NULL)->u); - glVertexAttribPointer(a_color, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(GrVertex), &((GrVertex*)NULL)->r); - glVertexAttribPointer(a_extra, 4, GL_BYTE, GL_FALSE, sizeof(GrVertex), &((GrVertex*)NULL)->tcx); + glBindBuffer(GL_ARRAY_BUFFER, g_glVertexBuffer[i]); + glBufferData(GL_ARRAY_BUFFER, sizeof(GrVertex) * MAX_NUM_POLY_BUFFER_VERTICES, NULL, GL_DYNAMIC_DRAW); + } glBindVertexArray(0); } @@ -1408,6 +1402,9 @@ void GR_SetOffscreenState(const RECT16& offscreenRect, int enable) // before drawing set source and target { glBindFramebuffer(GL_FRAMEBUFFER, g_glVRAMFramebuffer); + + // rebind texture + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, g_vramTexture, 0); // setup draw and read framebuffers glBindFramebuffer(GL_READ_FRAMEBUFFER, g_glOffscreenFramebuffer); // source is backbuffer @@ -1477,6 +1474,9 @@ void GR_StoreFrameBuffer(int x, int y, int w, int h) // before drawing set source and target glBindFramebuffer(GL_FRAMEBUFFER, g_glVRAMFramebuffer); + // rebind vram texture + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, g_vramTexture, 0); + // setup draw and read framebuffers glBindFramebuffer(GL_READ_FRAMEBUFFER, g_glBlitFramebuffer); // source is backbuffer glBindFramebuffer(GL_DRAW_FRAMEBUFFER, g_glVRAMFramebuffer); @@ -1543,6 +1543,10 @@ void GR_UpdateVRAM() vram_need_update = false; #if defined(RENDERER_OGL) || defined(OGLES) + g_vramTexture = g_vramTexturesDouble[g_vramTextureIdx]; + g_vramTextureIdx++; + g_vramTextureIdx &= 1; + glBindTexture(GL_TEXTURE_2D, g_vramTexture); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, VRAM_WIDTH, VRAM_HEIGHT, 0, VRAM_FORMAT, GL_UNSIGNED_BYTE, vram); //glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, VRAM_WIDTH, VRAM_HEIGHT, VRAM_FORMAT, GL_UNSIGNED_BYTE, vram); @@ -1670,9 +1674,40 @@ void GR_SetWireframe(bool enable) #endif } +void GR_BindVertexBuffer() +{ +#if defined(RENDERER_OGL) || defined(OGLES) + glBindVertexArray(g_glVertexArray[g_curVertexBuffer]); + + glEnableVertexAttribArray(a_position); + glEnableVertexAttribArray(a_texcoord); + glEnableVertexAttribArray(a_color); + glEnableVertexAttribArray(a_extra); + +#if defined(USE_PGXP) + glVertexAttribPointer(a_position, 4, GL_FLOAT, GL_FALSE, sizeof(GrVertex), &((GrVertex*)NULL)->x); + glVertexAttribPointer(a_zw, 4, GL_FLOAT, GL_FALSE, sizeof(GrVertex), &((GrVertex*)NULL)->z); + + glEnableVertexAttribArray(a_zw); +#else + glVertexAttribPointer(a_position, 4, GL_SHORT, GL_FALSE, sizeof(GrVertex), &((GrVertex*)NULL)->x); +#endif + glVertexAttribPointer(a_texcoord, 4, GL_UNSIGNED_BYTE, GL_FALSE, sizeof(GrVertex), &((GrVertex*)NULL)->u); + glVertexAttribPointer(a_color, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(GrVertex), &((GrVertex*)NULL)->r); + glVertexAttribPointer(a_extra, 4, GL_BYTE, GL_FALSE, sizeof(GrVertex), &((GrVertex*)NULL)->tcx); + + g_curVertexBuffer++; + g_curVertexBuffer &= 1; +#else +#error +#endif +} + void GR_UpdateVertexBuffer(const GrVertex* vertices, int num_vertices) { assert(num_vertices <= MAX_NUM_POLY_BUFFER_VERTICES); + GR_BindVertexBuffer(); + #if defined(RENDERER_OGL) || defined(OGLES) glBufferSubData(GL_ARRAY_BUFFER, 0, num_vertices * sizeof(GrVertex), vertices); #else