mirror of
https://github.com/nunuhara/xsystem4.git
synced 2026-09-22 23:18:01 +03:00
@@ -149,6 +149,8 @@ target_sources(xsystem4 PRIVATE
|
||||
src/hll/LoadCG.c
|
||||
src/hll/MainEXFile.c
|
||||
src/hll/MainSurface.c
|
||||
src/hll/MamanyoDemo.c
|
||||
src/hll/MamanyoSDemo.c
|
||||
src/hll/MarmotModelEngine.c
|
||||
src/hll/Math.c
|
||||
src/hll/MapLoader.c
|
||||
@@ -173,6 +175,29 @@ target_sources(xsystem4 PRIVATE
|
||||
src/hll/SystemServiceEx.c
|
||||
src/hll/Timer.c
|
||||
src/hll/Toushin3Loader.c
|
||||
src/hll/vmAnime.c
|
||||
src/hll/vmArray.c
|
||||
src/hll/vmCG.c
|
||||
src/hll/vmChrLoader.c
|
||||
src/hll/vmCursor.c
|
||||
src/hll/vmDialog.c
|
||||
src/hll/vmDrawGauge.c
|
||||
src/hll/vmDrawMsg.c
|
||||
src/hll/vmDrawNumber.c
|
||||
src/hll/vmFile.c
|
||||
src/hll/vmGraph.c
|
||||
src/hll/vmGraphQuake.c
|
||||
src/hll/vmKey.c
|
||||
src/hll/vmMapLoader.c
|
||||
src/hll/vmMsgLog.c
|
||||
src/hll/vmMsgSkip.c
|
||||
src/hll/vmMusic.c
|
||||
src/hll/vmSound.c
|
||||
src/hll/vmSprite.c
|
||||
src/hll/vmString.c
|
||||
src/hll/vmSurface.c
|
||||
src/hll/vmSystem.c
|
||||
src/hll/vmTimer.c
|
||||
src/hll/VSFile.c
|
||||
)
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ issues, please let me know or open a pull request to update this table.
|
||||
| Game | Status | Notes |
|
||||
| ------------------------------------------------------- | ----------- | ----- |
|
||||
| DALK外伝 | Unsupported | |
|
||||
| ままにょにょ | Unsupported | |
|
||||
| ままにょにょ | Supported | |
|
||||
| 大番長 -Big Bang Age- | Supported | |
|
||||
| Daibanchou -Big Bang Age- (EN) | Supported | |
|
||||
| 魔女の贖罪 | Unknown | |
|
||||
|
||||
+10
-2
@@ -17,14 +17,22 @@
|
||||
#ifndef SYSTEM4_ID_POOL_H
|
||||
#define SYSTEM4_ID_POOL_H
|
||||
|
||||
// A reasonable base value for pointer-based handles.
|
||||
#define ID_POOL_HANDLE_BASE 0x100000
|
||||
|
||||
struct id_pool {
|
||||
void **slots;
|
||||
int nr_slots;
|
||||
int base;
|
||||
};
|
||||
|
||||
void id_pool_init(struct id_pool *pool);
|
||||
void id_pool_release(struct id_pool *pool, int id);
|
||||
void id_pool_init(struct id_pool *pool, int base);
|
||||
void id_pool_delete(struct id_pool *pool);
|
||||
void *id_pool_release(struct id_pool *pool, int id);
|
||||
int id_pool_count(struct id_pool *pool);
|
||||
int id_pool_get_unused(struct id_pool *pool);
|
||||
int id_pool_get_first(struct id_pool *pool);
|
||||
int id_pool_get_next(struct id_pool *pool, int id);
|
||||
void *id_pool_get(struct id_pool *pool, int id);
|
||||
void *id_pool_set(struct id_pool *pool, int id, void *data);
|
||||
|
||||
|
||||
+5
-6
@@ -43,8 +43,8 @@ void audio_init(void)
|
||||
if (audio_initialized)
|
||||
return;
|
||||
|
||||
id_pool_init(&wav);
|
||||
id_pool_init(&bgm);
|
||||
id_pool_init(&wav, 0);
|
||||
id_pool_init(&bgm, 0);
|
||||
|
||||
for (int i = 0; i < NR_ANONYMOUS_CHANNELS; i++) {
|
||||
anonymous_channels[i] = -1;
|
||||
@@ -56,10 +56,10 @@ void audio_init(void)
|
||||
|
||||
void audio_reset(void)
|
||||
{
|
||||
for (int i = 0; i < wav.nr_slots; i++) {
|
||||
for (int i = id_pool_get_first(&wav); i >= 0; i = id_pool_get_next(&wav, i)) {
|
||||
wav_unprepare(i);
|
||||
}
|
||||
for (int i = 0; i < bgm.nr_slots; i++) {
|
||||
for (int i = id_pool_get_first(&bgm); i >= 0; i = id_pool_get_next(&bgm, i)) {
|
||||
bgm_unprepare(i);
|
||||
}
|
||||
for (int i = 0; i < NR_ANONYMOUS_CHANNELS; i++) {
|
||||
@@ -136,11 +136,10 @@ int bgm_prepare(int id, int no) { return audio_prepare(&bgm, id, ASSET_BGM, no);
|
||||
|
||||
static int audio_unprepare(struct id_pool *pool, int id)
|
||||
{
|
||||
struct channel *ch = id_pool_get(pool, id);
|
||||
struct channel *ch = id_pool_release(pool, id);
|
||||
if (!ch)
|
||||
return 0;
|
||||
channel_close(ch);
|
||||
id_pool_release(pool, id);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -343,6 +343,8 @@ extern struct static_library lib_KiwiSoundEngine;
|
||||
extern struct static_library lib_LoadCG;
|
||||
extern struct static_library lib_MainEXFile;
|
||||
extern struct static_library lib_MainSurface;
|
||||
extern struct static_library lib_MamanyoDemo;
|
||||
extern struct static_library lib_MamanyoSDemo;
|
||||
extern struct static_library lib_MarmotModelEngine;
|
||||
extern struct static_library lib_Math;
|
||||
extern struct static_library lib_MapLoader;
|
||||
@@ -369,6 +371,29 @@ extern struct static_library lib_SystemServiceEx;
|
||||
extern struct static_library lib_TapirEngine;
|
||||
extern struct static_library lib_Timer;
|
||||
extern struct static_library lib_Toushin3Loader;
|
||||
extern struct static_library lib_vmAnime;
|
||||
extern struct static_library lib_vmArray;
|
||||
extern struct static_library lib_vmCG;
|
||||
extern struct static_library lib_vmChrLoader;
|
||||
extern struct static_library lib_vmCursor;
|
||||
extern struct static_library lib_vmDialog;
|
||||
extern struct static_library lib_vmDrawGauge;
|
||||
extern struct static_library lib_vmDrawMsg;
|
||||
extern struct static_library lib_vmDrawNumber;
|
||||
extern struct static_library lib_vmFile;
|
||||
extern struct static_library lib_vmGraph;
|
||||
extern struct static_library lib_vmGraphQuake;
|
||||
extern struct static_library lib_vmKey;
|
||||
extern struct static_library lib_vmMapLoader;
|
||||
extern struct static_library lib_vmMsgLog;
|
||||
extern struct static_library lib_vmMsgSkip;
|
||||
extern struct static_library lib_vmMusic;
|
||||
extern struct static_library lib_vmSound;
|
||||
extern struct static_library lib_vmSprite;
|
||||
extern struct static_library lib_vmString;
|
||||
extern struct static_library lib_vmSurface;
|
||||
extern struct static_library lib_vmSystem;
|
||||
extern struct static_library lib_vmTimer;
|
||||
extern struct static_library lib_VSFile;
|
||||
|
||||
static struct static_library *static_libraries[] = {
|
||||
@@ -414,6 +439,8 @@ static struct static_library *static_libraries[] = {
|
||||
&lib_LoadCG,
|
||||
&lib_MainEXFile,
|
||||
&lib_MainSurface,
|
||||
&lib_MamanyoDemo,
|
||||
&lib_MamanyoSDemo,
|
||||
&lib_MarmotModelEngine,
|
||||
&lib_Math,
|
||||
&lib_MapLoader,
|
||||
@@ -440,6 +467,29 @@ static struct static_library *static_libraries[] = {
|
||||
&lib_TapirEngine,
|
||||
&lib_Timer,
|
||||
&lib_Toushin3Loader,
|
||||
&lib_vmAnime,
|
||||
&lib_vmArray,
|
||||
&lib_vmCG,
|
||||
&lib_vmChrLoader,
|
||||
&lib_vmCursor,
|
||||
&lib_vmDialog,
|
||||
&lib_vmDrawGauge,
|
||||
&lib_vmDrawMsg,
|
||||
&lib_vmDrawNumber,
|
||||
&lib_vmFile,
|
||||
&lib_vmGraph,
|
||||
&lib_vmGraphQuake,
|
||||
&lib_vmKey,
|
||||
&lib_vmMapLoader,
|
||||
&lib_vmMsgLog,
|
||||
&lib_vmMsgSkip,
|
||||
&lib_vmMusic,
|
||||
&lib_vmSound,
|
||||
&lib_vmSprite,
|
||||
&lib_vmString,
|
||||
&lib_vmSurface,
|
||||
&lib_vmSystem,
|
||||
&lib_vmTimer,
|
||||
&lib_VSFile,
|
||||
NULL
|
||||
};
|
||||
|
||||
+167
-85
@@ -28,10 +28,10 @@
|
||||
#include "system4/little_endian.h"
|
||||
|
||||
#include "audio.h"
|
||||
#include "hll.h"
|
||||
#include "sact.h"
|
||||
#include "xsystem4.h"
|
||||
|
||||
#include "hll.h"
|
||||
#include "ChrLoader.h"
|
||||
|
||||
/*
|
||||
* struct ChrHeader {
|
||||
@@ -50,7 +50,8 @@
|
||||
* };
|
||||
*
|
||||
* struct MineInfo {
|
||||
* uint32_t unknown[6];
|
||||
* uint32_t id;
|
||||
* uint32_t unknown[5];
|
||||
* uint32_t status[24];
|
||||
* char name[32];
|
||||
* };
|
||||
@@ -64,12 +65,14 @@
|
||||
* };
|
||||
*
|
||||
* struct EnmyInfo {
|
||||
* uint32_t unknown[5];
|
||||
* uint32_t id;
|
||||
* uint32_t unknown[4];
|
||||
* uint32_t status[17];
|
||||
* char name[32];
|
||||
* };
|
||||
*/
|
||||
|
||||
static char *chr_directory;
|
||||
static struct hash_table *chr_table; // Caches decrypted .chr file data
|
||||
|
||||
static bool is_enemy(uint8_t *data)
|
||||
@@ -84,7 +87,7 @@ static uint8_t *chr_get(int id)
|
||||
return slot->value;
|
||||
|
||||
char buf[32];
|
||||
sprintf(buf, "CHR/%d.chr", id);
|
||||
snprintf(buf, sizeof(buf), "%s/%d.chr", chr_directory, id);
|
||||
char *path = gamedir_path(buf);
|
||||
size_t size;
|
||||
uint8_t *data = file_read(path, &size);
|
||||
@@ -102,106 +105,51 @@ static uint8_t *chr_get(int id)
|
||||
return data;
|
||||
}
|
||||
|
||||
static bool ChrLoader_Init(void)
|
||||
void chr_loader_init(const char *dir)
|
||||
{
|
||||
chr_directory = strdup(dir);
|
||||
chr_table = ht_create(512);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool ChrLoader_LoadCG(int sprite, int x, int y, int id, int type)
|
||||
bool chr_loader_exists(int id)
|
||||
{
|
||||
return chr_get(id) != NULL;
|
||||
}
|
||||
|
||||
struct string *chr_loader_get_name(int id)
|
||||
{
|
||||
uint8_t *data = chr_get(id);
|
||||
if (!data)
|
||||
return false;
|
||||
return NULL;
|
||||
|
||||
struct sact_sprite *sp = sact_get_sprite(sprite);
|
||||
if (!sp)
|
||||
return false;
|
||||
|
||||
int index = -1;
|
||||
switch (type) {
|
||||
case 0: // Unit
|
||||
index = is_enemy(data) ? 0 : 1;
|
||||
break;
|
||||
case 1: // Attack
|
||||
index = is_enemy(data) ? 1 : 2;
|
||||
break;
|
||||
case 2: // Damage
|
||||
index = is_enemy(data) ? 2 : 3;
|
||||
break;
|
||||
case 3: // Face
|
||||
index = is_enemy(data) ? -1 : 0;
|
||||
break;
|
||||
}
|
||||
if (index < 0)
|
||||
return false;
|
||||
|
||||
size_t offset = LittleEndian_getDW(data, 12 + index * 4);
|
||||
size_t size = LittleEndian_getDW(data, (is_enemy(data) ? 24 : 28) + index * 4);
|
||||
struct cg *cg = cg_load_buffer(data + offset, size);
|
||||
if (!cg)
|
||||
return false;
|
||||
sprite_set_cg(sp, cg);
|
||||
cg_free(cg);
|
||||
return true;
|
||||
uint32_t offset = LittleEndian_getDW(data, 8);
|
||||
offset += is_enemy(data) ? 88 : 120;
|
||||
return cstr_to_string((char *)data + offset);
|
||||
}
|
||||
|
||||
static void chr_archive_free_data(struct archive_data *data) { /* no-op */ }
|
||||
|
||||
static struct archive_ops chr_archive_ops = {
|
||||
.free_data = chr_archive_free_data
|
||||
};
|
||||
|
||||
static struct archive chr_archive = { .mmapped = false, .ops = &chr_archive_ops };
|
||||
|
||||
static bool ChrLoader_LoadWavFile(int sound_channel, int id)
|
||||
struct string *chr_loader_get_string(int id, int index)
|
||||
{
|
||||
uint8_t *data = chr_get(id);
|
||||
if (!data)
|
||||
return false;
|
||||
if (!data || is_enemy(data) || (unsigned)index >= 48)
|
||||
return NULL;
|
||||
|
||||
size_t offset = LittleEndian_getDW(data, is_enemy(data) ? 36 : 44);
|
||||
size_t size = LittleEndian_getDW(data, is_enemy(data) ? 40 : 48);
|
||||
|
||||
struct archive_data *dfile = xcalloc(1, sizeof(struct archive_data));
|
||||
dfile->size = size;
|
||||
dfile->data = data + offset;
|
||||
dfile->no = id;
|
||||
dfile->archive = &chr_archive;
|
||||
|
||||
if (!wav_prepare_from_archive_data(sound_channel, dfile)) {
|
||||
WARNING("ChrLoader.LoadWavFile %d failed", id);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool ChrLoader_LoadSentence(int id, int type, struct string **msg)
|
||||
{
|
||||
uint8_t *data = chr_get(id);
|
||||
if (!data || is_enemy(data) || (unsigned)type >= 48)
|
||||
return false;
|
||||
|
||||
uint32_t offset = LittleEndian_getDW(data, 52 + type * 4);
|
||||
uint32_t offset = LittleEndian_getDW(data, 52 + index * 4);
|
||||
if (!offset)
|
||||
return false;
|
||||
*msg = cstr_to_string((char *)data + offset);
|
||||
return true;
|
||||
return NULL;
|
||||
return cstr_to_string((char *)data + offset);
|
||||
}
|
||||
|
||||
static bool ChrLoader_GetName(int id, struct string **name)
|
||||
int chr_loader_get_id(int id)
|
||||
{
|
||||
uint8_t *data = chr_get(id);
|
||||
if (!data)
|
||||
return false;
|
||||
|
||||
uint32_t offset = LittleEndian_getDW(data, 8);
|
||||
offset += is_enemy(data) ? 88 : 120;
|
||||
*name = cstr_to_string((char *)data + offset);
|
||||
return true;
|
||||
return LittleEndian_getDW(data, offset);
|
||||
}
|
||||
|
||||
static int ChrLoader_GetStatus(int id, int type)
|
||||
int chr_loader_get_status(int id, int type)
|
||||
{
|
||||
uint8_t *data = chr_get(id);
|
||||
if (!data)
|
||||
@@ -226,9 +174,143 @@ static int ChrLoader_GetStatus(int id, int type)
|
||||
return LittleEndian_getDW(data, offset);
|
||||
}
|
||||
|
||||
static bool ChrLoader_IsExist(int id)
|
||||
int chr_loader_get_blob_handle(int id, int index)
|
||||
{
|
||||
return chr_get(id) != NULL;
|
||||
if (!chr_get(id) || index < 0 || index > 4)
|
||||
return 0;
|
||||
return (id << 3) + index + 1;
|
||||
}
|
||||
|
||||
void *chr_loader_get_blob(int blob_handle, size_t *size)
|
||||
{
|
||||
if (!blob_handle)
|
||||
return NULL;
|
||||
int id = blob_handle >> 3;
|
||||
int index = (blob_handle & 7) - 1;
|
||||
uint8_t *data = chr_get(id);
|
||||
if (!data || index < 0 || index > 4)
|
||||
return NULL;
|
||||
|
||||
size_t ofs_ofs;
|
||||
size_t size_ofs;
|
||||
if (is_enemy(data)) {
|
||||
if (index == 4) {
|
||||
ofs_ofs = 36;
|
||||
size_ofs = 40;
|
||||
} else {
|
||||
ofs_ofs = 12 + index * 4;
|
||||
size_ofs = 24 + index * 4;
|
||||
}
|
||||
} else {
|
||||
if (index == 4) {
|
||||
ofs_ofs = 44;
|
||||
size_ofs = 48;
|
||||
} else {
|
||||
ofs_ofs = 12 + index * 4;
|
||||
size_ofs = 28 + index * 4;
|
||||
}
|
||||
}
|
||||
size_t offset = LittleEndian_getDW(data, ofs_ofs);
|
||||
*size = LittleEndian_getDW(data, size_ofs);
|
||||
return data + offset;
|
||||
}
|
||||
|
||||
static void chr_archive_free_data(struct archive_data *data) { /* no-op */ }
|
||||
|
||||
static struct archive_ops chr_archive_ops = {
|
||||
.free_data = chr_archive_free_data
|
||||
};
|
||||
|
||||
static struct archive chr_archive = { .mmapped = false, .ops = &chr_archive_ops };
|
||||
|
||||
struct archive_data *chr_loader_get_blob_as_archive_data(int blob_handle)
|
||||
{
|
||||
size_t size;
|
||||
uint8_t *data = chr_loader_get_blob(blob_handle, &size);
|
||||
if (!data)
|
||||
return NULL;
|
||||
|
||||
struct archive_data *dfile = xcalloc(1, sizeof(struct archive_data));
|
||||
dfile->size = size;
|
||||
dfile->data = data;
|
||||
dfile->archive = &chr_archive;
|
||||
return dfile;
|
||||
}
|
||||
|
||||
static bool ChrLoader_Init(void)
|
||||
{
|
||||
chr_loader_init("CHR");
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool ChrLoader_LoadCG(int sprite, int x, int y, int id, int type)
|
||||
{
|
||||
struct sact_sprite *sp = sact_get_sprite(sprite);
|
||||
if (!sp)
|
||||
return false;
|
||||
|
||||
uint8_t *data = chr_get(id);
|
||||
if (!data)
|
||||
return false;
|
||||
|
||||
int index = -1;
|
||||
switch (type) {
|
||||
case 0: // Unit
|
||||
index = is_enemy(data) ? 0 : 1;
|
||||
break;
|
||||
case 1: // Attack
|
||||
index = is_enemy(data) ? 1 : 2;
|
||||
break;
|
||||
case 2: // Damage
|
||||
index = is_enemy(data) ? 2 : 3;
|
||||
break;
|
||||
case 3: // Face
|
||||
index = is_enemy(data) ? -1 : 0;
|
||||
break;
|
||||
}
|
||||
if (index < 0)
|
||||
return false;
|
||||
|
||||
size_t size;
|
||||
uint8_t *blob = chr_loader_get_blob(chr_loader_get_blob_handle(id, index), &size);
|
||||
if (!blob)
|
||||
return false;
|
||||
|
||||
struct cg *cg = cg_load_buffer(blob, size);
|
||||
if (!cg)
|
||||
return false;
|
||||
sprite_set_cg(sp, cg);
|
||||
cg_free(cg);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool ChrLoader_LoadWavFile(int sound_channel, int id)
|
||||
{
|
||||
int blob = chr_loader_get_blob_handle(id, 4);
|
||||
struct archive_data *dfile = chr_loader_get_blob_as_archive_data(blob);
|
||||
if (!dfile || !wav_prepare_from_archive_data(sound_channel, dfile)) {
|
||||
WARNING("ChrLoader.LoadWavFile %d failed", id);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool ChrLoader_LoadSentence(int id, int type, struct string **msg)
|
||||
{
|
||||
struct string *s = chr_loader_get_string(id, type);
|
||||
if (!s)
|
||||
return false;
|
||||
*msg = s;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool ChrLoader_GetName(int id, struct string **name)
|
||||
{
|
||||
struct string *s = chr_loader_get_name(id);
|
||||
if (!s)
|
||||
return false;
|
||||
*name = s;
|
||||
return true;
|
||||
}
|
||||
|
||||
HLL_LIBRARY(ChrLoader,
|
||||
@@ -237,6 +319,6 @@ HLL_LIBRARY(ChrLoader,
|
||||
HLL_EXPORT(LoadWavFile, ChrLoader_LoadWavFile),
|
||||
HLL_EXPORT(LoadSentence, ChrLoader_LoadSentence),
|
||||
HLL_EXPORT(GetName, ChrLoader_GetName),
|
||||
HLL_EXPORT(GetStatus, ChrLoader_GetStatus),
|
||||
HLL_EXPORT(IsExist, ChrLoader_IsExist)
|
||||
HLL_EXPORT(GetStatus, chr_loader_get_status),
|
||||
HLL_EXPORT(IsExist, chr_loader_exists)
|
||||
);
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
/* Copyright (C) 2024 kichikuou <KichikuouChrome@gmail.com>
|
||||
*
|
||||
* 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_CHRLOADER_H
|
||||
#define SYSTEM4_HLL_CHRLOADER_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
struct archive_data;
|
||||
struct string;
|
||||
|
||||
void chr_loader_init(const char *dir);
|
||||
bool chr_loader_exists(int id);
|
||||
struct string *chr_loader_get_name(int id);
|
||||
struct string *chr_loader_get_string(int id, int index);
|
||||
int chr_loader_get_id(int id);
|
||||
int chr_loader_get_status(int id, int type);
|
||||
int chr_loader_get_blob_handle(int id, int index);
|
||||
void *chr_loader_get_blob(int blob_handle, size_t *size);
|
||||
struct archive_data *chr_loader_get_blob_as_archive_data(int blob_handle);
|
||||
|
||||
#endif /* SYSTEM4_HLL_CHRLOADER_H */
|
||||
@@ -0,0 +1,25 @@
|
||||
/* Copyright (C) 2024 kichikuou <KichikuouChrome@gmail.com>
|
||||
*
|
||||
* 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 "hll.h"
|
||||
|
||||
HLL_WARN_UNIMPLEMENTED(1, int, MamanyoDemo, Init, void *imainsystem);
|
||||
HLL_WARN_UNIMPLEMENTED(0, int, MamanyoDemo, Run, void);
|
||||
|
||||
HLL_LIBRARY(MamanyoDemo,
|
||||
HLL_EXPORT(Init, MamanyoDemo_Init),
|
||||
HLL_EXPORT(Run, MamanyoDemo_Run)
|
||||
);
|
||||
@@ -0,0 +1,27 @@
|
||||
/* Copyright (C) 2024 kichikuou <KichikuouChrome@gmail.com>
|
||||
*
|
||||
* 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 "hll.h"
|
||||
|
||||
HLL_WARN_UNIMPLEMENTED(0, int, MamanyoSDemo, Init, void *imainsystem);
|
||||
//int MamanyoSDemo_Run(void);
|
||||
//int MamanyoSDemo_AddChara(int nNum);
|
||||
|
||||
HLL_LIBRARY(MamanyoSDemo,
|
||||
HLL_EXPORT(Init, MamanyoSDemo_Init),
|
||||
HLL_TODO_EXPORT(Run, MamanyoSDemo_Run),
|
||||
HLL_TODO_EXPORT(AddChara, MamanyoSDemo_AddChara)
|
||||
);
|
||||
@@ -0,0 +1,151 @@
|
||||
/* Copyright (C) 2024 kichikuou <KichikuouChrome@gmail.com>
|
||||
*
|
||||
* 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 <SDL.h>
|
||||
|
||||
#include "system4/cg.h"
|
||||
|
||||
#include "asset_manager.h"
|
||||
#include "audio.h"
|
||||
#include "gfx/gfx.h"
|
||||
#include "hll.h"
|
||||
#include "id_pool.h"
|
||||
|
||||
struct vm_anime {
|
||||
int cg;
|
||||
int length;
|
||||
int type;
|
||||
int interval;
|
||||
Point pos;
|
||||
int wave_channel;
|
||||
};
|
||||
|
||||
static struct id_pool pool;
|
||||
|
||||
static void vmAnime_New(possibly_unused void *imainsystem)
|
||||
{
|
||||
if (pool.slots)
|
||||
return; // already initialized
|
||||
id_pool_init(&pool, ID_POOL_HANDLE_BASE);
|
||||
}
|
||||
|
||||
static int vmAnime_EnumHandle(void)
|
||||
{
|
||||
return id_pool_count(&pool);
|
||||
}
|
||||
|
||||
static int vmAnime_Open(int cg, int length, int type)
|
||||
{
|
||||
int no = id_pool_get_unused(&pool);
|
||||
struct vm_anime *anime = xcalloc(1, sizeof(struct vm_anime));
|
||||
id_pool_set(&pool, no, anime);
|
||||
anime->cg = cg;
|
||||
anime->length = length;
|
||||
anime->type = type;
|
||||
return no;
|
||||
}
|
||||
|
||||
static void vmAnime_Close(int handle)
|
||||
{
|
||||
struct vm_anime *anime = id_pool_release(&pool, handle);
|
||||
if (anime)
|
||||
free(anime);
|
||||
}
|
||||
|
||||
static int vmAnime_Release(void)
|
||||
{
|
||||
for (int i = id_pool_get_first(&pool); i >= 0; i = id_pool_get_next(&pool, i))
|
||||
vmAnime_Close(i);
|
||||
id_pool_delete(&pool);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void vmAnime_ModuleFini(void)
|
||||
{
|
||||
vmAnime_Release();
|
||||
}
|
||||
|
||||
static void vmAnime_SetInterval(int handle, int interval)
|
||||
{
|
||||
struct vm_anime *anime = id_pool_get(&pool, handle);
|
||||
if (!anime)
|
||||
return;
|
||||
anime->interval = interval;
|
||||
}
|
||||
|
||||
static void vmAnime_SetPos(int handle, int x, int y)
|
||||
{
|
||||
struct vm_anime *anime = id_pool_get(&pool, handle);
|
||||
if (!anime)
|
||||
return;
|
||||
anime->pos.x = x;
|
||||
anime->pos.y = y;
|
||||
}
|
||||
|
||||
static void vmAnime_SetWave(int handle, int channel)
|
||||
{
|
||||
struct vm_anime *anime = id_pool_get(&pool, handle);
|
||||
if (!anime)
|
||||
return;
|
||||
anime->wave_channel = channel;
|
||||
}
|
||||
|
||||
static void vmAnime_Draw(int handle, int return_)
|
||||
{
|
||||
struct vm_anime *anime = id_pool_get(&pool, handle);
|
||||
if (!anime)
|
||||
return;
|
||||
|
||||
if (anime->wave_channel) {
|
||||
wav_stop(anime->wave_channel);
|
||||
wav_play(anime->wave_channel);
|
||||
}
|
||||
|
||||
Texture old;
|
||||
gfx_copy_main_surface(&old);
|
||||
Texture *dst = gfx_main_surface();
|
||||
|
||||
uint64_t start_time = SDL_GetTicks64();
|
||||
for (int i = 0; i < anime->length; i++) {
|
||||
struct cg *cg = asset_cg_load(anime->cg + i);
|
||||
Texture src;
|
||||
gfx_init_texture_with_cg(&src, cg);
|
||||
gfx_copy(dst, 0, 0, &old, 0, 0, old.w, old.h);
|
||||
gfx_blend_add_satur(dst, anime->pos.x, anime->pos.y, &src, 0, 0, src.w, src.h);
|
||||
gfx_delete_texture(&src);
|
||||
cg_free(cg);
|
||||
gfx_swap();
|
||||
SDL_Delay(start_time + (i + 1) * anime->interval - SDL_GetTicks64());
|
||||
}
|
||||
if (return_) {
|
||||
gfx_copy(dst, 0, 0, &old, 0, 0, old.w, old.h);
|
||||
gfx_swap();
|
||||
}
|
||||
gfx_delete_texture(&old);
|
||||
}
|
||||
|
||||
HLL_LIBRARY(vmAnime,
|
||||
HLL_EXPORT(_ModuleFini, vmAnime_ModuleFini),
|
||||
HLL_EXPORT(New, vmAnime_New),
|
||||
HLL_EXPORT(Release, vmAnime_Release),
|
||||
HLL_EXPORT(EnumHandle, vmAnime_EnumHandle),
|
||||
HLL_EXPORT(Open, vmAnime_Open),
|
||||
HLL_EXPORT(Close, vmAnime_Close),
|
||||
HLL_EXPORT(SetInterval, vmAnime_SetInterval),
|
||||
HLL_EXPORT(SetPos, vmAnime_SetPos),
|
||||
HLL_EXPORT(SetWave, vmAnime_SetWave),
|
||||
HLL_EXPORT(Draw, vmAnime_Draw)
|
||||
);
|
||||
@@ -0,0 +1,746 @@
|
||||
/* Copyright (C) 2024 kichikuou <KichikuouChrome@gmail.com>
|
||||
*
|
||||
* 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 <stdint.h>
|
||||
|
||||
#include "hll.h"
|
||||
#include "vm/page.h"
|
||||
|
||||
static void check_array(struct page *array)
|
||||
{
|
||||
if (array->type != ARRAY_PAGE || array->a_type != AIN_ARRAY_INT || array->array.rank != 1)
|
||||
VM_ERROR("Not a flat integer array");
|
||||
}
|
||||
|
||||
//int vmArray_GetAdd(struct page *array, int index);
|
||||
//int vmArray_GetSub(struct page *array, int index);
|
||||
//int vmArray_GetMul(struct page *array, int index);
|
||||
//int vmArray_GetDiv(struct page *array, int index);
|
||||
//int vmArray_GetAnd(struct page *array, int index);
|
||||
//int vmArray_GetOr(struct page *array, int index);
|
||||
//int vmArray_GetXor(struct page *array, int index);
|
||||
|
||||
static void transform(struct page *array, int index, int (*func)(int, void *), void *data)
|
||||
{
|
||||
if (!array)
|
||||
return;
|
||||
check_array(array);
|
||||
|
||||
if (index >= 0) {
|
||||
for (int i = index; i < array->nr_vars; i++) {
|
||||
array->values[i].i = func(array->values[i].i, data);
|
||||
}
|
||||
} else {
|
||||
for (int i = -index - 1; i >= 0; --i) {
|
||||
array->values[i].i = func(array->values[i].i, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline int32_t clamp(int64_t val)
|
||||
{
|
||||
if (val > INT32_MAX)
|
||||
return INT32_MAX;
|
||||
if (val < INT32_MIN)
|
||||
return INT32_MIN;
|
||||
return val;
|
||||
}
|
||||
|
||||
static int trans_add(int x, void *data)
|
||||
{
|
||||
int64_t y = *(int*)data;
|
||||
return clamp(x + y);
|
||||
}
|
||||
|
||||
static int trans_sub(int x, void *data)
|
||||
{
|
||||
int64_t y = *(int*)data;
|
||||
return clamp(x - y);
|
||||
}
|
||||
|
||||
static int trans_mul(int x, void *data)
|
||||
{
|
||||
int64_t y = *(int*)data;
|
||||
return clamp(x * y);
|
||||
}
|
||||
|
||||
static int trans_div(int x, void *data)
|
||||
{
|
||||
int64_t y = *(int*)data;
|
||||
return clamp(x / y);
|
||||
}
|
||||
|
||||
static int trans_and(int x, void *data)
|
||||
{
|
||||
int y = *(int*)data;
|
||||
return x & y;
|
||||
}
|
||||
|
||||
static int trans_or(int x, void *data)
|
||||
{
|
||||
int y = *(int*)data;
|
||||
return x | y;
|
||||
}
|
||||
|
||||
static int trans_xor(int x, void *data)
|
||||
{
|
||||
int y = *(int*)data;
|
||||
return x ^ y;
|
||||
}
|
||||
|
||||
static void vmArray_AddNum(struct page **array, int index, int num)
|
||||
{
|
||||
transform(*array, index, trans_add, &num);
|
||||
}
|
||||
|
||||
static void vmArray_SubNum(struct page **array, int index, int num)
|
||||
{
|
||||
transform(*array, index, trans_sub, &num);
|
||||
}
|
||||
|
||||
static void vmArray_MulNum(struct page **array, int index, int num)
|
||||
{
|
||||
transform(*array, index, trans_mul, &num);
|
||||
}
|
||||
|
||||
static void vmArray_DivNum(struct page **array, int index, int num)
|
||||
{
|
||||
if (num != 0)
|
||||
transform(*array, index, trans_div, &num);
|
||||
}
|
||||
|
||||
static void vmArray_AndNum(struct page **array, int index, int num)
|
||||
{
|
||||
transform(*array, index, trans_and, &num);
|
||||
}
|
||||
|
||||
static void vmArray_OrNum(struct page **array, int index, int num)
|
||||
{
|
||||
transform(*array, index, trans_or, &num);
|
||||
}
|
||||
|
||||
static void vmArray_XorNum(struct page **array, int index, int num)
|
||||
{
|
||||
transform(*array, index, trans_xor, &num);
|
||||
}
|
||||
|
||||
//void vmArray_MinNum(struct page **array, int index, int num);
|
||||
//void vmArray_MaxNum(struct page **array, int index, int num);
|
||||
|
||||
struct vmarray_iter {
|
||||
struct page *array;
|
||||
int index;
|
||||
};
|
||||
|
||||
static int trans_add_array(int x, void *data)
|
||||
{
|
||||
struct vmarray_iter *iter = data;
|
||||
return clamp((int64_t)x + iter->array->values[iter->index++].i);
|
||||
}
|
||||
|
||||
static int trans_sub_array(int x, void *data)
|
||||
{
|
||||
struct vmarray_iter *iter = data;
|
||||
return clamp((int64_t)x - iter->array->values[iter->index++].i);
|
||||
}
|
||||
|
||||
static int trans_mul_array(int x, void *data)
|
||||
{
|
||||
struct vmarray_iter *iter = data;
|
||||
return clamp((int64_t)x * iter->array->values[iter->index++].i);
|
||||
}
|
||||
|
||||
static int trans_div_array(int x, void *data)
|
||||
{
|
||||
struct vmarray_iter *iter = data;
|
||||
int rhs = iter->array->values[iter->index++].i;
|
||||
return rhs ? x / rhs : x;
|
||||
}
|
||||
|
||||
static int trans_and_array(int x, void *data)
|
||||
{
|
||||
struct vmarray_iter *iter = data;
|
||||
return x & iter->array->values[iter->index++].i;
|
||||
}
|
||||
|
||||
static int trans_or_array(int x, void *data)
|
||||
{
|
||||
struct vmarray_iter *iter = data;
|
||||
return x | iter->array->values[iter->index++].i;
|
||||
}
|
||||
|
||||
static int trans_xor_array(int x, void *data)
|
||||
{
|
||||
struct vmarray_iter *iter = data;
|
||||
return x ^ iter->array->values[iter->index++].i;
|
||||
}
|
||||
|
||||
static void vmArray_AddArray(struct page **d_array, int index, struct page *s_array)
|
||||
{
|
||||
struct vmarray_iter iter = { s_array, 0 };
|
||||
transform(*d_array, index, trans_add_array, &iter);
|
||||
}
|
||||
|
||||
static void vmArray_SubArray(struct page **d_array, int index, struct page *s_array)
|
||||
{
|
||||
struct vmarray_iter iter = { s_array, 0 };
|
||||
transform(*d_array, index, trans_sub_array, &iter);
|
||||
}
|
||||
|
||||
static void vmArray_MulArray(struct page **d_array, int index, struct page *s_array)
|
||||
{
|
||||
struct vmarray_iter iter = { s_array, 0 };
|
||||
transform(*d_array, index, trans_mul_array, &iter);
|
||||
}
|
||||
|
||||
static void vmArray_DivArray(struct page **d_array, int index, struct page *s_array)
|
||||
{
|
||||
struct vmarray_iter iter = { s_array, 0 };
|
||||
transform(*d_array, index, trans_div_array, &iter);
|
||||
}
|
||||
|
||||
static void vmArray_AndArray(struct page **d_array, int index, struct page *s_array)
|
||||
{
|
||||
struct vmarray_iter iter = { s_array, 0 };
|
||||
transform(*d_array, index, trans_and_array, &iter);
|
||||
}
|
||||
|
||||
static void vmArray_OrArray(struct page **d_array, int index, struct page *s_array)
|
||||
{
|
||||
struct vmarray_iter iter = { s_array, 0 };
|
||||
transform(*d_array, index, trans_or_array, &iter);
|
||||
}
|
||||
|
||||
static void vmArray_XorArray(struct page **d_array, int index, struct page *s_array)
|
||||
{
|
||||
struct vmarray_iter iter = { s_array, 0 };
|
||||
transform(*d_array, index, trans_xor_array, &iter);
|
||||
}
|
||||
|
||||
//void vmArray_MinArray(struct page **d_array, int index, struct page *s_array);
|
||||
//void vmArray_MaxArray(struct page **d_array, int index, struct page *s_array);
|
||||
|
||||
static bool pred_equal(int x, void *data)
|
||||
{
|
||||
int y = *(int*)data;
|
||||
return x == y;
|
||||
}
|
||||
|
||||
static bool pred_not_equal(int x, void *data)
|
||||
{
|
||||
int y = *(int*)data;
|
||||
return x != y;
|
||||
}
|
||||
|
||||
static bool pred_low(int x, void *data)
|
||||
{
|
||||
int y = *(int*)data;
|
||||
return x <= y;
|
||||
}
|
||||
|
||||
static bool pred_high(int x, void *data)
|
||||
{
|
||||
int y = *(int*)data;
|
||||
return y <= x;
|
||||
}
|
||||
|
||||
struct range {
|
||||
int min;
|
||||
int max;
|
||||
};
|
||||
|
||||
static bool pred_in_range(int x, void *data)
|
||||
{
|
||||
struct range *r = data;
|
||||
return r->min <= x && x <= r->max;
|
||||
}
|
||||
|
||||
static int count_if(struct page *array, int index, bool (*pred)(int, void *), void *data)
|
||||
{
|
||||
if (!array)
|
||||
return 0;
|
||||
check_array(array);
|
||||
|
||||
int count = 0;
|
||||
for (int i = index; i < array->nr_vars; i++) {
|
||||
if (pred(array->values[i].i, data))
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
static int vmArray_EnumEquNum(struct page *array, int index, int num)
|
||||
{
|
||||
return count_if(array, index, pred_equal, &num);
|
||||
}
|
||||
|
||||
static int vmArray_EnumNotNum(struct page *array, int index, int num)
|
||||
{
|
||||
return count_if(array, index, pred_not_equal, &num);
|
||||
}
|
||||
|
||||
static int vmArray_EnumLowNum(struct page *array, int index, int num)
|
||||
{
|
||||
return count_if(array, index, pred_low, &num);
|
||||
}
|
||||
|
||||
static int vmArray_EnumHighNum(struct page *array, int index, int num)
|
||||
{
|
||||
return count_if(array, index, pred_high, &num);
|
||||
}
|
||||
|
||||
static int vmArray_EnumRangeNum(struct page *array, int index, int min, int max)
|
||||
{
|
||||
struct range r = { .min = min, .max = max };
|
||||
return count_if(array, index, pred_in_range, &r);
|
||||
}
|
||||
|
||||
static void replace(struct page *array, int index, int n, bool (*pred)(int, void *), void *data)
|
||||
{
|
||||
if (!array)
|
||||
return;
|
||||
check_array(array);
|
||||
|
||||
for (int i = index; i < array->nr_vars; i++) {
|
||||
if (pred(array->values[i].i, data))
|
||||
array->values[i].i = n;
|
||||
}
|
||||
}
|
||||
|
||||
static void vmArray_ChangeEquNum(struct page **array, int index, int num, int exg)
|
||||
{
|
||||
replace(*array, index, exg, pred_equal, &num);
|
||||
}
|
||||
|
||||
static void vmArray_ChangeNotNum(struct page **array, int index, int num, int exg)
|
||||
{
|
||||
replace(*array, index, exg, pred_not_equal, &num);
|
||||
}
|
||||
|
||||
static void vmArray_ChangeLowNum(struct page **array, int index, int num, int exg)
|
||||
{
|
||||
replace(*array, index, exg, pred_low, &num);
|
||||
}
|
||||
|
||||
static void vmArray_ChangeHighNum(struct page **array, int index, int num, int exg)
|
||||
{
|
||||
replace(*array, index, exg, pred_high, &num);
|
||||
}
|
||||
|
||||
static void vmArray_ChangeRangeNum(struct page **array, int index, int min, int max, int exg)
|
||||
{
|
||||
struct range r = { .min = min, .max = max };
|
||||
replace(*array, index, exg, pred_in_range, &r);
|
||||
}
|
||||
|
||||
static int find(struct page *array, int index, bool (*pred)(int, void *), void *data, int *out_index)
|
||||
{
|
||||
if (!array)
|
||||
return 0;
|
||||
check_array(array);
|
||||
|
||||
if (index >= 0) {
|
||||
for (int i = index; i < array->nr_vars; i++) {
|
||||
if (pred(array->values[i].i, data)) {
|
||||
*out_index = i;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int i = -index - 1; i >= 0; --i) {
|
||||
if (pred(array->values[i].i, data)) {
|
||||
*out_index = i;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vmArray_GrepEquNum(struct page *array, int index, int num, int *out_index)
|
||||
{
|
||||
return find(array, index, pred_equal, &num, out_index);
|
||||
}
|
||||
|
||||
static int vmArray_GrepNotNum(struct page *array, int index, int num, int *out_index)
|
||||
{
|
||||
return find(array, index, pred_not_equal, &num, out_index);
|
||||
}
|
||||
|
||||
static int vmArray_GrepLowNum(struct page *array, int index, int num, int *out_index)
|
||||
{
|
||||
return find(array, index, pred_low, &num, out_index);
|
||||
}
|
||||
|
||||
static int vmArray_GrepHighNum(struct page *array, int index, int num, int *out_index)
|
||||
{
|
||||
return find(array, index, pred_high, &num, out_index);
|
||||
}
|
||||
|
||||
static int vmArray_GrepRangeNum(struct page *array, int index, int min, int max, int *out_index)
|
||||
{
|
||||
struct range r = { .min = min, .max = max };
|
||||
return find(array, index, pred_in_range, &r, out_index);
|
||||
}
|
||||
|
||||
static int vmArray_GrepLowOrder(struct page *s_array, int index, struct page **d_array_, int *out_index)
|
||||
{
|
||||
struct page *d_array = *d_array_;
|
||||
check_array(s_array);
|
||||
check_array(d_array);
|
||||
|
||||
if (index < 0)
|
||||
VM_ERROR("not implemented");
|
||||
|
||||
int min_index = -1, min_value;
|
||||
for (int i = index; i < s_array->nr_vars; i++) {
|
||||
if (d_array->values[i].i)
|
||||
continue;
|
||||
int val = s_array->values[i].i;
|
||||
if (min_index < 0 || val < min_value) {
|
||||
min_index = i;
|
||||
min_value = val;
|
||||
}
|
||||
}
|
||||
if (min_index < 0)
|
||||
return 0;
|
||||
*out_index = min_index;
|
||||
d_array->values[min_index].i = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int vmArray_GrepHighOrder(struct page *s_array, int index, struct page **d_array_, int *out_index)
|
||||
{
|
||||
struct page *d_array = *d_array_;
|
||||
check_array(s_array);
|
||||
check_array(d_array);
|
||||
|
||||
if (index < 0)
|
||||
VM_ERROR("not implemented");
|
||||
|
||||
int max_index = -1, max_value;
|
||||
for (int i = index; i < s_array->nr_vars; i++) {
|
||||
if (d_array->values[i].i)
|
||||
continue;
|
||||
int val = s_array->values[i].i;
|
||||
if (max_index < 0 || val > max_value) {
|
||||
max_index = i;
|
||||
max_value = val;
|
||||
}
|
||||
}
|
||||
if (max_index < 0)
|
||||
return 0;
|
||||
*out_index = max_index;
|
||||
d_array->values[max_index].i = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void map_predicate(struct page *s_array, int index, bool (*pred)(int, void *), void *data, struct page *d_array)
|
||||
{
|
||||
if (!s_array || !d_array)
|
||||
return;
|
||||
check_array(s_array);
|
||||
check_array(d_array);
|
||||
|
||||
if (index >= 0) {
|
||||
for (int i = index; i < s_array->nr_vars; i++) {
|
||||
d_array->values[i].i = pred(s_array->values[i].i, data) ? 1 : 0;
|
||||
}
|
||||
} else {
|
||||
for (int i = -index - 1; i >= 0; --i) {
|
||||
d_array->values[i].i = pred(s_array->values[i].i, data) ? 1 : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void vmArray_SetEquNum(struct page *s_array, int index, int num, struct page **d_array)
|
||||
{
|
||||
map_predicate(s_array, index, pred_equal, &num, *d_array);
|
||||
}
|
||||
|
||||
static void vmArray_SetNotNum(struct page *s_array, int index, int num, struct page **d_array)
|
||||
{
|
||||
map_predicate(s_array, index, pred_not_equal, &num, *d_array);
|
||||
}
|
||||
|
||||
static void vmArray_SetLowNum(struct page *s_array, int index, int num, struct page **d_array)
|
||||
{
|
||||
map_predicate(s_array, index, pred_low, &num, *d_array);
|
||||
}
|
||||
|
||||
static void vmArray_SetHighNum(struct page *s_array, int index, int num, struct page **d_array)
|
||||
{
|
||||
map_predicate(s_array, index, pred_high, &num, *d_array);
|
||||
}
|
||||
|
||||
static void vmArray_SetRangeNum(struct page *s_array, int index, int min, int max, struct page **d_array)
|
||||
{
|
||||
struct range r = { .min = min, .max = max };
|
||||
map_predicate(s_array, index, pred_in_range, &r, *d_array);
|
||||
}
|
||||
|
||||
//void vmArray_AndEquNum(struct page *pISVMArray, int index, int num, struct page **pIDVMArray);
|
||||
//void vmArray_AndNotNum(struct page *pISVMArray, int index, int num, struct page **pIDVMArray);
|
||||
//void vmArray_AndLowNum(struct page *pISVMArray, int index, int num, struct page **pIDVMArray);
|
||||
//void vmArray_AndHighNum(struct page *pISVMArray, int index, int num, struct page **pIDVMArray);
|
||||
//void vmArray_AndRangeNum(struct page *pISVMArray, int index, int nMin, int nMax, struct page **pIDVMArray);
|
||||
|
||||
static void set_if(struct page *s_array, int index, bool (*pred)(int, void *), void *data, struct page *d_array)
|
||||
{
|
||||
if (!s_array || !d_array)
|
||||
return;
|
||||
check_array(s_array);
|
||||
check_array(d_array);
|
||||
|
||||
if (index >= 0) {
|
||||
for (int i = index; i < s_array->nr_vars; i++) {
|
||||
if (pred(s_array->values[i].i, data))
|
||||
d_array->values[i].i = 1;
|
||||
}
|
||||
} else {
|
||||
for (int i = -index - 1; i >= 0; --i) {
|
||||
if (pred(s_array->values[i].i, data))
|
||||
d_array->values[i].i = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void vmArray_OrEquNum(struct page *s_array, int index, int num, struct page **d_array)
|
||||
{
|
||||
set_if(s_array, index, pred_equal, &num, *d_array);
|
||||
}
|
||||
|
||||
static void vmArray_OrNotNum(struct page *s_array, int index, int num, struct page **d_array)
|
||||
{
|
||||
set_if(s_array, index, pred_not_equal, &num, *d_array);
|
||||
}
|
||||
|
||||
static void vmArray_OrLowNum(struct page *s_array, int index, int num, struct page **d_array)
|
||||
{
|
||||
set_if(s_array, index, pred_low, &num, *d_array);
|
||||
}
|
||||
|
||||
static void vmArray_OrHighNum(struct page *s_array, int index, int num, struct page **d_array)
|
||||
{
|
||||
set_if(s_array, index, pred_high, &num, *d_array);
|
||||
}
|
||||
|
||||
static void vmArray_OrRangeNum(struct page *s_array, int index, int min, int max, struct page **d_array)
|
||||
{
|
||||
struct range r = { .min = min, .max = max };
|
||||
set_if(s_array, index, pred_in_range, &r, *d_array);
|
||||
}
|
||||
|
||||
// Find num by visiting elements spirally around (x, y).
|
||||
static int vmArray_AroundRect(struct page *array, int width, int height, int x, int y, int length, int num, int *out_x, int *out_y)
|
||||
{
|
||||
for (int dist = 1;; dist++) {
|
||||
if (--length < 0)
|
||||
return 0;
|
||||
y--;
|
||||
if (0 <= x && x < width && 0 <= y && y < height && array->values[y * width + x].i == num)
|
||||
goto found;
|
||||
|
||||
for (int i = 0; i < dist; i++) {
|
||||
if (--length < 0)
|
||||
return 0;
|
||||
x++;
|
||||
y++;
|
||||
if (0 <= x && x < width && 0 <= y && y < height && array->values[y * width + x].i == num)
|
||||
goto found;
|
||||
}
|
||||
for (int i = 0; i < dist; i++) {
|
||||
if (--length < 0)
|
||||
return 0;
|
||||
x--;
|
||||
y++;
|
||||
if (0 <= x && x < width && 0 <= y && y < height && array->values[y * width + x].i == num)
|
||||
goto found;
|
||||
}
|
||||
for (int i = 0; i < dist; i++) {
|
||||
if (--length < 0)
|
||||
return 0;
|
||||
x--;
|
||||
y--;
|
||||
if (0 <= x && x < width && 0 <= y && y < height && array->values[y * width + x].i == num)
|
||||
goto found;
|
||||
}
|
||||
for (int i = 0; i < dist; i++) {
|
||||
if (--length < 0)
|
||||
return 0;
|
||||
x++;
|
||||
y--;
|
||||
if (0 <= x && x < width && 0 <= y && y < height && array->values[y * width + x].i == num)
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
found:
|
||||
*out_x = x;
|
||||
*out_y = y;
|
||||
return 1;
|
||||
}
|
||||
|
||||
//int vmArray_AroundHexa(struct page *array, int nWidth, int nHeight, int nX, int nY, int nLength, int num, int *pnRX, int *pnRY);
|
||||
|
||||
static int vmArray_PaintRect(struct page **array_, int width, int height, int x, int y, int length)
|
||||
{
|
||||
struct page *array = *array_;
|
||||
check_array(array);
|
||||
if (array->nr_vars < width * height || x >= width || y >= height || length < 0)
|
||||
return 0;
|
||||
|
||||
int size = width * height;
|
||||
for (int i = 0; i < size; i++) {
|
||||
array->values[i].i = array->values[i].i < 0 ? -2 : -1;
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
array->values[y * width + x].i = 0;
|
||||
for (int dist = 0; dist < length; dist++) {
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (array->values[i].i != dist)
|
||||
continue;
|
||||
if (i / width > 0 && array->values[i - width].i == -1) {
|
||||
array->values[i - width].i = dist + 1;
|
||||
count++;
|
||||
}
|
||||
if (i / width < height - 1 && array->values[i + width].i == -1) {
|
||||
array->values[i + width].i = dist + 1;
|
||||
count++;
|
||||
}
|
||||
if (i % width > 0 && array->values[i - 1].i == -1) {
|
||||
array->values[i - 1].i = dist + 1;
|
||||
count++;
|
||||
}
|
||||
if (i % width < width - 1 && array->values[i + 1].i == -1) {
|
||||
array->values[i + 1].i = dist + 1;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
//int vmArray_PaintHexa(struct page **pIVMArray, int nWidth, int nHeight, int nX, int nY, int nLength);
|
||||
|
||||
static int vmArray_CopyRectToRect(struct page **d_array_, int dw, int dh, int dx, int dy, struct page *s_array, int sw, int sh, int sx, int sy, int w, int h)
|
||||
{
|
||||
struct page *d_array = *d_array_;
|
||||
check_array(s_array);
|
||||
check_array(d_array);
|
||||
if (s_array->nr_vars < sw * sh || d_array->nr_vars < dw * dh)
|
||||
return 0;
|
||||
|
||||
for (int y = 0; y < h; y++) {
|
||||
for (int x = 0; x < w; x++) {
|
||||
if (dx + x < 0 || dx + x >= dw || dy + y < 0 || dy + y >= dh)
|
||||
continue;
|
||||
if (sx + x < 0 || sx + x >= sw || sy + y < 0 || sy + y >= sh)
|
||||
continue;
|
||||
d_array->values[(dy + y) * dw + dx + x] = s_array->values[(sy + y) * sw + sx + x];
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
//int vmArray_CopyHexaToHexa(struct page **pIDVMArray, int nDWidth, int nDHeight, int nDx, int nDy, struct page *pISVMArray, int nSWidth, int nSHeight, int nSx, int nSy, int nCWidth, int nCHeight);
|
||||
|
||||
// Transpose s_array (as a 2D array of s_width * s_height) into d_array.
|
||||
static int vmArray_ConvertRectSide(struct page **d_array_, struct page *s_array, int s_width, int s_height, int side)
|
||||
{
|
||||
struct page *d_array = *d_array_;
|
||||
check_array(s_array);
|
||||
check_array(d_array);
|
||||
int w = side ? s_width : s_height;
|
||||
int h = side ? s_height : s_width;
|
||||
|
||||
if (s_array->nr_vars < w * h || d_array->nr_vars < w * h)
|
||||
return 0;
|
||||
|
||||
for (int y = 0; y < h; y++) {
|
||||
for (int x = 0; x < w; x++) {
|
||||
d_array->values[x * h + y] = s_array->values[y * w + x];
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
HLL_LIBRARY(vmArray,
|
||||
HLL_TODO_EXPORT(GetAdd, vmArray_GetAdd),
|
||||
HLL_TODO_EXPORT(GetSub, vmArray_GetSub),
|
||||
HLL_TODO_EXPORT(GetMul, vmArray_GetMul),
|
||||
HLL_TODO_EXPORT(GetDiv, vmArray_GetDiv),
|
||||
HLL_TODO_EXPORT(GetAnd, vmArray_GetAnd),
|
||||
HLL_TODO_EXPORT(GetOr, vmArray_GetOr),
|
||||
HLL_TODO_EXPORT(GetXor, vmArray_GetXor),
|
||||
HLL_EXPORT(AddNum, vmArray_AddNum),
|
||||
HLL_EXPORT(SubNum, vmArray_SubNum),
|
||||
HLL_EXPORT(MulNum, vmArray_MulNum),
|
||||
HLL_EXPORT(DivNum, vmArray_DivNum),
|
||||
HLL_EXPORT(AndNum, vmArray_AndNum),
|
||||
HLL_EXPORT(OrNum, vmArray_OrNum),
|
||||
HLL_EXPORT(XorNum, vmArray_XorNum),
|
||||
HLL_TODO_EXPORT(MinNum, vmArray_MinNum),
|
||||
HLL_TODO_EXPORT(MaxNum, vmArray_MaxNum),
|
||||
HLL_EXPORT(AddArray, vmArray_AddArray),
|
||||
HLL_EXPORT(SubArray, vmArray_SubArray),
|
||||
HLL_EXPORT(MulArray, vmArray_MulArray),
|
||||
HLL_EXPORT(DivArray, vmArray_DivArray),
|
||||
HLL_EXPORT(AndArray, vmArray_AndArray),
|
||||
HLL_EXPORT(OrArray, vmArray_OrArray),
|
||||
HLL_EXPORT(XorArray, vmArray_XorArray),
|
||||
HLL_TODO_EXPORT(MinArray, vmArray_MinArray),
|
||||
HLL_TODO_EXPORT(MaxArray, vmArray_MaxArray),
|
||||
HLL_EXPORT(EnumEquNum, vmArray_EnumEquNum),
|
||||
HLL_EXPORT(EnumNotNum, vmArray_EnumNotNum),
|
||||
HLL_EXPORT(EnumLowNum, vmArray_EnumLowNum),
|
||||
HLL_EXPORT(EnumHighNum, vmArray_EnumHighNum),
|
||||
HLL_EXPORT(EnumRangeNum, vmArray_EnumRangeNum),
|
||||
HLL_EXPORT(ChangeEquNum, vmArray_ChangeEquNum),
|
||||
HLL_EXPORT(ChangeNotNum, vmArray_ChangeNotNum),
|
||||
HLL_EXPORT(ChangeLowNum, vmArray_ChangeLowNum),
|
||||
HLL_EXPORT(ChangeHighNum, vmArray_ChangeHighNum),
|
||||
HLL_EXPORT(ChangeRangeNum, vmArray_ChangeRangeNum),
|
||||
HLL_EXPORT(GrepEquNum, vmArray_GrepEquNum),
|
||||
HLL_EXPORT(GrepNotNum, vmArray_GrepNotNum),
|
||||
HLL_EXPORT(GrepLowNum, vmArray_GrepLowNum),
|
||||
HLL_EXPORT(GrepHighNum, vmArray_GrepHighNum),
|
||||
HLL_EXPORT(GrepRangeNum, vmArray_GrepRangeNum),
|
||||
HLL_EXPORT(GrepLowOrder, vmArray_GrepLowOrder),
|
||||
HLL_EXPORT(GrepHighOrder, vmArray_GrepHighOrder),
|
||||
HLL_EXPORT(SetEquNum, vmArray_SetEquNum),
|
||||
HLL_EXPORT(SetNotNum, vmArray_SetNotNum),
|
||||
HLL_EXPORT(SetLowNum, vmArray_SetLowNum),
|
||||
HLL_EXPORT(SetHighNum, vmArray_SetHighNum),
|
||||
HLL_EXPORT(SetRangeNum, vmArray_SetRangeNum),
|
||||
HLL_TODO_EXPORT(AndEquNum, vmArray_AndEquNum),
|
||||
HLL_TODO_EXPORT(AndNotNum, vmArray_AndNotNum),
|
||||
HLL_TODO_EXPORT(AndLowNum, vmArray_AndLowNum),
|
||||
HLL_TODO_EXPORT(AndHighNum, vmArray_AndHighNum),
|
||||
HLL_TODO_EXPORT(AndRangeNum, vmArray_AndRangeNum),
|
||||
HLL_EXPORT(OrEquNum, vmArray_OrEquNum),
|
||||
HLL_EXPORT(OrNotNum, vmArray_OrNotNum),
|
||||
HLL_EXPORT(OrLowNum, vmArray_OrLowNum),
|
||||
HLL_EXPORT(OrHighNum, vmArray_OrHighNum),
|
||||
HLL_EXPORT(OrRangeNum, vmArray_OrRangeNum),
|
||||
HLL_EXPORT(AroundRect, vmArray_AroundRect),
|
||||
HLL_TODO_EXPORT(AroundHexa, vmArray_AroundHexa),
|
||||
HLL_EXPORT(PaintRect, vmArray_PaintRect),
|
||||
HLL_TODO_EXPORT(PaintHexa, vmArray_PaintHexa),
|
||||
HLL_EXPORT(CopyRectToRect, vmArray_CopyRectToRect),
|
||||
HLL_TODO_EXPORT(CopyHexaToHexa, vmArray_CopyHexaToHexa),
|
||||
HLL_EXPORT(ConvertRectSide, vmArray_ConvertRectSide)
|
||||
);
|
||||
@@ -0,0 +1,85 @@
|
||||
/* Copyright (C) 2024 kichikuou <KichikuouChrome@gmail.com>
|
||||
*
|
||||
* 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 "system4.h"
|
||||
#include "system4/cg.h"
|
||||
|
||||
#include "asset_manager.h"
|
||||
#include "gfx/gfx.h"
|
||||
#include "hll.h"
|
||||
#include "vmSurface.h"
|
||||
|
||||
HLL_QUIET_UNIMPLEMENTED( , void, vmCG, New, void);
|
||||
//int vmCG_Release(void);
|
||||
HLL_WARN_UNIMPLEMENTED( , void, vmCG, SetType, int type);
|
||||
//int vmCG_EnumHandle(void);
|
||||
|
||||
static int vmCG_Exist(int num)
|
||||
{
|
||||
return asset_exists(ASSET_CG, num);
|
||||
}
|
||||
|
||||
static int vmCG_Load(int num)
|
||||
{
|
||||
struct cg *cg = asset_cg_load(num);
|
||||
if (!cg)
|
||||
return 0;
|
||||
struct vm_surface *sf = vm_surface_create(cg->metrics.w, cg->metrics.h);
|
||||
gfx_init_texture_with_cg(&sf->texture, cg);
|
||||
sf->has_pixel = cg->metrics.has_pixel;
|
||||
sf->has_alpha = cg->metrics.has_alpha;
|
||||
sf->cg_no = num;
|
||||
cg_free(cg);
|
||||
return sf->no;
|
||||
}
|
||||
|
||||
static void vmCG_Unload(int surface)
|
||||
{
|
||||
vm_surface_delete(surface);
|
||||
}
|
||||
|
||||
static int vmCG_Trans(int surface, int x, int y, int num)
|
||||
{
|
||||
struct vm_surface *sf = vm_surface_get(surface);
|
||||
if (!sf)
|
||||
return 0;
|
||||
|
||||
struct cg *cg = asset_cg_load(num);
|
||||
if (!cg)
|
||||
return 0;
|
||||
|
||||
Texture src;
|
||||
gfx_init_texture_with_cg(&src, cg);
|
||||
cg_free(cg);
|
||||
|
||||
if (sf->has_alpha)
|
||||
gfx_copy_with_alpha_map(&sf->texture, x, y, &src, 0, 0, src.w, src.h);
|
||||
else
|
||||
gfx_blend_amap(&sf->texture, x, y, &src, 0, 0, src.w, src.h);
|
||||
gfx_delete_texture(&src);
|
||||
return 1;
|
||||
}
|
||||
|
||||
HLL_LIBRARY(vmCG,
|
||||
HLL_EXPORT(New, vmCG_New),
|
||||
HLL_TODO_EXPORT(Release, vmCG_Release),
|
||||
HLL_EXPORT(SetType, vmCG_SetType),
|
||||
HLL_TODO_EXPORT(EnumHandle, vmCG_EnumHandle),
|
||||
HLL_EXPORT(Exist, vmCG_Exist),
|
||||
HLL_EXPORT(Load, vmCG_Load),
|
||||
HLL_EXPORT(Unload, vmCG_Unload),
|
||||
HLL_EXPORT(Trans, vmCG_Trans)
|
||||
);
|
||||
@@ -0,0 +1,89 @@
|
||||
/* Copyright (C) 2024 kichikuou <KichikuouChrome@gmail.com>
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "system4.h"
|
||||
#include "system4/cg.h"
|
||||
#include "system4/string.h"
|
||||
|
||||
#include "gfx/gfx.h"
|
||||
#include "hll.h"
|
||||
#include "ChrLoader.h"
|
||||
#include "vmSurface.h"
|
||||
#include "xsystem4.h"
|
||||
|
||||
static void vmChrLoader_Init(possibly_unused void *imainsystem, possibly_unused struct string *string)
|
||||
{
|
||||
chr_loader_init("Chr");
|
||||
}
|
||||
|
||||
static int vmChrLoader_Exist(int id)
|
||||
{
|
||||
return chr_loader_exists(id) ? 1 : 0;
|
||||
}
|
||||
|
||||
HLL_QUIET_UNIMPLEMENTED(, void, vmChrLoader, ReleaseMemory, int id, int index);
|
||||
|
||||
static struct string *vmChrLoader_GetMsg(int id, int index)
|
||||
{
|
||||
struct string *msg = chr_loader_get_string(id, index);
|
||||
return msg ? msg : string_ref(&EMPTY_STRING);
|
||||
}
|
||||
|
||||
static struct string *vmChrLoader_GetName(int id)
|
||||
{
|
||||
struct string *name = chr_loader_get_name(id);
|
||||
return name ? name : string_ref(&EMPTY_STRING);
|
||||
}
|
||||
|
||||
static int vmChrLoader_MemoryToSurface(int memory, int x, int y, int surface)
|
||||
{
|
||||
struct vm_surface *sf = vm_surface_get(surface);
|
||||
if (!sf)
|
||||
return 0;
|
||||
|
||||
size_t size;
|
||||
void *data = chr_loader_get_blob(memory, &size);
|
||||
if (!data)
|
||||
return 0;
|
||||
|
||||
struct cg *cg = cg_load_buffer(data, size);
|
||||
if (!cg)
|
||||
return 0;
|
||||
|
||||
Texture tex;
|
||||
gfx_init_texture_with_cg(&tex, cg);
|
||||
cg_free(cg);
|
||||
|
||||
gfx_copy(&sf->texture, x, y, &tex, 0, 0, tex.w, tex.h);
|
||||
gfx_delete_texture(&tex);
|
||||
return 1;
|
||||
}
|
||||
|
||||
HLL_LIBRARY(vmChrLoader,
|
||||
HLL_EXPORT(Init, vmChrLoader_Init),
|
||||
HLL_EXPORT(Exist, vmChrLoader_Exist),
|
||||
HLL_EXPORT(GetID, chr_loader_get_id),
|
||||
HLL_EXPORT(GetStatus, chr_loader_get_status),
|
||||
HLL_EXPORT(GetMemory, chr_loader_get_blob_handle),
|
||||
HLL_EXPORT(ReleaseMemory, vmChrLoader_ReleaseMemory),
|
||||
HLL_EXPORT(GetMsg, vmChrLoader_GetMsg),
|
||||
HLL_EXPORT(GetName, vmChrLoader_GetName),
|
||||
HLL_EXPORT(MemoryToSurface, vmChrLoader_MemoryToSurface)
|
||||
);
|
||||
@@ -0,0 +1,43 @@
|
||||
/* Copyright (C) 2024 kichikuou <KichikuouChrome@gmail.com>
|
||||
*
|
||||
* 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 "hll.h"
|
||||
#include "input.h"
|
||||
|
||||
HLL_QUIET_UNIMPLEMENTED( , void, vmCursor, Init, void *imainsystem);
|
||||
|
||||
static void vmCursor_SetPos(int x, int y)
|
||||
{
|
||||
mouse_set_pos(x, y);
|
||||
}
|
||||
|
||||
static int vmCursor_GetPos(int *x, int *y)
|
||||
{
|
||||
handle_events();
|
||||
mouse_get_pos(x, y);
|
||||
return mouse_focus && keyboard_focus;
|
||||
}
|
||||
|
||||
//void vmCursor_SetShow(int nShow);
|
||||
//int vmCursor_GetShow(void);
|
||||
|
||||
HLL_LIBRARY(vmCursor,
|
||||
HLL_EXPORT(Init, vmCursor_Init),
|
||||
HLL_EXPORT(SetPos, vmCursor_SetPos),
|
||||
HLL_EXPORT(GetPos, vmCursor_GetPos),
|
||||
HLL_TODO_EXPORT(SetShow, vmCursor_SetShow),
|
||||
HLL_TODO_EXPORT(GetShow, vmCursor_GetShow)
|
||||
);
|
||||
@@ -0,0 +1,53 @@
|
||||
/* Copyright (C) 2024 kichikuou <KichikuouChrome@gmail.com>
|
||||
*
|
||||
* 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 <SDL.h>
|
||||
|
||||
#include "system4/string.h"
|
||||
#include "system4/utfsjis.h"
|
||||
|
||||
#include "hll.h"
|
||||
|
||||
HLL_QUIET_UNIMPLEMENTED( , void, vmDialog, Init, void *imainsystem);
|
||||
|
||||
static int vmDialog_MsgBox(struct string *t_string, struct string *string, int type, possibly_unused int default_button)
|
||||
{
|
||||
uint32_t flags = (type == 4) ? SDL_MESSAGEBOX_ERROR : 0;
|
||||
char *title = sjis2utf(t_string->text, 0);
|
||||
char *message = sjis2utf(string->text, 0);
|
||||
SDL_ShowSimpleMessageBox(flags, title, message, NULL);
|
||||
free(message);
|
||||
free(title);
|
||||
return 1;
|
||||
}
|
||||
|
||||
//int vmDialog_InputNum(struct string *pITString, int nMin, int nMax, int *pnNum);
|
||||
//int vmDialog_InputString(struct string *pITString, int nLength, struct string **pIString);
|
||||
//int vmDialog_SelectNum(struct string *pITString, int nMin, int nMax, int *pnNum);
|
||||
//int vmDialog_SelectString(struct string *pITString, struct page **pIVMArray, int nNum, struct string **pIString);
|
||||
//int vmDialog_InputOpenFile(struct string *pITString, struct string **pIPString, struct string **pIString, struct string *pIDString, struct string *pIFString);
|
||||
//int vmDialog_InputSaveFile(struct string *pITString, struct string **pIPString, struct string **pIString, struct string *pIDString, struct string *pIFString);
|
||||
|
||||
HLL_LIBRARY(vmDialog,
|
||||
HLL_EXPORT(Init, vmDialog_Init),
|
||||
HLL_EXPORT(MsgBox, vmDialog_MsgBox),
|
||||
HLL_TODO_EXPORT(InputNum, vmDialog_InputNum),
|
||||
HLL_TODO_EXPORT(InputString, vmDialog_InputString),
|
||||
HLL_TODO_EXPORT(SelectNum, vmDialog_SelectNum),
|
||||
HLL_TODO_EXPORT(SelectString, vmDialog_SelectString),
|
||||
HLL_TODO_EXPORT(InputOpenFile, vmDialog_InputOpenFile),
|
||||
HLL_TODO_EXPORT(InputSaveFile, vmDialog_InputSaveFile)
|
||||
);
|
||||
@@ -0,0 +1,119 @@
|
||||
/* Copyright (C) 2024 kichikuou <KichikuouChrome@gmail.com>
|
||||
*
|
||||
* 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 "system4/cg.h"
|
||||
|
||||
#include "asset_manager.h"
|
||||
#include "gfx/gfx.h"
|
||||
#include "hll.h"
|
||||
#include "id_pool.h"
|
||||
#include "vmSurface.h"
|
||||
|
||||
struct vm_drawgauge {
|
||||
struct texture tex;
|
||||
int surface;
|
||||
};
|
||||
|
||||
static struct id_pool pool;
|
||||
|
||||
static void vmDrawGauge_New(void)
|
||||
{
|
||||
if (pool.slots)
|
||||
return; // already initialized
|
||||
id_pool_init(&pool, ID_POOL_HANDLE_BASE);
|
||||
}
|
||||
|
||||
static int vmDrawGauge_EnumHandle(void)
|
||||
{
|
||||
return id_pool_count(&pool);
|
||||
}
|
||||
|
||||
static int vmDrawGauge_Open(int cg_no, int origin, int phase)
|
||||
{
|
||||
struct cg *cg = asset_cg_load(cg_no);
|
||||
if (!cg)
|
||||
return 0;
|
||||
|
||||
int w = cg->metrics.w;
|
||||
int h = cg->metrics.h;
|
||||
|
||||
int handle = id_pool_get_unused(&pool);
|
||||
struct vm_drawgauge *dg = xcalloc(1, sizeof(struct vm_drawgauge));
|
||||
id_pool_set(&pool, handle, dg);
|
||||
|
||||
gfx_init_texture_with_cg(&dg->tex, cg);
|
||||
cg_free(cg);
|
||||
|
||||
struct vm_surface *sf = vm_surface_create(w, h);
|
||||
gfx_init_texture_blank(&sf->texture, w, h);
|
||||
dg->surface = sf->no;
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
static void vmDrawGauge_Close(int handle)
|
||||
{
|
||||
struct vm_drawgauge *dg = id_pool_release(&pool, handle);
|
||||
if (!dg)
|
||||
return;
|
||||
gfx_delete_texture(&dg->tex);
|
||||
vm_surface_delete(dg->surface);
|
||||
free(dg);
|
||||
}
|
||||
|
||||
static int vmDrawGauge_Release(void)
|
||||
{
|
||||
for (int i = id_pool_get_first(&pool); i >= 0; i = id_pool_get_next(&pool, i))
|
||||
vmDrawGauge_Close(i);
|
||||
id_pool_delete(&pool);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void vmDrawGauge_ModuleFini(void)
|
||||
{
|
||||
vmDrawGauge_Release();
|
||||
}
|
||||
|
||||
static int vmDrawGauge_GetSurface(int handle)
|
||||
{
|
||||
struct vm_drawgauge *dg = id_pool_get(&pool, handle);
|
||||
return dg ? dg->surface : 0;
|
||||
}
|
||||
|
||||
static void vmDrawGauge_Draw(int handle, int now, int max)
|
||||
{
|
||||
struct vm_drawgauge *dg = id_pool_get(&pool, handle);
|
||||
if (!dg)
|
||||
return;
|
||||
struct vm_surface *sf = vm_surface_get(dg->surface);
|
||||
if (!sf)
|
||||
return;
|
||||
|
||||
gfx_fill_with_alpha(&sf->texture, 0, 0, sf->texture.w, sf->texture.h, 255, 0, 255, 0);
|
||||
int w = sf->texture.w * now / max;
|
||||
gfx_copy_with_alpha_map(&sf->texture, 0, 0, &dg->tex, 0, 0, w, sf->texture.h);
|
||||
}
|
||||
|
||||
HLL_LIBRARY(vmDrawGauge,
|
||||
HLL_EXPORT(_ModuleFini, vmDrawGauge_ModuleFini),
|
||||
HLL_EXPORT(New, vmDrawGauge_New),
|
||||
HLL_EXPORT(Release, vmDrawGauge_Release),
|
||||
HLL_EXPORT(EnumHandle, vmDrawGauge_EnumHandle),
|
||||
HLL_EXPORT(Open, vmDrawGauge_Open),
|
||||
HLL_EXPORT(Close, vmDrawGauge_Close),
|
||||
HLL_EXPORT(GetSurface, vmDrawGauge_GetSurface),
|
||||
HLL_EXPORT(Draw, vmDrawGauge_Draw)
|
||||
);
|
||||
@@ -0,0 +1,266 @@
|
||||
/* Copyright (C) 2024 kichikuou <KichikuouChrome@gmail.com>
|
||||
*
|
||||
* 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 "system4.h"
|
||||
#include "system4/string.h"
|
||||
|
||||
#include "gfx/font.h"
|
||||
#include "hll.h"
|
||||
#include "id_pool.h"
|
||||
#include "vmSurface.h"
|
||||
#include "xsystem4.h"
|
||||
|
||||
enum {
|
||||
SURFACE_DROP_SHADOW,
|
||||
SURFACE_BOLD,
|
||||
SURFACE_TEXT,
|
||||
NR_SURFACES
|
||||
};
|
||||
|
||||
struct style {
|
||||
struct text_style ts;
|
||||
int drop_shadow;
|
||||
SDL_Color drop_shadow_color;
|
||||
int bold;
|
||||
SDL_Color bold_color;
|
||||
};
|
||||
|
||||
struct vm_drawmsg {
|
||||
int w;
|
||||
int h;
|
||||
int surfaces[NR_SURFACES];
|
||||
struct string *text;
|
||||
Point pos;
|
||||
Point initial_pos;
|
||||
struct style style;
|
||||
struct style initial_style;
|
||||
};
|
||||
|
||||
static struct id_pool pool;
|
||||
|
||||
static void vmDrawMsg_New(possibly_unused void *imainsystem)
|
||||
{
|
||||
if (pool.slots)
|
||||
return; // already initialized
|
||||
gfx_font_init();
|
||||
id_pool_init(&pool, ID_POOL_HANDLE_BASE);
|
||||
}
|
||||
|
||||
static int vmDrawMsg_EnumHandle(void)
|
||||
{
|
||||
return id_pool_count(&pool);
|
||||
}
|
||||
|
||||
static int vmDrawMsg_Open(int width, int height)
|
||||
{
|
||||
int no = id_pool_get_unused(&pool);
|
||||
struct vm_drawmsg *dm = xcalloc(1, sizeof(struct vm_drawmsg));
|
||||
id_pool_set(&pool, no, dm);
|
||||
dm->w = width;
|
||||
dm->h = height;
|
||||
for (int i = 0; i < NR_SURFACES; i++) {
|
||||
struct vm_surface *sf = vm_surface_create(width, height);
|
||||
dm->surfaces[i] = sf->no;
|
||||
gfx_init_texture_rgba(&sf->texture, sf->w, sf->h, COLOR(0, 0, 0, 0));
|
||||
}
|
||||
dm->text = string_dup(&EMPTY_STRING);
|
||||
|
||||
dm->initial_style.ts.face = FONT_GOTHIC;
|
||||
dm->initial_style.ts.size = 24.0f;
|
||||
dm->initial_style.ts.weight = FW_BOLD;
|
||||
dm->initial_style.ts.color = COLOR(255, 255, 255, 255);
|
||||
dm->initial_style.ts.scale_x = 1.0;
|
||||
dm->initial_style.ts.space_scale_x = 1.0f;
|
||||
dm->style = dm->initial_style;
|
||||
|
||||
return no;
|
||||
}
|
||||
|
||||
static void vmDrawMsg_Close(int handle)
|
||||
{
|
||||
struct vm_drawmsg *dm = id_pool_release(&pool, handle);
|
||||
if (!dm)
|
||||
return;
|
||||
free_string(dm->text);
|
||||
for (int i = 0; i < NR_SURFACES; i++) {
|
||||
vm_surface_delete(dm->surfaces[i]);
|
||||
}
|
||||
free(dm);
|
||||
}
|
||||
|
||||
static int vmDrawMsg_Release(void)
|
||||
{
|
||||
for (int i = id_pool_get_first(&pool); i >= 0; i = id_pool_get_next(&pool, i))
|
||||
vmDrawMsg_Close(i);
|
||||
id_pool_delete(&pool);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void vmDrawMsg_ModuleFini(void)
|
||||
{
|
||||
vmDrawMsg_Release();
|
||||
}
|
||||
|
||||
static int vmDrawMsg_GetNumofSurface(int handle)
|
||||
{
|
||||
struct vm_drawmsg *dm = id_pool_get(&pool, handle);
|
||||
return dm ? NR_SURFACES : 0;
|
||||
}
|
||||
|
||||
static int vmDrawMsg_GetSurface(int handle, int index)
|
||||
{
|
||||
struct vm_drawmsg *dm = id_pool_get(&pool, handle);
|
||||
if (!dm || index < 0 || index >= NR_SURFACES)
|
||||
return 0;
|
||||
return dm->surfaces[index];
|
||||
}
|
||||
|
||||
static int vmDrawMsg_AddMsg(int handle, struct string *s)
|
||||
{
|
||||
struct vm_drawmsg *dm = id_pool_get(&pool, handle);
|
||||
if (!dm)
|
||||
return 0;
|
||||
string_append(&dm->text, s);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int vmDrawMsg_Draw(int handle)
|
||||
{
|
||||
struct vm_drawmsg *dm = id_pool_get(&pool, handle);
|
||||
if (!dm)
|
||||
return 0;
|
||||
|
||||
char *s = dm->text->text;
|
||||
const int line_space = 2;
|
||||
while (*s) {
|
||||
int skiplen = 0, a1, a2, a3;
|
||||
if (*s != '<') {
|
||||
char *lb = strchr(s, '<');
|
||||
if (lb) {
|
||||
skiplen = lb - s;
|
||||
*lb = '\0';
|
||||
} else {
|
||||
skiplen = strlen(s);
|
||||
}
|
||||
if (dm->style.drop_shadow) {
|
||||
struct text_style ts = dm->style.ts;
|
||||
ts.color = dm->style.drop_shadow_color;
|
||||
struct vm_surface *sf = vm_surface_get(dm->surfaces[SURFACE_DROP_SHADOW]);
|
||||
int x = dm->pos.x + dm->style.drop_shadow;
|
||||
int y = dm->pos.y + dm->style.drop_shadow;
|
||||
gfx_render_text(&sf->texture, x, y, s, &ts);
|
||||
}
|
||||
if (dm->style.bold) {
|
||||
struct text_style ts = dm->style.ts;
|
||||
ts.bold_width = dm->style.bold;
|
||||
ts.color = dm->style.bold_color;
|
||||
struct vm_surface *sf = vm_surface_get(dm->surfaces[SURFACE_BOLD]);
|
||||
gfx_render_text(&sf->texture, dm->pos.x, dm->pos.y, s, &ts);
|
||||
}
|
||||
struct vm_surface *sf = vm_surface_get(dm->surfaces[SURFACE_TEXT]);
|
||||
dm->pos.x += gfx_render_text(&sf->texture, dm->pos.x, dm->pos.y, s, &dm->style.ts);
|
||||
if (lb)
|
||||
*lb = '<';
|
||||
} else if (sscanf(s, "<C%d,%d,%d>%n", &a1, &a2, &a3, &skiplen) == 3) {
|
||||
dm->style.ts.color = COLOR(a1, a2, a3, 255);
|
||||
} else if (sscanf(s, "<@C%d,%d,%d>%n", &a1, &a2, &a3, &skiplen) == 3) {
|
||||
dm->initial_style.ts.color = dm->style.ts.color = COLOR(a1, a2, a3, 255);
|
||||
} else if (!strncmp(s, "</C>", 4)) {
|
||||
skiplen = 4;
|
||||
dm->style.ts.color = dm->initial_style.ts.color;
|
||||
} else if (sscanf(s, "<E%d>%n", &a1, &skiplen) == 1) {
|
||||
dm->style.bold = a1;
|
||||
} else if (sscanf(s, "<@E%d>%n", &a1, &skiplen) == 1) {
|
||||
dm->initial_style.bold = dm->style.bold = a1;
|
||||
} else if (sscanf(s, "<EC%d,%d,%d>%n", &a1, &a2, &a3, &skiplen) == 3) {
|
||||
dm->style.bold_color = COLOR(a1, a2, a3, 255);
|
||||
} else if (sscanf(s, "<@EC%d,%d,%d>%n", &a1, &a2, &a3, &skiplen) == 3) {
|
||||
dm->initial_style.bold_color = dm->style.bold_color = COLOR(a1, a2, a3, 255);
|
||||
} else if (sscanf(s, "<K%d>%n", &a1, &skiplen) == 1) {
|
||||
dm->style.drop_shadow = a1;
|
||||
} else if (sscanf(s, "<@K%d>%n", &a1, &skiplen) == 1) {
|
||||
dm->initial_style.drop_shadow = dm->style.drop_shadow = a1;
|
||||
} else if (sscanf(s, "<KC%d,%d,%d>%n", &a1, &a2, &a3, &skiplen) == 3) {
|
||||
dm->style.drop_shadow_color = COLOR(a1, a2, a3, 255);
|
||||
} else if (sscanf(s, "<@KC%d,%d,%d>%n", &a1, &a2, &a3, &skiplen) == 3) {
|
||||
dm->initial_style.drop_shadow_color = dm->style.drop_shadow_color = COLOR(a1, a2, a3, 255);
|
||||
} else if (sscanf(s, "<S%d>%n", &a1, &skiplen) == 1) {
|
||||
dm->style.ts.size = a1;
|
||||
} else if (sscanf(s, "<@S%d>%n", &a1, &skiplen) == 1) {
|
||||
dm->initial_style.ts.size = dm->style.ts.size = a1;
|
||||
} else if (sscanf(s, "<P%d,%d>%n", &a1, &a2, &skiplen) == 2) {
|
||||
dm->pos = POINT(a1, a2);
|
||||
} else if (sscanf(s, "<@P%d,%d>%n", &a1, &a2, &skiplen) == 2) {
|
||||
dm->initial_pos = dm->pos = POINT(a1, a2);
|
||||
} else if (!strncmp(s, "<WCR>", 5)) {
|
||||
skiplen = 5;
|
||||
dm->pos = dm->initial_pos;
|
||||
for (int i = 0; i < NR_SURFACES; i++) {
|
||||
struct vm_surface *dst = vm_surface_get(dm->surfaces[i]);
|
||||
gfx_fill_amap(&dst->texture, 0, 0, dm->w, dm->h, 0);
|
||||
}
|
||||
} else if (!strncmp(s, "<CR>", 4)) {
|
||||
skiplen = 4;
|
||||
dm->pos = dm->initial_pos;
|
||||
dm->style = dm->initial_style;
|
||||
} else if (!strncmp(s, "<WA1>", 5)) {
|
||||
// no-op?
|
||||
skiplen = 5;
|
||||
} else if (!strncmp(s, "<R>", 3)) {
|
||||
skiplen = 3;
|
||||
dm->pos.x = dm->initial_pos.x;
|
||||
dm->pos.y += dm->style.ts.size + line_space;
|
||||
} else {
|
||||
char *rb = strchr(s, '>');
|
||||
if (rb) {
|
||||
WARNING("Unknown command %.*s", ++rb - s, s);
|
||||
skiplen = rb - s;
|
||||
} else {
|
||||
WARNING("Unfinished command in message '%s'", dm->text->text);
|
||||
break;
|
||||
}
|
||||
}
|
||||
s += skiplen;
|
||||
}
|
||||
string_clear(dm->text);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vmDrawMsg_RenewalRect(int handle, int *x, int *y, int *width, int *height)
|
||||
{
|
||||
struct vm_drawmsg *dm = id_pool_get(&pool, handle);
|
||||
if (!dm)
|
||||
return 0;
|
||||
*x = 0;
|
||||
*y = 0;
|
||||
*width = dm->w;
|
||||
*height = dm->h;
|
||||
return 1;
|
||||
}
|
||||
|
||||
HLL_LIBRARY(vmDrawMsg,
|
||||
HLL_EXPORT(_ModuleFini, vmDrawMsg_ModuleFini),
|
||||
HLL_EXPORT(New, vmDrawMsg_New),
|
||||
HLL_EXPORT(Release, vmDrawMsg_Release),
|
||||
HLL_EXPORT(EnumHandle, vmDrawMsg_EnumHandle),
|
||||
HLL_EXPORT(Open, vmDrawMsg_Open),
|
||||
HLL_EXPORT(Close, vmDrawMsg_Close),
|
||||
HLL_EXPORT(GetNumofSurface, vmDrawMsg_GetNumofSurface),
|
||||
HLL_EXPORT(GetSurface, vmDrawMsg_GetSurface),
|
||||
HLL_EXPORT(AddMsg, vmDrawMsg_AddMsg),
|
||||
HLL_EXPORT(Draw, vmDrawMsg_Draw),
|
||||
HLL_EXPORT(RenewalRect, vmDrawMsg_RenewalRect)
|
||||
);
|
||||
@@ -0,0 +1,188 @@
|
||||
/* Copyright (C) 2024 kichikuou <KichikuouChrome@gmail.com>
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
|
||||
#include "system4.h"
|
||||
#include "system4/cg.h"
|
||||
|
||||
#include "asset_manager.h"
|
||||
#include "gfx/gfx.h"
|
||||
#include "hll.h"
|
||||
#include "id_pool.h"
|
||||
#include "vmSurface.h"
|
||||
|
||||
enum {
|
||||
ALIGN_LEFT = 0,
|
||||
ZERO_PAD = 1,
|
||||
ALIGN_RIGHT = 2,
|
||||
ALIGN_CENTER = 4,
|
||||
};
|
||||
|
||||
struct vm_drawnumber {
|
||||
struct texture digits;
|
||||
struct texture sign;
|
||||
int surface;
|
||||
int kind;
|
||||
int figures;
|
||||
int space;
|
||||
};
|
||||
|
||||
static struct id_pool pool;
|
||||
|
||||
static void vmDrawNumber_New(void)
|
||||
{
|
||||
if (pool.slots)
|
||||
return; // already initialized
|
||||
id_pool_init(&pool, ID_POOL_HANDLE_BASE);
|
||||
}
|
||||
|
||||
static int vmDrawNumber_EnumHandle(void)
|
||||
{
|
||||
return id_pool_count(&pool);
|
||||
}
|
||||
|
||||
static int vmDrawNumber_Open(int cg_no, int kind, int figure, int space)
|
||||
{
|
||||
struct cg *cg = asset_cg_load(cg_no);
|
||||
if (!cg)
|
||||
return 0;
|
||||
|
||||
int width = cg->metrics.w / 10 * figure;
|
||||
int height = cg->metrics.h;
|
||||
|
||||
int handle = id_pool_get_unused(&pool);
|
||||
struct vm_drawnumber *dn = xcalloc(1, sizeof(struct vm_drawnumber));
|
||||
id_pool_set(&pool, handle, dn);
|
||||
|
||||
gfx_init_texture_with_cg(&dn->digits, cg);
|
||||
cg_free(cg);
|
||||
struct vm_surface *sf = vm_surface_create(width, height);
|
||||
gfx_init_texture_blank(&sf->texture, width, height);
|
||||
dn->surface = sf->no;
|
||||
dn->kind = kind;
|
||||
dn->figures = figure;
|
||||
dn->space = space;
|
||||
return handle;
|
||||
}
|
||||
|
||||
static void vmDrawNumber_Close(int handle)
|
||||
{
|
||||
struct vm_drawnumber *dn = id_pool_release(&pool, handle);
|
||||
if (!dn)
|
||||
return;
|
||||
gfx_delete_texture(&dn->digits);
|
||||
gfx_delete_texture(&dn->sign);
|
||||
vm_surface_delete(dn->surface);
|
||||
free(dn);
|
||||
}
|
||||
|
||||
static int vmDrawNumber_Release(void)
|
||||
{
|
||||
for (int i = id_pool_get_first(&pool); i >= 0; i = id_pool_get_next(&pool, i))
|
||||
vmDrawNumber_Close(i);
|
||||
id_pool_delete(&pool);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void vmDrawNumber_ModuleFini(void)
|
||||
{
|
||||
vmDrawNumber_Release();
|
||||
}
|
||||
|
||||
static int vmDrawNumber_GetSurface(int handle)
|
||||
{
|
||||
struct vm_drawnumber *dn = id_pool_get(&pool, handle);
|
||||
return dn ? dn->surface : 0;
|
||||
}
|
||||
|
||||
static void vmDrawNumber_Draw(int handle, int num)
|
||||
{
|
||||
struct vm_drawnumber *dn = id_pool_get(&pool, handle);
|
||||
if (!dn)
|
||||
return;
|
||||
struct vm_surface *sf = vm_surface_get(dn->surface);
|
||||
if (!sf)
|
||||
return;
|
||||
|
||||
char buf[16];
|
||||
if (dn->kind == ZERO_PAD) {
|
||||
snprintf(buf, min(sizeof(buf), dn->figures + 1), "%0*d", dn->figures, num);
|
||||
} else {
|
||||
snprintf(buf, min(sizeof(buf), dn->figures + 1), "%d", num);
|
||||
}
|
||||
|
||||
int dw = dn->digits.w / 10;
|
||||
int w = dw * strlen(buf);
|
||||
int h = dn->digits.h;
|
||||
int left;
|
||||
|
||||
switch (dn->kind) {
|
||||
case ALIGN_LEFT:
|
||||
case ZERO_PAD:
|
||||
left = 0;
|
||||
break;
|
||||
case ALIGN_RIGHT:
|
||||
left = sf->texture.w - w;
|
||||
break;
|
||||
case ALIGN_CENTER:
|
||||
left = (sf->texture.w - w) / 2;
|
||||
break;
|
||||
default:
|
||||
WARNING("vmDrawNumber.Draw: unknown kind %d", dn->kind);
|
||||
left = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
gfx_fill_amap(&sf->texture, 0, 0, sf->texture.w, sf->texture.h, 0);
|
||||
for (int i = 0; buf[i]; i++) {
|
||||
switch (buf[i]) {
|
||||
case '-':
|
||||
gfx_copy_with_alpha_map(&sf->texture, left + i * dw, 0, &dn->sign, 0, 0, dw, h);
|
||||
break;
|
||||
default:
|
||||
gfx_copy_with_alpha_map(&sf->texture, left + i * dw, 0, &dn->digits, (buf[i] - '0') * dw, 0, dw, h);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int vmDrawNumber_SetSign(int handle, int cg_no)
|
||||
{
|
||||
struct vm_drawnumber *dn = id_pool_get(&pool, handle);
|
||||
if (!dn)
|
||||
return 0;
|
||||
|
||||
struct cg *cg = asset_cg_load(cg_no);
|
||||
if (!cg)
|
||||
return 0;
|
||||
|
||||
gfx_init_texture_with_cg(&dn->sign, cg);
|
||||
cg_free(cg);
|
||||
return 1;
|
||||
}
|
||||
|
||||
HLL_LIBRARY(vmDrawNumber,
|
||||
HLL_EXPORT(_ModuleFini, vmDrawNumber_ModuleFini),
|
||||
HLL_EXPORT(New, vmDrawNumber_New),
|
||||
HLL_EXPORT(Release, vmDrawNumber_Release),
|
||||
HLL_EXPORT(EnumHandle, vmDrawNumber_EnumHandle),
|
||||
HLL_EXPORT(Open, vmDrawNumber_Open),
|
||||
HLL_EXPORT(Close, vmDrawNumber_Close),
|
||||
HLL_EXPORT(GetSurface, vmDrawNumber_GetSurface),
|
||||
HLL_EXPORT(Draw, vmDrawNumber_Draw),
|
||||
HLL_EXPORT(SetSign, vmDrawNumber_SetSign)
|
||||
);
|
||||
@@ -0,0 +1,372 @@
|
||||
/* Copyright (C) 2024 kichikuou <KichikuouChrome@gmail.com>
|
||||
*
|
||||
* 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 <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "system4.h"
|
||||
#include "system4/buffer.h"
|
||||
#include "system4/file.h"
|
||||
#include "system4/string.h"
|
||||
|
||||
#include "hll.h"
|
||||
#include "id_pool.h"
|
||||
#include "vm/heap.h"
|
||||
#include "vm/page.h"
|
||||
#include "xsystem4.h"
|
||||
|
||||
enum vm_file_mode {
|
||||
VM_FILE_READ = 1,
|
||||
VM_FILE_WRITE = 2
|
||||
};
|
||||
|
||||
struct vm_file {
|
||||
char *path;
|
||||
FILE *fp;
|
||||
struct buffer buf;
|
||||
};
|
||||
|
||||
static struct id_pool pool;
|
||||
|
||||
static void read_page(struct vm_file *vf, struct page *page);
|
||||
static void write_page(struct vm_file *vf, struct page *page);
|
||||
|
||||
static void read_value(struct vm_file *vf, union vm_value *v, enum ain_data_type type)
|
||||
{
|
||||
switch (type) {
|
||||
case AIN_INT:
|
||||
case AIN_BOOL:
|
||||
case AIN_LONG_INT:
|
||||
v->i = buffer_read_int32(&vf->buf);
|
||||
break;
|
||||
case AIN_FLOAT:
|
||||
v->f = buffer_read_float(&vf->buf);
|
||||
break;
|
||||
case AIN_STRING:
|
||||
variable_fini(*v, type);
|
||||
v->i = heap_alloc_string(buffer_read_string(&vf->buf));
|
||||
break;
|
||||
case AIN_STRUCT:
|
||||
case AIN_ARRAY_TYPE:
|
||||
read_page(vf, heap_get_page(v->i));
|
||||
break;
|
||||
default:
|
||||
VM_ERROR("Unsupported value type %d", type);
|
||||
}
|
||||
}
|
||||
|
||||
static void read_page(struct vm_file *vf, struct page *page)
|
||||
{
|
||||
switch (page->type) {
|
||||
case STRUCT_PAGE:
|
||||
{
|
||||
struct ain_struct *s = &ain->structures[page->index];
|
||||
for (int i = 0; i < s->nr_members; i++) {
|
||||
read_value(vf, &page->values[i], s->members[i].type.data);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ARRAY_PAGE:
|
||||
{
|
||||
enum ain_data_type type = page->array.rank > 1 ? page->a_type : array_type(page->a_type);
|
||||
for (int i = 0; i < page->nr_vars; i++) {
|
||||
read_value(vf, &page->values[i], type);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
VM_ERROR("Unsupported page type %d", page->type);
|
||||
}
|
||||
}
|
||||
|
||||
static void write_value(struct vm_file *vf, union vm_value v, enum ain_data_type type)
|
||||
{
|
||||
switch (type) {
|
||||
case AIN_INT:
|
||||
case AIN_BOOL:
|
||||
buffer_write_int32(&vf->buf, v.i);
|
||||
break;
|
||||
case AIN_FLOAT:
|
||||
buffer_write_float(&vf->buf, v.f);
|
||||
break;
|
||||
case AIN_STRING:
|
||||
buffer_write_cstringz(&vf->buf, heap_get_string(v.i)->text);
|
||||
break;
|
||||
case AIN_STRUCT:
|
||||
case AIN_ARRAY_TYPE:
|
||||
write_page(vf, heap_get_page(v.i));
|
||||
break;
|
||||
default:
|
||||
VM_ERROR("Unsupported value type %d", type);
|
||||
}
|
||||
}
|
||||
|
||||
static void write_page(struct vm_file *vf, struct page *page)
|
||||
{
|
||||
switch (page->type) {
|
||||
case STRUCT_PAGE:
|
||||
{
|
||||
struct ain_struct *s = &ain->structures[page->index];
|
||||
for (int i = 0; i < s->nr_members; i++) {
|
||||
write_value(vf, page->values[i], s->members[i].type.data);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ARRAY_PAGE:
|
||||
{
|
||||
enum ain_data_type type = page->array.rank > 1 ? page->a_type : array_type(page->a_type);
|
||||
for (int i = 0; i < page->nr_vars; i++) {
|
||||
write_value(vf, page->values[i], type);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
VM_ERROR("Unsupported page type %d", page->type);
|
||||
}
|
||||
}
|
||||
|
||||
static void vmFile_ModuleInit(void)
|
||||
{
|
||||
id_pool_init(&pool, ID_POOL_HANDLE_BASE);
|
||||
}
|
||||
|
||||
static int vmFile_EnumHandle(void)
|
||||
{
|
||||
return id_pool_count(&pool);
|
||||
}
|
||||
|
||||
static int vmFile_Open(struct string *string, int type)
|
||||
{
|
||||
struct vm_file *vf = xcalloc(1, sizeof(struct vm_file));
|
||||
char *path = savedir_path(string->text);
|
||||
vf->path = path;
|
||||
|
||||
if (type == VM_FILE_READ) {
|
||||
size_t len;
|
||||
uint8_t *data = file_read(path, &len);
|
||||
if (!data) {
|
||||
free(path);
|
||||
free(vf);
|
||||
return 0;
|
||||
}
|
||||
buffer_init(&vf->buf, data, len);
|
||||
} else if (type == VM_FILE_WRITE) {
|
||||
vf->fp = file_open_utf8(path, "wb");
|
||||
if (!vf->fp) {
|
||||
WARNING("Failed to open file '%s': %s", display_utf0(path), strerror(errno));
|
||||
free(path);
|
||||
free(vf);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
WARNING("Unknown mode in vmFile.Open: %d", type);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int handle = id_pool_get_unused(&pool);
|
||||
id_pool_set(&pool, handle, vf);
|
||||
return handle;
|
||||
}
|
||||
|
||||
static void vmFile_Close(int handle)
|
||||
{
|
||||
struct vm_file *vf = id_pool_release(&pool, handle);
|
||||
if (!vf)
|
||||
return;
|
||||
|
||||
if (vf->fp) { // write mode
|
||||
if (fwrite(vf->buf.buf, vf->buf.index, 1, vf->fp) != 1) {
|
||||
WARNING("%s: fwrite failed: %s", display_utf0(vf->path), strerror(errno));
|
||||
}
|
||||
fclose(vf->fp);
|
||||
}
|
||||
free(vf->buf.buf);
|
||||
free(vf->path);
|
||||
free(vf);
|
||||
}
|
||||
|
||||
static void vmFile_ModuleFini(void)
|
||||
{
|
||||
for (int i = id_pool_get_first(&pool); i >= 0; i = id_pool_get_next(&pool, i))
|
||||
vmFile_Close(i);
|
||||
id_pool_delete(&pool);
|
||||
}
|
||||
|
||||
static int vmFile_Encode(int handle, int seed, int rand)
|
||||
{
|
||||
struct vm_file *vf = id_pool_get(&pool, handle);
|
||||
if (!vf)
|
||||
return 0;
|
||||
|
||||
size_t len = vf->buf.index;
|
||||
int32_t *buf = xmalloc(len + 8);
|
||||
memcpy(buf + 2, vf->buf.buf, len);
|
||||
free(vf->buf.buf);
|
||||
vf->buf.buf = (uint8_t*)buf;
|
||||
vf->buf.index += 8;
|
||||
|
||||
int32_t mask = rand ^ ((rand & 1) ? 0xdf3d1b79 : 0x3ddf791b);
|
||||
int32_t checksum = 0;
|
||||
buf[0] = mask;
|
||||
|
||||
len >>= 2;
|
||||
for (int i = 0; i < len; i++) {
|
||||
buf[i + 2] ^= mask;
|
||||
mask = buf[i + 2] ^ seed;
|
||||
checksum ^= mask;
|
||||
if (i & 2)
|
||||
mask ^= i * -3 ^ 0xf7fef7fe;
|
||||
if (i & 4)
|
||||
mask = mask << ((3 - i) & 0xf) | mask >> ((i - 3) & 0xf);
|
||||
}
|
||||
buf[1] = checksum;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int vmFile_Decode(int handle, int seed)
|
||||
{
|
||||
struct vm_file *vf = id_pool_get(&pool, handle);
|
||||
if (!vf)
|
||||
return 0;
|
||||
|
||||
int32_t mask = buffer_read_int32(&vf->buf);
|
||||
int32_t checksum = buffer_read_int32(&vf->buf);
|
||||
|
||||
int32_t *buf = (int32_t*)buffer_strdata(&vf->buf);
|
||||
int len = buffer_remaining(&vf->buf) >> 2;
|
||||
|
||||
int32_t sum = 0;
|
||||
for (int i = 0; i < len; i++) {
|
||||
buf[i] ^= mask;
|
||||
mask ^= buf[i] ^ seed;
|
||||
sum ^= mask;
|
||||
if (i & 2)
|
||||
mask ^= i * -3 ^ 0xf7fef7fe;
|
||||
if (i & 4)
|
||||
mask = mask << ((3 - i) & 0xf) | mask >> ((i - 3) & 0xf);
|
||||
}
|
||||
if (sum != checksum) {
|
||||
WARNING("%s: checksum error", display_utf0(vf->path));
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
//int vmFile_ReadArrayChar(int handle, struct page **pIVMArray);
|
||||
//int vmFile_ReadArrayShort(int handle, struct page **pIVMArray);
|
||||
//int vmFile_ReadArrayInt(int handle, struct page **pIVMArray);
|
||||
//int vmFile_ReadArrayFloat(int handle, struct page **pIVMArray);
|
||||
//int vmFile_ReadArrayString(int handle, struct page **pIVMArray);
|
||||
//int vmFile_ReadArrayStruct(int handle, struct page **pIVMArray);
|
||||
|
||||
static int vmFile_ReadStruct(int handle, struct page **_page)
|
||||
{
|
||||
struct vm_file *vf = id_pool_get(&pool, handle);
|
||||
if (!vf)
|
||||
return 0;
|
||||
|
||||
struct page *page = *_page;
|
||||
if (page->type != STRUCT_PAGE) {
|
||||
VM_ERROR("vmFile.ReadStruct of non-struct");
|
||||
}
|
||||
|
||||
read_page(vf, page);
|
||||
return 1;
|
||||
}
|
||||
|
||||
//int vmFile_ReadGlobal(int handle, IMainSystem pIMainSystem);
|
||||
//int vmFile_WriteArrayChar(int handle, struct page *pIVMArray);
|
||||
//int vmFile_WriteArrayShort(int handle, struct page *pIVMArray);
|
||||
//int vmFile_WriteArrayInt(int handle, struct page *pIVMArray);
|
||||
//int vmFile_WriteArrayFloat(int handle, struct page *pIVMArray);
|
||||
//int vmFile_WriteArrayString(int handle, struct page *pIVMArray);
|
||||
//int vmFile_WriteArrayStruct(int handle, struct page *pIVMArray);
|
||||
|
||||
static int vmFile_WriteStruct(int handle, struct page *page)
|
||||
{
|
||||
struct vm_file *vf = id_pool_get(&pool, handle);
|
||||
if (!vf)
|
||||
return 0;
|
||||
write_page(vf, page);
|
||||
return 1;
|
||||
}
|
||||
|
||||
//int vmFile_WriteGlobal(int handle, IMainSystem pIMainSystem);
|
||||
//int vmFile_SeekChar(int handle, int nPos, int nAbsolute);
|
||||
//int vmFile_SeekShort(int handle, int nPos, int nAbsolute);
|
||||
//int vmFile_SeekInt(int handle, int nPos, int nAbsolute);
|
||||
//int vmFile_SeekFloat(int handle, int nPos, int nAbsolute);
|
||||
//int vmFile_SeekString(int handle, int nPos, int nAbsolute);
|
||||
//int vmFile_SizeChar(int handle);
|
||||
//int vmFile_SizeShort(int handle);
|
||||
//int vmFile_SizeInt(int handle);
|
||||
//int vmFile_SizeFloat(int handle);
|
||||
//int vmFile_SizeString(int handle);
|
||||
//int vmFile_Copy(struct string *pISString, struct string *pIDString);
|
||||
|
||||
static int vmFile_Delete(struct string *string)
|
||||
{
|
||||
char *path = savedir_path(string->text);
|
||||
int r = !remove_utf8(path);
|
||||
free(path);
|
||||
return r;
|
||||
}
|
||||
|
||||
//int vmFile_GetTime(struct string *pIString, struct page **pIVMStruct);
|
||||
//int vmFile_Find(struct string *pIWildString, struct string **pIString, int *pnCount);
|
||||
//int vmFile_MakeDirectory(struct string *pIString);
|
||||
|
||||
HLL_LIBRARY(vmFile,
|
||||
HLL_EXPORT(_ModuleInit, vmFile_ModuleInit),
|
||||
HLL_EXPORT(_ModuleFini, vmFile_ModuleFini),
|
||||
HLL_EXPORT(EnumHandle, vmFile_EnumHandle),
|
||||
HLL_EXPORT(Open, vmFile_Open),
|
||||
HLL_EXPORT(Close, vmFile_Close),
|
||||
HLL_EXPORT(Encode, vmFile_Encode),
|
||||
HLL_EXPORT(Decode, vmFile_Decode),
|
||||
HLL_TODO_EXPORT(ReadArrayChar, vmFile_ReadArrayChar),
|
||||
HLL_TODO_EXPORT(ReadArrayShort, vmFile_ReadArrayShort),
|
||||
HLL_TODO_EXPORT(ReadArrayInt, vmFile_ReadArrayInt),
|
||||
HLL_TODO_EXPORT(ReadArrayFloat, vmFile_ReadArrayFloat),
|
||||
HLL_TODO_EXPORT(ReadArrayString, vmFile_ReadArrayString),
|
||||
HLL_TODO_EXPORT(ReadArrayStruct, vmFile_ReadArrayStruct),
|
||||
HLL_EXPORT(ReadStruct, vmFile_ReadStruct),
|
||||
HLL_TODO_EXPORT(ReadGlobal, vmFile_ReadGlobal),
|
||||
HLL_TODO_EXPORT(WriteArrayChar, vmFile_WriteArrayChar),
|
||||
HLL_TODO_EXPORT(WriteArrayShort, vmFile_WriteArrayShort),
|
||||
HLL_TODO_EXPORT(WriteArrayInt, vmFile_WriteArrayInt),
|
||||
HLL_TODO_EXPORT(WriteArrayFloat, vmFile_WriteArrayFloat),
|
||||
HLL_TODO_EXPORT(WriteArrayString, vmFile_WriteArrayString),
|
||||
HLL_TODO_EXPORT(WriteArrayStruct, vmFile_WriteArrayStruct),
|
||||
HLL_EXPORT(WriteStruct, vmFile_WriteStruct),
|
||||
HLL_TODO_EXPORT(WriteGlobal, vmFile_WriteGlobal),
|
||||
HLL_TODO_EXPORT(SeekChar, vmFile_SeekChar),
|
||||
HLL_TODO_EXPORT(SeekShort, vmFile_SeekShort),
|
||||
HLL_TODO_EXPORT(SeekInt, vmFile_SeekInt),
|
||||
HLL_TODO_EXPORT(SeekFloat, vmFile_SeekFloat),
|
||||
HLL_TODO_EXPORT(SeekString, vmFile_SeekString),
|
||||
HLL_TODO_EXPORT(SizeChar, vmFile_SizeChar),
|
||||
HLL_TODO_EXPORT(SizeShort, vmFile_SizeShort),
|
||||
HLL_TODO_EXPORT(SizeInt, vmFile_SizeInt),
|
||||
HLL_TODO_EXPORT(SizeFloat, vmFile_SizeFloat),
|
||||
HLL_TODO_EXPORT(SizeString, vmFile_SizeString),
|
||||
HLL_TODO_EXPORT(Copy, vmFile_Copy),
|
||||
HLL_EXPORT(Delete, vmFile_Delete),
|
||||
HLL_TODO_EXPORT(GetTime, vmFile_GetTime),
|
||||
HLL_TODO_EXPORT(Find, vmFile_Find),
|
||||
HLL_TODO_EXPORT(MakeDirectory, vmFile_MakeDirectory)
|
||||
);
|
||||
@@ -0,0 +1,214 @@
|
||||
/* Copyright (C) 2024 kichikuou <KichikuouChrome@gmail.com>
|
||||
*
|
||||
* 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 "gfx/gfx.h"
|
||||
#include "vmSurface.h"
|
||||
#include "hll.h"
|
||||
|
||||
HLL_QUIET_UNIMPLEMENTED( , void, vmGraph, Init, void *imainsystem);
|
||||
//void vmGraph_SetUseCPUEx(int nUse);
|
||||
|
||||
static void vmGraph_Copy(int dst_surface, int dx, int dy, int src_surface, int sx, int sy, int width, int height)
|
||||
{
|
||||
struct vm_surface *dst = vm_surface_get(dst_surface);
|
||||
struct vm_surface *src = vm_surface_get(src_surface);
|
||||
if (!dst || !src)
|
||||
return;
|
||||
gfx_copy_with_alpha_map(&dst->texture, dx, dy, &src->texture, sx, sy, width, height);
|
||||
}
|
||||
|
||||
static void vmGraph_CopyPixelMap(int dst_surface, int dx, int dy, int src_surface, int sx, int sy, int width, int height)
|
||||
{
|
||||
struct vm_surface *dst = vm_surface_get(dst_surface);
|
||||
struct vm_surface *src = vm_surface_get(src_surface);
|
||||
if (!dst || !src)
|
||||
return;
|
||||
gfx_copy(&dst->texture, dx, dy, &src->texture, sx, sy, width, height);
|
||||
}
|
||||
|
||||
static void vmGraph_CopyAlphaMap(int dst_surface, int dx, int dy, int src_surface, int sx, int sy, int width, int height)
|
||||
{
|
||||
struct vm_surface *dst = vm_surface_get(dst_surface);
|
||||
struct vm_surface *src = vm_surface_get(src_surface);
|
||||
if (!dst || !src)
|
||||
return;
|
||||
gfx_copy_amap(&dst->texture, dx, dy, &src->texture, sx, sy, width, height);
|
||||
}
|
||||
|
||||
//void vmGraph_CopyBright(int dst_surface, int dx, int dy, int src_surface, int sx, int sy, int width, int height, int nRate);
|
||||
|
||||
static void vmGraph_CopySprite(int dst_surface, int dx, int dy, int src_surface, int sx, int sy, int width, int height, int r, int g, int b)
|
||||
{
|
||||
struct vm_surface *dst = vm_surface_get(dst_surface);
|
||||
struct vm_surface *src = vm_surface_get(src_surface);
|
||||
if (!dst || !src)
|
||||
return;
|
||||
gfx_copy_sprite(&dst->texture, dx, dy, &src->texture, sx, sy, width, height, COLOR(r, g, b, 0));
|
||||
}
|
||||
|
||||
//void vmGraph_Blend(int dst_surface, int dx, int dy, int src_surface, int sx, int sy, int width, int height, int alpha);
|
||||
//void vmGraph_BlendSrcBright(int dst_surface, int dx, int dy, int src_surface, int sx, int sy, int width, int height, int alpha, int nRate);
|
||||
//void vmGraph_BlendAddSatur(int dst_surface, int dx, int dy, int src_surface, int sx, int sy, int width, int height);
|
||||
|
||||
static void vmGraph_BlendAlphaMap(int dst_surface, int dx, int dy, int src_surface, int sx, int sy, int width, int height)
|
||||
{
|
||||
struct vm_surface *dst = vm_surface_get(dst_surface);
|
||||
struct vm_surface *src = vm_surface_get(src_surface);
|
||||
if (!dst || !src)
|
||||
return;
|
||||
gfx_blend_amap(&dst->texture, dx, dy, &src->texture, sx, sy, width, height);
|
||||
}
|
||||
|
||||
//void vmGraph_BlendAlphaMapSrcOnly(int dst_surface, int dx, int dy, int src_surface, int sx, int sy, int width, int height);
|
||||
//void vmGraph_BlendAlphaMapColor(int dst_surface, int dx, int dy, int src_surface, int sx, int sy, int width, int height, int r, int g, int b);
|
||||
//void vmGraph_BlendAlphaMapColorAlpha(int dst_surface, int dx, int dy, int src_surface, int sx, int sy, int width, int height, int r, int g, int b, int alpha);
|
||||
//void vmGraph_BlendAlphaMapAlpha(int dst_surface, int dx, int dy, int src_surface, int sx, int sy, int width, int height, int alpha);
|
||||
//void vmGraph_BlendAlphaMapBright(int dst_surface, int dx, int dy, int src_surface, int sx, int sy, int width, int height, int nRate);
|
||||
//void vmGraph_BlendAlphaMapAlphaSrcBright(int dst_surface, int dx, int dy, int src_surface, int sx, int sy, int width, int height, int alpha, int nRate);
|
||||
//void vmGraph_BlendUseAMapColor(int dst_surface, int dx, int dy, int width, int height, int hAlphaSurface, int nAx, int nAy, int r, int g, int b, int alpha);
|
||||
//void vmGraph_BlendScreen(int dst_surface, int dx, int dy, int src_surface, int sx, int sy, int width, int height);
|
||||
//void vmGraph_BlendMultiply(int dst_surface, int dx, int dy, int src_surface, int sx, int sy, int width, int height);
|
||||
//void vmGraph_BlendScreenAlpha(int dst_surface, int dx, int dy, int src_surface, int sx, int sy, int width, int height, int alpha);
|
||||
|
||||
static void vmGraph_Fill(int surface, int x, int y, int width, int height, int r, int g, int b, int alpha)
|
||||
{
|
||||
struct vm_surface *dst = vm_surface_get(surface);
|
||||
if (!dst)
|
||||
return;
|
||||
gfx_fill_with_alpha(&dst->texture, x, y, width, height, r, g, b, alpha);
|
||||
}
|
||||
|
||||
static void vmGraph_FillPixelMap(int surface, int x, int y, int width, int height, int r, int g, int b)
|
||||
{
|
||||
struct vm_surface *dst = vm_surface_get(surface);
|
||||
if (!dst)
|
||||
return;
|
||||
gfx_fill(&dst->texture, x, y, width, height, r, g, b);
|
||||
}
|
||||
|
||||
static void vmGraph_FillAlphaMap(int surface, int x, int y, int width, int height, int alpha)
|
||||
{
|
||||
struct vm_surface *dst = vm_surface_get(surface);
|
||||
if (!dst)
|
||||
return;
|
||||
gfx_fill_amap(&dst->texture, x, y, width, height, alpha);
|
||||
}
|
||||
|
||||
static void vmGraph_FillAlphaColor(int surface, int x, int y, int width, int height, int r, int g, int b, int rate)
|
||||
{
|
||||
struct vm_surface *dst = vm_surface_get(surface);
|
||||
if (!dst)
|
||||
return;
|
||||
gfx_fill_alpha_color(&dst->texture, x, y, width, height, r, g, b, rate);
|
||||
}
|
||||
|
||||
//void vmGraph_SaturDP_DPxSA(int dst_surface, int dx, int dy, int src_surface, int sx, int sy, int width, int height);
|
||||
//void vmGraph_ScreenDA_DAxSA(int dst_surface, int dx, int dy, int src_surface, int sx, int sy, int width, int height);
|
||||
|
||||
static void vmGraph_AddDA_DAxSA(int dst_surface, int dx, int dy, int src_surface, int sx, int sy, int width, int height)
|
||||
{
|
||||
struct vm_surface *dst = vm_surface_get(dst_surface);
|
||||
struct vm_surface *src = vm_surface_get(src_surface);
|
||||
if (!dst || !src)
|
||||
return;
|
||||
gfx_add_da_daxsa(&dst->texture, dx, dy, &src->texture, sx, sy, width, height);
|
||||
}
|
||||
|
||||
//void vmGraph_SubDA_DAxSA(int dst_surface, int dx, int dy, int src_surface, int sx, int sy, int width, int height);
|
||||
//void vmGraph_BrightDestOnly(int surface, int x, int y, int width, int height, int nRate);
|
||||
//void vmGraph_CopyTextureWrap(int dst_surface, int dx, int dy, int d_width, int d_height, int src_surface, int sx, int sy, int s_width, int s_height, int nU, int nV);
|
||||
//void vmGraph_CopyTextureWrapAlpha(int dst_surface, int dx, int dy, int d_width, int d_height, int src_surface, int sx, int sy, int s_width, int s_height, int nU, int nV, int alpha);
|
||||
|
||||
static void vmGraph_CopyStretch(int surface, int dx, int dy, int d_width, int d_height, int src_surface, float sx, float sy, float s_width, float s_height)
|
||||
{
|
||||
struct vm_surface *dst = vm_surface_get(surface);
|
||||
struct vm_surface *src = vm_surface_get(src_surface);
|
||||
if (!dst || !src)
|
||||
return;
|
||||
|
||||
// Use nearest neighbor interpolation to avoid magenta edges.
|
||||
glBindTexture(GL_TEXTURE_2D, src->texture.handle);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
gfx_copy_stretch(
|
||||
&dst->texture, dx, dy, d_width, d_height,
|
||||
&src->texture, sx, sy, s_width, s_height);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, src->texture.handle);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
//void vmGraph_CopyStretchBlend(int surface, int dx, int dy, int d_width, int d_height, int src_surface, float sx, float sy, float s_width, float s_height, int alpha);
|
||||
//void vmGraph_CopyStretchBlendAlphaMap(int surface, int dx, int dy, int d_width, int d_height, int src_surface, float sx, float sy, float s_width, float s_height);
|
||||
HLL_WARN_UNIMPLEMENTED( , void, vmGraph, SetClickCancel, int click);
|
||||
//int vmGraph_EffectCopy(int dx, int dy, int src_surface, int sx, int sy, int width, int height, int nEffect, int nTotalTime);
|
||||
//int vmGraph_GetMainWidth(void);
|
||||
//int vmGraph_GetMainHeight(void);
|
||||
//int vmGraph_GetMainBpp(void);
|
||||
|
||||
void vmGraph_Update(int x, int y, int width, int height)
|
||||
{
|
||||
gfx_swap();
|
||||
}
|
||||
|
||||
HLL_LIBRARY(vmGraph,
|
||||
HLL_EXPORT(Init, vmGraph_Init),
|
||||
HLL_TODO_EXPORT(SetUseCPUEx, vmGraph_SetUseCPUEx),
|
||||
HLL_EXPORT(Copy, vmGraph_Copy),
|
||||
HLL_EXPORT(CopyPixelMap, vmGraph_CopyPixelMap),
|
||||
HLL_EXPORT(CopyAlphaMap, vmGraph_CopyAlphaMap),
|
||||
HLL_TODO_EXPORT(CopyBright, vmGraph_CopyBright),
|
||||
HLL_EXPORT(CopySprite, vmGraph_CopySprite),
|
||||
HLL_TODO_EXPORT(Blend, vmGraph_Blend),
|
||||
HLL_TODO_EXPORT(BlendSrcBright, vmGraph_BlendSrcBright),
|
||||
HLL_TODO_EXPORT(BlendAddSatur, vmGraph_BlendAddSatur),
|
||||
HLL_EXPORT(BlendAlphaMap, vmGraph_BlendAlphaMap),
|
||||
HLL_TODO_EXPORT(BlendAlphaMapSrcOnly, vmGraph_BlendAlphaMapSrcOnly),
|
||||
HLL_TODO_EXPORT(BlendAlphaMapColor, vmGraph_BlendAlphaMapColor),
|
||||
HLL_TODO_EXPORT(BlendAlphaMapColorAlpha, vmGraph_BlendAlphaMapColorAlpha),
|
||||
HLL_TODO_EXPORT(BlendAlphaMapAlpha, vmGraph_BlendAlphaMapAlpha),
|
||||
HLL_TODO_EXPORT(BlendAlphaMapBright, vmGraph_BlendAlphaMapBright),
|
||||
HLL_TODO_EXPORT(BlendAlphaMapAlphaSrcBright, vmGraph_BlendAlphaMapAlphaSrcBright),
|
||||
HLL_TODO_EXPORT(BlendUseAMapColor, vmGraph_BlendUseAMapColor),
|
||||
HLL_TODO_EXPORT(BlendScreen, vmGraph_BlendScreen),
|
||||
HLL_TODO_EXPORT(BlendMultiply, vmGraph_BlendMultiply),
|
||||
HLL_TODO_EXPORT(BlendScreenAlpha, vmGraph_BlendScreenAlpha),
|
||||
HLL_EXPORT(Fill, vmGraph_Fill),
|
||||
HLL_EXPORT(FillPixelMap, vmGraph_FillPixelMap),
|
||||
HLL_EXPORT(FillAlphaMap, vmGraph_FillAlphaMap),
|
||||
HLL_EXPORT(FillAlphaColor, vmGraph_FillAlphaColor),
|
||||
HLL_TODO_EXPORT(SaturDP_DPxSA, vmGraph_SaturDP_DPxSA),
|
||||
HLL_TODO_EXPORT(ScreenDA_DAxSA, vmGraph_ScreenDA_DAxSA),
|
||||
HLL_EXPORT(AddDA_DAxSA, vmGraph_AddDA_DAxSA),
|
||||
HLL_TODO_EXPORT(SubDA_DAxSA, vmGraph_SubDA_DAxSA),
|
||||
HLL_TODO_EXPORT(BrightDestOnly, vmGraph_BrightDestOnly),
|
||||
HLL_TODO_EXPORT(CopyTextureWrap, vmGraph_CopyTextureWrap),
|
||||
HLL_TODO_EXPORT(CopyTextureWrapAlpha, vmGraph_CopyTextureWrapAlpha),
|
||||
HLL_EXPORT(CopyStretch, vmGraph_CopyStretch),
|
||||
HLL_TODO_EXPORT(CopyStretchBlend, vmGraph_CopyStretchBlend),
|
||||
HLL_TODO_EXPORT(CopyStretchBlendAlphaMap, vmGraph_CopyStretchBlendAlphaMap),
|
||||
HLL_EXPORT(SetClickCancel, vmGraph_SetClickCancel),
|
||||
HLL_TODO_EXPORT(EffectCopy, vmGraph_EffectCopy),
|
||||
HLL_EXPORT(GetMainSurface, vm_surface_get_main_surface),
|
||||
HLL_TODO_EXPORT(GetMainWidth, vmGraph_GetMainWidth),
|
||||
HLL_TODO_EXPORT(GetMainHeight, vmGraph_GetMainHeight),
|
||||
HLL_TODO_EXPORT(GetMainBpp, vmGraph_GetMainBpp),
|
||||
HLL_EXPORT(Update, vmGraph_Update)
|
||||
);
|
||||
@@ -0,0 +1,41 @@
|
||||
/* Copyright (C) 2024 kichikuou <KichikuouChrome@gmail.com>
|
||||
*
|
||||
* 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 "hll.h"
|
||||
|
||||
HLL_WARN_UNIMPLEMENTED(, void, vmGraphQuake, SetMode, int mode);
|
||||
//void vmGraphQuake_SetAmp(int nAmp);
|
||||
HLL_WARN_UNIMPLEMENTED(, void, vmGraphQuake, SetAmpX, int amp_x);
|
||||
HLL_WARN_UNIMPLEMENTED(, void, vmGraphQuake, SetAmpY, int amp_y);
|
||||
//void vmGraphQuake_SetCycle(int nCycle);
|
||||
//int vmGraphQuake_GetMode(void);
|
||||
//int vmGraphQuake_GetAmp(void);
|
||||
//int vmGraphQuake_GetAmpX(void);
|
||||
//int vmGraphQuake_GetAmpY(void);
|
||||
//int vmGraphQuake_GetCycle(void);
|
||||
|
||||
HLL_LIBRARY(vmGraphQuake,
|
||||
HLL_EXPORT(SetMode, vmGraphQuake_SetMode),
|
||||
HLL_TODO_EXPORT(SetAmp, vmGraphQuake_SetAmp),
|
||||
HLL_EXPORT(SetAmpX, vmGraphQuake_SetAmpX),
|
||||
HLL_EXPORT(SetAmpY, vmGraphQuake_SetAmpY),
|
||||
HLL_TODO_EXPORT(SetCycle, vmGraphQuake_SetCycle),
|
||||
HLL_TODO_EXPORT(GetMode, vmGraphQuake_GetMode),
|
||||
HLL_TODO_EXPORT(GetAmp, vmGraphQuake_GetAmp),
|
||||
HLL_TODO_EXPORT(GetAmpX, vmGraphQuake_GetAmpX),
|
||||
HLL_TODO_EXPORT(GetAmpY, vmGraphQuake_GetAmpY),
|
||||
HLL_TODO_EXPORT(GetCycle, vmGraphQuake_GetCycle)
|
||||
);
|
||||
+133
@@ -0,0 +1,133 @@
|
||||
/* Copyright (C) 2024 kichikuou <KichikuouChrome@gmail.com>
|
||||
*
|
||||
* 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 "system4.h"
|
||||
|
||||
#include "hll.h"
|
||||
#include "id_pool.h"
|
||||
#include "input.h"
|
||||
#include "vm.h"
|
||||
#include "xsystem4.h"
|
||||
|
||||
#define MAXENT 32
|
||||
|
||||
struct vm_key {
|
||||
int size;
|
||||
int win[MAXENT];
|
||||
int ret[MAXENT];
|
||||
};
|
||||
|
||||
static struct id_pool pool;
|
||||
|
||||
static void handle_events_throttled(void)
|
||||
{
|
||||
// To prevent taking 100% CPU time in busy input loops,
|
||||
// sleep 10ms every 30 input event checks.
|
||||
static int count;
|
||||
if (++count == 30) {
|
||||
count = 0;
|
||||
vm_sleep(10);
|
||||
}
|
||||
handle_events();
|
||||
}
|
||||
|
||||
static void vmKey_Init(possibly_unused void *imainsystem)
|
||||
{
|
||||
if (pool.slots)
|
||||
return; // already initialized
|
||||
id_pool_init(&pool, ID_POOL_HANDLE_BASE);
|
||||
}
|
||||
|
||||
static int vmKey_EnumHandle(void)
|
||||
{
|
||||
return id_pool_count(&pool);
|
||||
}
|
||||
|
||||
static int vmKey_Open(void)
|
||||
{
|
||||
int no = id_pool_get_unused(&pool);
|
||||
struct vm_key *vk = xcalloc(1, sizeof(struct vm_key));
|
||||
id_pool_set(&pool, no, vk);
|
||||
return no;
|
||||
}
|
||||
|
||||
static void vmKey_Close(int handle)
|
||||
{
|
||||
struct vm_key *vk = id_pool_release(&pool, handle);
|
||||
if (vk)
|
||||
free(vk);
|
||||
}
|
||||
|
||||
static void vmKey_ModuleFini(void)
|
||||
{
|
||||
for (int i = id_pool_get_first(&pool); i >= 0; i = id_pool_get_next(&pool, i))
|
||||
vmKey_Close(i);
|
||||
id_pool_delete(&pool);
|
||||
}
|
||||
|
||||
static int vmKey_Set(int handle, int win_key, int ret_key)
|
||||
{
|
||||
struct vm_key *vk = id_pool_get(&pool, handle);
|
||||
if (!vk)
|
||||
return 0;
|
||||
if (vk->size + 1 >= MAXENT)
|
||||
VM_ERROR("too many keys");
|
||||
vk->win[vk->size] = win_key;
|
||||
vk->ret[vk->size] = ret_key;
|
||||
vk->size++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int vmKey_Get(int handle)
|
||||
{
|
||||
struct vm_key *vk = id_pool_get(&pool, handle);
|
||||
if (!vk)
|
||||
return 0;
|
||||
|
||||
handle_events_throttled();
|
||||
int ret = 0;
|
||||
for (int i = 0; i < vk->size; i++) {
|
||||
if (key_is_down(vk->win[i])) {
|
||||
ret |= vk->ret[i];
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int vmKey_GetWheelCount(void)
|
||||
{
|
||||
int forward, back;
|
||||
handle_events_throttled();
|
||||
mouse_get_wheel(&forward, &back);
|
||||
mouse_clear_wheel();
|
||||
return back - forward;
|
||||
}
|
||||
|
||||
//void vmKey_ClearBuffer(void);
|
||||
|
||||
HLL_LIBRARY(vmKey,
|
||||
HLL_EXPORT(_ModuleFini, vmKey_ModuleFini),
|
||||
HLL_EXPORT(Init, vmKey_Init),
|
||||
HLL_EXPORT(EnumHandle, vmKey_EnumHandle),
|
||||
HLL_EXPORT(Open, vmKey_Open),
|
||||
HLL_EXPORT(Close, vmKey_Close),
|
||||
HLL_EXPORT(Set, vmKey_Set),
|
||||
HLL_EXPORT(Get, vmKey_Get),
|
||||
HLL_EXPORT(GetWheelCount, vmKey_GetWheelCount),
|
||||
HLL_TODO_EXPORT(ClearBuffer, vmKey_ClearBuffer)
|
||||
);
|
||||
@@ -0,0 +1,231 @@
|
||||
/* Copyright (C) 2024 kichikuou <KichikuouChrome@gmail.com>
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "system4/file.h"
|
||||
#include "system4/mt19937int.h"
|
||||
#include "system4/little_endian.h"
|
||||
|
||||
#include "hll.h"
|
||||
#include "xsystem4.h"
|
||||
|
||||
/*
|
||||
* struct MapHeader {
|
||||
* char magic[4]; // "Map\0"
|
||||
* // the below are encrypted
|
||||
* uint32_t width;
|
||||
* uint32_t height;
|
||||
* uint32_t cg_table_offset;
|
||||
* uint32_t move_table_offset;
|
||||
* uint32_t figure_table_offset;
|
||||
* uint32_t info_table_offset;
|
||||
* uint32_t map_no;
|
||||
* };
|
||||
*
|
||||
* struct CGTable {
|
||||
* uint32_t count;
|
||||
* uint32_t cg[count];
|
||||
* };
|
||||
*
|
||||
* struct MoveTable {
|
||||
* bool movable[height][width];
|
||||
* };
|
||||
*
|
||||
* struct FigureTable {
|
||||
* uint32_t count;
|
||||
* struct {
|
||||
* uint8_t x;
|
||||
* uint8_t y;
|
||||
* uint16_t unit;
|
||||
* } figures[count];
|
||||
* };
|
||||
*
|
||||
* struct InfoTable {
|
||||
* uint32_t item;
|
||||
* uint32_t gold;
|
||||
* uint32_t turn;
|
||||
* uint32_t level;
|
||||
* uint32_t unknown; // checksum?
|
||||
* };
|
||||
*/
|
||||
|
||||
static uint8_t *map_data;
|
||||
static size_t map_size;
|
||||
|
||||
static char *mapfile_path(int map_no)
|
||||
{
|
||||
char buf[32];
|
||||
sprintf(buf, "Map/%04d.map", map_no);
|
||||
return gamedir_path(buf);
|
||||
}
|
||||
|
||||
HLL_QUIET_UNIMPLEMENTED(, void, vmMapLoader,Init, void *imainsystem, struct string *string);
|
||||
|
||||
static int vmMapLoader_Exist(int map_no)
|
||||
{
|
||||
char *path = mapfile_path(map_no);
|
||||
bool result = file_exists(path);
|
||||
free(path);
|
||||
return result;
|
||||
}
|
||||
|
||||
static int vmMapLoader_New(int map_no)
|
||||
{
|
||||
if (map_data)
|
||||
free(map_data);
|
||||
|
||||
char *path = mapfile_path(map_no);
|
||||
map_data = file_read(path, &map_size);
|
||||
if (!map_data) {
|
||||
WARNING("Cannot read %s", path);
|
||||
} else if (memcmp(map_data, "Map", 4)) {
|
||||
WARNING("%s: Wrong magic bytes", path);
|
||||
free(map_data);
|
||||
map_data = NULL;
|
||||
} else {
|
||||
mt19937_xorcode(map_data + 4, map_size - 4, 12753);
|
||||
}
|
||||
|
||||
free(path);
|
||||
return !!map_data;
|
||||
}
|
||||
|
||||
void vmMapLoader_Release(void)
|
||||
{
|
||||
if (map_data) {
|
||||
free(map_data);
|
||||
map_data = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int vmMapLoader_GetWidth(void)
|
||||
{
|
||||
if (!map_data)
|
||||
return -1;
|
||||
return LittleEndian_getDW(map_data, 4);
|
||||
}
|
||||
|
||||
static int vmMapLoader_GetHeight(void)
|
||||
{
|
||||
if (!map_data)
|
||||
return -1;
|
||||
return LittleEndian_getDW(map_data, 8);
|
||||
}
|
||||
|
||||
static int vmMapLoader_GetBaseCG(int index)
|
||||
{
|
||||
if (!map_data)
|
||||
return -1;
|
||||
int nr_base_cg = LittleEndian_getDW(map_data, 32);
|
||||
if (index < 0 || index >= nr_base_cg)
|
||||
return -1;
|
||||
return LittleEndian_getDW(map_data, 36 + index * 4);
|
||||
}
|
||||
|
||||
static int vmMapLoader_GetNumofBaseCG(void)
|
||||
{
|
||||
if (!map_data)
|
||||
return -1;
|
||||
return LittleEndian_getDW(map_data, 32);
|
||||
}
|
||||
|
||||
static int vmMapLoader_IsMove(int x, int y)
|
||||
{
|
||||
if (!map_data)
|
||||
return -1;
|
||||
int w = LittleEndian_getDW(map_data, 4);
|
||||
int h = LittleEndian_getDW(map_data, 8);
|
||||
if (x < 0 || x >= w || y < 0 || y > h)
|
||||
return 0;
|
||||
uint8_t *table = map_data + LittleEndian_getDW(map_data, 16);
|
||||
return table[y * w + x];
|
||||
}
|
||||
|
||||
static int vmMapLoader_GetFigure(int x, int y)
|
||||
{
|
||||
if (!map_data)
|
||||
return 0;
|
||||
|
||||
int offset = LittleEndian_getDW(map_data, 20);
|
||||
int num = LittleEndian_getDW(map_data, offset);
|
||||
uint8_t *table = map_data + offset + 4;
|
||||
|
||||
for (int i = 0; i < num; i++) {
|
||||
if (x == table[i * 4] && y == table[i * 4 + 1])
|
||||
return LittleEndian_getW(table, i * 4 + 2);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vmMapLoader_GetItemNum(void)
|
||||
{
|
||||
if (!map_data)
|
||||
return -1;
|
||||
int offset = LittleEndian_getDW(map_data, 24);
|
||||
return LittleEndian_getDW(map_data, offset + 0);
|
||||
}
|
||||
|
||||
static int vmMapLoader_GetGoldNum(void)
|
||||
{
|
||||
if (!map_data)
|
||||
return -1;
|
||||
int offset = LittleEndian_getDW(map_data, 24);
|
||||
return LittleEndian_getDW(map_data, offset + 4);
|
||||
}
|
||||
|
||||
static int vmMapLoader_GetTurnNum(void)
|
||||
{
|
||||
if (!map_data)
|
||||
return -1;
|
||||
int offset = LittleEndian_getDW(map_data, 24);
|
||||
return LittleEndian_getDW(map_data, offset + 8);
|
||||
}
|
||||
|
||||
static int vmMapLoader_GetLevel(void)
|
||||
{
|
||||
if (!map_data)
|
||||
return -1;
|
||||
int offset = LittleEndian_getDW(map_data, 24);
|
||||
return LittleEndian_getDW(map_data, offset + 12);
|
||||
}
|
||||
|
||||
|
||||
static int vmMapLoader_GetID(void)
|
||||
{
|
||||
if (!map_data)
|
||||
return -1;
|
||||
return LittleEndian_getDW(map_data, 28);
|
||||
}
|
||||
|
||||
HLL_LIBRARY(vmMapLoader,
|
||||
HLL_EXPORT(Init, vmMapLoader_Init),
|
||||
HLL_EXPORT(Exist, vmMapLoader_Exist),
|
||||
HLL_EXPORT(New, vmMapLoader_New),
|
||||
HLL_EXPORT(Release, vmMapLoader_Release),
|
||||
HLL_EXPORT(GetWidth, vmMapLoader_GetWidth),
|
||||
HLL_EXPORT(GetHeight, vmMapLoader_GetHeight),
|
||||
HLL_EXPORT(GetBaseCG, vmMapLoader_GetBaseCG),
|
||||
HLL_EXPORT(GetNumofBaseCG, vmMapLoader_GetNumofBaseCG),
|
||||
HLL_EXPORT(IsMove, vmMapLoader_IsMove),
|
||||
HLL_EXPORT(GetFigure, vmMapLoader_GetFigure),
|
||||
HLL_EXPORT(GetItemNum, vmMapLoader_GetItemNum),
|
||||
HLL_EXPORT(GetGoldNum, vmMapLoader_GetGoldNum),
|
||||
HLL_EXPORT(GetTurnNum, vmMapLoader_GetTurnNum),
|
||||
HLL_EXPORT(GetLevel, vmMapLoader_GetLevel),
|
||||
HLL_EXPORT(GetID, vmMapLoader_GetID)
|
||||
);
|
||||
@@ -0,0 +1,108 @@
|
||||
/* Copyright (C) 2024 kichikuou <KichikuouChrome@gmail.com>
|
||||
*
|
||||
* 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 "system4/ain.h"
|
||||
#include "system4/string.h"
|
||||
|
||||
#include "hll.h"
|
||||
#include "id_pool.h"
|
||||
#include "vm.h"
|
||||
#include "vm/page.h"
|
||||
|
||||
struct vm_msglog {
|
||||
struct page *array; // backing store
|
||||
int ptr;
|
||||
};
|
||||
|
||||
static struct id_pool pool;
|
||||
|
||||
static void vmMsgLog_Init(possibly_unused void *imainsystem)
|
||||
{
|
||||
if (pool.slots)
|
||||
return; // already initialized
|
||||
id_pool_init(&pool, ID_POOL_HANDLE_BASE);
|
||||
}
|
||||
|
||||
static int vmMsgLog_EnumHandle(void)
|
||||
{
|
||||
return id_pool_count(&pool);
|
||||
}
|
||||
|
||||
static int vmMsgLog_Open(struct page **array)
|
||||
{
|
||||
int no = id_pool_get_unused(&pool);
|
||||
struct vm_msglog *log = xcalloc(1, sizeof(struct vm_msglog));
|
||||
id_pool_set(&pool, no, log);
|
||||
log->array = *array;
|
||||
log->ptr = 0;
|
||||
return no;
|
||||
}
|
||||
|
||||
static void vmMsgLog_Close(int handle)
|
||||
{
|
||||
struct vm_msglog *log = id_pool_release(&pool, handle);
|
||||
if (log)
|
||||
free(log);
|
||||
}
|
||||
|
||||
static void vmMsgLog_ModuleFini(void)
|
||||
{
|
||||
for (int i = id_pool_get_first(&pool); i >= 0; i = id_pool_get_next(&pool, i))
|
||||
vmMsgLog_Close(i);
|
||||
id_pool_delete(&pool);
|
||||
}
|
||||
|
||||
static int vmMsgLog_Set(int handle, int msg_num)
|
||||
{
|
||||
struct vm_msglog *log = id_pool_get(&pool, handle);
|
||||
if (!log)
|
||||
return 0;
|
||||
|
||||
if (--log->ptr < 0)
|
||||
log->ptr = log->array->nr_vars - 1;
|
||||
log->array->values[log->ptr].i = msg_num;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int vmMsgLog_Get(int handle, int index)
|
||||
{
|
||||
struct vm_msglog *log = id_pool_get(&pool, handle);
|
||||
if (!log)
|
||||
return -1;
|
||||
|
||||
int i = (index + log->ptr) % log->array->nr_vars;
|
||||
return log->array->values[i].i;
|
||||
}
|
||||
|
||||
static struct string *vmMsgLog_MsgNumToString(int msg_num)
|
||||
{
|
||||
if (msg_num < 0 || msg_num >= ain->nr_messages)
|
||||
return string_ref(&EMPTY_STRING);
|
||||
return string_ref(ain->messages[msg_num]);
|
||||
}
|
||||
|
||||
HLL_LIBRARY(vmMsgLog,
|
||||
HLL_EXPORT(_ModuleFini, vmMsgLog_ModuleFini),
|
||||
HLL_EXPORT(Init, vmMsgLog_Init),
|
||||
HLL_EXPORT(EnumHandle, vmMsgLog_EnumHandle),
|
||||
HLL_EXPORT(Open, vmMsgLog_Open),
|
||||
HLL_EXPORT(Close, vmMsgLog_Close),
|
||||
HLL_EXPORT(Set, vmMsgLog_Set),
|
||||
HLL_EXPORT(Get, vmMsgLog_Get),
|
||||
HLL_EXPORT(MsgNumToString, vmMsgLog_MsgNumToString)
|
||||
);
|
||||
@@ -0,0 +1,39 @@
|
||||
/* Copyright (C) 2024 kichikuou <KichikuouChrome@gmail.com>
|
||||
*
|
||||
* 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 "hll.h"
|
||||
|
||||
HLL_WARN_UNIMPLEMENTED(, void, vmMsgSkip, Init, void *imainsystem);
|
||||
//int vmMsgSkip_EnumHandle(void);
|
||||
//int vmMsgSkip_Open(struct string *pIString, int nOption);
|
||||
//void vmMsgSkip_Close(int hMsgSkip);
|
||||
//int vmMsgSkip_Query(int hMsgSkip, int nMsgNum);
|
||||
//void vmMsgSkip_SetEnable(int nEnable);
|
||||
HLL_QUIET_UNIMPLEMENTED(, void, vmMsgSkip, SetState, int state);
|
||||
//int vmMsgSkip_GetEnable(void);
|
||||
//int vmMsgSkip_GetState(void);
|
||||
|
||||
HLL_LIBRARY(vmMsgSkip,
|
||||
HLL_EXPORT(Init, vmMsgSkip_Init),
|
||||
HLL_TODO_EXPORT(EnumHandle, vmMsgSkip_EnumHandle),
|
||||
HLL_TODO_EXPORT(Open, vmMsgSkip_Open),
|
||||
HLL_TODO_EXPORT(Close, vmMsgSkip_Close),
|
||||
HLL_TODO_EXPORT(Query, vmMsgSkip_Query),
|
||||
HLL_TODO_EXPORT(SetEnable, vmMsgSkip_SetEnable),
|
||||
HLL_EXPORT(SetState, vmMsgSkip_SetState),
|
||||
HLL_TODO_EXPORT(GetEnable, vmMsgSkip_GetEnable),
|
||||
HLL_TODO_EXPORT(GetState, vmMsgSkip_GetState)
|
||||
);
|
||||
@@ -0,0 +1,85 @@
|
||||
/* Copyright (C) 2024 kichikuou <KichikuouChrome@gmail.com>
|
||||
*
|
||||
* 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 "system4.h"
|
||||
|
||||
#include "hll.h"
|
||||
#include "audio.h"
|
||||
|
||||
static int max_channel;
|
||||
static int *current;
|
||||
|
||||
static void vmMusic_Init(int max_channel_, possibly_unused void *imainsystem)
|
||||
{
|
||||
audio_init();
|
||||
max_channel = max_channel_;
|
||||
current = xcalloc(max_channel, sizeof(int));
|
||||
}
|
||||
|
||||
static int vmMusic_Prepare(int channel, int track)
|
||||
{
|
||||
if (channel < 0 || channel >= max_channel)
|
||||
return 0;
|
||||
if (current[channel] == track)
|
||||
return 1; // Keep playing current music.
|
||||
int r = bgm_prepare(channel, track);
|
||||
if (r)
|
||||
current[channel] = track;
|
||||
return r;
|
||||
}
|
||||
|
||||
static int vmMusic_Play(int channel)
|
||||
{
|
||||
return bgm_play(channel);
|
||||
}
|
||||
|
||||
static int vmMusic_Stop(int channel)
|
||||
{
|
||||
return bgm_stop(channel);
|
||||
}
|
||||
|
||||
static int vmMusic_IsPlay(int channel)
|
||||
{
|
||||
return bgm_is_playing(channel);
|
||||
}
|
||||
|
||||
//int vmMusic_SetLoop(int channel, int nLoop);
|
||||
//int vmMusic_GetLoop(int channel);
|
||||
|
||||
static int vmMusic_Fade(int channel, int time, int volume, int stop)
|
||||
{
|
||||
return bgm_fade(channel, time, volume, stop);
|
||||
}
|
||||
|
||||
//int vmMusic_StopFade(int channel);
|
||||
//int vmMusic_IsFade(int channel);
|
||||
//int vmMusic_GetPos(int channel);
|
||||
//int vmMusic_GetLength(int channel);
|
||||
|
||||
HLL_LIBRARY(vmMusic,
|
||||
HLL_EXPORT(Init, vmMusic_Init),
|
||||
HLL_EXPORT(Prepare, vmMusic_Prepare),
|
||||
HLL_EXPORT(Play, vmMusic_Play),
|
||||
HLL_EXPORT(Stop, vmMusic_Stop),
|
||||
HLL_EXPORT(IsPlay, vmMusic_IsPlay),
|
||||
HLL_TODO_EXPORT(SetLoop, vmMusic_SetLoop),
|
||||
HLL_TODO_EXPORT(GetLoop, vmMusic_GetLoop),
|
||||
HLL_EXPORT(Fade, vmMusic_Fade),
|
||||
HLL_TODO_EXPORT(StopFade, vmMusic_StopFade),
|
||||
HLL_TODO_EXPORT(IsFade, vmMusic_IsFade),
|
||||
HLL_TODO_EXPORT(GetPos, vmMusic_GetPos),
|
||||
HLL_TODO_EXPORT(GetLength, vmMusic_GetLength)
|
||||
);
|
||||
@@ -0,0 +1,86 @@
|
||||
/* Copyright (C) 2024 kichikuou <KichikuouChrome@gmail.com>
|
||||
*
|
||||
* 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 "audio.h"
|
||||
#include "hll.h"
|
||||
#include "ChrLoader.h"
|
||||
|
||||
static int ring_pos = 0;
|
||||
|
||||
static void vmSound_Init(possibly_unused void *imainsystem)
|
||||
{
|
||||
audio_init();
|
||||
}
|
||||
|
||||
//void vmSound_Enable(int nEnable);
|
||||
//void vmSound_SetType(int nType);
|
||||
|
||||
static int vmSound_Load(int channel, int num)
|
||||
{
|
||||
return wav_prepare(channel, num);
|
||||
}
|
||||
|
||||
static int vmSound_LoadMemory(int channel, int memory)
|
||||
{
|
||||
struct archive_data *dfile = chr_loader_get_blob_as_archive_data(memory);
|
||||
if (!dfile)
|
||||
return 0;
|
||||
return wav_prepare_from_archive_data(channel, dfile);
|
||||
}
|
||||
|
||||
static void vmSound_Unload(int channel, possibly_unused int length)
|
||||
{
|
||||
wav_unprepare(channel);
|
||||
}
|
||||
|
||||
static int vmSound_Play(int channel, possibly_unused int length)
|
||||
{
|
||||
wav_stop(channel);
|
||||
return wav_play(channel);
|
||||
}
|
||||
|
||||
static int vmSound_RingPlay(int channel, int ring)
|
||||
{
|
||||
channel += ring_pos++ % ring;
|
||||
wav_stop(channel);
|
||||
return wav_play(channel);
|
||||
}
|
||||
|
||||
//int vmSound_Stop(int channel, int nLength);
|
||||
//int vmSound_IsPlay(int channel, int nLength);
|
||||
//void vmSound_Wait(int channel, int nLength);
|
||||
//int vmSound_Fade(int channel, int nLength, int nTime, int nVolume, int nStopFlag);
|
||||
//int vmSound_StopFade(int channel, int nLength);
|
||||
//int vmSound_IsFade(int channel, int nLength);
|
||||
//int vmSound_ReverseLR(int channel, int nLength);
|
||||
|
||||
HLL_LIBRARY(vmSound,
|
||||
HLL_EXPORT(Init, vmSound_Init),
|
||||
HLL_TODO_EXPORT(Enable, vmSound_Enable),
|
||||
HLL_TODO_EXPORT(SetType, vmSound_SetType),
|
||||
HLL_EXPORT(Load, vmSound_Load),
|
||||
HLL_EXPORT(LoadMemory, vmSound_LoadMemory),
|
||||
HLL_EXPORT(Unload, vmSound_Unload),
|
||||
HLL_EXPORT(Play, vmSound_Play),
|
||||
HLL_EXPORT(RingPlay, vmSound_RingPlay),
|
||||
HLL_TODO_EXPORT(Stop, vmSound_Stop),
|
||||
HLL_TODO_EXPORT(IsPlay, vmSound_IsPlay),
|
||||
HLL_TODO_EXPORT(Wait, vmSound_Wait),
|
||||
HLL_TODO_EXPORT(Fade, vmSound_Fade),
|
||||
HLL_TODO_EXPORT(StopFade, vmSound_StopFade),
|
||||
HLL_TODO_EXPORT(IsFade, vmSound_IsFade),
|
||||
HLL_TODO_EXPORT(ReverseLR, vmSound_ReverseLR)
|
||||
);
|
||||
@@ -0,0 +1,628 @@
|
||||
/* Copyright (C) 2024 kichikuou <KichikuouChrome@gmail.com>
|
||||
*
|
||||
* 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 <SDL.h>
|
||||
|
||||
#include "cJSON.h"
|
||||
#include "effect.h"
|
||||
#include "gfx/gfx.h"
|
||||
#include "hll.h"
|
||||
#include "id_pool.h"
|
||||
#include "input.h"
|
||||
#include "json.h"
|
||||
#include "sact.h"
|
||||
#include "scene.h"
|
||||
#include "vm/page.h"
|
||||
#include "vmSurface.h"
|
||||
|
||||
struct child_surface {
|
||||
int surface;
|
||||
int type;
|
||||
Point pos;
|
||||
};
|
||||
|
||||
struct animation {
|
||||
int nr_frames;
|
||||
int current_frame;
|
||||
int total_frame_time;
|
||||
int frame_times[];
|
||||
};
|
||||
|
||||
struct vm_sprite {
|
||||
struct sprite sp;
|
||||
int surface;
|
||||
int type;
|
||||
Rectangle rect;
|
||||
int current;
|
||||
int id;
|
||||
bool findable;
|
||||
struct animation *anime;
|
||||
struct id_pool children;
|
||||
};
|
||||
|
||||
static struct id_pool pool;
|
||||
static int default_layer = 200000;
|
||||
static SDL_Rect dirty_rect;
|
||||
|
||||
static void check_array(struct page *array)
|
||||
{
|
||||
if (array->type != ARRAY_PAGE || array->a_type != AIN_ARRAY_INT || array->array.rank != 1)
|
||||
VM_ERROR("Not a flat integer array");
|
||||
}
|
||||
|
||||
static void vm_sprite_dirty(struct vm_sprite *sp)
|
||||
{
|
||||
scene_sprite_dirty(&sp->sp);
|
||||
SDL_UnionRect(&dirty_rect, &sp->rect, &dirty_rect);
|
||||
}
|
||||
|
||||
static void update_animation(void)
|
||||
{
|
||||
uint64_t now = SDL_GetTicks64();
|
||||
|
||||
for (int id = id_pool_get_first(&pool); id >= 0; id = id_pool_get_next(&pool, id)) {
|
||||
struct vm_sprite *sp = id_pool_get(&pool, id);
|
||||
if (!sp || !sp->anime)
|
||||
continue;
|
||||
int t = now % sp->anime->total_frame_time;
|
||||
int frame;
|
||||
for (frame = 0; t >= sp->anime->frame_times[frame]; frame++)
|
||||
t -= sp->anime->frame_times[frame];
|
||||
if (frame == sp->anime->current_frame)
|
||||
continue;
|
||||
sp->anime->current_frame = frame;
|
||||
vm_sprite_dirty(sp);
|
||||
}
|
||||
}
|
||||
|
||||
static void render_surface(int surface, int type, int current, Rectangle *rect, Point *pos)
|
||||
{
|
||||
struct vm_surface *sf = vm_surface_get(surface);
|
||||
Texture *src = &sf->texture;
|
||||
Texture *dst = gfx_main_surface();
|
||||
int sx = 0;
|
||||
int sy = 0;
|
||||
int dx = rect->x + (pos ? pos->x : 0);
|
||||
int dy = rect->y + (pos ? pos->y : 0);
|
||||
int w = pos ? src->w : rect->w;
|
||||
int h = pos ? src->h : rect->h;
|
||||
|
||||
if (current) {
|
||||
int col = sf->w / w;
|
||||
sx = current % col * w;
|
||||
sy = current / col * h;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case 0:
|
||||
gfx_copy(dst, dx, dy, src, sx, sy, w, h);
|
||||
break;
|
||||
case 1:
|
||||
gfx_blend_amap(dst, dx, dy, src, sx, sy, w, h);
|
||||
break;
|
||||
case 2:
|
||||
gfx_copy_sprite(dst, dx, dy, src, sx, sy, w, h, COLOR(255, 0, 255, 0));
|
||||
break;
|
||||
case 3:
|
||||
gfx_blend_add_satur(dst, dx, dy, src, sx, sy, w, h);
|
||||
break;
|
||||
default:
|
||||
WARNING("unknown vmSprite type %d", type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void vm_sprite_render(struct sprite *_sp)
|
||||
{
|
||||
struct vm_sprite *sp = (struct vm_sprite*)_sp;
|
||||
if (sp->current >= 0) {
|
||||
int current = sp->current + (sp->anime ? sp->anime->current_frame : 0);
|
||||
render_surface(sp->surface, sp->type, current, &sp->rect, NULL);
|
||||
}
|
||||
|
||||
for (int id = id_pool_get_first(&sp->children); id >= 0; id = id_pool_get_next(&sp->children, id)) {
|
||||
struct child_surface *child = id_pool_get(&sp->children, id);
|
||||
if (!child)
|
||||
continue;
|
||||
render_surface(child->surface, child->type, 0, &sp->rect, &child->pos);
|
||||
}
|
||||
}
|
||||
|
||||
static cJSON *vm_sprite_to_json(struct sprite *_sp, bool verbose)
|
||||
{
|
||||
struct vm_sprite* sp = (struct vm_sprite*)_sp;
|
||||
cJSON *ent, *sprite, *children;
|
||||
|
||||
ent = scene_sprite_to_json(_sp, verbose);
|
||||
cJSON_AddItemToObjectCS(ent, "vmSprite", sprite = cJSON_CreateObject());
|
||||
|
||||
cJSON_AddNumberToObject(sprite, "surface", sp->surface);
|
||||
struct vm_surface *sf = vm_surface_get(sp->surface);
|
||||
if (sf && sf->cg_no) {
|
||||
cJSON_AddNumberToObject(sprite, "cg_no", sf->cg_no);
|
||||
}
|
||||
|
||||
cJSON_AddNumberToObject(sprite, "type", sp->type);
|
||||
cJSON_AddItemToObjectCS(sprite, "rect", rectangle_to_json(&sp->rect, verbose));
|
||||
cJSON_AddNumberToObject(sprite, "current", sp->current);
|
||||
|
||||
cJSON_AddItemToObjectCS(sprite, "children", children = cJSON_CreateArray());
|
||||
for (int id = id_pool_get_first(&sp->children); id >= 0; id = id_pool_get_next(&sp->children, id)) {
|
||||
struct child_surface *child = id_pool_get(&sp->children, id);
|
||||
if (!child)
|
||||
continue;
|
||||
cJSON *c;
|
||||
cJSON_AddItemToArray(children, c = cJSON_CreateObject());
|
||||
cJSON_AddNumberToObject(c, "surface", child->surface);
|
||||
cJSON_AddNumberToObject(c, "type", child->type);
|
||||
cJSON_AddItemToObjectCS(c, "pos", point_to_json(&child->pos, verbose));
|
||||
}
|
||||
|
||||
return ent;
|
||||
}
|
||||
|
||||
static void vm_sprite_delete(struct vm_sprite *sp)
|
||||
{
|
||||
if (!sp)
|
||||
return;
|
||||
scene_unregister_sprite(&sp->sp);
|
||||
for (int id = id_pool_get_first(&sp->children); id >= 0; id = id_pool_get_next(&sp->children, id)) {
|
||||
struct child_surface *child = id_pool_get(&sp->children, id);
|
||||
if (child)
|
||||
free(child);
|
||||
}
|
||||
if (sp->anime)
|
||||
free(sp->anime);
|
||||
id_pool_delete(&sp->children);
|
||||
free(sp);
|
||||
}
|
||||
|
||||
static void vmSprite_New(possibly_unused void *imainsystem)
|
||||
{
|
||||
if (pool.slots)
|
||||
return; // already initialized
|
||||
id_pool_init(&pool, ID_POOL_HANDLE_BASE);
|
||||
}
|
||||
|
||||
static int vmSprite_EnumHandle(void)
|
||||
{
|
||||
return id_pool_count(&pool);
|
||||
}
|
||||
|
||||
static int vmSprite_Open(int surface, int type, int width, int height)
|
||||
{
|
||||
int no = id_pool_get_unused(&pool);
|
||||
struct vm_sprite *sp = xcalloc(1, sizeof(struct vm_sprite));
|
||||
id_pool_set(&pool, no, sp);
|
||||
sp->sp.z = ++default_layer;
|
||||
sp->sp.has_pixel = true;
|
||||
sp->sp.hidden = true;
|
||||
sp->sp.id = no;
|
||||
sp->sp.render = vm_sprite_render;
|
||||
sp->sp.to_json = vm_sprite_to_json;
|
||||
sp->surface = surface;
|
||||
sp->type = type;
|
||||
sp->rect.w = width;
|
||||
sp->rect.h = height;
|
||||
sp->id = -1;
|
||||
return no;
|
||||
}
|
||||
|
||||
static int vmSprite_Reopen(int sprite, int surface, int type, int width, int height)
|
||||
{
|
||||
struct vm_sprite *sp = id_pool_get(&pool, sprite);
|
||||
if (!sp)
|
||||
return 0;
|
||||
sp->surface = surface;
|
||||
sp->type = type;
|
||||
sp->rect.w = width;
|
||||
sp->rect.h = height;
|
||||
return sprite;
|
||||
}
|
||||
|
||||
static void vmSprite_Close(int sprite)
|
||||
{
|
||||
vm_sprite_delete(id_pool_release(&pool, sprite));
|
||||
}
|
||||
|
||||
static int vmSprite_Release(void)
|
||||
{
|
||||
for (int i = id_pool_get_first(&pool); i >= 0; i = id_pool_get_next(&pool, i))
|
||||
vmSprite_Close(i);
|
||||
id_pool_delete(&pool);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void vmSprite_ModuleFini(void)
|
||||
{
|
||||
vmSprite_Release();
|
||||
}
|
||||
|
||||
static int vmSprite_SetLayer(int sprite, int layer)
|
||||
{
|
||||
struct vm_sprite *sp = id_pool_get(&pool, sprite);
|
||||
if (!sp)
|
||||
return 0;
|
||||
scene_set_sprite_z(&sp->sp, layer);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void vmSprite_SetPos(int sprite, int x, int y)
|
||||
{
|
||||
struct vm_sprite *sp = id_pool_get(&pool, sprite);
|
||||
if (sp) {
|
||||
vm_sprite_dirty(sp);
|
||||
sp->rect.x = x;
|
||||
sp->rect.y = y;
|
||||
vm_sprite_dirty(sp);
|
||||
}
|
||||
}
|
||||
|
||||
static int vmSprite_SetCurrent(int sprite, int current)
|
||||
{
|
||||
struct vm_sprite *sp = id_pool_get(&pool, sprite);
|
||||
if (!sp)
|
||||
return 0;
|
||||
if (sp->current != current) {
|
||||
sp->current = current;
|
||||
vm_sprite_dirty(sp);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int vmSprite_SetCurrentArray1(struct page *array, int current)
|
||||
{
|
||||
if (!array)
|
||||
return 0;
|
||||
check_array(array);
|
||||
|
||||
for (int i = 0; i < array->nr_vars; i++) {
|
||||
vmSprite_SetCurrent(array->values[i].i, current);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int vmSprite_SetCurrentArray2(struct page *sprite_array, struct page *current_array)
|
||||
{
|
||||
if (!sprite_array || !current_array)
|
||||
return 0;
|
||||
check_array(sprite_array);
|
||||
check_array(current_array);
|
||||
if (sprite_array->nr_vars != current_array->nr_vars)
|
||||
return 0;
|
||||
for (int i = 0; i < sprite_array->nr_vars; i++) {
|
||||
vmSprite_SetCurrent(sprite_array->values[i].i, current_array->values[i].i);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int vmSprite_SetShow(int sprite, int show)
|
||||
{
|
||||
struct vm_sprite *sp = id_pool_get(&pool, sprite);
|
||||
if (!sp)
|
||||
return 0;
|
||||
scene_set_sprite_show(&sp->sp, show);
|
||||
vm_sprite_dirty(sp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int vmSprite_SetShowArray1(struct page *array, int show)
|
||||
{
|
||||
if (!array)
|
||||
return 0;
|
||||
check_array(array);
|
||||
|
||||
for (int i = 0; i < array->nr_vars; i++) {
|
||||
vmSprite_SetShow(array->values[i].i, show);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int vmSprite_SetShowArray2(struct page *sprite_array, struct page *show_array)
|
||||
{
|
||||
if (!sprite_array || !show_array)
|
||||
return 0;
|
||||
check_array(sprite_array);
|
||||
check_array(show_array);
|
||||
if (sprite_array->nr_vars != show_array->nr_vars)
|
||||
return 0;
|
||||
for (int i = 0; i < sprite_array->nr_vars; i++) {
|
||||
vmSprite_SetShow(sprite_array->values[i].i, show_array->values[i].i);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void vmSprite_SetRenewal(int sprite)
|
||||
{
|
||||
struct vm_sprite *sp = id_pool_get(&pool, sprite);
|
||||
if (!sp)
|
||||
return;
|
||||
vm_sprite_dirty(sp);
|
||||
}
|
||||
|
||||
static void vmSprite_SetFind(int sprite, int find)
|
||||
{
|
||||
struct vm_sprite *sp = id_pool_get(&pool, sprite);
|
||||
if (sp)
|
||||
sp->findable = !!find;
|
||||
}
|
||||
|
||||
static void vmSprite_SetID(int sprite, int id)
|
||||
{
|
||||
struct vm_sprite *sp = id_pool_get(&pool, sprite);
|
||||
if (sp)
|
||||
sp->id = id;
|
||||
}
|
||||
|
||||
static int vmSprite_SetAnime(int sprite, int frame_s, int frame_e, struct page *array)
|
||||
{
|
||||
struct vm_sprite *sp = id_pool_get(&pool, sprite);
|
||||
if (!sp)
|
||||
return 0;
|
||||
check_array(array);
|
||||
if (sp->anime)
|
||||
free(sp->anime);
|
||||
int nr_frames = array->nr_vars;
|
||||
struct animation *a = xmalloc(sizeof(struct animation) + nr_frames * sizeof(int));
|
||||
a->nr_frames = nr_frames;
|
||||
a->current_frame = 0;
|
||||
a->total_frame_time = 0;
|
||||
for (int i = 0; i < a->nr_frames; i++) {
|
||||
a->total_frame_time += a->frame_times[i] = array->values[i].i;
|
||||
}
|
||||
sp->anime = a;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void vmSprite_ResetAnime(int sprite)
|
||||
{
|
||||
struct vm_sprite *sp = id_pool_get(&pool, sprite);
|
||||
if (!sp)
|
||||
return;
|
||||
free(sp->anime);
|
||||
sp->anime = NULL;
|
||||
}
|
||||
|
||||
static int vmSprite_SetChildSurface(int sprite, int num, int surface, int type, int x, int y)
|
||||
{
|
||||
struct vm_sprite *sp = id_pool_get(&pool, sprite);
|
||||
if (!sp)
|
||||
return 0;
|
||||
|
||||
struct child_surface *child = id_pool_get(&sp->children, num);
|
||||
if (!child) {
|
||||
child = xcalloc(1, sizeof(struct child_surface));
|
||||
id_pool_set(&sp->children, num, child);
|
||||
}
|
||||
child->surface = surface;
|
||||
child->type = type;
|
||||
child->pos.x = x;
|
||||
child->pos.y = y;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int vmSprite_ResetChildSurface(int sprite, int num)
|
||||
{
|
||||
struct vm_sprite *sp = id_pool_get(&pool, sprite);
|
||||
if (!sp)
|
||||
return 0;
|
||||
|
||||
struct child_surface *child = id_pool_release(&sp->children, num);
|
||||
if (child)
|
||||
free(child);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void vmSprite_Draw(int update)
|
||||
{
|
||||
handle_events();
|
||||
update_animation();
|
||||
if (scene_is_dirty) {
|
||||
scene_render();
|
||||
if (update)
|
||||
gfx_swap();
|
||||
scene_is_dirty = false;
|
||||
dirty_rect = RECT(0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void vmSprite_DrawEffect(int effect, int time)
|
||||
{
|
||||
// XXX: This function should only apply the effect to `dirty_rect`, while
|
||||
// sact_Effect applies the effect to the whole screen. In most cases it
|
||||
// doesn't make a difference because (1) the effect is no-op for pixels
|
||||
// where the old and new colors are the same (e.g. crossfade), or (2) the
|
||||
// whole screen is dirty. In Mamanyonyo, the exception is
|
||||
// EFFECT_ROTATE_OUT_CW, which must be applied to `dirty_rect` correctly.
|
||||
if (effect != EFFECT_ROTATE_OUT_CW) {
|
||||
sact_Effect(effect, time, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (SDL_RectEmpty(&dirty_rect))
|
||||
return;
|
||||
uint64_t start = SDL_GetTicks64();
|
||||
Texture *screen = gfx_main_surface();
|
||||
Texture base, src;
|
||||
gfx_init_texture_blank(&src, dirty_rect.w, dirty_rect.h);
|
||||
gfx_copy(&src, 0, 0, screen, dirty_rect.x, dirty_rect.y, dirty_rect.w, dirty_rect.h);
|
||||
scene_render();
|
||||
gfx_copy_main_surface(&base);
|
||||
|
||||
uint64_t t = SDL_GetTicks64() - start;
|
||||
float cx = dirty_rect.x + dirty_rect.w / 2.0f;
|
||||
float cy = dirty_rect.y + dirty_rect.h / 2.0f;
|
||||
while (t < time) {
|
||||
float rate = (float)t / time;
|
||||
|
||||
gfx_clear();
|
||||
gfx_copy(screen, 0, 0, &base, 0, 0, screen->w, screen->h);
|
||||
gfx_copy_root_zoom2(screen, cx, cy, &src, src.w / 2.0f, src.h / 2.0f, rate * -360, 1.0f - rate);
|
||||
gfx_swap();
|
||||
|
||||
uint64_t t2 = SDL_GetTicks64() - start;
|
||||
if (t2 < t + 16) {
|
||||
SDL_Delay(t + 16 - t2);
|
||||
t += 16;
|
||||
} else {
|
||||
t = t2;
|
||||
}
|
||||
}
|
||||
gfx_delete_texture(&base);
|
||||
gfx_delete_texture(&src);
|
||||
}
|
||||
|
||||
static int vmSprite_AddRect(int x, int y, int width, int height)
|
||||
{
|
||||
SDL_Rect r = RECT(x, y, width, height);
|
||||
SDL_UnionRect(&dirty_rect, &r, &dirty_rect);
|
||||
scene_dirty();
|
||||
return 1;
|
||||
}
|
||||
|
||||
//void vmSprite_SetSurface(int hSurface);
|
||||
|
||||
static int vmSprite_FindPos(int x, int y)
|
||||
{
|
||||
int found = 0;
|
||||
int z = 0;
|
||||
Point p = { .x = x, .y = y };
|
||||
for (int id = id_pool_get_first(&pool); id >= 0; id = id_pool_get_next(&pool, id)) {
|
||||
struct vm_sprite *sp = id_pool_get(&pool, id);
|
||||
if (!sp || !sp->findable)
|
||||
continue;
|
||||
if (!SDL_PointInRect(&p, &sp->rect))
|
||||
continue;
|
||||
if (found && sp->sp.z < z)
|
||||
continue;
|
||||
found = id;
|
||||
z = sp->sp.z;
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
//int vmSprite_FindSprite(int sprite);
|
||||
|
||||
static int vmSprite_GetSurface(int sprite)
|
||||
{
|
||||
struct vm_sprite *sp = id_pool_get(&pool, sprite);
|
||||
return sp ? sp->surface : 0;
|
||||
}
|
||||
|
||||
static int vmSprite_GetType(int sprite)
|
||||
{
|
||||
struct vm_sprite *sp = id_pool_get(&pool, sprite);
|
||||
return sp ? sp->type : 0;
|
||||
}
|
||||
|
||||
static int vmSprite_GetWidth(int sprite)
|
||||
{
|
||||
struct vm_sprite *sp = id_pool_get(&pool, sprite);
|
||||
return sp ? sp->rect.w : 0;
|
||||
}
|
||||
|
||||
static int vmSprite_GetHeight(int sprite)
|
||||
{
|
||||
struct vm_sprite *sp = id_pool_get(&pool, sprite);
|
||||
return sp ? sp->rect.h : 0;
|
||||
}
|
||||
|
||||
static int vmSprite_GetLayer(int sprite)
|
||||
{
|
||||
struct vm_sprite *sp = id_pool_get(&pool, sprite);
|
||||
return sp ? sp->sp.z : 0;
|
||||
}
|
||||
|
||||
static int vmSprite_GetX(int sprite)
|
||||
{
|
||||
struct vm_sprite *sp = id_pool_get(&pool, sprite);
|
||||
return sp ? sp->rect.x : 0;
|
||||
}
|
||||
|
||||
static int vmSprite_GetY(int sprite)
|
||||
{
|
||||
struct vm_sprite *sp = id_pool_get(&pool, sprite);
|
||||
return sp ? sp->rect.y : 0;
|
||||
}
|
||||
|
||||
static int vmSprite_GetCurrent(int sprite)
|
||||
{
|
||||
struct vm_sprite *sp = id_pool_get(&pool, sprite);
|
||||
return sp ? sp->current : 0;
|
||||
}
|
||||
|
||||
static int vmSprite_GetShow(int sprite)
|
||||
{
|
||||
struct vm_sprite *sp = id_pool_get(&pool, sprite);
|
||||
return sp ? scene_get_sprite_show(&sp->sp) : 0;
|
||||
}
|
||||
|
||||
//int vmSprite_GetRenewal(int sprite);
|
||||
|
||||
static int vmSprite_GetFind(int sprite)
|
||||
{
|
||||
struct vm_sprite *sp = id_pool_get(&pool, sprite);
|
||||
return sp ? sp->findable : 0;
|
||||
}
|
||||
|
||||
static int vmSprite_GetID(int sprite)
|
||||
{
|
||||
struct vm_sprite *sp = id_pool_get(&pool, sprite);
|
||||
return sp ? sp->id : -1;
|
||||
}
|
||||
|
||||
HLL_LIBRARY(vmSprite,
|
||||
HLL_EXPORT(_ModuleFini, vmSprite_ModuleFini),
|
||||
HLL_EXPORT(New, vmSprite_New),
|
||||
HLL_EXPORT(Release, vmSprite_Release),
|
||||
HLL_EXPORT(EnumHandle, vmSprite_EnumHandle),
|
||||
HLL_EXPORT(Open, vmSprite_Open),
|
||||
HLL_EXPORT(Reopen, vmSprite_Reopen),
|
||||
HLL_EXPORT(Close, vmSprite_Close),
|
||||
HLL_EXPORT(SetLayer, vmSprite_SetLayer),
|
||||
HLL_EXPORT(SetPos, vmSprite_SetPos),
|
||||
HLL_EXPORT(SetCurrent, vmSprite_SetCurrent),
|
||||
HLL_EXPORT(SetCurrentArray1, vmSprite_SetCurrentArray1),
|
||||
HLL_EXPORT(SetCurrentArray2, vmSprite_SetCurrentArray2),
|
||||
HLL_EXPORT(SetShow, vmSprite_SetShow),
|
||||
HLL_EXPORT(SetShowArray1, vmSprite_SetShowArray1),
|
||||
HLL_EXPORT(SetShowArray2, vmSprite_SetShowArray2),
|
||||
HLL_EXPORT(SetRenewal, vmSprite_SetRenewal),
|
||||
HLL_EXPORT(SetFind, vmSprite_SetFind),
|
||||
HLL_EXPORT(SetID, vmSprite_SetID),
|
||||
HLL_EXPORT(SetAnime, vmSprite_SetAnime),
|
||||
HLL_EXPORT(ResetAnime, vmSprite_ResetAnime),
|
||||
HLL_EXPORT(SetChildSurface, vmSprite_SetChildSurface),
|
||||
HLL_EXPORT(ResetChildSurface, vmSprite_ResetChildSurface),
|
||||
HLL_EXPORT(Draw, vmSprite_Draw),
|
||||
HLL_EXPORT(DrawEffect, vmSprite_DrawEffect),
|
||||
HLL_EXPORT(AddRect, vmSprite_AddRect),
|
||||
HLL_TODO_EXPORT(SetSurface, vmSprite_SetSurface),
|
||||
HLL_EXPORT(FindPos, vmSprite_FindPos),
|
||||
HLL_TODO_EXPORT(FindSprite, vmSprite_FindSprite),
|
||||
HLL_EXPORT(GetSurface, vmSprite_GetSurface),
|
||||
HLL_EXPORT(GetType, vmSprite_GetType),
|
||||
HLL_EXPORT(GetWidth, vmSprite_GetWidth),
|
||||
HLL_EXPORT(GetHeight, vmSprite_GetHeight),
|
||||
HLL_EXPORT(GetLayer, vmSprite_GetLayer),
|
||||
HLL_EXPORT(GetX, vmSprite_GetX),
|
||||
HLL_EXPORT(GetY, vmSprite_GetY),
|
||||
HLL_EXPORT(GetCurrent, vmSprite_GetCurrent),
|
||||
HLL_EXPORT(GetShow, vmSprite_GetShow),
|
||||
HLL_TODO_EXPORT(GetRenewal, vmSprite_GetRenewal),
|
||||
HLL_EXPORT(GetFind, vmSprite_GetFind),
|
||||
HLL_EXPORT(GetID, vmSprite_GetID)
|
||||
);
|
||||
@@ -0,0 +1,88 @@
|
||||
/* Copyright (C) 2024 kichikuou <KichikuouChrome@gmail.com>
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "system4/string.h"
|
||||
#include "system4/utfsjis.h"
|
||||
|
||||
#include "hll.h"
|
||||
|
||||
static int vmString_GetLength(struct string *string)
|
||||
{
|
||||
return sjis_count_char(string->text);
|
||||
}
|
||||
|
||||
static int vmString_GetLengthA(struct string *string)
|
||||
{
|
||||
return strlen(string->text);
|
||||
}
|
||||
|
||||
static struct string *format_int(int v, int figures, bool zero_pad, bool zenkaku)
|
||||
{
|
||||
char buf[32];
|
||||
int_to_cstr(buf, sizeof(buf), v, figures, zero_pad, zenkaku);
|
||||
return cstr_to_string(buf);
|
||||
}
|
||||
|
||||
static struct string *vmString_IntToString(int num)
|
||||
{
|
||||
return format_int(num, 0, false, true);
|
||||
}
|
||||
|
||||
struct string *vmString_IntToStringA(int num)
|
||||
{
|
||||
return format_int(num, 0, false, false);
|
||||
}
|
||||
|
||||
static struct string *vmString_IntToStringEx(int num, int figure, int zero)
|
||||
{
|
||||
return format_int(num, figure, zero, true);
|
||||
}
|
||||
|
||||
static struct string *vmString_IntToStringExA(int num, int figure, int zero)
|
||||
{
|
||||
return format_int(num, figure, zero, false);
|
||||
}
|
||||
|
||||
//int vmString_StringToInt(struct string *pIString);
|
||||
//struct string *vmString_FloatToString(float fNum);
|
||||
//struct string *vmString_FloatToStringA(float fNum);
|
||||
//float vmString_StringToFloat(struct string *pIString);
|
||||
//struct string *vmString_GetString(struct string *pIString, int nIndex, int nLength);
|
||||
//struct string *vmString_CutTag(struct string *pIString);
|
||||
//void vmString_TransLower(struct string **pIString);
|
||||
//void vmString_TransUpper(struct string **pIString);
|
||||
//void vmString_Convert(struct string **pIDString, struct string *pISString, struct string *pICString);
|
||||
|
||||
HLL_LIBRARY(vmString,
|
||||
HLL_EXPORT(GetLength, vmString_GetLength),
|
||||
HLL_EXPORT(GetLengthA, vmString_GetLengthA),
|
||||
HLL_EXPORT(IntToString, vmString_IntToString),
|
||||
HLL_EXPORT(IntToStringA, vmString_IntToStringA),
|
||||
HLL_EXPORT(IntToStringEx, vmString_IntToStringEx),
|
||||
HLL_EXPORT(IntToStringExA, vmString_IntToStringExA),
|
||||
HLL_TODO_EXPORT(StringToInt, vmString_StringToInt),
|
||||
HLL_TODO_EXPORT(FloatToString, vmString_FloatToString),
|
||||
HLL_TODO_EXPORT(FloatToStringA, vmString_FloatToStringA),
|
||||
HLL_TODO_EXPORT(StringToFloat, vmString_StringToFloat),
|
||||
HLL_TODO_EXPORT(GetString, vmString_GetString),
|
||||
HLL_TODO_EXPORT(CutTag, vmString_CutTag),
|
||||
HLL_TODO_EXPORT(TransLower, vmString_TransLower),
|
||||
HLL_TODO_EXPORT(TransUpper, vmString_TransUpper),
|
||||
HLL_TODO_EXPORT(Convert, vmString_Convert)
|
||||
);
|
||||
@@ -0,0 +1,152 @@
|
||||
/* Copyright (C) 2024 kichikuou <KichikuouChrome@gmail.com>
|
||||
*
|
||||
* 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 <assert.h>
|
||||
|
||||
#include "hll.h"
|
||||
#include "id_pool.h"
|
||||
#include "vmSurface.h"
|
||||
|
||||
static struct id_pool pool;
|
||||
|
||||
struct vm_surface *vm_surface_create(int width, int height)
|
||||
{
|
||||
int no = id_pool_get_unused(&pool);
|
||||
struct vm_surface *sf = xcalloc(1, sizeof(struct vm_surface));
|
||||
id_pool_set(&pool, no, sf);
|
||||
sf->w = width;
|
||||
sf->h = height;
|
||||
sf->has_pixel = true;
|
||||
sf->has_alpha = true;
|
||||
sf->no = no;
|
||||
return sf;
|
||||
}
|
||||
|
||||
struct vm_surface *vm_surface_get(int no)
|
||||
{
|
||||
return id_pool_get(&pool, no);
|
||||
}
|
||||
|
||||
void vm_surface_delete(int no)
|
||||
{
|
||||
struct vm_surface *sf = id_pool_release(&pool, no);
|
||||
if (sf) {
|
||||
gfx_delete_texture(&sf->texture);
|
||||
free(sf);
|
||||
}
|
||||
}
|
||||
|
||||
int vm_surface_get_main_surface(void)
|
||||
{
|
||||
return ID_POOL_HANDLE_BASE;
|
||||
}
|
||||
|
||||
static void vmSurface_New(void)
|
||||
{
|
||||
if (pool.slots)
|
||||
return; // already initialized
|
||||
gfx_init();
|
||||
id_pool_init(&pool, ID_POOL_HANDLE_BASE);
|
||||
|
||||
// create main surface
|
||||
Texture *t = gfx_main_surface();
|
||||
struct vm_surface *sf = vm_surface_create(t->w, t->h);
|
||||
sf->texture = *t; // XXX: textures normally shouldn't be copied like this...
|
||||
assert(sf->no == ID_POOL_HANDLE_BASE);
|
||||
}
|
||||
|
||||
static int vmSurface_Release(void)
|
||||
{
|
||||
for (int i = id_pool_get_first(&pool); i >= 0; i = id_pool_get_next(&pool, i))
|
||||
vm_surface_delete(i);
|
||||
id_pool_delete(&pool);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void vmSurface_ModuleFini(void)
|
||||
{
|
||||
vmSurface_Release();
|
||||
}
|
||||
|
||||
static int vmSurface_EnumHandle(void)
|
||||
{
|
||||
return id_pool_count(&pool);
|
||||
}
|
||||
|
||||
static int vmSurface_Create(int width, int height, possibly_unused int bpp)
|
||||
{
|
||||
struct vm_surface *sf = vm_surface_create(width, height);
|
||||
gfx_init_texture_rgba(&sf->texture, sf->w, sf->h, (SDL_Color){0, 0, 0, 0});
|
||||
return sf->no;
|
||||
}
|
||||
|
||||
static int vmSurface_CreatePixelMap(int width, int height, possibly_unused int bpp)
|
||||
{
|
||||
struct vm_surface *sf = vm_surface_create(width, height);
|
||||
gfx_init_texture_rgba(&sf->texture, sf->w, sf->h, (SDL_Color){0, 0, 0, 255});
|
||||
sf->has_alpha = false;
|
||||
return sf->no;
|
||||
}
|
||||
|
||||
static int vmSurface_CreateAlphaMap(int width, int height)
|
||||
{
|
||||
struct vm_surface *sf = vm_surface_create(width, height);
|
||||
gfx_init_texture_rgba(&sf->texture, sf->w, sf->h, (SDL_Color){0, 0, 0, 255});
|
||||
sf->has_pixel = false;
|
||||
return sf->no;
|
||||
}
|
||||
|
||||
static int vmSurface_GetWidth(int surface)
|
||||
{
|
||||
struct vm_surface *sf = id_pool_get(&pool, surface);
|
||||
return sf ? sf->w : 0;
|
||||
}
|
||||
|
||||
static int vmSurface_GetHeight(int surface)
|
||||
{
|
||||
struct vm_surface *sf = id_pool_get(&pool, surface);
|
||||
return sf ? sf->h : 0;
|
||||
}
|
||||
|
||||
//int vmSurface_GetBpp(int surface);
|
||||
|
||||
static int vmSurface_ExistPixel(int surface)
|
||||
{
|
||||
struct vm_surface *sf = id_pool_get(&pool, surface);
|
||||
return sf && sf->has_pixel;
|
||||
}
|
||||
|
||||
static int vmSurface_ExistAlpha(int surface)
|
||||
{
|
||||
struct vm_surface *sf = id_pool_get(&pool, surface);
|
||||
return sf && sf->has_alpha;
|
||||
}
|
||||
|
||||
HLL_LIBRARY(vmSurface,
|
||||
HLL_EXPORT(_ModuleFini, vmSurface_ModuleFini),
|
||||
HLL_EXPORT(New, vmSurface_New),
|
||||
HLL_EXPORT(Release, vmSurface_Release),
|
||||
HLL_EXPORT(EnumHandle, vmSurface_EnumHandle),
|
||||
HLL_EXPORT(Create, vmSurface_Create),
|
||||
HLL_EXPORT(CreatePixelMap, vmSurface_CreatePixelMap),
|
||||
HLL_EXPORT(CreateAlphaMap, vmSurface_CreateAlphaMap),
|
||||
HLL_EXPORT(Delete, vm_surface_delete),
|
||||
HLL_EXPORT(GetWidth, vmSurface_GetWidth),
|
||||
HLL_EXPORT(GetHeight, vmSurface_GetHeight),
|
||||
HLL_TODO_EXPORT(GetBpp, vmSurface_GetBpp),
|
||||
HLL_EXPORT(ExistPixel, vmSurface_ExistPixel),
|
||||
HLL_EXPORT(ExistAlpha, vmSurface_ExistAlpha)
|
||||
);
|
||||
@@ -0,0 +1,37 @@
|
||||
/* Copyright (C) 2024 kichikuou <KichikuouChrome@gmail.com>
|
||||
*
|
||||
* 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_VMSURFACE_H
|
||||
#define SYSTEM4_HLL_VMSURFACE_H
|
||||
|
||||
#include "gfx/gfx.h"
|
||||
|
||||
struct vm_surface {
|
||||
struct texture texture;
|
||||
int no;
|
||||
int w;
|
||||
int h;
|
||||
bool has_pixel;
|
||||
bool has_alpha;
|
||||
int cg_no;
|
||||
};
|
||||
|
||||
struct vm_surface *vm_surface_create(int width, int height);
|
||||
struct vm_surface *vm_surface_get(int no);
|
||||
void vm_surface_delete(int no);
|
||||
int vm_surface_get_main_surface(void);
|
||||
|
||||
#endif /* SYSTEM4_HLL_VMSURFACE_H */
|
||||
@@ -0,0 +1,69 @@
|
||||
/* Copyright (C) 2024 kichikuou <KichikuouChrome@gmail.com>
|
||||
*
|
||||
* 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 <errno.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <SDL.h>
|
||||
|
||||
#include "system4/string.h"
|
||||
|
||||
#include "hll.h"
|
||||
#include "vm/page.h"
|
||||
|
||||
HLL_QUIET_UNIMPLEMENTED( , void, vmSystem, Init, void *imainsystem);
|
||||
|
||||
void vmSystem_CurrentTime(struct page **page)
|
||||
{
|
||||
struct timespec ts;
|
||||
if (clock_gettime(CLOCK_REALTIME, &ts) < 0) {
|
||||
WARNING("clock_gettime failed: %s", strerror(errno));
|
||||
return;
|
||||
}
|
||||
struct tm *tm = localtime(&ts.tv_sec);
|
||||
if (!tm) {
|
||||
WARNING("localtime failed: %s", strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
union vm_value *date = (*page)->values;
|
||||
date[0].i = tm->tm_year + 1900;
|
||||
date[1].i = tm->tm_mon + 1;
|
||||
date[2].i = tm->tm_mday;
|
||||
date[3].i = tm->tm_hour;
|
||||
date[4].i = tm->tm_min;
|
||||
date[5].i = tm->tm_sec;
|
||||
date[6].i = tm->tm_wday;
|
||||
}
|
||||
|
||||
//void vmSystem_Reset(void);
|
||||
//void vmSystem_Shutdown(void);
|
||||
|
||||
static int vmSystem_OpenWeb(struct string *url)
|
||||
{
|
||||
return SDL_OpenURL(url->text) == 0;
|
||||
}
|
||||
|
||||
HLL_WARN_UNIMPLEMENTED(0, int, vmSystem, AddURLMenu, struct string *title, struct string *url);
|
||||
|
||||
HLL_LIBRARY(vmSystem,
|
||||
HLL_EXPORT(Init, vmSystem_Init),
|
||||
HLL_EXPORT(CurrentTime, vmSystem_CurrentTime),
|
||||
HLL_TODO_EXPORT(Reset, vmSystem_Reset),
|
||||
HLL_TODO_EXPORT(Shutdown, vmSystem_Shutdown),
|
||||
HLL_EXPORT(OpenWeb, vmSystem_OpenWeb),
|
||||
HLL_EXPORT(AddURLMenu, vmSystem_AddURLMenu)
|
||||
);
|
||||
@@ -0,0 +1,103 @@
|
||||
/* Copyright (C) 2024 kichikuou <KichikuouChrome@gmail.com>
|
||||
*
|
||||
* 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 <SDL.h>
|
||||
|
||||
#include "hll.h"
|
||||
#include "id_pool.h"
|
||||
|
||||
struct vm_timer {
|
||||
uint64_t origin;
|
||||
};
|
||||
|
||||
static struct id_pool pool;
|
||||
|
||||
static void vmTimer_Init(possibly_unused void *imainsystem)
|
||||
{
|
||||
if (pool.slots)
|
||||
return; // already initialized
|
||||
id_pool_init(&pool, ID_POOL_HANDLE_BASE);
|
||||
}
|
||||
|
||||
static int vmTimer_EnumHandle(void)
|
||||
{
|
||||
return id_pool_count(&pool);
|
||||
}
|
||||
|
||||
static int vmTimer_Open(void)
|
||||
{
|
||||
int handle = id_pool_get_unused(&pool);
|
||||
struct vm_timer *timer = xcalloc(1, sizeof(struct vm_timer));
|
||||
id_pool_set(&pool, handle, timer);
|
||||
return handle;
|
||||
}
|
||||
|
||||
static void vmTimer_Close(int handle)
|
||||
{
|
||||
struct vm_timer *timer = id_pool_release(&pool, handle);
|
||||
if (timer)
|
||||
free(timer);
|
||||
}
|
||||
|
||||
static void vmTimer_ModuleFini(void)
|
||||
{
|
||||
for (int i = id_pool_get_first(&pool); i >= 0; i = id_pool_get_next(&pool, i))
|
||||
vmTimer_Close(i);
|
||||
id_pool_delete(&pool);
|
||||
}
|
||||
|
||||
static void vmTimer_Set(int handle, int time)
|
||||
{
|
||||
struct vm_timer *timer = id_pool_get(&pool, handle);
|
||||
if (!timer)
|
||||
return;
|
||||
timer->origin = SDL_GetTicks64() - time;
|
||||
}
|
||||
|
||||
static int vmTimer_Get(int handle)
|
||||
{
|
||||
struct vm_timer *timer = id_pool_get(&pool, handle);
|
||||
if (!timer)
|
||||
return 0;
|
||||
return SDL_GetTicks64() - timer->origin;
|
||||
}
|
||||
|
||||
static void vmTimer_Wait(int time)
|
||||
{
|
||||
SDL_Delay(time);
|
||||
}
|
||||
|
||||
static void vmTimer_Pass(int handle, int time)
|
||||
{
|
||||
struct vm_timer *timer = id_pool_get(&pool, handle);
|
||||
if (!timer)
|
||||
return;
|
||||
int ms = timer->origin + time - SDL_GetTicks64();
|
||||
if (ms > 0)
|
||||
SDL_Delay(ms);
|
||||
}
|
||||
|
||||
HLL_LIBRARY(vmTimer,
|
||||
HLL_EXPORT(_ModuleFini, vmTimer_ModuleFini),
|
||||
HLL_EXPORT(Init, vmTimer_Init),
|
||||
HLL_EXPORT(EnumHandle, vmTimer_EnumHandle),
|
||||
HLL_EXPORT(Open, vmTimer_Open),
|
||||
HLL_EXPORT(Close, vmTimer_Close),
|
||||
HLL_EXPORT(Set, vmTimer_Set),
|
||||
HLL_EXPORT(Get, vmTimer_Get),
|
||||
HLL_EXPORT(Wait, vmTimer_Wait),
|
||||
HLL_EXPORT(Pass, vmTimer_Pass)
|
||||
);
|
||||
+50
-6
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "system4.h"
|
||||
#include "id_pool.h"
|
||||
@@ -26,10 +27,18 @@
|
||||
#define ID_POOL_INIT_SLOTS 32
|
||||
#define ID_POOL_ALLOC_HEADROOM 256
|
||||
|
||||
void id_pool_init(struct id_pool *pool)
|
||||
void id_pool_init(struct id_pool *pool, int base)
|
||||
{
|
||||
pool->slots = xcalloc(ID_POOL_INIT_SLOTS, sizeof(void*));
|
||||
pool->nr_slots = ID_POOL_INIT_SLOTS;
|
||||
pool->base = base;
|
||||
}
|
||||
|
||||
void id_pool_delete(struct id_pool *pool)
|
||||
{
|
||||
free(pool->slots);
|
||||
pool->slots = NULL;
|
||||
pool->nr_slots = 0;
|
||||
}
|
||||
|
||||
static void id_pool_realloc(struct id_pool *pool, int new_size)
|
||||
@@ -38,26 +47,60 @@ static void id_pool_realloc(struct id_pool *pool, int new_size)
|
||||
pool->nr_slots = new_size;
|
||||
}
|
||||
|
||||
void id_pool_release(struct id_pool *pool, int id)
|
||||
void *id_pool_release(struct id_pool *pool, int id)
|
||||
{
|
||||
if (pool->slots[id])
|
||||
pool->slots[id] = NULL;
|
||||
id -= pool->base;
|
||||
if (id < 0 || id >= pool->nr_slots)
|
||||
return NULL;
|
||||
void *data = pool->slots[id];
|
||||
pool->slots[id] = NULL;
|
||||
return data;
|
||||
}
|
||||
|
||||
int id_pool_count(struct id_pool *pool)
|
||||
{
|
||||
int count = 0;
|
||||
for (int i = 0; i < pool->nr_slots; i++) {
|
||||
if (pool->slots[i])
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
int id_pool_get_unused(struct id_pool *pool)
|
||||
{
|
||||
for (int i = 0; i < pool->nr_slots; i++) {
|
||||
if (!pool->slots[i])
|
||||
return i;
|
||||
return pool->base + i;
|
||||
}
|
||||
|
||||
int id = pool->nr_slots;
|
||||
id_pool_realloc(pool, id + ID_POOL_ALLOC_HEADROOM);
|
||||
return id;
|
||||
return pool->base + id;
|
||||
}
|
||||
|
||||
int id_pool_get_first(struct id_pool *pool)
|
||||
{
|
||||
for (int i = 0; i < pool->nr_slots; i++) {
|
||||
if (pool->slots[i])
|
||||
return pool->base + i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int id_pool_get_next(struct id_pool *pool, int id)
|
||||
{
|
||||
id -= pool->base;
|
||||
for (int i = id + 1; i < pool->nr_slots; i++) {
|
||||
if (pool->slots[i])
|
||||
return pool->base + i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void *id_pool_get(struct id_pool *pool, int id)
|
||||
{
|
||||
id -= pool->base;
|
||||
if (id < 0 || id >= pool->nr_slots)
|
||||
return NULL;
|
||||
return pool->slots[id];
|
||||
@@ -65,6 +108,7 @@ void *id_pool_get(struct id_pool *pool, int id)
|
||||
|
||||
void *id_pool_set(struct id_pool *pool, int id, void *data)
|
||||
{
|
||||
id -= pool->base;
|
||||
assert(id >= 0);
|
||||
if (id >= pool->nr_slots)
|
||||
id_pool_realloc(pool, id + ID_POOL_ALLOC_HEADROOM);
|
||||
|
||||
@@ -103,6 +103,8 @@ xsystem4 = [version_h,
|
||||
'hll/LoadCG.c',
|
||||
'hll/MainEXFile.c',
|
||||
'hll/MainSurface.c',
|
||||
'hll/MamanyoDemo.c',
|
||||
'hll/MamanyoSDemo.c',
|
||||
'hll/MarmotModelEngine.c',
|
||||
'hll/Math.c',
|
||||
'hll/MapLoader.c',
|
||||
@@ -127,6 +129,29 @@ xsystem4 = [version_h,
|
||||
'hll/SystemServiceEx.c',
|
||||
'hll/Timer.c',
|
||||
'hll/Toushin3Loader.c',
|
||||
'hll/vmAnime.c',
|
||||
'hll/vmArray.c',
|
||||
'hll/vmCG.c',
|
||||
'hll/vmChrLoader.c',
|
||||
'hll/vmCursor.c',
|
||||
'hll/vmDialog.c',
|
||||
'hll/vmDrawGauge.c',
|
||||
'hll/vmDrawMsg.c',
|
||||
'hll/vmDrawNumber.c',
|
||||
'hll/vmFile.c',
|
||||
'hll/vmGraph.c',
|
||||
'hll/vmGraphQuake.c',
|
||||
'hll/vmKey.c',
|
||||
'hll/vmMapLoader.c',
|
||||
'hll/vmMsgLog.c',
|
||||
'hll/vmMsgSkip.c',
|
||||
'hll/vmMusic.c',
|
||||
'hll/vmSound.c',
|
||||
'hll/vmSprite.c',
|
||||
'hll/vmString.c',
|
||||
'hll/vmSurface.c',
|
||||
'hll/vmSystem.c',
|
||||
'hll/vmTimer.c',
|
||||
'hll/VSFile.c',
|
||||
]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user