raii and some memory savings

This commit is contained in:
maksw authored and Maksymilian Wilczynski committed 2025-12-17 21:34:59 +01:00
1 parent 333ebca300
commit 0c24781c81
2 files changed
+203 -121

No files matched your search

+201 -121
View File
@@ -1,20 +1,58 @@
#include <cstdio> // this file is an absolute clusterfuck to demo the internals.
// if you know any better please make a pr. please.
// i hate lines++; but i don't know any better, do i look like i know frontend?
// branching? use arbitrary lines value, do i look like i know any better?
#include <cstdio>
#include <cstdint> #include <cstdint>
#include <cstring> #include <cstring>
#include <chrono> #include <chrono>
#include <vector> #include <vector>
#include <memory>
#include <window.h> #include <window.h>
#include <text.h> #include <text.h>
#include <compositor.h> #include <compositor.h>
#include <image.h> #include <image.h>
// --- RAII wrappers for engine objects ---
struct WindowHandle {
window_t* ptr;
WindowHandle(window_t* w) : ptr(w) {}
~WindowHandle() { if (ptr) window_destroy(ptr); }
window_t* get() { return ptr; }
operator window_t* () { return ptr; }
};
struct CompositorHandle {
compositor_t* ptr;
CompositorHandle(compositor_t* c) : ptr(c) {}
~CompositorHandle() { if (ptr) compositor_destroy(ptr); }
compositor_t* get() { return ptr; }
operator compositor_t* () { return ptr; }
};
struct TextHandle {
text_t* ptr;
TextHandle(text_t* t) : ptr(t) {}
~TextHandle() { if (ptr) text_destroy(ptr); }
text_t* get() { return ptr; }
operator text_t* () { return ptr; }
};
struct ImageHandle {
uint32_t* ptr;
ImageHandle(uint32_t* p) : ptr(p) {}
~ImageHandle() { if (ptr) image_free(ptr); }
uint32_t* get() { return ptr; }
operator uint32_t* () { return ptr; }
};
int main() { int main() {
const int WIDTH = 1280; const int WIDTH = 1280;
const int HEIGHT = 720; const int HEIGHT = 720;
const int CHAR_WIDTH = 400; const int CHAR_WIDTH = 400;
const int CHAR_HEIGHT = 600; const int CHAR_HEIGHT = 600;
// --- New Character Positioning Constants --- // --- Character Positioning Constants ---
// The vertical baseline for character sprites, making positioning independent of sprite height. // The vertical baseline for character sprites, making positioning independent of sprite height.
const int CHAR_BASELINE_Y = HEIGHT - 140; const int CHAR_BASELINE_Y = HEIGHT - 140;
// The horizontal center for the character on the left. // The horizontal center for the character on the left.
@@ -24,86 +62,82 @@ int main() {
// An off-screen position to the left for transitions, based on the final position. // An off-screen position to the left for transitions, based on the final position.
const int OFFSCREEN_LEFT_X = LEFT_CHAR_CENTER_X - 660; const int OFFSCREEN_LEFT_X = LEFT_CHAR_CENTER_X - 660;
window_t* window = window_create(WIDTH, HEIGHT, u8"The Obwarzanek Narrative Engine"); WindowHandle window(window_create(WIDTH, HEIGHT, u8"The Obwarzanek Narrative Engine"));
if (!window) { if (!window.get()) {
printf("Failed to create window\n"); printf("Failed to create window\n");
return 1; return 1;
} }
compositor_t* compositor = compositor_init(WIDTH, HEIGHT); CompositorHandle compositor(compositor_init(WIDTH, HEIGHT));
if (!compositor) { if (!compositor.get()) {
printf("Failed to initialize compositor\n"); printf("Failed to initialize compositor\n");
window_destroy(window);
return 1; return 1;
} }
uint32_t* bg = image_load_resized("assets/background.png", WIDTH, HEIGHT); ImageHandle bg(image_load_resized("assets/background.png", WIDTH, HEIGHT));
if (bg) { if (bg.get()) {
uint32_t bg_id = compositor_insert(compositor, bg, WIDTH, HEIGHT, 0, 0, 0, 1.0f, ANCHOR_TOP_LEFT); uint32_t bg_id = compositor_insert(compositor.get(), bg.get(), WIDTH, HEIGHT, 0, 0, 0, 1.0f, ANCHOR_TOP_LEFT);
compositor_set_alpha(compositor, bg_id, 1.0f); compositor_set_alpha(compositor.get(), bg_id, 1.0f);
} }
uint32_t* textbox = image_load_resized("assets/textbox.png", WIDTH, 180); ImageHandle textbox(image_load_resized("assets/textbox.png", WIDTH, 180));
if (textbox) { if (textbox.get()) {
// Position via the bottom-left corner for easier alignment with screen bottom // Position via the bottom-left corner for easier alignment with screen bottom
compositor_insert(compositor, textbox, WIDTH, 180, 0, HEIGHT, 3, 1.0f, ANCHOR_BOTTOM_LEFT); compositor_insert(compositor.get(), textbox.get(), WIDTH, 180, 0, HEIGHT, 3, 1.0f, ANCHOR_BOTTOM_LEFT);
} }
uint32_t* maksw_happy = image_load_resized("assets/maksw.png", CHAR_WIDTH, CHAR_HEIGHT); ImageHandle maksw_happy(image_load_resized("assets/maksw.png", CHAR_WIDTH, CHAR_HEIGHT));
// Insert off-screen left, anchored at bottom-center for natural scaling // Insert off-screen left, anchored at bottom-center for natural scaling
uint32_t maksw_happy_id = compositor_insert(compositor, maksw_happy, uint32_t maksw_happy_id = compositor_insert(compositor.get(), maksw_happy.get(),
CHAR_WIDTH, CHAR_HEIGHT, OFFSCREEN_LEFT_X, CHAR_BASELINE_Y, 1, 1.0f, ANCHOR_BOTTOM_CENTER); CHAR_WIDTH, CHAR_HEIGHT, OFFSCREEN_LEFT_X, CHAR_BASELINE_Y, 1, 1.0f, ANCHOR_BOTTOM_CENTER);
uint32_t* maksw_neutral = image_load_resized("assets/maksw2.png", CHAR_WIDTH, CHAR_HEIGHT); ImageHandle maksw_neutral(image_load_resized("assets/maksw2.png", CHAR_WIDTH, CHAR_HEIGHT));
// Insert at the final left position, anchored at bottom-center // Insert at the final left position, anchored at bottom-center
uint32_t maksw_neutral_id = compositor_insert(compositor, maksw_neutral, uint32_t maksw_neutral_id = compositor_insert(compositor.get(), maksw_neutral.get(),
CHAR_WIDTH, CHAR_HEIGHT, LEFT_CHAR_CENTER_X, CHAR_BASELINE_Y, 1, 1.0f, ANCHOR_BOTTOM_CENTER); CHAR_WIDTH, CHAR_HEIGHT, LEFT_CHAR_CENTER_X, CHAR_BASELINE_Y, 1, 1.0f, ANCHOR_BOTTOM_CENTER);
compositor_set_visible(compositor, maksw_neutral_id, false); compositor_set_visible(compositor.get(), maksw_neutral_id, false);
uint32_t* wikor = image_load_resized("assets/wikor.png", CHAR_WIDTH, CHAR_HEIGHT); ImageHandle wikor(image_load_resized("assets/wikor.png", CHAR_WIDTH, CHAR_HEIGHT));
// Insert at the final right position, anchored at bottom-center // Insert at the final right position, anchored at bottom-center
uint32_t wikor_id = compositor_insert(compositor, wikor, uint32_t wikor_id = compositor_insert(compositor.get(), wikor.get(),
CHAR_WIDTH, CHAR_HEIGHT, RIGHT_CHAR_CENTER_X, CHAR_BASELINE_Y, 2, 1.0f, ANCHOR_BOTTOM_CENTER); CHAR_WIDTH, CHAR_HEIGHT, RIGHT_CHAR_CENTER_X, CHAR_BASELINE_Y, 2, 1.0f, ANCHOR_BOTTOM_CENTER);
text_t* name_text = text_init(300, 100); TextHandle name_text(text_init(300, 100));
text_set_font(name_text, "assets/Aller_Rg.ttf", 40.0f); text_set_font(name_text.get(), "assets/Aller_Rg.ttf", 40.0f);
// Text is anchored at top-left, positioned relative to textbox // Text is anchored at top-left, positioned relative to textbox
uint32_t name_id = compositor_insert(compositor, text_getfb(name_text), uint32_t name_id = compositor_insert(compositor.get(), text_getfb(name_text.get()),
300, 100, 60, HEIGHT - 180, 4, 1.0f, ANCHOR_TOP_LEFT); 300, 100, 60, HEIGHT - 180, 4, 1.0f, ANCHOR_TOP_LEFT);
text_t* dialogue_text = text_init(WIDTH - 140, 160); TextHandle dialogue_text(text_init(WIDTH - 140, 160));
text_set_font(dialogue_text, "assets/Vera.ttf", 30.0f); text_set_font(dialogue_text.get(), "assets/Vera.ttf", 30.0f);
// Text is anchored at top-left, positioned relative to textbox // Text is anchored at top-left, positioned relative to textbox
uint32_t dialogue_id = compositor_insert(compositor, text_getfb(dialogue_text), uint32_t dialogue_id = compositor_insert(compositor.get(), text_getfb(dialogue_text.get()),
WIDTH - 140, 160, 60, HEIGHT - 130, 4, 1.0f, ANCHOR_TOP_LEFT); WIDTH - 140, 160, 60, HEIGHT - 130, 4, 1.0f, ANCHOR_TOP_LEFT);
uint32_t* mask = image_load_resized("assets/mask.png", 1280, 1080); ImageHandle mask(image_load_resized("assets/mask.png", 1280, 1080));
// Use top-left anchor for full-screen wipes // Use top-left anchor for full-screen wipes
uint32_t mask_id = compositor_insert(compositor, mask, 1280, 1080, 0, -1080, 5, 1.0f, ANCHOR_TOP_LEFT); uint32_t mask_id = compositor_insert(compositor.get(), mask.get(), 1280, 1080, 0, -1080, 5, 1.0f, ANCHOR_TOP_LEFT);
compositor_set_visible(compositor, mask_id, false); compositor_set_visible(compositor.get(), mask_id, false);
uint32_t* mask2 = image_load_resized("assets/mask2.png", 1280, 1080); ImageHandle mask2(image_load_resized("assets/mask2.png", 1280, 1080));
// Use top-left anchor for full-screen wipes // Use top-left anchor for full-screen wipes
uint32_t mask2_id = compositor_insert(compositor, mask2, 1280, 1080, 0, 0, 5, 1.0f, ANCHOR_TOP_LEFT); uint32_t mask2_id = compositor_insert(compositor.get(), mask2.get(), 1280, 1080, 0, 0, 5, 1.0f, ANCHOR_TOP_LEFT);
compositor_set_visible(compositor, mask2_id, false); compositor_set_visible(compositor.get(), mask2_id, false);
uint32_t* black = (uint32_t*)malloc(WIDTH * HEIGHT * sizeof(uint32_t)); // yeah! memory savings!
for (int i = 0; i < WIDTH * HEIGHT; i++) { //std::unique_ptr<uint32_t[]> black(new uint32_t[WIDTH * HEIGHT]);
black[i] = 0xFF000000; //for (int i = 0; i < WIDTH * HEIGHT; i++) black[i] = 0xFF000000;
} //// Use top-left anchor for full-screen fade
// Use top-left anchor for full-screen fade //uint32_t black_id = compositor_insert(compositor.get(), black.get(), WIDTH, HEIGHT, 0, 0, 6, 1.0f, ANCHOR_TOP_LEFT);
uint32_t black_id = compositor_insert(compositor, black, WIDTH, HEIGHT, 0, 0, 6, 1.0f, ANCHOR_TOP_LEFT); //compositor_set_visible(compositor.get(), black_id, false);
compositor_set_visible(compositor, black_id, false); //compositor_set_alpha(compositor.get(), black_id, 0.0f);
compositor_set_alpha(compositor, black_id, 0.0f);
// Animate character into position using the new centered coordinates // Animate character into position using the new centered coordinates
compositor_animate_move(compositor, maksw_happy_id, LEFT_CHAR_CENTER_X, CHAR_BASELINE_Y, 1.0f, EASE_OUT_CUBIC); compositor_animate_move(compositor.get(), maksw_happy_id, LEFT_CHAR_CENTER_X, CHAR_BASELINE_Y, 1.0f, EASE_OUT_CUBIC);
compositor_animate_scale(compositor, maksw_happy_id, 1.05f, 0.3f, EASE_IN_OUT_CUBIC, true); compositor_animate_scale(compositor.get(), maksw_happy_id, 1.05f, 0.3f, EASE_IN_OUT_CUBIC, true);
text_push(name_text, "maksw", 0.0f, true); text_push(name_text.get(), "maksw", 0.0f, true);
text_push(dialogue_text, text_push(dialogue_text.get(),
"Hey there! Welcome to the Obwarzanek Narrative Engine demo. " "Hello and welcome to the Obwarzanek Narrative Engine demo!",
"This is a simple visual novel engine showcasing text rendering, "
"image compositing, and basic animation features.",
30.0f, true); 30.0f, true);
bool running = true; bool running = true;
@@ -116,7 +150,7 @@ int main() {
const std::chrono::duration<float> REPORT_INTERVAL = std::chrono::seconds(5); const std::chrono::duration<float> REPORT_INTERVAL = std::chrono::seconds(5);
while (running) { while (running) {
if (window_pollevent(window)) running = false; if (window_pollevent(window.get())) running = false;
auto current_time = std::chrono::high_resolution_clock::now(); auto current_time = std::chrono::high_resolution_clock::now();
std::chrono::duration<float> delta_duration = current_time - last_frame_time; std::chrono::duration<float> delta_duration = current_time - last_frame_time;
@@ -129,74 +163,135 @@ int main() {
std::chrono::duration<float> time_since_last_report = current_time - last_report_time; std::chrono::duration<float> time_since_last_report = current_time - last_report_time;
if (time_since_last_report >= REPORT_INTERVAL) { if (time_since_last_report >= REPORT_INTERVAL) {
// Only report if at least one frame has passed
if (frame_count > 0) { if (frame_count > 0) {
float avg_delta_time = frame_time_sum / (float)frame_count; float avg_delta_time = frame_time_sum / (float)frame_count;
float fps = 1.0f / avg_delta_time; float fps = 1.0f / avg_delta_time;
// Calculate the actual duration the FPS was measured over (should be approx 5.0f)
float actual_duration = time_since_last_report.count(); float actual_duration = time_since_last_report.count();
printf("FPS: %.2f (over %d frames in %.2f seconds)\n", printf("FPS: %.2f (over %d frames in %.2f seconds)\n",
fps, frame_count, actual_duration); fps, frame_count, actual_duration);
} }
// Reset counters and update last_report_time
frame_count = 0; frame_count = 0;
frame_time_sum = 0.0f; frame_time_sum = 0.0f;
last_report_time = current_time; // Mark the current time as the new report start last_report_time = current_time;
} }
static bool mouse_was_down = false; static bool mouse_was_down = false;
bool mouse_is_down = window_is_mouse_button_down(window, MOUSE_BUTTON_LEFT); bool mouse_is_down = window_is_mouse_button_down(window.get(), MOUSE_BUTTON_LEFT);
bool mouse_clicked = mouse_is_down && !mouse_was_down; bool mouse_clicked = mouse_is_down && !mouse_was_down;
mouse_was_down = mouse_is_down; mouse_was_down = mouse_is_down;
static bool key_was_down = false; static bool key_was_down = false;
bool key_is_down = window_is_key_down(window, KEY_SPACE); bool key_is_down = window_is_key_down(window.get(), KEY_SPACE);
bool key_pressed = key_is_down && !key_was_down; bool key_pressed = key_is_down && !key_was_down;
key_was_down = key_is_down; key_was_down = key_is_down;
// don't judge me, it will work for now // don't judge me, it will work for now
static unsigned int lines = 0; static unsigned int lines = 2;
static bool dialog_finished = false; static bool dialog_finished = false;
static bool transitioning = false; static bool transitioning = false;
if (mouse_clicked || key_pressed) { if (mouse_clicked || key_pressed) {
if (text_is_animating(dialogue_text)) { if (text_is_animating(dialogue_text.get())) {
text_show_all_current(dialogue_text); text_show_all_current(dialogue_text.get());
} }
else { else {
// this will bite me
switch (lines) { switch (lines) {
case 0: case 2:
// line 2 compositor_animation_complete_all(compositor.get());
compositor_animation_complete_all(compositor); text_clear(dialogue_text.get());
compositor_animate_scale(compositor, maksw_happy_id, 1.0f, 0.3f, EASE_IN_OUT_CUBIC); text_push(dialogue_text.get(), "Today I'll present to you-", 30.0f, true);
compositor_animate_scale(compositor, wikor_id, 1.1f, 0.3f, EASE_IN_OUT_CUBIC);
text_clear(dialogue_text);
text_clear(name_text);
text_push(name_text, "wikor", 0.0f, true);
text_push(dialogue_text, "Hello to you too, maksw..", 30.0f, true);
lines++; lines++;
break; break;
case 1: case 3:
// line 3 compositor_animation_complete_all(compositor.get());
compositor_animation_complete_all(compositor); compositor_animate_scale(compositor.get(), maksw_happy_id, 1.0f, 0.3f, EASE_IN_OUT_CUBIC);
compositor_animate_scale(compositor.get(), wikor_id, 1.05f, 0.3f, EASE_IN_OUT_CUBIC);
compositor_set_visible(compositor, mask_id, true); text_clear(dialogue_text.get());
compositor_animate_move(compositor, mask_id, 0, 0, 0.5f, EASE_OUT_CUBIC, false); text_clear(name_text.get());
text_push(name_text.get(), "wikor", 0.0f, true);
text_push(dialogue_text.get(), "Yeah, hello to you too.", 30.0f, true);
lines++;
break;
case 4:
compositor_animation_complete_all(compositor.get());
compositor_animate_scale(compositor.get(), wikor_id, 1.0f, 0.3f, EASE_IN_OUT_CUBIC);
compositor_animate_scale(compositor.get(), maksw_happy_id, 1.05f, 0.3f, EASE_IN_OUT_CUBIC);
text_clear(dialogue_text.get());
text_clear(name_text.get());
text_push(name_text.get(), "maksw", 0.0f, true);
text_push(dialogue_text.get(), "Oh Wiktor, what a nice suprise!", 30.0f, true);
lines++;
break;
case 5:
compositor_animation_complete_all(compositor.get());
text_clear(dialogue_text.get());
text_push(dialogue_text.get(), "Do you need something?", 30.0f, true);
lines++;
break;
case 6:
compositor_animation_complete_all(compositor.get());
compositor_animate_scale(compositor.get(), maksw_happy_id, 1.0f, 0.3f, EASE_IN_OUT_CUBIC);
compositor_animate_scale(compositor.get(), wikor_id, 1.05f, 0.3f, EASE_IN_OUT_CUBIC);
text_clear(dialogue_text.get());
text_clear(name_text.get());
text_push(name_text.get(), "wikor", 0.0f, true);
text_push(dialogue_text.get(), "No, i was just walking by.", 30.0f, true);
lines++;
break;
case 7:
compositor_animation_complete_all(compositor.get());
text_clear(dialogue_text.get());
text_push(dialogue_text.get(), "Cool engine though.", 30.0f, true);
lines++;
break;
case 8:
// fade transition
compositor_animation_complete_all(compositor.get());
compositor_set_visible(compositor.get(), mask_id, true);
compositor_animate_move(compositor.get(), mask_id, 0, 0, 0.5f, EASE_OUT_CUBIC, false);
transitioning = true; transitioning = true;
lines++; lines++;
break; break;
case 2: case 9:
// (line 4), fade out // some fucking how?
compositor_animation_complete_all(compositor); break;
compositor_animate_scale(compositor, maksw_neutral_id, 1.0f, 0.3f, EASE_IN_OUT_CUBIC, false); case 10:
compositor_animation_complete_all(compositor.get());
compositor_set_visible(compositor, black_id, true); compositor_animate_scale(compositor.get(), wikor_id, 1.0f, 0.3f, EASE_IN_OUT_CUBIC);
compositor_animate_fade(compositor, black_id, 1.0f, 1.0f, EASE_IN_CUBIC, false); compositor_animate_scale(compositor.get(), maksw_neutral_id, 1.05f, 0.3f, EASE_IN_OUT_CUBIC);
text_clear(dialogue_text.get());
text_clear(name_text.get());
text_push(name_text.get(), "maksw", 0.0f, true);
text_push(dialogue_text.get(), "Can't complain, the winter break is just a week away. Plus the compositor is finally cooperating.", 30.0f, true);
lines++;
break;
case 11:
compositor_animation_complete_all(compositor.get());
compositor_animate_scale(compositor.get(), maksw_neutral_id, 1.0f, 0.3f, EASE_IN_OUT_CUBIC);
compositor_animate_scale(compositor.get(), wikor_id, 1.05f, 0.3f, EASE_IN_OUT_CUBIC);
text_clear(dialogue_text.get());
text_clear(name_text.get());
text_push(name_text.get(), "wikor", 0.0f, true);
text_push(dialogue_text.get(), "Sure thing..", 30.0f, true);
lines++;
break;
case 12:
compositor_animation_complete_all(compositor.get());
text_clear(dialogue_text.get());
text_push(dialogue_text.get(), "You're talking to me like i know anything about computers.", 30.0f, true);
lines++;
break;
case 13:
// fade to black and end
compositor_animation_complete_all(compositor.get());
compositor_animate_scale(compositor.get(), maksw_neutral_id, 1.0f, 0.3f, EASE_IN_OUT_CUBIC, false);
//compositor_set_visible(compositor.get(), black_id, true);
//compositor_animate_fade(compositor.get(), black_id, 1.0f, 0.7f, EASE_IN_CUBIC, false);
// yeah! memory savings!
compositor_set_visible(compositor.get(), mask_id, true);
compositor_set_alpha(compositor.get(), mask_id, 0.0f);
compositor_animate_fade(compositor.get(), mask_id, 1.0f, 0.8f, EASE_IN_OUT_CUBIC, false);
dialog_finished = true; dialog_finished = true;
lines++; lines++;
break; break;
@@ -207,58 +302,43 @@ int main() {
} }
} }
compositor_tick(compositor, delta_time_sec); compositor_tick(compositor.get(), delta_time_sec);
if (transitioning) { if (transitioning) {
if (compositor_is_element_animating(compositor, mask_id) == false) { if (!compositor_is_element_animating(compositor.get(), mask_id)) {
compositor_set_visible(compositor, maksw_happy_id, false); compositor_set_visible(compositor.get(), maksw_happy_id, false);
compositor_set_visible(compositor, maksw_neutral_id, true); compositor_set_visible(compositor.get(), maksw_neutral_id, true);
compositor_set_scale(compositor, maksw_neutral_id, 1.05f); compositor_set_scale(compositor.get(), maksw_neutral_id, 1.0f);
text_clear(dialogue_text); compositor_set_scale(compositor.get(), wikor_id, 1.05f);
text_clear(name_text); text_clear(dialogue_text.get());
text_push(name_text, "maksw", 0.0f, true); text_clear(name_text.get());
text_push(dialogue_text, "why so.. serious?", 30.0f, true); text_push(name_text.get(), "wikor", 0.0f, true);
text_push(dialogue_text.get(), "Anyways, how's your day going?", 30.0f, true);
compositor_set_visible(compositor, mask_id, false); compositor_set_visible(compositor.get(), mask_id, false);
compositor_set_visible(compositor, mask2_id, true); compositor_set_visible(compositor.get(), mask2_id, true);
compositor_animate_move(compositor, mask2_id, 0, HEIGHT, 0.5f, EASE_OUT_CUBIC, false); compositor_animate_move(compositor.get(), mask2_id, 0, HEIGHT, 0.5f, EASE_OUT_CUBIC, false);
transitioning = false; transitioning = false;
lines++;
} }
} }
if (dialog_finished) { if (dialog_finished) {
compositor_mark_content_dirty(compositor, black_id); compositor_mark_content_dirty(compositor.get(), mask_id);
if (compositor_is_element_animating(compositor, black_id) == false) { if (!compositor_is_element_animating(compositor.get(), mask_id)) {
running = false; running = false;
} }
} }
if (text_nextframe(name_text, delta_time_sec)) if (text_nextframe(name_text.get(), delta_time_sec))
compositor_mark_content_dirty(compositor, name_id); compositor_mark_content_dirty(compositor.get(), name_id);
if (text_nextframe(dialogue_text, delta_time_sec)) if (text_nextframe(dialogue_text.get(), delta_time_sec))
compositor_mark_content_dirty(compositor, dialogue_id); compositor_mark_content_dirty(compositor.get(), dialogue_id);
const uint32_t* fb = compositor_compose(compositor); const uint32_t* fb = compositor_compose(compositor.get());
window_blit(window, fb); window_blit(window.get(), fb);
} }
// no raii because i'm tired already
if (maksw_happy) image_free(maksw_happy);
if (maksw_neutral) image_free(maksw_neutral);
if (wikor) image_free(wikor);
if (black) free(black);
if (mask) image_free(mask);
if (mask2) image_free(mask2);
if (bg) image_free(bg);
if (textbox) image_free(textbox);
text_destroy(name_text);
text_destroy(dialogue_text);
compositor_destroy(compositor);
window_destroy(window);
return 0; return 0;
} }
+2
View File
@@ -102,6 +102,7 @@
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet> <EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
<AdditionalOptions>/Zc:char8_t- %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/Zc:char8_t- %(AdditionalOptions)</AdditionalOptions>
<SupportJustMyCode>false</SupportJustMyCode>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
@@ -144,6 +145,7 @@
<MultiProcessorCompilation>true</MultiProcessorCompilation> <MultiProcessorCompilation>true</MultiProcessorCompilation>
<EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet> <EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>
<AdditionalOptions>/Zc:char8_t- %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/Zc:char8_t- %(AdditionalOptions)</AdditionalOptions>
<SupportJustMyCode>false</SupportJustMyCode>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>