]> granicus.if.org Git - xconq/blobdiff - sdl/sdlinit.cc
commits for 7.5.0 pre-release tarball
[xconq] / sdl / sdlinit.cc
diff --git a/sdl/sdlinit.cc b/sdl/sdlinit.cc
new file mode 100644 (file)
index 0000000..6b0bf14
--- /dev/null
@@ -0,0 +1,344 @@
+/* Initialization for the SDL interface to Xconq.
+   Copyright (C) 2000, 2001 Stanley T. Shebs.
+   Copyright (C) 2004 Eric A. McDonald.
+
+Xconq is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.  See the file COPYING.  */
+
+#include "sdlpreconq.h"
+#include "conq.h"
+#include "sdlconq.h"
+
+ImageFamily *hexagon_w1;
+ImageFamily *hexagon_w2;
+
+static void init_material_images(void);
+static void init_terrain_images(void);
+static void init_emblem_images(void);
+static void init_emblem(Side *side2);
+static void init_other_images(void);
+
+static void sdl_describe_image(Side *side, Image *img);
+static void report_missing_images(void);
+
+void
+init_ui(Side *side)
+{
+    /* Might be called a second time, deal with it. */
+    if (dside != NULL)
+      return;
+    if (side_wants_display(side)) {
+       if (dside == NULL) {
+           dside = side;
+           dside->ui = (UI *) xmalloc(sizeof(UI));
+           Dprintf("One UI is %d bytes.\n", sizeof(UI));
+           get_preferences();
+           return;
+       } else {
+           init_warning("Only one display allowed, cannot open for side %d",
+                        side_number(side));
+       }
+    }
+    side->ui = NULL;
+}
+
+/* Open display, create all the windows we'll need, do misc setup
+   things, and initialize some globals to out-of-range values for
+   recognition later. */
+
+void
+init_display(void)
+{
+    int i;
+    SDLCursor *newgeneric = NULL;
+
+    imf_describe_hook = sdl_describe_image;
+
+    /* Update the generic cursor if the global variable was changed by
+       the loaded game. */
+    if (strcmp(default_cursor_name, g_generic_cursor()) != 0)
+      newgeneric = get_cursor(g_generic_cursor(), 0, 0);
+    if (newgeneric != NULL)
+      generic_cursor = newgeneric;
+
+    for (i = 0; i < nummodes; ++i)
+      ui->cursors[i] = NULL;
+    ui->cursors[scroll_down_mode] = get_cursor("cursor-scroll-down", 16, 32);
+    ui->cursors[scroll_left_mode] = get_cursor("cursor-scroll-left", 0, 16);
+    ui->cursors[scroll_right_mode] = get_cursor("cursor-scroll-right", 32, 16);
+    ui->cursors[scroll_up_mode] = get_cursor("cursor-scroll-up", 16, 0);
+
+    ui->cursors[survey_mode] = get_cursor(g_survey_cursor(), 0, 0);
+    ui->cursors[attack_mode] = get_cursor(g_attack_cursor(), 0, 0);
+
+    init_ui_chars();
+    init_unit_images(dside);
+    init_material_images();
+    init_terrain_images();
+    init_emblem_images();
+    init_other_images();
+
+    report_missing_images();
+}
+
+/* A predicate that tests whether our display can safely be written to. */
+
+int
+active_display(Side *side)
+{
+    return (side && side->ui && side->ui->active);
+}
+
+SDLCursor *
+get_cursor(char *name, int hotx, int hoty)
+{
+    ImageFamily *imf;
+    Image *img;
+    SDL_Surface *surf = NULL;
+    SDLCursor *rslt = NULL;
+
+    imf = get_generic_images(name);
+    if (imf != NULL) {
+       record_imf_get(imf);
+       if (DebugG)
+         describe_imf(dside, "cursor", name, imf);
+       img = best_image(imf, 32, 32);
+       if (img != NULL)
+         surf = sdl_image(img);
+    }
+    if (surf != NULL) {
+       rslt = (SDLCursor *) xmalloc(sizeof(SDLCursor));
+       rslt->surf = surf;
+       rslt->hotx = hotx;  rslt->hoty = hoty;
+    } else {
+       init_warning("Could not load cursor \"%s\"", name);
+    }
+    return rslt;
+}
+
+static void
+init_material_images(void)
+{
+    int m;
+    ImageFamily *imf;
+    Image *img, *mimg;
+
+    ui->mimages =
+      (ImageFamily **) xmalloc(nummtypes * sizeof(ImageFamily *));
+    for_all_material_types(m) {
+       imf = get_material_type_images(dside, m);
+       if (DebugG)
+         describe_imf(dside, "material type", m_type_name(m), imf);
+       ui->mimages[m] = imf;
+       /* Look for a solid color. */
+       mimg = NULL;
+       for_all_images(ui->mimages[m], img) {
+           if (img->w == 1 && img->h == 1) {
+               mimg = img;
+               break;
+           }
+       }
+       if (mimg != NULL && mimg->w == 1 && mimg->h == 1) {
+           if (mimg->hook) {
+#if 0
+               /* Save the color if found. */
+               if (tkimg->solid)
+                 ui->material_color[m] = tkimg->solid;
+#endif
+           }
+       }
+    }
+}
+
+/* Collect images for all the terrain types. */
+
+#if 0
+static void init_shades(int t);
+#endif
+
+static void
+init_terrain_images(void)
+{
+    int t, p;
+    ImageFamily *imf;
+    Image *img, *timg, *subimg;
+
+    ui->timages = (ImageFamily **) xmalloc(numttypes * sizeof(ImageFamily *));
+    ui->tcolors = (Image **) xmalloc(numttypes * sizeof(Image *));
+    for (p = 0; p < NUMPOWERS; ++p) {
+       ui->best_timages[p] =
+         (Image **) xmalloc(numttypes * sizeof(Image *));
+    }
+    for_all_terrain_types(t) {
+       imf = get_terrain_type_images(dside, t);
+       if (DebugG)
+         describe_imf(dside, "terrain type", t_type_name(t), imf);
+       ui->timages[t] = imf;
+       /* Precalculate which images to use at which magnifications. */
+       for (p = 0; p < NUMPOWERS; ++p) {
+           timg = best_image(ui->timages[t], hws[p], hhs[p]);
+           (ui->best_timages[p])[t] = timg;
+           if (timg != NULL) {
+               subimg = timg;
+               /* If we have multiple subimages, pick the first as
+                   representative. */
+               if (timg->numsubimages > 0 && timg->subimages)
+                 subimg = timg->subimages[0];
+           }
+       }
+       /* Look for a solid color. */
+       timg = NULL;
+       for_all_images(ui->timages[t], img) {
+           if (img->w == 1 && img->h == 1) {
+               ui->tcolors[t] = img;
+               break;
+           }
+       }
+#if 0
+       if (elevations_defined())
+         init_shades(t);
+#endif
+    }
+}
+
+/* Set up a side's view of everybody else's colors and emblems. */
+
+static void
+init_emblem_images(void)
+{
+    Side *side2;
+    
+    ui->eimages =
+      (ImageFamily **) xmalloc((g_sides_max() + 1) * sizeof(ImageFamily *));
+    ui->eimages_loaded =
+      (short *) xmalloc((g_sides_max() + 1) * sizeof(short));
+    /* Independent units may have a distinguishing emblem, so the
+       indepside is included here. */
+    for_all_sides(side2) {
+       init_emblem(side2);
+    }
+}
+
+/* Compute the distinctive emblem by which one side will recognize units
+   of another side.  This does both our view of ourselves and others
+   orthogonally.  Note that sides without displays can still have emblems
+   and colors that the sides with displays will see, but that sides
+   without displays don't need to do any emblem init. */
+
+static void
+init_emblem(Side *side2)
+{
+#if 0
+    char cbuf[BUFSIZ], *s, *c;
+#endif
+    int s2 = side_number(side2) /*, i*/;
+    ImageFamily *imf;
+
+    /* Collect the color names of the other side and try to request
+       them for our own display. */
+#if 0
+    if (!empty_string(side2->colorscheme)) {
+       /* take spec apart and iterate for multiple colors */
+        /* (should be generic code) */
+       for (s = side2->colorscheme, c = cbuf, i = 0; i < 3; ++s) {
+           if (*s == ',' || *s == '\0') {
+               *c = '\0';
+               c = cbuf;
+               color = request_color(cbuf);
+               if (color != NULL)
+                 ui->colors[s2][i++] = color;
+           } else {
+               *c++ = *s;
+           }
+           if (*s == '\0')
+             break;
+       }
+       ui->numcolors[s2] = i;
+    } else {
+       ui->numcolors[s2] = 0;
+    }
+#endif
+    imf = get_emblem_images(dside, side2);
+    if (DebugG)
+      describe_imf(dside, "emblem", side_desig(side2), imf);
+    ui->eimages[s2] = imf;
+    ui->eimages_loaded[s2] = TRUE;
+}
+
+/* Collect random other images via the image family system, such as
+   blasts, terrain transitions, etc. */
+
+/* Wired-in names that we assume are available. */
+
+char *blastnames[] = { "miss", "hit", "kill", "nuke1", "nuke2", "nuke3" };
+
+void
+init_other_images(void)
+{
+    int i;
+    ImageFamily *imf;
+
+    /* Normal combat blasts include images for misses, hits, and
+       kills, while nuclear detonations get a sequence of three
+       images. */
+    for (i = 0; i < 6; ++i) {
+       imf = get_generic_images(blastnames[i]);
+       record_imf_get(imf);
+       if (DebugG)
+         describe_imf(dside, "blast", blastnames[i], imf);
+       ui->blastimages[i] = imf;
+    }
+    /* Get terrain transition bitmaps. */
+    imf = get_generic_images("transition");
+    record_imf_get(imf);
+    if (DebugG)
+      describe_imf(dside, "transition", "", imf);
+    generic_transition = imf;
+    imf = get_generic_images("hexagon-w1");
+    record_imf_get(imf);
+    if (DebugG)
+      describe_imf(dside, "hexagon-w1", "", imf);
+    hexagon_w1 = imf;
+    imf = get_generic_images("hexagon-w2");
+    record_imf_get(imf);
+    if (DebugG)
+      describe_imf(dside, "hexagon-w2", "", imf);
+    hexagon_w2 = imf;
+}
+
+/* Describe (for debugging) SDL-specific parts of an image. */
+
+static void
+sdl_describe_image(Side *side, Image *img)
+{
+    if (img->hook != NULL)
+      DGprintf(" (SDL surface 0x%x)", img->hook);
+}
+
+/* Collect all the names of types etc for which no images could be found,
+   report them all at once. */
+
+static void
+report_missing_images(void)
+{
+    int u, t, e;
+    Side *side2;
+
+    for_all_terrain_types(t) {
+       if (ui->timages[t] == NULL || ui->timages[t]->ersatz)
+         record_missing_image(TTYP, t_type_name(t));
+    }
+    for_all_unit_types(u) {
+       if (uimages[u] == NULL || uimages[u]->ersatz)
+         record_missing_image(UTYP, u_type_name(u));
+    }
+    for_all_sides(side2) {
+       e = side_number(side2);
+       if (ui->eimages[e] == NULL || ui->eimages[e]->ersatz)
+         record_missing_image(3, side_desig(side2));
+    }
+    if (missing_images(tmpbuf))
+      init_warning("Could not find %s", tmpbuf);
+}