git repos / blockattack-game

blame: source/code/sago/SagoDataHolder.cpp

normal view · raw

82da8a1c sago007 2015-12-19 18:00 1
/*
82da8a1c sago007 2015-12-19 18:00 2
  Copyright (c) 2015 Poul Sander
82da8a1c sago007 2015-12-19 18:00 3
82da8a1c sago007 2015-12-19 18:00 4
  Permission is hereby granted, free of charge, to any person
82da8a1c sago007 2015-12-19 18:00 5
  obtaining a copy of this software and associated documentation files
82da8a1c sago007 2015-12-19 18:00 6
  (the "Software"), to deal in the Software without restriction,
82da8a1c sago007 2015-12-19 18:00 7
  including without limitation the rights to use, copy, modify, merge,
82da8a1c sago007 2015-12-19 18:00 8
  publish, distribute, sublicense, and/or sell copies of the Software,
82da8a1c sago007 2015-12-19 18:00 9
  and to permit persons to whom the Software is furnished to do so,
82da8a1c sago007 2015-12-19 18:00 10
  subject to the following conditions:
82da8a1c sago007 2015-12-19 18:00 11
82da8a1c sago007 2015-12-19 18:00 12
  The above copyright notice and this permission notice shall be
82da8a1c sago007 2015-12-19 18:00 13
  included in all copies or substantial portions of the Software.
82da8a1c sago007 2015-12-19 18:00 14
82da8a1c sago007 2015-12-19 18:00 15
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
82da8a1c sago007 2015-12-19 18:00 16
  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
82da8a1c sago007 2015-12-19 18:00 17
  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
82da8a1c sago007 2015-12-19 18:00 18
  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
82da8a1c sago007 2015-12-19 18:00 19
  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
82da8a1c sago007 2015-12-19 18:00 20
  ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
82da8a1c sago007 2015-12-19 18:00 21
  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
82da8a1c sago007 2015-12-19 18:00 22
  SOFTWARE.
82da8a1c sago007 2015-12-19 18:00 23
*/
82da8a1c sago007 2015-12-19 18:00 24
82da8a1c sago007 2015-12-19 18:00 25
#include "SagoDataHolder.hpp"
82da8a1c sago007 2015-12-19 18:00 26
#include <iostream>
82da8a1c sago007 2015-12-19 18:00 27
#include <mutex>
82da8a1c sago007 2015-12-19 18:00 28
#include <map>
82da8a1c sago007 2015-12-19 18:00 29
#include <vector>
82da8a1c sago007 2015-12-19 18:00 30
#include <physfs.h>
82da8a1c sago007 2015-12-19 18:00 31
#include <memory>
b81f58ad sago007 2015-12-25 22:48 32
#include <SDL_mixer.h>
c3fc09e9 sago007 2016-01-22 18:31 33
#include "SagoMiscSdl2.hpp"
82da8a1c sago007 2015-12-19 18:00 34
82da8a1c sago007 2015-12-19 18:00 35
namespace sago {
82da8a1c sago007 2015-12-19 18:00 36
82da8a1c sago007 2015-12-19 18:00 37
struct SagoDataHolder::SagoDataHolderData {
82da8a1c sago007 2015-12-19 18:00 38
	std::map<std::string, SDL_Texture*> textures;
82da8a1c sago007 2015-12-19 18:00 39
	std::map<std::string, std::map<int, TTF_Font*> > fonts;  //font, ptsize
82da8a1c sago007 2015-12-19 18:00 40
	std::map<std::string, Mix_Music*> music;
82da8a1c sago007 2015-12-19 18:00 41
	std::map<std::string, Mix_Chunk*> sounds;
82da8a1c sago007 2015-12-19 18:00 42
	std::vector<SDL_RWops*> rwOpsToFree;
82da8a1c sago007 2015-12-19 18:00 43
	std::vector<std::unique_ptr<char[]>> dataToFree;
e297a2e8 sago007 2016-01-21 18:07 44
	bool verbose = false;
82da8a1c sago007 2015-12-19 18:00 45
	SDL_Renderer* renderer = nullptr;
82da8a1c sago007 2015-12-19 18:00 46
};
82da8a1c sago007 2015-12-19 18:00 47
e297a2e8 sago007 2016-01-21 18:07 48
static void printFileWeLoad(const std::string& value) {
161a010c sago007 2016-05-06 14:00 49
	std::cout << "Loading " << value << "\n";
e297a2e8 sago007 2016-01-21 18:07 50
}
e297a2e8 sago007 2016-01-21 18:07 51
82da8a1c sago007 2015-12-19 18:00 52
SagoDataHolder::SagoDataHolder(SDL_Renderer* renderer) {
82da8a1c sago007 2015-12-19 18:00 53
	data = new SagoDataHolderData();
82da8a1c sago007 2015-12-19 18:00 54
	data->renderer = renderer;
82da8a1c sago007 2015-12-19 18:00 55
}
82da8a1c sago007 2015-12-19 18:00 56
82da8a1c sago007 2015-12-19 18:00 57
SagoDataHolder::~SagoDataHolder() {
82da8a1c sago007 2015-12-19 18:00 58
	for (auto& item : data->textures) {
82da8a1c sago007 2015-12-19 18:00 59
		SDL_DestroyTexture(item.second);
82da8a1c sago007 2015-12-19 18:00 60
	}
82da8a1c sago007 2015-12-19 18:00 61
	for (auto& item : data->music) {
82da8a1c sago007 2015-12-19 18:00 62
		Mix_FreeMusic(item.second);
82da8a1c sago007 2015-12-19 18:00 63
	}
82da8a1c sago007 2015-12-19 18:00 64
	for (auto& item : data->sounds) {
82da8a1c sago007 2015-12-19 18:00 65
		Mix_FreeChunk(item.second);
82da8a1c sago007 2015-12-19 18:00 66
	}
82da8a1c sago007 2015-12-19 18:00 67
	for (auto& item : data->fonts) {
82da8a1c sago007 2015-12-19 18:00 68
		for (auto& item2 : item.second) {
82da8a1c sago007 2015-12-19 18:00 69
			TTF_CloseFont(item2.second);
82da8a1c sago007 2015-12-19 18:00 70
		}
82da8a1c sago007 2015-12-19 18:00 71
	}
82da8a1c sago007 2015-12-19 18:00 72
	for (auto& item : data->rwOpsToFree) {
82da8a1c sago007 2015-12-19 18:00 73
		SDL_FreeRW(item);
82da8a1c sago007 2015-12-19 18:00 74
	}
82da8a1c sago007 2015-12-19 18:00 75
	delete data;
82da8a1c sago007 2015-12-19 18:00 76
}
82da8a1c sago007 2015-12-19 18:00 77
82da8a1c sago007 2015-12-19 18:00 78
SDL_Texture* SagoDataHolder::getTexturePtr(const std::string& textureName) const {
82da8a1c sago007 2015-12-19 18:00 79
	SDL_Texture* ret = data->textures[textureName];
82da8a1c sago007 2015-12-19 18:00 80
	if (ret) {
82da8a1c sago007 2015-12-19 18:00 81
		return ret;
82da8a1c sago007 2015-12-19 18:00 82
	}
82da8a1c sago007 2015-12-19 18:00 83
	std::string path = "textures/"+textureName+".png";
e297a2e8 sago007 2016-01-21 18:07 84
	if (data->verbose) { 
e297a2e8 sago007 2016-01-21 18:07 85
		printFileWeLoad(path);
e297a2e8 sago007 2016-01-21 18:07 86
	}
82da8a1c sago007 2015-12-19 18:00 87
	if (!PHYSFS_exists(path.c_str())) {
c3fc09e9 sago007 2016-01-22 18:31 88
		sago::SagoFatalErrorF("getTextureFailed - Texture does not exist: %s", path.c_str());
82da8a1c sago007 2015-12-19 18:00 89
	}
82da8a1c sago007 2015-12-19 18:00 90
	PHYSFS_file* myfile = PHYSFS_openRead(path.c_str());
82da8a1c sago007 2015-12-19 18:00 91
	unsigned int m_size = PHYSFS_fileLength(myfile);
82da8a1c sago007 2015-12-19 18:00 92
	std::unique_ptr<char[]> m_data(new char[m_size]);
82da8a1c sago007 2015-12-19 18:00 93
	int length_read = PHYSFS_read (myfile, m_data.get(), 1, m_size);
82da8a1c sago007 2015-12-19 18:00 94
	if (length_read != (int)m_size) {
82da8a1c sago007 2015-12-19 18:00 95
		PHYSFS_close(myfile);
161a010c sago007 2016-05-06 14:00 96
		std::cerr << "Error: Curropt data file: " << path << "\n";
82da8a1c sago007 2015-12-19 18:00 97
		return ret;
82da8a1c sago007 2015-12-19 18:00 98
	}
82da8a1c sago007 2015-12-19 18:00 99
	PHYSFS_close(myfile);
82da8a1c sago007 2015-12-19 18:00 100
	SDL_RWops* rw = SDL_RWFromMem (m_data.get(), m_size);
82da8a1c sago007 2015-12-19 18:00 101
	//The above might fail an return null.
82da8a1c sago007 2015-12-19 18:00 102
	if (!rw) {
82da8a1c sago007 2015-12-19 18:00 103
		PHYSFS_close(myfile);
161a010c sago007 2016-05-06 14:00 104
		std::cerr << "Error. Curropt data file!\n";
82da8a1c sago007 2015-12-19 18:00 105
		return NULL;
82da8a1c sago007 2015-12-19 18:00 106
	}
82da8a1c sago007 2015-12-19 18:00 107
	SDL_Surface* surface = IMG_Load_RW(rw,true);
82da8a1c sago007 2015-12-19 18:00 108
82da8a1c sago007 2015-12-19 18:00 109
	ret = SDL_CreateTextureFromSurface(data->renderer, surface);
82da8a1c sago007 2015-12-19 18:00 110
82da8a1c sago007 2015-12-19 18:00 111
	if (!ret) {
161a010c sago007 2016-05-06 14:00 112
		std::cerr << "getTextureFailed to load " << path << "\n";
82da8a1c sago007 2015-12-19 18:00 113
	}
82da8a1c sago007 2015-12-19 18:00 114
	SDL_FreeSurface(surface);
82da8a1c sago007 2015-12-19 18:00 115
	data->textures[textureName] = ret;
82da8a1c sago007 2015-12-19 18:00 116
	return ret;
82da8a1c sago007 2015-12-19 18:00 117
}
82da8a1c sago007 2015-12-19 18:00 118
82da8a1c sago007 2015-12-19 18:00 119
TTF_Font* SagoDataHolder::getFontPtr(const std::string& fontName, int ptsize) const {
82da8a1c sago007 2015-12-19 18:00 120
	TTF_Font* ret = data->fonts[fontName][ptsize];
82da8a1c sago007 2015-12-19 18:00 121
	if (ret) {
82da8a1c sago007 2015-12-19 18:00 122
		return ret;
82da8a1c sago007 2015-12-19 18:00 123
	}
82da8a1c sago007 2015-12-19 18:00 124
	std::string path = "fonts/"+fontName+".ttf";
e297a2e8 sago007 2016-01-21 18:07 125
	if (data->verbose) { 
e297a2e8 sago007 2016-01-21 18:07 126
		printFileWeLoad(path);
e297a2e8 sago007 2016-01-21 18:07 127
	}
82da8a1c sago007 2015-12-19 18:00 128
	if (!PHYSFS_exists(path.c_str())) {
161a010c sago007 2016-05-06 14:00 129
		std::cerr << "getFontPtr - Font does not exists: " << path << "\n";
82da8a1c sago007 2015-12-19 18:00 130
		return ret;
82da8a1c sago007 2015-12-19 18:00 131
	}
82da8a1c sago007 2015-12-19 18:00 132
	PHYSFS_file* myfile = PHYSFS_openRead(path.c_str());
82da8a1c sago007 2015-12-19 18:00 133
	unsigned int m_size = PHYSFS_fileLength(myfile);
82da8a1c sago007 2015-12-19 18:00 134
	std::unique_ptr<char[]> m_data(new char[m_size]);
82da8a1c sago007 2015-12-19 18:00 135
	int length_read = PHYSFS_read (myfile, m_data.get(), 1, m_size);
82da8a1c sago007 2015-12-19 18:00 136
	if (length_read != (int)m_size) {
82da8a1c sago007 2015-12-19 18:00 137
		PHYSFS_close(myfile);
161a010c sago007 2016-05-06 14:00 138
		std::cerr << "Error: Curropt data file: " << path << "\n";
82da8a1c sago007 2015-12-19 18:00 139
		return ret;
82da8a1c sago007 2015-12-19 18:00 140
	}
82da8a1c sago007 2015-12-19 18:00 141
	PHYSFS_close(myfile);
82da8a1c sago007 2015-12-19 18:00 142
82da8a1c sago007 2015-12-19 18:00 143
	SDL_RWops* rw = SDL_RWFromMem (m_data.get(), m_size);
82da8a1c sago007 2015-12-19 18:00 144
82da8a1c sago007 2015-12-19 18:00 145
	//The above might fail an return null.
82da8a1c sago007 2015-12-19 18:00 146
	if (!rw) {
82da8a1c sago007 2015-12-19 18:00 147
		PHYSFS_close(myfile);
161a010c sago007 2016-05-06 14:00 148
		std::cerr << "Error: Curropt data file!\n";
82da8a1c sago007 2015-12-19 18:00 149
		return ret;
82da8a1c sago007 2015-12-19 18:00 150
	}
82da8a1c sago007 2015-12-19 18:00 151
82da8a1c sago007 2015-12-19 18:00 152
	ret = TTF_OpenFontRW(rw, SDL_FALSE, ptsize);
82da8a1c sago007 2015-12-19 18:00 153
	if (!ret) {
161a010c sago007 2016-05-06 14:00 154
		std::cerr << "Error openening font: " << fontName << " because: " << TTF_GetError() << "\n";
82da8a1c sago007 2015-12-19 18:00 155
	}
82da8a1c sago007 2015-12-19 18:00 156
	data->fonts[fontName][ptsize] = ret;
82da8a1c sago007 2015-12-19 18:00 157
	data->dataToFree.push_back(std::move(m_data));
82da8a1c sago007 2015-12-19 18:00 158
	data->rwOpsToFree.push_back(rw);
82da8a1c sago007 2015-12-19 18:00 159
	return ret;
82da8a1c sago007 2015-12-19 18:00 160
}
82da8a1c sago007 2015-12-19 18:00 161
82da8a1c sago007 2015-12-19 18:00 162
Mix_Music* SagoDataHolder::getMusicPtr(const std::string& musicName) const {
82da8a1c sago007 2015-12-19 18:00 163
	Mix_Music* ret = data->music[musicName];
82da8a1c sago007 2015-12-19 18:00 164
	if (ret) {
82da8a1c sago007 2015-12-19 18:00 165
		return ret;
82da8a1c sago007 2015-12-19 18:00 166
	}
82da8a1c sago007 2015-12-19 18:00 167
	std::string path = "music/"+musicName+".ogg";
e297a2e8 sago007 2016-01-21 18:07 168
	if (data->verbose) { 
e297a2e8 sago007 2016-01-21 18:07 169
		printFileWeLoad(path);
e297a2e8 sago007 2016-01-21 18:07 170
	}
82da8a1c sago007 2015-12-19 18:00 171
	if (!PHYSFS_exists(path.c_str())) {
161a010c sago007 2016-05-06 14:00 172
		std::cerr << "getMusicPtr - Music file does not exists: " << path << "\n";
82da8a1c sago007 2015-12-19 18:00 173
		return ret;
82da8a1c sago007 2015-12-19 18:00 174
	}
82da8a1c sago007 2015-12-19 18:00 175
	PHYSFS_file* myfile = PHYSFS_openRead(path.c_str());
82da8a1c sago007 2015-12-19 18:00 176
	unsigned int m_size = PHYSFS_fileLength(myfile);
82da8a1c sago007 2015-12-19 18:00 177
	std::unique_ptr<char[]> m_data(new char[m_size]);
82da8a1c sago007 2015-12-19 18:00 178
	int length_read = PHYSFS_read (myfile, m_data.get(), 1, m_size);
82da8a1c sago007 2015-12-19 18:00 179
	if (length_read != (int)m_size) {
82da8a1c sago007 2015-12-19 18:00 180
		PHYSFS_close(myfile);
161a010c sago007 2016-05-06 14:00 181
		std::cerr << "Error: Curropt data file: " << path << "\n";
82da8a1c sago007 2015-12-19 18:00 182
		return ret;
82da8a1c sago007 2015-12-19 18:00 183
	}
82da8a1c sago007 2015-12-19 18:00 184
	PHYSFS_close(myfile);
82da8a1c sago007 2015-12-19 18:00 185
	SDL_RWops* rw = SDL_RWFromMem (m_data.get(), m_size);
82da8a1c sago007 2015-12-19 18:00 186
82da8a1c sago007 2015-12-19 18:00 187
	//The above might fail an return null.
82da8a1c sago007 2015-12-19 18:00 188
	if (!rw) {
82da8a1c sago007 2015-12-19 18:00 189
		PHYSFS_close(myfile);
161a010c sago007 2016-05-06 14:00 190
		std::cerr << "Error. Curropt data file!\n";
82da8a1c sago007 2015-12-19 18:00 191
		return NULL;
82da8a1c sago007 2015-12-19 18:00 192
	}
82da8a1c sago007 2015-12-19 18:00 193
82da8a1c sago007 2015-12-19 18:00 194
	ret = Mix_LoadMUS_RW(rw, SDL_TRUE);  //SDL_TRUE causes rw to be freed
82da8a1c sago007 2015-12-19 18:00 195
82da8a1c sago007 2015-12-19 18:00 196
	if (!ret) {
161a010c sago007 2016-05-06 14:00 197
		std::cerr << "getMusicPtr to load " << path << " because: " << Mix_GetError() << "\n";
82da8a1c sago007 2015-12-19 18:00 198
	}
82da8a1c sago007 2015-12-19 18:00 199
	data->music[musicName] = ret;
344e2b89 sago007 2016-01-18 21:33 200
	data->dataToFree.push_back(std::move(m_data));
82da8a1c sago007 2015-12-19 18:00 201
	return ret;
82da8a1c sago007 2015-12-19 18:00 202
}
82da8a1c sago007 2015-12-19 18:00 203
82da8a1c sago007 2015-12-19 18:00 204
82da8a1c sago007 2015-12-19 18:00 205
Mix_Chunk* SagoDataHolder::getSoundPtr(const std::string& soundName) const {
82da8a1c sago007 2015-12-19 18:00 206
	Mix_Chunk* ret = data->sounds[soundName];
82da8a1c sago007 2015-12-19 18:00 207
	if (ret) {
82da8a1c sago007 2015-12-19 18:00 208
		return ret;
82da8a1c sago007 2015-12-19 18:00 209
	}
82da8a1c sago007 2015-12-19 18:00 210
	std::string path = "sounds/"+soundName+".ogg";
e297a2e8 sago007 2016-01-21 18:07 211
	if (data->verbose) { 
e297a2e8 sago007 2016-01-21 18:07 212
		printFileWeLoad(path);
e297a2e8 sago007 2016-01-21 18:07 213
	}
82da8a1c sago007 2015-12-19 18:00 214
	if (!PHYSFS_exists(path.c_str())) {
161a010c sago007 2016-05-06 14:00 215
		std::cerr << "getSoundPtr - Sound file does not exists: " << path << "\n";
82da8a1c sago007 2015-12-19 18:00 216
		return ret;
82da8a1c sago007 2015-12-19 18:00 217
	}
82da8a1c sago007 2015-12-19 18:00 218
	PHYSFS_file* myfile = PHYSFS_openRead(path.c_str());
82da8a1c sago007 2015-12-19 18:00 219
	unsigned int m_size = PHYSFS_fileLength(myfile);
82da8a1c sago007 2015-12-19 18:00 220
	std::unique_ptr<char[]> m_data(new char[m_size]);
82da8a1c sago007 2015-12-19 18:00 221
	int length_read = PHYSFS_read (myfile, m_data.get(), 1, m_size);
82da8a1c sago007 2015-12-19 18:00 222
	if (length_read != (int)m_size) {
82da8a1c sago007 2015-12-19 18:00 223
		PHYSFS_close(myfile);
161a010c sago007 2016-05-06 14:00 224
		std::cerr << "Error: Curropt data file: " << path << "\n";
82da8a1c sago007 2015-12-19 18:00 225
		return ret;
82da8a1c sago007 2015-12-19 18:00 226
	}
82da8a1c sago007 2015-12-19 18:00 227
	PHYSFS_close(myfile);
82da8a1c sago007 2015-12-19 18:00 228
	SDL_RWops* rw = SDL_RWFromMem (m_data.get(), m_size);
82da8a1c sago007 2015-12-19 18:00 229
82da8a1c sago007 2015-12-19 18:00 230
	//The above might fail an return null.
82da8a1c sago007 2015-12-19 18:00 231
	if (!rw) {
82da8a1c sago007 2015-12-19 18:00 232
		PHYSFS_close(myfile);
161a010c sago007 2016-05-06 14:00 233
		std::cerr << "Error. Curropt data file!\n";
82da8a1c sago007 2015-12-19 18:00 234
		return NULL;
82da8a1c sago007 2015-12-19 18:00 235
	}
82da8a1c sago007 2015-12-19 18:00 236
82da8a1c sago007 2015-12-19 18:00 237
	ret = Mix_LoadWAV_RW(rw, SDL_TRUE);
82da8a1c sago007 2015-12-19 18:00 238
	data->sounds[soundName] = ret;
344e2b89 sago007 2016-01-18 21:33 239
	data->dataToFree.push_back(std::move(m_data));
82da8a1c sago007 2015-12-19 18:00 240
	return ret;
82da8a1c sago007 2015-12-19 18:00 241
}
82da8a1c sago007 2015-12-19 18:00 242
e297a2e8 sago007 2016-01-21 18:07 243
void SagoDataHolder::setVerbose(bool value) {
e297a2e8 sago007 2016-01-21 18:07 244
	data->verbose = value;
e297a2e8 sago007 2016-01-21 18:07 245
}
e297a2e8 sago007 2016-01-21 18:07 246
82da8a1c sago007 2015-12-19 18:00 247
} //name space sago
1970-01-01 00:00 248