diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..60c81e6
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,26 @@
+CC = g++
+CC_FLAGS = -s -O3 `pkg-config --cflags --libs gtkmm-4.0` -Wall -Wextra
+#debug flags:
+#CC_FLAGS = -ggdb -O3 `pkg-config --cflags --libs gtkmm-4.0` -Wall -Wextra
+
+all: build/bin/pupes-slots
+
+build/bin/pupes-slots: build/obj/main.o build/obj/main-winodow.o build/obj/ultra-mega-functions.o build/obj/confirm-dialog.o
+ $(CC) $(CC_FLAGS) build/obj/main.o build/obj/main-window.o build/obj/ultra-mega-functions.o build/obj/confirm-dialog.o -o build/bin/pupes-slots
+
+build/obj/main.o: src/main.cpp
+ mkdir -p build/obj
+ mkdir -p build/bin
+ $(CC) $(CC_FLAGS) -c src/main.cpp -o build/obj/main.o
+
+build/obj/main-winodow.o: src/main-window.cpp
+ $(CC) $(CC_FLAGS) -c src/main-window.cpp -o build/obj/main-window.o
+
+build/obj/ultra-mega-functions.o: src/ultra-mega-functions.cpp
+ $(CC) $(CC_FLAGS) -c src/ultra-mega-functions.cpp -o build/obj/ultra-mega-functions.o
+
+build/obj/confirm-dialog.o: src/confirm-dialog.cpp
+ $(CC) $(CC_FLAGS) -c src/confirm-dialog.cpp -o build/obj/confirm-dialog.o
+
+clean:
+ rm -fr build
\ No newline at end of file
diff --git a/img/Arch.svg b/img/Arch.svg
new file mode 100644
index 0000000..5c9cb6a
--- /dev/null
+++ b/img/Arch.svg
@@ -0,0 +1,47 @@
+
+
diff --git a/img/Beastie.svg b/img/Beastie.svg
new file mode 100644
index 0000000..10798ce
--- /dev/null
+++ b/img/Beastie.svg
@@ -0,0 +1,139 @@
+
+
diff --git a/img/Debian.svg b/img/Debian.svg
new file mode 100644
index 0000000..6a24580
--- /dev/null
+++ b/img/Debian.svg
@@ -0,0 +1,50 @@
+
+
diff --git a/img/DragonFly.svg b/img/DragonFly.svg
new file mode 100644
index 0000000..f6ff949
--- /dev/null
+++ b/img/DragonFly.svg
@@ -0,0 +1,268 @@
+
+
diff --git a/img/GNU.svg b/img/GNU.svg
new file mode 100644
index 0000000..39ee80c
--- /dev/null
+++ b/img/GNU.svg
@@ -0,0 +1,44 @@
+
+
diff --git a/img/Puffy.svg b/img/Puffy.svg
new file mode 100644
index 0000000..54618ce
--- /dev/null
+++ b/img/Puffy.svg
@@ -0,0 +1,2825 @@
+
+
diff --git a/img/Slackware.svg b/img/Slackware.svg
new file mode 100644
index 0000000..07c42eb
--- /dev/null
+++ b/img/Slackware.svg
@@ -0,0 +1,846 @@
+
+
+
+
diff --git a/img/Tux.svg b/img/Tux.svg
new file mode 100644
index 0000000..541945c
--- /dev/null
+++ b/img/Tux.svg
@@ -0,0 +1,1380 @@
+
+
diff --git a/src/confirm-dialog.cpp b/src/confirm-dialog.cpp
new file mode 100644
index 0000000..3cee2b7
--- /dev/null
+++ b/src/confirm-dialog.cpp
@@ -0,0 +1,38 @@
+#include "confirm-dialog.h"
+
+ConfirmDialog::ConfirmDialog()
+ : c_Label1("_First name", true),
+ c_ButtonBox(Gtk::Orientation::HORIZONTAL, 5), c_Button_OK("_OK", true),
+ c_Button_Cancel("_Cancel", true) {
+ set_destroy_with_parent(true);
+
+ set_title("Name Dialog");
+ set_child(c_Grid);
+
+ c_Grid.set_row_spacing(4);
+ c_Grid.set_column_spacing(4);
+ c_Grid.set_expand(true);
+
+ c_Image.set_from_icon_name("dialog-question");
+ c_Image.set_icon_size(Gtk::IconSize::LARGE);
+ c_Grid.attach(c_Image, 0, 0, 1, 2);
+
+ c_Grid.attach(c_Label1, 1, 0);
+ c_Grid.attach(c_Entry1, 2, 0);
+ c_Label1.set_mnemonic_widget(c_Entry1);
+
+ c_Grid.attach(c_ButtonBox, 0, 2, 3, 1);
+ c_ButtonBox.set_halign(Gtk::Align::END);
+ c_ButtonBox.append(c_Button_OK);
+ c_ButtonBox.append(c_Button_Cancel);
+}
+
+void ConfirmDialog::buttons_clicked_connect(
+ const sigc::slot &slot) {
+ c_Button_OK.signal_clicked().connect(sigc::bind(slot, "OK"));
+ c_Button_Cancel.signal_clicked().connect(sigc::bind(slot, "Cancel"));
+}
+
+Glib::ustring ConfirmDialog::get_entry1() const { return c_Entry1.get_text(); }
+
+ConfirmDialog::~ConfirmDialog() {}
diff --git a/src/confirm-dialog.h b/src/confirm-dialog.h
new file mode 100644
index 0000000..5bacfb8
--- /dev/null
+++ b/src/confirm-dialog.h
@@ -0,0 +1,26 @@
+#ifndef GTKMM_NAME_DIALOG_H_
+#define GTKMM_NAME_DIALOG_H_
+
+#include
+
+class ConfirmDialog : public Gtk::Window {
+public:
+ ConfirmDialog();
+ ~ConfirmDialog() override;
+
+ void
+ buttons_clicked_connect(const sigc::slot &slot);
+ Glib::ustring get_entry1() const;
+
+protected:
+ // Member widgets:
+ Gtk::Grid c_Grid;
+ Gtk::Image c_Image;
+ Gtk::Label c_Label1;
+ Gtk::Entry c_Entry1;
+ Gtk::Box c_ButtonBox;
+ Gtk::Button c_Button_OK;
+ Gtk::Button c_Button_Cancel;
+};
+
+#endif /* GTKMM_NAME_DIALOG_H_ */
\ No newline at end of file
diff --git a/src/main-window.cpp b/src/main-window.cpp
new file mode 100644
index 0000000..9805305
--- /dev/null
+++ b/src/main-window.cpp
@@ -0,0 +1,174 @@
+#include "main-window.h"
+#include "glib.h"
+#include "glibmm/ustring.h"
+#include "gtk/gtk.h"
+#include "gtkmm/image.h"
+#include "ultra-mega-functions.h"
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+MainWindow::MainWindow()
+ : m_button_spin("spin"), m_button_reset("reset money"),
+ m_button_quit("Quit"), slot_image0(), slot_image1(), slot_image2(),
+ m_label_money(), m_label_spins(), m_label_info(), m_label_bet("bet:"),
+ m_entry_bet(), m_timer_number(0) {
+ set_title("Pupes Slots!");
+
+ m_grid.set_margin(12);
+ set_child(m_grid);
+
+ can_spin = true;
+
+ money = 100;
+ spins = 0;
+
+ m_label_spins.set_label(std::to_string(spins));
+ m_label_money.set_label(std::to_string(money));
+
+ // set image size
+ slot_image0.set_size_request(128, 128);
+ slot_image1.set_size_request(128, 128);
+ slot_image2.set_size_request(128, 128);
+
+ // status rows
+ m_grid.attach(m_label_spins, 0, 0);
+ m_grid.attach(m_label_money, 0, 1);
+
+ // row 2: slots
+ m_grid.attach(slot_image0, 0, 2);
+ m_grid.attach(slot_image1, 1, 2);
+ m_grid.attach(slot_image2, 2, 2);
+
+ m_grid.attach(m_button_spin, 0, 3);
+ m_grid.attach(m_label_bet, 1, 3);
+ m_grid.attach(m_entry_bet, 2, 3);
+
+ m_grid.attach(m_button_reset, 1, 4);
+ m_grid.attach_next_to(m_button_quit, m_button_spin, Gtk::PositionType::BOTTOM,
+ 2, 1);
+
+ m_button_spin.signal_clicked().connect(
+ sigc::bind(sigc::mem_fun(*this, &MainWindow::on_button_spin)));
+
+ m_button_quit.signal_clicked().connect(
+ sigc::mem_fun(*this, &MainWindow::on_button_quit));
+}
+
+MainWindow::~MainWindow() {}
+
+void MainWindow::on_button_quit() { set_visible(false); }
+
+// define symbols for slots
+Glib::ustring symbol[8]{
+ IMG_FOLDER "/Arch.svg", IMG_FOLDER "/Debian.svg",
+ IMG_FOLDER "/Slackware.svg",
+
+ IMG_FOLDER "/Beastie.svg", IMG_FOLDER "/DragonFly.svg",
+ IMG_FOLDER "/Puffy.svg",
+
+ IMG_FOLDER "/GNU.svg", IMG_FOLDER "/Tux.svg"};
+
+void MainWindow::randomise_slots(bool save, Glib::ustring *slot_status) {
+ uint8_t randoms[3];
+
+ for (int i = 0; i < (sizeof(randoms) / sizeof(*randoms)); i++) {
+ randoms[i] = get_random_num(0, ((sizeof(symbol) / sizeof(*symbol)) - 1));
+ }
+ slot_image0.set(symbol[randoms[0]]);
+ slot_image1.set(symbol[randoms[1]]);
+ slot_image2.set(symbol[randoms[2]]);
+
+ if (save) {
+ for (int i = 0; i < (sizeof(randoms) / sizeof(*randoms)); i++) {
+ slot_status[i] = symbol[randoms[i]];
+ }
+ }
+}
+
+bool MainWindow::refresh_slots(int timer_number) {
+
+ std::cout << "This is timer " << timer_number;
+
+ // decrement and check counter value
+ if (--m_counters[timer_number] == 0) {
+ std::cout << " being disconnected" << std::endl;
+
+ // delete the counter entry in the STL MAP
+ m_counters.erase(timer_number);
+
+ // delete the connection entry in the STL MAP
+ m_timers.erase(timer_number);
+
+ Glib::ustring slot_status[3];
+ randomise_slots(true, slot_status);
+
+ // debug statement
+ for (int i = 0; i < (sizeof(slot_status) / sizeof(*slot_status)); i++) {
+ std::cout << "slot: " << i << " is " << slot_status[i] << std::endl;
+ }
+
+ // check if win
+ {
+ if ((slot_status[0].compare(slot_status[1])) == 0 &&
+ slot_status[0].compare(slot_status[2]) == 0) {
+ }
+ }
+
+ can_spin = true;
+ // return false, to stop timer
+ return false;
+ } else {
+ if (m_counters[timer_number] < (count_value * 0.4)) {
+ if (get_random_num(0, 1) == 1) {
+ randomise_slots(false, NULL);
+ }
+ } else if (m_counters[timer_number] < (count_value * 0.2)) {
+ if (get_random_num(0, 4) == 1) {
+ randomise_slots(false, NULL);
+ }
+ } else {
+ randomise_slots(false, NULL);
+ }
+ }
+ // Print the timer value
+ std::cout << " - " << m_counters[timer_number] << "/" << count_value
+ << std::endl;
+
+ // Keep going (do not disconnect yet):
+ return true;
+}
+
+void MainWindow::on_button_spin() {
+ if (can_spin) {
+ can_spin = false;
+ spins++;
+
+ m_label_spins.set_label(std::to_string(spins));
+
+ count_value = get_random_num(30, 50);
+ // Creation of a new object prevents long lines and shows us a little
+ // how slots work. We have 0 parameters and bool as a return value
+ // after calling sigc::bind.
+ sigc::slot my_slot = sigc::bind(
+ sigc::mem_fun(*this, &MainWindow::refresh_slots), m_timer_number);
+
+ // This is where we connect the slot to the Glib::signal_timeout()
+ auto conn = Glib::signal_timeout().connect(my_slot, 300);
+
+ // Remember the connection:
+ m_timers[m_timer_number] = conn;
+
+ // Initialize timer count:
+ m_counters[m_timer_number] = count_value + 1;
+
+ // Print some info to the console for the user:
+ std::cout << "added timeout " << m_timer_number++ << std::endl;
+ } else {
+ std::cerr << "you are already spining\n";
+ }
+}
diff --git a/src/main-window.h b/src/main-window.h
new file mode 100644
index 0000000..777d881
--- /dev/null
+++ b/src/main-window.h
@@ -0,0 +1,52 @@
+#ifndef GTKMM_EXAMPLEWINDOW_H
+#define GTKMM_EXAMPLEWINDOW_H
+
+#include "confirm-dialog.h"
+#include "glibmm/ustring.h"
+#include "gtkmm/image.h"
+#include "gtkmm/label.h"
+#include
+#include
+#define IMG_FOLDER "img"
+
+class MainWindow : public Gtk::Window {
+public:
+ MainWindow();
+ virtual ~MainWindow();
+
+private:
+ // Signal handlers:
+ void on_button_quit();
+ void on_button_spin();
+ bool refresh_slots(int timer_number);
+ void randomise_slots(bool save_to_global, Glib::ustring *slot_status);
+
+ // Child widgets:
+ Gtk::Grid m_grid;
+ Gtk::Label m_label_money, m_label_spins, m_label_info, m_label_bet;
+ Gtk::Image slot_image0, slot_image1, slot_image2;
+ Gtk::Button m_button_spin, m_button_reset, m_button_quit;
+ Gtk::Entry m_entry_bet;
+
+ // money and spin counters that can contain even most dihard gamblers
+ unsigned long long spins;
+ unsigned long long money;
+
+ // counter boobalob
+ int m_timer_number;
+
+ // These two constants are initialized in the constructor's member
+ // initializer:
+ int count_value;
+
+ bool can_spin;
+ // STL map for storing our connections
+ std::map m_timers;
+
+ // STL map for storing our timer values.
+ // Each timer counts back from COUNT_VALUE to 0 and is removed when it reaches
+ // 0
+ std::map m_counters;
+};
+
+#endif /* GTKMM_EXAMPLEWINDOW_H */
\ No newline at end of file
diff --git a/src/main.cpp b/src/main.cpp
new file mode 100644
index 0000000..5463777
--- /dev/null
+++ b/src/main.cpp
@@ -0,0 +1,9 @@
+#include "main-window.h"
+#include
+
+int main(int argc, char *argv[]) {
+ auto app = Gtk::Application::create("org.pupes.gamba");
+
+ // Shows the window and returns when it is closed.
+ return app->make_window_and_run(argc, argv);
+}
diff --git a/src/ultra-mega-functions.cpp b/src/ultra-mega-functions.cpp
new file mode 100644
index 0000000..6e7cf64
--- /dev/null
+++ b/src/ultra-mega-functions.cpp
@@ -0,0 +1,11 @@
+#include "ultra-mega-functions.h"
+#include
+
+int get_random_num(int min, int max) {
+ std::random_device dev;
+ std::mt19937 rng(dev());
+ std::uniform_int_distribution dist(
+ min, max); // set range
+
+ return dist(rng);
+}
diff --git a/src/ultra-mega-functions.h b/src/ultra-mega-functions.h
new file mode 100644
index 0000000..81fe7f2
--- /dev/null
+++ b/src/ultra-mega-functions.h
@@ -0,0 +1 @@
+int get_random_num(int min, int max);
\ No newline at end of file