Main Page   Data Structures   File List   Data Fields   Globals   Related Pages  

linux-gtk/main.c

Go to the documentation of this file.
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                 /* Trouble at't mine, is it windows? */
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         /* start the timer */
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 /* \brief the ticker */
00168 unsigned int timekeeper = 0;
00169 /* \brief the disaster time clock */
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         /* this will be called every second */
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); /* yes, call us again in a sec */
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         //WriteLog("drawing: (%d,%d)\n", event->area.width, event->area.height);
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         //GtkTooltips *tips;
00454         GtkWidget *toolbox;
00455         //GtkWidget *button;
00456         //GtkWidget *handle;
00457         unsigned int i;
00458         char *image_path;
00459         size_t max_path = (size_t)pathconf("/", _PC_PATH_MAX) + 1;
00460         /* If you change the order here you need to change the xpm... */
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         //tips = gtk_tooltips_new();
00493 
00494         //toolbox = gtk_table_new(9, 3, TRUE);
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                 //button = gtk_button_new();
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                 /*gtk_container_add(GTK_CONTAINER(button), button_image);
00517                 gtk_tooltips_set_tip(GTK_TOOLTIPS(tips), button,
00518                     actions[i].text, NULL);
00519                 g_signal_connect(G_OBJECT(button), "clicked",
00520                     G_CALLBACK(toolbox_callback),
00521                 GINT_TO_POINTER(actions[i].entry));*/
00522                 //gtk_table_attach_defaults(GTK_TABLE(toolbox), button,
00523                 //    (i%3), (i%3)+1, (i/3), (i/3)+1);
00524         }
00525 
00526         /*handle = gtk_handle_box_new();
00527         gtk_handle_box_set_handle_position(
00528             (GtkHandleBox *)handle, GTK_POS_TOP);
00529         gtk_container_add(GTK_CONTAINER(handle), toolbox);*/
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         /* the actual playfield is a Gtkmw.drawing */
00605         mw.drawing = gtk_drawing_area_new();
00606         gtk_widget_set_size_request(mw.drawing, 320, 320);
00607         /* and some scrollbars for the mw.drawing */
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         /* arange in boxes  */
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         /* set up some mouse events */
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         /* show all the widgets */
00663         gtk_widget_show_all(main_box);
00664 
00665         gtk_widget_realize(mw.window);
00666 }
00667 
00668 static void
00669 ShowMainWindow(void)
00670 {
00671         /* finally, show the main window */
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         /* load the icon */
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         /* not used for this platform */
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         /* not used on this platform */
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         /* not used on this platform */
01256 }
01257 
01258 void
01259 UnlockZone(lockZone zone __attribute__((unused)))
01260 {
01261         /* not used on this platform */
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         /* se `man 3 rand` why I'm not using: return (rand() % max) */
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

Generated on Mon Aug 30 19:44:15 2004 for pocketcity by doxygen1.2.18