/* Copyright (C) 1997-2001 Id Software, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // // m_mp_player.c // #include "m_local.h" /* ============================================================================= PLAYER CONFIG MENU ============================================================================= */ #define MAX_PLAYERMODELS 512 #define MAX_PLAYERSKINS 512 typedef struct modelInfo_s { int numSkins; char **skinDisplayNames; char displayName[16]; char directory[MAX_QPATH]; } modelInfo_t; typedef struct m_playerConfigMenu_s { // Player model info qBool modelsFound; modelInfo_t modelInfo[MAX_PLAYERMODELS]; char *modelNames[MAX_PLAYERMODELS]; int numPlayerModels; // Menu items uiFrameWork_t frameWork; uiImage_t banner; uiAction_t header; uiField_t nameField; uiList_t modelList; uiList_t skinList; uiList_t handednessList; uiList_t rateList; uiAction_t backAction; } m_playerConfigMenu_t; static m_playerConfigMenu_t m_playerConfigMenu; static int rateTable[] = { 2500, 3200, 5000, 10000, 25000, 0 }; static void HandednessCallback (void *unused) { cgi.Cvar_SetValue ("hand", m_playerConfigMenu.handednessList.curValue, qFalse); } static void RateCallback (void *unused) { if (m_playerConfigMenu.rateList.curValue != sizeof (rateTable) / sizeof (*rateTable) - 1) cgi.Cvar_SetValue ("rate", rateTable[m_playerConfigMenu.rateList.curValue], qFalse); } static void ModelCallback (void *unused) { if (m_playerConfigMenu.modelList.curValue >= m_playerConfigMenu.numPlayerModels) m_playerConfigMenu.modelList.curValue = m_playerConfigMenu.numPlayerModels-1; m_playerConfigMenu.skinList.itemNames = m_playerConfigMenu.modelInfo[m_playerConfigMenu.modelList.curValue].skinDisplayNames; m_playerConfigMenu.skinList.curValue = 0; UI_SetupItem (&m_playerConfigMenu.skinList); } /* ============= PlayerConfig_ScanDirectories ============= */ static qBool PlayerConfig_ScanDirectories (void) { char *modelList[MAX_PLAYERMODELS]; char *skinList[MAX_PLAYERSKINS]; char **modelSkins; char scratch[1024]; char directory[1024]; int numModels; int numSkins; int numModelSkins; int i, j, k; char *p; m_playerConfigMenu.numPlayerModels = 0; // Model list numModels = cgi.FS_FindFiles ("players", "players/*/tris.md*", "md*", modelList, MAX_PLAYERMODELS, qFalse, qTrue); if (!numModels) return qFalse; for (i=0 ; i 0); } /* ============= PlayerConfigMenu_Init ============= */ static int pmicmpfnc (const void *_a, const void *_b) { const modelInfo_t *a = (const modelInfo_t *) _a; const modelInfo_t *b = (const modelInfo_t *) _b; /* ** sort by male, female, then alphabetical */ if (strcmp (a->directory, "male") == 0) return -1; else if (strcmp (b->directory, "male") == 0) return 1; if (strcmp (a->directory, "female") == 0) return -1; else if (strcmp (b->directory, "female") == 0) return 1; return strcmp (a->directory, b->directory); } static void PlayerConfigMenu_Init (void) { char currentDirectory[1024]; int currentDirectoryIndex; char currentSkin[1024]; int currentSkinIndex; int i, j; static char *rateNames[] = { "28.8 Modem", "33.6 Modem", "Single ISDN", "Dual ISDN/Cable", "T1/LAN", "User defined", 0 }; static char *handedness[] = { "right", "left", "center", 0 }; currentDirectoryIndex = 0; currentSkinIndex = 0; // clamp "hand" if (cgi.Cvar_GetIntegerValue ("hand") < 0 || cgi.Cvar_GetIntegerValue ("hand") > 2) cgi.Cvar_SetValue ("hand", 0, qFalse); // find current directory and skin Q_strncpyz (currentDirectory, cgi.Cvar_GetStringValue ("skin"), sizeof (currentDirectory)); if (strchr (currentDirectory, '/')) { Q_strncpyz (currentSkin, strchr (currentDirectory, '/') + 1, sizeof (currentSkin)); *strchr (currentDirectory, '/' ) = 0; } else if (strchr (currentDirectory, '\\')) { Q_strncpyz (currentSkin, strchr (currentDirectory, '\\') + 1, sizeof (currentSkin)); *strchr (currentDirectory, '\\') = 0; } else { Q_strncpyz (currentDirectory, "male", sizeof (currentDirectory)); Q_strncpyz (currentSkin, "grunt", sizeof (currentSkin)); } // sort qsort (m_playerConfigMenu.modelInfo, m_playerConfigMenu.numPlayerModels, sizeof (m_playerConfigMenu.modelInfo[0]), pmicmpfnc); // generate model and skin list memset (m_playerConfigMenu.modelNames, 0, sizeof (m_playerConfigMenu.modelNames)); for (i=0 ; i 360) yaw = 0; memset (entity, 0, sizeof (refEntity_t) * 2); // Player entity[0].model = cgi.R_RegisterModel (Q_VarArgs ("players/%s/tris.md2", m_playerConfigMenu.modelInfo[m_playerConfigMenu.modelList.curValue].directory)); if (entity[0].model) { entity[0].skin = cgi.R_RegisterSkin (Q_VarArgs ("players/%s/%s.pcx", m_playerConfigMenu.modelInfo[m_playerConfigMenu.modelList.curValue].directory, m_playerConfigMenu.modelInfo[m_playerConfigMenu.modelList.curValue].skinDisplayNames[m_playerConfigMenu.skinList.curValue])); if (entity[0].skin) { entity[0].origin[0] = entity[0].oldOrigin[0] = refDef.x; entity[0].origin[1] = entity[0].oldOrigin[1] = 0; entity[0].origin[2] = entity[0].oldOrigin[2] = 0; entity[0].color[0] = 255; entity[0].color[1] = 255; entity[0].color[2] = 255; entity[0].color[3] = 255; entity[0].flags = RF_DEPTHHACK|RF_NOSHADOW; entity[0].frame = 0; entity[0].oldFrame = 0; entity[0].backLerp = 0.0; entity[0].scale = 1; angles[0] = 0; angles[1] = yaw; angles[2] = 0; Angles_Matrix3 (angles, entity[0].axis); } } // Weapon entity[1].model = cgi.R_RegisterModel (Q_VarArgs ("players/%s/weapon.md2", m_playerConfigMenu.modelInfo[m_playerConfigMenu.modelList.curValue].directory)); if (0) { //entity[1].model) { entity[1].origin[0] = entity[1].oldOrigin[0] = refDef.x; entity[1].origin[1] = entity[1].oldOrigin[1] = 0; entity[1].origin[2] = entity[1].oldOrigin[2] = 0; entity[1].color[0] = 255; entity[1].color[1] = 255; entity[1].color[2] = 255; entity[1].color[3] = 255; entity[1].flags = RF_DEPTHHACK|RF_NOSHADOW; entity[1].frame = 0; entity[1].oldFrame = 0; entity[1].backLerp = 0.0; entity[1].scale = 1; angles[0] = 0; angles[1] = yaw; angles[2] = 0; Angles_Matrix3 (angles, entity[1].axis); } // Clear the scene and add the entities cgi.R_ClearScene (); if (entity[0].skin) { cgi.R_AddEntity (&entity[0]); if (entity[1].model) cgi.R_AddEntity (&entity[1]); } // Render the scene cgi.R_RenderScene (&refDef); // Pic selection icon = cgi.R_RegisterPic (Q_VarArgs ("players/%s/%s_i.pcx", m_playerConfigMenu.modelInfo[m_playerConfigMenu.modelList.curValue].directory, m_playerConfigMenu.modelInfo[m_playerConfigMenu.modelList.curValue].skinDisplayNames[m_playerConfigMenu.skinList.curValue])); if (icon) { int width; int height; cgi.R_GetImageSize (icon, &width, &height); cgi.R_DrawPic (icon, 0, refDef.x - (width * UIFT_SCALE), refDef.y, width*UIFT_SCALE, height*UIFT_SCALE, 0, 0, 1, 1, Q_colorWhite); } } /* ============= UI_PlayerConfigMenu_f ============= */ void UI_PlayerConfigMenu_f (void) { float midrow = (cg.refConfig.vidWidth*0.5) - (18*UIFT_SIZEMED); float midcol = (cg.refConfig.vidHeight*0.5) - (3*UIFT_SIZEMED); // show box UI_DrawTextBox (midrow, midcol, UIFT_SCALEMED, 36, 4); cgi.R_DrawString (NULL, midrow + (UIFT_SIZEMED*2), midcol + UIFT_SIZEMED, UIFT_SCALEMED, UIFT_SCALEMED, 0, " --- PLEASE WAIT! --- ", Q_colorGreen); cgi.R_DrawString (NULL, midrow + (UIFT_SIZEMED*2), midcol + (UIFT_SIZEMED*2), UIFT_SCALEMED, UIFT_SCALEMED, 0, "Player models, skins and icons are", Q_colorGreen); cgi.R_DrawString (NULL, midrow + (UIFT_SIZEMED*2), midcol + (UIFT_SIZEMED*3), UIFT_SCALEMED, UIFT_SCALEMED, 0, "being listed, and this might take ", Q_colorGreen); cgi.R_DrawString (NULL, midrow + (UIFT_SIZEMED*2), midcol + (UIFT_SIZEMED*4), UIFT_SCALEMED, UIFT_SCALEMED, 0, "a minute so, please be patient. ", Q_colorGreen); cgi.R_EndFrame (); // the text box won't show up unless we do a buffer swap // load models m_playerConfigMenu.modelsFound = PlayerConfig_ScanDirectories (); PlayerConfigMenu_Init (); M_PushMenu (&m_playerConfigMenu.frameWork, PlayerConfigMenu_Draw, PlayerConfigMenu_Close, M_KeyHandler); }