rpgxef/code/ui/ui_turbolift.cpp
Walter Julius Hennecke 9cac290629 Make all game code projects compile as cpp code
- Fixed all errors that occured due to using c++ compiler
- changed c++ standart to c++17
- removed lua, added library instead
- made all bg_* and q_* file into a shared item project
2017-09-30 21:49:31 +02:00

649 lines
16 KiB
C++

/**********************************************************************
UI_TURBOLIFT.C
User interface trigger from within game
**********************************************************************/
#include "ui_local.h"
#include "ui_logger.h"
typedef struct
{
int32_t deckNum;
char deckDesc[MAX_QPATH];
} deckData_t;
// Data for Closing Credits Menu
typedef struct //static
{
menuframework_s menu;
int32_t maxDecks;
int32_t chosenDeck;
int32_t highLightedDeck;
sfxHandle_t openingVoice;
menubitmap_s quitmenu;
menubitmap_s engage;
menubitmap_s deck1;
menubitmap_s deck2;
menubitmap_s deck3;
menubitmap_s deck4;
menubitmap_s deck5;
menubitmap_s deck6;
menubitmap_s deck7;
menubitmap_s deck8;
menubitmap_s deck9;
menubitmap_s deck10;
menubitmap_s deck11;
menubitmap_s deck12;
menubitmap_s deck13;
menubitmap_s deck14;
menubitmap_s deck15;
menubitmap_s deck16;
deckData_t deckData[MAX_DECKS];
int32_t numDecks;
int32_t liftNum;
} turbolift_t;
turbolift_t s_turbolift;
void TurboliftMenu_LoadText(void);
enum ui_turboliftIDs_e {
ID_ARROW1UP = 2,
ID_ARROW1DOWN,
ID_ARROW2UP,
ID_ARROW2DOWN,
ID_COMPUTERVOICE,
ID_QUIT = 10,
ID_DECK1,
ID_DECK2,
ID_DECK3,
ID_DECK4,
ID_DECK5,
ID_DECK6,
ID_DECK7,
ID_DECK8,
ID_DECK9,
ID_DECK10,
ID_DECK11,
ID_DECK12,
ID_DECK13,
ID_DECK14,
ID_DECK15,
ID_DECK16,
ID_ENGAGE = 100
};
void UI_HolodeckMenu_Cache(void);
/*
=================
M_Turbolift_Event
=================
*/
static void M_Turbolift_Event(void* ptr, int32_t notification)
{
int32_t id;
menubitmap_s *holdDeck;
id = ((menucommon_s*)ptr)->id;
UI_LogFuncBegin();
/*if ( notification != QM_ACTIVATED )
{
return;
}*/
switch (id)
{
case ID_QUIT:
if (notification == QM_ACTIVATED)
UI_PopMenu();
break;
case ID_DECK1:
case ID_DECK2:
case ID_DECK3:
case ID_DECK4:
case ID_DECK5:
case ID_DECK6:
case ID_DECK7:
case ID_DECK8:
case ID_DECK9:
case ID_DECK10:
case ID_DECK11:
case ID_DECK12:
case ID_DECK13:
case ID_DECK14:
case ID_DECK15:
case ID_DECK16:
if (notification == QM_ACTIVATED)
{
if (s_turbolift.chosenDeck >= 0)
{
holdDeck = &s_turbolift.deck1;
holdDeck += s_turbolift.chosenDeck;
holdDeck->textcolor = CT_BLACK;
}
s_turbolift.chosenDeck = id - ID_DECK1;
s_turbolift.engage.generic.flags = QMF_HIGHLIGHT_IF_FOCUS;
holdDeck = &s_turbolift.deck1;
holdDeck += s_turbolift.chosenDeck;
//holdDeck->textcolor = CT_WHITE;//CT_LTGOLD1;
}
else if (notification == QM_GOTFOCUS)
{
s_turbolift.highLightedDeck = id - ID_DECK1;
}
break;
case ID_ENGAGE: // Active only if a deck has been chosen
if (notification == QM_ACTIVATED) {
UI_ForceMenuOff();
trap_Cmd_ExecuteText(EXEC_APPEND, va("deck %i %i", s_turbolift.liftNum, s_turbolift.deckData[s_turbolift.chosenDeck].deckNum));
}
break;
}
UI_LogFuncEnd();
}
/*
=================
TurboliftMenu_Key
=================
*/
sfxHandle_t TurboliftMenu_Key(int32_t key)
{
return (Menu_DefaultKey(&s_turbolift.menu, key));
}
qhandle_t leftRound;
qhandle_t corner_ul_24_60;
qhandle_t corner_ll_12_60;
qhandle_t turbolift;
/*
=================
M_TurboliftMenu_Graphics
=================
*/
static void M_TurboliftMenu_Graphics(void)
{
menubitmap_s *holdDeck;
int32_t i, length, xTurboStart;
int32_t numColor, roundColor;
UI_LogFuncBegin();
// Draw the basic screen frame
// Upper corners
trap_R_SetColor(colorTable[CT_DKPURPLE1]);
UI_DrawHandlePic(20, 24, 64, 32, corner_ul_24_60); // Upper corner
UI_DrawHandlePic(20, 353, 64, 16, corner_ll_12_60); // Lower Corner
trap_R_SetColor(colorTable[CT_LTPURPLE1]); //colorTable[CT_LTBLUE1] //[CT_DKGOLD1] //colorTable[CT_VDKPURPLE2]
UI_DrawHandlePic(100, 86, 128, 128, turbolift); // Turbolift graphic
// Lower corners
trap_R_SetColor(colorTable[CT_DKPURPLE3]); //colorTable[CT_VDKPURPLE2]
UI_DrawHandlePic(20, 375, 64, -16, corner_ll_12_60); //
UI_DrawHandlePic(20, 440, 64, 16, corner_ll_12_60); //
xTurboStart = 604;
length = UI_ProportionalStringWidth(menu_normal_text[MNT_TURBOLIFT], UI_BIGFONT);
length += 4;
// Upper half
trap_R_SetColor(colorTable[CT_DKPURPLE1]); //DKGOLD1
UI_DrawHandlePic(79, 24, xTurboStart - (79 + length), PROP_BIG_HEIGHT, uis.whiteShader); // Top left line
UI_DrawHandlePic(20, 60, 60, 40, uis.whiteShader); //
trap_R_SetColor(colorTable[CT_DKPURPLE3]);
UI_DrawHandlePic(20, 106, 60, 11, uis.whiteShader); //
trap_R_SetColor(colorTable[CT_DKPURPLE1]); //DKGOLD1
UI_DrawHandlePic(20, 123, 60, 240, uis.whiteShader); // Left hand column
UI_DrawHandlePic(69, 356, 245, 12, uis.whiteShader); //
trap_R_SetColor(colorTable[CT_DKPURPLE3]); //colorTable[CT_DKPURPLE1]
UI_DrawHandlePic(319, 356, 93, 5, uis.whiteShader); //
UI_DrawHandlePic(319, 360, 31, 8, uis.whiteShader); //
UI_DrawHandlePic(381, 360, 31, 8, uis.whiteShader); //
trap_R_SetColor(colorTable[CT_DKPURPLE1]);
UI_DrawHandlePic(417, 356, 93, 12, uis.whiteShader); //
UI_DrawHandlePic(510, 356, 114, 12, uis.whiteShader); //
// Lower half
trap_R_SetColor(colorTable[CT_DKPURPLE3]); //colorTable[CT_VDKPURPLE2]
UI_DrawHandlePic(20, 380, 60, 70, uis.whiteShader); // Left Column
trap_R_SetColor(colorTable[CT_DKPURPLE3]); //colorTable[CT_VDKPURPLE2]
UI_DrawHandlePic(69, 376, 158, 12, uis.whiteShader); // Top line
UI_DrawHandlePic(232, 376, 82, 12, uis.whiteShader); // Top line
UI_DrawHandlePic(417, 376, 12, 12, uis.whiteShader); //
UI_DrawHandlePic(434, 376, 190, 12, uis.whiteShader); //
// Funky indent
trap_R_SetColor(colorTable[CT_DKPURPLE1]); //colorTable[CT_DKGOLD1]
UI_DrawHandlePic(319, 383, 93, 5, uis.whiteShader); //
UI_DrawHandlePic(319, 376, 31, 8, uis.whiteShader); //
UI_DrawHandlePic(381, 376, 31, 8, uis.whiteShader); //
// Bottom line
trap_R_SetColor(colorTable[CT_DKPURPLE3]); //colorTable[CT_VDKPURPLE2]
UI_DrawHandlePic(69, 443, 287, 12, uis.whiteShader); //
trap_R_SetColor(colorTable[CT_DKPURPLE1]); //colorTable[CT_DKGOLD1]
UI_DrawHandlePic(364, 443, 260, 12, uis.whiteShader); // Bottom line
UI_DrawProportionalString(xTurboStart, 24,
menu_normal_text[MNT_TURBOLIFT], UI_BIGFONT | UI_RIGHT, colorTable[CT_WHITE]);
trap_R_SetColor(colorTable[CT_DKPURPLE1]); //DKGOLD1
UI_DrawHandlePic(607, 24, -16, 32, leftRound);
holdDeck = &s_turbolift.deck1;
// Print deck buttons
for (i = 0; i < s_turbolift.maxDecks; i++)
{
if (s_turbolift.deckData[i].deckNum)
{
if (s_turbolift.chosenDeck == i) // This deck was chosen
{
numColor = CT_WHITE;//CT_LTGOLD1;
roundColor = CT_LTPURPLE1;//CT_LTGOLD1;
}
else // This deck was not chosen
{
numColor = CT_WHITE;
roundColor = CT_DKPURPLE1;//CT_DKGOLD1;
}
UI_DrawProportionalString(holdDeck->generic.x - 6,
holdDeck->generic.y,
va("%d", s_turbolift.deckData[i].deckNum), UI_BIGFONT | UI_RIGHT, colorTable[numColor]); //i+1
trap_R_SetColor(colorTable[roundColor]);
UI_DrawHandlePic(holdDeck->generic.x - 45,
holdDeck->generic.y,
16, 32, leftRound);
}
holdDeck++;
}
if (s_turbolift.highLightedDeck >= 0)
{
UI_DrawProportionalString(353, 409,
s_turbolift.deckData[s_turbolift.highLightedDeck].deckDesc, UI_SMALLFONT | UI_CENTER, colorTable[CT_WHITE]);
}
else
{
UI_DrawProportionalString(353, 409, menu_normal_text[MNT_SPECFICYDECK], UI_SMALLFONT | UI_CENTER, colorTable[CT_WHITE]);
}
// Round graphic on left of engage & quit button
trap_R_SetColor(colorTable[s_turbolift.quitmenu.color]);
UI_DrawHandlePic(s_turbolift.engage.generic.x - 14,
s_turbolift.engage.generic.y,
MENU_BUTTON_MED_HEIGHT, s_turbolift.engage.height, uis.graphicButtonLeftEnd);
UI_DrawHandlePic(s_turbolift.quitmenu.generic.x - 14,
s_turbolift.quitmenu.generic.y,
MENU_BUTTON_MED_HEIGHT, s_turbolift.quitmenu.height, uis.graphicButtonLeftEnd);
UI_LogFuncEnd();
}
/*
===============
TurboliftMenu_Draw
===============
*/
static void TurboliftMenu_Draw(void)
{
UI_LogFuncBegin();
// Draw graphics particular to Main Menu
M_TurboliftMenu_Graphics();
Menu_Draw(&s_turbolift.menu);
UI_LogFuncEnd();
}
/*
===============
UI_TurboliftMenu_Cache
===============
*/
void UI_TurboliftMenu_Cache(void)
{
UI_LogFuncBegin();
leftRound = trap_R_RegisterShaderNoMip("menu/common/halfroundl_24.tga");
corner_ul_24_60 = trap_R_RegisterShaderNoMip("menu/common/corner_ul_24_60.tga");
corner_ll_12_60 = trap_R_RegisterShaderNoMip("menu/common/corner_ll_12_60.tga");
turbolift = trap_R_RegisterShaderNoMip("menu/common/lift_button.tga");
UI_LogFuncEnd();
}
//Sorts decks in ascending order
static int32_t QDECL SortDecks(const void *arg1, const void *arg2)
{
int32_t deck1;
int32_t deck2;
UI_LogFuncBegin();
deck1 = ((deckData_t *)arg1)->deckNum;
deck2 = ((deckData_t *)arg2)->deckNum;
if (deck1 < 0)
deck1 = 0;
if (deck2 < 0)
deck2 = 0;
if (deck1 > deck2){
UI_LogFuncEnd();
return 1;
}
if (deck1 == deck2){
UI_LogFuncEnd();
return 0;
}
UI_LogFuncEnd();
return -1;
}
static void UI_TurboliftMenu_LoadDecks(void)
{
char buffer[MAX_TOKEN_CHARS];
int32_t i;
char *temp;
s_turbolift.numDecks = 0;
UI_LogFuncBegin();
//load the string
trap_GetConfigString(CS_TURBOLIFT_DATA, buffer, sizeof(buffer));
if (!buffer[0]){
UI_LogFuncEnd();
return;
}
memset(&s_turbolift.deckData, 0, sizeof(s_turbolift.deckData));
for (i = 0; i < MAX_DECKS; i++)
{
temp = Info_ValueForKey(buffer, va("d%i", i));
if (!temp[0])
break;
s_turbolift.deckData[s_turbolift.numDecks].deckNum = atoi(temp);
temp = Info_ValueForKey(buffer, va("n%i", i));
Q_strncpyz(s_turbolift.deckData[s_turbolift.numDecks].deckDesc, temp, sizeof(s_turbolift.deckData[s_turbolift.numDecks].deckDesc));
s_turbolift.numDecks++;
}
//TiM - sort the decks into their sequential order
qsort(s_turbolift.deckData, s_turbolift.numDecks, sizeof(deckData_t), SortDecks);
UI_LogFuncEnd();
}
static void UI_ManageDeckLoading(void)
{
char fileRoute[MAX_QPATH];
char mapRoute[MAX_QPATH];
char info[MAX_TOKEN_CHARS];
fileHandle_t f;
int32_t file_len;
char *textPtr;
char buffer[20000];
char *token;
UI_LogFuncBegin();
//get the map name
trap_GetConfigString(CS_SERVERINFO, info, sizeof(info));
Com_sprintf(mapRoute, sizeof(fileRoute), "maps/%s", Info_ValueForKey(info, "mapname"));
//check for language
UI_LanguageFilename(mapRoute, "turbolift", fileRoute);
file_len = trap_FS_FOpenFile(fileRoute, &f, FS_READ);
if (file_len <= 1)
{
//UI_Logger( LL_WARN, "Attempted to load %s, but wasn't found.\n", fileRoute );
UI_TurboliftMenu_LoadDecks();
UI_LogFuncEnd();
return;
}
trap_FS_Read(buffer, file_len, f);
trap_FS_FCloseFile(f);
if (!buffer[0])
{
UI_Logger(LL_ERROR, "Attempted to load %s, but no data was read.\n", fileRoute);
UI_TurboliftMenu_LoadDecks();
UI_LogFuncEnd();
return;
}
s_turbolift.numDecks = 0;
memset(&s_turbolift.deckData, 0, sizeof(s_turbolift.deckData));
buffer[file_len] = '\0';
COM_BeginParseSession();
textPtr = buffer;
//UI_Logger( LL_DEBUG, "Beginning Parse\n" );
//expected format is 'decknum' <space> 'deck Desc'
while (1)
{
token = COM_Parse(&textPtr);
if (!token[0])
break;
//UI_Logger( LL_DEBUG, "First Token: %s\n", token );
//in case of Scooter's EF SP style DAT files, which require 'DECK' in front of the number
if (!Q_strncmp(token, "DECK", 4))
token += 4;
//grab the deck number
s_turbolift.deckData[s_turbolift.numDecks].deckNum = atoi(token);
token = COM_ParseExt(&textPtr, qfalse);
if (!token[0])
continue;
//UI_Logger( LL_DEBUG, "Second Token: %s\n", token );
Q_strncpyz(s_turbolift.deckData[s_turbolift.numDecks].deckDesc,
token,
sizeof(s_turbolift.deckData[s_turbolift.numDecks].deckDesc));
s_turbolift.numDecks++;
//if this is an EF SP style script, there may be more data after these two. ignore them
if (COM_ParseExt(&textPtr, qfalse) == NULL)
SkipRestOfLine(&textPtr);
}
qsort(s_turbolift.deckData, s_turbolift.numDecks, sizeof(deckData_t), SortDecks);
UI_LogFuncEnd();
}
/*
===============
TurboliftMenu_Init
===============
*/
void TurboliftMenu_Init(void)
{
int32_t y, pad, x;
menubitmap_s *holdDeck;
int32_t i, width;
UI_LogFuncBegin();
UI_ManageDeckLoading();
s_turbolift.menu.nitems = 0;
s_turbolift.menu.draw = TurboliftMenu_Draw;
s_turbolift.menu.key = TurboliftMenu_Key;
s_turbolift.menu.wrapAround = qtrue;
s_turbolift.menu.descX = MENU_DESC_X;
s_turbolift.menu.descY = MENU_DESC_Y;
s_turbolift.menu.titleX = MENU_TITLE_X;
s_turbolift.menu.titleY = MENU_TITLE_Y;
s_turbolift.chosenDeck = -1;
s_turbolift.highLightedDeck = -1;
pad = PROP_BIG_HEIGHT + 10;
y = 72;
x = 319;
width = MENU_BUTTON_MED_WIDTH - 20;
s_turbolift.maxDecks = MAX_DECKS;
holdDeck = &s_turbolift.deck1;
for (i = 0; i < s_turbolift.maxDecks; i++)
{
holdDeck->generic.type = MTYPE_BITMAP;
holdDeck->generic.flags = QMF_HIGHLIGHT_IF_FOCUS;
holdDeck->generic.x = x;
holdDeck->generic.y = y;
holdDeck->generic.name = GRAPHIC_BUTTONRIGHT;
holdDeck->generic.id = ID_DECK1 + i;
holdDeck->generic.callback = M_Turbolift_Event;
holdDeck->width = width;
holdDeck->height = PROP_BIG_HEIGHT;
holdDeck->color = CT_DKPURPLE1;//CT_VDKRED1;//CT_DKGOLD1;
holdDeck->color2 = CT_LTPURPLE1;//CT_DKRED1;//CT_LTGOLD1;
holdDeck->textX = MENU_BUTTON_TEXT_X;
holdDeck->textY = 12;
holdDeck->textEnum = MBT_DECK;
holdDeck->textcolor = CT_BLACK;
holdDeck->textcolor2 = CT_WHITE;
holdDeck->textStyle = UI_TINYFONT;
holdDeck++;
y += pad;
// Start the next column
if (i == ((s_turbolift.maxDecks - 1) / 2))
{
x += width + 90;
y = 80;
}
}
s_turbolift.engage.generic.type = MTYPE_BITMAP;
s_turbolift.engage.generic.flags = QMF_GRAYED;
s_turbolift.engage.generic.x = 110;
s_turbolift.engage.generic.y = 72 + (pad * 5);
s_turbolift.engage.generic.name = GRAPHIC_BUTTONRIGHT;
s_turbolift.engage.generic.id = ID_ENGAGE;
s_turbolift.engage.generic.callback = M_Turbolift_Event;
s_turbolift.engage.width = width;
s_turbolift.engage.height = PROP_BIG_HEIGHT;
s_turbolift.engage.color = CT_DKORANGE;
s_turbolift.engage.color2 = CT_LTORANGE;
s_turbolift.engage.textX = MENU_BUTTON_TEXT_X;
s_turbolift.engage.textY = 6;
s_turbolift.engage.textEnum = MBT_ENGAGE;
s_turbolift.engage.textcolor = CT_BLACK;
s_turbolift.engage.textcolor2 = CT_WHITE;
//s_turbolift.engage.generic.statusbarfunc = Turbolift_StatusBar;
s_turbolift.quitmenu.generic.type = MTYPE_BITMAP;
s_turbolift.quitmenu.generic.flags = QMF_HIGHLIGHT_IF_FOCUS;
s_turbolift.quitmenu.generic.x = 110;
s_turbolift.quitmenu.generic.y = 72 + (pad * 7);
s_turbolift.quitmenu.generic.name = GRAPHIC_BUTTONRIGHT;
s_turbolift.quitmenu.generic.id = ID_QUIT;
s_turbolift.quitmenu.generic.callback = M_Turbolift_Event;
s_turbolift.quitmenu.width = width;
s_turbolift.quitmenu.height = PROP_BIG_HEIGHT;
s_turbolift.quitmenu.color = CT_DKORANGE;
s_turbolift.quitmenu.color2 = CT_LTORANGE;
s_turbolift.quitmenu.textX = MENU_BUTTON_TEXT_X;
s_turbolift.quitmenu.textY = 6;
s_turbolift.quitmenu.textEnum = MBT_RETURNMENU;//MBT_RETURN;
s_turbolift.quitmenu.textcolor = CT_BLACK;
s_turbolift.quitmenu.textcolor2 = CT_WHITE;
//s_turbolift.quitmenu.generic.statusbarfunc = Turbolift_StatusBar;
Menu_AddItem(&s_turbolift.menu, &s_turbolift.engage);
Menu_AddItem(&s_turbolift.menu, &s_turbolift.quitmenu);
holdDeck = &s_turbolift.deck1;
for (i = 0; i < s_turbolift.maxDecks; i++)
{
if (s_turbolift.deckData[i].deckDesc[0])
{
Menu_AddItem(&s_turbolift.menu, holdDeck);
}
holdDeck++;
}
UI_LogFuncEnd();
}
/*
===============
UI_TurboliftMenu
===============
*/
void UI_TurboliftMenu(int32_t liftNum)
{
UI_LogFuncBegin();
if (!liftNum){
UI_LogFuncEnd();
return;
}
memset(&s_turbolift, 0, sizeof(s_turbolift));
s_turbolift.liftNum = liftNum;
uis.menusp = 0;
ingameFlag = qtrue; // true when in game menu is in use
Mouse_Show();
UI_TurboliftMenu_Cache();
TurboliftMenu_Init();
UI_PushMenu(&s_turbolift.menu);
Menu_AdjustCursor(&s_turbolift.menu, 1);
UI_LogFuncEnd();
}