fixes for magic missile projectiles (curved paths and simultaneous creation)
[gemrb.git] / gemrb / plugins / MOSImporter / MOSImp.cpp
blobcd143436ecdf8cbe306158ae96f02e723ca3b3e6
1 /* GemRB - Infinity Engine Emulator
2 * Copyright (C) 2003 The GemRB Project
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.
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. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * $Id$
22 #include "../../includes/win32def.h"
23 #include "MOSImp.h"
24 #include "../../includes/RGBAColor.h"
25 #include "../Core/Compressor.h"
26 #include "../Core/FileStream.h"
27 #include "../Core/CachedFileStream.h"
28 #include "../Core/Interface.h"
29 #include "../Core/Video.h"
31 static ieDword red_mask = 0xff000000;
32 static ieDword green_mask = 0x00ff0000;
33 static ieDword blue_mask = 0x0000ff00;
35 MOSImp::MOSImp(void)
37 if (DataStream::IsEndianSwitch()) {
38 red_mask = 0x000000ff;
39 green_mask = 0x0000ff00;
40 blue_mask = 0x00ff0000;
44 MOSImp::~MOSImp(void)
48 bool MOSImp::Open(DataStream* stream, bool autoFree)
50 if (!Resource::Open(stream, autoFree))
51 return false;
52 str = stream;
53 char Signature[8];
54 str->Read( Signature, 8 );
55 if (strncmp( Signature, "MOSCV1 ", 8 ) == 0) {
56 char cpath[_MAX_PATH];
57 strcpy( cpath, core->CachePath );
58 strcat( cpath, stream->filename );
59 FILE* exist_in_cache = fopen( cpath, "rb" );
60 if (exist_in_cache) {
61 //File was previously cached, using local copy
62 if (autoFree)
63 delete( str );
64 fclose( exist_in_cache );
65 FileStream* s = new FileStream();
66 s->Open( cpath );
67 str = s;
68 str->Read( Signature, 8 );
69 } else {
70 //No file found in Cache, Decompressing and storing for further use
71 str->Seek( 4, GEM_CURRENT_POS );
73 if (!core->IsAvailable( IE_COMPRESSION_CLASS_ID )) {
74 printf( "No Compression Manager Available.\nCannot Load Compressed Mos File.\n" );
75 return false;
77 FILE* newfile = fopen( cpath, "wb" );
78 Compressor* comp = ( Compressor* )
79 core->GetInterface( IE_COMPRESSION_CLASS_ID );
80 comp->Decompress( newfile, str );
81 core->FreeInterface( comp );
82 fclose( newfile );
83 if (autoFree)
84 delete( str );
85 FileStream* s = new FileStream();
86 s->Open( cpath );
87 str = s;
88 str->Read( Signature, 8 );
91 if (strncmp( Signature, "MOS V1 ", 8 ) != 0) {
92 return false;
94 str->ReadWord( &Width );
95 str->ReadWord( &Height );
96 str->ReadWord( &Cols );
97 str->ReadWord( &Rows );
98 str->ReadDword( &BlockSize );
99 str->ReadDword( &PalOffset );
100 return true;
103 Sprite2D* MOSImp::GetImage()
105 RevColor RevCol[256];
106 unsigned char * pixels = ( unsigned char * ) malloc( Width * Height * 4 );
107 unsigned char * blockpixels = ( unsigned char * )
108 malloc( BlockSize * BlockSize );
109 ieDword blockoffset;
110 for (int y = 0; y < Rows; y++) {
111 int bh = ( y == Rows - 1 ) ?
112 ( ( Height % 64 ) == 0 ? 64 : Height % 64 ) :
114 for (int x = 0; x < Cols; x++) {
115 int bw = ( x == Cols - 1 ) ?
116 ( ( Width % 64 ) == 0 ? 64 : Width % 64 ) :
118 str->Seek( PalOffset + ( y * Cols * 1024 ) +
119 ( x * 1024 ), GEM_STREAM_START );
120 str->Read( &RevCol[0], 1024 );
121 str->Seek( PalOffset + ( Rows * Cols * 1024 ) +
122 ( y * Cols * 4 ) + ( x * 4 ),
123 GEM_STREAM_START );
124 str->ReadDword( &blockoffset );
125 str->Seek( PalOffset + ( Rows * Cols * 1024 ) +
126 ( Rows * Cols * 4 ) + blockoffset,
127 GEM_STREAM_START );
128 str->Read( blockpixels, bw * bh );
129 unsigned char * bp = blockpixels;
130 unsigned char * startpixel = pixels +
131 ( ( Width * 4 * y ) * 64 ) +
132 ( 4 * x * 64 );
133 for (int h = 0; h < bh; h++) {
134 for (int w = 0; w < bw; w++) {
135 *startpixel = RevCol[*bp].a;
136 startpixel++;
137 *startpixel = RevCol[*bp].b;
138 startpixel++;
139 *startpixel = RevCol[*bp].g;
140 startpixel++;
141 *startpixel = RevCol[*bp].r;
142 startpixel++;
143 bp++;
145 startpixel = startpixel + ( Width * 4 ) - ( 4 * bw );
149 free( blockpixels );
150 Sprite2D* ret = core->GetVideoDriver()->CreateSprite( Width, Height, 32,
151 red_mask, green_mask, blue_mask, 0,
152 pixels, true, green_mask );
153 return ret;
156 #include "../../includes/plugindef.h"
158 GEMRB_PLUGIN(0x167B73E, "MOS File Importer")
159 PLUGIN_IE_RESOURCE(&ImageMgr::ID, MOSImp, ".mos", (ieWord)IE_MOS_CLASS_ID)
160 END_PLUGIN()
161 /** No descriptions */
162 void MOSImp::GetPalette(int /*index*/, int /*colors*/, Color* /*pal*/)