Files
nunuhara_xsystem4/src/parts/input.c
T
Nunuhara Cabbage 7e04db958b parts: implement more ConstructionProcess ops
Implement Create, CreatePixelOnly, DrawText and CopyText operations.
2022-06-10 15:28:08 -07:00

179 lines
4.3 KiB
C

/* 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 "system4.h"
#include "asset_manager.h"
#include "audio.h"
#include "input.h"
#include "xsystem4.h"
#include "parts_internal.h"
// the mouse position at last update
Point parts_prev_pos = {0};
// true between calls to BeginClick and EndClick
bool parts_began_click = false;
// true when the left mouse button was down last update
static bool prev_clicking = false;
// the last (fully) clicked parts number
static int clicked_parts = 0;
// the current (partially) clicked parts number
static int click_down_parts = 0;
static void parts_update_mouse(struct parts *parts, Point cur_pos, bool cur_clicking)
{
bool prev_in = SDL_PointInRect(&parts_prev_pos, &parts->pos);
bool cur_in = SDL_PointInRect(&cur_pos, &parts->pos);
if (parts->linked_from >= 0 && cur_in != prev_in) {
parts_dirty(parts_get(parts->linked_from));
}
if (!parts_began_click || !parts->clickable)
return;
if (!cur_in) {
parts_set_state(parts, PARTS_STATE_DEFAULT);
return;
}
// click down: just remember the parts number for later
if (cur_clicking && !prev_clicking) {
click_down_parts = parts->no;
}
if (cur_clicking && click_down_parts == parts->no) {
parts_set_state(parts, PARTS_STATE_CLICKED);
} else {
if (!prev_in) {
audio_play_sound(parts->on_cursor_sound);
}
parts_set_state(parts, PARTS_STATE_HOVERED);
}
// click event: only if the click down event had same parts number
if (prev_clicking && !cur_clicking && click_down_parts == parts->no) {
audio_play_sound(parts->on_click_sound);
clicked_parts = parts->no;
}
}
void PE_UpdateInputState(possibly_unused int passed_time)
{
Point cur_pos;
bool cur_clicking = key_is_down(VK_LBUTTON);
mouse_get_pos(&cur_pos.x, &cur_pos.y);
struct parts *parts;
TAILQ_FOREACH(parts, &parts_list, parts_list_entry) {
parts_update_mouse(parts, cur_pos, cur_clicking);
}
if (prev_clicking && !cur_clicking) {
if (!click_down_parts) {
// TODO: play misclick sound
}
click_down_parts = 0;
}
prev_clicking = cur_clicking;
parts_prev_pos = cur_pos;
}
void PE_SetClickable(int parts_no, bool clickable)
{
parts_get(parts_no)->clickable = !!clickable;
}
bool PE_GetPartsClickable(int parts_no)
{
return parts_get(parts_no)->clickable;
}
void PE_SetPartsGroupDecideOnCursor(possibly_unused int GroupNumber, possibly_unused bool DecideOnCursor)
{
// TODO
}
void PE_SetPartsGroupDecideClick(possibly_unused int GroupNumber, possibly_unused bool DecideClick)
{
// TODO
}
void PE_SetOnCursorShowLinkPartsNumber(int parts_no, int link_parts_no)
{
struct parts *parts = parts_get(parts_no);
struct parts *link_parts = parts_get(link_parts_no);
parts->linked_to = link_parts_no;
link_parts->linked_from = parts_no;
}
bool PE_SetPartsOnCursorSoundNumber(int parts_no, int sound_no)
{
if (!asset_exists(ASSET_SOUND, sound_no)) {
WARNING("Invalid sound number: %d", sound_no);
return false;
}
struct parts *parts = parts_get(parts_no);
parts->on_cursor_sound = sound_no;
return true;
}
bool PE_SetPartsClickSoundNumber(int parts_no, int sound_no)
{
if (!asset_exists(ASSET_SOUND, sound_no)) {
WARNING("Invalid sound number: %d", sound_no);
return false;
}
struct parts *parts = parts_get(parts_no);
parts->on_click_sound = sound_no;
return true;
}
bool PE_SetClickMissSoundNumber(possibly_unused int sound_no)
{
// TODO
return true;
}
void PE_BeginInput(void)
{
parts_began_click = true;
}
void PE_EndInput(void)
{
parts_began_click = false;
clicked_parts = 0;
}
int PE_GetClickPartsNumber(void)
{
return clicked_parts;
}
bool PE_IsCursorIn(int parts_no, int mouse_x, int mouse_y, int state)
{
if (!parts_state_valid(--state))
return false;
// TODO
return false;
}