Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* bzflag
- * Copyright (c) 1993-2021 Tim Riker
- *
- * This package is free software; you can redistribute it and/or
- * modify it under the terms of the license found in the file
- * named COPYING that should have accompanied this file.
- *
- * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
- #include "BzfMedia.h"
- #include "TimeKeeper.h"
- #if !defined(HAVE_SDL) || defined(_WIN32)
- #include "wave.h"
- #endif
- #include "MediaFile.h"
- #include <string.h>
- #include <string>
- #include <stdio.h>
- #include "CacheManager.h"
- BzfMedia::BzfMedia() : mediaDir(DEFAULT_MEDIA_DIR) {}
- BzfMedia::~BzfMedia() {}
- double BzfMedia::stopwatch(bool start)
- {
- static TimeKeeper prev;
- if (start)
- {
- prev = TimeKeeper::getCurrent();
- return 0.0;
- }
- else
- return (double)(TimeKeeper::getCurrent() - prev);
- }
- std::string BzfMedia::getMediaDirectory() const
- {
- return mediaDir;
- }
- void BzfMedia::setMediaDirectory(const std::string& _dir)
- {
- mediaDir = _dir;
- }
- unsigned char* BzfMedia::readImage(const std::string& filename,
- int& width, int& height, int& depth) const
- {
- // try mediaDir/filename
- std::string name = makePath(mediaDir, filename);
- unsigned char* image = doReadImage(name, width, height, depth);
- if (image) return image;
- // try filename as is
- image = doReadImage(filename, width, height, depth);
- if (image) return image;
- #if defined(INSTALL_DATA_DIR)
- // try standard-mediaDir/filename
- name = makePath(INSTALL_DATA_DIR, filename);
- image = doReadImage(name, width, height, depth);
- if (image) return image;
- #endif
- // try mediaDir/filename with replaced extension
- name = replaceExtension(makePath(mediaDir, filename), getImageExtension());
- image = doReadImage(name, width, height, depth);
- if (image) return image;
- // try filename with replaced extension
- name = replaceExtension(filename, getImageExtension());
- image = doReadImage(name, width, height, depth);
- if (image) return image;
- #if defined(INSTALL_DATA_DIR)
- // try standard-mediaDir/filename with replaced extension
- name = makePath(INSTALL_DATA_DIR, filename);
- name = replaceExtension(name, getImageExtension());
- image = doReadImage(name, width, height, depth);
- if (image) return image;
- #endif
- // try data/filename
- name = makePath(DEFAULT_MEDIA_DIR, filename);
- image = doReadImage(name, width, height, depth);
- if (image) return image;
- // try data/filename with replaced extension
- name = replaceExtension(makePath(DEFAULT_MEDIA_DIR, filename), getImageExtension());
- image = doReadImage(name, width, height, depth);
- if (image) return image;
- // try ../data/filename
- name = "../";
- name += DEFAULT_MEDIA_DIR;
- name = makePath(name, filename);
- image = doReadImage(name, width, height, depth);
- if (image) return image;
- // try ../data/filename with replaced extension
- name = "../";
- name += DEFAULT_MEDIA_DIR;
- name = replaceExtension(makePath(name, filename), getImageExtension());
- image = doReadImage(name, width, height, depth);
- if (image) return image;
- // try ../../data/filename
- name = "../../";
- name += DEFAULT_MEDIA_DIR;
- name = makePath(name, filename);
- image = doReadImage(name, width, height, depth);
- if (image) return image;
- // try ../../data/filename with replaced extension
- name = "../../";
- name += DEFAULT_MEDIA_DIR;
- name = replaceExtension(makePath(name, filename), getImageExtension());
- image = doReadImage(name, width, height, depth);
- if (image) return image;
- #ifndef DEBUG
- std::cout << "Unable to locate [" << filename << "] image file (media dir is set to " << mediaDir << ")" << std::endl;
- #endif
- return NULL;
- }
- /* Get the sound file. */
- float* BzfMedia::readSound(const std::string& filename,
- int& numFrames, int& rate) const
- {
- // try mediaDir/filename IE: the data folder.
- std::string name = makePath(mediaDir, filename);
- float* sound = doReadSound(name, numFrames, rate);
- if (sound) return sound;
- // try filename as is IE: direct path.
- sound = doReadSound(filename, numFrames, rate);
- if (sound) return sound;
- #if defined(INSTALL_DATA_DIR)
- // try standard-mediaDir/filename
- name = makePath(INSTALL_DATA_DIR, filename);
- sound = doReadSound(name, numFrames, rate);
- if (sound) return sound;
- #endif
- // try mediaDir/filename with replaced extension
- name = replaceExtension(makePath(mediaDir, filename), getSoundExtension());
- sound = doReadSound(name, numFrames, rate);
- if (sound) return sound;
- // try filename with replaced extension
- name = replaceExtension(filename, getSoundExtension());
- sound = doReadSound(name, numFrames, rate);
- if (sound) return sound;
- #if defined(INSTALL_DATA_DIR)
- // try mediaDir/filename with replaced extension
- name = makePath(INSTALL_DATA_DIR, filename);
- name = replaceExtension(name, getSoundExtension());
- sound = doReadSound(name, numFrames, rate);
- if (sound) return sound;
- #endif
- // try mediaDir/filename
- name = makePath(DEFAULT_MEDIA_DIR, filename);
- sound = doReadSound(name, numFrames, rate);
- if (sound) return sound;
- // try mediaDir/filename with replaced extension
- name = replaceExtension(makePath(DEFAULT_MEDIA_DIR, filename), getSoundExtension());
- sound = doReadSound(name, numFrames, rate);
- if (sound) return sound;
- // try mediaDir/filename
- name = "../";
- name += DEFAULT_MEDIA_DIR;
- name = makePath(name, filename);
- sound = doReadSound(name, numFrames, rate);
- if (sound) return sound;
- // try mediaDir/filename with replaced extension
- name = "../";
- name += DEFAULT_MEDIA_DIR;
- name = replaceExtension(makePath(name, filename), getSoundExtension());
- sound = doReadSound(name, numFrames, rate);
- if (sound) return sound;
- // try mediaDir/filename
- name = "../../";
- name += DEFAULT_MEDIA_DIR;
- name = makePath(name, filename);
- sound = doReadSound(name, numFrames, rate);
- if (sound) return sound;
- // try mediaDir/filename with replaced extension
- name = "../../";
- name += DEFAULT_MEDIA_DIR;
- name = replaceExtension(makePath(name, filename), getSoundExtension());
- sound = doReadSound(name, numFrames, rate);
- if (sound) return sound;
- // try the cache...
- name = makePath(name, CACHEMGR.getLocalName(filename));
- sound = doReadSound(name, numFrames, rate);
- if (sound) return sound;
- #ifndef DEBUG
- std::cout << "Unable to locate [" << filename << "] audio file (media dir is set to " << mediaDir << ")" << std::endl;
- #endif
- return NULL;
- }
- std::string BzfMedia::makePath(const std::string& dir,
- const std::string& filename) const
- {
- if ((dir.length() == 0) || filename[0] == '/') return filename;
- std::string path = dir;
- path += "/";
- path += filename;
- return path;
- }
- std::string BzfMedia::replaceExtension(
- const std::string& pathname,
- const std::string& extension) const
- {
- std::string newName;
- const int extPosition = findExtension(pathname);
- if (extPosition == 0)
- newName = pathname;
- else
- newName = pathname.substr(0, extPosition);
- newName += ".";
- newName += extension;
- return newName;
- }
- int BzfMedia::findExtension(const std::string& pathname) const
- {
- int dot = pathname.rfind(".");
- int slash = pathname.rfind("/");
- return ((slash > dot) ? 0 : dot);
- }
- std::string BzfMedia::getImageExtension() const
- {
- return std::string("png");
- }
- std::string BzfMedia::getSoundExtension() const
- {
- return std::string("wav");
- }
- unsigned char* BzfMedia::doReadImage(const std::string& filename,
- int& dx, int& dy, int&) const
- {
- return MediaFile::readImage( filename, &dx, &dy );
- }
- int16_t BzfMedia::getShort(const void* ptr)
- {
- const unsigned char* data = (const unsigned char*)ptr;
- return ((int16_t)data[0] << 8) + (int16_t)data[1];
- }
- uint16_t BzfMedia::getUShort(const void* ptr)
- {
- const unsigned char* data = (const unsigned char*)ptr;
- return ((uint16_t)data[0] << 8) + (uint16_t)data[1];
- }
- int32_t BzfMedia::getLong(const void* ptr)
- {
- const unsigned char* data = (const unsigned char*)ptr;
- return ((int32_t)data[0] << 24) + ((int32_t)data[1] << 16) +
- ((int32_t)data[2] << 8) + (int32_t)data[3];
- }
- bool BzfMedia::doReadVerbatim(FILE* file,
- int dx, int dy, int dz,
- unsigned char* image)
- {
- // zero image data
- memset(image, 0, 4 * dx * dy);
- // how many channels to read?
- if (dz > 4)
- dz = 4;
- // read each channel one after the other
- unsigned char row[4096];
- for (int k = 0; k < dz; ++k)
- {
- unsigned char* dst = image + k;
- for (int j = 0; j < dy; ++j)
- {
- // read raw data
- if (fread(row, dx, 1, file) != 1)
- return false;
- // reformat
- for (int i = 0; i < dx; ++i)
- {
- *dst = row[i];
- dst += 4;
- }
- }
- }
- return true;
- }
- bool BzfMedia::doReadRLE(FILE* file,
- int dx, int dy, int dz,
- unsigned char* image)
- {
- // zero image data
- memset(image, 0, 4 * dx * dy);
- // how many channels to read?
- if (dz > 4)
- dz = 4;
- // read offset tables
- const int tableSize = dy * dz;
- int32_t* startTable = new int32_t[tableSize];
- if (fread(startTable, 4 * tableSize, 1, file) != 1)
- {
- delete[] startTable;
- return false;
- }
- int32_t* lengthTable = new int32_t[tableSize];
- if (fread(lengthTable, 4 * tableSize, 1, file) != 1)
- {
- delete[] startTable;
- delete[] lengthTable;
- return false;
- }
- // convert offset tables to proper endianness
- for (int n = 0; n < tableSize; ++n)
- {
- startTable[n] = getLong(startTable + n);
- lengthTable[n] = getLong(lengthTable + n);
- }
- // read each channel one after the other
- unsigned char row[4096];
- for (int k = 0; k < dz; ++k)
- {
- unsigned char* dst = image + k;
- for (int j = 0; j < dy; ++j)
- {
- // read raw data
- const int32_t length = lengthTable[j + k * dy];
- if (fseek(file, startTable[j + k * dy], SEEK_SET) < 0 ||
- fread(row, length, 1, file) != 1)
- {
- delete[] startTable;
- delete[] lengthTable;
- return false;
- }
- // decode
- unsigned char* src = row;
- while (1)
- {
- // check for error in image
- if (src - row >= length)
- {
- delete[] startTable;
- delete[] lengthTable;
- return false;
- }
- // get next code
- const unsigned char type = *src++;
- int count = (int)(type & 0x7f);
- // zero code means end of row
- if (count == 0)
- break;
- if (type & 0x80)
- {
- // copy count pixels
- while (count--)
- {
- *dst = *src++;
- dst += 4;
- }
- }
- else
- {
- // repeat pixel count times
- const unsigned char pixel = *src++;
- while (count--)
- {
- *dst = pixel;
- dst += 4;
- }
- }
- }
- }
- }
- delete[] startTable;
- delete[] lengthTable;
- return true;
- }
- #if defined(HAVE_SDL) && !defined(_WIN32)
- float* BzfMedia::doReadSound(const std::string&, int&, int&) const
- {
- return NULL;
- }
- #else
- float* BzfMedia::doReadSound(const std::string& filename,
- int& numFrames, int& rate) const
- {
- short format, channels, width;
- long speed;
- FILE* file;
- char *rawdata, *rawpos;
- int i;
- float *data;
- file = openWavFile(filename.c_str(), &format, &speed, &numFrames, &channels, &width);
- if (!file) return 0;
- rate=speed;
- rawdata=new char[numFrames*width*channels];
- if (readWavData(file, rawdata, numFrames*channels, width))
- {
- fprintf(stderr, "Failed to read the wav data\n");
- delete [] rawdata;
- closeWavFile(file);
- return 0;
- }
- closeWavFile(file);
- #ifdef HALF_RATE_AUDIO
- numFrames/=2;
- rate/=2;
- #endif
- data = new float[2*numFrames];
- rawpos=rawdata;
- for (i=0; i<numFrames; i++)
- {
- if (channels==1)
- {
- if (width==1)
- {
- data[i*2]=data[i*2+1] = (*(signed char*)rawpos)*256.0f;
- rawpos++;
- #ifdef HALF_RATE_AUDIO
- rawpos++;
- #endif
- }
- else
- {
- data[i*2]=data[i*2+1] = *(short*)rawpos;
- rawpos+=2;
- #ifdef HALF_RATE_AUDIO
- rawpos+=2;
- #endif
- }
- }
- else
- {
- if (width==1)
- {
- data[i*2] = (*(signed char*)rawpos)*256.0f;
- rawpos++;
- data[i*2+1] = (*(signed char*)rawpos)*256.0f;
- rawpos++;
- #ifdef HALF_RATE_AUDIO
- rawpos+=2;
- #endif
- }
- else
- {
- data[i*2] = *(short*)rawpos;
- rawpos+=2;
- data[i*2+1] = *(short*)rawpos;
- rawpos+=2;
- #ifdef HALF_RATE_AUDIO
- rawpos+=4;
- #endif
- }
- }
- }
- delete [] rawdata;
- return data;
- }
- #endif
- // Setting Audio Driver
- void BzfMedia::setDriver(std::string)
- {
- }
- // Setting Audio Device
- void BzfMedia::setDevice(std::string)
- {
- }
- void BzfMedia::audioDriver(std::string& driverName)
- {
- driverName = "";
- }
- // Local Variables: ***
- // mode: C++ ***
- // tab-width: 4 ***
- // c-basic-offset: 4 ***
- // indent-tabs-mode: nil ***
- // End: ***
- // ex: shiftwidth=4 tabstop=4
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement