summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/Frontend.cpp1470
-rw-r--r--src/Frontend.h291
-rw-r--r--src/PCSave.cpp5
-rw-r--r--src/PCSave.h9
-rw-r--r--src/Radar.cpp1068
-rw-r--r--src/Radar.h55
-rw-r--r--src/audio/DMAudio.cpp2
-rw-r--r--src/audio/DMAudio.h2
-rw-r--r--src/audio/MusicManager.cpp2
-rw-r--r--src/audio/MusicManager.h1
-rw-r--r--src/config.h1
-rw-r--r--src/control/Garages.cpp14
-rw-r--r--src/control/PedType.h4
-rw-r--r--src/control/Replay.cpp20
-rw-r--r--src/main.cpp22
-rw-r--r--src/render/Font.h24
-rw-r--r--src/render/Hud.cpp43
-rw-r--r--src/render/Hud.h6
-rw-r--r--src/skel/win/win.cpp6
-rw-r--r--src/skel/win/win.h2
20 files changed, 2547 insertions, 500 deletions
diff --git a/src/Frontend.cpp b/src/Frontend.cpp
index b8ee10f4..01acb740 100644
--- a/src/Frontend.cpp
+++ b/src/Frontend.cpp
@@ -1,6 +1,24 @@
+#define DIRECTINPUT_VERSION 0x0800
+#include <dinput.h>
#include "common.h"
#include "patcher.h"
+#include "win.h"
#include "Frontend.h"
+#include "Font.h"
+#include "Pad.h"
+#include "Text.h"
+#include "main.h"
+#include "Timer.h"
+#include "Game.h"
+#include "DMAudio.h"
+#include "MusicManager.h"
+#include "FileMgr.h"
+#include "Streaming.h"
+#include "TxdStore.h"
+#include "General.h"
+#include "PCSave.h"
+#include "Script.h"
+#include "Camera.h"
int32 &CMenuManager::OS_Language = *(int32*)0x5F2F78;
int8 &CMenuManager::m_PrefsUseVibration = *(int8*)0x95CD92;
@@ -17,6 +35,7 @@ int8 &CMenuManager::m_PrefsLanguage = *(int8*)0x941238;
bool &CMenuManager::m_PrefsAllowNastyGame = *(bool*)0x5F2E64;
bool &CMenuManager::m_bStartUpFrontEndRequested = *(bool*)0x95CCF4;
+bool &CMenuManager::m_bShutDownFrontEndRequested = *(bool*)0x95CD6A;
int8 &CMenuManager::m_PrefsUseWideScreen = *(int8*)0x95CD23;
int8 &CMenuManager::m_PrefsRadioStation = *(int8*)0x95CDA4;
@@ -29,14 +48,1130 @@ int32 &CMenuManager::m_PrefsSfxVolume = *(int32*)0x5F2E48;
CMenuManager &FrontEndMenuManager = *(CMenuManager*)0x8F59D8;
-WRAPPER void CMenuManager::Process(void) { EAXJMP(0x485100); }
+// TODO: replace magic numbers with enums
+const CMenuScreen aScreens[] = {
+ // MENU_PAGE_NONE = 0
+ { "", -1, -1, 1, 0, 0, },
+
+ // MENU_PAGE_STATS = 1
+ { "FET_STA", 0, 0, 0, 5, 2,
+ 2, "FEDS_TB", 0, 0,
+ },
+
+ // MENU_PAGE_NEW_GAME = 2
+ { "FET_SGA", 0, 0, 0, 0, 1,
+ 2, "FES_SNG", 0, 10,
+ 22, "GMLOAD", 0, 8,
+ 2, "FES_DGA", 0, 9,
+ 2, "FEDS_TB", 0, 0,
+ },
+
+ // MENU_PAGE_BRIEFS = 3
+ { "FET_BRE", 0, 0, 0, 6, 3,
+ 2, "FEDS_TB", 0, 0,
+ },
+
+ // MENU_CONTROLLER_SETTINGS = 4
+ { "FET_CON", 41, 41, 41, 0, 0,
+
+ },
+
+ // MENU_PAGE_SOUND_SETTINGS = 5
+ { "FET_AUD", 41, 41, 41, 1, 1,
+ 13, "FEA_MUS", 0, 5,
+ 14, "FEA_SFX", 0, 5,
+ 95, "FEA_3DH", 0, 5,
+ 96, "FEA_SPK", 0, 5,
+ 100, "FET_DAM", 0, 5,
+ 16, "FEA_RSS", 0, 5,
+ 98, "FET_DEF", 0, 5,
+ 2, "FEDS_TB", 0, 0,
+ },
+
+ // MENU_PAGE_GRAPHICS_SETTINGS = 6
+ { "FET_DIS", 41, 41, 41, 2, 2,
+ 11, "FED_BRI", 0, 6,
+ 12, "FEM_LOD", 0, 6,
+ 6, "FEM_VSC", 0, 6,
+ 7, "FEM_FRM", 0, 6,
+ 8, "FED_TRA", 0, 6,
+ 9, "FED_SUB", 0, 6,
+ 10, "FED_WIS", 0, 6,
+ 94, "FED_RES", 0, 6,
+ 98, "FET_DEF", 0, 6,
+ 2, "FEDS_TB", 0, 0,
+ },
+
+ // MENU_PAGE_LANGUAGE_SETTINGS = 7
+ { "FET_LAN", 41, 41, 41, 3, 3,
+ 17, "FEL_ENG", 0, 7,
+ 18, "FEL_FRE", 0, 7,
+ 19, "FEL_GER", 0, 7,
+ 20, "FEL_ITA", 0, 7,
+ 21, "FEL_SPA", 0, 7,
+ 2, "FEDS_TB", 0, 0,
+ },
+
+ // MENU_PAGE_CHOOSE_LOAD_SLOT = 8
+ { "FET_LG", 2, 2, 2, 1, 1,
+ 2, "FESZ_CA", 0, 2,
+ 23, "FEM_SL1", 2, 11,
+ 23, "FEM_SL2", 3, 11,
+ 23, "FEM_SL3", 4, 11,
+ 23, "FEM_SL4", 5, 11,
+ 23, "FEM_SL5", 6, 11,
+ 23, "FEM_SL6", 7, 11,
+ 23, "FEM_SL7", 8, 11,
+ 23, "FEM_SL8", 9, 11,
+ },
+
+ // MENU_PAGE_CHOOSE_DELETE_SLOT = 9
+ { "FET_DG", 2, 2, 2, 2, 2,
+ 2, "FESZ_CA", 0, 2,
+ 2, "FEM_SL1", 2, 12,
+ 2, "FEM_SL2", 3, 12,
+ 2, "FEM_SL3", 4, 12,
+ 2, "FEM_SL4", 5, 12,
+ 2, "FEM_SL5", 6, 12,
+ 2, "FEM_SL6", 7, 12,
+ 2, "FEM_SL7", 8, 12,
+ 2, "FEM_SL8", 9, 12,
+ },
+
+ // MENU_PAGE_NEW_GAME_RELOAD = 10
+ { "FET_NG", 2, 2, 2, 0, 0,
+ 1, "FESZ_QR", 0, 0,
+ 2, "FEM_NO", 0, 2,
+ 25, "FEM_YES", 0, 10,
+ },
+
+ // MENU_PAGE_LOAD_SLOT_CONFIRM = 11
+ { "FET_LG", 8, 8, 8, 0, 0,
+ 1, "FESZ_QL", 0, 0,
+ 2, "FEM_NO", 0, 8,
+ 2, "FEM_YES", 0, 14,
+ },
+
+ // MENU_PAGE_DELETE_SLOT_CONFIRM = 12
+ { "FET_DG", 9, 9, 9, 0, 0,
+ 1, "FESZ_QD", 0, 0,
+ 2, "FEM_NO", 0, 9,
+ 2, "FEM_YES", 0, 45,
+ },
+
+ // MENU_PAGE_13 = 13
+ { "FES_NOC", -1, -1, -1, 0, 0,
+
+ },
+
+ // MENU_PAGE_LOADING_IN_PROGRESS = 14
+ { "FET_LG", -1, -1, -1, 0, 0,
+ 1, "FED_LDW", 0, 11,
+ },
+
+ // MENU_PAGE_DELETING_IN_PROGRESS = 15
+ { "FET_DG", -1, -1, -1, 0, 0,
+ 1, "FEDL_WR", 0, 0,
+ },
+
+ // MENU_PAGE_16 = 16
+ { "FET_LG", -1, -1, -1, 0, 0,
+ 1, "FES_LOE", 0, 0,
+ },
+
+ // MENU_PAGE_DELETE_FAILED = 17
+ { "FET_DG", -1, -1, -1, 0, 0,
+ 1, "FES_DEE", 0, 0,
+ 2, "FEC_OKK", 0, 9,
+ },
+
+ // MENU_PAGE_DEBUG_MENU = 18
+ { "FED_DBG", -1, -1, -1, 0, 0,
+
+ },
+
+ // MENU_PAGE_MEMORY_CARD_1 = 19
+ { "FEM_MCM", -1, -1, -1, 0, 0,
+
+ },
+
+ // MENU_PAGE_MEMORY_CARD_2 = 20
+ { "FEM_MC2", -1, -1, -1, 0, 0,
+
+ },
+
+ // MENU_PAGE_MULTIPLAYER_MAIN = 21
+ { "FET_MP", -1, -1, -1, 0, 0,
+
+ },
+
+ // MENU_PAGE_SAVE_FAILED_1 = 22
+ { "MCDNSP", -1, -1, -1, 0, 0,
+ 48, "JAILB_U", 0, 0,
+ },
+
+ // MENU_PAGE_SAVE_FAILED_2 = 23
+ { "MCGNSP", -1, -1, -1, 0, 0,
+ 48, "JAILB_U", 0, 0,
+ },
+
+ // MENU_PAGE_SAVE = 24
+ { "FET_SG", -1, -1, -1, 0, 0,
+ 1, "FES_SCG", 0, 0,
+ 22, "GMSAVE", 0, 26,
+ 49, "FESZ_CA", 0, 0,
+ },
+
+ // MENU_PAGE_NO_MEMORY_CARD = 25
+ { "FES_NOC", -1, -1, -1, 0, 0,
+
+ },
+
+ // MENU_PAGE_CHOOSE_SAVE_SLOT = 26
+ { "FET_SG", -1, -1, -1, 0, 0,
+ 49, "FESZ_CA", 0, 0,
+ 2, "FEM_SL1", 2, 27,
+ 2, "FEM_SL2", 3, 27,
+ 2, "FEM_SL3", 4, 27,
+ 2, "FEM_SL4", 5, 27,
+ 2, "FEM_SL5", 6, 27,
+ 2, "FEM_SL6", 7, 27,
+ 2, "FEM_SL7", 8, 27,
+ 2, "FEM_SL8", 9, 27,
+ },
+
+ // MENU_PAGE_SAVE_OVERWRITE_CONFIRM = 27
+ { "FET_SG", 26, 26, 26, 0, 0,
+ 1, "FESZ_QO", 0, 0,
+ 2, "FEM_YES", 0, 43,
+ 2, "FEM_NO", 0, 26,
+ },
+
+ // MENU_PAGE_MULTIPLAYER_MAP = 28
+ { "FET_MAP", -1, -1, -1, 0, 0,
+
+ },
+
+ // MENU_PAGE_MULTIPLAYER_CONNECTION = 29
+ { "FET_CON", -1, -1, -1, 0, 0,
+
+ },
+
+ // MENU_PAGE_MULTIPLAYER_FIND_GAME = 30
+ { "FET_FG", -1, -1, -1, 0, 0,
+
+ },
+
+ // MENU_PAGE_MULTIPLAYER_MODE = 31
+ { "FET_GT", -1, -1, -1, 0, 0,
+
+ },
+
+ // MENU_PAGE_MULTIPLAYER_CREATE = 32
+ { "FET_HG", -1, -1, -1, 0, 0,
+
+ },
+
+ // MENU_PAGE_MULTIPLAYER_START = 33
+ { "FEN_STA", -1, -1, -1, 0, 0,
+
+ },
+
+ // MENU_PAGE_SKIN_SELECT_OLD = 34
+ { "FET_PS", -1, -1, -1, 0, 0,
+
+ },
+
+ // MENU_PAGE_CONTROLLER_PC = 35
+ { "FET_CTL", 41, 41, 41, 0, 0,
+ 99, "FET_CME", 0, 35,
+ 72, "FET_RDK", 0, 55,
+ 2, "FET_AMS", 0, 56,
+ 98, "FET_DEF", 0, 35,
+ 2, "FEDS_TB", 0, 0,
+ },
+
+ // MENU_PAGE_CONTROLLER_PC_OLD1 = 36
+ { "FET_CTL", 35, 35, 35, 0, 0,
+
+ },
+
+ // MENU_PAGE_CONTROLLER_PC_OLD2 = 37
+ { "FET_CTL", -1, -1, -1, 0, 0,
+
+ },
+
+ // MENU_PAGE_CONTROLLER_PC_OLD3 = 38
+ { "FET_CTL", -1, -1, -1, 0, 0,
+
+ },
+
+ // MENU_PAGE_CONTROLLER_PC_OLD4 = 39
+ { "FET_CTL", -1, -1, -1, 0, 0,
+
+ },
+
+ // MENU_PAGE_CONTROLLER_DEBUG = 40
+ { "FEC_DBG", -1, -1, -1, 0, 0,
+
+ },
+
+ // MENU_PAGE_OPTIONS = 41
+ { "FET_OPT", 0, 0, 0, 1, 4,
+ 2, "FET_CTL", 0, 35,
+ 101, "FET_AUD", 0, 5,
+ 2, "FET_DIS", 0, 6,
+ 2, "FET_LAN", 0, 7,
+ 97, "FET_PSU", 0, 54,
+ 2, "FEDS_TB", 0, 0,
+ },
+
+ // MENU_PAGE_EXIT = 42
+ { "FET_QG", 0, 0, 0, 2, 5,
+ 1, "FEQ_SRE", 0, 0,
+ 93, "FEM_NO", 0, 0,
+ 82, "FEM_YES", 0, 0,
+ },
+
+ // MENU_PAGE_SAVING_IN_PROGRESS = 43
+ { "", 26, 26, 26, 0, 0,
+ 1, "FES_WAR", 0, 0,
+ },
+
+ // MENU_PAGE_SAVE_SUCCESSFUL = 44
+ { "FET_SG", 26, 26, 26, 0, 0,
+ 1, "FES_SSC", 36, 0,
+ 49, "FEC_OKK", 0, 26,
+ },
+
+ // MENU_PAGE_DELETING = 45
+ { "FET_DG", 9, 9, 9, 0, 0,
+ 1, "FED_DLW", 0, 0,
+ },
+
+ // MENU_PAGE_DELETE_SUCCESS = 46
+ { "FET_DG", 9, 9, 9, 0, 0,
+ 1, "DEL_FNM", 0, 0,
+ 2, "FEC_OKK", 0, 9,
+ },
+
+ // MENU_PAGE_SAVE_FAILED = 47
+ { "FET_SG", 26, 26, 26, 0, 0,
+ 1, "FEC_SVU", 0, 0,
+ 2, "FEC_OKK", 0, 26,
+ },
+
+ // MENU_PAGE_LOAD_FAILED = 48
+ { "FET_SG", 26, 26, 26, 0, 0,
+ 1, "FEC_SVU", 0, 0,
+ },
+
+ // MENU_PAGE_LOAD_FAILED_2 = 49
+ { "FET_LG", 26, 26, 26, 0, 0,
+ 1, "FEC_LUN", 0, 0,
+ 2, "FEDS_TB", 0, 8,
+ },
+
+ // MENU_PAGE_FILTER_GAME = 50
+ { "FIL_FLT", -1, -1, -1, 0, 0,
+
+ },
+
+ // MENU_PAGE_START_MENU = 51
+ { "FEM_MM", -1, -1, -1, 0, 0,
+ 2, "FEN_STA", 0, 2,
+ 2, "FET_OPT", 0, 41,
+ 2, "FEM_QT", 0, 42
+ },
+
+ // MENU_PAGE_PAUSE_MENU = 52
+ { "FET_PAU", -1, -1, -1, 0, 0,
+ 92, "FEM_RES", 0, 0,
+ 2, "FEN_STA", 0, 2,
+ 2, "FEP_STA", 0, 1,
+ 2, "FEP_BRI", 0, 3,
+ 2, "FET_OPT", 0, 41,
+ 2, "FEM_QT", 0, 42,
+ },
+
+ // MENU_PAGE_CHOOSE_MODE = 53
+ { "FEN_STA", -1, -1, -1, 0, 0,
+
+ },
+
+ // MENU_PAGE_SKIN_SELECT = 54
+ { "FET_PSU", 41, 41, 41, 4, 4,
+ 35, "FEDS_TB", 0, 21,
+ },
+
+ // MENU_PAGE_KEYBOARD_CONTROLS = 55
+ { "FET_STI", 35, 35, 35, 1, 1,
+ 35, "FEDS_TB", 0, 35,
+ },
+
+ // MENU_PAGE_MOUSE_CONTROLS = 56
+ { "FET_MTI", 35, 35, 35, 2, 2,
+ 84, "FEC_MSH", 0, 35,
+ 81, "FEC_IVV", 0, 35,
+ 102, "FET_MST", 0, 35,
+ 2 , "FEDS_TB", 0, 0,
+ },
+
+ // MENU_PAGE_57 = 57
+ { "", -1, -1, -1, 0, 0,
+
+ },
+
+ // MENU_PAGE_58 = 58
+ { "", -1, -1, -1, 0, 0,
+
+ },
+};
+
+char *FrontendFilenames[] = {
+ "fe2_mainpanel_ul",
+ "fe2_mainpanel_ur",
+ "fe2_mainpanel_dl",
+ "fe2_mainpanel_dr",
+ "fe2_mainpanel_dr2",
+ "fe2_tabactive",
+ "fe_iconbrief",
+ "fe_iconstats",
+ "fe_iconcontrols",
+ "fe_iconsave",
+ "fe_iconaudio",
+ "fe_icondisplay",
+ "fe_iconlanguage",
+ "fe_controller",
+ "fe_controllersh",
+ "fe_arrows1",
+ "fe_arrows2",
+ "fe_arrows3",
+ "fe_arrows4",
+ "fe_radio1", // HEAD_RADIO
+ "fe_radio2", // DOUBLE_CLEF
+ "fe_radio5", // JAH_RADIO
+ "fe_radio7", // RISE_FM
+ "fe_radio8", // LIPS_106
+ "fe_radio3", // GAME_FM
+ "fe_radio4", // MSX_FM
+ "fe_radio6", // FLASHBACK
+ "fe_radio9", // CHATTERBOX
+};
+
+char *MenuFilenames[] = {
+ "connection24", "",
+ "findgame24", "",
+ "hostgame24", "",
+ "mainmenu24", "",
+ "Playersetup24", "",
+ "singleplayer24", "",
+ "multiplayer24", "",
+ "dmalogo128", "dmalogo128m",
+ "gtaLogo128", "gtaLogo128",
+ "rockstarLogo128", "rockstarlogo128m",
+ "gamespy256", "gamespy256a",
+ "mouse", "mousetimera",
+ "mousetimer", "mousetimera",
+ "mp3logo", "mp3logoA",
+ "downOFF", "buttonA",
+ "downON", "buttonA",
+ "upOFF", "buttonA",
+ "upON", "buttonA",
+ "gta3logo256", "gta3logo256m",
+ nil, nil
+};
+
+#if 1
+WRAPPER void CMenuManager::BuildStatLine(char *, void *, uint16, void *) { EAXJMP(0x483870); }
+#else
+void CMenuManager::BuildStatLine(char *, void *, uint16, void *)
+{
+
+}
+#endif
+
+#if 0
+WRAPPER void CMenuManager::CentreMousePointer() { EAXJMP(0x48ACE0); }
+#else
+void CMenuManager::CentreMousePointer()
+{
+ tagPOINT Point;
+
+ if (SCREENW * 0.5f == 0.0f && 0.0f == SCREENH * 0.5f) {
+ Point.x = SCREEN_WIDTH / 2;
+ Point.y = SCREEN_HEIGHT / 2;
+ ClientToScreen(PSGLOBAL(window), &Point);
+ SetCursorPos(Point.x, Point.y);
+
+ PSGLOBAL(lastMousePos.x) = SCREEN_WIDTH / 2;
+ PSGLOBAL(lastMousePos.y) = SCREEN_HEIGHT / 2;
+ }
+}
+#endif
+
+#if 1
+WRAPPER void CMenuManager::CheckCodesForControls(int, int) { EAXJMP(0x48A950); }
+#else
+void CMenuManager::CheckCodesForControls()
+{
+
+}
+#endif
+
+#if 0
+WRAPPER bool CMenuManager::CheckHover(int, int, int, int) { EAXJMP(0x48ACA0); }
+#else
+bool CMenuManager::CheckHover(int x1, int x2, int y1, int y2)
+{
+ return m_nMousePosX > x1 && m_nMousePosX < x2 &&
+ m_nMousePosY > y1 && m_nMousePosY < y2;
+}
+#endif
+
+#if 1
+WRAPPER int CMenuManager::CostructStatLine(int) { EAXJMP(0x482800); }
+#else
+int CMenuManager::CostructStatLine(int)
+{
+
+}
+#endif
+
+#if 0
+WRAPPER void CMenuManager::DisplayHelperText() { EAXJMP(0x48B490); }
+#else
+void CMenuManager::DisplayHelperText()
+{
+ wchar *str = nil;
+ switch (m_nHelperTextMsgId) {
+ case 0:
+ str = TheText.Get("FET_MIG");
+ break;
+ case 1:
+ str = TheText.Get("FET_APP");
+ break;
+ case 2:
+ str = TheText.Get("FET_HRD");
+ break;
+ case 3:
+ str = TheText.Get("FET_RSO");
+ break;
+ case 4:
+ str = TheText.Get("FET_RSC");
+ break;
+ default:
+ break;
+ };
+
+ CFont::SetAlignment(ALIGN_CENTER);
+ CFont::SetScale(SCREEN_SCALE_X(0.4f), SCREEN_SCALE_Y(0.6f));
+ CFont::SetFontStyle(FONT_HEADING);
+ CFont::SetDropColor(CRGBA(0, 0, 0, DROP_COLOR_A));
+ CFont::SetDropShadowPosition(DROP_COLOR_SIZE);
+
+ CFont::SetColor(CRGBA(255, 255, 255, 255));
+ CFont::PrintString(SCREEN_WIDTH / 2, SCREEN_SCALE_FROM_BOTTOM(120.0f), str);
+}
+#endif
+
+#if 0
+WRAPPER float CMenuManager::DisplaySlider(float, float, float, float, float, float) { EAXJMP(0x488420); }
+#else
+float CMenuManager::DisplaySlider(float x, float y, float leftSize, float rightSize, float rectSize, float progress)
+{
+ CRGBA color;
+ float sizeRange;
+
+ float input = 0.0f;
+ for (int i = 0; i < 16; i++) {
+ input = i * rectSize/16.0f + x;
+
+ if (i/16.0f + 1/32.0f < progress)
+ color = CRGBA(255, 217, 106, FadeIn(255));
+ else
+ color = CRGBA(185, 120, 0, FadeIn(255));
+
+ sizeRange = max(leftSize, rightSize);
+
+ float _x = i * rectSize/16.0f + x;
+ float _y = y + sizeRange - ((16 - i) * leftSize + i * rightSize)/16.0f;
+ float _w = SCREEN_SCALE_X(10.0f) + i * rectSize/16.0f + x;
+ float _h = y + sizeRange;
+ float _s = SCREEN_SCALE_X(2.0f);
+ CSprite2d::DrawRect(CRect(_x + _s, _y + _s, _w + _s, _h + _s), CRGBA(0, 0, 0, FadeIn(255))); // Shadow
+ CSprite2d::DrawRect(CRect(i * rectSize/16.0f + x, y + sizeRange - ((16 - i) * leftSize + i * rightSize)/16.0f, SCREEN_SCALE_X(10.0f) + i * rectSize/16.0f + x, y + sizeRange), color);
+ };
+ return input;
+}
+#endif
+
+#if 1
+WRAPPER void CMenuManager::DoSettingsBeforeStartingAGame() { EAXJMP(0x48AB40); }
+#else
+WRAPPER void CMenuManager::DoSettingsBeforeStartingAGame()
+{
+
+}
+#endif
+
+#if 0
+WRAPPER void CMenuManager::Draw() { EAXJMP(0x47AE00); }
+#else
+void CMenuManager::Draw()
+{
+ CFont::SetBackgroundOff();
+ CFont::SetPropOn();
+ CFont::SetCentreOff();
+ CFont::SetJustifyOn();
+ CFont::SetBackGroundOnlyTextOn();
+ CFont::SetWrapx(SCREEN_SCALE_FROM_RIGHT(40.0f));
+ CFont::SetRightJustifyWrap(0.0f);
+ CFont::SetDropColor(CRGBA(0, 0, 0, FadeIn(DROP_COLOR_A)));
+
+ switch (m_nCurrScreen) {
+ case MENU_STATS:
+ PrintStats();
+ break;
+ case MENU_BRIEFS:
+ PrintBriefs();
+ break;
+ case MENU_CONTROLLER_DEBUG:
+ DrawControllerScreenExtraText(0, 350, 20);
+ break;
+ }
+
+ // Header.
+ if (aScreens[m_nCurrScreen].m_ScreenName[0]) {
+ CFont::SetDropShadowPosition(0);
+ CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255)));
+ CFont::SetRightJustifyOn();
+ CFont::SetFontStyle(FONT_HEADING);
+ CFont::SetScale(SCREEN_SCALE_X(HEADER_WIDTH), SCREEN_SCALE_Y(HEADER_HEIGHT));
+ CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(HEADER_POS_X), SCREEN_SCALE_FROM_BOTTOM(HEADER_POS_Y), TheText.Get(aScreens[m_nCurrScreen].m_ScreenName));
+ }
+
+ // Action text.
+ wchar *str;
+ if (aScreens[m_nCurrScreen].m_aEntries[0].m_Action == 1) {
+ switch (m_nCurrScreen) {
+ case MENU_LOAD_SLOT_CONFIRM:
+ if (m_bGameNotLoaded)
+ str = TheText.Get("FES_LCG");
+ else
+ str = TheText.Get(aScreens[m_nCurrScreen].m_aEntries[0].m_EntryName);
+ break;
+ case MENU_SAVE_OVERWRITE_CONFIRM:
+ if (Slots[m_nCurrSaveSlot] == 1)
+ str = TheText.Get("FESZ_QZ");
+ else
+ str = TheText.Get(aScreens[m_nCurrScreen].m_aEntries[0].m_EntryName);
+ break;
+ case MENU_EXIT:
+ if (m_bGameNotLoaded)
+ str = TheText.Get("FEQ_SRW");
+ else
+ str = TheText.Get(aScreens[m_nCurrScreen].m_aEntries[0].m_EntryName);
+ break;
+ default:
+ str = TheText.Get(aScreens[m_nCurrScreen].m_aEntries[0].m_EntryName);
+ break;
+ };
+
+ CFont::SetDropShadowPosition(DROP_COLOR_SIZE);
+ CFont::SetDropColor(CRGBA(0, 0, 0, FadeIn(DROP_COLOR_A)));
+ CFont::SetFontStyle(FONT_BANK);
+ CFont::SetScale(SCREEN_SCALE_X(ACTION_WIDTH), SCREEN_SCALE_Y(ACTION_HEIGHT));
+ CFont::SetAlignment(ALIGN_LEFT);
+ CFont::SetColor(CRGBA(235, 170, 50, FadeIn(255)));
+ CFont::PrintString(SCREEN_SCALE_X(ACTION_POS_X), SCREEN_SCALE_Y(ACTION_POS_Y), str);
+ }
+
+ for (int i = 0; i < 18; ++i) {
+ if (aScreens[m_nCurrScreen].m_aEntries[i].m_Action != MENUACTION_LABEL && aScreens[m_nCurrScreen].m_aEntries[i].m_EntryName[0]) {
+ wchar *columnToPrint[COLUMNS] = { nil, nil };
+
+ if (aScreens[m_nCurrScreen].m_aEntries[i].m_ActionSlot >= MENU_ACTION_SAVE_1 && aScreens[m_nCurrScreen].m_aEntries[i].m_ActionSlot <= MENU_ACTION_SAVE_8) {
+ columnToPrint[L] = GetNameOfSavedGame(i - 1);
+ columnToPrint[R] = GetSavedGameDateAndTime(i - 1);
+
+ if (!columnToPrint[L][0]) {
+ sprintf(gString, "FEM_SL%d", i);
+ columnToPrint[L] = TheText.Get(gString);
+ }
+ }
+ else {
+ columnToPrint[L] = TheText.Get(aScreens[m_nCurrScreen].m_aEntries[i].m_EntryName);
+ }
+
+ switch (aScreens[m_nCurrScreen].m_aEntries[i].m_Action) {
+ case MENUACTION_CTRLVIBRATION:
+ break;
+ case MENUACTION_CTRLCONFIG:
+ switch (CPad::GetPad(0)->Mode) {
+ case 0:
+ columnToPrint[R] = TheText.Get("FEC_CF1");
+ break;
+ case 1:
+ columnToPrint[R] = TheText.Get("FEC_CF2");
+ break;
+ case 2:
+ columnToPrint[R] = TheText.Get("FEC_CF3");
+ break;
+ case 3:
+ columnToPrint[R] = TheText.Get("FEC_CF4");
+ break;
+ };
+ break;
+ case MENUACTION_CTRLDISPLAY:
+ break;
+ case MENUACTION_FRAMESYNC:
+ columnToPrint[R] = TheText.Get(m_PrefsVsyncDisp ? "FEM_ON" : "FEM_OFF");
+ break;
+ case MENUACTION_FRAMELIMIT:
+ columnToPrint[R] = TheText.Get(m_PrefsFrameLimiter ? "FEM_ON" : "FEM_OFF");
+ break;
+ case MENUACTION_TRAILS:
+ columnToPrint[R] = TheText.Get(BlurOn ? "FEM_ON" : "FEM_OFF");
+ break;
+ case MENUACTION_SUBTITLES:
+ columnToPrint[R] = TheText.Get(m_PrefsShowSubtitles ? "FEM_ON" : "FEM_OFF");
+ break;
+ case MENUACTION_WIDESCREEN:
+ columnToPrint[R] = TheText.Get(m_PrefsUseWideScreen ? "FEM_ON" : "FEM_OFF");
+ break;
+ case MENUACTION_RADIO:
+ sprintf(gString, "FEA_FM%d", m_PrefsRadioStation);
+ columnToPrint[R] = TheText.Get(gString);
+ break;
+ case MENUACTION_SETDBGFLAG:
+ columnToPrint[R] = TheText.Get(CTheScripts::DbgFlag ? "FEM_ON" : "FEM_OFF");
+ break;
+ case MENUACTION_SWITCHBIGWHITEDEBUGLIGHT:
+ columnToPrint[R] = TheText.Get(CTheScripts::DbgFlag ? "FEM_ON" : "FEM_OFF");
+ break;
+ case MENUACTION_INVVERT:
+ columnToPrint[R] = TheText.Get(MousePointerStateHelper.bInvertVertically ? "FEM_ON" : "FEM_OFF");
+ break;
+ case MENUACTION_SCREENRES:
+ {
+ char *res = _psGetVideoModeList()[m_nDisplayVideoMode];
+
+ if (!res)
+ res = "";
+
+ AsciiToUnicode(res, gUString);
+ columnToPrint[R] = gUString;
+ }
+ break;
+ case MENUACTION_AUDIOHW:
+ if (FrontEndMenuManager.m_nPrefsAudio3DProviderIndex == -1)
+ columnToPrint[R] = TheText.Get("FEA_NAH");
+ else {
+ char *provider = MusicManager.Get3DProviderName(FrontEndMenuManager.m_nPrefsAudio3DProviderIndex);
+ AsciiToUnicode(provider, gUString);
+ columnToPrint[R] = gUString;
+ }
+ break;
+ case MENUACTION_SPEAKERCONF:
+ if (FrontEndMenuManager.m_nPrefsAudio3DProviderIndex == -1)
+ columnToPrint[R] = TheText.Get("FEA_NAH");
+ else {
+ switch (m_PrefsSpeakers) {
+ case 0:
+ columnToPrint[R] = TheText.Get("FEA_2SP");
+ break;
+ case 1:
+ columnToPrint[R] = TheText.Get("FEA_EAR");
+ break;
+ case 2:
+ columnToPrint[R] = TheText.Get("FEA_4SP");
+ break;
+ };
+ }
+ break;
+ case MENUACTION_CTRLMETHOD:
+ switch (m_ControlMethod) {
+ case 0:
+ columnToPrint[L] = TheText.Get("FET_SCN");
+ break;
+ case 1:
+ columnToPrint[L] = TheText.Get("FET_CCN");
+ break;
+ };
+ break;
+ case MENUACTION_DYNAMICACOUSTIC:
+ columnToPrint[R] = TheText.Get(m_PrefsDMA ? "FEM_ON" : "FEM_OFF");
+ break;
+ case MENUACTION_MOUSESTEER:
+ columnToPrint[R] = TheText.Get(m_bDisableMouseSteering ? "FEM_ON" : "FEM_OFF");
+ break;
+ };
+
+ CFont::SetDropShadowPosition(DROP_COLOR_SIZE);
+ CFont::SetDropColor(CRGBA(0, 0, 0, FadeIn(DROP_COLOR_A)));
+ CFont::SetCentreSize(SCREEN_WIDTH);
+ CFont::SetWrapx(SCREEN_WIDTH);
+ CFont::SetRightJustifyWrap(-SCREEN_WIDTH);
+
+ // Set alignment.
+ CVector2D vecPositions = { 0.0f, 0.0f };
+ float fVerticalSpacing;
+ float fBarSize;
+
+ int SavePageSlot =
+ m_nCurrScreen == MENU_CHOOSE_LOAD_SLOT ||
+ m_nCurrScreen == MENU_CHOOSE_DELETE_SLOT ||
+ m_nCurrScreen == MENU_CHOOSE_SAVE_SLOT;
+
+ if (SavePageSlot) {
+ CFont::SetFontStyle(FONT_BANK);
+ CFont::SetAlignment(ALIGN_LEFT);
+ CFont::SetScale(SCREEN_SCALE_X(0.45f), SCREEN_SCALE_Y(0.7f));
+ fVerticalSpacing = COLUMN_SPACING_MIN;
+ fBarSize = SELECT_BOX_MIN;
+
+ vecPositions.x = SCREEN_SCALE_X(COLUMN_SAVE_X);
+ vecPositions.y = (SCREEN_HEIGHT / 2) - SCREEN_SCALE_Y(COLUMN_SAVE_Y);
+ }
+ else {
+ CFont::SetFontStyle(FONT_HEADING);
+
+ int LeftColumn =
+ m_nCurrScreen == MENU_SOUND_SETTINGS ||
+ m_nCurrScreen == MENU_GRAPHICS_SETTINGS ||
+ m_nCurrScreen == MENU_MOUSE_CONTROLS;
+
+ if (LeftColumn) {
+ CFont::SetAlignment(ALIGN_LEFT);
+ CFont::SetScale(SCREEN_SCALE_X(0.55f), SCREEN_SCALE_Y(0.8f));
+ fVerticalSpacing = COLUMN_SPACING_MIN;
+ fBarSize = SELECT_BOX_MIN;
+ }
+ else {
+ CFont::SetAlignment(ALIGN_CENTER);
+ CFont::SetScale(SCREEN_SCALE_X(0.75f), SCREEN_SCALE_Y(0.9f));
+ fVerticalSpacing = COLUMN_SPACING_MAX;
+ fBarSize = SELECT_BOX_MAX;
+ }
+
+ // Set positions.
+ if (CFont::GetDetails().centre)
+ vecPositions.x = SCREEN_WIDTH / 2;
+ else
+ vecPositions.x = SCREEN_SCALE_X(COLUMN_POS_X);
+
+ switch (m_nCurrScreen) {
+ case MENU_BRIEFS:
+ case MENU_STATS:
+ vecPositions.y = SCREEN_SCALE_FROM_BOTTOM(COLUMN_FEDS);
+ break;
+ case MENU_SOUND_SETTINGS:
+ vecPositions.y = (SCREEN_HEIGHT / 2) - SCREEN_SCALE_Y(COLUMN_MAX_Y);
+
+ if (i > 5)
+ vecPositions.y += SCREEN_SCALE_Y(FE_RADIO_ICON_H * 1.16f);
+ break;
+ case MENU_LANGUAGE_SETTINGS:
+ vecPositions.y = (SCREEN_HEIGHT / 2) - SCREEN_SCALE_Y(COLUMN_MIN_Y);
+ break;
+ case MENU_GRAPHICS_SETTINGS:
+ vecPositions.y = (SCREEN_HEIGHT / 2) - SCREEN_SCALE_Y(COLUMN_MAX_Y);
+ break;
+ case MENU_OPTIONS:
+ vecPositions.y = (SCREEN_HEIGHT / 2) - SCREEN_SCALE_Y(COLUMN_MID_Y);
+ break;
+ case MENU_PAUSE_MENU:
+ vecPositions.y = (SCREEN_HEIGHT / 2) - SCREEN_SCALE_Y(COLUMN_PAUSE_Y);
+ break;
+ case MENU_NEW_GAME:
+ vecPositions.y = (SCREEN_HEIGHT / 2) - SCREEN_SCALE_Y(COLUMN_MID_Y);
+ break;
+ case MENU_START_MENU:
+ vecPositions.y = (SCREEN_HEIGHT / 2) - SCREEN_SCALE_Y(COLUMN_START_Y);
+ break;
+ default:
+ vecPositions.y = (SCREEN_HEIGHT / 2) - SCREEN_SCALE_Y(COLUMN_MID_Y);
+ break;
+ };
+ }
+
+ if (i > 0)
+ vecPositions.y += SCREEN_SCALE_Y(fVerticalSpacing * i);
+
+ // Set color and draw selection bar.
+ if (i == m_nCurrOption && m_nMenuFadeAlpha >= 255) {
+ CFont::SetColor(CRGBA(255, 217, 106, FadeIn(255)));
+ CSprite2d::DrawRect(CRect(SCREEN_STRETCH_X(11.0f), vecPositions.y - SCREEN_STRETCH_Y(fBarSize * 0.13f), SCREEN_STRETCH_FROM_RIGHT(11.0f), vecPositions.y + SCREEN_STRETCH_Y(fBarSize)), CRGBA(100, 200, 50, 50));
+ }
+ else
+ CFont::SetColor(CRGBA(235, 170, 50, FadeIn(255)));
+
+ // Draw
+ if (columnToPrint[L])
+ CFont::PrintString(vecPositions.x, vecPositions.y, columnToPrint[L]);
+
+ if (columnToPrint[R]) {
+ CFont::SetAlignment(ALIGN_RIGHT);
+ CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(SavePageSlot ? COLUMN_SAVE_X : COLUMN_POS_X), vecPositions.y, columnToPrint[R]);
+ }
+
+ // Mouse support.
+ bool bIsMouseInPosition = false;
+ if (m_nMenuFadeAlpha >= 255) {
+ CVector2D vecInputSize = { SCREEN_SCALE_X(20.0f), SCREEN_SCALE_FROM_RIGHT(20.0f) };
+ if (m_bShowMouse &&
+ ((CheckHover(vecInputSize.x, vecInputSize.y, vecPositions.y, vecPositions.y + SCREEN_STRETCH_Y(20.0f)))))
+ bIsMouseInPosition = true;
+ else
+ bIsMouseInPosition = false;
+
+ if (bIsMouseInPosition) {
+ if (m_nCurrOption != i) {
+ m_nCurrOption = i;
+ DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_DENIED, 0);
+ }
+
+ m_nCurrentInput = m_nCurrOption;
+
+ if (CPad::GetPad(0)->NewMouseControllerState.LMB && !CPad::GetPad(0)->OldMouseControllerState.LMB)
+ m_nHoverOption = IGNORE_OPTION;
+ else
+ m_nHoverOption = ACTIVATE_OPTION;
+ }
+ }
+
+ // Sliders
+ // TODO: CheckHover
+ switch (aScreens[m_nCurrScreen].m_aEntries[i].m_Action) {
+ case MENUACTION_BRIGHTNESS:
+ DisplaySlider(SCREEN_SCALE_FROM_RIGHT(SLIDER_X), vecPositions.y - SCREEN_SCALE_Y(3.0f), SCREEN_SCALE_Y(2.0f), SCREEN_SCALE_Y(18.0f), SCREEN_SCALE_X(256.0f), m_PrefsBrightness/512.0f);
+ break;
+ case MENUACTION_DRAWDIST:
+ DisplaySlider(SCREEN_SCALE_FROM_RIGHT(SLIDER_X), vecPositions.y - SCREEN_SCALE_Y(3.0f), SCREEN_SCALE_Y(2.0f), SCREEN_SCALE_Y(18.0f), SCREEN_SCALE_X(256.0f), (m_PrefsLOD - 0.8f) * 1.0f);
+ break;
+ case MENUACTION_MUSICVOLUME:
+ DisplaySlider(SCREEN_SCALE_FROM_RIGHT(SLIDER_X), vecPositions.y - SCREEN_SCALE_Y(3.0f), SCREEN_SCALE_Y(2.0f), SCREEN_SCALE_Y(18.0f), SCREEN_SCALE_X(256.0f), m_PrefsMusicVolume/128.0f);
+ break;
+ case MENUACTION_SFXVOLUME:
+ DisplaySlider(SCREEN_SCALE_FROM_RIGHT(SLIDER_X), vecPositions.y - SCREEN_SCALE_Y(3.0f), SCREEN_SCALE_Y(2.0f), SCREEN_SCALE_Y(18.0f), SCREEN_SCALE_X(256.0f), m_PrefsSfxVolume/128.0f);
+ break;
+ case MENUACTION_MOUSESENS:
+ DisplaySlider(SCREEN_SCALE_FROM_RIGHT(SLIDER_X), vecPositions.y - SCREEN_SCALE_Y(3.0f), SCREEN_SCALE_Y(2.0f), SCREEN_SCALE_Y(18.0f), SCREEN_SCALE_X(256.0f), TheCamera.m_fMouseAccelHorzntl * 200.0f);
+ break;
+ };
+
+ // Radio icons.
+ float fIconSpacing = 59.52f;
+ if (m_nCurrScreen == MENU_SOUND_SETTINGS) {
+ for (int i = 0; i < POLICE_RADIO; i++) {
+
+ if (i == MSX_FM)
+ fIconSpacing -= 1.5f;
+
+ if (i < USERTRACK)
+ m_aFrontEndSprites[i + FE_RADIO1].Draw(SCREEN_STRETCH_X(FE_RADIO_ICON_X + fIconSpacing * i), (SCREEN_HEIGHT / 2) - SCREEN_SCALE_Y(FE_RADIO_ICON_Y), SCREEN_SCALE_X(FE_RADIO_ICON_W), SCREEN_SCALE_Y(FE_RADIO_ICON_H), i == m_PrefsRadioStation ? CRGBA(255, 255, 255, 255) : CRGBA(225, 0, 0, 170));
+ if (i > CHATTERBOX)
+ m_aMenuSprites[MENU_MP3LOGO].Draw(SCREEN_STRETCH_X(FE_RADIO_ICON_X + fIconSpacing * i), (SCREEN_HEIGHT / 2) - SCREEN_SCALE_Y(FE_RADIO_ICON_Y), SCREEN_SCALE_X(FE_RADIO_ICON_W), SCREEN_SCALE_Y(FE_RADIO_ICON_H), i == m_PrefsRadioStation ? CRGBA(255, 255, 255, 255) : CRGBA(225, 0, 0, DMAudio.IsMP3RadioChannelAvailable() ? 170 : 25));
+ }
+ }
+
+ // Helpers
+ if (!strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FED_RES")) {
+ if (m_nDisplayVideoMode == m_nPrefsVideoMode) {
+ if (m_nHelperTextMsgId == 1)
+ ResetHelperText();
+ }
+ else
+ SetHelperText(1);
+ }
+ else {
+ if (m_nDisplayVideoMode != m_nPrefsVideoMode) {
+ m_nDisplayVideoMode = m_nPrefsVideoMode;
+ SetHelperText(3);
+ }
+ }
+
+ switch (m_nCurrScreen) {
+ case MENU_CONTROLLER_SETTINGS:
+ case MENU_SOUND_SETTINGS:
+ case MENU_GRAPHICS_SETTINGS:
+ case MENU_SKIN_SELECT:
+ case MENU_CONTROLLER_PC:
+ case MENU_MOUSE_CONTROLS:
+ DisplayHelperText();
+ break;
+ };
+ }
+ };
+}
+#endif
+
+#if 1
+WRAPPER void CMenuManager::DrawControllerBound(int, int, int, uint8) { EAXJMP(0x489710); }
+#else
+void CMenuManager::DrawControllerBound(int, int, int, uint8)
+{
+
+}
+#endif
+
+#if 1
+WRAPPER void CMenuManager::DrawControllerScreenExtraText(int, int, int) { EAXJMP(0x4892F0); }
+#else
+void CMenuManager::DrawControllerScreenExtraText(int, int, int)
+{
+
+}
+#endif
+
+#if 1
+WRAPPER void CMenuManager::DrawControllerSetupScreen() { EAXJMP(0x481210); }
+#else
+void CMenuManager::DrawControllerSetupScreen()
+{
+
+}
+#endif
+
+#if 0
WRAPPER void CMenuManager::DrawFrontEnd(void) { EAXJMP(0x47A540); }
-WRAPPER void CMenuManager::UnloadTextures(void) { EAXJMP(0x47A440); }
-WRAPPER void CMenuManager::LoadAllTextures(void) { EAXJMP(0x47A230); }
-WRAPPER void CMenuManager::LoadSettings(void) { EAXJMP(0x488EE0); }
-WRAPPER void CMenuManager::WaitForUserCD(void) { EAXJMP(0x48ADD0); }
+#else
+void CMenuManager::DrawFrontEnd()
+{
+ CFont::SetAlphaFade(255.0f);
+
+ if (m_nCurrScreen == MENU_NONE) {
+ if (m_bGameNotLoaded)
+ m_nCurrScreen = MENU_START_MENU;
+ else
+ m_nCurrScreen = MENU_PAUSE_MENU;
+ }
+
+ if (!m_nCurrOption && aScreens[m_nCurrScreen].m_aEntries[0].m_Action == MENUACTION_LABEL)
+ m_nCurrOption = 1;
+
+ CMenuManager::DrawFrontEndNormal();
+ CMenuManager::PrintErrorMessage();
+}
+#endif
+
+#if 0
+WRAPPER void CMenuManager::DrawFrontEndNormal(void) { EAXJMP(0x47A5B0); }
+#else
+void CMenuManager::DrawFrontEndNormal()
+{
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void *)TRUE);
+ RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERLINEAR);
+ RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void *)FALSE);
+ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void *)FALSE);
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDINVSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATETEXTUREADDRESS, (void *)rwTEXTUREADDRESSCLAMP);
+
+ CSprite2d::InitPerFrame();
+ CFont::InitPerFrame();
-int CMenuManager::FadeIn(int alpha) {
+ eMenuSprites currentSprite = MENU_MAINMENU;
+ switch (m_nPrevScreen) {
+ case MENU_STATS:
+ case MENU_START_MENU:
+ case MENU_PAUSE_MENU:
+ currentSprite = MENU_MAINMENU;
+ break;
+ case MENU_NEW_GAME:
+ case MENU_CHOOSE_LOAD_SLOT:
+ case MENU_CHOOSE_DELETE_SLOT:
+ case MENU_NEW_GAME_RELOAD:
+ case MENU_LOAD_SLOT_CONFIRM:
+ case MENU_DELETE_SLOT_CONFIRM:
+ case MENU_EXIT:
+ currentSprite = MENU_SINGLEPLAYER;
+ break;
+ case MENU_MULTIPLAYER_MAIN:
+ currentSprite = MENU_MULTIPLAYER;
+ break;
+ case MENU_MULTIPLAYER_MAP:
+ case MENU_MULTIPLAYER_FIND_GAME:
+ case MENU_SKIN_SELECT:
+ case MENU_KEYBOARD_CONTROLS:
+ case MENU_MOUSE_CONTROLS:
+ currentSprite = MENU_FINDGAME;
+ break;
+ case MENU_MULTIPLAYER_CONNECTION:
+ case MENU_MULTIPLAYER_MODE:
+ currentSprite = MENU_CONNECTION;
+ break;
+ case MENU_MULTIPLAYER_CREATE:
+ currentSprite = MENU_HOSTGAME;
+ break;
+ case MENU_SKIN_SELECT_OLD:
+ case MENU_OPTIONS:
+ currentSprite = MENU_PLAYERSET;
+ break;
+ };
+
+ //CSprite2d::DrawRect(CRect(0.0f, 0.0f, SCREENW, SCREENH), CRGBA(0, 0, 0, 255));
+
+ uint32 savedShade;
+ uint32 savedAlpha;
+ RwRenderStateGet(rwRENDERSTATESHADEMODE, &savedShade);
+ RwRenderStateSet(rwRENDERSTATESHADEMODE, reinterpret_cast<void *>(rwSHADEMODEGOURAUD));
+ RwRenderStateGet(rwRENDERSTATEVERTEXALPHAENABLE, &savedAlpha);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, reinterpret_cast<void *>(TRUE));
+ if (m_nMenuFadeAlpha >= 255)
+ m_aMenuSprites[currentSprite].Draw(CRect(0.0f, 0.0f, SCREENW, SCREENH), CRGBA(255, 255, 255, 255));
+ else {
+ if (m_nMenuFadeAlpha != 255)
+ m_nMenuFadeAlpha += 0.1f * 255.0f;
+
+ m_aMenuSprites[currentSprite].Draw(CRect(0.0f, 0.0f, SCREENW, SCREENH), CRGBA(255, 255, 255, m_nMenuFadeAlpha));
+ }
+
+ // GTA LOGO
+ if (m_nCurrScreen == MENU_START_MENU || m_nCurrScreen == MENU_PAUSE_MENU) {
+ if (CGame::frenchGame || CGame::germanGame || !CGame::nastyGame)
+ m_aMenuSprites[MENU_GTA3LOGO].Draw(CRect((SCREEN_WIDTH / 2) - SCREEN_SCALE_X(115.0f), SCREEN_SCALE_Y(70.0f), (SCREEN_WIDTH / 2) + SCREEN_SCALE_X(115.0f), SCREEN_SCALE_Y(180.0f)), CRGBA(255, 255, 255, FadeIn(255)));
+ else
+ m_aMenuSprites[MENU_GTALOGO].Draw(CRect((SCREEN_WIDTH / 2) - SCREEN_SCALE_X(95.0f), SCREEN_SCALE_Y(40.0f), (SCREEN_WIDTH / 2) + SCREEN_SCALE_X(95.0f), SCREEN_SCALE_Y(210.0f)), CRGBA(255, 255, 255, FadeIn(255)));
+ }
+ RwRenderStateSet(rwRENDERSTATESHADEMODE, reinterpret_cast<void *>(savedShade));
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, reinterpret_cast<void *>(savedAlpha));
+
+ switch (m_nCurrScreen) {
+ case MENU_SKIN_SELECT:
+ CMenuManager::DrawPlayerSetupScreen();
+ break;
+ case MENU_KEYBOARD_CONTROLS:
+ CMenuManager::DrawControllerSetupScreen();
+ break;
+ default:
+ CMenuManager::Draw();
+ break;
+ };
+
+ CFont::DrawFonts();
+
+ // Draw mouse
+ if (m_bShowMouse)
+ m_aMenuSprites[MENU_MOUSE].Draw(m_nMousePosX, m_nMousePosY, SCREEN_SCALE_X(60.0f), SCREEN_SCALE_Y(60.0f), CRGBA(255, 255, 255, 255));
+}
+#endif
+
+#if 1
+WRAPPER void CMenuManager::DrawPlayerSetupScreen() { EAXJMP(0x47F2B0); }
+#else
+void CMenuManager::DrawPlayerSetupScreen()
+{
+
+}
+#endif
+
+#if 0
+WRAPPER int CMenuManager::FadeIn(int alpha) { EAXJMP(0x48AC60); }
+#else
+int CMenuManager::FadeIn(int alpha)
+{
if (m_nCurrScreen == MENU_LOADING_IN_PROGRESS ||
m_nCurrScreen == MENU_SAVING_IN_PROGRESS ||
m_nCurrScreen == MENU_DELETING)
@@ -47,7 +1182,328 @@ int CMenuManager::FadeIn(int alpha) {
return m_nMenuFadeAlpha;
}
+#endif
+
+#if 1
+WRAPPER void CMenuManager::FilterOutColorMarkersFromString(uint16, CRGBA &) { EAXJMP(0x4889C0); }
+#else
+void CMenuManager::FilterOutColorMarkersFromString(uint16, CRGBA &)
+{
+
+}
+#endif
+
+#if 1
+WRAPPER int CMenuManager::GetStartOptionsCntrlConfigScreens() { EAXJMP(0x489270); }
+#else
+int CMenuManager::GetStartOptionsCntrlConfigScreens()
+{
+
+}
+#endif
+
+#if 1
+WRAPPER void CMenuManager::InitialiseChangedLanguageSettings() { EAXJMP(0x47A4D0); }
+#else
+void CMenuManager::InitialiseChangedLanguageSettings()
+{
+
+}
+#endif
+
+#if 0
+WRAPPER void CMenuManager::LoadAllTextures() { EAXJMP(0x47A230); }
+#else
+void CMenuManager::LoadAllTextures()
+{
+ if (!m_bSpritesLoaded) {
+ CMenuManager::CentreMousePointer();
+ DMAudio.ChangeMusicMode(0);
+ DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_STARTING, 0);
+ m_nCurrOption = 0;
+ m_PrefsRadioStation = DMAudio.GetRadioInCar();
+
+ if (DMAudio.IsMP3RadioChannelAvailable()) {
+ if (CMenuManager::m_PrefsRadioStation > USERTRACK)
+ CMenuManager::m_PrefsRadioStation = CGeneral::GetRandomNumber() % 10;
+ }
+ else if (CMenuManager::m_PrefsRadioStation > CHATTERBOX)
+ CMenuManager::m_PrefsRadioStation = CGeneral::GetRandomNumber() % 9;
+
+ CFileMgr::SetDir("");
+ CTimer::Stop();
+ CStreaming::MakeSpaceFor(716800);
+ CStreaming::ImGonnaUseStreamingMemory();
+ CTxdStore::PushCurrentTxd();
+
+ int frontend = CTxdStore::AddTxdSlot("frontend");
+ CTxdStore::LoadTxd(frontend, "MODELS/FRONTEND.TXD");
+ CTxdStore::AddRef(frontend);
+ CTxdStore::SetCurrentTxd(frontend);
+ CStreaming::IHaveUsedStreamingMemory();
+ CTimer::Update();
+
+ debug("LOAD frontend\n");
+ for (int i = 0; i < ARRAY_SIZE(FrontendFilenames); i++) {
+ m_aFrontEndSprites[i].SetTexture(FrontendFilenames[i]);
+ m_aFrontEndSprites[i].SetAddressing(rwTEXTUREADDRESSBORDER);
+ };
+
+ CTxdStore::PopCurrentTxd();
+
+ int menu = CTxdStore::AddTxdSlot("menu");
+ CTxdStore::LoadTxd(menu, "MODELS/MENU.TXD");
+ CTxdStore::AddRef(menu);
+ CTxdStore::SetCurrentTxd(menu);
+
+ debug("LOAD sprite\n");
+ for (int i = 0; i < ARRAY_SIZE(MenuFilenames)/2; i++) {
+ m_aMenuSprites[i].SetTexture(MenuFilenames[i*2], MenuFilenames[i*2+1]);
+ m_aMenuSprites[i].SetAddressing(rwTEXTUREADDRESSBORDER);
+ };
+
+ CTxdStore::PopCurrentTxd();
+
+ m_bSpritesLoaded = true;
+ }
+}
+#endif
+
+#if 1
+WRAPPER void CMenuManager::LoadSettings() { EAXJMP(0x488EE0); }
+#else
+void CMenuManager::LoadSettings()
+{
+
+}
+#endif
+
+#if 1
+WRAPPER void CMenuManager::MessageScreen(char *) { EAXJMP(0x48B7E0); }
+#else
+void CMenuManager::MessageScreen(char *)
+{
+
+}
+#endif
+
+#if 1
+WRAPPER void CMenuManager::PickNewPlayerColour() { EAXJMP(0x488C40); }
+#else
+void CMenuManager::PickNewPlayerColour()
+{
+
+}
+#endif
+
+#if 1
+WRAPPER void CMenuManager::PrintBriefs() { EAXJMP(0x484D60); }
+#else
+void CMenuManager::PrintBriefs()
+{
+
+}
+#endif
+
+#if 0
+WRAPPER void CMenuManager::PrintErrorMessage() { EAXJMP(0x484F70); }
+#else
+void CMenuManager::PrintErrorMessage()
+{
+ if (!CPad::bDisplayNoControllerMessage && !CPad::bObsoleteControllerMessage)
+ return;
+
+ CSprite2d::DrawRect(CRect(SCREEN_SCALE_X(20.0f), SCREEN_SCALE_Y(140.0f), SCREEN_WIDTH - SCREEN_SCALE_X(20.0f), SCREEN_HEIGHT - SCREEN_SCALE_Y(140.0f)), CRGBA(64, 16, 16, 224));
+ CFont::SetFontStyle(FONT_BANK);
+ CFont::SetBackgroundOff();
+ CFont::SetPropOn();
+ CFont::SetCentreOff();
+ CFont::SetJustifyOn();
+ CFont::SetRightJustifyOff();
+ CFont::SetBackGroundOnlyTextOn();
+ CFont::SetWrapx(SCREEN_WIDTH - 40.0f);
+ CFont::SetColor(CRGBA(165, 165, 165, 255));
+ CFont::SetScale(SCREEN_SCALE_X(0.9f), SCREEN_SCALE_Y(0.9f));
+ CFont::PrintString(SCREEN_SCALE_X(40.0f), (SCREEN_HEIGHT / 2) - SCREEN_SCALE_Y(60.0f), TheText.Get(CPad::bDisplayNoControllerMessage ? "NOCONT" : "WRCONT"));
+ CFont::DrawFonts();
+}
+#endif
+
+#if 1
+WRAPPER void CMenuManager::PrintStats() { EAXJMP(0x482100); }
+#else
+void CMenuManager::PrintStats()
+{
+
+}
+#endif
+
+
+#if 1
+WRAPPER void CMenuManager::Process(void) { EAXJMP(0x485100); }
+#else
+void CMenuManager::Process(void)
+{
+
+}
+#endif
+
+#if 1
+WRAPPER void CMenuManager::ProcessButtonPresses() { EAXJMP(0x4856F0); }
+#else
+void CMenuManager::ProcessButtonPresses()
+{
+
+}
+#endif
+
+#if 1
+WRAPPER void CMenuManager::ProcessOnOffMenuOptions() { EAXJMP(0x48AE60); }
+#else
+void CMenuManager::ProcessOnOffMenuOptions()
+{
+
+}
+#endif
+
+#if 0
+WRAPPER void CMenuManager::RequestFrontEndShutdown() { EAXJMP(0x488750); }
+#else
+void CMenuManager::RequestFrontEndShutdown()
+{
+ m_bShutDownFrontEndRequested = true;
+ DMAudio.ChangeMusicMode(1);
+}
+#endif
+
+#if 0
+WRAPPER void CMenuManager::RequestFrontEndStartUp() { EAXJMP(0x488770); }
+#else
+void CMenuManager::RequestFrontEndStartUp()
+{
+ m_bStartUpFrontEndRequested = 1;
+}
+#endif
+
+#if 0
+WRAPPER void CMenuManager::ResetHelperText() { EAXJMP(0x48B470); }
+#else
+void CMenuManager::ResetHelperText()
+{
+ m_nHelperTextMsgId = 0;
+ m_nHelperTextAlpha = 300;
+}
+#endif
+
+#if 1
+WRAPPER void CMenuManager::SaveLoadFileError_SetUpErrorScreen() { EAXJMP(0x488930); }
+#else
+void CMenuManager::SaveLoadFileError_SetUpErrorScreen()
+{
+
+}
+#endif
+
+#if 0
+WRAPPER void CMenuManager::SetHelperText() { EAXJMP(0x48B450); }
+#else
+void CMenuManager::SetHelperText(int text)
+{
+ m_nHelperTextMsgId = text;
+ m_nHelperTextAlpha = 300;
+}
+#endif
+
+#if 1
+WRAPPER void CMenuManager::SaveSettings() { EAXJMP(0x488CC0); }
+#else
+void CMenuManager::SaveSettings()
+{
+
+}
+#endif
+
+#if 0
+WRAPPER void CMenuManager::ShutdownJustMenu() { EAXJMP(0x488920); }
+#else
+void CMenuManager::ShutdownJustMenu()
+{
+ m_bMenuActive = false;
+ CTimer::EndUserPause();
+}
+#endif
+
+#if 0
+WRAPPER float CMenuManager::StretchX(float) { EAXJMP(0x48ABE0); }
+#else
+float CMenuManager::StretchX(float x)
+{
+ if (SCREENW == 640)
+ return x;
+ else
+ return SCREENW * x * 0.0015625f;
+}
+#endif
+
+#if 0
+WRAPPER float CMenuManager::StretchY(float) { EAXJMP(0x48AC20); }
+#else
+float CMenuManager::StretchY(float y)
+{
+ if (SCREENH == 448)
+ return y;
+ else
+ return SCREENH * y * 0.002232143f;
+}
+#endif
+
+#if 0
+WRAPPER void CMenuManager::SwitchMenuOnAndOff() { EAXJMP(0x488790); }
+#else
+void CMenuManager::SwitchMenuOnAndOff()
+{
+
+}
+#endif
+
+#if 0
+WRAPPER void CMenuManager::UnloadTextures() { EAXJMP(0x47A440); }
+#else
+void CMenuManager::UnloadTextures()
+{
+ if (m_bSpritesLoaded) {
+ debug("Remove frontend\n");
+ for (int i = 0; i < ARRAY_SIZE(FrontendFilenames); ++i)
+ m_aFrontEndSprites[i].Delete();
+
+ int frontend = CTxdStore::FindTxdSlot("frontend");
+ CTxdStore::RemoveTxdSlot(frontend);
+
+ debug("Remove menu textures\n");
+ for (int i = 0; i < ARRAY_SIZE(MenuFilenames)/2; ++i)
+ m_aMenuSprites[i].Delete();
+
+ int menu = CTxdStore::FindTxdSlot("menu");
+ CTxdStore::RemoveTxdSlot(menu);
+
+ m_bSpritesLoaded = false;
+ }
+}
+#endif
+
+#if 1
+WRAPPER void CMenuManager::WaitForUserCD(void) { EAXJMP(0x48ADD0); }
+#else
+void CMenuManager::WaitForUserCD()
+{
+
+}
+#endif
STARTPATCHES
- InjectHook(0x48AC60, &CMenuManager::FadeIn, PATCH_JUMP);
+ InjectHook(0x47A230, &CMenuManager::LoadAllTextures, PATCH_JUMP);
+ InjectHook(0x47A440, &CMenuManager::UnloadTextures, PATCH_JUMP);
+
+ for (int i = 1; i < ARRAY_SIZE(aScreens); i++)
+ Patch(0x611930 + sizeof(CMenuScreen) * i, aScreens[i]);
ENDPATCHES \ No newline at end of file
diff --git a/src/Frontend.h b/src/Frontend.h
index 2e95d582..7245477f 100644
--- a/src/Frontend.h
+++ b/src/Frontend.h
@@ -2,6 +2,43 @@
#include "Sprite2d.h"
+#define HEADER_POS_X 35.0f
+#define HEADER_POS_Y 93.0f
+#define HEADER_WIDTH 0.84f
+#define HEADER_HEIGHT 1.6f
+
+#define ACTION_POS_X 20.0f
+#define ACTION_POS_Y 37.5f
+#define ACTION_WIDTH 0.675f
+#define ACTION_HEIGHT 0.81f
+
+#define COLUMN_POS_X HEADER_POS_X + 16.0f
+#define COLUMN_MAX_Y 149.0f
+#define COLUMN_MID_Y 100.0f
+#define COLUMN_MIN_Y 110.0f
+#define COLUMN_PAUSE_Y 25.0f
+#define COLUMN_START_Y 9.0f
+#define COLUMN_FEDS 139.0f
+
+#define COLUMN_SAVE_X 121.0f
+#define COLUMN_SAVE_Y 111.0f
+
+#define COLUMN_SPACING_MAX 24.0f
+#define COLUMN_SPACING_MIN 20.0f
+
+#define SELECT_BOX_MAX 20.5f
+#define SELECT_BOX_MIN 17.0f
+
+#define FE_RADIO_ICON_X 31.5f
+#define FE_RADIO_ICON_Y 29.5f
+#define FE_RADIO_ICON_W 60.0f
+#define FE_RADIO_ICON_H 60.0f
+
+#define DROP_COLOR_A 150
+#define DROP_COLOR_SIZE -1
+
+#define SLIDER_X 306.0f
+
enum {
LANGUAGE_AMERICAN,
LANGUAGE_FRENCH,
@@ -10,6 +47,70 @@ enum {
LANGUAGE_SPANISH,
};
+enum eFrontendSprites {
+ FE2_MAINPANEL_UL,
+ FE2_MAINPANEL_UR,
+ FE2_MAINPANEL_DL,
+ FE2_MAINPANEL_DR,
+ FE2_MAINPANEL_DR2,
+ FE2_TABACTIVE,
+ FE_ICONBRIEF,
+ FE_ICONSTATS,
+ FE_ICONCONTROLS,
+ FE_ICONSAVE,
+ FE_ICONAUDIO,
+ FE_ICONDISPLAY,
+ FE_ICONLANGUAGE,
+ FE_CONTROLLER,
+ FE_CONTROLLERSH,
+ FE_ARROWS1,
+ FE_ARROWS2,
+ FE_ARROWS3,
+ FE_ARROWS4,
+ FE_RADIO1,
+ FE_RADIO2,
+ FE_RADIO3,
+ FE_RADIO4,
+ FE_RADIO5,
+ FE_RADIO6,
+ FE_RADIO7,
+ FE_RADIO8,
+ FE_RADIO9,
+};
+
+enum eMenuSprites {
+ MENU_CONNECTION,
+ MENU_FINDGAME,
+ MENU_HOSTGAME,
+ MENU_MAINMENU,
+ MENU_PLAYERSET,
+ MENU_SINGLEPLAYER,
+ MENU_MULTIPLAYER,
+ MENU_DMALOGO,
+ MENU_GTALOGO,
+ MENU_RSTARLOGO,
+ MENU_GAMESPY,
+ MENU_MOUSE,
+ MENU_MOUSET,
+ MENU_MP3LOGO,
+ MENU_DOWNOFF,
+ MENU_DOWNON,
+ MENU_UPOFF,
+ MENU_UPON,
+ MENU_GTA3LOGO,
+};
+
+enum eMenuActions {
+ MENU_ACTION_SAVE_1 = 1,
+ MENU_ACTION_SAVE_2,
+ MENU_ACTION_SAVE_3,
+ MENU_ACTION_SAVE_4,
+ MENU_ACTION_SAVE_5,
+ MENU_ACTION_SAVE_6,
+ MENU_ACTION_SAVE_7,
+ MENU_ACTION_SAVE_8,
+};
+
enum eMenuScreen {
MENU_NONE = 0,
MENU_STATS = 1,
@@ -72,6 +173,125 @@ enum eMenuScreen {
MENU_58 = 58,
};
+enum eMenuAction {
+ MENUACTION_NOTHING,
+ MENUACTION_LABEL,
+ MENUACTION_CHANGEMENU,
+ MENUACTION_CTRLVIBRATION,
+ MENUACTION_CTRLCONFIG,
+ MENUACTION_CTRLDISPLAY,
+ MENUACTION_FRAMESYNC,
+ MENUACTION_FRAMELIMIT,
+ MENUACTION_TRAILS,
+ MENUACTION_SUBTITLES,
+ MENUACTION_WIDESCREEN,
+ MENUACTION_BRIGHTNESS,
+ MENUACTION_DRAWDIST,
+ MENUACTION_MUSICVOLUME,
+ MENUACTION_SFXVOLUME,
+ MENUACTION_UNK15,
+ MENUACTION_RADIO,
+ MENUACTION_LANG_ENG,
+ MENUACTION_LANG_FRE,
+ MENUACTION_LANG_GER,
+ MENUACTION_LANG_IT,
+ MENUACTION_LANG_SPA,
+ MENUACTION_UPDATESAVE,
+ MENUACTION_CHECKSAVE,
+ MENUACTION_UNK24,
+ MENUACTION_NEWGAME,
+ MENUACTION_RELOADIDE,
+ MENUACTION_RELOADIPL,
+ MENUACTION_SETDBGFLAG,
+ MENUACTION_SWITCHBIGWHITEDEBUGLIGHT,
+ MENUACTION_PEDROADGROUPS,
+ MENUACTION_CARROADGROUPS,
+ MENUACTION_COLLISIONPOLYS,
+ MENUACTION_REGMEMCARD1,
+ MENUACTION_TESTFORMATMEMCARD1,
+ MENUACTION_TESTUNFORMATMEMCARD1,
+ MENUACTION_CREATEROOTDIR,
+ MENUACTION_CREATELOADICONS,
+ MENUACTION_FILLWITHGUFF,
+ MENUACTION_SAVEONLYTHEGAME,
+ MENUACTION_SAVEGAME,
+ MENUACTION_SAVEGAMEUNDERGTA,
+ MENUACTION_CREATECOPYPROTECTED,
+ MENUACTION_TESTSAVE,
+ MENUACTION_TESTLOAD,
+ MENUACTION_TESTDELETE,
+ MENUACTION_PARSEHEAP,
+ MENUACTION_SHOWCULL,
+ MENUACTION_MEMCARDSAVECONFIRM,
+ MENUACTION_UPDATEMEMCARDSAVE,
+ MENUACTION_UNK50,
+ MENUACTION_DEBUGSTREAM,
+ MENUACTION_MPMAP_LIBERTY,
+ MENUACTION_MPMAP_REDLIGHT,
+ MENUACTION_MPMAP_CHINATOWN,
+ MENUACTION_MPMAP_TOWER,
+ MENUACTION_MPMAP_SEWER,
+ MENUACTION_MPMAP_INDUSTPARK,
+ MENUACTION_MPMAP_DOCKS,
+ MENUACTION_MPMAP_STAUNTON,
+ MENUACTION_MPMAP_DEATHMATCH1,
+ MENUACTION_MPMAP_DEATHMATCH2,
+ MENUACTION_MPMAP_TEAMDEATH1,
+ MENUACTION_MPMAP_TEAMDEATH2,
+ MENUACTION_MPMAP_STASH,
+ MENUACTION_MPMAP_CAPTURE,
+ MENUACTION_MPMAP_RATRACE,
+ MENUACTION_MPMAP_DOMINATION,
+ MENUACTION_STARTMP,
+ MENUACTION_UNK69,
+ MENUACTION_UNK70,
+ MENUACTION_FINDMP,
+ MENUACTION_REDEFCTRL,
+ MENUACTION_UNK73,
+ MENUACTION_INITMP,
+ MENUACTION_MP_PLAYERCOLOR,
+ MENUACTION_MP_PLAYERNAME,
+ MENUACTION_MP_GAMENAME,
+ MENUACTION_GETKEY,
+ MENUACTION_SHOWHEADBOB,
+ MENUACTION_UNK80,
+ MENUACTION_INVVERT,
+ MENUACTION_CANCLEGAME,
+ MENUACTION_MP_PLAYERNUMBER,
+ MENUACTION_MOUSESENS,
+ MENUACTION_CHECKMPGAMES,
+ MENUACTION_CHECKMPPING,
+ MENUACTION_MP_SERVER,
+ MENUACTION_MP_MAP,
+ MENUACTION_MP_GAMETYPE,
+ MENUACTION_MP_LAN,
+ MENUACTION_MP_INTERNET,
+ MENUACTION_RESUME,
+ MENUACTION_DONTCANCLE,
+ MENUACTION_SCREENRES,
+ MENUACTION_AUDIOHW,
+ MENUACTION_SPEAKERCONF,
+ MENUACTION_PLAYERSETUP,
+ MENUACTION_RESTOREDEF,
+ MENUACTION_CTRLMETHOD,
+ MENUACTION_DYNAMICACOUSTIC,
+ MENUACTION_LOADRADIO,
+ MENUACTION_MOUSESTEER,
+ MENUACTION_UNK103,
+ MENUACTION_UNK104,
+ MENUACTION_UNK105,
+ MENUACTION_UNK106,
+ MENUACTION_UNK107,
+ MENUACTION_UNK108,
+ MENUACTION_UNK109,
+ MENUACTION_UNK110,
+};
+
+enum eCheckHover {
+ ACTIVATE_OPTION = 2,
+ IGNORE_OPTION = 42,
+};
+
struct tSkinInfo
{
int field_0;
@@ -81,6 +301,20 @@ struct tSkinInfo
int field_304;
};
+struct CMenuScreen {
+ char m_ScreenName[8];
+ int32 m_PreviousPage[3]; //
+ int32 m_ParentEntry[2];
+
+ struct CMenuEntry
+ {
+ int32 m_Action;
+ char m_EntryName[8];
+ int32 m_ActionSlot;
+ int32 m_TargetMenu;
+ } m_aEntries[18];
+};
+
class CMenuManager
{
public:
@@ -136,10 +370,10 @@ public:
int m_nHelperTextAlpha;
int m_nMouseOldPosX;
int m_nMouseOldPosY;
- int field_544;
+ int m_nHoverOption;
int m_nCurrScreen;
int m_nCurrOption;
- int field_550;
+ int m_nCurrentInput;
int m_nPrevScreen;
int field_558;
int m_nCurrSaveSlot;
@@ -165,17 +399,56 @@ public:
static int8 &m_bFrontEnd_ReloadObrTxtGxt;
static int32 &m_PrefsMusicVolume;
static int32 &m_PrefsSfxVolume;
+ static bool &m_bStartUpFrontEndRequested;
+ static bool &m_bShutDownFrontEndRequested;
static bool &m_PrefsAllowNastyGame;
- static bool &m_bStartUpFrontEndRequested;
- void Process(void);
- void DrawFrontEnd(void);
- void UnloadTextures(void);
- void LoadAllTextures(void);
- void LoadSettings(void);
- void WaitForUserCD(void);
+private:
+ enum eColumns { L, R, COLUMNS, };
+
+public:
+ void BuildStatLine(char *, void *, uint16, void *);
+ static void CentreMousePointer();
+ void CheckCodesForControls(int, int);
+ bool CheckHover(int x1, int x2, int y1, int y2);
+ int CostructStatLine(int);
+ void DisplayHelperText();
+ float DisplaySlider(float, float, float, float, float, float);
+ void DoSettingsBeforeStartingAGame();
+ void Draw();
+ void DrawControllerBound(int, int, int, uint8);
+ void DrawControllerScreenExtraText(int, int, int);
+ void DrawControllerSetupScreen();
+ void DrawFrontEnd();
+ void DrawFrontEndNormal();
+ void DrawPlayerSetupScreen();
int FadeIn(int alpha);
+ void FilterOutColorMarkersFromString(uint16, CRGBA &);
+ int GetStartOptionsCntrlConfigScreens();
+ static void InitialiseChangedLanguageSettings();
+ void LoadAllTextures();
+ void LoadSettings();
+ static void MessageScreen(char *);
+ static void PickNewPlayerColour();
+ void PrintBriefs();
+ static void PrintErrorMessage();
+ void PrintStats();
+ void Process();
+ void ProcessButtonPresses();
+ void ProcessOnOffMenuOptions();
+ static void RequestFrontEndShutdown();
+ static void RequestFrontEndStartUp();
+ void ResetHelperText();
+ void SaveLoadFileError_SetUpErrorScreen();
+ void SaveSettings();
+ void SetHelperText(int text);
+ void ShutdownJustMenu();
+ static float StretchX(float);
+ static float StretchY(float );
+ void SwitchMenuOnAndOff();
+ void UnloadTextures();
+ void WaitForUserCD();
};
static_assert(sizeof(CMenuManager) == 0x564, "CMenuManager: error");
diff --git a/src/PCSave.cpp b/src/PCSave.cpp
index 2d49b23f..ae5e43b0 100644
--- a/src/PCSave.cpp
+++ b/src/PCSave.cpp
@@ -4,4 +4,9 @@
#include "PCSave.h"
WRAPPER void C_PcSave::SetSaveDirectory(const char *path) { EAXJMP(0x591EA0); }
+WRAPPER wchar *GetNameOfSavedGame(int counter) { EAXJMP(0x591B60); }
+WRAPPER wchar *GetSavedGameDateAndTime(int counter) { EAXJMP(0x591B50); }
+int *Slots = (int*)0x728040;
+int *SlotFileName = (int*)0x6F07C8;
+int *SlotSaveDate = (int*)0x72B858;
diff --git a/src/PCSave.h b/src/PCSave.h
index 324a3421..79202bc9 100644
--- a/src/PCSave.h
+++ b/src/PCSave.h
@@ -4,4 +4,11 @@ class C_PcSave
{
public:
static void SetSaveDirectory(const char *path);
-}; \ No newline at end of file
+};
+
+extern wchar *GetNameOfSavedGame(int counter);
+extern wchar *GetSavedGameDateAndTime(int counter);
+
+extern int *Slots;
+extern int *SlotFileName;
+extern int *SlotSaveDate;
diff --git a/src/Radar.cpp b/src/Radar.cpp
index 90d27af2..3c2f24d3 100644
--- a/src/Radar.cpp
+++ b/src/Radar.cpp
@@ -14,8 +14,6 @@
#include "World.h"
#include "Streaming.h"
-WRAPPER void CRadar::Draw3dMarkers() { EAXJMP(0x4A4C70); }
-
float &CRadar::m_RadarRange = *(float*)0x8E281C;
CBlip *CRadar::ms_RadarTrace = (CBlip*)0x6ED5E0;
@@ -77,107 +75,69 @@ static_assert(RADAR_TILE_SIZE == (WORLD_SIZE_Y / RADAR_NUM_TILES), "CRadar: not
#define RADAR_MAX_SPEED (0.9f)
#if 0
-WRAPPER void CRadar::DrawMap () { EAXJMP(0x4A4200); }
+WRAPPER void CRadar::CalculateBlipAlpha(float) { EAXJMP(0x4A4F90); }
#else
-void CRadar::DrawMap()
+int CRadar::CalculateBlipAlpha(float dist)
{
- if (!TheCamera.m_WideScreenOn && CHud::m_Wants_To_Draw_Hud) {
- if (FindPlayerVehicle()) {
- float speed = FindPlayerSpeed().Magnitude();
- if (speed < RADAR_MIN_SPEED)
- m_RadarRange = RADAR_MIN_RANGE;
- else if (speed < RADAR_MAX_SPEED)
- m_RadarRange = (speed - RADAR_MIN_SPEED)/(RADAR_MAX_SPEED-RADAR_MIN_SPEED) * (RADAR_MAX_RANGE-RADAR_MIN_RANGE) + RADAR_MIN_RANGE;
- else
- m_RadarRange = RADAR_MAX_RANGE;
- }
- else
- m_RadarRange = RADAR_MIN_RANGE;
+ if (dist <= 1.0f)
+ return 255;
- vec2DRadarOrigin = CVector2D(FindPlayerCentreOfWorld_NoSniperShift());
- DrawRadarMap();
- }
+ if (dist <= 5.0f)
+ return (((1.0f - ((dist * 0.25f) - 0.25f)) * 255.0f) + (((dist * 0.25f) - 0.25f) * 128.0f));
+
+ return 128;
}
-#endif
+#endif
-#if 0
-WRAPPER void CRadar::DrawRadarMask() { EAXJMP(0x4A69C0); }
+#if 1
+WRAPPER void CRadar::ChangeBlipBrightness(int32, int32) { EAXJMP(0x4A57A0); }
#else
-void CRadar::DrawRadarMask()
-{
- CVector2D corners[4] = {
- CVector2D(1.0f, -1.0f),
- CVector2D(1.0f, 1.0f),
- CVector2D(-1.0f, 1.0f),
- CVector2D(-1.0, -1.0f)
- };
-
- RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void*)FALSE);
- RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
- RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
- RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE);
- RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERLINEAR);
- RwRenderStateSet(rwRENDERSTATESHADEMODE, (void*)rwSHADEMODEFLAT);
- RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE);
- RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
- RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
- RwD3D8SetRenderState(rwRENDERSTATESTENCILFUNCTION, rwSTENCILFUNCTIONALWAYS);
+void CRadar::ChangeBlipBrightness(int32 i, int32 bright)
+{
- CVector2D out[8];
- CVector2D in;
+}
+#endif
- // Draw the shape we want to mask out from the radar in four segments
- for (int i = 0; i < 4; i++) {
- // First point is always the corner itself
- in.x = corners[i].x;
- in.y = corners[i].y;
- TransformRadarPointToScreenSpace(out[0], in);
+#if 1
+WRAPPER void CRadar::ChangeBlipColour(int32) { EAXJMP(0x4A5770); }
+#else
+void CRadar::ChangeBlipColour(int32 i)
+{
- // Then generate a quarter of the circle
- for (int j = 0; j < 7; j++) {
- in.x = corners[i].x * cos(j * (PI / 2.0f / 6.0f));
- in.y = corners[i].y * sin(j * (PI / 2.0f / 6.0f));
- TransformRadarPointToScreenSpace(out[j + 1], in);
- };
+}
+#endif
- CSprite2d::SetMaskVertices(8, (float *)out);
- RwIm2DRenderPrimitive(rwPRIMTYPETRIFAN, CSprite2d::GetVertices(), 8);
- };
+#if 1
+WRAPPER void CRadar::ChangeBlipDisplay(int32, int16) { EAXJMP(0x4A5810); }
+#else
+void CRadar::ChangeBlipDisplay(int32 i, int16 flag)
+{
- RwD3D8SetRenderState(rwRENDERSTATESTENCILFUNCTION, rwSTENCILFUNCTIONGREATER);
}
#endif
-#if 0
-WRAPPER void CRadar::SetRadarMarkerState(int counter, int flag) { EAXJMP(0x4A5C60); }
+#if 1
+WRAPPER void CRadar::ChangeBlipScale(int32, int16) { EAXJMP(0x4A57E0); }
#else
-void CRadar::SetRadarMarkerState(int counter, int flag)
+void CRadar::ChangeBlipScale(int32 i, int16 scale)
{
- CEntity *e;
- switch (ms_RadarTrace[counter].m_eBlipType) {
- case BLIP_CAR:
- e = CPools::GetVehiclePool()->GetAt(ms_RadarTrace[counter].m_nEntityHandle);
- break;
- case BLIP_CHAR:
- e = CPools::GetPedPool()->GetAt(ms_RadarTrace[counter].m_nEntityHandle);
- break;
- case BLIP_OBJECT:
- e = CPools::GetObjectPool()->GetAt(ms_RadarTrace[counter].m_nEntityHandle);
- break;
- default:
- return;
- }
- if (e)
- e->bHasBlip = flag;
+}
+#endif
+
+#if 1
+WRAPPER void CRadar::ClearBlip(int32) { EAXJMP(0x4A5720); }
+#else
+void CRadar::ClearBlip(int32 i)
+{
}
#endif
#if 0
-WRAPPER void CRadar::ClearBlipForEntity(eBlipType type, int32 id) { EAXJMP(0x4A56C0); }
+WRAPPER void CRadar::ClearBlipForEntity(int16, int32) { EAXJMP(0x4A56C0); }
#else
-void CRadar::ClearBlipForEntity(eBlipType type, int32 id)
+void CRadar::ClearBlipForEntity(int16 type, int32 id)
{
for (int i = 0; i < NUMRADARBLIPS; i++) {
if (type == ms_RadarTrace[i].m_eBlipType && id == ms_RadarTrace[i].m_nEntityHandle) {
@@ -191,87 +151,6 @@ void CRadar::ClearBlipForEntity(eBlipType type, int32 id)
}
#endif
-bool
-IsPointInsideRadar(const CVector2D &point)
-{
- if(point.x < -1.0f || point.x > 1.0f) return false;
- if(point.y < -1.0f || point.y > 1.0f) return false;
- return true;
-}
-
-// clip line p1,p2 against (-1.0, 1.0) in x and y, set out to clipped point closest to p1
-int
-LineRadarBoxCollision(CVector2D &out, const CVector2D &p1, const CVector2D &p2)
-{
- float d1, d2;
- float t;
- float x, y;
- float shortest = 1.0f;
- int edge = -1;
-
- // clip against left edge, x = -1.0
- d1 = -1.0f - p1.x;
- d2 = -1.0f - p2.x;
- if(d1 * d2 < 0.0f){
- // they are on opposite sides, get point of intersection
- t = d1 / (d1 - d2);
- y = (p2.y - p1.y)*t + p1.y;
- if(y >= -1.0f && y <= 1.0f && t <= shortest){
- out.x = -1.0f;
- out.y = y;
- edge = 3;
- shortest = t;
- }
- }
-
- // clip against right edge, x = 1.0
- d1 = p1.x - 1.0f;
- d2 = p2.x - 1.0f;
- if(d1 * d2 < 0.0f){
- // they are on opposite sides, get point of intersection
- t = d1 / (d1 - d2);
- y = (p2.y - p1.y)*t + p1.y;
- if(y >= -1.0f && y <= 1.0f && t <= shortest){
- out.x = 1.0f;
- out.y = y;
- edge = 1;
- shortest = t;
- }
- }
-
- // clip against top edge, y = -1.0
- d1 = -1.0f - p1.y;
- d2 = -1.0f - p2.y;
- if(d1 * d2 < 0.0f){
- // they are on opposite sides, get point of intersection
- t = d1 / (d1 - d2);
- x = (p2.x - p1.x)*t + p1.x;
- if(x >= -1.0f && x <= 1.0f && t <= shortest){
- out.y = -1.0f;
- out.x = x;
- edge = 0;
- shortest = t;
- }
- }
-
- // clip against bottom edge, y = 1.0
- d1 = p1.y - 1.0f;
- d2 = p2.y - 1.0f;
- if(d1 * d2 < 0.0f){
- // they are on opposite sides, get point of intersection
- t = d1 / (d1 - d2);
- x = (p2.x - p1.x)*t + p1.x;
- if(x >= -1.0f && x <= 1.0f && t <= shortest){
- out.y = 1.0f;
- out.x = x;
- edge = 2;
- shortest = t;
- }
- }
-
- return edge;
-}
-
#if 0
WRAPPER int CRadar::ClipRadarPoly(CVector2D *poly, const CVector2D *in) { EAXJMP(0x4A64A0); }
#else
@@ -289,36 +168,37 @@ int CRadar::ClipRadarPoly(CVector2D *poly, const CVector2D *rect)
int laste, e, e1, e2;;
bool inside[4];
- for(i = 0; i < 4; i++)
+ for (i = 0; i < 4; i++)
inside[i] = IsPointInsideRadar(rect[i]);
laste = -1;
n = 0;
- for(i = 0; i < 4; i++)
- if(inside[i]){
+ for (i = 0; i < 4; i++)
+ if (inside[i]) {
// point is inside, just add
poly[n++] = rect[i];
- }else{
+ }
+ else {
// point is outside but line to this point might be clipped
- e1 = LineRadarBoxCollision(poly[n], rect[i], rect[(i+4-1) % 4]);
- if(e1 != -1){
+ e1 = LineRadarBoxCollision(poly[n], rect[i], rect[(i + 4 - 1) % 4]);
+ if (e1 != -1) {
laste = e1;
n++;
}
// and line from this point might be clipped as well
- e2 = LineRadarBoxCollision(poly[n], rect[i], rect[(i+1) % 4]);
- if(e2 != -1){
- if(e1 == -1){
+ e2 = LineRadarBoxCollision(poly[n], rect[i], rect[(i + 1) % 4]);
+ if (e2 != -1) {
+ if (e1 == -1) {
// if other line wasn't clipped, i.e. it was complete outside,
// we may have to insert another vertex if last clipped line
// was on a different edge
// find the last intersection if we haven't seen it yet
- if(laste == -1)
- for(j = 3; j >= i; j--){
+ if (laste == -1)
+ for (j = 3; j >= i; j--) {
// game uses an if here for j == 0
- e = LineRadarBoxCollision(tmp, rect[j], rect[(j+4-1) % 4]);
- if(e != -1){
+ e = LineRadarBoxCollision(tmp, rect[j], rect[(j + 4 - 1) % 4]);
+ if (e != -1) {
laste = e;
break;
}
@@ -327,7 +207,7 @@ int CRadar::ClipRadarPoly(CVector2D *poly, const CVector2D *rect)
// insert corners that were skipped
tmp = poly[n];
- for(e = laste; e != e2; e = (e+1) % 4)
+ for (e = laste; e != e2; e = (e + 1) % 4)
poly[n++] = corners[e];
poly[n] = tmp;
}
@@ -335,13 +215,13 @@ int CRadar::ClipRadarPoly(CVector2D *poly, const CVector2D *rect)
}
}
- if(n == 0){
+ if (n == 0) {
// If no points, either the rectangle is completely outside or completely surrounds the radar
// no idea what's going on here...
float m = (rect[0].y - rect[1].y) / (rect[0].x - rect[1].x);
- if((m*rect[3].x - rect[3].y) * (m*rect[0].x - rect[0].y) < 0.0f){
+ if ((m*rect[3].x - rect[3].y) * (m*rect[0].x - rect[0].y) < 0.0f) {
m = (rect[0].y - rect[3].y) / (rect[0].x - rect[3].x);
- if((m*rect[1].x - rect[1].y) * (m*rect[0].x - rect[0].y) < 0.0f){
+ if ((m*rect[1].x - rect[1].y) * (m*rect[0].x - rect[0].y) < 0.0f) {
poly[0] = corners[0];
poly[1] = corners[1];
poly[2] = corners[2];
@@ -355,147 +235,27 @@ int CRadar::ClipRadarPoly(CVector2D *poly, const CVector2D *rect)
}
#endif
-#if 0
-WRAPPER void CRadar::DrawRadarSection(int x, int y) { EAXJMP(0x4A67E0); }
-#else
-void CRadar::DrawRadarSection(int x, int y)
+bool CRadar::DisplayThisBlip(int32 counter)
{
- int i;
- RwTexDictionary *txd;
- CVector2D worldPoly[8];
- CVector2D radarCorners[4];
- CVector2D radarPoly[8];
- CVector2D texCoords[8];
- CVector2D screenPoly[8];
- int numVertices;
- RwTexture *texture = nil;
-
- GetTextureCorners(x, y, worldPoly);
- ClipRadarTileCoords(x, y);
-
- assert(CTxdStore::GetSlot(gRadarTxdIds[x + RADAR_NUM_TILES * y]));
- txd = CTxdStore::GetSlot(gRadarTxdIds[x + RADAR_NUM_TILES * y])->texDict;
- if(txd)
- texture = GetFirstTexture(txd);
- if(texture == nil)
- return;
-
- for(i = 0; i < 4; i++)
- TransformRealWorldPointToRadarSpace(radarCorners[i], worldPoly[i]);
-
- numVertices = ClipRadarPoly(radarPoly, radarCorners);
-
- // FIX: can return earlier here
-// if(numVertices == 0)
- if(numVertices < 3)
- return;
-
- for(i = 0; i< numVertices; i++){
- TransformRadarPointToRealWorldSpace(worldPoly[i], radarPoly[i]);
- TransformRealWorldToTexCoordSpace(texCoords[i], worldPoly[i], x, y);
- TransformRadarPointToScreenSpace(screenPoly[i], radarPoly[i]);
+ switch (ms_RadarTrace[counter].m_IconID) {
+ case RADAR_SPRITE_BOMB:
+ case RADAR_SPRITE_SPRAY:
+ case RADAR_SPRITE_WEAPON:
+ return true;
+ default:
+ return false;
}
- RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(texture));
- CSprite2d::SetVertices(numVertices, (float*)screenPoly, (float*)texCoords, CRGBA(255, 255, 255, 255));
- // check done above now
-// if(numVertices > 2)
- RwIm2DRenderPrimitive(rwPRIMTYPETRIFAN, CSprite2d::GetVertices(), numVertices);
-}
-#endif
-
-void CRadar::RequestMapSection(int x, int y)
-{
- ClipRadarTileCoords(x, y);
- CStreaming::RequestTxd(gRadarTxdIds[x + RADAR_NUM_TILES * y], STREAMFLAGS_DONT_REMOVE|STREAMFLAGS_DEPENDENCY);
-}
-
-void CRadar::RemoveMapSection(int x, int y)
-{
- if (x >= 0 && x <= 7 && y >= 0 && y <= 7)
- CStreaming::RemoveTxd(gRadarTxdIds[x + RADAR_NUM_TILES * y]);
}
-#if 0
-WRAPPER void CRadar::StreamRadarSections(int x, int y) { EAXJMP(0x4A6100); }
-#else
-void CRadar::StreamRadarSections(int x, int y)
-{
- for (int i = 0; i < RADAR_NUM_TILES; ++i) {
- for (int j = 0; j < RADAR_NUM_TILES; ++j) {
- if ((i >= x - 1 && i <= x + 1) && (j >= y - 1 && j <= y + 1))
- RequestMapSection(i, j);
- else
- RemoveMapSection(i, j);
- };
- };
-}
-#endif
-
-#if 0
-WRAPPER float CRadar::LimitRadarPoint(CVector2D &point) { EAXJMP(0x4A4F30); }
+#if 1
+WRAPPER void CRadar::Draw3dMarkers() { EAXJMP(0x4A4C70); }
#else
-float CRadar::LimitRadarPoint(CVector2D &point)
+void CRadar::Draw3dMarkers()
{
- float dist, invdist;
- dist = point.Magnitude();
- if (dist > 1.0f) {
- invdist = 1.0f / dist;
- point.x *= invdist;
- point.y *= invdist;
- }
- return dist;
-}
-#endif
-
-#if 0
-WRAPPER void CRadar::TransformRealWorldToTexCoordSpace(CVector2D &out, const CVector2D &in, int x, int y) { EAXJMP(0x4A5530); }
-#else
-void CRadar::TransformRealWorldToTexCoordSpace(CVector2D &out, const CVector2D &in, int x, int y)
-{
- out.x = in.x - (x * RADAR_TILE_SIZE + WORLD_MIN_X);
- out.y = -(in.y - ((RADAR_NUM_TILES - y) * RADAR_TILE_SIZE + WORLD_MIN_Y));
- out.x /= RADAR_TILE_SIZE;
- out.y /= RADAR_TILE_SIZE;
}
#endif
-#if 0
-WRAPPER void CRadar::DrawRadarMap() { EAXJMP(0x4A6C20); }
-#else
-void CRadar::DrawRadarMap()
-{
- // Game calculates an unused CRect here
-
- DrawRadarMask();
-
- // top left ist (0, 0)
- int x = floorf((vec2DRadarOrigin.x - WORLD_MIN_X) / RADAR_TILE_SIZE);
- int y = ceilf((RADAR_NUM_TILES-1) - (vec2DRadarOrigin.y - WORLD_MIN_Y) / RADAR_TILE_SIZE);
- StreamRadarSections(x, y);
-
- RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE);
- RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
- RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
- RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERLINEAR);
- RwRenderStateSet(rwRENDERSTATESHADEMODE, (void*)rwSHADEMODEFLAT);
- RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE);
- RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
- RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
- RwRenderStateSet(rwRENDERSTATETEXTUREADDRESS, (void*)rwTEXTUREADDRESSCLAMP);
- RwRenderStateSet(rwRENDERSTATETEXTUREPERSPECTIVE, (void*)FALSE);
-
- DrawRadarSection(x - 1, y - 1);
- DrawRadarSection(x, y - 1);
- DrawRadarSection(x + 1, y - 1);
- DrawRadarSection(x - 1, y);
- DrawRadarSection(x, y);
- DrawRadarSection(x + 1, y);
- DrawRadarSection(x - 1, y + 1);
- DrawRadarSection(x, y + 1);
- DrawRadarSection(x + 1, y + 1);
-}
-#endif
#if 0
WRAPPER void CRadar::DrawBlips() { EAXJMP(0x4A42F0); }
@@ -566,12 +326,12 @@ void CRadar::DrawBlips()
int a = CalculateBlipAlpha(dist);
TransformRadarPointToScreenSpace(out, in);
- CRGBA col = GetRadarTraceColour(ms_RadarTrace[i].m_nColor, ms_RadarTrace[i].m_bDim);
+ int32 col = GetRadarTraceColour(ms_RadarTrace[i].m_nColor, ms_RadarTrace[i].m_bDim);
if (ms_RadarTrace[i].m_IconID)
DrawRadarSprite(ms_RadarTrace[i].m_IconID, out.x, out.y, a);
else
- ShowRadarTrace(out.x, out.y, ms_RadarTrace[i].m_wScale, col.r, col.g, col.b, 255);
+ ShowRadarTrace(out.x, out.y, ms_RadarTrace[i].m_wScale, ((col >> 24)), ((col >> 16) & 0xFF), ((col >> 8)), 255);
}
}
}
@@ -596,12 +356,12 @@ void CRadar::DrawBlips()
int a = CalculateBlipAlpha(dist);
TransformRadarPointToScreenSpace(out, in);
- CRGBA col = GetRadarTraceColour(ms_RadarTrace[i].m_nColor, ms_RadarTrace[i].m_bDim);
+ int32 col = GetRadarTraceColour(ms_RadarTrace[i].m_nColor, ms_RadarTrace[i].m_bDim);
if (ms_RadarTrace[i].m_IconID)
DrawRadarSprite(ms_RadarTrace[i].m_IconID, out.x, out.y, a);
else
- ShowRadarTrace(out.x, out.y, ms_RadarTrace[i].m_wScale, col.r, col.g, col.b, 255);
+ ShowRadarTrace(out.x, out.y, ms_RadarTrace[i].m_wScale, ((col >> 24)), ((col >> 16) & 0xFF), ((col >> 8)), 255);
}
}
}
@@ -611,227 +371,579 @@ void CRadar::DrawBlips()
}
#endif
-int CRadar::CalculateBlipAlpha(float dist)
+
+#if 0
+WRAPPER void CRadar::DrawMap () { EAXJMP(0x4A4200); }
+#else
+void CRadar::DrawMap()
{
- if (dist <= 1.0f)
- return 255;
+ if (!TheCamera.m_WideScreenOn && CHud::m_Wants_To_Draw_Hud) {
+ if (FindPlayerVehicle()) {
+ float speed = FindPlayerSpeed().Magnitude();
+ if (speed < RADAR_MIN_SPEED)
+ m_RadarRange = RADAR_MIN_RANGE;
+ else if (speed < RADAR_MAX_SPEED)
+ m_RadarRange = (speed - RADAR_MIN_SPEED)/(RADAR_MAX_SPEED-RADAR_MIN_SPEED) * (RADAR_MAX_RANGE-RADAR_MIN_RANGE) + RADAR_MIN_RANGE;
+ else
+ m_RadarRange = RADAR_MAX_RANGE;
+ }
+ else
+ m_RadarRange = RADAR_MIN_RANGE;
- if (dist <= 5.0f)
- return (((1.0f - ((dist * 0.25f) - 0.25f)) * 255.0f) + (((dist * 0.25f) - 0.25f) * 128.0f));
+ vec2DRadarOrigin = CVector2D(FindPlayerCentreOfWorld_NoSniperShift());
+ DrawRadarMap();
+ }
+}
+#endif
- return 128;
+#if 0
+WRAPPER void CRadar::DrawRadarMap() { EAXJMP(0x4A6C20); }
+#else
+void CRadar::DrawRadarMap()
+{
+ // Game calculates an unused CRect here
+
+ DrawRadarMask();
+
+ // top left ist (0, 0)
+ int x = floorf((vec2DRadarOrigin.x - WORLD_MIN_X) / RADAR_TILE_SIZE);
+ int y = ceilf((RADAR_NUM_TILES - 1) - (vec2DRadarOrigin.y - WORLD_MIN_Y) / RADAR_TILE_SIZE);
+ StreamRadarSections(x, y);
+
+ RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE);
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERLINEAR);
+ RwRenderStateSet(rwRENDERSTATESHADEMODE, (void*)rwSHADEMODEFLAT);
+ RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
+ RwRenderStateSet(rwRENDERSTATETEXTUREADDRESS, (void*)rwTEXTUREADDRESSCLAMP);
+ RwRenderStateSet(rwRENDERSTATETEXTUREPERSPECTIVE, (void*)FALSE);
+
+ DrawRadarSection(x - 1, y - 1);
+ DrawRadarSection(x, y - 1);
+ DrawRadarSection(x + 1, y - 1);
+ DrawRadarSection(x - 1, y);
+ DrawRadarSection(x, y);
+ DrawRadarSection(x + 1, y);
+ DrawRadarSection(x - 1, y + 1);
+ DrawRadarSection(x, y + 1);
+ DrawRadarSection(x + 1, y + 1);
}
+#endif
+
+#if 0
+WRAPPER void CRadar::DrawRadarMask() { EAXJMP(0x4A69C0); }
+#else
+void CRadar::DrawRadarMask()
+{
+ CVector2D corners[4] = {
+ CVector2D(1.0f, -1.0f),
+ CVector2D(1.0f, 1.0f),
+ CVector2D(-1.0f, 1.0f),
+ CVector2D(-1.0, -1.0f)
+ };
-CRGBA CRadar::GetRadarTraceColour(uint32 color, bool bright)
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void*)FALSE);
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE);
+ RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERLINEAR);
+ RwRenderStateSet(rwRENDERSTATESHADEMODE, (void*)rwSHADEMODEFLAT);
+ RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE);
+ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
+ RwD3D8SetRenderState(rwRENDERSTATESTENCILFUNCTION, rwSTENCILFUNCTIONALWAYS);
+
+ CVector2D out[8];
+ CVector2D in;
+
+ // Draw the shape we want to mask out from the radar in four segments
+ for (int i = 0; i < 4; i++) {
+ // First point is always the corner itself
+ in.x = corners[i].x;
+ in.y = corners[i].y;
+ TransformRadarPointToScreenSpace(out[0], in);
+
+ // Then generate a quarter of the circle
+ for (int j = 0; j < 7; j++) {
+ in.x = corners[i].x * cos(j * (PI / 2.0f / 6.0f));
+ in.y = corners[i].y * sin(j * (PI / 2.0f / 6.0f));
+ TransformRadarPointToScreenSpace(out[j + 1], in);
+ };
+
+ CSprite2d::SetMaskVertices(8, (float *)out);
+ RwIm2DRenderPrimitive(rwPRIMTYPETRIFAN, CSprite2d::GetVertices(), 8);
+ };
+
+ RwD3D8SetRenderState(rwRENDERSTATESTENCILFUNCTION, rwSTENCILFUNCTIONGREATER);
+}
+#endif
+
+#if 0
+WRAPPER void CRadar::DrawRadarSection(int32, int32) { EAXJMP(0x4A67E0); }
+#else
+void CRadar::DrawRadarSection(int32 x, int32 y)
{
+ int i;
+ RwTexDictionary *txd;
+ CVector2D worldPoly[8];
+ CVector2D radarCorners[4];
+ CVector2D radarPoly[8];
+ CVector2D texCoords[8];
+ CVector2D screenPoly[8];
+ int numVertices;
+ RwTexture *texture = nil;
+
+ GetTextureCorners(x, y, worldPoly);
+ ClipRadarTileCoords(x, y);
+
+ assert(CTxdStore::GetSlot(gRadarTxdIds[x + RADAR_NUM_TILES * y]));
+ txd = CTxdStore::GetSlot(gRadarTxdIds[x + RADAR_NUM_TILES * y])->texDict;
+ if (txd)
+ texture = GetFirstTexture(txd);
+ if (texture == nil)
+ return;
+
+ for (i = 0; i < 4; i++)
+ TransformRealWorldPointToRadarSpace(radarCorners[i], worldPoly[i]);
+
+ numVertices = ClipRadarPoly(radarPoly, radarCorners);
+
+ // FIX: can return earlier here
+// if(numVertices == 0)
+ if (numVertices < 3)
+ return;
+
+ for (i = 0; i < numVertices; i++) {
+ TransformRadarPointToRealWorldSpace(worldPoly[i], radarPoly[i]);
+ TransformRealWorldToTexCoordSpace(texCoords[i], worldPoly[i], x, y);
+ TransformRadarPointToScreenSpace(screenPoly[i], radarPoly[i]);
+ }
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(texture));
+ CSprite2d::SetVertices(numVertices, (float*)screenPoly, (float*)texCoords, CRGBA(255, 255, 255, 255));
+ // check done above now
+// if(numVertices > 2)
+ RwIm2DRenderPrimitive(rwPRIMTYPETRIFAN, CSprite2d::GetVertices(), numVertices);
+}
+#endif
+
+#if 0
+WRAPPER void CRadar::DrawRadarSprite(int32 sprite, float x, float y, int32 alpha) { EAXJMP(0x4A5EF0); }
+#else
+void CRadar::DrawRadarSprite(int32 sprite, float x, float y, int32 alpha)
+{
+ RadarSprites[sprite]->Draw(CRect(x - SCREEN_SCALE_X(8.0f), y - SCREEN_SCALE_Y(8.0f), x + SCREEN_SCALE_X(8.0f), y + SCREEN_SCALE_Y(8.0f)), CRGBA(255, 255, 255, alpha));
+}
+#endif
+
+#if 0
+WRAPPER void CRadar::DrawRotatingRadarSprite(CSprite2d* sprite, float x, float y, float angle, int32 alpha) { EAXJMP(0x4A5D10); }
+#else
+void CRadar::DrawRotatingRadarSprite(CSprite2d* sprite, float x, float y, float angle, int32 alpha)
+{
+ CVector curPosn[4];
+ CVector oldPosn[4];
+
+ curPosn[0].x = x - SCREEN_SCALE_X(5.6f);
+ curPosn[0].y = y + SCREEN_SCALE_Y(5.6f);
+
+ curPosn[1].x = x + SCREEN_SCALE_X(5.6f);
+ curPosn[1].y = y + SCREEN_SCALE_Y(5.6f);
+
+ curPosn[2].x = x - SCREEN_SCALE_X(5.6f);
+ curPosn[2].y = y - SCREEN_SCALE_Y(5.6f);
+
+ curPosn[3].x = x + SCREEN_SCALE_X(5.6f);
+ curPosn[3].y = y - SCREEN_SCALE_Y(5.6f);
+
+ for (uint32 i = 0; i < 4; i++) {
+ oldPosn[i] = curPosn[i];
+
+ curPosn[i].x = x + (oldPosn[i].x - x) * cosf(angle) + (oldPosn[i].y - y) * sinf(angle);
+ curPosn[i].y = y - (oldPosn[i].x - x) * sinf(angle) + (oldPosn[i].y - y) * cosf(angle);
+ }
+
+ sprite->Draw(curPosn[2].x, curPosn[2].y, curPosn[3].x, curPosn[3].y, curPosn[0].x, curPosn[0].y, curPosn[1].x, curPosn[1].y, CRGBA(255, 255, 255, alpha));
+}
+#endif
+
+#if 1
+WRAPPER int32 CRadar::GetActualBlipArray(int32) { EAXJMP(0x4A41C0); }
+#else
+int32 CRadar::GetActualBlipArray(int32 i)
+{
+ return int32();
+}
+#endif
+
+#if 1
+WRAPPER int32 CRadar::GetNewUniqueBlipIndex(int32) { EAXJMP(0x4A4180); }
+#else
+int32 CRadar::GetNewUniqueBlipIndex(int32 i)
+{
+ return int32();
+}
+#endif
+
+#if 0
+WRAPPER int32 CRadar::GetRadarTraceColour(int32 color, bool bright) { EAXJMP(0x4A5BB0); }
+#else
+int32 CRadar::GetRadarTraceColour(int32 color, bool bright)
+{
+ int32 c;
switch (color) {
case 0:
if (bright)
- return CRGBA(113, 43, 73, 255);
+ c = 0x712B49FF;
else
- return CRGBA(127, 0, 0, 255);
+ c = 0x7F0000FF;
+ break;
case 1:
if (bright)
- return CRGBA(95, 160, 106, 255);
+ c = 0x5FA06AFF;
else
- return CRGBA(127, 0, 255, 255);
+ c = 0x7F00FF;
+ break;
case 2:
if (bright)
- return CRGBA(128, 167, 243, 255);
+ c = 0x80A7F3FF;
else
- return CRGBA(0, 127, 255, 255);
+ c = 0x007FFF;
+ break;
case 3:
if (bright)
- return CRGBA(225, 225, 225, 255);
+ c = 0xE1E1E1FF;
else
- return CRGBA(127, 127, 127, 255);
+ c = 0x7F7F7FFF;
+ break;
case 4:
if (bright)
- return CRGBA(255, 225, 0, 255);
+ c = 0xFFFF00FF;
else
- return CRGBA(127, 127, 0, 255);
+ c = 0x7F7F00FF;
+ break;
case 5:
if (bright)
- return CRGBA(255, 0, 255, 255);
+ c = 0xFF00FFFF;
else
- return CRGBA(127, 0, 127, 255);
+ c = 0x7F007FFF;
+ break;
case 6:
if (bright)
- return CRGBA(255, 255, 255, 255);
+ c = 0xFFFFFF;
else
- return CRGBA(127, 127, 255, 255);
+ c = 0x7F7FFF;
+ break;
default:
- return CRGBA(0, 0, 0, 255);
- }
+ c = color;
+ break;
+ };
+ return c;
}
+#endif
-// Radar space goes from -1.0 to 1.0 in x and y, top right is (1.0, 1.0)
-void CRadar::TransformRadarPointToScreenSpace(CVector2D &out, const CVector2D &in)
+#if 0
+WRAPPER void CRadar::Initialise() { EAXJMP(0x4A3EF0); }
+#else
+void CRadar::Initialise()
{
- // FIX: game doesn't scale RADAR_LEFT here
- out.x = (in.x + 1.0f)*0.5f*SCREEN_SCALE_X(RADAR_WIDTH) + SCREEN_SCALE_X(RADAR_LEFT);
- out.y = (1.0f - in.y)*0.5f*SCREEN_SCALE_Y(RADAR_HEIGHT) + SCREEN_SCALE_FROM_BOTTOM(RADAR_BOTTOM + RADAR_HEIGHT);
+
}
+#endif
#if 0
-WRAPPER void CRadar::TransformRealWorldPointToRadarSpace(CVector2D &out, const CVector2D &in) { EAXJMP(0x4A50D0); }
+WRAPPER float CRadar::LimitRadarPoint(CVector2D &point) { EAXJMP(0x4A4F30); }
#else
-void CRadar::TransformRealWorldPointToRadarSpace(CVector2D &out, const CVector2D &in)
+float CRadar::LimitRadarPoint(CVector2D &point)
{
- float s, c;
- if (TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWN1 || TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWNPED) {
- s = 0.0f;
- c = 1.0f;
- } else if (TheCamera.GetLookDirection() == LOOKING_FORWARD) {
- s = sin(atan2(-TheCamera.GetForward().x, TheCamera.GetForward().y));
- c = cos(atan2(-TheCamera.GetForward().x, TheCamera.GetForward().y));
- } else {
- CVector forward;
-
- if (TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_FIRSTPERSON) {
- forward = TheCamera.Cams[TheCamera.ActiveCam].CamTargetEntity->GetForward();
- forward.Normalise(); // a bit useless...
- } else
- forward = TheCamera.Cams[TheCamera.ActiveCam].CamTargetEntity->GetPosition() - TheCamera.Cams[TheCamera.ActiveCam].SourceBeforeLookBehind;
+ float dist, invdist;
- s = sin(atan2(-forward.x, forward.y));
- c = cos(atan2(-forward.x, forward.y));
+ dist = point.Magnitude();
+ if (dist > 1.0f) {
+ invdist = 1.0f / dist;
+ point.x *= invdist;
+ point.y *= invdist;
}
+ return dist;
+}
+#endif
- float x = (in.x - vec2DRadarOrigin.x) * (1.0f / m_RadarRange);
- float y = (in.y - vec2DRadarOrigin.y) * (1.0f / m_RadarRange);
+#if 0
+WRAPPER void CRadar::LoadAllRadarBlips() { EAXJMP(0x4A6F30); }
+#else
+void CRadar::LoadAllRadarBlips(int32)
+{
- out.x = s * y + c * x;
- out.y = c * y - s * x;
}
#endif
#if 0
-WRAPPER void CRadar::TransformRadarPointToRealWorldSpace(CVector2D &out, const CVector2D &in) { EAXJMP(0x4A5300); }
+WRAPPER void CRadar::LoadTextures() { EAXJMP(0x4A4030); }
#else
-void CRadar::TransformRadarPointToRealWorldSpace(CVector2D &out, const CVector2D &in)
+void CRadar::LoadTextures()
{
- float s, c;
- s = -sin(atan2(-TheCamera.GetForward().x, TheCamera.GetForward().y));
- c = cos(atan2(-TheCamera.GetForward().x, TheCamera.GetForward().y));
+}
+#endif
- if (TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWN1 || TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWNPED) {
- s = 0.0f;
- c = 1.0f;
- } else if (TheCamera.GetLookDirection() != LOOKING_FORWARD) {
- CVector forward;
+#if 0
+WRAPPER void CRadar::RemoveRadarSections() { EAXJMP(0x00); }
+#else
+void CRadar::RemoveRadarSections()
+{
- if (TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_FIRSTPERSON) {
- forward = TheCamera.Cams[TheCamera.ActiveCam].CamTargetEntity->GetForward();
- forward.Normalise(); // a bit useless...
- } else
- forward = TheCamera.Cams[TheCamera.ActiveCam].CamTargetEntity->GetPosition() - TheCamera.Cams[TheCamera.ActiveCam].SourceBeforeLookBehind;
+}
+#endif
- s = -sin(atan2(-forward.x, forward.y));
- c = cos(atan2(-forward.x, forward.y));
- }
+#if 0
+WRAPPER void CRadar::RemoveMapSection(int32, int32) { EAXJMP(0x00); }
+#else
+void CRadar::RemoveMapSection(int32 x, int32 y)
+{
+ if (x >= 0 && x <= 7 && y >= 0 && y <= 7)
+ CStreaming::RemoveTxd(gRadarTxdIds[x + RADAR_NUM_TILES * y]);
+}
+#endif
- out.x = s * in.y + c * in.x;
- out.y = c * in.y - s * in.x;
+#if 0
+WRAPPER void CRadar::RequestMapSection(int32, int32) { EAXJMP(0x00); }
+#else
+void CRadar::RequestMapSection(int32 x, int32 y)
+{
+ ClipRadarTileCoords(x, y);
+ CStreaming::RequestTxd(gRadarTxdIds[x + RADAR_NUM_TILES * y], STREAMFLAGS_DONT_REMOVE | STREAMFLAGS_DEPENDENCY);
+}
+#endif
+
+#if 0
+WRAPPER void CRadar::SaveAllRadarBlips(int32) { EAXJMP(0x00); }
+#else
+void CRadar::SaveAllRadarBlips(int32)
+{
- out = out*m_RadarRange + vec2DRadarOrigin;
}
#endif
#if 0
-WRAPPER void CRadar::DrawRadarSprite(int sprite, float x, float y, int alpha) { EAXJMP(0x4A5EF0); }
+WRAPPER void CRadar::SetBlipSprite(int32, int32) { EAXJMP(0x00); }
#else
-void CRadar::DrawRadarSprite(int sprite, float x, float y, int alpha)
+void CRadar::SetBlipSprite(int32 i, int32 icon)
{
- RadarSprites[sprite]->Draw(CRect(x - SCREEN_SCALE_X(8.0f), y - SCREEN_SCALE_Y(8.0f), x + SCREEN_SCALE_X(8.0f), y + SCREEN_SCALE_Y(8.0f)), CRGBA(255, 255, 255, alpha));
+
}
#endif
#if 0
-WRAPPER void CRadar::ShowRadarTrace(float x, float y, uint32 size, uint32 red, uint32 green, uint32 blue, uint32 alpha) { EAXJMP(0x4A5870); }
+WRAPPER void CRadar::SetCoordBlip(int32, CVector, int32) { EAXJMP(0x00); }
#else
-void CRadar::ShowRadarTrace(float x, float y, uint32 size, uint32 red, uint32 green, uint32 blue, uint32 alpha)
+int CRadar::SetCoordBlip(int32 type, CVector pos, int32 flag)
{
- CSprite2d::DrawRect(CRect(x - SCREEN_SCALE_X(size + 1.0f), y - SCREEN_SCALE_Y(size + 1.0f), SCREEN_SCALE_X(size + 1.0f) + x, SCREEN_SCALE_Y(size + 1.0f) + y), CRGBA(0, 0, 0, alpha));
- CSprite2d::DrawRect(CRect(x - SCREEN_SCALE_X(size), y - SCREEN_SCALE_Y(size), SCREEN_SCALE_X(size) + x, SCREEN_SCALE_Y(size) + y), CRGBA(red, green, blue, alpha));
+ return 0;
+}
+#endif
+
+#if 0
+WRAPPER void CRadar::SetEntityBlip(int32 type, CVector pos, int32 color, int32 flag) { EAXJMP(0x00); }
+#else
+int CRadar::SetEntityBlip(int32 type, CVector pos, int32 color, int32 flag)
+{
+ return 0;
}
#endif
#if 0
-WRAPPER void CRadar::ShowRadarMarker(CVector pos, CRGBA color, float radius) { EAXJMP(0x4A59C0); }
+WRAPPER void CRadar::SetRadarMarkerState(int32, int32) { EAXJMP(0x4A5C60); }
#else
-void CRadar::ShowRadarMarker(CVector pos, CRGBA color, float radius) {
+void CRadar::SetRadarMarkerState(int32 counter, int32 flag)
+{
+ CEntity *e;
+ switch (ms_RadarTrace[counter].m_eBlipType) {
+ case BLIP_CAR:
+ e = CPools::GetVehiclePool()->GetAt(ms_RadarTrace[counter].m_nEntityHandle);
+ break;
+ case BLIP_CHAR:
+ e = CPools::GetPedPool()->GetAt(ms_RadarTrace[counter].m_nEntityHandle);
+ break;
+ case BLIP_OBJECT:
+ e = CPools::GetObjectPool()->GetAt(ms_RadarTrace[counter].m_nEntityHandle);
+ break;
+ default:
+ return;
+ }
+
+ if (e)
+ e->bHasBlip = flag;
+}
+#endif
+
+#if 0
+WRAPPER void CRadar::ShowRadarMarker(CVector pos, int16 color, float radius) { EAXJMP(0x4A59C0); }
+#else
+void CRadar::ShowRadarMarker(CVector pos, int16 color, float radius) {
float f1 = radius * 0.5f;
float f2 = radius * 1.4f;
CVector p1, p2;
p1 = pos + TheCamera.GetUp()*f1;
p2 = pos + TheCamera.GetUp()*f2;
- CTheScripts::ScriptDebugLine3D(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z, color.color32, color.color32);
+ CTheScripts::ScriptDebugLine3D(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z, color, color);
p1 = pos - TheCamera.GetUp()*f1;
p2 = pos - TheCamera.GetUp()*f2;
- CTheScripts::ScriptDebugLine3D(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z, color.color32, color.color32);
+ CTheScripts::ScriptDebugLine3D(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z, color, color);
p1 = pos + TheCamera.GetRight()*f1;
p2 = pos + TheCamera.GetRight()*f2;
- CTheScripts::ScriptDebugLine3D(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z, color.color32, color.color32);
+ CTheScripts::ScriptDebugLine3D(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z, color, color);
p1 = pos - TheCamera.GetRight()*f1;
p2 = pos - TheCamera.GetRight()*f2;
- CTheScripts::ScriptDebugLine3D(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z, color.color32, color.color32);
+ CTheScripts::ScriptDebugLine3D(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z, color, color);
+}
+#endif
+
+#if 0
+WRAPPER void CRadar::ShowRadarTrace(float x, float y, uint32 size, uint32 red, uint32 green, uint32 blue, uint32 alpha) { EAXJMP(0x4A5870); }
+#else
+void CRadar::ShowRadarTrace(float x, float y, uint32 size, uint32 red, uint32 green, uint32 blue, uint32 alpha)
+{
+ CSprite2d::DrawRect(CRect(x - SCREEN_SCALE_X(size + 1.0f), y - SCREEN_SCALE_Y(size + 1.0f), SCREEN_SCALE_X(size + 1.0f) + x, SCREEN_SCALE_Y(size + 1.0f) + y), CRGBA(0, 0, 0, alpha));
+ CSprite2d::DrawRect(CRect(x - SCREEN_SCALE_X(size), y - SCREEN_SCALE_Y(size), SCREEN_SCALE_X(size) + x, SCREEN_SCALE_Y(size) + y), CRGBA(red, green, blue, alpha));
}
#endif
#if 0
-WRAPPER void CRadar::DrawRotatingRadarSprite(CSprite2d* sprite, float x, float y, float angle, int alpha) { EAXJMP(0x4A5D10); }
+WRAPPER void CRadar::Shutdown() { EAXJMP(0x4A3F60); }
#else
-void CRadar::DrawRotatingRadarSprite(CSprite2d* sprite, float x, float y, float angle, int alpha)
+void CRadar::Shutdown()
{
- CVector curPosn[4];
- CVector oldPosn[4];
- curPosn[0].x = x - SCREEN_SCALE_X(5.6f);
- curPosn[0].y = y + SCREEN_SCALE_Y(5.6f);
+}
+#endif
- curPosn[1].x = x + SCREEN_SCALE_X(5.6f);
- curPosn[1].y = y + SCREEN_SCALE_Y(5.6f);
+#if 0
+WRAPPER void CRadar::StreamRadarSections() { EAXJMP(0x4A6B60); }
+#else
+void CRadar::StreamRadarSections(CVector posn)
+{
- curPosn[2].x = x - SCREEN_SCALE_X(5.6f);
- curPosn[2].y = y - SCREEN_SCALE_Y(5.6f);
+}
+#endif
- curPosn[3].x = x + SCREEN_SCALE_X(5.6f);
- curPosn[3].y = y - SCREEN_SCALE_Y(5.6f);
+#if 0
+WRAPPER void CRadar::StreamRadarSections(int32 x, int32 y) { EAXJMP(0x4A6100); }
+#else
+void CRadar::StreamRadarSections(int32 x, int32 y)
+{
+ for (int i = 0; i < RADAR_NUM_TILES; ++i) {
+ for (int j = 0; j < RADAR_NUM_TILES; ++j) {
+ if ((i >= x - 1 && i <= x + 1) && (j >= y - 1 && j <= y + 1))
+ RequestMapSection(i, j);
+ else
+ RemoveMapSection(i, j);
+ };
+ };
+}
+#endif
- for (uint32 i = 0; i < 4; i++) {
- oldPosn[i] = curPosn[i];
+#if 0
+WRAPPER void CRadar::TransformRealWorldToTexCoordSpace(CVector2D &out, const CVector2D &in, int32 x, int32 y) { EAXJMP(0x4A5530); }
+#else
+void CRadar::TransformRealWorldToTexCoordSpace(CVector2D &out, const CVector2D &in, int32 x, int32 y)
+{
+ out.x = in.x - (x * RADAR_TILE_SIZE + WORLD_MIN_X);
+ out.y = -(in.y - ((RADAR_NUM_TILES - y) * RADAR_TILE_SIZE + WORLD_MIN_Y));
+ out.x /= RADAR_TILE_SIZE;
+ out.y /= RADAR_TILE_SIZE;
+}
+#endif
- curPosn[i].x = x + (oldPosn[i].x - x) * cosf(angle) + (oldPosn[i].y - y) * sinf(angle);
- curPosn[i].y = y - (oldPosn[i].x - x) * sinf(angle) + (oldPosn[i].y - y) * cosf(angle);
- }
+#if 0
+WRAPPER void CRadar::TransformRadarPointToRealWorldSpace(CVector2D &out, const CVector2D &in) { EAXJMP(0x4A5300); }
+#else
+void CRadar::TransformRadarPointToRealWorldSpace(CVector2D &out, const CVector2D &in)
+{
+ float s, c;
- sprite->Draw(curPosn[2].x, curPosn[2].y, curPosn[3].x, curPosn[3].y, curPosn[0].x, curPosn[0].y, curPosn[1].x, curPosn[1].y, CRGBA(255, 255, 255, alpha));
+ s = -sin(atan2(-TheCamera.GetForward().x, TheCamera.GetForward().y));
+ c = cos(atan2(-TheCamera.GetForward().x, TheCamera.GetForward().y));
+
+ if (TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWN1 || TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWNPED) {
+ s = 0.0f;
+ c = 1.0f;
+ }
+ else if (TheCamera.GetLookDirection() != LOOKING_FORWARD) {
+ CVector forward;
+
+ if (TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_FIRSTPERSON) {
+ forward = TheCamera.Cams[TheCamera.ActiveCam].CamTargetEntity->GetForward();
+ forward.Normalise(); // a bit useless...
+ }
+ else
+ forward = TheCamera.Cams[TheCamera.ActiveCam].CamTargetEntity->GetPosition() - TheCamera.Cams[TheCamera.ActiveCam].SourceBeforeLookBehind;
+
+ s = -sin(atan2(-forward.x, forward.y));
+ c = cos(atan2(-forward.x, forward.y));
+ }
+
+ out.x = s * in.y + c * in.x;
+ out.y = c * in.y - s * in.x;
+
+ out = out * m_RadarRange + vec2DRadarOrigin;
}
-#endif
+#endif
-bool CRadar::DisplayThisBlip(int counter)
+// Radar space goes from -1.0 to 1.0 in x and y, top right is (1.0, 1.0)
+void CRadar::TransformRadarPointToScreenSpace(CVector2D &out, const CVector2D &in)
{
- switch (ms_RadarTrace[counter].m_IconID) {
- case RADAR_SPRITE_BOMB:
- case RADAR_SPRITE_SPRAY:
- case RADAR_SPRITE_WEAPON:
- return true;
- default:
- return false;
+ // FIX: game doesn't scale RADAR_LEFT here
+ out.x = (in.x + 1.0f)*0.5f*SCREEN_SCALE_X(RADAR_WIDTH) + SCREEN_SCALE_X(RADAR_LEFT);
+ out.y = (1.0f - in.y)*0.5f*SCREEN_SCALE_Y(RADAR_HEIGHT) + SCREEN_SCALE_FROM_BOTTOM(RADAR_BOTTOM + RADAR_HEIGHT);
+}
+
+#if 0
+WRAPPER void CRadar::TransformRealWorldPointToRadarSpace(CVector2D &out, const CVector2D &in) { EAXJMP(0x4A50D0); }
+#else
+void CRadar::TransformRealWorldPointToRadarSpace(CVector2D &out, const CVector2D &in)
+{
+ float s, c;
+ if (TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWN1 || TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWNPED) {
+ s = 0.0f;
+ c = 1.0f;
+ }
+ else if (TheCamera.GetLookDirection() == LOOKING_FORWARD) {
+ s = sin(atan2(-TheCamera.GetForward().x, TheCamera.GetForward().y));
+ c = cos(atan2(-TheCamera.GetForward().x, TheCamera.GetForward().y));
+ }
+ else {
+ CVector forward;
+
+ if (TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_FIRSTPERSON) {
+ forward = TheCamera.Cams[TheCamera.ActiveCam].CamTargetEntity->GetForward();
+ forward.Normalise(); // a bit useless...
+ }
+ else
+ forward = TheCamera.Cams[TheCamera.ActiveCam].CamTargetEntity->GetPosition() - TheCamera.Cams[TheCamera.ActiveCam].SourceBeforeLookBehind;
+
+ s = sin(atan2(-forward.x, forward.y));
+ c = cos(atan2(-forward.x, forward.y));
}
+
+ float x = (in.x - vec2DRadarOrigin.x) * (1.0f / m_RadarRange);
+ float y = (in.y - vec2DRadarOrigin.y) * (1.0f / m_RadarRange);
+
+ out.x = s * y + c * x;
+ out.y = c * y - s * x;
}
+#endif
#if 0
-WRAPPER void CRadar::GetTextureCorners(int x, int y, CVector2D *out) { EAXJMP(0x4A61C0); };
+WRAPPER void CRadar::GetTextureCorners(int32 x, int32 y, CVector2D *out) { EAXJMP(0x4A61C0); };
#else
// Transform from section indices to world coordinates
-void CRadar::GetTextureCorners(int x, int y, CVector2D *out)
+void CRadar::GetTextureCorners(int32 x, int32 y, CVector2D *out)
{
x = x - RADAR_NUM_TILES/2;
y = -(y - RADAR_NUM_TILES/2);
@@ -854,7 +966,10 @@ void CRadar::GetTextureCorners(int x, int y, CVector2D *out)
}
#endif
-void CRadar::ClipRadarTileCoords(int &x, int &y)
+#if 0
+WRAPPER void CRadar::ClipRadarTileCoords(int32 &, int32 &) { EAXJMP(0x00); };
+#else
+void CRadar::ClipRadarTileCoords(int32 &x, int32 &y)
{
if (x < 0)
x = 0;
@@ -865,6 +980,95 @@ void CRadar::ClipRadarTileCoords(int &x, int &y)
if (y > RADAR_NUM_TILES-1)
y = RADAR_NUM_TILES-1;
}
+#endif
+
+
+#if 0
+WRAPPER bool CRadar::IsPointInsideRadar(const CVector2D &) { EAXJMP(0x4A6160); }
+#else
+bool CRadar::IsPointInsideRadar(const CVector2D &point)
+{
+ if (point.x < -1.0f || point.x > 1.0f) return false;
+ if (point.y < -1.0f || point.y > 1.0f) return false;
+ return true;
+}
+#endif
+
+// clip line p1,p2 against (-1.0, 1.0) in x and y, set out to clipped point closest to p1
+#if 0
+WRAPPER int CRadar::LineRadarBoxCollision(CVector2D &, const CVector2D &, const CVector2D &) { EAXJMP(0x4A6250); }
+#else
+int CRadar::LineRadarBoxCollision(CVector2D &out, const CVector2D &p1, const CVector2D &p2)
+{
+ float d1, d2;
+ float t;
+ float x, y;
+ float shortest = 1.0f;
+ int edge = -1;
+
+ // clip against left edge, x = -1.0
+ d1 = -1.0f - p1.x;
+ d2 = -1.0f - p2.x;
+ if (d1 * d2 < 0.0f) {
+ // they are on opposite sides, get point of intersection
+ t = d1 / (d1 - d2);
+ y = (p2.y - p1.y)*t + p1.y;
+ if (y >= -1.0f && y <= 1.0f && t <= shortest) {
+ out.x = -1.0f;
+ out.y = y;
+ edge = 3;
+ shortest = t;
+ }
+ }
+
+ // clip against right edge, x = 1.0
+ d1 = p1.x - 1.0f;
+ d2 = p2.x - 1.0f;
+ if (d1 * d2 < 0.0f) {
+ // they are on opposite sides, get point of intersection
+ t = d1 / (d1 - d2);
+ y = (p2.y - p1.y)*t + p1.y;
+ if (y >= -1.0f && y <= 1.0f && t <= shortest) {
+ out.x = 1.0f;
+ out.y = y;
+ edge = 1;
+ shortest = t;
+ }
+ }
+
+ // clip against top edge, y = -1.0
+ d1 = -1.0f - p1.y;
+ d2 = -1.0f - p2.y;
+ if (d1 * d2 < 0.0f) {
+ // they are on opposite sides, get point of intersection
+ t = d1 / (d1 - d2);
+ x = (p2.x - p1.x)*t + p1.x;
+ if (x >= -1.0f && x <= 1.0f && t <= shortest) {
+ out.y = -1.0f;
+ out.x = x;
+ edge = 0;
+ shortest = t;
+ }
+ }
+
+ // clip against bottom edge, y = 1.0
+ d1 = p1.y - 1.0f;
+ d2 = p2.y - 1.0f;
+ if (d1 * d2 < 0.0f) {
+ // they are on opposite sides, get point of intersection
+ t = d1 / (d1 - d2);
+ x = (p2.x - p1.x)*t + p1.x;
+ if (x >= -1.0f && x <= 1.0f && t <= shortest) {
+ out.y = 1.0f;
+ out.x = x;
+ edge = 2;
+ shortest = t;
+ }
+ }
+
+ return edge;
+}
+#endif
STARTPATCHES
// InjectHook(0x4A3EF0, CRadar::Initialise, PATCH_JUMP);
@@ -892,12 +1096,12 @@ STARTPATCHES
// InjectHook(0x4A5840, CRadar::SetBlipSprite, PATCH_JUMP);
InjectHook(0x4A5870, CRadar::ShowRadarTrace, PATCH_JUMP);
InjectHook(0x4A59C0, CRadar::ShowRadarMarker, PATCH_JUMP);
- InjectHook(0x4A5BB0, CRadar::GetRadarTraceColour, PATCH_JUMP);
+ //InjectHook(0x4A5BB0, CRadar::GetRadarTraceColour, PATCH_JUMP);
InjectHook(0x4A5C60, CRadar::SetRadarMarkerState, PATCH_JUMP);
InjectHook(0x4A5D10, CRadar::DrawRotatingRadarSprite, PATCH_JUMP);
InjectHook(0x4A5EF0, CRadar::DrawRadarSprite, PATCH_JUMP);
// InjectHook(0x4A60E0, CRadar::RemoveRadarSections, PATCH_JUMP);
- InjectHook(0x4A6100, CRadar::StreamRadarSections, PATCH_JUMP);
+// InjectHook(0x4A6100, CRadar::StreamRadarSections, PATCH_JUMP);
InjectHook(0x4A64A0, CRadar::ClipRadarPoly, PATCH_JUMP);
InjectHook(0x4A67E0, CRadar::DrawRadarSection, PATCH_JUMP);
InjectHook(0x4A69C0, CRadar::DrawRadarMask, PATCH_JUMP);
@@ -907,6 +1111,6 @@ STARTPATCHES
// InjectHook(0x4A6F30, CRadar::LoadAllRadarBlips, PATCH_JUMP);
InjectHook(0x4A61C0, CRadar::GetTextureCorners, PATCH_JUMP);
- InjectHook(0x4A6160, IsPointInsideRadar, PATCH_JUMP);
- InjectHook(0x4A6250, LineRadarBoxCollision, PATCH_JUMP);
+ InjectHook(0x4A6160, CRadar::IsPointInsideRadar, PATCH_JUMP);
+ InjectHook(0x4A6250, CRadar::LineRadarBoxCollision, PATCH_JUMP);
ENDPATCHES
diff --git a/src/Radar.h b/src/Radar.h
index dec07667..5943498f 100644
--- a/src/Radar.h
+++ b/src/Radar.h
@@ -96,32 +96,51 @@ public:
static CSprite2d *RadarSprites[21];
public:
- static void ClearBlipForEntity(eBlipType type, int32 id);
- static void Draw3dMarkers();
- static void DrawMap();
- static void StreamRadarSections(int x, int y);
+ static int CalculateBlipAlpha(float dist);
+ static void ChangeBlipBrightness(int32 i, int32 bright);
+ static void ChangeBlipColour(int32 i);
+ static void ChangeBlipDisplay(int32 i, int16 flag);
+ static void ChangeBlipScale(int32 i, int16 scale);
+ static void ClearBlip(int32 i);
+ static void ClearBlipForEntity(int16 type, int32 id);
static int ClipRadarPoly(CVector2D *out, const CVector2D *in);
- static void DrawRadarSection(int x, int y);
- static void RequestMapSection(int x, int y);
- static void RemoveMapSection(int x, int y);
+ static bool DisplayThisBlip(int32 i);
+ static void Draw3dMarkers();
static void DrawBlips();
- static int CalculateBlipAlpha(float dist);
- static CRGBA GetRadarTraceColour(uint32 color, bool bright);
+ static void DrawMap();
static void DrawRadarMap();
- static void DrawRotatingRadarSprite(CSprite2d* sprite, float x, float y, float angle, int alpha);
+ static void DrawRadarMask();
+ static void DrawRadarSection(int32 x, int32 y);
+ static void DrawRadarSprite(int32 sprite, float x, float y, int32 alpha);
+ static void DrawRotatingRadarSprite(CSprite2d* sprite, float x, float y, float angle, int32 alpha);
+ static int32 GetActualBlipArray(int32 i);
+ static int32 GetNewUniqueBlipIndex(int32 i);
+ static int32 GetRadarTraceColour(int32 color, bool bright);
+ static void Initialise();
static float LimitRadarPoint(CVector2D &point);
- static void DrawRadarSprite(int sprite, float x, float y, int alpha);
- static void ShowRadarMarker(CVector pos, CRGBA color, float radius);
+ static void LoadAllRadarBlips(int32);
+ static void LoadTextures();
+ static void RemoveRadarSections();
+ static void RemoveMapSection(int32 x, int32 y);
+ static void RequestMapSection(int32 x, int32 y);
+ static void SaveAllRadarBlips(int32);
+ static void SetBlipSprite(int32 i, int32 icon);
+ static int SetCoordBlip(int32 type, CVector pos, int32 flag);
+ static int SetEntityBlip(int32 type, CVector pos, int32 color, int32 flag);
+ static void SetRadarMarkerState(int32 i, int32 flag);
+ static void ShowRadarMarker(CVector pos, int16 color, float radius);
static void ShowRadarTrace(float x, float y, uint32 size, uint32 red, uint32 green, uint32 blue, uint32 alpha);
- static void DrawRadarMask();
- static void SetRadarMarkerState(int counter, int flag);
- static bool DisplayThisBlip(int counter);
- static void TransformRealWorldToTexCoordSpace(CVector2D &out, const CVector2D &in, int x, int y);
+ static void Shutdown();
+ static void StreamRadarSections(CVector posn);
+ static void StreamRadarSections(int32 x, int32 y);
+ static void TransformRealWorldToTexCoordSpace(CVector2D &out, const CVector2D &in, int32 x, int32 y);
static void TransformRadarPointToRealWorldSpace(CVector2D &out, const CVector2D &in);
static void TransformRadarPointToScreenSpace(CVector2D &out, const CVector2D &in);
static void TransformRealWorldPointToRadarSpace(CVector2D &out, const CVector2D &in);
// no in CRadar in the game:
- static void GetTextureCorners(int x, int y, CVector2D *out);
- static void ClipRadarTileCoords(int &x, int &y);
+ static void GetTextureCorners(int32 x, int32 y, CVector2D *out);
+ static void ClipRadarTileCoords(int32 &x, int32 &y);
+ static bool IsPointInsideRadar(const CVector2D &);
+ static int LineRadarBoxCollision(CVector2D &, const CVector2D &, const CVector2D &);
};
diff --git a/src/audio/DMAudio.cpp b/src/audio/DMAudio.cpp
index c320ea94..b96bee01 100644
--- a/src/audio/DMAudio.cpp
+++ b/src/audio/DMAudio.cpp
@@ -18,3 +18,5 @@ WRAPPER void cDMAudio::ChangeMusicMode(uint8 mode) { EAXJMP(0x57CCF0); }
WRAPPER void cDMAudio::PlayFrontEndSound(uint32, uint32) { EAXJMP(0x57CC20); }
WRAPPER void cDMAudio::PlayOneShot(int, uint16, float) { EAXJMP(0x57C840); }
+WRAPPER int cDMAudio::GetRadioInCar() { EAXJMP(0x57CE40); }
+WRAPPER uint8 cDMAudio::IsMP3RadioChannelAvailable() { EAXJMP(0x57C9F0); } \ No newline at end of file
diff --git a/src/audio/DMAudio.h b/src/audio/DMAudio.h
index 3ebeaad8..ad67cf13 100644
--- a/src/audio/DMAudio.h
+++ b/src/audio/DMAudio.h
@@ -189,5 +189,7 @@ public:
void ChangeMusicMode(uint8 mode);
void PlayFrontEndSound(uint32, uint32);
void PlayOneShot(int, uint16, float);
+ int GetRadioInCar();
+ uint8 IsMP3RadioChannelAvailable();
};
extern cDMAudio &DMAudio;
diff --git a/src/audio/MusicManager.cpp b/src/audio/MusicManager.cpp
index f9c02739..6f2d3d86 100644
--- a/src/audio/MusicManager.cpp
+++ b/src/audio/MusicManager.cpp
@@ -16,6 +16,8 @@ int32 &gNumRetunePresses = *(int32*)0x650B80;
wchar *pCurrentStation = (wchar*)0x650B9C;
uint8 &cDisplay = *(uint8*)0x650BA1;
+WRAPPER char* cMusicManager::Get3DProviderName(char) { EAXJMP(0x57A8C0); }
+
bool cMusicManager::PlayerInCar()
{
if (!FindPlayerVehicle())
diff --git a/src/audio/MusicManager.h b/src/audio/MusicManager.h
index 644c3df3..dcb34daf 100644
--- a/src/audio/MusicManager.h
+++ b/src/audio/MusicManager.h
@@ -264,6 +264,7 @@ public:
uint8 field_2395;
public:
+ char *Get3DProviderName(char);
bool PlayerInCar();
void DisplayRadioStationName();
};
diff --git a/src/config.h b/src/config.h
index 7c228e60..1cd532ee 100644
--- a/src/config.h
+++ b/src/config.h
@@ -69,3 +69,4 @@ enum Config {
//#define NO_CDCHECK
#define NO_MOVIES
//#define USE_MY_DOCUMENTS
+#define NASTY_GAME \ No newline at end of file
diff --git a/src/control/Garages.cpp b/src/control/Garages.cpp
index 70a15476..d601db8e 100644
--- a/src/control/Garages.cpp
+++ b/src/control/Garages.cpp
@@ -68,7 +68,7 @@ WRAPPER void CGarages::PrintMessages(void) { EAXJMP(0x426310); }
#else
void CGarages::PrintMessages()
{
- if (CTimer::GetTimeInMilliseconds() > CGarages::MessageStartTime && CTimer::GetTimeInMilliseconds() < CGarages::MessageEndTime) {
+ if (CTimer::GetTimeInMilliseconds() > MessageStartTime && CTimer::GetTimeInMilliseconds() < MessageEndTime) {
CFont::SetScale(SCREEN_SCALE_X(1.2f / 2), SCREEN_SCALE_Y(1.5f / 2)); // BUG: game doesn't use macro here.
CFont::SetPropOn();
CFont::SetJustifyOff();
@@ -77,16 +77,16 @@ void CGarages::PrintMessages()
CFont::SetCentreOn();
CFont::SetFontStyle(FONT_BANK);
- if (CGarages::MessageNumberInString2 < 0) {
- if (CGarages::MessageNumberInString < 0) {
+ if (MessageNumberInString2 < 0) {
+ if (MessageNumberInString < 0) {
CFont::SetColor(CRGBA(0, 0, 0, 255));
- CFont::PrintString((SCREEN_WIDTH/ 2) + SCREEN_SCALE_X(2.0f), (SCREEN_HEIGHT / 2) + SCREEN_SCALE_Y(-84.0f), TheText.Get(CGarages::MessageIDString));
+ CFont::PrintString((SCREEN_WIDTH/ 2) + SCREEN_SCALE_X(2.0f), (SCREEN_HEIGHT / 2) + SCREEN_SCALE_Y(-84.0f), TheText.Get(MessageIDString));
CFont::SetColor(CRGBA(89, 115, 150, 255));
- CFont::PrintString((SCREEN_WIDTH / 2), (SCREEN_HEIGHT / 2) + SCREEN_SCALE_Y(-84.0f), TheText.Get(CGarages::MessageIDString));
+ CFont::PrintString((SCREEN_WIDTH / 2), (SCREEN_HEIGHT / 2) + SCREEN_SCALE_Y(-84.0f), TheText.Get(MessageIDString));
}
else {
- CMessages::InsertNumberInString(TheText.Get(CGarages::MessageIDString), CGarages::MessageNumberInString, -1, -1, -1, -1, -1, gUString);
+ CMessages::InsertNumberInString(TheText.Get(MessageIDString), MessageNumberInString, -1, -1, -1, -1, -1, gUString);
CFont::SetColor(CRGBA(0, 0, 0, 255));
CFont::PrintString((SCREEN_WIDTH / 2) + SCREEN_SCALE_X(2.0f), (SCREEN_HEIGHT / 2) + SCREEN_SCALE_Y(-84.0f + 2.0 - 40.0f), gUString);
@@ -96,7 +96,7 @@ void CGarages::PrintMessages()
}
}
else {
- CMessages::InsertNumberInString(TheText.Get(CGarages::MessageIDString), CGarages::MessageNumberInString2, -1, -1, -1, -1, -1, gUString);
+ CMessages::InsertNumberInString(TheText.Get(MessageIDString), MessageNumberInString, MessageNumberInString2, -1, -1, -1, -1, gUString);
CFont::SetColor(CRGBA(0, 0, 0, 255));
CFont::PrintString((SCREEN_WIDTH / 2) + SCREEN_SCALE_X(2.0f), (SCREEN_HEIGHT / 2) + SCREEN_SCALE_Y(-84.0f + 2.0 - 40.0f), gUString);
diff --git a/src/control/PedType.h b/src/control/PedType.h
index 02add8f6..455d8d8d 100644
--- a/src/control/PedType.h
+++ b/src/control/PedType.h
@@ -22,9 +22,9 @@ enum
PEDTYPE_EMERGENCY,
PEDTYPE_FIREMAN,
PEDTYPE_CRIMINAL,
- PEDTYPE_SPECIAL,
- PEDTYPE_PROSTITUTE,
PEDTYPE_UNUSED1,
+ PEDTYPE_PROSTITUTE,
+ PEDTYPE_SPECIAL,
PEDTYPE_UNUSED2,
NUM_PEDTYPES
diff --git a/src/control/Replay.cpp b/src/control/Replay.cpp
index a8d87302..a3d8ff1b 100644
--- a/src/control/Replay.cpp
+++ b/src/control/Replay.cpp
@@ -11,6 +11,8 @@
#include "CutsceneMgr.h"
#include "Timer.h"
#include "Weather.h"
+#include "Font.h"
+#include "Text.h"
uint8 &CReplay::Mode = *(uint8*)0x95CD5B;
CAddressInReplayBuffer &CReplay::Record = *(CAddressInReplayBuffer*)0x942F7C;
@@ -223,7 +225,6 @@ WRAPPER bool CReplay::PlayBackThisFrameInterpolation(CAddressInReplayBuffer *buf
WRAPPER void CReplay::FinishPlayback(void) { EAXJMP(0x595B20); }
WRAPPER void CReplay::Shutdown(void) { EAXJMP(0x595BD0); }
WRAPPER void CReplay::ProcessReplayCamera(void) { EAXJMP(0x595C40); }
-WRAPPER void CReplay::Display(void) { EAXJMP(0x595EE0); }
WRAPPER void CReplay::TriggerPlayback(uint8 cam_mode, float cam_x, float cam_y, float cam_z, bool load_scene) { EAXJMP(0x596030); }
WRAPPER void CReplay::StoreStuffInMem(void) { EAXJMP(0x5961F0); }
WRAPPER void CReplay::RestoreStuffFromMem(void) { EAXJMP(0x5966E0); }
@@ -238,6 +239,23 @@ WRAPPER bool CReplay::ShouldStandardCameraBeProcessed(void) { EAXJMP(0x597680);
WRAPPER void CReplay::ProcessLookAroundCam(void) { EAXJMP(0x5976C0); }
WRAPPER size_t CReplay::FindSizeOfPacket(uint8 type) { EAXJMP(0x597CC0); }
+#if 0
+WRAPPER void CReplay::Display(void) { EAXJMP(0x595EE0); }
+#else
+void CReplay::Display()
+{
+ if (CReplay::IsPlayingBack() && CTimer::GetFrameCounter() + 1 & 0x20) {
+ CFont::SetPropOn();
+ CFont::SetBackgroundOff();
+ CFont::SetScale(SCREEN_SCALE_X(1.5f), SCREEN_SCALE_Y(1.5f));
+ CFont::SetAlignment(ALIGN_LEFT);
+ CFont::SetColor(CRGBA(255, 255, 200, 200));
+ CFont::SetFontStyle(FONT_BANK);
+ CFont::PrintString(SCREEN_SCALE_X(63.5f), SCREEN_SCALE_Y(30.0f), TheText.Get("REPLAY"));
+ }
+}
+#endif
+
STARTPATCHES
InjectHook(0x592FC0, PrintElementsInPtrList, PATCH_JUMP);
InjectHook(0x592FE0, CReplay::Init, PATCH_JUMP);
diff --git a/src/main.cpp b/src/main.cpp
index f9ede02d..0dadc131 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -85,6 +85,7 @@ extern void (*DebugMenuProcess)(void);
extern void (*DebugMenuRender)(void);
void DebugMenuInit(void);
+void PrintGameVersion();
RwRGBA gColourTop;
@@ -154,6 +155,7 @@ Idle(void *arg)
}
RenderMenus();
+ PrintGameVersion();
DoFade();
Render2dStuffAfterFade();
CCredits::Render();
@@ -186,6 +188,7 @@ FrontendIdle(void)
DefinedState();
RenderMenus();
+ PrintGameVersion();
DoFade();
Render2dStuffAfterFade();
CFont::DrawFonts();
@@ -772,6 +775,25 @@ AppEventHandler(RsEvent event, void *param)
}
}
+void PrintGameVersion()
+{
+ CFont::SetPropOn();
+ CFont::SetBackgroundOff();
+ CFont::SetScale(SCREEN_SCALE_X(0.7f), SCREEN_SCALE_Y(0.5f));
+ CFont::SetCentreOff();
+ CFont::SetRightJustifyOff();
+ CFont::SetBackGroundOnlyTextOff();
+ CFont::SetFontStyle(FONT_BANK);
+ CFont::SetWrapx(SCREEN_WIDTH);
+ CFont::SetDropShadowPosition(0);
+ CFont::SetDropColor(CRGBA(0, 0, 0, 255));
+ CFont::SetColor(CRGBA(235, 170, 50, 255));
+
+ strcpy(gString, "RE3");
+ AsciiToUnicode(gString, gUString);
+ CFont::PrintString(SCREEN_SCALE_X(10.5f), SCREEN_SCALE_Y(8.0f), gUString);
+}
+
STARTPATCHES
InjectHook(0x48E480, Idle, PATCH_JUMP);
InjectHook(0x48E700, FrontendIdle, PATCH_JUMP);
diff --git a/src/render/Font.h b/src/render/Font.h
index 2e698533..11c0f8ec 100644
--- a/src/render/Font.h
+++ b/src/render/Font.h
@@ -33,6 +33,12 @@ enum {
FONT_HEADING,
};
+enum {
+ ALIGN_LEFT,
+ ALIGN_CENTER,
+ ALIGN_RIGHT,
+};
+
class CFont
{
static CFontDetails &Details;
@@ -56,6 +62,7 @@ public:
static void DrawFonts(void);
static uint16 character_code(uint8 c);
+ static CFontDetails GetDetails() { return Details; }
static void SetScale(float x, float y) { Details.scaleX = x; Details.scaleY = y; }
static void SetSlantRefPoint(float x, float y) { Details.slantRefX = x; Details.slantRefY = y; }
static void SetSlant(float s) { Details.slant = s; }
@@ -86,6 +93,23 @@ public:
static void SetCentreOff(void) {
Details.centre = false;
}
+ static void SetAlignment(uint8 alignment) {
+ if (alignment == ALIGN_LEFT) {
+ CFont::Details.justify = true;
+ CFont::Details.centre = false;
+ CFont::Details.rightJustify = false;
+ }
+ else if (alignment == ALIGN_CENTER) {
+ CFont::Details.justify = false;
+ CFont::Details.centre = true;
+ CFont::Details.rightJustify = false;
+ }
+ else if (alignment == ALIGN_RIGHT) {
+ CFont::Details.justify = false;
+ CFont::Details.centre = false;
+ CFont::Details.rightJustify = true;
+ }
+ }
static void SetWrapx(float x) { Details.wrapX = x; }
static void SetCentreSize(float s) { Details.centreSize = s; }
static void SetBackgroundOn(void) { Details.background = true; }
diff --git a/src/render/Hud.cpp b/src/render/Hud.cpp
index a17d5c2c..9243bc3a 100644
--- a/src/render/Hud.cpp
+++ b/src/render/Hud.cpp
@@ -53,9 +53,9 @@ wchar *CHud::m_PagerMessage = (wchar*)0x878840;
bool &CHud::m_Wants_To_Draw_Hud = *(bool*)0x95CD89;
bool &CHud::m_Wants_To_Draw_3dMarkers = *(bool*)0x95CD62;
wchar(*CHud::m_BigMessage)[128] = (wchar(*)[128])0x664CE0;
-float *CHud::BigMessageInUse = (float*)0x862140;
-float *CHud::BigMessageAlpha = (float*)0x862108;
-float *CHud::BigMessageX = (float*)0x773248;
+float CHud::BigMessageInUse[6];
+float CHud::BigMessageAlpha[6];
+float CHud::BigMessageX[6];
float &CHud::OddJob2OffTimer = *(float*)0x942FA0;
int8 &CHud::CounterOnLastFrame = *(int8*)0x95CD67;
@@ -231,8 +231,8 @@ void CHud::Draw()
CRect rect;
float fWidescreenOffset[2] = { 0.0f, 0.0f };
-
- if (CMenuManager::m_PrefsUseWideScreen) {
+
+ if (FrontEndMenuManager.m_PrefsUseWideScreen) {
fWidescreenOffset[0] = 0.0f;
fWidescreenOffset[1] = SCREEN_SCALE_Y(18.0f);
}
@@ -362,25 +362,32 @@ void CHud::Draw()
/*
DrawAmmo
*/
+ int16 AmmoAmount = CWeaponInfo::GetWeaponInfo(FindPlayerPed()->GetWeapon()->m_eWeaponType)->m_nAmountofAmmunition;
int32 AmmoInClip = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_nAmmoInClip;
int32 TotalAmmo = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_nAmmoTotal;
+ int32 Ammo, Clip;
- if (AmmoInClip <= 1 || AmmoInClip >= 1000) {
+ if (AmmoAmount <= 1 || AmmoAmount >= 1000)
sprintf(sTemp, "%d", TotalAmmo);
- }
else {
if (WeaponType == WEAPONTYPE_FLAMETHROWER) {
- int tot_min_clip_div_10 = (TotalAmmo - AmmoInClip) / 10;
- if (tot_min_clip_div_10 > 9999)
- tot_min_clip_div_10 = 9999;
+ Clip = AmmoInClip / 10;
- sprintf(sTemp, "%d-%d", tot_min_clip_div_10, AmmoInClip / 10);
+ if ((TotalAmmo - AmmoInClip) / 10 <= 9999)
+ Ammo = (TotalAmmo - AmmoInClip) / 10;
+ else
+ Ammo = 9999;
}
else {
- if (AmmoInClip > 9999)
- AmmoInClip = 9999;
- sprintf(sTemp, "%d-%d", (TotalAmmo - AmmoInClip), AmmoInClip);
+ Clip = AmmoInClip;
+
+ if (TotalAmmo - AmmoInClip > 9999)
+ Ammo = 9999;
+ else
+ Ammo = TotalAmmo - AmmoInClip;
}
+
+ sprintf(sTemp, "%d-%d", Ammo, Clip);
}
AsciiToUnicode(sTemp, sPrint);
@@ -580,7 +587,7 @@ void CHud::Draw()
CFont::SetPropOn();
CFont::SetBackgroundOff();
- if (CMenuManager::m_PrefsLanguage == 4)
+ if (FrontEndMenuManager.m_PrefsLanguage == 4)
CFont::SetScale(SCREEN_SCALE_X(1.2f * 0.8f), SCREEN_SCALE_Y(1.2f));
else
CFont::SetScale(SCREEN_SCALE_X(1.2f), SCREEN_SCALE_Y(1.2f));
@@ -676,7 +683,7 @@ void CHud::Draw()
CFont::SetPropOn();
CFont::SetBackgroundOff();
- if (CMenuManager::m_PrefsLanguage != 3 && CMenuManager::m_PrefsLanguage != 4)
+ if (FrontEndMenuManager.m_PrefsLanguage != 3 && FrontEndMenuManager.m_PrefsLanguage != 4)
CFont::SetScale(SCREEN_SCALE_X(1.2f), SCREEN_SCALE_Y(1.2f));
else
CFont::SetScale(SCREEN_SCALE_X(1.2f * 0.85f), SCREEN_SCALE_Y(1.2f));
@@ -976,7 +983,7 @@ void CHud::Draw()
DrawBigMessage
*/
// MissionCompleteFailedText
- if (CHud::m_BigMessage[0][0]) {
+ if (m_BigMessage[0][0]) {
if (BigMessageInUse[0] != 0.0f) {
CFont::SetJustifyOff();
CFont::SetBackgroundOff();
@@ -1251,7 +1258,7 @@ void CHud::DrawAfterFade()
CFont::SetJustifyOff();
CFont::SetBackgroundOff();
- if (CGame::frenchGame || CMenuManager::m_PrefsLanguage == 4)
+ if (CGame::frenchGame || FrontEndMenuManager.m_PrefsLanguage == 4)
CFont::SetScale(SCREEN_SCALE_X(0.884f), SCREEN_SCALE_Y(1.36f));
else
CFont::SetScale(SCREEN_SCALE_X(1.04f), SCREEN_SCALE_Y(1.6f));
diff --git a/src/render/Hud.h b/src/render/Hud.h
index 8f4b6fb6..260e5312 100644
--- a/src/render/Hud.h
+++ b/src/render/Hud.h
@@ -62,9 +62,9 @@ public:
static bool &m_Wants_To_Draw_Hud;
static bool &m_Wants_To_Draw_3dMarkers;
static wchar(*m_BigMessage)[128];
- static float *BigMessageInUse;
- static float *BigMessageAlpha;
- static float *BigMessageX;
+ static float BigMessageInUse[6];
+ static float BigMessageAlpha[6];
+ static float BigMessageX[6];
static float &OddJob2OffTimer;
static int8 &CounterOnLastFrame;
static float &OddJob2XOffset;
diff --git a/src/skel/win/win.cpp b/src/skel/win/win.cpp
index a8abe1dd..814cac84 100644
--- a/src/skel/win/win.cpp
+++ b/src/skel/win/win.cpp
@@ -633,8 +633,10 @@ psInitialise(void)
C_PcSave::SetSaveDirectory(_psGetUserFilesFolder());
- InitialiseLanguage();
-
+#ifndef NASTY_GAME
+ InitialiseLanguage();
+#endif
+
FrontEndMenuManager.LoadSettings();
gGameState = GS_START_UP;
diff --git a/src/skel/win/win.h b/src/skel/win/win.h
index d3b0169f..371b9e44 100644
--- a/src/skel/win/win.h
+++ b/src/skel/win/win.h
@@ -78,6 +78,8 @@ RwBool _psSetVideoMode(RwInt32 subSystem, RwInt32 videoMode);
void CenterVideo(void);
void CloseClip(void);
+RwChar **_psGetVideoModeList();
+
#ifdef __cplusplus
}
#endif /* __cplusplus */