| | 326 | Index: src/Game.cpp |
| | 327 | =================================================================== |
| | 328 | RCS file: /cvsroot/xmoto/xmoto/src/Game.cpp,v |
| | 329 | retrieving revision 1.147 |
| | 330 | diff -a -u -r1.147 Game.cpp |
| | 331 | --- src/Game.cpp 30 Jul 2006 10:48:21 -0000 1.147 |
| | 332 | +++ src/Game.cpp 10 Aug 2006 23:42:58 -0000 |
| | 333 | @@ -27,7 +27,6 @@ |
| | 334 | #include "Sound.h" |
| | 335 | #include "PhysSettings.h" |
| | 336 | #include "Input.h" |
| | 337 | -#include "md5sum/md5file.h" |
| | 338 | |
| | 339 | #if defined(SUPPORT_WEBACCESS) |
| | 340 | #include <curl/curl.h> |
| | 341 | @@ -247,7 +246,7 @@ |
| | 342 | m_MotoGame.setGhostActive(true); |
| | 343 | /* read first state */ |
| | 344 | static SerializedBikeState GhostBikeState; |
| | 345 | - m_pGhostReplay->peekState((char *)&GhostBikeState); |
| | 346 | + m_pGhostReplay->peekState(GhostBikeState); |
| | 347 | m_MotoGame.UpdateGhostFromReplay(&GhostBikeState); |
| | 348 | /* ghost info */ |
| | 349 | if(m_bEnableGhostInfo) { |
| | 350 | @@ -890,96 +889,43 @@ |
| | 351 | int GameApp::_LoadLevels(const std::vector<std::string> &LvlFiles) { |
| | 352 | int nNumCached = 0; |
| | 353 | |
| | 354 | - for(int i=0;i<LvlFiles.size();i++) { |
| | 355 | - bool bLoadedOK = true; |
| | 356 | - |
| | 357 | + for(int i=0;i<LvlFiles.size();i++) { |
| | 358 | int j = m_nNumLevels; |
| | 359 | if(j >= 2048) { |
| | 360 | Log("** Warning ** : Too many levels."); |
| | 361 | break; |
| | 362 | } |
| | 363 | - m_nNumLevels++; |
| | 364 | |
| | 365 | bool bCached = false; |
| | 366 | try { |
| | 367 | + // Load the level |
| | 368 | m_Levels[j].setFileName( LvlFiles[i] ); |
| | 369 | + bCached = m_Levels[j].load(m_bEnableLevelCache); |
| | 370 | |
| | 371 | - //if(strstr(LvlFiles[i].c_str(),"l138")) { |
| | 372 | - // __asm{int 3}; |
| | 373 | - //} |
| | 374 | - |
| | 375 | - /* Determine MD5 sum of level file */ |
| | 376 | - std::string MD5Sum = md5file( LvlFiles[i] ); |
| | 377 | - //printf("[%s][%s]\n",MD5Sum.c_str(),LvlFiles[i].c_str()); |
| | 378 | - m_Levels[j].setLevelMD5Sum( MD5Sum ); |
| | 379 | - |
| | 380 | - /* Cache or not to cache? */ |
| | 381 | - if(m_bEnableLevelCache) { |
| | 382 | - /* Start by determining file CRC */ |
| | 383 | - LevelCheckSum Sum; |
| | 384 | - m_Levels[j].probeCheckSum(&Sum); |
| | 385 | - |
| | 386 | - /* Determine name in cache */ |
| | 387 | - std::string LevelFileBaseName = FS::getFileBaseName(LvlFiles[i]); |
| | 388 | - char cCacheFileName[1024]; |
| | 389 | - sprintf(cCacheFileName,"LCache/%08x%s.blv",Sum.nCRC32,LevelFileBaseName.c_str()); |
| | 390 | - |
| | 391 | - /* Got level in cache? */ |
| | 392 | - if(!m_Levels[j].importBinary(cCacheFileName,&Sum)) { |
| | 393 | - /* Not in cache, buggers. Load it from (slow) XML then. */ |
| | 394 | - m_Levels[j].loadXML(); |
| | 395 | - |
| | 396 | - /* Cache it now */ |
| | 397 | - m_Levels[j].exportBinary(cCacheFileName,&Sum); |
| | 398 | - } |
| | 399 | - else { |
| | 400 | - nNumCached++; |
| | 401 | - bCached = true; |
| | 402 | - } |
| | 403 | - } |
| | 404 | - else { |
| | 405 | - /* Just load it */ |
| | 406 | - m_Levels[j].loadXML(); |
| | 407 | - } |
| | 408 | - } |
| | 409 | - catch(Exception &e) { |
| | 410 | - Log("** Warning ** : Problem loading '%s' (%s)",LvlFiles[i].c_str(),e.getMsg().c_str()); |
| | 411 | - m_nNumLevels--; |
| | 412 | - if(bCached) |
| | 413 | - nNumCached--; |
| | 414 | - bLoadedOK = false; |
| | 415 | - } |
| | 416 | - |
| | 417 | - bool bGoodLevel = true; |
| | 418 | - |
| | 419 | - if(bLoadedOK) { |
| | 420 | - /* Check for ID conflict */ |
| | 421 | - for(int k=0;k<m_nNumLevels-1;k++) { |
| | 422 | + // Check for ID conflict |
| | 423 | + for(int k=0;k<m_nNumLevels;k++) { |
| | 424 | if(m_Levels[k].getID() == m_Levels[j].getID()) { |
| | 425 | /* Conflict! */ |
| | 426 | Log("** Warning ** : More than one level with ID '%s'!",m_Levels[k].getID().c_str()); |
| | 427 | Log(" (%s)",m_Levels[j].getFileName().c_str()); |
| | 428 | Log(" (%s)",m_Levels[k].getFileName().c_str()); |
| | 429 | if(bCached) Log(" (cached)"); |
| | 430 | - m_nNumLevels--; |
| | 431 | - |
| | 432 | - if(bCached) |
| | 433 | - nNumCached--; |
| | 434 | - |
| | 435 | - bGoodLevel = false; |
| | 436 | - break; |
| | 437 | + throw Exception("Duplicate level ID"); |
| | 438 | } |
| | 439 | } |
| | 440 | - } |
| | 441 | - |
| | 442 | - if(bGoodLevel && bLoadedOK) { |
| | 443 | + |
| | 444 | + if (bCached) ++nNumCached; |
| | 445 | + ++m_nNumLevels; |
| | 446 | + |
| | 447 | /* Update level pack manager */ |
| | 448 | _UpdateLevelPackManager(&m_Levels[j]); |
| | 449 | - } |
| | 450 | |
| | 451 | - //printf("got level [%s][%s]\n",m_Levels[j].getID().c_str(),m_Levels[j].getFileName().c_str()); |
| | 452 | + } catch(Exception &e) { |
| | 453 | + Log("** Warning ** : Problem loading '%s' (%s)", |
| | 454 | + LvlFiles[i].c_str(),e.getMsg().c_str()); |
| | 455 | + } |
| | 456 | } |
| | 457 | - |
| | 458 | + |
| | 459 | return nNumCached; |
| | 460 | } |
| | 461 | |
| | 462 | @@ -1287,11 +1233,11 @@ |
| | 463 | static SerializedBikeState GhostBikeState; |
| | 464 | static SerializedBikeState previousGhostBikeState; |
| | 465 | |
| | 466 | - m_pGhostReplay->peekState((char *)&previousGhostBikeState); |
| | 467 | + m_pGhostReplay->peekState(previousGhostBikeState); |
| | 468 | if(previousGhostBikeState.fGameTime < m_MotoGame.getTime() |
| | 469 | && m_pGhostReplay->endOfFile() == false) { |
| | 470 | do { |
| | 471 | - m_pGhostReplay->loadState((char *)&GhostBikeState); |
| | 472 | + m_pGhostReplay->loadState(GhostBikeState); |
| | 473 | } while(GhostBikeState.fGameTime < m_MotoGame.getTime() |
| | 474 | && m_pGhostReplay->endOfFile() == false); |
| | 475 | |
| | 476 | @@ -1318,7 +1264,7 @@ |
| | 477 | SerializedBikeState BikeState; |
| | 478 | m_MotoGame.getSerializedBikeState(&BikeState); |
| | 479 | if(m_pReplay != NULL) |
| | 480 | - m_pReplay->storeState((const char *)&BikeState); |
| | 481 | + m_pReplay->storeState(BikeState); |
| | 482 | } |
| | 483 | } |
| | 484 | else if(m_State == GS_REPLAYING) { |
| | 485 | @@ -1331,7 +1277,7 @@ |
| | 486 | if(m_nFrame%2 || m_nFrame==1) { |
| | 487 | /* REAL NON-INTERPOLATED FRAME */ |
| | 488 | if(m_pReplay->endOfFile() == false) { |
| | 489 | - m_pReplay->loadState((char *)&BikeState); |
| | 490 | + m_pReplay->loadState(BikeState); |
| | 491 | /* Update game */ |
| | 492 | m_MotoGame.updateLevel( PHYS_STEP_SIZE,&BikeState,m_pReplay ); |
| | 493 | |
| | 494 | @@ -1351,7 +1297,7 @@ |
| | 495 | /* INTERPOLATED FRAME */ |
| | 496 | SerializedBikeState NextBikeState,ibs; |
| | 497 | if(m_pReplay->endOfFile() == false) { |
| | 498 | - m_pReplay->peekState((char *)&NextBikeState); |
| | 499 | + m_pReplay->peekState(NextBikeState); |
| | 500 | /* Nice. Interpolate the states! */ |
| | 501 | m_MotoGame.interpolateGameState(&BikeState,&NextBikeState,&ibs,0.5f); |
| | 502 | |
| | 503 | @@ -2479,41 +2425,11 @@ |
| | 504 | for(int i=0;i<UpdatedLvlFiles.size();i++) { |
| | 505 | try { |
| | 506 | /* Find levels by file names */ |
| | 507 | - bool bFound = false; |
| | 508 | for(int j=0;j<m_nNumLevels;j++) { |
| | 509 | if(m_Levels[j].getFileName() == UpdatedLvlFiles[i]) { |
| | 510 | /* Found it... */ |
| | 511 | - bFound = true; |
| | 512 | - |
| | 513 | - /* Determine MD5 sum of level file */ |
| | 514 | - std::string MD5Sum = md5file( UpdatedLvlFiles[i] ); |
| | 515 | - m_Levels[j].setLevelMD5Sum( MD5Sum ); |
| | 516 | - |
| | 517 | - /* Update cache? */ |
| | 518 | - if(m_bEnableLevelCache) { |
| | 519 | - /* Start by determining file CRC */ |
| | 520 | - LevelCheckSum Sum; |
| | 521 | - m_Levels[j].probeCheckSum(&Sum); |
| | 522 | - |
| | 523 | - /* Determine name in cache */ |
| | 524 | - std::string LevelFileBaseName = FS::getFileBaseName(UpdatedLvlFiles[i]); |
| | 525 | - char cCacheFileName[1024]; |
| | 526 | - sprintf(cCacheFileName,"LCache/%08x%s.blv",Sum.nCRC32,FS::getFileBaseName(UpdatedLvlFiles[i]).c_str()); |
| | 527 | - |
| | 528 | - /* Got level in cache? */ |
| | 529 | - if(!m_Levels[j].importBinary(cCacheFileName,&Sum)) { |
| | 530 | - /* Not in cache, buggers. Load it from (slow) XML then. */ |
| | 531 | - m_Levels[j].loadXML(); |
| | 532 | - |
| | 533 | - /* Cache it now */ |
| | 534 | - m_Levels[j].exportBinary(cCacheFileName,&Sum); |
| | 535 | - } |
| | 536 | - } |
| | 537 | - else { |
| | 538 | - /* Just load it */ |
| | 539 | - m_Levels[j].loadXML(); |
| | 540 | - } |
| | 541 | - |
| | 542 | + m_Levels[j].load(m_bEnableLevelCache); |
| | 543 | + |
| | 544 | /* Failed to load due to old xmoto? */ |
| | 545 | if(m_Levels[j].isXMotoTooOld()) |
| | 546 | nTooOldXMoto++; |
| | 547 | Index: src/LevelSrc.cpp |
| | 548 | =================================================================== |
| | 549 | RCS file: /cvsroot/xmoto/xmoto/src/LevelSrc.cpp,v |
| | 550 | retrieving revision 1.20 |
| | 551 | diff -a -u -r1.20 LevelSrc.cpp |
| | 552 | --- src/LevelSrc.cpp 30 Jul 2006 10:16:07 -0000 1.20 |
| | 553 | +++ src/LevelSrc.cpp 10 Aug 2006 23:42:58 -0000 |
| | 554 | @@ -27,6 +27,7 @@ |
| | 555 | |
| | 556 | #include "LevelSrc.h" |
| | 557 | #include "VFileIO.h" |
| | 558 | +#include "md5sum/md5file.h" |
| | 559 | |
| | 560 | namespace vapp { |
| | 561 | |
| | 562 | @@ -454,6 +455,46 @@ |
| | 563 | } |
| | 564 | } |
| | 565 | |
| | 566 | + /* Load using the best way possible. File name must already be set! |
| | 567 | + * Return whether or not it was loaded from the cache. */ |
| | 568 | + bool LevelSrc::load(bool cacheEnabled) { |
| | 569 | + char cCacheFileName[1024]; |
| | 570 | + LevelCheckSum Sum; |
| | 571 | + |
| | 572 | + std::string MD5Sum = md5file(getFileName()); |
| | 573 | + setLevelMD5Sum(MD5Sum); |
| | 574 | + |
| | 575 | + // First try to load it from the cache |
| | 576 | + bool cached = false; |
| | 577 | + if (cacheEnabled) { |
| | 578 | + /* Start by determining file CRC */ |
| | 579 | + probeCheckSum(&Sum); |
| | 580 | + |
| | 581 | + /* Determine name in cache */ |
| | 582 | + std::string LevelFileBaseName = FS::getFileBaseName(getFileName()); |
| | 583 | + sprintf(cCacheFileName,"LCache/%08lx%s.blv",Sum.nCRC32, |
| | 584 | + LevelFileBaseName.c_str()); |
| | 585 | + |
| | 586 | + try { |
| | 587 | + cached = importBinary(cCacheFileName,&Sum); |
| | 588 | + } catch (Exception &e) { |
| | 589 | + Log("** Warning **: Exception while loading binary level, will load " |
| | 590 | + "XML instead for '%s' (%s)", getFileName().c_str(), |
| | 591 | + e.getMsg().c_str()); |
| | 592 | + } |
| | 593 | + } |
| | 594 | + |
| | 595 | + // If we couldn't get it from the cache, then load from (slow) XML |
| | 596 | + if (!cached) { |
| | 597 | + loadXML(); |
| | 598 | + |
| | 599 | + if (cacheEnabled) |
| | 600 | + exportBinary(cCacheFileName,&Sum); /* Cache it now */ |
| | 601 | + } |
| | 602 | + |
| | 603 | + return cached; |
| | 604 | + } |
| | 605 | + |
| | 606 | /*=========================================================================== |
| | 607 | Easy-to-use function for adding entities |
| | 608 | ===========================================================================*/ |
| | 609 | @@ -636,10 +677,10 @@ |
| | 610 | FS::writeString(pfh,m_Info.Sky); |
| | 611 | FS::writeString(pfh,m_ScriptFile); |
| | 612 | |
| | 613 | - FS::writeFloat(pfh,m_fLeftLimit); |
| | 614 | - FS::writeFloat(pfh,m_fRightLimit); |
| | 615 | - FS::writeFloat(pfh,m_fTopLimit); |
| | 616 | - FS::writeFloat(pfh,m_fBottomLimit); |
| | 617 | + FS::writeFloat_LE(pfh,m_fLeftLimit); |
| | 618 | + FS::writeFloat_LE(pfh,m_fRightLimit); |
| | 619 | + FS::writeFloat_LE(pfh,m_fTopLimit); |
| | 620 | + FS::writeFloat_LE(pfh,m_fBottomLimit); |
| | 621 | |
| | 622 | /* Write script (if any) */ |
| | 623 | FS::writeInt_LE(pfh,m_ScriptSource.length()); |
| | 624 | @@ -653,14 +694,14 @@ |
| | 625 | FS::writeBool(pfh,m_Blocks[i]->bBackground); |
| | 626 | FS::writeBool(pfh,m_Blocks[i]->bWater); |
| | 627 | FS::writeString(pfh,m_Blocks[i]->Texture); |
| | 628 | - FS::writeFloat(pfh,m_Blocks[i]->fPosX); |
| | 629 | - FS::writeFloat(pfh,m_Blocks[i]->fPosY); |
| | 630 | + FS::writeFloat_LE(pfh,m_Blocks[i]->fPosX); |
| | 631 | + FS::writeFloat_LE(pfh,m_Blocks[i]->fPosY); |
| | 632 | |
| | 633 | FS::writeShort_LE(pfh,m_Blocks[i]->Vertices.size()); |
| | 634 | |
| | 635 | for(unsigned int j=0;j<m_Blocks[i]->Vertices.size();j++) { |
| | 636 | - FS::writeFloat(pfh,m_Blocks[i]->Vertices[j]->fX); |
| | 637 | - FS::writeFloat(pfh,m_Blocks[i]->Vertices[j]->fY); |
| | 638 | + FS::writeFloat_LE(pfh,m_Blocks[i]->Vertices[j]->fX); |
| | 639 | + FS::writeFloat_LE(pfh,m_Blocks[i]->Vertices[j]->fY); |
| | 640 | FS::writeString(pfh,m_Blocks[i]->Vertices[j]->EdgeEffect); |
| | 641 | } |
| | 642 | } |
| | 643 | @@ -670,9 +711,9 @@ |
| | 644 | for(unsigned int i=0;i<m_Entities.size();i++) { |
| | 645 | FS::writeString(pfh,m_Entities[i]->ID); |
| | 646 | FS::writeString(pfh,m_Entities[i]->TypeID); |
| | 647 | - FS::writeFloat(pfh,m_Entities[i]->fSize); |
| | 648 | - FS::writeFloat(pfh,m_Entities[i]->fPosX); |
| | 649 | - FS::writeFloat(pfh,m_Entities[i]->fPosY); |
| | 650 | + FS::writeFloat_LE(pfh,m_Entities[i]->fSize); |
| | 651 | + FS::writeFloat_LE(pfh,m_Entities[i]->fPosX); |
| | 652 | + FS::writeFloat_LE(pfh,m_Entities[i]->fPosY); |
| | 653 | FS::writeByte(pfh,m_Entities[i]->Params.size()); |
| | 654 | for(unsigned int j=0;j<m_Entities[i]->Params.size();j++) { |
| | 655 | FS::writeString(pfh,m_Entities[i]->Params[j]->Name); |
| | 656 | @@ -690,10 +731,10 @@ |
| | 657 | FS::writeInt_LE(pfh,(int)m_Zones[i]->Prims[j]->Type); |
| | 658 | |
| | 659 | if(m_Zones[i]->Prims[j]->Type == LZPT_BOX) { |
| | 660 | - FS::writeFloat(pfh,m_Zones[i]->Prims[j]->fLeft); |
| | 661 | - FS::writeFloat(pfh,m_Zones[i]->Prims[j]->fRight); |
| | 662 | - FS::writeFloat(pfh,m_Zones[i]->Prims[j]->fTop); |
| | 663 | - FS::writeFloat(pfh,m_Zones[i]->Prims[j]->fBottom); |
| | 664 | + FS::writeFloat_LE(pfh,m_Zones[i]->Prims[j]->fLeft); |
| | 665 | + FS::writeFloat_LE(pfh,m_Zones[i]->Prims[j]->fRight); |
| | 666 | + FS::writeFloat_LE(pfh,m_Zones[i]->Prims[j]->fTop); |
| | 667 | + FS::writeFloat_LE(pfh,m_Zones[i]->Prims[j]->fBottom); |
| | 668 | } |
| | 669 | } |
| | 670 | } |
| | 671 | @@ -750,15 +791,15 @@ |
| | 672 | m_Info.Sky = FS::readString(pfh); |
| | 673 | m_ScriptFile = FS::readString(pfh); |
| | 674 | |
| | 675 | - //m_fLeftLimit = FS::readFloat(pfh); |
| | 676 | - //m_fRightLimit = FS::readFloat(pfh); |
| | 677 | - //m_fTopLimit = FS::readFloat(pfh); |
| | 678 | - //m_fBottomLimit = FS::readFloat(pfh); |
| | 679 | - |
| | 680 | - m_fLeftLimit = FS::readFloat(pfh); |
| | 681 | - m_fRightLimit = FS::readFloat(pfh); |
| | 682 | - m_fTopLimit = FS::readFloat(pfh); |
| | 683 | - m_fBottomLimit = FS::readFloat(pfh); |
| | 684 | + //m_fLeftLimit = FS::readFloat_LE(pfh); |
| | 685 | + //m_fRightLimit = FS::readFloat_LE(pfh); |
| | 686 | + //m_fTopLimit = FS::readFloat_LE(pfh); |
| | 687 | + //m_fBottomLimit = FS::readFloat_LE(pfh); |
| | 688 | + |
| | 689 | + m_fLeftLimit = FS::readFloat_LE(pfh); |
| | 690 | + m_fRightLimit = FS::readFloat_LE(pfh); |
| | 691 | + m_fTopLimit = FS::readFloat_LE(pfh); |
| | 692 | + m_fBottomLimit = FS::readFloat_LE(pfh); |
| | 693 | |
| | 694 | /* Read embedded script */ |
| | 695 | int nScriptSourceLen = FS::readInt_LE(pfh); |
| | 696 | @@ -788,15 +829,15 @@ |
| | 697 | pBlock->bBackground = FS::readBool(pfh); |
| | 698 | pBlock->bWater = FS::readBool(pfh); |
| | 699 | pBlock->Texture = FS::readString(pfh); |
| | 700 | - pBlock->fPosX = FS::readFloat(pfh); |
| | 701 | - pBlock->fPosY = FS::readFloat(pfh); |
| | 702 | + pBlock->fPosX = FS::readFloat_LE(pfh); |
| | 703 | + pBlock->fPosY = FS::readFloat_LE(pfh); |
| | 704 | |
| | 705 | int nNumVertices = FS::readShort_LE(pfh); |
| | 706 | pBlock->Vertices.reserve(nNumVertices); |
| | 707 | for(int j=0;j<nNumVertices;j++) { |
| | 708 | LevelBlockVertex *pV = new LevelBlockVertex; |
| | 709 | - pV->fX = FS::readFloat(pfh); |
| | 710 | - pV->fY = FS::readFloat(pfh); |
| | 711 | + pV->fX = FS::readFloat_LE(pfh); |
| | 712 | + pV->fY = FS::readFloat_LE(pfh); |
| | 713 | pV->EdgeEffect = FS::readString(pfh); |
| | 714 | |
| | 715 | pBlock->Vertices.push_back(pV); |
| | 716 | @@ -812,9 +853,9 @@ |
| | 717 | LevelEntity *pEnt = new LevelEntity; |
| | 718 | pEnt->ID = FS::readString(pfh); |
| | 719 | pEnt->TypeID = FS::readString(pfh); |
| | 720 | - pEnt->fSize = FS::readFloat(pfh); |
| | 721 | - pEnt->fPosX = FS::readFloat(pfh); |
| | 722 | - pEnt->fPosY = FS::readFloat(pfh); |
| | 723 | + pEnt->fSize = FS::readFloat_LE(pfh); |
| | 724 | + pEnt->fPosX = FS::readFloat_LE(pfh); |
| | 725 | + pEnt->fPosY = FS::readFloat_LE(pfh); |
| | 726 | |
| | 727 | int nNumParams = FS::readByte(pfh); |
| | 728 | pEnt->Params.reserve(nNumParams); |
| | 729 | @@ -849,10 +890,10 @@ |
| | 730 | pP->Type = (LevelZonePrimType)FS::readInt_LE(pfh); |
| | 731 | |
| | 732 | if(pP->Type == LZPT_BOX) { |
| | 733 | - pP->fLeft = FS::readFloat(pfh); |
| | 734 | - pP->fRight = FS::readFloat(pfh); |
| | 735 | - pP->fTop = FS::readFloat(pfh); |
| | 736 | - pP->fBottom = FS::readFloat(pfh); |
| | 737 | + pP->fLeft = FS::readFloat_LE(pfh); |
| | 738 | + pP->fRight = FS::readFloat_LE(pfh); |
| | 739 | + pP->fTop = FS::readFloat_LE(pfh); |
| | 740 | + pP->fBottom = FS::readFloat_LE(pfh); |
| | 741 | } |
| | 742 | else { |
| | 743 | Log("** Warning ** : Invalid zone primitive encountered in: %s",FileName.c_str()); |
| | 744 | @@ -917,6 +958,5 @@ |
| | 745 | /* Same versions */ |
| | 746 | return 0; |
| | 747 | } |
| | 748 | - |
| | 749 | } |
| | 750 | |
| | 751 | Index: src/LevelSrc.h |
| | 752 | =================================================================== |
| | 753 | RCS file: /cvsroot/xmoto/xmoto/src/LevelSrc.h,v |
| | 754 | retrieving revision 1.13 |
| | 755 | diff -a -u -r1.13 LevelSrc.h |
| | 756 | --- src/LevelSrc.h 30 Jul 2006 10:16:07 -0000 1.13 |
| | 757 | +++ src/LevelSrc.h 10 Aug 2006 23:42:58 -0000 |
| | 758 | @@ -164,6 +164,8 @@ |
| | 759 | ~LevelSrc() {_UnloadLevelData();} |
| | 760 | |
| | 761 | /* Methods */ |
| | 762 | + bool load(bool cacheEnabled); |
| | 763 | + |
| | 764 | void saveXML(void); |
| | 765 | void loadXML(void); |
| | 766 | |
| | 796 | Index: src/PlayerData.cpp |
| | 797 | =================================================================== |
| | 798 | RCS file: /cvsroot/xmoto/xmoto/src/PlayerData.cpp,v |
| | 799 | retrieving revision 1.10 |
| | 800 | diff -a -u -r1.10 PlayerData.cpp |
| | 801 | --- src/PlayerData.cpp 30 Jul 2006 10:48:21 -0000 1.10 |
| | 802 | +++ src/PlayerData.cpp 10 Aug 2006 23:42:58 -0000 |
| | 803 | @@ -24,9 +24,15 @@ |
| | 804 | */ |
| | 805 | #include "VFileIO.h" |
| | 806 | #include "PlayerData.h" |
| | 807 | +#include "arch/SwapEndian.h" |
| | 808 | |
| | 809 | namespace vapp { |
| | 810 | |
| | 811 | + /* Return level IDs as-is */ |
| | 812 | + std::string PlayerData::_NoFixLevelID(const std::string &s) { |
| | 813 | + return s; |
| | 814 | + } |
| | 815 | + |
| | 816 | /*=========================================================================== |
| | 817 | Utility function to translate pre-0.1.7 level IDs to 0.1.9 level IDs |
| | 818 | ===========================================================================*/ |
| | 819 | @@ -59,6 +65,43 @@ |
| | 820 | if(s == "_iL00_") return "tut1"; |
| | 821 | return s; |
| | 822 | } |
| | 823 | + |
| | 824 | + /* Load the profiles from a file-handle. |
| | 825 | + * fixer - function pointer to fix the names of levels |
| | 826 | + * swapped - whether data is of the wrong endianness */ |
| | 827 | + void PlayerData::_LoadFileHandle(FileHandle *pfh, LevelFixer fixer, |
| | 828 | + bool swapped) { |
| | 829 | + /* Read number of player profiles */ |
| | 830 | + int nNumPlayerProfiles = FS::readInt_MaybeLE(pfh, swapped); |
| | 831 | + |
| | 832 | + if(nNumPlayerProfiles >= 0) { |
| | 833 | + /* For each player profile */ |
| | 834 | + for(int i=0;i<nNumPlayerProfiles;i++) { |
| | 835 | + std::string PlayerName = FS::readString(pfh); |
| | 836 | + PlayerProfile *pPlayer = createProfile(PlayerName); |
| | 837 | + |
| | 838 | + if(pPlayer != NULL) { |
| | 839 | + int nNumCompleted = FS::readInt_MaybeLE(pfh, swapped); |
| | 840 | + int nNumSkipped = FS::readInt_MaybeLE(pfh, swapped); |
| | 841 | + |
| | 842 | + for(int j=0;j<nNumCompleted;j++) |
| | 843 | + completeLevel(PlayerName,fixer(FS::readString(pfh))); |
| | 844 | + |
| | 845 | + for(int j=0;j<nNumSkipped;j++) |
| | 846 | + skipLevel(PlayerName,fixer(FS::readString(pfh))); |
| | 847 | + |
| | 848 | + while(1) { |
| | 849 | + std::string LevelID = fixer(FS::readString(pfh)); |
| | 850 | + if(LevelID.length() == 0) break; |
| | 851 | + std::string Replay = FS::readString(pfh); |
| | 852 | + std::string TimeStamp = FS::readString(pfh); |
| | 853 | + float fTime = FS::readFloat_MaybeLE(pfh, swapped); |
| | 854 | + addFinishTime(PlayerName,Replay,LevelID,fTime,TimeStamp); |
| | 855 | + } |
| | 856 | + } |
| | 857 | + } |
| | 858 | + } |
| | 859 | + } |
| | 860 | |
| | 861 | /*=========================================================================== |
| | 862 | Load from binary (would rather use XML, but this makes it a bit more |
| | 863 | @@ -66,122 +109,41 @@ |
| | 864 | ===========================================================================*/ |
| | 865 | void PlayerData::loadFile(void) { |
| | 866 | _FreePlayerData(); |
| | 867 | - |
| | 868 | + |
| | 869 | /* Open binary file for input */ |
| | 870 | FileHandle *pfh = FS::openIFile("players.bin"); |
| | 871 | if(pfh == NULL) { |
| | 872 | /* Nuthin */ |
| | 873 | - return; |
| | 874 | + return; |
| | 875 | } |
| | 876 | - |
| | 877 | + |
| | 878 | /* Parse it */ |
| | 879 | - int nVersion = FS::readShort(pfh); |
| | 880 | - |
| | 881 | + short nVersion = FS::readShort_LE(pfh); |
| | 882 | + bool swapped = false; |
| | 883 | + if ((nVersion & 0xFF) == 0 && (nVersion >> 8) >= 0x10) { |
| | 884 | + /* It looks like this file is big-endian! */ |
| | 885 | + swapped = true; |
| | 886 | + nVersion = SwapEndian::LittleShort(nVersion); |
| | 887 | + } |
| | 888 | + |
| | 889 | + /* If levels were moved around, swap the level numbers on the fly. */ |
| | 890 | + LevelFixer fixer = NULL; |
| | 891 | if(nVersion == 0x10) { |
| | 892 | - /* This is the old (<= 0.1.6) players.bin file. At 0.1.7 there was a bit of moving |
| | 893 | - around in the levels numbers, so if we try to load this now, it will for sure explode. |
| | 894 | - Instead, simply load it and translate the level numbers on-the-fly */ |
| | 895 | Log("** Warning ** : Found players.bin from before version 0.1.7, trying to upgrade...\n"); |
| | 896 | - |
| | 897 | - /* Read number of player profiles */ |
| | 898 | - int nNumPlayerProfiles = FS::readInt(pfh); |
| | 899 | - |
| | 900 | - if(nNumPlayerProfiles >= 0) { |
| | 901 | - /* For each player profile */ |
| | 902 | - for(int i=0;i<nNumPlayerProfiles;i++) { |
| | 903 | - std::string PlayerName = FS::readString(pfh); |
| | 904 | - PlayerProfile *pPlayer = createProfile(PlayerName); |
| | 905 | - if(pPlayer != NULL) { |
| | 906 | - int nNumCompleted = FS::readInt(pfh); |
| | 907 | - int nNumSkipped = FS::readInt(pfh); |
| | 908 | - |
| | 909 | - for(int j=0;j<nNumCompleted;j++) |
| | 910 | - completeLevel(PlayerName,_Fix016LevelID(FS::readString(pfh))); |
| | 911 | - |
| | 912 | - for(int j=0;j<nNumSkipped;j++) |
| | 913 | - skipLevel(PlayerName,_Fix016LevelID(FS::readString(pfh))); |
| | 914 | - |
| | 915 | - while(1) { |
| | 916 | - std::string LevelID = _Fix016LevelID(FS::readString(pfh)); |
| | 917 | - if(LevelID.length() == 0) break; |
| | 918 | - std::string Replay = FS::readString(pfh); |
| | 919 | - std::string TimeStamp = FS::readString(pfh); |
| | 920 | - float fTime = FS::readFloat(pfh); |
| | 921 | - addFinishTime(PlayerName,Replay,LevelID,fTime,TimeStamp); |
| | 922 | - } |
| | 923 | - } |
| | 924 | - } |
| | 925 | - } |
| | 926 | - } |
| | 927 | - else if(nVersion == 0x11) { |
| | 928 | - /* This is the old (<= 0.1.8) players.bin file. At 0.1.9 there was a bit of moving |
| | 929 | - around in the levels numbers, so if we try to load this now, it will for sure explode. |
| | 930 | - Instead, simply load it and translate the level numbers on-the-fly */ |
| | 931 | + fixer = _Fix016LevelID; |
| | 932 | + } else if(nVersion == 0x11) { |
| | 933 | Log("** Warning ** : Found players.bin from before version 0.1.9, trying to upgrade...\n"); |
| | 934 | - |
| | 935 | - /* Read number of player profiles */ |
| | 936 | - int nNumPlayerProfiles = FS::readInt(pfh); |
| | 937 | - |
| | 938 | - if(nNumPlayerProfiles >= 0) { |
| | 939 | - /* For each player profile */ |
| | 940 | - for(int i=0;i<nNumPlayerProfiles;i++) { |
| | 941 | - std::string PlayerName = FS::readString(pfh); |
| | 942 | - PlayerProfile *pPlayer = createProfile(PlayerName); |
| | 943 | - if(pPlayer != NULL) { |
| | 944 | - int nNumCompleted = FS::readInt(pfh); |
| | 945 | - int nNumSkipped = FS::readInt(pfh); |
| | 946 | - |
| | 947 | - for(int j=0;j<nNumCompleted;j++) |
| | 948 | - completeLevel(PlayerName,_Fix018LevelID(FS::readString(pfh))); |
| | 949 | - |
| | 950 | - for(int j=0;j<nNumSkipped;j++) |
| | 951 | - skipLevel(PlayerName,_Fix018LevelID(FS::readString(pfh))); |
| | 952 | - |
| | 953 | - while(1) { |
| | 954 | - std::string LevelID = _Fix018LevelID(FS::readString(pfh)); |
| | 955 | - if(LevelID.length() == 0) break; |
| | 956 | - std::string Replay = FS::readString(pfh); |
| | 957 | - std::string TimeStamp = FS::readString(pfh); |
| | 958 | - float fTime = FS::readFloat(pfh); |
| | 959 | - addFinishTime(PlayerName,Replay,LevelID,fTime,TimeStamp); |
| | 960 | - } |
| | 961 | - } |
| | 962 | - } |
| | 963 | - } |
| | 964 | + fixer = _Fix018LevelID; |
| | 965 | + } else if(nVersion == 0x12) { |
| | 966 | + fixer = _NoFixLevelID; // Nothing to fix! |
| | 967 | } |
| | 968 | - else if(nVersion == 0x12) { |
| | 969 | - /* Read number of player profiles */ |
| | 970 | - int nNumPlayerProfiles = FS::readInt(pfh); |
| | 971 | - |
| | 972 | - if(nNumPlayerProfiles >= 0) { |
| | 973 | - /* For each player profile */ |
| | 974 | - for(int i=0;i<nNumPlayerProfiles;i++) { |
| | 975 | - std::string PlayerName = FS::readString(pfh); |
| | 976 | - PlayerProfile *pPlayer = createProfile(PlayerName); |
| | 977 | - if(pPlayer != NULL) { |
| | 978 | - int nNumCompleted = FS::readInt(pfh); |
| | 979 | - int nNumSkipped = FS::readInt(pfh); |
| | 980 | - |
| | 981 | - for(int j=0;j<nNumCompleted;j++) |
| | 982 | - completeLevel(PlayerName,FS::readString(pfh)); |
| | 983 | - |
| | 984 | - for(int j=0;j<nNumSkipped;j++) |
| | 985 | - skipLevel(PlayerName,FS::readString(pfh)); |
| | 986 | - |
| | 987 | - while(1) { |
| | 988 | - std::string LevelID =FS::readString(pfh); |
| | 989 | - if(LevelID.length() == 0) break; |
| | 990 | - std::string Replay = FS::readString(pfh); |
| | 991 | - std::string TimeStamp = FS::readString(pfh); |
| | 992 | - float fTime = FS::readFloat(pfh); |
| | 993 | - addFinishTime(PlayerName,Replay,LevelID,fTime,TimeStamp); |
| | 994 | - } |
| | 995 | - } |
| | 996 | - } |
| | 997 | - } |
| | 998 | + |
| | 999 | + if (fixer != NULL) { |
| | 1000 | + _LoadFileHandle(pfh, fixer, swapped); |
| | 1001 | + } else { |
| | 1002 | + Log("** Warning ** : invalid/unsupported 'players.bin' file, all old stats is lost"); |
| | 1003 | } |
| | 1004 | - else Log("** Warning ** : invalid/unsupported 'players.bin' file, all old stats is lost"); |
| | 1005 | - |
| | 1006 | + |
| | 1007 | /* Clean */ |
| | 1008 | FS::closeFile(pfh); |
| | 1009 | } |
| | 1010 | @@ -198,12 +160,12 @@ |
| | 1011 | } |
| | 1012 | |
| | 1013 | /* Write */ |
| | 1014 | - FS::writeShort(pfh,0x12); |
| | 1015 | - FS::writeInt(pfh,m_Profiles.size()); |
| | 1016 | + FS::writeShort_LE(pfh,0x12); |
| | 1017 | + FS::writeInt_LE(pfh,m_Profiles.size()); |
| | 1018 | for(int i=0;i<m_Profiles.size();i++) { |
| | 1019 | FS::writeString(pfh,m_Profiles[i]->PlayerName); |
| | 1020 | - FS::writeInt(pfh,m_Profiles[i]->Completed.size()); |
| | 1021 | - FS::writeInt(pfh,m_Profiles[i]->Skipped.size()); |
| | 1022 | + FS::writeInt_LE(pfh,m_Profiles[i]->Completed.size()); |
| | 1023 | + FS::writeInt_LE(pfh,m_Profiles[i]->Skipped.size()); |
| | 1024 | |
| | 1025 | for(int j=0;j<m_Profiles[i]->Completed.size();j++) |
| | 1026 | FS::writeString(pfh,m_Profiles[i]->Completed[j]); |
| | 1027 | @@ -216,7 +178,7 @@ |
| | 1028 | FS::writeString(pfh,m_Profiles[i]->LevelStats[j]->LevelID); |
| | 1029 | FS::writeString(pfh,m_Profiles[i]->LevelStats[j]->BestTimes[k].Replay); |
| | 1030 | FS::writeString(pfh,m_Profiles[i]->LevelStats[j]->BestTimes[k].TimeStamp); |
| | 1031 | - FS::writeFloat(pfh,m_Profiles[i]->LevelStats[j]->BestTimes[k].fFinishTime); |
| | 1032 | + FS::writeFloat_LE(pfh,m_Profiles[i]->LevelStats[j]->BestTimes[k].fFinishTime); |
| | 1033 | } |
| | 1034 | } |
| | 1035 | |
| | 1036 | Index: src/PlayerData.h |
| | 1037 | =================================================================== |
| | 1038 | RCS file: /cvsroot/xmoto/xmoto/src/PlayerData.h,v |
| | 1039 | retrieving revision 1.6 |
| | 1040 | diff -a -u -r1.6 PlayerData.h |
| | 1041 | --- src/PlayerData.h 30 Jul 2006 10:48:21 -0000 1.6 |
| | 1042 | +++ src/PlayerData.h 10 Aug 2006 23:42:58 -0000 |
| | 1043 | @@ -105,10 +105,15 @@ |
| | 1044 | /* Data */ |
| | 1045 | std::vector<PlayerProfile *> m_Profiles; |
| | 1046 | |
| | 1047 | + |
| | 1048 | /* Helpers */ |
| | 1049 | + typedef std::string (*LevelFixer)(const std::string &); |
| | 1050 | + static std::string _NoFixLevelID (const std::string &); |
| | 1051 | + static std::string _Fix016LevelID(const std::string &); |
| | 1052 | + static std::string _Fix018LevelID(const std::string &); |
| | 1053 | + |
| | 1054 | + void _LoadFileHandle(FileHandle *pfh, LevelFixer fixer, bool swapped); |
| | 1055 | void _FreePlayerData(void); |
| | 1056 | - std::string _Fix016LevelID(const std::string &s); |
| | 1057 | - std::string _Fix018LevelID(const std::string &s); |
| | 1058 | }; |
| | 1059 | |
| | 1060 | } |