~ubuntu-branches/ubuntu/hoary/devil/hoary

« back to all changes in this revision

Viewing changes to src-IL/src/il_files.c

  • Committer: Bazaar Package Importer
  • Author(s): Marcelo E. Magallon
  • Date: 2005-01-03 19:57:42 UTC
  • Revision ID: james.westby@ubuntu.com-20050103195742-4ipkplcwygu3irv0
Tags: upstream-1.6.7
ImportĀ upstreamĀ versionĀ 1.6.7

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//-----------------------------------------------------------------------------
 
2
//
 
3
// ImageLib Sources
 
4
// Copyright (C) 2000-2002 by Denton Woods
 
5
// Last modified: 09/01/2003 <--Y2K Compliant! =]
 
6
//
 
7
// Filename: src-IL/src/il_files.c
 
8
//
 
9
// Description: File handling for DevIL
 
10
//
 
11
//-----------------------------------------------------------------------------
 
12
 
 
13
 
 
14
#define __FILES_C
 
15
#include "il_internal.h"
 
16
#include <stdarg.h>
 
17
 
 
18
 
 
19
// All specific to the next set of functions
 
20
ILboolean       ILAPIENTRY iEofFile(ILvoid);
 
21
ILboolean       ILAPIENTRY iEofLump(ILvoid);
 
22
ILint           ILAPIENTRY iGetcFile(ILvoid);
 
23
ILint           ILAPIENTRY iGetcLump(ILvoid);
 
24
ILuint          ILAPIENTRY iReadFile(ILvoid *Buffer, ILuint Size, ILuint Number);
 
25
ILuint          ILAPIENTRY iReadLump(ILvoid *Buffer, ILuint Size, ILuint Number);
 
26
ILuint          ILAPIENTRY iSeekRFile(ILint Offset, ILuint Mode);
 
27
ILuint          ILAPIENTRY iSeekRLump(ILint Offset, ILuint Mode);
 
28
ILuint          ILAPIENTRY iSeekWFile(ILint Offset, ILuint Mode);
 
29
ILuint          ILAPIENTRY iSeekWLump(ILint Offset, ILuint Mode);
 
30
ILuint          ILAPIENTRY iTellRFile(ILvoid);
 
31
ILuint          ILAPIENTRY iTellRLump(ILvoid);
 
32
ILuint          ILAPIENTRY iTellWFile(ILvoid);
 
33
ILuint          ILAPIENTRY iTellWLump(ILvoid);
 
34
ILint           ILAPIENTRY iPutcFile(ILubyte Char);
 
35
ILint           ILAPIENTRY iPutcLump(ILubyte Char);
 
36
ILint           ILAPIENTRY iWriteFile(const ILvoid *Buffer, ILuint Size, ILuint Number);
 
37
ILint           ILAPIENTRY iWriteLump(const ILvoid *Buffer, ILuint Size, ILuint Number);
 
38
ILHANDLE        FileRead = NULL, FileWrite = NULL;
 
39
ILvoid          *ReadLump = NULL, *WriteLump = NULL;
 
40
ILuint          ReadLumpPos = 0, ReadLumpSize = 0, ReadFileStart = 0, WriteFileStart = 0;
 
41
ILuint          WriteLumpPos = 0, WriteLumpSize = 0;
 
42
 
 
43
fGetcProc       GetcProcCopy;
 
44
fReadProc       ReadProcCopy;
 
45
fSeekRProc      SeekProcCopy;
 
46
fTellRProc      TellProcCopy;
 
47
ILHANDLE        (ILAPIENTRY *iopenCopy)(const ILstring);
 
48
ILvoid          (ILAPIENTRY *icloseCopy)(ILHANDLE);
 
49
 
 
50
ILboolean       UseCache = IL_FALSE;
 
51
ILubyte         *Cache = NULL;
 
52
ILuint          CacheSize, CachePos, CacheStartPos, CacheBytesRead;
 
53
 
 
54
 
 
55
/*// Just preserves the current read functions and replaces
 
56
//      the current read functions with the default read funcs.
 
57
ILvoid ILAPIENTRY iPreserveReadFuncs()
 
58
{
 
59
        // Create backups
 
60
        GetcProcCopy = GetcProc;
 
61
        ReadProcCopy = ReadProc;
 
62
        SeekProcCopy = SeekRProc;
 
63
        TellProcCopy = TellRProc;
 
64
        iopenCopy = iopenr;
 
65
        icloseCopy = icloser;
 
66
 
 
67
        // Set the standard procs to read
 
68
        ilResetRead();
 
69
 
 
70
        return;
 
71
}
 
72
 
 
73
 
 
74
// Restores the read functions - must be used after iPreserveReadFuncs().
 
75
ILvoid ILAPIENTRY iRestoreReadFuncs()
 
76
{
 
77
        GetcProc = GetcProcCopy;
 
78
        ReadProc = ReadProcCopy;
 
79
        SeekRProc = SeekProcCopy;
 
80
        TellRProc = TellProcCopy;
 
81
        iopenr = iopenCopy;
 
82
        icloser = icloseCopy;
 
83
 
 
84
        return;
 
85
}*/
 
86
 
 
87
 
 
88
// Next 7 functions are the default read functions
 
89
 
 
90
ILHANDLE ILAPIENTRY iDefaultOpenR(const ILstring FileName)
 
91
{
 
92
#ifndef _WIN32_WCE
 
93
        return (ILHANDLE)fopen(FileName, "rb");
 
94
#else
 
95
        return (ILHANDLE)_wfopen(FileName, L"rb");
 
96
#endif//_WIN32_WCE
 
97
}
 
98
 
 
99
 
 
100
ILvoid ILAPIENTRY iDefaultCloseR(ILHANDLE Handle)
 
101
{
 
102
        fclose((FILE*)Handle);
 
103
        return;
 
104
}
 
105
 
 
106
 
 
107
ILboolean ILAPIENTRY iDefaultEof(ILHANDLE Handle)
 
108
{
 
109
        ILuint OrigPos, FileSize;
 
110
 
 
111
        // Find out the filesize for checking for the end of file
 
112
        OrigPos = itell();
 
113
        iseek(0, IL_SEEK_END);
 
114
        FileSize = itell();
 
115
        iseek(OrigPos, IL_SEEK_SET);
 
116
 
 
117
        if (itell() >= FileSize)
 
118
                return IL_TRUE;
 
119
        return IL_FALSE;
 
120
}
 
121
 
 
122
 
 
123
ILint ILAPIENTRY iDefaultGetc(ILHANDLE Handle)
 
124
{
 
125
        ILint Val;
 
126
 
 
127
        if (!UseCache) {
 
128
                Val = fgetc((FILE*)Handle);
 
129
                if (Val == IL_EOF)
 
130
                        ilSetError(IL_FILE_READ_ERROR);
 
131
        }
 
132
        else {
 
133
                Val = 0;
 
134
                if (iread(&Val, 1, 1) != 1)
 
135
                        return IL_EOF;
 
136
        }
 
137
        return Val;
 
138
}
 
139
 
 
140
 
 
141
ILint ILAPIENTRY iDefaultRead(ILvoid *Buffer, ILuint Size, ILuint Number, ILHANDLE Handle)
 
142
{
 
143
        return fread(Buffer, Size, Number, (FILE*)Handle);
 
144
}
 
145
 
 
146
 
 
147
ILint ILAPIENTRY iDefaultRSeek(ILHANDLE Handle, ILint Offset, ILint Mode)
 
148
{
 
149
        return fseek((FILE*)Handle, Offset, Mode);
 
150
}
 
151
 
 
152
 
 
153
ILint ILAPIENTRY iDefaultWSeek(ILHANDLE Handle, ILint Offset, ILint Mode)
 
154
{
 
155
        return fseek((FILE*)Handle, Offset, Mode);
 
156
}
 
157
 
 
158
 
 
159
ILint ILAPIENTRY iDefaultRTell(ILHANDLE Handle)
 
160
{
 
161
        return ftell((FILE*)Handle);
 
162
}
 
163
 
 
164
 
 
165
ILint ILAPIENTRY iDefaultWTell(ILHANDLE Handle)
 
166
{
 
167
        return ftell((FILE*)Handle);
 
168
}
 
169
 
 
170
 
 
171
ILHANDLE ILAPIENTRY iDefaultOpenW(const ILstring FileName)
 
172
{
 
173
#ifndef _WIN32_WCE
 
174
        return (ILHANDLE)fopen(FileName, "wb");
 
175
#else
 
176
        return (ILHANDLE)_wfopen(FileName, L"wb");
 
177
#endif//_WIN32_WCE
 
178
}
 
179
 
 
180
 
 
181
ILvoid ILAPIENTRY iDefaultCloseW(ILHANDLE Handle)
 
182
{
 
183
        fclose((FILE*)Handle);
 
184
        return;
 
185
}
 
186
 
 
187
 
 
188
ILint ILAPIENTRY iDefaultPutc(ILubyte Char, ILHANDLE Handle)
 
189
{
 
190
        return fputc(Char, (FILE*)Handle);
 
191
}
 
192
 
 
193
 
 
194
ILint ILAPIENTRY iDefaultWrite(const ILvoid *Buffer, ILuint Size, ILuint Number, ILHANDLE Handle)
 
195
{
 
196
        return fwrite(Buffer, Size, Number, (FILE*)Handle);
 
197
}
 
198
 
 
199
 
 
200
ILvoid ILAPIENTRY ilResetRead()
 
201
{
 
202
        ilSetRead(iDefaultOpenR, iDefaultCloseR, iDefaultEof, iDefaultGetc, 
 
203
                                iDefaultRead, iDefaultRSeek, iDefaultRTell);
 
204
        return;
 
205
}
 
206
 
 
207
 
 
208
ILvoid ILAPIENTRY ilResetWrite()
 
209
{
 
210
        ilSetWrite(iDefaultOpenW, iDefaultCloseW, iDefaultPutc,
 
211
                                iDefaultWSeek, iDefaultWTell, iDefaultWrite);
 
212
        return;
 
213
}
 
214
 
 
215
 
 
216
//! Allows you to override the default file-reading functions.
 
217
ILvoid ILAPIENTRY ilSetRead(fOpenRProc Open, fCloseRProc Close, fEofProc Eof, fGetcProc Getc, fReadProc Read, fSeekRProc Seek, fTellRProc Tell)
 
218
{
 
219
        iopenr    = Open;
 
220
        icloser   = Close;
 
221
        EofProc   = Eof;
 
222
        GetcProc  = Getc;
 
223
        ReadProc  = Read;
 
224
        SeekRProc = Seek;
 
225
        TellRProc = Tell;
 
226
 
 
227
        return;
 
228
}
 
229
 
 
230
 
 
231
//! Allows you to override the default file-writing functions.
 
232
ILvoid ILAPIENTRY ilSetWrite(fOpenRProc Open, fCloseRProc Close, fPutcProc Putc, fSeekWProc Seek, fTellWProc Tell, fWriteProc Write)
 
233
{
 
234
        iopenw    = Open;
 
235
        iclosew   = Close;
 
236
        PutcProc  = Putc;
 
237
        WriteProc = Write;
 
238
        SeekWProc = Seek;
 
239
        TellWProc = Tell;
 
240
 
 
241
        return;
 
242
}
 
243
 
 
244
 
 
245
// Tells DevIL that we're reading from a file, not a lump
 
246
ILvoid iSetInputFile(ILHANDLE File)
 
247
{
 
248
        ieof  = iEofFile;
 
249
        igetc = iGetcFile;
 
250
        iread = iReadFile;
 
251
        iseek = iSeekRFile;
 
252
        itell = iTellRFile;
 
253
        FileRead = File;
 
254
        ReadFileStart = itell();
 
255
}
 
256
 
 
257
 
 
258
// Tells DevIL that we're reading from a lump, not a file
 
259
ILvoid iSetInputLump(ILvoid *Lump, ILuint Size)
 
260
{
 
261
        ieof  = iEofLump;
 
262
        igetc = iGetcLump;
 
263
        iread = iReadLump;
 
264
        iseek = iSeekRLump;
 
265
        itell = iTellRLump;
 
266
        ReadLump = Lump;
 
267
        ReadLumpPos = 0;
 
268
        ReadLumpSize = Size;
 
269
}
 
270
 
 
271
 
 
272
// Tells DevIL that we're writing to a file, not a lump
 
273
ILvoid iSetOutputFile(ILHANDLE File)
 
274
{
 
275
        // Helps with ilGetLumpPos().
 
276
        WriteLump = NULL;
 
277
        WriteLumpPos = 0;
 
278
        WriteLumpSize = 0;
 
279
 
 
280
        iputc  = iPutcFile;
 
281
        iseekw = iSeekWFile;
 
282
        itellw = iTellWFile;
 
283
        iwrite = iWriteFile;
 
284
        FileWrite = File;
 
285
}
 
286
 
 
287
 
 
288
// Tells DevIL that we're writing to a lump, not a file
 
289
ILvoid iSetOutputLump(ILvoid *Lump, ILuint Size)
 
290
{
 
291
        iputc  = iPutcLump;
 
292
        iseekw = iSeekWLump;
 
293
        itellw = iTellWLump;
 
294
        iwrite = iWriteLump;
 
295
        WriteLump = Lump;
 
296
        WriteLumpPos = 0;
 
297
        WriteLumpSize = Size;
 
298
}
 
299
 
 
300
 
 
301
ILuint ILAPIENTRY ilGetLumpPos()
 
302
{
 
303
        if (WriteLump)
 
304
                return WriteLumpPos;
 
305
        return 0;
 
306
}
 
307
 
 
308
 
 
309
ILuint ILAPIENTRY ilprintf(const char *Line, ...)
 
310
{
 
311
        char    Buffer[2048];  // Hope this is large enough
 
312
        va_list VaLine;
 
313
        ILuint  i;
 
314
 
 
315
        va_start(VaLine, Line);
 
316
        vsprintf(Buffer, Line, VaLine);
 
317
        va_end(VaLine);
 
318
 
 
319
        i = strlen(Buffer);
 
320
        iwrite(Buffer, 1, i);
 
321
 
 
322
        return i;
 
323
}
 
324
 
 
325
 
 
326
// To pad zeros where needed...
 
327
ILvoid ipad(ILuint NumZeros)
 
328
{
 
329
        ILuint i = 0;
 
330
        for (; i < NumZeros; i++)
 
331
                iputc(0);
 
332
        return;
 
333
}
 
334
 
 
335
 
 
336
//
 
337
// The rest of the functions following in this file are quite
 
338
//      self-explanatory, except where commented.
 
339
//
 
340
 
 
341
// Next 12 functions are the default write functions
 
342
 
 
343
ILboolean ILAPIENTRY iEofFile(ILvoid)
 
344
{
 
345
        return EofProc((FILE*)FileRead);
 
346
}
 
347
 
 
348
 
 
349
ILboolean ILAPIENTRY iEofLump(ILvoid)
 
350
{
 
351
        if (ReadLumpSize)
 
352
                return (ReadLumpPos >= ReadLumpSize);
 
353
        return IL_FALSE;
 
354
}
 
355
 
 
356
 
 
357
ILint ILAPIENTRY iGetcFile(ILvoid)
 
358
{
 
359
        if (!UseCache) {
 
360
                return GetcProc(FileRead);
 
361
        }
 
362
        if (CachePos >= CacheSize) {
 
363
                iPreCache(CacheSize);
 
364
        }
 
365
 
 
366
        CacheBytesRead++;
 
367
        return Cache[CachePos++];
 
368
}
 
369
 
 
370
 
 
371
ILint ILAPIENTRY iGetcLump(ILvoid)
 
372
{
 
373
        // If ReadLumpSize is 0, don't even check to see if we've gone past the bounds.
 
374
        if (ReadLumpSize > 0) {
 
375
                if (ReadLumpPos + 1 > ReadLumpSize) {
 
376
                        ReadLumpPos--;
 
377
                        ilSetError(IL_FILE_READ_ERROR);
 
378
                        return IL_EOF;
 
379
                }
 
380
        }
 
381
 
 
382
        return *((ILubyte*)ReadLump + ReadLumpPos++);
 
383
}
 
384
 
 
385
 
 
386
ILuint ILAPIENTRY iReadFile(ILvoid *Buffer, ILuint Size, ILuint Number)
 
387
{
 
388
        ILuint  TotalBytes = 0, BytesCopied;
 
389
        ILuint  BuffSize = Size * Number;
 
390
        ILuint NumRead;
 
391
 
 
392
        if (!UseCache) {
 
393
                NumRead = ReadProc(Buffer, Size, Number, FileRead);
 
394
                if (NumRead != Number)
 
395
                        ilSetError(IL_FILE_READ_ERROR);
 
396
                return NumRead;
 
397
        }
 
398
 
 
399
        /*if (Cache == NULL || CacheSize == 0) {  // Shouldn't happen, but we check anyway.
 
400
                return ReadProc(Buffer, Size, Number, FileRead);
 
401
        }*/
 
402
 
 
403
        if (BuffSize < CacheSize - CachePos) {
 
404
                memcpy(Buffer, Cache + CachePos, BuffSize);
 
405
                CachePos += BuffSize;
 
406
                CacheBytesRead += BuffSize;
 
407
                if (Size != 0)
 
408
                        BuffSize /= Size;
 
409
                return BuffSize;
 
410
        }
 
411
        else {
 
412
                while (TotalBytes < BuffSize) {
 
413
                        // If loop through more than once, after first, CachePos is 0.
 
414
                        if (TotalBytes + CacheSize - CachePos > BuffSize)
 
415
                                BytesCopied = BuffSize - TotalBytes;
 
416
                        else
 
417
                                BytesCopied = CacheSize - CachePos;
 
418
 
 
419
                        memcpy((ILubyte*)Buffer + TotalBytes, Cache + CachePos, BytesCopied);
 
420
                        TotalBytes += BytesCopied;
 
421
                        CachePos += BytesCopied;
 
422
                        if (TotalBytes < BuffSize) {
 
423
                                iPreCache(CacheSize);
 
424
                        }
 
425
                }
 
426
        }
 
427
 
 
428
        CacheBytesRead += TotalBytes;
 
429
        if (Size != 0)
 
430
                TotalBytes /= Size;
 
431
        if (TotalBytes != Number)
 
432
                ilSetError(IL_FILE_READ_ERROR);
 
433
        return TotalBytes;
 
434
}
 
435
 
 
436
 
 
437
ILuint ILAPIENTRY iReadLump(ILvoid *Buffer, ILuint Size, ILuint Number)
 
438
{
 
439
        ILuint i, ByteSize = Size * Number;
 
440
 
 
441
        for (i = 0; i < ByteSize; i++) {
 
442
                *((ILubyte*)Buffer + i) = *((ILubyte*)ReadLump + ReadLumpPos + i);
 
443
                if (ReadLumpSize > 0) {  // ReadLumpSize is too large to care about apparently
 
444
                        if (ReadLumpPos + i > ReadLumpSize) {
 
445
                                ReadLumpPos += i;
 
446
                                if (i != Number)
 
447
                                        ilSetError(IL_FILE_READ_ERROR);
 
448
                                return i;
 
449
                        }
 
450
                }
 
451
        }
 
452
 
 
453
        ReadLumpPos += i;
 
454
        if (Size != 0)
 
455
                i /= Size;
 
456
        if (i != Number)
 
457
                ilSetError(IL_FILE_READ_ERROR);
 
458
        return i;
 
459
}
 
460
 
 
461
 
 
462
ILboolean iPreCache(ILuint Size)
 
463
{
 
464
        // Reading from a memory lump, so don't cache.
 
465
        if (iread == iReadLump) {
 
466
                //iUnCache();  // DW: Removed 06-10-2002.
 
467
                return IL_TRUE;
 
468
        }
 
469
 
 
470
        if (Cache) {
 
471
                ifree(Cache);
 
472
        }
 
473
 
 
474
        if (Size == 0) {
 
475
                Size = 1;
 
476
        }
 
477
 
 
478
        Cache = (ILubyte*)ialloc(Size);
 
479
        if (Cache == NULL) {
 
480
                return IL_FALSE;
 
481
        }
 
482
 
 
483
        UseCache = IL_FALSE;
 
484
        CacheStartPos = itell();
 
485
        CacheSize = iread(Cache, 1, Size);
 
486
        if (CacheSize != Size)
 
487
                ilGetError();  // Get rid of the IL_FILE_READ_ERROR.
 
488
 
 
489
        //2003-09-09: uncommented the following line to prevent
 
490
        //an infinite loop in ilPreCache()
 
491
        CacheSize = Size;
 
492
        CachePos = 0;
 
493
        UseCache = IL_TRUE;
 
494
        CacheBytesRead = 0;
 
495
 
 
496
        return IL_TRUE;
 
497
}
 
498
 
 
499
 
 
500
ILvoid iUnCache()
 
501
{
 
502
        //changed 2003-09-01:
 
503
        //make iUnCache smart enough to return if
 
504
        //no cache is used
 
505
        if(!UseCache)
 
506
                return;
 
507
 
 
508
        if (iread == iReadLump)
 
509
                return;
 
510
 
 
511
        CacheSize = 0;
 
512
        CachePos = 0;
 
513
        if (Cache) {
 
514
                ifree(Cache);
 
515
                Cache = NULL;
 
516
        }
 
517
        UseCache = IL_FALSE;
 
518
 
 
519
        iseek(CacheStartPos + CacheBytesRead, IL_SEEK_SET);
 
520
 
 
521
        return;
 
522
}
 
523
 
 
524
 
 
525
ILuint ILAPIENTRY iSeekRFile(ILint Offset, ILuint Mode)
 
526
{
 
527
        if (Mode == IL_SEEK_SET)
 
528
                Offset += ReadFileStart;  // This allows us to use IL_SEEK_SET in the middle of a file.
 
529
        return SeekRProc(FileRead, Offset, Mode);
 
530
}
 
531
 
 
532
 
 
533
// Returns 1 on error, 0 on success
 
534
ILuint ILAPIENTRY iSeekRLump(ILint Offset, ILuint Mode)
 
535
{
 
536
        switch (Mode)
 
537
        {
 
538
                case IL_SEEK_SET:
 
539
                        if (Offset > (ILint)ReadLumpSize)
 
540
                                return 1;
 
541
                        ReadLumpPos = Offset;
 
542
                        break;
 
543
 
 
544
                case IL_SEEK_CUR:
 
545
                        if (ReadLumpPos + Offset > ReadLumpSize)
 
546
                                return 1;
 
547
                        ReadLumpPos += Offset;
 
548
                        break;
 
549
 
 
550
                case IL_SEEK_END:
 
551
                        if (Offset > 0)
 
552
                                return 1;
 
553
                        // Should we use >= instead?
 
554
                        if (abs(Offset) > (ILint)ReadLumpSize)  // If ReadLumpSize == 0, too bad
 
555
                                return 1;
 
556
                        ReadLumpPos = ReadLumpSize + Offset;
 
557
                        break;
 
558
 
 
559
                default:
 
560
                        return 1;
 
561
        }
 
562
 
 
563
        return 0;
 
564
}
 
565
 
 
566
 
 
567
ILuint ILAPIENTRY iTellRFile(ILvoid)
 
568
{
 
569
        return TellRProc(FileRead);
 
570
}
 
571
 
 
572
 
 
573
ILuint ILAPIENTRY iTellRLump(ILvoid)
 
574
{
 
575
        return ReadLumpPos;
 
576
}
 
577
 
 
578
 
 
579
ILHANDLE ILAPIENTRY iGetFile(ILvoid)
 
580
{
 
581
        return FileRead;
 
582
}
 
583
 
 
584
 
 
585
ILubyte* ILAPIENTRY iGetLump(ILvoid)
 
586
{
 
587
        return ReadLump;
 
588
}
 
589
 
 
590
 
 
591
 
 
592
// Next 4 functions are the default write functions
 
593
 
 
594
ILint ILAPIENTRY iPutcFile(ILubyte Char)
 
595
{
 
596
        return PutcProc(Char, FileWrite);
 
597
}
 
598
 
 
599
 
 
600
ILint ILAPIENTRY iPutcLump(ILubyte Char)
 
601
{
 
602
        if (WriteLumpPos >= WriteLumpSize)
 
603
                return IL_EOF;  // IL_EOF
 
604
        *((ILubyte*)(WriteLump) + WriteLumpPos++) = Char;
 
605
        return Char;
 
606
}
 
607
 
 
608
 
 
609
ILint ILAPIENTRY iWriteFile(const ILvoid *Buffer, ILuint Size, ILuint Number)
 
610
{
 
611
        ILuint NumWritten;
 
612
        NumWritten = WriteProc(Buffer, Size, Number, FileWrite);
 
613
        if (NumWritten != Number) {
 
614
                ilSetError(IL_FILE_WRITE_ERROR);
 
615
                return 0;
 
616
        }
 
617
        return NumWritten;
 
618
}
 
619
 
 
620
 
 
621
ILint ILAPIENTRY iWriteLump(const ILvoid *Buffer, ILuint Size, ILuint Number)
 
622
{
 
623
        ILuint SizeBytes = Size * Number;
 
624
        ILuint i = 0;
 
625
 
 
626
        for (; i < SizeBytes; i++) {
 
627
                if (WriteLumpSize > 0) {
 
628
                        if (WriteLumpPos + i >= WriteLumpSize) {  // Should we use > instead?
 
629
                                ilSetError(IL_FILE_WRITE_ERROR);
 
630
                                WriteLumpPos += i;
 
631
                                return i;
 
632
                        }
 
633
                }
 
634
 
 
635
                *((ILubyte*)WriteLump + WriteLumpPos + i) = *((ILubyte*)Buffer + i);
 
636
        }
 
637
 
 
638
        WriteLumpPos += SizeBytes;
 
639
        
 
640
        return SizeBytes;
 
641
}
 
642
 
 
643
 
 
644
ILuint ILAPIENTRY iSeekWFile(ILint Offset, ILuint Mode)
 
645
{
 
646
        if (Mode == IL_SEEK_SET)
 
647
                Offset += WriteFileStart;  // This allows us to use IL_SEEK_SET in the middle of a file.
 
648
        return SeekWProc(FileWrite, Offset, Mode);
 
649
}
 
650
 
 
651
 
 
652
// Returns 1 on error, 0 on success
 
653
ILuint ILAPIENTRY iSeekWLump(ILint Offset, ILuint Mode)
 
654
{
 
655
        switch (Mode)
 
656
        {
 
657
                case IL_SEEK_SET:
 
658
                        if (Offset > (ILint)WriteLumpSize)
 
659
                                return 1;
 
660
                        WriteLumpPos = Offset;
 
661
                        break;
 
662
 
 
663
                case IL_SEEK_CUR:
 
664
                        if (WriteLumpPos + Offset > WriteLumpSize)
 
665
                                return 1;
 
666
                        WriteLumpPos += Offset;
 
667
                        break;
 
668
 
 
669
                case IL_SEEK_END:
 
670
                        if (Offset > 0)
 
671
                                return 1;
 
672
                        // Should we use >= instead?
 
673
                        if (abs(Offset) > (ILint)WriteLumpSize)  // If WriteLumpSize == 0, too bad
 
674
                                return 1;
 
675
                        WriteLumpPos = WriteLumpSize + Offset;
 
676
                        break;
 
677
 
 
678
                default:
 
679
                        return 1;
 
680
        }
 
681
 
 
682
        return 0;
 
683
}
 
684
 
 
685
 
 
686
ILuint ILAPIENTRY iTellWFile(ILvoid)
 
687
{
 
688
        return TellWProc(FileWrite);
 
689
}
 
690
 
 
691
 
 
692
ILuint ILAPIENTRY iTellWLump(ILvoid)
 
693
{
 
694
        return WriteLumpPos;
 
695
}