diff options
Diffstat (limited to 'src/renderer')
29 files changed, 2089 insertions, 1843 deletions
diff --git a/src/renderer/Coronas.cpp b/src/renderer/Coronas.cpp index d9bf88d1..a00dc165 100644 --- a/src/renderer/Coronas.cpp +++ b/src/renderer/Coronas.cpp @@ -913,9 +913,9 @@ CEntity::ProcessLightsForEntity(void) effect->light.shadowSize, 0.0f, 0.0f, -effect->light.shadowSize, 128, - effect->col.r*CTimeCycle::GetSpriteBrightness()*effect->light.shadowIntensity/255.0f, - effect->col.g*CTimeCycle::GetSpriteBrightness()*effect->light.shadowIntensity/255.0f, - effect->col.b*CTimeCycle::GetSpriteBrightness()*effect->light.shadowIntensity/255.0f, + effect->col.r, + effect->col.g, + effect->col.b, 15.0f, 1.0f, 40.0f, false, 0.0f); }else if(lightFlickering){ CShadows::StoreStaticShadow((uintptr)this + i, SHADOWTYPE_ADDITIVE, diff --git a/src/renderer/Fluff.cpp b/src/renderer/Fluff.cpp index 1e4d289b..404f1a4a 100644 --- a/src/renderer/Fluff.cpp +++ b/src/renderer/Fluff.cpp @@ -424,8 +424,9 @@ void CMovingThings::Init() } } - CEscalators::Init(); - aScrollBars[0].Init(CVector(-1069.209f, 1320.126f, 18.848f), CVector(-1069.209f, 1342.299f, 22.612f), SCROLL_ARENA_STRING, 128, 255, 0, 0.3f); +// LCS: removed +// CEscalators::Init(); +// aScrollBars[0].Init(CVector(-1069.209f, 1320.126f, 18.848f), CVector(-1069.209f, 1342.299f, 22.612f), SCROLL_ARENA_STRING, 128, 255, 0, 0.3f); } void CMovingThings::Shutdown() diff --git a/src/renderer/Font.cpp b/src/renderer/Font.cpp index 6ae10011..b38b0efd 100644 --- a/src/renderer/Font.cpp +++ b/src/renderer/Font.cpp @@ -1,5 +1,6 @@ #include "common.h" +#include "main.h" #include "Sprite2d.h" #include "TxdStore.h" #include "Font.h" @@ -7,6 +8,9 @@ #include "FileMgr.h" #endif #include "Timer.h" +#include "Frontend.h" + +//--LCS: todo scaling (needs CSprite2d reversed), SuspendHandler, ReplaceGermanSZ, volatile mem, other todos void AsciiToUnicode(const char *src, wchar *dst) @@ -53,221 +57,44 @@ bool16 CFont::NewLine; CSprite2d CFont::Sprite[MAX_FONTS]; CFontRenderState CFont::RenderState; -#ifdef MORE_LANGUAGES -uint8 CFont::LanguageSet = FONT_LANGSET_EFIGS; -int32 CFont::Slot = -1; -#define JAP_TERMINATION (0x8000 | '~') - -int16 CFont::Size[LANGSET_MAX][MAX_FONTS][210] = { - { -#else -int16 CFont::Size[MAX_FONTS][210] = { -#endif - { - //FONT2 EFIGS - //SPC,!, $, %, &, ', [, ], +, , -, ., - 12, 9, 22, 17, 19, 19, 25, 4, 33, 33, 25, 35, 11, 10, 6, 33, - //0, 1, 2, 3, 4, 5, 6, 7, 8, 9, :, ??, - 18, 10, 17, 17, 17, 17, 17, 15, 12, 16, 5, 30, 30, 30, 30, 30, - // A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, - 12, 16, 19, 16, 19, 18, 18, 17, 22, 11, 17, 18, 18, 30, 22, 19, - //P, Q, R, S, T, U, V, W, X, Y, Z, ??, ??, ??, ¡, \, - #ifdef FIX_BUGS - 22, 19, 19, 20, 18, 19, 19, 29, 19, 18, 19, 19, 33, 33, 10, 19, - #else - 22, 19, 19, 20, 18, 19, 19, 29, 19, 18, 19, 19, 33, 33, 19, 19, - #endif - //??,a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, - 12, 14, 11, 11, 16, 11, 12, 14, 14, 10, 13, 12, 10, 19, 18, 12, - //p, q, r, s, t, u, v, w, x, y, z, ??, ??, ??, ??, ??, - 16, 13, 13, 11, 12, 15, 12, 15, 13, 12, 12, 37, 33, 37, 35, 37, - //À, Á, Â, Ä, Æ, Ç, È, É, Ê, Ë, Ì, Í, Î, Ï, Ò, Ó, - 16, 16, 16, 16, 33, 17, 18, 18, 18, 18, 11, 11, 11, 11, 19, 19, - //Ô, Ö, Ù, Ú, Û, Ü, ß, à, á, â, ä, æ, ç, è, é, ê, - 19, 19, 19, 19, 19, 19, 15, 14, 14, 14, 14, 20, 14, 11, 11, 11, - //ë, ì, í, î, ï, ò, ó, ô, ö, ù, ú, û, ü, Ñ, ñ, ¿, - #ifdef FIX_BUGS - 11, 10, 10, 10, 10, 12, 12, 12, 12, 15, 15, 15, 15, 22, 18, 21, - #else - 11, 10, 10, 10, 10, 12, 12, 12, 12, 15, 15, 15, 15, 24, 18, 21, - #endif - //i,BLANKS - 10, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - //space, unprop - 19, 16 - }, - { - //FONT1 EFIGS - //Characters with a '2' refer to the Pricedown font. - //Characters that are referred as '*I' are characters that contain icons for PS2/XBOX, but contain regular characters on PC - //in order to display them properly in the Keyboard controls menu. - //!2,!, *I,(R), $, %, &, ', [, ], *I, +, , -, ., *I, - 15, 7, 31, 25, 20, 23, 21, 7, 11, 10, 26, 14, 6, 12, 6, 26, - //0, 1, 2, 3, 4, 5, 6, 7, 8, 9, :, *I, *I, *I, *I, ?, - 20, 7, 20, 20, 21, 20, 20, 19, 21, 20, 8, 30, 24, 30, 24, 19, - //TM,A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, - 20, 22, 22, 21, 22, 18, 18, 22, 22, 9, 14, 21, 18, 27, 21, 24, - //P, Q, R, S, T, U, V, W, X, Y, Z, *I, \, *I, ¡, °, - #ifdef FIX_BUGS - 22, 22, 23, 20, 19, 23, 22, 31, 23, 23, 21, 25, 13, 30, 7, 19, - #else - 22, 22, 23, 20, 19, 23, 22, 31, 23, 23, 21, 25, 13, 30, 10, 19, - #endif - //(C),a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, - 10, 17, 17, 16, 17, 17, 11, 17, 17, 7, 7, 18, 7, 25, 17, 17, - //p, q, r, s, t, u, v, w, x, y, z, *I, *I, $2, (2, )2, - 17, 17, 11, 17, 11, 17, 18, 25, 19, 18, 17, 28, 26, 20, 15, 15, - //À, Á, Â, Ä, Æ, Ç, È, É, Ê, Ë, Ì, Í, Î, Ï, Ò, Ó, - 20, 20, 20, 20, 29, 22, 19, 19, 19, 19, 9, 9, 9, 9, 23, 23, - //Ô, Ö, Ù, Ú, Û, Ü, ß, à, á, â, ä, æ, ç, è, é, ê, - 23, 23, 24, 24, 24, 24, 20, 19, 17, 17, 17, 30, 16, 17, 17, 17, - //ë, ì, í, î, ï, ò, ó, ô, ö, ù, ú, û, ü, Ñ, ñ, ¿, - #ifdef FIX_BUGS - 17, 11, 11, 15, 12, 17, 17, 17, 17, 17, 17, 17, 17, 21, 17, 19, - #else - 17, 11, 11, 15, 12, 17, 17, 17, 17, 17, 17, 17, 17, 19, 20, 20, - #endif - //02,12,22, 32, 42, 52, 62, 72, 82, 92, :2, A2, B2, C2, D2, E2, - 20, 18, 19, 19, 21, 19, 19, 19, 19, 19, 16, 19, 19, 19, 20, 19, - //F2,G2,H2, I2, J2, K2, L2, M2, N2, O2, P2, Q2, R2, S2, T2, U2, - 16, 19, 19, 9, 19, 20, 14, 29, 19, 19, 19, 19, 19, 19, 21, 19, - //V2,W2,X2, Y2, Z2, À2, Á2, Â2, Ä2, Æ2, Ç2, È2, É2, Ê2, Ë2, Ì2, - 20, 32, 20, 19, 19, 19, 19, 19, 19, 29, 19, 19, 19, 19, 19, 9, - //Í2,Î2,Ï2, Ò2, Ó2, Ô2, Ö2, Ù2, Ú2, Û2, Ü2, ß2, Ñ2, ¿2, '2, .2, - #ifdef FIX_BUGS - 9, 9, 9, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 10, 9, - #else - 9, 9, 9, 19, 19, 19, 19, 19, 19, 19, 19, 19, 21, 21, 10, 9, - #endif - //space, unprop - 10, 20 - } - -#ifdef MORE_LANGUAGES - }, - { - { - 5, 9, 9, 0, 17, 17, 23, 3, 21, 18, 0, 8, 3, 8, 3, 0, - 16, 9, 16, 16, 15, 19, 15, 14, 17, 17, 4, 4, 0, 0, 0, 17, - 19, 17, 19, 15, 21, 18, 19, 16, 21, 13, 15, 21, 20, 28, 21, 18, - 22, 17, 21, 20, 18, 18, 20, 26, 22, 18, 18, 0, 8, 0, 9, 8, - 0, 14, 11, 12, 16, 11, 13, 13, 15, 10, 14, 15, 11, 21, 17, 10, - 20, 15, 12, 12, 16, 17, 13, 16, 13, 21, 11, 0, 0, 0, 0, 0, - 20, 19, 19, 22, 27, 15, 18, 18, 20, 26, 21, 23, 17, 22, 21, 17, - 26, 25, 26, 17, 20, 26, 17, 16, 11, 12, 13, 21, 11, 17, 17, 12, - 21, 17, 17, 15, 24, 16, 10, 20, 23, 16, 7, 9, 16, 23, 12, 11, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, - 19, 16 - }, - { - 11, 5, 10, 15, 19, 22, 20, 5, 9, 8, 11, 12, 5, 12, 6, 12, - 19, 5, 18, 19, 20, 18, 19, 18, 20, 19, 5, 6, 26, 12, 30, 19, - 23, 21, 20, 20, 20, 16, 16, 21, 19, 5, 13, 19, 16, 24, 20, 21, - 20, 21, 20, 19, 17, 20, 21, 30, 22, 21, 20, 25, 13, 30, 5, 9, - 10, 15, 15, 14, 15, 16, 10, 15, 15, 5, 5, 15, 5, 23, 15, 16, - 15, 15, 9, 16, 10, 15, 17, 24, 18, 15, 15, 27, 5, 19, 2, 2, - 20, 20, 16, 23, 30, 19, 20, 20, 21, 24, 19, 19, 20, 23, 22, 19, - 27, 29, 25, 20, 20, 28, 24, 16, 16, 14, 19, 25, 16, 16, 16, 17, - 19, 16, 16, 17, 25, 19, 15, 23, 26, 21, 16, 14, 22, 20, 16, 19, - 15, 14, 15, 16, 17, 15, 15, 15, 15, 15, 7, 15, 15, 15, 15, 15, - 13, 15, 15, 7, 15, 16, 13, 23, 15, 15, 15, 15, 15, 15, 17, 15, - 16, 24, 17, 17, 17, 15, 15, 13, 20, 23, 15, 17, 17, 16, 24, 15, - 15, 15, 23, 18, 15, 23, 26, 23, 16, 15, 23, 15, 15, 19, 2, 2, - 10, 20 - }, - }, - { - { - //FONT2 EFIGS - //SPC,!, $, %, &, ', [, ], +, , -, ., - 12, 9, 22, 17, 19, 19, 25, 4, 33, 33, 25, 35, 11, 10, 6, 33, - //0, 1, 2, 3, 4, 5, 6, 7, 8, 9, :, ??, - 18, 10, 17, 17, 17, 17, 17, 15, 12, 16, 5, 30, 30, 30, 30, 30, - // A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, - 12, 16, 19, 16, 19, 18, 18, 17, 22, 11, 17, 18, 18, 30, 22, 19, - //P, Q, R, S, T, U, V, W, X, Y, Z, ??, ??, ??, ¡, \, - 22, 19, 19, 20, 18, 19, 19, 29, 19, 18, 19, 19, 33, 33, 10, 19, - //??,a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, - 12, 14, 11, 11, 16, 11, 12, 14, 14, 10, 13, 12, 10, 19, 18, 12, - //p, q, r, s, t, u, v, w, x, y, z, ??, ??, ??, ??, ??, - 16, 13, 13, 11, 12, 15, 12, 15, 13, 12, 12, 37, 33, 37, 35, 37, - //À, Á, Â, Ä, Æ, Ç, È, É, Ê, Ë, Ì, Í, Î, Ï, Ò, Ó, - 16, 16, 16, 16, 33, 17, 18, 18, 18, 18, 11, 11, 11, 11, 19, 19, - //Ô, Ö, Ù, Ú, Û, Ü, ß, à, á, â, ä, æ, ç, è, é, ê, - 19, 19, 19, 19, 19, 19, 15, 14, 14, 14, 14, 20, 14, 11, 11, 11, - //ë, ì, í, î, ï, ò, ó, ô, ö, ù, ú, û, ü, Ñ, ñ, ¿, - 11, 10, 10, 10, 10, 12, 12, 12, 12, 15, 15, 15, 15, 22, 18, 21, - //i,BLANKS - 10, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - //space, unprop - 19, 16 - }, - { - //FONT1 EFIGS - //Characters with a '2' refer to the Pricedown font. - //Characters that are referred as '*I' are characters that contain icons for PS2/XBOX, but contain regular characters on PC - //in order to display them properly in the Keyboard controls menu. - //!2,!, *I,(R), $, %, &, ', [, ], *I, +, , -, ., *I, - 15, 7, 31, 25, 20, 23, 21, 7, 11, 10, 26, 14, 6, 12, 6, 26, - //0, 1, 2, 3, 4, 5, 6, 7, 8, 9, :, *I, *I, *I, *I, ?, - 20, 7, 20, 20, 21, 20, 20, 19, 21, 20, 8, 30, 24, 30, 24, 19, - //TM,A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, - 20, 22, 22, 21, 22, 18, 18, 22, 22, 9, 14, 21, 18, 27, 21, 24, - //P, Q, R, S, T, U, V, W, X, Y, Z, *I, \, *I, ¡, °, - 22, 22, 23, 20, 19, 23, 22, 31, 23, 23, 21, 25, 13, 30, 7, 19, - //(C),a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, - 10, 17, 17, 16, 17, 17, 11, 17, 17, 7, 7, 18, 7, 25, 17, 17, - //p, q, r, s, t, u, v, w, x, y, z, *I, *I, $2, (2, )2, - 17, 17, 11, 17, 11, 17, 18, 25, 19, 18, 17, 28, 26, 20, 15, 15, - //À, Á, Â, Ä, Æ, Ç, È, É, Ê, Ë, Ì, Í, Î, Ï, Ò, Ó, - 20, 20, 20, 20, 29, 22, 19, 19, 19, 19, 9, 9, 9, 9, 23, 23, - //Ô, Ö, Ù, Ú, Û, Ü, ß, à, á, â, ä, æ, ç, è, é, ê, - 23, 23, 24, 24, 24, 24, 20, 19, 17, 17, 17, 30, 16, 17, 17, 17, - //ë, ì, í, î, ï, ò, ó, ô, ö, ù, ú, û, ü, Ñ, ñ, ¿, - 17, 11, 11, 15, 12, 17, 17, 17, 17, 17, 17, 17, 17, 21, 17, 19, - //02,12,22, 32, 42, 52, 62, 72, 82, 92, :2, A2, B2, C2, D2, E2, - 20, 18, 19, 19, 21, 19, 19, 19, 19, 19, 16, 19, 19, 19, 20, 19, - //F2,G2,H2, I2, J2, K2, L2, M2, N2, O2, P2, Q2, R2, S2, T2, U2, - 16, 19, 19, 9, 19, 20, 14, 29, 19, 19, 19, 19, 19, 19, 21, 19, - //V2,W2,X2, Y2, Z2, À2, Á2, Â2, Ä2, Æ2, Ç2, È2, É2, Ê2, Ë2, Ì2, - 20, 32, 20, 19, 19, 19, 19, 19, 19, 29, 19, 19, 19, 19, 19, 9, - //Í2,Î2,Ï2, Ò2, Ó2, Ô2, Ö2, Ù2, Ú2, Û2, Ü2, ß2, Ñ2, ¿2, '2, .2, - 9, 9, 9, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 10, 9, - //space, unprop - 10, 20 - } - } -#endif +int16 CFont::Size[MAX_FONTS][419] = { + {15, 6, 8, 24, 22, 28, 28, 2, 8, 8, 12, 24, 8, 10, 8, 12, 24, 8, 22, 20, 24, 22, 22, 22, 24, 22, 8, 8, 22, 22, 24, 16, 28, 26, 20, 22, 22, 18, 18, + 24, 22, 4, 16, 20, 18, 26, 20, 24, 20, 24, 22, 24, 20, 20, 26, 32, 26, 26, 20, 10, 12, 8, 22, 18, 6, 26, 20, 22, 22, 18, 18, 24, 22, 4, 16, 20, 18, 26, + 20, 24, 20, 24, 22, 24, 20, 20, 26, 32, 26, 26, 20, 10, 12, 8, 22, 18, 26, 26, 26, 26, 26, 26, 26, 22, 18, 18, 18, 18, 8, 8, 10, 10, 26, 20, 24, 24, 24, + 24, 24, 22, 24, 20, 20, 20, 20, 26, 22, 20, 26, 26, 26, 26, 26, 26, 26, 22, 18, 18, 18, 18, 8, 8, 10, 10, 26, 20, 24, 24, 24, 24, 24, 22, 24, 20, 20, 20, + 20, 26, 22, 24, 24, 8, 16, 10, 8, 28, 8, 8, 18, 16, 10, 28, 8, 28, 24, 6, 16, 22, 18, 24, 4, 14, 10, 26, 14, 16, 26, 12, 2, 16, 16, 32, 19, 19, 19, + 19, 19, 19, 19, 19, 24, 19, 19, 19, 19, 19, 19, 19, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, -2, 0, -2, -2, 0, 0, 0, 0, -2, -2, -2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, -2, 0, -2, -2, 0, 0, 0, 0, -2, -2, -2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0, -2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28}, + {10, 12, 20, 24, 28, 30, 28, 12, 14, 14, 20, 24, 12, 16, 10, 28, 26, 20, 24, 24, 26, 24, 24, 24, 24, 24, 12, 12, 22, 22, 24, 24, 32, 28, 24, 26, 26, 24, 22, + 28, 26, 10, 22, 26, 22, 30, 28, 28, 26, 30, 26, 26, 28, 26, 26, 32, 26, 26, 26, 14, 18, 14, 22, 22, 14, 22, 22, 22, 22, 22, 18, 22, 22, 10, 12, 20, 10, 28, + 20, 22, 22, 22, 20, 22, 20, 20, 20, 30, 20, 22, 20, 16, 10, 16, 20, 0, 28, 28, 28, 28, 28, 28, 32, 26, 24, 24, 24, 24, 14, 14, 18, 16, 30, 28, 28, 28, 28, + 28, 28, 20, 30, 26, 26, 26, 26, 28, 26, 22, 22, 22, 22, 22, 22, 22, 32, 22, 22, 22, 22, 22, 14, 14, 18, 16, 22, 20, 22, 22, 22, 22, 22, 22, 24, 20, 20, 20, + 20, 22, 22, 22, 26, 12, 18, 18, 12, 32, 12, 12, 18, 18, 18, 32, 12, 32, 28, 10, 22, 28, 24, 28, 10, 26, 16, 30, 16, 20, 30, 18, 14, 18, 24, 32, 30, 30, 30, + 30, 24, 28, 24, 20, 24, 20, 20, 22, 20, 20, 10, 10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, -2, 0, 0, 0, -2, -2, 0, 0, 2, 0, 0, 0, 0, -2, -2, 0, 0, 0, -2, -2, -2, 0, -2, 0, -2, 0, 0, 0, 0, 0, 0, + 0, 0, -2, -2, 0, 0, -2, 0, -2, 1, 0, -2, -1, 0, 0, 0, -2, 0, 0, 0, -2, 0, 0, -2, 0, -2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, -2, -2, -2, -2, 0, 0, -2, 0, 0, 0, 0, -2, -2, -2, -2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28}, + {15, 8, 0, 0, 18, 0, 22, 8, 13, 13, 0, 0, 7, 0, 8, 22, 18, 17, 18, 18, 20, 18, 18, 18, 18, 18, 8, 18, 18, 18, 18, 18, 15, 18, 18, 8, 18, 18, 13, + 28, 18, 18, 18, 18, 18, 18, 20, 18, 19, 30, 18, 18, 18, 18, 18, 18, 0, 18, 0, 28, 18, 18, 18, 18, 0, 8, 8, 8, 8, 0, 18, 18, 18, 18, 0, 18, 0, 0, + 18, 18, 18, 18, 0, 0, 20, 30, 18, 8, 9, 9, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22} }; -#ifdef MORE_LANGUAGES -int16 Size_jp[] = { - 15, 14, 16, 20, 19, 26, 22, 11, 18, 18, 27, 26, 13, //; 0 - 19, 20, 27, 19, 15, 19, 19, 21, 19, 20, 18, 19, 15, //; 13 - 13, 28, 15, 32, 15, 35, 15, 19, 19, 19, 19, 17, 16, //; 26 - 19, 20, 15, 19, 20, 14, 17, 19, 19, 19, 19, 19, 19, //; 39 - 19, 19, 20, 25, 20, 19, 19, 33, 31, 39, 37, 39, 37, //; 52 - 21, 21, 21, 19, 17, 15, 23, 21, 15, 19, 20, 16, 19, //; 65 - 19, 19, 20, 20, 17, 22, 19, 22, 22, 19, 22, 22, 23, //; 78 - 35, 35, 35, 35, 37, 19, 19, 19, 19, 29, 19, 19, 19, //; 91 - 19, 19, 9, 9, 9, 9, 19, 19, 19, 19, 19, 19, 19, 19, //; 104 - 19, 19, 19, 19, 19, 30, 19, 19, 19, 19, 19, 10, 10, //; 118 - 10, 10, 19, 19, 19, 19, 19, 19, 19, 19, 19, 23, 35, //; 131 - 12, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, //; 144 - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, //; 157 - 19, 19, 19, 11, 19, 19, 19, 19, 19, 19, 19, 19, 19, //; 170 - 19, 19, 19, 19, 19, 19, 19, 19, 19, 21 -}; -#endif + +int FontSizeIncrementers[] = { 4, -2, 2 }; wchar foreign_table[128] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -301,44 +128,26 @@ int CFont::PS2Symbol = BUTTON_NONE; int CFont::ButtonsSlot = -1; #endif // BUTTON_ICONS +//--TODO(LCS): volatile memory void CFont::Initialise(void) { int slot; - slot = CTxdStore::AddTxdSlot("fonts"); -#ifdef MORE_LANGUAGES - Slot = slot; - switch (LanguageSet) + if (gMakeResources) { - case FONT_LANGSET_EFIGS: - default: + slot = CTxdStore::AddTxdSlot("fonts"); CTxdStore::LoadTxd(slot, "MODELS/FONTS.TXD"); - break; - case FONT_LANGSET_POLISH: - CTxdStore::LoadTxd(slot, "MODELS/FONTS_P.TXD"); - break; - case FONT_LANGSET_RUSSIAN: - CTxdStore::LoadTxd(slot, "MODELS/FONTS_R.TXD"); - break; - case FONT_LANGSET_JAPANESE: - CTxdStore::LoadTxd(slot, "MODELS/FONTS_J.TXD"); - break; - } -#else - CTxdStore::LoadTxd(slot, "MODELS/FONTS.TXD"); -#endif - CTxdStore::AddRef(slot); - CTxdStore::PushCurrentTxd(); - CTxdStore::SetCurrentTxd(slot); - Sprite[0].SetTexture("font2", "font2m"); -#ifdef MORE_LANGUAGES - if (IsJapanese()) { - Sprite[1].SetTexture("FONTJAP", "FONTJAP_mask"); - Sprite[3].SetTexture("FONTJAP", "FONTJAP_mask"); + CTxdStore::AddRef(slot); + CTxdStore::PushCurrentTxd(); + CTxdStore::SetCurrentTxd(slot); + Sprite[0].SetTexture("font2", "font2m"); + Sprite[1].SetTexture("font1", "font1m"); + Sprite[2].SetTexture("font3", "font3m"); + CTxdStore::PopCurrentTxd(); } -#endif // MORE_LANGUAGES - Sprite[1].SetTexture("font1", "font1m"); + else + slot = CTxdStore::FindTxdSlot("fonts"); SetScale(1.0f, 1.0f); SetSlantRefPoint(SCREEN_WIDTH, 0.0f); SetSlant(0.0f); @@ -355,7 +164,17 @@ CFont::Initialise(void) SetRightJustifyWrap(0.0f); SetAlphaFade(255.0f); SetDropShadowPosition(0); - CTxdStore::PopCurrentTxd(); + SetOutlineColor(CRGBA(0, 0, 0, 0)); + SetOutlineOn(0); + SetNewLineAdd(0); + SetNewLineAdd(2); + + /* + if (mspCompressedTexList) + { + // TODO (LCS): volatile shit + } + */ #if !defined(GAMEPAD_MENU) && defined(BUTTON_ICONS) // loaded in CMenuManager with GAMEPAD_MENU defined @@ -418,8 +237,9 @@ CFont::ReloadFonts(uint8 set) if (Slot != -1 && LanguageSet != set) { Sprite[0].Delete(); Sprite[1].Delete(); + Sprite[2].Delete(); if (IsJapanese()) - Sprite[2].Delete(); + Sprite[3].Delete(); CTxdStore::PushCurrentTxd(); CTxdStore::RemoveTxd(Slot); switch (set) @@ -441,15 +261,19 @@ CFont::ReloadFonts(uint8 set) CTxdStore::SetCurrentTxd(Slot); Sprite[0].SetTexture("font2", "font2_mask"); if (set == FONT_LANGSET_JAPANESE) { - Sprite[2].SetTexture("FONTJAP", "FONTJAP_mask"); + Sprite[1].SetTexture("FONTJAP", "FONTJAP_mask"); + Sprite[3].SetTexture("FONTJAP", "FONTJAP_mask"); } - Sprite[1].SetTexture("font1", "font1_mask"); + else + Sprite[1].SetTexture("pager", "pager_mask"); + Sprite[2].SetTexture("font1", "font1_mask"); CTxdStore::PopCurrentTxd(); } LanguageSet = set; } #endif +//--TODO(LCS): gpFonts void CFont::Shutdown(void) { @@ -463,6 +287,7 @@ CFont::Shutdown(void) #endif Sprite[0].Delete(); Sprite[1].Delete(); + Sprite[2].Delete(); #ifdef MORE_LANGUAGES if (IsJapanese()) Sprite[3].Delete(); @@ -473,6 +298,7 @@ CFont::Shutdown(void) #endif } +//--LCS: Done void CFont::InitPerFrame(void) { @@ -515,39 +341,39 @@ CFont::DrawButton(float x, float y) } #endif +//--LCS: TODO (mostly done but could use some checking) void CFont::PrintChar(float x, float y, wchar c) { + if (!(c >= 0 && c < 209)) return; + bool bDontPrint = false; if(x <= 0.0f || x > SCREEN_WIDTH || - y <= 0.0f || y > SCREEN_HEIGHT) // BUG: game uses SCREENW again + y <= -12.0f || y > SCREEN_HEIGHT) // BUG: game uses SCREENW again return; bDontPrint = c == '\0'; float w = GetCharacterWidth(c) / 32.0f; + + if ( !RenderState.proportional && RenderState.rightJustify ) + x += (GetCharacterWidth(c) - GetCharacterWidth(c, true)) * RenderState.scaleX; + if (Details.bFontHalfTexture && c == 208) c = '\0'; + + float xoff = c % 16; float yoff = c / 16; -#ifdef MORE_LANGUAGES - if (IsJapaneseFont()) { - w = 21.0f; - xoff = (float)(c % 48); - yoff = c / 48; - } -#endif + + // small float modifiers were left for pc if(RenderState.style == FONT_BANK || RenderState.style == FONT_STANDARD){ if (bDontPrint) return; if (RenderState.slant == 0.0f) { -#ifdef FIX_BUGS if (c < 192) { -#else - if (c < 193) { -#endif CSprite2d::AddToBuffer( CRect(x, y, - x + 32.0f * RenderState.scaleX * 1.0f, + x + 32.0f * RenderState.scaleX * 0.96f, y + 40.0f * RenderState.scaleY * 0.5f), RenderState.color, xoff / 16.0f, yoff / 12.8f + 0.0021f, @@ -555,10 +381,13 @@ CFont::PrintChar(float x, float y, wchar c) xoff / 16.0f, (yoff + 1.0f) / 12.8f - 0.0021f, (xoff + 1.0f) / 16.0f - 0.001f, (yoff + 1.0f) / 12.8f - 0.0021f); } else { + float xScale = 0.54f; + if (FrontEndMenuManager.m_PrefsUseWideScreen) + xScale = 0.486f; CSprite2d::AddToBuffer( - CRect(x, y, - x + 32.0f * RenderState.scaleX * 1.0f, - y + 33.0f * RenderState.scaleY * 0.5f), + CRect(x, y + RenderState.scaleY * 4.0f, + x + 32.0f * RenderState.scaleY * xScale * 0.96f, + y + 4.0f * RenderState.scaleY + 16.0f * RenderState.scaleY), RenderState.color, xoff / 16.0f, yoff / 12.8f + 0.0021f, (xoff + 1.0f) / 16.0f - 0.001f, yoff / 12.8f + 0.0021f, @@ -568,37 +397,13 @@ CFont::PrintChar(float x, float y, wchar c) } else CSprite2d::AddToBuffer( CRect(x, y, - x + 32.0f * RenderState.scaleX * 1.0f, + x + 32.0f * RenderState.scaleX * 0.96f, y + 40.0f * RenderState.scaleY * 0.5f), RenderState.color, xoff / 16.0f, yoff / 12.8f + 0.00055f, (xoff + 1.0f) / 16.0f - 0.001f, yoff / 12.8f + 0.0021f + 0.01f, xoff / 16.0f, (yoff + 1.0f) / 12.8f - 0.009f, (xoff + 1.0f) / 16.0f - 0.001f, (yoff + 1.0f) / 12.8f - 0.0021f + 0.01f); -#ifdef MORE_LANGUAGES - /*}else if (IsJapaneseFont()) { - if (Details.dropShadowPosition != 0) { - CSprite2d::AddSpriteToBank(Details.bank + Details.style, // BUG: game doesn't add bank - CRect(x + SCREEN_SCALE_X(Details.dropShadowPosition), - y + SCREEN_SCALE_Y(Details.dropShadowPosition), - x + SCREEN_SCALE_X(Details.dropShadowPosition) + 32.0f * Details.scaleX * 1.0f, - y + SCREEN_SCALE_Y(Details.dropShadowPosition) + 40.0f * Details.scaleY / 2.75f), - Details.dropColor, - xoff * w / 1024.0f, yoff / 25.6f, - xoff * w / 1024.0f + (1.0f / 48.0f) - 0.001f, yoff / 25.6f, - xoff * w / 1024.0f, (yoff + 1.0f) / 25.6f, - xoff * w / 1024.0f + (1.0f / 48.0f) - 0.001f, (yoff + 1.0f) / 25.6f - 0.0001f); - } - CSprite2d::AddSpriteToBank(Details.bank + Details.style, // BUG: game doesn't add bank - CRect(x, y, - x + 32.0f * Details.scaleX * 1.0f, - y + 40.0f * Details.scaleY / 2.75f), - Details.color, - xoff * w / 1024.0f, yoff / 25.6f, - xoff * w / 1024.0f + (1.0f / 48.0f) - 0.001f, yoff / 25.6f, - xoff * w / 1024.0f, (yoff + 1.0f) / 25.6f - 0.002f, - xoff * w / 1024.0f + (1.0f / 48.0f) - 0.001f, (yoff + 1.0f) / 25.6f - 0.0001f);*/ -#endif } else { if (bDontPrint) return; CSprite2d::AddToBuffer( @@ -606,10 +411,10 @@ CFont::PrintChar(float x, float y, wchar c) x + 32.0f * RenderState.scaleX * w, y + 32.0f * RenderState.scaleY * 0.5f), RenderState.color, - xoff / 16.0f, yoff / 16.0f, - (xoff + w) / 16.0f, yoff / 16.0f, - xoff / 16.0f, (yoff + 1.0f) / 16.0f, - (xoff + w) / 16.0f - 0.0001f, (yoff + 1.0f) / 16.0f - 0.0001f); + xoff / 16.0f, yoff / 6.4f, + (xoff + w) / 16.0f, yoff / 6.4f, + xoff / 16.0f, (yoff + 1.0f) / 6.4f, + (xoff + w) / 16.0f, (yoff + 1.0f) / 6.4f); } } @@ -635,6 +440,7 @@ bool CFont::IsAnsiCharacter(wchar *s) } #endif +//--LCS: TODO (mostly done but could use some checking) void CFont::RenderFontBuffer() { @@ -647,7 +453,7 @@ CFont::RenderFontBuffer() bool bFlash = false; Sprite[RenderState.style].SetRenderState(); - RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); + RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); // TODO: not in lcs RenderState = *(CFontRenderState*)&FontRenderStateBuf[0]; textPosX = RenderState.fTextPosX; textPosY = RenderState.fTextPosY; @@ -689,16 +495,15 @@ CFont::RenderFontBuffer() } Details.color.alpha = Details.bFlashState ? 0 : 255; } - if (!RenderState.bIsShadow) + if (!RenderState.bIsShadow && !RenderState.bOutlineOn) RenderState.color = color; } wchar c = *pRenderStateBufPointer.pStr; c -= ' '; + if (c == 200) c = '^'; + if (c == 201) c = '>'; if (RenderState.bFontHalfTexture) - c = FindNewCharacter(c); - else if (c > 155) - c = '\0'; - + c = FindNewCharacter(c); if (RenderState.slant != 0.0f) textPosY = (RenderState.slantRefX - textPosX) * RenderState.slant + RenderState.slantRefY; PrintChar(textPosX, textPosY, c); @@ -707,11 +512,11 @@ CFont::RenderFontBuffer() PrintChar(textPosX + 2.0f, textPosY, c); textPosX += 2.0f; } -#ifdef FIX_BUGS - // PS2 uses different chars for some symbols - if (!RenderState.bFontHalfTexture && c == 30) c = 61; // wanted star -#endif textPosX += RenderState.scaleX * GetCharacterWidth(c); +//#ifdef FIX_BUGS +// // PS2 uses different chars for some symbols +// if (!RenderState.bFontHalfTexture && c == 30) c = 61; // wanted star +//#endif if (c == '\0') textPosX += RenderState.fExtraSpace; } @@ -719,50 +524,8 @@ CFont::RenderFontBuffer() FontRenderStatePointer.pRenderState = (CFontRenderState*)FontRenderStateBuf; } -#if 0 //def MORE_LANGUAGES -bool -CFont::PrintString(float x, float y, wchar *start, wchar *&end, float spwidth, float japX) -{ - wchar *s, c, unused; - if (IsJapanese()) { - float jx = 0.0f; - for (s = start; s < end; s++) { - if (*s == JAP_TERMINATION || *s == '~') - s = ParseToken(s, &unused, true); - if (NewLine) { - NewLine = false; - break; - } - jx += GetCharacterSize(*s - ' '); - } - s = start; - if (Details.centre) - x = japX - jx / 2.0f; - else if (Details.rightJustify) - x = japX - jx; - } - - for (s = start; s < end; s++) { - if (*s == '~' || (IsJapanese() && *s == JAP_TERMINATION)) - s = ParseToken(s, &unused); - if (NewLine && IsJapanese()) { - NewLine = false; - end = s; - return true; - } - c = *s - ' '; - if (Details.slant != 0.0f && !IsJapanese()) - y = (Details.slantRefX - x) * Details.slant + Details.slantRefY; - - PrintChar(x, y, c); - x += GetCharacterSize(c); - if (c == 0 && (!NewLine || !IsJapanese())) // space - x += spwidth; - } - return false; -} -#else +//--LCS: TODO void CFont::PrintString(float x, float y, uint32, wchar *start, wchar *end, float spwidth) { @@ -773,26 +536,38 @@ CFont::PrintString(float x, float y, uint32, wchar *start, wchar *end, float spw RenderState.style = Details.style; } - float dropShadowPosition = Details.dropShadowPosition; - if (dropShadowPosition != 0.0f && (Details.style == FONT_BANK || Details.style == FONT_STANDARD)) { + if (Details.outlineColor.a != 0) { CRGBA color = Details.color; - Details.color = Details.dropColor; + Details.color = Details.outlineColor; + Details.bOutlineOn = true; + Details.outlineColor.a = 0; Details.dropShadowPosition = 0; - Details.bIsShadow = true; - if (Details.slant != 0.0f) { - Details.slantRefX += SCREEN_SCALE_X(dropShadowPosition); - Details.slantRefY += SCREEN_SCALE_Y(dropShadowPosition); - PrintString(SCREEN_SCALE_X(dropShadowPosition) + x, SCREEN_SCALE_Y(dropShadowPosition) + y, Details.anonymous_25, start, end, spwidth); - Details.slantRefX -= SCREEN_SCALE_X(dropShadowPosition); - Details.slantRefY -= SCREEN_SCALE_Y(dropShadowPosition); - } else { - PrintString(SCREEN_SCALE_X(dropShadowPosition) + x, SCREEN_SCALE_Y(dropShadowPosition) + y, Details.anonymous_25, start, end, spwidth); - } - Details.color = color; - Details.dropShadowPosition = dropShadowPosition; Details.bIsShadow = false; + PrintString(x, y, Details.anonymous_25, start, end, spwidth); + Details.color = color; + Details.bOutlineOn = false; + } else { + float dropShadowPosition = Details.dropShadowPosition; + if (dropShadowPosition != 0.0f && (Details.style == FONT_BANK || Details.style == FONT_STANDARD)) { + CRGBA color = Details.color; + Details.color = Details.dropColor; + Details.dropShadowPosition = 0; + Details.bIsShadow = true; + if (Details.slant != 0.0f) { + Details.slantRefX += SCREEN_SCALE_X(dropShadowPosition); + Details.slantRefY += SCREEN_SCALE_Y(dropShadowPosition); + PrintString(SCREEN_SCALE_X(dropShadowPosition) + x, SCREEN_SCALE_Y(dropShadowPosition) + y, Details.anonymous_25, start, end, spwidth); + Details.slantRefX -= SCREEN_SCALE_X(dropShadowPosition); + Details.slantRefY -= SCREEN_SCALE_Y(dropShadowPosition); + } else { + PrintString(SCREEN_SCALE_X(dropShadowPosition) + x, SCREEN_SCALE_Y(dropShadowPosition) + y, Details.anonymous_25, start, end, spwidth); + } + Details.color = color; + Details.dropShadowPosition = dropShadowPosition; + Details.bIsShadow = false; + } } - if (FontRenderStatePointer.pStr >= (wchar*)&FontRenderStateBuf[ARRAY_SIZE(FontRenderStateBuf)] - (end - start + 26)) // why 26? + if ((uintptr)FontRenderStatePointer.pStr >= (uintptr)&FontRenderStateBuf[ARRAY_SIZE(FontRenderStateBuf)] - sizeof(wchar) * (end - start + 2) - sizeof(CFontRenderState)) RenderFontBuffer(); CFontRenderState *pRenderState = FontRenderStatePointer.pRenderState; pRenderState->fTextPosX = x; @@ -828,17 +603,18 @@ CFont::PrintString(float x, float y, uint32, wchar *start, wchar *end, float spw *(FontRenderStatePointer.pStr++) = '\0'; FontRenderStatePointer.Align(); } -#endif +// LCS: Done void CFont::PrintStringFromBottom(float x, float y, wchar *str) { - y -= (32.0f * Details.scaleY / 2.0f + 2.0f * Details.scaleY) * GetNumberLines(x, y, str); + y -= (32.0f * Details.scaleY / 2.0f + Details.line * Details.scaleY) * GetNumberLines(x, y, str); if (Details.slant != 0.0f) y -= ((Details.slantRefX - x) * Details.slant + Details.slantRefY); PrintString(x, y, str); } +//--LCS: TODO void CFont::PrintString(float xstart, float ystart, wchar *s) { @@ -849,7 +625,8 @@ CFont::PrintString(float xstart, float ystart, wchar *s) bool first; wchar *start, *t; - Details.bFlash = false; + CRGBA outlineColor = Details.outlineColor; + CFont::SetFlashOff(); if(*s == '*') return; @@ -896,7 +673,7 @@ CFont::PrintString(float xstart, float ystart, wchar *s) float xleft = Details.centre ? xstart - x/2 : Details.rightJustify ? xstart - x : xstart; -#if 0//def MORE_LANGUAGES +#ifdef MORE_LANGUAGES PrintString(xleft, y, start, s, spaceWidth, xstart); #else PrintString(xleft, y, Details.anonymous_25, start, s, spaceWidth); @@ -934,7 +711,7 @@ CFont::PrintString(float xstart, float ystart, wchar *s) #endif lineLength = x; s = t+1; -#if 0 //def MORE_LANGUAGES +#ifdef MORE_LANGUAGES if (IsJapaneseFont() && !*s) { x += GetStringWidth(s); if (IsAnsiCharacter(s)) @@ -966,7 +743,7 @@ CFont::PrintString(float xstart, float ystart, wchar *s) float xleft = Details.centre ? xstart - x/2 : Details.rightJustify ? xstart - x : xstart; -#if 0 //def MORE_LANGUAGES +#ifdef MORE_LANGUAGES if (PrintString(xleft, y, start, s, 0.0f, xstart) && IsJapaneseFont()) { start = s; if (!Details.centre && !Details.rightJustify) @@ -984,6 +761,7 @@ CFont::PrintString(float xstart, float ystart, wchar *s) } } +//--LCS: TODO int CFont::GetNumberLines(float xstart, float ystart, wchar *s) { @@ -992,7 +770,7 @@ CFont::GetNumberLines(float xstart, float ystart, wchar *s) wchar *t; n = 0; -#if 0//def MORE_LANGUAGES +#ifdef MORE_LANGUAGES bool bSomeJapBool = false; if (IsJapanese()) { @@ -1085,6 +863,7 @@ CFont::GetNumberLines(float xstart, float ystart, wchar *s) return n; } +//--LCS: TODO void CFont::GetTextRect(CRect *rect, float xstart, float ystart, wchar *s) { @@ -1190,101 +969,65 @@ CFont::GetTextRect(CRect *rect, float xstart, float ystart, wchar *s) } } -float -CFont::GetCharacterWidth(wchar c) +//--LCS: done +bool IsPunctuation(wchar c) { -#ifdef MORE_LANGUAGES - if (IsJapanese()) { - if (!RenderState.proportional) - return Size[0][Details.style][192]; - if (c <= 94 || Details.style == FONT_HEADING || RenderState.style == FONT_BANK) { - switch (RenderState.style) - { - case FONT_JAPANESE: - return Size_jp[c]; - default: - return Size[0][RenderState.style][c]; - } - } - - switch (RenderState.style) - { - case FONT_JAPANESE: - return 29.4f; - case FONT_BANK: - return 10.0f; - default: - return Size[0][RenderState.style][c]; - } + switch (c) + { + case '!': + case '?': + case '.': + case ',': + case ':': + case ';': + + // these are lucid it seems + //case '$': + //case '/': + //case '\\': + return true; } - - else if (RenderState.proportional) - return Size[LanguageSet][RenderState.style][c]; - else - return Size[LanguageSet][RenderState.style][209]; -#else - - if (RenderState.proportional) - return Size[RenderState.style][c]; - else - return Size[RenderState.style][209]; -#endif // MORE_LANGUAGES + return false; } +//--LCS: done float -CFont::GetCharacterSize(wchar c) +CFont::GetCharacterWidth(wchar c, bool forceProportional) { -#ifdef MORE_LANGUAGES - - if (IsJapanese()) - { - if (!Details.proportional) - return Size[0][Details.style][209] * Details.scaleX; - if (c <= 94 || Details.style == FONT_HEADING || Details.style == FONT_BANK) { - switch (Details.style) - { - case FONT_JAPANESE: - return Size_jp[c] * Details.scaleX; - default: - return Size[0][Details.style][c] * Details.scaleX; - } - } - - switch (Details.style) - { - case FONT_JAPANESE: - return 29.4f * Details.scaleX; - case FONT_BANK: - return 10.0f * Details.scaleX; - default: - return Size[0][Details.style][c] * Details.scaleX; - } - } - else + if (RenderState.proportional || forceProportional) { - if (!Details.bFontHalfTexture && c == 30) c = 61; // wanted star - if (Details.bFontHalfTexture) - c = FindNewCharacter(c); - if (Details.proportional) - return Size[LanguageSet][Details.style][c] * Details.scaleX; + float inc = c < 192 ? 0.0f : 4.0f; + return Size[RenderState.style][c] + Size[RenderState.style][c + 209] + FontSizeIncrementers[RenderState.style] + inc; + } else { + if (IsPunctuation(c + ' ')) + return Size[RenderState.style][418] / 1.6f + FontSizeIncrementers[RenderState.style]; else - return Size[LanguageSet][Details.style][209] * Details.scaleX; + return Size[RenderState.style][418] + FontSizeIncrementers[RenderState.style]; } -#else +} -#ifdef FIX_BUGS +//--LCS: done +float +CFont::GetCharacterSize(wchar c) +{ +//#ifdef FIX_BUGS // PS2 don't call FindNewCharacter in here at all, and also uses different chars for some symbols - if (!Details.bFontHalfTexture && c == 30) c = 61; // wanted star -#endif +// if (!Details.bFontHalfTexture && c == 30) c = 61; // wanted star +//#endif if (Details.bFontHalfTexture) c = FindNewCharacter(c); - if (Details.proportional) - return Size[Details.style][c] * Details.scaleX; - else - return Size[Details.style][209] * Details.scaleX; -#endif // MORE_LANGUAGES + if (Details.proportional) { + float inc = c < 192 ? 0.0f : 4.0f; + return (Size[Details.style][c] + Size[Details.style][c + 209] + FontSizeIncrementers[Details.style] + inc) * Details.scaleX; + } else { + if (IsPunctuation(c + ' ')) + return (Size[Details.style][418] + FontSizeIncrementers[Details.style]) / 1.6f * Details.scaleX; + else + return Size[Details.style][418] + FontSizeIncrementers[Details.style] * Details.scaleX; + } } +//--LCS: TODO float CFont::GetStringWidth(wchar *s, bool spaces) { @@ -1397,6 +1140,19 @@ CFont::GetStringWidth_Jap(wchar* s) } #endif +//--LCS: done +bool16 +CFont::CheckNewLine(wchar *s) +{ + while (*s == ' ') + s++; + + if (*s == '~') + return s[1] == 'N' || s[1] == 'n'; + return false; +} + +//--LCS: TODO wchar* CFont::GetNextSpace(wchar *s) { @@ -1427,6 +1183,7 @@ CFont::GetNextSpace(wchar *s) return s; } +//--LCS: done wchar* CFont::ParseToken(wchar* str, CRGBA &color, bool &flash, bool &bold) { @@ -1439,28 +1196,36 @@ CFont::ParseToken(wchar* str, CRGBA &color, bool &flash, bool &bold) case 'B': bold = !bold; break; + case 'Y': + color.r = 255; + color.g = 227; + color.b = 79; + break; case 'b': - color.r = 27; - color.g = 89; - color.b = 130; + color.r = 77; + color.g = 155; + color.b = 210; break; case 'f': flash = !flash; break; case 'g': - color.r = 255; - color.g = 150; - color.b = 225; + color.r = 75; + color.g = 151; + color.b = 75; + Details.anonymous_23 = true; break; case 'h': - color.r = 225; - color.g = 225; - color.b = 225; + color.r = 255; + color.g = 255; + color.b = 255; + Details.anonymous_23 = true; break; case 'l': color.r = 0; color.g = 0; color.b = 0; + Details.anonymous_23 = true; break; case 'o': color.r = 229; @@ -1468,9 +1233,9 @@ CFont::ParseToken(wchar* str, CRGBA &color, bool &flash, bool &bold) color.b = 126; break; case 'p': - color.r = 168; - color.g = 110; - color.b = 252; + color.r = 151; + color.g = 82; + color.b = 197; break; case 'q': color.r = 199; @@ -1478,9 +1243,9 @@ CFont::ParseToken(wchar* str, CRGBA &color, bool &flash, bool &bold) color.b = 203; break; case 'r': - color.r = 255; - color.g = 150; - color.b = 225; + color.r = 174; + color.g = 0; + color.b = 0; break; case 't': color.r = 86; @@ -1488,27 +1253,20 @@ CFont::ParseToken(wchar* str, CRGBA &color, bool &flash, bool &bold) color.b = 146; break; case 'w': - color.r = 175; - color.g = 175; - color.b = 175; - break; -#ifdef FIX_BUGS - case 'x': - color.r = 0; - color.g = 255; - color.b = 255; + color.r = 225; + color.g = 225; + color.b = 225; + Details.anonymous_23 = true; break; -#else case 'x': color.r = 132; color.g = 146; color.b = 197; break; -#endif case 'y': color.r = 255; - color.g = 227; - color.b = 79; + color.g = 255; + color.b = 0; break; #ifdef BUTTON_ICONS case 'U': PS2Symbol = BUTTON_UP; break; @@ -1536,187 +1294,34 @@ CFont::ParseToken(wchar* str, CRGBA &color, bool &flash, bool &bold) } while (*s != '~') ++s; - if (*(++s) == '~') - s = ParseToken(s, color, flash, bold); - return s; -} -#if 0//def MORE_LANGUAGES -wchar* -CFont::ParseToken(wchar *s, bool japShit) -{ + // seem to be gone in lcs + //if (*(++s) == '~') + // s = ParseToken(s, color, flash, bold); + + // wtf? + if (*s == '\0') s++; s++; - if ((Details.color.r || Details.color.g || Details.color.b) && !japShit) { - wchar c = *s; - if (IsJapanese()) - c &= 0x7FFF; - switch (c) { - case 'N': - case 'n': - NewLine = true; - break; - case 'b': SetColor(CRGBA(128, 167, 243, 255)); break; - case 'g': SetColor(CRGBA(95, 160, 106, 255)); break; - case 'h': SetColor(CRGBA(225, 225, 225, 255)); break; - case 'l': SetColor(CRGBA(0, 0, 0, 255)); break; - case 'p': SetColor(CRGBA(168, 110, 252, 255)); break; - case 'r': SetColor(CRGBA(113, 43, 73, 255)); break; - case 'w': SetColor(CRGBA(175, 175, 175, 255)); break; - case 'y': SetColor(CRGBA(210, 196, 106, 255)); break; -#ifdef BUTTON_ICONS - case 'U': PS2Symbol = BUTTON_UP; break; - case 'D': PS2Symbol = BUTTON_DOWN; break; - case '<': PS2Symbol = BUTTON_LEFT; break; - case '>': PS2Symbol = BUTTON_RIGHT; break; - case 'X': PS2Symbol = BUTTON_CROSS; break; - case 'O': PS2Symbol = BUTTON_CIRCLE; break; - case 'Q': PS2Symbol = BUTTON_SQUARE; break; - case 'T': PS2Symbol = BUTTON_TRIANGLE; break; - case 'K': PS2Symbol = BUTTON_L1; break; - case 'M': PS2Symbol = BUTTON_L2; break; - case 'A': PS2Symbol = BUTTON_L3; break; - case 'J': PS2Symbol = BUTTON_R1; break; - case 'V': PS2Symbol = BUTTON_R2; break; - case 'C': PS2Symbol = BUTTON_R3; break; - case 'H': PS2Symbol = BUTTON_RSTICK_UP; break; - case 'L': PS2Symbol = BUTTON_RSTICK_DOWN; break; - case '(': PS2Symbol = BUTTON_RSTICK_LEFT; break; - case ')': PS2Symbol = BUTTON_RSTICK_RIGHT; break; -#endif - } - } else if (IsJapanese()) { - if ((*s & 0x7FFF) == 'N' || (*s & 0x7FFF) == 'n') - NewLine = true; - } - while ((!IsJapanese() || (*s != JAP_TERMINATION)) && *s != '~') s++; - return s + 1; + return s; } -#else + +//--LCS: done wchar* CFont::ParseToken(wchar *s) { - Details.anonymous_23 = false; - s++; - if(Details.color.r || Details.color.g || Details.color.b) - switch(*s){ - case 'B': - Details.bBold = !Details.bBold; - break; - case 'N': - case 'n': - NewLine = true; - break; - case 'b': - Details.color.r = 27; - Details.color.g = 89; - Details.color.b = 130; - Details.anonymous_23 = true; - break; - case 'f': - Details.bFlash = !Details.bFlash; - if (!Details.bFlash) - Details.color.a = 255; - break; - case 'g': - Details.color.r = 255; - Details.color.g = 150; - Details.color.b = 225; - Details.anonymous_23 = true; - break; - case 'h': - Details.color.r = 225; - Details.color.g = 225; - Details.color.b = 225; - Details.anonymous_23 = true; - break; - case 'l': - Details.color.r = 0; - Details.color.g = 0; - Details.color.b = 0; - Details.anonymous_23 = true; - break; - case 'o': - Details.color.r = 229; - Details.color.g = 125; - Details.color.b = 126; - Details.anonymous_23 = true; - break; - case 'p': - Details.color.r = 168; - Details.color.g = 110; - Details.color.b = 252; - Details.anonymous_23 = true; - break; - case 'q': - Details.color.r = 199; - Details.color.g = 144; - Details.color.b = 203; - Details.anonymous_23 = true; - break; - case 'r': - Details.color.r = 255; - Details.color.g = 150; - Details.color.b = 225; - Details.anonymous_23 = true; - break; - case 't': - Details.color.r = 86; - Details.color.g = 212; - Details.color.b = 146; - Details.anonymous_23 = true; - break; - case 'w': - Details.color.r = 175; - Details.color.g = 175; - Details.color.b = 175; - Details.anonymous_23 = true; - break; - case 'x': -#ifdef FIX_BUGS - Details.color.r = 0; - Details.color.g = 255; - Details.color.b = 255; -#else - Details.color.r = 132; - Details.color.g = 146; - Details.color.b = 197; -#endif - Details.anonymous_23 = true; - break; - case 'y': - Details.color.r = 255; - Details.color.g = 227; - Details.color.b = 79; - Details.anonymous_23 = true; - break; -#ifdef BUTTON_ICONS - case 'U': PS2Symbol = BUTTON_UP; break; - case 'D': PS2Symbol = BUTTON_DOWN; break; - case '<': PS2Symbol = BUTTON_LEFT; break; - case '>': PS2Symbol = BUTTON_RIGHT; break; - case 'X': PS2Symbol = BUTTON_CROSS; break; - case 'O': PS2Symbol = BUTTON_CIRCLE; break; - case 'Q': PS2Symbol = BUTTON_SQUARE; break; - case 'T': PS2Symbol = BUTTON_TRIANGLE; break; - case 'K': PS2Symbol = BUTTON_L1; break; - case 'M': PS2Symbol = BUTTON_L2; break; - case 'A': PS2Symbol = BUTTON_L3; break; - case 'J': PS2Symbol = BUTTON_R1; break; - case 'V': PS2Symbol = BUTTON_R2; break; - case 'C': PS2Symbol = BUTTON_R3; break; - case 'H': PS2Symbol = BUTTON_RSTICK_UP; break; - case 'L': PS2Symbol = BUTTON_RSTICK_DOWN; break; - case '(': PS2Symbol = BUTTON_RSTICK_LEFT; break; - case ')': PS2Symbol = BUTTON_RSTICK_RIGHT; break; -#endif - } - while(*s != '~') s++; - if (*(++s) == '~') - s = ParseToken(s); + bool flash = false; + bool bold = false; + CRGBA color = Details.color; + s = ParseToken(s, color, flash, bold); + Details.bFlash = flash; + Details.bBold = bold; + + if (Details.anonymous_23) + Details.color = color; return s; } -#endif +//--LCS: done void CFont::FilterOutTokensFromString(wchar *str) { @@ -1735,25 +1340,22 @@ CFont::FilterOutTokensFromString(wchar *str) str[newIdx] = '\0'; } +//--LCS: done void CFont::DrawFonts(void) { RenderFontBuffer(); } +//--LCS: done void CFont::SetScale(float x, float y) { -#ifdef MORE_LANGUAGES - /*if (IsJapanese()) { - x *= 1.35f; - y *= 1.25f; - }*/ -#endif Details.scaleX = x; Details.scaleY = y; } +//--LCS: done void CFont::SetSlantRefPoint(float x, float y) { @@ -1761,12 +1363,14 @@ CFont::SetSlantRefPoint(float x, float y) Details.slantRefY = y; } +//--LCS: done void CFont::SetSlant(float s) { Details.slant = s; } +//--LCS: done void CFont::SetColor(CRGBA col) { @@ -1775,6 +1379,14 @@ CFont::SetColor(CRGBA col) Details.color.a *= Details.alphaFade / 255.0f; } +//--LCS: done +void +CFont::SetFlashOff() +{ + Details.bFlash = false; +} + +//--LCS: done void CFont::SetJustifyOn(void) { @@ -1783,6 +1395,7 @@ CFont::SetJustifyOn(void) Details.rightJustify = false; } +//--LCS: done void CFont::SetJustifyOff(void) { @@ -1790,6 +1403,7 @@ CFont::SetJustifyOff(void) Details.rightJustify = false; } +//--LCS: done void CFont::SetCentreOn(void) { @@ -1798,54 +1412,65 @@ CFont::SetCentreOn(void) Details.rightJustify = false; } +//--LCS: done void CFont::SetCentreOff(void) { Details.centre = false; } +//--LCS: TODO void CFont::SetWrapx(float x) { + // uncomment when scaling is done + //x = clamp(x, 0.0f, DEFAULT_SCREEN_WIDTH); Details.wrapX = x; } +//--LCS: done void CFont::SetCentreSize(float s) { Details.centreSize = s; } +//--LCS: done void CFont::SetBackgroundOn(void) { Details.background = true; } +//--LCS: done void CFont::SetBackgroundOff(void) { Details.background = false; } +//--LCS: done void CFont::SetBackgroundColor(CRGBA col) { Details.backgroundColor = col; } +//--LCS: done void CFont::SetBackGroundOnlyTextOn(void) { Details.backgroundOnlyText = true; } +//--LCS: done void CFont::SetBackGroundOnlyTextOff(void) { Details.backgroundOnlyText = false; } +//--LCS: done void CFont::SetRightJustifyOn(void) { @@ -1854,6 +1479,7 @@ CFont::SetRightJustifyOn(void) Details.centre = false; } +//--LCS: done void CFont::SetRightJustifyOff(void) { @@ -1862,70 +1488,118 @@ CFont::SetRightJustifyOff(void) Details.centre = false; } +//--LCS: done void CFont::SetPropOff(void) { Details.proportional = false; } +//--LCS: done void CFont::SetPropOn(void) { Details.proportional = true; } +//--LCS: done void CFont::SetFontStyle(int16 style) { if (style == FONT_HEADING) { - Details.style = FONT_STANDARD; + Details.style = FONT_HEADING; Details.bFontHalfTexture = true; - } else { + } + else { Details.style = style; Details.bFontHalfTexture = false; } } +//--LCS: done void CFont::SetRightJustifyWrap(float wrap) { Details.rightJustifyWrap = wrap; } +//--LCS: done void CFont::SetAlphaFade(float fade) { Details.alphaFade = fade; } +//--LCS: done void CFont::SetDropColor(CRGBA col) { Details.dropColor = col; if (Details.alphaFade < 255.0f) - Details.dropColor.a *= Details.alphaFade / 255.0f; + // TODO: was this a copypaste bug in here? + //Details.dropColor.a *= Details.alphaFade / 255.0f; + Details.dropColor.a = Details.color.a * Details.alphaFade / 255.0f; +} + + +//--LCS: done +void +CFont::SetOutlineColor(CRGBA col) +{ + Details.outlineColor = col; + if (Details.alphaFade < 255.0f) + Details.outlineColor.a *= Details.alphaFade / 255.0f; +} + +//--LCS: done +void +CFont::SetOutlineOn(int on) +{ + Details.bOutlineOn = on; } +//--LCS: done +void +CFont::SetNewLineAdd(int line) +{ + Details.line = line; +} + +//--LCS: done void CFont::SetDropShadowPosition(int16 pos) { Details.dropShadowPosition = pos; } -wchar CFont::FindNewCharacter(wchar c) +int16 CFont::FindNewCharacter(int16 c) { - if (c >= 16 && c <= 26) return c + 128; - if (c >= 8 && c <= 9) return c + 86; - if (c == 4) return c + 89; - if (c == 7) return 206; - if (c == 14) return 207; - if (c >= 33 && c <= 58) return c + 122; - if (c >= 65 && c <= 90) return c + 90; - if (c >= 96 && c <= 118) return c + 85; - if (c >= 119 && c <= 140) return c + 62; - if (c >= 141 && c <= 142) return 204; - if (c == 143) return 205; - if (c == 1) return 208; + if (c >= 33 && c <= 33 + 25) + return c - 6; + else if(c >= 65 && c <= 65 + 25) + return c - 38; + else if (c >= 96 && c <= 96 + 31) + return c - 43; + else if (c >= 128 && c <= 128 + 31) + return c - 75; + + switch (c) + { + case 190: + return 90; + case 175: + return 87; + case 184: + return 88; + case 187: + return 89; + case 31: + return 88; + } + if (c >= 27 && c < 31) + return 2; + if (c >= 180 && c < 256) + c = 2; return c; } @@ -1935,4 +1609,4 @@ CFont::character_code(uint8 c) if(c < 128) return c; return foreign_table[c-128]; -}
\ No newline at end of file +} diff --git a/src/renderer/Font.h b/src/renderer/Font.h index 02e7df3b..fdf5f3f2 100644 --- a/src/renderer/Font.h +++ b/src/renderer/Font.h @@ -39,6 +39,9 @@ struct CFontDetails int nFlashTimer; bool8 anonymous_23; uint32 anonymous_25; + CRGBA outlineColor; + int bOutlineOn; + int line; }; struct CFontRenderState @@ -58,6 +61,9 @@ struct CFontRenderState bool8 proportional; bool8 anonymous_14; int16 style; + int bOutlineOn; + int line; + bool8 rightJustify; }; class CSprite2d; @@ -66,10 +72,7 @@ enum { FONT_BANK, FONT_STANDARD, FONT_HEADING, -#ifdef MORE_LANGUAGES - FONT_JAPANESE, -#endif - MAX_FONTS = FONT_HEADING + MAX_FONTS }; enum { @@ -127,7 +130,7 @@ class CFont static uint8 LanguageSet; static int32 Slot; #else - static int16 Size[MAX_FONTS][210]; + static int16 Size[MAX_FONTS][419]; #endif static bool16 NewLine; public: @@ -151,7 +154,6 @@ public: static void PrintChar(float x, float y, wchar c); static void PrintString(float x, float y, wchar *s); #ifdef XBOX_SUBTITLES - static void PrintStringFromBottom(float x, float y, wchar *str); static void PrintOutlinedString(float x, float y, wchar *str, float outlineStrength, bool fromBottom, CRGBA outlineColor); #endif static int GetNumberLines(float xstart, float ystart, wchar *s); @@ -162,7 +164,7 @@ public: static void PrintString(float x, float y, uint32, wchar *start, wchar *end, float spwidth); //#endif static void PrintStringFromBottom(float x, float y, wchar *str); - static float GetCharacterWidth(wchar c); + static float GetCharacterWidth(wchar c, bool forceProportional = false); static float GetCharacterSize(wchar c); static float GetStringWidth(wchar *s, bool spaces = false); #ifdef MORE_LANGUAGES @@ -194,6 +196,7 @@ public: static void SetBackgroundOff(void); static void SetBackGroundOnlyTextOn(void); static void SetBackGroundOnlyTextOff(void); + static void SetFlashOff(void); static void SetPropOn(void); static void SetPropOff(void); static void SetFontStyle(int16 style); @@ -203,8 +206,14 @@ public: static void SetBackgroundColor(CRGBA col); static void SetColor(CRGBA col); static void SetDropColor(CRGBA col); - static wchar FindNewCharacter(wchar c); + + static void SetOutlineColor(CRGBA col); + static void SetOutlineOn(int on); + static void SetNewLineAdd(int line); + + static int16 FindNewCharacter(int16 c); static void FilterOutTokensFromString(wchar*); + static bool16 CheckNewLine(wchar *s); #ifdef MORE_LANGUAGES static void ReloadFonts(uint8 set); diff --git a/src/renderer/Hud.cpp b/src/renderer/Hud.cpp index d7d8050f..5c0db44c 100644 --- a/src/renderer/Hud.cpp +++ b/src/renderer/Hud.cpp @@ -45,14 +45,14 @@ // Game has colors inlined in code. // For easier modification we collect them here: CRGBA MONEY_COLOR(0, 207, 133, 255); -CRGBA AMMO_COLOR(255, 150, 225, 255); +CRGBA AMMO_COLOR(255, 255, 255, 255); CRGBA HEALTH_COLOR(255, 150, 225, 255); CRGBA ARMOUR_COLOR(185, 185, 185, 255); CRGBA NOTWANTED_COLOR(27, 89, 130, 255); CRGBA WANTED_COLOR_FLASH(62, 141, 181, 255); CRGBA WANTED_COLOR(97, 194, 247, 255); -CRGBA ZONE_COLOR(45, 155, 90, 255); -CRGBA VEHICLE_COLOR(97, 194, 247, 255); +CRGBA ZONE_COLOR(255, 255, 255, 255); +CRGBA VEHICLE_COLOR(255, 255, 255, 255); CRGBA CLOCK_COLOR(97, 194, 247, 255); CRGBA TIMER_COLOR(97, 194, 247, 255); CRGBA COUNTER_COLOR(97, 194, 247, 255); @@ -95,7 +95,7 @@ bool CHud::m_HideRadar; int32 CHud::m_ClockState; // These aren't really in CHud -float CHud::BigMessageInUse[6]; +float BigMessageInUse[6]; float CHud::BigMessageAlpha[6]; float CHud::BigMessageX[6]; float CHud::OddJob2OffTimer; @@ -134,6 +134,10 @@ uint32 CHud::m_LastTimeEnergyLost; CSprite2d CHud::Sprites[NUM_HUD_SPRITES]; +wchar* CHud::gLastPrintForeverString; + +uint8 CHud::m_HudAlpha = 209; + struct { const char *name; @@ -190,24 +194,25 @@ struct { "", "" }, { "", "" }, { "radardisc", "radardisc" }, + { "radardiscback", "" }, { "", "" }, { "", "" }, { "", "" }, { "", "" }, { "", "" }, - { "", "" }, - { "", "" }, - { "", "" }, - { "", "" }, - { "", "" }, - { "", "" }, - { "", "" }, + { "bar_inside1dark", "" }, + { "bar_inside2dark", "" }, + { "hudnumbers", "" }, + { "bar_inside1", "" }, + { "bar_inside2", "" }, + { "bar_outline", "" }, { "sitesniper", "sitesniperm" }, { "siteM16", "siteM16m" }, { "sitelaser", "sitelaserm" }, { "laserdot", "laserdotm" }, { "viewfinder_128", "viewfinder_128m" }, - { "bleeder", "" } + { "bleeder", "" }, + { "gren_rem", "noMaskNeeded" } }; RwTexture *gpSniperSightTex; @@ -216,6 +221,7 @@ RwTexture *gpLaserSightTex; RwTexture *gpLaserDotTex; RwTexture *gpViewFinderTex; +// TODO(LCS): some things were reversed from LCS but not all void CHud::Draw() { RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERNEAREST); @@ -408,6 +414,8 @@ void CHud::Draw() DrawMoneyCounter */ + RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERLINEAR); // TODO(LCS): temp filtering fix for money counter, remove later + wchar sPrint[16]; wchar sPrintIcon[16]; char sTemp[16]; @@ -420,25 +428,8 @@ void CHud::Draw() m_LastDisplayScore = CWorld::Players[CWorld::PlayerInFocus].m_nVisibleMoney; } if (m_DisplayScoreState != FADED_OUT) { - sprintf(sTemp, "$%08d", CWorld::Players[CWorld::PlayerInFocus].m_nVisibleMoney); - AsciiToUnicode(sTemp, sPrint); - - CFont::SetPropOff(); - CFont::SetBackgroundOff(); - CFont::SetScale(SCREEN_SCALE_X(HUD_TEXT_SCALE_X), SCREEN_SCALE_Y(HUD_TEXT_SCALE_Y)); - CFont::SetCentreOff(); - CFont::SetRightJustifyOn(); - CFont::SetRightJustifyWrap(0.0f); - CFont::SetBackGroundOnlyTextOff(); - CFont::SetFontStyle(FONT_HEADING); - CFont::SetPropOff(); - CFont::SetDropShadowPosition(2); - CFont::SetDropColor(CRGBA(0, 0, 0, alpha)); - MONEY_COLOR.a = alpha; - CFont::SetColor(MONEY_COLOR); - if (FrontEndMenuManager.m_PrefsShowHud) { - CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(110.0f), SCREEN_SCALE_Y(43.0f), sPrint); + DrawCash(); } } @@ -451,46 +442,23 @@ void CHud::Draw() alpha = CHud::DrawFadeState(HUD_WEAPON_FADING, 1); m_LastWeapon = playerPed->GetWeapon()->m_eWeaponType; } + alpha = Min(alpha, m_HudAlpha); if (m_WeaponState != FADED_OUT) { CWeapon *weapon = playerPed->GetWeapon(); - int32 AmmoAmount = CWeaponInfo::GetWeaponInfo((eWeaponType)WeaponType)->m_nAmountofAmmunition; - int32 AmmoInClip = weapon->m_nAmmoInClip; - int32 TotalAmmo = weapon->m_nAmmoTotal; - int32 Ammo, Clip; - - if (AmmoAmount <= 1 || AmmoAmount >= 1000) - sprintf(sTemp, "%d", TotalAmmo); - else { - if (WeaponType == WEAPONTYPE_FLAMETHROWER) { - Clip = AmmoInClip / 10; - - Ammo = Min((TotalAmmo - AmmoInClip) / 10, 9999); - } else { - Clip = AmmoInClip; - - Ammo = Min(TotalAmmo - AmmoInClip, 9999); - } - - sprintf(sTemp, "%d-%d", Ammo, Clip); - } - - AsciiToUnicode(sTemp, sPrint); CWeaponInfo *weaponInfo = CWeaponInfo::GetWeaponInfo((eWeaponType)WeaponType); /* DrawWeaponIcon */ if (FrontEndMenuManager.m_PrefsShowHud) { + float right = FrontEndMenuManager.m_PrefsUseWideScreen ? 468.6f : 470.0f; + float left = right - (FrontEndMenuManager.m_PrefsUseWideScreen ? 48.6f : 54.0f); if (weaponInfo->m_nModelId <= 0) { RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERLINEAR); if (FrontEndMenuManager.m_PrefsShowHud) Sprites[WeaponType].Draw( - CRect(SCREEN_SCALE_FROM_RIGHT(99.0f), SCREEN_SCALE_Y(27.0f), SCREEN_SCALE_FROM_RIGHT(35.0f), SCREEN_SCALE_Y(91.0f)), - CRGBA(255, 255, 255, alpha), - 0.015f, 0.015f, - 1.0f, 0.0f, - 0.015f, 1.0f, - 1.0f, 1.0f); + CRect(PSP_SCREEN_SCALE_X(left), PSP_SCREEN_SCALE_Y(16.0f), PSP_SCREEN_SCALE_X(right), PSP_SCREEN_SCALE_Y(60.0f)), + CRGBA(255, 255, 255, alpha)); } else { CBaseModelInfo *weaponModel = CModelInfo::GetModelInfo(weaponInfo->m_nModelId); RwTexDictionary *weaponTxd = CTxdStore::GetSlot(weaponModel->GetTxdSlot())->texDict; @@ -510,12 +478,8 @@ void CHud::Draw() static CSprite2d sprite; sprite.m_pTexture = weaponIcon; sprite.Draw( - CRect(SCREEN_SCALE_FROM_RIGHT(99.0f), SCREEN_SCALE_Y(27.0f), SCREEN_SCALE_FROM_RIGHT(35.0f), SCREEN_SCALE_Y(91.0f)), - CRGBA(255, 255, 255, alpha), - 0.015f, 0.015f, - 1.0f, 0.0f, - 0.015f, 1.0f, - 1.0f, 1.0f); + CRect(PSP_SCREEN_SCALE_X(left), PSP_SCREEN_SCALE_Y(16.0f), PSP_SCREEN_SCALE_X(right), PSP_SCREEN_SCALE_Y(60.0f)), + CRGBA(255, 255, 255, alpha)); sprite.m_pTexture = nil; #endif } @@ -523,7 +487,7 @@ void CHud::Draw() } CFont::SetBackgroundOff(); - CFont::SetScale(SCREEN_SCALE_X(0.5f), SCREEN_SCALE_Y(0.8f)); + CFont::SetScale(PSP_SCREEN_SCALE_X(FrontEndMenuManager.m_PrefsUseWideScreen ? 0.18f : 0.2f), PSP_SCREEN_SCALE_Y(0.44f)); CFont::SetJustifyOff(); CFont::SetCentreOn(); CFont::SetCentreSize(SCREEN_STRETCH_X(DEFAULT_SCREEN_WIDTH)); @@ -531,13 +495,65 @@ void CHud::Draw() CFont::SetDropShadowPosition(0); CFont::SetFontStyle(FONT_STANDARD); + int32 AmmoAmount = CWeaponInfo::GetWeaponInfo((eWeaponType)WeaponType)->m_nAmountofAmmunition; + int32 AmmoInClip = weapon->m_nAmmoInClip; + int32 TotalAmmo = weapon->m_nAmmoTotal; + int32 Ammo, Clip; + if (Min(9999, TotalAmmo - AmmoInClip) != 9999 && !CDarkel::FrenzyOnGoing() && weaponInfo->m_nWeaponSlot > 1 && weapon->m_eWeaponType != WEAPONTYPE_DETONATOR) { CFont::SetDropShadowPosition(2); CFont::SetDropColor(CRGBA(0, 0, 0, alpha)); AMMO_COLOR.a = alpha; CFont::SetColor(AMMO_COLOR); - if (FrontEndMenuManager.m_PrefsShowHud) - CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(66.0f), SCREEN_SCALE_Y(90.0f), sPrint); + if (FrontEndMenuManager.m_PrefsShowHud) { + + + if (AmmoAmount <= 1 || AmmoAmount >= 1000) + { + sprintf(sTemp, "%d", TotalAmmo); + AsciiToUnicode(sTemp, sPrint); + float pos = 435.0f; +#ifdef FIX_BUGS + if (FrontEndMenuManager.m_PrefsUseWideScreen) + pos = 438.0f; +#endif + CFont::PrintString(PSP_SCREEN_SCALE_FROM_RIGHT(PSP_DEFAULT_SCREEN_WIDTH - pos), PSP_SCREEN_SCALE_Y(42.0f), sPrint); + } + else { + + if (WeaponType == WEAPONTYPE_FLAMETHROWER) { + Clip = AmmoInClip / 10; + + Ammo = Min((TotalAmmo - AmmoInClip) / 10, 9999); + } + else { + Clip = AmmoInClip; + + Ammo = Min(TotalAmmo - AmmoInClip, 9999); + } + + char sMinus[10]; + char sAmmo[20]; + char sClip[20]; + + sprintf(sMinus, "-"); + sprintf(sAmmo, "%d", Ammo); + sprintf(sClip, "%d", Clip); + + CFont::SetCentreOff(); + CFont::SetRightJustifyOn(); + AsciiToUnicode(sAmmo, sPrint); + CFont::PrintString(PSP_SCREEN_SCALE_FROM_RIGHT(PSP_DEFAULT_SCREEN_WIDTH - (FrontEndMenuManager.m_PrefsUseWideScreen ? 438.0f : 435.0f)), PSP_SCREEN_SCALE_Y(42.0f), sPrint); + + CFont::SetRightJustifyOff(); + AsciiToUnicode(sMinus, sPrint); + CFont::PrintString(PSP_SCREEN_SCALE_FROM_RIGHT(PSP_DEFAULT_SCREEN_WIDTH - (FrontEndMenuManager.m_PrefsUseWideScreen ? 439.0f : 436.0f)), PSP_SCREEN_SCALE_Y(42.0f), sPrint); + + AsciiToUnicode(sClip, sPrint); + CFont::PrintString(PSP_SCREEN_SCALE_FROM_RIGHT(PSP_DEFAULT_SCREEN_WIDTH - (FrontEndMenuManager.m_PrefsUseWideScreen ? 441.0f : 439.0f)), PSP_SCREEN_SCALE_Y(42.0f), sPrint); + + } + } CFont::SetDropShadowPosition(0); } } @@ -571,23 +587,8 @@ void CHud::Draw() && FRAMECOUNTER & 8) { if (playerPed->m_fHealth >= 10 || playerPed->m_fHealth < 10 && FRAMECOUNTER & 8) { - - AsciiToUnicode("{", sPrintIcon); -#ifdef FIX_BUGS - sprintf(sTemp, "%03d", int32(playerPed->m_fHealth + 0.5f)); -#else - sprintf(sTemp, "%03d", (int32)playerPed->m_fHealth); -#endif - AsciiToUnicode(sTemp, sPrint); - - CFont::SetColor(HEALTH_COLOR); if (FrontEndMenuManager.m_PrefsShowHud) { - CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(110.0f), SCREEN_SCALE_Y(65.0f), sPrint); - - if (!CWorld::Players[CWorld::PlayerInFocus].m_nTimeLastHealthLoss || CTimer::GetTimeInMilliseconds() > CWorld::Players[CWorld::PlayerInFocus].m_nTimeLastHealthLoss + 2000 || FRAMECOUNTER & 4) { - // CFont::SetColor(HEALTH_COLOR); - CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(110.0f + 54.0f), SCREEN_SCALE_Y(65.0f), sPrintIcon); - } + DrawHealthBar(playerPed->m_fHealth); } } } @@ -608,13 +609,7 @@ void CHud::Draw() CFont::SetColor(ARMOUR_COLOR); if (FrontEndMenuManager.m_PrefsShowHud) { - - CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(182.0f), SCREEN_SCALE_Y(65.0f), sPrint); - - if (!CWorld::Players[CWorld::PlayerInFocus].m_nTimeLastArmourLoss || CTimer::GetTimeInMilliseconds() > CWorld::Players[CWorld::PlayerInFocus].m_nTimeLastArmourLoss + 2000 || FRAMECOUNTER & 4) { - // CFont::SetColor(ARMOUR_COLOR); - CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(182.0f + 52.0f), SCREEN_SCALE_Y(65.0f), sPrintIcon); - } + DrawArmourBar(playerPed->m_fArmour); } } } @@ -631,36 +626,23 @@ void CHud::Draw() } if (m_WantedState != FADED_OUT) { - CFont::SetBackgroundOff(); - CFont::SetScale(SCREEN_SCALE_X(HUD_TEXT_SCALE_X), SCREEN_SCALE_Y(HUD_TEXT_SCALE_Y)); - CFont::SetJustifyOff(); - CFont::SetCentreOff(); - CFont::SetRightJustifyOn(); - CFont::SetPropOn(); - CFont::SetFontStyle(FONT_STANDARD); - - AsciiToUnicode(">", sPrintIcon); - + char wantedStar[] = "\x16"; + float starX = 441.0f; for (int i = 0; i < 6; i++) { if (FrontEndMenuManager.m_PrefsShowHud) { if (playerPed->m_pWanted->GetWantedLevel() > i && (CTimer::GetTimeInMilliseconds() > playerPed->m_pWanted->m_nLastWantedLevelChange + 2000 || FRAMECOUNTER & 4)) { - WANTED_COLOR.a = alpha; - CFont::SetColor(WANTED_COLOR); - CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(110.0f + 23.0f * i), SCREEN_SCALE_Y(87.0f), sPrintIcon); + DrawTimeAndCashNumbers(wantedStar, starX, 63.0f, false); } else if (playerPed->m_pWanted->m_nMinWantedLevel > i && FRAMECOUNTER & 4) { - WANTED_COLOR_FLASH.a = alpha; - CFont::SetColor(WANTED_COLOR_FLASH); - CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(110.0f + 23.0f * i), SCREEN_SCALE_Y(87.0f), sPrintIcon); - - } else if (playerPed->m_pWanted->GetWantedLevel() <= i) { - NOTWANTED_COLOR.a = alpha; - CFont::SetColor(NOTWANTED_COLOR); - CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(110.0f + 23.0f * i), SCREEN_SCALE_Y(87.0f), sPrintIcon); + DrawTimeAndCashNumbers(wantedStar, starX, 63.0f, true); } + if (FrontEndMenuManager.m_PrefsUseWideScreen) + starX -= 11.0f; + else + starX -= 13.5f; } } } @@ -788,14 +770,14 @@ void CHud::Draw() CFont::SetPropOn(); CFont::SetBackgroundOff(); - if (FrontEndMenuManager.m_PrefsLanguage == CMenuManager::LANGUAGE_SPANISH) - CFont::SetScale(SCREEN_SCALE_X(1.7f * 0.8f), SCREEN_SCALE_Y(1.8f)); + if (FrontEndMenuManager.m_PrefsUseWideScreen) + CFont::SetScale(PSP_SCREEN_SCALE_X(0.42768f), PSP_SCREEN_SCALE_Y(0.88f)); else - CFont::SetScale(SCREEN_SCALE_X(1.7f), SCREEN_SCALE_Y(1.8f)); - - CFont::SetSlantRefPoint(SCREEN_SCALE_FROM_RIGHT(32.0f), SCREEN_SCALE_FROM_BOTTOM(128.0f)); - CFont::SetSlant(0.15f); + CFont::SetScale(PSP_SCREEN_SCALE_X(0.4752f), PSP_SCREEN_SCALE_Y(0.88f)); + //CFont::SetSlantRefPoint(SCREEN_SCALE_FROM_RIGHT(32.0f), SCREEN_SCALE_FROM_BOTTOM(128.0f)); + //CFont::SetSlant(0.15f); + CFont::SetWrapx(SCREEN_WIDTH); CFont::SetRightJustifyOn(); CFont::SetRightJustifyWrap(0.0f); CFont::SetBackGroundOnlyTextOff(); @@ -805,9 +787,9 @@ void CHud::Draw() CFont::SetColor(CRGBA(ZONE_COLOR.r, ZONE_COLOR.g, ZONE_COLOR.b, fZoneAlpha)); if (!CTheScripts::bPlayerIsInTheStatium) - CFont::PrintStringFromBottom(SCREEN_SCALE_FROM_RIGHT(32.0f), SCREEN_SCALE_FROM_BOTTOM(128.0f), m_ZoneToPrint); + CFont::PrintStringFromBottom(PSP_SCREEN_SCALE_FROM_RIGHT(24.0f), PSP_SCREEN_SCALE_FROM_BOTTOM(16.0f), m_ZoneToPrint); - CFont::SetSlant(0.f); + //CFont::SetSlant(0.f); } else { m_ZoneState = 3; } @@ -888,13 +870,14 @@ void CHud::Draw() CFont::SetPropOn(); CFont::SetBackgroundOff(); - if (FrontEndMenuManager.m_PrefsLanguage != CMenuManager::LANGUAGE_ITALIAN && FrontEndMenuManager.m_PrefsLanguage != CMenuManager::LANGUAGE_SPANISH) - CFont::SetScale(SCREEN_SCALE_X(1.7f), SCREEN_SCALE_Y(1.8f)); + if (FrontEndMenuManager.m_PrefsUseWideScreen) + CFont::SetScale(PSP_SCREEN_SCALE_X(0.42768f), PSP_SCREEN_SCALE_Y(0.88f)); else - CFont::SetScale(SCREEN_SCALE_X(1.7f * 0.85f), SCREEN_SCALE_Y(1.8f)); + CFont::SetScale(PSP_SCREEN_SCALE_X(0.4752f), PSP_SCREEN_SCALE_Y(0.88f)); - CFont::SetSlantRefPoint(SCREEN_SCALE_FROM_RIGHT(32.0f), SCREEN_SCALE_FROM_BOTTOM(105.0f)); - CFont::SetSlant(0.15f); + CFont::SetWrapx(SCREEN_WIDTH); + CFont::SetSlantRefPoint(PSP_SCREEN_SCALE_FROM_RIGHT(24.0f), PSP_SCREEN_SCALE_FROM_BOTTOM(35.6f)); + CFont::SetSlant(0.f); CFont::SetRightJustifyOn(); CFont::SetRightJustifyWrap(0.0f); @@ -904,7 +887,7 @@ void CHud::Draw() CFont::SetColor(CRGBA(VEHICLE_COLOR.r, VEHICLE_COLOR.g, VEHICLE_COLOR.b, fVehicleAlpha)); CFont::SetDropColor(CRGBA(0, 0, 0, fVehicleAlpha)); - CFont::PrintStringFromBottom(SCREEN_SCALE_FROM_RIGHT(32.0f), SCREEN_SCALE_FROM_BOTTOM(105.0f), m_pVehicleNameToPrint); + CFont::PrintStringFromBottom(PSP_SCREEN_SCALE_FROM_RIGHT(24.0f), PSP_SCREEN_SCALE_FROM_BOTTOM(35.6f), m_pVehicleNameToPrint); CFont::SetSlant(0.f); } @@ -921,24 +904,8 @@ void CHud::Draw() DrawClock */ if (m_ClockState) { - CFont::SetJustifyOff(); - CFont::SetCentreOff(); - CFont::SetBackgroundOff(); - CFont::SetScale(SCREEN_SCALE_X(HUD_TEXT_SCALE_X), SCREEN_SCALE_Y(HUD_TEXT_SCALE_Y)); - CFont::SetBackGroundOnlyTextOff(); - CFont::SetPropOff(); - CFont::SetFontStyle(FONT_HEADING); - CFont::SetRightJustifyOn(); - CFont::SetRightJustifyWrap(0.0f); - CFont::SetDropShadowPosition(2); - CFont::SetDropColor(CRGBA(0, 0, 0, 255)); - - sprintf(sTemp, "%02d:%02d", CClock::GetHours(), CClock::GetMinutes()); - AsciiToUnicode(sTemp, sPrint); - - CFont::SetColor(CLOCK_COLOR); if (FrontEndMenuManager.m_PrefsShowHud) - CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(111.0f), SCREEN_SCALE_Y(22.0f), sPrint); + DrawTime(); } /* @@ -1205,7 +1172,7 @@ void CHud::Draw() onceItWasWidescreen = false; CFont::DrawFonts(); - CFont::SetDropShadowPosition(2); + CFont::SetDropShadowPosition(0); CFont::SetDropColor(CRGBA(0, 0, 0, 255)); CFont::SetScale(SCREEN_SCALE_X(0.58f), SCREEN_SCALE_Y(1.22f)); @@ -1431,6 +1398,221 @@ void CHud::Draw() } } +int HealthFlashTimer = 50; + +void +CHud::DrawHealthBar(int16 value) +{ + if (m_ItemToFlash == ITEM_HEALTH) { + if (CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_fHealth > 10.0f) { + if (HealthFlashTimer-- == 0) { + m_ItemToFlash = -1; + HealthFlashTimer = 50; + } + } + } + float fHealth = value; + float fMaxHealth = CWorld::Players[CWorld::PlayerInFocus].m_nMaxHealth; + fHealth = Clamp(fHealth, 0.0f, fMaxHealth); + float fWidth = (fHealth / fMaxHealth) * 40.0f + 16.0f + 4.0f; + float u = fWidth / 64.0f; + if (value == 0) { + fWidth = 0.0f; + u = 0.0f; + } else if (value == fMaxHealth) { + fWidth = 64.0f; + u = 1.0f; + } + + if (FrontEndMenuManager.m_PrefsUseWideScreen) + fWidth *= 0.68f; + else + fWidth *= 0.85f; + + float fX1 = FrontEndMenuManager.m_PrefsUseWideScreen ? 375.0f : 360.0f; + float fX2 = fWidth + (FrontEndMenuManager.m_PrefsUseWideScreen ? 375.0f : 360.0f); + CRect rect1(PSP_SCREEN_SCALE_X(fX1), PSP_SCREEN_SCALE_Y(40.0f), PSP_SCREEN_SCALE_X(fX2), PSP_SCREEN_SCALE_Y(50.0f)); + CRGBA color1(255, 255, 255, m_HudAlpha); + Sprites[HUD_BAR_INSIDE2].Draw(rect1, color1, 0.0f, 0.0f, u, 0.0f, 0.0f, 1.0f, u, 1.0f); + + fX1 = fWidth + (FrontEndMenuManager.m_PrefsUseWideScreen ? 375.0f : 360.0f); + fX2 = (FrontEndMenuManager.m_PrefsUseWideScreen ? 43.52f : 54.4f) + (FrontEndMenuManager.m_PrefsUseWideScreen ? 375.0f : 360.0f); + CRect rect2(PSP_SCREEN_SCALE_X(fX1), PSP_SCREEN_SCALE_Y(40.0f), PSP_SCREEN_SCALE_X(fX2), PSP_SCREEN_SCALE_Y(50.0f)); + CRGBA color2(255, 255, 255, m_HudAlpha); + Sprites[HUD_BAR_INSIDE2DARK].Draw(rect2, color2, u, 0.0f, 1.0f, 0.0f, u, 1.0f, 1.0f, 1.0f); + + fX1 = FrontEndMenuManager.m_PrefsUseWideScreen ? 375.0f : 360.0f; + fX2 = (FrontEndMenuManager.m_PrefsUseWideScreen ? 43.52f : 54.4f) + (FrontEndMenuManager.m_PrefsUseWideScreen ? 375.0f : 360.0f); + CRect rect3(PSP_SCREEN_SCALE_X(fX1), PSP_SCREEN_SCALE_Y(40.0f), PSP_SCREEN_SCALE_X(fX2), PSP_SCREEN_SCALE_Y(50.0f)); + CRGBA color3(255, 255, 255, m_HudAlpha); + Sprites[HUD_BAR_OUTLINE].Draw(rect3, color3, 0.01f, 0.0f, 1.0f, 0.0f, 0.01f, 1.0f, 1.0f, 1.0f); + + if (fMaxHealth > 100.0f) + { + CFont::SetFontStyle(FONT_STANDARD); + CFont::SetDropShadowPosition(0); + CFont::SetDropColor(CRGBA(0, 0, 0, m_HudAlpha)); + CFont::SetColor(CRGBA(255, 255, 255, m_HudAlpha)); + CFont::SetCentreOn(); + if (fMaxHealth > 125.0f) + CFont::SetScale(FrontEndMenuManager.StretchX(PSP_SCALE_TO_PS2_X(FrontEndMenuManager.m_PrefsUseWideScreen ? 0.3375f : 0.45f)), FrontEndMenuManager.StretchY(PSP_SCALE_TO_PS2_Y(0.75f))); + else + CFont::SetScale(FrontEndMenuManager.StretchX(PSP_SCALE_TO_PS2_X(FrontEndMenuManager.m_PrefsUseWideScreen ? 0.2625f : 0.35f)), FrontEndMenuManager.StretchY(PSP_SCALE_TO_PS2_Y(0.6f))); + + if (FrontEndMenuManager.m_PrefsUseWideScreen) + fX1 = 375.0f + 12.0f; + else + fX1 = 360.0f + 15.0f; + CFont::PrintString(PSP_SCREEN_SCALE_X(fX1), PSP_SCREEN_SCALE_Y(36.0f), (wchar*)L"+"); + } + +} + +int ArmourFlashTimer = 50; + +void +CHud::DrawArmourBar(int16 value) +{ + if (m_ItemToFlash == ITEM_ARMOUR) { + if (CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_fArmour > 10.0f) { + if (ArmourFlashTimer-- == 0) { + m_ItemToFlash = -1; + ArmourFlashTimer = 50; + } + } + } + float fArmour = value; + float fMaxArmour = CWorld::Players[CWorld::PlayerInFocus].m_nMaxArmour; + fArmour = Clamp(fArmour, 0.0f, fMaxArmour); + float fWidth = (fArmour / fMaxArmour) * 40.0f + 16.0f + 4.0f; + float u = fWidth / 64.0f; + if (value == 0) { + fWidth = 0.0f; + u = 0.0f; + } else if (value == fMaxArmour) { + fWidth = 64.0f; + u = 1.0f; + } + + if (FrontEndMenuManager.m_PrefsUseWideScreen) + fWidth *= 0.68f; + else + fWidth *= 0.85f; + + float fX1 = FrontEndMenuManager.m_PrefsUseWideScreen ? 375.0f : 360.0f; + float fX2 = fWidth + (FrontEndMenuManager.m_PrefsUseWideScreen ? 375.0f : 360.0f); + CRect rect1(PSP_SCREEN_SCALE_X(fX1), PSP_SCREEN_SCALE_Y(28.0f), PSP_SCREEN_SCALE_X(fX2), PSP_SCREEN_SCALE_Y(38.0f)); + CRGBA color1(255, 255, 255, m_HudAlpha); + Sprites[HUD_BAR_INSIDE1].Draw(rect1, color1, 0.0f, 0.0f, u, 0.0f, 0.0f, 1.0f, u, 1.0f); + + fX1 = fWidth + (FrontEndMenuManager.m_PrefsUseWideScreen ? 375.0f : 360.0f); + fX2 = (FrontEndMenuManager.m_PrefsUseWideScreen ? 43.52f : 54.4f) + (FrontEndMenuManager.m_PrefsUseWideScreen ? 375.0f : 360.0f); + CRect rect2(PSP_SCREEN_SCALE_X(fX1), PSP_SCREEN_SCALE_Y(28.0f), PSP_SCREEN_SCALE_X(fX2), PSP_SCREEN_SCALE_Y(38.0f)); + CRGBA color2(255, 255, 255, m_HudAlpha); + Sprites[HUD_BAR_INSIDE1DARK].Draw(rect2, color2, u, 0.0f, 1.0f, 0.0f, u, 1.0f, 1.0f, 1.0f); + + fX1 = FrontEndMenuManager.m_PrefsUseWideScreen ? 375.0f : 360.0f; + fX2 = (FrontEndMenuManager.m_PrefsUseWideScreen ? 43.52f : 54.4f) + (FrontEndMenuManager.m_PrefsUseWideScreen ? 375.0f : 360.0f); + CRect rect3(PSP_SCREEN_SCALE_X(fX1), PSP_SCREEN_SCALE_Y(28.0f), PSP_SCREEN_SCALE_X(fX2), PSP_SCREEN_SCALE_Y(38.0f)); + CRGBA color3(255, 255, 255, m_HudAlpha); + Sprites[HUD_BAR_OUTLINE].Draw(rect3, color3, 0.01f, 0.0f, 1.0f, 0.0f, 0.01f, 1.0f, 1.0f, 1.0f); + + if (fMaxArmour > 100.0f) { + CFont::SetFontStyle(FONT_STANDARD); + CFont::SetDropShadowPosition(0); + CFont::SetDropColor(CRGBA(0, 0, 0, m_HudAlpha)); + CFont::SetColor(CRGBA(255, 255, 255, m_HudAlpha)); + CFont::SetCentreOn(); + if (fMaxArmour > 125.0f) + CFont::SetScale(FrontEndMenuManager.StretchX(PSP_SCALE_TO_PS2_X(FrontEndMenuManager.m_PrefsUseWideScreen ? 0.3375f : 0.45f)), FrontEndMenuManager.StretchY(PSP_SCALE_TO_PS2_Y(0.75f))); + else + CFont::SetScale(FrontEndMenuManager.StretchX(PSP_SCALE_TO_PS2_X(FrontEndMenuManager.m_PrefsUseWideScreen ? 0.2625f : 0.35f)), FrontEndMenuManager.StretchY(PSP_SCALE_TO_PS2_Y(0.6f))); + + if (FrontEndMenuManager.m_PrefsUseWideScreen) + fX1 = 375.0f + 12.0f; + else + fX1 = 360.0f + 15.0f; + CFont::PrintString(PSP_SCREEN_SCALE_X(fX1), PSP_SCREEN_SCALE_Y(24.0f), (wchar*)L"+"); + } + +} + +void +CHud::DrawTimeAndCashNumbers(char *str, float x, float y, bool secondSet) +{ + CRGBA color(255, 255, 255, m_HudAlpha); + + float width = 11.0f; + if (FrontEndMenuManager.m_PrefsUseWideScreen) + width = 9.0f; + + float height = 10.0f; + while (*str) { + uint8 c = *str; + if (c >= '0' && c <= ':') + { + if (secondSet) c -= '%'; + else c -= '0'; + } else { + if (c == 22) { + if (secondSet) + color = CRGBA(62, 141, 188, m_HudAlpha); + else + color = CRGBA(192, 155, 54, m_HudAlpha); + } else if (!secondSet) + c = 10; + else + c = 21; + } + + int row = c / 8; + int col = c - row * 8; + float width2 = width; + if (c == 22) + width2 += 3.0f; + CRect rect(PSP_SCREEN_SCALE_X(x), PSP_SCREEN_SCALE_Y(y), PSP_SCREEN_SCALE_X(x+ width2), PSP_SCREEN_SCALE_Y(y) + PSP_SCREEN_SCALE_Y(height)); + + float u = col * 0.125f; + // TODO(LCS): some odd calculation with u going on in here if it's < 0, it might be fabs, but maybe not + + float v = row * 0.265625f; + // TODO(LCS): same odd calculation with v as above + + str++; + Sprites[HUD_HUDNUMBERS].Draw(rect, color, u, v, u + 0.125f, v, u, v + 0.265625f, u + 0.125f, v + 0.265625f); + + x += (width - 2.0f); + if (c == 10) + x -= 4.0f; + +#ifdef GTA_PSP + x = Ceil(PSP_SCREEN_SCALE_X(x)) * ((float)PSP_DEFAULT_SCREEN_WIDTH / (float)SCREEN_WIDTH); +#else + // BUG: actually above wasn't PSP only but on higher resolutions things don't look like they were meant to, so we stick with PS2 version here + x = Ceil(PSP_SCALE_TO_PS2_X(x)) * ((float)PSP_DEFAULT_SCREEN_WIDTH / (float)DEFAULT_SCREEN_WIDTH); +#endif + } +} + +void +CHud::DrawCash() +{ + char str[200]; + sprintf(str, "$%08d", CWorld::Players[CWorld::PlayerInFocus].m_nMoney); + DrawTimeAndCashNumbers(str, FrontEndMenuManager.m_PrefsUseWideScreen ? 386.0f : 373.0f, 53.0f, true); +} + +void +CHud::DrawTime() +{ + // TODO(LCS): a lot more code should be here + + char str[24]; + sprintf(str, "%02d:%02d", CClock::ms_nGameClockHours, CClock::ms_nGameClockMinutes); + DrawTimeAndCashNumbers(str, FrontEndMenuManager.m_PrefsUseWideScreen ? 386.0f : 373.0f, 17.0f, false); +} + + void CHud::DrawAfterFade() { RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERNEAREST); @@ -2086,4 +2268,4 @@ CHud::ResetWastedText(void) BigMessageInUse[0] = 0.0f; m_BigMessage[2][0] = 0; m_BigMessage[0][0] = 0; -} +}
\ No newline at end of file diff --git a/src/renderer/Hud.h b/src/renderer/Hud.h index a4b9609a..4ae36886 100644 --- a/src/renderer/Hud.h +++ b/src/renderer/Hud.h @@ -38,15 +38,23 @@ enum eSprites HUD_FIST, HUD_SITEROCKET = 41, HUD_RADARDISC = 50, - HUD_SITESNIPER = 63, + HUD_BAR_INSIDE1DARK = 57, + HUD_BAR_INSIDE2DARK, + HUD_HUDNUMBERS, + HUD_BAR_INSIDE1, + HUD_BAR_INSIDE2, + HUD_BAR_OUTLINE, + HUD_SITESNIPER, HUD_SITEM16, HUD_SITELASER, HUD_LASERDOT, HUD_VIEWFINDER, HUD_BLEEDER, - NUM_HUD_SPRITES = 69, + NUM_HUD_SPRITES = 70, }; +extern float BigMessageInUse[6]; + class CHud { public: @@ -82,7 +90,6 @@ public: static int32 m_ClockState; // These aren't really in CHud - static float BigMessageInUse[6]; static float BigMessageAlpha[6]; static float BigMessageX[6]; static float OddJob2OffTimer; @@ -117,6 +124,9 @@ public: static uint32 m_LastWeapon; static uint32 m_LastTimeEnergyLost; + static wchar* gLastPrintForeverString; + static uint8 m_HudAlpha; + public: static void Draw(); static void DrawAfterFade(); @@ -136,4 +146,9 @@ public: static void Shutdown(); static float DrawFadeState(DRAW_FADE_STATE, int); static void ResetWastedText(void); + static void DrawHealthBar(int16 value); + static void DrawArmourBar(int16 value); + static void DrawTimeAndCashNumbers(char *str, float x, float y, bool secondSet); + static void DrawCash(); + static void DrawTime(); }; diff --git a/src/renderer/MBlur.cpp b/src/renderer/MBlur.cpp index cc8270ce..f2c85719 100644 --- a/src/renderer/MBlur.cpp +++ b/src/renderer/MBlur.cpp @@ -593,6 +593,8 @@ CMBlur::AddRenderFx(RwCamera *cam, RwRect *rect, float z, FxType type) void CMBlur::OverlayRenderFx(RwCamera *cam, RwRaster *frontBuf) { + //TODO(LCS) +#if 0 bool drawWaterDrops = false; RwIm2DVertex verts[4]; int red = (0.75f*CTimeCycle::GetDirectionalRed() + CTimeCycle::GetAmbientRed())*0.55f * 255; @@ -798,4 +800,5 @@ CMBlur::OverlayRenderFx(RwCamera *cam, RwRaster *frontBuf) RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE); RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE); pBufVertCount = 0; +#endif } diff --git a/src/renderer/Particle.cpp b/src/renderer/Particle.cpp index 461a10a6..18e9e415 100644 --- a/src/renderer/Particle.cpp +++ b/src/renderer/Particle.cpp @@ -13,6 +13,7 @@ #include "Replay.h" #include "Stats.h" #include "Weather.h" +#include "WaterLevel.h" #include "MBlur.h" #include "main.h" #include "AudioScriptObject.h" @@ -213,7 +214,6 @@ RwRaster *gpRainDropRaster; RwTexture *gpSparkTex; RwTexture *gpNewspaperTex; RwTexture *gpGunSmokeTex; -RwTexture *gpDotTex; RwTexture *gpHeatHazeTex; RwTexture *gpBeastieTex; RwTexture *gpRainDripTex[MAX_RAINDRIP_FILES]; @@ -222,34 +222,30 @@ RwTexture *gpRainDripDarkTex[MAX_RAINDRIP_FILES]; RwRaster *gpSparkRaster; RwRaster *gpNewspaperRaster; RwRaster *gpGunSmokeRaster; -RwRaster *gpDotRaster; RwRaster *gpHeatHazeRaster; RwRaster *gpBeastieRaster; RwRaster *gpRainDripRaster[MAX_RAINDRIP_FILES]; RwRaster *gpRainDripDarkRaster[MAX_RAINDRIP_FILES]; +RwTexture *gpFireHoseTex; +RwRaster *gpFireHoseRaster; + +RwTexture *gpMultiPlayerHitTex; +RwRaster *gpMultiPlayerHitRaster; + float CParticle::ms_afRandTable[CParticle::RAND_TABLE_SIZE]; CParticle *CParticle::m_pUnusedListHead; float CParticle::m_SinTable[CParticle::SIN_COS_TABLE_SIZE]; float CParticle::m_CosTable[CParticle::SIN_COS_TABLE_SIZE]; int32 Randomizer; -int32 nParticleCreationInterval = 1; float PARTICLE_WIND_TEST_SCALE = 0.002f; -float fParticleScaleLimit = 0.5f; - -bool clearWaterDrop; -int32 numWaterDropOnScreen; #ifdef DEBUGMENU SETTWEAKPATH("Particle"); -TWEAKINT32(nParticleCreationInterval, 0, 5, 1); -TWEAKFLOAT(fParticleScaleLimit, 0.0f, 1.0f, 0.1f); TWEAKFUNC(CParticle::ReloadConfig); #endif - - void CParticle::ReloadConfig() { debug("Initialising CParticleMgr..."); @@ -287,14 +283,6 @@ void CParticle::ReloadConfig() gParticleArray[i].m_nFadeAlphaTimer = 0; - gParticleArray[i].m_nCurrentZRotation = 0; - - gParticleArray[i].m_nZRotationTimer = 0; - - gParticleArray[i].m_fCurrentZRadius = 0.0f; - - gParticleArray[i].m_nZRadiusTimer = 0; - gParticleArray[i].m_nCurrentFrame = 0; gParticleArray[i].m_nAnimationSpeedTimer = 0; @@ -319,7 +307,7 @@ void CParticle::Initialise() } for ( int32 i = 0; i < SIN_COS_TABLE_SIZE; i++ ) - { + { float angle = DEGTORAD(float(i) * float(360.0f / SIN_COS_TABLE_SIZE)); m_SinTable[i] = ::Sin(angle); @@ -334,83 +322,98 @@ void CParticle::Initialise() for ( int32 i = 0; i < MAX_SMOKE_FILES; i++ ) { gpSmokeTex[i] = RwTextureRead(SmokeFiles[i], nil); + ASSERT(gpSmokeTex[i] != nil); gpSmokeRaster[i] = RwTextureGetRaster(gpSmokeTex[i]); } gpSmoke2Tex = RwTextureRead("smokeII_3", nil); + ASSERT(gpSmoke2Tex != nil); gpSmoke2Raster = RwTextureGetRaster(gpSmoke2Tex); for ( int32 i = 0; i < MAX_RUBBER_FILES; i++ ) { gpRubberTex[i] = RwTextureRead(RubberFiles[i], nil); + ASSERT(gpRubberTex[i] != nil); gpRubberRaster[i] = RwTextureGetRaster(gpRubberTex[i]); } for ( int32 i = 0; i < MAX_RAINSPLASH_FILES; i++ ) { gpRainSplashTex[i] = RwTextureRead(RainSplashFiles[i], nil); + ASSERT(gpRainSplashTex[i] != nil); gpRainSplashRaster[i] = RwTextureGetRaster(gpRainSplashTex[i]); } for ( int32 i = 0; i < MAX_WATERSPRAY_FILES; i++ ) { gpWatersprayTex[i] = RwTextureRead(WatersprayFiles[i], nil); + ASSERT(gpWatersprayTex[i] != nil); gpWatersprayRaster[i] = RwTextureGetRaster(gpWatersprayTex[i]); } for ( int32 i = 0; i < MAX_EXPLOSIONMEDIUM_FILES; i++ ) { gpExplosionMediumTex[i] = RwTextureRead(ExplosionMediumFiles[i], nil); + ASSERT(gpExplosionMediumTex[i] != nil); gpExplosionMediumRaster[i] = RwTextureGetRaster(gpExplosionMediumTex[i]); } for ( int32 i = 0; i < MAX_GUNFLASH_FILES; i++ ) { gpGunFlashTex[i] = RwTextureRead(GunFlashFiles[i], nil); + ASSERT(gpGunFlashTex[i] != nil); gpGunFlashRaster[i] = RwTextureGetRaster(gpGunFlashTex[i]); } gpRainDropTex = RwTextureRead("raindrop4", nil); + ASSERT(gpRainDropTex != nil); gpRainDropRaster = RwTextureGetRaster(gpRainDropTex); - for ( int32 i = 0; i < MAX_RAINSPLASHUP_FILES; i++ ) { gpRainSplashupTex[i] = RwTextureRead(RainSplashupFiles[i], nil); + ASSERT(gpRainSplashupTex[i] != nil); gpRainSplashupRaster[i] = RwTextureGetRaster(gpRainSplashupTex[i]); } for ( int32 i = 0; i < MAX_BIRDFRONT_FILES; i++ ) { gpBirdfrontTex[i] = RwTextureRead(BirdfrontFiles[i], nil); + ASSERT(gpBirdfrontTex[i] != nil); gpBirdfrontRaster[i] = RwTextureGetRaster(gpBirdfrontTex[i]); } for ( int32 i = 0; i < MAX_BOAT_FILES; i++ ) { gpBoatTex[i] = RwTextureRead(BoatFiles[i], nil); + ASSERT(gpBoatTex[i] != nil); gpBoatRaster[i] = RwTextureGetRaster(gpBoatTex[i]); } for ( int32 i = 0; i < MAX_CARDEBRIS_FILES; i++ ) { gpCarDebrisTex[i] = RwTextureRead(CardebrisFiles[i], nil); + ASSERT(gpCarDebrisTex[i] != nil); gpCarDebrisRaster[i] = RwTextureGetRaster(gpCarDebrisTex[i]); } for ( int32 i = 0; i < MAX_CARSPLASH_FILES; i++ ) { gpCarSplashTex[i] = RwTextureRead(CarsplashFiles[i], nil); + ASSERT(gpCarSplashTex[i] != nil); gpCarSplashRaster[i] = RwTextureGetRaster(gpCarSplashTex[i]); } gpBoatWakeTex = RwTextureRead("boatwake2", nil); + ASSERT(gpBoatWakeTex != nil); gpBoatWakeRaster = RwTextureGetRaster(gpBoatWakeTex); gpFlame1Tex = RwTextureRead("flame1", nil); + ASSERT(gpFlame1Tex != nil); gpFlame1Raster = RwTextureGetRaster(gpFlame1Tex); gpFlame5Tex = RwTextureRead("flame5", nil); + ASSERT(gpFlame5Tex != nil); //#ifdef FIX_BUGS #if 0 @@ -421,257 +424,409 @@ void CParticle::Initialise() #endif gpRainDropSmallTex = RwTextureRead("rainsmall", nil); + ASSERT(gpRainDropSmallTex != nil); gpRainDropSmallRaster = RwTextureGetRaster(gpRainDropSmallTex); gpBloodTex = RwTextureRead("blood", nil); + ASSERT(gpBloodTex != nil); gpBloodRaster = RwTextureGetRaster(gpBloodTex); gpLeafTex[0] = RwTextureRead("gameleaf01_64", nil); + ASSERT(gpLeafTex[0] != nil); gpLeafRaster[0] = RwTextureGetRaster(gpLeafTex[0]); gpLeafTex[1] = RwTextureRead("letter", nil); + ASSERT(gpLeafTex[1] != nil); gpLeafRaster[1] = RwTextureGetRaster(gpLeafTex[1]); gpCloudTex1 = RwTextureRead("cloud3", nil); + ASSERT(gpCloudTex1 != nil); gpCloudRaster1 = RwTextureGetRaster(gpCloudTex1); gpCloudTex4 = RwTextureRead("cloudmasked", nil); + ASSERT(gpCloudTex4 != nil); gpCloudRaster4 = RwTextureGetRaster(gpCloudTex4); gpBloodSmallTex = RwTextureRead("bloodsplat2", nil); + ASSERT(gpBloodSmallTex != nil); gpBloodSmallRaster = RwTextureGetRaster(gpBloodSmallTex); gpGungeTex = RwTextureRead("gunge", nil); + ASSERT(gpGungeTex != nil); gpGungeRaster = RwTextureGetRaster(gpGungeTex); gpCollisionSmokeTex = RwTextureRead("collisionsmoke", nil); + ASSERT(gpCollisionSmokeTex != nil); gpCollisionSmokeRaster = RwTextureGetRaster(gpCollisionSmokeTex); gpBulletHitTex = RwTextureRead("bullethitsmoke", nil); + ASSERT(gpBulletHitTex != nil); gpBulletHitRaster = RwTextureGetRaster(gpBulletHitTex); gpGunShellTex = RwTextureRead("gunshell", nil); + ASSERT(gpGunShellTex != nil); gpGunShellRaster = RwTextureGetRaster(gpGunShellTex); - gpPointlightTex = RwTextureRead("pointlight", nil); + gpPointlightTex = RwTextureRead("smoke5", nil); + ASSERT(gpPointlightTex != nil); gpPointlightRaster = RwTextureGetRaster(gpPointlightTex); gpSparkTex = RwTextureRead("spark", nil); + ASSERT(gpSparkTex != nil); gpSparkRaster = RwTextureGetRaster(gpSparkTex); - gpNewspaperTex = RwTextureRead("newspaper02_64", nil); + gpNewspaperTex = RwTextureRead("ballot_paper", nil); + ASSERT(gpNewspaperTex != nil); gpNewspaperRaster = RwTextureGetRaster(gpNewspaperTex); gpGunSmokeTex = RwTextureRead("gunsmoke3", nil); + ASSERT(gpGunSmokeTex != nil); gpGunSmokeRaster = RwTextureGetRaster(gpGunSmokeTex); - gpDotTex = RwTextureRead("dot", nil); - gpDotRaster = RwTextureGetRaster(gpDotTex); - gpHeatHazeTex = RwTextureRead("heathaze", nil); + ASSERT(gpHeatHazeTex != nil); gpHeatHazeRaster = RwTextureGetRaster(gpHeatHazeTex); gpBeastieTex = RwTextureRead("beastie", nil); + ASSERT(gpBeastieTex != nil); gpBeastieRaster = RwTextureGetRaster(gpBeastieTex); gpRainDripTex[0] = RwTextureRead("raindrip64", nil); + ASSERT(gpRainDripTex[0] != nil); gpRainDripRaster[0] = RwTextureGetRaster(gpRainDripTex[0]); gpRainDripTex[1] = RwTextureRead("raindripb64", nil); + ASSERT(gpRainDripTex[1] != nil); gpRainDripRaster[1] = RwTextureGetRaster(gpRainDripTex[1]); gpRainDripDarkTex[0] = RwTextureRead("raindrip64_d", nil); + ASSERT(gpRainDripDarkTex[0] != nil); gpRainDripDarkRaster[0] = RwTextureGetRaster(gpRainDripDarkTex[0]); - gpRainDripDarkTex[1] = RwTextureRead("raindripb64_d", nil); - gpRainDripDarkRaster[1] = RwTextureGetRaster(gpRainDripDarkTex[1]); + gpMultiPlayerHitTex = RwTextureRead("mphit", nil); + ASSERT(gpMultiPlayerHitTex != nil); + gpMultiPlayerHitRaster = RwTextureGetRaster(gpMultiPlayerHitTex); - CTxdStore::PopCurrentTxd(); + gpFireHoseTex = RwTextureRead("firehose", nil); + ASSERT(gpFireHoseTex != nil); + gpFireHoseRaster = RwTextureGetRaster(gpFireHoseTex); - for ( int32 i = 0; i < MAX_PARTICLES; i++ ) + CTxdStore::PopCurrentTxd(); + SetPixelData(); + + debug("CParticle ready"); +} + +void CParticle::SetPixelData() +{ + for (int32 i = 0; i < MAX_PARTICLES; i++) { - tParticleSystemData *entry = &mod_ParticleSystemManager.m_aParticles[i]; - - switch ( i ) + tParticleSystemData* entry = &mod_ParticleSystemManager.m_aParticles[i]; + + switch (i) { - case PARTICLE_SPARK: - case PARTICLE_SPARK_SMALL: - case PARTICLE_RAINDROP_SMALL: - case PARTICLE_HELI_ATTACK: - entry->m_ppRaster = &gpRainDropSmallRaster; - break; - - case PARTICLE_WATER_SPARK: - entry->m_ppRaster = &gpSparkRaster; - break; - - case PARTICLE_WHEEL_DIRT: - case PARTICLE_SAND: - case PARTICLE_STEAM2: - case PARTICLE_STEAM_NY: - case PARTICLE_STEAM_NY_SLOWMOTION: - case PARTICLE_GROUND_STEAM: - case PARTICLE_ENGINE_STEAM: - case PARTICLE_PEDFOOT_DUST: - case PARTICLE_CAR_DUST: - case PARTICLE_EXHAUST_FUMES: - entry->m_ppRaster = &gpSmoke2Raster; - break; - - case PARTICLE_WHEEL_WATER: - case PARTICLE_WATER: - case PARTICLE_SMOKE: - case PARTICLE_SMOKE_SLOWMOTION: - case PARTICLE_DRY_ICE: - case PARTICLE_GARAGEPAINT_SPRAY: - case PARTICLE_STEAM: - case PARTICLE_WATER_CANNON: - case PARTICLE_EXTINGUISH_STEAM: - case PARTICLE_HELI_DUST: - case PARTICLE_PAINT_SMOKE: - case PARTICLE_BULLETHIT_SMOKE: - entry->m_ppRaster = gpSmokeRaster; - break; - - case PARTICLE_BLOOD: - entry->m_ppRaster = &gpBloodRaster; - break; - - case PARTICLE_BLOOD_SMALL: - case PARTICLE_BLOOD_SPURT: - entry->m_ppRaster = &gpBloodSmallRaster; - break; - - case PARTICLE_DEBRIS: - case PARTICLE_TREE_LEAVES: - entry->m_ppRaster = gpLeafRaster; - break; - - case PARTICLE_DEBRIS2: - entry->m_ppRaster = &gpGungeRaster; - break; - - case PARTICLE_FLYERS: - entry->m_ppRaster = &gpNewspaperRaster; - break; - - case PARTICLE_FLAME: - case PARTICLE_CARFLAME: - entry->m_ppRaster = &gpFlame1Raster; - break; - - case PARTICLE_FIREBALL: - entry->m_ppRaster = &gpFlame5Raster; - break; - - case PARTICLE_GUNFLASH: - case PARTICLE_GUNFLASH_NOANIM: - entry->m_ppRaster = gpGunFlashRaster; - break; - - - case PARTICLE_GUNSMOKE: - case PARTICLE_WATERDROP: - case PARTICLE_BLOODDROP: - case PARTICLE_HEATHAZE: - case PARTICLE_HEATHAZE_IN_DIST: - entry->m_ppRaster = nil; - break; - - case PARTICLE_GUNSMOKE2: - case PARTICLE_BOAT_THRUSTJET: - case PARTICLE_RUBBER_SMOKE: - entry->m_ppRaster = gpRubberRaster; - break; - - case PARTICLE_CIGARETTE_SMOKE: - entry->m_ppRaster = &gpGunSmokeRaster; - break; - - case PARTICLE_TEARGAS: - entry->m_ppRaster = &gpHeatHazeRaster; - break; - - case PARTICLE_SHARD: - case PARTICLE_RAINDROP: - case PARTICLE_RAINDROP_2D: - entry->m_ppRaster = &gpRainDropRaster; - break; - - case PARTICLE_SPLASH: - case PARTICLE_PED_SPLASH: - case PARTICLE_CAR_SPLASH: - case PARTICLE_WATER_HYDRANT: - entry->m_ppRaster = gpCarSplashRaster; - break; - - case PARTICLE_RAIN_SPLASH: - case PARTICLE_RAIN_SPLASH_BIGGROW: - entry->m_ppRaster = gpRainSplashRaster; - break; - - case PARTICLE_RAIN_SPLASHUP: - entry->m_ppRaster = gpRainSplashupRaster; - break; - - case PARTICLE_WATERSPRAY: - entry->m_ppRaster = gpWatersprayRaster; - break; - - case PARTICLE_EXPLOSION_MEDIUM: - case PARTICLE_EXPLOSION_LARGE: - case PARTICLE_EXPLOSION_MFAST: - case PARTICLE_EXPLOSION_LFAST: - entry->m_ppRaster = gpExplosionMediumRaster; - break; - - case PARTICLE_BOAT_SPLASH: - entry->m_ppRaster = &gpBoatWakeRaster; - break; - - case PARTICLE_ENGINE_SMOKE: - case PARTICLE_ENGINE_SMOKE2: - case PARTICLE_CARFLAME_SMOKE: - case PARTICLE_FIREBALL_SMOKE: - case PARTICLE_ROCKET_SMOKE: - case PARTICLE_TEST: - entry->m_ppRaster = &gpCloudRaster4; - break; - - case PARTICLE_CARCOLLISION_DUST: - case PARTICLE_BURNINGRUBBER_SMOKE: - entry->m_ppRaster = &gpCollisionSmokeRaster; - break; - - case PARTICLE_CAR_DEBRIS: - case PARTICLE_HELI_DEBRIS: - case PARTICLE_BIRD_DEBRIS: - entry->m_ppRaster = gpCarDebrisRaster; - break; - - case PARTICLE_GUNSHELL_FIRST: - case PARTICLE_GUNSHELL: - case PARTICLE_GUNSHELL_BUMP1: - case PARTICLE_GUNSHELL_BUMP2: - entry->m_ppRaster = &gpGunShellRaster; - break; - - - case PARTICLE_BIRD_FRONT: - entry->m_ppRaster = gpBirdfrontRaster; - break; - - case PARTICLE_SHIP_SIDE: - entry->m_ppRaster = gpBoatRaster; - break; - - case PARTICLE_BEASTIE: - entry->m_ppRaster = &gpBeastieRaster; - break; + case PARTICLE_SPARK: + entry->m_ppRaster = &gpRainDropSmallRaster; + break; + + case PARTICLE_SPARK_SMALL: + entry->m_ppRaster = &gpRainDropSmallRaster; + break; + + case PARTICLE_WATER_SPARK: + entry->m_ppRaster = &gpSparkRaster; + break; + + case PARTICLE_WHEEL_DIRT: + entry->m_ppRaster = &gpSmoke2Raster; + break; + + case PARTICLE_SAND: + entry->m_ppRaster = &gpSmoke2Raster; + break; + + case PARTICLE_WHEEL_WATER: + entry->m_ppRaster = gpSmokeRaster; + break; + + case PARTICLE_BLOOD: + entry->m_ppRaster = &gpBloodRaster; + break; + + case PARTICLE_BLOOD_SMALL: + entry->m_ppRaster = &gpBloodSmallRaster; + break; + + case PARTICLE_BLOOD_SPURT: + entry->m_ppRaster = &gpBloodSmallRaster; + break; + + case PARTICLE_DEBRIS: + entry->m_ppRaster = gpLeafRaster; + break; + + case PARTICLE_DEBRIS2: + entry->m_ppRaster = &gpGungeRaster; + break; + + case PARTICLE_FLYERS: + entry->m_ppRaster = &gpNewspaperRaster; + break; + + case PARTICLE_WATER: + entry->m_ppRaster = gpSmokeRaster; + break; + + case PARTICLE_FLAME: + entry->m_ppRaster = &gpFlame1Raster; + break; + + case PARTICLE_FIREBALL: + entry->m_ppRaster = &gpFlame5Raster; + break; + + case PARTICLE_GUNFLASH: + entry->m_ppRaster = gpGunFlashRaster; + break; + + case PARTICLE_GUNFLASH_NOANIM: + entry->m_ppRaster = gpGunFlashRaster; + break; + + case PARTICLE_GUNSMOKE: + entry->m_ppRaster = nil; + break; + + case PARTICLE_GUNSMOKE2: + entry->m_ppRaster = gpRubberRaster; + break; + + case PARTICLE_CIGARETTE_SMOKE: + entry->m_ppRaster = &gpGunSmokeRaster; + break; + + case PARTICLE_TEARGAS: + entry->m_ppRaster = &gpHeatHazeRaster; + break; + + case PARTICLE_SMOKE: + case PARTICLE_SMOKE_SLOWMOTION: + case PARTICLE_DRY_ICE: + entry->m_ppRaster = gpSmokeRaster; + break; + + case PARTICLE_GARAGEPAINT_SPRAY: + entry->m_ppRaster = gpSmokeRaster; + break; + + case PARTICLE_SHARD: + entry->m_ppRaster = &gpRainDropRaster; + break; + + case PARTICLE_SPLASH: + entry->m_ppRaster = gpCarSplashRaster; + break; + + case PARTICLE_CARFLAME: + entry->m_ppRaster = &gpFlame1Raster; + break; + + case PARTICLE_STEAM: + entry->m_ppRaster = gpSmokeRaster; + break; + + case PARTICLE_STEAM2: + entry->m_ppRaster = &gpSmoke2Raster; + break; + + case PARTICLE_STEAM_NY: + case PARTICLE_STEAM_NY_SLOWMOTION: + case PARTICLE_GROUND_STEAM: + case PARTICLE_HYDRANT_STEAM: + entry->m_ppRaster = &gpSmoke2Raster; + break; + + case PARTICLE_ENGINE_STEAM: + entry->m_ppRaster = &gpSmoke2Raster; + break; + + case PARTICLE_RAINDROP: + entry->m_ppRaster = &gpRainDropRaster; + break; + + case PARTICLE_RAINDROP_SMALL: + entry->m_ppRaster = &gpRainDropSmallRaster; + break; + + case PARTICLE_RAIN_SPLASH: + case PARTICLE_RAIN_SPLASH_BIGGROW: + entry->m_ppRaster = gpRainSplashRaster; + break; + + case PARTICLE_RAIN_SPLASHUP: + entry->m_ppRaster = gpRainSplashupRaster; + break; + + case PARTICLE_WATERSPRAY: + entry->m_ppRaster = gpWatersprayRaster; + break; + + case PARTICLE_RAINDROP_2D: + entry->m_ppRaster = &gpRainDropRaster; + break; + + case PARTICLE_EXPLOSION_MEDIUM: + entry->m_ppRaster = gpExplosionMediumRaster; + break; + + case PARTICLE_EXPLOSION_LARGE: + entry->m_ppRaster = gpExplosionMediumRaster; + break; + + case PARTICLE_EXPLOSION_MFAST: + entry->m_ppRaster = gpExplosionMediumRaster; + break; + + case PARTICLE_EXPLOSION_LFAST: + entry->m_ppRaster = gpExplosionMediumRaster; + break; + + case PARTICLE_CAR_SPLASH: + entry->m_ppRaster = gpCarSplashRaster; + break; + + case PARTICLE_BOAT_SPLASH: + entry->m_ppRaster = &gpBoatWakeRaster; + break; + + case PARTICLE_BOAT_THRUSTJET: + entry->m_ppRaster = gpRubberRaster; + break; + + case PARTICLE_WATER_HYDRANT: + entry->m_ppRaster = gpCarSplashRaster; + break; + + case PARTICLE_WATER_CANNON: + entry->m_ppRaster = gpSmokeRaster; + break; + + case PARTICLE_EXTINGUISH_STEAM: + entry->m_ppRaster = gpSmokeRaster; + break; + + case PARTICLE_PED_SPLASH: + entry->m_ppRaster = gpCarSplashRaster; + break; + + case PARTICLE_PEDFOOT_DUST: + entry->m_ppRaster = &gpSmoke2Raster; + break; + + case PARTICLE_CAR_DUST: + entry->m_ppRaster = &gpSmoke2Raster; + break; + + case PARTICLE_HELI_DUST: + entry->m_ppRaster = gpSmokeRaster; + break; + + case PARTICLE_HELI_ATTACK: + entry->m_ppRaster = &gpRainDropSmallRaster; + break; + + case PARTICLE_ENGINE_SMOKE: + entry->m_ppRaster = &gpCloudRaster4; + break; + + case PARTICLE_ENGINE_SMOKE2: + case PARTICLE_ROCKET_SMOKE: + entry->m_ppRaster = &gpCloudRaster4; + break; + + case PARTICLE_CARFLAME_SMOKE: + entry->m_ppRaster = &gpCloudRaster4; + break; + + case PARTICLE_FIREBALL_SMOKE: + entry->m_ppRaster = &gpCloudRaster4; + break; + + case PARTICLE_PAINT_SMOKE: + entry->m_ppRaster = gpSmokeRaster; + break; + + case PARTICLE_TREE_LEAVES: + entry->m_ppRaster = gpLeafRaster; + break; + + case PARTICLE_CARCOLLISION_DUST: + entry->m_ppRaster = &gpCollisionSmokeRaster; + break; + + case PARTICLE_CAR_DEBRIS: + case PARTICLE_BIRD_DEBRIS: + case PARTICLE_HELI_DEBRIS: + entry->m_ppRaster = gpCarDebrisRaster; + break; + + case PARTICLE_EXHAUST_FUMES: + entry->m_ppRaster = &gpSmoke2Raster; + break; + + case PARTICLE_RUBBER_SMOKE: + entry->m_ppRaster = gpRubberRaster; + break; + + case PARTICLE_BURNINGRUBBER_SMOKE: + entry->m_ppRaster = &gpCollisionSmokeRaster; + break; + + case PARTICLE_BULLETHIT_SMOKE: + entry->m_ppRaster = gpSmokeRaster; + break; + + case PARTICLE_GUNSHELL_FIRST: + entry->m_ppRaster = &gpGunShellRaster; + break; + + case PARTICLE_GUNSHELL: + entry->m_ppRaster = &gpGunShellRaster; + break; + + case PARTICLE_GUNSHELL_BUMP1: + entry->m_ppRaster = &gpGunShellRaster; + break; + + case PARTICLE_GUNSHELL_BUMP2: + entry->m_ppRaster = &gpGunShellRaster; + break; + + case PARTICLE_TEST: + entry->m_ppRaster = &gpCloudRaster4; + break; + + case PARTICLE_BIRD_FRONT: + entry->m_ppRaster = gpBirdfrontRaster; + break; + + case PARTICLE_SHIP_SIDE: + entry->m_ppRaster = gpBoatRaster; + break; + + case PARTICLE_BEASTIE: + entry->m_ppRaster = &gpBeastieRaster; + break; + + case PARTICLE_FERRY_CHIM_SMOKE: + entry->m_ppRaster = gpSmokeRaster; + break; + + case PARTICLE_MULTIPLAYER_HIT: + entry->m_ppRaster = &gpMultiPlayerHitRaster; + break; } } - - debug("CParticle ready"); } void CParticle::Shutdown() @@ -755,8 +910,13 @@ void CParticle::Shutdown() RwTextureDestroy(gpRainDripTex[i]); gpRainDripTex[i] = nil; - RwTextureDestroy(gpRainDripDarkTex[i]); - gpRainDripDarkTex[i] = nil; +#ifdef FIX_BUGS + if (gpRainDripDarkTex[i]) +#endif + { + RwTextureDestroy(gpRainDripDarkTex[i]); + gpRainDripDarkTex[i] = nil; + } } RwTextureDestroy(gpBoatWakeTex); @@ -812,14 +972,18 @@ void CParticle::Shutdown() RwTextureDestroy(gpGunSmokeTex); gpGunSmokeTex = nil; - - RwTextureDestroy(gpDotTex); - gpDotTex = nil; + RwTextureDestroy(gpHeatHazeTex); gpHeatHazeTex = nil; RwTextureDestroy(gpBeastieTex); gpBeastieTex = nil; + + RwTextureDestroy(gpMultiPlayerHitTex); + gpBeastieTex = nil; + + RwTextureDestroy(gpFireHoseTex); + gpFireHoseTex = nil; int32 slot; @@ -871,24 +1035,12 @@ CParticle *CParticle::AddParticle(tParticleType type, CVector const &vecPos, CVe CParticle *CParticle::AddParticle(tParticleType type, CVector const &vecPos, CVector const &vecDir, CEntity *pEntity, float fSize, RwRGBA const &color, int32 nRotationSpeed, int32 nRotation, int32 nCurFrame, int32 nLifeSpan) { - if ( CTimer::GetIsPaused() ) + if ( CTimer::GetIsPaused() /*TODO: || byte_355C47*/ ) return nil; - - if ( ( type == PARTICLE_ENGINE_SMOKE - || type == PARTICLE_ENGINE_SMOKE2 - || type == PARTICLE_ENGINE_STEAM - || type == PARTICLE_CARFLAME_SMOKE - || type == PARTICLE_RUBBER_SMOKE - || type == PARTICLE_BURNINGRUBBER_SMOKE - || type == PARTICLE_EXHAUST_FUMES - || type == PARTICLE_CARCOLLISION_DUST ) - && nParticleCreationInterval & CTimer::GetFrameCounter() ) - { - return nil; - } - +/* if ( !CReplay::IsPlayingBack() ) CReplay::RecordParticle(type, vecPos, vecDir, fSize, color); +*/ CParticle *pParticle = m_pUnusedListHead; @@ -923,38 +1075,15 @@ CParticle *CParticle::AddParticle(tParticleType type, CVector const &vecPos, CVe if ( psystem->m_nFadeAlphaTime ) pParticle->m_nFadeAlphaTimer /= psystem->m_nFadeAlphaTime; - pParticle->m_nCurrentZRotation = psystem->m_nZRotationInitialAngle; - pParticle->m_fCurrentZRadius = psystem->m_fInitialZRadius; - if ( nCurFrame != 0 ) pParticle->m_nCurrentFrame = nCurFrame; else pParticle->m_nCurrentFrame = psystem->m_nStartAnimationFrame; - - pParticle->m_nZRotationTimer = 0; - pParticle->m_nZRadiusTimer = 0; pParticle->m_nAnimationSpeedTimer = 0; pParticle->m_fZGround = 0.0f; - - if ( type != PARTICLE_HEATHAZE ) - pParticle->m_vecPosition = vecPos; - else - { - CVector screen; - float w, h; - - if ( !CSprite::CalcScreenCoors(vecPos, &screen, &w, &h, true) ) - return nil; - - pParticle->m_vecPosition = screen; - psystem->m_vecTextureStretch.x = w; - psystem->m_vecTextureStretch.y = h; - } - + pParticle->m_vecPosition = vecPos; pParticle->m_vecVelocity = vecDir; - - pParticle->m_vecParticleMovementOffset = CVector(0.0f, 0.0f, 0.0f); pParticle->m_nTimeWhenColorWillBeChanged = 0; if ( color.alpha != 0 ) @@ -1091,14 +1220,14 @@ CParticle *CParticle::AddParticle(tParticleType type, CVector const &vecPos, CVe break; case PARTICLE_EXPLOSION_MEDIUM: - pParticle->m_nColorIntensity -= 30 * (CGeneral::GetRandomNumber() & 1); // mb "+= -30 * rand" here ? + pParticle->m_nColorIntensity -= 2 * 15 * (CGeneral::GetRandomNumber() & 1); // mb "+= -30 * rand" here ? pParticle->m_nAnimationSpeedTimer = CGeneral::GetRandomNumber() & 7; pParticle->m_fSize = CGeneral::GetRandomNumberInRange(0.3f, 0.8f); pParticle->m_vecPosition.z -= CGeneral::GetRandomNumberInRange(-0.1f, 0.1f); break; case PARTICLE_EXPLOSION_LARGE: - pParticle->m_nColorIntensity -= 30 * (CGeneral::GetRandomNumber() & 1); // mb "+= -30 * rand" here ? + pParticle->m_nColorIntensity -= 2 * 15 * (CGeneral::GetRandomNumber() & 1); // mb "+= -30 * rand" here ? pParticle->m_nAnimationSpeedTimer = CGeneral::GetRandomNumber() & 7; pParticle->m_fSize = CGeneral::GetRandomNumberInRange(0.8f, 1.4f); pParticle->m_vecPosition.z -= CGeneral::GetRandomNumberInRange(-0.3f, 0.3f); @@ -1124,7 +1253,7 @@ CParticle *CParticle::AddParticle(tParticleType type, CVector const &vecPos, CVe void CParticle::Update() { - if ( CTimer::GetIsPaused() ) + if ( CTimer::GetIsPaused() /*TODO: || byte_355C47*/ ) return; CRGBA color(0, 0, 0, 0); @@ -1137,7 +1266,9 @@ void CParticle::Update() float fFricDeccel99 = pow(0.99f, CTimer::GetTimeStep()); CParticleObject::UpdateAll(); - + + // no more erectedcocks +#ifndef FIX_BUGS // ejaculation at 23:00, 23:15, 23:30, 23:45 if ( CClock::ms_nGameClockHours == 23 && ( CClock::ms_nGameClockMinutes == 0 @@ -1156,6 +1287,7 @@ void CParticle::Update() 1, 1000); } +#endif for ( int32 i = 0; i < MAX_PARTICLES; i++ ) { @@ -1175,68 +1307,7 @@ void CParticle::Update() CVector vecMoveStep = particle->m_vecVelocity * CTimer::GetTimeStep(); CVector vecPos = particle->m_vecPosition; - - if ( numWaterDropOnScreen == 0 ) - clearWaterDrop = false; - - if ( psystem->m_Type == PARTICLE_WATERDROP ) - { - if ( CGame::IsInInterior() || clearWaterDrop == true ) - { - bRemoveParticle = true; - continue; - } - - static uint8 nWaterDropCount; - - if ( nWaterDropCount == 5 ) - { - vecMoveStep = CVector(0.0f, 0.0f, 0.0f); - particle->m_nTimeWhenWillBeDestroyed += 1250; - nWaterDropCount = 0; - } - else - { - if ( TheCamera.m_CameraAverageSpeed > 0.35f ) - { - if ( vecMoveStep.Magnitude() > 0.5f ) - { - if ( vecMoveStep.Magnitude() > 0.4f && vecMoveStep.Magnitude() < 0.8f ) - { - vecMoveStep.x += TheCamera.m_CameraAverageSpeed * 1.5f; - vecMoveStep.y += TheCamera.m_CameraAverageSpeed * 1.5f; - } - else if ( vecMoveStep.Magnitude() != 0.0f ) - { - vecMoveStep.x += CGeneral::GetRandomNumberInRange(0.01f, 0.05f); - vecMoveStep.y += CGeneral::GetRandomNumberInRange(0.01f, 0.05f); - } - } - } - - nWaterDropCount++; - } - - if ( vecPos.z <= 1.5f ) - vecMoveStep.z = 0.0f; - } - - if ( psystem->m_Type == PARTICLE_HEATHAZE || psystem->m_Type == PARTICLE_HEATHAZE_IN_DIST ) - { -#ifdef FIX_BUGS - int32 nSinCosIndex = (int32(DEGTORAD((float)particle->m_nRotation) * float(SIN_COS_TABLE_SIZE) / TWOPI) + SIN_COS_TABLE_SIZE) % SIN_COS_TABLE_SIZE; -#else - int32 nSinCosIndex = int32(DEGTORAD((float)particle->m_nRotation) * float(SIN_COS_TABLE_SIZE) / TWOPI) % SIN_COS_TABLE_SIZE; -#endif - vecMoveStep.x = Sin(nSinCosIndex); - vecMoveStep.y = Sin(nSinCosIndex); - - if ( psystem->m_Type == PARTICLE_HEATHAZE_IN_DIST ) - particle->m_nRotation = int16((float)particle->m_nRotation + 0.75f); - else - particle->m_nRotation = int16((float)particle->m_nRotation + 1.0f); - } - + if ( psystem->m_Type == PARTICLE_BEASTIE ) { #ifdef FIX_BUGS @@ -1259,28 +1330,7 @@ void CParticle::Update() } vecPos += vecMoveStep; - - if ( psystem->m_Type == PARTICLE_FIREBALL ) - { - AddParticle(PARTICLE_HEATHAZE, particle->m_vecPosition, CVector(0.0f, 0.0f, 0.0f), - nil, particle->m_fSize * 5.0f); - } - - if ( psystem->m_Type == PARTICLE_GUNSMOKE2 ) - { - if ( CTimer::GetFrameCounter() & 10 ) - { -#ifdef FIX_BUGS - if ( FindPlayerPed() && FindPlayerPed()->GetWeapon()->m_eWeaponType == WEAPONTYPE_MINIGUN ) -#else - if ( FindPlayerPed()->GetWeapon()->m_eWeaponType == WEAPONTYPE_MINIGUN ) -#endif - { - AddParticle(PARTICLE_HEATHAZE, particle->m_vecPosition, CVector(0.0f, 0.0f, 0.0f)); - } - } - } - + if ( CWeather::Wind > 0.0f ) { if ( vecMoveStep.Magnitude() != 0.0f ) @@ -1300,12 +1350,15 @@ void CParticle::Update() || psystem->m_Type == PARTICLE_BOAT_SPLASH || psystem->m_Type == PARTICLE_RAINDROP_2D ) { - int32 nMaxDrops = int32(6.0f * TheCamera.m_CameraAverageSpeed + 1.0f); + //int32 nMaxDrops = int32(6.0f * TheCamera.m_CameraAverageSpeed + 1.0f); float fDistToCam = 0.0f; if ( psystem->m_Type == PARTICLE_BOAT_SPLASH || psystem->m_Type == PARTICLE_CAR_SPLASH ) { - if ( vecPos.z + particle->m_fSize < 5.0f ) + float fWaterLevel = 0.0f; + CWaterLevel::GetWaterLevelNoWaves(vecPos.x, vecPos.y, vecPos.z, &fWaterLevel); + + if ( vecPos.z + particle->m_fSize < fWaterLevel ) { bRemoveParticle = true; continue; @@ -1316,61 +1369,16 @@ void CParticle::Update() case LOOKING_LEFT: case LOOKING_RIGHT: case LOOKING_FORWARD: - nMaxDrops /= 2; + //nMaxDrops /= 2; break; default: - nMaxDrops = 0; + //nMaxDrops = 0; break; } fDistToCam = (TheCamera.GetPosition() - vecPos).Magnitude(); } - - if ( numWaterDropOnScreen < nMaxDrops && numWaterDropOnScreen < 63 - && fDistToCam < 10.0f - && clearWaterDrop == false - && !CGame::IsInInterior() ) - { - CVector vecWaterdropTarget - ( - CGeneral::GetRandomNumberInRange(-0.25f, 0.25f), - CGeneral::GetRandomNumberInRange(0.1f, 0.75f), - -0.01f - ); - - CVector vecWaterdropPos; - - if ( TheCamera.m_CameraAverageSpeed < 0.35f ) - vecWaterdropPos.x = (float)CGeneral::GetRandomNumberInRange(50, int32(SCREEN_WIDTH) - 50); - else - vecWaterdropPos.x = (float)CGeneral::GetRandomNumberInRange(200, int32(SCREEN_WIDTH) - 200); - - if ( psystem->m_Type == PARTICLE_BOAT_SPLASH || psystem->m_Type == PARTICLE_CAR_SPLASH ) - vecWaterdropPos.y = (float)CGeneral::GetRandomNumberInRange(SCREEN_HEIGHT / 2, SCREEN_HEIGHT); - else - { - if ( TheCamera.m_CameraAverageSpeed < 0.35f ) - vecWaterdropPos.y = (float)CGeneral::GetRandomNumberInRange(0, int32(SCREEN_HEIGHT)); - else - vecWaterdropPos.y = (float)CGeneral::GetRandomNumberInRange(150, int32(SCREEN_HEIGHT) - 200); - } - - vecWaterdropPos.z = 2.0f; - - if ( AddParticle(PARTICLE_WATERDROP, - vecWaterdropPos, - vecWaterdropTarget, - nil, - CGeneral::GetRandomNumberInRange(0.1f, 0.15f), - 0, - 0, - CGeneral::GetRandomNumber() & 1, - 0) != nil ) - { - numWaterDropOnScreen++; - } - } } if ( CTimer::GetTimeInMilliseconds() > particle->m_nTimeWhenWillBeDestroyed || particle->m_nAlpha == 0 ) @@ -1433,10 +1441,7 @@ void CParticle::Update() } else size = particle->m_fSize + particle->m_fExpansionRate; - - if ( psystem->m_Type == PARTICLE_WATERDROP ) - size = (size - Abs(vecMoveStep.x) * 0.000150000007f) + (Abs(vecMoveStep.z) * 0.0500000007f); //TODO: - + if ( size < 0.0f ) { bRemoveParticle = true; @@ -1717,28 +1722,6 @@ void CParticle::Update() continue; } } - - if ( psystem->m_nZRotationAngleChangeAmount != 0 ) - { - if ( particle->m_nZRotationTimer >= psystem->m_nZRotationChangeTime ) - { - particle->m_nZRotationTimer = 0; - particle->m_nCurrentZRotation += psystem->m_nZRotationAngleChangeAmount; - } - else - ++particle->m_nZRotationTimer; - } - - if ( psystem->m_fZRadiusChangeAmount != 0.0f ) - { - if ( particle->m_nZRadiusTimer >= psystem->m_nZRadiusChangeTime ) - { - particle->m_nZRadiusTimer = 0; - particle->m_fCurrentZRadius += psystem->m_fZRadiusChangeAmount; - } - else - ++particle->m_nZRadiusTimer; - } if ( psystem->m_nAnimationSpeed != 0 ) { @@ -1765,21 +1748,6 @@ void CParticle::Update() particle->m_nRotation += particle->m_nRotationStep; #endif - if ( particle->m_fCurrentZRadius != 0.0f ) - { - int32 nSinCosIndex = particle->m_nCurrentZRotation % SIN_COS_TABLE_SIZE; - - float fX = (Cos(nSinCosIndex) - Sin(nSinCosIndex)) * particle->m_fCurrentZRadius; - - float fY = (Sin(nSinCosIndex) + Cos(nSinCosIndex)) * particle->m_fCurrentZRadius; - - vecPos -= particle->m_vecParticleMovementOffset; - - vecPos += CVector(fX, fY, 0.0f); - - particle->m_vecParticleMovementOffset = CVector(fX, fY, 0.0f); - } - particle->m_vecPosition = vecPos; } } @@ -1812,6 +1780,8 @@ void CParticle::Render() RwRaster **frames = psystem->m_ppRaster; tParticleType type = psystem->m_Type; + /* + something on ps2 if ( type == PARTICLE_ENGINE_SMOKE || type == PARTICLE_ENGINE_SMOKE2 || type == PARTICLE_ENGINE_STEAM @@ -1823,7 +1793,7 @@ void CParticle::Render() { particleBanned = true; } - + */ if ( particle ) { if ( (flags & DRAW_OPAQUE) != (psystem->Flags & DRAW_OPAQUE) @@ -1868,6 +1838,8 @@ void CParticle::Render() if ( particle->m_nAlpha == 0 ) canDraw = false; + // TODO: psp vert buffer check + if ( canDraw && psystem->m_nFinalAnimationFrame != 0 && frames != nil ) { RwRaster *curFrame = frames[particle->m_nCurrentFrame]; @@ -1881,20 +1853,7 @@ void CParticle::Render() if ( canDraw && psystem->Flags & DRAWTOP2D ) { - float screenZ; -#ifdef FIX_BUGS - bool zIsZero = true; - if ( particle->m_vecPosition.z != 0.0f ) { -#endif - screenZ = (particle->m_vecPosition.z - CDraw::GetNearClipZ()) - * (CSprite::GetFarScreenZ() - CSprite::GetNearScreenZ()) - * CDraw::GetFarClipZ() - / ( (CDraw::GetFarClipZ() - CDraw::GetNearClipZ()) * particle->m_vecPosition.z ) - + CSprite::GetNearScreenZ(); -#ifdef FIX_BUGS - zIsZero = false; - } -#endif + float screenZ = CalcScreenZ(particle->m_vecPosition.z); float stretchTexW; float stretchTexH; @@ -1909,115 +1868,7 @@ void CParticle::Render() stretchTexW = CGeneral::GetRandomNumberInRange(0.1f, 1.0f) * psystem->m_vecTextureStretch.x + 63.0f; stretchTexH = CGeneral::GetRandomNumberInRange(0.1f, 1.0f) * psystem->m_vecTextureStretch.y + 63.0f; } - -#ifdef FIX_BUGS - if (!zIsZero) { -#endif - - if ( i == PARTICLE_WATERDROP ) - { - int32 timeLeft = (particle->m_nTimeWhenWillBeDestroyed - CTimer::GetTimeInMilliseconds()) / particle->m_nTimeWhenWillBeDestroyed; - - stretchTexH += (1.0f - (float)timeLeft ) * psystem->m_vecTextureStretch.y; - - RwRect rect; - - rect.x = int32(particle->m_vecPosition.x - SCREEN_STRETCH_X(particle->m_fSize * stretchTexW)); - rect.y = int32(particle->m_vecPosition.y - SCREEN_STRETCH_Y(particle->m_fSize * stretchTexH)); - rect.w = int32(particle->m_vecPosition.x + SCREEN_STRETCH_X(particle->m_fSize * stretchTexW)); - rect.h = int32(particle->m_vecPosition.y + SCREEN_STRETCH_Y(particle->m_fSize * stretchTexH)); - - FxType fxtype; - - if ( particle->m_nCurrentFrame != 0 ) - fxtype = FXTYPE_WATER2; - else - fxtype = FXTYPE_WATER1; - - CMBlur::AddRenderFx(Scene.camera, &rect, screenZ, fxtype); - - canDraw = false; - } - - if ( i == PARTICLE_BLOODDROP ) - { - int32 timeLeft = (particle->m_nTimeWhenWillBeDestroyed - CTimer::GetTimeInMilliseconds()) / particle->m_nTimeWhenWillBeDestroyed; - - stretchTexH += (1.0f + (float)timeLeft) * psystem->m_vecTextureStretch.y; - stretchTexW += (1.0f - (float)timeLeft) * psystem->m_vecTextureStretch.x; - - RwRect rect; - - rect.x = int32(particle->m_vecPosition.x - SCREEN_STRETCH_X(particle->m_fSize * stretchTexW)); - rect.y = int32(particle->m_vecPosition.y - SCREEN_STRETCH_Y(particle->m_fSize * stretchTexH)); - rect.w = int32(particle->m_vecPosition.x + SCREEN_STRETCH_X(particle->m_fSize * stretchTexW)); - rect.h = int32(particle->m_vecPosition.y + SCREEN_STRETCH_Y(particle->m_fSize * stretchTexH)); - - FxType fxtype; - - if ( particle->m_nCurrentFrame ) - fxtype = FXTYPE_BLOOD2; - else - fxtype = FXTYPE_BLOOD1; - - CMBlur::AddRenderFx(Scene.camera, &rect, screenZ, fxtype); - - canDraw = false; - } - - if ( i == PARTICLE_HEATHAZE_IN_DIST ) - { - RwRect rect; - - rect.x = int32(particle->m_vecPosition.x - SCREEN_STRETCH_X(particle->m_fSize * stretchTexW)); - rect.y = int32(particle->m_vecPosition.y - SCREEN_STRETCH_Y(particle->m_fSize * stretchTexH * 0.15f)); - rect.w = int32(particle->m_vecPosition.x + SCREEN_STRETCH_X(particle->m_fSize * stretchTexW)); - rect.h = int32(particle->m_vecPosition.y + SCREEN_STRETCH_Y(particle->m_fSize * stretchTexH * 0.15f)); - - CMBlur::AddRenderFx(Scene.camera, &rect, screenZ, FXTYPE_HEATHAZE); - - canDraw = false; - } - if ( i == PARTICLE_HEATHAZE ) - { - RwRect rect; - - switch ( TheCamera.GetLookDirection() ) - { - case LOOKING_LEFT: - rect.x = int32(particle->m_vecPosition.x - SCREEN_STRETCH_X(particle->m_fSize * psystem->m_vecTextureStretch.x * 2.0f)); - rect.y = int32(particle->m_vecPosition.y - SCREEN_STRETCH_Y(particle->m_fSize * psystem->m_vecTextureStretch.y)); - rect.w = int32(particle->m_vecPosition.x - SCREEN_STRETCH_X(particle->m_fSize * psystem->m_vecTextureStretch.x)); - rect.h = int32(particle->m_vecPosition.y + SCREEN_STRETCH_Y(particle->m_fSize * psystem->m_vecTextureStretch.y)); - - break; - - case LOOKING_RIGHT: - rect.x = int32(particle->m_vecPosition.x + SCREEN_STRETCH_X(particle->m_fSize * psystem->m_vecTextureStretch.x)); - rect.y = int32(particle->m_vecPosition.y - SCREEN_STRETCH_Y(particle->m_fSize * psystem->m_vecTextureStretch.y)); - rect.w = int32(particle->m_vecPosition.x + SCREEN_STRETCH_X(particle->m_fSize * psystem->m_vecTextureStretch.x * 4.0f)); - rect.h = int32(particle->m_vecPosition.y + SCREEN_STRETCH_Y(particle->m_fSize * psystem->m_vecTextureStretch.y)); - - break; - - default: - rect.x = int32(particle->m_vecPosition.x - SCREEN_STRETCH_X(particle->m_fSize * psystem->m_vecTextureStretch.x)); - rect.y = int32(particle->m_vecPosition.y - SCREEN_STRETCH_Y(particle->m_fSize * psystem->m_vecTextureStretch.y)); - rect.w = int32(particle->m_vecPosition.x + SCREEN_STRETCH_X(particle->m_fSize * psystem->m_vecTextureStretch.x)); - rect.h = int32(particle->m_vecPosition.y + SCREEN_STRETCH_Y(particle->m_fSize * psystem->m_vecTextureStretch.y)); - - break; - } - - CMBlur::AddRenderFx(Scene.camera, &rect, screenZ, FXTYPE_HEATHAZE); - - canDraw = false; - } -#ifdef FIX_BUGS - } - if ( !(zIsZero && (i == PARTICLE_WATERDROP || i == PARTICLE_BLOODDROP || i == PARTICLE_HEATHAZE_IN_DIST || i == PARTICLE_HEATHAZE) ) ) -#endif if ( canDraw ) { if ( particle->m_nRotation != 0 ) @@ -2082,6 +1933,8 @@ void CParticle::Render() } else if ( i == PARTICLE_WATER_HYDRANT ) { + float screenZ = CalcScreenZ(particle->m_vecPosition.z); + int32 timeLeft = (particle->m_nTimeWhenWillBeDestroyed - CTimer::GetTimeInMilliseconds()) / particle->m_nTimeWhenWillBeDestroyed; w += (1.0f - (float)timeLeft) * psystem->m_vecTextureStretch.x; @@ -2101,190 +1954,149 @@ void CParticle::Render() h += CGeneral::GetRandomNumberInRange(0.1f, 1.0f) * psystem->m_vecTextureStretch.y; } - if ( i == PARTICLE_WATER_HYDRANT - || (!particleBanned || SCREEN_WIDTH * fParticleScaleLimit >= w) - && SCREEN_HEIGHT * fParticleScaleLimit >= h ) + if ( particle->m_nRotation != 0 && i != PARTICLE_BEASTIE ) + { + CSprite::RenderBufferedOneXLUSprite_Rotate_Dimension(coors.x, coors.y, coors.z, + particle->m_fSize * w, particle->m_fSize * h, + particle->m_Color.red, + particle->m_Color.green, + particle->m_Color.blue, + particle->m_nColorIntensity, + 1.0f / coors.z, + DEGTORAD((float)particle->m_nRotation), + particle->m_nAlpha); + } + else if ( psystem->Flags & SCREEN_TRAIL ) { - if ( i == PARTICLE_WATER_HYDRANT ) + float fRotation; + float fTrailLength; + + if ( particle->m_fZGround == 0.0f ) { - RwRect rect; - - if ( w > 0.0f ) - { - rect.x = int32(coors.x - SCREEN_STRETCH_X(particle->m_fSize * w)); - rect.w = int32(coors.x + SCREEN_STRETCH_X(particle->m_fSize * w)); - } - else - { - rect.w = int32(coors.x - SCREEN_STRETCH_X(particle->m_fSize * w)); - rect.x = int32(coors.x + SCREEN_STRETCH_X(particle->m_fSize * w)); - } - - if ( h > 0.0f ) - { - rect.y = int32(coors.y - SCREEN_STRETCH_Y(particle->m_fSize * h)); - rect.h = int32(coors.y + SCREEN_STRETCH_Y(particle->m_fSize * h)); - } - else - { - rect.h = int32(coors.y - SCREEN_STRETCH_Y(particle->m_fSize * h)); - rect.y = int32(coors.y + SCREEN_STRETCH_Y(particle->m_fSize * h)); - } - - float screenZ = (coors.z - CDraw::GetNearClipZ()) - * (CSprite::GetFarScreenZ() - CSprite::GetNearScreenZ()) * CDraw::GetFarClipZ() - / ( (CDraw::GetFarClipZ() - CDraw::GetNearClipZ()) * coors.z ) + CSprite::GetNearScreenZ(); - - CMBlur::AddRenderFx(Scene.camera, &rect, screenZ, FXTYPE_SPLASH1); + fTrailLength = 0.0f; + fRotation = 0.0f; } else { - if ( particle->m_nRotation != 0 && i != PARTICLE_BEASTIE ) - { - CSprite::RenderBufferedOneXLUSprite_Rotate_Dimension(coors.x, coors.y, coors.z, - particle->m_fSize * w, particle->m_fSize * h, - particle->m_Color.red, - particle->m_Color.green, - particle->m_Color.blue, - particle->m_nColorIntensity, - 1.0f / coors.z, - DEGTORAD((float)particle->m_nRotation), - particle->m_nAlpha); - } - else if ( psystem->Flags & SCREEN_TRAIL ) - { - float fRotation; - float fTrailLength; - - if ( particle->m_fZGround == 0.0f ) - { - fTrailLength = 0.0f; - fRotation = 0.0f; - } - else - { - CVector2D vecDist - ( - coors.x - particle->m_fZGround, - coors.y - particle->m_fExpansionRate - ); + CVector2D vecDist + ( + coors.x - particle->m_fZGround, + coors.y - particle->m_fExpansionRate + ); - float fDist = vecDist.Magnitude(); + float fDist = vecDist.Magnitude(); - fTrailLength = fDist; - - float fRot = Asin(vecDist.x / fDist); + fTrailLength = fDist; + + float fRot = Asin(vecDist.x / fDist); - fRotation = fRot; + fRotation = fRot; - if ( vecDist.y < 0.0f ) - fRotation = -1.0f * fRot + DEGTORAD(180.0f); - - float fSpeed = particle->m_vecVelocity.Magnitude(); - - float fNewTrailLength = fSpeed * CTimer::GetTimeStep() * w * 2.0f; - - if ( fDist > fNewTrailLength ) - fTrailLength = fNewTrailLength; - } - - CSprite::RenderBufferedOneXLUSprite_Rotate_Dimension(coors.x, coors.y, coors.z, - particle->m_fSize * w, - particle->m_fSize * h + fTrailLength * psystem->m_fTrailLengthMultiplier, - particle->m_Color.red, - particle->m_Color.green, - particle->m_Color.blue, - particle->m_nColorIntensity, - 1.0f / coors.z, - fRotation, - particle->m_nAlpha); + if ( vecDist.y < 0.0f ) + fRotation = -1.0f * fRot + DEGTORAD(180.0f); + + float fSpeed = particle->m_vecVelocity.Magnitude(); + + float fNewTrailLength = fSpeed * CTimer::GetTimeStep() * w * 2.0f; + + if ( fDist > fNewTrailLength ) + fTrailLength = fNewTrailLength; + } + + CSprite::RenderBufferedOneXLUSprite_Rotate_Dimension(coors.x, coors.y, coors.z, + particle->m_fSize * w, + particle->m_fSize * h + fTrailLength * psystem->m_fTrailLengthMultiplier, + particle->m_Color.red, + particle->m_Color.green, + particle->m_Color.blue, + particle->m_nColorIntensity, + 1.0f / coors.z, + fRotation, + particle->m_nAlpha); - particle->m_fZGround = coors.x; // WTF ? - particle->m_fExpansionRate = coors.y; // WTF ? - } - else if ( psystem->Flags & SPEED_TRAIL ) - { - CVector vecPrevPos = particle->m_vecPosition - particle->m_vecVelocity; - float fRotation; - float fTrailLength; - CVector vecScreenPosition; - - if ( CSprite::CalcScreenCoors(vecPrevPos, &vecScreenPosition, &fTrailLength, &fRotation, true) ) - { - CVector2D vecDist - ( - coors.x - vecScreenPosition.x, - coors.y - vecScreenPosition.y - ); - - float fDist = vecDist.Magnitude(); - - fTrailLength = fDist; - - float fRot = Asin(vecDist.x / fDist); - - fRotation = fRot; - - if ( vecDist.y < 0.0f ) - fRotation = -1.0f * fRot + DEGTORAD(180.0f); - } - else - { - fRotation = 0.0f; - fTrailLength = 0.0f; - } - - CSprite::RenderBufferedOneXLUSprite_Rotate_Dimension(coors.x, coors.y, coors.z, - particle->m_fSize * w, - particle->m_fSize * h + fTrailLength * psystem->m_fTrailLengthMultiplier, - particle->m_Color.red, - particle->m_Color.green, - particle->m_Color.blue, - particle->m_nColorIntensity, - 1.0f / coors.z, - fRotation, - particle->m_nAlpha); - } - else if ( psystem->Flags & VERT_TRAIL ) - { - float fTrailLength = fabsf(particle->m_vecVelocity.z * 10.0f); - - CSprite::RenderBufferedOneXLUSprite(coors.x, coors.y, coors.z, - particle->m_fSize * w, - (particle->m_fSize + fTrailLength * psystem->m_fTrailLengthMultiplier) * h, - particle->m_Color.red, - particle->m_Color.green, - particle->m_Color.blue, - particle->m_nColorIntensity, - 1.0f / coors.z, - particle->m_nAlpha); - } - else if ( i == PARTICLE_RAINDROP_SMALL ) - { - CSprite::RenderBufferedOneXLUSprite(coors.x, coors.y, coors.z, - particle->m_fSize * w * 0.05f, - particle->m_fSize * h, - particle->m_Color.red, - particle->m_Color.green, - particle->m_Color.blue, - particle->m_nColorIntensity, - 1.0f / coors.z, - particle->m_nAlpha); - } - /*else if ( i == PARTICLE_BOAT_WAKE )*/ - else - { - CSprite::RenderBufferedOneXLUSprite(coors.x, coors.y, coors.z, - particle->m_fSize * w, - particle->m_fSize * h, - particle->m_Color.red, - particle->m_Color.green, - particle->m_Color.blue, - particle->m_nColorIntensity, - 1.0f / coors.z, - particle->m_nAlpha); - } + particle->m_fZGround = coors.x; // WTF ? + particle->m_fExpansionRate = coors.y; // WTF ? + } + else if ( psystem->Flags & SPEED_TRAIL ) + { + CVector vecPrevPos = particle->m_vecPosition - particle->m_vecVelocity; + float fRotation; + float fTrailLength; + CVector vecScreenPosition; + + if ( CSprite::CalcScreenCoors(vecPrevPos, &vecScreenPosition, &fTrailLength, &fRotation, true) ) + { + CVector2D vecDist + ( + coors.x - vecScreenPosition.x, + coors.y - vecScreenPosition.y + ); + + float fDist = vecDist.Magnitude(); + + fTrailLength = fDist; + + float fRot = Asin(vecDist.x / fDist); + + fRotation = fRot; + + if ( vecDist.y < 0.0f ) + fRotation = -1.0f * fRot + DEGTORAD(180.0f); + } + else + { + fRotation = 0.0f; + fTrailLength = 0.0f; } + + CSprite::RenderBufferedOneXLUSprite_Rotate_Dimension(coors.x, coors.y, coors.z, + particle->m_fSize * w, + particle->m_fSize * h + fTrailLength * psystem->m_fTrailLengthMultiplier, + particle->m_Color.red, + particle->m_Color.green, + particle->m_Color.blue, + particle->m_nColorIntensity, + 1.0f / coors.z, + fRotation, + particle->m_nAlpha); + } + else if ( psystem->Flags & VERT_TRAIL ) + { + float fTrailLength = Abs(particle->m_vecVelocity.z * 10.0f); + + CSprite::RenderBufferedOneXLUSprite(coors.x, coors.y, coors.z, + particle->m_fSize * w, + (particle->m_fSize + fTrailLength * psystem->m_fTrailLengthMultiplier) * h, + particle->m_Color.red, + particle->m_Color.green, + particle->m_Color.blue, + particle->m_nColorIntensity, + 1.0f / coors.z, + particle->m_nAlpha); + } + else if ( i == PARTICLE_RAINDROP_SMALL ) + { + CSprite::RenderBufferedOneXLUSprite(coors.x, coors.y, coors.z, + particle->m_fSize * w * 0.05f, + particle->m_fSize * h, + particle->m_Color.red, + particle->m_Color.green, + particle->m_Color.blue, + particle->m_nColorIntensity, + 1.0f / coors.z, + particle->m_nAlpha); + } + else + { + CSprite::RenderBufferedOneXLUSprite(coors.x, coors.y, coors.z, + particle->m_fSize * w, + particle->m_fSize * h, + particle->m_Color.red, + particle->m_Color.green, + particle->m_Color.blue, + particle->m_nColorIntensity, + 1.0f / coors.z, + particle->m_nAlpha); } } } @@ -2315,9 +2127,6 @@ void CParticle::RemovePSystem(tParticleType type) void CParticle::RemoveParticle(CParticle *pParticle, CParticle *pPrevParticle, tParticleSystemData *pPSystemData) { - if ( pPSystemData->m_Type == PARTICLE_WATERDROP ) - --numWaterDropOnScreen; - if ( pPrevParticle ) pPrevParticle->m_pNext = pParticle->m_pNext; else @@ -2417,18 +2226,7 @@ void CParticle::CalWindDir(CVector *vecDirIn, CVector *vecDirOut) void CParticle::HandleShipsAtHorizonStuff() { - tParticleSystemData *psystemdata = &mod_ParticleSystemManager.m_aParticles[PARTICLE_SHIP_SIDE]; - - for ( CParticle *particle = psystemdata->m_pParticles; particle; particle = particle->m_pNext ) - { - if ( CTimer::GetTimeInMilliseconds() > particle->m_nTimeWhenWillBeDestroyed - 32000 - && CTimer::GetTimeInMilliseconds() < particle->m_nTimeWhenWillBeDestroyed - 22000 ) - { - particle->m_nAlpha = Min(particle->m_nAlpha + 1, 96); - } - if ( CTimer::GetTimeInMilliseconds() > particle->m_nTimeWhenWillBeDestroyed - 10000 ) - particle->m_nFadeAlphaTimer = 1; - } + ; } void CParticle::HandleShootableBirdsStuff(CEntity *entity, CVector const&camPos) @@ -2468,7 +2266,7 @@ void CParticle::HandleShootableBirdsStuff(CEntity *entity, CVector const&camPos) bRemoveParticle = true; for ( int32 i = 0; i < 8; i++ ) - { + { CParticle *pBirdDerbis = AddParticle(PARTICLE_BIRD_DEBRIS, particle->m_vecPosition, CVector diff --git a/src/renderer/Particle.h b/src/renderer/Particle.h index 5542dc02..57e36f82 100644 --- a/src/renderer/Particle.h +++ b/src/renderer/Particle.h @@ -18,11 +18,6 @@ public: uint32 m_nTimeWhenWillBeDestroyed; uint32 m_nTimeWhenColorWillBeChanged; float m_fZGround; - CVector m_vecParticleMovementOffset; - int16 m_nCurrentZRotation; - uint16 m_nZRotationTimer; - float m_fCurrentZRadius; - uint16 m_nZRadiusTimer; uint8 m_nColorIntensity; uint8 m_nAlpha; float m_fSize; @@ -35,12 +30,13 @@ public: uint8 m_nCurrentFrame; RwRGBA m_Color; CParticle *m_pNext; - + int32 field_4C; + CParticle() { ; } - + ~CParticle() { ; @@ -95,14 +91,13 @@ public: static void HandleShipsAtHorizonStuff(); static void HandleShootableBirdsStuff(CEntity *entity, CVector const&camPos); + + static void SetPixelData(); }; -extern bool clearWaterDrop; -extern int32 numWaterDropOnScreen; extern RwRaster *gpCarSplashRaster[]; extern RwRaster *gpHeatHazeRaster; -extern RwRaster *gpDotRaster; extern RwRaster *gpRainDripRaster[]; extern RwRaster *gpRainDripDarkRaster[]; -VALIDATE_SIZE(CParticle, 0x58); +VALIDATE_SIZE(CParticle, 0x50); diff --git a/src/renderer/ParticleMgr.cpp b/src/renderer/ParticleMgr.cpp index f6919435..04f42c82 100644 --- a/src/renderer/ParticleMgr.cpp +++ b/src/renderer/ParticleMgr.cpp @@ -4,18 +4,30 @@ #include "FileMgr.h" #include "ParticleMgr.h" +// --LCS: File done + cParticleSystemMgr mod_ParticleSystemManager; const char *ParticleFilename = "PARTICLE.CFG"; cParticleSystemMgr::cParticleSystemMgr() { - memset(this, 0, sizeof(*this)); +#ifdef FIX_BUGS + m_aParticles = nil; +#endif +} + +#ifdef FIX_BUGS +cParticleSystemMgr::~cParticleSystemMgr() +{ + delete [] m_aParticles; } +#endif void cParticleSystemMgr::Initialise() { - LoadParticleData(); + if ( gMakeResources ) + LoadParticleData(); for ( int32 i = 0; i < MAX_PARTICLES; i++ ) m_aParticles[i].m_pParticles = nil; @@ -23,20 +35,30 @@ void cParticleSystemMgr::Initialise() void cParticleSystemMgr::LoadParticleData() { - CFileMgr::SetDir("DATA"); - CFileMgr::LoadFile(ParticleFilename, work_buff, ARRAY_SIZE(work_buff), "r"); +#ifdef FIX_BUGS + delete [] m_aParticles; +#endif + m_aParticles = new tParticleSystemData[MAX_PARTICLES]; + + memset(m_aParticles, 0, sizeof(tParticleSystemData)*MAX_PARTICLES); + + CFileMgr::SetDir("Data"); + ssize_t len = CFileMgr::LoadFile(ParticleFilename, work_buff, ARRAY_SIZE(work_buff), "r"); CFileMgr::SetDir(""); + ASSERT(!(len <= 0)); + tParticleSystemData *entry = nil; int32 type = PARTICLE_FIRST; + char *buffEnd = (char *)&work_buff[len]; char *lineStart = (char *)work_buff; char *lineEnd = lineStart + 1; char line[500]; char delims[4]; - while ( true ) + while ( lineStart < buffEnd ) { ASSERT(lineStart != nil); ASSERT(lineEnd != nil); diff --git a/src/renderer/ParticleMgr.h b/src/renderer/ParticleMgr.h index f4afc018..16da2c5f 100644 --- a/src/renderer/ParticleMgr.h +++ b/src/renderer/ParticleMgr.h @@ -124,15 +124,18 @@ class cParticleSystemMgr }; public: - tParticleSystemData m_aParticles[MAX_PARTICLES]; + tParticleSystemData *m_aParticles;//[MAX_PARTICLES]; cParticleSystemMgr(); +#ifdef FIX_BUGS + ~cParticleSystemMgr(); +#endif void Initialise(); void LoadParticleData(); void RangeCheck(tParticleSystemData *pData) { } }; -VALIDATE_SIZE(cParticleSystemMgr, 0x2FFC); +VALIDATE_SIZE(cParticleSystemMgr, 0x4); extern cParticleSystemMgr mod_ParticleSystemManager; diff --git a/src/renderer/ParticleType.h b/src/renderer/ParticleType.h index 9578083d..cb3d53f0 100644 --- a/src/renderer/ParticleType.h +++ b/src/renderer/ParticleType.h @@ -42,8 +42,6 @@ enum tParticleType PARTICLE_RAIN_SPLASH_BIGGROW, PARTICLE_RAIN_SPLASHUP, PARTICLE_WATERSPRAY, - PARTICLE_WATERDROP, - PARTICLE_BLOODDROP, PARTICLE_EXPLOSION_MEDIUM, PARTICLE_EXPLOSION_LARGE, PARTICLE_EXPLOSION_MFAST, @@ -83,10 +81,11 @@ enum tParticleType PARTICLE_SHIP_SIDE, PARTICLE_BEASTIE, PARTICLE_RAINDROP_2D, - PARTICLE_HEATHAZE, - PARTICLE_HEATHAZE_IN_DIST, + PARTICLE_FERRY_CHIM_SMOKE, + PARTICLE_MULTIPLAYER_HIT, + PARTICLE_HYDRANT_STEAM, MAX_PARTICLES, PARTICLE_FIRST = PARTICLE_SPARK, - PARTICLE_LAST = PARTICLE_HEATHAZE_IN_DIST + PARTICLE_LAST = PARTICLE_HYDRANT_STEAM };
\ No newline at end of file diff --git a/src/renderer/PlayerSkin.cpp b/src/renderer/PlayerSkin.cpp index ee944ca7..672312d4 100644 --- a/src/renderer/PlayerSkin.cpp +++ b/src/renderer/PlayerSkin.cpp @@ -124,7 +124,7 @@ void CPlayerSkin::BeginFrontendSkinEdit(void) { LoadPlayerDff(); - RpClumpForAllAtomics(gpPlayerClump, CClumpModelInfo::SetAtomicRendererCB, (void*)CVisibilityPlugins::RenderPlayerCB); +// RpClumpForAllAtomics(gpPlayerClump, CClumpModelInfo::SetAtomicRendererCB, (void*)CVisibilityPlugins::RenderPlayerCB); CWorld::Players[0].LoadPlayerSkin(); gOldFov = CDraw::GetFOV(); CDraw::SetFOV(30.0f); diff --git a/src/renderer/Renderer.cpp b/src/renderer/Renderer.cpp index 49e8e611..8e460208 100644 --- a/src/renderer/Renderer.cpp +++ b/src/renderer/Renderer.cpp @@ -2,6 +2,7 @@ #include "common.h" #include "main.h" +#include "General.h" #include "Lights.h" #include "ModelInfo.h" #include "Treadable.h" @@ -20,11 +21,18 @@ #include "ModelIndices.h" #include "Streaming.h" #include "Shadows.h" +#include "Coronas.h" #include "PointLights.h" #include "Occlusion.h" #include "Renderer.h" #include "custompipes.h" #include "Frontend.h" +#include "Ferry.h" +#include "Plane.h" +#include "WaterLevel.h" + +// maybe some day... +//#define GTA_WORLDSTREAM bool gbShowPedRoadGroups; bool gbShowCarRoadGroups; @@ -40,6 +48,11 @@ bool gbDontRenderPeds; bool gbDontRenderObjects; bool gbDontRenderVehicles; +bool gbRenderDebugEnvMap; + +// unused +bool gbLighting; + // unused int16 TestCloseThings; int16 TestBigThings; @@ -56,9 +69,9 @@ int32 CRenderer::ms_nNoOfVisibleEntities; CEntity *CRenderer::ms_aVisibleEntityPtrs[NUMVISIBLEENTITIES]; CEntity *CRenderer::ms_aInVisibleEntityPtrs[NUMINVISIBLEENTITIES]; int32 CRenderer::ms_nNoOfInVisibleEntities; -#ifdef NEW_RENDERER int32 CRenderer::ms_nNoOfVisibleVehicles; CEntity *CRenderer::ms_aVisibleVehiclePtrs[NUMVISIBLEENTITIES]; +#ifdef NEW_RENDERER int32 CRenderer::ms_nNoOfVisibleBuildings; CEntity *CRenderer::ms_aVisibleBuildingPtrs[NUMVISIBLEENTITIES]; #endif @@ -68,16 +81,12 @@ CVehicle *CRenderer::m_pFirstPersonVehicle; bool CRenderer::m_loadingPriority; float CRenderer::ms_lodDistScale = 1.2f; -// unused -BlockedRange CRenderer::aBlockedRanges[16]; -BlockedRange* CRenderer::pFullBlockedRanges; -BlockedRange* CRenderer::pEmptyBlockedRanges; - void CRenderer::Init(void) { gSortedVehiclesAndPeds.Init(40); - SortBIGBuildings(); + if(gMakeResources) + SortBIGBuildings(); } void @@ -95,10 +104,10 @@ CRenderer::PreRender(void) for(i = 0; i < ms_nNoOfVisibleEntities; i++) ms_aVisibleEntityPtrs[i]->PreRender(); + for(i = 0; i < ms_nNoOfVisibleVehicles; i++) + ms_aVisibleVehiclePtrs[i]->PreRender(); #ifdef NEW_RENDERER if(gbNewRenderer){ - for(i = 0; i < ms_nNoOfVisibleVehicles; i++) - ms_aVisibleVehiclePtrs[i]->PreRender(); // How is this done with cWorldStream? for(i = 0; i < ms_nNoOfVisibleBuildings; i++) ms_aVisibleBuildingPtrs[i]->PreRender(); @@ -128,11 +137,9 @@ CRenderer::PreRender(void) void CRenderer::RenderOneRoad(CEntity *e) { -#ifndef FINAL +#ifndef MASTER if(gbDontRenderBuildings) return; -#endif -#ifndef MASTER if(gbShowCollisionPolys || gbShowCollisionPolysReflections || gbShowCollisionPolysNoShadows) CCollision::DrawColModel_Coloured(e->GetMatrix(), *CModelInfo::GetModelInfo(e->GetModelIndex())->GetColModel(), e->GetModelIndex()); else @@ -206,16 +213,36 @@ CRenderer::RenderOneNonRoad(CEntity *e) // Render Peds in vehicle before vehicle itself if(e->IsVehicle()){ veh = (CVehicle*)e; - if(veh->pDriver && veh->pDriver->m_nPedState == PED_DRIVING) +#ifdef VIS_DISTANCE_ALPHA + int vehalpha = CVisibilityPlugins::GetObjectDistanceAlpha(veh->m_rwObject); +#endif + if(veh->pDriver && veh->pDriver->m_nPedState == PED_DRIVING){ +#ifdef VIS_DISTANCE_ALPHA + int alpha = CVisibilityPlugins::GetObjectDistanceAlpha(veh->pDriver->m_rwObject); + CVisibilityPlugins::SetObjectDistanceAlpha(veh->pDriver->m_rwObject, vehalpha); + veh->pDriver->Render(); + CVisibilityPlugins::SetObjectDistanceAlpha(veh->pDriver->m_rwObject, alpha); +#else veh->pDriver->Render(); +#endif + } for(i = 0; i < 8; i++) - if(veh->pPassengers[i] && veh->pPassengers[i]->m_nPedState == PED_DRIVING) + if(veh->pPassengers[i] && veh->pPassengers[i]->m_nPedState == PED_DRIVING){ +#ifdef VIS_DISTANCE_ALPHA + int alpha = CVisibilityPlugins::GetObjectDistanceAlpha(veh->pPassengers[i]->m_rwObject); + CVisibilityPlugins::SetObjectDistanceAlpha(veh->pPassengers[i]->m_rwObject, vehalpha); + veh->pPassengers[i]->Render(); + CVisibilityPlugins::SetObjectDistanceAlpha(veh->pPassengers[i]->m_rwObject, alpha); +#else veh->pPassengers[i]->Render(); +#endif + } SetCullMode(rwCULLMODECULLNONE); } e->Render(); if(e->IsVehicle()){ + // TODO(LCS): LCS does not use bImBeingRendered, keeping it for safety e->bImBeingRendered = true; CVisibilityPlugins::RenderAlphaAtomics(); e->bImBeingRendered = false; @@ -252,7 +279,7 @@ CRenderer::RenderRoads(void) PUSH_RENDERGROUP("CRenderer::RenderRoads"); RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)TRUE); - RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); +// RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); SetCullMode(rwCULLMODECULLBACK); DeActivateDirectional(); SetAmbientColours(); @@ -278,18 +305,18 @@ inline bool PutIntoSortedVehicleList(CVehicle *veh) return veh->bTouchingWater; } +// this only renders objects in LCS void CRenderer::RenderEverythingBarRoads(void) { int i; CEntity *e; - EntityInfo ei; PUSH_RENDERGROUP("CRenderer::RenderEverythingBarRoads"); - RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)TRUE); - RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); +// RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)TRUE); +// RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); SetCullMode(rwCULLMODECULLBACK); - gSortedVehiclesAndPeds.Clear(); +// gSortedVehiclesAndPeds.Clear(); for(i = 0; i < ms_nNoOfVisibleEntities; i++){ e = ms_aVisibleEntityPtrs[i]; @@ -302,17 +329,19 @@ CRenderer::RenderEverythingBarRoads(void) continue; #endif - if(e->IsVehicle() || - e->IsPed() && CVisibilityPlugins::GetClumpAlpha((RpClump*)e->m_rwObject) != 255){ - if(e->IsVehicle() && PutIntoSortedVehicleList((CVehicle*)e)){ - ei.ent = e; - ei.sort = (ms_vecCameraPosition - e->GetPosition()).MagnitudeSqr(); - gSortedVehiclesAndPeds.InsertSorted(ei); - }else{ - if(!CVisibilityPlugins::InsertEntityIntoSortedList(e, (ms_vecCameraPosition - e->GetPosition()).Magnitude())){ - printf("Ran out of space in alpha entity list"); - RenderOneNonRoad(e); - } + // we're not even rendering peds here.... +#ifdef VIS_DISTANCE_ALPHA + // this looks like a fix for objects just popping in + int distAlpha = CVisibilityPlugins::GetObjectDistanceAlpha(e->m_rwObject); + if(e->IsPed() && CVisibilityPlugins::GetClumpAlpha((RpClump*)e->m_rwObject) != 255 || + distAlpha != 255){ + if(distAlpha != 0 && !CVisibilityPlugins::InsertEntityIntoSortedList(e, (ms_vecCameraPosition - e->GetPosition()).Magnitude())){ +#else + if(e->IsPed() && CVisibilityPlugins::GetClumpAlpha((RpClump*)e->m_rwObject) != 255){ + if(!CVisibilityPlugins::InsertEntityIntoSortedList(e, (ms_vecCameraPosition - e->GetPosition()).Magnitude())){ +#endif + printf("Ran out of space in alpha entity list"); + RenderOneNonRoad(e); } }else RenderOneNonRoad(e); @@ -323,30 +352,26 @@ CRenderer::RenderEverythingBarRoads(void) void CRenderer::RenderBoats(void) { + int i; + CEntity *e; + EntityInfo ei; CLink<EntityInfo> *node; PUSH_RENDERGROUP("CRenderer::RenderBoats"); + gbLighting = true; RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)TRUE); - RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); +// RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); SetCullMode(rwCULLMODECULLBACK); -#ifdef NEW_RENDERER - int i; - CEntity *e; - EntityInfo ei; - if(gbNewRenderer){ - gSortedVehiclesAndPeds.Clear(); - // not the real thing - for(i = 0; i < ms_nNoOfVisibleVehicles; i++){ - e = ms_aVisibleVehiclePtrs[i]; - if(e->IsVehicle() && PutIntoSortedVehicleList((CVehicle*)e)){ - ei.ent = e; - ei.sort = (ms_vecCameraPosition - e->GetPosition()).MagnitudeSqr(); - gSortedVehiclesAndPeds.InsertSorted(ei); - } + gSortedVehiclesAndPeds.Clear(); + for(i = 0; i < ms_nNoOfVisibleVehicles; i++){ + e = ms_aVisibleVehiclePtrs[i]; + if(e->IsVehicle() && PutIntoSortedVehicleList((CVehicle*)e)){ + ei.ent = e; + ei.sort = (ms_vecCameraPosition - e->GetPosition()).MagnitudeSqr(); + gSortedVehiclesAndPeds.InsertSorted(ei); } } -#endif for(node = gSortedVehiclesAndPeds.tail.prev; node != &gSortedVehiclesAndPeds.head; @@ -354,6 +379,69 @@ CRenderer::RenderBoats(void) CVehicle *v = (CVehicle*)node->item.ent; RenderOneNonRoad(v); } + RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE); + gbLighting = false; + POP_RENDERGROUP(); +} + +// also renders peds +void +CRenderer::RenderVehicles(void) +{ + int i; + CEntity *e; + + PUSH_RENDERGROUP("CRenderer::RenderVehicles"); + // LCS: not on android + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); + // TODO(LCS): PS2VehicleAlphaFunc(); + + gbLighting = true; + RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)TRUE); + + CVisibilityPlugins::InitAlphaEntityList(); + for(i = 0; i < ms_nNoOfVisibleVehicles; i++){ + e = ms_aVisibleVehiclePtrs[i]; +#ifdef VIS_DISTANCE_ALPHA + if(CVisibilityPlugins::GetClumpAlpha((RpClump*)e->m_rwObject) == 0 || + CVisibilityPlugins::GetObjectDistanceAlpha(e->m_rwObject) == 0) + continue; +#endif + + int behindDriver = e->bIsPed && ((CPed*)e)->m_nPedState == PED_DRIVING && + TheCamera.GetLookDirection() == LOOKING_FORWARD; + // what is going on here? !behindDriver will always be true because we're checking for !PED_DRIVING + if(!e->bDistanceFade && (e->IsPed() || e->bIsPed) && ((CPed*)e)->m_nPedState != PED_DRIVING && !behindDriver){ +#ifdef VIS_DISTANCE_ALPHA + if(CVisibilityPlugins::GetClumpAlpha((RpClump*)e->m_rwObject) != 255 || + CVisibilityPlugins::GetObjectDistanceAlpha(e->m_rwObject) != 255) + ; // set blend render states + else + ; // set default render states +#endif + RenderOneNonRoad(e); + }else if(!PutIntoSortedVehicleList((CVehicle*)e) && // boats handled elsewhere + !CVisibilityPlugins::InsertEntityIntoSortedList(e, (ms_vecCameraPosition - e->GetPosition()).Magnitude())){ +#ifdef VIS_DISTANCE_ALPHA + if(CVisibilityPlugins::GetClumpAlpha((RpClump*)e->m_rwObject) != 255 || + CVisibilityPlugins::GetObjectDistanceAlpha(e->m_rwObject) != 255) + ; // set blend render states + else + ; // set default render states +#endif + printf("Ran out of space in alpha entity list"); + RenderOneNonRoad(e); + } + } + CVisibilityPlugins::RenderFadingEntities(); + + CFerry::RenderAllRemaning(); + CPlane::RenderAllRemaning(); + // TODO(LCS): gpGlobalEnvironmentMap = nil; + // TODO(LCS): CMattRenderer::Get().ResetRenderStates(); + RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE); + gbLighting = false; POP_RENDERGROUP(); } @@ -361,7 +449,6 @@ CRenderer::RenderBoats(void) #ifndef LIBRW #error "Need librw for EXTENDED_PIPELINES" #endif -#include "WaterLevel.h" enum { // blend passes @@ -442,12 +529,16 @@ CRenderer::RenderOneBuilding(CEntity *ent, float camdist) ent->bImBeingRendered = false; // TODO: this seems wrong, but do we even need it? } +// our replacement for cWorldStream::Render void CRenderer::RenderWorld(int pass) { int i; CEntity *e; CLink<CVisibilityPlugins::AlphaObjectInfo> *node; + // use old renderer + if(gbPreviewCity) + return; RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)TRUE); SetCullMode(rwCULLMODECULLBACK); @@ -511,57 +602,21 @@ CRenderer::RenderWorld(int pass) break; } } +#endif +// actually CMattRenderer::RenderWater +// adapted slightly void -CRenderer::RenderPeds(void) +CRenderer::RenderWater(void) { int i; CEntity *e; - PUSH_RENDERGROUP("CRenderer::RenderPeds"); - for(i = 0; i < ms_nNoOfVisibleVehicles; i++){ - e = ms_aVisibleVehiclePtrs[i]; - if(e->IsPed()) - RenderOneNonRoad(e); - } - POP_RENDERGROUP(); -} + PUSH_RENDERGROUP("CRenderer::RenderWater"); -void -CRenderer::RenderVehicles(void) -{ - int i; - CEntity *e; - EntityInfo ei; - CLink<EntityInfo> *node; - - PUSH_RENDERGROUP("CRenderer::RenderVehicles"); - // not the real thing - for(i = 0; i < ms_nNoOfVisibleVehicles; i++){ - e = ms_aVisibleVehiclePtrs[i]; - if(!e->IsVehicle()) - continue; - if(PutIntoSortedVehicleList((CVehicle*)e)) - continue; // boats handled elsewhere - ei.ent = e; - ei.sort = (ms_vecCameraPosition - e->GetPosition()).MagnitudeSqr(); - gSortedVehiclesAndPeds.InsertSorted(ei); - } + gbLighting = false; + CWaterLevel::RenderWater(); - for(node = gSortedVehiclesAndPeds.tail.prev; - node != &gSortedVehiclesAndPeds.head; - node = node->prev) - RenderOneNonRoad(node->item.ent); - POP_RENDERGROUP(); -} - -void -CRenderer::RenderTransparentWater(void) -{ - int i; - CEntity *e; - - PUSH_RENDERGROUP("CRenderer::RenderTransparentWater"); RwRenderStateSet(rwRENDERSTATETEXTURERASTER, nil); RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE); @@ -585,6 +640,7 @@ CRenderer::RenderTransparentWater(void) CWaterLevel::RenderTransparentWater(); SetStencilState(0); + gbLighting = true; POP_RENDERGROUP(); } @@ -593,22 +649,23 @@ CRenderer::ClearForFrame(void) { ms_nNoOfVisibleEntities = 0; ms_nNoOfVisibleVehicles = 0; - ms_nNoOfVisibleBuildings = 0; ms_nNoOfInVisibleEntities = 0; gSortedVehiclesAndPeds.Clear(); +#ifdef NEW_RENDERER + ms_nNoOfVisibleBuildings = 0; WorldRender::numBlendInsts[PASS_NOZ] = 0; WorldRender::numBlendInsts[PASS_ADD] = 0; WorldRender::numBlendInsts[PASS_BLEND] = 0; -} #endif +} void CRenderer::RenderFadingInEntities(void) { PUSH_RENDERGROUP("CRenderer::RenderFadingInEntities"); RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)TRUE); - RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); +// RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); SetCullMode(rwCULLMODECULLBACK); DeActivateDirectional(); SetAmbientColours(); @@ -620,6 +677,9 @@ void CRenderer::RenderFadingInUnderwaterEntities(void) { PUSH_RENDERGROUP("CRenderer::RenderFadingInUnderwaterEntities"); + RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)TRUE); +// RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); + SetCullMode(rwCULLMODECULLBACK); DeActivateDirectional(); SetAmbientColours(); CVisibilityPlugins::RenderFadingUnderwaterEntities(); @@ -666,6 +726,9 @@ CRenderer::SetupEntityVisibility(CEntity *ent) float dist; bool request = true; + if(mi->GetModelType() == MITYPE_SIMPLE){ + // TODO(LCS): some cWorldStream dynamics stuff + } if(mi->GetModelType() == MITYPE_TIME){ ti = (CTimeModelInfo*)mi; other = ti->GetOtherTimeModel(); @@ -687,6 +750,7 @@ CRenderer::SetupEntityVisibility(CEntity *ent) if(mi->GetModelType() != MITYPE_SIMPLE && mi->GetModelType() != MITYPE_WEAPON){ if(FindPlayerVehicle() == ent && TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_1STPERSON && +// TODO(LCS): something in CWorld::Players... !(FindPlayerVehicle()->IsBike() && ((CBike*)FindPlayerVehicle())->bWheelieCam)){ // Player's vehicle in first person mode CVehicle *veh = (CVehicle*)ent; @@ -694,6 +758,7 @@ CRenderer::SetupEntityVisibility(CEntity *ent) int direction = TheCamera.Cams[TheCamera.ActiveCam].DirectionWasLooking; if(direction == LOOKING_FORWARD || ent->GetModelIndex() == MI_RHINO || + ent->GetModelIndex() == MI_BUS || ent->GetModelIndex() == MI_COACH || TheCamera.m_bInATunnelAndABigVehicle || direction == LOOKING_BEHIND && veh->pHandling->Flags & HANDLING_UNKNOWN){ @@ -702,7 +767,7 @@ CRenderer::SetupEntityVisibility(CEntity *ent) } if(direction != LOOKING_BEHIND || - !veh->IsBoat() || model == MI_REEFER || model == MI_TROPIC || model == MI_PREDATOR || model == MI_SKIMMER){ + !veh->IsBoat() || model == MI_REEFER || model == MI_PREDATOR){ m_pFirstPersonVehicle = (CVehicle*)ent; ent->bNoBrightHeadLights = false; return VIS_OFFSCREEN; @@ -744,7 +809,8 @@ CRenderer::SetupEntityVisibility(CEntity *ent) dist = (ent->GetPosition() - ms_vecCameraPosition).Magnitude(); -#ifndef FIX_BUGS +//#ifndef FIX_BUGS +#if 0 // Whatever this is supposed to do, it breaks fading for objects // whose draw dist is > LOD_DISTANCE-FADE_DISTANCE, i.e. 280 // because decreasing dist here makes the object visible above LOD_DISTANCE @@ -754,6 +820,9 @@ CRenderer::SetupEntityVisibility(CEntity *ent) if(LOD_DISTANCE < dist && dist < mi->GetLargestLodDistance() + FADE_DISTANCE) dist += mi->GetLargestLodDistance() - LOD_DISTANCE; #endif + // LCS has this now, wonder if it's any better: + if(LOD_DISTANCE + STREAM_DISTANCE < dist && dist < mi->GetLargestLodDistance()) + dist = mi->GetLargestLodDistance(); if(ent->IsObject() && ent->bRenderDamaged) mi->m_isDamaged = true; @@ -805,7 +874,7 @@ CRenderer::SetupEntityVisibility(CEntity *ent) // We might be fading - a = mi->GetAtomicFromDistance(dist - FADE_DISTANCE); + a = mi->GetLastAtomic(dist - FADE_DISTANCE); mi->m_isDamaged = false; if(a == nil){ // request model @@ -871,7 +940,7 @@ CRenderer::SetupBigBuildingVisibility(CEntity *ent) // Find out whether to draw below near distance. // This is only the case if there is a non-LOD which is either not // loaded or not completely faded in yet. - if(dist < mi->GetNearDistance() && dist < LOD_DISTANCE){ + if(dist < mi->GetNearDistance() && dist < LOD_DISTANCE + STREAM_DISTANCE){ // No non-LOD or non-LOD is completely visible. if(nonLOD == nil || nonLOD->GetRwObject() && nonLOD->m_alpha == 255) @@ -927,7 +996,7 @@ CRenderer::SetupBigBuildingVisibility(CEntity *ent) // get faded atomic a = mi->GetFirstAtomicFromDistance(dist - FADE_DISTANCE); if(a == nil){ - if(ent->bStreamBIGBuilding && dist-STREAM_DISTANCE < mi->GetLodDistance(0) && request){ + if(ent->bStreamBIGBuilding && dist-STREAM_DISTANCE-FADE_DISTANCE < mi->GetLodDistance(0) && request){ return ent->GetIsOnScreen() ? VIS_STREAMME : VIS_INVISIBLE; }else{ ent->DeleteRwObject(); @@ -956,30 +1025,15 @@ void CRenderer::ConstructRenderList(void) { COcclusion::ProcessBeforeRendering(); -#ifdef NEW_RENDERER - if(!gbNewRenderer) -#endif -{ - ms_nNoOfVisibleEntities = 0; - ms_nNoOfInVisibleEntities = 0; -} ms_vecCameraPosition = TheCamera.GetPosition(); // unused - pFullBlockedRanges = nil; - pEmptyBlockedRanges = aBlockedRanges; - for(int i = 0; i < 16; i++){ - aBlockedRanges[i].prev = &aBlockedRanges[i-1]; - aBlockedRanges[i].next = &aBlockedRanges[i+1]; - } - aBlockedRanges[0].prev = nil; - aBlockedRanges[15].next = nil; - - // unused TestCloseThings = 0; TestBigThings = 0; ScanWorld(); + + // LCS: mobile has a bunch of code after this, } void @@ -1128,7 +1182,9 @@ CRenderer::ScanWorld(void) poly[2].y = CWorld::GetSectorY(vectors[CORNER_FAR_TOPRIGHT].y); ScanSectorPoly(poly, 3, ScanSectorList); } - + +#ifndef GTA_WORLDSTREAM + // TODO(LCS): may be better to have this code with gbPreviewCity #ifdef NO_ISLAND_LOADING if (FrontEndMenuManager.m_PrefsIslandLoading == CMenuManager::ISLAND_LOADING_HIGH) { ScanBigBuildingList(CWorld::GetBigBuildingList(LEVEL_BEACH)); @@ -1142,6 +1198,7 @@ CRenderer::ScanWorld(void) ScanBigBuildingList(CWorld::GetBigBuildingList(CGame::currLevel)); } ScanBigBuildingList(CWorld::GetBigBuildingList(LEVEL_GENERIC)); +#endif } } } @@ -1434,6 +1491,7 @@ CRenderer::ScanSectorPoly(RwV2d *poly, int32 numVertices, void (*scanfunc)(CPtrL } } +// probably didn't exist as a separate function in LCS void CRenderer::InsertEntityIntoList(CEntity *ent) { @@ -1441,15 +1499,32 @@ CRenderer::InsertEntityIntoList(CEntity *ent) if (!ent->m_rwObject) return; #endif -#ifdef NEW_RENDERER - // TODO: there are more flags being checked here - if(gbNewRenderer && (ent->IsVehicle() || ent->IsPed())) + if(ent->IsVehicle() || ent->bIsVehicle || ent->IsPed() || ent->bIsPed) ms_aVisibleVehiclePtrs[ms_nNoOfVisibleVehicles++] = ent; - else if(gbNewRenderer && ent->IsBuilding()) +#ifdef NEW_RENDERER + else if(!gbPreviewCity && ent->IsBuilding()) + ms_aVisibleBuildingPtrs[ms_nNoOfVisibleBuildings++] = ent; +#endif + else + ms_aVisibleEntityPtrs[ms_nNoOfVisibleEntities++] = ent; +#if defined(VIS_DISTANCE_ALPHA) && defined(FIX_BUGS) + // this flag can only be trusted if entity is in alpha list + // unfortunately we're checking it in other cases too, which is bad. + // no idea why this isn't a problem on android + ent->bDistanceFade = false; +#endif +} + +void +CRenderer::AddVisibleEntity(CEntity *ent) +{ +#ifdef NEW_RENDERER + if(!gbPreviewCity && ent->IsBuilding()) ms_aVisibleBuildingPtrs[ms_nNoOfVisibleBuildings++] = ent; else #endif ms_aVisibleEntityPtrs[ms_nNoOfVisibleEntities++] = ent; + ent->bOffscreen = false; } void @@ -1459,18 +1534,21 @@ CRenderer::ScanBigBuildingList(CPtrList &list) CEntity *ent; int vis; - int f = CTimer::GetFrameCounter() & 3; + int f = CTimer::GetFrameCounter() & 6; for(node = list.first; node; node = node->next){ ent = (CEntity*)node->item; - if(ent->bOffscreen || (ent->m_randomSeed&3) != f){ + if(ent->bOffscreen || (ent->m_randomSeed&6) != f){ ent->bOffscreen = true; vis = SetupBigBuildingVisibility(ent); }else - vis = VIS_VISIBLE; + vis = ent->bOffscreen ? VIS_INVISIBLE : VIS_VISIBLE; + if(ent->bMakeVisible){ + ent->bMakeVisible = false; + ent->bIsVisible = true; + } switch(vis){ case VIS_VISIBLE: - InsertEntityIntoList(ent); - ent->bOffscreen = false; + AddVisibleEntity(ent); break; case VIS_STREAMME: if(!CStreaming::ms_disableStreaming) @@ -1489,7 +1567,15 @@ CRenderer::ScanSectorList(CPtrList *lists) int i; float dx, dy; - for(i = 0; i < NUMSECTORENTITYLISTS; i++){ + int numLists = NUMSECTORENTITYLISTS; +#ifdef GTA_WORLDSTREAM + if(gbPreviewCity){ + numLists -= ENTITYLIST_UNKNOWN; + lists += ENTITYLIST_UNKNOWN; + } +#endif + + for(i = 0; i < numLists; i++){ list = &lists[i]; for(node = list->first; node; node = node->next){ ent = (CEntity*)node->item; @@ -1498,7 +1584,12 @@ CRenderer::ScanSectorList(CPtrList *lists) ent->m_scanCode = CWorld::GetCurrentScanCode(); ent->bOffscreen = false; - switch(SetupEntityVisibility(ent)){ + int vis = SetupEntityVisibility(ent); + if(ent->bMakeVisible){ + ent->bMakeVisible = false; + ent->bIsVisible = true; + } + switch(vis){ case VIS_VISIBLE: InsertEntityIntoList(ent); break; @@ -1534,7 +1625,15 @@ CRenderer::ScanSectorList_Priority(CPtrList *lists) int i; float dx, dy; - for(i = 0; i < NUMSECTORENTITYLISTS; i++){ + int numLists = NUMSECTORENTITYLISTS; +#ifdef GTA_WORLDSTREAM + if(gbPreviewCity){ + numLists -= ENTITYLIST_UNKNOWN; + lists += ENTITYLIST_UNKNOWN; + } +#endif + + for(i = 0; i < numLists; i++){ list = &lists[i]; for(node = list->first; node; node = node->next){ ent = (CEntity*)node->item; @@ -1543,7 +1642,12 @@ CRenderer::ScanSectorList_Priority(CPtrList *lists) ent->m_scanCode = CWorld::GetCurrentScanCode(); ent->bOffscreen = false; - switch(SetupEntityVisibility(ent)){ + int vis = SetupEntityVisibility(ent); + if(ent->bMakeVisible){ + ent->bMakeVisible = false; + ent->bIsVisible = true; + } + switch(vis){ case VIS_VISIBLE: InsertEntityIntoList(ent); break; @@ -1582,7 +1686,15 @@ CRenderer::ScanSectorList_Subway(CPtrList *lists) int i; float dx, dy; - for(i = 0; i < NUMSECTORENTITYLISTS; i++){ + int numLists = NUMSECTORENTITYLISTS; +#ifdef GTA_WORLDSTREAM + if(gbPreviewCity){ + numLists -= ENTITYLIST_UNKNOWN; + lists += ENTITYLIST_UNKNOWN; + } +#endif + + for(i = 0; i < numLists; i++){ list = &lists[i]; for(node = list->first; node; node = node->next){ ent = (CEntity*)node->item; @@ -1617,7 +1729,15 @@ CRenderer::ScanSectorList_RequestModels(CPtrList *lists) CEntity *ent; int i; - for(i = 0; i < NUMSECTORENTITYLISTS; i++){ + int numLists = NUMSECTORENTITYLISTS; +#ifdef GTA_WORLDSTREAM + if(gbPreviewCity){ + numLists -= ENTITYLIST_UNKNOWN; + lists += ENTITYLIST_UNKNOWN; + } +#endif + + for(i = 0; i < numLists; i++){ list = &lists[i]; for(node = list->first; node; node = node->next){ ent = (CEntity*)node->item; @@ -1664,9 +1784,12 @@ CRenderer::ShouldModelBeStreamed(CEntity *ent, const CVector &campos) if(!IsAreaVisible(ent->m_area)) return false; CTimeModelInfo *mi = (CTimeModelInfo *)CModelInfo::GetModelInfo(ent->GetModelIndex()); - if(mi->GetModelType() == MITYPE_TIME) - if(!CClock::GetIsTimeInRange(mi->GetTimeOn(), mi->GetTimeOff())) - return false; + if(!ent->IsObject() && !ent->IsDummy()){ + if(mi->GetModelType() == MITYPE_TIME) + if(!CClock::GetIsTimeInRange(mi->GetTimeOn(), mi->GetTimeOff())) + return false; + // LCS(TODO): cWorldStream::pDynamic, but just returns 0 anyway + } float dist = (ent->GetPosition() - campos).Magnitude(); if(mi->m_noFade) return dist - STREAM_DISTANCE < mi->GetLargestLodDistance(); @@ -1682,6 +1805,188 @@ CRenderer::RemoveVehiclePedLights(CEntity *ent, bool reset) if(reset) ReSetAmbientAndDirectionalColours(); } - SetAmbientColours(); - DeActivateDirectional(); +// SetAmbientColours(); +// DeActivateDirectional(); +} + + +#include "postfx.h" + +static RwIm2DVertex Screen2EnvQuad[4]; +static RwImVertexIndex EnvQuadIndices[6] = { 0, 1, 2, 0, 2, 3 }; + +static void +SetQuadVertices(RwRaster *env, RwRaster *screen, float z) +{ + uint32 width = RwRasterGetWidth(env); + uint32 height = RwRasterGetHeight(env); + + float zero, xmax, ymax; + + zero = -HALFPX; + xmax = width - HALFPX; + ymax = height - HALFPX; + + float recipz = 1.0f/z; + float umax = (float)SCREEN_WIDTH/RwRasterGetWidth(screen); + float vmax = (float)SCREEN_HEIGHT/RwRasterGetHeight(screen); + + RwIm2DVertexSetScreenX(&Screen2EnvQuad[0], zero); + RwIm2DVertexSetScreenY(&Screen2EnvQuad[0], zero); + RwIm2DVertexSetScreenZ(&Screen2EnvQuad[0], RwIm2DGetNearScreenZ()); + RwIm2DVertexSetCameraZ(&Screen2EnvQuad[0], z); + RwIm2DVertexSetRecipCameraZ(&Screen2EnvQuad[0], recipz); + RwIm2DVertexSetU(&Screen2EnvQuad[0], 0.0f, recipz); + RwIm2DVertexSetV(&Screen2EnvQuad[0], 0.0f, recipz); + RwIm2DVertexSetIntRGBA(&Screen2EnvQuad[0], 255, 255, 255, 255); + + RwIm2DVertexSetScreenX(&Screen2EnvQuad[1], zero); + RwIm2DVertexSetScreenY(&Screen2EnvQuad[1], ymax); + RwIm2DVertexSetScreenZ(&Screen2EnvQuad[1], RwIm2DGetNearScreenZ()); + RwIm2DVertexSetCameraZ(&Screen2EnvQuad[1], z); + RwIm2DVertexSetRecipCameraZ(&Screen2EnvQuad[1], recipz); + RwIm2DVertexSetU(&Screen2EnvQuad[1], 0.0f, recipz); + RwIm2DVertexSetV(&Screen2EnvQuad[1], vmax, recipz); + RwIm2DVertexSetIntRGBA(&Screen2EnvQuad[1], 255, 255, 255, 255); + + RwIm2DVertexSetScreenX(&Screen2EnvQuad[2], xmax); + RwIm2DVertexSetScreenY(&Screen2EnvQuad[2], ymax); + RwIm2DVertexSetScreenZ(&Screen2EnvQuad[2], RwIm2DGetNearScreenZ()); + RwIm2DVertexSetCameraZ(&Screen2EnvQuad[2], z); + RwIm2DVertexSetRecipCameraZ(&Screen2EnvQuad[2], recipz); + RwIm2DVertexSetU(&Screen2EnvQuad[2], umax, recipz); + RwIm2DVertexSetV(&Screen2EnvQuad[2], vmax, recipz); + RwIm2DVertexSetIntRGBA(&Screen2EnvQuad[2], 255, 255, 255, 255); + + RwIm2DVertexSetScreenX(&Screen2EnvQuad[3], xmax); + RwIm2DVertexSetScreenY(&Screen2EnvQuad[3], zero); + RwIm2DVertexSetScreenZ(&Screen2EnvQuad[3], RwIm2DGetNearScreenZ()); + RwIm2DVertexSetCameraZ(&Screen2EnvQuad[3], z); + RwIm2DVertexSetRecipCameraZ(&Screen2EnvQuad[3], recipz); + RwIm2DVertexSetU(&Screen2EnvQuad[3], umax, recipz); + RwIm2DVertexSetV(&Screen2EnvQuad[3], 0.0f, recipz); + RwIm2DVertexSetIntRGBA(&Screen2EnvQuad[3], 255, 255, 255, 255); +} + +static RwIm2DVertex coronaVerts[4*4]; +static RwImVertexIndex coronaIndices[6*4]; +static int numCoronaVerts, numCoronaIndices; + +static void +AddCorona(float x, float y, float sz) +{ + float nearz, recipz; + RwIm2DVertex *v; + nearz = RwIm2DGetNearScreenZ(); + float z = RwCameraGetNearClipPlane(RwCameraGetCurrentCamera()); + recipz = 1.0f/z; + + v = &coronaVerts[numCoronaVerts]; + RwIm2DVertexSetScreenX(&v[0], x); + RwIm2DVertexSetScreenY(&v[0], y); + RwIm2DVertexSetScreenZ(&v[0], z); + RwIm2DVertexSetScreenZ(&v[0], nearz); + RwIm2DVertexSetRecipCameraZ(&v[0], recipz); + RwIm2DVertexSetU(&v[0], 0.0f, recipz); + RwIm2DVertexSetV(&v[0], 0.0f, recipz); + RwIm2DVertexSetIntRGBA(&v[0], 255, 255, 255, 255); + + RwIm2DVertexSetScreenX(&v[1], x); + RwIm2DVertexSetScreenY(&v[1], y + sz); + RwIm2DVertexSetScreenZ(&v[1], z); + RwIm2DVertexSetScreenZ(&v[1], nearz); + RwIm2DVertexSetRecipCameraZ(&v[1], recipz); + RwIm2DVertexSetU(&v[1], 0.0f, recipz); + RwIm2DVertexSetV(&v[1], 1.0f, recipz); + RwIm2DVertexSetIntRGBA(&v[1], 255, 255, 255, 255); + + RwIm2DVertexSetScreenX(&v[2], x + sz); + RwIm2DVertexSetScreenY(&v[2], y + sz); + RwIm2DVertexSetScreenZ(&v[2], z); + RwIm2DVertexSetScreenZ(&v[2], nearz); + RwIm2DVertexSetRecipCameraZ(&v[2], recipz); + RwIm2DVertexSetU(&v[2], 1.0f, recipz); + RwIm2DVertexSetV(&v[2], 1.0f, recipz); + RwIm2DVertexSetIntRGBA(&v[2], 255, 255, 255, 255); + + RwIm2DVertexSetScreenX(&v[3], x + sz); + RwIm2DVertexSetScreenY(&v[3], y); + RwIm2DVertexSetScreenZ(&v[3], z); + RwIm2DVertexSetScreenZ(&v[3], nearz); + RwIm2DVertexSetRecipCameraZ(&v[3], recipz); + RwIm2DVertexSetU(&v[3], 1.0f, recipz); + RwIm2DVertexSetV(&v[3], 0.0f, recipz); + RwIm2DVertexSetIntRGBA(&v[3], 255, 255, 255, 255); + + + coronaIndices[numCoronaIndices++] = numCoronaVerts; + coronaIndices[numCoronaIndices++] = numCoronaVerts + 1; + coronaIndices[numCoronaIndices++] = numCoronaVerts + 2; + coronaIndices[numCoronaIndices++] = numCoronaVerts; + coronaIndices[numCoronaIndices++] = numCoronaVerts + 2; + coronaIndices[numCoronaIndices++] = numCoronaVerts + 3; + numCoronaVerts += 4; +} + +static void +DrawEnvMapCoronas(float heading) +{ + RwRaster *rt = RwTextureGetRaster(CustomPipes::EnvMapTex); + const float BIG = 89.0f * RwRasterGetWidth(rt)/128.0f; + const float SMALL = 38.0f * RwRasterGetHeight(rt)/128.0f; + + float x; + numCoronaVerts = 0; + numCoronaIndices = 0; + x = (heading - PI)/TWOPI;// - 1.0f; + x *= BIG+SMALL; + AddCorona(x, 0.0f, BIG); x += BIG; + AddCorona(x, 12.0f, SMALL); x += SMALL; + AddCorona(x, 0.0f, BIG); x += BIG; + AddCorona(x, 12.0f, SMALL); x += SMALL; + + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE); + RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); + RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpCoronaTexture[CCoronas::TYPE_STAR])); + RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, coronaVerts, numCoronaVerts, coronaIndices, numCoronaIndices); + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); + RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE); +} + +void +CRenderer::GenerateEnvironmentMap(void) +{ + // We'll probably do this differently eventually + // re-using all sorts of stuff here... + + CPostFX::GetBackBuffer(Scene.camera); + + RwCameraBeginUpdate(CustomPipes::EnvMapCam); + + // get current scene + SetQuadVertices(RwTextureGetRaster(CustomPipes::EnvMapTex), CPostFX::pBackBuffer, RwCameraGetNearClipPlane(RwCameraGetCurrentCamera())); + RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE); + RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE); + RwRenderStateSet(rwRENDERSTATETEXTURERASTER, CPostFX::pBackBuffer); + RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERLINEAR); + RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE); + RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, Screen2EnvQuad, 4, EnvQuadIndices, 6); + RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE); + RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE); + + // Draw coronas + if(CustomPipes::VehiclePipeSwitch != CustomPipes::VEHICLEPIPE_MOBILE) + DrawEnvMapCoronas(TheCamera.GetForward().Heading()); + + RwCameraEndUpdate(CustomPipes::EnvMapCam); + + + RwCameraBeginUpdate(Scene.camera); + + if(gbRenderDebugEnvMap){ + RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(CustomPipes::EnvMapTex)); + RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, CustomPipes::EnvScreenQuad, 4, (RwImVertexIndex*)CustomPipes::QuadIndices, 6); + } } diff --git a/src/renderer/Renderer.h b/src/renderer/Renderer.h index 9b202098..baf2016b 100644 --- a/src/renderer/Renderer.h +++ b/src/renderer/Renderer.h @@ -25,13 +25,6 @@ extern bool gbDontRenderVehicles; class CVehicle; class CPtrList; -// unused -struct BlockedRange -{ - float a, b; // unknown - BlockedRange *prev, *next; -}; - class CRenderer { static int32 ms_nNoOfVisibleEntities; @@ -49,10 +42,6 @@ class CRenderer static CVector ms_vecCameraPosition; static CVehicle *m_pFirstPersonVehicle; - // unused - static BlockedRange aBlockedRanges[16]; - static BlockedRange *pFullBlockedRanges; - static BlockedRange *pEmptyBlockedRanges; public: static float ms_lodDistScale; static bool m_loadingPriority; @@ -93,13 +82,15 @@ public: static void RemoveVehiclePedLights(CEntity *ent, bool reset); -#ifdef NEW_RENDERER static void ClearForFrame(void); - static void RenderPeds(void); static void RenderVehicles(void); // also renders peds in LCS + static void RenderWater(void); // keep-out polys and transparent water +#ifdef NEW_RENDERER static void RenderOneBuilding(CEntity *ent, float camdist = 0.0f); static void RenderWorld(int pass); // like cWorldStream::Render(int) - static void RenderTransparentWater(void); // keep-out polys and transparent water #endif static void InsertEntityIntoList(CEntity *ent); + static void AddVisibleEntity(CEntity *ent); + + static void GenerateEnvironmentMap(void); }; diff --git a/src/renderer/Shadows.cpp b/src/renderer/Shadows.cpp index dd87bff6..ae4cf724 100644 --- a/src/renderer/Shadows.cpp +++ b/src/renderer/Shadows.cpp @@ -76,14 +76,14 @@ CShadows::Init(void) gpShadowBikeTex = RwTextureRead("shad_bike", nil); gpShadowBaronTex = RwTextureRead("shad_rcbaron", nil); gpShadowExplosionTex = RwTextureRead("shad_exp", nil); - gpShadowHeadLightsTex = RwTextureRead("headlight", nil); + gpShadowHeadLightsTex = RwTextureRead("headlight_single", nil); gpOutline1Tex = RwTextureRead("outline_64", nil); gpOutline2Tex = RwTextureRead("outline2_64", nil); gpOutline3Tex = RwTextureRead("outline3_64", nil); gpBloodPoolTex = RwTextureRead("bloodpool_64", nil); - gpReflectionTex = RwTextureRead("reflection01", nil); + //gpReflectionTex = RwTextureRead("reflection01", nil); gpWalkDontTex = RwTextureRead("walk_dont", nil); - gpCrackedGlassTex = RwTextureRead("wincrack_32", nil); + //gpCrackedGlassTex = RwTextureRead("wincrack_32", nil); gpPostShadowTex = RwTextureRead("lamp_shad_64", nil); CTxdStore::PopCurrentTxd(); @@ -99,9 +99,9 @@ CShadows::Init(void) ASSERT(gpOutline2Tex != nil); ASSERT(gpOutline3Tex != nil); ASSERT(gpBloodPoolTex != nil); - ASSERT(gpReflectionTex != nil); + //ASSERT(gpReflectionTex != nil); ASSERT(gpWalkDontTex != nil); - ASSERT(gpCrackedGlassTex != nil); + //ASSERT(gpCrackedGlassTex != nil); ASSERT(gpPostShadowTex != nil); @@ -178,9 +178,9 @@ CShadows::Shutdown(void) ASSERT(gpOutline2Tex != nil); ASSERT(gpOutline3Tex != nil); ASSERT(gpBloodPoolTex != nil); - ASSERT(gpReflectionTex != nil); + //ASSERT(gpReflectionTex != nil); ASSERT(gpWalkDontTex != nil); - ASSERT(gpCrackedGlassTex != nil); + //ASSERT(gpCrackedGlassTex != nil); ASSERT(gpPostShadowTex != nil); RwTextureDestroy(gpShadowCarTex); @@ -194,9 +194,9 @@ CShadows::Shutdown(void) RwTextureDestroy(gpOutline2Tex); RwTextureDestroy(gpOutline3Tex); RwTextureDestroy(gpBloodPoolTex); - RwTextureDestroy(gpReflectionTex); + //RwTextureDestroy(gpReflectionTex); RwTextureDestroy(gpWalkDontTex); - RwTextureDestroy(gpCrackedGlassTex); + //RwTextureDestroy(gpCrackedGlassTex); RwTextureDestroy(gpPostShadowTex); } diff --git a/src/renderer/SpecialFX.cpp b/src/renderer/SpecialFX.cpp index 61750f85..4bf94f2b 100644 --- a/src/renderer/SpecialFX.cpp +++ b/src/renderer/SpecialFX.cpp @@ -878,7 +878,7 @@ C3dMarkers::PlaceMarker(uint32 identifier, uint16 type, CVector &pos, float size pMarker->m_Matrix.GetPosition() = pos; if (pMarker->m_bFindZOnNextPlacement) { - if ((playerPos - pos).MagnitudeSqr() < sq(100.f) && CColStore::HasCollisionLoaded(CVector2D(pos))) { + if ((playerPos - pos).MagnitudeSqr() < sq(100.f) && CColStore::HasCollisionLoaded(pos)) { float z = CWorld::FindGroundZFor3DCoord(pos.x, pos.y, pos.z + 1.0f, nil); if (z != 0.0f) pMarker->m_Matrix.GetPosition().z = z - 0.05f * size; @@ -894,7 +894,7 @@ C3dMarkers::PlaceMarker(uint32 identifier, uint16 type, CVector &pos, float size pMarker->AddMarker(identifier, type, size, r, g, b, a, pulsePeriod, pulseFraction, rotateRate); if (type == MARKERTYPE_CYLINDER || type == MARKERTYPE_0 || type == MARKERTYPE_2) { - if ((playerPos - pos).MagnitudeSqr() < sq(100.f) && CColStore::HasCollisionLoaded(CVector2D(pos))) { + if ((playerPos - pos).MagnitudeSqr() < sq(100.f) && CColStore::HasCollisionLoaded(pos)) { float z = CWorld::FindGroundZFor3DCoord(pos.x, pos.y, pos.z + 1.0f, nil); if (z != 0.0f) pos.z = z - 0.05f * size; diff --git a/src/renderer/Sprite.cpp b/src/renderer/Sprite.cpp index ecfd3fdc..bf2c929f 100644 --- a/src/renderer/Sprite.cpp +++ b/src/renderer/Sprite.cpp @@ -14,6 +14,19 @@ float CSprite::m_f2DFarScreenZ; float CSprite::m_fRecipNearClipPlane; int32 CSprite::m_bFlushSpriteBufferSwitchZTest; +float CalcScreenZ(float z) +{ + // LCS TODO: check + + if ( z == 0.0f ) + return CSprite::GetNearScreenZ(); + + return (z - CDraw::GetNearClipZ()) + * (CSprite::GetFarScreenZ() - CSprite::GetNearScreenZ()) * CDraw::GetFarClipZ() + / ( (CDraw::GetFarClipZ() - CDraw::GetNearClipZ()) * z ) + + CSprite::GetNearScreenZ(); +} + float CSprite::CalcHorizonCoors(void) { diff --git a/src/renderer/Sprite.h b/src/renderer/Sprite.h index fae6684e..952837a0 100644 --- a/src/renderer/Sprite.h +++ b/src/renderer/Sprite.h @@ -29,3 +29,5 @@ public: static void RenderBufferedOneXLUSprite2D_Rotate_Dimension(float x, float y, float w, float h, const RwRGBA &colour, int16 intens, float rotation, uint8 alpha); }; + +extern float CalcScreenZ(float z);
\ No newline at end of file diff --git a/src/renderer/Timecycle.cpp b/src/renderer/Timecycle.cpp index 95d9fe3c..8a3efd85 100644 --- a/src/renderer/Timecycle.cpp +++ b/src/renderer/Timecycle.cpp @@ -134,6 +134,61 @@ float CTimeCycle::m_fShadowSideY[16]; float CTimeCycle::m_fShadowDisplacementX[16]; float CTimeCycle::m_fShadowDisplacementY[16]; + + +static float tmp_nAmbientRed[NUMHOURS][NUMWEATHERS]; +static float tmp_nAmbientGreen[NUMHOURS][NUMWEATHERS]; +static float tmp_nAmbientBlue[NUMHOURS][NUMWEATHERS]; +static float tmp_nAmbientRed_Obj[NUMHOURS][NUMWEATHERS]; +static float tmp_nAmbientGreen_Obj[NUMHOURS][NUMWEATHERS]; +static float tmp_nAmbientBlue_Obj[NUMHOURS][NUMWEATHERS]; +static float tmp_nAmbientRed_Bl[NUMHOURS][NUMWEATHERS]; +static float tmp_nAmbientGreen_Bl[NUMHOURS][NUMWEATHERS]; +static float tmp_nAmbientBlue_Bl[NUMHOURS][NUMWEATHERS]; +static float tmp_nAmbientRed_Obj_Bl[NUMHOURS][NUMWEATHERS]; +static float tmp_nAmbientGreen_Obj_Bl[NUMHOURS][NUMWEATHERS]; +static float tmp_nAmbientBlue_Obj_Bl[NUMHOURS][NUMWEATHERS]; +static float tmp_nDirectionalRed[NUMHOURS][NUMWEATHERS]; +static float tmp_nDirectionalGreen[NUMHOURS][NUMWEATHERS]; +static float tmp_nDirectionalBlue[NUMHOURS][NUMWEATHERS]; +static float tmp_nSkyTopRed[NUMHOURS][NUMWEATHERS]; +static float tmp_nSkyTopGreen[NUMHOURS][NUMWEATHERS]; +static float tmp_nSkyTopBlue[NUMHOURS][NUMWEATHERS]; +static float tmp_nSkyBottomRed[NUMHOURS][NUMWEATHERS]; +static float tmp_nSkyBottomGreen[NUMHOURS][NUMWEATHERS]; +static float tmp_nSkyBottomBlue[NUMHOURS][NUMWEATHERS]; +static float tmp_nSunCoreRed[NUMHOURS][NUMWEATHERS]; +static float tmp_nSunCoreGreen[NUMHOURS][NUMWEATHERS]; +static float tmp_nSunCoreBlue[NUMHOURS][NUMWEATHERS]; +static float tmp_nSunCoronaRed[NUMHOURS][NUMWEATHERS]; +static float tmp_nSunCoronaGreen[NUMHOURS][NUMWEATHERS]; +static float tmp_nSunCoronaBlue[NUMHOURS][NUMWEATHERS]; +static float tmp_fSunSize[NUMHOURS][NUMWEATHERS]; +static float tmp_fSpriteSize[NUMHOURS][NUMWEATHERS]; +static float tmp_fSpriteBrightness[NUMHOURS][NUMWEATHERS]; +static float tmp_nShadowStrength[NUMHOURS][NUMWEATHERS]; +static float tmp_nLightShadowStrength[NUMHOURS][NUMWEATHERS]; +static float tmp_nPoleShadowStrength[NUMHOURS][NUMWEATHERS]; +static float tmp_fFogStart[NUMHOURS][NUMWEATHERS]; +static float tmp_fFarClip[NUMHOURS][NUMWEATHERS]; +static float tmp_fLightsOnGroundBrightness[NUMHOURS][NUMWEATHERS]; +static float tmp_nLowCloudsRed[NUMHOURS][NUMWEATHERS]; +static float tmp_nLowCloudsGreen[NUMHOURS][NUMWEATHERS]; +static float tmp_nLowCloudsBlue[NUMHOURS][NUMWEATHERS]; +static float tmp_nFluffyCloudsTopRed[NUMHOURS][NUMWEATHERS]; +static float tmp_nFluffyCloudsTopGreen[NUMHOURS][NUMWEATHERS]; +static float tmp_nFluffyCloudsTopBlue[NUMHOURS][NUMWEATHERS]; +static float tmp_nFluffyCloudsBottomRed[NUMHOURS][NUMWEATHERS]; +static float tmp_nFluffyCloudsBottomGreen[NUMHOURS][NUMWEATHERS]; +static float tmp_nFluffyCloudsBottomBlue[NUMHOURS][NUMWEATHERS]; +static float tmp_fBlurRed[NUMHOURS][NUMWEATHERS]; +static float tmp_fBlurGreen[NUMHOURS][NUMWEATHERS]; +static float tmp_fBlurBlue[NUMHOURS][NUMWEATHERS]; +static float tmp_fWaterRed[NUMHOURS][NUMWEATHERS]; +static float tmp_fWaterGreen[NUMHOURS][NUMWEATHERS]; +static float tmp_fWaterBlue[NUMHOURS][NUMWEATHERS]; +static float tmp_fWaterAlpha[NUMHOURS][NUMWEATHERS]; + void CTimeCycle::Initialise(void) { @@ -171,7 +226,7 @@ CTimeCycle::Initialise(void) for(h = 0; h < NUMHOURS; h++){ li = 0; while(work_buff[bi] == '/' || work_buff[bi] == '\n' || - work_buff[bi] == '\0' || work_buff[bi] == ' ' || work_buff[bi] == '\r'){ + work_buff[bi] == '\0' || work_buff[bi] == '\r'){ while(work_buff[bi] != '\n' && work_buff[bi] != '\0' && work_buff[bi] != '\r') bi++; bi++; @@ -207,65 +262,180 @@ CTimeCycle::Initialise(void) &blurR, &blurG, &blurB, &waterR, &waterG, &waterB, &waterA); - m_nAmbientRed[h][w] = ambR; - m_nAmbientGreen[h][w] = ambG; - m_nAmbientBlue[h][w] = ambB; - m_nAmbientRed_Obj[h][w] = ambobjR; - m_nAmbientGreen_Obj[h][w] = ambobjG; - m_nAmbientBlue_Obj[h][w] = ambobjB; - m_nAmbientRed_Bl[h][w] = ambblR; - m_nAmbientGreen_Bl[h][w] = ambblG; - m_nAmbientBlue_Bl[h][w] = ambblB; - m_nAmbientRed_Obj_Bl[h][w] = ambobjblR; - m_nAmbientGreen_Obj_Bl[h][w] = ambobjblG; - m_nAmbientBlue_Obj_Bl[h][w] = ambobjblB; - m_nDirectionalRed[h][w] = dirR; - m_nDirectionalGreen[h][w] = dirG; - m_nDirectionalBlue[h][w] = dirB; - m_nSkyTopRed[h][w] = skyTopR; - m_nSkyTopGreen[h][w] = skyTopG; - m_nSkyTopBlue[h][w] = skyTopB; - m_nSkyBottomRed[h][w] = skyBotR; - m_nSkyBottomGreen[h][w] = skyBotG; - m_nSkyBottomBlue[h][w] = skyBotB; - m_nSunCoreRed[h][w] = sunCoreR; - m_nSunCoreGreen[h][w] = sunCoreG; - m_nSunCoreBlue[h][w] = sunCoreB; - m_nSunCoronaRed[h][w] = sunCoronaR; - m_nSunCoronaGreen[h][w] = sunCoronaG; - m_nSunCoronaBlue[h][w] = sunCoronaB; - m_fSunSize[h][w] = sunSz * 10.0f; - m_fSpriteSize[h][w] = sprSz * 10.0f; - m_fSpriteBrightness[h][w] = sprBght * 10.0f; - m_nShadowStrength[h][w] = shad; - m_nLightShadowStrength[h][w] = lightShad; - m_nPoleShadowStrength[h][w] = poleShad; - m_fFarClip[h][w] = farClp; - m_fFogStart[h][w] = fogSt; - m_fLightsOnGroundBrightness[h][w] = lightGnd * 10.0f; - m_nLowCloudsRed[h][w] = cloudR; - m_nLowCloudsGreen[h][w] = cloudG; - m_nLowCloudsBlue[h][w] = cloudB; - m_nFluffyCloudsTopRed[h][w] = fluffyTopR; - m_nFluffyCloudsTopGreen[h][w] = fluffyTopG; - m_nFluffyCloudsTopBlue[h][w] = fluffyTopB; - m_nFluffyCloudsBottomRed[h][w] = fluffyBotR; - m_nFluffyCloudsBottomGreen[h][w] = fluffyBotG; - m_nFluffyCloudsBottomBlue[h][w] = fluffyBotB; - m_fBlurRed[h][w] = blurR; - m_fBlurGreen[h][w] = blurG; - m_fBlurBlue[h][w] = blurB; - m_fWaterRed[h][w] = waterR; - m_fWaterGreen[h][w] = waterG; - m_fWaterBlue[h][w] = waterB; - m_fWaterAlpha[h][w] = waterA; + tmp_nAmbientRed[h][w] = ambR; + tmp_nAmbientGreen[h][w] = ambG; + tmp_nAmbientBlue[h][w] = ambB; + tmp_nAmbientRed_Obj[h][w] = ambobjR; + tmp_nAmbientGreen_Obj[h][w] = ambobjG; + tmp_nAmbientBlue_Obj[h][w] = ambobjB; + tmp_nAmbientRed_Bl[h][w] = ambblR; + tmp_nAmbientGreen_Bl[h][w] = ambblG; + tmp_nAmbientBlue_Bl[h][w] = ambblB; + tmp_nAmbientRed_Obj_Bl[h][w] = ambobjblR; + tmp_nAmbientGreen_Obj_Bl[h][w] = ambobjblG; + tmp_nAmbientBlue_Obj_Bl[h][w] = ambobjblB; + tmp_nDirectionalRed[h][w] = dirR; + tmp_nDirectionalGreen[h][w] = dirG; + tmp_nDirectionalBlue[h][w] = dirB; + tmp_nSkyTopRed[h][w] = skyTopR; + tmp_nSkyTopGreen[h][w] = skyTopG; + tmp_nSkyTopBlue[h][w] = skyTopB; + tmp_nSkyBottomRed[h][w] = skyBotR; + tmp_nSkyBottomGreen[h][w] = skyBotG; + tmp_nSkyBottomBlue[h][w] = skyBotB; + tmp_nSunCoreRed[h][w] = sunCoreR; + tmp_nSunCoreGreen[h][w] = sunCoreG; + tmp_nSunCoreBlue[h][w] = sunCoreB; + tmp_nSunCoronaRed[h][w] = sunCoronaR; + tmp_nSunCoronaGreen[h][w] = sunCoronaG; + tmp_nSunCoronaBlue[h][w] = sunCoronaB; + if(sunSz == -1) + tmp_fSunSize[h][w] = -1; + else + tmp_fSunSize[h][w] = sunSz * 10.0f; + if(sprSz == -1) + tmp_fSpriteSize[h][w] = -1; + else + tmp_fSpriteSize[h][w] = sprSz * 10.0f; + if(sprBght == -1) + tmp_fSpriteBrightness[h][w] = -1; + else + tmp_fSpriteBrightness[h][w] = sprBght * 10.0f; + tmp_nShadowStrength[h][w] = shad; + tmp_nLightShadowStrength[h][w] = lightShad; + tmp_nPoleShadowStrength[h][w] = poleShad; + tmp_fFarClip[h][w] = farClp; + tmp_fFogStart[h][w] = fogSt; + if(lightGnd == -1) + tmp_fLightsOnGroundBrightness[h][w] = -1; + else + tmp_fLightsOnGroundBrightness[h][w] = lightGnd * 10.0f; + tmp_nLowCloudsRed[h][w] = cloudR; + tmp_nLowCloudsGreen[h][w] = cloudG; + tmp_nLowCloudsBlue[h][w] = cloudB; + tmp_nFluffyCloudsTopRed[h][w] = fluffyTopR; + tmp_nFluffyCloudsTopGreen[h][w] = fluffyTopG; + tmp_nFluffyCloudsTopBlue[h][w] = fluffyTopB; + tmp_nFluffyCloudsBottomRed[h][w] = fluffyBotR; + tmp_nFluffyCloudsBottomGreen[h][w] = fluffyBotG; + tmp_nFluffyCloudsBottomBlue[h][w] = fluffyBotB; + tmp_fBlurRed[h][w] = blurR; + tmp_fBlurGreen[h][w] = blurG; + tmp_fBlurBlue[h][w] = blurB; + tmp_fWaterRed[h][w] = waterR; + tmp_fWaterGreen[h][w] = waterG; + tmp_fWaterBlue[h][w] = waterB; + tmp_fWaterAlpha[h][w] = waterA; } + UpdateArrays(); + m_FogReduction = 0; debug("CTimeCycle ready\n"); } +template<typename T> void +FillGaps(T (*out)[NUMWEATHERS], float (*in)[NUMWEATHERS]) +{ + int w; + for(w = 0; w < NUMWEATHERS; w++){ + for(int h = 0; h < NUMHOURS; h++) + out[h][w] = in[h][w]; + +#define NEXT(h) (((h)+1)%NUMHOURS) +#define PREV(h) (((h)+NUMHOURS-1)%NUMHOURS) + int hend, h1, h2; + for(hend = 0; hend < NUMHOURS; hend++) + if(in[hend][w] != -1.0f) + goto foundstart; + return; // this should never happen +foundstart: + // Found the start of a block of filled in entries + for(h1 = NEXT(hend); h1 != hend; h1 = h2){ + // Skip filled in entries + for(; h1 != hend; h1 = NEXT(h1)) + if(in[h1][w] == -1.0f) + goto foundfirst; + break; // all filled in already +foundfirst: + // h1 is now the first -1 after n filled in values + for(h2 = NEXT(h1); ; h2 = NEXT(h2)) + if(in[h2][w] != -1.0f) + goto foundlast; + break; +foundlast: + // h2 is now the first entry after a row of -1s + h1 = PREV(h1); // make h1 the first before a row of -1s + int n = (h2-h1 + NUMHOURS) % NUMHOURS; + if(n == 0) n = NUMHOURS; // can't happen + float step = (in[h2][w] - in[h1][w])/n; + + for(int i = 1; i < n; i++){ + float f = (float)i/n; + out[(h1+i)%NUMHOURS][w] = in[h2][w]*f + in[h1][w]*(1.0f-f); + } + } + } +} + +void +CTimeCycle::UpdateArrays(void) +{ + FillGaps(m_nAmbientRed, tmp_nAmbientRed); + FillGaps(m_nAmbientGreen, tmp_nAmbientGreen); + FillGaps(m_nAmbientBlue, tmp_nAmbientBlue); + FillGaps(m_nAmbientRed_Obj, tmp_nAmbientRed_Obj); + FillGaps(m_nAmbientGreen_Obj, tmp_nAmbientGreen_Obj); + FillGaps(m_nAmbientBlue_Obj, tmp_nAmbientBlue_Obj); + FillGaps(m_nAmbientRed_Bl, tmp_nAmbientRed_Bl); + FillGaps(m_nAmbientGreen_Bl, tmp_nAmbientGreen_Bl); + FillGaps(m_nAmbientBlue_Bl, tmp_nAmbientBlue_Bl); + FillGaps(m_nAmbientRed_Obj_Bl, tmp_nAmbientRed_Obj_Bl); + FillGaps(m_nAmbientGreen_Obj_Bl, tmp_nAmbientGreen_Obj_Bl); + FillGaps(m_nAmbientBlue_Obj_Bl, tmp_nAmbientBlue_Obj_Bl); + FillGaps(m_nDirectionalRed, tmp_nDirectionalRed); + FillGaps(m_nDirectionalGreen, tmp_nDirectionalGreen); + FillGaps(m_nDirectionalBlue, tmp_nDirectionalBlue); + FillGaps(m_nSkyTopRed, tmp_nSkyTopRed); + FillGaps(m_nSkyTopGreen, tmp_nSkyTopGreen); + FillGaps(m_nSkyTopBlue, tmp_nSkyTopBlue); + FillGaps(m_nSkyBottomRed, tmp_nSkyBottomRed); + FillGaps(m_nSkyBottomGreen, tmp_nSkyBottomGreen); + FillGaps(m_nSkyBottomBlue, tmp_nSkyBottomBlue); + FillGaps(m_nSunCoreRed, tmp_nSunCoreRed); + FillGaps(m_nSunCoreGreen, tmp_nSunCoreGreen); + FillGaps(m_nSunCoreBlue, tmp_nSunCoreBlue); + FillGaps(m_nSunCoronaRed, tmp_nSunCoronaRed); + FillGaps(m_nSunCoronaGreen, tmp_nSunCoronaGreen); + FillGaps(m_nSunCoronaBlue, tmp_nSunCoronaBlue); + FillGaps(m_fSunSize, tmp_fSunSize); + FillGaps(m_fSpriteSize, tmp_fSpriteSize); + FillGaps(m_fSpriteBrightness, tmp_fSpriteBrightness); + FillGaps(m_nShadowStrength, tmp_nShadowStrength); + FillGaps(m_nLightShadowStrength, tmp_nLightShadowStrength); + FillGaps(m_nPoleShadowStrength, tmp_nPoleShadowStrength); + FillGaps(m_fFogStart, tmp_fFogStart); + FillGaps(m_fFarClip, tmp_fFarClip); + FillGaps(m_fLightsOnGroundBrightness, tmp_fLightsOnGroundBrightness); + FillGaps(m_nLowCloudsRed, tmp_nLowCloudsRed); + FillGaps(m_nLowCloudsGreen, tmp_nLowCloudsGreen); + FillGaps(m_nLowCloudsBlue, tmp_nLowCloudsBlue); + FillGaps(m_nFluffyCloudsTopRed, tmp_nFluffyCloudsTopRed); + FillGaps(m_nFluffyCloudsTopGreen, tmp_nFluffyCloudsTopGreen); + FillGaps(m_nFluffyCloudsTopBlue, tmp_nFluffyCloudsTopBlue); + FillGaps(m_nFluffyCloudsBottomRed, tmp_nFluffyCloudsBottomRed); + FillGaps(m_nFluffyCloudsBottomGreen, tmp_nFluffyCloudsBottomGreen); + FillGaps(m_nFluffyCloudsBottomBlue, tmp_nFluffyCloudsBottomBlue); + FillGaps(m_fBlurRed, tmp_fBlurRed); + FillGaps(m_fBlurGreen, tmp_fBlurGreen); + FillGaps(m_fBlurBlue, tmp_fBlurBlue); + FillGaps(m_fWaterRed, tmp_fWaterRed); + FillGaps(m_fWaterGreen, tmp_fWaterGreen); + FillGaps(m_fWaterBlue, tmp_fWaterBlue); + FillGaps(m_fWaterAlpha, tmp_fWaterAlpha); +} + static float interp_c0, interp_c1, interp_c2, interp_c3; float CTimeCycle::Interpolate(int8 *a, int8 *b) diff --git a/src/renderer/Timecycle.h b/src/renderer/Timecycle.h index da911b75..d8c333f6 100644 --- a/src/renderer/Timecycle.h +++ b/src/renderer/Timecycle.h @@ -185,6 +185,7 @@ public: static int32 GetWaterAlpha(void) { return m_fCurrentWaterAlpha; } static void Initialise(void); + static void UpdateArrays(void); static void Update(void); static float Interpolate(int8 *a, int8 *b); static float Interpolate(uint8 *a, uint8 *b); diff --git a/src/renderer/WaterCannon.cpp b/src/renderer/WaterCannon.cpp index 4976f8a3..4aaa8d6f 100644 --- a/src/renderer/WaterCannon.cpp +++ b/src/renderer/WaterCannon.cpp @@ -13,6 +13,16 @@ #include "Camera.h" #include "Particle.h" +// --LCS: file done + +#ifdef PSP_WATERCANNON + //PSP: + #define WATER_COLOR 255 +#else + //PS2: + #define WATER_COLOR 127 +#endif + #define WATERCANNONVERTS 4 #define WATERCANNONINDEXES 12 @@ -115,23 +125,33 @@ void CWaterCannon::Update_NewInput(CVector *pos, CVector *dir) m_abUsed[m_nCur] = true; } +static float fWaterCannonU = 0.0f; void CWaterCannon::Render(void) { + extern RwRaster *gpFireHoseRaster; + RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void *)FALSE); RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void *)TRUE); RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void *)TRUE); - RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void *)gpWaterRaster); + RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void *)gpFireHoseRaster); - float v = float(CGeneral::GetRandomNumber() & 255) / 256; - - RwIm3DVertexSetV(&WaterCannonVertices[0], v); - RwIm3DVertexSetV(&WaterCannonVertices[1], v); - RwIm3DVertexSetV(&WaterCannonVertices[2], v); - RwIm3DVertexSetV(&WaterCannonVertices[3], v); + fWaterCannonU += CTimer::GetTimeStepInSeconds() * 6.0f; - int16 pointA = m_nCur % NUM_SEGMENTPOINTS; + while ( fWaterCannonU >= 1.0f ) + fWaterCannonU -= 1.0f; + RwIm3DVertexSetU(&WaterCannonVertices[0], -fWaterCannonU); + RwIm3DVertexSetV(&WaterCannonVertices[0], 0.0f); + RwIm3DVertexSetU(&WaterCannonVertices[1], -fWaterCannonU); + RwIm3DVertexSetV(&WaterCannonVertices[1], 1.0f); + RwIm3DVertexSetU(&WaterCannonVertices[2], 1.0f - fWaterCannonU); + RwIm3DVertexSetV(&WaterCannonVertices[2], 0.0f); + RwIm3DVertexSetU(&WaterCannonVertices[3], 1.0f - fWaterCannonU); + RwIm3DVertexSetV(&WaterCannonVertices[3], 1.0f); + + int16 pointA = m_nCur % NUM_SEGMENTPOINTS; int16 pointB = pointA - 1; + int16 pointC = pointA; if ( pointB < 0 ) pointB += NUM_SEGMENTPOINTS; @@ -142,6 +162,10 @@ void CWaterCannon::Render(void) { if ( m_abUsed[pointA] && m_abUsed[pointB] ) { + bool bFirst = false; + if ( i == 0 || m_abUsed[pointA] && !m_abUsed[pointC] ) + bFirst = true; + if ( !bInit ) { CVector cp = CrossProduct(m_avecPos[pointB] - m_avecPos[pointA], TheCamera.GetForward()); @@ -149,26 +173,25 @@ void CWaterCannon::Render(void) bInit = true; } - float dist = float(i*i*i) / 300.0f + 1.0f; float brightness = float(i) / NUM_SEGMENTPOINTS; - int32 color = (int32)((1.0f - brightness*brightness) * 255.0f); - CVector offset = dist * norm; - RwIm3DVertexSetRGBA(&WaterCannonVertices[0], color, color, color, color); + CVector offset = (float(i)+1.0f) * norm; + + RwIm3DVertexSetRGBA(&WaterCannonVertices[0], WATER_COLOR, WATER_COLOR, WATER_COLOR, bFirst ? 0 : color); RwIm3DVertexSetPos (&WaterCannonVertices[0], m_avecPos[pointA].x - offset.x, m_avecPos[pointA].y - offset.y, m_avecPos[pointA].z - offset.z); - RwIm3DVertexSetRGBA(&WaterCannonVertices[1], color, color, color, color); + RwIm3DVertexSetRGBA(&WaterCannonVertices[1], WATER_COLOR, WATER_COLOR, WATER_COLOR, bFirst ? 0 : color); RwIm3DVertexSetPos (&WaterCannonVertices[1], m_avecPos[pointA].x + offset.x, m_avecPos[pointA].y + offset.y, m_avecPos[pointA].z + offset.z); - RwIm3DVertexSetRGBA(&WaterCannonVertices[2], color, color, color, color); + offset = (float(i+1)+1.0f) * norm; + + RwIm3DVertexSetRGBA(&WaterCannonVertices[2], WATER_COLOR, WATER_COLOR, WATER_COLOR, color); RwIm3DVertexSetPos (&WaterCannonVertices[2], m_avecPos[pointB].x - offset.x, m_avecPos[pointB].y - offset.y, m_avecPos[pointB].z - offset.z); - RwIm3DVertexSetRGBA(&WaterCannonVertices[3], color, color, color, color); + RwIm3DVertexSetRGBA(&WaterCannonVertices[3], WATER_COLOR, WATER_COLOR, WATER_COLOR, color); RwIm3DVertexSetPos (&WaterCannonVertices[3], m_avecPos[pointB].x + offset.x, m_avecPos[pointB].y + offset.y, m_avecPos[pointB].z + offset.z); - LittleTest(); - if ( RwIm3DTransform(WaterCannonVertices, WATERCANNONVERTS, NULL, rwIM3D_VERTEXUV) ) { RwIm3DRenderIndexedPrimitive(rwPRIMTYPETRILIST, WaterCannonIndexList, WATERCANNONINDEXES); @@ -176,6 +199,7 @@ void CWaterCannon::Render(void) } } + pointC = pointA; pointA = pointB--; if ( pointB < 0 ) pointB += NUM_SEGMENTPOINTS; diff --git a/src/renderer/WaterCannon.h b/src/renderer/WaterCannon.h index a37bdd12..5b60639c 100644 --- a/src/renderer/WaterCannon.h +++ b/src/renderer/WaterCannon.h @@ -14,6 +14,7 @@ public: int32 m_nId; int16 m_nCur; uint32 m_nTimeCreated; + int32 field_C; CVector m_avecPos[NUM_SEGMENTPOINTS]; CVector m_avecVelocity[NUM_SEGMENTPOINTS]; bool m_abUsed[NUM_SEGMENTPOINTS]; @@ -25,7 +26,7 @@ public: void PushPeds(void); }; -VALIDATE_SIZE(CWaterCannon, 412); +VALIDATE_SIZE(CWaterCannon, 0x1A0); class CWaterCannons { diff --git a/src/renderer/WaterCreatures.cpp b/src/renderer/WaterCreatures.cpp index 92fb74ee..4c6c92a6 100644 --- a/src/renderer/WaterCreatures.cpp +++ b/src/renderer/WaterCreatures.cpp @@ -8,6 +8,7 @@ #include "General.h" #include "Object.h" +/* int CWaterCreatures::nNumActiveSeaLifeForms; CWaterCreature CWaterCreatures::aWaterCreatures[NUM_WATER_CREATURES]; @@ -272,4 +273,5 @@ void CWaterCreatures::RemoveAll() { nNumActiveSeaLifeForms--; } } -}
\ No newline at end of file +} +*/
\ No newline at end of file diff --git a/src/renderer/WaterCreatures.h b/src/renderer/WaterCreatures.h index 32754a10..099cc1a4 100644 --- a/src/renderer/WaterCreatures.h +++ b/src/renderer/WaterCreatures.h @@ -2,6 +2,7 @@ class CObject; +/* enum eFishSlotState { WATER_CREATURE_INIT = 0, WATER_CREATURE_ACTIVE, @@ -46,4 +47,4 @@ struct WaterCreatureProperties { float fLevel; float fUnknown; //unused float fWaterDepth; -};
\ No newline at end of file +};*/
\ No newline at end of file diff --git a/src/renderer/WaterLevel.cpp b/src/renderer/WaterLevel.cpp index dee60d66..1aa63697 100644 --- a/src/renderer/WaterLevel.cpp +++ b/src/renderer/WaterLevel.cpp @@ -374,7 +374,7 @@ CWaterLevel::CreateWavyAtomic() { wavyMaterial = RpMaterialCreate(); RpMaterialSetTexture(wavyMaterial, gpWaterTex); - RwRGBA watercolor = { 255, 255, 255, 192 }; + RwRGBA watercolor = { 255, 255, 255, 255 /*192*/ }; RpMaterialSetColor(wavyMaterial, &watercolor); } @@ -1176,13 +1176,13 @@ CWaterLevel::RenderWater() if ( WavesCalculatedThisFrame ) { RenderSeaBirds(); - RenderShipsOnHorizon(); - CParticle::HandleShipsAtHorizonStuff(); - HandleBeachToysStuff(); + //RenderShipsOnHorizon(); + //CParticle::HandleShipsAtHorizonStuff(); + //HandleBeachToysStuff(); } - if ( _bSeaLife ) - HandleSeaLifeForms(); + //if ( _bSeaLife ) + // HandleSeaLifeForms(); DefinedState(); } @@ -1227,7 +1227,7 @@ CWaterLevel::RenderTransparentWater(void) colorTrans.red = CTimeCycle::GetWaterRed(); colorTrans.green = CTimeCycle::GetWaterGreen(); colorTrans.blue = CTimeCycle::GetWaterBlue(); - colorTrans.alpha = CTimeCycle::GetWaterAlpha(); + colorTrans.alpha = 255; //CTimeCycle::GetWaterAlpha(); TempBufferVerticesStored = 0; TempBufferIndicesStored = 0; @@ -1676,7 +1676,6 @@ void CWaterLevel::RenderOneWavySector(float fX, float fY, float fZ, RwRGBA const &color, bool bDontRender) { CVector vecSectorPos(fX + (SMALL_SECTOR_SIZE/2), fY + (SMALL_SECTOR_SIZE/2), fZ + 2.0f); - if ( COcclusion::IsAABoxOccluded(vecSectorPos, SMALL_SECTOR_SIZE, SMALL_SECTOR_SIZE, 4.0f) ) return; @@ -1815,6 +1814,7 @@ CWaterLevel::RenderWavyMask(float fX, float fY, float fZ, int32 nCamDirX, int32 nCamDirY, RwRGBA const&color) #endif { +return; // LCS #ifndef PC_WATER bool bRender = true; if (m_nRenderWaterLayers != 0 && m_nRenderWaterLayers != 2 && m_nRenderWaterLayers != 3) @@ -2531,7 +2531,7 @@ CWaterLevel::RenderBoatWakes(void) CBoat::FillBoatList(); - float fWakeZ = 5.97f; + float fWakeZ = 0.0f;//5.97f; float fWakeLifeTimeMult = 0.01f / CBoat::WAKE_LIFETIME; for ( int32 idx = 0; idx < ARRAY_SIZE(CBoat::apFrameWakeGeneratingBoats); idx++ ) @@ -3110,6 +3110,7 @@ CWaterLevel::RenderShipsOnHorizon() } } +/* void CWaterLevel::HandleSeaLifeForms() { @@ -3150,7 +3151,7 @@ CWaterLevel::HandleSeaLifeForms() } CWaterCreatures::UpdateAll(); -} +}*/ void CWaterLevel::HandleBeachToysStuff(void) diff --git a/src/renderer/WaterLevel.h b/src/renderer/WaterLevel.h index 6d6614d8..d12fb9f6 100644 --- a/src/renderer/WaterLevel.h +++ b/src/renderer/WaterLevel.h @@ -1,6 +1,6 @@ #pragma once -#define WATER_X_OFFSET (400.0f) +#define WATER_X_OFFSET (0.0f) #define WATER_Z_OFFSET (0.5f) diff --git a/src/renderer/Weather.cpp b/src/renderer/Weather.cpp index 9f925a8c..7358654c 100644 --- a/src/renderer/Weather.cpp +++ b/src/renderer/Weather.cpp @@ -49,6 +49,11 @@ float CWeather::WindClipped; float CWeather::TrafficLightBrightness; bool CWeather::bScriptsForceRain; +bool CWeather::Stored_StateStored; +float CWeather::Stored_InterpolationValue; +int16 CWeather::Stored_OldWeatherType; +int16 CWeather::Stored_NewWeatherType; +float CWeather::Stored_Rain; tRainStreak Streaks[NUM_RAIN_STREAKS]; @@ -323,6 +328,7 @@ void CWeather::Update(void) void CWeather::AddHeatHaze() { + /* if(TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWN || TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOP_DOWN_PED) return; @@ -334,6 +340,7 @@ void CWeather::AddHeatHaze() pos.y = CGeneral::GetRandomNumberInRange(SCREEN_HEIGHT*0.4f, SCREEN_HEIGHT*0.9f); pos.z = 100.0f; CParticle::AddParticle(PARTICLE_HEATHAZE_IN_DIST, pos, CVector(0.0f, 0.0f, 0.0f)); + */ } void CWeather::AddBeastie() @@ -646,6 +653,26 @@ void CWeather::RenderRainStreaks(void) TempBufferIndicesStored = 0; } +void CWeather::StoreWeatherState() +{ + Stored_StateStored = true; + Stored_InterpolationValue = InterpolationValue; + Stored_Rain = Rain; + Stored_NewWeatherType = NewWeatherType; + Stored_OldWeatherType = OldWeatherType; +} + +void CWeather::RestoreWeatherState() +{ +#ifdef FIX_BUGS // it's not used anyway though + Stored_StateStored = false; +#endif + InterpolationValue = Stored_InterpolationValue; + Rain = Stored_Rain; + NewWeatherType = Stored_NewWeatherType; + OldWeatherType = Stored_OldWeatherType; +} + #ifdef SECUROM void CWeather::ForceHurricaneWeather() { diff --git a/src/renderer/Weather.h b/src/renderer/Weather.h index bda57d55..0e7cf9bd 100644 --- a/src/renderer/Weather.h +++ b/src/renderer/Weather.h @@ -42,6 +42,11 @@ public: static float TrafficLightBrightness; static bool bScriptsForceRain; + static bool Stored_StateStored; + static float Stored_InterpolationValue; + static int16 Stored_OldWeatherType; + static int16 Stored_NewWeatherType; + static float Stored_Rain; static void RenderRainStreaks(void); static void Update(void); @@ -57,6 +62,8 @@ public: static void AddBeastie(); static void ForceHurricaneWeather(); + static void StoreWeatherState(); + static void RestoreWeatherState(); }; enum { |