gzdoom-gles/src/s_playlist.cpp
Randy Heit e815474cbe - Fixed: ACS improperly calculated the address of local variables when
returning from one function to another function when the function that
  was called was used as part of an expression.
- Fixed: Using Thing_Hate with arg0 (hater) set to 0 from an open script
  could crash.
- Fixed: Some items along ledges in Hexen's MAP32 (Orchard of Lamentations)
  appeared at the bottom of the ledge (and consequently inside it) instead
  of on top of it because the items were placed directly on the lines.
  AActor::LinkToWorldForMapThing() needs to use the original R_PointOnLineSide()
  code to handle situations like this. Previously, it just used the original
  code for straight horizontal/vertical lines and used the new code for
  diagonal lines.
- Fixed: FWadCollection::MergeLumps() used in incorrect realloc.
- Fixed: FPlayList::NextLine() did not properly handle blank lines in the
  playlist.
- Changed: Decals now use lightweight thinkers instead of actors. (76 bytes
  versus 396, so you save 320k if you have 1024 decals present.)
- Fixed: Wads added with pullin were loaded immediately after the IWAD.
  Exec files are now processed immediately before -file but after autoloading
  wads in D_DoomMain().
- Fixed: sdl/i_system.h unconditionally defined SHARE_DIR, preventing
  redefinition from the command line.
- Fixed: The standard way to include SDL.h is <SDL.h>, not <SDL/SDL.h>.
- Fixed: Returned FActiveInterpolation::HashKey()'s return type to size_t,
  avoiding a pointer truncation warning.


SVN r30 (trunk)
2006-04-12 01:50:09 +00:00

199 lines
4.5 KiB
C++

/*
** s_playlist.cpp
** Implementation of the FPlayList class. Handles m3u playlist parsing
**
**---------------------------------------------------------------------------
** Copyright 1998-2005 Randy Heit
** 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.
**---------------------------------------------------------------------------
**
*/
#include <stdlib.h>
#include "cmdlib.h"
#include "s_playlist.h"
#include "templates.h"
FPlayList::FPlayList (const char *path)
{
Songs = NULL;
SongList = NULL;
ChangeList (path);
}
FPlayList::~FPlayList ()
{
if (Songs) delete[] Songs;
if (SongList) delete[] SongList;
}
bool FPlayList::ChangeList (const char *path)
{
char linebuff[256];
size_t songlengths;
int songcount;
FILE *file;
if (Songs)
{
delete[] Songs;
Songs = NULL;
}
if (SongList)
{
delete[] SongList;
SongList = NULL;
}
Position = 0;
NumSongs = 0;
if ( (file = fopen (path, "r")) == NULL)
return false;
songlengths = 0;
songcount = 0;
while (NextLine (file, linebuff, sizeof(linebuff)))
{
songcount++;
songlengths += strlen (linebuff) + 1;
}
rewind (file);
if (songcount > 0)
{
Songs = new char *[songcount];
SongList = new char[songlengths];
NumSongs = songcount;
songlengths = 0;
for (songcount = 0; songcount < NumSongs &&
NextLine (file, linebuff, sizeof(linebuff)); songcount++)
{
size_t len = strlen (linebuff) + 1;
memcpy (SongList + songlengths, linebuff, len);
Songs[songcount] = SongList + songlengths;
songlengths += len;
}
NumSongs = songcount;
}
fclose (file);
return NumSongs > 0;
}
bool FPlayList::NextLine (FILE *file, char *buffer, int n)
{
char *skipper;
do
{
if (NULL == fgets (buffer, n, file))
return false;
for (skipper = buffer; *skipper != 0 && *skipper <= ' '; skipper++)
;
} while (*skipper == '#' || *skipper == 0);
if (skipper > buffer)
memmove (buffer, skipper, strlen (skipper)+1);
if (buffer[strlen (buffer)-1] == '\n')
buffer[strlen (buffer)-1] = 0;
FixPathSeperator (buffer);
return true;
}
// Shuffles the playlist and resets the position to the start
void FPlayList::Shuffle ()
{
int i;
for (i = 0; i < NumSongs; ++i)
{
swap (Songs[i], Songs[(rand() % (NumSongs - i)) + i]);
}
Position = 0;
}
int FPlayList::GetNumSongs () const
{
return NumSongs;
}
int FPlayList::SetPosition (int position)
{
if ((unsigned)position >= (unsigned)NumSongs)
{
Position = 0;
}
else
{
Position = position;
}
DPrintf ("Playlist position set to %d\n", Position);
return Position;
}
int FPlayList::GetPosition () const
{
return Position;
}
int FPlayList::Advance ()
{
if (++Position >= NumSongs)
{
Position = 0;
}
DPrintf ("Playlist advanced to song %d\n", Position);
return Position;
}
int FPlayList::Backup ()
{
if (--Position < 0)
{
Position = NumSongs - 1;
}
DPrintf ("Playlist backed up to song %d\n", Position);
return Position;
}
const char *FPlayList::GetSong (int position) const
{
if ((unsigned)position >= (unsigned)NumSongs)
return NULL;
return Songs[position];
}