00001
00007 #include <gtk/gtk.h>
00008 #include <stdlib.h>
00009 #include <time.h>
00010 #include <stdio.h>
00011 #include <string.h>
00012 #include <unistd.h>
00013 #include <sys/stat.h>
00014
00015 #include <main.h>
00016 #include <savegame_fe.h>
00017 #include <budget.h>
00018 #include <logging.h>
00019 #include <locking.h>
00020 #include <ui.h>
00021 #include <handler.h>
00022 #include <drawing.h>
00023 #include <globals.h>
00024 #include <build.h>
00025 #include <simulation.h>
00026 #include <disaster.h>
00027 #include <compilerpragmas.h>
00028 #include <nix_utils.h>
00029 #include <simulation-ui.h>
00030 #include <zonemon.h>
00031
00033 #define PATHSEARCH ".:./graphic:./graphic/icons:../graphic"
00034
00036 static struct main_window {
00037 GtkWidget *window;
00038 GtkWidget *drawing;
00039 GtkWidget *l_credits;
00040 GtkWidget *l_location;
00041 GtkWidget *l_pop;
00042 GtkWidget *l_time;
00044 GtkObject *sc_hor;
00045 GtkObject *sc_vert;
00047 GtkWidget *hscroll;
00048 GtkWidget *vscroll;
00050 GdkPixmap *p_zones;
00051 GdkPixmap *p_monsters;
00052 GdkPixmap *p_units;
00054 GdkPixmap *p_zones_m;
00055 GdkPixmap *p_monsters_m;
00056 GdkPixmap *p_units_m;
00058 GdkPixmap *p_mapzones;
00059 GdkPixmap *p_mapspecials;
00060 GdkPixmap *p_mapunits;
00062 GdkPixmap *p_play;
00063 } mw;
00064
00066 static char *exec_dir;
00067
00068 static void SetUpMainWindow(void);
00069 static gint mainloop_callback(gpointer data);
00070 static void QuitGame(void);
00071 static void SetSpeed(gpointer data, guint action, GtkWidget *w);
00072 static void cleanupPixmaps(void);
00073 static void ResetViewable(void);
00074 static void ShowMainWindow(void);
00075 static void forceRedistribute(void);
00076
00078 const GtkItemFactoryEntry menu_items[] = {
00079 { "/_File", NULL, NULL, 0, "<Branch>", 0 },
00080 { "/File/_New", "<control>N", newgame_handler, 0, NULL, 0 },
00081 { "/File/_Open", "<control>O", opengame_handler, 0, NULL, NULL },
00082 { "/File/_Save", "<control>S", savegame_handler, 0, NULL, 0 },
00083 { "/File/Save _As", NULL, savegameas_handler, 0, NULL, 0 },
00084 { "/File/sep1", NULL, NULL, 0, "<Separator>", 0 },
00085 { "/File/E_xit", "<alt>F4", QuitGame, 0, NULL, 0 },
00086 { "/_View", NULL, NULL, 0, "<Branch>", 0 },
00087 { "/View/_Budget", "<control>B", ViewBudget, 0, NULL, 0 },
00088 { "/View/_Map", "<control>M", showMap, 0, NULL, 0 },
00089 { "/View/_Hover", NULL, hoverShow, 0, NULL, 0 },
00090 { "/_Speed", NULL, NULL, 0, "<Branch>", 0 },
00091 { "/Speed/_Pause", "<control>0", SetSpeed, 1 + SPEED_PAUSED, NULL,
00092 NULL },
00093 { "/Speed/sep1", NULL, NULL, 0, "<Separator>", 0 },
00094 { "/Speed/_Slow", "<control>1", SetSpeed, 1 + SPEED_SLOW, NULL, NULL },
00095 { "/Speed/_Medium", "<control>2", SetSpeed, 1 + SPEED_MEDIUM, NULL,
00096 NULL },
00097 { "/Speed/_Fast", "<control>3", SetSpeed, 1 + SPEED_FAST, NULL, NULL },
00098 { "/Speed/_Turbo", "<control>4", SetSpeed, 1 + SPEED_TURBO, NULL,
00099 NULL },
00100 { "/S_imulation", NULL, NULL, 0, "<Branch>", 0 },
00101 { "/Simulation/_Redistribute", NULL, forceRedistribute, 0, NULL, NULL }
00102
00103 };
00104 #define NMENU_ITEMS (sizeof (menu_items) / sizeof (menu_items[0]))
00105
00113 int
00114 main(int argc, char **argv)
00115 {
00116 gint timerID;
00117 char *px;
00118
00119 exec_dir = strdup(argv[0]);
00120 px = strrchr(exec_dir, '/');
00121 if (px != NULL) {
00122 *px = '\0';
00123 } else {
00124
00125 g_print("Windows??\n");
00126 }
00127
00128 gtk_init(&argc, &argv);
00129 srand(time(NULL));
00130
00131 ResetViewable();
00132 SetUpMainWindow();
00133
00134 PCityMain();
00135 InitGameStruct();
00136 ConfigureNewGame();
00137
00138 ShowMainWindow();
00139
00140
00141 timerID = g_timeout_add(1000, (mainloop_callback), 0);
00142
00143 gtk_main();
00144 WriteLog("Cleaning up\n");
00145 g_source_remove(timerID);
00146 PurgeWorld();
00147 free(exec_dir);
00148 PCityShutdown();
00149 cleanupMap();
00150 cleanupPixmaps();
00151
00152 return (0);
00153 }
00154
00155 GtkWidget *
00156 window_main_get(void)
00157 {
00158 return (mw.window);
00159 }
00160
00161 GdkDrawable *
00162 drawable_main_get(void)
00163 {
00164 return (mw.window->window);
00165 }
00166
00167
00168 unsigned int timekeeper = 0;
00169
00170 unsigned int timekeeperdisaster = 0;
00171
00178 static void
00179 SetSpeed(gpointer data __attribute__((unused)), guint speed,
00180 GtkWidget *w __attribute__((unused)))
00181 {
00182 speed -= 1;
00183 WriteLog("Setting speed to %i\n", speed);
00184 setLoopSeconds(speed);
00185 }
00186
00192 static gint
00193 mainloop_callback(gpointer data __attribute__((unused)))
00194 {
00195
00196 unsigned int phase = 1;
00197
00198 timekeeper++;
00199 timekeeperdisaster++;
00200
00201 if (timekeeperdisaster >= SIM_GAME_LOOP_DISASTER) {
00202 MoveAllObjects();
00203 if (UpdateDisasters()) {
00204 gtk_widget_queue_draw(mw.drawing);
00205 }
00206 }
00207
00208 if (timekeeper >= getLoopSeconds() &&
00209 getLoopSeconds() != SPEED_PAUSED) {
00210 WriteLog("A month has gone by - total months: %lu\n",
00211 (unsigned long)getMonthsElapsed());
00212 timekeeper = 0;
00213 do {
00214 phase = Sim_DoPhase(phase);
00215 } while (phase != 0);
00216 gtk_widget_queue_draw(mw.drawing);
00217 }
00218
00219 UIUpdateBudget();
00220 return (TRUE);
00221 }
00222
00224 static UInt8 selectedBuildItem = 0;
00225
00232 static gint
00233 toolbox_callback(GtkWidget *widget __attribute__((unused)), gpointer data)
00234 {
00235 selectedBuildItem = GPOINTER_TO_INT(data);
00236 return (FALSE);
00237 }
00238
00240 static void
00241 ResetViewable(void)
00242 {
00244 setGameTileSize(16);
00245 setMapTileSize(4);
00246 }
00247
00254 void
00255 scrollbar(GtkAdjustment *adj __attribute__((unused)))
00256 {
00257 Goto(GTK_ADJUSTMENT(mw.sc_hor)->value,
00258 GTK_ADJUSTMENT(mw.sc_vert)->value, goto_center);
00259 }
00260
00270 void
00271 ResizeCheck(int width, int height)
00272 {
00273 GtkAdjustment *adjh = GTK_ADJUSTMENT(mw.sc_hor);
00274 GtkAdjustment *adjv = GTK_ADJUSTMENT(mw.sc_vert);
00275 setVisibleX(width / gameTileSize());
00276 setVisibleY(height / gameTileSize());
00277 adjh->lower = getVisibleX() / 2;
00278 adjh->upper = getMapWidth() + adjh->lower;
00279 adjv->lower = getVisibleY() / 2;
00280 adjv->upper = getMapHeight() + adjh->lower;
00281 if (adjh->value > adjh->upper) adjh->value = adjh->upper;
00282 if (adjv->value > adjv->upper) adjv->value = adjh->upper;
00283
00284 WriteLog("visx = %d, visy = %d\n", getVisibleX(), getVisibleY());
00285 WriteLog("hor: lower = %d, upper = %d\n", (int)adjh->lower,
00286 (int)adjh->upper);
00287 WriteLog("ver: lower = %d, upper = %d\n", (int)adjv->lower,
00288 (int)adjv->upper);
00289 gtk_adjustment_changed(adjh);
00290 gtk_adjustment_changed(adjv);
00291 gtk_adjustment_value_changed(adjh);
00292 gtk_adjustment_value_changed(adjv);
00293 }
00294
00304 void
00305 check_configure(GtkContainer *widget __attribute__((unused)),
00306 GdkEventConfigure *event,
00307 gpointer data __attribute__((unused)))
00308 {
00309 ResizeCheck(event->width, event->height);
00310 }
00311
00322 static gint
00323 delete_event(GtkWidget *widget __attribute__((unused)),
00324 GdkEvent *event __attribute__((unused)),
00325 gpointer data __attribute__((unused)))
00326 {
00327 gtk_main_quit();
00328 return (FALSE);
00329 }
00330
00341 static gint
00342 drawing_exposed_callback(GtkWidget *widget,
00343 GdkEventExpose *event,
00344 gpointer data __attribute__((unused)))
00345 {
00346 GdkGC *gc = gdk_gc_new(widget->window);
00347
00348
00349
00350 gdk_draw_drawable(
00351 widget->window,
00352 gc,
00353 mw.p_play,
00354 event->area.x + (getMapXPos() * gameTileSize()),
00355 event->area.y + (getMapYPos() * gameTileSize()),
00356 event->area.x,
00357 event->area.y,
00358 event->area.width,
00359 event->area.height);
00360 g_object_unref(gc);
00361 return (FALSE);
00362 }
00363
00375 static gint
00376 drawing_realized_callback(GtkWidget *widget __attribute__((unused)),
00377 GdkEvent *event __attribute__((unused)),
00378 gpointer data __attribute__((unused)))
00379 {
00380 return (FALSE);
00381 }
00382
00391 static gint
00392 button_press_event(GtkWidget *widget __attribute__((unused)),
00393 GdkEventButton *event)
00394 {
00395 if (event->button == 1) {
00396 BuildSomething(
00397 (int)(event->x / gameTileSize()) + getMapXPos(),
00398 (int)(event->y / gameTileSize()) + getMapYPos());
00399 } else if (event->button == 3) {
00400 Build_Bulldoze(
00401 (int)(event->x / gameTileSize()) + getMapXPos(),
00402 (int)(event->y / gameTileSize()) + getMapYPos(), 0);
00403 }
00404
00405 return (TRUE);
00406 }
00407
00413 static gint
00414 motion_notify_event(GtkWidget *widget __attribute__((unused)),
00415 GdkEventMotion *event)
00416 {
00417 int x, y;
00418 GdkModifierType state;
00419
00420 if (event->is_hint) {
00421 gdk_window_get_pointer(event->window, &x, &y, &state);
00422 } else {
00423 x = event->x;
00424 y = event->y;
00425 state = event->state;
00426 }
00427
00428 if (state & GDK_BUTTON1_MASK &&
00429 x > 0 && x < getVisibleX() * gameTileSize() &&
00430 y > 0 && y < getVisibleY() * gameTileSize()) {
00431 BuildSomething(
00432 (int)(x / gameTileSize()) + getMapXPos(),
00433 (int)(y / gameTileSize()) + getMapYPos());
00434 } else if (state & GDK_BUTTON3_MASK &&
00435 x > 0 && x < getVisibleX() * gameTileSize() &&
00436 y > 0 && y < getVisibleY() * gameTileSize()) {
00437 Build_Bulldoze(
00438 (int)(x / gameTileSize()) + getMapXPos(),
00439 (int)(y / gameTileSize()) + getMapYPos(), 1);
00440 }
00441
00442 return (TRUE);
00443 }
00444
00449 GtkWidget *
00450 setupToolBox(void)
00451 {
00452 GtkWidget *button_image;
00453
00454 GtkWidget *toolbox;
00455
00456
00457 unsigned int i;
00458 char *image_path;
00459 size_t max_path = (size_t)pathconf("/", _PC_PATH_MAX) + 1;
00460
00462 const struct gaa {
00463 gint entry;
00464 const char *text;
00465 const char *file;
00466 } actions[] = {
00467 { Be_Bulldozer, "Bulldozer", "interface_00.png" },
00468 { Be_Road, "Road", "interface_01.png" },
00469 { Be_Power_Line, "Power Line", "interface_02.png" },
00470 { Be_Zone_Residential, "Residential", "interface_03.png" },
00471 { Be_Zone_Commercial, "Commercial", "interface_04.png" },
00472 { Be_Zone_Industrial, "Industrial", "interface_05.png" },
00473 { Be_Tree, "Tree", "interface_06.png" },
00474 { Be_Water, "Water", "interface_07.png" },
00475 { Be_Water_Pipe, "Water Pipe", "interface_08.png" },
00476 { Be_Power_Plant, "Power Plant", "interface_09.png" },
00477 { Be_Nuclear_Plant, "Nuclear Power Plant", "interface_10.png" },
00478 { Be_Water_Pump, "Water Pump", "interface_11.png" },
00479 { Be_Fire_Station, "Fire Station", "interface_12.png" },
00480 { Be_Police_Station, "Police Station", "interface_13.png" },
00481 { Be_Military_Base, "Military Base", "interface_14.png" },
00482 { -1, NULL, NULL },
00483 { Be_Defence_Fire, "Fire Brigade", "interface_18.png" },
00484 { Be_Defence_Police, "Police Car", "interface_19.png" },
00485 { Be_Defence_Military, "Tank", "interface_20.png" }
00486 };
00487
00488 #define SIZE_ACTIONS (sizeof (actions) / sizeof (actions[0]))
00489
00490 image_path = malloc(max_path);
00491
00492
00493
00494
00495 toolbox = gtk_toolbar_new();
00496 gtk_container_set_border_width(GTK_CONTAINER(toolbox), 0);
00497
00498 for (i = 0; i < SIZE_ACTIONS; i++) {
00499 if (actions[i].entry == -1) {
00500 gtk_toolbar_append_space(GTK_TOOLBAR(toolbox));
00501 continue;
00502 }
00503
00504
00505 strcpy(image_path, actions[i].file);
00506 if (searchForFile(image_path, max_path, PATHSEARCH))
00507 button_image = gtk_image_new_from_file(image_path);
00508 else {
00509 perror(image_path);
00510 exit(1);
00511 }
00512 gtk_toolbar_append_item(GTK_TOOLBAR(toolbox),
00513 NULL, actions[i].text, NULL, button_image,
00514 G_CALLBACK(toolbox_callback),
00515 GINT_TO_POINTER(actions[i].entry));
00516
00517
00518
00519
00520
00521
00522
00523
00524 }
00525
00526
00527
00528
00529
00530
00531 free(image_path);
00532 return (toolbox);
00533 }
00534
00539 GtkAccelGroup *
00540 createMenu(GtkWidget *main_box)
00541 {
00542 GtkItemFactory *item_factory;
00543 GtkAccelGroup *accel_group;
00544
00545 accel_group = gtk_accel_group_new();
00546 item_factory = gtk_item_factory_new(GTK_TYPE_MENU_BAR, "<main>",
00547 accel_group);
00548 gtk_item_factory_create_items(item_factory, NMENU_ITEMS,
00549 (GtkItemFactoryEntry *)menu_items, NULL);
00550
00551 gtk_box_pack_start(GTK_BOX(main_box),
00552 gtk_item_factory_get_widget(item_factory, "<main>"),
00553 FALSE, TRUE, 0);
00554
00555 return (accel_group);
00556 }
00557
00564 static gboolean
00565 hoveringDrawing(GtkWidget *widget __attribute__((unused)),
00566 GdkEventMotion *event, gpointer data __attribute__((unused)))
00567 {
00568 hoverUpdate((event->x / gameTileSize()) + getMapXPos(),
00569 (event->y / gameTileSize()) + getMapYPos(), 0);
00570 return (0);
00571 }
00572
00579 void
00580 SetUpMainWindow(void)
00581 {
00582 GtkWidget *fieldbox, *box, *toolbox, *headerbox;
00583 GtkWidget *playingbox, *main_box;
00584 GtkAccelGroup *accel_group;
00585
00586 mw.window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
00587 gtk_window_set_title(GTK_WINDOW(mw.window), "Pocket City");
00588 g_signal_connect(G_OBJECT(mw.window), "delete_event",
00589 G_CALLBACK(delete_event), NULL);
00590
00591 main_box = gtk_vbox_new(FALSE, 0);
00592 box = gtk_vbox_new(FALSE, 0);
00593 fieldbox = gtk_vbox_new(FALSE, 0);
00594 headerbox = gtk_hbox_new(FALSE, 0);
00595 playingbox = gtk_table_new(2, 2, FALSE);
00596
00597 gtk_container_add(GTK_CONTAINER(mw.window), main_box);
00598
00599 mw.l_credits = gtk_label_new("Credits");
00600 mw.l_location = gtk_label_new("Location");
00601 mw.l_pop = gtk_label_new("Population");
00602 mw.l_time = gtk_label_new("Game Time");
00603
00604
00605 mw.drawing = gtk_drawing_area_new();
00606 gtk_widget_set_size_request(mw.drawing, 320, 320);
00607
00608 mw.sc_hor = gtk_adjustment_new(50, 0, 100, 1, 10, 20);
00609 mw.sc_vert = gtk_adjustment_new(50, 0, 100, 1, 10, 15);
00610 mw.hscroll = gtk_hscrollbar_new(GTK_ADJUSTMENT(mw.sc_hor));
00611 mw.vscroll = gtk_vscrollbar_new(GTK_ADJUSTMENT(mw.sc_vert));
00612 g_signal_connect(G_OBJECT(mw.sc_hor), "value_changed",
00613 G_CALLBACK(scrollbar), NULL);
00614 g_signal_connect(G_OBJECT(mw.sc_vert), "value_changed",
00615 G_CALLBACK(scrollbar), NULL);
00616
00617 gtk_table_attach(GTK_TABLE(playingbox), mw.drawing,
00618 0, 1, 0, 1, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, 0, 0);
00619 gtk_table_attach(GTK_TABLE(playingbox), mw.hscroll, 0, 1, 1, 2,
00620 GTK_FILL, 0, 0, 0);
00621 gtk_table_attach(GTK_TABLE(playingbox), mw.vscroll, 1, 2, 0, 1,
00622 0, GTK_FILL, 0, 0);
00623 g_signal_connect(G_OBJECT(mw.drawing), "configure_event",
00624 G_CALLBACK(check_configure), NULL);
00625
00626
00627 toolbox = setupToolBox();
00628 gtk_box_pack_end(GTK_BOX(main_box), box, TRUE, TRUE, 0);
00629 gtk_box_pack_start(GTK_BOX(box), toolbox, FALSE, FALSE, 0);
00630 gtk_box_pack_end(GTK_BOX(box), fieldbox, TRUE, TRUE, 0);
00631
00632 gtk_box_pack_start(GTK_BOX(fieldbox), headerbox, FALSE, TRUE, 0);
00633 gtk_box_pack_start(GTK_BOX(fieldbox), playingbox, TRUE, TRUE, 0);
00634 gtk_box_pack_start(GTK_BOX(fieldbox), mw.l_location, FALSE, TRUE, 0);
00635 gtk_box_pack_end(GTK_BOX(fieldbox), mw.l_pop, FALSE, TRUE, 0);
00636
00637 gtk_box_pack_start(GTK_BOX(headerbox), mw.l_credits, TRUE, TRUE, 0);
00638 gtk_box_pack_start(GTK_BOX(headerbox), mw.l_time, TRUE, TRUE, 0);
00639
00640 g_signal_connect(G_OBJECT(mw.drawing), "expose_event",
00641 G_CALLBACK(drawing_exposed_callback), NULL);
00642
00643 g_signal_connect_after(G_OBJECT(mw.drawing), "realize",
00644 G_CALLBACK(drawing_realized_callback), NULL);
00645
00646 g_signal_connect(G_OBJECT(mw.drawing), "motion_notify_event",
00647 G_CALLBACK(hoveringDrawing), NULL);
00648
00649
00650 gtk_signal_connect(GTK_OBJECT(mw.drawing), "motion_notify_event",
00651 G_CALLBACK(motion_notify_event), NULL);
00652 gtk_signal_connect(GTK_OBJECT(mw.drawing), "button_press_event",
00653 G_CALLBACK(button_press_event), NULL);
00654
00655 gtk_widget_set_events(mw.drawing, GDK_EXPOSURE_MASK |
00656 GDK_LEAVE_NOTIFY_MASK | GDK_BUTTON_PRESS_MASK |
00657 GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK);
00658
00659 accel_group = createMenu(main_box);
00660 gtk_window_add_accel_group(GTK_WINDOW(mw.window), accel_group);
00661
00662
00663 gtk_widget_show_all(main_box);
00664
00665 gtk_widget_realize(mw.window);
00666 }
00667
00668 static void
00669 ShowMainWindow(void)
00670 {
00671
00672 gtk_widget_show(mw.window);
00673 }
00674
00676 static struct image_pms {
00677 char *filename;
00678 GdkPixmap **pm;
00679 GdkPixmap **mask;
00680 } image_pixmaps[] = {
00681 { "tile-16x16-color.png", &mw.p_zones, &mw.p_zones_m },
00682 { "monsters_16x16-color.png", &mw.p_monsters, &mw.p_monsters_m },
00683 { "units_16x16-color.png", &mw.p_units, &mw.p_units_m },
00684 { "tile-4x4-color.png", &mw.p_mapzones, NULL },
00685 { "monsters_16x16-color.png", &mw.p_mapspecials, NULL },
00686 { "units_16x16-color.png", &mw.p_mapunits, NULL },
00687 { NULL, NULL, NULL }
00688 };
00689
00693 static void
00694 cleanupPixmaps(void)
00695 {
00696 int elt;
00697
00698 if (mw.p_play != NULL) g_object_unref(G_OBJECT(mw.p_play));
00699 for (elt = 0; image_pixmaps[elt].filename != NULL; elt++) {
00700 if (image_pixmaps[elt].pm != NULL &&
00701 *image_pixmaps[elt].pm != NULL)
00702 g_object_unref(G_OBJECT(*image_pixmaps[elt].pm));
00703 if (image_pixmaps[elt].mask != NULL &&
00704 *image_pixmaps[elt].mask != NULL)
00705 g_object_unref(G_OBJECT(*image_pixmaps[elt].mask));
00706
00707 }
00708 }
00709
00713 void
00714 UIInitGraphic(void)
00715 {
00716 char *image_path;
00717 int i;
00718 struct image_pms *ipm;
00719 size_t max_path = (size_t)pathconf("/", _PC_PATH_MAX) + 1;
00720
00721 image_path = malloc(max_path);
00722
00723 for (i = 0; image_pixmaps[i].filename != NULL; i++) {
00724 ipm = image_pixmaps + i;
00725 strlcpy(image_path, ipm->filename, max_path);
00726 if (searchForFile(image_path, max_path, PATHSEARCH)) {
00727 *ipm->pm = gdk_pixmap_create_from_xpm(
00728 mw.window->window, ipm->mask, NULL, image_path);
00729 if (*ipm->pm == NULL) {
00730 WriteLog("Could not create pixmap from file %s",
00731 ipm->filename);
00732 free(image_path);
00733 exit(1);
00734 }
00735 } else {
00736 perror(image_path);
00737 free(image_path);
00738 exit(1);
00739 }
00740 }
00741
00742 strlcpy(image_path, "pcityicon.png", max_path);
00743 if (searchForFile(image_path, max_path, PATHSEARCH)) {
00744 gtk_window_set_icon_from_file(GTK_WINDOW(mw.window),
00745 image_path, NULL);
00746 }
00747 free(image_path);
00748 }
00749
00754 void
00755 UIDisplayError1(char *error)
00756 {
00757 GtkWidget * dialog;
00758 dialog = gtk_message_dialog_new(GTK_WINDOW(mw.window),
00759 GTK_DIALOG_DESTROY_WITH_PARENT,
00760 GTK_MESSAGE_ERROR,
00761 GTK_BUTTONS_OK,
00762 "%s",
00763 error);
00764 gtk_dialog_run(GTK_DIALOG(dialog));
00765 gtk_widget_destroy(GTK_WIDGET(dialog));
00766 }
00767
00768 void
00769 UIDisasterNotify(disaster_t disaster)
00770 {
00771 char temp[100];
00772
00773 switch (disaster) {
00774 case diFireOutbreak:
00775 strcpy(temp, "An Australian fire has broken out somewhere!");
00776 break;
00777 case diPlantExplosion:
00778 strcpy(temp, "A power plant just exploded!");
00779 break;
00780 case diMonster:
00781 strcpy(temp, "Godzilla just came to town!");
00782 break;
00783 case diDragon:
00784 strcpy(temp, "A fire dragon wants to use your city as "
00785 "it's lair!");
00786 break;
00787 case diMeteor:
00788 strcpy(temp, "A gigantic meteor has hit your city!");
00789 break;
00790 default:
00791 return;
00792 }
00793 UIDisplayError1(temp);
00794 }
00795
00800 void
00801 UIProblemNotify(problem_t problem)
00802 {
00803 char temp[100];
00804
00805 switch (problem) {
00806 case peFineOnMoney:
00807 return;
00808 case peLowOnMoney:
00809 strcpy(temp, "Low on money");
00810 break;
00811 case peOutOfMoney:
00812 strcpy(temp, "Out of money");
00813 break;
00814 case peFineOnPower:
00815 return;
00816 case peLowOnPower:
00817 strcpy(temp, "Low On Power");
00818 break;
00819 case peOutOfPower:
00820 strcpy(temp, "Out of Power");
00821 break;
00822 case peFineOnWater:
00823 return;
00824 case peLowOnWater:
00825 strcpy(temp, "Low on Water");
00826 break;
00827 case peOutOfWater:
00828 strcpy(temp, "Out of Water");
00829 break;
00830 default:
00831 return;
00832 }
00833
00834 UIDisplayError1(temp);
00835 }
00836
00837 void
00838 UISystemErrorNotify(syserror_t error)
00839 {
00840 char temp[100];
00841
00842 if (error == seOutOfMemory) {
00843 strcpy(temp, "Out of memory. Save and exit now!!!!");
00844 } else {
00845 return;
00846 }
00847 UIDisplayError1(temp);
00848 }
00849
00851 void
00852 UIInitDrawing(void)
00853 {
00854 }
00855
00857 void
00858 UIFinishDrawing(void)
00859 {
00860 }
00861
00863 void
00864 UIPostLoadGame(void)
00865 {
00866 }
00867
00868 void
00869 UIUnlockScreen(void)
00870 {
00871 gtk_widget_queue_draw(mw.drawing);
00872 }
00873
00875 void
00876 UILockScreen(void)
00877 {
00878
00879 }
00880
00882 void
00883 UIDrawBorder(void)
00884 {
00885
00886 }
00887
00891 void
00892 UIDrawCredits(void)
00893 {
00894 char temp[24];
00895
00896 sprintf(temp, "$: %ld", (long)getCredits());
00897 gtk_label_set_text((GtkLabel *)mw.l_credits, temp);
00898 }
00899
00903 void
00904 UIDrawDate(void)
00905 {
00906 char temp[24];
00907
00908 getDate((char *)temp);
00909 gtk_label_set_text((GtkLabel *)mw.l_time, temp);
00910 }
00911
00915 void
00916 UIDrawLoc(void)
00917 {
00918 char temp[50];
00919
00920 sprintf(temp, "(%02u, %02u)", (int)getMapXPos(), (int)getMapYPos());
00921
00922 gtk_label_set_text((GtkLabel*)mw.l_location, temp);
00923 }
00924
00930 void
00931 UIDrawPop(void)
00932 {
00933 char temp[50];
00934 sprintf(temp, "Population: %-9li", (long)getPopulation());
00935
00936 gtk_label_set_text((GtkLabel*)mw.l_pop, temp);
00937 }
00938
00943 void
00944 UIDrawSpeed(void)
00945 {
00946 }
00947
00952 void
00953 UIDrawBuildIcon(void)
00954 {
00955
00956 }
00957
00959 void
00960 UIUpdateBuildIcon(void)
00961 {
00962
00963 }
00964
00966 void
00967 UIGotoForm(Int16 n __attribute__((unused)))
00968 {
00969
00970 }
00971
00973 void
00974 UICheckMoney(void)
00975 {
00976
00977 }
00978
00984 void
00985 UIScrollDisplay(dirType direction __attribute__((unused)))
00986 {
00987 RedrawAllFields();
00988 gtk_widget_queue_draw(mw.drawing);
00989 }
00990
00994 void
00995 _UIDrawRect(Int16 nTop __attribute__((unused)),
00996 Int16 nLeft __attribute__((unused)), Int16 nHeight __attribute__((unused)),
00997 Int16 nWidth __attribute__((unused)))
00998 {
00999 WriteLog("_UIDrawRect\n");
01000 }
01001
01002 void
01003 UIPaintField(UInt16 xpos, UInt16 ypos, welem_t nGraphic)
01004 {
01005 GdkGC *gc = gdk_gc_new(mw.p_play);
01006
01007 gdk_draw_drawable(
01008 GDK_DRAWABLE(mw.p_play),
01009 gc,
01010 mw.p_zones,
01011 (nGraphic % HORIZONTAL_TILESIZE) * gameTileSize(),
01012 (nGraphic / HORIZONTAL_TILESIZE) * gameTileSize(),
01013 xpos * gameTileSize(),
01014 ypos * gameTileSize(),
01015 gameTileSize(),
01016 gameTileSize());
01017 g_object_unref(gc);
01018 gtk_widget_queue_draw(mw.drawing);
01019 }
01020
01021 void
01022 UIPaintSpecialObject(UInt16 xpos, UInt16 ypos, Int8 i)
01023 {
01024 GdkGC *gc;
01025
01026 gc = gdk_gc_new(mw.p_play);
01027 gdk_gc_set_clip_mask(gc, mw.p_monsters_m);
01028 gdk_gc_set_clip_origin(gc,
01029 xpos * gameTileSize() - (GG.objects[i].dir * gameTileSize()),
01030 ypos * gameTileSize() - (i * gameTileSize()));
01031
01032 gdk_draw_drawable(
01033 mw.p_play,
01034 gc,
01035 mw.p_monsters,
01036 GG.objects[i].dir * gameTileSize(),
01037 i * gameTileSize(),
01038 xpos * gameTileSize(),
01039 ypos * gameTileSize(),
01040 gameTileSize(),
01041 gameTileSize());
01042 g_object_unref(gc);
01043 gtk_widget_queue_draw(mw.drawing);
01044 }
01045
01046 void
01047 UIPaintSpecialUnit(UInt16 xpos, UInt16 ypos, Int8 i)
01048 {
01049 GdkGC *gc;
01050
01051 gc = gdk_gc_new(mw.p_play);
01052 gdk_gc_set_clip_mask(gc, mw.p_units_m);
01053 gdk_gc_set_clip_origin(gc,
01054 xpos * gameTileSize() - (GG.units[i].type * gameTileSize()),
01055 ypos * gameTileSize());
01056
01057 gdk_draw_drawable(
01058 mw.p_play,
01059 gc,
01060 mw.p_units,
01061 GG.units[i].type * gameTileSize(),
01062 0,
01063 xpos * gameTileSize(),
01064 ypos * gameTileSize(),
01065 gameTileSize(),
01066 gameTileSize());
01067 g_object_unref(gc);
01068 gtk_widget_queue_draw(mw.drawing);
01069 }
01070
01071 void
01072 UIDrawMapZone(Int16 xpos, Int16 ypos, welem_t nGraphic, GdkDrawable *drawable)
01073 {
01074 GdkGC *gc = gdk_gc_new(drawable);
01075 gdk_draw_drawable(
01076 drawable,
01077 gc,
01078 mw.p_mapzones,
01079 (nGraphic % HORIZONTAL_TILESIZE) * mapTileSize(),
01080 (nGraphic / HORIZONTAL_TILESIZE) * mapTileSize(),
01081 xpos * mapTileSize(),
01082 ypos * mapTileSize(),
01083 mapTileSize(),
01084 mapTileSize());
01085 g_object_unref(gc);
01086 }
01087
01088 void
01089 UIDrawMapSpecialObject(Int16 xpos, Int16 ypos, Int16 i, GdkDrawable *drawable)
01090 {
01091 GdkGC *gc = gdk_gc_new(drawable);
01092
01093 gdk_draw_drawable(
01094 drawable,
01095 gc,
01096 mw.p_mapspecials,
01097 i * mapTileSize(),
01098 0,
01099 xpos * mapTileSize(),
01100 ypos * mapTileSize(),
01101 mapTileSize(),
01102 mapTileSize());
01103 g_object_unref(gc);
01104 }
01105
01106 void
01107 UIDrawMapSpecialUnit(Int16 xpos, Int16 ypos, Int16 i, GdkDrawable *drawable)
01108 {
01109 GdkGC *gc = gdk_gc_new(drawable);
01110
01111 gdk_draw_drawable(
01112 drawable,
01113 gc,
01114 mw.p_units,
01115 i * mapTileSize(),
01116 0,
01117 xpos * mapTileSize(),
01118 ypos * mapTileSize(),
01119 mapTileSize(),
01120 mapTileSize());
01121 g_object_unref(gc);
01122 }
01123
01124 void
01125 UIPaintCursor(UInt16 xpos __attribute__((unused)),
01126 UInt16 ypos __attribute__((unused)))
01127 {
01128
01129 }
01130
01137 static void
01138 DrawOverlay(UInt16 xpos, UInt16 ypos, welem_t offset)
01139 {
01140 GdkGC *gc;
01141
01142 gc = gdk_gc_new(mw.p_play);
01143 gdk_gc_set_clip_mask(gc, mw.p_zones_m);
01144 gdk_gc_set_clip_origin(gc,
01145 (xpos - (offset % HORIZONTAL_TILESIZE)) * gameTileSize(),
01146 (ypos - (offset / HORIZONTAL_TILESIZE)) * gameTileSize());
01147
01148 gdk_draw_drawable(
01149 mw.p_play,
01150 gc,
01151 mw.p_zones,
01152 (offset % HORIZONTAL_TILESIZE) * gameTileSize(),
01153 (offset / HORIZONTAL_TILESIZE) * gameTileSize(),
01154 xpos * gameTileSize(),
01155 ypos * gameTileSize(),
01156 gameTileSize(),
01157 gameTileSize());
01158 g_object_unref(gc);
01159 }
01160
01161 void
01162 UIPaintPowerLoss(UInt16 xpos, UInt16 ypos)
01163 {
01164 DrawOverlay(xpos, ypos, Z_POWER_OUT);
01165 }
01166
01167 void
01168 UIPaintWaterLoss(UInt16 xpos, UInt16 ypos)
01169 {
01170 DrawOverlay(xpos, ypos, Z_WATER_OUT);
01171 }
01172
01173 BuildCode
01174 UIGetSelectedBuildItem(void)
01175 {
01176 return (selectedBuildItem);
01177 }
01178
01180 static int painted_flag;
01181
01183 void
01184 clearPaintedFlag(void)
01185 {
01186 painted_flag = 0;
01187 }
01188
01190 void
01191 setPaintedFlag(void)
01192 {
01193 painted_flag = 1;
01194 }
01195
01200 int
01201 getPaintedFlag(void)
01202 {
01203 return (painted_flag);
01204 }
01205
01210 void
01211 UIDrawPlayArea(void)
01212 {
01213 Int16 x;
01214 Int16 y;
01215 Int16 maxx = getMapXPos() + getVisibleX() >= getMapWidth() ?
01216 getMapWidth() : getMapXPos() + getVisibleX();
01217 Int16 maxy = getMapYPos() + getVisibleY() >= getMapHeight() ?
01218 getMapHeight() : getMapYPos() + getVisibleY();
01219
01220 for (x = getMapXPos(); x < maxx; x++) {
01221 for (y = getMapYPos(); y < maxy; y++) {
01222 if (!(getWorldFlags(WORLDPOS(x, y)) & PAINTEDBIT))
01223 DrawFieldWithoutInit(x, y);
01224 }
01225 }
01226
01227 gtk_widget_queue_draw(mw.drawing);
01228 }
01229
01234 void
01235 UIMapResize(void)
01236 {
01237 if (mw.p_play != NULL) g_object_unref(G_OBJECT(mw.p_play));
01238 mw.p_play = gdk_pixmap_new(drawable_main_get(),
01239 getMapWidth() * gameTileSize(),
01240 getMapHeight() * gameTileSize(), -1);
01241 clearPaintedFlag();
01242 resizeMap();
01243 }
01244
01245 Int8
01246 UIClipped(UInt16 xpos __attribute__((unused)),
01247 UInt16 ypos __attribute__((unused)))
01248 {
01249 return (FALSE);
01250 }
01251
01252 void
01253 LockZone(lockZone zone __attribute__((unused)))
01254 {
01255
01256 }
01257
01258 void
01259 UnlockZone(lockZone zone __attribute__((unused)))
01260 {
01261
01262 }
01263
01264 void
01265 ReleaseZone(lockZone zone)
01266 {
01267 if (zone == lz_world) {
01268 free(worldPtr);
01269 worldPtr = NULL;
01270 }
01271 }
01272
01273 UInt32
01274 GetRandomNumber(UInt32 max)
01275 {
01276
01277 return ((UInt32)((float)max*rand()/(RAND_MAX+1.0)));
01278 }
01279
01283 void
01284 MapHasJumped(void)
01285 {
01286 GTK_ADJUSTMENT(mw.sc_hor)->value = getMapXPos();
01287 GTK_ADJUSTMENT(mw.sc_vert)->value = getMapYPos();
01288 gtk_adjustment_value_changed(GTK_ADJUSTMENT(mw.sc_hor));
01289 gtk_adjustment_value_changed(GTK_ADJUSTMENT(mw.sc_vert));
01290 gtk_widget_queue_draw(mw.drawing);
01291 }
01292
01298 static void
01299 QuitGame(void)
01300 {
01301 gtk_main_quit();
01302 }
01303
01307 static void
01308 forceRedistribute(void)
01309 {
01310 AddGridUpdate(GRID_ALL);
01311 }
01312
01313 #ifdef DEBUG
01314
01315 #include <stdarg.h>
01316
01317 void
01318 WriteLog(char *s, ...)
01319 {
01320 va_list args;
01321 char mbuf[2048];
01322
01323 va_start(args, s);
01324 vsprintf(mbuf, s, args);
01325 g_print(mbuf);
01326 va_end(args);
01327 }
01328 #endif