Unverified Commit e19269c2 authored by RobLoach's avatar RobLoach Committed by GitHub
Browse files

0.20.1 (#238)

### Fixed
- Better memory usage
- Compilation warnings
parent 1573acca
[submodule "vendor/sdl-libretro"]
path = vendor/sdl-libretro
url = https://github.com/libretro/sdl-libretro.git
ignore = dirty
[submodule "vendor/libretro-common"]
path = vendor/libretro-common
url = https://github.com/libretro/libretro-common.git
......@@ -29,6 +30,7 @@
[submodule "vendor/libretro-deps"]
path = vendor/libretro-deps
url = https://github.com/libretro/libretro-deps.git
ignore = dirty
[submodule "vendor/styleguide"]
path = vendor/styleguide
url = https://github.com/google/styleguide.git
......
......@@ -4,6 +4,11 @@ All notable changes to [ChaiLove](https://github.com/RobLoach/ChaiLove) will be
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
## 0.20.1 - 2018-04-24
### Fixed
- Better memory usage
- Compilation warnings
## 0.20.0 - 2018-04-22
### Added
- No Game demo when ChaiLove is loaded without content
......
......@@ -35,7 +35,7 @@ clean:
vendor/libretro-common/include/libretro.h:
@git submodule update --init --recursive
test: unittest cpplint
test: unittest unittest-chailove cpplint
@echo "Run the testing suite by using:\n\n retroarch -L $(TARGET) test/main.chai\n\n"
vendor/noarch/noarch: vendor/libretro-common/include/libretro.h
......@@ -44,6 +44,9 @@ vendor/noarch/noarch: vendor/libretro-common/include/libretro.h
unittest: vendor/noarch/noarch all
vendor/noarch/noarch $(CORE_DIR)/$(TARGET) test/unittests/main.chai
unittest-chailove: vendor/noarch/noarch all
vendor/noarch/noarch $(CORE_DIR)/$(TARGET) test/test.chailove
examples: all
@retroarch -L $(TARGET) examples/benchmark/main.chai
......
......@@ -8,7 +8,7 @@ ChaiLove is an awesome framework you can use to make 2D games in [ChaiScript](ht
[![Floppy Bird Gameplay](docs/screenshot.png)](https://www.youtube.com/watch?v=RLVwTh6qDFI&hd=1)
## Games
## Gallery
- [Floppy Bird](https://github.com/RobLoach/ChaiLove-FloppyBird)
- [Nyan Cat](https://github.com/RobLoach/ChaiLove-NyanCat)
......@@ -38,6 +38,7 @@ The [ChaiLove API](https://rawgit.com/libretro/libretro-chailove/docs/) is rough
``` lua
global logo
global x = 10.0f
def load() {
logo = love.graphics.newImage("logo.png")
......@@ -45,11 +46,11 @@ def load() {
def draw() {
love.graphics.print("Hello World!", 400, 300)
love.graphics.draw(logo, 100, 100)
love.graphics.draw(logo, x, 100)
}
def update(delta) {
// Change something on the screen.
def update(dt) {
x = x + 20.0f * dt
}
```
......
......@@ -23,7 +23,7 @@ PROJECT_NAME = "ChaiLove API"
# This could be handy for archiving the generated documentation or
# if some version control system is used.
PROJECT_NUMBER = "0.20.0"
PROJECT_NUMBER = "0.20.1"
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
# base path where the generated documentation will be put.
......
......@@ -10,14 +10,19 @@ retro_input_poll_t ChaiLove::input_poll_cb = NULL;
retro_environment_t ChaiLove::environ_cb = NULL;
void ChaiLove::destroy() {
std::cout << "[ChaiLove] Attempting to destroy ChaiLove" << std::endl;
if (hasInstance()) {
std::cout << "[ChaiLove] Destroying ChaiLove" << std::endl;
m_instance->quit();
delete m_instance;
m_instance = NULL;
}
std::cout << "[ChaiLove] Destroyed ChaiLove" << std::endl;
}
ChaiLove* ChaiLove::getInstance() {
if (!hasInstance()) {
std::cout << "[ChaiLove] Initializing ChaiLove" << std::endl;
m_instance = new ChaiLove;
}
return m_instance;
......@@ -32,14 +37,18 @@ ChaiLove::~ChaiLove() {
}
void ChaiLove::quit(void) {
// Quit all the subsystems.
event.m_shouldclose = true;
// Destroy all the subsystems.
if (script) {
delete script;
script = NULL;
}
joystick.unload();
font.unload();
image.unload();
sound.unload();
filesystem.unload();
window.unload();
std::cout << "[ChaiLove] Unloaded ChaiLove" << std::endl;
}
bool ChaiLove::load(const std::string& file) {
......@@ -162,7 +171,9 @@ void ChaiLove::update() {
keyboard.update();
// Step forward the timer, and update the game.
script->update(timer.getDelta());
if (script != NULL) {
script->update(timer.getDelta());
}
}
/**
......@@ -171,7 +182,9 @@ void ChaiLove::update() {
void ChaiLove::reset() {
// Tell the script that we are to reset the game.
std::cout << "[ChaiLove] Reset" << std::endl;
script->reset();
if (script != NULL) {
script->reset();
}
}
/**
......@@ -186,7 +199,9 @@ void ChaiLove::draw() {
graphics.clear();
// Render the game.
script->draw();
if (script != NULL) {
script->draw();
}
// Render the in-game console.
console.draw();
......@@ -202,12 +217,18 @@ void ChaiLove::draw() {
* Tell the script to return a string representing the game data.
*/
std::string ChaiLove::savestate() {
return script->savestate();
if (script != NULL) {
return script->savestate();
}
return "";
}
/**
* Ask the script to load the given string.
*/
bool ChaiLove::loadstate(const std::string& data) {
return script->loadstate(data);
if (script != NULL) {
return script->loadstate(data);
}
return false;
}
......@@ -36,8 +36,8 @@
#define CHAILOVE_VERSION_MAJOR 0
#define CHAILOVE_VERSION_MINOR 20
#define CHAILOVE_VERSION_PATCH 0
#define CHAILOVE_VERSION_STRING "0.20.0"
#define CHAILOVE_VERSION_PATCH 1
#define CHAILOVE_VERSION_STRING "0.20.1"
#include "SDL.h"
#include "libretro.h"
......
......@@ -228,6 +228,7 @@ void retro_get_system_info(struct retro_system_info *info) {
* libretro callback; Set the audio/video settings.
*/
void retro_get_system_av_info(struct retro_system_av_info *info) {
std::cout << "[ChaiLove] retro_get_system_av_info" << std::endl;
if (!ChaiLove::hasInstance()) {
return;
}
......@@ -251,6 +252,7 @@ void retro_get_system_av_info(struct retro_system_av_info *info) {
}
void retro_set_controller_port_device(unsigned port, unsigned device) {
std::cout << "[ChaiLove] retro_set_controller_port_device" << std::endl;
(void)port;
(void)device;
}
......@@ -270,6 +272,7 @@ bool retro_serialize(void *data, size_t size) {
if (!ChaiLove::hasInstance()) {
return false;
}
std::cout << "[ChaiLove] retro_serialize" << std::endl;
// Ask ChaiLove for save data.
ChaiLove* app = ChaiLove::getInstance();
......@@ -293,6 +296,7 @@ bool retro_unserialize(const void *data, size_t size) {
if (!ChaiLove::hasInstance()) {
return false;
}
std::cout << "[ChaiLove] retro_unserialize" << std::endl;
// Create a string stream from the data.
std::stringstream ss(std::string(
......@@ -342,6 +346,7 @@ void frame_time_cb(retro_usec_t usec) {
* libretro callback; Load the given game.
*/
bool retro_load_game(const struct retro_game_info *info) {
std::cout << "[ChaiLove] retro_load_game" << std::endl;
// Update the core options.
update_variables();
......@@ -368,6 +373,7 @@ bool retro_load_game(const struct retro_game_info *info) {
* libretro callback; Loads the given special game.
*/
bool retro_load_game_special(unsigned game_type, const struct retro_game_info *info, size_t num_info) {
std::cout << "[ChaiLove] retro_load_game_special" << std::endl;
return retro_load_game(info);
}
......@@ -442,8 +448,6 @@ void retro_init(void) {
if (!ChaiLove::environ_cb(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &fmt)) {
std::cout << "[ChaiLove] Pixel format XRGB8888 not supported by platform, cannot use." << std::endl;
}
ChaiLove::getInstance();
}
/**
......@@ -458,6 +462,7 @@ void retro_deinit(void) {
* libretro callback; The frontend requested to reset the game.
*/
void retro_reset(void) {
std::cout << "[ChaiLove] retro_reset()" << std::endl;
if (ChaiLove::hasInstance()) {
ChaiLove::getInstance()->reset();
}
......@@ -467,14 +472,14 @@ void retro_reset(void) {
* libretro callback; Run a game loop in the core.
*/
void retro_run(void) {
// Ensure there is a game running.
if (!ChaiLove::hasInstance()) {
return;
}
// Check if the game should be closed.
ChaiLove* app = ChaiLove::getInstance();
if (app->event.m_shouldclose) {
ChaiLove::destroy();
ChaiLove::environ_cb(RETRO_ENVIRONMENT_SHUTDOWN, 0);
return;
}
......@@ -486,4 +491,9 @@ void retro_run(void) {
// Copy the video buffer to the screen.
video_cb(app->videoBuffer, app->config.window.width, app->config.window.height, app->config.window.width << 2);
// See if the game requested to close itself.
if (app->event.m_shouldclose) {
ChaiLove::environ_cb(RETRO_ENVIRONMENT_SHUTDOWN, 0);
}
}
......@@ -19,7 +19,7 @@ SoundData::SoundData(const std::string& filename) {
int result = PHYSFS_readBytes(file, &sndta.head, sizeof(uint8_t) * WAV_HEADER_SIZE);
if (result < 0) {
std::cout << "[ChaiLove] Failed to load SoundData " << filename << PHYSFS_getLastError() << std::endl;
std::cout << "[ChaiLove] Failed to load SoundData " << filename << app->filesystem.getLastError() << std::endl;
return;
}
......@@ -86,7 +86,7 @@ bool SoundData::stop() {
}
bool SoundData::isLoaded() {
return sndta.fp != NULL;
return sndta.fp != NULL && ChaiLove::hasInstance();
}
bool SoundData::isPlaying() {
......
......@@ -19,7 +19,7 @@ namespace love {
*
* @code
* def conf(t) {
* t.version = "0.20.0" // Version of ChaiLove
* t.version = "0.20.1" // Version of ChaiLove
* t.identity = "mygame" // Machine name of your game
* t.window.title = "My Game" // Human-readable name
* t.window.width = 1024 // Game width
......
......@@ -10,16 +10,20 @@ void event::quit() {
}
void event::update() {
// Poll all the inputs.
ChaiLove::input_poll_cb();
if (ChaiLove::hasInstance()) {
// Poll all the inputs.
ChaiLove::input_poll_cb();
// Poll all SDL events.
while (SDL_PollEvent(&sdlEvent)) {
switch (sdlEvent.type) {
case SDL_QUIT:
quit();
break;
// TODO(RobLoach): Is polling the SDL events required?
/*
while (SDL_PollEvent(&sdlEvent)) {
switch (sdlEvent.type) {
case SDL_QUIT:
quit();
break;
}
}
*/
}
}
......
......@@ -16,10 +16,12 @@ namespace love {
* Initialize the file system.
*/
bool filesystem::init(const std::string& file) {
// Initialize PhysFS
if (PHYSFS_init(NULL) == 0) {
std::cout << "[ChaiLove] [filesystem] Error loading PhysFS - " << PHYSFS_getLastError() << std::endl;
return false;
if (PHYSFS_isInit() == 0) {
// Initialize PhysFS
if (PHYSFS_init(NULL) == 0) {
std::cout << "[ChaiLove] [filesystem] Error loading PhysFS - " << getLastError() << std::endl;
return false;
}
}
// Check if we are simply running ChaiLove.
......@@ -71,12 +73,7 @@ PHYSFS_sint64 filesystem::getSize(PHYSFS_File* file) {
if (file) {
size = PHYSFS_fileLength(file);
if (size < 0) {
const char* errorChar = PHYSFS_getLastError();
std::string physErr("");
if (errorChar != NULL) {
physErr = errorChar;
}
std::cout << "[ChaiLove] [filesystem] Could not get size of file " << physErr << std::endl;
std::cout << "[ChaiLove] [filesystem] Could not get size of file " << getLastError() << std::endl;
return -1;
}
} else {
......@@ -86,26 +83,22 @@ PHYSFS_sint64 filesystem::getSize(PHYSFS_File* file) {
}
bool filesystem::unload() {
PHYSFS_deinit();
if (PHYSFS_isInit() != 0) {
PHYSFS_deinit();
}
return true;
}
SDL_RWops* filesystem::openRW(const std::string& filename) {
SDL_RWops* rw = PHYSFSRWOPS_openRead(filename.c_str());
if (rw == NULL) {
const char* errorChar = PHYSFS_getLastError();
std::string physErr("");
if (errorChar != NULL) {
physErr = errorChar;
}
errorChar = SDL_GetError();
const char* errorChar = SDL_GetError();
std::string sdlErr("");
if (errorChar != NULL) {
sdlErr = errorChar;
}
std::cout << "[ChaiLove] [filesystem] Error loading file " << filename << physErr << sdlErr << std::endl;
std::cout << "[ChaiLove] [filesystem] Error loading file " << filename << getLastError() << sdlErr << std::endl;
}
return rw;
}
......@@ -113,12 +106,7 @@ SDL_RWops* filesystem::openRW(const std::string& filename) {
PHYSFS_file* filesystem::openFile(const std::string& filename) {
PHYSFS_file* myfile = PHYSFS_openRead(filename.c_str());
if (myfile == NULL) {
const char* errorChar = PHYSFS_getLastError();
std::string physErr("");
if (errorChar != NULL) {
physErr = errorChar;
}
std::cout << "[ChaiLove] [filesystem] Error opening file " << filename << physErr << std::endl;
std::cout << "[ChaiLove] [filesystem] Error opening file " << filename << getLastError() << std::endl;
return NULL;
}
return myfile;
......@@ -136,20 +124,14 @@ char* filesystem::readChar(const std::string& filename) {
output = new char[file_size + 1];
int length_read = PHYSFS_readBytes(myfile, output, file_size);
if (length_read != file_size) {
const char* errorChar = PHYSFS_getLastError();
std::string physErr("");
if (errorChar != NULL) {
physErr = errorChar;
}
std::cout << "[ChaiLove] [filesystem] File System error while reading from file " << filename << physErr << std::endl;
std::cout << "[ChaiLove] [filesystem] File System error while reading from file " << filename << getLastError() << std::endl;
output = NULL;
} else {
// Make sure there is a null terminating character at the end of the string.
output[file_size] = '\0';
}
} else {
std::string physErr = PHYSFS_getLastError();
std::cout << "[ChaiLove] [filesystem] Error getting filesize of " << filename << physErr << std::endl;
std::cout << "[ChaiLove] [filesystem] Error getting filesize of " << filename << getLastError() << std::endl;
}
PHYSFS_close(myfile);
......@@ -275,4 +257,12 @@ FileInfo filesystem::getInfo(const std::string& path) {
return fileInfo;
}
std::string filesystem::getLastError() {
const char* charErr = PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode());
if (charErr) {
return std::string(charErr);
}
return "";
}
} // namespace love
......@@ -118,6 +118,8 @@ class filesystem {
*/
std::vector<std::string> lines(const std::string& filename, const std::string& delimiter);
std::vector<std::string> lines(const std::string& filename);
std::string getLastError();
};
} // namespace love
......
......@@ -23,14 +23,15 @@ graphics::graphics() {
}
SDL_Surface* graphics::getScreen() {
return ChaiLove::getInstance()->screen;
if (ChaiLove::hasInstance()) {
return ChaiLove::getInstance()->screen;
}
return NULL;
}
bool graphics::load() {
ChaiLove* app = ChaiLove::getInstance();
// Enable alpha blending.
if (app->config.options["alphablending"]) {
if (ChaiLove::getInstance()->config.options["alphablending"]) {
if (SDL_SetAlpha(getScreen(), SDL_SRCALPHA, 0) == -1) {
std::cout << "[ChaiLove] Enabling alpha blending failed" << std::endl;
}
......
......@@ -49,12 +49,13 @@ class graphics {
/**
* Clears the screen to the given background color.
*
* @param r Red value.
* @param g Green value.
* @param b Blue value.
* @param a (255) Alpha value.
*/
graphics& clear(int r, int g, int b, int a);
/**
* Clears the screen to the given background color.
*/
graphics& clear(int r, int g, int b);
/**
......
......@@ -50,6 +50,10 @@ def draw() {
def update(delta) {
tests[currenttest].update(delta)
if (love.keyboard.isDown("q")) {
love.event.quit()
}
}
def joystickpressed(joystick, button) {
......
Subproject commit 953e95f7a50b36bafa8ce443827b3b6dd12affaa
Subproject commit 0ee02b2cdc16a4e198549436084189fb1e34a7af
Subproject commit 71205d809e1970df242d6934beade6fdc6a661db
Subproject commit 6e3ad249a62aa7828543d2f62b2e3539f0c81e3a
Subproject commit 76a8c3b8f0036d180be1cea1d46d31e6035064d0
Subproject commit 3fe77e5e77f3c3433b20ecc84126e6fe6e411077
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment