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);
}
}
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)
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.
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.
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 made a dumb silly simple thing.
Oh also there's a slightly more useful endpoint
which just returns your IP as a raw text string. I know there are infinite sites like this but I just think it's fun.
The instructions are the last resort.
start
welp, the time has come. my personal website is long overdue a redesign and i started working on it recently.
for now i'm not gonna share any code or screenshots, cause everything is still kind of messy, but the base idea i have is a kind of mask design, with three columns showing the same logo shape but with different style of logo and background and separate content for each. one column per major hobby category.
i'm kind of broken between making it interactive or more of a static page design - i even wrote a whole overengineered parallax tilt&move component which looks great, but right now i'm basically scrapping that to have pure CSS stuff. okay not entirely pure, i'm also trying out new stuff a bit more, like scss.
it's pretty fun so far, and i'm not just aimlessly wandering around - i still have some diverging ideas i could go with for each column (cause i'm trying to make each one unique), but unlike last time i know exactly what i want to do for the core design, and that it's achievable.
i'll send updates when it's at a very-early-wip-works-okay state.
update 1
played around with scss and gsap for the past couple of days, both are pretty cute, but i decided the effects i wanna go for inside the columns will need some more flair so fuck it im gonna go with three fiber again