2008-03-19 11:19:03 +00:00
|
|
|
/*
|
|
|
|
** files.cpp
|
|
|
|
** Implements classes for reading from files or memory blocks
|
|
|
|
**
|
|
|
|
**---------------------------------------------------------------------------
|
|
|
|
** Copyright 1998-2008 Randy Heit
|
|
|
|
** Copyright 2005-2008 Christoph Oelckers
|
|
|
|
** All rights reserved.
|
|
|
|
**
|
|
|
|
** Redistribution and use in source and binary forms, with or without
|
|
|
|
** modification, are permitted provided that the following conditions
|
|
|
|
** are met:
|
|
|
|
**
|
|
|
|
** 1. Redistributions of source code must retain the above copyright
|
|
|
|
** notice, this list of conditions and the following disclaimer.
|
|
|
|
** 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
** notice, this list of conditions and the following disclaimer in the
|
|
|
|
** documentation and/or other materials provided with the distribution.
|
|
|
|
** 3. The name of the author may not be used to endorse or promote products
|
|
|
|
** derived from this software without specific prior written permission.
|
|
|
|
**
|
|
|
|
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
|
|
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
|
|
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
|
|
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
|
|
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
|
|
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
|
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
|
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
|
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
|
|
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
**---------------------------------------------------------------------------
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
|
2008-01-27 11:25:03 +00:00
|
|
|
#include "files.h"
|
|
|
|
#include "i_system.h"
|
|
|
|
#include "templates.h"
|
2012-06-18 17:32:23 +00:00
|
|
|
#include "m_misc.h"
|
2008-01-27 11:25:03 +00:00
|
|
|
|
2008-03-19 11:19:03 +00:00
|
|
|
//==========================================================================
|
|
|
|
//
|
|
|
|
// FileReader
|
|
|
|
//
|
|
|
|
// reads data from an uncompressed file or part of it
|
|
|
|
//
|
|
|
|
//==========================================================================
|
|
|
|
|
2008-01-27 11:25:03 +00:00
|
|
|
FileReader::FileReader ()
|
2008-04-13 14:34:31 +00:00
|
|
|
: File(NULL), Length(0), StartPos(0), CloseOnDestruct(false)
|
2008-01-27 11:25:03 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
FileReader::FileReader (const FileReader &other, long length)
|
|
|
|
: File(other.File), Length(length), CloseOnDestruct(false)
|
|
|
|
{
|
|
|
|
FilePos = StartPos = ftell (other.File);
|
|
|
|
}
|
|
|
|
|
|
|
|
FileReader::FileReader (const char *filename)
|
|
|
|
: File(NULL), Length(0), StartPos(0), FilePos(0), CloseOnDestruct(false)
|
|
|
|
{
|
2008-04-13 14:34:31 +00:00
|
|
|
if (!Open(filename))
|
2008-01-27 11:25:03 +00:00
|
|
|
{
|
|
|
|
I_Error ("Could not open %s", filename);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
FileReader::FileReader (FILE *file)
|
|
|
|
: File(file), Length(0), StartPos(0), FilePos(0), CloseOnDestruct(false)
|
|
|
|
{
|
|
|
|
Length = CalcFileLen();
|
|
|
|
}
|
|
|
|
|
|
|
|
FileReader::FileReader (FILE *file, long length)
|
|
|
|
: File(file), Length(length), CloseOnDestruct(true)
|
|
|
|
{
|
|
|
|
FilePos = StartPos = ftell (file);
|
|
|
|
}
|
|
|
|
|
|
|
|
FileReader::~FileReader ()
|
|
|
|
{
|
|
|
|
if (CloseOnDestruct && File != NULL)
|
|
|
|
{
|
|
|
|
fclose (File);
|
|
|
|
File = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-04-13 14:34:31 +00:00
|
|
|
bool FileReader::Open (const char *filename)
|
|
|
|
{
|
|
|
|
File = fopen (filename, "rb");
|
|
|
|
if (File == NULL) return false;
|
|
|
|
FilePos = 0;
|
|
|
|
StartPos = 0;
|
|
|
|
CloseOnDestruct = true;
|
|
|
|
Length = CalcFileLen();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-01-27 11:25:03 +00:00
|
|
|
void FileReader::ResetFilePtr ()
|
|
|
|
{
|
|
|
|
FilePos = ftell (File);
|
|
|
|
}
|
|
|
|
|
|
|
|
long FileReader::Tell () const
|
|
|
|
{
|
|
|
|
return FilePos - StartPos;
|
|
|
|
}
|
|
|
|
|
|
|
|
long FileReader::Seek (long offset, int origin)
|
|
|
|
{
|
|
|
|
if (origin == SEEK_SET)
|
|
|
|
{
|
|
|
|
offset += StartPos;
|
|
|
|
}
|
|
|
|
else if (origin == SEEK_CUR)
|
|
|
|
{
|
|
|
|
offset += FilePos;
|
|
|
|
}
|
|
|
|
else if (origin == SEEK_END)
|
|
|
|
{
|
|
|
|
offset += StartPos + Length;
|
|
|
|
}
|
|
|
|
if (0 == fseek (File, offset, SEEK_SET))
|
|
|
|
{
|
|
|
|
FilePos = offset;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
long FileReader::Read (void *buffer, long len)
|
|
|
|
{
|
2010-09-04 08:57:10 +00:00
|
|
|
assert(len >= 0);
|
|
|
|
if (len <= 0) return 0;
|
2008-01-27 11:25:03 +00:00
|
|
|
if (FilePos + len > StartPos + Length)
|
|
|
|
{
|
|
|
|
len = Length - FilePos + StartPos;
|
|
|
|
}
|
|
|
|
len = (long)fread (buffer, 1, len, File);
|
|
|
|
FilePos += len;
|
|
|
|
return len;
|
|
|
|
}
|
|
|
|
|
Update to ZDoom r905:
- Added Martin Howe's morph system update.
- Added support for defining composite textures in HIRESTEX. It is not fully tested
and right now can't do much more than the old TEXTUREx method.
- Added a few NULL pointer checks to the texture code.
- Made duplicate class names in DECORATE non-fatal. There is really no stability
concern here and the worst that can happen is that the wrong actor is spawned.
This was a constant hassle when testing with WADs that contain duplicate resources.
- Removed some GCC warnings.
- Fixed: MinGW doesn't have _get_pgmptr(), so it couldn't compile i_main.cpp.
- Fixed: MOD_WAVETABLE and MOD_SWSYNTH are not defined by w32api, so MinGW
failed compiling the new MIDI code.
- Fixed: LocalSndInfo and LocalSndSeq in S_Start() need to be const char
pointers, since "" is a constant.
- Fixed: parsecontext.h was missing a newline at the end of the file.
- Fixed: Timidity::Channel::mono, rpn, and nrpn were not initialized. In
particular, this meant that every channel was almost certainly in mono mode,
which can sound pretty bad if the song isn't meant to be played that way.
- Added bank numbers to the MIDI precaching for Timidity, since I guess I do
need to care about banks, if even the Duke MIDIs use various banks.
- Fixed: snd_midiprecache only exists in Win32 builds, so gameconfigfile.cpp
shouldn't unconditionally link against it.
- Fixed: pre_resample() was still disabled, and it left two samples at the end
of the new wave data uninitialized.
- Moved the xmap table from timidity/tables.cpp to playmidi.cpp. Now I can get
rid of timidity/tables.cpp, which conflicts in name with the main Doom
tables.cpp. (And interestingly, VC++ automatically renamed the object file,
so I wasn't aware of the problem with GCC.)
- Added a Gets function to the FileReader class which I planned to use
to enable Timidity to read its config and sound patches from Zips.
I put this on hold though after finding out that the sound quality
isn't even near that of Timidity++.
- GCC-Fixes (FString::GetChars() for Printf calls)
- Added a dummy Weapon.NOLMS flag so that Skulltag weapons using this flag
can be loaded
- Changed the MIDIStreamer to send the all notes off controller to each
channel when restarting the song, rather than emitting a single note off
event which only has 1 in 127 chance of being for a note that's playing
on that channel. Then I decided it would probably be a good idea to reset
all the controllers as well.
- Increasing the size of the internal Timidity stream buffer from 1/14 sec
(copied from the OPL player) improved its sound dramatically, so apparently
Timidity has issues with short stream buffers. It's now at 1/2 sec in
length. However, there seems to be something weird going on with
corazonazul_ff6boss.mid near the beginning where it stops and immediately
restarts a guitar on the exact same note.
- Added a new sound debugging cvar: snd_drawoutput, which can show various
oscilloscopes and spectrums.
- Eliminated some more global variables (onmobj, DoRipping, LastRipped,
MissileActor, bulletpitch and linetarget.)
- Internal TiMidity now plays music. Unfortunately, it doesn't sound right. :(
- Changed the progdir global variable into an FString.
git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@90 b0f79afe-0144-0410-b225-9a4edf0717df
2008-04-12 18:59:23 +00:00
|
|
|
char *FileReader::Gets(char *strbuf, int len)
|
|
|
|
{
|
2012-04-01 07:17:11 +00:00
|
|
|
if (len <= 0 || FilePos >= StartPos + Length) return NULL;
|
Update to ZDoom r905:
- Added Martin Howe's morph system update.
- Added support for defining composite textures in HIRESTEX. It is not fully tested
and right now can't do much more than the old TEXTUREx method.
- Added a few NULL pointer checks to the texture code.
- Made duplicate class names in DECORATE non-fatal. There is really no stability
concern here and the worst that can happen is that the wrong actor is spawned.
This was a constant hassle when testing with WADs that contain duplicate resources.
- Removed some GCC warnings.
- Fixed: MinGW doesn't have _get_pgmptr(), so it couldn't compile i_main.cpp.
- Fixed: MOD_WAVETABLE and MOD_SWSYNTH are not defined by w32api, so MinGW
failed compiling the new MIDI code.
- Fixed: LocalSndInfo and LocalSndSeq in S_Start() need to be const char
pointers, since "" is a constant.
- Fixed: parsecontext.h was missing a newline at the end of the file.
- Fixed: Timidity::Channel::mono, rpn, and nrpn were not initialized. In
particular, this meant that every channel was almost certainly in mono mode,
which can sound pretty bad if the song isn't meant to be played that way.
- Added bank numbers to the MIDI precaching for Timidity, since I guess I do
need to care about banks, if even the Duke MIDIs use various banks.
- Fixed: snd_midiprecache only exists in Win32 builds, so gameconfigfile.cpp
shouldn't unconditionally link against it.
- Fixed: pre_resample() was still disabled, and it left two samples at the end
of the new wave data uninitialized.
- Moved the xmap table from timidity/tables.cpp to playmidi.cpp. Now I can get
rid of timidity/tables.cpp, which conflicts in name with the main Doom
tables.cpp. (And interestingly, VC++ automatically renamed the object file,
so I wasn't aware of the problem with GCC.)
- Added a Gets function to the FileReader class which I planned to use
to enable Timidity to read its config and sound patches from Zips.
I put this on hold though after finding out that the sound quality
isn't even near that of Timidity++.
- GCC-Fixes (FString::GetChars() for Printf calls)
- Added a dummy Weapon.NOLMS flag so that Skulltag weapons using this flag
can be loaded
- Changed the MIDIStreamer to send the all notes off controller to each
channel when restarting the song, rather than emitting a single note off
event which only has 1 in 127 chance of being for a note that's playing
on that channel. Then I decided it would probably be a good idea to reset
all the controllers as well.
- Increasing the size of the internal Timidity stream buffer from 1/14 sec
(copied from the OPL player) improved its sound dramatically, so apparently
Timidity has issues with short stream buffers. It's now at 1/2 sec in
length. However, there seems to be something weird going on with
corazonazul_ff6boss.mid near the beginning where it stops and immediately
restarts a guitar on the exact same note.
- Added a new sound debugging cvar: snd_drawoutput, which can show various
oscilloscopes and spectrums.
- Eliminated some more global variables (onmobj, DoRipping, LastRipped,
MissileActor, bulletpitch and linetarget.)
- Internal TiMidity now plays music. Unfortunately, it doesn't sound right. :(
- Changed the progdir global variable into an FString.
git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@90 b0f79afe-0144-0410-b225-9a4edf0717df
2008-04-12 18:59:23 +00:00
|
|
|
char *p = fgets(strbuf, len, File);
|
2008-04-13 14:34:31 +00:00
|
|
|
if (p != NULL)
|
|
|
|
{
|
2012-03-31 19:47:46 +00:00
|
|
|
int old = FilePos;
|
2012-04-01 07:17:11 +00:00
|
|
|
FilePos = ftell(File);
|
|
|
|
if (FilePos - StartPos > Length)
|
2012-03-31 19:47:46 +00:00
|
|
|
{
|
2012-04-01 07:17:11 +00:00
|
|
|
strbuf[Length - old + StartPos] = 0;
|
2012-03-31 19:47:46 +00:00
|
|
|
}
|
2008-04-13 14:34:31 +00:00
|
|
|
}
|
Update to ZDoom r905:
- Added Martin Howe's morph system update.
- Added support for defining composite textures in HIRESTEX. It is not fully tested
and right now can't do much more than the old TEXTUREx method.
- Added a few NULL pointer checks to the texture code.
- Made duplicate class names in DECORATE non-fatal. There is really no stability
concern here and the worst that can happen is that the wrong actor is spawned.
This was a constant hassle when testing with WADs that contain duplicate resources.
- Removed some GCC warnings.
- Fixed: MinGW doesn't have _get_pgmptr(), so it couldn't compile i_main.cpp.
- Fixed: MOD_WAVETABLE and MOD_SWSYNTH are not defined by w32api, so MinGW
failed compiling the new MIDI code.
- Fixed: LocalSndInfo and LocalSndSeq in S_Start() need to be const char
pointers, since "" is a constant.
- Fixed: parsecontext.h was missing a newline at the end of the file.
- Fixed: Timidity::Channel::mono, rpn, and nrpn were not initialized. In
particular, this meant that every channel was almost certainly in mono mode,
which can sound pretty bad if the song isn't meant to be played that way.
- Added bank numbers to the MIDI precaching for Timidity, since I guess I do
need to care about banks, if even the Duke MIDIs use various banks.
- Fixed: snd_midiprecache only exists in Win32 builds, so gameconfigfile.cpp
shouldn't unconditionally link against it.
- Fixed: pre_resample() was still disabled, and it left two samples at the end
of the new wave data uninitialized.
- Moved the xmap table from timidity/tables.cpp to playmidi.cpp. Now I can get
rid of timidity/tables.cpp, which conflicts in name with the main Doom
tables.cpp. (And interestingly, VC++ automatically renamed the object file,
so I wasn't aware of the problem with GCC.)
- Added a Gets function to the FileReader class which I planned to use
to enable Timidity to read its config and sound patches from Zips.
I put this on hold though after finding out that the sound quality
isn't even near that of Timidity++.
- GCC-Fixes (FString::GetChars() for Printf calls)
- Added a dummy Weapon.NOLMS flag so that Skulltag weapons using this flag
can be loaded
- Changed the MIDIStreamer to send the all notes off controller to each
channel when restarting the song, rather than emitting a single note off
event which only has 1 in 127 chance of being for a note that's playing
on that channel. Then I decided it would probably be a good idea to reset
all the controllers as well.
- Increasing the size of the internal Timidity stream buffer from 1/14 sec
(copied from the OPL player) improved its sound dramatically, so apparently
Timidity has issues with short stream buffers. It's now at 1/2 sec in
length. However, there seems to be something weird going on with
corazonazul_ff6boss.mid near the beginning where it stops and immediately
restarts a guitar on the exact same note.
- Added a new sound debugging cvar: snd_drawoutput, which can show various
oscilloscopes and spectrums.
- Eliminated some more global variables (onmobj, DoRipping, LastRipped,
MissileActor, bulletpitch and linetarget.)
- Internal TiMidity now plays music. Unfortunately, it doesn't sound right. :(
- Changed the progdir global variable into an FString.
git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@90 b0f79afe-0144-0410-b225-9a4edf0717df
2008-04-12 18:59:23 +00:00
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
|
|
|
char *FileReader::GetsFromBuffer(const char * bufptr, char *strbuf, int len)
|
|
|
|
{
|
|
|
|
if (len>Length-FilePos) len=Length-FilePos;
|
|
|
|
if (len <= 0) return NULL;
|
|
|
|
|
|
|
|
char *p = strbuf;
|
2008-04-13 14:34:31 +00:00
|
|
|
while (len > 1)
|
Update to ZDoom r905:
- Added Martin Howe's morph system update.
- Added support for defining composite textures in HIRESTEX. It is not fully tested
and right now can't do much more than the old TEXTUREx method.
- Added a few NULL pointer checks to the texture code.
- Made duplicate class names in DECORATE non-fatal. There is really no stability
concern here and the worst that can happen is that the wrong actor is spawned.
This was a constant hassle when testing with WADs that contain duplicate resources.
- Removed some GCC warnings.
- Fixed: MinGW doesn't have _get_pgmptr(), so it couldn't compile i_main.cpp.
- Fixed: MOD_WAVETABLE and MOD_SWSYNTH are not defined by w32api, so MinGW
failed compiling the new MIDI code.
- Fixed: LocalSndInfo and LocalSndSeq in S_Start() need to be const char
pointers, since "" is a constant.
- Fixed: parsecontext.h was missing a newline at the end of the file.
- Fixed: Timidity::Channel::mono, rpn, and nrpn were not initialized. In
particular, this meant that every channel was almost certainly in mono mode,
which can sound pretty bad if the song isn't meant to be played that way.
- Added bank numbers to the MIDI precaching for Timidity, since I guess I do
need to care about banks, if even the Duke MIDIs use various banks.
- Fixed: snd_midiprecache only exists in Win32 builds, so gameconfigfile.cpp
shouldn't unconditionally link against it.
- Fixed: pre_resample() was still disabled, and it left two samples at the end
of the new wave data uninitialized.
- Moved the xmap table from timidity/tables.cpp to playmidi.cpp. Now I can get
rid of timidity/tables.cpp, which conflicts in name with the main Doom
tables.cpp. (And interestingly, VC++ automatically renamed the object file,
so I wasn't aware of the problem with GCC.)
- Added a Gets function to the FileReader class which I planned to use
to enable Timidity to read its config and sound patches from Zips.
I put this on hold though after finding out that the sound quality
isn't even near that of Timidity++.
- GCC-Fixes (FString::GetChars() for Printf calls)
- Added a dummy Weapon.NOLMS flag so that Skulltag weapons using this flag
can be loaded
- Changed the MIDIStreamer to send the all notes off controller to each
channel when restarting the song, rather than emitting a single note off
event which only has 1 in 127 chance of being for a note that's playing
on that channel. Then I decided it would probably be a good idea to reset
all the controllers as well.
- Increasing the size of the internal Timidity stream buffer from 1/14 sec
(copied from the OPL player) improved its sound dramatically, so apparently
Timidity has issues with short stream buffers. It's now at 1/2 sec in
length. However, there seems to be something weird going on with
corazonazul_ff6boss.mid near the beginning where it stops and immediately
restarts a guitar on the exact same note.
- Added a new sound debugging cvar: snd_drawoutput, which can show various
oscilloscopes and spectrums.
- Eliminated some more global variables (onmobj, DoRipping, LastRipped,
MissileActor, bulletpitch and linetarget.)
- Internal TiMidity now plays music. Unfortunately, it doesn't sound right. :(
- Changed the progdir global variable into an FString.
git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@90 b0f79afe-0144-0410-b225-9a4edf0717df
2008-04-12 18:59:23 +00:00
|
|
|
{
|
2008-04-13 14:34:31 +00:00
|
|
|
if (bufptr[FilePos] == 0)
|
|
|
|
{
|
|
|
|
FilePos++;
|
|
|
|
break;
|
|
|
|
}
|
Update to ZDoom r905:
- Added Martin Howe's morph system update.
- Added support for defining composite textures in HIRESTEX. It is not fully tested
and right now can't do much more than the old TEXTUREx method.
- Added a few NULL pointer checks to the texture code.
- Made duplicate class names in DECORATE non-fatal. There is really no stability
concern here and the worst that can happen is that the wrong actor is spawned.
This was a constant hassle when testing with WADs that contain duplicate resources.
- Removed some GCC warnings.
- Fixed: MinGW doesn't have _get_pgmptr(), so it couldn't compile i_main.cpp.
- Fixed: MOD_WAVETABLE and MOD_SWSYNTH are not defined by w32api, so MinGW
failed compiling the new MIDI code.
- Fixed: LocalSndInfo and LocalSndSeq in S_Start() need to be const char
pointers, since "" is a constant.
- Fixed: parsecontext.h was missing a newline at the end of the file.
- Fixed: Timidity::Channel::mono, rpn, and nrpn were not initialized. In
particular, this meant that every channel was almost certainly in mono mode,
which can sound pretty bad if the song isn't meant to be played that way.
- Added bank numbers to the MIDI precaching for Timidity, since I guess I do
need to care about banks, if even the Duke MIDIs use various banks.
- Fixed: snd_midiprecache only exists in Win32 builds, so gameconfigfile.cpp
shouldn't unconditionally link against it.
- Fixed: pre_resample() was still disabled, and it left two samples at the end
of the new wave data uninitialized.
- Moved the xmap table from timidity/tables.cpp to playmidi.cpp. Now I can get
rid of timidity/tables.cpp, which conflicts in name with the main Doom
tables.cpp. (And interestingly, VC++ automatically renamed the object file,
so I wasn't aware of the problem with GCC.)
- Added a Gets function to the FileReader class which I planned to use
to enable Timidity to read its config and sound patches from Zips.
I put this on hold though after finding out that the sound quality
isn't even near that of Timidity++.
- GCC-Fixes (FString::GetChars() for Printf calls)
- Added a dummy Weapon.NOLMS flag so that Skulltag weapons using this flag
can be loaded
- Changed the MIDIStreamer to send the all notes off controller to each
channel when restarting the song, rather than emitting a single note off
event which only has 1 in 127 chance of being for a note that's playing
on that channel. Then I decided it would probably be a good idea to reset
all the controllers as well.
- Increasing the size of the internal Timidity stream buffer from 1/14 sec
(copied from the OPL player) improved its sound dramatically, so apparently
Timidity has issues with short stream buffers. It's now at 1/2 sec in
length. However, there seems to be something weird going on with
corazonazul_ff6boss.mid near the beginning where it stops and immediately
restarts a guitar on the exact same note.
- Added a new sound debugging cvar: snd_drawoutput, which can show various
oscilloscopes and spectrums.
- Eliminated some more global variables (onmobj, DoRipping, LastRipped,
MissileActor, bulletpitch and linetarget.)
- Internal TiMidity now plays music. Unfortunately, it doesn't sound right. :(
- Changed the progdir global variable into an FString.
git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@90 b0f79afe-0144-0410-b225-9a4edf0717df
2008-04-12 18:59:23 +00:00
|
|
|
if (bufptr[FilePos] != '\r')
|
|
|
|
{
|
|
|
|
*p++ = bufptr[FilePos];
|
|
|
|
len--;
|
2008-04-13 14:34:31 +00:00
|
|
|
if (bufptr[FilePos] == '\n')
|
|
|
|
{
|
|
|
|
FilePos++;
|
|
|
|
break;
|
|
|
|
}
|
Update to ZDoom r905:
- Added Martin Howe's morph system update.
- Added support for defining composite textures in HIRESTEX. It is not fully tested
and right now can't do much more than the old TEXTUREx method.
- Added a few NULL pointer checks to the texture code.
- Made duplicate class names in DECORATE non-fatal. There is really no stability
concern here and the worst that can happen is that the wrong actor is spawned.
This was a constant hassle when testing with WADs that contain duplicate resources.
- Removed some GCC warnings.
- Fixed: MinGW doesn't have _get_pgmptr(), so it couldn't compile i_main.cpp.
- Fixed: MOD_WAVETABLE and MOD_SWSYNTH are not defined by w32api, so MinGW
failed compiling the new MIDI code.
- Fixed: LocalSndInfo and LocalSndSeq in S_Start() need to be const char
pointers, since "" is a constant.
- Fixed: parsecontext.h was missing a newline at the end of the file.
- Fixed: Timidity::Channel::mono, rpn, and nrpn were not initialized. In
particular, this meant that every channel was almost certainly in mono mode,
which can sound pretty bad if the song isn't meant to be played that way.
- Added bank numbers to the MIDI precaching for Timidity, since I guess I do
need to care about banks, if even the Duke MIDIs use various banks.
- Fixed: snd_midiprecache only exists in Win32 builds, so gameconfigfile.cpp
shouldn't unconditionally link against it.
- Fixed: pre_resample() was still disabled, and it left two samples at the end
of the new wave data uninitialized.
- Moved the xmap table from timidity/tables.cpp to playmidi.cpp. Now I can get
rid of timidity/tables.cpp, which conflicts in name with the main Doom
tables.cpp. (And interestingly, VC++ automatically renamed the object file,
so I wasn't aware of the problem with GCC.)
- Added a Gets function to the FileReader class which I planned to use
to enable Timidity to read its config and sound patches from Zips.
I put this on hold though after finding out that the sound quality
isn't even near that of Timidity++.
- GCC-Fixes (FString::GetChars() for Printf calls)
- Added a dummy Weapon.NOLMS flag so that Skulltag weapons using this flag
can be loaded
- Changed the MIDIStreamer to send the all notes off controller to each
channel when restarting the song, rather than emitting a single note off
event which only has 1 in 127 chance of being for a note that's playing
on that channel. Then I decided it would probably be a good idea to reset
all the controllers as well.
- Increasing the size of the internal Timidity stream buffer from 1/14 sec
(copied from the OPL player) improved its sound dramatically, so apparently
Timidity has issues with short stream buffers. It's now at 1/2 sec in
length. However, there seems to be something weird going on with
corazonazul_ff6boss.mid near the beginning where it stops and immediately
restarts a guitar on the exact same note.
- Added a new sound debugging cvar: snd_drawoutput, which can show various
oscilloscopes and spectrums.
- Eliminated some more global variables (onmobj, DoRipping, LastRipped,
MissileActor, bulletpitch and linetarget.)
- Internal TiMidity now plays music. Unfortunately, it doesn't sound right. :(
- Changed the progdir global variable into an FString.
git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@90 b0f79afe-0144-0410-b225-9a4edf0717df
2008-04-12 18:59:23 +00:00
|
|
|
}
|
|
|
|
FilePos++;
|
|
|
|
}
|
2008-04-13 14:34:31 +00:00
|
|
|
if (p==strbuf) return NULL;
|
Update to ZDoom r905:
- Added Martin Howe's morph system update.
- Added support for defining composite textures in HIRESTEX. It is not fully tested
and right now can't do much more than the old TEXTUREx method.
- Added a few NULL pointer checks to the texture code.
- Made duplicate class names in DECORATE non-fatal. There is really no stability
concern here and the worst that can happen is that the wrong actor is spawned.
This was a constant hassle when testing with WADs that contain duplicate resources.
- Removed some GCC warnings.
- Fixed: MinGW doesn't have _get_pgmptr(), so it couldn't compile i_main.cpp.
- Fixed: MOD_WAVETABLE and MOD_SWSYNTH are not defined by w32api, so MinGW
failed compiling the new MIDI code.
- Fixed: LocalSndInfo and LocalSndSeq in S_Start() need to be const char
pointers, since "" is a constant.
- Fixed: parsecontext.h was missing a newline at the end of the file.
- Fixed: Timidity::Channel::mono, rpn, and nrpn were not initialized. In
particular, this meant that every channel was almost certainly in mono mode,
which can sound pretty bad if the song isn't meant to be played that way.
- Added bank numbers to the MIDI precaching for Timidity, since I guess I do
need to care about banks, if even the Duke MIDIs use various banks.
- Fixed: snd_midiprecache only exists in Win32 builds, so gameconfigfile.cpp
shouldn't unconditionally link against it.
- Fixed: pre_resample() was still disabled, and it left two samples at the end
of the new wave data uninitialized.
- Moved the xmap table from timidity/tables.cpp to playmidi.cpp. Now I can get
rid of timidity/tables.cpp, which conflicts in name with the main Doom
tables.cpp. (And interestingly, VC++ automatically renamed the object file,
so I wasn't aware of the problem with GCC.)
- Added a Gets function to the FileReader class which I planned to use
to enable Timidity to read its config and sound patches from Zips.
I put this on hold though after finding out that the sound quality
isn't even near that of Timidity++.
- GCC-Fixes (FString::GetChars() for Printf calls)
- Added a dummy Weapon.NOLMS flag so that Skulltag weapons using this flag
can be loaded
- Changed the MIDIStreamer to send the all notes off controller to each
channel when restarting the song, rather than emitting a single note off
event which only has 1 in 127 chance of being for a note that's playing
on that channel. Then I decided it would probably be a good idea to reset
all the controllers as well.
- Increasing the size of the internal Timidity stream buffer from 1/14 sec
(copied from the OPL player) improved its sound dramatically, so apparently
Timidity has issues with short stream buffers. It's now at 1/2 sec in
length. However, there seems to be something weird going on with
corazonazul_ff6boss.mid near the beginning where it stops and immediately
restarts a guitar on the exact same note.
- Added a new sound debugging cvar: snd_drawoutput, which can show various
oscilloscopes and spectrums.
- Eliminated some more global variables (onmobj, DoRipping, LastRipped,
MissileActor, bulletpitch and linetarget.)
- Internal TiMidity now plays music. Unfortunately, it doesn't sound right. :(
- Changed the progdir global variable into an FString.
git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@90 b0f79afe-0144-0410-b225-9a4edf0717df
2008-04-12 18:59:23 +00:00
|
|
|
*p++=0;
|
|
|
|
return strbuf;
|
|
|
|
}
|
|
|
|
|
2008-01-27 11:25:03 +00:00
|
|
|
long FileReader::CalcFileLen() const
|
|
|
|
{
|
|
|
|
long endpos;
|
|
|
|
|
|
|
|
fseek (File, 0, SEEK_END);
|
|
|
|
endpos = ftell (File);
|
|
|
|
fseek (File, 0, SEEK_SET);
|
|
|
|
return endpos;
|
|
|
|
}
|
|
|
|
|
2008-03-19 11:19:03 +00:00
|
|
|
//==========================================================================
|
|
|
|
//
|
|
|
|
// FileReaderZ
|
|
|
|
//
|
|
|
|
// The zlib wrapper
|
|
|
|
// reads data from a ZLib compressed stream
|
|
|
|
//
|
|
|
|
//==========================================================================
|
2008-01-27 11:25:03 +00:00
|
|
|
|
|
|
|
FileReaderZ::FileReaderZ (FileReader &file, bool zip)
|
|
|
|
: File(file), SawEOF(false)
|
|
|
|
{
|
|
|
|
int err;
|
|
|
|
|
|
|
|
FillBuffer ();
|
|
|
|
|
|
|
|
Stream.zalloc = Z_NULL;
|
|
|
|
Stream.zfree = Z_NULL;
|
|
|
|
|
|
|
|
if (!zip) err = inflateInit (&Stream);
|
|
|
|
else err = inflateInit2 (&Stream, -MAX_WBITS);
|
|
|
|
|
|
|
|
if (err != Z_OK)
|
|
|
|
{
|
2012-06-18 17:50:32 +00:00
|
|
|
I_Error ("FileReaderZ: inflateInit failed: %s\n", M_ZLibError(err).GetChars());
|
2008-01-27 11:25:03 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
FileReaderZ::~FileReaderZ ()
|
|
|
|
{
|
|
|
|
inflateEnd (&Stream);
|
|
|
|
}
|
|
|
|
|
|
|
|
long FileReaderZ::Read (void *buffer, long len)
|
|
|
|
{
|
|
|
|
int err;
|
|
|
|
|
|
|
|
Stream.next_out = (Bytef *)buffer;
|
|
|
|
Stream.avail_out = len;
|
|
|
|
|
|
|
|
do
|
|
|
|
{
|
|
|
|
err = inflate (&Stream, Z_SYNC_FLUSH);
|
|
|
|
if (Stream.avail_in == 0 && !SawEOF)
|
|
|
|
{
|
|
|
|
FillBuffer ();
|
|
|
|
}
|
|
|
|
} while (err == Z_OK && Stream.avail_out != 0);
|
|
|
|
|
|
|
|
if (err != Z_OK && err != Z_STREAM_END)
|
|
|
|
{
|
|
|
|
I_Error ("Corrupt zlib stream");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Stream.avail_out != 0)
|
|
|
|
{
|
|
|
|
I_Error ("Ran out of data in zlib stream");
|
|
|
|
}
|
|
|
|
|
|
|
|
return len - Stream.avail_out;
|
|
|
|
}
|
|
|
|
|
|
|
|
void FileReaderZ::FillBuffer ()
|
|
|
|
{
|
|
|
|
long numread = File.Read (InBuff, BUFF_SIZE);
|
|
|
|
|
|
|
|
if (numread < BUFF_SIZE)
|
|
|
|
{
|
|
|
|
SawEOF = true;
|
|
|
|
}
|
|
|
|
Stream.next_in = InBuff;
|
|
|
|
Stream.avail_in = numread;
|
|
|
|
}
|
|
|
|
|
2009-03-12 20:59:09 +00:00
|
|
|
//==========================================================================
|
|
|
|
//
|
|
|
|
// FileReaderZ
|
|
|
|
//
|
|
|
|
// The bzip2 wrapper
|
|
|
|
// reads data from a libbzip2 compressed stream
|
|
|
|
//
|
|
|
|
//==========================================================================
|
|
|
|
|
|
|
|
FileReaderBZ2::FileReaderBZ2 (FileReader &file)
|
|
|
|
: File(file), SawEOF(false)
|
|
|
|
{
|
|
|
|
int err;
|
|
|
|
|
|
|
|
FillBuffer ();
|
|
|
|
|
|
|
|
Stream.bzalloc = NULL;
|
|
|
|
Stream.bzfree = NULL;
|
|
|
|
Stream.opaque = NULL;
|
|
|
|
|
|
|
|
err = BZ2_bzDecompressInit(&Stream, 0, 0);
|
|
|
|
|
|
|
|
if (err != BZ_OK)
|
|
|
|
{
|
|
|
|
I_Error ("FileReaderBZ2: bzDecompressInit failed: %d\n", err);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
FileReaderBZ2::~FileReaderBZ2 ()
|
|
|
|
{
|
|
|
|
BZ2_bzDecompressEnd (&Stream);
|
|
|
|
}
|
|
|
|
|
|
|
|
long FileReaderBZ2::Read (void *buffer, long len)
|
|
|
|
{
|
|
|
|
int err;
|
|
|
|
|
|
|
|
Stream.next_out = (char *)buffer;
|
|
|
|
Stream.avail_out = len;
|
|
|
|
|
|
|
|
do
|
|
|
|
{
|
|
|
|
err = BZ2_bzDecompress(&Stream);
|
|
|
|
if (Stream.avail_in == 0 && !SawEOF)
|
|
|
|
{
|
|
|
|
FillBuffer ();
|
|
|
|
}
|
|
|
|
} while (err == BZ_OK && Stream.avail_out != 0);
|
|
|
|
|
|
|
|
if (err != BZ_OK && err != BZ_STREAM_END)
|
|
|
|
{
|
|
|
|
I_Error ("Corrupt bzip2 stream");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Stream.avail_out != 0)
|
|
|
|
{
|
|
|
|
I_Error ("Ran out of data in bzip2 stream");
|
|
|
|
}
|
|
|
|
|
|
|
|
return len - Stream.avail_out;
|
|
|
|
}
|
|
|
|
|
|
|
|
void FileReaderBZ2::FillBuffer ()
|
|
|
|
{
|
|
|
|
long numread = File.Read(InBuff, BUFF_SIZE);
|
|
|
|
|
|
|
|
if (numread < BUFF_SIZE)
|
|
|
|
{
|
|
|
|
SawEOF = true;
|
|
|
|
}
|
|
|
|
Stream.next_in = (char *)InBuff;
|
|
|
|
Stream.avail_in = numread;
|
|
|
|
}
|
|
|
|
|
|
|
|
//==========================================================================
|
|
|
|
//
|
|
|
|
// bz_internal_error
|
|
|
|
//
|
|
|
|
// libbzip2 wants this, since we build it with BZ_NO_STDIO set.
|
|
|
|
//
|
|
|
|
//==========================================================================
|
|
|
|
|
|
|
|
extern "C" void bz_internal_error (int errcode)
|
|
|
|
{
|
|
|
|
I_FatalError("libbzip2: internal error number %d\n", errcode);
|
|
|
|
}
|
|
|
|
|
|
|
|
//==========================================================================
|
|
|
|
//
|
|
|
|
// FileReaderLZMA
|
|
|
|
//
|
|
|
|
// The lzma wrapper
|
|
|
|
// reads data from a LZMA compressed stream
|
|
|
|
//
|
|
|
|
//==========================================================================
|
|
|
|
|
|
|
|
static void *SzAlloc(void *p, size_t size) { p = p; return malloc(size); }
|
|
|
|
static void SzFree(void *p, void *address) { p = p; free(address); }
|
2009-04-19 06:46:53 +00:00
|
|
|
ISzAlloc g_Alloc = { SzAlloc, SzFree };
|
2009-03-12 20:59:09 +00:00
|
|
|
|
|
|
|
FileReaderLZMA::FileReaderLZMA (FileReader &file, size_t uncompressed_size, bool zip)
|
|
|
|
: File(file), SawEOF(false)
|
|
|
|
{
|
|
|
|
BYTE header[4 + LZMA_PROPS_SIZE];
|
|
|
|
int err;
|
|
|
|
|
|
|
|
assert(zip == true);
|
|
|
|
|
|
|
|
Size = uncompressed_size;
|
|
|
|
OutProcessed = 0;
|
|
|
|
|
|
|
|
// Read zip LZMA properties header
|
|
|
|
if (File.Read(header, sizeof(header)) < (long)sizeof(header))
|
|
|
|
{
|
|
|
|
I_Error("FileReaderLZMA: File too shart\n");
|
|
|
|
}
|
|
|
|
if (header[2] + header[3] * 256 != LZMA_PROPS_SIZE)
|
|
|
|
{
|
|
|
|
I_Error("FileReaderLZMA: LZMA props size is %d (expected %d)\n",
|
|
|
|
header[2] + header[3] * 256, LZMA_PROPS_SIZE);
|
|
|
|
}
|
|
|
|
|
|
|
|
FillBuffer();
|
|
|
|
|
|
|
|
LzmaDec_Construct(&Stream);
|
|
|
|
err = LzmaDec_Allocate(&Stream, header + 4, LZMA_PROPS_SIZE, &g_Alloc);
|
|
|
|
|
|
|
|
if (err != SZ_OK)
|
|
|
|
{
|
|
|
|
I_Error("FileReaderLZMA: LzmaDec_Allocate failed: %d\n", err);
|
|
|
|
}
|
|
|
|
|
|
|
|
LzmaDec_Init(&Stream);
|
|
|
|
}
|
|
|
|
|
|
|
|
FileReaderLZMA::~FileReaderLZMA ()
|
|
|
|
{
|
|
|
|
LzmaDec_Free(&Stream, &g_Alloc);
|
|
|
|
}
|
|
|
|
|
|
|
|
long FileReaderLZMA::Read (void *buffer, long len)
|
|
|
|
{
|
|
|
|
int err;
|
|
|
|
Byte *next_out = (Byte *)buffer;
|
|
|
|
|
|
|
|
do
|
|
|
|
{
|
|
|
|
ELzmaFinishMode finish_mode = LZMA_FINISH_ANY;
|
|
|
|
ELzmaStatus status;
|
|
|
|
size_t out_processed = len;
|
|
|
|
size_t in_processed = InSize;
|
|
|
|
|
|
|
|
err = LzmaDec_DecodeToBuf(&Stream, next_out, &out_processed, InBuff + InPos, &in_processed, finish_mode, &status);
|
|
|
|
InPos += in_processed;
|
|
|
|
InSize -= in_processed;
|
|
|
|
next_out += out_processed;
|
|
|
|
len = (long)(len - out_processed);
|
|
|
|
if (err != SZ_OK)
|
|
|
|
{
|
|
|
|
I_Error ("Corrupt LZMA stream");
|
|
|
|
}
|
|
|
|
if (in_processed == 0 && out_processed == 0)
|
|
|
|
{
|
|
|
|
if (status != LZMA_STATUS_FINISHED_WITH_MARK)
|
|
|
|
{
|
|
|
|
I_Error ("Corrupt LZMA stream");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (InSize == 0 && !SawEOF)
|
|
|
|
{
|
|
|
|
FillBuffer ();
|
|
|
|
}
|
|
|
|
} while (err == SZ_OK && len != 0);
|
|
|
|
|
|
|
|
if (err != Z_OK && err != Z_STREAM_END)
|
|
|
|
{
|
|
|
|
I_Error ("Corrupt LZMA stream");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (len != 0)
|
|
|
|
{
|
|
|
|
I_Error ("Ran out of data in LZMA stream");
|
|
|
|
}
|
|
|
|
|
|
|
|
return (long)(next_out - (Byte *)buffer);
|
|
|
|
}
|
|
|
|
|
|
|
|
void FileReaderLZMA::FillBuffer ()
|
|
|
|
{
|
|
|
|
long numread = File.Read(InBuff, BUFF_SIZE);
|
|
|
|
|
|
|
|
if (numread < BUFF_SIZE)
|
|
|
|
{
|
|
|
|
SawEOF = true;
|
|
|
|
}
|
|
|
|
InPos = 0;
|
|
|
|
InSize = numread;
|
|
|
|
}
|
|
|
|
|
2008-03-19 11:19:03 +00:00
|
|
|
//==========================================================================
|
|
|
|
//
|
|
|
|
// MemoryReader
|
|
|
|
//
|
|
|
|
// reads data from a block of memory
|
|
|
|
//
|
|
|
|
//==========================================================================
|
|
|
|
|
2008-01-27 11:25:03 +00:00
|
|
|
MemoryReader::MemoryReader (const char *buffer, long length)
|
|
|
|
{
|
|
|
|
bufptr=buffer;
|
|
|
|
Length=length;
|
|
|
|
FilePos=0;
|
|
|
|
}
|
|
|
|
|
|
|
|
MemoryReader::~MemoryReader ()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
long MemoryReader::Tell () const
|
|
|
|
{
|
|
|
|
return FilePos;
|
|
|
|
}
|
|
|
|
|
|
|
|
long MemoryReader::Seek (long offset, int origin)
|
|
|
|
{
|
|
|
|
switch (origin)
|
|
|
|
{
|
|
|
|
case SEEK_CUR:
|
|
|
|
offset+=FilePos;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SEEK_END:
|
|
|
|
offset+=Length;
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
FilePos=clamp<long>(offset,0,Length-1);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
long MemoryReader::Read (void *buffer, long len)
|
|
|
|
{
|
|
|
|
if (len>Length-FilePos) len=Length-FilePos;
|
|
|
|
if (len<0) len=0;
|
|
|
|
memcpy(buffer,bufptr+FilePos,len);
|
|
|
|
FilePos+=len;
|
|
|
|
return len;
|
|
|
|
}
|
Update to ZDoom r905:
- Added Martin Howe's morph system update.
- Added support for defining composite textures in HIRESTEX. It is not fully tested
and right now can't do much more than the old TEXTUREx method.
- Added a few NULL pointer checks to the texture code.
- Made duplicate class names in DECORATE non-fatal. There is really no stability
concern here and the worst that can happen is that the wrong actor is spawned.
This was a constant hassle when testing with WADs that contain duplicate resources.
- Removed some GCC warnings.
- Fixed: MinGW doesn't have _get_pgmptr(), so it couldn't compile i_main.cpp.
- Fixed: MOD_WAVETABLE and MOD_SWSYNTH are not defined by w32api, so MinGW
failed compiling the new MIDI code.
- Fixed: LocalSndInfo and LocalSndSeq in S_Start() need to be const char
pointers, since "" is a constant.
- Fixed: parsecontext.h was missing a newline at the end of the file.
- Fixed: Timidity::Channel::mono, rpn, and nrpn were not initialized. In
particular, this meant that every channel was almost certainly in mono mode,
which can sound pretty bad if the song isn't meant to be played that way.
- Added bank numbers to the MIDI precaching for Timidity, since I guess I do
need to care about banks, if even the Duke MIDIs use various banks.
- Fixed: snd_midiprecache only exists in Win32 builds, so gameconfigfile.cpp
shouldn't unconditionally link against it.
- Fixed: pre_resample() was still disabled, and it left two samples at the end
of the new wave data uninitialized.
- Moved the xmap table from timidity/tables.cpp to playmidi.cpp. Now I can get
rid of timidity/tables.cpp, which conflicts in name with the main Doom
tables.cpp. (And interestingly, VC++ automatically renamed the object file,
so I wasn't aware of the problem with GCC.)
- Added a Gets function to the FileReader class which I planned to use
to enable Timidity to read its config and sound patches from Zips.
I put this on hold though after finding out that the sound quality
isn't even near that of Timidity++.
- GCC-Fixes (FString::GetChars() for Printf calls)
- Added a dummy Weapon.NOLMS flag so that Skulltag weapons using this flag
can be loaded
- Changed the MIDIStreamer to send the all notes off controller to each
channel when restarting the song, rather than emitting a single note off
event which only has 1 in 127 chance of being for a note that's playing
on that channel. Then I decided it would probably be a good idea to reset
all the controllers as well.
- Increasing the size of the internal Timidity stream buffer from 1/14 sec
(copied from the OPL player) improved its sound dramatically, so apparently
Timidity has issues with short stream buffers. It's now at 1/2 sec in
length. However, there seems to be something weird going on with
corazonazul_ff6boss.mid near the beginning where it stops and immediately
restarts a guitar on the exact same note.
- Added a new sound debugging cvar: snd_drawoutput, which can show various
oscilloscopes and spectrums.
- Eliminated some more global variables (onmobj, DoRipping, LastRipped,
MissileActor, bulletpitch and linetarget.)
- Internal TiMidity now plays music. Unfortunately, it doesn't sound right. :(
- Changed the progdir global variable into an FString.
git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@90 b0f79afe-0144-0410-b225-9a4edf0717df
2008-04-12 18:59:23 +00:00
|
|
|
|
|
|
|
char *MemoryReader::Gets(char *strbuf, int len)
|
|
|
|
{
|
|
|
|
return GetsFromBuffer(bufptr, strbuf, len);
|
|
|
|
}
|