Skip to content
This repository
Browse code

Simplified (P)File classes

- ozCore
  * (P)File
    + immutable (setPath() removed)
    + stat() made private, automatically stat'd in ctor
    + mapping functionality removed for PFile (isMapped(), map(), unmap(),
      inputStream())
  * JSON: arrays iterators
  • Loading branch information...
commit cb35dd6d35c0069bb5436d4d7574f6718ae714f5 1 parent 75425c3
Davorin Učakar authored

Showing 58 changed files with 524 additions and 862 deletions. Show diff stats Hide diff stats

  1. +4 4 src/builder/BSP.cc
  2. +26 59 src/builder/Builder.cc
  3. +1 1  src/builder/Class.cc
  4. +26 26 src/builder/Context.cc
  5. +1 1  src/builder/FragPool.cc
  6. +5 8 src/builder/Lingua.cc
  7. +5 7 src/builder/MD2.cc
  8. +6 7 src/builder/MD3.cc
  9. +1 2  src/builder/OBJ.cc
  10. +1 1  src/builder/Terra.cc
  11. +7 10 src/builder/UI.cc
  12. +8 5 src/client/BSP.cc
  13. +1 1  src/client/BSP.hh
  14. +4 6 src/client/Caelum.cc
  15. +1 1  src/client/CinematicProxy.cc
  16. +2 2 src/client/Client.cc
  17. +15 10 src/client/Context.cc
  18. +2 2 src/client/GameStage.cc
  19. +3 3 src/client/Input.cc
  20. +6 18 src/client/Lua.cc
  21. +9 7 src/client/MD2.cc
  22. +3 2 src/client/MD2.hh
  23. +7 3 src/client/MD3.cc
  24. +2 1  src/client/MD3.hh
  25. +2 2 src/client/MenuStage.cc
  26. +2 2 src/client/Profile.cc
  27. +8 6 src/client/SMM.cc
  28. +5 4 src/client/SMM.hh
  29. +10 8 src/client/Shader.cc
  30. +6 7 src/client/Terra.cc
  31. +5 3 src/client/ui/CreditsMenu.cc
  32. +7 4 src/client/ui/Font.cc
  33. +2 2 src/client/ui/Font.hh
  34. +4 3 src/client/ui/GalileoFrame.cc
  35. +2 2 src/client/ui/MainMenu.cc
  36. +2 2 src/client/ui/MissionMenu.cc
  37. +4 4 src/client/ui/Mouse.cc
  38. +1 2  src/client/ui/Style.cc
  39. +14 17 src/common/Lingua.cc
  40. +10 12 src/matrix/BSP.cc
  41. +14 29 src/matrix/Liber.cc
  42. +3 9 src/matrix/Lua.cc
  43. +3 4 src/matrix/NamePool.cc
  44. +5 5 src/matrix/Terra.cc
  45. +3 9 src/nirvana/Lua.cc
  46. +1 1  src/ozCore/Buffer.cc
  47. +1 1  src/ozCore/Buffer.hh
  48. +61 130 src/ozCore/File.cc
  49. +47 39 src/ozCore/File.hh
  50. +14 46 src/ozCore/JSON.cc
  51. +7 26 src/ozCore/JSON.hh
  52. +50 181 src/ozCore/PFile.cc
  53. +42 66 src/ozCore/PFile.hh
  54. +2 2 src/ozCore/String.cc
  55. +2 2 src/ozCore/String.hh
  56. +1 1  src/tests/test.cc
  57. +38 40 src/tools/ozGettext.cc
  58. +0 4 src/tools/ozManifest.cc
8 src/builder/BSP.cc
@@ -48,7 +48,7 @@ void BSP::load()
48 48 PFile bspFile( String::str( "baseq3/maps/%s.bsp", name.cstr() ) );
49 49
50 50 JSON config;
51   - if( !config.load( &configFile ) ) {
  51 + if( !config.load( configFile ) ) {
52 52 OZ_ERROR( "BSP config loading failed" );
53 53 }
54 54
@@ -83,11 +83,12 @@ void BSP::load()
83 83 OZ_ERROR( "Invalid BSP config" );
84 84 }
85 85
86   - if( !bspFile.map() ) {
  86 + if( bspFile.type() != File::REGULAR ) {
87 87 OZ_ERROR( "BSP reading failed" );
88 88 }
89 89
90   - InputStream is = bspFile.inputStream( Endian::LITTLE );
  90 + Buffer buffer = bspFile.read();
  91 + InputStream is = buffer.inputStream( Endian::LITTLE );
91 92
92 93 char id[4];
93 94 id[0] = is.readChar();
@@ -499,7 +500,6 @@ void BSP::load()
499 500 }
500 501 }
501 502
502   - bspFile.unmap();
503 503 config.clear( true );
504 504 }
505 505
85 src/builder/Builder.cc
@@ -106,8 +106,6 @@ void Builder::copyFiles( const char* srcDir, const char* destDir, const char* ex
106 106 foreach( file, dirList.iter() ) {
107 107 String fileName = file->name();
108 108
109   - file->stat();
110   -
111 109 if( file->type() == File::DIRECTORY ) {
112 110 if( recurse ) {
113 111 copyFiles( srcDir + ( "/" + file->name() ), destDir + ( "/" + file->name() ), ext, true );
@@ -118,19 +116,11 @@ void Builder::copyFiles( const char* srcDir, const char* destDir, const char* ex
118 116 {
119 117 Log::print( "Copying '%s' ...", fileName.cstr() );
120 118
121   - if( !file->map() ) {
122   - OZ_ERROR( "Failed to map '%s'", file->path().cstr() );
123   - }
124   -
125   - InputStream is = file->inputStream();
126 119 File destFile( sDestDir + fileName );
127   -
128   - if( !destFile.write( is.begin(), is.capacity() ) ) {
  120 + if( !destFile.write( file->read() ) ) {
129 121 OZ_ERROR( "Failed to write '%s'", file->path().cstr() );
130 122 }
131 123
132   - file->unmap();
133   -
134 124 Log::printEnd( " OK" );
135 125 continue;
136 126 }
@@ -231,8 +221,6 @@ void Builder::buildBSPTextures()
231 221 DArray<PFile> dirList = dir.ls();
232 222
233 223 foreach( subDir, dirList.iter() ) {
234   - subDir->stat();
235   -
236 224 if( subDir->type() != File::DIRECTORY ) {
237 225 continue;
238 226 }
@@ -316,28 +304,24 @@ void Builder::buildBSPTextures()
316 304 DArray<PFile> texList = subDir.ls();
317 305
318 306 foreach( file, texList.iter() ) {
  307 + if( file->type() != File::REGULAR ) {
  308 + continue;
  309 + }
  310 +
319 311 String name = file->name();
320 312 String path = file->path();
321 313
322 314 if( name.beginsWith( "COPYING" ) || name.beginsWith( "README" ) ) {
323 315 Log::print( "Copying '%s' ...", path.cstr() );
324 316
325   - if( !file->map() ) {
326   - OZ_ERROR( "Failed to read '%s'", file->path().cstr() );
327   - }
328   -
329   - InputStream is = file->inputStream();
330   - File destFile( String::str( "tex/%s/%s", subDir.name().cstr(), name.cstr() ) );
331   -
332 317 File::mkdir( "tex" );
333 318 File::mkdir( "tex/" + subDir.name() );
334 319
335   - if( !destFile.write( is.begin(), is.capacity() ) ) {
  320 + File destFile( String::str( "tex/%s/%s", subDir.name().cstr(), name.cstr() ) );
  321 + if( !destFile.write( file->read() ) ) {
336 322 OZ_ERROR( "Failed to write '%s'", destFile.path().cstr() );
337 323 }
338 324
339   - file->unmap();
340   -
341 325 Log::printEnd( " OK" );
342 326 continue;
343 327 }
@@ -488,34 +472,30 @@ void Builder::buildModels()
488 472 DArray<PFile> fileList = dir->ls();
489 473
490 474 foreach( file, fileList.iter() ) {
  475 + if( file->type() != File::REGULAR ) {
  476 + continue;
  477 + }
  478 +
491 479 String name = file->name();
492 480 String path = file->path();
493 481
494 482 if( name.beginsWith( "COPYING" ) || name.beginsWith( "README" ) ) {
495 483 Log::print( "Copying '%s' ...", path.cstr() );
496 484
497   - if( !file->map() ) {
498   - OZ_ERROR( "Failed to read '%s'", file->path().cstr() );
499   - }
500   -
501   - InputStream is = file->inputStream();
502 485 File destFile( path );
503   -
504   - if( !destFile.write( is.begin(), is.length() ) ) {
  486 + if( !destFile.write( file->read() ) ) {
505 487 OZ_ERROR( "Failed to write '%s'", destFile.path().cstr() );
506 488 }
507 489
508   - file->unmap();
509   -
510 490 Log::printEnd( " OK" );
511 491 continue;
512 492 }
513 493 }
514 494
515   - if( PFile( dir->path() + "/data.obj" ).stat() ) {
  495 + if( PFile( dir->path() + "/data.obj" ).type() != File::MISSING ) {
516 496 obj.build( dir->path() );
517 497 }
518   - else if( PFile( dir->path() + "/tris.md2" ).stat() ) {
  498 + else if( PFile( dir->path() + "/tris.md2" ).type() != File::MISSING ) {
519 499 md2.build( dir->path() );
520 500 }
521 501 else {
@@ -542,8 +522,6 @@ void Builder::copySounds()
542 522 DArray<PFile> dirList = dir.ls();
543 523
544 524 foreach( subDir, dirList.iter() ) {
545   - subDir->stat();
546   -
547 525 if( subDir->type() != File::DIRECTORY ) {
548 526 continue;
549 527 }
@@ -551,6 +529,10 @@ void Builder::copySounds()
551 529 DArray<PFile> sndList = subDir->ls();
552 530
553 531 foreach( file, sndList.iter() ) {
  532 + if( file->type() != File::REGULAR ) {
  533 + continue;
  534 + }
  535 +
554 536 String name = file->name();
555 537 String path = file->path();
556 538
@@ -576,20 +558,11 @@ void Builder::copySounds()
576 558 File::mkdir( "snd" );
577 559 File::mkdir( "snd/" + subDir->name() );
578 560
579   - if( !file->map() ) {
580   - OZ_ERROR( "Failed to copy '%s'", file->path().cstr() );
581   - }
582   -
583   - InputStream is = file->inputStream();
584   -
585 561 File destFile( file->path() );
586   -
587   - if( !destFile.write( is.begin(), is.capacity() ) ) {
  562 + if( !destFile.write( file->read() ) ) {
588 563 OZ_ERROR( "Failed to write '%s'", destFile.path().cstr() );
589 564 }
590 565
591   - file->unmap();
592   -
593 566 Log::printEnd( " OK" );
594 567 }
595 568 }
@@ -599,28 +572,24 @@ void Builder::copySounds()
599 572 DArray<PFile> texList = subDir.ls();
600 573
601 574 foreach( file, texList.iter() ) {
  575 + if( file->type() != File::REGULAR ) {
  576 + continue;
  577 + }
  578 +
602 579 String name = file->name();
603 580 String path = file->path();
604 581
605 582 if( name.beginsWith( "COPYING" ) || name.beginsWith( "README" ) ) {
606 583 Log::print( "Copying '%s' ...", path.cstr() );
607 584
608   - if( !file->map() ) {
609   - OZ_ERROR( "Failed to read '%s'", file->path().cstr() );
610   - }
611   -
612   - InputStream is = file->inputStream();
613   - File destFile( path );
614   -
615 585 File::mkdir( "snd" );
616 586 File::mkdir( "snd/" + subDir.name() );
617 587
618   - if( !destFile.write( is.begin(), is.capacity() ) ) {
  588 + File destFile( path );
  589 + if( !destFile.write( file->read() ) ) {
619 590 OZ_ERROR( "Failed to write '%s'", destFile.path().cstr() );
620 591 }
621 592
622   - file->unmap();
623   -
624 593 Log::printEnd( " OK" );
625 594 continue;
626 595 }
@@ -683,7 +652,7 @@ void Builder::buildMissions()
683 652 PFile srcFile( mission->path() + "/description.png" );
684 653 File outFile( mission->path() + "/description.ozImage" );
685 654
686   - if( !srcFile.stat() ) {
  655 + if( srcFile.type() == File::MISSING ) {
687 656 continue;
688 657 }
689 658
@@ -727,9 +696,7 @@ void Builder::packArchive( const char* name, bool useCompression, bool use7zip )
727 696 OZ_ERROR( use7zip ? "Packing 7zip archive failed" : "Packing ZIP archive failed" );
728 697 }
729 698
730   - archive.stat();
731 699 int size = archive.size();
732   -
733 700 if( size >= 0 ) {
734 701 Log::println();
735 702 Log::println( "Archive size: %.2f MiB = %.2f MB",
2  src/builder/Class.cc
@@ -767,7 +767,7 @@ void Class::build( BufferStream* os, const char* className )
767 767 {
768 768 PFile configFile( String::str( "class/%s.json", className ) );
769 769
770   - if( !config.load( &configFile ) ) {
  770 + if( !config.load( configFile ) ) {
771 771 OZ_ERROR( "Failed to load '%s'", configFile.path().cstr() );
772 772 }
773 773
52 src/builder/Context.cc
@@ -312,7 +312,7 @@ Context::Image Context::loadImage( const char* path, int forceFormat )
312 312 PFile file( path );
313 313 String realPath = file.realDir() + "/" + file.path();
314 314
315   - if( !file.stat() ) {
  315 + if( file.type() == File::MISSING ) {
316 316 OZ_ERROR( "File '%s' does not exits", realPath.cstr() );
317 317 }
318 318
@@ -440,43 +440,43 @@ void Context::loadTextures( Texture* diffuseTex, Texture* masksTex, Texture* nor
440 440 PFile diffuse, masks, specular, emission, normals;
441 441
442 442 for( int i = 0; i < aLength( IMAGE_EXTENSIONS ); ++i ) {
443   - if( diffuse.path().isEmpty() || !diffuse.stat() ) {
444   - diffuse.setPath( diffuseBasePath + IMAGE_EXTENSIONS[i] );
  443 + if( diffuse.path().isEmpty() || diffuse.type() == File::MISSING ) {
  444 + diffuse = PFile( diffuseBasePath + IMAGE_EXTENSIONS[i] );
445 445 }
446   - if( !diffuse.stat() ) {
447   - diffuse.setPath( diffuse1BasePath + IMAGE_EXTENSIONS[i] );
  446 + if( diffuse.type() == File::MISSING ) {
  447 + diffuse = PFile( diffuse1BasePath + IMAGE_EXTENSIONS[i] );
448 448 }
449 449
450   - if( masks.path().isEmpty() || !masks.stat() ) {
451   - masks.setPath( masksBasePath + IMAGE_EXTENSIONS[i] );
  450 + if( masks.path().isEmpty() || masks.type() == File::MISSING ) {
  451 + masks = PFile( masksBasePath + IMAGE_EXTENSIONS[i] );
452 452 }
453 453
454   - if( specular.path().isEmpty() || !specular.stat() ) {
455   - specular.setPath( specularBasePath + IMAGE_EXTENSIONS[i] );
  454 + if( specular.path().isEmpty() || specular.type() == File::MISSING ) {
  455 + specular = PFile( specularBasePath + IMAGE_EXTENSIONS[i] );
456 456 }
457   - if( !specular.stat() ) {
458   - specular.setPath( specular1BasePath + IMAGE_EXTENSIONS[i] );
  457 + if( specular.type() == File::MISSING ) {
  458 + specular = PFile( specular1BasePath + IMAGE_EXTENSIONS[i] );
459 459 }
460 460
461   - if( emission.path().isEmpty() || !emission.stat() ) {
462   - emission.setPath( emissionBasePath + IMAGE_EXTENSIONS[i] );
  461 + if( emission.path().isEmpty() || emission.type() == File::MISSING ) {
  462 + emission = PFile( emissionBasePath + IMAGE_EXTENSIONS[i] );
463 463 }
464 464
465   - if( normals.path().isEmpty() || !normals.stat() ) {
466   - normals.setPath( normalsBasePath + IMAGE_EXTENSIONS[i] );
  465 + if( normals.path().isEmpty() || normals.type() == File::MISSING ) {
  466 + normals = PFile( normalsBasePath + IMAGE_EXTENSIONS[i] );
467 467 }
468   - if( !normals.stat() ) {
469   - normals.setPath( normals1BasePath + IMAGE_EXTENSIONS[i] );
  468 + if( normals.type() == File::MISSING ) {
  469 + normals = PFile( normals1BasePath + IMAGE_EXTENSIONS[i] );
470 470 }
471   - if( !normals.stat() ) {
472   - normals.setPath( normals2BasePath + IMAGE_EXTENSIONS[i] );
  471 + if( normals.type() == File::MISSING ) {
  472 + normals = PFile( normals2BasePath + IMAGE_EXTENSIONS[i] );
473 473 }
474   - if( !normals.stat() ) {
475   - normals.setPath( normals3BasePath + IMAGE_EXTENSIONS[i] );
  474 + if( normals.type() == File::MISSING ) {
  475 + normals = PFile( normals3BasePath + IMAGE_EXTENSIONS[i] );
476 476 }
477 477 }
478 478
479   - if( diffuse.stat() ) {
  479 + if( diffuse.type() != File::MISSING ) {
480 480 Image diffuseImage = loadImage( diffuse.path() );
481 481
482 482 *diffuseTex = Texture( &diffuseImage, wrap, magFilter, minFilter );
@@ -486,7 +486,7 @@ void Context::loadTextures( Texture* diffuseTex, Texture* masksTex, Texture* nor
486 486 OZ_ERROR( "Missing texture '%s' (.png, .jpeg, .jpg and .tga checked)", basePath.cstr() );
487 487 }
488 488
489   - if( masks.stat() ) {
  489 + if( masks.type() != File::MISSING ) {
490 490 Image masksImage = loadImage( masks.path(), GL_RGB );
491 491
492 492 *masksTex = Texture( &masksImage, wrap, magFilter, minFilter );
@@ -497,10 +497,10 @@ void Context::loadTextures( Texture* diffuseTex, Texture* masksTex, Texture* nor
497 497 specularImage.dib = nullptr;
498 498 emissionImage.dib = nullptr;
499 499
500   - if( specular.stat() ) {
  500 + if( specular.type() != File::MISSING ) {
501 501 specularImage = loadImage( specular.path(), GL_RGB );
502 502 }
503   - if( emission.stat() ) {
  503 + if( emission.type() != File::MISSING ) {
504 504 emissionImage = loadImage( emission.path(), GL_LUMINANCE );
505 505 }
506 506
@@ -565,7 +565,7 @@ void Context::loadTextures( Texture* diffuseTex, Texture* masksTex, Texture* nor
565 565 }
566 566 }
567 567
568   - if( bumpmap && normals.stat() ) {
  568 + if( bumpmap && normals.type() != File::MISSING ) {
569 569 Image normalsImage = loadImage( normals.path() );
570 570
571 571 *normalsTex = Texture( &normalsImage, wrap, magFilter, minFilter );
2  src/builder/FragPool.cc
@@ -41,7 +41,7 @@ void FragPool::build( BufferStream* os, const char* className )
41 41 PFile configFile( String::str( "frag/%s.json", className ) );
42 42
43 43 JSON config;
44   - if( !config.load( &configFile ) ) {
  44 + if( !config.load( configFile ) ) {
45 45 OZ_ERROR( "Failed to load '%s'", configFile.path().cstr() );
46 46 }
47 47
13 src/builder/Lingua.cc
@@ -34,11 +34,12 @@ void Lingua::buildCatalogue( const char* directory, const char* catalogue )
34 34 PFile srcFile( String::str( "%s/%s.po", directory, catalogue ) );
35 35 File outFile( String::str( "%s/%s.ozCat", directory, catalogue ) );
36 36
37   - if( !srcFile.map() ) {
38   - OZ_ERROR( "Cannot map catalogue source file '%s'", srcFile.path().cstr() );
  37 + if( srcFile.type() != File::REGULAR ) {
  38 + OZ_ERROR( "Cannot read catalogue source file '%s'", srcFile.path().cstr() );
39 39 }
40 40
41   - InputStream is = srcFile.inputStream();
  41 + Buffer buffer = srcFile.read();
  42 + InputStream is = buffer.inputStream();
42 43
43 44 List<String> messages;
44 45
@@ -133,8 +134,6 @@ void Lingua::buildCatalogue( const char* directory, const char* catalogue )
133 134 }
134 135 }
135 136
136   - srcFile.unmap();
137   -
138 137 if( !lastOriginal.isEmpty() && !lastOriginal.equals( lastTranslation ) ) {
139 138 messages.add( lastOriginal );
140 139 messages.add( lastTranslation );
@@ -170,8 +169,6 @@ void Lingua::build()
170 169 }
171 170
172 171 foreach( langDir, languages.iter() ) {
173   - langDir->stat();
174   -
175 172 if( langDir->type() != File::DIRECTORY ) {
176 173 continue;
177 174 }
@@ -195,7 +192,7 @@ void Lingua::build()
195 192 DArray<PFile> missions = missionsDir.ls();
196 193
197 194 foreach( mission, missions.citer() ) {
198   - linguaDir.setPath( mission->path() + "/lingua" );
  195 + linguaDir = PFile( mission->path() + "/lingua" );
199 196 languages = linguaDir.ls();
200 197
201 198 foreach( catalogue, languages.citer() ) {
12 src/builder/MD2.cc
@@ -211,14 +211,14 @@ void MD2::build( const char* path )
211 211 Log::println( "Prebuilding MD2 model '%s' {", path );
212 212 Log::indent();
213 213
214   - JSON config;
215   - config.load( &configFile );
  214 + JSON config( configFile );
216 215
217   - if( !modelFile.map() ) {
218   - OZ_ERROR( "MD2 reading failed" );
  216 + if( modelFile.type() != File::REGULAR ) {
  217 + OZ_ERROR( "MD2 file read failed" );
219 218 }
220 219
221   - InputStream is = modelFile.inputStream( Endian::LITTLE );
  220 + Buffer buffer = modelFile.read();
  221 + InputStream is = buffer.inputStream( Endian::LITTLE );
222 222
223 223 MD2Header header;
224 224
@@ -339,8 +339,6 @@ void MD2::build( const char* path )
339 339 triangles[i].texCoords[2] = is.readShort();
340 340 }
341 341
342   - modelFile.unmap();
343   -
344 342 compiler.beginMesh();
345 343 compiler.enable( Compiler::UNIQUE );
346 344 compiler.enable( Compiler::CLOCKWISE );
13 src/builder/MD3.cc
@@ -58,11 +58,13 @@ void MD3::buildMesh( const char* name, int frame )
58 58 Log::print( "Mesh '%s' ...", name );
59 59
60 60 PFile file( String::str( "%s/%s.md3", sPath.cstr(), name ) );
61   - if( !file.map() ) {
62   - OZ_ERROR( "Cannot mmap MD3 model part file '%s'", file.path().cstr() );
  61 +
  62 + if( file.type() != File::REGULAR ) {
  63 + OZ_ERROR( "Cannot read MD3 model part file '%s'", file.path().cstr() );
63 64 }
64 65
65   - InputStream is = file.inputStream( Endian::LITTLE );
  66 + Buffer buffer = file.read();
  67 + InputStream is = buffer.inputStream( Endian::LITTLE );
66 68
67 69 MD3Header header;
68 70
@@ -265,8 +267,6 @@ void MD3::buildMesh( const char* name, int frame )
265 267 indexBase += surface.nVertices;
266 268 }
267 269
268   - file.unmap();
269   -
270 270 Log::printEnd( " OK" );
271 271 }
272 272
@@ -274,8 +274,7 @@ void MD3::load()
274 274 {
275 275 PFile configFile( sPath + "/config.json" );
276 276
277   - JSON config;
278   - config.load( &configFile );
  277 + JSON config( configFile );
279 278
280 279 scale = config["scale"].get( 0.04f );
281 280 skin = config["skin"].get( "" );
3  src/builder/OBJ.cc
@@ -279,8 +279,7 @@ void OBJ::load()
279 279
280 280 int currentMaterial = 0;
281 281
282   - JSON config;
283   - config.load( &configFile );
  282 + JSON config( configFile );
284 283
285 284 float scale = config["scale"].get( 1.0f );
286 285 Vec3 translation = config["translate"].get( Vec3::ZERO );
2  src/builder/Terra.cc
@@ -40,7 +40,7 @@ void Terra::load()
40 40 PFile imageFile( "terra/" + name + ".png" );
41 41
42 42 JSON config;
43   - if( !config.load( &configFile ) ) {
  43 + if( !config.load( configFile ) ) {
44 44 OZ_ERROR( "Failed to loa terra configuration '%s'", configFile.path().cstr() );
45 45 }
46 46
17 src/builder/UI.cc
@@ -54,7 +54,7 @@ const char* const UI::ICON_NAMES[] = {
54 54
55 55 void UI::buildCursors()
56 56 {
57   - if( !PFile( "ui/cur" ).stat() ) {
  57 + if( PFile( "ui/cur" ).type() == File::MISSING ) {
58 58 return;
59 59 }
60 60
@@ -109,7 +109,7 @@ void UI::buildCursors()
109 109
110 110 void UI::buildIcons()
111 111 {
112   - if( !PFile( "ui/icon" ).stat() ) {
  112 + if( PFile( "ui/icon" ).type() == File::MISSING ) {
113 113 return;
114 114 }
115 115
@@ -150,16 +150,13 @@ void UI::copyScheme()
150 150 PFile srcFile( "ui/style.json" );
151 151 File outFile( "ui/style.json" );
152 152
153   - Buffer buffer = srcFile.read();
154   - if( buffer.isEmpty() ) {
155   - return;
156   - }
  153 + if( srcFile.type() == File::REGULAR ) {
  154 + Log::print( "Copying UI colour scheme '%s' ...", srcFile.path().cstr() );
157 155
158   - Log::print( "Copying UI colour scheme '%s' ...", srcFile.path().cstr() );
  156 + outFile.write( srcFile.read() );
159 157
160   - outFile.write( buffer.begin(), buffer.length() );
161   -
162   - Log::printEnd( " OK" );
  158 + Log::printEnd( " OK" );
  159 + }
163 160 }
164 161
165 162 }
13 src/client/BSP.cc
@@ -34,7 +34,7 @@ namespace client
34 34 {
35 35
36 36 BSP::BSP( const matrix::BSP* bsp_ ) :
37   - bsp( bsp_ ), file( "bsp/" + bsp->name + ".ozcBSP" ), isPreloaded( false ), isLoaded( false )
  37 + bsp( bsp_ ), isPreloaded( false ), isLoaded( false )
38 38 {
39 39 foreach( model, bsp->models.citer() ) {
40 40 context.requestSMM( *model );
@@ -54,8 +54,11 @@ BSP::~BSP()
54 54
55 55 void BSP::preload()
56 56 {
57   - if( !file.map() ) {
58   - OZ_ERROR( "BSP file '%s' mmap failed", file.path().cstr() );
  57 + PFile file( "bsp/" + bsp->name + ".ozcBSP" );
  58 +
  59 + buffer = file.read();
  60 + if( buffer.isEmpty() ) {
  61 + OZ_ERROR( "BSP file '%s' read failed", file.path().cstr() );
59 62 }
60 63
61 64 isPreloaded = true;
@@ -63,7 +66,7 @@ void BSP::preload()
63 66
64 67 void BSP::load()
65 68 {
66   - InputStream istream = file.inputStream();
  69 + InputStream istream = buffer.inputStream();
67 70
68 71 waterFogColour = istream.readVec4();
69 72 lavaFogColour = istream.readVec4();
@@ -72,7 +75,7 @@ void BSP::load()
72 75
73 76 hard_assert( !istream.isAvailable() );
74 77
75   - file.setPath( "" );
  78 + buffer.deallocate();
76 79
77 80 isLoaded = true;
78 81 }
2  src/client/BSP.hh
@@ -36,7 +36,7 @@ class BSP
36 36
37 37 const matrix::BSP* bsp;
38 38 Mesh mesh;
39   - PFile file;
  39 + Buffer buffer;
40 40
41 41 public:
42 42
10 src/client/Caelum.cc
@@ -167,12 +167,12 @@ void Caelum::load()
167 167 Math::sin( orbis.caelum.heading ),
168 168 0.0f );
169 169
170   - PFile file( path );
171   - if( !file.map() ) {
172   - OZ_ERROR( "Caelum file '%s' mmap failed", path.cstr() );
  170 + Buffer buffer = PFile( path ).read();
  171 + if( buffer.isEmpty() ) {
  172 + OZ_ERROR( "Caelum file '%s' read failed", path.cstr() );
173 173 }
174 174
175   - InputStream is = file.inputStream();
  175 + InputStream is = buffer.inputStream();
176 176
177 177 int vboSize = MAX_STARS * 4 * int( sizeof( float[3] ) );
178 178 int iboSize = MAX_STARS * 6 * int( sizeof( ushort ) );
@@ -196,8 +196,6 @@ void Caelum::load()
196 196 nightColour = Vec4( NIGHT_COLOUR );
197 197 nightLuminance = ( nightColour.x + nightColour.y + nightColour.z ) / 3.0f;
198 198
199   - file.unmap();
200   -
201 199 OZ_GL_CHECK_ERROR();
202 200
203 201 update();
2  src/client/CinematicProxy.cc
@@ -55,7 +55,7 @@ void CinematicProxy::executeSequence( const char* path, const Lingua* missionLin
55 55 JSON sequence;
56 56 PFile file( path );
57 57
58   - if( !sequence.load( &file ) ) {
  58 + if( !sequence.load( file ) ) {
59 59 OZ_ERROR( "Failed to load sequence from '%s'", file.path().cstr() );
60 60 }
61 61
4 src/client/Client.cc
@@ -246,7 +246,7 @@ int Client::init( int argc, char** argv )
246 246 File::rm( configDir + "/client.rc" );
247 247
248 248 File configFile( configDir + "/client.json" );
249   - if( config.load( &configFile ) ) {
  249 + if( config.load( configFile ) ) {
250 250 Log::printEnd( "Configuration read from '%s'", configFile.path().cstr() );
251 251
252 252 if( String::equals( config["_version"].get( "" ), OZ_VERSION ) ) {
@@ -526,7 +526,7 @@ void Client::shutdown()
526 526
527 527 Log::print( "Writing configuration to '%s' ...", configFile.path().cstr() );
528 528
529   - config.save( &configFile );
  529 + config.save( configFile );
530 530
531 531 Log::printEnd( " OK" );
532 532 }
25 src/client/Context.cc
@@ -318,11 +318,13 @@ uint Context::readTextureLayer( InputStream* istream )
318 318 uint Context::loadTextureLayer( const char* path )
319 319 {
320 320 PFile file( path );
321   - if( !file.map() ) {
322   - OZ_ERROR( "Texture file '%s' mmap failed", path );
  321 + Buffer buffer = file.read();
  322 +
  323 + if( buffer.isEmpty() ) {
  324 + OZ_ERROR( "Texture file '%s' mmap failed", file.path().cstr() );
323 325 }
324 326
325   - InputStream is = file.inputStream();
  327 + InputStream is = buffer.inputStream();
326 328 return readTextureLayer( &is );
327 329 }
328 330
@@ -343,11 +345,13 @@ Texture Context::readTexture( InputStream* istream )
343 345 Texture Context::loadTexture( const char* path )
344 346 {
345 347 PFile file( path );
346   - if( !file.map() ) {
347   - OZ_ERROR( "Texture file '%s' mmap failed", path );
  348 + Buffer buffer = file.read();
  349 +
  350 + if( buffer.isEmpty() ) {
  351 + OZ_ERROR( "Texture file '%s' read failed", path );
348 352 }
349 353
350   - InputStream is = file.inputStream();
  354 + InputStream is = buffer.inputStream();
351 355 return readTexture( &is );
352 356 }
353 357
@@ -399,11 +403,13 @@ uint Context::requestSound( int id )
399 403 const String& path = liber.sounds[id].path;
400 404
401 405 PFile file( path );
402   - if( !file.map() ) {
403   - OZ_ERROR( "Sound file '%s' mmap failed", path.cstr() );
  406 + Buffer buffer = file.read();
  407 +
  408 + if( buffer.isEmpty() ) {
  409 + OZ_ERROR( "Sound file '%s' read failed", path.cstr() );
404 410 }
405 411
406   - InputStream is = file.inputStream();
  412 + InputStream is = buffer.inputStream();
407 413
408 414 uint length;
409 415 ubyte* data;
@@ -432,7 +438,6 @@ uint Context::requestSound( int id )
432 438 alBufferData( resource.id, format, data, int( length ), audioSpec.freq );
433 439
434 440 SDL_FreeWAV( data );
435   - file.unmap();
436 441
437 442 OZ_AL_CHECK_ERROR();
438 443
4 src/client/GameStage.cc
@@ -264,7 +264,7 @@ bool GameStage::update()
264 264 if( input.keys[Input::KEY_QUICKLOAD] && !input.oldKeys[Input::KEY_QUICKLOAD] ) {
265 265 File quicksaveFile( QUICKSAVE_FILE );
266 266
267   - if( quicksaveFile.stat() ) {
  267 + if( quicksaveFile.type() == File::REGULAR ) {
268 268 stateFile = QUICKSAVE_FILE;
269 269 reload();
270 270 }
@@ -272,7 +272,7 @@ bool GameStage::update()
272 272 if( input.keys[Input::KEY_AUTOLOAD] && !input.oldKeys[Input::KEY_AUTOLOAD] ) {
273 273 File autosaveFile( AUTOSAVE_FILE );
274 274
275   - if( autosaveFile.stat() ) {
  275 + if( autosaveFile.type() == File::REGULAR ) {
276 276 stateFile = AUTOSAVE_FILE;
277 277 reload();
278 278 }
6 src/client/Input.cc
@@ -469,7 +469,7 @@ void Input::update()
469 469 mouseX = +float( dx );
470 470 mouseY = -float( dy );
471 471
472   -# if SDL_MAJOR_VERSION < 2 && !defined( _WIN32 )
  472 +# ifndef _WIN32
473 473 if( window.hasGrab ) {
474 474 // Compensate lack of mouse acceleration when receiving raw (non-accelerated) mouse input. This
475 475 // code is not based on actual code from X.Org, but experimentally tuned to match default X
@@ -547,7 +547,7 @@ void Input::init()
547 547 Log::print( "Initialising Input from '%s' ...", configFile.path().cstr() );
548 548
549 549 JSON inputConfig;
550   - configExists = inputConfig.load( &configFile );
  550 + configExists = inputConfig.load( configFile );
551 551
552 552 if( !String::equals( inputConfig["_version"].get( "" ), OZ_VERSION ) ) {
553 553 configExists = false;
@@ -663,7 +663,7 @@ void Input::destroy()
663 663 keyboardConfig.add( "sensitivity.y", keySensY );
664 664 keyMapConfig = keyMapToJSON();
665 665
666   - if( !inputConfig.save( &configFile ) ) {
  666 + if( !inputConfig.save( configFile ) ) {
667 667 OZ_ERROR( "Failed to write '%s'", configFile.path().cstr() );
668 668 }
669 669
24 src/client/Lua.cc
@@ -85,21 +85,15 @@ void Lua::create( const char* mission_ )
85 85 }
86 86
87 87 foreach( file, files.iter() ) {
88   - if( !file->hasExtension( "lua" ) ) {
  88 + if( file->type() != File::REGULAR || !file->hasExtension( "lua" ) ) {
89 89 continue;
90 90 }
91 91
92   - if( !file->map() ) {
93   - OZ_ERROR( "Failed to read mission script '%s'", file->path().cstr() );
94   - }
95   -
96   - InputStream is = file->inputStream();
  92 + Buffer buffer = file->read();
97 93
98   - if( l_dobuffer( is.begin(), is.capacity(), file->path() ) != 0 ) {
  94 + if( !buffer.isEmpty() && l_dobuffer( buffer.begin(), buffer.length(), file->path() ) != 0 ) {
99 95 OZ_ERROR( "Client Lua script error in %s", file->path().cstr() );
100 96 }
101   -
102   - file->unmap();
103 97 }
104 98
105 99 staticCall( "onCreate" );
@@ -135,21 +129,15 @@ void Lua::read( InputStream* istream )
135 129 }
136 130
137 131 foreach( file, files.iter() ) {
138   - if( !file->hasExtension( "lua" ) ) {
  132 + if( file->type() != File::REGULAR || !file->hasExtension( "lua" ) ) {
139 133 continue;
140 134 }
141 135
142   - if( !file->map() ) {
143   - OZ_ERROR( "Failed to read mission script '%s'", file->path().cstr() );
144   - }
145   -
146   - InputStream is = file->inputStream();
  136 + Buffer buffer = file->read();
147 137
148   - if( l_dobuffer( is.begin(), is.capacity(), file->path() ) != 0 ) {
  138 + if( !buffer.isEmpty() && l_dobuffer( buffer.begin(), buffer.length(), file->path() ) != 0 ) {
149 139 OZ_ERROR( "Client Lua script error in %s", file->path().cstr() );
150 140 }
151   -
152   - file->unmap();
153 141 }
154 142
155 143 const char* name = istream->readString();
16 src/client/MD2.cc
@@ -221,14 +221,17 @@ void MD2::AnimState::advance()
221 221 hard_assert( 0.0f <= frameRatio && frameRatio < 1.0f );
222 222 }
223 223
224   -MD2::MD2( int id ) :
225   - file( liber.models[id].path ), isPreloaded( false ), isLoaded( false )
  224 +MD2::MD2( int id_ ) :
  225 + id( id_ ), isPreloaded( false ), isLoaded( false )
226 226 {}
227 227
228 228 void MD2::preload()
229 229 {
230   - if( !file.map() ) {
231   - OZ_ERROR( "MD2 model file '%s' mmap failed", file.path().cstr() );
  230 + PFile file( liber.models[id].path );
  231 +
  232 + buffer = file.read();
  233 + if( buffer.isEmpty() ) {
  234 + OZ_ERROR( "MD2 model file '%s' read failed", file.path().cstr() );
232 235 }
233 236
234 237 isPreloaded = true;
@@ -236,15 +239,14 @@ void MD2::preload()
236 239
237 240 void MD2::load()
238 241 {
239   - InputStream is = file.inputStream();
  242 + InputStream is = buffer.inputStream();
240 243
241 244 weaponTransf = is.readMat44();
242   -
243 245 mesh.load( &is, shader.hasVertexTexture ? GL_STATIC_DRAW : GL_STREAM_DRAW );
244 246
245 247 hard_assert( !is.isAvailable() );
246 248
247   - file.setPath( "" );
  249 + buffer.deallocate();
248 250
249 251 isLoaded = true;
250 252 }
5 src/client/MD2.hh
@@ -104,8 +104,9 @@ class MD2
104 104
105 105 private:
106 106
107   - Mesh mesh;
108   - PFile file;
  107 + int id;
  108 + Buffer buffer;
  109 + Mesh mesh;
109 110
110 111 public:
111 112
10 src/client/MD3.cc
@@ -32,13 +32,16 @@ namespace oz
32 32 namespace client
33 33 {
34 34
35   -MD3::MD3( int id ) :
36   - file( liber.models[id].path ), isPreloaded( false ), isLoaded( false )
  35 +MD3::MD3( int id_ ) :
  36 + id( id_ ), isPreloaded( false ), isLoaded( false )
37 37 {}
38 38
39 39 void MD3::preload()
40 40 {
41   - if( !file.map() ) {
  41 + PFile file( liber.models[id].path );
  42 +
  43 + buffer = file.read();
  44 + if( buffer.isEmpty() ) {
42 45 OZ_ERROR( "MD3 model file '%s' mmap failed", file.path().cstr() );
43 46 }
44 47
@@ -47,6 +50,7 @@ void MD3::preload()
47 50
48 51 void MD3::load()
49 52 {
  53 + buffer.deallocate();
50 54 isLoaded = true;
51 55 }
52 56
3  src/client/MD3.hh
@@ -127,7 +127,8 @@ class MD3
127 127 // AnimInfo torsoAnimList[TORSO_ANIM_MAX];
128 128 // Joint joints[MAX_FRAMES][JOINTS_MAX];
129 129
130   - PFile file;
  130 + int id;
  131 + Buffer buffer;
131 132
132 133 public:
133 134
4 src/client/MenuStage.cc
@@ -66,10 +66,10 @@ void MenuStage::load()
66 66 File autosaveFile( GameStage::AUTOSAVE_FILE );
67 67 File quicksaveFile( GameStage::QUICKSAVE_FILE );
68 68
69   - if( autosaveFile.stat() ) {
  69 + if( autosaveFile.type() == File::REGULAR ) {
70 70 showAutosaved = true;
71 71 }
72   - if( quicksaveFile.stat() ) {
  72 + if( quicksaveFile.type() == File::REGULAR ) {
73 73 showQuicksaved = true;
74 74 }
75 75
4 src/client/Profile.cc
@@ -42,7 +42,7 @@ void Profile::init()
42 42 File profileFile( config["dir.config"].asString() + "/profile.json" );
43 43
44 44 JSON profileConfig;
45   - bool configExists = profileConfig.load( &profileFile );
  45 + bool configExists = profileConfig.load( profileFile );
46 46
47 47 if( profileConfig.isNull() ) {
48 48 profileConfig.setObject();
@@ -136,7 +136,7 @@ void Profile::init()
136 136 }
137 137
138 138 if( !configExists ) {
139   - profileConfig.save( &profileFile );
  139 + profileConfig.save( profileFile );
140 140 }
141 141
142 142 profileConfig.clear( true );
14 src/client/SMM.cc
@@ -36,13 +36,16 @@ namespace oz
36 36 namespace client
37 37 {
38 38
39   -SMM::SMM( int id ) :
40   - file( liber.models[id].path ), isPreloaded( false ), isLoaded( false )
  39 +SMM::SMM( int id_ ) :
  40 + id( id_ ), isPreloaded( false ), isLoaded( false )
41 41 {}
42 42
43 43 void SMM::preload()
44 44 {
45   - if( !file.map() ) {
  45 + PFile file( liber.models[id].path );
  46 +
  47 + buffer = file.read();
  48 + if( buffer.isEmpty() ) {
46 49 OZ_ERROR( "SMM file '%s' mmap failed", file.path().cstr() );
47 50 }
48 51
@@ -51,13 +54,12 @@ void SMM::preload()
51 54
52 55 void SMM::load()
53 56 {
54   - InputStream is = file.inputStream();
55   -
  57 + InputStream is = buffer.inputStream();
56 58 mesh.load( &is, GL_STATIC_DRAW );
57 59
58 60 hard_assert( !is.isAvailable() );
59 61
60   - file.setPath( "" );
  62 + buffer.deallocate();
61 63
62 64 isLoaded = true;
63 65 }
9 src/client/SMM.hh
@@ -38,13 +38,14 @@ class SMM
38 38 {
39 39 private:
40 40
41   - Mesh mesh;
42   - PFile file;
  41 + int id;
  42 + Buffer buffer;
  43 + Mesh mesh;
43 44
44 45 public:
45 46
46   - bool isPreloaded;
47   - bool isLoaded;
  47 + bool isPreloaded;
  48 + bool isLoaded;
48 49
49 50 explicit SMM( int id );
50 51
18 src/client/Shader.cc
@@ -124,11 +124,13 @@ Shader::Light::Light( const Point& pos_, const Vec4& diffuse_ ) :
124 124 void Shader::compileShader( uint id, const char* path, const char** sources, int* lengths ) const
125 125 {
126 126 PFile file( path );
127   - if( !file.map() ) {
128   - OZ_ERROR( "Shader source '%s' mmap failed", path );
  127 +
  128 + Buffer buffer = file.read();
  129 + if( buffer.isEmpty() ) {
  130 + OZ_ERROR( "Shader source '%s' read failed", path );
129 131 }
130 132
131   - InputStream is = file.inputStream();
  133 + InputStream is = buffer.inputStream();
132 134
133 135 sources[2] = is.begin();
134 136 lengths[2] = is.capacity();
@@ -136,8 +138,6 @@ void Shader::compileShader( uint id, const char* path, const char** sources, int
136 138 glShaderSource( id, 3, sources, lengths );
137 139 glCompileShader( id );
138 140
139   - file.unmap();
140   -
141 141 int result;
142 142 glGetShaderiv( id, GL_COMPILE_STATUS, &result );
143 143
@@ -168,7 +168,7 @@ void Shader::loadProgram( int id )
168 168 PFile configFile( "glsl/" + name + ".json" );
169 169 JSON programConfig;
170 170
171   - if( !programConfig.load( &configFile ) ) {
  171 + if( !programConfig.load( configFile ) ) {
172 172 OZ_ERROR( "Failed to read shader program configuration '%s'", configFile.path().cstr() );
173 173 }
174 174
@@ -376,9 +376,11 @@ void Shader::init()
376 376 sources[0] = defines;
377 377 lengths[0] = defines.length();
378 378
379   - Buffer buffer = PFile( "glsl/header.glsl" ).read();
  379 + PFile file( "glsl/header.glsl" );
  380 + Buffer buffer = file.read();
  381 +
380 382 if( buffer.isEmpty() ) {
381   - OZ_ERROR( "header.glsl reading failed" );
  383 + OZ_ERROR( "'%s' read failed", file.path().cstr() );
382 384 }
383 385
384 386 sources[1] = buffer.begin();
13 src/client/Terra.cc
@@ -160,14 +160,15 @@ void Terra::load()
160 160 id = orbis.terra.id;
161 161
162 162 const String& name = liber.terrae[id].name;
163   - String path = "terra/" + name + ".ozcTerra";
164 163
165   - PFile file( path );
166   - if( !file.map() ) {
167   - OZ_ERROR( "Terra file mmap failed" );
  164 + PFile file( "terra/" + name + ".ozcTerra" );
  165 + Buffer buffer = file.read();
  166 +
  167 + if( buffer.isEmpty() ) {
  168 + OZ_ERROR( "Terra file '%s' read failed", file.path().cstr() );
168 169 }
169 170
170   - InputStream is = file.inputStream();
  171 + InputStream is = buffer.inputStream();
171 172
172 173 waterTexId = context.readTextureLayer( &is );
173 174 detailTexId = context.readTextureLayer( &is );
@@ -228,8 +229,6 @@ void Terra::load()
228 229 liquidFogColour = is.readVec4();
229 230
230 231 hard_assert( !is.isAvailable() );
231   -
232   - file.unmap();
233 232 }
234 233
235 234 void Terra::unload()
8 src/client/ui/CreditsMenu.cc
@@ -157,8 +157,10 @@ CreditsMenu::CreditsMenu() :
157 157 lines.add( "Davorin Učakar" );
158 158
159 159 foreach( creditsFile, creditsFiles.iter() ) {
160   - if( !creditsFile->map() ) {
161   - OZ_ERROR( "Failed to map '%s'", creditsFile->path().cstr() );
  160 + Buffer buffer = creditsFile->read();
  161 +
  162 + if( buffer.isEmpty() ) {
  163 + OZ_ERROR( "Failed to read '%s'", creditsFile->path().cstr() );
162 164 }
163 165
164 166 lines.add( "" );
@@ -172,7 +174,7 @@ CreditsMenu::CreditsMenu() :
172 174 lines.add( "" );
173 175
174 176 String contents = "";
175   - InputStream is = creditsFile->inputStream();
  177 + InputStream is = buffer.inputStream();
176 178
177 179 while( is.isAvailable() ) {
178 180 contents += is.readLine() + "\n";
11 src/client/ui/Font.cc
@@ -69,13 +69,15 @@ void Font::draw( const char* s, uint texId_, int* width, int* height ) const
69 69 void Font::init( const char* name, int height_ )
70 70 {
71 71 height = height_;
72   - file.setPath( String::str( "ui/font/%s.ttf", name ) );
73 72
74   - if( !file.map() ) {
  73 + PFile file( String::str( "ui/font/%s.ttf", name ) );
  74 +
  75 + buffer = file.read();
  76 + if( buffer.isEmpty() ) {
75 77 OZ_ERROR( "Failed to read font file '%s'", file.path().cstr() );
76 78 }
77 79
78   - InputStream istream = file.inputStream();
  80 + InputStream istream = buffer.inputStream();
79 81
80 82 handle = TTF_OpenFontRW( SDL_RWFromConstMem( istream.begin(), istream.capacity() ), true, height );
81 83 if( handle == nullptr ) {
@@ -88,7 +90,8 @@ void Font::destroy()
88 90 if( handle != nullptr ) {
89 91 TTF_CloseFont( static_cast<TTF_Font*>( handle ) );
90 92 }
91   - file.unmap();
  93 +
  94 + buffer.deallocate();
92 95 }
93 96