/* xprep.cc 1.19 95/12/24 01:05:05 */ // xspacewarp by Greg Walker (gow@math.orst.edu) // This is free software. Non-profit redistribution and/or modification // is allowed and welcome. // prepare the X windows stuff. #include "xprep.hh" #include #include // convert string to long int #include #include #include #include #include #include "common.hh" #include "params.hh" #include "globals.hh" #include "math.h" static void nomouse(void); static void install_GCs(void); static int read_dashes(const char *, char *); static void check_values(void); void xprep(int argc, char **argv) { // Intrinsics do not provide a string-to-long resource converter XtAddConverter(XtRString, XtRLong, XmuCvtStringToLong, NULL, 0); XtVaGetApplicationResources(toplevel, &app_data, resources, XtNumber(resources), NULL); check_values(); // look for invalid values in app_data XtAppAddActions(app_context, actions, XtNumber(actions)); // all drawing will be done on this thing and on a pixmap widget = XtVaCreateManagedWidget("widget", coreWidgetClass, toplevel, XtNwidth, GAMEW, XtNheight, GAMEH, NULL); // see if widget translation table is missing. install default // trans-table if necessary XtTranslations trans_table; XtVaGetValues(widget, XtNtranslations, &trans_table, NULL); if (!trans_table) // app-default trans-table is missing { trans_table = XtParseTranslationTable(def_trans_table); XtOverrideTranslations(widget, trans_table); } // create window and map it XtRealizeWidget(toplevel); // if desired, install an invisible mouse cursor // that does not block view of xspacewarp. if (app_data.nomouse) nomouse(); // pixmap to use as backing store pixmap = XCreatePixmap(DISPLAY, XtWindow(toplevel), GAMEW, GAMEH, DEPTH); // make graphics contexts install_GCs(); } // Make the mouse pointer invisible when it enters the game window. void nomouse(void) { Pixmap pix; Cursor cursor; XColor bg; pix = XCreatePixmapFromBitmapData(DISPLAY, XtWindow(widget), bitcursor_bits, bitcursor_width, bitcursor_height, WHITE, BLACK, 1); bg.pixel = app_data.background; XQueryColor(DISPLAY, COLORMAP, &bg); cursor = XCreatePixmapCursor(DISPLAY, pix, None, &bg, &bg, bitcursor_x_hot, bitcursor_y_hot); XDefineCursor(DISPLAY, WINDOW, cursor); XFreePixmap(DISPLAY, pix); } // Install the graphics contexts used in this game static void install_GCs(void) { Font font; XGCValues gcvalues; // create the default GC used for drawing text and borders if (!(font = XLoadFont(DISPLAY, "9x15"))) { cerr << "xspacewarp: cannot load font 9x15." << endl; exit(1); } gcvalues.foreground = app_data.foreground; gcvalues.background = app_data.background; gcvalues.line_width = 1; gcvalues.font = font; def_GC = XCreateGC(DISPLAY, XtWindow(toplevel), (GCForeground | GCBackground | GCLineWidth | GCFont), &gcvalues); // create the default reverse video GC for erasing regions gcvalues.foreground = app_data.background; gcvalues.background = app_data.foreground; gcvalues.line_width = 1; gcvalues.font = font; defrv_GC = XCreateGC(DISPLAY, XtWindow(toplevel), (GCForeground | GCBackground | GCLineWidth | GCFont), &gcvalues); // GC to use for faser blasts gcvalues.line_width = FASERWTH; gcvalues.line_style = LineOnOffDash; gcvalues.foreground = app_data.faser_color; faserGC = XCreateGC(DISPLAY, XtWindow(toplevel), (GCLineWidth | GCLineStyle | GCForeground), &gcvalues); // get the dash pattern to use for the fasers char dash_list[FASERMAXDASH]; int ndashes; if ((ndashes = read_dashes(app_data.faser_dash_list, dash_list)) < 1) { invalid("faserDashList"); app_data.faser_dash_list = def_app_data.faser_dash_list; (void) read_dashes(app_data.faser_dash_list, dash_list); } XSetDashes(DISPLAY, faserGC, app_data.faser_dash_offset, dash_list, ndashes); // reverse video GC to use for faser blasts gcvalues.line_width = FASERRVWTH; // extra width to clean up non-right angles gcvalues.line_style = LineSolid; gcvalues.foreground = app_data.background; faserGC_rv = XCreateGC(DISPLAY, XtWindow(toplevel), (GCLineWidth | GCLineStyle | GCForeground), &gcvalues); // GC to use for torpedo shots gcvalues.line_width = TORPWTH; gcvalues.line_style = LineSolid; gcvalues.foreground = app_data.torpedo_color; torpGC = XCreateGC(DISPLAY, XtWindow(toplevel), (GCLineWidth | GCLineStyle | GCForeground), &gcvalues); // reverse video GC to use for torpedo shots gcvalues.line_width = TORPRVWTH; // extra width to clean up non-right angles gcvalues.line_style = LineSolid; gcvalues.foreground = app_data.background; torpGC_rv = XCreateGC(DISPLAY, XtWindow(toplevel), (GCLineWidth | GCLineStyle | GCForeground), &gcvalues); // GC to use for explosions gcvalues.foreground = app_data.explosion_color; explodeGC = XCreateGC(DISPLAY, XtWindow(toplevel), GCForeground, &gcvalues); // GC to use for endever gcvalues.foreground = app_data.endever_color; gcvalues.font = font; endeverGC = XCreateGC(DISPLAY, XtWindow(toplevel), (GCForeground | GCFont), &gcvalues); // GC to use for bases gcvalues.foreground = app_data.base_color; gcvalues.font = font; baseGC = XCreateGC(DISPLAY, XtWindow(toplevel), (GCForeground | GCFont), &gcvalues); // GC to use for jovians gcvalues.foreground = app_data.jovian_color; gcvalues.font = font; jovianGC = XCreateGC(DISPLAY, XtWindow(toplevel), (GCForeground | GCFont), &gcvalues); // GC to use for stars gcvalues.foreground = app_data.star_color; gcvalues.font = font; starGC = XCreateGC(DISPLAY, XtWindow(toplevel), (GCForeground | GCFont), &gcvalues); // GC to use for blackholes gcvalues.foreground = app_data.blackhole_color; gcvalues.font = font; blackholeGC = XCreateGC(DISPLAY, XtWindow(toplevel), (GCForeground | GCFont), &gcvalues); } // This reads a sequence of chars (one byte integers) // represented symbolically in in_str (eg, in_str = "10 5 4 13") // and converts in_str to an array of chars ( [10, 5, 4, 13] in // example above). read_dashes() reads a string (ie, an unbroken // sequence on non white space) out of in_str (skipping over // white space), scans the string for a char (one byte integer), // stores the char in out_str, skips over white space, reads the // next string out of in_str, etc. static int read_dashes(const char *in_str, char *out_str) { const int maxstrlen = 2; char dashvalue[maxstrlen+1]; // plus a null int ndashes = 0; int n; while (*in_str && ndashes < FASERMAXDASH) { while (*in_str && isspace(*in_str)) // skip white space in_str++; n = 0; while (*in_str && !isspace(*in_str)) // read non white space { if (n+1 > maxstrlen) return (0); dashvalue[n++] = *in_str++; } dashvalue[n] = 0; if (n > 0) // number of digits in dash length { if (sscanf(dashvalue, "%d", &n) < 1) // not a number return (0); if (n < 1) // dash lengths must be at least 1 return (0); out_str[ndashes++] = (char) n; } } return (ndashes); } // Check validity of data read in from X resources. static void check_values(void) { if (app_data.rows < 1) { invalid("rows"); app_data.rows = def_app_data.rows; } if (app_data.columns < 1) { invalid("columns"); app_data.columns = def_app_data.columns; } if (app_data.min_average_base_pop < 1 || app_data.min_variation_base_pop < 0 || app_data.min_average_base_pop - app_data.min_variation_base_pop < 1 || app_data.min_average_base_pop + app_data.min_variation_base_pop > UROWS*UCOLS) { invalid("minAverageBasePop or minVariationBasePop"); app_data.min_average_base_pop = def_app_data.min_average_base_pop; app_data.min_variation_base_pop = def_app_data.min_variation_base_pop; } if (app_data.max_average_base_pop < 1 || app_data.max_variation_base_pop < 0 || app_data.max_average_base_pop - app_data.max_variation_base_pop < 1 || app_data.max_average_base_pop + app_data.max_variation_base_pop > UROWS*UCOLS) { invalid("maxAverageBasePop or maxVariationBasePop"); app_data.max_average_base_pop = def_app_data.max_average_base_pop; app_data.max_variation_base_pop = def_app_data.max_variation_base_pop; } if (app_data.max_jovians_per_sector < 1) { invalid("maxJoviansPerSector"); app_data.max_jovians_per_sector = def_app_data.max_jovians_per_sector; } if (app_data.min_average_jovian_pop < 1 || app_data.min_variation_jovian_pop < 0 || app_data.min_average_jovian_pop - app_data.min_variation_jovian_pop < 1 || app_data.min_average_jovian_pop + app_data.min_variation_jovian_pop > app_data.max_jovians_per_sector*UROWS*UCOLS) { invalid("minAverageJovianPop or minVariationJovianPop"); app_data.min_average_jovian_pop = def_app_data.min_average_jovian_pop; app_data.min_variation_jovian_pop = def_app_data.min_variation_jovian_pop; } if (app_data.max_average_jovian_pop < 1 || app_data.max_variation_jovian_pop < 0 || app_data.max_average_jovian_pop - app_data.max_variation_jovian_pop < 1 || app_data.max_average_jovian_pop + app_data.max_variation_jovian_pop > app_data.max_jovians_per_sector*UROWS*UCOLS) { invalid("maxAverageJovianPop or maxVariationJovianPop"); app_data.max_average_jovian_pop = def_app_data.max_average_jovian_pop; app_data.max_variation_jovian_pop = def_app_data.max_variation_jovian_pop; } if (app_data.max_stars_per_sector < 1) { invalid("maxStarsPerSector"); app_data.max_stars_per_sector = def_app_data.max_stars_per_sector; } if (app_data.min_average_star_pop < 1 || app_data.min_variation_star_pop < 0 || app_data.min_average_star_pop - app_data.min_variation_star_pop < 1 || app_data.min_average_star_pop + app_data.min_variation_star_pop > app_data.max_stars_per_sector*UROWS*UCOLS) { invalid("minAverageStarPop or minVariationStarPop"); app_data.min_average_star_pop = def_app_data.min_average_star_pop; app_data.min_variation_star_pop = def_app_data.min_variation_star_pop; } if (app_data.max_average_star_pop < 1 || app_data.max_variation_star_pop < 0 || app_data.max_average_star_pop - app_data.max_variation_star_pop < 1 || app_data.max_average_star_pop + app_data.max_variation_star_pop > app_data.max_stars_per_sector*UROWS*UCOLS) { invalid("maxAverageStarPop or maxVariationStarPop"); app_data.max_average_star_pop = def_app_data.max_average_star_pop; app_data.max_variation_star_pop = def_app_data.max_variation_star_pop; } if (app_data.min_average_blackhole_pop < 1 || app_data.min_variation_blackhole_pop < 0 || app_data.min_average_blackhole_pop - app_data.min_variation_blackhole_pop < 1 || app_data.min_average_blackhole_pop + app_data.min_variation_blackhole_pop > UROWS*UCOLS) { invalid("minAverageBlackholePop or minVariationBlackholePop"); app_data.min_average_blackhole_pop = def_app_data.min_average_blackhole_pop; app_data.min_variation_blackhole_pop = def_app_data.min_variation_blackhole_pop; } if (app_data.max_average_blackhole_pop < 1 || app_data.max_variation_blackhole_pop < 0 || app_data.max_average_blackhole_pop - app_data.max_variation_blackhole_pop < 1 || app_data.max_average_blackhole_pop + app_data.max_variation_blackhole_pop > UROWS*UCOLS) { invalid("maxAverageBlackholePop or maxVariationBlackholePop"); app_data.max_average_blackhole_pop = def_app_data.max_average_blackhole_pop; app_data.max_variation_blackhole_pop = def_app_data.max_variation_blackhole_pop; } if (app_data.faser_width < 1) { invalid("faserWidth"); app_data.faser_width = def_app_data.faser_width; } if (app_data.faser_dash_offset < 0) { invalid("faserDashOffset"); app_data.faser_dash_offset = def_app_data.faser_dash_offset; } if (app_data.faser_speed < 1) { invalid("faserSpeed"); app_data.faser_speed = def_app_data.faser_speed; } if (app_data.torpedo_width < 1) { invalid("torpedoWidth"); app_data.torpedo_width = def_app_data.torpedo_width; } if (app_data.torpedo_length < 1) { invalid("torpedoLength"); app_data.torpedo_length = def_app_data.torpedo_length; } if (app_data.torpedo_speed < 1) { invalid("torpedoSpeed"); app_data.torpedo_speed = def_app_data.torpedo_speed; } if (app_data.explosion_speed < 1) { invalid("explosionSpeed"); app_data.explosion_speed = def_app_data.explosion_speed; } if (app_data.explosion_radius_small < 1) { invalid("explosionRadiusSmall"); app_data.explosion_radius_small = def_app_data.explosion_radius_small; } if (app_data.explosion_radius_big < 1) { invalid("explosionRadiusBig"); app_data.explosion_radius_big = def_app_data.explosion_radius_big; } if (app_data.endever_thrust_speed < 1) { invalid("endeverThrustSpeed"); app_data.endever_thrust_speed = def_app_data.endever_thrust_speed; } if (app_data.ship_energize_speed < 1) { invalid("shipEnergizeSpeed"); app_data.ship_energize_speed = def_app_data.ship_energize_speed; } if (app_data.jovian_action_speed < 1) { invalid("jovianActionSpeed."); app_data.jovian_action_speed = def_app_data.jovian_action_speed; } if (strlen(app_data.self_destruct_code) != 3) { invalid("selfDestructCode"); app_data.self_destruct_code = def_app_data.self_destruct_code; } if (app_data.max_torpedoes < 0) { invalid("maxTorpedoes"); app_data.max_torpedoes = def_app_data.max_torpedoes; } if (app_data.mask_probability < 0 || app_data.mask_probability > 100) { invalid("maskProbability"); app_data.mask_probability = def_app_data.mask_probability; } if (app_data.min_jovian_distance < 0 || app_data.min_jovian_distance > sqrt((double)SECTDIAGSQ)/(double)4) { invalid("minJovianDistance"); app_data.min_jovian_distance = def_app_data.min_jovian_distance; } if (app_data.endever_min_faser_energy < 0 || app_data.endever_min_faser_energy > 100) { invalid("endeverMinFaserEnergy"); app_data.endever_min_faser_energy = def_app_data.endever_min_faser_energy; } if (app_data.endever_min_warp_energy < 0 || app_data.endever_min_warp_energy > 100) { invalid("endeverMinWarpEnergy"); app_data.endever_min_warp_energy = def_app_data.endever_min_warp_energy; } if (app_data.endever_min_thrust_energy < 0 || app_data.endever_min_thrust_energy > 100) { invalid("endeverMinThrustEnergy"); app_data.endever_min_thrust_energy = def_app_data.endever_min_thrust_energy; } if (app_data.jovian_min_faser_energy < 0 || app_data.jovian_min_faser_energy > 100) { invalid("jovianMinFaserEnergy"); app_data.jovian_min_faser_energy = def_app_data.jovian_min_faser_energy; } if (app_data.jovian_min_warp_energy < 0 || app_data.jovian_min_warp_energy > 100) { invalid("jovianMinWarpEnergy"); app_data.jovian_min_warp_energy = def_app_data.jovian_min_warp_energy; } if (app_data.jovian_min_thrust_energy < 0 || app_data.jovian_min_thrust_energy > 100) { invalid("jovianMinThrustEnergy"); app_data.jovian_min_thrust_energy = def_app_data.jovian_min_thrust_energy; } if (app_data.jovian_thrust_retreat_energy < 0 || app_data.jovian_thrust_retreat_energy > 100) { invalid("jovianThrustRetreatEnergy"); app_data.jovian_thrust_retreat_energy = def_app_data.jovian_thrust_retreat_energy; } if (app_data.jovian_warp_retreat_energy < 0 || app_data.jovian_warp_retreat_energy > 100) { invalid("jovianWarpRetreatEnergy"); app_data.jovian_warp_retreat_energy = def_app_data.jovian_warp_retreat_energy; } if (app_data.jovian_faser_retreat_energy < 0 || app_data.jovian_faser_retreat_energy > 100) { invalid("jovianFaserRetreatEnergy"); app_data.jovian_faser_retreat_energy = def_app_data.jovian_faser_retreat_energy; } if (app_data.jovian_shield_retreat_energy < 0 || app_data.jovian_shield_retreat_energy > 100) { invalid("jovianShieldRetreatEnergy"); app_data.jovian_shield_retreat_energy = def_app_data.jovian_shield_retreat_energy; } if (app_data.jovian_retreat_probability < 0 || app_data.jovian_retreat_probability > 100) { invalid("jovianRetreatProbability"); app_data.jovian_retreat_probability = def_app_data.jovian_retreat_probability; } if (app_data.jovian_retreat_speed <= 0) { invalid("jovianRetreatSpeed"); app_data.jovian_retreat_speed = def_app_data.jovian_retreat_speed; } if (app_data.jovian_min_fight_frequency <= 0) { invalid("jovianMinFightFrequency"); app_data.jovian_min_fight_frequency = def_app_data.jovian_min_fight_frequency; } if (app_data.jovian_max_fight_frequency <= 0) { invalid("jovianMaxFightFrequency"); app_data.jovian_max_fight_frequency = def_app_data.jovian_max_fight_frequency; } if (app_data.jovian_min_raid_frequency <= 0) { invalid("jovianMinRaidFrequency"); app_data.jovian_min_raid_frequency = def_app_data.jovian_min_raid_frequency; } if (app_data.jovian_max_raid_frequency <= 0) { invalid("jovianMaxRaidFrequency"); app_data.jovian_max_raid_frequency = def_app_data.jovian_max_raid_frequency; } if (app_data.jovian_min_leap_frequency <= 0) { invalid("jovianMinLeapFrequency"); app_data.jovian_min_leap_frequency = def_app_data.jovian_min_leap_frequency; } if (app_data.jovian_max_leap_frequency <= 0) { invalid("jovianMaxLeapFrequency"); app_data.jovian_max_leap_frequency = app_data.jovian_max_leap_frequency; } } // end