diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a251e74 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +assets/*.h +build* +.vscode +subprojects/*/ diff --git a/.gitingore b/.gitingore deleted file mode 100644 index 0540d2a..0000000 --- a/.gitingore +++ /dev/null @@ -1,2 +0,0 @@ -assets/*.h -build* diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index a68ca29..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,81 +0,0 @@ -{ - "C_Cpp.default.compileCommands": "builddir/vscode_compile_commands.json", - "files.associations": { - "array": "cpp", - "atomic": "cpp", - "hash_map": "cpp", - "bit": "cpp", - "*.tcc": "cpp", - "bitset": "cpp", - "cctype": "cpp", - "charconv": "cpp", - "chrono": "cpp", - "clocale": "cpp", - "cmath": "cpp", - "codecvt": "cpp", - "compare": "cpp", - "concepts": "cpp", - "condition_variable": "cpp", - "csignal": "cpp", - "cstdarg": "cpp", - "cstddef": "cpp", - "cstdint": "cpp", - "cstdio": "cpp", - "cstdlib": "cpp", - "cstring": "cpp", - "ctime": "cpp", - "cwchar": "cpp", - "cwctype": "cpp", - "deque": "cpp", - "forward_list": "cpp", - "list": "cpp", - "map": "cpp", - "set": "cpp", - "string": "cpp", - "unordered_map": "cpp", - "unordered_set": "cpp", - "vector": "cpp", - "exception": "cpp", - "algorithm": "cpp", - "functional": "cpp", - "iterator": "cpp", - "memory": "cpp", - "memory_resource": "cpp", - "numeric": "cpp", - "optional": "cpp", - "random": "cpp", - "ratio": "cpp", - "source_location": "cpp", - "string_view": "cpp", - "system_error": "cpp", - "tuple": "cpp", - "type_traits": "cpp", - "utility": "cpp", - "fstream": "cpp", - "future": "cpp", - "initializer_list": "cpp", - "iomanip": "cpp", - "iosfwd": "cpp", - "iostream": "cpp", - "istream": "cpp", - "limits": "cpp", - "mutex": "cpp", - "new": "cpp", - "numbers": "cpp", - "ostream": "cpp", - "semaphore": "cpp", - "shared_mutex": "cpp", - "sstream": "cpp", - "stdexcept": "cpp", - "stop_token": "cpp", - "streambuf": "cpp", - "thread": "cpp", - "cfenv": "cpp", - "cinttypes": "cpp", - "typeindex": "cpp", - "typeinfo": "cpp", - "valarray": "cpp", - "variant": "cpp" - }, - "mesonbuild.configureOnOpen": true -} \ No newline at end of file diff --git a/cmake2meson.py b/cmake2meson.py deleted file mode 100755 index a12d9cf..0000000 --- a/cmake2meson.py +++ /dev/null @@ -1,330 +0,0 @@ -#!/usr/bin/env python3 - -# Copyright 2014 Jussi Pakkanen - -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at - -# http://www.apache.org/licenses/LICENSE-2.0 - -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import typing as T -from pathlib import Path -import sys -import re -import argparse - - -class Token: - def __init__(self, tid: str, value: str): - self.tid = tid - self.value = value - self.lineno = 0 - self.colno = 0 - -class Statement: - def __init__(self, name: str, args: list): - self.name = name.lower() - self.args = args - -class Lexer: - def __init__(self) -> None: - self.token_specification = [ - # Need to be sorted longest to shortest. - ('ignore', re.compile(r'[ \t]')), - ('string', re.compile(r'"([^\\]|(\\.))*?"', re.M)), - ('varexp', re.compile(r'\${[-_0-9a-z/A-Z.]+}')), - ('id', re.compile('''[,-><${}=+_0-9a-z/A-Z|@.*]+''')), - ('eol', re.compile(r'\n')), - ('comment', re.compile(r'#.*')), - ('lparen', re.compile(r'\(')), - ('rparen', re.compile(r'\)')), - ] - - def lex(self, code: str) -> T.Iterator[Token]: - lineno = 1 - line_start = 0 - loc = 0 - col = 0 - while loc < len(code): - matched = False - for (tid, reg) in self.token_specification: - mo = reg.match(code, loc) - if mo: - col = mo.start() - line_start - matched = True - loc = mo.end() - match_text = mo.group() - if tid == 'ignore': - continue - if tid == 'comment': - yield(Token('comment', match_text)) - elif tid == 'lparen': - yield(Token('lparen', '(')) - elif tid == 'rparen': - yield(Token('rparen', ')')) - elif tid == 'string': - yield(Token('string', match_text[1:-1])) - elif tid == 'id': - yield(Token('id', match_text)) - elif tid == 'eol': - # yield('eol') - lineno += 1 - col = 1 - line_start = mo.end() - elif tid == 'varexp': - yield(Token('varexp', match_text[2:-1])) - else: - raise ValueError(f'lex: unknown element {tid}') - break - if not matched: - raise ValueError('Lexer got confused line %d column %d' % (lineno, col)) - -class Parser: - def __init__(self, code: str) -> None: - self.stream = Lexer().lex(code) - self.getsym() - - def getsym(self) -> None: - try: - self.current = next(self.stream) - except StopIteration: - self.current = Token('eof', '') - - def accept(self, s: str) -> bool: - if self.current.tid == s: - self.getsym() - return True - return False - - def expect(self, s: str) -> bool: - if self.accept(s): - return True - raise ValueError(f'Expecting {s} got {self.current.tid}.', self.current.lineno, self.current.colno) - - def statement(self) -> Statement: - cur = self.current - if self.accept('comment'): - return Statement('_', [cur.value]) - self.accept('id') - self.expect('lparen') - args = self.arguments() - self.expect('rparen') - return Statement(cur.value, args) - - def arguments(self) -> T.List[T.Union[Token, T.Any]]: - args = [] # type: T.List[T.Union[Token, T.Any]] - if self.accept('lparen'): - args.append(self.arguments()) - self.expect('rparen') - arg = self.current - if self.accept('comment'): - rest = self.arguments() - args += rest - elif self.accept('string') \ - or self.accept('varexp') \ - or self.accept('id'): - args.append(arg) - rest = self.arguments() - args += rest - return args - - def parse(self) -> T.Iterator[Statement]: - while not self.accept('eof'): - yield(self.statement()) - -def token_or_group(arg: T.Union[Token, T.List[Token]]) -> str: - if isinstance(arg, Token): - return ' ' + arg.value - elif isinstance(arg, list): - line = ' (' - for a in arg: - line += ' ' + token_or_group(a) - line += ' )' - return line - raise RuntimeError('Conversion error in token_or_group') - -class Converter: - ignored_funcs = {'cmake_minimum_required': True, - 'enable_testing': True, - 'include': True} - - def __init__(self, cmake_root: str): - self.cmake_root = Path(cmake_root).expanduser() - self.indent_unit = ' ' - self.indent_level = 0 - self.options = [] # type: T.List[tuple] - - def convert_args(self, args: T.List[Token], as_array: bool = True) -> str: - res = [] - if as_array: - start = '[' - end = ']' - else: - start = '' - end = '' - for i in args: - if i.tid == 'id': - res.append("'%s'" % i.value) - elif i.tid == 'varexp': - res.append('%s' % i.value.lower()) - elif i.tid == 'string': - res.append("'%s'" % i.value) - else: - raise ValueError(f'Unknown arg type {i.tid}') - if len(res) > 1: - return start + ', '.join(res) + end - if len(res) == 1: - return res[0] - return '' - - def write_entry(self, outfile: T.TextIO, t: Statement) -> None: - if t.name in Converter.ignored_funcs: - return - preincrement = 0 - postincrement = 0 - if t.name == '_': - line = t.args[0] - elif t.name == 'add_subdirectory': - line = "subdir('" + t.args[0].value + "')" - elif t.name == 'pkg_search_module' or t.name == 'pkg_search_modules': - varname = t.args[0].value.lower() - mods = ["dependency('%s')" % i.value for i in t.args[1:]] - if len(mods) == 1: - line = '{} = {}'.format(varname, mods[0]) - else: - line = '{} = [{}]'.format(varname, ', '.join(["'%s'" % i for i in mods])) - elif t.name == 'find_package': - line = "{}_dep = dependency('{}')".format(t.args[0].value, t.args[0].value) - elif t.name == 'find_library': - line = "{} = find_library('{}')".format(t.args[0].value.lower(), t.args[0].value) - elif t.name == 'add_executable': - line = '{}_exe = executable({})'.format(t.args[0].value, self.convert_args(t.args, False)) - elif t.name == 'add_library': - if t.args[1].value == 'SHARED': - libcmd = 'shared_library' - args = [t.args[0]] + t.args[2:] - elif t.args[1].value == 'STATIC': - libcmd = 'static_library' - args = [t.args[0]] + t.args[2:] - else: - libcmd = 'library' - args = t.args - line = '{}_lib = {}({})'.format(t.args[0].value, libcmd, self.convert_args(args, False)) - elif t.name == 'add_test': - line = 'test(%s)' % self.convert_args(t.args, False) - elif t.name == 'option': - optname = t.args[0].value - description = t.args[1].value - if len(t.args) > 2: - default = t.args[2].value - else: - default = None - self.options.append((optname, description, default)) - return - elif t.name == 'project': - pname = t.args[0].value - args = [pname] - for l in t.args[1:]: - l = l.value.lower() - if l == 'cxx': - l = 'cpp' - args.append(l) - args = ["'%s'" % i for i in args] - line = 'project(' + ', '.join(args) + ", default_options : ['default_library=static'])" - elif t.name == 'set': - varname = t.args[0].value.lower() - line = '{} = {}\n'.format(varname, self.convert_args(t.args[1:])) - elif t.name == 'if': - postincrement = 1 - try: - line = 'if %s' % self.convert_args(t.args, False) - except AttributeError: # complex if statements - line = t.name - for arg in t.args: - line += token_or_group(arg) - elif t.name == 'elseif': - preincrement = -1 - postincrement = 1 - try: - line = 'elif %s' % self.convert_args(t.args, False) - except AttributeError: # complex if statements - line = t.name - for arg in t.args: - line += token_or_group(arg) - elif t.name == 'else': - preincrement = -1 - postincrement = 1 - line = 'else' - elif t.name == 'endif': - preincrement = -1 - line = 'endif' - else: - line = '''# {}({})'''.format(t.name, self.convert_args(t.args)) - self.indent_level += preincrement - indent = self.indent_level * self.indent_unit - outfile.write(indent) - outfile.write(line) - if not(line.endswith('\n')): - outfile.write('\n') - self.indent_level += postincrement - - def convert(self, subdir: Path = None) -> None: - if not subdir: - subdir = self.cmake_root - cfile = Path(subdir).expanduser() / 'CMakeLists.txt' - try: - with cfile.open(encoding='utf-8') as f: - cmakecode = f.read() - except FileNotFoundError: - print('\nWarning: No CMakeLists.txt in', subdir, '\n', file=sys.stderr) - return - p = Parser(cmakecode) - with (subdir / 'meson.build').open('w', encoding='utf-8') as outfile: - for t in p.parse(): - if t.name == 'add_subdirectory': - # print('\nRecursing to subdir', - # self.cmake_root / t.args[0].value, - # '\n') - self.convert(subdir / t.args[0].value) - # print('\nReturning to', self.cmake_root, '\n') - self.write_entry(outfile, t) - if subdir == self.cmake_root and len(self.options) > 0: - self.write_options() - - def write_options(self) -> None: - filename = self.cmake_root / 'meson_options.txt' - with filename.open('w', encoding='utf-8') as optfile: - for o in self.options: - (optname, description, default) = o - if default is None: - typestr = '' - defaultstr = '' - else: - if default == 'OFF': - typestr = ' type : \'boolean\',' - default = 'false' - elif default == 'ON': - default = 'true' - typestr = ' type : \'boolean\',' - else: - typestr = ' type : \'string\',' - defaultstr = ' value : %s,' % default - line = "option({!r},{}{} description : '{}')\n".format(optname, - typestr, - defaultstr, - description) - optfile.write(line) - -if __name__ == '__main__': - p = argparse.ArgumentParser(description='Convert CMakeLists.txt to meson.build and meson_options.txt') - p.add_argument('cmake_root', help='CMake project root (where top-level CMakeLists.txt is)') - P = p.parse_args() - - Converter(P.cmake_root).convert() diff --git a/meson.build b/meson.build index bea2302..2f914b5 100644 --- a/meson.build +++ b/meson.build @@ -2,16 +2,18 @@ project('neko-player', ['c', 'cpp'], version : '0.1', default_options : ['warning_level=3', 'cpp_std=c++20']) - if get_option('debug') add_global_arguments('-DDEBUG', language: 'cpp') endif +raudio_lib = static_library('raudio', 'raudio/src/raudio.c', c_args: ['-DRAUDIO_STANDALONE', '-DSUPPORT_MODULE_RAUDIO', '-DSUPPORT_FILEFORMAT_WAV', '-DSUPPORT_FILEFORMAT_OGG', '-DSUPPORT_FILEFORMAT_MP3', '-DSUPPORT_FILEFORMAT_QOA', '-DSUPPORT_FILEFORMAT_FLAC', '-DSUPPORT_FILEFORMAT_XM', '-DSUPPORT_FILEFORMAT_MOD']) +raudio_include = include_directories('raudio/src') +raudio_dep = declare_dependency(include_directories: raudio_include, link_with: raudio_lib) deps = [ - dependency('raylib'), dependency('sdl2'), dependency('sdl2_image'), dependency('gl'), dependency('jsoncpp'), + raudio_dep, ] srcs = [ @@ -32,6 +34,7 @@ include_dirs = [ 'imgui-filebrowser', 'IconFontCppHeaders', 'assets', + 'raudio/src', ] res = run_command('./assets/update-assets.sh', check: true) diff --git a/playback.cpp b/playback.cpp index aaa9811..c830dc1 100644 --- a/playback.cpp +++ b/playback.cpp @@ -1,5 +1,7 @@ #include "playback.h" -#include +extern "C" { +#include "raudio.h" +} #include using namespace std::chrono; void Playback::ThreadFunc() { diff --git a/subprojects/raylib b/subprojects/raylib deleted file mode 160000 index 334e96d..0000000 --- a/subprojects/raylib +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 334e96d470c5cb09d154e1c849d04adb721a7a8c