Implement mouse and keyboard input support

The popolytan demo now has a functional menu, albeit without text.
This commit is contained in:
Nunuhara Cabbage
2019-11-18 21:58:54 -08:00
parent 00c4e7bf1f
commit 419da7889c
6 changed files with 404 additions and 34 deletions
+28 -20
View File
@@ -43,19 +43,24 @@ static enum cg_type check_cgformat(uint8_t *data)
return ALCG_UNKNOWN;
}
void _cg_free(struct cg *cg)
{
if (!cg)
return;
if (cg->s) {
if (cg->no >= 0)
free(cg->s->pixels);
SDL_FreeSurface(cg->s);
}
}
/*
* Free CG data
* cg: object to free
*/
void cg_free(struct cg *cg)
{
if (!cg)
return;
if (cg->s) {
if (cg->no < 0)
free(cg->s->pixels);
SDL_FreeSurface(cg->s);
}
_cg_free(cg);
free(cg);
}
@@ -101,21 +106,24 @@ bool cg_load(struct cg *cg, int no)
return true;
}
void _cg_init(struct cg *cg, int width, int height, uint8_t r, uint8_t g, uint8_t b, uint8_t a)
{
cg->no = -1;
cg->rect.w = width;
cg->rect.h = height;
cg->color = (SDL_Color) { .r = r, .g = g, .b = b, .a = a };
cg->s = NULL;
}
void cg_reinit(struct cg *cg, int width, int height, uint8_t r, uint8_t g, uint8_t b, uint8_t a)
{
_cg_free(cg);
_cg_init(cg, width, height, r, g, b, a);
}
struct cg *cg_init(int width, int height, uint8_t r, uint8_t g, uint8_t b, uint8_t a)
{
struct cg *cg = calloc(1, sizeof(struct cg));
*cg = (struct cg) {
.no = -1,
.rect = {
.w = width,
.h = height
},
.color = {
.r = r,
.g = g,
.b = b,
.a = a
}
};
_cg_init(cg, width, height, r, g, b, a);
return cg;
}
+1
View File
@@ -51,6 +51,7 @@ struct cg {
bool cg_exists(int no);
bool cg_load(struct cg *cg, int no);
struct cg *cg_init(int width, int height, uint8_t r, uint8_t g, uint8_t b, uint8_t a);
void cg_reinit(struct cg *cg, int width, int height, uint8_t r, uint8_t g, uint8_t b, uint8_t a);
void cg_free(struct cg *cg);
#endif /* SYSTEM4_CG_H */
+26 -14
View File
@@ -20,6 +20,7 @@
#include "../system4.h"
#include "../vm.h"
#include "../cg.h"
#include "../input.h"
#include "../queue.h"
#include "../sdl_core.h"
@@ -83,6 +84,7 @@ hll_unimplemented(SACT2, GetMainSurfaceNumber)
// int Update(void)
hll_defun(Update, _)
{
handle_events();
struct SACT2_sprite *p;
TAILQ_FOREACH_REVERSE(p, &sprite_list, listhead, entry) {
if (!p->cg->show)
@@ -162,14 +164,13 @@ hll_defun(SP_Create, args)
int b = args[5].i;
int a = args[6].i;
if (sprites[sp].used) {
TAILQ_REMOVE(&sprite_list, &sprites[sp], entry);
cg_free(sprites[sp].cg);
if (sprites[sp].used && sprites[sp].cg) {
cg_reinit(sprites[sp].cg, width, height, r, g, b, a);
} else {
sprites[sp].used = true;
sprites[sp].cg = cg_init(width, height, r, g, b, a);
sprite_register(&sprites[sp]);
}
sprites[sp].used = true;
sprites[sp].cg = cg_init(width, height, r, g, b, a);
sprite_register(&sprites[sp]);
hll_return(1);
}
@@ -319,8 +320,18 @@ hll_unimplemented(SACT2, SP_GetTextPosY)
hll_unimplemented(SACT2, SP_GetTextLineSpace)
// int SP_IsPtIn(int nSP, int nX, int nY)
hll_unimplemented(SACT2, SP_IsPtIn)
// int SP_IsPtInRect(int nSP, int nX, int nY)
hll_unimplemented(SACT2, SP_IsPtInRect)
hll_defun(SP_IsPtInRect, args)
{
struct SACT2_sprite *sp = &sprites[args[0].i];
Point p = { .x = args[1].i, .y = args[2].i };
if (!sp->used)
hll_return(0);
hll_return(!!SDL_PointInRect(&p, &sp->cg->rect));
}
// int GAME_MSG_GetNumof(void)
hll_unimplemented(SACT2, GAME_MSG_GetNumof)
// void GAME_MSG_Get(int nIndex, ref string text)
@@ -335,14 +346,12 @@ hll_unimplemented(SACT2, StringPopFront)
// int Mouse_GetPos(ref int pnX, ref int pnY)
hll_defun(Mouse_GetPos, args)
{
hll_unimplemented_warning(SACT2, Mouse_GetPos);
*args[0].iref = 0;
*args[1].iref = 0;
hll_return(0);
mouse_get_pos(args[0].iref, args[1].iref);
hll_return(mouse_focus && keyboard_focus);
}
// int Mouse_SetPos(int nX, int nY)
hll_unimplemented(SACT2, Mouse_SetPos)
hll_warn_unimplemented(SACT2, Mouse_SetPos, 1)
// void Mouse_ClearWheel(void)
hll_warn_unimplemented(SACT2, Mouse_ClearWheel, 0)
@@ -388,7 +397,10 @@ hll_defun(Joypad_GetDigitalStickStatus, args)
hll_warn_unimplemented(SACT2, Key_ClearFlag, 1)
// int Key_IsDown(int nKeyCode)
hll_warn_unimplemented(SACT2, Key_IsDown, 0)
hll_defun(Key_IsDown, args)
{
hll_return(key_is_down(args[0].i));
}
// int Timer_Get(void)
hll_defun(Timer_Get, _)
+204
View File
@@ -0,0 +1,204 @@
/* Copyright (C) 2019 Nunuhara Cabbage <nunuhara@haniwa.technology>
*
* 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 <SDL.h>
#include "system4.h"
#include "sdl_private.h"
#include "input.h"
bool key_state[VK_NR_KEYCODES];
static enum sact_keycode sdl_keytable[];
bool mouse_focus = true;
bool keyboard_focus = true;
static SDL_Scancode sact_to_sdl_button(enum sact_keycode code)
{
switch (code) {
case VK_LBUTTON: return SDL_BUTTON_LEFT;
case VK_RBUTTON: return SDL_BUTTON_RIGHT;
case VK_MBUTTON: return SDL_BUTTON_MIDDLE;
default: return 0;
}
}
bool key_is_down(enum sact_keycode code)
{
int button = sact_to_sdl_button(code);
if (button)
return SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(button);
return key_state[code];
}
static void key_event(SDL_KeyboardEvent *e, bool pressed)
{
enum sact_keycode code = sdl_keytable[e->keysym.scancode];
if (code)
key_state[code] = pressed;
}
void mouse_get_pos(int *x, int *y)
{
SDL_GetMouseState(x, y);
}
void handle_events(void)
{
SDL_Event e;
while (SDL_PollEvent(&e)) {
switch (e.type) {
case SDL_QUIT:
sys_exit(0);
break;
case SDL_WINDOWEVENT:
switch (e.window.event) {
case SDL_WINDOWEVENT_EXPOSED:
sdl.dirty = true;
break;
case SDL_WINDOWEVENT_ENTER:
mouse_focus = true;
break;
case SDL_WINDOWEVENT_LEAVE:
mouse_focus = false;
break;
case SDL_WINDOWEVENT_FOCUS_GAINED:
keyboard_focus = true;
break;
case SDL_WINDOWEVENT_FOCUS_LOST:
keyboard_focus = false;
break;
}
break;
case SDL_KEYDOWN:
key_event(&e.key, true);
break;
case SDL_KEYUP:
key_event(&e.key, false);
break;
default:
break;
}
}
}
static enum sact_keycode sdl_keytable[] = {
[SDL_SCANCODE_0] = VK_0,
[SDL_SCANCODE_1] = VK_1,
[SDL_SCANCODE_2] = VK_2,
[SDL_SCANCODE_3] = VK_3,
[SDL_SCANCODE_4] = VK_4,
[SDL_SCANCODE_5] = VK_5,
[SDL_SCANCODE_6] = VK_6,
[SDL_SCANCODE_7] = VK_7,
[SDL_SCANCODE_8] = VK_8,
[SDL_SCANCODE_9] = VK_9,
[SDL_SCANCODE_A] = VK_A,
[SDL_SCANCODE_B] = VK_B,
[SDL_SCANCODE_C] = VK_C,
[SDL_SCANCODE_D] = VK_D,
[SDL_SCANCODE_E] = VK_E,
[SDL_SCANCODE_F] = VK_F,
[SDL_SCANCODE_G] = VK_G,
[SDL_SCANCODE_H] = VK_H,
[SDL_SCANCODE_I] = VK_I,
[SDL_SCANCODE_J] = VK_J,
[SDL_SCANCODE_K] = VK_K,
[SDL_SCANCODE_L] = VK_L,
[SDL_SCANCODE_M] = VK_M,
[SDL_SCANCODE_N] = VK_N,
[SDL_SCANCODE_O] = VK_O,
[SDL_SCANCODE_P] = VK_P,
[SDL_SCANCODE_Q] = VK_Q,
[SDL_SCANCODE_R] = VK_R,
[SDL_SCANCODE_S] = VK_S,
[SDL_SCANCODE_T] = VK_T,
[SDL_SCANCODE_U] = VK_U,
[SDL_SCANCODE_V] = VK_V,
[SDL_SCANCODE_W] = VK_W,
[SDL_SCANCODE_X] = VK_X,
[SDL_SCANCODE_Y] = VK_Y,
[SDL_SCANCODE_Z] = VK_Z,
[SDL_SCANCODE_BACKSPACE] = VK_BACK,
[SDL_SCANCODE_TAB] = VK_TAB,
[SDL_SCANCODE_CLEAR] = VK_CLEAR,
[SDL_SCANCODE_RETURN] = VK_RETURN,
[SDL_SCANCODE_LSHIFT] = VK_SHIFT,
[SDL_SCANCODE_RSHIFT] = VK_SHIFT,
[SDL_SCANCODE_LCTRL] = VK_CONTROL,
[SDL_SCANCODE_RCTRL] = VK_CONTROL,
[SDL_SCANCODE_LALT] = VK_MENU,
[SDL_SCANCODE_RALT] = VK_MENU,
[SDL_SCANCODE_PAUSE] = VK_PAUSE,
[SDL_SCANCODE_CAPSLOCK] = VK_CAPITAL,
[SDL_SCANCODE_ESCAPE] = VK_ESCAPE,
[SDL_SCANCODE_SPACE] = VK_SPACE,
[SDL_SCANCODE_PAGEUP] = VK_PRIOR,
[SDL_SCANCODE_PAGEDOWN] = VK_NEXT,
[SDL_SCANCODE_END] = VK_END,
[SDL_SCANCODE_HOME] = VK_HOME,
[SDL_SCANCODE_LEFT] = VK_LEFT,
[SDL_SCANCODE_UP] = VK_UP,
[SDL_SCANCODE_RIGHT] = VK_RIGHT,
[SDL_SCANCODE_DOWN] = VK_DOWN,
[SDL_SCANCODE_SELECT] = VK_SELECT,
[SDL_SCANCODE_EXECUTE] = VK_EXECUTE,
[SDL_SCANCODE_PRINTSCREEN] = VK_SNAPSHOT,
[SDL_SCANCODE_INSERT] = VK_INSERT,
[SDL_SCANCODE_DELETE] = VK_DELETE,
[SDL_SCANCODE_HELP] = VK_HELP,
[SDL_SCANCODE_KP_0] = VK_NUMPAD0,
[SDL_SCANCODE_KP_1] = VK_NUMPAD1,
[SDL_SCANCODE_KP_2] = VK_NUMPAD2,
[SDL_SCANCODE_KP_3] = VK_NUMPAD3,
[SDL_SCANCODE_KP_4] = VK_NUMPAD4,
[SDL_SCANCODE_KP_5] = VK_NUMPAD5,
[SDL_SCANCODE_KP_6] = VK_NUMPAD6,
[SDL_SCANCODE_KP_7] = VK_NUMPAD7,
[SDL_SCANCODE_KP_8] = VK_NUMPAD8,
[SDL_SCANCODE_KP_9] = VK_NUMPAD9,
[SDL_SCANCODE_KP_MULTIPLY] = VK_MULTIPLY,
[SDL_SCANCODE_KP_PLUS] = VK_ADD,
[SDL_SCANCODE_KP_VERTICALBAR] = VK_SEPARATOR, // ???
[SDL_SCANCODE_KP_MINUS] = VK_SUBTRACT,
[SDL_SCANCODE_KP_PERIOD] = VK_DECIMAL,
[SDL_SCANCODE_KP_DIVIDE] = VK_DIVIDE,
[SDL_SCANCODE_F1] = VK_F1,
[SDL_SCANCODE_F2] = VK_F2,
[SDL_SCANCODE_F3] = VK_F3,
[SDL_SCANCODE_F4] = VK_F4,
[SDL_SCANCODE_F5] = VK_F5,
[SDL_SCANCODE_F6] = VK_F6,
[SDL_SCANCODE_F7] = VK_F7,
[SDL_SCANCODE_F8] = VK_F8,
[SDL_SCANCODE_F9] = VK_F9,
[SDL_SCANCODE_F10] = VK_F10,
[SDL_SCANCODE_F11] = VK_F11,
[SDL_SCANCODE_F12] = VK_F12,
[SDL_SCANCODE_F13] = VK_F13,
[SDL_SCANCODE_F14] = VK_F14,
[SDL_SCANCODE_F15] = VK_F15,
[SDL_SCANCODE_F16] = VK_F16,
[SDL_SCANCODE_F17] = VK_F17,
[SDL_SCANCODE_F18] = VK_F18,
[SDL_SCANCODE_F19] = VK_F19,
[SDL_SCANCODE_F20] = VK_F20,
[SDL_SCANCODE_F21] = VK_F21,
[SDL_SCANCODE_F22] = VK_F22,
[SDL_SCANCODE_F23] = VK_F23,
[SDL_SCANCODE_F24] = VK_F24,
[SDL_SCANCODE_NUMLOCKCLEAR] = VK_NUMLOCK,
[SDL_SCANCODE_SCROLLLOCK] = VK_SCROLL,
};
+144
View File
@@ -0,0 +1,144 @@
/* Copyright (C) 2019 Nunuhara Cabbage <nunuhara@haniwa.technology>
*
* 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/>.
*/
#ifndef SYSTEM4_INPUT_H
#define SYSTEM4_INPUT_H
#include <stdbool.h>
#include <stdint.h>
enum sact_keycode {
VK_LBUTTON = 0x01, // マウスの左ボタン
VK_RBUTTON = 0x02, // マウスの右ボタン
VK_MBUTTON = 0x04, // マウスの中央ボタンもしくはホイールクリック
VK_BACK = 0x08, // Backspace
VK_TAB = 0x09, // Tab
VK_CLEAR = 0x0c, // Clear(不明)
VK_RETURN = 0x0d, // Enter
VK_SHIFT = 0x10, // Shift
VK_CONTROL = 0x11, // Ctrl
VK_MENU = 0x12, // Alt([Alt]+[何か]の形でシステムが使用するので、通常は使用不可)
VK_PAUSE = 0x13, // Pause(通常は使用不可)
VK_CAPITAL = 0x14, // CapsLock(通常は使用不可)
VK_KANA = 0x15, // 英数カナ(不明)
VK_KANJI = 0x19, // (不明)
VK_ESCAPE = 0x1b, // Esc
VK_CONVERT = 0x1c, // (不明)
VK_NOCONVERT = 0x1d, // (不明)
VK_SPACE = 0x20, // space
VK_PRIOR = 0x21, // PageUp
VK_NEXT = 0x22, // PageDown
VK_END = 0x23, // End
VK_HOME = 0x24, // Home
VK_LEFT = 0x25, // ←
VK_UP = 0x26, // ↑
VK_RIGHT = 0x27, // →
VK_DOWN = 0x28, // ↓
VK_SELECT = 0x29, // Select(不明)
VK_EXECUTE = 0x2B, // Execute(不明)
VK_SNAPSHOT = 0x2C, // PrintScrn(使用不可)
VK_INSERT = 0x2D, // Insert,Ins
VK_DELETE = 0x2E, // Delete,Del
VK_HELP = 0x2F, // Help(不明)
VK_0 = 0x30, // テンキーはVK_NUMPAD0
VK_1 = 0x31, // テンキーはVK_NUMPAD1
VK_2 = 0x32, // テンキーはVK_NUMPAD2
VK_3 = 0x33, // テンキーはVK_NUMPAD3
VK_4 = 0x34, // テンキーはVK_NUMPAD4
VK_5 = 0x35, // テンキーはVK_NUMPAD5
VK_6 = 0x36, // テンキーはVK_NUMPAD6
VK_7 = 0x37, // テンキーはVK_NUMPAD7
VK_8 = 0x38, // テンキーはVK_NUMPAD8
VK_9 = 0x39, // テンキーはVK_NUMPAD9
VK_A = 0x41, // 'A'で代用可
VK_B = 0x42, // 'B'で代用可
VK_C = 0x43, // 'C'で代用可
VK_D = 0x44, // 'D'で代用可
VK_E = 0x45, // 'E'で代用可
VK_F = 0x46, // 'F'で代用可
VK_G = 0x47, // 'G'で代用可
VK_H = 0x48, // 'H'で代用可
VK_I = 0x49, // 'I'で代用可
VK_J = 0x4a, // 'J'で代用可
VK_K = 0x4b, // 'K'で代用可
VK_L = 0x4c, // 'L'で代用可
VK_M = 0x4d, // 'M'で代用可
VK_N = 0x4e, // 'N'で代用可
VK_O = 0x4f, // 'O'で代用可
VK_P = 0x50, // 'P'で代用可
VK_Q = 0x51, // 'Q'で代用可
VK_R = 0x52, // 'R'で代用可
VK_S = 0x53, // 'S'で代用可
VK_T = 0x54, // 'T'で代用可
VK_U = 0x55, // 'U'で代用可
VK_V = 0x56, // 'V'で代用可
VK_W = 0x57, // 'W'で代用可
VK_X = 0x58, // 'X'で代用可
VK_Y = 0x59, // 'Y'で代用可
VK_Z = 0x5a, // 'Z'で代用可
VK_NUMPAD0 = 0x60, // テンキーの0
VK_NUMPAD1 = 0x61, // テンキーの1
VK_NUMPAD2 = 0x62, // テンキーの2
VK_NUMPAD3 = 0x63, // テンキーの3
VK_NUMPAD4 = 0x64, // テンキーの4
VK_NUMPAD5 = 0x65, // テンキーの5
VK_NUMPAD6 = 0x66, // テンキーの6
VK_NUMPAD7 = 0x67, // テンキーの7
VK_NUMPAD8 = 0x68, // テンキーの8
VK_NUMPAD9 = 0x69, // テンキーの9
VK_MULTIPLY = 0x6a, // テンキーの*
VK_ADD = 0x6b, // テンキーの+
VK_SEPARATOR = 0x6c, // Separator(不明)
VK_SUBTRACT = 0x6d, // テンキーの-
VK_DECIMAL = 0x6e, // テンキーの.
VK_DIVIDE = 0x6f, // テンキーの/
VK_F1 = 0x70, // F1
VK_F2 = 0x71, // F2
VK_F3 = 0x72, // F3
VK_F4 = 0x73, // F4
VK_F5 = 0x74, // F5
VK_F6 = 0x75, // F6
VK_F7 = 0x76, // F7
VK_F8 = 0x77, // F8
VK_F9 = 0x78, // F9
VK_F10 = 0x79, // F10(使用不可)
VK_F11 = 0x7A, // F11
VK_F12 = 0x7B, // F12
VK_F13 = 0x7C, // F13
VK_F14 = 0x7D, // F14
VK_F15 = 0x7E, // F15
VK_F16 = 0x7F, // F16
VK_F17 = 0x80, // F17
VK_F18 = 0x81, // F18
VK_F19 = 0x82, // F19
VK_F20 = 0x83, // F20
VK_F21 = 0x84, // F21
VK_F22 = 0x85, // F22
VK_F23 = 0x86, // F23
VK_F24 = 0x87, // F24
VK_NUMLOCK = 0x90, // NumLock(通常は使用不可)
VK_SCROLL = 0x91, // ScrollLock(通常は使用不可)
VK_NR_KEYCODES
};
bool mouse_focus;
bool keyboard_focus;
void handle_events(void);
bool key_is_down(enum sact_keycode code);
void mouse_get_pos(int *x, int *y);
#endif /* SYSTEM4_INPUT_H */
+1
View File
@@ -10,6 +10,7 @@ xsystem4 = ['ald.c',
'cg.c',
'qnt.c',
'ini.c',
'input.c',
'page.c',
'sdl_draw.c',
'sdl_video.c',