mirror of
https://github.com/TerryCavanagh/VVVVVV.git
synced 2024-11-10 13:09:43 +01:00
2b84384606
This mirrors a926ce9851
upstream, which
replaces all other SDL_free calls.
112 lines
2.5 KiB
C
112 lines
2.5 KiB
C
#include "Textbook.h"
|
|
|
|
#include <SDL.h>
|
|
|
|
#include "Alloc.h"
|
|
#include "Vlogging.h"
|
|
|
|
void textbook_init(Textbook* textbook)
|
|
{
|
|
textbook->pages_used = 0;
|
|
textbook->protect = false;
|
|
}
|
|
|
|
void textbook_clear(Textbook* textbook)
|
|
{
|
|
if (textbook->protect)
|
|
{
|
|
return;
|
|
}
|
|
|
|
for (short p = 0; p < textbook->pages_used; p++)
|
|
{
|
|
VVV_free(textbook->page[p]);
|
|
}
|
|
textbook->pages_used = 0;
|
|
}
|
|
|
|
void textbook_set_protected(Textbook* textbook, bool protect)
|
|
{
|
|
/* A protected textbook is silently not cleared when requested.
|
|
* Not a memory leak as long as you unprotect and clear at some point. */
|
|
textbook->protect = protect;
|
|
}
|
|
|
|
const void* textbook_store_raw(Textbook* textbook, const void* data, size_t data_len)
|
|
{
|
|
if (data == NULL)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
if (data_len > TEXTBOOK_PAGE_SIZE)
|
|
{
|
|
vlog_warn(
|
|
"Cannot store data of %ld bytes in Textbook, max page size is %d",
|
|
data_len,
|
|
TEXTBOOK_PAGE_SIZE
|
|
);
|
|
return NULL;
|
|
}
|
|
|
|
/* Find a suitable page to place our text on */
|
|
short found_page = -1;
|
|
for (short p = 0; p < textbook->pages_used; p++)
|
|
{
|
|
size_t free = TEXTBOOK_PAGE_SIZE - textbook->page_len[p];
|
|
|
|
if (data_len <= free)
|
|
{
|
|
found_page = p;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (found_page == -1)
|
|
{
|
|
/* Create a new page then */
|
|
found_page = textbook->pages_used;
|
|
|
|
if (found_page >= TEXTBOOK_MAX_PAGES)
|
|
{
|
|
vlog_warn(
|
|
"Textbook is full! %hd pages used (%d chars per page)",
|
|
textbook->pages_used,
|
|
TEXTBOOK_PAGE_SIZE
|
|
);
|
|
return NULL;
|
|
}
|
|
|
|
textbook->page[found_page] = (char*) SDL_malloc(TEXTBOOK_PAGE_SIZE);
|
|
if (textbook->page[found_page] == NULL)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
textbook->page_len[found_page] = 0;
|
|
textbook->pages_used++;
|
|
}
|
|
|
|
size_t cursor = textbook->page_len[found_page];
|
|
char* added_text = &textbook->page[found_page][cursor];
|
|
SDL_memcpy(added_text, data, data_len);
|
|
textbook->page_len[found_page] += data_len;
|
|
|
|
return added_text;
|
|
}
|
|
|
|
const char* textbook_store(Textbook* textbook, const char* text)
|
|
{
|
|
if (text == NULL)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
if (text[0] == '\0')
|
|
{
|
|
/* Don't go and store a single null terminator when we have one right here for you: */
|
|
return "";
|
|
}
|
|
|
|
return textbook_store_raw(textbook, text, SDL_strlen(text)+1);
|
|
}
|