diff options
| author | KonAki <konaki@anokonaki.org> | 2026-10-14 18:55:24 +0800 |
|---|---|---|
| committer | KonAki <konaki@anokonaki.org> | 2026-10-14 18:55:24 +0800 |
| commit | ae3e03e0c5663fe4e59c136115090f4777e63282 (patch) | |
| tree | f41e773ffac4341f0c987017d2a9437bcae8f58d | |
| parent | ac3f5875c373ade26547fecb7ad2e2a53003aabc (diff) | |
add rm module: one host function for the RPG Maker commands
| -rw-r--r-- | kon/konrm.c | 176 | ||||
| -rw-r--r-- | kon/konrm.h | 56 |
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 |
