From 0d74a3b686b63d7df48c4d8b874ddb96fa57fa13 Mon Sep 17 00:00:00 2001 From: Nunuhara Cabbage Date: Sun, 8 Mar 2020 17:09:55 -0700 Subject: [PATCH] Partial MsgLogManager/MsgLogViewer implementation Enough to get the message log in Sengoku Rance working. --- include/input.h | 2 + src/ffi.c | 2 + src/hll/MsgLogManager.c | 61 ++++++++++++++++++++-- src/hll/MsgLogManager.h | 36 +++++++++++++ src/hll/MsgLogViewer.c | 110 ++++++++++++++++++++++++++++++++++++++++ src/hll/SACT2.c | 6 +-- src/input.c | 17 +++++++ src/meson.build | 1 + 8 files changed, 228 insertions(+), 7 deletions(-) create mode 100644 src/hll/MsgLogManager.h create mode 100644 src/hll/MsgLogViewer.c diff --git a/include/input.h b/include/input.h index 3c77d8b..6899317 100644 --- a/include/input.h +++ b/include/input.h @@ -141,5 +141,7 @@ void handle_events(void); bool key_is_down(enum sact_keycode code); void key_clear_flag(void); void mouse_get_pos(int *x, int *y); +void mouse_get_wheel(int *forward, int *back); +void mouse_clear_wheel(void); #endif /* SYSTEM4_INPUT_H */ diff --git a/src/ffi.c b/src/ffi.c index bd24746..7e6c9d9 100644 --- a/src/ffi.c +++ b/src/ffi.c @@ -141,6 +141,7 @@ extern struct static_library lib_DrawPluginManager; extern struct static_library lib_File; extern struct static_library lib_Math; extern struct static_library lib_MsgLogManager; +extern struct static_library lib_MsgLogViewer; extern struct static_library lib_MsgSkip; extern struct static_library lib_OutputLog; extern struct static_library lib_PlayMovie; @@ -158,6 +159,7 @@ static struct static_library *static_libraries[] = { &lib_File, &lib_Math, &lib_MsgLogManager, + &lib_MsgLogViewer, &lib_MsgSkip, &lib_OutputLog, &lib_PlayMovie, diff --git a/src/hll/MsgLogManager.c b/src/hll/MsgLogManager.c index a2b1d66..b2b30ee 100644 --- a/src/hll/MsgLogManager.c +++ b/src/hll/MsgLogManager.c @@ -14,11 +14,66 @@ * along with this program; if not, see . */ +#include +#include +#include "system4.h" +#include "system4/string.h" #include "hll.h" +#include "MsgLogManager.h" + +static size_t msg_log_size = 0; +static size_t msg_log_i = 0; +struct msg_log_entry *msg_log = NULL; + +#define LOG_MAX 2048 + +static void msg_log_alloc(void) +{ + if (msg_log_i < msg_log_size) + return; + if (!msg_log_size) + msg_log_size = 1; + + // rotate log + if (msg_log_i >= LOG_MAX) { + for (size_t i = 0; i < msg_log_i - LOG_MAX/2; i++) { + if (msg_log[i].data_type == MSG_LOG_STRING) + free_string(msg_log[i].s); + } + memcpy(msg_log, msg_log + (msg_log_i - LOG_MAX/2), sizeof(struct msg_log_entry) * LOG_MAX/2); + msg_log_i = LOG_MAX/2; + return; + } + + msg_log = xrealloc(msg_log, sizeof(struct msg_log_entry) * msg_log_size * 2); + msg_log_size *= 2; +} + +int MsgLogManager_Numof(void) +{ + return msg_log_i; +} + +static void MsgLogManager_AddInt(int type, int value) +{ + msg_log_alloc(); + msg_log[msg_log_i++] = (struct msg_log_entry) { + .data_type = MSG_LOG_INT, + .type = type, + .i = value + }; +} + +static void MsgLogManager_AddString(int type, struct string *str) +{ + msg_log_alloc(); + msg_log[msg_log_i++] = (struct msg_log_entry) { + .data_type = MSG_LOG_STRING, + .type = type, + .s = string_ref(str) + }; +} -HLL_WARN_UNIMPLEMENTED(0, int, MsgLogManager, Numof, void); -HLL_WARN_UNIMPLEMENTED( , void, MsgLogManager, AddInt, int type, int value); -HLL_WARN_UNIMPLEMENTED( , void, MsgLogManager, AddString, int type, struct string *str); HLL_WARN_UNIMPLEMENTED(0, int, MsgLogManager, GetType, int index); HLL_WARN_UNIMPLEMENTED(0, int, MsgLogManager, GetInt, int index); HLL_WARN_UNIMPLEMENTED( , void, MsgLogManager, GetString, int index, struct string **str); diff --git a/src/hll/MsgLogManager.h b/src/hll/MsgLogManager.h new file mode 100644 index 0000000..c3e47ff --- /dev/null +++ b/src/hll/MsgLogManager.h @@ -0,0 +1,36 @@ +/* Copyright (C) 2019 Nunuhara Cabbage + * + * 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 . + */ + +#ifndef SYSTEM4_MSGLOGMANAGER_H +#define SYSTEM4_MSGLOGMANAGER_H + +enum msg_data_type { + MSG_LOG_INT, + MSG_LOG_STRING +}; + +struct msg_log_entry { + enum msg_data_type data_type; + int type; + union { + int i; + struct string *s; + }; +}; + +struct msg_log_entry *msg_log; + +#endif /* SYSTEM4_MSGLOGMANAGER_H */ diff --git a/src/hll/MsgLogViewer.c b/src/hll/MsgLogViewer.c new file mode 100644 index 0000000..5415cd5 --- /dev/null +++ b/src/hll/MsgLogViewer.c @@ -0,0 +1,110 @@ +/* Copyright (C) 2019 Nunuhara Cabbage + * + * 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 . + */ + +#include +#include "vm.h" +#include "vm/page.h" +#include "system4/string.h" +#include "hll.h" +#include "MsgLogManager.h" + +struct log_data { + struct string *text; + int voice; + int separator; +}; + +static size_t log_viewer_size = 0; +static size_t log_viewer_i = 0; +static struct log_data *log_viewer = NULL; + +int MsgLogViewer_Numof(void) +{ + return log_viewer_i; +} + +void MsgLogViewer_Clear(void) +{ + for (size_t i = 0; i < log_viewer_i; i++) { + free_string(log_viewer[i].text); + } + free(log_viewer); + log_viewer = NULL; + log_viewer_size = 0; + log_viewer_i = 0; +} + +HLL_WARN_UNIMPLEMENTED( , void, MsgLogViewer, Add, struct page *log); + +void MsgLogViewer_Get(int index, struct page **log) +{ + // ??? + if ((size_t)index >= log_viewer_i) { + (*log)->values[0].i = vm_string_ref(&EMPTY_STRING); + (*log)->values[1].i = 0; + (*log)->values[2].i = 0; + return; + } + + (*log)->values[0].i = vm_string_ref(log_viewer[index].text); + (*log)->values[1].i = 0; + (*log)->values[2].i = 0; +} + +static void log_viewer_alloc(void) +{ + if (log_viewer_i < log_viewer_size) + return; + if (!log_viewer_size) + log_viewer_size = 128; + log_viewer = xrealloc(log_viewer, sizeof(struct log_data) * log_viewer_size * 2); +} + +static void log_viewer_push(struct string *s, int voice, int separator) +{ + log_viewer_alloc(); + log_viewer[log_viewer_i++] = (struct log_data) { + .text = string_ref(s), + .voice = voice, + .separator = separator + }; +} + +int MsgLogManager_Numof(void); + +void MsgLogViewer_ConvertFromMsgLogManager(possibly_unused int msg_log_manager) +{ + int log_size = MsgLogManager_Numof(); + MsgLogViewer_Clear(); + + for (int i = 0; i < log_size; i++) { + if (msg_log[i].data_type == MSG_LOG_INT) { + if (msg_log[i].type == 1102) { + log_viewer_push(&EMPTY_STRING, 0, 0); + } + } + if (msg_log[i].data_type == MSG_LOG_STRING) { + log_viewer_push(msg_log[i].s, 0, 0); + } + } +} + +HLL_LIBRARY(MsgLogViewer, + HLL_EXPORT(Numof, MsgLogViewer_Numof), + HLL_EXPORT(Clear, MsgLogViewer_Clear), + HLL_EXPORT(Add, MsgLogViewer_Add), + HLL_EXPORT(Get, MsgLogViewer_Get), + HLL_EXPORT(ConvertFromMsgLogManager, MsgLogViewer_ConvertFromMsgLogManager)); diff --git a/src/hll/SACT2.c b/src/hll/SACT2.c index 73d321b..f1dac1b 100644 --- a/src/hll/SACT2.c +++ b/src/hll/SACT2.c @@ -62,14 +62,12 @@ int sact_Mouse_GetPos(int *x, int *y) void sact_Mouse_ClearWheel(void) { - // TODO + mouse_clear_wheel(); } void sact_Mouse_GetWheel(int *forward, int *back) { - // TODO - *forward = 0; - *back = 0; + mouse_get_wheel(forward, back); } void sact_Joypad_ClearKeyDownFlag(int n) diff --git a/src/input.c b/src/input.c index 6699c9a..ad9e30b 100644 --- a/src/input.c +++ b/src/input.c @@ -14,6 +14,7 @@ * along with this program; if not, see . */ +#include #include #include "system4.h" #include "gfx/private.h" @@ -53,6 +54,19 @@ void mouse_get_pos(int *x, int *y) SDL_GetMouseState(x, y); } +static int wheel_dir = 0; + +void mouse_get_wheel(int *forward, int *back) +{ + *forward = wheel_dir > 0; + *back = wheel_dir < 0; +} + +void mouse_clear_wheel(void) +{ + wheel_dir = 0; +} + static void key_event(SDL_KeyboardEvent *e, bool pressed) { enum sact_keycode code = sdl_keytable[e->keysym.scancode]; @@ -106,6 +120,9 @@ void handle_events(void) case SDL_MOUSEBUTTONDOWN: mouse_event(&e.button); break; + case SDL_MOUSEWHEEL: + wheel_dir = e.wheel.y; + break; default: break; } diff --git a/src/meson.build b/src/meson.build index 0c2bef3..80a93ec 100644 --- a/src/meson.build +++ b/src/meson.build @@ -45,6 +45,7 @@ xsystem4 = ['audio.c', 'hll/File.c', 'hll/Math.c', 'hll/MsgLogManager.c', + 'hll/MsgLogViewer.c', 'hll/MsgSkip.c', 'hll/OutputLog.c', 'hll/PlayMovie.c',