mirror of
https://github.com/nunuhara/xsystem4.git
synced 2026-09-22 23:18:01 +03:00
PartsEngine: Implement message dispatch system
This adds a message queue that captures GUI events and exposes them through HLL accessor functions.
This commit is contained in:
@@ -176,6 +176,19 @@ void PE_EndInput(void);
|
||||
int PE_GetClickPartsNumber(void);
|
||||
bool PE_IsCursorIn(int parts_no, int mouse_x, int mouse_y, int state);
|
||||
|
||||
// message.c
|
||||
void PE_ReleaseMessage(void);
|
||||
void PE_PopMessage(void);
|
||||
int PE_GetMessageType(void);
|
||||
int PE_GetMessagePartsNumber(void);
|
||||
int PE_GetMessageDelegateIndex(void);
|
||||
int PE_GetMessageVariableCount(void);
|
||||
int PE_GetMessageVariableType(int index);
|
||||
int PE_GetMessageVariableInt(int index);
|
||||
float PE_GetMessageVariableFloat(int index);
|
||||
bool PE_GetMessageVariableBool(int index);
|
||||
void PE_GetMessageVariableString(int index, struct string **out);
|
||||
|
||||
// motion.c
|
||||
void PE_AddMotionPos(int parts_no, int begin_x, int begin_y, int end_x, int end_y, int begin_t, int end_t);
|
||||
void PE_AddMotionPos_curve(int parts_no, int begin_x, int begin_y, int end_x, int end_y,
|
||||
|
||||
+11
-13
@@ -143,8 +143,6 @@ static int PartsEngine_PartsFunc(int func_id, struct page **array_int,
|
||||
}
|
||||
|
||||
HLL_WARN_UNIMPLEMENTED(, void, PartsEngine, StopSoundWithoutSystemSound);
|
||||
HLL_WARN_UNIMPLEMENTED(, void, PartsEngine, ReleaseMessage, void);
|
||||
HLL_WARN_UNIMPLEMENTED(0, int, PartsEngine, GetMessageType, void);
|
||||
HLL_WARN_UNIMPLEMENTED(, void, PartsEngine, Parts_SetPassCursor, int Number, bool Pass);
|
||||
|
||||
static void PartsEngine_PreLink(void);
|
||||
@@ -332,18 +330,18 @@ HLL_LIBRARY(PartsEngine,
|
||||
HLL_TODO_EXPORT(ReleaseActivity, PartsEngine_ReleaseActivity),
|
||||
HLL_TODO_EXPORT(CrateActivityBinary, PartsEngine_CrateActivityBinary),
|
||||
HLL_TODO_EXPORT(ReadActivityBinary, PartsEngine_ReadActivityBinary),
|
||||
HLL_EXPORT(ReleaseMessage, PartsEngine_ReleaseMessage),
|
||||
HLL_TODO_EXPORT(PopMessage, PartsEngine_PopMessage),
|
||||
HLL_TODO_EXPORT(GetMessagePartsNumber, PartsEngine_GetMessagePartsNumber),
|
||||
HLL_TODO_EXPORT(GetMessageDelegateIndex, PartsEngine_GetMessageDelegateIndex),
|
||||
HLL_EXPORT(ReleaseMessage, PE_ReleaseMessage),
|
||||
HLL_EXPORT(PopMessage, PE_PopMessage),
|
||||
HLL_EXPORT(GetMessagePartsNumber, PE_GetMessagePartsNumber),
|
||||
HLL_EXPORT(GetMessageDelegateIndex, PE_GetMessageDelegateIndex),
|
||||
HLL_EXPORT(GetDelegateIndex, PE_GetDelegateIndex),
|
||||
HLL_EXPORT(GetMessageType, PartsEngine_GetMessageType),
|
||||
HLL_TODO_EXPORT(GetMessageVariableCount, PartsEngine_GetMessageVariableCount),
|
||||
HLL_TODO_EXPORT(GetMessageVariableType, PartsEngine_GetMessageVariableType),
|
||||
HLL_TODO_EXPORT(GetMessageVariableInt, PartsEngine_GetMessageVariableInt),
|
||||
HLL_TODO_EXPORT(GetMessageVariableFloat, PartsEngine_GetMessageVariableFloat),
|
||||
HLL_TODO_EXPORT(GetMessageVariableBool, PartsEngine_GetMessageVariableBool),
|
||||
HLL_TODO_EXPORT(GetMessageVariableString, PartsEngine_GetMessageVariableString),
|
||||
HLL_EXPORT(GetMessageType, PE_GetMessageType),
|
||||
HLL_EXPORT(GetMessageVariableCount, PE_GetMessageVariableCount),
|
||||
HLL_EXPORT(GetMessageVariableType, PE_GetMessageVariableType),
|
||||
HLL_EXPORT(GetMessageVariableInt, PE_GetMessageVariableInt),
|
||||
HLL_EXPORT(GetMessageVariableFloat, PE_GetMessageVariableFloat),
|
||||
HLL_EXPORT(GetMessageVariableBool, PE_GetMessageVariableBool),
|
||||
HLL_EXPORT(GetMessageVariableString, PE_GetMessageVariableString),
|
||||
HLL_EXPORT(SetDelegateIndex, PE_SetDelegateIndex),
|
||||
HLL_TODO_EXPORT(SetFocus, PartsEngine_SetFocus),
|
||||
HLL_TODO_EXPORT(IsFocus, PartsEngine_IsFocus),
|
||||
|
||||
@@ -61,6 +61,7 @@ xsystem4 = [version_h,
|
||||
'parts/flash.c',
|
||||
'parts/flat.c',
|
||||
'parts/input.c',
|
||||
'parts/message.c',
|
||||
'parts/motion.c',
|
||||
'parts/parts.c',
|
||||
'parts/render.c',
|
||||
|
||||
@@ -0,0 +1,146 @@
|
||||
/* 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 <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "system4.h"
|
||||
#include "system4/string.h"
|
||||
|
||||
#include "vm.h"
|
||||
#include "parts.h"
|
||||
#include "parts_internal.h"
|
||||
|
||||
#define PARTS_MSG_MAX_VARS 4
|
||||
|
||||
struct parts_message {
|
||||
STAILQ_ENTRY(parts_message) entry;
|
||||
int parts_no;
|
||||
int delegate_index;
|
||||
int type;
|
||||
int variables[PARTS_MSG_MAX_VARS];
|
||||
int nr_variables;
|
||||
};
|
||||
|
||||
static STAILQ_HEAD(, parts_message) msg_queue =
|
||||
STAILQ_HEAD_INITIALIZER(msg_queue);
|
||||
|
||||
void parts_msg_push(int parts_no, int delegate_index, int type, const char *fmt, ...)
|
||||
{
|
||||
// Message system is introduced in Rance 9
|
||||
if (!parts_multi_controller)
|
||||
return;
|
||||
|
||||
struct parts_message *msg = xmalloc(sizeof(*msg));
|
||||
msg->parts_no = parts_no;
|
||||
msg->delegate_index = delegate_index;
|
||||
msg->type = type;
|
||||
msg->nr_variables = 0;
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
for (const char *p = fmt; *p; p++) {
|
||||
if (msg->nr_variables >= PARTS_MSG_MAX_VARS) {
|
||||
VM_ERROR("parts_msg_push: too many variables");
|
||||
}
|
||||
switch (*p) {
|
||||
case 'i':
|
||||
msg->variables[msg->nr_variables++] = va_arg(ap, int);
|
||||
break;
|
||||
default:
|
||||
VM_ERROR("parts_msg_push: unsupported format '%c'", *p);
|
||||
}
|
||||
}
|
||||
va_end(ap);
|
||||
|
||||
STAILQ_INSERT_TAIL(&msg_queue, msg, entry);
|
||||
}
|
||||
|
||||
void PE_ReleaseMessage(void)
|
||||
{
|
||||
while (!STAILQ_EMPTY(&msg_queue)) {
|
||||
struct parts_message *msg = STAILQ_FIRST(&msg_queue);
|
||||
STAILQ_REMOVE_HEAD(&msg_queue, entry);
|
||||
free(msg);
|
||||
}
|
||||
}
|
||||
|
||||
void PE_PopMessage(void)
|
||||
{
|
||||
if (STAILQ_EMPTY(&msg_queue))
|
||||
return;
|
||||
struct parts_message *msg = STAILQ_FIRST(&msg_queue);
|
||||
STAILQ_REMOVE_HEAD(&msg_queue, entry);
|
||||
free(msg);
|
||||
}
|
||||
|
||||
int PE_GetMessageType(void)
|
||||
{
|
||||
struct parts_message *msg = STAILQ_FIRST(&msg_queue);
|
||||
return msg ? msg->type : 0;
|
||||
}
|
||||
|
||||
int PE_GetMessagePartsNumber(void)
|
||||
{
|
||||
struct parts_message *msg = STAILQ_FIRST(&msg_queue);
|
||||
return msg ? msg->parts_no : 0;
|
||||
}
|
||||
|
||||
int PE_GetMessageDelegateIndex(void)
|
||||
{
|
||||
struct parts_message *msg = STAILQ_FIRST(&msg_queue);
|
||||
return msg ? msg->delegate_index : -1;
|
||||
}
|
||||
|
||||
int PE_GetMessageVariableCount(void)
|
||||
{
|
||||
struct parts_message *msg = STAILQ_FIRST(&msg_queue);
|
||||
return msg ? msg->nr_variables : 0;
|
||||
}
|
||||
|
||||
int PE_GetMessageVariableType(possibly_unused int index)
|
||||
{
|
||||
// In the current implementation, all variables are integers.
|
||||
return 1;
|
||||
}
|
||||
|
||||
int PE_GetMessageVariableInt(int index)
|
||||
{
|
||||
struct parts_message *msg = STAILQ_FIRST(&msg_queue);
|
||||
if (!msg)
|
||||
return 0;
|
||||
if (index < 0 || index >= msg->nr_variables)
|
||||
return 0;
|
||||
return msg->variables[index];
|
||||
}
|
||||
|
||||
float PE_GetMessageVariableFloat(possibly_unused int index)
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
bool PE_GetMessageVariableBool(possibly_unused int index)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void PE_GetMessageVariableString(possibly_unused int index, struct string **out)
|
||||
{
|
||||
if (*out)
|
||||
free_string(*out);
|
||||
*out = string_ref(&EMPTY_STRING);
|
||||
}
|
||||
@@ -1020,6 +1020,7 @@ bool PE_Init(void)
|
||||
void PE_Reset(void)
|
||||
{
|
||||
PE_ReleaseAllParts();
|
||||
PE_ReleaseMessage();
|
||||
ctrl_stack_fini();
|
||||
sact_ModuleFini();
|
||||
}
|
||||
|
||||
@@ -465,6 +465,24 @@ void parts_add_motion(struct parts *parts, struct parts_motion *motion);
|
||||
extern Point parts_prev_pos;
|
||||
extern bool parts_began_click;
|
||||
|
||||
// message.c
|
||||
enum parts_message_type {
|
||||
PARTS_MSG_MOUSE_ENTER = 1,
|
||||
PARTS_MSG_MOUSE_MOVE = 2,
|
||||
PARTS_MSG_MOUSE_LEAVE = 3,
|
||||
PARTS_MSG_MOUSE_WHEEL = 4,
|
||||
PARTS_MSG_MOUSE_CLICK = 5,
|
||||
PARTS_MSG_MOUSE_ON = 6,
|
||||
PARTS_MSG_DRAG_BEGIN = 7,
|
||||
PARTS_MSG_DRAGGING = 8,
|
||||
PARTS_MSG_DRAG_END = 9,
|
||||
PARTS_MSG_KEY_TRIGGER = 14,
|
||||
PARTS_MSG_KEY_DOWN = 15,
|
||||
PARTS_MSG_KEY_UP = 17,
|
||||
};
|
||||
|
||||
void parts_msg_push(int parts_no, int delegate_index, int type, const char *fmt, ...);
|
||||
|
||||
// construction.c
|
||||
void parts_cp_op_free(struct parts_cp_op *op);
|
||||
void parts_add_cp_op(struct parts_construction_process *cproc, struct parts_cp_op *op);
|
||||
|
||||
Reference in New Issue
Block a user