mirror of
https://github.com/nunuhara/xsystem4.git
synced 2026-09-29 18:38:04 +03:00
Implement StoatSpriteEngine.CharSprite functions
With the exception of the Rebuild, Save and Load functions. Used in 僕だけの保健室
This commit is contained in:
@@ -0,0 +1,242 @@
|
||||
/* Copyright (C) 2019 Nunuhara Cabbage <nunuhara@haniwa.technology>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "system4.h"
|
||||
#include "system4/string.h"
|
||||
#include "system4/utfsjis.h"
|
||||
#include "vm/heap.h"
|
||||
#include "vm/page.h"
|
||||
#include "sprite.h"
|
||||
#include "CharSpriteManager.h"
|
||||
|
||||
/*
|
||||
* NOTE: This is not a library on it's own, but rather part of
|
||||
* StoatSpriteEngine/ChipmunkSpriteEngine.
|
||||
*/
|
||||
|
||||
struct charsprite {
|
||||
struct sact_sprite sp;
|
||||
// NOTE: even though we only render a single character, we need to store an
|
||||
// arbitrary string because CharSprite_GetChar returns it.
|
||||
struct string *ch;
|
||||
struct text_metrics tm;
|
||||
};
|
||||
|
||||
static struct {
|
||||
unsigned size;
|
||||
struct charsprite **sprites;
|
||||
unsigned nr_free;
|
||||
int *free;
|
||||
} chars = {0};
|
||||
|
||||
static void grow_chars(unsigned new_size) {
|
||||
assert(new_size > chars.size);
|
||||
chars.sprites = xrealloc_array(chars.sprites, chars.size, new_size, sizeof(struct charsprite*));
|
||||
chars.free = xrealloc_array(chars.free, chars.size, new_size, sizeof(int));
|
||||
|
||||
for (unsigned i = chars.size; i < new_size; i++) {
|
||||
chars.free[chars.nr_free++] = i;
|
||||
}
|
||||
|
||||
chars.size = new_size;
|
||||
}
|
||||
|
||||
static int get_handle(void)
|
||||
{
|
||||
if (!chars.nr_free) {
|
||||
grow_chars(chars.size ? chars.size*2 : 256);
|
||||
}
|
||||
return chars.free[--chars.nr_free];
|
||||
}
|
||||
|
||||
static bool handle_valid(int handle)
|
||||
{
|
||||
return handle >= 0 && (unsigned)handle < chars.size && chars.sprites[handle];
|
||||
}
|
||||
|
||||
static void check_handle(int handle)
|
||||
{
|
||||
if (!handle_valid(handle))
|
||||
VM_ERROR("Invalid CharSprite handle: %d", handle);
|
||||
}
|
||||
|
||||
static struct charsprite *charsprite_get(int handle)
|
||||
{
|
||||
check_handle(handle);
|
||||
return chars.sprites[handle];
|
||||
}
|
||||
|
||||
static bool charsprite_allocated(struct charsprite *cs)
|
||||
{
|
||||
return cs->ch != NULL;
|
||||
}
|
||||
|
||||
int CharSpriteManager_CreateHandle(void)
|
||||
{
|
||||
int handle = get_handle();
|
||||
assert(!chars.sprites[handle]);
|
||||
chars.sprites[handle] = xcalloc(1, sizeof(struct charsprite));
|
||||
return handle;
|
||||
}
|
||||
|
||||
bool CharSpriteManager_ReleaseHandle(int handle)
|
||||
{
|
||||
if (!handle_valid(handle))
|
||||
return false;
|
||||
|
||||
sprite_free(&chars.sprites[handle]->sp);
|
||||
if (chars.sprites[handle]->ch) {
|
||||
free_string(chars.sprites[handle]->ch);
|
||||
}
|
||||
free(chars.sprites[handle]);
|
||||
chars.sprites[handle] = NULL;
|
||||
chars.free[chars.nr_free++] = handle;
|
||||
return true;
|
||||
}
|
||||
|
||||
void CharSpriteManager_Clear(void)
|
||||
{
|
||||
for (unsigned i = 0; i < chars.size; i++) {
|
||||
CharSpriteManager_ReleaseHandle(i);
|
||||
}
|
||||
}
|
||||
|
||||
//static void CharSpriteManager_Rebuild(void);
|
||||
//static bool CharSpriteManager_Save(struct page **iarray);
|
||||
//static bool CharSpriteManager_Load(struct page **iarray);
|
||||
|
||||
void CharSprite_Release(int handle)
|
||||
{
|
||||
struct charsprite *sp = charsprite_get(handle);
|
||||
sprite_free(&sp->sp);
|
||||
}
|
||||
|
||||
static void CASColor_to_SDL_Color(SDL_Color *color, int page_no)
|
||||
{
|
||||
struct page *page = heap_get_page(page_no);
|
||||
assert(page);
|
||||
assert(page->nr_vars == 4);
|
||||
color->r = page->values[0].i;
|
||||
color->g = page->values[1].i;
|
||||
color->b = page->values[2].i;
|
||||
color->a = page->values[3].i;
|
||||
}
|
||||
|
||||
static void CASCharSpriteProperty_to_text_metrics(struct text_metrics *tm, struct page *page)
|
||||
{
|
||||
assert(page);
|
||||
assert(page->nr_vars == 6);
|
||||
|
||||
tm->face = page->values[0].i;
|
||||
tm->size = page->values[1].i;
|
||||
CASColor_to_SDL_Color(&tm->color, page->values[2].i);
|
||||
//tm->weight = page->values[3].f;
|
||||
tm->weight = FW_NORMAL;
|
||||
tm->outline_left = page->values[4].f;
|
||||
tm->outline_up = tm->outline_left;
|
||||
tm->outline_right = tm->outline_left;
|
||||
tm->outline_down = tm->outline_left;
|
||||
CASColor_to_SDL_Color(&tm->outline_color, page->values[5].i);
|
||||
}
|
||||
|
||||
static int extract_sjis_char(char *src, char *dst)
|
||||
{
|
||||
if (SJIS_2BYTE(*src)) {
|
||||
dst[0] = src[0];
|
||||
dst[1] = src[1];
|
||||
dst[2] = '\0';
|
||||
return 2;
|
||||
}
|
||||
dst[0] = src[0];
|
||||
dst[1] = '\0';
|
||||
return 1;
|
||||
}
|
||||
|
||||
void CharSprite_SetChar(int handle, struct string **s, struct page **property)
|
||||
{
|
||||
struct charsprite *sp = charsprite_get(handle);
|
||||
CASCharSpriteProperty_to_text_metrics(&sp->tm, *property);
|
||||
|
||||
if (charsprite_allocated(sp)) {
|
||||
sprite_free(&sp->sp);
|
||||
}
|
||||
if (sp->ch) {
|
||||
free_string(sp->ch);
|
||||
sp->ch = NULL;
|
||||
}
|
||||
if (!(*s)->size) {
|
||||
return;
|
||||
}
|
||||
|
||||
sp->ch = string_ref(*s);
|
||||
|
||||
char ch[3];
|
||||
extract_sjis_char((*s)->text, ch);
|
||||
|
||||
int w = sp->tm.size;
|
||||
int h = sp->tm.size;
|
||||
if (isascii(ch[0]))
|
||||
w /= 2;
|
||||
|
||||
sprite_init(&sp->sp, w, h, 0, 0, 0, 0);
|
||||
sprite_get_texture(&sp->sp); // XXX: force initialization of texture
|
||||
gfx_render_text(&sp->sp.texture, (Point) { .x=0, .y = 0 }, ch, &sp->tm, 0);
|
||||
sprite_dirty(&sp->sp);
|
||||
}
|
||||
|
||||
void CharSprite_SetPos(int handle, int x, int y)
|
||||
{
|
||||
struct charsprite *sp = charsprite_get(handle);
|
||||
sprite_set_pos(&sp->sp, x, y);
|
||||
}
|
||||
|
||||
void CharSprite_SetZ(int handle, int z)
|
||||
{
|
||||
struct charsprite *sp = charsprite_get(handle);
|
||||
sprite_set_z(&sp->sp, z);
|
||||
}
|
||||
|
||||
void CharSprite_SetAlphaRate(int handle, int rate)
|
||||
{
|
||||
struct charsprite *sp = charsprite_get(handle);
|
||||
sprite_set_blend_rate(&sp->sp, rate);
|
||||
}
|
||||
|
||||
void CharSprite_SetShow(int handle, bool show)
|
||||
{
|
||||
struct charsprite *sp = charsprite_get(handle);
|
||||
sprite_set_show(&sp->sp, show);
|
||||
}
|
||||
|
||||
void CharSprite_GetChar(int handle, struct string **ch)
|
||||
{
|
||||
struct charsprite *sp = charsprite_get(handle);
|
||||
if (*ch)
|
||||
free_string(*ch);
|
||||
if (sp->ch)
|
||||
*ch = string_ref(sp->ch);
|
||||
else
|
||||
*ch = string_ref(&EMPTY_STRING);
|
||||
}
|
||||
|
||||
int CharSprite_GetAlphaRate(int handle)
|
||||
{
|
||||
struct charsprite *sp = charsprite_get(handle);
|
||||
return sprite_get_blend_rate(&sp->sp);
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/* Copyright (C) 2019 Nunuhara Cabbage <nunuhara@haniwa.technology>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef SYSTEM4_HLL_CHARSPRITE_MANAGER_H
|
||||
#define SYSTEM4_HLL_CHARSPRITE_MANAGER_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
struct page;
|
||||
struct string;
|
||||
|
||||
int CharSpriteManager_CreateHandle(void);
|
||||
bool CharSpriteManager_ReleaseHandle(int handle);
|
||||
void CharSpriteManager_Clear(void);
|
||||
void CharSpriteManager_Rebuild(void);
|
||||
bool CharSpriteManager_Save(struct page **iarray);
|
||||
bool CharSpriteManager_Load(struct page **iarray);
|
||||
void CharSprite_Release(int nHandle);
|
||||
void CharSprite_SetChar(int handle, struct string **s, struct page **property);
|
||||
void CharSprite_SetPos(int handle, int x, int y);
|
||||
void CharSprite_SetZ(int handle, int z);
|
||||
void CharSprite_SetAlphaRate(int handle, int rate);
|
||||
void CharSprite_SetShow(int handle, bool show);
|
||||
void CharSprite_GetChar(int handle, struct string **ch);
|
||||
int CharSprite_GetAlphaRate(int handle);
|
||||
|
||||
#endif /* SYSTEM4_HLL_CHARSPRITE_MANAGER_H */
|
||||
+15
-13
@@ -35,6 +35,7 @@
|
||||
#include "xsystem4.h"
|
||||
#include "sact.h"
|
||||
#include "AnteaterADVEngine.h"
|
||||
#include "CharSpriteManager.h"
|
||||
|
||||
HLL_WARN_UNIMPLEMENTED( , void, StoatSpriteEngine, JoypadQuake_Set, int num, int type, int magnitude);
|
||||
HLL_WARN_UNIMPLEMENTED(1, int, StoatSpriteEngine, Music_SetLoopCount, int ch, int count);
|
||||
@@ -553,19 +554,6 @@ HLL_WARN_UNIMPLEMENTED(0, bool, StoatSpriteEngine, SYSTEM_GetInvalidateFrameSkip
|
||||
//void StoatSpriteEngine_ADVSceneKeeper_Clear(void);
|
||||
//bool StoatSpriteEngine_ADVSceneKeeper_Save(ref array@int pIVMArray);
|
||||
//bool StoatSpriteEngine_ADVSceneKeeper_Load(ref array@int pIVMArray);
|
||||
//void StoatSpriteEngine_ADVLogList_Clear(void);
|
||||
//void StoatSpriteEngine_ADVLogList_AddText(ref string pIText);
|
||||
//void StoatSpriteEngine_ADVLogList_AddNewLine(void);
|
||||
//void StoatSpriteEngine_ADVLogList_AddNewPage(void);
|
||||
//void StoatSpriteEngine_ADVLogList_AddVoice(int nVoiceNumber);
|
||||
//void StoatSpriteEngine_ADVLogList_SetEnable(bool bEnable);
|
||||
//bool StoatSpriteEngine_ADVLogList_IsEnable(void);
|
||||
//int StoatSpriteEngine_ADVLogList_GetNumofADVLog(void);
|
||||
//int StoatSpriteEngine_ADVLogList_GetNumofADVLogText(int nADVLog);
|
||||
//void StoatSpriteEngine_ADVLogList_GetADVLogText(int nADVLog, int nText, ref string pIText);
|
||||
//int StoatSpriteEngine_ADVLogList_GetADVLogVoice(int nADVLog);
|
||||
//bool StoatSpriteEngine_ADVLogList_Save(ref array@int pIVMArray);
|
||||
//bool StoatSpriteEngine_ADVLogList_Load(ref array@int pIVMArray);
|
||||
|
||||
HLL_LIBRARY(StoatSpriteEngine,
|
||||
HLL_EXPORT(_ModuleFini, StoatSpriteEngine_ModuleFini),
|
||||
@@ -765,6 +753,20 @@ HLL_LIBRARY(StoatSpriteEngine,
|
||||
HLL_EXPORT(MultiSprite_Rebuild, StoatSpriteEngine_MultiSprite_Rebuild),
|
||||
HLL_EXPORT(MultiSprite_Encode, StoatSpriteEngine_MultiSprite_Encode),
|
||||
HLL_EXPORT(MultiSprite_Decode, StoatSpriteEngine_MultiSprite_Decode),
|
||||
HLL_EXPORT(CharSpriteManager_CreateHandle, CharSpriteManager_CreateHandle),
|
||||
HLL_EXPORT(CharSpriteManager_ReleaseHandle, CharSpriteManager_ReleaseHandle),
|
||||
HLL_EXPORT(CharSpriteManager_Clear, CharSpriteManager_Clear),
|
||||
HLL_TODO_EXPORT(CharSpriteManager_Rebuild, CharSpriteManager_Rebuild),
|
||||
HLL_TODO_EXPORT(CharSpriteManager_Save, CharSpriteManager_Save),
|
||||
HLL_TODO_EXPORT(CharSpriteManager_Load, CharSpriteManager_Load),
|
||||
HLL_EXPORT(CharSprite_Release, CharSprite_Release),
|
||||
HLL_EXPORT(CharSprite_SetChar, CharSprite_SetChar),
|
||||
HLL_EXPORT(CharSprite_SetPos, CharSprite_SetPos),
|
||||
HLL_EXPORT(CharSprite_SetZ, CharSprite_SetZ),
|
||||
HLL_EXPORT(CharSprite_SetAlphaRate, CharSprite_SetAlphaRate),
|
||||
HLL_EXPORT(CharSprite_SetShow, CharSprite_SetShow),
|
||||
HLL_EXPORT(CharSprite_GetChar, CharSprite_GetChar),
|
||||
HLL_EXPORT(CharSprite_GetAlphaRate, CharSprite_GetAlphaRate),
|
||||
HLL_EXPORT(SYSTEM_IsResetOnce, StoatSpriteEngine_SYSTEM_IsResetOnce),
|
||||
HLL_EXPORT(SYSTEM_SetConfigOverFrameRateSleep, StoatSpriteEngine_SYSTEM_SetConfigOverFrameRateSleep),
|
||||
HLL_EXPORT(SYSTEM_GetConfigOverFrameRateSleep, StoatSpriteEngine_SYSTEM_GetConfigOverFrameRateSleep),
|
||||
|
||||
@@ -26,6 +26,7 @@ xsystem4 = ['audio.c',
|
||||
'hll/AnteaterADVEngine.c',
|
||||
'hll/BanMisc.c',
|
||||
'hll/Bitarray.c',
|
||||
'hll/CharSpriteManager.c',
|
||||
'hll/Confirm.c',
|
||||
'hll/Confirm2.c',
|
||||
'hll/CrayfishLogViewer.c',
|
||||
|
||||
@@ -69,6 +69,7 @@ void sprite_free(struct sact_sprite *sp)
|
||||
sprite_unregister(sp);
|
||||
gfx_delete_texture(&sp->texture);
|
||||
gfx_delete_texture(&sp->text.texture);
|
||||
memset(sp, 0, sizeof(struct sact_sprite));
|
||||
}
|
||||
|
||||
void sprite_render_scene(void)
|
||||
|
||||
Reference in New Issue
Block a user