gvaliente / butano Goto Github PK
View Code? Open in Web Editor NEWModern C++ high level GBA engine
License: zlib License
Modern C++ high level GBA engine
License: zlib License
I have this error:
ERROR in bn_string.h
_assign::714
other _size<=_max_size
Not enough space 4-0
this is the main.cpp code:
int main()
{
bn::core::init();
carta carta_mewv;
carta_mewv.pokemon.imagen = bn::sprite_items::psiquicov.create_sprite(0,0);
carta_mewv.pokemon.espalda = bn::sprite_items::carta_back.create_sprite(0,0);
while(true)
{
bn::core::update();
}
}
"carta" is an union:
union carta{
struct entrenador entrenador;
struct pokemon pokemon;
struct energia energia;
carta() {}
~carta() {}
};
pokemon struct:
struct pokemon{
bn::sprite_ptr imagen;
bn::sprite_ptr espalda;
};
The problem appears when i add "carta_mewv.pokemon.nombre = "MewV";" to the main and "bn::string<32> nombre;" to the pokemon struct.
Hello, I use a CPU with 2 cores and I was wondering if I were to use the "-j8/16" parameter in the Makefile, would that make the computer demand too much of my CPU?
Sorry if my English is bad, I'm using google translator =)
Any chance that support for GSM player https://github.com/pinobatch/gsmplayer-gba/tree/master could be added down the road? I'm interested in making some rhythm games using music that's not possible using tracker files. Thanks for the amazing engine!
Hi :)
I was trying to build the example projects but every single time I get the following error:
error: array subscript value '17' is outside the bounds of array type 'char [17]'
Any ideas?
I'm new with C/C++ and I thought this could be a fun place to start.
I'm on MacOS Monterrey 12.0.1
Thanks!!!
Here is a more detailed error log:
/Users/agustinmachiavello/softwareprojects/butano/butano/include/bn_span.h:480:9: in 'constexpr' expansion of '_bn::assert::file_name<10>(((const char*)"/Users/agustinmachiavello/softwareprojects/butano/butano/include/bn_span.h"))' /Users/agustinmachiavello/softwareprojects/butano/butano/include/bn_assert.h:171:35: error: array subscript value '17' is outside the bounds of array type 'char [17]' make[2]: *** [common_stats.o] Error 1 make[2]: *** [main.o] Error 1 make[1]: *** [build] Error 2 make: *** [all] Error 2
graphics/dynamic_nums.bmp
#include "bn_core.h"
#include "bn_log.h"
#include "bn_regular_bg_item.h"
#include "bn_regular_bg_map_cell_info.h"
#include "bn_regular_bg_map_ptr.h"
#include "bn_regular_bg_ptr.h"
// graphics/dynamic_nums.bmp
#include "bn_regular_bg_items_dynamic_nums.h"
const bn::regular_bg_item& dynamic_nums = bn::regular_bg_items::dynamic_nums;
struct dynamic_nums_bg
{
char padding[2];
/* alignas(4) */ bn::regular_bg_map_cell cells[1024];
bn::regular_bg_map_item map_item;
bn::regular_bg_item bg_item;
bn::regular_bg_ptr bg;
bn::regular_bg_map_ptr bg_map;
dynamic_nums_bg()
: cells{}, map_item(cells[0], bn::size(32, 32)),
bg_item(dynamic_nums.tiles_item(), dynamic_nums.palette_item(), map_item),
bg(bg_item.create_bg(128 - 120, 128 - 80)), bg_map(bg.map())
{
BN_LOG("alignof(bn::regular_bg_map_cell) == ", alignof(bn::regular_bg_map_cell));
BN_LOG("alignof(cells) == ", alignof(cells)); // GNU Extension warning, but it's nice to show the error.
set_cells_in_order();
}
void set_cells_in_order()
{
for (int y = 0; y < 4; ++y)
for (int x = 0; x < 32; ++x)
{
const int cell_index = map_item.cell_index(x, y);
bn::regular_bg_map_cell& cell = cells[cell_index];
bn::regular_bg_map_cell_info cell_info(cell);
cell_info.set_tile_index(cell_index);
cell = cell_info.cell();
}
bg_map.reload_cells_ref();
}
};
int main()
{
bn::core::init();
dynamic_nums_bg bg;
while (true)
bn::core::update();
}
[WARN] GBA Debug: alignof(bn::regular_bg_map_cell) == 2
[WARN] GBA Debug: alignof(cells) == 2
[WARN] GBA Debug: alignof(bn::regular_bg_map_cell) == 2
[WARN] GBA Debug: alignof(cells) == 4
In general, I think it is always ok to stop something not running.
But in this case, it seams worst because I didn't see any bn::music::isPlaying()
method, or something like this, so, you can't know if it's possible to stop the music...
.
Edit: Sorry, there is a bn::music::playing()
. It's late, I'm probably too tired... Still, I think it's ok to stop something not running. It would avoid a useless test. bn::sound::stop_all()
don't raise any error.
I'm not sure but I think those methods:
void stop()
bool paused()
void pause()
void resume()
int position()
void set_position(int position)
should be available in bn::music_item
also ??
Hi,
I was wondering if there are specific resources included intended for 3D development. Something geometrically simple, similar to PSX or Minecraft.
Skeletons, animation controllers and collisions perhaps?
I was inspired by the recent impressive port of OpenLara for GBA. It clearly shows this console is able to manage 3D graphics, even if a lot of optimization is needed.
Thanks in advance.
Hi, I've tried to compile some of your examples (sprites and windows) but when I tried to compile this error happened :
linking cartridge
/opt/devkitpro/devkitARM/bin/../lib/gcc/arm-none-eabi/12.1.0/../../../../arm-none-eabi/bin/ld: bn_hw_audio.bn_noflto.o: in function `bn::hw::audio::init(void (*)(), void (*)())':
/Users/usr/Documents/gbadev/butano-10.3.0/butano/hw/src/bn_hw_audio.bn_noflto.cpp:200: undefined reference to `_bn_audio_soundbank_bin'
collect2: error: ld returned 1 exit status
make[2]: *** [/Users/usr/Documents/gbadev/butano-10.3.0/examples/windows/windows.elf] Error 1
make[1]: *** [build] Error 2
make: *** [all] Error 2
I'm using MacOS Monterey 12.4 with devkitproARM updated at the latest version. How can I fix this?
I'm still confused about the docs on bn::regular_bg_ptr::set_visible(bool)
.
void set_visible(bool visible)
Sets if this regular background must be committed to the GBA or not.
https://gvaliente.github.io/butano/namespacebn_1_1bgs.html#a5cb214772bcaf49a87011baa6bfbbec4
int bn::bgs::used_items_count()
Returns the number of used background items.A background item which is hidden is not committed to the GBA, so there can be more than 4 background items.
At first glance, I thought calling bn::regular_bg_ptr::set_visible(false)
on some bgs would allow me to deallocate them,
so that I can have more than 4 unique regular bgs, but only up to 4 of them can be set as visible.
But clearly this is not how it works, as this code fails to do that.
#include "bn_bgs.h"
#include "bn_core.h"
#include "bn_log.h"
#include "bn_regular_bg_ptr.h"
#include "bn_vector.h"
// graphics/blue.bmp
#include "bn_regular_bg_items_blue.h"
int main() {
bn::core::init();
bn::vector<bn::regular_bg_ptr, 5> bgs;
for (int i = 0; i < 5; ++i) {
bgs.push_back(bn::regular_bg_items::blue.create_bg(0, 0));
// set_visible(false) for every single regular bg
bgs.back().set_visible(false);
BN_LOG("used_bg=", bn::bgs::used_items_count(), ", available_bg=", bn::bgs::available_items_count());
}
while (true)
bn::core::update();
}
[WARN] GBA Debug: used_bg=1, available_bg=3
[WARN] GBA Debug: used_bg=2, available_bg=2
[WARN] GBA Debug: used_bg=3, available_bg=1
[WARN] GBA Debug: used_bg=4, available_bg=0
Same goes for affine bgs and sprites.
Does "committed to the GBA" mean something different?
Or am I missing something else?
Looks like LinkUniversal.hpp has been added to gba-link-connection, which you can use to support both link cable and the wireless adapter.
It would be nice to update to this instead of current LinkConnection.h
#include "bn_bitset.h"
#include "bn_core.h"
int main() {
bn::core::init();
bn::bitset<16> flags;
bn::bitset<32> another_flags;
while (true)
bn::core::update();
}
In file included from ../src/main.cpp:1:
../butano/include/bn_bitset.h: In instantiation of 'class bn::bitset<32>':
../src/main.cpp:7:20: required from here
../butano/include/bn_bitset.h:716:43: error: ambiguating new declaration of 'constexpr bn::bitset<32> bn::operator&(const ibitset&, const ibitset&)'
716 | [[nodiscard]] constexpr friend bitset operator&(const ibitset& a, const ibitset& b)
| ^~~~~~~~
../butano/include/bn_bitset.h:716:43: note: old declaration 'constexpr bn::bitset<16> bn::operator&(const ibitset&, const ibitset&)'
../butano/include/bn_bitset.h:726:43: error: ambiguating new declaration of 'constexpr bn::bitset<32> bn::operator|(const ibitset&, const ibitset&)'
726 | [[nodiscard]] constexpr friend bitset operator|(const ibitset& a, const ibitset& b)
| ^~~~~~~~
../butano/include/bn_bitset.h:726:43: note: old declaration 'constexpr bn::bitset<16> bn::operator|(const ibitset&, const ibitset&)'
../butano/include/bn_bitset.h:736:43: error: ambiguating new declaration of 'constexpr bn::bitset<32> bn::operator^(const ibitset&, const ibitset&)'
736 | [[nodiscard]] constexpr friend bitset operator^(const ibitset& a, const ibitset& b)
| ^~~~~~~~
../butano/include/bn_bitset.h:736:43: note: old declaration 'constexpr bn::bitset<16> bn::operator^(const ibitset&, const ibitset&)'
bn::utf8_character::size()
returns 0
for ASCII characters.
#include <bn_core.h>
#include <bn_utf8_character.h>
#include <bn_log.h>
int main() {
bn::core::init();
bn::string_view test = "E한";
bn::utf8_character chEng(test[0]);
bn::utf8_character chKor(test[1]);
BN_LOG("chEng('",test.substr(0, 1), "') : size=", chEng.size());
BN_LOG("chKor('",test.substr(1, 3), "') : size=", chKor.size());
while (true)
bn::core::update();
}
[WARN] GBA Debug: chEng('E') : size=0
[WARN] GBA Debug: chKor('한') : size=3
Whenever I try to change directory to varooom 3d and use sudo make -j8
I get the error
/home/mystuff/butano/butano/butano.mak:10: *** "DEVKITARM and WONDERFUL_TOOLCHAIN not found". Stop
butano/butano/include/bn_sprite_font.h
Line 121 in 0e5c422
bn::sprite_font
with thousands of utf-8 characters.
butano/butano/include/bn_sprite_font.h
Lines 200 to 213 in 0e5c422
for
loop here may need optimization to reduce operation counts.
Chinese font with 3500 chracters
Japanese font with 1945 characters
main.cpp
In file included from C:/Users/laqie/Projects/gba-dev-best-practice/source/common-text/src/main.cpp:7:
c:\users\laqie\projects\butano\common\include\common_cn_variable_16x16_sprite_font.h:26:52: in 'constexpr' expansion of 'bn::sprite_font(bn::sprite_items::common_cn_variable_16x16, bn::span<const bn::string_view>(common::cn::variable_16x16_sprite_font_utf8_characters), bn::span<const signed char>(common::cn::variable_16x16_sprite_font_character_widths))'
C:/Users/laqie/Projects/butano/butano/include/bn_sprite_font.h:85:71: in 'constexpr' expansion of '((bn::sprite_font*)this)->bn::sprite_font::sprite_font((* & item), (* & utf8_characters_ref), (* & character_widths_ref), 0)'
C:/Users/laqie/Projects/butano/butano/include/bn_sprite_font.h:121:9: in 'constexpr' expansion of '((bn::sprite_font*)this)->bn::sprite_font::_duplicated_utf8_characters()'
C:/Users/laqie/Projects/butano/butano/include/bn_sprite_font.h:209:22: in 'constexpr' expansion of 'bn::operator==((* & a), (* & b))'
C:/Users/laqie/Projects/butano/butano/include/bn_string_view.h:425:28: in 'constexpr' expansion of '(& b)->bn::string_view::size()'
c:\users\laqie\projects\butano\common\include\common_cn_variable_16x16_sprite_font.h:26:52: error: 'constexpr' evaluation operation count exceeds limit of 33554432 (use '-fconstexpr-ops-limit=' to increase the limit)
26 | variable_16x16_sprite_font_character_widths);
| ^
In file included from C:/Users/laqie/Projects/butano/butano/include/bn_sprite_font.h:17,
from C:/Users/laqie/Projects/butano/butano/include/bn_sprite_text_generator.h:19,
from C:/Users/laqie/Projects/gba-dev-best-practice/source/common-text/src/main.cpp:4:
c:\users\laqie\projects\butano\common\include\common_jp_variable_16x16_sprite_font.h:26:52: in 'constexpr' expansion of 'bn::sprite_font(bn::sprite_items::common_jp_variable_16x16, bn::span<const bn::string_view>(common::jp::variable_16x16_sprite_font_utf8_characters), bn::span<const signed char>(common::jp::variable_16x16_sprite_font_character_widths))'
C:/Users/laqie/Projects/butano/butano/include/bn_sprite_font.h:85:71: in 'constexpr' expansion of '((bn::sprite_font*)this)->bn::sprite_font::sprite_font((* & item), (* & utf8_characters_ref), (* & character_widths_ref), 0)'
C:/Users/laqie/Projects/butano/butano/include/bn_sprite_font.h:121:9: in 'constexpr' expansion of '((bn::sprite_font*)this)->bn::sprite_font::_duplicated_utf8_characters()'
C:/Users/laqie/Projects/butano/butano/include/bn_sprite_font.h:209:22: in 'constexpr' expansion of 'bn::operator==((* & a), (* & b))'
C:/Users/laqie/Projects/butano/butano/include/bn_string_view.h:430:23: error: 'constexpr' evaluation operation count exceeds limit of 33554432 (use '-fconstexpr-ops-limit=' to increase the limit)
430 | const_pointer a_data = a.data();
| ^~~~~~
make[2]: *** [/opt/devkitpro/devkitARM/base_rules:80: main.o] Error 1
make[1]: *** [/home/laqie/Projects/butano/butano/butano.mak:165: build] Error 2
make: *** [/home/laqie/Projects/butano/butano/butano.mak:160: all] Error 2
Note: This issue is opened according to #18 (comment).
I think the stats class (in common_stats.cpp
) should ignore the cpu usage when _counter == 60
because it includes the process of the stats class. On my project, it add 4-5%...
/opt/devkitpro/devkitARM/bin/../lib/gcc/arm-none-eabi/10.2.0/../../../../arm-none-eabi/bin/ld: btn_hw_audio.o: in function btn::hw::audio::init()': /home/farlandercraft/2Drive/GBADev/butano/butano/hw/src/btn_hw_audio.cpp:139: undefined reference to
_btn_audio_soundbank_bin'
collect2: error: ld returned 1 exit status
make[1]: *** [/opt/devkitpro/devkitARM/gba_rules:25: /home/farlandercraft/2Drive/GBADev/butano/tests/tests.elf] Error 1
make: *** [/home/farlandercraft/2Drive/GBADev/butano/butano/butano.mak:137: build] Error 2
I get an error saying "butano/hw/src/btn_hw_audio.cpp:139: undefined reference to _btn_audio_soundbank_bin
"
every time I try to build any of the examples, or Butano Fighter. Please fix this soon ;-; ...
(Arch Linux, Kernel 5.9.1-arch1-1, gcc version 10.2.0.)
Unfortunately, this is NOT fixed in the 228b503.
Here's the patch that reproduces this issue.
vgm_intr_vblank_failed_2.zip
hash for the bn::type_id_t
is missing for some reason?
namespace bn {
template <>
struct hash<type_id_t> {
[[nodiscard]] constexpr unsigned operator()(type_id_t value) const {
return hash<unsigned>()(unsigned(value.internal_id()));
}
};
} // namespace bn
Hello Butano development team! Sorry to open an issue on this, but I didn't see contact information for any of the developers.
I think Butano is a fantastic project, but as a regular user of CMake over Makefiles, I find myself desperately wanting a CMake equivalent for the toolchain.
Is there any interest in this at all within the Butano team? The current makefile toolchain seems to be quite straightforward, so I was thinking that I could take some time, write up some basic CMake project structure, and then open a PR.
I'd rather not take the time to do this if the Butano team is not interested, however. I'd envision this as an either/or sort of thing -- We would leave the Makefiles as-is, and then for those that use CMake extensively for project management we could provide the CMake bindings.
Theoretically Butano could work with CMake as-is if inserted as an external project, but if I'm being entirely honest that's not particularly pretty.
But either way, if this isn't something that you would like to integrate, feel free to tell me to buzz off.
I have a song-A
that uses both the music & dmg_music channels with sync enabled.
In my game, I need this use-case:
song-A
song-B
for a bitsong-A
from where it's stopped.In order to do this, I tried to save both the bn::dmg_music::position()
and bn::music::position()
.
But when I restore these positions and resume the song-A
, the sync breaks and one of the channel plays the song super fast.
Is there any way to work around this?
#include <bn_audio.h>
#include <bn_core.h>
#include <bn_dmg_music.h>
#include <bn_dmg_music_position.h>
#include <bn_keypad.h>
#include <bn_music.h>
// `sync.s3m`
#include "bn_dmg_music_items_sync.h"
#include "bn_music_items.h"
bn::optional<bn::pair<bn::dmg_music_position, int>> savedBgmPositions;
void saveBgm() {
savedBgmPositions = {bn::dmg_music::position(), bn::music::position()};
bn::music::stop();
bn::dmg_music::stop();
}
void restoreBgm() {
bn::music_items::sync.play(0.25);
bn::dmg_music_items::sync.play();
bn::dmg_music::set_position(savedBgmPositions->first);
bn::music::set_position(savedBgmPositions->second);
savedBgmPositions.reset();
}
int main() {
bn::core::init();
bn::audio::set_dmg_sync_enabled(true);
bn::music_items::sync.play(0.25);
bn::dmg_music_items::sync.play();
while (true) {
if (bn::keypad::a_pressed()) {
if (savedBgmPositions)
restoreBgm();
else
saveBgm();
}
bn::core::update();
}
}
Line 10 in butano.mak should not be indented, or be indented using spaces.
When Make encounters a tab-indented $(...)
, it tries to parse it as part of a recipe, resulting in the error message recipe commences before first target
being shown, instead of the message about the missing environment variables.
Only "directives" like conditionals, includes, and variable assignments can be indented (with tab, indenting with spaces is fine outside of recipes). See GNU Make Error Messages.
BN_ASSERT
macro in -O0
flag is broken after 23f4ba2 (newlib removed).
It fails to link with "undefined reference to __assert_func
".
Giving linker flag -O0
in any example should reproduce this.
building sprites
example with -O0
Linking ROM...
.../arm-none-eabi/bin/ld.exe: main.o: in function `bn::degrees_lut_sin(bn::fixed_t<12>)':
/butano/butano/include/bn_math.h:186: undefined reference to `__assert_func'
.../arm-none-eabi/bin/ld.exe: main.o: in function `bn::sprite_rotate_loop_action::sprite_rotate_loop_action(bn::sprite_ptr const&, int, bn::fixed_t<12>)':
/butano/butano/include/bn_sprite_actions.h:617: undefined reference to `__assert_func'
.../arm-none-eabi/bin/ld.exe: main.o: in function `bn::sprite_scale_loop_action::sprite_scale_loop_action(bn::sprite_ptr const&, int, bn::fixed_t<12>)':
/butano/butano/include/bn_sprite_actions.h:1233: undefined reference to `__assert_func'
.../arm-none-eabi/bin/ld.exe: main.o: in function `bn::color::color(int, int, int)':
/butano/butano/include/bn_color.h:55: undefined reference to `__assert_func'
.../arm-none-eabi/bin/ld.exe: /butano/butano/include/bn_color.h:56: undefined reference to `__assert_func'
.../arm-none-eabi/bin/ld.exe: main.o:/butano/butano/include/bn_color.h:57: more undefined references to `__assert_func' follow
collect2.exe: error: ld returned 1 exit status
make[2]: *** [/butano/butano/butano.mak:69: /butano/examples/sprites/sprites.elf] Error 1
make[1]: *** [/butano/butano/butano.mak:202: build] Error 2
make: *** [/butano/butano/butano.mak:197: all] Error 2
Both GBT Player & VGM Player forgot to set the REG_SOUNDCNT_H |= SOUNDCNT_H_PSG_VOLUME_100;
The default volume for DMG is 25%, that's why DMG music is so quiet compared to Maxmod music.
https://gbadev.net/gbadoc/audio/registers.html#direct-sound-output-control-register
https://gbadev.net/tonc/sndsqr.html#sec-gbasnd
If you return a static local variable, link fails with undefined reference to __cxa_guard_acquire
, __cxa_guard_release
.
(I also got undefined reference to atexit
in my real code.)
This doesn't happen before 23f4ba2 (newlib removed).
class Singleton {
public:
static auto instance() -> Singleton& {
static Singleton inst;
return inst;
}
private:
Singleton() {}
};
int main() {
Singleton::instance();
}
Linking ROM...
.../arm-none-eabi/bin/ld.exe: main.o: in function `Singleton::instance()':
/test/src/main.cpp:6: undefined reference to `__cxa_guard_acquire'
.../arm-none-eabi/bin/ld.exe: /test/src/main.cpp:4: undefined reference to `__cxa_guard_release'
collect2.exe: error: ld returned 1 exit status
make[2]: *** [/butano/butano.mak:69: /test/test.elf] Error 1
make[1]: *** [/butano/butano.mak:202: build] Error 2
make: *** [/butano/butano.mak:197: all] Error 2
Hi,
I may not be fully understanding how Regular Backgrounds work.
I'm trying to compose a fullscreen screen background composed of 16x16 pixel tiles instead of what looks to be the default of 8x8 pixel tiles.
Is it possible to specify a different tile size?
Thanks
Is there any more convenient way for me to convert mod or it audio?
I'm not sure this is intended behavior or not, but it seems that both bn::generic_pool
and bn::pool
doesn't support storing const
objects?
#include "bn_core.h"
#include "bn_generic_pool.h"
#include "bn_pool.h"
int main() {
bn::core::init();
bn::pool<const int, 4> pool;
bn::generic_pool<sizeof(int), 4> generic_pool;
const int& num = pool.create(42);
pool.destroy(num);
const int& num2 = generic_pool.create<const int>(42);
generic_pool.destroy(num2);
while (true)
bn::core::update();
}
In file included from /test/src/main.cpp:3:
butano/butano/include/bn_pool.h: In instantiation of 'Type& bn::ipool<Type>::create(Args&& ...) [with Args = {int}; Type = const int]':
GameDev/butano/test/src/main.cpp:11:33: required from here
butano/butano/include/bn_pool.h:83:15: error: invalid conversion from 'const void*' to 'void*' [-fpermissive]
83 | ::new(result) Type(forward<Args>(args)...);
| ^~~~~~
| |
| const void*
In file included from \devkitpro\devkitarm\arm-none-eabi\include\c++\12.2.0\bits\stl_iterator.h:82,
from \devkitpro\devkitarm\arm-none-eabi\include\c++\12.2.0\bits\stl_algobase.h:67,
from \devkitpro\devkitarm\arm-none-eabi\include\c++\12.2.0\algorithm:60,
from /butano/butano/include/bn_algorithm.h:16,
from /butano/butano/include/bn_istring_base.h:16,
from /butano/butano/include/bn_assert.h:120,
from /butano/butano/include/bn_array.h:16,
from /butano/butano/include/bn_span.h:16,
from /butano/butano/include/bn_core.h:16,
from /test/src/main.cpp:1:
\devkitpro\devkitarm\arm-none-eabi\include\c++\12.2.0\new:174:65: note: initializing argument 2 of 'void* operator new(std::size_t, void*)'
174 | _GLIBCXX_NODISCARD inline void* operator new(std::size_t, void* __p) _GLIBCXX_USE_NOEXCEPT
| ~~~~~~^~~
/butano/butano/include/bn_pool.h: In instantiation of 'void bn::ipool<Type>::destroy(Type&) [with Type = const int]':
/test/src/main.cpp:12:17: required from here
/butano/butano/include/bn_pool.h:95:26: error: 'reinterpret_cast' from type 'const int*' to type 'char*' casts away qualifiers
95 | base_type::_free(reinterpret_cast<char*>(&value));
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /test/src/main.cpp:2:
/butano/butano/include/bn_generic_pool.h: In instantiation of 'Type& bn::igeneric_pool<MaxElementSize>::create(Args&& ...) [with Type = const int; Args = {int}; int MaxElementSize = 4]':
/test/src/main.cpp:14:53: required from here
/butano/butano/include/bn_generic_pool.h:184:15: error: invalid conversion from 'const void*' to 'void*' [-fpermissive]
184 | ::new(result) Type(forward<Args>(args)...);
| ^~~~~~
| |
| const void*
\devkitpro\devkitarm\arm-none-eabi\include\c++\12.2.0\new:174:65: note: initializing argument 2 of 'void* operator new(std::size_t, void*)'
174 | _GLIBCXX_NODISCARD inline void* operator new(std::size_t, void* __p) _GLIBCXX_USE_NOEXCEPT
| ~~~~~~^~~
/butano/butano/include/bn_generic_pool.h: In instantiation of 'void bn::igeneric_pool<MaxElementSize>::destroy(Type&) [with Type = const int; int MaxElementSize = 4]':
/test/src/main.cpp:15:25: required from here
/butano/butano/include/bn_generic_pool.h:199:15: error: 'reinterpret_cast' from type 'const int*' to type 'char*' casts away qualifiers
199 | _free(reinterpret_cast<char*>(&value));
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
make[2]: *** [/opt/devkitpro/devkitARM/base_rules:80: main.o] Error 1
make[1]: *** [/d/Library/butano/butano/butano.mak:181: build] Error 2
make: *** [/d/Library/butano/butano/butano.mak:176: all] Error 2
You can export custom waveform on s3m2gbt
.
You are allowed to replace the samples of the channel 3. If the resulting sample is exactly 32 or 64 samples long, you can pass the --instruments flag to s3m2gbt and it will export all valid instruments along the patterns of your song. They will replace the default instruments of GBT Player for the duration of the song.
But looks like Butano doesn't provide any option to enable it.
Related closed PR: #33
Trying to use shared_ptr fails with below error. std::unique_ptr works just fine though.
#include <memory>
int main()
{
std::make_shared<int>(42);
}
Make fails during linking:
$ make
main.cpp
Linking ROM...
/opt/devkitpro/devkitARM/bin/../lib/gcc/arm-none-eabi/13.2.0/../../../../arm-none-eabi/bin/ld: main.o: in function `std::_Sp_counted_ptr_inplace<int, std::allocator<void>, (__gnu_cxx::_Lock_policy)1>::_M_get_deleter(std::type_info const&)':
/opt/devkitpro/devkitARM/arm-none-eabi/include/c++/13.2.0/bits/shared_ptr_base.h:643:(.text._ZNSt23_Sp_counted_ptr_inplaceIiSaIvELN9__gnu_cxx12_Lock_policyE1EE14_M_get_deleterERKSt9type_info[_ZNSt23_Sp_counted_ptr_inplaceIiSaIvELN9__gnu_cxx12_Lock_policyE1EE14_M_get_deleterERKSt9type_info]+0xe): undefined reference to `std::_Sp_make_shared_tag::_S_eq(std::type_info const&)'
/opt/devkitpro/devkitARM/bin/../lib/gcc/arm-none-eabi/13.2.0/../../../../arm-none-eabi/bin/ld: main.o: in function `std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)1>::_M_release_last_use()':
/opt/devkitpro/devkitARM/arm-none-eabi/include/c++/13.2.0/bits/shared_ptr_base.h:182:(.text.startup.main+0x34): undefined reference to `__sync_synchronize'
/opt/devkitpro/devkitARM/bin/../lib/gcc/arm-none-eabi/13.2.0/../../../../arm-none-eabi/bin/ld: main.o: in function `__gnu_cxx::__exchange_and_add_dispatch(int*, int)':
/opt/devkitpro/devkitARM/arm-none-eabi/include/c++/13.2.0/ext/atomicity.h:101:(.text.startup.main+0x60): undefined reference to `__gnu_cxx::__exchange_and_add(int volatile*, int)'
/opt/devkitpro/devkitARM/bin/../lib/gcc/arm-none-eabi/13.2.0/../../../../arm-none-eabi/bin/ld: /opt/devkitpro/devkitARM/arm-none-eabi/include/c++/13.2.0/ext/atomicity.h:101:(.text.startup.main+0x72): undefined reference to `__gnu_cxx::__exchange_and_add(int volatile*, int)'
collect2: error: ld returned 1 exit status
make[2]: *** [butano/examples/core/core.elf] Error 1
make[1]: *** [build] Error 2
make: *** [all] Error 2
The above error path contains butano/examples/core/
because that's the example folder I repurposed for this test.
I'm using butano 15.8.2, devkitpro v6.0.2, and macOS 13.2.1 if that matters.
Currently, you can use fixed_t<Precision>
to set the number of bits to be used for the fractional part of a "poor man's float." There is a an alias fixed
for fixed_t<12>
.
There are other classes that would benefit from a configurable precision, most notably fixed_point
. This 2D pair holds two fixed
members. However, this is locked at the default 12 bits of fractional precision. It would be nice to instead have a fixed_point_t<Precision>
, and have fixed_point
be an alias for fixed_point_t<12>
. This would allow anyone wanting a different precision to use the underlying fixed_point_t
.
I would be happy to give implementing this a try if desired, though I am somewhat new to C++ and my PR would likely need a fair amount of feedback.
Alternatively, is there some simpler way that I'm missing to do this? Thanks!
Hello, if I want to add new utf-8 char in this engine, how can I do it?
This might be a bit of a niche request, but it would be nice to have a way to write code that is executed when an assert or error is failed for testing/development purposes. That way developers can log additional diagnostic information.
Of course, one could simply define BN_ASSERT
or BN_ERROR
themselves, but it would be nice to not have to copy and paste the existing implementation.
Perhaps there could be a definable macro placed next to _bn::assert::show
and _bn::assert::show_args
like BN_CFG_ON_ASSERT_FAIL
and BN_CFG_ON_ERROR
that the user could define to inject code into the assert (+error)?
butano/butano/include/bn_sprite_font.h
Lines 113 to 127 in bbbe241
C:/Users/laqie/Projects/butano/butano/include/bn_sprite_font.h:85:71: in 'constexpr' expansion of '((bn::sprite_font*)this)->bn::sprite_font::sprite_font((* & item), (* & utf8_characters_ref), (* & character_widths_ref), 0)'
C:/Users/laqie/Projects/butano/butano/include/bn_assert.h:96:21: error: call to non-'constexpr' function 'void __assert_func(const char*, int, const char*, const char*)'
96 | assert(condition); \
| ^~~~~~
C:/Users/laqie/Projects/butano/butano/include/bn_sprite_font.h:114:9: note: in expansion of macro 'BN_ASSERT'
114 | BN_ASSERT(item.tiles_item().graphics_count() >= minimum_graphics + utf8_characters_ref.size(),
| ^~~~~~~~~
c:\devkitpro\devkitarm\arm-none-eabi\include\assert.h:41:6: note: 'void __assert_func(const char*, int, const char*, const char*)' declared here
41 | void __assert_func (const char *, int, const char *, const char *)
| ^~~~~~~~~~~~~
C:/Users/laqie/Projects/butano/butano/include/bn_sprite_font.h:85:71: in 'constexpr' expansion of '((bn::sprite_font*)this)->bn::sprite_font::sprite_font((* & item), (* & utf8_characters_ref), (* & character_widths_ref), 0)'
C:/Users/laqie/Projects/butano/butano/include/bn_sprite_font.h:120:9: in 'constexpr' expansion of '((bn::sprite_font*)this)->bn::sprite_font::_validate_utf8_characters()'
C:/Users/laqie/Projects/butano/butano/include/bn_sprite_font.h:180:64: in 'constexpr' expansion of 'utf8_char.bn::utf8_character::utf8_character((& utf8_character_text)->bn::string_view::data())'
C:/Users/laqie/Projects/butano/examples/text/include/fixed_32x64_sprite_font.h:17:84: in 'constexpr' expansion of 'bn::utf8_character((* text_ptr))'
C:/Users/laqie/Projects/butano/butano/include/bn_assert.h:118:21: error: call to non-'constexpr' function 'void __assert_func(const char*, int, const char*, const char*)'
118 | assert(false); \
| ^~~~~~
C:/Users/laqie/Projects/butano/butano/include/bn_utf8_character.h:113:13: note: in expansion of macro 'BN_ERROR'
113 | BN_ERROR("Invalid UTF-8 character");
| ^~~~~~~~
c:\devkitpro\devkitarm\arm-none-eabi\include\assert.h:41:6: note: 'void __assert_func(const char*, int, const char*, const char*)' declared here
41 | void __assert_func (const char *, int, const char *, const char *)
| ^~~~~~~~~~~~~
C:/Users/laqie/Projects/butano/butano/include/bn_sprite_font.h:85:71: in 'constexpr' expansion of '((bn::sprite_font*)this)->bn::sprite_font::sprite_font((* & item), (* & utf8_characters_ref), (* & character_widths_ref), 0)'
C:/Users/laqie/Projects/butano/butano/include/bn_assert.h:96:21: error: call to non-'constexpr' function 'void __assert_func(const char*, int, const char*, const char*)'
96 | assert(condition); \
| ^~~~~~
C:/Users/laqie/Projects/butano/butano/include/bn_sprite_font.h:122:9: note: in expansion of macro 'BN_ASSERT'
122 | BN_ASSERT(character_widths_ref.empty() ||
| ^~~~~~~~~
c:\devkitpro\devkitarm\arm-none-eabi\include\assert.h:41:6: note: 'void __assert_func(const char*, int, const char*, const char*)' declared here
41 | void __assert_func (const char *, int, const char *, const char *)
| ^~~~~~~~~~~~~
Attached is a minimum reproducible example of what is happening. In the example, you'd expect the tiles to cycle blue -> yellow -> green -> red, but on yellow and green tiles erroneously set their neighbor to 1 more than what they are (tile 1, or blank, in this case)
For better readability and quicker typing, is it possible to invoke the library methods like this?
bn.core.init();
bn.regular_bg_ptr background = bn.regular_bg_items.gba.create_bg(0, 0);
bn.sprite_ptr up_sprite = bn.sprite_items.up_button.create_sprite(-63, -47);
...
The discord.io/gbadev (discord invite) is not working.
It seems as though you cannot use the text classes to render Japanese text, am I correct in assuming this?
I'd like to switch smoothly between 2 color palette. It does not seams to be possible.
Just to try, I made "bn_palettes_manager.h" and "palette_bank.h" public and I use bn::palettes_manager::bg_palettes_bank().set_colors(0,colors);
It seams to work, but it would be nice to be able to do that with vanilla code.
I tried to add value_template_actions
to my own Entity
class, but it seems that every action template copies it by value.
butano/butano/include/bn_value_template_actions.h
Lines 94 to 95 in 10f3688
This effectively copies the Entity
, thus there's a duplicated copy of instances in the game.
So this template would work only if the copy of Value
shares the members with the original, but it's generally not the case in my opinion.
And also, my Entity
is actually an abstract class, so I can't use this at all.
I could easily copy these and change it to store Value&
instead, but it would be nice if they are in the Butano directly.
Could you provide VS Solution? I'd like to make some tests making a .DLL and creating a Unity Engine Plugin so it can be used directly with the engine
bn::best_fit_allocator::create<T>()
uses BN_BASIC_ASSERT
and bn::forward<Args>(args)...
.
butano/butano/include/bn_best_fit_allocator.h
Lines 151 to 153 in ae32d97
bn_best_fit_allocator.h
doesn't include bn_assert.h
nor bn_utility.h
.bn_best_fit_allocator.h
.
main.cpp
#include <bn_core.h>
void best_fit_alloc_test();
int main() {
bn::core::init();
best_fit_alloc_test();
while (true)
bn::core::update();
}
best_fit_alloc_test.cpp
#include <bn_best_fit_allocator.h>
void best_fit_alloc_test() {
char myBuffer[16];
bn::best_fit_allocator myHeap(myBuffer, sizeof(myBuffer));
auto& num = myHeap.create<int>(42);
myHeap.destroy(num);
}
In file included from test/src/best_fit_alloc_test.cpp:1:
butano/butano/include/bn_best_fit_allocator.h: In instantiation of 'Type& bn::best_fit_allocator::create(Args&& ...) [with Type = int; Args = {int}]':
test/src/best_fit_alloc_test.cpp:5:35: required from here
butano/butano/include/bn_best_fit_allocator.h:151:24: error: 'BN_BASIC_ASSERT' was not declared in this scope
151 | BN_BASIC_ASSERT(result, "Allocation failed");
| ~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
butano/butano/include/bn_best_fit_allocator.h:153:39: error: 'forward' was not declared in this scope
153 | new(result) Type(forward<Args>(args)...);
| ~~~~~~~~~~~~~^~~~~~
When you import a bpp_8 image, if the image only use less than 16 colors, its palette will be automatically switched to bpp_4. I totally understand why and you can force to use a 256 colors by using the palette_item option, it works fine.
Doing that, it is possible to use the same image to switch between a 16 colors image to 256 colors image just with a palette switch but it would be easier if it was possible to disable this optimization.
But my main problem is, if multiple color "slots" in the palette are the same, it seams that the import process "merge" all those colors in the image. I can't see any workaround for this (I tried to slightly change the color but they are 24bits, and I guess, when translated to 15bits, they are still the same, I guess it would work by changing them more so they are not the same in 15bits, but I don't really want to).
Again here, I totally understand why the behaviour is like this but it a problem for what I try to do.
It would be great to have an option to disable this optimization.
This is probably a very minor issue in the context of GBA game development, but maybe worth pointing out.
When calling random.get_int(int limit)
, if limit
is not a factor of numeric_limits<int>::max()
then there will be a bias towards smaller numbers due to modulo bias. There are a couple of ways I can think of to address this:
get_int
to use one of the suggested fixes from the linked article. However, this comes at the cost of worse speed.In any case, thanks for the great library! I'm having fun with it~
butano/butano/include/bn_random.h
Line 40 in 8d16ff3
Would like to request that the [[nodiscard]] here be removed as it could be useful to progress the internal state of the RNG while ignoring the return value.
If I understand correctly, bn::optional<T>::emplace()
is the only option to create a bn::optional<T>
object which contains actual value, when T
contains const member variable(s).
std::optional<T>::emplace()
supports this, but bn::optional<T>::emplace()
doesn't.
Because bn::optional<T>::emplace()
uses operator=
internally, but T
can't have assignment operators, as it has const member variable(s).
#include "bn_core.h"
#include "bn_log.h"
#include "bn_optional.h"
class Test
{
const int num_;
public:
Test(int num) : num_(num) {}
int GetNum() const { return num_; }
};
int main()
{
bn::core::init();
bn::optional<Test> a;
// error: use of deleted function 'Test& Test::operator=(Test&&)'
a.emplace(42);
BN_LOG(a->GetNum());
while (true)
bn::core::update();
}
#include <iostream>
#include <optional>
class Test
{
const int num_;
public:
Test(int num) : num_(num) {}
int GetNum() const { return num_; }
};
int main()
{
std::optional<Test> a;
// no issue
a.emplace(42);
std::cout << a->GetNum();
return 0;
}
Provide a template specialization for bn::array<T, 0>
(Zero-sized, empty array).
In my current game, I'm generating constexpr MTilemap
instances to store meta-tilemap information in ROM.
To do this, I'm storing bunch of bn::array<SpawnPointType, Count>
instances like below:
// Meta-tilemap struct to hard-coded in ROM.
// The instance of this class will be generated with auto-tilemap generation Python script.
template <int MWidth, int MHeight, int MobCount, int ItemCount, int MCellDecoCount, int DecoCount>
struct MTilemap : MTilemapBase
{
private:
const bn::array<MobSpawnPoint, MobCount> _mobSpawnPoints;
const bn::array<ItemSpawnPoint, ItemCount> _itemSpawnPoints;
const bn::array<MCellDecoSpawnPoint, MCellDecoCount> _mCellDecoSpawnPoints;
const bn::array<DecoSpawnPoint, DecoCount> _decoSpawnPoints;
const bn::array<MTileIndex, MWidth * MHeight> _board;
...
};
But if any of these Count
template arguments turns out to be zero, this MTilemap
struct won't work.
Because bn::array
doesn't support zero-sized arrays.
butano/butano/include/bn_array.h
Lines 25 to 28 in bc9d142
I could make a custom wrapper around bn::array
to deal with empty array, but it would be nice if it is supported directly on bn::array
.
So, could you please provide a template specialization for the bn::array<Type, 0>
, like the std::array
does?
Sorry, I am fairly new to butano, but I am having a lot of issues with the makefile that I can't seem to resolve, this being one of them. Am I using the wrong makefile? Did something install incorrectly?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.