1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
|
/* mode.c - handle the program's modes in a consistent way
*
* Copyright (C) 2000 Jochen Voss. */
static const char rcsid[] = "$Id: mode.c 4839 2003-04-13 16:50:02Z voss $";
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdlib.h>
#include "moon-buggy.h"
#include "darray.h"
static const struct mode *current;
static int mode_entered, mode_seed;
struct mode *
new_mode (void)
/* Allocate a new mode struct. */
{
struct mode *res = xmalloc (sizeof (struct mode));
res->enter = NULL;
res->leave = NULL;
res->redraw = NULL;
DA_INIT (res->keys, struct binding);
res->keypress = NULL;
return res;
}
void
mode_add_key (struct mode *m, int meanings, const char *desc, int res)
/* Add a key binding to mode M.
* MEANINGS should a combination (via |) of `mbk_key' values, DESC is
* the label to display near the bottom of the screen. RES is passed
* through to `keypress' handler. */
{
struct binding *keys;
DA_ADD_EMPTY (m->keys, struct binding, keys);
keys->meanings = meanings;
keys->desc = desc;
keys->res = res;
}
void
mode_complete (struct mode *m)
/* This must be called at the very end of each mode's initialisation. */
{
mode_add_key (m, mbk_redraw, "redraw", 0);
}
void
mode_change (const struct mode *m, int seed)
/* Change into new mode M. Pass SEED to the `enter' handler. */
{
if (mode_entered && current->leave) current->leave ();
current = m;
mode_entered = 0;
mode_seed = seed;
}
static void
mode_enter (void)
{
werase (moon);
wnoutrefresh (moon);
if (! current) return;
if (current->enter) current->enter (mode_seed);
mode_entered = 1;
}
void
mode_update (void)
/* Flush queued mode updates. */
{
if (! mode_entered) {
clear_queue ();
mode_enter ();
mode_redraw ();
}
doupdate ();
}
void
mode_redraw (void)
/* Make the current mode redraw the screen but leave the status message intact.
* This is also called after the screen is resized. */
{
if (! mode_entered) return;
describe_keys (current->keys.used, current->keys.data);
if (current->redraw) current->redraw ();
doupdate ();
}
int
mode_keypress (game_time t, int meaning)
/* Feed a keypress with meaning MEANING to the current mode.
* Return 1 if the keypress could be processed, and 0 else. */
{
int i;
if (meaning == mbk_redraw) {
clear_windows ();
mode_redraw ();
return 1;
}
for (i=0; i<current->keys.used; ++i) {
if (current->keys.data[i].meanings & meaning) {
current->keypress (t, current->keys.data[i].res);
return 1;
}
}
return 0;
}
void
mode_signal (int signum)
/* Feed signal SIGNUM to the current mode. */
{
if (current->signal) current->signal (signum);
}
|