File: mode.c

package info (click to toggle)
moon-buggy 1%3A1.0.51-15
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 1,316 kB
  • sloc: ansic: 3,824; sh: 3,567; makefile: 162
file content (130 lines) | stat: -rw-r--r-- 2,721 bytes parent folder | download | duplicates (4)
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);
}