mirror of
https://github.com/libretro/libretro-chailove.git
synced 2024-11-23 16:09:59 +00:00
commit
dd5c352a7d
1
.gitignore
vendored
1
.gitignore
vendored
@ -7,3 +7,4 @@ node_modules
|
||||
/package.json
|
||||
/.bsv
|
||||
/*.mkv
|
||||
*.d
|
||||
|
5
.gitmodules
vendored
5
.gitmodules
vendored
@ -13,11 +13,6 @@
|
||||
url = https://github.com/ChaiScript/ChaiScript.git
|
||||
ignore = dirty
|
||||
branch = develop
|
||||
[submodule "vendor/filesystem"]
|
||||
path = vendor/filesystem
|
||||
url = https://github.com/wjakob/filesystem.git
|
||||
ignore = dirty
|
||||
branch = master
|
||||
[submodule "vendor/SDL_tty"]
|
||||
path = vendor/SDL_tty
|
||||
url = https://github.com/Grumbel/SDL_tty.git
|
||||
|
17
CHANGELOG.md
17
CHANGELOG.md
@ -4,6 +4,23 @@ 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.29.1 - 2018-11-05
|
||||
### Chores
|
||||
- Moved String Methods to [ChaiScript_Extras](https://github.com/ChaiScript/ChaiScript_Extras)
|
||||
- Replaced use of `filesystem/path.h` with internal functions
|
||||
- Updated ChaiScript/ChaiScript_Extras
|
||||
- Updated libretro/libretro-common
|
||||
- Updated effolkronium/random
|
||||
|
||||
## 0.29.0 - 2018-10-13
|
||||
### Fixes
|
||||
- Fixed `/libretro/saves` mounting
|
||||
|
||||
### Features
|
||||
- Added `string::trim()`
|
||||
- Added `string::split()`
|
||||
- Adds loading of `conf.chai` for the `conf()` callback
|
||||
|
||||
## 0.28.0 - 2018-10-07
|
||||
### Features
|
||||
- `love.timer.step()` now returns `dt`
|
||||
|
@ -8,6 +8,7 @@ SOURCES_CXX := $(wildcard \
|
||||
$(CORE_DIR)/src/love/Types/Graphics/*.cpp \
|
||||
$(CORE_DIR)/src/love/Types/Input/*.cpp \
|
||||
)
|
||||
FLAGS += -Wfatal-errors
|
||||
|
||||
# semver
|
||||
FLAGS += -I$(CORE_DIR)/vendor/semver
|
||||
@ -16,9 +17,6 @@ SOURCES_C := $(CORE_DIR)/vendor/semver/semver.c
|
||||
# random
|
||||
FLAGS += -I$(CORE_DIR)/vendor/random/include
|
||||
|
||||
# filesystem
|
||||
FLAGS += -I$(CORE_DIR)/vendor/filesystem
|
||||
|
||||
# libretro-common
|
||||
FLAGS += -I$(CORE_DIR)/vendor/libretro-common/include
|
||||
# Only compile libretro-common when not STATIC_LINKING
|
||||
@ -48,7 +46,7 @@ ifneq ($(STATIC_LINKING), 1)
|
||||
)
|
||||
# Ensure the sinc_resampler_neon is available for ARM NEON devices.
|
||||
OBJECTS += $(CORE_DIR)/vendor/libretro-common/audio/resampler/drivers/sinc_resampler_neon.o
|
||||
|
||||
|
||||
# MD5
|
||||
FLAGS += -I$(CORE_DIR)/vendor/libretro-common/include
|
||||
SOURCES_C += $(CORE_DIR)/vendor/libretro-common/utils/md5.c
|
||||
@ -189,6 +187,7 @@ ifeq ($(HAVE_CHAISCRIPT),)
|
||||
FLAGS += -I$(CORE_DIR)/vendor/ChaiScript_Extras/include
|
||||
FLAGS += -D__HAVE_CHAISCRIPT__
|
||||
FLAGS += -DCHAISCRIPT_NO_THREADS -DCHAISCRIPT_NO_THREADS_WARNING -DCHAISCRIPT_NO_DYNLOAD
|
||||
FLAGS += -DCHAISCRIPT_EXTRAS_MATH_SKIP_ADVANCED
|
||||
endif
|
||||
|
||||
# SDL
|
||||
|
@ -277,19 +277,23 @@ else ifeq ($(platform), switch)
|
||||
|
||||
# Nintendo Switch (libnx)
|
||||
else ifeq ($(platform), libnx)
|
||||
include $(DEVKITPRO)/libnx/switch_rules
|
||||
EXT=a
|
||||
TARGET := $(TARGET_NAME)_libretro_$(platform).$(EXT)
|
||||
DEFINES := -DSWITCH=1 -U__linux__ -U__linux -DRARCH_INTERNAL
|
||||
CFLAGS := $(DEFINES) -g \
|
||||
-O2 \
|
||||
export DEPSDIR := $(CURDIR)/
|
||||
include $(DEVKITPRO)/libnx/switch_rules
|
||||
EXT=a
|
||||
TARGET := $(TARGET_NAME)_libretro_$(platform).$(EXT)
|
||||
DEFINES := -DSWITCH=1 -U__linux__ -U__linux -DRARCH_INTERNAL
|
||||
CFLAGS := $(DEFINES) -g \
|
||||
-O2 \
|
||||
-fPIE -I$(LIBNX)/include/ -ffunction-sections -fdata-sections -ftls-model=local-exec -Wl,--allow-multiple-definition -specs=$(LIBNX)/switch.specs
|
||||
CFLAGS += $(INCDIRS)
|
||||
CFLAGS += $(INCLUDE) -D__SWITCH__ -DHAVE_LIBNX
|
||||
CXXFLAGS := $(ASFLAGS) $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11
|
||||
CFLAGS += -std=gnu11
|
||||
PLATFORM_DEFINES += -DARM -march=armv8-a -mtune=cortex-a57 -mtp=soft
|
||||
STATIC_LINKING = 1
|
||||
CFLAGS += $(INCDIRS)
|
||||
CFLAGS += $(INCLUDE) -D__SWITCH__ -DHAVE_LIBNX
|
||||
# Replaced -fno-rtti -fno-exceptions with -fexceptions, using C++14
|
||||
CXXFLAGS := $(ASFLAGS) $(CFLAGS) -fexceptions -std=c++14
|
||||
CFLAGS += -std=gnu11
|
||||
PLATFORM_DEFINES += -DARM -march=armv8-a -mtune=cortex-a57 -mtp=soft
|
||||
STATIC_LINKING = 1
|
||||
#PLATFORM_DEFINES += -D_INCL_PHYSFS_PLATFORMS -DPHYSFS_PLATFORM_UNIX=1 -DPHYSFS_PLATFORM_POSIX=1
|
||||
#PLATFORM_DEFINES += -Dpthread_t=Thread -Dpthread_mutex_t=Mutex -Dpthread_mutexattr_t='void*' -Dpthread_attr_t=int -Dpthread_cond_t=CondVar -Dpthread_condattr_t='int' -D_SYS__PTHREADTYPES_H_
|
||||
|
||||
# Classic Platforms ####################
|
||||
# Platform affix = classic_<ISA>_<µARCH>
|
||||
|
14
README.md
14
README.md
@ -16,14 +16,20 @@ ChaiLove is an awesome framework you can use to make 2D games in [ChaiScript](ht
|
||||
- [Game of Life](https://github.com/RobLoach/ChaiLove-GameOfLife)
|
||||
- [... and more](https://github.com/topics/chailove)
|
||||
|
||||
## Usage
|
||||
## Installation
|
||||
|
||||
ChaiLove is a [libretro](https://www.libretro.com/) core, which can be run through [RetroArch](http://retroarch.com/). [Floppy Bird](https://github.com/RobLoach/ChaiLove-FloppyBird) is a [free game you can download and play](https://www.youtube.com/watch?v=RLVwTh6qDFI)...
|
||||
ChaiLove is a [libretro](https://www.libretro.com/) core, which can be installed through [RetroArch](http://retroarch.com/).
|
||||
|
||||
1. Run [RetroArch](http://retroarch.com/)
|
||||
2. *Online Updater* → *Core Updator* → *ChaiLove*
|
||||
3. *Online Updater* → *Content Downloader* → *ChaiLove* → *Floppy Bird*
|
||||
4. *Load Content* → *Downloads* → *Floppy Bird.chailove*
|
||||
|
||||
## Usage
|
||||
|
||||
[Floppy Bird](https://github.com/RobLoach/ChaiLove-FloppyBird) is a [free game you can download and play](https://www.youtube.com/watch?v=RLVwTh6qDFI)...
|
||||
|
||||
1. Run [RetroArch](http://retroarch.com/)
|
||||
2. *Online Updater* → *Content Downloader* → *ChaiLove* → *FloppyBird.chailove*
|
||||
3. *Load Content* → *Downloads* → *FloppyBird.chailove*
|
||||
|
||||
Alternatively, you can run the ChaiLove core through RetroArch via the command line:
|
||||
|
||||
|
@ -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.28.0"
|
||||
PROJECT_NUMBER = "0.29.1"
|
||||
|
||||
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
|
||||
# base path where the generated documentation will be put.
|
||||
|
8
examples/benchmark/conf.chai
Normal file
8
examples/benchmark/conf.chai
Normal file
@ -0,0 +1,8 @@
|
||||
/**
|
||||
* ChaiLove callback; Configure the application.
|
||||
*/
|
||||
def conf(t) {
|
||||
t.window.width = 720
|
||||
t.window.height = 680
|
||||
t.console = true
|
||||
}
|
@ -7,15 +7,6 @@ global sprites = List()
|
||||
global img
|
||||
global music
|
||||
|
||||
/**
|
||||
* ChaiLove callback; Configure the application.
|
||||
*/
|
||||
def conf(t) {
|
||||
t.window.width = 720
|
||||
t.window.height = 680
|
||||
t.console = true
|
||||
}
|
||||
|
||||
/**
|
||||
* ChaiLove callback; Load the application.
|
||||
*/
|
||||
@ -94,8 +85,8 @@ class Sprite {
|
||||
def Sprite() {
|
||||
this.x = love.math.random(love.graphics.getWidth()) * 1.0f
|
||||
this.y = love.math.random(love.graphics.getHeight()) * 1.0f
|
||||
this.xspeed = love.math.random(10) * 50.0f
|
||||
this.yspeed = love.math.random(10) * 50.0f
|
||||
this.xspeed = love.math.random(-10, 10) * 50
|
||||
this.yspeed = love.math.random(-10, 10) * 50
|
||||
}
|
||||
|
||||
def draw() {
|
||||
@ -124,32 +115,3 @@ class Sprite {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
def loadstate(data) {
|
||||
print("Load State")
|
||||
print(data)
|
||||
var info = from_json(data)
|
||||
var num = info["number"]
|
||||
|
||||
// Do something with the loaded number.
|
||||
sprites.clear()
|
||||
for (var i = 0; i < num; ++i) {
|
||||
sprites.push_back(Sprite())
|
||||
}
|
||||
|
||||
// The state loaded correctly, so return true.
|
||||
return true
|
||||
}
|
||||
|
||||
def savestate() {
|
||||
// Retrieve the number to save.
|
||||
var num = sprites.size()
|
||||
|
||||
// Construct the JSON data.
|
||||
var data = ["number": num]
|
||||
print("Save State")
|
||||
print(to_json(data))
|
||||
|
||||
// Tell the system to save the JSON data.
|
||||
return to_json(data)
|
||||
}
|
||||
|
9
examples/pong/conf.chai
Normal file
9
examples/pong/conf.chai
Normal file
@ -0,0 +1,9 @@
|
||||
/**
|
||||
* ChaiLove callback; Configure the application.
|
||||
*/
|
||||
def conf(t) {
|
||||
t.window.width = 640
|
||||
t.window.height = 480
|
||||
//t.modules.sound = false
|
||||
t.console = true
|
||||
}
|
@ -5,16 +5,6 @@ global players = []
|
||||
global pongSound
|
||||
global ball
|
||||
|
||||
/**
|
||||
* ChaiLove callback; Configure the application.
|
||||
*/
|
||||
def conf(t) {
|
||||
t.window.width = 640
|
||||
t.window.height = 480
|
||||
//t.modules.sound = false
|
||||
t.console = true
|
||||
}
|
||||
|
||||
/**
|
||||
* ChaiLove callback; Load the application.
|
||||
*/
|
||||
@ -29,7 +19,6 @@ def load() {
|
||||
Player(false, 80.0f, love.graphics.getHeight() / 2.0f),
|
||||
Player(true, love.graphics.getWidth() - 80.0f, love.graphics.getHeight() / 2.0f)
|
||||
]
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -47,7 +47,7 @@ global T
|
||||
def conf(t) {
|
||||
t.window.width = WIDTH * gridScale
|
||||
t.window.height = HEIGHT * gridScale
|
||||
t.version = "0.28.0"
|
||||
t.version = "0.29.0"
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -47,9 +47,9 @@
|
||||
#define SRC_CHAILOVE_H_
|
||||
|
||||
#define CHAILOVE_VERSION_MAJOR 0
|
||||
#define CHAILOVE_VERSION_MINOR 28
|
||||
#define CHAILOVE_VERSION_PATCH 0
|
||||
#define CHAILOVE_VERSION_STRING "0.28.0"
|
||||
#define CHAILOVE_VERSION_MINOR 29
|
||||
#define CHAILOVE_VERSION_PATCH 1
|
||||
#define CHAILOVE_VERSION_STRING "0.29.1"
|
||||
|
||||
#include "SDL.h"
|
||||
#include "libretro.h"
|
||||
|
@ -100,6 +100,24 @@ class String {
|
||||
* @endcode
|
||||
*/
|
||||
std::string replace(const std::string& search, const std::string& replace);
|
||||
|
||||
/**
|
||||
* Returns a trimmed version of the given string.
|
||||
*
|
||||
* @return A new string with trimmed left and right.
|
||||
*
|
||||
* @code
|
||||
* var hello = " Hello World! "
|
||||
* var result = hello.trim()
|
||||
* // => "Hello World!"
|
||||
* @endcode
|
||||
*/
|
||||
std::string trim();
|
||||
|
||||
/**
|
||||
* Splits a string by the given token.
|
||||
*/
|
||||
std::string split(const std::string& token);
|
||||
};
|
||||
|
||||
#endif // SRC_CHAILOVEDOCS_H_
|
||||
|
@ -78,7 +78,6 @@ void retro_set_environment(retro_environment_t cb) {
|
||||
* libretro callback; Updates the core option variables.
|
||||
*/
|
||||
static void update_variables(void) {
|
||||
std::cout << "[ChaiLove] [libretro] update_variables()" << std::endl;
|
||||
ChaiLove* app = ChaiLove::getInstance();
|
||||
app->system.updateVariables(app->config);
|
||||
}
|
||||
@ -226,8 +225,8 @@ void retro_set_controller_port_device(unsigned port, unsigned device) {
|
||||
* libretro callback; Return the amount of bytes required to save a state.
|
||||
*/
|
||||
size_t retro_serialize_size(void) {
|
||||
// Save states will be 5 kilobytes.
|
||||
return 5000;
|
||||
// Save states will be 8 KB.
|
||||
return 8192;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -314,7 +313,6 @@ 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();
|
||||
|
||||
|
@ -4,7 +4,6 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "filesystem/path.h"
|
||||
|
||||
#include "../../../ChaiLove.h"
|
||||
|
||||
@ -38,9 +37,8 @@ std::string FileData::getString() {
|
||||
}
|
||||
|
||||
std::string FileData::getExtension() {
|
||||
::filesystem::path p(m_filepath.c_str());
|
||||
std::string extension(p.extension());
|
||||
return extension;
|
||||
ChaiLove* app = ChaiLove::getInstance();
|
||||
return app->filesystem.getFileExtension(m_filepath);
|
||||
}
|
||||
|
||||
} // namespace FileSystem
|
||||
|
@ -3,7 +3,6 @@
|
||||
#include "Types/Audio/SoundData.h"
|
||||
#include "../ChaiLove.h"
|
||||
#include "sound.h"
|
||||
#include "physfs.h"
|
||||
#include "audio/conversion/float_to_s16.h"
|
||||
|
||||
using love::Types::Audio::SoundData;
|
||||
|
@ -5,7 +5,6 @@
|
||||
#include "physfs.h"
|
||||
#include "filesystem.h"
|
||||
#include "physfsrwops.h"
|
||||
#include "filesystem/path.h"
|
||||
#include "../ChaiLove.h"
|
||||
#include "Types/FileSystem/FileInfo.h"
|
||||
|
||||
@ -32,8 +31,7 @@ bool filesystem::init(const std::string& file, const void* data) {
|
||||
}
|
||||
|
||||
// Find the parent and extension of the given file.
|
||||
::filesystem::path p(file.c_str());
|
||||
std::string extension(p.extension());
|
||||
std::string extension(getFileExtension(file));
|
||||
|
||||
// Allow loading from an Archive.
|
||||
if (extension == "chaigame" || extension == "chailove" || extension == "zip") {
|
||||
@ -41,8 +39,7 @@ bool filesystem::init(const std::string& file, const void* data) {
|
||||
}
|
||||
|
||||
// If we are just running the core, load the base path.
|
||||
::filesystem::path parent(p.parent_path());
|
||||
std::string parentPath(parent.str());
|
||||
std::string parentPath(getParentDirectory(file));
|
||||
if (parentPath.empty()) {
|
||||
return mount(".", "/", false);
|
||||
}
|
||||
@ -51,6 +48,36 @@ bool filesystem::init(const std::string& file, const void* data) {
|
||||
return mount(parentPath.c_str(), "/", false);
|
||||
}
|
||||
|
||||
std::string filesystem::getParentDirectory(const std::string& filepath) {
|
||||
size_t last = filepath.find_last_of("/\\");
|
||||
if (last != std::string::npos) {
|
||||
return filepath.substr(0, last);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string filesystem::getFileExtension(const std::string& filepath) {
|
||||
size_t i = filepath.rfind('.', filepath.length());
|
||||
if (i != std::string::npos) {
|
||||
return filepath.substr(i + 1, filepath.length() - i);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string filesystem::getBasename(const std::string& filepath) {
|
||||
char sep = '/';
|
||||
if (filepath.find('\\') != std::string::npos) {
|
||||
sep = '\\';
|
||||
}
|
||||
|
||||
size_t i = filepath.rfind(sep, filepath.length());
|
||||
if (i != std::string::npos) {
|
||||
return filepath.substr(i + 1, filepath.length() - i);
|
||||
}
|
||||
|
||||
return filepath;
|
||||
}
|
||||
|
||||
void filesystem::mountlibretro() {
|
||||
// Mount some of the libretro directories.
|
||||
const char *system_dir = NULL;
|
||||
@ -60,8 +87,8 @@ void filesystem::mountlibretro() {
|
||||
|
||||
if (ChaiLove::environ_cb(RETRO_ENVIRONMENT_GET_LIBRETRO_PATH, &core_dir) && core_dir) {
|
||||
// Make sure to get the directory of the core.
|
||||
::filesystem::path p(core_dir);
|
||||
mount(p.parent_path().str(), "/libretro/core", false);
|
||||
std::string parentPath(getParentDirectory(core_dir));
|
||||
mount(parentPath, "/libretro/core", false);
|
||||
}
|
||||
if (ChaiLove::environ_cb(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &system_dir) && system_dir) {
|
||||
mount(system_dir, "/libretro/system", false);
|
||||
@ -72,8 +99,12 @@ void filesystem::mountlibretro() {
|
||||
if (ChaiLove::environ_cb(RETRO_ENVIRONMENT_GET_SAVE_DIRECTORY, &save_dir) && save_dir) {
|
||||
save_dir = *save_dir ? save_dir : system_dir;
|
||||
mount(save_dir, "/libretro/saves", false);
|
||||
} else {
|
||||
} else if (system_dir) {
|
||||
// Have the system directory be the save directory if available.
|
||||
mount(save_dir = system_dir, "/libretro/saves", false);
|
||||
} else {
|
||||
// Save directory becomes the current working directory.
|
||||
mount(save_dir = ".", "/libretro/saves", false);
|
||||
}
|
||||
|
||||
// Ensure the write directory is set to the Save Directory.
|
||||
@ -171,10 +202,11 @@ char* filesystem::readChar(const std::string& filename) {
|
||||
std::string filesystem::read(const std::string& filename) {
|
||||
// Retrieve a character buffer.
|
||||
char* myBuf = readChar(filename);
|
||||
if (myBuf == NULL) {
|
||||
return std::string("");
|
||||
std::string output;
|
||||
if (myBuf != NULL) {
|
||||
output = std::string(myBuf);
|
||||
}
|
||||
return std::string(myBuf);
|
||||
return output;
|
||||
}
|
||||
|
||||
void* filesystem::readBuffer(const std::string& filename, int& size) {
|
||||
@ -222,6 +254,9 @@ bool filesystem::unmount(const std::string& archive) {
|
||||
}
|
||||
|
||||
bool filesystem::mount(const char *archive, const std::string& mountpoint) {
|
||||
if (strlen(archive) == 0) {
|
||||
return false;
|
||||
}
|
||||
return mount(std::string(archive), mountpoint);
|
||||
}
|
||||
|
||||
|
@ -78,6 +78,10 @@ class filesystem {
|
||||
*/
|
||||
int getSize(const std::string& file);
|
||||
|
||||
std::string getFileExtension(const std::string& filepath);
|
||||
std::string getBasename(const std::string& filepath);
|
||||
std::string getParentDirectory(const std::string& filepath);
|
||||
|
||||
/**
|
||||
* Removes a file or empty directory.
|
||||
*
|
||||
|
@ -1,10 +1,10 @@
|
||||
#include "script.h"
|
||||
#include "../ChaiLove.h"
|
||||
#include <filesystem/path.h>
|
||||
#include <algorithm>
|
||||
|
||||
#ifdef __HAVE_CHAISCRIPT__
|
||||
#include "chaiscript/extras/math.hpp"
|
||||
#include "chaiscript/extras/string_methods.hpp"
|
||||
using namespace chaiscript;
|
||||
#endif
|
||||
|
||||
@ -35,7 +35,7 @@ bool script::loadModule(const std::string& moduleName) {
|
||||
// See if we are to append .chai.
|
||||
filename = filename + ".chai";
|
||||
if (!app->filesystem.exists(filename)) {
|
||||
std::cout << "[ChaiLove] [script] Module " << moduleName << " not found." << std::endl;
|
||||
std::cout << "[ChaiLove] [script] Module " << filename << " not found." << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -45,7 +45,7 @@ bool script::loadModule(const std::string& moduleName) {
|
||||
|
||||
// Make sure it was not empty.
|
||||
if (contents.empty()) {
|
||||
std::cout << "[ChaiLove] [script] Module " << moduleName << " was loaded, but empty." << std::endl;
|
||||
std::cout << "[ChaiLove] [script] Module " << filename << " was loaded, but empty." << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -58,7 +58,7 @@ bool script::loadModule(const std::string& moduleName) {
|
||||
|
||||
bool script::loadModuleRequire(const std::string& moduleName) {
|
||||
// Check if the module has already been loaded.
|
||||
std::string filename = replaceString(moduleName, ".", "/");
|
||||
std::string filename = replaceString(replaceString(moduleName, ".chai", ""), ".", "/");
|
||||
if (std::find(m_requiremodules.begin(), m_requiremodules.end(), filename) != m_requiremodules.end()) {
|
||||
return true;
|
||||
}
|
||||
@ -76,6 +76,7 @@ chaiscript::Boxed_Value script::eval(const std::string& code, const std::string&
|
||||
std::string contents = replaceString(code, "\t", " ");
|
||||
return chai.eval(contents, Exception_Handler(), filename);
|
||||
}
|
||||
|
||||
std::string script::evalString(const std::string& code, const std::string& filename) {
|
||||
// Replace possible problematic tabs, and evaluate the script.
|
||||
std::string contents = replaceString(code, "\t", " ");
|
||||
@ -84,6 +85,7 @@ std::string script::evalString(const std::string& code, const std::string& filen
|
||||
|
||||
script::script(const std::string& file) {
|
||||
#ifdef __HAVE_CHAISCRIPT__
|
||||
ChaiLove* app = ChaiLove::getInstance();
|
||||
|
||||
// ChaiScript Standard Library Additions
|
||||
// This adds some basic type definitions to ChaiScript.
|
||||
@ -91,23 +93,8 @@ script::script(const std::string& file) {
|
||||
chai.add(bootstrap::standard_library::vector_type<std::vector<std::string>>("StringVector"));
|
||||
chai.add(bootstrap::standard_library::map_type<std::map<std::string, bool>>("StringBoolMap"));
|
||||
|
||||
// Global Helpers
|
||||
// string::replace(std::string search, std::string replace)
|
||||
chai.add(fun([](const std::string& subject, const std::string& search, const std::string& replace) {
|
||||
std::string newSubject(subject);
|
||||
size_t pos = 0;
|
||||
while ((pos = newSubject.find(search, pos)) != std::string::npos) {
|
||||
newSubject.replace(pos, search.length(), replace);
|
||||
pos += replace.length();
|
||||
}
|
||||
return newSubject;
|
||||
}), "replace");
|
||||
// string::replace(char search, char replace)
|
||||
chai.add(fun([](const std::string& subject, char search, char replace) {
|
||||
std::string newSubject(subject);
|
||||
std::replace(newSubject.begin(), newSubject.end(), search, replace);
|
||||
return newSubject;
|
||||
}), "replace");
|
||||
auto stringmethods = chaiscript::extras::string_methods::bootstrap();
|
||||
chai.add(stringmethods);
|
||||
|
||||
// List
|
||||
auto listModule = std::make_shared<chaiscript::Module>();
|
||||
@ -324,15 +311,18 @@ script::script(const std::string& file) {
|
||||
chai.add(fun<std::vector<std::string>, filesystem, const std::string&, const std::string&>(&filesystem::lines), "lines");
|
||||
chai.add(fun(&filesystem::load), "load");
|
||||
chai.add(fun(&script::loadModuleRequire, this), "require");
|
||||
chai.add(fun(&filesystem::getFileExtension), "getFileExtension");
|
||||
chai.add(fun(&filesystem::getBasename), "getBasename");
|
||||
chai.add(fun(&filesystem::getParentDirectory), "getParentDirectory");
|
||||
|
||||
// System
|
||||
chai.add(fun(&system::getOS), "getOS");
|
||||
chai.add(fun(&system::getVersion), "getVersion");
|
||||
chai.add(fun(&system::getVersionString), "getVersionString");
|
||||
chai.add(fun(&system::getUsername), "getUsername");
|
||||
chai.add(fun(&system::execute), "execute");
|
||||
chai.add(fun(&system::getClipboardText), "getClipboardText");
|
||||
chai.add(fun(&system::setClipboardText), "setClipboardText");
|
||||
chai.add(fun(&system::execute), "execute");
|
||||
|
||||
// Mouse
|
||||
chai.add(fun(&mouse::getX), "getX");
|
||||
@ -401,18 +391,19 @@ script::script(const std::string& file) {
|
||||
// Load the desired main.chai file.
|
||||
if (file.empty()) {
|
||||
// When no content is provided, display a No Game demo.
|
||||
eval(ChaiLove::getInstance()->demo(), "demo.chai");
|
||||
eval(app->demo(), "demo.chai");
|
||||
mainLoaded = true;
|
||||
} else {
|
||||
// Load the main.chai file.
|
||||
::filesystem::path p(file.c_str());
|
||||
std::string extension(p.extension());
|
||||
loadModuleRequire("conf");
|
||||
|
||||
std::string extension(app->filesystem.getFileExtension(file));
|
||||
if (extension == "chailove" || extension == "chaigame") {
|
||||
mainLoaded = loadModule("main.chai");
|
||||
mainLoaded = loadModuleRequire("main");
|
||||
} else {
|
||||
// Otherwise, load the actual file.
|
||||
std::string filename(p.filename());
|
||||
mainLoaded = loadModule(filename);
|
||||
std::string filename(app->filesystem.getBasename(file));
|
||||
mainLoaded = loadModuleRequire(filename);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -45,6 +45,8 @@ class script {
|
||||
*
|
||||
* @param t The config object to modify.
|
||||
*
|
||||
* This callback can live in the `conf.chai` file.
|
||||
*
|
||||
* ### Example
|
||||
*
|
||||
* @code
|
||||
@ -53,7 +55,7 @@ class script {
|
||||
* t.console = false
|
||||
*
|
||||
* // The ChaiLove version this game was made for.
|
||||
* t.version = "0.27.0"
|
||||
* t.version = "0.29.0"
|
||||
*
|
||||
* // The width and height of the game.
|
||||
* t.window.width = 1024
|
||||
|
@ -96,7 +96,9 @@ class system {
|
||||
/**
|
||||
* Execute an operating system shell command. This is like the C system() function.
|
||||
*
|
||||
* @return True or False depending on whether or not the command started properly.
|
||||
* @param command The command to run.
|
||||
*
|
||||
* @return Returns true or false depending on the process succeeded to execute.
|
||||
*/
|
||||
bool execute(const std::string& command);
|
||||
|
||||
|
8
test/unittests/conf.chai
Normal file
8
test/unittests/conf.chai
Normal file
@ -0,0 +1,8 @@
|
||||
global confTestLoaded = false
|
||||
|
||||
def conf(t) {
|
||||
t.console = true
|
||||
t.window.width = 640
|
||||
t.window.height = 500
|
||||
confTestLoaded = true
|
||||
}
|
@ -102,3 +102,15 @@ requiretestFileLoaded = false
|
||||
requireReturn = require("assets.requiretest")
|
||||
assert(requireReturn, " double call")
|
||||
assert_not(requiretestFileLoaded, " not loaded twice")
|
||||
|
||||
// getFileExtension()
|
||||
assert_equal(love.filesystem.getFileExtension("/opt/var/something.txt"), "txt", "love.filesystem.getFileExtension()")
|
||||
assert_equal(love.filesystem.getFileExtension("/opt/var/something.tar.gz"), "gz", "love.filesystem.getFileExtension()")
|
||||
|
||||
// getBasename
|
||||
assert_equal(love.filesystem.getBasename("/opt/var/something.txt"), "something.txt", "love.filesystem.getBasename()")
|
||||
assert_equal(love.filesystem.getBasename("something.txt"), "something.txt", "love.filesystem.getBasename()")
|
||||
|
||||
// getParentDirectory
|
||||
assert_equal(love.filesystem.getParentDirectory("/opt/var/something.txt"), "/opt/var", "love.filesystem.getParentDirectory()")
|
||||
assert_equal(love.filesystem.getParentDirectory("something.txt"), "", "love.filesystem.getParentDirectory()")
|
||||
|
@ -1,11 +1,5 @@
|
||||
global failure = ""
|
||||
|
||||
def conf(t) {
|
||||
t.console = true
|
||||
t.window.width = 640
|
||||
t.window.height = 500
|
||||
}
|
||||
|
||||
def load() {
|
||||
print("\n================================\n")
|
||||
print("ChaiLove: Unit Testing Framework\n")
|
||||
|
@ -16,6 +16,7 @@ assert(true, "love.system.getUsername() == '" + username + "'")
|
||||
|
||||
// getOS()
|
||||
if (love.system.getOS() == "Linux") {
|
||||
// Run in foreground.
|
||||
var result = love.system.execute("uname")
|
||||
assert(result, "love.system.execute('uname')")
|
||||
}
|
||||
@ -32,3 +33,23 @@ var newReplaceString = replaceSubject.replace("World", "Space")
|
||||
assert_equal(newReplaceString, "Hello Space! Hello Space!", "string::replace(string, string)")
|
||||
newReplaceString = replaceSubject.replace('!', '.')
|
||||
assert_equal(newReplaceString, "Hello World. Hello World.", "string::replace(char, char)")
|
||||
|
||||
// string::trim()
|
||||
var trimSubject = " Hello World! "
|
||||
assert_equal(trimSubject.trim(), "Hello World!", "string::trim()")
|
||||
|
||||
// string::split()
|
||||
var splitTest = "Hello|How|Are|You"
|
||||
var splitResult = splitTest.split("|")
|
||||
assert_equal(splitResult[1], "How", "string::split()")
|
||||
splitTest = "Hello, World, Time"
|
||||
splitResult = splitTest.split(", ")
|
||||
assert_equal(splitResult[1], "World", " - commas")
|
||||
|
||||
// conf.chai
|
||||
var objs = get_objects()
|
||||
var confTestLoadedExists = objs["confTestLoaded"].get_type_info().bare_equal(bool_type)
|
||||
assert(confTestLoadedExists, "conf.chai is loaded")
|
||||
if (confTestLoadedExists) {
|
||||
assert(confTestLoaded, "conf() called")
|
||||
}
|
||||
|
@ -4,4 +4,4 @@ assert(delta >= 0, "love.timer.getDelta()")
|
||||
|
||||
// getFPS()
|
||||
var fps = love.timer.getFPS()
|
||||
assert(fps >= 0, "love.love.timer.getFPS()")
|
||||
assert(fps >= 0, "love.timer.getFPS()")
|
||||
|
2
vendor/ChaiScript_Extras
vendored
2
vendor/ChaiScript_Extras
vendored
@ -1 +1 @@
|
||||
Subproject commit 7043c12105f20baec7655e62563796ca43535557
|
||||
Subproject commit 4f3ee02194411edc5b7aa80d109e400d3b94c15d
|
2
vendor/cppcodec
vendored
2
vendor/cppcodec
vendored
@ -1 +1 @@
|
||||
Subproject commit 302dc28f8fd5c8bf2ea8d7212aed3be884d5d166
|
||||
Subproject commit 82d011756adfece7506728b4fa9e7354cbe58641
|
2
vendor/didstopia-physfs
vendored
2
vendor/didstopia-physfs
vendored
@ -1 +1 @@
|
||||
Subproject commit fe12df08508044287aba2317e13cd91596af5af1
|
||||
Subproject commit 3ae84ee5d0a0af72a6a808a32b63e1ea0076f2be
|
1
vendor/filesystem
vendored
1
vendor/filesystem
vendored
@ -1 +0,0 @@
|
||||
Subproject commit 0a539a6c988dc8691af317e077893e831dee2908
|
2
vendor/libretro-common
vendored
2
vendor/libretro-common
vendored
@ -1 +1 @@
|
||||
Subproject commit 29905d94e39090dbde5f9e6d726eb2510618704a
|
||||
Subproject commit 4f99997d94bbfed63d957153976dd9a43c73aced
|
2
vendor/random
vendored
2
vendor/random
vendored
@ -1 +1 @@
|
||||
Subproject commit 2cdf5dc1b22a390f1a09008a98c56a7604d27597
|
||||
Subproject commit 985de84de4ec891ce060c4c6579cf70d3c1c86e2
|
Loading…
Reference in New Issue
Block a user