mirror of
https://github.com/nunuhara/xsystem4.git
synced 2026-10-05 13:28:04 +03:00
PartsEngine: Implement movie parts
This adds PARTS_MOVIE type which creates a SACT sprite as a render target for DrawMovie. The GL texture is shared between the SACT sprite and parts_common, so movie frames rendered to the sprite are directly visible through the parts engine's rendering path.
This commit is contained in:
@@ -116,6 +116,9 @@ bool PE_Load(struct page **buffer);
|
||||
// GUIEngine
|
||||
int PE_GetFreeNumber(void);
|
||||
bool PE_IsExist(int parts_no);
|
||||
// PartsFunc interface
|
||||
bool PE_init_parts_movie(int parts_no, int width, int height, int bg_r, int bg_g, int bg_b, int state);
|
||||
int PE_get_movie_sprite(int parts_no, int state);
|
||||
|
||||
// construction.c
|
||||
bool PE_AddCreateToPartsConstructionProcess(int parts_no, int w, int h, int state);
|
||||
|
||||
+34
-1
@@ -18,6 +18,7 @@
|
||||
|
||||
#include "system4/ain.h"
|
||||
|
||||
#include "vm/page.h"
|
||||
#include "parts.h"
|
||||
#include "hll.h"
|
||||
|
||||
@@ -96,7 +97,39 @@ static void PartsEngine_AddComponentMotionPos(int parts_no, float begin_x, float
|
||||
begin_t, end_t, curve_name);
|
||||
}
|
||||
|
||||
HLL_WARN_UNIMPLEMENTED(0, int, PartsEngine, PartsFunc, int func_id, struct page **array_int, struct page **array_float, struct page **array_string);
|
||||
// Generic dispatch function for PartsEngine operations.
|
||||
// func_id selects the operation; arguments and return values are passed
|
||||
// through three typed arrays (int/bool, float, string).
|
||||
//
|
||||
// Calling convention (from game script):
|
||||
// 1. Push input values into the appropriate arrays.
|
||||
// 2. Push a placeholder (0 or "") for each output slot.
|
||||
// 3. Call PartsFunc; outputs are written back into the placeholder slots.
|
||||
static int PartsEngine_PartsFunc(int func_id, struct page **array_int,
|
||||
struct page **array_float, struct page **array_string)
|
||||
{
|
||||
int nr_ints = (array_int && *array_int) ? (*array_int)->nr_vars : 0;
|
||||
union vm_value *ints = nr_ints ? (*array_int)->values : NULL;
|
||||
|
||||
#define REQUIRE_INTS(n) \
|
||||
if (nr_ints != (n)) VM_ERROR("Invalid arguments for PartsFunc %d: expected %d ints, got %d", func_id, (n), nr_ints)
|
||||
|
||||
switch (func_id) {
|
||||
case 162: // bool InitPartsMovie(int parts_no, int width, int height, int bg_r, int bg_g, int bg_b, int state)
|
||||
REQUIRE_INTS(8);
|
||||
ints[7].i = PE_init_parts_movie(ints[0].i, ints[1].i, ints[2].i, ints[3].i, ints[4].i, ints[5].i, ints[6].i);
|
||||
return 1;
|
||||
case 163: // int GetMovieSprite(int parts_no, int state)
|
||||
REQUIRE_INTS(3);
|
||||
ints[2].i = PE_get_movie_sprite(ints[0].i, ints[1].i);
|
||||
return 1;
|
||||
default:
|
||||
WARNING("Unknown func_id: %d", func_id);
|
||||
return 0;
|
||||
}
|
||||
#undef REQUIRE_INTS
|
||||
}
|
||||
|
||||
HLL_WARN_UNIMPLEMENTED(, void, PartsEngine, StopSoundWithoutSystemSound);
|
||||
HLL_WARN_UNIMPLEMENTED(, void, PartsEngine, ReleaseMessage, void);
|
||||
HLL_WARN_UNIMPLEMENTED(0, int, PartsEngine, GetMessageType, void);
|
||||
|
||||
@@ -209,6 +209,11 @@ static void parts_flat_to_json(struct parts_flat *flat, cJSON *out, bool verbose
|
||||
cJSON_AddNumberToObject(out, "end_frame", flat->end_frame);
|
||||
}
|
||||
|
||||
static void parts_movie_to_json(struct parts_movie *movie, cJSON *out, bool verbose)
|
||||
{
|
||||
cJSON_AddNumberToObject(out, "sprite_no", movie->sprite_no);
|
||||
}
|
||||
|
||||
static cJSON *parts_state_to_json(struct parts_state *state, bool verbose)
|
||||
{
|
||||
static const char *state_types[PARTS_NR_TYPES] = {
|
||||
@@ -262,6 +267,9 @@ static cJSON *parts_state_to_json(struct parts_state *state, bool verbose)
|
||||
case PARTS_FLAT:
|
||||
parts_flat_to_json(&state->flat, obj, verbose);
|
||||
break;
|
||||
case PARTS_MOVIE:
|
||||
parts_movie_to_json(&state->movie, obj, verbose);
|
||||
break;
|
||||
}
|
||||
|
||||
return obj;
|
||||
@@ -545,6 +553,9 @@ static void parts_list_print(struct parts *parts, int indent)
|
||||
case PARTS_FLAT:
|
||||
sys_message("(flat %s)", state->flat.name ? display_sjis0(state->flat.name->text) : "(null)");
|
||||
break;
|
||||
case PARTS_MOVIE:
|
||||
sys_message("(movie sp=%d)", state->movie.sprite_no);
|
||||
break;
|
||||
}
|
||||
|
||||
sys_message(" @ z=%d (%d)\n", parts->global.z, parts->local.z);
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "vm/page.h"
|
||||
#include "xsystem4.h"
|
||||
#include "sact.h"
|
||||
#include "sprite.h"
|
||||
#include "parts.h"
|
||||
#include "parts_internal.h"
|
||||
|
||||
@@ -178,6 +179,12 @@ static void parts_state_free(struct parts_state *state)
|
||||
case PARTS_FLAT:
|
||||
parts_flat_free(&state->flat);
|
||||
break;
|
||||
case PARTS_MOVIE:
|
||||
// The texture is owned by the SACT sprite.
|
||||
state->common.texture.handle = 0;
|
||||
if (state->movie.sprite_no >= 0)
|
||||
sact_SP_Delete(state->movie.sprite_no);
|
||||
break;
|
||||
}
|
||||
memset(state, 0, sizeof(struct parts_state));
|
||||
}
|
||||
@@ -225,6 +232,9 @@ void parts_state_reset(struct parts_state *state, enum parts_type type)
|
||||
case PARTS_FLASH:
|
||||
case PARTS_FLAT:
|
||||
break;
|
||||
case PARTS_MOVIE:
|
||||
state->movie.sprite_no = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -300,6 +310,14 @@ struct parts_flat *parts_get_flat(struct parts *parts, int state)
|
||||
return &parts->states[state].flat;
|
||||
}
|
||||
|
||||
struct parts_movie *parts_get_movie(struct parts *parts, int state)
|
||||
{
|
||||
if (parts->states[state].type != PARTS_MOVIE) {
|
||||
parts_state_reset(&parts->states[state], PARTS_MOVIE);
|
||||
}
|
||||
return &parts->states[state].movie;
|
||||
}
|
||||
|
||||
static Point calculate_offset(int mode, int w, int h)
|
||||
{
|
||||
switch (mode) {
|
||||
@@ -1861,3 +1879,36 @@ void PE_SetSpeedupRateByMessageSkip(int parts_no, int rate)
|
||||
if (rate != 1)
|
||||
UNIMPLEMENTED("(%d, %d)");
|
||||
}
|
||||
|
||||
bool PE_init_parts_movie(int parts_no, int width, int height, int bg_r, int bg_g, int bg_b, int state)
|
||||
{
|
||||
if (!parts_state_valid(--state))
|
||||
return false;
|
||||
|
||||
struct parts *parts = parts_get(parts_no);
|
||||
struct parts_movie *movie = parts_get_movie(parts, state);
|
||||
|
||||
int sp_no = sact_SP_GetUnuseNum(0);
|
||||
struct sact_sprite *sp = sact_create_sprite(sp_no, width, height, bg_r, bg_g, bg_b, 255);
|
||||
if (!sp)
|
||||
return false;
|
||||
|
||||
struct texture *tex = sprite_get_texture(sp);
|
||||
movie->sprite_no = sp_no;
|
||||
movie->common.texture = *tex; // XXX: textures normally shouldn't be copied like this...
|
||||
parts_set_dims(parts, &movie->common, width, height);
|
||||
parts_dirty(parts);
|
||||
return true;
|
||||
}
|
||||
|
||||
int PE_get_movie_sprite(int parts_no, int state)
|
||||
{
|
||||
if (!parts_state_valid(--state))
|
||||
return -1;
|
||||
|
||||
struct parts *parts = parts_try_get(parts_no);
|
||||
if (!parts || parts->states[state].type != PARTS_MOVIE)
|
||||
return -1;
|
||||
|
||||
return parts->states[state].movie.sprite_no;
|
||||
}
|
||||
|
||||
@@ -104,7 +104,8 @@ enum parts_type {
|
||||
PARTS_CONSTRUCTION_PROCESS,
|
||||
PARTS_FLASH,
|
||||
PARTS_FLAT,
|
||||
#define PARTS_NR_TYPES (PARTS_FLAT+1)
|
||||
PARTS_MOVIE,
|
||||
#define PARTS_NR_TYPES (PARTS_MOVIE+1)
|
||||
};
|
||||
|
||||
struct parts_common {
|
||||
@@ -313,6 +314,11 @@ struct parts_flat {
|
||||
size_t nr_textures;
|
||||
};
|
||||
|
||||
struct parts_movie {
|
||||
struct parts_common common;
|
||||
int sprite_no; // SACT sprite number used as movie render target
|
||||
};
|
||||
|
||||
struct parts_state {
|
||||
enum parts_type type;
|
||||
union {
|
||||
@@ -325,6 +331,7 @@ struct parts_state {
|
||||
struct parts_construction_process cproc;
|
||||
struct parts_flash flash;
|
||||
struct parts_flat flat;
|
||||
struct parts_movie movie;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -385,6 +392,7 @@ struct parts_gauge *parts_get_vgauge(struct parts *parts, int state);
|
||||
struct parts_construction_process *parts_get_construction_process(struct parts *parts, int state);
|
||||
struct parts_flash *parts_get_flash(struct parts *parts, int state);
|
||||
struct parts_flat *parts_get_flat(struct parts *parts, int state);
|
||||
struct parts_movie *parts_get_movie(struct parts *parts, int state);
|
||||
void parts_set_pos(struct parts *parts, Point pos);
|
||||
void parts_set_global_pos(Point pos);
|
||||
void parts_set_dims(struct parts *parts, struct parts_common *common, int w, int h);
|
||||
|
||||
@@ -419,6 +419,7 @@ void parts_render(struct parts *parts)
|
||||
case PARTS_HGAUGE:
|
||||
case PARTS_VGAUGE:
|
||||
case PARTS_CONSTRUCTION_PROCESS:
|
||||
case PARTS_MOVIE:
|
||||
if (state->common.texture.handle)
|
||||
parts_render_cg(parts, &state->common);
|
||||
break;
|
||||
|
||||
@@ -386,6 +386,8 @@ static void save_parts_state(struct iarray_writer *w, struct parts_state *state)
|
||||
case PARTS_FLAT:
|
||||
save_parts_flat(w, &state->flat);
|
||||
break;
|
||||
case PARTS_MOVIE:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -428,6 +430,8 @@ static void load_parts_state(struct iarray_reader *r, struct parts *parts,
|
||||
case PARTS_FLAT:
|
||||
load_parts_flat(r, parts, &state->flat);
|
||||
break;
|
||||
case PARTS_MOVIE:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user