[gnome-robots] Rewrite GameConfig in Vala
- From: Andrey Kutejko <akutejko src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-robots] Rewrite GameConfig in Vala
- Date: Tue, 6 Oct 2020 19:31:40 +0000 (UTC)
commit eebf5e111fa9cb48621f80d8d04949b9394ae714
Author: Andrey Kutejko <andy128k gmail com>
Date: Mon Aug 24 20:37:09 2020 +0200
Rewrite GameConfig in Vala
meson.build | 6 +
src/config.vapi | 7 +
src/game-config.vala | 209 +++++++++++++++++++++++
src/game.c | 95 ++++++-----
src/gameconfig.c | 466 ---------------------------------------------------
src/gameconfig.h | 58 -------
src/gnome-robots.c | 5 +-
src/meson.build | 22 ++-
src/properties.c | 32 ++--
src/properties.h | 4 +
10 files changed, 315 insertions(+), 589 deletions(-)
---
diff --git a/meson.build b/meson.build
index db53890..54b0f92 100644
--- a/meson.build
+++ b/meson.build
@@ -7,6 +7,12 @@ i18n = import('i18n')
application_id = 'org.gnome.Robots'
+add_project_arguments([
+ '-include', 'config.h'
+ ],
+ language: 'c'
+)
+
gee_dependency = dependency('gee-0.8')
gio_dependency = dependency('gio-2.0', version: '>= 2.32')
glib_dependency = dependency('glib-2.0', version: '>= 2.32')
diff --git a/src/config.vapi b/src/config.vapi
new file mode 100644
index 0000000..b9f8304
--- /dev/null
+++ b/src/config.vapi
@@ -0,0 +1,7 @@
+public const string GETTEXT_PACKAGE;
+public const string LOCALEDIR;
+public const string PACKAGE;
+public const string DATA_DIRECTORY;
+public const string SOUND_DIRECTORY;
+public const string VERSION;
+
diff --git a/src/game-config.vala b/src/game-config.vala
new file mode 100644
index 0000000..b85f49b
--- /dev/null
+++ b/src/game-config.vala
@@ -0,0 +1,209 @@
+/*
+ * 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.
+ */
+
+public struct GameConfig {
+ public string description;
+ public int initial_type1;
+ public int initial_type2;
+ public int increment_type1;
+ public int increment_type2;
+ public int maximum_type1;
+ public int maximum_type2;
+ public int score_type1;
+ public int score_type2;
+ public int score_type1_waiting;
+ public int score_type2_waiting;
+ public int score_type1_splatted;
+ public int score_type2_splatted;
+ public int num_robots_per_safe;
+ public int safe_score_boundary;
+ public int initial_safe_teleports;
+ public int free_safe_teleports;
+ public int max_safe_teleports;
+ public bool moveable_heaps;
+
+ public string name () {
+ return description.replace ("_", " ");
+ }
+
+ public static GameConfig from_file (string filename) throws Error {
+ GameConfig gcfg = GameConfig ();
+
+ gcfg.description = Path.get_basename (filename);
+ if (gcfg.description.has_suffix (".cfg")) {
+ gcfg.description = gcfg.description.substring (0, gcfg.description.length - 4);
+ }
+
+ var line_regex = new Regex ("^(\\w+)\\s*=\\s*(\\d+)");
+
+ var file = File.new_for_path (filename);
+ var dis = new DataInputStream (file.read ());
+
+ string line;
+ uint pflag = 0;
+ while ((line = dis.read_line (null)) != null) {
+ MatchInfo match_info;
+ if (!line_regex.match (line, 0, out match_info)) {
+ continue;
+ }
+ string key = match_info.fetch (1);
+ int val = int.parse (match_info.fetch (2));
+
+ if (key == "initial_type1") {
+ gcfg.initial_type1 = val;
+ pflag |= 0x00000001;
+ }
+ if (key == "initial_type2") {
+ gcfg.initial_type2 = val;
+ pflag |= 0x00000002;
+ }
+ if (key == "increment_type1") {
+ gcfg.increment_type1 = val;
+ pflag |= 0x00000004;
+ }
+ if (key == "increment_type2") {
+ gcfg.increment_type2 = val;
+ pflag |= 0x00000008;
+ }
+ if (key == "maximum_type1") {
+ gcfg.maximum_type1 = val;
+ pflag |= 0x00000010;
+ }
+ if (key == "maximum_type2") {
+ gcfg.maximum_type2 = val;
+ pflag |= 0x00000020;
+ }
+ if (key == "score_type1") {
+ gcfg.score_type1 = val;
+ pflag |= 0x00000040;
+ }
+ if (key == "score_type2") {
+ gcfg.score_type2 = val;
+ pflag |= 0x00000080;
+ }
+ if (key == "score_type1_waiting") {
+ gcfg.score_type1_waiting = val;
+ pflag |= 0x00000100;
+ }
+ if (key == "score_type2_waiting") {
+ gcfg.score_type2_waiting = val;
+ pflag |= 0x00000200;
+ }
+ if (key == "score_type1_splatted") {
+ gcfg.score_type1_splatted = val;
+ pflag |= 0x00000400;
+ }
+ if (key == "score_type2_splatted") {
+ gcfg.score_type2_splatted = val;
+ pflag |= 0x00000800;
+ }
+ if (key == "num_robots_per_safe") {
+ gcfg.num_robots_per_safe = val;
+ pflag |= 0x00001000;
+ }
+ if (key == "safe_score_boundary") {
+ gcfg.safe_score_boundary = val;
+ pflag |= 0x00002000;
+ }
+ if (key == "max_safe_teleports") {
+ gcfg.max_safe_teleports = val;
+ pflag |= 0x00004000;
+ }
+ if (key == "initial_safe_teleports") {
+ gcfg.initial_safe_teleports = val;
+ pflag |= 0x00008000;
+ }
+ if (key == "free_safe_teleports") {
+ gcfg.free_safe_teleports = val;
+ pflag |= 0x00010000;
+ }
+ if (key == "moveable_heaps") {
+ gcfg.moveable_heaps = val != 0;
+ pflag |= 0x00020000;
+ }
+ }
+
+ // Check we have got all types
+ if (pflag != 0x0003ffff) {
+ throw new FileError.INVAL ("Bad game config file.");
+ }
+
+ return gcfg;
+ }
+}
+
+public class GameConfigs {
+ private Gee.ArrayList<GameConfig?> game_configs;
+ private uint current_config;
+
+ public GameConfigs.load () throws Error {
+ var dname = Path.build_filename (DATA_DIRECTORY, "games");
+ var dir = Dir.open (dname);
+ game_configs = new Gee.ArrayList<GameConfig?> ();
+ string? filename;
+ while ((filename = dir.read_name ()) != null) {
+ if (!filename.has_suffix (".cfg")) {
+ continue;
+ }
+ var fullname = Path.build_filename (dname, filename);
+ try {
+ var gcfg = GameConfig.from_file (fullname);
+ game_configs.add (gcfg);
+ } catch (Error e) {
+ warning ("%s", e.message);
+ }
+ }
+
+ if (game_configs.size >= 0) {
+ current_config = 0;
+ } else {
+ throw new FileError.NOENT ("No game config was found.");
+ }
+ }
+
+ public uint count () {
+ return game_configs.size;
+ }
+
+ public GameConfig? @get (uint n) {
+ if (n < game_configs.size)
+ return game_configs[(int)n];
+ else
+ return null;
+ }
+
+ public string? get_name (uint n) {
+ if (n < game_configs.size)
+ return game_configs[(int)n].description.replace ("_", " ");
+ else
+ return null;
+ }
+
+ public GameConfig get_current () {
+ return game_configs[(int)current_config];
+ }
+
+ public uint get_current_index () {
+ return current_config;
+ }
+
+ public void set_current_index (uint n) {
+ if (n < game_configs.size)
+ current_config = n;
+ }
+}
+
diff --git a/src/game.c b/src/game.c
index 417c47b..4c61986 100644
--- a/src/game.c
+++ b/src/game.c
@@ -28,7 +28,7 @@
#include <libgnome-games-support.h>
#include "gbdefs.h"
-#include "gameconfig.h"
+#include "riiv.h"
#include "keyboard.h"
#include "game.h"
#include "gnome-robots.h"
@@ -154,19 +154,16 @@ static void
log_score (gint sc)
{
gchar *sbuf = NULL;
+ GameConfig game_config;
+
+ game_configs_get_current (game_configs, &game_config);
if (properties_super_safe_moves ()) {
- sbuf =
- g_strdup_printf ("%s-super-safe",
- game_config_filename (current_game_config ()));
+ sbuf = g_strdup_printf ("%s-super-safe", game_config.description);
} else if (properties_safe_moves ()) {
- sbuf =
- g_strdup_printf ("%s-safe",
- game_config_filename (current_game_config ()));
+ sbuf = g_strdup_printf ("%s-safe", game_config.description);
} else {
- sbuf =
- g_strdup_printf ("%s",
- game_config_filename (current_game_config ()));
+ sbuf = g_strdup_printf ("%s", game_config.description);
}
if (sc != 0) {
@@ -207,42 +204,45 @@ static void
add_kill (gint type)
{
gint si;
+ GameConfig game_config;
+
+ game_configs_get_current (game_configs, &game_config);
if ((game_state == STATE_WAITING) || (game_state == STATE_WTYPE2)) {
if (type == OBJECT_ROBOT1) {
- si = game_config ()->score_type1_waiting;
+ si = game_config.score_type1_waiting;
kills += 1;
} else {
- si = game_config ()->score_type2_waiting;
+ si = game_config.score_type2_waiting;
kills += 2;
}
} else {
if (type == OBJECT_ROBOT1) {
- si = game_config ()->score_type1;
+ si = game_config.score_type1;
} else {
- si = game_config ()->score_type2;
+ si = game_config.score_type2;
}
}
score += si;
score_step += si;
- if (game_config ()->safe_score_boundary > 0) {
- while (score_step >= game_config ()->safe_score_boundary) {
+ if (game_config.safe_score_boundary > 0) {
+ while (score_step >= game_config.safe_score_boundary) {
safe_teleports += 1;
- score_step -= game_config ()->safe_score_boundary;
+ score_step -= game_config.safe_score_boundary;
}
}
- if (game_config ()->num_robots_per_safe > 0) {
- while (kills >= game_config ()->num_robots_per_safe) {
+ if (game_config.num_robots_per_safe > 0) {
+ while (kills >= game_config.num_robots_per_safe) {
safe_teleports += 1;
- kills -= game_config ()->num_robots_per_safe;
+ kills -= game_config.num_robots_per_safe;
}
}
- if (safe_teleports > game_config ()->max_safe_teleports) {
- safe_teleports = game_config ()->max_safe_teleports;
+ if (safe_teleports > game_config.max_safe_teleports) {
+ safe_teleports = game_config.max_safe_teleports;
}
update_game_status (score, current_level + 1, safe_teleports);
@@ -325,6 +325,9 @@ generate_level (void)
{
gint i;
gint xp, yp;
+ GameConfig game_config;
+
+ game_configs_get_current (game_configs, &game_config);
clear_arena ();
@@ -332,38 +335,38 @@ generate_level (void)
player_xpos = PLAYER_DEF_XPOS;
player_ypos = PLAYER_DEF_YPOS;
- num_robots1 = game_config ()->initial_type1 +
- game_config ()->increment_type1 * current_level;
+ num_robots1 = game_config.initial_type1 +
+ game_config.increment_type1 * current_level;
- if (num_robots1 > game_config ()->maximum_type1) {
- num_robots1 = game_config ()->maximum_type1;
+ if (num_robots1 > game_config.maximum_type1) {
+ num_robots1 = game_config.maximum_type1;
}
if (num_robots1 > MAX_ROBOTS) {
current_level = 0;
- num_robots1 = game_config ()->initial_type1;
+ num_robots1 = game_config.initial_type1;
message_box (_("Congratulations, You Have Defeated the Robots!! \nBut Can You do it Again?"));
play_sound (SOUND_VICTORY);
}
- num_robots2 = game_config ()->initial_type2 +
- game_config ()->increment_type2 * current_level;
+ num_robots2 = game_config.initial_type2 +
+ game_config.increment_type2 * current_level;
- if (num_robots2 > game_config ()->maximum_type2) {
- num_robots2 = game_config ()->maximum_type2;
+ if (num_robots2 > game_config.maximum_type2) {
+ num_robots2 = game_config.maximum_type2;
}
if ((num_robots1 + num_robots2) > MAX_ROBOTS) {
current_level = 0;
- num_robots1 = game_config ()->initial_type1;
- num_robots2 = game_config ()->initial_type2;
+ num_robots1 = game_config.initial_type1;
+ num_robots2 = game_config.initial_type2;
message_box (_("Congratulations, You Have Defeated the Robots!! \nBut Can You do it Again?"));
play_sound (SOUND_VICTORY);
}
- safe_teleports += game_config ()->free_safe_teleports;
+ safe_teleports += game_config.free_safe_teleports;
- if (safe_teleports > game_config ()->max_safe_teleports) {
- safe_teleports = game_config ()->max_safe_teleports;
+ if (safe_teleports > game_config.max_safe_teleports) {
+ safe_teleports = game_config.max_safe_teleports;
}
update_game_status (score, current_level, safe_teleports);
@@ -405,6 +408,9 @@ static void
update_arena (void)
{
gint i, j;
+ GameConfig game_config;
+
+ game_configs_get_current (game_configs, &game_config);
num_robots1 = 0;
num_robots2 = 0;
@@ -419,13 +425,13 @@ update_arena (void)
add_splat_bubble (i, j);
play_sound (SOUND_SPLAT);
push_xpos = push_ypos = -1;
- score += game_config ()->score_type1_splatted;
+ score += game_config.score_type1_splatted;
}
if (arena[i][j] == OBJECT_ROBOT2) {
add_splat_bubble (i, j);
play_sound (SOUND_SPLAT);
push_xpos = push_ypos = -1;
- score += game_config ()->score_type2_splatted;
+ score += game_config.score_type2_splatted;
}
}
@@ -587,7 +593,7 @@ init_game (void)
void
start_new_game (void)
{
- GameConfig *conf;
+ GameConfig game_config;
current_level = 0;
score = 0;
kills = 0;
@@ -596,10 +602,10 @@ start_new_game (void)
if (game_state == STATE_PLAYING)
log_score (score);
- conf = game_config ();
- g_return_if_fail (conf != NULL);
+ game_configs_get_current (game_configs, &game_config);
+ // g_return_if_fail (game_config != NULL);
- safe_teleports = conf->initial_safe_teleports;
+ safe_teleports = game_config.initial_safe_teleports;
remove_bubble ();
reset_player_animation ();
@@ -901,6 +907,9 @@ static gboolean
try_player_move (gint dx, gint dy)
{
gint nx, ny;
+ GameConfig game_config;
+
+ game_configs_get_current (game_configs, &game_config);
nx = player_xpos + dx;
ny = player_ypos + dy;
@@ -912,7 +921,7 @@ try_player_move (gint dx, gint dy)
load_temp_arena ();
if (temp_arena[nx][ny] == OBJECT_HEAP) {
- if (game_config ()->moveable_heaps) {
+ if (game_config.moveable_heaps) {
if (!push_heap (nx, ny, dx, dy)) {
push_xpos = push_ypos = -1;
return FALSE;
diff --git a/src/gnome-robots.c b/src/gnome-robots.c
index b173736..b42bccc 100644
--- a/src/gnome-robots.c
+++ b/src/gnome-robots.c
@@ -34,7 +34,7 @@
#include <libgnome-games-support.h>
#include "gbdefs.h"
-#include "gameconfig.h"
+#include "riiv.h"
#include "graphics.h"
#include "sound.h"
#include "properties.h"
@@ -460,7 +460,8 @@ activate (GtkApplication *app, gpointer user_data)
gtk_widget_show_all (window);
- if (!load_game_configs ()) {
+ game_configs = game_configs_new_load (NULL);
+ if (!game_configs) {
/* Oops, no configs, we probably haven't been installed properly. */
errordialog = gtk_message_dialog_new_with_markup (NULL, 0, GTK_MESSAGE_ERROR,
GTK_BUTTONS_OK,
diff --git a/src/meson.build b/src/meson.build
index 085e9a1..3342577 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -1,13 +1,27 @@
+add_project_arguments(['--vapidir', meson.current_source_dir()], language: 'vala')
+
+
+config_header = configure_file(
+ output: 'config.h',
+ configuration: config_h
+)
+
+vapi_sources = files(
+ 'config.vapi',
+)
+
vala_sources = files(
'image-suffix-list.vala',
'file-list.vala',
'find-file.vala',
'preimage.vala',
'controls.vala',
+ 'game-config.vala',
)
vala_lib = static_library('riiv',
- vala_sources,
+ config_header,
+ vapi_sources + vala_sources,
dependencies: [
gee_dependency,
gio_dependency,
@@ -27,7 +41,6 @@ riiv_dependency = declare_dependency(
sources = files(
'cursors.c',
'game.c',
- 'gameconfig.c',
'gnome-robots.c',
'graphics.c',
'keyboard.c',
@@ -40,11 +53,6 @@ resources = gnome.compile_resources(
source_dir: '../'
)
-config_header = configure_file(
- output: 'config.h',
- configuration: config_h
-)
-
executable(
meson.project_name(),
sources + resources,
diff --git a/src/properties.c b/src/properties.c
index d60c4cb..079196c 100644
--- a/src/properties.c
+++ b/src/properties.c
@@ -28,7 +28,6 @@
#include <libgnome-games-support.h>
#include "properties.h"
-#include "gameconfig.h"
#include "gnome-robots.h"
#include "graphics.h"
#include "gbdefs.h"
@@ -37,6 +36,9 @@
#include "riiv.h"
+GameConfigs* game_configs;
+
+
/**********************************************************************/
/* Defines */
/**********************************************************************/
@@ -203,16 +205,19 @@ pmap_selection (GtkWidget * widget, gpointer data)
static void
type_selection (GtkWidget * widget, gpointer data)
{
- gchar *config;
+ GameConfig *config;
+ gchar *config_name;
gint num = gtk_combo_box_get_active (GTK_COMBO_BOX (widget));
properties.selected_config = num;
- config = game_config_name (properties.selected_config);
- conf_set_configuration (config);
- g_free (config);
+ config = game_configs_get (game_configs, (guint)properties.selected_config);
+
+ config_name = game_config_name (config);
+ conf_set_configuration (config_name);
+ g_free (config_name);
- set_game_config (properties.selected_config);
+ game_configs_set_current_index (game_configs, (guint)properties.selected_config);
start_new_game ();
}
@@ -310,8 +315,8 @@ fill_typemenu (GtkWidget * menu)
gint i;
gchar *config;
- for (i = 0; i < num_game_configs (); ++i) {
- config = game_config_name (i);
+ for (i = 0; i < game_configs_count (game_configs); ++i) {
+ config = game_configs_get_name (game_configs, (guint)i);
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (menu), _(config));
g_free (config);
}
@@ -565,8 +570,8 @@ load_properties (void)
cname = g_settings_get_string (settings, KEY_CONFIGURATION);
properties.selected_config = 0;
- for (i = 0; i < num_game_configs (); ++i) {
- config = game_config_name (i);
+ for (i = 0; i < game_configs_count (game_configs); ++i) {
+ config = game_configs_get_name (game_configs, (guint)i);
if (!strcmp (cname, config)) {
g_free (config);
properties.selected_config = i;
@@ -582,7 +587,7 @@ load_properties (void)
properties.show_toolbar = g_settings_get_boolean (settings, KEY_SHOW_TOOLBAR);
load_game_graphics ();
- set_game_config (properties.selected_config);
+ game_configs_set_current_index (game_configs, (guint)properties.selected_config);
keyboard_set (properties.keys);
return TRUE;
}
@@ -677,7 +682,7 @@ save_properties (void)
conf_set_theme (properties.themename);
- config = game_config_name (properties.selected_config);
+ config = game_configs_get_name (game_configs, (guint)properties.selected_config);
conf_set_configuration (config);
g_free (config);
@@ -766,9 +771,10 @@ properties_show_toolbar (void)
gboolean
properties_set_config (gint n)
{
- if (!set_game_config (n))
+ if (n >= game_configs_count (game_configs))
return FALSE;
+ game_configs_set_current_index (game_configs, (guint)n);
properties.selected_config = n;
return TRUE;
diff --git a/src/properties.h b/src/properties.h
index aeceadf..0f9c7d1 100644
--- a/src/properties.h
+++ b/src/properties.h
@@ -1,6 +1,10 @@
#ifndef PROPERTIES_H
#define PROPERTIES_H
+#include "riiv.h"
+
+extern GameConfigs* game_configs;
+
/**********************************************************************/
/* Exported functions */
/**********************************************************************/
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]