mirror of
https://github.com/nunuhara/xsystem4.git
synced 2026-09-22 23:18:01 +03:00
Merge pull request #304 from kichikuou/pascha3-hll
Implement HLLs for Pastel Chime 3
This commit is contained in:
@@ -156,6 +156,7 @@ target_sources(xsystem4 PRIVATE
|
||||
src/hll/InputString.c
|
||||
src/hll/KiwiSoundEngine.c
|
||||
src/hll/LoadCG.c
|
||||
src/hll/MADLoader.c
|
||||
src/hll/MainEXFile.c
|
||||
src/hll/MainSurface.c
|
||||
src/hll/MamanyoDemo.c
|
||||
@@ -171,6 +172,8 @@ target_sources(xsystem4 PRIVATE
|
||||
src/hll/MusicSystem.c
|
||||
src/hll/NewFont.c
|
||||
src/hll/OutputLog.c
|
||||
src/hll/P3MapSprite.c
|
||||
src/hll/P3SquareSprite.c
|
||||
src/hll/PassRegister.c
|
||||
src/hll/PastelChime2.c
|
||||
src/hll/PartsEngine.c
|
||||
|
||||
@@ -184,6 +184,8 @@ void gfx_copy_with_alpha_map(Texture *dst, int dx, int dy, Texture *src, int sx,
|
||||
void gfx_fill_with_alpha(Texture *dst, int x, int y, int w, int h, int r, int g, int b, int a);
|
||||
void gfx_copy_stretch_with_alpha_map(Texture *dst, int dx, int dy, int dw, int dh, Texture *src, int sx, int sy, int sw, int sh);
|
||||
void gfx_copy_grayscale(Texture *dst, int dx, int dy, Texture *src, int sx, int sy, int w, int h);
|
||||
void gfx_copy_grayscale_with_alpha_map(Texture *dst, int dx, int dy, Texture *src, int sx, int sy, int w, int h);
|
||||
void gfx_copy_grayscale_reverse_LR_with_alpha_map(Texture *dst, int dx, int dy, Texture *src, int sx, int sy, int w, int h);
|
||||
void gfx_draw_line(Texture *dst, int x0, int y0, int x1, int y1, int r, int g, int b);
|
||||
void gfx_draw_line_to_amap(Texture *dst, int x0, int y0, int x1, int y1, int a);
|
||||
void gfx_draw_glyph(Texture *dst, float dx, int dy, Texture *glyph, SDL_Color color, float scale_x, float bold_width, bool blend);
|
||||
|
||||
@@ -20,6 +20,7 @@ in vec2 tex_coord;
|
||||
out vec4 frag_color;
|
||||
|
||||
void main() {
|
||||
float gray = dot(texture(tex, tex_coord).rgb, vec3(0.299, 0.587, 0.114));
|
||||
frag_color = vec4(vec3(gray), 1);
|
||||
vec4 texel = texture(tex, tex_coord);
|
||||
float gray = dot(texel.rgb, vec3(0.299, 0.587, 0.114));
|
||||
frag_color = vec4(vec3(gray), texel.a);
|
||||
}
|
||||
|
||||
+27
@@ -1094,6 +1094,33 @@ void gfx_copy_grayscale(Texture *dst, int dx, int dy, Texture *src, int sx, int
|
||||
restore_blend_mode();
|
||||
}
|
||||
|
||||
void gfx_copy_grayscale_with_alpha_map(Texture *dst, int dx, int dy, Texture *src, int sx, int sy, int w, int h)
|
||||
{
|
||||
glBlendFuncSeparate(GL_ONE, GL_ZERO, GL_ONE, GL_ZERO);
|
||||
|
||||
struct copy_data data = COPY_DATA(dx, dy, sx, sy, w, h);
|
||||
run_copy_shader(©_grayscale_shader.s, dst, src, &data);
|
||||
|
||||
restore_blend_mode();
|
||||
}
|
||||
|
||||
void gfx_copy_grayscale_reverse_LR_with_alpha_map(Texture *dst, int dx, int dy, Texture *src, int sx, int sy, int w, int h)
|
||||
{
|
||||
mat4 mw_transform = MAT4(
|
||||
-src->w, 0, 0, sx + w,
|
||||
0, src->h, 0, -sy,
|
||||
0, 0, 1, 0,
|
||||
0, 0, 0, 1);
|
||||
mat4 wv_transform = WV_TRANSFORM(w, h);
|
||||
|
||||
glBlendFuncSeparate(GL_ONE, GL_ZERO, GL_ONE, GL_ZERO);
|
||||
|
||||
struct copy_data data = COPY_DATA(dx, dy, sx, sy, w, h);
|
||||
run_draw_shader(©_grayscale_shader.s, dst, src, mw_transform, wv_transform, &data);
|
||||
|
||||
restore_blend_mode();
|
||||
}
|
||||
|
||||
static void draw_line(Texture *dst, int x0, int y0, int x1, int y1, struct copy_data *data)
|
||||
{
|
||||
GLfloat w = dst->w;
|
||||
|
||||
@@ -469,6 +469,7 @@ extern struct static_library lib_InputDevice;
|
||||
extern struct static_library lib_InputString;
|
||||
extern struct static_library lib_KiwiSoundEngine;
|
||||
extern struct static_library lib_LoadCG;
|
||||
extern struct static_library lib_MADLoader;
|
||||
extern struct static_library lib_MainEXFile;
|
||||
extern struct static_library lib_MainSurface;
|
||||
extern struct static_library lib_MamanyoDemo;
|
||||
@@ -484,6 +485,8 @@ extern struct static_library lib_MsgSkip;
|
||||
extern struct static_library lib_MusicSystem;
|
||||
extern struct static_library lib_NewFont;
|
||||
extern struct static_library lib_OutputLog;
|
||||
extern struct static_library lib_P3MapSprite;
|
||||
extern struct static_library lib_P3SquareSprite;
|
||||
extern struct static_library lib_PassRegister;
|
||||
extern struct static_library lib_PastelChime2;
|
||||
extern struct static_library lib_PartsEngine;
|
||||
@@ -587,6 +590,7 @@ static struct static_library *static_libraries[] = {
|
||||
&lib_InputString,
|
||||
&lib_KiwiSoundEngine,
|
||||
&lib_LoadCG,
|
||||
&lib_MADLoader,
|
||||
&lib_MainEXFile,
|
||||
&lib_MainSurface,
|
||||
&lib_MamanyoDemo,
|
||||
@@ -602,6 +606,8 @@ static struct static_library *static_libraries[] = {
|
||||
&lib_MusicSystem,
|
||||
&lib_NewFont,
|
||||
&lib_OutputLog,
|
||||
&lib_P3MapSprite,
|
||||
&lib_P3SquareSprite,
|
||||
&lib_PassRegister,
|
||||
&lib_PastelChime2,
|
||||
&lib_PartsEngine,
|
||||
|
||||
@@ -0,0 +1,336 @@
|
||||
/* Copyright (C) 2026 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/little_endian.h"
|
||||
#include "system4/file.h"
|
||||
#include "system4/string.h"
|
||||
#include "system4/cg.h"
|
||||
|
||||
#include "hll.h"
|
||||
#include "id_pool.h"
|
||||
#include "xsystem4.h"
|
||||
#include "gfx/gfx.h"
|
||||
#include "sact.h"
|
||||
|
||||
// A MAD file consists of this header, followed by `nr_images` QNT images, each
|
||||
// prefixed with its size.
|
||||
struct MADHeader {
|
||||
char magic[4]; // "MAD\0"
|
||||
unsigned char unknown1[8];
|
||||
int width;
|
||||
int height;
|
||||
int total_time;
|
||||
int nr_images;
|
||||
int draw_method;
|
||||
int is_loop;
|
||||
unsigned char unknown2[8];
|
||||
int keep_last_frame;
|
||||
};
|
||||
|
||||
struct MAD {
|
||||
struct MADHeader header;
|
||||
Texture textures[];
|
||||
};
|
||||
|
||||
static struct id_pool pool;
|
||||
|
||||
static void MADLoader_ModuleInit(void)
|
||||
{
|
||||
id_pool_init(&pool, 0);
|
||||
}
|
||||
|
||||
static void MADLoader_Close(int handle)
|
||||
{
|
||||
struct MAD *mad = id_pool_release(&pool, handle);
|
||||
if (!mad)
|
||||
return;
|
||||
for (int i = 0; i < mad->header.nr_images; i++) {
|
||||
if (mad->textures[i].handle)
|
||||
gfx_delete_texture(&mad->textures[i]);
|
||||
}
|
||||
free(mad);
|
||||
}
|
||||
|
||||
static void MADLoader_Delete(void)
|
||||
{
|
||||
for (int i = id_pool_get_first(&pool); i >= 0; i = id_pool_get_next(&pool, i))
|
||||
MADLoader_Close(i);
|
||||
}
|
||||
|
||||
static void MADLoader_ModuleFini(void)
|
||||
{
|
||||
MADLoader_Delete();
|
||||
id_pool_delete(&pool);
|
||||
}
|
||||
|
||||
static FILE *mad_open(struct string *filename, struct MADHeader *header)
|
||||
{
|
||||
char *path = gamedir_path(filename->text);
|
||||
FILE *fp = file_open_utf8(path, "rb");
|
||||
free(path);
|
||||
if (!fp)
|
||||
return NULL;
|
||||
|
||||
uint8_t buf[48];
|
||||
if (fread(buf, sizeof buf, 1, fp) != 1 || memcmp(buf, "MAD", 4)) {
|
||||
fclose(fp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy(header->magic, buf, 4);
|
||||
memcpy(header->unknown1, buf + 4, 8);
|
||||
header->width = LittleEndian_getDW(buf, 12);
|
||||
header->height = LittleEndian_getDW(buf, 16);
|
||||
header->total_time = LittleEndian_getDW(buf, 20);
|
||||
header->nr_images = LittleEndian_getDW(buf, 24);
|
||||
header->draw_method = LittleEndian_getDW(buf, 28);
|
||||
header->is_loop = LittleEndian_getDW(buf, 32);
|
||||
memcpy(header->unknown2, buf + 36, 8);
|
||||
header->keep_last_frame = LittleEndian_getDW(buf, 44);
|
||||
|
||||
return fp;
|
||||
}
|
||||
|
||||
static bool mad_read_header(struct string *filename, struct MADHeader *header)
|
||||
{
|
||||
FILE *fp = mad_open(filename, header);
|
||||
fclose(fp);
|
||||
return fp != NULL;
|
||||
}
|
||||
|
||||
static int MADLoader_Open(struct string *filename)
|
||||
{
|
||||
struct MADHeader header;
|
||||
FILE *fp = mad_open(filename, &header);
|
||||
if (!fp)
|
||||
return -1;
|
||||
|
||||
struct MAD *mad = xcalloc(1, sizeof(struct MAD) + header.nr_images * sizeof(Texture));
|
||||
mad->header = header;
|
||||
for (int i = 0; i < mad->header.nr_images; i++) {
|
||||
uint8_t buf[4];
|
||||
if (fread(buf, 4, 1, fp) != 1)
|
||||
VM_ERROR("MADLoader: failed to read image size %d of %s", i, display_sjis0(filename->text));
|
||||
uint32_t image_size = LittleEndian_getDW(buf, 0);
|
||||
uint8_t *image_data = xmalloc(image_size);
|
||||
if (fread(image_data, image_size, 1, fp) != 1)
|
||||
VM_ERROR("MADLoader: failed to read image data %d of %s", i, display_sjis0(filename->text));
|
||||
struct cg *cg = cg_load_buffer(image_data, image_size);
|
||||
if (!cg)
|
||||
VM_ERROR("MADLoader: failed to load cg %d of %s", i, display_sjis0(filename->text));
|
||||
gfx_init_texture_with_cg(&mad->textures[i], cg);
|
||||
cg_free(cg);
|
||||
free(image_data);
|
||||
}
|
||||
fclose(fp);
|
||||
|
||||
int handle = id_pool_get_unused(&pool);
|
||||
id_pool_set(&pool, handle, mad);
|
||||
return handle;
|
||||
}
|
||||
|
||||
static bool MADLoader_GetSize(int handle, int *width, int *height)
|
||||
{
|
||||
struct MAD *mad = id_pool_get(&pool, handle);
|
||||
if (!mad)
|
||||
return false;
|
||||
*width = mad->header.width;
|
||||
*height = mad->header.height;
|
||||
return true;
|
||||
}
|
||||
|
||||
static int MADLoader_GetNumof(int handle)
|
||||
{
|
||||
struct MAD *mad = id_pool_get(&pool, handle);
|
||||
return mad ? mad->header.nr_images : -1;
|
||||
}
|
||||
|
||||
static int MADLoader_GetTotalTime(int handle)
|
||||
{
|
||||
struct MAD *mad = id_pool_get(&pool, handle);
|
||||
return mad ? mad->header.total_time : -1;
|
||||
}
|
||||
|
||||
static int MADLoader_GetDrawMethod(int handle)
|
||||
{
|
||||
struct MAD *mad = id_pool_get(&pool, handle);
|
||||
return mad ? mad->header.draw_method : -1;
|
||||
}
|
||||
|
||||
static bool MADLoader_IsLoop(int handle)
|
||||
{
|
||||
struct MAD *mad = id_pool_get(&pool, handle);
|
||||
return mad && mad->header.is_loop == 1;
|
||||
}
|
||||
|
||||
static bool MADLoader_IsKeepLastFrame(int handle)
|
||||
{
|
||||
struct MAD *mad = id_pool_get(&pool, handle);
|
||||
return mad && mad->header.keep_last_frame == 1;
|
||||
}
|
||||
|
||||
static bool MADLoader_IsLoading(int handle)
|
||||
{
|
||||
// We don't support background loading.
|
||||
return false;
|
||||
}
|
||||
|
||||
static int MADLoader_GetLoadNumof(int handle)
|
||||
{
|
||||
struct MAD *mad = id_pool_get(&pool, handle);
|
||||
return mad ? mad->header.nr_images : 0;
|
||||
}
|
||||
|
||||
static bool MADLoader_GetSizeFromFile(struct string *filename, int *width, int *height)
|
||||
{
|
||||
struct MADHeader header;
|
||||
if (!mad_read_header(filename, &header))
|
||||
return false;
|
||||
*width = header.width;
|
||||
*height = header.height;
|
||||
return true;
|
||||
}
|
||||
|
||||
static int MADLoader_GetNumofFromFile(struct string *filename)
|
||||
{
|
||||
struct MADHeader header;
|
||||
if (!mad_read_header(filename, &header))
|
||||
return -1;
|
||||
return header.nr_images;
|
||||
}
|
||||
|
||||
static int MADLoader_GetTotalTimeFromFile(struct string *filename)
|
||||
{
|
||||
struct MADHeader header;
|
||||
if (!mad_read_header(filename, &header))
|
||||
return -1;
|
||||
return header.total_time;
|
||||
}
|
||||
|
||||
static int MADLoader_GetDrawMethodFromFile(struct string *filename)
|
||||
{
|
||||
struct MADHeader header;
|
||||
if (!mad_read_header(filename, &header))
|
||||
return -1;
|
||||
return header.draw_method;
|
||||
}
|
||||
|
||||
static bool MADLoader_IsLoopFromFile(struct string *filename)
|
||||
{
|
||||
struct MADHeader header;
|
||||
if (!mad_read_header(filename, &header))
|
||||
return false;
|
||||
return header.is_loop == 1;
|
||||
}
|
||||
|
||||
static bool MADLoader_IsKeepLastFrameFromFile(struct string *filename)
|
||||
{
|
||||
struct MADHeader header;
|
||||
if (!mad_read_header(filename, &header))
|
||||
return false;
|
||||
return header.keep_last_frame == 1;
|
||||
}
|
||||
|
||||
static Texture *get_mad_texture(int handle, int index)
|
||||
{
|
||||
struct MAD *mad = id_pool_get(&pool, handle);
|
||||
if (!mad || index < 0 || index >= mad->header.nr_images)
|
||||
return NULL;
|
||||
return &mad->textures[index];
|
||||
}
|
||||
|
||||
static Texture *get_dest_texture(int sp_no)
|
||||
{
|
||||
struct sact_sprite *sp = sact_get_sprite(sp_no);
|
||||
if (!sp)
|
||||
return NULL;
|
||||
sprite_dirty(sp);
|
||||
return sprite_get_texture(sp);
|
||||
}
|
||||
|
||||
static bool MADLoader_Copy(int handle, int sprite, int index)
|
||||
{
|
||||
Texture *src = get_mad_texture(handle, index);
|
||||
Texture *dst = get_dest_texture(sprite);
|
||||
if (!src || !dst)
|
||||
return false;
|
||||
|
||||
gfx_copy_with_alpha_map(dst, 0, 0, src, 0, 0, src->w, src->h);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool MADLoader_CopyReverseLR(int handle, int sprite, int index)
|
||||
{
|
||||
Texture *src = get_mad_texture(handle, index);
|
||||
Texture *dst = get_dest_texture(sprite);
|
||||
if (!src || !dst)
|
||||
return false;
|
||||
|
||||
gfx_copy_reverse_LR_with_alpha_map(dst, 0, 0, src, 0, 0, src->w, src->h);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool MADLoader_CopyGrayscale(int handle, int sprite, int index)
|
||||
{
|
||||
Texture *src = get_mad_texture(handle, index);
|
||||
Texture *dst = get_dest_texture(sprite);
|
||||
if (!src || !dst)
|
||||
return false;
|
||||
|
||||
gfx_copy_grayscale_with_alpha_map(dst, 0, 0, src, 0, 0, src->w, src->h);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool MADLoader_CopyGrayscaleReverseLR(int handle, int sprite, int index)
|
||||
{
|
||||
Texture *src = get_mad_texture(handle, index);
|
||||
Texture *dst = get_dest_texture(sprite);
|
||||
if (!src || !dst)
|
||||
return false;
|
||||
|
||||
gfx_copy_grayscale_reverse_LR_with_alpha_map(dst, 0, 0, src, 0, 0, src->w, src->h);
|
||||
return true;
|
||||
}
|
||||
|
||||
HLL_LIBRARY(MADLoader,
|
||||
HLL_EXPORT(_ModuleInit, MADLoader_ModuleInit),
|
||||
HLL_EXPORT(_ModuleFini, MADLoader_ModuleFini),
|
||||
HLL_EXPORT(Delete, MADLoader_Delete),
|
||||
HLL_EXPORT(Open, MADLoader_Open),
|
||||
HLL_EXPORT(Close, MADLoader_Close),
|
||||
HLL_EXPORT(GetSize, MADLoader_GetSize),
|
||||
HLL_EXPORT(GetNumof, MADLoader_GetNumof),
|
||||
HLL_EXPORT(GetTotalTime, MADLoader_GetTotalTime),
|
||||
HLL_EXPORT(GetDrawMethod, MADLoader_GetDrawMethod),
|
||||
HLL_EXPORT(IsLoop, MADLoader_IsLoop),
|
||||
HLL_EXPORT(IsKeepLastFrame, MADLoader_IsKeepLastFrame),
|
||||
HLL_EXPORT(IsLoading, MADLoader_IsLoading),
|
||||
HLL_EXPORT(GetLoadNumof, MADLoader_GetLoadNumof),
|
||||
HLL_EXPORT(GetSizeFromFile, MADLoader_GetSizeFromFile),
|
||||
HLL_EXPORT(GetNumofFromFile, MADLoader_GetNumofFromFile),
|
||||
HLL_EXPORT(GetTotalTimeFromFile, MADLoader_GetTotalTimeFromFile),
|
||||
HLL_EXPORT(GetDrawMethodFromFile, MADLoader_GetDrawMethodFromFile),
|
||||
HLL_EXPORT(IsLoopFromFile, MADLoader_IsLoopFromFile),
|
||||
HLL_EXPORT(IsKeepLastFrameFromFile, MADLoader_IsKeepLastFrameFromFile),
|
||||
HLL_EXPORT(Copy, MADLoader_Copy),
|
||||
HLL_EXPORT(CopyReverseLR, MADLoader_CopyReverseLR),
|
||||
HLL_EXPORT(CopyGrayscale, MADLoader_CopyGrayscale),
|
||||
HLL_EXPORT(CopyGrayscaleReverseLR, MADLoader_CopyGrayscaleReverseLR)
|
||||
);
|
||||
@@ -0,0 +1,121 @@
|
||||
/* Copyright (C) 2026 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 "vm/page.h"
|
||||
#include "hll.h"
|
||||
#include "sact.h"
|
||||
#include "xsystem4.h"
|
||||
|
||||
static struct {
|
||||
Texture bg;
|
||||
Texture grid;
|
||||
int blend_rate;
|
||||
} p3map;
|
||||
|
||||
// Initializes the grid texture with isometric tiles based on the provided array.
|
||||
static void init_grid_texture(Texture *tile, int offset_x, int offset_y, int rows, int cols, struct page *array)
|
||||
{
|
||||
if (array->nr_vars != rows * cols)
|
||||
VM_ERROR("Expected %d variables in array, got %d", rows * cols, array->nr_vars);
|
||||
for (int row = 0; row < rows; row++) {
|
||||
for (int col = 0; col < cols; col++) {
|
||||
if (array->values[row * cols + col].i != 0)
|
||||
continue;
|
||||
// Isometric Coordinates.
|
||||
int x = ((col - row) - 1) * (tile->w / 2) + offset_x;
|
||||
int y = (col + row) * (tile->h / 2) + offset_y;
|
||||
gfx_copy_with_alpha_map(&p3map.grid, x, y, tile, 0, 0, tile->w, tile->h);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Creates the map background and grid textures.
|
||||
static bool P3MapSprite_Create(int src_sprite, int square_sprite, int x, int y, int line, int column, int blend_rate, struct page *array)
|
||||
{
|
||||
struct sact_sprite *src = sact_try_get_sprite(src_sprite);
|
||||
struct sact_sprite *square = sact_try_get_sprite(square_sprite);
|
||||
if (!src || !square)
|
||||
return false;
|
||||
Texture *tx_src = sprite_get_texture(src);
|
||||
Texture *tx_square = sprite_get_texture(square);
|
||||
int width = tx_src->w;
|
||||
int height = tx_src->h;
|
||||
|
||||
if (p3map.bg.handle)
|
||||
gfx_delete_texture(&p3map.bg);
|
||||
gfx_init_texture_blank(&p3map.bg, width, height);
|
||||
gfx_copy(&p3map.bg, 0, 0, tx_src, 0, 0, width, height);
|
||||
|
||||
if (p3map.grid.handle)
|
||||
gfx_delete_texture(&p3map.grid);
|
||||
gfx_init_texture_rgba(&p3map.grid, width, height, COLOR(0, 0, 0, 0));
|
||||
init_grid_texture(tx_square, x, y, line, column, array);
|
||||
|
||||
p3map.blend_rate = blend_rate;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Deletes the map background and grid textures.
|
||||
static void P3MapSprite_Delete(void)
|
||||
{
|
||||
if (p3map.grid.handle)
|
||||
gfx_delete_texture(&p3map.grid);
|
||||
if (p3map.bg.handle)
|
||||
gfx_delete_texture(&p3map.bg);
|
||||
}
|
||||
|
||||
// Copies the map background and optionally blends the grid to a destination sprite.
|
||||
static bool P3MapSprite_Copy(int dest_sprite, int src_x, int src_y, bool copy_square)
|
||||
{
|
||||
struct sact_sprite *dst = sact_get_sprite(dest_sprite);
|
||||
if (!dst)
|
||||
return false;
|
||||
Texture *tx_dst = sprite_get_texture(dst);
|
||||
int w = sprite_get_width(dst);
|
||||
int h = sprite_get_height(dst);
|
||||
gfx_copy(tx_dst, 0, 0, &p3map.bg, src_x, src_y, w, h);
|
||||
if (copy_square)
|
||||
gfx_blend_amap_alpha(tx_dst, 0, 0, &p3map.grid, src_x, src_y, w, h, p3map.blend_rate);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Sets the blend rate for map rendering.
|
||||
static bool P3MapSprite_CreateMatrixPixel(int blend_rate)
|
||||
{
|
||||
p3map.blend_rate = blend_rate;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Blends the grid texture onto a destination sprite.
|
||||
static bool P3MapSprite_CopyMatrix(int dest_sprite, int dest_x, int dest_y, int src_x, int src_y, int width, int height)
|
||||
{
|
||||
struct sact_sprite *dst = sact_get_sprite(dest_sprite);
|
||||
if (!dst)
|
||||
return false;
|
||||
Texture *tx_dst = sprite_get_texture(dst);
|
||||
gfx_blend_amap(tx_dst, dest_x, dest_y, &p3map.grid, src_x, src_y, width, height);
|
||||
gfx_copy_amap_max(tx_dst, dest_x, dest_y, &p3map.grid, src_x, src_y, width, height);
|
||||
return true;
|
||||
}
|
||||
|
||||
HLL_LIBRARY(P3MapSprite,
|
||||
HLL_EXPORT(Create, P3MapSprite_Create),
|
||||
HLL_EXPORT(Delete, P3MapSprite_Delete),
|
||||
HLL_EXPORT(Copy, P3MapSprite_Copy),
|
||||
HLL_EXPORT(CreateMatrixPixel, P3MapSprite_CreateMatrixPixel),
|
||||
HLL_EXPORT(CopyMatrix, P3MapSprite_CopyMatrix)
|
||||
);
|
||||
@@ -0,0 +1,69 @@
|
||||
/* Copyright (C) 2026 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 "sact.h"
|
||||
#include "gfx/gfx.h"
|
||||
#include "vm/page.h"
|
||||
#include "hll.h"
|
||||
#include "xsystem4.h"
|
||||
|
||||
static bool P3SquareSprite_Copy(int dest_handle, int src_handle, int size, struct page *matrix)
|
||||
{
|
||||
struct sact_sprite *dest = sact_try_get_sprite(dest_handle);
|
||||
struct sact_sprite *src = sact_try_get_sprite(src_handle);
|
||||
|
||||
if (!dest || !src)
|
||||
return false;
|
||||
|
||||
Texture *dest_tex = sprite_get_texture(dest);
|
||||
Texture *src_tex = sprite_get_texture(src);
|
||||
|
||||
int tile_w = src_tex->w;
|
||||
int tile_h = src_tex->h;
|
||||
int half_w = tile_w / 2;
|
||||
int half_h = tile_h / 2;
|
||||
|
||||
int canvas_center_x = dest_tex->w / 2;
|
||||
int canvas_center_y = dest_tex->h / 2;
|
||||
|
||||
int side_count = size * 2 + 1;
|
||||
|
||||
if (matrix->nr_vars != side_count * side_count)
|
||||
VM_ERROR("Expected %d variables in array, got %d", side_count * side_count, matrix->nr_vars);
|
||||
|
||||
int index = 0;
|
||||
for (int y = -size; y <= size; ++y) {
|
||||
for (int x = -size; x <= size; ++x) {
|
||||
// Check if we should draw this tile
|
||||
if (matrix->values[index++].i == 0)
|
||||
continue;
|
||||
|
||||
// Isometric coordinate conversion
|
||||
int screen_pos_x = canvas_center_x + (x - y - 1) * half_w;
|
||||
int screen_pos_y = canvas_center_y + (x + y - 1) * half_h;
|
||||
|
||||
// Draw the sprite
|
||||
gfx_copy_use_amap_border(dest_tex, screen_pos_x, screen_pos_y, src_tex, 0, 0, tile_w, tile_h, 1);
|
||||
gfx_copy_amap_max(dest_tex, screen_pos_x, screen_pos_y, src_tex, 0, 0, tile_w, tile_h);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
HLL_LIBRARY(P3SquareSprite,
|
||||
HLL_EXPORT(Copy, P3SquareSprite_Copy)
|
||||
);
|
||||
@@ -117,6 +117,7 @@ xsystem4 = [version_h,
|
||||
'hll/InputString.c',
|
||||
'hll/KiwiSoundEngine.c',
|
||||
'hll/LoadCG.c',
|
||||
'hll/MADLoader.c',
|
||||
'hll/MainEXFile.c',
|
||||
'hll/MainSurface.c',
|
||||
'hll/MamanyoDemo.c',
|
||||
@@ -132,6 +133,8 @@ xsystem4 = [version_h,
|
||||
'hll/MusicSystem.c',
|
||||
'hll/NewFont.c',
|
||||
'hll/OutputLog.c',
|
||||
'hll/P3MapSprite.c',
|
||||
'hll/P3SquareSprite.c',
|
||||
'hll/PassRegister.c',
|
||||
'hll/PastelChime2.c',
|
||||
'hll/PartsEngine.c',
|
||||
|
||||
Reference in New Issue
Block a user