!makefile vc Makefile.vc
!makefile cygwin Makefile.cyg
-WINDOWS = windows user32.lib gdi32.lib
+WINDOWS = windows user32.lib gdi32.lib comctl32.lib
COMMON = midend misc malloc
NET = net random tree234
state->previous = state->current;
state->angle = 0.0;
- state->completed = FALSE;
+ state->completed = 0;
state->movecount = 0;
return state;
if (ret->facecolours[i])
j++;
if (j == ret->solid->nfaces)
- ret->completed = TRUE;
+ ret->completed = ret->movecount;
}
sfree(poly);
draw_update(fe, 0, 0, (int)((bb.r-bb.l+2.0F) * GRID_SCALE),
(int)((bb.d-bb.u+2.0F) * GRID_SCALE));
+
+ /*
+ * Update the status bar.
+ */
+ {
+ char statusbuf[256];
+
+ sprintf(statusbuf, "%sMoves: %d",
+ (state->completed ? "COMPLETED! " : ""),
+ (state->completed ? state->completed : state->movecount));
+
+ status_bar(fe, statusbuf);
+ }
}
float game_anim_length(game_state *oldstate, game_state *newstate)
{
return 0.0F;
}
+
+int game_wants_statusbar(void)
+{
+ return TRUE;
+}
int *tiles;
int gap_pos;
int completed;
+ int movecount;
};
game_params *default_params(void)
assert(!*p);
assert(state->tiles[state->gap_pos] == 0);
- state->completed = FALSE;
+ state->completed = state->movecount = 0;
return state;
}
memcpy(ret->tiles, state->tiles, state->w * state->h * sizeof(int));
ret->gap_pos = state->gap_pos;
ret->completed = state->completed;
+ ret->movecount = state->movecount;
return ret;
}
for (p = from->gap_pos; p != ret->gap_pos; p += up) {
assert(p >= 0 && p < from->n);
ret->tiles[p] = from->tiles[p + up];
+ ret->movecount++;
}
/*
* See if the game has been completed.
*/
if (!ret->completed) {
- ret->completed = TRUE;
+ ret->completed = ret->movecount;
for (p = 0; p < ret->n; p++)
if (ret->tiles[p] != (p < ret->n-1 ? p+1 : 0))
- ret->completed = FALSE;
+ ret->completed = 0;
}
return ret;
}
}
ds->bgcolour = bgcolour;
+
+ /*
+ * Update the status bar.
+ */
+ {
+ char statusbuf[256];
+
+ sprintf(statusbuf, "%sMoves: %d",
+ (state->completed ? "COMPLETED! " : ""),
+ (state->completed ? state->completed : state->movecount));
+
+ status_bar(fe, statusbuf);
+ }
}
float game_anim_length(game_state *oldstate, game_state *newstate)
else
return 0.0F;
}
+
+int game_wants_statusbar(void)
+{
+ return TRUE;
+}
*/
#include <stdio.h>
+#include <assert.h>
#include <stdlib.h>
#include <time.h>
#include <stdarg.h>
struct frontend {
GtkWidget *window;
GtkWidget *area;
+ GtkWidget *statusbar;
+ guint statusctx;
GdkPixmap *pixmap;
GdkColor *colours;
int ncolours;
output[2] = col.blue / 65535.0;
}
+void status_bar(frontend *fe, char *text)
+{
+ assert(fe->statusbar);
+
+ gtk_statusbar_pop(GTK_STATUSBAR(fe->statusbar), fe->statusctx);
+ gtk_statusbar_push(GTK_STATUSBAR(fe->statusbar), fe->statusctx, text);
+}
+
void start_draw(frontend *fe)
{
fe->gc = gdk_gc_new(fe->area->window);
return TRUE;
}
+static gint map_window(GtkWidget *widget, GdkEvent *event,
+ gpointer data)
+{
+ frontend *fe = (frontend *)data;
+
+ /*
+ * Apparently we need to do this because otherwise the status
+ * bar will fail to update immediately. Annoying, but there we
+ * go.
+ */
+ gtk_widget_queue_draw(fe->window);
+
+ return TRUE;
+}
+
static gint configure_area(GtkWidget *widget,
GdkEventConfigure *event, gpointer data)
{
}
}
+ if (midend_wants_statusbar(fe->me)) {
+ fe->statusbar = gtk_statusbar_new();
+ gtk_box_pack_end(vbox, fe->statusbar, FALSE, FALSE, 0);
+ gtk_widget_show(fe->statusbar);
+ fe->statusctx = gtk_statusbar_get_context_id
+ (GTK_STATUSBAR(fe->statusbar), "game");
+ gtk_statusbar_push(GTK_STATUSBAR(fe->statusbar), fe->statusctx,
+ "");
+ } else
+ fe->statusbar = NULL;
+
fe->area = gtk_drawing_area_new();
midend_size(fe->me, &x, &y);
gtk_drawing_area_size(GTK_DRAWING_AREA(fe->area), x, y);
GTK_SIGNAL_FUNC(button_event), fe);
gtk_signal_connect(GTK_OBJECT(fe->area), "expose_event",
GTK_SIGNAL_FUNC(expose_area), fe);
+ gtk_signal_connect(GTK_OBJECT(fe->window), "map_event",
+ GTK_SIGNAL_FUNC(map_window), fe);
gtk_signal_connect(GTK_OBJECT(fe->area), "configure_event",
GTK_SIGNAL_FUNC(configure_area), fe);
*name = me->preset_names[n];
*params = me->presets[n];
}
+
+int midend_wants_statusbar(midend_data *me)
+{
+ return game_wants_statusbar();
+}
}
}
+ /*
+ * Update the status bar.
+ */
+ {
+ char statusbuf[256];
+ int i, n, a;
+
+ n = state->width * state->height;
+ for (i = a = 0; i < n; i++)
+ if (active[i])
+ a++;
+
+ sprintf(statusbuf, "%sActive: %d/%d",
+ (state->completed ? "COMPLETED! " : ""), a, n);
+
+ status_bar(fe, statusbuf);
+ }
+
sfree(active);
}
return 0.0F;
}
+
+int game_wants_statusbar(void)
+{
+ return TRUE;
+}
{
return 0.0F;
}
+
+int game_wants_statusbar(void)
+{
+ return FALSE;
+}
void end_draw(frontend *fe);
void deactivate_timer(frontend *fe);
void activate_timer(frontend *fe);
+void status_bar(frontend *fe, char *text);
/*
* midend.c
int midend_num_presets(midend_data *me);
void midend_fetch_preset(midend_data *me, int n,
char **name, game_params **params);
+int midend_wants_statusbar(midend_data *me);
/*
* malloc.c
game_state *newstate, float anim_time, float flash_time);
float game_anim_length(game_state *oldstate, game_state *newstate);
float game_flash_length(game_state *oldstate, game_state *newstate);
+int game_wants_statusbar(void);
#endif /* PUZZLES_PUZZLES_H */
int w, h, n;
int *tiles;
int completed;
+ int movecount;
};
game_params *default_params(void)
}
assert(!*p);
- state->completed = FALSE;
+ state->completed = state->movecount = 0;
return state;
}
ret->tiles = snewn(state->w * state->h, int);
memcpy(ret->tiles, state->tiles, state->w * state->h * sizeof(int));
ret->completed = state->completed;
+ ret->movecount = state->movecount;
return ret;
}
ret->tiles[C(ret, cx, cy)] = from->tiles[C(from, tx, ty)];
} while (--n > 0);
+ ret->movecount++;
+
/*
* See if the game has been completed.
*/
if (!ret->completed) {
- ret->completed = TRUE;
+ ret->completed = ret->movecount;
for (n = 0; n < ret->n; n++)
if (ret->tiles[n] != n+1)
ret->completed = FALSE;
unclip(fe);
ds->bgcolour = bgcolour;
+
+ /*
+ * Update the status bar.
+ */
+ {
+ char statusbuf[256];
+
+ sprintf(statusbuf, "%sMoves: %d",
+ (state->completed ? "COMPLETED! " : ""),
+ (state->completed ? state->completed : state->movecount));
+
+ status_bar(fe, statusbuf);
+ }
}
float game_anim_length(game_state *oldstate, game_state *newstate)
else
return 0.0F;
}
+
+int game_wants_statusbar(void)
+{
+ return TRUE;
+}
*/
#include <windows.h>
+#include <commctrl.h>
#include <stdio.h>
#include <assert.h>
struct frontend {
midend_data *me;
- HWND hwnd;
+ HWND hwnd, statusbar;
HBITMAP bitmap, prevbm;
HDC hdc_bm;
COLORREF *colours;
exit(1);
}
+void status_bar(frontend *fe, char *text)
+{
+ SetWindowText(fe->statusbar, text);
+}
+
void frontend_default_colour(frontend *fe, float *output)
{
DWORD c = GetSysColor(COLOR_MENU); /* ick */
{
frontend *fe;
int x, y;
- RECT r;
+ RECT r, sr;
HDC hdc;
fe = snew(frontend);
SetMenu(fe->hwnd, bar);
}
+ if (midend_wants_statusbar(fe->me)) {
+ fe->statusbar = CreateWindowEx(0, STATUSCLASSNAME, "ooh",
+ WS_CHILD | WS_VISIBLE,
+ 0, 0, 0, 0, /* status bar does these */
+ fe->hwnd, NULL, inst, NULL);
+ GetWindowRect(fe->statusbar, &sr);
+ SetWindowPos(fe->hwnd, NULL, 0, 0,
+ r.right - r.left, r.bottom - r.top + sr.bottom - sr.top,
+ SWP_NOMOVE | SWP_NOZORDER);
+ SetWindowPos(fe->statusbar, NULL, 0, y, x, sr.bottom - sr.top,
+ SWP_NOZORDER);
+ } else {
+ fe->statusbar = NULL;
+ }
+
hdc = GetDC(fe->hwnd);
fe->bitmap = CreateCompatibleBitmap(hdc, x, y);
ReleaseDC(fe->hwnd, hdc);
int p = ((wParam &~ 0xF) - IDM_PRESETS) / 0x10;
if (p >= 0 && p < fe->npresets) {
- RECT r;
+ RECT r, sr;
HDC hdc;
int x, y;
WS_OVERLAPPED),
TRUE, 0);
+ if (fe->statusbar != NULL) {
+ GetWindowRect(fe->statusbar, &sr);
+ } else {
+ sr.left = sr.right = sr.top = sr.bottom = 0;
+ }
SetWindowPos(fe->hwnd, NULL, 0, 0,
- r.right - r.left, r.bottom - r.top,
+ r.right - r.left,
+ r.bottom - r.top + sr.bottom - sr.top,
SWP_NOMOVE | SWP_NOZORDER);
+ if (fe->statusbar != NULL)
+ SetWindowPos(fe->statusbar, NULL, 0, y, x,
+ sr.bottom - sr.top, SWP_NOZORDER);
DeleteObject(fe->bitmap);
srand(time(NULL));
+ InitCommonControls();
+
if (!prev) {
WNDCLASS wndclass;