diff options
author | nathan <thenathansmithsmith@gmail.com> | 2023-04-07 00:36:56 +0000 |
---|---|---|
committer | nathan <thenathansmithsmith@gmail.com> | 2023-04-07 00:36:56 +0000 |
commit | 4fb3172f1baf4813fcc18259b971bfe121e5f116 (patch) | |
tree | 342a6106bb819f87a7099db45574494a72a1fffa /src | |
download | color_game-4fb3172f1baf4813fcc18259b971bfe121e5f116.tar.gz color_game-4fb3172f1baf4813fcc18259b971bfe121e5f116.tar.bz2 color_game-4fb3172f1baf4813fcc18259b971bfe121e5f116.zip |
first commit
Diffstat (limited to 'src')
-rw-r--r-- | src/color_box.h | 351 | ||||
-rw-r--r-- | src/color_game.cpp | 189 | ||||
-rw-r--r-- | src/handle_json.h | 58 | ||||
-rw-r--r-- | src/icon.rc | 1 | ||||
-rw-r--r-- | src/icon.res | bin | 0 -> 93326 bytes | |||
-rw-r--r-- | src/input.h | 253 | ||||
-rw-r--r-- | src/map.h | 141 | ||||
-rw-r--r-- | src/window.h | 166 |
8 files changed, 1159 insertions, 0 deletions
diff --git a/src/color_box.h b/src/color_box.h new file mode 100644 index 0000000..8162640 --- /dev/null +++ b/src/color_box.h @@ -0,0 +1,351 @@ +class ColorBox : public Fl_Box { + public: + ColorBox(int _x, int _y, int _w, int _h, const char * l=0) : + Fl_Box(_x, _y, _w, _h, l) { + box(FL_UP_BOX); + labeltype(FL_SHADOW_LABEL); + } + + int handle(int event); + + void xy_vars(int _x, int _y) { + this->_x = _x; + this->_y = _y; + } + + void set_overlap(bool overlap) { + this->overlap = overlap; + } + + bool set_overlap() { + return overlap; + } + + void setbox(); + private: + int _x, _y; + bool overlap; + int old_x, old_y; +}; + +void add_boxs() { + int _y, _x, _font_size; + memset(all_colors, 0, sizeof(all_colors)); + + bside = (_window->w() - _window->h()) / 2; + bsize = _window->h() / MBLOCKS; + _font_size = bsize / 2; + + for (_y = 0; _y < 50; _y++) + for (_x = 0; _x < 50; _x++) { + + if (_y + map_y_offset >= MBLOCKS || + _x + map_x_offset >= MBLOCKS) { + if (boxs[_y][_x]) + boxs[_y][_x]->hide(); + continue; + } + + all_colors[color_map[_y][_x]]++; + + // Add boxes. + if (!boxs[_y][_x]) + boxs[_y][_x] = new ColorBox(0, 0, 0, 0); + + boxs[_y][_x]->resize((_x * bsize) + bside, _y * + bsize, bsize, bsize); + + // Activate. + if (g_active) + boxs[_y][_x]->activate(); + + // Hide some boxes. + if (color_map[_y][_x] == 0) { + boxs[_y][_x]->hide(); + continue; + } + + boxs[_y][_x]->show(); + + // Adding color and label to boxes. + boxs[_y][_x]->label(color_to_label(color_map[_y][_x])); + boxs[_y][_x]->labelsize(_font_size); + boxs[_y][_x]->color(color_to_flcolor(color_map[_y][_x])); + boxs[_y][_x]->xy_vars(_x, _y); + boxs[_y][_x]->set_overlap(false); + + if (color_map[_y][_x] == BLACK) + boxs[_y][_x]->labelcolor(FL_GRAY); + else + boxs[_y][_x]->labelcolor(FL_BLACK); + } + + _window->redraw(); +} + +void act_boxs(bool act) { + int x, y; + + for (y = 0; y < MBLOCKS; y++) + for (x = 0; x < MBLOCKS; x++) { + if (boxs[y][x]) { + if (act) + boxs[y][x]->activate(); + else + boxs[y][x]->deactivate(); + } + } + + if (overlap_wid) + overlap_wid->resize(0, 0, 0, 0); +} + +int ColorBox::handle(int event) { + int i, the_x, the_y, real_x, real_y; + + switch(event) { + case FL_ENTER: + if (!g_active || !active_r()) + return 1; + + if (!overlap && color() != FL_GRAY && color() != FL_WHITE && + color() != FL_BLACK && color() != FL_BROWN) { + int _font_size = bsize / 2; + + overlap_wid->labelsize(_font_size); + overlap_wid->xy_vars(_x, _y); + overlap_wid->resize((_x * bsize) + bside, _y * + bsize, bsize, bsize); + + overlap_wid->set_overlap(true); + overlap_wid->color(color()); + overlap_wid->labelcolor(labelcolor()); + + overlap_wid->label(label()); + } + + return 1; + case FL_PUSH: + return 1; + case FL_DRAG: + if (!g_active || !active_r()) + return 1; + + switch(Fl::event_button()) { + case FL_LEFT_MOUSE: + + if (!overlap) + break; + + position(Fl::event_x(), Fl::event_y()); + + // Stop box from leaving window. + real_x = x() + (w() / 2); + real_y = y() + (h() / 2); + + if (real_x <= 0) + position(3, y()); + if (real_x >= _window->w()) + position(_window->w() - (w() + 3), y()); + if (real_y <= 0) + position(x(), 3); + if (real_y >= _window->h()) + position(x(), _window->h() - (h() + 3)); + + // Drawing. + if (old_x && old_y) { + old_x = (old_x - x()) * 3; + old_y = (old_y - y()) * 3; + + if (old_x < 0) + old_x *= -1; + if (old_y < 0) + old_y *= -1; + + if (old_x == 0) + old_x = 100; + if (old_y == 0) + old_y = 100; + + _window->damage(FL_DAMAGE_ALL, x() - old_x, + y() - old_y, w() + (old_x * 2), h() + + (old_y * 2)); + } else + _window->redraw(); + + old_x = x(); + old_y = y(); + + break; + default: + break; + } + + return 1; + case FL_RELEASE: + + if (Fl::event_button() == FL_LEFT_MOUSE) + setbox(); + + return 1; + default: + return 0; + } +} + +void ColorBox::setbox() { + int x_block = (x() - bside) / bsize; + int y_block = y() / bsize; + int _font_size, repos_t = 0; + unsigned char ccolor = color_map[_y][_x], chc = 0; + bool repos = false; + + if (!overlap) + return; + else if (!boxs[y_block][x_block]) { + resize(0, 0, 0, 0); + _window->redraw(); + return; + } + + resize(0, 0, 0, 0); + + // Color combo. + switch (color_map[y_block][x_block]) { + case BLANK: + repos = true; + break; + case RED: + if (ccolor == GREEN) + repos = true; + break; + case YELLOW: + if (ccolor == RED) + repos = true; + break; + case GREEN: + if (ccolor == BLUE) + repos = true; + break; + case BLUE: + if (ccolor == YELLOW) + repos = true; + break; + case WHITE: + chc = 1; + repos = true; + break; + case BLACK: + chc = 2; + repos = true; + break; + default: + break; + } + + if (!repos) { + _window->redraw(); + return; + } + + // Distances. + if (x_block > _x) { + if (x_block - _x == 1) + repos = true; + else + repos = false; + repos_t++; + } if (_x > x_block) { + if (_x - x_block == 1) + repos = true; + else + repos = false; + repos_t++; + } if (y_block > _y) { + if (y_block - _y == 1) + repos = true; + else + repos = false; + repos_t++; + } if (_y > y_block) { + if (_y - y_block == 1) + repos = true; + else + repos = false; + repos_t++; + } + + // repos_t stops diagonal movemet. + if (repos_t > 1) + repos = false; + else if (repos && chc > 0) { + unsigned char new_color; + + // White. + if (chc == 1) { + switch (ccolor) { + case RED: + new_color = BLUE; + break; + case YELLOW: + new_color = GREEN; + break; + case GREEN: + new_color = YELLOW; + break; + case BLUE: + new_color = RED; + break; + default: + break; + } + // Black. + } else if (chc == 2) { + switch(ccolor) { + case RED: + new_color = GREEN; + break; + case YELLOW: + new_color = RED; + break; + case GREEN: + new_color = BLUE; + break; + case BLUE: + new_color = YELLOW; + break; + default: + break; + } + } + + all_colors[new_color]++; + all_colors[color_map[y_block][x_block]]--; + + color_map[y_block][x_block] = new_color; + int _font_size = bsize / 2; + + boxs[y_block][x_block]->labelsize(_font_size); + boxs[y_block][x_block]->color(color_to_flcolor(new_color)); + boxs[y_block][x_block]->label(color_to_label(new_color)); + boxs[y_block][x_block]->labelcolor(FL_BLACK); + + } else if (repos) { + all_colors[color_map[_y][_x]]++; + all_colors[color_map[y_block][x_block]]--; + + color_map[y_block][x_block] = color_map[_y][_x]; + _font_size = bsize / 2; + + boxs[y_block][x_block]->labelsize(_font_size); + boxs[y_block][x_block]->color(color()); + boxs[y_block][x_block]->labelcolor(labelcolor()); + boxs[y_block][x_block]->label(label()); + } + + int da_size = (bsize * 2 + 10); + + _window->damage(FL_DAMAGE_ALL, boxs[y_block][x_block]->x() - da_size, + boxs[y_block][x_block]->y() - da_size, boxs[y_block][x_block]->w() + da_size * 2, + boxs[y_block][x_block]->h() + da_size * 2); +} diff --git a/src/color_game.cpp b/src/color_game.cpp new file mode 100644 index 0000000..298f404 --- /dev/null +++ b/src/color_game.cpp @@ -0,0 +1,189 @@ +// FLTK headers. +#include "FL/Fl.H" +#include "FL/Fl_Double_Window.H" +#include "FL/Fl_Box.H" +#include "FL/Fl_Button.H" +#include "FL/Fl_Output.H" +#include "FL/Fl_Multiline_Output.H" +#include "FL/Fl_File_Browser.H" +#include "FL/Fl_PNG_Image.H" + +#ifndef FL_BROWN + #define FL_BROWN 0x65432100 +#endif + +#ifdef _WIN32 + #define dir_to_map_prf "%smaps\\" + #include <windows.h> + #include "FL/x.H" +#else + #define dir_to_map_prf "%smaps/" +#endif + +// Main Folder. +// MAINDIR must end with / or \ (windows) and be a full path. +#ifdef _WIN32 + #define MAINDIR ".\\" +#else + #define MAINDIR "/usr/local/share/color_game/" +#endif + +#define check_game_speed 5.0 +#define max_map 50 +#define button_gap 10 +// buttet_height is the fraction of bside. +#define button_height 7 + +// Max blocks. +int MBLOCKS; + +// Window. +Fl_Double_Window * _window; + +// Color boxes. +class ColorBox; +ColorBox * boxs[50][50]; +ColorBox * overlap_wid; + +// Buttons. +Fl_Button * startb; +Fl_Button * exit_button; +Fl_Button * fullsc_button; +Fl_Button * browse_maps; + +// Output. +Fl_Multiline_Output * _output; + +// Browser. +class MapBrowser; +MapBrowser * map_browser; + +// Error box. +Fl_Button * ok_button; +Fl_Output * error_msg; + +// Game over +Fl_Button * game_over; + +// Screen size and flags. +int bside, bsize; +bool g_active, ext_used; + +// Std lib. +#include <cstdlib> +#include <cstdio> +#include <cstring> + +// My headers. +#include "handle_json.h" +#include "map.h" +#include "color_box.h" +#include "input.h" +#include "window.h" + +int main(int argv, char ** args) { + Fl::background(0xC0, 0xC0, 0xC0); + g_active = false; + ext_used = false; + + _window = new MyWindow(Fl::w() / 2, Fl::h() / 2, "color game"); + _window->xclass("color game"); + + bside = (_window->w() - _window->h()) / 2; + bsize = _window->h() / MBLOCKS; + + int bw, by; + bw = bside - (bside / 3); + by = bside / button_height; + + add_boxs(); + + // Start button. + startb = new Fl_Button((_window->w() / 2) - (bside / 2), + (_window->h() / 2) - (bside / 4), bside, bside / 2, "Start"); + startb->labelsize(bw / 4); + startb->color(FL_BLUE); + startb->labelcolor(FL_WHITE); + startb->callback(startb_cb); + startb->box(FL_ROUNDED_BOX); + act_boxs(false); + + // Exit button. + exit_button = new Fl_Button(0, 0, bw, by, "Exit"); + exit_button->labelsize(bw / 4); + exit_button->callback(exit_cb); + exit_button->shortcut(FL_Escape); + + // Fullscreen button. + fullsc_button = new Fl_Button(0, 0, bw, by, "Fullscreen"); + fullsc_button->labelsize(bw / 6); + fullsc_button->callback(fullsc_cb); + fullsc_button->shortcut(FL_F + 11); + + // Output. + _output = new Fl_Multiline_Output((_window->w() - bside) + 10, 10, \ + bside - 20, _window->h() - 20); + _output->textsize(_output->w() / 8); + + // Browser button. + browse_maps = new Fl_Button(0, 0, bw, by, "maps"); + browse_maps->labelsize(browse_maps->w() / 5); + browse_maps->when(FL_WHEN_CHANGED); + browse_maps->callback(browse_cb); + + // Overlap. + overlap_wid = new ColorBox(0, 0, 0, 0); + + // Browser. + map_browser = new MapBrowser((_window->w() / 2) - (_window->w() / 4), + (_window->h() / 2) - (_window->h() / 4), _window->w() / 2, + _window->h() / 2, "Map Browser"); + + // Error box. + int e_w, e_h, e_x, e_y; + e_w = _window->w() / 5; + e_h = _window->h() / 8; + e_x = (_window->w() / 2) - (e_w / 2); + e_y = (_window->h() / 2) - (e_h / 2); + + error_msg = new Fl_Output(e_x, e_y, e_w, e_h); + error_msg->hide(); + + ok_button = new Fl_Button(e_x, e_y + e_h, e_w, e_h, "Ok"); + ok_button->callback(error_cb); + ok_button->hide(); + + // Game over. + int gx, gy, gw, gh; + gw = _window->w() / 3; + gh = _window->h() / 5; + gx = (_window->w() / 2) - (gw / 2); + gy = (_window->h() / 2) - (gh / 2); + + game_over = new Fl_Button(gx, gy, gw, gh, "You Win! (:"); + game_over->box(FL_UP_BOX); + game_over->labeltype(FL_SHADOW_LABEL); + game_over->labelsize(gw / 7); + game_over->hide(); + game_over->callback(startb_cb); + + _window->end(); + _window->resizable(_window); + ((MyWindow*)_window)->reset_sizes(); + + // Setting window icon. + #ifdef _WIN32 + _window->icon((char*)LoadIcon(fl_display, MAKEINTRESOURCE(101))); + #else + char icon_image_path[255]; + sprintf(icon_image_path, "%sicon.png", MAINDIR); + Fl_PNG_Image * icon_image = + new Fl_PNG_Image((const char*)icon_image_path); + + if (!icon_image->fail()) + _window->icon(icon_image); + #endif + + _window->show(argv, args); + return Fl::run(); +} diff --git a/src/handle_json.h b/src/handle_json.h new file mode 100644 index 0000000..ddf5934 --- /dev/null +++ b/src/handle_json.h @@ -0,0 +1,58 @@ +#include "json.h" + +bool get_jsonf_size(json_value * value, int * w, int * h) { + json_object_entry _size = value->u.object.values[0]; + json_object_entry * _size_objects = _size.value->u.object.values; + + if (strcmp(_size.name, "size")) + return true; + + // Width. + if (!strcmp(_size_objects[0].name, "w")) + *w = _size_objects[0].value->u.integer; + else if (!strcmp(_size_objects[0].name, "h")) + *h = _size_objects[0].value->u.integer; + else + return true; + + // Height + if (!strcmp(_size_objects[1].name, "w")) + *w = _size_objects[1].value->u.integer; + else if (!strcmp(_size_objects[1].name, "h")) + *h = _size_objects[1].value->u.integer; + else + return true; + + if (*w > 255 || *w < 2 || *h > 255 || *h < 2) + return true; + + return false; +} + +bool read_data_jsonf(json_value * value, int w, int h, unsigned char ** buf) { + json_object_entry _size = value->u.object.values[0]; + json_object_entry _map = value->u.object.values[1]; + json_value ** astart = _map.value->u.array.values; + + if (strcmp(_size.name, "size") || + strcmp(_map.name, "map")) + return true; + + unsigned char y, x; + long int int_value; + + for (y = 0; y < h; y++) + for (x = 0; x < w; x++) { + + if (astart[y]->u.array.values[x]->type != json_integer) + return true; + + int_value = astart[y]->u.array.values[x]->u.integer; + + if (int_value > 8 || int_value < 0) + return true; + buf[y][x] = (unsigned char)int_value; + } + + return false; +} diff --git a/src/icon.rc b/src/icon.rc new file mode 100644 index 0000000..c5bd20b --- /dev/null +++ b/src/icon.rc @@ -0,0 +1 @@ +101 ICON DISCARDABLE icons.windows/icon.ico diff --git a/src/icon.res b/src/icon.res Binary files differnew file mode 100644 index 0000000..8cab40e --- /dev/null +++ b/src/icon.res diff --git a/src/input.h b/src/input.h new file mode 100644 index 0000000..c80c78f --- /dev/null +++ b/src/input.h @@ -0,0 +1,253 @@ +/* +Warning ugly code on line 248 turn back now if u +want to keep your joy and happens. +*/ + +void show_error(const char * label) { + ok_button->show(); + ok_button->labelsize(ok_button->w() / 5); + error_msg->show(); + error_msg->value(label); + + if (!g_active) + startb->do_callback(); + + act_boxs(false); +} + +void error_cb(Fl_Widget * w, void * d) { + ok_button->hide(); + error_msg->hide(); + act_boxs(true); +} + +class MapBrowser : public Fl_File_Browser { + public: + MapBrowser(int _x, int _y, int _w, int _h, const char * l=0) : + Fl_File_Browser(_x, _y, _w, _h, l) { + sprintf(mapdir, dir_to_map_prf, MAINDIR); + + load(mapdir); + type(FL_HOLD_BROWSER); + hide(); + callback(map_browser_cb, (void*)this); + + int bw, bh; + bw = w() / 5; + bh = h() / 5; + + close_button = new Fl_Button(x(), y() - bh, bw, bh, + "close"); + close_button->callback(close_cb, (void*)this); + close_button->labelsize(bw / 3); + close_button->hide(); + + if (text(1)) + if (!strcmp(text(1), "../")) + remove(1); + } + + static void map_browser_cb(Fl_Widget * w, void * d) { + MapBrowser * br = (MapBrowser*)d; + br->real_cb(); + } + + void show_all() { + close_button->show(); + show(); + act_boxs(false); + } + + void hide_all() { + close_button->hide(); + hide(); + + if (g_active) + act_boxs(true); + } + + bool is_visible() { + if (close_button->visible()) + return true; + else + return false; + } + + static void close_cb(Fl_Widget * w, void * d) { + MapBrowser * br = (MapBrowser*)d; + br->hide_all(); + } + + void handle_resize() { + close_button->labelsize(close_button->w() / 3); + } + + void real_cb(); + private: + Fl_Button * close_button; + int last_clicked; + char mapdir[255]; +}; + +void MapBrowser::real_cb() { + + if (!text(value())) + return; + else if (last_clicked != value()) { + last_clicked = value(); + return; + } + + last_clicked = -1; + map_browser->hide_all(); + + // Loading json. + char filename[255]; + sprintf(filename, "%s%s", mapdir, text(value())); + + FILE * fp = fopen(filename, "rt"); + + if (!fp) { + show_error("File not found"); + fclose(fp); + return; + } + + long int file_size = findsize(fp); + char file_buf[file_size]; + file_buf[0] = '\0'; + file_buf[file_size] = '\0'; + int a_w, a_h, c, r; + + fread(file_buf, file_size, 1, fp); + fclose(fp); + + json_value * _value = json_parse(file_buf, file_size); + + if (!_value) { + show_error("Can't read map"); + return; + } + + if (get_jsonf_size(_value, &a_w, &a_h)) { + show_error("Bad formatt"); + return; + } + + // Making 2d array. + unsigned char ** the_map = new unsigned char*[a_h]; + unsigned char i; + + if (the_map == NULL) { + show_error("Can't malloc data"); + delete [] the_map; + return; + } + + for (i = 0; i < a_h; i++) + the_map[i] = new unsigned char[a_w]; + + // Reading data. + if (read_data_jsonf(_value, a_w, a_h, the_map)) { + show_error("Bad formatt"); + + // Deleting memory. + for (i = 0; i < a_h; i++) { + delete [] the_map[i]; + } + + delete [] the_map; + + return; + } + + // Settings Max blocks. + if (a_w > a_h) + MBLOCKS = a_w; + else + MBLOCKS = a_h; + + if (a_w > max_map || a_h > max_map) { + // Deleting memory. + for (i = 0; i < a_h; i++) { + delete [] the_map[i]; + } + + delete [] the_map; + + loaded_map = false; + map_init(); + add_boxs(); + + show_error("Map is to big"); + return; + } + + map_init(the_map, a_w, a_h); + + // Deleting memory. + for (i = 0; i < a_h; i++) { + delete [] the_map[i]; + } + + delete [] the_map; + loaded_map = true; + + add_boxs(); + + // Activate game. + if (!g_active) + startb->do_callback(); + g_active = true; +} + +void startb_cb(Fl_Widget * w, void * d) { + int bw, by; + bw = bside - (bside / 3); + by = bside / 5; + ext_used = false; + + if (!g_active) { + g_active = true; + startb->label("Restart"); + startb->labelsize(bw / 5); + startb->resize(10, 10, exit_button->w(), + exit_button->h()); + startb->color(FL_GRAY); + startb->labelcolor(FL_BLACK); + startb->box(FL_UP_BOX); + act_boxs(true); + } + + overlap_wid->resize(0, 0, 0, 0); + map_init(); + add_boxs(); + + game_over->hide(); +} + +void exit_cb(Fl_Widget * w, void * d) { + _window->hide(); +} + +void fullsc_cb(Fl_Widget * w, void * d) { + if (_window->fullscreen_active()) + _window->fullscreen_off(); + else + _window->fullscreen(); +} + +void browse_cb(Fl_Widget * w, void * d) { + /* + My compiler was being stupid. The extistence of + this code makes me angery. + It should look like this: + game_over->hide(); + Why do I have to do this! + */ + if (game_over->visible()) + startb->do_callback(); + // The saddness is over for now. + + map_browser->show_all(); +} diff --git a/src/map.h b/src/map.h new file mode 100644 index 0000000..7f1c301 --- /dev/null +++ b/src/map.h @@ -0,0 +1,141 @@ +#define RED 1 +#define YELLOW 2 +#define GREEN 3 +#define BLUE 4 + +#define WHITE 5 +#define BLACK 6 +#define BROWN 7 +#define BLANK 8 + +// 0 == not part of the map. + +unsigned char info_output[9]; +unsigned char all_colors[9]; +unsigned char color_map[max_map][max_map]; +unsigned char old_color_map[max_map][max_map]; +bool loaded_map; +int map_x_offset, map_y_offset; + +unsigned char default_map[9][8] = { + {0, 0, 0, 0, 0, 0, 8, 8}, // 1 + {0, 0, 4, 3, 2, 0, 8, 4}, // 2 + {6, 8, 8, 8, 8, 8, 8, 0}, // 3 + {0, 8, 0, 8, 0, 8, 8, 0}, // 4 + {0, 1, 8, 8, 8, 8, 0, 0}, // 5 + {0, 0, 8, 0, 8, 8, 8, 8}, // 6 + {0, 8, 8, 0, 8, 8, 8, 5}, // 7 + {0, 0, 8, 0, 8, 0, 0, 0}, // 8 + {0, 0, 2, 7, 8, 0, 0, 0} // 9 +}; + +const char * color_to_label(unsigned char _color) { + switch (_color) { + case RED: + return "R"; + case YELLOW: + return "Y"; + case GREEN: + return "G"; + case BLUE: + return "B"; + case WHITE: + return "W"; + case BLACK: + return "X"; + case BROWN: + return "N"; + default: + return "\0"; + } +} + +Fl_Color color_to_flcolor(unsigned char _color) { + switch (_color) { + case RED: + return FL_RED; + case YELLOW: + return FL_YELLOW; + case GREEN: + return FL_GREEN; + case BLUE: + return FL_BLUE; + case WHITE: + return FL_WHITE; + case BLACK: + return FL_BLACK; + case BROWN: + return FL_BROWN; + default: + return FL_GRAY; + } +} + +long int findsize(FILE * fp) { + fseek(fp, 0L, SEEK_END); + long int _size = ftell(fp); + fseek(fp, 0L, SEEK_SET); + return _size; +} + +void map_init(unsigned char ** new_map=NULL, int a_w=0, int a_h=0) { + memset(color_map, 0, sizeof(color_map)); + memset(all_colors, 0, sizeof(all_colors)); + ext_used = false; + + int x, y; + + /* + Sorry this function is a bit hacky. + It was made for testing but then made + it to this version. + */ + + // Loading new maps. + if (new_map || loaded_map) { + + // For rectangle shaped maps. + if (new_map) { + map_x_offset = 0; + map_y_offset = 0; + + if (a_w < MBLOCKS) + map_x_offset = MBLOCKS - a_w; + if (a_h < MBLOCKS) + map_y_offset = MBLOCKS - a_h; + } + + for (y = 0; y < MBLOCKS; y++) + for (x = 0; x < MBLOCKS; x++) { + + if (y + map_y_offset >= MBLOCKS || + x + map_x_offset >= MBLOCKS) + continue; + + if (loaded_map && !new_map) + color_map[y][x] = old_color_map[y][x]; + else { + color_map[y][x] = new_map[y][x]; + old_color_map[y][x] = color_map[y][x]; + } + + all_colors[color_map[y][x]]++; + info_output[color_map[y][x]]++; + } + + loaded_map = true; + return; + } + + // Default map. + MBLOCKS = 9; + for (y = 0; y < MBLOCKS; y++) + for (x = 0; x < MBLOCKS; x++) { + + if (y < 9 && x < 8) + color_map[y][x] = default_map[y][x]; + + all_colors[color_map[y][x]]++; + info_output[color_map[y][x]]++; + } +} diff --git a/src/window.h b/src/window.h new file mode 100644 index 0000000..3eeb848 --- /dev/null +++ b/src/window.h @@ -0,0 +1,166 @@ +class MyWindow : public Fl_Double_Window { + public: + MyWindow(int _w, int _h, const char * l=0) : + Fl_Double_Window(_w, _h, l) { + color(FL_GRAY); + map_init(); + old_w = w(); + old_h = h(); + Fl::add_timeout(1.0/check_game_speed, time_cb, (void*)this); + } + + static void time_cb(void * data) { + MyWindow * win = (MyWindow*)data; + win->real_time_cb(); + Fl::repeat_timeout(1.0/check_game_speed, time_cb, data); + } + + void reset_sizes(); + void real_time_cb(); + private: + int old_w, old_h; +}; + +void update_output() { + char buf[10], end_buf[100], clabel[8]; + unsigned char i; + buf[0] = '\0'; + end_buf[0] = '\0'; + clabel[0] = '\0'; + + for (i = 1; i < 9; i++) { + info_output[i] = all_colors[i]; + clabel[0] = '\0'; + + // Label. + switch(i) { + case BLANK: + strcat(clabel, "Blank"); + break; + default: + strcat(clabel, color_to_label(i)); + break; + } + + sprintf(buf, "%s %d\n", clabel, all_colors[i]); + strcat(end_buf, buf); + } + + _output->value(end_buf); +} + +void check_game() { + unsigned char i, ext_color = 0; + bool updated = false; + + // Checking colors and for game over. + for (i = 0; i < 9; i++) { + // Updating output. + if (info_output[i] != all_colors[i] && !updated) { + update_output(); + updated = true; + // Game over. + } if (all_colors[i] + all_colors[0] == (MBLOCKS - + map_x_offset) * (MBLOCKS - map_y_offset)) { + act_boxs(false); + game_over->show(); + break; + // Extinct color. + } if (all_colors[i] == 0 && i > 0 && i <= 4 && !ext_used) { + ext_color = i; + break; + } + } + + if (!ext_color) + return; + + int num_of_browns = 0, x, y, max_browns = all_colors[BROWN]; + + for (y = 0; y < MBLOCKS; y++) + for (x = 0; x < MBLOCKS; x++) { + + if (color_map[y][x] == BROWN) { + color_map[y][x] = ext_color; + boxs[y][x]->color(color_to_flcolor(ext_color)); + boxs[y][x]->label(color_to_label(ext_color)); + all_colors[ext_color]++; + num_of_browns++; + } + + if (num_of_browns >= max_browns) + break; + } + + all_colors[BROWN] = 0; + ext_used = true; +} + +void MyWindow::reset_sizes() { + // Varibles. + old_w = w(); + old_h = h(); + bside = (_window->w() - _window->h()) / 2; + bsize = _window->h() / MBLOCKS; + + int bw, by; + bw = bside - (bside / 3); + by = bside / button_height; + + // Overlap. + overlap_wid->resize(0, 0, 0, 0); + + // Start button position. + if (g_active) + startb->resize(10, 10, exit_button->w(), exit_button->h()); + + startb->labelsize(startb->w() / 4); + + // Exit button. + exit_button->labelsize(exit_button->w() / 4); + exit_button->position(10, 10 + button_gap + exit_button->h()); + + // Fullscreen button. + fullsc_button->labelsize(fullsc_button->w() / 6); + fullsc_button->position(10, exit_button->y() + exit_button->h() + button_gap); + + // Browse button. + browse_maps->labelsize(browse_maps->w() / 5); + browse_maps->position(10, fullsc_button->y() + fullsc_button->h() + button_gap); + + // Map browser. + map_browser->handle_resize(); + + // Output. + _output->textsize(_output->w() / 8); + + // Error. + ok_button->labelsize(ok_button->w() / 5); + + // Game over. + game_over->labelsize(game_over->w() / 7); + + add_boxs(); + + if (map_browser->is_visible()) + act_boxs(false); +} + +void MyWindow::real_time_cb() { + bool dont_resize = false; + + // Testing screen size. + float screen_ra = (float)w() / (float)h(); + + if (screen_ra > 2.0 || screen_ra < 1.75) { + size(w(), int((float)w() / 1.756653)); + dont_resize = true; + } + + // Window resizing. + if ((old_w != w() || old_h != h()) && !dont_resize) { + reset_sizes(); + } + + check_game(); +} |