LPP* CnLPP::getLPP() { setComment("C(n) LPP " + gameId()); // each line is a structural variable for (const Line& l: b.getLineList()) { std::string v_name = to_string(l); setVariableBounds(v_name, 0.0, 1.0); } // each dot is a structural variable for (const Dot& d: b.getDotList()) { std::string v_name = "dot_" + to_string(d); setVariableBounds(v_name, 0.0, 1.0); getObjective().push_back(std::pair<std::string, double>(v_name, -1.0)); // Constraint for exact problems. // // variables are either 0 or 1 (i.e. the move is either played or not) if (getFlag("exact")) { setVariableBoolean(v_name, true); } } // constraints: // // (1) for each segment, sum of weights of moves that use this segment is <= 1 // (2) for each segment, // dot_weight >= sum of weights of lines that use this segment // // (3) sum of line weights = n // // (4) dot_weight for dots from the cross is equal to 1 // (1) for each segment, sum of weights of moves that use this segment is <= 1 // (IT IS REDUNDANT TO (2) because dot_weight <= 1): // (2) for each segment, // dot_weight >= sum of weights of moves that remove this segment for (const Segment& s: b.getSegmentList()) { Constraint c; c.setName("used_segment_" + to_string(s)); for (const Line& l: b.getLinesUsingSegment(s)) { c.addVariable(to_string(l), -1.0); } c.addVariable("dot_" + to_string(s.first), 1.0); c.setBound(0.0); c.setType(Constraint::GT); addConstraint(c); } // (3) sum of line weights = n { Constraint c; c.setName("startingdots"); for (const Line& l: b.getLineList()) { c.addVariable(to_string(l), 1.0); } c.setBound(n); c.setType(Constraint::EQ); addConstraint(c); } // (4) dot_weight for dots from the cross is equal to 1 for (const Dot& d: b.getDotList()) { if (b.hasDot(d)) { Constraint c; c.setName("cross_" + to_string(d)); c.addVariable("dot_" + to_string(d), 1.0); c.setBound(1.0); c.setType(Constraint::EQ); addConstraint(c); } } // symmetric solutions if (getFlag("symmetric")) { for (const Line&l: b.getLineList()) { Line sl = b.centerSymmetry(l); Constraint c; c.addVariable(to_string(l), 1.0); c.addVariable(to_string(sl), -1.0); c.setType(Constraint::EQ); c.setBound(0.0); c.setName("sym_" + to_string(l)); addConstraint(c); } } return this; }
LPP* MorpionLPP::getLPP() { setComment(gameId()); // each possible move is a structural variable // our goal is to maximize sum over all variables for (const Move& m: b.getMoveList()) { std::string v_name = to_string(m); setVariableBounds(v_name, 0.0, 1.0); getObjective().push_back(std::pair<std::string, double>(v_name, 1.0)); // Constraint for exact problems. // // mv_ variables are either 0 or 1 (i.e. the move is either played or not) if (getFlag("exact") || getFlag("binary_moves")) { setVariableBoolean(v_name, true); } } // each segment gives us constraints: // (1) if the segment is placed in the starting position // (a) sum of weights of moves that place this segment <= 0 // (b) 1 - sum of weights of moves that remove this segment >= 0 // i.e. sum of weights of moves that remove this segment <= 1 // (2) if the segment is not placed in the starting position // (a) sum of weights of moves that place this segment <= 1 // (b) sum of weights of moves that place this segment // - sum of weights of moves that remove this segment >= 0 for (const Segment& s: b.getSegmentList()) { int x = s.first.x; int y = s.first.y; int d = s.second; std::string constr_name = "segment_" + to_string(x) + "_" + to_string(y) + "_" + to_string(d); if (b.hasDot(Dot(x,y))) { // (1a) { Constraint constr; for (Move& pl: b.getMovesPlacingSegment(s)) { constr.addVariable(to_string(pl), 1.0); } constr.setName("r1a_" + constr_name); constr.setType(Constraint::LT); constr.setBound(0.0); addConstraint(constr); } // (1b) { Constraint constr; for (Move& rm: b.getMovesRemovingSegment(s)) { constr.addVariable(to_string(rm), 1.0); } constr.setName("r1b_" + constr_name); constr.setType(Constraint::LT); constr.setBound(1.0); addConstraint(constr); } } else { // (2a) { Constraint constr; for (Move& pl: b.getMovesPlacingSegment(s)) { constr.addVariable(to_string(pl), 1.0); } constr.setName("r2a_" + constr_name); constr.setType(Constraint::LT); constr.setBound(1.0); addConstraint(constr); } // (2b) { Constraint constr; for (Move& pl: b.getMovesPlacingSegment(s)) { constr.addVariable(to_string(pl), 1.0); } for (Move& rm: b.getMovesRemovingSegment(s)) { constr.addVariable(to_string(rm), -1.0); } constr.setName("r2b_" + constr_name); constr.setType(Constraint::GT); constr.setBound(0.0); addConstraint(constr); } } } // EXTRA CONSTRAINTS: // // for each move m: // for each dot d required by m: // for each move n placing d that is consistent with m: // weight_m <= sum of weights of n's if (getFlag("extra")) { for (const Move& m: b.getMoveList()) { std::string constr_name = "_" + to_string(m); for (const Dot& d: m.requiredDots(b.getVariant())) { if (b.hasDot(d)) continue; Constraint constr; for (const Move& n: b.getMovesPlacingSegment(Segment(d,0))) { if (m.consistentWith(n,b.getVariant())) { constr.addVariable(to_string(n), -1.0); } } constr.addVariable(to_string(m), 1.0); constr.setName("extra_" + to_string(d) + constr_name); constr.setType(Constraint::LT); constr.setBound(0.0); addConstraint(constr); } } } // Disallow cycles of length 3 from the solution. // Improves fuzzy solutions if (getFlag("short-cycles")) { for (const Segment& s: b.getSegmentList()) { int d = s.second; if (d % 2 == 1) continue; addConstraints(createCycleConstraints(s, d + 2, d + 5)); addConstraints(createCycleConstraints(s, d + 6, d + 1)); } } // Constraints for acyclic problems (explanation makes sense for exact problems): // // OBSOLETE // // 1. Each move mv_* has accompanying order variable order_* // 2. Move that is not picked has always order 0, // move that is picked has order between 1 and 675 // // It is accomplished with the condition: // mv_ <= order_ <= 675 * mv_ // // 3. Assume that mv_1 removes segment s and mv_2 places segment s (mv_1 != mv_2). // Then // order_1 + (1 - mv_1) * 1000 >= order_2 + 1 // // The (1-mv_1)*1000 term assures that the condition is not enforced // for moves that are not picked (i.e. have mv_1 = 0) if (getFlag("acyclic")) { throw std::string("not implemented"); } // Constraints for symmetric problems. // // Moves that are symmetric by central symmetry // with center at ref + (1.5,1.5) have to have equal weights if (getFlag("symmetric")) { for (const Move&m: b.getMoveList()) { Move sm = b.centerSymmetry(m); Constraint c; c.addVariable(to_string(m), 1.0); c.addVariable(to_string(sm), -1.0); c.setType(Constraint::EQ); c.setBound(0.0); c.setName("sym_" + to_string(m)); addConstraint(c); } } // dot-acyclic - better implementation of acyclic problems // dots that are not placed have dot_ variable equal to 0 // this is important for --hull option // use this not only for dot-acyclic problems for (const Dot& d: b.getDotList()) { if (b.hasDot(d)) continue; Constraint c; c.setName("dotmove_" + to_string(d)); c.addVariable("dot_" + to_string(d), 1.0); for (const Move& m: b.getMovesPlacingDot(d)) { c.addVariable(to_string(m), -b.bound()); } c.setType(Constraint::LT); c.setBound(0.0); addConstraint(c); } if (getFlag("dot-acyclic")) { for (int x = 0; x < b.getWidth(); x++) { for (int y= 0; y < b.getHeight(); y++) { if (b.infeasibleDot(Dot(x,y)) || b.hasDot(Dot(x,y))) continue; setVariableBounds("dot_" + to_string(Dot(x,y)), 0, b.bound()); if (getFlag("symmetric")) { Constraint c; if (b.infeasibleDot(b.centerSymmetry(Dot(x,y)))) continue; c.setName("dotsym_"); c.addVariable("dot_" + to_string(Dot(x,y)), 1.0); c.addVariable("dot_" + to_string(b.centerSymmetry(Dot(x,y))), -1.0); c.setType(Constraint::EQ); c.setBound(0.0); addConstraint(c); } } } for (const Move& m: b.getMoveList()) { for (const Dot& rq: m.requiredDots(b.getVariant())) { if (b.hasDot(rq)) continue; Constraint c; // dot_placed >= dot_required + 1 - (1 - m) * bound // i.e. dot_placed - dot_required - bound * m >= 1 - bound c.setName("dot_"); c.addVariable("dot_" + to_string(m.placedDot()), 1.0); c.addVariable("dot_" + to_string(rq), -1.0); c.addVariable(to_string(m), -b.bound()); c.setBound(1 - b.bound()); c.setType(Constraint::GT); addConstraint(c); } } } // Constraints that enforce that the board (if it is rectangle) is // the convex hull of the solution if (getFlag("rhull")) { // right side addConstraint(getSideConstraint(1,0,true)); // left side addConstraint(getSideConstraint(1,0,false)); // top side addConstraint(getSideConstraint(0,1,true)); // bottom side addConstraint(getSideConstraint(0,1,false)); } // Constraints that enforce that the board (if it is octagon) is // the convex hull of the solution if (getFlag("hull")) { // right side addConstraint(getSideConstraint(1,0,true)); // left side addConstraint(getSideConstraint(1,0,false)); // lower right side addConstraint(getSideConstraint(1,-1,false)); // upper left side addConstraint(getSideConstraint(1,-1,true)); // top side addConstraint(getSideConstraint(0,1,true)); // bottom side addConstraint(getSideConstraint(0,1,false)); // lower left side addConstraint(getSideConstraint(1,1,false)); // upper right side addConstraint(getSideConstraint(1,1,true)); } return this; }
LPP* PlusPlusLPP::getLPP() { setComment("++LPP " + gameId()); // each line is a structural variable for (const Line& l: b.getLineList()) { std::string v_name = to_string(l); setVariableBounds(v_name, 0.0, 1.0); getObjective().push_back(std::pair<std::string, double>(v_name, 1.0)); } // each dot is a structural variable for (const Dot& d: b.getDotList()) { std::string v_name = "dot_" + to_string(d); setVariableBounds(v_name, 0.0, 1.0); // Constraint for exact problems. // // variables are either 0 or 1 (i.e. the move is either played or not) if (getFlag("exact")) { setVariableBoolean(v_name, true); setVariableOrd(v_name, 1000-abs(b.getCRef().x - d.x) - abs(b.getCRef().y - d.y)); } } // constraints: // // (1) for each segment, sum of weights of moves that use this segment is <= 1 // (2) for each segment, // dot_weight >= sum of weights of lines that use this segment // // (3) sum of dot weights = 36 + sum of line weights // // (4) dot_weight for dots from the cross is equal to 1 // (1) for each segment, sum of weights of moves that use this segment is <= 1 // (IT IS REDUNDANT TO (2) because dot_weight <= 1): // (2) for each segment, // dot_weight >= sum of weights of moves that remove this segment for (const Segment& s: b.getSegmentList()) { Constraint c; c.setName("used_segment_" + to_string(s)); for (const Line& l: b.getLinesUsingSegment(s)) { c.addVariable(to_string(l), -1.0); } c.addVariable("dot_" + to_string(s.first), 1.0); c.setBound(0.0); c.setType(Constraint::GT); addConstraint(c); } // (3) sum of dot weights <= 36 + sum of line weights { Constraint c; c.setName("startingdots"); for (const Dot& d: b.getDotList()) { c.addVariable("dot_" + to_string(d), 1.0); } for (const Line& l: b.getLineList()) { c.addVariable(to_string(l), -1.0); } c.setBound(36.0); c.setType(Constraint::EQ); addConstraint(c); } // (4) dot_weight for dots from the cross is equal to 1 for (const Dot& d: b.getDotList()) { if (b.hasDot(d)) { Constraint c; c.setName("cross_" + to_string(d)); c.addVariable("dot_" + to_string(d), 1.0); c.setBound(1.0); c.setType(Constraint::EQ); addConstraint(c); } } // symmetric solutions if (getFlag("symmetric")) { for (const Line&l: b.getLineList()) { Line sl = b.centerSymmetry(l); Constraint c; c.addVariable(to_string(l), 1.0); c.addVariable(to_string(sl), -1.0); c.setType(Constraint::EQ); c.setBound(0.0); c.setName("sym_" + to_string(l)); addConstraint(c); } for (const Dot&d: b.getDotList()) { Dot sd = b.centerSymmetry(d); Constraint c; c.addVariable("dot_"+to_string(d), 1.0); c.addVariable("dot_"+to_string(sd), -1.0); c.setType(Constraint::EQ); c.setBound(0.0); c.setName("dotsym_" + to_string(d)); addConstraint(c); } } // exact hull if (getFlag("hull")) { // right side addConstraint(getSideConstraint(1,0,true)); // left side addConstraint(getSideConstraint(1,0,false)); // lower right side addConstraint(getSideConstraint(1,-1,false)); // upper left side addConstraint(getSideConstraint(1,-1,true)); // top side addConstraint(getSideConstraint(0,1,true)); // bottom side addConstraint(getSideConstraint(0,1,false)); // lower left side addConstraint(getSideConstraint(1,1,false)); // upper right side addConstraint(getSideConstraint(1,1,true)); } // dots that are not placed have dot_ variable equal to 0 // this is important for --hull option // and possibly for other reasons as well for (const Dot& d: b.getDotList()) { Constraint c; c.setName("dotline_" + to_string(d)); c.addVariable("dot_" + to_string(d), 1.0); for (const Line& l: b.getLinesUsingDot(d)) { c.addVariable(to_string(l), -1.0); } c.setType(Constraint::LT); c.setBound(0.0); addConstraint(c); } // extra constraints that remove small gaps from the solution // there is always an optimal solution without 1-segment gaps if (getFlag("extra")) { for (const Line& l: b.getLineList()) { { Constraint c; c.setName("smallgaps1_" + to_string(l)); c.addVariable(to_string(l), 1.0); Line ol; if (b.getVariant() == T5) { ol = Line(l.st + direction[l.dir]*5, l.dir); if (b.validLine(ol)) { c.addVariable(to_string(ol), 1.0); } } else { ol = Line(l.st + direction[l.dir]*6, l.dir); if (b.validLine(ol)) { c.addVariable(to_string(ol), 1.0); } } c.setType(Constraint::LT); c.setBound(1.0); addConstraint(c); } { Constraint c; c.setName("smallgaps2_" + to_string(l)); c.addVariable(to_string(l), 1.0); Line ol; if (b.getVariant() == T5) { ol = Line(l.st + direction[l.dir]*(-5), l.dir); if (b.validLine(ol)) { c.addVariable(to_string(ol), 1.0); } } else { ol = Line(l.st + direction[l.dir]*(-6), l.dir); if (b.validLine(ol)) { c.addVariable(to_string(ol), 1.0); } } c.setType(Constraint::LT); c.setBound(1.0); addConstraint(c); } } } return this; }
LPP* PotentialLPP::getLPP() { setComment("PotentialLPP " + gameId()); // each move is a structural variable for (const Move& l: b.getMoveList()) { std::string v_name = to_string(l); setVariableBounds(v_name, 0.0, 1.0); if (getFlag("exact") && getFlag("dot-acyclic")) { setVariableBoolean(v_name, true); setVariableOrd(v_name, 0); } } // each dot is a structural variable for (Dot d: b.getDotList()) { std::string v_name = "dot_" + to_string(d); if (!b.hasDot(d)) { getObjective().push_back(std::pair<std::string, double>(v_name, 1.0)); } // dots are the only boolean variables if (getFlag("exact")) { setVariableBoolean(v_name, true); if (b.infeasibleDot(d + Dot(1,0)) || b.infeasibleDot(d + Dot(1,1)) || b.infeasibleDot(d + Dot(0,1)) || b.infeasibleDot(d + Dot(1,-1)) || b.infeasibleDot(d + Dot(0,-1)) || b.infeasibleDot(d + Dot(-1,-1)) || b.infeasibleDot(d + Dot(-1,0)) || b.infeasibleDot(d + Dot(-1,1))) { Dot n = d - b.getCRef(); setVariableOrd(v_name, 1 + abs(n.x) + abs(n.y)); } else { setVariableOrd(v_name, -1); } } // dots that are placed on board have dot variable equal to 1 if (b.hasDot(d)) { setVariableBounds(v_name, 1.0, 1.0); } else { setVariableBounds(v_name, 0.0, 1.0); } } // constraints: // // (1) dot at beginning of segment - moves removing segment starting from dot >= 0 // // (2) dot == sum of weights of moves that place dot // // (3) sum of weights of dots - sum of weights of moves <= 36 // (1) // L4 for (const Segment& s: b.getSegmentList()) { Constraint c; c.setName("sgm_" + to_string(s)); c.addVariable("dot_" + to_string(s.first), 1.0); for (const Move& m: b.getMovesRemovingSegment(s)) { c.addVariable(to_string(m), -1.0); } c.setType(Constraint::GT); c.setBound(0.0); addConstraint(c); } // L3 for (const Dot& d: b.getDotList()) { if (b.hasDot(d)) continue; Constraint c; c.setName("L3_" + to_string(d)); c.addVariable("dot_" + to_string(d), 1.0f); for (const Move& m: b.getMovesPlacingDot(d)) { c.addVariable(to_string(m), -1.0f); } c.setBound(0.0f); c.setType(Constraint::EQ); addConstraint(c); } /* // (2) for (const Dot &d: b.getDotList()) { if (b.hasDot(d)) continue; Constraint c; c.setName("dotmv_" + to_string(d)); for (const Move &m: b.getMovesPlacingDot(d)) { c.addVariable(to_string(m), -1.0); } c.addVariable("dot_" + to_string(d), 1.0); c.setBound(0.0); c.setType(Constraint::EQ); addConstraint(c); } */ /* // (3) { Constraint c; c.setName("dots_moves"); for (const Dot &d: b.getDotList()) { c.addVariable("dot_"+to_string(d), 1.0); } for (const Move &m: b.getMoveList()) { c.addVariable(to_string(m), -1.0); } c.setBound(36.0); c.setType(Constraint::LT); addConstraint(c); } */ // dots that are not placed have dot_ variable equal to 0 // this is important for --hull option // use this not only for dot-acyclic problems /* for (const Dot& d: b.getDotList()) { if (b.hasDot(d)) continue; Constraint c; c.setName("dotmove_" + to_string(d)); c.addVariable("dot_" + to_string(d), 1.0); for (const Move& m: b.getMovesPlacingDot(d)) { c.addVariable(to_string(m), -b.bound()); } c.setType(Constraint::LT); c.setBound(0.0); addConstraint(c); } */ // Constraints that enforce that the board (if it is an octagon) is // the convex hull of the solution if (getFlag("hull")) { // right side addConstraint(getSideConstraint(1,0,true)); // left side addConstraint(getSideConstraint(1,0,false)); // lower right side addConstraint(getSideConstraint(1,-1,false)); // upper left side addConstraint(getSideConstraint(1,-1,true)); // top side addConstraint(getSideConstraint(0,1,true)); // bottom side addConstraint(getSideConstraint(0,1,false)); // lower left side addConstraint(getSideConstraint(1,1,false)); // upper right side addConstraint(getSideConstraint(1,1,true)); } if (getFlag("rhull")) { // right side addConstraint(getSideConstraint(1,0,true)); // left side addConstraint(getSideConstraint(1,0,false)); // top side addConstraint(getSideConstraint(0,1,true)); // bottom side addConstraint(getSideConstraint(0,1,false)); } if (getFlag("rside")) { // right side addConstraint(getSideConstraint(1,0,true)); } if (getFlag("symmetric")) { for (const Move&m: b.getMoveList()) { Move sm = b.centerSymmetry(m); Constraint c; c.addVariable(to_string(m), 1.0); c.addVariable(to_string(sm), -1.0); c.setType(Constraint::EQ); c.setBound(0.0); c.setName("sym_" + to_string(m)); addConstraint(c); } for (const Dot& d: b.getDotList()) { std::string v_name = "symdot_" + to_string(d); Dot sd = b.centerSymmetry(d); if (b.hasDot(d) || b.hasDot(sd)) { continue; } Constraint c; c.addVariable("dot_" + to_string(d), 1.0); c.addVariable("dot_" + to_string(sd), -1.0); c.setType(Constraint::EQ); c.setBound(0.0); c.setName("symdot_" + to_string(d)); addConstraint(c); } } // create only acyclic solutions if (getFlag("dot-acyclic")) { for (int x = 0; x < b.getWidth(); x++) { for (int y= 0; y < b.getHeight(); y++) { if (b.infeasibleDot(Dot(x,y)) || b.hasDot(Dot(x,y))) continue; setVariableBounds("ord_" + to_string(Dot(x,y)), 0, b.bound()); if (getFlag("symmetric")) { Constraint c; if (b.infeasibleDot(b.centerSymmetry(Dot(x,y)))) continue; c.setName("ordsym_"+to_string(Dot(x,y))); c.addVariable("ord_" + to_string(Dot(x,y)), 1.0); c.addVariable("ord_" + to_string(b.centerSymmetry(Dot(x,y))), -1.0); c.setType(Constraint::EQ); c.setBound(0.0); addConstraint(c); } } } for (const Move& m: b.getMoveList()) { for (const Dot& rq: m.requiredDots(b.getVariant())) { if (b.hasDot(rq)) continue; Constraint c; // dot_placed >= dot_required + 1 - (1 - m) * bound // i.e. dot_placed - dot_required - bound * m >= 1 - bound c.setName("ord_" + to_string(m) + "_" + to_string(rq)); c.addVariable("ord_" + to_string(m.placedDot()), 1.0); c.addVariable("ord_" + to_string(rq), -1.0); c.addVariable(to_string(m), -b.bound()); c.setBound(1 - b.bound()); c.setType(Constraint::GT); addConstraint(c); } } } /* enum { R = 0, D = 2, L = 4, U = 6 }; std::vector<int> inside_path = { R, U, U, R, D, D, D, R, R, R, D, L, L, L, D, D, D, L, U, U, U, L, L, L, U, R, R, R }; Dot r = b.getReference(); for (auto & d: inside_path) { r = r + direction[d]; Constraint c; c.setName("inside_" + to_string(r)); c.addVariable("dot_" + to_string(r), 1.0f); c.setBound(1.0f); c.setType(Constraint::EQ); addConstraint(c); } */ return this; }
EditGameDialog::EditGameDialog(const String &domain, const String &desc) : OptionsDialog(domain, "GameOptions") { // Retrieve all game specific options. const EnginePlugin *plugin = 0; // To allow for game domains without a gameid. // TODO: Is it intentional that this is still supported? String gameId(ConfMan.get("gameid", domain)); if (gameId.empty()) gameId = domain; // Retrieve the plugin, since we need to access the engine's MetaEngine // implementation. EngineMan.findGame(gameId, &plugin); if (plugin) { _engineOptions = (*plugin)->getExtraGuiOptions(domain); } else { warning("Plugin for target \"%s\" not found! Game specific settings might be missing", domain.c_str()); } // GAME: Path to game data (r/o), extra data (r/o), and save data (r/w) String gamePath(ConfMan.get("path", _domain)); String extraPath(ConfMan.get("extrapath", _domain)); String savePath(ConfMan.get("savepath", _domain)); // GAME: Determine the description string String description(ConfMan.get("description", domain)); if (description.empty() && !desc.empty()) { description = desc; } // GUI: Add tab widget TabWidget *tab = new TabWidget(this, "GameOptions.TabWidget"); // // 1) The game tab // tab->addTab(_("Game")); // GUI: Label & edit widget for the game ID if (g_system->getOverlayWidth() > 320) new StaticTextWidget(tab, "GameOptions_Game.Id", _("ID:"), _("Short game identifier used for referring to saved games and running the game from the command line")); else new StaticTextWidget(tab, "GameOptions_Game.Id", _c("ID:", "lowres"), _("Short game identifier used for referring to saved games and running the game from the command line")); _domainWidget = new DomainEditTextWidget(tab, "GameOptions_Game.Domain", _domain, _("Short game identifier used for referring to saved games and running the game from the command line")); // GUI: Label & edit widget for the description if (g_system->getOverlayWidth() > 320) new StaticTextWidget(tab, "GameOptions_Game.Name", _("Name:"), _("Full title of the game")); else new StaticTextWidget(tab, "GameOptions_Game.Name", _c("Name:", "lowres"), _("Full title of the game")); _descriptionWidget = new EditTextWidget(tab, "GameOptions_Game.Desc", description, _("Full title of the game")); // Language popup _langPopUpDesc = new StaticTextWidget(tab, "GameOptions_Game.LangPopupDesc", _("Language:"), _("Language of the game. This will not turn your Spanish game version into English")); _langPopUp = new PopUpWidget(tab, "GameOptions_Game.LangPopup", _("Language of the game. This will not turn your Spanish game version into English")); _langPopUp->appendEntry(_("<default>"), (uint32)Common::UNK_LANG); _langPopUp->appendEntry("", (uint32)Common::UNK_LANG); const Common::LanguageDescription *l = Common::g_languages; for (; l->code; ++l) { if (checkGameGUIOptionLanguage(l->id, _guioptionsString)) _langPopUp->appendEntry(l->description, l->id); } // Platform popup if (g_system->getOverlayWidth() > 320) _platformPopUpDesc = new StaticTextWidget(tab, "GameOptions_Game.PlatformPopupDesc", _("Platform:"), _("Platform the game was originally designed for")); else _platformPopUpDesc = new StaticTextWidget(tab, "GameOptions_Game.PlatformPopupDesc", _c("Platform:", "lowres"), _("Platform the game was originally designed for")); _platformPopUp = new PopUpWidget(tab, "GameOptions_Game.PlatformPopup", _("Platform the game was originally designed for")); _platformPopUp->appendEntry(_("<default>")); _platformPopUp->appendEntry(""); const Common::PlatformDescription *p = Common::g_platforms; for (; p->code; ++p) { _platformPopUp->appendEntry(p->description, p->id); } // // 2) The engine tab (shown only if there are custom engine options) // if (_engineOptions.size() > 0) { tab->addTab(_("Engine")); addEngineControls(tab, "GameOptions_Engine.", _engineOptions); } // // 3) The graphics tab // _graphicsTabId = tab->addTab(g_system->getOverlayWidth() > 320 ? _("Graphics") : _("GFX")); if (g_system->getOverlayWidth() > 320) _globalGraphicsOverride = new CheckboxWidget(tab, "GameOptions_Graphics.EnableTabCheckbox", _("Override global graphic settings"), 0, kCmdGlobalGraphicsOverride); else _globalGraphicsOverride = new CheckboxWidget(tab, "GameOptions_Graphics.EnableTabCheckbox", _c("Override global graphic settings", "lowres"), 0, kCmdGlobalGraphicsOverride); addGraphicControls(tab, "GameOptions_Graphics."); // // 4) The audio tab // tab->addTab(_("Audio")); if (g_system->getOverlayWidth() > 320) _globalAudioOverride = new CheckboxWidget(tab, "GameOptions_Audio.EnableTabCheckbox", _("Override global audio settings"), 0, kCmdGlobalAudioOverride); else _globalAudioOverride = new CheckboxWidget(tab, "GameOptions_Audio.EnableTabCheckbox", _c("Override global audio settings", "lowres"), 0, kCmdGlobalAudioOverride); addAudioControls(tab, "GameOptions_Audio."); addSubtitleControls(tab, "GameOptions_Audio."); // // 5) The volume tab // if (g_system->getOverlayWidth() > 320) tab->addTab(_("Volume")); else tab->addTab(_c("Volume", "lowres")); if (g_system->getOverlayWidth() > 320) _globalVolumeOverride = new CheckboxWidget(tab, "GameOptions_Volume.EnableTabCheckbox", _("Override global volume settings"), 0, kCmdGlobalVolumeOverride); else _globalVolumeOverride = new CheckboxWidget(tab, "GameOptions_Volume.EnableTabCheckbox", _c("Override global volume settings", "lowres"), 0, kCmdGlobalVolumeOverride); addVolumeControls(tab, "GameOptions_Volume."); // // 6) The MIDI tab // _globalMIDIOverride = NULL; if (!_guioptions.contains(GUIO_NOMIDI)) { tab->addTab(_("MIDI")); if (g_system->getOverlayWidth() > 320) _globalMIDIOverride = new CheckboxWidget(tab, "GameOptions_MIDI.EnableTabCheckbox", _("Override global MIDI settings"), 0, kCmdGlobalMIDIOverride); else _globalMIDIOverride = new CheckboxWidget(tab, "GameOptions_MIDI.EnableTabCheckbox", _c("Override global MIDI settings", "lowres"), 0, kCmdGlobalMIDIOverride); addMIDIControls(tab, "GameOptions_MIDI."); } // // 7) The MT-32 tab // _globalMT32Override = NULL; if (!_guioptions.contains(GUIO_NOMIDI)) { tab->addTab(_("MT-32")); if (g_system->getOverlayWidth() > 320) _globalMT32Override = new CheckboxWidget(tab, "GameOptions_MT32.EnableTabCheckbox", _("Override global MT-32 settings"), 0, kCmdGlobalMT32Override); else _globalMT32Override = new CheckboxWidget(tab, "GameOptions_MT32.EnableTabCheckbox", _c("Override global MT-32 settings", "lowres"), 0, kCmdGlobalMT32Override); addMT32Controls(tab, "GameOptions_MT32."); } // // 8) The Paths tab // if (g_system->getOverlayWidth() > 320) tab->addTab(_("Paths")); else tab->addTab(_c("Paths", "lowres")); // These buttons have to be extra wide, or the text will be truncated // in the small version of the GUI. // GUI: Button + Label for the game path if (g_system->getOverlayWidth() > 320) new ButtonWidget(tab, "GameOptions_Paths.Gamepath", _("Game Path:"), 0, kCmdGameBrowser); else new ButtonWidget(tab, "GameOptions_Paths.Gamepath", _c("Game Path:", "lowres"), 0, kCmdGameBrowser); _gamePathWidget = new StaticTextWidget(tab, "GameOptions_Paths.GamepathText", gamePath); // GUI: Button + Label for the additional path if (g_system->getOverlayWidth() > 320) new ButtonWidget(tab, "GameOptions_Paths.Extrapath", _("Extra Path:"), _("Specifies path to additional data used by the game"), kCmdExtraBrowser); else new ButtonWidget(tab, "GameOptions_Paths.Extrapath", _c("Extra Path:", "lowres"), _("Specifies path to additional data used by the game"), kCmdExtraBrowser); _extraPathWidget = new StaticTextWidget(tab, "GameOptions_Paths.ExtrapathText", extraPath, _("Specifies path to additional data used by the game")); _extraPathClearButton = addClearButton(tab, "GameOptions_Paths.ExtraPathClearButton", kCmdExtraPathClear); // GUI: Button + Label for the save path if (g_system->getOverlayWidth() > 320) new ButtonWidget(tab, "GameOptions_Paths.Savepath", _("Save Path:"), _("Specifies where your saved games are put"), kCmdSaveBrowser); else new ButtonWidget(tab, "GameOptions_Paths.Savepath", _c("Save Path:", "lowres"), _("Specifies where your saved games are put"), kCmdSaveBrowser); _savePathWidget = new StaticTextWidget(tab, "GameOptions_Paths.SavepathText", savePath, _("Specifies where your saved games are put")); _savePathClearButton = addClearButton(tab, "GameOptions_Paths.SavePathClearButton", kCmdSavePathClear); // Activate the first tab tab->setActiveTab(0); _tabWidget = tab; // Add OK & Cancel buttons new ButtonWidget(this, "GameOptions.Cancel", _("Cancel"), 0, kCloseCmd); new ButtonWidget(this, "GameOptions.Ok", _("OK"), 0, kOKCmd); }
int PBGameInfo::qt_metacall(QMetaObject::Call _c, int _id, void **_a) { _id = QObject::qt_metacall(_c, _id, _a); if (_id < 0) return _id; #ifndef QT_NO_PROPERTIES if (_c == QMetaObject::ReadProperty) { void *_v = _a[0]; switch (_id) { case 0: *reinterpret_cast< QString*>(_v) = gameId(); break; case 1: *reinterpret_cast< QString*>(_v) = tableId(); break; case 2: *reinterpret_cast< QString*>(_v) = tourneyTableId(); break; case 3: *reinterpret_cast< QString*>(_v) = siteId(); break; case 4: *reinterpret_cast< int*>(_v) = canJoin(); break; case 5: *reinterpret_cast< QString*>(_v) = gameFamily(); break; case 6: *reinterpret_cast< double*>(_v) = smallBlind(); break; case 7: *reinterpret_cast< double*>(_v) = bigBlind(); break; case 8: *reinterpret_cast< int*>(_v) = maxSeats(); break; case 9: *reinterpret_cast< QString*>(_v) = driver(); break; case 10: *reinterpret_cast< int*>(_v) = canOpen(); break; case 11: *reinterpret_cast< int*>(_v) = openedTablesCount(); break; case 12: *reinterpret_cast< int*>(_v) = tablesMax(); break; case 13: *reinterpret_cast< int*>(_v) = tableOpened(); break; case 14: *reinterpret_cast< int*>(_v) = tourneyOpened(); break; case 15: *reinterpret_cast< int*>(_v) = gameComplete(); break; } _id -= 16; } else if (_c == QMetaObject::WriteProperty) { void *_v = _a[0]; switch (_id) { case 0: setGameId(*reinterpret_cast< QString*>(_v)); break; case 1: setTableId(*reinterpret_cast< QString*>(_v)); break; case 2: setTourneyTableId(*reinterpret_cast< QString*>(_v)); break; case 3: setSiteId(*reinterpret_cast< QString*>(_v)); break; case 4: setCanJoin(*reinterpret_cast< int*>(_v)); break; case 5: setGameFamily(*reinterpret_cast< QString*>(_v)); break; case 6: setSmallBlind(*reinterpret_cast< double*>(_v)); break; case 7: setBigBlind(*reinterpret_cast< double*>(_v)); break; case 8: setMaxSeats(*reinterpret_cast< int*>(_v)); break; case 9: setDriver(*reinterpret_cast< QString*>(_v)); break; case 10: setCanOpen(*reinterpret_cast< int*>(_v)); break; case 11: setOpenedTablesCount(*reinterpret_cast< int*>(_v)); break; case 12: setTablesMax(*reinterpret_cast< int*>(_v)); break; case 13: setTableOpened(*reinterpret_cast< int*>(_v)); break; case 14: setTourneyOpened(*reinterpret_cast< int*>(_v)); break; case 15: setGameComplete(*reinterpret_cast< int*>(_v)); break; } _id -= 16; } else if (_c == QMetaObject::ResetProperty) { _id -= 16; } else if (_c == QMetaObject::QueryPropertyDesignable) { _id -= 16; } else if (_c == QMetaObject::QueryPropertyScriptable) { _id -= 16; } else if (_c == QMetaObject::QueryPropertyStored) { _id -= 16; } else if (_c == QMetaObject::QueryPropertyEditable) { _id -= 16; } else if (_c == QMetaObject::QueryPropertyUser) { _id -= 16; } #endif // QT_NO_PROPERTIES return _id; }