Vegastrike 0.5.1 rc1  1.0
Original sources for Vegastrike Evolved
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
cockpit_xml.cpp
Go to the documentation of this file.
1 #include "config.h"
2 #include "cockpit.h"
3 #include "xml_support.h"
4 #include "gauge.h"
5 #include <float.h>
6 #include "hud.h"
7 #include "vdu.h"
8 #include "mesh.h"
9 
16 
17 namespace CockpitXML
18 {
19 //
20 
21 enum Names
22 {
45  RED,
55 //use the UnitImages<void> enum for the gauge values instead!
56 /* KARMORF,
57  * KARMORB,
58  * KARMORR,
59  * KARMORL,
60  * KFUEL,
61  * KSHIELDF,
62  * KSHIELDR,
63  * KSHIELDL,
64  * KSHIELDB,
65  * KENERGY,
66  * KAUTO,
67  * KEJECT,
68  * KLOCK,
69  * KHULL,
70  * KWARPENERGY,
71  * KKPS,
72  * KSETKPS,
73  * KFPS,
74  * COCKPIT_LAG,
75  */
82 };
83 
85  EnumMap::Pair( "UNKNOWN", UNKNOWN ),
86  EnumMap::Pair( "Cockpit", COCKPIT ),
87  EnumMap::Pair( "Radar", RADAR ),
88  EnumMap::Pair( "RearRadar", REARRADAR ),
89  EnumMap::Pair( "LeftVDU", LVDU ),
90  EnumMap::Pair( "VDU", AVDU ),
91  EnumMap::Pair( "RightVDU", RVDU ),
92  EnumMap::Pair( "Panel", PANEL ),
93  EnumMap::Pair( "Crosshairs", CROSSHAIRS ),
152 };
154  EnumMap::Pair( "UNKNOWN", UNKNOWN ),
155  EnumMap::Pair( "mesh", MESH ),
156  EnumMap::Pair( "file", XFILE ),
157  EnumMap::Pair( "soundfile", SOUNDFILE ),
158  EnumMap::Pair( "font", MYFONT ),
159  EnumMap::Pair( "front", FRONT ),
160  EnumMap::Pair( "left", LEFT ),
161  EnumMap::Pair( "right", RIGHT ),
162  EnumMap::Pair( "back", BACK ),
163  EnumMap::Pair( "xcent", XCENT ),
164  EnumMap::Pair( "ycent", YCENT ),
165  EnumMap::Pair( "width", XSIZE ),
166  EnumMap::Pair( "height", YSIZE ),
167  EnumMap::Pair( "Top", TOPY ),
168  EnumMap::Pair( "Bottom", BOTY ),
169  EnumMap::Pair( "ViewOffset", VIEWOFFSET ),
170  EnumMap::Pair( "CockpitOffset", COCKPITOFFSET ),
171  EnumMap::Pair( "network", NETWORK ),
172  EnumMap::Pair( "GaugeUp", G_UP ),
173  EnumMap::Pair( "GaugeDown", G_DOWN ),
174  EnumMap::Pair( "GaugeLeft", G_LEFT ),
175  EnumMap::Pair( "GaugeRight", G_RIGHT ),
176  EnumMap::Pair( "GaugeTime", G_TIME ),
177  EnumMap::Pair( "TextRows", ROWS ),
178  EnumMap::Pair( "TextCols", COLS ),
179  EnumMap::Pair( "r", RED ),
180  EnumMap::Pair( "g", GREEN ),
181  EnumMap::Pair( "b", BLUE ),
182  EnumMap::Pair( "type", VDUTYPE ),
183  EnumMap::Pair( "a", ALPH )
184 };
185 
186 const EnumMap element_map( element_names, sizeof (element_names)/sizeof (element_names[0]) );
188 }
189 
190 using XMLSupport::EnumMap;
193 using namespace CockpitXML;
194 
195 string getRes( string inp )
196 {
197  string::size_type where = inp.rfind( "." );
198  int x = g_game.x_resolution;
199  if (x < 700) x = 640;
200  else if (x < 840)
201  x = 800;
202  else if (x < 1100)
203  x = 1024;
204  else if (x < 1400)
205  x = 1280;
206  else if (x < 1700)
207  x = 1600;
208  else x = 1600;
209  string rez = XMLSupport::tostring( x );
210  if (where == string::npos)
211  return inp+"_"+rez+".spr";
212  else
213  return inp.substr( 0, where )+"_"+rez+".spr";
214 }
215 
216 void GameCockpit::beginElement( const string &name, const AttributeList &attributes )
217 {
218  static bool cockpit_smooth =
219  XMLSupport::parse_bool( vs_config->getVariable( "graphics", "cockpit_smooth_texture", "false" ) );
220  static bool panel_smooth =
221  XMLSupport::parse_bool( vs_config->getVariable( "graphics", "panel_smooth_texture", "true" ) );
222  static bool crosshair_smooth =
223  XMLSupport::parse_bool( vs_config->getVariable( "graphics", "crosshair_smooth_texture", "true" ) );
224  AttributeList::const_iterator iter;
226  VSSprite **newsprite = NULL;
227  VDU **newvdu = NULL;
228  VSSprite *adjsprite = NULL;
229  std::string gaugename( "shieldstat.spr" );
230  std::string myfont( "9x12.font" );
231  Names elem = (Names) element_map.lookup( name );
232  Names attr;
233  unsigned int mymodes = 0;
234  float xsize = -1, ysize = -1, xcent = FLT_MAX, ycent = FLT_MAX;
235  float leftx = -10;
236  float rightx = -10;
237  float topy = -10;
238  float boty = -10;
239  short rows = 13;
240  short cols = 15;
241  unsigned int default_mode = VDU::TARGET;
242  VSSprite *oldpit = NULL;
243  bool replaced[4] = {false, false, false, false};
244  int counter = 0;
245  switch (elem)
246  {
247  case COCKPIT:
248  for (iter = attributes.begin(); iter != attributes.end(); iter++) {
249  attr = (Names) attribute_map.lookup( (*iter).name );
250  switch (attr)
251  {
252  case MYFONT:
253  myfont = (*iter).value;
254  break;
255  case RED:
256  textcol.r = XMLSupport::parse_float( (*iter).value );
257  break;
258  case GREEN:
259  textcol.g = XMLSupport::parse_float( (*iter).value );
260  break;
261  case BLUE:
262  textcol.b = XMLSupport::parse_float( (*iter).value );
263  break;
264  case ALPH:
265  textcol.a = XMLSupport::parse_float( (*iter).value );
266  break;
267  case VIEWOFFSET:
268  viewport_offset = XMLSupport::parse_float( (*iter).value );
269  break;
270  case COCKPITOFFSET:
271  cockpit_offset = XMLSupport::parse_float( (*iter).value );
272  break;
273  case XFILE:
274  {
275  std::string tmp = getRes( (*iter).value );
276  oldpit = Pit[0];
277  Pit[0] = new VSSprite( tmp.c_str(), cockpit_smooth ? BILINEAR : NEAREST );
278  if ( !Pit[0]->LoadSuccess() ) {
279  delete Pit[0];
280  Pit[0] = new VSSprite( (*iter).value.c_str(), cockpit_smooth ? BILINEAR : NEAREST );
281  }
282  replaced[0] = true;
283  if (oldpit)
284  delete oldpit;
285  break;
286  }
287  case SOUNDFILE:
288  SetSoundFile( (*iter).value );
289  break;
290  case MESH:
291  mesh = Mesh::LoadMeshes( (*iter).value.c_str(), Vector( 1, 1, 1 ), 0, NULL );
292  break;
293  case FRONT:
294  case BACK:
295  case LEFT:
296  case RIGHT:
297  {
298  std::string tmp = getRes( (*iter).value );
299  oldpit = Pit[attr-FRONT];
300  Pit[attr-FRONT] = new VSSprite( tmp.c_str(), cockpit_smooth ? BILINEAR : NEAREST );
301  if ( !Pit[attr-FRONT]->LoadSuccess() ) {
302  delete Pit[attr-FRONT];
303  Pit[attr-FRONT] = new VSSprite( (*iter).value.c_str(), cockpit_smooth ? BILINEAR : NEAREST );
304  }
305  replaced[attr-FRONT] = true;
306  if (oldpit)
307  delete oldpit;
308  break;
309  }
310  default:
311  break;
312  }
313  }
314  text = new TextPlane();
315  for (counter = 0; counter < 4; ++counter)
316  if (!replaced[counter]) {
317  delete Pit[counter];
318  Pit[counter] = false;
319  }
320  break;
325  shield8 = true;
326  goto pastarmor8;
331  armor8 = true;
332 pastarmor8:
375  for (iter = attributes.begin(); iter != attributes.end(); iter++) {
376  switch ( attribute_map.lookup( (*iter).name ) )
377  {
378  case XFILE:
379  gaugename = (*iter).value;
380  break;
381  case NETWORK:
382  if ( (Network != NULL) != XMLSupport::parse_bool( (*iter).value ) )
383  return; //Don't show if not in multiplayer (or single if false)
384 
385  break;
386  case TOPY:
387  topy = XMLSupport::parse_float( (*iter).value );
388  break;
389  case BOTY:
390  boty = XMLSupport::parse_float( (*iter).value );
391  break;
392  case LEFT:
393  leftx = XMLSupport::parse_float( (*iter).value );
394  break;
395  case RIGHT:
396  rightx = XMLSupport::parse_float( (*iter).value );
397  break;
398  case XSIZE:
399  xsize = XMLSupport::parse_float( (*iter).value );
400  break;
401  case YSIZE:
402  ysize = XMLSupport::parse_float( (*iter).value );
403  break;
404  case XCENT:
405  xcent = XMLSupport::parse_float( (*iter).value );
406  break;
407  case YCENT:
408  ycent = XMLSupport::parse_float( (*iter).value );
409  break;
410  case G_UP:
411  tmpdir = Gauge::GAUGE_UP;
412  break;
413  case G_DOWN:
414  tmpdir = Gauge::GAUGE_DOWN;
415  break;
416  case G_LEFT:
417  tmpdir = Gauge::GAUGE_LEFT;
418  break;
419  case G_RIGHT:
420  tmpdir = Gauge::GAUGE_RIGHT;
421  break;
422  case G_TIME:
423  tmpdir = Gauge::GAUGE_TIME;
424  break;
425  }
426  }
427  gauges[elem] = new Gauge( gaugename.c_str(), tmpdir );
428  if (xsize != -1)
429  gauges[elem]->SetSize( xsize, ysize );
430  if (xcent != FLT_MAX)
431  gauges[elem]->SetPosition( xcent, ycent );
432  if (leftx != -10 && rightx != -10 && topy != -10 && boty != -10) {
433  gauges[elem]->SetPosition( .5*(leftx+rightx), .5*(topy+boty) );
434  gauges[elem]->SetSize( fabs( leftx-rightx ), fabs( topy-boty ) );
435  }
436  break;
437  case CROSSHAIRS:
438  case PANEL:
439  if (elem == CROSSHAIRS) {
440  if (Panel.size() == 0)
441  Panel.push_back( NULL );
442  if ( Panel.front() ) {
443  delete Panel.front();
444  Panel.front() = NULL;
445  }
446  newsprite = &Panel.front();
447  } else {
448  if (Panel.size() == 0) /* Create NULL crosshairs */
449  Panel.push_back( NULL );
450  Panel.push_back( NULL );
451  newsprite = &Panel.back();
452  }
453  goto loadsprite;
454  case RADAR:
455  newsprite = &radarSprites[0];
456  goto loadsprite;
457  case REARRADAR:
458  newsprite = &radarSprites[1];
459  goto loadsprite;
460  case LVDU:
461  vdu.push_back( NULL );
462  newvdu = &vdu.back();
464  default_mode = VDU::OBJECTIVES;
465 #ifdef NETCOMM_WEBCAM
466  mymodes = mymodes|VDU::WEBCAM;
467 #endif
468  if (Network != NULL)
469  mymodes = mymodes|VDU::NETWORK;
470  goto loadsprite;
471  case RVDU:
472  vdu.push_back( NULL );
473  newvdu = &vdu.back();
475  default_mode = VDU::TARGET;
476  goto loadsprite;
477  case AVDU:
478  vdu.push_back( NULL );
479  newvdu = &vdu.back();
480  mymodes = VDU::MSG;
481  for (iter = attributes.begin(); iter != attributes.end(); iter++) {
482  switch ( attribute_map.lookup( (*iter).name ) )
483  {
484  case VDUTYPE:
485  {
486  mymodes = parse_vdu_type( (*iter).value.c_str() );
487  std::string firstmode = (*iter).value.substr( 0, (*iter).value.find( " " ) );
488  default_mode = parse_vdu_type( firstmode.c_str() );
489  break;
490  }
491  default:
492  break;
493  }
494  }
495  goto loadsprite;
496 loadsprite:
497  for (iter = attributes.begin(); iter != attributes.end(); iter++) {
498  switch ( attribute_map.lookup( (*iter).name ) )
499  {
500  case NETWORK:
501  if ( (Network != NULL) != XMLSupport::parse_bool( (*iter).value ) )
502  return; //Don't show if not in multiplayer (or single if false)
503 
504  break;
505  case XFILE:
506  if (newsprite) {
507  std::string tmp = getRes( (*iter).value );
508  bool bil = elem == PANEL ? panel_smooth : crosshair_smooth;
509  (*newsprite) = new VSSprite( tmp.c_str(), bil ? BILINEAR : NEAREST );
510  if ( !(*newsprite)->LoadSuccess() ) {
511  delete (*newsprite);
512  (*newsprite) = new VSSprite( (*iter).value.c_str(), bil ? BILINEAR : NEAREST );
513  }
514  adjsprite = *newsprite;
515  } else if (newvdu) {
516  VDU *tmp = new VDU( (*iter).value.c_str(), text, mymodes, rows, cols, &StartArmor[0], &maxhull );
517  (*newvdu) = tmp;
518  adjsprite = *newvdu;
519  if (tmp->getMode() != default_mode) {
520  for (int i = 0; i < 32; ++i) {
521  tmp->SwitchMode( NULL );
522  if (tmp->getMode() == default_mode)
523  break;
524  }
525  }
526  }
527  break;
528  case TOPY:
529  topy = XMLSupport::parse_float( (*iter).value );
530  break;
531  case BOTY:
532  boty = XMLSupport::parse_float( (*iter).value );
533  break;
534  case LEFT:
535  leftx = XMLSupport::parse_float( (*iter).value );
536  break;
537  case RIGHT:
538  rightx = XMLSupport::parse_float( (*iter).value );
539  break;
540  case XSIZE:
541  xsize = XMLSupport::parse_float( (*iter).value );
542  break;
543  case YSIZE:
544  ysize = XMLSupport::parse_float( (*iter).value );
545  break;
546  case XCENT:
547  xcent = XMLSupport::parse_float( (*iter).value );
548  break;
549  case YCENT:
550  ycent = XMLSupport::parse_float( (*iter).value );
551  break;
552  case ROWS:
553  rows = XMLSupport::parse_int( (*iter).value );
554  break;
555  case COLS:
556  cols = XMLSupport::parse_int( (*iter).value );
557  break;
558  break;
559  }
560  }
561  if (adjsprite) {
562  if (xsize != -1)
563  adjsprite->SetSize( xsize, ysize );
564  if (xcent != FLT_MAX)
565  adjsprite->SetPosition( xcent, ycent );
566  if (leftx != -10 && rightx != -10 && topy != -10 && boty != -10) {
567  adjsprite->SetPosition( .5*(leftx+rightx), .5*(topy+boty) );
568  adjsprite->SetSize( fabs( leftx-rightx ), fabs( topy-boty ) );
569  }
570  } else if ( newsprite == &Panel.back() ) {
571  Panel.erase( Panel.end()-1 ); //don't want null panels
572  }
573  break;
574  default:
575  break;
576  }
577 }
578 
579 void GameCockpit::endElement( const string &name )
580 {
581 }
582 
583 using namespace VSFileSystem;
584 
585 void GameCockpit::LoadXML( const char *filename )
586 {
587  const int chunk_size = 16384;
588 
589  VSFile f;
590  VSError err = Unspecified;
591  if (filename[0] != '\0')
592  VSError err = f.OpenReadOnly( filename, CockpitFile );
593  LoadXML( f );
594 }
595 
596 void GameCockpit::LoadXML( VSFileSystem::VSFile &f )
597 {
598  if ( !f.Valid() ) {
599  cockpit_offset = 0;
600  viewport_offset = 0;
601  Panel.push_back( new VSSprite( "crosshairs.spr" ) );
602  return;
603  }
604  XML_Parser parser = XML_ParserCreate( NULL );
605  XML_SetUserData( parser, this );
606  XML_SetElementHandler( parser, &Cockpit::beginElement, &Cockpit::endElement );
607 
608  XML_Parse( parser, ( f.ReadFull() ).c_str(), f.Size(), 1 );
609  /*
610  * do {
611  * #ifdef BIDBG
612  * char *buf = (XML_Char*)XML_GetBuffer(parser, chunk_size);
613  * #else
614  * char buf[chunk_size];
615  * #endif
616  * int length;
617  *
618  * length = VSFileSystem::vs_read (buf,1, chunk_size,inFile);
619  * //length = inFile.gcount();
620  * #ifdef BIDBG
621  * XML_ParseBuffer(parser, length, VSFileSystem::vs_feof(inFile));
622  * #else
623  * XML_Parse (parser,buf,length,VSFileSystem::vs_feof(inFile));
624  * #endif
625  * } while(!VSFileSystem::vs_feof(inFile));
626  * VSFileSystem::vs_close (inFile);
627  */
628  XML_ParserFree( parser );
629 }
630