summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonAki <konaki@anokonaki.org>2026-10-14 18:55:24 +0800
committerKonAki <konaki@anokonaki.org>2026-10-14 18:55:24 +0800
commitae3e03e0c5663fe4e59c136115090f4777e63282 (patch)
treef41e773ffac4341f0c987017d2a9437bcae8f58d
parentac3f5875c373ade26547fecb7ad2e2a53003aabc (diff)
add rm module: one host function for the RPG Maker commands
-rw-r--r--kon/konrm.c176
-rw-r--r--kon/konrm.h56
2 files changed, 232 insertions, 0 deletions
diff --git a/kon/konrm.c b/kon/konrm.c
new file mode 100644
index 0000000..d244619
--- /dev/null
+++ b/kon/konrm.c
@@ -0,0 +1,176 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * konrm.c
+ *
+ * Copyright (c) 2026 KonAki
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include "konrm.h"
+
+#ifdef KON_MODULE_SOUND
+#include "konsound.h"
+#endif
+#ifdef KON_MODULE_PICTURE
+#include "konpicture.h"
+#endif
+#ifdef KON_MODULE_FX
+#include "konfx.h"
+#endif
+
+/*** helpers ***/
+
+#ifdef KON_MODULE_PICTURE
+
+/* the text is the parameters joined by tabs, and the first three numbers are also in b, c and d when there is no text */
+static int fieldInt(int b, int c, int d, const char *text, int index, int fallback)
+{
+ long value = 0;
+ int negative = 0, digits = 0;
+
+ if (!text) return index == 0 ? b : index == 1 ? c : index == 2 ? d : fallback;
+
+ while (index > 0 && *text) {
+ if (*text++ == '\t') index--;
+ }
+ if (index > 0) return fallback;
+ if (*text == '-') {
+ negative = 1;
+ text++;
+ }
+ while (*text >= '0' && *text <= '9' && digits < 9) {
+ value = value * 10 + (*text++ - '0');
+ digits++;
+ }
+ if (!digits) return fallback;
+ return (int)(negative ? -value : value);
+}
+
+
+static void fieldString(const char *text, int index, char *out, size_t size)
+{
+ size_t length = 0;
+
+ out[0] = '\0';
+ if (!text || size == 0) return;
+ while (index > 0 && *text) {
+ if (*text++ == '\t') index--;
+ }
+ if (index > 0) return;
+ while (text[length] && text[length] != '\t' && length < size - 1) {
+ out[length] = text[length];
+ length++;
+ }
+ out[length] = '\0';
+}
+
+static int place(kon_rm_t *rm, int type, int value)
+{
+ if (type == 1) return rm->variable ? rm->variable(value, rm->user) : 0;
+ return value;
+}
+
+static int picture(kon_rm_t *rm, int code, int b, int c, int d, const char *text)
+{
+ kon_pictures_t *p = rm->pictures;
+ char name[KON_PICTURE_NAME];
+ int id = fieldInt(b, c, d, text, 0, 0);
+ int origin, type, x, y, scaleX, scaleY, opacity, blend, frames, wait;
+
+ if (!p) return -1;
+ switch (code) {
+ case 231:
+ fieldString(text, 1, name, sizeof name);
+ origin = fieldInt(b, c, d, text, 2, 0);
+ type = fieldInt(b, c, d, text, 3, 0);
+ x = place(rm, type, fieldInt(b, c, d, text, 4, 0));
+ y = place(rm, type, fieldInt(b, c, d, text, 5, 0));
+ scaleX = fieldInt(b, c, d, text, 6, 100);
+ scaleY = fieldInt(b, c, d, text, 7, 100);
+ opacity = fieldInt(b, c, d, text, 8, 255);
+ blend = fieldInt(b, c, d, text, 9, 0);
+ kon_pictureShow(p, id, name, origin, x, y, scaleX, scaleY, opacity, blend);
+ return 0;
+ case 232:
+ origin = fieldInt(b, c, d, text, 2, 0);
+ type = fieldInt(b, c, d, text, 3, 0);
+ x = place(rm, type, fieldInt(b, c, d, text, 4, 0));
+ y = place(rm, type, fieldInt(b, c, d, text, 5, 0));
+ scaleX = fieldInt(b, c, d, text, 6, 100);
+ scaleY = fieldInt(b, c, d, text, 7, 100);
+ opacity = fieldInt(b, c, d, text, 8, 255);
+ blend = fieldInt(b, c, d, text, 9, 0);
+ frames = fieldInt(b, c, d, text, 10, 0);
+ wait = fieldInt(b, c, d, text, 11, 0);
+ kon_pictureMove(p, id, origin, x, y, scaleX, scaleY, opacity, blend, frames, fieldInt(b, c, d, text, 12, 0));
+ return wait && frames > 0;
+ case 233:
+ kon_pictureRotate(p, id, fieldInt(b, c, d, text, 1, 0));
+ return 0;
+ case 234:
+ frames = fieldInt(b, c, d, text, 5, 0);
+ wait = fieldInt(b, c, d, text, 6, 0);
+ kon_pictureTint(p, id, fieldInt(b, c, d, text, 1, 0), fieldInt(b, c, d, text, 2, 0), fieldInt(b, c, d, text, 3, 0), fieldInt(b, c, d, text, 4, 0), frames);
+ return wait && frames > 0;
+ case 235:
+ kon_pictureErase(p, id);
+ return 0;
+ default:
+ return -1;
+ }
+}
+
+#endif
+
+/*** commands ***/
+
+int kon_rmHost(kon_rm_t *rm, int code, int b, int c, int d, const char *text)
+{
+ if (!rm) return -1;
+
+#ifdef KON_MODULE_FX
+ if (code >= 221 && code <= 225) return rm->fx ? kon_screenfxHost(rm->fx, code, b, c, d, text) : -1;
+#endif
+#ifdef KON_MODULE_PICTURE
+ if (code >= 231 && code <= 235) return picture(rm, code, b, c, d, text);
+#endif
+#ifdef KON_MODULE_SOUND
+ if (rm->sound && kon_soundHost(rm->sound, code, b, c, d, text)) return 0;
+#endif
+
+ (void)code;
+ (void)b;
+ (void)c;
+ (void)d;
+ (void)text;
+ return -1;
+}
+
+int kon_rmBusy(const kon_rm_t *rm)
+{
+ if (!rm) return 0;
+#ifdef KON_MODULE_FX
+ if (rm->fx && kon_screenfxBusy(rm->fx)) return 1;
+#endif
+#ifdef KON_MODULE_PICTURE
+ if (rm->pictures && kon_picturesBusy(rm->pictures)) return 1;
+#endif
+ return 0;
+}
diff --git a/kon/konrm.h b/kon/konrm.h
new file mode 100644
index 0000000..edbae6d
--- /dev/null
+++ b/kon/konrm.h
@@ -0,0 +1,56 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * konrm.h
+ *
+ * Copyright (c) 2026 KonAki
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef KONRM_H
+#define KONRM_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*** definition ***/
+
+/* one place to send the RPG Maker commands that mzscript writes as host commands. it hands each to the module that knows
+ it: sound (241 to 251), screen effects (221 to 225) and pictures (231 to 235). what you did not build or did not give
+ is skipped, so the command is just not handled. the structs are yours, this only points to them */
+typedef struct kon_rm {
+ struct kon_soundDeck *sound;
+ struct kon_pictures *pictures;
+ struct kon_screenfx *fx;
+ int (*variable)(int id, void *user); /* for pictures placed by variables, NULL reads them as 0 */
+ void *user;
+} kon_rm_t;
+
+/* call this from your host function with what the command gives you. returns -1 when the code is not one of these,
+ 0 when it is done and 1 when the script should wait. a wait is over when kon_rmBusy says 0, then kon_scriptResume */
+int kon_rmHost(kon_rm_t *rm, int code, int b, int c, int d, const char *text);
+
+/* 1 while a screen effect or a picture is still changing */
+int kon_rmBusy(const kon_rm_t *rm);
+
+#ifdef __cplusplus
+}
+#endif
+#endif