Implemented A* pathfinding today :DDD
On a sidenote, rendering text with SDL2 is a pain in the ass if you aren't using any extra libraries like SDL_TTF, and even then it's still annoying because you have to load a font and render glyphs with it ahead of time; you can't just draw a string on the fly, you have to render the whole thing to a surface and blit it.
So I put together this beautiful monstrosity:
On a sidenote, rendering text with SDL2 is a pain in the ass if you aren't using any extra libraries like SDL_TTF, and even then it's still annoying because you have to load a font and render glyphs with it ahead of time; you can't just draw a string on the fly, you have to render the whole thing to a surface and blit it.
So I put together this beautiful monstrosity:
void DrawString(SDL_Renderer* renderer, const char* txt, int x, int y) {
static uint64_t font[] = {0x7cfc3cfcfefe3cc6,0x7e7ec6c0c6c67cfc,0x7cfc7cfcc6c6c6c6,0xccfe187c0000600c,0x0000c6c666c6c0c0,
0x66c61818ccc0eee6,0xc6c6c6c6c630c6c6,0xc6c6cc0618c60000,0x30180000c6c6c0c6,0xc0c0c0c61818d8c0,0xfef6c6c6c6c6c030,
0xc6c6c66ccc0c1806,0x00001830fc00fefc,0xc0c6f8f8c0fe1818,0xf0c0d6dec6c6c6c6,0x7030c6c6c6387818,0x180c00000c600000,
0xc6c6c0c6c0c0cec6,0x1818d8c0c6cec6fc,0xc6fc1c30c6c6d66c,0x3030181800000c60,0x0000c6c6c0c6c0c0,0xc2c61818ccc0c6c6,
0xc6c0c6c60630c6c6,0xfec6306018300000,0x1830fc00c6c666c6,0xc0c066c61818c6c0,0xc6c6c6c0ccc6c630,0xc66ceec630c00000,
0x180830180000c6fc,0x3cfcfec03cc67e70,0xc6fec6c67cc07ac6,0x7c307c38c6c630fe,0x18301818600c0000,0x0c0000007c187c7c,
0xccfe7cfe7c7c7c30,0x467c6c000000d8c0,0xe0e060c030c03060,0x3c3c0c000000c638,0xc6c6ccc0c606c6c6,0xc678e6d66c00c0c0,
0xd8c0c060c0606060,0x30604242183000cc,0xc6180606ccc0c006,0xc6c6c6cc4cd0fe00,0xc0c04840c060c060,0x6060303099991830,
0x00ccd6180c1cfe7c,0xfc0c7c7e6c001870,0x6c6c00009080c060,0xc060c0303030a1a5,0x30fcfc30d6181806,0x0c06c618c6063000,
0x301c6cd800000000,0xc060c06060603018,0xa1a5303000ccc618,0x30060c06c630c606,0xd8006416fe00c040,0x0000c060c0606060,
0x3018999d603000cc,0xc61860c60cc6c630,0xc6c6cc00ced66c00,0xc0c00000c060c060,0x6060300c42466000,0x00007c3cfe7c0c7c,
0x7c307c7c7600c47c,0x6c0000000000e0e0,0x60c030c0300c3c3c};
static const char* font_mapping = "abcdefghijklmnopqrstuvwxyz!?.,><= /+-*0123456789&^%$#~:;\"'[](){}|\\`@";
static SDL_Surface* font_surface = NULL;
static SDL_Texture* font_texture = NULL;
if (!font_surface) {
font_surface = SDL_CreateRGBSurfaceWithFormat(0, 272, 16, 32, SDL_PIXELFORMAT_ABGR8888);
for (int i = 0; i < 272 * 16; i++)
((uint32_t*)font_surface->pixels)[i] = ((font[i >> 6] >> (63 - (i & 63))) & 1) * 0xFFFFFFFF;
font_texture = SDL_CreateTextureFromSurface(renderer, font_surface);
}
for (int i = 0; i < strlen(txt); i++) {
const char* pos = strchr(font_mapping, tolower(txt[i]));
size_t ci = pos ? pos - font_mapping : 0;
SDL_Rect src_rect = {(ci % 34) * 8, (ci / 34) * 8, 8, 8};
SDL_Rect dst_rect = {x + i * 8, y, 8, 8};
SDL_RenderCopy(renderer, font_texture, &src_rect, &dst_rect);
}
}
I once shot a man in Reno, just to watch him die.
Decided to pick up an old project of mine again, mainly just something to keep me sober. It's based on a Doom-y engine I wrote in C++ a few years ago but I'm expanding it to support a bunch of things Doom couldn't, e.g. rooms over rooms, slopes, terrain, skeletal animations, etc.. most of which is done, I just need to finish up the level editor.
I also decided to give scripting a go. I took an old Scheme interpreter I wrote and tacked a few more things onto it, and now you can use it to programmatically generate level geometry in-game :D
Unlike Doom it doesn't revolve around traversing a BSP tree to render level geometry, and it doesn't use portals like Ken Silverman's Build engine either. Instead I opted for a more modern approach using constructive solid geometry, basically generating a static mesh out of the sector data and optimizing it to render w/ as few draw calls as possible.
Ig for reference, the old version looked something like this:
If I can get the new level editor finished up I hope to put the source on GitHub soon (or ideally Gitea if my instance still works, fuck Microsoft)
I once shot a man in Reno, just to watch him die.
That's really cool!! I'd really like to give graphics programming a go someday but I'm way too stuck in web dev hell... Integrating the scripting engine is also really neat. The lighting reminds me of an old Bisqwit video where he wrote an engine in C, although that used the Ken Silverman portals concept. Did you draw the mascot character in the about dialog yourself? If you do release this I'll definitely stick around to stalk the progress on it, maybe learn something from seeing it evolve.
Also I apologise for constantly plugging it lol but if you want a Patchii profile, just let me know! Because, yeah, fuck Microsoft. If I don't get Flashii ID logins working with that thing before the end of August I need to be thrown out of a window.
Also I apologise for constantly plugging it lol but if you want a Patchii profile, just let me know! Because, yeah, fuck Microsoft. If I don't get Flashii ID logins working with that thing before the end of August I need to be thrown out of a window.
That looks really cool! I don't have the balls or the know-how to make a 3d engine from scratch (I can barely explain what a sine is and all the math makes my head spin). Was this design just for its own sake or do you know anyone (including yourself) who plans to make a game on it?
By the way, I know I'm about to make a double post but F--K the etiquette and the rules never mention double posts. Henceforth I am declaring right now happy hour where double posting is allowed. Since you mentioned the inconvenience of rendering text in SDL (this also applies to raw OpenGL) I would like to offer a description of the algorithm I made to solve this problem. Essentially the idea is to cache an arbitrary number of glyphs pre-rendered and use them to make textures. The algorithm operates very quickly, in worst case on linear time though in short order.
Essentially I instantiate a hashmap with the keys being chars and the values being pointers to the glyphs to be rendered, and a linked list containing all the glyphs that have been rendered so far (the linked list ought also to contain a head and tail pointer). Whenever a request is made to render a glyph to the screen, the corresponding char is attached to the front of the linked list. If the char is found in the hashmap then the glyph can be rendered from the resulting value; if not, then the font renderer must create a texture for the char and then add it to the hashmap. If the number of cached chars reaches maximum, then a fixed amount (I chose 25%) at the tail end of the linked list is removed, as well as the hash map entries, and the rendered glyphs are also disposed of. This system is according to my calculations very efficient at caching Hanzi and other ideographic writing systems. Whether chinese and japanese texts lexically follow Zipf's law is irrelevant in this case, we're only concerned about using the cache space efficiently for individual characters.
Essentially I instantiate a hashmap with the keys being chars and the values being pointers to the glyphs to be rendered, and a linked list containing all the glyphs that have been rendered so far (the linked list ought also to contain a head and tail pointer). Whenever a request is made to render a glyph to the screen, the corresponding char is attached to the front of the linked list. If the char is found in the hashmap then the glyph can be rendered from the resulting value; if not, then the font renderer must create a texture for the char and then add it to the hashmap. If the number of cached chars reaches maximum, then a fixed amount (I chose 25%) at the tail end of the linked list is removed, as well as the hash map entries, and the rendered glyphs are also disposed of. This system is according to my calculations very efficient at caching Hanzi and other ideographic writing systems. Whether chinese and japanese texts lexically follow Zipf's law is irrelevant in this case, we're only concerned about using the cache space efficiently for individual characters.
tysm flash/Sangui! I can't take credit for the drawing, it's pretty much an AI-traced placeholder until I can find an artist to commission (which I want to do cuz AI is nasty)
To answer your question Sangui, I do have a game in the works (le secret) with the previous version of the engine (and probably keeping it that way so much as to not get distracted), but I think my goal with this new one is to make a fun sandbox more than anything else. The reasoning behind using this kind of map system is that it's absurdly easy to edit with, and I think that kind of ease-of-use is something we don't see enough of anymore. Compare the experience of using DoomBuilder to Hammer, DoomBuilder has its faults but Hammer is a tremendous pain in the ass by comparison.
Growing up I used to play a game called Cube 2: Sauerbraten a lot, it wasn't ever the most popular thing, but it featured real-time in-game co-op map editing in addition to old school Quake-style FPS gameplay, a concept I think has a lot of potential but unfortunately will never see much popularity due to the old and kinda janky nature of the engine. Interestingly, rather than using sectors, portals, brushes, etc. its map system is comprised of an octree you "carve out" to make level geometry with. It's fun, but not as intuitive as it could be. In any case, if I make a "game" with this engine it'll probably be something more akin to that: a simple shooter that's hackable and easy to make silly maps for.
In other words it should be really easy to make stupid shit like this:
On a sidenote, that system you mentioned for glyph caching sounds efficient! I never really considered optimizing for different writing systems. My engine just does it the braindead way and makes an atlas filled with standard ASCII glyphs, and if you need something besides ASCII, get bent I guess lol. Writing a better text renderer in the future could be a fun project, and I'll consider your algo :3
To answer your question Sangui, I do have a game in the works (le secret) with the previous version of the engine (and probably keeping it that way so much as to not get distracted), but I think my goal with this new one is to make a fun sandbox more than anything else. The reasoning behind using this kind of map system is that it's absurdly easy to edit with, and I think that kind of ease-of-use is something we don't see enough of anymore. Compare the experience of using DoomBuilder to Hammer, DoomBuilder has its faults but Hammer is a tremendous pain in the ass by comparison.
Growing up I used to play a game called Cube 2: Sauerbraten a lot, it wasn't ever the most popular thing, but it featured real-time in-game co-op map editing in addition to old school Quake-style FPS gameplay, a concept I think has a lot of potential but unfortunately will never see much popularity due to the old and kinda janky nature of the engine. Interestingly, rather than using sectors, portals, brushes, etc. its map system is comprised of an octree you "carve out" to make level geometry with. It's fun, but not as intuitive as it could be. In any case, if I make a "game" with this engine it'll probably be something more akin to that: a simple shooter that's hackable and easy to make silly maps for.
In other words it should be really easy to make stupid shit like this:
On a sidenote, that system you mentioned for glyph caching sounds efficient! I never really considered optimizing for different writing systems. My engine just does it the braindead way and makes an atlas filled with standard ASCII glyphs, and if you need something besides ASCII, get bent I guess lol. Writing a better text renderer in the future could be a fun project, and I'll consider your algo :3
I once shot a man in Reno, just to watch him die.