1 /*
2 Copyright (C) 2003-2006 Andrey Nazarov
3 
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8 
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 
13 See the GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18 
19 */
20 
21 #include "ui_local.h"
22 
23 
24 
25 /*
26 =============================================================================
27 
28 PLAYER CONFIG MENU
29 
30 =============================================================================
31 */
32 
33 #define ID_MODEL 103
34 #define ID_SKIN	104
35 
36 typedef struct m_playerConfig_s {
37 	menuFrameWork_t	menu;
38 	menuField_t		nameField;
39 	menuSpinControl_t		modelBox;
40 	menuSpinControl_t		skinBox;
41 	menuSpinControl_t		handBox;
42 	menuAction_t	downloadAction;
43 	menuAction_t	back;
44 	menuAction_t	apply;
45 	menuStatic_t	banner;
46 
47 	refdef_t	refdef;
48 	entity_t	entities[2];
49 
50 	int		time;
51 	int		oldTime;
52 
53 	char *pmnames[MAX_PLAYERMODELS];
54 } m_playerConfig_t;
55 
56 static m_playerConfig_t	m_playerConfig;
57 
58 static const char *handedness[] = {
59 	"right",
60 	"left",
61 	"center",
62 	0
63 };
64 
ApplyChanges(void)65 static void ApplyChanges( void ) {
66 	char scratch[MAX_OSPATH];
67 
68 	cvar.Set( "name", m_playerConfig.nameField.field.text );
69 
70 	Com_sprintf( scratch, sizeof( scratch ), "%s/%s",
71 		uis.pmi[m_playerConfig.modelBox.curvalue].directory,
72 		uis.pmi[m_playerConfig.modelBox.curvalue].skindisplaynames[m_playerConfig.skinBox.curvalue] );
73 
74 	cvar.Set( "skin", scratch );
75 
76 	cvar.SetInteger( "hand", m_playerConfig.handBox.curvalue );
77 }
78 
ReloadMedia(void)79 static void ReloadMedia( void ) {
80 	char scratch[MAX_QPATH];
81 
82 	Com_sprintf( scratch, sizeof( scratch ), "players/%s/tris.md2", uis.pmi[m_playerConfig.modelBox.curvalue].directory );
83 	m_playerConfig.entities[0].model = ref.RegisterModel( scratch );
84 	Com_sprintf( scratch, sizeof( scratch ), "players/%s/%s.pcx", uis.pmi[m_playerConfig.modelBox.curvalue].directory, uis.pmi[m_playerConfig.modelBox.curvalue].skindisplaynames[m_playerConfig.skinBox.curvalue] );
85 	m_playerConfig.entities[0].skin = ref.RegisterSkin( scratch );
86 
87 	Com_sprintf( scratch, sizeof( scratch ), "players/%s/w_railgun.md2", uis.pmi[m_playerConfig.modelBox.curvalue].directory );
88 	m_playerConfig.entities[1].model = ref.RegisterModel( scratch );
89 }
90 
PlayerConfig_RunFrame(void)91 static void PlayerConfig_RunFrame( void ) {
92 	int frame;
93 
94 	if( m_playerConfig.time < uis.realtime ) {
95 		m_playerConfig.oldTime = m_playerConfig.time;
96 
97 		m_playerConfig.time += 120;
98 		if( m_playerConfig.time < uis.realtime ) {
99 			m_playerConfig.time = uis.realtime;
100 		}
101 
102 		frame = ( m_playerConfig.time / 120 ) % 40;
103 
104 		m_playerConfig.entities[0].oldframe = m_playerConfig.entities[0].frame;
105 		m_playerConfig.entities[1].oldframe = m_playerConfig.entities[1].frame;
106 		m_playerConfig.entities[0].frame = frame;
107 		m_playerConfig.entities[1].frame = frame;
108 
109 	}
110 }
111 
PlayerConfig_MenuDraw(menuFrameWork_t * self)112 static void PlayerConfig_MenuDraw( menuFrameWork_t *self ) {
113 	float backlerp;
114 
115 	m_playerConfig.refdef.time = uis.realtime * 0.001f;
116 
117 	PlayerConfig_RunFrame();
118 
119 	if( m_playerConfig.time == m_playerConfig.oldTime ) {
120 		backlerp = 0;
121 	} else {
122 		backlerp = 1 - ( float )( uis.realtime - m_playerConfig.oldTime ) /
123 			( float )( m_playerConfig.time - m_playerConfig.oldTime );
124 	}
125 
126 	m_playerConfig.entities[0].backlerp = backlerp;
127 	m_playerConfig.entities[1].backlerp = backlerp;
128 
129 	//m_playerConfig.entities[0].angles[1] = anglemod( uis.realtime / 20.0f );
130 	//m_playerConfig.entities[1].angles[1] = anglemod( uis.realtime / 20.0f );
131 
132 	Menu_Draw( self );
133 
134 	ref.RenderFrame( &m_playerConfig.refdef );
135 
136 	//Com_sprintf( scratch, sizeof( scratch ), "/players/%s/%s_i.pcx",
137 	//	uis.pmi[m_playerConfig.modelBox.curvalue].directory,
138 	//	uis.pmi[m_playerConfig.modelBox.curvalue].skindisplaynames[m_playerConfig.skinBox.curvalue] );
139 	//ref.DrawStretchPic( m_playerConfig.menu.x - 40, refdef.y, scratch );
140 
141 
142 }
143 
PlayerConfig_MenuCallback(int id,int msg,int param)144 static int PlayerConfig_MenuCallback( int id, int msg, int param ) {
145 	switch( msg ) {
146 	case QM_CHANGE:
147 		switch( id ) {
148 		case ID_MODEL:
149 			m_playerConfig.skinBox.itemnames = ( const char ** )
150 				uis.pmi[m_playerConfig.modelBox.curvalue].skindisplaynames;
151 			m_playerConfig.skinBox.curvalue = 0;
152 			SpinControl_Init( &m_playerConfig.skinBox );
153 			// fall through
154 		case ID_SKIN:
155 			ReloadMedia();
156 			break;
157 		default:
158 			break;
159 		}
160 		return QMS_MOVE;
161 	case QM_DESTROY:
162 		ApplyChanges();
163 		break;
164 	default:
165 		break;
166 	}
167 
168 	return QMS_NOTHANDLED;
169 
170 }
171 
PlayerConfig_MenuInit(void)172 qboolean PlayerConfig_MenuInit( void ) {
173 	char currentdirectory[MAX_QPATH];
174 	char currentskin[MAX_QPATH];
175 	int i, j;
176 	int currentdirectoryindex = 0;
177 	int currentskinindex = 0;
178 	char *p;
179 	int x, y;
180 	vec3_t origin = { 80.0f, 5.0f, 0.0f };
181 	vec3_t angles = { 0.0f, 260.0f, 0.0f };
182 
183 	memset( &m_playerConfig, 0, sizeof( m_playerConfig ) );
184 
185 	// find and register all player models
186 	if( !uis.numPlayerModels ) {
187 		PlayerModel_Load();
188 		if( !uis.numPlayerModels ) {
189 			return qfalse;
190 		}
191 	}
192 
193 	cvar.VariableStringBuffer( "skin", currentdirectory, sizeof( currentdirectory ) );
194 
195 	if( ( p = strchr( currentdirectory, '/' ) ) || ( p = strchr( currentdirectory, '\\' ) ) ) {
196 		*p++ = 0;
197 		Q_strncpyz( currentskin, p, sizeof( currentskin ) );
198 	} else {
199 		strcpy( currentdirectory, "male" );
200 		strcpy( currentskin, "grunt" );
201 	}
202 
203 	for( i = 0 ; i < uis.numPlayerModels ; i++ ) {
204 		m_playerConfig.pmnames[i] = uis.pmi[i].directory;
205 		if( Q_stricmp( uis.pmi[i].directory, currentdirectory ) == 0 ) {
206 			currentdirectoryindex = i;
207 
208 			for( j = 0 ; j < uis.pmi[i].nskins ; j++ ) {
209 				if( Q_stricmp( uis.pmi[i].skindisplaynames[j], currentskin ) == 0 ) {
210 					currentskinindex = j;
211 					break;
212 				}
213 			}
214 		}
215 	}
216 
217 	m_playerConfig.refdef.x = uis.glconfig.vidWidth / 2;
218 	m_playerConfig.refdef.y = 60;
219 	m_playerConfig.refdef.width = uis.glconfig.vidWidth / 2;
220 	m_playerConfig.refdef.height = uis.glconfig.vidHeight - 122;
221 
222 	m_playerConfig.refdef.fov_x = 40;
223 	m_playerConfig.refdef.fov_y = Com_CalcFov( m_playerConfig.refdef.fov_x,
224 		m_playerConfig.refdef.width, m_playerConfig.refdef.height );
225 
226 	m_playerConfig.entities[0].flags = RF_FULLBRIGHT;
227 	VectorCopy( angles, m_playerConfig.entities[0].angles );
228 	VectorCopy( origin, m_playerConfig.entities[0].origin );
229 	VectorCopy( origin, m_playerConfig.entities[0].oldorigin );
230 
231 	m_playerConfig.entities[1].flags = RF_FULLBRIGHT;
232 	VectorCopy( angles, m_playerConfig.entities[1].angles );
233 	VectorCopy( origin, m_playerConfig.entities[1].origin );
234 	VectorCopy( origin, m_playerConfig.entities[1].oldorigin );
235 
236 	m_playerConfig.refdef.num_entities = 2;
237 
238 	m_playerConfig.refdef.entities = m_playerConfig.entities;
239 	m_playerConfig.refdef.rdflags = RDF_NOWORLDMODEL;
240 
241 	// set up oldframe correctly
242 	m_playerConfig.time = uis.realtime - 120;
243 	m_playerConfig.oldTime = m_playerConfig.time;
244 	PlayerConfig_RunFrame();
245 
246 	x = uis.glconfig.vidWidth / 2 - 130;
247 	y = uis.glconfig.vidHeight / 2 - 97;
248 
249 	m_playerConfig.menu.draw = PlayerConfig_MenuDraw;
250 	m_playerConfig.menu.callback = PlayerConfig_MenuCallback;
251 
252 	m_playerConfig.nameField.generic.type = MTYPE_FIELD;
253 	m_playerConfig.nameField.generic.flags = QMF_HASFOCUS;
254 	m_playerConfig.nameField.generic.name = "name";
255 	m_playerConfig.nameField.generic.x		= x;
256 	m_playerConfig.nameField.generic.y		= y;
257 	IF_InitText( &m_playerConfig.nameField.field, 16, 16,
258 		cvar.VariableString( "name" ) );
259 	y += 32;
260 
261 	m_playerConfig.modelBox.generic.type = MTYPE_SPINCONTROL;
262 	m_playerConfig.modelBox.generic.id = ID_MODEL;
263 	m_playerConfig.modelBox.generic.name = "model";
264 	m_playerConfig.modelBox.generic.x	= x;
265 	m_playerConfig.modelBox.generic.y	= y;
266 	m_playerConfig.modelBox.curvalue = currentdirectoryindex;
267 	m_playerConfig.modelBox.itemnames = ( const char ** )m_playerConfig.pmnames;
268 	y += 16;
269 
270 	m_playerConfig.skinBox.generic.type = MTYPE_SPINCONTROL;
271 	m_playerConfig.skinBox.generic.id = ID_SKIN;
272 	m_playerConfig.skinBox.generic.name = "skin";
273 	m_playerConfig.skinBox.generic.x	= x;
274 	m_playerConfig.skinBox.generic.y	= y;
275 	m_playerConfig.skinBox.curvalue = currentskinindex;
276 	m_playerConfig.skinBox.itemnames = ( const char ** )
277 		uis.pmi[currentdirectoryindex].skindisplaynames;
278 	y += 16;
279 
280 	m_playerConfig.handBox.generic.type = MTYPE_SPINCONTROL;
281 	m_playerConfig.handBox.generic.name = "handedness";
282 	m_playerConfig.handBox.generic.x	= x;
283 	m_playerConfig.handBox.generic.y	= y;
284 	m_playerConfig.handBox.curvalue = cvar.VariableInteger( "hand" );
285 	clamp( m_playerConfig.handBox.curvalue, 0, 2 );
286 	m_playerConfig.handBox.itemnames = handedness;
287 
288 	UI_SetupDefaultBanner( &m_playerConfig.banner, "Player Setup" );
289 
290 	Menu_AddItem( &m_playerConfig.menu, &m_playerConfig.nameField );
291 	Menu_AddItem( &m_playerConfig.menu, &m_playerConfig.modelBox );
292 	if( m_playerConfig.skinBox.itemnames ) {
293 		Menu_AddItem( &m_playerConfig.menu, &m_playerConfig.skinBox );
294 	}
295 	Menu_AddItem( &m_playerConfig.menu, &m_playerConfig.handBox );
296 	//Menu_AddItem( &m_playerConfig.menu, &m_playerConfig.downloadAction );
297 	Menu_AddItem( &m_playerConfig.menu, &m_playerConfig.banner );
298 
299 	ReloadMedia();
300 
301 	return qtrue;
302 }
303 
304 
M_Menu_PlayerConfig_f(void)305 void M_Menu_PlayerConfig_f( void ) {
306 	if( !PlayerConfig_MenuInit() ) {
307 		return;
308 	}
309 	UI_PushMenu( &m_playerConfig.menu );
310 }
311 
312 
313 
314