[gnome-robots] Rewrite graphics module in Vala
- From: Andrey Kutejko <akutejko src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-robots] Rewrite graphics module in Vala
- Date: Tue, 6 Oct 2020 19:31:40 +0000 (UTC)
commit 290726c383096a6e2c72158f7114ac5efa8b0055
Author: Andrey Kutejko <andy128k gmail com>
Date: Wed Aug 26 00:57:13 2020 +0200
Rewrite graphics module in Vala
src/game.c | 139 ++++++------
src/gbdefs.h | 46 ----
src/gnome-robots.c | 22 +-
src/graphics.c | 611 ----------------------------------------------------
src/graphics.h | 35 ---
src/graphics.vala | 459 +++++++++++++++++++++++++++++++++++++++
src/keyboard.c | 1 +
src/main.vapi | 7 +-
src/meson.build | 2 +-
src/properties.vala | 6 +-
10 files changed, 558 insertions(+), 770 deletions(-)
---
diff --git a/src/game.c b/src/game.c
index 1e2be47..224120d 100644
--- a/src/game.c
+++ b/src/game.c
@@ -32,7 +32,6 @@
#include "keyboard.h"
#include "game.h"
#include "gnome-robots.h"
-#include "graphics.h"
/**********************************************************************/
/* Exported Variables */
@@ -183,7 +182,7 @@ kill_player (void)
{
game_state = STATE_DEAD;
play_sound (SOUND_DIE);
- arena[player_xpos][player_ypos] = OBJECT_PLAYER;
+ arena[player_xpos][player_ypos] = OBJECT_TYPE_PLAYER;
endlev_counter = 0;
add_aieee_bubble (player_xpos, player_ypos);
player_animation_dead ();
@@ -206,7 +205,7 @@ add_kill (gint type)
game_configs_get_current (game_configs, &game_config);
if ((game_state == STATE_WAITING) || (game_state == STATE_WTYPE2)) {
- if (type == OBJECT_ROBOT1) {
+ if (type == OBJECT_TYPE_ROBOT1) {
si = game_config.score_type1_waiting;
kills += 1;
} else {
@@ -214,7 +213,7 @@ add_kill (gint type)
kills += 2;
}
} else {
- if (type == OBJECT_ROBOT1) {
+ if (type == OBJECT_TYPE_ROBOT1) {
si = game_config.score_type1;
} else {
si = game_config.score_type2;
@@ -259,7 +258,7 @@ clear_arena (void)
for (i = 0; i < GAME_WIDTH; ++i) {
for (j = 0; j < GAME_HEIGHT; ++j) {
- arena[i][j] = OBJECT_NONE;
+ arena[i][j] = OBJECT_TYPE_NONE;
}
}
@@ -281,10 +280,10 @@ load_temp_arena (void)
for (i = 0; i < GAME_WIDTH; ++i) {
for (j = 0; j < GAME_HEIGHT; ++j) {
- if (arena[i][j] != OBJECT_PLAYER) {
+ if (arena[i][j] != OBJECT_TYPE_PLAYER) {
temp_arena[i][j] = arena[i][j];
} else {
- temp_arena[i][j] = OBJECT_NONE;
+ temp_arena[i][j] = OBJECT_TYPE_NONE;
}
}
}
@@ -299,13 +298,13 @@ load_temp_arena (void)
* checks for an object at a given location
*
* Returns:
- * type of object if present or OBJECT_NONE
+ * type of object if present or OBJECT_TYPE_NONE
**/
static gint
check_location (gint x, gint y)
{
if ((x < 0) || (y < 0) || (x >= GAME_WIDTH) || (y >= GAME_HEIGHT)) {
- return OBJECT_NONE;
+ return OBJECT_TYPE_NONE;
}
return arena[x][y];
@@ -328,7 +327,7 @@ generate_level (void)
clear_arena ();
- arena[PLAYER_DEF_XPOS][PLAYER_DEF_YPOS] = OBJECT_PLAYER;
+ arena[PLAYER_DEF_XPOS][PLAYER_DEF_YPOS] = OBJECT_TYPE_PLAYER;
player_xpos = PLAYER_DEF_XPOS;
player_ypos = PLAYER_DEF_YPOS;
@@ -373,8 +372,8 @@ generate_level (void)
xp = rand () % GAME_WIDTH;
yp = rand () % GAME_HEIGHT;
- if (check_location (xp, yp) == OBJECT_NONE) {
- arena[xp][yp] = OBJECT_ROBOT1;
+ if (check_location (xp, yp) == OBJECT_TYPE_NONE) {
+ arena[xp][yp] = OBJECT_TYPE_ROBOT1;
break;
}
}
@@ -386,8 +385,8 @@ generate_level (void)
xp = rand () % GAME_WIDTH;
yp = rand () % GAME_HEIGHT;
- if (check_location (xp, yp) == OBJECT_NONE) {
- arena[xp][yp] = OBJECT_ROBOT2;
+ if (check_location (xp, yp) == OBJECT_TYPE_NONE) {
+ arena[xp][yp] = OBJECT_TYPE_ROBOT2;
break;
}
}
@@ -416,15 +415,15 @@ update_arena (void)
for (j = 0; j < GAME_HEIGHT; ++j) {
- if ((temp_arena[i][j] == OBJECT_HEAP) &&
+ if ((temp_arena[i][j] == OBJECT_TYPE_HEAP) &&
(push_xpos == i) && (push_ypos == j)) {
- if (arena[i][j] == OBJECT_ROBOT1) {
+ if (arena[i][j] == OBJECT_TYPE_ROBOT1) {
add_splat_bubble (i, j);
play_sound (SOUND_SPLAT);
push_xpos = push_ypos = -1;
score += game_config.score_type1_splatted;
}
- if (arena[i][j] == OBJECT_ROBOT2) {
+ if (arena[i][j] == OBJECT_TYPE_ROBOT2) {
add_splat_bubble (i, j);
play_sound (SOUND_SPLAT);
push_xpos = push_ypos = -1;
@@ -434,15 +433,15 @@ update_arena (void)
arena[i][j] = temp_arena[i][j];
- if (arena[i][j] == OBJECT_ROBOT1) {
+ if (arena[i][j] == OBJECT_TYPE_ROBOT1) {
num_robots1 += 1;
- } else if (arena[i][j] == OBJECT_ROBOT2) {
+ } else if (arena[i][j] == OBJECT_TYPE_ROBOT2) {
num_robots2 += 1;
}
}
}
- if (arena[player_xpos][player_ypos] != OBJECT_PLAYER) {
+ if (arena[player_xpos][player_ypos] != OBJECT_TYPE_PLAYER) {
kill_player ();
} else {
/* This is in the else statement to catch the case where the last
@@ -630,17 +629,17 @@ move_all_robots (void)
for (i = 0; i < GAME_WIDTH; ++i) {
for (j = 0; j < GAME_HEIGHT; ++j) {
- if ((arena[i][j] == OBJECT_PLAYER) || (arena[i][j] == OBJECT_HEAP)) {
+ if ((arena[i][j] == OBJECT_TYPE_PLAYER) || (arena[i][j] == OBJECT_TYPE_HEAP)) {
temp_arena[i][j] = arena[i][j];
} else {
- temp_arena[i][j] = OBJECT_NONE;
+ temp_arena[i][j] = OBJECT_TYPE_NONE;
}
}
}
for (i = 0; i < GAME_WIDTH; ++i) {
for (j = 0; j < GAME_HEIGHT; ++j) {
- if ((arena[i][j] == OBJECT_ROBOT1) || (arena[i][j] == OBJECT_ROBOT2)) {
+ if ((arena[i][j] == OBJECT_TYPE_ROBOT1) || (arena[i][j] == OBJECT_TYPE_ROBOT2)) {
nx = i;
ny = j;
if (player_xpos < nx)
@@ -652,13 +651,13 @@ move_all_robots (void)
if (player_ypos > ny)
ny += 1;
- if (temp_arena[nx][ny] == OBJECT_HEAP) {
+ if (temp_arena[nx][ny] == OBJECT_TYPE_HEAP) {
add_kill (arena[i][j]);
- } else if ((temp_arena[nx][ny] == OBJECT_ROBOT1) ||
- (temp_arena[nx][ny] == OBJECT_ROBOT2)) {
+ } else if ((temp_arena[nx][ny] == OBJECT_TYPE_ROBOT1) ||
+ (temp_arena[nx][ny] == OBJECT_TYPE_ROBOT2)) {
add_kill (arena[i][j]);
add_kill (temp_arena[nx][ny]);
- temp_arena[nx][ny] = OBJECT_HEAP;
+ temp_arena[nx][ny] = OBJECT_TYPE_HEAP;
} else {
temp_arena[nx][ny] = arena[i][j];
}
@@ -683,18 +682,18 @@ move_type2_robots (void)
for (i = 0; i < GAME_WIDTH; ++i) {
for (j = 0; j < GAME_HEIGHT; ++j) {
- if ((arena[i][j] == OBJECT_PLAYER) ||
- (arena[i][j] == OBJECT_ROBOT1) || (arena[i][j] == OBJECT_HEAP)) {
+ if ((arena[i][j] == OBJECT_TYPE_PLAYER) ||
+ (arena[i][j] == OBJECT_TYPE_ROBOT1) || (arena[i][j] == OBJECT_TYPE_HEAP)) {
temp_arena[i][j] = arena[i][j];
} else {
- temp_arena[i][j] = OBJECT_NONE;
+ temp_arena[i][j] = OBJECT_TYPE_NONE;
}
}
}
for (i = 0; i < GAME_WIDTH; ++i) {
for (j = 0; j < GAME_HEIGHT; ++j) {
- if (arena[i][j] == OBJECT_ROBOT2) {
+ if (arena[i][j] == OBJECT_TYPE_ROBOT2) {
nx = i;
ny = j;
if (player_xpos < nx)
@@ -706,13 +705,13 @@ move_type2_robots (void)
if (player_ypos > ny)
ny += 1;
- if (temp_arena[nx][ny] == OBJECT_HEAP) {
+ if (temp_arena[nx][ny] == OBJECT_TYPE_HEAP) {
add_kill (arena[i][j]);
- } else if ((temp_arena[nx][ny] == OBJECT_ROBOT1) ||
- (temp_arena[nx][ny] == OBJECT_ROBOT2)) {
+ } else if ((temp_arena[nx][ny] == OBJECT_TYPE_ROBOT1) ||
+ (temp_arena[nx][ny] == OBJECT_TYPE_ROBOT2)) {
add_kill (arena[i][j]);
add_kill (temp_arena[nx][ny]);
- temp_arena[nx][ny] = OBJECT_HEAP;
+ temp_arena[nx][ny] = OBJECT_TYPE_HEAP;
} else {
temp_arena[nx][ny] = arena[i][j];
}
@@ -765,24 +764,24 @@ check_safe (gint x, gint y)
gint i, j;
gint nx, ny;
- if (temp_arena[x][y] != OBJECT_NONE)
+ if (temp_arena[x][y] != OBJECT_TYPE_NONE)
return FALSE;
for (i = 0; i < GAME_WIDTH; ++i) {
for (j = 0; j < GAME_HEIGHT; ++j) {
- if ((temp_arena[i][j] == OBJECT_PLAYER) ||
- (temp_arena[i][j] == OBJECT_HEAP)) {
+ if ((temp_arena[i][j] == OBJECT_TYPE_PLAYER) ||
+ (temp_arena[i][j] == OBJECT_TYPE_HEAP)) {
temp2_arena[i][j] = temp_arena[i][j];
} else {
- temp2_arena[i][j] = OBJECT_NONE;
+ temp2_arena[i][j] = OBJECT_TYPE_NONE;
}
}
}
for (i = 0; i < GAME_WIDTH; ++i) {
for (j = 0; j < GAME_HEIGHT; ++j) {
- if ((temp_arena[i][j] == OBJECT_ROBOT1) ||
- (temp_arena[i][j] == OBJECT_ROBOT2)) {
+ if ((temp_arena[i][j] == OBJECT_TYPE_ROBOT1) ||
+ (temp_arena[i][j] == OBJECT_TYPE_ROBOT2)) {
nx = i;
ny = j;
if (x < nx)
@@ -794,10 +793,10 @@ check_safe (gint x, gint y)
if (y > ny)
ny += 1;
- if ((temp2_arena[nx][ny] == OBJECT_ROBOT1) ||
- (temp2_arena[nx][ny] == OBJECT_ROBOT2) ||
- (temp2_arena[nx][ny] == OBJECT_HEAP)) {
- temp2_arena[nx][ny] = OBJECT_HEAP;
+ if ((temp2_arena[nx][ny] == OBJECT_TYPE_ROBOT1) ||
+ (temp2_arena[nx][ny] == OBJECT_TYPE_ROBOT2) ||
+ (temp2_arena[nx][ny] == OBJECT_TYPE_HEAP)) {
+ temp2_arena[nx][ny] = OBJECT_TYPE_HEAP;
} else {
temp2_arena[nx][ny] = temp_arena[i][j];
}
@@ -805,23 +804,23 @@ check_safe (gint x, gint y)
}
}
- if (temp2_arena[x][y] != OBJECT_NONE)
+ if (temp2_arena[x][y] != OBJECT_TYPE_NONE)
return FALSE;
for (i = 0; i < GAME_WIDTH; ++i) {
for (j = 0; j < GAME_HEIGHT; ++j) {
- if ((temp2_arena[i][j] == OBJECT_PLAYER) ||
- (temp2_arena[i][j] == OBJECT_HEAP)) {
+ if ((temp2_arena[i][j] == OBJECT_TYPE_PLAYER) ||
+ (temp2_arena[i][j] == OBJECT_TYPE_HEAP)) {
temp3_arena[i][j] = temp2_arena[i][j];
} else {
- temp3_arena[i][j] = OBJECT_NONE;
+ temp3_arena[i][j] = OBJECT_TYPE_NONE;
}
}
}
for (i = 0; i < GAME_WIDTH; ++i) {
for (j = 0; j < GAME_HEIGHT; ++j) {
- if (temp2_arena[i][j] == OBJECT_ROBOT2) {
+ if (temp2_arena[i][j] == OBJECT_TYPE_ROBOT2) {
nx = i;
ny = j;
if (x < nx)
@@ -833,10 +832,10 @@ check_safe (gint x, gint y)
if (y > ny)
ny += 1;
- if ((temp3_arena[nx][ny] == OBJECT_ROBOT1) ||
- (temp3_arena[nx][ny] == OBJECT_ROBOT2) ||
- (temp3_arena[nx][ny] == OBJECT_HEAP)) {
- temp3_arena[nx][ny] = OBJECT_HEAP;
+ if ((temp3_arena[nx][ny] == OBJECT_TYPE_ROBOT1) ||
+ (temp3_arena[nx][ny] == OBJECT_TYPE_ROBOT2) ||
+ (temp3_arena[nx][ny] == OBJECT_TYPE_HEAP)) {
+ temp3_arena[nx][ny] = OBJECT_TYPE_HEAP;
} else {
temp3_arena[nx][ny] = temp2_arena[i][j];
}
@@ -844,7 +843,7 @@ check_safe (gint x, gint y)
}
}
- if (temp3_arena[x][y] != OBJECT_NONE)
+ if (temp3_arena[x][y] != OBJECT_TYPE_NONE)
return FALSE;
return TRUE;
@@ -869,21 +868,21 @@ push_heap (gint x, gint y, gint dx, gint dy)
gint nx = x + dx;
gint ny = y + dy;
- if (temp_arena[x][y] != OBJECT_HEAP)
+ if (temp_arena[x][y] != OBJECT_TYPE_HEAP)
return FALSE;
if ((nx < 0) || (nx >= GAME_WIDTH) || (ny < 0) || (ny >= GAME_HEIGHT)) {
return FALSE;
}
- if (temp_arena[nx][ny] == OBJECT_HEAP)
+ if (temp_arena[nx][ny] == OBJECT_TYPE_HEAP)
return FALSE;
push_xpos = nx;
push_ypos = ny;
- temp_arena[nx][ny] = OBJECT_HEAP;
- temp_arena[x][y] = OBJECT_NONE;
+ temp_arena[nx][ny] = OBJECT_TYPE_HEAP;
+ temp_arena[x][y] = OBJECT_TYPE_NONE;
return TRUE;
}
@@ -917,7 +916,7 @@ try_player_move (gint dx, gint dy)
load_temp_arena ();
- if (temp_arena[nx][ny] == OBJECT_HEAP) {
+ if (temp_arena[nx][ny] == OBJECT_TYPE_HEAP) {
if (game_config.moveable_heaps) {
if (!push_heap (nx, ny, dx, dy)) {
push_xpos = push_ypos = -1;
@@ -1062,8 +1061,8 @@ player_move (gint dx, gint dy)
player_xpos = nx;
player_ypos = ny;
- if (temp_arena[player_xpos][player_ypos] == OBJECT_NONE) {
- temp_arena[player_xpos][player_ypos] = OBJECT_PLAYER;
+ if (temp_arena[player_xpos][player_ypos] == OBJECT_TYPE_NONE) {
+ temp_arena[player_xpos][player_ypos] = OBJECT_TYPE_PLAYER;
}
reset_player_animation ();
@@ -1093,10 +1092,10 @@ random_teleport (void)
for (i = 0; i < GAME_WIDTH; ++i) {
for (j = 0; j < GAME_HEIGHT; ++j) {
- if (arena[i][j] != OBJECT_PLAYER) {
+ if (arena[i][j] != OBJECT_TYPE_PLAYER) {
temp_arena[i][j] = arena[i][j];
} else {
- temp_arena[i][j] = OBJECT_NONE;
+ temp_arena[i][j] = OBJECT_TYPE_NONE;
}
}
}
@@ -1106,10 +1105,10 @@ random_teleport (void)
iyp = yp = rand () % GAME_HEIGHT;
while (1) {
- if (temp_arena[xp][yp] == OBJECT_NONE) {
+ if (temp_arena[xp][yp] == OBJECT_TYPE_NONE) {
player_xpos = xp;
player_ypos = yp;
- temp_arena[player_xpos][player_ypos] = OBJECT_PLAYER;
+ temp_arena[player_xpos][player_ypos] = OBJECT_TYPE_PLAYER;
reset_player_animation ();
@@ -1166,10 +1165,10 @@ safe_teleport (void)
for (i = 0; i < GAME_WIDTH; ++i) {
for (j = 0; j < GAME_HEIGHT; ++j) {
- if (arena[i][j] != OBJECT_PLAYER) {
+ if (arena[i][j] != OBJECT_TYPE_PLAYER) {
temp_arena[i][j] = arena[i][j];
} else {
- temp_arena[i][j] = OBJECT_NONE;
+ temp_arena[i][j] = OBJECT_TYPE_NONE;
}
}
}
@@ -1179,10 +1178,10 @@ safe_teleport (void)
while (1) {
- if ((temp_arena[xp][yp] == OBJECT_NONE) && check_safe (xp, yp)) {
+ if ((temp_arena[xp][yp] == OBJECT_TYPE_NONE) && check_safe (xp, yp)) {
player_xpos = xp;
player_ypos = yp;
- temp_arena[player_xpos][player_ypos] = OBJECT_PLAYER;
+ temp_arena[player_xpos][player_ypos] = OBJECT_TYPE_PLAYER;
reset_player_animation ();
diff --git a/src/gbdefs.h b/src/gbdefs.h
index 119df09..6d74f26 100644
--- a/src/gbdefs.h
+++ b/src/gbdefs.h
@@ -4,40 +4,12 @@
#ifndef GBDEFS_H
#define GBDEFS_H
-/*
- * Bubble Sizes
- */
-#define BUBBLE_WIDTH 86
-#define BUBBLE_HEIGHT 34
-#define BUBBLE_XOFFSET 8
-#define BUBBLE_YOFFSET 4
-
-/*
- * Size of the game playing area
- */
-#define GAME_WIDTH 45
-#define GAME_HEIGHT 30
-
/*
* Initial player position
*/
#define PLAYER_DEF_XPOS (GAME_WIDTH/2)
#define PLAYER_DEF_YPOS (GAME_HEIGHT/2)
-/*
- * Scenario pixmaps
- */
-#define SCENARIO_PIXMAP_WIDTH 14
-#define SCENARIO_PLAYER_START 0
-#define SCENARIO_ROBOT1_START 5
-#define SCENARIO_ROBOT2_START 9
-#define SCENARIO_HEAP_POS 13
-
-#define NUM_ROBOT_ANIMATIONS 4
-#define NUM_PLAYER_ANIMATIONS 4
-#define PLAYER_WAVE_WAIT 20
-#define PLAYER_NUM_WAVES 2
-
/*
* Animation
*/
@@ -52,24 +24,6 @@
#define MAX_ROBOTS ((GAME_WIDTH*GAME_HEIGHT)/2)
#define MAX_HEAPS (MAX_ROBOTS/2)
-/*
- * Game object types
- */
-#define OBJECT_PLAYER 0
-#define OBJECT_HEAP 1
-#define OBJECT_ROBOT1 2
-#define OBJECT_ROBOT2 3
-#define OBJECT_NONE 99
-#define OBJECT_FOO 666
-
-/*
- * Bubble Types
- */
-#define BUBBLE_NONE 0
-#define BUBBLE_YAHOO 1
-#define BUBBLE_AIEEE 2
-#define BUBBLE_SPLAT 3
-
/*
* Game states
*/
diff --git a/src/gnome-robots.c b/src/gnome-robots.c
index ebe336b..b220ad3 100644
--- a/src/gnome-robots.c
+++ b/src/gnome-robots.c
@@ -35,7 +35,6 @@
#include "gbdefs.h"
#include "riiv.h"
-#include "graphics.h"
#include "game.h"
/* Minimum sizes. */
@@ -170,6 +169,22 @@ update_game_status (gint score, gint current_level, gint safes)
g_free (button_text);
}
+static gboolean
+draw_cb (GtkWidget * w, cairo_t * cr, gpointer data)
+{
+ gint i, j;
+
+ for (j = 0; j < GAME_HEIGHT; j++) {
+ for (i = 0; i < GAME_WIDTH; i++) {
+ draw_object (i, j, arena[i][j], cr);
+ }
+ }
+
+ draw_bubble (cr);
+
+ return TRUE;
+}
+
const gchar *
category_name_from_key (const gchar* key)
{
@@ -473,7 +488,10 @@ activate (GtkApplication *app, gpointer user_data)
load_properties ();
- if (!load_game_graphics ()) {
+ GError *load_game_graphics_error = NULL;
+ load_game_graphics (&load_game_graphics_error);
+ if (load_game_graphics_error) {
+ g_error ("%s", load_game_graphics_error->message);
/* Oops, no graphics, we probably haven't been installed properly. */
errordialog = gtk_message_dialog_new_with_markup (GTK_WINDOW (window),
GTK_DIALOG_MODAL,
diff --git a/src/graphics.vala b/src/graphics.vala
new file mode 100644
index 0000000..8c2bacc
--- /dev/null
+++ b/src/graphics.vala
@@ -0,0 +1,459 @@
+/*
+ * Gnome Robots II
+ * written by Mark Rae <m rae inpharmatica co uk>
+ *
+ * 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 3 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://www.gnu.org/licenses/>.
+ *
+ * For more details see the file COPYING.
+ */
+
+using Gtk;
+using Gdk;
+using Cairo;
+
+/*
+ * Size of the game playing area
+ */
+public const int GAME_WIDTH = 45;
+public const int GAME_HEIGHT = 30;
+
+public enum BubbleType {
+ NONE = 0,
+ YAHOO,
+ AIEEE,
+ SPLAT,
+}
+
+public const int BUBBLE_WIDTH = 86;
+public const int BUBBLE_HEIGHT = 34;
+public const int BUBBLE_XOFFSET = 8;
+public const int BUBBLE_YOFFSET = 4;
+
+/*
+ * Scenario pixmaps
+ */
+public const int SCENARIO_PIXMAP_WIDTH = 14;
+public const int SCENARIO_PLAYER_START = 0;
+public const int SCENARIO_ROBOT1_START = 5;
+public const int SCENARIO_ROBOT2_START = 9;
+public const int SCENARIO_HEAP_POS = 13;
+
+public const int NUM_ROBOT_ANIMATIONS = 4;
+public const int NUM_PLAYER_ANIMATIONS = 4;
+public const int PLAYER_WAVE_WAIT = 20;
+public const int PLAYER_NUM_WAVES = 2;
+
+public enum ObjectType {
+ PLAYER = 0,
+ HEAP = 1,
+ ROBOT1 = 2,
+ ROBOT2 = 3,
+ NONE = 99,
+ FOO = 666,
+}
+
+public int tile_width = 0;
+public int tile_height = 0;
+
+GamesPreimage theme_preimage = null;
+Pixbuf theme_pixbuf = null;
+bool rerender_needed = true;
+
+RGBA light_background;
+RGBA dark_background;
+
+Pixbuf aieee_pixbuf = null;
+Pixbuf yahoo_pixbuf = null;
+Pixbuf splat_pixbuf = null;
+
+int robot_animation = 0;
+int player_animation = 0;
+int player_num_waves = 0;
+int player_wave_wait = 0;
+int player_wave_dir = 1;
+
+int bubble_xpos = 0;
+int bubble_ypos = 0;
+int bubble_xo = 0;
+int bubble_yo = 0;
+BubbleType bubble_type = BubbleType.NONE;
+
+void render_graphics () {
+ theme_pixbuf = theme_preimage.render (14 * tile_width, tile_height);
+ rerender_needed = false;
+}
+
+public bool resize_cb (Widget w, EventConfigure e) {
+ int trial_width;
+ int trial_height;
+
+ trial_width = e.width / GAME_WIDTH;
+ trial_height = e.height / GAME_HEIGHT;
+
+ if ((trial_width != tile_width) || (trial_height != tile_height)) {
+ tile_width = trial_width;
+ tile_height = trial_height;
+ rerender_needed = true;
+ }
+
+ return false;
+}
+
+/**
+ * Loads all of the 'speech bubble' graphics
+ **/
+void load_bubble_graphics () throws Error {
+ yahoo_pixbuf = new Pixbuf.from_file (
+ GLib.Path.build_filename (DATA_DIRECTORY, "pixmaps", "yahoo.png"));
+ aieee_pixbuf = new Pixbuf.from_file (
+ GLib.Path.build_filename (DATA_DIRECTORY, "pixmaps", "aieee.png"));
+ splat_pixbuf = new Pixbuf.from_file (
+ GLib.Path.build_filename (DATA_DIRECTORY, "pixmaps", "splat.png"));
+}
+
+
+/**
+ * load_game_graphics
+ *
+ * Description:
+ * Loads all of the game graphics
+ *
+ * Returns:
+ * TRUE on success FALSE otherwise
+ **/
+public void load_game_graphics () throws Error {
+ if (theme_preimage != null) {
+ free_game_graphics ();
+ }
+
+ var themedir = GLib.Path.build_filename (DATA_DIRECTORY, "themes");
+ var filename = games_find_similar_file (properties_theme_name (), themedir);
+
+ try {
+ theme_preimage = new GamesPreimage.from_file (filename);
+ } catch (Error e) {
+ filename = games_find_similar_file ("robots", themedir);
+ theme_preimage = new GamesPreimage.from_file (filename);
+ }
+
+ load_bubble_graphics ();
+
+ rerender_needed = true;
+}
+
+/**
+ * Frees all of the resources used by the game graphics
+ **/
+public void free_game_graphics () {
+ theme_preimage = null;
+ theme_pixbuf = null;
+ aieee_pixbuf = null;
+ yahoo_pixbuf = null;
+ splat_pixbuf = null;
+}
+
+public void set_background_color (RGBA color) {
+ if (game_area == null)
+ return;
+
+ /* While the two colours are labelled "light" and "dark" which one is
+ * which actually depends on how light or dark the base colour is. */
+
+ double brightness = color.red + color.green + color.blue;
+ if (brightness > (1.0 / 1.1)) {
+ /* Darken light colours. */
+ light_background.red = 0.9 * color.red;
+ light_background.green = 0.9 * color.green;
+ light_background.blue = 0.9 * color.blue;
+ } else if (brightness > 0.04) {
+ /* Lighten darker colours. */
+ light_background.red = 1.1 * color.red;
+ light_background.green = 1.1 * color.green;
+ light_background.blue = 1.1 * color.blue;
+ } else {
+ /* Very dark colours, add rather than multiply. */
+ light_background.red += 0.04;
+ light_background.green += 0.04;
+ light_background.blue += 0.04;
+ }
+ light_background.alpha = 1.0;
+ dark_background = color;
+
+ clear_game_area ();
+}
+
+public void set_background_color_from_name (string name) {
+ RGBA color = RGBA ();
+ if (!color.parse (name)) {
+ color.parse ("#7590AE");
+ }
+ set_background_color (color);
+}
+
+/**
+ * draw_tile_pixmap
+ * @tileno: Graphics tile number
+ * @pno: Number of graphics set
+ * @x: x position in grid squares
+ * @y: y position in grid squares
+ * @cr: context to draw on
+ *
+ * Description:
+ * Draws tile pixmap @tileno from graphics set @pno at (@x, @y) in
+ * a widget @area
+ **/
+void draw_tile_pixmap (int tileno, int x, int y, Context cr) {
+ if ((x + y) % 2 != 0) {
+ cairo_set_source_rgba (cr, dark_background);
+ } else {
+ cairo_set_source_rgba (cr, light_background);
+ }
+
+ x *= tile_width;
+ y *= tile_height;
+
+ cr.rectangle (x, y, tile_width, tile_height);
+ cr.fill ();
+
+ if (rerender_needed)
+ render_graphics ();
+
+ if ((tileno < 0) || (tileno >= SCENARIO_PIXMAP_WIDTH)) {
+ /* nothing */
+ } else {
+ cairo_set_source_pixbuf (cr, theme_pixbuf, x - tileno * tile_width, y);
+ cr.rectangle (x, y, tile_width, tile_height);
+ cr.fill ();
+ }
+}
+
+
+/**
+ * draw_object
+ * @x: x position
+ * @y: y position
+ * @type: object type
+ * @cr: context to draw on
+ *
+ * Description:
+ * Draws graphics for an object at specified location
+ **/
+public void draw_object (int x, int y, ObjectType type, Context cr) {
+ if (game_area == null)
+ return;
+
+ switch (type) {
+ case ObjectType.PLAYER:
+ draw_tile_pixmap (SCENARIO_PLAYER_START + player_animation, x, y, cr);
+ break;
+ case ObjectType.ROBOT1:
+ draw_tile_pixmap (SCENARIO_ROBOT1_START + robot_animation, x, y, cr);
+ break;
+ case ObjectType.ROBOT2:
+ draw_tile_pixmap (SCENARIO_ROBOT2_START + robot_animation, x, y, cr);
+ break;
+ case ObjectType.HEAP:
+ draw_tile_pixmap (SCENARIO_HEAP_POS, x, y, cr);
+ break;
+ case ObjectType.NONE:
+ draw_tile_pixmap (-1, x, y, cr);
+ break;
+ }
+}
+
+
+/**
+ * clears the whole of the game area
+ **/
+public void clear_game_area () {
+ if (game_area == null)
+ return;
+
+ game_area.queue_draw ();
+}
+
+
+/**
+ * reset_player_animation
+ *
+ * Description:
+ * resets player animation to standing position
+ **/
+public void reset_player_animation () {
+ player_wave_wait = 0;
+ player_num_waves = 0;
+ player_wave_dir = 1;
+ player_animation = 0;
+}
+
+
+/**
+ * player_animation_dead
+ *
+ * Description:
+ * sets player animation to be dead
+ **/
+public void player_animation_dead () {
+ player_wave_wait = 0;
+ player_num_waves = 0;
+ player_wave_dir = 1;
+ player_animation = NUM_PLAYER_ANIMATIONS;
+}
+
+
+/**
+ * animate_game_graphics
+ *
+ * Description:
+ * updates animation for object graphics
+ **/
+public void animate_game_graphics () {
+ ++robot_animation;
+ if (robot_animation >= NUM_ROBOT_ANIMATIONS) {
+ robot_animation = 0;
+ }
+
+ if (player_animation == NUM_PLAYER_ANIMATIONS) {
+ /* do nothing */
+ } else if (player_wave_wait < PLAYER_WAVE_WAIT) {
+ ++player_wave_wait;
+ player_animation = 0;
+ } else {
+ player_animation += player_wave_dir;
+ if (player_animation >= NUM_PLAYER_ANIMATIONS) {
+ player_wave_dir = -1;
+ player_animation -= 2;
+ } else if (player_animation < 0) {
+ player_wave_dir = 1;
+ player_animation = 1;
+ ++player_num_waves;
+ if (player_num_waves >= PLAYER_NUM_WAVES) {
+ reset_player_animation ();
+ }
+ }
+ }
+}
+
+/**
+ * Draws a bubble if there is one
+ **/
+public void draw_bubble (Context cr) {
+ if (bubble_type == BubbleType.NONE)
+ return;
+
+ Pixbuf pmap;
+ if (bubble_type == BubbleType.YAHOO) {
+ pmap = yahoo_pixbuf;
+ } else if (bubble_type == BubbleType.AIEEE) {
+ pmap = aieee_pixbuf;
+ } else {
+ pmap = splat_pixbuf;
+ }
+
+ cairo_set_source_pixbuf (cr, pmap, bubble_xpos - bubble_xo, bubble_ypos - bubble_yo);
+ cr.rectangle (bubble_xpos, bubble_ypos, BUBBLE_WIDTH, BUBBLE_HEIGHT);
+ cr.fill ();
+}
+
+/**
+ * add_bubble
+ * @x: x position
+ * @y: y position
+ *
+ * Description:
+ * adds a bubble at @x,@y
+ **/
+void add_bubble (BubbleType type, int x, int y) {
+ bubble_type = type;
+ bubble_xpos = x * tile_width - BUBBLE_WIDTH + BUBBLE_XOFFSET;
+ bubble_ypos = y * tile_height - BUBBLE_HEIGHT + BUBBLE_YOFFSET;
+
+ bubble_xo = 0;
+ bubble_yo = 0;
+
+ if (bubble_ypos < 0) {
+ bubble_yo = BUBBLE_HEIGHT;
+ bubble_ypos += BUBBLE_HEIGHT;
+ }
+ if (bubble_xpos < 0) {
+ bubble_xo = BUBBLE_WIDTH;
+ bubble_xpos += BUBBLE_WIDTH;
+ }
+ game_area.queue_draw ();
+}
+
+/**
+ * remove_bubble
+ *
+ * Description:
+ * removes all types of bubble
+ **/
+public void remove_bubble () {
+ if (bubble_type == BubbleType.NONE)
+ return;
+
+ bubble_type = BubbleType.NONE;
+ game_area.queue_draw ();
+}
+
+/**
+ * removes a splat bubble if there is one
+ **/
+public void remove_splat_bubble () {
+ if (bubble_type != BubbleType.SPLAT)
+ return;
+
+ bubble_type = BubbleType.NONE;
+ game_area.queue_draw ();
+}
+
+
+/**
+ * add_yahoo_bubble
+ * @x: x position
+ * @y: y position
+ *
+ * Description:
+ * adds and "Yahoo" bubble at @x,@y
+ **/
+public void add_yahoo_bubble (int x, int y) {
+ add_bubble (BubbleType.YAHOO, x, y);
+}
+
+
+/**
+ * add_aieee_bubble
+ * @x: x position
+ * @y: y position
+ *
+ * Description:
+ * adds and "Aieee" bubble at @x,@y
+ **/
+public void add_aieee_bubble (int x, int y) {
+ add_bubble (BubbleType.AIEEE, x, y);
+}
+
+/**
+ * add_splat_bubble
+ * @x: x position
+ * @y: y position
+ *
+ * Description:
+ * adds a "Splat" speech bubble at @x,@y
+ **/
+public void add_splat_bubble (int x, int y) {
+ add_bubble (BubbleType.SPLAT, x, y);
+ bubble_ypos += BUBBLE_YOFFSET;
+}
+
diff --git a/src/keyboard.c b/src/keyboard.c
index 04aa968..6173ca1 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -26,6 +26,7 @@
#include <gdk/gdkkeysyms.h>
#include "keyboard.h"
+#include "riiv.h"
#include "game.h"
/**********************************************************************/
diff --git a/src/main.vapi b/src/main.vapi
index 785dcbd..2882a9f 100644
--- a/src/main.vapi
+++ b/src/main.vapi
@@ -1,14 +1,13 @@
public void keyboard_set (uint keys[9]);
-public bool load_game_graphics ();
-public void clear_game_area ();
-public void set_background_color (Gdk.RGBA color);
-
public void start_new_game ();
[CCode (cheader_filename = "gnome-robots.h")]
public Gtk.Window window;
+[CCode (cheader_filename = "gnome-robots.h")]
+public Gtk.Widget game_area;
+
[CCode (cheader_filename = "gnome-robots.h")]
public GLib.Settings settings;
diff --git a/src/meson.build b/src/meson.build
index d9a3f9d..4fd8e94 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -19,6 +19,7 @@ vala_sources = files(
'sound.vala',
'cursors.vala',
'properties.vala',
+ 'graphics.vala',
)
vala_lib = static_library('riiv',
@@ -43,7 +44,6 @@ riiv_dependency = declare_dependency(
sources = files(
'game.c',
'gnome-robots.c',
- 'graphics.c',
'keyboard.c',
)
resources = gnome.compile_resources(
diff --git a/src/properties.vala b/src/properties.vala
index 79004ac..b28e49d 100644
--- a/src/properties.vala
+++ b/src/properties.vala
@@ -91,7 +91,11 @@ void pmap_selection (ComboBox combo) {
conf_set_theme (properties.themename);
- load_game_graphics ();
+ try {
+ load_game_graphics ();
+ } catch (Error e) {
+ // TODO
+ }
clear_game_area ();
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]